krb5-1.22.1/0000775000175000017500000000000015051422641012342 5ustar ghudsonghudsonkrb5-1.22.1/doc/0000775000175000017500000000000015051422775013117 5ustar ghudsonghudsonkrb5-1.22.1/doc/user/0000775000175000017500000000000015051422640014064 5ustar ghudsonghudsonkrb5-1.22.1/doc/user/user_config/0000775000175000017500000000000015051422640016367 5ustar ghudsonghudsonkrb5-1.22.1/doc/user/user_config/k5login.rst0000664000175000017500000000345415051422640020477 0ustar ghudsonghudson.. _.k5login(5): .k5login ======== DESCRIPTION ----------- The .k5login file, which resides in a user's home directory, contains a list of the Kerberos principals. Anyone with valid tickets for a principal in the file is allowed host access with the UID of the user in whose home directory the file resides. One common use is to place a .k5login file in root's home directory, thereby granting system administrators remote root access to the host via Kerberos. EXAMPLES -------- Suppose the user ``alice`` had a .k5login file in her home directory containing just the following line:: bob@FOOBAR.ORG This would allow ``bob`` to use Kerberos network applications, such as ssh(1), to access ``alice``'s account, using ``bob``'s Kerberos tickets. In a default configuration (with **k5login_authoritative** set to true in :ref:`krb5.conf(5)`), this .k5login file would not let ``alice`` use those network applications to access her account, since she is not listed! With no .k5login file, or with **k5login_authoritative** set to false, a default rule would permit the principal ``alice`` in the machine's default realm to access the ``alice`` account. Let us further suppose that ``alice`` is a system administrator. Alice and the other system administrators would have their principals in root's .k5login file on each host:: alice@BLEEP.COM joeadmin/root@BLEEP.COM This would allow either system administrator to log in to these hosts using their Kerberos tickets instead of having to type the root password. Note that because ``bob`` retains the Kerberos tickets for his own principal, ``bob@FOOBAR.ORG``, he would not have any of the privileges that require ``alice``'s tickets, such as root access to any of the site's hosts, or the ability to change ``alice``'s password. SEE ALSO -------- kerberos(1) krb5-1.22.1/doc/user/user_config/kerberos.rst0000664000175000017500000001600515051422640020737 0ustar ghudsonghudson.. _kerberos(7): kerberos ======== DESCRIPTION ----------- The Kerberos system authenticates individual users in a network environment. After authenticating yourself to Kerberos, you can use Kerberos-enabled programs without having to present passwords or certificates to those programs. If you receive the following response from :ref:`kinit(1)`: kinit: Client not found in Kerberos database while getting initial credentials you haven't been registered as a Kerberos user. See your system administrator. A Kerberos name usually contains three parts. The first is the **primary**, which is usually a user's or service's name. The second is the **instance**, which in the case of a user is usually null. Some users may have privileged instances, however, such as ``root`` or ``admin``. In the case of a service, the instance is the fully qualified name of the machine on which it runs; i.e. there can be an ssh service running on the machine ABC (ssh/ABC@REALM), which is different from the ssh service running on the machine XYZ (ssh/XYZ@REALM). The third part of a Kerberos name is the **realm**. The realm corresponds to the Kerberos service providing authentication for the principal. Realms are conventionally all-uppercase, and often match the end of hostnames in the realm (for instance, host01.example.com might be in realm EXAMPLE.COM). When writing a Kerberos name, the principal name is separated from the instance (if not null) by a slash, and the realm (if not the local realm) follows, preceded by an "@" sign. The following are examples of valid Kerberos names:: david jennifer/admin joeuser@BLEEP.COM cbrown/root@FUBAR.ORG When you authenticate yourself with Kerberos you get an initial Kerberos **ticket**. (A Kerberos ticket is an encrypted protocol message that provides authentication.) Kerberos uses this ticket for network utilities such as ssh. The ticket transactions are done transparently, so you don't have to worry about their management. Note, however, that tickets expire. Administrators may configure more privileged tickets, such as those with service or instance of ``root`` or ``admin``, to expire in a few minutes, while tickets that carry more ordinary privileges may be good for several hours or a day. If your login session extends beyond the time limit, you will have to re-authenticate yourself to Kerberos to get new tickets using the :ref:`kinit(1)` command. Some tickets are **renewable** beyond their initial lifetime. This means that ``kinit -R`` can extend their lifetime without requiring you to re-authenticate. If you wish to delete your local tickets, use the :ref:`kdestroy(1)` command. Kerberos tickets can be forwarded. In order to forward tickets, you must request **forwardable** tickets when you kinit. Once you have forwardable tickets, most Kerberos programs have a command line option to forward them to the remote host. This can be useful for, e.g., running kinit on your local machine and then sshing into another to do work. Note that this should not be done on untrusted machines since they will then have your tickets. ENVIRONMENT VARIABLES --------------------- Several environment variables affect the operation of Kerberos-enabled programs. These include: **KRB5CCNAME** Default name for the credentials cache file, in the form *TYPE*:*residual*. The type of the default cache may determine the availability of a cache collection. ``FILE`` is not a collection type; ``KEYRING``, ``DIR``, and ``KCM`` are. If not set, the value of **default_ccache_name** from configuration files (see **KRB5_CONFIG**) will be used. If that is also not set, the default *type* is ``FILE``, and the *residual* is the path /tmp/krb5cc_*uid*, where *uid* is the decimal user ID of the user. **KRB5_KTNAME** Specifies the location of the default keytab file, in the form *TYPE*:*residual*. If no *type* is present, the **FILE** type is assumed and *residual* is the pathname of the keytab file. If unset, |keytab| will be used. **KRB5_CONFIG** Specifies the location of the Kerberos configuration file. The default is |sysconfdir|\ ``/krb5.conf``. Multiple filenames can be specified, separated by a colon; all files which are present will be read. **KRB5_KDC_PROFILE** Specifies the location of the KDC configuration file, which contains additional configuration directives for the Key Distribution Center daemon and associated programs. The default is |kdcdir|\ ``/kdc.conf``. **KRB5RCACHENAME** (New in release 1.18) Specifies the location of the default replay cache, in the form *type*:*residual*. The ``file2`` type with a pathname residual specifies a replay cache file in the version-2 format in the specified location. The ``none`` type (residual is ignored) disables the replay cache. The ``dfl`` type (residual is ignored) indicates the default, which uses a file2 replay cache in a temporary directory. The default is ``dfl:``. **KRB5RCACHETYPE** Specifies the type of the default replay cache, if **KRB5RCACHENAME** is unspecified. No residual can be specified, so ``none`` and ``dfl`` are the only useful types. **KRB5RCACHEDIR** Specifies the directory used by the ``dfl`` replay cache type. The default is the value of the **TMPDIR** environment variable, or ``/var/tmp`` if **TMPDIR** is not set. **KRB5_TRACE** Specifies a filename to write trace log output to. Trace logs can help illuminate decisions made internally by the Kerberos libraries. For example, ``env KRB5_TRACE=/dev/stderr kinit`` would send tracing information for :ref:`kinit(1)` to ``/dev/stderr``. The default is not to write trace log output anywhere. **KRB5_CLIENT_KTNAME** Default client keytab file name. If unset, |ckeytab| will be used). **KPROP_PORT** :ref:`kprop(8)` port to use. Defaults to 754. **GSS_MECH_CONFIG** Specifies a filename containing GSSAPI mechanism module configuration. The default is to read |sysconfdir|\ ``/gss/mech`` and files with a ``.conf`` suffix within the directory |sysconfdir|\ ``/gss/mech.d``. Most environment variables are disabled for certain programs, such as login system programs and setuid programs, which are designed to be secure when run within an untrusted process environment. SEE ALSO -------- :ref:`kdestroy(1)`, :ref:`kinit(1)`, :ref:`klist(1)`, :ref:`kswitch(1)`, :ref:`kpasswd(1)`, :ref:`ksu(1)`, :ref:`krb5.conf(5)`, :ref:`kdc.conf(5)`, :ref:`kadmin(1)`, :ref:`kadmind(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)` BUGS ---- AUTHORS ------- | Steve Miller, MIT Project Athena/Digital Equipment Corporation | Clifford Neuman, MIT Project Athena | Greg Hudson, MIT Kerberos Consortium | Robbie Harwood, Red Hat, Inc. HISTORY ------- The MIT Kerberos 5 implementation was developed at MIT, with contributions from many outside parties. It is currently maintained by the MIT Kerberos Consortium. RESTRICTIONS ------------ Copyright 1985, 1986, 1989-1996, 2002, 2011, 2018 Masachusetts Institute of Technology krb5-1.22.1/doc/user/user_config/k5identity.rst0000664000175000017500000000414315051422640021214 0ustar ghudsonghudson.. _.k5identity(5): .k5identity =========== DESCRIPTION ----------- The .k5identity file, which resides in a user's home directory, contains a list of rules for selecting a client principals based on the server being accessed. These rules are used to choose a credential cache within the cache collection when possible. Blank lines and lines beginning with ``#`` are ignored. Each line has the form: *principal* *field*\=\ *value* ... If the server principal meets all of the field constraints, then principal is chosen as the client principal. The following fields are recognized: **realm** If the realm of the server principal is known, it is matched against *value*, which may be a pattern using shell wildcards. For host-based server principals, the realm will generally only be known if there is a :ref:`domain_realm` section in :ref:`krb5.conf(5)` with a mapping for the hostname. **service** If the server principal is a host-based principal, its service component is matched against *value*, which may be a pattern using shell wildcards. **host** If the server principal is a host-based principal, its hostname component is converted to lower case and matched against *value*, which may be a pattern using shell wildcards. If the server principal matches the constraints of multiple lines in the .k5identity file, the principal from the first matching line is used. If no line matches, credentials will be selected some other way, such as the realm heuristic or the current primary cache. EXAMPLE ------- The following example .k5identity file selects the client principal ``alice@KRBTEST.COM`` if the server principal is within that realm, the principal ``alice/root@EXAMPLE.COM`` if the server host is within a servers subdomain, and the principal ``alice/mail@EXAMPLE.COM`` when accessing the IMAP service on ``mail.example.com``:: alice@KRBTEST.COM realm=KRBTEST.COM alice/root@EXAMPLE.COM host=*.servers.example.com alice/mail@EXAMPLE.COM host=mail.example.com service=imap SEE ALSO -------- kerberos(1), :ref:`krb5.conf(5)` krb5-1.22.1/doc/user/user_config/index.rst0000664000175000017500000000045515051422640020234 0ustar ghudsonghudsonUser config files ================= The following files in your home directory can be used to control the behavior of Kerberos as it applies to your account (unless they have been disabled by your host's configuration): .. toctree:: :maxdepth: 1 kerberos.rst k5login.rst k5identity.rst krb5-1.22.1/doc/user/tkt_mgmt.rst0000664000175000017500000003047715051422640016457 0ustar ghudsonghudsonTicket management ================= On many systems, Kerberos is built into the login program, and you get tickets automatically when you log in. Other programs, such as ssh, can forward copies of your tickets to a remote host. Most of these programs also automatically destroy your tickets when they exit. However, MIT recommends that you explicitly destroy your Kerberos tickets when you are through with them, just to be sure. One way to help ensure that this happens is to add the :ref:`kdestroy(1)` command to your .logout file. Additionally, if you are going to be away from your machine and are concerned about an intruder using your permissions, it is safest to either destroy all copies of your tickets, or use a screensaver that locks the screen. Kerberos ticket properties -------------------------- There are various properties that Kerberos tickets can have: If a ticket is **forwardable**, then the KDC can issue a new ticket (with a different network address, if necessary) based on the forwardable ticket. This allows for authentication forwarding without requiring a password to be typed in again. For example, if a user with a forwardable TGT logs into a remote system, the KDC could issue a new TGT for that user with the network address of the remote system, allowing authentication on that host to work as though the user were logged in locally. When the KDC creates a new ticket based on a forwardable ticket, it sets the **forwarded** flag on that new ticket. Any tickets that are created based on a ticket with the forwarded flag set will also have their forwarded flags set. A **proxiable** ticket is similar to a forwardable ticket in that it allows a service to take on the identity of the client. Unlike a forwardable ticket, however, a proxiable ticket is only issued for specific services. In other words, a ticket-granting ticket cannot be issued based on a ticket that is proxiable but not forwardable. A **proxy** ticket is one that was issued based on a proxiable ticket. A **postdated** ticket is issued with the invalid flag set. After the starting time listed on the ticket, it can be presented to the KDC to obtain valid tickets. Ticket-granting tickets with the **postdateable** flag set can be used to obtain postdated service tickets. **Renewable** tickets can be used to obtain new session keys without the user entering their password again. A renewable ticket has two expiration times. The first is the time at which this particular ticket expires. The second is the latest possible expiration time for any ticket issued based on this renewable ticket. A ticket with the **initial flag** set was issued based on the authentication protocol, and not on a ticket-granting ticket. Application servers that wish to ensure that the user's key has been recently presented for verification could specify that this flag must be set to accept the ticket. An **invalid** ticket must be rejected by application servers. Postdated tickets are usually issued with this flag set, and must be validated by the KDC before they can be used. A **preauthenticated** ticket is one that was only issued after the client requesting the ticket had authenticated itself to the KDC. The **hardware authentication** flag is set on a ticket which required the use of hardware for authentication. The hardware is expected to be possessed only by the client which requested the tickets. If a ticket has the **transit policy** checked flag set, then the KDC that issued this ticket implements the transited-realm check policy and checked the transited-realms list on the ticket. The transited-realms list contains a list of all intermediate realms between the realm of the KDC that issued the first ticket and that of the one that issued the current ticket. If this flag is not set, then the application server must check the transited realms itself or else reject the ticket. The **okay as delegate** flag indicates that the server specified in the ticket is suitable as a delegate as determined by the policy of that realm. Some client applications may use this flag to decide whether to forward tickets to a remote host, although many applications do not honor it. An **anonymous** ticket is one in which the named principal is a generic principal for that realm; it does not actually specify the individual that will be using the ticket. This ticket is meant only to securely distribute a session key. .. _obtain_tkt: Obtaining tickets with kinit ---------------------------- If your site has integrated Kerberos V5 with the login system, you will get Kerberos tickets automatically when you log in. Otherwise, you may need to explicitly obtain your Kerberos tickets, using the :ref:`kinit(1)` program. Similarly, if your Kerberos tickets expire, use the kinit program to obtain new ones. To use the kinit program, simply type ``kinit`` and then type your password at the prompt. For example, Jennifer (whose username is ``jennifer``) works for Bleep, Inc. (a fictitious company with the domain name mit.edu and the Kerberos realm ATHENA.MIT.EDU). She would type:: shell% kinit Password for jennifer@ATHENA.MIT.EDU: <-- [Type jennifer's password here.] shell% If you type your password incorrectly, kinit will give you the following error message:: shell% kinit Password for jennifer@ATHENA.MIT.EDU: <-- [Type the wrong password here.] kinit: Password incorrect shell% and you won't get Kerberos tickets. By default, kinit assumes you want tickets for your own username in your default realm. Suppose Jennifer's friend David is visiting, and he wants to borrow a window to check his mail. David needs to get tickets for himself in his own realm, EXAMPLE.COM. He would type:: shell% kinit david@EXAMPLE.COM Password for david@EXAMPLE.COM: <-- [Type david's password here.] shell% David would then have tickets which he could use to log onto his own machine. Note that he typed his password locally on Jennifer's machine, but it never went over the network. Kerberos on the local host performed the authentication to the KDC in the other realm. If you want to be able to forward your tickets to another host, you need to request forwardable tickets. You do this by specifying the **-f** option:: shell% kinit -f Password for jennifer@ATHENA.MIT.EDU: <-- [Type your password here.] shell% Note that kinit does not tell you that it obtained forwardable tickets; you can verify this using the :ref:`klist(1)` command (see :ref:`view_tkt`). Normally, your tickets are good for your system's default ticket lifetime, which is ten hours on many systems. You can specify a different ticket lifetime with the **-l** option. Add the letter **s** to the value for seconds, **m** for minutes, **h** for hours, or **d** for days. For example, to obtain forwardable tickets for ``david@EXAMPLE.COM`` that would be good for three hours, you would type:: shell% kinit -f -l 3h david@EXAMPLE.COM Password for david@EXAMPLE.COM: <-- [Type david's password here.] shell% .. note:: You cannot mix units; specifying a lifetime of 3h30m would result in an error. Note also that most systems specify a maximum ticket lifetime. If you request a longer ticket lifetime, it will be automatically truncated to the maximum lifetime. .. _view_tkt: Viewing tickets with klist -------------------------- The :ref:`klist(1)` command shows your tickets. When you first obtain tickets, you will have only the ticket-granting ticket. The listing would look like this:: shell% klist Ticket cache: /tmp/krb5cc_ttypa Default principal: jennifer@ATHENA.MIT.EDU Valid starting Expires Service principal 06/07/04 19:49:21 06/08/04 05:49:19 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU shell% The ticket cache is the location of your ticket file. In the above example, this file is named ``/tmp/krb5cc_ttypa``. The default principal is your Kerberos principal. The "valid starting" and "expires" fields describe the period of time during which the ticket is valid. The "service principal" describes each ticket. The ticket-granting ticket has a first component ``krbtgt``, and a second component which is the realm name. Now, if ``jennifer`` connected to the machine ``daffodil.mit.edu``, and then typed "klist" again, she would have gotten the following result:: shell% klist Ticket cache: /tmp/krb5cc_ttypa Default principal: jennifer@ATHENA.MIT.EDU Valid starting Expires Service principal 06/07/04 19:49:21 06/08/04 05:49:19 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU 06/07/04 20:22:30 06/08/04 05:49:19 host/daffodil.mit.edu@ATHENA.MIT.EDU shell% Here's what happened: when ``jennifer`` used ssh to connect to the host ``daffodil.mit.edu``, the ssh program presented her ticket-granting ticket to the KDC and requested a host ticket for the host ``daffodil.mit.edu``. The KDC sent the host ticket, which ssh then presented to the host ``daffodil.mit.edu``, and she was allowed to log in without typing her password. Suppose your Kerberos tickets allow you to log into a host in another domain, such as ``trillium.example.com``, which is also in another Kerberos realm, ``EXAMPLE.COM``. If you ssh to this host, you will receive a ticket-granting ticket for the realm ``EXAMPLE.COM``, plus the new host ticket for ``trillium.example.com``. klist will now show:: shell% klist Ticket cache: /tmp/krb5cc_ttypa Default principal: jennifer@ATHENA.MIT.EDU Valid starting Expires Service principal 06/07/04 19:49:21 06/08/04 05:49:19 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU 06/07/04 20:22:30 06/08/04 05:49:19 host/daffodil.mit.edu@ATHENA.MIT.EDU 06/07/04 20:24:18 06/08/04 05:49:19 krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU 06/07/04 20:24:18 06/08/04 05:49:19 host/trillium.example.com@EXAMPLE.COM shell% Depending on your host's and realm's configuration, you may also see a ticket with the service principal ``host/trillium.example.com@``. If so, this means that your host did not know what realm trillium.example.com is in, so it asked the ``ATHENA.MIT.EDU`` KDC for a referral. The next time you connect to ``trillium.example.com``, the odd-looking entry will be used to avoid needing to ask for a referral again. You can use the **-f** option to view the flags that apply to your tickets. The flags are: ===== ========================= F Forwardable f forwarded P Proxiable p proxy D postDateable d postdated R Renewable I Initial i invalid H Hardware authenticated A preAuthenticated T Transit policy checked O Okay as delegate a anonymous ===== ========================= Here is a sample listing. In this example, the user *jennifer* obtained her initial tickets (**I**), which are forwardable (**F**) and postdated (**d**) but not yet validated (**i**):: shell% klist -f Ticket cache: /tmp/krb5cc_320 Default principal: jennifer@ATHENA.MIT.EDU Valid starting Expires Service principal 31/07/05 19:06:25 31/07/05 19:16:25 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU Flags: FdiI shell% In the following example, the user *david*'s tickets were forwarded (**f**) to this host from another host. The tickets are reforwardable (**F**):: shell% klist -f Ticket cache: /tmp/krb5cc_p11795 Default principal: david@EXAMPLE.COM Valid starting Expires Service principal 07/31/05 11:52:29 07/31/05 21:11:23 krbtgt/EXAMPLE.COM@EXAMPLE.COM Flags: Ff 07/31/05 12:03:48 07/31/05 21:11:23 host/trillium.example.com@EXAMPLE.COM Flags: Ff shell% Destroying tickets with kdestroy -------------------------------- Your Kerberos tickets are proof that you are indeed yourself, and tickets could be stolen if someone gains access to a computer where they are stored. If this happens, the person who has them can masquerade as you until they expire. For this reason, you should destroy your Kerberos tickets when you are away from your computer. Destroying your tickets is easy. Simply type kdestroy:: shell% kdestroy shell% If :ref:`kdestroy(1)` fails to destroy your tickets, it will beep and give an error message. For example, if kdestroy can't find any tickets to destroy, it will give the following message:: shell% kdestroy kdestroy: No credentials cache file found while destroying cache shell% krb5-1.22.1/doc/user/pwd_mgmt.rst0000664000175000017500000001012115051422640016427 0ustar ghudsonghudsonPassword management =================== Your password is the only way Kerberos has of verifying your identity. If someone finds out your password, that person can masquerade as you---send email that comes from you, read, edit, or delete your files, or log into other hosts as you---and no one will be able to tell the difference. For this reason, it is important that you choose a good password, and keep it secret. If you need to give access to your account to someone else, you can do so through Kerberos (see :ref:`grant_access`). You should never tell your password to anyone, including your system administrator, for any reason. You should change your password frequently, particularly any time you think someone may have found out what it is. Changing your password ---------------------- To change your Kerberos password, use the :ref:`kpasswd(1)` command. It will ask you for your old password (to prevent someone else from walking up to your computer when you're not there and changing your password), and then prompt you for the new one twice. (The reason you have to type it twice is to make sure you have typed it correctly.) For example, user ``david`` would do the following:: shell% kpasswd Password for david: <- Type your old password. Enter new password: <- Type your new password. Enter it again: <- Type the new password again. Password changed. shell% If ``david`` typed the incorrect old password, he would get the following message:: shell% kpasswd Password for david: <- Type the incorrect old password. kpasswd: Password incorrect while getting initial ticket shell% If you make a mistake and don't type the new password the same way twice, kpasswd will ask you to try again:: shell% kpasswd Password for david: <- Type the old password. Enter new password: <- Type the new password. Enter it again: <- Type a different new password. kpasswd: Password mismatch while reading password shell% Once you change your password, it takes some time for the change to propagate through the system. Depending on how your system is set up, this might be anywhere from a few minutes to an hour or more. If you need to get new Kerberos tickets shortly after changing your password, try the new password. If the new password doesn't work, try again using the old one. .. _grant_access: Granting access to your account ------------------------------- If you need to give someone access to log into your account, you can do so through Kerberos, without telling the person your password. Simply create a file called :ref:`.k5login(5)` in your home directory. This file should contain the Kerberos principal of each person to whom you wish to give access. Each principal must be on a separate line. Here is a sample .k5login file:: jennifer@ATHENA.MIT.EDU david@EXAMPLE.COM This file would allow the users ``jennifer`` and ``david`` to use your user ID, provided that they had Kerberos tickets in their respective realms. If you will be logging into other hosts across a network, you will want to include your own Kerberos principal in your .k5login file on each of these hosts. Using a .k5login file is much safer than giving out your password, because: * You can take access away any time simply by removing the principal from your .k5login file. * Although the user has full access to your account on one particular host (or set of hosts if your .k5login file is shared, e.g., over NFS), that user does not inherit your network privileges. * Kerberos keeps a log of who obtains tickets, so a system administrator could find out, if necessary, who was capable of using your user ID at a particular time. One common application is to have a .k5login file in root's home directory, giving root access to that machine to the Kerberos principals listed. This allows system administrators to allow users to become root locally, or to log in remotely as root, without their having to give out the root password, and without anyone having to type the root password over the network. Password quality verification ----------------------------- TODO krb5-1.22.1/doc/user/user_commands/0000775000175000017500000000000015051422640016723 5ustar ghudsonghudsonkrb5-1.22.1/doc/user/user_commands/sclient.rst0000664000175000017500000000076115051422640021122 0ustar ghudsonghudson.. _sclient(1): sclient ======= SYNOPSIS -------- **sclient** *remotehost* DESCRIPTION ----------- sclient is a sample application, primarily useful for testing purposes. It contacts a sample server :ref:`sserver(8)` and authenticates to it using Kerberos version 5 tickets, then displays the server's response. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kinit(1)`, :ref:`sserver(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/user/user_commands/krb5-config.rst0000664000175000017500000000456315051422640021573 0ustar ghudsonghudson.. _krb5-config(1): krb5-config =========== SYNOPSIS -------- **krb5-config** [**-**\ **-help** | **-**\ **-all** | **-**\ **-version** | **-**\ **-vendor** | **-**\ **-prefix** | **-**\ **-exec-prefix** | **-**\ **-defccname** | **-**\ **-defktname** | **-**\ **-defcktname** | **-**\ **-cflags** | **-**\ **-libs** [*libraries*]] DESCRIPTION ----------- krb5-config tells the application programmer what flags to use to compile and link programs against the installed Kerberos libraries. OPTIONS ------- **-**\ **-help** prints a usage message. This is the default behavior when no options are specified. **-**\ **-all** prints the version, vendor, prefix, and exec-prefix. **-**\ **-version** prints the version number of the Kerberos installation. **-**\ **-vendor** prints the name of the vendor of the Kerberos installation. **-**\ **-prefix** prints the prefix for which the Kerberos installation was built. **-**\ **-exec-prefix** prints the prefix for executables for which the Kerberos installation was built. **-**\ **-defccname** prints the built-in default credentials cache location. **-**\ **-defktname** prints the built-in default keytab location. **-**\ **-defcktname** prints the built-in default client (initiator) keytab location. **-**\ **-cflags** prints the compilation flags used to build the Kerberos installation. **-**\ **-libs** [*library*] prints the compiler options needed to link against *library*. Allowed values for *library* are: ============ =============================================== krb5 Kerberos 5 applications (default) gssapi GSSAPI applications with Kerberos 5 bindings kadm-client Kadmin client kadm-server Kadmin server kdb Applications that access the Kerberos database ============ =============================================== EXAMPLES -------- krb5-config is particularly useful for compiling against a Kerberos installation that was installed in a non-standard location. For example, a Kerberos installation that is installed in ``/opt/krb5/`` but uses libraries in ``/usr/local/lib/`` for text localization would produce the following output:: shell% krb5-config --libs krb5 -L/opt/krb5/lib -Wl,-rpath -Wl,/opt/krb5/lib -L/usr/local/lib -lkrb5 -lk5crypto -lcom_err SEE ALSO -------- :ref:`kerberos(7)`, cc(1) krb5-1.22.1/doc/user/user_commands/kvno.rst0000664000175000017500000000640215051422640020434 0ustar ghudsonghudson.. _kvno(1): kvno ==== SYNOPSIS -------- **kvno** [**-c** *ccache*] [**-e** *etype*] [**-k** *keytab*] [**-q**] [**-u** | **-S** *sname*] [**-P**] [**--cached-only**] [**--no-store**] [**--out-cache** *cache*] [[{**-F** *cert_file* | {**-I** | **-U**} *for_user*} [**-P**]] | **--u2u** *ccache*] *service1 service2* ... DESCRIPTION ----------- kvno acquires a service ticket for the specified Kerberos principals and prints out the key version numbers of each. OPTIONS ------- **-c** *ccache* Specifies the name of a credentials cache to use (if not the default) **-e** *etype* Specifies the enctype which will be requested for the session key of all the services named on the command line. This is useful in certain backward compatibility situations. **-k** *keytab* Decrypt the acquired tickets using *keytab* to confirm their validity. **-q** Suppress printing output when successful. If a service ticket cannot be obtained, an error message will still be printed and kvno will exit with nonzero status. **-u** Use the unknown name type in requested service principal names. This option Cannot be used with *-S*. **-P** Specifies that the *service1 service2* ... arguments are to be treated as services for which credentials should be acquired using constrained delegation. This option is only valid when used in conjunction with protocol transition. **-S** *sname* Specifies that the *service1 service2* ... arguments are interpreted as hostnames, and the service principals are to be constructed from those hostnames and the service name *sname*. The service hostnames will be canonicalized according to the usual rules for constructing service principals. **-I** *for_user* Specifies that protocol transition (S4U2Self) is to be used to acquire a ticket on behalf of *for_user*. If constrained delegation is not requested, the service name must match the credentials cache client principal. **-U** *for_user* Same as -I, but treats *for_user* as an enterprise name. **-F** *cert_file* Specifies that protocol transition is to be used, identifying the client principal with the X.509 certificate in *cert_file*. The certificate file must be in PEM format. **--cached-only** Only retrieve credentials already present in the cache, not from the KDC. (Added in release 1.19.) **--no-store** Do not store retrieved credentials in the cache. If **--out-cache** is also specified, credentials will still be stored into the output credential cache. (Added in release 1.19.) **--out-cache** *ccache* Initialize *ccache* and store all retrieved credentials into it. Do not store acquired credentials in the input cache. (Added in release 1.19.) **--u2u** *ccache* Requests a user-to-user ticket. *ccache* must contain a local krbtgt ticket for the server principal. The reported version number will typically be 0, as the resulting ticket is not encrypted in the server's long-term key. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| Default location of the credentials cache SEE ALSO -------- :ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/user/user_commands/kinit.rst0000664000175000017500000001636115051422640020602 0ustar ghudsonghudson.. _kinit(1): kinit ===== SYNOPSIS -------- **kinit** [**-V**] [**-l** *lifetime*] [**-s** *start_time*] [**-r** *renewable_life*] [**-p** | -**P**] [**-f** | -**F**] [**-a**] [**-A**] [**-C**] [**-E**] [**-v**] [**-R**] [**-k** [**-i** | -**t** *keytab_file*]] [**-c** *cache_name*] [**-n**] [**-S** *service_name*] [**-I** *input_ccache*] [**-T** *armor_ccache*] [**-X** *attribute*\ [=\ *value*]] [**--request-pac** | **--no-request-pac**] [*principal*] DESCRIPTION ----------- kinit obtains and caches an initial ticket-granting ticket for *principal*. If *principal* is absent, kinit chooses an appropriate principal name based on existing credential cache contents or the local username of the user invoking kinit. Some options modify the choice of principal name. OPTIONS ------- **-V** display verbose output. **-l** *lifetime* (:ref:`duration` string.) Requests a ticket with the lifetime *lifetime*. For example, ``kinit -l 5:30`` or ``kinit -l 5h30m``. If the **-l** option is not specified, the default ticket lifetime (configured by each site) is used. Specifying a ticket lifetime longer than the maximum ticket lifetime (configured by each site) will not override the configured maximum ticket lifetime. **-s** *start_time* (:ref:`duration` string.) Requests a postdated ticket. Postdated tickets are issued with the **invalid** flag set, and need to be resubmitted to the KDC for validation before use. *start_time* specifies the duration of the delay before the ticket can become valid. **-r** *renewable_life* (:ref:`duration` string.) Requests renewable tickets, with a total lifetime of *renewable_life*. **-f** requests forwardable tickets. **-F** requests non-forwardable tickets. **-p** requests proxiable tickets. **-P** requests non-proxiable tickets. **-a** requests tickets restricted to the host's local address[es]. **-A** requests tickets not restricted by address. **-C** requests canonicalization of the principal name, and allows the KDC to reply with a different client principal from the one requested. **-E** treats the principal name as an enterprise name. **-v** requests that the ticket-granting ticket in the cache (with the **invalid** flag set) be passed to the KDC for validation. If the ticket is within its requested time range, the cache is replaced with the validated ticket. **-R** requests renewal of the ticket-granting ticket. Note that an expired ticket cannot be renewed, even if the ticket is still within its renewable life. Note that renewable tickets that have expired as reported by :ref:`klist(1)` may sometimes be renewed using this option, because the KDC applies a grace period to account for client-KDC clock skew. See :ref:`krb5.conf(5)` **clockskew** setting. **-k** [**-i** | **-t** *keytab_file*] requests a ticket, obtained from a key in the local host's keytab. The location of the keytab may be specified with the **-t** *keytab_file* option, or with the **-i** option to specify the use of the default client keytab; otherwise the default keytab will be used. By default, a host ticket for the local host is requested, but any principal may be specified. On a KDC, the special keytab location ``KDB:`` can be used to indicate that kinit should open the KDC database and look up the key directly. This permits an administrator to obtain tickets as any principal that supports authentication based on the key. **-n** Requests anonymous processing. Two types of anonymous principals are supported. For fully anonymous Kerberos, configure pkinit on the KDC and configure **pkinit_anchors** in the client's :ref:`krb5.conf(5)`. Then use the **-n** option with a principal of the form ``@REALM`` (an empty principal name followed by the at-sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. A second form of anonymous tickets is supported; these realm-exposed tickets hide the identity of the client but not the client's realm. For this mode, use ``kinit -n`` with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation. **-I** *input_ccache* Specifies the name of a credentials cache that already contains a ticket. When obtaining that ticket, if information about how that ticket was obtained was also stored to the cache, that information will be used to affect how new credentials are obtained, including preselecting the same methods of authenticating to the KDC. **-T** *armor_ccache* Specifies the name of a credentials cache that already contains a ticket. If supported by the KDC, this cache will be used to armor the request, preventing offline dictionary attacks and allowing the use of additional preauthentication mechanisms. Armoring also makes sure that the response from the KDC is not modified in transit. **-c** *cache_name* use *cache_name* as the Kerberos 5 credentials (ticket) cache location. If this option is not used, the default cache location is used. The default cache location may vary between systems. If the **KRB5CCNAME** environment variable is set, its value is used to locate the default cache. If a principal name is specified and the type of the default cache supports a collection (such as the DIR type), an existing cache containing credentials for the principal is selected or a new one is created and becomes the new primary cache. Otherwise, any existing contents of the default cache are destroyed by kinit. **-S** *service_name* specify an alternate service name to use when getting initial tickets. **-X** *attribute*\ [=\ *value*] specify a pre-authentication *attribute* and *value* to be interpreted by pre-authentication modules. The acceptable attribute and value values vary from module to module. This option may be specified multiple times to specify multiple attributes. If no value is specified, it is assumed to be "yes". The following attributes are recognized by the PKINIT pre-authentication mechanism: **X509_user_identity**\ =\ *value* specify where to find user's X509 identity information **X509_anchors**\ =\ *value* specify where to find trusted X509 anchor information **disable_freshness**\ [**=yes**] disable sending freshness tokens (for testing purposes only) **--request-pac** | **--no-request-pac** mutually exclusive. If **--request-pac** is set, ask the KDC to include a PAC in authdata; if **--no-request-pac** is set, ask the KDC not to include a PAC; if neither are set, the KDC will follow its default, which is typically is to include a PAC if doing so is supported. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| default location of Kerberos 5 credentials cache |keytab| default location for the local host's keytab. SEE ALSO -------- :ref:`klist(1)`, :ref:`kdestroy(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/user/user_commands/kdestroy.rst0000664000175000017500000000325615051422640021327 0ustar ghudsonghudson.. _kdestroy(1): kdestroy ======== SYNOPSIS -------- **kdestroy** [**-A**] [**-q**] [**-c** *cache_name*] [**-p** *princ_name*] DESCRIPTION ----------- The kdestroy utility destroys the user's active Kerberos authorization tickets by overwriting and deleting the credentials cache that contains them. If the credentials cache is not specified, the default credentials cache is destroyed. OPTIONS ------- **-A** Destroys all caches in the collection, if a cache collection is available. May be used with the **-c** option to specify the collection to be destroyed. **-q** Run quietly. Normally kdestroy beeps if it fails to destroy the user's tickets. The **-q** flag suppresses this behavior. **-c** *cache_name* Use *cache_name* as the credentials (ticket) cache name and location; if this option is not used, the default cache name and location are used. The default credentials cache may vary between systems. If the **KRB5CCNAME** environment variable is set, its value is used to name the default ticket cache. **-p** *princ_name* If a cache collection is available, destroy the cache for *princ_name* instead of the primary cache. May be used with the **-c** option to specify the collection to be searched. NOTE ---- Most installations recommend that you place the kdestroy command in your .logout file, so that your tickets are destroyed automatically when you log out. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| Default location of Kerberos 5 credentials cache SEE ALSO -------- :ref:`kinit(1)`, :ref:`klist(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/user/user_commands/kswitch.rst0000664000175000017500000000145015051422640021131 0ustar ghudsonghudson.. _kswitch(1): kswitch ======= SYNOPSIS -------- **kswitch** {**-c** *cachename*\|\ **-p** *principal*} DESCRIPTION ----------- kswitch makes the specified credential cache the primary cache for the collection, if a cache collection is available. OPTIONS ------- **-c** *cachename* Directly specifies the credential cache to be made primary. **-p** *principal* Causes the cache collection to be searched for a cache containing credentials for *principal*. If one is found, that collection is made primary. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| Default location of Kerberos 5 credentials cache SEE ALSO -------- :ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`klist(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/user/user_commands/kpasswd.rst0000664000175000017500000000204315051422640021130 0ustar ghudsonghudson.. _kpasswd(1): kpasswd ======= SYNOPSIS -------- **kpasswd** [*principal*] DESCRIPTION ----------- The kpasswd command is used to change a Kerberos principal's password. kpasswd first prompts for the current Kerberos password, then prompts the user twice for the new password, and the password is changed. If the principal is governed by a policy that specifies the length and/or number of character classes required in the new password, the new password must conform to the policy. (The five character classes are lower case, upper case, numbers, punctuation, and all other characters.) OPTIONS ------- *principal* Change the password for the Kerberos principal principal. Otherwise, kpasswd uses the principal name from an existing ccache if there is one; if not, the principal is derived from the identity of the user invoking the kpasswd command. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`kadmind(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/user/user_commands/ksu.rst0000664000175000017500000003740315051422640020266 0ustar ghudsonghudson.. _ksu(1): ksu === SYNOPSIS -------- **ksu** [ *target_user* ] [ **-n** *target_principal_name* ] [ **-c** *source_cache_name* ] [ **-k** ] [ **-r** time ] [ **-p** | **-P**] [ **-f** | **-F**] [ **-l** *lifetime* ] [ **-z | Z** ] [ **-q** ] [ **-e** *command* [ args ... ] ] [ **-a** [ args ... ] ] REQUIREMENTS ------------ Must have Kerberos version 5 installed to compile ksu. Must have a Kerberos version 5 server running to use ksu. DESCRIPTION ----------- ksu is a Kerberized version of the su program that has two missions: one is to securely change the real and effective user ID to that of the target user, and the other is to create a new security context. .. note:: For the sake of clarity, all references to and attributes of the user invoking the program will start with "source" (e.g., "source user", "source cache", etc.). Likewise, all references to and attributes of the target account will start with "target". AUTHENTICATION -------------- To fulfill the first mission, ksu operates in two phases: authentication and authorization. Resolving the target principal name is the first step in authentication. The user can either specify his principal name with the **-n** option (e.g., ``-n jqpublic@USC.EDU``) or a default principal name will be assigned using a heuristic described in the OPTIONS section (see **-n** option). The target user name must be the first argument to ksu; if not specified root is the default. If ``.`` is specified then the target user will be the source user (e.g., ``ksu .``). If the source user is root or the target user is the source user, no authentication or authorization takes place. Otherwise, ksu looks for an appropriate Kerberos ticket in the source cache. The ticket can either be for the end-server or a ticket granting ticket (TGT) for the target principal's realm. If the ticket for the end-server is already in the cache, it's decrypted and verified. If it's not in the cache but the TGT is, the TGT is used to obtain the ticket for the end-server. The end-server ticket is then verified. If neither ticket is in the cache, but ksu is compiled with the **GET_TGT_VIA_PASSWD** define, the user will be prompted for a Kerberos password which will then be used to get a TGT. If the user is logged in remotely and does not have a secure channel, the password may be exposed. If neither ticket is in the cache and **GET_TGT_VIA_PASSWD** is not defined, authentication fails. AUTHORIZATION ------------- This section describes authorization of the source user when ksu is invoked without the **-e** option. For a description of the **-e** option, see the OPTIONS section. Upon successful authentication, ksu checks whether the target principal is authorized to access the target account. In the target user's home directory, ksu attempts to access two authorization files: :ref:`.k5login(5)` and .k5users. In the .k5login file each line contains the name of a principal that is authorized to access the account. For example:: jqpublic@USC.EDU jqpublic/secure@USC.EDU jqpublic/admin@USC.EDU The format of .k5users is the same, except the principal name may be followed by a list of commands that the principal is authorized to execute (see the **-e** option in the OPTIONS section for details). Thus if the target principal name is found in the .k5login file the source user is authorized to access the target account. Otherwise ksu looks in the .k5users file. If the target principal name is found without any trailing commands or followed only by ``*`` then the source user is authorized. If either .k5login or .k5users exist but an appropriate entry for the target principal does not exist then access is denied. If neither file exists then the principal will be granted access to the account according to the aname->lname mapping rules. Otherwise, authorization fails. EXECUTION OF THE TARGET SHELL ----------------------------- Upon successful authentication and authorization, ksu proceeds in a similar fashion to su. The environment is unmodified with the exception of USER, HOME and SHELL variables. If the target user is not root, USER gets set to the target user name. Otherwise USER remains unchanged. Both HOME and SHELL are set to the target login's default values. In addition, the environment variable **KRB5CCNAME** gets set to the name of the target cache. The real and effective user ID are changed to that of the target user. The target user's shell is then invoked (the shell name is specified in the password file). Upon termination of the shell, ksu deletes the target cache (unless ksu is invoked with the **-k** option). This is implemented by first doing a fork and then an exec, instead of just exec, as done by su. CREATING A NEW SECURITY CONTEXT ------------------------------- ksu can be used to create a new security context for the target program (either the target shell, or command specified via the **-e** option). The target program inherits a set of credentials from the source user. By default, this set includes all of the credentials in the source cache plus any additional credentials obtained during authentication. The source user is able to limit the credentials in this set by using **-z** or **-Z** option. **-z** restricts the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. The **-Z** option provides the target user with a fresh target cache (no creds in the cache). Note that for security reasons, when the source user is root and target user is non-root, **-z** option is the default mode of operation. While no authentication takes place if the source user is root or is the same as the target user, additional tickets can still be obtained for the target cache. If **-n** is specified and no credentials can be copied to the target cache, the source user is prompted for a Kerberos password (unless **-Z** specified or **GET_TGT_VIA_PASSWD** is undefined). If successful, a TGT is obtained from the Kerberos server and stored in the target cache. Otherwise, if a password is not provided (user hit return) ksu continues in a normal mode of operation (the target cache will not contain the desired TGT). If the wrong password is typed in, ksu fails. .. note:: During authentication, only the tickets that could be obtained without providing a password are cached in the source cache. OPTIONS ------- **-n** *target_principal_name* Specify a Kerberos target principal name. Used in authentication and authorization phases of ksu. If ksu is invoked without **-n**, a default principal name is assigned via the following heuristic: * Case 1: source user is non-root. If the target user is the source user the default principal name is set to the default principal of the source cache. If the cache does not exist then the default principal name is set to ``target_user@local_realm``. If the source and target users are different and neither ``~target_user/.k5users`` nor ``~target_user/.k5login`` exist then the default principal name is ``target_user_login_name@local_realm``. Otherwise, starting with the first principal listed below, ksu checks if the principal is authorized to access the target account and whether there is a legitimate ticket for that principal in the source cache. If both conditions are met that principal becomes the default target principal, otherwise go to the next principal. a) default principal of the source cache b) target_user\@local_realm c) source_user\@local_realm If a-c fails try any principal for which there is a ticket in the source cache and that is authorized to access the target account. If that fails select the first principal that is authorized to access the target account from the above list. If none are authorized and ksu is configured with **PRINC_LOOK_AHEAD** turned on, select the default principal as follows: For each candidate in the above list, select an authorized principal that has the same realm name and first part of the principal name equal to the prefix of the candidate. For example if candidate a) is ``jqpublic@ISI.EDU`` and ``jqpublic/secure@ISI.EDU`` is authorized to access the target account then the default principal is set to ``jqpublic/secure@ISI.EDU``. * Case 2: source user is root. If the target user is non-root then the default principal name is ``target_user@local_realm``. Else, if the source cache exists the default principal name is set to the default principal of the source cache. If the source cache does not exist, default principal name is set to ``root\@local_realm``. **-c** *source_cache_name* Specify source cache name (e.g., ``-c FILE:/tmp/my_cache``). If **-c** option is not used then the name is obtained from **KRB5CCNAME** environment variable. If **KRB5CCNAME** is not defined the source cache name is set to ``krb5cc_``. The target cache name is automatically set to ``krb5cc_.(gen_sym())``, where gen_sym generates a new number such that the resulting cache does not already exist. For example:: krb5cc_1984.2 **-k** Do not delete the target cache upon termination of the target shell or a command (**-e** command). Without **-k**, ksu deletes the target cache. **-z** Restrict the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. Use the **-n** option if you want the tickets for other then the default principal. Note that the **-z** option is mutually exclusive with the **-Z** option. **-Z** Don't copy any tickets from the source cache to the target cache. Just create a fresh target cache, where the default principal name of the cache is initialized to the target principal name. Note that the **-Z** option is mutually exclusive with the **-z** option. **-q** Suppress the printing of status messages. Ticket granting ticket options: **-l** *lifetime* **-r** *time* **-p** **-P** **-f** **-F** The ticket granting ticket options only apply to the case where there are no appropriate tickets in the cache to authenticate the source user. In this case if ksu is configured to prompt users for a Kerberos password (**GET_TGT_VIA_PASSWD** is defined), the ticket granting ticket options that are specified will be used when getting a ticket granting ticket from the Kerberos server. **-l** *lifetime* (:ref:`duration` string.) Specifies the lifetime to be requested for the ticket; if this option is not specified, the default ticket lifetime (12 hours) is used instead. **-r** *time* (:ref:`duration` string.) Specifies that the **renewable** option should be requested for the ticket, and specifies the desired total lifetime of the ticket. **-p** specifies that the **proxiable** option should be requested for the ticket. **-P** specifies that the **proxiable** option should not be requested for the ticket, even if the default configuration is to ask for proxiable tickets. **-f** option specifies that the **forwardable** option should be requested for the ticket. **-F** option specifies that the **forwardable** option should not be requested for the ticket, even if the default configuration is to ask for forwardable tickets. **-e** *command* [*args* ...] ksu proceeds exactly the same as if it was invoked without the **-e** option, except instead of executing the target shell, ksu executes the specified command. Example of usage:: ksu bob -e ls -lag The authorization algorithm for **-e** is as follows: If the source user is root or source user == target user, no authorization takes place and the command is executed. If source user id != 0, and ``~target_user/.k5users`` file does not exist, authorization fails. Otherwise, ``~target_user/.k5users`` file must have an appropriate entry for target principal to get authorized. The .k5users file format: A single principal entry on each line that may be followed by a list of commands that the principal is authorized to execute. A principal name followed by a ``*`` means that the user is authorized to execute any command. Thus, in the following example:: jqpublic@USC.EDU ls mail /local/kerberos/klist jqpublic/secure@USC.EDU * jqpublic/admin@USC.EDU ``jqpublic@USC.EDU`` is only authorized to execute ``ls``, ``mail`` and ``klist`` commands. ``jqpublic/secure@USC.EDU`` is authorized to execute any command. ``jqpublic/admin@USC.EDU`` is not authorized to execute any command. Note, that ``jqpublic/admin@USC.EDU`` is authorized to execute the target shell (regular ksu, without the **-e** option) but ``jqpublic@USC.EDU`` is not. The commands listed after the principal name must be either a full path names or just the program name. In the second case, **CMD_PATH** specifying the location of authorized programs must be defined at the compilation time of ksu. Which command gets executed? If the source user is root or the target user is the source user or the user is authorized to execute any command (``*`` entry) then command can be either a full or a relative path leading to the target program. Otherwise, the user must specify either a full path or just the program name. **-a** *args* Specify arguments to be passed to the target shell. Note that all flags and parameters following -a will be passed to the shell, thus all options intended for ksu must precede **-a**. The **-a** option can be used to simulate the **-e** option if used as follows:: -a -c [command [arguments]]. **-c** is interpreted by the c-shell to execute the command. INSTALLATION INSTRUCTIONS ------------------------- ksu can be compiled with the following four flags: **GET_TGT_VIA_PASSWD** In case no appropriate tickets are found in the source cache, the user will be prompted for a Kerberos password. The password is then used to get a ticket granting ticket from the Kerberos server. The danger of configuring ksu with this macro is if the source user is logged in remotely and does not have a secure channel, the password may get exposed. **PRINC_LOOK_AHEAD** During the resolution of the default principal name, **PRINC_LOOK_AHEAD** enables ksu to find principal names in the .k5users file as described in the OPTIONS section (see **-n** option). **CMD_PATH** Specifies a list of directories containing programs that users are authorized to execute (via .k5users file). **HAVE_GETUSERSHELL** If the source user is non-root, ksu insists that the target user's shell to be invoked is a "legal shell". *getusershell(3)* is called to obtain the names of "legal shells". Note that the target user's shell is obtained from the passwd file. Sample configuration:: KSU_OPTS = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /usr/ucb /local/bin" ksu should be owned by root and have the set user id bit turned on. ksu attempts to get a ticket for the end server just as Kerberized telnet and rlogin. Thus, there must be an entry for the server in the Kerberos database (e.g., ``host/nii.isi.edu@ISI.EDU``). The keytab file must be in an appropriate location. SIDE EFFECTS ------------ ksu deletes all expired tickets from the source cache. AUTHOR OF KSU ------------- GENNADY (ARI) MEDVINSKY ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kerberos(7)`, :ref:`kinit(1)` krb5-1.22.1/doc/user/user_commands/index.rst0000664000175000017500000000032015051422640020557 0ustar ghudsonghudson.. _user_commands: User commands ============= .. toctree:: :maxdepth: 1 kdestroy.rst kinit.rst klist.rst kpasswd.rst krb5-config.rst ksu.rst kswitch.rst kvno.rst sclient.rst krb5-1.22.1/doc/user/user_commands/klist.rst0000664000175000017500000000555715051422640020617 0ustar ghudsonghudson.. _klist(1): klist ===== SYNOPSIS -------- **klist** [**-e**] [[**-c**] [**-l**] [**-A**] [**-f**] [**-s**] [**-a** [**-n**]]] [**-C**] [**-k** [**-i**] [**-t**] [**-K**]] [**-V**] [**-d**] [*cache_name*\|\ *keytab_name*] DESCRIPTION ----------- klist lists the Kerberos principal and Kerberos tickets held in a credentials cache, or the keys held in a keytab file. OPTIONS ------- **-e** Displays the encryption types of the session key and the ticket for each credential in the credential cache, or each key in the keytab file. **-l** If a cache collection is available, displays a table summarizing the caches present in the collection. **-A** If a cache collection is available, displays the contents of all of the caches in the collection. **-c** List tickets held in a credentials cache. This is the default if neither **-c** nor **-k** is specified. **-f** Shows the flags present in the credentials, using the following abbreviations:: F Forwardable f forwarded P Proxiable p proxy D postDateable d postdated R Renewable I Initial i invalid H Hardware authenticated A preAuthenticated T Transit policy checked O Okay as delegate a anonymous **-s** Causes klist to run silently (produce no output). klist will exit with status 1 if the credentials cache cannot be read or is expired, and with status 0 otherwise. **-a** Display list of addresses in credentials. **-n** Show numeric addresses instead of reverse-resolving addresses. **-C** List configuration data that has been stored in the credentials cache when klist encounters it. By default, configuration data is not listed. **-k** List keys held in a keytab file. **-i** In combination with **-k**, defaults to using the default client keytab instead of the default acceptor keytab, if no name is given. **-t** Display the time entry timestamps for each keytab entry in the keytab file. **-K** Display the value of the encryption key in each keytab entry in the keytab file. **-d** Display the authdata types (if any) for each entry. **-V** Display the Kerberos version number and exit. If *cache_name* or *keytab_name* is not specified, klist will display the credentials in the default credentials cache or keytab file as appropriate. If the **KRB5CCNAME** environment variable is set, its value is used to locate the default ticket cache. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| Default location of Kerberos 5 credentials cache |keytab| Default location for the local host's keytab file. SEE ALSO -------- :ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/user/index.rst0000664000175000017500000000020715051422640015724 0ustar ghudsonghudsonFor users ========= .. toctree:: :maxdepth: 2 pwd_mgmt.rst tkt_mgmt.rst user_config/index.rst user_commands/index.rst krb5-1.22.1/doc/conf.py0000664000175000017500000003160515051422640014412 0ustar ghudsonghudson# -*- coding: utf-8 -*- # # MIT Kerberos documentation build configuration file, created by # sphinx-quickstart on Wed Oct 13 09:14:03 2010. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. #extensions = ['sphinx.ext.autodoc', 'sphinxcontrib.doxylink'] extensions = ['sphinx.ext.autodoc'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. if 'notice' in tags: master_doc = 'notice' else: master_doc = 'index' # General information about the project. project = u'MIT Kerberos' copyright = u'1985-2025, MIT' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. exec(open("version.py").read()) # The short X.Y version. r_list = [r_major, r_minor] if r_patch: r_list += [r_patch] version = '.'.join(map(str, r_list)) # The full version, including alpha/beta/rc tags. release = version if r_tail: release += '-' + r_tail # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: today = ' ' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # When we can rely on Sphinx 1.8 (released Sep 2018) we can just set: # html_css_files = ['kerb.css'] # But in the meantime, we add this file using either a way that works # after 1.8 or a way that works before 4.0. def setup(app): if callable(getattr(app, 'add_css_file', None)): app.add_css_file('kerb.css') else: app.add_stylesheet('kerb.css') # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'default' html_theme = 'agogo' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. html_theme_options = { "linkcolor": "#881f0d", "footerbg": "#5d1509", "bgcolor": "#5d1509", "documentwidth": "80%", "pagewidth": "auto", "sidebarwidth": "20%" } # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = "MIT Kerberos Documentation" # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. if os.environ.get('HTML_LOGO'): html_logo = os.environ['HTML_LOGO'] # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. html_split_index = True # If true, links to the reST sources are added to the pages. html_show_sourcelink = False # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g., ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'MIT Kerberos' pointsize = '10pt' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('admin/index', 'admin.tex', u"Kerberos Administration Guide", u'MIT', 'manual'), ('appdev/index', 'appdev.tex', u"Kerberos Application Developer Guide", u'MIT', 'manual'), ('basic/index', 'basic.tex', u"Kerberos Concepts", u'MIT', 'manual'), ('build/index', 'build.tex', u"Building MIT Kerberos", u'MIT', 'manual'), ('plugindev/index', 'plugindev.tex', u"Kerberos Plugin Module Developer Guide", u'MIT', 'manual'), ('user/index', 'user.tex', u"Kerberos User Guide", u'MIT', 'manual') ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True if 'mansubs' in tags: bindir = '``@BINDIR@``' sbindir = '``@SBINDIR@``' libdir = '``@LIBDIR@``' localstatedir = '``@LOCALSTATEDIR@``' runstatedir = '``@RUNSTATEDIR@``' sysconfdir = '``@SYSCONFDIR@``' ccache = '``@CCNAME@``' keytab = '``@KTNAME@``' ckeytab = '``@CKTNAME@``' pkcs11_modname = '``@PKCS11MOD@``' elif 'pathsubs' in tags: # Read configured paths from a file produced by the build system. exec(open("paths.py").read()) else: bindir = ':ref:`BINDIR `' sbindir = ':ref:`SBINDIR `' libdir = ':ref:`LIBDIR `' localstatedir = ':ref:`LOCALSTATEDIR `' runstatedir = ':ref:`RUNSTATEDIR `' sysconfdir = ':ref:`SYSCONFDIR `' ccache = ':ref:`DEFCCNAME `' keytab = ':ref:`DEFKTNAME `' ckeytab = ':ref:`DEFCKTNAME `' pkcs11_modname = ':ref:`PKCS11_MODNAME `' rst_epilog = '\n' if 'notice' in tags: exclude_patterns = [ 'admin', 'appdev', 'basic', 'build', 'formats', 'plugindev', 'user' ] exclude_patterns += [ 'about.rst', 'build_this.rst', 'copyright.rst', 'index.rst', 'mitK5*.rst', 'resources.rst' ] rst_epilog += '.. |copy| replace:: \(C\)' else: exclude_patterns += [ 'notice.rst' ] rst_epilog += '.. |bindir| replace:: %s\n' % bindir rst_epilog += '.. |sbindir| replace:: %s\n' % sbindir rst_epilog += '.. |libdir| replace:: %s\n' % libdir rst_epilog += '.. |kdcdir| replace:: %s\\ ``/krb5kdc``\n' % localstatedir rst_epilog += '.. |kdcrundir| replace:: %s\\ ``/krb5kdc``\n' % runstatedir rst_epilog += '.. |sysconfdir| replace:: %s\n' % sysconfdir rst_epilog += '.. |ccache| replace:: %s\n' % ccache rst_epilog += '.. |keytab| replace:: %s\n' % keytab rst_epilog += '.. |ckeytab| replace:: %s\n' % ckeytab rst_epilog += '.. |pkcs11_modname| replace:: %s\n' % pkcs11_modname rst_epilog += ''' .. |krb5conf| replace:: ``/etc/krb5.conf`` .. |defkeysalts| replace:: ``aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal`` .. |defetypes| replace:: ``aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 aes128-cts-hmac-sha256-128 des3-cbc-sha1 arcfour-hmac-md5 camellia256-cts-cmac camellia128-cts-cmac`` .. |defmkey| replace:: ``aes256-cts-hmac-sha1-96`` .. |copy| unicode:: U+000A9 ''' # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('user/user_commands/kinit', 'kinit', u'obtain and cache Kerberos ticket-granting ticket', [u'MIT'], 1), ('user/user_commands/klist', 'klist', u'list cached Kerberos tickets', [u'MIT'], 1), ('user/user_commands/kdestroy', 'kdestroy', u'destroy Kerberos tickets', [u'MIT'], 1), ('user/user_commands/kswitch', 'kswitch', u'switch primary ticket cache', [u'MIT'], 1), ('user/user_commands/kpasswd', 'kpasswd', u'change a user\'s Kerberos password', [u'MIT'], 1), ('user/user_commands/kvno', 'kvno', u'print key version numbers of Kerberos principals', [u'MIT'], 1), ('user/user_commands/ksu', 'ksu', u'Kerberized super-user', [u'MIT'], 1), ('user/user_commands/krb5-config', 'krb5-config', u'tool for linking against MIT Kerberos libraries', [u'MIT'], 1), ('user/user_config/k5login', 'k5login', u'Kerberos V5 acl file for host access', [u'MIT'], 5), ('user/user_config/k5identity', 'k5identity', u'Kerberos V5 client principal selection rules', [u'MIT'], 5), ('user/user_config/kerberos', 'kerberos', u'Overview of using Kerberos', [u'MIT'], 7), ('admin/admin_commands/krb5kdc', 'krb5kdc', u'Kerberos V5 KDC', [u'MIT'], 8), ('admin/admin_commands/kadmin_local', 'kadmin', u'Kerberos V5 database administration program', [u'MIT'], 1), ('admin/admin_commands/kprop', 'kprop', u'propagate a Kerberos V5 principal database to a replica server', [u'MIT'], 8), ('admin/admin_commands/kproplog', 'kproplog', u'display the contents of the Kerberos principal update log', [u'MIT'], 8), ('admin/admin_commands/kpropd', 'kpropd', u'Kerberos V5 replica KDC update server', [u'MIT'], 8), ('admin/admin_commands/kdb5_util', 'kdb5_util', u'Kerberos database maintenance utility', [u'MIT'], 8), ('admin/admin_commands/ktutil', 'ktutil', u'Kerberos keytab file maintenance utility', [u'MIT'], 1), ('admin/admin_commands/k5srvutil', 'k5srvutil', u'host key table (keytab) manipulation utility', [u'MIT'], 1), ('admin/admin_commands/kadmind', 'kadmind', u'KADM5 administration server', [u'MIT'], 8), ('admin/admin_commands/kdb5_ldap_util', 'kdb5_ldap_util', u'Kerberos configuration utility', [u'MIT'], 8), ('admin/conf_files/krb5_conf', 'krb5.conf', u'Kerberos configuration file', [u'MIT'], 5), ('admin/conf_files/kdc_conf', 'kdc.conf', u'Kerberos V5 KDC configuration file', [u'MIT'], 5), ('admin/conf_files/kadm5_acl', 'kadm5.acl', u'Kerberos ACL file', [u'MIT'], 5), ('user/user_commands/sclient', 'sclient', u'sample Kerberos version 5 client', [u'MIT'], 1), ('admin/admin_commands/sserver', 'sserver', u'sample Kerberos version 5 server', [u'MIT'], 8), ] krb5-1.22.1/doc/rpc/0000775000175000017500000000000015051422640013672 5ustar ghudsonghudsonkrb5-1.22.1/doc/rpc/design.tex0000664000175000017500000012571615051422640015701 0ustar ghudsonghudson\documentstyle[fullpage,12pt]{article} \title{GSS-API Extensions to Sun RPC} \date{Draft---\today} \author{Barry Jaspan} \setlength{\parskip}{.7\baselineskip} \setlength{\parindent}{0pt} \makeatletter \newcount\savecnt\savecnt=0 \def\saveenum#1{\global\savecnt=\csname c@enum#1\endcsname} \def\restoreenum#1{\csname c@enum#1\endcsname=\savecnt} \makeatother %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Make _ actually generate an _, and allow line-breaking after it. \let\underscore=\_ \catcode`_=13 \def_{\underscore\penalty75\relax} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} {\setlength{\parskip}{0pt}\maketitle\tableofcontents} \section{Introduction} This document describes the integration of GSS-API authentication and security with Sun RPC. \section{Requirements} The requirements of the GSS-API authentication system for Sun RPC are: \begin{enumerate} \item It must provide mutual authentication between RPC clients and servers. \item It must provide for integrity checking and encryption of all procedure arguments and results passed over the network. \saveenum{i} \end{enumerate} The following features are desired, but not mandatory: \begin{enumerate} \restoreenum{i} \item It should provide for integrity checking and encryption of all ``header information'' that specifies the program and procedure being called. \item It should obey the Sun RPC protocol so that clients using it can interoperate with existing servers. In this case, ``interoperate'' means that existing servers will return an error code indicating that they do not understand the authentication flavor, but not that they do not understand the request at all. \item It should require minimal or no changes to the standard Sun RPC programming paradigm for either clients or servers so that existing code can use it with little or no effort. \item It should operate correctly with all the standard Sun RPC transport mechansims (e.g. UDP and TCP). \saveenum{i} \end{enumerate} \section{Functional Specification} This section describes the programmer's interface to the GSS-API authentication flavor. Knowledge of standard Sun RPC programming is assumed. \subsection{Client Side} A RPC client can select the GSS-API authentication flavor in the same way it can select any other authentication flavor, by setting the cl_auth field of the CLIENT structure to the appropriate value: \begin{verbatim} clnt = clnt_create(server_host, PROG_NUM, PROG_VERS, protocol); clnt->cl_auth = auth_gssapi_create(clnt, ...); \end{verbatim} There are two functions that create GSS-API authentication flavor structures for the cl_auth field, auth_gssapi_create and auth_gssapi_create_default. \begin{verbatim} AUTH *auth_gssapi_create(CLIENT *clnt, OM_uint32 *major_status, OM_uint32 *minor_status, gss_cred_id_t claimant_cred_handle, gss_name_t target_name, gss_OID mech_type, int req_flags, int time_req, gss_OID *actual_mech_type, int *ret_flags, OM_uint32 *time_rec); \end{verbatim} auth_gssapi_create creates a GSS-API authentication structure and provides most of the flexibility of gss_init_sec_context. The arguments have the same interpretation as those of gss_init_sec_context with the same name, except: \begin{description} \item[clnt] The CLIENT structure returned by client_create or one of its relatives. It is not modified. \end{description} auth_gssapi_create calls gss_init_sec_context as needed, passing each generated token to and processing each token returned from the RPC server specified by the RPC handle clnt. On return, if major_status is GSS_S_COMPLETE, the context has been established, the returned AUTH structure is valid, and all of the arguments filled in by gss_init_sec_context have the correct values. If major_status is not GSS_S_COMPLETE then it and minor_status contain error codes that can be passed to gss_display_status and the returned value is NULL. \begin{verbatim} AUTH *auth_gssapi_create_default(CLIENT *clnt, char *service_name); \end{verbatim} auth_gssapi_create_default is a shorthand for auth_gssapi_create that attempts to create a context that provides procedure call and result integrity, using the default credentials and GSS-API mechanism. service_name is parsed as a GSS-API ``service'' name and used as the target name. The other arguments to auth_gssapi_create are as follows: \begin{verbatim} auth_gssapi_create(clnt, &dummy, &dummy, GSS_C_NO_CREDENTIAL, target_name, GSS_C_NULL_OID, GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, 0, NULL, NULL, NULL); \end{verbatim} Note that if the underlying default mechanism does not support data integrity (e.g. the trust mechanism), this function will fail. The GSS-API major and minor status codes can be interpreted with auth_gssapi_display_status: \begin{verbatim} void auth_gssapi_display_status(char *msg, OM_uint32 major, OM_uint32 minor); \end{verbatim} All of the error messages associated with the major and minor status are displated on the standard error output, preceeded by the message ``GSS-API authentication error $<$msg$>$:''. \subsection{Server Side} \subsubsection{Service Name Registration} An application server must register the service name(s) that it will use for GSS-API connections before any AUTH_GSSAPI requests will succeed. \begin{verbatim} typedef struct _auth_gssapi_name { char *name; gss_OID type; } auth_gssapi_name; bool_t _svcauth_gssapi_set_names(auth_gssapi_name *names, int num); \end{verbatim} names is an array of name specifications, each of which consists of a null-terminated ASCII representation of a name and the GSS-API name type that should be used to import it with gss_import_name. The name type ``gss_nt_service_name'' is recommended. \subsubsection{Calling Client and Service Identification} Each application server's dispatch function is passed two arguments, the transport mechanism (transp) and the RPC service request (rqstp). If the service request's credential flavor (rq_cred.oa_flavor) is AUTH_GSSAPI (300001)\footnote{The value 4 was originally used, but 300001 has been officially assigned by the IETF.}, then the call has been authenticated. The rq_clntcred field of transp contains the gss_name_t of the authenticated caller and can be passed to gss_display_name to obtain a string represtation or gss_compare_name to compare it with other names. The rq_svccred field of transp contains the GSS-API context established with the caller and can be passed to gss_inquire_context. \subsubsection{Error Logging} An application server can register a function to be called when a failure occurs during GSS-API context establishment with _svcauth_set_log_badauth_func. \begin{verbatim} typedef void (*auth_gssapi_log_badauth_func)(OM_uint32 major, OM_uint32 minor, struct sockaddr_in *raddr, caddr_t data); void _svcauth_set_log_badauth_func(auth_gssapi_log_badauth_func func, caddr_t data); \end{verbatim} The function func is called each time gss_accept_sec_context fails. The major and minor arguments indicate the GSS-API major and minor status codes returned. The raddr field contains the INET socket that the request came from, and the data field contains the data argument of _svcauth_gssapi_set_log_badauth_func. An application server can register a function to be called when an RPC request with an invalid verifier arrives with _svcauth_set_log_badverf_func. \begin{verbatim} typedef void (*auth_gssapi_log_badverf_func)(gss_name_t client, gss_name_t server, struct svc_req *rqst, struct rpc_msg *msg, caddr_t data); void _svcauth_set_log_badverf_func(auth_gssapi_log_badverf_func func, caddr_t data); \end{verbatim} The function specified in func is called each time an invalid verifier is received. The client and server fields identify the (falsely claimed) originating client and the server it originally authenticated to. The raddr and addrlen fields contain the INET socket that the request (claims to have) come from, and data contains the data argument of _svcauth_set_log_badverf_func. \section{Modifications to Sun RPC} The Sun RPC extensible authentication mechanism is designed to allow different authentication systems to be integrated into Sun RPC easily. Unfortunately, it has two drawbacks. First, the existing system has a number of non-general design properties that are intended specifically for Sun's Secure RPC, and second, the existing system has no concept of or ability to perform authentication-flavor-specific operations on function arguments and results passed over the wire. The first problem merely makes the system confusing, since a number of features touted as ``general'' do not make any sense for arbitrary authentication systems. The second problem is more substantial, and can only be corrected by modifications to Sun RPC internals. The following sections describe the necessary modifications to Sun RPC. \subsection{Client Side Authentication, AUTH Structure} The AUTH structure (figure \ref{fig:auth}) encapsulates the data and function pointers for an authentication flavor instance. It has been changed in two ways. \begin{figure}[htbp] \begin{verbatim} typedef struct { struct opaque_auth ah_cred; struct opaque_auth ah_verf; union des_block ah_key; struct auth_ops { void (*ah_nextverf)(); int (*ah_marshal)(); /* nextverf & serialize */ int (*ah_validate)(); /* validate varifier */ int (*ah_refresh)(); /* refresh credentials */ int (*ah_wrap)(); /* encode data for wire */ int (*ah_unwrap)(); /* decode data from wire */ void (*ah_destroy)(); /* destroy this structure */ } *ah_ops; caddr_t ah_private; } AUTH; \end{verbatim} \caption{The AUTH structure, with the new function pointers ah_wrap and ah_unwrap.} \label{fig:auth} \end{figure} First, the new functions ah_wrap and ah_unwrap prepare function arguments and results for transmission over the wire. The authentication mechanism can use them to sign, encrypt, or perform any other operation on the data. Their prototype is: \begin{verbatim} bool_t ah_wrap(AUTH *auth, XDR *out_xdrs, xdrproc_t func, caddr_t ptr); bool_t ah_unwrap(AUTH *auth, XDR *in_xdrs, xdrproc_t func, caddr_t ptr); \end{verbatim} ah_wrap encodes function arguments for transmission. func and ptr are the XDR procedure and pointer that serialize the arguments, and out_xdrs is the xdr stream that the encoded arguments should be written to. ah_unwrap decodes function arguments received from the network. Its arguments are the converse of those to ah_wrap. It is the responsibility of RPC transport mechanisms to call an authorization flavor's ah_wrap and ah_unwrap functions when function arguments or results would normally be written to or read from the wire. Authorization flavors that do not need to perform any encoding or decoding can use the provided function authany_wrap for ah_wrap and ah_unwrap; it consists of the single statement ``return (*func)(out_xdrs, ptr)'' (or in_xdrs, as appropriate). Second, the function ah_refresh has been changed to take the RPC error message that resulted in its being called as an argument. This is necessary since the contents of the error message may dictate how ah_refresh should go about correcting the authentication failure. \subsection{Client Side Transport Mechanisms} Each client side transport mechanism must be modified to call the ah_wrap and ah_unwrap functions from the cl_auth field of the CLIENT structure during the call and reply process. The modification is fairly simple. For example, the UDP transport mechanism used to encode procedure calls like this: \begin{verbatim} if ((! XDR_PUTLONG(xdrs, (long *)&proc)) || (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || (! (*xargs)(xdrs, argsp))) return (cu->cu_error.re_status = RPC_CANTENCODEARGS); \end{verbatim} The last function call in the conditional serializes the arguments onto the xdr stream. This must be replaced with a call to the appropriate ah_wrap function: \begin{verbatim} if ((! XDR_PUTLONG(xdrs, (long *)&proc)) || (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || (! AUTH_WRAP(cl->cl_auth, xdrs, xargs, argsp))) return (cu->cu_error.re_status = RPC_CANTENCODEARGS); \end{verbatim} AUTH_WRAP is a macro that takes the four arguments for an ah_wrap function and extracts and calls the function pointer from the cl_auth structure with the specified arguments. Similarly, the transport mechanism must unwrap procedure results. Again, the UDP mechanism will be instructive. It used to deserialize function results like this: \begin{verbatim} reply_msg.acpted_rply.ar_results.where = resultsp; reply_msg.acpted_rply.ar_results.proc = xresults; ok = xdr_replymsg(&reply_xdrs, &reply_msg); \end{verbatim} The problem here is that xdr_replymsg deserializes an entire reply message, including the results. Since xresults and resultsp are the function and pointer to decode the results, they will be automatically deserialized {\it without} ah_unwrap being invoked. The simplest solution (which is also the normal method used by the TCP mechanism) is to arrange to deserialize the function results explicitly: \begin{verbatim} reply_msg.acpted_rply.ar_results.where = NULL; reply_msg.acpted_rply.ar_results.proc = xdr_void; if ((! xdr_replymsg(&reply_xdrs, &reply_msg)) || (! AUTH_UNWRAP(cl->cl_auth, reply_xdrs, xresults, resultsp))) { return (cu->cu_error.re_status = RPC_CANTENCODEARGS); } \end{verbatim} Since xdr_void does not read any data from the XDR stream, the function results are still available when AUTH_UNWRAP is called. Note that AUTH_UNWRAP should only be called on {\it successful} calls; if the reply message status is not RPC_SUCCESS there are no arguments to read. Currently, the UDP and TCP transport mechanisms has been converted.\footnote{The ``raw'' mechanism, for direct connections, has not been.} \subsection{Service Side Authentication, SVCAUTH and XPRT} Standard Sun RPC service-side authentication consists of a single function per authentication flavor; there is no concept of an AUTH structure containing function pointers and private data as with the client side. Previously, nothing else was necessary, because each flavor only did a single thing (authenticated individual calls in a stateless manner). More functions and state are now required, however; they are stored in the SVCAUTH structure, see figure \ref{fig:svcauth}. \begin{figure}[htbp] \begin{verbatim} typedef struct { struct svc_auth_ops { int (*svc_ah_wrap)(); int (*svc_ah_unwrap)(); } *svc_ah_ops; caddr_t svc_ah_private; } SVCAUTH; \end{verbatim} \caption{The new SVCAUTH structure.} \label{fig:svcauth} \end{figure} There is one SVCAUTH structure per authentication flavor (there is a default, svc_auth_any, for existing authentication flavors that do not need the extra functionality). The svc_ah_wrap and svc_ah_unwrap perform the same logical function as their client-side counterparts. Just as with the client side, it is the responsibility of the transport mechanism to call the svc_ah_wrap and svc_ah_unwrap functions associated with the authentication flavor associated with each RPC call at the appropriate time. Unfortunately, the transport mechanism code does not have access to the RPC call structure containing the authenticator flavor because the RPC call structure itself is not passed as an argument to the necessary functions. The present solution is to add another argument to the transport mechanism structure, xp_auth, that stores the SVCAUTH of the {\it current} call on that mechanism; see figure \ref{fig:xprt}. xp_auth is initialized to svc_auth_any so that existing authentication mechanisms that do not set the field will still operate correctly. \footnote{This is not an great solution, because it forces each transport mechanism to be single threaded. The correct solution is to store the SVCAUTH associated with each RPC call in the RPC call structure; however, doing so would require changing a lot of code to pass around the RPC call structure that currently does not do so. Since other parts of Sun RPC use the XPRT structure in a non-reentrant way, the present solution does not make the situation any worse.}$^{\mbox{,}}$\footnote{A somewhat irrelevant side effect of adding SVCAUTH to XPRT is that the standard include file $<$rpc/rpc.h$>$ had to be changed to include $<$rpc/svc_auth$>$ before $<$rpc/svc.h$>$, whereas they used to be in the opposite order.} \begin{figure}[htbp] \begin{verbatim} typedef struct { int xp_sock; u_short xp_port; /* associated port number */ struct xp_ops { bool_t (*xp_recv)(); /* receive incomming requests */ enum xprt_stat (*xp_stat)(); /* get transport status */ bool_t (*xp_getargs)(); /* get arguments */ bool_t (*xp_reply)(); /* send reply */ bool_t (*xp_freeargs)();/* free mem allocated for args */ void (*xp_destroy)(); /* destroy this struct */ } *xp_ops; int xp_addrlen; /* length of remote address */ struct sockaddr_in xp_raddr; /* remote address */ struct opaque_auth xp_verf; /* raw response verifier */ SVCAUTH *xp_auth; /* auth flavor of current req */ caddr_t xp_p1; /* private */ caddr_t xp_p2; /* private */ } SVCXPRT; \end{verbatim} \caption{The modified XPRT structure, with the xp_auth field.} \label{fig:xprt} \end{figure} Finally, with the modified XPRT structure carrying around the authentication flavor structure, the functions that serialize and deserialize function arguments and results must be modified to use the svc_ah_wrap and svc_ah_unwrap functions. Each service-side transport mechanism has getargs and reply functions that must be modified to use the SVCAUTH_UNWRAP and SVCAUTH_WRAP macros, respectively, in a manner completely parallel to the client side. \subsection{Authenticated Service Identification, svc_req} Sun RPC provides the authenticated credentials of a client to the application server via rq_clntcred (``cooked credentials'') field of the service request (svc_req) structure. In many authentication systems, services are also named entities, and there is no reason that an RPC should be restricted to accepting connections as a single authenticated service name. However, access control decisions may be based on the service name a client authenticated to, so that information must be available to the application server. Figure \ref{fig:svc-req} shows the modified service request structure that contains a single new field, rq_svccred. Like rq_clntcred, the authentication flavor is responsible for setting rq_svccred to the ``cooked'' service credentials associated with a given RPC call. Authentication flavors that do not have the concept of service names can of course leave this field blank. \begin{figure}[htbp] \begin{verbatim} struct svc_req { u_long rq_prog; /* service program number */ u_long rq_vers; /* service protocol version */ u_long rq_proc; /* the desired procedure */ struct opaque_auth rq_cred; /* raw creds from the wire */ caddr_t rq_clntcred; /* read only cooked client cred */ caddr_t rq_svccred; /* read only cooked svc cred */ SVCXPRT *rq_xprt; /* associated transport */ }; \end{verbatim} \caption{The modified svc_req structure, with the rq_svccred field.} \label{fig:svc-req} \end{figure} \subsection{Authentication Negotiation, no_dispatch} In order to avoid having to transmit a full set of authentication information with every call, the service-side authentication mechanism must save state between calls. Establishing that state may require multiple messages between the client-side and service-side authentication mechanisms. The client-side authentication mechanism can make arbitrary RPC calls to the server simply by requiring the programmer to specify the CLIENT structure to the authentication flavor initialization routine. The service side, however, is more complex. In the normal course of events, an RPC call comes in, is authenticated, and is then dispatched to the appropriate procedure. For client- and service-side authentication flavors to communicate independent of the server implemented above the RPC layer, the service-side flavor must be able to send a reply to the client directly and {\it prevent} the call from being dispatched. This is implemented by a simple modification to the _authenticate routine, which dispatches each RPC call to the appropriate authentication flavor; see figure \ref{fig:authenticate}. It takes an additional argument, no_dispatch, that instructs the mechanism not to dispatch the RPC call to the specified procedure. \begin{figure}[htbp] \begin{verbatim} why=_authenticate(&r, &msg, &no_dispatch); if (why != AUTH_OK) { svcerr_auth(xprt, why); goto call_done; } else if (no_dispatch) { goto call_done; } \end{verbatim} \caption{A call to the modified _authenticate.} \label{fig:authenticate} \end{figure} If _authenticate sets no_dispatch to true, the call is considered finished and no procedure dispatch takes place. Presumably, an authentication flavor that sets no_dispatch to true also replies to the RPC call with svc_sendreply. Authentication flavors that do not modify no_dispatch implicitly leave it set to false, so the normal dispatch takes place. \subsection{Affected Files} Table \ref{tab:modfiles} lists the files that were affected for each of the modifications described in previous sections. \begin{table}[htbp] \centering \caption{Files modified for each change to Sun RPC.} \label{tab:modfiles} \begin{tabular}{ll} AUTH structure & auth.h \\ & auth_none.c \\ & auth_exit.c \\ & auth_any.c \\ Client Transport Mechanisms & clnt_udp.c \\ & clnt_tcp.c \\ SVCAUTH and XPRT structures & rpc.h \\ & svc.h \\ & svc_auth.h \\ & svc.c \\ & svc_auth.c \\ & svc_auth_any.c \\ & svc_auth_unix.c \\ Server Transport Mechanisms & svc_udp.c \\ & svc_tcp.c \end{tabular} \end{table} \section{GSS-API Authentication Flavor} The following sections describe the implementation of the GSS-API authentication flavor for Sun RPC. \subsection{Authentication Algorithms} \label{sec:algorithms} \subsubsection{Context Initiation} The client creates a GSS-API context with the server each time it calls auth_gssapi_create. The context is created using the standard gss_init_sec_context and gss_accept_sec_context function calls. The generated tokens are passed between the client and server as arguments and results of normal RPC calls. The client side, in auth_gssapi_create, performs the following steps to initiate a context: \begin{enumerate} \item\label{item:process-token} The client calls gss_init_sec_context. On the first such call, no input token is provided; on subsequent calls, the token received from the server is provided. \item If gss_init_sec_context produces an output token: \begin{enumerate} \item The client transmits the token to the server, identifying itself with client_handle if it has already been received (see next step). The return value from the server will contain a client_handle and one or both of a token and a signed initial sequence number. \item If this is the first response from the server, the client_handle is stored for subsequent calls. Otherwise, the client_handle should be the same as returned on the previous call. \item If the response contains a signed initian sequence number but the context is not yet established, then the response also contains a token that will established the context. The signed initial sequence number is stored. \item If the response contains a token, step \ref{item:process-token} repeated. \end{enumerate} \item The signed initial sequence number is verified using the established context. \end{enumerate} The server side, in _svcauth_gssapi, performs the following steps to initiate a context: \begin{enumerate} \item If a call arrives with no client_handle, a new client_handle is allocated and stored in the database. Otherwise, the client's previous state is is looked up in the database. \item The received token is passed to gss_accept_sec_context. If an output token is generated, it is returned to the client. Note that since the application server may have registered multiple service names and there is no way to determine {\it a priori} which service a token is for, _svcauth_gssapi calls gss_accept_sec_context once for each registered credential until one of them succeeds. The code assumes that GSS_S_FAILURE is the only error that can result from a credential mismatch, so any other error terminates the loop immediately. \item If the context is established, the server signs an initial sequence number and returns it to the client. \end{enumerate} Note that these algorithms require context establishment to be synchronous. If gss_init_sec_context returns GSS_S_COMPLETE upon processing a token, it will either produce a token or not. If it does, then gss_accept_sec_context will return GSS_S_COMPLETE when that token is processed; if it does not, then gss_accept_sec_context already returned GSS_S_COMPLETE (and presumably returned the token that caused gss_init_sec_context to return GSS_S_COMPLETE when processed). The reverse is also true. \subsubsection{RPC Calls} After the GSS-API context is established, both the server and the client possess a client handle and a corresponding sequence number. Each call from the client contains the client handle as the ``credential'' so that the server can identify which context to apply to the call. Each client call and server response includes a ``verifier'' that contains the sealed current sequence number.\footnote{In a future version, the verifier will also contain a signature block for the call header, including the procedure number called.} The sequence number prevents replay attacks\footnote{Although some GSS-API mechanisms provide replay detection themselves, not all of them do; explicitly including the sequence number in the RPC therefore provides better end-to-end security}, but by itself it does not prevent splicing attacks. Each procedure argument and result block consists of the current sequence number and the actual serialized argument string, all sealed with gss_seal. Combining the sequence number with the argument/result data prevents splicing attacks. The sequence number is incremented by one for each RPC call and by one for each response. The client and server will both reject messages that do not contain the expected sequence number. Packets retransmitted by the client should use the {\it same} sequence number as the original packet, since even if the server receives multiple copies only one will be honored. \subsection{RPC Call Credential Structure} Every message transmitted from the client to the server has a credentials (cb_cred) field of the type auth_gssapi_creds: \begin{verbatim} typedef struct _auth_gssapi_creds { bool_t auth_msg; gss_buffer_desc client_handle; }; \end{verbatim} The auth_msg field indicates whether the message is intended for the authentication mechanism for the actual server. Any message whose auth_msg field is true is processed by the authentication mechanism; any message whose auth_msg is false is passed to the application server's dispatch function if authentication succeeds. All messages must have an auth_msg of true until the context is established, since authentication cannot succeed until it is. The client_handle field contains the client handle obtained from the first call to the server. On the first call, this field is empty. \subsection{GSS-API Authentication Flavor Procedures} The GSS-API authentication flavor uses standard RPC calls over the client handle it is provided for the interactions described in \ref{sec:algorithms}. All of the following procedures require the auth_msg field in the credentials to be true; otherwise, the server-side authentication flavor will simply attempt to authenticate the caller and pass the call to the application server. The server-side authentication flavor uses the no_dispatch variable to indicate that it has handled the call. \subsubsection{AUTH_GSSAPI_INIT, AUTH_GSSAPI_CONTINUE_INIT} Context initiation is performed via AUTH_GSSAPI_INIT and AUTH_GSSAPI_CONTINUE_INIT. The former is used to transfer the first token generated by gss_init_sec_context, when no client handle is included in the credentials; the latter is used on subsequent calls, when a client handle is included. Both procedures take an argument of type auth_gssapi_init_arg and return results of the type auth_gssapi_init_res. \begin{verbatim} typedef struct _auth_gssapi_init_arg { u_long version; gss_buffer_desc token; } auth_gssapi_init_arg; \end{verbatim} \begin{description} \item[version] Three versions are presently defined. \begin{description} \item[1] The original version, as described in this document \item[2] In earlier versions of Secure there was a bug in the GSS-API library that affected the contents of accept_sec_context output tokens. A client specifies version 2 to indicate that it expects the correct (fixed) behavior. If the server indicates AUTH_BADCRED or AUTH_FAILED it does not understand this version, so the client should fall back to version 1. \item[3] Version three indicates that channel bindings are in use. The client must specify channel bindings with the version, and the server will as well. If the server indicates AUTH_BADCRED or AUTH_FAILED it does not understand this version, so the client should fall back to version 2 (and cease specifying channel bindings). \item[4] The previous versions all used the old GSS-API krb5 mechanism oid; this version uses the new one specified in the RFC. \end{description} \item[token] The token field contains the token generated by gss_init_sec_context. \end{description} \begin{verbatim} typedef struct _auth_gssapi_init_res { u_long version; gss_buffer_desc client_handle; gss_buffer_desc token; OM_uint32 gss_major, gss_minor; gss_buffer_desc signed_isn; } auth_gssapi_init_res; \end{verbatim} \begin{description} \item[version] There are two versions currently defined. \begin{description} \item[1] The original version, as described in this document. This is the response version for {\it both} versions 1 and 2. The Secure 1.1 server will always return this version. \item[3] Version three indicates that the server specified channel bindings in response to a call arg version number of three. The server must not specify this version unless the client does. \end{description} \item[client_handle] The client_handle field contains the client handle that the client must use in the credentials field in all subsequent RPC calls. In response to AUTH_GSSAPI_CONTINUE_INIT, it is the same client handle that arrived in the credentials. \item[gss_major, gss_minor] The GSS-API error codes that resulted from processing the auth_gssapi_init_arg. If gss_major is GSS_S_COMPLETE, the argument token was processed successfully. Otherwise, gss_major and gss_minor contain the relevant major and minor status codes, and the context currently being negotiated is no longer valid. \item[token] In any response that the client is expecting another token (i.e.: gss_init_sec_context last returned GSS_S_CONTINUE), the token field contains the output token from gss_accept_sec_context. If the client is not expecting a token and this field is not empty, an error has occurred. \item[signed_isn] If the client is not expecting another token (i.e.: the previous call to gss_init_sec_context yielded a token and returned GSS_S_COMPLETE) or the supplied token completes the context, the signed_isn field contains the signed initial sequence number. The server expects the first RPC call to have a sequence number one greater than the initial sequence number (so that the signed_isn block cannot be replayed). If the client is expecting another token and the signed_isn field is not empty, an error has occurred. \end{description} \subsubsection{AUTH_GSSAPI_DESTROY} Context tear-down is performed via AUTH_GSSAPI_DESTROY. This procedure takes no arguments and returns no results; it merely informs the server that the client wishes to destroy the established context. When a client wishes to tear down an established context between itself and a server, auth_gssapi_destroy first calls the AUTH_GSSAPI_DESTROY procedure. The server authenticates the message and immediately sends a ``success'' response with no results. The client and server then both independently call gss_delete_sec_context and discard the context-destruction token that is generated. No RPC error checking is performed by either the client or the server. The client waits a brief time for a success response from the server, but if none arrives it destroys the context anyway since presumably the user is waiting for the application to exit. The server similar ignores any RPC errors since it knows that the client will ignore any errors that are reported. \subsection{RPC Call Authentication Implementation} Once the context has been established, all subsequent RPC calls are authenticated via the verifier described in section \ref{sec:algorithms}. auth_gssapi_marshall, invoked via AUTH_MARSHALL while the RPC call is being created on the client side, serializes the client_handle obtained during context initiation {\it in plaintext} as the credentials and serializes the current sequence number, sealed with gss_seal, as the verifier. auth_gssapi_wrap, invoked next via AUTH_WRAP, serializes a sealed token containing both the sequence number of the current call and the serialized arguments. _svcauth_gssapi, invoked on the server side by _authenticate, uses the client_handle contained in the credentials to look up the correct context and verifies the sequence number provided in the verifier; if the sequence number is not correct, it declares a potential replay attack.\footnote{Retransmitted packets will appear as replay attacks, of course.} The response verifier is set to the serialized sealed incremented sequence number. svc_auth_gssapi_unwrap, invoked when either the application server or _svcauth_gssapi (in response to an AUTH_GSSAPI authentication flavor message) attempts to read its arguments, deserialzes and unseals the block containing the current sequence number and serialized arguments. If the sequence number is incorrect, it declares a splicing attack; otherwise, it unserializes the arguments into the original structure. svc_auth_gssapi_wrap, invoked when either the application server or _svcauth_gssapi attempts to write its response, performs the same operation as auth_gssapi_wrap. auth_gssapi_validate, invoked by the client-side RPC mechanism when an RPC_SUCCESS response is received, verifies that the returned sequence number is one greater than the previous value sent by auth_gssapi_marshall. Finally, auth_gssapi_unwrap, invoked by the client-side RPC mechanism after auth_gssapi_validate succeeds, performs the same operation as svc_auth_gssapi_unwrap. If an RPC request generates an error message (a status of other than RPC_SUCCESS), auth_gssapi_refresh is called. If the error status is AUTH_REJECTEDVERF, then the server rejected the sequence number as invalid or replayed. The client guesses that, on some previous call, the server received a message but the server's response did not make it back to the client; this could happen if the packet got lost or if the server was being debugged and the client timed out waiting for it. As a result, the server is expected a higher sequence number than the client sent. auth_gssapi_refresh increments the sequence number and returns true so that the call will be tried again. The transport mechanism will only call auth_gssapi_refresh twice for each RPC request, so if some other error occurred an infinite loop will not result; however, it is unlikely the the client and server will be able to resynchronize after such an event. \subsection{Client State Information} The client-side GSS-API authentication flavor maintains an auth_gssapi_data structure for each authentication instance: \begin{verbatim} struct auth_gssapi_data { bool_t established; CLIENT *clnt; gss_ctx_id_t context; gss_buffer_desc client_handle; u_long seq_num; int def_cred; /* pre-serialized ah_cred */ u_char cred_buf[MAX_AUTH_BYTES]; u_long cred_len; }; \end{verbatim} The established field indicates whether the authentication context between the client and server has been established. It is set to true when gss_init_sec_context returns GSS_S_COM\-PLETE. When this field is false, the auth_gssapi functions marshall, validate, wrap, and unwrap mimic the ``no authentication'' flavor since there is no context with which to perform authentication functions.\footnote{This field is necessary because, when auth_gssapi_create calls clnt_call to make an RPC call, it has to have set the client's authentication flavor to AUTH_GSSAPI; otherwise, the service-side RPC mechanism will not know to dispatch the call to _svcauth_gssapi. However, with the client's authentication flavor set, all of the authentication flavor's functions will be automatically invoked, even though they are not ready to operate.} The clnt field contains the RPC client structure that can be used to communicate with the GSS-API authentication flavor on the server. The context field contains the context structure created by gss_init_sec_context. The client_handle field contains the client handle used on all RPC calls except the first one; the handle is obtained as the result of the first call. The sequence_number field contains the sequence number that will be used when transmitting RPC calls to the server and verifying the server's responses after the context is initialized. The def_cred field is true if gss_init_sec_context created a default credential, in which case the authentication mechanism is responsible for releasing the default credential that gets automatically allocated. The cred_buf and cred_len fields contain the pre-serialized credentials structure used in each call. This provides a small performance enhancement since the credentials structure does not change very often; the same pre-serialized version can be used on virtually every call. \subsection{Server State Information} \label{sec:server-state} The server-side GSS-API authentication flavor maintains an svcauth_gssapi_data structure for each established or partially established context: \begin{verbatim} typedef struct _svc_auth_gssapi_data { bool_t established; gss_ctx_id_t context; gss_name_t client_name, server_name; gss_cred_id_t server_creds; u_long expiration; u_long seq_num; u_long key; SVCAUTH svcauth; } svc_auth_gssapi_data; \end{verbatim} The established field indicates whether the context is fully established. The context field contains the context created by gss_accept_sec_context. The client_name field contains the client's authenticated name, as returned by gss_accept_sec_context. _svcauth_gssapi sets the ``cooked credentials'' field of the RPC call structure to this value after the call is authenticated; the application server can use it to perform authorization. The server_name field contains the service name that the client established a context with. This is useful if the application server registered more than one service name with the library; it allows the server to determine which service the client chose. The server_creds field contains the service credentials that the client established a context with. It is used to avoid having to scan through the server_creds_list multiple times in the case that context establishment requires more than one round-trip to the server. The expiration field contains the expiration time of the context, as a Unix timestamp. If a context has no expiration (time_rec is GSS_C_INDEFINITE), the expiration time is set to 24 hours in the future. When the structure is created, before the context is established, the expiration time is initialized to small duration (currently 5 minutes) so that partially created and abandoned contexts will be expired quickly. The seq_num field is the current sequence number for the client. The key field is the client's key into the hash table (see below). The client_handle field sent to the client is the key treated as an arbitrary four-byte string. The svcauth field is a kludge that allows the svc_auth_gssapi functions to access the per-client data structure while processing a call. One SVCAUTH structure is allocated for each client structure, and the svc_ah_private field is set to the corresponding client. The client's svcauth field is then set to the new SVCAUTH structure, so that client_data->svcauth->svc_ah_private == client_data. As each request is processed, the transport mechanism's xp_auth field is set to the client's svcauth field; thus, the server-side functions that dispatch to server-side authentication flavors can access an appropriate SVCAUTH structure, and the server-side authentication function that is called can determine the appropriate per-client structure from the SVCAUTH structure. The per-client structures are all stored both in a BSD 4.4 db library hash table and b-tree. The hash table maps client handles (key fields) the client structures, and is used to look up client structures based on the client_handle field of a call's credentials structure. The b-tree stores the client structures as keys, sorted by their expiration time. Each time _svcauth_gssapi is activated, it traverses the tree and destroys all client structures that have expired. \end{document} krb5-1.22.1/doc/README0000664000175000017500000000453715051422640013777 0ustar ghudsonghudsonBUILDING ======== See doc/build_this.rst for details about how to build the documentation. CONVENTIONS =========== We use the following conventions: * Use four-space indentation where indentation levels are arbitrary. Do not use tabs anywhere. Avoid trailing whitespace at the end of lines or files. * Fill lines to 70 columns (the emacs default) where lines can be wrapped. * For section headers, use === underlines for page titles, --- for sections, ~~~ for subsections, and ### for sub-subsections. Make underlines exactly as long as titles. Do not include trailing punctuation in section headers. Do not capitalize section headers (except for the first word) except in source files intended to generate man pages. * For bullet lists, use * for top-level bullets and - for sub-bullets. Do not indent bullet or enumerated lists relative to the surrounding text. * Use italics (*word*) for words representing variables or parameters. Use boldface (**word**) for command options, subcommands of programs like kadmin, and krb5.conf/kdc.conf parameter names. Use literal text (``text``) for examples and multi-component pathnames. For command names, single-component filenames, and krb5.conf/kdc.conf section names, use references (like :ref:`kadmin(1)`) if introducing them, or just use them unadorned otherwise. * In man pages for commands with subcommands, make a subsection for each subcommand. Start the subcommand with an indented synopsis, then follow with non-indented text describing the subcommand and its options. See kadmin_local.rst for an example. * In man page synopses, put a newline in the RST source before each option. Put all parts of the synopsis at the same indentation level. Ideally we would want a hanging indent to the width of the command or subcommand name, but RST doesn't support that. Use boldface for literal text in the synopsis, italics for variable text, and unadorned text for syntax symbols (such as square brackets to indicate optional parameters). If immediately following one kind of inline markup with another or putting inline markup next to punctuation, you may need to use "\ " as a dummy separator. * For directives that take a content block (e.g., note, error, and warning), leave a blank line before the content block (after any arguments or options that may be present). krb5-1.22.1/doc/doxy_examples/0000775000175000017500000000000015051422640015767 5ustar ghudsonghudsonkrb5-1.22.1/doc/doxy_examples/cc_unique.c0000664000175000017500000000066615051422640020116 0ustar ghudsonghudson/** @example cc_unique.c * * Usage example for krb5_cc_new_unique function */ #include "k5-int.h" krb5_error_code func(krb5_context context) { krb5_error_code ret; krb5_ccache ccache = NULL; ret = krb5_cc_new_unique(context, "MEMORY", NULL, &ccache); if (ret){ ccache = NULL; return ret; } /* do something */ if (ccache) (void)krb5_cc_destroy(context, ccache); return 0; } krb5-1.22.1/doc/doxy_examples/verify_init_creds.c0000664000175000017500000000147015051422640021644 0ustar ghudsonghudson/** @example verify_init_creds.c * * Usage example for krb5_verify_init_creds function family */ #include "k5-int.h" krb5_error_code func(krb5_context context, krb5_creds *creds, krb5_principal server_principal) { krb5_error_code ret = KRB5_OK; krb5_verify_init_creds_opt options; krb5_verify_init_creds_opt_init (&options); krb5_verify_init_creds_opt_set_ap_req_nofail (&options, 1); ret = krb5_verify_init_creds(context, creds, server_principal, NULL /* use default keytab */, NULL /* don't store creds in ccache */, &options); if (ret) { /* error while verifying credentials for server */ } return ret; } krb5-1.22.1/doc/doxy_examples/tkt_creds.c0000664000175000017500000000255215051422640020121 0ustar ghudsonghudson/** @example tkt_creds.c * * Usage example for krb5_tkt_creds function family */ #include "krb5.h" krb5_error_code func(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **out_creds) { krb5_error_code code = KRB5_OK; krb5_creds *ncreds = NULL; krb5_tkt_creds_context ctx = NULL; *out_creds = NULL; /* Allocate a container. */ ncreds = k5alloc(sizeof(*ncreds), &code); if (ncreds == NULL) goto cleanup; /* Make and execute a krb5_tkt_creds context to get the credential. */ code = krb5_tkt_creds_init(context, ccache, in_creds, options, &ctx); if (code != KRB5_OK) goto cleanup; code = krb5_tkt_creds_get(context, ctx); if (code != KRB5_OK) goto cleanup; code = krb5_tkt_creds_get_creds(context, ctx, ncreds); if (code != KRB5_OK) goto cleanup; *out_creds = ncreds; ncreds = NULL; cleanup: krb5_free_creds(context, ncreds); krb5_tkt_creds_free(context, ctx); return code; } /* Allocate zeroed memory; set *code to 0 on success or ENOMEM on failure. */ static inline void * k5alloc(size_t len, krb5_error_code *code) { void *ptr; /* Allocate at least one byte since zero-byte allocs may return NULL. */ ptr = calloc((len > 0) ? len : 1, 1); *code = (ptr == NULL) ? ENOMEM : 0; return ptr; } krb5-1.22.1/doc/doxy_examples/error_message.c0000775000175000017500000000075115051422640020776 0ustar ghudsonghudson/** @example error_message.c * * Demo for krb5_get/set/free_error_message function family */ #include krb5_error_code func(krb5_context context) { krb5_error_code ret; ret = krb5_func(context); if (ret) { const char *err_str = krb5_get_error_message(context, ret); krb5_set_error_message(context, ret, "Failed krb5_func: %s", err_str); krb5_free_error_message(context, err_str); } } krb5-1.22.1/doc/doxy_examples/cc_set_config.c0000664000175000017500000000151115051422640020716 0ustar ghudsonghudson/** @example cc_set_config.c * * Usage examples for krb5_cc_set_config and krb5_cc_get_config functions */ #include krb5_error_code func_set(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *key) { krb5_data config_data; config_data.data = "yes"; config_data.length = strlen(config_data.data); return krb5_cc_set_config(context, id, principal, key, &config_data); } krb5_error_code func_get(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *key) { krb5_data config_data; krb5_error_code ret; config_data.data = NULL; ret = krb5_cc_get_config(context, id, principal, key, &config_data); if (ret){ return ret; } /* do something */ krb5_free_data_contents(context, &config_data); return ret; } krb5-1.22.1/doc/iprop-notes.txt0000664000175000017500000001520615051422640016132 0ustar ghudsonghudsonSome (intentional) changes from Sun's submission are noted in the install guide. Bugs or issues: The "full resync" part of the protocol involves the primary side firing off a normal kprop (and going back to servicing requests), and the replica side stopping all the incremental propagation stuff and waiting for the kprop. If the connection from the primary never comes in for some reason, the replica side just blocks forever, and never resumes incremental propagation. The protocol does not currently pass policy database changes; this was an intentional decision on Sun's part. The policy database is only relevant to the primary KDC, and is usually fairly static (aside from refcount updates), but not propagating it does mean that a replica maintained via iprop can't simply be promoted to a primary in disaster recovery or other cases without doing a full propagation or restoring a database from backups. Shawn had a good suggestion after I started the integration work, and which I haven't had a chance to implement: Make the update-log code fit in as a sort of pseudo-database layer via the DAL, being called through the standard DAL methods, and doing its work around calls through to the real database back end again through the DAL methods. So for example, creating a "iprop+db2" database would create an update log and the real db2 database; storing a principal entry would update the update log as well; etc. At least initially, we wouldn't treat it as a differently-named database; the installation of the hooks would be done by explicitly checking if iprop is enabled, etc. The "iprop role" is assumed to be either primary or replica. The primary writes a log, and the replica fetches it. But what about a cascade propagation model where A sends to B which sends to C, perhaps because A's bandwidth is highly limited, or B and C are co-located? In such a case, B would want to operate in both modes. Granted, with iprop the bandwidth issues should be less important, but there may still be reasons one may wish to run in such a configuration. The propagation of changes does not happen in real time. It's not a "push" protocol; the replicas poll periodically for changes. Perhaps a future revision of the protocol could address that. kadmin/cli/kadmin.c call to kadm5_init_iprop - is this needed in client-side program? Should it be done in libkadm5srv instead as part of the existing kadm5_init* so that database-accessing applications that don't get updated at the source level will automatically start changing the update log as needed? Locking: Currently DAL exports the DB locking interface to the caller; we want to slip the iprop code in between -- run it plus the DB update operation with the DB lock held, whether or not the caller grabbed the lock. (Does the caller always grab the lock before making changes?) Currently we're using a file lock on the update log itself; this will be independent of whether the DB back end implements locking (which may be a good thing or a bad thing, depending). Various logging calls with odd format strings like "" should be fixed. Why are different principal names used, when incremental propagation requires that normal kprop (which uses host principals) be possible anyways? Why is this tied to kadmind, aside from (a) wanting to prevent other db changes, which locking protocols should deal with anyways, (b) existing acl code, (c) existing server process? The incremental propagation protocol requires an ACL entry on the primary, listing the replica. Since the full-resync part uses normal kprop, the replica also has to have an ACL entry for the primary. If this is missing, I suspect the behavior will be that every two minutes, the primary side will (at the prompting of the replica) dump out the database and attempt a full propagation. Possible optimizations: If an existing dump file has a recent enough serial number, just send it, without dumping again? Use just one dump file instead of one per replica? Requiring normal kprop means the replica still can't be behind a NAT or firewall without special configuration. The incremental parts can work in such a configuration, so long as outgoing TCP connections are allowed. Still limited to IPv4 because of limitations in MIT's version of the RPC code. (This could be fixed for kprop, if IPv6 sites want to do full propagation only. Doing incremental propagation over IPv6 will take work on the RPC library, and probably introduce backwards-incompatible ABI changes.) Overflow checks for ulogentries times block size? If file can't be made the size indicated by ulogentries, should we truncate or error out? If we error out, this could blow out when resizing the log because of a too-large log entry. The kprop invocation doesn't specify a realm name, so it'll only work for the default realm. No clean way to specify a port number, either. Would it be overkill to come up with a way to configure host+port for kpropd on the primary? Preferably in a way that'd support cascading propagations. The kadmind process, when it needs to run kprop, extracts the replica host name from the client principal name. It assumes that the principal name will be of the form foo/hostname@REALM, and looks specifically for the "/" and "@" to chop up the string form of the name. If looking up that name won't give a working IPv4 address for the replica, kprop will fail (and kpropd will keep waiting, incremental updates will stop, etc). Mapping between file offsets and structure addresses, we should be careful about alignment. We're probably okay on current platforms, but if we break log-format compatibility with Sun at some point, use the chance to make the kdb_ent_header_t offsets be more strictly aligned in the file. (16 or 32 bytes?) Not thread safe! The kdb5.c code will get a lock on the update log file while making changes, but the lock is per-process. Currently there are no processes I know of that use multiple threads and change the database. (There's the Novell patch to make the KDC multithreaded, but the kdc-kdb-update option doesn't currently compile.) Logging in kpropd is poor to useless. If there are any problems, run it in debug mode ("-d"). You'll still lose all output from the invocation of kdb5_util dump and kprop run out of kadmind. Other man page updates needed: Anything with new -x options. Comments from lha: Verify both client and server are demanding privacy from RPC. Authorization code in check_iprop_rpcsec_auth is weird. Check realm checking, is it trusting the client realm length? What will happen if my realm is named "A" and I can get a cross realm (though multihop) to ATHENA.MIT.EDU's iprop server? Why is the ACL not applied before we get to the functions themselves? krb5-1.22.1/doc/mitK5features.rst0000664000175000017500000007064115051422640016400 0ustar ghudsonghudson.. highlight:: rst .. toctree:: :hidden: mitK5license.rst .. _mitK5features: MIT Kerberos features ===================== https://web.mit.edu/kerberos Quick facts ----------- License - :ref:`mitK5license` Releases: - Latest stable: https://web.mit.edu/kerberos/krb5-1.22/ - Supported: https://web.mit.edu/kerberos/krb5-1.21/ - Release cycle: approximately 12 months Supported platforms \/ OS distributions: - Windows (KfW 4.0): Windows 7, Vista, XP - Solaris: SPARC, x86_64/x86 - GNU/Linux: Debian x86_64/x86, Ubuntu x86_64/x86, RedHat x86_64/x86 - BSD: NetBSD x86_64/x86 Crypto backends: - builtin - MIT Kerberos native crypto library - OpenSSL (1.0\+) - https://www.openssl.org Database backends: LDAP, DB2, LMDB krb4 support: Kerberos 5 release < 1.8 DES support: Kerberos 5 release < 1.18 (See :ref:`retiring-des`) Interoperability ---------------- `Microsoft` Starting from release 1.7: * Follow client principal referrals in the client library when obtaining initial tickets. * KDC can issue realm referrals for service principals based on domain names. * Extensions supporting DCE RPC, including three-leg GSS context setup and unencapsulated GSS tokens inside SPNEGO. * Microsoft GSS_WrapEX, implemented using the gss_iov API, which is similar to the equivalent SSPI functionality. This is needed to support some instances of DCE RPC. * NTLM recognition support in GSS-API, to facilitate dropping in an NTLM implementation for improved compatibility with older releases of Microsoft Windows. * KDC support for principal aliases, if the back end supports them. Currently, only the LDAP back end supports aliases. * Support Microsoft set/change password (:rfc:`3244`) protocol in kadmind. * Implement client and KDC support for GSS_C_DELEG_POLICY_FLAG, which allows a GSS application to request credential delegation only if permitted by KDC policy. Starting from release 1.8: * Microsoft Services for User (S4U) compatibility `Heimdal` * Support for KCM credential cache starting from release 1.13 Feature list ------------ For more information on the specific project see https://k5wiki.kerberos.org/wiki/Projects Release 1.7 - Credentials delegation :rfc:`5896` - Cross-realm authentication and referrals :rfc:`6806` - Master key migration - PKINIT :rfc:`4556` :ref:`pkinit` Release 1.8 - Anonymous PKINIT :rfc:`6112` :ref:`anonymous_pkinit` - Constrained delegation - IAKERB https://tools.ietf.org/html/draft-ietf-krb-wg-iakerb-02 - Heimdal bridge plugin for KDC backend - GSS-API S4U extensions https://msdn.microsoft.com/en-us/library/cc246071 - GSS-API naming extensions :rfc:`6680` - GSS-API extensions for storing delegated credentials :rfc:`5588` Release 1.9 - Advance warning on password expiry - Camellia encryption (CTS-CMAC mode) :rfc:`6803` - KDC support for SecurID preauthentication - kadmin over IPv6 - Trace logging :ref:`trace_logging` - GSSAPI/KRB5 multi-realm support - Plugin to test password quality :ref:`pwqual_plugin` - Plugin to synchronize password changes :ref:`kadm5_hook_plugin` - Parallel KDC - GSS-API extensions for SASL GS2 bridge :rfc:`5801` :rfc:`5587` - Purging old keys - Naming extensions for delegation chain - Password expiration API - Windows client support (build-only) - IPv6 support in iprop Release 1.10 - Plugin interface for configuration :ref:`profile_plugin` - Credentials for multiple identities :ref:`ccselect_plugin` Release 1.11 - Client support for FAST OTP :rfc:`6560` - GSS-API extensions for credential locations - Responder mechanism Release 1.12 - Plugin to control krb5_aname_to_localname and krb5_kuserok behavior :ref:`localauth_plugin` - Plugin to control hostname-to-realm mappings and the default realm :ref:`hostrealm_plugin` - GSSAPI extensions for constructing MIC tokens using IOV lists :ref:`gssapi_mic_token` - Principal may refer to nonexistent policies `Policy Refcount project `_ - Support for having no long-term keys for a principal `Principals Without Keys project `_ - Collection support to the KEYRING credential cache type on Linux :ref:`ccache_definition` - FAST OTP preauthentication module for the KDC which uses RADIUS to validate OTP token values :ref:`otp_preauth` - Experimental Audit plugin for KDC processing `Audit project `_ Release 1.13 - Add support for accessing KDCs via an HTTPS proxy server using the `MS-KKDCP `_ protocol. - Add support for `hierarchical incremental propagation `_, where replicas can act as intermediates between an upstream primary and other downstream replicas. - Add support for configuring GSS mechanisms using ``/etc/gss/mech.d/*.conf`` files in addition to ``/etc/gss/mech``. - Add support to the LDAP KDB module for `binding to the LDAP server using SASL `_. - The KDC listens for TCP connections by default. - Fix a minor key disclosure vulnerability where using the "keepold" option to the kadmin randkey operation could return the old keys. `[CVE-2014-5351] `_ - Add client support for the Kerberos Cache Manager protocol. If the host is running a Heimdal kcm daemon, caches served by the daemon can be accessed with the KCM: cache type. - When built on macOS 10.7 and higher, use "KCM:" as the default cachetype, unless overridden by command-line options or krb5-config values. - Add support for doing unlocked database dumps for the DB2 KDC back end, which would allow the KDC and kadmind to continue accessing the database during lengthy database dumps. Release 1.14 * Administrator experience - Add a new kdb5_util tabdump command to provide reporting-friendly tabular dump formats (tab-separated or CSV) for the KDC database. Unlike the normal dump format, each output table has a fixed number of fields. Some tables include human-readable forms of data that are opaque in ordinary dump files. This format is also suitable for importing into relational databases for complex queries. - Add support to kadmin and kadmin.local for specifying a single command line following any global options, where the command arguments are split by the shell--for example, "kadmin getprinc principalname". Commands issued this way do not prompt for confirmation or display warning messages, and exit with non-zero status if the operation fails. - Accept the same principal flag names in kadmin as we do for the default_principal_flags kdc.conf variable, and vice versa. Also accept flag specifiers in the form that kadmin prints, as well as hexadecimal numbers. - Remove the triple-DES and RC4 encryption types from the default value of supported_enctypes, which determines the default key and salt types for new password-derived keys. By default, keys will only created only for AES128 and AES256. This mitigates some types of password guessing attacks. - Add support for directory names in the KRB5_CONFIG and KRB5_KDC_PROFILE environment variables. - Add support for authentication indicators, which are ticket annotations to indicate the strength of the initial authentication. Add support for the "require_auth" string attribute, which can be set on server principal entries to require an indicator when authenticating to the server. - Add support for key version numbers larger than 255 in keytab files, and for version numbers up to 65535 in KDC databases. - Transmit only one ETYPE-INFO and/or ETYPE-INFO2 entry from the KDC during pre-authentication, corresponding to the client's most preferred encryption type. - Add support for server name identification (SNI) when proxying KDC requests over HTTPS. - Add support for the err_fmt profile parameter, which can be used to generate custom-formatted error messages. * Developer experience: - Change gss_acquire_cred_with_password() to acquire credentials into a private memory credential cache. Applications can use gss_store_cred() to make the resulting credentials visible to other processes. - Change gss_acquire_cred() and SPNEGO not to acquire credentials for IAKERB or for non-standard variants of the krb5 mechanism OID unless explicitly requested. (SPNEGO will still accept the Microsoft variant of the krb5 mechanism OID during negotiation.) - Change gss_accept_sec_context() not to accept tokens for IAKERB or for non-standard variants of the krb5 mechanism OID unless an acceptor credential is acquired for those mechanisms. - Change gss_acquire_cred() to immediately resolve credentials if the time_rec parameter is not NULL, so that a correct expiration time can be returned. Normally credential resolution is delayed until the target name is known. - Add krb5_prepend_error_message() and krb5_wrap_error_message() APIs, which can be used by plugin modules or applications to add prefixes to existing detailed error messages. - Add krb5_c_prfplus() and krb5_c_derive_prfplus() APIs, which implement the RFC 6113 PRF+ operation and key derivation using PRF+. - Add support for pre-authentication mechanisms which use multiple round trips, using the the KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error code. Add get_cookie() and set_cookie() callbacks to the kdcpreauth interface; these callbacks can be used to save marshalled state information in an encrypted cookie for the next request. - Add a client_key() callback to the kdcpreauth interface to retrieve the chosen client key, corresponding to the ETYPE-INFO2 entry sent by the KDC. - Add an add_auth_indicator() callback to the kdcpreauth interface, allowing pre-authentication modules to assert authentication indicators. - Add support for the GSS_KRB5_CRED_NO_CI_FLAGS_X cred option to suppress sending the confidentiality and integrity flags in GSS initiator tokens unless they are requested by the caller. These flags control the negotiated SASL security layer for the Microsoft GSS-SPNEGO SASL mechanism. - Make the FILE credential cache implementation less prone to corruption issues in multi-threaded programs, especially on platforms with support for open file description locks. * Performance: - On replica KDCs, poll the primary KDC immediately after processing a full resync, and do not require two full resyncs after the primary KDC's log file is reset. Release 1.15 * Administrator experience: - Add support to kadmin for remote extraction of current keys without changing them (requires a special kadmin permission that is excluded from the wildcard permission), with the exception of highly protected keys. - Add a lockdown_keys principal attribute to prevent retrieval of the principal's keys (old or new) via the kadmin protocol. In newly created databases, this attribute is set on the krbtgt and kadmin principals. - Restore recursive dump capability for DB2 back end, so sites can more easily recover from database corruption resulting from power failure events. - Add DNS auto-discovery of KDC and kpasswd servers from URI records, in addition to SRV records. URI records can convey TCP and UDP servers and primary KDC status in a single DNS lookup, and can also point to HTTPS proxy servers. - Add support for password history to the LDAP back end. - Add support for principal renaming to the LDAP back end. - Use the getrandom system call on supported Linux kernels to avoid blocking problems when getting entropy from the operating system. * Code quality: - Clean up numerous compilation warnings. - Remove various infrequently built modules, including some preauth modules that were not built by default. * Developer experience: - Add support for building with OpenSSL 1.1. - Use SHA-256 instead of MD5 for (non-cryptographic) hashing of authenticators in the replay cache. This helps sites that must build with FIPS 140 conformant libraries that lack MD5. * Protocol evolution: - Add support for the AES-SHA2 enctypes, which allows sites to conform to Suite B crypto requirements. Release 1.16 * Administrator experience: - The KDC can match PKINIT client certificates against the "pkinit_cert_match" string attribute on the client principal entry, using the same syntax as the existing "pkinit_cert_match" profile option. - The ktutil addent command supports the "-k 0" option to ignore the key version, and the "-s" option to use a non-default salt string. - kpropd supports a --pid-file option to write a pid file at startup, when it is run in standalone mode. - The "encrypted_challenge_indicator" realm option can be used to attach an authentication indicator to tickets obtained using FAST encrypted challenge pre-authentication. - Localization support can be disabled at build time with the --disable-nls configure option. * Developer experience: - The kdcpolicy pluggable interface allows modules control whether tickets are issued by the KDC. - The kadm5_auth pluggable interface allows modules to control whether kadmind grants access to a kadmin request. - The certauth pluggable interface allows modules to control which PKINIT client certificates can authenticate to which client principals. - KDB modules can use the client and KDC interface IP addresses to determine whether to allow an AS request. - GSS applications can query the bit strength of a krb5 GSS context using the GSS_C_SEC_CONTEXT_SASL_SSF OID with gss_inquire_sec_context_by_oid(). - GSS applications can query the impersonator name of a krb5 GSS credential using the GSS_KRB5_GET_CRED_IMPERSONATOR OID with gss_inquire_cred_by_oid(). - kdcpreauth modules can query the KDC for the canonicalized requested client principal name, or match a principal name against the requested client principal name with canonicalization. * Protocol evolution: - The client library will continue to try pre-authentication mechanisms after most failure conditions. - The KDC will issue trivially renewable tickets (where the renewable lifetime is equal to or less than the ticket lifetime) if requested by the client, to be friendlier to scripts. - The client library will use a random nonce for TGS requests instead of the current system time. - For the RC4 string-to-key or PAC operations, UTF-16 is supported (previously only UCS-2 was supported). - When matching PKINIT client certificates, UPN SANs will be matched correctly as UPNs, with canonicalization. * User experience: - Dates after the year 2038 are accepted (provided that the platform time facilities support them), through the year 2106. - Automatic credential cache selection based on the client realm will take into account the fallback realm and the service hostname. - Referral and alternate cross-realm TGTs will not be cached, avoiding some scenarios where they can be added to the credential cache multiple times. - A German translation has been added. * Code quality: - The build is warning-clean under clang with the configured warning options. - The automated test suite runs cleanly under AddressSanitizer. Release 1.17 * Administrator experience: - A new Kerberos database module using the Lightning Memory-Mapped Database library (LMDB) has been added. The LMDB KDB module should be more performant and more robust than the DB2 module, and may become the default module for new databases in a future release. - "kdb5_util dump" will no longer dump policy entries when specific principal names are requested. * Developer experience: - The new krb5_get_etype_info() API can be used to retrieve enctype, salt, and string-to-key parameters from the KDC for a client principal. - The new GSS_KRB5_NT_ENTERPRISE_NAME name type allows enterprise principal names to be used with GSS-API functions. - KDC and kadmind modules which call com_err() will now write to the log file in a format more consistent with other log messages. - Programs which use large numbers of memory credential caches should perform better. * Protocol evolution: - The SPAKE pre-authentication mechanism is now supported. This mechanism protects against password dictionary attacks without requiring any additional infrastructure such as certificates. SPAKE is enabled by default on clients, but must be manually enabled on the KDC for this release. - PKINIT freshness tokens are now supported. Freshness tokens can protect against scenarios where an attacker uses temporary access to a smart card to generate authentication requests for the future. - Password change operations now prefer TCP over UDP, to avoid spurious error messages about replays when a response packet is dropped. - The KDC now supports cross-realm S4U2Self requests when used with a third-party KDB module such as Samba's. The client code for cross-realm S4U2Self requests is also now more robust. * User experience: - The new ktutil addent -f flag can be used to fetch salt information from the KDC for password-based keys. - The new kdestroy -p option can be used to destroy a credential cache within a collection by client principal name. - The Kerberos man page has been restored, and documents the environment variables that affect programs using the Kerberos library. * Code quality: - Python test scripts now use Python 3. - Python test scripts now display markers in verbose output, making it easier to find where a failure occurred within the scripts. - The Windows build system has been simplified and updated to work with more recent versions of Visual Studio. A large volume of unused Windows-specific code has been removed. Visual Studio 2013 or later is now required. Release 1.18 * Administrator experience: - Remove support for single-DES encryption types. - Change the replay cache format to be more efficient and robust. Replay cache filenames using the new format end with ``.rcache2`` by default. - setuid programs will automatically ignore environment variables that normally affect krb5 API functions, even if the caller does not use krb5_init_secure_context(). - Add an ``enforce_ok_as_delegate`` krb5.conf relation to disable credential forwarding during GSSAPI authentication unless the KDC sets the ok-as-delegate bit in the service ticket. * Developer experience: - Implement krb5_cc_remove_cred() for all credential cache types. - Add the krb5_pac_get_client_info() API to get the client account name from a PAC. * Protocol evolution: - Add KDC support for S4U2Self requests where the user is identified by X.509 certificate. (Requires support for certificate lookup from a third-party KDB module.) - Remove support for an old ("draft 9") variant of PKINIT. - Add support for Microsoft NegoEx. (Requires one or more third-party GSS modules implementing NegoEx mechanisms.) * User experience: - Add support for ``dns_canonicalize_hostname=fallback``, causing host-based principal names to be tried first without DNS canonicalization, and again with DNS canonicalization if the un-canonicalized server is not found. - Expand single-component hostnames in hhost-based principal names when DNS canonicalization is not used, adding the system's first DNS search path as a suffix. Add a ``qualify_shortname`` krb5.conf relation to override this suffix or disable expansion. * Code quality: - The libkrb5 serialization code (used to export and import krb5 GSS security contexts) has been simplified and made type-safe. - The libkrb5 code for creating KRB-PRIV, KRB-SAFE, and KRB-CRED messages has been revised to conform to current coding practices. - The test suite has been modified to work with macOS System Integrity Protection enabled. - The test suite incorporates soft-pkcs11 so that PKINIT PKCS11 support can always be tested. Release 1.19 * Administrator experience: - When a client keytab is present, the GSSAPI krb5 mech will refresh credentials even if the current credentials were acquired manually. - It is now harder to accidentally delete the K/M entry from a KDB. * Developer experience: - gss_acquire_cred_from() now supports the "password" and "verify" options, allowing credentials to be acquired via password and verified using a keytab key. - When an application accepts a GSS security context, the new GSS_C_CHANNEL_BOUND_FLAG will be set if the initiator and acceptor both provided matching channel bindings. - Added the GSS_KRB5_NT_X509_CERT name type, allowing S4U2Self requests to identify the desired client principal by certificate. - PKINIT certauth modules can now cause the hw-authent flag to be set in issued tickets. - The krb5_init_creds_step() API will now issue the same password expiration warnings as krb5_get_init_creds_password(). * Protocol evolution: - Added client and KDC support for Microsoft's Resource-Based Constrained Delegation, which allows cross-realm S4U2Proxy requests. A third-party database module is required for KDC support. - kadmin/admin is now the preferred server principal name for kadmin connections, and the host-based form is no longer created by default. The client will still try the host-based form as a fallback. - Added client and server support for Microsoft's KERB_AP_OPTIONS_CBT extension, which causes channel bindings to be required for the initiator if the acceptor provided them. The client will send this option if the client_aware_gss_bindings profile option is set. User experience: - The default setting of dns_canonicalize_realm is now "fallback". Hostnames provided from applications will be tried in principal names as given (possibly with shortname qualification), falling back to the canonicalized name. - kinit will now issue a warning if the des3-cbc-sha1 encryption type is used in the reply. This encryption type will be deprecated and removed in future releases. - Added kvno flags --out-cache, --no-store, and --cached-only (inspired by Heimdal's kgetcred). Release 1.20 * Administrator experience: - Added a "disable_pac" realm relation to suppress adding PAC authdata to tickets, for realms which do not need to support S4U requests. - Most credential cache types will use atomic replacement when a cache is reinitialized using kinit or refreshed from the client keytab. - kprop can now propagate databases with a dump size larger than 4GB, if both the client and server are upgraded. - kprop can now work over NATs that change the destination IP address, if the client is upgraded. * Developer experience: - Updated the KDB interface. The sign_authdata() method is replaced with the issue_pac() method, allowing KDB modules to add logon info and other buffers to the PAC issued by the KDC. - Host-based initiator names are better supported in the GSS krb5 mechanism. * Protocol evolution: - Replaced AD-SIGNEDPATH authdata with minimal PACs. - To avoid spurious replay errors, password change requests will not be attempted over UDP until the attempt over TCP fails. - PKINIT will sign its CMS messages with SHA-256 instead of SHA-1. * Code quality: - Updated all code using OpenSSL to be compatible with OpenSSL 3. - Reorganized the libk5crypto build system to allow the OpenSSL back-end to pull in material from the builtin back-end depending on the OpenSSL version. - Simplified the PRNG logic to always use the platform PRNG. - Converted the remaining Tcl tests to Python. Release 1.21 * User experience: - Added a credential cache type providing compatibility with the macOS 11 native credential cache. * Developer experience: - libkadm5 will use the provided krb5_context object to read configuration values, instead of creating its own. - Added an interface to retrieve the ticket session key from a GSS context. * Protocol evolution: - The KDC will no longer issue tickets with RC4 or triple-DES session keys unless explicitly configured with the new allow_rc4 or allow_des3 variables respectively. - The KDC will assume that all services can handle aes256-sha1 session keys unless the service principal has a session_enctypes string attribute. - Support for PAC full KDC checksums has been added to mitigate an S4U2Proxy privilege escalation attack. - The PKINIT client will advertise a more modern set of supported CMS algorithms. * Code quality: - Removed unused code in libkrb5, libkrb5support, and the PKINIT module. - Modernized the KDC code for processing TGS requests, the code for encrypting and decrypting key data, the PAC handling code, and the GSS library packet parsing and composition code. - Improved the test framework's detection of memory errors in daemon processes when used with asan. Release 1.22 * User experience: - The libdefaults configuration variable "request_timeout" can be set to limit the total timeout for KDC requests. When making a KDC request, the client will now wait indefinitely (or until the request timeout has elapsed) on a KDC which accepts a TCP connection, without contacting any additional KDCs. Clients will make fewer DNS queries in some configurations. - The realm configuration variable "sitename" can be set to cause the client to query site-specific DNS records when making KDC requests. * Administrator experience: - Principal aliases are supported in the DB2 and LMDB KDB modules and in the kadmin protocol. (The LDAP KDB module has supported aliases since release 1.7.) - UNIX domain sockets are supported for the Kerberos and kpasswd protocols. - systemd socket activation is supported for krb5kdc and kadmind. * Developer experience: - KDB modules can be be implemented in terms of other modules using the new krb5_db_load_module() function. - The profile library supports the modification of empty profiles and the copying of modified profiles, making it possible to construct an in-memory profile and pass it to krb5_init_context_profile(). - GSS-API applications can pass the GSS_C_CHANNEL_BOUND flag to gss_init_sec_context() to request strict enforcement of channel bindings by the acceptor. * Protocol evolution: - The PKINIT preauth module supports elliptic curve client certificates, ECDH key exchange, and the Microsoft paChecksum2 field. - The IAKERB implementation has been changed to comply with the most recent draft standard and to support realm discovery. - Message-Authenticator is supported in the RADIUS implementation used by the OTP kdcpreauth module. * Code quality: - Removed old-style function declarations, to accomodate compilers which have removed support for them. - Added OSS-Fuzz to the project's continuous integration infrastructure. - Rewrote the GSS per-message token parsing code for improved safety. `Pre-authentication mechanisms` - PW-SALT :rfc:`4120#section-5.2.7.3` - ENC-TIMESTAMP :rfc:`4120#section-5.2.7.2` - SAM-2 - FAST negotiation framework (release 1.8) :rfc:`6113` - PKINIT with FAST on client (release 1.10) :rfc:`6113` - PKINIT :rfc:`4556` - FX-COOKIE :rfc:`6113#section-5.2` - S4U-X509-USER (release 1.8) https://msdn.microsoft.com/en-us/library/cc246091 - OTP (release 1.12) :ref:`otp_preauth` - SPAKE (release 1.17) :ref:`spake` krb5-1.22.1/doc/pdf/0000775000175000017500000000000015051422775013670 5ustar ghudsonghudsonkrb5-1.22.1/doc/pdf/user.tex0000664000175000017500000033602615051422736015377 0ustar ghudsonghudson%% Generated by Sphinx. \def\sphinxdocclass{report} \documentclass[letterpaper,10pt,english]{sphinxmanual} \ifdefined\pdfpxdimen \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen \fi \sphinxpxdimen=.75bp\relax \ifdefined\pdfimageresolution \pdfimageresolution= \numexpr \dimexpr1in\relax/\sphinxpxdimen\relax \fi %% let collapsible pdf bookmarks panel have high depth per default \PassOptionsToPackage{bookmarksdepth=5}{hyperref} \PassOptionsToPackage{booktabs}{sphinx} \PassOptionsToPackage{colorrows}{sphinx} \PassOptionsToPackage{warn}{textcomp} \usepackage[utf8]{inputenc} \ifdefined\DeclareUnicodeCharacter % support both utf8 and utf8x syntaxes \ifdefined\DeclareUnicodeCharacterAsOptional \def\sphinxDUC#1{\DeclareUnicodeCharacter{"#1}} \else \let\sphinxDUC\DeclareUnicodeCharacter \fi \sphinxDUC{00A0}{\nobreakspace} \sphinxDUC{2500}{\sphinxunichar{2500}} \sphinxDUC{2502}{\sphinxunichar{2502}} \sphinxDUC{2514}{\sphinxunichar{2514}} \sphinxDUC{251C}{\sphinxunichar{251C}} \sphinxDUC{2572}{\textbackslash} \fi \usepackage{cmap} \usepackage[T1]{fontenc} \usepackage{amsmath,amssymb,amstext} \usepackage{babel} \usepackage{tgtermes} \usepackage{tgheros} \renewcommand{\ttdefault}{txtt} \usepackage[Bjarne]{fncychap} \usepackage{sphinx} \fvset{fontsize=auto} \usepackage{geometry} % Include hyperref last. \usepackage{hyperref} % Fix anchor placement for figures with captions. \usepackage{hypcap}% it must be loaded after hyperref. % Set up styles of URL: it should be placed after hyperref. \urlstyle{same} \usepackage{sphinxmessages} \setcounter{tocdepth}{1} \title{Kerberos User Guide} \date{ } \release{1.22.1} \author{MIT} \newcommand{\sphinxlogo}{\vbox{}} \renewcommand{\releasename}{Release} \makeindex \begin{document} \ifdefined\shorthandoff \ifnum\catcode`\=\string=\active\shorthandoff{=}\fi \ifnum\catcode`\"=\active\shorthandoff{"}\fi \fi \pagestyle{empty} \sphinxmaketitle \pagestyle{plain} \sphinxtableofcontents \pagestyle{normal} \phantomsection\label{\detokenize{user/index::doc}} \sphinxstepscope \chapter{Password management} \label{\detokenize{user/pwd_mgmt:password-management}}\label{\detokenize{user/pwd_mgmt::doc}} \sphinxAtStartPar Your password is the only way Kerberos has of verifying your identity. If someone finds out your password, that person can masquerade as you—send email that comes from you, read, edit, or delete your files, or log into other hosts as you—and no one will be able to tell the difference. For this reason, it is important that you choose a good password, and keep it secret. If you need to give access to your account to someone else, you can do so through Kerberos (see {\hyperref[\detokenize{user/pwd_mgmt:grant-access}]{\sphinxcrossref{\DUrole{std,std-ref}{Granting access to your account}}}}). You should never tell your password to anyone, including your system administrator, for any reason. You should change your password frequently, particularly any time you think someone may have found out what it is. \section{Changing your password} \label{\detokenize{user/pwd_mgmt:changing-your-password}} \sphinxAtStartPar To change your Kerberos password, use the {\hyperref[\detokenize{user/user_commands/kpasswd:kpasswd-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kpasswd}}}} command. It will ask you for your old password (to prevent someone else from walking up to your computer when you’re not there and changing your password), and then prompt you for the new one twice. (The reason you have to type it twice is to make sure you have typed it correctly.) For example, user \sphinxcode{\sphinxupquote{david}} would do the following: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kpasswd} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{david}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}} \PYG{n}{Type} \PYG{n}{your} \PYG{n}{old} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Enter} \PYG{n}{new} \PYG{n}{password}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}} \PYG{n}{Type} \PYG{n}{your} \PYG{n}{new} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Enter} \PYG{n}{it} \PYG{n}{again}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}} \PYG{n}{Type} \PYG{n}{the} \PYG{n}{new} \PYG{n}{password} \PYG{n}{again}\PYG{o}{.} \PYG{n}{Password} \PYG{n}{changed}\PYG{o}{.} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar If \sphinxcode{\sphinxupquote{david}} typed the incorrect old password, he would get the following message: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kpasswd} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{david}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}} \PYG{n}{Type} \PYG{n}{the} \PYG{n}{incorrect} \PYG{n}{old} \PYG{n}{password}\PYG{o}{.} \PYG{n}{kpasswd}\PYG{p}{:} \PYG{n}{Password} \PYG{n}{incorrect} \PYG{k}{while} \PYG{n}{getting} \PYG{n}{initial} \PYG{n}{ticket} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar If you make a mistake and don’t type the new password the same way twice, kpasswd will ask you to try again: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kpasswd} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{david}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}} \PYG{n}{Type} \PYG{n}{the} \PYG{n}{old} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Enter} \PYG{n}{new} \PYG{n}{password}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}} \PYG{n}{Type} \PYG{n}{the} \PYG{n}{new} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Enter} \PYG{n}{it} \PYG{n}{again}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}} \PYG{n}{Type} \PYG{n}{a} \PYG{n}{different} \PYG{n}{new} \PYG{n}{password}\PYG{o}{.} \PYG{n}{kpasswd}\PYG{p}{:} \PYG{n}{Password} \PYG{n}{mismatch} \PYG{k}{while} \PYG{n}{reading} \PYG{n}{password} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar Once you change your password, it takes some time for the change to propagate through the system. Depending on how your system is set up, this might be anywhere from a few minutes to an hour or more. If you need to get new Kerberos tickets shortly after changing your password, try the new password. If the new password doesn’t work, try again using the old one. \section{Granting access to your account} \label{\detokenize{user/pwd_mgmt:granting-access-to-your-account}}\label{\detokenize{user/pwd_mgmt:grant-access}} \sphinxAtStartPar If you need to give someone access to log into your account, you can do so through Kerberos, without telling the person your password. Simply create a file called {\hyperref[\detokenize{user/user_config/k5login:k5login-5}]{\sphinxcrossref{\DUrole{std,std-ref}{.k5login}}}} in your home directory. This file should contain the Kerberos principal of each person to whom you wish to give access. Each principal must be on a separate line. Here is a sample .k5login file: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{david}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \end{sphinxVerbatim} \sphinxAtStartPar This file would allow the users \sphinxcode{\sphinxupquote{jennifer}} and \sphinxcode{\sphinxupquote{david}} to use your user ID, provided that they had Kerberos tickets in their respective realms. If you will be logging into other hosts across a network, you will want to include your own Kerberos principal in your .k5login file on each of these hosts. \sphinxAtStartPar Using a .k5login file is much safer than giving out your password, because: \begin{itemize} \item {} \sphinxAtStartPar You can take access away any time simply by removing the principal from your .k5login file. \item {} \sphinxAtStartPar Although the user has full access to your account on one particular host (or set of hosts if your .k5login file is shared, e.g., over NFS), that user does not inherit your network privileges. \item {} \sphinxAtStartPar Kerberos keeps a log of who obtains tickets, so a system administrator could find out, if necessary, who was capable of using your user ID at a particular time. \end{itemize} \sphinxAtStartPar One common application is to have a .k5login file in root’s home directory, giving root access to that machine to the Kerberos principals listed. This allows system administrators to allow users to become root locally, or to log in remotely as root, without their having to give out the root password, and without anyone having to type the root password over the network. \section{Password quality verification} \label{\detokenize{user/pwd_mgmt:password-quality-verification}} \sphinxAtStartPar TODO \sphinxstepscope \chapter{Ticket management} \label{\detokenize{user/tkt_mgmt:ticket-management}}\label{\detokenize{user/tkt_mgmt::doc}} \sphinxAtStartPar On many systems, Kerberos is built into the login program, and you get tickets automatically when you log in. Other programs, such as ssh, can forward copies of your tickets to a remote host. Most of these programs also automatically destroy your tickets when they exit. However, MIT recommends that you explicitly destroy your Kerberos tickets when you are through with them, just to be sure. One way to help ensure that this happens is to add the {\hyperref[\detokenize{user/user_commands/kdestroy:kdestroy-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kdestroy}}}} command to your .logout file. Additionally, if you are going to be away from your machine and are concerned about an intruder using your permissions, it is safest to either destroy all copies of your tickets, or use a screensaver that locks the screen. \section{Kerberos ticket properties} \label{\detokenize{user/tkt_mgmt:kerberos-ticket-properties}} \sphinxAtStartPar There are various properties that Kerberos tickets can have: \sphinxAtStartPar If a ticket is \sphinxstylestrong{forwardable}, then the KDC can issue a new ticket (with a different network address, if necessary) based on the forwardable ticket. This allows for authentication forwarding without requiring a password to be typed in again. For example, if a user with a forwardable TGT logs into a remote system, the KDC could issue a new TGT for that user with the network address of the remote system, allowing authentication on that host to work as though the user were logged in locally. \sphinxAtStartPar When the KDC creates a new ticket based on a forwardable ticket, it sets the \sphinxstylestrong{forwarded} flag on that new ticket. Any tickets that are created based on a ticket with the forwarded flag set will also have their forwarded flags set. \sphinxAtStartPar A \sphinxstylestrong{proxiable} ticket is similar to a forwardable ticket in that it allows a service to take on the identity of the client. Unlike a forwardable ticket, however, a proxiable ticket is only issued for specific services. In other words, a ticket\sphinxhyphen{}granting ticket cannot be issued based on a ticket that is proxiable but not forwardable. \sphinxAtStartPar A \sphinxstylestrong{proxy} ticket is one that was issued based on a proxiable ticket. \sphinxAtStartPar A \sphinxstylestrong{postdated} ticket is issued with the invalid flag set. After the starting time listed on the ticket, it can be presented to the KDC to obtain valid tickets. \sphinxAtStartPar Ticket\sphinxhyphen{}granting tickets with the \sphinxstylestrong{postdateable} flag set can be used to obtain postdated service tickets. \sphinxAtStartPar \sphinxstylestrong{Renewable} tickets can be used to obtain new session keys without the user entering their password again. A renewable ticket has two expiration times. The first is the time at which this particular ticket expires. The second is the latest possible expiration time for any ticket issued based on this renewable ticket. \sphinxAtStartPar A ticket with the \sphinxstylestrong{initial flag} set was issued based on the authentication protocol, and not on a ticket\sphinxhyphen{}granting ticket. Application servers that wish to ensure that the user’s key has been recently presented for verification could specify that this flag must be set to accept the ticket. \sphinxAtStartPar An \sphinxstylestrong{invalid} ticket must be rejected by application servers. Postdated tickets are usually issued with this flag set, and must be validated by the KDC before they can be used. \sphinxAtStartPar A \sphinxstylestrong{preauthenticated} ticket is one that was only issued after the client requesting the ticket had authenticated itself to the KDC. \sphinxAtStartPar The \sphinxstylestrong{hardware authentication} flag is set on a ticket which required the use of hardware for authentication. The hardware is expected to be possessed only by the client which requested the tickets. \sphinxAtStartPar If a ticket has the \sphinxstylestrong{transit policy} checked flag set, then the KDC that issued this ticket implements the transited\sphinxhyphen{}realm check policy and checked the transited\sphinxhyphen{}realms list on the ticket. The transited\sphinxhyphen{}realms list contains a list of all intermediate realms between the realm of the KDC that issued the first ticket and that of the one that issued the current ticket. If this flag is not set, then the application server must check the transited realms itself or else reject the ticket. \sphinxAtStartPar The \sphinxstylestrong{okay as delegate} flag indicates that the server specified in the ticket is suitable as a delegate as determined by the policy of that realm. Some client applications may use this flag to decide whether to forward tickets to a remote host, although many applications do not honor it. \sphinxAtStartPar An \sphinxstylestrong{anonymous} ticket is one in which the named principal is a generic principal for that realm; it does not actually specify the individual that will be using the ticket. This ticket is meant only to securely distribute a session key. \section{Obtaining tickets with kinit} \label{\detokenize{user/tkt_mgmt:obtaining-tickets-with-kinit}}\label{\detokenize{user/tkt_mgmt:obtain-tkt}} \sphinxAtStartPar If your site has integrated Kerberos V5 with the login system, you will get Kerberos tickets automatically when you log in. Otherwise, you may need to explicitly obtain your Kerberos tickets, using the {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}} program. Similarly, if your Kerberos tickets expire, use the kinit program to obtain new ones. \sphinxAtStartPar To use the kinit program, simply type \sphinxcode{\sphinxupquote{kinit}} and then type your password at the prompt. For example, Jennifer (whose username is \sphinxcode{\sphinxupquote{jennifer}}) works for Bleep, Inc. (a fictitious company with the domain name mit.edu and the Kerberos realm ATHENA.MIT.EDU). She would type: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kinit} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{p}{[}\PYG{n}{Type} \PYG{n}{jennifer}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{s password here.]} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar If you type your password incorrectly, kinit will give you the following error message: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kinit} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{p}{[}\PYG{n}{Type} \PYG{n}{the} \PYG{n}{wrong} \PYG{n}{password} \PYG{n}{here}\PYG{o}{.}\PYG{p}{]} \PYG{n}{kinit}\PYG{p}{:} \PYG{n}{Password} \PYG{n}{incorrect} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar and you won’t get Kerberos tickets. \sphinxAtStartPar By default, kinit assumes you want tickets for your own username in your default realm. Suppose Jennifer’s friend David is visiting, and he wants to borrow a window to check his mail. David needs to get tickets for himself in his own realm, EXAMPLE.COM. He would type: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kinit} \PYG{n}{david}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{david}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{p}{[}\PYG{n}{Type} \PYG{n}{david}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{s password here.]} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar David would then have tickets which he could use to log onto his own machine. Note that he typed his password locally on Jennifer’s machine, but it never went over the network. Kerberos on the local host performed the authentication to the KDC in the other realm. \sphinxAtStartPar If you want to be able to forward your tickets to another host, you need to request forwardable tickets. You do this by specifying the \sphinxstylestrong{\sphinxhyphen{}f} option: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kinit} \PYG{o}{\PYGZhy{}}\PYG{n}{f} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{p}{[}\PYG{n}{Type} \PYG{n}{your} \PYG{n}{password} \PYG{n}{here}\PYG{o}{.}\PYG{p}{]} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar Note that kinit does not tell you that it obtained forwardable tickets; you can verify this using the {\hyperref[\detokenize{user/user_commands/klist:klist-1}]{\sphinxcrossref{\DUrole{std,std-ref}{klist}}}} command (see {\hyperref[\detokenize{user/tkt_mgmt:view-tkt}]{\sphinxcrossref{\DUrole{std,std-ref}{Viewing tickets with klist}}}}). \sphinxAtStartPar Normally, your tickets are good for your system’s default ticket lifetime, which is ten hours on many systems. You can specify a different ticket lifetime with the \sphinxstylestrong{\sphinxhyphen{}l} option. Add the letter \sphinxstylestrong{s} to the value for seconds, \sphinxstylestrong{m} for minutes, \sphinxstylestrong{h} for hours, or \sphinxstylestrong{d} for days. For example, to obtain forwardable tickets for \sphinxcode{\sphinxupquote{david@EXAMPLE.COM}} that would be good for three hours, you would type: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kinit} \PYG{o}{\PYGZhy{}}\PYG{n}{f} \PYG{o}{\PYGZhy{}}\PYG{n}{l} \PYG{l+m+mi}{3}\PYG{n}{h} \PYG{n}{david}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{david}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{p}{[}\PYG{n}{Type} \PYG{n}{david}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{s password here.]} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar You cannot mix units; specifying a lifetime of 3h30m would result in an error. Note also that most systems specify a maximum ticket lifetime. If you request a longer ticket lifetime, it will be automatically truncated to the maximum lifetime. \end{sphinxadmonition} \section{Viewing tickets with klist} \label{\detokenize{user/tkt_mgmt:viewing-tickets-with-klist}}\label{\detokenize{user/tkt_mgmt:view-tkt}} \sphinxAtStartPar The {\hyperref[\detokenize{user/user_commands/klist:klist-1}]{\sphinxcrossref{\DUrole{std,std-ref}{klist}}}} command shows your tickets. When you first obtain tickets, you will have only the ticket\sphinxhyphen{}granting ticket. The listing would look like this: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{klist} \PYG{n}{Ticket} \PYG{n}{cache}\PYG{p}{:} \PYG{o}{/}\PYG{n}{tmp}\PYG{o}{/}\PYG{n}{krb5cc\PYGZus{}ttypa} \PYG{n}{Default} \PYG{n}{principal}\PYG{p}{:} \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{Valid} \PYG{n}{starting} \PYG{n}{Expires} \PYG{n}{Service} \PYG{n}{principal} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{19}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{21} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{08}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{05}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar The ticket cache is the location of your ticket file. In the above example, this file is named \sphinxcode{\sphinxupquote{/tmp/krb5cc\_ttypa}}. The default principal is your Kerberos principal. \sphinxAtStartPar The “valid starting†and “expires†fields describe the period of time during which the ticket is valid. The “service principal†describes each ticket. The ticket\sphinxhyphen{}granting ticket has a first component \sphinxcode{\sphinxupquote{krbtgt}}, and a second component which is the realm name. \sphinxAtStartPar Now, if \sphinxcode{\sphinxupquote{jennifer}} connected to the machine \sphinxcode{\sphinxupquote{daffodil.mit.edu}}, and then typed “klist†again, she would have gotten the following result: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{klist} \PYG{n}{Ticket} \PYG{n}{cache}\PYG{p}{:} \PYG{o}{/}\PYG{n}{tmp}\PYG{o}{/}\PYG{n}{krb5cc\PYGZus{}ttypa} \PYG{n}{Default} \PYG{n}{principal}\PYG{p}{:} \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{Valid} \PYG{n}{starting} \PYG{n}{Expires} \PYG{n}{Service} \PYG{n}{principal} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{19}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{21} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{08}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{05}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{20}\PYG{p}{:}\PYG{l+m+mi}{22}\PYG{p}{:}\PYG{l+m+mi}{30} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{08}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{05}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{host}\PYG{o}{/}\PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar Here’s what happened: when \sphinxcode{\sphinxupquote{jennifer}} used ssh to connect to the host \sphinxcode{\sphinxupquote{daffodil.mit.edu}}, the ssh program presented her ticket\sphinxhyphen{}granting ticket to the KDC and requested a host ticket for the host \sphinxcode{\sphinxupquote{daffodil.mit.edu}}. The KDC sent the host ticket, which ssh then presented to the host \sphinxcode{\sphinxupquote{daffodil.mit.edu}}, and she was allowed to log in without typing her password. \sphinxAtStartPar Suppose your Kerberos tickets allow you to log into a host in another domain, such as \sphinxcode{\sphinxupquote{trillium.example.com}}, which is also in another Kerberos realm, \sphinxcode{\sphinxupquote{EXAMPLE.COM}}. If you ssh to this host, you will receive a ticket\sphinxhyphen{}granting ticket for the realm \sphinxcode{\sphinxupquote{EXAMPLE.COM}}, plus the new host ticket for \sphinxcode{\sphinxupquote{trillium.example.com}}. klist will now show: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{klist} \PYG{n}{Ticket} \PYG{n}{cache}\PYG{p}{:} \PYG{o}{/}\PYG{n}{tmp}\PYG{o}{/}\PYG{n}{krb5cc\PYGZus{}ttypa} \PYG{n}{Default} \PYG{n}{principal}\PYG{p}{:} \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{Valid} \PYG{n}{starting} \PYG{n}{Expires} \PYG{n}{Service} \PYG{n}{principal} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{19}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{21} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{08}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{05}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{20}\PYG{p}{:}\PYG{l+m+mi}{22}\PYG{p}{:}\PYG{l+m+mi}{30} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{08}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{05}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{host}\PYG{o}{/}\PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{20}\PYG{p}{:}\PYG{l+m+mi}{24}\PYG{p}{:}\PYG{l+m+mi}{18} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{08}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{05}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{20}\PYG{p}{:}\PYG{l+m+mi}{24}\PYG{p}{:}\PYG{l+m+mi}{18} \PYG{l+m+mi}{06}\PYG{o}{/}\PYG{l+m+mi}{08}\PYG{o}{/}\PYG{l+m+mi}{04} \PYG{l+m+mi}{05}\PYG{p}{:}\PYG{l+m+mi}{49}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{host}\PYG{o}{/}\PYG{n}{trillium}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar Depending on your host’s and realm’s configuration, you may also see a ticket with the service principal \sphinxcode{\sphinxupquote{host/trillium.example.com@}}. If so, this means that your host did not know what realm trillium.example.com is in, so it asked the \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} KDC for a referral. The next time you connect to \sphinxcode{\sphinxupquote{trillium.example.com}}, the odd\sphinxhyphen{}looking entry will be used to avoid needing to ask for a referral again. \sphinxAtStartPar You can use the \sphinxstylestrong{\sphinxhyphen{}f} option to view the flags that apply to your tickets. The flags are: \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar F & \sphinxAtStartPar Forwardable \\ \sphinxhline \sphinxAtStartPar f & \sphinxAtStartPar forwarded \\ \sphinxhline \sphinxAtStartPar P & \sphinxAtStartPar Proxiable \\ \sphinxhline \sphinxAtStartPar p & \sphinxAtStartPar proxy \\ \sphinxhline \sphinxAtStartPar D & \sphinxAtStartPar postDateable \\ \sphinxhline \sphinxAtStartPar d & \sphinxAtStartPar postdated \\ \sphinxhline \sphinxAtStartPar R & \sphinxAtStartPar Renewable \\ \sphinxhline \sphinxAtStartPar I & \sphinxAtStartPar Initial \\ \sphinxhline \sphinxAtStartPar i & \sphinxAtStartPar invalid \\ \sphinxhline \sphinxAtStartPar H & \sphinxAtStartPar Hardware authenticated \\ \sphinxhline \sphinxAtStartPar A & \sphinxAtStartPar preAuthenticated \\ \sphinxhline \sphinxAtStartPar T & \sphinxAtStartPar Transit policy checked \\ \sphinxhline \sphinxAtStartPar O & \sphinxAtStartPar Okay as delegate \\ \sphinxhline \sphinxAtStartPar a & \sphinxAtStartPar anonymous \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxAtStartPar Here is a sample listing. In this example, the user \sphinxstyleemphasis{jennifer} obtained her initial tickets (\sphinxstylestrong{I}), which are forwardable (\sphinxstylestrong{F}) and postdated (\sphinxstylestrong{d}) but not yet validated (\sphinxstylestrong{i}): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{klist} \PYG{o}{\PYGZhy{}}\PYG{n}{f} \PYG{n}{Ticket} \PYG{n}{cache}\PYG{p}{:} \PYG{o}{/}\PYG{n}{tmp}\PYG{o}{/}\PYG{n}{krb5cc\PYGZus{}320} \PYG{n}{Default} \PYG{n}{principal}\PYG{p}{:} \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{Valid} \PYG{n}{starting} \PYG{n}{Expires} \PYG{n}{Service} \PYG{n}{principal} \PYG{l+m+mi}{31}\PYG{o}{/}\PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{05} \PYG{l+m+mi}{19}\PYG{p}{:}\PYG{l+m+mi}{06}\PYG{p}{:}\PYG{l+m+mi}{25} \PYG{l+m+mi}{31}\PYG{o}{/}\PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{05} \PYG{l+m+mi}{19}\PYG{p}{:}\PYG{l+m+mi}{16}\PYG{p}{:}\PYG{l+m+mi}{25} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{Flags}\PYG{p}{:} \PYG{n}{FdiI} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar In the following example, the user \sphinxstyleemphasis{david}’s tickets were forwarded (\sphinxstylestrong{f}) to this host from another host. The tickets are reforwardable (\sphinxstylestrong{F}): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{klist} \PYG{o}{\PYGZhy{}}\PYG{n}{f} \PYG{n}{Ticket} \PYG{n}{cache}\PYG{p}{:} \PYG{o}{/}\PYG{n}{tmp}\PYG{o}{/}\PYG{n}{krb5cc\PYGZus{}p11795} \PYG{n}{Default} \PYG{n}{principal}\PYG{p}{:} \PYG{n}{david}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{Valid} \PYG{n}{starting} \PYG{n}{Expires} \PYG{n}{Service} \PYG{n}{principal} \PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{31}\PYG{o}{/}\PYG{l+m+mi}{05} \PYG{l+m+mi}{11}\PYG{p}{:}\PYG{l+m+mi}{52}\PYG{p}{:}\PYG{l+m+mi}{29} \PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{31}\PYG{o}{/}\PYG{l+m+mi}{05} \PYG{l+m+mi}{21}\PYG{p}{:}\PYG{l+m+mi}{11}\PYG{p}{:}\PYG{l+m+mi}{23} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{Flags}\PYG{p}{:} \PYG{n}{Ff} \PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{31}\PYG{o}{/}\PYG{l+m+mi}{05} \PYG{l+m+mi}{12}\PYG{p}{:}\PYG{l+m+mi}{03}\PYG{p}{:}\PYG{l+m+mi}{48} \PYG{l+m+mi}{07}\PYG{o}{/}\PYG{l+m+mi}{31}\PYG{o}{/}\PYG{l+m+mi}{05} \PYG{l+m+mi}{21}\PYG{p}{:}\PYG{l+m+mi}{11}\PYG{p}{:}\PYG{l+m+mi}{23} \PYG{n}{host}\PYG{o}{/}\PYG{n}{trillium}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{Flags}\PYG{p}{:} \PYG{n}{Ff} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \section{Destroying tickets with kdestroy} \label{\detokenize{user/tkt_mgmt:destroying-tickets-with-kdestroy}} \sphinxAtStartPar Your Kerberos tickets are proof that you are indeed yourself, and tickets could be stolen if someone gains access to a computer where they are stored. If this happens, the person who has them can masquerade as you until they expire. For this reason, you should destroy your Kerberos tickets when you are away from your computer. \sphinxAtStartPar Destroying your tickets is easy. Simply type kdestroy: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kdestroy} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar If {\hyperref[\detokenize{user/user_commands/kdestroy:kdestroy-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kdestroy}}}} fails to destroy your tickets, it will beep and give an error message. For example, if kdestroy can’t find any tickets to destroy, it will give the following message: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kdestroy} \PYG{n}{kdestroy}\PYG{p}{:} \PYG{n}{No} \PYG{n}{credentials} \PYG{n}{cache} \PYG{n}{file} \PYG{n}{found} \PYG{k}{while} \PYG{n}{destroying} \PYG{n}{cache} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxstepscope \chapter{User config files} \label{\detokenize{user/user_config/index:user-config-files}}\label{\detokenize{user/user_config/index::doc}} \sphinxAtStartPar The following files in your home directory can be used to control the behavior of Kerberos as it applies to your account (unless they have been disabled by your host’s configuration): \sphinxstepscope \section{kerberos} \label{\detokenize{user/user_config/kerberos:kerberos}}\label{\detokenize{user/user_config/kerberos:kerberos-7}}\label{\detokenize{user/user_config/kerberos::doc}} \subsection{DESCRIPTION} \label{\detokenize{user/user_config/kerberos:description}} \sphinxAtStartPar The Kerberos system authenticates individual users in a network environment. After authenticating yourself to Kerberos, you can use Kerberos\sphinxhyphen{}enabled programs without having to present passwords or certificates to those programs. \sphinxAtStartPar If you receive the following response from {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}}: \sphinxAtStartPar kinit: Client not found in Kerberos database while getting initial credentials \sphinxAtStartPar you haven’t been registered as a Kerberos user. See your system administrator. \sphinxAtStartPar A Kerberos name usually contains three parts. The first is the \sphinxstylestrong{primary}, which is usually a user’s or service’s name. The second is the \sphinxstylestrong{instance}, which in the case of a user is usually null. Some users may have privileged instances, however, such as \sphinxcode{\sphinxupquote{root}} or \sphinxcode{\sphinxupquote{admin}}. In the case of a service, the instance is the fully qualified name of the machine on which it runs; i.e. there can be an ssh service running on the machine ABC (\sphinxhref{mailto:ssh/ABC@REALM}{ssh/ABC@REALM}), which is different from the ssh service running on the machine XYZ (\sphinxhref{mailto:ssh/XYZ@REALM}{ssh/XYZ@REALM}). The third part of a Kerberos name is the \sphinxstylestrong{realm}. The realm corresponds to the Kerberos service providing authentication for the principal. Realms are conventionally all\sphinxhyphen{}uppercase, and often match the end of hostnames in the realm (for instance, host01.example.com might be in realm EXAMPLE.COM). \sphinxAtStartPar When writing a Kerberos name, the principal name is separated from the instance (if not null) by a slash, and the realm (if not the local realm) follows, preceded by an “@†sign. The following are examples of valid Kerberos names: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{david} \PYG{n}{jennifer}\PYG{o}{/}\PYG{n}{admin} \PYG{n}{joeuser}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{cbrown}\PYG{o}{/}\PYG{n}{root}\PYG{n+nd}{@FUBAR}\PYG{o}{.}\PYG{n}{ORG} \end{sphinxVerbatim} \sphinxAtStartPar When you authenticate yourself with Kerberos you get an initial Kerberos \sphinxstylestrong{ticket}. (A Kerberos ticket is an encrypted protocol message that provides authentication.) Kerberos uses this ticket for network utilities such as ssh. The ticket transactions are done transparently, so you don’t have to worry about their management. \sphinxAtStartPar Note, however, that tickets expire. Administrators may configure more privileged tickets, such as those with service or instance of \sphinxcode{\sphinxupquote{root}} or \sphinxcode{\sphinxupquote{admin}}, to expire in a few minutes, while tickets that carry more ordinary privileges may be good for several hours or a day. If your login session extends beyond the time limit, you will have to re\sphinxhyphen{}authenticate yourself to Kerberos to get new tickets using the {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}} command. \sphinxAtStartPar Some tickets are \sphinxstylestrong{renewable} beyond their initial lifetime. This means that \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}R}} can extend their lifetime without requiring you to re\sphinxhyphen{}authenticate. \sphinxAtStartPar If you wish to delete your local tickets, use the {\hyperref[\detokenize{user/user_commands/kdestroy:kdestroy-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kdestroy}}}} command. \sphinxAtStartPar Kerberos tickets can be forwarded. In order to forward tickets, you must request \sphinxstylestrong{forwardable} tickets when you kinit. Once you have forwardable tickets, most Kerberos programs have a command line option to forward them to the remote host. This can be useful for, e.g., running kinit on your local machine and then sshing into another to do work. Note that this should not be done on untrusted machines since they will then have your tickets. \subsection{ENVIRONMENT VARIABLES} \label{\detokenize{user/user_config/kerberos:environment-variables}} \sphinxAtStartPar Several environment variables affect the operation of Kerberos\sphinxhyphen{}enabled programs. These include: \begin{description} \sphinxlineitem{\sphinxstylestrong{KRB5CCNAME}} \sphinxAtStartPar Default name for the credentials cache file, in the form \sphinxstyleemphasis{TYPE}:\sphinxstyleemphasis{residual}. The type of the default cache may determine the availability of a cache collection. \sphinxcode{\sphinxupquote{FILE}} is not a collection type; \sphinxcode{\sphinxupquote{KEYRING}}, \sphinxcode{\sphinxupquote{DIR}}, and \sphinxcode{\sphinxupquote{KCM}} are. \sphinxAtStartPar If not set, the value of \sphinxstylestrong{default\_ccache\_name} from configuration files (see \sphinxstylestrong{KRB5\_CONFIG}) will be used. If that is also not set, the default \sphinxstyleemphasis{type} is \sphinxcode{\sphinxupquote{FILE}}, and the \sphinxstyleemphasis{residual} is the path /tmp/krb5cc\_*uid*, where \sphinxstyleemphasis{uid} is the decimal user ID of the user. \sphinxlineitem{\sphinxstylestrong{KRB5\_KTNAME}} \sphinxAtStartPar Specifies the location of the default keytab file, in the form \sphinxstyleemphasis{TYPE}:\sphinxstyleemphasis{residual}. If no \sphinxstyleemphasis{type} is present, the \sphinxstylestrong{FILE} type is assumed and \sphinxstyleemphasis{residual} is the pathname of the keytab file. If unset, \DUrole{xref,std,std-ref}{DEFKTNAME} will be used. \sphinxlineitem{\sphinxstylestrong{KRB5\_CONFIG}} \sphinxAtStartPar Specifies the location of the Kerberos configuration file. The default is \DUrole{xref,std,std-ref}{SYSCONFDIR}\sphinxcode{\sphinxupquote{/krb5.conf}}. Multiple filenames can be specified, separated by a colon; all files which are present will be read. \sphinxlineitem{\sphinxstylestrong{KRB5\_KDC\_PROFILE}} \sphinxAtStartPar Specifies the location of the KDC configuration file, which contains additional configuration directives for the Key Distribution Center daemon and associated programs. The default is \DUrole{xref,std,std-ref}{LOCALSTATEDIR}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kdc.conf}}. \sphinxlineitem{\sphinxstylestrong{KRB5RCACHENAME}} \sphinxAtStartPar (New in release 1.18) Specifies the location of the default replay cache, in the form \sphinxstyleemphasis{type}:\sphinxstyleemphasis{residual}. The \sphinxcode{\sphinxupquote{file2}} type with a pathname residual specifies a replay cache file in the version\sphinxhyphen{}2 format in the specified location. The \sphinxcode{\sphinxupquote{none}} type (residual is ignored) disables the replay cache. The \sphinxcode{\sphinxupquote{dfl}} type (residual is ignored) indicates the default, which uses a file2 replay cache in a temporary directory. The default is \sphinxcode{\sphinxupquote{dfl:}}. \sphinxlineitem{\sphinxstylestrong{KRB5RCACHETYPE}} \sphinxAtStartPar Specifies the type of the default replay cache, if \sphinxstylestrong{KRB5RCACHENAME} is unspecified. No residual can be specified, so \sphinxcode{\sphinxupquote{none}} and \sphinxcode{\sphinxupquote{dfl}} are the only useful types. \sphinxlineitem{\sphinxstylestrong{KRB5RCACHEDIR}} \sphinxAtStartPar Specifies the directory used by the \sphinxcode{\sphinxupquote{dfl}} replay cache type. The default is the value of the \sphinxstylestrong{TMPDIR} environment variable, or \sphinxcode{\sphinxupquote{/var/tmp}} if \sphinxstylestrong{TMPDIR} is not set. \sphinxlineitem{\sphinxstylestrong{KRB5\_TRACE}} \sphinxAtStartPar Specifies a filename to write trace log output to. Trace logs can help illuminate decisions made internally by the Kerberos libraries. For example, \sphinxcode{\sphinxupquote{env KRB5\_TRACE=/dev/stderr kinit}} would send tracing information for {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}} to \sphinxcode{\sphinxupquote{/dev/stderr}}. The default is not to write trace log output anywhere. \sphinxlineitem{\sphinxstylestrong{KRB5\_CLIENT\_KTNAME}} \sphinxAtStartPar Default client keytab file name. If unset, \DUrole{xref,std,std-ref}{DEFCKTNAME} will be used). \sphinxlineitem{\sphinxstylestrong{KPROP\_PORT}} \sphinxAtStartPar \DUrole{xref,std,std-ref}{kprop(8)} port to use. Defaults to 754. \sphinxlineitem{\sphinxstylestrong{GSS\_MECH\_CONFIG}} \sphinxAtStartPar Specifies a filename containing GSSAPI mechanism module configuration. The default is to read \DUrole{xref,std,std-ref}{SYSCONFDIR}\sphinxcode{\sphinxupquote{/gss/mech}} and files with a \sphinxcode{\sphinxupquote{.conf}} suffix within the directory \DUrole{xref,std,std-ref}{SYSCONFDIR}\sphinxcode{\sphinxupquote{/gss/mech.d}}. \end{description} \sphinxAtStartPar Most environment variables are disabled for certain programs, such as login system programs and setuid programs, which are designed to be secure when run within an untrusted process environment. \subsection{SEE ALSO} \label{\detokenize{user/user_config/kerberos:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{user/user_commands/kdestroy:kdestroy-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kdestroy}}}}, {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}}, {\hyperref[\detokenize{user/user_commands/klist:klist-1}]{\sphinxcrossref{\DUrole{std,std-ref}{klist}}}}, {\hyperref[\detokenize{user/user_commands/kswitch:kswitch-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kswitch}}}}, {\hyperref[\detokenize{user/user_commands/kpasswd:kpasswd-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kpasswd}}}}, {\hyperref[\detokenize{user/user_commands/ksu:ksu-1}]{\sphinxcrossref{\DUrole{std,std-ref}{ksu}}}}, \DUrole{xref,std,std-ref}{krb5.conf(5)}, \DUrole{xref,std,std-ref}{kdc.conf(5)}, \DUrole{xref,std,std-ref}{kadmin(1)}, \DUrole{xref,std,std-ref}{kadmind(8)}, \DUrole{xref,std,std-ref}{kdb5\_util(8)}, \DUrole{xref,std,std-ref}{krb5kdc(8)} \subsection{BUGS} \label{\detokenize{user/user_config/kerberos:bugs}} \subsection{AUTHORS} \label{\detokenize{user/user_config/kerberos:authors}} \begin{DUlineblock}{0em} \item[] Steve Miller, MIT Project Athena/Digital Equipment Corporation \item[] Clifford Neuman, MIT Project Athena \item[] Greg Hudson, MIT Kerberos Consortium \item[] Robbie Harwood, Red Hat, Inc. \end{DUlineblock} \subsection{HISTORY} \label{\detokenize{user/user_config/kerberos:history}} \sphinxAtStartPar The MIT Kerberos 5 implementation was developed at MIT, with contributions from many outside parties. It is currently maintained by the MIT Kerberos Consortium. \subsection{RESTRICTIONS} \label{\detokenize{user/user_config/kerberos:restrictions}} \sphinxAtStartPar Copyright 1985, 1986, 1989\sphinxhyphen{}1996, 2002, 2011, 2018 Masachusetts Institute of Technology \sphinxstepscope \section{.k5login} \label{\detokenize{user/user_config/k5login:k5login}}\label{\detokenize{user/user_config/k5login:k5login-5}}\label{\detokenize{user/user_config/k5login::doc}} \subsection{DESCRIPTION} \label{\detokenize{user/user_config/k5login:description}} \sphinxAtStartPar The .k5login file, which resides in a user’s home directory, contains a list of the Kerberos principals. Anyone with valid tickets for a principal in the file is allowed host access with the UID of the user in whose home directory the file resides. One common use is to place a .k5login file in root’s home directory, thereby granting system administrators remote root access to the host via Kerberos. \subsection{EXAMPLES} \label{\detokenize{user/user_config/k5login:examples}} \sphinxAtStartPar Suppose the user \sphinxcode{\sphinxupquote{alice}} had a .k5login file in her home directory containing just the following line: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{bob}\PYG{n+nd}{@FOOBAR}\PYG{o}{.}\PYG{n}{ORG} \end{sphinxVerbatim} \sphinxAtStartPar This would allow \sphinxcode{\sphinxupquote{bob}} to use Kerberos network applications, such as ssh(1), to access \sphinxcode{\sphinxupquote{alice}}’s account, using \sphinxcode{\sphinxupquote{bob}}’s Kerberos tickets. In a default configuration (with \sphinxstylestrong{k5login\_authoritative} set to true in \DUrole{xref,std,std-ref}{krb5.conf(5)}), this .k5login file would not let \sphinxcode{\sphinxupquote{alice}} use those network applications to access her account, since she is not listed! With no .k5login file, or with \sphinxstylestrong{k5login\_authoritative} set to false, a default rule would permit the principal \sphinxcode{\sphinxupquote{alice}} in the machine’s default realm to access the \sphinxcode{\sphinxupquote{alice}} account. \sphinxAtStartPar Let us further suppose that \sphinxcode{\sphinxupquote{alice}} is a system administrator. Alice and the other system administrators would have their principals in root’s .k5login file on each host: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{alice}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{joeadmin}\PYG{o}{/}\PYG{n}{root}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM} \end{sphinxVerbatim} \sphinxAtStartPar This would allow either system administrator to log in to these hosts using their Kerberos tickets instead of having to type the root password. Note that because \sphinxcode{\sphinxupquote{bob}} retains the Kerberos tickets for his own principal, \sphinxcode{\sphinxupquote{bob@FOOBAR.ORG}}, he would not have any of the privileges that require \sphinxcode{\sphinxupquote{alice}}’s tickets, such as root access to any of the site’s hosts, or the ability to change \sphinxcode{\sphinxupquote{alice}}’s password. \subsection{SEE ALSO} \label{\detokenize{user/user_config/k5login:see-also}} \sphinxAtStartPar kerberos(1) \sphinxstepscope \section{.k5identity} \label{\detokenize{user/user_config/k5identity:k5identity}}\label{\detokenize{user/user_config/k5identity:k5identity-5}}\label{\detokenize{user/user_config/k5identity::doc}} \subsection{DESCRIPTION} \label{\detokenize{user/user_config/k5identity:description}} \sphinxAtStartPar The .k5identity file, which resides in a user’s home directory, contains a list of rules for selecting a client principals based on the server being accessed. These rules are used to choose a credential cache within the cache collection when possible. \sphinxAtStartPar Blank lines and lines beginning with \sphinxcode{\sphinxupquote{\#}} are ignored. Each line has the form: \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{principal} \sphinxstyleemphasis{field}=\sphinxstyleemphasis{value} … \end{quote} \sphinxAtStartPar If the server principal meets all of the field constraints, then principal is chosen as the client principal. The following fields are recognized: \begin{description} \sphinxlineitem{\sphinxstylestrong{realm}} \sphinxAtStartPar If the realm of the server principal is known, it is matched against \sphinxstyleemphasis{value}, which may be a pattern using shell wildcards. For host\sphinxhyphen{}based server principals, the realm will generally only be known if there is a \DUrole{xref,std,std-ref}{domain\_realm} section in \DUrole{xref,std,std-ref}{krb5.conf(5)} with a mapping for the hostname. \sphinxlineitem{\sphinxstylestrong{service}} \sphinxAtStartPar If the server principal is a host\sphinxhyphen{}based principal, its service component is matched against \sphinxstyleemphasis{value}, which may be a pattern using shell wildcards. \sphinxlineitem{\sphinxstylestrong{host}} \sphinxAtStartPar If the server principal is a host\sphinxhyphen{}based principal, its hostname component is converted to lower case and matched against \sphinxstyleemphasis{value}, which may be a pattern using shell wildcards. \sphinxAtStartPar If the server principal matches the constraints of multiple lines in the .k5identity file, the principal from the first matching line is used. If no line matches, credentials will be selected some other way, such as the realm heuristic or the current primary cache. \end{description} \subsection{EXAMPLE} \label{\detokenize{user/user_config/k5identity:example}} \sphinxAtStartPar The following example .k5identity file selects the client principal \sphinxcode{\sphinxupquote{alice@KRBTEST.COM}} if the server principal is within that realm, the principal \sphinxcode{\sphinxupquote{alice/root@EXAMPLE.COM}} if the server host is within a servers subdomain, and the principal \sphinxcode{\sphinxupquote{alice/mail@EXAMPLE.COM}} when accessing the IMAP service on \sphinxcode{\sphinxupquote{mail.example.com}}: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{alice}\PYG{n+nd}{@KRBTEST}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{realm}\PYG{o}{=}\PYG{n}{KRBTEST}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{alice}\PYG{o}{/}\PYG{n}{root}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{host}\PYG{o}{=}\PYG{o}{*}\PYG{o}{.}\PYG{n}{servers}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{n}{alice}\PYG{o}{/}\PYG{n}{mail}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{host}\PYG{o}{=}\PYG{n}{mail}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{n}{service}\PYG{o}{=}\PYG{n}{imap} \end{sphinxVerbatim} \subsection{SEE ALSO} \label{\detokenize{user/user_config/k5identity:see-also}} \sphinxAtStartPar kerberos(1), \DUrole{xref,std,std-ref}{krb5.conf(5)} \sphinxstepscope \chapter{User commands} \label{\detokenize{user/user_commands/index:user-commands}}\label{\detokenize{user/user_commands/index:id1}}\label{\detokenize{user/user_commands/index::doc}} \sphinxstepscope \section{kdestroy} \label{\detokenize{user/user_commands/kdestroy:kdestroy}}\label{\detokenize{user/user_commands/kdestroy:kdestroy-1}}\label{\detokenize{user/user_commands/kdestroy::doc}} \subsection{SYNOPSIS} \label{\detokenize{user/user_commands/kdestroy:synopsis}} \sphinxAtStartPar \sphinxstylestrong{kdestroy} {[}\sphinxstylestrong{\sphinxhyphen{}A}{]} {[}\sphinxstylestrong{\sphinxhyphen{}q}{]} {[}\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{cache\_name}{]} {[}\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{princ\_name}{]} \subsection{DESCRIPTION} \label{\detokenize{user/user_commands/kdestroy:description}} \sphinxAtStartPar The kdestroy utility destroys the user’s active Kerberos authorization tickets by overwriting and deleting the credentials cache that contains them. If the credentials cache is not specified, the default credentials cache is destroyed. \subsection{OPTIONS} \label{\detokenize{user/user_commands/kdestroy:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}A}} \sphinxAtStartPar Destroys all caches in the collection, if a cache collection is available. May be used with the \sphinxstylestrong{\sphinxhyphen{}c} option to specify the collection to be destroyed. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}q}} \sphinxAtStartPar Run quietly. Normally kdestroy beeps if it fails to destroy the user’s tickets. The \sphinxstylestrong{\sphinxhyphen{}q} flag suppresses this behavior. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{cache\_name}} \sphinxAtStartPar Use \sphinxstyleemphasis{cache\_name} as the credentials (ticket) cache name and location; if this option is not used, the default cache name and location are used. \sphinxAtStartPar The default credentials cache may vary between systems. If the \sphinxstylestrong{KRB5CCNAME} environment variable is set, its value is used to name the default ticket cache. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{princ\_name}} \sphinxAtStartPar If a cache collection is available, destroy the cache for \sphinxstyleemphasis{princ\_name} instead of the primary cache. May be used with the \sphinxstylestrong{\sphinxhyphen{}c} option to specify the collection to be searched. \end{description} \subsection{NOTE} \label{\detokenize{user/user_commands/kdestroy:note}} \sphinxAtStartPar Most installations recommend that you place the kdestroy command in your .logout file, so that your tickets are destroyed automatically when you log out. \subsection{ENVIRONMENT} \label{\detokenize{user/user_commands/kdestroy:environment}} \sphinxAtStartPar See {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} for a description of Kerberos environment variables. \subsection{FILES} \label{\detokenize{user/user_commands/kdestroy:files}}\begin{description} \sphinxlineitem{\DUrole{xref,std,std-ref}{DEFCCNAME}} \sphinxAtStartPar Default location of Kerberos 5 credentials cache \end{description} \subsection{SEE ALSO} \label{\detokenize{user/user_commands/kdestroy:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}}, {\hyperref[\detokenize{user/user_commands/klist:klist-1}]{\sphinxcrossref{\DUrole{std,std-ref}{klist}}}}, {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} \sphinxstepscope \section{kinit} \label{\detokenize{user/user_commands/kinit:kinit}}\label{\detokenize{user/user_commands/kinit:kinit-1}}\label{\detokenize{user/user_commands/kinit::doc}} \subsection{SYNOPSIS} \label{\detokenize{user/user_commands/kinit:synopsis}} \sphinxAtStartPar \sphinxstylestrong{kinit} {[}\sphinxstylestrong{\sphinxhyphen{}V}{]} {[}\sphinxstylestrong{\sphinxhyphen{}l} \sphinxstyleemphasis{lifetime}{]} {[}\sphinxstylestrong{\sphinxhyphen{}s} \sphinxstyleemphasis{start\_time}{]} {[}\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{renewable\_life}{]} {[}\sphinxstylestrong{\sphinxhyphen{}p} | \sphinxhyphen{}\sphinxstylestrong{P}{]} {[}\sphinxstylestrong{\sphinxhyphen{}f} | \sphinxhyphen{}\sphinxstylestrong{F}{]} {[}\sphinxstylestrong{\sphinxhyphen{}a}{]} {[}\sphinxstylestrong{\sphinxhyphen{}A}{]} {[}\sphinxstylestrong{\sphinxhyphen{}C}{]} {[}\sphinxstylestrong{\sphinxhyphen{}E}{]} {[}\sphinxstylestrong{\sphinxhyphen{}v}{]} {[}\sphinxstylestrong{\sphinxhyphen{}R}{]} {[}\sphinxstylestrong{\sphinxhyphen{}k} {[}\sphinxstylestrong{\sphinxhyphen{}i} | \sphinxhyphen{}\sphinxstylestrong{t} \sphinxstyleemphasis{keytab\_file}{]}{]} {[}\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{cache\_name}{]} {[}\sphinxstylestrong{\sphinxhyphen{}n}{]} {[}\sphinxstylestrong{\sphinxhyphen{}S} \sphinxstyleemphasis{service\_name}{]} {[}\sphinxstylestrong{\sphinxhyphen{}I} \sphinxstyleemphasis{input\_ccache}{]} {[}\sphinxstylestrong{\sphinxhyphen{}T} \sphinxstyleemphasis{armor\_ccache}{]} {[}\sphinxstylestrong{\sphinxhyphen{}X} \sphinxstyleemphasis{attribute}{[}=\sphinxstyleemphasis{value}{]}{]} {[}\sphinxstylestrong{\textendash{}request\sphinxhyphen{}pac} | \sphinxstylestrong{\textendash{}no\sphinxhyphen{}request\sphinxhyphen{}pac}{]} {[}\sphinxstyleemphasis{principal}{]} \subsection{DESCRIPTION} \label{\detokenize{user/user_commands/kinit:description}} \sphinxAtStartPar kinit obtains and caches an initial ticket\sphinxhyphen{}granting ticket for \sphinxstyleemphasis{principal}. If \sphinxstyleemphasis{principal} is absent, kinit chooses an appropriate principal name based on existing credential cache contents or the local username of the user invoking kinit. Some options modify the choice of principal name. \subsection{OPTIONS} \label{\detokenize{user/user_commands/kinit:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}V}} \sphinxAtStartPar display verbose output. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}l} \sphinxstyleemphasis{lifetime}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Requests a ticket with the lifetime \sphinxstyleemphasis{lifetime}. \sphinxAtStartPar For example, \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}l 5:30}} or \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}l 5h30m}}. \sphinxAtStartPar If the \sphinxstylestrong{\sphinxhyphen{}l} option is not specified, the default ticket lifetime (configured by each site) is used. Specifying a ticket lifetime longer than the maximum ticket lifetime (configured by each site) will not override the configured maximum ticket lifetime. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}s} \sphinxstyleemphasis{start\_time}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Requests a postdated ticket. Postdated tickets are issued with the \sphinxstylestrong{invalid} flag set, and need to be resubmitted to the KDC for validation before use. \sphinxAtStartPar \sphinxstyleemphasis{start\_time} specifies the duration of the delay before the ticket can become valid. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{renewable\_life}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Requests renewable tickets, with a total lifetime of \sphinxstyleemphasis{renewable\_life}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}f}} \sphinxAtStartPar requests forwardable tickets. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}F}} \sphinxAtStartPar requests non\sphinxhyphen{}forwardable tickets. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}p}} \sphinxAtStartPar requests proxiable tickets. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}P}} \sphinxAtStartPar requests non\sphinxhyphen{}proxiable tickets. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}a}} \sphinxAtStartPar requests tickets restricted to the host’s local address{[}es{]}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}A}} \sphinxAtStartPar requests tickets not restricted by address. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}C}} \sphinxAtStartPar requests canonicalization of the principal name, and allows the KDC to reply with a different client principal from the one requested. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}E}} \sphinxAtStartPar treats the principal name as an enterprise name. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}v}} \sphinxAtStartPar requests that the ticket\sphinxhyphen{}granting ticket in the cache (with the \sphinxstylestrong{invalid} flag set) be passed to the KDC for validation. If the ticket is within its requested time range, the cache is replaced with the validated ticket. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}R}} \sphinxAtStartPar requests renewal of the ticket\sphinxhyphen{}granting ticket. Note that an expired ticket cannot be renewed, even if the ticket is still within its renewable life. \sphinxAtStartPar Note that renewable tickets that have expired as reported by {\hyperref[\detokenize{user/user_commands/klist:klist-1}]{\sphinxcrossref{\DUrole{std,std-ref}{klist}}}} may sometimes be renewed using this option, because the KDC applies a grace period to account for client\sphinxhyphen{}KDC clock skew. See \DUrole{xref,std,std-ref}{krb5.conf(5)} \sphinxstylestrong{clockskew} setting. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k} {[}\sphinxstylestrong{\sphinxhyphen{}i} | \sphinxstylestrong{\sphinxhyphen{}t} \sphinxstyleemphasis{keytab\_file}{]}} \sphinxAtStartPar requests a ticket, obtained from a key in the local host’s keytab. The location of the keytab may be specified with the \sphinxstylestrong{\sphinxhyphen{}t} \sphinxstyleemphasis{keytab\_file} option, or with the \sphinxstylestrong{\sphinxhyphen{}i} option to specify the use of the default client keytab; otherwise the default keytab will be used. By default, a host ticket for the local host is requested, but any principal may be specified. On a KDC, the special keytab location \sphinxcode{\sphinxupquote{KDB:}} can be used to indicate that kinit should open the KDC database and look up the key directly. This permits an administrator to obtain tickets as any principal that supports authentication based on the key. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}n}} \sphinxAtStartPar Requests anonymous processing. Two types of anonymous principals are supported. \sphinxAtStartPar For fully anonymous Kerberos, configure pkinit on the KDC and configure \sphinxstylestrong{pkinit\_anchors} in the client’s \DUrole{xref,std,std-ref}{krb5.conf(5)}. Then use the \sphinxstylestrong{\sphinxhyphen{}n} option with a principal of the form \sphinxcode{\sphinxupquote{@REALM}} (an empty principal name followed by the at\sphinxhyphen{}sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. \sphinxAtStartPar A second form of anonymous tickets is supported; these realm\sphinxhyphen{}exposed tickets hide the identity of the client but not the client’s realm. For this mode, use \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}n}} with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. \sphinxAtStartPar As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation. \end{description} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}I} \sphinxstyleemphasis{input\_ccache} \begin{quote} \sphinxAtStartPar Specifies the name of a credentials cache that already contains a ticket. When obtaining that ticket, if information about how that ticket was obtained was also stored to the cache, that information will be used to affect how new credentials are obtained, including preselecting the same methods of authenticating to the KDC. \end{quote} \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}T} \sphinxstyleemphasis{armor\_ccache}} \sphinxAtStartPar Specifies the name of a credentials cache that already contains a ticket. If supported by the KDC, this cache will be used to armor the request, preventing offline dictionary attacks and allowing the use of additional preauthentication mechanisms. Armoring also makes sure that the response from the KDC is not modified in transit. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{cache\_name}} \sphinxAtStartPar use \sphinxstyleemphasis{cache\_name} as the Kerberos 5 credentials (ticket) cache location. If this option is not used, the default cache location is used. \sphinxAtStartPar The default cache location may vary between systems. If the \sphinxstylestrong{KRB5CCNAME} environment variable is set, its value is used to locate the default cache. If a principal name is specified and the type of the default cache supports a collection (such as the DIR type), an existing cache containing credentials for the principal is selected or a new one is created and becomes the new primary cache. Otherwise, any existing contents of the default cache are destroyed by kinit. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}S} \sphinxstyleemphasis{service\_name}} \sphinxAtStartPar specify an alternate service name to use when getting initial tickets. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}X} \sphinxstyleemphasis{attribute}{[}=\sphinxstyleemphasis{value}{]}} \sphinxAtStartPar specify a pre\sphinxhyphen{}authentication \sphinxstyleemphasis{attribute} and \sphinxstyleemphasis{value} to be interpreted by pre\sphinxhyphen{}authentication modules. The acceptable attribute and value values vary from module to module. This option may be specified multiple times to specify multiple attributes. If no value is specified, it is assumed to be “yesâ€. \sphinxAtStartPar The following attributes are recognized by the PKINIT pre\sphinxhyphen{}authentication mechanism: \begin{description} \sphinxlineitem{\sphinxstylestrong{X509\_user\_identity}=\sphinxstyleemphasis{value}} \sphinxAtStartPar specify where to find user’s X509 identity information \sphinxlineitem{\sphinxstylestrong{X509\_anchors}=\sphinxstyleemphasis{value}} \sphinxAtStartPar specify where to find trusted X509 anchor information \sphinxlineitem{\sphinxstylestrong{disable\_freshness}{[}\sphinxstylestrong{=yes}{]}} \sphinxAtStartPar disable sending freshness tokens (for testing purposes only) \end{description} \sphinxlineitem{\sphinxstylestrong{\textendash{}request\sphinxhyphen{}pac} | \sphinxstylestrong{\textendash{}no\sphinxhyphen{}request\sphinxhyphen{}pac}} \sphinxAtStartPar mutually exclusive. If \sphinxstylestrong{\textendash{}request\sphinxhyphen{}pac} is set, ask the KDC to include a PAC in authdata; if \sphinxstylestrong{\textendash{}no\sphinxhyphen{}request\sphinxhyphen{}pac} is set, ask the KDC not to include a PAC; if neither are set, the KDC will follow its default, which is typically is to include a PAC if doing so is supported. \end{description} \subsection{ENVIRONMENT} \label{\detokenize{user/user_commands/kinit:environment}} \sphinxAtStartPar See {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} for a description of Kerberos environment variables. \subsection{FILES} \label{\detokenize{user/user_commands/kinit:files}}\begin{description} \sphinxlineitem{\DUrole{xref,std,std-ref}{DEFCCNAME}} \sphinxAtStartPar default location of Kerberos 5 credentials cache \sphinxlineitem{\DUrole{xref,std,std-ref}{DEFKTNAME}} \sphinxAtStartPar default location for the local host’s keytab. \end{description} \subsection{SEE ALSO} \label{\detokenize{user/user_commands/kinit:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{user/user_commands/klist:klist-1}]{\sphinxcrossref{\DUrole{std,std-ref}{klist}}}}, {\hyperref[\detokenize{user/user_commands/kdestroy:kdestroy-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kdestroy}}}}, {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} \sphinxstepscope \section{klist} \label{\detokenize{user/user_commands/klist:klist}}\label{\detokenize{user/user_commands/klist:klist-1}}\label{\detokenize{user/user_commands/klist::doc}} \subsection{SYNOPSIS} \label{\detokenize{user/user_commands/klist:synopsis}} \sphinxAtStartPar \sphinxstylestrong{klist} {[}\sphinxstylestrong{\sphinxhyphen{}e}{]} {[}{[}\sphinxstylestrong{\sphinxhyphen{}c}{]} {[}\sphinxstylestrong{\sphinxhyphen{}l}{]} {[}\sphinxstylestrong{\sphinxhyphen{}A}{]} {[}\sphinxstylestrong{\sphinxhyphen{}f}{]} {[}\sphinxstylestrong{\sphinxhyphen{}s}{]} {[}\sphinxstylestrong{\sphinxhyphen{}a} {[}\sphinxstylestrong{\sphinxhyphen{}n}{]}{]}{]} {[}\sphinxstylestrong{\sphinxhyphen{}C}{]} {[}\sphinxstylestrong{\sphinxhyphen{}k} {[}\sphinxstylestrong{\sphinxhyphen{}i}{]} {[}\sphinxstylestrong{\sphinxhyphen{}t}{]} {[}\sphinxstylestrong{\sphinxhyphen{}K}{]}{]} {[}\sphinxstylestrong{\sphinxhyphen{}V}{]} {[}\sphinxstylestrong{\sphinxhyphen{}d}{]} {[}\sphinxstyleemphasis{cache\_name}|\sphinxstyleemphasis{keytab\_name}{]} \subsection{DESCRIPTION} \label{\detokenize{user/user_commands/klist:description}} \sphinxAtStartPar klist lists the Kerberos principal and Kerberos tickets held in a credentials cache, or the keys held in a keytab file. \subsection{OPTIONS} \label{\detokenize{user/user_commands/klist:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}e}} \sphinxAtStartPar Displays the encryption types of the session key and the ticket for each credential in the credential cache, or each key in the keytab file. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}l}} \sphinxAtStartPar If a cache collection is available, displays a table summarizing the caches present in the collection. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}A}} \sphinxAtStartPar If a cache collection is available, displays the contents of all of the caches in the collection. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}c}} \sphinxAtStartPar List tickets held in a credentials cache. This is the default if neither \sphinxstylestrong{\sphinxhyphen{}c} nor \sphinxstylestrong{\sphinxhyphen{}k} is specified. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}f}} \sphinxAtStartPar Shows the flags present in the credentials, using the following abbreviations: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{F} \PYG{n}{Forwardable} \PYG{n}{f} \PYG{n}{forwarded} \PYG{n}{P} \PYG{n}{Proxiable} \PYG{n}{p} \PYG{n}{proxy} \PYG{n}{D} \PYG{n}{postDateable} \PYG{n}{d} \PYG{n}{postdated} \PYG{n}{R} \PYG{n}{Renewable} \PYG{n}{I} \PYG{n}{Initial} \PYG{n}{i} \PYG{n}{invalid} \PYG{n}{H} \PYG{n}{Hardware} \PYG{n}{authenticated} \PYG{n}{A} \PYG{n}{preAuthenticated} \PYG{n}{T} \PYG{n}{Transit} \PYG{n}{policy} \PYG{n}{checked} \PYG{n}{O} \PYG{n}{Okay} \PYG{k}{as} \PYG{n}{delegate} \PYG{n}{a} \PYG{n}{anonymous} \end{sphinxVerbatim} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}s}} \sphinxAtStartPar Causes klist to run silently (produce no output). klist will exit with status 1 if the credentials cache cannot be read or is expired, and with status 0 otherwise. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}a}} \sphinxAtStartPar Display list of addresses in credentials. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}n}} \sphinxAtStartPar Show numeric addresses instead of reverse\sphinxhyphen{}resolving addresses. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}C}} \sphinxAtStartPar List configuration data that has been stored in the credentials cache when klist encounters it. By default, configuration data is not listed. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k}} \sphinxAtStartPar List keys held in a keytab file. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}i}} \sphinxAtStartPar In combination with \sphinxstylestrong{\sphinxhyphen{}k}, defaults to using the default client keytab instead of the default acceptor keytab, if no name is given. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}t}} \sphinxAtStartPar Display the time entry timestamps for each keytab entry in the keytab file. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}K}} \sphinxAtStartPar Display the value of the encryption key in each keytab entry in the keytab file. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}d}} \sphinxAtStartPar Display the authdata types (if any) for each entry. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}V}} \sphinxAtStartPar Display the Kerberos version number and exit. \end{description} \sphinxAtStartPar If \sphinxstyleemphasis{cache\_name} or \sphinxstyleemphasis{keytab\_name} is not specified, klist will display the credentials in the default credentials cache or keytab file as appropriate. If the \sphinxstylestrong{KRB5CCNAME} environment variable is set, its value is used to locate the default ticket cache. \subsection{ENVIRONMENT} \label{\detokenize{user/user_commands/klist:environment}} \sphinxAtStartPar See {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} for a description of Kerberos environment variables. \subsection{FILES} \label{\detokenize{user/user_commands/klist:files}}\begin{description} \sphinxlineitem{\DUrole{xref,std,std-ref}{DEFCCNAME}} \sphinxAtStartPar Default location of Kerberos 5 credentials cache \sphinxlineitem{\DUrole{xref,std,std-ref}{DEFKTNAME}} \sphinxAtStartPar Default location for the local host’s keytab file. \end{description} \subsection{SEE ALSO} \label{\detokenize{user/user_commands/klist:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}}, {\hyperref[\detokenize{user/user_commands/kdestroy:kdestroy-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kdestroy}}}}, {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} \sphinxstepscope \section{kpasswd} \label{\detokenize{user/user_commands/kpasswd:kpasswd}}\label{\detokenize{user/user_commands/kpasswd:kpasswd-1}}\label{\detokenize{user/user_commands/kpasswd::doc}} \subsection{SYNOPSIS} \label{\detokenize{user/user_commands/kpasswd:synopsis}} \sphinxAtStartPar \sphinxstylestrong{kpasswd} {[}\sphinxstyleemphasis{principal}{]} \subsection{DESCRIPTION} \label{\detokenize{user/user_commands/kpasswd:description}} \sphinxAtStartPar The kpasswd command is used to change a Kerberos principal’s password. kpasswd first prompts for the current Kerberos password, then prompts the user twice for the new password, and the password is changed. \sphinxAtStartPar If the principal is governed by a policy that specifies the length and/or number of character classes required in the new password, the new password must conform to the policy. (The five character classes are lower case, upper case, numbers, punctuation, and all other characters.) \subsection{OPTIONS} \label{\detokenize{user/user_commands/kpasswd:options}}\begin{description} \sphinxlineitem{\sphinxstyleemphasis{principal}} \sphinxAtStartPar Change the password for the Kerberos principal principal. Otherwise, kpasswd uses the principal name from an existing ccache if there is one; if not, the principal is derived from the identity of the user invoking the kpasswd command. \end{description} \subsection{ENVIRONMENT} \label{\detokenize{user/user_commands/kpasswd:environment}} \sphinxAtStartPar See {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{user/user_commands/kpasswd:see-also}} \sphinxAtStartPar \DUrole{xref,std,std-ref}{kadmin(1)}, \DUrole{xref,std,std-ref}{kadmind(8)}, {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} \sphinxstepscope \section{krb5\sphinxhyphen{}config} \label{\detokenize{user/user_commands/krb5-config:krb5-config}}\label{\detokenize{user/user_commands/krb5-config:krb5-config-1}}\label{\detokenize{user/user_commands/krb5-config::doc}} \subsection{SYNOPSIS} \label{\detokenize{user/user_commands/krb5-config:synopsis}} \sphinxAtStartPar \sphinxstylestrong{krb5\sphinxhyphen{}config} {[}\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}help} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}all} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}version} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}vendor} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}prefix} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}exec\sphinxhyphen{}prefix} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}defccname} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}defktname} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}defcktname} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}cflags} | \sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}libs} {[}\sphinxstyleemphasis{libraries}{]}{]} \subsection{DESCRIPTION} \label{\detokenize{user/user_commands/krb5-config:description}} \sphinxAtStartPar krb5\sphinxhyphen{}config tells the application programmer what flags to use to compile and link programs against the installed Kerberos libraries. \subsection{OPTIONS} \label{\detokenize{user/user_commands/krb5-config:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}help}} \sphinxAtStartPar prints a usage message. This is the default behavior when no options are specified. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}all}} \sphinxAtStartPar prints the version, vendor, prefix, and exec\sphinxhyphen{}prefix. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}version}} \sphinxAtStartPar prints the version number of the Kerberos installation. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}vendor}} \sphinxAtStartPar prints the name of the vendor of the Kerberos installation. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}prefix}} \sphinxAtStartPar prints the prefix for which the Kerberos installation was built. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}exec\sphinxhyphen{}prefix}} \sphinxAtStartPar prints the prefix for executables for which the Kerberos installation was built. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}defccname}} \sphinxAtStartPar prints the built\sphinxhyphen{}in default credentials cache location. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}defktname}} \sphinxAtStartPar prints the built\sphinxhyphen{}in default keytab location. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}defcktname}} \sphinxAtStartPar prints the built\sphinxhyphen{}in default client (initiator) keytab location. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}cflags}} \sphinxAtStartPar prints the compilation flags used to build the Kerberos installation. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}}\sphinxstylestrong{\sphinxhyphen{}libs} {[}\sphinxstyleemphasis{library}{]}} \sphinxAtStartPar prints the compiler options needed to link against \sphinxstyleemphasis{library}. Allowed values for \sphinxstyleemphasis{library} are: \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar krb5 & \sphinxAtStartPar Kerberos 5 applications (default) \\ \sphinxhline \sphinxAtStartPar gssapi & \sphinxAtStartPar GSSAPI applications with Kerberos 5 bindings \\ \sphinxhline \sphinxAtStartPar kadm\sphinxhyphen{}client & \sphinxAtStartPar Kadmin client \\ \sphinxhline \sphinxAtStartPar kadm\sphinxhyphen{}server & \sphinxAtStartPar Kadmin server \\ \sphinxhline \sphinxAtStartPar kdb & \sphinxAtStartPar Applications that access the Kerberos database \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \end{description} \subsection{EXAMPLES} \label{\detokenize{user/user_commands/krb5-config:examples}} \sphinxAtStartPar krb5\sphinxhyphen{}config is particularly useful for compiling against a Kerberos installation that was installed in a non\sphinxhyphen{}standard location. For example, a Kerberos installation that is installed in \sphinxcode{\sphinxupquote{/opt/krb5/}} but uses libraries in \sphinxcode{\sphinxupquote{/usr/local/lib/}} for text localization would produce the following output: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{krb5}\PYG{o}{\PYGZhy{}}\PYG{n}{config} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{n}{libs} \PYG{n}{krb5} \PYG{o}{\PYGZhy{}}\PYG{n}{L}\PYG{o}{/}\PYG{n}{opt}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{/}\PYG{n}{lib} \PYG{o}{\PYGZhy{}}\PYG{n}{Wl}\PYG{p}{,}\PYG{o}{\PYGZhy{}}\PYG{n}{rpath} \PYG{o}{\PYGZhy{}}\PYG{n}{Wl}\PYG{p}{,}\PYG{o}{/}\PYG{n}{opt}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{/}\PYG{n}{lib} \PYG{o}{\PYGZhy{}}\PYG{n}{L}\PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{lib} \PYG{o}{\PYGZhy{}}\PYG{n}{lkrb5} \PYG{o}{\PYGZhy{}}\PYG{n}{lk5crypto} \PYG{o}{\PYGZhy{}}\PYG{n}{lcom\PYGZus{}err} \end{sphinxVerbatim} \subsection{SEE ALSO} \label{\detokenize{user/user_commands/krb5-config:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}}, cc(1) \sphinxstepscope \section{ksu} \label{\detokenize{user/user_commands/ksu:ksu}}\label{\detokenize{user/user_commands/ksu:ksu-1}}\label{\detokenize{user/user_commands/ksu::doc}} \subsection{SYNOPSIS} \label{\detokenize{user/user_commands/ksu:synopsis}} \sphinxAtStartPar \sphinxstylestrong{ksu} {[} \sphinxstyleemphasis{target\_user} {]} {[} \sphinxstylestrong{\sphinxhyphen{}n} \sphinxstyleemphasis{target\_principal\_name} {]} {[} \sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{source\_cache\_name} {]} {[} \sphinxstylestrong{\sphinxhyphen{}k} {]} {[} \sphinxstylestrong{\sphinxhyphen{}r} time {]} {[} \sphinxstylestrong{\sphinxhyphen{}p} | \sphinxstylestrong{\sphinxhyphen{}P}{]} {[} \sphinxstylestrong{\sphinxhyphen{}f} | \sphinxstylestrong{\sphinxhyphen{}F}{]} {[} \sphinxstylestrong{\sphinxhyphen{}l} \sphinxstyleemphasis{lifetime} {]} {[} \sphinxstylestrong{\sphinxhyphen{}z | Z} {]} {[} \sphinxstylestrong{\sphinxhyphen{}q} {]} {[} \sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{command} {[} args … {]} {]} {[} \sphinxstylestrong{\sphinxhyphen{}a} {[} args … {]} {]} \subsection{REQUIREMENTS} \label{\detokenize{user/user_commands/ksu:requirements}} \sphinxAtStartPar Must have Kerberos version 5 installed to compile ksu. Must have a Kerberos version 5 server running to use ksu. \subsection{DESCRIPTION} \label{\detokenize{user/user_commands/ksu:description}} \sphinxAtStartPar ksu is a Kerberized version of the su program that has two missions: one is to securely change the real and effective user ID to that of the target user, and the other is to create a new security context. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar For the sake of clarity, all references to and attributes of the user invoking the program will start with “source†(e.g., “source userâ€, “source cacheâ€, etc.). \sphinxAtStartPar Likewise, all references to and attributes of the target account will start with “targetâ€. \end{sphinxadmonition} \subsection{AUTHENTICATION} \label{\detokenize{user/user_commands/ksu:authentication}} \sphinxAtStartPar To fulfill the first mission, ksu operates in two phases: authentication and authorization. Resolving the target principal name is the first step in authentication. The user can either specify his principal name with the \sphinxstylestrong{\sphinxhyphen{}n} option (e.g., \sphinxcode{\sphinxupquote{\sphinxhyphen{}n jqpublic@USC.EDU}}) or a default principal name will be assigned using a heuristic described in the OPTIONS section (see \sphinxstylestrong{\sphinxhyphen{}n} option). The target user name must be the first argument to ksu; if not specified root is the default. If \sphinxcode{\sphinxupquote{.}} is specified then the target user will be the source user (e.g., \sphinxcode{\sphinxupquote{ksu .}}). If the source user is root or the target user is the source user, no authentication or authorization takes place. Otherwise, ksu looks for an appropriate Kerberos ticket in the source cache. \sphinxAtStartPar The ticket can either be for the end\sphinxhyphen{}server or a ticket granting ticket (TGT) for the target principal’s realm. If the ticket for the end\sphinxhyphen{}server is already in the cache, it’s decrypted and verified. If it’s not in the cache but the TGT is, the TGT is used to obtain the ticket for the end\sphinxhyphen{}server. The end\sphinxhyphen{}server ticket is then verified. If neither ticket is in the cache, but ksu is compiled with the \sphinxstylestrong{GET\_TGT\_VIA\_PASSWD} define, the user will be prompted for a Kerberos password which will then be used to get a TGT. If the user is logged in remotely and does not have a secure channel, the password may be exposed. If neither ticket is in the cache and \sphinxstylestrong{GET\_TGT\_VIA\_PASSWD} is not defined, authentication fails. \subsection{AUTHORIZATION} \label{\detokenize{user/user_commands/ksu:authorization}} \sphinxAtStartPar This section describes authorization of the source user when ksu is invoked without the \sphinxstylestrong{\sphinxhyphen{}e} option. For a description of the \sphinxstylestrong{\sphinxhyphen{}e} option, see the OPTIONS section. \sphinxAtStartPar Upon successful authentication, ksu checks whether the target principal is authorized to access the target account. In the target user’s home directory, ksu attempts to access two authorization files: {\hyperref[\detokenize{user/user_config/k5login:k5login-5}]{\sphinxcrossref{\DUrole{std,std-ref}{.k5login}}}} and .k5users. In the .k5login file each line contains the name of a principal that is authorized to access the account. \sphinxAtStartPar For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{jqpublic}\PYG{n+nd}{@USC}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{jqpublic}\PYG{o}{/}\PYG{n}{secure}\PYG{n+nd}{@USC}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{jqpublic}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@USC}\PYG{o}{.}\PYG{n}{EDU} \end{sphinxVerbatim} \sphinxAtStartPar The format of .k5users is the same, except the principal name may be followed by a list of commands that the principal is authorized to execute (see the \sphinxstylestrong{\sphinxhyphen{}e} option in the OPTIONS section for details). \sphinxAtStartPar Thus if the target principal name is found in the .k5login file the source user is authorized to access the target account. Otherwise ksu looks in the .k5users file. If the target principal name is found without any trailing commands or followed only by \sphinxcode{\sphinxupquote{*}} then the source user is authorized. If either .k5login or .k5users exist but an appropriate entry for the target principal does not exist then access is denied. If neither file exists then the principal will be granted access to the account according to the aname\sphinxhyphen{}\textgreater{}lname mapping rules. Otherwise, authorization fails. \subsection{EXECUTION OF THE TARGET SHELL} \label{\detokenize{user/user_commands/ksu:execution-of-the-target-shell}} \sphinxAtStartPar Upon successful authentication and authorization, ksu proceeds in a similar fashion to su. The environment is unmodified with the exception of USER, HOME and SHELL variables. If the target user is not root, USER gets set to the target user name. Otherwise USER remains unchanged. Both HOME and SHELL are set to the target login’s default values. In addition, the environment variable \sphinxstylestrong{KRB5CCNAME} gets set to the name of the target cache. The real and effective user ID are changed to that of the target user. The target user’s shell is then invoked (the shell name is specified in the password file). Upon termination of the shell, ksu deletes the target cache (unless ksu is invoked with the \sphinxstylestrong{\sphinxhyphen{}k} option). This is implemented by first doing a fork and then an exec, instead of just exec, as done by su. \subsection{CREATING A NEW SECURITY CONTEXT} \label{\detokenize{user/user_commands/ksu:creating-a-new-security-context}} \sphinxAtStartPar ksu can be used to create a new security context for the target program (either the target shell, or command specified via the \sphinxstylestrong{\sphinxhyphen{}e} option). The target program inherits a set of credentials from the source user. By default, this set includes all of the credentials in the source cache plus any additional credentials obtained during authentication. The source user is able to limit the credentials in this set by using \sphinxstylestrong{\sphinxhyphen{}z} or \sphinxstylestrong{\sphinxhyphen{}Z} option. \sphinxstylestrong{\sphinxhyphen{}z} restricts the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. The \sphinxstylestrong{\sphinxhyphen{}Z} option provides the target user with a fresh target cache (no creds in the cache). Note that for security reasons, when the source user is root and target user is non\sphinxhyphen{}root, \sphinxstylestrong{\sphinxhyphen{}z} option is the default mode of operation. \sphinxAtStartPar While no authentication takes place if the source user is root or is the same as the target user, additional tickets can still be obtained for the target cache. If \sphinxstylestrong{\sphinxhyphen{}n} is specified and no credentials can be copied to the target cache, the source user is prompted for a Kerberos password (unless \sphinxstylestrong{\sphinxhyphen{}Z} specified or \sphinxstylestrong{GET\_TGT\_VIA\_PASSWD} is undefined). If successful, a TGT is obtained from the Kerberos server and stored in the target cache. Otherwise, if a password is not provided (user hit return) ksu continues in a normal mode of operation (the target cache will not contain the desired TGT). If the wrong password is typed in, ksu fails. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar During authentication, only the tickets that could be obtained without providing a password are cached in the source cache. \end{sphinxadmonition} \subsection{OPTIONS} \label{\detokenize{user/user_commands/ksu:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}n} \sphinxstyleemphasis{target\_principal\_name}} \sphinxAtStartPar Specify a Kerberos target principal name. Used in authentication and authorization phases of ksu. \sphinxAtStartPar If ksu is invoked without \sphinxstylestrong{\sphinxhyphen{}n}, a default principal name is assigned via the following heuristic: \begin{itemize} \item {} \sphinxAtStartPar Case 1: source user is non\sphinxhyphen{}root. \sphinxAtStartPar If the target user is the source user the default principal name is set to the default principal of the source cache. If the cache does not exist then the default principal name is set to \sphinxcode{\sphinxupquote{target\_user@local\_realm}}. If the source and target users are different and neither \sphinxcode{\sphinxupquote{\textasciitilde{}target\_user/.k5users}} nor \sphinxcode{\sphinxupquote{\textasciitilde{}target\_user/.k5login}} exist then the default principal name is \sphinxcode{\sphinxupquote{target\_user\_login\_name@local\_realm}}. Otherwise, starting with the first principal listed below, ksu checks if the principal is authorized to access the target account and whether there is a legitimate ticket for that principal in the source cache. If both conditions are met that principal becomes the default target principal, otherwise go to the next principal. \begin{enumerate} \sphinxsetlistlabels{\alph}{enumi}{enumii}{}{)}% \item {} \sphinxAtStartPar default principal of the source cache \item {} \sphinxAtStartPar target\_user@local\_realm \item {} \sphinxAtStartPar source\_user@local\_realm \end{enumerate} \sphinxAtStartPar If a\sphinxhyphen{}c fails try any principal for which there is a ticket in the source cache and that is authorized to access the target account. If that fails select the first principal that is authorized to access the target account from the above list. If none are authorized and ksu is configured with \sphinxstylestrong{PRINC\_LOOK\_AHEAD} turned on, select the default principal as follows: \sphinxAtStartPar For each candidate in the above list, select an authorized principal that has the same realm name and first part of the principal name equal to the prefix of the candidate. For example if candidate a) is \sphinxcode{\sphinxupquote{jqpublic@ISI.EDU}} and \sphinxcode{\sphinxupquote{jqpublic/secure@ISI.EDU}} is authorized to access the target account then the default principal is set to \sphinxcode{\sphinxupquote{jqpublic/secure@ISI.EDU}}. \item {} \sphinxAtStartPar Case 2: source user is root. \sphinxAtStartPar If the target user is non\sphinxhyphen{}root then the default principal name is \sphinxcode{\sphinxupquote{target\_user@local\_realm}}. Else, if the source cache exists the default principal name is set to the default principal of the source cache. If the source cache does not exist, default principal name is set to \sphinxcode{\sphinxupquote{root\textbackslash{}@local\_realm}}. \end{itemize} \end{description} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{source\_cache\_name} \begin{quote} \sphinxAtStartPar Specify source cache name (e.g., \sphinxcode{\sphinxupquote{\sphinxhyphen{}c FILE:/tmp/my\_cache}}). If \sphinxstylestrong{\sphinxhyphen{}c} option is not used then the name is obtained from \sphinxstylestrong{KRB5CCNAME} environment variable. If \sphinxstylestrong{KRB5CCNAME} is not defined the source cache name is set to \sphinxcode{\sphinxupquote{krb5cc\_\textless{}source uid\textgreater{}}}. The target cache name is automatically set to \sphinxcode{\sphinxupquote{krb5cc\_\textless{}target uid\textgreater{}.(gen\_sym())}}, where gen\_sym generates a new number such that the resulting cache does not already exist. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5cc\PYGZus{}1984}\PYG{l+m+mf}{.2} \end{sphinxVerbatim} \end{quote} \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k}} \sphinxAtStartPar Do not delete the target cache upon termination of the target shell or a command (\sphinxstylestrong{\sphinxhyphen{}e} command). Without \sphinxstylestrong{\sphinxhyphen{}k}, ksu deletes the target cache. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}z}} \sphinxAtStartPar Restrict the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. Use the \sphinxstylestrong{\sphinxhyphen{}n} option if you want the tickets for other then the default principal. Note that the \sphinxstylestrong{\sphinxhyphen{}z} option is mutually exclusive with the \sphinxstylestrong{\sphinxhyphen{}Z} option. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}Z}} \sphinxAtStartPar Don’t copy any tickets from the source cache to the target cache. Just create a fresh target cache, where the default principal name of the cache is initialized to the target principal name. Note that the \sphinxstylestrong{\sphinxhyphen{}Z} option is mutually exclusive with the \sphinxstylestrong{\sphinxhyphen{}z} option. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}q}} \sphinxAtStartPar Suppress the printing of status messages. \end{description} \sphinxAtStartPar Ticket granting ticket options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}l} \sphinxstyleemphasis{lifetime} \sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{time} \sphinxstylestrong{\sphinxhyphen{}p} \sphinxstylestrong{\sphinxhyphen{}P} \sphinxstylestrong{\sphinxhyphen{}f} \sphinxstylestrong{\sphinxhyphen{}F}} \sphinxAtStartPar The ticket granting ticket options only apply to the case where there are no appropriate tickets in the cache to authenticate the source user. In this case if ksu is configured to prompt users for a Kerberos password (\sphinxstylestrong{GET\_TGT\_VIA\_PASSWD} is defined), the ticket granting ticket options that are specified will be used when getting a ticket granting ticket from the Kerberos server. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}l} \sphinxstyleemphasis{lifetime}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Specifies the lifetime to be requested for the ticket; if this option is not specified, the default ticket lifetime (12 hours) is used instead. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{time}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Specifies that the \sphinxstylestrong{renewable} option should be requested for the ticket, and specifies the desired total lifetime of the ticket. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}p}} \sphinxAtStartPar specifies that the \sphinxstylestrong{proxiable} option should be requested for the ticket. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}P}} \sphinxAtStartPar specifies that the \sphinxstylestrong{proxiable} option should not be requested for the ticket, even if the default configuration is to ask for proxiable tickets. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}f}} \sphinxAtStartPar option specifies that the \sphinxstylestrong{forwardable} option should be requested for the ticket. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}F}} \sphinxAtStartPar option specifies that the \sphinxstylestrong{forwardable} option should not be requested for the ticket, even if the default configuration is to ask for forwardable tickets. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{command} {[}\sphinxstyleemphasis{args} …{]}} \sphinxAtStartPar ksu proceeds exactly the same as if it was invoked without the \sphinxstylestrong{\sphinxhyphen{}e} option, except instead of executing the target shell, ksu executes the specified command. Example of usage: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{ksu} \PYG{n}{bob} \PYG{o}{\PYGZhy{}}\PYG{n}{e} \PYG{n}{ls} \PYG{o}{\PYGZhy{}}\PYG{n}{lag} \end{sphinxVerbatim} \sphinxAtStartPar The authorization algorithm for \sphinxstylestrong{\sphinxhyphen{}e} is as follows: \sphinxAtStartPar If the source user is root or source user == target user, no authorization takes place and the command is executed. If source user id != 0, and \sphinxcode{\sphinxupquote{\textasciitilde{}target\_user/.k5users}} file does not exist, authorization fails. Otherwise, \sphinxcode{\sphinxupquote{\textasciitilde{}target\_user/.k5users}} file must have an appropriate entry for target principal to get authorized. \sphinxAtStartPar The .k5users file format: \sphinxAtStartPar A single principal entry on each line that may be followed by a list of commands that the principal is authorized to execute. A principal name followed by a \sphinxcode{\sphinxupquote{*}} means that the user is authorized to execute any command. Thus, in the following example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{jqpublic}\PYG{n+nd}{@USC}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{ls} \PYG{n}{mail} \PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{/}\PYG{n}{klist} \PYG{n}{jqpublic}\PYG{o}{/}\PYG{n}{secure}\PYG{n+nd}{@USC}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{*} \PYG{n}{jqpublic}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@USC}\PYG{o}{.}\PYG{n}{EDU} \end{sphinxVerbatim} \sphinxAtStartPar \sphinxcode{\sphinxupquote{jqpublic@USC.EDU}} is only authorized to execute \sphinxcode{\sphinxupquote{ls}}, \sphinxcode{\sphinxupquote{mail}} and \sphinxcode{\sphinxupquote{klist}} commands. \sphinxcode{\sphinxupquote{jqpublic/secure@USC.EDU}} is authorized to execute any command. \sphinxcode{\sphinxupquote{jqpublic/admin@USC.EDU}} is not authorized to execute any command. Note, that \sphinxcode{\sphinxupquote{jqpublic/admin@USC.EDU}} is authorized to execute the target shell (regular ksu, without the \sphinxstylestrong{\sphinxhyphen{}e} option) but \sphinxcode{\sphinxupquote{jqpublic@USC.EDU}} is not. \sphinxAtStartPar The commands listed after the principal name must be either a full path names or just the program name. In the second case, \sphinxstylestrong{CMD\_PATH} specifying the location of authorized programs must be defined at the compilation time of ksu. Which command gets executed? \sphinxAtStartPar If the source user is root or the target user is the source user or the user is authorized to execute any command (\sphinxcode{\sphinxupquote{*}} entry) then command can be either a full or a relative path leading to the target program. Otherwise, the user must specify either a full path or just the program name. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}a} \sphinxstyleemphasis{args}} \sphinxAtStartPar Specify arguments to be passed to the target shell. Note that all flags and parameters following \sphinxhyphen{}a will be passed to the shell, thus all options intended for ksu must precede \sphinxstylestrong{\sphinxhyphen{}a}. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}a} option can be used to simulate the \sphinxstylestrong{\sphinxhyphen{}e} option if used as follows: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{o}{\PYGZhy{}}\PYG{n}{a} \PYG{o}{\PYGZhy{}}\PYG{n}{c} \PYG{p}{[}\PYG{n}{command} \PYG{p}{[}\PYG{n}{arguments}\PYG{p}{]}\PYG{p}{]}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}c} is interpreted by the c\sphinxhyphen{}shell to execute the command. \end{description} \subsection{INSTALLATION INSTRUCTIONS} \label{\detokenize{user/user_commands/ksu:installation-instructions}} \sphinxAtStartPar ksu can be compiled with the following four flags: \begin{description} \sphinxlineitem{\sphinxstylestrong{GET\_TGT\_VIA\_PASSWD}} \sphinxAtStartPar In case no appropriate tickets are found in the source cache, the user will be prompted for a Kerberos password. The password is then used to get a ticket granting ticket from the Kerberos server. The danger of configuring ksu with this macro is if the source user is logged in remotely and does not have a secure channel, the password may get exposed. \sphinxlineitem{\sphinxstylestrong{PRINC\_LOOK\_AHEAD}} \sphinxAtStartPar During the resolution of the default principal name, \sphinxstylestrong{PRINC\_LOOK\_AHEAD} enables ksu to find principal names in the .k5users file as described in the OPTIONS section (see \sphinxstylestrong{\sphinxhyphen{}n} option). \sphinxlineitem{\sphinxstylestrong{CMD\_PATH}} \sphinxAtStartPar Specifies a list of directories containing programs that users are authorized to execute (via .k5users file). \sphinxlineitem{\sphinxstylestrong{HAVE\_GETUSERSHELL}} \sphinxAtStartPar If the source user is non\sphinxhyphen{}root, ksu insists that the target user’s shell to be invoked is a “legal shellâ€. \sphinxstyleemphasis{getusershell(3)} is called to obtain the names of “legal shellsâ€. Note that the target user’s shell is obtained from the passwd file. \end{description} \sphinxAtStartPar Sample configuration: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{KSU\PYGZus{}OPTS} \PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{n}{DGET\PYGZus{}TGT\PYGZus{}VIA\PYGZus{}PASSWD} \PYG{o}{\PYGZhy{}}\PYG{n}{DPRINC\PYGZus{}LOOK\PYGZus{}AHEAD} \PYG{o}{\PYGZhy{}}\PYG{n}{DCMD\PYGZus{}PATH}\PYG{o}{=}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{\PYGZdq{}}\PYG{l+s+s1}{/bin /usr/ucb /local/bin}\PYG{l+s+s1}{\PYGZdq{}} \end{sphinxVerbatim} \sphinxAtStartPar ksu should be owned by root and have the set user id bit turned on. \sphinxAtStartPar ksu attempts to get a ticket for the end server just as Kerberized telnet and rlogin. Thus, there must be an entry for the server in the Kerberos database (e.g., \sphinxcode{\sphinxupquote{host/nii.isi.edu@ISI.EDU}}). The keytab file must be in an appropriate location. \subsection{SIDE EFFECTS} \label{\detokenize{user/user_commands/ksu:side-effects}} \sphinxAtStartPar ksu deletes all expired tickets from the source cache. \subsection{AUTHOR OF KSU} \label{\detokenize{user/user_commands/ksu:author-of-ksu}} \sphinxAtStartPar GENNADY (ARI) MEDVINSKY \subsection{ENVIRONMENT} \label{\detokenize{user/user_commands/ksu:environment}} \sphinxAtStartPar See {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{user/user_commands/ksu:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}}, {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}} \sphinxstepscope \section{kswitch} \label{\detokenize{user/user_commands/kswitch:kswitch}}\label{\detokenize{user/user_commands/kswitch:kswitch-1}}\label{\detokenize{user/user_commands/kswitch::doc}} \subsection{SYNOPSIS} \label{\detokenize{user/user_commands/kswitch:synopsis}} \sphinxAtStartPar \sphinxstylestrong{kswitch} \{\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{cachename}|\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{principal}\} \subsection{DESCRIPTION} \label{\detokenize{user/user_commands/kswitch:description}} \sphinxAtStartPar kswitch makes the specified credential cache the primary cache for the collection, if a cache collection is available. \subsection{OPTIONS} \label{\detokenize{user/user_commands/kswitch:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{cachename}} \sphinxAtStartPar Directly specifies the credential cache to be made primary. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{principal}} \sphinxAtStartPar Causes the cache collection to be searched for a cache containing credentials for \sphinxstyleemphasis{principal}. If one is found, that collection is made primary. \end{description} \subsection{ENVIRONMENT} \label{\detokenize{user/user_commands/kswitch:environment}} \sphinxAtStartPar See {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} for a description of Kerberos environment variables. \subsection{FILES} \label{\detokenize{user/user_commands/kswitch:files}}\begin{description} \sphinxlineitem{\DUrole{xref,std,std-ref}{DEFCCNAME}} \sphinxAtStartPar Default location of Kerberos 5 credentials cache \end{description} \subsection{SEE ALSO} \label{\detokenize{user/user_commands/kswitch:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}}, {\hyperref[\detokenize{user/user_commands/kdestroy:kdestroy-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kdestroy}}}}, {\hyperref[\detokenize{user/user_commands/klist:klist-1}]{\sphinxcrossref{\DUrole{std,std-ref}{klist}}}}, {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} \sphinxstepscope \section{kvno} \label{\detokenize{user/user_commands/kvno:kvno}}\label{\detokenize{user/user_commands/kvno:kvno-1}}\label{\detokenize{user/user_commands/kvno::doc}} \subsection{SYNOPSIS} \label{\detokenize{user/user_commands/kvno:synopsis}} \sphinxAtStartPar \sphinxstylestrong{kvno} {[}\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{ccache}{]} {[}\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{etype}{]} {[}\sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{keytab}{]} {[}\sphinxstylestrong{\sphinxhyphen{}q}{]} {[}\sphinxstylestrong{\sphinxhyphen{}u} | \sphinxstylestrong{\sphinxhyphen{}S} \sphinxstyleemphasis{sname}{]} {[}\sphinxstylestrong{\sphinxhyphen{}P}{]} {[}\sphinxstylestrong{\textendash{}cached\sphinxhyphen{}only}{]} {[}\sphinxstylestrong{\textendash{}no\sphinxhyphen{}store}{]} {[}\sphinxstylestrong{\textendash{}out\sphinxhyphen{}cache} \sphinxstyleemphasis{cache}{]} {[}{[}\{\sphinxstylestrong{\sphinxhyphen{}F} \sphinxstyleemphasis{cert\_file} | \{\sphinxstylestrong{\sphinxhyphen{}I} | \sphinxstylestrong{\sphinxhyphen{}U}\} \sphinxstyleemphasis{for\_user}\} {[}\sphinxstylestrong{\sphinxhyphen{}P}{]}{]} | \sphinxstylestrong{\textendash{}u2u} \sphinxstyleemphasis{ccache}{]} \sphinxstyleemphasis{service1 service2} … \subsection{DESCRIPTION} \label{\detokenize{user/user_commands/kvno:description}} \sphinxAtStartPar kvno acquires a service ticket for the specified Kerberos principals and prints out the key version numbers of each. \subsection{OPTIONS} \label{\detokenize{user/user_commands/kvno:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{ccache}} \sphinxAtStartPar Specifies the name of a credentials cache to use (if not the default) \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{etype}} \sphinxAtStartPar Specifies the enctype which will be requested for the session key of all the services named on the command line. This is useful in certain backward compatibility situations. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{keytab}} \sphinxAtStartPar Decrypt the acquired tickets using \sphinxstyleemphasis{keytab} to confirm their validity. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}q}} \sphinxAtStartPar Suppress printing output when successful. If a service ticket cannot be obtained, an error message will still be printed and kvno will exit with nonzero status. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}u}} \sphinxAtStartPar Use the unknown name type in requested service principal names. This option Cannot be used with \sphinxstyleemphasis{\sphinxhyphen{}S}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}P}} \sphinxAtStartPar Specifies that the \sphinxstyleemphasis{service1 service2} … arguments are to be treated as services for which credentials should be acquired using constrained delegation. This option is only valid when used in conjunction with protocol transition. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}S} \sphinxstyleemphasis{sname}} \sphinxAtStartPar Specifies that the \sphinxstyleemphasis{service1 service2} … arguments are interpreted as hostnames, and the service principals are to be constructed from those hostnames and the service name \sphinxstyleemphasis{sname}. The service hostnames will be canonicalized according to the usual rules for constructing service principals. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}I} \sphinxstyleemphasis{for\_user}} \sphinxAtStartPar Specifies that protocol transition (S4U2Self) is to be used to acquire a ticket on behalf of \sphinxstyleemphasis{for\_user}. If constrained delegation is not requested, the service name must match the credentials cache client principal. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}U} \sphinxstyleemphasis{for\_user}} \sphinxAtStartPar Same as \sphinxhyphen{}I, but treats \sphinxstyleemphasis{for\_user} as an enterprise name. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}F} \sphinxstyleemphasis{cert\_file}} \sphinxAtStartPar Specifies that protocol transition is to be used, identifying the client principal with the X.509 certificate in \sphinxstyleemphasis{cert\_file}. The certificate file must be in PEM format. \sphinxlineitem{\sphinxstylestrong{\textendash{}cached\sphinxhyphen{}only}} \sphinxAtStartPar Only retrieve credentials already present in the cache, not from the KDC. (Added in release 1.19.) \sphinxlineitem{\sphinxstylestrong{\textendash{}no\sphinxhyphen{}store}} \sphinxAtStartPar Do not store retrieved credentials in the cache. If \sphinxstylestrong{\textendash{}out\sphinxhyphen{}cache} is also specified, credentials will still be stored into the output credential cache. (Added in release 1.19.) \sphinxlineitem{\sphinxstylestrong{\textendash{}out\sphinxhyphen{}cache} \sphinxstyleemphasis{ccache}} \sphinxAtStartPar Initialize \sphinxstyleemphasis{ccache} and store all retrieved credentials into it. Do not store acquired credentials in the input cache. (Added in release 1.19.) \sphinxlineitem{\sphinxstylestrong{\textendash{}u2u} \sphinxstyleemphasis{ccache}} \sphinxAtStartPar Requests a user\sphinxhyphen{}to\sphinxhyphen{}user ticket. \sphinxstyleemphasis{ccache} must contain a local krbtgt ticket for the server principal. The reported version number will typically be 0, as the resulting ticket is not encrypted in the server’s long\sphinxhyphen{}term key. \end{description} \subsection{ENVIRONMENT} \label{\detokenize{user/user_commands/kvno:environment}} \sphinxAtStartPar See {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} for a description of Kerberos environment variables. \subsection{FILES} \label{\detokenize{user/user_commands/kvno:files}}\begin{description} \sphinxlineitem{\DUrole{xref,std,std-ref}{DEFCCNAME}} \sphinxAtStartPar Default location of the credentials cache \end{description} \subsection{SEE ALSO} \label{\detokenize{user/user_commands/kvno:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}}, {\hyperref[\detokenize{user/user_commands/kdestroy:kdestroy-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kdestroy}}}}, {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} \sphinxstepscope \section{sclient} \label{\detokenize{user/user_commands/sclient:sclient}}\label{\detokenize{user/user_commands/sclient:sclient-1}}\label{\detokenize{user/user_commands/sclient::doc}} \subsection{SYNOPSIS} \label{\detokenize{user/user_commands/sclient:synopsis}} \sphinxAtStartPar \sphinxstylestrong{sclient} \sphinxstyleemphasis{remotehost} \subsection{DESCRIPTION} \label{\detokenize{user/user_commands/sclient:description}} \sphinxAtStartPar sclient is a sample application, primarily useful for testing purposes. It contacts a sample server \DUrole{xref,std,std-ref}{sserver(8)} and authenticates to it using Kerberos version 5 tickets, then displays the server’s response. \subsection{ENVIRONMENT} \label{\detokenize{user/user_commands/sclient:environment}} \sphinxAtStartPar See {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{user/user_commands/sclient:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{user/user_commands/kinit:kinit-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kinit}}}}, \DUrole{xref,std,std-ref}{sserver(8)}, {\hyperref[\detokenize{user/user_config/kerberos:kerberos-7}]{\sphinxcrossref{\DUrole{std,std-ref}{kerberos}}}} \renewcommand{\indexname}{Index} \printindex \end{document}krb5-1.22.1/doc/pdf/admin.pdf0000664000175000017500000243023115051422751015452 0ustar ghudsonghudson%PDF-1.5 %ÐÔÅØ 1 0 obj << /Length 843 /Filter /FlateDecode >> stream xÚmUMoâ0½çWx•ÚÅNÈW…œ„H¶­ Zí•&¦‹Tàп~3Ú®öz¿™yóœ87?ž×Ûö¯nÝkõâNýehܤü¹=77Uß\®;?:׺vÜ==¨ç¡oÖî¬nËUµêöç;O^uÍû¥u#ëÿ¤Â½í»O ú¨Ûû=Ù˜‰a³?¿ûkLy 6FÑæ/7œö}÷ Ì½ÖÚ–][öH<Si£¦cãݾké¥^Ñ90¡j÷ÍYVôßü¬H^œÎî°êv}0Ÿ«é‹ß<‡ÒrLŸ†Ö ûîͯ_®/Çã»Ck¥ƒÅBµnç«øy·§¦Wý×øæãèTHkÃý›¾u§ã¶qö{sÁ\ë…š×õ"p]ûϞќòº¹KÏÕµÿ u”/‚¹A² )`JbD>`´öØ2ãš™$`¤TY'`”(ZqŠÇÁ¼BJÅŒ )KÒÌŒ%553<Æ,£è(‡hþl™×wBš6„‹0¦Ða™G„+L¤gıè«cŽWÀ c œrn œqœø9çÖÀ–ã°MÜ—8%Ç àŠCMq.â†5„Sâhr›ê›®®AƒáúI‚Öå皎­ú\SåþÈ©¿ÇÀ á]8 é`Y‡7ÑŒ1OÊyeäµñÖzlÃë,d mYĸ”S£SJfß-›1i‰:C&e c4ÎRÆÄÉØˆËÄ$D&™ Ë Æ&+ü¬bLõÉãaÉjÆ çÁbôÍy°üœ£‡+çÁbèÉYB¹ü‘þœõ§Ägý ñYJõYŠYrÖŸb–œõ§x(rÖÁèœõGT“õÌ›ËÁ`F+ƒÙ­L ,C9ô²â?d+þ£¯ÿ¡ÍŠÿÄÿ1£ÿ1—ÿ¡ÓŠÿðÄŠÿ˜×ŠÿT_ü‡~+þCg!þ£o!þƒ_ˆÿàâ?ôâ?åŠÿÄÿ‰/þ?ã«„°øY ñ³â?^ŒBü‡Ÿ¿\–jò‹UPñœŠ{Åð¡âxᇻLöó^U}9pQãóq½÷›Ë0øO}cèÖÇ}¿ïÜõ3tìÈ¢}¿Æ!VOuðÊñË· endstream endobj 3 0 obj << /Type /ObjStm /N 100 /First 829 /Length 1525 /Filter /FlateDecode >> stream xÚÍYMo7½ëWðçà,¿I Ha4MQ8( Ø Ô9¬%Å"[[ÉNëßGµŠ»ËÝÕ‡ÓLk)îÌ›yÙ!%XÁ “³ŒKÅxÁ¸1Œs&8f“šI%wL:|ï™öø^0#ÜHHfcÂ0'0i™³6ˆó$9ó†ã]æ=ÞÕ+%dà¿Å·¡K è)ä(h0J1õÆ ¦ ßc‘*!TL@‚ãAk&¤Æ3´KÒ`Ñü×bd$à`*„˜·LxiT o5³@ƽaV1)€Ñ+a€Teð½gÒ HcýȺWsp—Ç"g™Pæ ˜PhXÌ0‚Ÿ¼fJY<;¦4¼á=Lƒ^Û¸ñB2å6N‡œ  Ó[¬Áz]Ác0¬Ð…>|¥á çÁVØ /FDp8ÑÂñ+ZJ8¼èàd.‚ã‚«ÁV32¸PüC»Öà‰ƒ!m”‚" “ñ’m ojküˆCva hÒ.¬OÚ‡5 J{È1EPª 8Ç Z`×BÊ3#ƒRÐe¤w#¾Œ†q!þ áƒi! @™±o3ã‚@šñ0…"‹J`Än”“å!NAœ’át+áuꬔX¯Y äY½ jά !ú¬^þì†h}x ºB üðà #Foß²7WìÍËë%{óž½ÏÊêqº:çgìݻѫi þìMQ?…á! ë0<†¡ †’¾˜‡aIoܪÿïÂðD &a˜ž5P¬§ãÇùò᜷áø>½Q7M×-"Ÿnw¤hßœ–ÜíZu†÷„-£¼>—iߪ+iédwzœúå3ŽN_‘¯¶/môÌÓ­ÞH¸'µ›¹çŒñ½v«¦Ý?s“ñ뾆öFc|sAh!¯*Wåݪ¬f¯ÏuÓ€/¤ï6 : çm0;›Œà I(³æq›Ù?1ÊtõF†’I*©$w”ÑÓ^¬®‰õ‚„O;`B‘·å<Ý@µ0XÒܺaêr€ñd÷Ç®0ê5Ôÿß ½¤™ØñqÙ|úyÑtËU*sÕH'7`JÎ^¦y»´™F¾måü¨â‘óA•V»1É^ívò‡& YÊTÂúZýÜtëÆæŒûáÅ핽 ˰Âüb[jð/éΨHÃÝþbH*èÎI1(Ƥâ8¯´î©]ŸèÃ}ÒÕZ”-ýÅÆ?ßõïr3¸Fì›ëjyéÜ7O ]^?NSl¦ü™v‹1J2íù‰8ÓZŸt3ÖÍt]ù|œª¿o9씿ï¬öõÞ–8åëÈOFê¯aø™ýÖ!Õ\¾]uß’ª¢²éÀð™’q õÿÕ™© -U±Ëû†ÙýÖ…ñ*M_ÓÇ~FDK'zÝžéº;‘ƒO‚grß2ÍÍsÂ×ÔWÍU·$æ©P15Œ;Z“¶ÎlÝu‰#zkÙMeÖ(èî~EK÷û{šbnãÅdÚÈ=ѺGŠýOÝÚtF[íð³ M=D¨É¤ù¡L«Á —¶SuV›Ñ3r•nÙP{\Fr™Qâ3Úb¡y¢?O–O}çÙR7Æ4Ääºh ãm꘷ìøUjõ8¿vÁ´ìýŠÚç?ÈÒf†=‘I?µk-½ ±º,iýé‘É•iÑœ½ 2•‰¡EÚ©OûezæÚ­ò›˜/M»v¶äƶÆ"›¯Nïù–ĺ Dã·‰›‰…izúr`’­\æ–ä’šøØÎ_7®L«Ã*¶ô™6 J“èœlzî8ò Ã;OëÍCŠü±qk0O[ÆxÛx¿ÇùyÇfUêéÁÍÝQôÔÕã¸eÚ1ÇcK-“›¿¿Ò^"–ßÞÛ‡]H¹Ö4©ÒJ|”÷>ß©–úó(ýH?Œ^þÒŠÕ endstream endobj 204 0 obj << /Type /ObjStm /N 100 /First 874 /Length 1538 /Filter /FlateDecode >> stream xÚÅXïo9ýž¿ÂéI´þí] !…Ñ^+('N×û°$i‘6Qšõ¿¿7ÌÖY{7 EH­w7¶ß̼y{WK#¤Ð2SàRˆR ­”PºÄU U W9ü£[y¡ƒÅµ}ZKa¼ÁÕS†žÖVØ@ÏA8 j]ç0Ï(á×hái¼q—è7^„ås)=[) ‡gkDQÏZ¸CÏA”^áZ%-œqpPèqðPLu.“ŸÎ“ïpÒ•BXÔ^ e-Â)e ×[¡û€Bö@ö4=ÙU 𡃥È\PØÈ…/àF%¦ÃUê²§ —˜¡ ø$LÄ›Ä,§¡^2L–Gœéè¦@SÂK ¦”­Æ ©lÏHK>!MDl@p†œ+á¸Aº0A.s‚n‹‡éÑà_à C)Ó ÎPÎp‡üjœï-lÀÏ„îy30Hœñà‡x4Akš‡È)$žßM©¹¦æb¯Óg—ñyAÍœš[^ðã²cØî3èÃs»}ÓžUóêr^ÍF MЄ ØÐ5;?a»7Ôü×n­ÈX›3|Å W›‚–Ð¥Ï_Ï{'; ]1÷ƒØÆpS*ccÂÈ—ÜŒ9É— ë ò”9˜ePÖ„èL锚÷Ô¼£æ/¾;{¸R§leC¥®[N…×<¿ÏJºoµ³òfnèCb‘¿çù÷œç*Ö×Ê脺©µ×m4·ö+VÝ,ÖÚÊÞ&…íáø7ìßd³²ää §ÿˆSô±©øu%ßdJ~Åô,ItÌQÅDMºOT Ã:pj^Qói9奱|~ñ¼€[õq¡fDÍ<®ô]1ê>Æ×[xuè4á“&~F‹¯V'u$FiT2ÇôÍyOÍ›4KÕ³è‰i\vArït‘ƼÓö ŸÞivk+§ÑÊYÌ“IüzÍ-iâàÿ…•nk+çø"ªž~g;š‹Óéb4;ò/^ï¹OÏø×I$d9þ.êj-ºXýí’v±‘ä¶|^Æikiø‘Oæ¹™b3Ý; çÜøoüë<^!µ«tÌÞóÂs–Óv{¶¢0¥òu ºaÁ¥;GæÜEäeÙsù@#»ÖïQåu\îÛ£˜sÎãøú†%¶º?"€Ò&¼€¼Gº|ù+&ø˜ïAË¡ O‚Qº5|ò01t¼Fr)T¦D¥jÞÂ1'䮤?Aü;^±Kç ¶}Œk.»Ç¼~¦6µRáhø¤ŽÌfþRgŒVô{¾›Ìz±-wܹWåð»ã¦^n»7ìºÏüIÍWÿºÏÛ¯\Ó"í¡2§IWçýW§ªô›hÛyTy©]¤Ï®KË%²ëCú•G«·Ü-Eïe{"?G3n ˆºÂ?ääŒÓg]ôìŽÝ?®U®Õ lÝ|#2•©pDZéŽR¿õîêÎ?¬Žcf\­Þ¿€mdrÊ D§¨,;›±,$²êðSâ`Ú=°:ÕëŸ"n.Ã{‘(V…}UV©€MáÌì ýǘ®ŒR¨‡Ü“§ü`?Ï> stream xÚ½XÛn7}×Wð1éƒÍû@ m‚Ö@m± €_dIv_äJ²Óü}7ð¬¨åîJ²UæÎ.É3—3’òÒ )¼ŒÂá•ÊáU¡Bz·Â`€W„î€gNyáµÎF<µð„ïÚ RjàµÁ`¾Ž"ẋ¬dÄ@€+•zŒJ¦ªÂ®²xóVAð@³Z(/ÓÁ„·^(òéK„a8°RÌð.™JPဓ ä˜p\ZB¡÷ BRêµÐ Nxï 8?ðÞ ­“Ë>Bè")´1$ ”¬ÐÖÁm¼hmå³vipròÚ “N29Ø€8€<@Ž)lÈ1 +¦ø¦GX!Ú>0¤FËACÀ`B°ŒÑn@Ò c1˜kÖiÄ^ ã@ 8ã\„d¯  §Ü6”ˆÂ8C`‡Àž Èøj‚2<1ÑšŸµ2Mƒ6QI¨Ui:8³Z¦®!Àfða ô´„´&êAk-fÁk6BЭSP­Ãa‚u1u9åâ(,¥ À›0 Z›Á  ÉB0hC²á³ý”P jšé$x J™lSœB?Á[§S|À ÓÞ  :“̃Πý3EŒ :XȘÈøƒä´žBãR.0èŸ :2qðî8<‡ÎÎgâð£x³˜Œ–ÓÙýòê­xÿ~ðæ áŸ.¤”ŸRsŸšQj–©ù™š‡ÔLR³HÍ…´2=§<þùËœþ“šÇ|^¸xÛe•nZu–ƒ,Xó¬¡þ†‡þ\ý¼àÏ·,Õ®`ušfš¦ý‘šï<–ÛW™v½jÈdË_1ê|õó°ì\5æ‰ÕW*&.Ù—êÈ^1Ü5:g–\<ñ¨9ª^/s"ºóÁ픥Ï6ŒØ´;°fø%K·,ý‚ì´Ë7í:ÎCUŠR3#ª?XúÙ`ž»ðÜ7c‹Ç9ÿ-©6Ï£ÔE\1+›Á}>,'óEÍPü•šsn>ó2~Öñ»öoÃ÷ÑKÒ°ƒ9*Õ½Ms¾…Ã%WfòÕIU²ì‹hhšø-YÓvŸ`´ÑÚ¬·Í¬«N—¥±ÅÒ1'l­jšï›U‘µDY[Yw}$–è¾áùëf/WÁJpUbKÍIjNóŒ?ª¤~àÂÆ÷‘«ÝgéÆüÌËëˆÕžôë)ìb§­pÚn[lÿÀ˜•ô;KgìÙ3Ï/¶Áµ,ëS.ÍǬþ„-lfìß|¡Ò×¹S5ÊPž«Ó¼øNóÍç¶_i¡¦Þñ"¨×ìU]7_߆Bšçe§^ƒ“=Ù7þ0¯¶Ã¶Ê+ ÙT0.œ—{t’ 5eÄE~˜ï9M†ùÉøG^¼Çýê •ç!ß÷jÍkì \¨7×yX÷ÑBAº-lA[kÞÐg·±ÏkÛáÚcU…ê´ØVU¿ê]%¯¡%lWig9­£¶C{®%è•Ö•š•™•Úí–ÞŽZÜk­¤jÚy#\Sê[Nu˵¤éG¢.¤z¿«Sä©íZ½Zâ2coúA ûß#/©­á¢ÜŽ«ÍYSZØÞj¸_÷íþão¹dñqòœO{Õù[?&µü¶P¿2ú—ü,zœ;ï×Zî Ÿ§àêtú78í¼Ùèmn6«aq_×ý?]oô®7ºt½ÙCžèÒæ5òÄ´äɘþr«‹þ1¿’ßöÙmvOšÿ“`…Ó endstream endobj 807 0 obj << /Type /ObjStm /N 100 /First 877 /Length 1074 /Filter /FlateDecode >> stream xÚÍWmk9þ¾¿BÛÂ9’fô2P ¥ ¥pi:WÈ—4É]CÒØ$Íý÷÷̽x÷vÝÚ¦2i¥g^ž‘Æ©>;ïjðŽ*†à‚gŒìGŒÉÅ”1VE×Å'WcÄvÂHŽ#ÖcvœcScqɇ¼KŒs\ªÀ!v9ŒÉå¤óê²è\\V…­’1gr¥ŒY1›ÊÐ+ÜKÞ lלØMðÏL JÁîT]p·&RáSŽ.D8X3¹@ØXs†"ÜÔ\·x(ž§ [— 3ŸCÎ0^€\4øЦ)€) W cÖT8„±Y€, ÂŒð C!ý„¤|¯‚¬Æ¨+¾ˆ.’(E£=‘ª4â‹‹5 ¢“OP€¬ÎKKWÑ çÀmÒbÖd9]AFb‚äJ±LÀZ5 ÚÈ㨀7òH­€8ÒŠ0G¡êf”BÔÍX¥X±ä{DdÐGŒ™‚#)Eøƒ}”ÀŒ€j]…ÒâÄF$M¸`UäFÀ Uö€AÒ¬ ²S8IUƒì#Ž#löàJÀ km<à 5„UþÔ¶€q XKm”3&M&°˜ô8dV@0ˆh` r"ýä¤ÄA\­J¸É9Õ€±À åæùsw4wGo§ wôÚ=yxüôpuñõzq7 2£Y|ê^¼hžœQÉø+gÞû×*ŽUÌU¼RñAÅ[¿©8µé{ڡM;¯ìü‰‰—-œyñ‹Š_ÍØ;óì̳·ã½.µþûÅßå×°a?›Ið…Š{W*ÎU|m§ãpyîÒ ©E_¨ø6ŽY71WHç6ý<Š„rpïQÅË (=Åxkµ]N@éÉü¹åæf@¸4q¨Xd7ÆÃ· à=D>Zª¯~¼ $ðºËí…v×3=…³´@Ú4ÿ5ÍT[2¯¥‘±vÖ .Í™6ú;»ÿm¸ê.ß›[K¼¶ê»w5ô\‚ÕUú4ýN¬¿O=µxloÑïöæ}è>|'Ý}§ãvzÊrn '÷¥½Éí†÷=Ø+àž»xc‰hS’Ö)¹í’º\ÿöØeåv,&ž…˜>ZbVícn©œ¦iòOÚ4yoM3Úi×Ä/°M¼/v§/­˜þœøÀ†žöoCiýûgŠì¾™‡Æßþ (4ñ7i÷–ƒåÄðcÚ†ä'}Ñìbj~Ê6¥°3«2^0»²Eaë²Ú™iÚî‡Ç¶¶ÖŸÃtDÞWGLñ¾ÛW]òbÌÕ´¯F—ÔèR_£ûÁ&•úšTëöFÙ‰™hÉ;Ç> stream xÚÕX[OG~çWÌc¨T3÷KEЉª†Ra·j%^À°BlŠM.ÿ¾ßðY»ko‘m©Hæznß7gfQR!…’J 鯆°ÔpBYê(/TÌSIhŽÔRhOSÚ#i·¶Âø<„•v(¬£]F ›5´pY¡qÂEÚe¼ð&O%á}"ÃRL£aD†VD•§‚ˆ.@³"išrJ$OÛ~òWº¼—Ì:ò&ÒF¡à—’FU Yýš“±êH <–-aÁc‰ ¤™„UäkÀkó%&û Ài² m“4á5é‹°á³6‚&×"lOù¡ŒÆœqJN ä_¶dÈ«„ʼn Éä…–ŽIH¿LPªr­r´ Za¦µŒÔ hY¿‡VÚ øAËQøèjK+$L[ò@!Ú¦<Î ÂØ‘ã ¹Úy 6||J§:ÂpÖ!ï’:æ½@ZG UK´¢l$ŸÇ‘Q* m¤£1KDJy LzŒ€Ô˜ì 7&Ïsc5yÌÍš¹qÙ07Žh¡€¹ñüæ&HZÌM”´ÛL4ÀC<+­æ–؆–V[G-‡Á ô„5)%a-Ì­ËyæÖåHõ#$Âzb.",sˆu ˜Û$)§P È.á2á0wàÂe˜;4©e…KH'Z­÷Þ¼}qðq:˜ŠƒCñjöp1 çã餧R/ôô¾xûvïÕ™ ¿áLJyHâˆDŸÄ{§$~!ñ;‰wOHü¶¿ÖŽ©Û9iU—m¯×ië:?°¦OUë5¹º¦#öäOÖyZºx\®¬·ãëvú¬$‹3T<úûŽcÈ NtWŠc]ígw$îIL¹{ËÝëuþÆžjñ÷oº±Ïiê¯W¼ÚÅ-Ð.6Ñn d‰M¤ÜYR Yæ$¸5ÎdYçeÚEÒŽ(’š(òž÷³xÇñ®€uÿÔÃUW×|Ë©åLwÐÒP3ò‘‘8'q™¹€J…e½¡®÷+3F/RÞP‘†åùý²òä¦Ë—l¡²U$w&<—ýø±Þ •uƒ—›° Ö“fÙLE…øüŽÊ¥³V[¥o¼Žå“ÔVÿâósÌçôñz^¯s77sÚÖͬdKµuŒQFðëKН’Ûª¾Ð¼›ò Cf'ÃÝÄ ÌXŒJˆ»kU[Ví XÕõb­0]¤ÿˆíW Ÿ./8.ýí3f»?úáànr0´É—Üðæün>ºïé†ÊrÌ>–•þZñ¢ìN™«‹õÕzÅÜ_D­wÊSȺ±*},ïÄÊü9+Þ˜ù†Ÿ²Î»òF²‰"[‡ÌÖÅpÓ·TÞwÍ­ªtO9ÐeZŽíj…÷•“75̯Øíûåá?8×w?—ü\=®ž6eÅ?ÊGH^ð¥%Læ´j9‘. ã† «}öÞZøòµ|k޹{Q>WyÕÀ§AéÆC“FNô”EÅIÛøqÝtŠå±ÖR¿ôuÏ¢«½†0?5½<ŸLM™6‹‘êPß—l𭬑dº)Ø+ß·Ô·L·‚€£ré&œÔ-ôlT×Õ¡‹šûÕÅ—¿./ù†»¦¥¢Ý°­Â× ÇQxÿÀeä® tÞ¡ŒTQ«!ÖµªnÎË¥Ù¿qãòè-\—_€ÏOßòÒqYèæe±(î§aÉËËJ>ÛÙ7ßòÅüŸ UoTV½«†;oUæ«;åYv³¯;\™ÿK‚u€*´> stream xÚmTËŽâ0¼ç+¼$æÀà$0Š ‰Ã£­ö ‰a#A%áÀ߯«›ÀÌjDÕå²»«ífðãc;ZæÕÁŽÌ«Ÿ¶­®MfGÑÏ}í q•]/¶ìÞ­ÍmÞ¯¶o⣩²­íÄ0ZÇë²è^œx]fçkn{ÕÿE+{*ʧyÄpg6;5’PìŠîìVž¤pH8$hù—mÚ¢*ß„z•R:")󨺠ÊÖß3‰qŸûX”ysO'Hî)-ò"ëî}³‹³‹ÍÛ[ÛÙ˺s á3 4†{´¢p¿YôdšrýØëKæ‘+ˆ™ÇÞ a }ÀõàíÑ« W€‡Œ{ Fvm734…4˜‡¢´A­«»èGÞÿc Ú¤Þ_86 endstream endobj 1288 0 obj << /Length 770 /Filter /FlateDecode >> stream xÚmUËn£0ÝóžE¥Î"±y$UÉ6 É¢5Õh¶)8¤"’,ú÷ãc\W³Ýsß/.7?ž·3ÑôozÆï(yѧþ2Ôz¦vÇèæ¦èëËAwçG­ÝŒÒÓ=yúz«ÏäVmŠMמåMW\=jý_Iê÷¶ó*ˆCn_õŸÙÃfö ¯íùÃ&1yØ+ü­‡SÛw÷$¾£”FÙ5ª? ÅS4¿†!ó1ð¾íšá‹¼!r3Ò´õùŠì»>˜Za¼ý<õaÓíûhµ"ó#<‡O›ËÏhþ44zh»wrû°1p{9?4B“4Z¯I£÷Æ‹©çqwÐd>å?ñ¯É»Ü=ûõó¨‰Ã±K«î}:îj=ìºw­(]“UU­#Ý5ßd¦kò¶u¥Ñ¥¥y že¥ÖÑ*†ƒx12+ƒ¹Sx¦æ,öÌÒ09Ì9Ô)5t´J N¦Š'†™™{fSÉ –2Œ¬Rà̼   KÙÀÒV i‰X¤¤†BÆRs>–^ÿÝ ×.¹¢KäCc†2—ÀÜc4‰&WÀ©o"²¦™ÇÖîq¼ð8^zlã p5u%†=c¾K(œq/‡?–xŒQ±Ôcøc™·/€s/G|¶°£•¨•-mõ„¥•鯝P/S8+8èÂÑ 4fÁR§SYZ"?.ì‚0»1Òшŕ[KŽþòÒñ­¾õÃúPKS6Ò×0ÃÔæ—eÈ;Uކ}Z8~S›gÈ;­ _™õÇàg®v»ói;K¹æÊcÄÌ g‡ÝÌ­oZ ÞÜú¦ ú¶ø’'ü êê„LÄá^ î¥àá^Š$ÜK‘†{)²p/Eî¥X„{)–á^ î¥(½ߎ‡¨> stream xÚmVMoÛ8¼ûWhÒCj~H”\HÉrhSÔÁb¯ŽÄd IJ!Û‡üûÕ¼±Ã¢ØƒõøÞ¼!9ÔÝ_?7¾?¼ÄûUe¿âép»øPßgwwÍ¡»ìãpþcûÛÛÓ·ìçxè6ñœÝ×Íã°;™‚‡îýÒÇ[Ôÿ…ø¶Rêd÷ÏñŸ‡§ï›…ˆçÝù}z“³ eÊäõßq<í÷LUJM롯{°<Íæ×JÙüVûu7ôãµ\ö‚â3m²~ׯOòßí§v1yóq:Çýãðz˜-—Ùü×ôòt?„Í—Ùüiìã¸Þ²û‰Ïô¼¹ïµ35[­²>¾Ni¦ž~l÷1›§>_\é“}~þ8ÆÌȳ&±îÐÇÓqÛÅq;¼ÅÙR©U¶lÛÕ,ýï g¼¼^Cs=…~úk*[4õ¢^Í–¥™žåO×mT·I:/nYº·ãµž1ÚLs*J`#¸lœ ne¼ÀÜ¢ì8W—Ìi+Á‹xAì€=±Ì ÄpM¼n˜?¯™SbZbÄhòÏ`-؃6‚+ÔÒ–µtΘ¸ 7 þÆûXøû €ÉßB[Mþ98hò¯ ›&ÿ ýjòwÐJ7Äà¯É¿”qò/1n„¿^ –ÑÄÈi 1z1–ùMN þ¦ F_ƃ›¡þ¹Ä ÝHþ±ä÷Ä’?K|M,ù愆fý[þ«þÐÜ e‘ÓRÿ©Õ S…xKýúµÂ¿¨e¹‚ä‘ýc­Ä íQ×Rþ–ú+™ëe¿y¬‹¥þ ëhÉ_Ë8ùkôh©¿G_–ü=âsêoSsƒ¹9µµ¨›S[‹<9õ”^rê©%æZ:ä¬kÁ³`Nø‚<åÜ'{¸à>© [AžkZ§&ŽûÜ#¿£Îùä· 9%F-—ËÜ‚µÏ©ì=WC'}•k‰_K—óRV³ᯌÔõÄèQàV ç$¾!–6n/xzjgÿu › endstream endobj 1290 0 obj << /Length 1026 /Filter /FlateDecode >> stream xÚm–KoÛ0 ÇïþÞ¡@wÈbK²EÉ ‡=°î©­v;p’C¿ýLÒ2­b‡ü™z”é¿n>ý|ܘnxvù%‰¹óp[·)¿íOÑÍM5´×£ë/ßë\ç½ç¯ñÏqhÝ%¾-ª‡þpù< ~èÛ·kçü¨ÿ²îõÐóØ'¾}r6ßê?›F<.o“‡Æ“OVŒîßn<†þkœ~I1=¨û®Žå9ÚÎ;Å[¿÷Ë¡ïÆy»ø6Rw‡ö2þ·Ç)]˜üø~¾¸ãCÿ2Dwwñö×ä<_ÆwŒæs´ý1vn<ô¯ñíÏÄ×ÓéÍÁÞqÝßÇ{™–™rú¾?ºxË),Ž9|Šž?½Ÿ\LœR`íйóiߺqß¿ºè.Iî㻦¹\ß}𥹢9Ï/íßý8Öß5õdNœžrf=KâʳšXÈÄxΈ—ñ9ñ²¾&^Ößázz_/ë¯ëe¾%^æ—ÀI%À®Ð®s°k°‹f™×ûyé*ïx•7²`?¬Jö#+® rÆuAι.Ț낼㺠\dÃuA¶\är® ØÕ\°Wyã¸UÞÀb•·^å¼:oäÕy#¯ÎyuÞÈ«óF^7ò꼑Wçl8/a9/Qr^8®â¼WyÃù‰†Þ…lf™`…;%»[ mpŒ$[MyX[RŽÞ+Iù¨¥¤ÜL6§Ñ`ÓYÜË 9HKvvI6ä)+²K°k² Ø Ù§šã‡¹Šâ7ð+Š¿€¹Šâ/°×Qe\G…ñ›$Ÿû@if¨Â<„¨½¿`F¿¡ñ‰÷[fô—Ä©÷WÌ诉…÷7ÌàÏ0O‘úùæ*’Ƴ xü÷"ÜE)=+b¿~–ÑúÊsN~¦‰—ýv¼?ÆSðþȆ÷G¶¼?rÉû#W¼?rÍû#7¼?p>çïãËSfôcÊ¥~¹dF¿b†w4ψ}}òœÇkf¿ãþGÁýl¸ÿ‘-÷?rÉý\qÿ#×ÜÿÈ ÷?°žó÷z¢Sfô fˆWKfèUM}k¡5õ­…ÐsßBohÍ:¡çï0οÁÐÿšò¬ ÷4}{ÆCùU¸NµzŽçšVcC6¬¹û ¯&á9&ýà¡öj¯Q¡öš,Ô^“‡Úkt¨½fj¯)Bí5&Ô^S…ÚkêP{MÃÚk®©MCíµ"Ô^+Cíµ*Ô^›…ÚkóP{­µ×îBíµE¨½Ö„Úkm¨½¶ µ×V¡öÚ:Ô^Ûð·µLøÛZ¦¡ö–"ÔÞR†Ú[ªå=™njó îlpÅ\®†íu§[#ÞCñW¿Cï–«êi8Á,üá×ß™~4Ñ?„ãªs endstream endobj 1292 0 obj << /Length 212 /Filter /FlateDecode >> stream xÚe=oÂ0†wÿŠí«ï⯌TjTÚzC ´1U$"ñ÷{!ª2½Öù}ÝYø eÿåI‘¤‚ÈÉ¢¯|uj½±ÐÈ|ë:ÀõÖêÀ…$¹‡õvçzÌêáٰØ"AÞÅ ‰#„ÀÈ!7°Ö/†½.ýg郙qLznÈë¦kípîÍÌëí¹=¦¿Å¥mŠÙ䕸+ŠÇ»ÑÍ®Æñ)-L²âÍý^öe;” %dFúeé/›Ú((B²Õľ.󨽻ë)«ŽqG¢ endstream endobj 1299 0 obj << /Length 19 /Filter /FlateDecode >> stream xÚ3PHW0Ppç2ÀAc(á endstream endobj 1325 0 obj << /Length 800 /Filter /FlateDecode >> stream xÚ­—ÉzÚ0…÷<…–ò®K¶–ÈØ¼K³0¶úblê!)o_É„©ÐoÀ ûsî¹W€Àu™÷ó ÷íÊÅ»u9Á p9và€»Ä!ƒ OðÂbðaôe38²žƒ»ròr¨çªW×ç P‹îL>^«œáNxÁ¦¾X†°1ÂÇBÇÀ–#o³²ja˜¦a%ó̲ CpRË8Ñ ¼B¥R?GíŸÃv»€M°#°§—!†ã"Ï~!êNêbâJ¦I¹EÁ|QoEq†YAcøzj0-‚`¦3 í£Š“H–j´EödSÌ9.û,Údq Ëeh23ËD‡ã™ÌdYœCÊ°Ž”aÿ¦©ó#éáApqfQ£(¯³J#¤yÔdìÕrÌëê0 û"Œ±¬·cY™M4ÎýÒ>Å8),Ì`^êÙwYMõÓÃ<ɾ_ZŒÁ³¡ž‡í`ÐN²xÛS„2Ï…\|ÑS~+à|žÊhÍÌeR¼5¢&ÅáLzeR›¼¬öרA Ö Fª³*Šs£~=7©Ê_ZY¢ZåP%S§ ÷ˆ@¢#4¬Ñ†÷·ƒÛàóù¸—c¢9ãÔ¡Ö#¬«i’U­‰¢xIB5ÊhhùÊÂ÷ý“ºÊ‘«T;RÛA¬9ÊrÕb5,a±0m»2½ÓÔúr²åëÎB„O1ø‹åŽ™1‘jM‘œ‡©™…³Ä=T­fùp9ÔLÐŽ4㩟EÅbÞ(öÑ„Žo$¢«Â÷4ÅM G:ø\÷ê&•ÿQojŸ' (NîÉm…ùk.Ú4ñ’Bfq3Îw;³:G1¾:¡S*^/±©XwõÆAc]¨IÎŽÑnˆˆiÓ?ÚF¸“—fÖiuÌí ·fn´z“'›%í¹äÍ" ¨áxÏ v‹ÉëˆÉ4ìÀ⪹,ê&ú4Ïuµ©îtDl|Þz¿{X="€GsÂ=ÍzOÏÄjú®!>x_~i¦nФ`Ôû¹ºë|\DõBºè`LtH¹ð/Jãþ endstream endobj 1333 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚ¥‘MK1†ïùsLg&Ÿ{TÐbojðRzM•Åv«­_?ß´a…*hÁK&™wx߇  LŽU3F@m‚-§6EøÑ¼žˆ³$N.¼V·ž=¤{ P£ 2Ì$Õ8Dyª Êü¦ØÉ»¡[dÕ°Cù²~ê»­š§éW8Xg4:_{rTõ£¡ -&ÝÒHb+É­Š…aÓ¯_·bÙ1´ÿdˆÕèrÈ Å(?~ót Ÿ'ñ,¨\h÷ÁÎjöº•˜ÍriOwùm„÷ýÐ ¬/D°„qUwdépG–5׸¾ÿžö gµqX endstream endobj 1339 0 obj << /Length 2374 /Filter /FlateDecode >> stream xÚÝksÜ6î»…>jg² )Šzä››8©ûpÚx;ývndIöꢕ¶’6߯?€€++©7¾™›»dÆ"A@¼È•Î#wg’¿)øJG9¡ç„J £'Ý}üS:Àp¤ˆãÀ¹·X;Ç"ø–ÎõÙ¯gßmÎ^¾õ•‹8ðgsëø±‘TN{BIãl2ç£ûzµ6î÷ç¿l.>¬þÜü`I”/´xH£B¡”rÖž1|-Éû« D=»Ø ˜P„Ú?UÀÉn: E€œ”>mvyu½2îf÷ü§ŸVk%ÝóU$ÝÍåû«ÕÚ #÷Ýo—oH ÞlR(ÐX /ÐðWÊi`áðû3g­•±[®-€5TB3<ñǵ‘Ò}]WˆŸW]ûL†d*%bc¬©$Š.âh”ø?%óeÕvèIYÕÙøÇ7¯xùVG×i<8Æ€ê÷m^­ÖÚ·Í»ÎrÁÉaOßWžtóæ&oê– £'ôÙ7uvH»¢f0pÓÒý\4uµ[¾h¤Ü¢cbfr“·+e\†v5}·‰¥]i`CÝ¡ìŠ}ɳ&ß—EÊ[=I’²®îÚ"c¬û¢Ûö"‚Pa: Rx߀¤[ì<€£1²ƒA(­0È«öÐä4î¶9-¦à$EuÈ3‚³¼lU”ÉMQÝ!Ö·SJä?’¶ÿ—å˜-C>iÞ \îE’¢y¶3Ñp÷¤¨Ú~sûIë=J±¸/ŽpÁYÒ%7I›ãÎZ»¤óŒ\2‚­,8eÁYדÝ30ÅSóü©€ˆ€Q4yRîhØËò‚ym‹Þ 8E"ë]Þï]?âÈnÂ/ê ·0ä»Ciu„IQuýiØC-ñ@|˜ž—%aô"ÒŒÄK hÛÊÀ?¤‘ía ¯ì“¶½Gï®›l‘*&ix‹]’ñ# ¿¤'²[8¢Èj,áƒåÚ#Œ#èc¢F±>ÛòäÌk¢ÜÎ`ŸìB·¾³é½I*JHsäÈx„€psèh±ªy01 pM²]Q” š³ÞÛ´„¤®\öH`A ëEKßC5 ËÒ:· ÝŸ/7K®Ðäi½ƒd•!ƒTÝZç€ÑÃÊ=àøW$gb}V‡õ齡%(˰&79Rl +ʽ=TœCízKø9d²¼é…b’%3  ŒWWùT(9rXØéÅb`ÜV­HCdAa?X§¼#Ò·¼á–½4+x¹ÊÁãÚ)[MQ˜çT …'#,ž¡ý( º:ÚÒ“Z©Ã@HÕ—LsmõßÚ’Ó[¥H=lœT™5ëº'>ö5$_ÊO_*ׯ‘÷`‚2uÁ p☠;‘Màušg¶„Y$FÆØË8W}âL†ÔÊ‘`ùˆ#¹æ-¤†U…Oîq§´Â#Ç‹­äWÈ¥!ÿˆƒÑ±0Ò{‹©±aŽŸª@oÛ C/6Qƒ!48 tÄ1gÔßWP{“¦Gy5;Þ œÐª@ø: E¬=>dH€_s‰H\™ vÎS6@ÚŒMò|G°&/ [¨¢ˆÎ`]Ïb¹Á Äj9vbiÇÄÅŽ©‹êÖÆ;…áŽ]híûƽà^ŠvKºÙ¾‹™!´‘dÅD»˜·çqdGÇ]$‡Âò(p²@Û‡Š’´ªÔŽÙ¾¦¬©Ðµâk綦C sÓßpn—ØûJ?íˆ%wÄ=ª9¸`m‚+d©CE`n†^3¤ÍS0y6£Êò̶N ß&MvoÏO¸y†µ²ØŒè»IŠO3ÝË[ÂÓ;¢Ø<Î-õ[e‹U#´/ •ißV—ÐŒ­ƒ=´ù¾ êðvóËß¡ØPËoþÍúeˆ>úÒrEzÓ£\ Sˆ“ª£ñŽÛñ¢Ê™Y[ïrªR°|¿­‰´¾Á–Øz€›ºîYZë-5^8ßáŽ\öd{rÜE³«në²O㜳“j±§®[ƃMÚ¾S?”ìÜûº¥ ô¦1îÐÝ“1ɺÜYÏr̤eç`9íŽ< 'í ¨Æk_ O±ÇL.·t³¥|¸{ ÷Ü¡™(ÈÈmq4”dÖ®Ä'܈/ú¼E­‡Æ Æ·M½›™éýõzÒQ÷¶O(¯$ãeÁp¶\æÒBh¥<Ænæ:çIVÿãæP”5¤þG[ÛÿWkÏóD(Õ¼Øa!>±Ø/…„!Yë mU¯ eïòWô,ud\/ú—·h‚^çAÓýŽk?¸ïèÑ}ß’ÕéaG‰WCÛFñ¸èêГœ©"•¥=Œ{êÚ\%»¼}5¸¬ñcgþeÇ]Z"óöÆ "PP;JûŒ öuþr¨ð_ÖlšîM&µ0ÆXp 3Þ¯ð|èiA íCc0´“NføÃ?K>ðMÆ#Ç `´qÇ”ËaRö9²“ãv)L4`ËŸ?Òj–þßëwëüê€ïÄ?ۋEŸì¤;[2—/|Pγö2¼2Ø«½úY ÙÐ<õE` ®G^p¿· Ygj4“¡AžjŠo £G üíM¹b¸BÁWi5kOJIÑqJRQ,Âø§Ésæ£Áû?Vž#ˆ}Mu›=@óó,z¸z@oÒ]Ϙ¬ &E[Π’á„+Ù¼¹ú×ówx¬ÎQt_¶§"Rÿm;)(„ËvnKvâvë|óýÅÕù³äå7¤o¦¿xóÛ)újõe}í»)±œ=éÌwIøÉ)z2jxcÉ-ÜõsŸÉT ¢ñf‹§gþ'?y€@¶wh–ßÚç¡ì¾úð{ÂĪg:>-øý ø1/ØÆ®¿!eƒ ½}‹àýmk9eÒä%ß ‘UÅœìÝÇ¢mÙiߎãÝÕ¾¤jÏ=Çf4›Ü"§ÜgÙ—A%cè8âÙïRI·Ý»&ï§ö½böœƒ‘ã_Ûžzˆñ·ÛSï‹¿tîuXé/°züC·¶Ù‡+¡ï ¥øýKÍßÿ ~hq¸ endstream endobj 1359 0 obj << /Length 2565 /Filter /FlateDecode >> stream xÚíZÛnä6}÷WØ—nÀ­áU”äa2·8“™l<ųƒ†,ɶ0j©#©ã1ûï[Å‹nÝvì´Çñë7Y’ŠÅb±xIâ]xÄ{sôÝòèÙkA½ÈxËsO1O‰Ð÷–©÷qövÎä,«Ï²ºjæ ¦ÂÙó9•³t—yÓÖó…œÅm^•æÙ›mžfǦ|šYÜd¦B}Æ|:ÿ´üáèÕòè×# Í𿄝ˆò’õÑÇOÄKAþƒG|…Þ•~kí‰ „ßÂûpô󱦟‚ÅÄgÇ·êÕð`GxzS')ñ W¦“¯Ò¼5v¾}ùÂ’ªüáâb;í"J‹¬Ñ]q¶<{ÍÃzâ-˜€Ö¥Ñþ®JóókøZðY{™™B¯ßé¡Õ}l”ûŒ„Ø %à¿ÓÁ©ð›‚Aó”q? Á¦ùÏõ™ô¡¹óÛLÌ'uŸÄez  ÙY&¿k—F­ùCHˆY[¿ÔxFfI»ãDˆÏº{”C+‚Ì´œÌÖ#ßJÒl ÞK”°Yܘ'iµŽórQgq±6’u¼Y ±0Ž4ô‰TÞ‚R?’v@7yyßò@{J`žÁ<I“#~›sœAVZÆë¬[¨©öÖBåZW¶¶¦íñç Î"mü‡,;lPÄUÎÅïN–SËqª;ëÓì«ñ¶hoõˆAË]àŒºc†I÷$©Öë¬L³tG¹U¢‡ª1^çTBOèØë½nIP·N-P´“}êëÏaúQåGœ»é×à cKúwn~qXˆõXB)/'vç(/ã9wƒj$ãÞ€à7]-¶YãÆöÉU^¶„ ªúsWƒ1pÏ=•³õÈü&o³ƒB„³åeV[bWhªµ.7ôë "ã¹kb¡œ¹ø0ceÆíê²rC8vÌÛmßg2;³o5›,ÉQC–‰™}:rûi©ÀŽéÜ ¾EwÙq^º/ u/ kã(jN N”R&°Ð‡¨®vcd_jìk;1ƒB·fèJŠ}à:!hEuµž45 (T%. ‹ˆDáÃì©„/U—pßž~'W/Ð…?½}òÆ|0ÁêMòýDéBHîTŒG]ë†erõ÷S ÚŸ^ŸüøjO”HŸŠÀµ•zÖäuUB"h‡Ãn²dŸnøuÚ‡ßM•»WÈÎM2¾q$tk®ÕM››éZ`{×s%g8ƒ8Ÿ½ÆÔçRŠ ‘9eëM‘}cç eRDÞô×b}`ÞÄq'Á…Ü“óU!Èñ~õàÝ%ˆymRMÖ7¸Gq_J©ÅÔ`¤I¡û€ú\@ìöî%ƒS¾ŠàOÞ #_È@E½FNìk}‹(•]¥p vÒ«#}s T8¼MÜûö‡èž%ùþ{?{<‘Ĭˆ?oºˆ0ÐÖü¿o8@ñ̺Kø:Ç´¿¤}ÒùË Œ¿\)ëh[…è”®{]œ šáÄzgètƒý rWWü‘yÔaýɯså"€4FáWmBÍ!4ÚÂ1Ú—!õÄÉE_6U yEB60™²Ë’`§@ÿ»Ú¼‘¬ߎ–¼;~ôlô®ë¥y}Ÿ†wt`¼ªÀ-àÓÕ}ÇK&çwùþÐUiò žºõœðNp1n-ù=’Iå‡Ñ— ø³\+‘(-«ÖH¶ p#{ùþƒ‘-ÿ¹4ÄãuÚ©æE‡R BZ :Êù.Þlºö/ÀÂÊ­™i³‚eD•ya—€à;µ†Ä@n¥rU$d/% Ä;¨”Ø ’ÈÈñ‘EÅì…°pt°5Í,RøŠMy 5XmUc§4‹ÜÅCììy¢PÎÔ᜾àmþXägCâöé6׸#½ç,n`$a¢ ìëÈe 5QeP4Q…_NOLqþ~8EÄõ££=¦&ô˜ˆtê·ýø~m ¡:'5Ån (˜  ´ãžÁCmˆ(Ÿ¨n~Ø]&2{™7I57›8ÀFN¿Å>XèD &ñΔ쇊ÃxÇVò2)¶if*7Ä»€}°_³ч>geziôõdÚÍb»ÁbZz†IÊŽt³{OC Ð —é2°û€@‘~7ûìrëáÊŠîαÙr醯áþƶÌ!Z/_åí¥q‰µ‹c`…ãNª£®£ ##t;ÏZ^¦÷”hw@Ðúœt¢›YA Nù®Û€!ïÍ\Ýc€˜ÚMbvI ¤åõ̼ò¼ÜËöö’JCÛ–BÔÑýØDBÔí2%Jù”*Q*v¸R/C:Ð×:VЋÈ@'´úX„ð©÷óNÄ0z|b=1CJÙ”Bç-aÍziäí æø!ª} –~Ÿrq#A@ò¹¤#ÕC(çÙØ7Vµ[ÆîH,4£úvB.´ðùòûWïŸÄQpWÿï_½üÅ|ØãY’sKÝçã±Gìbötì?x(þÝwr÷ïÇ"oná³;,:¤»ë¼=èû,Ýîãþf“ýŠtZâ+Üñì¡Ä|D¿ºg‚)ŽÊê¿^,öüÛóè2Éhçã'“¥Þùgl¸ÃµîD ÊI\šÂ™l}â%}~€¯Te[W…:•En0nVj>‹¢=ZnñL‚Qsn8üÆp8(˜£4L‡>›b¡9]éàh±NªSé¢;ÑJŒtÈÝ÷MÌîø#Ûø,vçgíõ&›œƒ¸ãªãùÅtrïIéíØxt°ò5 ±Šð顽Òa<2F|¨ÛDXÀ %LŠ!üÓu jt©‡5ºJzÄêO´Å“²å÷æ½],G貃ˆBMê;§ `ì2Jâz4êîBw¤€j'}ùªÐ°»½ÈÁ aÄ^ú³àdØ/Ÿ+H)N["î¶øéÃpœÓwôU›lþl«þ*wPe0ÜJWúÌ屆G‰èÖ¨YÇ_ bγG3ˆ²©ç/Ý sWd¬¡Ù·£oê¬Ì®ðÞÂãzIM Lîâv3$¬zõ9»^ió³0Î&ƒ?ÎIð(°Ýkm³ÝàÎÒUV&hoó„ þ¦¬êu\ÌJʇRi7~¥hév}‡M ¿ù>Ùߌixö„¿ëbÁ.¸¦âp­}Tá!–ô™šmnK×ú*¥–eívs<žoCÒXêÁýd÷=í&} ºS‚Ä!/»jî†Yi°²Ý ßÄúº´¾ß¹¯µéÝg)€;ÝùêóÞ‹ÌxyÚÍm¦Ù6{qoæ¸ioô ìù"Ñì¤lZ}¥¹(·š/ðâöÈd0õ¿¤kn) endstream endobj 1209 0 obj << /Type /ObjStm /N 100 /First 984 /Length 2359 /Filter /FlateDecode >> stream xÚÕZmsÛ6þ®_m?@¯7™Î¤ÉåÚéõ¦§½'d[µ}N%$ç’ÏBhŠ%;LonƦ–är÷Áîb R…Úh#(ñ/ 2– /ÈAxg@%|ÒLè-#(æ´|0Nh¢|-‚ò~ ­eé„çmˆLÅåÇȃò,˜‚Ð>Kafùš…Žõ½øhXŠ…Ž´½…QFA‡Mºù0B#ó9àem΃J© Œ÷|ãÕka¢c½Þ‚J¬×;AÊð>‚r:|¤¤ °’,%°x&ÀPÌ*"6„‰ TF¸dóØ¢XJ„—íñ¬³:äy ‰ikƒ!›C è —}C1@)%¬f>RZX‚¿@amæS$`‚Ìg… :0a·R”6mïá´f—!TŽ"ËÓJ8Çî&­…ó._3¶3l"\b_’¶Â+— C;áuÊ×¼ðÄ!@AÖçk±”X›NÂâ°Šž¯AQPŠ/‚¦LP!ó‘FÃç°1¨˜­ÊB¼fEÁq)|ÌáhEˆ=AräX#Š"¤,™œˆŠýÿ°e>/"9‚Db´‘Q!£ƒx09û"zžÃ/ûWa Áñ1fKÚ ’ÚRQ$Ø…%'‘Xø”H6ð]Ož#‚ÀœBö¢8ÅÈø8Da—ü4)GÂÎPì{Ì6ð+ži&QOž=Ó1ýËòÍRL_НÖwgü7?ß\/ßHmã×âÛo'_½¥àñÞ*¥nøpˇ–õôO|x«¬âß¿Õ{åJÃ}LJ æ6G®ê•ue(÷þS®ùð¾#î¼>¼¨‡y½±©Oæ—Ã@Öõá<ŠÍéׇm˜žjÃGŽ aiÙ:³þV ÞŒáâÿÒŽN=ÕŽ'{µöÛìß=CìnÖå«ÊµhÛå¼2yì­rªª¸«xöXvÝVv±OáϬ+š«Ê߈¾÷¹Ó ŽÏ1ÂØs~5»ÝÌWÒP7PžW3}hý¼ß¹›v85cX÷ê6D¡Wê®æ×UA3ò!×¾äßsØöωÚúô}_e¯ÛÉJ?–iº2ßäG«5æUz½¬©¦\¹©ŒŸö™mGo×~©*/ëfÕW­@ÜI;nm&ÔüˆD£÷Xણõ¦Ê=«Æ¾ì”ª[´æÎ¢z?Ö(xñxƒ¶Æa†æÁÅ¡ô²i[´Ëµ‹hx&Ϫ—nk*yD~\æðc¬Aÿ;kœu|Ñ.ÐMÍvÙ1;”j~¯@?—jŽÉom3üþð^³Ê˜5U刑¸îHNª¼&bš$¶é ZvªySª.+¢óŽú¢êº?ŽÈ\öè|ñ²ë³³6šÂÿSûÞ¦åòc㰪؃ò×*~ÕžzwÇ¿oÇÑÍ¡ZhûjÓßÛˉf8·í 1<±ûJÕ]Oå»®*ÞL{ïô0gíH[·{–eßrg¯Zž ¾«ö‡v‘Ø.ä:BNó¯ÅôÕõæKyöl2}óév.¦?Ï.ç“é‹åb3_lÖ¼M`˜u2}=_/ïVçóõv;!_ûi~q=ûnùQœ*\ðè_C2ï&²ÂÓ̘õLî5´TÿãŸÿBÇ?%wïß¿+L¯ Z0âW¼]cÐöo‘Zî“Ëg`þ¼ZžŸÌ7â˜_¾Ó7óQ¥ìLêLxÒ`vôÐÌ[8»šy÷áQš§Ï‹%¤nwjØy£æž0… BØB¸BøB„BÄB¤{BɺHÖE².’u‘¬‹d]$ë"YɺH6E²ÙJÞ±YÝdzrw¶Éç½^ÜL¦ß-WóU¶Œz7ý~úÃôÅ©Î'lÌs8 h©0TGAzÞ9òF:XÅÙ(m °=ûòÜ6팊B;`fºy#œñÒ97ˆÂŒŽÂ&’!Fa€Æ³-”•žâ E ™ä:üa£‘Á ‚°ãƒ°I&ÞìsZbY¯dTÃ Üø HIoNKëçQÆhQøñQ(/5æ'ò‰Ô! «=LâQ„ÑQPD-FNà›¨”œT6 ¢ˆã£@–àtíƒ$Þ‚G¬"U ¢H㣰°ï™Ç(=₤FÈYj|©Òz~'"ùE™$Qk‡aŒŸ;MŠ’_pÄ a"ׄaãçN¼ôü–*%ˆ'~#íð$ÑãçNãŒôX{"±ö1ž¤³ÃyKŸ= WHüŽ,ȈŠn¬æ"; cüüiò%¿çBöö†ëZâ*; cüª#&%À Rå \f‡aŒŸA9g).iÈã–ßë £?ƒj‹Œ©¶("¿as¨öî@î?…bŠ¢±æ¬áX=¯.¥¢ ®ñS¨VZò+@·Ä/â´âR;Œbü 11Y]V ¤ … #heOnÏø]pÓži Š_r¶Z´.ã#ú8Ÿ]?«ã:Ýé§wS¦t8¦ô*¤¾@‹8o ÑÊÒüZÆ«r3~iñ\_yYn¹´há±KÕŌ_Y¼w˜‡N …bU,|°¸Ü¢³éñ0ÉØ&F_;2Ÿ‹©'ÃÓc‘JKmK“M~ÌX´Ahø;I»Ã4qc”×|ýé{w6|‘Öð"£L Ú35¾ ÌŒÈOhÌŒÀ- ÷Žù#"B|DMÙ†f<2—¶{ré“™\àUc:‚‘,¢Áf4h|¤ãr=åo]LÉüü±‰¥ž:€3þÞÆºr–ŸóŸ7/]ϼtŸ1/mÙØ²ecË–báÊÆ–+[f®W¶Ì\™Í®Ìo7ê´Ö +Ýyû‹Wîhc gwâEâÞ™Tö±ë âQÐ,#Æ^Ñ$Ìs>?͈"i5'¨<ëxÅ_•E¬ÿèµ":øÛ:mxWNxJÒ+÷‡»ÈJþøÌ)%ù“G..ï`òDªÄ’ÆôŽvJr^°X±rî0 #5¼‰‰Šäû—·³Õìr5»½úfÔµ‰E×í‚«Pjq€ÒØdľúú]<—ÁÜ[9b¡,ªpLj/a•¦µ®@,ڜ㠇¾Ñ$¼7¦aáQªPˆ‹u†æÐô˜ÇAÉ¥Í[ŸÝ@éý/ïOæ endstream endobj 1370 0 obj << /Length 3138 /Filter /FlateDecode >> stream xÚíko#·ñ»ÅE °éå’û:´@/ßÕ¹ä®qÔÁ%8¬¤•¼Ð>”}œÏúß;Ã!©Ýµì³l5͇X€—’Ùá g†¤ë¬×ysòõìäüµäNÌâÀ œÙÊüâ:K€ë¸LÄ‘s£zŽ "øæÎ'?œ¸š~·Ï‡ˆœÅ¡Ë‘)bDá. ¼øøÙõÝEU¶YÙ¥K Éw'«º*¨´­SdóSVu†$kÅ8 #ªí´Œ{¾Œñ·^;÷5]½Až ÇAÄ.ߘëûȵó«}c\éR·QuQ8‚ æû¾çPó™Ç9ÊF†nàLHáõÂYô›}—IëöJ‚ê4P\5ãâÿ6ïÊùÁaÇ>Ê?o¬I7ð|°ø<9žfC2 lxŠ_·X> €ø°Í¾k¸x,OQ˜ºy>À}äÉhÐrµ“ËY3—ÃuKú…£¬#=+ç\°H 'ˆaiD@Öñg°cT÷ÏÛ<[dm~Ku0˜U¶îÀ:Tµ½Ö…U•çÕMV®©ú)É»´y1²“/Ï8‡Åõ-wÝÉ2i“9lˤÐ3þ>矒ú|SÏýÍrq¾­³r‘m“ühoÒÛM›4×WYþÀÌlã³—³\¼{ɾ¿œ±‹oþu4’Eþ…É7ɲðôÌyþöÈÝ*Ÿy`ž§çЫü¡›@M<ÁbN-òj½†õü…p>‚þ‘Vœ#–ø¯µ2-ÓUÒåíéH—Þ~óŠ I¹¤2˜™ÊM–çT©Puí¶k©Ü5¨…G>"kn˜„MÏ88‹ÉOU§­ )©•M›&š°&5$î%¬­´©ÀZ6º_¶±†”Ìe´|#ú`ÙõÂHdÂüS¼ ÈÛ­9}ôøúò»‹`šœ°€©×ϲzÎxm‡à`÷Ð`…¬­CiÝÇ&­?¥õÒ&i+™UØZ£õfð‡œ­VçÙü‚V±ðØàf/YìjM¿R¡í6O) ì=BEE€Võ½ëæF3`dÄÓ7ñ»(yÈÜÀöÙèt‚YËÒe·i0Ú7Y{Ma¹òX ÈKÕŠ¾·S •®¦¤-n/mH&¹÷•§Á;Üɧ©À$Çtl¶é¢Í˜£¬n§¡o%Ž?\õ£Ø~Ïøé@ 2Îgäò©}ŸŠ¸ …ñ„¶™w˜xUSbH_ìšäŒK»p?AGtIàqD<¹N¦ÂðIå î¶€oH(Y«{nµ”ЬiT¦‡@ó%?ް! Ò¦–`ˬIVŸòƒÅT †5zºý ÈÄF”"yŸ3©œL»s9,Í‘‰[­z}!ži© ¶z0ÑÉOzQæ]q>…çéÜ`R‘•÷†$ˆd@ Iè!üÙ2߇bt¥»U̻Ӏ>¹2´â½H½˜E‘ÅúX•±Ë"?É<×%%OôÀzt¯®­Š¤Í(då}ßìMgùÞšœdÕïè~·8R «0Ž}^UícµT‹@Þ»‡B#…–ÄxâÌ3ôw¡’>ïiïkïk7šÅGš…Ó¦¹A—VÕˇÆ-€˜íuÊÓ:uJ•Yca®±A]ë27ºª÷¾r­ñ½¤ÆuU-IUµ~4UúV%NðžLJ„¨#EZ3؈*ˆÉSzlÓJ bò&`â“u—6 Ò (.>ã®”[u F®¨×<Ñôõ)Ö}’ZãÁwtØÉæé¾$‹V¬SÑ®ƒ á+ÈD< ÎjŸ7>E™½U€nèš*=R­>À¶Õ¶ËÕ@A¡¸(&*rά٪¾ õZ!()è€ÝSAecÐb@hP/Ì^P™V2ø¤N œûéÉz?ôêL,o¢¹±0÷¼Ï Ýé4„·ÔŽÄ¤lÍpP·~ÅC½TM¸v TþÍì mÑ / ]{“-RÝ’¶ f€ñ”†p¿O’$Íྱ09i”ÞPy¬%ªŸÒäl ×5ܶÚú|0ð²Kr¶O4ï•sf[]% D Ÿ±Ç“›ëÌnÊP-²õuKEeÖ "e¬ ’id™î±Ìtù œÆr¡5–Ç–‹Xs¡[5ìg×s!?ŵÈhÛ—oý?”Œ „‚/-ÛfŸ0HîžÀ¾6-ª&í$ªIÍ Àž â(™î;µ†Ñ ÍDµ¢Â]¶¨_M%ú,ÕÃ’¡Dmr!lÉÓ–vihTk°žÛ¨YžS2©¦›Óø¬g‚‡öƒ Ê®Hk%SͦÜÑÖcCš0y,°ž2ø®B G™ègÜY¹È»eÚŒ‚‡mW.ÚÎ\$BÝ:4ÒrÉ̵œ¢%d±Ðs†8¤ DBžWHÝTðT›qßÄï…G ;_Ó`bÀ‚_cc‡„@Ãå唨è›&[Rÿ^ˆpÅÑœ%ui {b~N¹Ð)õ¤“o¢í¹ù‹èCØ33h  :‘Qñ¤øÂAS1&÷žxÐt¼3!stxœ{]îq&!#ùÍïuaÂþÔøT@ª@$oqr.uÇݤ;^øîj¹½Ø´ ·‡Óíͺø­î‘ç|þnï­9×7u>Øã0ß› kZJù(iè±J0ɳ®ÁGß;WÞhv*P^ ó*ð_Ì ômgsæù!‡íÙwí°Û%é–Ãgãcüš°Ñnø¬ ŒVž3ÞÞj?ƒaõîš/ñ´(ɳÛ÷Ö]ö.Ÿ%z«@ôîo „.ŸýÁ“×{~µï>ø øú;ˆ°çºç]SŸçÕ"Éÿøà âƒ|3¿x×5£¹Æ7€¾¾/çÐXt«ª~èžY¿ÐéŠä‰‹ Àê#ï¨kphðƒ7ð<?¡)©>nö§Ñh‘4*&WûBª<˜Lô)DF‚Qð?‘æÛóïÿ~\‰Æ ‘ÝŃ=ãÀ™ Xâ³O-v¯=æú©c¥K-È'˜CÌ"bvÅí•Þ‰9Ô¾ï-ö?1Æäçé;í‡@:ôG‡­—í“9öY[è@÷>~G}‹mU·Iiž°¨“,Ýšõy÷~F…×ï¯Þ\Ìv¯YôbAzç]”Vàö¹ÐpMFxÈszíóב<Šö½Ïf·Ûñ{¹>uGÑ(¿:$ê¸ë£ÓC…;|àô)­³ÕïDà™Ö×d<ëÙÊHÀÏŒ÷ÞNÆnhŽ,²f|qbè@EHs;oê¹9@±\>1ñç-D±4Àwï_áÅËïÔ‘Ã3œV=÷ž]|syõÐFy…”ÖûŸ÷ži¯+$ÂNhO~÷ô`Ð…'BšWu¶ŒÜ§Ë#1ïAظ‹¼€^†^Z;á^K=¿óŒ/ì{;˜žù*?ÁC*Oó¸ûÐ$pöš²¥ãµûN0v†ÚÓÓ}Op ³õvÌÂ×ñ… qïÓ„hü4!ºƒ”U›ƒwžÈ-Á£_üï=à1HCi^Î8›ž2ž¼ªJõ‚ÀœíÊÀëGÃbLÕÝ&f endstream endobj 1384 0 obj << /Length 2768 /Filter /FlateDecode >> stream xÚíkoÜ6ò»…Pà€] K“õJï€ú'u›¦×dïÃ!)òJö Þ•Ü•6>ÿû›áŒ¨Ç®¿äþà%‡äp^œ%½ Oz¯þ:?8|e”—ˆ$Ô¡7?÷"íE&&ñ½yæ}˜ü4ÕÁ$ߜ囪žÎtOަ*˜dë¢,êf3“´)ª’Æ^o‹,ÿ–ÚïòUžÖ9u”ÐZ¨éoóNæ¿(Ø^zж3"’‘·X|øMzÀô¤ð“Ø»¶³Öž cø]yï~=Lºì³F=b ß½HI!ýˆØø¨•´»·Ë_Á”ÞaÂìäf‰T™—=æ’ã(‚fŒšú ËÒ&=#Ž¡÷Qúf²€M¾þ^* EùínW›¢\WéJ\ö`D倳™ŠaŒÆ†H|ýÞîÏɪZ .?Ë—‰D¨Â[ø€æònæ‚PÈ8`æüG3—„b+­—Ômižù2š%›eQS+GÖÿ5U ”õÕ*ßÇš–"q»¸ ÄÑü‡“·GâçÓ¹8yùwZ3 ,1B' A[žÓïÍÔÈIµ¥NVÑoY5Ô¸ÆC—–ÜK÷ðôyŠ'pAC[Ç‹!=«5§Z-ªõ:-3¤×›ieD¸I¥×E³¬¶ iQ‘8ük¨èXµ¬Íê}Üà ÓΨ®ÐEÚ4ÖBGz¨åWh`Õ†ö\W¶¼¢<·r"öÖ­£‘öwlÅåÅm'whÓuž“U j~Ä ‡ÞÌløÎZkØãOJIÔrøËU¾±JCë! ZÖ®KÁé;ÄÝaéÊ$B%=ù ^PÐ*" ´äÜüÌH)¢8òf¾1;Iòìyìtè⑇ʶ9 „Û˼ `iÇo¨CzKLÐ…!íÿ÷§ÃØ`ILïœÄÁ¤ÌóŒZ‹Mž69µÓ’~ao9Y,òº¦þqU6›jE7l#Ôû(y4 Th*¶N¢ÅÉ]my ±‘eá2Oöv«Î/ÇPØ# *óáK¼íc¥NT‡ ³ûn'ì±”ò±ÒàµV0÷ÉcÎ×øm¢ýmE: áú¨^;À¹ÒûE<|‚ñM"„àz™¯øJ$ J½ýg‰@€Xð§çô>ÌpЗÎÛÜ¡áÊQL,Q|y{&Ô/¦–Rvöí í=÷áwƒoï‚üÏb@lü‹†(±ïêßSÙ°Å}è©Øûõ²iü|:’4ùA‚ üƬ-V×ÛŠ${U­ŠÅ µë«|Qœ9×ë„´`Z XNÈ9I8d]€;‡L`(#2¼>dŒÈ®Œ4¸ídôÍƒÑ Ãì÷»ï5ÅöÍXÌßñÝKãa_¾j¼ `jÁé×=v°šx£Y~nk\Oæêq7ʼOJ{Ý·6r¸®66«(Æ v›Uí³µóþøuø™€‰ÿãüÈ‹ ˜)¸qLþüƒú˾ճ£t¯9=†+¸7"ÖÑÐdßåA9 *>‹·eÞèÿ—Åûÿ­?¿¹ÊIyXS±J¼HŸ”ZÍt¨D FÑéo›ÞMõNl¶tñåø ‚UŸ/§}ÒPåÇ" XªÞÓ+š{¼:`¥—;í7Zn>¸ *7öé1¼<~ÀãÄÑ”‰ðÝÇ4>f•Ei_ïý¸WÂ)öÍg`ð†—Uâo[¸*Ü¢äùã:fHeQÂ׿ãPpÓ œ 凸ϔžT”ôKOÌÕ4ozÁIF°8^Ž8ÝSfvMàj8åöÿ:zï¬øu®j‹WàPž·b¤t$tl¾xŶÝ-¤èd\GñåNŰ>à:®Hà ²C'»í¾T¥èkåï^¢øËWˆ ƒëˆt<®ù²·/Y:}¹ â¶4ø¾†Ê¯¨¿­2¤L†à?ke¨óyã(øœ¥§lO¥›"J"y»“Ô}àc?1> stream xÚíkoܸñ»…p@qZà–áCÏôKÓ$—æ‚K{W÷C‘…V«µïJ{’ö|þ÷áÔcåÄkûÜà±Èg8‡óÐrïÂãÞ›³¿žŸ=û>^ÊÒHFÞùÆS"aIœzq° UÞùÚûà¿[ÈÐ/šUÑÔíb)ãı¡¿Þ•UÙvÍbúYWÖ½{s(×ÅwÔþ¹ØY[PG0)™X|<ÿáìõùÙ/gxàžðb Ó,æ±—ïÎ>|äÞà?xœ©4ñ®õ¨D <·Þ?Ï~:ㆮß55~~3¡*8“I4¥|†ª–J¤RZQš0žHÈ{\~½ÜïŠç¸ gß«d(EÅx˜1=úEÛ@T‹¥R‘³¸_°û×(Ù¬êèUwY ¬°¹ÎŠ]]µ4ª« Øâ´],ƒsØÓ˜ìÐÕ;Ø…<Ûn‘è ½Ḭ̂U]ÛIÊîŽ “1+yV”õÚ±³3j¼{õòÛEGzñÑpñK³ú¥, C’Á³¢ËŸ5ùœ¬R&¸²²ª›Š@ˆ'Nœšh^×e«zQÈ$Ìjÿ‡«`[0äZùÿ† õ‚eÈýª(ÖÔÂåáó2[(îÿºP íÉèaß^þw] E˜œÔÞ•æY7ë¢Ó[›gwY¶Lëý±ÂNOB'pÂ{éìHH+Œ˜T)Ib°x•ÒnËÀ®‡¥lnèmw‰zƒ¯qÇA&>V@->³oê=PVópìÊâÁˆñ.‹Ç\é“€#6Zý7QÙÌÍ‚ ŽÐ]Ѷم¶D-¡hÉkn lë‹ G}[çÚ(™ÁN×ñÙE» ¤7‡Iž Õ‰”8ܨ# lèg45ëúU³ Y^W³å´C“í À*Ù«iÈÛ¢x`ºC%,ÉF?Å…+/LsR¾Çª:¨"¿¡µËvû-<àRÈ0€C9yj^ç_‘¶[] å… g±”¨ïÞ/ŒM‘·€Ó°I7ßyŠŽ@¬X†¼…œy!ðTqd^¦pP^>èÁRãþitT,#¸þÅ00Ãú(’®³µ:ïÉñ~º: Fs;Þ<¸^Yþ‡_߯ûÉåICTH|¼qA÷=þMOVÉb`^q Õ"‘Z^¡yãäe$/Û …´éJÖ3Ð ƒÁ4Ð!é å‚b0h(»Šâ>ç¨w€ÆO+Êe”2.à&°ʓܚé!aÛ#ãÖ´—8tº”¶ý£™A€@øÓȶx–!Zì¬<…ˆÆy6!äÿš5§0r„ÆïAøhïÖù)4Ø-UýÓ»¨ nt‡Ê'Á¶È€¥Üèþ‹Êúëèñ‘ïÝÔMk#¹¸T«òúPu6ì¹¾,·Å(`2.<ùä8¢„óEÕ¶5ÁÑÊ lKB²A™«ÜÔ½wÑÖ¡Û:æ,f©R6ÜÆ`&õu„ƒNëz­ÃµlKðQăqÅ ˜±É8T!„rC„®0èD! ”0½kyq¤òѲ²¢¥-ÞîÍœ`Žö°~ûV‡ZðºPÄQ( ¯ó¦ÈH8Щ«#Ú†F¿–õÁ6ÒÜÏA\ÄÃb º˜¸ÇÚìYF)!itj£Ã6s´Ÿ2hÛý}‡²ÓY&Ĭ[«pæc éQŒ€˜9éLó3’:T²ppžyôä!‹g\zÐü‰KaàÔ¥w tZ]ǹ®Â{r¼Ÿî©B–/u}w Y’§YD8 YD4 YD2˜:$¡\p‘ Y€Þ²ÀñŠxpkÈ ÉDœ>¦Ë¦-;ݘ'û=G®Ó‚«ÛþÑFmWãQG†,”ΔýåÅùß^¿1q>Ï×Dj*Ò†Ë=òÔ~|{þ Oïõ«9áõéõEÖ™5£ªÃRD°§ô–*aIŸo«¶Óµí4ĉ¹í ¡KÅ~[æÞ½zÙ~ê† gGEáQ.o­ÆÜ@U÷í5uàº]ߌó¹Óü;ÂòºBââ`/÷‹‰ÛÒ8>ñŽ>ïš ”x´êE Ò»W/d:H öÅ )‡> tHnÐh‹®sCháÐÐ{¢[:…‹ãj;Dû•ßûš¹¯á>1 &—¾¤«&äšr@=á2“»à‹¸»66u3É[ÈÐâG†ârœ·pX¥sa¿9™œñ-žMoe“Va?¾=g.yqÝo¦’þ³Qƶ-/*ã³Þ‘˜F¼×êÖÅ&;l»GXÀÒfžFÎÖ?ëÿ=Åjžj¯¨2lê)÷?]Ê)–Š?¶IZÞ£öꋯ†ìw5d½÷þÕ”}Δ…ÿwSö»îÖã³[>ˆM&sb*ñKL©Ø¯jf ˼ë¿ÿMüªÈñ‹Ý>Q0MüIu[ÙÔ>4æ2*1)@¤X _Õ„Ê8—…x6?„Ál üÕ¡#xiVBÉgh¬ ‰K°¼7f̆@ƒoˆ“Á§ûfe3ÖÉ~Û­l Ê•}b:Ê$´1çZО)8´³G¼§¬&fH:L=p›/éš,ïf’aÀd*>—jT,éëKxgéD[Êg…íæ©0å€îÝ÷"xNME!å¶-%AÒ»Z Rn~©€-­ ðì“S8Üe¶æ£Çؽ hw¦ì⯠4Ìý„ ÿíºp?°ˆBß â„ÁqKÕ@F‰«È(É[¿ð%Ç, ~Ëî~Öƒô÷jok:ËRQÆèýÛ AðÔ¢§=¦³ñ em¹ÚÒ¯väõxÀz‚y]jdfþ¢Ê¢îéÛ\+{úuDtÛ¹h ½‘"±;‡¹ÉÎjë ¬ŠŽ2MÍ£ Åù"¥ÏG09’$àe?!¼Z—M10PÂ~Cãú:°æ¥·åýfñ5Íû˜VÓܸÏ~’AZMëU Ah“{̤719™ºÏfÝl•r·ƒÃó|dó§<êу5[^Á_5“ç ¿Â‰‚ÔYWºÄRuTK "ɂȕpÊÕÿ¤À†D endstream endobj 1398 0 obj << /Length 2895 /Filter /FlateDecode >> stream xÚíÑrܶñ]_Á·ÞÍø @ÒOue9uœ¤“T}è$™ER:Vwä…äYÑßwHGɲÎÖ( í‘X»‹Åb±ØÅÑ÷®=ßûæäo'§ï8õbK&½‹+/d^È#ÂãÀ»È¼Ÿ–L,òú2¯«f¹ba´x³¤b‘m‹²hÚz¹‹¤-ªë¾ÙYþ ßÊ7yÒäX „1B—¿^|{r~qòÛ ò¾G‘'¡zéöäç_}/ø·žO‚8ònu«­ÇeÏ÷Ï“O|úO(<öÆÏúÚ»¯ê§o:º2"’žô)‘œ+ÚÞo4Œ•¸ÍFÅtëÈN!„o $£TqÈCi*( xÀ@à¥n5¥$ŒáŸîßCÂ… ã'¥Ü4ì‰ö°Ðö¥¥Úƒ|§ïPM¡@¿ë‚_0ýÓŒóÊûÑMŠ…R*õè55ÿ~®z0˜'†È´Ü„©éäf(·®šR#q[fD X=6¼CI•Œ”òÑÒ0}µ`+’§,®niŽžV¤+Ÿª§ÏˆÏ™’«¶@ÀÜÐùœ0£ºI”±y –,ÑM›d¾®«¦ÕÅ'\M†ý£y@€5ÀsŠ O ±5kŸd5@c¡¡šÔHÇ…`'JƤ·Åg±~Ð?Ïö Åèz,Šê¼lë;ƒØ×8r¤ €øô](¹ ZK5ª«ªMåg]ã]]”i±K6ó̘™yÊÐ0$QÐ õ¶h×N$4îZß|,+Cø1#×óÄÆÌ¿ÂùËË´¾Ûé]ý±CñV, –p¨íÝ.Ñ’¼aB>}z¶ÍQý×Û$= A³NèWWÐXNŠ/ËrcÛÊÆü®M.ñýÝûïÎ_µó6=n×—â¨ed†ót+m¡èlgûøí£ü¤}¤,šíãlgû8ÛÇÙü?õƒˆ}Ùl"g9›È?›‰¬Ó«j_oãfsñ(§ïWu:ãÁ8‰aÎô\½¿Z®ÆwKî/ª½*0Q9B‹²Q©•6O2¬É—XüÞÖIÚå56J°êfÉ|Uï/pTÕ•ÆZc¡]çØ²Îw›"MúáíBÓd³ …¨¼ "¦Î3±¢–-1Ko4Ö8$Ah{¨TЀpÌÛ_î:V^a+ Ð\’Þ‘ÑmÖÕ~BaÂ_ìuJ ^|€^ÂðÚÜT·ùvWÕ=) KÁ~ñ¾1˜:Áië¤Å7¥ü0ë¢Ô}ÿ²äbÑLa´šÿ”˜ùùÅ8'ÅcId<{NJ©ІQ¦FʃDMRˆ®Ð¥!:ˆß£ó{rÏ•‹z©ã{©9( RP’3PR:d €Òqå¢ÄÀmòI/"÷ÄÁZù`àîË= A Â{sOß t§ƒ=õæs1luív÷Guý\ŸavaçüÝ|¸˜ã/s|z>MÍÁ—Ù>Îù»Ù>ÎöñKD›Œr^¨ ë8 öŒPÑEnNá`qê|zGÔ(•pì¶_š”H§]çú/. eÒÂh“®Jš FbXSïé9U"¾Ÿ…HèX‰s2 °Ðšî)RÉ?/¾Å åÒv!]´@„I¥Ô´*>j+8¸`½â*ÂæÇÞ*PMÄyV•j’®÷úBµ¹3ï&z§Þž5iœ&˜X{uûm²ÃØ‘ ÃU»äZÅ­ì}íˆ/ÒjWä 6ÐÂS/iU¶yÙpu…M»êƒx^ƒÊÌÐTwÀc¶¸Ü·^Y2eÕ2”[v¬:­ö6£Ñ§f=u~r›Ñë9çú4/Ô«X¼Y ±8ûáØ,W<¸j£‚›M¥¢°·:«zØf»7z¦K—¹#Õ ›_ê !Â×I™–*¬ÍMˆ¡]¨™~“›Ý…0_ÇBµ#ñH¢²ZÙäÀç-—ÆVs¿¸?èð¥Ò|u»__ìf²üJ“ý¦}PÍVë@ô£jnƒ³JlªTOm3yÍml×d@_}„еD’pàmEC°FíaÔˆýˆpÙ‰D[P»«‡¨¬°ËT²ôˆ(í&Iºy4ö*ÛÄ$)êƒH8úêÆÙulߤBCü^/¯êO>°CÌYF»êÔ®‚뇩¶EÀd§ бMÆ¢°EVÔyÚVlL5™•%Û“¶¥¢w‹µzeGેõ`’ 6èÅ<6Ø *]ôežgvHm5eÂkpIŽÞ2¨uRIß굵Òv§‡«oŠgkž-ig*Œå£W%ߌ„íu†uWuµÅÚÖvž”™'ݰB@×Á±z·8]ÿ±HzÌÇA¦\ùþ$±C«·ËRzuZd›%ù¶*Õ=ÿ z#túNñénV±Ô€ «W˜Ö”„ÀÕ0­µËÓâêN¹,Âú.¢ ž8Þ® »Sh'ª6{uˆ.ú̈ W‘™Ö½Ý¯ Þl¿ÝáÛ~Óžpeü¸Ž©n’TÁMŒ!wZ÷4?øÀŒÙ­¡aÔ‰LéûYãbí•ÝMÍ•ÉÖfön”ff… % ‘º£Šõ&È¢س”“%îêÉD24Æ\€Ñ{î© §N¬`4}ûœ³éCIûW£a4_6£È(# Ÿ=£ÎèaÆÅãŒ[àdÜ:Ê)u….³ÔAüß“{®ŒâKßKÍ(²pQdÑ8£ø™À7Òqå¢ÄÙŒ"à{ EF˜hqoF‘Á^r9´!Ï;üŠQÀ@ŸtÍÝ™ˆú1‰‚Ț˿¾¹øûùoF±£Os5ŽdH°tltDïùU'ŸcÆ{þö_¸S'1ÜÂæpðÓÜ2ÇHE8Ñ–RwÓÿqÛü¬<˜‚`ü³vþ‰Ÿµ£ †l#‰™ù=ìÊy¨ÔÙ¥Í_O¹#1l2ÝúRWÎw®œ©‚ñRÁ+²¹óÄíá @Sn<€1‚ÁÝXçÖk‡·Ûb³Á·Kƒ¨çýíÈÄPmª­%VÁ‘_+Ão[lu‰‹Å¦è¿ Œ`‹otl3¶û2À0Ú™íªLØ3šN/Ev;Q-'·“,-ƒí¼“Eš7ü†>(Æàj¾¢áfbs_Á‹+ól±#¿‘MÙ©‚2ewX»«ó&/MÞˆšf¿í¢}JögDÆlt³ìÞÑ®2Þ˜q2šîÞv˜»‚&ý-©ÉÏ_·”šÅ$•_&%[œ­“ÝRñ¤ü?ûI«åJòxñ¾lZý¬ÍÆùÖµúÖ˜Õÿ_ÒÉÝ endstream endobj 1404 0 obj << /Length 2261 /Filter /FlateDecode >> stream xÚíZmܶþ~¿BMZxðrÅ7½¸èÇw6mã\?Nh%WµV:KÚ\ýï;Ã!µ’V÷_ŒkqwÀJ’3Ã!9óp(ßûàùÞ›“ïÎOÖ¯÷b"ðÎ/<É#…±ªˆ©Xzç™÷~ñv)ô"o6yS·Ë•£ÅË%׋lWTEÛ5Ë•^$]QWT÷f_dùsz——yÒæTàLÆ—¿œrv~ò鄃¾Ç½P€8ÅB?ôÒÝÉû_|/ú÷žÏdyW¦ÕÎSAÏÒûñä‡ßêï3.´Š½é³ùà]WõîM/7ˆXÀ¥Ä!‘FÙÞ'Æh åS³I1Ýy’Ô %ÓZr %Í稡 [Á™TR ÒK‡Õš…1ü™î=1dJ0=G˜jvØ“R`ÙJ'°§øvþA\  ­ý¾==|3²ôÿ~|Þ¬œXã"ÂÇaEЊÃßøÞËA°”Ö\Š)œ0öÒ¶¦·—#½újm m‹ 4¬ù/ Ä@¬3´ ÂvCƒÜÕ¿gõ[pòt¦\1ó¹y†,ˆÚÓ¸ÐíànpëûŠ “§ùØlô¯—M}i¼ˆ=™F³KnR@ïýJ¡^„ZQŸÞ5(lä~LßÅô]¬G€Ð¥N¶ÐN’¨ÿˆýׯC9 aajœÌX¾¿~ómï8±Ôä—e‘&TÀ&ÈuÕX¿–C#­ã•P,/iØ¿3N¹EGÜ%àƒ¡Ô᯿(ª¼Ëè5Kò]]1äœW°]b˜~ÓÿeÙåØÍ_T ÁoK ÜJäùyèÅsê?ao ã›=*4däl3!óÁp®0`o— «/³›†.9,¢ØõIZÒ*)We«¤¬«|<â•”rq¾-l÷lòOKî/öE“[]móÊÙ-mò]^uIIšŸ%˜È…·§¼J6ež‘mW܇ «Llãæß±k–½Z®`/ºmÒᛄ·œHý‚ÀÂÛÓWTB€"lךj’4Í/;¢eI—lLxÅÒD[˜A0› tØ£ÏÊ’ZV9Þ¨Q÷uIC9‘rÑÔ»IƒKZFÅ.¡—Ïýrãà^5Ù¢µ‹Z³ Ž—åÐfÿ8?{AV>­éYÕÝìŠ44£ Í®5&Œ1ñå³ÙýÕ•È nEi'<›JÛ&Két­½\”Df¦T_L92ɳ¥Ò‹Ö-Q2(sNÖ:l =› œŸ›Í~A50lȺƒÒ (¶$mr‘Bð’ჺMÆ:Ü5½çIº¥7æz+­xÃ%DÈ"‡_£=‹†Ìj}l*³¨ÖËö»KzûÙ—ªÌ¯±âaå™êê6#÷ón%;qa¦¼,íV„…Ó¾èmÿÐàu!µWOò Adô„ AâîÒ2ºAj)‡íGqf›ƒ7§Í}'ø— 4Èìc8t€šñWwçiú!Ë}ÛÜG¯£þe&åqø-ù2 ÌÒ/âaCô¯èÛ»&©Zl0TH÷šõ軤Ú'¥…©G-¿1~t6¸C°Ãð´‡ “ÐQLƒÎ8–ÕË‹ÿÁšì.Ëüaà 8(€¿øÚñEÆ3þWñ©ÿUâÈÿö$ô0}¡÷3=Å?°óâ¾V|y¬ã{¬ñEÆ£ø¢üi|Qb  d¡]Pœï⋌E|ÁíSÆg6¾¨0B¤4¾ rwŽ(«©/½xŠIPL¢Ir™›{ð^M’PwI`-8›j´+ºûH=êŸg{w¸’ŰÊÍâ=íâ4ýd!ÿ÷þ‚ñã¿^½:;;=;½`d–Ÿ nkÊ u“€7Ê“ˆ@›s+ÚÔ91ƒƒ)ài´Ø²Êˆ4&Øzk_€•Œ|8DŸÀÓ¤œ :©è9D4§glD}¾«÷6»gëÉq]3 ÌKÍ$m®Ž2#ݶhÑñ'Æüp]ê(¬ˆ§—:ê–KòÁrìƒe°Hh—#üVãø;BZ“é1À¦>kH‰Ò]¾Û˜”DÒÍ$ƒìt ":†$ÍIÄ(,p%™ô¥“±Gº6Îp m=pJÕ8œ7µŽ\¿«¢ÛNf•ì®Ë‡ô-›s€7+š<íj— õâ®S$£6“¼ï=Ƚ›P1Óaøõ³&àgÒ BåàÜy”XèiæìÜ—Gèžäxú©_-{òÈÇùh³(BŽÓ(*¦yØÌƒD ”¬•Fö1ÖP}2EÈGvqÛÅ¡¾íÊ@1®ìÑûÛ?­7Eµn·#4aop²´,ÚŽ¢íßèñƒ+Î ”3Ä!#H±ŽþÍ,Ëã´ ×YÿºžM&LAÏ:FJê¤ôRX¼óg7„™Ð©šàã*ïÉ/î©_/—®æØgx—ukRd€Y”pZqÄÝ!¥Í;"ì/é™=mLFÿ®7ã.Iö¶º£[4d5ȪsMrjQT]Ñ#MÊ–-4Êò´ÈœšN‰Э,Lhõ³¯ý6Ï¿ìÒQÂ.ûp{À¿(ÑÝ@JSîŠï†«•‚ Ç ´ãöîO‚ñXÜp÷7·\Wm'ל·\5½EA‡si¯ç3'Mª;Ü£9ü2¸Q}ØŒðFOßÜ<ݘ<}sóÄxÜ^Š_ÿÍ x+ðŠñƒf´®=òLÛ/ÁKIÎíÑGrëv4s¡‹õ”•ǽ+#ó°ÄãM²q·¦ÎŸª³j¢&Yæ$V‹´ÞíÌ‘ Ôn HnQä³™ Ô’E2ìO€yñ~nü˜öõûvu3wšä,ˆÅˆUQ¸ñ~+åÃ6–E ‹Gx‘ÞºïvêƒG?ÄŽÃqþ¾Þߤ}Wï N¦ã+×6µûl¢+vù853=xjÅDpçï=¿S M’sû1gŒWНêÊ|ÿPu18«€;Û†S­þ Ì“k endstream endobj 1420 0 obj << /Length 2076 /Filter /FlateDecode >> stream xÚíYK“œ6¾ï¯à¨òbÄ_RÎ:N%®¼¼{IÙ9h@³C–‚Àÿût«%^ƒg7Þ”+‡\fÔ’úÝ_ƒgÝZžõÝÅ77Ï_‡ÌÊÜ,öcëfo%¾•„©fuSXïì7ŽÙ¢Û‰®‘Î¥Ÿ¤öK‡Evq,ëRösÙ¼/›šÖ¾ÊB<£ç·¢\ 0×÷]æü~óÃÅ·7^0¸Þ³]º‰—XùñâÝïžUÀü–çYjÝ+ª£Æ)üWÖõůžfÝspì¹~ u̬N&ß~JHæ¹^¿tMËoW²ìyY‰âkų¹ôùë ãY@é¦FW¿9Ì‹ìf€ý^j¹xöGˆ:o†º ûƒ ‡½zvSUDö}Yßjr¤‹ì®Qô™}Rƒh é:—Ëì׎;õy\_ÙtúÜBôŠ}=*e>HI¢ÁØü· Lî*½'çƒRXë­²©Ò ³õZ^•9^~‡ªA0æfQD:PGGž–¢À¸*ë;MÒÐÿNSv¢(;‘÷ŠkZWºwáR´fÂo˜Ædèõä[´NϬÃBà ©ˆ³'6P‡Í2ËCÓ '÷¨ô36Ž—±ñ ü6ÜÅÐ@»QÀCâfv¶¤ú|9|7ŒBÃÁ]K2´/À‚ÀþI´IºåÒJ…gÏ, „N©Ñý¡¬4QÞÔ5 ¦ÜoµI¢Á‘? 7ÃóB¤m•]jŽI>ñím\iIŒvŠë=8vñe¥Ö>|©¯WÜÎDÿ$Tî åçƒó ê¾Ìù¤¨÷^äC7*CŠº0´:ÿÊñÄ’„ìD§ëãÿ±nÕW)ýÒ!Ø r£›ê´N•ª t~ZÈZ6/[^éñÈcb4<¼Wua‡¥ìRo1]ýsãpåG•á4ŠÛo^]Išç&¢§‡¡%ʽ˜31ßÚC]ƒ±¨ªr¢N[CæäÅGšSI3ì~®ÇùP–Y˜Œ.Ì‹uÿœ@ûq2ú©a¦jxAœ¶$ÓLñ°LE°;Õ—£“JvFé $”Z£ž°–r#,Ç‘›úlY“$•]ûC™«ú!¦úŒ…ê Ö´ÉA`l¯ìîR”ÝJ½ÐvM. ZôN3]™kùv&ÞöCU9J,}ï­’A0¤¾Qð/“ Ÿ1 ÔÁ(ÎÌ—4€©’ˆ-“ô Á$Á Á$¾Ýä9GÁ'y€äŸyÝÒ)Ìû`S-h¦ÙÓÄ̺0Û‰°§%0Í¥>î w¯9rzøè$Èqzž± ²[Þ4#Þ¶¢¦érOÿSè…²ÚÞ*Ïîx¡Àˆht(rÊùÍ««gôd Žº1òæÂžÝ®«3×nĵ7•R¥¼ãòàšT/V~»!U–•Á)Âæ;ËšJçE/uÁúÜ<ì-2ðõ}Ùçâ‰2.I¯ýÇàLxPÄä)¹Ã#nô¿çžxnôó\ÃÛ ½”r8’c¤ÑLÂ4„ãBbaÚ{/o!ãDƒ¶TKÊ<é¢lÀ²¶Hªë!ÌìôQœÚÙÊ~¨M¤àº¤YQª¢B”½eKt›fF_Ïi89 hÃFˆ»Œúú±ÀM>EÝ›Æ(oŽ0,$b.m2Ò@4‡0¨Å¬{ÒG-ÇG~§ Ý*ä˜ ¶C˜¤r YÀx†|±eÆï÷«sò#!ežÒ±†:sÆHtóŽ8\Ì s=èÌtñkª‚ˆ¹„En’ĆæÓ"¼Xµ}~è»AŸmû¬w—û›QÔQž;…¦Š¤rµw¥móèW¥Ô^½0hgóG³3k¼oà ï…\íœ`Ï&/þfg£yy‹î3àÅ,›Ç$ŒÌ±8JPðÉŸÚž&޼Æ´Gö³ÈeøVER-œzÒS:þ$SÀÀô*¿ÌwTJè™´'oZSH`Uåš9ù(FÆØþ­¢[Š'"q–ºQ0!>êü@w!ênÝê¯xÚ~ N}ܼK4yJGê™²Ë’Ì ü‘LHPú¾ï&«Xøù|lÂQãIµ¸ßŠÌÔƒ˜AäFØ >—×肽%ý‚ÛÏ·¾@MÒÖ©8Û;%à@‘ÙUpqœ7çOv£È‡.`Ôåµòr”{z#´p ©R7¶DÈ•\eÞù>ƒñ‚Eî?çQYìúYvâQss¡›dÑc’áµÐ¨nú¡„Øl¤ÃOdÃÑ>¤ Eÿõž cªéc*€‚ü L`ŽLL²Œí«Ÿ¯—?~+i²ilU›Õ5°¶ÜÓìVô3z£‚½‘ïÊ ÁzÎk~…ï¬zZWÈBÝ\ªw ~8nšðÕ‰Ø`)”AoX‚¤I¾§% @™7¢»n¹x÷çLýCÉÂ_vªˆ‘ 0¾.Õ ÉA™Wåˆ/œ+ë±1ÜjN_t‚WÇ'6Œ[/sê *¯6ÞÆé–rùéæñ#z ËØä-8¨©¿Z|i:_ìh´ÔÎL1‰#ôüß!`×s¸+(—\½Íó—W޽*îKyXž¥^â&4ü/A9J1¨œ8Róíc¢øW±²Ñ…\?£Ä`¼ñe¡²&!ÃæiújWIïÛ1€ñ™7¦ÌÅû úÖµ‚Î믌Q^øèŒ›Ÿ ì3¦s_Š'Ž}û v3‹0õ­Ó¹ŒÃ ´ µóV³ÏŠ·ø‰tÍêß¿H: endstream endobj 1440 0 obj << /Length 3222 /Filter /FlateDecode >> stream xÚµYsã¶ùÝ¿Bo¥f"†ïGgsÔÉdÛîz3íl2J‚,Æ©ðˆãþú~HÒº›lûb@à»/8X=¬‚Õ77_Üß|þu¤V¹Ÿ':YÝV¡Êü,ÍWi”ùQ®î÷«÷Þwk{¦Ýš¶éÖfÞíZÅÞþTÖe×·ëMì}ÙÔ¼öÍPîÍg<~c*St†'Ê×ÚWëŸî¿½ùêþæ×8+µJ5\ùi®v§›÷?«=À¿]~˜g«'ÚuZEI¿ÕêíÍ?nÁüõ ø: ñ«D­ZX¸¾™(VÊÏãX#Éx½ ü L™Z墄埿fõ~wWw=q§ªÊú¹PÔ{ìšúÇ Œ†v\{÷úX•¦îy|*vDz6Ý §Ï¿3GnÁj£#¸=fîÈó.SHøŽ¯ÄÉÃ÷¡]>ÈØãÛÈ.x¨kv€Yp&t,¬ÎÕW‹O · b¥Ž@Ûmì /‘¡ ¥öæ ™b É+`ß[̘n°îÓ@a#L@ .‰Ú<£v ,CKÈ` 1²WîÍYY Uÿs ¾Î3EuâÏfˆ&€¨íWé)ÎPŠQ87Îr>—Ÿ†#+ßWåÕŒh÷Ó‹,Íý4˦4fešýZžO~-„¼—r2 c£å¡ox_¾~˰·oÐ?þÀPHÎ$¦äìT>‘Ì2z=ÒùWÐSA_'Óñ…TRJáÂï¾|õ¢Ñd±Ÿeñ¤M±âCì÷ïÞÜý_ÈH!ÑŒF––²ƒìE“‘¡!"Ôæ´× HB?M”Ky^ºÎº9mEse; ÎØÃId&?)Žu£ŸhÜiæçùh5ï[¢Låe] S_§ñd5;ñrì¬ÈÝH7ÙŠiç¿È—ZDaÌì0 ‘Ì])pGI>Og^5uu/‰"uÍxá%’ÌOFµl©Œ®»+nJe=i‡êÔcK­(¹†)eôð *Ç7'ãÎc£l›HÃÙÞœM½7µ]mä3ènÙ™)j§ÀJŽqX9ññd¼|õ5®2ŽgFð†ßÊgü›<ðó(^$: ë™'¥Í¡w¿Î¡Œà¯E˜QNù2ÀÇA3¯IÈà“)êÎî-zͰ ÈìFI¢£­l‚¬©1“‘²9ròœ¸xâjE¶á±ÂH¹b‹0W<‘Éá P7üõ¯èàÀã%y°qF&Z|"E.jS¨îø¤W¯tûýW<~Á÷kÔëBºz“·'¬„KW(†È ÇªË¦g@3 ÓÙ¡y„ü„¶ª0ÖðS¨b׈հHãDK`4j :›JBc®x£dö"Uþ躦–šZ¬„òû+Å FE7¯¥´·¨¡þ(Ï\·«1aÅ¥CkX~﨨ˆ’4^NÆÞšScO±"î¦|Üøþg¶«€®;JࢻÇc¯iq±­¤&Ø#¤Jp:räÎzº+Òý°ßÓ™Ÿ¦¹õg|å:ò‚t奌#_e‘ë©sD¨•g+F±x®ýl9Øl%VÁÆÓzYÊçcÏ>wôÏçRçoP<Éqegw«±¬ŠY[ž**N˜O³ÀgnªAeç” f 0Ã%}ß®ðL…Pj¨Ï@i¹Èí—JÁ´9#lÜãcYÑõE؃̺Øÿ"k€ú£¹¢ 9T ÙØ¯£Šó´Ÿ«’T„gåéšf@J£RµLœùÒ†!,®Up¡öSU2iS+õ*S?ô²‘›V½º®$«ÇÙØô,¦ÂŒD*'¡÷5m·•5ó£€pKƒ°3Ný8^¤÷§f̸2é€f³VG6µ:`(ú[(fdô8!µ‡ÅIÚö_ù×”Ç~s”cµ'•þã¾`‡PõP®œž|¶“š¾èŒàÉ Ìt&ÊŽ;ŒÜŠ÷uò¹]c«ÅÑÂ]# ÏÖLñM%”í;*xãf ¸d¬ßÏ%•$0‡¢N ÷ÉÑ&^q ºÞ9 ¾¤@©DÜ•%«¸ÍC™øN|:lâö-ÞÈ’Â驨§9Ñù[Ù#°jj¶Ø–‘x‰7¶U2¶âj³Õ›§"J순ç’±=~*~Ç Øfú•ôÑ¥m²uš{fêHçÑróå³Ð#ÞCwÔIâº@ì†RÔ¬Ô35½[èè‹ ,‚¸{·ã„‚ÔtÊþ:Þk cÙRhZ9RqÞOÙ<à>@¦Ý“•yùÃP1Œµ|Ö$ Œ?©0 ÃØWá ÞsøóX ½XA™OaóTœÏâ¬Ù)6;Ž,T‡*Ÿ+3šÚ;‘Û3ÆŸ)cÅE'ÁÕ­!Õ¥%bÌåÌe ¡Ô擪9¹!úêÇdè1é3Ç ÂÌAÐvúJ52A¨Ž—-ÚWXÎØWIXV~ÊÐFέŠ~~ûÕÞ¬M&§¢˜3D'ˆ îšõÃfùé¬rm†~n£²“N¯1ru-¶ôˬLw”0všž®½¹ö:6ÕüùÓçëd:ϪØÊ ý, §WÕðóª:½’ޞϤèSÿó­5u䇡îèy6½…cT™úìÜ ˜\ˆè&íBÒnþ™¼ÎÀº°‰*³sËM%>¤AÑ@NƒÈe—±¿¢MÎS•=_¾¯MoÃ^èsô˜q·-(s)Fá`+wÿètrhA‰´º¦ød&:£ÝÐ^¥`)÷n§ÎYs\6ÌÈ t.‰(<Á/çÈÙ)zãÎbÂ±Ž²ÂM‡¶9ñhæ?컡v^ÓáÐñŽœsUÙËÛäm}IàDÛHÀ‹ONÈç`8ŠÿC/ksÂ$Zo­C˜Nžüͤ9×Î6fO>ÒqHÂGÛ4vR¾4Y6ôay?ìù!æ•1á­*B"å·eÜR ˜_Òòòô/O϶¾¿»ç5Ì"N'HÎäfIçHÇî»(lr¯Šg YÆŸ]ý÷ –}M§eXçpã¡îåéÁ àA>8 ç\¨¶kœð¦K>âÑKÏ2¯À$»0Øs¢ÿ1ó„#&|édîéRŒˆ[s’Ѥ(3üèÎù¨Jܸ$(cŀߙbš©‹^ƾ6` ñ5£bM‘¡K‡lI·±¸Å±Á…³ë̤àºNÆ-ñlp•E¥|¨7‹öž+»â\lË o;Ec$Zþ TA°ûèÿ€ºüÏ-8"Ò¾RzŠ·ëMåX¢÷k °–¢!J´Moù«ÿʯÊ5 endstream endobj 1453 0 obj << /Length 3175 /Filter /FlateDecode >> stream xÚí[[wÛ¸~÷¯`z*c#€džšMœ­÷ÖÝÄÛöœÝ} (ÚbM‘ŠH%õ¿ï àM²k[»§ÛÔ~A\gsý×¾<ùâòäÅ[%‚„%Fšàò*ˆd©˜©$ .—ÁO³¯çRÏòí"ßÖÍüLFñìÕ\èÙr]TEÓnçgz–¶E]QÛ—»b™ŸRù]^æi“Ó‹`R21ÿåò«“óË“'–ç å‹xd듟~áÁê¿ 8 “8ød{­ebx–Áû“N¸#3s&Mˆ½¶Ð°Wùî.&g<ŒˆÉË•#óyËñç¶µ¬-¨þgª2·äûõ_¼ ãÁ”<8“ VÔ4㫲„‘J¡üø@~PÓä 5¨ü8Q²X©gë4ÃUWE•»nUž/©”ÒãÆÎ49Ðfé‚:G—¢­]÷]»Ê«¶ÈÒ6§ßÒ®\Å×o^3*}qKƒ—ùntº+[j°; Ï¿»øÇ\ëÙYY8ˆ‰[ìÞ Ím¾nüüECÓõòBÁÁíc{h>«Ò5ðgÊ$q·"¿*6´‘ÓÊw(rc"c&T$;ñ›ó·_[¹^~‡t¾úöü¾íÒ QìÇ2¢‰Ô {¢Ö¢5´{&ÒŠže¥%³zcÇÑ[}Eƒ[?óª&™aŸ?ÍŠpºâ<ÒHPªû⇠¢å6u‹àiÚÔEÕ ‚¹ª–´ðÖnÒYî&ã­ºš+€ÝP3è±ØæéÍÜ€>ÚyˆBXR[sK"Xo¶õºhò¥ëò U½Þ•®cZ–5Ö|¢×]µÍI*DR‘µ¹ï™eyÓPÙj1.Óº /K–ô‚ú=aIÝ µvÕ“²puÀÖ2]øuU¢zߎØT~{£h¶­ëYŒC'¨ëf ¡gÿ*Ü–ÛænjÛüfäô ?0Rèë• z-‹æ¸V"ô®ËôŽhˆfUÝR‡…kܤ(fG!€jÐåž±!Qí΀˜ÝfÜ󱧇l}W•´{¨™~'¡lwŸ^½÷—ƒÊeÚ¦cínòl·µªúÉŠëUÛÉtÐpïŠwÉšpSݤMCª»]²ŽÁˆ%¡$/`ûBž`;:òÇv%¬º¶q³Ê·Ö cMJ¦Ú‰M¥uý’N»OQ»C¢|XO³­wý´¥8/–Ñ¢gYUVlP‰°©pÄ»™ãI¨Â&Ü‚ÄpÐ5 ¯—ž0ï,_Â^ŒÉ?`-érYT×ÐMôöŠ“ C’Âw;+TøÕ¨ºpÝ–y“9ê¸÷Øvµ+ýŽcàä¨@"¹`!7>|¿urjî‹ J0 ³ Z&`„š¿Ïó#ɉ™]\{½Å=ÍÓ–R“^’Üî:°“£&5N4ØÛª´ÐÐM ¹µBà¿—)¡5ÓQÇU¯—ÂFœsá69”Œ‡´gdùƒMÛ`vÈ@0cZxLó–>´gï‹AX¥©wU…ºu”¬Eb´g=xÌnïS¬J?†<¿%¾ÙYe÷žæ(ÊŒ„,6êkÁ’î#Ij&º|"ðÈ"Ÿ…›Ç”’Îu¹¼þ-Jßw¹8…*•®7%%ðÎiBëØ•Icl2 {;haÚi3Š÷ÆÇ¨ï\ ÜØ‘‚Þ±ßn‹²,vk¶.Zž‡FŒªÎj<í“dí³š!)]R^d6‡¶Fi\µ›S'OrTñXã;-ØÔ›ÓI°Ié´D)NÚ’§œ0,`Rv;øÏ:ï´pêxà˜*ßq˜Z9Ì'Ë;mðY£æuuˆx,ÂÇH¯‚P¦D£ÇÃÇ—†ÐçüM­’EÀtbSL‹ÒÊM»–Nn¾‚äÖ5«ÈIÜ¿ƒ¾j0¦~6`~°¾9)äc¥áÆZÁuÛÀYð¨£ìSÑ®îÛ8i˜è3{|ƒ£Ù´ã¹ˆ™PŽ5òûñÄG2uEùÀ<'“Oÿ]íÓÎIê·P>ù[*ßKÊÛ„Æ|BŒ÷’üÎK²mʲm²¿ãýϸG<$_GÇÄͲÙëgÄ äØŸ7¾˜œWíöö©ž¦a,ŸäY&aîóÑÿ§FZ8€‹þ@ùi7«ÚýP ˜ÚBé2ÒaÍ».á §´Ÿ’âåU¶½µ̉›±½ÝŒÿE7Nqa(Hv?sÅö¾{Ô‹·Ž@,Ác2Èà,„#sÄÃq@9u'e9è)7&ýáàªùÖÿw*Í©Ícôâl*Û¬mŽ¿ÂïåÇLЬÒ0VOŸâaŠ5›Læ©qÉe±ÿkIøQqIýþâÒo[tl¿Âü±åaR¿3þìÅUïUŸãÒs\zŽKåçw&ýÅ¥çóÒï5.™ç¸ô—žãÒÁ¸ôaGÎxúÿ¬ãÿevzœpf¾¸šƒ•ªÙ­:ìèeGÓ Œ…=@šîqÅXFŒ">Óª†1[z¢Ób>^‹Ëvz¸zëæ¡G”µ‹\=Š*„húÉ»!K‡"-*‡Hzh' q ‚}ÄSÄ! †`±ê"€}Õü±°ØʳàÛ1܆°QØ€Q¤ÞµíX-;8Qá*wú{Bîn:lÔ`…ídù*o„ñ†u茇áæ' ù3¥™@o§kïëµCΧK„θò‚˜€¢…l"’Þ5ágåæ8ú)&1žýMÓ3K+m¬Ûüe¨½ÆËÔ‘pÿ•¼CaS¦™ëäWïçš,6µÜ-Ý(¿0YÊ*u(×bÈxY°l—x˜{VïªÖA»ÖyÚì¶¹Cö00krh?ΰßUkÉÔœ­/¼©zëôðEgq¤c+gˆuÛYsCf3ÀãwöZ¦[äŠ<æÖ_(óîÆÁÒ×yDÝÞœ•uÓ£¿Ö1ËŸGœÐÁˆzGlXNª‡¤¦-•&€ì†jÉ2´ÃaSy|qkœwƒ·¡4µ-ðë¼çSYó#á³ D’_ã^zfFt]\yF ǧZÇ‚×ô"öPL™ ãI4¶ä} Ëpp5!43Ü ¬Ã[TÞ¦Cã‡êe]åTc/8³weï\Ä3ˆô6ZcØØŠFM"EHXNxÄ 7©ší–܇éckj=ç”zOæfEQï]=¶ÃóÕ4]É2û ÓÑ]ã/^˜áAáÚby·)ø|Aw(tv7"ºfx•ƒ<k¤ýu3½Ê5è¼íDrxXtcg‘£{ ‹/›vxùcp±Ãô;„ÀðŸnuË¢ruƒË-èrªám‰¬dÀ¦ÇˆÇ$ "·2ÒÅñ0F”´¥Z0yÇ ð¡óãÉ„swùpY`"¡Å3Ê/®æ¤ÓöDœ7wü“mŒv—Li ª;J÷D°ì›|Q¤•?óHä©ñua;Ç4©$šñþ>o{×ïo·à— [˜hÔ胴O D$ô}]zMlžHîëºB…ºÞù;#דµOñûzú ñÓ;ŸZYpû¯|¼À©$ÂoÇôLp3{½J7sô•ÎÁÙ«§ó3£’ÙEÕÐÎ>‰VJb†4­ÿ¦a endstream endobj 1362 0 obj << /Type /ObjStm /N 100 /First 953 /Length 2452 /Filter /FlateDecode >> stream xÚ½ZÛnÉ}çWôãîÛÓ]—¾ÂÞÝ8Y ¶$ü@SÄJ±, $8ŸS-Ž$Š69¦Ç|XCVw×tWSU3$.8*N¢‹¬ÙÂgªŽB1ýA§!˜ .q6!¹œÅ„ìj´QS• ã"TµŸ0þC*6I0õŒ¤ØwÿÙºf­&aDm e³Íˆc±ï0Œ˜h):’fYQG)D؉O!'ÐNXNÄQ&[·D9™=£j0©dsÌêRÇf^©Ž™"f¯¸mI˜ ¿i`§„O±¹j€TÚ\˜!G³¾ŠÃý™õ¸i|ß~­ØÑˆ‘ ŸÚFšTu ³mnTÚ]n@ì. ©“ŒûNø-cðMÂ?©ÒF&§ñ~d†yµ˜TŒ ¶Buªv’ƒÓ¶ °ÆiIí;rZk›]жÇÅ%²µ.ÉýjÉ%…K@Ê.¥6Ç…Í• ü!•v”D.µóÂlUÍ&,uSq9àN3á³ÍN¸ˆÑæ$øOT[›2¤ûÙ¡Oí¨B*¶\Æ™; ÏÍ%BKÌ—›ž¥Ø¡š>Ts›Ùå w€$®s21…¢`øKam#àõRMA€-*PÆ'‚ `\ÆVc‰’¥7©­Ÿ(ÍSEØÕÐv.R‰Ì~Reµ;–ä*Í$Jb[~Us¶{‘êj5/ÅT!´ƒ4 gªI Ká<l„­pp“³³I÷«;GÐDð+×ýó_ÿ¶V©ž`ÒÍÝõõÛÉO?}V‘#ûŸßR|¹¸Y»³3×½4@ *÷C^¶@D¼Ü_% _¬±¹²à¡Ò_5Í´¹Ê uûâF á3²š¤äCÔ½^Œ€ω‰£O0YÎr³‚ø-ÒD1œJòÆüš€,–$±Ov ¬\¿8š¾e´ €±sµà)Ù |O65že(á`¹Ê d’Wä Ï©%Ù—11|"mö–‰ö4€dÖ#áù¬5ýàËøìXÔS˽Ô[ƈÜ\E'6•ŠGþm•‘ÏH€™T„_£l:IºC…RÁ–"Ò{*FVTóÔȇ‰€RÈ¢‘ËSèßID‡“Ë:9š@*íH ÇHéé¢ôtQꘜ°ñçF æ9a¥å>RØõ8"3¤ôh Åë>cn§ËéËéíå^G´$‹G •&2>„;ŠEÞÄ<$ÌëNpÕ80¸¶‘gUðL*‡‘ yÊ˵íHØ3ß JÊ'¢$%µ¯ÒªŽ¨Â“ªœ€ïºbêŠyÛQo ?èaÛeþV²¾·Y°…æOýôX³VÐs³žÙ±þf]¹æoÖ”µ‘pú|"»ÈÙgÔ 5~Ñ9­ç£°D1D vÁÑ)k£cb”¾y±À»g ÍA·­h]H$ÁÇùÛV‰9´9u´‡ÑnʺÇ{Xê=,÷Bé…M½hÛ{z{AzA{¡Ÿ9ŽÚ¿"dÖäM izÃ*$˜Œkøp¥ýP9bUV b¨V¸e¨¡Ê Z!JÝ6×ÖNåÖ£:Ìš:º5fÛö.šP4DTºD“ÔŒD9–&;{œâ5Ûó`C9Hj#&{€ €@N%5º·^¾"ë«tFÆÌ£x{ÂÀ(¼œE8±¬ [#–ØJ€£Œ›ŠW¶Nöä*_PÜ0ªn Ë ›4V Ú3£Þ@­õ:÷[òÌoØ57*~+P ßJt`GŸá¾V‹K9å ÀA¢÷Mòر,Q?cÊ·«ÝŠE­³Vy"ì!“±ëJ™Ö*;ùBØ“ÞV±‚‡*%ø²Uu‡®êE& | hû:@Qf |X¹(à{€\lÆ4@1ÝW;‡cò"l¤Zº:@±p@ Èˆ:¥¯}2ytº'ŸH÷x`º'B;é÷÷÷÷÷÷û’¬é!ÈØB+ò"’¦€}OŪÏrÊ´ZÔº/ Là>¥pë?kM§¶è3hG#|8Ûë àfkdV{(yïiD¼ç€ÛWy°„ ’[8Î>Sk2‘xRh”×¢„ÌM†’FLRìQIó ½2Rð™á81Û¦ƒ‡3æžÀ„ÈözHÙ‰=]γ1ˆðAKÒòPä! øLIÍ:އ4$•¿å Gc°ò.k<ƒ¥G\éWzÄ•q¥¯Æ¥¯Æ¥¯Æ5Œ Æ¡¶Öãã³½Ywz0¶Çü(­(²·×P¶•le¤úTåtÅ<ËZA½RQ6ZùºÇާ‰÷˜ *Ô;Hn­GzÒ`;ÄÆ'.\­±°1ÄJV)û yö02iuz¬2Òöb€°ƒìiäW˜öºì§–Ðó¤Z#ÿSòØB¨„ÄÞEmV“µ}67Óî¥{qvÖè^´Å»×Ý?^ýfß]®×·êºõ|vy‹]ò«Û«›ëÅìýjq}gª+?[|è.Þ_O—ÝûùòÝ|¹XùËõ‡ëï7»TÚ‹~(J¬àÆ=X)Ѳ¯ö¾Õؾ‚ñ‹ÙÊ/–ÓÙõ¼Y;»èþŒ2LùǻӢš»ôaºX-ÿó_ê®n.æŸßD㥴¥ø9 z¦ÄöÎÅ€É!SéIÙòÿÓÅ­ endstream endobj 1465 0 obj << /Length 2337 /Filter /FlateDecode >> stream xÚÝZßܶ~¿¿B@ª² )Š”Ô Žsv/?ìÆÞ"(Ü ÕiuwB´ÒZÒúêýß;Ãq%íºñÕ†aÔGrH‡‡ß µ–Ám ƒ§’Ë× J¨ ‰‚DIa´ ŠÝÅ«Ÿe°ù·Yfƒ{7jÄ6…²^^üxñõæâË'± 2‘ÙÈ›› ΔH¥ l %M°Ù¯ÂÇ«µ ÿôèϛ˫Ÿ7ߺ)*:¶Ϊ5i°Ž´È”¢)›Õ:2áO«H†ÏqÎÅåfn©5‰HtüPK'ËêĈX›À*-âÑP>öäêé_^¡“þÆ© :ð—á‹§€«µDt–›&€¼ƒâ—îÚØó ie§[ GB¦Ù8%ßïë À€ Á:Ö™H¬•™a‡r[Vâ N) =I=lŸªÃ]I•ñXZ:ÔÕu—wP—áÛ•5á(N/è.ÀŽfà±y³¥J_ÒŒ7x8e€­54Ÿ ö¶ã¥¾y¼v‚'[œéJáL·¶ózTÍdž{—óM9Z•Á)•Tzýå–UóaG—¤BíOn[üæÁiCjiÆW Gxƒ=Ã="ÔRãèâÐÈ;²,ÁoWpÛÛxNNÅé•Éâpßµ¤’ÆÀãé×+§I æ~’¢({ö 4lu~¦€´UsÈáaK& ·ùÃå(±•…Ûª+‹¡F›ß®~àQxËXûjβÝ‘õ½6F¨Ä_ gk^÷-ÙÙ6l£“BXC±ß `Ÿ_P­¨ º¶f•{öø]Ð9(Qz³ŠÉáq®Ýù8\±oªšŽ­PH”S€G\Ål›R(Ø @g5B§â\ ’sN‡+£S‘E¤BÐ\ïƒõ¯ÖFÊð1 ¡ÁqÁ‡)$ƒÞ`h¥Ê[ü±l~/â…å#@ÏòqlÜ©Éd2Ù5Ç‹†uôŒ¼r> ÓE¤ãþùeEaÕxgA7r=èq‘‚®¢>lÉqäè80¥ný½Åf˦€?±Äñ±«``¤ÙKj>Ç£G·µ/gõr#ÐÕ•y½ë©×­2 ¦²+)£ý™ ·å ^²üP[|fïw-ÙÞä;¤b­‘$mµ>9Kè# ¾™, Ÿùø†'X3µPÐ׃:š~ ]ý]{¨·¤uÑ;ydGÝS_ƒ¦÷5èŽUD¥GæmLjíò1;£Di„V#%~YÅ™¤-¾¢qoï¯+ÈW½ýl)ÿˆ¬ˆt4‡Ñ¥eìct¨Î j fªÌ’½X™8 F¯ÆVâCöpè_((ò¦êÚfç…oœN^3¿®KBO÷h"‘*Ì¿{ñµùûc<—ßž%Q":A+ý†Wûš)ÚºmÖ}¹Ïánc0A!9”CL£H;fl–ôíò1*«˜µL` ƒ˜ÅN +‘Yö @R>ÉIP3gŠÓ4¤÷weÀ<¨cÃöpÇÚnPEsvÃµØ b¯—x)†œ¼`à”ÓmÄ•]Y—.mÀi@í1æ}0máÇnìBg"–ÑÙüOr€Çe‚j™ Êó@Bb.uò!@fcÊ •I>§£á®bó8ý“§›Ù=0Í„R¸ý=¿lHзu9æ.ØFþ¥Õ÷wysØ1ÍWãeSHp¹ƒO-€²]¾mÀ¤¼¿+dž³ ÊC³…EÛ9s@À'n`(éÄ)Ë{P¨Ÿ…Zˆôð0rÖ½ºC1 ‡<oEKn†²Óx-åõ,²1ÁÀUÊ~Ÿ%hQtjtŸ¡RÝ6pº[–ò)í)Õ=ß`ñ—à«üL˜N½ƒ“gú—…½Üà“­àG 4Чٻ*õ¯Wøõ áÁY iüâ¢-/¯ÃËÜ3‘Qs¥#wž{R2Fã~…À=÷ì]Ûy®OÃjºY~öïê&΂eÉ® Üþrã?ÓÀ­´‚ |‚Å ~ª ^ô‘&²±¤a‹f± 4}½I´0Æ8q -xi*…OÍ8±ÜüCh> tPL»H2øç¦{a"bcáÕä5ª”‡Wô¢TúF=.è%ò¨N—+ ¡a´ôã©ngÅÿýþn‚ƒ |Ò"£añÔ{cæžÃ¨æî‰Œ®XݹÈáe¸Çã5 /ßmhnZa $G]*, BgŠ n‚§! ï ÅÿrN€\ŽP®m&¤RøÙT mÜ7[÷•s–'\?hj~`Þ´-ßí±ÿ8Sf~H ÿqžXx )ÏiÆ@Á*“äÚîã‰2JÄb?5‘À²§ÍèåE3ñÉEó"t%ßðå%ò¨N—ûTDò¹îh$ýôDbÔŒHॵ O–¡3ÅaˆF"}Ÿ‘àõJ!w}‘¨ QÉßÖnLL%ÿr‰{“/>¿~d²Z&O×ù¯EýëÃáŸô9·‰ÿ6OnÆ$l’ÔcÓ߯l5oƼ¿—±´…ü­›æôuüõªeuóެoüÉÏ¡—[E_8ÆŒxXÌ$øSÝ95¼>.ûg^OÙ''ÿ(9CŽQ¶$G-OÈÑ‹ðúû†'/‘Guò¸Ü§"ÿÏuŸ+ùGÉŒü£tIþZN–Ñ’Ñ™â‚0¤#ùƒ¾ÏüÛ£$y7÷«H¤2å_šF BöÃ_ÆŸ=úáòÃò@ ûÍÕ‹q¨·dùÃ>ä ‘M–¿ëãQ¿ßÿ@0Qê¾îÆ‘£É¥–Kþc®¦$ endstream endobj 1485 0 obj << /Length 3295 /Filter /FlateDecode >> stream xÚåÉvܸñ®¯è[Zyn\œ“Ç[<žÅckrqæ9h6[â3›ì!ÙV<_Ÿ*T\D)²üž‰j¬…Ú€áêr®^ž}qöÝ‹H¬² ‹e¼ºØ¯¹J¢4ˆ2µºØ­Þ¯_ŸK½.ÚmÑ6ÝùF&éúɹÐëÝ¡¬Ë®oÏ7zmú²©iîå©Ü¨ý¶¨ ÓÔ”8ÿý⇳çgœ 8>\ :. ’0Y凳÷¿‡«Œÿ° •¥«k»ê°Šâ~«Õ»³_ÏÂ1êqŽ•v{ÑQÏT5}½.û«²¦v´ÞìúªéxYÁÛó¦îoÚ¢C^I¹~‡jÐÈ Ï6R ð9ë4E 4Z„T3p™A-&›E½›ACÊ0Ú÷Ðt€i¸©ºÆ­¶üßñQ§b –Õî jm‹Ë²#²@¶=õϵ„'¬$¨›R‰õ±mœzJ%GäA‡P„EÝ纎—9êÉ çK`êÈ-êžÖ¡ðp°-[jHÝ£p$ a)………!A:8Fr= #F3–bš`Î#’ôÓ¢ [` ¨‘×À­E¯Db…¥€™^ôŠDŸ f©‘èq±å ­6;jÑþdQuaºi‹¿AqG àð©lN —ïøL”»"›‚å3êl ·ã5-ó"v.Ò³ÂÍ&A¦$;©LÎ숬£€Ÿýõ/Üß÷H‘Š Æòªéü†-X%rö#þ+z´ö<@sb²`H—q4 ”«'æFßô®UÜØË»G¯ …Â{o”Vmª/'B¹u–ÑáúP˜ÚSâÎWër?Çq¶ÞUÅ"Hd2Õ5¦ÔjmŽÇ´w.‘-¦ä¹Ê 7£ÏÇ~ÙÓïu‰n[(_;sYƒÛÚ¡õF"·ìNÛÉQ¹± éwLKrØññŒ†c Áê„í£“=B14feow“ì±Y€å¹6y%l˜Ë%mcgmlÐÂíƒæX¤Asl S)(Ñ\NÛfäÉy‚É“còäˆ<±@žtä‰<9 ˆ$ÙI$Ââ–­ß°E{j, è`šôhÉ5µwž™WhÄ;ÓÙí°lGDzF1&¤CßðB&ýÇOÊl¢-M08E%7§®`(ŸpÜT§‚³$¸;µ‘&Ñ:ÜÌjDȪ=¯XôȤüÀ­pp Ó‹¼ÄkÈÛÁÐÕÈ~Ó$Ð'²ý¾~û½þð£Ä/?¿xõrÁÞˆ–#{GÈuÓó{úÑ=O´GغìÇm ¬YËÃ!té5>\›Ú‘⃜_pž¦Ó •ûbNÚm")Á >¶[msêá1eÝ€†eÜކ匽—oj\~yj-áZNk±½e@ͶÏTðè¾mÔ2ôS5”füC³;U¶B÷ÉÀ28¸v­bŽm.®+ªý¢iœœ/±uÞ±©ªó—k?O¹fù Gy¥ég[m¢Pû- ‹Ø°±¢kÿ5XmËóþ†¡t ³äÛICeHa«¾}¹QL±~°ÆÈ<…xÐ6ó”0ã¼ÎåÛÖí\rJÊ×W÷àsbù uT­³\ rRqáåÝQúEÉßMª¡ºT!œè‘ØíJ$ÿ¡ÅÚ]FÎÝIrË÷† TÍ~–Û¸;sæë®èr¾°ÞN/T^·È$äPÙÝ«nÑwrýº=¹lÀýv³{YãhʛÙ‚ck_"‹¯¬R F +å¤XáìvÁ]-T, ØšU,³ìxá"ñöÂånÙÞRÍx‘?ž¡;¹1§WËÁ¸ë "ê.:ù‚cR,¾¡¯I({³âË÷Ê®_?{Ê# ”]w*x¨¿v4Ï/¹0Èlòm¾é®Œ I(Ç;bÌÓ>b €ùQ¢×¯jZ»?õ§–O¿¢ ä¢U/˜AR÷Ô–%Ää+MXD–®©GȦm1&îBàôŽë5d¤4à\’Æ[ærj'¥êŠÀ=Në½ÌÈÖŽ¸×©_§D‹Å]ú²ñr_Ôšr}½âÄ+4HqpÙŠƒC7Yq ¹±íÔžGz½¹:˜œfý΂þ¨,$ý‰GúKGú#“ÈÉ&¼þX¬þ #ýYÀgñ£ÂñÿY®mAb>~ÈÛÏGLÙ_¨Rö/޽€â‘€âµë «lü˜ žj+_ëekš¹¦"î#õŠšèç#{p<ëó±ð‡éÐp—åX}eúûÜ"Z{´ÉÐ ‘;8–Àa‘ÿôík±0ñð¸ou…XÌfC_°°Ì¢ª/ðY™ï(ñš|&êæd¿Ëø ±Ô}}–AÐå‹Ë…·â‚¼Hh5‚¬æCÙ}ùz&ΰOSûã³–› u¹ùcÿ%7J*{õqó© {ñ_ª‹Ü&hÙÐñ)ËŒ<‡.«&nFnyê܉A‡ †Éô“Žûù’{;þð(7P÷b©[þYÜÛăP¡bÌTy€£nÌú»¬¡ž,ûT> stream xÚåZÝ“Û6ß¿ÂÞ™X•DRwO¹4É´ëL³ûÖv2²D¯u«¯Jòmóß @Y”µ›l7swÓ{±($@ðG„ìoî6þæýÕ?n¯¾y'ƒMê¥Qmn$^§›X&žLÅæ¶Øü¼ýá:T[Ýïuß×»0N¶¯¯µ-ê²)‡±¿Þ©m6–mC´÷§²Ð¯¨ýAW:4½^zÁõ¯·ß_½½½úí*üM°‰C'½Ø7y}õó¯þ¦€þï7¾'Òdó`¸êŒxV››«Ÿ®ü¹þ"™éŸF^ óÄïù"&õ›¬F}„L·YS@CøÐ®á©{X‘ÓíC9©U”¿øBè^7#ñæUIm v°ÚÐß–M^vY5ÃxÌ"GM^ÿvøÛ“ÐR£f±îp+¹ªˆºçÁYžëÆx`Ù8ØÞšI^èîDvªF´"˜`^ª­ó߆XÐÜ „ ô¤1Õ =czk»oÞEbf¸](åvA쥂7>ϳõ?êã§N/Æ;†Ÿ†Ïº=¢Al;xl³6bÔ=uÔkŒ´á É~H=\KÛ2=‰Úˆ˜÷º€)Ñ‚Ø?iIdT•çÎÌû÷¸áŸˆpÐñ•ÀO@ô¶g1 +Ùõí´ü-¨>Àvˆ@Òv ß3¶C†´ð”x4¤Ü>KÒ_L×ëVÅlÆب[‚½å'´‰Ú:±ga)TRÛ›:«*c_`™4á¹s„+6ö,ã4 ÜÙ¯­;8Øû²*ÇOÔEÇ„&èŒ\&¶U±fˆ²î*]ƒÂÆI0*q/ñ ¾ÅŸùè™aÜN²|d"ɇÖæÝ‚À hèI†„Æè£Ö‘Mú'DÕæ¨ðýpo–ˆzxÑf“U`u `ã~/ëS/!ìTÕâìfÛöódu{2›m²^àèƒv$}Ì,eC,ƒÎÛ¦˜fãBtUîûì¼*d‡d˜ZÀ zÛkF‡UhNpvïh”™ze÷³Çö¹ÖÃÝ™Ðâ:,ЖÁ - ƒhAÇÉócg:ñ{Â÷yãɯ==ÁÉKÂ0«S6§QÞ´†Ù¶“ìT>jïT€”q$cŸÑžàv[jñKñà놆hTÜjŸG% 1"Fê#Äftú¹ÏD3šÖñ{Wö6 ›Ij\ÍNFrûg2 1ctÊð`bdôÕB&«ÿØž3Ú!¶žŒÀÙãWPà«ì©y¡ŒvDegñ {ðºgºõMÑÝ5-ÙlØúʳ<ðìG;{³^/Çœªê.Âyºh1Ýrñ1¨ ;ºb¦iáF?Šå€|0†cË›ª™Pœ&K)›\XOR~*P „ÙO{¨…c‚„+•¡ÅàýŒC„ô-M¤{4ð4t?ÎÒ̹þ\º&˜=U’ÁBÎ1'“Ƶ§Ö¥_C.=åp’p†®—Š/ÒY¼À3¢{ÆWF‚Vf%^è'˜”Æ~emzXÚEçc¸ÈÉ©cÖʦþöí»7o~Ä-zýÏ·O™(‚¬ÍÃÂÞ„œdI¦6ÏÕdFAÂÅWÆðò;±Qdài,×À·ÕJóq(æZLÖ[[òJ ãˆ.o±š]Þ “#f˜Øï¹±Zò"çNtªMFç=Z˜a~^>?`F³€) çE Ø ˜(û0‘N|Ñ#¼i”Š™J8µ˜¡òätŽa?¯rz*ÇL!­g–’c¦ˆØtHs À3³%Ò×c&œëè\ýZ1Sýõc¦ø‹™ê/3—ÐR üÅÿϺü_L!C/8ÜB> stream xÚ½Ù’Û¸ñ}¾B/©PU— ‘|Üxx·âJÖ“£Êëš‚HhÄŠÔò°×ùúô^’7öl*/"ÐFßP°yÜ›ïïþt÷Õw±Úd~¶÷›ûã& 7Iœúqmî‹Í[ïÇm¨=ÛlÛtÛ]˜¤Þ×[¥½â\Öe×·ÛöL_65}?”…}ÁíŸleMg¹£ü0ôÕöÝýwßÞßýr§`û`£x»ØO‚d“ŸïÞ¾ 6ÀØ~”¥›4뼉÷)|«Í›»¿ÝBz0?Â>ZA~%|„¢îrS7u™›ªü·}85]_›³%rž¯¾‹Ò’0ö3 j§”Ÿi͈^Õ èáH*½'ÛŸl‹È#t®šæ ZÚ.L,«Š[˳‡Î éþÎéã9@$2šDÇmxMË¡“ ËštHKxïË\F. (ë¼¼!ÐùÛ]¤”÷Æö}Y?"€‹£ö§6`õÏA¤Í#¶Q‹ß# …©œÄ3¼<_Úfiï=þÈhgóAé?ò¼Ã6 ¼<ÜÚbÈ‘ imUš:—¥àýæõ› 9 =ƒÎÖÔBa2ìNÈ ­ç‘áôž•|!¸ nú[§Ç{Šâdq+ƒˆqêÀ;}ÄŸÝ/[xÌnÅnêâå{˜ùê(h˜¿Ðj.¬>ØfX ,ëÇÝ€<ï…h¦Ú×*¢‰Ø£©ªƒÉŸxæBˆcíGAä&þè ¶Èú²lÛ:MŽ•¯R˜©á ±ž8´‹¢ÀOÃpɨƒœU–Á “NâЋHê(ÏÐ>#×pè7Fy&Yjy霧< y†#x•`¬C]8búÏ1Ë–åcY!tÂj-Çh-_«å-ך²€Ûº/AP­¢È»§}tà–e¨z¼g½dIÇoÏô Ö_Y¤…YÛ&)ñ³(œlZœáòðTäÏ7h!ÜühÐB ¼w‚¾ùi›hï mmÞ´EÇ# mCUðÀAp°e EQR5Ó|0øã7/‰©e~ãöN×7ßñ„IZp™£ÇTç *Ó&l^hbkoÝKK”yUÉ·KdCu¿L*4žÚƒöó¦>ºñ…Ô:©‡‘ >_N¢`„)àë-ÚµÞºi¦_-0èZ®„‡@Ìú‘ûçiç_Að['¸aêˆ>ÇÛGÓ‚RãPA´ Ì6ü¼½ÉE¾Ÿˆøâ÷67ä¥h¾S ,Dz¾Tö gšm40b[ª ø²×õÖG#5žUB"–oks¨Ø¡€C«ÂÉдhÈ@«¹ØšÇ‡ C wû+S޲È֠廿¸[ºZœmzà^í9ª=I#tÍÙ6µ`ê. CŸ({œd€˜‚QÁ)èÆÍ++J˜×ã¬(a {ÇrO 2`—YŸ¸&à#H¤Nµ÷gòÖP_,Ú&70â9´ŸƒÜÆšˆ†áºa¬pnÓ’ßÀO@Ëð‡ÙÅkˆ…sJ€q²Á(%‚¤ç[Î'd–ŒÍ`dä^>áµÃ l €´ILá[_ ‚†Õd@2PHptd!v:K& ZeÏ_ÔÛƒí ´íëIÐCÜÓ!o_²ͲtåCðÌ } L…þ‰'Œà­…Z[ç¢è6LxÓç—QJoËÆêlsÅ[r!ÄQlà‘EÁØwc‹M¤f·=wS3ƒ©Ù¿6Ãèàœ¹UÅX(Ÿ)÷ÐD¡V¸­ÁöŽT#­R¾,c5^‰ ³3µÈm‚’üÙ>3ºò™-^YÀç{Î$œyNè°ƒÆý¿î¹1yMèŒ^‚«ƒ¬¯ -’WøžÍ…«4`>Ç™nhÎF'z{5_+4fžï† ±Q΋„ÞÛ¢9ðL´ë;„ËÃëE{O6§5 /)ÀL‹3)k»À§VÁQ4ÆÊ£„½ó»†ù:£Y\¯xýòW··‡C)åV‘‰”óÿ!†Ú>[ì{wÒej¶I$ùq¯øÕ͵ R£çÉåЖ"›¿C"ÁªN q¹ÚûûO¯¸1I$tF‰Ô±èºv -vôzŠãv’†ÄqÚ]>4šißq@g>^SGôH§ÙsºM$ŽÃ‰«8NÏã8­–qܲ8yƒÆ<Žƒî§ƒ†c¾Ø.,¨šb98Îk5g§"J©áxxÆ ñGd³6vLÑÑÙ]îËe­°³¯¾ÔŽ™Ïÿ !¯‘¥.cœ‚cƈÈõ—g.. ¢ €=rûÐ<=˜î¡Ä¤×ýç—gäø”[G ù¢Yí" ¤v‘Mg¤ø#ð¾óÅó뿾âyS>Ç}¦Vˆˆ L ûFÄŠå`#C8dzì,œ¸Mæ¬yÚ™nG›ÉÑW'Nöô«)—ŸNæNKº€ ,°¥J?½²TT«Û‹XCcÍÒÐ"’aˆÁ¾"{y‰ ´Øv°Ñþ¡6§á'¯’ÄRõù‡×~–ÄnúU õ ZfÕÐUë4>gg»w©>´Œû^.U)1 q0Ô‘Qê’ƒÝÅæÝTãúª` J5Û³çêæïp,¶mŽçþK=Ê=_ô“ØÊHèÁ¡%ü ))“yâr ›3÷Ùx­‡X¤ƒ» ©Dˆ€•)ÆR ²)S,t¸'æ¼n)»ƒÀSÑ9þ­­ä,àî%a¾±;‹Gઔ7¼N7¤&ÔýÔg¿* ¤4é`uüuÖû‡¿¶Ú9ú6Ih®Ö¿\šê1þy÷ BMûµo̓) ¶ºú< £k )mÄ!ÌGÑG(ÕnœAOÊ ¥waLAI%(2¢ %!”BÀ]Íb†lÚÀ?’Ÿ8f%Å}b¨Ãhx°¶ýr\Ò¦¶»%7¯Q¢¾ÞB8sÑîÆÙ Ga]€¤Š$T©1c‚9Þ®ã"9VÎÒ –F‘j‘Ðb33­·²çó)ÉB”HŒb9V(_ç³ÙuöbZ#»La½ dîF©Ž2ÍÕ¡9» Lgd]Íèf¬¿ý Mœ½¯›+±[IXé”Þˆ±øgÖUUÀêp)òœ€ŠQ ª*|iT~d‰§ ­ÑQAÛÁæ1Iˆ},+ààòbE2YFB‰ØÃxaÅ„êBê 8Ë…Òa<÷8n¿ãZ10È,®—²1 ©ãsëÞ–Ž sc=VÿGV>¢qE9x0yn/Øì›öÙzÿ¤@e©GèØ”ãsÀ<(ÄáFž0‰`ÈêU ±jqÙ¯}Ç“¦»ÙÓÅî`øù/K×ovY¾Ù‘1 2>¸¼žH‰‡§/ßCèqÅtÝí”~¼ÈÔepÐÀ† tfánœEâ…R½°™¸¬*!–éY#s@ ¡³$ŠãH<ÑŒÀU¼ õC%ÂÈÍ)•Ê•·Ìaஹ6AâÍ+½Šqµ{ñIb9c¢§‚Ê4ª©øGú3KNeQhp@ah$Î ÂlWdÆÙ9G•úúY~k.ø‹YK[N“ØX°H•‡²"I£]Žü½~%Häw7Ÿªèf©ÖÓÛ*~É¡ž~ƒ¾“(½(ˆùÅrñÔÄKrÊ™3 Y¼Ö ÚçÈ’ô¾”§Ùë¥ÓNR†‘¯^QÛÔ)£‹÷Z,L¶´07îø¿Î_–Ô_n žtÕ<–õjBÓbSQâ(wúç¸7 lÎ#Pžƒ-œxâ•áI³§¢@<~°*š Êš¿F†%º ¨–Ñ¢þ¹‡„ÉaGÊâJÐ’Ö϶y$6´¦7š-DËÛuB{y\à˨ƒzñÞ3ãÒ¸sy¢+"Á¤’C$ј¸F³d1’"\&® g0|ešv6Κa=w²ÁØA(Y îÌÐä3K5÷Ô6Ãã‰\ñ 7±l٠؆sçŽ7¾Ñ¦RÎfnqfº LlÒÁŠMRåw5|~[¼89YeKÞü?_¿WêV”ä ||Ž–)2¦©Lj†ªÊCkÆ'W…%þkŽñÿ|¨äá¼|BM„‰ê d­:8<ÞŒâÒÝ NÆ×É@gT0Œ_þGXG¢yü›Ö0xc•¸À¹ü5²€KSòo†‘QëeéØ÷Ÿý§¬›ÿ#‹C_)©ö©˜ž4Uê½<™ËeÉy¬Ô ñÏ1qæ½lj¤úqXÿ­ì;Hº5¹ÿ?ØÆ endstream endobj 1503 0 obj << /Length 3063 /Filter /FlateDecode >> stream xÚ­Û’›Fö}¾B•—EU¦æR[ûà8N*qbgcmíV%)‚žk2 '_¿çÖq3HfXÌZÚÎEe}èxš@#\EE:XóÌEŸÄí’Í–5¤s›õR}u¸9ÓmŽRIU6¨ ûŽ–|ÌË3µÀ'VzRmegä›<³[(©E¦•úkœlQ>, À³]~äü-Š z9†ãï\C¥jKìÏ㯉þ¡ÿÃò|ÜúÀ>—¢¦Šúå¼39€ÕI¶Ÿã>“>>ðJ¸ÀªCš”­Ež& \WZôû„¸S7YQ´¨l(5Ì£óÅ„8±6 #ð_¡®ãÔ±°žåx¦ž9Ñsó¬‹QãRÝiý•‘PB ŒX±ä~³ÂX$®ÎÙäj*Æœ"}w}¹¤.ăT TfUÅ}Ûn,}1®Ÿ´T>5Ó–ðbYF&{ƒÆøb­5Ø~ öðTÍ~¼œL{,{H;ºXô=Þ¨¨Ä¶ü% â¶:q¢¡Y:†(ѬgàÈÑ[Ùˆ•Œ£ÓPƒË‚Á\p0ÝnØŸÕÂnNNFPJ ³…ñL“Ìd¿6Ë*Ær& ç\‚ý„ÐW5ma¸üup|jA«Ä%§9„ݶ͑G‡òî`ì¥Ð’ðW¬‘’!Ïc™¿ïø>ãh)µ˜“p]ko¨ðA¹*!ú|ñY:!»ãAVu /†ðºhÖJÓv¸œX¨žöÀ8o¥ÍòØ•òÜÀzÁq…Úßukœ_…n †ÖÕu½»]v’.nþ¾ÿÜæIdz)·7*€Vûeü†#뢋ÉM  ó™ãÜU%Ë-„Ž\/ä“™Rÿô²9@aµé™Ú¤„ç›NùÉŸOÎWI½‚Ï´É9“ºjaCÜ`¼gaº`“ïù$9¦Ío›sËøÇB34ÏŽ¦ªÊÌRcQ¸të"xöT‹7º¡ø »!?uµ gñ®:ß•õn.±+Êö)/Pžä ¬‹¯î¿pš/9•röäz’ ÍËuª¢’«•é÷í^3)”²V6ÂûBˆÒxƒ«Ä<±G\0²Gœ/G-\Ç$àƒþ`íHÃs{üµð7}"‘³æC¥ë¾Ð&M ËÄ Ž¦×ʈ4ÛR!eBø¤Nš•;7„Âáÿ岃yÓ§¬kb­`¸ùé”Õ,©ƒëŒaô½‘ÐÊí'ΗrŒ  ‘4–„^KfáL¼0~|æì–¢{ËÅN ˜‡vOJÍ,>•&—jFR¢Jc4ƪ3#ÐU{s/LT.ùJêñ‚1>®ðQ¶´ŽÓ;諒µÄÃŽ¶ID §x"ªãIN߉¤†ÑXÜ.m‹å'×%Qõ…‰­ø8â /¹ƒ<7tˆÄ èü\pêYN/zaþRºb6“Õ(Ji|l¿y¾§âgü "DŽÒv‚’飣crꦱ"(÷Ö©´x‘¢¤"­§çüüúû7ßo¥”¼]îpºóé$…Ÿ§X¶Æ7"žó©Ìö•yRA½“%iè1–*`ygsi pòº·¯²Æ5ú©%2¯ºÅ‘<›Êìâ\辟m4Ù¸´÷øŸ±ªî 5þTÁ9«ÊÛ‡]whÚžÞÊŠ¢~ñˆ7 Ѩ¾ŽmwŠ#탘 ŒfGÑ>ô -ÅÞFbሿUÀxb€|ÆóÛR„°Ÿãˆ¾S€ß¬(JÖ)Ø0þ²—ýÅqvñÈQ÷ ¶5‹d 9u#”¨Tzv%‹“5®¼<ÑG °Œ¶ÃÖ"#Hx©]öÜX«'…,¬$Æ!‹ ëùlbžøFßp(«a¥/¦ ÓNHn¤s†í“döªÙÐk‚¼ÿ?ß—Í?ÚÑÇ£/þfçú[#Ø"ô]¥Ä'`Gaê¼l u­ÖrËBžúÃK>¥çdýŸó… endstream endobj 1517 0 obj << /Length 2981 /Filter /FlateDecode >> stream xÚÝÙŽÛÈñ}¾Bo‘ÍæM¿m|Ák`áØäÁk-±5"ÌCæ±³“¯O]M‘”<y`“'6«¯º»ª«ÝÅíÂ]¼½úûÍÕó7Z¤NyÑâf·ˆ½E$Nú‹›lñyù~å…KÓlLS·«k/N–¿¬T¸ÌʼÊÛ®Y]‡KÝåuÅ}oû<3ϸýÑF·†”ãyŽZ}¹ùõêõÍÕ·+Û» ÅÛNìÆ‹myõù‹»ÈþëÂuü4YÜѨrD |‹Å§«\¹‚º;&!òg$(×qý˜IhVÊ]]”뮹_gu©óª%TìÏßøÉh/pR@èZ)' C^ä]•å[Ý!9‘·¼Û›noþÑüÙƒ€3ÝÊw—[á²e8oÈím]êÊTôµûº/2nodí¾5éjYÁt´—»®Ë(Øž w$ €4H+7ëÝl´EÒY]ûQº¼80˜0!öº.zœäú¼Š‹«ä-Cxã”ëM!¹8RÉÕ™[V °¡›.¯÷”FW²VUwÜ ravkt³E,÷¨IÊ[º'sx(|…{‹ŸàqVDƒó®5ÅNvPßÝAm}ŽE£C%;‡ƒ°ƒÑ¾Ð—¥ÉrÖø=èTàÏÐUÆÐ¶fÀg׸zgæÒ&¤]>-vRß;Fpín]O aØå¥¹ÔCþî†nÖ7ö4@¼ÉÅKT·ŒPÌ„O¦b»ï²£±˜˜} € M0¡H‘rã>y—³% [ÔâòßÂÞ0víÅ2v†#)¹ðÛóûî Ûwk$¡î»'2:Qßatx £ë¢0Pýg^ö¥@뎘…Mfh2ö0üý«— eG• ûjÛ;²·&ã1Öß°¯çQgøŒÝð"û!õô“ÕFÀ¨ýc—#¤w}ßl騰Ġ¯¬ß1µ<`cº;Òf#î~Ž9~qº0ìS¼„Ë:ÀЉ¼“laÀѹHh˺Bè0ŒU”µ±hìÐ)è- ¨Rö‡c¦Ô×­ÐE“z"°È%Ìâ¡;YB\C;¬huG Šc¤ŸL ¥@GCÈÓP]X D’=ß„?Ÿ>¬`Ü/ï_ó„CC\€ÃU¼£sN‡±ê¶Í‡se©U—Ƽ8ÍW<7uB8óƒ4€C>š'-qI‹âŠACââ¤Ê?oÏ.©E+"ÜÎöœ$‰YìÆ¹ÏK¸Tœ:¾ÚµbH†@Þ„ÙZ”?MÕC…N¤‹ ÍSÅ\3ŸÃ W/ UÊú5ÁcÊ(@ÁKæ˜(H-U<•$tü0ž¢òzŽ BýØ0 Qõ€µ®ø)¦–I²hí9ðã‰í%)È4°!ÞÇ7/yárä‡,,@±¥vÚÑÀHj‰_É ¿¬è¢(~ªä`^êËÉù-°Ž~ˆ‚ˆl‚ÁOKlŒÂoï>avÃÌ;"ô_\ h»É‰à q ¸Ô;+¸ï*º\„§O–\˜€dÔXr~<ÖØ¦(ü´èÆ8œbô¿$ºÚ\àBO];®71ºÐS5º) ?-º1çD‡ý¿ˆŽÍ@9±ÌOMå$ê„mçgûÞE§ø)ïÓˆ¢©º*Ǿ7 0‰¶Ç©–oﯠ±-rb¸Í× ÀçñžÊ÷€€cp8O憑$ ‡EÿñSQä´ñ£/æ-÷«8´ëO`X‡“oÄ<ñi/œ¿C^Oº‹÷¹Û‹¿Ê5…˜{&+ÉçÒ\£Ï6ËØI:KG[l/ó‹/0þµ§¬<ÅäÒKÊOS¾XiÚV7 ©Ü1B3 {Ïf ñµ(wI2‰ó'ð¾6¼yùa#Â1üÿÏWx¥™ã}Úüß2†òd\}o¾ƒ÷ù»S½¡¤Füîé%¤9¡Œõ1¬Ÿû#ðiQ2²ö2¥w;Ô!ć­'Ø"G´%ä]˜(#°Ûëê ŽÊ÷Á'‡OE2¶ €4áôBä*Þ—àW>]dJ6MÏøºÕ‡“Óóƒ)“'õGI+×EnàïG¢ûí üf¬`x½›™5Šû77u'ׯ‡¦îêm]È$Q4bf7 Ùô²bXó߯æÎ”lò½uhÉyÑ^n©r¥‘ïî×ú°–ûÆut)Zòâªæô¤ä9%å ¢ê[†Z˜ÐÛ«ÜDäˆ#´ýZúhxÍÀã] ²èž;Lj#¶É0›§k=0¯qœe’`²“¥é2gÊ ŠíRó&p_6b]“!h¯Ç¥ÅÞ;Ø)“óìôæá …Çúä\UšËÌt­5j·dÁ$äµ½‚­L±ÞääUÛŸ‘6}¤Î-+m)qïXÚ¡/Ò¦RV!(}8rÃk2Ò=¹¤aØ™A€ZÛ’êè€;®L’ÂY~,Ѻ³-ØZ×çD¸Ÿûýá`Ëo"°sÅÒ-‡ÙÀL3ÔÖà÷èéåÜ×öâos²øÏòs…r”‡‘º‡q+øYÅáûHáû¤ø?¨œt,àg*òSMðËC,õb'±^ëáê7%!-Š}Žc_„Ï, 2ƾ&ºóx,úÍBÚDû¸³Ò¥™ÎÓü™U8aÚ ®'ÌŽý oÏm~$¡,ßöŒfÕr„ù]‡Å=ƒØ—4*õÊê(•ø‘6.îÛò4ÀnFt17í¸¨œMe³í ÝŒžP?^¾ARÃhs”L¤ŽuÖ(8>àÓÓÞ¿²>ãŽúV0?V@†— jt·›1À>{èÎ?3 ­El—YIl|ñgt§>Qãc”ukki—º=:cì4ÿ¹¼ì¼1³š_Âp®`½ 8-HÀ`û|Bɸ88“Rª—Ф q,™xlT»'Œ{Yó·¥<gð‡ÔJªa%oëÊ.øSÂAÊ>~¬VÛü`'£+n§2…Ôì™±vÝDËw‚ùÐÚ˜a<½ ‘@Ú£šQsÖ£œ<¡Ð¢¹ò'F%¹ô‰ø®TOHÕµÍçm€q<†m­•R]µ…–bëøLdÕÉêÁüµ\À þèÇrgß÷ž£”<Qú¼À˽>¬ÐÈE×ãdéîQ._ÖzÇÛ~þÜïM¹ÓÝÿkÿÈ endstream endobj 1521 0 obj << /Length 3408 /Filter /FlateDecode >> stream xÚå]sܶñ]¿â<Ó»ŒH‚ÎôAMdÇq’&Ö¥}p\ Å£tlxä…äYÖtúß»‹@‚Év^«.»‹ýùânÁ¯Îþ¶9;‰EƲ8ˆ›ÛE(R–&Ù"‰Reáb³]¼[¾YrYv7e×ö«u¤Ë‹•Ëí¾jª~èVk¹Ì‡ªmèÝ«cµ-ŸÓømY—y_Òƒ`AÀÄêýæû³ËÍÙghà ±HØ.b OÅþìÝ{¾ØÂü÷ ÎÂ,]Ü+¨ý"ŠSø­Wg¿œqM?Ÿò‡>²˜e€/œñ0!6Þ®B¹üõ‡ËHÂùË”Oùæ,Ž$ S%²÷ñ H5{œ¿ ÓÉ‚uÊ’ ]¬…`™”´l³CN%_Öm‘×4lò½ž¼¯j=w£gnW_¶ ¿€/÷Ç:Ê­~ѵ{"2Ž'{ŠX°8Ž,•DáŒ0²4H C 2‘pœX†SryàÒ‘îä)2c‚ËOP!Yf¦ê5šé¥,–±xçÙ'd  ñ`ˆX– ðâSú•àË¡«š;ª dB†ôýo\r¾˜Å¡e¼[…|YÞ­"9ÊÀų0¶ôJÑŸûN•³hdãj_ Ç?>¶P½40 ν|iêÒy¨ó¢Ü—Íà“cÆ"nÕêüÎsž K¤•jŠdÔŸª@ÊGøÔ%`r~Œn0Õ̲S5ÛªKè õ®E£½§‡}Þ /ôT´ûC»&ýÚoäšcÜ"ã HñrÈ;”.Q;ÐËi~ÕÕA™-Ìõ»öXoi¼Ëq×HH‰¬Áòõ­Á[éÀn ļ+{ô}Aˆ{6ô.×8ñý`6»£Ií€4å`ƱÆRÓðˆG£Ç©¸#fWÅ‘Á²?ÞYÕpô:g™Ò'É0 —]™×{¶·ôkßÈæ\Oâx ˆ6Ib•ã÷û³Ñ†óf;nè›=©kŽËø Úî°#ŒJPe>›³à)ÎBˆ£ÂJûYógI6ñ¼dwLEÎlY¹û^ÉÞ£ç½gÐRβ sðßí®Ù¶åyŽ¡ÛgåGb(R ìa-c2±@ï‚Ï‚gâ¶mß{B¨Hë1ïÑ„´]Eue¬W ý»0˜‹‡Î¹±âI3Ôø¸ƒ”fŒ8è•5ÇdÍjseÍžÝÕäÄÄ=º˜Rx˜¥¾ áZ%‰`j•Yd\GOôÜÑbÎähôççïî|Â#H¸,¿®¥«d-•¨õ{2*ØLû"˜V¾fHG ¬|1ùÁn$O½š ilÌëö€[‚Úz¢™„¨YnüÁ'ÃîHd‘ûÒB,YœÎ<—‡uH²†ÖÍÆîêöÆdm3N%Äሂ[~¾ÿ¦'-QVDY™ëÔOù‰Æ›t§›mýa$F ~ãaÔš°:jÐ?I} c™ü‰èÁf©±s¢ë0ãGn¶ùíåËUÊ¡rˆ1 _%r¹y*¿àüDâ˯áñ…Â$Ú0Ò#u´ (p¯â(Ìä=ý•IÕaP݈ }C¦}CÂǾ½wí¾íJ³AÞЂ œ#tÜÞ‰ÇØ¦ÊT7´ÃéªÁ¶¼UnŸ|§RˆÇÏ ”A M·Ö«Nðæ‡C ™Ö /0ݨh›1ñézk8c!C„Tµ®2ì™á±ÄÏËU ³€/ÕGT³|¨Ë¤L2‚88ûíî½zû +HS?f!“"ƒQ@<XC.þXl†ºq›=ûEHe%ºpRqIˆ€B¨”$‚ø@o #àgœÅä)…ä8ƒ?µÞNfl ¼(Ñ*ܸ§*§}¨ÍŽv†øø¸_!@s¯¸â­ø?àðvñË(“èDðç•Õ ìdº‡ð¥*ÕN¤ˆ†±:”¨!§ôÆ ÌLÀÌ$QõôQÕºéWÆ'Ûd\Kg*ƒ^†ù\Qü[š·S̯å,,ƒ$|&&ã åI-—ô´å"CÈùíÍÞ)ßÔ«ìd¡2Rẻ‹Íw—?]°_oØå·¿®ÖÊ_éç?ã¢ÀùqØ]íµöÝ“5o±½ƒ)©P%¼N©ôþûêÙùݱì‡sÇñ~Ò¯Ÿ / úZå›Ïµ~8ÿ³ˆG¬]Ûrññ ‘Bœ½øõ‡öÈSéi‘ÿ×Ý׿l(x|š®ÇÁ˜®Ç‚‚Ìyì©PbŒÅTÒƒ/}—˜ÄÚä9õ§rìf=RD²`lG=VÚ`ÓDÚbKÅk ™bÐÙ—í4£Ó80-ýÞhС˛Þ4ë`Yœa›†h#ÆE6¯ t„†TCJ©‘ê-ÌÅ¡Þßæ4aèÅ)¢wµKE3NAé+ܰùø“’Ê "™¥Û¸å l‰)⯰±‚“N:„0oU ÕÎx yÄDè%€¶ lg¨ô…„3±¦¾~EÈS“âá’DÙ.KȳQñ͉üaNËF9ýXùÃꉾà+¯ì!ûñ'µ¬pl³IÀ·1|èì þåêœFýT¿P—jÈL—¬šõšÙNC®ICÁÒ4u]…+ _Ÿ!BÁÛâÍô¾òu^Æ“yùs¿«¦åʘYæ5õ6ˆÂ L*Òlãnš©Îûí>oJ%Æ*À¿Ó>çSUꪾvÒ]Ç/_#1ý“UN¤b¦#ôJáCH’±n- }ÒŠ—ºÖíPÂ<(=>ÒƒR\ˆÂ¤2˜èW½ÚCÞž^­ÚŠjä5ú’𿉻±'aJ& ‡+"­±¸"¿£q$l>‹fš¨ñŸ?V“|PZQgUͤfQ¥+°É­E:Ñ]æé>qÆæ|&…,:wAÎýzÛîsr¢ŸuÂrzÂÂJ@A/ûCYTèLKó†b‰\ê-ÔX×±OAIš&AÁó®%g¬ Aï©™„8uä"©ÀÄ,ÎÆ‹=˜‰49%©Ã‡ªÐdÌ]!l \ãÁ.×Úw¾f¹¤ŸStª›!ùØý>­­Ó(_…ª~x¤Y˜%,æcä)ö[²Fw1o„F© ACëm?²`l[!®sƒj1oùòÈHÜäS ñ„©À6UÀªÇ²ýºlŠîá š6åöz¨öèÓÖJX¨‡/UKÕêH#ÓCH%Fw©4fÍœnòÕid¦A E]QΔÚ[ ˜¥~L´J9׃Œ¨ç‡eU¸ ²£TŽžÀPL±5:à ‘maVšì®üeqÔË ¢“¡*Ît?òÍ·ß0Ÿ¢^•ƒ±ŽÔÈFV0.T_»²>hÀ–~@tO¤Ž”>¦pZʃçšCšÌ‡!/Ðh~W;d#•øŽ90™™º`Jb\Ñ©U±¥.54ÝÀ¦õÇÃA»Æv¼úy•ñåÅ›KŸ<¢ãò¥˜vÆçª©†JŬ< |aaÁ‘õdWj¼û’²¼©ú½»¥Sh1Ë—«ø¹Bm°ÓÈ@‡Ó84§ècÛ[¤6*IŠá Àcé±QlwàüGgÓ)×òd¹=N. p bsD£ò:aƒÅF½Ò'½­²œ¨Nêì6Æ3¦Žå€¯„aéÜÌÛŒ'&‡Atjr(½0\þ¤î¢Qè÷n;²³_vÀ6Þ¾ ê\i7 ‡ë¼¡#o»þKýÕ?U¥Ñs¨,(cÀ©ßyßßëÎt+“f)ÆEEQöTTH4§®=Þíèá»Íæç+:•|}¬Ô o¨n*Š©½n4î㈷ÕÄ`¨¿} ×ó„H¦+dE"“êN@dúÌqâÔ‡ 6ðaú€WçÖ&ïMÙ`®XŒU&qÂXïf˜xŽcÈ8ùŠFQÒ ùÇù—=Óœu†²¯öUwîmÔ°ËgdΗ;¸Ç‹çN-€bŽÛ¶ÉáwôFsS›…³ñrôù…/ÄΔ…êŽsÚâm¿©r®—‚Œñé÷/aT—&ßÂòI½udéÂ̯3cH¸¢É'ET"€–î­›]éY-¿Â2R͵ûû¡l®®~P‡¿&5z@wg®EŠ|}sl¶õä­.™O6š>÷Òëõ[¯d"àÝ&£ÛJë3ʆÞϲ>j.Éœï­ÀÔ¢‰p¸NÖaR _64ˆ¡ÈlÇüÞMërx„<{ÈñªR-°vƒoNíFYuº¼P €ÈôZ>¸ÉÄ`pº»Í'´N ª)·_ë¾bÚq Õíxô:¥¢BaÈMèzÔÖ±þ0@?_þèùH/WÍÙç¾-N?ï³.c¦)Ü5ŸËŸþ±ïçÕÉÒÌ^º–Íò)çßRʈñgJyú ( ˆÕ,Q»ÂN4޲å7 Ä•JA¨íÉXu—5y"™“õ?Zø•ô endstream endobj 1527 0 obj << /Length 3429 /Filter /FlateDecode >> stream xÚíÙrÜÆñ_±oÁV‰#ÌàVU™Rd'Š-Ñ*§l €ZD¸Œƒ4ÿ>ÝÓ=ƒƒKY”^\©ð;ÓstOwO_w÷açî^ýíòìéK_î‘„*Ü]^ï"µ‹üXø‰·»Ìw?;ßíUàý¡èÛa®¢Øy¾—“×eSc¿?œt,Û†Æ^Me^<¡öÛ¢*Ò¡ ŽJ ¹ÿõòÛ³‹Ë³ßÎ$ ww’Ðù"r£]VŸýü«»ËþíÎ^ïnõ¬zç‡1üV»wg?œ¹KÒÃpAzŠö‰¤+\/"ò‹ææOöˆûéK/^,ð\á«vÓS‡®ÈÊ_\Ï/à ž9ã± F“ÖÜj¯é7mè·höžëÜ”}ÛÔE3Ð E‹!¨ïüGtDRÈ@šÙ$$ÉBÒ,ôÝHÄ~´æ¡–œ \Á}”'b³ãË×ÿ¸xöt¬»§õÝU×·¿ß‰®¨O"e Ü01넾;Fù·˜{.CODQH$_Ýy¶Y´B |}]Vç¸D•W¾d•W¾"-Hšç}1 ¼f u`@³G’<¦¦ÑЉã) |÷Í êÏê ÐñȘú"­j4¾Çƒvåo^ÿD€¼­Ó²!èÐf¨˜ñŸŒwéx¤Q¢ÑnQµYZU¨0wŒnI&ŠÖ]ó¨õ—Ià‹œ_÷mM3õ±aØFÌFÈ•üޤÊÚªmxË:µã0· ye“US^ä5Õw^_Øb™wG‚õÎ,ʇÛ2QÌãÖmßùÅ ÜYn0xÏ4vÊkš^Ž4«ä­Ðb"üõ÷7!Cˆ ØWòÚNÒj±Ü ¡ßá7D5¥=út)}Fƒ&ó’X ²ÊáHKHÓ̹¨©År‚¨5q´²Šc#SÂ]†û~0Gœ§94õ4=kën Ó´‡}r ¡´ìu=5eZC€ÛRk3N92ˆ.@fa´HoÁ!{“´hàéš\Oöº9Ëó‡tþå Ê]“Šé¢ÃÏÂa·äÑ%v—°ÓÀ0†"ãø`±€O#QßÐå~˜útž…R( N¨—ô¼hI¿dvJç›7ï¨ñîí> œ÷Ô鋬íóÉA}÷À…'¢@°ÀâáÓöÖÚÎ¥¹íÒa¸Í¯†¢'Öõ_f}e¢m³CÆdÈ:šaQÀÉh ±?…sa´F³†‚,œ!Fg¥‘ñ¼¡ÕX= d¶g„ öä pÓ;°¿S;Ø×-Yã©H(׺;öA[߈ÀU³k;÷”§ SÕ36­¹ðÛ´LÇdõ  Ð ïöaà<áÇW"’k¾’fD‚•à ‘Ò„Œ sªD[£h릦"w³˜k‡2Ïõ…[êû Ä®žõÛy3\Umûqê®Nó"„æÌ/´†hW¤»"ÑúY§¥Ïjì­ŒPë‡>ÑÔ2mîm sCÇSŠ!üFY·¤AÔîû6š¼a%D±ð¢dÍò_¥ÑröñªN°W_Æ(Æ@Ë(þ}¾±<»¾¬Óþîa1pdžJgÓÒÚŠ+49&ñQ'­ààú´“Ò7r¶¢0_k9üNƒÖ?h¥ Iiþ5ͯÆãѲë‡Qn"¢9ò~Äi M;Rc·þ@v>(–'7Áçóc¤÷.Ùh31ºlˆ aX^§ææk0l¼²ß/T΋‰îH{­/P蟈;kŸ `! ù*€´uIÉ@ÄÏWÀ– @)¯HDZ¨»‘1´ôK¦™Y_èC¦£%—ÕÉ ìPdéD™4‡Þð«‘ÁoI‰©H™pé!ž• ÂXA S•:‰ÂþÐ^·”Hñ c&Õâ$ÐÑ'Á 0FÌ Ðl{J4Ñ<±„ÒòÔÅ®ÐWÁš¿ì!ž:É‚µËó´·¨ñ `³i„×>Ùàyp¥^OÙ=4¦.§(;ÐLšÀ})pSØÙÇ( ë@ŠÜì “ðåþ}ÑUÒQgã”yû;ÝÅ©“¿Ác(ã[2©š»0313µ°C9ÚD>ò†¾[–J´é#ƒ«WëérÈúÏ šìL9nl´ž>ÞñMî(5°[+ôëç(,¶šC‚ÿ¬E–Ρé£Z¦žš6cõtÄvzÍqÅQ«R–ã'Âe]ßú|þ+Zuã_A®… $¬¸‚«E·YÓ=>Þïáyd¯o%è=4GôEç9”!B#¥jž–e74ÞÒÚ9Fçùœùa"Uè”xX.ˆˆ?Tßµ®)/®a:Uã'õ'"‚9[¡«Ó®ÓÁ)"áô½*PjnÞÕRK,‡ƒ¾2^ ë=ÆK`·qžY?Ýç;h V£o¡Þ¢‡ÝáØNUNíƒYÙ§ÍP‘QÐý–ç¶5ϰÞ5£þºð0)6v˜éI™v;$ß‚™;™Þ×x°f\›’”óJÛZ/@ÞôkŒ{“•Ö?†”>Þä€Ê÷sëñ‹ÔB¼‰&ArcÇ@ÙwCËÔQp”ØÀý!P>µ«òÐ/LëÛi,›‚·º=ê@ßÕú´¸’wS†‹Rš£Ù¿÷ØSX 0ª•~Sxï?´(™y»àë‘RÊé•9rìŠc£ÐÐb5'äž¡ZÚ.¦+:NOïyŇK4˜êbäârõEǰh8òúÍ2ÎgÖ8ql¤ƒU’èF\„X¨ö<ÿÀÄuÁ:Ö8Ì ÜE®_ç}ã_‰ kUôÓEâE(w=¨ï=àÛWÛw{<)b~œø™ìÞ•~EAl¿~êFK ·ŽÍà 5Qó.´À´àë‘`dFΰÌ5a8¥c¥x¦Ç5JZš£g·4iñ„õ EàC${1ׂc·`N¹Fm˸ )Ù““AŸ%œ.ÜÅF³/ÀÎìÔuö›rbl‘D« 6L \$MДKã—8ˆx]-ø@5ÑÈ–ä"ý:ƒø:S=hÕƒ¯dúŠVýmB&”·¬Xzø% Îü`²~›ŸD?@€šE¾ˆ‚híøVGÆš‹­8m„jjBÔ´egìLmfÎÒr®Ç”XºáцRWàÞ袲à¿ù¶¾7[ ¾7«G=ðg@¿ÍR{¤D«Û'G"ÜÀrz¾ @XË.Ê\T‚Æ\8ÔçÏŒaAFáHÊ èRh6ƒù®ÜÔ›æˆÀµ…ãjM†Çè „ Û¯¹– ðMý™5@Ÿì¶¿l†N S/.í‹+„T¡ôvÒ‹…—øøêºûmsdžïÒ´M7«w=ÄFž‚@ƒ+èÂbtåB3ä)<âÛàí²Eô(?½Ü=áa”Ì;>O›1ZP[ÚNeZˆ;oçÎè2èx0Û5óùÇÕ'ËþçÏw½ûaÊ“xcðç•Õzk§ÿUF†J¹x^_øp8¥ùðˆå—¿L/Ìhî*`6ç½àîÏh CÜYòÙÀË!ŸËŠ/¹GÆÞl +ÏÁÆ“9€ë% ùI*Äëo,d £‰‰7 ‹–«YÉút8²ðQ(柦yRï½cUŽ_µ¾È§G¬?À-ýu³‡^^¼»ü*Bž_þýâÍó¯Ú⟯¿Ž„‹o~üüõ›ÀæÞfyqóÁþ¹»•ÙŸ…Åm‚®sc³8Ó1%,Åü˜ˆùIÆ1‡Ó« ¦"¹ýG*á'ö¡F[CRÌÙûïjqdg—.N1šÁ¹´oc¨Æ‚-€Yâô¥ 6|3m Qr\-õº£1/Þ+uæÎI–¼1Õ+¹ýÖhjrŒñ“2þB-p–´µ«ñ…;¿.‚™ùÇ\Dñšc¸ùóD> stream xÚí]ܶñý~…Þª² õAQ*Ð×=I DZ}±@§Õy…h¥¤ÍÕ(úß;ÃR+;çÆ­;÷p"‡ä|p´’ÞkOz¯þº»úúQx™È’0ñv·^¤"Õ™§ãTÄYäíöÞ ÿ»M¨ü²»)»¶ßlCú6ò÷Ǫ©ú¡Ûl•ŸUÛÐÚãsµ/¿¢ñ³².ó¾¤I ÂP›W»o¯®wW?_ÀƒôO‡@.Zj¯8^½x%½=À¿õ¤ˆ²Ô»3»Ž^œ¤ð¬½çW?\É)ÿQ:áqRÈHëßÜn¶‘Lü¦Å§ò‡.oúš¹Å…²ABé¿¡y~:ÕUÙÓdàS9M >È=4ù±$ȹ/÷4ºÝÄÒo»Ùþ¾$Ô¿Tï? jŠê”×ïsr¨Š ~Âå@›»òçM ýsIlÎ#X|¤®nº|&Ü]UרPÞ6D¦ii®’Zû¯ÙÖ Áºòv¡3À`ÀÊ`8Ú Æ®µÒæCiOçõ‘¥îÚãâLŠo˜œÙù§M¬üžv}÷·‡‚–Ȥx.çÍû¶ä]MË þ\e¹7* FÖ‚›HúSìÄØŠf*vø¢mzpëÍjmFø û¶¡€ 3™PÁMûö˜W%§–ThãF# <ðËD¿‘K™œöϧSÙQ_©òÏM]öýÈHðõ£$š4D–‰#N‡þ‚²þ8to~$~z:5 £4aÙS}9 UóšÈ€¨§mI‘Ñ\]/Àçöà"À{~®‡þŠ!ý"‡@éiœÓc_½”Q E‹#à”c§(Ñái4 O 9a’ˆp+EC®H¯ƒ´p|öx™äÀÆQ ‚4f¦‹ü”`Ö`åܲМ µHmJüÆ-†¸Ý[Álû'Ž]×0>ÒÒ¾êÊeÔÊ)•lÚf{¨JˆÒæPy ð€vnû-Ç ò3ظL`ò—q‰nšŒ_Ÿ;—ƒcvÛØo ȇFþöåÀBþ.yÜ­¶]MºÖ\ 1k™á=·,yꡆ ‡H‹,b½=@2Ò…:ŽMRÚ†I†¦%Ðp $¸^a¥bW€}(o³·[ùÌ\9C&éÈœGXª¦àô ( RØíNÛÛA—£9`ApÌPYèïÞ¶eE³,½JYz¥­ô¥Wœ`yL Åí^<ðá 5À"«hìiß jc~8e³ c©l¶ƒÜ³¤D©@éñœ©ªe+˜¢}Êš ½M‰@” ±_õµY¥[õ"Ppg2zj<Ÿ9=†ü5²iUM!ã‘4;å6õb¦Ì†ð±þ¤dxS="r‹K4L*õ9óПoÈ“ Ùâd{Ë,ÄÒOF ж ÔŽ¶f°sk}.×TG>êüwÂBm-Ëž7.”{*Ò¸ì|>óï #1߸rÌ­KÀÚB‹¥«sI,[8(ˆ©˜lÊð‚ÞͪÄ]y*sr¼ÒÞ-=òêéyl-ÉÓ¨mì¦MØp1 b> Ш~ÂÀ_ÊP 4 &XBLXŠxSaÚ<¸ÃÝí„ïí¹e”"€TÒ%"´5¤FÈ›M¢|ŒÖˆr×T? é§áê¹&¡ËÔ4î홂v,¶y]·È(åÎý¼"/=`ª!1ð}ìnÃ/b­ÉrîâmnÛ¸8õ6œRfŒ™€¸jc“Ûb›ŽàJ .v–»0‹Ž÷µsB§®ìšä~°$ ÍQæ:g˜ pi,û¥*ƒº…Ò¾f x;7iªð$ &ý©ÏF'åKFÂ*Ų—W«ÁÒ!$Êj@'|9H¦ÑÉ7‚¡51Jj¸Ä="bvs>fô±d̃Žuçë×¾@ݳ£V|K´¥siÞ¯ì2U=wå$­Ò˜ª’)\ŠeÃcÕ­al©ÒcTùÿÄ«u~<Õ@Ÿ®áÓë£Rp/uêOþ.ÿ•‹w”ˆ$pûV1‰0K솧ïFŽˆ £œ$¡+O´¶[Ÿ\?{þð-HãL¤Ú5ä‹€ö®êQÓ)@è.““¦dÖ¥'BfNÊëçâÉõnM†.éŽ1ë-(GOØM%ƒùZvƒe›¿ã0E•S߉ˆu6BSÂ÷jt•…‹jvÑ¥$ZH­,‹»ëç;ñvã&J¨À©oV\µ‹ÊËäÌpI<QtÞ×r¡SåÍ™SöË—x¡9 “ðž>æÌ(åÎvÂc[Åyƒî²dÔ[ çÑn3ÅŠ ±Rß#z2ÈØµ­\6±/m•£ºë ]ݶ?ñ¨âzËy¡êÿìºLgÞòɽæÚtœ×;÷z+I–‚4cá.ïg¶fÈt,i×bZ½ˆ^zéH(¥ ¸†`<(†¢…@D1d¥yÅd‚1uæüD¬‡3„h£#ÑVÚqV[ª#HNpÊ Õfö?¤‘°øbä¼õ~ðÀ—2…¯ðñØ9½çÄÿÙ{»G(4H²Úbƒˆ¡Ñ›â§7 ½ÙHÀ·s¨ ¢oÄÂO(ጵ4ÓÑŸ5й¯Jþ›ð²/i–O«Òm’A~'ð/‚ÀèÕ¼,N/‹c‰4Õ+/‚<¸Ñga0OQ\E€ë­bÿfgàѤÄé%pÚºçù­‚üõ—ü×Èa8çKÐobñ£‹øÄWë§Ÿˆ±®Ÿÿ&6øn´¼›jÿË÷a°~ 7Ü®Åå¿×düýë¯æ£ßq:™Û1y‡Ÿþa†ÿo®¸ˆ}:iò 5λâæcçø/'{MCdÑ4oíE7ŒE&µû……ái¯¦¿Ç­½D»ü-€©'?ÞòÙfíMT E©{¾ÐPÉ'Úêë WïÝËñ÷-®i•³šT­1Œf@%â(‰’±­…%Ú6vµ„íš›¸žÍAäˆNŽä ÃWý‰s÷ëmõ{›AÍZj;ʑԕ,¨m–ïˆ%µ³±¤Ñ…¤Ñ(©%Ö$ýŸvË£ã®6ËA ÍrÞ·Yþ£ô~ìê³é/>°z’ÏL=ˆOµ­ùP×Äé—]Zdr¿ù•)R¥ :T H˜Ftü: n3CÕœí‡kö>ÓÐÏ}î³5úLÒ|¶5»¹ñsù©«ŠE˜ÜûK×Ë/tñ¥%¾Óä4 C±Ù&qæ?v7Ê7¿“¢1c•˜|ÇW¤ ›±lýöù*` endstream endobj 1536 0 obj << /Length 1861 /Filter /FlateDecode >> stream xÚíZKoÛF¾ëWðV °·û —d\WqÒ&ÎÃjZÀñ–VŠtD)nPô¿wfgI‘´ì(µm|0ÉÙÇÌ|3»œo)î]xÜ;ü4|ÿ$^Â-µ7žy‘ô¢ fA¢¼ñÔ;õÊÐ7Ës³,«á¾Œbÿ`(BºÈЬZ-‡û¡Ÿ®²² ¶£u65{tÿÆä&­ =&%óñ/ƒÑxð~ @=÷© XÄ#o²œžqo ò_<ÎT{W¶× t ×Ü;¼pg:o» b/bI娄é$‚3-#òãù¤,VY±6S°)äþlY.èîriÐÍY¹®œ$½°ŽÃ0²ºQË„ ƒÄë_—ÞMMoŽÐçÚc3-”" :í½÷ k‚8õê=Nž""ÅÂ0´âžB&…@h‚H»ÁT dK ¼I»9Ö,€±¼u§è™º ·'_MïÌ{íÖIˆ°ãå¨Rƒþ.|’E`Žtn,7¤õ#t-µ€ühšc]{±«ÿ&_êl«}Þ× ã®˜6al·‰ c³v…P,”§€]iJüÑ å/ ˜úŸUß‘€VèÍ:É‚ãÑø3ƃ}¡ÿcoÁì<°§|_B ¥ôö…€ É¿±´w„ÇÏïääÑË·wsÒ ÿ²Æm3ûxôæäðQØx?ùÐ Ž¾%8¯¾çëç¶•óµw‡›c£Ml¾Ä6Œïäå·-pwï «~ ÿGÛˆ­¸7…u„òD,á®âþ}nˆÀOñúÕú|eµeÉÖ•­ÆA²(—†îVó´ Ö²˜8ÙU¶šgÝé`.dRø“<3ÅÊÍx•å9õ[WÍ„ÆÍ·œš%Éʉ>`™ŸækS¹¾%]§fe»r˜Žîæ €¬æl¸¯@÷¸;÷–´°š€Rt4Ásæ®E¹r‚Åe‰*ѵÂɬ9p­œ1† éXåb£†PJ­° Ö¢.+»Bså‰J°ØEê4½¼œšYºÎWÕY'zq†a2bqÍ Gé¹àM´ñÀˆmá¸qó[ÿI‡Wfâ˜# *ÒÚøÂ˜'o1O¼ ©/L—g“šv†ˆ½é&Є¹™2jE=27•Ë;h;*ît• s‹ò-Ám™rZaN(år¢rz¬3aU·;È8dÛ;®‚¢N¦C 5œ›yŠU]ºÎ³aÀ¼ñ”·-cå@’• Þô°f0­þ ¶¸ÌÍMvÝÕ•":y® %ðgÇo¤Š¡Ž’Íœ˜ uÜ(ÝÈožò†ì5"Þš“·´N¾·~ä~>Z. ‡xý,™Qofç[šðÉ¡ÔÁÇ¢áÆZ`v…ä.Gýëµ£\v‰ÒÛ "#†}L&7¼¼ú•Þ.ÆW&/ÌêëăñÓÑñÁ ˜ÏîVL~þí¾½¢À¾Ä½h™¥9T:›‚Mlã»S‘‡ ²¾ÿW˵ÙZxYò~u|Æ¡Ô2åÃaÜÏã[AÖã[ÉÓ;®©@z^bíDu91*ÈÖŽh\ÙŽŠL¸s,…èGàW—f’Í>fÅEª´KÇ]I*ëêMXº1ÕÜÚråä5_f‚õp—ù Ù,MZ9Õ!~™˜©Êå¨Í³¢¶©fk½2qo[Úg8=”–nÁ×UÝ #³. R ÷dcâüÆ.&Ít;úãàÅ«ç#vˆ _¾Øs#Üœàì:ŸZ¡Þñ²S3»VW27!JšíÇH‹)ÝÔÉDó[㥣`xuÖ<ÊJ`ãÔôõˆ¨o[ª"­  .ðÈe 8€wËtA­ æNÐ…ð°YÙ;ëG"†…Xk³a°a0·è{Y UŽFBHÝ Vn—†1îoÓ 0þÓ©%j'W]Zg#­x[³âV†î²]»_«Pø9ìEx”ƒOÒî…(µÛ0Rðô<7®ÉšSQ{ññÁ4ÇدsÍ ·ÙÛÖsÓž`; >f5]GI{èúÝ0°ï ì´HÝÌõGé ªUT;ÕµaË–Ü>{qÇIµ¿õ·pˆ¯Ë¡´¾i½×èTŠ`ΦSSôÒÍ<”u^›¼^@¸©Ñ‹ZrËú:± Öô®î í±•Ö­D€dqÔdÂÒî½u>Þth%¦tkgš4G"͈þO€I½ó/¶þˆ"LI:%‡0 )bÿpž^1û¨QìK &,¬Ã²@Ì.ÖýßT<ÉrSõÍýèŠ¢Í endstream endobj 1545 0 obj << /Length 1966 /Filter /FlateDecode >> stream xÚµYKsœF¾ëWp TiÇ /çä¤l—*WÅÙœd—Ф%fa ¬ýûtOÏ ‹T’R¾,Ã<úñõcºYîÜ:ÜyñÛöâÕ;á;Ëâ v¶7Nè§,M2')YèlKçÊýà "·êwUß Þ&HR÷çGny¨Ûz{o¹ùXw-­½?ÕeuIãÏUSåCE/> æ{_·/Þn/¾_ø w|' €` Oœâpqõ•;%Ìt8 ³Ô¹“»ŽˆSx6Î_^p%?g>ˆÍY‡¸;öÎ&?¯iŠ\}Îx˜’WÇæt[·ÃW) á ž¯ÞʼnuØ™SÔb©FéKàóùYðEHüŠ4&é–“Ÿ%õØ¢ÐÇdwß=Ÿ»§¼™õø[v ÷#}¦nÇ Ìp÷M—ÕâìL™@A„³ñ–…ÁOÕæ›·eòò]ï»îÛc*E!ËDðB•†ßW*ý\ͱ÷BîVùiDKíS  Au4oKÚüRAÀÓ$1à–ÅsD‰a˜=Œï€‡Á c˜Ï Üz ì¹ÅlàÇpŸ‰;î+š˜bIÎU¡Ò¬¹ì*Z= UI3cG3}u[˜aH$X)ïÛüPôBÄië¡+OM¥ä@8g„Æ©¤8Z›WËcu_x2oûɃSÝH;+ä‡b”äî%2 ñYE ü~ÁjÄ¥|·H ß5M­x¯œÝv0°±ƒW…ݯ‹]];ÌG•=ó¾ÒÅéPë’Þ÷U_1#»eÎOv…žs§å¥goò7¼€²«§ßæžß?[û¢ÃÙ¸ Ç®-µBZ Ài7ùj~³À M†î›¦YôÄñ¨8 ‡ü F#xóëeJ ­páóüXÖƒTð‘ ËàN›yÉv_£TqŒ q¹‡¿§Ù½|!gS˧f¬JXÿ!lNÕ€j§ÜýpCÛF4.í!ûÇ‘µ™n<øõú€%‰¼®%.­!G‹wÒ}P>0WK¼az§v*DÊ9/;RbÂÀ ÿ$Waec0¶LSµHïºkOë“LÏL$e"L&‚—…‰py2¼ÍMd"‘Á0ïÏ6Óûd"yÀ’M$Rm" ¬ÁÃ÷†8 ´Á„áE F;µ“p*×’Ù$†-?É^$æ ÍägÊL Âd&˜]˜ f,3ÁÛÜLAh§1{™Hk^9=èv"ÅëV±—™ åÙ+Š êhÌÔJ„B_Á„Úïõ1÷8 C3,² *så£W€ wûÚÌŠ\],Jy‘‡‰ÏbYY†öàŠè.Iæv» oR­ÞtE>ê¸`Hx»ôÈ&ßT©9-|»ÖèîTc`ß÷†ç ž´e*`N9Œ“»Ÿ‹ç§À2=‡vE8(4ãÔÔΓÑmJà?w}…gÄ8à8Ãs-6â’À¹´DqòT ¡ÄŸ6K‡LAY¥¤©+Ë*˜ÈwCלƊfÑ‘ÐG²Ô­GÚ ,Jüafì+el¤£ÃÕM‰X‘fKG-BŠÔÉ!äí|½ƒêẬû}À±åSûíx^7}wø¥ñ&„H‰‚`nŸ«¦Þ•ÙÒÁ¢Û["ž±$5>DµÏ&,΢yôN–‹h÷,:Ë’Y¼Z\˽wêJȢɩa×—•¢vÈG8;€ Cngô,:› ¯åqO«ùŠÂ fA4ŠË€%£Ì¤%J¯@±Õ©,oÌÍ,‹î T€Zô$‘’êHŠ•˜³Tˆ¹-dp…<Óê†\^o*‡ã‚¼&q0Wõ’6EjÓtè£w²ï)iûÎÐ'?Õ͸Á‚W €øB“éŠ Ùº 鬤–œ*ÍÊ'õæL¨‡³ ˜°ÀxûJ‰²°ÁF˜#F-—]ãc÷tiîévÙ&(G²êæqß VÍ«Q‡©Åߢ«­a«iÌ G÷çZán”,NºQhGãz‹Ê^79uû¤¦JÕûOþˆ´ø‚ê…>ôßê3@1@³¤ïOˆxÏô‹7ç_+f¶æóI„$Z‹$¤ÄY#„«];ö]£Òõ”R»ð€sD àVKƒá9Uç(&ÄBQM'øRº{—€XŽNàÕh~PGó²¬'ñôm÷Rø@Ë|–À°g5½ñ­áraÍügŠtë,½T¸ó_ÅŒ¦¾ðˆSïÙ•#ÒÑíóÔÐ(¿ZÈ¡{@L@ÒR© ý-ª¥eÆûç¶‘›ïªKf-¥^(¦"}!8$Ï/žˆ\EhߌZ=Ø·Óß:fM¹qȉuÑÔÀXuº$.êãÙËG:HõO•7‡—ã1µö*ø~ÔúsC/)ÏÔ¹…ò_©@ÊǾÓzä£Î@V  by2ç7…ųՆŒ<ê¢ï9ZËÆ’ % :ÃÌ rN–Žð¶26X¤ÉKÄú‹ÔãTõÉ–>Ÿà掞PJ@ñy(Ìڀ«tb=èò¯ƒHÈú‰ÿ¬þ•µï«f†Öb‘¹¿w”ÃÛ‘¾„Š(fY`>HþR¬ÿŸ7s, endstream endobj 1551 0 obj << /Length 1592 /Filter /FlateDecode >> stream xÚ½ɲÓFðî¯Ð-v3’¬%7y„¼ •€o„¢æIã牵!É8æëÓ==#K¶ÏlKÝÓê}3çÞaÎóÙ/ëÙ㛀;‰›„^è¬7Nä9Q»Aâ;ëÌy3¿]x«¹lîdSµ‹¥Åó' ¾šg…*UÛ5‹åj.:U•tö|¯2ùˆÞ_É\ŠVÀ]Ïsùâíú÷Ù¯ëÙûñÌá$.p#9i1{ó–9àw˜ë'±sÐT…„1‹æiUvM•·tZTÙ>—Ø,6¯:bÍkѶ‡…¿‚“ŒŽ¬Õ Š[­1n 9Ãð°U)ÆmkèZb¹o¥aÕUôlä? $½ƒ06—bw)¾E‡ åœ»ÉjE–¶Ó`ÅÎH5J4’^H QÞëÄÊ\`îûä5<&Óó¼ÂÏ È4ún¯òn© ÿÞYH¤ü,¾ÝIC@·U†òÒ;?ŸÒfX¹‰o›)ðË'òÀ ÜÒxä’§[™.@ÞÎzá!¡Ê¡¶µ½‘"/è…A¦R÷HÈ¿™äòS*/{%Pq” «1W OjAH¿Òaœ°î.êî8ækÕÚÊVUÙµú<È£Ö ù) ol«‚¢¯,¢¤ço¤–qøŠUeŽ.0&« =oQê©-æ Sª¤«Á«n{ɹÝ×5%è¼)üjïÕ*Óïâ¼´*ꪔ¥ xµ9KÓšœ òU­;&àJQ˜Ä|p[>ëɽ•>wcÓ—w"+Vï¶UµûF}ÙKâ1Ó$šè DW7º}€‰ÖL¾¿G_iÀÄU3˜Ì1 ±Ï .…jGJlÐ,Á–¦°¾ÓÉÙYÇ×_ºçd¥É± 02ë[¬îƒA2m1F^”Dp'û:2¼p<àÉÁXÒ aRB{†H4)¦ø±$m›ªT ý/ÖD5Q@}¡ˆ²‚dkˆ0¸£=B×cšpÒOplAûü€ž3ß=S ´°Ê¶Óh57^y‰zTC+ÎÖ –mxð|q¿®&ØD5ˆ½vÓ7©†Ø3¸_QÀþ§pKÉö©ÎÀiÄ +»Þ’»<ÔmLC§Í¡Ó°àä9º¡ÊÈDULœÔGqÒerµñ>Xm&r!“ö+ •}\TL~…Î`À¥¹‚–G¨‹r…sc$·«‰Þ2:Ô)öú‘¢è-TäÂh˜˜„þäßv pèV8ï@~ø.‘Hók"Ó„VÜèß/>™AcNPÍx,ÆÂˆø âjæ©k& RæFqúPÍ,–ÐG1ÇÝÏh ·ÚšïhÕzD:™ŽÊǹ)Æ}m;­Úúê#|"s™¦ÐÛû5—z'·³–ÏI˜]vyߌ›À¹~U޽LÚ»_*L@[™o¾0¢Ü?E”ûžâf¿lMÂ}P©¡9c¥§ùÞøÀ³!|Ά F Új˜nˆ¶”èî!ˆdUÐûN <<"â¡pht$b9*%³DiÅü 63x1½Xý´€aÏ»ˆDè)]Þà\ßïàIEk‰ oÑYÌݾÓ&ú‘G‰ˆÇ#-/ª«\¥GzŠOV©40Ü)[&ZÈØ÷Ûo{i^ëÿäiÄQåÁË.K//æ_{õ5s-Õ0E\ /Zâàà²U¶æ‹¾®ig3«.õè6<{¥Õ€FÏHüí³§–\+*5ù­YKSË©X•ª-Úqµ–v1›pÏ5£¤Þ©Ru_:MØhš¨¢ÎeqºÀô—?o_¼Ôû§¾Ä\¸Uó±nE^ß@e™6GºiËìa•ç²¼§nó}íCé´àÖ]ÜÇ:ôûðÍ"bó'¯Q«µ ¬îÈ}­é*dÛÑð5?üxÛµ:wEQ6¾çÿK®è`þ[ròOÆÀs97vÏÃÂõx ·pQ/° Ló‚VæA­†pÙyZ•8»ï÷ç¬Þ¨ü¬½ºÿ€#ž+ endstream endobj 1555 0 obj << /Length 1979 /Filter /FlateDecode >> stream xÚÍYK“Ü4¾ï¯ð Oc$K–mn*¶ ™œBjÊëÑfÌzìÁl–_OK-ù5Ú×'K­W¿ÔýµL¼Oñ~¾øasñÝ+N½4HE(¼ÍµÇh$qêÅ< xʼÍÎûà¿Y…‘/›+ÙÔíjƉÿbE#w(ª¢íšÕ:ò³®¨+û¹/vò[l¿•¥ÌZ‰„a@W7¿\¼Ü\ü}AâQ/á8Ä$öòÃŇÄÛý,M¼[=ëàq‘À·ôÞ]üqA ÿ$ À6 BÁÔlA½Nˆo]’ªS) ‹QÈ}mD‘Yy@†‹ª[)Á¡Güë,—šw{øw¯X2Ùx°&H¬Î6{-u¨öUÊê»oè·2·ê ý?IDà ¦Þõ¹Ü!­0cͨ¾ÔGC˜L±—׫5õÕº²EÊv(¥é\¯8ñë;Ý’—uW¯'üÀñVHeiT›/öo÷E®ìU—ùÙŸ„1ཷ…(É) Ò(BÉË:ÏJ˜!˜ÈŽÇ¢ú„ú¿–‰*;hnÔÕê«äEž€4ͪ™¦å€2U¹œo½“(@_vHЫ5‹©±Q7eY¯Xäßü]õEÙ­µêëƒ6¡#ÕÌ/ò=ݤq) Ûj]DŠý~áBà£3¢q2ãBÇFWƒÒyù ë…€$üüVäP3Õ×&¼¼ÿýïs/.mœêÐßÇ ðP€%9¸(žñŒ9µƒ°·ÛþX92o,@œ¡:xü¹ç!lö„·?¦ª‘8rzž¼éÏ| 'oB¡ iác¼ê`p‚†38A_y ÑãTŸ5TK?kè¥è„ØÉÌ÷å—NV;N¡‡² $wHxßfŸôï!³ª3*,®z{²zt6·\¿Ê(Úm¡#x(žöÄ;ªn‹$ñMKù‘m“ Ó˜õL›.ÿQE²á“Q98q(¨ÉjÐTm<õ¬19Væý‚Gà¬ã;gÈ–lý ¢›.´ endstream endobj 1559 0 obj << /Length 2697 /Filter /FlateDecode >> stream xÚíioÛÊñ»~(UD›=yè7uR¿$/yŽHƒ€¢(‹ Eú‰T·èïìî,/Q>âä5E“¦öš{fw–zõžýéüèñ3ɼ˜Ä¼ó•r/”‘±ðΗÞ;ÿÅŒ+?Û.²mUÏæ<ŒüãSþr“—yÝlgså'M^•vìù._fìﳬȒ:³ F8'löþü§£“ó£_lO=f·“$¤¡—nŽÞ½§Þúò(qä]™YO| ïíÑ/GQ§}1"QBEhIX.6I“j¬×·òñ3õ–qIb@cΉ•²KÏ×¹¡šú›j¹+2û;Ù5ë HçÔÏÿ™™ Ì70¸Íþ‘¥ ®jÖ¸$Íô°ò›üïTÈ4i¨4­¶Ë¼¼Àù•vµÎ`)BÌDÁQ‘õ A#ò…ˆ 4ƒ —ARÍ@ ù0àÈüˆ…nU­§5H#`ó½¹ä  Y”4nÚbg¨RÔ7ê ùð#-ò¬lìïK5Í/“â‘íÌWnE‚Ó¦àaY ðˆ'a@%¸øå[ï^çÙó±ªÏÄ#êÊ›§?Ÿž[­.gZ`UYÔ†¥Ô{˜ÿw¬Ñ€ía«‘FË[4zR“’X»ŸµTª>eO&dÈcÂ#îdxn¸Ï5“ “¢¨fBùWVÙ ;Ùâ8*^_f©UQ= Èl.8Ók\óIû…¤Ø]„‰›d&¨m8©…–-mG^Úï»"_,³•±+šú=bTÛïEQ-’ÂþîOÓÊÂ…65£Hî@¯òfmvᱟÀGh‹LŠÍ2¬w‹ Õº.˜U­lÿjzS!­}ÃxG(| ¡Ø€P0”ÀÀÄÞ0:`ÌÊk/ ³Î°ºO£î ܽÇÖ"&öQ½}Ð,µü?é?èÐÀ–YfXVÎú–K´µ¦Â±Ä~.L@(3\‹;M º;„KÁ\Š©‡³d‹É"¸]ZÌ´©?A«»ÍÚT€ÊûZÛÀꆞP©„§I 632ðÞ»¹¢‡¸>Ð,…š5Å£'­ÿR2öÆ_ôbSC– ޱ ŠÅ DTh>x¿z07ÖIj§šéÆ–5ì•ÒÌÒ ’ \&c¡nIÅp„×¼×!¼´×‚a ÿÌú¶Sƒ0îTçu{¶])Àl…Û±í¡<Úí—BCÀlêæã‡ÚÒÿ WÞ/(P¬´^êÏóV+tãßûªDHB@>¶ “1‘@]lFq¤e˜ë° s-ÅÕØä$P`ƒ,%{Û@Ãr§ÏÍ\¦rWV|‰-]‚û:VÎÁÂby6±8TšŸ6X÷ÝF˜lBI#À&.Q»oH¡bΆ>üäoǯ޼'›Ë"{ðÒjó°õÛ3¢¾ÜPÿ}Ó¡â1 Ñ6ÆüÁn”bäãÌ¿—ɨ6“ùºO²˜PȾïGàû&O›˜ŒØOÌ„6øœÙŠy¯ÏÿrrvvrüòÕƒ<ßë³ç?ÂÞ#ìUú~ÊùAò«¶ß ò©{G>¼þ“‘oúÈ{kä;p$þ!P€íi§û›‡@NïA÷DÛ¥]`ÛhaÛC;x´Ûï7 ß-…ßkäá òhím#(r§Ï͆ȅ@€÷=„@mbQÞE¾Š‡÷9û}ƒðòçÓ³ÿõèr¡½mž~h¶»ºÉ–Ò¤þrx_^ ŠD\Ë>"‘”V`oõhu%›hP1È—YÙäÍ5¶Ê•¾ª¯¶[!»!QC!¨—èßÜë`q]6ÉgûÛÞâo{« h¿Ù- ˜^Ì Jeî–ZÑ­@ùx™‹µ•­ó¸Þrén“uÔ27ÅUšt7™š"‡„©Gµ#äZ–ôJ6IÝŸèjz›ö¢×qfPÑ×ݺ‚œiS§ÇÏ"Ú¯|DµÅ+}<-²2ÙL–Ç”1QœúîÑ0:ÝŒÙõðÀ­q0fœýþÆ”#æ„A‚?UbÔ÷Ä—?׎_iU6™æÕçfïì½ÈÖ¦ñ)ÎC»+ô8vZN P.G%ÂVMö K"aÔ²ÄÖ_öA²XLƒÌ³z (p޶uJD Á˜8$Õ,@DhìÊ1š‹ä, ¾YnºÌ­|`ËÐ|sòj>Rn;n·µ“´0 ÌX]쮆äVý~&A¡mFÊbaA<”ö~ؔքºš¢_ª4qÀ­‰¼å§Ñ*ΰ¤Ãi¿Feêh¡+7í¡oÖ¹2­Msœùqà[`šÛÆê(lјÇZ6Œ,pi^NPh&ƒ»ÉX[úÜøJ#“òñ5ÖÍ©•×Ù”RA$eUæÌUL˜ÛOöQ¯zÕžv¨U ´æVú“&¸­†ÜÚ÷Q¹ƒ•C¾Áâ‘IB¦a*n˜mŒmühp›Óh ô²ªŠ)¦E$ì|í”0àì±»Z8—{Hêz·É–®Téüâ­ÒIÐϾ¾ÌÊ·o_›œÛ`x­ùÝ ,™/vå²È’ܰ@ŒÂD˜|\N6[p [f.ó­#þP3+¾‡BIÀø½ˆÛ N ÿºD’P=öÎæ áÃîE‰!„ÙÇ`|‰k;¤ßØ_V?p…Þg‰Hõ7b`À4lÑúÁKŒñcŽˆˆy›M€ àwÀ‹Ý é d†ž„Eú6Ô'´eˆÙZ›ÐÒ¿L0xÙqkKj¸ÀZŠlMN¡©ö¦Õ8$ûY£êž7¡wT°_¾­íL·×ä;*èÇÔUM:R9 [-ªæ]‹ ý¿®³áŒ)QVº//ðu ªƒP‰¹käçCÖ婇/gjàé„KœÁá{”Än4âšèÅ›JôJLêÜfY‡Th§Îû ô¾¢M’ú/ZÄd€bx¨s!ËÚ ïöBv<ä~½ë?éÇØ|pÒ@†Ùh°÷,mR›†wy %aôR”‡tHµl åZ—(†æïN^W„÷è”ßæw•Œ¾^@ïC·;\A:Åâ Ó)ÝÐ:Åbe"º,í÷¦°­Ç!ú­- å?ÕwlûÇÞ[÷Yh~fI÷> stream xÚÍZßoÅ÷_±ÀÃÞþ˜ÙAR@Bm¿Ò¢>˜Ô´%®W‚ÿžÏìùBìØõʤ<$ž»›ÝýÌìüÚ¹‹ÄÕ‰ÅQ´ßè$á·K©ÁeV#¢ã`,%¹Bو⪋0†ñ+NJšÅ˜œ0Äâ”ȳS5n­v ÿR£ªqd1 ,\Û½âbÅpP¸¶±,ª4¥.Ålà$e5ü]¢Øî%—˜mR).¶šq+AªZ’ì’´À4ÙúR] HÄå”m^-.çÒž*ab‘B%%N.WFÊ.kj#¨bŠRè4TŒà ÝÚîUG)b ÉQŽÁž’#‚ò¢é—ˆ m4bªFal3(<±ù (‡Ò¨ì8Q£È1¥F‰c.a!~£ÝbPd“#WSc{Y¸M¬ LQœŠÃU•hÛ˜¥$Û¨¼äØn1(VH%2ÉØžrÁÐŒ9J,)(n1 6ÁrvEL¡ ÖLµ[JŒ vS£T[AöÎ`fuÕ¶O1¢$›F[k±ÅÀRµ KÅIhà Ռ–iæˆg›^9Àj%c{JMÃІp¯&MÕÅlóc )¶­ð é÷òHmÜЧ` £À¯¶6D­PQ5o°µaÔú¥áAM`¸Æ&æ‡b üin²a5Í¥=Äœl>…íƒ+) ÏÎÎfÝ·îž›àÈÏ\÷ÿ_~uX³z%v—Þ½{9ûê«ÃŒ¥ú¡¶Ÿ./×îìÌuO-*$¥~ÈS“Ì6£¿BÀU®Ú³²¹2Îux–làÆ›YÌO¹çÄ‚ÝÏ«åÅóÅÚ»îçoŸºîÅ⯵»Æòâï÷ <˜¿^̺o€kq¹¾²Òf›uÏWË«‹ÅUhÚ½Ÿ¯Þο^þåÎn”h¦‘^b¡ù £Í0RÏøäòr‰ÙÎû@gxZ Û½œ;@ÚY÷üÃoëvýãÛË?fÝ×ËիŪ-^vßw?tßœÇva/ ñFæ &Çö9™_fŸ©‚ïIÓøs×}·|±tجϮ>üv…Áo——>ùèã禮IÐ y3nx·7‹R|†qÂÉ<åQhÒ„hjôˆ´ˆzÞ¼.Eöf󜪇Óo‚if^膙#Jpõðä=þ°ÅK·eB”÷ùå8#g_óŽ2¼%ã‰ÝÐ’DF¿—«ÉW“û¸ZÝxX¥à(qÍ#¡BO•ÁSeZO ÕWÔ<( ¼`yÄÛf|-î¬XUˆ’G­ßˆÞ  Å—Xö¢y?_Í_¯æïß|á=¤²âPá®°;ƒ†Ôx ?”¼™ª@o…A«á¸VÊ@aDR”h)lŒ4h•k¥>ÂÆ ¸[EÁiȪòQ$òH2LÊ2ÕVd2¡£Ht:$H­>ÙvÀ_¬ÚÌBžì¹FXÊÃysÛ «ˆsòÅŽ‚Üß@HxzÌ5ž/àpÓ¡!Kö×Xjé·ê–CŠiIMÆ&]ÙI“(¬\?ʘ“C)ãÒävbÜIš7ãvÒ<9Möën§IM§§IR  )P‡ì(C.Ô!jœ4Fœ^­³S´8¬ TDñº?¨][FØ®Æî‰DÅã ˆ“/£|ÆA•‚Wè,ù¨<"E0Å ¼f_íÀz uìÓÊ#£b¶v‰bM¤=ÕGD‘ÝÞhÁ‰ë[ËJ‰üØq,A Ö…º†cµRà£p>Ê4e#ëóíPs°Z?=ðèžÀSïx¶D—ÓEßvGk-¸]a­o6JX¼+¬õáfŸ§6ÖÛÂF¾›°7RŠ5[º°BuC¤ÈAÉ$ûœ18(åß§’L”¨mNQ¥_¶€º¸ÜøwsïîÉÙY[¡{Òœ±{ÞýïÙö÷Ù›õúýÕ—]÷j¾ž¯Wó‹?+ÿv±þÝ/W¯»WË‹îÍúÏwÝê÷‹ZI¼]|~  Œ]p¤ÁŽQ±6H¶¾­ÏÚd¨­25fÆ)v*ÌŒh×÷šfˆP%ýÇ1“5ÁþÕ3DôIô|÷GšdÝ$T{;`•«õΑ…?ž‚á ·òŒuúG•ÌÛŒ¨„3êôÌÓFåíôtrØJqOØÒÓct S%$iï%òûh§+bOüN÷ˆß‰¦¬òs"¯¨êS ­¦EäƒÚ›¿ˆ¢6Ý­¡ÓoÔXcN;Æ,Ñ[ðþǺɻŸœ÷sº‡1ç0RG[ŒövMZ[ò¿Q™är[+™N·ìœ§µìà¥öAºBðLÚŸÚ¥Kª'Xvæ±»Æ;‚£W>iצÌt»“Ï4²“o]ç[»¶éLػٞ ¡Â¤¡Â¤I›óýñ·TʼnÏtW=!ÈQì÷Á“Þ­Íqê£x)Ñ·/¥£½çÆå¡ŽÀ6”49ʨM†Â0÷‚A>Ä1P&}M}L7À¨z6pŸ̦[’ćԾ,iï`)#”ŽHpt+ ÐÈç6ã·Š»L0ÄŠ82 ÚÄŸ¤Õɼ''’žGH¦Œö2Û^{„f)D¡]ø)$?ém²}-2nß9ŒØ÷&$NoŸÙe$ˆd_CeLBÌÓ6«N7–=I‡ï˜t¶dëƒ<Æw˜ì„ÊqÆDV$ß»;]«ºG«õZ•±Z•í²´ÄV9ÎÈ’|¨qcžk9ÎØZK2£½´Ï©®ÿ}»ç? endstream endobj 1569 0 obj << /Length 3168 /Filter /FlateDecode >> stream xÚ­ZmoÜ6þî_±@žÈ2¢(꟦Ná¤M{±sè! y—¶uÑJ[IÇ@üÍpH‰Ü¥Ý´è‹äRÃá¼<ó"Ç‹›E¼øþäÛË“§/R¾(Y™%Ùâòz!xÁм\äiÁÒR,.7‹wÑ«e"#Õ_©¾–«$/¢gK.£Í¶nëaì—+UcݵôÛ÷ûz£žÐøjT5(šp–$Œ/ß_¾<9»<ùí„ñ‚/òŽKYç‹õöäÝûx±õ—‹˜‰²XÜé]ÛEšðl'ÿ>‰]þEáð_f¬:9Y,rbÿ¼Å3Ÿ¾È„³‘sØP½e÷®2~è—<ŽÔRÄѧeGÝÇ¥€‹ÓÛÞ1²`q‘Ø·Ÿú™»ƒqÁí†M B‰µÕ6DMHJ»¹FgIT Ã~«64;z^)ócKÏŸvª½¸ø&2Z ¨•ñùo̾Ûj¸µ4ž£ŸÑ8Rë±¶’8º§µ»[Õ›×TµFZ·4ƒUxó £[[MÃzSÓ‰x¥ÅŠƒÌžã€•R:—‘eD»^óóº¥gE_c‘j–aŒBÚ‰zªÍYYdVJx±Uw½ZW«µêGÖl™2žæö¶\‰,Ž.o-Su{ÝWÄ b¿÷½aÃnRíºÛ÷ÕöÍ£†ýhøo÷ƒ»ñÖ;7É«o—×]McÒ´Ôæ(£Ïh˜øÉÆ­Ô×ôÄ£©fë®+â"&Ça-Âú¤E=û5–±}ñç³ip­½¸ßV#ìáOBÇs¿Ô†i—·>{à‡«$Õ»â ^aççWKPÔó žœ’V‹Øu—’%RX­’à­g¹Ç¸î¸â)iæ ÛõÐ)3–¤©ç”æ¾z ßÒ£îÚ3ðžJàf_ñ$(B+ldà‰§³º½98 dØ/áµ aÃؼöù±F Nu`;:ªþ„JŸ~þˆtŒÆr=®™Œ3.ùšá§ï¶Ýfߨ(‰oÞôÄAÖ"P¶Ï¢öNJc–Æ¿;ší}¬7ß„Ô/YšMN {ÇU½ PMUùd&ïߎÏÛoÂFÓnتÚUS]©&ÄoÆ„Èʈ@afáj2)ìV­5¼ÙçŒÏr0t5!Ò2™“~ˆkt1Ëã@õží¯R!Ë¥ï.Ï´sǵ¢; 'ýæ)ÙY³×{*£0èv5UÃAB$¸r´!c>ïvj­íÞF®ƒfF6<=3N´gâõU_ÍVêí®Q[ÕŽät°âx/̾‚ëCÐàyt~m®Eé¶Êó„Å< „¾<£ÒŽŠb,ÜÕ#Ö<ÚŽVEP(’¨i§%6'0Íëlq~«BNÀ²¬øc!‹‚å"u¢eʺ8ж¬’Ó¯ üÁ‚ålV ñnµ?mÔµ–×¾1©B’¥àñÇòÒ&É’¸ÀÜ/VX ¿=Z|sñ%ü:9èQJS~üé»×(ßg?ž=fó$¾™“+' òWéâÎäò¾‘9é@~ °L-»(<À Rƒ†OÔ¶•¶yjÔ.]ÉÓdÒÆœµ2Ë·æ…ý`V´ƒÀBEÓ]eƒÊzßè1RßV½¡»Æ)0Nr—^U–²œ"<sѶ[šêl—mªi,žÛŽV ø±2Û»Ölª('G#ªßÒf*sÁöa %yúEâ©KÎÅb¿€$&Kµ¬_™+øZÒ¢¡§«% ÉXÀù¦dÆê žZÛR+7úËHyHy8SÀwÛ4ô†òÃz­´ë‹èbâØò0æÛý”9j„0X5'ŸzÒØ“¨¤¨új `8hHМ}@ŠžYéH"$lmî4$ÜDçB¸>‚á(U½É, ¤QAÊ=Àm²4‹.”!3£¤WæœI™„¨ô®™jèXñ2ÛH×¢¼n ^ %áyiJ.TÄž¿>¿\qôç“÷³×ÿY–2 eî‰Ð°o¤ Ððéþ­úDzwPM|Œ¨ö™crpˆT»é‚ˆÉÅô€¢ŽÐ“ð‰ÈƒOà §î»óZ´êÄQ—!žßÖ¶ZÆ]·•9æJ)CmP†‚V)ãÄ4BOÁ|¼2Ag%îk]vg° ûö`*¾ºÛ#Gw"“Ñ ”½¶GøÕ­4wX–C"L*ŠI² êÓ_d\~øùÍO¿ü7 ˆ\¸1ó cú úÈ#1O\ºb1"˜(§Ë£LHÉŠ²ptŒQŒH=09µÔ1eé ÷Åùg§OÇíîéöþîï>ß³ÚNç\²xŽJÆŸÙ3ÌjÀ «É8%9‡‹:Éñús+Á«ÌAÓ:¹Mv´·ê&ÛÇþJ2mHzÚí–èûZ'ÿzÀŸy¡)lßÏ€`Õ’y–>–@MXàHéÂËÔ!›˜r'S‡™MDl†â å3` H°GÑwîCÐŽc”3ç9¾é¿njmoLJZFM5Ô7†ÇWß=ð0Œ˜qI­%7„™°=…€LÌÉN®=½ä@ï‚\¹Þi„Áî_½%—Í8C æ-7ãüºï¶4"„ƒHDǶÙð «0ÐqØ«¡¦iÝ‚8à4¬µ#ºC-’ö ¥±î¶Û©UÑÔ­úóaæÁý×í“óh¢D!@Æ8»²ÓÑŽm™Œ ƒñ Ϲ¼13¬¼R÷ÍæÚl«Í™¤\Ñf +Õ8ªíΜ9ù?l¨öÀ´ä],¤#,é„,t‚‡Ñ-ŒeîZ,‹då´ŒîI ÏtDìt…+ i²!ˆ…µÙÛaq@C¨tëÊtq¯)ôO“ÔÀ*Í…m:ë pë\(”¦P(³ƒB¡tµ?[,@ªØ‘ Üjr³€‚Â9¡ñSjÚà}µÆô€ 8Ûw¾ÑÙZݺ=cçkö™­Ã˜µñý®§âsNN3!‚=Ó¶XMÕu§ËÔ0ã·›½ÀÁK.öWÿÓù5N&P:†=âˆV;› „ešš½r¾dë…·ƒù šz­®´Èèë¥ÿ ÎLPµ çœNXâÿ“„6$2I•ŸöÎ%o -Õp4ß ·y÷Âç^~ÒdÈÎxèöñ’)K²/þ«ãÿ iÂ87ÖCÝX/£çÜíd¤ŽDoV&“×'ò­ÿnæ½è endstream endobj 1575 0 obj << /Length 2781 /Filter /FlateDecode >> stream xÚíksÛÆñ»~>¥`GD¸Ã«Óvª(²ãG\G’gŽO䔋ØÉ×Go~ÎÆŸ:“iâܨµ£¢¾¥sqôÓ‘`ÖÅp Q<Ø‚$^šDNì OȘöñ6ð…!o×}ûH&ƒE°å(… ¼¹…Ýuð9ÁÏýØKep‰u{‘?¯oŠê“©È¨äe¡«îd&…»íV¿))½ÎŠòeSw:7úë€D4$á'^$ý1[ý~¾m³›™5›—E;ó…ÛÑê±0ö ÁÄ ÔE¸~¤›×ëu6oõ&k²N/iÎà —©¯i´Ñï¶h,h¸p5Šè=¾BvPëiþlgåV·Þl.ýØ=)KÜÍdQÑx·Ò÷YÜõvÈЂa6náŒpÇΜ69÷}/ CÞ*" #…F®l¸]ñVH•Æ‘/)'ÈáF ;beŒz¡ÿô!Õ€käGÁ¨Æ²¸)º¬¼(nª¬Û6ú7½X·;)œUy±Yq wÝ Y /TÉx?g¿¢VdëM©[†ç¡´“osã<4uþ›5m©ôB?uÂ@x©ŠÐ¼9ï€M‘m%lÒÍ׎$‹68œd÷T(¼À÷cì©Ðçß“ D´N>ì¥^œÂŸYo•ï©0ŠÓJ0ÜŽf?”ξSöíˆØá;z9vZXxþ³·ü`‡×ÎO(P¢¾âçq¯èØRþÿ¹*{10Ÿ’ÀTê)ØavJ3½Àì ¬ï¥,jêÂEˆBp­;\*Ig($ÇËP Ÿ*ŠCîÒÔÓÛ¯ånXêÃE$¢<)‡4òRˆ.BPœÏÀ¿_%í®ÖY—³gôJßþ3ÌF€'ç P Ý¿ŒÌÑg,ü× [ôçÑ"¸xõÝÓ³ÓËÏØªû×C{‡,úã”Ûïë³Ïáô+=X®'/þd &G:»fÑhäýj< Øz2ꃮ¿½>ùñåó³Ïæer#Á¢&JZ¬ÞTž§ÿ‘ütC4$Òq8ôû]Ýo9ƒo¾ŠŠ={u¸Š “cNúdà@†ž\\¼:;ÿ¿)yˆ¨`¥~o¥ýÏW¥/äçc¹…æ2±}Çg£o·W9¦g+c£7Ê9,ª¡mº\™¼4ŠÝzÃ5‘(rÛÎMª¦yòn•uÔ:ûµÓÕÒ$¢8Îß`z˜¿A·ÏßœBöý)5îg†É)&щݮæïŠçé$ip¤"ƺ겢2WbªÔoE(^ Ë5Ò‘>r„“°¼¸¶#š 8²GXeíhId‹0föb»ø‡Î»“²ãl»øe&A6/ŒTÖ¼HWymŠ«&(C–°-fáÔåã jT€âx´M>T¼0 åÞÓ3J'®Üª6"“n¥sݶ±ùž&Û¢Ê55Y踰ÝöXNq'Ô6’0G¢¢ÓC–$ÁIS.«ÚW €³òaŸq:ÊôGÕè7:¯oæû$Pÿ4ÄCq¿qÛ,B´äšºH°ä©¬¹_VÞF1)mpºqÀ’¿ÿÆaí…¿\{ñÝ¥¾6;ܖݤŽÃ¥£Šë?ãûiPdÝÉvRà à¨ð¶’ŽV?Ë9)ðüÙËgËœÐ.!q&µÔH¸²¥([ „¼5B«'M¦˜$d§ƒç÷Dª¤v¢­ÎÚŠd§Â0ú¼ýÔÜõ½aÚÔ°bHËé^è†dÓ¹æ:¢×£ÂÝ&"3ÁIY8¬J_ Î~y #¨ 8á[{%°W½+€Œi±uññÈo7ó–-Ô”%k€–c[ F˜å¹Þ€öfóÐW¤Ùæðbé%I2–Ëí´Ô·} ÔÇ×¶µPÓ‹¼®{}ÆŠ`½^ë&/2`¼·«Û­]7ÙÝCÉöÃêÒõ@]ªºÒ_K=ÄN=,Ú)6éù±•“£©: m…íhŽ ·°vV<àníÙb‹²Y2ô!æ —Œ½¦ïN® ÷ë÷4X0ö  +ÌéL¶(=ª¬÷¨‡¦ÞhÄÍNÊÊÛ–u£¾¶&ÝjI¼ 4‡v t $µ|Ä$D^¨ñs¬µ\]­‹êjQtíç†XCc-{û žnQSo7ÔÇ}ÉÀß|ë"=ÿA—å%(ûCà‹4Âgƒ"lóm…VÖuz½áa<4$²Ä[«$yW78Œkïf¾Ñ´ÖÚwB%Ç$ó—3%\hEÜW"FS2QÜ'¯ÖO`eŒ.­ÇûÅÁ#AÆÐnJôã”z·Ï*cÄz7¶7Mÿ(ó(hB“O Ú÷(R±„#*ºB¡Ù`XF‰[Ö¹yÐD´7qЌ߃‘)ÎO¾¤YÆ#Xƒ*ö|ßbR¯Á}¥ÇxO„Q Ëš, p"Q¢¥cÄc±·Ô,liv`¿ö©ÔμرHÁl­ukÞj•«3²L43ô1+ ³î“ÉJéHá[7Kc° ¹…Í”ÔÜãé@Ð^·z<™ w—K aÈçJ·z˜åÈâ"ó³‡Û“¬דÀuÛZï5Œÿî{“8õ|Ù;Š×prW¸ôª?¹û¾% ½0éߣê{ïwøXi/OYTúÃvÔOR/ &/b¬ÿ·ËüjU·&/Ÿ|":#?Ò>@æÜ3î@ÖHç$¨Ëž¥ì#eiã^hô¹¤ä˜¾h>)ÕAȚВ…¤±Œ>äYÉ>Ïja 5X±|q±Ëÿpàýd§ÚšóHŒ¸Rw_6IÖÙâäë°MÖ™‡Dlî+í“ÉaãwNvY@k×PRšCiÖ~Yè±+@ #CåcA¾’^$’]^Ìç¬ —÷FÚëŒÜ$…Qâ%þ$*5QN¢FfÈ ôŒáR þ¤CIäÈæ ŠU½-y5!xñŠ!F±ôWÉV¤ 0²3¦Ãu¤dÐ@}0ÕŽ„å×ãeªI÷ÕÅ;Ô‹mêºü2ÿå»,Äú/6Q·ëßÁ—g1Á~+XîV…õgÏÞt¼˜] @/³ÌÈΘÁšÁöXê=hG¬õ¹µYnÈgt/¦'°ÐÝÒÔš­kF:ÜðØ|µð‚1e›ådQå^Aí {ÉÐ)¦.….¥ p º4hrÐð„Æð`ç*o°[~… &²¨¦ÕØ+P5IXxŠ„‹6MÅ0êpZ­¬¼3ÈIr Œ×8;2 eˆ+-¸¬(ùÖÃ00d˜¨‡”÷…RDÄø€h5£0¡¡Ðobµ½•°ÑæEÄ 4¤ˆÐ2ÄžùÙPbB8„Èèƒï6æ‚nÁ˜ú¨hØm¨ÃÅ¥ýETƒ¤‘8=~L­‡OÉÐ ©Òï›ÒžÑ’[詊MÛ*/ˆ>ù§}{¨Ï÷9ì "c@˜§«l3C[ÁÛŠ7ÀPY¥î)ÆîRÝl§?N|T”“DØý7 xÓ– endstream endobj 1580 0 obj << /Length 2474 /Filter /FlateDecode >> stream xÚÝZ[sÛ¶~÷¯àË™‘f"‚—ΜÇv·NâÚÎÉtÜŒ†©˜cŠTH*©§“ÿÞ]\(BV#Er/§/"à·ß~ ,RïƒG½Óƒç×ß½ð™“8àw=õ‹HÆ^èGÄ…wz7ƒ‡\²ú6««f8âa4829Hgy™7m=ÉAÒæU©ÿ;]äiöLß_fE–4™.0Â9aÃ÷×?œ\|<`€zÌ 9¼Î'! ½Éìàæ=õR¨ÿÁ£DÄ‘÷Yµšy~Áµð®~: }ü"êáC?!£„ŠPÃÿ4@ÐAþ ~–½dƒ­‘|PV­®(  ku>ÈK]ŸèËÑåù3ýGUëšö.«3Ó¶ÑUe¥ËÐXWÌë¬ÉJó†éЧæix¤m,f‘—̃Èöá3óæ2E¾{ˆ¾—€ÈûÀ2p~ŽhÇõÑAö-Xäº0žÔX,ƼÜe“!pp¯R:Ôl¯#ÆH,¥î[›E8 JŠFyÊ`y©ïÑ;±b€?›Åd’eiCð…€wÄB £«—>úy()vo{Šð->04]c½ÊäÓÏÀö(èUV‹xÐj³èc@…ÞÐõÆïPg›*¿CYû*òrél:˜YRàŸ-þ¤Í‹ä¶0=-›ë7Øþ­6 ÖjÉ*™ŠUÇ_[úejÞ®³BðŠ›žŠaA|X†›»jQ ›q<¸ÍôµÉZ}ÓVæÚ£Š ]}g*æU‘OÌŸéd¡Áئ‰és1µÕ(MZó,øÉ<1[è¨wÁذÕTðÕ½X^0‚~ÐõÚcŠånØZ¡ܬ-M:_CºÖ ¾í^½a¥7‡ç®3DèήæÙD|hrᦨ:U@©šê둲(±º1­/ÕDÐYÚ{6œç‹Ðò*)0 ¦+þ K¥¯·æ%‹F ¿Xƒv?¬ ž¹Máþ³;Ü9bŸ> *%»ÁacCfyš·ÆOÊt=®é›ôÍdPo’¥d8B ®ïìXYÍ—6K¬P¸56?RÓjQ´ù¼0·ù,kŒd·RÂA10Ì«Áë*/OW'òNT mþÅŒÖÓõ,¢¯ g09gº¿Î“²Aè_ÑU]‹ÀPz…ϵ‰¥H T|Î[ŒÀˆê.€jFá=Š Ø{“º±ö‹q#ŽŒjíD54Kš5£OG>³LšMñ‰˜›¨AG€r ¢’Ûq‰<¦b€F¶ƒ5) 3U)+æI ·YÝh8JÁP¯Ü©x•ŠËT‰Ã›þ7Œ©œO0‡Ån”:Ý‚ ’:ûÞñ„½:Ùû“lëW2¨0» JÀÄÉA&‹"1Çñrº®Ç€€ zÄzû4Ì“ §:ó¦½Dìk]Á4âÇ>‰lGŒKÈÍà?˜+==N阉Jöãˆ+åÿüv}òê⋉‘þËr¸  ¸ €ƒ~%¶ÀN`òu\#Ôl^Õ‰3Þ§yMÚÊÖ|‘Æ­sò«¾Ü›¡(ÇqËäá_6èrìLQÁ[ ¸2ÿUSg*ÈáîíÙ±'ÍÜù5/Sc.&® å[CJ¢xoCŸøa'±¬ÏàF‰9v&°À%0ƒ C€¶r=fêJ˜, ‰»ºI–2‚„dY‚m’3ËêÛ«“˳ãí•邨™Ø>ˆ+ûõkHq£e“ØüïK‹¤D¥¥\ÅöbsìÌIÁÉlns!È™YXgRÛ¨E|µˆˆ¬SËùÙóã³ËíÕâ‚Ø™™>ˆ³RY@oUä·[ ý›´+ ì?rq=YÖžŸ½î³¶QN.ˆYëƒXÏÚm^>Å|É0‘ô÷&á®S'µ«Ö6jÍE±3k}ëYKp«í›Ü :C2'÷Wå$ô;ՙɿ,_·ß –iìcÁå§=Í>>wÙ·yrÝN™N÷V¦ˆ1u·¼^\98J ‰'ün-Ò@»²Û„ä®É.–<_ªÍdf¶4A¿óy‘÷·ŸÒ¤MìFToe²ÐëÈÚì—l©éPîï­iF$Òr„0o^½zózü57l¹ ng7ôÁmôÃá–´Ã`³d»ÙVé <Þ_éA Ên¶£÷ËÎÇ{iÞ…¶3Ù=h¹>¯&v}óר]âeï$THÞÑ©ý ÇÌŸ‡¾Ôû:°ÆÞ^á. IïÚÈú.rš]P§9³>ùEºäx“ÄE ~±7Ç>'q·¨|IÆÔó;„sµ½¨]0;óÛ³;½©Ü$W\ðýå ½áÙOo)‰Hô ýúÅÙéöruíLgÐF>/ôA*Æ×h™\¼:»Ö7÷õ­4CCUâö°™>ñÖî ï”/ &‰î/d*ãÇS#Ú¼Æ%íÂÚÙ}X}pTÍfv`þ“™÷‘yAB­n¢2±G®}XèÌxû=ÝmÏ Ÿý‡ÜãÈ9^î’àY>–#E~¦ºh¸Ùâ¨À$å/ÍY9í•“Òžá†9 (™u§ 657Sç;¥=ã™,g1uþú¾;:‘r­^ !ëþºTN´^p@x‘ƒÔ6¸÷ÑC_£y>Õ­VŠ“™ýZ! ˆ”’jÏ,K°Ð!¾[å2ˆ  RDÆ@ÿ kŠ¢kå‰'Ì]ò¸Ëª‹tÙ5ýOŠâ…eêýäaÀH0äb‰ÖzÐo¦XBhIÊY¶„kI§PÜ•ˆôÞ*¥ÀB‰w ¸µÈ±GYcžUÖ¬Ú²‹¾VÏrìÕr1 ðë¸.e§"5ˆV"U„RsBSä·i6ų®æ½:aâ8÷1÷ôÓ´ãNüÌ„ˆüÚ…Ü©ÀÞÍHBäý× tSyxýòäõá7t5 +ݨ!xŸçOŽß®;éMËf\TÕýb>¾O'Obl[/2çUÁ£W=³SüÔFŸZWrAìÈ|£^ôWÿs³7¿-䮑OåØ{ûiÛ>æÎòv¯ç³t±Nǧ#÷ð™0Ì$66­è×è‡ØŸÎLðÊ ÿ«4£v‹Ç°¼øÔ-Ïþ½2¯óYR?Œÿ•ƒÁhݰ÷åqÊÂ’O¦ž€¤r)õ@ –K"H‘Û¼\dö %“x—:ó6ÛOóD'Ùj±´ñÃHB¤kŠ­¿Ú]»âð9aÌ|0·d8 üi¥ú8©l•#<VŒH„ù,‡‡<€õ;M$¬ endstream endobj 1591 0 obj << /Length 1565 /Filter /FlateDecode >> stream xÚÝYmoÛ6þî_¡2P3|õ‚aÒÔÍÚ¦M›xÀ†®d‰±…È’+Éé‚¡ÿ}w$%Ëš4s°ýbŠGïîás|3uuNGÏg££—s"ùÜwf×NÀÀ ‰ g–:Ý7c.]UÍUUÖã B÷x̤›®²"«›j<‘nÜdeaÚN7Yªž™ï •«¸V¦Âç„?Í^¦³ÑçóÔaÆœG8ÉjôñuR¿v(Qè|ѽVŽç‡PæÎåèÈZ×i?:‰Ê0ODÄAÂ(ñy`âøƒJš”E“•‚O’º×U¹2_ëJa˜·Y¹©­$^èÀAÍxÝ™%ŒK/r†eµp¾ÕtqŠ1·û!ñ™p$8DžĨÏôp@"!s~Œ¡…¡Ðá0=œ;Æ`^¥ñò&MÅÂM»T®ú3^­suÐ ¬-,}:qN† °”Hì"˜¥c_b”؉NŒÛÊU­ª[Uý˜t˜ìߦè×^¤8$b¦åcZ®b€¤Rq¾ú´Í¶‹Û*k‹0Ý< Üdz_¦ïŽråí«ÙAúÓ¿~Í$^ÇͲÞ¤‰§À#­µÂ×§¶<‰áŠã“}1}Ý·œ<½­oŸë?çk6û ¢>9ù Î}Ü–„ßnR! =¸Ãt¹/Bzžó嫳éåŽíÁá ÈÃ=ÑNË‘j’£›j. \®s†Œ„ö*r9Ú›ÔÙåùÀ#qGõ^Iê¼\àeF콚<À=ÃAÞú'HèÛ;ÜÔßúÁ&p¶)ÅóN¿ï s¶Ä;clu¡æÃNx¹m©7kØWªhÚS}#<¤[è·†B¹ï÷L30L=<­›ÓÙîtïw×ãp;Z•ë±Gݲ2~­«r1ž0êVñª6nYf ^˜—¦G\Ùš»u–ÄyŽSzgDe±­ùî¦Ö÷T-·º¦áÍ‹“g- ;C[‹ÍR ‡»Y”îØº’‰'$ ‡›i\¤ÎŽO"ìdýÐÈê#bzŸ3"€ád«•ÆjUúV/´Gúã`Œ"ÙãM:—W›&Ëïå Œ‹‘UéS…Œ'Âãî…~qÈõsŠu8-“ ÒÜ,e%¤lÇ­³ó´w|¦Ç¿œ…4¯v³é‹W÷íŽòvœ£^êÉ ÛÙ–ÿ@`/¢îïcF%àa‚Lb G‰öoñGaÄÒ5qg©EÃ&#ìAøZÄå.ÿRu3oòÆÌn^&½¹žwiÄPMÜ0•Ž·ªÀ.·YUHS#¼ÕcZG⹹ݢ* É;4Þ\<—W0£Wï/pÀse=Œ0ÑQ´·êu ÃçvéþßýÚ¾÷4ʸ=+†¸jrº'Ëx=FÚ<‡.‡…Á÷"÷¤ãÖàÿ‚—Y®ê¡»07A endstream endobj 1610 0 obj << /Length 2199 /Filter /FlateDecode >> stream xÚÝYKsÛ8¾ûWð(U­0€dªöàx²3©™ÉÄšS’RÑ$³B‘ Iå1[ûß·¾L;²\ãÃú`²`£ñu£ v ^]ükyñÃO‚ IWÁr„,&q”‘ˆ‰HÂ`¹ ÞÍ^ϹœéêFWe=_ð(ž]ΙœmöY‘ÕM5_ÈYÚdeaÇ^³þ‡}«sÖÚŒpNØüÃò—‹«åŧ :Ѐ‡å‰h¬÷ï>Ð`ü_JÂ$¾˜Yû@¨žyp}ñÇuúSÂ@mJ¸ q¶bAw˜o§vŠ«2JhÙM^ë5î¡6úù~ø)Œ{ßÐ`Áˆ”ö“å-îLÒÙÇÍš¬Ëbk©÷4¹Ù§óξY¦4iVX¢ñoç‚ÎÊ^MJ„J‰qÀ}ÍIGA¥ƒíûûEI€KIN¸¤$錑„ßÄiŒ–Šü±²F3½•ê„Eœ(‚|I"˜dÌò̱Ñ[tÚô˜7õ‡I‡zpå!#2Іªs’üpZy£ÒÀGx%ÅP¥—:ÖºŸ ™uÝw‚ʯ_þh_nô­ñŸÏ ™MÐÄ(•oq€Ï†¼xBæ¯P[æû» ß§w úPï³aïëóÖ.PgQô:ù¶ÈnÒ&½±‘ÉLÛ+Ç€™›Žeí-pŸû´à1áqòlãÈûþææi®?Ôýl+ôuºãüCðÇð~×Á™"a(ž ^<ÎZx÷åæ˜ë3ü{¨öÙÈöÕycó\ÈÙâaP¿ë³òZô|>K#àyŸÍËÝ”}¼³•>Ò¾2?BŽ®ÊÜ…å[›”]XžsÚ+ƒŒ#ë=– †8h ßýPéß¹ žb “…) ¤Ä( Ébwv5ý1WòQEÁ“ª(©€L¢Aî>¥Tær%æu¹GÏåá¬Òyj 1Cšr‰ W.ãnv7lW.9£ýö›%6ƒðŒAîÑÁÌò.úó¬!³ô=Vµ<™5¥pãT:Özã´ÝÚg§m岡Y©>Þ€ž ÄpŽjèòΦôEAQ6…cj§‰ú¡--›tGæ‹0 ¡ºÕݘuÃSOñèsBĈ@ÿ‡SþÈÞpÖ¸ñ9óUg­{ußhLÉEæ}Xå¶ãã\ë-d´¸Šz‹#øàà ‡£:Ÿ{Ïö¾‚H%^ãÛ²nV_7«ZWŸ³µ®\Ñ~|þzà嫺+]üíËʪ9}3üÌUšõá¹6„K=nSç¬T”+ãÕœÁØšcPUiþ·.jƒ¦;[7«´€#„íå¾<Ö«¦\5»%Žö¬ 4×û-¿Ó~N…Ù¶oéÇD—(mŸ‚2´^]ZÄúÄV`éO¸‹cæ±.š@‡x¡…÷é×ÕfW¥{‡þ!ÇÜümUg釢P‹D/ò^ûÖÀï¥ A°J¶?:¥é×øhŠ—Írî›ÔÇê´ðÍ›/Å 7d ¶¹h÷çË7 ?K.»àw_¿hÉÌ©*h¢ÜjÆ}7†÷ºB8u:!ÈÙBÑòX(ßSI.½su)èE€Ç01ÈA¸ð 0¼8ü„°¡½?Êà† C[—ÑG7œf×ÜÚ¡.t„k¢c‹4buXzù}@ìîi€¸ñ‹dû¬1©™½ ¿_;ý]•M¦2ú£)oºú~4þ´:؃›Ûtèݦ9e\ö[^ã—;íÅÎÙR&lxhÂPYÜñâ(R•ÇÒ=ëà`j×oæ ]¾¾²dyhikïlmyCýa‡Ä-¬u· ‰u”x’(æm1‰Ï®Bá a=-á8†õ•p'àÙÕ³âiUÔ"E©†˜¿Ë³Ú÷‘¢xIµ‰aPDʺÎnüdWïºbð~ÏÌÆ•gSúÚ»«oc«™à7a5\é7ÓxŠ\?å Úª½$‚øÖÏ,¾§¶&£¾dE„ò sÑ]O-ä µªïM\ª¼Jí¶À±“kj|‰ú†h"£«õ‘Ý–¸H ®8ÅÍMfEºwoùp(µä°ÉÄ#qdÊZ§õBH_H+¿Ó²¶ 'Þv ^±xöåVWz°¤×õ£šë]YŽÖJ|…—C ÉX7ºBJú19>9Úihft˜cžºa¿A¡Ü‘9U–[#ùrº?änníÛt\[V׸ƒ2Ɖ9Ô½ô/­îý•+÷©2ãØ~9—r¶ü÷ÕoèΗäן—órÝÕË?½KÖ^´.,EŒŸÎ‘§†Þš{ߨ«˜(0žc_| ðþÝUP;mD®÷Ah5‰ [“Ò°s $áŒá)"Rn€‘P@UØ1Â`Ý£$#Qæó–!DŸV¢nZ·bËZƒÈ–Èý‚-‡vâh·ÜˆfS?ß=¨ÙÙúÿ~Ûà/‹¤½,’¦¼GØÆìÿǺ'(Ï\‚Ø7xI7Òâå/OIæ€v$'Jª¸'KŠÞ2@Xtú¸ î3äT(Î9Gímâèé¡\¨„POH)Nâi¯-ãá-ƒc1ËUuI$àÔ\ÈãƆKwþÚÃÿ3ê8 %|1¬ý€1å)ßc,:ýû…„ØùÏ‘ ÃüO·I>Ü$6a•.ô,‹ {Øê§-fÄ.qZè3}ŸÓ}w»ñ±öT t,áöÉöO–`3îb¶Ë»ÿlìë™ú]ÖØCePOü6Ýv«ma¿ViîÚ±w¡‰³ÛrbØÁ߇XÈÕÉ?ïO^3 Ns¼B½ Db®ëçPÓö²'€0k°sU1OÆjýþ¸²ý endstream endobj 1617 0 obj << /Length 2481 /Filter /FlateDecode >> stream xÚÍZKsÛ8¾ûW¨æ2T­ÉŸ[µ‡Œg3IíìÆÚS&•DÈf™"’Šã¿Ýh€/Ñ^?2[{± Fèç×hÈlqµ`‹·'¿¬N^]|‘ziäG‹Õvû‹8H¼ ‹U¶øä¼_ú¡£êµª«féúqâ¼^òÐÉvy™7m½tCG¶yUÒÜÛCž©ST…’¢/Üó}/?¯~=y³:ùzÂáx¶àt\àÅ,^lv'Ÿ>³Eô_Ìi²¸Õ\»E%ðY,.OþuÂŒèl¨B$&*pæ1“ rS|ù‰ Pú|»ðÕ…H«üÀKA —s/ CZù; ÙåÒg* yyåƒÖ!s>T£ºð…SmñÓwÚkE¹Ù¨¦!â¦*ÛºZºÜ)ˆPä š±%V#Y/[’ÓóY‚†ˆø$Ñ¢ÁˆQ“(jÂ…—>(©•¸c™#ÑcÙC‰ÇãØ®:4ª!áÚŠËT«È °“Ññö:ß ×IJ·fÚä{Y˜õ²6šÉ¢¨–"tn—‚9J˲pýâ‚§c»¶u}wnÓ€½1Yì蘃Ymp¼GOõ¡ ,™låbÐxꬖ)s*b®`SÙš•·y{]ZZ$;¯—aèœ} "y#›ÇN£ k{7Ä\«Â¦ŠTÙys€ÚíÛ;’ß»xÒV`õA¤ƒ_Gʼ$ÖAÕÛ£&„ ý}üô­96н4 í:°E€-t˜2nÝbŠËCÁÈ|ç›þZ} _)0¥]0~øí õ­Íê\®04 ¬Þœ¿û8 Ï‘öqè}P¿º©×áM¶yuz`ŒÅÓÀãALžžÖQq:†lÉQÉ¡dãíQ%} Ã.²¹$Sº5Ç Ö5XðØ÷Ží8HXŒß—Ösáëhü³êù¾6·ÇGÔóÓϽ@ãæ°ŽÁ8ìKwÐ…1ý}Ÿ÷@ôÔº&ׄA¹.Ja:½ä™Œ,w.‡™‡¬T·¢#äJ ¼uriZFwVéºËŽîÜ8¹„k)?R˜²'é4‚5:1š"f¢iîüQऎ]ÌNgffi+;DÙNɲƒë!ZÕÑЪž£ºŒÊ«æ9þ»($¢JÊïq\ÆÇ+9cÃA¶v‡õ¡µìÚ_ðyì/(½¿€CûK›µÖ_(ÇÊ;¹¯N‰£ ¦Mc—sþÜT»t…åNKÆÓhеò4Ö!Õþ”zݼhúù™×ʈ¥hBI*8KËiF7¿zÔ@CVdv½YWâ-ÆÈ¢Qgÿp&ÊÓ‰í13зàÈòFŸŠæ#m~jÍFOÜ¢»™ï«¦ÅÈÖw®cÃz‘t×ñÓ™íB/ŒyO¨Ô­Ž±Z?¾Ü·1‡1zôÆíUëbÉf¶)tmâÑ[Xà¥BQIÐy á±èñªïµºîú=¿gKÃÿ¶cWg²ÃÞmn‰Ý”g6L<ÎâG˨_5£¶Û BŽ™À(m3ç(ßIÐhªúø,7ð…ÇE4ÎFÕßòͬ9€«“ÍBâü͸µÀ\š§†Co0Â[ˆùÚÜd70à~Ø­•¹0k„ÃrÕ4ùÚ¶½F†¿>„òl|Þ£Lz/Æ£üŒƒî%]L’j+V’x VEƒ÷çg4gÚ‡ëa£K#.°"âå¸mh¾‡b½enÈcüGT+ݹ#á{(¡jU¶9ö%`—»9ÐÊóÚœ wk;R"œ^l;‡•–17KLÁy°0[; óLv=ÓO#q:+P[f^AÉ©†ä¦Al['Q›W/ ¨ÊÕcó*CFÑéDKœ9í {Á¦Î|ªÁÀöÿ©Ýæ"Ú°Z·ÒFÈðÎa„6/ 3–{º9®iÏ=>Åú}!¶åŒD§;Ž-Í nª_êK»JÑ`j‡áâZ}Eô9äµ~l‰Ì˸^¥PfLξŸ#ñÐh‡àPÒÇ5ËMó®ø•B97˜™ä†ö^åß:7ËÒ¼õüÓ—•‹:¸Ý…K5ý+%謿dÏL!Òîñ§^¤‚õ´4l”mCÔâ[=½¥A?*ÀÒ×çîå»·ÿxsÞs¬þN,Ø1Óh[W;b7/H”YFÏd)yN$“ì×3Óì×Ûu¯"µ¯ Sï¼ ª N²q3U¨+Ýà´ê9yà'$|PAÝø6Ȭ6yKœPÚÆ.W4Ø9ø„æmYdØ®dTŠ ÿFÿh<ô{GâÚlFŠ‘L¯¤[ƒzeŸA÷ü,b©C­¡÷žmðÖþ ÿ§BðÁ>>^ÿ¾TÅöåü´Où¿,9 ¤î9;Aî„hÏ®5ܶ×8êàŒSWŸ]³Š_ô{*|Jú°Y…ã±°4ù‘-MÜ&Ý1ãø°ImÂu•]5­MƒIª{0À{ÓlÜwÔø#Ù  Æû „sGqÀ–ßJÃJL¼esêól×cì Ë;;ÃØÜ׉A¶÷íŒçÀÖã9 ~MO¢úôǃª4·ðÑO úº™ƒ™œÝô×íQµz‹’­lrHÓ›]Ëã|9Ò²Î[‹…í8 ¦ÿfž=ú¿,fÿ1$ÀŸêÍO‚¡«|ž8g×r¿ÄG!ü?ú5ËïGÐÖœuoá“ÿ¹È ÕLÅý'ʧ endstream endobj 1622 0 obj << /Length 2453 /Filter /FlateDecode >> stream xÚÍZYsÛF~ׯàÛ‚UŒ܉c»œ¤¶¼·ò¤TCr$¢Œƒ €–µ¿~»§{p²L9©Ú‡˜ƒ9zúüº{u¿òWï®~Ü\½zŠUæe±ŒW›»U R/M²U¦^˜«Í~õ»óËZFŽn¶º©Ûµ+“Ôùa-"g_æUÞvÍÚÕåuEkïNù^_Óø£.´j5}OJO¬ÿÜü|õfsõŸ+<ø+±J$\z‰Ÿ¬våÕïú«=Ìÿ¼ò½ KWfW¹ ã~‹ÕÍÕ¿®|æßË#9²ØË€^"|ÏãØ ×õ:ð/¹ÚÚ°bi¼z¤#Rx™HV®€ß("o*8•W÷ Nä;Ý!oiô‡DŠgUQÀ ‘ó€:kíNMàÀ•¾“W»ü¨ ^¬é·Þv*¯ì>CãË#oÉwk8ö ÿÑ]ëÍøžîöŒ'^°Hn‡âðtþáïÖ!Òì4¯)Gµ­á nö43b÷\U¼Kñ–‰¶pa®-œ %”Ê[»aæ;›ƒe¨=Ô§‚×Uljø–ŸZÍëàs PÈDðö¨w¹qQ÷C·Ñrl%!ôÒµK—ǽN~G«ŠNŸU8ùuH!æ2⮃ji@4ycŠWBøT´FçO$þpNRÁ)©ãÓÈ¡#¤â½3Ó,(å!ï@±ùå}= †¦>ÝfÁ^ÕD°´‘~ꄲ“>#¼Ÿñ Ùëf [¦l°k²²OêŒî½<~4¯®4¦µÿkälÎ8ýkô…ø1’;•Vît@™çr›z6øå§×ûý„—9Àº!èï}E‹MŸÀáCx"¡‘ªötu¡:¸è^/Œ Sˆz·«]Y0ÆŒÝsó°?4¼Ú¢swyQÌýøÔIsØa€‘™IE–x2Ãzðµ?ÝöÒ0¾òH'&Æ }/N{`ì¦Öu[Ý=ãFQæ¥i4õ£î¾s· Á÷åž$zë 1°†€;÷$XW ¸óøéS ñ#–6Ãf½®FØ.fÛ]àÀ¢QiÕ½;]D0,‚‰+…br>j…‡–¼¨%¸„R Ê.£3Å?OS²{ 2zò›wÈéfúÎ×-Æ^*éa÷ù®»c„Ï€chêÒ‰|ø‘ƒWwÖH÷Ì ¨«Aˆ_k+nIªÆ‚D„Ä4ð^XUtô‘&™3ÞÕÊj\¿)šú›ZK5‡#v8¨êŽî< 8³Ž“ àªayc™óÁ5É‚}™CjêÊt ÉœOZ=ׄ‚)7ÒÐdeš¬j:ªöûÜ(¥ ù‡CÞéö¨¨R±)ë耽-çÆÆÔ=ȶñä§á |½—û:“ðµÀ\]ä»GƒVòûJ/Êkð‰ävmËú=3ðï5Å{y}wžîyé¡O[Bƒ‡œ…Š~®<°Î;ñûÓì-h÷%~ÿc]C‚AÛÇÒùl‚¶8ivÿ ÎÈT°Æžp2V#V^,81ÂFÆsq`s$ ?¬¡BþaEÎë–fÑãPc„"U”| ¥9˜¼ ÿ-otÁ¼L¦?Œz5˜ªA³&^Û‰éc[AÎ ÁúÍ»APè˜y}g´q*ºiÞ¡é¢Õì'àÜä sS[—y7ó7RÙ­ž`8ÖóôO$ÏUÕ¤DŠø€îÞ¿À}$)DW»æñˆ%f§÷·\Æ…æ&õ6¯ö÷`¦¿ Tcí¦s„±(e<’³ƒ‹fKï¦ö¨NX`"))ØPk¹êqºÖÒB¥›ÝóT‹Ë”˜ È–SK° o× Øå†2Ô‚g¡" !Žžv٬ξ186ÚŠùœ¡¡ð‹/·í¡n»[S;ÜrùÜ~³ãÁŠ¿õèí"¶F Éä²Tn« "Žð:‚Ä@‰ƒú©ó+Oµ´c\~òÔ8†ð“bFC3  ¡ãÚzæS¬#ÉÈâs\•pÞB¥Âêg³³¢Ê'‘-XÏúoËä@}¹ ²°@˜ùæÙÁ¸”í1yÃ÷BTþNÑaWäà—›;ç÷µã-½‡¼ÄÖC:ˆüót.: \‚?Í¥ñ×]£KàÞjg¯:µí! ¬rTXÆý6âGœgqxý‹°ü=Š;õ}›ÿ÷Eª{_ušÜµY?Vgãf:³M% Jõ%/O%}T§rKŠ”\KHøÁ>qYí‰Ôô»eZ¶È…_£Ç¼`n97„ÑyfuLt¾OX@ø¾ÏÖûÀ¼Ö³”YÂâzæû#…œYzÒRÀþ…éQd—WWƒk”ª…NûraQIC±ªJ3Š{·ËиFaßü.»çìÎ8òb{à8Ò>^i\Øë'InœÎ{“üâib…ý9Oó[eœPÓ+Š>9抭âLjfYÏE’2ó],“ß?XnhÑ)Ýê.97¥þá{¬MnGè'Ô-´ÅKªŸŸtÑa›žá3(]frÞUÙ, uô%`ë›>C¡¾ëLæÊ,zÀ\C ÒÕ”°Œì¶47€ÌW}ˆÀÊéÈl/ºkê’ù<0›Ö…ʾíTé£{ÿÅ0An1Ö] ˆ²‰e¹à"ð|!†— È^òÖ5\ "yuáPµ—BDòu§I|/M§œ¦-*œJ†ïu›@&ì68Zv›(¶½¾ìE&_ /ŽeÉßgü¦x4ZÄÉ¿ÆÈ„jØ$Œ‘SŒ‘Ô÷ã/cŒdŒÁ_+ÌÆÈtc\)/€¬>ÑéeB‚³x 9“Úî›ÑEø‘—úÁSžE2†ó ¼cZŒû‚ßäB1‹³b<É f`Å< r¬ ˆØÇ¯§4½_á”Úï(­é¸éÅ_ gèµð{ô¸!m¡}åCŸšâß–!|/LãU8›üh”Ož„SOÈÌç“yëTøGð¯>æºöÜD—{¥KSø„do”í>诉Ýð˜ç‡P“p•Ž‹öïwX#ã"´“ýK:êή“–®IéŠ&{ýÐ'|æñÞl3Á4"ÎDìäžf—©ð%{óãÎmÿºÞ+gþ‡ÿ(ôdüÍ÷?ÿÿ€D(¡ãR†XT„™óº®º5¶[=Ä„QìeRZëbÎÖÿ::wN endstream endobj 1634 0 obj << /Length 3522 /Filter /FlateDecode >> stream xÚµZYÜ6~Ÿ_ÑÈËvYI ìƒ×GàØ›xí ²@šíÜ-uZêÌúßo«H‘jÍøÊ¾´x³X¬úê`§«÷«tõýÅ?¯.>SbU%Užå««w«"[ªLT%WWÍê×õ‹M¦×æxmŽý°¹ÌŠrýh#ôºÙ·];ŒÇÍ¥^×cÛwÔ÷ý©mÌ*¿6;S†*"ɲDl~¿úáâéÕŶOW‚¶SI‘«íþâ×ßÓUí?¬ÒDVåêÖŽÚ¯T^Âw·zsñï‹4$]–éUžT°N!Ò$•‘_o.¥È×Û~×w +ÓõówÔ6Þ*ÔMs4À #»±n»!˜7À¤ÌÖ¦Ûîú'µ#;úlDº>ÕGCë\ëí&K×ðÇŒƒÝ\ðæzÝõg{ÃZüfÛþ–JeÞÚÓzÛîšm}l“À†K!’Jk>«[+Ó®…ßÓ`šÑvolúPãí5Ty‡÷[·;>öô½ö¨%]×ݘ÷‘{^ÊÒ……€dj`b 2ÏÒ3Ò°‹w¦åÝÆJ×X±¶-åùúÊmÓšuÚñr¿¥:½½1òãá³\â0ãN{8âÒýá­éêë¡‘é2IË&ÒdI¦Ö(äp‡'{ l’SWOuæVÐBŒa¶yº"èªÇÙØCÏǦö˜§Ðß.3ÓY¢sí©öÇ„ÕÆ…Cª<‘Ê +ÿˆs ^ð­ßÊÒpôJ ":±:ì”pFË¥,ãiœ/’JÊ»H æG´eÊjptoxïðÒæ t§=`Ò$'¡{Q¢\¿ñ³XU1kaøaq6é©íš‡¢ÆPÏ»Ji[hn»íÑì  ÃŽ—<ö‡ú=ª·ÀI¨Ö¿, £ÔyRæç—tŸ,æÀÀPaO/‹,ÀŽÚBuıñÆW oÏ3Ԩª=Úƒ*¾mø»ìÄîÝÖTyñä1MlDæ¾?ƒU±eg1_bv[i™àæsÀ6”YvΘÇΘ;2‘¢Œ¸c·Z>©˜e˜,òD¨˜_bj»¯©€—V §…Æé´¢X׸oZâêûØoI/â;~cÀ‚†PÓHŒQÓõ\Ôq-;†÷ŠAw\7¥“¢ü"ŽfP¬ÜsfŠáYÜ&VeRhó°ß€ù ÑÎÓÃðNò¥PõšåIßì CP‘À±Ñ(ü*P¢#`ÇYãk Fyp"!³D ¯B6— lúîÁ Y$J{8mj³GݾôDL¡ï½#ʤ>vÛ·c»7ýé« ð‰Ù¨pVÁRÎÆ’YݽwH×5CÂÜ!!ˆâ¾?u#5Z3­H`~ç‘ú Ì×LÅ»“5äÐ0B^’ÚöûÃÎŒ&!º®HŠœ! 9„“j^‹¤ÙÛîœp®Š ¤Šä_¤Œ‚«½þâ½2Y±¥Æí;w2g©¡–Z|ÂRº`¡ÍÎp¢OüýY}†‹´;C¾kWï K¦.f’‰ý·„ž“› …Ó¡©G.)T`‚lÙKd4íhêÝžŠ0¿¾¶üÀZË{¡Tâ÷šÛIú£õ‘‘º+·TtëKK€|-‰*ÃÖŒÝ`¦µ,&P ŒÀ·ÈŸÈ+ðÓò3@þˆ»T{1f>ûCÚàXŠbÓ»t6­’R• >Tˆs7 ÜKéݨO™ ƒÔÞl͆²)!wäÚB|]ÐÀ×Eh{¿Ë’&e¥b—…óø¥ÀÿËM ¦ïPoÍ%”³„æ½€}}9˜C ÜÊ tÂ>~Ù8ȼ˜¹-9+®@ÄQãëW©Ñ­`:TÛçó4Ü‚‡DD6yžÜ7y5¼Ñ7¹›*ÓIVͽÍK–PêŒö)Gƒ¢JÎQ ÛOAàÜ7Ü„¶!Ù×Îá±ðDuGß¶sº@¢¹54Žùö€â¦š‡¾:TÙW®¹a]4ÙíÔPëòl[%‰$‚-«øØqf‹ÄÛfãìÖ•jªþüãóÿ°»Öïk ûÀ öaŽãz¼±. aƒMŠ©jRª ‹–Ù@ã³Øå³ØÓŽ±3f±!è7·Ú¿äJL”qQÎrƒ6åd)‡® Õ„ÁéÒlŠY¶¾ÚT ýÔÜ´ƒMCØÊ\©`­IS ßk"”I¡Œê|&k° ¥ ý „©€Ë¥Ì%C2¶UÓ¡Ìþ0~ä£ÇÑ ¼ÃMB&U%¼:ÆÐv©A,ÿAŸï¾[€ñ œ¯"N’et[°å”?e”? è¿öFæñ”?…nkyD93¶Í0"ÈŸ’ZÀÀbÎrš6>“ÎŽ@)HªB‚0yžTUiÆôÆVªàôf0´Œnn sEˆ§7ñQnžÞÄm—g2S&Ã]äÉÍ\@ðîÆ> ,Å­AH •äræU2‹º†JéåüL>èäõÓG/ÿµdãU"¦ {ut¤«á¤HJá׿kI ^~?K„ñÚ {þ-]§iîãÂÐl&ÇÍö/ ÓJAº[.…i¥˜‡i*Ëç²íÞËóˆ¬QDV”£ˆ¬ #2^ó›äú’4pH&îµ$À°¢ZÈý¯0y¤¹ˆ=ô =‰â0в)³ŠJßšÕu1Ãþ)«(ƒÆoan‡U‡M“ÝN fë)ƒrtÕù„³8>>æªß ¾,øðUåAù,ƒ¶ SEAnuå|a(L§¨Ê0³5÷ F`ÐÓòâ~ã0ƒúBnnßëæ{s~ivÐYf«`IÖ6#¦£ÿ<|ðלˆË§(Œÿ“Mvÿ,¾é,÷3–ö4Ü;®çk Æ—¥ûó‚[S‡TøXº§X*±:/0ƒž{ŠõÏO^m*M.wÁ±ØÓ€Rð Œí½ë7TpaÞù£õß•Nò)Ì›`ñ“!^QB¨!„t!]ôö çVb9Œùü›Yáäéx.æ#Çv,Å Žm (ðËy (Ëø4ŠÿH#KçîÉ2Œù$Ç›`ÏÏÿH“9#/çyZÉ?½t‡ ô$.CŠåPtœX:eðž,ÉÓÿ5ŽéÀjøf›)5¥6ñ{f3±Ñé "UÜ>ͻوæ€Ý¯XÄÝBöaIgÓI±‚'åEH—xëR¸wÒ„ŽÓXŸžÌ´üvã:»·Ï3®EVÌôL³i…gØîúƒÿäiìh÷oÃÇOèÝê9O &·l¤¿Ãfõ8ÙP]p /g×Z»s( ô’sö¦f¿W5t"ÊrÎèRVP:ö)Zÿ(Q^ôƒG çUúƒÆ \t柭ÙDÞ¸=|©+™ßåJj*ëWR«³Œ¿šÿeK»t&¬põøÕ\,˜÷:ò)µž|J­bŸR‡ÿ]Ðú/ð)+‘dòË\ÊB„R¼Tj4”áW…ûÇ#ú1Áÿù¯÷Gà[` ßíÖþg¢b€¶”•п[|ƒ†²Ê>K4•LDQ†Æir^BfŒ«óŒ1RÀn^"ûxò_P•¡pGG14ü²Ÿ)µ˜µ }ugJXéDÇ®B ú_‘öÿQssªø`Ф|>8háÿÚU^TI5tÔnJ$ÒØÁßI´aâ¢HmæûbCªJ÷ÏšK¡@•å,Áò ë:ÿ˶Vç~ö?¶ÿd®²D†!™¡CiðÇ7õaƒž+§®Àìe šËjýØÿhöŸógíÎ srÿìúË endstream endobj 1644 0 obj << /Length 3067 /Filter /FlateDecode >> stream xÚ­]“Û¶ñý~…&/¥:MðœNòåÔq›qceÚ™$s‘¼{É”ÿûîb ñ®ñ¹/'`,ö{Ë 6÷›`óÝÍWû›—¯b±Éý< ÓÍþn éË,ßd±ôã<ÚìËÍÏÞ›m˜xU¨úvØîÂLz_nEâ•纩‡±ßîOuÛÐÚw—º¬^ÐøÇêT©¡¢‰ðÃÐÛ_÷ßß|»¿ùíF ÁFl²®‹ý,È6Åùæç_ƒM ðï7åróAï:oâTÂïióîæŸ7ÓÌùH£ˆS~eÄÂCYÜŽEwÛµý8hÌÙ—¯"9;Æ~„ì„ðó$¡Ã¿Ið¯c=VC§Šj·ÝűôÚ3¯hÏgµªNõj¬JZ<ÕJh1Äyæ•U×W.û€Klw9ô- ¯&DÒØ™!Pø"a$ãš,ïù]¼8ùh‡ˆC³ ½»m ÕÀ<0¾`Ïh™øa QîY c™nzÒðG”ZšÎ¤&R_HÔ' »?$ ð§ÄáÔ(UuÖì!‰~ [•†GžY7lèÉOß¼¥A_ý¶w©Xþv—ÉÜ{͇'™Â^”)TSòe ›£¬á§éÜQ LÕ‘êÌ£s¥šº¹gLÚ¨#Ü%¡¥Ž1Kþ7}j!š4³Íhê;Tb¨‘F“öq†6¿MËËeõKÅ ˜š#ÿ%iRúyœi™ŸGìç†匴Oõ’¯]gÓÌj’m?’‘÷®«Šé¬ü4%ùâf¦ay²"AãFU–}5 t.C ¾ÔvKXŽðpk£Çuk-8ùl3âÌ—‰ÕÍÜEË'=óÓP,Ý'A|« ä𨽠ܼkÕŒ(>"wVÛˆ'Â;TT ÍëíwßăhÅë$5ŒÊiì)ÚAÓær>X'ÐÛšÅaºA»ÌÕiaN륅þHKp`®.ÚSÛð5m?[ÞO?¼þ÷ZŒ*Û³ª‘¢HxC[lÇüS!Qèuj<6àœ(Ø0ó^ßÑV2,XŸ¸hÑ6#`hIS£…AžkŠS«S쫹½˜¢Œêé¡WsJçò¦]¹»æ[ëå‹Ãé”Á”cïC}* Õ—4›pÁDãŠ#ï2 ¿ï"@¿ßæ`ñ´\Öƒ:œëLš¼&“çÁħ(œ8ÍŽt!%#ÚiÃÌF¾Ù_»ñ# g=C‡zÖ}ÒsU“ŬýPr½${ÄKDûqº^òx‰˜ù~-+„ºâ[)Èà¨Ey¼Ç?É;ËŠÖ9ŽÙs…™§û#ÚêûÆðã›?2à"áÇ`. é9Z‚ ®´¤½îJK³b\÷æ<Û€ùF¶øÐ¥±”ŸîÄgÊèo´,5Ò[,7žãÏï°Z˜¡ñàÈ­‹uÙÏÑwéQ{ç,uSQwêD0r[Ô\ƒ¡œ0Í.CäK=Í©†!q&9.îÍöeš!Y_çí( ü,¶™÷Íˬ˜/ÄÐ4Sv~J1ØP'ÿSãÇîYºx3ãz' "׈`tU¯5 ±T“>tä3s¡âÂL¨ÚbEÛÖnõ ùžpEK‰ã©÷zzºðºY¸FŽŒàu½„¹ƒØÈ\UC˜¤»bvdz*vÃQ‰]ž®é †¹\(kƒod? Â¥8_!S-[“¢°—¦«Nl¦] Á„*T˜Yþöî¡úÜ„ƒõظúmSôXSx;M”}D£ôŸì AÀãðYlE~ä®Åþáü5þ,3-/½}ôËÇ,3ÉÝ"»çHA}¾œZŸÜU¦ UÒÒ” au^%)5‡ÓÎó –¦g)lÐÏR²Bë’Àuch¢8ÛT%&Ápn÷+Á™ÌC~Óï±½ôÃsÂûï·=¦œªá*oÓü¿©-xLmWq?ÎçQÚª-0j‹¯Ôáù2X9™¨…‹Õ¥Aèh2Îçš X“˜XP%í4%²Ñg`ô¹òš}<<¢ÏàtÒM{{l‡‘õHZë{H‰ŸÛï$¹D”å×ý^\tZ\ãŸÚ²¸c`…½¯ Ô1bÒO>X:œL;COïúöL¨ G­S\î4ÎÝA æêÊ;,Üõ-\4ÀÑÕæB…¨©.D%JIFi ŠS •%ϪœuË‘½€WµÀŸt©GXÛ?†µ.RóquZÙW#Y­©£$Ô`c¶6 }ñ-\AZ¸Îv2ñÃhæ<ºžù¬áUwdpóşײjü”U¹^Gï°›dUµTïÕšl:¶l*GS²?å:" ý pJ*ò™ÿTJ©¼{Õ õ³^«_µ-¼˜,fòɹÙ3’XP& ¨™„›´#à/©þ‚_¢ˆŸ¯¸ð曯iÀÝ“Ð<*ë8"Ÿ¶OEîÔ½]³¤ýFpêh‹Íy¸PôP”ìô2\I>¢îqª{ˆÂôV¾ª€}&æfœ¤ºOI`ˆ$Ý…8a·×Ûé\ê1 Ãò !u`e:á/"ååTH¶è‚ €µùèõìη@o’ó/<~Ñ6wOH2[rbv;UÁú+â`“L,©¤”Tx‰8IæËÔñ¸«Ä•r“~©)Žc¸˜o³†¯þj`[Ò™5ç® ¡Tàù·´¸,¸‡%mËb1¸ÛWÂe««HðSl*é|$Í÷<S€3­,½²àcw¯{þ`Õ#{{¼ B'›Ä8,Zƒ…1 ݯ֞ÄëËzûæõ¯÷|{K¿&¯j0x–4™¢äòĸÊõ«mx_êÎìžR®â°fRðu"Óyy<¶Ní–~þoyE=‚. KŽÍ6©äÊeùøÑß’ù۟ƾt­T.\+åwR*§tÌ–_¶Ró\º ·Ëï\ùÒ1ÝØJbhú£ÿ¯uýf€ÊC!øåC 6sïk(Ô¶ø*¥Šu'©Ÿ‡öE.YÿKõ| endstream endobj 1653 0 obj << /Length 2088 /Filter /FlateDecode >> stream xÚÝËrÛ6ðî¯à­ÔLÁGfzp'm“¾bõ”d4 [S¤JPqÓNÿ½»øŒª‰ãÔ‡ê ‹Å¾°Ø],ïÆ ¼gß®ÎΟ‡ÔKI±È[]{1óâ0!aʽUî½ñ_.˜ðU³QM­K'þÅ‚ ?ßU¡Ûf±¾l‹º²s/E®¾¶ï¯U©¤Vv@ c„.Þ­~8»\ý~F}àQË.$q{ÙîìÍ»ÀËþƒž&ÞÁÚya”À³ô®Î~= œèÁX…ˆÏT  xlUÐ{y»à Åzß,hà+yh·ë¢Ê‹L¶uc„ê¨?çɈ I ¢-)%©–ÜÛ@W ø¨=<Šê†Œ‚)bæ_íUV¼ x¨À\œ¾¬Ü˜ªªEžÆ\œ¥þ ƒAy¶–åAÙa»•m÷¦ì‚—Ïž:jZ+d/üÖñ)ª¶¶HÀÅ»Å?ÕM×›V•Êíè AjûzõË" ü‹——h°ÁD×}£–SÁÉbÔ_mÍÆr?W×FêCÙZ@aÜ„ùUí(>ežÛ°ðýàÐ;èž²¥Àýzß9÷w²_Ãüã­{[ç ¤(ö¥²hm±S–*óB§UHã²ßô> JhLfÞ1q´eï1I¹;0ú°ß×M«òµª²öÃüà3ì$†qê××H¸G£¥<""¨Yt«>Xœ yÊ E‡óäFâ(í´„]¬^ñä×zÛb#/CÍ:¯N a ZØgËg÷áÃÂGK]®±`ËŠü‘9þù¨w*ÃÝ>Îö–îîPîAMSäã6Ž×#»Îœë}܇}®÷v¡/£ì#º\ß\{á¶x‡‘°6a0_cœ.Õ/DÛJ¯÷hQ‹X¢t¦i‰ò)ùìX…¡,˜äzô©.k;j ;¶%¾mÜýßÛŽ´½®ÃËP™à¨,6´··BVù1D'Þa¡Ö¾”Îa-¬¼ñ¥8Z’ج‹©z,ŽF™fí];Ð+¹Sdr7@¤}ØuhEö–e'M- ‡;a1PœÝ×Eo´ÑRCô«Eˆ7{¡»O9T½“åÒ%s4ÙÚªyän°ì–Mï}Ý^. *q5ת«el…S–5:íi– Xáð<Árgû Ô[‹å®]ê ¶ø©'õ‘[Uw/ÖãhêD¥u±Â_}wùÚï‚üøýj‘€—Ï~ëj,0â“þ¤‰0õæOwÞŽMÁ©»\õº(!ÜT¨ˆç)vé¼ß=ÀMѺa`ÑfÃlçqÛ¸‹9Bp #¼õPìå…qä&(\p!¢îe£‘ $Nág–÷@NBÅé@Q„màØƒ2 ÙÊŽa rÁÀ.ƒì ÃwÀh–ýïõ»ö~õÀyàn‰Ž½GØÞ,þßß ¨á™3WHBPŽ{ 7ÓÛ«X{u#A¡Ý‘HDɈ–Gl``­3¶ šÁ-Cƒ|ª)>çÍ›Õݳ3å2JI@)6J"CÐ{Ú†v2mhÓ4%vðXÂóØ›Ñit»ÀðpáB@ˆ[Òý‰'th8 €aå!ë1}úzÓöùfFÃÿ”œµaòBËM©Ö¥ÔíZ²LiýEX¶ÍAÙöÏ„­³íßÇrL· ¦@‰F5Ɖt9Ü%Œ¡¿ ƒM—X&ùRþ¬Ÿ0Mí¸ ïR<9U¨ÓºnšEMº¾gÇÚõìiì?û–-{±3„%¶RÁI×ëWצ3x)ë›ºc<=J0ml0ž¶Å¬v]Olð)ìýrÆœý‘Ää+RÑk©ðˆ‘Ñ®yõóSä|ñÊuW+Üfóluùìû×󽘜mA¡Á{n.äP¨Â–Mœý¶Ù¸Œžïת>â…IBRÍÚŽñü»$}òg·£_ CF(u·1‚Í)ÚöéVîøí”ûæóƒ ‰ÂÔZW¸]7‡ù‡ÃçE9ûPâþ¼ù< endstream endobj 1659 0 obj << /Length 2863 /Filter /FlateDecode >> stream xÚÅÙrÜ6ò]_1œ*C}³#Û¥Øqem¥j«²)‡„4\ñ˜ðˆbýv£Aþxù†FDùMoIÝu„í;¼ßð>Oãã)²ì²—[_X¯2IÛ3/™øÖÎ ;ˆ|vÄt¤Yƒ¾É㦽iº$‘Mó\_»B·‘ÕÈ–mµfißv£^¦¶îäšàŽyƒ¾A“,ô­¦;k`K9®ïX.¿'2Ý1ÕîL4é©ÿu<çcÜ`È·´P‹wÛå„w€\¶ßíW2.•×ÂDÅ,>¢¢$;ÆzX¬¡=µÜ¡X›l×õ¦zúmë:V—õAXz‡å”)îûÖÙ¶R«ÂGÀœˆ5´ˆ·Ì±¾âDXYq¬«-‚ðOêÍ%Q}|%.©ˆØM8?™’aÜä´v*BY‚ú<Ð4­èYV-±PË^De\°ãDþ…¤ä»¥ÄœA\k/'ËÎ<~jP„˜ÅùšAi¥2¨ Òº 8cÌz‡Ûdµ¹[òB%2íçô¬‡Ó& Îù(d-Ȫd ú¼WÆèÚ—Ä™ëUœyî©8ólÇ žhž7 4Ü^MU@²‹·°  ÜªC Ë•&½v¼¸LÇ-Þ¡‹ŽqÓ< ¬ªSÞ¶²8¶ÞÀ Ûè˜ó@åÑTg*|Ýp¾n0_ÀxŒQZ½ŒQ¬ 1ŠH£8êc‰ 1Š/1ª6?£˜ÿ·ö]KˆqÞT4ÒÕL¢Ì'‰ã$©ºRûôàqLyÜßêüñƒgÜMR•es’Þ4²îCýE%Íäì…횣L2t„Dç ••C½3É#eWìûDƒîOäO&hÙ»¢ç^/*bÐüõú9ö;LÏáFÛ²@ÏOJc÷ir“¢|Wljðõ›KØß>[ƒR™2ŠÎ¨^‚ Ñ“Q‡~ЃTRˆwyKx—ŸèÅèÃ0Ùãj:Áôùì8ã†â¢h]q;ºª´TrÚžbu@ýdóÐßÔ øøYéØ7¢ðmOŒEW½ ÜsºcÂvý¡$e¡Ž*à²k(ææVd‘ks—OÑ4ã2 LO20óð€ÍUV ”žþ”ØœA9 ç:äaå8g% Û ¢?:W‡VœÕF½”J#5äÅ¡ò€wèîÑ:.öV”‡e©‡jwÅÅg<¡íÇ) \ñšN£Ð‚¥ºãcJ|,„•Ãâ³èú,ˆ³ƒJÖ½.ŸÊ]ñ•>îmCthõBÆzϸßüA#·zí°ÉLÆCKŠì©h„wBq ›/”×õH^µ%ÒO”h¥&£p s©.Ð \SRÕ «+sÝÌl1;ð'>SæÌL自Ñëbòɹ_€+úábïYŸ2Û8Ä4:x}\káô9ßQƒïÓép³ …i¢›~LGªÌ1Ñ}¥Y)eÚ‚:´Ð/$lh³ü©–'Îãqr|’óx\›ASAš^ÜÞÁq •¤q)‰  ì®¬juBáä–ž1=¾ ‹¯¿|¤%…$¹cßBãkjT]Âà!k+va¹‚p®äš¸ÉoúmW,³Óë¦ÕY½fx×vÂp5$f±…HÍHh¥E›µ¶~0ÔÍˈÜv]·´Ë«÷o¿\ï~¼k%¥gCà˜AùJVÚ­üáÔð}ÝM",•­68p§Tht;Œ <T`ùCu:ÏÜP„|šº±ßËycȬnáoÐs¹šÄñ¨*ÀõuҎÛ@ðµ F&Á Û8*…âæ Ó$W|{b®øöò\6:+àåhñ1Wøþh`#Ð+€}‘}ë£ 67ò.®èÙõè|£1_x1#_ Cëùš¾«r-U•ye‘duÒÚÂeböùúVf©îãéŽRP ·ÞâŠû|¥Æ,#ã\ÖÑ9o1_æ/Ì9ã/Ì †æßð>èÅ£¿ ¸&¦ñuøÔæ)9Žöx­Ü;ƈë÷»šÍŽ¢¼êNž+½ãè ¸š\a·æ3¡Èöoó ’¯©€RÕàýYK-[\Ƭß8_Îc—nø¥Eôô»ØÐ³ÅØèLþ /îGΟ FèØÞøÅz˽Ò(8®í‹¨›85Ç€Šø2ŽOöës"øõÏȶC:('ße˜0ó~TW ãÜ;®úa©3kÚþлWiþØMW?öul‡GÓè- Ëdß^ nÈÔÇ-“ÀD  L©àt'Í€ìYÑ4Q Àˆ>/šàµ‡4¿.ÂTŽx¯šÕU éºmz‚š€¼CŧÀ€ºfpû[q6ùj¥7¾R2»E× µ­®JÌÍPµô³…} ŽÓ8¿Sx;e¿ÿ ‘¬AeMVdíP ÑåLÇo¨²êªnž[uSO™µ&¸ -üS?Z[~l[pO}Ý¢t C`Ðç‘õ=©ÂRæB¥Cj5¿2`bÎÖÿÄÝI­ endstream endobj 1667 0 obj << /Length 2229 /Filter /FlateDecode >> stream xÚÕYYoÜF~ׯ˜·å; ›7M€µC‰#–°@ ‡lÍâµ<¬øß§ª«šCRÔØr g÷e†]¬®®úº®nZ«ÝÊZ½9y}sòÝ…+V‘ù¶¿º¹_ö*pCÓœÕMºº5~ZÛž!›­lªv½±ƒÐø÷ZxFZdeÖvÍzãq—U%½{Óg©ü'=¿“¹Œ[IaÚ¶)Öw7?žœßœü÷DÀòÖJÐr®XÁ*)Nnï¬U ôW–éDáêQq+×á?_]Ÿüzb±êÖØß™™ ,Ór2¡ˆÿx߬…eÈ8•M«”г¿»pÂÑTÛ5#Pe#„yM¿Ùgh¹ãW?Ÿ½Þ´µL²ß-ÇMè]¼£·Y™fIÜIfîö’`ù¬è ¢–}PÒsuO IU&=Ò<£‘eG/P6+YtÝT‰l[-ú~íZFÕðú´Žc¤qoðÖ\o;½%š fNÌIå=niÜ縒gÔ0ï% •±ð/ìà_pÃåÚ±ŒGf)é¿vùM˜3l'Û²À ÌÈa÷*«öc™|á–€‘O·ÄxKàm—ô°•ôßÊŽY*"d`»v<@ÁA#‘ E®}Sõ»}ÝwôBíü?Äèÿ) bzŒ æ5L£ø@àºâc,”Ã*»ű!~Ë.l˜Ä¹Ô²$¤}ÒþÓ¾‰·Yžuiü»åYLÈ…ð=;Tf—´zKÄ"ÆmåùeÅ[åà½Ó_­àzÄyÊZT¨ïØ(k:¢D¦©,鹑۪ê@[æ ãR+\Év VÌ2bØdG&<¢mR£m‚14bøéìÔ¤§MúÜ0 ®¼•ß ú2¯’5ÿuÜ ƒâ¬‘M>."}DÀÂã™db ³¯šÓ5½$¦©xËŒl[3¡›Z˜h\áìµ=‰9¤©˜ÃU“¸W‰ ‰hWV5ÛAAE S‚öü‚à C»0R4:4zÜg9¿àü¨ò% –1y»r¦•Çv¦`ÕäáY™duœ«Œéײë8çZl.>•^¬©K˜ ᙡ~ TÇ´Å€<¥&X7]Œ"²¿Å1ßÉ2•*¹DÆvp ­ •åÜLhˆ•²ÓFãøq/ùMÚuK@’J8‘i¹#å“¢yÜ –‡ø¶•†£²‘ÓP€íÀÀ˜h[Ž› ’5”5{×TiŸ(D’c’z“±u%@>ß㚘ç”$ S)€‡C¦ó]*@œX©„4ƒÚåhëG¢(¥P^è6Ý u.Û;3¨ɪ®j:—Ó@oxö('£R$ˆ±æÉ«·}!Þ7UñêXZ±¦ %ݾ§%Þƒa_Xd1*á­b²6kœië¼ßé}l?"Ž´ã² Z^UCfÕ]ÌÈ¥hĸ°ë 9{–¢Û}Õçì;[¦Å¼v¼m«¼ï´Vq·çt ©À‡îÒØ ÇôŪ@žß½™÷Ń÷A ¹±¼Í«X»»;-l‰˜¡î§c“ɘÁ‹T$ZIî¹ä’¶¢– ¿nè“s¢2À÷ÇIÊõLß“ÍÖ{Hv^ŽkúæÇ.篭ïnƒ¸•¸:¦C`ºà<«–”¶®¾¢K¡É.sÉ)fÔß÷ÆÚ9]J”„(o¾:^Æ$7ð§a§Ìzßʆ’ú‹#ïzHK_Ó¼À ÐÁ¿ú´³8†—°1ؼ)^Ÿðÿ ¢†È_@qÜY ‡>UpŸúµ0R™é,tîù +¦åzˆ$ȹ²Lä´âˆÓÜø¨æYT/ÇBH•—÷ΩÜö»—"„'¦×UíÚãPaL<ž¬7®ïÌ`&¨{  Ôº èxâà (TÖ#¼Hòžú¹È%ô€šW<Qp€áIÕan¯•»Æ\öÛÚõŒë«·oL’s&7K ”ž©RB+…¯âüQ™LiR•kÅpPV°²ªaßó´yiÚ|I–q+Õy`2‹g]M-Ù±&ä³%QuÛÎÌêè‹tÜž¼“º©§8›còíÎ~ÞRÇÊŽz5Ž¡C8ŒƒdRµöjp8ˆºtMá|I¿xqyuþ=]Bk;¡ê¸-5¶,ã‚O9‰P/"1¤D¥…*Á¯;¡é»Þ²àçyZ¦>s#$&{ C}µm 9ßLÿÀp♇ìƒY ÛœªàÍŽÿõ˜¯mf¥ÄÆ[M <ƒÙ´Š8fà ™:Œ:ê8?Îv$Šô”ï„BÝ*Ù¼_±.@'Å>xHÙ1ŸeŒ.ÉHΣAÊ?Ѓ³‡GÞ8ÁêŽlt'óÔšjoP÷Õ‚9¡é¹ásöŒbVÛ3Ž“Áž_\×út­ÊÐñŠx¦ÝÃ$X®1Üœ¿{÷å'«YâœõiEœ8ë¼ÏœuTWwÕt¬ÒªÊ<*wCW7Œä+h}$ãÛK/¯Æ§8÷í/×o¯ÎÿÀ¤ÂIŽ’ý(›_'.lÛ¾® 9CCœu/îìü?—§‹9ò‰k!ò¯T~È•P~8š,EdzÂâoˆéô®EUauïV¼¦ëßp.¶Aøêv©´¸pÞ<$ÕV~Ð7Öx}ÃBé²ÌЊѢPßôÔ$tÿTœú£``¾»;^Ó óìÿ…mZ¼´5Tãv/$•ÓG‘±é~’úI•T¢"©¨¡µáϾ‡—ÉŽêcLjGwŸ£–gòµc_Ð¥(0Ú"\NÛÈ­´hõ=ùûá¶qy½ N<CRê¹CBÕCÞ{^1^¼‘û@àÕÕPg¦fàµY–çÓK«lWVL§a0ÿL깦íöWÒÅ»®m Á§ŽhÙ"4N÷q½F˜x‚аÁ ߌӪD¤výü;ïE–Ëv®îŸV)ª endstream endobj 1673 0 obj << /Length 3088 /Filter /FlateDecode >> stream xÚÝZÝsܸ ÷_¡‡>hg²´H}»½Î¸¶“úΉsö¦Ž/s#¯d[vµ‘´q<ýç  ¾VNìä2Ó©LŠAÁu¬[˱^íým±·ÿÒ“V,â@ÖâÆre$¢0¶B/^ìZ‹Ôº²™)ßΪë¬*ëÙ\…‘}8“¾®òu^7ÕlîÛI“—kê{µÍÓìÕ/²"KêŒ>¤PJÈÙûÅÏ{'‹½{dp,i… ¦óDè„ÖrµwõÞ±RhÿÙr„GÖ½¦ZY^AYX—{¿î9}ùݨ'ˆø„ÒŽ’ø‹;@‚7¸Žd™yó@-I… ¹Ý®²uƒ-¡]o²eþ›ãzYM$Í㣷ë4«¨z—/‘Õqi­²ºNnµþj3%wå-u¤b6wäÌ™f•Ì\Ç~ ^×LŸ¬ÛÆÈ.ov¤ó»,Šræúö}¾¾E=ƒ’æRŠØ÷I½%ä(Š”]o7›V=M–b›k_óLدgÀÆúG× öoŽï¸ðOÅ2) "ƒØÖƒaÊ>;õ;õnª ûùEÛ¸½}S+b/ÉâN.ÞÕ`wU$ÂÈ5D/&øøÂuoîrCiºÇ‚¥:k±Îd.^°ýv[‘Nœý*ûˆZÚ‚Y¤Ãp•n<pßk³¬˜"¡â|ÍñìW“¯øë-~%u}6^š1fžŒ"ûáTÌðâðøôÝ¥ Ÿ‡¡>4‰VþÞEí%ÎF¹!Ðh»{ĽU³þ5¿Eâ·:ݯµµ6Ë…×<ªwc=ÙÖàb:–WóƒdˆleÝT,mSÒ  ²s%Ò½¥éÔ·‘Xuô­Ž¡¾»'z,Ú¢7xnX¢ýbåšY$Äò®¤adðئJµrƒö–ôÕæîðšèHÛ0Ì7Ì0M+¸[ÍdÂP{,a ú,ñÛX[Ò;ܵuþ™ï[å*ÉÙ êr‰FA–ÁfÈócæÂué Ò5­‡ÆØ@Ù)åèxó(ÂÔÑ 5nÔ !^k#u‡I‰I½— ÜA´^œŸ^Œ k B€ï©öŽø¡ºö!<Ûÿ nÅ_,ñ,mâª*}átWUñ%Û{3†ŒMxY¡ÉdY¿ÑŒUˆŒ*ù:ÍÁEfÜžPA7t6,ýí;½ì56uSQúKpm½Œž¨üÎ-ƒÕ‡ÒýQ[6•MæµrVXÞ€F)Nßc÷D[2Ô!>HÉ+».l\Û†9Äé$. 568PrÆ »Z|€ÆMÒ?+ú|(ÉçHÛ‰´¾+·EJí˜~I*j×ÇÚ˜¿¯·¶jñzŠ|Í]è/{´žIÔèÎ6ÝíySgÅÍŸiÉE–¤¤œZ㥎òâ‘°$08XzIü4:Q߸Mh ‘°‰sK>ç– ¥ÊVÚY‘á³HàIŠû,>iä(¶< –6‘µu!fQmþfèv“Á£0©:`–„¸wh‡í°gŒvz¡Ý Ž,¢3‰sp•á4 3î¶é®„ñ5[mšãÂÙ> NŠì;Qmª«7\v0«ËuÙìø[ÆèsP4G&yÝyu3’à¥Çªå|öZÜê¡^±M¹}6Üj7‡g É(ëYQCÊàs𜇠ì¬}=±áÁ´à@Êté–t@æ¿Ë¸å£“Êz¸9¦1>‡6¸YLZR©QfÙŒÆ3(Lœ¥É0mîŽ{?6»ÛmyX¨” 9ôÈ,“eUÖLI¯vPCâµf¦‹,/îÖõkæQdu;YfÖvª¾¾4K*u Ž•Þ)&!ðdÕSÙ¦ÌÓaìÌêøZT¡K¿=5¸ÃϰRÎõs…ZzªµçÜ?=CÃìÇÍëíê:㫼1gl¸E]x¿J€I‡5ì¢ÝÇäÀðÁãIÛ.ô¬ÏWr ºÝüNªNŠÕs•Œ~B…¾ª0`eCSû´5Èð;"ê§Ø™V´DMûÏÓô—­GÆ"54wËêO§2§SO§bŒå”ºnr“zRzûÍÄÄD‚Œ—ªÓ¥ùbª;î^ÃK“b¯­Z¯«†÷mE÷m&evùfþ¡¨™˜ò/*Qàñ´[9Sä›ÂÀ ¾¹â! èwË ùÜ{2øa~RHOè œB¢‰èàtý´¤ÂîSñD^„«€3ýŠ˜˜q«²É¦A“¬>7wáã·èÓ`$õÅé©OAüÓ¨ö±Ë>}¹Â¿…9ôÂÓ=…yÃg0Ïuæ5ù2&]_ŽgR¼œÞ|{ýp¡OÉ¢ü­Ž(o­‹ÿtãÔNP‹/!}â .™ÛZ¬èv%–åê@FRMÇÄtïé ¿P'+ÀŸçx_ï¯M8Àçë­ } b® }K6ü+ l;›2þí£ï <ù§»?ÙøÃ#ÉnªúâÛG î ŸB «=?ÐûÁ.Ö âXÿ„Ó‡ endstream endobj 1564 0 obj << /Type /ObjStm /N 100 /First 988 /Length 2417 /Filter /FlateDecode >> stream xÚÕZ]·}ׯàcÒyïåW±àÄp ÛÚ~جÛHº2dHÿ}Ï¡4kW»’ÆZµ1`-g†ž¹¼÷Ü2¦T\p1åê¢d6’“dld§-¢Q‚KE\¬Õå¨|R\î]йR9ºD×ba?¡ÕYì#¤4ÞÃk-U¶0ÚZ¿‡Ÿ¬lULQÔ‚n ýkì½pU3'høiýUDÌP͉dªÀlXkzíýŠ“Ì©pKÄ‹)¤¹„€FèœÅ ÐÐzÁjŒü‚Š[ |(…ïoÕ©Yî ž§E„­è´æÈ–8 x€–:‹D”ƒ9"Ê1:ÃÍ™@ff$¼i‹$gIû+*Z”bŽÙYnýxZsŸ*»´™ ¸)ÀÅ%¡Ì¸LÉbž¡e.áïU—rëïKXP%tL 1ö§Í¥–÷ËÜß,-#tÎ+ï™Ë]¸†Ôˆ9 ¿\¸`”kêO¡#­õ±Å•(ýiuE2gÃe±À÷ip%uôš\É…cU\)‘ýL¡`R8Gt¥U¢‡,k”°ÖŸ*‰c-¸ª­ˆ®®ß‡Ïª¹ë™‰«¥HhUå[¬¸Úº¬¬BwcÂÖ\*YNÁ5m| >¦%å áa*PÈ¢qIð ZŸûü„—ñ{ j|6¿;¡KFTá+ç`÷ ´´œÙA»jPg‚U~Kx=üuø~øîUìv…OŠ!y¡Y4/d®–=Ø‹Æác!¦']²/Üð—ÅË…žº¯>bàûŵ—àõk h]3CÈ.ÞÌ,­øõÓX½BËÕ¢o 4•æ5Ô×7Ó¿exrqÑgžôÙ‡ÃÏ¿çÿ¯Þ­V>þyÞ\®.WËË«_æKÿ~¾úÙ/–o‡7‹«áÝê߿˟¯À;êyñõï ŸBô }åÿñÏÁŒa«Å“€®?ýúëëû;‚ý*„-ÞêxŸ6ÞÒ¿-Ýü\ãÒÍÉÚXÒ]m,:]KÜhc)cCPËýÚ t &Û[ð T`ªTñÚ`)åÛÚp$è¡(XD‹â•A›/p~&ÑÇÿ?AwpŒtšôÑ9ûB&´z&ÈݘŠí·º{©½ÐDÒnÓzÀ˜™hÑF8Ù´jØaZõ@Óªô¶XÚd´ÕQQ ] ÷vDPèåËYë3ÑN_‹wÅWÛqâûœ™ªn©ÚØ=gÍcc$­ZOêK[òòPÍ^¡¡‚¿™±tñˆÒwûÒO?ݸS»¼×Ÿ &… n²0#¡>ˆf%6ŸN‡¤Ï`Qż‘xð·R,š<’}@ät@b3ßilˆ bÙ‘èé¨/H0`g>a‘,Ï0^™èô°ëh$H¥<3. 2á*d$üà£U¶ÓM ØVGDSˆ=ÐQ«¯HövÔ}ÞI‰·:JBG¤VS(qË¿Üò='ð/ˆÄï$ÓæÉÙê†üÚÚ-ôÜ~ÓˆcCÆ†Ž ;)SÈÙ=²Kès/qtù#ôf»õîÃåòòíòòû?y+'$… b7AšLCPøB³ZöB©E@ÑM!…·-©ì…ÒJ5Bá”YT:4Äüû ¤ðP‚baza kG–e¯PR<%WZÏQ´µÕÈ3U— WÏ©)4XGËÙY¦‚KϼFXÍö»MÙ¬ýDÙÛÁ6öwJ t?Á¬!L‹K·iw+98}Ìšc¹KÉ1M¦dúß Ëæ±±‰P9~Ó™8ž”‰54Ä@ê2c#¼²ñ S‰Ô¨gŒÎ¤ z†òeØ;ÔE“€FààÃ[8gHÄLØ 9Ã9A-M êÖV‰‰NÆÀz!C*Ò<ÖÞ’éˆü%#œïe‘³ñ°Dó¬Ë&úèÐ7|=" žJ€Ìià£÷5âÀ%¤Ì2Lë\h¨Û…¿éfÛv˜m™n¶iLàÒIn‘ME&„QÜжš¡¹§Ñ>£#îÛª°ÒÔ3"¾Dþ,Ÿô§ú‡IúóŽ:pNÓU%á\«¾y¬úf;-ÃCIJ]§­tÉU|}HϨ;’+ÒÖtD‘µ1–s–Ÿc‚öž^F;Š "Qgš}Õô?‚Щ;‡Ã ,†h®Y9>?Êù@nßênâyÀø-ï4§sÙi•/ˆ´òW•Ïâªÿ….½ endstream endobj 1682 0 obj << /Length 2803 /Filter /FlateDecode >> stream xÚÝZ[sÛº~÷¯à#5sÄâF23}p'ÍÉ¥9‰ÓËød<EÛl(R!©8n§ÿ½»X€Ivì8ÇMkψÄØÅ.û-2ïÜcÞ³ƒ?üüT†^$škïøÌ‹¸É8‰ðŽ—Þ‰ÿbÆ•Ÿ7‹¼©ÛÙœG±8 •¿\UÑvÍl®ü´+êŠêžmŠeþ½¿ÍËžõÖ#¿ ß»šŽ †[%d A n´P¶¦×ÂH W’Üêp[ ¾ÅUœ£9ç: XˆO­¦Pkãò°$†U†"ˆ%xUš\¾É»¦ÈÁ¡xòè¡Ð™ï< Á°ŠÂ:.Ö§Mž–«Iã®Ùä¦ýœƒU9Ÿöú7V™¥7ŒƒÂ`¹ f—Þ! ¿X­Ë"+:*-ó3\a馴„®þ8ãÌÏmëîjÓ[•®`ÉaS¥• BÊ)OŽž¾y¼gP"ºvEëäÿÆ„¬0`ñl&™_7T¸¼èGqa±Î›™Tþ| M`”E•ë´¤:ˆ+Èë|ÓØPhø×¹•TÕVÃvgÅÙ™4LdÇáÔ¦)4äáÄœS0%RûÏ»–h»2¡ŸÑ žíE=Ê¿´äE^Ry1ß0Šü¿ÏB¦üzC-VéL0ÿŠX›¶Ÿñ'Ge•oU^ævtNÎdœ¡›2qmR¯rh^S1]£¤‹ÒrŒ}®LaÓìõТÛ=Q0þNAXip=xVa%ðgº÷DH¥£dਤm6HìI›ûBéö6°cƒ¸ìÂýªß­€%yx`Q¡5´-rH Ô ¼”‰Ygl4ƒí†¹­)îƒPÛÏÄÂ奥ÞYùi&[´:©»õ³ö†ŒÀ(ºÃ¨%Άû1ƒP`ŒÞ‰²qîf‰ÿ¤ðëð{H:KËökj&A;®úŸù§Dµ•ª÷`+bI<ß¼xþúù1%Ýõz Q³¦°fžPˆù§È8IÉ“ 9ÜNÉåWRršd1d™pH[ì$¿Æ½C Ðãwù£}P +9äª ø2Î¥E1‚Æý´±õë°éæ_3ª¯×Fy@<™„È­Í©â³É<ÊAhè?ÀT.,Óž›I ¢¨¨âäã2e/í;Ë켬&3Ú¸ÙOäVʼn# ò˜ƒj–ôžâCøÆ'šae»Y´yf÷]P®Ïèybš·PeÐè°lkª€$§·î"íˆuJ„ýzYãœó >'hq»æ¥|Çʲ*,—Vfm¥ûÀvZUnYf´Ûce$ã4ù(*„ O1ÕyÚdèdT®›%%1À¸µÉÃWÝ_BÜŠ¸¼«ûoïH·Ž!Ž+Ó8à*&­Ã`'b0¶o2P«ñt£VgÖFvº¿SV” ‡‰'vtrç¬HÆ€áh#ƒŠ!ÆG&m|¦ƒ=ÁÀ`_§ ±Oz–CÞÐË|¼èÿXïdFÉ·m¹e)‹4ƒ…e‚ÙŒjJ5½Á æJ” E—õ¼03êÅü𙬰߹€\%×læa{gFÃ^Þ­ôk¤£¿¾zóòèi‹¿€üÇ~õ;'XÔ§i•]ÔMû]„=}þòèÑ]Ôþy[íMÛÜ«Yg€÷÷áIWë2¿×äeõê~ý›nO¦ª'™ªm½}è#Dm}l¾ÞöCý8×@ ¶(×9P¿. HüÎà«. ùÃö@Ov A°hèIüúB{ ø±Aރ߫á­À/yxðãÑüx¼ ~‚Äf­3¶ š!vàü~ðC` ÃÁO0É-øÑú·kõï†-Ož¿ý_‡–sŒ¶EvÚ5›¶Ë—§YÚ~;¿íÀ/UóxøŸâ‰píö\UÄ ÔU:laÒE½é¶â|{Uué—éO§”Žöñ†DüŸ8åÌåEU‰5i·M4*Zô&A¬wüðŽŽëÍqòïV”ÙøV]Ñ] j R¶žVÍ ª$ˆÃáJ¢ºß¸C<ÅîOM>6 d5 é†à©ìl5œáÌq;¬`û:‡u›±½ÚÌn»_qûÅÙë I.ø®?_1ËÊú¼ ×»;eEóŽÕäD›væ¨Ã¨Œ÷¼M óà×¹¼5ÔÌÞdtîèÀɼ¼(úã‚ñ^~®°Ú¬¨@sÙäÕywaOJÏèù{ë|þ§¼,W©ý¨–?LDSoÖ[L­“Ä4 ð¼,Ê’Â6«é™fY¾îè}ˆ†P »3g^ äx¾öÈ'ÓŠòeôž0öÿ2K n–ÅrŸ MŽ4•¦ÃJ¥Ü’PI$U»É–ŽQ>5Rè`š†ŒKˆ®"æ>g2¶¯oP ˜imËàÚzR%b×+­–Ä’*Am¼ÍŠ˜ÞãÈ­(0˜¨ª‡O9ÆC0±y$×ÀKµW€\Ko¬VÆð—ÓGÓ²óÉÊÎ÷7:2ŸÆF<°é—§›uukWÖ{\YhmÏmé M§#ò?¤¶Mï¦YM­œÿ!Í…)ó¾/&ãÐÕJÒþ«"kê¶>³]ß·yófrþÚÌáÊ gèý›×ÎxÛ¾ún³øìÝ ¿Nüò³ÛÁ ‚>1cMì<±ò|‡µ‡†o@T´àm•§•}¥ªÝ Ù`Zø‹¢ZÒrÕ6ŒkAz1Þ¡ã¡f×r¶k=°Ø£ö ³ÞûO©ÌwGÓ Œc‚ÆÛ§Ú“5²oÇlùQ«²Í‡u3НÅusK‰—Ðö"ŸƒM)âãÚÎPOæ3W.eI¤º*QÆ•úÐ&®q'êl¢¬Ðãb9wW6&ÈB«´¥ªÑg¦eŸ…x&…ٌűM¶ˆowÖ§ˆ`ƒÃ…KtÞ>}L|¥Rú¦%)yEzÈæ‚Ç8½Î“¡ lº&ì¦!ÛØï&`­õæÂ©­wñÕ÷²hé»,X?·Ü äzÏÇ>Ý9$1@þ›ܜ#öÚ•È£A=xo'ˆ 6¼¤ë'¨:úÒåÕÒL4”^LÀï[û qù½xoS:`4‰CŠñø"5wÆ3ûí$%[&þãþƒ£­o>ŸeÞn÷?aQÅ endstream endobj 1688 0 obj << /Length 2045 /Filter /FlateDecode >> stream xÚÅYÝoÛ6÷_¡·É@­’ú²õ˜ei×¥+ºÔ´E!Kt,D–T}ÔÈ¿;ÞQ–l%M›{1Éã‘<ÞÇïN´°n-a½žýºž½|åK+r¢Ð ­õÖòäÊY-#ké¯?ò¬uj}´¯çn`«z£ê²™/Üåʾ˜ËÀN÷Y‘5m=_vÜfeAs¯»,U/¨£r7ŠÒq]GÎ?¯ÿ˜]­g_gd–´–.ç;K±´’ýìãga¥@ÿÃŽ­¬ƒæÚ[~¸‚6·>Ìþš –_ ïzƒ{D¡Á~K)á-éwÕež©¢½˜{ÂîÚ–Älñò•·¬w¥É¥µÐ­_ï2¼¾»²©]ÚíN!U[ÔQÜå-¾éaÞ)bŒ‹”èM¥’ì“ð|Å[µ»¸%žD GÔDVa‡Vó&q«øÄ}× ê™mãU¾Í=0ÙŽOÌÒEuöi×ïO®­¯®ÿ¦NÜ @£»¦ .Š;+HYŽ+C°‹ïEhÕʪA{gÄ›×§æð]GAÐæ7¯.i[?ÂǬË"™eÎ ëè„…¡³Š"è,ÈcÏm’·å­þé–~³Euûå0dt$ö&Lµ—,³Ó–ƒå‡L«XÈF@ú3K ¢Ê-/ý°y-/ã:%Æ^ —íO"`ä}³¸«M²ÈËÛ²¢œ2ç!ËsRùFQ'‰ªZ•>®Ô^9e¡~J¡à¥z-ôBÒ&PN´éi.ˆ§×+ðMë&øjzó–Öé;â •Jæ®°ïðG»3L´%1RäàÆàâÛ{žó@¤ðè$Ä`Q\Ð i0Þä|Z‡¸Ö;5eˆ®aý—[j[¤TŒ¡oL£+A§VI¹ß«"ýžÅ|ˆ×[Œ€à ÀrÑfíý£Æó5nŽdþ0Ä,¹ ɱ“— ?ŽðJr§¯»üeîƒiøˆˆº½(4*¶s@†Øë-Ažtsõî•9)° ­V_ç@-«Ñ²z«-µte¦±Kj7,^ÓUUÉ^ë'¬µ1Ž  Å–ƒ[}'hŒ'LP¤¨ N}Ž \Ÿ½Ð‡ÌÒa¼´™1ÎOÑ,ÚÛ59É»T™Oî˜[㤥IÔ&Îmê… Í'§¼²<E¡ùÃÓ@ø#]‡í¡OX7¦t¤ïˆüóUe™?ËrP^‘Æ= ¢É=ØfEˈ´Wiª$ò$þá.‡]F8G|½nq°áÅd+äÞ fYz4SJâ¬U›£{¾–äêKͪώ)ÇžÅjx RlŽ˜v˜1ø ©gWäEE:Z=Ã8H\(àõ0bßXO¢ëÑÿ ñi÷“ŽS#L)Ê$ˆtw”OžËÀTÁÀ•p¤sËÒ·/§ ó7ºžÇ×Fkßf} #Œ­Ë›·:f4a ªY–’Ýð!ŒÐëQt(±ö9ì(Ý/ƒÓlœ·#Ÿ I =s‰¥: sj_7L:Uó¿û†;á_QëÈôàKRã0ÿ2ª`X!?â1kBwyò„É`óÅØ<ÅÀ-íª.Õ44à zq~Л“æ\ hØk\iÖÖÄe.Ër.¢€\O¹%Ðð; Qö‘v£x JZR£_0f1éKÃË‹p¬¡Î†K„#¸†t uM 15 “Áaf¼‰Ýië‡5 HЙ4†à$}<"ñõ¶’>ƒ´ª ÚúÝã6ê4æØÎŽ£8ào¢À5uª´ólˆÊ.ça24|˜ ÂK;D­˜·!RQÒ˜‰Pժဖ â’¶1‚4 O Q/øäB—v'é¹®³„:Y<+O"pav)Ï  ™%oôÛ”…A²‡¬‰ØÓÁw†J _´aéå÷—RŽíý^ØxŠïb4œßÞ!ƒÿöòî¾ {Ò÷]Ô'k†ÊåHg»û¢gÕv‡1Ù=ÌL¢‡ø`ö7¾Tã¨LP¥Ô¯]#{=Ñ.ƒ(;W°x¤ x††=Çèb 7»²ËQ›QD‰ ÚFWîÐѨÕC‘Ñ tª2Ï’{žlx“®2Íóž]µhËEJpc°¯¼J „1aKªfáGªÄò‰£Ðœ„ÉbÏ,½ÆJßRÛì ÌfϪÂB+ôfhÅC;ø4E‚䢤s?É`S³­`ÌJi§0+¨}ýæÝ›5mmÎRdûaÄÉxÇÉÃ×ÉO6åL%úÎZ¾³éâû ‹€ŽJz4<%êGÃÑ[toU£”„¸*Ê]÷Õ˜ytnï+õ¨%…ÞÎ ù2…)ól#8Ÿó­©R¡“à“šçßvuŸ_})¹6¾†Ÿ_8˜½!î˜&òc] D]©UÑu@S‚âéú.š/‰™¶a(ÀaF{Ê}/ë~“9Í!ým(Üòœ“†û@UDX)=›$fü+nµ_A÷êLhà5BCw×Ç×6ÇLÿ$\A©*¾ƒ¾äÙ"=N§ @ ’Ô0@XèBÎ ÐòD`€_® ‚M–ÓW6]K*R 3xL›rô*u ½_þuøàÄOþçâüØÂw)ù£º æÐx-;ÑEZz¡ôt"×5ðïE§bý x_œñ endstream endobj 1693 0 obj << /Length 3116 /Filter /FlateDecode >> stream xÚÝZIwã6¾ûWðH½i!±ì9yÜKÖ÷&mçÍ!É–è6Ç"¥R;ýïS…¸‰²i9‡yム€@¡ðÕŠŸ|¼ø×ÍÅ7”R–šÈ7wA±J˜Jep³~ XD:ÌëÛ¼Þ6‹e'áåBèp]UÑìëÅR‡Ù¾ØVôîã¡Xço¨ý)ßäY“SG°(bbñûÍ÷ïo.þ¸°=m§XÌã`U^üú;Ö0þ}À™L“àÑÎ*exn‚닟/¸c}Hƒ§ÌÈtL#Nã> ƹèè°4BRø8¢f˜Ô©á˜_±$‰ƒ:îzlœ$#X˜T’‰'$”`2R€wZ)YYȤ/‹˜¥qT`ÿD‘<Öy#—«ÛղΒ‡Ò!€#!ô˜ÅŒÇz6+‘H™àÑ—›…æ!¨@ÄÃb·AICÿÝûkj“Ô(·k÷Îól;¿qͱŸgÐþ$ $Ÿ„9ÓÉ¢‘d©˜hb˜ˆÒ Í}&ËXÅ4t_fn øzKÕñ¢åÃú9Þ[) Ù÷R˜É~+„>ÿ/Âc±¿§Ö·?].´¯¾¡£{¡¬ó]¯²}¾î‹å”‚‘X”a&Ž_)18"+Ë›H›åjßt’X¦fJÝT:ƒë{ÙͲŽ!ÿçÊ¥€Ë÷×À!–®n®O‹!5ËÛbOíëo/Ñá.ÅPBól\ll^+™0É;!ˆ(yZf<µöûBxÖ8†üŸ+„þPÀÆß+„'-AƒƒLôk… ”§,A&j)Òè c€IÑ\å±|.î}žç+?ãx8ßú¯cÅRe^½N9SIrRÿ\Ô¨ièÊGsU~Äò™Ðxž¯òÈìô­Ô^¦õZ0._ ½1LÇúzu·P<Üê…¾ÿÅRÆqX¯TÛ3Gó¦|“•]¹Ö³ bxšs¥Ò?Î'äñJŒÀ?½ÓÏà§uxÑk "fÀŸÀ2_Hþ¹[,W­ ÚÑ)›˜¢¢è¯™e(Ãó+’þßÿ¹ÛbÞ¤Ã}vë§Éi*{}ÚL¸„A¿RJ"a±v‡Xee¾Ù™+4Œ 9ŒæÍ¶„!ÃçÂÞçøÊq23>\½$¨8…ØÿJ|TJ‰áëÃÀ¾frÞ\µ1|&¾Ž[|ç«—¸yeb(Œ_YÎ*¨RiºBj®2w?·‚lsïÙŸ¬ î0,fe±ÁçWü÷"”£Âq–z*ÉÝR¼B=uôE›rÌVµáæçªZwBOIÌ9¨1 V”N%±‹¥±šÀë"¥NÕÝ[\?éÚŽã7®©ÖƒbäD÷¼ÚKù•z­ÞK ˆ;è vÎVûáîgë}ûVïñO&c³46×QúZä@I…yÚÙz?dáløú<´ðygû ~“Qz¨¢§Í“["f‰Pã«JƒG‡;Z¨(²Ï½1OÈpáqHì¼#ö>µúŒù惑½¥‰¥'§…ïÞX$<¼\þòã"Öá ­l§b«Ô¯Yemvë6=4ùšZû->!CÍï0ÍÌëþ0<=›ëœDvØìß¹klïˆÂþë.ohˆ, ‘øb ¸“º<† ÇÛ ÁÃCNxÛŠ¡;Làt‚óÐÓV-ÙVƒ ¿+žÞjäÉæÝkóÌ@)8vËO=gÐòœýþ ›¼ÛáNÀ8ûkYæNƒ­)ÿš‘ m½Ì“ð>sd \\L­2Ï*‚ :~Þ-ÒÐó¸·ÓZ2¨qÔò¬ŒÜ j‘H˨c˜ *T·¬„,C HB<¦³¾%q"ê™ßå/?Þ,–¯\lŸÁË9íW r¤—ÊH(sã!êÈÌö°AEòƒ'CÃ3Ò¼±†ϼZ9ðwîó’鬚NìÐêBÐéÍbçpaæ d$T<riÞËO-,£Ȩ2Äâ“ È1Ê‚`1•FƒxÄS‹ DŠcd0uçäö§“ÚÞô±çÀ·[÷ôa\Iµg­yAT–îóàî ~ìÞ#Ã4oµ¥w9<áÕ5ØN­Öä„aFG=r½:vŠ\·s“½6‡][îÛs c³¡ÑЪº/žðj»Ëkû‘³±V[`œ§Ä•µ3Øj»?½ÙmoÅ—6*µCÛ›çÞ5¸iƒ’áᎵA&6%³×׸òòßßa? ô%8zÿyV&Öñ=Ô·z i4F¢ðî·vÞ÷kÇæ—bE!)q›•óq2òlw÷ìánÔBµÜöÔ¡‚A‘¢‘ÒûÉ gNƒBÞ:Åü\ÐÖÎ ¬èè³;ê ¤Öäól¨¨Fðû+j¬³}v›5ù¤5`þ3¡¼±½ä“·Ä#íÕ%úYcÐÉØfÑ;>6í±yä5Y„Uî?ÔÂhá&Öí}è&´ Cñ‘ŠàÔ¡Š‘‘ŠÀ+xãTF¼ŠÖ+΄Ê¤-6åö&<°?& õ<™—]€FÿcªuÞr‘a hǪ`<øéãø £PA&qÿ÷xЯø¯Élð‰ÌHü½•«Fªt"{˜–PßM¦É$ißÉÂHÑk7›tÍŽÐ÷ÚÜÆ®X;}*º Ó\: ­]Ö4[ëuƒI%pÌÍj[–`?Ž òrv¸Âòó¡ö~ÑR¬!yÛ;Þ0Ë&ýOKe¾²áZ„Ÿ-”UÞR2N©á9Œî37n{>l†KAaP=–(— ¨ÏYÇ„aR/‹…‰»¬¨mœ‚„⡲ÁýÑ1—¹x "ì%<ÆVá]ÄCþwpzá¹äát¬5Pb·¹ºcÂ÷P¸Â±î§hé"ŸÔ*¾Ò‘qÄ 8Ìôô8:¬lª-Ү͆Îéë|ãã-¶3ztˆJ¡€Þ@•˜)K)¬â$k‡ø¾—„%éúsÊMÏ»N`$ð‚­õþo§È@úØVµ  *øqÕôÖPE~W­‹/Å̇XŸÄ_tUöʼ¼µªŽ§´fhÁÉÑ ö#ø¬@@• Ф£k7´¯î[êæ\ÓÓF¼Ö°ª„Wκtç®›]¶Ê§¦1º5éÊÍÇåÍÛÖ'j¼=gœzõÉÞ¡ø‹“0AFhÉbm–üà] â®8MuWe é~$†ÊGkwC¢bH<…•´Š{y–’Qo@«þkÍâþìòv0fJ›8í(âç;­Û±Zɶ³ñ¶#¼#Ç»íVx³y;ŸÜžlõ¾»àç/Ö4]¬iv^#臇ôÿ¥ê† ÌG.Å.²xi÷¦ÅË^íkí€v]ôÌ&éÑIoè:}\ðn2Šsì¨ý äèé¡\š”q[ÅjÙ¢ýxkïÍèQÎbà‰P†¿-uæ­nÿÏr3&‚_éÒb¹ 3¦ª²ãP;¦eæÛj[—Ùæ åîµ /O)Vê¯Sû©t—ªY—ÿÂØa‡OåQ£y[zÚ,ƶÚÚ3ß:ÀÒÂMíÖËnréç]Ë©$MM¦€²ŸJ_kH]!‰5ó*|È:âô™ ¼BϺXª?ŸFGùƉ´Ý}\:4TÛà%þ> stream xÚíZ]“›6}÷¯ íCñÌZA ÈÌ>¤íæ³íL6Û¾l3 ²Mƒ8›Nþ{¯>ÀÀ’]Û¸›L“}X$!]{¸º[ÆÂ°Œg£Ÿ.Fž:Øð‘Ï3.æ†=ä¹¾á:r|Û¸ˆŒKóÕ˜P“ç3žgÅxB\Ï|2ÆÔŒVqe>žP3(ã,U÷žm∟¨ò9OxPpUÁˆ„Ço/^ŽÎ.FïF0X6\Ó9ȵ\#\.ßZFí/ Ù¾g\Ë^+Ãa\ãÍèõÈÒø·60ó‘å8†kùˆÙ~×뻵!âÚÈÇöÖò‰°'.ý&²©-LŠÕp‚<Ï5rnÌ€>mËC>Øb¾´z•-Jm9ÆÈ§´kK:ÇöÎÁ.EÁ`ÅC–ç(ç¤8€Xæ*H$µm-¢ Á°"¿‹‚€[, W„¸C±#âs¡’`“”‡Zæ|ìX¦ÄPÕP´ü9ö„¦ %h zO¡÷ºèk=‚¨cåÐc°¿æÉê>5móׄP+®ˆ4CåR74¨=Q-×q¹Ì6šèM§ UT«Å8Ý:@ˆC>Ÿ÷è£fصõ«Ôuvµ<²4k¸iñ|¯NÛ8æ¹ dSpÍoi7êú]S ÷]uK=Md(«Œ ‚+ѬyoŸû{uÛFp0ŸM ¹7¤<ÊJ¿šÐ ²Õ>4©pË(ƒøêvÃ-F¾…±4Å{Ʊ( f‹-‡a#»ç}Û%l]Œ8ˆPEÆ›`%6Ãu¢w¼«(Dar’µ§1´K4ü¿–1[6ÓÆžóœmËüqìPS /ÐB„Ôü0ÆÐ²R³ AÏ[hLµ¿,ÛIøcíL(è¡{Õëî»u.½U± ŠfÂ'Œ"Ë8h¼3„WÅRKuëTÕa«ø§”ÊæjÄ„ÅÞî¸LßÀÈv@§Û˜£Qsˆ …?9~ÛJ‘C$/µM‡0Ýq;é¶-³ÛZRÏZ7Y ›VcÖj6 °ª!úbɆ_Í:çÆkC<ÒT=Ò$])Dånêÿ¾ò È…M¤*°D"y£úNÍ[Õ x«j°ÍxUw¯a ߘIÔ4K-~$z¬$fWJy¾ê²s­(ˆ‡áŠä P^eDb^;"Q×G˜E.! @!’‡â­xú "¶\aF…}Ù :MÈåy•#8ÂAÕ?‰»ÕpË …ÐÚŠh°/©èfW´Ù²èy­‘"úu•áús£šô±u)“…;è|rñüì÷'{€6Q{ÚKó·ƒÆŸýòÇ0Òtã?ÛE’އqŒ¦ë,/Ì?®ã÷ˆ)P«àHfÎ &]æ—Õ»« «ka5ØB!½Öy¤79¤j×Á,áË’Û ^âL3D¬|zÅo¦åÍšå) xA(Û' LºXò4~¹ ÂAŠe€7°››LŸÝ¹«›µW<šò4Þ)¾¹çsºçÒ|œf¹xuUñˆ‰÷5ó¨’=è« çâH ­‡3Ð ùÝÄöD´%ëaN“¤ÑŽüL‘¾ë8ë~dû8¶“‚±«&þ´ÃEä´!{ö:iE”Á,(øt•E›ä8á3[ó4‰È&áŸ<‹ÙÛ¹N >6n2"Þè¬/É‹8]Ü™EîÓ¿ž=ÞGCº$oŠ|Ðø$ ë×J‡Yx Cp•Ïè~|öØØo<ºÍ¢oƒ—yï´àù{žó÷—äo陣¸¼Ž 2T šÝ”–qæJë˜B°)ƒ8…|0J¢•p¯õöÐ\C:Ùî[¶Vq9Ô6=t×l«-à²{ûqæÕ»C4ƒsÓ,ò›£Lt%`÷…˜(.Ô! ÎÓb†¼8N¦ZæÞ7¡Rm–©%^†Cþ1[ lµl~À@Ðÿ)hX>è ¾S¥ÁS­£}õ"‰ 8|;¨j‘©Žk7?‰ôhò•˖˸P¥lö7KUN9ts™©ë2xÏU)çA¤KñbYVÃÓ½Qv½[CÚN$>vÉxRE§Á:Ó0^W™y±™•9¯ŽKõ÷‹VÞ7ùt8Ô¯Š¾‰ë`q±ã‰«öñu—ü)8‘œÅ!Ÿ®ƒ¢¸Îòh:“Áo»vx+1áåÀĦúéÄ#š“AéÑ¿©˜ìÝATR|œ­J,¤ÅI6êɯ£>’á J‹érÊcœAöxÿIû¾tŽï[}º¿ó¢"lçŸyõ~owÂXÜ‚"O˜ã›?CT‹"¨×?†#~E@HõÂÁ]XÿÑœ( endstream endobj 1710 0 obj << /Length 2609 /Filter /FlateDecode >> stream xÚÝZYsœH~ׯ b_è‰éróæµe‡föŒ¥‡ÝÐ:& ‰0 = mÙÿ~3ëàj,ánûeÇ1ª¨Ìʯ¾Ê£hêÝ{Ô{{öÏë³o$ób<ð®ï¼{¡ŒˆŒ…wy7þ¿V\ùùî6ßÕÍjÍÃȹbÊÏ6EU4ínµV~ÒueúÞî‹,ÿÕÜÈË^ÿ~v~}ö÷õÔcF$! ½tsvó‘z´ÿîQ"âÈ{Ôom<Dp-½«³?Ϩ:% fL ¾0o¾e$£„ŠÐùæâòüJO®—Îi„"B eéÓFþâM DSoÍ%hVFòåûW×ËK€úW×+¡ €×ç¯/>ŒT‚ h8GE¤äÐ£å¼ø´»UŸ²ôüOÒºº3Cc0`m¥¯#‘áêüÜ.ðåÕû F`4  ƒÉwv‹¡Ý"&dÎî_­GN@’8ê0´>©HÆ?Pygȧ՚Q?É6Š$i9†÷»­W“1+ÅõrFŒ„‘€å$ ¸Ñ¦q¢"ïf­(õ?ÍÏûXö!-<™y¾>¿zõáâë‹÷ïžZšÉƺ~ÏÂBŽŠvê¤õRŠpq°^E•=ɘ€¡r£²$ß /ĉ훼1w‰my¹ÔOÓ¼ÑíÌUWí®.MçeÑ _hÍÓ©¢/WJù¯.á–¹F!Kkv[›ë&©’{í£Ì¤“Ïýv:ÅýCÛŒµ³àé–,i“[pÛöÖ1Œ*omÈf½%ªQ8—~½Íw:4æ¹}HZ¼ƒ°ÓyÚšö­L•Û¤l0FðØL»­­f¤³;àÝÚÜ¥-«çñ¡H¯‡YñFNŠÀ÷“´ëjVB sÙ™qa à I,Ä€‚2?Ëïþd_¶¦¡¬Så~}gZ[÷þrlélÇg;Þ'šÅ!Qª£ôEC·0Ù šÉÐ ÙW¥f¥A¢h:û F8“ÏøG¯€rÄͲ¼24!øŒWCÞâvúЍ†WObHÄ:wýËÂ{8_ „¼óÖŸõ’Úi$·šŒ qbD€L'ìãÑ(”ý(#ÖŒ 'F}&"L¢þJ*ÿ?ï®WáßK°uÛç›mkÁ/‹ ]Þ&à-§mƯ%fiÛ¢º7ÍEûÐ/žyóÁ¾µµÏÅ}eîÐÚΉSÙ‚ƒç3ë:ô鯓êiîÜŠÞWõ.ÏQðÁݤÑÛ$ãºÙö òªµÜp¯?$HFÃá‰Qw+iÝ%oÝþÖ­¡’±7½Ú•œë‚õ„ÔÙ%ά$žd1‘À8Hž½¿=x7FÃ%5¯MÓ'L> p J7—ð 1†,“a`; w‚„—» cøOïC"UùS'‘Eöµ^c×”‚Èî¡t »Ú‹£½º¼M»÷Í…jËÒÿ{ûî¼?= O¬pâåmÇS2áßø»éÀI“ç.I$Ç5^Êötx¹ƒW×­,Ðö²";µ—Å¢x0è qA#ì0d)Ç죃„Ø^”ë &”Á·W ÄSW‘ã¨p@„‘22îe»³¦Ž°ñ!éØMcr#Ýr^ð>oÿš¾y³Ë¡–.RG}„š\àGë‹ñZ£ÿ0*Ÿa5;lZ>ËgÊgcŽ›#¢˜¨È:øwè¶ëdÁmþÛŒgåñÀõ¢ç4î®Þe&Š3 —úÚ¹Âí3í†;b³­mœHªV{eiR-7bç²dîÔ¤pÖM³Þ3uA¦,MOê’míÿm–Œ½ÖñË4&iëšÆÙ é®mXJLzb %'ï`f&5oç$‘… Œ¹§ñ÷.ðh¡#:Yh’P Ç[ ¡ê |"€øÓpl(Fæ?0§í|ÃÍWÇ÷£æ¿‘Xû¤,pQs›4Œsãyð©_%›œ˜XŽAûj›§FJ3‰¼sƒêÆuç6(w›t”`±„×[—œäíl%pžte„΀ÂÐÐZ7™NÞ‘w¿:%À×,M` YDöM—ô)îhI CA—hÿ2³Qa©ûÌÖÌ5ÙÁÁ|K& >¢Êš`i¬¬ÅödaèØ–²Å:•Ñb±HÀz`½È¢q%‰=>ø€,—FUÝšD{ÝŠŽR.„R¿4™Ì º”w8õ.z¦V€ÜKv®o섌t3›nG¤û2Ù™¾ƒ •Ž1ðp…5Ú\¥!lêìh|o½ „YÁ&þF ²ÏZûa¼Ù™ë¦Ö„?ê^1\„SYêúëÑ îÊî$B˱£FÄi†:°èÏ «n¿ÅE€šbšÃ_Zï«Ö–v( ÚÎ#ÿb:«1Cu“)„'ë%b¨îDЕ˜Z1Ú(>\5)H£³=ð’’€N K˜J5Ù¶9‡ñŠúYÑ$?¤WWI\L÷ýÔ*#d†…T Ÿ&ÈfNöÓÖAn N.ö…†ô¾°mшƒƒzF#"¡ªärßîçáÝÔ™.¶Òäg;[ ¹x|2s~8±Iøv1sǺFv¨üyh·»z‹^©?ƒí“'î kÿac߸rÿÔL\†DÅݦ‹*ÝéÒaeç¼~˜!X§m‘Ζ'jz&B"™}QYºùèXž¼ù øVöä¥Y¼ùƪ¦È@÷Òp¼ÅÔv'H‡ž®{ŽSËd–PK·'$Àq =ˆ íù²x{ŽuýPùÕƒ;%žC*Û¤EÙlm%þrI>enŽe›~ šÅÂ?i¾mgÎÙXÖ}ˆÍ—|i\º/ *N­¯ðê~ùóËâ}1V}ôÚ t_u盉…÷ Y‚0Á¢éI#;˜ÍÜèˆÄ,þ®“‰a!÷”„JfñÏg\(9aÌ"9žñA!ë¿zH¶+ä¬ýCùHÈ „qú~?ýAå ëøûäå¡ö endstream endobj 1715 0 obj << /Length 3296 /Filter /FlateDecode >> stream xÚí[Y“ܶ~ß_Áª¼Ì8΋7¶,ɶ[ÞTRe»\w—‡s8^¹ìü÷t£Ás8{)N¢$zØ!›8}|ÝZ<¸ xðüìgO? E³ØH\\JD,²q`È…± .6Á·‹Ï—R/²zÕÕ~¹’6Zœ/…^l¶y™ï›z¹Ò‹¤É«’¾=?ä›ì =¿ÎŠ,Ùgô"˜”L,¿¿øììÙÅÙgx଄éBf¹ ÒíÙ·ßó`ôÏÎT7®Õ6M¿EðÍÙ×gÜóÏÝ·ú* ‡×Ï'£ Îdd¦£†wŒê¤bÔ@*0–‰#Æ#Iù—_-_4Ù‡¸ §Ÿªh(Eθa0×úâ:£6fØ-¬hÛdo›:I›¹±b&…lÛí@Ú’/òŸò"»rjw#ùž~˪ñ„2-›lÓ¾ÑosíÚóÅM^lÒ¤öŸGý~°‹Ü¶=ìqÉþmí'Í–J/ÞîŠ<Í›»ýLƒ'û}~Uf¶\)c`ý-w3܃UdY¨l°‚ÅZÓJ“¢¨pül‡ýUìÙ‡‡Ã>«=©¢_â…„èo–0P9pÕpYWÛÉX›¤IÖ`¤h²¡X$å†èƒ5ÃÛÚ·¾†ïEæ›ÜäÍ5=]-W` u–øæ [ìòŽÁYù ¹¬rß}“ïÓ¢Új?vuI¿ùvWáò`ò¤t6ê gfqà`EîéðfaUëyn`Gò„7 :ïÓˆì&Cj½n®š–Ú*«Ló]RìA™¡0c:ˆT–E2j­´¨RdäͦZ‚nÊÞງüÛ¹1Œ«hjç491”4§®_Hš”ôqí `¿ØŠ(;/ÌéDŸyq®W,2æ´TAú|hTo@óOû]–æßq¦ô>k4tp‰¬fïiNðKê€o= lÇü`¬ÞS˜ÎcÄ›B©Ñ¥qøPÐ_Ä'à§$S2&)5I}…2ÊšKp‘VKÄ 3Ñ® YÌ'þ×üO;”lR u®¾"Y‘íç-ªÄYi .|‘D>$…Ó„?wšì"ô:2(hU&ÛŒ‚&ÿ¦Õg¶§ï¤Ÿ=ÀïÍuž"N\{·0#ìÖL…=xg$¯mY•s^°j»¤ uÜ&£\{£Iv€¼²J-ž%ž ÷-­BJ´öyƒÃ•ÓÓìÐmth­ñ°ÏË«~ˆã`¦¸`2´ ý`fe–YÙ…;â5AÇ™À°lFzà¤1 M ²°,V²3?TîÕ2DDA€3XàV ÌrÕÍ‹p¡ |±¯ðI¶’Èë„€kiôbUg—3ê¬LÑ$°5€Ê1£"IÝc×iv”aZuì@ÈQZºèŒ³OMiØ$ÛNÀåa Æ=Ÿ.Ä¢K=¶IC#ÿ>À…¤>ÂÔÙ,eƒú%`T!ÓVŽ=u-htƒ„–éX<\l‚#èTŒ!*o>uúÏ\â‰àã°yÿ.àC€K;÷Èîìªuú«±Bèäjïýî¼KS7-èFð’×Ö”1oÏû8²ÏÂŽðËï]ý$;—@aÅ­d‰Oçé·Èf¡GSÙ`O´MJ,ÑF/1’WuŠKD:FW¤“AaC0¢4i軄p Æ•ˆ[+£¬ËÜ‚ ‚ëÂS½Pi(—;ß;¼BRâÛøìfÀZKŸËO”±€ªûl²•·vO-ÿu—аüÐòwlÎ1lSLgø´l¯÷Ä-¯w™3ØŽ€¬¡ƒ 1$ÃÖ#ùñµ³3ö~k»8òf“²´*/oÓ«Ò4ì½¼,ŠXì|~`d«¶näb» RüŸo› 63ƹé@Œ¾­ß[ÿЊ\4©Æ'Û—VßɰŸnÈïp>xþÙ=FÀÈ€ÄM‡€Õö Éìiì™,0:ñüÕ/3no™ »1]H|»Ë $ŸxqÜPþ=ói›¼-rŠs=…Z”™µöóŒ[ zÕÙå&»†¶A“ßFB[&Ì1RS ÜÀV-›EèÁaïY¥yÒ%Òu™M16¹S:~õòKœyFÑRrw62YÔTÕ°­‘ž¥«>>1‰ë`M°ua"6cý_´ \²vQ‡65£¸ä¿§M+;CR»³Ü¨O“çò0‹j“_ú€xÒo‰ú¼eä=É\hÜ´šhåÜ\'M|µ^|ü½y™ýcºÑQw 8ÙèÄ ³¹Î°¯Û ©lÂÛúó@)HÍÑÒ,Íå;a©»1÷^Â-T1V¹0'ÛS»¿,-¦%¸ÇÜ•挋."¾„äF‰ÐG\Ð%lˆÚi_p‡TøV.;í¿ž óLø2g“d[4ìZfÙÆ÷v¹ü®ý¨­­¶ÁÌwï=¼ø-DIа§žíHMâ÷òΕüRG[*p5¥²´ñ6ÆH"1H•â¹ ÌS¢ Ì£óÒ•u‚‡mã¡ü³¿ž¿úê‹g·ÿaHq/²:›øN9<@ÌH¶»6›h3Ñ„~PÄš%iÑáèçÃn]:Œƒé¯_ÝÜ':Rh¶OF¨@ò…ÚÏ?d¢Ò„œšM^Óm Èv­bZkG.à R!МCküéž ‚tð]l ÿ\÷Žhcã~D€JjÖÏØ‘R²{)Ú ; ï‡ãýt)º-´æm{ÿÃÝÊÒÿúõ]_`<±FóÅŸçEЩ<ý}¨9@ö£6I\`R°8éä¥ý—N^-äÕ¾Yíí_ 3²ËFƒià…¤3” ŠÁwCÜWñ£S[<Ürý7Ȉòº÷ʲøEŒ ¡™þGã3:i…Ë?û˜ÍžŽ:á~ùE»á~°:Üi‘9©ùÎêx„3Þ³ÓÔ¬x-™âáûç´N3ùC|×YÊ?&ëªjëiqÌ”µïŸ§=Ò¹ -\ä¤o©w]ù¼ÿýûÕ¬ ©ˆä{¨Ò€ZÒ‡y×ÇQù$»PíÞjH!Ä»Â×ÿ˜7—{äMáÿ½é?Ñ›ŠwSH15èñ´¥è‡ç4ûíþ±êš™þªð=R_(!ßû/É2œZVS.è°>kvî©nœx:ÎõCÖ0ËɮڻÓxwÅõØL[ ÆutÒ*Í­WUúÛÝ&^-çÝÙ¶™)ç0‘¯‹OÔ7°YÁ»«U2YFÅ<|O‹4ðÔåÑu–[ÞWŒÁSRÎÌ£-> stream xÚ¥WÝ“›6÷_ÁäIÌä$‚‡Îô’Ü廙朾$™Œ ²­9Œ\ÀI¯}W¬À†ó$mïI˲Ÿ¿ÝQ° ¢àÅâérñä:aANó”§ÁrHÈ$£IË2øDÞ„\ݬtcÛð‚ËŒ\†LrgjÓvMx!ˆêŒ­ñÝ‹ƒ)õcÜЕV­Æ£œS~Y¾^\-.¨†ê*#»Å§/QPýuÑ8Ï‚ï=×.HÒ Ö*¸Yü¾ˆNM³™é,¢Q,ÑôÏ‘ˆ*Sƒq,‰€#ÃíeƹsÖ<¹NOEˆ˜ –€ü^@cm‡L=<¡àÒÀ´‡ðˆ˜º0{U¡SŸ“QŸ]._^ývIß½ZÒ«çÏh‘)#w¡j”¼éÓQëFuÞ¯në7•i]f:wJ‰]#uj^;Ú7ý¶TZA² u±ÈˆªË—N8€àÄyÁÍ…ðñ°•)Œv`Iã^Oäƒ& ’dB–[ã91SŽw ´z¯ÐOG]7v7çLÔRIVºP‡V¯SË^cv¦m¦ÀÒ‡Ó½µuåz‡ä•» /XDUwºÄ7›Ê®TåySA¼ÞÚz-íMCÑîua>GqR—ˆH§gæ°CÚ,?t”#iÇs 3)IŠ@fPU×Nœ©g–±œc¼÷÷ÿ›)4~ôNÕ MØéºó\wŽ€qÓ;ä›û> 9Ï)“ñ€Ñv×þúSTç‚æÇÛªõ;Pé4]þµcAþrBï;äDZר¢3õñsA£LN³p‚<ïœtç)Y˜°ã;8ðûÕ ÝVyVãעр˶ÁugË>Ùý»©¼€&nãæ´¨U¥½l‹ëˆ wØ[ÌÔŠ>a5…óÝéfÊϾünº­÷—ʬ]Ô¼¾Šg ­lÆ4´Û¾X`—ã²µ‡qºˆ(ƒ´B_Kc×±S4Мï?¼˜OÐ3šùFýîýóo¯pP<½zyépüÇ«÷P‡ï÷3 èÃqš¢ˆ%öÓIòì-\:*ÿÂ×ÊcŒ–Q™ˆ¡Únû¶¦Êø ž…°ßbÙ |è l€Y;H¨Bÿ(%±¤)GV« 1œFôîc§¹mV‚BÜÖ?´&§i‡Oܸᙇ t„ F˜À«Öí  Mg¾õ3N  OPῲ{7‘±aõŒ)ñ‚.Nÿ?0ç4ÏØ½``(MÜóëü×LÀŸNú¯ÿÌÎþL&ðÛÇ8êO’þâÁ2òl«ö¡¾CÏʇ&9y6ÎÃÙ¿åµq}çÔl0÷©¤ endstream endobj 1733 0 obj << /Length 2131 /Filter /FlateDecode >> stream xÚÝÛrÛ¶òÝ_Á·R3 ‚Hž77u·uÜÚêI;i¦CSÅ1/ IÕÍßwÀ‹d7ir<™ãX\ö¾Ø]ïÖ#Þ‹b¾ïNBø/ôbêÅ! x$¼¼:yó–xk€ï‘ M…w¯wU |Kïúäç“oW'ß–Â:ši ÷D Ñ]þx±XÒ8Z¹ùêùù‹_®N ñWç—¯p廳gç×0»F¢dÄö’‚àÔ¥KE^b®ýVnŒøM+áNü¢î!÷û¬,‹úa?,(ñe{#Û¦CÈù×f{o¾f¡–¹ìº¬…ñß#¬oð›7uW¬ek [ƒñ—e³ˆ¸ï]·—Ý´€­|ó\Ä#ŽB0`qÆAQäçwàrvf"…$`"…T¡¥¡Î*3j6ø}¯©Ú·I •YYáðwÂI3çêðF™åJ²ÛÑy+Ä)N+I¹ÆQå”Óo³Ú\ZK@‰g‰¼¢x¢!ž—¨’#ÄÝe‰£¬ëŠÛú˜Ì¶ Z’’D7µ„ÄÙýoÙy½-ÆØ¡Îü¾;ªñïžëõlp—­«ÂN:‰¶þg‘[.áì;9S±²Èyư³nŒ#ÝH{Ôy‚³©5ø*œíË~ÎÂB68°ÐÊ]Yä™Z÷¨);Þoå`Ôc‘tÛf_®§²(›<ëåúÃyü¤XpÄn…j¾¨¦áÎñx š'TÒ¦•ï!˜‘¬ûRÍûG½x×6»ìVy%znuYŸÝdÖmSÍ6< çAÖëÝ ¼RÀ ¨ˆà7¡×ÂÂðêÅÁ³¹¤,HIì-£$HDA8½ý£±xo–œÿÊD|xfupD/( ¸!á´ìÁªoUÜIã±¥É<º}Y`˜ëp»´'`p=˜œ^?;?Ç!Z¬ÑC} A'"©zpÕö?•]€¹­0˜´bà[ewš ³Ú›Õ­AÚáSKYwÈB쯛*+j+É(ì¡¢C‰HÉ" A&ÏÚïv1÷—¹³©Rö½lÑ ôþ‘ êóÂY­4Ñ¿éG› b žq±€sTË‹›'/ @y¹enm¦¼ n¸+LFh`‚ÒËE1aŽ)|¨(þ<ækE¹i@ Ø[*÷JáAyêRmC Ü‹h i‚áì×Ó‹Ÿ~<3þÍ”¼í&gÑ‹?}ýT-zyq$÷¼iDç*'tô¢ÃÄdZ0ª I, šál†‚ ·Š Bøç+ …àWÉzmvAÁÑA³ï̽kÙåæÕÙõ>4†“=Áð~”wÃTÖ†Äû¢× hüž¨K]¼ž?æuÑyâ~œËgÝ稔G¡üÉ#*D0¯YĉÈAÄq åSnâ<ËAÈpÐ=UDýRùû ˆš<}D¥ñ$¢BR9‹¨¡‰ˆ‘ÎX.J ‰¨pß—Q•{1úpD¥±rzÛ¡º¼^]¾ú¤€úƒò<$½¼üåK"ï3QÀ ãA’2[?ÑÏS?]d»ö4 ‚‚œÝØ0mê^eõ Î~PëðZ¤UÝYýb}DÙ5 | ª¯ÿ©5ím®›z–æ;@ãÚ;­4 {ݪÁr F³ê†Žša¬zˆk‘BˆÔ¯$¾oY]tîÁš£½ëpà¢R­eëdsEàã¼/Ï ®(Çæ€ (ÑÑ-fʼZœµ™1’5 !)¢®ùðí?ZŰ’ÝÛÇ% é±=ÛÉkSCø'ÑÁPb}õ]{áž«7QGsGU; ÿ7°G®E•.ĵ€w2/6ïZ¡i›„4‘Õº­ÂƒÀÛLs]Y1÷u5c-®»_0vÅs,ܾÆìËðc æ± ãÊMÖ`XKÅþ [ÛyVºŽOÌG‰[Ì'e«FŽß~«mH¸±ý€^ÏrSÔÂÀñ­gSñš[“ ÍâË|¨ì»ýÍìzhe<6CM/~r¹Sös¼€m=*+klæ9s.µ\ØŒ·Á¹IqCÓÆ‚+þ¥j†­í¥C÷!­Ühα1Ûf¥ÒO$ÿµ:l2ÞÐJF•ì·ÍZ'âVĈõ+¥t³i°c$%3ð ç›=¨üˆ¤W¢G‚j˜UžšDcݱ¡¢ˆIˆ³ïqÁ(>òó²ÛíŠÆÃTëÚÀ‹" oh;Mš“#¬û`­ í‡)sСLul…† 6é÷ê¬Ñ¦âvÛ“H¯Ïò^{ ÷_oåØÉ˜aÍpU”½Ü0iNO‰´Êw ‡ë,qœ²IÓÂìAejANÜËÕn3ÍZ…¾»›èeJ¼Öµ³¸Nðy ¤½jfÐj ˆvû¯ç}|×B†ÒQ ×OÂgñ@S˜nÛJv]èCz4ÓôgþÿWÎ 9ø±Jà?ìÄ\e²r„¡y©Ÿ£üo´0X endstream endobj 1742 0 obj << /Length 3022 /Filter /FlateDecode >> stream xÚåÙŽÜÆñ}¿‚oáº›ìæ‘·D¶ÙHK #$\’»CˆCŽxh­|}êb“$Ë«A²ÛÍ꫺îªåÝyÊ{zõçë«ïžíeA‡±w}ë%¡—˜40Yä]—ÞKÿ§]hýª¿©únØíÃ$õÿ´ÓÖ/u[c¿Û[?ë®å±§S]V¸ÿ¼jª|¨øCaèÝëë¯~¸¾zw¥áxåi>ΉJ¼âxõòµòJ€ÿè© ÊRïžf=§Ð6Þ‹«Ÿ¯Ôõ(=C]«@E £~½Ë”ßÁù©ö'B$U~_Ýî"¼|Z¿Ï›ÑM3¿hꪞuœ¼åÈ‹o*nqò§¶­Û;†üõÙ5/xÛßXé æN×óP“pšQ¾”·%ŒÙ÷§ïsg}¬úò±Ú«àØd}¬–c­ò¤:l¯uY+´³üÝ“8ZQP'AšÄ0—æºa|s,,ß Uÿ¾.ª×l¨ž&ì¼/waß8HÓyJÛ½¡ûV>rþ÷Àˆ {'QEÙ¼ð=ŠbÎÔ¨ó›¦BfEÚ¯Qø¢è‰¦‚P¥(A‰ÿ&½Dæ#àó§ @q¼:.ƒÄšù¸—=¡–7Çá5ï+’w†d”Êá8T…h ÖÝ> £…óÖoË"(ºöö ¸XÍ+Š\!I ” ;n_©È´Õ~œZ¢·|­³­´|¤4Ø¢€r¤Ñûš„ ts;‹6t@´ùK‚,³òŒd<ôkR¸È=ìrꆡæ2ü‡E:\«hÈ7€¢Ù¡ÿýß^pçú×<ÔWE×—¤à` êÛ ’ 4,¡XÙoš®{;D<û—dh;=©£ªE¡,ùlÊñÞFAº°Ôü˼ςØèyI°Û`Í‹©@‹r`¤ðj»=|O§ÙmT L1[vç=’TÅ~Yó•àëyýû‰_‚D 6NÍ(ƒU‘3+àƒY" ´$ˆ°¬nAA¦yûSß]Ñ5ó9‡¦°–tèXÛ¡[tSSòn}5¸ó»Û£…ù²7™øÃ©ëX–Ë‹vñnc¢™—(:ƈ8˜%û÷uÓpodlW#‚ifbco:q›sÃò 3E.‚Þ§ £8ôO}uªÚ’}:ã¨Å¿ŠtoDÂX0ÎNºß¼ùÇ"m2ðùNàæ;¸CÀb“gjócÅȳ€ƒÁÈl Â3ƒñ•gªx ØC”F3u!ùÈ=Gè×`´ &B“©%6¤V°Ž Ð6Àô|«ãIÀ97+‰g€#)ôW$½@;°¥zq>_ ]ºhÑŽ.)ØÎ´Ã“ÿ°3Öß²;掊)èaº%"Òn)rm¨AìtN ÓDèóN2—nš‰f¡àA€Óì*¨í{Ò€f½9dSÿÉ.1\¯Üpÿ©TØÌ9øðîÀòª½«Ûªê¼Aõk~<5ذKæT[¸¼v|$¦)áU³`ÅBÜÙ± *w‰Ç€6i | ½Ç[е oõG1É:´{Ö’a¾<æ¢Ö9fÓ 'k!nM-Å­Þ;æfx£xÚÙgqô"e!¦±Ö¸/„Z#éLË€"nD^±ú²êeðGË0 Œ“lÙÑ™¶œè@…-Í| ƒ¨e;µWÀG³Õ<_E7+þçïwëýìðdÝ/6ODp¶Âÿ¿V0æ´*r™ÀÀåB¢—•G¯Àôš¿¬BËgÄÔsÙ BÚåø`ê¬é‚deHßJŠß£GsðrÞΤÜÇY Àì-ø®L!ГR½ø,Õ³xÄY|Á:f)>ÿ#„6ÀƒB¤u4å ׃¶X½‡íÃóA{ˆ±=q¾ ­þ.úߎàeŸ G…&ÈT²äûä9‰n&ùìnÏ6 %{W…G«V-¡ô]dÆŸµxâ1gG,Y`>œmÞS>åü÷ÅÌðN`‹( )¬ÇöÈeÇ-ŠQ¨}ÎqºóeÂäD{ÇŠ'çm=t_Ãp»9§ç¯¡)3j‹À1—(¿¯‡ÃöØ¡{i1"ÁÒ \wO<à-bëË .Ø`~‘ßÙ©Û±êóbä|£¸…ðè-ù8^`ØJ ÚâSPȃÁcÅz6Ø[ e¤Ôj¦?E¤¢4€$ˆ‚h»ïWïï½Ü[¥ü¿#?$ó%¸Åü`ë@šëdÜ·’2äX‡äîPñ®Nõ©<5®aÕfDa´Mi£Ðø'®jR8«'8rãØaT-R¥d‡Ü OS¯-ŽÒåB—ÛœÏðÄd ¿¼^H0G )ÚPpomäÿèjEŒ Ö‡Hö0ÀÇ©÷TðZ©Z^¾µÂQ)³Û–*ÚÍ­$LXhJ9]Ê6«¤7ÅjÀT¼™äjíå¨áT5Z)®´Hù/ÅZÍRêP—’®Õc b Ð|UEÆ„‰ÜÄ™«©rUÚy)^)ÿÅó]bý_„œK+MçÚ*haA4w–->¸ú©m ýªjcè$ÛÞÆ”9íŠ'YÆÅ@‚¯ÒLNÕ¡9v½¬]ßMwù¯1%×ÍØcx¥øÙNGPÁ?¤Î™­Ò}X)élz¦²ùÅʦ}R¶§Ïƒä¡+ ã?]ñG÷°Š¯ RãéÇ]‹D½›zgå?±œú•³&¥e—ÒHav$óé²`"5¬{ë<Ž‹·Xˆ[tâ² Ÿa|¨,ÄÞf©5~'ëÀšðÌϘoãgžW§¦.rçJ¾ÆI<§W°y}ózêÈ (¼¯ËŠTëL0Èeµ/ª–|¶2‡„·ÙJ"@ƺ@ÇQã~–ÆV=î³qtt[‘x~QŠ×FœôfudÝæ,꛺áúªLf>7÷')ÇsW錔}Æ;Qè°r7ŶŸ 'kî-®«È·›Øý)-ž :%üUÖ»B`ÔËŠ» =5yQ¹ÅGômœu‡Øm@´zr—Ù¸žÝ¼éîV39XCý(©r8|âÕÃù¨b؆ÙKxI1p5rª{1>“Œ &¬‚ŒÌo®!¾rpµµî+™%åUè­ìo¸ª^CŸž„pG~jh€ŒÎêÚKæF,7ô®‘ìÐKo˜.œÄ ÌIBC6Dá-êS>ÊAó`S³¨ …/°Ìÿ0S8w¯JÜ9Öw‡q.ïIõ¯å7)2ˆu#÷³"XØ‘G+ҎͶNP7g8ã.ÉͶȸð„4÷"+_tG™äÀVôÄAº-š©œë“Î"ÅÉö ÕDév×W¡VŸ³bi`bçŸÿ²¹¶Æ€bÄ6óñ^2>w­Œ;zà$¢‡–ˆZnnäÚReG‘ur1*N¡†6!j!è‚EA°’QF‰€’ÓV¶Á7™CìN§ÙF–ü^£´;˜§g.Eß7\´p¤&ø7öLZæFø;¸O!:Y[èµEàaº À‰‘Aƒ{ÒÃÖu„çÜœmĘÆüŽü×vË3Í£1”u“·¼Ïm{Ê%þªÙá¤Wʪ$p®î8lá®ß‡ ¤Š×M$áÓIr~h*ø!ÿ 9&ñ‹id`7bŸ†Ðáï Jþºí»£Œ³@hÊ!À]ƒøh|îØj ¿&á²E!æl”ÅŸ6‚ÐŒäb|Wçüç¥ ‚3÷ˆŽú@ÕŽÅS–TÛ•êã;)©>ÂS¨b1…¥8WÏÏÃHñJÞ¡~3Õ¼PÂ0“ál$¯Ô^\ª^6/øGC˜§Ê›îi•ö2ä„zå Wã‹‚ÕTi:pëõ¿æ7#|éfB@±åÑùðò7ÿ\éâ/¬ 1ÔZøkðçB6Õx|ÈO;d…$ 4xÝØd»rá ß>]RpöÛ«9Lαÿ7b–F endstream endobj 1751 0 obj << /Length 2816 /Filter /FlateDecode >> stream xÚåZëoܸÿî¿B8¨ˆI|Hê·Ä‰ÓÜ!NÏv’C Õjm!zl$m\ß_ߩǮ²q|ú¡þ`QCrÈyýfH­ïÜ:¾óæìåÍÙó 8 KT¨œ›­Ãƒ˜ÅQâD"f"áÎÍÆùàþ² ¥›·ë¼mº•F±ûbHwSuÑõíÊ“nÚMM}oöÅ&Fí«¼ÌÓ.§—€…! V¿ßü|öúæìËY{ðÀ‰BXN°Èœ¬:ûð»ïl€þ³ã3žÄνU9BÅð,ë³_Ï|³ÿáÉؾÏBÅq– œ:ŽˆW£Ä`\¨EÆåýˆ ‘´œI½Ç§/â|ð¤ï»oº¾N«Üèl» |·iéå—WçÝl•ç<žØÁw¼0f‰ iOïÞÞ¬¼ ŠÜ6ÏšªÊëM‡ï±Ûߥ=µVØï[§ùkú]ºâ¾ûuÅÁ„Ô—RÇ®Í7ùGŸ‹:ßPG—^Í–ç—8÷Å»×DÆÅ[Z9r?úÒuymÇÐâšEÊ ßÁ¨|!H¸Ûí3sgúµøÏ/ÔTj*Ȥ×R¶>§GÎôãÙ¡^€š$MØj€ ¸à š! :÷Ý¢J©ñ@ý "j¤õfa/3?÷â »‘!ã¾°CŸ-pƒÍruÄ+|/+å2PÄàøˆ¸Z”–ƒ‘ve‘¥$:ºŒVAèÞÜï1œµW<¬”´K[šoüˆ^ê}CóohrG³wFu(¸* FF˜£JÉÞE­Ñ@ú#k|iê9=Ð-„-\Ÿ49­o5ø-¥‡v;läuoMJ‚ ±MA­a ¨e ~ß]fêÍ >â1ˆX "¾À˜Ž(øÔñ‰ÏíZR+`7”$nV°Q3#ÓJ|·l²´Ï‰˜Ò£ÍÓ²úëJH× ¦(ÆV×6ûÛ;z!ù¡±ïHh^_­"éþf™@Å…0P jX V ž VÅ1Ø!ñ Áàl’gAZŸ¼º8§eÈÂS &8ãÈ–¦(@¤]·¯†­£ëj7¾b2 ænÉÇŸ$xÑj¢&á ¶ Ýît QRz² ±iª´¨Çy<äy—[ÆVmȰÞÆBÀV‡’çH§×©7ÔØip‡>³Æ¾Zk? ·Á3kê>Ízâiã×ú×Dh‚õ0»ËÉÿ™#è¼Ãd›–CüÀ°û¢GçT¸G?ϋۻž ´ChX$l̳/þЉ[«"FUиAUÐ6‚Bkßé…5l_o'ŒÞ/¤ÆÃÙÚ@ãe̸ ¼5çîuŽ2RòjÓ’ÂsS@Öây AE„©‹xm^‚Õ ˜Lµg€Æ$dD“ÖÐP°¿8ò,¢ÿÓgÚš|¡éاýfw*BÁÿ Y ‡ é9t$W!#b¬ ±õ‹Î]8e=!þóÕ? Äð1=àëÈ“zÒ}Q–Ô³ÎéiL -24*ãè4¥Ùö9º‰„{‰ê6.TM܆åÄ]³/ Û²¹E“HY0Ûa@>µuƒ¦ng¹Äà<å¹ô œ¶cŸ=ÕŽ±Á 8˜Ø1öçv„ÎÑŽ±oìÔõ„xs>Ú^¿¥n˜5ªÆ ꆎ½†´xŽI@c´a(&›ž9 Ùøä@kª¢§˜B)·D´°}`> ô±V7&P­äõÜÄ(±n ÛíL2O ª::›ÕMànò­¦ïK³À à&Y¾Î!ð@-ö_p¯J»^"°ÔÓãŸGáÌ<M€}-ˆ¨×¥.]†¹‡<”S}´%üj¸hô1*а‡ §àÇV‰M`i]J¯¶;HÒ÷¸´Ær¤ÌK¥îpCv;Ó|=õEboÒ>]ƒ-á#î¾EoR\gkxì ±• `JÙÜÞRðÀ‹N<ÐIM™²óíjŽ»]ž¶MÐŽÄuneÆÕ [õèl*™QÅFm–À£Í'‘¢{tÎw!ާ"d¤0ŽIÎ\”C‘jVÀ80‘òÑýùÞãOć1N3̆ÃmA©´^,jµ)À‚çÇGìžîÐßÔ† R=3¤–(“tʺÃZjLæD… £{íAZ@¦ÄpÐ{šey×ër\‹:L„n­…7ù†»ä£¦Ïºuºñ‚…¶m4V%øipËÝÒáfÓ ßñùÆž½-Ï¢;:ÓDxÔ{4N…ß©tSýXbS³Ä&Ô˜Ä,“CÏ4¿@g$¢k£ 5MÓнpÇA`NF®÷»ÇiMÝ…!Ú}‘zKÕ®Ìu±äÔPûA€¾¨tõ Äõ¾Ÿ33”‰Öý~Hµ B02”Äи’63âËñT æ[T8¾Q˜®‡k˜¯:2¥°˜ÕÌS9ÒgJ…s+ãažAý¶=©ö„)1ìït¼*Á¤ˆ¤®xR=j0eÌݮӬÍ*ÇÕ–M?6Ôà¶59TU#JSî Úp”ŸBãR¤KL}c%ØÍKÁô[{|JŦ³âæÏœÎ„œÈx73€¡œ¡˜ƒ¡t…Ô 0”30”Ë`(0”î[ÃÖnÄ€ ´îïrÃ2º ×£" ‰w¶wZ&è#v@Y_È,g/@bƒ½Ð˜\"ãmá+ÐSzÌiÈEºo~öˆÞK}_·‚Ž¡0ƒ… üÕœv&ã¿hBEÖâL¾&ýÎÑíáA†ûÿ§ý†þ$n˜¹á]Ø*­–sÅ–ðÉ5Þ÷ïò ojDf?%XCÁÏ û¢Õ¾ SÂ%¶ŠÒìþ•ú¼ØÐ€§s²´nê"ÓwD@×SñfÛ—ÆSh¾IàjõëF÷‹‰ðÀ'Çèø7î1Å’âÙ’gÌJ½ ¯Ú¨ …y¹ßäPHìË’’é`Šñ²QÏ\ºÕÀ›Û—o/_y$û–eŽ÷¨ÔÿGcËGTs™›;,„R$ÎáÓ|­Zê‚„øúfø§b¦îÄ1˜\á'9ç‹Cô<áÓ¨ƒ×¬r8}¥‹8“Rjr o’…A€îD¤LGÀ¸€bu$p'›vsÉ¢þôü‘1!U”Œ<›ã¢#-¶ã[iWIþ„§?Y5ƒ7üa =|-aö#çÖùÕ_‚Z ýo¡³ø?ùa÷ñC‘µ &ú²€âRÏ 7K ½ Ý\ÛwÅ”Tñ„?Y ߌ–fúÑÚ0sµb«’§„×ÑÇdó´*õT¢¿6zq³P­úSõì#b:a ™°G½¿¼¿zûæíåÊ“€äÛ¦Y§-”«[¬OÃÇT/Фoþuƒßý õÓÅû÷/_\±ó÷ï~Zº°'ÆP%»ç—ú{p¨`ÍMZt‹EÂäk©q9ŸéÚtô¶M›å^¹ÿœŸd.°XïëúÁkÓõºèOJKµ*ȇìô›Ù'•™^8Ë™4`6&ÃdÎó{Ó'Ö÷¸IæÍ7£4§#g #ùr~Kk“Љ'4§ûßa9­Á=ØŸ®—g܆09ü½ˆ,Tþ¹ÈñÏ\€…Y„ÃO>ð+¹Hõ› À”%áð=TD‡{ýë"¼ endstream endobj 1760 0 obj << /Length 3059 /Filter /FlateDecode >> stream xÚÝZÝsܸ ÷_¡·jo² )Šúð[šKÒÜ%mÎñµI2Y’mµÒÞJÇ÷×  Ï•Çnf:õƒW¿@ø ) G:¯Žþzzôô¥¯œXÄ8§çNè9¡ ?ÖÎiæ|p]yÆÍwgù®nVk/ŒÜg+eÜlSTEÓîVkã&mQWT÷j_dùú>ÉËþrôâôè#ÓKGÑt¾e褛£Ÿ¤“ýG Gεmµqü ‚ßÒyôÛ‘³®£ëJ ©CbýyYäU‹\G±›&«µr+*$eSÓ×òK7­«Rûû]žQÍuÑ^R]{™)_iã~Ý–EZ´TUÖi·z¨¯Ï‰Úä Oº_Š4çé÷MQ] Þ¾ ôˆy­´0!.Óò~•¥Ôh²Be„‘^׿ÉÂ0Fø¡îl’¦ÍwŸ—ÇòcIý­±ü®A‚;þVö… <ÑDB+5Œ«QWÙÂÐktLâ­•±1¼èmÒ4×Ùݳ„RÕóýÕ3!qÉYiåxnQÑ/ ûH OF¨U¸"áG³5: ž¼¥ ‚ÑtA`ºé>ìVZºyRnšO4.kãŒI‚þöÕä)+ pJò(†|%†]¹Úº{~'3±ü~_Äj­ƒÈ}Af¦ŠsúmêMN_io<[(K"ŸuÕS{ Û |MÌørÖžñ`—g»Ý[ o5´ ªyBåí®Æê/EFö¤÷'«Ð¸ÿ¤Â.Oë]ÖPÙ„¯1ªí‹gy•#»-÷ÕŒ} ñzyZÔZîÉ]šü|Ï£¯|éÖÌp ÆŸMÑæ°+–°ÔPÄZÏ‘(‰*ú Y†² zY·€…‚-MÜëL\%›|ÉÊA™¢~ïw¨¹4ðá/¥‘UŽJ~Mí fv×£9Í¡¥B]Š<÷õ9‘úAvh4Ë ËoòÖº‡UqùV8TrØÑæ‘æ¨àO'iÛ|³Eqjê UÄê@e]_æw¿m¨–ÄŠu¥'ÅOÜ~ŸíÞUQË¢"í>r.9o‘„Ÿ–ul6znUeTŠÛÖi]™tnÂî³qï´UÑbÁÿÊ‘ÿµ*›ˆ’×Ú}l¯›mž(¹tÁ&6 næ Š*+À¾X§gØu°lïk±IXóÛš/ó±ÕtFS–¶ÃuoªK9·G›Û™L’‚‡$›éÑK º P*›(BÆ9Ñ"#ÀšòAA•D§#¸k%À=÷»Çw>¬”î¯??§ æç¢Ik\Å\+ÈÍ]Ð y±³ô e{(xîÛ×§ø¡-ŽI e@žZêP>8v/ÄJ jì~BøäÆ·ýùïï飽ÜÕû‹Kšì÷“×D hùgR( _Ç(Š(bÏ4#’gš„0ÚGӻ擗ÏiäÐ}—| qC׋aŤû¦Ø-y¨ Éz·û°=µ™‘‡ Á3ñHÑ0Z"Ž,[7û’+¬Fþ¬Ý%D&¡ý•ÇÀFTØÈcÔ eß3ôkð9Uñ@=ði³gÔc>ÑT 2§‘ŒØãÁíi—TͶf¸¢êöf›7O–ð¤³FÄ‹ÎÉ%½ÓJ6ìnab$FŸÓH£zèal°kll¦þ#4¦¨f;CѲvVïÛ —þþ²òË€Åjoý¿Õ¡-Ý%Ï1Ù­TEW}:…6– w›pÙL¦š =fõ+g2lŽg&„ã KŒ˜s—ž’ó>c3ƒ¤.èC†ÏWìSÄÉ‹goÞ.Dàxc?èÚO–BºÓsŽ îâvÅÂWf*臱»†<äV–•T"‚™ïÁó•Ígf ŽéÚÝ Q_j, û/š‚Ú0 Ö_b D kŒÍ A[0 ØiYÈðQÛd—ظ ‹(´¼Ìldïk„çTœ'[8GÞ“\*€,½wqMz™oòãçerÑ|:î¸=7Rd{›”4/9$ñßзØ¡¿­oÁmúÖ¤¸5Èæ/ZA.Ý»ÞÌæHUÞÌk—_]ØÖ¥K=Z¡§awðšÑ²¹¬÷eçZÊkëËö½´ÏòáBò+L“Ûf÷e‰ï@ÃÀÝ"ô"#T¤¾•·Š¤b`øð@~ºÇHÐÛ6)¬¿‡´æO€+ú²ê)7û;›eሜþ d/AcSoc3*ã>ß“;ß *W6Ê´û¤©®rÄÉ\Yd‡ÃÍ’ C“ãd6K‡9ÂÓ“³œPAS·4k—M4oÖ€Ç\ö ‚­ŽØ$\àMíosGît>v/nAT(]ޱÀË·KjÇK–†AòÀy¨†40 üâ¬`ܼG[úýä }Øþð›dÙÎfOkí…î341H§¶„|PÏZ±ïØHvKF§a‚AÚt»|ðÄ“ ^D~,µÏnd¢S:ÀŦHE:¸Ê™ò`›Boî)­’ù€lQhnù·ï׿BÐònŒ`?RƒèÐðV }a|ïET¬ˆg‚×Áx’€¢ƒüðõ;jÃz`©žÕ¤ZuÁž˜2 á,§_;Ajµ«ùdz48èîD¡k4U\žŸÂmËAEÍê-Fî´H°tZ×dFʯBÓ¥VèÏë YÆ›`å°MXšÛŽ ¶¬Ý7¨åHKˆð·ÓÓwïé$ñ„ë0"A’ÍMðƒCI×Ù$Ðé©*V%vÉ@qNÇœ¾ˆåÌY?ã “Úc’l¶]Nb-~!öï²¢ þYWù–9'ByÆù/Ÿi,UAæþâ´¿ "ëK½@‰ÂÄtsäüá@ÛÕÓ—ÔlVL7ަ‹™P cŒ%—P¯¡:p? ¸B íƒÛÚIG%ÈöÃþl÷ž¨…o‚0F4>7fìI) ÙÊnž"‡áä0]  ­eמ¤]Yú¿¾sç7”€~^õAwoø?þnu€pÕЮׇ´OEž•—áš^^äÕ•ŒbAs‚e¾aËø£i @ÒËÅÀÝP ÷ÅCìèàl‘;Q®ƒXHˆ°ñ^z)”§½¸ f—ZXÞ,Ûe ÷QâÝ?ËЄbO*gA^üûÙÛwo^K*F‰Ü£µÙÄöÚçû#y¡9|Œdäã1’‘ß÷ɇ@X÷¢M¶Û²èOœëY:<ÓÜÕîªÏ.½{ßÓQ'OƒÆ§QÈü"¤R^po&qUŠÃw?BÂP¹Ï/“í ØlÂÈÕ`¡»'üHÃûŸÙkÊ,O‹ÆÞ ϸÿš‰Ä endstream endobj 1765 0 obj << /Length 1028 /Filter /FlateDecode >> stream xÚVK·›6ÞûWh çä*ÄkÙ6MNÒUo¼»ÉB][ AüûÎhÛ‹œn4ïùf4H°#ìÃî÷ýîí{±’—Yœ±ý+K¢‚yÉrYpY&l_³—à¯0N=ôÐÛð)΋à·0Jƒº5±ã>¥MßïÃdjý†öϺÑÊj:D<Žy~ÝÚý¹ß}ßEƒ`Ëcp'y.rVµ»—¯‚Õ@ÿÄOÊ‚]œTËdVÀÚ°Ï»¿wÂÇ¿¬<‚ð³µ²ˆ À¸#>_3Ž$OdcÊè^ä\Êœ²MxîbüÿNØËS*DðNšÃ‚ÀyèÏêxÅkíæíû¤XB°§¸àeSPûš(r¬…XÕ¢(‚Z³ àÚüžåJÄ‘´1XE`ZE›ŸÞè»?Þ€êj"µ“ÅD>xë>ÐT£®gÇ©{@l°Q~’Ê‘ŠÉNª¹óà&bPDªвþé ù{"bèâE€GJx úܘ MÄ †oyø”ÀöcG¤ZW¦6ÝOqpêÃ$ .Äzô÷0Á¤»q‰ èH¯“¤®®=õSS{sê|Ö" -EÐO$u1®“é´ÃíöD9¨Fu•Þ8KÕöS7’DÿꙦ}˜4)‰èA„@Õ7×–Žžoº¥Ž(3[hÕÓN-¸£}§g.1ÁÞÅ„šqi™¬h·@û“ ÿ‹p{q—>¬„Zg6^jÃÆâYY{AÍ~ðÖ* ý¤ Œ8€B‚ÖS±$O'ýE$‰®F¾¨ä¼Lü4ûˆ¥ó¥H³h"—ò…±$Öô>ŽaÖWqÆÉä+XÓ| +Š-&ñnh~äØB麅€wƒ è)bœÝ…Ršêî¾I€–‡Ê)ΓÁ¹)7`Ü:Mç—¦iƒ}€«¿xl&àKˆä%,Á±ê~6d¬ÑwWlëå~¼æã}·º«ß’_„̬7Èd„ŒpãVmGúà½<éŽv·} ·TÑý¦Ól 4¬Þ¥Ómð$K›UðHöCAÕµA´U³µ· þûY{mÕØžþÌ<þÕs _Ydôÿ%>ã¿;ËÖ¨”Ë(4oºjÀÔu ]?‡² êÝîÒ“âÁÛ`^oŸM©„‡Ç/¿šî_{`B“,Š——´`&Ë_{º0™f¼Œã9QYn‚†`ÿA੉ endstream endobj 1675 0 obj << /Type /ObjStm /N 100 /First 971 /Length 2239 /Filter /FlateDecode >> stream xÚÍZëoÇÿοb?&ý°·óÚG!pb¸ Іím PdÆ6âŠEéßß,y’¨)êL°Ì¹»¹ÙyÏìQÎ-¤@¹à?©hà’+¡â7˜?©´tÜrêJ(š¨¡ÖŽ#Rn3V DäØUY‡ü^#‡pÉÂaQõ5Z Íâ÷eðÐ6ïç *…ñ~nx«¦6„ |°á¥¦NÞoýõ†-PrZ­j h@euFšÂv¨$Ü×¾—Žá¯–” ¶ \³“N$%uH í÷4WvÈ‚('‡ „•ýAlvP«g`-D.•ÊŒ Öª-CR['^ƒ4g²M8qPráÊAbpæUÖ%hßAa@–}WЛ®wÀxa½ªÁRÇ£Œ\´,»Ì S0u…¸Í fA¬æ~¶þŒ5H»ÕJ#§P‚5ê«U˜…[J ™|ïÀÍì{oö.iîvUÄ¡ŽSËݲ ·³¸˜%˜—€€ÀÚu¢0·dýi ؆K‹ß ¦¨+´QŒ\axfn-æöR`ˆ¥tUÁèJµ °Õš¤s’ã«a¿U nå*æ CdUÖ‹²Ô‰–P»åu _kËN¼6R—’YhÜñ,‡¶¶,ÚÌü”ÖÜØ\0­¨‹‚iŽ©d,ÒRGÔØi¸Jœõ%N6;9™ oþ÷e†gçç‹Õlxýõ×U¿þǧóßgËåûùòm‚»§wÃ߇Ÿ‡ŸÞR¿˜ ¯æg«ð~ 4¥I#C¯ÊÝK•,eà= ''ax†¿-Þ,Âð<|w7?-Î#§(߇~˜áßœÄÌØ]Ñ(0 i“¹Û8«âäyx‹àÂXÿUþõïÿÀr` %VˆóüëçÏïîG„‘3H¶_,ÎWü X.1L¢¿òÂMq`så¡ ña¼êÏòx•ýJú^.g¯çØx^>†7ó?Váݶ,_ž~˜Ï†Ÿ@{~¾ºð˜Ø)¹È._—gó‹u`í÷þ9ÿéôÇÅ¡K9ÃJcˆíåéo{xÍkÄ®¡ îaÝùéa}¬¹7‘R™ t„õ–cò˜V)R 96¢;•úåtyúayúåã_¢´éìKaOì’‰ÿ~ˆ•‹¯¿^šXç÷rsyø{ +ò¹À±`\cÇSr{i1'7ïÍŽú††g''Âð¬“^¿¼úÙÿ¾û¸Z}¹øë0¼?]®–§g¿Ï—ñÓ|õ[\,? ïgÃÇÕ?ËßÎÔ,G¿øþ†cTÚÓ1¶!1Í|'2Rôœ¿Ñ]ýPOÛö­m¿›ÄÓêž–÷ô´–n{Z{À¯v›Y‹Hʨ§"AŒp]Q  3ÇÆÇµž²¯õ”-e³Áÿ¿÷Rö¶B¯«þ`…6¹­ÐFSèõíµ}ÓKãr(Qa¹ÆôÒÊ2²'È(ï+£¼%£¬·¨„žØ ³“ýj|V\š™ž$±Bé–ļž?8L´u˜èÉ àа(Sfï‚ 4ÐáEXiÅOí1G“±4ù`äÔ'„Ô™)15yZæ~43hlQ§æ+n´¡‚ÞÁ͆jÑ&äÄ8–Z®8Ae#ž$ö—Ë„J"páŽÁw“7ÚY¢·`²Õ]Ráéøà\#ºYX D y‡zYŸºÿËlÑ FE?‰’ñ‘Åì×ø%)ûègB¹HM±¨ÀØ’w9)ZY²yG£‡ZãfwåS”½Bû6"B úàH¹¤¨°ä݈䡩ìF´ª±ÙˆZQ§ï[“^Oº7SÏC©Ûga°Ç'¦»zHN=>rš0w0‚¶¡ô±$ѧ=’*Â$û*æG›~×éž&·…ˆ6CÖ³'Vž7|]‰7MÁçIRdÊJƒõ¶º™Ÿ îMÇïóÂ5@uÆ"„Ç"„iJÛ€kGž¹S¢Ï2MˆÐˆ‹Íb)í>ã¸>˜¾¸°‚<åÓfØ)g\£è©¬GfÆ‹‰ªvÅM£¨hwpóJA—é%¥ dTáHŠ.¹Âð[éÈ l£(-ÉóZQ~–8—c3CžÃÑR^rƒâØìrsO½ÓcÖHv·-Dd@áb»œCš`Ø2A§Yäv7î§{E³"v+šñe4›t~Éð»Ö­4&ƒE│«wÍ/9OèŒrɈ D?5¹Ÿ‘‡C·Ùs„±x_ wI%Å*m7"Jã˜è°H?I´og¦z{ÞîK‡›é˜Ye̬2f_-XÆ4,mÚQ|Cwèí»Åäç,9GÊæÇkH²˔µN8ŠOÐ%'ª(èAF¾] WX£øÈÌ@ȶÑ0‹wvì„›9ŠŸÂ¡HN0|EñÜ )exù±³Í댖¼ŸÏ~xůÉz;z¾Í±znè¥ýT£ÁQ4¡(xxæR£Þ |ºç È6"wã¨f»¥äý[އ¼t˜×£ßÁÎèŽ×p:Î$uœInø=ôäCѽì/ Zýª]†æ%#j¨É78úàRùæÑÇS'uˆ&ýƒê£Ó@µDi~Ƙ\xWµ8¡S#ä6êæiþ†”hИøÐ£XEXÚÓ™¶ï¨"þ'%ß1Ò·ú»Ž‰ÝƾÎb£³ØXؤ“|Fn¥êç…H$¤þ©Êƶoòç §ÖŒ¦ß¿°Y†IjyLúÒ9ÄÊî@»ïÈÝn ɹDJ2y1roóuxè½c¤åðЛ'iSÊQý«I(׫@VD,ÇŠÒó蔼ï8;ëýyóÿ— p endstream endobj 1770 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚP»N1ìý[ÚglŸç2 ˆ*À]HqœMbép¾ˆßÇĤQ¤ÚÝÕìÌ0؃5ºqèú^r°Ôj¡Á½`dC¥­ÁyØâ"ók˜§D*a¼"\a?Ä1¦e&•Âí§±ìÖÇèÃUéŸBÚ àTÊÉÎmÐCˆç÷ xy'©aºmw |žo€ÑÚ6ðyº@ê&מÑ#b?ÒÏõ—’Tè‹©þu/³N.ŠyŲze Ç·‡ö(¼ï0Š¥š’JK›}¶ýPFÝ4¾°Zîsñ¡‹)£tJà,='ñ:ú\' endstream endobj 1785 0 obj << /Length 3011 /Filter /FlateDecode >> stream xÚåËrÜF`å²œŠ‡éf?Hz/«ÄJ¢xc9ö䔤RII,qÈ19c­ÿ~øœ±KŠrÚ½L“h4@ãÙáÝzÂûáLðøáLÂ(<éE¡Ie½l{öÛÂËþ“'‚$±ÞƒÃÚzÚÆ0VÞû³_ξݜ}ó½–^$6´ÞæÆÓ‰ b!=›„ÆÛäÞoþw«µñ<»¹x·úcó“["u ´ qMD‘ôÖ¡ )iÅ÷+iü«_úÙÅfΤ5°Bé§29ÙQ)©=+U iÇW+eüóU,üÍ*†§oWJøçï/Vë0ŠýóW?_¾¹|¿2þæ!]^½!YT<Zí(¯‘ǘiŸ¯Ö22þëU(ü¢½.Ú¦#HžîÓë´+è-kê}ZÖ<—V=47  ¡-Òjû•6~÷9²»¸~Ygå.­ºM„¿¿+Ê–Ò®{@›6ï§Ó:çýÑáY?Í·e]vxû6Ý—q s[Ö7+-€‚Ûk ³M½¯¥ ÇŸ^7‡=àXëi†¤îèmÎe°Z«8„ƒ™&`#ô°mˆ^˜â<¼¾ÀÃþ'ÇÇ&JÔ[h#ÿÐ#´#„Ì"P‘†_[¯8¾ûìÅÚÉ©†aèÈ‚dN¢ûüÚüyØ—Qe?ZX‚GB’´d×6· 6á·é–™jX´´.w‡*Ý3™£Å±âÔh-ø–24uJ‡Ç8›©þᮩ P’o˜˜çkÆàGƒ.œTÎN¾¤ kÀsOk™Bm$¨{'6AÉZÒúv§]tsTRŠzÏ–Ô£/s”^s`dÚ&þšçê檂VhàÿÁŸ¬Ø9‹&‚]O0ÝŒ«íHó‰".4ï¬P…’¬3 ؼwÞ—#~$MÏuâ44ε0C_Fr rûP3•©cDÝhëoîxá=•[y¼å>”{~˜QÏš-˜k¾®Êº8åêe½/è(n×4Cã  3ƒñá®"€™:.â|Úütǃ7â(Bœ¹ê‚ç™5ʉROpr‰œ˜5jëc™;C1†ì|o[¤5Cœ&”Aß;õHpì¢*ø%ò«&ÍN±5òóÃv7#¸ˆ 01±p%ÿrÏøU×o8$„÷:£9b*öÛÆÅN€ .Ú·då,êì¼é t8=(­À‰éœ-À,»´Â·ÆGá´æ€ÓnwiQÚÝÑkJIJfG+s¡[Óï<¥íð»¦Çp®Ê¸Ï ÿc¹=òò/GT£~UÚ#ÿU.¤ ¢$˜h¯Í}ž}q¨DÕ/ÈÓbÛ¸ã•diMÚ¢9Uèp”tê:`¿L+åþŽrºÁÄ_ÒŠž!°Àîû¿Ù™c$T\ñgœQEþX®À É«0ã`ÔªÓ:+hÆ™˜:ò1€—U¡Jf!—ñšªÌ 1:À;ŽË~¯¹õ"[˜Š:â Ħ: èèáaâ¿áB êÀ5ŸÉ?;ª-V‘Š‘|¤ ¬ãn´+ ‚ºšö#MÖÅžå¹'xV•ciòÐQÜðBAHàj­÷e–rêŒØ»‘DœCSЊžg& jl©Õ“ýRÃãPÀ¼ ÿÚÙ3°…Å/sè²>ˆÀAÔiˆc!67Ñ\Õ]ÊcIkWœJí×é¶Àó–soP5YZñì4!F^¶E¶NL`ÍŠ®£|Ò4Â%€i+ˆNûÂô ¬ï6%ØïBi0²O¸ ê-!¡ÅQÎÁ•ms¸e¾þý ÷ù[²¿iæ·¬û‰h :ë`½|š—]ÁAä°£±¨yOxv~øùj §qÝWTÃMfݲžh!îù™“[†:J„A'œJ&[ —ø01ð‚ ¸™ï0Y6ø;çQdš­™„ÌC 5švjÄa”2¢qûÍ#&M©•rÓž ¿6rAïÇ«÷›ä $…xÈlh5Îkˆê,u&CÒú ¹µÖ*ªf&E5·ì‹x(N¹ D"ˆ3‘DŒ(¬||\(Ÿ#§6Ö¿\®‚Z,ÇS?g÷©ýüX:áÌ8.óÎ÷3 /Jê£gÌPäOäò€‰2µh²¯X@—jÚQBšA™ëì¤*iš²‰@JhÿŸ• ÖaÝ®ÈJ VŸJÆ\A!ÎRVÄï×—åŒÕdî$Ó™×ç¯~6x ÐJ]±v )(»bØò”à d²jˆóëÝ ÁAÜ8NÅÖ‚¸·ƒ¬ïO‘ ¡2¤'4mY'±ËZ@° eSÂKH¡7ñâÞÖ:æÒdÄcql€Åæ V5Âú=¦ªF½BvE…  ÷ ]c‡À¼è[4˜ÈõÜí+pÿ'»=´“@Tý°‚Ä{(È=;‚¦'bŒQ:Š1ŸY*Ïy®+Ü`îS92S€Ý´Í–gïíõ«ï^0èpøpp–°ÒýSè;Ó6ÉÒèiƉ”I`“Åý{Â4ïp±û¾(žÝ'ÄcÛñøÚ9®gÆ06Mž)V¡Tä”Õ˜m+3|…8§åÀ¤áœ"²‡3Þd6‹²‚÷‚¬V’èK }~¯»Ö14IP˜©åqÒè@Ω?yï·µÂÛö•ÿ—4 ÇÂæ†w¿˜\yêñª ÂUtQp¾ô;ª©ajz駦©æR–‹Ô±۾߶ªß ûþ⠪߂—2šºw]“•`Ü<ëªwæ<æDxX^ïž°õÍ*Áû«uB‘#åò+¼‰À7b8G„c³ŠÕtØßø†òù-¿„èc“GÜrΕ„<5vüyþ箕pó¹Æ YÄuwÚÿ•¢O¸,:’»ƒþ»b}ºÃ¤ÉƒÉkV]1åýõ0ëãFžî‹ÆÄ;‹ ‚ÇókôhP:ªÀx·ZØu »7vÛSùTCðSò8¡J0ÞÕŽ.$·å¾¼Ec¦ sy™áб}@ ØmJ‘˜)aÚ=;n&P„ŽwÔçyÞbăæÅì n\ËNÍ TâB-nƈE…É‚:²»ÿbØÐ&ÐÒLJjù’Å‘¡Ñ‰·9VšÑ.6Ã÷2Cé¯à T‚mfÛ3ïƒG_ËÀ{¡-^³­§è3Z¤cŒWðf‚Pº>BG–'$_è™F€ò²é[‚·VIâ–÷@-¡×°Q2RÔ!£;  H/Õ°a#91n—á `‹Ÿá$Ëþçå»ñ~ñÀxƒæ†ÃƒE€$1ÿ>Õ€)`>dui°Y‡N_†g}õÒ×ð–°¢éUCeo 挴t8Ù^H;S½àv¼ òXUü?:ªxìU¹¶àû}ÜË*ƒútŸ›ga‚Šùd(§…ïK Ÿ%\’`oרýþÇ17ƒp5뾞E zŸHp½$8Æub´ÂBøD¢¿ ¯>ˆãîBñ”ön ¹ÜÞ3ˆ‹ÁÑ4G1ZúP‡ÒEÅ4Ûή@ÀLÃÉÇ—I¦Å,`ú,ï=ƒŒrµ¨=³”ñ¯×ï¾Ý\¼ßß]ýüWˆ|µÔøKþ ˜¸3%¿+žpžÇgYü}g”€%ëèÿûŒ–·.Rš@€àëP‰ˆHZ®á´>QÃéùÕ¯6ýÿôòþÄ¡>ûª\:Ïê‹·¯/ß\nˆ8´xís{h]o×ÿãs…Jœ±j¡BØ–¸Ûä”×Ãg93££<îétÝ)U4-¤×us_|:¡w¥‚XÚyqùòd³!´‰±»›~Yê#±RŠ"qPT¶áγO4Ø»q°?íEÿ>»ê3âÄéc?œÖóûëQAøœÄí÷ AU—Xû(Ej® ᪩o×Ã]·íYÝÇf¦ªwíy>p ¦Úß,i@o6ÿ@ÿ`¨Ý·§|~PËÿx =x´ü‹–,ûšÁ&> stream xÚí[YoÜ8~÷¯ÐæeÕ@šá!ŠR^f3Ù$˜ ›É˜‡$ÈÊ-Ù­u·Ô#©ãøßoÝíøÃâK,‘ŪùÕ!6õÎ<ê½9úñøèÙë€y1‰Czǧžâž "ÄÂ;N½÷þ/ .ý¬:ɪ²^,¹Šü &ýt›yÝT‹¥ô“&/ óìÍ>O³§æþ]¶É’:3 F8'lññøç£WÇG1˜žzÌLE•·Ú½ÿH½è?{”ˆ8ò.t¯­„\7ÞG¿Q+:%ŒË öÆ×êÌ;ôèÝ›vÞ0"!^(‘4ƹ½¿<è£jºš«­'Œ8J)¥&o % g % Th0"Á{á­z-¢bøÓÃ[¢" UÜqT‘íÖÍØ’VÀ²mlÜ„-…vìh7Ý zS×ß^¨ÖlõÍëwêýîÁʉ%."¼t+¬8üóåÀ‰á¹5W@PŽk{Iû¤µ—#{¹–’Öж’Pšïx©¨7 4ŒuúvA3Øahëšâ6›¨Ý‚£«3å2Œ ex…íÓí©‘d" —±AšóAå9 N’¦»*/V1( ÐúîŸn@™¼÷zÜÒ °×¢<Ï. ÏuY77àç?ó:-Ë›Œ'ãñÛ¼¹Óø,Ý# šKÆ`õÊÃ7`º;[íÜ0»«Â`ú&9ù¶­ÿªhªK˘jîa(ÀøÙköö€€M©‘B³:-«Á¤£ ÀxÛYo|—l¾-óÞÆŠ,ÀðÂæ"oÖWš1$,f®÷ùçÂé ¼)Dè˜EÀ>¥Û.l,ûSó²bU]ît4t]M,Çær—˜Ìj.ÛØu²•WM}§ñëm²ºƒz°Û30>úšýò9 $ŽÀ‚ð:—œ)BÁ•våSdòì5ºÜ¶'#4lßû?³\G´^àùÕ…2Zr!ÑþYO‡³/:M³Ô¬¢¦´HÞÏ?ß½þé×WÏï oÏbÉàÑØ:üŽ€ßðïG@Æ£ïø‚AûjµxÈÁÈÔâáñ"¦>¨À%õ·ešŸ^šû¤Áz §~~²o²ÚËSû°0×l!¤ÿ%¯±ÈÒäÅ™¡îì@ƒwO q¯‹+pÓ¬íÉÌ‹EÇ‚J¹7`¤úÔ¨Y*ƒì 0" Ü€U¹Ý&EúÜáÄ-’ÆWÇãâ‹T0—^|áj¦8ÁãqqBÐIq¢%aúÝ6Ú$¼¥ÐŽí¦{¨âËcÕï±_¸_x4.¾Ú›FPk¾]Ð ‘+¾¿ÇP|‘Ø“‹/2ŽH$ƒ™ÀÃý_²/»¼Ê¨o˪*/l}g“¯²¹túm“`rÀ.„6€PºÉŸŒÜÙu1þõË»_ýqL^þç·Û0y2çÎ4ÄæYzo®†v2i¶Éë’ûq,€ îÐù/ Ë®v^(ñ·ºŒÖlÆC» Éf UŠ1¤Ê`©- A£m´ÐÑRhÇŽvÓ=”Ëx¬ú]ËeDï2$¸ ÉÇ.pµ›Æ:}» ¸sÀï1¸ Ü^» L3ՌDŽ0ãjpáœÁe¹77õ~BºHŠf˜8|Ó´µ½eÿO&Pþäóä•ô2«Ÿ%Ü1+0®ö>‡˜ö%JÉß’ól¬\³Nš‘šëä³}XeÛòs›û¬!öŸSð´*·Î¼–ôâ寶ïIvZV-»} ‰™AhçCÔЇû+L8Ö $˜Æ-Ô¾ }É?hfŸ$u} KY¥àcD¤ŒÁgúEáÍᤄFýrNOHƒ>õxëÎs'‡3ò7d± Cæ¿E&=éæ”´Jl“ÔêÛ¬«r¦K'`¨(üàsŸZ¬§­¬­÷'ÿËVu­åÈÅÖÉÖÞíòhJ ë+w©`b¯¦Ï~c;%»Ýå½N0å6ÑN' Z;#‘ÑÎ8~=<ŽÁp[t+Y‘XˆiŒñ9‡ÌejwuN{ûXD Ö‰"ÚØÚîa]ºmWÄL\EÜKdNF¹ÃÅE`e`Pº²Þˆ¨+{Ä“ˆrS~”+0åþž›9‡ìo< æQ”Ãvr0ù•ô¦—vþð”0{‰÷~i‰iÖYcÚ¸C‘`–Â~“Ù~g½·cžzWcß>øÖð¶èr:Iu/ýÊ‘Uš¯³"Š'§¶û­F¯]¤&_:êÛññ&?Õ‚4¹Þ^3aGË¢>¿ØoO´ÐRX œ{¨’U“Uµ¡éé'͸Õ¤È\Gs;{oÏŽ)‹&É n²ãnÑm^®r“N™ÛiÏ5”ïš9…n¡3Mšä6ÜW}žèƒvÑwmvɄҟÃh[” :óPX¢ÐVFDS|¥]³¸ýð²X2Æ"bÿk~!‹y­„3Ðaüï7ç¡þÀ›;PÆ&ÊØô@ë(c“e¬;Pƺeì¡Ì=VýkΆæØäÀë˜c‘µNß.¨D{`Ž=Žs¸½”Rp* )˜+7w®Ø‚W“=Hñ•¹T<©î^v½‹Òr7e{„áÚÁÅ\Ý·nRpÕM’oÖ~%ÄûIF…D£àCs™dTB….óf.ófWEÛæÜåèsà!¿ÉBw\ —g‹p …+Óôí;Ó ‰çÆ ã¡×ïG¼‡ä•ŠàïÙÌÇ>;Ôu¹ÊÇi‹#‡!ú=ÕÚ9Àïúmözù U¢&–MˆÇrdkÂRéx>ÑCØ0Œ@9°i N˜éJÎHF¼eߤ&„4ÇXVWõíÛQІ´”SQ 3‡@ ÞŠ(²h1"N?ö`\y¼ˆ¨O^âj}øÎ0ë>á "ÈÚäÙìâAîŒù3ù¤ð³ÂnèKÓÞ&mÚÆIf®í²KMÛ¼GýÄ\в ȰHª§l1û E;ö«ÄfáÂe½½¬ˆaj’º ,ÃÁ4V†fÄÓsÈÔÍíש¾:œÅXÃÓ× Ì‘t‹»ÏV¶GrÚØ,Ëô1y•ࢫ¹áøkŸ'›—YÒ:+ çñô‰¹ŒßŽá¨7 §®Ó¬¡õèAbÀ]zƒ£T3JR€Q[(i ¿ò‹¶:Øí\\ÝïÓÒô‹™ ùØ-Ð~"4‡.1‰Dx‹âX· Tî›Ý¾V Æ¿ã‘àSÂkÿŒgö—G'ŒÙ%9h)Æü—ëd·ÀµhqùºŸ öÿ­Ëê¾NûÌ“dúˤ‘ÐÿÙ#  endstream endobj 1801 0 obj << /Length 2791 /Filter /FlateDecode >> stream xÚÝZmܶþ~¿B t7ðòH‰¤$£E`ûb#qZ7éýàN«Ë©§•6’Ö×û÷áÔËêÎëØuÆÀ‰ïä ‡ó<3üðàÕÙó˳ó—R)Ku¨ƒËë  Kâ4ˆeÂd—Ûàíêõ:T«¢½*Ú¦[oÂ8Y=[ µÚîʺìúv½Q«¬/›šú^Êmñ„Ê?U‘uU C&Ö?_~wöÍåÙogÎÀÄ!l'YÌã ß½ý™[hÿ.à,J“àÎŒÚR'ð­‚¿ŸýpÆíùý— 8>g¡Žp–A G? ÁR¥B·œñ(&i%s§üýÛo7ŠóÕ?P5û-(§þ•tÐßXeÜ€æÖ‚¯Ph÷žZoQ¯þ¹Ÿœàüe”Œn‰›PÂ^ŠNüí5ÌŽø*£Ï¾©ÊüžÊݾÈËŸx$ ¼¹H¸1õa×IåÆNoª-n×!‡S@éo¾·î{ZÇMêïÖ‘Z5v»â®iDÒ Œ'A©zèØNvì–µv^Qç¸*ôî{7·¬'ƒ.íâ4ðX ­VæÜH–ÿßËwü€ñ¤ 1?¯¼E ¿j!‹áð¡U—d„ ¾”íñúr ¤/ß­¬¢mU3­À©k‰d´ TH;c½ v*äTUüžwtÄYìשr£SÆ~áD*¨OCŠ&8œH‡<ÕS 3à*rôÅ/û¬ëîšvk½ÄKpÌ'-–ÁôÍ„ÙÀâmVoo‹{Zœvú€5Wçóõ†SâM©“êòÆ`Þìv™{¨Ü•U…¥=qYQ{yMß D‚u}OãÐÆ ¯5“¡GñÍ­AÍb¾úøŒx?»Á@ÝTö«qÞ|õ¦cyS´kmòÝໆƒŒWNó¶È€`Y,p#‚÷úé  ¹b,gœ»CÕ—€®GøqÞeUïÀpwUÖ&„è˜GßùÖ„Ú±g½º>ô¢˜I’#M¤Ž}•¹± }w%@(`| Òù$‚ænÛmG'¶®-šBa£Bk9?Ö.#åf0›fgØ™YXò—X¸¿ÙBw“hE‹Ë"Ù,ñ–ðO"<‡CÌ>æpêˆz*Ü~0Û˜ÄO'ÇM›Ah#uh,¼‡4t‘Yôiⲿµå»²*È0 2zO¨'PöÏPF |.ÀªJÒ S1QtZyU· Gϲ^½ùÈÚFW™g›m±¬ù£c¼ª°~3ä-c‰~2ѤŽy£Q·Ö#YÃ}O⣣ðÇŠeyõ˜’¤`šû¨Æ]>þÃÍ?¢x“ _Æœ%™³ _¾'è'´Š¦h%UÂTjýú_QY û¾xºäb1Ú÷b>j‚CÞ5·l_Û˜ŒS:“irO9«s;Ø€ ôt ÕO ¹[Ây£º·£‹}f}ôÒû„ºì:t‡4C—î`ãV:ˆíɦ¶h »ó¼è:*Û€fc¥ž¸2®æ†-ÎmíG…žŒ>£ƒ/.0V7‘HW/qù6µ€ 9œ n¡]ˆ¡#žÂU‡îúþÕž2ÌÍ2bI⡀ধ•o2гì»u2éÙ™©kx¹8³ì¬6UÄ$܉:³=C„Ò<¡RžUU±]Êp8°ˆç’?$ópà¨a€dKj`B¸hï(‘ªST‰é&7ŽR>rþѪ¹ê37i²º’L‡ééâÅ–þ^û2G[!dé­HÍÀ€ÿMQÛÛHñ™q;טåýT>Ššë¢ØZÛÛ`ØøýMãŠóÇx²cƒ˜‡˜õ‡øµHf€ »G±`‰òÉLùi óQ†MôÚ,°Ëøú¤æq¢x‹™˜e ít˜½¼ùH(ƒX4Cžm{¥~9ôåã Æ!BnÊÄ’<{9A¥÷»lDÓÀu5ME¥Ái@eîˆ^Ž–›9OhѨC7S-‡ÙÏC*¸ý¾ÿËÅsz ³ù3FØl•c%XŠÔ5<ó8ñNäbB`0 ö(¿ÒvPC¸£„ÍT½ÀxÄS×l‰¹tí¶è,y/¯Féã H¦ :O^´&ÈkC® ‘Ë3¹‹³#>"´à!Ó±š&pb8ŒŒ¦¡Ï°‹mˆ†eM ‰-/̺ªZhF8SfËãi€cL o¼y»u+(~Uä™õ‡~®žè>¶àÒQ¥nzcƒH;¤ìí±(T=>Ó …辇@'±Ét ˜±q&6NQ³ÍN:Ò]ûŒm[L‚,oe×m³›¦y3 B~ØSãð]xiMÎjãÙÚ â”¡O®Êv4ø'Gä¢å±ÛšqÞHÇL –]Od½»YPR(Y¥3Ïöi“µaÇùì©ZpÇ©L$fÓT&:¨Y*Ó7a²ÎW|Êηða9>l÷¹Rµ_ª|'¥jÓÏŸªø§jU8OÕ*9Ú*¤±^P ¡KÕÂz_BªWBú\LÕ† è[ÒëþƒM£z×aª]o=Ã;èhÁEj5w‘Z¹Hß„NÀW¼+ð-|XŽÛ}.øRåûR­ÓÑ´œC°üa¨vÆzA5H:ú" Ÿ—”C€H!Ò“ê1 _~`ÑA^UÑ{÷ú€kû—¿fü;W !•§¤\Êuýçï²öü¶½R·Ûü|ߺœÛºB1®“÷­ëC÷'tF“;ÇÂ=æ`‡¶øÚþV•†à}Åùÿz<þ¿51×2!†ßÇØz£eºôW."eoÃ*ší?¥5⤠endstream endobj 1808 0 obj << /Length 2848 /Filter /FlateDecode >> stream xÚíZmoÛ8þž_¡îƒ}ˆR"õÒO×mÓ^´ÝmÝÝÅB¶åXˆ-y-¹Ùüû›áÔ‹å4iƒ^p×í"âûËpøÌ3CsïÒãÞË“Ÿ¦'g/¤ð–„~èM—^ä{‘Œ™Loºð>.ƾe»Y¶+«ñÄâÑÓ±P£Å&/òªÞ'j”ÖyYPÝË}¾ÈN)ý>[gi•QF0ßgbüûôõÉùôäÏÓsOÐt’E<ò曓O¿soå¯=΂$ö®u«'þkïÃÉ/'Ü,Ý}™€•sæ‡ö …·ƒŠƒÂ÷Íf…`‰R¾Ý­àŒíV2iVùõÓxŸ&ŠóÑóý…³Í‹KAZ,(±.ÓESJŸC1/ÒZ w†2l¯èìE·Œ{_ÂÜŠv0'|TÂ~0Zì7[LI= À,¼5 TÀ,4ƒ®Ï‹ºìt¨³q FÕTøäÚ4]Ž%̳£ŠY:Ç‘¯ÆPý–ZØÊz—ÕÇÉvT³ÝcdSVY…Úâ'£=­š¯Ìv™Ïc”j$ᯌCx¿ð= $ [ ŸEx $«ÅLý±¯óuOˆÐ¢é#á$eb»€ÜPÇ·Ø£'m?dI"mÃy¹Ùбâ~ Ú@Yè x“ ~<ô&¤pÔ¥\âÖ¹Þ¦N\<V=1;¾ÂUô¾Fцª`÷pìe cŠÀS¡Ï‚@â…òþô m‚«—œšõ²óЋ¦”ÒÅkÈ)æ ×NF¡©,ß*¼y+ÛøOww}¸`R…QÒ )¸o6s6esµÉ­í¤MoÉ›Iç  =w=èÃõþæÿ'»\z¿x H‰B=ÇÏK§©ø7¹·jÀª`¾ $ìÐ×RS¦ÆIÍÔlÎÈ˵朅 P½ ¶ÞšsFFéh¹˜¾(–» äknÖ 0_+ÐI˜0.à‹. ”ª¶1aÜ5¨¡òA²þ¨Ø×À’ÎTÛÔ2_† ¸,I:}g‹á¾“Ïî%"éÐHmºJÑ‚Ÿé¿ÿ|:ý×ùÛ§ìÍ«);þq°ùnV_Ög݆wéGÓ¬€*”»›;t¸8{s[«°3ì|•—Ùöz Ç ‘D0Öýÿ=\Ê=!ð&|tC™j›Íó¥É\¯ò9Z‚e·h¶8XÉy¾Mוò’¾(íSJî+2ï\î×ë¡ÎTV¤›Ì åëýÂõÛeézó°fA&ˆ-ê»›…`0å^ÊC¸”m´”`)¬” TßÛ <Öý=VStM<°²m¤o¤Ó– NçŒ@ð8ŒxLL$ò¨Päx‚w2] ¯ÊM¶ÝBT”Iîž ~¿æÃÐ|h£ž7¢!­B,C`˜ojp×)A(mœ¬Lwå¦Ó•‡ºYC­¿ÉƒðåG÷v ¤p]ÐÃr8‹}¿ç<<0Èˈ ØÌ÷y¡†Xqt@ŠãCN·)q|Àˆã†GÝtß äëþ+È ÕåûáÝÛl?6ÒiË7Z‡ñÈÃõR¡: òRI&äm¯¡á€žßNWÛ(ºß:Z-èKAšœàÕQÈ.Š^çõªƒÛ”‚0unÙh´.ÐéyYÔi^¸aËb±*K—Á4 ’ã# ÜYû,Œ•…ĉÙÝ¡D€õîðÖ§ÒËFNp·Ìù9 §CÎør>rÂõJ‚ð8rò˜©~œãtZœè³c"høW­ÿÑ]ï<8qÀb%ûò ´ì »ì ̆Þß"þ–c`—=¢ 2¿ê‚»x݆à¾[d¥¸sYÛV’tºÈŠ ¢+¨SwÑÕ˜ ÄúÔðò¢¬)q™Öñüât`æè yîͪ9³‹¥_ç6RRâØŸÝƒ,˜–:ë‰ìvÃÇd¾ÝWê*ð‹á6º(ÿa >êç'†{k"¹Ab“Võ؈²W¤­ú^š +ù€~[íX„žD*K4 µs€,:ý6¯ ãáaüE·¬¯bAè<®t½Öº¥•º¢u‘L 2Ñj¤…"%Å× F‘AlYÒwf:Pd0…}ãÓÝ‚ mè’©‘Bifm4FßîÊyVé»,ÖÌðYu£ ™DÀ«Ì*Ë%=) é3.U×1×áËÏú¢æët–¯óúf©O‚ èúàå‘KÖ¾UI(Þ‘D¨FèÐIÔañË ±µo[æ|<ჩ`˜óÆ,X· éï;ýžfOÈ—ŽanRJÜPýÅóg§Ô€Š÷ÅÑ0@%2,yUÿ±¹Ênª”üuzoÑÿªÐ®o endstream endobj 1819 0 obj << /Length 2938 /Filter /FlateDecode >> stream xÚÝZëoÜ6ÿî¿B(¨¶°YR|HÊ}(š'Ú´—65p8¤E ke[°vµYiãø¿¿©×jm'¹ÆåC–¾f†3¿ŽÌƒ‹€¯Žžž}ÿR‰ e©‰LpzH‘°$NƒX%L¥28]ïÂ׋H‡Åö¬ØÖÍâ$Š“ðÇ…ÐárU®Ë¦Ý.Nt˜µe½¦±W»rYSûmQYSPG°(bbñ×éÏG/N> à"ˆ#8N±˜ÇA¾:z÷–@ÿ9àL¦Ipmg­eø­‚?Ž~?âŽ>”C&9Å”–A,8ã2&14³gûEÁ»ÍyøØ–±‹,G¡.©·-6U™gÔyýüÙ1¶x²F<Ü­q£ï_šá‰"ÒL©¶¶‡]-Ïôû][V Ð^Šz¿º*nZ:bVð„I.üÒ¶¦c?.$ªÝYžß±½ÌZß*ˆ©u±<¼&ê*kPŒ×aÿj«í·AÙÐïf[4źÁa¶^v»ÎIwEp}IœÁR­g…lÚ¬¹œ‘/á,Uf(^¤a'Y[PßʃNì åÁþH»¬ž,ï®;puß.°F]Ú ¹´Ý?¹TU11‹“T2rÆ,•ÎÌaË‘Æ]ÜÕÆI´Ê¨qCãÎ| u«ùDLƒÃ͛Ϯ)¬õP/šµ!àWmN<+.Ê5q·kÊõňc30˜02ª:Ö!ƒÃS¾µ`°©²¼˜#‘L¤±gcŽÓ„éXù ×e{Ùó“0Ç”%FŒ-ÍùBcQFê4¬Ïé—DF/ tF¢@(ŠÑ!^Gb¬¡Ñl³ÙÖþò² âÄù? ÁuXïhRžù“7ˆuYU¡"nˆÖlŠœ\·£ŸeÖ:ÖÎЇõöK¦eµÕ«å¬Èë•…W86oKRÓ?ÊðÌ{ `ï²8Gv³]…ðeKË®KÄΙߌúåjU,Q7Nj²%’ð7§7”gZ„ßíúEtL>Ä"ž ´£ 0•˜` NµG|û ݘad’†Å6ƒ,N3ŒAË‘sN¬MƬ·¶ÕŽ´Lž9æ ,ÄÀ,ɦ¯‘Æ»»$Ì)°PìÈÀÁ"ÒÙ™2w›¶w¾³ú†Vð#‹¼âˆ vM(>ˆ@ŠK²)Å£9ÂqB lÝÀR)!Ðíùýf[®ó÷Å:ßÞX7˜C¢8b†wÌ$NExjU…,€‘­l¸A†Éú q`k=;5š^ÿpb`»ŒÇ“@¼egÖÚ¬Ú`f0œ «¤ŠMëFñÄ©E6D ÕÂ¥á÷ñSÃg0Òþ4§16Ãâ n 6ó6Ó³ @|7ëùÓÈám¤ýkžÁ¸tTÊ{8´:‡ön!Û-,”UvV¹ëËÒ7}«Á¥!ÙQƒPÁõl×Ò@^•R4Ôi.ë]åVœ»S¨7¾]{Pívîb7t@·ÕŸ\óòœÚÃÖ°³-æDw¹ , 0‡ËÓ˜€€Z$µ%jiŸkÕKŒuÀÞOkšÓaN,“D¦ËR•¡A0Ø8¯€;‰Í¢À³Êµ³lé¶=ìŒÒ8Õœñä“sÊuUçWè9±Ü*R†¡µŸá¹°<áñ8Q‹Ð]Cƒ'«Ç»ÕÂ9.ìˆaGË#g[>®®[¢:s„ÖEXÕ=½&q32-íWÑšbãö¸tÌu.f5áE™ÅœÁÏeä9Ð ‹Ç¬ÓJ\ƒhNAT÷ï‚æV,ˆdËÿ½HàÀÒ&÷¶²— !Èçù2ÌÎŽCcã°ÓмK'§Ÿ&CLo² Ô[†Ñ¶­Ý®•;gðä‘Î÷ìøÚ-èX®qr¯É±hádÝU¤ƒNûæò¢±p‡ªso“vç—˼Xúÿ$gáÎEn·Ôe¸¶iÞÍöp¹ÎËMæƒïºuÔâ^—– À#Ó™ À΢ŽÇ–2€áí-£ø€ÏovÛ‹âðx–Q2}cå€[k¯‘ «uµ¼û‰ecÚPp™œÁ„ÍHLØ O·ùÛ”hó7%¡˜T&¢'¤‚·æS2a©S+dXãí?û½]!ÂU)|E‚D†Æ/ÏѬ~üÍåÄø’†5¥“°WÇòéeñu™¬HA ftÍÕ2ÛÐ]߇Q,êó³."K#]F!}†0›Úñº®¨Õ¿I`vF¥kˆåÖ™ûí$V€x_BÊ £ ®±j`éþ•9\ j7Víšá…(å™Wõr‡qˆž2|¶-„ÁôÛmB5b)=C˜=µh\þWžù¡õ×]Ÿ7cwÏê5–.vÛŽåž9„eÏ –ÃÒŠ+‘Te÷(BT8÷›U«¦ÓØ:Æwá5ìQxZÐÙ7qP©ª4á,‰;äÃbÙÆi¦ÒhbÿOÜeÂëE¥ÁôׯÜ\ì‹Ó®if„ d"¯Ö!ƒÌMñpÅiÚ¤›¯I¥ÉX2­µ%WÐÓ,,‡\‘Àm!”ôäƒ^¯ÔþÙå1…0dà©Óí(¹›ÖŸØ‘rزëTþÀŽÂûíx\ ³¹Ÿï~¸•,ÿ¿—ï<ø=ã” ~^uAÕgúÿsͲp`>rêWá"«/íF:}yéË÷ ¨†]°N ¹B¿—äƒc$wÚêÕà–¡B/ñ£½àí~½*OLʸø‹U„ú´%ûQúƒ:8pì€ë”÷LÀ£«¦Ï>yß>=}ñÇ){öæ×üÀ8®XÊã10⃠â•ï¤Ï·¡‘µ>E„WˆM®hëŽ8H?&ñÕ§5ßh‡»Oi¸¢.¦;6öY—’E©™@>R¾Ähc#9œX`Dù„q&[mªÂqÖ:1§Uª³ƒ¡«´Äõ¨I¤¶Kê«ìS¹Ú­ä—ƒ÷aëã˹MæÿÇHIð¡bÐ>A¸dòS ëHèª]§sØŽÂûíxÜCõc•ï±µÐ# f Ô"ÒÎP/(„ñ@ û=   :9Ôã®TwµÇU[´¤h¯Z€ƒ‚ßNËz·m¾¹?bÛ¤³l6U6üè³Í=ئµÙ »ýŠ|¿EÄ]*Ú¥ÕûD‚™$ý[sVaQ$ e:JL¡BE{PёкNç…÷Ûñþ¸‡‚ÂÇ*ßc…B™Ž Pñ)ªhp fV;C½àqÜC¡L¢{‘„Â(ÑLp}'HX€ «‚;gUohÞ¿²¤J¶9Igá3Oʧ¿úü Wœ–ùæ]Øþ€Ömäpv™Ý4ŽÀŸþ„óÄ:‘ d¸-B^³¼Ûb5ªCOaÕ}æÜÖ«Ï©,])w[caꦫ¥”¾¸›×ë?.}9jK3-:Ô†[ûý­Ælö@Ö­…ú[Á[¤ñ÷‘3àfôÜŒÙ·Ž„îÛu:'î(¼ßŽ÷Ç=x?Vù+x9o£¦àmÌàèv†zA5(ÞF> ðF0anox€hcîo‹õø3»[õ¼¨ ªV[ÈÆÏ_„µ¾=H?-¼ÄzXÏÄ$ZwÉá·3Ÿ„ô°â¿WÝí¦ܤºk3?~L|á÷sÛ¸Á¯ÕöoøvÛâ÷ 5…7[÷µÎE*üßÞlŠ\ฯ87E3§ÍL*nÛDp6þcBd¢Ãy¹]áÿœD´=ØX­™Hñæõ±¿Øáí=òKcŒÝr3ß}Gl?¿[—‚ÜóدÁ^˜…Ýú¦XŽ¿+Nÿ"5æÞ¼ÿ‡Ì±Í³…è¿3âßæ¨ô«?ÿIë)ûÿä!‹W endstream endobj 1829 0 obj << /Length 2837 /Filter /FlateDecode >> stream xÚí[moÛ8þž_!,8{¯V)¾Iêá°›6i·»ím›ºw´‹@±™DÙr%¹©ÿýÍp(Y’—f›"8¸("q8‡ä3Cj̼3y/öžŽ÷?—û±æÚŸz!÷Bù2Þxê}ü6äj`ŠSäåpÄÃh°? Ô`:KçiYÑ$UšÏ©îÅ2šGô~d2“”† Ϲ ÿÿºw8Þû´@÷Ì ¨;é‡,ô&³½0o ô_=æ‹8ò.-×Ì“:‚gæ½Û{»ÇœêÍÓ@sæs-°•¼*6ˆGëÁ+ÅëÑÌg"¤ÑJ_9-ïÞ÷a¤ŒÓ ç­e†jP‘!Þ`9ÏÒÉŠÊù¬Xvº~ü\D­™aÞˆKèD‘ªï‡‚ æYz1äl`­ ªsûÂO9Q’ù”(¯^<%Ò,Ÿ.3SÚY ë&ÁàÕÁP«Áþb'&ª)—‹EJÂB¨J× º¥¾+j²hF ò“ÿšIU÷qyì0ìsªœ$sjqâ:HÊ2Ÿ¤Ieœ®—iuŽ–À!ÓdѨ¤óIºH2PEP%Ç'¦Ä>*Ç3©¨z–|IgËñôÕF†,= ˜¢*'Ò ùKÓH™O“*'Ù+¢uµ¡™PÉYéÃŒ†j0ZM6º¬-…-œ¥\Ç…¡—iJƒáÕ6Kœ9 ‰KææOăXñG’Sª²Ý¤8(¬Ÿšrâ4>1ŽÃ$ê•¥¸‘Éîc+5-k±gp*%wë èVUd¥™M }Eu`-×jZ‹+òåÙ9.¦'ê8›&‹ãe•fÔ¢H`EÍ ë£=fMc¾Ht|4ÓÆ`;\“ Aa`íÐ{B¹ÁÝqI…ŪX=°âaY: dPµ¡'hôø9ìóõ†ä2ô;ŸôëhÒÊ;é¶Ig«ÈYÜ´Èg¸°žÐ®,Q2öúO3ÛªlLk(Õ‘¯áiÚÑÔûäkŒ}KF\½âdæ ØPøJ)KΠ¤|ˆ¹2Ô®"ð…¼EÞ¤]­ü0†¶yC }©t¯%‘c[÷Ø& ²)du‡ …­Å±uw(àf ?=˜Ùäÿ~|§Þ[ÖN¬ÐiàãE³ ȇâßø«—÷CPž;sI_Âี—r5½jÙ«©VÎЮ¨}­À‹¯eQ«(uÚvÁA¸fhÛšâ.ÛhÃÛ»gmÊ‘Ž}àv—bÖž6œÐQ7vÒ#Iûû/àû€‡4¬(,i®ª0ss ÉéNÏi²* WÀ©¢Ü‚,ÄÌeƒ"\»W,j ‘@Ý@E¨j\8Ô['ÜnÐõw¸ 6ÅcœÙEJø+#M–ï0¼Ñº¦LCÔÕØx1šZÈïE ‚8×¢–ôtu¼(j§¼i'Ø»¬ìL1pê›ÐH‘š-™N¯•©b?’º%4 ›8|'+ÖölLÕër$"»a9wœÞè‹óJMÎ?\Ó¶é”ô ]ÿW:®ýXÊš-_`Äùm}Ò@Cg;ç³s>;çóÍn¯˜«+ _u]ÅÌY>Iœãˆ´Pæ|Îz®á…ü‹%&@0_ájÂf9žA>Û#U'$¿& wMé.pâZºSÎZƦ Ú¹—É̽­ QÜœžf¶¨V[Uh 1ô-Ö“j¼É7ÆRØ›Qî°t‡¥;,½, bŸÇúj,åÊÂàO¢é4s@=d3‘_šË¡³ÛAkë6îŽ7 ÷@soÊUWßqHX*ò~ï8¤†Ïï<Ü‚pâëa‡`ØÑpw4…f4¶ÇÖÝ}/l|¨ã{¨ØÈÃ6ò¨‚µºÌY§m4CTc#È{؈Û+ ø•Ø(#8ÐK~ã%G'ú—Ø_{•HEü|%U}鲬ìu7bÞéWEŸ‘!cúþÓ»ˆ¸ #5‡ñÉûÅHˆ!TéñwGPlAˆÀ{£äÂ4$ÜCM¡ÙI …­Å±uwß Aêø*‚ª ƒ Š÷TÉV7P ë´í‚fà5‚‚¼‡€ ¸»Ttõ§4†>ãñ PqÙÁÏ1Ì µìFãtr†œÔêI¿ÙHBÏ¡è¶{]'’ ¯ýN—œd¦tO“ÒúbGoŒ=±ÿ­d˜Á®Qè4KÎJ'éèðíû—G‡ïŽßï¿ÿB䃗ïö_½úýßÇïþu´G:„•¨œ7}À´Î“É‡Òæ²´/Dïåá ØºX]Àó`BÔPªÁuñ²€×{ÅzŽû#Ö;°ßýì£Ø#°ÇDË+ÁžÇÊWBÝö1òÕxß»`Û,6d¹L³F@f*Û·Ö~€Þ âƒBÕÎ ˆ`ºùÚóWo˜ÔçM}+<ïˆáÚ¿IJs“ðÈ]!NÕU¾¤—rY˜ŸÈ]ñ öu¨»ƒÇ܆jµ0[T°¢Û«°2ÛÆ× qp€ùë¬LÓ´‰/ùü4-f˜$ñ“‘q^w›·þñǯ˜¡(òã@ßz\wŸ¡ÎÈhEMýnÚð­Ó…)%Y–Ô6%yàe©Š! Q~Ë:1Y›´ägE^–#›rl’lFIÈx¨4spþ”Ê}C2XY¹Ë¿—6n°9§6}^O1¬ taJÚoÏè%­ùç† §Ъœž-eŒknÑ&š¹¯Ôm‘®«iú‘ _‘+"ØlÄRG›-×_W`'S2ëZ_—S-\|¤šOǪŽu´ÓÌAu‰_rÊlÅW« æëØZi'9JÆ·iR%'Ii3³…´l:0ZúÚ&NòEqR9Zièÿ¿4YÊf²4›Éévm+fÏqð5}pÂÄÖd¶ÈŒS-=¥Ú•·Üf‡¹Áä_¸í€¦9•'´iâ±¢·ú,Ó‰©.ÑþÆ8Ù¸I×-›’ e?˜»m¹?þåðŸûþë—cÿðàýöL0ÁvÌزÑCÖæRâð?û¯ß¼:ôŸýþzÛ…DL¶pÕ®-dU§ôìeæ S›ˆ£‰,Š(ô¥èy2öS½{S»©7QV5¹tv¡8Op‰5¹*qý xq)$(°•Wo·&ã=|&’Q”ôC Ì—3€«šŸRP€læ.µ¨^ôÒåßÝJ Ä{Pn–ü-{«0ŸpGâ`û³ðÓý« ïÝq­4Uë+qsJë¢ëiéóVû~ÖÌö¼EÎc{Œw38ºø<Ï·'Fk.J>ô]ø¢´/a—`·ÅB´<‹–Nk-ûC@_\Z¨¸]^È ì굌dc`lÚ­í€rM`ù WÐõO`Pýª‰ŽÇøs’x[ûÙh—sªlZ¶f™M€º$³cÏùl´mñ[_µÎ{3¾ÅU¥®Š°šò¤ÿžtœtÿ'Up6‚ÝöU[&ñWÎË+ ]G!@Ö³ódaË„ë…b {PƒO8H*û;¦“æ7_ÉæÄzJÿvŠqª endstream endobj 1836 0 obj << /Length 3454 /Filter /FlateDecode >> stream xÚí[moÜ6þî_!pÀ.UDR¥|ª›8iÚ¦½&.´+Ú¼+m$mr¹_3œ¡^7‰§¹öš]Q÷áp8/åÀ»ôïÉÉ×ç'÷‡ÂKý4–±w~á)‘ø‰N=&~˜*ï<÷~Y|·”ÑÂÔkSWÍr%u²8]Šh‘hÚz¹ŠY[T%Õ=9¹¹Gåçfk²ÆÐ‹ð¥ôÅò·óoOÎÎO^à!ð„§%Lú:ÐÞfwòËo—ý[/ðUšxol«Æ <·Þ‹“ŸNæ?ð…ŒÂÔ›>ëKï]UÏŸtóƉ åÁÿ~”¦8·÷ʃ†) # ¨Ùäu³ó±£¡WYòÞ"_ †:æ á«PÉAy›Á[šú:…ÿl÷®O ü0Šaº!E ¹a?gOÛÀ¨ýÛÖMÚ“‚Á˜A?é^´ºôìú6‘U^x?y Ei„ …^;Hûè÷¶ª\Á$ -ôCX¡´R‹¸¦“š#ÔÜË«k~Á胥&Â7–ÑH:V.ÜÅrS|̱êåä麊S?ø„—¦ö°[¼õAú2JÉö4Wf»µ6#ðC”¹û±ÌŒ(Àtø;5æÉðìدë íÕmFò§#m«Mv^켫é(†G6 á'V4ˆÒð·Ñ7ë¸ÈL#£xµi›eUïß·d<3ü¬„€SÑÖDY¼Yžïë¢ÜÜY<µyu(jÓ¼Ü×&;´W¼{õº½lo³{÷§ŸžsöÃéàÙÓó;õ?{ô3÷WÊëlÿú߬ãÁ¹©ôSki¬ì¿:û×é³|6ÙÕ³59n¡ð“P¹Qg ?üñ’¼•Rà A9F pV¶¦¦ýÙgMó¦ªs^^8]¼¼e¾< ñv|\Tõˆ“ Ó,¯ìDaծ؃†Ñ”Žˆ!Ê åç×”¬*òU,ǪòÜÜFs›ùé4- A:ú‹¦ý?hš€ˆ"R¬iñŸÒ+dö‘[ÈVú£ÜŠÖ~¯à_ õñã7PÅXÉwnà'ÒXÜå'Rþ5œÒÿXQDƒ0~EQ¿§¢°¥‰ôÿ*ÑËEùÄŠâ< uÂ8°ýãM¡¬(üTDS(+ü”E™°gÂQ¢| )³eãÄܪ¥­±ÌܬF2 £Nðg¯—*‚¸i ñX°(.蹫¥¥·=¨¿„JRÀ†›Ú.b‘Ñ+¸»íŽŠYm¨piñÀÒÔ¤æP|Kä ´mMN/o t’Xj¯ q;ZŒœ¥ŽÝ×e^!sàgí úZ[°þv¾^û:îtâ×@EÙ%ÍhÊl½5ù½%z˜¿à¥ Û|ˆ~$ÔxÇË $$Ãx‘›¦¨q0zµ'<7uÕ4+ !Î!F-6…F×K­YªäBjˆº6›ìÐðxyU”—Tl*zî2ê×ÐÀ3Rìö0eÑqÒró¼hzö86™2RYÔcš½ÃþÊ(X4†”àu±1«uÇíjH§–ë¬)¤§Ôâ‘–˜‡*Ë%<³†ßKzâÖÛ‚Aeü7îf¶Ûo™˜­+$“¢rG 6›j·3enrÿ¦ç.’¾ÒémÏÝ|àñ¨ L>$3Ÿä4 âOnvšeêË>´~Š’äO’íÐ[® Aœî¬´ÍQõ3î;a•гSÄ« ·¾Û  \VUÎÐ;b xH«RX‹k+»jÜDnÊó'¨ÈçÇ&=2.›_Zõ( _;ua%Ã6bø*cznv•ÕÙÜ:«QuÁꔕyµ£ò鋇OŸ²z’Z¶7U1Øu?Jn¯aýeEŒ8[l}g,ž:&>ï¯eDè«”Ô'Œ"hÌêúzìSo= f:`^eå%dð…Ç!TFÉüy;‰kF ÷„m“Äá)nx‚wGß-WÂZA ž#µØà/™;œ*HO`§Zâæ=­~ ¢€µ Š‚Û£•½NìT´³‘’ÅÅ2-©¹])Hæ_$à ’Ù÷Iÿ9î¾&è¦û\ßLüQ×÷GýZBDã¯%âÙÇÉð[‰„¥3” ."vßI zóøNò,È=Ów~'¡¤†(ôØeü­[¶Ö¼Ãí¸©kóöÎã\³Õþr}f=d»Qjþi Òiš#«@ÂI™æÈpôæÈî6‘–äÆAô¾þh|©ÔlˆH<á€ße Ýc_ê¦Kxä“úB+O&‰ŸÄ âþs©H-!Ž:†úWƒñôÂÞPXüBº+äÐ<Ô.„¼Go% â‡glŠAò8 7Z…,èÙšTKÙÝ»šÇ‹×‡-¢¿ <êÄļÏ6°I=³rc8UG ”BÃCËìr— e&+Â(kËÚ6£ô¨H¤]Ò¤„D1@pÓš¶ÀT[XÀÊYIO+,ŒäbkjzÎr)$b.…`²Ô æÜU\ñýÇe³Œ²‘°ÛÑý¡¦lbØ8|DÀŸ©d–,ØyyݹÁUÏ—äFg!M&W¤„Í[€l›Ž¯_—Uù_‘›>lG„Ña=DÝvÙu‡þ6‡Ú¸0Õt™‹`Ǩ‹Ã‡9A±oÇLä’úN\†Ðmú9Êÿ»(wûÍ9çJÛ£[æ¬A?–ý]…à äxeXã/[© ´®.FÝÅ(ïG™*4d˜£!¥ ÊÅ H~r´¢š¡rÍHˆ«K›­vPÙ¼ž‘0ÑÀZ²ëÒž‹–ˆ\¬ŽS¨2>5Ä!&G±è3ÐmÆDÚ×8êAE ÙZìÂO ¶ëð æ ¢:lykwlEËpœBžŒg aeMÓñ:6ˆ8„c>šÃA“é§ë8"1êˆØšÄƘ»¡¸Ÿ$u¦à…[Ža™-4` 6ôzF›D¾è¿Ì@‹ŒÖ4Ö‹¯ÝµUVåÊüø2†‘²Ù°ÇüÒT;ƒ ˜{5ÖFA)£Ç¶Øt)hk[*X%ƒç1¼n%:à >ÑíSâpÌ8í­PO_гÆ[D0Ñ|­IÓ *B—MVR;‹YÁsvo!ØØaâñ‡x9NX“‘1— ¯ÝzÅÉ´šØÕaþž$‹ó+¾›œž<˹Ĺ¯¶±~¯h®¬¶bÓV(_¯ÖÖ—X_̯d€6`UÏ]Š%âÈA(ÔÇžYh}h§¼€gSð_G“ cåÞlŠ‹·«àš»Ò0ìgá2G|æÊ5I®r¾> stream xÚ­[K“Ü6¾Ï¯èÛª«<ŠDR¯ìɉ¬ãì&›LUIÊ¥ni<*ëÑÑóÞ_¿R¢Z3nÏìÁn ¤H>€'ؽ߻ﯾ¹¹úê;î2?‹E¼»¹Ý%b—¨ÔW™Üݻ߽·{ye(ûnØ_‹$õ^îÃÈ+šª­†±ß_G^>V]KmßOUQ¾ ç_ʺ̇’^B_?ÜÿyóÃÕ뛫¿®B˜>Ø…4ò“ Ù›«ßÿ vÐØ¾ÌÒݽîÕìTœÂo½ûõêßW³ný8|Kü*w=4œ™*_ªX˜Õ‰¯TB«U~ªy|ú$»ß¯£ ðÞ´G-›²)ÛQ ©&A9½¬hN}wÊßÏ‚|Þü´ÂÐÏ¢H¯0Ø]KxKíúxž½ÂŸ>¢”°Jx«ry÷ÎÈ_}'Ó…b#ÇÄÉË=|¢Yæ ]ƒ²ÈRïã^Ú1?Qc÷8Ñ{­‡Ôk¨Ær-“aèSsªÚ÷Ô7o ê1öy;4Õ8Ú¦ñ®¤Ø#|èxÌ[nÏ? GLnºž»Ucžî¨oêUUUŸjþèv¯¯ë©íˆLÃÄ70v(!퉂fÏG*Ž¼Û¾kð)f¾t"©TM>‹Úß¾ú–Úal÷ƒ¾<ÕÕ1·Ý$–dÞéPŽjýÔº –ŒIC¯a:ô¢"½]Ð-/в0C¬& ý„(=[ÿÆzµø"XJ;–- ošø…Ñûrà.ã]l›1?“ K¿¡x«ñŽ”ÀY ÎV‚IJŽ*Pq¬¢žû‚Ž„×çÍ@$ó…^õ9>’µð©#š5>¹ûî #º‡ä¼:zºçáÇÒ¬Çè’Š¼ë-6 ÐÍÝ„[“$¼@;W?líøƒ–ÞÿD0 Ò: ×Ý{ …¦QªZcyª`:Ø,ø§7 G`_SßcÕ§Zˈ‡ ¾•ÚŠ¡­»u»–¬KyÅìÕKPM ¿´ˆx$Àï¹[™Óš¶¤aU=#Ó›‚Ç®mËã8à[ªTî5Xä:–DÁ‰Bƒø°±é8ÿ Ž-§å«QÖŸ¨­jNµÖH”˜&,F×(é‹ EPMü¯Ò˜ðvMÔˆ˜9㨔‰Gˆ@/ýƒVÝýqñüÊØÏTd¾²«'¼…•„,–ù=qª+@²5¯ e ¢ü8Pë-økŒL k°K£µß’ÎõQ·¢ÕàÓ]¾—†¢ʲ¥§&/˜6€—«ëœ&\NSÑò? ÞIé}ó‰ÚŠò'ϧz|1£ËÆwŒNÜTt-OUâçk…ÃÜ#á öaï´ ZoÀ…Îç€ Äi(×Ò#4¨ë'º'Ÿ† µ#oRi!uõ%n#bH_æuà z 79”G×¢ýó<æ9 ~-Ÿ©Ã*ü ´*\}˜ðöQõhXúõõë­`Ò‚h…„"[”I–,JØ–4›ƒJ?81þ|¿5¢ôS%qD¤›¯…Ÿ¦É®/w·Ë¸ô¡¡ÀX‚x…°ti‡™…b'¤Ÿ…ë‘t¼êH!Áyå.‘xÉ›¢½#߯»²dÀP@¦gL$~E0ál^³€î‡®ß~–ñg¨Ö ¨P‡¨J!”Ê¡£ÃÀ­>+VA¸Yl”mE#ut‡ŒýPYLÅ!ÐP­¾d)Á5\×3=ú]ÄKm=9wi;í0r<”lÚÄÔJ¦Ý˜)?àœ[³Ï3kt¡$ô8Õ ÙaD¼1ö¾€D zRŒ}@{– }P›RLa?LGßèBJº®u B7 ãde`ï)0q±E€bDZc ;†²7A`ƒQÆç82æ±f‰Ìã–¶íÃá©Ý ãF}†Úlz¸ èý9žÙ¢V<³E]*FkRKžß´èúGô-R˜(V¯šz@$bt‡4×QwCÛp×MuAÔÑ—&œD*:"¤ò¡g¢R$ÂæÞF*!½ÅfGo±OÅ“†Aü£ÔZçóªfbWhV²ô÷ð/ð?‡cFwEŒ©„•îªÄOÅåh®b°Xs@'ÝåxöÝ |þ¥˜¾æ…”ö^6•ÖaFŸ}·p)s¿!n¶$è¸ÔG¬Ä}©pF; Zh´™wG  /|v·£†{ar@›Ð@5jŒ zcܾ[çsÁ§lŸ³b+; ù¼Ò}:±ÞXúBý9_?—^€Ê2ÃØ-|*+ ~G³çTÂ…X¼fäiXìrr9ÇOÂâÏOÄb‡ç_Oå±Â8ܦ’4¨ŠsrèÒ(ݤÜNQœTÕ*ºÉÖñÎÓÔO£lØü—9óU½·âlÚ¡Ó©™`Ë,6DOñQ´4¸Å!dê§#:‹ —"´Œà¬FÏÓc™ ØWá"ôð©=¾C„ÄäË…½ææiÊì²óÜÀâs0¼âù‰Êìðì*3ê®F6¡fí¢Nm(A Ó³#â½Àj$ê[•N4!m"ˆVáòb c‡™š‘06b%džŠgìNøQÎc™Ï¢nÈw¥¶ݯfÐÜŒ'˜ ç7ìJù 9؇ƒKñ[¤x8U+½‡ÆD^™€÷õ…)Þë¡Î\ˆßkFHåad[å—œÌ ¬EßæMy)H¯c½¾TBV¯—Œ9z-3áÝß•XG™‰žfC[ Ö˜yF¢É° Ñ*36ðg¡Ç ¤-²ÈÐPñ\¨Mø~àyèôÓõúÔ—D&zÆïè9ãèyì˜Åí¼=GÔë-Š|‘ÚC¶áíÙŠ•Ü ‹•=#ÚSÃ'ÊSÙC†rN™ëuô öa²ù’N¡‘朒-}bš*Ì$¨Júô<•.5¤Þ=*Î%ñmVfÎËxJݘ¾ ­|óÓI×L|NÅF™F©­ rü áî§›×_SòüÍ-%ÓÝíÑMÕТÂý ½ÂÈy«Çœî¯ÚUyÁìŠîM»¢+&ïòçîå1ŸLÓ~üã«}y/¶QÒæ ;ä6#+°~SÐA3ª:¥B…6ÈH؄Ʃ„súžyÝv`µX>Œšï76 ,‹m:¤84]1A@²±s*ò•PsÊÝŠI$&·4³‰9ð¾¸>v…á£`÷ RHSW4«Äs†¨D˜|}Â&ÂÌI¥«Ý˜76rö¼Ò".ÓÞ:zHj`EbXY€/Ùk×êú“/‘ôa³Äg¹*>NN%M|_ÕœUo»Ñ²½êjrdó) ·+Qª¹r>|C`®B^¸ñI(WïëÜÞç¼7å›Eúaœ­óÍÀ4b+ß´ñqà'Iø%éï@ìDûúš.â èÃà¡R¨á±Ý†ðHªBûB 7“)Ô`ƒ[ðÁöÜ­´¶ÇêDÕÜ@mÁ;â@#&”Õª:Dùê®Æ´Ä©e! ½±Ù °9! CâAç¡aìVº´dÚÖŽ9µ‹ë-û#ØÞ RB’k%œL© þ»¦ãU^3>½àäAÞv-åðUZHSn̸"‰y<ç–¡©/ßW&9Jh#õÔŠ¿Õ×!ìÅèb°ƒÙ Cô\ï '_¥­c8cOšÚŸÏÝ×1¿ ^¶óOh§&QeklÈ– ÏD›«XTº}flŽFf×_½þî­^Æö¼/ÿùú±(½v’-«Y>ñuc‘'] 2û"5¤ Îä ó49mŽ~Y_3[|]OOe xɧ±Ã‹s=X“¾ 5†µ«ˆd.Gn$ɨîÈ%ÙÃd*ü;ƾRÓÁÏQ-]-æ”ÁÌî2ã¶Î,Ðm˜e…–aî'¿0÷Y²x“áÌܺ‡î»É Yx ç  "? ¿lóÔ\n9Û<˜s!x;0§µ1é‚Þ«õR>ð%ýòrEÞ·?ÒËÿ'V†}éÙµ„ÈÏõc¶àné-ÑØB ©R޳n6®"]m×ÞZ.<ƒ@fã– —‘Ž‘óǪ.íU3>…Ï-wƒ#•©êçžgQ:õû˜híИÐR •ÔwÏtWF椹Ty¤ÒU%}‰¢ ôìKuÑ쵉æ¿€ÑÉÍÙšPÄ'VäWoÁ„ùÆö÷7"c÷zW´u½‹ 8ظ(½&±Æl¥ðÛùZ «£fS-Ñ‚çc×á̦ƒ‘îÙ‹AAË|IšÏùZ½Iν{·ƒÒÛ÷HnÌ‘×)ã©—‹ÄØÖ”¦ÈP µRh"m9˜¨vα{u£Nnݨ“ÎÝ@¬ÑAë?ÑÎò¾ @1Ÿ†«Û³#¾!ZÉ™Iíƒ6œÿÔòË(æ ZH“Œ|AL7m\8JlˆoP1J¶7ϼÚ:œ'¬;Ú§XD[r©¥ÿ`í€ÇfÐN-5gb4`¦ØéuÇ!­2GìhÛó@»ñÜUŠû>ǽFò¾›t<ŽÏô3 ‹ËëKέC Ó5\|Ò¹ÉyYü–µÑPuewn_Ü5Åδ…@Õ1|øDûcúÚRñ¬ x¼ŒÒÌ{Óš‘µ²Âh1ƒ‘ÆL§-{3J$“bXÑØÂIºy ¸`‡í€€7Œ™BŸBT´¸õÇæœtÔ÷1õdrzµi>$é} tÍÄ„_¹ƒ¬/ðXmyM—‘h > stream xÚXY“Û6 ~ß_¡·Ê3±–Ô­öi›´™mÓ6Mü–dvh‰Y««ÃÕ±;Û__€eÉVÒãÅA „sïçõÕ÷»«ëCéd^û±³ûì2õÒ$s’0õÂ,pv…óÁýyãG®îöºkûÍÖOR÷f##·¨Ë¦ì‡n³\5”mCs¯Ç²Ð/ˆ~§+­zMéù¾'7Ÿv?]ý°»úóJ‚ ‘N⃺ÐKDâäõÕ‡OÂ)€ÿ“#¼ K'³ªvÂ8…ÿÊyõû•˜Û¤3ûQ–ž2ýö3莥«ú×Í&îcÙµM­›˜Õó*ú«T‡þÝ·‰ÕŒ5¸OtË2;}¬Ê\õèk¸%K«ªx¦Áž÷º/;µ¯x8´¬EFn§š¹²á k¢ÊfaØ¡Ôêr4î0SR6=²­Š¥…EÞ‚tˆ:„l+¥—EÅÔl¶”î­nY+"ž‰Ýk>ncòÆc¡ÝÓ½¤€9°V-p€´ýШZ¯Ø*(¸tn« ŒDõ‰ÏEߦL6áê²Óù@ôÉKµ^.5g„:¢½œÆ}ä‚Áë=“H[¶v+/ %vÝY¡–èç©¡*b>4압̺Ȇ‘„+›3kó‘ †j—ÔÇJc)úÖ ‹…8¯dâØ ƒ3£?úRœíY ¸göTvh†ÌЮ¼#¥1¨,Æjj‡6oy¦h±ZjÚˆʽ?¶äÉ@›è°, ð<,ü?¶úg¢Ûýpƽ‡i¸7 ÀQ<[¶*³ÊÈ=L¦žþ L<•U5ÔX Ë£ù<ÎfŸ›ü,%Õi–2ÖûÚ m)ÜtBþÿ=¡™ºM(Üo6aä²Y?¿úžˆº-ÆŠ×Ö#% §ìxœ rª6ß@pF¿cçy&W9U¤÷¶tz„ÛeÚ¾yµ‰#÷æíªÿ>"ÿ;g}!Ö@Ùm†°ƒœ‡D°k¸–î/ÁÇ+0 ÊQF»—o‰ÈÛ¦ÑS! ¾ÇPR;ˆ"¬Âx}Â%òT‡v¬UVþ°¸„Š-HüÿfEp¯¤Â]QxB!<¸–±‹ˆ¥ÓÁÄóÝkj(Û}o?ô2„t€ö4怇^êùKÿY‘óaCïÇæú—Û5D#Ø> stream xÚ»N1E{Å”¶Ä3~•<#… p¥pX+eØ]ÄïãÄ ‘‚jžš¹ç*xsvÙù-!¬¶ŸÁipä%…Ä–üNhÃó°ÎÃnvž_4¼í»m7Nƒh OS·ÛÖÙü£kóYÍò&§1×¥ÖÅ*.ØMdï Ë{Xß‘tÊÁSÏ–+mé/@ÉYððyØê¬/qìž©oéÇøë–!©í¿O¤§¢u…·ª¨÷‘_½¦7aø$öfT$’¢±øuš.¬`Ó_wöàGÅÅ€/þVYg endstream endobj 1871 0 obj << /Length 2816 /Filter /FlateDecode >> stream xÚåZëoÜÆÿ®¿‚y@n»O> ôƒËŽ“´pbµ@a¤,V<òBò¬Eÿ÷Îììòq¢)r€¢Õqwö53;;ó›ÝãÁÇ€/ϸûþr&àËÄ2ˆgFEA¾?{ûžп8KÓ(¸µ½öŽøÖÁ›³ŸÎž]žýá…AÊÒHFÁåU SÁ.‚(•Lp\ÁÛðÛÍÖ„ß¿¾¼øyóþò{;Dh¦t$qŒˆ˜âq°•Š¥BЯþv}Ï..—F&f±Òåp¶œ’)(FB1M«=ß(žo^n(=Û(ž¿¹Øleœm+Lø÷×oˆ{•ÌÞ*Íít[d,qžÃHž„?l$ËnWvm”4,²!Ûe}IíyÖyçÕþP—û²Ê‚n«áššÚ¦$R{E„áº+iw¬êa[5Ô0_# ]‹Ò}ªŠ²ë¿šˆaݺ¦€ÇçϨ°o‹c]öl³UÀõ›öj¸ÝHf]‰bƒF·B°Ô¸=½½®ò ¨¹Kã°jò¶ƒ¢ m— eOäẤŸ_]b! oº!ÒÏ¿¥Â>Cu¦JV÷-•fŒ»57«¥ß64!ñÓXþ}ëðÒ/|µÑêŠ3½C8‚Ó$U²¦ðãܨ¼mÞq¥?AQÀûC™WHÎ]ïvµg#?1K•"~œ„Ñ|»¡6|>¸Wjȸ0®k÷(κpØuIÆ©™q‹ަJai»d±ûPW».ë>¯°4Ö¾ë'2Rh¶« VUÓrgœåÁñU8’é$ :ðJwˆ?¿„SE³Õ"n&ñ«½-vNçïiZçÛNX4šMc& –ÈPº‰?[èʬÞ[›âá <ÍÐ7c« ²)–6R¢‘ýs#`×ñ ÿÑÉ(¤Ñ Ä“¯•t½ ä¿ç½^”0ðUV “&FÏüÏ“‘æÔí¤šïEÎ0VÌcÉ5Ô “B t¹®QÉAù¬f‹Sø³ÃG"øNÅé4#(—ºM+ޤ¦+µ_p¤ði:>-—CEAoîû»·’åÿóò]?`<©AcÆÏËÑ"àl¤‰ûÿXs,æ¥S—f„“V_ƵŒúòÒ—¯áíª’E"î4—ѳe BÚ™ëÕà†¡BªŠßrŽø Üñ_¯Êm”2¨c‹Ç+‚ƒ ú´ !š{:ŒÊXs8}Ëgp~ùÝÅ_Πи%þŸåxAFa[8/ `Ô|Êø‹ç}Äø­Ÿý§“9,ñ_“r)ä2$ X‡ð:dâ ¬ekáTF,ŠÆ¥!p²„XÑûÙÓ  FÂ)l•Ã(€\” ”°™d]e c<„Ý»zØ*€bìbCO,û„»\š‘—ëöX;tsìGx„ba©ÉöކZ¬8”™ë ö.CB&Œ°ûwFÁÎŒÌ0g8øWp×K¬´IaM¶Ú»¬é+Ò“»êÚ=µX„¤ QÙQÙRKíYÓ‚º; °J›ÄkÔþdt# ë£-û7d&ž,y¾A€‰Ôh)¿>UyéØÄMº«w@2éh”7ÅÎ|8U½¡yÜÖTÁN¸ppªÍát N‡‘üx°¶4“,­ ñhÜI%CÊ'2€è0-G&_À¥$—Z>–Ž[ÂÒúèf'l.c2b±kkÇ]‹±‚ÄC{8ÖŽìRlBªˆ¡/ÒÖëÎ:óyg1?S؇ΔªžÚ|¾‰ ó~½„å›SÆ~ª{LïV“{L¬ë";Œº<5qý í¦Ó£bl¾>•œ–hï1ÓGË·Èȉú%…I™–éN¡ÝO[Ú®~—_! ã“÷Ä4^¤˜%º+†®$'•Qš>Lì>-K «‘oÈîoŠü^'¥!‹Içz}Òú[ Ø:'QìÁ3\nÖ+»ÜÕì >ŸéÂÊ zoû»*¿ã†΂¸O5Î plÄìºAq8Èå•u¢Çz ‚½öÀ‚_Ëp¬WŒLTÏð½S;6 @èùmÎ޲§RFŸO˜x—]OQxI¦¸÷@°šÂÛ¸ºt©žuŠvó?obƒ§Ì-|åD$Oä–$Wì¨F‡Û5¡Â Ç€cÄ00O%˜@;˜{¡YLTtȆkMxv•²uqqäÛ©V6…»b²×8+êNÐòFu›£õÞÌõ?ß™îÔTVí>!cÁ¤R_EÈð¿f-²&s§û¥kë*w;ÓîþÍw)‰ÀÍê¯'Õ¯í–à€*&´ýÄíšI;ß&CÂÑzyxüM$xhX ¸Æ5ÇÓ+ƒ½ïOâ§Gù4fR¬"йJç]sOÚ0„<®¥21bù¼Ýï k©ewaOÄÊ"tëð[òèéaG~ýIr ÑGO0 Žhµ=Ü(aH<åç~W¾7R1£ŸÆ,žD˜ìÍê">/Y— ›hÙÖ%hp.E/ÔGÔ°Ís,^(­fï5PɳcÿDãŠÆC&]$ŸÈÈ”‚cm[+{(áY;;÷õƒƒ{U[Á¾¬Áw¨ö® àßÛB}û-ý—–ôåЇ|íÌÒ#¥¨ªw e½Ô`C…?ò´cãÍ]CbK¦ë…•@\ŽëJ†®Á‰âÏ–/®Ýq-Ñu7¾³<°òÙýžÏp€/8>Y<ðÙÅý$a|Xâ‹g&~zIHavûšâž˜ýìÉÉVñAÅÆ'[ããhNçvõú¿‚‡_Íz´JÍâ%Ë× ”,ªÉéó”â³ç)Å$s9÷Ä?OÁ|'2ü®ÏP“y­¾B!ê4‰üÿ}…Z:_ÀÄ1F8ž©»]Žôè‚9æUsôɪÿ¹EC>bð‰5¡ç;w"þ{ú+$%ŠO„„fü°ŸI¼Z‘2Ð2„ÛÍh¹4,ù¿aë# endstream endobj 1767 0 obj << /Type /ObjStm /N 100 /First 974 /Length 2269 /Filter /FlateDecode >> stream xÚ½Z]o\·}ׯàc’.93’…Ôvê6hƒ¶ ´ü 8‹Ä¨+² ¤ÿ¾çp÷]­¬½^Ý¹{ç’CÎ×™!su )äê=4ÃßšCnÂZQøYjç+ Ö+ ®…„>€(¡gS=ädõ 8ófȲJ&…a¬p¬æÒ9Fã åŒ _4ç@R¿y¬-¨ø^¥C®ì˜¡)¨Bþ~mCX¼-™CöÄsu, % ªø 'íÆÎ-¥ ©PLH£˜•”ƒ×S`¹jcñ2x6~!Ak! ^n8rÀì˜ck«cHÚó˜ K&¤4—)ŒiÆ.µT‚Y)ü­lbÎÑ ø}è[k5s ,Í*^€‚6¸4Pàk:ÆpPTAË-”Ä]j¹äÍ%Á¶€òPLÈ')”B4(¨8—ßD@)•ý¯ƒÂ(ƒ‚Â(_(v¾`û8)†ƒi»u"ÚDô-ÑÒD䉘˜ÛfŠ;+2œ­^~üév<ÿåíÕ¿ÎVO¯o~^ß ùÓëÕŸV߯ž]äñÀ%¿ÁfIo‘®XŠÆð£-*Ba)¹Ü'c»_†Õ¯_]hê«øòíõUÌ=ê×ÜûE$ɪQáEZ,´V·Xa§pÞhZI’—“¤æ˜¢›ÇŠsŠðM&¿XºpKTs,PŽUl#(w†1¾D×~HYPÌÈœ·Ä0zG¬Ÿ)HY^5f‘5'‰LdÉ/ŸÐF Vš‘)L%6€ó™>Ì4"£œP7 Q™)Ã{˜˜hCÅ¢˜pGDktd0É%ÄUq `&K9¥ VRLH/’Ö9"[ïÄ‘îäͯ—ïo×7Ðè⦚»ÄDœhß&[ªL 1„O‚ ‘˜ÕG€á»ô°;Z9ºÙá½ÏˆÔ ¤yI:Œ×feü‡ žÆ;Ÿž”HÛ>µ×GBŸ®û¸¡çãqC›OKfwàJj–=بDPBÅQ¥¤D#8Þ)ï› 4ä]`,Ÿ»Ãþ€¡ñwSØA„©·«‹Y=9?3¬žŒÙW/W{ñ=ÿ}õïË·ïn¯wùîí›õïÿüâé«?¼|Ÿýõ‡¯ïXf—™–¹Ãˆb޹ •Ã,£Û5¬ÿ5¥ÕsÕm™ÌSøä÷ëŽA²^¢R–Cæ-å{̳ož}®}®}‚£½-i°Zzt”QD¨Q:k°Tý÷ìÇŸ&›Eˆ[ÁkØQ ÐÊ‚XàlF Á¸ú)±±ÀF™å¥'Ê­E#˜£¤}0ˆ—%ñ¨#lÈ'1Ì€OQ)?$µóIAßÄz7£°3Ëow?“Qî2±x@ay˜5ªzTêy Ùì¦%¶†t["ïÛmÏ·Ùø9Ö·Ù–žÌ®Ô–(Kº4]˜;ë À'Û@È ƒwEå©'ô"AWÕØKCadž +ÛmÌý”’äŠÙÛD’”™ñÌÆb‚¹öúE’l¬¹Îu¢:ljv™œP]ÕÃŒ‚ZÁò0#AAš#_.(còœQ¤ túxè¸ë¿;¾ýù ´7ç¾ï͹ïÍyrâ\&ÂõfÔ»^{ð‚ò–f¨òxÿ‰‡ wÁ²·'ÔÛð]ƒOc­¹HäEA&Ê«Íë+EY™ÙŒW&P`‡¥A,Žy¸ØÜO…¹ÍôâÆÏyñ&G†C‰r˜Ïd,è cqTöHi‡•wöŒ‰ý.] ?àÒ‹$a¹Çmån+‹:©Ô±—Á{Àg pQ ²d8iû¢²oèIæ¦Ì1Ì;L£qÔü(­?¬ÿÐK}_ëjó´Þt_ëºmîó¤kKè¢v}דK„^Øzñ«!v~¡<¶~áuEñ_"O.!LLýGô>зõ%ÓÆÔ•CžÈ<Ÿðb‹ß[l}Výâ{Ρe¦sì0ŽãÛ˜tÆÃ®,Ð×ìžhgõv¿ívñpvKL`S5b± ÈØ²@1ÑÙøÏLØÀ¡‡Ò‰kNy¶Âj$ñ”F:“ j>Qåžç´<–”&Õ(ÆÎBŽY6'-Æg ‚$zbirå©o¢ èá}=|2 ýöpÅ&iÉŠÍRÇÁzìÀyˆh©0‚%ž—ž¸1•ëF+W±F×(FÏõaãµeåè£wšY¤6vCÆ- àt°ØGÀ6hØ aw°,T#~¶ãstˆ-¶b‹bK^ôÁ2 ï4±6€ˆãaV²/òᙢ3õ¼ÃˆàØ<ªÊÂòM÷rOc®ø—©pgéõÔ×aZÝ?7hÞ·BŸò»OH×§DïS¢÷)Ñû”èÝ'¢NÄö‚L«‹âcõ:’‹vçU<Ø*ï·IþìíûË›Ë_n.ßÿú Á.€qJãú hãÂØmiàT?e_Å:üuÜïË‘7èŠ å*/ÜIÔ”O׃[Ad–Lx3³@>;å ‚ Ç$×™òвl’\—2»Yû_í±jT endstream endobj 1879 0 obj << /Length 3514 /Filter /FlateDecode >> stream xÚÍ]“Û¶ñý~…y3K$H¶Ó‡8v]'qg’\ŸìL†y'Ö©ð#—K§ÿ½û’¢¨Ø‰=iïá,Àîb±_P°yØ›—7Ïînþô·PmR?µÚnîî7±ÞÄa⇩ÙÜå›7ÞW·:òŠvW´Mw»Õqâ}~«"/?–uÙõíí6ò²¾lj{9”yñ·¿-ª"ë î(_k_Ý~÷åÍ‹»›olloúqoöÇ›7ß›à_nߤɿ‘°Ž›Ð&ð­6ßÝ|séÁœ“lb?…,„&õmøVÇÌÇÛ öMÝ—õPä@Sx÷msäÖ©-ÍŸÊfè’=ã0©·õ•ŽÂt³ü¶›kCß¾DžÇ6ñ­2k#ßF¹Þü¸ÜO mÑÝ7†?Š"WЋ|­Ê&Œ­ (ß„FÏf³ŸõBí‡05˜†þË4ù´ßþ´ëýæ› :Pæøy9Jõ‚ÿÿVÑi?b´0ú!0¡‰‹HFF.€¹p½P ÊÁïQ§hŽã­Mý@á×Z?ˆkRy¸Ó­UÊøIZ•‚Äe•Ïw?Tå®ÍÚ'Ö`?Dé¸DÅ6ß¼ÙF ö=Syæ;`m•‚S‰x—¡®šý»²/ÚO²Kßm³Õp’ZŸoö¢ë>ñΈ úi ×ý$•X¸/°{{°E˜&•¦^Æ Ssk"ïñÖ`áÿo}VVƒ›ÖÈ@Ó'Ž÷`Ùdƒî gthûâÈÝaès^[°Žnòä(º‚áe 6©+ez½/‹ŽqJ™»:Jxõê¬â±SC@™ñXö˜µrBÀ­VÖ˳>Û±A†ÞÛÀ„™jm¼nØ#êYÏr>Ó±4% aqZô]¾‹~úh!åާ•³«câØÍÙguÝô¼I[ôÌNɦ¥%¤eUÅ“`€\N™ÀŠzœ×1E¥UÌ¢š3êßnV¤ ÌV)3º²Èi û¥ÐäN‰ÔO¡Ñ#r&Êla¢ïºrWQO{}ÃÐ+ÚÀÝ'óvõ€¨µm‹ýÐvÅÊq)m|£Æ%_x¹³^8!½fÖZVô¤a$@¥~¢Â…µèø­¶‰œ—Máʃ&Æ^Y˽Èr ìhÂAð™0Ž>fÓñà@𮋠ÈSæC¤õÓš¤Æx&¨‰aë\P3Ž“¥ ¬òÁ²œÄvï²ý-ö»G²Gm.aÉhG°“U]ík— †ºæ(-’|™ h°–aëñPŽº¥ìÆ—õÚúEíæ¹yŒ}¤K‹;‘8‰ˆ“œ˜UYðÚtîV9'yßA᪠ÁÝZ¶Î$~ªR–„&ç ÿæ Ð÷uùpèkVVˆ__Gb*òž¶¯³Ó‰¸øs0•ïÆH÷ØäC%m :ßUÇ|wF.Ô ¸ÐÀăÄÅYýXy4™›n]l³VtÜÉò©Á&y ø¶.ôÆ(WŒ7"ˆ½W=ƒÀÿÈäÞíôõëçϸÅ1àÓ­¼ÏØ¿dµl2ù2è4àG 9Fè슾wí“x«ûÛ0ðF}¨÷´žVRËlWVeÿ´æ»ÀáåÖb0±q4œDÈʇÄŽîÛn`ǼùÐò»¼Ž;x`97É|h5Ûaò”Ð;eý¡Î޼‘ñ^Ý/èqãÜ+ê\6G‡¼bwLŠñÜh:N­³ü—F&Œý M9+rsìå·aa²0ãížñ½‰w¼¦mñç…6Úxnܬ\r*#*ùV«`9gN+¤Œ6½`ÊGõ½dÌÂÂi8g ¨Âì,+åÊa ÖTå^ K³ûW±ï—f‹”ˆÌbÞÂes‹°`cØð4[äWD°…Ô%³À20+ƒ-ÆÈ+‚HC_…v!ᦠ˜àühÛ…9wl³ N¯¹Ê-º3 Jù)ØEV›¡¿rô*€¨ÀÄ3–JÎÎÞ¡ )B/Ûî±M1¨Ù½`ôÎ7íºøDÃ[eN)!î¾èºû¡âµ²/R_î%~ ]Ëc!“9¢ÏL“Kœ#\®H‡Ã+ž)k=wE{î“/ÖCz<õùË3/²¹»~¾ÿÚ¹ó~âS¿¦ìÊD~š¤ŸFÛ/ta©ëÀ• ü$µçì}Wœ2Œ@ÈʤFæ¦Îžäre^hN)êòÄŽ1(k’VÁã_=ÿ‚!%¥4ªgT˃»ëHP͘ä÷pg.µ‘6"ácp‡¸§)þ…)³4' aÙš_'ƒ¡‹Ï”a9+æÈ^NN/`ï ˆr$4’=SúK£’a!‚Í„ÊnèY°0ò(buƒ]SãÙ³u×L’¿Høî{9û¸(Y‘A¬œ¶•Cg½;]åQ‡ò²Ëv|OSMv¦+Ķú: ÒTb¥#±b.ÃZ{v/ q›RÑ-!T„Ôð€³•ŠHª…ˆÑFbùt¼‹¿p*È~‚T¹=ÑÎ|6KLÝJ ɨ¹Þ¤óˆ :“’ï„BŽÅr)礑oƒE:¸s7W&Ï“ŽnØuÅ· R^°fꙸ´]1&u‘/íëh"&¹\³—·úŒ”¬â@›ã]Ñs€2ϲ~)ZIÅ~¢ÕPtþ¨n3óó¬êÑ©ÄÜØ£Vìdü9JÊÁù?²7(/×’cc:ìÉ©ày†)7ÚŠ,Ëv±ø^œñÊž¿oç®üE6™¥Œ´†5;S¸²X1’p E-l³ŸËãp䯭Á7“WœãÍ/88ç;®äÌæXÏA 7«JºžÐ–±ø"Úƒ«6g«ƒY}Ä“lηBñià¯sØå¾Xu&¹æ…:=ê”JYw5E»Ýp$BJ5,ítW£OoœL1Ãk¹#Ý)ÛÁvêJZZRv}–#çŠqªòXöÎm¸‘ÍÞëTY–ºQQò›;Ga^pÐ2T2eÔü5QБ&‰§t‚tìïcÆå¾|0Þg¨rn“¨°œ:€”í¾,è.ÃÀDΘ{T xêœÔ磷éØ<ÀÐE´°yQø„ÄŠH⪊€CRã& ÆZ‡±JïyëU8Wsra¦ØáL§qÙ¨”¦£%†aઠ¯S xèàEM&©l›úÈr2˜oŸDé7jN7ÌUŒìRx… R°bNÔ(á0çѪyp$ É!‰±à:À˜˜’ج¥J<½²¾sŠlfÎ) }=彎‹Ë€Ò@~<&O¬~rŒÕfy³š; œ÷[16BUhå¥ÒºÛm-=làîTRT¢ýÖŠ ºHjš`p°û3ìxr$tEßñNëkÏ©±^¤ø™e›*ßs®E·FòøOô( ÖÐ#õ‡?JZãÇ)üÑôˆ´Ø8V´VЦG¾UŽÊm8B‚i¹`Únÿ=þ¿ò÷A­éÿÐjZº¡o#HB§µ ~ž¶Kg.ƒLC|¨(>æÅvù½xÁÅë•\yÁõFC¾ªC1—oò×7»ïɸGι5øüîï/þñùoxvõüÅ“«÷úÕÝGÍñüŸŸäÙ÷ß“‹'ßOüŠÍõÿ4s3¿“€ž”üÑŒ{c˜C¦‰bç'ú~烷Ϲ„Ö!d'72þLQªxE€M7tÆ‚´)Nƒ/8Ä\^Ò 'A_¸ úÂYÐw6ú5Åq3ÎTl-pŠ„ˆY}n.˜ö¬’ ­ó\Wž ž!;I:W “]â‹cÝSÍ¡(®pû:™1U’tVeH8÷%”²£‚xÏ)&guQè•–pj›Õ]¶—Äg¶×ñd]¼&üEýÒáa/ÕR†u¤xBÅñW":Ñ¿A„ù¯D0éЉܳd|÷éã{"€W €ÓòÓN–>“ªKõ‘žëg–D¹¢@/Ë$ÉÙ{X"W'qÕϵ\£é¦fURqÌ·EÅöú£ ý.Gs9ArS‰¥ãUÊž¿MÍ8ã"”wÌx­Dˆày!HÈN øP>xµd5<Nƒìr¶úµ,‘3%v+¢À!äÕKÅÌCÖub6rV$>«¬æËåŠþ€JSÌk79•éÔ“ ’ÈWé˜Õ iÂJ椹"yÝ Y\‚[¶G©¨@Pæ)™óPH*9–Z)×u2+C:²µÁ_ôøÑÂR½ç…kµàvçªîJÑs¡\)œÜÝEáñt’Ç~pZwªÊ}¹('ޝ•ôÚ;Ö?ª¬ÃBëÑ®ƒ™Ã|Òæï2ó£7Š‚‚`QÖ¾<{ˆT4žý¾9 ÌÏ»åOt1!·ü ÝÕ‡ÚWJƒå טԓ‘ä/£ÈÅÁĉÁuµaºò+‹þéTtKšÿ m¿)˜ endstream endobj 1887 0 obj << /Length 1052 /Filter /FlateDecode >> stream xÚ¥VÉrÜ6½ÏWðHVy ¬\ró»b»*‰<9É>`HHÃ’ ¹Dñß»)QR©’è2Ä4Àë÷º ÑMD£»7‡ÝÅ{É¢‚)O£Ãu$XNò¬ˆ2™YˆèPEWñ§„«Ø G3Ø1Ùó,_'LÅU[wõ8 É^Åzªm‡sæº2¯p|i£GƒᜰäÛáãî×Ãîûޱ(ãpœ$Í¢²Ý]}£Qö%¢È£[ïÕF2ÍáÛD_vîhÀ¿~ ø”ðT¸U)‹˜xd¼¼‹˜I"dÊ]Èîxš)3ŒVá1þÿC¢«½¢4þü.*~ýFßÚjn_©¢ç¦Ò= Øæ°‹÷"¿'ö<'…âíprõ~±¦wû‚yt²Lv0#Îõ  §qÝ•u¯ôÑ]&mS—?ÐXéI£uëîfñDÄ‘†8Ü7ýÛcEc’ìçñ!)hlÑkö¢ÃâzBÃDÂä0ψ§JÛ}¥BÞÌCXƒ«ÍÁ飃6ÇcÀB~&w:ÂÓa0ÂR˜ÞKa°Œ¥ƒp2­vð…ˆ¿ƒRNs'f&áWæ)êüÐxéÄJÓ{b1ÁH^(åÁ¼]ÃBF7(\E-Hn#Fãþû½7ݽÌËQ—‰ ñÙ­ÙaE ãlÁpíYpŸÊLºnFâ™Å Ò¡ö,#…•þƔڑ÷"„ò œ‡£:Wås …+oµï1Yì±1ûé4]™Êu”\ÄžLçÓ\jßr6 V—ÌÇÐu²X—¥G_àÙjGeXÞÔ­OO°z÷m¶7ÃÚÌ2H ÁÎ7§~ž K$ño׸Àe–ç1£$ϳmÞãä£ÄõF¥‚xl Uhô§Â7¤-,Õ­A¿'79ÙµŽàŸ¬Æ `1Ö¼sA2ªÅѦ:H¹QFÀX‹4®ëÔ¿\\ çFC©éâø×åçW¸í^.œ“›*ä_®ËÕ–¸# ´ˆÝÍÒê8WPŽsgNŽ5ÿKg'ôvëcãîÁ¥k)#ÜBN"IÚ“O¾ý!s3Õ}Žôd¹Á­cØg¬Õ°ý`—,ò.õtZ ½´XrN2ž=_-p¹lÊ‹«U’ýíb0A2¶ºØóÙãµÈ¾„^•Ñì›N›Ð0ÁrFÆÓMh 4¬ýÌ^‡¾†‰FÁõ»ke³AÊC¯¡Û&sXšòr‹Áp½Å\Ÿ²&tF/¯oÖsßÛ ZŒS韮°:X ’œd窴\/R‰KNîºê9ÙCÚ½ž ¨]Ûà‚î µ8<"ÔÚþJÛ¶P¯d³óÃ÷’’ðâø×Ï¥ÇÏ<Ø"bŒ¯O(µTÿåÍ%w _#LÅCÈ?¢K· endstream endobj 1892 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚËNÃ0E÷þŠYÚ1¶3~-Ë«RYÞU]¤Ä…HM[#ÄßãÄ ‰«yjî=#à,ÉU —w(Áso”°«À¢ãèk-¬é=SšÆa‡ãÈ*e]0©iÛw‡nL«4mRw<”Ùò½kãEÉã>6c,…äJqÉ6aEny#2Ë E¹ž{²Þhs‚×ÞÁǼÕ—ãžÈßÖÏñ×-\™Ÿú“³O© ¼ÁÉ1ÔµçÖM2s÷úµ91M›Sð4g•AOoš4dûž>Oqœ¹Ï†3ÿƒâX endstream endobj 1901 0 obj << /Length 2544 /Filter /FlateDecode >> stream xÚÝZÝsÜ6÷_¡‡›9í´Ëã‡HIyºÔ—¦iÚ$M¶Ó»I:Y+Û:ïJI7ÿý©¯Ý8vêf2ç‹Iðrypðàñ wßw'¾<A,ƒXp¦• òíÉëßy°úgij‚kÛkD&ï&xuòËÉw«“|‰ e©‘&XQ*XÂE`RÉ×Áj¼OKþððÅêÑËÅï«í1‰c¤fÿõÙj±”qþ´P<|~út¡‘º"¹U2ZêRÀÈi‰2%žW ãSÖçômŠM‘µVLºùv±TÜ„ÝeAíOÿuJmyVå̵äuõ†«èbßk¢t5uÝÔùBòðÊʹ侮kàËòÊË]¶qrdç]Ѹ"®öÛ3OòRž/$´—?S¶«®Ì³®¬+—u]±Ýu-ª¼‚¥ÚíðuÙ]–ØO; |v…§FžÊÍ ]¹-hA&¨xæy½¯:jëWtZ—òšÂ6»ÂÖ‚ø•®y[7•Ö%(Ìäûk±ú‚ž yÖkl$áD__D:l]KÖ¶×huã„?C‰>PëÛwnÚóEÒ6yñ-ÖÓð ?¢#Ø”Gó~-UíBà vòJŽ#Uìêñ;¬»ÖÎñ\•ûæyѶÓ}¦«fÖË|,àL€ms&‚ÿ l»†âËÇ^kU K%-Õ01å{gþÁë¥æ<<í} ¬.È1³Þ^ ‚ö±Åj¤&µ÷“ÍÜ$”)ãRô>?˜žâñ¡é¡›ÖÕ=ãuq&qÕRc¿KØvà|ØÝ‚šÑßmE2Iž²HÄ ›•é›f!`gß-„÷%UÚ·;* K‰B‰dâ¬ãÊÒÙMÙ¸™æ2ü ‚(nY(Mé$¤”¤  „T”°#¸^U“5ƒöÀ˜¥œõUU£R®añ>—ðh¨R»/2°4@…ù¦,*Gj÷ÖPÏ÷¯g¤®‹œ´ùa×Ùˆ4 ˜X(GNàØ”þÛ¶ûbÁ%ŽÃ'=ÑMOþ‡”펜+ì2/IçÚZÏóøŽEÜ€‰J¯ïe¶ÙÔh×oÛ÷Í‘í‰ 3i4Û«ÎH+Ƶqê4ÔÁÆZS„šÑ(¨a[ÝyG•²³‘+9ˆ\qxÞÔ[ÇÔ1¯A µÜ”UAõu™c”ÏœÎ]çIÌD“iêýÅåD¼ÕãWThÐf!"C1¬­sþ?@Ç#Šúå^Ò²"¿À1NRÐÑ#¦®ncD³îfC“<Á`ƒêY”Š3s¢cÆŒ¶+Ž™‰S¿]°tXU¶ÞÂÑvCdQè~LÖŽC8Z‡u°µö“MH¥Áüë"á±&pGA&a€]ÀqA ‘Pð. îũ۬šoEà(VLkmɨi&…@¼ÅÆ5êJŽ0ǸY³8…?;¼'Æ,Ò¨¹ž£H\·aÆž”˾²ñö>°ãÃt9Tôæ}úp»²üÿ~}çÁ/OªÑñó¸·°éÔZ6²¹£9HƒðÒ©+‚ãH$ÒêK»–^_ž@ú꛵S´«BÀÓ€À^"MÒÎX/¸7 r[U|Ž ÷õª\À„,ѽ  ú´I„{<$"™ˆc(lŒx§-øù¶^ï®äÎÛ#Ô¾ÿg…›PÖqßLb p…¨ (À"€þô¿ Ãåœ!VtPÙö/Ÿ<;}öðçGGÎ-DKKy|-É49ÔS<|šl[@¾ÑR=³À óT&ß—ÙŸ‹ÔÐ@vwõ¦Ì?ÐlõÙá`lo ÙZ3ö¨ Ϊà  ‹x›y0 ²ž9"%h äÒÿ(éœ#\Š‹I‡p—¨ÄÒ¾-§¤à“Cî0…1ÞpÍ(átÈE¦tÈ@ " ¼á’¯ Êâ ýª $p69Q„ÊìÚð|ÚÓða¹ð© +¶r™4ç`”ìÐñ $ÀP¹&Z]91²Êì@tJո׃B8;^Õ É{˜X ³T)ÒÑÊ.ZóAãX›Ô!ívêg@½CåЂ±GS<˜Ù‰ÇVgX†Dò¸dç|–E}¦M',2=øØfø¬|ß ÅMI6 RD ¶ºóŠê3~(Û,Üâ“QÆOÙ%e÷¶vV¸äÆqèYƒ]e;Ó("sÇö0)›ès©ãI:Ýà¿H¡3mZS(ÁÀ ›Ä…ïmÍMzŽS¦Tü1Egc¼—mfq—!~§äîÚŠRTŸØ“›4˜Ä,áæ‹h7佂M]ƒQX{=tƒ¾Œb‚«êk;ø£7L¼ú$Òÿ”ÉMnQl¸MfƒíHK?Þ¼=;ÕBSšl»ó»è„ÜÅE}rŒ¶8‚f Ë1g¡‹‚¦‚fÏÜ_ ¹°ù1•Üo^!ñ–$Ò_<¯Pé܉9î†@7ÇÝ= ‘e_éñeOá;>L÷¥òНu}·Ê+’/ŸW¨t’WD|žWDr4 TH;c½àtÜç*ý*ò t¯(RÍ+¤†ªLäÙz aãO'ˆ+ì)Xø°×®*;¦ ¬ΔÏÂIàÏà¢yïÝ;ˆ“|†<,VÎ@÷tpª¸3nt¾Ý^0Ãg -Õ1}ëB?åG¤¹—\ò`IþÀ9"Éa.x?ï‘fIùy?«EŒ—âݽ<$ uâW‹† <3½ ÔÎÕ.3[ÃTH>|.P„#”=å顤īuÄ ýåªå4z^Ã…(›2ùù *Ìqr©àe½+FæH¶WìÈØfbc©y¸-/.]ñÌ5âKö†´ 3Ãc·­[È"Ëú &kçX¤Gq×MíËøú™ØûÞnFã‘0©6«èµ IçÇF`oŒV“\Hxô.\.4O–ÈþBÀC:ºi%ÒÍ;$ÀºW (îP%†q}{<å±{ˆÀ'€ò¥hJ°¯É 4œ#ð`«x4ÚB8ÚïGsbœÛÙ7_… ŸÆ%wV©ž`_ÓbZ•s ¡£ÐÐ~%ãu ìÒ à7[Ã_ (ó:Š'xR”ºç¥¿Q°‡¸„©ûû¨™ÿ¿@G¶oHØë¼n†îÿ|úò»Õ£W+vúüçÇÆZöî›òXV7}µÂêõe‰‹>©¢neWbÈÃJÞkŒ•x6žì“KšF~Èûb°|®IÒáâÍøŒk^#Ù³ü­¢l°óîo86hþ‹°r ûì+hÀ·ûEÆcJZ˜/„_ד©aÊÿeË]ñ endstream endobj 1909 0 obj << /Length 2447 /Filter /FlateDecode >> stream xÚÍZKsÜ6¾ëWð°U;S•að øÐiåg%޳ޣ›í‡ƒ‘Xš!'|HÑ¿O7àk(Y²µ^é0  »Ñh|hˆyóÞž¼8?ùùMÀ½ÄOBzç[/^Ä~Hï|ã}Z¼[ µÐÕZWe½\‰(^œ-¹Zlöy‘×Mµ\©EÚäeAmoÛ|£¢òG½Ói­©Â}!|¾ürþëÉëó“¿N8LϾ8ýç¹ÿò¿ïOÑ·ašç`gE}¯`k7§Ôa¼ËŠ€”à#åá> ošˆBÇoeU)²Jï#“nè[š73FϘ\álñBg)\”(õ&…€ ŸI8E xr^c¾*vY0 uN³ŽoàÄX+¨¨é…TÔJÉ'(ìS¢3‚“ܶ¤vvJüAé`³Sy¹!îÜNµowMËevÔÝZ!ϱÄP6ÇÆk0G x—kš¹ˆä…õ§"ÃTÉ“EHÞoB᫤Ç7éß[ìÛ½­0¥gM€st)±CZ¥{mÒ§’4[JÕC žyKe46qFu³é°€ªm7*(›Ðlí¨¨<1äEׇ €HÁ‚×yUèHÄ…Ï´N»û´{p“wâh>ˆä#3^ìæªñ ÷'‹.NÝ…²É;*ƒìµ£nÑԀͅ׵¶™]=‰ÔsO.àO¡´‰æ­õ¥Þ½¥±FnæÃ~ŒßÒebˆâ ¯¾Ã]m^ûlθÕɰ-rš#fÈg—„ZÉ5¼iM.&@tn“²Í±D.ÎD‹cê½™íâëî‘9Fg/…³ñŠ>îb´–:u׵ǎÏçáioI|> stream xÚÝXKÛF ¾ûWè(ñd^š‘ ôt»i’¢mÒzØ,ÉYueÉÑ#Û¢è/9=ìušGÓK÷°3ägÒ(­3IZç~’eÍP÷DTM†˜Þ®áL3ôGÚ<¼Tñâ{ñ`#c–D’t ß@) Br”‰Ó¾¡q7T~Ç?aߦÞK«“|$P¾[R$ß1;üä}Úã§UÜ{SЂ3'ûöuG6—}q¬‡?'æ ò´O·ÎKœêÞ„ôƒÛn¼ô!ËŠ®#¼¾œ3 mJ˪È&ÄCÀ#"<Ò¤Ô}™9ÿd€ªÑá/k…£veý.’–ôÃÑ©“…Z@•o\,ÔE›Îp{ß´~c±VQøû¡¨»òN‹ñÚ´¦Y[¤ù$u×6{/ G`µ »Y‘QøŒ¥×bŸâ·ñ²oá…'qØ• S„uù+W:K³»ÜÒÌ͇=òÈs“¥çjô\7wî Pj›„:Ú×ìè‚vŠ÷ã=A“„Åi¹ôÛMו۪ ."Ü~ µWôT´2Gðïy§3nôNåèÝôHJ'ÃŽqâ¤7Ä<Ú±¿2ß‹ƒ3‡[ÿ9poWôäUH 7ü‡—樉fÂXÐÊi“—] h¼®Ò®í=NÅz3Éåx#àÌÍ–E*¾wñ™žÊÉÝ&aÜèñÜ;TÞéð†ÎcãýÃÅ2¦AŒ7Ê@*²âê}“îKG¢xÛ™*€·q¹ ìŠ1}ZЀéØPf=e¾ÄìgÌˬ£Ö·yƲ¦ÞýS¾T]K'æ^ºDÛ’N¿˜©Óý¡*¾ò é$8ý pn ´…Wn|ã#TEQŒï\ð6€½ *¦9m;!³} è鳊ÁIÇ®€„@#´5~AÀs¦ä‚¡‚lAÅlîøÄŒ˜Ž <öÓÆøm³Ä‰•Á•Q'Ÿ¯ã³¸ »ù¸ßÜY–ýïíÛ/pž$BoÄáÉäTÝÐÿOuÉ,(/=\ši0N:¼"¿2á52¯‘2ÊíIÍLõÕ|„Ù,Bg‰ Âà!  ÅçÄѽJÌ#”Ì^F ¯(2ˆ§+ôÌ2ô¡Î3<™k¥ë|K¹©{åÒ—¼åIòºxìÃ_ãçÿ9m8¾èƒ¬ùõQöñÌ?gòXÀûRÿ¿Ù·ÃÙb`ñ$ÜNµå—’µ9gâ_gž›Í¶Ô,á¾ðþq7¿™4¹Ã\ìßåûo¾½<™ÞÛ3!¼†ÂÄŸþÌ ðîÐ] užS`膹æCÆQÝu¬yŠBABÅâX»B¢é æ\ž™ë/ë믔`²ûÆš{ ¸WÙZ_M$¨ï*›;OÎ=‡=SUYÚVeVº×ßR…ŒcêA¥…% ÐáwþJ…O§˦5Ç&0ÖTýÁm³^ûÔõ6Q¥W˜ëÂ¥<(ƒ 7;bš§ÀhòÜ(|° ¿/÷¾<¹+ûšÝ¦ØÜ²ã>ð£û¿Ó”PPɱ¿4_¸¿„ú ìÿMOyµN8!:ÞpÈ]­¸/7N½#?S»«s<éZ<`|4×YyH+ÏR÷ú.÷-K ¶~9uŽ‚œÞkwÔrNü…¦Ç‰7–°Ø9Õ‚î‚›³9ôâ±Ä8•¾¶uA©Âº!fw(²2uICarrßøÔüHè‘Þbu9”m‘c ¾(@9&~±6Qøè'ºi!kÚ£ÆNM†?x•†9ÝH‡n÷-4}EN+K¬N)’ zù§(ºJ~ûö/¨Ÿî|hÝøÈ"5aâÔ„ñ&íüÁzJ©@aoL3ÒçÁDxOâ~¦r¡[yMêÆ³vCQ׿ôõÓ_ž" ±õÑ?<ÝÿÁ ®Ð’ 1w|¹_Ð¸ÏØS;þbrÇc endstream endobj 1918 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚ»NÃ0†w?Åm‰Ûñu,*• ðVu‰¡I ‰#^·¦Ó¹êœÿû¼ƒ-ºñèú^rpÔi¡Á¿‚`¤¥ÒÕà;Øã"óK˜ãB*a,Þ®p7öS¿¤™T 7©S™m×¾ W% Ch–P N… œüÝyô‰x~Ï€—w’f ÑþÀ Ëý0Z; _ç­¤¶9ðŒû‘~‰¿n)I…þ÷©?éeÖÉE×–TµP5Ç·Çæƒ(œÈÉŒ‚¤)©´tŶë”Ê`ˆíÉ–w"Žk:C_ÔføovÃVö endstream endobj 1930 0 obj << /Length 2963 /Filter /FlateDecode >> stream xÚí[YsÜ6~ׯ`í¾p¶<ˆ‹d¶ü Ûò˲c)»Ùr\*II,qÈÉÅÿ>Ýhðœ±lyì­T9~Á&Ðhô…þ€1s®æ<;`öùÛOæøNÀÀgžÚI–ïÞ3'úó¢H;·¦×Ò‘:„gáœütðèüàð©ôÈ‹4×Îù¥##ß ™ïèˆ{>SÎyê¼sÏæÊ}~ôæüøíìýùfˆ/=!5Ç1sæI¡œ9^äû4äìø?ǧØùàø|,¢Vy_óùäUÚѾðd+¡r_Ÿ>}ñìç·/NgsŸ¹Ïfs„îËã·@jøzF„ÿ¾8N­×oŽOOžÌ„rÞåÑL0÷)_ΤrçǧOÌZ]>á@Ys­<Å„3Ç%…Vß qÞÍcî«øfÆ™›Íæ’I·Þ¬MK¹Íµ%$š$1²5ˆÄÜßQl#1¯i̦ÎË+"UÔŒ7À«lò$nòª$Ú¯L1²˜ÊÍ•öÂmb$.Òx•ÿpxH=G+”à R´?›kÉÝÊŠt~rvçL2ðX$†Õ;fáÚóÎâÍæA¤Ý³,#ezÜ׺YE:kÐîñ­Q7ŠsÝ4«—4{{{; ˜kìâÌ…Š<僻ú>x‘õðj••( ó•{EÓ*¡Fœ.ó’šMQ{×Ͳ˜™«À½œIfTÃsó²FV r“ Ujú„æÁgR•¿2!¯6ÔÇXéF«Ø¨7«ñs›–+=_ƒÀËøÌ®®hîsO* ÏÀ‹§Uò®y„^Ÿ¦°:)ɱñÒ¸ëz‘­«š(u‚ë¹Î–1½£è…íÝT“á½;ãÛÙÔ‘hÝx4l´,ËèÅÓíù.×Õr4T¹7ë…²‚V›ub;¦ùܘ½S‡oR‡QÇ:KšŠû03üˆ éñ¨uÏz®ŠÍØ÷ð&]¢ÛùÚ¦}cµæuNU¤ùå.·ˆ®‰Û Q…kêª(*ÔÛ­õ²¼þfwã媰}7uV[ç»ÅØÁm¢@×'Šl€ù\IŒ£ñÓ„ÙîOlÚÛÄ ªâÒ4diHîÎo¥u®%£n“×déÊ÷2ôð¤¬/F¶à›ÐÒ?øqON2ü¬¼ ‚f|G Àè:ˆ,ýÐöëçìH ðì^ŠvÆŽÂz~¬Ÿ/½Yן̬-ùVxéüä€E Ó >žu^i92É„¸¯KÀ– ÂG¤0Øñ%¬.2 cöK§°–@ ë>+«jûª=­ ¬{^~8˜^H;C½à"ì0TÈçªâKb‰MʺöÙªrau:s ±ÀTx¦4%ªH{ ‚\B÷›n éÂ\¢ÊÛ?F¢…vPûÍ|²U¸ÿ›úñ/PžìÍï9ñ£âãÜÜç¿Ú Ý‹½¼¯º§VqsýåZlÑû owµû0™–]™µ“v7ýhUÞîõ\šh0Q v–>¯«ªÆJAH÷ÉiM®ŠÃ,/lÊBÌdDáBm+Ð ñ-J£õ0$¨ºâ‹”›4¹K|˜Bµâ2Ýo~ÈèßÕÖ7™r6½SˆpXñŒ«7«&SòÁs¬aK21*Å6¦-?ÀzG™Eš.É:‹›¬ã²$*˜Û<Ë,Éê:n+¶@µ%½hO€UÀ#;ÅE]QaºÈè •lJ­ 2¼s ªâV-’Z.Aéu ›ªØqõ~Jâ Š©{--ÔŦɋ;Õ¨‹‹^Mfù¢*Ô‘Åd‚¾‹²[S1ƒàÆ×Ú¨‡ ¾ø.à/AˆE!dF_Û c¾šÀ2ÔÎ0@Å8EâÆ„ÎÌ!ÈÙ ‘§ Ã!q‚!Hmæø±s$OÂüßfílló:³vÛ;½òÈ ƒÎߥ‹e•nЬ~—u”ðtouVÄηCVh/d|+Ôq]\,3ëe;"¤Òb˜ È/óe^@þRÛpfÓ|ìrçžÕå5i7¦¢;2–ŠÇøÉX ½•ð­³RžØï«¸®oÑfÕ:%J ¸‘çÂúmÄ¢;ÔÅBÏ×r¤/˜ '¹ðGµ¥–ý¶ö|„B ’ŒyÐý¹Îv`ó9Ôòž”“ó¤fz©¦¤ª›¸¾®×¿¯nwÍ)¸×mxÆÛAFÊ50Š^‡ª‰Ô'(ßžåaãå“ÇÔ ËC£?x±;lwÆ )m÷…ú9&·r÷)žÃ´3L€ÿ×ÅîBBnõߨýoì>ÆîÑߨý+aw 1ª;Á;²ן›Æ¾sTj7—½ðäMöá27û¬0)ïÃëá¯õÂdú-ÆûB>Ù&ÁïËÊâ{³ÐØ:ÙÙM¾j«±¼­ ÍΗY:0|öe(–Õë®\ï..…äÖA³¥µµm–Ðh˨jû%‘Ò*³r”•½÷Xg¿á¶·ÉÛYcz ÷ä;¯@lM¥î<à*$Æ!¡—ñNØ ºWEµ óôprS‚c (oâ¼Ìì(ÐÁà–!4· ‹MC/iEcìJÃæ³ܸi;Å •/³î AÐï¨×“ÓíÛ[2ücpJaÅõ¸¦Vެê \80àêw£ZÈšP²ïDµ4ý¾ ¶Îï…iUà»oƒeq±$¡&Å×Î9z*R Ê5­…9À`Ö)7eŠG6 cjOò‰ Ê,6GæôØ̜K¡yD~ÓÞ&ùÊøtË‚½z„/T3ZÜlG€©sÂgÌàÏáìõ\“6tjA¾¶›pÓìÕoŠ†îˆ‘XÙžæÊÞël¯Éµñ°hÙû*6½•»$·Êʤ;0×}£´ÑJFרV2õy÷ zwBiá·çXМcùbûn‰G3¥ÜÇ'µYÑ3+ãE1åfÐ6èØ „îàNg“ưútÄDº·Ö š­ù†ùécÑŸÆMŒž/B÷Åå®èWë!Yš×¸°‹"®›‹zC‡;`pÕÿÄ¡q2Üb\%(õ m8ÍÞ:òxÐ!͘lº‹Êd1?B”J$ÒYÔÝÄÛž¤ðhÿ#Ÿaf¼ï„ôDÊ[ou–Ð.‰²õGн€P=¾Ç£­Klˆƒ]p”“0!(ªìiœùí=]šn«uW6躳eÏF|'›³Ôô ÚκKê1O ÛuU´¿kè7Z¨ ¾ÁÕtá×φ2ö—HZccìÆñ§Gc DˆÁ(=šãã‡Pμ¤bZ=X1¯¬çÁ쉣øk óiÌxo%³!^ìQ“w¹!š8ÞìŠFë1Käbº–o úzÇû(æó¡/ìUU#G0îð™–{AœE\g_$À…~Ź›ÒâBƒþ±ÿ ‡ƒðÉÁâÃ}aê¿¶¶w šÄFµ—Äü^ñ;ÔyR><ƒ '1?åúÊ6ÓßÄf­d ‡)=¬¥˜m9»ÌüO²ì›uõ{žZÄ¿ËôthN`•iNÚ*Ó›ìëz‚­G—[_߯ VÀÚù[»–õKÝëø—£WoNŽ½Ç¯_=€×›õ¢ÓÞƒ4yØŸn<´'ß&m| uƒ¬Ió—c€·s{öMKnp»FT±ãï»Ð1€³ÿ§ŽÇˆêèê%ó#Té±Àþ¬SËîG£ C+/7ÙäÇÅ%ÿ¦='»2žd¶ÏéÏô pL¥?äû¼ÿH x1ÉÉ=ßoqw4š¦üs:î endstream endobj 1947 0 obj << /Length 3059 /Filter /FlateDecode >> stream xÚåZY“œF~Ÿ_A¬_è 5¢. ´¡YZ+d9lÙš}c˜V4´€ÖXþõ›YYÅÕ̬.;CQWVfe}ùeÑ¡wå…ÞÓ³¯ÏÏî#™—IÄ#ïüÒÓÜÓ2d"¼óÜ{å?ßpåí®h›n³å:öm˜òó}Y—]ßn¶ÊOû²©©íé±Ì‹{Tþ©¨Š´+è…œlóúüÛ³žŸ½=c >ô‰“µ—íÏ^½½ê¿õÂ@$±wczí=Å𬼗g?ž…véáT{:HtÈP)’ Š¡†…AÄ5éñs¨Â¬©û²>9¬I…þeÛì©th Tó]Ù;[“^Åa­z0®dâ-Ÿí•w[ÓOOQg§q"ÅOÅ l¡ÖÞ[ú&¸2¤n‹×lï 2l‚9ÉR…gLã›T̶°@HÁ'Â˦Í< $ '%Aï4Ð>B#2ûó_z?z`îD¡åññt°!zGb}äc ¨ ËIH™ôHŒ¡môp¤ÇÐ Åjñ¡:|ŠË8‡s:oÁq{[ó@D7¾gc<¾ LóØ‹’(P""ßß½'$Æý3âg5 Õ{µUà÷Ÿù¼­¬›º°q#SM4«‰î£Åd][;ÂA ŽZв¾Ú˜i_´Í;@ zI³¬è:*÷ =mYgå!­º{TQ^nì‚z*ë¼hë"í¯íÈk;][¤ÕžŠxøÓ².Ú`¦ÛÂ~¡·ep0•¢%®-'¯?š~°°¤ßw}[3ÇÃ[K ÿ"1±¾«·ñoŸ0ÐoŽ]Ñv÷òìañkº?T3ËO˜m¾Ϲ1òèž_°°Ö¬ÿ½Íúi&Íê‡oòl V}WfÅïbXÚð›¶ìk-ùÿÂÆi¾ÿ“mü%av3€ôyòn9Œ_B Þë 5[ 2HB+òÀ9çŒP U“N‰\Œ‡~³l œ^Ó:§Â+BßE ªlÚÙèÐò½kYÎÛ4:í²ûO‘õ¶ÿåF†vºÐO©Î³ŒÖ- òuZƒÌ!µ+•Ýšû”õ( ô÷ŽUí®›ceIë® çñ§}‘/Nè–ñ@* O ÃÂRxœìPúÏð0F*¥ÑóeìÂù¢ÒDt «ãV‚Sr‰,ÇÈx `[.±u¶ùBÑ´4âé±Oßl@]«Uwlm‰6Yº1JU5g¯«šê¶¨×Ô늞 e=NôYŠ2 ^!‹Üº_å»}“«¢{}—²J@î!Ý ú8Ò°£ãNOU5ÎôÀ®öˤRFALìO3´ tfüP©Á;# Ûã”:¶ýF™C&ÃKå$5á8_8ÊËþ¨|æ/«á_5qÒÊšÚ¾‚g* ßã\:žˆ²ÎÔ.h; ò¡¦øœükù<ÉÇpÉ¡fëù¤aI¨=ÅD ¹Åã|wQ•»6m-'ë [cP‡ìIMgI¡´“_~¡.óÄàkÀ¨7UžVæ¼›)þ¿ça®‹»þ€€@"Õ}^´ eGzŒ«;ua49öeu—ðV6D×sº;òÁÆa!Ĩ’MTÝÚœÕÆÚY‚ˆQù× ƒ<åÚv˜¥±°)L[‘œDþ /…Â3Xaz] d ø  ÉG!¸†SV)ALÖ(ÎâìxS „¥xXqB±Õ³˜†ž¤Ð4 r=õ)íŒ)=ºâ¶Æ@ØèrzÓD׊3©ÖE°8rW°Pg^KÿëÂòËûâ¸Zœ5kh\\»„4ˆÅ ‰`q óî÷@„‘U…Ìa –cVØNÌŠ†¤ýlp2®{î‹ ˆÄÛÒa^ïð_±\‡j‚áí7OÈ 2‚ÁÜ3ówE²òŽhŽ)˜:έ¥¡pº¿\k¬*j^n,T™»#3È^ Íæs;³Œ;{v¸eû²Gœú1ÇhÅÕG8r,Õ‰#Ãô&ÇÁBÞÐjÌÝVÜ JD%}Òã½²kŽ=ÙN íôÜ¡Ìèô€fs:VnÜ#Pv‚ß 9&»o _Kfî9¼¼4¾äØo³X#ÊŸ£§xu?@·Ÿ*Œ¹÷à ÿî ®íÑ zƒ+Ýá7Œ;p— ˆ:lšõV0®’èè´Í0©\vô$ìÍéÅú§ñ->ÆTˆ+)Œ’!.££ÛØ Çàk —Šp$ÈlÊr(²òçPH·B@íPMãÀö«c›:ÄÕ>ÖT[¢@áÒż´æÉÜØ7T2wL¡'·¡æÂÖ’`(<7¸æ¾IaÍÉÙŒa?´ÑI‘x=PtEÝ;xEñ~£¢pÚÅ.f£5¤v;+À-·KjèI€â|A|nOìMë>G¹ƒ°?V} 9aÝi¾õ®d•²<‘£-EV\Ê€ä²x»æ"`c h6™Ir§3 ÈcÄHeÚÝ w“ÿ}º/VäÄÀ1ÃáЃ€ðDc# `} ª”‚ºªiÞ€+Û‰îæÛBBã¿®Ý9æó&Šc‹*‹Jºâ©¯ûþÐ=¸6[û777 ±¦¯ñ´ÙÏ 2‘Ì·¾1ðŠæMFCr©ØkÀààºßW_Áª¥ÿl0.†ún¹¥'—y®Z¹ i)ìÌ/þK(1²q˜ß^vIDºÈ"ã.ÍðP½¡¶‚nÔ¤ÑÍ<;zš®+wÆ7íSÛE0_q°"­J@M;frm¦N7ÎHëmm;%82¢«²®):¡øšF·Ã'e¨ÄOÊRx2—gŽ«Ñiõ4¦yNÞ;IVѱµ TQ²‚²‰„¼t¸î‚I.ŒÐµ ‡%zNxY,ýݱ'ưš ß ñ°fbb¨G:e´×z¢=¼°@ScY¨@$i ¿"Üt³½1’œ­4byÛ¯®­ ôšhŽÑyÙšøDwuuy8V3W¨Óà=ñ*x›ïì”=Xß|„ó>v|Oïvg 4.^,0Û· PÙ~gâ{ut}ÍÒÄ”˜Ín/!Ï ™\Å&<ëø„Ä\NÐ;í`[ ã¹Ú ³$yb TdÖ›ê–k¦[LA1ËÆMë%ª%(ŒOá|¸;Œ“+Á³.ðA:ÚêŒ7ÀÓõK[ys]ÒU5½žMœ í0›NWS—YZYé;Ä);!¥¿$pÕê@KÉøÄêÝtwYŠŠÝaõ™U[lm¢â÷q1wc—`YÀ äc– å ˆˆ)h™°9ª÷¸±fªØžÖ%Ø›n -ÔžÚ€Å]Bö‘6€AaÄ×m@bék†~v¦°¡™uãVÒë4×v5àˆQxjUD§‰ ðf÷­Bðˆø~¯Ï1¥4‚°Ú&÷•+€˜mg™™½E9±œÓ{f5¤ =N"¥Iâ¤Ë­"û—–æ¶ %Â]Z­-ˆ'©ÿ.h+ –„b‘ŽÍ·´»ë3uÔÕtìÅÉ!VÇÆ1˜ÔÚÂÝbKtYpNÆ“m· ÏŸ<¦Â }ÏÛ"?«JC¯±² é"›Iâ©vð¸ò7DÌéeþãE5u&ĉ q®ìŠW.ûòŒàP£…\~ÞK6Òýk“é 5*uÚÙ\M­äÁ‡ªÌ "ƒ@€•^Q«Ñ3õËޚݚ!ÂÚåây*‚«àÞ™Ž8D‚ÑÙʺ´WÆÛÇ·]%ˆÙ=®AK…÷b€M0/¾Iþ6 öå8žƒÖª³gø‰ÝÔqÅ¥»S< ‰©\ïr¹ÓÌšåïä-ôºùÙàê/%‡ÔÝRBò •NüÇ×éaƒpn/)€4iÌ%4 )/E:h:ýäH+€ar£5ȳ· Õ†}Cš½Ðð¿)Ž,¬ endstream endobj 1957 0 obj << /Length 2350 /Filter /FlateDecode >> stream xÚí[[sÛ¶~÷¯ày:ÔL„âB€džê“ºŽÓ[š¨éäô)[#‰TH*®ÿýÙÅ‚W)®o9É(±‹{ÃÚáޕǽóîÚ'Zî /”^(8ÓÊxóÍɇ?¹—ýÇYïÆÎÚx‰ ]{ïO~=ùÏìä›ïáÅ,6Òx³…Ä‚E\x&–LpíÍRïƒÿj2ÕþëÓ·³³w“?goì0i×0¥Co*‹… gç¯g8÷äl6”Ðè…*x¨„½íT¢iÏÅÚíôíÛ/^M÷O'÷g¿ü<™Ê0ò߃ÀRû¿Ÿ½{O‚«¨wÖ©â9MQ¤ÈñºXàRáßNî;ìp?ϲ”ÈuAí2¯&Bûu²^»ëŒæþ0‘ÜÏÊˬ,*ú]S»-‹«ÉTp¿L6M.rJšv»]/çI½¤îWY Üÿ4Q¸¢P/pÄøÛu–T-+³…ï É™Ä2]tç ]&*‹µ»þóÝ2ÍØd ·ìÿ’Ï‘§ŽzAç:AôIH¢ô²Ø‰ÄªXÔ7x1I™ái rspã’‚Ú$my$µÛ²  †Û=FGJšÔÉ%A½ÿrÍ«,³:Ê™ä rL…ü "ã•`[{Äwç ‹Æô­…+f€Y Þ–Ë|¾Ü&ëŠØ: ©] ˜6q³äƒ$O-üÓ ÐL¢böoá Ëò¬Lj{@ã¯ìIÿ[8 -,œ%Mh0Ó-f¸!\f70/ò:Á+³=¢é0æÿžÚwz[NBí£n±ÿÇ<†»Dã Ín®Ó¸[Òþ&ql¯Ú•Y#i6t¼ñ|]ÌqåŠæ/ùfY_/s¢9M*iò&ùk¹Ùmp"òKëuC”bA­“ Lû»W\-ø¸TP£PUŒ Í­æ ½H¦"K,bbÈ÷Áü½SÍ­÷AìnkôÚÉåºRHB;1N?§QÔÉ]ša@‘¶¤¶GÂâÚ­.ÐCÜä{Ûàõr œ7×Ë9ö¯ûûƒZåɺ¸*vÕP£œX;ô—r(Ò6©ªÜ·(SëÅ L8 †îcw;°c5¹:¤XVŒî@Yòy¢ÎÄ!=[/h”f…N¡€ E×I冊†0p¨0’ÐÀÞÝÄ­€0©gÇq;;غ¥#:WåäÎSš¹oÙA(ý7»Ö×âäª9šÛ¦éo¶ärÀëçõ!˜:·Ñ ïÊ…Á&`A„¬³yÝF¯¥›Ú¿ÂÊÆ?M»c$v<²à~üdà–ˆ#‘,m D£Ç÷dˆ~…꫾ãÃ}]ìÖ.]HÖçPI:‰sì¦E™Bi0¡‚u†«‰ÕV ‚³Ÿé²Z!0Š»»ZÏËJë[7´¼Ì’4¹\;z‘·€Aï²±^œWÖ•èxvqÓœT¢i —În$­"ë”æŽƒ¹sáꋤa^»ë_ ]¿.|àÇr£r†¤Aü‹4kõÂhÌ ”RÝYpIsü&Ùõ¸>)K&€œZ7esÀ$Ý,ó»\³’L‡mš0/6{ V¢‚Ú 1ù«.ÔT$$ÔŒqFZaOvuùS7lú^w€è!–hyN›¶ˆ8d òhºC‚—Ye³Ç§DM{ÕmÔT,2]Ø|®ÀyЧNÓe~EO‡m—ËÙ~Þ¥ ïÎ}X…Ào"³Il9)PÌaR‡¼B5v4¨°ZX§…sj·ÚfÅí"±çÙ‘Q;7§–tÆ…Z{Z¤ÜnWeŽY¨µêKÆ1“V×N­Ó/-È1T(öuv^”ÅÆÉ`M-¼ûë¬t€X-³g´J¦dÈŒCP%›íÚ%iUVUÏ_PoWÑb¾Wäèl®veðyϯÚD=@‘;‰i`ç 1u8{ßL™Ü·[d÷Òù!u{ãÖ)ß¡!PAx#7/d1xØz20 øJö>zô>–&à4mÔoûùtéÿ^ªüÊXè˜îÉûÓÅìIç=ûî7 $RÄÌÀyä,¯Ë[ÇŸ[F˜Ö ‡Ç€²‡M¶æEo¢%ƒcJ°ZÙNn³¯Sµ ¥0J†-> stream xÚÝZÝsܶ×_Á™>”7㣠üjŸÅvÇNb©“é8ÄY¬xä™äYUÿúîbà‡¨ÄŽ=I¦z,»¿ýàùÎ;Çwž}uuöø©Næeq;W{' œD¦žÌBçªtÞ¸/6Aäªn§º¶ßlƒ$uÏ7"rËCÕTýÐm¶‘›UÛÐØ³SUªGÔ~­j•÷Š: Ol~¾úæìÉÕÙû3ÛûŽ í¤—ø‰SÎÞüì;%пq|/ÌRçVÏ:82NáY;—g?œù̺}z8÷½ ñ­X8 Ü#¾+„—EQ`N+|Ï:mê /Ô\þömœ7ÛÈ÷ÝöUóŽŸÓã§ðßÝ å¶#ú°¾ÛòÔâ=*-Y^QWª¸M%ª¼îg¼>~¦“«ôm «ˆÎöãuU゜À?µ }à$ßõDÌ;=*ܶ+«&‡}€XÕxÿw4ãÔ«’ZCËï…:Ô.º‘+½Î¾k<¤Уb±;\ÓÖ<–7¼VÝ·ôâN=¼ß{ˆ‡§€âŽôÞ„ƒG(”]6I ¯ëvFî-ÝLRo5zEçýPLÑ[Â3?¿°h‘Ë‘¦…¡nMÏn—xYȦsµÉè^ƒÄ=äÍ ¶·ÂLÜv7ä•>zº]''¡™Óc~e(É0@Ñ(Š”¦¡@~ò#_À?moŸ‚rŽJÈÄ‹#4'Íãö†æÌd$fF{Dóæ ‡öÆ}n½ám5\<Üß/Ë<»Ý°²]æ‰x±­Xíg§KBàI,2¸ } Û0N¼HÄó«×’Æ»»æK,ÕO’Ÿêu[h [½Ê¯Ô»ªièNdh-¥ÛY²ð„@AÉÈ}vy‰švþýsÊǺ¢ z¢ÞÃ;~»h›ŸüP¾;uZë¢ f€ ¶‡UpÔ ¶SF;À•fê¶D\jÍ.»§g£`­ÒÛlÃ0t¯Œô:U´‡ƒjJÍ*Fæ7bÕÏ×Úo$„1BYÃðùQf_5Èׇªk›Ь5 ÁýйB~ЦɈÎD1/˜üÐU®VM~P¨ Qèž×³é|@=Sl2qä¢mF)£f?pZ‘JO ‹‚€â-ÝûÛ½.]Ïf þ(ß½E&Yt;v-ñL ¬ž3Á«ÖŠâ~ŠqE¢÷dSȱ$¾FÇÇÓ.ôdœ™=ßÔÕn‚výÏ¿3ÈÌKR{vƒ¾+ÀhÌù1ÐÊ>wÿy§~ä%AhxüúÉÓ TÁZŠ3u|èqäÅUç…UnEz©/æ¶®Úî¥ÖÌ<¬¦Örqñ V·ÚÓhÚÊкQÁ©˺2°²ˆÑØq˜®@Ü3ö ÜÛëª@E¾¦·U]ÓKè8i%Þ„Ã. ŒPˆÐؤÛrôãIc¥{l{m†ˆ}ÝŽKkÍI!£µš)Î"$“Ús„\s ÑòuÅ”Ñcæ‹QÏyc›.Áýœ ¨;Ü-¹l|_¹Ê0„?±¦ôôù·k7D±™DŽ6ØñFFžÐÀ†ìL1FÀd´ˆUá¡Á!Ñu…¾Ar MÎ]ºIlé›Ä©ä£ªÌŒW°ebVÝ9é “Y9ÝŠCòZ5~ùäåw¯1Ôý׊"”R: `ÆŸ–rµSvÛ’Z(|òÑä" Ç!Ꟈ Å1I/ËŠ…"ÛÖŒþì±x Õ÷Ç\*†ªÂòú¶ThlF š¥ݬ{Ï„ÕSÀÀ EÎñB®ã¢À“½ >g6³y ‚×îìGÈ–YŽ€ðìñ%¢¬“8YOÑUQ¡Øm`55Yì›ëydR®Ò ûNõ×v½µvŠ/mâ“BÙ)ÎŽ`zóÛùøÜžêTËX×0ÁÎül8õ²ÀÔ‚/SA¸€Ãdÿ†2ÿK®`èü+Y?017ç ñqŒe,ã„ M2šbõOÛMGÄk˜.´®â;‡ÓØ‹ù’Õ‘z:(ÃI²­‹ ´ì]Cwa_õ_mù@m;š\ñZ bÐêÔ¿UÁûM´Ý²Ù)*(b¥'ªVѕԆ+`Oº/ÛÒ„‡ðš ÛT˜°hˆxÕI‰^Xz"‚Ÿ˜Z ’MPHÀk!§Å=EUc> 7@•Ç‘XY˜^òšß+^0Ÿx¨:¨¿Sx~ÈÙŒˆ·SÇ­Š§V=íñD¥·vþ+ò–2¦d 2S…FQ+œ“lnâpdf†\ç6ðŽFBx~¨xäD)&hBŽKÐÅVÒ¥˜x ¾EQÓªï?(m»ð.¥µ±[r0³çÝ­y·ËU9en¸Î™•¦¥·Ä ¼•[.–¯We Sóifj¢qªÏ³Fl»§¹˜kvÞ0ÛM çÄJ„^2qœ–ó1ø]q·@GZϼšDøŸD`U6 ¾@ñŰôvL%™Ac2þ þm)h.m¸9ÝzédeL%á‚êSIÊ8]¶lÑ—c c쌕F>î8Ï¿§g^– rýš\&Ó¡îL£·Z…u%œÄ웄 ­§R‹ÈžWÝáŽÂ-f÷{zNͳ'ÒÌÛânZC*]‰˜…T\øŽ÷±õŠY0:+`˜`‰bªzÏõŒ½›”5ä"l[‘ò¬pE¾y ÞùGcRÿX ÅcÇЯ¥¿à*ÇòèXàƒ»Ë¹¡·É—!ÀËxÔzÒP|LJÅĺ2ªÖ«ÓKq‹î!ÿ$f¹÷]d^£·uó)¸hî4’™³|²§]ûäÊ~ûS/¡#ÒD‡ŠÃ™óÞ¹ÊUú4mÑ-NHŸ„“Ћ¢H“kèE^ tÑV&1Â`Bb:Á­ÁŸ~Ý—(N²qE‘ò´qGK*œpìÔfCKñÇåüq»:!Ìöí|zøúdÅÿýùöÎ(OaЄgV#è«?ýÿTu¼˜X\Xºz…¥+/C yÙáˆÍÝØ‹#@„q-‘N¶Ig*<¿†ùXQü;ºñòÓˆrgž/°Š æ•B„òÔ?€˜ø"ƒóÅ¢¢sŠàÙ9A ‰ÆžôŽm^☚ÅEGÔîvQürߣçÝWèwqyRÂ"©C̺Ê{µ†¬¾­°höþ¡º~™ïyùáX¯¡8bL|<ŠGsÿÂH‡Žo¤ ³$b‰2¸‡–„ºn;Vã-Å—óÇí~/¤û³žïÏŠta6C:é/‘N“m Cҙʷó Ò…ÙtȃµzŠ*2e)åõ‚ó ebÑ0 h(S/5±ñ_­( Ä–yæô ß@ ËúFhxMÙaJ¡JËä¦q©Ïÿä5±ÐòÛÞË/óñãZPIG»Ÿà–ß@ÜCõyï«òdù×fijXýßUªñ=©ÆIä–ù~ß–Uý‡KQ_ªå†Ô¼ƒÜ©:¨w›ß¨Ïrù]»£ä.=^”cÛÓp< ÓŸ,Ì$J@Æ6˺©+£›«¿a“Ò C;{‘5™è>ae€â‡Y²Ä‘Åu{ªKó;†öÆäcTy™ÿ|iùËVˆ(‚ø£غú[\ð@Bpp–ùRº×ùë•ΓÔM!‘ŒeæžÏ2iSCA³1+\pý?³— endstream endobj 1874 0 obj << /Type /ObjStm /N 100 /First 971 /Length 2238 /Filter /FlateDecode >> stream xÚÍZ[o\·~ׯ З$<Î…d!pb¸5Іím =(Òªì Òvÿ}¿áje¯VÒÞN„‰5ç쿹òP5 )P5 ÄÕ‰r1'jÊ •æDV%pÕP²âo ÅœÃZ¨‰£†–Û ”´ø+ÌE͹*Öá\7°²õÁ!äëW°)ûº•YíüòI*F4U§$äÔKÔræ„é q.ä?jÀßE£%ûÄX,+õw ”bÙ–@ùt Ó•Òù0¶%_¬Yà$¾ff*},Äf×FK9°H ’„~…>|#¬®ÈÚZ`óɤáÂ.¾³Uõ)œ¯µt$$Í„‘>MéÓcf"çÇ?’Íç p°+¨AfQ¨Pr‚#ˆ¥þ^™t~ÌQÇÐUû;ðù.px×TœJAI †•ÉU“É›œÊA-÷øµ˜óe Ú•Ô°_K"XõÊ%ç>ƒ0;ÓÔ_<*¾EP}cË. NÞ¬/Á˜¤ô ŽV¤øNUEÀ×ÈGH %•þŽGò˜¾pßšp(â¨k"Rßt_êbl ¥5߆täV¬¡ Té|*9vtSÉ\j¡rê‡*‹ù$Tí2k µ$?%¼*dz €cœ5$Èiãê0¢fZR—°Äa¹N,Gÿ•öë+a¼Ç±CÈfÒ_¨Ž @¤•\ŽŽ†÷ÿ½š„áÅt:› ï>ÿ6ïÏ»˜þçhøev}>¹þ`îédøëðzøõõ‡£áíäl>°åH8v²PõDêæ”"|/ÂñqÞ…á/³÷³0¼ ?Ü`äÅl©Eû1üüóþ;\˜@þ&‰H\·–$' ì#fx@Ò“ ´(n3VcÛ$‡Ž¨Ó¨w±˜€%h¢¹Ó´œ>)‰)H!èFÄ“û ÕH§d»ˆñÊ…Õ`ò·aøç¿þà‹–XR¦Ÿ//Og„!Ã>72q.Ñ}ã ã«ÙtÞE|¿A yåÁa­‹'ãE¬º}òà—rûÔ9mùTüIû–Þ\ÏÎÞM ¨0¼yù* ï'_çádU÷oN?Nކ_!Éd:¿ñ8Ø|¼«øföùúlr³ˆýÝß'秿̾†~*7_Z†¢ßœ^c4¹.û‰Þ`á~]ž}8çìs*Q]F Ùc\ˆj-E¦ú|DLî¶X,8aDá(ˆQðV%ó&›¤u Öm1XWà¥5Çmì¯G!´¶ï€¸7¼jY‡WÕ-áUÛ¼*Ý«æ%ÁKBÆ\ŽžL™q,†´)²y† ðÊôàYŸ}:½šO®c1$8Y„mƒ“nž³"PB 8_æúœa@9Ï®2u €¾!õFÞxNI˜8âR4ñ\ÉpdF»[aµ-­p…ñH°¥>åÒǰ¹–×m®¥Ýlîûm7Ú¬Ÿ‡·¾ïZ¢¶Ðöw·òôZë–°%Q–DÓBƒ×’’%× òGÔ¥ÈÏ5Ún¡â@G†Ôf듼‚Ä콦DèD${R3m$”²1{ò†$R9ažÄ=%ÆO±´ÑÅ€ a/ÈK‰¨‡”¥>-EMcK‘ñÇËhz8 ¯ýáÔI7ˆ±æÀ¼©°•[e|$•½Ï„:=za#ccbýÿÏy[ZÏy½µ°¯wñþʈžƒQy&(<#ģƥB¯´rO•jáÅ9Õmᱚe» +›™àK`F§£Þ»ã’NNW0â½=.üböFÉ:*(ï ¢Qã‰Öè­OË^õÆMì­0’æ8î1I«‘Óêö?ëúÀYÛÞ)’÷=Ÿ;Eâ´¾…\·ÛBãu¸æ…7ïÙ‘iIä%q÷“, ]¶$ʰç)@ßÊ ”ZJPEY!õ®Û¤¨ÃXÊÉétË^÷†çûáo_ûÿ?|šÏ¯nþ< _¾|‰³«Éôòüô*ή?ç³³áôü÷‹é0¿¼‰Ÿæ¿_þøHXß,í"Ž»ŒâÝþÜzw@•"w…?Ÿ¬»;$¤E-x]—zøv‰I${Ær.3ÇW~'HñNkÛR> stream xÚíZÝ۸߿B@*g.¿eµ/MóÕ\piîâ ¤‡BkË»ÂÚ–#ÉYä¿ï ‡”DÙ ² ŠïƒIgÈáÌo†ZžÜ&¤¯gÒ¤esS6u;›Ël‘>™ “®wÕ¾j»f67iÑUõžú^«uùÕ)·eÑ–ÔLJ&f¿-¼z¾¼úx%@žˆ$“0fÏ’ÕîêÃo'e0åÜæŒ ,!¼¨ËŽÒ è6¤ }®™49ešOU½-\†à@„ù šÜXR&¢€×/25LZ& .Î õHK¶î·¢¨:¿§‘½¦Uæ^|.€ÂøÌW~îŠß»òO^7J„§[DÝ’Nè:šF,»Õ#Æ8•¿onÌc`'Ð’€ ”x±¿¾ù;-õmSíWÕ¡Ø~ûL“±æÑ´ß¨ëÿ·aè÷·®‹ÐEè"tº]„.B¡‹ÐEè"ôß*Üd•ðí1…„a6þVeéV%'—9w%¹«á‚û=WÊu±ÙÔëjû]×Ê]Õ}—|¹>zy…–?N>¢Ð½ßŽnîBr&Ýs3Ò_ž,ÿöüÍ“G»iò ,³¢M8Ñ÷§WËïZïógï‘týBE"“Ìr™Ì¥f9÷nµ™ÍE¾H?Ï4Oë#5fЧeSR««©lÛ»˜ÐÝU-ÖrÄ ¾Úv^¼êv‡£±½«[?F¤Õx­Û²AñôSµ*Ͻi¨;±XÕyÐàã™ÅW,ëlCàOˆ‰Z$B3¥­¤§)•ÁY2W –K|Át<ü£§ÁüÁyú´Þ£ãnMµ¿¥—úÏèÕúØP {Ý#93;“Û-õt3|TpõæÞ·¼°vúñàW3y‡‹l”°J#ìËŒØÇƾ,×Xi Ê©y[u%õ-U»šÊ›’X‹›m÷Ü:Õ:j¼vHôi q?jµôi¨Õ”Åvç¾yXd… ®gw ¨tá'ºˆX— `<ÉëgO1/1¨Ï ½)?¢ŽÄòl®¤NKð†ˆ’ +:¢öÆÄÆ]ê~š)t°c,¨£)Ûjå09U <Ûjí9±ËÅ-þW0“(-Ä4P±«e¤ß‡õë©©5jÿ@Í÷ÏÞ~Í6%ùÝ™p§³uŽ_°¨ÄVÁcЬ÷¥¯ ó±nH³´¸Hž¥îû0<ÜU![‚¶dWÏ}@CÈ~l—òü(^¯e­ã~! >×–’î2¬Ë3ÅqÛõt†ÅâÏ œ€¤J0ˆ”ˆ!ä÷š]À« ÁUë´=”« ÝàÂNŠV <þ8Bï¹ûŽ‚•éEx¿ŸiÓ·rÍ8ïÓðýzÅ›¯å HV› A[Ã}®Dú®ÚUÛ¢ÁÞ¢É>ϬI1RµM« ­bÈ-°Ÿ[€åh‡ÜL4#ùxF‹ø‚@±§¸öRweÕP÷¡hÛ„FݬÉsa¬$Që mò1êÌbH7VŒÓ ðÒ ´œzPzõ  2¤hqM’O"ƒ_|©Úï»=¼A¾ö„ ¨Ü»e®©1†¦!<÷¡B#T·±fÚjt)„‚²÷„3>x¬â½heìEè ^DÓÕT:3«7Ó¨§ oÜΤn•@Y d&V‚þÁ9zìè9$oü\§³Î¶@O+N¦•Þ9gìrÆUÜ»ŠWñh¥MÑUa?À¾ÈsüÔsüÄs~ ƒ2Ó9y.h'¥†½]©(ÝcDì½·°Ë{ «ÕÞï;ÊD_Ø €þP…Á%ݦ”ÞÆØ "eó0•>ob§ó«Köf”2ÆóàÔmÏ8 >Þå¾ ß&DÇé’¤Éú€íy.òŽÝmMÇ7h-Ÿ¾%nwþF î‰>sœì‚}VȦ!ºX8ó0Î0ý„Â3h¢Þ8Û%N-¶±tØ'¢3vêá!åpÜsG|‚ÖG¶”ü¼-¥ðnCŸ-¤‡­ GÄIÐIÞgD¨N¬¥9BoØ%p$¥%-è"SMŒl{Î:# ð„Þ<ŸÂµ“ˆ‡ þbK<íC–â#šÈ Ú‡–cnJÏN’§ÜgO’Ræc{™Þ^ý¦-ýÎ ‘õþÐÔê9³ò‘ÜÈñx¼iêãí]ÌA)Ó ´«;¯¾;›×ÑgâHP5¥¿rö‘ëOK íÕO¯¸ n”¹èÏVÍù—³Êé=Üml?ntÇŽv)LŒvˆnuÿ\ðœi•ÇðY†Í禮ï½Âc“hÿÿ8ÄýþÍ«û;w?mÑ‹ú°Üyz¹‚Kl÷ùÌŠàbÎû¢ü¬ý¹‰§ÏèTù0yJyØŸÃû3#ôTÞÄ·uíEM…7H‚ˆFožÃ®ß€ášAƒï{Ö|ÑuˆÌ9†6~Z˜þ;ÑpÓÿæÿ¦;ý/@BK&ÄðÔ Φÿ“·‚¹È i¦¦Kþ7qÑ.w endstream endobj 1979 0 obj << /Length 234 /Filter /FlateDecode >> stream xÚ=OÃ0†wÿŠm‰Û9A¥2Ùª¡1`)iCàïãÆT‰é>u÷¾€°&W ¹¼E ž{£ 4Ï`Xt} M[zÇ”¦az Ó1±JYGWLjÚ ñÓ<±JÓvŽÇC™­ßc.JþúЦP É•â’íš ¹iÈ‘ù½YÞ!·ÂÂ~ Û€.÷7 xí|.[ q9öðHî‰ø–~Ž¿niäÊüûÔŸî1딪˜·ÈªZ DzýÚŽLÓ™`KŽ³Ê §«qìãþ„´lúqDiq~–œ |X/XÐ endstream endobj 1988 0 obj << /Length 2629 /Filter /FlateDecode >> stream xÚÝZYsÛF~ׯÀ#XeN03ÙÚª(±l+‰íÄ¢kl— A e  0Š÷×o÷t.Ñò¡<­ çèž>¿:ð®½À{zðó㙄gàI/V^,atä廳7ïoô_½@¤iäÝÚY;/ŒxVÞÕÙŸg?¯Î~xJ/i¤"oµõÂTŠ$^”*!ã­6Þÿ—ÅÒøÏÎÿX]¼Z¼[ýj—ÈPè0R¸Fj‘Âꥂ§”´äÅå‹ œ{v±šJ™XÄ:üV Gìt Û˜={yµ0þj±TqÂÿå‹'—O_¿:_$¿º|ù‚¤ÖÉè K„¸ÍåIx£óªÂMÿ¦iÒø]‹ŸÒ?À#ðu]Ö×4᷊ú84<§m¶ÝíB?;düÛ›¢»)4o øŸh=L"r^•Eݵ¼"Ûï«2Ϻ²©yׂxÿµÐø¹y oúÛã_)Ïxɺ yS¿ tx}<9¶(?Z%*% ‡ð7L"ïÞt‡øê)h?ŠFj ¼¥”"5ìk#€Ñ–ve—œ©Z§" Ñì±Xj­ýg…Õ€ ü[T ¿oŠ6§—k&µÍŽßš-=Q“öe]Üd¸ø¯Òê(9Zí&ƒS‚!Š–ˆŸ!,>ÒÇ®¼¾éc´VÍ_]òֶbr¤@H8 h(Ò¨¡H’ÂæD«°©».ùøK@˜R!§»3ïÍÒÿ¸ØfǪ#Ï?`˜Yµ»Ï`@•Š@qœ^ÖƒNäʈ¼‚ü¦*×›bk òµïîÉ(⻥m‘£û?šÈÌô8KÅà‚½G!#IŒÞ2èu0ã)¤±[u°³,“CQ¹C‡+ºvæh££aþvØŽ}û Ž:—,0rÿF±²Ý¾*~d5KeÂÔ›?Ùܧ†@åK]& Ð u$‚(Ålê}ô(ª( hÚì3ßyšl¬…1Æ’+ø2BI‰!µÒ€ÿÕjDÐ^>úR4Søg—÷Ä\ ŠÓaGð´cOÊaËþ£r {J0l ìrøÐ0;póùØ“åÿ÷çÛzzà<©ÁHÂÇÓÞ# <Ó„ÿ~«;(ƒðŠÕЧ¬¾ ôúrÒ—ûR1+š?Á; Tña/ŒØè€µ3Ö ª—¡B¾VßGwÒ.?*—dH@2K ¯0ŠQŸˆDãt`&4!è4™ä¼!ßy 4‰–*fÔ'+JTC¢!ÚÆý±¢O(œî!ý{’F™x¾zvñâü¶òÅlÿùåêAë/¿>±Üùh)àó¯>›SG 9ࢡ´ŸË¶w+YÏröÖVýªj0ÿÞpë‹>!1xkœU&°öp æ‡#-%Ô­éo• î«f xLêŠÌn –+£ÇžÑM—û¬"Z9„SòñöÙ¡µ  ÏqhX+•’îÑ—ªÓH“nÇc¿_É(ªn¸°Ž…W©دø?½º8ÿýù Ój-’¸Ÿ–7»}SI9ží¾ÈK„ ÅFܧe¨™±Có=WU͵sšìØÝ4l™ÿŽ @Öž€¥ç‚ìZ ÀÚ÷ŸD¥Ó©ï8Ý€'RÔ€+œ8d;/•Ðg”|iF³/YWИ= 3zÌB &l².[g-ö,:PìU0sªI˜è4 cÖÂðd¯‚A‹žíªŽ;–]Y'Ås 髳nØ÷œ%†# îw`ðXWEÛÞ “D$ÐI²Þ–‡® 2”$7" ¢d¹îuI W=í ¬Go?M"šß}ö—Ô÷8z€œ£JÃy7ˆïzâ4m—¹N>ŽVÓ0, ”©eaÄYÆn)aÁ[Õ4(kŒ㞈¥ x¡©g£)ÿÂ@öÀ6"1„½?ŸÀYhgÌ$UqŸÊBäÐ÷ è4RS¾DŸœ¶äÓÔ kbê¾ëšK­×ÌêøšÎþ ÃJ%¤ ûžiÓì²²†FS soÓ €ücèõGÙ˕Ƶ3Ó¸hÜu%[&®„ѵEµýBzàSðîK.Iàoe÷6 ä¼$¶} ;û)`M=Ä~}*ö%@î¾™ìú‘;¨ çØ«‹ác½¥¢wÍÑ% Hj ? 7oT¬ï¯H‚\KB?0ö#—‘»÷±ß–ÝÑšÕ^õ(É6¨aDwKoövfc LÈs|s· ðJ®cʼÃîU©QµÑY÷Ê”¼ãh›5 ¥²™ºû>õÏÜ÷ýÎÂÇ ï\õ 7~ ‹Q£d›ÄÖ“¨¿é&¢»èni0#ê4.‹£{Cœ2aR_Pʼ`ʱ‡}¸WKÔ—û¢¾ºzFÄÛ²»!òÓ«+´ûù—çÇp8è'†«p˜ËŒÑÓ g«‰å©°9éù„UÑCû`ű¿·`ÞÝôT+çªUæúN[Ë7S™åyc3甹ÛF›c݉þ<£Úðó'éá,½ii­‰S)µE‡S)5Ã|Þ‘8épJl'Öü$Ùh"+퀾pÄáØ.ëÈö…Û ãVÏÁ§à±Ù̶ü\u˜ì¿~P^ˆ£AD¤ârHËaú+†Êc˜žÑñ] ÀÔr­MÔ`,)ù™UmCo-ÕýÆ UF§7ØÒ$–Ö¸ÖÅÉÜInÑ$ Mì;ëö”H_ÊiW…}QÂ÷QW®ÕÜ$ãES“(6ä¿°œÊ%”5é,«s€'®b#‚¨Ç`Y¹àºŸÏ/Wââñ럦Ÿ§@Z •ôà°¤£/ÃH mÌ4ÉÏô? .p^œ@P#t:õ„0x%ö5np.ºH¹»i¨DÒß‹|ñ¨xa*£ÑI¿ :ZpÌ…O 'Sè½¢PCÜÍ¥w¤Œ/¿,܉îÐTôÁÉo†d 9k¸_í«ø`lÆà2„Ù‘LZ‹‘y{µH¿qkY6 amî ý}•åLÎN¨T›t JÏê C‘„zï±_$Ùëž-½Ü4œX 9„Ъų[ÚòPä.5€®dZ€Ï"seM&zp ª8§X!Áò×yFK¯£+Ü´½iŽÕ††ø¢Ó¶iÌ…J¾:ûX^ã™uÙ˜Ji ?Ž—,lÉëló‹/t£‰ùøÔEWâãßïñW‡¯ûÁÀFˆ)Ùec3gù?ãì endstream endobj 1996 0 obj << /Length 2326 /Filter /FlateDecode >> stream xÚåkoã6ò{~…]àäÚ!©÷hÚf·íM½Ÿv"Ó±PYr%9iîpÿýf8¤¶œ&›`Q ù’Ã!çÉá eî\;ÜysòÕâäôµ/œ„%¡ Åʉ¤ù1óÏY,÷î3¸ª¾RuÕÌæ2ŠÝ³™Üå&/ó¦­góÀMÛ¼*iîÍ._ª—Ô¿P…JEÁ¤dböqñýÉùâä·ä¹#ˆœÏ"9ÙæäýGî,þ½Ã™—ÄέÆÚ8~C[8¿œü|‡¬{ñë‚3îEÄz[í@º;`Ÿ¾‡Ø2dzœpÙ¯AQ]ç%!޶ö¼@XÄÜó ÕÐÎE•¥­Zâ@¸yIÀ4˪]ÙÒ`]mõ–y­²¶IîæªyIàvm™ó4EÌYÌKÔ0w {Ìwõ>w¬F1ó„oWÕª°¦BÄž°O8“¬¦º@"$j7•~Žõé³6‡ì£ûšº-vôäLhøhýOó}V™Õ \ýeI»ØåpAŸ7ëGÛ6Í‹flãý>“áƒ0ùSò!IQQY”ð}á~½N·3ü"†¿l ß'$ˆ…~â~‹ž®!ý»wÿ‡=nÿ8( endstream endobj 2002 0 obj << /Length 2494 /Filter /FlateDecode >> stream xÚíZ_oܸ÷§Ð[w,Íÿ’èCÚk‚»Þ½œ‹¢È…¼+ÛªµÒf¥Ï(úÝ;Ã!%J»Ns’»ñƒWÉáÌpæÇ‘xrðäåÙ.ÎÎ_h‘ä,·Ò&W‰ËÒ£–s|p+ÀowWõÁ°Ý‚q=Æ‹—~˜3 ü^ªº_9Žk°Á R–+†ž£Yôhr0Ñp¬€Þ·Îï;ê"Ÿú•3#yç–úœ® « æ_ÑòMõ3»›‚„„çöòŸ câú‰Žbc‹³il5Ŷd]K¼ëÉ×&~™=-ñ7ÔQÕlÚ¥2‹;Œº1|ýÝwï"ãÌê|.æ®O ‘2£&B¸£ßx­Œ~ úc•ä+Zç¶_¿uö-êu§¸Aå*Ü,ö%ì FDŽ`D7¨ñ£Ýî Cn’–¨S/ÆžªT"¥F¾MK½wèªæ:ÈSzªø\Aˆ•:¶"Št¬<ÆÎåíËÚE\$ìÇyžÛÌn·owäyUÑ{ý)+Y®åTÝár8ͽÐCáPú¹€0FG÷Ì`9£ÓÅEàzç´VJâ ®¼_É Óê1ÛÍÌÈvQ׺®¼WL¬ DôB¢’]c¾]ÑßГ3îñÏH]RC,ÍÔL]%8h©†”â3¢ÔÒi ­ÛÚ©GASö áH6¤ÞUpN­½êˆˆ—ž­c;Ï/\žœv…ˆSPÄ€U·Ôt~5)ã¦Vïzâ¬üJ‡æÐ /ÁÐ’ƒG}HÐqR´¤'†¢ «H¥Æ°ô»›jˆÊЬ¶»ºÜB>÷£·‡º¯vN)*ÄSß5NåãÖ!=àTMï“þ•s»ué#LTùÕ·ÕõlZÿpYº€“F)F”èL?/dµ—\ wrðO „‚ÒG€.ø|ºŒ†žÑ,›áTXð{)¿¿÷s8!:gÆa]žìO, -ãiFãY8ïÛóa¡ÓéCðœejR>áÐj¿ð<}ù•Ç)BL³_bOuf¤pºÍ˜*1B1% bõäm¼9ʧ9±Íšëm¢¾§Šc¹†–aRÜŠN­ïÉ•Œ*YG-ÈSinø@TL –aF£=Û¸â@ZÔC£ >NÇÇåÖÐPÀÍ¿ÿángëÿûý]%?$à<¹ADŠ?/ ýÿPw,á¥W—f6'¾Œïô¤¯Ð2Â+Ú7Á8dã\FGË@ƒ´ëÕà‡¡B«Š_rŽŽn“þ7¨resÆüâñJá˜>Ýeu7à®jŒeD?¾3@Rg¹ÓÀ¸®£Ø²k´IøçDžPüíÂùï'×Oü׸ΠÀŒâÉ‹ Qð«˜nq>›ŠÆS&èÛ' ŸdÇÎÂæ³P"tBçÿ>‘#VÁ àZ’ót^3Öß­Ç©H@'ºÆ\\\ºÌhg÷aârxº¾ÿæ‚xÓ$\7û‚úÓøBgÓQ_ŒEl¸S»Õˆ0^!]ö„w‰D¸©ÅßÊtñàMÕ¹SÀ'ÀÁ)‰è1– 6[´'Ž “û£L/³òÝß1pªÓw )2&†KZûè†dG¶=BýX€°o¿ìøžAÊŒ®£ÙÓÑìÓà˜Àþg‡k†6â5€'ðZT ‚Äÿ@µ¼ü_Ñ/»5ÕZ¨1`AˆÜ%®,”5ÁY8 sà3¶ ï0ݯ‡4OY.¾ ¡/hè úøhHóŒ)ž=ˆ†4­æ|,ZûXòiÁPÛŸ¼J!Ÿ°Äw·¨X&&¥6_0FêÁ±1V \k(+,ìÊuuuO]e>™/}DêSLŒÜYî;¤¯¶ƒ×Õ;ªñÝ¥òQÒÓóÕ%ð/5Ëze×±q‘Óõè:Ô?š"HY£.ï—Ö¸Û¹ˆ‹©\{ÌÂOž»ºZW½â]"SŒ– oDRÜÄÓÆD>—5ê@´Ë·»!bT Λ¢¼Ñû!×Ð ȦT!“Ò"ÿh›1Âý)ôf%²0#;(ƒŸDÂèÝú’ÿÓÞÃiYš ïan—+\ßnnÞû*ƺ}øQ…¬Qž[’nWtÝÊßî7Dy‹95ÁÎG-ÃŽ›Ñ¸«gñ¨XÅ#`#ò|Kùü‹W½¤ÞÆk¬cRm%,\4õìWÒ>Š¦ê¶¿ ’–þ•ŸQ¡:އ5sÄaíâH˜S‡ÆY §ããrŸ QýV÷÷(D•~DeÕQY=GTDÆe AÚ‰õ‚jÐQYõ›@TÒ Æ­xQAЦET»»·øòâá)û ŠK4ÙÿzméƒUò`iiV,3ùýGUøG@¯Ï1¹R¡ªÂÏJ¤Í•/fEE› ²þ Žà ˆÑ{/#Z™ò˜ñAD«r–ŽHõ¿Ãw×ÔVuæd‹[ ÈÖÕÚ‰Ä^©9Àæ|¦ÕP> stream xÚíYKsÛF¾ëWà¶`•9š'©­­RdYVb;Ž¤Ë–ír$Db4@Zñ¿O÷ô`BpűtÚ²Â?'ÕËz9@h[¯eÞíqúB%ƒ#àÁ\jàfH¦3ÉÃVB†›¢Eø÷؇áb™•8!°®«°W2ö»Ø5ûš¾ËºÚ7µ£ßÔ3eÂ{š±²b£Í‰ïgœÌ›–h³&§i«J¾¢ŽÅ­×Nª¼é&Ûb»+Ñt¾P1SœÚ"ܕٲ¨ÖN¸ãÝn2\ ¸ tF@½ø_¾Üƒ\RX¤”áóW¯h ¨P=²œpè=—¼,4 MA³ía±*àãûâøÝÑ×-–!®¢¡]yXŽ–F&D# ï7ÅUßКU~‡Jg‡rß:©j:j&y‚6kø¯“ˆÌg4.>õZ9LŠª×ùQzΕQLÁ‘KyuÙjÊ­AL—¦£}àø ·´ßP+£õG{EäÒ_"@ênê®%,žª=vÑŸ ™RáEæãìQUN-ëæà ¶nÈCŽMÖzjÜ¡GuÂorç ¤Ñi0þº;65g‰W—vE ø0ŒTÚÔ+ømŠªiNd£îr(ÊÆbÅŒ1v¸„žã²JÇ‘›LiÀ¯PÁr8mXœÂŸ]îc¦M§=G‘8²~G?´–¾SvúÞ³ãývKè( æžž>Üj¶ü¿×ï.ø=ãI Þ0ü\z‹ „ÿ§ÿØ$‹AxéàÒLƒrÒâe܌ǫ ¼ü´q@».DD÷±ç%’Á6Ð!t†¸ nò­P|Ï=zëÜ·ƒr¥Œ øBìd \àik#¥‡—–œÖ}TÙ.¼àpãëbåZ»l¿L¼«wè©ÛÎ h<•îŸúh„¢«]ùïQÀ- :lpvåш]î¿ìòѺoÙ1üÏ߇锻Šë·ª+dâ‚+6PiÌ*ÓѰ-H«m ³=,س‘Mþ SÒ¸ûs^}…DŠw±ó×–Á„S›SMÑŽäe#Q‡Õg]‚ …ãphs§EïØ“*‡Åa½¦ æ`Øf‡RµKŽÃfY;BÅU¸; îê6o§”FÿÓ‡24­‡:ÃÍQ<*¬©4ƒF—9+®C¨ï«}! KE;{7"f^Ø·˜i™¥­é»pKŽs®)5$^á,zó•CÔr˜ðt e² C?*Ó‰áòHÆyÌâ(>Æ›ÒD¬Rc_P(ÈŠ<,0NõyŒué¤åɈ Ÿþ×;«*Þä Ù•d^ò÷pw‹;b½k c¨ö0$hW€Ãæä:2[Ù†ƒrrRýw¥vìË-ås`|6PR2¦¦>T~9Q‚êt¹pW‹•ïeFP-H{ OùÿåûIƒTèý ë|ÌØ"S&å úÕD¸Ì*š±7 ¾î†Edf8¥S/ÔËh²ÝåËŸOpÌŠa[öE¦ ÌæbžwÀÀÎÞ_á2뀺®†ÃG¬;ó±ùmŠ–P¥¡ˆEµÏû›ÝàCƳq>h“Wûñ{@{•·Åº²`Ywy'ð[æ»=u—YY¶Ç5(ã¸y9:Dû(³T¹wÁ+„ɘ.M5a^¡³û\4uµ”hð³} qoUÙ¢tG õßà¨AuaÒî¬Á{||}qþòã9ŠeÁÕå”}pÉxœùiدÍ÷¥Ø=xʃ³£tF­¬iÒÖåCo“Š&¤ ~î\¶PýÔSÕâÜáª/ÂÕÓáç^¹Ñ».8Wî~ç#æú ô”ÐCæHÓ»[¼oø®C™ºs`pˆÕQQäyáÙÀʉœh u ›GV鞃'ìŒ a|Iø5ý!ű÷ø`yyÎÄÈ8¼¥V.”÷Ð:a3êOba½3>…­éÝ*@¿ÌxªŽm¬—kTáúRËЧ­ ø/Í£ä òGùô$^¯„›¯Vøë¸£4Õ@¼{{vûòÍÙ닟nn¯¯ÞLЮ s¯¥÷ûóÉ´…wcog §ßÿ€½}®}}1õÜŽ¿OÕmÄM)í‚eߨ²‰GÚ%Qé SJUÿrãþåÛ }!Ñ~æøV«)Á¹aBûz‹ >……ŠX"¿&/•%.…±åÙ@ôA²=œPcÜ+JÂ-Õ£rî¶óÎÃ$î¾(Kï¼»'ÃŒÒj—®Ùéw: t.;¤yèô!_¶*¸e.:<Ý~‹î¡r]Õ]-æ tüÛ-œ4šÇ7þt;ùk3J!Üï qbƒ¡áù&ÛÍPh«žM:RŸ‘N×u»§‘åDº2’ö/UHÑ endstream endobj 2017 0 obj << /Length 1804 /Filter /FlateDecode >> stream xÚ­XÍrÛ6¾û)x+5c±IÔÑvœÄñ´IcezHs€HØb-‘,AÖõÛw»¤ ™ñ43½Àîbña±Tè=x¡÷î,äñ¯3cè /‹¼L„ŒS¯ØŸ}ýz%Ð?xa°Z¥Þ“•Ú{IšÃ¸óîÎ~;»\Ÿýü6Þ*X¥Qê­ï½d%‚<^ºŠJo]z_ý«ÅRúï/>­¯?/¾­?Ø-" â$pX2̼e+!hËúúW=»^Ledqò£Óâ(‡c¼TÄABg].âпXÄÒ¿ºýòén±Œ²Üÿø–Æ»ë«/Ÿ¯iþþãÝBúk¼Í]$λ/#™¢ê%bÌYùï[]Ãî0õŸIè7.2£ŠEúÄZ¢*Z] &Ò¶1 !ýþ–0:J@nÛ »’ä4âÿŠÝPjè·<µàMZ$Ò7´ëAh¤>÷jC²„q²ãÓï»f¢ê€m°XÆbåßÜ3¤f¯›šw7›^Uµ.‰¥ˆX4­= ï´"XIv”µDÍà‹&L™+z-G Cõ$ÖêÎ45Í ¶L÷е“®šPY“¹XÐüµ¡?èN•£¸9Az¼å –¯\áiÉIEÑì[¸RetÌå¡§9À˜ ª€ÛúMõ0tª¯šÚàͳȬôƒ'üÙéòC0éŠ » 6Lfè/PÃfµ3 qÕnÇGDÓŽ®izæ…6†öôÍwD¿És½­xÿø20Ý0ÚVu0áªv0H;šÍЂóÌNšké‚Ŕûa®kCõB†cÚ“ì~sꈪÆôž-ïRÌžjC›4Îf  s€Y«Œ± ¨é(«M¯’ñƒ(ÑRAqJ´q\¹Á×c¨Ý:q¬ø‡ð¾.eú—`(éì`9•ãlLZ0¹¥Ä²ÜbˆR¢•!Ml”ѯ9`Æ~C2è Œ{(NOUQLJºƒdòxîXÆ6PQ¢â=mcLe=0žÊò<ô[ûš#TäT‚iùœf‘±Ñ'2¹'þ‚«·=£¥Ì9›t¿lUÛ‚ËÑ +²)="a’×sªÓí®*°rÇ™Mš¶\¯çú¾zØ¢#Å©jÖßèJ6’QUhÞg h¢Ós¡…%kPCßì¡@Ä„Ъ´’-šD´uñ "uŒ†dòdŠ7XV5¹?”A>‚è÷ÆäÓ©Ëɤ?[Õß5s©sC°‚mõ„­^QQ³ãÂ& PŒmx½\µW4y&2Xøœw¤˜{j’pî +÷ΰÜðn×|ãFùd|à¿:ƒ/kޱ¹6JÉFÎ;fÉéÃa±vò-ì@„|4›wPÖšúœ2÷/7ë‘ ¿×uiFy›,3·¯²Óœg’³AâÄRã ùŽùìQ'=‹õÀœú—ºPÃ(ø8™{O0¼'MìEÁõЦî«z€ž‡±ÜrØ·dÝXÎ;µ¤WƒQÑ0µ XÕDƒäMAw>z–îEø<éÆzzˆõ|Ú@w`ðíPíÛݬ1 |{ D¦tŠ„nJaìPØG£èlTáÏfC“V³5›ðì&K¡ô¨¤|˺Ѐ$0ÙÅ9[ÑòP#ÓãeôÎØ&é '–q9ž‚µî¹R>bSlÛ~¼'YÈ×d7ckFÁœõ•–C»W5ó,bà9;cG‰dç«;_$ ¿;Hžn2^´bl€NŠšÎ&d0ªÉHÍ1PGÏ€/Ûóº¸u]°ÿ·ãm{VÒwª6ÐËÌâ3æQàö3DÊW,NÝ_œdð)b¿Ôo3ï‹]NôÀŠŠ§èEJ=?zjS|À®Q¶uKF‡“þþðÒ&*]óüàŠêì€Ó¶—ibÆ`à`l8ÿ‡ÖÚÛèЙ¿™R vŠ5·¤xÕ†CÊÄøk¸gœÌúZËžEñqËîÊŸþM$èô²Ó‰âUþÿÆ’Ø´E‘—DÜ»e«Ó#ÿ‘ çÆ endstream endobj 2021 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚ?oà Åw>Å Õ0æÏ˜Tm¤tjËeplÒX‰ãÔØê×/6ÎP©C§wÜ¡»÷~ >Á­z|‘,µJ(pGд4TÚ\ ;üJD}ð}H&´Á+ \·Íµ CO²—CÓ]Ól36µHõ»¿ø2øôàTÊÉÞmѳC_ˆÇó x:'©fªíö êØß£¹5ð=ÿjA*õè ±Åú]í*$êß«þL/£O.RxÃ&÷6øéTÞH2ÁX"1J2%-^—Õ„á<ÞBÝ1iðÕ8Z œº0„™ÁÝ|dñ¼[3 endstream endobj 2025 0 obj << /Length 2137 /Filter /FlateDecode >> stream xÚÝ]sÜ6îÝ¿BÚ™¬ŽE}\ŸÜÔñ¥½IÛÄí´“öA«ÕzuÑJ}Äõ¿?€%J–“¸ÉÌÍœL ñE¸Â¹u„s}!x|áÃ(߉'ö…§dää§‹· gðïá¥iäÜi¬“F Œ•óæâç‹oo.þñ"ôÔK£ rnN˜ú^"|'JÏʹÙ;oÝç›­rÿuùÓÍÕëÍŸ7ßë-~èÉ0 pÏ6õgH/õ}Úpõï«_¯^!îÅÕÍ\ÂHÅ^,çJh±“Qê‰H9‘/½øýôÃËW/o6Û N@XåþøêÅËë_^_náÞ¼üñI-KÑmÆšÌJ„dà»eGc†ƒpÏm‘ ý±¨û2Ïú²©iõTä_¹Ç¬.»›P¸MK?l`oÑazŠèÝKÚIС+xý7O‰”¦yTåöåB†À–p„Û7,Û$QAøfÆß=gHƒêƒE·¾ï¥ŠÏ4¯JØäüTºY½§É‡2/pº6RÜ]æ?-ƒXyVó¾ªkh¶+h5öD ç•¢ÎvUaø€Ù¤pïOeO n8ŸÖò BÕªAîwe}Ë ma á¼9†šUGŽ]‘mQm€ÔýšÊweDF‚Œ„m$œÂÂÉÎçjo17F_ˆ¿œÍ4ú,Ä#¸­ÍmŠ [²©`ƒJ¹mñ~ã w([íùA×ÃÑD‰ W¢„P¦8„Š ˜P\hJ{š4uA„fŠl Oø2'„óù ÌŽfü,+^XD(@†mµâŸ¬8ä,ˆ¹ Lݘ;´g†‰;ÍÐÑ:oˆ•ûŒ¡’WÃ÷še^v„h™wÏ$vÚ—q¯ñÉ0YÏCšaËë¦ÇD!÷’·Ctm^B0S@2ãn€±¢ü"º8.ÖäGxÆ1¹c¥œg¸ç)>cJ&†oQÜ¢.ZKrb :~W;šW,çêÇ^*%©£% ðªý¨'k 9ç½BcÔÇ3HxÓò¾èrvÌÓ:Råm ч¤\vGe4¬Z—Á…&i[Ã0xô&¸ 1u™r½ÏZ^/æUò–),Oxó®´'â„‹`„ÿÐq‘]‘É/œkæÐT;"« Ú¹>¶cô½}ÇHɎヿB½qõÖ×Jkb¢©‘ëí`²ÓíìÞ±R»ù/ãp8]¢``i²Á¾ƒä÷|þ÷c8}ÙŤµ/&é%‘œn¦¯u7]cãõdÝNÙG.)ÆÐÞNŽþ(æ'n3¸w#>¼ß!Áªñ´ÆÄµŒÂé à2‚C¸ûx|’ûC(ñüfþJ^Û*rhÃæûâ åWˆ::ÌJå„A‘Þý“lÇ ÂÔYŽ|BkKpNИΠJ<¨ç)à(E€ÝóÞ¡¾ ˆBAh‹ÏüäHjbé)¥4¸‚/å¾=DG¼àC%$ Üú  HáOo©ª(N'ŠR0ÚÄq厜>*Ãp„ˆ‰œ˜Øåð![|„Ö,ÿ¿×ïàüì€ó¤ c ‡ëÑ# šÓ„ÿ?Õ/á6Wè… \ í¥xe´—½ÌW³¡ù¼SAW:Ñ’Âb#[Ƕ š·¡A>×'ŽdJ)·Ø1Co¾ÅðÒº­Žì´­¹ôSÏ—ÜÂ7ç¢î:(bd”Û¢†N#=DË›Z°„ó/ìÚÎÒ$ÒÄ Wòì]qÿr®·$u.N&ñ`âWˆ-Í`C&q&s2Ë{ÖVKã/Õ•üêúþ}qêâî‹iü…]×Wô¸àúÿ¹aöÙ}÷To‚ ^|º HE<«ïc¬dªcs‡RyL-#‚³îM¦Û>zCáÞñY5Ü4C¸„͘ÖzM»øUTû›¶ BñºÅ ï× Lv£ü½ÝOÄX;J* g²iÂÊ.°ä•7Ûÿg ze M‘!¡Ðeþ:—íø ‹å© ™V\IƒºTýÐ|½r’îÎH‹8ürwËŲEªN;¢ºÙ¡‡©~Bœ¥L)b/Ð\k±5n´ð„ ò|å,´KºoÊ:/Ú~ZüÐ=Y†Ò¯nhN¨ ¥'9·êTÈi—ØS¦MZýÀNüÔQÖäS©õø¡÷É%›-§›å{h)i°ºc3T̯æ2õdµÓ>fxcŸ!¹AÖË3Ÿ pÐÖ¸4ËGn@C?´Å7ˆÝ/ì²#-2o³"²×Cgš±y¿Ó^ §1ÍNÙèNXÜvY2Ü'm¶+«±B×-gg0hl§®lóádzè|ùPX‰DŠ.¨n¨ðEJÄ:ÖSãÔÔçôÅïQ‚âX£Þ¡º } Uúõ«söN?Z“jЕz˜d5"½™!ùlôP\¯†Bèc;' ÿõª¯ Ò€wóvW²:¯ß l—k©Â¼½Q¢16׈^Ãd`¿Éi/ŸB¾ÌIö? 3ß<·M-o±çä¸Ðuž®ÓIË“)˜ƒô‘G'˜™„É#ž+à¿èñ+.Ìçx¼‰Tqbk=‰Ñ „=éô‹ƒcCÔôŸ|옩SÔf±Éì7ÆùóÃøt´*Íç¼¢—ïòW&zA/dÂVâó~Sø @x¾Ï‘—øK–ÿhH´Ê endstream endobj 2030 0 obj << /Length 2334 /Filter /FlateDecode >> stream xÚåkoÛFò»?p`±Ë]>D÷|€êS 7©ÛØÎáŠ4hi-±¦H…¸Fqÿ½3;»|‰NãØÈ8𾆳3³óÚY1km1ëô໫ƒo^x®9QÀëêÆ ¹z3Ç‹„uµ²ÞÚ/'Ü·eq-‹¼œLy8³ç×·WÛ$Kʪ˜L};®’<£µÓ:YÉCê_ÈTÆ¥¤ëpwWß,®>¸°=³\ÚÎsBZËíÁÛwÌZÁü÷sD4³îÔÖò‚´©uyðú€iÒ›Öqræð@àWk°°7yÑ2ëºNäûÜpë2‡‰¸…% T‘ùåûXo§>cö©Ì¤‘O¶&1ÄÔ¼ü× u–Á™]%¿0á-ãjÂîmÿÍ 1볦܃|¢w>™ æ>Á|ÏoñI¸™xÌÎ ªK={—TšúéåÙùÙÍ&%µ…ü0q™]'…\T•ÓÊ&žfœ$V­”ùV㬳º¬ã”¦‘™®JÐáÎì»M²DåÙè6¾ï²$àµÒ4™–‚T¹¥UE+%@Høq'³ËËWÈ5#2€´» HRÍ,óí.MP+ a¿@ ’¢Ä¦:$¨{%žšwIšR/“È9öbjŸTÌYƒ¨£…1J’ušæ(Ÿ;X?¢Uñ½È¶Z‹Æ–@—ÀXŒ©3'p…å¹3gz æb}°6BÝð †Ë­%È‚Báø¾¯¦Sùw]4*/ ô‚ëOð΄°–÷„Fð§¾og}Çóƒ0jqr/Ѐí¦íÜж£ÔìÚN±NÖÙu #0ó‰n˜âpùÃçõÚeŠ|tØœ6BNÿGVî„À×bóXäJn¾^iäf&Hnfh‰›±ç>8î0ßÙ GZJ=ù(ièo•`>W$_b_{^^·F¤Ó r˜ ­çF]”«Š#Á¬4ŸƒlµSz{»Z¾_\½ë¹¬€V¯ã2Yžä„Op Uy|2?z1u¹óo·òþM¯åq–grW¯nWÉ:©âô2YgqUòÙ2Ùmd±•Y…ãùºcˆåo•ÌVrõÒlBu ÞÐóǾ)ëë_岂OÎV€6¹Idq¼‰ËQÏ×Õ&/’ê¾t%«Ã¤,kˆU#ŸÑÊ<­Îã­<¦ÑÑ2ß݉Rd spÂöŽºÌðo/¯ß,ÎOGx.»"É–ï3€2¹p"·sr-Ä»1 §ÛãÅ~:b‡*ÈÃ1T:ú¿ý¾8ÿ÷ÑÑÅbþê‡ÿŽ}ª0'»8UØ÷pŸ:QBüí¸G¡%ñ¿¯îwRzv~µ8]\ñKÅÃ'i*?)11ªñjÙ=î 붸®ÖÕƒRâÇ"ÛÑÌ(bz˳ ÷…e‘8¾V¹ÉZ` C8èeI£¸Ð»4^ª”&“ŒZ‰Ÿ¡Å”`|¥[ض|ÞüC0°*h¿vþe/,‡á0*‡³½ ÜLa´iMÈifX‹ŽµÛ}­¼ã¯Êßg峯Ÿo„~/Ý‘ ²pÖÙ$®\P I4ß_!Ï@óB_ÿPž!À yÀÉÂs¸ü”%ÜV|pk™e¬mÝCÙ›Š´ÞŒ¾¥ÂWÓÞmqÖá±úølgˆk·7í{ð~ì#´0çîLKgÞ¬fz<#ŸÄp&ïžUhO’Øs0„§öÌ'¸—Ý aD7HèÄ«_k¢ƒÆtõCˆ}i¾.AtWÝ%…~˜Á¹Ulx¹&¡Ý•ôãl½_ÓÎêí5í b¿©¨r3Œ` nQhBØÔ8žþñÀq}n tQþBÝ—·²ÝE2–Ù•ÉôªðÕøi@O)8¦e>ª> 9à)Ouq?ÏôL#8T"ež®NüÔ HðŽÉÐX€«ÓŠú¨ìØ‚–•zf'›@õVf„½kýy¢Wª;Ü7§=1¨\¨.½“ÐÁ…¾íìÔ«@SU:ˆ³ N?píïrU1hÑÑ`ÛjTCFØ–;º$[]1ü0+ ð@&\?¹t­½}M)gÔ15îèµ,!c7'ÜÝ$ðm½AË,iÞ'.äM 'î Ò¼’Kõ@dxÄÃ:’×­óÀ€_Çâm‚ÚƒgE2ó]ÐÎhAÇ š·¬¡Á³&ÜO‚)¬àéð@Š f+[º›å˜€ì[ž ÇçÂàGC¿dЭ¤@c–WԹͨÈD!¸Qs¯¯ 1õ#O.¶«¤ÍÒZ- |°£äƒsœT:¤9r¡ØS|v¿»¤b/ æi¥ßN302SÕÕs¥K¯p,3|&Ô;h\Ä5öâÝNÆ…î—#g4p™ªàŒ$ý£ÎÊz·Ë P¤Ž "=WE˜®ß»R޵дYN\mcýIq:«\60Z«·RI¿‰…à}Œï6ïŠÜLQ!qh`¹Ï~>1|µ÷=‡Ÿýh?ú;;®«}êŒÃîÑŒGöÉ&ÞMÐnñgúÇ.ˆ ÜpóL­žÎó )]×ß þmeÕ4 endstream endobj 2034 0 obj << /Length 2709 /Filter /FlateDecode >> stream xÚåkoܸñ»…>¨ð2õÞ«‹úÜMàKΗØNÑCrä]Ú«;­´µqŒCÿ{g8¤¤ÕÊi§×õ‹áÌp8Or¹sãpçÙÁ÷—Ožž“²4‘syíø^Â’8uâ aAê;—Kçû|"BWÖW²®Ôd*âÄ=žx¡»\çe®šz2 ݬɫ’æžmó¥<¤ö¹,d¦$u<&ó&¿\þp0¿w?L|`€æUµ6­m¹UÛ¬¸3aOKÅ&Svt9I¹[Ñ’­? ‰8ûŽ æ6oVÔúi#Ë‹‹(!‰áz5D2ú(x!§‹j½©J"£x^.òÞ’ˆÜ2[k…ÜiD[‚½Í‹‚Z¥”Kƒ¼¤¯DI}ld©@ñáAÆ IóoyÈ—¸_Ö-ñëºZS«Y¸ç?¹aØC¹ÙU…tB€Ý“â*› ¬²¼™‘n†Aê ¿FmǦ@yÁ:­mF ‹<ß ´[hŸÎ{`SÔǀؠ»X;>™lì³0 õp½ ÏC+âÈL€¥¾è øÎ¢×¾ÇâþôúnÔgA›jq ?0€Ñnlh»^a©vC¼‡“÷¨. çÃn—˜×;\üßìóÚyå€2¥!:%üW$_b_{aÅ|­H§QʸßÀK™ˆ=”«\Q?€9Fq+%ÛCÞô8Òæ—1çp•©|qÎ¥©ÁG4êèäxöôøÅÅ| ø7y÷Ze7òh™ßäMV\ä7eÖlky3sôž+Y¯öoj)±3†I¢S[Êås‹É"ˆ± ÒÐ ÆÖ¨íÕ¯rÑÀ’Ó% Í¯sY­2µζͪªóænøÊ—‡¹R[ˆ,ýe-£™ã¢9÷D½Ù¢ÚÜ}‚! ]ÿ®±5ëoF|w1õz~v2Ÿmjˆ0ï0°XlÂg©gNª›=¨ZfÅúhþÏ—3~¨3S£SÿÓïó³Ìfçóã?þklS3F6]ãðw¹Ò³J¾¿—1 0Ê¢}×Üm¤áïôìrþl~>óîVšõ{YQ;|ì1¢F¹ÐÓÞѨpN^œÎÏ.µtFs§”Y^CdM"‹“p7ÄÒTÐ(ej3¼)²…Π—4¹ÀY#¦iØK+p¡sX9È‹@i*07jef‘M•©±T) mªÔm)2‰QQèÝb:¢4"­²úº9ƒHRPñž3$ñH(^‘4å{´ÂÑvÚ0ÑŽðïÈýQ¹Â·º¿o5GHâ!I†BÊ{dRn¤Ó— Š!±Éàûr4/´àûrÌPD‚,¼‚ÒI)(fBp7²¬Ufl=@ÙÛšµSʪéNUŠ8· á#×áö(]6D·‘kë~°ŽÚ·v¤cIð ÙE3;Û®)ä=jÏ¥¼}4ÔEn_í(ÅOÝe;Y`ùHèÜå!ކ~þéõù;æìøÇ9a¥ ÿx´/ÏOÏN:´; ô1ä)µÞz~ðù´87áíŠcïNŽ;½È¾89¶Ü`Añ?gçÑÖË×ù½pgäïÚâ¨çE½4Á¨Ë©`(s;.׃ã{ö+ÒhÛTxØ’è?è›ì]5u–ÿîg=~V€û:Ç{+œízŒ4lþûp ’Ý=n—Ùzhäñ£p \߆ó5–J0âsêõ×vòŸ®¯Î&Â\ÊrwV;w“(t¡( xLEŠÓ5gm/£q ¹År¥ÂNÔV'4¥VÕ¶XÒÌ•YO$¶%õª’f[ôVuppUÍBDõÖp-Õ¶ Ëún-Ó¶ˆpöFVsYg¥ºÖÅ"Õcµ´Øª±2‹hxÞhý†ãt‘A÷ÓÍY†©×Þsûïð5«¼^Ô$,'íEî±¢Q,Q PÒÒ ²ÀÀ‡¼Ú¢"7êï’Pïb§ÝŽk¾Õo{챑DàΊ->HøB¸Õ5~ýq¡À¼}W@¾ûí*_ «+³ ki»2àJ64ÓT4ú^_w:â(¡»§f9m—Y˜٭!¬¶W$£¼Ù6Ø”õ5Áëk›?OPRÐ×?Ð fD?Obîv 2«Ó}篯ìi`Ãè2YB8ºÿ¨âô,r¼ÐŽ4£ú Aw{'QÇfB¸ß˳ÍIdî2Õå¯Ý{’ˆï;ý‘SîïN„®Q6ymŸalIWк2‡‰mÒƒ¬¼¡§µÐX6ÊíúŠ(q7»nèp°…HY$6bOm851/Š÷†,…Å,õÍ#饦Gƃ`;ÖÊ-´{É•ÙÈvg0až˜`âÊ,o}’»A݉o t«’ä^ˆ¡Ï×+I[`•qZ0gxÂý¾ÒCBZÐ{ì1¾A™Êص|’d[ܽC9dë³¾3çtÛ‡4ß3i NoXjp¤#šòVóɰ­–ôiQ¼ÁÑÞvQ“¤ÅP5rÑèÛ<èš':Ô›ÅB*µ¯vúîW±vã=Ðþ60þ6°þú•ûúî% ÚÇM e\+´–¹Ú™õ`}”mTƒöÐþqÌ8ŸÝóˆöû˜!´Ê¯÷„+fÙ–j»ÙT5Hä¯#æà ŸEiÜˉ[¶´eAÀ¢8ÞUˆ º='ùyõ.ÁÚËV˜9Ó‡¸–}G`’G#úks4ôi¿ÃÞS2¶÷„‰ÔK[ÝÖƒC‘â<‰g;ÅÞºª †f…þǪÒ"íÞŸq±d7lÌ!E ó¢öLÀŠš'òc¶Þ’–¿µ•óðH ôàÝ:tì‡ÝÎÆŸ^³CŠ2áJ HÈBŸÈ> dQÔªˆÞ‰PJ}Ö–N™"4Süf¨5h¤ØÁØŽ_s ÔYcÞ¶) <Ð1'¨c}-ú‹ÄI‰¨ƒt¡1·âC)‹ßrÕ]0 X÷, ,e~ÃÒ¤ç;çjÅc „ Á{Y{ä#ä"Á<Ñâ¢X¡â  A ¥àÄXr…ã½¼dȳqªáÓXv}žBBˆVzþiîð¸eÕÐø:kú`Ú*õ8žë”¹l?þè¡û…G/$´Éæ`¹Œ2ß÷ݧmeÒ9w§ŸÄv8J­-èŽ)M° )Ör¶S5 òLDŸý‹§ý_jŠtÁ½_-M¦Qº'úG²ÿ“£{f¶A¥Øz„Ä2ýo¼ÈBp endstream endobj 2043 0 obj << /Length 3103 /Filter /FlateDecode >> stream xÚí\moÔ:þÞ_]]‰Œ–1Ž; »¬º¸].”•V,ª2·Í6“„I†Ò»Úÿ¾çø%o3S(-¡á;Çö±}žçØN©sæPçÙÞ“ã½OωI,˜pŽO9a‘ öã¹óÎ}1aܕ˙\–õdÊÂÈ}<ñ¸;_dEV7ËÉ”»I“•…Î{¶Êæò¾~~-s™ÔR'<Âñ&ïŸïï}Øó zêxºº€„4tÒÅÞ»÷Ô™ƒü¹C‰GÎ¥*µpÁoî¼Ùû}š¦Sâ1ÄÎøwyælËzý¬­WDDx¾#BŸø!ǺŒÑÕÅFÉtáøº9ðç\‰sHqÂ<[„ÂdxÄ|ÖøNÚOÅ$ŒáŸzÝ \„q§1`¦XWc+JAe›ÈÛ ­„vêhW]Š (MmyóCUÏÒŸ¾§ÎïÌœ˜ã$ŸnFè§ÿ¿ét€FAã™1W@èSöâ&§µ—h{µ©ØZ'J‡9ßé X¯Hhëôí‚Õ™×Ð _jНYDíýZSNEL¨‡¿0¬aè£=•§¶ = ã±ö4ïªeV¤Y•äõ{t jêy0H\ç«lïÑ3YÈe’¿i yöð×ÿýóáÃý—‡GÇÞÿ¶¾Ç®{©÷<õûÍ-, 18&¥åø=\YL|ê~Ì–e±EƒÂÐýˆ^2oȨ›%³\ÖZã Ã‰'BЬ4š6o¨¦³§æµ*—óMÊBâÞPû¬®ÅªFïÝè®4ç²ÐퟙÎÕÒt¨)Û"ZðoêËþËØ,•SË {®M§å¢* 0M­ ^¶µhû¬ŠF`C— 3 Bˆáð••,ê: â4ÞÐI+C¶“DÁL'Ì^&|\ݳ“{(„i­Ð `™¦ÚcÔNýˆÄL놖±¡úWã¼›rJÝý²@›ž­p>jÔÆ†‡ßT²ajB“8ëOÍ€«×ÔCo˜!už¨;ñȵ+†9z…³V—” “¤©¬ký¬æþ®éO%%äd¨)MšV/§ó”TržQ©&ÆF=•Y1zùX-IlóÕ@-Šûy!wmMd2õ}†6nrÆÐj*SÛŽØ=Ô-ó¼DÓ\êa€ü¥Ì-¥TVèÂf%Plý½I€†SCDU°Âü#A$ô¸…jzÁÔî-`  ±hW0š--‹ÓëÆÝ‰Ì¢]§rE¶ Q2ƒö-uK³¢ëç­š(B*Óþš8—§j¨Vy£ô¶¦rNxäÛWÁEt-GÍLn×HL.hòn‰sC&ùâúö)YØv­^ÍlqöLÆI åG“ˆÓK0³iuU-K;õÔi•4çE²5Nʇ¦c_±@’GT•Qwªêñ TÐgDå¼hʵ"$+m¢¥,­„vêhWÝ÷¢ª?jÿ~TªêñUõĘª"¯o«„¶Nß.Ø a©*èû¨*.¯@G¡©*÷Á¦‘ Š« ˆ~›ˆu‹&k®Ì:Ðîö?Õ¬Ä@?¸ÏGÏd„O_<¼&÷ÁH‹ûèmÞϳ٭޿XÎ8Âô­tÜì}2~øÀýçé…¼º­?žê‰ž%kHóÌpH\fyŽO.¬0Úh2C!oUkÆKy¶ÊUø$B…³‰y¿¬ª²–sP|U¥®pQ®jÃ3!ûՋãÃcd…÷MùsS“æ›ðÐãÅØì¼.õÓˆ!CòfÙòeä[eŸ_ÂÃ>¾ýX?o¤Ì ÇÞ¦I›k ­¡u&ÈêéÜÂYÓ6šèQ×!ciU\O]îž¹B`T;æ²c.;ær÷Ì—WĶo²á°ûq<`.I‘ž—ËzG\î s•o¾=æ>‘i²R§*”»%0ƵƒAÀêLÚhYý!u1]œÜ~˜xÔ]IlµÎÕX£²ëª,jYë¤Åi(2„XÈ»Rh´Ò‰EbijÓà âBJ£X¤Ê3ð¥ÅÇû¯ŒÜ‚i[ÖnA&€øÃ£àÐÄ–v°´ƒ¥oKÌ#^l‡%’0l7?Oš´:ɳº‘ÅíP ÚŠ›í‹ùv¾/é^Œ¢Ïí²÷ïkåSµÇL [¿£}Ö–D»W:£-›—鎑æ‰\XÂo#*3›å*µªFÀÆ`!Åž'…ÆŽšèÐj…ˆ'$±ï÷OXØnÞë3;”ááX£¥WºŒŽV–&3Ñuè¬K¦a ŒŽu‰^´93Sm×x+£zÍÂÖ2µÑÕRöÂNè)@ïŠzeË4çY­_7‘‹ì€Žc½´\,$ï…|üp·­»C¡ Å;º#Âå%Âh+ ùœÆk»HðZÓMág:æñ,p,Šn_ø ú…!ïe1âÓöûÞÖ¾DÝ {}TY”suB£ÿ \%ºÉúĸH-þ×?Þ¾>yõúðhÿèño_Qý 7̃©ÓÌÝ»Ѧ,G +i¹oÄZ°5{]Â:jxZ¶WÌ tƒÝ×W²F‹”k‡ßª¬ël–›‚%ñí… CÚ}?n#)xÈËâlÚèÊ]hYÿðYí *©Šªxè&¦®1,‚¬‹BÇNPþòâ¹Ì«!WHs{oåôJKlu´ÑêP\-f·r©]Šy†kvBg6„ç¢44)©/ÚíÊŽ¨`³Y×—ØëryÇË"}p¾ÃØÆî0öÎ1–E¡×Dz,Æk]ñO±Õjy&/äU­Ñtšäù·ÀU{DDÞâ*aòµ»ŒÖÑ ürÕså–¨ÝÐCïnÞ­+™ªÓ, I³]i D£ 6›ÌBLRo:×RðzÇ 0BÅn»o;ø Ë+|;P0øé1 ™ÏOÚ{ì×[Ó¢ÄKß"ð CXs_†¾T Ϙ®ô%ˆÞmOõM³W*"{¥"êoºÕƒ{*·ÝÎÃçµµÎh¶ÞÂh«3Û®Å?2ÿ©f$šB >NÉA•QT5{}ðøåo#"1h˜/”kØâ=Ï¿˜©®÷Ë9Ôú—7oŸ\‡/&ÞA%ÂHµ}k L|üún&(ÛBë …³>Ýúªh’OZ¸R°O)mÑÛ}Ö{$ ƒþiö¦ïšF |PßÎJö£-@Cý8žÄ` ó5ø?Ÿ{£‹»Ý$_˜¯»|¡Ì¢%HRð·(‹©e#X Åo @û›i-0-qÃú4êÒ{(ø43µ¯<%í¡¹oø0æÍ³:Q<ƒâtC[†‹ùÚLRŸûëiRs²n{¸>?ÇßÊjÛË‹ÕÉšÂõˆ)‰X<?oØâÿ¦|$džߎàý•5¸fñ®}º×­©M´°ÔJh§ŽvÕ}/:ò£öïGÝØaဎ°hLG|ګƧÆ:}» "KG@ß@G`uÁðo¥#qD(ƒ/D»¯CöfÞvþÅú–[ßCG-òñáèóKÿÎÈÆ?0âyæ³ë(߃t÷Ï“j‚•Ì¥[ü{'øI²â.awu©û³)£ÿ¤¦Z1 endstream endobj 2053 0 obj << /Length 3528 /Filter /FlateDecode >> stream xÚíkoÜ6ò»…¾U Ä %Šz¸¹4 Ò´É5qQ¹"µ²-xWÚèŸï×ß gH=V›Ú±› ûƒ)‡äpHΓ+œsG8/Žþyrôøyè;©—FA䜜9ÒO¼$N8L¼0•ÎÉÚyï¾ZÊ-šÓ¢©ÛÕq'î“•¯Üõ¶¬Ê¶kVÇÊͺ²®¨íE_®‹Gôý¶ØY[PÅ÷‚ÀóWœüxôìäèã‘4Çw⦠½XÄN¾=zÿ‡pÖÿÑžLçJcm0J Ü8ïŽ~9L¿-=È^IìùN {À·ÃŠýГaà’qz{aÓj}ß“šÈ/ŸÅy¬„pŸÖÕ¿… Ïû¦¬Î‰Ý3#ß”EÕµ“‰?—Éh/„s$^ª¢ë©î½Eâ^ÀFÀt¸"v·=U©ñ´ 2·ÓkÂëjjÁ= „;éE”ÁGÙ¶=Ñ =²¾»¨ »ì® ál —€¶[ì¾úá)O[`Œ[âìyÖÞêXú©û| ý2êU+)Ü«•TîOOQeÙé¦l/ˆú¥‘{È&زT)bÓŒâH¹p¥¥4˜õômIµ±-CÚ>!mÜçÝí5RJ˜Å–Z²#3Ùû÷«È6ÛöÏ‘(c/ˆm¯¶?m‹œ™âF\•ÝÅz5t—uU¶-ZÜ¢ïy ~ ÂÔ™—,"–š`= Œ/ò¥4zI’¢$t>:€›"Ù¡ ´Y5ß:’„c,=¥”o ¦¼À÷Q^†qÄ ÕBؘ |ܬ¼8…?ÝÝA,ªÔÔ¡ 3ZPCÚÊÆLh!bN ÓåP‘€-,>B¯,ÿÛ¯ïÌùÅÓ*<«X¼°'‚ôý¿íq¼ˆ˜]¡ÂâÍ/Å-–_@ü²ÍŠÍÕÈ‹hàa,?MâΘ/¸î† ¹)+¾äí©j. +£Ô>–\þDÚˆ’‰8q")½$b»gw N÷!«rÐ(¬ª½Ùnþiª&Öþ Ãÿ1‘A |þò§gßßb$÷ñl·èò;õG)~§´–ên3„7”‚ìÐKÛa/ÏÈlк?´…K:áe‹¥¶-4Z½ÝM^fcZRÛ£EßmA’t|sht4 d4b-¤?'&u·ÖÂÀÚ¦¼D+¨˜PTå›~mhB•‰e¶dÜì™ ŒÖeú‹MžëU¬\´·¤t_ùB¹uOhyÆ ®ÝyyvM•²£òUçµÑ€hå ~cØryª­ bÖ#‚éiçƒZmuQoŠE*5Ì0ƒ‡¨ïW“*¸óR¨Mú I4éýkR¼^±5©‚³ÀþUšô‡—oÿ¿Š´m7wÓ£ EÛ?Wƒè7&rA™I`•bì)3ÝmÉÝøU ãè!ú¶)ݪîècæÿ„;tb÷¼Zg Ïþ¯W/_¿<¡oã/Uy¹ËxV'ÐZ3iÏþÓÕÚPÿŠ4ÖB Šï×6;×Q(Ò…ý[ðÛÚGFÌÔÏ’“Œzl½.ÑßÓ¤¡f´q’lpKVzMñÔ¨ÛƒúZ߯~ S¸@à½~mýð¾üÒ¹ü–bO~[J([±rÊBÄ0œ¦ûZúé[]ß·ªŸ‚x¢Ÿ‚d®Ÿ¤M#sgÌdCbôŒ÷Mè'½¢ð°~s#JÕD?—ý‡ü¢È/QV܇’ºÜ½+šOEó¤ï.&b-šÌ{¹Î?\Ôm§…ä}Ìûƒí{iõٺâîÔõcyVš8ï-ÉŒü¹ßtånØàÀÂ}‘—Jî;ÀñÙèiè)iº˜ ªÖ¡q¤ÅÙ0³C‹ŽC ¸<õyUþ· ðÖ©)`à}Ý¢FÚFTÖhÊô Y=)7Ó!^8TÒ÷BP&¥ùÕiÞ•ƒ Üæ~ÀÖõ6Ó‘Zø†Åt èL  ”'jÖ4kÑu|%fÌõAnDZ$ÞŽ» 8f&Fܲ…P`=3”Qàg?í;¶v¸l/ê~³æ^5O‹Åa4Lïv,º…5±ð”¯¦ hí€X@åÒòa²¤$ñ‚À²Á£Maà1x3©ä,ÎÉ V„äÄ`'±Å6J¨¸èÔÇxrÎû^àaHZ;áÐPïvu«Ï4èu0«ÀlAÓi[÷-§ â‘M†( ŠªÃëGY§çR„<›¼QBZF l›„š²Å„Îg"c2—,;;ùâM ¸NŽh<“Ñ&_̉¼qæ†ä‘¶»ºZ³Ñ§¬Mú Iµ_ެÎÙLã&Œ©ðÄúf&£Ô^1#`Ñ茦BDqjf®¬å:0E ;¤|· ‘ÑwJšD¡%±9ª_Ô¡Mg3ù¯MðÀ òÓ/Êï¨o4¿#aI2‘Q©‡¨Ô`õ§Q©{²úñzÅ@ý!«_¦Ê“*ž¨ørб+‹‡1½IýÜ1ÅóèïÀ„Ëâú뤺‚È<ïˆÌcšÈ¼üˆFVØ0ê.0™@wÙ¢Žümèqšš¬å +²P¨A[ÏP‚qÙ–§®ià Pù¹PÅÆóDÙú©çkùDæÞ¨•¾}[4;Iœ˜>¨ëž)„E&|xÎË%kZ‚ÛÆéÔzÜem«_ÕÍzÊû›¿Öš?(F¼4°ÏÁÂûyö­ô€­tzÆú ùìÒYK_?Ç’A ¸l7D§¡¤˜ªy·'`¥±KÉ`×Xæ€á7î;–õi—™Á2<íé¡Ýn Æ9:GŠ03UŦ6Vv™1ösru4p:ö–Œäw=ùc€Hda1' aä¨Ã‡>ÜPöä81A£ÞÏWpGž¼ÃÎ'ÜÀÞ˜fì|üÕ±ïvx³¤ïZ„šJ°5áÞÙëˆdÔÛm_•ìÍ0»x&¬Ð {fHbù{äåñ :Ûk˜´àfJ_ŽåÆî""À"îÆmBG¦§öÁÄ…â«¢álw¨Ù€-5l>‘~U¶ÜR*ç¹%åæC“Ë—Òç’bΨ—& Oc,8”Æ_ %GBXVÖ5•>ÀBoëšj7OŠ{„±b…2~/GqùMŃjéHø£šFÎ6ÔÚ¢º-EµZ´³À ›2× 27RžJmŒÜ`ã÷À§ukY ¡A;M#" åÿa §˜%‚ÕUâ/¿’ÄÄp1>1Œ0~ÍÃÕ¡•'‡V ‘C9[yV‘Tàôâ|ñ‘—DáçŸðUÆùõ.ÔÍ|•ÃÃØÅ•2Òµ›Õì Ðé³ìäsJj«B<íÖãÝñ,È"E4’šb$¦ÅÒ[Ò–´ü„A| aæmˆRŸI=„.£F‡G@Ä´E>p8ýÀ*¹ÝÅ :?·E8¯Ž„iÉ ¬­B‚p!¬'c0MÀ˜ 7ŽP6F‚3.…>Áì›Ç•o.”2*:b—„NIPœ®)ƒË±dí½ÙNL\û GSí¿Ù„!Ä8îÆ÷6œ÷ðÛü¼#ÃtÝ6v<x|4…¨ÚOáþ1Dûݱ‘£°‘¬ðÝÌ™¿Ép“ÕÁ ·6b¶^8n@Œa\G×Í[N=Y‰ŸÂe ,e&A´úÚVš„ÞÕøZJ‚²˜ùð2µ³'>D5¦A¦Ñø 1U&î$v™¹“Üçê¢4ž4V7»¸º ‡–h<Îåá7ç‡ÑDŒöÒ ¦‡/\`lÇ3Ú€ Ì£á èaÁÞ·Ì,’OX¦/Tz½ üººàvíâK©ÆQü¹™J}÷eE8­ðˆº,ôȟʦ®¸“Ò¦°…ÆúÉz°I° u5~äÚ"•ÚÀÇxÛÂjwMÑò¯Ð( ‘rì`d·áO¸ð,E 68il,.û³³Øzàé ô$“ d° ¡rò‚¢ ±Ž!mî Jß–lß`ÍB(é,„’ÎC4&Má£.öC%Ó‚ÒYZ›ÐôáÁ¶É5P{Qíç$#£ ;щÒȧ7šö}’Ï' @:XϧÁ·ƒEÛ5eŽþψü]ý¡;ï–ì34Y —\ò™p;ÑýÓYú¸é—œ™@‚ûª?É‹ï7e[ŸÍH†+v™p|š ¶r|Â?Í„¡QšL3áÓ¸óü§Í*ô‚èÆ¿lÞÿE6 éwGKQ˜ÞèçÅèÈ ßMÔœÆÿ;f‡ endstream endobj 2059 0 obj << /Length 1804 /Filter /FlateDecode >> stream xÚÝXëoÛ6ÿž¿Bß&5Ë—^Å04Ý’ M›®­‡nH‹B‘éX¨,»z4Ë¿;%KŽûÚ°›?XÇ#y<þxÇ»#÷n<î=™=<ÕÂKYÉÈ›/½Xz±N˜N•7_xWþE CßÔצÞ4ÁLƉˆÐ_¬‹ªhÚ:˜…~Ö›ŠúκbaýÊ”&k 5“’‰àÝüéÑÉüèã‘€å¹'h9Íb{ùúèê÷Àêq¦ÒÄ»µ£ÖžŽø–Þ룗G|¬ºJöTœq“êó åþ&˜©Hø›ë6+*¢³ ÔUÜ¿[oºYÒÏk³0U[deãÆ÷cé“—tÃÆˆ„MKîwîæái4VAò…Q Z >H-@ÎÜð‰ÆZ°D«~4ŠORS,«˵ßǯNŽŸ=¿<~~r`Á%Kã°ŸÞ:Pš­É‹åAàvZ›¬\³`E‘?_æAGÂR{3!X†$¥6MW¶Eup„Üo‹<X>àŸibÞeIÔ*CÈ? ¬ÉMX9‚À%ºÊÖæÐö£˜…¡ì7ðæäÙ³‹Ëo._¾¸üãù‹ß^?xÞ$$W,Mt/ˆY‹ìMŠ3£8“ˆ44¼:î1_‘ÓÍ”Ž$Š©X°PE@R’„XáTþw¯ã]ÍBÎýStBëk¦YU¦qžØ üú£©šÉR{ÛæÞL‚b¡ ÍNëAŽ)ØZåÚyVœ®6nÐ*k{ʱúƒCz•ÙÉ ˜EÌ5¾ë»Ddy>Z“¾EÛ/jЯB°£·\éWìÛ-¶é$hº-Læd„GˆWnàpb8»_u'Æõ}f2œ?·+S}VpäÕ¢@{n0S¦Ã(NwwÃv+¬D²_pàð8¾[.‡†‚Ѽï>Üî,ÿßïoé½ôÀxÒã8~΋ ”˜þ¿×$‹AyéàÒLÃæ¤Å+t=^=ƒðê[2v@»&XgÚN–â£ewèŒqAÜ4ä[¡ø;~t/árßÊY”2.à ™3“\#ž¶žˆöê‰P++w!ýzq~y>DùöèvÂ&ÜNÆe☟à&¢{€ã¹hê)R{±Éds]€1âC®»¬7ë½,U[îÏŠœp¬ÈiYÙ„ÒIüq"}°Bí·uQåÅ6+ú__ ü4•8)$›ÇNîó |Õæ_‡1I˜LÕƽR Þ£Ð,å{5.V £¨LŒ¸:¦ù¶»bذyCS0ÚÞ~ˆ¡D¾å!7˜4ü‰¹Ù¶4c"teet(¡Æ†TÈ–7.Å©fÁbr%icZÖ®ú¢PM‹š±}mmUü¾F ‰‘°÷Kú:0ÕÇ)“r¨)½v¹vv]bú£–,÷+S Á#êɶîÌ¡ª*E9˜¢}‡@y¶ŽÒPzo¡Zès{LëÉf$·×}Œ&®“ˆÌfŸIV:6|¸¤#ìbW5â‹çÖ¼û’yAÝ*’áá¢é®“Ó»ªŠ•jêT˜¹\êé*°·‘›Þ59Ë7Õò+Šî|KÅÒàs{_°/ZÙ >µÖ•0}Ú– TáòºÍÖ½eaØLóA‹)Å%Œ_x"±’‡^k~§ï¢hЮÞï<ô€QÂNõÍPlÑŠ3–åÝþ^Æ^¶¿“Êy[‚/»rúò±ÿ&j&£o~’;øŠ¨%½„$(&2õ^eÛÀퟞŸN]€ &XžíM7zaÜSø/Yÿ” endstream endobj 2067 0 obj << /Length 2220 /Filter /FlateDecode >> stream xÚåY[oÜ6~÷¯ÐÛj€Œ¢u)º¼‰›º-œÔ· ¸Á®Fâx„èIS×XìïGR·™fí¦‹<Ô&uHžûáá9cw†m¼:³ÕøáÌÁhŽºFèØó#-ÏnßÙFø·†mÅq`ÜË]¥áÆÂx{öÃÙ?6gÏ¿ö#¶âÀ ŒÍÎðcÇŠlÇb×rlfl2ãÖ|±Z3ó›ó7›‹ëջͷòˆã[ž¸âÌD?6Ö®gÅŽCg6«µËÌŸ.¾_Ŷùã…8wv±™s°Ð =ÿ©ÜNH{L°ãY>~½rmsóäÃÈ|s}q¾òlófóÍÅÕæò…˜Ÿ¯"l¸|}E²xÑD|Š%µ`-Ò(%:;2óŽÆ„†¦åÉ¡ßóªÏÓ¤ÏëŠÀ%OW3÷I•w%v+ß6ëV|Äæw‚CÞny[+|Œ†û}N'éóÐqµþºâ4Ùˆ£y©¾Þˆ¯¤ëîWöLíþÙf6XÆà ¯Û#³ ¾‰§´È±"4u¯ÇŠ™2¾<ìxj«ã›ß½|ahC O)© ìiÀÏÔÁR ¾ÿxK¤¢-¼J¥²Ì‡¦×x¾^…0Þ[i^‚h5W¼PäÕñ´àI»ò™¹† @ÿkŽ=qðˆ¥ä)ÍD¥§4’uu‡­Q`Þçýžf '‚À×$­«ŸmÏ¿;´Ú7"FÊÛ[)ü¯ôI´1iù‡•c›0Ùzµª%zsÞfë&ieˆõ„ùúüååÍ[ÚÑ=¬°B(x Ù}ßìÒ:XæU²-¸ú¨ýºÞ­ÁÁzK<’9­Ëbló"—™­eÇ,¡¡G x'hsU‡r+õy½S» „M6 É`<PßoŠZ˃t‹Œ ÐVCþó>QžAKsQ;k`>´bÏ#æåe¹0CR(r3ŸlVFîS6/Ú`¾O\ûÚ; _dN™]êðž–ä¾1ö±A¡ñ¤“åÒ&D¶ð…l2‚$-Ü\]þ“Y]&„F$LÐ~©tW§"šÞËûH†ˆçi7Zç¤é2Ç^¾0ªr:M šJ©H° /õ|zω‰‚#”³‚/He°x^t r³kW}Hˆ¶åà2·-7ððß £ÅÂðúÕQ6º¼ÈŠ]Ò–ƒ 8GüdÆíšÙ¶ù’‹‹ "s#+õ°õ{¡^)ÐCCO©-2xsÁsuz% a9¥=BAêiåIÊ:Žrµ•#ta\IÎB‡>þûQ@Â,R[A0aÈñ\‹ubè}»e®¼ÝÇ„ð¡RÏÕGêOåÀ¶Âx Ÿ¥ÿ“¼ZAéIšâ‚'£õÕ Ç£¸Õ=웤r³Lú/” ŽËðZŽÊ1N-A¼‡ôk(ˆ,¼a 7ÆÈä‹Èø`Ð[J¶iÛâ3- I¡g1Æ$¸À³\Çrúa 894?<#.ãšcüÉó#¯*@ÉNáBG¢#,Úñ«ÐTG=ÁiO¨¦øòpÀŽÐ`K Ó¿Œœ;ãÎ3áÀbx5xb!ŽÔÿ§º‡k…ÀUjó-"ºRoL­ zÓÒÛ°Œg}1ûvá§x›Ø ü„’øRZšéGjC•Šy¬JþH|]ÜjÔ*]±eƒ…µc‚«z•EF0½5P¨@¥¸ëbº7në¾y§¢ÞZ×ÿ$33ˆH.Ìâ:óDüåì– Jð¦4Ê[ó«EÆ{Ì¡5Ûäï ÊøùXŒº‹oÅ$ò„ƒGzÙ×]ÿES·½bÁ–GDJÀe)1Í 2G„óá[ê¹EÊòÃÌÒC~pôÞ]^ðO³‹’JÔcß%‡ÙBB:Îi²åE}/ 5aµ ,m¶¼ÿ|6øô ß¡*)QÁ¢ìø|"åUÏïžä×°¬zˆçG=ý.œBF¦Ø)„·0v]eÝ»Á'OxxB›ë—â_UuÞ’©ßÓVe5ÿBÁS”ŸOcÛº.xRý®‘¾=ðß=¯2QÕŸñòÚÇ«ùÏ—»ª«Qîõ©¼õß“½=•‰]ߊ‘äÆKYP†úÕ˜*zÇ«¢ˆâEF;¶ü.¯:ZÐ=Àü÷ó¿‰þ”h)°ÈÌ{½^úADüPã¦A,s…3QøT1/Ø9*Ñ™g¾–Õ›àò>ïøŒd@-8ªë¥ÆOÅM8áBÁ÷ °¨jNyr±ìˆ|L'ÙT‹ÍŸö²õbÉ>Å>fª!çsQ&™k Os©åL6e\Å™X¢ô'ç£&gë†ú:Š…*ÓyÙÈŽÕ•>} >%f[Ñ%R;áo¢ƒ#|Î:¥‹ËÝ¢X<á6öÔmlSwUªºWGæ2‹-½®ÚêÝPœ~Z©…XžAׂ˛«·1ž «n.^^^ìmx˜2à¹(÷Qr?ÿR¼ ¾²`Û÷ôFYƒ7• 57)sí(½Üy“NyѼYN´D—é¶Tì:ha?µÔžÑò`bÌ'J^`Ö­Æ*ÍéVXÔå.â·€jqì¦S-à+‰W7链Wø¶j»‡ÔÆÛï‘nüð´&9Ù£ÓnG=¯35ï’,ôÚñªèÛZ·Ñî÷\]!S>’{âµ§l¢»Jc#¸nGˆxàÍñO¹ÓWˆîÞ-[¶2Àˆ¢8Œ&éL~Ž‘ª_eBùsLÇ«þ™ê´çSÅuzkwàêØ¡r{£ŸôÔT[Žfê&ÇlË5kå¤×è”ÂX Ð$ÂÕ‘ù¯EMÛêa¶(>)øY`ùÞ‚çÙ~œÿj%{ƒ’²lMÊ>þGÛ‘Ž¨ˆQi)¤"õI“:ä˜H,“-?ºÕ.DdÞ }`Ô Ý¼C—d'wªëæýà寎ÌG-.tm•ÇýDÊDÑÌtT;6 —$y* endstream endobj 1970 0 obj << /Type /ObjStm /N 100 /First 962 /Length 2050 /Filter /FlateDecode >> stream xÚÍZ[o[¹~ׯàc·97`½ mXlòÐÖȃ7kì]ØãÛßo(Ô²dI–…EgÎÑü8œ;Oíæ©¤Ú­'©IT’þóT‰ã5¥j¢I¢Œ \Õƒ ¤Úƒ°d“€·±,ð‚Sk¿xꥂð’z¼-Õ"1Õ-(pPPøÃëÆ¥1«Û€à˜À /Ä0ÊE’4Lä.-~_±Ûux uPÄÁÒk"n±@§DZc “I€ë-Qó†tìÖÉ1àS×1Ö3÷Ä„Õð+'fA°S–RâUŘ©TPЉñN7ü¥‰]hʇ\@5H´ÆˆâIHƒ¯â($NCXAÈ\p ¢•ƒ ëŠ?Ä Ѻ`ŠÑÇ;OZ yÁ„Ø3Á^´j¨*¨\T’ÒD8Yn±ûÚ“J-†J‹d8÷Æ -`3¬¢ØŠšVL„),$[ <à „)|ìŽÁÑÇzÓu¬ ã x­ÄñlÖª÷…¨ &Ps@MŒ-``g¦4~m {U#|œ÷ÐÉØ”­•‹Ac‰bÔ!#¨|£ûS¼ƒÄƒMS³˜Ä Çò•–šûxçÉC zò:–Õ£YÍó‰YBrñ²PàwÛ‡€\5 á›Ç8ètƒ­„$Û+¨ËãŒûj)«©‹èâÕ«Åòût3dòiùÏý; Û”\!©ëÏ¿ýönñõ×2BríÇ0*g‚æd„þg…´6_ß\ߥW¯Òòµ„½CÇ×8¤Ê8ÖÕf–}z²ø§§Áië§°b†â K,¸½yÿæê.]¤åß¿NË·W¿ß¥/«¿ýïÇ+üpùËÕbù\]ß} w¤1~±üñêÓÍçÛ÷Wã¯Þýãêç—ßÞüž. ^N©uz‡….o1Œ8çÁøÍõõ f»X9ÇÀ3œcÖœ‹å›Ï?Ý翸þÏbùíÍíÏW·c•ònù×åß–ß]ÔñÀÞß…„5‡›ÐJÙZø0ÊðmP3ºí›!Ù7iù—›·7 ‡ò§OŸú„±n®3åšé«Ò,`ZÍáuÎp6@u”"Îb7’5ŒÚ³ÝG14§É=Í1jË›ÚV± F8BYЧb+žBÅïVÆ{êwºŠõ*Öž¦b‚ðÃÛ-ˆ“·à¾½·#·ÐË–•ød%NÁ!sÚÍZUUJF(L5ÌG¬Z3”í¦Îg7ÝräUˆáY#AÏ„ó‡ SÝ æãåíå/·—ýs&™ {ä Ç ܈!Aósõú¨\¾ˆpÊ|pjñ\©‚8kÓìðJ&Òƒ’Ùö*ÞŽô*Œ‘”ÃLˆíYü0qDA:) nƽ͘¸áÌáIŸgßݶí{…ìDûÖµ5÷ÉÐûdèç´oØŽi]±Ž (ÔÏÎ~V›j’ ‡dH’j”$¡%HÐQºä"çDB¥Aï"uäŒ"™‘@#T:ˆDgD"=w$ö¬ð¿(È-Ã|37}’aa]O}[¶iE{²ÎòLTjôÐÂF¡x²…uŸì©ÏiO1„Ýß•3·F(‚ÆÖè¸"ÛöäÈó&9â¼0)‚‹’fŒA´0Ÿ™XŸ,U.;¤êÏj?Vª}–Üo³ßx¯ÃxºDd["L§K„ùH‰0ÿA%"¼-©O“ÈýÅS¶ËS¶Ë>}MH™3z£<6MjÑž¤D­mÑž¬gnë³(²nú‚F ²qÞ æ^é'mÆl\‘}·ÿ‰Æ©´£‘øœÝr\3ÒoëÈ‚× ©%ê„CE茭Ž6R\”Cg$®à#ÿ­kDrZ> stream xÚÝYëoÛFÿî¿‚È' ˆ¶û&Ùöp¯M\Ѥ±òÉ Z¢m^)J©EÐÿýfv‡¯5(9#μÚç¼vg~3äÑMÄ£çg?¬Î¾y¦E”±ÌJ­®£DF‰N™ÎT´ÚD—ñ¿ÒÄÅáª8ìšÅR&i|¾&Þl˺lÚÃbiâ¼-wµŸ{~,7ÅSÿûMQySøŽ`R2±x·zyöÓêìý™ò<žœf O¢õöìò60þ2âLeitçVm#mSh«èâì×3N¬÷-À9gÒ*ÜeEt€‰{ƒoa…fJ[ÙI˦u⥒IÇäçS‰.—†óxuK’oŠëüXµ¾Ó.w  RYû×¾˜üæ™JGáÑR¦,3Òsx» ÇSÑ0t2 ´pªäþTìâ©îWÙøöØ©Û «ë¼ªð˜¿üÄÝm·½Þxj³/Öåo\éîðë… ¾“ûæ¦üs¡L prX@ËK¥Tü¢¹)ð¼º;0oÆWÕºC®›o½ÞÀ FgQØ’æ¦ÀLp »;hSf…Š,Ü‹Li¼‡ÑûÖfhÍý² »ÞFÊ_ÍD1cŒ® g˜o«N,M¸nJŽT´õŒ`In{?¨˜66Ɇ¦eÅ~h Göª#Øðá8>[CGÁjÞ­§†;ÉÖÿ÷ò]G¿Fpy2ƒï›çýðÞÇÿÿÔë YÌKR—f„“N_†fz}u^_]ÏR4u%³üßp–Ñ#2ÐñÚëÕ@ÛP!§ªâsÞÑ=GIm§Ê¥ÍØ ÃÐ}:GlÓiÔ±&aIBQçr×îßáëŽ$hZÂv!ÀDÆÏþøÓ³ó·?¯èõk´F÷Ï1;!— þâ7Kƒ*rJ¢[¹ÿýPäÕöQ(]çUã<=8ôrãTàû—ô\§å"‹RYœû ŒÁ¤=ä-:]Þæ ÅÑ¥cÇyKï}O޽ã‡(íçÛî°IPð¬L,$R×oVh‚€g?Ó¬[7 Žœ ø«)·û.ö`ÿjÄ4E€²¾!A±Iãõ®Æñ›ãÎÝ•ím J“o;=K`š«©¢k˜fÓ rpñgÁYöèA=zX$&À eÝ´mÕkBƒ>v:X-2ˆ§ 1-F~U¡ö´Š_­^ûÁ>’c'÷ͺ*‹ºõ ÷t•êu¹Ï+}Ê2n˜¹œ°i{ôC~Qê}÷ú‹§FlËLé/ÞT»Ÿ¹x"aB÷(‹7ÄTÛ\[’w"f{›kSéªX û7ü¢ ¸Æ$w1"ÑøüSëmºKcíøQ+¦·Á­×€ ÿÞ8ùÈòGl Œ›^' øL­æuªIÓTh¦÷*t8Í£¼P™c¼F ïåÅ«_>²zwMò¶"—Õ>.–Ó2ƒœB~q,gÕ Ö±&Ä:ÖÞÃ:ýFó¾ÓÇô~„ÇñÜ—Âr_«|'a¹ìËc9«&XÎêËgÈ@Çkg¬Tƒî°œU_–Ó vºÂr:ù2Â+—èi'纎“ÉȈ)ê³þœ'ž|ûɇq†‹Ùøµ“碓±‹Ö‚¥Zu~ðûæ¾?>åPØúÏÀ‰O5¥òôÓµ´L³c&ä ºmÄ8_FU.¯5_¿ª‡G±yª«²Þ”kD'Ígh‹pý%müdÕ%):º¯^u^JÆØ»ÏQ»2à]ƒLçf"L“ ì¨0IBx¢„Œ}«7û~NyPŸ%Á‚lÇÙ lÙ]ý§X· €?#²ø‡Ë4`ÜÕ»ªMó‘ͲÛLÄî¦;@i$®)ÀéRõx­«Rcn“ô†%ž<|þÄäÀBÀebž—,) ˜I©vëôÌ û¿ƒ>äJâz×ú£R V€Ý•43*V6~S»›K1MÆ´<%Å´òd~=‘¯D1F´5e‡Á™Z±,‘÷´9¬ãÞaX˜ùÓ‰U‹NE~þŠúË•ðWYÓ ¿3‰ß"¶Ö&^þâŽèVp§)ÜበޜÿøâíîË‚ +¨2‹_\ûI2EvÏb`yš×Ð>¤ï~ycgŽsÚélÜêÀ:¥Ü»#‘òõÏ[Ó™{(àºÊ‚o‰…lRTV¾îJÁ=>UÇà³çÌ> Õ3fLB3¦.qñªìRRìíèZçGà·n‘’ÿºá¬ØSîn±_[ƒæó–L {P…9~•XDÒYüʉ÷Ú¾vº,oðü_ï½< endstream endobj 2084 0 obj << /Length 2607 /Filter /FlateDecode >> stream xÚíËrÜ6ò®¯àq¦’ÁâÁgR{P´ZGq­V±Ç'Å¥¢HJb‰CŽIŽÿýv£œ¡)v¹\[ÖaH4€F£ßÝ÷n=î½:âæùáHÀ“{‹¤ ÎzÙæèò=÷r€ÿæq–$¡÷ Wmûï9]CÅ£›¯dÈ5ÊHn*±m‹t×ßu_fi_65‚Õâð4Ï‹œV•ÜU‘v¬4ÚuEG‹¶»ëªÌz¿”|Q ¥Ÿµð„Ѷon—+Ámº½sójÑÙR‹»ºü°„Ù!õ}c· ,é ˜Þ"ú´¬;ÜÓkÉp&90š©È‡_?½ÔêøæH ÇŠ¢`†£L5Ÿ¶i×= aM‹¿9"÷VvÑJ–F›ò2CÎ¥p5sž,Ò¾O3Üyß]F»÷„ ¦Dbe€A$‹w¸¯®JýϺ–‹B{ÀÅë³ó³õS¡&±]ÿ#]¦ìé™7ZðV7Bù$¨²-ÌÅëåˆ y^jÞTQ}Ó¦$-R„]ÖïìÎnG²7[ÍIY+aCùW>(iÑý ©U]¹ÙVKXb­‹"ïH^BÅL&j*/­K_\ô 4-µVw45 ´í]WÖ·Û çìÀ›Ô^M^Ð]u-ë¬5F„gß™—“‹wô’Ö†ŠºèAPÀ{TMêÜÛýú_'LߘÃU#–(uhíQ8K5€³Ô¼ì4YœYinèy³ôáXÍ(UUn{mä¸Ýðï#RköãnvÛnŒ %ôeo ÆÊð’ùjDš–ÌOýžŒ‹ÿÄÒ•ä¼-@`¾‹õ]áØ0’x[dÍfSÔ¹•ð@žJG4›B¢X<˜B‘?¤mÞÉ ÉŒ· %‹Bß.þÙʧ-Œ„ÎÏÞâ]Ö4š²¬# :Ý2bÅ¢`°`XΜ/C&9Øí!Ÿ%±Шا’‡ø¤dÜ„!tÇšx8[Ø´êŒ=v»í¶1Æ^ä¤Ï+å,árªÖ¿€6ˆüQqƒÒOwU¯=Ujò‰¢™HÔ@öñy‘ÄÆ#{ÈeU^8Õ½*’ÁííÖÞp-¥GUš¼CsH{Jœ¬ª¹ “ío8r‡:´HðT¨/¸ñ‘[§ZêYo"d€,’ÉT”× ª÷$¢í…’iœ x6šh|Eß»`Wpá›Iæ‹è¹60˜²‹KãêFù'#\!¡½§ñüÒp›„‡1ƒÔÙó%è‚Ô‰¸÷Á£\†”×ñýa¶ñåæ$üA ÁŒ€f!Ð+ø`@4yš%ÁP^6IH±øÓÛ0a~FÉ€ÒGZ6œè@ tƒÊè |@LJã2(XÍízóàúfÙÿýýn¼ß=Pž$@ûÅÇ+§ Il~_ªÌxiØåƒ¾‹Xj~fÆñˈ_v$#Ãh3í ÀŠ\ŠŽQÜpgÌdƒÙ† y.+þŽñ½Ü>-+WaÂ8Â+4¯HJä§®a'Žê`_CÔÄÓ^ÖƒÝ‰Ü G50bØha#ÅVZÞð£o0áÞ%¤ÁâŸn€á˜V– ‰„Ê—1Þ)tê³ñN &Cçù~ (÷ƒÔ?zÐcßÌ©1–W.¿«ñ)éD•(mPPkŠ4uVn±,Ãy˜4ÐS¥„.¿pù'Jüi¥ê»*§¡Ëéqàê>:d¿Ð0ù±h*ÿMa3ù²Û|Ù` 0)ÿú±@3¾„ºç+E|à+½8Ÿà |@LJã¾V,øVï÷­ÆLb÷cˆGÇÀ€¸3æ ^"´±ð} ±@…Š ? ,Œ„i;Þ§ù¦¬Zjϼiòm è¥nþ‡=7Í'lùüf`伯%÷üf`À‚xÚ Ä&›éŸ§,û_êtS|ÙÊFò„â{›ë{›kTÚ$ßÛ\_¨´AóJÀÌ+m$PìûjâC^ÔæÒ>ÑøÃâëw»B¢É}Þ–‡#‡ƒ–Ú:¤ôÁ€æ ƒ4±&É?JSüˆIÀC,£OÛr”ûÀÊ!ˆÃÌa%$]’aj…Îx—öÓ#M½…:½Sq±.|^²d¾„êwÓb¬ÓŸü]±„s“¯ö€å%ežýD¬¥o NÒûÿtø:·ÝûŸ#ôÏûר´8‘`Ü’ !‰q²äÿâ+ìh endstream endobj 2089 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚP;oÂ0Þý+n´¥Æµ?â‘"Š -ÞC n±D$Füý:†J:ÝÝw§û ¾Á½9ôú.9XjµÐà¾À0²¢Ò–àØà% û~çûÓ@ a*œ A9Ùºš9tA<Ñ3à™NRà ì[´Ù2h¾FK[Áí~Õ‚ÔUªGX£ÄÒŸõ×/%©Ðÿ~õ§{™tr‘Í[6ª×†áé¡>…#ÃxX*))´´x½"ZáÉr–ñÕ=__ãÁw1ìs<£ó§ä”À2ÝY& endstream endobj 2099 0 obj << /Length 3356 /Filter /FlateDecode >> stream xÚÝZÝsÜ6÷_¡·ÓN³:Q"õÑ7_â¦ifÒ4Þ>Ü´Ž,im]v¥­¤Mêÿ¾R”Vv¿nîáü`‘ ‚ þnèÝ{¡÷ú*äï/W¾¡'¼4òR*N¼òxõÃO¡Wý/ ò<ñ>ë^GO&|ÞíÕwWÿÚ]ýó+)¼<È“(ñv{Oæ"ÈBá%yˆPy»ÊûÁ¹Ù*ÿëë÷»››Ÿvßè!B±L"³Ã@æÞ6Šƒ\òÕF(ÿÛï?ìnnÞᘫ›Ý\ÒD¥AË?+©3m$eªØKDHšõúÕ«7··oÞm¶"ô_o¶Qšù¯Þ¼Ü½ùöÝFù×6±òÿMäëMú»Ý&:’_¾%ú‡7·o7qèßÒRãÌÑÎV¤‘žs‹Òg<ëÛMúuW÷Ý<€aÓ6cS¨RœÇ‡º›²›®åܱíz(„þ±86‘ò‰<Ô幯+ªœ‡¦½§"0¢Byh€%•OÄ¢iËæTþ±‘0žZ]{¿kž‚hµ°¸ÀÇM¢ü@Í¥ÿù¡)qǨÓ~#C_‹¦ç¯ûa.ö=ÊZ·[TlÑVˆ Wl,uï¬%IüŠço>¡–õ¢`Þ}ß©½ ©†ÏØ£ë«`³as¾ç…›N v2}¶ë|/– £Ü%ëNeíÊgõ@ýH»P`úð‘ºwû™¤USâFÔ‹WYŒcQâ<Q£i­ûzM?š@îŽ ó!êèʔӜðê_6`Ñçº-k¢h¡à{ꆡ¹;0ÕÕâ’Äafz˜-^=skŒåÜýx¶FµC=°õaw¤³‘å|0ë éÎ‡ŠªwõrŽš[Æn¶ÄÇUå€élc7- kŸPøâpF­ÄBèÅ#]ïÜ-N•¤Dìßi´4¨ÙkGQ~%ˆS ÿe–x=8Ò â‡×àp’Ä9üB%A–ƒÄZRÖ´>&ð¿2bšò‘ÊÝÝêrhRvÖ ’çà8Sòèy5pâ˜ê eçYNúŠm7º]A„†­J4öôI»#Ý>7ÜØ×$ˆ³t¾—våŽÕD(µ@aèŽõØk¦k;@ò¹,Áögô† ¨âGM; ©Ì•û6÷m¶&)·ìû¢d· 5mô𥓠ã› Ø´3^}]ŽèH¢Ä×ÿ{«Y³FÜH±’±PЧìà§–(“Ç„ÊÜ#D4nŠ}ÑVÚý©¹å‚‘$ ò8æ{ Orx¹#Htüˆ® ötXÁ]ˆC80í¡ik¢¡”ú šN J’Yì_·Lvº®L(.&ÄK¿'ÖȤ F2 âe€ÖêÂøÍÇ1Pž¡å™×6i¨OE_ŒÚíëvjk^@$Ï#ØlòÐûêå "ÁNPA_mÔ§¯y ÌóSc=l¸ä%ׂl9w:4Çf$ÿG«@âpªkîi´²dh/q¨žú*Ë]}Ân¨CMiG„êã„äˆã”½#PÚzd…~$BYœŠ²©ßnÚSÆÉ4ÐÀ ìÅlV4 ¶oÍõÒfâdî6p„vØrÇÃ@Q ¹­0ìs6‹þë>{y Ë²;nŠ*”¸êÝy|ÎG'qÉÈøh<,0h÷@P( /†³¶¨"ù (ŒÝè"»Ø{}•cgtd€¬ž94ÌàXƒ˜‘c81Ã#Q¨¶Àï%¶ÐÂÐà ö™íûjÿìöˆ´›ƒo¿¾"X 3uÎýܺç‰D–ZgCµ A¢ëWD–ie"ýI¿‚æé9îF¸W´WÑüè²=ÔŒ]j<¿ŽÔÀ ¶îÉâÄ>g×V®§wÜÑ èÄ.—˜Zä9ÍÊñwk€Ùz¿H¨…÷CÊå)L$ ’µåé[OˆwÇú¾›n>Á˜™;JÇ: IÐYÁr&χSv³©{>dÒVf¢– wÜåɽÃFnÂŒt(h0jEQŒ9ÓÄ7_sWiš] žQÁú/Z¨þ¹A”‰¥É¦C ä‘ÕŽˆ&Q‚A†Ù†#·éÒHÿ–¡AP;+ÿÄX'y<éS ÅCž8&8ñ|€2ôžD"_¾¢’®ÕýhA -‡]ëõÍ-p/ˆzW—À%ãÃ;*ªKát; ‡Å³éX°£¶ª@"-éd|§ºøpPÚPhlÇn;‹ÇpèþÜj€°|à×Ά* v=šÐ‹u»`÷{7ÝúP«à×ëÞÙx¹¹´\Öœ§xÎM‚†Þ¢Ë\=ްæÎð_DF3I­êœ«e0@·< k'™W@ÁÅ à¿…€9ŽZDÒþ‘® 4âÕëžûöhòí˜ @ßoOÅÈÙƒ5‚Á6çÁݬFÙ·`.Ã8&bR3¤¢3õ=à†#Á¿y®‚œ’›4!¼‚%’<ùƒ’—:º]1<㘗ë‘v=t!K‡qAþÙ®]LعnÆ3·Eˆ@,`3A†ñõ-Õ/q/4ÎÒ8ÑžÎQû"TuµÝ6æú ŒÉP•1CÀ^ñ öb£ü¢GQL¥3X~>Qsd+ù¶,\—웥Š{tg"ã(F9…² ÂrAŸÝë[,ÈKa+:Þb¯ÓEzŒ“©³|Ïü*ŒOcZf‡^–jVãÎï@ãÆ4q¡z ±xµ3s·CEf;”˜PXl‡OlGžBI£Ë-Üx ûùçáS¿¢z™*‘sÕk´žlNº£¹ŠªêÉêA”ÙqR—ž3RšNÂX¯Ž€Ûø¦(yxà´–k^.ß\X$¡\¢V¢2HEöPe/È·¶ â­…é_r\""%soùÕÑÉzÄ(7;›O² ±©,È£“áÞ/¥Á£D†ÔmQ-^Lùñ4”Rš|€š "!ð´È4áÄÜõDˆ½ÒmVAšÃŸn‰i U’æG‘q·iFK*¥­Ì„–NìÂiº*1ômú„zeåÿýúöÞwO®0äÄÏkkÏæ:ªÍÿ¼9DA ÂG¬.HX\¤õ¥¸ÅêËH_¶Y±¢¹š‰J2‡—Èœi BÚqõ‚‹àa¨?ªŠ¿rŽÂÅK˜ùUn“<…ÀôfÄQ†úÔïH‰ëèÒÈ‹ä!G¬µ7ú (Æ#UW”ã¥AT‰[`þi gÌûAþb–VÖp!êÃ[ÏÞx†ávÉ89pÝ®%m‹c½âÏá6Ž$¬2u°›kˆ¼0»FhG×8RhšDä`` û´Ó™@$ÑQÁF…Ç®mÈ»kÎK¨',Ôƒæ9ÔC= ÆîÍÀ=ÃÄ žJ“äÃh”2Œ?#¤e D2¡Q€íUe°YÃ{Õ׈˜Y"); o¹ ›Dnœêµe6~ŸÝQݽ0?”)~âý³D|2•~`y&oçÓÉyGEÙÇà¹ÝÒöüõå7t‘ë¤ÙßÛÖ4Â&¿ÞíÞßcØRXP‡ûúëãs’)å†sÖ ôçÖþFIt8DÎ/X ]ÃR³_4]^d"O­‹Çööyb>÷ÆÑ[˜GA²–iÒV¬}ɯ|¼/B¼™aÙQ:ñ¿Øí,õ¿Ú¤!f@ª>‰£Þ2Ü«n¬ËÑvã4w2ýdE§Î?YAot5ù ›dOì‹æ2®ñ¸6k¨G ³ÑöÊXŒ§Œ]ºÞ‘âï™qžB€ÛG÷¶kÝ™®­imûû·oÞ½Ù=· q¨é!Ÿ²eø!ÊË÷(Wý›û GT5N״̯d`”'Ø…<4ìÊ ìJÓâ¨ÜñLÇ®jöT¾Db0š‘4Ï‘fI7¨†RѨ|*_ 'À8eóÓ(ŒÎEšþ/ù‡îÀT:Dù”ÀRø›ƒ=Ȇ8½çÖ¦5Ãa;òÜ73]`)d¸Š¥T>½ØOã/3ùI¨“å¦[Å“#â<ÿ½šÄß/üÄïåoé(uʧPì '™k® ZDLÿÛǵà54‡2Ëß*Dà?ÄØøýQE˜RP7Ò·–Vt.–Sþ£?oû endstream endobj 2107 0 obj << /Length 987 /Filter /FlateDecode >> stream xÚ¥VKsÛ6¾ëWàVp¦B@|ÓÄNϤnÄžO"!‡cŠT Ê­ÿ}X¥”Œ¦S_b±Ïo'„“«_ÊÕ›k“‚©HI¹#™ ™Ê™*$)krOo#‘P3lÍÐÛh-²œ¾â„Öû¦kì8Dë„ê±é;<ûpljó3þ6­ÑÖà&fB°8z(?®®ÊÕŸ«Ìs£9Å2ž‘j¿ºà¤úG™,rò—çÚ•æ°¶d³ú}Ńë|Bš-BÈÁ}™“,æŒË Ãø"bî­Obo®e!ÃTZÀg¾êô¶mºÇh­„ ›»¨àôíí•ÛJzŒ>ŽßL76UˆÜq鮯skÆq–>g” c"VL¤Éd®n,Ø3_MW /‡(æt4õ×±Ù;FkØê½ƒü€šNÜŽeÌd"'MÏ.Y’"8mœNtiìƒKQH²ˆ'Áq8š¨ ‹gåM´aL+ÎÏ]¢2_•§dh¿#~vX§éBëZÅ9+’œ¬ãÖÕß‘äÔèvo.eJfLd3vö¸µ¦ ˜pÚïpuNúŸªm Uá¿ï¾p©ƒO;3sRDk•0¨Lð1c…”ÿ£Šþ°¾ $¤NwnUôײ¼Û é0ô‘Lèß/x¢-’kc«¿­©ƒôÖ³>»k.)—¡L\M‡«Ü© ‘óO‘Jh0ð4lÒ;dàxò:ëDdôf÷ºdC°t®³Û÷ïœ:²ä“ €>¨úBö•0Àòr oåÆD6¨PRУu˜é ßSÚZÕ M#i¿ÛZƒ¨#ÈC¤8ucL¦>w^ª OQB£®œ·OîãÅk¯#ï´gÙN¬¾—m ¼ÿ´ úÞÁïJÆí‘SÒJ^jÚÑ0³$Bp¤—…zGIøÑ¸Ô Xf˜"Ô£û=»)¬“®Ï4{ — ›âÕ}ä¬]GLâ¼ ‘ÙÚYßø³eß0„K(Vð,x#ÐÀkK9{w{ó馼8¿ËÕÜ€ð«l×À” Ú~+ï.™p g³«zp9„ #ô‹HéÎÕ½Oºp¥ÝâæôÊó­1 Y;軪9èv7N®í»Çõjk4lì8ÓÝÁ"[ø•àåê˜êÆÏúpބӹ-&9Kz"]FëK÷¨ÛÖ~9+j=ßUpøìŠ8¹$îÿÏ—¾µ¼ŠâP‡…p°*ðìÝ7}ˆ`”G¡ÝJÁ@NUž_µyz–Ð`l@hü ­rß'¤ }r {Û?avë endstream endobj 2113 0 obj << /Length 2669 /Filter /FlateDecode >> stream xÚ½YK“Û8¾÷¯ðmåª6×^[µ‡l&™ôÌNo6ñ-I¥d‹n«Z–IN§÷×/@²$«“Ijj/ ’@š/î|ñëwßÏW¾|!±\Ä‚³PE‹íáêýG¾ÈþÛ‚³4vÖa¡£¾åâÝÕ®þ¹¾zöJ‹EÊÒHF‹õn¡SÁ.Q*™àáb/Þ/–«0xýüÍúåÛåÇõov‰ÐLéHâš•,Läb%K… 5¯n^­_¾¼ÅùW/×c-£0f±Ò?ªå@¤R Ó8 Å4 |óöæv¹o›=¼  Réf¨CÐÔ“”§ÜœõóÛmÎ8ÊòÆêÎGYß5‡ê9€iO[ä¶§^æ©í؈kê¡Ô×ëõ”èHäYn¬Ú¡µÞîܪp‹lsèæž^!±(fï1ši7æ€Y¿¡˜¥JцƸ¢„ ²üPT-l²®nZ¢×»Î‚>4§MY´{ìÈà1ß”å꾪QŸ7iŽsY8v¸ ÓÔ£=Ê܉jÌŽòI\ò aòů͑Ø(*·Ý,÷*Ÿ%ÌE½ÏÚ0+V>WÅ’ÖÅΰ1ISñywà´1žpí]Aù³}jå¬}~¨'¼6¤)6EYt4 ¿¹9–5ºû#æ|»bä{V%ÙƒÏÌÆ/  %mq,WÛÃabSôÞ ÍIq@ÄCq·ï¨¹1ôE#æÔDï-ëênõ=1«p#ÐX€ò ,°*©`srìݱcó¡ðêUYwjÎ… ’†î‚ýnî»Ç£‹ù¶>¬ î¨[÷¶N:‚5Á7K¯GžŽ+{O§N[ûVI!2ƒYsna±¬öpë0 +:«kY˜ÐÁ&+3Àv¿ Ïv¸ñˆ6ŽÛu Dr_ Ù,0b>mã,‡uMÝe¾âœä0 cã.·P­Ïä,(E"ÝÏj̶nr_Ÿ9!PwÿUUÙJ¤œiQq&Ò¾:“ÿ§êlpA ŠûÏj7`Ž]Áܬ©qßlBj¹âÛ¶ËbÓd¤Î#Þœ ”’$½ÔÀNÆcÇï´F‹‡!o7Ûè- ÷ÝÖU×ÔeIËe°q îu'WQã£2¯ÚOËÔ'PŠbj®ä‰Y’ö•Òõ wÍÒDôVåí›”©xÀ¥O¿—ì¤d\Ç~êg´Ö ÔÜ=~j÷u󔞉dý‚Ag ʚ³¿[o`P­¢gÅPÉ1DätS¢õî(nC©—òÎ?DYp[l?~ËÕt ×âÔ/e®þÓ!Óz\&ÜìfL"@¯´á:>ÉY§ãŠ5u ‚í ²( !Üï³kNsœñÑ‚K? k%W§ÁÀ*D )OÆ•cX_ô³}Haûè"á Ø<8Ø{ê˜ö@'œÓªÆ´uy¢XþlãS‚¿±¯D’²|õââ.} "cܼù¢‰úÌJ$jä¨y)ëÄTûà·~ZáЩ‡p©8‹uŸ¸3ò.ª]öDcÍ>oIó+­4WþÖ²ŽM ÅéæR8îîñˆîÒ§p˜ ²Ü†¨Ÿ×‡ŒBp1Màj’Ž-Õžðiä+ÌÖ1¥K¸mëxºm ;úVÆä&¿¦ùTsCƒÎs¨aæ‹[<:Ld¶{ÎV0ßf+ŸÚ´e[³A£x[èq uƒÈ™ódÁ¢TŒBxºbS°Ð–/ÏÊ}¥ßr,Àt,þ²â¬jBsÉD«‹>d„öGŒ–§g* Í† eô „ú(C Ïn4˺¶ð® ñ5>ÊÐò¯lésnªÎx’ÓÑE už %SÆC9ô¤ 4žVË*§2ìB’=Fò¦±M2#÷ÎÚ¶ÞYçk°‡¢sJwÍåÁ›õ[W—YÏœ½è=…ࡌÁBÝoZÖ)-Ž>à ïÓí|yÖ+#&B10ž’.žç¯•$[Uí.”Ã=äþÚHw%¥øÄÖÍn€ùó¼ññˆ0:•,„‚ct4uu~…Kke¨1xdÀ.úIÁì›P èÓùIU—áÕöªÚϋîO÷};Ñ>!dM¶nûTåM3úg–ÑãëùÅùЗƒ–lß³±Ñš¬ñŠ÷HkÇ(~±µqR²ãÑT˜ø WìæßYMÓ¿©ú;ƒ}ÃS˜ æªÀjs%÷—V$˜žÑñã§þC—*Ð M}¾Òp“Ü­ Kò¢=óíöEÿ¾c3«›D(™¶.ò½°K™PÉOE¬±½ô‰ØEÀd?u|xÕ‚¨+7Ùö~†»V,<ç t[@H4™p¯(¢1¥Éš‘8‰óHœ4$»¼õlŠnðg’ºÆºáÊl‹fƒÕŽÕ.ñsÅx¬/œ f¥ÚÚÉVÔØÜ€'¶€‚—G⻦ÿÇSØ$"È{ZÊ…¹e‡rCÌb(¾+¶øŠ@O SÑ?³û4Ez¢ã¥S{cÜ>– mnúOMßs‘V8§ª†»v¦“ùfL'ã‹ò(Žúâ,¦¸‰£)žâÐà˜°kã)ŽÎl‡'‚OŸ¶¤ûî‘> stream xÚÝYKoÜ8¾ûWè¶j`Z!%êµÀ<É&Èldƾ%A –ØnÁzt$õž_¿U¬¢^Ý23ÞËú`ŠE²X,Öãcµpîá¼¹úùöêÅk%ÔK#?rn÷Nì;±J<•Îmá|rÿ³ñCWw;ݵýfëlj{½‘¡[ÔeSöC·Ù†n6”mCcoNe¡¢ïßt¥³^SGz¾ïÉÍ—Û_®þ}{õíJÂö‘´òb;y}õé‹p  ÿâ/HçÁ̪%ÐVÎÍÕ¯W‚E[O‚äÂó£WEÒé`àŒøÛtX©¼@E¾=­ˆ=¥b:­ ½Àù×wq>mC!àô_¸¿£®´Ñ’ÕÄ«÷7ôQ—} ùA÷‹_¼’Ù}gë'^ú$àM[롬uJ–)è/éêfÀmஎØ·Äýdâ»eUÑœC¶ P¤D¢±¼m†®åáh´#J9ô4o¿QÂm‰ñDÖ4Åœ?v§æ6í°X-ÝNãælÅ‚… ߘtaÞlƒ’eé­Pk¨)A=!©çÔ¤†È-~Œ‡ÄN»Ç6œFß²â„ÛèH=~/sžtìH9åÈøŒ»„æ@@Ç•{äO™òE¸èa ÷U¬Ä»|sȲ6÷õHÓŒZñcy‹H©O9šÙzeóYáI7Vø²¹¤©^CÙÜÁ”(vOGl“óÀA2XøètÞvEOÉ$`¹j¤fEÑéž;ý1Ë5\r„îÛ=ÑàØóÍè#q‹$ŽòS5”š—>”þîLüeMž°Eð)¬ O#q‡ö’>ÐÍEÁ- ÜöÔî@4f*ð0-h™½xÍ}6I¼Äaù+à‚Dÿ¢fŸU ”Y¶põ(ôàÚí2Ra‹¼*ÁDè»ÎHƲѽ·ŒS?ŸÖ!p+Cå‰Äwàž¼Ôã zž8øC`Wt…ù²ã±*óYÚØi°jãqp±? ¯'>xK*vsŒ‡¾§7zj[sû0`. è'KȨ_è½±!0>¢Zºç&«5³jëcÛÐÀ„’wK.;"­†ŠFWnòò˜U4Ërë>hf’å¹>²m£P'àÚl/ÙçÀEóT!°(G§WÊbB[U ”4Ú·`Œ—Bß/˜±>«²9ÉpFÛtÖyÆzS‡`qVUDé Ï“¿¡"IMj~ǼkÑÒÂáP2åÑxèÀG:õ¬e‚£1Ï šT¬à¿J"²¶5ÑXu- e®¼ûnzöß3.%ð­ûq|ü'Ë!ýP¥ÎºeÛ¿42б0'J¼HNBÉ4B¨ã|s`nŠ›+AÓVݼvB?qà…ahÈô LH‰€HÅHpg}"N>ëù±§ðg–ÄÔSa§Ç@ð´iÇ‘”˱SÙ GŠ˜Ø‰i»:Ìv>7œ,ÿ¿?ßÞùÕãIC´8lÞŒAÿ§Ú|/á}V—òÎ7ú ydÔ—%¾l’S5ï‚u†Á&^˜mÖÎ\/¨^† ùQUü?:ËAÜZUn£ÔZt¯´ ú4X‘”ê‡e*ãàŸªrÑ#ÿÅD\4îKŽ<«¼kÚN¥8Ýv_!dR¸¤° ðšì?sŠ…Ó IýóÈÃÄ¡;]Â[+ˆ¯¼T° ãÓ¯A£Ô5@R¦1¾ÔÄôRÃ!8a—Q&zäÉ-µK¬¢p¾*˜3]¦jÀ]ÿØ@ fîœbMÎ3<÷´v™ qd ‘¶Ì=f+„oÈàÉ£fÔŒ°ü²%vH%R¸]VÃÜ@€–n’¾A ¶¦¤œ|‡YÒ‚)6)áÊÆÂqèÜeÏ`;ôg3†lÇB²6›eY;¤éc&€ÂéÙˆPÐG§³ªžÎUÀóY„¢Ün¼+IWð4¥Éê<»,´žЙ¢~‰u? _ÐÀWèH"ó‹fBÊŒEpbYe»Jó0ãÙŽÊ<3ó’¢X1«2|ÁÇsÁ\AøV¦#À Ÿà~„·!¢Ÿ²«!î½A½øïq05’ÝŸyåh@i®Œ!ðÏ‘%Ϋ½ûdf8»?´§ª êŽ9àEÐ,Þdm©fROc5ç»FA ºÆá¥3#…@3>| pF’eÉûFÖAc9ð»àÁk–ì<ç­0õâ ¶Ýéß e³oÑÐÞ/DØËQÑø@ÓÇ@Æ­Æ7¦QAUõ¾¡`ÔP7«J²ã³|B5\.ÄZÃÞž„µtöPÅQóPÅ8Äì­[ó{ GŠV³2Ž£ö¶2@€‘,cÀeCd‘·˜«ÞtçÊF4.©°„C Í7¶SWáIÄço-,Ò¬b;Ä禮l¬TL8‹˜@›i`.¿)º£W™X>Ûþw!#zžqsÔ9@åO¼‡³Â¨÷ïmFÇ1.5z‰œŽÃÙ¿ ŸL‘“kœýA›×!|¢öýÁ:â÷ h>bï¿á”tîî?ÿhÞ›››ëoo†®Ì‡kÆh/:¿_\šöB aâ%ÉXnAkœÁ©ˆxEw§Ž/‰H©x'uë¶°D°þL(bš:cÞuZ¡N‘éÚn`°9t¨6 –Qqˆ|™ºX$“Féбl|Ÿs6N˜¼z‚ÚÁ`¡’ׂ™?bÅJÈ ÕÛ3v@59þFç¶`¡.ÃÒKwȘIÕ¶÷´È“¯›£é39I \„b8\Â@K”¥,Êš•>¯µ¦4b#Vºµ=•î‘CÄ"£óêór5©\ è"àN!éSÒÀ²í(î¤ìîÐŽi½üƒÙ¬Ò5PÎÒ5°BcëºÃf¢™„‰=Ûp0·áÔKÔK;ó aÓ_°[_šB˜ º=ñìÍO/Jpm~ò}X3†ü§ªç€ŸÃ š‡säÌn(V¯cZxã3½݀ŽZšQ”=¿_ 'r&AÕꀫÕÐ7õK‰Hé’w„ð£ÑSoÀJ¾¾ÿðòúý‡÷”œÚæÂaú´k.*E‚£ÆÑ¾=ò`¥$¬M–×hkŸkQ¡™ð/„…_ >ú‚Jy"x÷êúãâlÎp#Ñ ©°k›zü}ƒ^l ¨úeÀYÿr*Píÿp|ñ·n,úJC©ÂØEÊ}yÈŽ 6\Á°C0H¥ðÞ›\èÆuµ™Ç+ÿÄ»’û¿¥Â·– endstream endobj 2125 0 obj << /Length 2073 /Filter /FlateDecode >> stream xÚ½Ûr¤6öÝ_ÁÛÒU†HÈ>ÍÎ:³Iª²É¸65“J©iM™ô¸ü÷{¤sjšq’½=¸%ޤs¿IfÁCÀ‚w7ŒÆ_oYyä ‹3.ƒêtóágþmÀâ²”Á³Ýu „,`l‚û›oþº¿ùó×" ʸ”© öŸQ&qÁ’@–iœ°,؃áÛ]”…óÃþîýîçý·öH"b.djÎD “¢¢”Çe’à™ûoþ¹¿»ûÞ쿹Û_r)³<ιø£\z$y™ÅL›@Z A %,|û~dzð§ößüi^„{€ÈÝ=2Ï OÞˆÓSdx*×w»”…z8è¡át.ÂJµ89' ‡Ï»4 Õ¤XXëé¡Ý':V÷z ÍCGû¦Çá:û¡›t5™,<ªIÅ»ˆ³<|ƒË Y)$÷¤HKsÐ Cöu[ /ý´1Õñ=½ôzC~™ÇRæîàG–1ÕŒÄÓSÛ]>E,ƒ&®9ÈÁ|Lz |Oã\øô³)ˆ„±,Rð¥$.3ò»(¦inTm†±×Uý‘qQáwÕu«PF0Z÷ö;å§©\)ןaJAÝNúÁº‘ÛûB6ŽÓ™LgÔô¹>j:‡·êZÃïQ·S­š[{ü2=£v©K)cä&¢\ð³8½²8c0p$`á øþÝU ^ÄeŠ'—ˆÿ0àC”1Þ¡éGŒ½ºÅq0Dÿj~ÏzœÆ Z+ÎRà,#ÖÞ65¨ÏàixRO6ðkz6Š7ÊIè¨ÜúŒPÝÅd‡Ã8ùw{½¿ûÑúžîå#á†_áìͽÙ:â>4@÷ïlâ”'áÏ%aeÙÅ=+ÆZDöš‘»Ã¤¬Ú`^·µqü˜êÊÈŽ °ÂÐ’וj“‰^¬pØ›½Ç¢wƒgl¾´aA»g {£#ówK˜­`BÂƬpê„ òŒýüs]éM¡âY3y\rŽšÙ;ü`“kÚƒ¦Õ£É \¨þÌ!ÝqZÕЉçGí´;ŽçYj‹ŸKIh Zø«• C]\ÂI€O£äÇÓ„½æöE,dé#ŠÌÓ°éÚ‡h"µæË€ý;/ƒ‰¯gðbžŠe •Ègï„óӣʹC‡£© ÃK?­p«j:[—\Ñ!Tú3ÁinE»kgoõ8A*±a’è€AŒ6¸RËÊÜ=+ÿŽAW‹«|nÉÈŸv|vp'kòšþlAaß:~ÍôÚñÂÿ Óà¯z±´bíË`TÁœQ`/*öAt»Ó¬\XªŒÈ]‡: µBj—0¸a¥oTåöw­F`ÕõÞÞº±âY”´å*||¤3·P­é wç†Õg ¾ }ÏÔ”Šz…Æ!cÚpðÏ º'@sõÿ°žäMø‰|®1åÈtæ<+ˆkÀ€6•sxˆL')P² T»Gã–… ¯'º=:t!s$1µ™¨Í“ðkÞiêÖ"V­GS äìJ;jËWÑ*×Ñ*)‰Ig5éURöÔµÐÓ©Æ0Ô=míÁ‰Ïᢱ„8š5yŸL-æÅ@W¬‘CùÛÕ¦PF+嬹Î|·[zpi… Éx>,tW Ì9*ôB:ëüÒ%ïFõ•¿úµÒç’™;àøðûj 1ÓLmÖbr)× mç3ˆü¦Á„ãÁ¬ZÂd6¯v8‚FN5Áâhj·åF½t™§¢u<œ¡¤ðý\7 ZÈ£¢ªJ÷ÆËEÎ<'ò™Ã6íÖAº™™ ã*Û}TåVº|IŽ^BçëÜkV8=¯¯³æog”ë„î!5ÒrîIëc¦¾íÖ±>p_÷÷j6|-ânõ².ó~Ñ¿iuæît©Iÿ;—šûY ¸Ë<hóó‚€År¿q«)c–¦U¾p•;_×iWŠÂ÷›bmâ|¾kÛÕüçÕ9ÆŒ oœÃ¸8Z!c=m½,p–Ø«•·^ Px™#ðúŽ_@÷›rwÄ9‘ ¦|‘Êw.ÇEŽ¥/Š˜çÙʳüž/ßÌs¹ßÃ9‚0ñ»¿Üëþ¤éþàn/’åÿ ßåÚ[PénAÞ&JgÀÉŸvbæd• 5òd÷:•šò–‰ðÞÈ6¹Ö†.*9uµ úpÈ¢$NÇ\7BÑgÞ=§ ôP¡àtÒÇËçŒñÜ÷ÝÒO™mz6#ˆõèñ¤ªh|TITÊ¿˜–Ý)ý‡,‡ò•¸œ;Úò4ý2Ú7àÁ¨ç•Ò$’8­ÛÿØ$æ‚ñd_7ÕñT¿Zybª6¹¸‚õ¤êf¼ìÖÿPÈ”í|ýÿ^¿ó¿™yp„Ò,RˆqªÐe¶&ù/x¢l~ endstream endobj 2132 0 obj << /Length 2502 /Filter /FlateDecode >> stream xÚíZOܶ¿ï§ðѼQ,ÉÑSš&AÛS“-zHƒ@c{vŒõØSÛÓÅ~ûGŠ’-{¼“ͦïð€^Ö2MIÉEr6ðî¼À{óãíÍ«w!÷2–Å"ön÷^"¼$LY˜Iï¶ð>ù¿nDä—Ý®ìÚ~³Iê¿ÞðÈ/ŽUSõC·ÙF¾ª¶¡oïÏUQþ‡ÆʺT}I/œ Áøæóí/7oooþºá°}àqÚ.dIxùñæÓçÀ+€þ‹0™¥Þƒæ:zaœÂ³ö>ÞüvÑÇ'ã yÀD,qV̽>\?L‡å!“a,ìiƒ„…aB§å1“ZÈ—ïâ}ÚFAà¿9´m_5wtü²É‡ÇSi4¸ßðÀo;zQôèK|ü¿«¼œIðêLûÞV¤,‹ ü¾lÊNÕ5ZéqG>*_½*˜i¶*Qí¹.h|P ß6,L3í~sJüøH„vOÏá c¿G'ºˆþA¯ÄcÎj'(CÞµÃF•¡¨¦˜­ù¿þôÆHy>´‚à#Ûl¥àþÏKF檧'õÜ4¨vP!êŠsÐUDºR¸PâwÖ/ñ¥Tžµ®PQH¥þ}·‹¶œq*Ñb#n‡OU÷-qžûr®Íü–ž¤4Î`¶¢uáY"F™3eãrûMHîAæ¨Ûƒy³º5¢vdHs{ãb9l»¢‹…‚£(ôoiIŠ•"ôªº&RÛÓô3i/´ûJÿÏ@†uü²8”ô«f1¥®\~t0|ÖàQÛÁœâHœîZ DOœŽ–$ê…¦<ž ºÙVK­À§*ÇEiåAXø»ó0M\óÇp" .dEÚ¥¬H­š¢Êµ#ày0 z6 ¡94j\Þ’‘☰g£À ˤ‰Ý¯QU2õ›v( f¾ÚµwÂ<ž; –•YŠÔ¬çOˆ‘ XÄ%ìÌ'5\‡¥ò¶A¹;wæ®@¦¾p³žXŒ3˜!°Ô–©ïÍŒl¦ÜûLGë«.ss1‘ÊS šÁz²¶ÀþBÍÃüËó¼b4 Q08(ÃDºn;´¾^Œ/ê)SŸˆP5yuR5›ßPϾ™–—¨OÂU"Æ«/ü‡®¾ÑÚ‹ìào<¼ê*µ«ÁÓŸÉÝZ}’¶êZûðƒ ó¯ÞÅîÜ’—Ó =õS]íŠr¯ÎõÐ&îÙNIÀÂ4²Ü“K’ÏŒL)2 =äŽéüK¢Vp;k‡’ñ$µk#nøöþÚÁCH’¤°S(þjÏ…JðgãMtþµÈ¡!ˆº5Ú¾lØbC°Ø´!\œ!1ž…*U?|yÐBÝɻǦ-p¿]‘_„,ƒTnKP?¢D›pq³ÆR[1 B{ršQ÷åŠÉ ‘ âQ­kÁ ¶0Á F&^¥pËÅ2ñÿ8”ÍÊî$ŸüàÚö”&Ù^—Œ–r)ÓÓq×|[¯ ªcU«ÎÂD»àaÌ7± |v߃ãg¾$xJ!¹‰£[z!hÎÆðÍA‚ŸÖ3–,IÄ‹@‚ÖwA¢71Fæ3#[kQ¶.Ÿ vÄ‹@"¤í4À6”Æ;Î%$Z-ë$f àÁÄýŒ%|Õå{Î!FlGˆ±ºƒ3a ¸Š•°bº=À5bḚ¢Ze@Õ(ÆãÀÌ +ÂÅ .ý„€©ã2@«Œ`$.~b×5þײ§gaƈh´Ò/ºTäuNW̹M–WøtÎ(FŽòˆ0]¸z¦õESÎTnm6qîŠ Nu†£4v$,ÿ¬Ò6l-àQHš.è•¡md íÔµwg:öD²¥}¤³œ~¤Úå´¶ÃŒË 2!Óp°ÊÂQu×´¡®4…$YŸMÛl—~‰ô™7-ø—œ—‚'äËÜé‚ ‘3žjl…[<±å#±S{É* ƒŽ¿<µ®”¸Q•ÖŠ+itJ–­&Ò×suÈ7£x,­Ö“t€‰[$¼8K¿†Ò0ŽXdó›íÚA¾å‚sÀ˜Ž(æƒ^hô‰‹ÞÀ6U¡¸Ÿ–˜;(Ròº¢TÆuµë”QlmºâfΞztT÷ä%5…ñùúãöÃÛß½`‘ƒOºdÝ*[sXãyPOÚ*ÇW“xî÷§2¯°?“ÓûZRÏI½&¨âðO-„¥ÌbT}SÕ¡þÕ×ý¹4¢Lí5+èÜDŸ—T [>S Ã’ûµƒëò™V¶ºÄ2¦ ý›AQ÷}ÞÉkt´xpûpãï«]Xc1·ŠrŒ]]TOç“|]}{Šw t/·^Ì—@àÆJŸ@¦%–@àøø*øîë»·ï' pnÀÿÂÿ)Ö=þJ_—ÚÞ%åœ]©êãØŸÆïßÛ åJñb¼/ò¯ögeÂâé¶]Ù~¡ç·¿1»ý–߮ǞÄLÈÅ-J?½(Ù½2ŠMvƒYØ@5&` s-xš ·½ªóãd”ø'UuãZjø>C ž±`j"ÞkïRø?ÅUkyù¢›ŽQûÓoˆðâZÚÈñåÏ‘@[Z [*©ôËJ'ÁäìQ¢(+¸ƒÌ«=Î~}²ÝƒÅ'Õ÷ºåÞvÅÜ‚Ëÿšˆ°mÿìšXý?ü±›b)‹±I‡±ÿæ Nü]ÖDüç›çaæ¿¥2 YÆv.Äý/¦Ü> endstream endobj 2145 0 obj << /Length 3438 /Filter /FlateDecode >> stream xÚ­[[“â6~ï_Á#T j]}ÙÚ$5›Ì¤6³yØ™Îæ!IMãn\ ˜Ø&½ýï÷]ŒdLf_°,ËGçò‹$C'O:ùñîw÷%›¤$x4yxœ–$N'±LˆLÅäa9ùmúiÆÕ´¨E]5³9“éûSÓå¦Ü–M[Ïæjšµeµ5Ï~Ü—Ëâi.ÖEÖæ†Î ›ýñðÓ݇‡»?ïð@'ls˜N’˜Æ“|s÷Ût²„þŸ&”ˆ4™¼èQ›‰Œ¸®'_îþ}G-ÿÝ•0`Ÿ |+b“u~>HÌ$2â(2NOc"el¤eQšÉñ³L~›+J§¶yûº³ÒçÕµM-ÊuÙ¾s܉g:™ó„¤Š–¾…M8MpšX¯L"ÃA¿ó3Ò‹"È”Ä1Õä€/0š Ó×ÚÑšNÑ)rÛ¼ÅWMÁÇ™¤Óª6ïfËe‰”²µ¹/·‡ÇtºÉ³d‹jßšfa4ÔcT°(&ˆE âHö¡§q G$RâJ@ÅÀåÇ!’*Ò ’øÀ½ÎI’Ä“º˜<ú{ƒ–BZRÊ…£ÅÐldÆÀzªOL£O¤¾abs3 “ÀŽV«Uе¸?}  žF„'¬ÏRDPq1‚r"T0ð2c`šìù»s,ňHTŸ cùå: ¼|Ñgá¹^¨³³§œPÆÀ‰dW( M åÿµÜ.+ÔÁËLM›slt¨’4ŸôQÅHÂŽØ~›ª´séEÀc˜§\ó—A’¤<èå ÌOÓÒ0\Ó(¾æÉ̃«4j^Í<_äó¼Î­Ž}†±²qÖ“!¬û\¼Ì„û9:¬‡,\€õdë> g„%gçwhï©à<Ú“´ûÓû §”ºù32sÈ% ø¸ ,%Qš†HØ,å96:$„lŒE‚ÏE §Xè²0 > NÎïÐSÁ8$øÓw„¨$Lݠèƒ@]B6Æ‚Àçâêp²0> ×…ƒž ÆÀŸþºp €No*U$N’ BC¡YeìÒ€Ðcd$z|ìê"ÏÚbyiHè11 ß~û4$ô•0 ÁôÛj[\TkÝŒ…DDX4funÖûz&Õt¾ÚdW =~ÆBÂgççD‰±ð™@HˆKD_ ã NU€ˆÂSv3(b(¤ãä4(æÅL¨éwÇ‹¯±àðÙº¶€è±0> 4ÎF‹ž ÆA#œÞ‡ÆÙxëp!nʬs 4ŠèÌó¶1¨À2O£‹CFÈÒ›¨8µfêÌÒk^_ºë<¿'Ë8ó†ÓÿgÆé´lô¶Qvqr{1ô%¹ŠNÚù¬÷‡,³³GnÀÎ!­±vö¥»Î{²Œ³s8ý Ïú³€©ùíþ,"-×)F»CßÅ.ru›K‡´ÆšÚP×wêbŸî 3ÎÖþü~wÖ‘9%2¾Ý‘¹$TÅ'Y$rÎR~±/‡\ÝæË!­±ö |Ö™{ÂŒ3°?ÿUäç6ß i5­/š6½Øu{²Œ³¬?ý5®+A£êöÐL)aî ÌÖ¹¯oØs>²s“ˆ¤ÆšÕ,0ë9‡íI2Ϊþì—Z5ÒV•$‘j䙾ǞW­‹ƒ b`_$ÞÉÍœÃZ¬6‡¿xd,¢©ÞÔÒýÙviºÖ°Ž®Mß²2]Ûª5Í~·3G‹Ó֯ŃYk[»ðˆgãÙ~ÝSBˆéÏe^WMõh8Å J'ÕÛ˜Ëo ‹í‘©–Nh$›@ï`ÕÜYÌk>ËN$¨ýÜêÞj• ŸE*Ñ~±é7Ì@Ã1O§BeO¦ÛÛ#Ñ÷…>næxÜláÇ<ÿ*Znóõ~ B K÷#a<§Âãõ»ƒ}@RB9s£‘Ùc’ PMcêü±Ú×ÝÞRÿЛ“8’n0pË ß¥åÓßkEÎ¥èÉ4„ȺzB9iõ–p3ütÂtVûv·GðHšÕ=t×݇‰V}jZeÓìµÚ€Jfº4Z2£à-*P÷.÷¦§ë(·e[ê³y|uÈß¶eîNåqÀ〞D‘TÊ+TÁ׎.­Üû¦X§¡˜ÄPÝúˆG­ûv_C®ñR®×!àÌ ä8»!‡}Â9zŽW`ÿ_3Ú}<Áý«cx£×<¶Æ/è ¾–(󸶤ÿùÊœ%ŒD"æ"ÁêÃ}Ãý¾aù¹|røh(Å Oé“ñ ƒÖ«é{¬ñólUë¥ Ð´Ž¯ð;“î3è?û™Iïó—÷h!óµ‘^ÖY‹z amCPg=‹€a›ÌÇ- s­‹?5ÚÊ£k+ódS‚xðˆÛ±™PÙzãzµçÑ6²ãÐuñ„ëæ,·OŽ"vjéßa¶`Ó¢Ùyy@“éÑ2¶*†RŽcG:Ns“Ãrñfßhk ÉlLÁÎ.¦à 8ŒihMJÜ·¬‘÷u ú€BDŠ Æ=¬ÊÆÐñôcDwšUµ_Û)–ðÎÚ#øú§èÙn;x¿sD—–aj âP€1tÝ.D¬Ê±HŒÎáFø¨oM›S{yÌ}25˜Hÿ vdiŒvDq±‰ºd)z‰aÂüT$]ì4¬=¿v™ü8Ž%àå2é^)Zã£z¦ímŒA,áªKÏËœäÕöñ-Ÿ…È«÷ªÇ o$ßá7Ù3ªÕö7{§œv•µ–ùÖŒ\VEcztYhäÂ:Á¾Ñí·ë;4›~+8¢HBc’Ð^V~Ë–ºŽ3ÀP±mº$e¸ÅTë:*`é%…ÎñÆJ¬cÆ¡¸ÓE/R¨,©}ÓQ¯\ó4§××v߯Š9yÆ8Ì\„é%SÉaiؼ°}jï?xÿ¯Ÿ‡j#¥Y‡“+:òr§k ˜Ä†"S7ßxTƱÞq¬éÐaj©˜c nÒ›yéÉX^lw50:  qb_ȫͪ„Eª´S£TQimSRcº3s9ït<‰iXCß²­°NY¢Õ~EŠõHãb; ð–µááj‘š¾sõ†¹nöþØ…%âç¾¥ƒ¢1›?×®®òbÙ¹À­1†+´L§èïWÙöé0)šÈMl@hÛÅ›_ÎÂjœò®`µe§ ¬¯Ó“ÎÀ°(vF¨:8ƒÛ=„(@^‡*KIÒ4vþ¸Ÿ¬pZ—B±½ÒU…ËPØSm]H1wº;l¬Ÿ@Ýc¡4‹ænAS“€à¡§pÝëššé N_¼øÛøñÓÒ€)ƒ “ªc”öàæ¤óÁæå|6“v×k³ü=HînKS–~¿  vKWÝö‡I€Ù¾Ê~3} BÙܧ°úa'crd&¢i…uƒéëÖ‹Ðbªùð½˜XàFúƒýÝ‹ lìýk»ÌÚ&Â}—CºÉî!é@±Í6ÅàÌŽ]¡åÊíŠÍœÌÛHÙå×¢éÂJŸ0¦Ïl{6/e»¨¤XBIÄ;§õ”hÿºËšF'k°'þ‰Áš× gãyNŒþ(XM%i·ºµü}u†º‰ñÓòtÖeQGüÓýP²e‰¿³qìó<1ù &ÑjÞÛ]1½šÁ‹—šàN§&¸©I ,\4ãÖ¿ElÉ˃ ³ÄÒSö †üÛjB7üÄ‚ÌßèãsüË@¯à;ãè›Ì9:®-.sq(x빸í ìÿKƒÇa£q‹Ö2Ç•ð.æ–qÐ ––p¼´„N["=í?ا×eú…ý¦° ïµó˜·n-Ë„’°Zˆ«……úºoËõ[U™ÄýÄníÒšRn±ÜoÐ;Øçøo¸V^u‘B†öîʶ2øK¨}:¤}êT…Õ+“°ËjZ™¹x©¹Í¦¯®Z·h†;wÕèÇFsÄŽ ¾¸KÀƒõí _YÒî ]9¶pì47Y·ÌŸUcá_çL,Ì_ÉÃðPÙ-¢ã}[Ñ‹€ÔÛç[Wëå)žEÓ^+»xxïân3`¨«öO+ÓnËMaZÝF€âç/»OƒmTGyÚÆvVþ+»²¶ôEk"o±µWöI˜³MŸŸ©âþ¡ƒÛloì ³!3¼aB—r ÉJeÑ«²âr¾È¹¡`áŠ<ëä tÌ—òh]Ž¶Ù¨îMaÉ¢³%ö°²4íF—¦p¼ùç±!qëÃM5P~ô&Ö›¹Ö:Þ¿Ò–zßo`és[¹)ñdO^»dî‰~S-ËÇׯz¹j×ÕX±ì^Lx¡(ú?[CE‡j(Š{Î`Å«‚m¯Ü-2m]v¤·¾Á|úéÄœ]üÎã¢â¹"×ÿoèþ•‰,Ós«Äô¼¦qŸ½ÿz¸› endstream endobj 2150 0 obj << /Length 612 /Filter /FlateDecode >> stream xÚTÁnÛ0 ½û+t”Z•,Y¶]›kwY›Šbpb5êØ™­´Ëß2å írvERäã#)NÖ„“ÛèË"ºœ+AJVêT“Å ÉS’«‚©R’EMžè}œfÔôKÓwCœ¤yA¯b‘Ñzk[;¸>N2Z9Ûµh»ÝÛÚ\ ü`S /‚¥)ñóâ.š-¢_‘€ôœL§XÎs²ÚFOϜԠ¿#œÉ² ï£×–(]ÀÙÇè{ÄO¡ËâtÁ—9Bÿú¹yJ+Ú˜uœrZ­¨6íª÷=ìBàä;ƒæM5 Ðvm‡XµKc“ÚÕ²1uÐÇ"¢\›Ï^µoBÛ¢ÁmB’·1d?ówók¿ÌPƒ÷mkÛ5ÚºQ½¿¹¾@• ‰VU;Á PìxöºDVfr4!×9­°§¾»®‡ž"¶ÆWàëÑš¾[·A_Ÿ¢]ε> stream xÚíYësܶÿ®¿‚ßÊ›ñ1Að‘™~pYQì8ŠtnÚQ=ŠäéXóÈ3Rôßw ðu´Y™Œ§S}€°»XìãG³î,fŸ0Ý~<áÐ2‹[kœ9RøV²?¹yϬè?X̉"ßzP«ö–ç‡ÐÖõÉÏ'Ûœ|óÊãVäD¾ë[›­åEÜ ·üÈu8“Ö&µnìÓÕZÚß¿¼Üœ]­Þo~P[¸çÏwqÏZ„ŽÖ®p"ÎiÏõÙßÏÞnÎÎÞ⎓³ÍTO_N ¼§ê9*¸tŽG"¿ßl.¯Wk7íË«•´Z iÿãŸD9EÂÛWçï®^®Bfo.~zK‡áèük׊ï5 5狘¸¾§iÞæ•µµ·Y^ÞaWÚñm‘M'»FÞ}wIª¦vsz9^*í¤Úï»2OâVoIó:KÚbsDyÈÛV…š×ßêqCLòFKéÚ"/³”F¹VùêÕ©Ç]öF‚Ûq™ŽØ‚1ÀàkÎHê‹ÿpˆ›æÝd¨8³ïó$kˆ¤Ø¤ ®È÷y×4Ø¢Úq³s¡¸Ð³Û]FSI‘geK[‹ü¶Ž‰qnØ&qI¸m³ý¡¥2´dQ”ªWõ÷؇ºÂKÿíq¦2³zÊglî…³kSK¦N ™:ꡬƒ±u^©kÈ/ KG‡(ØVIUhNÃ%ÁHYÚ›¯×¯AÚå{§W,p"!t4özkö¼×•Ïtå ¸®º;3YRk ݱÁð¨E¡Æxy -¡ÛÒe<$Ve'íììdf½ôa—iyeÖ>àTU ¿˜ðêl% ©zÏ>¿ÛµK·QIÈCŽ÷/<tÏp7IEB"¬ÛSo[WªÇí´R–BbS9«µÏ"{³Ó\:bÇíjK„Í›kêÄESQ/+þx@CÐd¡Ö1ÇOˆÉ­:*³3<»Ö‡:½ÕnŒ¼É4ÜØ‹¥ƒÏIW »º]°:ÐéÔnèâ¥]2ìPÞJ×%ÍÌf:ü‰1'+hˆr÷ç‰ìž;yxèÁ¼J-é8Q!öe’ÀÖK§7©]³`Œ×TGX¬ÐäåXÇ„ö¡kã)©Yqië äÆÌ¾­L¼œi½<{1 _ª<$‡<äMó\ÊC:SC«×Þç©J°;Ö315[µ+n»:£ù\ lª}F=£¸¡5èÍ8ócžÔUSm[þ‚FÈËtå0q=SÑc¶JÛÆƒ:¿àÜõù…>ÅþPd륻ۃ=c]-Á”e¼‡ó©Šëû£ŠpGD.l¦Š“&à V…Qö;.Ñ€6¤Ï͆Ü\®¿WÙj•áQN0®{lwF­ƒvöø÷ö»ÒLÝŸºïj1‡ƒ Ìq}ÿ(QÃÄñêü­¬9ƒH¡°œV©>ħüŸ,ǺYKÆ $”˜RﺚÂðŽ.¶aïØcA3‹ÂŹ –ÔzmV”¦ÕšGŒ²##U; Iƒ“ûR9 sÑGp•I¸l×GÎì»~s-9]7^¡4ÇÎ)ÞÈKZø°Ë\³£©¼i:ŒÅcë½BYyʱqúúúÖIy8ˆÉÑV˜F .ì‹íœ‘–ÌA`Ïj‘Ã’ß+„K)+Œ9ÆÉ™ñA 4xxæl¿~€È§iF¨©+ôÖ&kiF…3ò˜L% Xv¬Xƒ÷Á1íÏвµ ² „qeê=ù ë¬0A»¤zŸÝØ_,D”6“r2Çe!ºhàÁ/ôÉ{çD%“Là õ© ¾•è¿ýœë®Í¦Éà‘?™âø‰©=ú¿\é0tÀwŒÎ7µ*þq±oÞNm8<Í®¦ƒ‚ªJñ·ZîJ/²æ­ÎKS |c™/,>ȸ°ØFz.~eY-ú¾r}ѲÙ0Ù[‚>¼áH)¹€‘t\Îñ[Ì |=)Ûîˆ ¬d<- ‚?µ½'Ž'ý 8òP/$ö¤XöƒÂì)l`Çq ¬fýzj˜:Yò?¾­õ³ÎIt:lÎ{'ŽBýÿ©îà:(ïjsyއs•½¤žéíed¯~ZjCë¡ïø¾î^<‰Ygl<„Þ†ù½¦ø’8:ªÆº5¦\û‘Ã8´^‘zÃPïþ8À°Žä>…ø®m¿Æe²«j“%=´¹ù§TšPtu‡¬þ×I&ÑÄWoξ}'û›;k“gíÇüü,I u«} gÎâ{ÇñŒçD,ÐøsrúïȈ Èÿµ;„¦š\Q»Ûn„fu¤VS ò„‘©9Hœ •ˆ>–󲡅±!³IZ„ ѧ@Œ¯¾gÁµ€ò$üÀã…(<Ulì'=‡û}M«  ÒY{ž«ÞÖ´J:ýæ=c_Õºän»¢Å¢’ü¬šËY?'ˆÈñ½þ+ƒ>ãÖêBÒ˜=¯ŒSd¾l¡Óc$VÔÆI’5Íl!½¾Dæû:ÃSQ$&OED¹Õž fY’o ×¼¦nQ% ›iy Ù`Û>x‰Ð‡D&ŸdPtßìèñÖH«–ZäH&§>Cè“ì°×a[jû×)f¿»z£}kX?{M¿^Í>³ÿX0åÂ18Vž?L¹ÁØ]f`C°#°Ñ“°œöƒ¾¨ö6°cƒ¸? L}­çûZÁ”LÀ`˜l$F0m±]Ð ¡SÀïkS^ÂìShÊõB‡y^ÿJô‡€(¬‡Í3PÔ—"HT÷«žƒ|¶ÓòYèëuš\Ö½°}âwŸ_Ÿ¬çÿMýßLýy¨ªž¢†7°Éï3HW€éýëañÎ Р-õj5šT¿Ò »¹ú Øê'®¦€+LJh”c•ÝPPþÓ¾’—y»p2×w¸ì׋FâXM?Ü—ÕȤ.¸Ð#c™.éKƒjĵü~ÜslvUW¤ÚŽø“{Û•É€yE™0ô$BJƒ]bƒl9óœùoÞ6Íì'o´äïûi^âç¦ë"òâ\?ÕFÑ\äUgŒØ endstream endobj 2070 0 obj << /Type /ObjStm /N 100 /First 963 /Length 2165 /Filter /FlateDecode >> stream xÚÍZ[oÇ~篘Ç6Ã9·™9€ ‰á¶@ ±Ú~P"1H†$é¿ïw†ZÅ)’"×B[<»;—3çòË.—Ê©$.U)¡‰›Ñ“’&üš%SNêp!¢IªjAPj1¯4K^taZ“ã‰YIÞ¿š¨ð˜SA­Çr"*1½co–ؼµDâãÆÙú^OTk Êõ <-‰|°ÛÇŸ8AÇ4&ÇfD·À.{ ÷´Ä±¬Œ{øcÚãþÔL9–kµc‹8ªö\’s5 µ1Î’H¬G…’¨¶ JÃY "•ÊcXU)Ö$-v,ʧ€D’Æ¡@yR& J’ ÄJ“j÷ Êc…å™s[œ 2„^â@Ú*!vHË Á…µ’ ¢M¦BìD”Œã\Dz¤1ãU bbL0èÈ u«xh¡¾ ý4bç6HК`uˆÃZ †ü¬¯WŠ¡ÂùÍ[œ×!bbNK„kªà–Bk'€1á6¬ê òãÕ$–…!TÜŒ‰Öú`³Ç²žZ©ñfÙ8V‚,C·K7R”’špÌTMMJ&UyÌÄ„6Ø…šÓ Zêe¨>Щ‡ø`ýn•’ºÖxŠõ:D éX:¨šzouQqˆîKçÝ-Öиåc¼'§¡Y£äa½¸×A…ù’µä2„iœÜÂ@áÉ«ÆþXÊ[—Å‹‹åÛÿ~Z¥åw——W·‹å›Ï?ݎ뿼üÏbùýÕõÏ«ëwn^Þ/ÿºüÛò‡w4.ËWnÓ;¶š©Ã©ç^ê’%,ÒscưïÒ‹iù&-ÿrõö*-_¦?Ý|þés?^]fΔùÏéÛoø73=k¸¡I†ö“°f /­šA»¹™X)Yæã¶†RGEKÉ-àFs«u'#~½øt»º†4¿dã%NUà“%ý˜–ÿü׿Sà¥5,Êéòóo¿½| ‡=¤3œasà««ËÛÁá+(œD×S^Á˜aø|w…•p%ÓÕxv·ø«kiëgXtùúúêÛD“–¯_¾JË·«ßoÓûMi¿¾øeµXþ€½W—·7ÚcßêÍÕçë«›5ö{ÿXýüñâû«ßÓÐC¨5¿¾¸Æìˆ5¾8txƒG° ~ÞÏ£äF¹”ÀMÎ>\Åo€fv{ÔòïÿX–¦ïvXÓÓôƒA€ô\Q Ùj²Sîp´SlgÃZ"…À®;íjKê;,©ŸcImð3’5ÑúDøô¨LĬfg…²†¡t3-Ù=", WÛ~pÑù0n2l¯) f¡`‹øÙØ V_~ωÌÝãƒf >ÈG–¦µÃ³áDê™#n…B;ùøtq}ñËõŧ_¿É<£HD! ÷ôŒ, ²Ç\ ! U;ÈŠÍ(•ŽÓ‡VÔ`¤=òÝÜ#·FÞàDÂ/XѶ‘ýXˆì òü÷%jŽL¾™ÚÓiãØý°|výä#øŽ#x;\î€Óy"d"t"lMD5#¸2·î£âÉQ!_ÏÈiQ÷„wïO!uÎ\ö]Qkd”°³ŠŒÄ¨ÒšìEµ:#¸ @•9 ¤Hc;0U£€Îξ[çL§ErôP¸ä(”¨÷làªZ.JûÙhó±ð’£8G ÔûÈ‹ 0£ºÚkˆJ3"¼M#ãD}G}š‘D'$ãÿ“ø˜áýHLÝ8¦næ~›Mµ³à‰JÛ‚§è†œOu‚žŸ™•Öê®áuX€Š !¢Ëä9ù¡Ì·hÊ ér¤µ“€„õ½†'sâÒ@ÂÿyíÞ \á—íùØ@j×$*µ}±µ?jª¨Ÿ`aÏ–zRMÿƒ eÇñÁÑ ú'f›»åöûý H8ÙÑI¶è8G'²‡ŽíÑX* D-†ÕˆŒŽÙhœz‰ÚÓꃡ'âãP{sà#Í‚‡ƒ"ªHâ„¶‘è×ìœn¾Ã ÚQ¿FÿH[IPò1Ä6?¦uJÛ&Ñ5‰~ŒIlª‘ S=

£*Í3Cx¥–œ.¾.LÜçGUòOuš¨çf|¦ö**•ya„s–Ÿ7¿œ¬7'¿Ÿ0ÀCæø¶v‰O}'>œ|üLè¿8”ˆ0p®õ¬ƒãÊž{çüä·je¡„”p)p¶dN&ij9©qWF ¾øKqám‹d[F»%d ¯Ìã×"Uiõðæì‡Õ9Jþòtm(ø].WŒ.Ñòµ[ œˆÆwá¿HtL /N¥ì¡¤ÎŠ» „שŠ'/¶qž¨Á~/NA¬žŒÀœ‚.&êU°•×›,9ñ`'¢5¬¿ºF5Ø:γJË·jZýu. X‹©¥ðߪçOÃ#ˆ¢ÑÅÕC¡ù>qYÛ…-¼÷(.‘Uõ4´~H\ˆ6‰ªè.t®^í’givQ³BÂ@æc$ô¼ïGS—ªÀ%Û¼~êAJJ‚‘jŠ¥ß;{qù‚H¶¸ZP3ár„aÏ#ؼsß󮢯S! Þ‚D+ΈïÙx{ŒŠè0`ïÀçùCÕL³Ï­U:³Ð‡NDIè·ÐWfÉÛô¢ˆ0JÓÅMŸ‰6_+ÿ©å²b> …#è9Àm0|Œ`¼Äµ*«º|r?Ëë0ÚÚg J¿C0eì‘€¶š²ÁÝÓÁ}F­Œ§5=÷¹I¢ÊÍó¾á–*™†QF‚`, ˜¡Ý£X§Î+= ñÐU ~….Рǻ"?Ì@˜æ?N~1'ÿŒŒ 7¥•‘Od|€à 9ðLï dMý˜,Á¹Äâü¨âtgéï>¼}kMdgžY^ÙR‰9žû.„C .;8¶sˆÂÕWígY+·ŸŽ8¡cßúĽ+vA}&[o¢Fˆó:ÆÚäßæ-·2~–Ö ­ÒÞ —v‡/ø\yÑ8`¢JÜßYI¸ž;D·¹JíÂ]Åßj#³_¢C!KöT³éõ++bú‰ ·Ù9­šDSŒÙYÕÍRz »>ʬ;˜$“õIë=À)·òôóÚuØ•UÚU…Yw‹{X µnCŒŠ]¨>9ˆ:p×»™ q"÷zuÇlÑ2³§lA^E x@ð`‹Br¶†”$…®nñ¥TXȈ X€%M¾30«ýÞ/ìçZGü†á)ƒ3B?D¢eÇ`‡,Á“­Ó̲i66¦"ZS1f6ÕˆœØø¿„£žU"VàÊïQb8R"3J¤‹}G{K™ÓaFe(Ö˜ÕkµF­ÖØ=Z+T¬ÒvÊdË‘îØŒî ƒÂzPOLRX$5#Lf Æ¢4³Þ’gæÊƒ7•~°€3€XÜ ôazÛ—KÀúaóóöGÔþûw›õ7ÛWï·çëß>¬ßá9ü¸6ÓÁµ=¼SáÃŽà!êÕ²9·„TÑ9ÙCØ…a»OÍëa.ÕïȤVYl)Y}¸Ðã|g`õE\] ¸éòP uÝœp0Ò+tp…gŒh¯TŒáú‹ŽÙ‰ù€³ÁeÒæ~¡‰æœ`Ðx4އ¸‘ÒàÆ±Žš{Ë4Ÿó·Éùcu)ˆï†]”[ .Þa&;з5Z„+›ðG—&µY=éV„¸iwãònܼþÏÚÌoL—èÝ€¦MOfM’¹ÇüÇë+씌ª1þ’™,lÀŸ‚­è#ÇE_4odM=àÓ|™åò@W„CåêXĸ‰Rð¼N«+ZXZ€x´ìiUé ´b¡1XýZÃÅ´xm(ÚYú\âÚVp 0”=û&KkZ3} tP†³î‚&™]­à0íeiEWQ6ÖÔSMÙ†¥~¢*[K,šŽÒ¥Q‹æSË­iÖ^?4›¾Òî ¥ôeÖ\±²ªÄ–Œ¾„༹š¬+èJõG)ׯuadŸ­ã™ç>ÏÌyýjºéáÞçõÜáÇ?øà"<îø¹÷tütox^.#Œ‡¸Î"¹®ÆÕ¿æ.œ°°­F7Wj6•˜bSßߣ8JhØUúZsY´]3*}­9`Œ6á.-ÐHÍ·hK׳nSgëS0Q¢q™Ì.àbÀFÙæn.Ä‹Ç×F½ÞQ›¨çÝ–p]N\ÊŸqYw!°¹è^ ¬¹<±AÌSoöM+,J¶Ç¨,¯QÞ¼H½â3øjF‘yLg꛸}ÑzÂ7yÔ|Ljë-Žuõ'5“åÖLn5²Mh!œµçÿ­[Ê£ž­yÕ>²qíÙŽëø˜©üùè£öR bà¤Ï UÕ& eÛãubÖY™^fMã&ÍìfÏÊôjÛ[2£rзnØþáMK °¹ÿoZuxÿƒÿG%怘ÆÕÈ).I‹þéë¬jÙâÁ›q—:Ñ?Òì²i“`Þ¢ó•!î~·ì¸ùpI¤÷[Ïh,¹ 1zf×'k*‹þŒ<Ûc˜¸iÞbÕXÖD Ꭶ_Ó,« mósmc ŽîÍ6ýZÛo¼ã>µZ^cµvˆŒS `Í7Z6n´¾ÏÚôÈtÀ¶þ{ˆ¾¥‡úÐñ·jÛM!7};Ë `ulî^ٙأ:˜ŒÂ5M°¿²…η0Gˆ°]J> stream xÚÍYÛrÛ6}÷WðQÊX(./íLgâÄusiãÚêt:IFCQ°Í1M²$Çýú.° EÐTš8IÓ‘Äe±»Ø=gQïÒ£ÞÉÁÑòໟ|æÅ$xà-/¼{¡?Þr㽞½˜s9SõZÕe3_ð0š=®ªùy¬ZÊÆusí8Õî¾*³âÒ:˜ˆ å*¾Þö‘ßúoî1P@l$%<šÕæÕ€ ÷ÏNÆU è )Yþ¾®×rÕ$yÛÞUjÕÎè¶jÚM€ c'“}e‚Æ´Ø“àCËÀ7-ɾqî0#zÍ@o{D„€ÑćRØ4n<»‡{`@ÓÀ&Uc Ô+]SŒJ(e§}æŒÒ;SN:õè÷)ô†J[ =Ô å¨i(ø‡ª+àvΞۭÖ6¾1[Y=ZouÌÁÞBÛ¦Š°Ùaº¥*¦ 1ñÃp`(›Þ¿y‚X1»€Êç°yHuÐP'7Žxr°ÐE×YñÖa­žÀ8)À£}QµÀñçÝx‡Õ°°²+J-Yº:[‘NÚ¿.·íÛ–Kce”NáH™£n¼£L­R•¡*#d˜R³Ã,±:¿œÔupµï=é†À½"rÇ.'5"85¡ïû…œ°©B. ˆÕ¤•:ôÝGÇ“Pó‘kR­qGéŸ5É÷UOÃóà„†£ᓎ7Ôº É,Ò;ÔmÖŸpz8Ü÷ç(úlrV/‹é«Jqù»j´®œ/$TTºÛ´ØWø¹kuW²v8â©+ÀÁý{°yÛôDƒ1®)¢Ri¡à›À††Á²¯˜Åsõ•xD~1Qõ;ëÙ»ÊxôZÕ] ®›ÚÃYM|EFüh7ß· kHªˆõ%=IiÄyßö0Ôôç‰ÏP/„£‡tÜùf¯nŒ„bçæöðótX°@(’.½]t̘]«©{x áýꑞȻ³H;±Ñ<$”Æ_œPy M ØÑ ·T?u\”ÀÕa> stream xÚíY[oÛ6~÷¯Ð£=Ô,ï’ö¶õ’­-Š-õžÚ"m:bK®$7Mýy(Y’å$n»†‘Ì˹Ÿm\48ý>=~.Y“XsÌV$á"B‹`¶ ÞŽ_N¸›bnмœLyÛn×é"©Ò<çfÂéøã„ÁÂu¾5ŸíÒ¥y„ïçfm’ÒàF8'lò~öbôl6ú0b` XrP-IHÃ`±½}Oƒ%Œ¿(qܸU›@êžëàÍèïõ¾Ð¶OZ´|Š5‰A^È(¡"D—Š £ccÿU»"svôÙ’"8¡aLYHbÁQÊ;Îhgïãç"jíê&ê(ÒV•ý`Ÿã"/ðó"_šÒÊ ¦Z©”׿Ó0»JýÆÕ.[øØÃ§ÒT~¼º2ø²4+›³d·®¼*Øp»õ³k‰òS«‰¤ãÚ„ÙÙ|)ÌÁ¥^Á&Yz»2Í.­­&Ý) ïªvz‘g•+ŠO.îÄG0¢ ã~m•ȃ¤qÉê%ÆŽ”ÒxH8”¬_J|bì_qàËùÙA¹i¥‰Œ¢~¹É{Êí°Ì¬,(]è 4൵5w%f~27&š5Õ±On> :I¨¦>à?§¶6îÉr7±ï¨¢«"ßÔÅ•½£B^ÖsB®½˜:÷ó]º®¦),SìÁÑšDšŸ=JR „ÖÖÌ)9<‚(«•‚ c䮋¹º\¿/LÍt±1e™€£®ÅÜLññÆ­Â÷Ä#—.¨Nw¶4K?X`SÂë¡°•Íi=݈Ùï°mLŽ@J§h0åÕèˆËyž.±VÀÍV­tɦ©¼Ç]woÕn¦uáG¸‚‚@»§‘q(m²"áïž;lw£‚ácE¯¿yª$‰ØªO¾Î€E¦ºñ€XØf€xØøßeL²áŽmøxùô ¾ló²šú­&E–†3{15§8 ¹Ô—"—ó¥ñãçA®}'|%‚ K“xÇ"È’c dA]’WÙ8G/mD4Ñô ÕäÑk™TÉ@œ£ˆ„<úö ¥cJáA‹)h¹hãñ|ØÐ D‡ý†ž]5÷#C âå¼0t ¶cæ'ûÖüÝuÀØm9׸ñúŸW¯<´äžÖ¥e2¯ÉYƒ7VoŸ¾é^ùÓ!õ޾$Ã0L©ì™ý$Y¯çÉÂFþº‘tœ{³¶IYše37@à(¨h:¨©í:޵nÀ%4Vº{×:ØØóD`4ZnÒõz2’;;…ãødí´cɪ²èm‡)ÌvmÙÃ-ŽZ*ŽÃ.-÷[‘O·v:ŒµŸ—»Ö±á´àÃ*Æ6tÍ„èU¨Þ‰/wH@ðBˆîa£x¾˜X+¹Dð¸twôêbQ˜¥Éª4Y—¶ÊËO•ÒØV!æÛ-…ði“Øßâ¢4+·fQጭU÷> stream xÚÕZMo¹½Ï¯à1ÉCV‹EÀX`?à$@,Ö>$|p¼B`d!² lþ}^±›#Çöp…Ö¹H5ÝEòu}½"»sN%¤ ™-H9§Œüw ™2þ¨àФ@PÆ- $.”Ø\e$T¢„L³_ÑÐZsÁ0W—|êêS–²`HX»_²6‡T°²‘¹TCnZMˆdX¡$Ÿ*S†´Œh2û²sõù*âìðPY$ ¤â¨w«ùxFjäø•´` ,É”ŸZ`æ>¢–ê#j Œ¿.åÀµ¸ª›¤¹ÝRcʪp×Z”»^…Tk¤¤æ³îR·¥ ’}5ËAJQ— §ÍDZ>³IÖŸÖ/î;H IŸ¥†ÿ`–Œ+îxª¨ÏÒ(M}¬A‚ ö ¥š?oƒÔ=ÿÓõ`¸u.›[¼Á%»?ÜÉêH)A¥ú0òaÍýAICM0X ?ú5—zX`Òêk†âäCª®Gªä¼SÊ)ÔŽ™0A­ˆYHгê«e –r¿‹èó‚¤ç>s¶`B}B¼Û€(«xhH‹Û»Ü#×ÜZëVC¨X[F œ&{t¶äv&MKC„Hlîd%.¡‘º„%›pŸ¯…Vª?°Õä#`œfâVcB¢˜crNž|êÑÛ#\sÏÄ©_5Å‘!¦!zî‘glrl€ QëîÙ³Ýþ‡p…œõ,ÿ)ìÿö÷À¬ð­DAlÝ|øå—W»o¾ù²¢j,~VQ¸FAÖWÌ9*Òî¬"Õx^±¤ˆì8Ò{~{ó><{öÏ[âQÖG<ÇÂ’UÇ/ä'Ñò«—@x~½§ÈFÄÚòË{Ñ[ï×\~aÁýw·o^\¿WaÿãÏÃþåõ¯ïÃËËÿþç7^ÿëz·ÿ¸®oÞ¿óÕQìö?]¿»ýp÷æúÝR¶úµ¿^ÿüöõw·¿†«Ô«32 Ñ+,ôú£ƒ&áEñÛ››[ÌvµaÇÓ‹ð*”!èlmJB a™ð“çè+îö/>üó}ÿý—·7ÿÞí¿»½ûùú®£M¯öÚÿyÿýUî?üßÀ45ÇäõEK,á§á¹Jm‰Pû¶ûëEØÿñöåm€§÷ßÞÞü!6M¿wCouÊ ©E+“Hœ¸¶ƒÂ¤Qí kCn´9(ÖòvH@<Èóz@"5Å4k”&º’5NX)zaqÂf±J»dœ¤ W^˜I9‚<€¤F”ØKÆ 5‹ %n@á*±¢'¡¨m(K«  ÿ€ÿë”MCöàŸ5R¨PtªwdµÉ‘pFd ÷HØ€ N"ÉèÄ>†Ò®|ÌphuJ¦ô*,ÇT¦ˆ`»óŠÅÐÌ̈64–œÏ+¢Ù•ó$ ‘ë'ÄûŠ~®rJÕæh8W;¡a<ªƒGu³bÖAÌhoVa³b®ƒ˜k~ 6†ÿïË«z2©]´¼JLèÛ ˆ¢­¥b‘±QÑTGå²å•–`…â4\áµI(›–WÁÒ¾I[¡ UßcÎ@Ù¸¼®þY#Å9¨o {ö¯#©FÛw±Á‡Ž^2ºdÄ’³.Ê;"5ùz#î@`«mÁ8Øÿ pK½‘œ„²iÄ¢ST? Z¡'CnsP¶ØRàŸCœPkˆ0'ϳY\NY¸ò$ )¢˜ ¡3™QÄV;‘³z’R,61¡7†–&÷Â_Ûï“ð—i÷˜ LÂ-’°ÙÃIØyÚ`cllƒm°± 6¶±M¶ú”«ŸŒ®ð@¹­ÄÄõ (WQÒýhí@¹hÝ$ñSPî€r Ü9([ïhj¾·ŠïhÔÏ5g < å*Jj‘æçÑÑÇr9Ó›Ù–ç9ú±íŠƒ+á¿ÍÉÔ6ä~q“øùí ËÇ~Ô<¥©>‚sÖ4î§ŽŽé€<»Ék'ôbm’^ŽQþ(M(2R¶‡lǾVíg·jeê¯£Ž™À_<˜ Ú¨òmTù6ª|›¯66_mÝ|ù+ŒU Ç`;‹ö”L°œ˜`=Ûz&XζL°žm=øÙÖÇLàg[OÁ«ÖHg[Ž,Ûô<ÊÙÖ@2ζ¦|z¶µIöšáû} .{0Œ…ŃP°ý­4yúæñ"á7 {íö÷®SLp¬ø&8Qú|N‘œä¼"Õ¥Òÿ·Ÿr ås‹¿Ž^X"ºÈ<B‚Á†0؆ÒcœðIFI§ûmØ—‹rŒj4n œÑE›ÒøÞ(!=éžu¹¡ï§KZ„3j¨0j(¡½ö¾ çï À/©]”u…sD£~€"ø_xÉ–Uý`”Õ=¬¥WUGV+ý¶¾z“@ɵFÿ"gJn¸.rÉÔAOä•i áâÞ±9$JN‘ë=AV'ž5Šð ×MrÝ‘¢¿±ÒÈ<£¨Ø*–|^QH#=¯È­Eÿ\ç¬"&¶:¡ˆMHL¤“ ºÁW*Ç|ú`åÓoVˆåá Jƒ ip!NåÁ©LCØô{vd4÷Y_|TúgIÅÐÛ»è­4ç.ìÇÑsH6þ2f1‰ˆ®_Æ,6d”\Ô$Œž5ƒ “îïM!ɉ¶· ±×©v° • rЧ0Ê€â;eÎ: %§rR‹yò3âO?3XŽÏ*–q;¯( ’‰¥ö—Œdhï>z·ò?»Á¼k endstream endobj 6260 0 obj << /Length 1444 /Filter /FlateDecode >> stream xÚÝYKSã8¾çWøhSDèéGí ˜šfÚ P)ǃ‹$ÎÚ,ÿ~[–ìXÆd™%3{‰mYjuÝýuËÁÎ7;GG“ÑÁ)'N„"ŸúÎäÆ ¨ðñˆ9“Ô¹t¿xT¸²˜É"/½1 B÷pµšgI\eùRKb÷Þ#0qž¯d¡‡?®³Tîëûs9—q)õA”"â]O>N&£¿FTÁÑ[sàÀI£Ëkì¤0þÙÁˆE¡óPÏZ8Üá:w.FŒ°1#ÚcD}¦fûÄ)àÅ“Áóç &ahƒïŠ™˜‚ªÂ­¦` ØϧU¶0Êõ增 ï7/ó+ÌXÙyÏ\ÎSý¼b}©7JòeÓkÿ6‹ÊªX'ÕZoŽjœZC[ƒ)•U‡_úÚàþ |pêûk±3¦ÀceQ('çh“Jk¿ƒS€§ƒÇ€©…ÀÔBkaCÑYqDxÐ,¹Âë þ«Qf)P#¨Bà³UgawG!ÍJµHzLæû¯Ó‡1uki¤(=‚Ý*^¬¶éäûHD¤Y[JÐ*-_«Èì!”-+F·éÁ}DIëÖE–@®ke @¡è8” Gè¿\A*ëHs R{L1Š(ÕÒWq/,ñ%("3&p&Š/³å5¤ŽÀƯ:—jÕíÑAÔ¨>ÖKβY+ÊÂîcWHÆ~KS#eL1Ö×ÀÎÞ"²Þîç5½Æsý¤"gß–S?¬r¥ °ŠâÜ!•´h­í«¤ª2$^· @ìŪY2¨ß‹½EˆòÀƲP©#ëü¹W*€C"AïÆ=E¸ï•+J𶸇2W“z2Ö¦\¬“D–å/ú)¯n¥Ž‡¬._0fàù¢ÂlS…z¨A(4*ŽRYƒíŒ}¸à¶v“Û¬^¸7ëebÊ©ðÁó•‡ÍÍ®0pg*L¥§fM4t€p†øÆ›=~ìAÀòY‹A•[û.T.âfjOYÈebFg²zð,—=EËGå±RíWÉ…ž½Q>^¦½ù…‰/k–±>••Á~‘-eª$?;ÿgJ™Ç!( ÏØm‚B#¶EJ©9 ËGatI².š[ò=¡-»›:þâF¥×¥Œ ð"‰ ÀÁc¡ÕªTE¶ü6­TÂäÓD5 wê¾\/ªÇ•ݵ|€k[5meõ$Z˜ikj‰ÖëäVZ˜‰°Í›oS J€Ð]ƒÌÓÚF¨€êõ»•¾c¡iýš(,oc“ò{:ô5´°á+‹9ð:‰¸Ýî¨Xïš°¥¹ˆ6¦ì%ÊñͺÕP]§@MdçuÁa‚öʺnâò©/à¼qÚ«\ÊÖLËõu&Û*¯ ¼W…Þ0w%Ó¡êjö° ~¾®šžcY»¸ú(xR]?¨T2 ‚:[TU§ˆù\¦ú)ûÎ"ð³Õ¼“ {òé×?=HI÷ðì•äÙ”ßíÜ™Êy¥Ø-®vJš­Øþi±–Ï×?Š<ýÝ“§²%®†˜G(Ü4[˜óç§°ŒØ¨þì1(DaØZ¾§ Q%dÂF ù¼9‘ÿ!QêD€ühQµƒ’ô‰†ÇÊ ›ÈàGuôÑû<‚œ‰éñÉ™wâ Jõ3™yðòðøô·ó¯zä§Ð'œvØpšoe T‡ÜãÊ3çËwØs6Ð ð&óŒ¾å޳£ü³×|8gmzM³bˆ:9›õ9pG]&ê‰Â·Óe‘¦=£ŽpõÕ@G8`WÍ7Ó ~?ÃÚÀÛÇU]ú&œlÛûÅà‡phjô·˜fþÿ‚C¾øo‰Á?8d1èJ•>a¨ÎqÍlž‰à6ycŸG@ž Õ7®æ²™ ßë?nÌ áš3Ö=üýSâ毇46-ø¶ì[úÁF9© endstream endobj 6281 0 obj << /Length 1447 /Filter /FlateDecode >> stream xÚÕYKsÛ6¾ëWð(y,$§§¤3Iñ" *¼Ù£¡(‹¼À‘1o6÷.Æ&”ey#˼šLiŽ_Å*Mâ:Í3ýâ9¡xüeB`á*/d©_¿Ý¤sy¬ïÏåJÆ•ÔQŠÈäjö~ôf6úkD@ì/ ÀÚG¼d=º¸ÂÞÞ¿÷0bQèÝ5«Öž/B¸®¼Ï£ßFØè‚0¢‚©Õ‚x%|ØyyîÒZq%ah…ÿ,oøuU—iv{]Oç×U¼ªëûˆ?Õ—ŸAýNm¥2×úK¬/š†¾×„ìÏ@Ô|Ò¨1G§O§Å¡>ðá×…Ökøô:9¢§ö¦ÔyO'Y–Ê—yyäsiñ;9+ôLÄ1˜Îaž1€på½}„‚lQÔn¼ÄëU,ì­âdí’DYo+óq<>ªÔc­ 쎵Ï5‡(‹¸¥FšÕŒT·„ó¢¤Sý¨U¶phëcñ §,qûð_®@•õ¨NQFà@ O©¦^Äe¼¶È{” ˆÞ”À•?_¤Ù•6¥ ¾]ëC‚E>m¥žêÕŸU$oí®_Ö¹¾&èL:3Λ@ï­ˆ3}•Y¢iÜÔ¢m¬XzA¦$@3`s‘oêVÛò–pj¨Î¦–Ÿ%Þy¾ÄÌ_­ä\?¥Ù£îŠ Ds+qWJ•ÕRýÔ_TjÅ+'I å÷H1ŠpÙŠ_R‚ KdÑå6*o’DVÕOú)¯—…îÒÊ(llóæÝÇß'ä{ufê©h9€Ê©àȇXƒEáÃpY§kY7À kõ[7w¨#臇N-z¼.œØÉ§OÁNòýÀÓ·iÄo¢Ý¨ðP´ x§É‘ÙÆ›m.Õ9AŒ†‡R…å1@Jþ{ mqȨ€Jûcd› àP ,\¸Ð2à(b è§&ž¡ÊÒÒòÖ^H„ÌöIÿ¿IÉ“/æ±2í½ˆçr¢ò6íuÑé–æ&ÙþÔɬÞb ¾»Kë¥Y”ÃWµ¨|5ëªB&©*{Ép_oYÕp6è:ÿcSÕk`ñ£·¢­%ïP0˜-ÄD_€‚½^µaÞXY¹LüH4r…¤COµIªlÿZ¿•ƒ[v(T.eí°!ðð·móûZŠ…³/êkµ)uˆ;Ê#¢Ô¥7elúÒ>‘Æ.Ô5T,ø n×\b°àPŒ™’ÚW wusú¬Ö4샙åÐÀûòÖt°mPÛ0â~ø Ô›2û.¥âƒrËö|CM1º$—yÙFË\6ªlѽ/ól™š‹M–lçH.ÓHå]íÍJ쪻¸WßtHÈõ6¾LÅZè+T Ö¯Aü>•~³ÐíööûçqŽ£ ÚÍå Á‚T¯Ûõ–0Ë|5ß3×täNvJ·fm—îΦmฦ9Ig2»mÁ¶Åb[ïAIÓDl“uÜ» ´3°ÏŒ-:âÊMß Žµ¶AÝOÓÈGwÆÄK%è²2]ìk}]™ò¶¤eyíhdê½ T÷ç42Ã? §âÉÿ#8ÿð)"ÄÄd4š@JD ô™ÿA>½k ÇWçaw@(³$Éþ‘· endstream endobj 6299 0 obj << /Length 1522 /Filter /FlateDecode >> stream xÚíXÝoÛ6÷_¡·ÉCÌò[ÒöÔvkÐ6è¶Æ{JC¶éX¨"¹’Ü$ûëwü"Êjë.ÁÚƒS"Ç»ãÝï«§“góÉ“œ J$•Á|D4ˆxŒx‚ù:¸_O©UµTUYOg4ŠÃ§»]ž­Ò&+ ;ñ‹šR~œ Ì˪ìôé>[«ûüVå*­•}!ˆRD¦—óW“_ç“¢à€Ø£9Šp¬®'—8XÃü«#–ÄÁ¡º¸ŒãóÉìÔÀ}u$ï©ChŒ’XÁ³ÈêôŽlŽo÷=yÁâÞ&P_&°`ˆ1-px¾_­T]ÿlßÊfkÔÄáMfÔ‚¹™^kcÜLè=†UYÙ÷U¹Vµ>?˜I¸ÁŒD(aÔør£×@Ù)AœH»tmI<©58ji2wxQ6öáÍŸgg'#œ…@ &í¶åþf $>äO%ìA”µZ;£ìÝQM9r¨Kæ#T1~NÌ:ó;«g:ídÛ´JWªœ7Y³uçnÝU|ÔN›æ{÷ZnìøãˆX„Q”ú5¦EÖwì ª•BL’ g:˜|{:Œ° "nGÄ2}_-ŢɮU Fá¯õÿnÑL È¿¨›*+®løÌìð¯ ;ë‹]IípÀÌMŽ¥å޼èFDq¬u‰8üs%£æpÒ¨é3ÊÁ¢§Ÿª*}3eµÐ10Aÿ sÜ9|Ï8é5¥3ˆ½Oá¼@‚vîó êÿT(#‡‚h+ja>‡#"¦“Äíf׉ïÎÎ=»àã8tuö—Z¸°òcÆ×š'(æqOk2~›_-ó\5¡ BW‰QBI#xTŸ}@ J…´dYqéâÒy"˜ 6튇1&9’I<û¹vñ¾á:€qHZL™Ž&Z”mœu<5of/®.{†=AdÑ@ªg-½'̶Ìן«IÏ Ædu'ZYÙДŸÁM.‘$r ê¹6`SVé•Éãv2µÒiŒÌòt™»é¬ÁÇX"ÎÄXz8Ú‰ˆàðû*U:€”‰"‡Ö£<éÀG‰ÏéûÎæó6'ÙK·ÇX,×&wL+ÕìíRÑ:JV ’Z^®R¸*¸º¦\„ngºÛUåαMG»îžÒ¢çxía»JÕªhL ÷Àl†ÇÒØûf±ªtÎQëz±±OÊË^/ô{ .™ˆ?=·/–àƒþßÑ“]ÍTû2Þ6ènã¹À ™À,3—é½¼8‡¹ðáÞhc5Qj|“Hô¸Ç“Àh¬Óümó9G‡0‹I'»Þ¤´¢·ÍÉÃäaL?ŽØDû¢¶Ë‘ò%áŽÍª¹ÍÞˆrþèiŒÂÑèö°4f-j¼n,SëhX¶žeË*µÁy×gb®eý-?SÝKÐÍ;@1’™Óĉöe÷.ëŒJ1Á¦¹Òþ`~àÃÎŒÅ1’þŒ¡/³ýóÛKIhèœußh¡J“ÔOcÍ@I­³ª¡6xãƒ$Ü×±zHh#öµš£-5ƒ;Ñ'!òÊÔFj*ÚÞ¡äù]±ÚVeQîëüÎN•K[Òg®ùn™œgiîZô}Ýu «ßQ3Ðò•jÆ0™#ÂÿÇä²´­=“Å “£bòq†“1ÿ–ÕuüïU×=ç[SAcnöÅÊ}’Ä4¬8MoíÀSÛà΀xÖ–NCÈ=rÂj‹œ°–Ú™þµ´{RÛÎÁêRÇÛ]SVd1h UrþVØ]µ5ÐfŸÛ½òßà‚ÆË¾¿w=€/¯žH]\vÅ}Ûc(­´íA×Ã/eC 5Í¡{»—ù¸ŒJ"À"?Jm@$A\ò·© t£ ™ú«k7z¼€•GÈ-8E„8¼!”ë[c>ߦ;S)¸ »%ø—äIø¼´_úrÕôþÆí€ÿbå·cOéÊÓ.Ât¦Îhîv6;5Áj–Î endstream endobj 6324 0 obj << /Length 1540 /Filter /FlateDecode >> stream xÚíYmsÓFþî_¡oµ|Ü«^ÚOJÂЖ¸Ÿ€É(ò™hbKF–“ôßw÷V–%Y6¦I[˜ÌXÒénïÙçöv]¸÷ÑãÞéàÙdðä…^Ä"_úÞdæÉP3©"/Ð!Ó‘ò&SïÝðl$ÍЗ¶ÈW£± ÂáÓårž&q™æ5<·#ɇ7#çùÒÔ|ºN§ö1Ý¿µs¯,=&%£“Wƒ_'ƒOx¸'¼@ÂÔš<ð’ÅàÝîM¡ý•Ç™ŠBïÖõZxÚá:÷Î xå g\àLú {ûÂ+àÅNãÛ>¯qVÁW9|]\š‹òº¼HÀðhººø8 >´#3l´’/ãø²HLЋ8ù„ý×i5ŒZ7FlV¦ñ¼25+òE5ˆ.4vzN4‚ŒÙUYÙɳr„sAÇ»’9JkNjn$‘€@ï}â¦ÛÜ㲆WÞÝ–˜0¦MÔÒ!cÉ‹ŒôƯU¸<Ú·¾PoaÃòŠþ°ý̬ª6È)°ÇÇ@ˆ¬/ã"^´Ì{îuÐÆú.Í>À†2¼Zd·›z; 8‹‚:2Ç4äuzYĘòøð¯¦)•ÿ-¤••1ð)µƒ ¼ë™YI¸¼×œyârÜ AA^À¨)BQYl£È×åFëlòÀuËS ”„`¤…ËsÎÊ6ÇZä.8îMP“4ŸòsP<ï5 ¦t›8Þ%û½üP@CõóëUæäÉù:Iìjõ =åå•¥%¿M]Uƒ¶Šˆ3Œžm½4ø€×a‘›…™ZGøi˜† l¡›\¥0ÐH1œ­³„ª,>%ù2µÕ˜žnâ娒f)ò]iðO&±ÆP44·>Àb°¹¤gÙ1?ˆºOš•yŸ%Îüh›”šù£cò€‘uº`ÂhÏJ¤«å㊨Ÿ­7Nå‹åÜn‰ÉgD¦P­ÜZ7¶v·ð85SbQq™g¬¹âÂh®º}i3Ùå¦3€ø'.xÝ}VXëú»¤ \¯Ú¶$wÅ~=t)_ú(¾ Sº®·W6#ËiIp0jð9«fœçy[Tô„ʉœ=™…™n„þa±pP ºêÌð¨u¦?£Îœæjmp°¥¡z©°ÚÛoêÜímûsŸïóE½%ß¾¦niG¥]Á±#=Ñaƿԑ{ÊLm$3æ8™Y¦ {¤Ä,Ó-\Så×\[øZ•¥ÿï(Kòü‡²üj”åXÀ—e}©‚°][—l·K·Y ¡RÖœ?Ú·ÔX\‚‡×˜aàØ‰ù ³±v]y)ºòÒ%,ø½v«lÚp·³‘æÃÆŠLЍŒ¾[) £( ðf' °±®a±n¾¾Šq‡ß`»à. >æ—e ²ä ½mŠVl¸Icº±)9ýYaç “ôá%á®Ì;NB@½güa´ÊïÐøÿ“’Z1­ô,†$@ŽŠ½b¿cZúç„^Å$Kšj¦­U*õƒætßÐU_rüvöüä'4Y½ŸôˬSg+K¿Ør^íÇ›4±ßŽpr|ïÒ(@Á÷%™’$v¢äÊÛ?Ú~2ãðâÊÞl\õå‡pvÓ¶zÓáÛ}U›„ùõÎNö|Ï•‰?¤™ÏëÀÉ—ø½~_D b_Ê–·j9ÔþX˜ÜO<˜„TZ2~sÇ”rAï{»óŸÔU½2PwWq6Û>dlŸ”=tL _ÛÛóª ÆË g]®Ë^U¸37™Ø3y¾tU»BÕ™ý7Úô€Éte+ÿÏÞ>3§'ô°ˆl;1·s£¡Îý¿²þ# ˆFQ-®ÏðˆËבÛYÕÿú~é$”]„§5•;ð%ÝEö7c¨Ê¸ endstream endobj 6338 0 obj << /Length 2120 /Filter /FlateDecode >> stream xÚåY_sœ8÷§àí˜-[+°÷”8Ž+ë­Ø7ž<%©)†‘=T ÀÄñ·ßnµ˜çìd«îá*åAˆ–ôëÿÝ wîî\ž¼^œüþ6NÌbå)gq焞 bßY¬îÕÌ“®®Wº.›Ù™Fʳ4i³² ‰7zæq÷ÛLa^Vº¦éË]¶Ö§4žë\'¦Á<‰ÙçÅŸ'‹“¯' pGÐÑ yè¤Û“Ÿ¹³†ù?Îü8r ÕÖ TÏܹ=ùÏ ï³¡üBD,ò'œq?$^>–»ö3`ÜMÛïà÷·~Ô[åGÌ‹CØÒŸé{ÃØÌçîM,.oiPë¯3ÁÝn¤µ;—E ÔÒýÞ;Œãçð™âÌs&Bû!¨q{?í7ÔC’On [}.<ÆÃØîdÕøÉ|°vÄ9h\Åãœ8¹Ý¥©nšÓ[ÙnŒfA ™Ñ$ÌY ]¡þ6"ñŸn]ÖPÖ $8ø”,rˆn±É`¡¯¸{·+R²,|«j]%µ¶ßÚ’žåªM2K‘Öz­‹6KrK´MÚµ±ÉŠ{Ò°R=>=0=):FÓÕª×Í„-x‹½ŽÌØBWg$¶3ÜH iv¹E <ëÑ0Ÿ¤$Ÿ¬Él|ƒ¯}6Tib¿¬ìv»F¯íÍcAöW—E¹kr´‡G¢¶¢ª/õJ.Û/íÍ·Y’2tõ‰K‚È ÷@üßvìøì©y´ÿ½‰ám·=cñ}÷V[©‚ïX0ë,õ²çZ=`cÝŒÐÑ$ÈcRþºÀ1xWk=<£3Iü2é6’I¹wÏéh.ˆ½¯?ltA{fÖ‚2‹¶°gåeA¼[Ö X36ñ_}ïÐ`~y”ºd1p·Qæ ^œ¹p+¥˜ ­.Mú)MÐLÅ©˜)±ÝGÉ*³Lƒu<—3!ý—r™@Ä€ÈØJ˜CŽ&çOsxl¾³3éig0¨¨€8³†žQÖ…1…¦ùn§¯ÞœÓ€6úŠ¿üì×Ì0 =¸ÒDx¡mð'Ý$E-ͦ3:óx„ì…Ê)RÄùxrnuߊÁ; ËøªÏ¶®k´Á²^bÎ¥lSOh°9WâÇ!‰õÙ[Çh_à ËÑ ?Ëdž/0X•?#«•‹ Úéü÷aO ïÃПŠMôÏÅ+ÆûáåaAR`­“6ù‚À‡½ö~ËŠ_„¦•—ØL¡~ TÑ¿ˆ|]Å¿$“ãOm¶)šì¾0Ø<ÞûÄ}™Ü7n 8$%Oöü@ü°Vn ï«ÉX€¬AÄÂvPÁ&ÛÁöŽý<ÐÄǬøÜï (ŠÇ{ U`z”¿²UPAô8Ù†Œ‘Ú]ÝFÁtwÚþþÉ/j†ŽäE;j„ Ïé.b~Œ@P˜7 šª,º*ã›ÞV­IYŒÊI0 ÀMò¼3†1V{ðë¡¡„Ñ”Èb&•÷DCi Ê!þ¡§dF[>…ƒZFpŽiÓñƒ1š¹)ypÁqqWü4J{Ôо(®9ôsH þãõ®­víÑÒç÷ÖŠ…Á¨#þÿê­=Xqè­ñ \“ÔGïÒÖ’‘{À §}x#íãÁö¡&r÷ÞƒûïMÅI ^gïøCíBbkmŒá>ö y‰¨'ëÃ@§ÔvWÓø¶.óe m%ø?ÉÇ€Rnyw€?Ñ)M4Ä¡r“bMƒZWÐr6Ð1A;í^4k‹M5 0XO§úé3íë’ÉÈ&8“‡š£Ù”»Ü¢XÙãm1bC7±€º ‡´;åë-+Š)æáÒݪéX-z`”äSO„tOÚc‰coBùLFr(Rô°¯ö-kÿ®¡ ÂUmïLöÝãH'“ä;Pk)w[Âr3:Ö$Î&Ýgjæ&ux,:é§C“QäpUóå9m½²G9áyÄçÕüµ\.®ËóùÅ›Ûå-ºòââfùö¯W3)ÝËå9"¾~¿x÷þÃ.‘Æò¬h1·CÑ¡…2è¹&¾¥ÞPÊ|^ÙEUž¤X%ḳÀ¡$´°j_ÏO§4ƒö > stream xÚåYYsÛÈ~ׯÀ#éZŽç¨<%Þõ–×N*Yk÷Åv©@b$""JV~}ºçÀEPR¬Te«òBsô|}L÷7ÝD4úùâ/—¯ßJe$S\E—×O%á"‹™™‰è²ˆ>-Þ/y¼ÐÍZ7u»\ñ$]üùpØ•›Ü”uå~ÔKNwKwõA7®ùçcYèÜó¯z§óV»F8'lùåò—‹Ÿ./¾^0ÀC#%––$¡I´Ù_|úB£Ú‰(YÝÛQûHªþwÑÇ‹\P¯ % T „+£‹è8iüuNk\•QBEâ¾mÖñÕ±Úç F¼h·ùîjcu¡+Sæ;o†UP¾Õ ´–ÿòÚåîÏŠ ý”zýO½1ÄjÞAïTà4Eœ‰„_™*§Â´TxýV©~­¸õâ|Ý4趺¹ÚÔ…­÷ú-(<ЄS°ÒTw¯w¯3È€…ãÁT&b’eaêgS·Ð÷*Cð€lêÊØ úf&*ˆt8O’”Åa&NÒK/¾Œ½˜bK‹bÌ á%Dˆx°ÈMþ2)@S^áð^‚+½!&¨ ±G€¬X ;.ãðÀHûPyõ Ü^ÕG3ã^HYš ÜËæãö‰*†H8D‚ˆ[q@ÂR'ý7ù~$>²ÝÉð§²úÒùÔØ¬óÍCG%YÒEæÊMùP®ÜÓ0éa(ƊׄÔKY±„dBL€3—+FùÌú"#”ÊÉú—[íZíP¸¤Qx,'[m„ÅKc¿s4Kfƒ ÷åJ fç5º=îLYÝôPZ÷èÖ£~Ÿ"M©T)w :tøcî0/å»Y‘ J­È Úÿ3gô±@‡Â¥:=©Sâãq³Ñmû'¯’Ùzûß—­7€7È{ ¨¾ÔÅø‚ÿ‹¦nBÄÚú'Z©˜HˆË:[ ¾õžn`™˜v)!$‰œÚ:ì™ú4DlCY¹y½”  C°ÇøÄÆcbl™âa2çí»?yù›|ƒyòQi˜æïpÏèÖÕh“69ØÇ¼*‚-e¼xó×yɇ¦6õ¦ÞoÊ„$P’G¦ü-øÆ&¹ëFk[Z\¿_.˜ûgŒÍÀ´¯ !SžÙ$2ì*ÐýV{õJ¯zéÍ^ùEw5ìKŽ|»ÿ¾º?›LØÈŠ)€äk%I‡”Äñ«¦¼~¸*«ÒL¹…§#¿£Ýí(÷ŽC!bÜË,Éo°1/«ÖŒ Œ]Œ±þ£—»‘u|Iœ’ªþ(¬Eβ–áÅN 1Qˬ5°ö{)( ©A94eµ)“0­VœÄ1 óBJuY§Á¤ôB\+Î3+ޏ……w«L¾~ÔmŒ$¢;[1lZ…y/5ƒÊ9ñ&N¾Õb„f¬w]—m_j'døià`j”‹0 F¹(¤ÖÀjÏÃepÚRI—–_ÕNºUμµË¸-ìýziJ˜š}ßo~oÀ|½Ó=6Ä4¶ì1šB_[ ´; &’³šXg¬YütoºðÎÑ?û‚V2~@qrPx¶/,Ž3ñŒ¹ŒÕ'ƒéŽJÅD…ß—é8D»k)+ΉšqÈH·gø‰O曩r ; ´ÿ—£ÏåÖÒcÆ×Çj〻ɽ?ßg7›¤KU±s››9/Q3,~îÜ$ˆÝáêÞ)í¤×k׆.ÃC½wí¹kxÿã÷~_š­kº¢0ïñg§ Çõ½°k¯{½eh€“Ù©"œ)Ò§äžjL•€Má K]¤Z ùõ‡!k]"¡Fq9¹.'˜É°ö 2¡ˆRê9Èx7ʺâ¦"ø¨ïædËŒ°ž§[2'lÐùšÀÀ"¦«À‰ÝpW "‚1 o[Þlµ»á[ÝÞÙÓ€û†AªëK/¼÷9FÛØó+M* ´Uù^»q?TÓñë†4vºd nÃ¥Êâ±xv‡úûË|çô±*¿b&9êÏ”³mítÆçŽ#—=W0Ï]œD.×øNo®ÒŸiñ¼6ÜñàíUœy?Ä_´½ <ÁöL¥ã ¢WÙÞª6®ÉñŸÒi:«DY¿`_écyXªxaûßÏ fUœµvm΋ɰ°*«2˼r4¶æ•_f#Øbä4¬éØ•OÇ5†¨’ƒs޶ƒ•¥J±àÞOÈW¨lR%‹}îãG¢ÚøßÞ–‡šG«ä}/º®PÀͱéD¤AöyUø.úq^i¼0,èøU–*wShEA,:í€E;…Ɔ”\Xë65êbµD7bóZo-ô»=ƒ}áN {ûMnï"±;w=ç­cº:#]¹‘Ç96¶VL3ðvÃÃf¸[wp‚1öµ¿iB¹x±6ÁôÔø„°V›«üpÕè¯WUíòv¹ ÒÏm­ÓˆK‰’} §)N·*¥PÊm¢ÆŒB†»Ï‹ÐžE‰´ÉÞÇçÊg¸ˆ(Ž!ÁܸQ.§ÀÃY_a'¸xceÜ—;¿æÚÏ-|‡@%a –ÌE$ jÿ³ê²2žÐH¤öràZ›ØEÒÙ ±Ü µØë}Ý—hÝo»W ž¬b0Œšk;1¬<"ñvCáC?¸)?à€ÊÏo´ñÖ¯‚ÈYÂ!b>øZô”m’þ€ƒçټř$Iœ~‡Pop§tít̽ý¹¡có{¶\ž|™=¬lÁ8»P0»ò62éÜ‘×;jpèuñW7áŒÓ—ÌpÞ­<¾~ÉŽ%æ³?dÏ~–†“5cþ”Ô¼¢dfSŽÿÿ÷wÖ~Òˆè¿32žL‘ý¨ëà endstream endobj 6243 0 obj << /Type /ObjStm /N 100 /First 993 /Length 2048 /Filter /FlateDecode >> stream xÚÝZKo¹¾Ï¯à1ÉÃbY,ÀX`p ¶Iï 0²Ð² lþ}¾â4gVR„á ­vO]Í.’‹õ$»fI!…šY‚žÅ5'¤>5jNh¨EhA­:s †Ž (PÒÞŸeJPˆ½O.5´â”ª9ƒªè¡5¢ê3&ï[3(nhSŒÒÔ¼ ”eçSôµÚù$ä”ò†iNÂÞV@µŽ¥…LÙgk)dÿ€¯° ‡\ñµ˜÷P|Uöñ<·êKļœ’cV L"X‡B¹õX:zmKq|-®h„²²fVtC›¹}^@ãæË'LÎÍ:zÖØšïC«ARî¨ TõÙÀ,99…ñ„ÕWd)H¡þ•‚Ôâ=,Ñæ¨ »iÙ×a%”TëÀŽ•ìrÆ Ca†Øýµ°ÏËN æEzˆÏ˘²”tØPP"ÞÆ ú^s<іѦµnð¯)õ¾˜œ0¨v(¼ á`”Rœs5ïAqcÇB˜È|?¢SJ½‡Í‚u0tbî=,hqY1D«ïãUÕ¼T@«£PÚÛj€ª‰·5PÄÔ’9¶¶+æÈøJ³·eò‘|ÜçÈV°hPÚa^Ÿú®2shÆ>LÃ’ºÔ¸˾T»qIÌVA™£‡ špÿŠ6QРìNIÖ\ëŠnÖgÃVPJ}™°SJn¾Õkg…¥’lóêÕfû]¸‚Øù›°ýÛßÿIÂjt¼×_~üñý櫯:ãëýõmxõ*l_ÃlöÐå5ŒP¨Öñæ®ú|xƒÆãÇ·zPÕÃæw$˷✇7L¸ýþfÿñíî6\…í÷ß½Ûw»ŸnÃË»ÿþg‡þµÛl¿®Ýõíg·_wWo6Û7»Ïû/7wŸßÛþºûáÓ‡oö?…«îÓ oµü}¸Ao4èÂøõõõ£]Üœãénn!tm!J ‚!ƒÝË¡û½uô7Û·_þyÛßÿòéúß›í7û›v7mz¿ýÓöÏÛo¯¨¿ø?B4J1%ìmÖM’bs=²±Ó`ûºï×Û°ýãþÝ>`«÷?í¯ÿ­¦ß» W‚8kÓ#’ìà ¦ÜézP8[”z Bqç>…ÊzP`µ±¸ŸX ÀýFw´sûc¼’EQÄRdØÃP”’$Â+_PQ8Kô=0žµG¡ $PZ]&ð‹QÜ7.2áJ:sI™¤5á#†óõTf r…ÕE‚¤)>‰á0"C»¤HˆcƒÿHDu£žC"w,§Ç7ÄÅS|CP46d1wâÛCF„äç™RЉÚyÆÂ0|d›ç“ÅÜ&Ùr´,ŒµF¤çϰž`ÌŒ=©“9Âdä1<š[<9Ghô0GP›Ë|Oîçudud:2ŽŒ@GF #³ÐÑý~üæRäᘑOñ¸JD^þrA%M$=‰¤”ŒÈòAp á ë’uS”±®¿C&âþ‡.)TQUâ ,ê2‰då Òã1ª©…%×,”gØj5V2ËtÑ¿aF?l±h~X!-úI JÿØ”™Hz0ii2 ßa|, ßgz4 ßc,cE1}žø(MŒ(Ø"™`$‰~²s–1 C m‚‘?¶ö« Èf²éÓr³%¢ÚˆÃ6â°åAŒ8l#[}ŽðËýÐî~.…å’†«)§‘°Çœ:‰d]gFð§aNæ A¯áK\ñ™Ji—ôð¹Iä$ V ˜CÂéŠÐÄÝŸ‹P˜ry‰œdàÌyžó›~ !§Î!¹·7ÝKZ›Œ4wa!Z!‚2ÁˆŠ †ržQL£ŸŸg„ZO02¦ö3øóŒšUŸ‹ +áÞO È”Ä?tjlð+ˆîîýb!Ú –°á× ‘ÁƒAŒqhŒCcãä4zŽÐR ú./yè;B ’(/u9×ÈÍ79r¾¨Cç !H=B‘(~G4eU.^¸ø…Ì¥d˜¨_aÍ@iU×?ô%BØåSmÇêâ/ (’KôrwÑá‚MӗГÉP“9$«ªÉQ&Ëî°H÷䎬&:'”´¾žÀW»´zB„|ѤDƒ¥–úñ£Šó«Kòã»ìK¿–8BiÚÏc'¡´¥"~0‚p3 x’ÚKŠ(«ú“ãþ,Š‚ú žN;²¤g¯êºhnÆ 2’nÇSHþ_’è?)L%‰w9ŽxÀôØqÄ}FÑ„ Þ&%÷{‘³ŒÙ³ç*ç ¹i¢ük;<@9û0Aäúô‘GÒÆ# ä‘òÈydË_ë&vÒȃÑÏ.i5jy?,È(ûaßâ‡K‚µÑ‹øáEØK­: eݼNàô„ί•I¡4£gØžEOrkÑudjrA$(b²“ÆrA ¢íIHºObôÂwa"ýô‚'Øÿê{ÂM÷<Ùù¹ÿkâRz¹"O÷r2|š Ÿ&ç_žxüéÄãO'–QÙŽ_žxüòÄe ¸üûô›«u÷ÇR—ë¡ÞDQ'‰/ê .±*]Tsµò’U­_ü"÷ç….*™¼ºç‘> stream xÚíYKsÛ6¾ëWðHf,>ÀcšÆ§9´ŽÚ’Œ†!‹cŠTHª¶ûë»–IѯÄN›™^D\,v¿}‚¢Î…C·“Ÿf“—§>sb‡Ñ€Z §RÃùðëËÐZb¸x®EÃÀpÁúòx‚l ¬ Á¦‡È & £½‚/._¶Ô| Câó®>lðûžÀUt¸N…ˆIHC° %1ç–û6©’M½Ã‰YäL<4ßǬø žPw/½Ç¨ÛÑ §²mÔj0µ;ÿð¤ö5˜P·ïpð²EÃLjƒ©¥4n§Ð  ­A\M™€WŒŒÈG$ ýH¶sûæË¼(WI–÷îƒ!²ã«µ™¬ÛÔó˜¨Ë0Úð(ý»Ëpÿ¿tµ²Ú4?vXð2>m~¯<±>—†‡v{KÝóÿº£„þ“‡-—  —ò‡ Û¡>xÈ”E$b(§ 4Áf°{¢F´ô¢þ¹Vx0iJû»i†H ÅÜ-—ª®W»ÜÎM”Œ(h½$Šd_ÜÙÚDªîjW, ÁÝT5Èg“ IÖ¥æe)Zg>Ø‹89ÆqÌÎ…Z'ÚÍ-=²ËV–SQÚù¥nx”&»i’Ò+Ïã ,ÉAÂVnäk}9YäPÓ§‚GîÙ MÖFŸqBãkc!±·¿ÍBSÜÖsȬq Ø>aÐ-v‡"ˆœ“;Â1ÃPVI:ÀÀP#Iš-G”}†š¦¹ãÝþž’Ö½Üï‹vF1€¥HUzT™~äZ¦/ü÷Ö1ØÈcùœŸÜSÉü'®dá·T²ð»W2þôŸ cIü_Éž£’ ¼¿ˆí/ꡲv —øÏ®½ ÿshæáƒÿrýÅç„1¬ÕŒK-¦”Ô}½NÌ]o_VC¸|‡p÷~]nôe›«– ûv…;tª_.;¿žµùK@ªˆàæf«Ž4ýDœ» endstream endobj 6385 0 obj << /Length 1499 /Filter /FlateDecode >> stream xÚåXIsÛ6¾ëWðV1ÁXœžšiœiÒCêøæd4 [œP"ËÅK~}JE9ªíL3Ó‹HBxÛ÷V{7öÞÍÞ\ÎÎÎâÅ(Tx—×DYì…A„‚˜y—™w5ÿàS>—õJÖeã/hÍ«ª"O“6/·fáwéS<¿õ l,ÊJÖfù]—gòµy¿…Li>¢ÿËåûÙÛËÙß3ú`x!Ñ q襛ÙÕìe°þÞÈőw§wm¼@Dð,¼O³¿fØÚ‚0¢‚©Ý‚x5üq°x1eµ’J0Â,4­W|y{FðyR-e]—õr#›&¹ñÏ­ †²:ËÌGb•¦•Ÿ1 îÍJëaélÊrøŸI³uÛšE-̼¦e&Õ/ [‹ü¡]“oo¾Ú ɲțiˆwÙçÙ9‹æcoA@‡ëo}Æçež)Ò³sÀfRÀÀi‘4„ÀnOH(GœÆ=ågÌ±Ñ Q)ׄü‘0^/^(…0䦎i ªð»o›G¶òEdgAÚÞ¿~ž$D„»ˆ*aíÀG” 7Dº%.‹LSø¸i&¢%Š Ý‡ÁB&Ãø{OàÊ\”@q‹…zA1‰ ÷*©“ÃÞÓl»Ê·_,í½QÙŽQꪤw/ÌÖ?óU­áÀ󇌭Tùe¢t¬¡å²€¨ŠKîdB<‘ÁHüÇZ*àoó²kÌŠ®Ë|n*ŒV§çæêaÙÑãˆ,¯±‘oO”h‰D:–¡4%CyGÏU±, è›ÄÆš‰;³hª¥bêvç2¶ÎªÆgªÚVó)å"GàJê>È]í#D¢ð b†)R^Ûü©zÕÛkU:™N‰e>ÃóB:‰Õm §4&]#Ž0!®‚—ëÜFÅu·Mm+‡¯~µÉ7yÑ's[š§.'¶â÷€-X)í”r6ñWµ¤k¤e›VŠ~°0p)OVI*•ªŒÍ?Ië^#^jÙtE»óð“fD`s ³á8ò Î1‡5ru¨.l¹S×þÝüa£&}˜@DÃ Š„­ˆMWΓ%yW Ž¡”t«BON0EÀ$ésƒ î°ÓE»NìҬˮ°3ͶTSˆýce‡Ÿ4) ™õƒŒ™aÒ¶xxîÔÂák8,WE™*9_—MþÍÁ.$ØÓvµ½JójÝ_Bí¨¬a@ŠŽ úĦ<±¾ß•±ËíÊS­™“çcÕÜ~ŽË”ý¸µï‹Ïr báj$áˆòP=:ÝpÈ•}æZ‚×ýaæ›\ÚJóJÄý×#ð òò× Ü&Àór(¦ô©×eÐþ~ªr`ÆÏa,—#|àŠ±t LÛÔÊ®ö‡Ì=ƒ‘dÃÁžÊ®µ¢'<ç( Àq#ñoz’} |¯†xLGôhL©AŒ!Xûúä¨*©9ÏGŽo0µ9C)ûâ3%ø±LˆP vA€¹Ÿºª|ó«CÛµ-þwyc±€}PhíoûLœ#|‡…Š“¯ð'/äŠ4A!‚X×{èþø‡ž>8°hç-&ÇšýÊ{ endstream endobj 6407 0 obj << /Length 1503 /Filter /FlateDecode >> stream xÚíYÝoÛ6÷_¡G©¨Y’"){j»¦èÚ,1ia(2“•-U–ÓfýîHJ–d9ÉÖ[·¾X$Åû>Þï(SïÒ£ÞóÉ“ùäÑ‘`ÞŒÌWÞü‹¸‰˜ˆYèÍ—Þ™ÿ*àÒ×Õ¹®ŠM0åQì?.ËѹN6ÚNᜰàÃüåäÙ|òiÂ@ê1+ZˆF^ºšœ} ÞÖ_z”„³Øûlv­<¡bxæÞéä· ufPÂ@{J¸ q·b^/öOÌ(¡ad þXËEºH¯tL¥ÿ1`ÔßlW‹\¯/ë+kÁ´±*~½­œê+g`wkqaŸC~Ι8-œÇ’ñ­ŽûM©‰qZkuk=§1š ø±²ÖÁúGGJuL§Þ” ðŒìX®« #^T‹´Xêž¼GG૎ã€9ï¹ícÇ]@Be‡Œ1IªféÞSI­”¿k…$ÉGY+ÑMoÐqèØ÷œÑÛÒEµ¥ÖˆÓmšêÍæ;+ zÚð~Î PÀš³ÿ¿ƒ ‰|ú•)œ&–zãí}‘`2™: ‰P`¥Ý”XíM½¾$‡¡À½ZñÉe0510+ïi(t¾´“M©Ó WRWÿäÒèuO¹’°¨nʺ¸*¨ J|c¨ø—#Dô.ŒŠ0Ùž&GðµšH♨™Åš¼7£»,"*n9µªaöÄDÆq¶ëMv¹ÖK{޳ulˆr#Aí ¿9¨qAvZÔŠXPëäÎ>®¨(Hf‹†ØUŽ[Íq8 ù€Ø0&Ši_ìR eº"¿+zf"é©vo^<‘‹§'A$ýwÇó·‹¹©•Ù׫$@h’`¨¯Ý×w‡À»üê),¡b¨ð릆#L]8ƒ¯/uO‘‚Ĉ¢nîÈ`3Àø6ze#|EMW<8ñ þY6‹ûÉOüÿ:ü_dºíº×eynGÙºÛŒ]ø®t²[¤ôÝ=¹®ðâ—dys‰NÖ®(“å2[_ö9»NâÅ[¬¿»µÊòÀZ}€s¾S ¾SN½ëàâ!w7£ÿǵñŸlä]Í€É~üîs‹vPw±(ëcæƒeR'#×ÙõvµÀW#áŸÁ©òÛ#¿ŠáZ$~"ÿ}‘Ÿ·’wX !3ÈœŒ‹ˆ‡zQS¯`’¸Zžà'’› ¦»¤9¨ ¡X pŠðßú>Þ†ŠpÑñ&%ï¶.’‹ÿúe{‡™ÝÔ8F-X1ågûÜèÚj¼Å²ÈÝba!Iëm’ÛqÙ%­ô'tØ6«Ì VΓM34y‹ì6eUàù¹Î–°e?¨\aáæÃ¨îwgX¯Ü¦ó-´f¡®6Êçm  <6•_ôÍÞ¶ 'µñ¥õEVÚ‹Q,HÄBW]®nKȸµF_3j•²SÓ"àà`¿¼8}ñüÍâí›×Fûw.Ñ´æµ{¡/=Šl£ÓXkVò¼À?0L8wm 9^ue[4ö«¦mh \ ûÝÉðÿÀZ®îýwÀèÇ}Á c.7YˆÇÆ1~TKl?'ý¦×Rd%fþÓb…T™ëfƒ}oú*pŽ¥Xtu¯õ³±ïvm¦0ÁYÇÚºZú'ôÈ(ë endstream endobj 6431 0 obj << /Length 2311 /Filter /FlateDecode >> stream xÚåZioÜÆþ®_ÁÜÀ;ž{È( 4²áØMSK)P؆ÀåR!.¹]re«¿¾ïr¸ÔJŽÜ ma@;3œã½'ÁÑu„£×'ß_œ¼|ÅI”¢TR]\E4ሲ4RÝn«2Ϻ²©íÂÅ‚âønA`cÕl‹]~½/×Å ;~_TEÖvB¥ˆ,>]üxrvqòÏôàˆDŠÂÓ)¬¢|sòáŽÖ°þc„K“è³Ùµ‰¸Là·ŠÎOþv‚/`#*™Þ-I´ƒ‹ïç¸Ö¯Œ0S–áÛÝJ\æ—ë"×|ˆø~»qg)_ö Ï|[g0qfgû¶¬¯íЭÜùè?÷vá#ØJ NupQáÜËutbU5¹Þw ‡2¢ó¼{PœhF‡¿<‘VÓEÁËWRŽ€£%å 1â¿Øí´Þ›ÝeÞ¬‹à½—¯@b#ñÁåÄ| ¼ûm§ÏÁcb¼òýv-{ù¯%^€Å†7ugäö¥›Í’ñ9ŽÂû“úP±`"þÒiƒX¯´úšî™ä)Ƽ-¬6¡Pb¤hÒýîVûX¡OÝ/¤ˆ_<. jÀlJ׾ͮ\ÛÜ1ºR©§ËÑâÛÊ îR(QI´$¥blšàgÙ1ú8ƒ;©—[^noŠÝ¥%*ë¾1 AŒ†ú-êüQ%E4%žÆ²Ö¤l÷Ý3µÊ`Sªj¾RZ;2fü®VŒü–Ì¡G~áV6V3'qàaIAÍ$±·o³]¶ ®ÌgZDzþä•Ù™ôÅ‘º:F©J{Ò—öÈ»rµËtÇ&ûKL pü”º[–D¡”±)·ú óÎC „WL'œÕ¹{ëR©¹gðò"ÜEa}[÷=Ô³¤jBÂÛÑk£4'fªÃs[¸ÉÛ÷ߋ˷gÿøå\ózº"~}f?m²ªƒÞ(tlŸ¶DSO4˜Z¯>ç¢? †T8G"@üÉ„þ?›ƒvìün¾-òòÊñõÓ/ïÞÙQyeë¦sƒ¢Xë9ºÝ“Ûû윰)R∺á=³Ö;çÄÌùðáA\c sLeäj•ÙwŸì¦J@0žP´[m<ð§»Ó6“U³WÂU|ì aïFÎ>R‚Å(¨F¥÷_lY8ßçyѶNÙMgíÇŸËÖÙk`ã¾~zbj·]³ë •¼-%D#1áó⦄ƒLÒøj_çÖUõl=¬ÛT¸oZÀ0"±IõÔ¥úI¸&ã(ñY¸¬çÕ Å™àÞu³zmß°ßìŠéãÎ≯¬»fîeœ 9Üù Eщ¡A‹¥”)Ä=”åÝ´nøKËhÍÌÂ粪ìhUX‰3¯1FöµSfygª¶Zªâ«]³™á¬^oPÅÌðYF29áŒL$ˆ$¬kúRh*°ð·™ˆäÌê…Ú=\‡Úžô¯ Q1ãžÃ[Þىѧ‰B½ß (>â7Ž€º©—õ¾ª^Ì0§Ë)<ÔÝCQ„uÌ´}ÆL@NMz‘ ä¶…F‰”HsJ”vûª¸.ëÚvAãøl§«0±¬êÀTÌäDÝ#é¹ÒÍx€ ÁΡ÷[ð·>¶}.»›É­“§Á#ÌïÊÍ·YÛö§³v݃#þʺ¯B ûÎLÿÓ5›ùuÚ´ÍåÐ~¨$™¶¹ü‘6×4¯AdÖwA¶ ·BÿI“ݵ˜«D4zÞ ¬'sçYUikÕãÍÞÆfVÖeWfUù¯b6Œ@¼Êßcadh‚lƒ«áÍ&7Z13÷ Æ FïP'\ߨq»Ír·Û›žt= ÷U§Ã\à™Û·6JÁp»ƒ˜Uö—˜¸®Ï7ÖŒ‰Lá$4ãJ*$oû ~¯öàÌfé,HÆUc-XqÆ#÷A©Ó'¢ óT½yà …{ D$ŒsèÊÌÔ[öfhæÂ#Ó¥³¤¡Ž–ªŠúºÓvr3£/hORJFaŸ ¿Òñ­q\¶ÍÆ1ÑIÇ¢ö…‹ç 4Ö ã¹w« fâ8TS[zœÎDøÐ¿ÉF•lYçÕ~í=|½öhevuEûdgV¨ _ë¬ÏĤ ÏC OŽaR—e£3ËÝ×bS¥Ã—¶•ñ'=l÷Ûmc­¨óÀÕéÙéÿ/PÈòn¦íM9Dõ;«Äï®Rsp•/Ÿ‰nparæ¯Á¬–”@Á+EÚÿCØ•I¤Ïa!«ç*5«Ó™S'Ë.„ׯâÓq‚èý}§Ùr¢k¡@¸ìl  C×0Iõ~s9jwh š A¿9´D 1h^þ‡ ¥I3’¢Æ¥Ø30&wÑ®ù/˜Dø€IQ4ü÷€ß_²/NIp“´5½sچʇOÅ7](ÿÝu2åpE‘¦Žc,þK³šNS)-M!€fÁ¾ó€\S?H¥ÔÝ›Py®{ Û6]ÍÕ«QîñÕHw”‡æû  *öt¨*ùí *>UÑ” *š²)T¥7Ø’ªÒ»ŽCU ‘¡2"yØça$=ýÄ©Òù·}•ò‘.¹ä¶{Ó›{ÉÐzÀbˆ»À 2éO«¢ç‚'ÙvO1”à4Œü€L”B¢#)¨‰¦M¶B # M Ñ¡|m’ŒhS"&\ÃÂ<Ú”Ø.WoÑ&X ˜XÀàmÒ_-ÚÄ™²h,E›ÀñÓ!<=mJÏÑ&G¡C› –S“Œ=F›Tù(2bUõ ŽšÁ,õ×mRÒY±rhœÐ&åÑ&Xv·GÚ¯{ð[ëñjsÑærƒQ;RzHïôç7sù‡ñ²ªmæà®Éþ ¥gÀ*ãà>E  £òÉÿsÊl[Ï!é—–$"«â©!ÌõÜ?¿1Zåà lè ; ìßÕqÅi endstream endobj 6454 0 obj << /Length 2319 /Filter /FlateDecode >> stream xÚÝZ[oܶ~÷¯Ð£6Í*")RR  uì Mæ8îC‘†¼ËµUïJ{$­SŸ_f8Ô…Zù’f ô!É%çÆ™á7dBïÊ ½×G?Ÿ½8˜—©âÊ;_y1÷â( ¢TxçKï“ÿvÆ¥¯«K]•õlÎãĹݮóEÖäeA¯ôŒ‡þíŒÁÄu¹Õ ¿ÞåKýœÚgz­³ZS‡œlöåü—£“ó£ÿ1%ô±Ž‚8Œ½ÅæèÓ—Ð[Âø/^ˆ4ñ¾šY/R |×ÞÇ£…VÐüV]yÔ8{=¢Ê€'jL5z„ª1Ž®qTšaÂÉ8ïQçrÆB¿Ñ?¢B/NE2˜ÏÓ ‰c ffÿŠö’ʯt³C…¾ˆýUUnè§ŒnªKy±¸XêÍ»Û6y9Ò¿ýÊþ1š¿ÈÖk4±LüæZ“J $`©”­Ë¬ÉæÿZëâªA©¯'d–2` §][‘ºáhÅ Nú7$ãnZišUvv¶ücG“ôÒ*[#|…Ô‹Æ®€ÕÙÅñÐG&ž3¤R’ FæktAÉýr…_ÖJÅýE¾½6~‡œPÀ?úaWëe0› ‘ø§è¥eEã4 mm¶kã¦0š¯èÛÑÝfËe^\7Áδ’4eIuV¡žW&\ž;dÜ•_óõšZ—–I¥—»E'满¢hH´Iè£ÐÈæu ­CبE…!d0°ö#bjJ© –ßaÀÀM œ . .3<öÏîI-JÀïQLZt^^å”<.¶äJ«ízg“ͼM1íêgô¹¡!øsG»šv šu¹±“ч¥¿Ý5Ô…À¾%ñt›ÛÎÙé15c‚ZÎNÀxkÍÚ&œÖ„'S¿¹øq€8ï¥&æMY « ¤-¸m èÁ >0ïæÿˆ9åá0'ŠÓ‰S6På«ÃbÍ0ÔLz¨9ð{%ýïDS¶!c¹vuv5‹Ðç’‹qÚÉe–tµíÁì†Å?Ddb3—úVDÜOÏè à‚„ÊšË™@~åòÛ;?8b‡ š§nB>*â°¬—Ʀõý¸ò±8<:Ž˜ "Ðcnáï“бúÛÑ1ßGÇæ„ëA­{TCz ÇÉ"æï©àغS,†þZ¯S} ÔBõñÁÝEsJkm;oÏ~–oO~ÿí#êúr&¥ÿú„~Úd‹ª¬ïƒ™–õXèg¶!ÚD1:F ü‹“‘üÇÝõ^ íañO¶¿Õ‹|eõ2‡ÐÄŠ¾çlCë%ÀÇ ¹-ËU"¯0 Ù”ô½ìáOçÓ’LÕ$LŸC –ä·kqú^’x,lc ÉYº¦©ðÖT›Kï[ô!º¶" Cƒá¸èüÌYøPÎJ etñ’ w‹…®k»ù-VG(Z[3;>ß=\ ý ËUeÕ&‚¥®©LQ¤œ*S„âƒ2{Ãm´ †Å†10´˜ïÔAãKy8ó8ýûô¶X“Qʦô@e¥ÇÌ[¨Ží¼ï›à&êiÞëQj¿“@£T ±Œìe½ÑS³Np  B[—t¡ @¸‰QŲܯ.¹}Ù×¼^±Î=ÕLè§Žjh ›(0‰‹sZh´ ʾ[‘xnU-0í+‡ð*ìqx’BÌ¡TwL$ÅTg’^ܺ—Ðlb›È¥p7ñR_åEa_Mùšº½ªÃÚOO‘X3ëY(GÅ7¦dл-Ä[›Û¾æôÂ2¬<]Öã|¼Íêº]ÝV££"´]Ò‘,¯K ŸúèÂbDPŽâ%’I0>{òCdØ£?È,Íó!:+¶7ö¡Žzy‘7y¶Îÿ;õ¨˜BvxB`Ÿ¸é )ËraöÄô,?|°×€®®©]o³…™ô΃ãM«dÂÝÚ.D$cKrìº5>=¤Òc\÷Žj™I¹6u¹Ýü¥nlDoòb|»‘mÊ]Ѻê…$FâutÅü8õÄßmÓ6¶ûÉ^ìnâÄkê“\à“øægEûuhAéÎÕ“ÿ/Àä{#*Æ,’b‚ã&& àÉëŒ.tìû)¾øá!¥þ1^BXëvýnnoôÊ®˜±´sWôòÃ{ dÒÔà¢Svíà°ÚÿˆÎ!W endstream endobj 6359 0 obj << /Type /ObjStm /N 100 /First 992 /Length 2129 /Filter /FlateDecode >> stream xÚÕZÁ޹½ë+xÌæ@±ŠUd0Ø]ÃI€0l61|ðz…ÀÈbÌŒÍßç%ÎXš(âÚ=š ª»«ÉG²øê[%K )”¬)P67(p-npR7rP7j(-âœBÍýŽ…ZÉïH0 9Õ`šWx„;Í}ŠJÝ»À“šwR½e怒=©ÞM‘@…ºŸªèV d`Õ8qó® VM+É÷ ÃCÿèƒñŠß+)ÞÅ=î01JÎä-W¼á#CVsË$°Ró§“@ è¸gÒïiàfÕ­Јc®5d.޹ZÈ’¼eKƒ÷~Z÷Q\¹Ÿáݦ‹ÀjŒ>Ð¨ìÆ†ùŒÍý`¹_éëÀnX;¤-÷9µ ËçOžî¬áÂþÎR ¡,…´ä-·4eQ«A©ãâhÞ½Û‚ŠÏ‹$²ûÜû°´²¹…P0L,4ŸRïHòŠØ&÷Ð<³£ÇüBòΓ‡Oõ÷#_Zë­ø?ñ%Óâ–ª>^¡â‘‡õª¡¦Òüb½s̉‡££b¦ôöÐy-ìïâ_­Xªµî§Á’ÇŸwiÔç¹™}`¨&ê#ÏŒhîÑ„´âÐ$gXÅ£kiµ#ðð¯%‚e´ÚÜ“hm÷†…F¾yÓÞ¸yæMÁ¢Ð0½nqhÕ§I$‡f}D¢¡5s¤ˆgJÔ‡„'”¸IúîêƒBÿ”Ô£B|7§RyõìÙjýæ_ÿÜ„õwWWÛÛÕúõ§ŸnûõŸ?^ýcµþ~{ýóæúm¤wë?®ÿ´þá-õ‹ÕúÕæÃmx fˆµR96ìeÄOlŠk˱J†ßwáÙ³°~Öؾنõóð»¼ùq{õûˆXù&|ûí _ë}.Äsʧ€`+ÑrH¸P,ˆq))ÂlM|Ž(V³3P¸ñrP°b'‹Å—Ä3 ÅÒ#ÌŠÔè4š;4ŠRÊ9(ªŸCyÞ"‡(:xÖ?þõoü]µ"¢8\}úå—w§ÙyaÂ)¥˜@"g•JôÜxÖÑÒSâã‹íÕmö ltñ$Õ_yádŽŒ¶¿ò·Yt<ä‘+yÏïŸÒ /ï¯ÄŸI¿B‡ë—×Û¯7XŒ°~ùüEX¿ÙüzÞ®ïË÷߬Ö?׿êöÆ3 K€W¾Œ7ÛO×67»¬ØïýeóóÇ÷ßo }å rgmŒ¥|ùþoƒÛmïØ£æ÷<ïxzšßy2 Æn(ïŠAG€KbòÝP,ª“cÓ˜rým!ø•“Kô ¦-GÏ &€hI"7º$ÎD‰ šâä2†¢’_„²8¥Ê‚³’¸àJ®-2TÔ”V–d+ìjEÏP|±«Æ …Jâ¢(/9)lˆRÀ”9(G“Òy©Ø$o8žâÍc§“¼y䈱@mžw¤[špErƒŒ>ï˜ ”=áÈH— StÞám7E퇄ýߨý0 |Ní_Læ»¶É|‡å<™ç–yÔ]u×Aݵ £Ãö†¥aŒ\`¼(Ï3(Ì¥7ÄŸ—v(Y±)Å«°m¾èîE—µÞCA²‹jeÊ¢”†"*zµ2 ®Ž½4¸8’A®‚L£¨ô¹j‚D¬å)Èu@ä:eáåÙÉÃD0)¾Ý/Â<%_~Â"Xp[ƒ~·K†IÖ((Œ÷@@õ£— ë†*ËwSâ²ÄšNN‰äx/ÉÏgàÇSøØéd>rÔ,'²Û±c2¥ç³`÷ðŒ#µèç\g¹I'­‹eÖeŠ&IõAžõC¬/γmÔJm$Ü6ny¶<ÛFžmmgøiÝÞàaäaÈ’™wÏ£Âä1Ua-K~Ü v_ë‘¢­õeM±^î¡ Ö¢i™†B‹SûØÐcyœ ¨É%—Å ™…R+^Ô¸8qd™£˜^tyrë‘qËR°\SPŽØý+%zôHP•÷òw ‰™-'Ù…Zÿ³‹“,|þ¬nÙ8©˜’‚íËX¤œý{J?oÎ@Tõ²"ÀÏP¥ÜAñmŒ4eÙ8QŽÍk‰=e èéw‰ëÿ84¥GOè‘N§ôȱ£•'ºUìXÿ*sÖåilmÆQjôï&ÿgg³’é¡ÌàöÅ2ÃO$wª€Ê0ê0lCTpÆP«ÝÅ`ÕFtÄ¿µ×.–gü5–Ó¤;p<¥ÆŽNª±#GV5šp,möãÇÿvRy¨”¿\;å!òH2’ $ãøE†R’!d$IFƒ2ÔÑ Ò#h'µØvBÎF_ôT Ð?–$0Äd&Ð ô{ãaK]¶Ú³¨|Å^TýWZSP–%ÝR!èŠbVT'geQªë3"ÅÙÔê—c>÷£…E+`?hÖþsÃIXÌsH–]¡X Åk¹?Rò3œü…Gn.âîêA´> stream xÚÕYioÜFý®_ÁÃÓî“ÇXÀIdñ6‡­,؆Àá´$F3C†CÊÑþúTuõðJ¶WA@€ÔÝìãÕë:[<¸ xðòäëó“g/´R–F2 Î/™h&UÄ:a:UÁù:x¾^HÚzeër¿XÊ8 ŸWզȳ¦(w4ð­]HÞ.LÜ”•­iøe[¬íSj¿±›í-u“’‰Å‡óïNNÏO~;€‡"ˆ%­YÌã ßž¼ûÀƒ5Œp¦Ò$øèfm%ðw¼=ùé„{Y8 g2R8;A ŽßÌI§ θŠIà›ze.ò »ËQÞU 6E‰DÜ’Kús:žCƒë &̨WxŽªM–{ñ÷mU•¸Ž‡M±»ò¤ž>ÿ–Zï¹áD"lÒÀ¾Öó~ ûÆ¿îV›2Çy7°H0ÇhGIGä Êkø­“ˆ¨™5Ï^DÑ€,¥ÚÌ€[×ÈBY_äåÚŽÎ{öˆ° ›s`ÿˆÓ» ¹¼Åµp ,I5:>,Aè€ÿWÊ<PîÇÝïͺJ†ë4K„9¬ÄEv¡Lø{ƒºl8Žìq›æ‘ðb¦”¼±t£ŠÃ%?€0â,–SOnÐü,®¢åлyú8pÚ°8I¦àÚ}vµÐ¨|€[J‘°nv)KW·=ÉŸL"0‘Ž`‚ùeÁÓ ¶’wyQ]Ûú‚°d}úèKMÍDëÀ’ñj*Wð°tÎ=æCwœ0™v7ðÅòÔí‹ÿÙ Çp-93 æ#®wí¶£abc*eÆÈ‰y§ñ‰¿°«^¹€È¡d‚wÏR‘ÐîUVgÛÑöûѾ+v:h\(!ûœš%gi×KZrV¬êŒ|éÝpg¯^þR¿ËRÀE)5Epƒ '–4%fZš  ð¦}htv¦9‹†6º Ù 's;Vã¨wÂëÁiƒP$×EŸº·¾óúÍ׿âõé/?¿E¡Ÿ/Œ _žÒ§m–C´?hÇ´?úЃ‚ ª5>†ð¯'Ø¿q뼆¬ñ+߯l^\z™¾ÿùìŒZÅ%ýÝ•oX»¶ë9Ìt"A–ä²mU¡¸?PPÃ1ìfM¼ËèV„QLô™AïÉGÒƒãâîî²ÝšŽ Ó)k—4ÂAÝÙ ëUÛP»WÃ¥Ž4ˆbir–7-Ü—›cÜ ÞŒ ¬øXlüü•ßcí/n/]ƒ"V,á©÷ü¾¬ËíŒüPHÞ'F“œhBƒŠY¢Ä†Bc(8:Ó%1SR ‹Tgêο$f"5 dD ÷ü$@ìž&8‡Õ> \.4¨cMºhsŒ_ï*w1*_y»r·Üµ›ÍÓ9¶ÀðÓÞ=õù GJ¥ÂŒOàk:íéáî{„îÞ4ærñ$b¯ìU±ÛùÒeà­±+¢Â7FE…¯Xæ8ö\•y-†ŽGXÕV ýÖ~,škö»Ý”4¼òý*Ûï«3¿%d°†L–“-w‡äÁ wÇÆšhHúŠl³9¯më[ P^ht@ÃëÏÕuÓy÷ÕaƒÒ‡µ.{$Ö\Ö¨¨íb$}mÁnÉâ ïo`€îÊ '°ƒRøÏ|5øØ¿=ä Ùf_þkF¥øØ?ú’om{ `2H=ñÓk÷)õôM@¥†q!§oúo®ÒI„{%d¹OP¿G Kg)vN"™²$îr¬\J…µ²Hn &7æ>e40~A˜ÝÍÇ«qI}r°¸©çJ!×Rj –ÿÞØÝ•«#®ç Û0÷ÌCôz…ŠfTˆfgµŸ­õÊL LLæâHwalÞø8¨$‰Áe$rl)óµS8éü`s0w¹_ØôæZ0_—J%á t›eH“ƒl[m¨¦”>”ý¾U¶^{Õ‚Ÿé‘4eI ¤p ç Dí¶¯ôZ+Hm×mÞÁ< ŠD݆{àbÜSÆÇú`—ydkö¹F\ÇæKâ‘eJ€)ÆòÁ‡²Ž­þì4rºT‹ÀØdÙÂå 3h´Ý?çmË‹\z Žî$ù[¿o= RØ!R0yMÄDÇ¥Ÿ?~èðâÃ6ð;ó"´†Ð3ÉSžÜ{ ß{“?ÿ$åÌhó\Ûq-Åês^>ú Žª\Üáž“‡×<Ý”œÖ¹ç>wê-_rŸéŸ’êùGÚjÿf0Ô®)I<1_‚r‚¥Gþ%åx¬çrœ…ýµÕxú×Uã“G3ªÆ¬è«qìåå”ÉúoŽo%uÑq/cðÑÌg#ø¡ªKê©·ò!¶GÕ $3O-`ëèºÄì^W†%iWšÑ)'lZÊi"JpÀ!*­Ðæ—D‘Ò1Ó*{* ÚV¯Ðò^”j.d-ïÚҳľݎCî4ÿ€ "£Ïþ?Ýl2¡%Âë)H "º¸áÿ%öã+'†TGõOöB©)²?åà endstream endobj 6495 0 obj << /Length 1743 /Filter /FlateDecode >> stream xÚåYoÛ6øÝ¿BVP³ÞÏF°‚bH{(À³ØŒ¾|ÅÎÖ?9±P87úÔÆñ|ÏĹý1ÂV Œpõ™:í'‡½ÅóCŒ0 ŒÀë|ίW2]”w[yµÈ6î„·Q®V‚‰yœí•7.ÁãÌ|¥ >¾Ûº|ܨL¡.VA-C- ÅB1xðë ßÈÒ_Y^O}¿%v&Ô9yK™çÊ~Yr,e‡Þë)HÞR Ç ®CJ!5<å-0B8Â~XÁ]bŽ •§JÁe].²´Ô®u[öøg¢ ç!A¼ RI—ññmùêyü0¯]ެVŽrã#Âk­HòL&ØUøOa¢’ô™þöq¦Þ•`°êTè°8î+á\O»·‰zÜ=Tn…æ¨ÜtXnÁ w«ez«¼ÀÆiúM³zD! ý¡JK]•„ˆû¤ÇÓï»RÕâ!]<¦Yòú-Îÿl"ÁH{"ÁØô*ížép`Ùv8¼îpö3åßuó›ý¸,ÌVœ*ç´«io`c›D‹=R¹,vIu4¶Ø#ó™j+ë‘H j×\úõNµüA§tøZë¶Iu;í{‹Q4÷-YÔWµj[³f÷ÊUTÚûŒŠb·‘EkÛx~§âˆñ°Žëɇqä7ƒf¥©dÐP4Éép0÷påV’S+œ®²uT[þoâreÞÒ¬¼šQ¥ fk—$ö¼¶eW/Ê’ÚïhàC{Hº:¯þ!茢êy•1¾ƒÅIÒ½ Œµ¢¢ÚŠÊç€ÊB¸‰‰¦â©¸a­.4€¥3¤=Œƒßc>_÷cz/šMdr[G•ê–ñ%fLæ2mæéÿãõÿÒ„LLýÿ£9øÿ¤G!6‰æ)î·«Hÿ«èÚLW¹ß ëKÄ”=`öÍ,ïÚBp%B÷öõæóÇÞÍhÙñž~ö$ý8‡@3 endstream endobj 6519 0 obj << /Length 1507 /Filter /FlateDecode >> stream xÚíYÝs›F×_Á#x¢Ë}pw0}rZ;“8“imù¡“d4ᘑ * 8î_ß½‡°â‰O:í‹€åöö·{{¿]NØûìaïõäÕlòò4$^ŒbA…7»öh"ÊbO† cæÍÞÿ, ÜϪ«¬*ë`Jeä¯×«5—7ð6OVùßVœ˜K‘ÁÈ;sŸæë›6ýyv¼CÞy@q¤`Ê~ÃH†Bðàå©=øØ›Ò¼ã=ôYU©U+«yZ.2ÇÞËSð·çR‚÷mA(ø¢ËIlü¸Ø¤iV׿˜§²1‚ËymÆYÌ®EàêA]ýª¬Úd^dµå—ÇVêA™ž [ÄÐŒ[¯j(«Õ|]•åõž«¢®â†k¶±0"ÛË$mK½íXUs½° »N9cpër+,ó·X•C/ºåK«`7Ô¦¨óÏE»ÿòB»)†ÀÂÍ•£´Ü»T³mŒ)GGO<”ày„å“W J$"þ¯?ØèåÎÐ:EB²õÃ(`{m«{kDz™Áµ¼=-Щ4V&cÄ)ÖI=Ø0¾--ÉjU*·ït#jhpo©G4ŒµAŽä—ƒVr„Åp‘ŽíçzÒ;9 ö£3†  ·Ž?ï±Gô ÇÛJÝGwÙN¨9åºÊ²¹»~ªh 0Á-ÍU ´©!œR¡ èv€CQc™ te >/ìöÈ·ÿ)¬ÙUY˜ºª==ËÃψáß9PU¨xô¿9£ÿÍ@JˆM ¨ (€2Ö³ÿFýþFG8ä±í)2a|ˆì0ŒoŠ endstream endobj 6540 0 obj << /Length 1909 /Filter /FlateDecode >> stream xÚÝYßoÛ6~Ï_¡·ÙEÅ’©ÛSÛ¥A—¡Øšìah‹@¶éDˆ,¹²œ4ûëwGR²D3Nº¬@7°$Š<Þ}w¼ïHÑà2 ÁÉÑ«ó£o 2’Å<ΗAƒD¤DdQp¾>LN§\NT3SM½™†|¢ÁÚ (‰²4¸Õ½VˆS¸–ÁÙÑïGÔšA í)áq„½c4ðb¯ñý}3Jh”ƒ¯›™¼˜_\ksðïn*'¥ª.Û+ @ØÙ/ÚmcQ0]Ì}½4×öÊš¼Y«yñ‘FB-LÃP¼n(¬˜byׂhµ!£ÞÈÞXNS´(ð/ÒØë6‚±/ÞÄñÀR„\r`¨jtpÝ\Ìë…Í÷â @3À „SÀsŒ’ºë ¡0ŸŒHS’±¤ñ‘JjäÿSý%áÑxþºj5Ž_ZGó(Ž$e¢‰ƒÔ4’“/íó§éEp;ÖHUóön­jÖÃhûã*‘t²)þR­¹vŠB4Ìô«6ã~0I2X1ÄnÈɤuíp0þÙØÜw‘ˆÞí\Äü!÷À¤F©!K# zBJ±ÔH_çM¾‰ôkG÷Eõɘi<†÷º8R’%Y§zh†üZÌšóÕ몢Ýmíij¥„,#Wƒ;ÝÙ9‰“È™ý¸šÛ¹×6;BãN€3³‘0ž¹Þ¶vêkÔ¹s¿0î÷è3HÕŽïpEoW3ˆáYg#¸öadõyÊèd[4:)¡ªµ¹®r?ú)ïÚ…”Ç£ˆ±†²Å ãql,Ž”»Ní2ëÀÌ¥U^zU{t˜B‚¢™ãü1Qø×Þ Ž0‡O$ˆÃTÀ uÃè#gôP"’ÕT¦;ScÉÙv>W›ÍOÖXàP·ÅÆzÃbrªMîicU{{ÒÔMø 1_ÁŽ5†±$BŠ ŒIÇôˆ!‚™÷b~¥æÓP"¡AbÚ®Fùº^á»õVó™iËÍÅ?IÂT€¼!A˨ÕoÎÊÚHÀ´õýS% fкFk÷S1£HSß ]ÊoD—|¬®YÄã!Ò„¼ñ>ÏÍ1ø»aÏû<¿AãÚ§)™09°A£C U=¤cÈyB(Ï,Å*Žåä‰ ò:íé·Ýä—S ㆌ$YŸpô,íÿ]ü€Ow¤¬Õ[äm~H-(AÄ.å?ƒ:˜éŒñÔhƒNY¼m˜vlÐv&͈Œ3§®ê#ϳ€!IR!¾A-kfý—R£5ëc~I’X8:¼Fouˆïª)[HjYs‰RÇ{«¼‚«Gšã¨Î!{…‹™x\¹ôj —}¥#àÊS³À¾Îž §]tÐÁŠ"á±Âjrøf±Ó‰x½HN]uût±£ìÃéûWòâôøÏ?ÎPë—S)''Ç3æP Ü½ú¥ûLàSš“D::¿íûëÇ.ïìMª‡ÞWv; —Ié9³ž¨J5y{ÈW^ê nåÒq(þÿêÑ]Y9ÔîüªÀ`çr[A]Ç&vñ0º·êR1½X˜iýRïØh×5d–ÀÆTÆ»B":˜” @yÖ³má}£Wfã“¶£æ¢òG.8ú\‹äËRX]EuéÉSÉ]ɤ|9ˆ˜Iß§XÌÉÓ½0Ù4 ï‹1ª¾o])Ä8RLŽYçíÒc i”=v¡÷eI¨aÆuHf hµðȇü—pùR1-„+¶ª«°Ú–%¸"¢pÐî.ëƒ÷·EYš¶™m±C™KA° ¶‹ÕºT+Uµ“¿#ˆÌheŽ{`—Ã&m„øÀi?`h÷Ljˆ’LO@¦¡€¨;ïN'óy»Õ{ixïQKo»†| Öz0³B657}àÀÛeS¯¼ÍH,£ýÅDï/¿ß!…ìNÓFe°»î$”séh™ìÛ• ­Àd»;äÖáöNr;?™!(‘Ü©M\¤‰[hí<"„õ´UZ§[D²DEFiªñà ’Dbo…ùH‰žÆV[[öë fvþÆœ×/lkª—%&+ý Ëêe£`c똦7›ëÈýTó¿p{¥*sWØ Ë ,…ýj椒ÊH•ueªË%•R µ z§cV9ëj”¼ÜÔ?zÀpúÛ½z—äu$,ïö¬ë2tŠ?Ü–èlEܯ,Ã]eæ~Õ|ÕÐß*FÖ¡¬h†[|Þ¡^µ.”Ï:ž‘˜õ‰ÔR¬4»«M»ÖM±*ʼŸš-æEw$x/v9ëÊ/<ÅÉû³FO¬÷ÔÜî©Ýl>ìUï%¾4î×>y¬/`‡ŸM¥/ºëH–„ÇþXåýôÕ(c¶ÔcQŒ—¦¸ñÉ×øuijÃòL 9"Y¦Vª®ƒy¯ÏÌÔÒŽ˜ýÕè0îåoomº¯lê’2m6£ÒPûÝ(É endstream endobj 6558 0 obj << /Length 1664 /Filter /FlateDecode >> stream xÚåX]oÛ6}÷¯Ð£UÔ,I‘”´=¥išuéš.qma(6Ó¶%O’Óf¿~÷’”,ÉŠ›-°a`SŒHž{îÏ5õ>{Ô;=ŸŽž½Ì‹I¬¸ò¦×áAì…"""¼éÂû0>ó¹ëâJyéOx6›U:Oª4ÏìÄ ís:¾õ¼¸Ê7º°Ó§Ût¡ŸÚñ…^é¤ÔöÎ ó?MLG¿à¡óBG ÒЛ¯G>Qoó?{”qä}1o­=¡"ø^y—£_GÔÙB (á*À·ó øÇÞäÅÕx*£„¡5xY\ÉÙ|¶N–Æ ÙüFÏý‰Ã#—Ûõ,Í‘’[kËÄ~½LW+;J)‰ý꯶³ÀÆZgUwÅ«s?ãßÜò¢Àe b¸³S©¤–]˜¯|ÀæRûÁ6+®V¹=Y¦ªÊ8—PÀ§ˆ”¥¬? ”={©T‹/êM¸:e‹. h“¼˜Íó…îœ÷ì%Üb6§à•>×–ç¥å÷w€cek!ã’H×+‘ {ÎßµCB¬³.\‚~­z&Q{¡ õJ\¤Ñq_«§0 ºˆü€Ž‘”ên£aRŠÄ;ræ˜õ2Ì@Ig‰ÆU9aRB†*0Ëv,µ ;„|+%!k¬O–Vãª;_Éñ#Iä¼Ô%pmËä³/09áb$Œ£z©Y‚¥ï±€B"XØõ*¤0š»±þ€Â›¢‚5ô¾ˆð¸ññ“ER%æ##Bˆ®OÊô=«¬ó3H+| ¯äA$[iuO¹øÆ7ì´Ã¤Ä‹ìHÖí=óï°‹üCš}j‚¶2—‹ÍÈ~"R‡ !»äuzU$xQS7›ML†:û;HÝ.’8ö´SiÐ*ÑÃpŒEß­³3fµaá¢vxí p}aÖIÊ;ÈqUí‘>lwð=°—h¯Kª}ÐÔoÊ{ O²¹;|ã®v³Ï.9÷1'û/᱋š:ï6V8$÷XasއˆQ»*âl8ëÃm²xG~©ÝÃÙÅs9;;yÿîQùRŽOOjgÌAîÜG½;Ú‚æ è|[9ÜàHŸ å$}îá꩹ú‘UÃî¸HZîë…¬ÝãÖ\²ß‹@p{=—P-ì(¿vGvî&E¸h¼.%® Ò\ò^´Xù4~T·è£d5¸'ì%ÚH8¡ýtýÈ=T9AΪ¦N¸ä»ÜÎçº,tFW7ÚFÿ—´tDtbªÀ¬ƒê4@ÍSÚJ Y) ŒuBã¸ÐI…{Æ6câÔ0³FÂ7`±¡Ç~(ÇïßNÏgSãÓ÷oOfÇ?Ÿ]¾ûž·““ðc4ßšDD|1;°Í ¼qMäOñãÈÌÆêʲrÀ½Û\¾:}3;ó| p¹±ÚÄm¶,í3·VpU“XÄý¸ê¹Sf$ kŸg+ š;»»¡ ¡ ß+ôgSä 4ç<º6Œd÷2Zç‹ô# „^T¤]W_Öµ%Y•ù¦Ðnà:ý»ó€¹¾›õÃÕ:ËWë†Æ?T!æ”G¿™T¡Úk¦Ä7š)Ó"u¬„½‚¸QöÄ—›ÌÕCVò˜(Öxuz“ºÄ¹ÞfóÝÝRÏ–é:]%.—ªÜÝ)F¹™. Óï›”8•{µuŠ%È:wÄÀuf¤*wRuO‰KÂZR\]¢L’Hµ¢òa> ¢ÐþEŸ<²Á PäÑpƒkÊl‘¯g­²ÓÞžê¬ÝwºÕµœ BeRnôܤÊÜÎïömÞ³…„/èÞt mõÁGäŸiWÕwnW ÇXÝf‚ƒªïܬþË{UÑ(ÂdÊ[ðX$†ªßð=¨°ÒÂÈÏVÁ²”s[rr sŠ Wß¿qIËè?ß8µÂa_«0xH÷±ëš@”Ú™7aU}fŠüb¿ ÍxlWµï4{Ûë‡z'¸iõÐeõµq·C„BÊ^uYZ¥É 4öâðEôpE &ŽåÿLQ;tïê Mº_Zφ5EtqÙ覎ÄÀu—? BÅî—Aˆ Ãe·Ü÷ˆw1ñåF»pÈÜI«<³ñêÌË´^8=ÙÜ P¹¹zðჷ¾à„1éPyA8+ÎÜùo_Ž…d$ˆšž”aÙŸ>íθ endstream endobj 6458 0 obj << /Type /ObjStm /N 100 /First 995 /Length 2064 /Filter /FlateDecode >> stream xÚíZ]o\·}ß_ÁǶ\r>H`Hb¸-ÐF쇶F\G(ŒR!É@úï{†{¹²VQ—U®vá €aͽ;$9äœCòÑR(¢2·ÉRÈÕüM DÉßH ’ýM œÈ , £æ Í‚:ª¸‘CËyƒ‚©×\8äÔ¼Æ"¨š[ÞþƒUCÖÔ«@ëEz „Ž¡¢¬åê ð«©—E3ÙL7Ù±PââïV­n¥@9»ŸÃ¦]‰Èa5t…½/¨žjõÖJXr¿–Ñ?ñúÐ'ÎMÐ&™¼DStºô%°šãk-píÐAnÕû””üWÃèdñ^¡>PV‚ºŸÜ*Œ6¬Ñ„¡æŒ²*Þú+ÚÜ/KÀ`ö²«x?ŒzŠš]F·Rš*¹EAÉøÀ*KÛÀ’ Òª¿Ó …Š[5hõúÝWC¨LÍxÌ>¦šÑ8g/‘½qe·¼Ië%ðC%C˜-¥y@ÙÐÇT}èL<Üèt±æµÀª‰Ü0j*ÝCÍÀœ™,Ÿ9Jk×F •ÓJÙBåêïPAÕÕBÙkÁ¯M3‚\­9H&ÌHo\™Cë3c‚ä–†æ•Â*àÕÛ¨¡¡Þ!ͤ£B 3/!˜Ø;ôX/¶CÅ`¹¸¿Û¡Çj1Ú•Ð`²³J°Bm¤Õâ£!(a=–ÞPJâA 9íF‹-'îã­¾”|õÁÄ*H»øÒEà½uõv!/†l^¼Ølßþû_aûõååÕífûæÓßoûóŸ>^þs³ýæêú‡‹ëw i }¿ýÃöÛoßåþ°Ù~wñá6¼“Ü"#OpÓX‹/ù3`²YĸÃïëðâEؾ Ûß_½½ Û—á77(ùñêòwÓê·á«¯6øçH^†w}¥ð]Øþå¯C„=Œ±!_\~úñÇïwôÌÓ"aåw¤1:ꈵ…tÂ1—ˆ—÷_]]Þöž¿’¾ÔÛ®È+¤<ø—å S#Èã7,{ Ý=yÍ„j—ßÔ=÷OâOÒŸÐàöõõÕ‡7ˆGؾ~ù*lß^ütöXv!~ýþ›í·Àuqy{ãy®·ä‘¼¹útýáâf—#û»?_üðñý7W?…ü‚_Í×ï¯QkÞÇ>qnÐpOôާ'úÅ að0d:Œ:Œ6 ëÆü§ÎК#@N^YRì Ø4&®G&hIŸOÐ_„Ðrñ4Û(zÎ%Gàôf%ñG’©ÊzPX)6¾ƒ"™còŒ3n=(¢†B{(`ŠXüyЬ8*d9º (5EO¸HìÑ)¿áµIeÍòŠá1Šæ»ÁÊŠÕçì’Fë!Y&_ÌånñpJ´rÊÅ£%"ãj5:'CÅʾˆZn']<¢zsb!6WÄ3PLøåÕ×cÛY*S‹Œ}9Ö\äd'§TS$Ok æ 8w æìúcÂE°™‘ý˜põ¿§ì$s¾Câ7~ë1…äYÆ„°·ô»¶‘ÛHrd³Sæ¶Vcõ+Ô} &d~ÉHqEOšÚ|K zP„)f³9(«n19샃8äj0CV‘ÿmš¸4ñÛÏ)1vßñ1öÀé11vè¨Ð·gSë>ê(Éb2>îÈHÄœ'©ùÕ G)ñ°/_€º“ôPÝq{ºº£!Øh6Zìüjy1†ðã¡Üx(7ÊË0êÿ%Ü3ç9ìû‰e…+²éŽÒ†X)>6wSaõƒ ö,ì+ØÈO& ¢ƒÍ þ–Ó ìÔ§ê€âG®Š$1 eE .KÀC E,yÊú'%~”j&?)Q'H×–ÇnÞÖú µây}öhÑ’Uu¾_ƒ݈bQ³î4$?8®ñ»»9…pÏñ1…pèô¨B8p|\!:þœBøèWÛCúÕòtú•ÁŸ2øS!Ë d„¬ã(E!ë d„¬úëüÞ¤b[QìŽó¨ì.¶Î@¿X¹M>;¶ ©Öi(ùFeÿ‘Eÿ‚têÛŠu> stream xÚÝYYoÛF~ׯà#å–›½x¡@ر$Mâ:z)bਕM˜"IÜ_ßÙƒ§iÅµÝ î‹¸ZîÎ|sìÌG[—¶Žgû‹Ù‹#N¬…õ¬ÅÚò©åóñY‹•õÉ~;§®-Š¥(òrîP?°_n·iGU’gz╘Sl™X˜æ[Qèéã:Y‰_õøT¤"*…þC¥ˆÌÏof‡‹Ùç(Ø"Z5G>ö­x3ûtŽ­Ì¿±0ba`}U«6÷¸¦ÖÇÙŸ3lÌÀˆzŒ¨ÇäjXܸ5yz—Á#Ì|mðu±t/â‹m´Z%ÙåE*²ËêJwcæ®]Õ…1?Ò—¬Þ,Óóµ¾!f2®`ŸÚ["e} ¿5ƒâ@bõ9üòÀÓfŒ'ÁŒGž×³[å`¢Û3A… ]^\ÄùJ ô½8£{á<µË~Ø:ÝÞ.‚CøA³í »X+y¨.¢l"Ï*•Tߪ|ô÷q·Ù)7‰9síoÕ¯ÃØ‰,®n¶b'‘Ö—f½<.¶ËäoqQéñ*ª"ã[Ór¤~Iè‚B×D²ÎÊä2+½)ÉÌî=)j"&>…<îE„L§Ùw® ”õ„:”QäJd‘@KßFE´ˆ·Ô푟’ì\cÖB¡£9vF¡6нådYDòHaû¦/DEט?@j¤8ÄW²1‚^ôÆÚ)ò|6Ò~˜ÅF÷ÖÔ:˜ìŒ4k wh†hÏ‚íhpœàr×; )>0V5E"¸z°M£¤ó†¾—›[Ñj ¤Ñ¡AR2¯«ó.?'q‚0#{/kKSñz躊''ãJTåÎCô(ŒG~,æà:!ª/Rm”NŠQ¼|á,ŒsጼëðBßóÚŠ†µë8eù›1 ܯ³âkRš@—¼=Ýw/öç0zùêâð½¬\ ö¿Nõ÷\bZ\%¥°®!AÛL+´¥)+G‘Ï&ߥÅDŒÀÏÒ‡uR4õävºôë (bŒ4îè*–”r5}†1÷›õ}ÕmvôSÖôÀ{·îQßvD˜ArF4l^ÚqëAÛ>™täîÃjÒÔ§ÜŠ89ÌǦs—¢^åŽ^Ÿ­òž^Êv£ö?‡^¬'š„,U”ýÔ}»©õ¥S=žYì^‹›ešÇs†íë]=Œ|Ú&ôÞµ ¾»ôvøwýHŽÁ]äÁœ|K«Ú¾]äE“q+Q~\0NzäBþ+áy<®Ô-*`å\ÓòL»»½i Oð+=„© ÂÀ<võr\eGŽa<Ö·u ”jÉq¾H ƒ:i0š ÕÂè—gå‹:0Å>`­ì$›Î4Ùny³šó¸d(±bOR‹äTʵœxæäöjG!Ê:•9é1ùd–Oà€#tåýΔ§r;â„@¹Ï t2R¥© ;èÙÔ¦%ª;ÛB$YR%QÚ=Ü%tÔýžúU(¤2ЛÇQe`”Û(úÆzÎ!m =¯‰'ÌjÈæíùv]j ó#Nf$ïP-@ ɵ£©DLƒ¡£W¢2d“dbDwo³Z-ÿ‘ì۴.¿O-ïA!õLã+ùjéè@ÃŒiò0>zû—ü°ðc¸(š!)¯¥æ¤PrHÚ‡tÿõ±¾‘¬ÍBe¶ó{óA„øÜ–äRÞ«ò\RÈQÑ¥úh¤§Z² ÿÈf¦·Vf‡^ 툆R؇ïeR}xwø®‘7|$ÑäSv±þñZ+†˜¤uѼoo8r”ÝÍÍ›·¢ î¨Ó·,¥ïÕñG+(f@yîûÍjò ¤,!æ|HåA€íƒ«h+¿Í]»ù´ä=ôxhHÄpRÑ,Ð÷Ýk³Cº6®òòäµùn¥x ÔÛiÉ]n¶¢[úˆÐ endstream endobj 6600 0 obj << /Length 1512 /Filter /FlateDecode >> stream xÚÕXYs›H~ׯàeÍdn`÷)µI*åUôf»Tm*X@±½¿~{`•Ä›ª 6‰Õ8‹ÖJ[Q¨µýš9ÓÇïí†$„ÙU£¦ DÐ<`4ç”ý=MòÜÀëͶÑ[{¸ªUVdm–äÙ¿j·ŒCT"ò¤»ç &½€ a'…¶]`ô—Ê~koÜb­š¬VÝ™M¹-Z».¯ìgS%©ÒÞ0æ¼Í\×ÎÁÁ^dÕ¨íº jP]nÜk´YßfynW›¤M57é!áZòçd'ý1dò›d­¯=»Xœ<Èté´Ž§™ÎŸ“é’3]J°4æÖ€ÏÚÙrNÀUõû>sc$IÜ™k“ àÓ.X6.·›Á.SµêB§Ü¡%oè `æîjM‹(;™Eé„d›*W›^f{“´d>O‰QŸ/Ä#°`DSˆ$FɃÍÅ>¾ÔZ)‡ßc‹å×úR¬ÒU¥ |_õœ8NTs[’°¶™‹>oa=¼cr>»TŸÂïÒ¶;p-_é—Ž{GͪHõŽðï+­¸§ìö¾R²ˆŠ#íµÎ|Ä#i™n “rÁ^`À0T]ë磬Wi¹V#}o¾– Ë.+{${myŠÁ(þéohªµò¿×~oPB^êGí®˜>*(ÁQ´«}IÍ™ðïÚƒ3ˆ1X²‘EN¹G­‘ˆˆ¾¼Ý…DzÀý+W`oØ=¨†€jĨ’ýYòÄç„£&_( Sj¥WIlFâ= ÇËYV\X›-¶P[wûxX€è°÷<°W>e—ub ò~(ÄÈù?²ÔI HˆbƦ 0ÕN‘ ÙDû‘-?Ð]íhp'`¢ÙJkn¸èß«=j´q8uzÏà t=z%‹êÔ2 V n-sÁ«5Ý(óÌ|Ó5žä{E‚(>4—"êtÙµ¯:„–kC•& ;q•úÜ·`òR é0‚¢pDa;Ò^%ë5p[—ÕÜdãÿ¾òõØ·žš}¿‡/ƒg÷•Yø•IØDy[4Ùuѵ Y×ph›r[§E¦ú=5mó¹ADˆÄÈuÒ&9PB3U6à¾7ݵ ìÀ“‹^¦)fðß,ÔÆG/¢é 9ëŒVy‡´7U£ŽQÖº÷#ºáÜ÷·C¢ˆò±ÈãÓÅÑ{âïæBøË£CÃ]ÿ©ÿ¹ˆ÷§cÓ²¸¶ÿlݾÒ|Ò¿¡èùïåül’¯&­WeÚBkfúÂfÒ+Ê^°ë/ ¥˜s úU˜ 0î«¶ù5™åµÛ»§8‚3E»+?™ÆÛ‘_­…Û5Rñ çH°i·Ì„èÉÞIBk0¡ÂŸÚ:E?¡urФE<ÖÕ•ééZ@×s­‡C Ë]Jï2z<²Ààz8±q`=¦YÏLó¯j%øÁþµ†Åéâ³öâÄ~Û6vÆÆÜM»«KÏ®vÍziõSˆÆLÚ¢nÒÆ“6>š´±§'mžDʹlçk ªŸ¯Ð9ÕìJǵöâ¡Û0¦S ?*Ÿ=ŽÝ;"áâ2Bš‘¥äqº'Ÿþe¼á‚ ¶KÂâ©eÿ Ê› endstream endobj 6623 0 obj << /Length 1592 /Filter /FlateDecode >> stream xÚíY[oÛ6~÷¯Ð£]Ì,¯µº6-ÚC—ø­-Ebb!ŠäIrÓì×ïðbIT”Ä­½aEK¦És¾C~çÆàà*ÀÁ›Ùo«Ùóל1ŠC«Ë ¢AÄ%â1 VYðqþ~AÅ\Õª®šÅ’Frþb³)ò4ióª´¯Ô‚âù—‰EµQµ~³Í3õ“}?U…Je¿D)"‹Ï«w³“Õì¯(8 V5GŽ‚ôföñ32`ÄbÜšY7%<‹àlöç ;30"€#2=;$A ?Ü<}È`‚f‘5øº¾çé9!æI™U7çUs®Ê¶®6ÚÌ;ƒ»SÜ Xj-‡O.C `<ž¿Ãv,)pb \ÕµÞôª>O«Lyúž¿¸ì ƒ>òjƒÔŠÁBB4Þ­ü„¶z¾×(#>ªl %¾¶#˜.äH¾[©©ó¯­fŽÀ󤘗F {Ê«ñ/Ïšmšª¦™´“#!ÙÀN2}~Ox^_é;?–.¾¨RÙÙíBO0ƒ‰‹IªLÛ»Z6•æŸ0ã©¿'ì²®nì[¯Ù~Ï@®AÿŽÇ‡G÷øöJMz;æ(ÔÀŽéíßíìbÒÙÂØ~õ9<Š&D¤ÛJ7ÿP ^…h”<†‚3ÕaæÎR¯:Ë’jžIîGƒ hrQTé‚apˆG°…E4ê°]‹Õ®uüRzýßÂüž=èR ¼£^tT•ßt?æågðüð;æÄó¨Ë‹K»ä÷ü¢îâÞ@ˆ¡®³ßCê¤x‘»G0 æX;EaÄFÚOÊÔéÞ¸š {#ÍV‚—zÍ=¹Kˆ­É„(BoÀé.,š´«}³uÉwGï1'ÇRm[‡dH%&<*ypbŽp$ÇpLZj¶E›Cвò|BîÍ)BÀccáã¬uâQú£ý¢U%ŤLŇ¾OêèÐ?Q‚s0(´Ãn³±5å̦ø_ì·ª]+{ü·¹) aÌmÃ{csWškf™T=¯«zGÓL™Z!X†q1²³¯.·ÀÉž\‰ÝÎfÈš§Nzˆ`Hப3É­kSÄ÷â&Lµâ7u•mÓŽÄ>Ü‘äÙäÉ‘`aqŸ¬€v=˜.[úA°D]л\p8„ÚCp•1¤-'Bc:Ê*Z€-qŸ}Д qH—XDþ™)G‚¤hªŸ'ÊIW" w > U^µëFWƒð¬ÿtr1PÆÝƒôI9îÎøÝ™é¹<Ó´,ÊLen@þa*^ãpjÊ&*¡ÊîèñVG/i V"ɬû®ý:¯µ7a¼»5JêÌ8‘µj½‰C°¯èƒ°ÛÁýÄú‰]½hï/ܧœ?:¤½p·(†ï¹¾J1A‚r¨Öôu† a·ÇÀ qžEô ÌIqè‰ýû©ïíí|ˆD2Žݤ¯ë ãYºÖf¯Î'üÑùôš]4¿¯X×kœŽŸé]ê½Ä)v÷b]Æ,5 l)h“§Ëº÷ 9«ã!h@ï©Q ÂÆçq¦ç«àíä^¸µ6_¶\,F²¿ËuŠÍe›©*j·B]¡ôéq„n‹íßmÉÿ Ûêô‹$ÈWP±ìûßÉŠ‡SDˆÛ9µXBý÷rl:V;.BÙ¢Å2ä1T:7úsS¨Ý„Á}§ºt+tÅ™*¯DzñáíîR5ó¯DµÞ³ô8MKý endstream endobj 6644 0 obj << /Length 1695 /Filter /FlateDecode >> stream xÚÍYKs›H¾ëWpD©h2f€ÚS6»6É!{÷’¤TÆ%Z@Qôï·ç!Ä`pÛIí!Æ3Ý_¿»GØûâaïröûõìÅE@¼Å‚ ïúÆ£Q€(‹½0ˆP3ï:ó>úoç”û²^ɺjæ FþËÝ®ÈӤͫÒ,ü!çû_ç6ÕNÖfùrŸgò¹yÿ ™4Ò|D)"óÏ×of¯¯gÿÎàÁñB ¬âÐK·³Ÿ±—Áú#GÞAïÚzˆàYxW³¿f¸/ ‹z²(Z#ÌB#Æõ:WðIìßìËÔbÔ)¼0ž))aûm£ ½¸¢G/Æ(b0ÓÔš9Á~[çå³ÕaM9b E»µ­ £d„(ˆÑiçFG¨ޏ §=Õ¡&ËTÅþqgeÉÚãNŽp Ñ:œ<ïs81Ša§}ÊpTøûF iȯ¥aÞìdšÂ,Ù»£ ì„j’¢“*D8è¤Bó£ l$ §R*›”M å~Gk«Z&í(Ï^Cö#ŠÜî寛·ÀãCp™!(æÜlY)4ûµñÝÌ|­´£yO“¢0êM½âË›ZÊåF…ƒá¸*ªT}m–àh­,Ûææþsè°–¥yË[ûl̳¬Ì³¨€=9'¬K™É éèÁˆ€lQÁT€t5ÄíÅ—ÃHÇÞ‚ÙØÐÈÓe£zÙ*ß®@Îê¿ãò·ëå.ÜO¶  þB=¸ÿ ¼¯‹~ã“­Ù˜ †¬YRÂ7ûtmþ’4½Âß%MsÐÌëÌjH( ©‡bšYWøìŽ,ËU@$…6,v-Ú‰ 犰 ­6m2鞈âH©0„àAA$Œv‡‹Z»Ž7W€æEO½²®•«!“¿ày=_âXt¾ìÚì"ÏöP¶0ÁÀ¬öV~©¥²€Ž flˆ`º[áЭœK¾åþúV[‹½¶Èål(Îtȹ™jïT„tÀøJié®–±-á§Fb¬×ìÚšå1¡”‰žŠqDØÐWj¯~ûªêORìGuaÏN0ì—š¡0å–ï•.Ô Ùʺ™Ð¼:ær«ö­e·Ñ êEŒ+&xö¹Yž—²”µn-'æî6‚ ~\—¨U"uÃoU8JHn3‡ný‰|W
KtöÃÖ~û4•Mó›ùª 7NvÈëUVoµÈÝœ¦bǸX]Õ'÷Ëdcú]ÁQÀ0 hoBR_f•ùM¾Í ÚjQ¹¶zžÚ·Zé>ål‚SË ƒAû¶Ú·†bR4–L›˜íÀîì=úû°ÎSÅam>·‰íÁ5D˜L[KHê%)¾TO»ÞZIJ{¤kmªYdr'Ë ZuÕQ2˜B”Í ÃëQ%$vTttTSÓ£ q,Æßúâøö¬¢I¯,çÞX¢VOc‰bÞ%‚>`,QB›±Žç–kn=‡¨A8Ž]ÕýúYEI‘gËTuðžÍ~«S½¾cX˜Ç?ó@ÁÉoŽæ»]'­yë±z!]K‡–=ÐQÌíõGbóyûšdšÞ/7VUÞQÞ5gðò(Ì_N7']Ž4,à›XD?uºÐ-VÂd§%PL»Œ™N †GðèÉ[,€W(Ò:JÚbM´7Eá°È½REjÜÖæþ.@‚†nâï¸}]þ’âvýaιÿ÷k{åqÓ×…s b+nžÙaãbbÿ廫Áɲj—dºŠxWª95£÷K0ÉDž±WwP*vꢻE}x¦¹‹âOÊ5üÉrÓá»™ƒ³â'Î4»4ØL¥Š(Äø“§È$°†>0Ãl¦2 C?2@Ý?Ëph£Ùÿ4ËlŸe,ïá<€sïß.nÿþ$ íb- žݦbí¬ö·—÷ê>,à±ó ÈÙÇŠB… endstream endobj 6668 0 obj << /Length 2066 /Filter /FlateDecode >> stream xÚíZmoÛ8þž_¡VQ³¤HêåîS7M{ÝôÒ^ã.P´…¡Ør#Ä–¼’œn÷×ß IÉ¢D;é&8ìb¬7r8óÌû ÔûêQïÕÉO³“g/ó’„AèÍV^x‘ˆ‰H¸7[zŸ&ç~ 'Yu•UeíOƒ(ž<ßn×ù"mò²Ð/^d~@'·>ƒ…ër›Uúõ«]¾Ìžêû÷Ù:KëL?0„ù_f?ŸœÍN~=aÀ õ˜>ZˆFÞbsòé õ–ðþgžÄÞ7µjã‰0†ëÚ»<ùÏ 5bP€{J‚ãêy|½|H`F 呸¦º’óÅ\‹Så«ïóÅu¶ð§rrã3:©w-ÅT_~ñ…Y§ŸS}qïùL%ÕÉIÚø°Ñ`ÚBy£NÅŸïWëRS€MŒ(´:q;±£l‘€_‡ZìáKûÙË0ìÉL½i Ù9«*TuYÍå2³Î{ö@ê!Ä) kãµÇêå…ýp¨ìmcL±Ý‡XèSþ¨@ŽÛ\”E£ü­ðÏãþ>Ab&Û¸)ó¹œüÖ ±JŠoj$Ó<½ˆp.-o2­VNAÓG8 )‰‚¨Ýúäý+Ã]ßýPNž>Œ¯€Ã">äkW§_•)ãkÊ’ÀSÆH"õ¨$>À ±¸\¦MzŒ;ÁTС†Ë—%·<°Mµ‚¾Ž*5vP«n;ƒx²@­âžês K [+Š»«²„¸[u†ˆÄ¼³†'·¨Ét/ !#QÏ™;*ÝqªÜbÒŒ#¸öY¬©oÓ*µÁôÔçÈ–òS^|éTܨ<¤}(%%ÉÞš¦zË›üªJ1Y¡_õˆ¨X`ä·85T¦,;àCnp£ñÒ1â- œ sþÖ¤SEgïíêÅÊâ²~HÇ‹ðØ¥­Í1Ø›ãP ÃÉ)´7SÆîÃÒÔ·CrL»QÅA²@vÙ£ .NC œ²Cœ‚ûS†ˆ8ÐN¥b€ö Œê®)õõ*k…nl¿,ÊÍv×dæ…ÂûÛ¤ ¡¼øêÀ]4¦Ñ Óç$­2QAÕÒ¹®‚”ƒˆ°¤[©œæ½˜8²C’ÐÐ#g³íË6’ŠÇ¡¡ŸŽªàV™±ö†ü3å"[º3Ôm“(wÍ—–оlÆB°¦hÀØrUÓß¡¾ux[½[,²º6iäÀ¢•:4_ïªìh@™w …°°e©°^Ìð§1²8I)Ñ7÷€Ða`ú0z,ðCv‘jI.µ¸ÿÔOesmò-¯š lç*Dt]¤ZurRµ `YãùÊlË–f×9nŒ“ÉjW,Lðƒ§±à²à¸N‡0F÷tw1¡=>mÏm G=:¼;Ùk}ÌF®+;4ÛBeÈ…ðÙ-"þTH6y½Ò'ÖÆÏß·æ{¹r ÷F@Á•U’q¬{êà`ÊcE`òsxG ‹âØâAm†;·A5XøQ7C®PÎ  ÇÖ™ÏP¸Ë WÀ†jƒÆ÷µ+¶o'Zi¨¾¤ÅÒAC .ƒ;³¤¢lôÍŇ7ožj˜:I7pZÚ”û’Æ%½rIÎ8Qá½WKµ&&ŽØ9ԔߕàC(Z;ä¾å뵦ª"},•žÑøA·³kó.]4»Ô¬s9€TE°eHXL–­©ÜvÆ‹ÂT寥`!Hÿ(n]BT XlÕ3B:˧@ö˧|u@°ž“ÚØ(Œ³ŠI½Í½ Ú„ŽvÚê´R”6‘ƒe ª¾1àvêºáˆFpJâh4¢wŒhÔàÅÊH‹Å$ŒLº@ÖJ•ú²¸àKHȺði¦ß}§ömoòuZÙņnv烸2‚‚£ loLÚ¿Ú5&!n³*m2s‚£^WÍ}`šû¡ë@øïMMW€rŸ!î©P{ ÙjäC3hI¡Œï;4›ç%šóíxx†YWÃî1AËÖÙ&+ý›©Ùë·¨Ð_ÌöJ×Ôíï6v”o]£7.I’ü©'oâ‡ãdÅ1˜AHTZ;6• I²¯Êº€Ûwz4eR:hЮ~x.ÿùæ‚!#QzúÇÆO~kÎ…SDa«€Qªxƒ á1¶¡Û»E`Xç¿gsõ p+ýéAì'بļ‰ñœ€š$õñœåÙ KBq÷ÜBWÉp‡a”:Æ£*Üìj5â˜ráÁF-¿©boÀÐcw?(ìÀ¯3ópþþ'9??ûøá¹~îK9yuÖ*cQ•õ!èÍÑ5`„:$¢ªAHÍ@$íén™¦qàtvrb»Í\BÜ2Õ©kLÀ¡Ÿb<¦°ùJ Ð¦ÑÀ ÿ?cûƒ3¶ø7cÈyZØ%jò¾$ãzŒwB·„øjÜâ[¬­õ†L¯WNvúÞääã»ÙÛùLYæÇwgóÓž_~ø·ÞÐUèŠJ­¯©¦Ñ›²>,·ce£vN9ÌÇ ,‚”÷Ïðç¹ñÃbÙ‹Η¯_]Ìß^¼“€zu•}ͱnÑMe1h£¡¸àØÌ-âp!j+â² Téº.]­-µÍÔö›TÇãQ:7Ç·}ªe‚Ãîgá½ÿ£ÂÙꉀ0fxc"@{ŠcLŽéÖÇzË4ÓÐH…ÄŸ†"ÓCeN¶ë¬] ¿«,[™ð[,2«#|þîµiã”ÚàFÅ@ìÛ …ÖCIÿ ÞV¢ endstream endobj 6562 0 obj << /Type /ObjStm /N 100 /First 995 /Length 2168 /Filter /FlateDecode >> stream xÚÕZËn¹Ýë+¸L²àe=XEÆó€“ 0{1‰à…ã#)m`ò÷9E5¯,iìÛqZ­d#Uß.’‡Åz²iÕJ*‰D-)%«F©Åÿj‰˜!´’ØB0MÚz5[–<ªµÔ‹„Ð-gV’‡ºº§'Ò-]Õ-¼&r)!aÄf£…'.e´h‰I£EãÄÜÐL* WŒÑ°á7M¬A I‡Új xøÃu  ®æ:$/!5ŒÖzŒÖZ’"£EOB®£S¡˜ç$ªÀÑ{ô×kg É’4 ËuOÒ£?+› ¦ •0-ü‰a ü‹smgøM  ¬¦¢%ô`m+®Tc) `¾ Úz,†a ÚcnVzª%–è¤Ê%ôˆR%Œ)Tõ0’„U,TìmÉæL!áE‰õ°X2²˜¡™”Ðc¼Ðð“ö˜Ö2T0Çàá8âѬÇÍ%ô°‚æãE‹®ŒÑÕ°š©$/eôÜ“3Å[ÀpÑèE(¹6ÃÂð¹Ü-|XC4y/£EM­H .?ÇcŠ0lÓ*!ÁËë°Ÿ¢…s`Æ‚67Çp¸ÖJ`îhÑtè¡¿Ö#Rº¦Öe`FÏÝ2€¢g8W§1F¥ÔeŒQñvøŸáEÇ_Œí­ªZSï*‹éà÷ÑuuˆL£uĔԘ báÕ£ŒF%¬PÜ£™ Ä^¢• lgÏž¾KçÇé?¤Ãù+,æÎ‹|ùáçŸ_}õÕ'ÅZFœÖÓ’ûýŸ_]¾OÏž¥Ãsh€ÉF“çÃûá£7OQ¥XÞUh¶ù„õÓÌwˆBãåIãŽ' xøþúêÍ‹‹÷é<¾ÿîy:¼¼øå}:byù¯^àÅë¿_œ¾®‹Ë÷ï"Ø)ÚŸ~¸xwõáúÍÅ»›D1~ûóÅOo_sõK:4Qä_a ××h E®7Š__^^¡·ó›DxF¢\›B›B_/S )ðf?>ûñÙûn:¼7ÅæìðâÃßÞç?½½üÇÙ᛫ëŸ.®ÇDÊ«Ã<|{Nã!æþVsÊeødϨHÖ%·È}½æ"µ¯ÇR¾H‡ß_½¼Jð‚ß¼C÷W—¿ËÝÊoc 6‚$5Pã\H¨d¤ ‘Œ<ÿy$Ä®ÛA­™ç'EØ´Hšk  ®·C²¬ŽÖžÕoW5.‹ï¹:ÔáˆÎ¹¡Ör…)1Ú$»î»:D9Êó„"0RU^ ¥°o>7nG(js}V@AñÝI§|Cn€äÚŸÈâ±Ì5?œË•r+¶g>¡žY˜¥gÚèšKPÊZ29ïê±B¨’õE:gA´ʶ+(ØpŒ E]±VZeSG9®Ïâ)ØqÀUoµJÿ’AMZùˆš€c1ê_œ3.ÂR>ã”qh <™BÂì‡f?Ô¦0;äòg ÿQòŸð,»°çÚ aËqظ ɶ©bÒ `¾ÝÕŠ-ïºÃ0â§‚ßãô‚š¨Øyhßy?šÏ?BÁ²Äáþ*(›ÒEQ-ØôL$êá ²ɶ۱¹<‹£ŒS”˜ª±1¤=÷¨Ç#Ëý£έð8,#˜§ÃŽß­?…á,» ʶ[ƒ©ó‰ö–µ¬D²­Ãº‚š/^"äã¤6`5õaˆÆÁ–,8´ ž…×á¸5AJb󱊉ÝUüÄ)Æ¥ObÜW¬ ÑÖÖ(•ŠÜjv±ŠèÑ›þßb¨>¤aÊëh˜i@Ãxr$™¤K&é’Iºd’.Ñ)Lö%“tÉ$]:ûQz ÒUP/z»%]qÀX÷$B’{ŒŒHô¨`ÖPÉâ;6rƒîz®iÀâ;ðEkÃî‡ÖAÙ4_‚ý—[KRc÷&Ê;Å=¥’ŒoX‰Æ÷¾ÚžÉÑ&‹ËmB5‹ÚžHºÁóúIØ$΄W!yÒ%¶ñD ÖQN€5Ú0vXãKt="Ø"¾¦¯B‚0~„ƒ'jÊ£IX¢6úž&‘–ÍëÂ]ÄÖ¹—MFÅUYÉ1î(òØÎv—Šª™í#È}Ei˜û E‹ïšvZ‘Mr”ÓÓŠ³îÿýqÏgx¶çÖòŒ›¾ŒgÔÉ*êdu²Š:YE¬¢Î3:éE4Å&½°Ù¡Ímv8¯ÉØrMfc \ÔŸôÜǰ¸s‡ÅÆ­š§¸ÃvÍoï°ˆfê+ï°lüÍ9òK¿…R >nK®ƒ¢›Þ1‹+ ^@Ä¢¼¡¸Ä%Hd6=E̶¥CÅr‰+ž µžÇ]ÛUHÈÁi—ð‘Xž¸Îˆ°:yD¸i›„Qf>:¿•ÚOo¦·ãðTì Ôs\#E±ÅÔ,3é¾a f‡PU+îÖ®…BÛEÀM‘õE9ûøoØèµ=J|þŠåX(Ã&¶È–édšdqX©ÄŒ°~ªð´ÆÈ¿ϵqW endstream endobj 6688 0 obj << /Length 1507 /Filter /FlateDecode >> stream xÚÝXKs›H¾ëWp.3™7°{r’Mv“Tj×VNŽK…$lSz E(‰óë·{0ŠØ9l60búÝß× ®¼=ŸŒž½’,HIª¹&—O$á" b™™Š`²ÎÇoC®Æy5Ë«rFömùËÁõü¬òÍÛŠ©xËm6œÎ{®=ȉD*‰’J ®8ÜÙfU¶îH8#)‹ƒˆÁU¹ŒŸ› ï%ï¬'Eb-½í‘Ýô¢…/”šÝ]ÝöˆÅ$Ž8ÎË}}ÑŠõ®bšqOñsÿ~ ¯ËÕÂy(°=&*ÀßE;Ÿ5Ü©ïÞD­›íŽÝR²ëžÝg¨´.«ìʦ]̬©°ºÏVn¹Ø m¢‰ †¶Ãöàra€m)@¦uÉÕK…ˆ“ž²–¬e‚,Ù†}Nhœvƒó‘3ú­†ƒÉA7ýF]Xöóy¾Ûý¾v¨ù¹Ø¹`¸ø½5tÔÌŠúìVeå3¿³hòP èá?«„‰#I›9JŸfûúz‘Õà€äÆÞ?Ö8ø€Ë›P?Wæ…­ÃsØ]VÅ×Öxä…ý$t×O…î]ÿ­ïÖï!°`eì§b<†)öKý­‚ƒrOXƒ\¸)GXøR?Î !àVt,‚È` ™èÜG> stream xÚÝYI“£6¾ûWp î -H@rêYz2Ë!éöTÝ].l«ÛÔ`pÏöëó„$6cOoIMr1 åé½Ooù$cçÖÁÎëÉóÙäÙ™OœE‚ gvãÔ üùsf+çÒ}7¥Ü•ÅBy9õhº§Ûmš,ã*É3ÝðRN)v?M Ló­,tóë]²’?ë÷s™Ê¸”úƒ J™^ÏÞN^Í&M¨‚¢—öQ€g¹™\^cgíoŒX:ŸëQÇ!>³ª{zÊyÿÚ‡™öah5>Ì•÷ÓÆ‡UGnð„Ø`ª—™Øà®Y²o—YÓ#Š˜I9—ù®ºî­öa_[N€˜íkûÜŽï)³ÎÓÕPïRmx¥£¶uÙžnf­bÙ÷> "ª]¨\QåE|[#ªc ’‚0IãEjšëY]ò·R»ÈÜÙ‹÷á#ìÃ]¨´#ÕOe6sT&Èò;²E8ˆú’®(ÁÇâÊŠˆ¬ØÀ²[.eYþª¿òjm2éç¤4`üÞ)üÚBıõ«"/¬Ï­di²Ê]ëÁ x‚#âÆc…Ý‚ 3%}ïªõ*Ö¥2e¦ß’ÌÖKãñ#¼üo]/ȃ<èÎýwâ îõþÿwç0ÎÞÜŒ1(†A?í( ê"VÖ˜ŒQn(¼‰8K>ΦvOß_¼2©¨ZëâÞì xì”ÒŽ”ý §øiês×ô/ã,Ï’%lLýiJ"VE#M>ÖÈ\aJbYz˪ôÖÀܽr/ªK¥34õcã@°l$¼/¸$âÑ ÉZHfçê(ñÁ"’T{Ü €½z` SbÙa$Z㻞9ü³ƒŠ;ÿ×1úÏ…O@SÄ÷•}aG±u\Ó©¡EÀ`l„ð# Lu¯´…°7ºÿUܘ\¡ÒçZ§¿¿±ÔjÕ¿ÀRè•CKÿNTbˆ endstream endobj 6724 0 obj << /Length 1404 /Filter /FlateDecode >> stream xÚí˜[s›FÇßõ)x+ÊDë½íS’Æž$NëèÍöh´’cP²ã|úž½€!Ùõ¥Ó™ô XvÏžó?g ‹½¥‡½³Áûñàä”/B‘¤Ò/<rDYä$Ø/ÕÏ: “S6$ÛõVC†ý;B`?É애Ȩ±FWa$ÿq ð4€`@LIÌ{ç}E¡'P"°A\S1QÙ¬¼_«I©CÏ'›²H²¥MîÈ^>@qÔE¡ $²obW5`C· ÿ~=þ®š´awg¬»QöbgBN­*ùU”‡:”€kM ß&Ên#D Y•±7¢Í‹B~^Lfù\µæ;9Mq,«·å©¥1¥ì†"–um\bí,OBÀÚíó¢ã{«>…DDÔ>¸omQÎtêVqaŸÞL·—˜1H%Ǿë±I¾ë0÷æµPY_¤,B\HIþ¸vÖâJ1Ê!yEÔ­Èu\Ä7-ó…åEoDà*\Ž/’ìÊ:ÞP©+E2¨%ÙîmÕb¨ZW²Ð¸3ÐöÐY‘EÌñô"ß–W Í´¤=s$YЙû}ÕßNšÛë*Oçu(|³éÒ -m]M¶¶Ó¶®¥jç¸å/—:Ùñ÷«&@™ñÒì!¶1Öü»Õ q’ÆÓTÕ(´þ4K:”ˆ3QYmÊõè"!À®hCrERh°(ƒmëIÚklñ†-F¢¶8—”àc 6ÒÝÇN–íl¦6›_ìS^®ï’Ãé÷Eë·Ûzu†-1‹ÜÕ€fÓÆa㱈ïð}$â°,FŒ °ÉøÌYS“ÙJÍôíµl³½iqþTëçz¶Hmlô&ngåÖŽB¤oÉXZZÿn‡ МÌmÉ´h ,À\´8¸(\×Úƒ}>E`YÈWñ,ÏJ³~+˜£Ô®ëAJÇù­|û<Ó·mô"Ô¹K¥Ê!·¤^»õ¦±`ºœ—( ^óTrÄ9s˜'Oļ•Ö“ÍAWz0D|ý–L‹ØµiÄ䤗žÖÊz¶„kÍ`á¢;ûêÒ³Ço³~T{#˜ºg]ïfix£ ‚ïÞÎ4^%Ž&‹-ì}õF¡‡¹€¤FÀYéšóE£ QÕÞŽ’À—}Õ+Îæ™—”•.Ð3GCœ|<ä종W6úcÀ³1ÀÍÞìÕ‘(žÄIåž5ÍõÏÚÿlü²‘ìü.?ïø`£.øÃH;JÆx”Œ± ”ú…YúºmgU7÷ƒ’3%}(¬îÿZLpøø-­í,/í”nnÞ»n¯Ð9!ó?¹áelŒ·?z;Erá»Nó¸Œm¯už@ˆ…›;g¶ij[4Ñ’ð?‰¸þ+kÖšÇT-“,³ç³¢>2!$2‹Ã&UUiJª›TeËrÕÎíwø>~æí MZë¿©‡öƒê€#.Ls¬å½ooý›€1þoÁÿºŽ¦‡V˜#‰ƒ—Å>y2÷ù+qŸís¿Rå(ôå4z,ôåË’"üÑ ÿÎýûš„ûß³ªî¦P-Öcßȵ\Ý“V}æ)}Ý{nÊ)"ÄåG"$–<2ÅæÒÿød˜ÉìâaM|ÂE׳¿x¾¬P endstream endobj 6747 0 obj << /Length 2278 /Filter /FlateDecode >> stream xÚÝZYoÜ8~÷¯Ðc·‘fDR¤¤Y`N0“`v&qIÐP«i[°,itÄãùõ[ER[>²öCfa u‘źëcѾwîùÞÛ£—§GÏßÔ‹I,™ôNϼya‘ æÞéÞû¼z·fb¥êªËf½aa´zQUy–&mVæÅkµfþêÛšÂÀ¼¬Tm^¿í²½zfî?¨\%2”0Fèúëé/G'§GQ`Å÷¨Y: ¡zéÕÑ篾·‡÷¿x>áqä]ëQW^ #¸æÞÇ£ß|+†O(pï&9Ž–Ô«áÃÁË· L}âóÐ|YïÄö diÔ¶=o·©yØ[ù7æòc‡™7‰ÕGRë× *䯼*Ï̵'¥Š6Kró®ië.m;ó¥!Z/ƒ`öúü &<ûÞ† ’0,[s±*³=N}þG2,0a*Û ʤç¥qN†ýœ/¾ð O„ùj2 à7ˆ¤Q²ûòr+儞 ŒÏ8HË¢ÕÞòW;“Ö‘R$¢ï8I¡ µÏÇçx;ç¨^seÕq?AH|÷óŽA‡KêCˈh¢>ºhÒû®@•O¨n˜€‡ †ŸÄŒêUR'W3ò£$¦¡·¡pÖA>gÅWp6á[-B¸Õ»Òá áÆLyŸíêcÚ×Þ<Ѧ°òÏ8µT64$1ç.£ÖfKsA9KÿŠ1Öåù¦U†«¬HZµ7_5Sƒ Úβ¦ Y¬û kì²¥¹¢÷[…Ẍþ7q“‘(â$£àžd¤SÌL#HË@)Ö¿¢ó—k \©ŸtÁb"é`†Ó eXÏ“'¶æ ¤›%+¬ ýpG=ÆPÓ8 ¾ ”Ë~[ C%¸í]uSvýRÖ\ŸÞ¿7wU™h3¸%Ô¶ˆC"û^m?2õ I …¨SÁeŸï“v ¿ÛK©&¹ÜæÿWÓQ6ñ›‹!ãN;«Ë+sg,7ªHÛ›j¨{;ݹ‡5t=ÑOY1_l½ËË^âÏrùŸs¦Sq´ˆ ê8XYCBß+'sΪPÄ}9˸¨fPèWÝ,$Ñ(ÒYìǨAÁb êS¡ ˆÇ±Îçeô¢ Á{y‡Ò'!çñ%&w¥C~ Ž“<²V–Yì2v?<&Ô«dÙµ æ¥ñ}öä52 eáÕ?½F^âÄшë Å»ÀKDXÄ^Þ ˆY:`ÁL6,X]}sYùÖÒ]ñ?Uò'V³NõìÜiV—#ÈÅ«” +]+¿a¶Ô¼ e0e“ߥô…Qÿ.Ç…Mψî|#ÉÇ.MUÓü˪2·1òuÖXY{¥x)¶/±Þ½x½=ÑþÕ©¶Û¿àª „8ÛŒ§¡¶×êLÛ¼†š zê [gËbVgýºeÁ ɲ© 2ªzfAR£Ú9Z¢d½áœ¯>õâÚÜ­÷60Aë(^ÄZ.ƒR9–ƒ‡0x}¡¬ 2ËaÏra×ÊËâÜlUí{po«àƒ1‚6ؘ)8%Q8+_{•€uS­ ±Áë¥oó2Þ50|K%7/P©f; ³4̰;Ð~ã]bÜÁÇNP@cüøuxS-ˆÆä]ÿ¿åß]W‡:?MR¬É ”cƘËM×$çë=ê.øAIlé)…O ãÌAB›»Ø‚Õ#"c1¯ñÇiVA ßž}>-›%œÍQ¤ó{y•Œ°xHuÇð•ª{´‹Á 8ü.­h±)v«áyðäð‡`«(ã!>‹þàÛ„‚$ê»ê¤Híú•m¬.Öù¹º ¡[˜0¡è¯Ô `gÉÂÛq㔂ÙÝÂ#&áF© Þywòǧ(답«·'æÓU’ÖeÓ;ÅD7K»L¸³Q‹zÛ%þ#êw›E¯ôD dú·È­©TšÝ¸mŠì¬í5,ñm—œ£åAÙCÌ.)›‘PÜaî¾ÕçÆôü¹Âf0}yYF¸:²Àdq݇i( ‰&L×>>œf`ÍvÉʺü½j;ë;O.Ùê¬+Rªø´Ÿ(ÖÐmý  wtåîÇf5X„„ÑdŲY‚‰`]Ý4Â5ŒÃ—µr·þ¡ï³ùRJåHóVb°÷; °326;$ž¤m‡G(çTƒŠ¦ÙL¿¸ÎòÜÜí”Ñ8§°wŠöÞ3ÓÇÚkYhÚi‡²€×OZ§Coé`k1¶=Q…K{PÉÖôHÈÕŠ ¾¨éŒìÍ„Å)0@:}šµ—ÃÞ»‚² ˜ÍëvÓæ P¶yf);rDÎcûÎ0¾ùw®ŠóýäbÁ^°;‰d}.~÷+WMye…±Í3›Î#Ø=G|žÎ۱兔°Æ¸¾t?Ÿ‘2ÿÕôP0+Ò¼Û¾ßyh§Gµã±û}±q"¢ð»©ìu~à@>}ð¿:,ž^4¤ÔF; $>Š _$¦ïdÛaa´’A¼z…‡PËrÕ0ßÍaÖ™!V¶ 9¶´^üö³sNÕ÷³´Ågˆ ”ö_‚ÞEB endstream endobj 6769 0 obj << /Length 2250 /Filter /FlateDecode >> stream xÚíZmoÜ6þî_¡Ú"ËðE$¥p@zq‚4é[âpHC«•m]Ö+U«uêûõ7á^W~«“Cd)‰Î<œÎ< μ<úîäèé‹H KŒ4ÁÉY ãˆI•6ŠY”¨àd¼_/¤óz•×ån±”6ŸUÕ¦ÈÒ¦(·ôây¾<¼Z˜¸)«¼¦×/÷Å:Bã·ù&Ow9=&%‹'ߟýv$@ˆÀJØ:b–Û »šC/×) t˜ÒSá1ª6iæÍßí«ªÄuâ†)@|)y“ô*­ÓË‘øÀ}¶ãz_l?v~иû¢mdœ%¶³}IKÞ«:¥y=â¢ÏÛ?ÒÔKY 8¥¦|Â…>`5Pܸœhp¼Íüþ•¿æœœ>ðf”ð‚nP‚ƒSD:ª‘v¢ÂëÁn h‰{ÄĸËýÃë·ßéÓ×ÇÿúõÚúl¡uøò˜>]¦ÜÜ­Sœ1mMJ˃³ó!.Î 13£¼…«<šèþ·ÎûpoóÏUžgÞ¦}ó†FÅ™wó²õ÷<_çë9iÇ)Îå¾ñZ» õó7 ¡2=íW?-,ÿI)ÝèuJÐ[2ˆj¥ÂÊuñ«”"·Kw©³Y¤}npË7ji\¸j¢å;H4*Ïü–£kÅ0uqï vQ¬åÖsXŽ5WèzéfV&ÈŠ†šHÆ»hô>õA ~[„‚Óti€{ƒ÷Y–ïvÞoʆ\ЇŸ‹b*]‰ªñ±¬Ûü±†* ö–F³“ÚÐΓ‹ ¨¥ÎöÛŒ"Ÿ| èÒ€ŸZøoˆ°­6e†|š9Á±ˆxz,ëEØw^™n×$˜B§¬óéÞàëÕ¾¡qï†p÷$`ŠŸ“fÍÎëÀŽÎ¸a:s/>?ådXXGËŠ+—B½Zguy9cêR´6š\Ôù\ΊC{g³LÆjT]´ÉDšÔÌ$4—H16O&|h º²Ïë0Ï]fê"^œ-"𻚖;ðñm~p7ÀËæºÂÏ _y¶åv¹Ýo6OfŒ“Úœ¾,íKŽ©’êù™äÀònQ¯®×ßkÈáøÎ‹í[ çñÊjÜt0ƯnÓ2,1j`*< ø èboâÐÃ"ÅrWœíp„ß}nžû—Ÿ‹æ‚ÖuR'[7%ý®üs•îvíêÔ‹„. Ö8Ÿw¢Ê‰¢Û¶8pO†VRLàº,ÝlÀ >öÓ˽/VéØ@H“‚º=yxÿ9¿èK²U{Í•þþê ABÍ€ŠúÆî2¤¯{PÚøa•ûð[¡¦Ôº›ÆìT)ü‚g?¿š»xø8í¾k „t³+¿q)>N„¾AºxkÖƒÒÿ`¥ìþ@uwGލ4di¶í¿-ø€î©4Í[*m(u²õ4wTÊÞM³ýhI'r@¥ 5÷cÓÆ: iîý¿6fÛT¸„ð‰É0%®úóÿAâçWîH"8:ÕW"²SÍþ ㆗ endstream endobj 6672 0 obj << /Type /ObjStm /N 100 /First 992 /Length 2094 /Filter /FlateDecode >> stream xÚÝZÑŽ[·}×Wð±éEÎ ‡ÀÄp[ ŒØm<¸ŽP VÅîHÿ¾g(Qki«ˆpîjÛöîÜ{ç’‡Ã!ÏÞUÕRPU ™þ~TÚe Y*Õïä@x g ÌîÓj³Ý%´¬+5Xa¿ƒSëÏБ·ÔzRq+‡\Rv‹CVîOª¿ÛJÈ– $Íá(¬fèÂ!¡QÉ@–«û,Â%îX…ü@æVûÌh¹¦Hz&tgáÖ{3<5iÞG œ–&òq¦„á+¹•\ÂâÀŠÂ’ÀµÇ#•À,°,È}vË£QÑ‘dÒUbXZý^‚ÁÁa’îG°¬÷¡A˜½=Cª[Y‚¨Ç¹b¼˜ ÷ì‰Qo¯†’ÓQs ô{ ‹¿A)i½½Š’¿K%”Z<¦è¨´>6RX’üž¶ÝhÙˆüÚ3eôA~BY¼ù$Åý0„„°ÃBÀrG%¸¤>^FóbŽÊ‡¥}fú>6ÆKSô‹¸VôÁ0oÁ®LÞ M Þ£&9 …zoj«îT-eŸ7di.&¥Qó4—“÷ͳ3KÉ÷wK‚%îWáÒøÓ²îu¤øÑjÇŒIiÆý] –ª÷‹w Ù‰>Š<ôèbi!ÕKiÁ´·§)XUÃ2Kþ..#º>LÅRI¹ùÛ3qö×áŸôþ>€¦beõâÅjýö_ÿÜ„õ777ÛûÕúͧ¿Ý÷ë?~¼ùÇjýíööÇÍí»„= ý°þýúëïÞå~±Z¿ùpÞ!.‘±˜r4À,I"âŽP¢q…ß7áÅ‹°~ֿ۾݆õËð›;¼ùq{óÛˆ ¾þz…Žäex‡½£¢ýïÃúÏù+¦óUcÃØn>ýôÓç1‰ÈÏËN)EDæ²#ÅŠL¾ì¨²øÈñÕöæ¾úæC2’¨¿ò qÇú¥ýUõ•+e<ÃúÌm\!{qÅãYßt\‰?“~…ׯo·Þl0aýúå«°~»ùù>°ì¦÷õû¿oVëï€kssç[]Çä³x·ýtûas·Ûþú½?m~üøþÛíÏ¡O,¶HE9KMÓçYúë€P¥˜À¦ s‹evǼ}D¤P,ù©-Jæ+„G€pšŠHJÆz÷]RªF0äňȂH°æ!Q‹Œm I5{‚ìæÆ·˜$ŽKq»]²`Ž@8Eß…ö@ )°)>Ž}®klb#Y©à7]sñúL@ý œ*f†§€´%}9?D„G×ç3@r>ÎÕÎjm–uÛ1ýA·Ål~"‘¸]v,É¢ÉDÏ‚!3´áEGhöh©`Ù'šdò#F>aëi–_‚É]Mž2¹—_Ìä6Ø“Û`rLn{&÷Zgoäað0dOÂä˜U/”Ln%¦KzsÙÍ ` b;HØ•¯—-3Hšµå©Üˆõ”qX›ò \^P ¨æ™¦(íYÈ|@l>åIؼäýHaÐ9êí¨—uÅ’t¶P¯ù÷HÄj¤\žÉ t§«ñI®´®*>©@à`SwbÏ~”:…(§Š%\íá“D8’“Ј$Ÿ‘:ä?TÑ~~5ÅçÇŽgªèGNçªèSÇ%í;—QÿdTŽ]q50íEGg}=•ÿýuy%yÌæD_Ìæ~¸cá\†¡Ã¨ÃhôNƒÖ)ÿVáŠìHŸUá;a²äºÏ†…ÎH1¬{Ô “­—Zuø²ŒIÕÐ% °j ›ƒÒr] ×(~žŽéTâdQ“òue)CP !¢OAY6(Øt› H¨ÅKéå AlSÖX]5SÅÞ7 0”pòï$“Pò#º"ž¤«#Çóåç#¿såç©ãÙòóÔñlùyêÈ ª\'0rñuV/;’`³Ò‰® ÚWšüÏU´Rsி/ã@lÆ£HåQ¤ò Gôȃy°"V”ÑŽŒv„†1Y’03jI-z¨1Ižu²Ú]zуüãÛ(wÙÉœ'Ë]­‹^ÉQz¨Š(´¼]SEp‰þAm ñ}Ñ?LO!Y˜§°'hÒqìŸc§ $ZpzÔèŸ PP‰ó|Tš-ž),Øë!QX«ºf¢d$†ÿUD‘ˆÍ3%ä@Pñuó$µXº~éHIPz Õ ùš–bý³íH?7Ršr‘®KD'åÝ‘ã¹ÓˆS§³§'ŽŽ/»ËŽ~*Ä—ýØüdÂ2Ù5'ÄŽ¥×/Š­#Yö‡j…˜Ö9!æDx*ÄÊPIeÈ®2dW²«ŒS‰2ô—Ù¥Cvé]:ÔÑ Ž÷‘XøäB­Ïø3~u@ÏþåJj/?Bu]†¡ M|ÝÚ5±ÿ•Þ k‹Éÿ²mÊ¢d‚"«Ú‘Ö+Ò9(‹²Éa‚ö©BÍ÷Ò hì»Ï5éDPˆ×¶Ä“H-ÜYÊô°z8S„ô|!F†ÔµÏ”XN¨æù9”Ø€rbsPžBŠ (-6åI´Ø€rc3PžDŒ¤e‘¾»±ËzÕuŒ$m âä Çf|¦ ÿ ¡þU endstream endobj 6786 0 obj << /Length 2162 /Filter /FlateDecode >> stream xÚ½YmoÜ6þî_¡Ú"Ë”HIW @Ú8Aš\{—¸I°µ´Wç]IÕ‹“ô×ß ‡ÒJZÙNšô>$KRäð™WÎŒ¹wíqïùÙgŸ…ÂKX¢¥ö.®¼HzQ³0 ¼‹­÷Ö¹’Ê7õ¥©Ëfµ–Qì?©ª}ž¥m^´ðÔ¬$÷oW6îËÊÔ´ü¼Ë·æ_›½ICÁ¤dbõþâç³ó‹³?Î@áž «CñÈËgoßso ë?{œIì}°»^¨cøÝ{oÎþ}ÆÜ~«¯=¼~>£*8“±žS  j…£ƒ©pt3KÎ/Ès¹ÜoÍ?¡ÇÏ‚x´_&Œ'ˆÙÝ;€H"?K÷{”Ž]ƒDZšåEÞæé>ÿÓ5­GÔ’„©¨'VvmÕµKwF,އmi±%Êpe JsRwjet½)ÊîzGã¦J3»;ö¯V!÷K¸í¹¨MÓíÝÁw\ñ®É‹kšÞÔ—j“mL‘¡-pÿSÕnö¦¸nw¸þYí{k¡4SaÁ¥r[ÂÅý­i ?ä…¡5{9ÒCÙ-Ë+úuˆqX³5[¼ˆ-RD’)PìD”ë,BTænA¬Z²X%ý‘ù~O7]ºãÐôðP³¶KÝnÂö°1Ë«åôaVò?¶ý‚yÏýFG1øúR çLwà( ha/9Y|}G Ð¡dw¾`u~Óë\ÎWÀÇ&/1€Ü’ç¯éç|º‡·h“ÊOi–»ØRíI§0lºª*É Zki6?yJ#´, > Íb‘‹W}˜*«ôüØ9z76`áŸCE”^B’Ç(†(DyB±š/‚„f6ƽµ Azz$S×(Œ²ÞdåÖLî{ü ä9.纷¶‘hÑ“òòÖµG‡‰pð{”]ðWPLY ‡"ûØÎ OE…,ª?‰‡œ-?ú:ð’ˆ%`B“Ðjq‚£¥÷á  9ú;ŠJÈW N,53,ðYTKE|C.mØÀœâ>9‚ ŽrüÙr2làýܸp\t‡ã¹Ç‡jä1b9<ð;ËÖ!×,‰¯%H^ÄD½Jëô0!ïÙÏÑTAoóâý`­Í«>.=òг$x_Ó‘WùeºwLÄzŸã‚ÔQY ÐIÌÜàAç0§‚Іþ)‚óуOé¡¥st¼ŽsäÜ7 ÀPµŒf^ŽnQ@NìccÜäåëÕæåù�A^Ÿ¬”òŸŸÓ§CšAÆÛʼnŽéê;$×» &Gðþ·Kà!á ûOC6ÜûÛ÷}rc²üÊñôËo¯^Ñ(wIDQ¶ãÌg 3Ý8‡ ÉCm`Ä»doý„sm¿øuqÿ?.Ë¡½NIô‘òxuøÿ,·ù;„Škû¨³E‹¤{î«óå;QêÜ`†ò &Ó}Âuš šÉpPÄIl|ÈÙx±’áÔ|kŒaÆ–·hzý-ÑZá‰d|îï¤à÷Å@(Ôô¸c¸Ë2Ó4ÎnÊvç²èyã1q•¡´S8!%–u?¶EÙT]+bP£»ØåpP@.uÕy<ÎÆy¿Û@U¥y).¡ A7Kzjñ\-3îDRNKL­ë”µ™ßíj&;>š!¼=‰«Í`½ÏÖç| ÌÙ] ZÀrdiDP¹Ð±üÖ†Pëª. ¬®ˆ6 gµY鄉1¿Kµ ”ºÁ$»è’y¡¨˜Nj6$bÊžLø˜4e×a'êmd<†rSu«'ÂÄÅöS…Ëò_8EY¬‹n¿´ÀœÔ!‹Žié15á*)Ÿ_^ X>:ÂuøB,å®ó¢ÀÒÂZ|)ƒ¸'ŠÂ2ÑÁˆU˜!œ²ªCk+=LR´&sÅÝVŽðÛU`æÆ-~Èm™çª³«m ¿—n^¥MÓŸNI¨¢àŒµyKªœ-úäÀ΄è‘$ŸÀs®_RáSq»ö z “ºÖÙÏõ]öÏ\_‰ IÍ&€ÕÃcH_;pPëÚT}; ô%4@ Úо4ÇZGeç@fz²ïrI×å’ Šm— 0_EA.D1¶ÿƒaÝûeVc7xû¹Ý-™àSõÿînI®˜L»[W¶½dÌfÔ<š´¶žÚŸ¦p-- èÃÕŠ$¡ð™p_2×Ìu«Ò“&•[·Ï†M'Šë—¹ãÖ,Fó]Þº6ØŸæ±;òÐylw®¬êÊÜå“.•äŒ èAD(ž>™Üà,˜C~Ó•øË=ªðoêQ_ܣЗzT§âí'|ë~…5Úb~)¾¨_1ëRœ¼‹ÓÂ@kîà ©?û¯>‹ÞBu+œ³Š0Æ8ÇPRïRê1»ðŽ !zé0ñ— ²£½é7<ä¦ÎÇ!‡˜ùbß»Æt¶™sú?熴è endstream endobj 6809 0 obj << /Length 1842 /Filter /FlateDecode >> stream xÚÝY[oÛ6~÷¯ÐÛì`fyÕe{j»´h3 [“= m(²Ü‘%W’“æßï’ºšqÒ&Š!ˆ%‘âá¹}çBQï“G½×³g³g¯$ó"ùÜ÷ÎÖ%á"ò ïl彟Ÿ,¸š§ÕEZ•õbɃpþ|»Í³$n²²0¿¥ Nç× /æå6­Ìðë]¶J6÷ïÒ<ëÔ<0Â9a‹gogÇg³Ï3üPy‡­% hà%›ÙûÔ[Áø[…Þ~kãI?„kîÎþšQ+ % D „ûßö™WÁÄÞà;—Ô¸+£„ŠÀ|U]¨ó«ó+-þÜž§EÒÜn-÷ËV¢…š7U6ÝL4—öf´ª\›kl.f“~ 3Z7Õ.iv ?'ZA„¤œ†(N áW†¾‘t:’>{åû1©·ä´ R¶7zö Ò/S>a*‚™‘nÒÛáZØI –D’0´K>PEÍßʹ§1”E£U÷¥™°.Âá:IB¦Ú•¸(]5ÿÒüü8~„€Û1G Cœˆˆ0$kW Ç+t~ëÐê,h¹ýàž+Pªà^œH!à†’ˆsC}WñfDÞã ¶¼%ƒ«RCÕÓFßèJ, ‘­ ¹ô–‚‘ðn4î/ò2A°\= š|I¹Å™Û12;ÜÞM]•›ÆU…Aº¬«ƒh€8õh†”õÊçzb8³oƳü±ñì«ù#¹a!dG>åF;"ìpuˆ-Ÿ’€w–::0v¾Š›Øa\©ˆFOm$åDýÁ¦›æ{Ó(òbÉè<þnQiìŸ'—©°_½ÛŒÂÑK j¾Ý5‹½Hä\‡3e”šÇz‘­¼Ú‚«ÜÆŸqr·±Ð„ß)äøOr@qFiW(´# RÄúÿ½†£Üàôá(ÉÆ0÷TfÄJ»ì‘\I@’b?J$¯ã$¿Ň–«]ZHtûCªb$ˆ:Ué%ØÍ`S¢(š³Fhé[vÃq‰ÜFÛ»ø’huæ?Ê dÄc½ ^Šü}¯Â(cë ¶Ð)»åGg9 ±JñôyC`¬e`z¦«à¯Iï³âcg×a ™BrRЙki–üž]T1ö­¦,ìˆh¬[ùGœZ*£Ü4à`J¾Ç–^¢™Z•ëÛ>ÂF@jn× I!ðš‡M\€¯•#ÎqUk‘)ÛvãQÎìÙž$×)Ö! P>aú¸Hìæ[{  éôq`Ÿçxÿ%ÜvÕª 0Ô„C ËÉÊ70§s—âx~_"YN¦ìv¢W~Ú‡“w/ÔùÉñ?Ÿ"×ÏJÍ_·ÆHª²¾Kõvë;˜îB€‹iƒjÂó›î}ý8(ïÆ›ê¥ã=Ë]3uSL¡|jí×i‘VqsÈVÆz §hìŠÖA)þ4×h€8w’Rr蘜Ð)?pFź˜s$ý²EÖé.IÒºþÕ<•Ð×¾Éjkü‘Ãtgb ð:¯ZǪ¨Ö*BN*9æîì2Ã…ŒÍ×»"±Àa¸l&Mí\l§ZÖ“ºme6FËÚˆ@¦ü¾J8'ºx^¢k_kTV.Ú˜ô»—³ÂíµHtqS. YYñÉA’‡D¨¾BK]ñ‡"ƒÎ#³V~ݶƒB\jêB(Ìgc­ºÂƒ 1F„pC$óÇçÍÚ!IOô`µKBûúDsqíŽ0Z¬ô!ö\Ý£)Ÿ@[0%[”ŲØå9˜BPfãÅÁîVq0“å¹»°#v)›¦@À²)—Ùf›§›´hF¿O‘áJk[±qñ×í',þêî¤u’„‚Ho@K ^wÖíÄI³‹s3ï`K·RÃ\VzXpa‰¬lXÈ®;ÇY}6ärlFü{=Û'Lvnà¶;„ÁAì¨úOÕǶlí,Š‘¶?Î×þ/ÔÛ4É>P!ˆag(ƒI‰âÑØ>Æ1ÂÀ¥\mM"¥5 Œš§TeŽŒÜZUªóŒC* {si"MtýÌfg«}½Á…Ý¿2_&Vv´U²ç9F+ý ‹éu•BÛ:M·’àì˜ø©NþzÁÍeZ˜»Ìî˜Ù„ÀBèF£¶­±]uQšÄ‘—…)=l")Òt•®ˆ#·ON>NÛ%Îëò‡2¦)º;8o£¼ö„õížtP&—â6#úé÷æsA34ù~#ïù~£¿ÊŒ¤CZº±²žõòUêÊ uIÇ#â³6¿båÙçW¬²ìhm²<¶*n¬ê­FðP¡r§*l÷xÑÖ^xT›¤OE;Fvw®ì,ðƒSÜ›ï¾#µ¤rªüJ ´×-% ÷ü1Îùi PƬ‹B”ôû2Òª¶ÿ|£Q!#¢o‰!Žª7ò__÷Þ endstream endobj 6829 0 obj << /Length 1847 /Filter /FlateDecode >> stream xÚÕY[s›8~ϯàwjUÄe÷)M“l7ݦ›¸;Ói;‚•” 6pÚì¯ßs$“[“îL'36$}ç;}ǡ΅C׳s"ùÜwfçNÀÀ ‰ g¶p>ºG.]Už©2¯&S„înQdi×i¾2¯Ô„S÷jÂàÅ,/Ti†×éB=7×'*Sq¥Ì #œ6ù<ûsg¶óu‡ê0³µG8Érçãgê,`üO‡…Î7ýÖÒñü¾3çtçïjÍ „zJ¸/ðmŸ9%<Ø<¹É`F 1ø²<“óËù2¾ÔÍ“/*™L¥ ·Ô­ÖËyš#%WÆ–©ù:H³Ì\¥–”Ø| g›Q`c©VuÆëã‰î?vzYâ´1\›¡OTRÃ.Œ×ÀfÒø!/â¯øpmy6è`®!¼e¬eŽÓé <øôBß07æ^ø~‡6êL¹¬Êk @5y9Oò…êí÷âxî‹SpÎrC÷¥¡ù W€meg"ã’H53‘³ÏÚ! ¬$ÉÁ3ÈÜ÷z`‚»=2¯™‰“úï{ýüq€„€KÑG4ÔERêëB݆É÷I´!'Á´l¦=•Höý¥®oƒ""ÂpU;¡(4ãzâK÷‘` ò8 |Ï™2°dÕºŠ/&FþmL1D-<=ëÜ#ñ€x,èûòÍ.0¤j¬¹® X0oõž|¶ˆëK©„"’þ«æµ¹^Ažà£‘D‰ =¿“'7äÿß°ªè2ïaþ±\̳Ь^Äe¼ì-ïèÇAßAÓÕgƒÛd p`Rl˜Y”DAkûÔLy“ž•1ž,T×ÃvrÖþR»Ê”Aä ±… ›#|©¬a‹¹gFôl}…•ˆšËó‰^.ÍÍ2^‡òrœÕxdÛn|ìK´×æÑ6h™òèýUb7/ì‘­×Ùäã6æxû%ÜvÑP‘ÜebÄ ‹ÄXÁ‡V˜t£îñž >6 á¶ »!¿Röæè䥜íxЍw'Rº‡û317Qo·RŸ¯k‹9™2äg$h9äÛ{8ÒªtdU³ë–qÇ}ƒ5kÜà{›ì7"ðÇb€àª…¹ÊÏí–½ÃÆ'Ükü)%÷® Ò\òA´–Xä~ÔWè£8]ÖòºH8¡mºÚˆùĽ­H‚LõÛ:a“ït$ªª~·F×_”‰þoie‰èÅT+l%Þ5i€"¦ÂýuVzPÆzvî•*®qÍÈdL4’zT <ø,æBGèÞÉ$î‡w³ãùLûôûýùÞû{G§ïÿ2ïmd"ÜäÍW:_ÄnYæ²:ògø±kA®ÚÚ/Ë7/súúðíüøíð% À9Æ׫ËÊ܃qÛaÅ)ˆ/ÆÕÀ}œ’P´Géʸ{¼Ê0h®Íêš2¼¸eø^©.t‘ÓЬó8Õ ”Öjßl·Ìé'*<µ #©HûxÚÔ–8«òßFL¡ýа‚vã-s~=† t*–¯Î (8ôˆŒa“ä±d6IÞM’n}zVâZÔ'AsŽ¿E|¹Î\5f%ˆÏZ¯Î¾¤6qÎ׫ds¶4£UºL³ØæRÛ3Ek"Ý]aúÝI‰=gk«x°‚¬³[4[êÎ`¯ÕXCU&ÛÒluëÀ4&Ièwbñ~žQ2ͨ'Ù® Ή¨j…‰²ó^Wz¨VÝvÑöžà+ÐÓªP‰Î€ÄŒ•Z/ò©yµÈm«z†ž¹î¶›íCÉÏiDý§kD‹ò|DQÃéìsñ´ç7žò'5žüÁ=^ôsz<¨qœ÷ó-y²-½°5àœL@f±~4/ðR< (H€1R°t ¼'oÒD!A–Á ‰¿j“öÝN·S¸«/ÙÚ¯˜±¾„“@å}û~ÓÄ£}…žÚßsÓTtƒ£Ï0ä£ [›·{ûÝ;.8äZ$üÉÔºøÔºU+œwÕ gn";©í£ØŒ5Gas nM:‹+Ý Ãƒ|Tÿ‚ä»SrÈM‘@q®Lò%xXŸ©°SÚ@³ÎÑg*Œ÷ºm RZÈ–ít5b\¶‘騵xàYœ¤« ³­éY`ÃRUë¬6ƒé äÜö¦S€Ò Y¿ Üß‚‰ŽüB€›¬ß“8ËTóʺ2¿žé»¢Té*­Ó8ÃÞvÄv¨z›“ãžÛúµÂÏòÄôu¨a‹8Q#¿Ô LCË}õ"óqSù$ÊIèÝû¿•{#4ŸP s°„Ê{èsùP}μ:¿èÁúÜ~÷ÖÙÅý{ÿgjT¸ÃAÀ˜­»Lb ¤aˆ?+ÆÅÃÛ6‹ ™}Hß‹Ü=¬?pÄdªyÁ<×â[ÛE½êIÿÝw¯í?’t`Ã…þé;ˆÿªW§µÿ,뵮 endstream endobj 6853 0 obj << /Length 2025 /Filter /FlateDecode >> stream xÚåZ[oÛF~÷¯à£D“¹“Ü}j·I&Èî&nE´4ЉH¢JQNÓ_¿çÌ /Cd»öb[DŠœ9s®ß¹È4ùœÐäåÅ÷—Ï^H–ä$×\'—«„g’p‘'©ÌˆÌEr¹L>L^O¹š˜úÊÔÕ~:ãi6ùn·[—‹¢)«­{ðƒ™r:¹™2X¸®v¦v_Ê¥yêîß™µ)öÆ}a„s¦Ÿ.¼x~yñË~hÂ’”ÃÑ’¤4M›‹Ÿh²„ç?&”ˆ[Ç=Ç–f$Í;CÙ-˜q1qôƒÂö¨åæaü<@dS€åsY4Å9þ¤š¢ŸàòÇåMæsßB»`lÃ¥uð“úCGèìÉíŠ{ê_ p5Œ»«ª‚*f{Ž™ËaJ‡z~rƒ&-Öm6"°!“é£'–S’*]‹üÙ½Çrû©3ñ0EŒcrNÚEÔÌmyS^Õ–€ÔIô^þ€SO%È==£,4ŽiVÊG<·Õž¿óEª¥ÓÇ»}°šJ ì¾Ç‹ðØ¥½Ý‘÷î8–ÂsrB ÖÔ!Áq€ižö28â!öfƒ2ÃÄpŸi}„"1NµNÙ)N!¾§3†‰h;'”Ê‘¶@ü°wMå®W¦ºU`ûfQmv‡Æ:ßZ}=¡iO¨Ü~Žè¢4“ÞG3CNŠÚDˆÊzŽQæ)poW:å|D  ¯z~l¡…N’BK6vôijlÛ åG*¤YÆóÔC—¨ͧ–J_!c¼)1ö¹ª¶³ß kŒDÛþ°X˜ýÞ§‘‹VöÐr}¨ÍY@rFÏ%èœuªÔIòÞ‰ûw÷­‚ÎÐäk¹÷fòj{m!¢ëµu¦S“ºU V‹{[¬cK%C_º¼.qc–OV‡íƒ|;v\–ƒ:®‹&Œj¢tzÇ PY‡ íñE{në8ök$ºóÞêÇl亪Ë/m¡2f€|v‹Èt&›¼Z¹]?_Ûù÷Õ*ªEæmZ'´Ë*ù1Ö=p0™€Öûü¬oº4Ë$oAî,6H:ƒm¨ð¥UÜŒ¹… ázní wå6ØPmÐì®~Åú¾¡•†ºK±]F¨CKÀ¿5D”´­wóö§7ož:5u’nà´¢©ú’&&½ IM¾…÷A-Õº˜<ãçP;Pq[‚×P´všûZ®×ŽªEúLY;£óƒm/¯ý³bÑ ¿.rTÁ–1a9Y¶®rÓ9/ SW›˜¥$yv/Qâ¶Tã,ìŠ¤Š–O\ ˧ruB°ˆI-6J¬r²ß™Å E‚5¡u…¡9ƒå\ädÙ‚¦og ø‡‡ýƒnc<ø\ `|4ø”· >í83ÈH ÖÜ—üo‘µÊ¦>ó·˜úr¢YŸ>`úí|kŸîËM¹.ê°Øp-Û|„+ó±RpíOûW‡Æ'Ä©‹ÆøÚ팸>Äj4Á82¿Cá§úÄpGCP°:Õ÷5Ä'Ð\§PÉŠ»ÎÆæe…^|ƒã+W=ÀÅÎÈ0Ùº™—{X¸KlPñ±îÖÛ^_ýíø³ß^»)Z7ò¦§¦kÞr)M×èŸ~ºʾ‰tÉó¿Ô€­Ë×6©›Éh’÷5Y‡¸í\A§’+vŸ±À4Ø*•P?þãÜñŸ¢¤ŸÓ8SBü¢ð;GP¡² ‚ÍÞ9nAÐÞé‡ÃÀ}ù›™»ßf,w£Ö sn!’Üú‡9Às*ï;—S¯}Sÿÿ˜Çam¨Rñ§ŸÇÁáÚÒTËÛ®,V.ŸÐHÿTvû]­E"c-<øÄlå¯7FLìö“ÁNù{㿼~÷½š¿~þŸŸÞ#×ßM•š¼|ÞcQWûSª÷G?ÖD*[Î8•ú H1üa5T™£qât;'9ÐØ_‹ïÌ|› h`¤<žK„|âæ¡CþA‡jã*[}çÈ–´’CïÅÖʾ™–¹lÿo$ÿze³…„’Pô?0±Þgÿ‹êA“ endstream endobj 6869 0 obj << /Length 1819 /Filter /FlateDecode >> stream xÚ½XIsÛ6¾ëWðV*! piO޳4±ë¸¶rÈ8 MBÇ©”ÿû¾€«è¥qÚÉĤ@àá{ûB­+‹Zï'¯ç“Wï8³BzŽgÍ—–ïX>]kžXöÑÔ¶,.e‘—Ó™ãöÁv»Nã¨JóL/¼‘S‡Ú7S×ùVzùý.MäKý~&×2*¥þÁˆã6ý6ÿ8y;Ÿ|Ÿ0€B-¦¯æÄ§¾o&ߨ•ÀúG‹7 ¬[µkcq/€çÚ:Ÿü=¡†ûžŠ=Ïí°z$ú>£„º¾f±˜2jKüSÝ ·ÑZaJ¼CÉuõCkÆ|ºŽ¦ôÕa´wöÕ;7蜹z!|P›)HCPû|Dz,ÿпòj¥äGíÛTÉ Öfúq„Rn5!ð>í"/ôï8Od‰÷[3O.„AgTy˜g_©Ë5ùÍt&˜kW«¨Â7oR/ŨȕŒñºërg6¦Y}@êýGg¯Åâðlê ûËéüÓb>¿œ¾]þùöðèüó_úh~#³ÊP)õ3Ò4Œ¸Óä¡›óe y£À#!p§ ô^o¦ž°¦BØsüs …e‰‘ç½Ï?¼?Y|:9“€½»W`ðFð( |*a¨…|ê `h9°:ÚWĹ4Ç¢u™ÿ®÷÷ìd°ÿº¸‹ëÅ&ºV&°Êia®ÿJ…ÿ̘ þ+®,ýrö~ÏÙ<¼iàlügÛw* %À±¸gðž ¾\9”cÏ ‰Ç?˜¯R#Öå.‹MXA™šÕ2ݤëȘx•ë§I¼¸A¾Ã¤Ë»G%óRŸ¾ÜUÆÝ ZE•47Õ7çÛè;¢ßI£K¯ç÷!ñ™[£¿–w#2A8eö'*D!¡ÿ¥Bš'ap;%èb¦ÇÔe{‹gmØ×~äÔ:”xܸ•Gá£qðé×X3t,¯Àƒí(¾Óñ?97 #Ke›ÄB˜hÔ¹ŒbÌ~ââANwrpvÜ©@H2V ¢]µÒfúqn0hˆ&Ÿu¬¡äæS)³¤%²-´í«q¾&÷ˆÑ¡Bö9ê8ð47ÃEÅMÏ‘œŠ7²(0”æÅsÀ j;¾ Äic™Z …^»èìöH“¢Þ^¤iÿ,vA·w7ØB¥„ü£z(q NÖàÀCýúGõòyx\_{ˆ@¨¸ÕS¡ù>ᬦð司uø £BW N…wLBõj À«#k ÿðP¤Yœn…Ö€Ï!B4çÊÆ%uÄçÔ~&.' ¾ß×=HÖuÂÄ=â0¯õWDWåsq¸$ }ù@R©¢ËÕˈï¶n¬ê‚©Km<÷L<Ã8aÂï—Y W•ÆxɵD+zÐ+¸OÜÖÕ_¼À“˜“Ðj$Ò¸pWØ 4lò&3Bå+g¦¾ŠhÓ#o©ÏŽ/Òì[]W£?òÕH®‡¬ú tS¬§—E¤-ö®KD…‘ qf¨ôÚ @ï*¢YîCåó½’ÓBÎô½PP¡ÚÒìÊ”9¦¦Ê”åÜâž5f‘p!¡4JÚ۟ćÁЫ_[I.“±r0 w°ß!Ötm eèkbSåm«¼»ØP»Ø‡†cÓF`€Õ‡m$Ÿésƒf×Áä^aRן»ÕgUŸÂ‡K©o¢ÊÔ¤‰r…ê‹ÒL+C/ê>¶Çë{%PÇoS.ì²ßÑA8U$7à{ÜòùP3Ò*BlMx_:ù\hœûJ:eµ¸5Š2^­aåpòùøØXFïÚú¢LÅ­¦±Ú¯¸D§â6Áqߎpl1ˆ!{vÂB%¢{„`búy7 ¸  ø$IQ75³åVÆ)vÚZeå Clèîĵ’§Žçª+å—„ ½ý¨Í¦aŠ.k'BÏÃkü¿I©i,ë{ÛÓšßr}k_zm”jâ¼b@UÁ£ÀohKs<×Ï#¦“.MÌÊ«:xÉD&&Œ!Pûï³ñ æ@îÓç@Áÿ7â};»¯áÞÖWãžÔÞ”ƒIG9æòeš˜Ï¹ÑOTïÖÑ+ì1”L›<¢sþ15)˜%ŽM‡Þ1a$Òm3¾Š2½iÖ7 »HS¨»y=’é´^TáP¢0×m+ä±6¬$½6@€, ¯ñϵ’T´,¤\ôKžf6ÓcàÆ±ˆçÀÅ­‡ì—]ÃÈÇ mìév%ë JÕŸ¤dæÖund]t}hlp5cúîÿ‚ùUm ƒ!•ö½I‡†þÉcàÑ)6‡Ö†‹gÂA£ j®¢í¥Ø6ö™Î<Ú‡9Ní-ÄK³A×£‚¥93‹z`aƧô‹6NxIÔTÕŽª»í`ˆœþù^©u endstream endobj 6774 0 obj << /Type /ObjStm /N 100 /First 994 /Length 2153 /Filter /FlateDecode >> stream xÚÕZK·¾Ï¯à1öCÖƒd‚? Ä@–I:Èò bì«`ÿû|ÅiÎzF^ ¡ôŽá½luO5ù±XÕ]jM!…,jAr(µæP® ‡œÍoPÈêB©R‚Ð4°¸PKP"j(]VkŒ«+cðEH9dÊâ†dõfóy[ ¹°#).Õ~@j†²à2We¿gL0E“k(-AÏ*¤Š¡ˆ²?kˆ¥¹Ä¤9Ó@…º^ T‹#0¬ÊR¢N¾®†U2&Ù@Ê9¿GX´ŠKX1<$ \¹?“´b.• )aå-'XTÄÑ+¤æHMˆúŠ`o*Œ9°@Áĸk&q=—ZŸ·òñ¨ÑÒGÆxn|H˜Í  ©MnÓ–[Ðì6mØ?eN˜ƒRPéø0¹–Ž8h_IÐÖ|7N"_aø¬®ç $˜øpÉìó2†ÇÒ—ÍÃ21crQGïpÅ\Ï•Ã>¼ùÈ,¡&r,ø¡æÒ\ª†ôg$[¨ÚQaSà†„9Ľ³ø(Bð4óg¡ {ù0æîO”]·ÔÐTû-4@pÉBss_ ͊φ­µœhƒ)$ñQÔ%w`1¸3ËïHÅc~`œº^…Ô1k†ÔwË2us6†Õnq7ÀÅ: ô¬¯Í‡JÙ£¨yÈ%*> eø¢Ã.°|Rv´¥@,l­zX5DpT5+V ±[Þ#&!7Ïžm¶ß„ÄoC ¶ÿü׿ƒG¹Öè³ß¾ÿé§W›/¾xDf†?\VJ)&xÞEEØ)àe½\cJg>ßßÞ‡gÏÂö9^·<ò†B„®ð´|aùm ¾Ãìˆ+¿!Ì2^®Ä“~… ·ßÝíß¼ØÝ‡›°ýî›çaûr÷Ë}8byùëÏ;üðú?»ÍökàÚÝÞ¿óüÔGÛl¿ß½Û¿¿{³ë÷äpï»ß¾þjÿK¸ñœ[²»0½ÂD¯ïð´§O>(~y{»Çh7‡ëxzŽ]„6[„–†‡@C8,õ u³}ñþ‡û~ý÷··ÿÝl¿Úßý¸»ëØÒ«íß¶ßn¿¾Éý—ó†¨{?O9²y•HÑÓW¡9e¨}ÙwçEØþuÿr°±y‡ßîo?Ǧ§Ïܬ«!Ì\<e‰î9ÈO@†x"¥Ô#ÉTe=(LÅSÈ…K‹©Ê,”f+Bi%¢6¡ˆŠÍBI"O°A‹«PãØ‹zÖÈR>¥Y^Ñ(B±ç׉$‹†Ú7‡¤ÑzHrŶ ú'Ì VÏI¨„”H–¯é´`Q3¡p:iÊ©Óöô=2ìÅêr¢èô Eµ E¦/º¬HµF¢‰I,R¥ÉsR*ÎÊÈtùY£Ä´d”§‰Ÿ\blT UÃx:„Q†l”![ʳåEÈC !ðd:„ò…©á¿Ÿ¨ á|yYà ‰Ï„W ,̬@¨¡B:‹ž²r]òü–ë +#ïMCY³.-»ƒÓFLý@t  Új´î×£ ÍÏG N‡ä3…dåía‰ØŠ(•£Ÿ€&¡¬JŒb¢(¢È´:k•DuuO®1ûafñA¹JY®é) ¶€ÀMQ@«±5à/¨÷ÛU6È,G$’a¼ªÌ!Y‘Iáp]à$N‡B;‡dM=îÎâ'œ)–¾[ðµk]†kªý€âÛcdsPV%ºŽ ‘(ož’ë9£ó®Ú£;U|¤_ðÒcý‚sÅ’ÌÄ—YÌê„¢»­eP,žÿôÏÖ‚hô;ü>z»ñÀÙrB yéEx§q ¤Ai@Ò“Àb=a»S$pÕâQQPÝÖ¨Þ$)ìÝ\xž$¾jõÀñÊ»¡ŠGÞAœ„²f~ªŠüôE³ÄÞMžƒ²jý´¸ 3ÈWß0ðŒF×­ÇZ=Bo ôÎÿ”UÛKø¸-¼ ðaAÞ¿*KÏS /$„“‹¿/™B²rŸÄ)ðƒM I/º4K3h†fÐ,Í8Sd?¨S™PÄá¨UùÓ‘åIæO'<ª:ªÎƒð`<Øv ƒÈèÉ  2Æ‘Ád (c@ÊPÓš ‚à.­'ߥ}ƒùk…ë·o=b)üо!D¼¿VøãÚ7šNxÕоA­ì¯·Á$üƒÎ¥#Ò~¥×=•ÃÚÛ7 lõöÍ”5·Gö ˜Ñ,”ußúŒ *gõ®‰Dï{gé"Å[÷­G.rÔ@‚‹Ù$’\×ìšH?—$š)rj³Hdõ8&ðnûM–¼¢¥«Æ±Ÿü«œ ¬‡€~Fñ®N.vÕ0†M8Õ#”ÞCAÙš…²&±B¸fÔžEIbÿ:iʪde°*<5‡3X¦s<¿fd–Ì×Ì(’q2“#A5Ì2dÕÑ3ÿö›àá&(=Ö]¦½§QÜi¥Ò$í=Q|Œöž+=J{Ïï®)>Þ];SÄYT&±bÿ2fŠHŸÒã¾a=¡ÜO@¤Ëït×ÊÿÑ]ÓAeËàÆepã2¸qd» ’\I.OÑBü÷–á‘ê%Ѧ×,ˆ3õï&íЯ¢âŽêMíæ©èª5"!)¡øQ‘°“PJ[1 öEøE¬ Ú$”d«¶Ð4E°!Þ³ygá Zã’]ø¬&ãoÍZAn²#ñ·AVç ˜ñš¯`€ÄŒ"Þ¦ñ¦Þ”QÈè h e§æÒÕª—vÇ>ø¾§Í~=ÚξãÔŠƒ¸¬ˆ\“¨M(be÷¨ø?8L=I endstream endobj 6899 0 obj << /Length 2043 /Filter /FlateDecode >> stream xÚíZÛrÛ6}÷Wð­’ÇBp!x™>%MÒI“6©-?% MÂ1ÇÉ’TÒü}^‘ŽR¥f¦/– ÀÙÅîÁžµ°÷ÁÃÞÏgOÖgžûÄ‹QÐÀ[ßz4òe±úòcæ­3ïíâå’ò…¨oD]6Ë £ÅãªÚæiÒæe¡žŠ%Å‹K_Ü–•¨õðÏû<úý¥ØŠ¤úA”"²|¿þåìÙúì3x°G¼ÂÖ> q襻³·ï±—Áø/F,޼Oê[;Ï"xÝzWg¿Ÿac FLÀˆL~; ^ /§¬–»Œ0 µÁ÷õ ߀ `LªlJöíÝF[§†›Þð•~¹Rw0Ößî‹tpÑí’àEi5¢Èä¢úSU—òa«¾‘–[=ú)ïžOî\%j Ù‰%‡©ê œ/rjï•Þ;GÒ¡ý(ÐÞqÁ;žÁÈ5Ø[Q<ÇGžu-#¢¬7i™ k¿GÏÁ—#ÇÂâ`ìVp©v§¨•10öä£YÇ( £nÚ;̱ÞäïÁ!¦-iY´Ê§¶|çù("¼›)'‰%ã‹?Û‹Óð0&ßZˆÀ%òô†È'Ý çÊ¡ß_@Žˆ…¯*sƒ«~ÖŠÒ²-òV„ ˜›¨¹ÍND¢. :/Ò¼J¶Á (âýù5}Ž2e†'¢ CûÁKŒ>É%áÛŒ'šSq0Y(îÅç6¹y0´ Ù™’½!vðBÎ; Ä@€ìP¸Ú<•›Ü IÆ·"6$íù¹œ 5Гó/@AdŸ[–´Éƒx¬ÕO9714C`ÌG8¦#þ"Ó¤ü…WX•ýÊàÎÄ`Њ‚_I¤W‡k ÙYË{êqh»ÿm^¼‡èçØÐ¸QŒÅaÜA_é)¯ò›:ÑÉóy¼ˆâc¿…Ô¬²"!Šë”ûÖ€Ö’(F$ $oj±Òû抡¼ø Ÿ¨›^ ÆŸäw¶ò–ê×"iE6ì~”ƒk‡1â6›€ œùÔý\bÍ·BÊD“joæU[ÖS›Uf6&ëHì áàÊá>5X†GÕ˜¼l»~õÊX(I²ólR(‚Ðò.î-šö9"á,tè#Y\:ùqà«øÕN ® uN,Ïbðs<ðX‚ϲ\d±M%ÒÖñu)ÛL¡0‹ÍœÄ½ò§&Îå .ðI{¡˜&n$?&>W¦FäxÌÃSXô:6”!§zŠTT=9 % ÜèXËyÁNC~k2¬l»T™ÈæŽÏì4‡ö€Am’·¤ƒrT3«à-[S+;«}=ô£8„ ¡‘µtµö÷GI8NE2ZÊÇ(P¹Ëï(ÁÝA5AÏc“Øû4Mó£!ÁöÎ$ú§¼1lc¼÷Rl/â864°¨»ü–żJopäsßF·¾ËÍÄ‘®‘¾5£M¾Ë·‰Y«-M@w%¿ò ž<åvõØH9áÎÀMœ…ˆ©ömG:!áÅ.@TÛ$Ý—`óCnbA¢¢óÞG™càbÕ‰(!z1ªêhéL`‘Qh–Æ*Ó‚FMþ´ÍEÑž("ÿëB°GX?hqþ¿þûþôŸô˜\xÐ}šZäÌ»¤ÖìB#Šˆªndt6TÕv3âñÀ†£%c?/U™xª< !Ñ÷ ^G5Õ¼Â÷åÕEmy‘TÀòlJUËœ*gƒb›œ"ÏòBÍ85M³c‡8juqdÍ´+.j ÔGvªWÀÄØš¦‰ÒÓwâÁœd F‡ˆ–sd6Š“e~ Ãuw(óû{áK^¢þ ðGåÈé± œp‡a!DÕáUQ¤Õ>íŠä9Œ±‚á8?¯…Œóf¿=•€'È}h­(ȇNoåüª$d·)âA}ón‚ŠÁÐQ݈èÿnÄ÷Ò0åxÒ<¾MgU«L*ë{Sû—–xüRCÃÒò$8wÿ„%!EQ<9Ïú?”T¡üd©B%K䃡_AB2Ìô€$ò$ò ¨‘w·.Ø÷ÃÒÑ0à¶ö?ì ÚúQ1s‚ºØ˜íp»1W´÷"á°“3¥ÆõÿjCi †^k†¢h©¦e%¡ÄÌЕ±³‘#»¼ðZƒþo„ ñÇo6¯ß¬¯ô‡]’‚žëZ˜•gzNº®Ðž)º¢P0øn£G–.–(¾}C£µŸô*Ø­ö¦XMo6ãJUt(_fSäEØm°¼(d.ôj[Þ'€0O¶Í…ÍjCc¥¾oÄd?c1«ôèË•ƒû$Ž€¦g ê–é®vÃá§¾YÀžЬÂñl¯JÖ3¤«gŽèí½èÛMŪØo·½'y¡//Ÿlž]^J6y}iBS4MòAý·]Ô¢Ýë@(ºÛâ¶.wGÇȸaHm³ÂØt®ºœ“UÍ„}AŒ"je?ÌTFƒz4)²‰ €(ë˾ Ó)ÎgS<ðsïXÕd‚-L&o~½^_/¾xüjsùì÷ë—Ïž^hH½“µÔÄ>ÂØ©Qû,Ó¥œ‰msf»}»ïBFÞÌ2„ÒQ§IßÏòµ…9°C÷ãÙ€ÒåÚ|z‚Šx|\T¬i ÿ ‰H‡EvËVuæþøêRýÛ‹É_R€<$Ä[€Z®?V%®ùíÈ›êl|N4áÌEöSõi8 endstream endobj 6913 0 obj << /Length 2095 /Filter /FlateDecode >> stream xÚµY]s›F¾÷¯àRÊX›ý€Ò«$N3n2™¾ŽûÞ$ †UÍŠ]ÿûž³gA€£ºîd"`?Ξ=Ï>gͽ?<î}<{w}öúg_x1‹µÔÞõÊ ¥úócå]gÞ·Ù§¹ f¦¾1uµ/dÍÞn6Ež&M^•Ôpaæ’ÏîçÕÆÔÔüq—gæœÞ¯La’­¡Á¤dbþûõ/g®Ïþ<  ÷-í³‡^º>ûö;÷2hÿÅãLÅ‘÷`G­=_Gð,¼¯gÿ;ãnÇžv{Zõ¶kƒüPpÆUH[¬ç‚Ï þ4÷¸Û¤°º…$¿'IIÆÃØ[ˆÅJ’¤ïRðÁÜ×?«¨7ìªcè°ƒ9X#೯»45ÛíOôU5·Ö~|ö[{AÛ‚ŸÐÊ{OøÏY]ÕôV™ÙâúÞB̧såõmî&®veêü_·âjîƒô¾v#A'»ÈMÙÐûëÔ]Ñ3q¦Ì’]sûº6)™>œ®sÌþŸå6)ÿ°‘E½7sÅg{!9ô’à2£hòû®} &KH‚Ó´BÙ÷øÛ€»tÏô¾0‰Öø«ŒÆ ÜAÆ~;„‘%ÁŒ, G¦|_› Ì‘'…[}ôvpãvµÝ˜4ÿΕoÜ&ò²µjmܘk&š oÛ7“±w,#¦=T플Ú=^®&LAŠt†ÊËeZ£z&ÛN˜Li¦`åv0ZC†³/¿}þŒ™/£Y:°ô%µ¡žê¦IòÒššr)Ð~WßKrm³ìMÿÎÿßm)à•bfn(vó2Í7¸ÞáÖ”ŒXwÛwA}¸­… }& ­B°ÉÇ`<”)4ÄGØŠÜb2)„CÅ»HÈ–!¨ ¢l$ŽÇϸÞm1Áša(–U¹(wEñÓÄr¡dZýØ&HwËôýí"»¢ç®¯@2³"D(œjCoux2e`Øà^¿4Iqi;¡cÌ"?ØöXî,T$á`yñì‰!%ãÓ³'ŒÅ {BÕù 3(îjÏ*Ó°M> ~‰ID­ µ5yŠ'Å=.{Ç£4„Á{°Ç)ÖIÐúJÓbV»^ú—M_ÂKÍD0Ì›2Ú† fô„û!Á¡N7iô"`ð4»ìp·=S`#ç£u‡ÿ®;Q&ƒ‘G,Ôòfˤh¸²-ûA°ûÜ¿|°Ç"<Õ3!S~Üv%cŒ)¥º¬7…i 5¢» Ò0vi³«Ñy m–74-@C³¨BS /ça€!„†¤°‹P¨6°­ø]aį& ©O ƒž‹Ï'$-T¬Xh™d/eN ½—ÜÑ¥Ã%¤`Qð 1Г HÈõ½D&¨#—M:¦غ€(™íµéÏöô†×„†gH””©‰dbû ÌÐxºWM•VE»NRÒLxsS†| —+§¬#êvŒë,[3C”mqÁCÃ>“ûè=w€èTqø~È‹‚”»1d3Æ¡Ð"'kWxˆdk¤²3®ôm2°íox˜*! HWÀ-ŠöðS e^„ýS`EW :ô¨vÍ“ÙêC‰¦Eo¿ª¥fvýd³¬ÍfiÊt¹Ih÷M_éÔQGÕZ­xi¤ µÏ-’„ ‹e<ÒÉVCãìÝq`!r†VÎ8¦'ø!ìS׈ÕdBBwûy¸5åþxÙ3¥.£JG”ŠÊ±®†+ @_Ö²Â~éºð 5 ¯mPY½™ÐŠ!ß©_u”LÀlÎ$(Õ7ÄA Wéö€€Kºå”b‘vË`ÁtEsòÞ·EÀùì aC&Ìá‘ÑeÂfw0Aïyi{\5›¤T ?wWŽÇp|îmH ìkóA«Ú¤B-3w[² Çû‰¡Ô“Ðãðžåÿ=[=úð‡×Õ$ø“Ø‘ëqÜ)­Û³Ý%d(ûÉ¡X—}«Ü›šˆ^[ƒ>ÔhÏ+0I!&”^ðëy²î7Z÷ŒÊ%©Ä@ ¤ÅÖÒ5OñÀôHtõ>N"þÛœÿ;… b=4Ìjéã‡}üº¬ ÝÑ>¢@ŽÆŽï!^ÝûGíâ¥êÛ]B-ûò/>üzõá=fÝÛyÌ®[ˆ¾²> stream xÚåXMs£8½ûWp„T¬è ¨=e'ÉÔÎì!›ñ-“rÉX›PÆàÅ8™ù÷Ûú€&Ï&©Êî^ jé½V÷ëìÝzØû8ùu69¹‰— DPáÍþôh"Ê/ c&Ì›-½kÿs@¹¯ª…ªÊm0¥QìŸn6y–Ê:+ ;p¦Šýû€ÀļܨÊÜeKulï¯T®äVÙ?QŠHp3û49ŸMþšÀƒ=âE¶Q„#/]O®o°·„ñOF,‰½3kí…"†kî}™ü1ÁŽ F(`DÓ³ñ*x°7x5ÆZïJ0Â,²„WÕ‚Ï宾›§e1¿ ¦û*à~ ´€àº ` †µÝ-V†´þùnø´€Z`Çz÷(„ß0Øp€\ÑA…½) 4ï€RU¥£¬ÙRõö;¹N°8T]‹ÚÀW6ìÍ;Ö„$bÒ˜ÅÛÍþ)aÕ8jã¹oõ€‹»v!Š o,µ‘ ÷¿ÕÇ/ÃÃܲ¡{ô¹Þ -ŠPˆ“f‰Æ¹¯„oJ„@$Žà† „wcNl‘—iÀ°¿zŸÀ(¢qƒïèh¥STi3kOýàèCØ—D“'ãaýƒ+¬Êº|NS |HlWßÈJ®{Ë{æñ€¶u+ൢ3ƒD(alÏõOÎYéS%ßóÙØÇ4t¶ÔÚž_^ÐywpîÏÎÏ@Ä8ö¯Œ.nr™ª¥Y˜ ìýPDô\H»ô^ïmt£=^ÚÑÈÅÌ¡J61 ÌŠ#2–óY‘Õ™èÔÄyé4zj/ä®géD]ÛÚ;“ÚÖ¿fÌ.bï[Ó4ÛÜ5â¿­µZJcˆþ-ÒhÝ.÷ŒÈ"ƒœïDÃw«Šä)Qq)D}ˆß@n’%1ƒ8Á(¡ä0¹vÚuVÜØˆÊð`é¨-Skò{¶¨¤Î€Vöù÷ºUzŠóˆ`LÛ†爱xãT ت¢~lÔöÁìÏ$BT«wWS«ÀôEºº×©'óÑ%a©°cá–¯[é+%ø¹ ‚fT´ŽÆ–É—]šªíöû¯¬­î`ÿ!3bcΟжí+×ôÕ¯Œ§,ÕÖT©à(ò¼¬DŽr‡'ú\’ÇZùTªì'/÷ƨ.-†]ƒº•P¸ßêUjY»Gpœâ²^Í7–svß”çª3­Z>5M©‹ÔMÝ7\ªá“¥¬å ëÓ4ŽÖ9iªTGc»,× ³ÈË|nÊ”|ç%c´+ ?4Iþã}4í!j]òlsJçmhâ³H]6Ûì¶hÚª¬pAXéTÎUqÜŠ™Í›»ú¥…AÇÛïõ„;éâú¨R2_;s+Zó·‡õÊr7ææå^Ër=ß*€ø&ò#^K~oë0d¡Êðè%<ºD=%d°VkrÔL8²-~l§^/ס!¶!=,ÙˆùD%_𡳻ÌuH)$Ó^7R¸>%/ û.ëµPº k;Þˆûýw½áç=ˆ*þº7ú­.¤ˆ'KLE˜˜p_'/3n u=x> stream xÚåXMwÓ8ÝçWhisˆªoÉËÒ̆)Ù1×Q©OØ8.Cæ×ód¹‰íº™‚› lEÒ“î{º÷é)}A½½YÌN.EŽShqƒ4CZ,"ŽKô)ø+d2°Õµ­ŠM8gÚ§e™giRgÅÚwœÛ‘à[Hab^”¶òÝoï³¥}íÛW6·ÉÆú3†iøyñ~v±˜}Q€Bõ[ ¬‰Féjöé3AKèæ‘Aÿ6³VH(ß9ú8û{FZ7¦€ž`¦¸›­(ª`àQçÕSS‚ ×Þá»êZÆi’§÷yR‡àRœÞÚ4œËà.¤$ØÜ¯ä»­w1n-àSå! ;ÂÉ¥Rý š3ðdg{[U.ìE§ÅÒöö;¹Àô°8/G°{àw-`ØUvì(#X:lÞð"‰ßæWݘñ>Œb]7”ø^à¦k'°¡òÁÒÙËà{ýzΡ9@r¸xÔÛÒ¤ŽX´Ãä¦ODÖjžãS—EÖFª:jN .khPÉ–.ÙÚ)L/³ÿl\ûv¶Žs»þRßNDm(&f"lC°6úaµËÀ®ûe Ï©¢ØhÞÒþø”[d€cÏÎóWÅ}º÷„˜ÇZËŽ–èxŠøŸoX•w]\ ®h€+ÔøÕˤJúÐQ3<à…@öêsY†jqÞáôØ@¶ïmO§7Èög:fÔ9Ô±áÇ1íÓ](l˜èÛœ_|¸º8s©ñ4”2X\œ{þ|´Ö7üAÇ«äÎ- ÐÔy»‘Ësûóyö­1¸2ÀîXÖ%×àŽˆ½GY0ðsþ[U4ñè%zÈ „±¾Ûô¾Ûk@ËH`*ôožâÙ‹¥ø‘‚²”ŒŽ lÅÂ%1va”û99 UÔªúhb²ëÔÕ2Ø–P€ÕÇ©·ÔKÕ[í¶¬Gè£ÖJþYœVÀõe]…‚Sk.Ž™ìÇ뙘\¼Ü»‹jèqåí©% «ˆŽ”,^Ò@€ºŽ¯ó§¸ƒ!eXtŠÛ9éN=n…9Óš}sìƒt2ò,Q˜‰—O¸œp­>F%Õ2¶á|õD36Êö÷ý˜ÕþÐF7íEð×릫æq_æI %\ÓsíØµíeÿWþ×é‡w¾q㌒U–»ïm¨e€{Q¾éáðݳå™OúѺ`˜Ò6bT*ÀAŒ!ÁÙmâ/ˆ†Í ‡s%¢à¬X¹r¬ÌíÃ?^¹^{ÓZÀç:mGæí¿›ÐHÖKßX&µ›™¸›u3ôô5w* endstream endobj 6985 0 obj << /Length 924 /Filter /FlateDecode >> stream xÚåXMSÛ0½çWèh3Dè[Ö‘–)½´47`2!àIˆ]Ç´M}W’1¶ñP†¤th/¶,KÚ·«÷vet:¼ öŽEÅ]!–̸AZ$XŽF3t}Œ™Œlqi‹l™N¢ý<_¤ÓI™fËÐq`cF¢o1…‹,·Eè>¾Kgv7´OíÂNV6Ú÷ú7¾Ov=qo¹ßQgUo}˜Zrd ÆQ cµ©O’ÄoTGŒ]¡4ŽYÍZ¿°ËëòfÃ"*%VŒv1÷$ž6$H<µ|P˜Ê¬ÇE¤ØºgpHÑ/’B\_ùs›å‹cöÏ–²sÂÅ2]ÝŒç>G»ËúÏ3µ­/š«4¶ë~iø<•ê¿ú¨y»õ Ö5ÆT¢¥©~½ªr+—º¿6€-L=ûÏFï gZå-HÇ8*a<¾êÏ `s’bžÔ ¢Rw‘ýp‚3Ñ endstream endobj 6872 0 obj << /Type /ObjStm /N 100 /First 1006 /Length 2226 /Filter /FlateDecode >> stream xÚÝZ[o\·~ׯàcÛ.çÂËF€$†Û-Ä~H+øÁu„Âh ¾é¿ï7ÜU,A]V8Z·ñƒ<ç,9ü8¿ž6ZO%µa#‘ºÐ5©jª£ºÐRgu¡§ÑÄ4.…]²D¤i”DŒGHU4. q¢Z»¿ÓDÍ\TÒÙ£%²îcŽž˜Êì;ó~XbÞ×JâÊÍ%JÜšC1N< a “Ä&Þ×4IéÞ ÓìÑ’HE+%‰BU¯UØß¤fþÎ’4*þŽ!UÇg’ñE3»±ï1 J!Õ¤$Õ¥ž”ûüuÀv>í>ƒRm>#XvÀTY µêúZi>ô™v¼ƒqÔÆìÛR-ìúˆ ¹­ CVžHi¤ª25[‚™}–\Rí$.‘/¹$©Ú0Œá«HnIcç6ÛAúZcÈê–4²¹%m.ùsúÓ’"©ó¾¼³¸MªÃCFêRܦPÕ¥NÌ.MÛ+úêTgëÚÅßAK%× G굺ME!M;Wôíâ’÷µ9†jÓ_LkÓ_L[Ó_܈£ú ?Œ6g©–à¡n Ó_¬rÂÚy* öÒýaaÁ€aî/Z²&>¸²õæ£5Jæ ÷vi"hÐgîÞ>ߣCl³%ŒR¨ø€ðaˆ:|ßK4o’"äÈ›¿­ê†rÿ„o 2Èë°fqh±Ë\v£‹ÏÛ—H¦[bÕbÏž]ì^Ü\LÏž¥Ý X[Ûÿ{<¨Rkñ_%àÙ?aMñ$ñ[ƒ¿ÃcöOAËpøÍwÅØ?}õÕÅî»÷7o_^}L—i÷Ýói÷êêçéõ~r,¯þõÏ+üðæïW»oëêúãßxæý/vß_}¸ùôþíÕ‡ýfœïþ|õã»7ßÜüœ.‹Ç-ìÌnü½yÞ¾ódßðëëëh»Ü‡4Ç3CÚAh!ôFvF BàBá…#ŽP8Bá… -Z(4 !4[h¶½æ;6›³»Ø½üô·óùOï®ÿq±ûææýWï§eÊëÝvÜ}{IóÁùËÐ)İV{&ÝZò ¹³s‘Žf_Oßx™v¿¿yu“vÏÓo> ã»›ëßekå·¾¨›áÚ²º'Î ‘G¨ä.3¼d-òŸ‘à Ñí ˆÖLólÚCQæ¼ß¦KPÚØŠÉm´#”*#—Æ‹PŠÙ† Ô,#$¥ÖK®Ÿ"”û<)ƒ œ€‚.Pƒ×â< (Z|ÅÖ ˜É†ë#¹5 Îó̽-…Ÿ`¶²Éì¶8œòÔúlé*‚(¢`G(ýµ¯AA4ÜÉ!¼‰X6æcxÓBðåsF7Ò\qÚȰÌ86$|¢Rr©ý¬Ñ ~!•Pd”Ì~¼¯AÙ4º)åPÔZf²E(ÛF·^s{’ÞV‘ž;軌‘è¼Ñ­f] (È%2ä/ESès@©X˜^¡Xk®¼ÔpºqذdÏÇzˤçŒ(Ò$w°ý¢à)8 ‘´¾åâ ¦€h䃙p-!!ô Â[El)ÞÈýÐLꔟè–~âê¬$xhHž–ôÁ[7°È[“ uÌMrÇOž§ËY™)Õùkêžw4ãtýé§Ÿ^?Üé—…FqAN6D®žueXçd­ßiø`®¹˜AÞË<ÌQ›kɽ\Ó‹-Í5½@4ó6¯„ÂázmhÃÜŽ‹æ6÷ò‡ëÈ^³8&ÎI:ùŠL&¸‡2 Y]C²iÐ<Bj=×_Bò|Šë9¡1RJ„L¡UXFqÊ{Éã„uq¼ŠP~âõ¥E([2£UëãÑÓ—ÉÓ©“|ïM/Ô.ÍÏ"þTœ©" YWÕ…†H9¼Hz²!C£Ôqº!Ù@VÕ#ìÿL5Ϥݰ¢°a”"Œr B"s„cŽpÌ¡‡CDwáä)ŠoÍ@ÜôKßàJì$êÜ=q®2¾Hñm4D€q„¢àÛ³ê~öÚÛÑ(‡åÁ¦ÄVŸÀÊàÿ.mâ'•”à®á'‡(õ³ZÈåˆÃ+€Í¯¤Vplì%­e¿ª (ª87ÆX…²¥›D‰ [Fù¶‚.} /äs.l2Äf>ØÍüÆ Hù`³qÖåÁñéžP”znm,BÙ´„„¯3¸ÍíÞ!„™VôœËƒ‘›õ#ÏT ²%$/èÔ­Qÿ«ß;®@¹SM™ÌDê"Íú¬á¹é½Få¦wVjg§*rðºÐP‹=@Úî4ô ·ÐBCÆN@ð:ÝÐÉwíÿ.nå>»«ãñìNƒ¹i07 æ¦-„ pNƒÂÕ ‚5(\ …5ÖPXCaí¿Î;VdUE÷w¬ÕÏ,œÑ“\ Ÿý„\PüŽ•ç× kP¶,r«åù‘ÅJEtlE× `[Þ›É4·‰<ö÷h+·‰›"9zJÜà ¹–nðhCîKÖœø'¿+ªˆz\K>$è:ì¬5¬Q3#©Î~iÉÜjÎúÞ¸¥œs‘èœç£PLœjN¿ÉZó"7wô~Þ ãð´ìeòï¾eÓ½£…1·[$~‰¦Èh׌²í­f¬ÏÁS¤‚»ÚȵžØÆ R[RN,Ýú¬‚Õ—gÉ]£L¾Tm‘s~Öð!Îy·ÑƒœóNCuÊŒw§¶‚ Ÿnçß¶p_˜‡âŽñ‚åÑ”p¯ûsJ8äñ”°ËkÁòz°¼»t¯Ý‹oý,¾õ³øÖÏâ[?‹Oü,>ñ³Ã'~¿º‚ß!0LÎCz Ü_ à; Dà^‚ò$;DàþÛÅú<%÷RññI÷± zÜ‹eÐ-rØ=}_ic„^^àerê\E¹áêø§^›> aeô5$¿Ü=ÿ,ëR endstream endobj 7017 0 obj << /Length 1031 /Filter /FlateDecode >> stream xÚåXKw›8ÞûW°ŸZÑ[°ÌäÑ3M'õ®íñ! 8œ` ˜&õ¿Ÿ+ »àP×µÓvº±…¤+}÷õéJØ›{Ø{=úk::»æÄ‹P$©ô¦wž¢žâ!âó¦©÷Þÿ' Â×õ­®Ëe0¡*ôÏ«*Ï’¸ÉÊÂu\ê€bÿ1 01/+]»îן³T¿ríëx©ÝA”"|œ¾]MGŸF `¸­9RXyÉbôþ#öRèãaÄ¢Ð{²³—!üç޻ѿ#ܪôQÉÌlI¼žuÞ|Ka‚fÊ)üPߊÙÌx‘-ïg ‹ðã"-³« ùYYì›Í7 (ÍNŠÃ/¥±Ý ή¥ì ÀÞ„r(:t]×õ,)SÝÛïì wðÃâôìße{‹[[¼°©èˆ"–ÑZîØír¨QÖC‘”EcMö¥ÙÂÏ®G!ákI#¤&ü/ MÏÒ,Ó O!ÆD .p/Ãþª²Ìnó2 àûaÞ".7ök+ñÿðê8€q$‰€A‘èCUf­)ëïYRm,9®šzÈï1Þu;æïüê¬ ž2‰"J àIèV¯â:^ô–÷ì°êëè|&tbò(±–¾Zxh\‡ýµ¦=sL¸D!åítê¦_^½½¹º0©uáO¯.]”ÝXš«ò8Ñ©ë¹5‘°rmϳ±û:û·kÜ¡x‘åæ(á£6ö¥£-.Ý'’n%³y0%u1+t ü§_œ} `‹õi üTØÍžŸÌ:buŽÂØinÙ#¶¬r¯wbGd“¼F´p2[6¤ ‰P>…£AJN(¶™¼WËÝÜ&]O™Ã³c“ÐÏr¤MÀxblê¢Éâ|éNpý[dÎ\øèz8‰û³2ª1Ï—»Ð@Ý(ÍÒNª¬Luº< 8—’£s9Ù„ÿ±…ÔT‘¨ è•NwÛHu+¾qVØ`;ÖJœ!E¶N€½Ñl<6—Ÿ]ð/.$2 OÎxL1µÊ Ô,¥+KL '=FܦKë#ßãÙâÖR ; vtá3·SKGfìÉy×yëDÏždn/™qž¥q˜ËØïÅçùЙNA2$ÿsZgѺzZ?¤D›©ìëD¿ö9½CDŒM¤¿­G?@ë§/d¹=&×wQuÊJö0^g/Áëôd¼þh¯±Žšú¬ÞZjû•8‚ʽéŸÜ8E„´**†Ø¿¸+Cü}ë°¯…É#ÿ¢\˜³ Êõz‚w'Ä]+aJý¤™´ï•öº¸H]ÜæY¯YUz¹­é5«õ0 endstream endobj 7046 0 obj << /Length 1011 /Filter /FlateDecode >> stream xÚÝXËrÛ6Ýë+°$5Œ7ÀeZÛ™¦›ÔÑ.Éphµ4’M–dêøï{AP2¡rd%”gšn$ ÏsçÞ#t‡z7ûe9»¸%8QL¡åŸˆO‹„£e>E¿ÇLF¶¾µuÙÄ ¦Mô¶ª¶ë}!¨€ñ÷ˆ`žôØ­ºGBøÞ¢³?f¤·…` &Ìw«E5LükðfÌjw+%˜pí ÞÔ·2½‹”D6–Q›®ÒvÓ¦ëv•VYÓ<Æ0UÖEgÀÁ #Æ]§| £<’ÃA@rq­ÔA &¥ °uí¼_Öi^6¸ïâpŒ€Ã ;4ÁŽ@ïaÃÝr°›JŠUBwÛ?Iüe?jŒ„< ÀäåCÛåÇ·öÀ n†û6TîvºM6æ2úÖ¾™†‡s÷ úL¸Ìîšch •;Úï*+—ñÍT$cF$YQÔ1‡lkŽ¢YP¥ (NdŸ'spRã<Û·$‰æî´© e‚Mf“}ÈÛ§Ê žÂT&»]ó[?Ù]'ZH*ï¬ìkëx¸z Õ‚Jä>ðZUÛNX¥=ÈÎw®ÌÝó*«{ÇzêsGÇb¢UTœ@½ ’g¹3lõ‚5ýVoŽê‰âö:°vª»áPfgîÝ]gŠÆDí™2ÏkX? ØiDeSä©GSÍC%ÛïœÏk(„Y“Ö¶Úºjú4R¥Ë’Aý£ãÅý…o8•ƒ%˜zŒeàWÚ÷—*«³ûàxÔO‡1íŠôU_1] ¢ÃvÕÈeW‘‚é¾kwU`l³rlxåZÞ€c÷Xà2®;é9Ggý=Å(?×™ÖŬûéâFvq é 6ëâåÕ‡›«_]¨ßÆRFË«KÏà›NÉTÛ,·…¹uÉôäŸû¶ï–¸¾¹nÓ.‹Ó!í]ctÉûÔ>Ut(°ˆfNÑͦëšîãéuô†z-½ÑlìÕ([«ÿˆÔ¯$5øÏ-5 “ ßËù¾/:Æ.ä …jvÔsè`…ìÿ¢;ÇJ«ï“@'ð÷„ª8x»-;a±9†T…fúÙ‡®àZ_•Œ&:Áÿµ#9&ÏKΦrŒ»¿ & ÍϬvä÷«svµÃ5FŠ^í˜ÓÔŽ<®vøÙÕ;Iíìö»–ÐóàLB‡AèðW:Ú¦ÖáûèšLüzfôe‹`˜ÒÞ P¹q¼P"éPõ¯—>üÖ9LnöÝJü!²cÝw™ endstream endobj 7072 0 obj << /Length 1201 /Filter /FlateDecode >> stream xÚµXË–›8Ýû+X‚O¬Ö±ìô#g2›Lg•äphP·}ü€ÁäÑŸ’6r°Ý‰ =oUÝ*] ÏÞÞNGW÷œ J$•Áô)ˆis…x‚i| ÿލuý¨ërMh¬ÂëªZÎ󬙗k×p«#ŠÃ¯˲ҵk~÷e^è7îýA/u¶Ñîƒ J‰>OßÿG à€¸­9Šqä«ÑÇÏ8( ý}€KTðÍŽZ\*ø]ÿŽþáÖ Œ ÇˆJfFKÔÐñSãÃ!ƒ F˜ÅÎàEý(ÒçhBp¨#6é|6‹&ý6oféÂi/M4aöhÍØâØâ¡X™McO®¤Ã³ßx®î¥ìÁÁ„rÀ*zXt]›”uš—…öö»ºô=S`q &÷ Ñ{è—Æ†Eo.á&,ÝÜOX`·ÓïZ"eă’—ëÆºï{³gSý‰)»™f’Ž˜¿7oÎļ2Ñ'ÌDö¼9†ø(ÍÒnVYÖoÎE¦¾o²¢¨#ŒÛE#$,¹µa ÎÙZs€:D%Á„”ˆ–Bc³ôÙˆ ÜG¬×yóRéhÉ–ã…~6’Xx@*ç¸ì ‡³S &„2$c¹ç¥ªÖ),1K/òP1î¡ÜåÝAo³­»²Úö 5u,4óÏÄu]$ÊOÊ<ËÍê³N‹ ÄRµN“mnš¹€r¦Ï§Wâgfî‚ZÏÍa™ì²¡†ñç"Á(Q>”E‘§Mu4|1tËÌñ¸†Â›mÒZWKS½_J®P°™ê•\2|˜œø…UY?Vœ(ĸ€zn%í©Veu¶ò–Ún?¤¶Üå\6ç‰!8´«&Çl ôº[­`KÍP‡Ëý¡È^sÐöroh߬6™ÀD— ötvé´¿àŽ”ƒ½n»b‹ë³ÚÐÙO>Ü…ÏO .‘¢ÜGz{÷ááîÆDü:"œÞÝ‚æ8|°2ªZf¹.\Ë£5Ž·šÃ 1Çõ¼I-™÷²ßʆ%¨åøk5Ïžà«!áÔa¹c·7êÆ@€w­ƒìÜsJ'`Z>}5A+ç…sŸ'V(h..ÄÊÖz8m·ûþ¤Và$R­oõŒÎŠË“Ünoy­‹rÕ×òFÄËK‰x‡¼E­‡Ž‚=z™„ømõ.Õ»°'YÏ€#ÆÄ¾ …àšRéÒ3}z™”]ë(â½DÕvÝÅeñNHÇxÙÖ)ÃW!•Å4ÞÉéÝÑÐÃ|ž<(V‰/®ËyöúTÔã­àWM=ÄQ ²$¹x¹cŒÂÙÊõKåîÜiËÛŽ C¢¤'H†ÇuÇ–ÔúÜšú ‘§c÷uýá/÷òd&e«y«Ac"Ï+û÷/H*_}ý2x™Â)"¤u‘p`¥px3ˬ’ˆ,—ì=DÑDò$¼)W¦*WKÝ pýNƒ<µ3à¹ÎÛžI{eÍ„(î¥ÈܵÌVIö-ýHc endstream endobj 7101 0 obj << /Length 978 /Filter /FlateDecode >> stream xÚÝXÉ’Ó0½ç+t´§°Fûr˜ ¸ÀN@¥GC¥²Ø8fû{Z¶“ØR§X.^dµúõS÷“d‚>!‚žžŽG—·‚"‹­b ï33n‘ ËÑx†Þ¯B&—O]žnˆi\eÙržÄÅ<]W ×.d$øRè¸L3—WÍÏ¿ÌgîIõ|ç–.Þ¸ê…bÆ0 ?Ž_ŽnÆ£Ï# x¢H3p-°&%«ÑûÍ ý%"˜[ƒ¾•½VH(÷%z;z3"u,S`¦¸ï­(ÊáÃƻ¾¨½WJ0Ạx‘OådQLî! ÈMܺðÉàG yçsç›ãhWaTå»Û¾/o•j8&(bpɆ_—çžï4Ÿ$é̵ü]ÞÒlœ@x]Ð5à+8” +0zkòHR9xl²¥ I×E™ß‹tnšv*·–ÞÈ…\ß‹'§ááÜ?¶)q?ŠxZO!')ìàÒK+¶öõ¼×F.™Äʈ—´?9~s‡QycÔˆs… §[ƪѳ8W­á£ØR" w)›DÞŠ}Ÿ_TcËëBndE+êH€K&êεËë›×w7Ï|*^…Rã›k_$xWÖ0<”ì–Ù¶ð.a§=Õžµ2àuSYÌן…‹g¸žçc‹¶S±§Ø4뵬Õx=KW€Çg ¿œ©^ÕPõš×€]_‚iÐ`©þêb-§Zªy=žÆœË@·Nê¢ÍJ“é2M|ž-á5 %÷E\A:.N…9-€Y:¯)ÌÇ ÞYfP‚'¢‰˜‘0/¼­[É;Š(E°ffGÔE£Žwœõä%¨¥zpác\‚úÀÝ ›T÷ZÑì¾nµ5¤$(ò>Ã…Ïó^Bè'?¬Ÿwån*[Ɖ›U-ÓÒACT“ÉEõvõúEõpïâÕ|–›-ƒá4ËÓÄm6çWÏÁv;;Ľòi8¬ÏË'}´~Š3mvøysP·XYÝÝœ…ÄvCp0©Ê¾^›‚Õ“Ô`cíà:E%Ç ÖèV¢£„J*vP¨ªÑ+B›"Ÿ¯?M ¯Éé?$E[Üé/Äè8xý½{9u¦½?“I?•ÅTµW Y\ć° cíÎþû°˜„-ÅæL›xYô‰7KÌð§k Ñ öGÅû`?`/Œ@üâ¾{®~ë\Kå«,¨ì[ Û§²WªäwÙ¨0uô»Þÿo‚Á™¢FÇ FJØbýÇ!Oˆó}ö@=t‘ý…€ÝÒ endstream endobj 6991 0 obj << /Type /ObjStm /N 100 /First 998 /Length 2180 /Filter /FlateDecode >> stream xÚÝZÑŠ\¹}ï¯Ðc6j©ªT%YØ]ã$€±ý°‰ñƒã‚É2fưùûœRwµ=3úâ½îÆ®¾S·îQ©T:G·u˜¥’tXO• F/‰¬¹Q“TrƒRkÕ MÚGªM9û]Ý’©ùK½t¿ÒS—±©ÍjêcúŒ4àŒ+- ó+¸\KV£d¥jªÕ<ÂÀ5iÃ-Á]CÝj©;*|­Ýx«'*à‰ª D)O€‹ ™[œh".E0´RÝj‰:Ï;4‘–%®U܉©Ñ¾%1û .7jnQbÕ‰™Ûð(¸Ïÿö$cÇpòW§Ÿ[â‰Ãx¥bøV¨$!®H¨û2ΊA»Õ ¬1#·$ K`µ‰€$I ‰Ï,M­VG…á²aÔSÛE¡Éd¿s‚ió(\SëÕïeLõÏKÒÒýO;ÑôÃTpóÈ^)2ކmßÛP£Æ ƒéÝüZÒÀÄã4êÌ4¨{ÆQ>CÈçCQÄMý^Õ4tæÅJž~=aÓoÌŸP½ÈÉç_Ë4GÁcàU‘o󫿦ú#±F*ò羸fsp¦nªùÚiìÙ,nj›·aõ_e0qouHV< (ºyòd³}õßÿ\¤í——W·›íËÿ¼ßÿúþòß›íW׿\\¿.èåÍöÏÛ¿lz]ç—ÍöÅÅ»Ûôš…ó@)ZÍ‚j¹#ûÒ[f3¸ýž¨ âíêû¯~¢>@o¥E}Ô‘ 98?›`¨|õá9àOt¶ë®íꃧêhõ!eäμT~ Z³R:té¸#„ UÏ¢„üåÄøD ôN¹xr%Ä-Eø£jâ'¾gB„nfN›°pýgÞ܆-•Bë¿|E¿tÑí,Aé¤o)ZÍN¨»X+Þél Žûi_S(gÂd—F„†²ʺ/é#)»Ùa¬a¶°£U².íwr«ÊÄ9ŸWÍ2 w,09¤Õ…÷Žãc÷¾Ó£÷žãã÷¾ãç8îçý,Áa;¢¾µ|çùµÔ‡¬y÷ó¤/cͼՂ÷ Â=øoþÛƒY÷ Â=ˆp8=⌈3‚Pˆ3"Έ8#⌠Ôû_­Ì£ÁBáy4ž¬ÝHÈ^†dåÎJc6õ€â‡KM")ÜÉÿo™à endstream endobj 7122 0 obj << /Length 1033 /Filter /FlateDecode >> stream xÚµWMs£8½ûWè© H qÌæcjg.™Ä·ì…AžPÁ6‹qf<¿~[HÁ€q&{.6HHýúu÷S‹ ïˆ O“¿¦“‹Û€¢G‚ 4£¡08ˆ|4ÍУóÅeÜQÕLU«µë±P:—eYäiRç«¥¸V.#΋KáÃbUªÊ Úä™:7Ï÷ªPÉZ™ŠÃÔý6ý<¹™NþP€B5¦’¥‹Éã7‚2ÿŒö#‰~4_-P $üèaòuB¬S@O0¾þZPTÁÄÞàý!‡)ÁÄÃÏՌǛµŠÕ2­·¥jp¶†ZƒŒH½kÀo …18ƒ·Bt¬ä±ÀðŽ1UUšäU§«¬oïâàu°Âæ|:ŒÌñÎéc!ÛÿNÌö…Ï1óiÏ~ºZÖMäÖä¾ì. °¤ÁëJ½H¹>w~ÖçÇò}xô{ˆ€ È@Ÿ8ÛR«ãY±J]x~  d8êìFgªYiý|,@} î%Ö.i¶Ãáõ)&;ï!¼t<[ó»ú]½€E˜©JpĘٽLªdÑÛ1Š#"Â?çÝÐq&tÂÓG¾•“¯½Y6âi/X½Í®oîîo®tí\ºœ;Ó›kNœûF³Ê"IUfFf:þ[ólÒ6>3o—w›‡¹^”,òBÿoÝ;ØFþ½Ú2ð â#»²b4²ÊçÛ8}R©ëqàg½Yü™§’™—êg‹v‹”èO«5–þ‡¤†õ5²|ü®ž…€BŠZLúós“v€oÝÈÔqà‚¨)‹=p:Ë,Æ·ðA¥s,ü¨_Ëg¦Raí±Ôq†b̵Ný:.W¹kõ¦@Ê6½ò¥åoÿRqmžóe\¨å÷úéH¸dU ×£QˆE0`t­T6\[è#•uƒ“‰<ã ¨r¯QqyJ‘oE|¨ïm>­Ê—ã£b†“š·1;{|~ü,yPªwl¼h-iZ\È7­ˆ:t•YÏ´îíÇèÿ!¤;©±‡ˆí0 fΉ÷î=NŒ3¦ס²}²ÌÌú®6i½©ôù“ÇY45ÉÃvÇb$[0=Ow›ÜKŽá½~rxë(@’e–qFI6hôwmM拉Y_i´C6kM³M¯_{ÐY›Dm¢©^ûœ€@`^¬±“v:×*-’†*sG|C$5I!–¯wMMR¦æV›S±ÅoãE»º#mx·„¾€‰w_-G/Š$+µüRÁ46)‰sõ””®>­2@ ìz þÎÕj¡™( õú™7©4·+¸î|íŒgoÙM_Ú­Ê,© ©MÅ<ý¢f¸´ endstream endobj 7143 0 obj << /Length 848 /Filter /FlateDecode >> stream xÚÝWIsÚ0¾ûWèhwŠ¢ÝÒ1,3éôД[ša[! `ˆmÚé¿ï³eÀ6z‘mI~Ë÷v‚†ˆ [ïKß»¸lS¨ÿŒ˜˜qƒB¡±0õôà ˜ômöd³YôX¨ýËù|2Š£b4KÝÆ• ñ.Nfs›¹íÛÅ(±ŸÝû½Ø(·îƒbÆ0 ûwÞuß{õ(ÈCE!Ö‡$DñÔ{x$(ý;D07ý®nM‘PžôÃûî‘Z‚)¨@0S¼¼­(Êà`có~›Ö%WJ0á¡Sø›>•*H?¯D\ñXñbD—C«ÐÊñên¯‹¥Œí±^;Ξä` Gq›ÍäCÞ /A_Ð…4¨GI’Ù¼­%)ŽIIÚý…Ë«@—5é‚OÐå…-òîz SRp?J-‚ £}‚%~ñgnOƒšg”GfÞmy^ÜxÇóâ†ë̀䦃9Š‹4 S›@8IâÒ‘>Ús(Áçõœ‰M‡Å˹]P"DnqY\Tù©\ŠŽZ-ÄH½ÂâÓÇ€Øè3Eäò<ž¥…M‹üm`÷NÜèbQ£XK³Šl[(nǵÌ~Ø(Gdù[G5jpÈ6]ñýð9^CÇÑi¨ß+O¢ª¸*÷†»t’z)hbŸ]`VâCtrÖø®“ àŽ•xsŠuØJ‘óA%¸}=Ä(ò`£›,vf²èfh^œø‹â)D'2l^eçÿ H,Õæ  LÃÞ ¤>ªÅÿ× lºQ'J)tf{fÃÓžp,¹ÙRc~.£a~´ Vë2p´€Þl^ÆA~P k(PЃ÷(”7!©ûjJx  7[XËö¤f†¥ ?ä+B†Øð¦§B)³Éxb¾Fá5žžÕL ØØ™ÈèèDÛDýrHŒ`—‹-În›Æƒ$*¢µê 3s¨WT£u1še‡•7˜KÖÆü:]•ø3_ÅC›ÅºÄÕt»±„™\í=ooLÛ´f8è)a*Ý<^Ö¶z¶ÒĽäE•máz 8ä$TħŠw…ý @»Ì endstream endobj 7173 0 obj << /Length 1016 /Filter /FlateDecode >> stream xÚÝXKsÛ6¾ëWðV2Á€ä1uìLÒéŒkë–f8[ó‹d[ÿû,t(Fj-[v2½ìëÛý°$ön<ì}˜ýº˜œ3â%(Tx‹k/¢^ÄbÄ’Ð[¬¼Ïþoå¾Ü,å¦iƒ9bÿRe‘g]ÑÔvá½ (öÿ l,%7vùC_¬ä[;¿”¥ÌZiÿD)"Á—ŧÙÙbv7#` öˆUÍP„#/¯fŸ¿`oëŸ<ŒÂ$öþ6»*‰ÆÒ»šý1ÃÎ ŒX¡Þ-ˆ·ß-^îs˜`„ÃÈ:|»Yò4S)xþ(cæƒ7žœ‡ñHöæ”n%t÷Jêc'ç ûÛ.’ H4Q³GÅUs'eN1J(µ²N!®û j#[YwYg ¥æÚŽï.†ýùåÙ…ý_ɶÍn ´H«×.%¡“¸XK»±5hjtCè_ÆývPÙª¦nÝæ®±cf‡¼,À˜ œ¹ ö{Ùê„éìâµ6¯Ù8ãú®ÏJ'ªïÖ Ä岡z4Ú¨ÁÉ Øý^æefP¶¹> stream xÚÍZ]o\·}ß_ÁǦ\r¾HF€$†Û-`Ä~HbøÁu‘@[H2þûžá.WñÆÊ%”»R Cš{5wxîðpx†»%U )”T9d.nH bnh,nXPe7j°Fn´P©Áh)4«näsòÇ‘è– dõàMCÖܰM}œVB.­?QCnŒ¸9Q „xٲʩù=†%þ%Xµø=`$ªÜsËä¤Oà^…¥Éï! Æh¤A9j÷J·2"W€„•'·(p.´%9{¼¬Eð±"1°JàBýÙ¸»Õ‚¤”}4FÙQapÉž d'á1Ü3XZ15÷“„ñü¸f·j!0„üô$âR“†¼ˆŠcw)} DnÙQQ š”}Œ0 U ÊäïÁ)¨˜?Ë9¨uÌ@ª…=÷ÌAké~ðGÇ,;2Ð5 Ä1!EÔ¿>ñìl¶‚KA²a!¨˜¡xAužfä¯hÈ_F«¤ˆ‡Wò1àwȤGé<Í mMC MÍý¯Š•ÀÉŸ *þ2 o¨Z=CF¡r?LY­Î{Lf¨­a} ¡yŠaYhÔãY MR÷«¡é!^óEæ~pi•|ŽŠq¾€R9áŸßT7Ùó‹U ³Ôͳg›íëÿþg¶_]]ío7ÛWÿ}Û¯ÿùáêçÍöëýõ»ë7 E ½Ýþ}ûí7or¿Øl¿Ý½¿ oJŽ ó†ÅŒiÃtÆš")&mpû*<{¶¯Âöoû×û°}þrƒ?ì¯þ›¥/—_nðÿÏ!’Øš£ä£Ò";«Ëè‘`ÈzP˜Ktæ(’[Ì™ç 4¶õˆ*Þ!Ñœ”<™ÔÅ ÌÏ‘)T59´Š‘d •õ 9Ëà(cÎr³H&ÉYNÈ6‹Ê±öœHTa ‘hœ•³à(ªÃ v¨ØJžƒ².g-G¯~‰RŽ@1™”K #ê‰&„ß’ø1i‚ Ò†¨` OÓ>WÄ5kJ¥Xù ÄH¬ž¢(ëÒ“cX;‰r]t2)«ÒÂ2Vh‘O)O5VÊ©-¯˜’Ä(`tÄ%IìA8ž;÷“õmØ~÷ýPA%VD¿úøË/oïw„‚¦YvB}q‰·èhptU³è¨«B–ý„I βcÊ=‹ŽT¼bM Î'r=s|±¿ºíó²R\ÓöG^˜ËÿDÇ«šâø7ï¾ê¸‚¬Æ¿yS‡ý Cl_^ïß¿Úaûòù‹°}½ûõ6¼ý”q/ßý´Ûl¿’ÝÕí÷}\'ÖÍþãõûÝÍ¡“è÷þµûñû¯÷¿†ÎECI,@¯—ï®ñ´ëõ£cçñ îÝ”ãéÍÔÑÈàaÈ0t6Œ2Œ:ŒCÀ·«z«øöu”zóBËå Á@2Á’Ë(‚e(‚¹¤¬Zê¡§Kû ’Æ=í$áÕ¢Àú¹Â©ÛAÉGSý˜³•èg4 u¢K”­¤+æD|Û ‰R‹BÒ÷4Ê“²àÇûdÁ¹Ó½²àÌQ+TVq¾œ&Y¨/êeG¬5ª¶ìHÒ”'RC¨XÌË~xŒ¥õÿ¯„¯$?\?ÐP4” %@CZð<¤iÁ<Œ¡1xh ‘yDæ™GdI—`‡úñŠlìf9jZl\ÖÜEÀ¯˜‹ÝA©†ëI(Xø«o¬†nþÁ@FxÇ•¢Ö…º]lÅj ÊDÒ; ­àR'¬™(ðè3Á êaÆ~R\|¡š›ÙÌ $OñOe2™Ÿí£Í–ÅDkë²ÕKØ J=4¸SP.‘jX.¨csÆæUõ)Vð $2ö§9(Åêú9ANèÛœ'~æMµyo¼$Wì|dCwyB‚ß{Ï’‹¤‚ýS¾ ¥ä?¢¶@.Ð$·U—„DÐ JEåÇx3P.’“Ôº2÷zëk™P–N™S^³Ðs—Á' ÞSöÏ‹—œ%¤+5¡IUü‰ã}ªøÌɰº¥å Gp]­M8ª`+ŽÈSùìiÙ™£¶Š7žˆ¨E .&Rã]œAH.: Š5™pT¤'Ï8¢‡õ¯ ,:²Hä2‘Q•ÒLzð"ýÃÃeG£hm"=5ÕJ}P×€^€L>Û5|ÚQü¶‡xp×P>Ó5”?Ñ5èô:$½Io£Y°Ñ,Øhl4 6šÍ‚fÁFd‘mD.—hÔå å(5”¡OÕžBjœ øiœÙ”RlýS¸„.¡–Ó¢.MYŸ`9!Á&â d É%RB-E—EK ‡òª=%ºëv…äp¦?å"9ÁŠí_|Ȇ½ÝŸ’ïv §ñš}5€øwC¼€N¹HFT®<ûw ô1?æ‡È¹(™NPH~žƒr‰œ`#‹†ž!£ÝNä‡C íâ–CJkÒCR>A!±6å,']•Y•^fTú¹Ó½g×å\S§~¨srü>jü endstream endobj 7193 0 obj << /Length 801 /Filter /FlateDecode >> stream xÚÕWKs›0¾ó+t„NQôB‚cZ'™IÛ™6áÒÉd2ÄÈŽ'6v·“ß•~â:¶“C/iw¿O«ÝACDЕ÷)õÎ.E N$“(  Ìx‚”ˆ±H8Jstç XäëòQ—Ó*™ŠýóÙl<êgõhZ8AOŒø¿ ÇÓ™.øj>ÊõG÷~£Ç:«´û ˜1LƒûôÚ»H½_¢H10-°" õ'ÞÝ=A9ȯÁ<‰Ñ;k‚„Œa£[ï‡G,S€@0“ÜÌ–•ðcKxÓ…ÚX¥®àçò1zÈæõSžÕAù™uta©Ï.y¼¢„  °9õËL›eg— }9‹&X—¶ uÙa,lô„Œà„1§íÖìAm¨'þ¼_ÏKCvDüA ˆ?-݇±æÞŒM쌾š» â3§8nhëéþ8+-a62Vñt¥pÜF˜!+×çWe¢h à Ö©²²öÞÈ7=yÔHÕ½)˜‘ØèRž"–Î̦К‘r7l `’ Gýu3¨W|E}P!Úöx­,“1ŽDÜ.ÃQARhÿwø»k<–¦2Ž“¨‰nº' Ä·Úv:oJa%ïÌ[–?l{¼ï”3‰#£À‰NÏy/ Bààç÷ ¼¦ÌæŸ2gHNxcó¢ »#3*êæ b+)ß™ª±.†¥bŠ,¹Z§ê«Óc‘O[Yïä0íâÛR2…´eJ¡Ídÿʃ`/ØüpÚÖ€3ñ‘‡_íÛÚNèO‹ZuuÐæ$ ¦t#Œ{§WŸÿ+©{«tï> stream xÚÝXMÛ6½ûWèE b.¿EÛ¤4E6õ- YfÖÂê+’Übóë3eG’½Ží•…¢›©áÌ{œÇ!±óà`çÝì—Åìîž'@¤ÒY|v|êø\!0g±v>º¿{T¸º\é2¯¼9õ•ûsQ$qÖqžÙoµG±ûG``’º´¯ßmãµ~mÛt¢ÃJÛ‚(EÄû´x?ûu1û2#à vˆš#ûN”Î>~ÂÎÞ¿w0brþmF¥— þçïÙ_3܆ï1¢’™Ñ’8%t¼üð\À#Ì|ð:]™„[5.îçØÏE±2}¿\I;×ð%Ìuw/eg"ì@ôHí€},Wb™†qÔŸæó>ë˜/Ä‚;ÖÃm½ÑYmÈÊËÞ,àšè|p$¸Ø}‹ÌP°N»Öe»þ#N?÷-VsÂáûF% Š2΢¸“q`“ ñÔ乨EI VOÂvwÏTæ#Nƒ€Á{væT`7 S}Wê0I¯£;…‰ ýæÄGë.ÔÈcØÝèæï±Ú¦\z~KÍ=¦¯ìÐkù‡™„ˆî ²2ÄRD 2Jh°¢«×–,X¶Év­+ûT?ºíÈ £¥/XÐgrg5£ãd —ˆ ±‰¶•Ž.ã„„•x>k‹M«ÈÍ^%Üf/»ú´ƒO§À=æÃ´I»$Á-IØ'^d¼¿03ââ„vMFB7õÓ*É­Š”0Œ|ê(a“lÌÕv^HFÂ÷û4ՆȽcªªl±' lУ €OžîĶ—|$cHL£`•þ²Ì¶MQy3D!6”1°e$d«³¨%ç§  }Œ›uX‡'3D8Øo¾¯^˜B¦Å¦ ˘ÍËøks¼YùãtP®ÒÉÚlR*¿îNÀÙwógŸ_‡—=OŒ åwËäUžÃ‘+;êýÀkܘa€šÍ~¨LŽ DDÙãàÔ—͆¡µÎG 6’fÚ·:JÂæplG¢ê·LTký¹­²*~ÈôzW˜µ[ÒaP×:[Fº´©ÁñG“>ÏÕ™c1sV1ûŸ¤¦2ÅónŠZb–í¤_WwH;葽ÿÑ…ÀÑe1ÐK©âäìÊp’ËH jj/èðXj"Ú¥Æ(Eu@ƒë`£—6—‡~_P_cLú$‡ºö¢]WäKyc(=Ô››¯ x¸‚rÐsqÙÈÎ)Ñ‚ý»ÈŽ~"¸AfFyVC…Tíð"V@ÆÉ³ïaÞªrŠi¡&REW »o6aá¬Íµ²½–È›K¸oòÔÈl‘èÝÛ߈/lö øµÕ/ôÌÛ+é?³0[Û”Vv+‚üê#‘~ÃT^ endstream endobj 7252 0 obj << /Length 777 /Filter /FlateDecode >> stream xÚÕWMs›0½ó+t„LQô…$ŽiÒd&šø–ÉxˆQ\¦ø£@ÚÉ¿ï ØNcÇÎL/$Y»ïíÛÕŠ )"èÊû<òN/E1Ž%“hôˆ˜˜ñ)¡±ˆ9¥èÎÿ°È7Ń)e2¥ý³å2Ï&I•-ænàÂŒø¿ óÅÒnøê)KÍ'÷~cr“”Æ}P̦ÁýèÚû2ò~yü!ˆ"ÅÀ´ÀŠ(4™yw÷¥0~æ±FêU3$¤†gŽn½ïi°LÁLr»ZRTÀÄÚàÍ&ÔÖ*%˜påÿ,¢ñd1/«ñr‘Í«À¯]Ykž§—\w6"(dìDnŸêyiìßN/ÁÂË*ceÝÚll‹¥Ýq@†Ù ¬£Ø¿0“<`E¾ f×òl ëV[j!œ‘ <üE–º/ Æ*¡:qß+„õ`å¾hÀN±Þ°"›O²e’D¼^µµÅæ*Œà˜1·éyËNj{¡Ô¥K1X<6Œ1¢--JÀ¯ÐÒ16¬S¼cW[÷@¬Ü§I•¼{JŒ¶ÿÆï‹]H5lÑ^¤Ä•Ì:Ò[ÚjDü.Ø-Êì-<¤@¿™Ùƒ©Ñ•›µ²CT¥ÜÎE h–L³Iß̾¢‰*äÂ[¥ÎE=ÙÇ}Ù r+‚ã¦ßà÷Ö"¸']!•ö(áýì«q­åÀÞ¤ EZa’|vlÒ"GrK}´Aªö©8y_^4=2­«ërøWYç@’Òð†„p»œ5ÅÛV6h¢Š$àÄ^ôúéŠO[z¦%Þ[…ý¨ÁÉCR…cÞ­pürv ©K̨ú ©çf>­~]ë ˆìºÖÿWÚÚ®æ-eKV·§tpêÃΤ»tarç.¬ØbàM­WÛsØÄÌ«,ÉK—uæ¯eæÓ¤z* >dSp –gॿÔét†| ï^Üþ䛯^/Rîu´9WAå8¥ˆkóîæg]on‘É•jèì_r endstream endobj 7183 0 obj << /Type /ObjStm /N 100 /First 980 /Length 1910 /Filter /FlateDecode >> stream xÚÍZKo¹¾ëWð˜äÀa½H`,°8 ‹µÉ >8^!0²Y6ÿ>_QÃÉZŠÐ„Ñ#¯vMw±ø±Þ¬6ÕÞSIZMJñoKUÇ_,É*üÒxRKÔJI¬¼=q¯Axn zIRûJZ<žpRà‰Ç\i0kj¯º%çDMTjHì Ûª'¢<‘6ƒtL$! ÈšQ  ²­`;lëñ k{ÃÏF8ŽÓØGp É8¹ªáh2äáH¥éVà¸DšÌ\@Yœœqò±¬±&fiɨâCx†µBçdÁ‹ÆÁ§¡#­õ"Aá­+]´8 (”@ƒ4ø4‰Øà³$ âR¡ÖP0°%i0¨žÄ! ”C×ý1l¥PGPж`œ\‡ SëƒO“6ŽÝÈàqPp÷؃âX2¤ôdÜÆ[O¦4NT  )Lp{0Cí „šŒ×ÏÜ_Kµ yÐP--ö…y*…°P|B Æ ¬­6g¥BmØC4ÕÐ.$WPЮ†ª–°¾BŠ*>…יžÆ3ìku¸ $×X¨V ,!¯ö{`E˜V´  öqr¸Yu+ÂȬñ"™#z”CW€ÑlX_aƈP`éöˆeÞÆÛš 8t t:¤ôÔ¥‡&ÕS·¡!8C¯ç0¬¨pyÈ´Ô›ÄɱQo-NŽö›¿xqqø.]"ä¡ýC:üíï?BL²V²cûë?ÿüæâ«¯žfTÊØfä’ÛŒÛb›Q=›,0Š÷¼²³HÏâ+‹ç‚³ÉÈ=v^ÈV¡}ÃÇr—…­‘ørä®O_Þ\ߥ/Òá%\PIûý’—0 R—ã¯ÐmøÞý/äXìs|‡ÄÀðžã;‹u÷œØâðýíÍ»WWwé2¾ÿîe:¼¾úå.výŸ_áÅÛ^]¾’«ë»‘Ǿ‡®>Ü|¼}wõá>+Žg½úéýÛon~I—%Eð#\œß`£··XŒ~Ïøõõõ ¤]Þ׊ÀÓ&°Q+ŽD›DŸ„ /ƒxvˆ½8¼úø»ñû/ï¯ÿuqøææö§«Û©¼9üéðç÷—4~Ä)ÞÝ…9rAv6-¹BÕ¨O¹¢\"f붯‡^¥Ão^ß$Xðw°ðýÍõ2ÊZù}¨s$Ä”£bŸ 88\‚ÒœöC2uBžÃ?5B?E2RêßQ#عV™@P¯rÔÔE ´§i8Ã)PTsGúG d¤i+%¶y~èIvD;‘åQ_[vÒMgõ}52Ï J8k_„ò@'#)ú¯“"J¥µ-ÌãìéŸfÏhß¶™`©B}›±Zɨ¶ÛŒh¹ro Ñifk |(iU}%MlQ›†—nó±G8-0z¢1xÀ(q²rh)=ã<ی܀¼ÂH’•ü·_L™íQ1¶ôs‹i\EF}Œ›È‘àIÈ$t6‰:‰6‰>‰cÁ È‘˜’iJ¦)™¦dš’iJ¦)™¦dš’yJæ)™ù Å=[åSq¯HVp»/QÜ'h±$kPzáÝk®N9.O¨¥ÅWA“±QS vT ¶Fo3‘àΘKŒVœE#hغ ͸…â:&Ú(ïÚžqÜN@p‡ÍŠþw È4b¸™ôÚî<ˆÌZWšâî.;jasˆ#ÈîÍú³hÄzŽÑ,R­9»mE râž>‚â'$ g¥˜Ê¬ 9‹FØ ¢ ¡Ds7nÚÊ­¼kØÄ•œOP#£º.!9‡JÔûG{®¹„÷–Š{ËV{ÎÆ{Æ îŒL'((ÝHó} ÊYt‚6Xúð’ ·Õ&1:zÎ+œr.•'Žv{ Æ9ÔAŠšçýÔ‘P;ýÉ \%RÛ ’]«ÞT ¢·$8KQ oFM£}s«G.;BA/ŒBÜÖ ìÛ Ü(ê\|¤pAØ@G„[g‘ç7N—{ÅŽËùvŽ?Ǽa gm¾ä>âÖ_p–¦ Ÿ2>1mxÈT}›Óc3\|1J²ÂHQ…·ù¬õ,hº·ÕЃ¶Fâ\·Ù´!”d!R@TïÆÒt# µpá$‚&ÓyÁÆ7]a44$}áÐä ÷¶Æj¹®†Ts++ãÒÑ<½ÛãXyj²:Ey8}ùõdæ³',Æ',V>Â"sl¡sl¡sl¡s ¢s ¢s ¢s ¢s ¢s ¢s ¢¾çÔƒ I[⛆ £6ÆÝ >$òÒVEEK²÷‡ì]MOíNw-ü%Ú …Ák¾¥sß_'ñõ77ŠtÓÃß5o}Ôè»vÄØ0þÃÂÐŒ¢-9ƒB¥¡"—}V84ÐNH˜QÈmÈ94‚²ï¢§ù‹ÔƒðóÏ_&Ô‚<þ/Ë ³h)$ÿÓHLÌêPÈÇI! 8ècÔV£Å>ôƧúЇLO}õzÈXÑMÐÿû¤ôˆ±Ô'Æÿ7È| endstream endobj 7285 0 obj << /Length 992 /Filter /FlateDecode >> stream xÚÝX[sÓ8~ϯУÍ¡›eù‘-ÐY¶dŸ€É¸¶ žú¶¶[àßsd)ÁvÓôÃÂK¬Hö¹|ŸÎE"è"èxñ×jñä… (‘d­ÎPÈP(G«½÷^ù,ðtsª›ªõ—,TÞӺγ$´ϴψwéSx1¯jÝØéã‹,ÕíøDç:nµýC1c˜úW/ÏW‹ÿL!ˆZÕ‡$DI±xÿ‘ æ_"‚y¤Ð—þ­ ©à™£w‹ĹA0ë f’›·%E ,\™<¹ÎaJ0á¡uøµ.N ×ö&nulu1¢ŒÀPÀ¯PÒêšN‚®'/¤("¼Çjìys¬‹øS–ŒÕÜA|Èâð|!éI£Ó‘p°(|<“`ó6o‚L6”‰߬ï0õºç}ZR±EpÄèÀ•tsâk³Ëº‰S\ 1ÿaõ£GöÝû¢ÚæÜ:×]»Ö‰K`(KàH+ge" ‚ßsó2ñ½·Õ˜j "—4Äî]]&ë4îâÃl_É0‹è|Hkë¸éîuD°”b õó21 Žxßêì[²€x Ø ¼nvÐA7„N×Îbf<(I´…éáf©Ÿ@»KP"Óô¯Á©Ô;Ⱥô¹©h-Ô¯Çv&;³ÏØ|si ^œåñi®·®.“Ò²¥‘S¬Â1‹P_†,²)‹×8Kz¡ ¶ùã[­w`J#ë&<­ïN˜ÍÉÌŠ<‚rî¶¼6p~í,‚F‹.»,Î[myæ âUÖÅ¢ïˆ*áùL'yÜÃi;’=‘0)À»T;êÛ¾®X+/çÍú rÖe»zÝâûÃz‘Ýûo’0"ÍçƒþÔ¶DD€•ÚÑ–deÇÙa03ΉÙf½¬ÊDß-0 r0ΰoL£Ñ‹êÃá HU›ŒsÓ¹+a—¢òf\ÔêA$¢0 oßöíWí¾‰A± “:w¬KÝlc@ƒíÊZ«“ªL]"®+—Ÿ~$àù¸ù-ÃâðzxTìá£È8Dÿ2Râ4µÍcÛî«’É|Ö~q†ˆj{÷¦®ÝÈ ‡ÝÎZXït™öw¦#tBI†û£ k@˜ ¹“þŠ*Éê ZÏÿoÛ3ši~aTícOòù¯+f©`æâÂxXݪùš^ôÚà[ßóí¼µ SêÎ#T*Óº+E¼£Ïqí›>Üòì…£ÄþRŠÈ;ª ÓK×¹Þ¼`×íiìÌ}˜c¨[Yº+Ï·ÛA\¦vÆ=sÀ!b¼…ÁÓïq’ôT endstream endobj 7324 0 obj << /Length 1069 /Filter /FlateDecode >> stream xÚíX[›8~ϯðÛB<¶± …å¶Rµ]~»+r5·÷U©R­ìŠÃÔÿ¼x7{³˜ý3£`AE Ts‘eëÙ§Ïå°þ&1úÒîZ#.c¸–èjöaFœ/Sp`&C³[RTï?Nym´R‚IY‡o른ÎÀð&¿.6+ŸoÛZû Î]/.ø'‰ €qP$¬ æ¾R测KPñß.šàÈØ5Ðf5MkÙ£-p‚Fp;¯@’Ú4EZ°ñŒýì7˜oÝ¡Ö>Ñ-RÂkTÞ-5[k±”}‹y‚y”t&¿Ùdïëå«Ú DèO?^ ‚ J}y`fD° ÜÅÖÃo†k„UÀÀYJ BŠcHÕVèk••i ˜u¯Ä ˆ"wÉm ÊÕÊz¯M76P»¬±‹×€ÚPÚëG¹F†>ý¡ÖKÕú¤§“3a‡_K«g¼Øê€9Š@ëÆ:½)²¡šgˆÂžx¾Bº?Ý`–è§Iˆ…àƒ4Õ€ÞÔ=Ÿ0xßõÐ8”Å8]}ÉžC·ê~Yn3“ÿ·%›$P Qgó —–ã$>{\µÒz\AO¶!èCL(˜H\½r‚l©˜ãA™pÝÛ…î:NãªIm2[x÷•+¼fÝ» >8;‡ 2kc@#œ„ý¨êb“UZž¦ $ƒ°Ÿ -ÚmÈÊšý3Ñ’˜³Ø¡»SÃÊiã^Yºh´kéÆÁU«´\ÿÂb 8Lï aÅ•²Üù¡á]?Ö‹Ù_$é> $Àò¤ÙtÞn¶*¿2ø D ¾@¥€,L4#v³Wƒi„æ¤Q-=¿ku""ªèÙ+cÂâ§ ƒI“dˆÃK…]ó÷¼ÏÖRÇ`çÝ1’Ï»¢Ø´'ÎXYž½:Ò<·|XëÇ€‚òóÅ‘”ÀÜ…ç.¢Ì¸ö\øÀn0„Ï"U§=°uÌ»ÚÂä¡j=äV±«5A¶•!÷i ÷ôØ)ÂÁØ'܃±O?gÜ“‡Œ{úô£Þh~ÙÕª›ê²r—››)bÕUÓ>¾&…77e±jÏ&S×Ã!Ÿtú>csú×·ŒÓõ<‹Ç?ÕG O‹aÙ|?†y‚`Ãôä’ ›°•ý›ÏMNîe—EÛ[€ãð1©ýŸòýS¢qןBC¨>;–ñ‡TÁ¡M}ówÔɯ¢œaJÉ‘˜a? Û³ntS·GO{ŒÂÃD’xT&ccÿ•ò<† endstream endobj 7357 0 obj << /Length 1469 /Filter /FlateDecode >> stream xÚíYKsÛ6¾ëWðV2" ÁçôäW2ŽÓÔuÔC&Éh(²9¦H•¤ì:¿¾ , ‘”[®”^z1)ìb±»ß¾@SãÚ Æ»Ññxôæ­ç1‰70Æ3#tЋˆ3cœ_Ì ËõM^Oy]5–톑y´Xyš´yUâÂ)·\jÞY0Ղ׸ün™gü5¾_ñ‚' Çq]âX߯ïGgãÑ_#T¡†ƒG{$¤¡‘ÎG_¾Q#ƒõ÷%,ŽŒ{É57¼ ‚ga|ý1¢ÊŒÕ“¸4ü¡½(0j l,^)Ã``¸C e!~[OýÉ-˜Uj1jÞJ…w?éÍÛuŽ ( Ýd¬Ikž5=é šßÙã»Ä÷"½‡Vêv9ˆËV2Q羃盷,êì·cF|p²íx$ö<Ôð¦A}jò2¸RóaÑ®oð\xçòrfyÔ¬^ì«$¶ Ú@4ØNHbæv\Öæˆ A×ÂÏ9oöƒOèÂQÎ!ðY Ý¢íè8Ô'e}xŠ|f1H9!îðÞg‡L« Ò¹ÜÃýDŒ2!òfÒ@Rì–¦Ôë;¼ÅXjoÏð)bÑÕ¹Ð*Z³™5<Ó(á3)«öFËM!Û¿Xžo*1M7Ñ îWÊüäzOÙå< Ñ À wȦô–·“Y±¡ô‡!ñ¸±6¾Ô›—¶$Ëj4ß—zêûH^…ø«WÈûRœÄÛAsPXíX÷â˜0'ìC$$ýt€º ’%m²§ì`@pévLŽÝÒ" Ì´šm%®‘­«[^^+DÚ†³ÿX#Ðð´*³Éž€@iÛ¢þu¿)Õ¼HV§­ïT_©OïòœþyùáüDLüG–ï›ã3ûÓÅÙg¤UªS}ÀŸØã‹±ú¦}þQ2çи'ËÖr¨y³ÿÀuChü×µñù- ìÚ´éé™{µU*%¿'ë9}-œ8°¬8è„á¢tBïZ¸…9$ {¾GÀ|cA5èT“¼t·ÕšT fà<¬3 ¾ÅYN w¦`LT⨻ݜ†’ÀA$vU×ý$ÒAÏvi»¬y?k2Þ¨!.Ÿ*R¢“ìzåâJOƒ\ å·}zã¶yP'VÆ»44Â?Ýa|£ÜÓKgUŒ:³ÛÀr×!l]èæ|>ÅÉÓí›'«cÂ\ŠD ˆ|Cû\MrL@™ ”¡Ëf,~L»PD–§Ö¡8Ô˜üp›~‹*/[­WÕSÂŒ*Þ4%i‘÷>/ \›jæ¤ÌKY¥Æ‘y,ÂͶë‚*ò‚åØÔ½AYh»Ql]ž %bÀ4QÓ¸\Oð!µ”*Ç uXD5ápñjl˜ÈÁ >çe‹TéZ!ªDb‚)U'úbÝáY県™lBÉÕmAì/*Ùý>ooººµÉ¿ó¾Lå³Í“Zœy¼اƒR¸I%-t¤–Kˆ89é}«ëm¤ä¥½(’”ÿ "©‡€„w(w‹;-x¯â²ù HwÛ“¤(x­Îš/µOÅv T)‡4i¯xQ2®o[¹ÄØb*¨ÅÚc^ÝfnwîÁrÑèÇÛ·®)(´ŒJ] U0ÖÑ? ºÈ¿+дWšOyZ0}»Àš¥(Áp×ßûDÆg|¶9ã­¸8yÔ[øMè¾Ü—y¿©ú B~kùéì1pÆÊ‘ Œ5Ñâä›êU{ø$’ zV{ŒaDâÐ{î$ºû `!q4˜1z`ëþ€sdÃÕ‹«crr% ÈçËñã ¼ž!yž¤uÕüŒ‰ñÀ7…ýƒô䨟Ã/ç¾ùóìç[¿û{.q5i@×EProîT]#3Õ86Oª¹HÂEÁ5ÒejBÁ¾{ÅVÿC¸<Ç—DÞfà%=H”+ˆ¨~”‚¥ÿ!ÏÖ endstream endobj 7260 0 obj << /Type /ObjStm /N 100 /First 982 /Length 1974 /Filter /FlateDecode >> stream xÚÅZ]\5 }Ÿ_‘Gà!ÇvœHmU@ Ñ>«>”v„*ÐÚn%ø÷g&³íöãFen ð½ãØ''Žcç®ÔTC d¥!üßr¨9XV ”Ù TÄ…rR,déB ¹Tgó7-p©²š‚¤æo à_ËU‚BÏr¡P«,9PÊî¬p *®UÜmsS~…»\¨‘Kg©m Õ@Uú¯-P«þ«¥‰Ü)”³Ã„”CææzÆ!+w= °ÙõH]“kÝžYàT >¬bVTý¦Åêà1/–æ¼À%—n|±ógN·äŒ`‚pë–+ìµ>ß ŠSvâjƒT |4ÐCɧå¿RÑÉZ’ss©@2gÈß1¹_ÀVç9°æ#ÄÔ}–€}ƒí¼TŒU<c‘Å2FpJAu‰‚’’K9¨‡ÄA%—°’ZºžbMSÞ@*A«$gA›õ5¢>¢…ò!Q …›[Æ L»”C)XnHJ…KHJãæ~H®¸OºL;>_©]ÿ)ŸSlR3B$v6ðkõïKFù`ؽù°V>Åås4è:*,tÝ2§Pɱð•|Í™}Ã`‚T­â¨ª/#ÞÁž«PÍÁæ>zÒyÆBU,ˆK ©u%Te÷hU­Oï,ùÌ3´Ö% <þÊÍ·¤š$ÛÜ»·Ù> Ø}„ÍýsØþòëo KD1aÌåë¿þzºùúë+rŠ„ý¹¨(¥ÅÚ&,Ф¨ˆºeEj±” ‹ØU[yY¯Xô½¼¬(›LLQÓÌ\rÕheE.Qé–ëGûËëpï^Ø>ÏRC±g ¸?<9ežŽOØÍžDOųöÓñI}ÜA.¶?]íŸ?Þ]‡‹°ýéᣰ}²ûç:œ¼?ù÷ï~xöÇn³}$»ËëWž8úøÍöçÝ«ýë«ç»W‡dÒßý¸{ñòÙýý?á"áEÁ|°¿žÂѳ+ŒFØ…]ñ›ËË=¬]NÇÓOƒ£ÀC!èÊluí(X°lò Ë6,Û°lò Ë6,Û°\‡å:,׃å[œõÙm¶_ÿ~ÝŸxyùçf{õbwÕ™IO·ßm¿ß>¸ þàd>Ç26'RO1‹êgcN2ò EM jßôhx¶ßîŸìé‹WørùU¤TÒ—¾ªgAB™"J‚(€æ'ád¹ó!œh‰^ÅŠÄ\Ì“I] ávNJjôs{ ±ý˜B² #™c?ä8Gà _Øjèã@Z¢32½Þ8!©ý,šB²%ÚR¬(·H%"v“À‹,À=#!Å…ŒŒS‚p†ÏY¶½"‰bÌÉî"‘ (¸ V¦ œuq'êû¶z»-{áž±­Ë¶i|FJ@;>AA Q3dF²FÁ)Lض (s‹²xÜd:çÆkm7P2 6Ržƒ²'h²Õå&JÊ3Ο?JS”ÌY…måŽAÔR±¨~ˆ©3H2‚£ždÈÍï$f¬B ¨¨(N” Ã1kwAÉɉ’$kPBHëÍoŽPx†šc)\µœ‘ôp^¦ $*lÉÛ”ôF­ÊºmEúÞÆø-E¿”IËJ¥•(ïížo+š¢oŠR¢w,ËŠ„’ž—õ´H*Š\cá E©Èê<1iÉýNdQÑoüÂlYýŒ÷ŽËŠ¢±’N(RŽ'\£{Œ©LÌ:‹EïÒ—I¢ß±Mݼ}pë–à{Û÷ oÞ5|êgyçÎÀ/·>õÎÀ/*{ÿí÷”G!‡ CÐ!”!ØêŽ-¾_O…a™†e–iX¦a™†e–iX¦¶Â zR“S]¯Þï,vëÔõI;ÔISHΚï#Ô`×ÏjŒd„h)ÝSÊg=ŒÁ¢e@ÉÈ ÞòLAYƒ©(èép'TšRle‰üsÞ+ÄÄ JN ¬Ó”U8A€’ñ‰TOÞËÜ 'G(ƒ“)(«p‚½ìß$ˆSíß”PB-Ý$•smðŒzäICvÑ:‡d J¸VTÙ?@¢T1ÿlE–ZâtÎlÏõ„$#«Zâ$«0¢X"ͧf‡KCËþy›TƒzâéµùuÅ 5ñNƒn.ׯ‘øNáÄücS™CRËùï)sôrk$W_±¬|ÉõÛ'5™ƒ²'-¡C¿9ƒ)y7u'gð@2™Ar‹ïBüï¦â·?п£„ Q]V,ê—ìËzŠé6³ EõÏÎmB}®½ïãï;ŠÉ"ëF1‰š'0ŠÊëÅTc}_/~[‘­ôo7ËŠ¹Å,ô CœM(fÍ8ä'©áÈ›¡‡ ûG¿ EAiÎ2¡Hˆ²™p4‹Íêÿÿ|?Û¦r+®ön+®úé­x s 3˜GÌ£»–¡,CYFw-£»–Ñ]Ëè®et×2,˰,òË:,ë°¬Ã²Ê ­¸%þ<£ñ4¯Ó>wãIÑü”êW€4e3¯XŽŠÝ0ªç@šõ.Ê甆2Úÿ aÊœüêˆÃ¥ endstream endobj 7375 0 obj << /Length 619 /Filter /FlateDecode >> stream xÚÝ–ßo›0Çßù+üÓâø¶yÜÔ¥R§=¬Ë[UUÜdSÿû1)$%S“5“º ‡¹ï}|æ|-A—Þǹ7 Š"I&Ñü1-0ãRBcq4OÑÿ9`¡oª…©Öu0aJûÊ2Ï’¸ÉÖ…3\˜€ÿg@ab¾.MåÌ—›,5ïÝýµÉM\÷@1c˜·ó+ïÓÜûáQˆ‡ ŠiQ(Yy7·¥`¿BóH£_í¬RØ£oÞWt,S@ ˜IngKŠ*xñÌx=FmU)Á„+ü½Z„w‰eýÇ2ý& Ä_ÛKóXš6ì'ÝnœÎ¸¸$hÂ(†Îãö³é ´úY4Âʸ#ûX6ëƒ2Çãî±N:Í X‡‘S¾0Io軜•GÀÖÛ½aMͽ]*â²¢álðÜ®#ñw©NÔ9Åz˜§4nÚÀÏš‰ß^>jû?6ný7IãŒw=PŸ¤žïu2óŬ¦¨Ç— 3¢­/%à*´t2ûÆVFÊømð«x™%»2G¸W|à>TØ L=D> Ë~·à‘ýBIݾ‰õÀ¸—ç %¦Ÿàˆ1çnSÔÙ²0©K%üz]OŧXIyFüÜËæáD~J¬ã§Î_bwøC\9þwG¥Á,GÒ«—ÒŸ±Š(…9 w«ˆ#0¹«Í1R] Aæ€ÄÛ;²†0¯xR™"ù7§U'ôXOP}žF9÷ûÉ:Zùâvr´9ЫҮâJÌp0‘"jCpݬEè:ã¸HÝMÝT°i—ľäDIâSE÷ƒý zö¬º endstream endobj 7413 0 obj << /Length 1324 /Filter /FlateDecode >> stream xÚÝY[s£6~÷¯à­°³VtGWˆ̙̜ïî7 Wç×:O oL}å~ʲ$ŽÂ2NWvâL{»IšéÜN¹gú£_êD‡…¶¢ïÇäëè|2º;IJæÈǾ-Gß`gó_ŒX œª]K‡KÏĹý5µ#*™Ù-‰“ÃÂÖäås Œ0ó­ÂèåµQA¸E%âšÇšÅÊô9ür%-¯î$ð:ù,å#ì€öH5ÀÞæ×bº qÔf³yŸm /è‚7¨ëU4…eØbR‰×¤B‚«æ5d¶aºIQÖ¬÷ÈûÜó­0 e(FìÞR§|Êôà’ˆˆ` ¸H³¡Wäƒ?Lõ@vû°Jƒ¦àl`÷Ú÷ðX…%=Xm©òv¬, ŠQœÝè¼ÔånÄ^;yòaƒ3fqÎ:ºÜ΢i•$u6ÍB“ñ±Û/ÈÉgðÌväÀRX‚Mtt%ò„}\-ÇÝZw˜Žkz-£Ÿ‚л@/×…^•MEƒ¹tnej¹Ž¯¼‘é|};;½¬Š^váùÂ5(…Ÿ ÆÖ–Ëò´L£4±¼–º(ÂEUe+“ƒ°&•+>„uüä&.ì ͳ¼ÑvAm5n©=&\ðˆ.åæ°lÓP­íž²RÏì\¸ªñªÐ ÝõT0”K$™hÔXÆ—ç=0˜â.ý–ƒ¿Ã?i@Ç” é×F=ÓQVŽiÍÙ·-OÜ¨ÇÆgznõ,Œ]K Í}Tƒ6íóC‹Ý°cý]ªâ¶Žÿ³åÙ î¤GBLXÈW×Þ£ô*R ¡‚žj²,lV f)òNäüW7yÅbúbײ•aáРbj ú\*z6m@9 p'[ÚæG?]'iä1ˆÌ]‰@bx·:VßZûQ ÷ñf½X»YîECAçK‰jꪦc³˜9ÍiƒÚ“)khh3%!d[ðè'€§¾ÀLæ­øï°šbPŽ×1ñáf«FÇ 0дÕwûÙMAÛ4¬Ýˆ¥ôÉÖ—<´æjš—ꙥñªÔyÓ-¤MůËZ¬‹AL»ûS€ÑõÔÆký£UºŠöL€LVi¤eŸ?M,U¤*ðçyºlºÎ;ãô÷ÚvƒY/µ ³p™Æ"R¢žô@!¹|ª³=3Úéü1‹ó>NdzpèÿÆL„‹â`Çp‰ÕÑÂ`žlIþbD:åeb¢z1Ú—º_®‘9‚óÛ&@W±VÇÂAÌáS`u´Æ¬Gð—¬!ÞI;)ýÏÍ1QrͱnîqHTƒ„,WQœ…ÉREB }8 ?À±k¿ Ä–mô¯´­¿• r¿xÜœålÕ®«s “5Ï ªv ÑÂa?üÜLálf›±¢ØÕ‚A'É;d ÆŽ–Ù"£c±wç¹GVv»¯ŠéÇzWf Q˜ žþ²°ïê±mI…øÏû¶ÿ„%7®Øäöåí‹Æ4çÕv:ï¹ ËrÞ—7&£vç¶ ×ý”%8¢òÕ_²z¿Kq ¥´–øÔˆ¦vOoÂÌ3—JUþ¨>©Iä%ÜSÓ_ 7Kt³Á®Û«Úyý†0 Õ+ãú£ÞÅov`oÿ`03w…æ NêEWÓx” endstream endobj 7368 0 obj << /Type /ObjStm /N 100 /First 990 /Length 1978 /Filter /FlateDecode >> stream xÚÅZß5 ~ß¿"ÀC6v'–*$Úª€REûT}(í UT·èî*ÁÏçÜfÛk 0áJxv<öÇ?“«9[H¡fIru‚×â!v"‡R:m§„ÆÙ ¦ýU ”¬9Õq.;Pæ" _S!ç+HÅù ªMœÊŒû[ œŠk(-0™Ã(˜³‚‚"æêo35èPP9°$—¢"X¨ªAQcP…9¨ø ˜ñ$kP¿©¸6UP­k«°Wè(ø¶ªc®ÜÌ1«…œÄµÕ2⅜ɿ­`#_yÕxÉuÔŒäðV!@â{Û* `&)ÉÕÈß‚jÙÑCTnÝ’X~6rP™­8æ >3u¾$A‘hRPÕuÀVBä:` !QæN®ëßeˆnÐáøD’Û´áÛÚ:…ߌÝö`)I]/6¯pòo[ [ÁtEº5à(E»5Z ¥vk@Tiæ;“hb—ŒG°¹dÃöää’-¤ø0¶–Ö¿(A+ÖJá†Å%[ jÖù ’²ï‡A(»¼î âòK­Åå‰ÃU õ·0§•|ÃÜ’Ñ”ÂùóÕÐò¼ZIÏBÓìoáÔ­z¸6Ks›Â’ÍàÞø ò¬u>Jr|BTuÔ>ðýÅ®uØ}#sŸÄ¢ ®íTGªØ³`p6§ðÖƒƒòE "ÒÄ}; ªÑîÞ½Ýþéï¿Âþ‹‹‹ãõnÿäíO×ýù›×¿ìö÷—¯—Ï2@z¾ÿjÿõþÁ3ê»ýw‡—×áY¥˜`,6VwnÑ3†–U l_„{÷ÂþIØy|z û‡á“+|øúxñYl$Ÿ†Ï?ßáßâš=†ÎHZŽ sH´®‡d˜$il04Q‰„¤¢œb­ü÷@LuE“@³ÂãÎHjŠ¿›B²…IJÍÑzþ×h=ÖkD$ü=ZV‚z‘JÏ@Œ¢MâØÄ ‚ÿ£,À?`¤ÁRb¢%g5ZÓG$JOÊ'$j1±N"ÙÂ$©Åžà†I˜# ß…I’a’)$˜Dj‰èfÐ,QT¤6iY—ÂfU“Ç„VêŒÄHò’-LÂɰé(Ù÷ˆ½ŒMp´¶f"i½ÑÀ^4*ZŽ9¼º=¨V„k9G YB-Éw5g$ViyÉm“<ĺ2¬™Âwaÿý?¢uC† ¼xûæÍó¿fDu3ŽÆ3ŒÊ‘Ñ,-3r„~|‘±˜DF¿ºÌ¨9¢èL0¢«)yBµ "Ó„@Ìž×'áÉI'$¢ßì!°ÈȱʪÙ[9ž0#Y>ÜÝb|t¼¸îžöH|²A•ïŸ<Ò>Óðé©O3Oï|òA}zç«—ñëã]îOP±|y|ùäûÇ…ýÓÃo×áùí züâçÃnÿH×W>^:ž>]žÄÍŸ¯[‚ÐU»ÃZGEWá~¹è(iZ³Á§H˜rÎPÐÍV”ç)(ë¦:4nB €çPåè3¬dF»ýæ\O±ƒ*(‚žÍú8ÚDÿH¯*“)÷#üsç2SJÈ×-3–/Î3Œ¢ð±‰‹O ˜§—‘ô †ûeFL&¨Œ„Þ«N¨ÎX5Fì Fì³ÈÄÎd8~i;ƒÌY& Îh£DgÆøÄs©þý”ýa:Ÿ-ÿ6ÕûùᇩùïS}‰½ñ ò de:ˆ:ˆ6ˆQ2l” ’mH¶!Ù†d’mH¶!Ù†d;IöµAƒàAäAÈ Ê tumC2¥ Š Y,Èo£¨!gÆ’ì.ŠÚ T¤‹)(–hýS«‚œê§ß¬½¸)ª,rìÉkšÄ»íü‰W7¸Ï’-L’Q¼ÎÊ«øÙfò½%7)iÝ“¼"õ”†n¿Õ9(›Ø€ÓÁ˜7•- •;˜7ÏHZé§4SH¶0 ò!æØ÷ZdâØî¦EP8çè·SSP,Ùú6©ùPxúá|ó«)Ž”uÑ&k‚ü>(hKieÊ&6A—^üÞ&SÄùõy1ðª§àŠ*Ãg(,̓sÊ&6qõ{Ø"чüŒê³l’²fÕAÇÚ¨ž‘pÕèw¦3H¶°·ý~‘ÐíW„v]bkZ„jtÅ' ìq„NoÈ´HHn~…“̯áȼä$LeÝÛ#ŸÑ‹µæ9(›ØEÐÏ:Çc?9«wpÅ8€0š·js86°5ެˆÉu¿§`ªK>’ÖÌ­PmýZþ £E¯2e›ÀIýï,Í@Bn%?{Ö¥¾ÿ­7PYÞAÁ4+Jß”Ml‚¬j§)Ç/¢)§¸t`¶Å=ôÀá‰DyÇöh(»é¦M³Lí#—¥¨I«vóÙ«  \Pëìá‡GþJS™·ÿâ óC&E$ËŸÝò|ÄXáæ6¡Vý²ýÏÎþ>b̰é2c1‹þ'KËŒÀXZ›`Lu£ 8O¨¿8¢‰Åøù6ÑƬeÇ&‘˜gT§G|o1zÎÖ˜ endstream endobj 7453 0 obj << /Length 961 /Filter /FlateDecode >> stream xÚÕXKoÛ8¾ûWð(1×Hqo]´)ÐEÛú–- EbÁ²¬•ä-Ü_¿CRreG‰ó° ô"êAÍÌ7ßÌC‚îAŸ&Î&—W‚"µdÍn‹f\#%b,4G³ ]…, L}cêUN™Šƒ÷UUäiÒæ«Ò¿ø`BF‚ÿB ‹UejÿúÓ:ÏÌ…¿ÿj “4Æ?P̦á÷ÙçÉÇÙäß {¢H1P-°" ¥ËÉõw‚2xÿÌuŒ~¸YK$d c¾Mþž Á Ì$·³%E5|xðòëj«•L¸ò€õM47e:oí¼J,´ÎÚ­ºn¼¼âñ@AS&@Qäµ›ÊØß.¯@ůYTceí×6®è…ÓNXˆ5c^âÇ2õ6oªÖdp‘ÀȆ{\Ýú±ÍSËÜÂ^L‹½êg»rÏ€žSw^ü`ÒÂ*(CT#nS8îκ-3… ªÖãY§ùóжØùvDh_ÌòÆ8hÍ8Y˜‘ØÊR®"–^ÍþK§FÊÇá,“; iGÍ Ä+>TˆÄgX ~5ø'êÅ#QAåè¿ØüØøZWM) )Uút€é£ä®9ŽÏ¬;éä>»-Ø|(÷©ÀTKë ¬…ðbÞ ~×ÉPÍ4ã)UXóaT.Ìæ¦X¥!·Åã‰Ô–ê“ê1¾ë²ðµ\`Ÿ#|Ó4û%ë $hµKF/È×%Wd­Ç6vEý#œr΃¼L‹uf?ðô‹Æ)Ù«jP›WIqœ‘ GÑ y¡ý„´ÈMùÂ’ÃN¶4;¼trœËËdi.k“ËSx œ«ðž”MÞºRv$ïSÌit†´hkgû¾Ý €úLø.Eî×õ½ÝÈV{t¤œ¼’Ù-­bÆKs¤¥C1PEÏ‘#FbE@β]R’u{1Üuõ{§‹¾8e=3¥+d?À]Eqj†’,«­6(¦O-5‘ÉÛ`}÷ƵÆÞñ3$Ujѽ;.¡Y{äy®êÄ/0;yUµu·¾´+?Z¥àNsò삘 ) MžÜ'PL´üÝȳ³ªóŸ®Ã™?Àx8 –B=ÌBOÒ/y¯m[¶¼ š—Þ>^6Uh«žÛËA?³8u—[COê´-žn^¸oˆ¹Àq¤ÏØŠn[nïL×Uïô£c†–쟄D>û dôXŠ<¥ÝDb†Ã©ÚäÏa,¼îL')3Ó´5€[;wÙœ(Iªø¾±ÿö²H‘ endstream endobj 7490 0 obj << /Length 919 /Filter /FlateDecode >> stream xÚíXÝoÓ0ï_a‰Do¶ãD<Áø $}S•¥fDK›¤Cûï9×i•†¶¬[Êâ¥MÎöÝý~绳CÉ¡äÍàÅhpôZ0A¤¸"£¯Ds¢E" ÈhBN½÷>—ž)ÏM™WþëÐ{^YšÄušÏœà¥ñ9õ®|†³¼0¥¿™§óÔ=Ÿ˜ÌÄ•q/ 8æŸÞ ^ß ]¡„9Ó4Õ$™NÏ(™ ü¡D!ù±˜5%B…øŸ‘σOÚÀ ÀÐ{ \v¶b¤Ä_„'Û3 4Ðð3=·¤W-\\ÙXÙâ4´ µÀ_*g«+D[G¯•j¢ÑC¸$ö²<—ãi|‘&ëföP¯ƒ–z‰x mi7³¤¼.êñy–'—kVÐ5ÙZI –%·ìTÔÎÛÚ¯Æ78½íÿ¶\ ÂèãSˆ8[U_¦'Ò0Ý4qSÒJsÔ^—×çNAÃoa»4×–P¯ -[*ÍõÒõ'nêm9…d_"ºÝÌÞ¸JtJÄ)”r2 „¸_~³7“jó_ é–/—u±©W]º¶Úè›3¸í¥I²xQ]™ß±U:UÍ::1_±ÐKê¼OguÀ[ïkhnë5Z „ºÍRYæåaã°ÕÂK+nÛ‰øÊ¶GéYU R¦¦ªâ‹E—u‚Ê6ÒÚŽRožÔóÒ@ŸdõÛŽ—N8nxZGØöæ_jÖ¿ì®N1”FüA5i£bC£©SÜÖ>£^O‹~(ÃÜíÔý0ÆV-Úz½W~G(†ùꡂ á´g)6ù&ILâ — žÍ¸gN”ö%ÎàÖô¬kZ„'ç!ÓíX¸ÜK „Îô!·m2·œí|{ æ÷„ào BÕK>×®üÀÞ wEãàô? ztããlÕK9Ú…û Â<‹žR yØØÿ¬§q?¬R Ø|ÖKòIsÈûB%-ʼΓ> stream xÚÕWKoÛ8¾ûWè(1CŠÔ {j‘¦@{ÚÖ=µ… K´#T–T‘nÓ¿CeK¶³hÒØ=$2‡ä73ßð_¤±7ÀÄ™ð½ó>Ž'ÞíŒÊtüë°ŽòªÐ…5ôñ®o>&BÀ8‚Ëaè†:˜MöD!qØCÌR@ §+ `l\ å½ž{ò½¾åédó2‰I†/™ ™r#UiHýº×õ÷€CPaQ€7ƒ{MžLÈŒïeZ!ÔK–Œ‡ÿWÒåsŸ@ûË€S¿ªjSUEƒ„ÛBŠ|c¯ˆüeuŒÌºn·¸Æ(w! ð•˜Vb†$ -I³²?‚3’&§TåeWÉ‹î¸E-‡c2þìåîXFcѯ«yˆE‡|,dˆ÷QÉÊ%k‡ßš7ÍÉæ1üú‰ò¢Å¯iWc+ƒ¡2MLz¯,©Æ)›ž®®îL-¤1àA`Šfo‡‰OQZ·•iŒR¡TíËR*õW°äTN=LuúÎFw ¥p\ ´ìvù˜8e8ÖBpã* -‡[Û¥u~L™|ª ”¦…?†,5Ɔµ.êÖ)u[÷]’AŠ0’ERp1 õëf,‚®¡¾°Yìz”÷…R?쮡:d¾ºTI—q 5•e·oõÄ1]×]×)ײj•7Bäƒüf½}îüýLyTlÕcÒ4zlšnš‡4ü‡óò~2ãëãí–A“ L¬ë¶Öy‰¥Ry×ém$[yЊõoØL™ênãilB¡p° H´mvuŒS’Ƈ+Zî¨æ„gSjà¼C`fK¯ÙìŽw0ûôIÁ£(þåÉù« > stream xÚÍY[‹\¹~ï_¡Ç$jÕU˜…½à$À²öC’ÁŽw&Ëtaóïó•ºÕkÏÎr„éf2=Õç”JŸ>•ꢮʖJªÊž”âMãKÄBOä AJâbˆ«C0NRCY,9ÇÁ‡ëBM½ŒW°S𠆨†-‰„Â8¦$µ˜_9‘µÐSIT‡5ÕD͇žaî2ô<1IÃZsz €ŽözböðÁÞJMÜæ[ÃÛ°g8q‡=j] ŒÖa¯µ›%),˜ÃÒ@`5 •àÁ$uX‡ÔBò’„f'H^C;R°ü^ðLͻÞôÏ0‡ Åx«5¸>±>Æj’>ÈvKZ4xìP =˜ÇСגÆ!õ<¾–¤U‚ÕæÁvÉʰW±|öª&ãa›b0’'Ã_H5™í5/€Ô“õ±¶V’Ó°Î\:—a¯Ir£Ñ4¹Û©=vŒèBÁAP2(&*%F`?j;Ê¥‡^l- ï@ ^–€g0ÊéŒ)±é€«ñ¬{<4B‚Q©±¶>|wÌáÇ-ƒ„Vs‡Š)c*†%àT°¸“ Öâ!A¥êXÆÖ6LácÀï©àDQ#45pe ®ÅFAê©y 3*4üEœAã¶ØK<ƒ•Zƒ 8k Ö ¶5 6àŽðî`nŸÖÝ‹»ýwé+fœïÒþoÿØÁ¡¨9H¹ûøÓOov_}õÛŠb9Ž×¶báìXó¦"NuÆ6.(JÍB Sã@f·GS¿<Ü=¤/Òþ%˜R£cÈË8?Àzú'BÌÓùÎâlÙ|rYç7/¼“ñ Sì¿¿?¼{uûnÒþûï^¦ýëÛŸÒyö×ÿýÏ-^¼ý×ínÿ-ÜÞ=|ˆP1Æïö?Ü~8|¼w;žÑñÙ_o|ÿö›ÃÏ馤8Wð°Îo0ÑÛ{Œ†û¶rTüúîîk7LjxFÄ= u m ý$h™M§ SÐ)LË:-ë´¬Ó²NËv´ühõçnÿêã?Æ÷¿¼¿û÷nÿÍáþÇÛû±Æòfÿ§ýŸ÷ßÞÐø´¼¡•rÁ1-Ù#$3þG2ÍÖ:Ô¾ûú*íÿxx}Hp‰ß}ÀÀ÷‡»?d*^~ûs$Ä”)‚á gű\‚ÒY/‡drB=‡Ã“eÂY3‘ìÞ6p¸_ÌìÈü' \<7äœ5 W 6·(„2ÇΔ’z·œ„ë)Ï5ñ ª‘Œ„²„ä*”˜ÄžƒÉ•‹F¨'Ý —¤D2ÎÈ ³æc®Z€rNp‘bÃK ÄÍ\¤nP¢—¤„‘ÌúD †Y–\ƒi-£‚FÝ-9’†"}“o.—<8˜º#ƒM(Qj ÂYƒrN̲ “{îQ…{ÏÜ6ܵÚEcIÍȼsËUá«0ÂHx>Îöų– oEл¤p.ÑB Ägá5ø…£}Z8¢˜·ŠôõT)jŸW˜•Ë‚"~Aÿ´©ˆò~”›Šè„s« Í:ÂÉ‚žÄÌ}A±ÔLmÁ"úGĵ½ˆ3î Š„¼É ¥Â t¢À‡Z‘mEôýxkÉ\0FHC„[jL>m07«MË7&½üº1iíËŸ}„Ï>Âgá³ðÙGøì#êìPêìPêìPêìPê´\§å:-×i¹NËuZnÓr›–۴ܦå6-ŸÈ¼l;ƒ&bÍlg¼SFÛÿí̄„Ä+´¥‹_<½¸9ÂÑÈ·q­â8Vy8T.ÉœËu*£H[r B/*RÈlg«ÁŒ?G;3¡DÊ­8ªKP®Á‰PÍq…6ŽH<¯ÏqpÎPª!/¯!ézyJ¸{¦¸RG¹XzàBåÑl«x'»l¥jý(Q¢ö5(WáÄ%3’7ü—#GWäè­3Ü/Là1ñ`lÈ5‘’Ií̈¢T~F&ÉÈ+0BN‹~jž&B»õ,çæ åtn– \…×ìñ; i.ñûXmh%Ú'Æ—tÍÆô ”hwá'KP®Â {5=_¡‘"~Ž+´3”¸$Aç¶åœôhEë/”š*¶ç d"™Œ¬ yÄÈèÕZ_¼ øLñ·.)9òbüƹ­ˆZ¼/(NÇ“ýîcŸ›o ­[V–EG=Œúx[± š=ù“Ý#Eæ]VÙFɵ©(n9~õÝVDaÛ[[P$Lí „s“ìd ŠV2ÚåE _\ðjŠÅ,ì £(^˜šà=, S7Ïbúÿÿ£«•ö«» +þåwmÞ7´Ó}Cü¢®qsP‹Ei€‘á¸;¤[) ]ô :–}F‚M‹@®‘‹¼rgF¾h[)à*Œœ‘YòD.ŠJp)}®i†Ñt¯(*ú´RÑf /(šôq5¿©¨¥÷EC‚§Ejù©»äÇz¢-˧üé­<ð endstream endobj 7534 0 obj << /Length 893 /Filter /FlateDecode >> stream xÚÝXÛŽÚ0}ç+ü˜TÅëKb;½®ÚªR»åm[!“ˆ MÂnû÷Ç ×¥°¥¢/`ì‰gÎጂFˆ ëÎË^çêm@Q„#Áê ‘dH G½Ýz|z¦˜bVú]&•÷"ϳ4ÖU:›º‰×ÆgÄ»ó)f³Ünúzž&æ¹ߘÌèÒ¸3†©ÿ­÷¾ó¦×ùÑ¡ AÔ¹°$Å“Îí7‚˜æ‘B÷µÕBÁw†¾t>wHƒ` ÑÌ·Ö‚¢6&ov¦.à×&Î4@=ц¹ðsõ–«Ö£¬TU¿r“˜!€ ‰WZ:*Kñæqå&ûß‹AØÕ”VýtšVý¸0IÙŸåÅ>ƒ:’ƒ‘®Á„X9ŪùÑL¦Y®| ”e÷’|J87듵!vSRÃùJx¨GkŽþÀä- aZûvPµüÓDØÚ€2‚E ;`k >XË$ÄŒ/Ö‡ÙF軾å¬K¥] :‚#F[ГUºz"æVJž¹ê{ÕÏÒ¡ùëäÁ‘!‚†<öŸW˜©¹?œ¾µƒi”FQétq†Iå˜ÿ} è2õfŽ.=ÈŽ$G˜JµªŒK#!/f?Óƒ)8!VÈjŸAfÛ›mßE LÃhò³Óp¤Øù2ÍXpieuœÈ”Ä„^¸È8ègf:ªÆg[ûÌÖIRøœx¦,\ – =;QqvÄϧ8‹ð®¹ˆŽæày3«sG³žW>%Þø± — ž—O˜áô||ç……9>>ÇáX.ßÏ.ö"y`á_dùÊk­®ô>µöd—¥¶¥‹RgÈìØ®~­ã0ÕåVpá¶ ¥1àð¡äìçÚò[°[ÃØRÄ®yYÄnAH#,m|.þô^È·¦Ûn%¡®á•×ÕËiìŠáF²î¸r목¬ÓÁ¼2Ww¶^ÖÙÜ4é´(ñS–Ëgè ¬‘Ùjl£ù<]€ýÐb‹fli±±ž˜¤ Aר9L_ë)JBL=ø¶ò9®¢py·¢ÛËåá®Î™CˆXïÓ…Èìà6ÝÖ¦[À0¥ …T ›JïÕX×ǘo»Ž®_(°ßA佚M¬Vs¨…·^+rÌ=ŸÓ¸Yé6ËOïÜ@O7X6=WµH}Iø; endstream endobj 7566 0 obj << /Length 972 /Filter /FlateDecode >> stream xÚÍX[s›8~÷¯Ð#tŠ¢zlséL;;Óu½OC°’e‚1 $;ù÷{$Alˆs±ïô„.çöïHˆ kDЗÙçÅìäBP¤±–L¢Åb‰ÀŒk¤D‚…æh±D?ƒo!‹Ó\šf݆SIð©®Ë"Ϻb]ùŽ32Ü…&–ëÚ4¾ûËm±4}{nJ“µÆP̦á¯Å×ÙùböÏŒ‚=Q¤¨X…òÕìç/‚–ÐÿÌu‚þu³VHÈÞ%ú1ûsFz_¦àÁLr;[RÔÀÀ£Îù.¯­VJ0áÊ;|Ó\ÆiQuT: Tôï“ žl­&(b„Ç~qw_»ìäÄnfQ•µåUöwjâQÔ«‹¸ÀI¬½Ò3“— ¹mÍ;|R82Àú´4W€]LgvÚù©#‡ 9ÅÉÎŽ À~w8›08òŽÜ,óÔYkê}`ûÂàô<¡ã ]áekF½°¹«SucZSuCq‚­û¸u÷‰Q‰ÂB²Á og§Ñüü»Ÿ7RiË’TüºYwë|]zÉ+Ó¶ÙµSßCD9ƒÚ¨Gh¼SÞ´¶_{1gÁ¨xk•ä¡dX…wp!†½vßaî“5éÀ(E”&8æcÒøXµ×]ß!Z æ =N´Ä‚Åéc“_*’‘C¨ÀZˆžñóÏqúéGjYïËEãßnê¡„øàøŒa€*©á€Q…5ßNÙ:K—Y—=Ço®Ø”Ïz~•mñãæu=réE˜(À$Æ(}oLv ¼ê6çNÀÈÉv­«f½êq;;= Rl©¦¨ò¢ÎÊ÷¡Œd8ŽÂA¿‡¼, x{ÒEbB؈S/ÇEºö{É ×—UKßÀÊÕÑ)érزŒÛÛžcŽP˜oÂñFâ€9Ç*qÃ8xvcöLÇXAðZØ3Tqð¿€âô@S§Î(JžçŒ†Ýf“ç¿/gèH¶’BbM';Î_6P•Ùç]Èí}H »ÐÇþ¬‡4³kî,¨YQf—¥Ã:½êˆœž_}Ó±óÞB0Li¿3IÌpI¡]týE‹=#õ—6¾2C£í8þßú_;äDIP¥¦Æþ°\1z endstream endobj 7610 0 obj << /Length 1177 /Filter /FlateDecode >> stream xÚíY[s›8~÷¯à:E‘ⱹζ³ÛÖñ>ì´Åa‚N§ýõ{„ä_R_bv73ûbƒçò}:çHlM,l] NGƒ“KŸX! 9åÖèÖ ¨øù¡gë‹ýÁ¡Ì–Õ¬ŠÚqi ìwe™¥qÔ¤E®Î¥C±ý蘘¥¬ôðÕ,Mä[}=”™Œj©o¢çÛèýàb4x0[D«öQ€+ž¾|ÃVãï-Œ¼PXßÛYSËçþ3ëzðy€°#Ê=5›«‚kƒÃç&a/ÐßW7l|ŸÄcpzhí|RdþO.=Ñ‘-—ú ‚iÍRª×N.Aøb Q ,ZÕóŒŽgt¹FŒK1 )ÕÂÎY†íJ–•¬eÞÌÙ±âVÿ8?s‡ŸõMYM™¾›ÊºŽ&-ÑoõHšÇÙ,IóÉһóñÜ ˜ý—C0³‘¶|gøW°Ü<‚„Aþ\ÆYÔ¢®Íð‰ù"U€'Ò8Z«…بEˆíYÜèÁñÜíÐ:Çqãw9½‘­õf^ÅBÉ |øõ×jV[5œ?ïtkÿ4š¤ñ²š=Ä^G<Wa½n[ž`ë¼Å=%˜¿…6,{†¨7¾ÁÜçþEÉ%D €‡&@H¬z2Í#À%'H?p=‰‹Çë&oK˜" 2]â£Ð÷Mž²ñ»ëñS (*ÛêÁèª}‚†f™H†!dq—(ôºËµŒÆIÔD¿ mÀÕ_dÉ7oLhÈ’ºòú]Óe´æÒV†ˆb(\fèS%£YsÙ{Q]%¼w^¾bE“ú8‘5œ«I}‚®¥B©Þ y!…ÍÄðöò=@A³gRW™˜ Ñ*zÁŸvã¢‚Š›–Qv8EŒD€Ø•€8Ka¥î™—8¢P8—À?ÓrÌ®¤-Ús(Ú±(Oæ{›(›öŸ ^µ¬a»ñb"®¥FÿÑñÔ†ÿ?ÃH“NUPb»‰¦å‘Xህ=WîÛª˜îYÀtAvNMú.j‰²M)¬þ'd3!Mše½"çqÑ ôõ³P)»{¥¡’¹tøE\“¾ÉƒU²ÞyÉ‘ƒ†¤ß3‡êSUú³mSŒ÷o`ÖF÷?y¬?Ê1 çç¢ òïÐF¨Es·­qÅ Âákj\ÍrµòÆ4°|ø+ ¬?UR2·ñ¸œW¿1Q¾ó' t|Š1Õ‹B™#¶Ïî¢ÒQ{sÀ „Í‘ãr?´Ïà´æ2»„í¢™ Ÿë@·æ ¦2ºy⚯aŸ~Óz à¡þ†±VøÁÓ¿®4\˜ endstream endobj 7511 0 obj << /Type /ObjStm /N 100 /First 987 /Length 2053 /Filter /FlateDecode >> stream xÚÅZM·½Ï¯à1ÉS¬"‹,@0à(1†¥ƒí…Š<„;ÁjØÿ>¯8ÃY­d¹™Ewæ²[Ý],>>ÉzÝ“K“@!Y‘“ÿ¯¡qÈJ5$–P iHšaˆ6‚‘8”Ö ¤Â!ÕáJéÄ`uJ2"+yñRfRã(ð«gŸhKÝ/‡BÅÇ‹ ˜ÞBbz<$0ö-¥ÞÂB©Ù[(!ª·J© t®˜V¿'AO¹¢5hƤ$kðËê#ÚÓÊ0ꃆe°€  )ãž!ŠVONC”š0„)æiAn™'&@›8R„×V4SK>Ž ?ÏjXˆlOÇâ”POfo–ØçÜœIõ‰âÎ f¡jé-pY­ÇÃ¥uî QÏ:Œ²qÏb$ @y ¬°–{”†u¢ì\aä­vv‘*Íúªh5Ø œ-y—¼˜ôq€NËÅ[ U¬˜÷f$Ž—Öz†Y‰ˆt÷ìÙnÿM¸Á ®Xá߇ý?þ„á¤}ôñܾÿå—W»/¾ø¬#·+í²#[p¿ìH}HŸoïógaÿ‹('dyoò\ ´;]]¤wÏì¾ÏÏÜœÇ*žI¿BûïîŽo^îÃMØ÷Íó°yøõ>\zùÛxðú_‡Ýþk 9ÜÞ¿óuÕ{Úí¿?¼;¾¿{sxwZkýÞ??¿}ýÕñ×pC¸¡¾–Œ_¡£×wh*øÉñËÛÛ#¢ÝœöLÇÓ÷̳‘‡Q†¡Ã¨Ãhð³Á4Œ4Œ™Gd‘yDæ™Gd‘yD–YN‘?b¨e·ñþŸ÷ýúïooÿ½Ûu¼ûùp×y Wû¿í¿Ý}“ú…S÷¤×‰2XB.aí¥Tb*)Ö¬pû²Ïý‹°ÿëñå1 mþô ßoÿMõÏ>…«ñž+s ai‘};™Cbë!9SRLcÃ:L «Ç|ï¤Ø¸ü1fmMJ /@8cc9›RK4Eƒìâ992…cUBZŽâ„” ;“FC “3Zã+‘ŒUË@r‹t%“$&((£â À~“´ YVÌá˜ò.9VësH6˜šlgïejðŸSýÿÏMÆ”Ê}n¼œË­D¶…mEÔšsS#ª€„•"ÍÙ„‘B5 DÄì…ºbÊjþc )Ñšªû ÚIL@Ù$]Q*Bt\Ò5;7…¯09Ô¢Wæ(F®(½*–´tؤu›¬õ‚ÄO›„‚y ɪ”X‰¹Wçž,ØÓˆ£ºÌVlHË«I¾…\€PŠ&õÒå‡ÈòÃ%VÐ_¿£S9¢žG™½è¤ª8Ë„£hô÷ËŽ(Q„ñ¢#D^l8u–+²j|Ù±H$è¯eG?'(,)á€lËŽÙ(r`'+ÊÂ2ÁwƦ—e‚ŒC»Ì ÕhÔ2A£ BóËŽ ûOðÍÈY×ÄËŽÌLJô÷cUÿ9 þ¡–~ª"²WýTƒkžÓà¥ê'¼ …[†v.C;—¡ËÐÎehç2´sÚ¹ í\†vÖYGd‘U6PÓâ£ú‹UŠŠµãÙ¤i©² ¥O/ÆúÉ( u§é3]ý@çæ:ê‘öF¨Y&j²ÈÉš¯ü=ÖÀ ¶é^ìÌ@Ù„ì„þVÐ91ÁÉ®8Ñ“.q²j•#'1? 0“$sP6ᇬPœxXÜþòÒÄ–ªò´*'}§¹@±†e\æ lÁ ¶x Ñß¼à éoë+ôýÒÚIfk®@hPñY(›pÉÄ8ÿ\ñûûþÉ„Mn­œ&Ø: MrÒI$[P‚ôœl©¿‡Ò¦¥|¥5³¤fh&½ aì.eÉcJzq¤eR!> stream xÚÝXKÓ:Þ÷Wd™"êñÛ΃Bºº4jS35MB’·ÿþÛÉÐ$¶Óib“8~ŸóÇç·Þ^OGWלŠ$•Áô{@5G”EâñˆÓEð%ü0¦"4åÜ”y5žP¥ÃWE‘&ñ¬NòÌw¼1cŠÃû1‰i^˜Òw¿[' óÒ·?™ÔÌ*ã?¢‘ñ·éûÑÛéèLj€>8 ¢°5G « ^¾|ÃÁúß±H?ݬUÀ¥†w|ý;Â-oD±¶ó‡'×2(a`Ðù©±^Ê-ëíî#Ì”7|YÎÅMÄc†Ã¥±ÆÕNåv¯«k¦·–s…e0â¿xáç­ÏÕµb[Ò\«æ4Y.â›Òüè© ÅÖ"É“ª]…ìTK·fð/i'T&γ…5qiº¦õß=S'c) Ž"ν¸ÏNxXàÐÂ!±´íúf6,DXÎ, ß÷ œ6’f)´I}%É,J’xÐú´NüN(¨Á3aém/.]hÚÇfžæñx"@µ]÷ ÅN$¬zS˜ ’)«Ûö†Æm´|ª^΄¸”zioÿ+òÊ4¨¾µÉêÊåß\ýËcí±UÂ{ÿt(qÄ7&N­ûDè³~OXÈÒmõ°-L£iå’Ȇ×q7‡´wrÁãíztøŒ~4«¹qV»]ö„<î•ΘÕìÒ£³Í©eB€©Š½~¡Ð("äèB±CáÇÞ§â4!6Ño¢Ÿld²¸M¼3&Ñi€ÑC€µã;5>¶00“nXgUr›µe Éêç‘‹ HIyé¨IMv[ß]Tû o$b¼ç›©EÄ *³ûþÙx®Jlü•¼å*ûÅݵ¼Ïòóx 2Upö; Ï@åCϸÓ鶇>ô™ô~Ìì•Qå/ˆ #[;€ÖE¼@‡ç-wis¦œÁp†P¿!i@êÓŪ,zér×dJeâ²½zÙ[¹úWp‚¹}7¼Eœ"B¯HDÑx"yä ó€ö$Ó\&ÎÜ•4ªº„sÌÚì ÃJ⨨¯ìÿvDÉ€ endstream endobj 7668 0 obj << /Length 751 /Filter /FlateDecode >> stream xÚÍW[OÛ0}ϯðc"-Ævì$~Ü` 1&m¬oU!1]EnäÂԿϱSÒ®(*/¹øv¾sÎç/A DÐ…ói朜sŠ$–! ÑìE E<Æ\h–¡÷«Ç„«š;ÕT­ç³(v?Öu¾L“nY•¦áLyŒ¸O…yU«Æ4_ôËL}0Ï×*WI«Ì ÅŒaêÝÎ.Ï3çÑ¡ AÔ@s‘¥…ssKPí—ˆà@Æè÷0ª@<Œáž£ŸÎ‡XSˆž`ztHQ5^ï#L &Ad?4wbþ0Ñ—Uß& ϧ^uÄkH{?9âÉjùŒ˜0‹u«z˜vr0Ï£¨Ä‘ŽmЍ¤Ý ‡óÜ"é[D?à8Òàž©4OÀ,á3§È;hE8“BÓÊÔ=Ø)ˆ Yv›¼?è”P^@¬€:‰ Àk)@Åñ†KÝ<ímÕ¼­;Ò>”÷oO]AÃÆ\´É蘮<•Õ!f„›±à]ûЗírQªÌ¼S3ÖŒŽèCž´Ý|ˆ[=ÎU٠7Ý'Óâ­þiÒäZzF°d̬y•´º[©`]êp¯¦–Ô/.>¦ŠG2ÞDk‚ìSö|”kè\Kf™³ï> stream xÚÕVËnÛ0¼ë+x”Œ˜&©÷±Eêé©©nI Èí–%G¢Òöï»é„qÀiíC|-9;œ]q Z!‚®œÏ™3›¥8X„²%bI€™Ÿ¢8Hpú(+Ñ­ûÕc¡+º…èÚÞ›²8q?m·uÅ Yµž¸#î“GÁ°n·¢ÓÓWCUŠ Ý¿µ(z¡3†©wŸ];_2çÑ¡àAÅ  “ñs{OP ó׈`?MÐÑjƒ‚(¶Fßo1\¦@`ùÊ:¢¨ƒ…?&o±V¨”`âÇšðº[„ù¦XU|ôð´³¹ŸX» š²õfùk+Ô¶ÙŽ}±¢)Ž•/G!|œÔ£©›úNÂTƒ^ ^ Lèjåläœbœì"@q*Å´ ‰ö}T8t»¶Ëy[ kÅbõ·ÞºOqòJu>z.sþ ¸ê®=JÜ~ØäË¡9³Pn€×ï¾ü¬#8eLŸœûÄU>ŒwךÛUg›¼‚ÑЋR÷ŠÞ´ºáE]/ ®²n­gd«ÛÕ˜­è iŽæ*-Õ¥)cð_Ï–…4g-½ð;=Ð\ñ)‰#âÒ„¾"Îþ¦ñpx endstream endobj 7629 0 obj << /Type /ObjStm /N 100 /First 990 /Length 1817 /Filter /FlateDecode >> stream xÚÕYÛjG}߯èÇ$=]·¾€0ø‚’@ÂöC£Ç^‚‰ÑIçïsªW³¶ÖÓqve"ŒU»S]}æTu]ZÅš…еHŠ %pQjPbZ0Å£œRÈU] P™\àЬ¹ l@Ò@,¶‚dnÆ3Q K0œRƒ¤Õ¿cHÕðaEæìR…”}+‚½’ºž–í Ø+Õw#€­’°HÅ¡øÚæx3af‰¤Ö%‚yqìÌŠ¹$‰º¤ÌÑ3Qsˆ¥`p.Ž€k`¡þ¾.™h¬[V°¢d·ç¯Ú’ï+)HRG%„ª³!dkE$ˆZÆ€&î H¤H_›ƒÔΣ©³!îu¤Ò‚rõš‚*û ¥s¾¶ÔÜ|• µ¿‡jÐÖß\-‘c†)có–‚IsšÀ)@ZÒîyñï gX¡‡_AºÏaÀrß´[î\™+xËN»<9VSwE…¤î ügµvxÚú{À0Ü¥vŽd#¶<®pàß÷ET"ŽÜ[øÎW`#ðп£·HAIÎÍ­Àh®âñ’5ä–!w¥¾Yó ¨`ž+Œ*üQÄ$¡"Ù#ïVîFübKUl­†ä0nþÔÏ<ˆïòö ôR'lUœâ’›³ëç­ˆïáÔ•î#׫äË<¼«9¾‚µ9»n¯‰£ÇÚšzÔ•°ÀíΊwXœ¬¦çÿµÓË‹Íõjzöî÷ëþù§7®¦G›Ë×ëË  O?L?N_Pÿ°šž®_]‡…¢ÓÏ–cÁ á·Ÿ ’"< µ‡áä$LÏÂôýæù&LOÂ7WXøfsñ]ÄÉû6žà¥2,…§aúå×ß‚W +±ÂüÅ»·oÏïVDAA“´¬”RôîlQíPô6dQ5?Ö2`-FDñ[Öß¹ (‚io<µä¨u€BUŠŠ>kY1ÕˆöhYQŠÅ<ð.‚ ª4°³¤› ìÌ¥ ,ôT#zðE"œü‹èíqôÔ¢ÙÀÎD½QZŽî†£}[ítsqÝà©÷Ô„&¿/8íý7^{ûÉ]Êj7Ÿ°•"×ÏÏÐw3ƒ›gæë¶šØb:»Ü¼z¶FÓÙ“Ó0=_¿¿ç·3ËÙË?Ö«é1¬/®¯¼Ýí°=\mÞ]¾Z_m[àþÝÏë×o^>Ú¼=çøtU#œ½¼ÄjOy«ØóÕ6î‹ãéóÊV4 4 < 2 : 6 ³ÙÙ©³Ðn-ëlYgË:[ÖٲΖukùü ™¿$CyFíAKY1ÒaJ‰šx!ç¢j0ùsì£ì ¥IO^cPŽQµy?‹Ö€ÑQ—Ò³$‘%$9’Š„0ÝAAiL8˜ƒPø¤ ck)ïZk­9bä»ÏæšKô™n‡}SBBrXNˆÑýHLæ×z•–zlüvü1ûÅ!´JƒPŽA ¡Ï³Æ~Cýâ–ÅÅ‹&;ì”líæ†ñ˜Æ…´´Å¯–‘OüêÓç÷œs¬òð`k¿kŸ¡0¦ÁVtÊ1HAû^¥õ9™Eú_j¹×ƒ­ ÒŠ_½Q(·IéýÿÜÎ/ÎÊ·1ÝbDñÚ·¬h9(&ê½Î¢¢õë‚‹†|[,/+js:m@±¤Ø>;dî+*†Ì6À£"Ì‘—¥%”özDªÍ²cÖË#|³¥(¯âYKZ]VôkÑ&~!4TÉÞ¥_¼îàw ®·‡Ó½1öÎQõöˆûŃk®Ÿ®9ùàšça2ÏÃdž‡É<“y&³a†yh°Ú®Ñrïæå{»c4Z3O‹Û&tŠÉákEöÔSw%ºˆ ÷þÿJ4aŒÓ”êãP‚ôPÑèíÚ,í6ú*}Ö FªôkÍ1({¤ô<”Ë`ù¼¥x×Uó¾ÒWÍ{Š8ØhÚ€"š¨J´¬hN“EÍ8zo¬Õ¯˜d@›tDÑ/>Û‚ì)J®(ïy@Q·cÑ¢"£aÈe€pýXL>øšà™\Ë€"Ê6³ý.s‹}Z‹ü»šø1Eå-ŽCùT)…— endstream endobj 7695 0 obj << /Length 888 /Filter /FlateDecode >> stream xÚÝXÛNÛ@}ÏWì£]‘eo¶×”›JU‰†ô ¡È±—ba'Æ—Tü}g½6qœP‘¢x¼Þ™svföBÐoDÐéàëx°"(ò±ï2¯‘Ç'$>Gã]ZßmæX*Ÿª|^ØCæIë Ë’8 Êx>3 GÊfÄZØ:&óLå¦ù´Š#µgä‘JTP(óB1c˜ÚWã³Áñxp7 à AÔ˜Ø# ÓÁåA´Ÿ!‚¹/ÑŸºWŠ„+á™ ‹ÁÏi`LÁ{‚™Ëuo—¢>¬5ŽL &Ü3€T˜Á± Dífkgÿ„ËÎP‚–-Uå}¦"u bšŽRSA¬*,Mãä6Ÿ:“,€_8ÉÕií7Ö·FÔƒ>qŠeæ‡J§ªS¬YLjԺ<ÿBºÆL¿±6ãºC¯!Lçs˜åUÆ^bÀãhç³£¿OÑä¸Nw>}LÙĺ+¨f]Õ˜qÚvˆgaREJkÞÌÐæ©RêaFö…0ÊÆ#Ûq¬_Çf^ã&ó8·}bè‡MˆÜÌ«$2òT5cŒ;QûfžãÓ‹áèøÜ¦„D¯!!úQÒ²[(¯&•óI8ÐúÅdD2‰‚²–6’µ!?øá,ócÃtP{Úí5_Úu ¶ÝàÉ z=#C.°tüw¬K¾¹á†Õ’îg= ^)[Žù_kÈÚ4÷È”±6X¾48_Yc $}qàõê &Dc] 9Tš8 ’ÝTk—aÇyg&˼RK“Yª·¦j½'EC'ý\t²Z©¢„Èü@N»!ZÆ©‚úI¬2H³ñêb(ð‘ð w$q4©feœ¼9§K¶)NC›ëFÕÛ¢JwD+qGñÊ·Þ¹å*›„ë v¶-`ÔÅÔ÷W÷à»Û¹¯Ù->ûÞh±å~hñéö@ﲘ,^’™À§|ÛŠ÷ˆÿϨ<)X9PêÛ‡•ÙmÏFzmÚ3â|–è~÷æÍl¬Ìù©h›îôBRÅ0¯xÕ¿€pDÅÖ÷oÔ6 •LÇ·”Ä:¼ 2(¥Ý@ñ¤åb{è ß:œ§:´²DµÌ÷n©ÅYØ|6W1çߌÌ"#´õGgZÑGúCO endstream endobj 7715 0 obj << /Length 1174 /Filter /FlateDecode >> stream xÚµXKsÛ6¾ëWðHfJ/‚à1­ë´I;Ó&º% EB'©òáŒóë»x¢$:±bû`Äcw¿o»€°wëaïÍâ×åâê†/A‰ Â[n<*9¢,ñb.O˜·Ì½þ»€F¾jÖª©Û ¤±ô_ï÷e‘¥]QWvàZûw…e½W~Ó¹úÅöß«R¥­²QŠHðyùvñûrñß‚€=Ø#^LA5G1޽l·øø{9Œ¿õ0b‰ô¾šU; mé}Xü»À F `DÓ«ñ˜8|?‡Zk%a[À_šu´Ú§«<í‚0òScç¨ÈµW7LNd`/¤TDVDw¿WzÛÕ ?¬" еEgzæu< +tbBŠQB©öO£Â´ï¶ªê®‰°¯…#+ýÑðØAÒ±s­²2m 1FËÔðRb$‡@Ò¤äjcíju°t:P°ßg\Qb†ÎIz«ÝZí<÷ˆb©eÅþs)¬šÓA£Fˆ‡Aûwém‘«¹@|Ì&â#€ 1õ££¢É.Á#ñ° Í„fŸ fì}¨ýYšBB$D± b2…Ó û ‚9 ØßGééÔÅ4Å/CÝ0Ï þÑq&E"†G çãy~è8ÛžVƒŽô˜”`-(F sØWmq[©Üî*ªÎ¢Ÿ?‚b!^8þJUÝvÛ‹HL"Äñ ‡Y1x½9ˇOá9º #5$4] MŽû^†ä{$óÕÓ<ÆHú²ÑÕUÙ^æ†$vä™ë§W¥‘ýIR·¨käúÊò²…[«y@Çå·’SpC‰gÉ(yÖÊ{°È¯‹üÕ´ÀNÁÍ%n,𣬓 1ÈÜ‘s„ˆ$úÚ.™_ÕUø nñúFžPg‚ä d·ë«C™¥}çO‹Ò” X’VùŒ)DÄɘslÝÞ—÷s1Dð˜GÚmÝ—NôZY•P¤êFå(9cþr«ìôÖúAÛtðŒïR­íÞN5ªë-ÅÕŒ™Ó‹9«ÍYðBØÏ¢‹4J"—$LNü¼ø„S dD;08Û†Ab4i²õ‡¡ƒÙðÑÞWPáÛ⛲ßN® Í¿[µžîP‰¶) öWêëjôǪî»ÄBC’Ãíb§þ@¦UÚg™jÛM_:³â*EIÀ¹ Ö87Aot“á&¤¡#þF÷ÇÔïí›Ú#œÕ{ƒÖÔ­O8ÂðGì|WÛjÐùÛAÏo ;»eï>‡;C¸'ñE”Q„å˜uÌÓ6-SUÛ7j°&uv®ÍÒÊvÖƒaRù€ÉE$“Ñõzéàz‡ÏR*á,ÉJËbݤ–çŸi<}dGðÌ~cϾ˜9<à‰{{ D!OŒí_§m÷s,è´]îêm=€I†c}ÀrjìÿËô endstream endobj 7734 0 obj << /Length 1427 /Filter /FlateDecode >> stream xÚÍXÝs£6÷_Á#öÄŠ¾ðxMšëÝMgÚ«ß®7 rÌ 8×ü÷]}€…c'NÆ™é’v%íþ~+í ìÝ{Øû8ùe1¹¾ãÄ‹Q,¨ðk/¤^È#Äcæ-2ï›ÿeJ_6+ÙTítNÃÈÿP×Ež&]^•fàVN)ö¦‹ª–þ¸Ë3yeÚ_e!“VšA”"2ý¾ø<ùu1ùgBÀì³5G!½t;ùö{Œö0bqäýÔZ[‹¾…÷×äÏ ¶n`DÀzŒ¨`J[¯Á“Á¯§&a‡oeZ$àBà•™ý>×w,r¦büAQU÷XËL®§s.ˆÿ£YK Eà7U³L«Lþl¤3G©`ºnÙÈôa¹.A‹(1ö•¾VI«²“Søÿvf¢3„üЫòÌ®Ÿ%]¢%ì¨%ý*š 54V(•c„ 8Œczµ¢Zû³F&ÅöÊtöu÷Pu+Û6¹×1tÞ„FÖ…RœŠÀ¿:®3+Áwìÿ\ÊËj×iÜ4[gGÃA(€ÛŒ 0äŽÛµ¹le™9£px&,8lìÃBM»¾ƒPÛk‘…Ê¢Ñ^Ïïsb¿¹]jN1Š1 þVU? \ë]™ÚêzSŽýª1¼lk ÂòÞôûñm•åëÇaØ!±5#`¥å¯«Ì÷ËíM‹†à Q̨1ä*B¿ÛHÓØË åX½Vv­ÁI' ÔEAT)vÅ>P¯i7SF€ª³qudÑ‘˜÷ Ö=îYŒÐ¶ÿ™…1·¬:ÓXÉÞþÒŽhL\—œ+ÓJÊì@vŸë£+- ûø×Ýý~»VÚ©¹=@2É â@ ÀhýœÆŽ®¯ÐuâÊ Xo¡µ’½mTåFuà€j¹Z.Æ~]$©•Uë#Q*£3inÔ!¸0!È]H5ðœÅˆ±`|]Zœ¹pqæŠÚn§öËÖÈÛ]š‚ë]1pÎçÝF¡kTdgÏ'H$HôMШwݱà¦@!ÏïPƒð†å5|ˆjÑð>raÀÀÕQ0nm“Þ0P1FüÅÆ.¤Q1ÑS1fîU¬ƒÿ…Šö«¸7ƒ6Öêð?êt ò£É–J®í cŒÚ¥•oìBÊÆ¤ØI£ß߈'€ ÃWŸ€]Ê8b½ÊK·'ÓØ=R!œ•e»kdï`b]Í; ERÈYÄ`Ë1äša•©o›m™IaˆH_iÌí…¿±óŠ|Õ$cKø%“ï%Ê0?W†tæ(9É×V` 9Qd\©jÊ©ÀÔÒ¶³ÕZ_ò Û™r†“h_NqAOÔaâxö´¸:Y)9ª*Ìþ?…U²ë6}…ôž…Õ³û¼þqààP‚1ŽD@/ÂIyÙ1êôŸxtYjò2Íë¤x )âõ¤<·Ë…)!—§¤6wŸuB£ÙIñeH²ÿ»Ü®¤ö¢=Ž¢8R‹«ñH˜}õ>£Ätà³öc›Üçéx›W,2·ê_!*^0+pS*CÇûZìixˆùôˆÁ'cë8Í †§–yrÞ΋3¼;X:÷¼;X1zX‡•Ï‚™=CoÅ òÞp>¥ÿ¥§;lbõ€à(böÜ}°oõÄÖ-‰S~Uö rK\x´èÍQ7& îò‡ã'¼“.ÚQ¾‘‹è%.’ YÞw›³‚ûð?dÀá>>û7äÑŸŠœ"B,€$⊨(ÂþÍ&©§ª¾SUÍÿPO%Ácÿ¦Úª;½.d¯`ä¦PZÛêùœZÉÜþ‘ýã“i˜¿ ÐÈÔK@%9ÈZãžþ%õjˆ endstream endobj 7757 0 obj << /Length 950 /Filter /FlateDecode >> stream xÚÕX[“›6~÷¯Ð#tj­îÀô)™t3M'6õ[šÙÁ µ™` 'Ýß#$²“ÍÚYo§/F>GçûÎE´A½^¼\-®®E NShu‹X,0ã ŠDŒEÂÑ*Gïƒ_C&Ý®u[ïÃ%‹âàEÓ”E–vE]YÁ+2| ),,ëF·VüúPäúG;~§KîµýC1c˜†Vo?¯/(ØCEƒ­ŽH„²Ýâý‚r¿Aó$FŸûU;$T Ïý¹øcA–/OÌHlÖG~E¬P GÂw½R#ôfwJ0á‘þ±]Ë›¢ê8ë-=}‹«ëˆô …@ǽö¦-ª¬hÒÒÛì’c»8VF¹}›¥ ™VHðtwö >âˆÂk`±âÆbE-€©°à…Ç’2‰‰ThÉŽe2ä&O»p)ƒtÖ„«k´d6“¾åt4Á‘±íkÛ¥—Bk÷õÀ¾ÒY™¶=À>ü}·‹p<¤‘—ë[HI‚½I•Τ Yg…Y/ôà=<Û›p.H0’S»ˆ«wkÝ£ÛÏszBè{©5á¢Ç²K7Eö4™%*„Ì##d’^ ù·²k˜Ÿ1ú«qw&WK*%æœe'Œ@ûÙµˆÃij0Öê´Ü]š18¯”£16IRŸ‡\2K*NbzIN¿(ÿfÕ›À„Êã  'BX-/*[ZLAƒ3¾MCN‚;+«g*UQmöøìøó]u?!Æžpóç?pŸ6ÈK]mºíÅë…ÑL”ÿ/9»dŸ205Ó§Ô;s¾5!Dõ)-Š:½E©wMwZ’º†cìßUCSrüãÚ„ÛP@z¶öÛ¥ö:·£¢Ïj·6KËrf¦UÿèTªÌ´1ø)›ˆK¶H7cjÇmÑ=×ÏÓ = $3¶oSÇûwž*~ö‹çÁØšd¢kâG§â±ªV`´wž¬¶ú8*»Úùs[›(þìK»áÞ6„§¾ÌŸPî¾RÊ1¿(¡Û"Ïuu¡P²$Q>¡/뾚«Ÿ†¬¾O}hW|2ŒÎp>TgF?þ‹H¢ñ‡KÎyðû/¿€^ú0ÿÏÛ¯§uk«›òî$¯Æ +•ø^}{°µÍúeíüŹÎÒn(ák휭Ÿ:c‡·õ¡+*í'ÏôjE (€¾Y9¾‚aJÝ 4 LJ$=×öbÇTpwI”V¹ì»ê÷¡/¦f’“H‘€Ærjì¿ÀõP4 endstream endobj 7678 0 obj << /Type /ObjStm /N 100 /First 979 /Length 1810 /Filter /FlateDecode >> stream xÚÕYËŽ\5Ý÷Wx ,Ü®‡]¶EÊC$¢$ `”EHZ("šF“‰þžSîö$éÉèZC7#Xº·ËuË®S£œC œj Jø·¥P9d Äâ/4PQ7*þ—ƒ©ÀOK`J¸š%×`”a”¶b¢„pˆK¤A3+fA»!!‹À@äBæoZ¨ÙßÔÀ @ÄÍ-ŽRÜ’@šò  eõX5œu¿¨öh@D ³‚åˆ[ܳ8 „g)Õ-L#'X\ÔG4L˪ú0¶rÆ ØgYük smIüüšª¿ƒ_«þNRÄê–Â*=^ âì˜%üJjn¬ZW°´9o† Â¥ùØCü¢¨cÂTE$vQ'ϰ¢Ö`l&|ÍÀµ¬"~…_%õoX–ÙßÕ ©õ_[ÐÝw}™0Ä-Â:%÷#ZÔrÂÌQeøUN¾ø+û¢g¬lm\eDnÒ|„/ríck@¸n5XÅ¿‹ÇÜ“†Š§¦•ków?,ræÎŸáƒ¿Â˜L•˜yÖtþ€ «9X™\|¥ ™š­õwrŸ¯¤â¨°Zî–…"ÚGÔP´úÌ‘f¥PÃ7#,ûšƒX¤•ç¸Á¯â“À°Ìñ!'‘=+-;M˜9VÛGx'éÂ'Ï{q )®Zß&žŽN6'gÎÆ}ݰë€ÌÑ#LØgäÄîÖÈE} šOPû<ðqËÖÇâWdìêÞ½Õúq8öRììgaý˯¿!* ¤˜°,çÞ½{¹ºÿFÇRrtˆËŽ©ÄŠÄYtÌ•b’Gn± ±µ´XÛDDU4ƒ{#26Ê¢£äýXvdðÈŽ8T"  G¡Ø°+—±2$ŽO¶ç—áÞ½°~‚\SÒºò©¦¾wONkîO¸~z±}ý|sÎÂúéã'aýbóñ2\Å|ñ÷_üðêÍjýñ7ç—ïýLêãWëg›÷Û¯7ïwçT÷óæÍÛW·ÃY‹‚ãÆ¿Ä‡^]`´gsÙ9>8?ß"ÚÙ®B8ž^!ö ƒ‡!ÃÐaäa”aØ0ê0Fä6"·¹í"̵£Z­Ÿøý²?ÿôöüÏÕúáöâÍæ¢Ï(½\ÿ°þqýèŒúƒ“ðô¶@ê/âq¨ã8¢hZàö ¯Íó°þ~ûb°¬ß¼ÇÀ·Ûóï°Éô[_Œ£ñ/W4 Jd¬àc %ããAÙs‚|C`u’Ø€D¥Æ”y“FGä„ZÔbWH¸T<ËpbÇç$IôBC"@àâ̰£€à¿#r‚/çü êžç€œ‚Á÷:b0"­Däî]P2 ì)™CrN õSr=&¨±!É@±“‹¹}‚­ŒçI$'áDSD='¡ËP¯5JYíº8jB}È¢S¼„†`ÙQJô¾bÑmIœˆ‡Ž&f­Ž’¢Ë—EGâ4á¨È‘ GæDõ¡c¢H¥ºž˜´ä½ \vD%×:mÑ×Uú#:ÒTz».¾½=\t$³XR½JG³¬ÞAî5;”ŠCÛÿæEz¯}£çѱ^ÓóÞ‘Oéyc:Ôó~?Ñ5¶_Oì:Œ½ ÷»‰½AÃ8… Ï8¤ýÒ„ÿ¢YÇs],æ%S‘c— ë¹‚‚ªXÀI(ǃèaOP*~ÔH,¥.•‹TÈ >ŽqÄ{¿Ù™ÂqTBG_á`Iª – ùVBóDw°4š]L „SŽæÇ@1œ6º˜¯í¸ùêGÊ—|ÞÌAù’?ýærª”éxC)¿ætÓÅסcÉ BP–3² ÚDÄŒr•mÂ}fÑ6á˜Ð}Õ‰ˆjК4áç7neb*^ÊíkwO‡ŽÒ…ÝDI5æ41io³üšö_ÞfÍWÍ[×IÑëuRøöu’÷—[~Á½7ty£–ò¨¥!i8õüoa3HNà yg÷'Œ2awq­w…¤å˜Ê$’“pbm×ô’7ÐÖ´Ðû¶&ÇdÄ"óŒÆ±NÂ8¤£Ô"“uû Ç›êöSÁîö]¾ìèwémÂ1EÿÓᢣŠ4á‡M—lÙO@¸~U‚:úÉV&¦ÂHe©3ŽJUtÂ11Zv$“è!]vÌ¥LÐMB3Žrœ&ÑY7«ÿÅíºbÈùöŠAF×,£kÖ+cˆ bB‡˜Ð!&tˆ bB‡˜Ðјçñ‰<"ç9ÈYO <,å¨ gœžæÇ{âéãó##-[ endstream endobj 7775 0 obj << /Length 1148 /Filter /FlateDecode >> stream xÚÕX_oÛ8 ϧðÛÙE£J–ÿ>î¶ë°Øvyëc+­1ÇvmçÚ~û‘¦ÔØNºµ]:`/-Q$¤HQáÖ•Å­÷³?³³sOX1‹7°k+t­Ð‹˜Kk‘YöߎëÛªY©¦j¹Fö›º.ò4éòª¤‰wÊq¹ý¿#€±¨jÕÐôûmž©S¢¿¨B%­¢Á\— çrñqö×bv3` ·©öXÈC+ÝÌ..¹•ÁüG‹3GÖmϵ±¼ ‚±°þ}žq ƒ3Ösæ¹a5°°7ùå1À‚3.CüµYù˺©6ÎÜ·kÇ·»ew_«ÞÜ}z<;—Ñ@·æ®š|’d¶ƒŽ—ˆYˆ†MÔÕßÑó|œs­t.=ù1©~§Ò"i&s¨ù²EæP ¡™ZC8}Nò²“îà{ÑK-ÍR°èÑà8x:—ë´ûúŽ¢G>øÝå,v]’ø Sªõ™ë*Œ2úJ“¢X%)¦ØWšYoËÆŽéÙcWŸL·›ªY¦U¦þã>§Õ“ÓÐ¥À!h yûå´ÿ8Ò·ï:ZL`Qq¨8ý˜iÙYÒ%zx[,Gf+Ò׈®g,“zã*)çèD,‹}}nJèqû”Â$¢Ün4ªöt/†¡m/.{ÄGOŒÛl ^èƒøœtž¤(ùýŠEÌímª£²ƒ„n„ó8‘úGmVªÒvsy„²B~½( 5ÓÉ^ DîQØ=€Mr•§c5ÏÊx Â¹øá1«üÁ¶ b¾™mìÀùò™+Íú{ŸZh] ª ­ i˜™¹b’ÉWFܪ›­*So[vO‚þâ2BÆÃh|ÕIÛªúºÁk š´%ôj5±eânÁá4p߀89ù9?÷Ô+;úª#–¬H²ÈóÇ5«GÒ§ºjëªÌTÓ_kزàu~÷º=K3Rªî~¾qy£;—ä¥iPÖxVͨ…i•.­ÕÚ\|*Ùv×€ÝÓ¦ouXQUÎñ2&)efˆöÖ‘Z¼–=ÜÄ!‹åÎ"ŸKû*}ŽzœÈ[Û-¾]TF_+”|O4˜†„׻ަ¦ööî1IÈ\µÑ[+ÍOÃÄ÷k½sØÆ1g.xìÚ:Ò öŽû s!ƒ—ÁòÀQ8EnÚüBçâxÀ‹ýô"iRѨTå}Û¤ ËÀ¿sáÜþ¼/È\‹ËË‘Mçæç´¯Ô¡fÊ@Bé^(ím›—WDN\i8—{x±kÄŽ Ú.ßE‹ô Ÿ+ þ¡ø«þ¥Û-uXª¤©‰t<ê¸}ç»±ì'š ;–»ÝF<@Ji/ð$ŽóŠÛ›q6%‡³7üáxx@)Q§HÍ.úÎT­ÌšÉÐΘ³§Œz^è¥Ù¨°LŸô¾•óÉ/úƒïsÏeBèŒQ€‰"n¿½NvO@úk!'^l¿Õ/ÄBZ§b¼Ö;àn^Z™ë?7>} ‚œ„i¨±ð¶S¤ß<]I¿ endstream endobj 7787 0 obj << /Length 815 /Filter /FlateDecode >> stream xÚÍWMs›0½ó+t„L,ë ÇvRgšNM}K3 rœ¤ÿ¾+;Øql·µ;½Z-Ú}ûÞ AÐ"èÒù8v†#AQ„#É$Ï f?Hç`¸XuœâÐ"…(é*ÒlïÜB‡ð_q›×†#]ËW/áÀdÔ¶/Ð;v-]L1+^wÊ´ BÝf‹"±º4#O·´S±5fEÖfqƒ¤Ö„¯c(²¹$†Žû¸¸ë‚`“¬Mqÿ³e:†[­=ª¹Îôš`±fWYe ÜE\4Ï×Qõç`lï€n_l©žŒ¹Ìl­ÏÒ¸Ï÷v0¥éb¶—JC[M’{C”VÒ€…ý›þ*{ÕÎVû㬚’ úÑéwÏÉ6ŒÐ§P`Óª[%°ÝóˆôUó©ê`7‡܃nS«—í‰1šèÐWJHlÓØ%ðþW\`øDþž,†#-·ž¸„ÄÒ÷—Ëà-úóõaa9ߨú)Köm%¸Ã‘I¹&¸@bîóõÏ€í<³ö:Ï7ך,T‘3ãPî’#e>&’.ý% 扇±…UÒ­[ž¨ãY(qD¢õ–ß±õYº“aGÝ$á´;à©ëñ?쀣9~C}ÍçÝð­g?·Í£¸¯äÁ'ñ­çj¡ùÔ¶©Ä {)¢.3ø0€íOE\¤ð䵆»°zòœ’¸4 6“ý‹å1S endstream endobj 7809 0 obj << /Length 776 /Filter /FlateDecode >> stream xÚíX]o›0}çWøªÅñ¶yÜÚµZ§I[—·®ŠhpTŒÐNý÷³c’ùK›TŠöŽ}ã{Ïñ¹æÚLW·ӿd0à„ƒÁ“ "pë~öˆïªâ^ÙÜë!Ý÷yžÄ£°Œ³Ôv\( ÷ÉÃÚ0ÉrUØî«Ç8RïlûF%*œ+ûCB öî×ÎÇóÓÁ:°uÍ @ŒfÎí‘î¿Ò@‚_ «`\êw¾;ßTÁ@ëè$œkŽA¡Ö:o¶Æ"*,à/jvo øî|âÊÇÊAÒL(˜~2É­¯v§öÕ¿ä¼æÊ%±Ž?ü¨NZŽþÁ 5š;nŒjójžgi¤ŠaVæÃ2{PiœŽ³†?¦_›3…–Ó@c«‘š‰ ]Ž“µø·½÷%®‡9š?‚køâ´¤ä•ØãhGf/+faypú¤Î8^ÑGNˆ¾D¥“rÚ‰¾þ%•ÛI©452{Ø44˜Ü3;ñ¾Œí^u FðÒàI¥QVìG‰à ÙÔÉ P2š†‰QŠzVNG(‹I‡qô_*5RÂdòWJ:×­Bãi”Aéud¦ÜX¡Ëâ4.‡KÙz=ŒÜÍÚm-‹©0˜öîW+üœ« €q… v#³-ßêPTØL\¨Q.˜°µesY×€ÖJ)4Rc«»¹QaiDˆÜÇQi;‡[`ZÅZšMk­»[ïÉÆ@1”oQuEkrÓÅzZÆåó.Þ1Ñ'¹úüž½0ÇM‹î#Äv–s)ã]«† i¬æR7E"½+vLôÌ<Åwz=™ _¡Ü‘ØM&Ž“Ï»áïKº;ù›Yæ ÈH÷oi7½üt#…^ù†§›×ç°Y£u?b·¯S|¦%Ûù6eãÝ#ãŠU,¥I:)‘{> sOg¡g.‡ìµ‡^³À=ÏfF÷y¢–vÜî}ãêú™Žª‘^u±ôõ“m„id‘>/v þM4ÒßÏ‹‚ endstream endobj 7767 0 obj << /Type /ObjStm /N 100 /First 990 /Length 1833 /Filter /FlateDecode >> stream xÚÅZ]k\7}ß_¡Ç¶Zi>¤˜@>p[hÁ4yhü&K Þb;þûž‘÷nâ Éε7$f®ïH:3ÍœÑM­œC µJ™Í T‹ $« TÉ ¥eJ0ª.ÔÐJ×±sêJ-d’´ªU¦¬®¦˜\û\˜'—>™rȵùÒ*!·>Z TJ ü ”S Â!azÂ3$k.)~ùþXƼåìó• Ig-Ü|µ‚Y„ÙÇb„T bXœôf*¼Põuƒ´9–" û0Jík@¥RǬî%_S‘Ya“ôÕZàl®WS`Î>¶æÀ¢îØJfA*+Ó ð¶Vx¼¿576@‚0ŸÁñÝGÜl7_ÖIݻեn†I‚ÛØí¨©ÛB@ ¹ë`5œ0¬a…»ˆÍ‘Z ¢©ÀÛ"n‡9\—àÎF„5Ì‚&ßø.¨G¤ &ˆ™º_àfHØ —6JZÆXNnð)‹Û†5Nð5ð;@ÅØ7•â¶ÁíªÉ£a©* ]êq…aZàX‰™«úÁ‰%õ8ÅGIB¡ÚgA€K_£„¢=†àÄR¬¿µPŒÜòÖp ˜ õ¸7¸®"î]Âc{ƒ1µÇ½%(„<$ípW0U{ßn<¹½@€'‘3$ßËÉwÁ2ãÜ‘¯›RézÁ>•eœJ–>_…d¶:9Y­_ü÷ï&¬_\l¯WëçïÿºîÏ¿¼½øgµ~²½|³¹|™Òùú§õÏë§/sX­Û¼¾/s®‘"iDÎi4Î-J"¨=''aý<¬ܾ؆õ³ðݾÝ^ü3þ|=Záï·#©9&xQ‰c…Í™R,p²r¥ð ’TÒrH2å˜qt'(8Ÿ15„àË;%Qô0Ιcó#˜KÄaû:k îNÎIbBB@ iɽøD,GC2|"Mºêœ¤© Ò]Dr?‹ &ûž§qŠMfâµ5^Ò%=›L@P‚bvš1ä~\BS•.Љè.ÙÙ»dȲ.AXJSóÔ¦ѫ  ë,¶“…Z£Q á*¶PÂyªüHvQ’Ÿ¥3Ü›T‚䵕#ä’=’Ú¢S´!$‡>yÃ*Xb ¿…õïü‰jšR£…]¼÷îüËŠ`OÖú®Ì+¤r^‘Säy5Åf4@–É€"r¥‘¥SŠÎïf¥`[xÀf‘ŠÈXZ2! ÃV£óúyEFeÎ~Dˈ1h@`õ€{з¡̘ ¡`<Ý^\÷ ?E!Þö!§hÊ„°nž¼e!PéÝ;o~ÐìÞyž•鉽­ö',±>»Ü¾~¾Áa ë³g§aýbóá:œß>¿g¯þÞ¬ÖOdsq}åRŸÍéÕöýåëÍÕM×Ô÷ëæÍÛWO¶B?Ù>ÝÇQ={u‰ÑP¤|£Ø³Âî=¤ãé-äPÓ$äI¸±õ|ÑG-Ìæ=¯FŽEÛ1xõJÃùDS3½Òâ%ˆpž¯Y%š·£ÂÏö@¦Ýc²ây»ƒ®eíÞ *KV °Ø„œf …rà“~æ« V [Š8D””²S¶yÅ/—©CÅT¢7峊êžâEjèe^Qàš&e@‘Q-Tç¹u¶: È ê2àG;±…Ìp¨üMm"ÁèÆ)YÔÊcUåÓêpX9F+ΫŠÕÏ«ŠéÝ«ŠÑ®tì ê7v Ö]ëÀ~ìw¸ÎرÇìq›fsƒêâù’ýJ†ëMÞ줧™Ì!Y2aòE¢º‡Â("taÊm§ôp¶QÊne aÚ!]\ÖEI‘t@QQ«šŒ(fÔ}0DL{k:¯¨)ªð¼"7$Ì6€‘½ÌYP´)¥ (¦ý Ǭ" ûÍù¼"x¸}{~û‡þ4÷Ý5¿YjŸå7Kõîù­Mù­Mù­É$è$”I¨“0qí¶ãÚ~›¿ò$Ð$ð$È$è$”{àãààÈ\~} ~’Ù?¼EM3$·äƒv†7!ADDÿ4„dÙ\:ùD‹sŒé²® Á¨ÙÃ_Öíp¨£w©C8îÇ!¬ SöÑ#⌲Á#; {—ŒYÖ%;R²tÚèÿB!ðMÑ# ÑÆÑPð÷HðøH*²Ê‰(Èü×»û@¢–A‘x¼ãä0Î,¡Zä†þÆüóºšýNUë’±E”Ü WŽþù| -¾9­™z˜øu‡ÃK„Dÿ >Ù_¸×X˜öyÍ/ô‰~ÂѯBe Ç¡Cœ©ù@¢î·¿@Ý•J+QZP¬Þ µEïU¤(2‚–Ê€bN2¯¨`f< èíEùÄêÿg'ºý endstream endobj 7841 0 obj << /Length 870 /Filter /FlateDecode >> stream xÚÕX[o›0~ϯð#Hë?nêZ©ÓÖæ­«"N…– Эÿ~Ç6iIJÚ¤ ‘öıÏù¾s5= ‚®F_'£óKA‘ÂJ2‰&sÄ"W(Š£IŠî¼ï> <½šéUQùcFÞ—²\dI\gEî&.´Ïˆ÷äSظ(J½rÓWM–ê37¾Ñ WÚý¡˜1LýûÉõèÛdô8¢ A… D ’%ËÑÝ=A)Ì_#‚¹ŠÐ»k‰„ŒàwnG?G¤ÅB03ÉÍnIÑ ÞLÞô¡6R)Á„‡ðïÕ,˜S•EJE_$µ¿ç—<êBИ ¸3êçÒ>v~ §¿î¢ ‡F¥® ÷„o Û¸•8æGrr/t²ˆ-@gîäX!ŽÖ¾``¥zV ˆW{ׯÖÄk’ÚMN7AÙ¹œŸÅúpŠ£ÖR?ôr¦-ªŸ>ÌHdÎ |‹H:1Û“VŒ”»a[Ëø!K6Åp|È;ÇüâC7­‚Îc2ÂT©õc¸Ç¿ßõz¾;½ë“4)ãX l¬ëà)À!L:°>rÖ “‘F_XÓU?èé:€‡$FXª–;Ú•Æu|$Ê8, íhûe°#Ð%±¢}¾–å5gG"LbFà ÓKÔ:æEž O›ÂRÈ7«3pvŸ¯Ž—åqè“jè]éÇFWµÕ¨ª) `›U³Ó”‹Øäµg©¶ŒÜ!€¼çž¬ð¾¼—Òß—ÛÌý9ñž]y6[ÒŠ4ÄŠ·eïV?÷h´ñR»5o\Á5ã8OÝ õ£Àù‘Êò¹/ˆW¸æ`¹na¥hê²i{…YG ‡4–î‘ìé |è–°õ¾*žû ¬·ácöC6H¯&µèYw¯ü¯ÝÒ‰’Kdlå—öV³gv¶š¿Õú£`¢iÀLêÀJwÔÄ\‹ºÑqÖ:†NŠ<­ÜŸÒF ¬ƒ§áO3µ™ô!Ñ(¸DmDóIJåöh€­ÃL—¹0Tû™b™%p¯=©=º­K“MÅÑZ½à樠(d a²m•F›œo¿@Y¹÷ëÞ˾`˜ÒÖàÃØK¡,cîí„Éáí›Wv`PÕ+ÈàMûVÀsJâÑHm+ûÇþ a endstream endobj 7871 0 obj << /Length 1105 /Filter /FlateDecode >> stream xÚÕXKsÛ6¾ëWðHe,>Žgš´3mª[&ãDØâˆ¯Õüû.¡(Ê•É3¾ˆÔÜ]ì·ÄΣƒ“÷óÉõ#N„"ŸúÎüÁ ¨°±Èsæ±óÕý<¥Ü•ÕBVE=Ñ t+Ë4Y •¹ÜÊ)ÅîÓ”ÀÆ´(eeÄ7I,¯Ìý™JQKó‡ J™~›š|˜O¾O¸‚bL3àÀYf“¯ß°ƒü“ƒ‘…ζٕ9Ìáš:ÿLþž`{ Œxõ=½Û'N {Â/‡L0Â^`¼®ü^%Ë錻ëæLSîªÆÛΜ½^ßyaOvf”!n©¥Ô]߉Ÿ»H„í×®µµ7qÀÔÌj™QŒ"J®¹†‡ßµþ•3ʱ[ëS( v7Kµ©$Ò¶´¿$@‘×>¾’fÿ¹T²¬d-sÕB ²âÁ\U»WØËd]‹Ç&o®Œd›¨•¹æRI®šDÑ:ŠÒSùÒœìG©dlµ‹F³«‰éÑÙ1H GPhãV.S­˜»ÆŸ>\#™ °­! ±|EÃﻬslá,‡"Æ·?e¶Í©êñD‡ZYÀà—…¾±36v|ÿp šsdâN²cæõ×SÏá¬PWÿSFàï?…^û©NŽh·>âí¡ëKƒ4#ÄC4ä¶Iï4e•äˤéyâåSÄùEÂEÚ µ¬ž •Njc£€pÃPÄX§§©Ž§©§G©ƒ\dòº’"Í^ÝÈC«Žp`[`?I¡£ÜÇB‰³ÅFä²×CÏS'‡žÁ\Ý }¿›v=W·/ÛÈ×Oyqu¸ñ‚¬ˆ“üñÑDj­î›FO°«žkÆ|Þóíž/„< ÉE»N &= M !Û³TƒË}Èl‘Õ€¶6yhGµ§—aŽŠ$‹TþÚÜéÐìOŸq²à¯@¹ž1tñ"ǯ–Œ´„)“]Å{2ÑÊ*™K À¶ µnª†{ ³R€×&66ê‡èM”ó0·Wå8Æ{Ý”DVži†øˆGÇ¥ï õ„">9¶õˆZi•§„ç# Z©ˆÌrta“a» !Iì»Àç[Kô“ºÞ´ý¨#öIž¨¤Mü1f¬V­ÞeaJ ÞÊ"ëákERiA—žRo8jèZê<©P4L¢2ÉÇ Lž¼°ÀÚ÷?»¼©ms߉?a1õrX‡|$޹†DÐPöÉáÆÆÍ9‹{¿ ¥¦ÿ–IÕ{_×Ñ¥ûEù-(MÓ_Ç塤Â?cÿlåÝ–„—º-{lžLâ]Œ‡Ÿõ8ƒi}ôW½ÑotŒ"Blw%Ö,# ±{³eó}ξ)¡ë£éÌg‘{Sdzä—©l7˜õ†i1OpM¸íÊÌ~àüëwscÈÜÄ:€šß©‡'ýt' ò endstream endobj 7891 0 obj << /Length 1078 /Filter /FlateDecode >> stream xÚÍWKsÛ6¾ëWðHf,>ISg’N§­£Cg’Œ"!‹#ŠdHÐNþ}XP¦eÙq> stream xÚÕZMo7 ½ï¯Ð±íA+’"%A€| m’Ú9¤É¢x ÇÒßG­å8®“𽨠Gz|¢(¾™en-¤›XÈX’„Êþ¿b ¥R d‚Â픽§Îê=øSÍ-ÜâÄÊ 9Uô`œœ9-ê6>ƒ÷pÍúSˆ’yË0kfoa~)Ý ”úÝ(ª^R Ò}BûLØÉÜN—“Ï%è²»!Àš« OÙÈG–¸¨# Oš;‡ÉÁoX€,ø³Þ' TðÚy¼pÛÇËÎK·S§¡bAœ´ð„hoU´šÓ,U6ê¬K.Õû@¡:³WÔ’?>KÞRç5»¿˜\¬vÏq·°#(¸ëÃã®`“÷i™sW˜<˜T¬±’û §³©s¥5äÒýІ0è ƒÉõÀ¤QГÆAL"ôÀ¤å `s˜úâúÈxLkëO”`Iœ «Á¨t¤¬¼FK1¨6ï«î9|³,Î30[.î%À”s€X,¾#@™öÕ*Ì|ièÍp©ëa^²©uvKiî[AËc- ªIc}ŽšÐ²î%ŒSòVƒ1u^ÜØÑ£ga]a¢Õ¹¯TØY«Ý}ÿƒÝQS_ZB¥L>GEüž×Ü‘ÂUD–‚ñÖÝ=‚—XOàÊ9» {ÇÈ=ªÞRgÍG¶î(KisçÎfû0œ`óUìí'aû˯¿…â hÑ£ãôÝ›7Ï7wï~Ú(ìŽEÃ\,:‘ˆT#ÖnÑ™' Šæè ¼lÈ-¶6‘›F¦Z6eÆ.•˜ëDª±‘>6|´?=wî„í#ìûLùâ‘GØ`™±ˆ‡+lÄL÷Ô‰Öq=Œ+¤8Ü“~…)¶Ïö/ŸîÎÃIØ>~ø(lŸíÞŸ‡ËÙŸýý×7^ü±ÛlÉîôü­g$òç7Û'»·ûwg/woy¨÷ý¼{õúÅýýûp’Ða„¨oü½8ÃÓž`ø`xïôtÑNgãégÁECGÃF£ŒFvÑ44<cd#ËYÆÈ2F–ÃÈ×¼ï87Û§ï~?ï×?½>ýs³½¿?{µ;ë>¦çÛ¶?nœP¿pZ^‚ÐB1á TEÈ#i§hؽZ8*;#÷úº> Ûï÷Ïö!ñÍ[<øzú¶§¥o}}Ž‚„˜"yRPEÏ…sP-ǃ2H‘ ‰€Hcñ³B)Ú"%툔Eß0—@°÷²ÎY…à)^ÄĆ£AÅ£¥}ImtLF2Ò”}@Ró!^g¬Â οXÂY ©EŸÒš“’‚SèGE§IëRrôºqL(!s­il “‘Lí5׀⇊œI(kŠEÂ6HaôCŠÜ) ³D?Áæ @>ŸÆf†”{åaD©ôõ÷ÎÂI_'¬B‰zýÄÉ19°¤1—¥]ÌÊÇͰÊ4pJÈ#³H®QÒëÇœ®ÔÐ#?hÿ.4?2DA}¾lx‰ê²¡ fm† *hÙ"'j’ CEÅ\'> stream xÚÕWM“›8½ûWè©X# ‰cv’Im¶¶j7ñ-›š’AöPáüÙù÷iÑbˆØÎd«rA@KÝz¯û5ˆ‘-aäõâ·ÕâêFr’Ð$!YmH$H$c*“€¬2òÞûÃÊ3ÍÚ4uë/E{/v»"Ou—×¾xi|Á¼}‹zg|ýzŸgæ9Þ¿5…Ñ­ÁN… Üÿ°z³xµZ|ZpØ #CK±ˆ¤åâýF2xÿ†0$1ùÜÏ*‰ c ònñ÷‚9ŒrØ=£" ìì“ _½|{ 0g”þجÕm”§Ss›WŸ3¯î·ûÏW7AâÚɦcIc Ú­¥v†eM@MD€(¢Ià\ïû{©ºÂz¿÷CåAA*ôòÆ@yuåLð$½´®:W-Úº;ƒ73ŒÉpziÚVoûljڭÌLgÜô¼f?¸;æ§µV¾ìyîW™»i¬y»/T‹ êÍÌ­­»ÒR%Å9MTˆœ”:mê瘙õ¾sItc©-é÷Îjp4>xü¯3UfqŒ3ëÈrkëÆ-ø‡ÒY;ˆ[tçÌ›}·o Å:=Yv3ͪ€ÓØ)î¥I ‚ëëo, ‹h<4'«°Ìlpgcâ÷©ãävª¯>ah9dxBPšrmzPí©­c rƒp\ªìýv ~æö)Xl7I¸Ê8Ä}Î_öûŒ‚Q( q$?¥ÿ€ìÕ¸SÆ4ŠåDº³Ö¦¨;ŠË|³¡]Ìõ’[ª•Ê¡Ÿ¨äëÖ]µ vö³· t$Ê9}ûý†>Vï~ã¤w?†CmWiA§øõÔ8FqˆÈÿGƒçHhòœï”z›§Ó0—*TT¨¼ïÚ\ œóï ôaÂÕé…D-¹HhȤ«u>BTCQØ?FlsO›xá…´‰SûZ×ÜýádÁ' øš—4‘ý¬|¨ýÃzvb‡(ôbb¦i€î–°áÿj\µ™îô‘€áç-Ðo\úß§³RSÖ30JÁµsôƒýóÝQëAü¶!ZŠûnz·(<ûC4„Ò' z~îR„ðäc×ÁCüÂsî>f<¶ñÇ1ó®ïôη ·§H<ÿ…Ô_†2úKKÌ®0ô÷¾#¸BYY8ËÒ@ÿúoúßj{3pli˜Ö ýµ`3 endstream endobj 7925 0 obj << /Length 665 /Filter /FlateDecode >> stream xÚÕVKo›@¾ó+öU³ÙËrl•&RªšúEÃÚEÅØåá*ÿ¾‹cÀ8u\|ÈÅàÙaf¾o;-AwÖç™u}+(ò±/™D³bJ`Æ}ä ……ÏÑ,FöW‡¹¶Îç:_Îó”ýi³I“(,“uf7ÚaÄÞ:ÓõFçF|W%±þhÞtªÃB›?3†©ó4»·¾Ì¬ß…x¢ÈcàZ`x(ZYOÅ ¿Gs_¡?Ö ©à™¢Öw‹´X¦`&y­-)Êáà@ø0†ºöJ &Ü3€ot”†Áµ Ä:ÌŸë[®:Ÿx°ÚQU>ot¬Ò%vQÓQÖT»ŠJ# ~ås7hô‚8,C# '#À˜8ŪóM¯æºSô€ì‰cDÕ¶<¿BIãf(lÜHyza.“¨ïæ æ=Þ1ïTH éXô’év³écR[7âZL³®i¨qºS ùØó\¦®(XP „ì3Ú”d%gÓ&$fÔ» ˆú…ŽÿÇ­À¾º\Cîάòyæ\4m¨`: ¬\¿ƒ£J6êsdÚ °.û0@C}ì±~ u0(ã­j¢ ¬‚v¤2(;wÔÈ4·ÓΨx ýîô‹÷I?gCúÅäô›µ-OÏp%e5¡ë¸Ög8_¦NͶçØ8-ß_®^Ùõ¶¯émŽF î“ûÅndÃ¥Ù…µ]ž¼3nÀrÚ^ʰI`çJ ¿ ̬ì5Üvý³Ø¼e`+S/pȉ'‰M}> ö/€ÑèÌ endstream endobj 7943 0 obj << /Length 799 /Filter /FlateDecode >> stream xÚåWÛr›0}ç+ô™¢è‚„xl“&“t:Ó¦~K3 ÆrÂÁ8—¿ï‚°‹ñ¥vnÓi_ ’Ö{öí®A׈ SëÓÀ:<ñ( p ™Dƒ1òò=…½€£Á]Ú_&l]u™O—ùÊþXiGU’gfâX;ŒØ÷Ã4/ti¦OgÉH0ï:ÕÑT›ÅŒaê\ έÏë΢ AÔ@{Ø'>Š'ÖåA#˜?Gó@¡‡Æj‚<©à™¢Öw‹´4¦=ÁLòÚZRTÂÂÊäÅ&”`Â}Cø«ž k ž6!.0XŒ¨Ú¡ïÁ¯§¤ÁêOÖቔ ‚€=VsaoË¡.¢ëÐ>ï€v²6êø¿×e2~ “,©Â¸Ô£i˜Õ):>(—˜ó…\Û ë˜Ìø|}œ®D¿áyx^;q©’˜ú4!8`Ô¸K²6¸çJ@9æï"DEXê»0ËÇQ’nUbEÖ àÅÃçwÃ<‡JÉZvÍê^J» IêÏÅ,ê…/h}LÀ¨“Ѭº ãÜ Õ_ž{ab3lO?þ3çW˜Ã¨x`×®½æÖÄ5³[‡B„³É|3ÞlãÛm(õ6ñÇ1gq\çýZNý•ð ò/Tk¯GÜÖhÛ„iàÕ©¤±n¢Jм¹ÙIì¸Ò ì£|Ró.R=70ë@Ìü~³¸]qÛ»å·3óe#ó ßHD§}¦¿i¯x endstream endobj 7952 0 obj << /Length 577 /Filter /FlateDecode >> stream xÚÍVMs›0½ó+tD"KB€8¶M™ôÔ”[&ã!BN˜ €Óößw…ðŽÝÖâéÅB+yß¾}»°Ý#Š.‰3› †b‡ÄÚ 2J¨YÂÍ]°PUÙa cˆýèúP7XÃ:›ûrÇ E€X/ÝÏZ›¿Íæà{‹Å$2AíAé#§óÛ#ç €ž/ˆ b {¡U‘‚HkEÜE>À*"r] †U¦— c@ÝÖÞ±©»R5.¶œ°@îÞYû¾Ù‚þ+-ËgDŽS µêIµUó¶‚õHÇPŽ m„à”Äœ[wŸ¬›>AK,¨»Þ´ú3Ȫ.»<-¬­¨ªGìAÊW5™2{UCŸšºÊAáfWòq²& 1qgʳu&P2§zÔ˜ë42±QUUœ¯7°7mÏj*ïí¶2¯´ó³.ý´šv›ØölÚßÊ6“ãRÙÏð„=—y·P=/µçü ÈkÔ?~‡u~ `‚ ÿz|98Œ˜ØP!á{¡ˆû íôd8 “XZfö¡í϶˜9ôiR—ÅÁˆû “*i6 endstream endobj 7898 0 obj << /Type /ObjStm /N 100 /First 984 /Length 1705 /Filter /FlateDecode >> stream xÚÕYMo7 ½ï¯Ð±íA+’"%F€|Àm’Ò9¤É¢x ÇÒßÇY¯íŽ`lbôbs4OÒã‡Hj¶u×TRën©Rüo©sbqJÄ’ªwMd5F4qQ@º'®–š—–¤qLò¤Uc¤$ëu° Ç'·‚$*XR¥'8ÖžVð≔Jl’‚Šã‘´wlsc[lIÖ v l1£NR̨\sŽ1KÔE 1Vé­ÆzœÈ)ö%à\' \º‹? E[-ð‚È1oyR‘L=¤–X5 G6ŸÞ‚d—Ðû²·Ðœ) •˜‹ÈÎtlI¤ë ûö$•cQL“PoaX-Á9ÞîL õE{Ì•’ÄÁ ¬b+ öh%,Tñ¶iØ¥VH^VVBê€` ëõRì†0{àÜcXÏ'=ÂõEb·Ê À¯Š?¶Vݤ¦ ÏÀVphm6ñC(ùÄæ„ÓŒž”ú4±"“MÁªÅnà§êá-pQ“˜ ¥ÕZÄ ¦¶Bj ­$ÎP_»„µ´·i=쎂„·®áÕŠ}Ý#šš%+¶!+ø01a^!YX¡g‰¤ [l‡1©O{LDZBÏœ°ŠN¶GH(ÀLð›a B%‡™¯8\k» B )bW§Ö'+æFìb ëM©ˆ+„LR­AòBDg+{`£Vš¯ŽŽVë'éG³àx?Kë—¿ýž` QÏQtúñýûW«nJÏ{/©çðñ"ç"SX‘µçŽ#µ dÉ]oOÏÓÑQZÃC•Ó”c˜ÇV.ž0»ÆyÞ=!l‘'x~Ó3T¿x§1o‡Äë§gÛ7Ï7çé$­Ÿ>9Në›Oçér÷ÿü½Á‹×nVëÇ`²9=ÿémb±Z?Û|Ø~<{³™Æl7öëæí»×¶ŸÒIh‡(Œã÷ ½>ÃldWåðáéé«ìnð™î…@³À³ ³Pga§ÅÙiÙÕúùÇ?Χç_ÞþµZ?Úž½ÝœM”Ê«õOëŸ×Ohz-Þ@‚ã{œ\*9%òh6ä:Dcn…€{8ùáyZÿ¸}±Mpáw0óÝöô‡LÌþ}Øó Tå-…ð¿Gá*Ùr(k.ì LŠ•Ã1AÉ„sIÅ[–Q&,õà6a/9Š!iŽì,¥Bã¾h’:‡Èr§™‰s®H{cL¾ŠI´e$#Øé#ú Œ³,lw:¤Ij®È—L`$²o’HŒÑ‰}NŒ¨™X·£†]Ë WÈ4¨&Ë Rr¹)ï !2Á"P‘áÝpŒ”Òô¨^sç:leоe ùt€QQeÄ:"aÆ\‰¬Ã­åè—Â9úøe`AšùTÖë•åÎ5šÅ]¤6 }æZËs­å¹Ö2² ^¤'£–չЙPÆÕæ>ªØL®Äó(\ž³Õ-w0ˆbÒ8RMÁ×ÿfâ.‡ÌÙÈÕü™ˆw<Ò‘Ú½SÜ„r\bqEÁ#ú®îMß}8G#mÔË&C é½ó7m2±‘~f*±qÓ£²g”)5r,©W€·•Ô=î ©@‰xo@ؾ[j”Ê›®a×€ í‘ÉPÞYmO_Ö·Ô¼®BË@qD¦Ž ÇÙÜ,0­JsƒmX)ÇíÅw´Ü^-Ów.¾U®ßJw/¾2_Ye¾²Ê|e…¹@Ë\ e.Ð2èZ¾F9F—¥8ø‘Ü(¾—9b®,\åÜì•G³]2aÅÁ¬<Æ„XõpTzÍ6QËq£C!2xÈÐTkïß’È…sª¡³EšŸ{¥ŠÃÖ]î£Wš©°HÕA*l‡/ǵr.\/ï·5ÑÓû­çø<93Á¥ñbcL¾ŽMÂK…?ÛDÐ'è}˜ä‚È¥Iˆì[dª•û“+ÀÛú“=¡Ë­N@4¡j>ÄTê?+È1 b×[jÿ>`ñ>°sí”ã÷ƒe š¿ñ;Ç>°âÊ?±ââMm`Ei¸vP*ç®Êî5ñ Ø"Õ±}ˆ Øm_ŒKü~·çj§tçŽgnZ¾ìx´Œu<ñÓZ¿4„Òàá½¼íðîƒný^·4CÔ© jÑ2Pq„nø}`|Ù»±+ÞVóî+ÖZÑŸ‹çøEo(ZâB=dϲË@Æ•ªUNeê‹ÿá[[} endstream endobj 7958 0 obj << /Length 828 /Filter /FlateDecode >> stream xÚÕVKOÜ0¾çWøè ®±óΑBAÐC)Ýž(ZyÃFd“8´ô×wœñ¾è.‰­ÔKâÇxf¾oÆãáäŽpræ|;‡§ )K#/"ã[{$¤>çäš~v½ªvªÚºsG^œÐ£¦)‹LꢮpáD¹§®Á²nT‹Ëg}‘«8¾R¥’‰`žÇ„{3¾p>G€+œ4°˜Ç$›;×7œä°~A8óÓ„ü¤æ$ˆø—ä›óÕág¼çÌ‹|# ÒÂÆ_‹W» θ#à•• „!7vOýdí('€‡% ªôS£ru CN;C‡6TpÚg'÷í4œU¡'Y«òn’Õ•V®Ò_úE^@W^ õNpÖ,±(3÷CÈÌçiæ pЮàšc‡§@áJJ¤,6άÛQÛõï°3²*€:–z*úÒÈW— y‚ܪtñƒûÁo°rëœÖv"-›&3>ã2ã†Á!b–úVó÷!/þ,ô Gzf—,M0ôèò¼ÃÕ•%˜L•ÖÊŽ1÷×]át.«Lm9תFI­rTn®ÍoÝN_:9_xµ†jX•UÓwòn¸°Ìù¾0·wSr¶nɆ`i!ó3ÄEL«Ú¦ ÿ}7x £®˜÷¥–•ªû®46‘ žÊ‰¢)íY=k•Ì;S<ŸÊå >ëŸ9!×&&÷åJ—–Ó…ª¢Ò–êJ–ÖŸÁm`§H‰´jKb4ám`Óºik­2 {Ïû¶Ïªb“té JlßÝgÑÀ龋‰ÞaâíÏÁ3tËÊã, Óõ ÜïŠÕè;†«‘Ù[â½5>»ô¿ªØ Tt馜¹aH‘˜\j¹•ƾµï®ñ5ÃP÷h.ø²°˜¡×3[‘‹ß‹æÅ¼#Õf±6;ÿ×ÍÂ'†ŸƒÍµ÷Á Ö"Ûf2›©½^îL<ÿ?oýºsÜÚЖ Ûˆ42\' §Ç3Ù¸æI40¶°¼¯QÒãzn"kž8+€ûC¼!tx¾ØÀÎÈ6Ñ—ç8Àw BL «Û`þìÙ0 endstream endobj 7962 0 obj << /Length 1027 /Filter /FlateDecode >> stream xÚµXMsâF¼ó+æˆRaÆ–}_WØa©±œÙ±ŒÓ.®¡Üî. ÜÅêö.ֽͬ‡5ʃbéÒÜ›ðÿwqÒÄ.Qz¾oiã U ºQ&tA[Y¶Ùó ó’-WÍÒžŒÏFäuç{tõüÅ[Ì‹=û2Mcœ·J΂x0FîÌŠ½]²(Rálwoˆ¨s´®ÚÃà[^äp4º'¸â÷»«Iüvw‹æmTÙ µm´jÅ(¯•œ”JÁ®–i)¸%YKÜ6, y*EØfôLäËM$9®P/ 7?Ó%÷ˆ”eÆž*¡{ËE,a¸v´ÅÄ…+û_Ûä2´yw©€S€ \TµJ%­BÁZW/F+nø§Ö¢4dÕ¦Z‹ø.Hˆ¶¶Ê ¨bö”EVÓ^ͳ•qÝZ}Ö™¨ÚåC“ë/c2|Æ@»ýÜÅú¶ÖÄËÃ;ׄ. §Øä¨ÒsC¾Ý÷[H<‘àþ²;Åôn¾–Xõ•%–7ÇÍɮ׎; Aãu8,ØËK˽”õ:ºZ^|¨Ë aZ-_Š* ¢vuQÛ,ÿn6aáN]>ËòÒô»Éñ£÷W—ã·¿âÉiøË9i¿E:Ól|tT„¸sTƒÚ]_àáDØög3·›åãÉ 2ÀÓ[ ²ÜÁx§'½äBb·‘Çjìˆñµ„T½œÎYS…J1Û«VÛªbÃ(嫪¶y¾œ*yÐ]ú{–ßÉãùgb“áGwg¹üÀô±ÆrpToÒGSŽÁöX/!‘%;[æ“;†:Â4"á%ÃkSb9”Š”>Ùá&6÷Kŵ’‡Ô:–éSR½Œ®ÖÆ{޵µ2¢¹©ý1¦T"’ªKÚéådnŠ:ux 8O:öä? ½¯ãy¿{}âÉÀêpÒûÓ†p¢ËòU—‚«x²ýû²À endstream endobj 7970 0 obj << /Length 1086 /Filter /FlateDecode >> stream xÚ¥XMoÛF½ëWì©j²³ß{tlÇpT®­K‘bÑ­ÙVe·Mÿ}ÅY´Hj¡‹–"9oß¼RŠ?„£÷³Ñ»†E¤è”³;á•ð&‰ZÌâóø—LÙq¾þž¯Ÿž³‰òa|²Z-ïoç/÷O剳-ËGݱ¡ b—Ñ]ŠÓݞĹ«3yð³.Â=º_„@–ÃV¯!-¶Y)íÎä ,k†h¬nI‡ÃŽ{ŽñdCì¬ÏêSmÉVÇäc‹HauÃV¯DÅ*)œØuÐêu4nă“²|”Õ-Grj¯Ó¯®¦×Çõn„ý^×qÃÛxMQÛ^´†`x½”ðilÒR…§yX²À²\LÌ ^·ÄÒ`{VÅé¬Ïë‘ \Ýâ‘ìu íÕYò ÕkM±J¤mM‡¬ÞD;r!-ÇG9ÝÀ£»à>«ßLòyGxGAw«=²§\¯HÚCz—Ò’1Í>_‡'tÒËÁNÁÖXÞPä”ÞEQÄrÓÎ{Õ¥WŸÇ™lä6T+OεhlZ?\Ï+MѾ*畤ƒå|l<§åø(“µAI½ßäß>eZާ§Åïɧ£š`MO;0öÚž=kHBîmæZ¯‡kûÊèfϯÓl_`ÉËÒ~Û©¢Ä:i6{MF¡îRmbñ²øEZ9_,Ö/ÿ­ró¡e¿Mܬæäº¿Cñ5—’ÝOå ¬–Cè5Ùp¨ëŽÛÙX1¯£ —'Ù㨣°ËDì¢{V Ï÷—Ó›c¶†>ˆŽÈ!=$ ˲¿ÔU樆´è_ôv¿.Ã{ ·ÙD-»fïx“0 ="à ïÈ[Ó'YÏr@¯.ñîßb’Ü8%îRÙtüf¸ ªd…uUmYÛ m´´&)ÏoÀŠ>¯úîàB 1W›$ÇM” AŽOÿœ¯2;~ÉŠï[å—)GÙÝôøôéeb¼Zæõ åõuq6¿«"ðûx[]™T߯®.˃ùã¢> stream xÚ­XMSãF½ûWÌÑ®Š{»ç{Ž$ŠeCÛÙ"µÙ¢X°ST “òãóÆ–e,lÉÂ{§ŸZ¯_÷<‰ÕoŠÕiçÛqç݉•(yíÕxªt´¤MRÁF²É¨ñ­úÔ=ïi×̾LfϽ¾±{ôôtwsý×ÝãË Ç“žæî?=ÁÆûǧÉlyùôï»ÛÉ7Ë¿‡“ûÉõódùÖ$½Ïã÷Á¸ógG+QAãÖ–uóÐùô™Õ-®¿WL&Eõïb׃²>b½W£ÎO.ž…IðLÚ›¼Û‹šá‡W‡Ûž:ßU˜Ø„åǽ>æ—W—£E¢åŠõÝ âÖ ¬úÚâîF]øjÝx~m=%Àz(§«$„JD"± k"(é ™—Ó­Bì¼.~(Â5ÅÔl¢¦dîÆŠË&Ò"+¬`)I$%çªX ºÁÊ ‘9MÉ&å±”u_9l°d´KRMÃr(á¾iÈûJæu$x ÎÖQÖlv*™¼Ñìl¤R¸þ=ÝŽ [¬Óot;9šmUçW`Ù´[è}ïïC;|‰'†õúpÆÝßg_ÜòóÔóÝ^ºO÷Å窇ë›üí 4Á³ ¼¢þ"ZRÚP> stream xÚ½X[sÚ8}çWèÑî4Šî—G’:Lšn“réL§ÓapšL °\ºé¿ßO– k6™ÍrdéðÝŽÎ'ú‰ê´.ú­ó+A‘ÅV1…úH3¤…ÁÂrÔ£ïÁMÈd,î“Ålž1m‚ö|>yÅ«§ÙÔO|HBF‚ß!……“Ùƒ ‘i¡(ùJÝr’C ßâ®ßâ¶*VÏ(–––-iZ𠘬lÑòbŽ-ø,¬ Ä–ëbXëª}»UrÓ$Ã'•:‡È°=w™A/ö¢^$xx};AvŽA:Nvé•”c™,—ùåîY %$øjT¨ƒfXÉ7U&<½ßB= $=Y=WiË_Ÿ„zõ(™ôJõ(XD^DCõ`ÜåH¾R=ÜnnÿOõ Ö¤×Çýœ\¼ƒÔ0‰z°N2Mñ*)ôkËõýAb¥‹YÖáA3çFk×ùÉ`Í] 7Ó‰Ùý*~š&ãÀ‹dìÅx²ÜÇdpÂ@„¹€„U¦TûÕë`è~eÚ–X¶»¡‚ ½IòþýÂÍ&ÙøœŽ²7gÙ¦w×þ!žŽýÃ8^¹•ñêÏ> stream xÚ½XÛnÛ8}÷WðÑÖ,g8¼=ºŽ¶©Ñ¬íbQ…‘&Î"¨Ó¤Nw·Ÿ¿C]ìJ¶$+.Ú6²x4<ÛøÃåx9šmú£å(þ4œŽß¾}=ô]¬` ôˆœƒ2` ØTû h¤2ÐÙdÄéĨ¾õJËýl‚ljm‚0 iÔøí.* y¯šíFçÓ»Ùˆ±0bi+ÕΜzèxe3ZF Òš#én°“ñl'ªEZÎŽG»‰Ý‡Ê1©J´:© XÇÄGU‚Û¬´­9RÛmÇOò’áäg½ëæ%4öe¥fsëÀZ¼„ݼDÚsù¿ÒKÄ[í<ý/÷ý©f"´ÒÀ‘|·›©Õ3ÝT *uë&˜õ3ÝD,ôݤ½—†l½›f {Iãi•hV‡p¸%ãdã×ÄÊlN-œ}¸ƒn7@È£q»b’OïfÆP t ¬ ¤íБ·¬W­AjÕDXS?Æ]«»HWÍkÃZ¯D5¯Ú+HÁ*ÛE)ª²Ú¦ùíl#­ê¸Í'iCìªë+ÈÙx>z9:©^4@ÔH>f¹Û±-§® Á£ù2óävw²é5oùGL1 Íé;¤|¶3yŸ‚ÅÑsŠ ªDÒYô\­¸/…’ŠžÚEŸÓªã¶˜*­­¢ßÍÖ-'½}>Iôâ’}­è_mÓôÌ,‡iÖŸÄ[†wïg'9áU¬äæhRÖñB胧2˜9b’¹õ\gŽhœ Äx²Ûì|zÇÆÉð‰•%˜¦ð쾉û cYé±ÑÙ?„f»ÁN6žˆ©ç[ål‡¾‰Ë*`9¨ ¸½kÊù…˜ö¨Êok×´›-gê†ïÅ“wöèû°ƒ.ã7úÜàÊd`)ô¿l>›ì:îéî>Þv=®óë¹û«ëx×Ç4 â³³N»t6õwW.þ­ËCò endstream endobj 8011 0 obj << /Length 1004 /Filter /FlateDecode >> stream xÚ½˜KoÛFÇïú{$j33û>ºŠì4AŠÔREªE7d[•Õ¦ùöåC2)K$-¡‘"wÿ;¯wH WƒŸ§ƒ7—EÁ’Ó[áH8í¥JLâKò!%“dë?²õãS:$ç“‹Õjyw3ßÜ=>Þf)AòOŠ^¤Ê$£ÙäÝ΂]Œ'H>÷`kBy|sÉ‚;uCÒ¼¸©Ä£p©ÙIo§«|Cd *t¯/G[‰â2 ÅèdPåˆÏOÙ¢òýnó­8ÿs6ŠŽBîhaÇl4ä>›g>ï§‹€¤¦ ,q¹ø½œ¹à¶9#pµÚå-~ÅÃÕ‹’F`”Œ7ªé$=¯³ÎÄm-÷‡µTÔB%•6•Z%½2Qcšbyyp²v&`ïÀ²ŒÝ³CkVÕâÆÅÀê¦i˜V\ù¶³]Ê‘Mu»à_¸m3`e^‹Ùh¥Ç½õ_žL¼n¯¬ŸD©qžÿª^”’±g¥ôÞÉ”ª~”²=(5¨„NjlÉ—’ëFi!©9ynW@ÅôÞ”jÔB{’äð$J²Œ‘ÞøÎiÆÕÌŠ"t4²iŒm¹¥Õlä…{eý$JµvœÿЉÒXÅq¿9ãvÚA²'« È}®‹ßr+¢¼® ä`„¹Ý±V·rµ“ä[~»1TÓ{qµLÔ²Aâö.HC¶V -oQ±ŽÚ>A?B–c¶ƒi˜Ö›,>çÒ¨Y–“¥ÚÖß†ÙÆ'â^˜[Èz>ÐöËûId)ޱöÈ⪜a Wl“ÜA²…,ìGSű ç$‹8i^ë³E†Û8ïOE‹ Ïs¦OÔÛÑjØöJ¶j¦ålé®l‘‰OEõJ¶È°Îülq+ ¶coùv> stream xÚ͘Ïn7 Æïûz-)J$9´o‚4‡¶FAº( q;@úöý(E2»Æ°1Šæàµ–óIü£53;¬q¡bsPéÿ­p1˜¥5)mH+M{ ´qìR¤Ã::ñÐô^zßÒÀÇ8ÀâeâÒhet+ÃYðáaÑ¢ «¥¢Fe4òb¼¼k1L°©\þ02%¼#„i±²zaâVT¨c4¿5ŒfÈL ³ Œœ0²Á¡kl±ZŒb‹H¸MÛ(,ñL¬"NذJGe`‹‘®P™A#¬)c4 k«Æ… õhJ¸jÙDTÎ6øuT6)<‰°!‚¹jn¸:=ÊŒ´µðaH¢ìŠÀÒ ’A0°Ehì‘‘ájk+8jº| ‚<FëƒcÖë3" G#êÿ° »›¨:‰ÑÚç3¾ |˜D¾ŽU,BSÞœ5| šjÇ_5EhmÊŠQM_>&ðÑXerÖ…lmÕ¡I[õÆJ[õƒs‘ÖP+,/¢K×ÁEh@DzºÌQ„¡ØK-ê‚}“@6øPŠX&VѱbqŒæò«æóà´Å#pÅÉDMaCTlV:hØ£:ÙÉ—ìs o¨Pg¸„ #l\Ø&FƒÃ‡b4ù¡°É…+‹­Ü¼ôÎ6LöÅU|t]« z´‡ s5ZÉs·Þ0­›Ñáêêp|^nÐJÑ×/Ëñ§Ÿ) D¯Qé÷ß½{}xöl ¯oßß—««r¼Æv³?L¹]þð ³ÑÜc}ÃÄã‹·o<Ý—›r|ñüº_>Ý—Ö|õç'\xóÛépüëŸÞßßEg¯µÇ—§»ÛÞžîº}Ù~8ýúû›ïn?•‚!šÀf{ Go>`vûþíá!=û,=lä°ê@ê‹ôÎ…X¹Ñ¾HU+áÙvª8Ðö…8+õ„°»Õf‰D@E†Þ6­ÑÖ»BQ â‰qø×äw…@½2Úq_(\E3+Ò¨qžÿ_±3Œ•¾cå$ÆÊ Œ7¢Ç1Þ Åx+Dùq î G5îWûBò‡ú®°;WÍ膢|_(>+áFº/D§Žô]!ny5sö…:°Í ×x,¨J‰¬Ù¨Æmû‰}q¼Ö¸ù»ÄèB—øºdf»dfºd#"ªÄ¾/TiÕ.ïÚFH½:Í}á«cHBH$\wÍx*J¹£“5ܹøò!²ò¬AÕ®Bu^¼+l…Mj<§ þ0ö Û0¶,Æ–Áز[cËblYŒ-‹±e1¶,Æ–ÅØ²[cû¶0ž0ö'`ìYŒ=ƒ±g1ö,ÆžÅØ³{ã;Y;'„x¦ª}$b”6Ï_ã. ‰ñH—p݉™:Æ$oëøï1þòñã+¡Æ[ó¨gjLö3¨gê™zf¡žY¨gêpà8ËäÑñª¦š±Pµ„g1¯ãâù¸2PMèšK•LGz~ËH3o‘©ók‘^?"eÞ/#}.zé3áÀÑæ^Ï…Š7ÁÏïùDÁL endstream endobj 8021 0 obj << /Length 1040 /Filter /FlateDecode >> stream xÚ½XÉrÛ8½ë+pS#ÝXyÔxË$åY$å0•J©›N©FŽ<²gùüy µ˜´(’’jN0ià¡ñú½nˆJ|J\÷~œôή ‰T¦Ž˜<F²N…7AšT‹É½øÜÿ˜°íg˯Ùrñœ ؇þðéi>»»}™-¾/.²„Uÿï„0q¾xÊ–Åëë¿f÷ÙÅߣlžÝ>gÅIfIɗɇÞå¤÷g$Jú–Ré¸Vù£qìC-sTÃë1j„ò† b¼–)ÊÜ^FÐýUå¯!•D1Ýf¨XÞQú1ËŒf+}4!ßEú© ^ãjÀR‡½¤í¾‘¯KgáƒUcK¡äÂçfá¯x…g”U^•¿^í¤ Ýò|”ò ”jÐO[Hzq9>…ükqv[€5œn…öÈ+»½Ô š“nvÀÑJc^]%òÕÝ (¡p ±Án rÃÔÖ`T3bÀxIžyÛãƒC „Vêê`V¶OnÝhƒ5¹¸ˆ¾ªÿ·M&xµÖxê”ê£L Á?+ÝÂö¨›O‘HÛ½þ££KKþ”õŸ˜Ñ|’úÏ.HíݱõŸ=8½—µæP æÀPŠ%—¾oÛØ¡†;:°ÄÕQ±ÿ_ ˆ;§è˜-Ô¢`kY•ž°P°R±>E \ÑÈ…c[y'½5¼5·€J@¶€R<¹BÛ@°±|Xˆ‹•5]rý+^ìá×ú{TÍ I­z ~ÒÉd€ksÿåW[|{ž=&Ûš¯>=ÞÆo‘$Üæ·H~¾š×ís+òÿe¸,A endstream endobj 8031 0 obj << /Length 943 /Filter /FlateDecode >> stream xÚ½˜ÛRÛ0†ïóº´g¡]/i 00”¤†É¤Ä´ÌH=½}W>$Ø;NRnp¬ß»ÿêÓ&ìì°ó~ØÙ;PÀ<÷ Þ0‹Ì*Ç•—l8a—ÑIŒ:Jæ_“ùÃcÜEë¢ýÙlz{=~º}¸Ï>$1ŠèW tãôa–̳áß·“ä]öù"™&ãÇ$û8"‡øjxÜé;?:@¡Ù£·Â²ë»Îå•`?f‚KïØïô®;¦Œ£ë” :Ÿ:"OCp èG#ÃÝØœ&^ ^¼–0.¤ÍîÄRDƒÏ§Ã¸K}9ïGûY¸‹çå×½Z½”¬‹Šž¤ ¥ R+°’®"$¸GÌ„.z䜑ôøKãP·””Q†+ðU÷¬· ÷×ðÌAzJˆ!\WJJRÉt"_ŽÜ9Ëæ »)Uáu-´$UÞºBËiNIp¯uU*-ù¸´•å–r3RqWçp)ˆ’M wäi%ÊPSñ× DJJÞW„IS SÑsM»²b*p/X½ŒjWå­øÐžŒó&KµF\ˆ¨·Äc¿? ŽÂˆŽ££ÓýXꨗÖdäÍäôÏzÃ’rªZ¯Ø%\xËÑI¦¥,öÈk&#X®&”’T7OsyÕ‹å­P Z´À–v±ƒ¬âHZ&AÙQÁ5Ò–BÙÂôº,Q媑µ…ËZ.µ-à‚Fº6‚U›àz¾Z lW÷­àRNr«õp¡6#šk×i,uhbPAÌ áW!æ<ùg™¢E M­ÕD! nF¬¤ê9½¬}¾¼b¤%)?%᪈Ѱwëïdðšz±&:жó½Ž2Ÿî¬Jtm1£ÞKg@9¸3ÙˆYau8B\Õé&Ê‹CI°]é·¢LZÁ ÈÊBþO ˔߼…IaŠ-²«&©èVø´0ô´Y´Ú¶…aàLA Ó%² [X)°”-\·…¡'£ß°…!AfÕv0Ô$gq¶¤S#ð¸]«VºNt· ¼,6Ê®:Péµq;é``ýd’Ûv0pHdúv¾7w°Jtv°Rp)ejÝ6œvÃVkï[Õþ…XømEÇžYû…ÇêoÈrüP(ÚºÂ9Bðûxëè)ïo²7/†Ç]£|Ô{¸ 0ΦIqC6?£ÉM¾‚þÞ_ç3ÝüÝÏùÇìÃø~’}˜ŒŸÂã§¿³ä±Ä™þÅ®æü endstream endobj 8040 0 obj << /Length 1006 /Filter /FlateDecode >> stream xÚ½˜osÚFÆßó))›Û½ÿ/‰nÓ8M0í´“É0䎧»8Mûñ³'!°d°$ðô•à¤{nïÙûÝi%ÅŸBŠ‹ÞëiïÕX£,Y1½ä5 Âi:(1]ŠOÉÏ}2I¶¹Î6wý9Ÿ ïïW·‹ù×Û»/EÛ¬O2ùÖG~puwŸmŠæ‹n—ÙÅïI¶ÊæYñ°ÿyú¶7šöþî!Ç# G<´'X¬{Ÿ>K±äö·B‚ ^ü›?µÚz¾®ÄUïcOnç"y Ȫø´E±áO'‡fGE R¹b£÷ýÊ$òÅ$|͆“¾IÒqœß/¿Nf?^ûŠò ì"Ø^_Yo/.Å€4mJítZ(¦ã­Ôa™½œò59 ¨›ŒSvÔÈD;ãà©¡D¤V[Ðꦺàv¦¢áAö¶ò1€x¹8¤§•Žzy{Þ—À{'6™¸©äå˜ÀBŠ—‚ó;!´à,ñ•ošºVž96òÑzU’<ËhðÍWb©ø¤4AU‡§ixU´ G16&T£‘ÿI‰®iüÒW `x±V|Eðødðƒ]Ñê.)>‹,ø`;3ýþá…¨9*õBä ãƒ0J•+⨯^‚'l†§”äT¾WfyÛ½?¬¥Y =ƒèvRÊõª=?„¼ÞG„àHµ1û† ApºSW†x‘JƒÕrˆ|#D¥¿¼‹h6´æoGzKRÝ~JÚ+pÆC)í+™ /GïÞý4Dò³xË$W³ô„SÈVSœVdsÉ“N#¬1e½T‡˜’†M Bs'Tö9‹Irúµjfª”ä¬y³ËyÙ½S¬%£–Ô̧ÙïÂ,ï°­¡âQZ–áÓÀS[ÇŸË*Ð|ÚÖâê –å³©VVh«4™³J¾îqW»Î1Ô-égq¥œ‹ª WdìY\™ÃY.dO犺q¥¤-ÈKq¥x@'ËpE—ŠÑçrE>moæª׉\UÂʹš·åŠBÜÉ`‘üøÿÈñ “vtŒ«7£+5K_ó;ÃûßÎ8›eÚI,3P=‹ëEñc}W”¥ü3½¼*~d_âvð-’Ÿ—°Ë¢y9ÿ:?XWqùÂ˃*—ÎÑ—Ë¥¥mSZ•’’ßÉö%Ѷ{çêʳ¡è<8T§—Wü`\ˆž€BhÊÏó啿“£Ž{‹íV^Å ãq8‘4yÓ\_mÍuq‡tusK¬}oB§l?‹µ“fÊZâ8üÎH€¸EÐ «Cò׿Ú_Xn×ñ4»_m¿¸¬ç‹øù†mÚ (>ˆeÑ›·‘ ^ìÛwgïÖX endstream endobj 8049 0 obj << /Length 959 /Filter /FlateDecode >> stream xÚ½˜ÛnÛ8†ïý¼”€zÊrx¸L4»-vÑ&‹¢ÜXÙ à$®“=ôí;’|¨”È´l£7¡B‘Ãá?‡ciõ—Òê|ðfd'óùìözòtûp_wœ9éìßeàìa^,êîón§Å«úù¢˜“Ç¢þ0ÿ<~78¾P\Ñ ë¥-xíÕõÝàÓg­¦ÒÿNi01¨ÿªQwʺ íL]>ôrP¼×@Δ£ª…¼xÖyѵaÔ ¯7|ö{>DÆÒpö燳«Ó³Ks5z3ºº8ÉYgTž¯—^¶¯ßŠ¡U­†deQ^[¦^6³jÂ9Ьœ‹Lmq|ôkqÅ…<©´W6ç/ÙCЮ»ê¯æ„àÕ¢P7 }» 1D1d#âÚ:ðŽ¤•—ܶUE@tÙhE†@SPŽI6RŠ5|ièd,£iûc °DwWwŒàϱéþ_kíRë¯tµ^ÎkêŠðÙâ/NÕÑ÷ ñAä;´(&É¿üå¤õ®#†]f¶QÏ.Zs4êÙ1‡SÏlAk:”zfbJ±4õ-ö£¾áME=ïH=Ëy¡à÷¡žYÆÉ¢?‹zÆ© ÇcäúN;ذ†•õ¢´ÛD”%ðiðW5Hj\G¨žÝ}¦4ÅA<±kS$”ÅìS‹$w9 IÙ¶±/{CÔò§/û ‡?ºS²:ÍþRZ96Ú‡–´IúW“¸Ð+Ðáo…V+×c7ÿ•þ£‹œ³Ña`ihÔÿN,/%·='Xò%ÿÊ"ƒµ›*¥žÝI’r»'€Þ¤~Þ°Gê—¥åJ3ÎzJ¨¶…~!H‰Òr§wæ—ëÌsÓ›*õcÿ¥´RIþ˜ú+e“ôoæZ½}þF’i“Âÿ·S{XɳÕÊVö)HÑ‘} ¢Œ¡c°O.€ñîPöÉËgª¥Ùo¹³'û o*öiWöÉIöv¸üåä’ØŸ?©*ä¢LÂÏGHü]V¶ÂAªãáÇÀRi›cÀR”¡ ‡Â^~+°M¨–†¿åΞð7¼©à7»Ârn,Ó~ð—“5Û>‘~f«¬æ­p¿ó'£ŽŠ—7Éïü!éä`ü=™K ô”—_ÀêoWò¡ÔÐÙèá.r6Ÿ«õûEÙ[Ü,gÈßûëå›áòëÙ‡_ë‡Éý´~˜NžÊ‘“§oóâ±q^DòïS" endstream endobj 8059 0 obj << /Length 1102 /Filter /FlateDecode >> stream xÚ½XmsÚFþί¸ÒLØÜÞû}$˜8“Æžh;L†Á ¤LÁv±ÓôçwO'0/’ÀÓOBûÜjwŸ}ö޳oŒ³ëλqçí{…̃7°ñW&œ!=³Êò’çìsòS*t’­ï²õÃSÚÖ%½ÇÇåb6}^<ÜÇWY*xòOŠôâòá1[ÇÇ×ßóìM¼fËlú”ÅB¦_Æ;ƒqçï’?œ!³‚–V`¹e³UçóÎæôü#ã ½c?ò·VLG×%u~éðâ[8 }adxÛ [Ó{‡‡¾:¬Š¸´ñƒ·iyÒÓE'ü<˜\ F“þ»þdØK5O~Ïß®\\ß¾'œPκBÑšzƒÙ—‘£l®¥°áÀ’1„¨E56ÖÛmlP+0ö%<àE@ —냈ÜäÑÎÿˆÖœ³l±¯¥‡ÒÆ0£<Ä-"h‰t¯u,O­¿Sz’–V’-èƒ\MÔJ¾”b%¥Göw”$olco¤Òà­.{Ãÿ圫:¶¡U–8d*¡Ep¸·þacîm«L_Dƒ œð§ðᦗJô'£=lC³ŸLÂ:s„”ÔLH…r*4FÊ$Ø jpÚm3­[’@‚ P”ÎÅJP½Ñ«I <(cA;_·4 F᪵¥¦NÍuÙŸœ®žEp‰AÂÙJpki°1¦iÝ6¹¾ˆ=q”£ s½<“þÍèÕÀ¼ÀIW á.|$ˆ’=RUÒ¥‹ç?ã]@~o~~ó´øv?}þ¾Î`_w…0@iVÚlŠåx×!_0«À£î‰;-0ضäõaRœÙÑÖ´ •À‰ Šf ¥l]&N±J€¦j«øÓZ\H1}Ù›œT¾žT1®2´ÀJ\k)U˜:°Ê¶IñE„RÜ€²GuåæJO†«Zª¢*©w.Ÿ0¢J•KÃH±vtŠ*ÊÅ™W×Âp£i,y…qM KÜô—ŽkR"H^—‹úq­âΙãZÉ›œRӦ㚠üàê¼qMR›2ÜüãšðaÞ8º_¹ýõÓ§ Äé¨ùáÁL >ùD3«©Ù £&Ô Þ·‘éÛ"æí ž°\À’¡wo{¶Uà©Þ×;I™W¤^Òäƒù‘x(tµÇªm hbLżÐym¡ob*CNt5¦u•¾c-k6&{I¾¨ÔÑ»|’=RêÔ¶$"ßn» è‡5(Íd˜*rOD˜ÝÍâÍê!žƒì HvŸÊpf"‹3“y|<Ÿ>OOH RßÕøŠ’‚2Æ¼Š¤ ÏÒ\,)(ˆjÚÔd§^R*îœ))%or¦ÍšJ bhˆgJJ0º•¤ìa… "Š5>M;< @,ö$¤]£|ò×úNÇü§Å*íêäqYî­¦³pRHA¢ 鱄Ÿ[ nKÔ¢¨ýP¼W€ endstream endobj 8070 0 obj << /Length 1226 /Filter /FlateDecode >> stream xÚµX]sÚF}çWì£4Ö{÷{)&®¨QÛi3†9ñŒ?(&Ióï{W+!#,$AË‹ÄJ{tuî=»çŠ‘Ï„‘‹ÞOIïì­â¨Ó\“ä–NŒ´T:A’%ù½¹ŠÒõ§týô÷¹±Ñ`µº¿»YlîžÃÀys}‹o¼Z¥ë0|ñõn™¾ ç×é}ºxNàœSˆ?&ïz£¤÷w0F ó\¸Œ,-5•àªôg¶ôƒ ¤LÆç£÷‡‹W!!=dv!ŸÎ©µ†¬Sr»“Æz,æ±–ޱ–c“ @RU¨,Ϙ‚’L.&DR{09;Qìð$¸£ ¥¾¢ÂѶ‘¡¨‚J$ìÆØ²)€-«ˆÂº®° ÔÂ^¯Ï-»¥ù$…)§©uºQa³ù$«ñÑô¿P¢B:BußÏ&£ÁôÿP Xʱ:òžWVmj –ƒf˜m‡×ŠZɧwS bSDù£0eÝq*•h¯ALX,ÔpÑ"e´¨°ä”«†ÔU‹ W<¡w#Ê´˜6j±à‚C•ß&-¾˜Í¸è–ð“´(-J[©:-Î~ÀV¾š;ˆPïf4‡ª‡iP 8“Ëïnó%œåª¬Šîùîóãbóu¾&1ŽL+"0ã‡WK³¾rIPÂx#"êõÛø}›xMý1>aWóP“„â¸ç˜ôÆsÉmÓŽïÀ´2v¨–ü¥ñÓ;;Kb樱æxcÇд Tq€±ÃÆN¨½@°æ ÓŒ»`ÍÃím_—‘Šraª¤¶ðua¶¡ÚˆnY>©ô9nM¸Nä­âùp>™&óÁÕ•·>¡ÜçÓÉ,VQr\”eQ2:B/°'fr>¨z]ÜÇD›†Ç¡¹Çå£Ù_ÞB”N>½£¿B¶=HªÊƸÁ^¹ƒ¿Â=CàÞ–Ùµ6ÔP„ÀG[QHK4|¶Ã.€R¨ÄƒŠ,û5;¬œa@2_t;9ëœ-º½”Ÿ¤ °xoÑíô½&ùN0¾ ¯.ÿa°¶˜ƒ±‡ª‡©ÑúI‹»)öŸÁ¸Ôò‚/by›V£@ôßvJ “Oï(\R pEÖîh7„»“Ò¸rrŽi;¤´UŠWãéªÜ耻Ýp2;í„ó ¸À+Yå·Qål®t§„ïùf^¢Z£{½á w…œYßF[܆_+Ü,6±ÿä>j÷µtÑðé!î«huŸ7„ëk?šÞæ3”ïÊó+ýüsåô2œ,—á[pçbóc•>ïÈIÿ{(|I endstream endobj 8080 0 obj << /Length 1105 /Filter /FlateDecode >> stream xÚ­X]sÚH|çWì#ª:6;³ß°Ïqç@U©«TŠrlrå:ûìÃ÷áŸ-„%@B& [hZ³=ÝšY)ñ»Pâ¼÷>í½;3$¢ŒŽH¿ F²ŽÂ› MÔ"½_ú— Ûþrõm¹z|NìCøôtwsý÷Ý㟛ãeªÿoB¸ðþñi¹Úœ>ÿçîvùÓæïÙò~yý¼ÜüC’YRò5ýЛ¤½¿z„|” á·6Ò+/nz_¾*q‹ó„’:ñßúªa\Àñ^Ì{¿öT¾% KP’ήv$Vøaçälߪ³»’’Jû|ÁãÑâêSºMÛþ2Y\LÃñøã"½LXbºN¼¼s~|wœ-¨6¸§­cV÷cÇ 9¬XZÒÂ9àZ®3ä£/bådôzË’ŒœAf‡ó½$•[“žýP„³ Á‹ÕR|¯0}ËÎDÉD–§‰d´¶¶.8z%A•I„³Œ%…£Ø«dTáL „zR`ÐØptNÚB°ÊVsR/J)ÆGµ%Q²l<–æê,“ ´“Äþh}·²Ÿd GFŽÕŒ/æ™×‡ï?Nél8_¤“ñb” lÿçÉ貋5Ürõ â^ƒPpÈ—…uQ’ÑLé¹Vƒl!­ PLQº<¼“A2,ÏZXk$”SÄã™ U+FЏ+@¼´!v`°Á$NA‚±žXW“8P…uT2[›dí“¶$J¦á1¾Ît‹I¶Ñ¸7ïTú“Lb)JÇÕ:L¦èª?*FöÈš_N~;¡qL¦\3Ò¶á%šª0^˨m5ÝúQÓÞ6 H%ñd-•œ‡wlÀ²¹˜K£›X}|Û sf–:A]ƒt„C=£®v@ç‰ÞV*Ü B{ËȆ™”u†[[Fí¤ Ý*~’ ”kÐf+ôŸecáÕ,ûþœXLT³q¢íºƒœà‡³«Ùg DÙï häFhÒ²kdÆ[i#µ{¡„´Ò˜íØ“‡wó°s†vP[bAsVÓñ^_0^’çÞŒÀQ ŵtºAƒ €•lÔ‹É­Ðê„‚_Œ¨Û¶PÐÛf„WÁÆS·zŸä„Œ;VºÕ “ñ S^ËûÀ5µØé¡¦Ô8MfžcšA‰^ôv¬ÙDwÓ? tåТ}9(“ÂîÄwÑ?tK,Ø#ÀéFΚԹ ÑZ2ÕV‚©æ¢^øXõäb¸Â&­Fn›ú_gŠíRë“ÄÏ£:g…øOWsl§Óͳ? ªŸvÓ¾ÝKÇÃô-Ú§€ŠªøµOÁJÅúGhŸ0¦‘ §jŸ<6Ö4rÖ®ýZ2oÔ~%Ì@ÜMûëËoÓ~¬¬éRë¬lÊîè—Rf#I”·?'µLû¬¾ÙÍ;±ç»‡lýtŸ¿#{¸¾É^¸$Ìq„’¿Žf+¢kÿÄÆ-Ü endstream endobj 8018 0 obj << /Type /ObjStm /N 100 /First 974 /Length 1142 /Filter /FlateDecode >> stream xÚ͘ÍjG…÷÷)ú úvWuwuð"1ÚŒãEá…p.!`¤ Éà¼}Î9!i˜Š°6=5gºþ¾þ¹+=•4Kí©Õ$V<ÍÊ瑪ÐP5Õ!´X’¢@"­a %iã+‘ÔZ¡ØR›õ‹¦^',˜£w§¦¥Q¨‘žF£ ¦ÐâÉ„3ËH6,ʧN‹¥Ù-LãÌ39þ!O>8³–TKç*©ÖΨá Vgl˜ª <ÀÖ12&«-U­‹Î1ê‹oÕõ †©jS&¨(B³]·„‰má‘àÛî E1ηôkÎFS™JT§1Ñ^Y4øð¾èð­û¢k,0“5ÅÈè1K] ‰G©K%Y)Kx!K-Fª|ÛQ㦆<ÐGiÆøX’^™ÇĽ3R$-Ý6g袃ßa¬•+ûBýK2°AŒ¬iÃ,³¡VèF“µÂ¤â²äÅÇLÊ€f@¥2H¶Uëd¤˜T-‡Í1̤©êÀjsÔjpä…6Ì×”ù‚m¬é{Ú+»êjg “jwF…0t,]@Ët£BÅÕŒo  3È ©/³`Ruqu§7ô£.Ø&F¶èLm,è´q93BšÙbÙ„LŠà™9zÙt,u™\9‹ÇÈù}kKg&jßî;ƒuÒIœ¨i³…ĉ¨¦LT­™ÏÃÙÙáø:] +‹úm:þôó/XZø´gêêÓÇï¯^m Õò´}–LFèû:iÙ$ õÜÁï¾°ÖÜ×!ž__Ý¥³³t<ÇbhälùäœIë_žØ;,É/Oƒ½š÷ï0ÍñÍÍõ‡Owé"ß¼>OÇw§Ïwéïþüã„—¿ÇïáítuwË- òûÃñíéöúÓ͇Óíý¾´Ø~8ýúûåwןÓ3U’¹¼‡£Ë|Í}t óA²òïdkBw3›û¸*ò°*\ªû¢Rr©s_8T2—ü¾°´ÌÅ»+ìàŠKs_X<pÝšdÅŽ¹/¬-«jˆý$ã,«gr´+Äž›], Íný9Pÿ/ëËW`¬QŒ5‚±F1^ :?Å÷…}ìz–Šm/ l¦Ùždi%Ô9sÇa±/%óHÛâ®’[‰Á{ëòBvÒV#¨ó+ô(‚AУzA"èQ=Š Gô(‚EÐ_2‚þAÜeŸàß‘ï"ø@¸…àZ´‰àJ¸}˜¯…›‡ùJ¸}˜¯…›‡ùJ¸}˜¯…›‡ùJ¸}˜¯…›‡ùJ¸}˜¯…ßø0ïO`Ü£{„qbÜ#÷(Æ=ŠqbÜ£÷(Æ+!:™ñ›p_¨>°ïbTüÚy’¹•?L³FÊ(uä)cÅ©P×eüï?ܨŸÍ´=q;óùLèí`Dn#z;ÑÛÁˆÞFôv0¢·ƒ½Œèí`%«ˆQFÏ:1V«(xµ’«½”?Ì' ¶¯€Ú¢P[j‹B½noÔkáæF½>Ú¨ÿÅ<) endstream endobj 8091 0 obj << /Length 1020 /Filter /FlateDecode >> stream xÚ½XÛnÛF}×Wì# T“Ùû£ã(F’Örl­†jÑ­ÙVe·Mÿ¾³¢H›”Ä‹dD"µÜ9œ=sfg´Rü!¤8¼ Þ¼×(KVLn„#á´”˜ÌÄ×äSJ&É–¿gˇÇtHÎ'G‹ÅüözútûpŸ¼ËR’É?)òÄùÃ"[æÃ'ßβŸòûólžM³ü`úmòq0š þ »"æ¯Öà¤×wƒ¯ß¤˜ñøG!A/þ]ͺÚz¾ÎÅÅàó@®—!Ù{ dUœmQ,ùÁÆàù®£©ÜzÁÆg“«³óÔ$ãT™ä·Go­ü-_¸¾¾yÏæÏXR Ió«LjÜ€Q\+\)ÐÊkÏP\IZ¨ž9@1^N¶""H»¢xõ ·&ðÞ‰e&n*´î†RJ ÄJ2²CÁ˜:ØŠyfæ™-¢IXC¼ ßÈYÅ“ SŠ'–LÍæMßÙ¥X(^W}‘ßQæŸ6'JrµãÔ±5r:ýzÀÖ¾Û¾QæÚ)œò¯(sí$ðø*2g1ñU(sm ”ßÉW»Êknì©ò—n°Èóu¹æ‘Îï)rm,Xÿ5®Y¤š«àÒIìcV8ûõ1Êq(ɾb£œ­ñ5úeïƒæÐ>FY訑³ö>¦æÌž}LÅ—¨zß«a‰wûµ1ÑV;üqmŒbþIªÍ_?ÐÊ”!ܳ]ùhVÅ•<Ç›»:Þ`=a»ôKH¦E•Õ¿0ï§}Æâ=¬åžV´à¸Fv—>‚á?äØÀª6ÞÔ¯$ÿÏ©ùÓ[ýžUªî{>¶«¿à×ò®m±Îo›þ_XGÑö øA «Mà:Ycÿó—Ñ÷ò“«£Ótˆ2Ÿ^þ2þrqPˆ˜° k{:Hâ4àMÄs€ecÛGÒBp*A i@’*ÂU˜÷KÆÒ¨rc†öE¹'q¸k>ÈxtÂRqœGFwb¯!)4o“äëNõM n´IšªOyRø.%¡`™sJª³Ü–/¬¥Ñ½Â¾{x.’¶óùÐŽ ו‘xSrмLŽÿœ.8[žÒxÜ•TYH‡ÜR'ÇwéÐ$‹yVLÈŸ/ãhv³¶àïûëõ“áú¨ììC~3½Ÿå7³éSœ9}úo‘=V²‡Iÿ·M> endstream endobj 8101 0 obj << /Length 1286 /Filter /FlateDecode >> stream xÚ­XYoÛF~ׯXä‰êÍÎÞÛ7ÅVœÄ²¤JJƒ" ÅfR¡º¢#Mþ}gyÉÔERŽ›ÖŠûíð›ùæ #_ #·WÃÆË׈£NsM†_·’rሑ–J'Èð‘| îB®‚hõ9Z-Öá76h.—ÓÉÃx3YÌ“…›(ä,øÞ8],£U²|»¼ ¯P¼ÃÑu¨‚îý}·3ºoîêD»~І@%(Ç,åL¥)ÎòaTìùÒ˜Ï!1:1&2ï¤Ûë…=bºK)Iã9Æ™P=ò‘/°a UÖ•ðv.ø•˜´öÌ©ü™Y´†ýPÒÆÑ_ü¿¨nÍ>¿eñŸïÆñðZ–8ªyÊ}ÿ•5Û¡C„ÖçzÁ‚÷Ã7£$é{U\©àM³ÝnuP',¸mú­A¯Û\T’ã†ÍøŸ@—¡îÐ…ÝC÷žIf<ÝÄõ—óñÆ×[Å‚ñvóO4ßìj6®m~.£õa gЂH¥³ :å˜ð„,•àÓ+ä 2Û^K‚ <–dÔê<áÖÄ«.A&0FaP,ÒÔôËI:Tƒ}ó°ÛÑ(ƒÊ’t¨ ãŠÖiYvxγðÙó€ç)îv[j¤©çøgIQ2M¥qOȬÛùë¾û~0êõß& ×,OÃþ%e)}Šx=8T¢3H›sT扟³ÅvHj™èn2˜,ÇÓdm>žEôPfœ)äÇ!1üõY² ?Dy¡ËÑûʨÜûéöz…±˜ÇÂÆÈ€ËU†-›T¢ºÊðF`M*XOœQ–HÂsÏ$l4ÖÊÊ’c¢hЋܘ¥Å.ãØ·mX¶ö8.+vùnE5«éôg)Œ;|laN+¬ßj¶ïë‹Kuiv™¸øIq­¢ñtvDI`,uÆ`ŽuY`œdÕ7J˜ÚJ V©ã<—¹9Ý^¯`!–õXØr+c/•àdî”LZÐJ¼Ÿ‘’—¥€“p–rxwe-aàÌMzñ¡Õnßuº:¿W—UÎ7ød(öù.+\OvK-ëÀ³dïu…¼ÖC/ô.®O§wW«IýøUÍz¹˜¯ÓÎo³H®³íf›•¤f/SÔ·sÀÛ@œý6ǪTÚžè,R~Õ<€˜ã¿dÌ–~º¬&dãÄEOœðÇ™¢`qprrß ,|XcjL…˜£µ¢3Åüï¿«Ïj4[õM;~PþoÕÙÌafäpáh†›¯7Š`ùyK¢ *¿Ö;Þ'r ä–†WZºÀS“¼U\Of~N[NÓ·Œ³ñƒe‰$áè}Ì’ÝØ˜T†¬ýp¯…B endstream endobj 8111 0 obj << /Length 1123 /Filter /FlateDecode >> stream xÚ½˜K“ÚH €ïüŠ>⪠´úÝG2“Ì’­š! {ʦ(2x*  »µÿ~Õ¶yØ`lÃTЦÛ²Ô_K2gßgw­wÃÖÛ ™o„aÃgf³Êò’ 'ìsûÏHèv¼ú¯ë¨#¬kw—ËÙôi¼™.æéÄm Þþ'Bºq¶XÆ«túî×t¿I¯ñ,¯ãô‚€Ñ—áÇÖûaëg ÉÎ0ýk–[öôÒúü…³ Íd¤wìß䮦Œ£qÆ[ŸZ<{ HÖsF†» ²-MÊ9pi³¼Ó£n4xÿ)1q÷ÙøöIìÅ9ëEÚu=é½é Z8x!R-ÝHòö¯Íwò—æíUü3½Ø,Òqœ‹M¬Ÿ‡È¬ˆ¦àØ¿®˜Qú¢“­·;'£Õ =îM¶ËÃpwR¥”*¨L2qÎY¶ŠÙs.Xåºkf$m붺Œãî‰C"0^‡Cms†%-åv›¼Kš"äií5XÒa”öJ–´@°B–Ġ𥂗²”3£”%lÂ’F: ^ÈRæBþF–”“`õ 2•©']Á¦Zzóéf:žey‰RV<ßäRS}”éEi^%Er_%Åa©¯DIqÚ‰’T£T°âR”rf”¢Ä› ¤8„îB’1¿‘$i9Ìi¡èúkøÇm(¢º‘ãíaäèjÔ½¿= .NWAewxVÍvÌ;Vúäi$©ôâ|Š¡,DU{5;•FíSL&ÞŒ ÒŃ.îÁºýáNÈY#êïH¥ /Å$JVV9®|JMûƒˆ,ÚcA:]ÛÚ2`èˆÌ™£+Øú•°â‹~­‚`'m NÙ,ÐWA ˆ):QjAÐ=ô‡½‡ûÇëA8¯ê4 B‚’šFŠnEïbhGÉjv©8h]Réf(*T¡}Ð3HЧ“ r„§¾L¤§žëÎà`8í:_´IXpÊ4À!­Ýs&¡’•@l‹äȃ^%unª¢U)Æú*ÐѽùN¥‡laÔ»¿íÝ„Ù*uáÍr…9çêî°QÎÀô¤^Òº§Ôsô¬NÔ)¥¶Ãk›}ᑉ7,¥è¸ 5“§çö;UÚáº&Hý¯e( ÔvßT¬¤M®‹v‘zƒ 2‡¥ë°‰Íò¶º|ÊüK‰ÊhUôoeý´—Ú4 ø‘²Ð«+¤öë·Ó-ŠÄ¬²$‚Ã{)GdÜ|/#j¢äUòÐ@Ô1Ê·o/QG·—³x{Cº¾ ³ñs&Aßó§l¥“½‰ì÷Ò‹ñ|’^LÆ›pç8”°ë6äôÿzxT endstream endobj 8121 0 obj << /Length 1139 /Filter /FlateDecode >> stream xÚ¥XÛnÛF}×Wì# T›ÝÙû£bQ®’Ønd&H‚c+…Q¹vå¦ýý^$Š”Ä ôD›âΞ™3g–‚ýÁ»½MGofZ²Àƒ%ËÒŒ¼æ¤sÚsKØ×è}L&Zm¾¯6ϯñ˜œ&//ëÇû»Ÿÿ*nLW1‰èßXâÁõóËjSܾüùø°ú¥ø{±Z¯î^WÅ?’qKß’tô÷H"Á$s„Wkî„c÷O£¯ß{ÀýwLp<û/ê‰iëq]³ÛÑÇ‘(÷"¸Ä'«²§­düppsql×Ù[¥àB¹rË·f9‰•ˆ>¥¿Nce¢IìE”Æ-/²&WW“쇋|» Êë› +|ÁƤñz³ŸAORÀePÇa¶×E¤,7R2ki¨É“ nÇ“Tž·Ç”Af—Ë£’ ›SŸÿP.'î½c›ûQãû4–ΰtà„ëKZî,áʃ1M°<% g¯5qí=³†°%ßE\-˜] ›ÐÍxP~VšÞá(¸0²N°]/ß«äd›ÄJîåÁ˯Á ËôYj°RsO¡’4Cõ¿ÿ–,¯“Ë›¬ ¤óâùÍõuØcINÒ-2PO"VÈÊ7³´Èy1»@÷1"ÒF9~Ø|H0˜1r[*§ø&!¹Óª[Y[H¤0ÙU_¹|˜²€%2,”…¨DêбQZ½……¥°@ Üš!œ·hÌ…¼´ê‘‘ã^÷LyÃI¨z`à®Sc[ŠUÖu“â.íV+„i‡åü,ÀYßËqf_–“ÅÕÍâl¯i:á6ЂgÚ ³¢ÝlÐ`5F‡n³)ÑIeÕËÕ½µì%ÓZpo+¯Aå©þ’@7 ƒ0yhíº‰ks"Ö͈†º ¬ò}íäd·ÛÌB@R0Ûi6åb"wÃ}–´ÀÀàzyÍ|¶\$’ϱÃvžm.[¼SXÇA‚AŽ2VT+Qzè¡Ä3ŽáwYË×S”SÚ R•~Ì?RÁe<`B~èC[‹¬çÖå8Ú}=À㜦zLÝr(‰ÕèìÊÕ‰íCµÔ(?$ÇgIAêåóë9¼ùÃòs²˜ÏæÉ´<”Üží‡À'@kC&VÌ5ÖpãM»›ZL¬}&¨-$aÎ •½ËNP8T@ ˜ÑWw£‚ô (½%"²Ã1àŒÆ™q‹-R Ø Á ”J€¡›îÇÖc„*9ƩߑorÜ9BU«•–ó³äB8S +ûèåýôb9¿½ý”LÏVHÔ Ï(Ú tØ‘³í EsÁ»]£D´ÙÙ°jnùâ¶á¹?Jƒù[™êŒê0ž¢ðêlÞÆäIöa®Í6òþÛ i¨kJÉÕ#ÒÝ®QkÐû©Al§mTk%É!i>ÀÊN˜mïaLJ+P ©ØºåŠÇc«Côçæ»)¾Ã½>>Åc½¬ËïrOw÷ÙG>p„]‚n~¾š¤ªÕ;HûÕ»Gž endstream endobj 8132 0 obj << /Length 1211 /Filter /FlateDecode >> stream xÚ¥XÛnÛ8}÷WðQê 9¼?ºŽ“MƒÆ©£b·( ÃM”m'qm§Ýþý-YŽäX8/V(Îáð ÏÌPœýË8;ï½Oz'gJ0Þ aÉ=³È¬r ¼dÉû]ƨ£tù=]>¯â>Z ‹ùÃílýðü” œ¦1òèW,hâüy‘.³á󗇻ô]öôFIïgO+œ‰li–[vûØûú³;ÿÀ8HïØïͬG¦Œ£ß9»é}êñ|yÏ ³`Kz±789´aÁK›oxò^O±äÑçä¯ÓXêh;%±£§éÇÁÕë1Ú÷xþÿ2= ûO¦—§ÃÍÖ ßòß“3Zi·,g}Tä•~½jXqd« ’ñ„Pk·¿%‘ö"µgƺÆ*“ÖÛ‚Iá)wl‚Ç~Îß„ÀÍ&8›¹9‚s–-Sv_ŠÈa, XÊ Q`Yè ¼ÖU°MЈ©{( Hi˜ÑH[r8,ùUbNºÀ˜Ùw ¤Ó­=“žƒ’²ì™kZ» XY’ž©R,À‰½µß¶æÞv‹ùQÊ1BCßF9㛳éépÔEæ­¸Öá¼­)Á§ÚxJÖ²Cé¹oVD©ÁiW„+7零K+à ,¤GS[+BzpVŒí|#s5:ÐzƒPqˆr¶t@ÉÂSöǨF!l™%ù ³Uf›„PXÓDZ´S¨‚ ¶ÑÁÍè&”ÁÇÑÑe‚ ÁP‚M™MY ^êZz¤o] %l!9Pâ,â•›wT‚°´#_TE¹ÞšJPÊ9j2wou:@ÚƒªºÓUÚ×¢äÑÍ2Èi%õp몴6Ê`kmÀ¸na>JŠÎjˆ`\œ_%ÃËQr¼ ê¡Þ–J*ÓšIKÁESË%y!›•P jPj×>dÖÝ„@P2@I¹Sï¢o)œ²½ÐS4`,‹m¨«Qƒátè|Õ'´à”éPÌ&A—\Òõ°%—ªÊ«ªqÛ¤†W¶ÊŠN¡>J ’øG.Û¨áï‹+¼œ^Ç& Ó»áÑmRŽ8èru@C©Š¡£‹ú.’’Z‹.i‹GdÉ]c³±í¨MÇ‹¡q í®9–”çu9Ð|ŽT“,Ù‚´ºÚà(´ªêRg5PâDÙ#Í·…œXÝÉÊÄ6Š¡0 ¸CŒ’BhÌ<ÕÐ})L‡1]›¯’Ñ?ÉôtL¥ùÓçÑUÜ<Õ M‡UІ;ÃÉ•ç2nà>ÏQ×Ë4|ùÄ™>­ã>j-ÓÅ|öñ'¼[eƒ¿Ö?²§Uú3¦}¼¤O·i6òôòø=]®`ÿÛ‡ðt8Ãa¦>*?P‡ƒá”‘šäW@šp+ܵ/™u'†[£Pt5@¹+HT œlß ï€G—FÑ:`ÍW•Š_$+jÚ:_UJ~ñÿxö×xe)xÖ”7±Êsƒ_Ó•¯SÜ÷ÀÂ=„2Šiýýì@BäÇ…¢“ËUªáÙ‚¤ºŽÃçÀìCž¸OM4|~Œû:ZÌÓí„ìý2Œ¦÷¹EÎmþ¦ŸJ¼¾ÈfOwÙÃÝlfÎÖ骤WâüÙäeÓ endstream endobj 8142 0 obj << /Length 1113 /Filter /FlateDecode >> stream xÚµ˜ÛrÛ6†ïõ¸$gj‹3.[V›:Q£03Éd4ŠÄÔšèTJÛ·ïB¤(“:°_˜Èý¹ÜÝ ‘¿#ýÎë¤óê^qÔi®Iò•p+)Ži©t‚$Sò)ú=æ*J³/i¶ÚÄ7ÜØ¨»^Ïg“ñv¶ZæwiÌYô=¼q¾Z§Y>Üÿg6MÉχé<oÒüPÎ)ÄŸ“7^Òù»è#@ ÇGKj˜!“EçÓgF¦8þ†0*œ%O»»Dj‹Ç9ùÐyßaÅ»0 ø Œr-üÝH†Ž‡§ÞÚ?eÂ/<|­FÝX°ècòëè6VÑà]Òû3Ý FÉoo{;¿ËÇW÷(sÐdä†K|¤z.¹“k¡uж¦É¨ã<×ü#K}f¾Ç£¾Übd‹²t={×ÿó×6ùàÓlû˜Ÿmg‹tãÓ´/ÖÅÕñrzd»û=Oü­)=Îgœ*DKM%¸zºŒ3eº8ÓÔqH¾‚A蟔„ô’þÂÞœSk ÉRòµ’öóZ$ÑKÍØ½HNP§T]lW˜±g<0Ï Œ¤¶e.+Ub&¤Â‚´u§´¤RÙÖ> …ÖLU}bÿ²üšœ(£ÌUÈE-Ê@-9qÚ´ KûU„*§©uºÐ~ï]oØ-‹’ÞèÁß0¸õÿ»£îÝÝð‡›?Ãën/é¶£¸Ÿ.Ól¼M >‹“ùj2žç§Ëtûä_eß `§Ó,ÝlNP  Jˆ}…MvÔÛHe)‰wxm_/…y•^‹y-°¨iµ§¨6í c(0‡.5\çé¡Fcy×ý Ô"#ÖVÝkhpÀ™•C=à €>·f\„UÀU€J+¨Qêå€Þ|§T·ÌþeñTáZTkö”ézåMؘOa­,eZ‰Þ€Ð“êN“ÍTï±L¬:Ynµ2È…&’Iœ T)…MΊöL#dLT±YV/€m±ÛÙ#'CÉÆðhìz'K²e#Ùû 3œm-æM\—¶>9<¨®ÂZF5ˆ¬‡½·¿ÀÓßt½ø%᫺n–.VûÁ¶«±@á—> stream xÚ½X]OÛJ}ϯð£-Ýlwf?¼û©K)¥¥‰‘nÅEQJ E%$MBÛûïï¬?lâØt+'öîÉøÌœ9csïÆãÞQï0î½y'Á³ÌjÔ^|í…è…Ò0i…O½ ÿ$@å'ËoÉr¾ úÿ`±¸»½š¬oç÷Ù‰·I€Üÿ-¼›/’evúèávšü•}&wÉd•d_€!2.ã½(îýì…Â=È~Z²‡ÞÕ¬wqɽ)ÿàq&¬ñ~§«fžÔ†ŽwÞ¨÷¥ÇóÛà (zÎP ·Zƒ·¤ ONën8ã"Ìoxx¨Æàþyü~<”ÿùSýÏ¢áéq<>øø1 }óÛùñÍ;BÚÂr¯’~U=FMÛÁÇC`%ÓtÿZ´Â*M¡ 74!qL˶T1‹ÒŽvBã:eÞ](¶#3&ô–‰w]¢»K9,iX  Ó\yÌ*UK3B4m©CΙ–ÊÓ é–L[KA•h#ª˜ e5."Q*Ó:,¡,ã Êañ?<ý¼)ˆ Ñ2$ué*ÑÀ < b÷nnÃn™‘84HfÐ6ˆcÅãQôå<úôûƒ¨‹Ft]Š·¨5€[`a*À.&.â_ E-Hq•ü (̇äþ*?sÿ0£·Ê¾\’ûóeöe²íwìiÓc™¤Þ¡µU›!ˆuÕ,É’rmi}Q)ùön’$,AÜ(¡ߨ4•2ÑÞ¶ôÁ*&©<•°L«éÚ§IÃËJ`]%IëÑ@9®B’Ü4J² Z¸v*«D7Ir³[P´º[æ_$IÅi¶d||½Š[íkP!Ö©p};KVnlXOf‹gHÏZf¨Ka¨šíÞ¦ÕÖì†$Í!f[ùöŽnh)ëIêÇÍF{4]”ÜP1j‚ÑLAËíÑ5•PŠjT½P)@9¨ð°Ù sšÑ5MQ¥¹Ñ ‹ÝœÊny‘ð„1LIÝ ¼óQ4žD__ÅàöŠBRÉêלµZªW™R-‚}éœ(0Á[ó×<'VâzæœX «Ð¶žI‹sùÌ9Q ".õÿ8'¢4i<6¥Á0zû\ó©ÝÛÎkËdZõîÿvϲ“åôöþ&»Hö³šÜ¤O¸;üQÁÓÀ…¶(‡:.A+F}¬ID[DMG¹ÇÒÝ4ä „ƒ¢ñ\…›>Nµ‡Ø¾VÝ­I ä™RMêK RÚd5àš ÚA]UR9•‚ø‡+îþÿX~SãÙêfýï"¡ï€èþ6FV ®ÿ‰ Ñ z¼YjÙ)ï/’Zku) n\úz»7,ŸÇ1=\¹¯ÙM_ùï£Á‰óŸÑùésf0$pN1^V»'­‹ùÃú2ÓÖ•ì¾'W.ò«‡ÙŽñîôx°KuÔ÷œ 袦jɧb·-4—ã †·^ãövTœ¢z¦ê†tìߌsäÐaœȸS(uE«Tìq,M–©Ÿ2aÚ©iÚ•XŽI7k,%ÖM¹e^Vì(:dø {¢'@Ýú…áNÙQrã@ÐÎ*ŒáþàûdACÝ:pï?³7—š}-­?˜ÏœþwI± »¾tg“ë|ýÍ^/Е~þîôì8û0¹Ÿf¦“µ[9qýmUR‘ýÌõ«T endstream endobj 8088 0 obj << /Type /ObjStm /N 100 /First 973 /Length 1159 /Filter /FlateDecode >> stream xÚÍ—ËŠ\7†÷ýzµê&©`ð"1³ Ç‹$Æ ã4!`fÂÌœ·Ï_g ØêGxìM£Sç“T—_:Õ½tM%q¯5)¥^º¥Îxn%Kj¢ªaÁO±°´ÄZ1h=ÌxIÒb¶sÒêX{2*a‘dŠ «ZïaÑTÙÃRSmc©Á‚ušqXjj˜ ‹¦.ìÓ +{ON±{ ,vïž |.Ø#NDqyŒ˜)l‚‘õ°!$v›& Î’t:Àf‰”9lx«U‚à  [ÇH-l #¤‹0U®aÃÛZ·”x¢V«X¹—xKà¼è3°žo«¼òȸ Ü(‘r¢ÈtäÜ:‡C°a#86„@‘vB˜9"R,À5""äZ¨`€Å"røÌâ[^w•؃±›I¼P·‚¸Á¶U$*Ï ÂšF£¾qQw)ÈÛ£TØë–°m½pÒâ±ÆÈ·ÝZ’Á8`)-"‚ã!À?Ç(JIpHØâ-œ1AÐHè•J¢@`Ã\m‘XBp7’(fW1ò¨ $&UbµEDbˆIi¹:–—^"r/=N¡Ò75áQ¼Ç[•¤›ìCpŽÃ¦6*КR•PZåX¾ ðÊÍ‘+ÔC…#|(B¥Æ8ª˜VQ\!Ùª=â€0Õ8²ÊhÝ´Ä"pŠŽQ ÿ ^5÷ÃÕÕáø2½ÅÁtœé×éøÛï$dÉŠçZ(Ý|úøñÝáÅ‹)¨ÊYÏ>HšCQ» ª”£Fû y¦.û e‡žöA–ìmØúúöæ!]]¥ã5Šª‘ëmÊuÄĨÚãSEù¨?>aâñÕÝí‡_Oém:¾zyŽoNŸÒÿk¾ù÷Ÿ^¼ÿët8þŒõO7÷qPÌ?_Ÿîo?Ý}8Ý?^U›í—ÓŸ¿ÿéösz[`¨¸šó;lôþ³â ðËð¼|á¢l¹×K%ø ÄÊÐÜ>TJ.8»`έÒX4øš´l& àTÆ8—ñNe<€sàTÆ8—ñ~_S¹ cÿvÇGzIÆ_ƒŸA3àTÆgàLÆ#8•ñ8“ñ¢’ߘ}P¼fµñ½Í—47røºgYI#Z—ò}°•L­=UÅÇk‰ï.Ø“4M皎Öè›5M«š¦MÓª¦°â6ëìû õš{k `¡\û¨Mr»t?Ž :ªlè„öÁZ²¹îƒhˆ³È‚\-K_ðq.jz6Q)ãgº¨ù‚¨iQÔø;t&j^5¯ˆšWEÍ«5¯^ÔhøD¯Ä¡ñ×ç÷4¯ÞÓ#Èž¹ÈˆŠNbdAqñ8`©¹(ÿ µð¹¦¥|»¦…5ý8ÓôM5=€sMàTÓ8o>FpÚ| à´‡>g=ôN{è3pÖCà´‡>Ÿ§‡~&QëQëD­«¢ÖQ모pÞ} à¼ûÁi÷1€óîcçÝÇN»äfYË õ«ñÒ+Ø…^AŸÐ+Øj¯`+½‚íô ÿšö€ endstream endobj 8162 0 obj << /Length 1036 /Filter /FlateDecode >> stream xÚ­˜]sÚ8†ïùº´gÊ©Ž¾u™J¿6ÍRßd2™ŒÜ,³R »ûó÷›ƒí!WÆÆzuô=G’9{bœzï’ÞÛ ™o„aÉO&œ!=³Êò’%v}‰…޲ål¹XÅ}a]tõò2›>¦ëébž?d±àÑ?1Ò‹³ÅK¶Ì~O'Ù›ü÷8›eé*Ëo„Œï“ϽaÒûÕCЇ3dVP× ,·ìñ¹wwÏÙ„žf¤wìßÍ[ÏLG×ûÞû³Ç‹±p@adxÛ [ÒGÇu£½".m1àñ;ýð~KÝÞ$adß’¸ávø0ϯbÇ£$váWÅ.Œâúö‰î{à¬/ K8 o4¯’z½žt=^ˆ\ïn:.k-~¯ïó_/³t:_g!ØÿÖÇN i@#2£ (ôU»­·;»Q:ðöÀrê8„.£ZI (UÜüQ4àœeËŒý,¥í´– Z’¦ 5Þj O¯"]´®Šm2KÌg%@9G2 \ ÷KÑ”ü’Úàê( ÒéÖñHC|9,Ç#šúÞ+¤q¨£ºÂCëŠrDØ Oî,—áR1¶¢mH€è–ç‹È‘–ƒAÙ†œ›ØÐ.n0øtMx4zèf£7ºd :ØÉ¥“ÉtþTC‘p`(ÉÍvVœ´W+0¶™¢"îwÙÎ[w£ˆ¤4áiŽèƒÝ ãºPD]+I2”Â6~ŸÃˆ*¸> ©#E–Ž.–#RÎ J^ÕÙ&Œ¶«:åù"Š„¶ ¬hCÑ÷O£ë‡o×_c$†n_cÚ*Þ^²í6réjµxœ¦kÚËmî'é:­#*ÔYš ^ngÈI§¦D¶ j«È ‡}ýÌ[w$J‚ RÖÅý1€Îê´ïhOm/­èïÛ¹†)»)ñÕ º2Eïk[ŽI63UxkCý³o™Ú7ÖÞwIõ‘V8ëÐÆÏ´þjQ¿Û£º‚l$Ä}£|ô÷ò‡Î?š¬¦Ïq_ÓÁ¾øˆòœ>†/2dSÉoAúù‰m rí±&Ù endstream endobj 8171 0 obj << /Length 1197 /Filter /FlateDecode >> stream xÚ½XÛnã6}÷WðQ6\Þ/Ž£Ù6‰Wv.ÒÀÐÚJbÔ±][î"ß¡)Ù‘o’’ O¢(òp43gI‚žAW­ó~ë률Èb«˜BýG¤ÒÂ`a9êÐ}ð[Èd.~¦‹Ù2ô¿µ¢~ëŸS¢~i5ÑhøÒº hýßÁÜôk=ê eà9A½Ö÷Ƀ` ÖÌw£E ø°×ûaJ0á:ÿáø\:qÈeð£Ûwv7è‡gÔ½Fƒ^(ƒ~µoÖæoÖÏŸ_/m Mа²,!* ®ÁŽ#m¹ÙA$Ø2æïÇÓð©$A:ÍÆ‹Ô·_Òå2yZÇÍwügϳUæ_Fépö2Ÿ-ÇÓ'ß‘=çÖ.‚™‹ VÃlUà§ÙÌ·žÓdá$ø’ƒ%Yâ[Ét”Ã-’ñdðòsõá<],÷£Í8äAJ(,¨Ý¸¶zq*,Ün£pîq«CˆS.âº?ŸÍ°1-RôXJœãPÔP¤¤6,ΰQŠ­”»`ëÜ‚`o߯L‚I\`S+ Jö”üŇÿ{&i̬mWKÊÊ骵 Ï2˜ lÚñ,ņî-}p2U¢Y ?Dki6VÕ¡u?n_ÿÅŸAêSP5Y \Íi=t”|N‡ÎÞ¿—«ßûè8[Ìzʾγ,c+°Ur^dÍQïK•®fYñ´ð­H?»ËJ*…$5ÀX½e™ÆÊ4a,-8XD±f¼N\NÑLa"÷LjÈ2 ÇtÙ"Yɲ³J"£;ž­bٛɄñFþË„áXË~œGqÏ¥lûª[Ôù#Ž®/špKí¡U"UP‹zÄÎ+ld–É£+)v@nD×òQµ`‹ƒ-5Ÿ¢ZÜhLÞÔéwª·xekÄ¢ZµvMzŸj•,²5U Â\è÷©7[aÿGÕâ’Aõ{ãô‹»›öõíàOIÈ ÛÏ»›nõzïÕªÜ)¬zbÕ+‹dºgéh£H³Ñv{ù:O—ø2­ -3ƒ®W°z ]Êñ$Özíõ܆ª$!+Ó|]76iÀŸ¢‰Ôa0Kbjà|uß5ª©,ÁéJ°²M´Z–¼cµ+yªìØJQʧ¸ýSÝ©ˆBŒC¹ào Wt [=tº¡’Aû•ÿvhd¯Ö ޾o† üèë¾—bÑm§Û¾h÷ `À<ŽWfYR†¨Cl‚#,—-‹9êjë*«&Ô —›ÀçÓ›q °˜ÃR`ËVä@ ¯Ÿ¿ ö6œ+˜·»I8íñ¼> {Ù.¦±ª­  IQ2 T¡’X…ƒ¥+b×ÁUÜÚÌv¥A5Šø˜;- `Ví›—Ã[AØõÒ> stream xÚ¥XÛ’Ú8}ç+ôhWí(jÝõH¸…$ÅT¶¶j³)Š€3K…[ “Ýì×oË67ƒ±=<€±P·N÷é–ÌÈ3a¤×x;j¼éJ Ž:Í5}#ÜJÊ…#FZ* £ù|¹ ¢øk¯·á76hn6‹ùt²›¯Wé@; 9 ~†€ëM§Ã½—ù,ú-ý=ŒÑd¥7@9§~½otF @b8>ZRà ™.Ÿ¿02Ãñ÷„Qá,ù'™µ$R[¼.ÈSãSƒekap Œr-ül $Æ?.‡×VíŸ Œ2a²ߪqg8 Uð8Lœ<<%»¾é¢Í€‘._ÛA„Í0ê8OA:žCÄëäÊ‚8ÚnÖ«mD/Yãhg9ÑRS .ÏœqæÀ˜”†{ø<ï¿ô®! BzÄd<³æÔZCâˆ|; @1’¥ÆÜØ=”–T*K¨S*•DÉ<ÉK®“uh!©-¢ùÌs‚0­qy'€i*T÷ÂeJŸ{ñS̾Ç_Õx¹}ÞýÚDxÂB©gÑÜQ…Iš#¨… ¿®ƒ–õâ~—Z”ÓÔ:}†n¨UÐ|BÅŒÆÃΧßûÃNûµÊé6ŸJ@ª)h˜Ô­!°àeG©Œ>´[éÝ:½n_6›TcÁ.醆ùµ`E…–×çÉ%Ä>Ÿ ™—ŽJ¬¨¥ŠË1–ÿÚ'Bf]Oqˆ‹ê5¯Îva(WÞ%@‹Û*Îpáa¬È{ƒ•Eá]UgÎúÜö/c¬\a±€Å‘CžØ2…õâ|—¤Ô¨SUôZãV(01C¡Ìa¼«'1k¶Þ½N^ýáµ1Ye¢™N¦¾ûÿÍ2yͧ^@ßýW”ÍY¯^’¿B£®ŠJaYC$>0Ø·ØfËBš±áV¿BsÚCâ|æqÏÌkv'‡µT'›)«Ž{KT¨Ñ¼º0I„QTJ( à 9)…pþÔ”“ª}E9uG–÷¦”Wî|Ż൴9eÖÖáôzq¾KN\*M¾xùÓÒ Ù›ýA§=nw>vz~÷ÕôbÔÜÓ®û ¸YX­}µð0å;Ö.žÌWû®5ÃCê³oY“"qá9Q(Ü78±Ï–BÒß;ðrq žŽE53¯'.ÄâËXìUÇó„FÍù]U\(F,§Ü¹ê‘¸!3“&kÎ3α0×v[ÎĹcº\g{Š/‰&Oq™ÎN¬•sµb~æOO5VùÇõí!§™1T4|ÐÒþš¾_ÙΗ~‡¸Ydï[–“©yƒ4©+›w1mùàÎD„¼ýXÁÝÀ endstream endobj 8190 0 obj << /Length 1157 /Filter /FlateDecode >> stream xÚ¥XMsÚH½ó+æ(U…É|kæhìu’²³B[>¤R”ò†Z ð&ûï÷ ` P¸h„fæ©çu¿îFŒüM¹ë\'÷·ŠG†$Ï$$R–*'I2&_‚¡ÐA¶ü–-ç«°+"\-ÓÉ(]Oæ³üA/  þ 9Nç‹l™?¾{Œ³wù}œM³t•å?8‚òðkò¡ÓO:?:¦0ÂóW+±ˆŒ^:_¾22Æó„Qé,ù¹YõB”±§dÐù³ÃŠc0Êa=£ÂH¿Úp²ÄÄÁÃøÔ9£LFÅãk=¼»Þúó<Æþúj\ŽPb¸þÔߘ¾{w1¾¿Ò–‘®Px«® >ÆO@:‰²G“¶‚ƨ"G» % F?B΂×ÉÒÓªYð*Ì=ù,øé½–.Çé·i1»žŒ¼—þñ—l½¢‡ô é6Œe¨â®êƒÈE;p))¢dï˜æ ÷ÃÝQHI¹Tr3QlÔÚˆ,3ò\òåi,æ±$â'²;,Ω–#uZWÁ6î†öL ¥)g 0ŠÚFï”l)±%5bJ»ª9ˆlÃõÙÖH ®¥)[ÃMÓËw¼ G5»Â+§–¼üønnT;G_$4í µÎ”I»ˆãÇá ÔAâÃó1¾Da@JNAœ'¯Þ<×Ìl¾ÎoV> ¬ç[¥Mfù8Zfãl¶ž¤Óâw:ò ¿gÇÔ¥à*D»£E¼œ$C"jV×~t˜Û)"ßÞN]ÀR‹[(5Úb9M­:_[Z# â4²Î/5Âò¶j ¨´m„Y2]6Å6êjË(‡,¯2Ú¤«7»™í\|‘®”…Lµ>®«$¾zÜ'Û°«ƒ?ú7ÛˆË8qwªAd¼Ùdõ¦:-ÓÙj²ÎÆ…rå똘ÖD#{Ö­a@³’ <8Îê½Û7{ÛÉHhÄ'QLA‘zŸ—#j¬<_GR €,`,Jœã‚=‰£ª6µ-T±ÍEÙ$)UËôl™×&1mwzþE_¤$1ðRI] úñærAYªÇ8¯.=…–é¬(J¯+tÚJÝÍÍ‘&ïh2Ôùc2³ †Ó)ÊÂçT¡-$rsûœ™ooY… @` ‡èÐû~‘qÊ¢=žÔ)HåK)^눺B¡÷‘Æ´-D™ž—máÍ…('U8ŸáHm,DÅnëp‚vN¾H=BGTE¥„ÕO†÷>WÅýÞ`øø9^õzq0~ºÏ;¾ß­FµÈI­ÌJ\s«Ð* RáÒÈÖVÿ1Kš4±ƒôÙ’í Êv{+Mx,,ŽÞÙ¨}þf ñdÏŽCî# që÷¡¾´%²F&°cªöù£¢{;[&0OIY6ýbL°&¶ds‡'«\7Håíf-E+ç€ù8€3g¿8ÞÌ Šö0g@àø(yÿæ{º€^Ö¡ÿ“H14ìå‚›ù‹ïí覊ùüÒ?Íž‹¸ÎFÅL·ø”óù>¿Igãüfœ®ýÊtýß"[•4ÎÿpÃé© endstream endobj 8199 0 obj << /Length 1083 /Filter /FlateDecode >> stream xÚµ˜ÛrÚH†ïyй”ª–ÎtÏùÒLHÃb¥\ÙTŠrl²åZ{ñ&ÙÇß"ÈFb{cÐüÓú{¾™nIñ§¢ß9.:¯Î4ŠÁ’ÅA^© œö ƒÅ­ø˜½ÍÉdÓùçéüá)ï’óÙÑããìîæúŸ»‡¯Ë/N§9Éì{Ž|ãìáq:_~Ýÿvw;ýmùÿx:›^?M—ˆóOÅ›N¯èüÝAŽG Žxj N:qsßùøIŠ[þþ ‚?wÝ m=_gâ²ó{G–Ï"ù$Uñn‹bÎ?<ûrüÒSÇYQ‚T®|àñ±™ô{Ådp1(&'ãÞéåd8*&Gye6¼øðnøþr}5}y}uÆbke)º¤ybÓ&ܤ¹ºn8…@%¬e}Cu»\p•]D|0kË P”Œ—þ‹’Ò.2X 'ðÞ‰ùT|Ù°}›BˆZ:!®´×—3N`üÕÔÅ™a¯Öþaðœa ñù$7Û°N9 ë¡iFí™òÆûÍÐä¿RKÙ6å³v ™­ûŒàñY/–Á¥%~/F,jðš³p’+™U  –ÏôRp±-sÄTN¶Ë¾LLÜÛxc16jÕh\\ Þ¶SIðÆW™,‡§ÃZµŒ)©Ò’´ö ÄpB½aÇ1„T#¨ñq£±õøR±áð´R›á16´6+³™8ò®nv6Õh¾‘'NÊþ^Ø `©š®É^÷'£«ÓÉhünTðp9iÕÝ‚ ‚á,h§ (Ól˜gówÁe%)wßu—ÃqAÞ^LöaÔ›œ.s“—^Qê&±xWs\Yp²É6ú¥›±C1VIÞÿ«*e5<‘•Š—²qc3ëbŒÍñ)Ň«FYè(ÍÆ¦r,,–G-ºäzÌðþ®6ƒcT˜•vTJ«¹îýé\)n%e=X;LKý^¨( ‹'nLÃYlɆãø÷*7&;ŸæŠ/Çç‡,ÈΆã+VÞªºËå$qÏÉ™ÆæBVùEíÑÍJ’ T몞e–• ˃]U¥GS áY9¾ÝªD›NÇ ¢\23Ü`-ºÈŒÔíÌ”N[> ,Ön…f=:.ô¤ÔïMd0ðqܘˆÑ¸wû–÷Åëÿဉê¥r‘Þ½ g?d8d÷ÂíHRé^«E´~ßî¹EwF§ÙÞ½ÔâûÅîe#¼ŒÞ¹{AfMúÅî%Ž–F'eÿ™XìIXÎîüŽmK¥ˆå9kAAÞå’>ûkþÙ,_ñ=ÝÝǦæqV¾ò»¿¾‰ïÙ&®*‘«YbýÅh"Üà€}ûçqsR endstream endobj 8209 0 obj << /Length 1190 /Filter /FlateDecode >> stream xÚ­XÛnÛ8}÷WðQÖ,‡w>æân‚$ë¨Øma¸¶Ò5à$^ÇÙfÿ~‡’,EŠ#‰u_,™â ÏÌá ÅÈÂÈùà8|8“@ušk’ÜÉ‘–J'H² _¢‹˜«(Ý|O7Oñ­×«å|¶]>>ä§iÌYôo 8qõ¸N7ùðùór‘þ‘ßOÒU:{Jó?@9§K>FÉàŸ +Œ@þjI 3d~?øò‘Ž$Œ gÉÏlÖ=‘ÚâuEnX± F½g”kágk |ðfpòÞ‚Q&L±àɱšž’éøjœLO&£ÓÛéõM2½™Ä*ºŽ…Š>Ž/G™ÿ¥ÅõÃÂUØŒ ¹ÄW«.èëÌݵÆ8N™DkÄW¼I˜q¦$ŒsC­SiÔqé/ç{!2ÅÀ?Ø™sj­!›”ÜÕˆ ¨óXÒQ°Ã‹áU†€ªš`Yl«Š?pC´â¸"DbͱuÂhª éšT‰þž Ë©²¶î{aŒÙ®÷—!i+? Ø5]òm¾ÔåG£FuÍ#öÒ©¬’ZéwEÛ ¶«ô¼2"(Ð銃Ƴ,´èêâôäW‹M-‚ïát(Š7åaö©'\Þå×Y,ü®¢Ùr5û¾J÷‰K¶ÎØ2qÌ•vÊ¥o—]·¸ DœÕñgg&.„ ™šÄ«ãÇÆ©½Å…æ\y—XÖèwŦEZH“3²éP¨´”ÃÃ9Ôýa/dzÂÉl—¶*c°6(Ðo°üF¢®z{§ß£Efc¡ÄœeÖ²èäïÙ…·ýÅüS ¦ñÏ ÑÉã}Õ$‰”ÿ{ʆU endstream endobj 8219 0 obj << /Length 1088 /Filter /FlateDecode >> stream xÚ½X]sÛ6|ׯÀ£4S]p>•Xö(iÜÖVfÚI3Çb:žÊ–+õëç÷ ÒbHI¤(eúD $‹½Å V¿)­®z¯§½W—U„èÈ©éEÁ™¨¼ `£QÓ¹úØ7 îg«ÏÙj¹ ɇþèùyñp÷çÃò)o¸È¤ûP\,Ÿ³UÞ|õ×Ã<û.ÿ}“-²»u–ÿA |š¾í§½?z(|´BåI†¶àµW÷½Ÿ´šKû[¥ÁÄ þÙ<õ¨¬ r]¨ÛÞO=]ÌEÊ43éi‡j%7voöÍ:Š´ñÅ„o^ólr=™ÎÞÜŒ/ng·îOÇ?Î.¿ Q÷GÃý«Ùiýáz:¹þ0ÞLdˤ¸¾ºÜr­†d…#`$¸M %¸ 5p ‘(¿\%¡Y÷WÙúyù´ÎÖùß§,›gsØ£ F9ëÀb¬«ï£ßªOèÁ[V@ÆM¬Òåj/¤”ç2ÝxéN‚W«L}©Tñ0&,#Îñá ƒH (ˆ™ë`›B‹Þ_Ù[ñ Œ…еjñLp=ÖÙ‘‡`ÝÑäL4 m¨’ÓÿbÛè[)‹Ñk:#Ü}ot¶[áÏZr„è*E˜¢›½ý|úzjx¹VÔ#‰ÃN1Kí›æ$î·µ i½Üâ­Y‹îŒŸ°ˆ½bã ÅÔdùíz–BHÝØDpÜ xƒÃÅÖÔi˜Fw0¸a`¬ñp̆ۆß*jÒÕÖm±xÙÛQ×­ÄçY\#¸àwŸ\Ÿiñû-®=È[UY–âijœ¿¬IFÓnñ-$G·-Hѽ›ÅË%,«%÷ðD£O( ¬mP¼ÁdQhÓ lðx&1@•+L~Õ¬‡Õ%7Dil ÷­Ð²fÐîÝæümï Wß­òg9ßjÙGøX­ƒ¡®áîŽØïüôBʸ4WÓ8}›.¶¿@d¬Ë}HÑ»›ï ƒd«e‰C:Ñ÷F^ß,„„AÚ¸”«!ÛÑmJYãáľ|<#z±Y•¡•“„qÖ·ú¼ÐUöŠÑøº®m6/;³ ÝÊ|–Ë ¦ ß®ègÅ{@c¼““×kàoïä(Æoïi"™x^¼[9¦Ö«=Ýk4NM÷¯‰TÂ=_sÝÂä´í)œî©·1ÿc¶“†–ûeÞùp›¾äGãñlt1›LO>oàFÍ0ò>MTªée¾y§'¯ÄèÃ_@:º\ EÎÖÅ,Yž DNïèx ZIÚ k‡ƒ8Ûtk~Ù¼Eoë|$Èøîèàçâõ*j÷þ‹®,¡Mu][¿ìŒ„ê¼–öérÈrGrÚ¿á!@,>¿ÈûCgcÿ÷Õgοx­Cî?/Š/`w÷ésš¨$›h”,$Áϵ#Sq¼ÈöÂü$ä endstream endobj 8159 0 obj << /Type /ObjStm /N 100 /First 974 /Length 1151 /Filter /FlateDecode >> stream xÚ͘Ïj]7Æ÷÷)ôºšÑH3&‹6xWimM!¹”B°Kâ@úöýæÚX÷Š#ì7FgôÍý4÷ȵpM%5IB©ÖdÏ-3 •õ–ž¸HXZbiaÑÄÖÂâ©r‹¥Úõ`$ž¤,R+1…5úöº`°½Þ%u ¢I9\ô–´‡¦Q²²iðªô°àÉbå®ÉÙÂâÉ»‡ÆŠ$zÁ(Þ%Å(‚Àˆ‘<Ô‚ˆ-‚RŒ*GäXj8!•DRôP‹"c‘M‡"ˆ!¹£VÇvŒ4J¥ŽÊPK±Jo[aóŬzÄbX϶U ~½d¼É{De(bÙJ…Y8tx‹‡7“ÄTÛ£ê‘ lÁ6Ç;6‡=*¦–¸Ö>0+5fc½VQj*ðÑ4âsNÜQ5ØAߪ†À¹{èohÝtˆ@QØà[¶µ~€ >Ì5lˆÀë–"pÚ{ì“Q%¡ˆ•°Ñ•©‡ i!¬°¡ G°Áy­¡‹¤«"FÌUHÆ c¶(H6üiR†نbWbµƒ^ØÀNßðEUËæQipÀ‘¾Y䀸Æ>2¯J"%(dl²”À0Ž…Ä–Yl€P€HQbãaÃ!Ú Ú…£¦Œ‚ ;ö[jÔ4Ò—ª[,° m>,I£˜å’¤G̤·Èƒc EEƒDF‚¢ºé®®Ç×é›Tp¨ß¦ão¿ÿ£•zå¬8‰·ß>~xõj.,’­ø¾°‘çÎû:qÊt_Xz]ðŒ­Ë ;µ/$Ê+:¶š+-„œsìø¾PKŽžðHx}w{Ÿ®®Òñ}VÐV^¹ŽÜ£><¡Jð‡''‰¶OXæøæËÝÇ_O÷é&ß¼¾NÇw§ï÷é?ïþùû„‰žÇŸáít{ÿ5ZÇû‡ãÛÓ×»o_>ž¾>4ÊÍöËéÓ_~ºûžnÂÍLßÃч/xBöMøc²àèÿd)iÓlQx$ÄÊàz_TJ.7cv©ìûÂf=›ê‚°U[âøeE+Ú¢·ä†¶±/ì%7ô¿]!kËèD BÑ,Ÿ‚àÐ=òÉ*]@ÐŸŽ –Eµ, 8ЦÂ9‚ƒpŽà(œ"8çêØ-KîøUÙ £QÓ¾ŸhÔ ÅÆ÷H~1Z9'Pm‘@ìȾJ ¯è«ú*¾J ¯è«úb…Ó&8çMp¾¨&è´g h«Ú ‚¶Š ­"h«Ú*‚¶Š ­"h«Ú*‚ö¢ôs]ŸŽ Û"‚„3GÑÁA8¿ÝŒÂéíf¶ª¹µº ,¸•ׂŸ×*² ÄyÂMt_XA]¤âªí q_Í~ñÆ4 ¹f×öÜûÍS1ærŽq\¤ŸŠqüC` ãÇ Æg¢Æ£pŠñ™p†ñ(œb|&œa< §Ÿ gÂ)ÆgÂÆ£+èô…¹ô\„_Æ5éÔô ¨ijZšV¡„ÓσQ8ý<8ÿyúYs endstream endobj 8230 0 obj << /Length 1075 /Filter /FlateDecode >> stream xÚ½XMsâF½ó+æ(U…Þéùž# ,ñºÖE@>lmmQÄȉ«°M°“Tþ}z‘l}-T.HŒ¦ßô¼î7Ýg¿1ÎfƒÉàÃ'…̃7°äžYÁ¬r ¼dɆ}‹®c¡£tÿkº~‰‡Âºh´ÛmîÖ¯ÏOÙÀ$þŠ‘&nŸwé>žýù°IÊîé6]¿¤Ù!ãïÉçÁ4ü1@r…3Ì–V`¹ewƒoß9ÛÐøgÆAzÇþ>ÌzdÊ8ºnÙrðË€çÛà€ä=ad˜míéÁ›ÁE݆‘—6ßðâ£^]O¿Þ.îF±ÔÑlºMVדñÕry;¬Æ×±äÑòöËa…ùõÃ'‚<ás6Š–×UøÑ[Ø:ÈãµD—àšvè™1¯E•3ëmÁ™àVÉoàE€ —Ù»ÜÂÍ8gÙ>e÷%îë±xÀRâ ­MÌ ‚׺ vQu¢L¹aF Ú’ëCbɱuÒÊLÕ7JKƒº³kÒsPR–]Cß¶xA²²$3S%Áá›Åß·æÞö‹úY*1¨ÀÑÊÍ*ù’Lû¨ÂÔ´æ}%HšÂ¨¤ 7p‚Ò·®] ¤§]‘½¹y?%– XZç¢ÀBÖˆîJP”scA;ßF\CöS¾z«ªþôÍ~ík,»#xkö‰%'„³UbÛ²¿°¦‰´h¯HŸ•ý=P°š“y5»™Næ±Ñ4êx”ü|‰ ‘£ŽjÐÞ—êCT”•à¥n$ÊqÒ5¶K¢€ä@g¹Ü¼Ÿ$‹ ”väŠ* ´I‰ÙYAS™RF€tÙkÐ…q`hŠW‚SÝ m€N]Qrj(°UGvINܺ*»mº(¬ ×/ÚgÉBQ憳­Ióùjî3IÄŽî.ÙBøQ2êÝ>å”IKÑæ’ ‘–²[á%"$H}R¥(×½"´¢+ ¡óÄy]õ«oí &Г;%·ÐvÕ%$ü§tô“H0VÿGHA]&—½52½‰‡È£ñ"<ø:OÎ龜¡žÞŒu€5b¡-jÏ„£°cc׉žÞïœè –#$q(O]QnÞS,„°è—¶h©‘úAnú¼kÒЉOFv§°I/þ'ÏúêÅéC•CÓ®—œbCUÁ`•âVÁœ¬C’÷ŠùY‚’š*À‚Y-¦óB"Y˵H.PMrÜñ¼®±š £8sÉj‚.¼HËKT¤Ó;·š ¥7­ºò×^M*~ý`5)¹…¢k5A•ÒâËI°æZõ ø°ð~¡H?|Õôb€˜S!T<ÜQ5ÿ¾ÞÅ:zÃw¼ì œxH-|4~~Œ‡:ÚmÓã„ìù>Œ¦÷¹ý>ÝåO†ù7ÀùUv³~Úd7›õk˜¹~ýg—¾”tC¤ÿ œüVê endstream endobj 8240 0 obj << /Length 1042 /Filter /FlateDecode >> stream xÚ­XMoã6½ûWð(õ,gø}ôºÞ¤HlçP,F6ÑA&uúñ÷;´d9’mI\ç$K‡oæñ %ÅïBŠ‹ÑÇåèÃ'"@°dÅò» ¯TN{ÐA‰åƒø’]æd²bó­Ø<¿æcr>›¼¼¬ïïþ~|þ³|ðs‘“ÌþÍ‘_\?¿›òñÅ?ÅOåïy±.î^‹ò0ÿºü<š-Gã‘…#žZƒ“NÜ?¾|•âŸTðâ¿í[OB[Ï×µXŒnF²Z‹ä%H «âÛņÿ8x8?¶ê8+JÊU ž4«ËÙo·‹¸ªI®Lv1[M®WóÙÍŠoev»üe|={uýð‰±öÀRŒIó¼¦;yƒw kwmD¤@+#¬e\Cm–\p5Kh  Ú"b¼\EDvËûör4÷Nl ñ½Áõi(¡tB¬¡4A@-!ÓÛ¦ƒzS„@# kˆäq׈¨Á˜²äAL\~Íà”ãr%× ±oîš[íXN¶Å-‚ǃ¹–Á%¥ú,-XÔà)$ha5½Œ¿·W)ª°=™eÔSˆÇµ!ðî!Œ €Zu,˜!â¨! xãëVÃÓÔÁX6b RRåxËåÚ¬TàÆñ!Ãxäeb;´T‘xÇ훑¡ìÉŽcÖy׿¸O%õh~‘'MJúY21ÀR§Jœ‡ëÕì×|Œ2›^çÖd“ùò|çØáN¯OÁz ©…v ï,]\9&`¿@jHÉÅöE]Oc!oÕÚxŽE×X|k¥I° 艻å‡ò×!Ëæ *Çà)Ú Ö„o¥z•±#—%o“Û§Œz´ëÓ’}–04'@³Õö)ãæ}„p“ SSʹ$Ûɉòœï@ i@ë}ÏS OcEâ”U\,¦ÆB ŽwšÁà~Ks­)ëõ×Qù¼#§Ûñ¤Ú‚ Ü€a3c{‹G,÷¥o\¡âµ¯öß ÖÓ}Vñ+n^Iªþâ_•vP»Ãj™M¶8¿ªÐ#2ƒ.Rì¡L7yN7v7œ>6Õ4ÀvÌÚ÷<ÕðD{à×#–õÀ{ò¾™æò²)ýç;Îíx€UÃ)ìoŸÚ‘¥ZDÙ>5ë?bìæcáÚ ÷zÄ~t¬í¤”Ÿ¥R܃°vèdÏ“««íýôl³˜F¨iºY ç¬ÊðžfÞ€$õ.fÜÌ¡õçšr—ãŒî#®ß,Zñü Y4±z¨Y kGúA·ˆ£¥ÑI™>‹'>ÑÙÁ_°NôP€Xy¥ù˜»ëìÍ7S~@{}|Švñ²®>¨=ÝÝǯsL÷{ÈûNêv4‘iÔ<óö?6"< endstream endobj 8251 0 obj << /Length 1081 /Filter /FlateDecode >> stream xÚ½XMSÛH½ûWÌQªZw¦{¾Ž±ÀR v[©å`±K•¯aw+ÿ~{,YÆëS¹ 3š~Óóºßt¤øSHqÜû8í}k‚%+¦7‘pÚƒJLçâ[r–’I²Õlõð˜öÉùd°\.n¯gO·÷ùÀQ–’LþM‘'.–Ù*>þçvžý–ÿ¾ÌÙì1ËÿA L¿O?õFÓÞß=dW¤À|i N:q}×ûö]Š9Tðâ¿õ¬;¡­ççBLz_z²Ø†dï%Uq¶E±â//÷m%HåŠ _~4Wg£?¾N⮩2Éñèjt‘öQ&ëaÚ7ÉÉàü¼áwÃóÓÑÅt½ŸÒ¡âùaÌðÛµ¤è“fWLu©Áz FÏ‘ëA7Ïò0ðL“µ¼€¡*ƒ.¸’AB’zË"Šñqü*$‚´ë ÄsïXeâf'û±\ÂꄸÁBÏä0 "cª`ë`1Y[IðÎ kˆá|7w\Û!O±ÆÛªwœ¦MkçT0Àôï:gtÓâ%ÍÚ±ìl•f/ÝZ×-î©Æ¢Oá­ª9;v‘ŒmŽõ>ÄWõBÒŸ6ÂØ¨Uo,TzÙBr’_æxaÞI/ËF,£AJ*±œâi­TàÆq‚‡Ö‰y›Xu­«X¼ãÄö»žÓ´xÉ1kŒ¼«rÜ –­5OäE;ý ± `©N+ãÔšd0IM2-uspM&­‹.—g/´S”©eˆK­B³,6ˆ’3:”+¬»©‚¡Ð£ÐƳ+ºÄ"Ç-…j¯ ÅóY Ú(ßÌ[Ø‘x¤Vꪮٷõ̃R(xeI竼6)aclÁúnQ>HšsUs…m)„ñéÅéädtô>B¨E{] ˜ÇW9Ž/ÙZ¢œ°Y%¤­·PaÞMŒ…Òp)>DM‰e(§ÛëyCO ãµä¯Fn\¯ºŠÂ9ndÝ®SF5ªbC/7­ÏêCÁn“*žk‡ÝÂ}.qç)U[]\Ž>Ü<­Cº¨®6縢{ÇÚ@ž9Rô.µ¬çä·‡ÖâV5×\*½±8ì8d¨eu ˼ŷU‡hS÷וRÜvpm-ƒ/ÅÕâ,U2™|ýý} Å÷älÞžRAâ¡ë9Ú²¾·ô$ßÑ›KÅÒ€$µ½4çæKOXÜØ¡Ý¶ |F{e:\(> stream xÚ­XÛr"7}ç+ôUq¯ºuô–ÊÆ²[©­-Êk³)WìØÁ¹ü~ÎÀ0˜1ž…<=¨ZG}ÔG£Õ¯J«QïlÞ{wiY%J^¼šS-‰I*ØH65¿UŸû“¸þrõu¹z|œHˆýÓ§§û»›ë?ïß¼¸XD÷ÿ0Þ?>-W›×£¿în—ßmþž.ï—×ÏËÍ?L"ă/ó÷½á¼÷G‘V¬‚`jKAuóÐûüE«[¼¯4™Õ?ëQÊúˆç½šõ~êér-šKÐ$Þ£=«~xõrzhÕŬ¬I›P.xzæ“á/?ÏŠUŒë†‹Ñl¶˜/~œ,~Ÿ¯“¯f/Ÿï.µÖêD,æuuÜÓ-^Öö¹Gˆ!kœò¸Nê,…*–Ø;b³#Š’ˆÅct‘Iû5ïë6ÑB1µZªo{\¿ e (›H˜+(+”Ø*fJÎÕÁÖÛ†^¡$²,Ê;Á‚b'îö2ÚcÌxOúUN(?Ï®sJ& \%ì§$Ò6wÅ­ “¯qËùÕ܇ƒu Y[}”<[Š’ºjáÓôôj1þ0Žr$á›¶µò°248@ÖÎ'bkšèÍliTŽ¢‹Uí”áyÚ–.°œ%­¥*…È™ÎÚÀ@Ö0\L9$6H$‡‰¯ç–«‘¤Q¯f?51­Ù’ iI u’ÛDREc &ÍÚõ£Tâ8‘—,‘\MÇÿ·¶ÑŒø†D°ÊC 'KÓ‰’<¹.Ý£‚Ô„#¶*ë2›è<Šcá\ RWaI€k6Ýu`0]Ëø@¤¸†úGÝ‹¶õŒrëžUÖëz‘åV”ÌŸîÚÖضòßÅÚÀyû|TùxXѦ©üǧ“áôì?©à yê‚wX ,.Ø]n6š±0ÓÒ®† d™Û)Ãóä¬X`ùH&¼0ц¢qm!b æð¦3ƒ ªʼnYÏ+»)$÷Ó²í7‹-Á¸ÝàæV'¸M/¢‹ZÎÚñ£t!Ö´A“‹óÅtxµ˜Ï'ÃùÑ͡ܪ؜y±½ºÑY2}—¸ƒ*¶Å]Àì Î&> stream xÚ½X]“Ú6}çWèÑž)ŠîÕ÷#!°Ýì4¡ÀvÚÉdºx›° ÒNþ}¯lóaï‚mØæÉ¶,_{ŽdÁþb‚]µÞŽ[oú ˜çÞ aã{f‘Yå¸ò’gìSt£Ž’ÕŸÉj±ŽÛh]ÔY.çwÓÍÃâ)kx—Ä(¢b ŽóÅ2YeÍWßfÉOÙý0™'Óu’=Gä¿oõÆ­¿[@¡Ù§·Â²»Ç֧ςͨý=\zÇþM{=2e]çlÔúµ%òi½àhdèm€­èųÆá± ƒàBÚ|Â÷zrÓûãvfÕ‰¥Ž®zjt‡½w“Þ‡¸ "êb££ÎpœNcG~}Ó'Ôý'k£¢tù "rwp p{-ð…¶ÔžCàˤYow¤'Òî‰ãd¸\½ \˜4é‹|8rç,[%ì¾@þq, XÊsØaOІp¯u,͵'Áp) 3iJ®>……° ÄIëÓÚ(EFUi@×L:ÍQÈb` ª>¾£XYR™)S ÜÁ³¿]Nh#3‹Ig4é{£Ÿ?ôF£‹7Vƒx{\Z¡Š¸!¹žo×ÉŒwZD÷±Ñb•?¬’õ—§d½Î7‹¯aJÉÓš??ým&4z[7¯eEHë+ú×±"š)W¿YˬÃÞJÖNJµÜJq¡åN™Ær; K×?Ë  +ä¹VFKù­($A¨!·þï“n8Î|¼¹î]ìCƒ ï8X…Öð¤Ö’§»p'¢ïËͶC?¶4¥tbã¬ån±øú¼¬?Gk"A*¤Óé ÷Ò¾ŽÛåtΆƒÃR>¼¡þ‡àkÒrypX¢Ú*ûúv§8„ÒT"= ÔJÓ õ™pˆ(ÕX|H¥k‹1é:Áœ^VL[¦·R}ûÑà\£|?  EÊ«ýçîÈ‘äUŽèB5;G¥/Ó%‰p‡‘Ù/DÃã6.¢îâ1nëh9O¶²÷«ÐšÜç#tGþ¦ÿÄ\g7Ó§Yv3›nBÏéæû2YäI¤ÿwZŠ‚ endstream endobj 8281 0 obj << /Length 1074 /Filter /FlateDecode >> stream xÚ½XÛnÛ8}÷WðQ–CÎðòè¦Nš:í¦¾ ŠÂHµê4©³ÛýýJŠÉŽ%ÙÆ>I¢ÈÃá™9œ!•ø!”8í½™ô^Ÿ ˆ ƒÕVL¾ íQj„C/11¹_’aª)Éß²Åýcz¤OúóÛë«¿oï o³T«äO Üq~ÿ-ŠæÓno²WÅû(›gWYñRk é×ÉûÞ`ÒûݶG NóÔ(râú®÷å«7Üþ^(i‚ÿæ½îZÏϹ÷>õT¹%— ¤¶&ö¶ üc­q´iÕqVPRW.xô†fÃÁåtWÕO %§ƒÙEj)éÏþŠm“‹Ùhði:§”Lòe,í(Ÿ¯Ou5…GÙªÏÐÈŒºDÜ ·‚5¾«dк€g‘_RÉèä¸x±dUñö˜]—þâö²\g_IòAX´!Ô]à‚[º¼’^ÃÊ lD41>N7B #dþ£®¥÷N,2ñ½âÊ—±¡ GóK(òÒ*2Õ±rg3ëÏB\ƒ$ë¥oïŠMÖŒ3ÒªÛÅn¡½YÆñ;‡LÅ,¤¦É—üêÀ«2u~AzX›|óh°ØÍá{é‚eÒl ½] Ï>žMfÃχÙv°§g•a.ˆØ»[)rÅš5Q"¢ã?´tY9º›$*²i¬,¶Ì¼™7o@ì ›¯ƒL¼_´£n‹, ’'¨ÕYœPWmBl”CI-‹ÈÖ©mRÃÓ`Ã6ÚnžÞO ¤õm’ϧ³Ï¤Âl:Œxƒº8OTrym¬c_¶W d§{ÄNWzy:†o6M2YAjéÀ®©ÞI'‹"²‹-,±”’ˆ¾½R¸¿Ebäq®+‘[4Ãöypköu ²y>`Õ<íš&_ÍZ\#ºA5«Ñžëºy~/Ù â2Å…d³Kåf[z»¹†«’ïƒD.<\™­ôñÆœ0…óIN’Z$åðnÂa,Ã%§Aâ}X/±¸\*´ŽL\ºq ùù¢3•/Go zÅqW·°«t,“ƒUµm”ÎÕ\ÞãêT7IçÙh2¾›ï÷’ŽX«¶QNÞöaÆÇ JÞõÏÏÓ#Î8Üãx˜•Œ§’|â~ýìÖä£m,géÉG[-uI>|ðâm÷M>šª]ylÎ=uóvË=Ï­ÓÔ6õh.Yö;¦ž8Ú˜ÿ1óhà*‡ÿ寧É(ï{<<{{x1ø‹À[óP^Ú:{È<ÖI’†€ˆ·gÚ7 Å;ƒx˜íÌdsª[¸[ªØ> q"Ñ;f¡84tòüX<Í +¨õýÝæÊNK€òNËJ#Ó#‹!ù¹øFÅõáãí]ÔÓü¼N¼»ºŽw“ÌŸ@>Å©’;*`Úþñu~Y endstream endobj 8291 0 obj << /Length 1109 /Filter /FlateDecode >> stream xÚµXMÛ6½ûWð(õ„ŸCòèÝ8F³hêXΡÃ]kÛöÃõn[ôßghÉR%Û’'K–8Ã7ó8Cqöãl6ºZŽÞ¼Ó‚yð(‘-ÌjÚ+¶Ü°ÏÉM*M’ï~ÏwÏ/éXZ—L¶Û‡ûÛõëýóSñàmžJžü“ øð¼ÍwÅãÙß÷›ü§â~‘?äë—¼ø#@Jé—åûÑt9úk$ÈÎD1µË-»}}þÂÙ†ž¿g”wìßý¨G¦ÑÑõe£#^.ƒƒ ï9HTa4 ¶£Gç,8peË/®ÌêfúÛ§,¬j’*“̦«yŠ&™¬Šg¿¬Ólþë‡lº_DåEy}óŽ0ë 8KMó›6þ$àfÞáÚ K Þj†HØF¶³ÞVŒ ‡ÀiHÅx ÃevRÇ}ö/Js ÎY¶ËÙ]ƒùóX.`iRˆ 8e˜àiƒíƒC<ÕÜIáh dh$-É f°áUƒ7eŒhûE ‰b¸[ÊI0Î5Ý’¶oîŠ`mI`Ø&X€G“Ÿ¶æÞÆEü"} Ðà¤ïÒGVä&Jx*žÙüÊi(¿_‡AºjÕÉŠR@{[¿*Hθ*L¥yœ‹,£sYaQ¦%†ë@\Œ¥Äó=¼ud¿¡Hßv'6ý ‚VØôMoúx%ÕHgÛ¼ö¥eMiÒ¨@_”þFx@Ù•ýËðg–Ñ&4_M?¤cÁ“ëB‹å*›fY\\*–Õ×ó>Ü“R^RõÔV§M¸ƒA2u¯TjH´¥ÖùT˜GI%`™€eù¢+,n­.\1Ô'HP.šÈóé« ˜kÛöOXšf¸v4GJ<ÝpÏõM]ÑL‚ãÖµiîQNm€..ì GS2k*²ß¬œOW?D8çaÏèÆÒ~¥¨u ÀKì$²A«!º9@кnCJóHÝX‹z+ãL­NÐ1ºQR*HpVÆÙQs|X”lû­²æ¾éžïNÉ3µ´uÅ9ÐÜ«›ÚX[÷‹„£$u§\ ÎÇÕäí·<â^ÈÓ­·Tv){…Jt7¨>tᪿ« ‰6U·O¥y\+FX°Ðê<ô`ˆ™áGj.$ÁY2@Cb‡F¨a÷”bG¾EiDyEÊ5]Ó½mÙc¤ò€¢Íq_[ö?ëØQA¿H$’º> stream xÚ͘ÑjG †ïÏSÌ왑4ÒL.Úà»BHsÑÖä"¤‡Rv±Hß¾¿Æ¡·gYaê3«ùg$ýóÍš³ƒˆK-Üie þij•†)zi*ˆx+T{D´(Í A‡ˆ1Å­ÈàĽô¹SéÚb¹­.*\˜*cj¤Ò bÅ4vfl†¦†šdDááDzq®±â6K¥Õ6·vŒ<6@/­9Ê&ªÑH'„‘QĤ4nÑ iܧ»°÷b˜äã(¾‰E‡zSŒºG #­0¤†GQ‹À6³ìgÓÁŽÙè#ìçµ£‹ÈáÓÄŽ |„è“ê4 QÕp+¨Õ©ëIxÒáaJŒ¦ù¤# [:…[CœZ:vfŸý:ÎŽ#G¬ˆŽ0BmѯB§=*UÆhúÃȦ±ŸYèð‡F3x…"iôðe`¿áá N\œ.ù_…W ïQ8WZ[ý¢…&‘ÃbÅ.qPÈ„>4ß¿>áòJ¼ž9žæ°ÍñÍíÍÇO÷åªß¼¾,Çw§/÷åï ïþüㄉ¿Çï‘ít}ïƒëÇ·§»›Ï·Owo®ûáôëï¾»ùR®B¤àÆœÞ#ч[¬.#ÞÆ!ü¶Y\’šmź-CéŒ+„Øî‹j]jûBeZL[BXeÕ÷…méÂê‹ÖDjZð²H›,ì YlÁ¿„°ùí Aþâd !~ëOú?ÁXÎ`ÌIŒé¡°GíqcÎ`ÌYŒ9‹1g1æ,ƜŘ³scÎbÌYŒ9‹1¿,Œñæ_‹?ã^“?na¼mb¼nc¼nb¼nc¼nb¼nc¼nb¼nc¼nb¼nc¼þÏëŒû30Ö,ÆšÁX³kcÍb¬YŒ5‹±f1Ö,ÆšÅX³kc}YÛŒõ[cË`lYŒ-‹±e1¶,Æ–ÅØ²[cËblYŒWÂí|káÓð}‹ñãŸO†zœÚžõÈB=2P,Ô+¡‚ƒA¾/ìC—a–‚ƒLÛ1ÖÂÍ+áöGŒµpó#ÆZ¸ùcd™õÄð3Lg0í;Lÿ4­ Ö endstream endobj 8302 0 obj << /Length 1145 /Filter /FlateDecode >> stream xÚ­XÛnÛ8}÷WðQ6SÎðþèĮۛ¦¶³‹EQi¢îM⬓¶À~ý%ÙŽå‹Ä8O²hòpx†‡g()þR ;ǓΛ·E€`ÉŠÉ7A^© œö ƒ“kñ9;í’Éòù×|>{ì‘óYïááöæêòéfv_6ôó.Éìg¹ãíì!Ÿ—ÍÃ7×ùoåïQ~›_>æå `÷ËäCg0éüÛAŽG Žxj N:qu×ùüEŠknÿ $¨àů¢×ÐÖóóVŒ;Ÿ:²Z‹ä%H «bo‹bÎl4޶­:Ί¤rÕ‚GÇfz:øëbWÕë*“ ÓI|ާ£Á§)·Éìbò®XÁ2„êùæ-®Ð¥8"Í“›:x/‚.w-žk4)ÐÊkØP+Ü’+´P­è‚@1>†[¤-Ø/þ(GxïÄ<ßÖß ¥"”@ˆK(ÞR¨µ@„`L¬H Sôl+R$¬!^oGÞZHk”)Ç{Îoå@yÓ:&帿që1¹¦©—ÜjÇ¢²5n> stream xÚ½X]Ú8}çWø1‘×ß”-ÓN!«]©ªP ž+h`vÔ¿×$ „ Õ¾$ŽcŸÜ{Ï=¾vúºm½Zïú‚"‹­b EH3¤…ÁÂrÍÐ×àcÈdà’ï.YmÂ6Ó&è¬×‹ù4ÞÎWË´ãÆ…Œÿ†.Vk—¤Ý·Ïó™û#mÜÂÅ—>P̦á·èC«µ~¶(˜BM?-°&MŸZ_¿4ƒþˆ`n zÙzBB¸/иõ¥E27¦`=ÁLq?ZQ”À‹RçèœÃ”`Âuæð轜|¼• :ã±wꯛÉàÓ t†“þ0lStB.ƒÛɧ^ï¦w³sdoIv×ÜÃGj36ÈÂ7¿€Ý©„<@ssM°e,…Ž}”% Ö‰Û¸åÖÍÒÇiâfð8›´ã%äˆÍF/WÛ´±ú¾çË|Öóf¾ü‘6ã 6Þl^¼û«$3›'nº]ø<ùjà2³Œh Ô"%ÔÓ«­ÞÓK­Â’òÅàšwÜßnOBrL¹ð»Ùt†Ñ(qè¡&ç±”ÇâšÚì±´Å‚L)¶Rƒí2 =0Á(ÇšQ€Ø4£º`X!tÜ(l5-Û†¹‘›Æ-ÇD˜¢iºîÛû3¨è(ÆZúöéÙT‰f¤_¥g pƪ =ßu†}ßü<º»^Àì<Ðe²½‹¡ùùÅ“O¹÷3„çÙm¼¹ÛSÚâ|笄{– gà «+#¶^[9$0gá]Î{6½™¶K{,j@§zÅ4T~¹¶¸ÅFs0‰‚Æx= ŠR×–,j¨(¥²½2ˆÖ**,……–Š£ÈÖ)êÕlÂx3ª¯R”0À¢”ŠîG½Ñ(ôšj"(u‚Ê ë P h xï÷$¥Z5õÖ>ÆPÓü®&—Ø?P¿Ü¬B[)W¿S[84’þm "@§òZm b°4¬žzm[ô6m —jKXÍ¥%ˆg€ýÒâš`Ey•´þìv{ðte™ª‚¹¬HŸ§S·ÙœŠÝ9̉Êy?>Ÿ´Â\ ”Æ»ç3›ÞP(L…˜…4‡Í"hP+v¹P„Ä”€‘XZã ™H ‰mKö4• ÅJ©¢9¤^&i\™õkZ)®µ:Éf Ûñ|•L˜ÔXè׋ÓpôeÒ'»ÃX·MzßGƒ»Þ[«Ï¯+¿ÃÊ &K8ÀvÀTW vÔ§†ç—@r(»¹ÍrŸIH§Ý[‰ÃŠ,¶T4¨ ²#@g…­ªLÈܲQ ó_ È0V´©þP“–Z¨P¼׺Ü?Ì”œ5 ¸„äÏ(PDÔÅ?:Noʦ4sü÷cHÐ}Œ×° Û†þ¿MúÇEá°­„ º«§°-ƒõÂåÒ÷‰ïuÙ ¸.§Ù›vöÏç~6âå,mÌâ­o­álòZ&íÿm÷÷ endstream endobj 8322 0 obj << /Length 979 /Filter /FlateDecode >> stream xÚ½XÛnÛ8}÷WðQÖSÎÃË£‹º†»Þ¢±µèEa¤‰ºê4YgÛýýY¶bù&)6ú¤D&‡gÎጨÕßJ«QïuÖ{õÖ¢Š9•}U,‰ÊÛ6•ݪOÉï)q’/¿äˇ§´O>$ƒÇÇÅÝÍõ¿wßËoò”tò3E¸xxÌ—åëÑ»Ûü·òïi¾È¯Ÿòò"Àôsö®7ÌzÿôPâÑ •'YÚ‚×^ÝÜ÷>}ÖêVÞ¿SL ê¿Õ¨{e]çBÍzW=½Þ‹”-h gŠÑÕR~Ø{9=´ëbUÔ _oxúšç“éÕ|0™Ì'iu2˜¥œdóñûq6LVW+¯Ÿ¯Þ Î3¨V}²²&ÂÌNcmž5rˆhVÎ ,Ó.A>úŠ d‰ã™"ˆTàÑ!<íV„¯Þ¯æ„àÕ2W_kbˆd#bd "Z…(?ò.Ö* BΖö ¦ “l&´¢­P,ã8·”¸uLÆ‹-Õc¢¦µ7ÄZ/&rubî-|pªŽ¾KŽÏ’¿C b“ü§Ã÷Ã)sÒÍîX.Wx/°»hÍÅ,ÀŽ!p8ßÌ´¦s-ÀìClE[³vƒz™j1Ù–`ñ ÿ 0Ë8YïWY€1‚£f\]äð?†sXõÆËf½hø$%&@ô¡Yø¤9"«­§wÓ¾`Ù‹ƒÄb+,…ÉÐÖâ³Ø¤º“´‘¸º—8HÛ½x:ê^Ê,¬…òßÐ*fÑ>ìÒÚ¤üj¶º¥ù,í[k‘ÁñgE“7*š¼ì"&ÈFYw/Y%wIÏ`-^ÄÆ9&ù\ç=52×ì‚Ý€^æ‚Z<ØÖ¢9Ø:ý»¹ ˜l=þB’^Q›6˜g³?‡o.Ò INOÁ6–I¦ IÆÓý¢ˆœ#6›¢‚ÊÌV×PNïf ÁB©å$ˆñ[°4&º½IˆÃ@мLp¦-'¼á ‰í…ÕÑÄX¡•i´Æ†^'g¼Ã]z›¼±5»Ðs§|Ÿå 2Ò{H1ÝçþÃÇùð¯Ùøá¹E¡éHY@9 I¥>Ý-Ê— 5-¾ 6ˆ,½¸ynåËÙ‹Šp%«Ò¸¡ÛjägÓá³ÀÉç Šl=·ÉÁ©#û°{!u- Q Dõˆ\sY(™ÃX¦]fËB5Y³í”è=¬¢Ý—ºæZß2éšq]HûÒI'ß–_¸¼äzº»Oûœ<.Ö—^÷×7Å š$ ß$øå‚15Å kÿ°=(á endstream endobj 8332 0 obj << /Length 991 /Filter /FlateDecode >> stream xÚ½˜moâFÇßó)ö¥-•¹Ý}xÉ¥⚦b©'Ý N‰$”¤=õÛwüÄ`нÁÆÞ™ÿg~ëñJñ§bÔ{ŸôÞ}0(«¬Hî„SÂ&h‘ÌÅ—è—XQ”®þHWOÏq_9 –ËÅýíìåþ鱸ðs+ý#\<-ÓUqyôÏý<ý©8Ÿ¤‹töœ”Œ¿%{ä÷w9)°˜Ú€“NÜ>ô¾|“bÎ×? :xñ=õ Œõ|\ˆ›ÞuO–!9z Êêl´E±âo.Nö=0JÚ•°áÖ‹}exª;Ùg¿>VPäÀh%¬e_¤ê2¸à62¨íV *ó˜F;="H› ›Ý(­xïÄ*w1÷»ÒZ k(ĵ+Ï:› !Õ}år³([¡8Àú[Rü8~¯Z•*ií@ù7a ç©uÚhÎV5 Ù4õFLÃÇ`kb"x|3ónc\§ÜžTÝ xjR³ÒÓA¬)º¸H¦ÃÏŸ’ñ¯ Ýîò×äkwÑ£% ¸’ô!aÐPÀæªß¸$ðä·5R˜w+{ö…’‘)ÕÆ—Qд¯{V ½b7ȇVê€ÀJ®¶PJkζ‡ÀZð\Ç•˜¾J’}ǿ؈ÃZe†HyWW¹‰‡5äÉ;¥ý$ Xµ#—ùŠ?¸‰)J¦ã«q2\ž²øç>7‡}dÂ8 AÓ9™0N¯gaÂçXÌ©L«xñn%^3µ˜ŽDâuH9ª †’ÎI„! Öÿ@ çÁð«´ˆÉðjø{L‰ŠÜß1ThÇ)VöœTho ž… Í-y:• m¹ pª•zÍXÔ‚:‹JL9¦ \„pô‹"36 Zq‹)u3×§vNeF¯;° ›^Ç“S@­(X Ì0ñ÷XMà& ^g•Û%ß'A X¤ÀïÓ’l`”í$gy9$£¤; è9½2œôRésÀ€ÜË¡õ§Â€Î‚#Ó¨[3 µ€Ž„¡Ov™%Cê82cI¦K¾ßøÊ> sÐzÓiO ˆå{‘3÷•ô^FÍ–ŒÇKœí¡»_â>÷ßÑÅÓCܧh¹H׊û«ìjzWZðïãmy§_î¿}'³Çyq2Ÿ½d#g/ÿ-Óç 5,ùÿQÎ6ø endstream endobj 8342 0 obj << /Length 1140 /Filter /FlateDecode >> stream xÚ½XÛnÛF}×Wì# T›™½>:‘b(uTEbI 8¶R•lWNôï;KR7JIËð‹ISܳ³göÌ™¥ %Î;¯³Î«·DÁ¢Ùw^K¤ œöRÙµøœüž¢IfËo³åÝCÚE瓳ûûùÍÕå›»ÛâAo–¢J~¦À/ÎïîgËâñù¿7׳ߊûñl>»|˜ÿ€D”~ÍÞuúYçŸpÍ=ˆÖ®i6ŽÍ‘ôÁTãâæÇ‚iá6|Ïf',Põ.SòK±*îñ[ë2«Ñž­ÎµKøIÓÊJíÂûÄ5=ö¦ƒÞS=g 7Oç1¸A;Ì !éâò%÷ã¿”T2Ÿn/åÝåíuq3ô*®°yÒ¬ûœýñ†0ΰåçÆšF2;bÖþzâ‡1 endstream endobj 8352 0 obj << /Length 1077 /Filter /FlateDecode >> stream xÚ½˜ÛnÛ8†ïý¼”€šåQ$/Û4Í&»5²Ž°(Ð-Õ¦amÙ••ûö; %k%ù$ÛèMH‹š_£™ù8ŒzBÝ Þǃ·E›ˆE(ž!Å ÃQŒdðîW7,Ç·A V#hÈÅ÷£Xüt}Œ^f—Æq0ŽÜ¶¸!¯‚©F‡‹&”î¡~fI:¯ÙÝ—ä¼*˜KÁ%!“Ö.—cÊÕ¹pIF±b|oŽÃÕvæ4¸¾¨cá’6A°> .gMÿ…p ͱ’m*Æ®¤ÿzüí‹ûàÕ¦tìDâSà¢^éÁz„~¤“°ŸiñìgÏËÿwÁºùÕ}ͯ'Yeû7‘¤°óÌe£Ë'ËÅ"ɦkXÙr quÉD \¢<Ú›¢0ìT‡é«$!ÕZÖ…Rš÷£´¨Ó"H–•–!8êÃТ ˆh,5Û“À}ä1,)o;Ò—<8lÊ–#ü xU< lºÎCÜmŒ]ÜY¿üžÅW.I|;w·£ÞàÉnÞ@%>£­uÉNÊFÇÊêP˜¥ßC8¿Ø}Ìý“+žŠŒ 8Ž@ÍsUµ³{ïƒ4±c:\% ›1õfìÍ{v8ƒÜÎ Ô’ÜEÄZô`L‘K€ˆÄBÐ}¹Ú™„òÒmOz·78yÙt…no>¢Ì¸°Ñƒí­´Öt¿ ŸE“ ŶSöù"ííó¯êoUWËÝ¡1K³'ÿØj™Ù¬Øþ¯™<5¼*™K±E¡d¤/ÂU+ÊÏc‹jØËÙ—¡Ãlµ<9‘­†+âX¶¨r :‘-g-é•⎘;‚ àêè¯.ÛÏ”p*¡%tŒG®¾µ&ÁÕs² ]9»HþóO„Ãa$Lpµ„‘d°šÛ꿞»«vVZÀ_ßU`eX~€º¿õß›`2M wgRü»²ë˜ôÿ…$ä endstream endobj 8361 0 obj << /Length 1083 /Filter /FlateDecode >> stream xÚ¥˜ÛnâH†ïyо´¥¥¦úÜ}™Lb–q”•fGˆÏ §!dGûö[mˆÍÁ8\al×ßå¿ëëjÙ? Ùmë2i}ºQœyðF–ü`Â)Ò3«(/Yò¾Ew±ÐQº|N—ó׸-¬‹.‹Éx4\ç³ìÄU Œþ9Ý8™/Òevúömü’þ‘÷ÓI:|M³?„O¾´®“Ö¯§|qf ­À¢e£iëÛwd/tþ CÞ±ß뻦LG¿öµõg ógAàôÂÈp·álIvNö÷=u•# ´ù÷/õ › ;Wë7c俟n(bެ-©ëÓ¢·*ÒUT¼™Êc,1šÅ£·àšÆ¨s»– #ÀÐóe@q_õÍz»ñÍ0Vo­£ÑB.áçv¯¢.UP òhÎY¶LÙ’û‡¥t’4ãÖRƃqžq^ëªÖz~ÈÌwUiE" ÜA—K”’RjQM‚[NŸœ„”ŽªÉ—³Ðuco¼~mDÙKŽï ½?˜ÕhjÏ¢A{ΛŠÓÝ»nܦr|¬?uÏAƒ¤(œ†G7¬IÃiÆê¿E~4›¯²ƒŸ³y,uô{¶-@ =¦”EAò•£r£ž™B’¦ÊÓµ¢ÆòðfÐZœ*NÚBË#Д̌¦`ë)!VÈ#þG½\Vi õ]Ik¹)üä´ª ^õ³œwÑ(d³ >‹å$X])÷§ëûû³cö‰}ži=Å©QOÚJ2hþF¯‹t4Nèg'¡™c4žÆ‹ádNÔ±¥6LÑ\š£n "ŽH¨Å©¤ tz;ýyx3œHKhË*BSoK‰Ú&@ÑÌS7THåìÄÑI9†”¦ZrÕdh7dx¤4u2Ôå\8¯…ªpƒUSë˜Ú÷E³Y>‹)iÃÊWYÂþÒˆƒ^¿“aõ¹Ó‹Ž.îÏhJE; tZoêÝuº$v탅zNh­MQm …‹¾–$­=è7óš‡7ƒ…´lhXžÊA«mXÚ±ËÓa‘œ•$£A)^oôb RaúŒ6!“íhJ ™Z`rg…+ÛŽ³uÄÑ΃UÍfú,`hµeß/Qa©ÿ<¸•™$ýÎåcrýuÐéÞ„×¶‡¶¤ÞI–äÎèL½Ø#%ª)Ѭû W«¼ÿ<¿­Ò×}D jòT ^õqÐfMãÖãTè!íØ·«ä:¶KBSqR¥:°|³õ§½ü4A‰Þ^hµæŽö4ÞŸâü1˜$(jb•œš¶zÓ\”Sâ¶–¦ÜXV>[6¶¥m¨ö¾Áï(…·‚Íœüaÿ6vè<Ì€„¸m”~.Ÿuö}ãu<Û:ZLòïÓá(|> stream xÚÍVËŠG¼ÏWÔÔTef½`ÑÁs3YÛ‹‹<ƒØ5»+ÿÞ5Ø–z¦éDcð^šìì¨|Fe§ª¥B—¡A[P5 ­óÝB΃Šrˆ$ehŠ1¡¦éJM *F LÔ²SÅ K•šÌ„>‚uXVØ(M(h¨-áx…Ïœ©ÐtD1¨)|@Ã-ïðRÃÈB „¢üÜÂ@¸ª=…œtž@Щê˜G®Ô H¥QJ̱ÀPf€ÓaAf›VrÔèkW2ÁT.…Þ¥1q %RÔÀh¹6úȰÒð€–[a2¨gî)! d›»1e4”_EQ_öÀ½$vE "•\© ™…6Ä"¢G©¡]{¢BÒ ÕLNXbÉ–Í”º ÅRæ! R¥…•Z%D5{bSšMQDե^™/ &#‡´Àž‰CTc$êBRæËkj€ ¬)R@­QSC?Q%Æ‚’ "y°ý2kjd_¥•™Ba¾h¨–ÄHÁ\-³~LºÌúÑo%­Rª‡F5Ù*>4øCµ‘ÊÖðèä2‰¯½2*8×1™È˜‡±B¸6::£*TïüŠè-O+:™V–Iͨ ¦³ …ÒL—BgÐZc£àVlv¹YIÌhP2fTpŸÊìÚcU™/[“¾»¹Ùí_‡[\:Þé·aÿÓϿԺ¡±÷Ÿ>~|¿{õj”RL ì&°ªÄ†o“ÅŽ[· D×bAñ¶iÄš®QÊHBl³EÞîM X3H¾ Ì#’›@)9\Òm hmáúðpÿnnÂþ€[,úéÈ9 hzëÁÈÓîß<>|øñønÃþÍëCØ¿;~~ÿØ|÷çG|¸ûí¸ÛûÇûç'ŽKáùÝþíñéáÓã‡ãÓi„NÝÇ_¿ûîás¸¥¢bJµ!ïáèî§9óNÀ/Òãàßôrh¥Å^/´àkà Ï@k4^Wi|\£ñ¸Jã3à—@t2Zvñ3Šœ‡ÛÀœã%Î-qø¯Gõ”ÿјÅl)æÖ®eñþ€¿Åœ²Wq:ë9§sþvNgqrú+à§— UN/€Ó ãcXz½50åX»ˆgl—æãˆý*üB·5Å2l(­DnYÛ@Ìp+ò-ü’tÿÑX• cU®«â«â«â«â«â«â«â« àêvp\Û–ÀÕíà ¸¶,«ÛÁðÞôõ «—Æê¡±zi¬^«—Æê¥±zi¬^«—Æê¥±zi¬^ëË¢±] ±]AcóÒØ<46/ÍKcóÒØ¼46/Í»äšwÉ5ç’kÞ%×¼K®½ä%·\àt¹‚ÓÅËéâátñrz\_rÀõ%w \]rÀõ%w\_r—ÀÕ%w\_r—ÀµäÖ|‚ÃIÁÚÿ¦à_“±\ endstream endobj 8372 0 obj << /Length 1028 /Filter /FlateDecode >> stream xÚ½XÛ’â6}ç+ôhW­ºudfŠÍdv3CåekkÊÏÆn²©ü}Z؆17c ò‚%·N÷‘Ž%Øw&ØCëã õá^óÜ4lðÆ,2«W^²Áˆ}~ŽQGéâ÷t1[Æm´.êÌçãl˜¬²Ù4p—Æ(¢1PÇñlž.òÇg£ô§üþ9§É2ÍÿGä|jõ­¿Z@¡ù«·Â²á¤õõ›`#zþ‰ .½cÿ¬{M˜2Ž®cöÒúµ%Ši½àhdèm€-¨aïáó± ƒàBÚbÂÏõë—Øè¨Ku_»ýÞÓàµÿtføy÷æÅÅõÃ=Ál1k£¢Wê÷÷P‡a¶pÒíÀ îs¸î8K§+âR‹hšLÒü.™Žò›U6 ùø3ü¤E·lú+Íø>ë( ×Ì(Ãø]ê­·êA:îí;ú)¦q¸<„”¤ ë†b8rç,[¤ì­’ÂãX*`I*\báÖ ]¹×zlebK!*äÊ9‚QÜÕç¥L….©‘&¡v㡊6 ÏGjÏ…†j8 ê^¾!=×TÖ;Äw°÷òãÁ¨f™¾J`Úî¼9-°îcÜuú¿¼Ü@cÝÇ£@ÍU6'ÙdY•RXåD4Y¯ƒeEõᘖ²,“£\+Ï•ôg¨*G¤ìyj*s_Œn(*àà€ip$P»ÁBKK³<_T’úëp‹²>§då8 µQSYEA5 õ²Ê™¥5E!ì2[«ªÍ`²Y¢¯•r’[­‰ê¹wGô÷;/m]f7›U¼‹ö/(”µHG$­,7”Åš)ÂiN2MËë‚*ð(sNoÓ¾ÛLN¨©>™Š”©·õC;¨jBª G0Žk‡gñBPÆqcöƒ²\º‚²äÇVcÂZ=Ä ”QáµNLåÈÀ?6IñUR’VÐ:#Hé®÷Ø{ˆÃÖ; úŸŸnb×°î*C8›.C8«E’MÓÂŽÈr°tê560g^ S–ËMÄ%©¬ð׋ =•Ž~ç%-7N6zÍ•‚sRqJ[’rµSãÍŠL`5$€3Å…>¬‚þu¡ó$êÿM\¨-WŠë·~·w©ù3{‰,Ð.5EÂ'­Ž~dÃôZ^–5r#”ymÜM XÇ-Èk 8äè}}2ê àNDÀJ@ Ï4€`Ãâg/3€a°ö¾Q¢÷°Â·ÍÀœ}rØ"(7kéB:Ú¹º$ó˜v‰8èäG1†Çm£<í “¸­£ù8-;äí‹ð4}+FÐïtX´´‹Ã /ýü&?~ ›Q² =“Õ¿ótY‘ Qþ3&ù› endstream endobj 8381 0 obj << /Length 1038 /Filter /FlateDecode >> stream xÚ½XÛRÛH}÷WÌ£Tµt¦{îÄ–„ ÄvxI¥(bDÖ;&&°¿¿=º`[¾ÈŠ©<ÉiÎôœîÓg$)¾ )Î:o‡7§E€`ÉŠá½ ¯TN{ÐA‰áøœ¼OÉ$Ùük6Ÿ=¦Gä|rüð0ng?Š“,%™<§ÈNfÙ¼>{ße¿ûÙ$»}ÌŠ?D€é—á»NoØùÙAŽG Žxi N:1šv>‘âŽÇß *xñ_þÔThëù:ƒÎÇŽ,÷"y Ȫø´E1çkƒýM»Ž«¢©\¹áþ[ss•Z“§Ê$Ý›“Þõy·wsþá4îð2ûeáòúæ”a˜R‘æ%Í2äñ2Ôf˜œò58 ¨€‹|›äy<Š|™ŒܧZ&³È»L¦yf`^R ¢°Ú‚ÆPçØ÷Â1*Á-ñÌ‹ÇÐâål#¤T:Bæ7ÊéÞ;1ÏÄýJ®¶c鈥¸>xr……œ%¾B0¦–§“i^*bM ½g ¾9+Á¬Ð¥ ñ&t=.]‹fïp” ®†ƒºiñb)€áú­‹àqmñͳÑêv™>HI&XðÁnQÒEªdryvùáUÄtQ!¢¥‹Ù·¼µ‘Fp¼o£TU[É%ÏyØCF$ç+ð½*Ûåôv2b,±Ð³$ÝBFFa 9pÜ$ qh¤¨oVQ=Ê·WÑJ4Ø(¢ŠVn!š°Nk“ˆ–fKRíò|ˆ´WàŒÙ"¢«þùuôÛAÓuÿ¦›™äï^÷}ü?øôOIÙZ^#ö bF¼mX ÂÂó¤[Èj…þo6Š1|šn’1ÅFhžÊîdš !4ë©ÄãÌy³È{>·˜Èp -5ëÒ¼±ÅÔûkIWg.O{q¾CQÖƒµëAµT”ブ¦Õ˜\£¢Jb%·>¿Êk“šª™‘j“⃤¤œd»V[¤Ôï}üÔ¤&Æâ¼ìâFÖp È~ft•ɱŽ­ÐÎ<û™¢Lž²Ç(¢_¹5ñðàüd‡1)i«Âx-cRœp'ë.³8+r´J¶7& ´ÆÝYØ¡¢£U=šÖ§;žp5ôû…ØðÂoùÀ×?èKdhG[Ä4èõãkÉuïu-‰asÈÃi'»ço6oáNEÃÅ ªRÙÞ»4X·‡?Uˆ’O÷K4ŸÝÒ¡8ÅL:ϲXzQp`½jaQ¼4Ë=…°Ov9TÞëë!µ5(âÂt«Ùfƒ*™u±º³µ˜lBh“è5¬ø.¤YS{ÊØ|d°·IH¬É÷ùWS|IyO£Ô&å—•éí(~¦a’„6È|ãç³I…é0kÿ8eÖ endstream endobj 8390 0 obj << /Length 1079 /Filter /FlateDecode >> stream xÚµXÛr9}ç+ô8Sµîz$`¼Ž½Žã§TŠ"0$T¸-àMåï·5nƒa“}AB—£Öé>jiùN¹­}HjïÛˆ£NsM’1œi©t‚$Cò%º¹ŠÒå·t9_ÅunlÔX,&ãA=žÏBC+9‹þNæ‹tšo_ÆÃô]¨wÒIÚ_¥áPÎ)Ä_“µ›¤öO ÐF ,-©a† ¦µ/_bûG¨p–üÊFM‰ÔË éÖ>×X¾ F­g”káGk Kì8jìœÚ00Ê„É7Üù zO±VQ#*jö’»æýMÒkÆuýuÓ¼‹ºÏgöo ÈË÷m„Ûa3Rç—VûФ‡;µƒ¶É¨ã<@&žúñÀÿþô?é9V,xoüHCÇêeJéæ\S¦ˆ–šJpEÊ3[ÊAáú;Òquo›/n_ÄôxY{6—Sk Y¦dtàµS@Š:(Æn„¡Ú €ªˆ•ùyÞŧŒ[„‘Ô^æ{¸ZP‰›*Ø„q¬A]l’ÐŽ*à‡&.[|C,ÇÙËĵp´ò«SAË*>¾JPÊij>!¨ç§Ç^ë±Û»{lû(ýt’ö°>]!£çUvj¡p¾DIÍãEÚfýijýÙ0TpÍPÏF±dÑü5 ‘± °Ìƒæ$ûxîqvÆ6èP‡}›XȧW“bk¶X2èËuæ¨5Mj¸(õÏ‘)E•uEƒ*‹ ¨ÖúÐà¥"Û0 xr(2[¦³½ÙŒ‹j®¾JjÒ¢•:!µöóÃÃU™Kü¯È[¶šA?£—Éäò”å_K$"ÐçYvx`_"¨€ˆ~³jÏëavE= D2‰R;=¼ïTÉ[8^¡IÌ¢x9ÿçe1ÔdѢʂ€Íöµg¸rAf™ðEØR9ås½x5?_¥&ar#ŽÔÔòrjÄ–á…Ëb­×hwE¯ëCµñ;…ÍoNb­F²Ák<$W$±æïeô}ö²Ê¤ã»ÁP'òítÚ¹ä$pö.T…Óp:qqë(ÓüO&.n5Æü‘ÄÅÈ”+7†*fK}Rž¸ ½1qØìÒÄÅ G*õ78ðøáõ?&.O¿Bå–Kí©×¹ù|­¾NƒlÊCVq³BiùQçoÎÜŸp¦\[H†÷øÝ‘˜O¯&ï eK ìÞLSÁàr (ô>kÀbì8wž¶sñ0ÊYc¨°â_áÍ ³ú1PþVFõ›"«eá¿7[9WÉÍG`þáƒnѾxýBÇ)@~¢sÉükÄ¢š?ú‹XEëØ ßQ4ëZº¨9ŸúÞb’n„þ¥oMGù ü òžzþ%çé.T³+ÃþÚì¯/ÒÕZôÿPŠß‘ endstream endobj 8399 0 obj << /Length 1055 /Filter /FlateDecode >> stream xÚ­˜ÛrÚH†ïyй”ªBgzÎsI@vœÄ./R.¶R)Êe׈ ÄÙ×ß$ÀI!7–fþiýÝßÄÙ?Œ³ëÞ›¬÷úJ!óà0,ûÊ„S ¤gV9P^²lÆ>Eïc¡£|õ%_=­ã¾°.,—óÇéÃÏǧïÅQ ýŠ‘Ο–ùª¸}ýü8Ë_¿Çù<XçÅ?BÆŸ³w½$ëýè!ÅÃ2+hh–[6]ô>}ælF÷ß1Ò;öߦՂ)ãè:giï¯/ß…Ò+pF†ÖÙŠÜ{ë0*ràÒ–/<~£'÷±ÑÑ`Kú;e±£_“A:Æ}½M†ïcÉ£ôãíæ5vq”××W¤º‚³¾P~9Â`4È Å vJi¯(]M‘ƒ¢P¤ä¬æÑ4äàß|òñmý¼€C“…0À53Ê€B_7Úz»35··šF ±„Ëõ1= (UÐÛÜßôàœe«œ}­äê”OB’Êú ´dˆôP×µ6Ù$[_Ô0µç‘Œ×ÊðJ8«¤v ¸ª‡$,8eZG$ Qå°½VÓè[c…M\1ÁáÁÐG»¢Q]r|FÚpÞ´Âèjœ¤oï’4½œŸóRí_ ‚·ü(5”ÔLK¹-…“–M$´à¦T¤$yz¶ÍoÑ»#9dBG}í Æu@‡"QHiVÈ6^ŸaÇpªQ_©3;EEUBBÍ›Ù)ÍEšåÖÌm¤gß™ Ù)×ñ£œ«u3?É]ÜG ÇáÁß÷Y2*—¥Á‡å³ë¤ Xæ0ÙÉÝp\J²'øÂ_Qã‹“‘Â3EPšsž Nµ Z¶•¤4:½«m÷n„‘Z\¬zWO–¦vß¾œ5DnHÆv¢ƒég@³~S`µÐº‚æ4-u²J×ÚÖdNó¢«{ÜÚ®sH†è–ô‹H“4É”íI›¤aK5¸Ý &i2ü8¾]¸pQª'i³`»å+ͧϫ›YØòa½ž>Íò f¡%ZðRÖ@¤™žáx«è(à›³)A6¢™Ã¤k÷«SÙ½‡¤å‚–•›¹e7¯‡h»pè¨!m-hîÚ'ç †.(DfÐê€!a‹®˜i„pë°±©;ÜDá®75<> stream xÚ­XÛŽÛ6}÷WðQj†Ã;7^{áÝÝ: " uÍmŒúÛÛ"ß¡)¯*ß$Õû"Šy8œÃÊ‘? #w÷YçÝ@qÔi®IöL 'FZ* Ù„|M>¦\%~ý‡_/7i—›Ü¬V³éS¾.±áÖ§œ%§€gË•_Çæ»—éÄÿßG~æó œSH¿e:ý¬ó£h #§–Ô0Cžæ¯ß™`û¨p–ü³ë5'R[,gäSç·+–Á( õŒr-Bo dŽGç Œ2aŠÞ«ñcªUrs› |¦–%YjñmÜ¿O»À’ÞøóýðË8þÚß­âÕŒ¢|7@ÐrFº\¢ê¿ÜÜÞd°«Äö“QÇyÄÜNç~ØæózY±Ä/ž,ù¹ÚúIl›.bùW ̧?¦F%4Ì ÁP' ÈÑ ;Kàì˜,Î5eŠhŽ{Åfœy% š]R†F‡%…âœAÀÛµïÆrjqе'ÏÎÏ)êR½INH€Õ!ÖnW ?¥¹à”q‹0ºtI sƒ*ÎÚR­2TXÕØ&aP’WmRus *~jáhÞ“#Ñm(¾JÊX¬ŠjÌP*ùý±?ÞÂî¸VŽYöp…ûÛŸ+¿×Ûs*Y²Œµø¾Ž•ÕÚç/ÛïUé‰fÒHˆ%ÒŠ.ò"•¢øöˆY2¥fâèvòC(°@¤å”›RÈÜà©/Zèû+4É*j±¬¥ê‚ø”Å#EZ„1HC ñi‰.‚ªAµê+÷ûHµÜ.Ÿ–³XÛ®óÅfZ$ÿX_û)¦Ä/Eúy*Z‰ë¨2tž»|Š¡Y“pU@"©VÊòTÃ[Æ+6 –´ÑÚW,̱Œæ-Äæ¨5aUFÕqs)Zá¾RîÐVª›KMiŒºjz¿>\žUáX‡ž­WûÑXÕŽê«ÔÆ9f·L7PÛ—q/E½=|^{w PçqZ†)L²=›ê2ûÍðF©^8ì o’ê…»••eÚˆ\8Ç[§z Þ•µŽ¾¤¼äyhPkí8¼ö@Õ¢aª½¯KíS=Ȫ­ˆ> w(T—nüåtÈ)@±M¹ä!(XÔQï{¾JÃAþ Åÿ9š¦]-]Ò[ÎÓ®JV3¿ï¿¯C«.F¨ðg¢øÒ-þ(=ãK¾˜Ä—I¾ =óp•ÚTô….ÿ©ß endstream endobj 8417 0 obj << /Length 1039 /Filter /FlateDecode >> stream xÚµXMoÛF½ëWì‘êÉÎ~ïQ‰$)j'2-‚@-&*Ūì¶è¿ï£HI%‹¤…\¼ò’óføfÞÌ’R|R\÷Þg½w#Ã"Rtʉì›PÁÒQxÈD-²™ø’üš*›äëû|ýø”^)’þjµ˜?LŸç?ÊAž*™ü“2n\<®òu¹}ý÷|–ÿRþç‹|ú”—ÿ0)Eœ~Í>ö†Yï¯#)Xx׆¼ôâaÙûòUŠö? I:ñïæ®¥0.`]ˆ»Þ瞬žEã$)§‹»‹5.mŽO=uá•%Ií«¿·“O©³IjüMƒL²4à×dôûd8§6¹oÂßù¯Öw# í¡¥¸RžíKäþ Ÿm‘^ÙÃéPƒ“•*áÆ£àÓÊÄ1k:¦SiM!:áŒ#ñΩ~Ç)ƒv%ãžWx)b(–듚X›rs¡2W‚ë\|;ÈÍëX¾ÀÒ¨vXìÈ;…•¢µu°MúÀç‹¢Õ‘‚×€1š™>æ€.mQ$6ÖãQž‚q­ÃÑdkwkßä}ǬŠdQ°5f™y?mÍÎtKõEÒ±Ñm<·‘ÎhsåòÉ.WϨ—ýTñ8²Ì‚٪^eTŠ>´O‰$E\Û¦¸2ï(žBÓÀâ!ú½x˜¬æöâ1ŠL‰É+Ý@ôíOÞèz8µƒ*V| k׬ŠX´û±ÚÙ[K¥»eú"혀hm³v®‡Ùd´;¿M²ô söOÃÁ¤~_Q¹ã\—^ %:öÞ"0.‘‡Ëû|6Ëg¥Êæ?Êõù¿Õvk6}žn„WX²§¨uMš†•<¡LYÔšF*4²ó½.©ÕÍʬ qÌ ÈûQT™wS&°\<ÉÜ£íÆöZPèJ\ê(;dëŒJte¸ci­RXt™R"Ýr,¡]Ô9néÎÚP4±[Ò/©¶ '4kôº”ÉíÍðÂÑvóÄv=dÕ฀âÔÒa¦Ø³¼0êXùf1ì Q2îGKiÞM À2¸]Eä×î΋Ñb.´—‚µ8€X2†ÏQvnBY¤<Ô#AßAAv˜P8J{Šl,ýŠQŰ>b´©ô·Ö!BÝ2|Qå+ëÉxÕ\ú·w£ÉàÃðÂñs¥ÝÈB98ó¦ÉbÊþÈÞn@ÏQ­šL‹3ß]DÛ]ê+óŽbb4\`9ÄÞ~äC'ÅÛ ^ZäáÜë’ÂYÈԣ骧HÒòa0¡YO©…µ3uRõ´µäà³K–ÀŠ7 v×ú‹Å郠"h·|zGx¹Â`Mþ\ßÛòƒÉÓ|™^Ùdµ¨> ,§Åט¢Â :’ øå6ú@@àí*õȧ endstream endobj 8427 0 obj << /Length 999 /Filter /FlateDecode >> stream xÚ½˜ßsÚ8Çßù+ôhÏU»úýH’K›K(¸sN†‚Ó2C€ƒô:ýïo… Ôü6äîÅ–eé«Õî~¼¶ûÆ»n¼Ëo¯0ϽAòGf‘Yå¸ò’eCö9ù¢Nòù×|>]¤M´.iÍfãÑ ÿ<šNbÇež¢HþIާ³|»¯Œ†ù›Øîæã¼¿ÈãpDé—ì}£5þn™"Ä¥·Â²ÁSãóÁ†Ôÿž .½c?—£ž˜2ŽÎcÖk|lˆb‚Y/8F`sº±ÓÙ=´a\H[l¸ûN?tR£“Öe*é˜:‘d©£ÖÃ}ØhÖy¸H›:ù£u{Û¾K› ’ëör7ksŠóÛ+߬$X¢_¨uÙÊH8ˆFÁZMé¶4÷ˆQ³{E¦¡‰ÑFÄÖ"¡¢ Åï:IÂ!3Êp~ÛùÖÛµóÁFO®@KÃÂézŸ¢ä UP\ö³‘;gÙÌÀqŠi)WYsØ÷šk_³•$…ÓÓ½u.Äéõ@#-šép–vC]ª:¤ÑC†2L#·²Z^BÍð]£ê’f©à -ÛD›:JÚʽ@OF„m÷Cí·Ùe½xŸÅšr’[­«³ÖmüÔúk fö7Še§ðUù½el™*Š”@šÝ­ié E,êQøœÞ9·f Ó”§L EêµD®´¬èHÆqí°‚ï_ JÇÔÜ2©v£@8([D•ùx‹Žôte¿­^ÅÌà¬â³x’T Èã<ÅîÐ{ñpßÉnîïzgÖ¬Nëe¥jëÏ^óÃÍm;ÒÓŸ cƒz{WŸ‚µ‡i’¬2äUh’t+üù4¡§\Ñê\šÐk®Tpüqš¶L:‘¦’E`lEšÐ‡Çž?'tž[õ¿Ñ„Úre±M¯V¡B\ϯP£É`üc˜GŽþ Ÿ¾£ÉpLý>˜ñF'õ‚6 i/WIó*€å6î|ÀÀ:nAž ½ rô¾B ޶eÒ‰€•,tž„öÀÂTí}ï(…/(2ßTþ7²ÿÅÞƒ¡ éý—rÚoßû3Bë9 ¿zâOÃÓ¦Q>¹˜>…o°Ù8_ ˆ÷ç¡7,fÐq2(î4‹ßD›Øˆå†ÃþsÙþ5Ë%öÈÝÿy-ó endstream endobj 8369 0 obj << /Type /ObjStm /N 100 /First 974 /Length 1097 /Filter /FlateDecode >> stream xÚ͘Áj$7†ïóz‚©T’ªÀì!Y| ,Î’˜=,›!;Ø^ؼ}þ_Ѭhá=ÄàCuéïªRõ§ê[®bÈ%¦ )X®94ãu )9Rí »¤Q'å –é©!‹ÒÓ–ð´ ±b©xPm0Z E ªfˆ%…jJ†† xJh¨c× í³rÈ%çàÂÈ­GxZH1]KYu‹°<Â2Xɸj’J-ØiʪP~â3kKY;jJª]ç°¬ë°Z„)¸£Tæ@¨T[SPA-ìÑò¾ÜÛ2»c°,sÕ‘×ű‹J«±>ˆ%Fîƒ}ÊJ¸-3‘¤Üu «±Kh HbÇRØ'4CÄÙ(¯Arîû0XìdvXŠÛLc RzKA*£h¤¥Ì†]Je×4¢ª–»´Öu|܉ÙXŸ=À‡ª eÀ‡ X)ZH$ŒR‘7KAÍÊ& šBåÌl —`åîÐÔu N $•Ô¯”»M$'÷K#ƒÒèƒÕJ_ÅcDõXÄCõØPG×…>è¼÷J"î¡2­ÂlÀ;`Ь80™9EMÍ  ²’aUv›V49Y³÷Uè”Í©8GZ2ëéZ÷ô´&Vʼµô3EË©ÃCÁ£túPA3æ@áj’WW‡ãÛp‹ãq¨oÂñ—_ xÚ­´Íp°î¾|þüáðæÍD(ø‹ ¢·ˆ&î kÒͰ¯]a±ºˆÙÆ´U[¢E[»Bœ’­ ãû·‚¶+”V6ž‹}¡¶MËðT®ïïžÂÕU8^+'2ÆA¿åš{̨ç+‚†™òï®ž×æøîáþÓϧ§pŽïÞ^‡ãûÓ×§ð_†÷ÿuÂÂÇ?N‡ãÈvº{zä¼â{àæp¼9=Þyøtz|ž¢Ý÷Óé÷??þpÿ5ÜÒÁ©Ñ\> ÑÇÜÍ@/ól³Àn Á3á ÁQ4Ep΄sGáÁA8GpÎ…SáÁQøª´ô ýåÚê´•)h«SÐV§ ­NA[‚¶:mu Úê´Õ)h¯y z¼DÐì;ôU}A_EÐWôU}A_EÐWôUÏ…øÐÝ´-4_ÎÛë!Ð/ ħ⋠t[$ðL8#pM „sáœÀQ8%pÎ „sGá”ÀA8'p¾"5ÚüõRùÛo‰Àsá„À ÑŒÀQX`y]VÛ\u_ˆŸf`za#š±ã¶¯ËE€ô‚Ntk² ” ¬²/SÚÊXâÿ`j—¦² *»0ÕEÏ„3GÑÀA8£p:/„³8 §#pâ߯ÿ­ì ¨Ö´/œ~^_Ów Ê7”ï@PV”eAYEPV”UeÁA8} _Ç·ð? ÚJ endstream endobj 8437 0 obj << /Length 902 /Filter /FlateDecode >> stream xÚ½XÛRÛ0}ÏWèÑž)‹vµº=¦¥0@§…‡Î0 ·Ã4zùý®â\° ±¤}‰Å::>«£#[«¯J«£ÞëaoÿQEˆŽœ~QÈDå9G£†7ê2;ÍÉfÅäs1¹Ì÷ȇ¬ÿð0¾½¾úy{ÿ½ì8(rÒÙïåÂñýC1)»~ÝÞ¯Êïƒb\\=å"ÀüÓð¤÷vØûÑCá£*O25ƒ×^]ßõ.?iu#ý'Jƒ‰Aý™^u§ØiÇê¢wÞÓ³{Ñ€r È™tµC5‘?žuVÝuš5hãg7èÚfY‘Ò› 3‰¬´ÞþÇP")—ÓŽzç]Ci]I7 %êJhý|9ì(”ЦgY³‹PJ)žìÁ†¦gAyrk£tc(Õ8mJJÈmC Y6;Ù 7 %d©«1]Jý +=þˆÃ\ëW«Ïz"ÎV©ùžtömòÙ–oJoïò=›=ŒgoNî®®Ók˜lL ÁŸŽ&¶‡ˆjóùÉø endstream endobj 8446 0 obj << /Length 1120 /Filter /FlateDecode >> stream xÚ¥˜ÛrâF†ïyй”ª–ñtÏù’µ±“7q€­¤j³Ew©ÂÀÊ8©}ûô0â$’Â…i~õt÷7݃`_™`­÷ƒÖͽæ¹7hØà™YdV9®¼dƒ ûœü’¢N²üï,_¼¦m´.é,—³éx´š.æqà.KQ$ÿ¤@ÎË,ÃoÓIö.~ïe³lôšÅ€#rH¿ >´ºƒÖ÷)‚A|µâVX6~i}þ"Ø„Æ?0Á¥wìßõS/LG×ë·~o‰b‚Y/8ž6Àrºq4Ø;·`\H[,¸÷^ŸR£“Î]*é3u"¤Ž¾ ŸþöÃZ;©×4–°µ¡¸ÞÜ“âN^°6*z»ÞWïÜuQ­óxZe§&]IMpÕz÷·äR-4|ìQTÀ-­Ö(Ãø²[­·[·:®aϵô–`C¸<œ””¤ ’ëÅtäÎY–gìù <çµLÐ’”Ömµ¸–@Wîµ.‹­#HîÜ9•å–Vg¤â®ÒѶxKjäÞª#s,—N×¶FjÏ…†CkdÕ»·nEÏ5%lÉ­À½ûôl0ªYœ¯BG{Ã7Õèôº÷Ý^À¹Ž™‹2õ ™ä£çUÄ&ÏžƒëK'ùh‡_„Mï5lh«ìåVÒi)7‰rÖÝÒQNÕÀj#Iôtoÿbz3¬d ´À¢v‡•áÖ`¬+çÈ$J.”U±¨æªd͹:0u%XÇÒêBÙ±U`íÍ(›Eú*°”“Üj] V_}þ©…~êw{Mè2Ç­Öª@ ¢æ¸ j5ýKHE½BÁZæ‹Õb¼(0[å£ùë´è#Ö4~OA$oY$ïwôG®¡ Hs16z·»B‘Âëô.9ŠÙͨ#©7¡`½•"ˆ<¨úСY/D Ú¦Ö ÑòŒäŠŠtÉ(´Ü)SŸ#ŸêßÅÁ·å„jàä€Ô¡ dör“Oç÷9͵¯QÒ¶’‚N{ûnœÞ ÁбQºƒutÂÚJ4‘i› ¨8Ð.N½¯  Z¥dUcé\§í¡Q5ŠÚƽ6l™¶ìÞ* ÷fkïÅûH,¿!Xûç’Ó&íEPð‰ÊP GTÞ~-ÓÐ…Ç#ëÃÓ¶Q>¹]¼F—³ló@¼Ÿ‡Q:QÅô9wÚÅ/GO?Ç/£ù$~!,“£Õ%u}û\’Óÿ½ü endstream endobj 8455 0 obj << /Length 1005 /Filter /FlateDecode >> stream xÚ½XÛrÛ8 }÷WðQši¼?:“ÙvºÍÚzët2Ž­´iíÆk»»³¿ .V$_$žXE‚8$ξ0ÎnWÉàòF æÁ4,ydè ôÌ*ÊK–ÌÙ§è}Œ:J×éúy_ uÑpµZ<ͦۧçùÀu#þ‰M\<¯Òu>|ûóiž¾ÉÿÓE:ݤùDñçäÝ`” þò‡3Á,ÒÒ ,·l¶|úÌÙœÆß1Ò;öo6kÉ”qt]°Éà¯/öÂAÐ8 ‘a¶lMöLJvV¸´Å†ÇWúþ.6:^Ç’~cÇ£$vôï~6:üp?]ÿ1½M²=ìœ(®—7YásvŠ–×/á‡×ÄàÚ *Hé!>K\Ú:º•}Ä5¹ûøçdôKÄuê q ‰ºL‡_¢Jàæ|éhNaâê\éh.i/¢ ÑíÒiøôJéÔ\²£t”gœv‚)÷¿M:Êhpˆý¥s}ÄcNÇôX‹|ЍÌ×ÓÇm^xf¡Aø:],Ò_²¦"Þün6áá6]¾É®æÓm:?¤5N”0ű̟£‘°9¹íjË©Å/Ü.+ ëž‚#ÊYnu8S;%”ê.8ʵ°é9å»ç”äZ áU_ÉYjÌÖ’ªUN® G£m’Û*ºÂXW¾_¬ÏÒÔDŽë »Q!¼³kÕhr ¤c•J7Óe!¨Õúù[:Û¾ª ¤ö[jÃÐ "ë4å(I­ò*!§ª*T˜÷Óa¡&#M…ÍUZå$5™¦)üT„Îjm[ÂqBXFû=o,Pºw–6TMÝÛª«’UMŒXÙdµMX;k Îê~a>KYˆÔ¶rÓAZùøû³•uw £¼6xtÌQ*YÕ°“Ì8jB\”t¨Èê ¦0ï)¢/`òåEþ à¶Gþ+ VPÏcŽUÿŠ´é¯6 ¾`P¹éžýTuáÛËJÉ)‰†Õä´5ýKëPM¯ ï…7Ò éüÍâp§‡ DqFÓañÙèûúAçŸL6OËøBG«Eñ e9…ï1á„WZЃ„Ÿ¿A*[KwâíôëÍV endstream endobj 8464 0 obj << /Length 1111 /Filter /FlateDecode >> stream xÚ­X]sÚ8}çWèÑžYnuõ­G ¡Ùi(¸ít:† ΖY ,¤Ûé¿ß+l ˜€í’,[Òññ=÷èJpö7ãìºñ6i¼é*d¼†%Ì f•å%K&ìkt ¥«¿ÒÕã:n ë¢Ör9›ÞŸ¦‹ìA;þ‹‘Ηé*{|ýc:IÿÈÚƒt–Ž×ivƒ `ü-y×è$HT8ÃìÕ ,·ì~Þøú³ =Ç8HïØÏͨ9SÆÑuƆ ž$ö„‘a´A¶¢Ž£‡ƒSŒ¸´ùÞêQ?6:jµcI¿±ãQ;jöMv?êµû£»¬_òècr#6´c”_ßt ÿ2ΚBýü]­v+ɱsÜÖI¼=®t\^ˆ w°mBáÖ<º?eÞ¤Ÿ5æé}ëûx1]ÏáXAñÚ3£ (ôE5¬·;5ГšNì!b¸\¿)¥ ›Ž|ºç,[¥ìá@ÕÓX"`IšlÝËHpR3DðZÁ6ÂSÜ÷1h@JC0 \ EXÄMZbàu‘˜°à”©ÌKZjSÖðB]úö]ˆ…M9_1‚ã·¿<ª§ùEîÓÞPÔL-÷e#†ÃÛΗױ]ÿ Ø%žë‡¥q¼^ÿ®iX*~Uõ ÁÓRnsé¤VƒöXÁƒ9$Iì©o› ùôšt€\3®Òî°¨t RÕ=H² ¥’VÈjòœ1 1pLª¶ÿ¨: {È µ,÷_^ZW”ÀbxKý·ŸÍ…¬§÷EþSN‚ÕºÜþŸ¤I·3´þõÞwCßÕ± 9ÖxXÀ¼ûb†û9š.&üÏ`Éuæ7Á9ÏZ«ô!tn¶):ZgëýZð2W|Ð½ÊÆ'øKþ´J+¦¸ØèvN/²²JÌ i·÷u-Ÿ^ÓŸ4<`9 üY1¨]#‰ ½[zFùÊÚ«‘4yцÐ`uZÒ ÐÎÒÊU:ëÐ<ÀNƒT¶àR‡ng+ðÊ×Sü"‡JMáqåMB‘¹’ .¬ŠÉ”íõ ´è-í $“ÜPmÑç‚#Èeж€evØCÒúÄý.Uòéµì°°m]œÞo?)á´Äêv *‚„^ƒRX·3&àŽL`ŽèPð$¯NG¢¢B OÓiõ«°ÙZ›PºÄ»Ù΃Uõ„¿ÈBœå¶ø8쌆ýÎU¯Ûë´G·ŸÞÇMäW­#ÔKÊÖ®Ø(¤Ç§Odèå6a^ëD†¤º6îUNdhX|Vm<-ò¦ö‰Œv„ ¼¯ósåÆoªÀ¬v½ÑTäå!±*õ&± ‹¢ýÍY˜­}½SøX8g)2Uå¿V^Þ*ÒÎsÇ å(e¹#Ÿ]}/c=Åù®ÊºÈ@ܤÊ]=Î㦎–³t; ë_…§´ËfÐïâ>ïiæÿ2õ{Yc¼˜dI8Séhüôk™®¼FAÿ;«¶ endstream endobj 8473 0 obj << /Length 1072 /Filter /FlateDecode >> stream xÚ­X[sÓ<}ϯУ=C„Vw=–’v ¥-ixb&¤¦ãÁ¹¾ïç³²¸ŽÛjûdù¢³«³{´+3òH¹¼› Þ^H Ž:Í5™ü$ÜJÊ…#FZ* “ò5ús%ëÉz¹‰‡ÜØèlµÊÒÙt›.Ń÷IÌYô7ü0[®’uñøòOú¼)Æã$K¦›¤¸Ê9…øÛäÃ`4üúÃÃÑ´¤†2›¾~cäŸ Œ gÉùWs"µÅkF\ £€K`”ká¿Ö@Öø¢ñp|lÕÞ*0Ê„)<~§¾ß¯nâ!°èüê.Ö*:»þ~«èöSq7á­`ÑÙýèÂ/ûöú}¾œ½?åõí¢W¦r‰ž¨KhÄ@ôÙ£žB¬…=@fÔq^ ÏëaºØ$‹MºMÿÆ#Óä›ã²…rDKM%¸CÒ3{ÒÁaÐ,¯ˆG[Þ¹< )(é!óåtN­5dŸµàÆâKàdc÷X³Ôi@R‡`y|‘à'Y š ¡FRD}ͯs•"”nºF…U½=ŽQ)DÝ3Ùe{O1wTajP ÔBÃöñÙ eXÌ_$2å4µ·‘n&£1~v?z=yu`öØ—»¿*MËë:™fÅhå÷?¥‹YºšfzDxL!mŽ(!vés*œ5Rt o‰quø®ÌŠÝô0á!óX`QÄfŸa˜ôF™á¦Ñ%ô‹  ´IÓÞê†s¡ÒSTcú×|ãÒÛ‘Œ[ŠäpHr—ôžÌf\„EýEÒ“V`äTô®.‹nq<] Q n 6B·£vh ôôq±\'•úæÅp¶œ¯–‹d±mêœÃ-ȉ0€%¡-À)g²Sw{H ªUUJ”Óƒt籌sD2‰VÕή(‡ÝažY£Æ¢Rx`(Z”ç°L¡‡î…)O2†„ɺwÐe{O3ÃÓ²Ü!¼j² û‹„' £Dð¾L.ìëU»“hýêÜ…µ=ZÖêÕÍ í‘B‡XH¸`z—1'› S0ÙYçvˆ¸£1Wå`1;¬Ì!2ʱͱªjU• ÂÈþjã:_G•J =ƒÑ¢2#0YUíÀúfpœ/î‰W¶Kr¹óÛcƒÜ®òVNÆúldX¨_¤1® •†·k¬T×ýs[Êãí®b¿bvî…V³MºxÌ’aUÈò§8ÈOÖj¯ÄMÒTf–´ô›àÄ.§^«ßÌ¥í«ô›`,5 žÐ+úM°¸‡cí±65º<\ã†ZÙß3T.VQ÷Œý/ûö›`üþižÙoúÙʹ ¨7Àüá{ÿš9Þˆr PJOå4jé¢_ëªø3´I±‰ÃÏÊ?EóéÌÿvBšˆT€; ?½ºt5µ!oÿÌ@e endstream endobj 8483 0 obj << /Length 1088 /Filter /FlateDecode >> stream xÚ½X]sÚ8}çWèmí™EÕÕ·iC2t³Ù”ЇN§ÃxÁi™!Àº›ý÷{ ÁVÈì 6–utuÏ=:’ùN¹ê¼uÞ]J Ž:Í5ÝÉ‘–J'ÈhJ¾&¿¥\%yñg^,×i—›ôV«ùl’mfËExp‘§œ%§€/Η«¼¯~Φù¯á~˜Ïól‡?@9§~}ìôG¿:€¡0ahI 3dòÐùú‘)>ÿHÎ’žÞz R[¼ÎÉ]çS‡•Ó`0zF¹þm ¤À†g‡/Me”¾WãÛáà&íK> nS­’Þõ8\‡wýñà*´ý1ì‡ýÞõïOSÙÅR^ß]"r5 #].1 Uðà[àÓ˜¶°5lFç{ð}±,|®KŠ<›?„ÛÙ}¸®Š|/6ô9൘j-5•àê,gv,pà”3Y1Ãûàüåê(¤  ¤‡ô ÛîœZkH‘“û6_Æ2Î-°‚ŒÝbÅšQ†P§Tì‰pÌz•-εF#Œ¤6’ƒÈr'0 ¡t=8n¨•ºulÂ1*…8Œ=Ú¦ÑwiæŽ*¬÷ZšZx6úñÞ eïg)O9#ë¶Ê+u7¾è_¾­ònš0Û)ï—DÉ’_R©’MP[6†›i~ï—Òìç|³'Í£*4”[A”ÛJz™ ƒåÒF…%$ì°mW¡{¤ m^¯BœV†â@ QÜœR!¢a‘Õ‚ÃL2¡B‹ª{{Ö,Ã2Ï€ (‡zžeXõf\Ä– ¥HžŠ•a´õiš_-?¸}¿óPI±,oß×M&Èq3 ”#‘AèS,€ÃµÞòFùí ‘X«ve±í%?Å=“(eµÃÒ‚Z¡ÚËC8;É,U–·æå„ô F€Õ‹5@ƒ÷¾"÷ãBé5¾K±_Vl=à «:{*xåg OF5ˆ¶Âö?}¼õ®³´ùE¨o±Ü4ïEÃb(˜Þ–Ó[¹ À1̽‰ r¬«d傘ï‚Ü)*%ıtÊ1iêÑEoFÑ6¥= Ž=ò¶.È_AÝ+]c*üM+„3ü´?ßTj¼ÜÝ^?µ÷RÇ’/ç;!¢WȽ/gXá‘h¾žd«òX¸^å“Y6&þäþ#+²É&/ÖÇ,‘¤™Ã‚(ËéåõQS… Z£%î XöìÐ=ÎK{,c©QY¢£LëKÄeó8xÌlMÐ)OôÓ©+CŒGY{{”–¸M±ñ+¨©§¸É÷z+ç¢8æOz%ØúÃÎñ]*§¥>±n±x™µ(ÎÙ*õUî¿S…/Lš¦]-]òa‰Æ£’Õ<ß¾Ú ÿÏc¡þ.&eK·üÆu;7Ùbn¦ÙÆ¿™mþ]åëabÒÿ°È4é endstream endobj 8492 0 obj << /Length 1172 /Filter /FlateDecode >> stream xÚ­XÛ’Ú8}ç+ôhWí(jÝõH66Ù$°Àf*•MQx&Ôr[ ™Éß§…l›‹í™}_û¨Õ§ºeFî#ÖËaëÅk ÄQ§¹&Ã[­¤\8b¤¥Ò 2œÏÑŸ1WQºþš®—›øŠµW«Ùtœl§ËE¸ñ*9‹~Ä€/Ζ«tnw¾O'éo἟ÎÒd“†  œSˆ¿ ß¶®‡­ÿZ€þ0ÄpZRà Ï[Ÿ¿02Áûo £ÂYr¿{kN¤¶xœ‘Aë¯ËæÂ(àåZø·55>8ºÙ?5k?*0Ê„É&Ü©F½þ›ñ°è÷7½X«¨ýnô÷‡pÖ\³î¨Ý~÷~7‘½'ÙñÅkÄ= ÂÈ—èƒ*ð:À^B< [BfÔq»ó飬X´N“Ù<œ&³{Ïb ýôgz}ÎÌ-5•àÊgöpÔHq Ç÷ÞùCç$¤  ¤‡ôrsN­5d’Û•籘ǘ>ÆæX`0g&Ô)UÛ±A”ãø"00’ÚFtü*DN·Kµ’kÜP+ë{&¬¢œ‰¢gìW¾2wTaª—‚ ÔÂÑè§­AËf¬?KtÊij‘¹Ú¢üÑíÿ?±‡{†Ò¦·Ù1{4Ý„ãö[NfËq2{dvJˆÀ©3’(!òt:G XM™âÕBÌ!‘e‡ÏrñdæÍ„ˆXÖcEQ›=–²T3Õ@ˆ_Ä4à˜U\Ô¥ê’ Q}¶ìVSC…2E¯ØTŠ00àâÉ¡à*>²f\4cüY"”VP£JBùØDdºŽm…¢ `ô|〚ù±+VÛL1I¡ÝÀót³IîvmÉ)õpA¥PD"2}1–×¾U,GDv¬:p¬›i¡„‡bu¨r(å°#²õ¥ƒ*–€ä1K•å' ¸ª–#m²ìE*ÔwÂb“ˆéTp⦘ÿý»þªFóÍÝöç*Åkààÿ+=ËÍ„Wr1ÎUÚÛzBx#ÚŸ¥ aÕP\¿buß÷†£!V3}êa+q}3 •l0ð}òýWO/ga€=6âޜëWÏzëå|••­ÛX²h¹‹Ô÷÷áb•l6÷±Pøtîx¾'ß3é.îν6öÓþ–,‚p÷éPZE1Öʹ˜¥æY_íëT¾:æöI•™7¬|˜ˆÅÑØ*yHPA­hRùPi¸2q§v ªËê¥Ò‡`¼JŽ5®}xŽ™Wð«Nš…˜;¿â…¸²öeÖÖawÙŒòg —+C¥áOî¨í³»c·ÚÆ®õÉó4á£vçjÝRú41ûºŠÿÓÅ‰Ê NR›op"ϲ³[Üàk¬1Uê<@2Ü»vN™y#uz,ÆR↸­S_ ×s‰jÆ2ÉkHÖb~+«Ëî5Õ(ÎÆG¦à{U£ïmüÊjÊ®Ðèckå\#æÀüÖ÷ìºöGžÓ+§™xq9¥ñ•–.ò}GøÆ´™âŽLE«YöÍižŒý, ‘ ¨Ø­#;kž7&™§·_Î?*, endstream endobj 8501 0 obj << /Length 1279 /Filter /FlateDecode >> stream xÚ­XÉrÛF½ó+æf *Ͼ©Åò[ ÅÈ•r\,F„"UQ"CR¶ò÷yƒ…À€˜ Ðoz^Ïëî#F.:'ÃÎÛwŠO½† o‰Ä*G•—d8!ߢO±ÐQ²ø+YÌ–qWXõæóéýÍxu?{ÌÎ’X°èGÌñât6OÙðÅÓý$ù%»$Ód¼L²?œ Ayü}ø±s>ìüÓáp…žM­¨e–Üsr9ò©àrkõ¹1fB¶ŠõQúTNR«KBºþ]b›¶Q¢)\¾Fz|-½Õìf6-4"C²\+íñéíHŒ»]%Í Öh^¹4‡h´† T’ZɈŒÓë¨æÖí$( ˜‚út¥=:"×\1VRg9PÕNìäý€DP’\Ån©tº¹D$î}Ù]+‚J†|æ*LÖécm(­{”>$Ê¡á/rѯŸG'ƒ^&“Ó¸«£÷£ìÒ¼¶|mPO¶¨¸V£` ^®ZQcÔ‰‘S£6u"³nY'°E$óÔºM@RFÎk¾ëÑ,¡­$’£ìXYOÜ hMë«ÕW ëKUÔ„u½tèM˜»â¹¦"$ëô9Íž—€Âs^¼ð¦¾Èä‘ò˜å•ÈÔ™ÂEÚÊVå( «)2N)j§×±eQÑõNÂMï,dûbìú|põz9^÷RÜÞYïÖnEq3¬J»[s4r(ØZÔKj iÒ3D¸Ü¼¦€åWTq8B›äÃÜ¡]jÈ^½¬*Ná(¨ÑŠ5o¾2Y•|bÏŒ1Q+‚áÀ΋RÎp6^X«šÒVÈwx·tBÚÇÕ§ýQ‡Ë/¯íÊÖ1­Û# ¬B{4ø/?HÇéØ5QD> mZ‘ܼ¥"ÀtÀâËöE`©6Š08Ô lݽC’pT0Uõªµ$áe§RIÔ2((Fg´ªR\+‰µÐ¦UÌ·À§¬Ã4þº·û´"(çy¿)´À‰€9‡ìn> stream xÚ͘ÁŠ7†ïóz‚©ª$•`ñ!1{ LJ$Æã !`vƒ½çíóÿ=$x4.ºÙ\沫)}-UUÒÀh«žrrSMVð_jráç–Š¯ž¤{ÒÖ$iŒŒ¤µ1‚?£#b9‘ÓÖ1èã€HIU2#–jãÂ&©eaÄS3eDSsã‚5uîkÆÍשž†ÀÈe4æcžÆDX6ff#'5r*EˆUŽš2f©Hæòµ`„¥sŒ°b’ŠÊš;8¬ÊFÖ²Gu¥6KÚ‘qi™¹ÕŽŠ@ ³Í™&zWº+Ø··•l\c ë¹q†Ywg O a‡Ð”2:먚$ö‰KÉì1–ÉO ,c~h·ˆWÆ0Ra­cÔÈiNbyåðÆÐœb†Ñàm$©ZÈa¶vö ›K+¬–VÙ+LH¯ë,žu´S;Š̯#«!¬ÃÁh¬££Ô\ÈÎuåPìբ܃•Î^¡k*…½ê0I*ëèHMV—ðÆUgá†ÚPÔAõª2?–_ wÊ× 3uŽÐDí=Ÿ_> stream xÚÝY[oÛÆ~÷¯ zYDÛ½òrPp;pìÚ‰¬ (Ò $*fC‘ )×H‹þ÷Îì…i¹’¬¦Ç&wwvfvv曊z<ê½:ú~tôÍ™d^B’‡ÞhæñX./’1‘‰ðFSï½pågõ8««&ð(ö‹"Ÿ¤Ë¼*ÍÄË,àÔÿ-`@XT‹¬6Ó¯îóiö¼³"K›Ì ᜰà—Ñë£ÓÑѧ#úPyÑ’D4ò&ó£÷¿Po ó¯=JD{šjîÉ0†gáݽ=¢ö,”08%<H2¯†…G“ÃM§F©Œ*"{àá÷êvxzv:_ÂËñåZÕV–}~s;Wl¨7नý¸¬¸‰¸Ç’„sÃí¤*4ï2-—`CEýY ©_ÕfPgi1w¯³@à…áЯӢ! —¬mÊH–ô­%Qkm&XY”B•ññj#KA˜ÈR/ØíœÄqäÕ™7ëÜÚÓ¼(òà)QÜòbŒ(ÁàI¥úÌôÅ‚õ×ÜY*¨6’Ä[北KÇZB÷¨¤¯øpÈÔÎÚ¶aW›¯¾Ú&¼µ+OˆGîÙ•‘˜=¾y7 å~}PH©$$qvŒ~óæúêåéðöÍÅùÕùèöì20ꣿ¾º¹!ˆ\_œ^ݾ»A¢ó«Û“@ù×ï®F·—€5$øñù±øHü1JíI4â®< XGwyc‚ñg*TúÁ¼çåA3³KË»ÔFrZ:‚Ie£6›Ø5Pɼ< §vosœMí~K‹«1 «r’Yò¼}]ÞÙ—¢C»Ìç}‚}uÙ€2LD x–›§œOi$ÄV”iY‚?'°f£Ámß eE^,žQÖQÄ®qÍ𕉸8ÔãžF‰>&}}•KD;«+9œZ†]u¦Š²` à^¿ýÖ<)̱m*µ×ÁÛ8ë_ÇpZßM¹ØÏ?'Ö)u8A<(’ÈhˆD?íLáÞnÒ´¨ŸžLìYÀ¤Ccýs^~Ø«ò¢° ’Þ7}`YVÑ–Y醪 N´ü—MVÌþS0dÓS$¸a¬Ø?‚)’JˆJu(¦HóCe;¦ôô}&¦tÔÝ€)lL‘²FüLH‘¯ÿ‹"" å 8 RL™srqúòËV9—OËø"%Nüu-£¦/ÞØ"ç³nw8üo Û ¦¨Zº¸òî<äË;‡5›púÐ$JäM6¸ZföYfö¥6ÏyUgë$JóØ`•'A+P&×jàúϬV<ô§»D«áÚ8+*¼ç‡ T>è/¤4&GÚEÕ4ùؔü}ê \ñÒ ;óL§ÓÌ2) AÖ¸>éÄÆàqéœÂÄJ6éª}¯\G?Ï‹´F'²ÚÀ¿A™ÎÝ7“‹3<-¾¶7Õô¤KŒo.ð’OnþØ™8~snÅÜU÷…åh.^ÆvÛ4[dåÔ ´‘«1NÉÄë?-ÒmZjxvð ) ˨ò×i×ûä!Š#´Hj¨zà @­ù2 ¢”¢re¤g ¿hÉ(´ Œ)øÚ´k#Mqz{;)ˆT!@~ËQIK¶’ØNM€e;(œÀv†®ØÑ•¸ æ ¦ŽÞ>¨>Ùäÿþ|3ï­‡)[™”­ ¥8‡0ÿÍÿ}Ýc—O¹5—$ǵ½”]iíå&Œ½ÜÚÁb}ÈI¨ÂxÔ3+1XÜhë¬ÛÍ`·¡Av5ÅsÂè©ììL9B¡­@ÅÍ—Ç…TØE…¡4ˆô‡ëë÷OëÑ™YïÙÜßAh—QöæF‰Ä+vÿ4mgh½÷¦ ìÔ( ´YÖ˜‘È]ØøßuËœ/£çÿž-Ä2˜˜iþMK–÷ó1¤­g[&^ìïH½,OˆÉ™ƒMö'.m¨C¡Z§Ñz©ÛJ¬æ¨ïªÐGÍâ†jfxwƒ)wÔM„¶²êü&çJ±îM÷ìÐäáοunþ’É c¶'‰€ª.”‰ÿ±+óS+T Ðù‹Âþô:O'ø;.ZQ: ‡z7W¢¯ì_¯5Ì‚ endstream endobj 8522 0 obj << /Length 1788 /Filter /FlateDecode >> stream xÚÝYmoÛ6þî_Aô“ŒÅ,ß)À4uƒ´]’&.0 -×V£ŽäÊJÓlØßQ$eY±c+M lù‰oÏ÷ïd‚.AûƒÎóW‚"ƒb .fH‹ ÃÑ`ŒÎ¢7]&£$ÿ”äÙ¼Ûc:Žvg³éd4,&Yê:^&]F¢¯] §Ù,É]÷þÍdœì¸÷“dš ç‰kP̦݃×þ ó¥CA‚¨-°&®;g CÿkD071º-g]#¡bxNÑiç]‡ømL™5Ÿù%Z7t²_ÉU1V”#¥(ÌŠF_Ì3Ö$‚¸Yæèq§æXJYvO¡%1£Ô*(´òsÁY­ƒ£Q­%)ÖþÊåU'ÇB*mˆRøi ‰U× «Æ4¬zÈŽ,Ä Áa6 óýƒ”;ýï÷wÞ!p#­ÙÇÂ!œÃ¹ÿmÝa Ê3o.lŽ•ö’~¤²Wèpö -I½¡}“a%ÁåXRÔÄ@ÃY§nk¿Ìd[S<†CÏ`Êž2˜PûvÅ´´gt”l"0“Æ¿Ëà@°ýª¥"K=5ùˆÁ‘0C)œ¥t0ÒbRܵF#XØ3ÿʹK=0õ$„ÆßxPã,šù$½ô"·‰~_‚øAzþúh!`6œÏo³|üŸ2&tì´÷%²ìFc‹z«|ìŸû÷5+àž“Ø4/3mtu™1¸ •‹ ¸xÄ@‘Üà˜p iÂr†ãX£õ¶Û£$Úírퟞïuetôömop~|p¸üóù+€^È^0j¬SŠØµÈ`ð?T\ ‹ð–¸+µ|ùjS×áôÆ÷ÿñþ´4„k}ò½£l:MFE2Æ+ˆÃÙ¨d&øãÚã®ËXm&r©àøþå—·#2`Q‹EUa1…ˆ·æ 5àf±˜2Þöl 3èÇ¥jêg·Ê[ÐÔœ/«G¾BØF2cSĆ6½‰ÌÕj`ªaíNÿ»È,bØ2$óÀÎ8zÓoEiµå±Öo 5ý>RÙg»­$}*jë­‘ *øæÚÃ…Bƒû7R»‚gX0Û¯nÇl€Š-¡%d…Ea&1Û3<ØØr@‘%iû#~ˆÛ¦ôø††­¹-ËKpIÁ’Ût#·½µ¹±±Ù4ͽ‰ÛµÕRÒvÇÿ]ÜæJc³6Ü>ìÿé8톟ò¦¶ÐGk ì-Ý tI3»éÛ€âžyқߥ#ûé*ÏÒÉ_áãŒ]gcx;)®Bæå·(.¸ýˆÕ….—ÊÛ rL^mÂ/¸q+j %vé·YG‚æA«ÙÔ†¡»µâS·¸á(h:žÌgÓa—XkóÀaK÷m„×,–P¾°§,2À=!PORd0M°¬ØI5е¯1˜†LèÚ™]šãØÈ†jm#ìÄå–4+#—ضÄ`ÊyùÈîZÿăq(‰HÜ&rö»JF»'»ÝÆûO]h>`?€û“*ÕùGž7.þ¤âC6 ñi6ÌA„X$×Ëá‰×õãTTúqÊ!\„ðcGŠ¡‹s7˜ÀLAË N.\ïjCv¥O!áäjÙ½[éÏ“w{’ñèà ôJñšR‹ùiV¸AX¸oÜ™-l®ö%Oæ³,Û¸K•‰®}\„F%SÃÀ(Kíi¤¥¹ì`©£ùŵk7Ší­¥ˆvt˜Ž]ÿÜ^#E–ûþIáºíÉØçÂHµÔOó¨åÙ;¼ù­Õ4¨—åËxKû¨yBsíÕñ.àÏRËÚ U³’µzð=‡[ºQ¾ÞÕÀ@ÃU·“é´™6W†&þ"M‡Ó†¢ÍŠ‹BLeˆrE›*ft›ŠÙC2…ªqnyËŠ™ba±(äõŠšºEÅk¸Üln0ÝX1ßR¥Õ ®ÚT°uZ õnù ¦_y9Å›Kfomj/É{ÖÞX2/V‹M%sãøïéò'¦¶þ5pu-Í0¥>ÎC*o½8†»hïj8ƒ’¹è–yaù³¤‚§„‰ö2 ¦ŒfÓ$Lpã¹íM.ü øŸŽüHÏÿ0z|à^ÊXc_ÆöÊ€PRÜÍ 0×/(0ú¿°‰Œ endstream endobj 8530 0 obj << /Length 1556 /Filter /FlateDecode >> stream xÚíZ[oÛ6~÷¯ ö$5Ë»Èb6n›¶IZÇdEàØrbT¶ÙI1 ûï;¼H¶»¶’ XÓäÁ Ås?ç#%tzÓzÙo=-(2Ø(¦PŒ˜˜qƒb¡±0õGè4zßf2Jòó$Ïæí‹u´wu•N†ƒÅ$›yÂ~Òf$ºmS¸1Í®’Ü“ßÜLFÉ3ÿ/I“Á<ñŠôý¥ÿ®Õí·®[ô!ˆ¢˜hc£á´uú… Ðß!‚¹Ñè›»kŠ„ÒpMÑIëS‹[¦`ÁLq{·¢(‡‰;ÄÞ:«­TJ0áq0¸÷Ržõº'ö»½³ck[ÿãÙkkÞqïp¯­a|¶÷áãÛ½£Ï‡ÝÞÁ+gI©J¸> Œ—Rê0JÈõB¬Ë|ÆÅµâ:j&’#¥@ˆduÿÅ&.ýÇXŒµ‘KbÃ,K{y³–%ÅD¹Ø‰b9ÃZÇ(Oи‡M¼(6–—0˜QZò¿bµ³²ÎÌ… ¶t"5â„”d`‘nîÉŠvÿ °R¬® 1×rgýÑ8†ª(ȶÉ.-b(;Uw4ÅšÞ‘½~51q³È?¨jX3Ó¤jö»¯÷>4)µ-Ìßã¹äÍu·õ¼û—‰kM’Dã¶ Qf‰¦ƒ…'³ÙÜÚ±ÌsO‚Î6[LÆúÑâò{˳qí®EöÕº'™ùá­í°ƒô&Áw["#âa”´ÈËÑ%Ç‚o­ë’%$Œa²L·°¼Q][^Äòâ “²EPÀ‘XÆ;— †)QÀÅ`%›|sYqm°Ôª®[³ŠæFB_UÕÈ6Ñ¥‹¹íÆ¢îâ-½\ÍAIÕ,æªh ì”n„ƒo»¿ïÝ£ª·Âà6¾PP@´4BN¶  sÝŽ‚Khét¥9ûå QP`iy ‚µZ¢ Ä[Åz÷r!+!ÀBÄ=ù=„}p¬)Ødœ¨êG·£`p4Tw½‹Õ€À"nùÕŒµVÄëQðÓçîI[Fýƒã£¢~}–©ç¸Ûn gW;øÉ“ùU6¹]; ¯Û”D7‰<Øâ;P²‹! ç%bÂÝŠ.ŠU¸½ÎÅß4™ûÙÁÜàÈ“¿]:(„ ‘@z¿ÿÊS&³‘=k$sO_\:Tµ<Ï ]ÂhUVžx]&y!n„eyPØfž4̦Wi²H aIi¼Ï}güà&ýý·;œóàðß»“ã£&›¡uÑå M“Ù…;j… ÆüE¨ʤ0¨~ 9ºnªç*«¨ ¥±¢€9€‚Œ;´G×ÈV Í AümµápЏ?kÅK)9…‘´›{ü± sÁÙ £áê´æP}ðçÖ/©C“†²)yR­ÂK¡KÚØ.Gi!uI"+<ÉŠÔ!Œ8, å!ÎÂáOcç}B¶ýJß~%ô‡"CüñÚþšÆé °à6è÷`"s~“a¦ô[Að~+§5/ÆÂn´ô 70~E’/Uüön­sÌ®.¹O}mj¹…K;Ê`ÛõŽ-;ÅÝð.PBÓçp–:´ä¿BÅÇsЧH…²*Þʠ÷V(p/BÑjû¥Š»°9æI~;&÷YZ—'lR?nQ…⽨-jâ—]t$ôÛ_+B¬•‹|­¸i(»?ˆ$Ù•†A ÿÛžìý­®Ê³ÿ&!È¿ p†Mf³qödCÍió˜ºÒ©zëÿ^¤ãtp1<% û°55:»™žÃÞí‘ÖÖm2eù#Š!%ägî³ê¹0 Gƒ'Ô}BÝÓÈfÂâò±w†JwÊ…M@Ÿåö©ÂS.<åBØï?žd 2~‰{&à ½xL©°þðC§yÍqïï{0ªm11Æ÷U¦ªË÷à{½švjÍ» ‰W_H fóomN¢âå‚{ξúô{Í{ ~>qoKüè|Û“õE2ªfaý«")0S;T´þ5Ô2ožÂ·;J˜èk~.ý7MóÉ´Ý‘ÑU¾qš†öƒ)ëE!)æî©¨ÿDʺ²ÿ“þÌ endstream endobj 8539 0 obj << /Length 1701 /Filter /FlateDecode >> stream xÚÝYYoÛF~ׯXøIâÍÞGQpl9Èe;’‚ Hƒ‘Ö¶]å-úß;Ë]R"uÒij&¹ËÙÙ™ùæ ºE=o<ë5žž Š,¶Š)Ô»Aš!- –£Þ}h¾j1ÙtóOn>M[ÇL›æÉl6ö“Åp: g®ÅHók‹ÂÂÑtææaúùýpàž„çŽ¹$ua@1c˜¶>ö^6ڽƗQ¢ak5Ѩ?n|øHÐæ_"‚¹5è[¶jŒ„2p¡nãmƒÄcL™Uïó[´íUçy±¯2XQŽ”°X(é÷F_,´^'‚„e•aŒxGs,¥Ì¦G0’˜Qê%ZÅsÁÙÊGý•‘âX[øËÈ‹I‰…TÚ.9*—-w,¦úÀ²Œò ‹²dG–ÛõaÀa5É×ÇÉNÖôç»AoxŽ•Þ‰üméÁãµ®;0¬AxÕ%°€Ã±L_2¾)ô•O}å#Å£¢ãP`%Áç—¼”ZÙA;«zñjˆd^!‡ªâ! * X¹çª4ÓÏn2œÜLB\ÝQxwÊ/Qi&ýR!ª£™C68–ç-m»NîÇù£1’ó·*‹'ÿ)É¿`ůÉèÞ= 2µÉ„éb>œÜÖ6Bôˆ?ˆ$Ó™ÏõÉžécu…Ùpòx+ý?p°Új8VÁzûWOϹYÉ``&°%qɹ/7§¾Ê”¤9žÎ]x¸E2= ƒY^oÂsêâCçü4<@f$x½e ‡Õ fÙ+U¨¶º¨B©…*Ö°e%Š- uƒ#n`Ià84+.³‘œac4š;tSªf·óòRZƒA9+É1×ETx­§ZFæ\D+UúªóL^wÚݫˋ³vçúí»v·÷âòâú²w ½*RIi .ÁEE*n0‡Ñ¡Bq¨$ee¡Ž¦‹ÙѾísK ÇpVL±¡kûo¢–Ø UÏâd‹(~ ¥òdgK“%AmJë­êoÉff«–’Í“n×wWï½ã_vÎÊñ#ÞŸž×*f¸’» |¬ßoc¹d½Go X¿žNnY×pŒðKÒô[‹K€é ÌÌ]:›N.ÂöK‹’æ½Ký±|PÉИEr-œ{wCè99çkËÃlþ6I?{͸A~»sÙÑ\ܹ05ªÈèçÊ2®ò›87pÜ:–†5_,¯»$; ÷¾æ.DUß$Ga&‘[±y8zêÊ›¤Ãñläé~,eÍu°×5”Ž}C£Ji袅Ô;ãÐlµ7Ž,¡é2¦€yN^+Žy^Ôó’^ VC`‡‡ jápFß¾ë:n¾?˜•Eƒ^ v©ÌJ’e†#îh…ª}`_¦Œ\Õ{"Ú’šAÂQõlÿSM@PP¬¢ëQyrÞ~h¼ên£=,0u“œ˜ü“Òg+_9¸4Mr7ÕÌ{‚D\êè [ƒ’˜òý•@Ác½’¨u½BXqÏJ€3›³’3v¸›2f±7åBb¡7ë}GÞ5 ¬%ª2PiØ:Tc ¤¦e!|­éÿ?Ï?Éëqz»ø1s¾ædd¥òÜ.Y®hᣯ(z_As‹µ–µìþSèáDcIôzÞ\¿y—×W¯®Û-(š›§ï׿_õâšZ*:cyŸv2–'*h`Û¿Ï<ä¼É"ÏnØîCÚ £O“ºùtCú²+e²ødŒÙƒ¥bú*XBŒZöœ¼^ú^þË` €¬—u8D{"÷|âÃ¥DŒ åh•¹ËG|h*rÕM^Ede±Èw6ûÛ›¼rE36YUÑû’WA­ Çõ,ÿSðó;W’O„_·}q¶¼öÙC '+Fެ3 {Ž{WQ´†vâ™·Û(©}M³#9G‰¹-TN^#Š3àÅ¡ÄàöÁ½*F¬F¹ö_œTß.ˆ„v¯"Vmˆ(Ј*KE¾‹ƒ!õÌ ŒWõ¼"KjÁd-ï1ó}(”‹êàܶ~˜ÒXs1©|cb €å.™µ|È÷¿†_þôTJØæéz0é?Òä Âû¹Ÿu7‘®“~|s{¼z².Ë? ’…_™ø!-Á”þ0E,² endstream endobj 8547 0 obj << /Length 1146 /Filter /FlateDecode >> stream xÚ¥˜]oÛ6†ïý+x)3C~_ªIœ¢i,V ]a(¶ÚµãÌv¶l¿~‡–(GŠmIu.¢‹¯ßLJ#ß #7ƒwéàb$9qÔiÐ$ýFÀJ Â#-•NtF¾D·1¨(_ßçëÕ&‚±Qòô´˜O³í|õXܸÊc`Ñß1Ç«§|]ܾyžÏò_Šó»|‘g›¼¸à€òøkúapþpŒ‡N à«%5Ìérðå+#3¼ÿ0*œ%ÿìžZ©-d<ømÀʾ0ʱ Œ‚þiÍÉxsóîP¯ý[9£L˜²ÃwïÔdì{”|š|_—çW“d<¹½þcvõÞòx1B•½$#CøFõZ1¨V Çš1À EgˆÖ¨ª éŽq¦r‡;M{‡¨/é7%9ezgøî‡²9Pk Yçä[ÍåãZÚkIGóJK•JΩSª)¶K:ôjøqA p¢`—lïjñÔÂQ‹Ð?©l爄TÔUˆ½XVüµQy, ò¤›sjù› ·fÎôKúY8h.©÷*©Gàrò)‰-‹Š‹x¨¢÷øõj’ÞÆCD?íC†~-î…ÓË –žäâb$lCÏ[Ï ½ôÁO1ŠE›|ºzœçÛùÔGüÃÿ˷ŽåóÆOWá*ÛNýå};)’(ÅÃH:š«)C<[Ù ’˜Yªeó~ì¡–õZï1áødwô,>¨â¨VíÉ9ž¤ç“z<½¹Cc¥ª‡Ã^ êl;wÁ_á§KÙô·»ªµÀhu¿„ŸÅbœjkºp—Ä‚EŸÓ÷W±PQù«õg?Yª4'^4I“ŸfÏÛ‡•_ °hþ_X/àýY¶ÍúcˆÞ)G¤°X¯ÜéÙIµ]0 ’¸æ°ûaR6ï‰!&ØkáÊÆÝshp­Ó§j*„F?¡wHÐ)ñÕV4#êM¢ ÍxˆÐÄÒaðs§h:Ü bhÍðAÙ/åg(¬¥Jê. Ž>bñÃå¡çðf|v }Lލt+€ÉbQ½áŸL¨ìû&”ŵùc㱊½ârºÎgùãvž-6‡H½¯Êìö «–“D`?Ë¡w4qFQåxVƒ$N‘ª‘T6ïɪ¥œ)"˜Cî÷5™P‚wg{ÇqÌ \¶ #Z²yTpTâæ£N_P:Ô¢ ¤2ÙNjé/ÃéÕ𦿭¤†Ö¸0¢_ÂÏ"PNâ›{“:¹þ}wv™ž]2wYöz—éU³…Ü#•²¸Ì}O^bì]6Ý.ü†ýߨ¨èš ŠýŽ+cO.n€i\uÙI–’8tp†NhÞs'‰[FÅ~C£å~e,±†ùÛ]Ñdþ†—Ã1$ SÒNŠ»@ŽÓX#¨¾€úýÎ:µ˜ ¼Ã^²p™;œSEÓäÖ­ä¾±Ð+ëoÄüBU"š?Ò3Êyé®yh<Ä­zôc}¯ŠoD›ùÒcû´(¿-³©ÿ….‰NŠ]±ßµejØ¡mÿHA ý endstream endobj 8556 0 obj << /Length 1170 /Filter /FlateDecode >> stream xÚ½XÛrÛ6}×Wà‘œ©,îxt\ÅuÜ\jq:ͤ #ѱ¦´ÄHrÿ}"DY´$’–§z 8\ìîÙ‘o„‘‹Þë¤÷êâ¨Ó\“ä†NŒ´T:A’ ù]Å\EÙâk¶˜/ã>76:+Š|:NWÓù¬ìø5‹9‹~Ä€óy‘-Êî‹ûé$û¥¼¿Îò,]fe(çâ/ÉÛÞ é}ïšÂ”¯–Ô0CÆw½Ï_™`ÿ[¨p–ü»uG¤¶xÍɰ÷G…e0 h=£\ ?ZYàƒ'ׇ Œ2a‚¯_«QâWt>zw[•¸¯¢ßF—ÃÑðjðim|õöp}õ±¶ÀŒô¹Ä÷ªÇ¸39?޳Ŷ†Ç¨ã¼ÄKn½;‹¦ËÑòob =”3!³|R6îî—>8«ÐJWcß¼-›8KE?c`Q:^å>Ú±Q}œ:#‰–šJpõ gª Õ”)¾ ÚíWå/{!!=äúA˜Î©µ†,2r³ìÃXÖc L0c+,ÔáPÀ‹Ru°u>`ˆ¶næ`q GIm‹àíX³ã/Z›ºAZR©lk{„D×JµkûÉÊo2¢ò0wT!jjá‰ûgƒ–ÝB~'•ÓÔ:݆“WqÓ9Yÿú88™›WÉ!”ŽÌÌfc_ ‘”E¨–Øù„ª«‡";ÊÓ½T´”3I”›Ô:£¨rЂŠCíù²I”0½#-¦ˆòWa*,Ìy% =1F`1†‹†X!".I¢5sºQ '@îZˆŒ51ø°zr¨û·‘ˆÛÙŒ‹n?‰ˆÒ j”jCÄáµ—?Gïc½|xÿ{ ¨+ÔRï‹òðAKÄgI&” fAßJÞmh:KïÂ]1÷|EVlßÔ%£§³ñ´Hó:@{ƒsXß,‘h }, ¾ûØ71¸‚ıªÊ°ÍôN öXÆ9"™Äj ªlÅ­!HÙžÁL¡&k„±TYÞ.¶Gˆ, j¡¨[Õ•ÈJP‹9±cÔFQe#‘+73¬½¶îåo'ûpðna?‰ÇÂ0ªA´áqrùn0¿ó\.òl3 |¾ð½ÙM˜¡üi3<é‡u/Ë›t6)o&^ä*"9—;üE§ÿûÊZ§ endstream endobj 8565 0 obj << /Length 1252 /Filter /FlateDecode >> stream xÚ¥XÛrÛ6|×W`òDÎÔîGñ$N#WbÚ$£QdÚñD²In›¿ï‚7™”ÄKä›˃=»däž0r5x^¾Uœ8êŒ0$¾#Â**¤#‘²T9Iâ[ò)¸…’Í×d³Ú†"²Á«õzñ0ŸíVÙ7I(XðOÈñàbµN6Ùí«§‡Ûä·ì|œ,’Ù6É.8‚òðKü~0Œ?ñ0ÂI$ðjE#‘ùrðé #·¸ÿž0*%ÿ¦O-‰2Ç™ þ°|.ŒrLQa¤Úp²Á?nŽÍÚ¿•3Êd”OxüZOc?£ËéÇð‚³`ä/âw—×Ã8 º|k~|ù{@F.„Âûôs<` Šc…! eš4-êœD.*9á¯ß³Bðxþpu SfRŽÓûéXA­È&!wZOiꤜ@NS«çø—®#¥´ƒ‘gb“‚2a‰ÑS±M\U¢¨0$§Úñz$ LiÛ9)"jŒ«†ÂþcÙh ¢ UEp©ÒÊ©åÊ\Ô'ÃgéÝpE­p‡zÝ 3É_~%„?ö¼©&у]~8…±Ç’¶†åIæÖhø"£Y0{¼ÍNæ‹UZHpºû–Ÿ|fR-òó»P±`µÉ.’ÙÜ—¥oùÐü*Ò—ª´ŒÑÃZ$„¤Jj¢5/”u25FS.;¸/GD²Ð¥N²Ñ=ý'©ôPòÙ™Á×ïî@á¨â(ŽÝœ¼& bÑ@ÕXú:PB¶(•PJòvæÔJ_)UÚVƒ%‚5½2}– 5òeì‘UgòçÍÍhßL¯aFÄéß¿n†“3–Ÿg ñI¨SŠ 2. ´}Z¯3§»$·çw?‡ÄWŸ¹I®“mvº|Úzÿíò«Ù.³ã1û10 ¥¤ÅZåš’"@c¤:ø¯„D‹aK‘ÃûXÌc¡‘qXÄ ÁI,$Vvw äÌÆPÍ;%¬ÁˆJDÖcêëDô~ÚU#Ê(k5bÁ±ðUSÖ9nsb9šáAÕ/égYQZÌZ™º¯&èuðê÷__=Ä©ñÇ›>”@¶O§m®F(XhÕÛ…_ ⨣ý“ï'|`0…–)â®À² Z¹îºWH4SˆˆSÉNóÕ vn©‹âÐ(á`¨{ãëZ/¾o¾îîw/Zµ^Ðê{8¦ê´¶i½­©a=ó|–Ö…óÍCtZëÓÉ»¿‡¿¼Òä < r\õʯÜGTЖ½ÖkŶʾ„ÌLYä'ÞOöÀ:J7-z¿Ï@í†nzt\©‘ 0&í÷ik¿‡A‘®GQiuwñkƒ¾ÇTƒ1­ª/X•>+ºÎj›êŸ–-žƒ4Ÿ¥zî,žµGT?Þœ#öSûíoÆéוízõXîiVÙØÙÉ&ùbGö”d½Ó±f‰kª-Ê/:ݼUA¡¶‚·{§DôßjöY·÷ó°ÒµÁ½²RGŠ:ÞcÅð}}ùæF›S9hЭƒJØA½ì Tiªq|fšù_,zºÜÞûŽלKÿ·5²‚kîKŸªsÝæ¨g£EËü0¿)A¡3¿¿µÎó­Ø¥á…Q.ðädŸÿ¶ËðBëEþ9p9›ûo‹ ‰(ì¶¥ÀOG í*Þoÿ׳g} endstream endobj 8575 0 obj << /Length 1367 /Filter /FlateDecode >> stream xÚ­X[sÚ8~çWhú„g6ªŽîz¤)diRH‰w;™n‡¡`²L @w³ÿ~| æf›ôlËÒç£ïœOçHŒ<F®ïÂÆÛŽâ¨Ó\“pJ 'FZ* á„|i^\5£Õ·hµXÜØfk¹|œG›Ùbž4¼Κÿ€Ëh•4_ýœM¢ß’ûAôÖQò”s Á×ðC£6~4Ma’OKj˜!ã§Æ—¯ŒL°ýaT8Kþ{=©-^É]ãSƒ¥Ó`ÐzF¹¾·²Â{ƒcF™0é„ïÔ0ô3ººÚŸb;ó¥×·ö‚ÁÈ—ø µ qbø Œ°;0Œ:Î˜ØˆÙØÿ÷ÑùS¬ù\k®FóÍlþ4­cÒ½„÷VÒ¸Š~Øñg´ö®ÙÐ}Æ9(ª¬#Zj*ÁíÒnœÉi˨åðB=Úégá/W!!=dü"Ωµ†¬"2-¸ï8–D(cle$uh+uJíBÅþE?¼Ê9P¥ ¢Hj{¨`B‘$‡1Äö̦©`Pݧ)·ºhÇ_L1ÿû¾ú¦†Oë‡ÍËŸ¸ÿ/µ,ãš;œ¢Øå¨…=Ã-ë9ÿUzSH…uzÛ×Óª/í÷wûïÛ·ÃÎMê-ÕWÃKlí÷ÂnïöÙ¢¼Î?‘à·öf5¥~\¬¢Lsëåb¾ŽÖÉã<Š&Ñä€òÀ9¤À%DTÇÈçÀ1þd©òrHô§Ãwi4dÃk)Ïc爋*6/‘…˳2Õcž)jF“€.j9âxØ ´B(½k7ÔJ]Ù6²–BmcÏ¥¢Ëi\3Q;4—ˆn{4㢞ß_%:iún[ ¶ÝÎý°Ûëf¾è߆ÃÖ­_‡½XyýN U³Õ½©#8]ùýÎ1èìZ¤ÞàÐÅRXÊôÉtŵ¤ ‰RÑäÙ6OWÙðz¢A,- ‘XÞ8ž' Ÿ€„®ž°À ö¸DM¨sÈ<¡‡ÙölÄd­Du]K†ùÀí˜ÈžcåòÉGV8ˆ]ÂËä“F@Ö‹€WÉGXK•ÜíÏí››ëT&¾<ûÜCÑ X>¶ãô58W2 nßÃy¬#@%‰ Àޝüf«¤LRÒxñ„*š§‹irí…Ù„¸ŸR8ŸäÍ2)-góñl9z\*#™A¯H"p.iP­$œQ^F怚ʓY6¼^‰XÚc1–}If˜08.Á•“`ì!±¯ÂˆrP!®6kÒ‹´£ÚV_(„Dn¥*ô&7æMiù˜qÌp95°ËqYù˜Fv¨çôWI‘Ü`bŒç{3ÀÍš¯ïoÛ¸2†íÁí …XÖ »ýÞðcëîúŒŠÑCP[§Ñæ¬8ø”Ã,€®.Ùb!MÚòJÚH ±ÙÚb¥ÃkkCy,ÀÕrks£|HÉZÚИ@¸/É*ówB ©j×,LS†Õ(ñ4î3€­bÏf:VÑFÌ1avkk•r\AÙhY²µÚsú«´áwjm­ Úïb±Ýøó,$†ýÞM˜»îÏÈS™g3Ìニ,ÒÍ'àJ¨àW<€ß¦sõ+\\¹eP½jEí“ðµ–ªDÝ E(‰Y°©fá&”£ ù.˜Äž-VnU|lË3ühŽ®ãð=0„ Q •Ï oˆ8H7ð\3_äXÌ—–¯–Òƒ4c›šZºæåâ)¸PÍåc”uHÞ¯|k4MGàÿ|œ¾¹HLo»ÉÍh>In&£ï9ò>ë‚lôÿͱ«ù endstream endobj 8510 0 obj << /Type /ObjStm /N 100 /First 974 /Length 1207 /Filter /FlateDecode >> stream xÚÍ—ÍŠ\7…÷ýzµJUú)¼HÌìÆñ"‰ñÂ$MO°Çà¼}ιM~Z=⊎!Þ4º¥ïªTUGuÕÚ%…zI%˜íb¡g>× YièAªÑÒC¥æl•¹·ÐÍ=hî°Hf逅¢p ¥9§J¨RaQ µ4Zj¨NFKhº1-´žhÁSZ°jͰ˜OÊ•=¸q?"Á{Á ¤®ié öŸH6Œ*#)à4ñÕ\02ÆR8ê &#`Ëí›cT6/Œ£„Qa¢²3œE ÒŒ!ayiÌDѤÃ%lx·WîO1ë‰\Ãn Q(våx¶‚´nÉSŽêæ ©¡7ä0çÄYK!ëy¤]ÞP±¬Û*5ÙV±Ìê8âÀD.Û*H^.…yq¼QœyA‘fMÁÕÆ¼ ˜ÜÚ6ÛYZ–±+ÖÂà×sŽº#¤D“âÅÁ¨‘£#Á°akR¸~T—RlŸ6<æÆ ±*¬ê¡&Û,Þ…žx6°Áyqzƒ ´êæ#ìYrmB®iÅhÃ*Íé£2|Eþ\9jÌ•åÒáÂÜCë–6}ÖŠ#Á ¹òp8÷‡ªZVƉB.Ü)¤bÊM:òlZ6³êô†B™)kŽtšµNGŒB†#†àpd5±Zƪ16è BdþàÈx40®úyøðó*ðá¥îîÇçá5N&õËpüáÇŸ–+Ib…Þz÷îÍáÙ³)hMcC´» Ô)—}°¦XÜöÁìUö˜k‰8¤û Xœ‰}°¥(mp}ÿðþ1ÜÝ…ã=JIöó+÷ÌR†`ÏO8Ÿ&8|ç§Jô¿æ¶¶‡#À',z|ñááçïOáu8¾x~ޝNŸÃßþ^ýñû o=ŽßÂ÷éýãGv¹míÃñåéãç?Ÿ>ž;ßfûîôËoo¿yø^3žŠæÛ<¿£·ð6úrßâ¼Ð?¡Kh¥E6Øë]€XpJ)&éû`‹t,½ÆÞÚ8•øÎ%>€s‰àTâˆf-­€Ö¢•üey³s¾–`N·K0Ë¢/@ŠF¢yßK×Iå«E-mD‡ÀWaDcŠYV@DÍkÉ.˜‹EAÅ÷Á\£t_ÍЩ¦ºY4šžM_MÁgúJ4¾*_è[#4í[X5ÇVeLhpÉ÷A\âJøÒÇZ¶ˆBF“…-âz‚&ã·4™Kõ|½øµ^´Ý®í‹z¹Ù;gYàŠÆZú>hŠÏH_XÑ$A ¾jÆgDÀìøŒ<ùMAÉ1ûB0Ò-êØY×zÌå‡éßzºY3Ö®5s^ó6ÍX]ÔÌ8ë1#4í18ï1#8í18í17ï1#˜Ð:Ú‚gmnûàüö?‚OÝþÿ·®UêµñWòf–²¨À p¦Àš*pç·óœßÎGpz;Àùí|ç·óœÞÎp~;Á¯êv^˵«Þ.Áj‹¼g¡©pÞGpÚpÚnÞGpÚpÞGpV¸Œÿ7º’Å,5¦•, N“¤¯å.Øžtû’n«’n+’n;’þÍ‘;E endstream endobj 8586 0 obj << /Length 1201 /Filter /FlateDecode >> stream xÚ¥XÙrÛF|çWì#P×{TLÖqÙå¸X²*ªH¢BÙ‰œ¯O/$Â!>0½³=݃¹!Œì÷v³Þ»=ʼn§ÞC² NQ!=±ÊQå%ɮɗä(:ÉgßòÙô)í ë’ÁããÝíÕå÷ÛéC<ñ>OKþI9n¼›>æ³xzÿÇíu¾_äwùåSÿp*åé×ìCo˜õþîqäÃ'V`iE-³äê¾÷å+#×8ÿ0*½#ÿÎïº'Ê8ïȨ÷[{a”c Œ #Ã݆“.¬¼Ø´ë°*g”I7|2ø4>~Fª,ÉR§“Áîø4Åád8>žÎÓ^®[ßíeÉH_(¬¨KˆYªCY¡IWAcÔ ÑŽ§7HN³$˜þ¸ù3þž¤Š%ÓYüƒÏSÏ’Aªu’„õæç‰‡§é}^ ¤R'Ïßg—t½BJê¼!Fª¸¯–Äz», GÕó«² Û°—pØß))—*@Î/á‚:gÉ,'“Ri_DzKBNÖ-±8§Zr©×º 6¯>ÊòBóÒSg%`u+åRbK* ¹¹j:H’YÓ:©Ít9ÎkZ~ɬðTCïf9u|mùÍÑܨn¥ÞÊyÚ›ùÊ‘öÑð×ñûËÝÃì-.kˆ^˼)ðÑé@<çµ;çЧ°Í"_@*‹Kz%ÌÞMäÀRK»b8o<5η—¸ÖЄâôk\×H›;ê!âr°°FËl­l¡)Ó•$سc-´½ ¦ZU mÒö2Z"SÓ­ÂÛi›qÔɾàûcjÑ”Ç'ƒÑÑ[þ±.þòÀUõc¢–!©Òm4¾€Ôr³,IÞQãŠò€¥z_`9­ºˆ%Áý hJÙW «‘9¨æb-èܲ\"o_Ƀ=ÛÉdÒ¬ó‚TX„«5Ru¾ˆvÔ*Û­Ê[é\1 ÖÇ­ŽÂ(88N=q–ö1~>Ž{£ùS´ÏY²Åì ‹Š~1ôÞþ+0›}€)Ê "M`CÖdãŽmP jK5[ Et7 [c„ÑbÕã µF´w0óH4½0É7°Vci©p²šFõš>Ì#M9›ßO3øñS£ nᥭrÛd†U°–®[©·ò‚äaü«µB4ÁÙ6vÐÕžž½Á hRa08]Ëná²…ˆ‚ ï—%‹ÑÝá(tutÒ7÷˜g€Qx¿k ­Î Šc«Ùt6XUº”L{3ÔâÍÜ W¡¶Ñ «`);z+/4/†ëófÃáyjð}189;Ó‹t©جu&¨D³ÛÚPàaæm ±/ ¥l©õEt7±JqE8æt!W/ hÁ-¸µØYøjsh‡ÞÇ72Ö×B'0ÍžwâïŸÅñ?œäÍ>À»²wÕD;¾Ž„GŠ·ºœçô1ˆyýÜi•Ë’¸põ|ZðßäˆÁ\ðNzX “>F/Óú£Õæ!JP¼~D2 •4íå“¿fßtüföt{J%wÅ7´ûË«ðA,açTâiÇb´0¼ä Ðö?Á÷2Ø endstream endobj 8597 0 obj << /Length 1048 /Filter /FlateDecode >> stream xÚ½XÛnÛF}×Wì# T“Ùû£KŽ×vF†bÑ­ÙVe·uÿ¾³¢. e’¢iD€EšÜ9œ=sÎîˆRü!¤8ôÞ4ŠÁ’“áH8íA%&3ñ-ùœ’I²ålùð˜öÉùd°XÌo¯§O·÷ù…£,%™ü“"œ?,²e~ùøïÛYöK~>ÎæÙô1ËÿA L¿O>õ†“Þ_=äT¤ÀüÑœtâú®÷í»3¾þIHPÁ‹W£î„¶žsñ¥÷[O®§!9{ dUmQ,ùÆÞÅqÕ„Q‚T.ŸðäsÚç™L®F§©’ÉñÕàŒ/Èäüì÷_Ï¿~Y¥½}îúønÄ(;H)ú¤ù‰fƒÁ"PÆæX „HVFXËx†Ê¼¸à¶¼ 5€jG Šˆñpü""‚´+¦W7òhïXfâ¦Àn5”ŠP:!n¡$#;ˆŒ)ƒ­ ÀÌìØ"  ‘„5Äòµœ2)0¥˜qbå”’aÞ´ñç¢ëÅëb.òYòÇó_S[rµcÙ¹÷rx9XתÖäoQƒ§P!ÿa.ÿW©5Éàj<¼hã[¬çðŒªA*L 9?alÔª–—Ï´ÙkDžÕ±)Ó:º¥ 8†2¤¤,(ÙÆv5cê9«3åyíeÓÚÌ@ÅdV&@y rrÙBä]™ÜF¬ƒy?ºU­;™À`KŽí|¿/SÃ.¥ŠïO‡öƒÑùø’‘*Q^6z^ç´ÐNAàÕ¢–!&à†-¤^>wËÃÛÙ±PÁzã\ô‹µgT?h@Ö¶Ê7ÐVçÞZxc/eÓÚLêB2òYËüÓh‡ »ì&é|™Ý&?l£-Xß®Úü ¹š÷у 1<ên… ŒÚÖH9®-Ù7l3©5¾Ek¤¬â%Ôtm”u€Žj9knJɼ²5*ä"ŸéPlÈå¾Ó»×uF1V;üyQ\?Hª |¼¼ij¯“:¢ˆR…P!|–KCžË‰õ}"÷Üã7 ƒÈ¤¨]“G·¾ÃS$ëA¹mxgi!{ÅæNXUÃWèyá n/‘¶¢'Òèb&±ÂE¿&Öòêm±Dl£êwÁQªmêÜIõ¤¸µàÝòeÕŸœLN§û:„ZÅ£çZÊð†ŠGÏõ%õŠGnÈÐúnŠGÇ¿Œ®á«Yñ¥D^©øB&Qñº•â‘ £ ½Nñ18æÐ¢Î{X±¥çmÏü.©¢ Äõ^G–Ò>IïùÇðŸÓEj’§4¾Ë_jYHûÜ<'îÒ¾Iól3 ¿¿ŒW³›uß_¯ïôׯÕ.Nò“éý,?™MŸâÈéÓ‹ì±à¦ü Ñ$ endstream endobj 8607 0 obj << /Length 1070 /Filter /FlateDecode >> stream xÚ­XÛnÛF}×Wì# Ô›Ùû£ɪc§Nm¶h‚c+…Q¹vå6Íç÷ð"Ú¤%^¬è…Å=;{fÎìY*ñ‡Pb1y›MÞQFÇNd_#YGáM&j‘݈ÉiÊ6Ym>¯6÷éûLÖ·×WÿÜÞÿUÞ˜­RVÉ×”ðàúþaµ)o/þ½½YýP~¿X­WW«òIfIé§ìÝdžMþžâQ‚„gLm¤W^\ßM>~Râ÷ß %u â¿â©;a\Àu-.'?OTµ% KP’Οv$6øãÅÍ‹]«Îg%%•ö傳Óô+É–Çg©VÉbyòÓ¯©WÉôìdVÄ\OZ]ßâ O‰#6˜Înár¤e/ÂöÚ`ƒ9Hç€f¹M‰¾¦„¬‘Î?±"#çˆùe±‘¤rÉÅåh–!x±Y‰/ b÷CYç„3Q2Ñ** š‰d´¶ U0ÙŸÕ›ÆÄF gË |5¢h°¤)Èè_ÎŒ ƒ#Ñl¥²¦‰ú¦HŸ¾ jb‡p\‹X’^İ{°Š~TžªzGFŽ{ªþý4*ù}ùáü2ÅýYªm2MƒJ²ù¸fVßO Äl6ݳ[ d¥ QX%¡`º( ‹¢~-ÔVTÊ6eÕðqb–²£×Pä¤w<\ L”Œ/"ëá­CšQÌÜŽg¬$t@%Åf8„(‰-¿Pßæ·Oõh<ˆë¨„$ KQ"i»5q~ºœ^.gó³ù"%õ9´6…g€#UØ(Œ×2jÛÉOÄvx€ ¶èá&Ö «†¨Î±l@,¦Æb_W¤µÃŽÏR‡~æº$™ƒn4VFËV8„*%Ñ/ˆŠ_èIùÐæ·WÛÑNº0.ßéÁ l öÕ݂ر9â‘¶n”KÒÒ@Ú#³ì:™A«'=À%mÑÕMí(ªÑ#] &‡ríÌÖP þËðI‘Œ—乓³ €q†µn3z[@ÕÓŒ*à¡N©"ôÙ®PrÛk”žÆO£R}4øg¥÷iàb¾œæ_É~<À0û ö”¾Ã>SòI=¾Ó(ü œè'SŒYöÅ$Ø©}í†#Œ–q6€‰á Øc€Ó]\u•<,U¤v$£=6CÉ?,ù’V‡Îí¨IkoÅ×Có*‘áƒê5\vÉ}õŽ–žwüßN¦oϱ?.Î;0:û=¤TÅïØï)à Èú{ô{‚-#í÷äq‚°¦“³þ~ß æ•ý¾‹úVŒ÷{‚vŒå×5ü|p~:‘ëX¹µnð«¥=nHU›¼©L`•“?7Ÿmùfëñö.=²ÉúzÓuwu¿6Ipnטû²b4TØ(z°ö?LqÇ endstream endobj 8617 0 obj << /Length 1113 /Filter /FlateDecode >> stream xÚ½XÛrÛ6}×Wà‘œ©`q”eÙUìÚ®L§Éd2Å¢[OeK•ÕKþ> ÞdÒ/R¦ye{ppp»$#¿FÎ{'QïÝ™äÄQ§A“è FZ* Ñœ|.BPA¼þ¯—/aŒ «Õâñ~¶y\>§7NãXðOÈqàb¹Š×éíó¿çñOéïI¼ˆg/qú§”‡_¢÷½QÔû«Ç‘ #HœOåxÊÃ\ï‰Ï¯%1@j&Z#–‚ª"Æ™BŽ¢s[U¨é/ç;!9e:9y…µÖuLJÊîÇ2K: œçXE—ŽpNRU¬D{”e+G­D+@4»W°‰’L‚#ù†Š&•mÍCpäì?fYò¯‰D!¬4˜8º*,§–¿!±;š9Óm§ò½æ—íöø~2ºý* N.G]Œ¯Ëû˜àìÅØm~T E”vè'Q+‰V”‹fZtF¾Eit7ë#”ðPJRÆ €b˜U†·÷>8*9 Œ¡ÊºZÍjüÞ¦J¦«ÿÚÅÊ2ô–þÏÅÅôk*â6Ù¿Æ8w—½>Êý “^ÃóG“ÁÕí8šÞ\_އŸ¦Ã°¯‚ŸGËÑé%  Z¸3-¸EË`’FP‡’ÕHåª1/¶Œâšo]Þ)1<–– ó‹ÜÚÀa¹Ñ­ÍÈÂÄPXè Û^Áš$ABÀd•X×$Áñ`y‰—Ï‘4Iš8BcŠ1c«B7$É6ZSm»müQI"ÑÇëj²Ú¡aÁàr|:_EÓ“qä³âö€„øðä¶KSäæÂàF‚®=+|ƒ"m‹¦(‡D×É¢ÈÃ;6Eèt¥£ªhŠ”÷Këº ñC³ m(7°_°æ¢Pám½Á¶¯kQ(ñ~|lîˆ2U±Õ|U2Q¢m°4¼Û.åv5˜¨ºýîP»ë×»wwˆßÓÖ,n$7?ò%°U?ä%´¥Â}¯ÃRÂ;¿€Á-jk6|…ˆÂ2麾Ä䮵ã3]5žÐšøࣽMÿ¿w?³Ãš˜,öÏõW5½_>¿l8Ô‚wÛV‹Ææ7ŽÕ7 ’Œj4x©ð0Ûö< ïfpÄ2 .®íh¿¬ñFS£öH]÷Šk©CSWH¯Xû®JÊ“—H´š¿ÓB*¨ ÚäìWÑ~þ.;üÌwíè~ÝúÑžž†ržÕ3Ð2ì³–Ã?f«P›ÐïJ¿Tiö±+†Ë'ö¯q> }¾öwã‡,ÿ¾Ïžô³oe7ãôÇìyžþ˜Ï6~älóm¿”Eÿ8!Y endstream endobj 8627 0 obj << /Length 1255 /Filter /FlateDecode >> stream xÚµXÛŽÛF }÷WÌS!·ëÙ¹pnEÓ¢E» ¤A&ÎSl¯’õ­^')úõ=#Y²%ku‰Ó‡…díCòp8ì=ìvôÓtt}C’¬²lúŽ)O\éÀyNA³é={•ü:V&IwoÓÝæa³·Üðð¼¾øQ—`EØÊ4©jQS<ëpX mFÕápÁÂÁ…°GHxPQ[|ÜÖµI.lnüVH*î½c»”½« úˆÉ³Úqel¡HÇe`Jó ëz2¼Ç ÞŽç™5 ~ø &™÷‡0b¾YïÓöWº±„ Ø=“Ì„®òµ ,ÎÓªj}U¯=ì¬ù à˜’ÔæRÅÞCÕ‹7oâæ×7ÚŸ¬ Ü-ÙŠèMñ—[;ÑB'ßÅ(€$"‰P<,þMKÿÇÚ$ƒ‰–69.ŠJ E”ü0ž€¸Ù6Õ%“ïïgûY¾Û7ù£b%ßfèNrs+ÿöòÙ³Ù: {ç ïrÿÛÀI¨ 7TÏAɽ4uØÏä$ ¤ÂEUÁ 0ÃÑY†®g«tH1°ý54Öélf§1 ™÷m(¸r®³U"Ý….IpT¢.e3¤¸ ²ºH¸Y&™î² ½â‡!í~õó’}ÉVô!¿6H>ê¶z$…Þ¦9nÖŠ©9çªtë°¦Œ!µªG¡ƒ¥´†eZK‹‹ˆa„ƒÿçgÜ.–él¹ºŒ»GU4ÓÃj®¼û¾vvxÃI…nvç6”µªÆè’QYîµ/ÙVË¡Ðöf‡ Y`ÈØ`ÁìbzãŽô™±}ƒ“ýùªâ•¬ÍúªF’Ìê>†•ã¤Òõˆt1¥”è°gPŠ\Ä’Š“9OqtÂ&ÙaLƒ¶ý`ÒU¥Ìr‡Ð¶@¢ƒ§=ΔR¥æäM£B|k + iƒJ{ 7ª¶ ýóPJàE”U}%m nmÄ9¼œ-?¤ýÎä„ 5Û%8¡ÑLôçå¤mÕö¢u¬S(·ðIþø:®(­íÅ®"r„ý%Õ#×Å®i#í°Tºˆ]Z¢…'ßÉ®;Æñ}vÙ¹T¦ËÝñpïõ€Ë¥Í.ƶ÷¯P»îóé Ýn<Ô‹Nú <ˆg>ú;QL6%KžA3á蛫Áâöì!»„ïÂíËr ª; ¾×f@CG8 dÕƒ&¢ñ£OŽŽô6÷8g¶¸šeõù|¤=‹."™Rh•Ñ—w’l™®ßïÿüRkÑÖ<,ÁÅ5o‰Mk+L¸°{!»Ç%¹> ÐË>¨60AUDBÆé±Ãw>»võÍO4%&^¦.„nÔþŠÕ\” v0Å*>4RìÔ‡Ï!Y9Üx(¸zäºÆ …¨€…C’¨i`¦*Û{’ÙÜ>*.y†2›'–Bù|ú°Èç“ËÃ`u5›Ç)mäºíU1šQÖT¸Äþó: endstream endobj 8637 0 obj << /Length 1213 /Filter /FlateDecode >> stream xÚ­XKs"7¾ó+t„‘Õ­wI%»YW6—dÃÍÙ¢ð0¶©Å@Æxç×§5OfxÍ€ Ш{>u÷×Ý’`L°›Þ¯£ÞõGÌsoаÑ=³È¬r\yÉFSvÛÿc€º'wq²| Ѻþ/«Õ|MÖ³å"›øPô¿ €Η«8ɦo^fÓø*ûý9žÇ“ç8û‘ÃàËèSï·QïßÁ {µâVX=õn¿6¥ùOLpéûž®zbÊ8çìïÞ_=‘oCp ô‚£‘aµ–ЃÉχ6 ‚ i³ Mîôx•ÌÑøyö_œÂ,ß“×IªR!ؽA·×PŒ5€˜1¤McÓ ÖÛÒ h<·rËÜcP†›½* “6<(Ä‘;gY³ûš5ëA—ò ]`=×dîµn*K N–©¬Örž´%·ßfCMa÷Ð"Z.Öñf}•ͤ+h:‹ž:К)¥&—kßÄê§8h‹TjÕ4u¤T cøÓ<^<¬OÁ)Ý ,QË4ÝÜÁžýÒÂÛnqq3 (îÐïøhýºêÄ Ó^Ãf˜§¦í’G- ÉãÖ¶`F¡Rs§]é’\¼#3 ™ÖŠ g3Ã!—Ò“˵;`õË™¡Så ¬Ž‚BùöÔ |bÈ­5¨ jT.>FŒÜ D1t¶é…“Ä(¤i!¡èCƒçäðÊCÉòe1}Y[.މ`„äV¦hôRÏ Škц…JÊ’ÊWI*ïÈI:,SÚU2‚âKKèP+(¡¢¢OÌp{ìU²a“óൠÐ)î­ßA§%—VµF‡ž ¢65tËög“âI¡ýP¡}­f‡Ùaæº|>ïjÿN3)÷1RX×ôÞI&Ò†×-š."’"*(*Еk7çrhÓ=”•bÒ’ÿÑÛ®T{ñ4w …a(Û\¸sH“$MFRbÕeh Êt¢q(?+p¤†š-‹5+•Q¸Z'9k&ÉÃs+âµ wÐyM]–mOBE´Ž®` ¡ P~.þ¿Ûš¬hS þ1<Ü-“u¾® 5er§Ñ¦ªÒ“ûì_*Qe¡S]D‰TÆ„¬ù“_Ñ¹ÍØ&ê@©R¯¡#çÃÑ6T*¤×ÊÓ´)UÒæeÙŒâ݈#C&!]ÆQ7g—%Ò©éj¶º„:Js«¡ %EšlÏœÐé «£{3æ¤måã$ ‚ ZÓ¨p¢¡Úa éÄSLÚ’ñß%ªÎ>þgæÆœTyÔ ç5ˆò,Çý¤hýv;ÔBô?Ä«„lÞ£Éz@Ã4»ÿxšDá2¥öŠÖª)!pZÓ^¶ ¨Æt4¨®dÂuŒè¯ÇQ†eú<þ:ά±™îoqÔSu´gçö-{VH»x“žT¨fU‘–Z"Ù¹g叨ÆxGNký›˜ÐrÄö˜$Ðzáv1wPµí3éÎõ™]f`GY8…)"GëÛÂý'È B)(pÅ9Ñÿ8YeSÚæ÷™††t,ê¿_>"­æq± {žÑë>— ïE”?æ§þžý˜,òL0¥¼@+'á¤\Odòÿÿ¶z endstream endobj 8583 0 obj << /Type /ObjStm /N 100 /First 974 /Length 1150 /Filter /FlateDecode >> stream xÚ͘ËjG†÷óõ5u.uáEb´ Ç‹$ á !`¤ Éà¼}þ¿%‚Õ3ͤ@¼Õ§þªsûªzZ6›¥’Fí#¹$›­§¡|žIÔ`è’¤9,£$-•–šÔ-’ttZf2´h²6wXnØŽûŽšjY¦zj¥A<,5ﴌԆÓÒS×JËL½Q3%BÍÄNóc`gLM´Ì4;]LMRD’—bU†?9ÂìéIĘÀlLi™IÌ WtŒ"lHØËØ9·÷™F+£IÔ$Õ„6ÌÖ®´aE£ ´ê°)¼5ÆÚK·F¼õÞiÃì% 쇿´!ªéË.væ µ° ­Ì¤G°5Œòm¨«j¡Î9rê³** ›'$é;ذ‹µJvv8 Wu–I-€ +ª.± ³µ/>àa„µ½2ß [gM‚³‚Z! Àº(FS¨-:+uЍæd]ÚHVŒuQ R:ë‚"šëBФÚÐ}™Œ•D…yTÒµøÀ,3Âûyc¾ÀÒja¤¤¢.õ#Uu©šlÜ6¬h¹¡Ö ër¬{ƒãh°. Äan†¨Fã¹6 £2òZY!åQ žM–²xƒX!Æ#’VğæiW‚þ:’ƒ }skÔ±` ‰6îè%lØÏëÇÇŠB¸ º^—ÌŠØ0Á“„vn8»ýÛt…ãç8ÔïÓþ—_ÃÑJhq(ÏÍ—ÏŸ?îÞ¼ÙÖÑòªç…Er¡wË?/,-{Ĉ>åª×:-›E„­feŽÌbŸö’e]ÇËÛ›‡tq‘ö—ìµàP.K.™¼z}z"C2ìé‰ÇÅò„möïîn?ý|xHWiÿîíeÚ8|}Hÿzøð÷_L\ÿqØí„·ÃÍÃ=¯ÀÆõ»ýûÃýí—»O‡ûÇkq±ýtøýÏën¿¦«ïŒ>õ#]ßa5ïÅGá·É>Å󘬤^{Æy8Q•gBì ŠÏ‹JÉEÆyá6Ô+á6Ôk¡ÌÉÃ'àoÑÖŒó|^ˆ÷nöÈÅtfÅ«å¼TkÀµšeÞÑç…8 Åõ;azöc¦g}9Ó³™~&Übz-Údz%Ä{(÷&aüežVë¹V  à/×xIesq@mjhÞ³œ|G¬…8 äè¬äçyò±*èïõ%Pÿ·rŒ1…½cþ0aü\¸ñ‘h ãµpã#áÆká&ÆGÂ-Œ×ÂMŒ„[¯…› ·0^ 71>þÏË ŒåKc‰`,QŒ%бD1–(ÆÅX¢Kc‰b,QŒ%б|_ë Œõkc`¬QŒWB|šƒÎv^X§æQ= ÔšùO”³BŸ=7¸v+ø›aÑì§>êÖB³š#Õ±Ò³j@¨6g {*š‹¾b<ñÃø‰ßÐ/ÜNn¯Ü¢€[p‹nÑ{Ú¢÷´Eïi‹ÞÓ½§-zO[ôž¶è=mÑ{z-TÁiý&™Óäø endstream endobj 8648 0 obj << /Length 451 /Filter /FlateDecode >> stream xÚ•TMOã@ ½çWø˜H[3ö|Y•ØÓ²¹B¥P´)í¦ÝŸ¿NR iƒT.qâ???ÛQð ¦Ù×2;»2£cåp0È:‚7MÔP.à6ÿV°ÍSó˜šÕ¦˜°ùùz]WóÙ¶Z½ôŽ‹T°Êÿ$ëÕ:5½{ú»Z¤/ýûMªÓl“úBf¤â¾¼Î.ËìWFÂGgImÐ+óev{¯`!þkP¨c€¿Ý­%ÄÖð#ûž©]- IJPÈN··A#GΛ±ªÛ¬¤Pißü³y´lª—jû ›o7Ó}ª=»’À76’ÄŽ€|€ðj°vh‰À9A³|(„~/é€Ñ¿#·­™ŽB*×iÛìÂCðÐ$xú1–i±LDûŠE„V“XŒÖ‚uš‹2ï&Í0šÀY–’¸f+“w§¬ú'~\†´ÂiãÑ}ÈŒ=ãN&¦­ÆÀ4$ÖrP§pØ+-\Lt‡J:â0­¢ÿTëÀd8­l³;y•FCÚDĽ 5‘·kT¿É›j)mÊ×õn³—³yû›™ÀXBXð»ha2XÑí?² ý endstream endobj 8654 0 obj << /Length 264 /Filter /FlateDecode >> stream xÚP=OÃ0Ýý+n´%bl×qœ T”h¶ªƒI®)& þ=n H ,¾ó»çó{OÀ+Øë‚\Þi 9Ï2P!SiËu¾‚¢‚=}`*¥8¼àÐ,Q™¥WÞ7u馺ï"pƒL úÉd 6½Ç!›ºÂ‹Ø?cƒnÄx‘\).١ؒۂ¼¤ñkÍ3‘AÙ’ýA@ð-¾Ê-|Y-hcCm`Gžˆ˜m,õ×®Tseþ½êÏ$tÐ)U Bä k]¿9ÏR:±S2Ñ“á,1:§ë¾eIJ}ƒ !·ŠÇùE8»rž$sª÷±q]›ÊM'¦›¾=Žç´›!µ9³h endstream endobj 8726 0 obj << /Length 1467 /Filter /FlateDecode >> stream xÚíœ]oÛ6†ïý+t™3+Rü¼”e%QcK®(7é²Bh×mX±uG²ìX2eÙrƒ•rob#%žGïùà!×ùÃqë‘Ûøœd£WW;˜"râd¿;Tq„™t8SH0'ûä<\Dñ4¼¿|Ÿ½Þ |uÅk£Æ”ÐrØX¹ÈÃb5Î/ÆÀ¥ÌQHq‹+]g ㄪ®˜æÙ»E˜‡÷Y˜Æþl5À“[$ÌGWøÅenuW¾u‘W>´ºæã?Oÿ¼æ^|½$ìâ×ÇŸ~3ÜžÃdäöíñO+Kq¥Æ ?©äÎ0}ç—éõÈy(Ÿƒ•j"Ú¶{ŒEDbø‚‘b¬nÿUΪ¯s_ßæ‰ ‰ª8Èïœ(D*jæ†×‘)„SÃA™Ü P<‰’ŠoÐaúÖhÿÀ=aš–Š/‹$ÍLÀˆºV@tPˆaÒ ¸ñm˜ž`H`nÃëï°žzH¶?.LscˆÀ¥ö¿x&ÉÛLÒ0ȢĜ±+«ä€Ž‰ëµ@ˆâÐäùbõ ´/; SÍÈ¿e;·ÚñeÇ-A_ºHQnƒî»¬WîÞf¾ÎgI`ô|{²ž€­5&zÑ"ÂD«‘@8ráµ×äÒ‚‚0~>(øŠ4ðˆÅké.ókégó§¡&Õ)_S>ÛSxÂ|Êr? ®’ezÆA¡D¡o|œ+žû¡n ‘À“{ª§0”è¤Ñ\ÊOcŒåî2Џd/O!Éð¡lZb¦mlø·eÁÄ3–¡¹Ä†PB:ªPˆ‰„vqmä`òy}k2ªØȸVt ¢1¯XX |¢„ƒÅÄÞÅÊ“4ÇŠìq©³cµS¡Ù©ä5ˆå’¢âHg…l¬^èÕ 4?DT/Q@ÉHa¯É#Õ>ȃZ½ìóŽïï(2É-0¢lÈ<`5B=o?vî2`ç%ƒDQÔ`§ì‰ÿï  rS×;@ag(ŒƒÕi©²˃L×Êy“`¸B\yý#˜Ü-:<¨$ÔáEœ»EG#ÓîAUUµ¦Cêõx¿ú~…œ[YŸJ‡ê!„·@Hý;»!ðþqtÁÜ1±æ˜ô7ƒ€í^òã{[JAj.+0’|J€2[‰æ†Ù¹1`çÀ›´¥kˆÓt°Y²ÚÅ QQû«5{0×vW ¢‚,ú¦Eÿ´Á9¸C¼œÍÚöÛùÞ¿áXùÚô4 {W ƒ|ýŒPÈßly ÌŠSP=þ¢ªf¾Î?\´É 8H¬€ÁtŽx¡Ìû"¡5Ë%Ù?,ãÛ8¹‹‡å Ím¤ÊÊm¤j“è¶}I®/™ÅqëÜŸÍ’»|‘èlêg¡±xˆ15¥H†8§õ ¹ÆøqG?‹~‡ä.ëÏ0ý5*z{®ƒAœâ)ίŸGï]çüúuqG0ñßò¢Ï-å“£Go6ÿ.æy¬›$%ªëªÏÇëÏü:¡< endstream endobj 8827 0 obj << /Length 2168 /Filter /FlateDecode >> stream xÚí][sÚF¾÷¯ÐeXÊ„¥¬÷;×ãøzn!JñäëÑ/s. ÀP¦`µSɃآ[{±uz|žßCµøà +œ`ˆa,8A({]"¢vÖ®¼¯‡:jUí³(¬éêǰz+ÀÕtˆu:“?è8I?fcÙEŒ/¯*ƒ*$ì[Ù PÅ€»™ ÕTQR¥iŸ‡º–iõYHU~A ©¨›‡ÍÖï•V-ÕVÙ$—û©I¡8°ê®¬ûXpÀ„5Ç ŠW L†°[ .›í¨V‰Þ0­æg6P<Œ—‹»ßþ}à‰L¹±·ÂFøû[Æþ¦Ÿg ›Î4 ÚBÉW@‚`öÓ$K >]…íHWÍÆŸÍ«v™ógóçÿUêgi t,Pr€„(ƒ7@k K´Ž?͆«Í‹‹fC_TÚç¥Î},eƒÜÅ× Sݾš8ÑÝØô¦ú®×u–@\8÷TV©1uòÐõm’©Ë P”—Àp±>UÀ~ûr`HákŠÙ\ô$îºýIgOX]p3uç–õ/¥ErϱÇPë‚×&ðv‘ÿ0~p$c;µM¶Nsn]»9\8 wz½ØL]€¹ÍÛCÐÉ÷‰Ë¶1‚ä!d䑲¢€¬ö~žbé5c‘a@°ÜõÐ ¯Mœ!c’‹Œ9ñ„wì³q[OÌ(™¾fÜÜ{`F·É—|²šâ ¦(¤6ˆ{عí»Rù9¹‹š¼h¸Ü ãÖ'ØäSϽdäòé8¶Þ m=Ž{NÙì-í" NoD7‰{j:q7_Ó~‰p½m •áÒ2B×¼g•w¼~ O¦`Ä™› ãoú›éÜÙ¬ìû$—.-ã»geç­÷LWêQå*ú¨+‘-Ì?Vêõ°qêVؾl6ÚÎi5sÂÑ^…ÙbŠÇxÅÔ<ÕÁsí|þ¢]` ¡SCF¡ÑÉXÆÝÎ ýOùJºWÉÒG߇ãÙÔS­íÚ­(rA"+­Û¹q<¶*õeë¬QmG­Rp} +×wEbÓ 3RÄ ™?åáÊå(@+¬Ô/Þ¢,x¸´\ºÖ­Õ³WЬµî a§û›X¥ŸäýŲ ÍîN*Ï„ ̨«me“äZÙ¼DEG½Vލ3Õ]àάbwQ3á€2™)ký,²~þ¶œõOIo@ läq'rDÚ{–Sä’Ø"m~65Ý· >ËØßø©¹×£YÆz‘@€¨]‹…Õ »‚¡`ŽŽ°÷í£„ØR“mÅÈìúÎ|w±A ´qëS ÇYùܧRçsø|î¾\ù9 Ÿ»ö2ž¤%V¾ÃÆ &Ò¦ÊJè,ðYòÅŒ’ô‰ƒqœËn£âŒ'„¢l¡—2™%‡$³÷ÀJúÎ$åžC­^WHP`I¹Õ\Žé“ž¹é̉¾¦3ÊêT¨¢6éØ~íÉŸÀ§IÜÝäädgµîÛ‡6ed ‚8ÉBþé­ _Šl6¤¥ˆôMlL–§“Eµp¾ï öõ­¥sÉiùlœï¹iê'òDw¿˜îÝt6ÔéŠÛQ+}\N 0TVúÄÃAI¥/—¾7™eÊfv¸œ `HÛìð,7ƒÎíÛ~Fo¢ØûŒä¾ûŒ–ë»ò‰\.òù>ƒ©¹ÏîÓÛÛ˼ý‚ƒìÖœŠ¢‚àÝ'­(€ {ˆ»õË·ÕDm]Ëe9ûØt¿>CWöE¶(o[Vb¯äàw;@F…Ýpã;,@,ý ljÙèJ’€s²‘ÊaV±Ò‘pÏIÅ:#™VQh@Œå S3ê•Ô-x4`Ù-p/þº~ H,ÛÖsm{¤¨û_M7ç1F!¬>dðŽoZúÖ‡G¶H†Sbs¯ç$d=Qöú98¼ýó¯8~¼}9È3Þû(:ò,™OÆqò6‘—´ød¿AÞSäå-þ|èýÅßtË⯨AwÈò²ü]™ó|šƒl•ç¿ Èb`65qú§ŒÍ?Áìý%æï$ÏÝ;Ͼ%[yDŽáúÞÅ,?}ú°ÚlDá‘®5u;=&ªQ 3”~»é¶k¼¯„w¼ŸžCAóܦú£¶©ò äDga©Íb{›µFÄiØ[•(ÔõfµROÏãm½ÂUÙΪz™úpUϤËÕ€,òþ_‡…bc[~ZáEÓ^2¸IÇÓáÝUéA‘lÆËV²ß’1›é ¥ïs1fý¤jWÂþÓ¨‚.ÃÖÅY¤+õº3€añžgº1î'C)г0¾óôb›Vm ïvùPý‚­Ÿ£Ëf÷ìÇ…{˜rîd*3ÖKëОÁþ IÙEw8Xx™À[*¼!ìªêöÕûŒãÓ_‹A=^WÕ =G“oý£Îßd x»·]L`š¾øó Ñ³QoþC /­É®å\1ý® endstream endobj 8645 0 obj << /Type /ObjStm /N 100 /First 1010 /Length 2710 /Filter /FlateDecode >> stream xÚÅ[ËŽ\·ÝÏWp™lجYE@0à”HÃÖ"‰ …c#†ÆeÀùûœâíêGNÇvZÌjØ÷qxn±ªX$ÏøP-­ø^”ðW­÷hÌÂ,¸(\x(®ôV¤­gF市û<¢ÑKçõ —>ú0ÇÃ}Y÷­Ã¢å…Æ‚ê³Iô7Z!-*ÜZàtMÇ]›1£¥…µÉZ½p—À->ðìM¢å…çqw‚·EoxD¸ü‘èÍcÑ›I‘Ñ¢7Ó"&}X/âÇÝQ´w-¬²Þu|ÿqwÕ…ì­h_wŠŽu×¹¨¯w›Ç]-½£ãµ0£ÒEã;ÜJW[x‹¶õÆ,ÝÖ ÍVúÁjRmõ;¹ŒƒÕ˜þ¸«ehècb8úBž£Œ±§° M/xv!Ïb-îZkÅ8ú5 ”­ñ6 Š) –Ô¢¥ÅLCŽ4·õiDÑðõ÷ß|óêîƒÖƒÏ^¿-Ïž•Ósô¥a°õÊs<¯ Èã׈ÜáÇ/¼xúôÍן߿-/ËéÓOž—Ó‹ûÞ– æ‹~{_üýþîô1ðï_¿ý.’ʾ;}vÿÝÃ÷o¾¼ÿîH4ëÚŸî¿úú‹~(/. ¸ˆM~…޾xƒ·#ÐzðÜÃú<ŒÒãçÁƒ»UG>ùÑç½û ‡ÓÿŒ‡Z« Þöÿ2V×w…Ôû«û¯ÆúéÏûµŸ`<Þù„ˆº_ô §_¿~ÚËcž >kš97<óÜ-” ΆdC³Ñ³‘È#‘G"D¶D¶D¶D¶D¶D¶D¶D¶D¶D¶DöDöDöDöDöDöDöDöDöDöDž‰<y&òLä™È3‘g"ÏDž‰<ÏÈ1wœ” ΆdC³Ñ³1²aÙðl$2%2%2%2%2%2%2%2%2%2%2'2'2ÈÿæÈËåîNŸÿ··ë÷¿~ý»ÓGo¾º³Üµ½:ýþô‡ÓÇ/iýÿ±Á"µÇ¤ß©:FŽ{««Zâ*¦xìÃ\Ÿ—Óï^<Äåo¾EÌTšó·e·!a €QeÌ:’[żR­*Í],TkÓ¨z¬N„V'ÜeSÕ±Í9 4V.ÏáQ{óm$¼¢@B)“D‘Û{5d·NZ{—k,ì†,X*E±?¹¢6Ø€×>} âù¥\% óDï¨Ëf«C·™¢ÃðHI:<€ UEu¥æ9t›-0# k•Ñ;‹VGÉ©cT”“×Xø{p Ä+2Eº…ÂDf¶„W‰…¦ QÆZT{ K(Ã"¼‹Ä9L•²õ¸„©JC¡´Í! yÓÔ%BÈë¤}¶8ò¦`Á ±ò>ò&Ö™uvÛ< âWÔ9 2{mweïó€`a…l=.".˜àÆæ‰L0Æ®Êy@™«MúÏ$¸µ’@ÖŽÒ[ys;Oƒ)@ªOTc‹s}#2*jó,oDñ×·™"ǃ‘'¥_ÆC¸x»%à¢öXè R:¦´]$Î…ž`¹ìÜ/…žU¡¾m<Ž\ÁŽ¿vI,©S’Ô)Iê”$uJ’:%IdMdMdMdMdMdMdMdMdMdMäžÈ=‘{"÷Dî‰Ü9uw–º;KÝ¥îÎRwg©»³ÔÝYêî,uw–º;KÝ¥îÎRwg©»³ÔÝYêî,uw–º;KÝ¥îÎRwg©»³ÔÝYêî,uw–º;KÝ¥îÎRwg©»³ÔÝYêî,uw–º;KÝ¥îÎRwg©»³ÔÝYêî,uw–º;KÝ¥îÎSwç©»óÔÝyêî‡Õ«ÛžP[3L ~9¡F}‰²úê5o¿©>Ö†¶]vÕGìh÷],òtx¬=m¾µ©-»X¬cÇøÏ„‰ŠÖÖÚá`ÔÔm¶8…? ^ò|¾Rç”Ý,¤£¤}<¥(ëšØn,ˆ'¶@Y×®nR»½úmPl–‹úm ¬£«‡ïƒEŸ³†øúµÙ6[¤@ÔcËîQyÖ±2fÚf‹³*²zÇT›ªÈîˆØ±Íç Þr%æ–ÌàÝ9ul‘'BîA?r_ÝC%º}ê\BîÖ/©3„Üruõ¦,ΧåKÈýxX¾tÜW÷PǸ½œ$ö†f°8ä$±Ö«[¨ã–‚]LÜb'B–¾‡CöÖýÐqËS ¾= ´ä=¡ã¾¶‡úHâ_Ÿàñ endstream endobj 8934 0 obj << /Length 2275 /Filter /FlateDecode >> stream xÚå][Sã8}çWøª.ÖÅl¦è…ÌìNõN©Œ£€ ÇNÛÝ̯_9 ]–¬Ä¸ÓvÏSBðí|—ó}’èÝyÐ;?øe|ðó™¼ 3o<õ°ð&Ç}ü€xã‰÷áðݦ‡*¿UyVc.óyGagéêƒSu„ááãÒ&Ù\å«ÏñDý´z­jõtô×ø×ƒáøàãÒÏ=äq¬oí¹Í>ü½‰þüWïÓò¨™ç3¡_ïæàßð%F_`©®… €„¯`<ä·T†‹ò~–auëŸÏˆxy<¾ úbË£ÿ)\ÄØ‹ƒ H<s¢ÁPxX>Í•áz˜Nü×C?-C€¡¨qýO}KæåÂW^Ÿx–×GŒ®N\CÝÀy€jÇ€RXN¤å!€`ÑõLÍtD.é#›ì7¢\ŸÔ²´TiY‘s@i°r¾ò}x1 ªž¨ô®¼7Á†À ¯פá×:|ÞÅ‘6‚‰~zÛg @ϰٚ”¯¡rðûø_§ƒñ@.OåÕu;î¾]ÄIy§+øù‡yÞ&&þ`š¬oÁáz#pªÏ&¯}¿a„÷òêýxtuyc2â]üßQ; ì×ÚA¿‘£ËÓÑÉ`l G74encp 8z“1Ž‘Ð÷§¹î2 € ¨Î6'ƒ‹‹ÁI¿…¼5Q†ã?ßååðüj<T c² š…§â‹9Ž«ÓôÃæ®Wf1•.̈Ò=˜JëY¥Îþ+׿$Ú]?t4`ŒÕÌèL^þ1¸›,¡}‹iÿ3k@´ê q9Ò)ó›ücx=: O5Ÿ‹&iÂP#“¬Ò…j&Ó²üÕ£8ìDð2³¾½8ò:3½;=‘£››ß‡§½®Äd‡Jl”eZ—U5øOyvu]YeßDK÷E´þ‰öêæLžž Û¡~¯xñ<«Ï µ<{3¼\ û­Nü·ª“›Ñùåxtòn8î5yøo•ñÿ]âwò½Y­b¬4øâ!€@$újHoi\ø·Ü­ÛKë3¨°41TZVÕÌÔpÐ!ÃH?!k…)œAõW–Ç/ËÒÒ¦EfÌwìä ŽªNÎs‘¤B×Ü 2wyÑ™ Z1«¯‘D{7pÚ(ºWÑC±˜™Õ×ÏÊ;ÚÙcŽÚ(´ÞEx>‰õ­ŒAºƒ @ r{¾Œgª•’¸ÇΦ :o}Q¨èŸ ÝÚÐþñ¡ê£L–§EÔˆ£~f|è†ÝXÜ>¨§™í^2ým–%*LMjTW|J;)|êÁ¾ÆÊ ~®ÄøDÎó8ây˜´:O7]¤ÑrfÞìå  àØ=Q‡aà.Ã$É"ù¶šá{±À).ðPŸË6é½ Ø5¿#²t³ÛwÚî:¢®™yLqÉ[貈ÿnu4»Ì8¨ÇL H(=’ÏÃi_Ðx† {+Z†@÷J ntx”?ÍËL~ƒ•{qº ¸•â7Ë8{ìÁ9ÁÛ.’µDoZ_¦UbsäìZ Ìë [ݸkµG;`Wwò…v?*]ΦódQ´º¶n?бsuO#««´§AŽùr?ƒœ4ògØ5å»ÛANvò¯ WãGe³y˜«J¿©t™æJÉ¢ ËþiUè­:ý,£)Ö}67O—w\°ù[œÆe_ýMwð÷êBçv’è žeSiU!P¿'ð7_7ÌA) Äc„†ýM[<¨'5±›¡âytV°»· ø9ø×¸Ÿªç¶Ù5„úšË 6l3Àª¼ýË~Ö8ûgგu³©°Z%úмb{fVï¯ï{xÞŽ²á[ Ï‘Ýíy˜N²™´L®l­ê¾ãySU7'“8½siùîêYáæxߌ<ŸžŒúúmw+»-„rjƒkwrÇ ½y«ÙÞˆÙº)ÑIG×4%Ö<¦óZVË<›·:YÜ ‡WÓÅ Õ¡_2z•ʼÍóGŸu®ït÷aã*¾_(5±uãDW‡*®ÄšnÜv™Ù¤K·;þ.SJ¯É½(óJºü#S;rù).ïµËÙ‘ìtÊ‚ìhÆH­(ÚØÌ¹±FÇùÎ{9×&y “xÝ©°~­A§5¼z†_A_·¦{˜¨q<ª<ž>ՎصÓêìðÅÇN§sb$¿ è¶!;ú–¨«eÏ_S Œù&Ñ" Ëún Æ@øÝ]5ÄÜ«†Lë£HÃ×°µÈ-£ûV¿×b1Ï·øb ã¸T¸“¬P¶¯ééê 3v4gÕAÎ-€µ†—Q®&Eß$-o¬h5êE^w;5´óE¿.ôÿR¾Ùk¸5 ‰iå„€ ð»Ú¤pÅ5fRK\¯!Ë4œõO±¸€ÛK\k÷ì©w¾oðõbnZ¿ܪó](ÛÕg¥KmVéDV»TîTÙ¿ÚÌv¨Í,v§R™ªO}‹lDßÚÚǺD§Óø®o뿜ž®)ÏêiÞõnj˜7ž^ƒ^$‰µd}³y²Vó¦KÞVÈ- ˆó®îHq$6A‹šÄ®Ý‰Õ鎮½öU¼+äµÜmoͽ]-u‹ÃIJ §Ë4îB]Gã³ìQµ¹±² <†ôiÌ"Ì´8‘‹4þ¸è—];O꼜ªÏ岃лbÍ›ë\UÁmƒÝq .škð\YbÌêNkpW|×Ið\•y¬jœÝéJÍEs]V¨DE½Ûoæ+[*Ä}n‰70x…ÚÕ/ëòÆIÑtßä z/Gš5]²VMî‡yY×Bê4£¹×2Z™åV"ïv~£7ä÷b>Ï*Š-óyÞR&pÃu ‘q§+Øàç×Íß,¡>ÀlëŸ,ùúgWô%| t²¯x”N–¿§òyùmu>E€ˆ/ŒùëøÓÏòkÑ endstream endobj 8829 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2665 /Filter /FlateDecode >> stream xÚ½[]‹¹}Ÿ_¡ÇäEWUª*I`v×8 $`Ö~Hbüàx‡°d™Yü›ŸSê®k'ÛhŒGwZ÷¨ºT*ÕÑÑô&–JêMZ¢Z½Ñ›yc¤:Z’ÎGJɬyƒS/äšFeoH¢bê-MD£ß¡e9Ÿ\¶§=‘Žî­‘¨U±’¨›x‹ùÔ81mOkbžßEÞ,ÂG†I–òfþãÍ(ÃŒ:¿W(æx­¤Êói£Të|Æ©Êün«©ÚöTRmÛSMµ[ÃÍ’”âNj- Í7j= Ûl$u¸õ½$Qv¼NIÌü“´áx½&ìŽí’´¨¿Gפ4ctƒÙmî-©¨ÛÜ{RnUIûsÑÕÇÀÃÇœŒØÇÀ@ÆÛSIV·§šLÙ}5 Ó§nÁhÉ­žl°¿Û &¯w¼jÄx‹¦hx‹SŸö^jÂ,Î~’àÍÙOÞjÜ¡e ˜³Ì šýð2Œ°B PÎé`š’x  чoND /3ü¿Ž.£lO5 j>†u{ÚÒíiOC7ä‘F›È\Òèó)SBX92^• ùH£Â2{"*Kmþ*˜*B˜÷Q½ƒÎW€ïñ.âcVD+YsXÄ'Ñ|Ž @Ô‹÷õ¯qi¯1OS˜£iMź€?æ×°0س¿ Ù¶XÜgÁhµL£UÇŒVyë€Ñªl0ZÕ­F«¶uðUØ·¾Æ‡ô»gÏî.¯ÿùË}º|ûððøéîòêóß>ÍÏüéáw—ï?üxÿáMAf(o/¿¿üáòýšî.?Ü¿ÿ”Þ°Pmwv?°ö<0½2J6F·oÓ³géò*]~÷øú1]ž§ßüòîï÷Nümúæ›;üûÿ@þÈæƒZˈfÂØX:°©gú #Œ×ÁÕ²ù2WËŒàCbÊFn”åF·Œ¨O`„HfÏ“a„JFF>Ë † °Ö¤r®˜–Š G¦ÎÈ/§YQò@vüÄrÀžÑò@Z–Z2ÖÈi3BY‘g¤ôLÓ¾ÕõÜû O¬ueä/ìâ–IÜ5—â›™åQå,#HDµK&,R®=#Za” œä BFð¬ZgÏš}[¯áÓBbÏ™(52·-Sx`Ö†y²~Ã+s¦r&/0P‘\°E`gò¥úßm`¢•žh™QHT–Œ‚ ž3QÔªþûs<Áð„`³®„ŸêU¯äŠš«rEœ4ÜJ&fµ 9¡ÈâŽy˜FQF{Ö|x²BaŒ¢;hŸéJQ«ò¹ÖvúÞÜ »ùWøÏÚù,W”†¨à yŠ¢ÕEÓ,ÜN²‚¬ç Žá1j¨Ö©k®¨áذ´[õÕÒàDXxÑx8HŸ+„Õ÷¶v–„d fÈŒTåAZ7Ÿ€ f5>ÑŠé Btz|xã¾à†ÔβÂ8;«à¢†/P~ƒŠ¸q¦t²4(Aýˆ‚šsœí ð¯ÌWhPnr–#ˆ´ýä÷¯â´¯eçåä|¤ž7å¬äsF®(`{Ó³¬Øó&26~^Ó&‰×8·²&¯Ïš„—|ö¬ Úœ‡é™eù9òÓ$„(>½è)§Bõ´$i4äHä‹&yÑ!TΣƒ{âÆ,8K¼íläd*èç_1A§"§Aéxß.©9ëòÃÂB.ÒÉâfÕ¯+€#àñáñ“Èy\Ó°tª'!6«}ëªN†QÌT…MY´Ÿ”#®F€t‰óóÝl#£Ô³Œ,H–¶ó1£·d`cã&õ°'ˆ‰ŒELRǸE=V¡ŒŒ„%iÎüÀ<EŸ¦©ÜdOá g~ã+OTÉåó°¶Ò~HO€ùsÁ~tOà÷t‹x¬4"<¡Nüü<1”acgë'y¢Šë>> ؼ±6«Ñ¤>Z8ë-ÒÑÊzO„å)SçNv$Béú˜˜"TÓkLªPOâ p¾Á×8Ò Vš58ã3½Ö4‡T[xn& æ ¸Fñõ‰¼ébü¡µ4"ö¬í”+ꑵ¨•ž¸1õ§« GúÓÒÉØ·ÐПb =ÔŸ?»þFêOOb„ëOõ‹'õ§µFl;hÈO±ƒÊO­®Ï–Õ’AD#[VgB·ˆèR#ölé"XµqM—‡"X“'ðÄ®]=q¤-5"<±k`WOi`kØ L×À|ûVx„QKj`måáJ¸&¼I`VçNj®ÀI`4d}Yžqc¥âTÚÿƒö´t:Pa×M{Ý÷ó’îX{bZ8u +/ªïc¾Ÿª>K­¿½€z‹7ÔìXpYkEñ#Z‡oâlãXìxW¶ì[Øî‰C­cmTìëƒ$iÔë 9–U,G×óýŠÍœ¹žï/µÁs$Xð~¼¯âçÜv|¾¿Öûdxv¢/Ùêètý?lxžÞôÎ~ ù‡tùó_þš°Øb¬§‡Ï?ÿü6:¾x|ø4_"tί¼°¹"tÿ„Ä…O5ž™Wá‘.¯ïý”Þþ»;^ÂÈ»Ë÷íþáÓÇÔQªú÷ý­?>~þðþ~þŽ·ßýéþÇŸÞ}÷økšŽ2âÔf¾|÷ßNÝO fÇéäx^&u{æUÒ½AÑàhÔh\;k4,-=coH K K K K K K K K K k k k k k k k k k k [ [ [ [ [ [ [ [ [ [ ·@nܹr äÈ-[ ·@nܹräÈ={ ÷@îܹòäÈ#G @<yòä±#R¢AÑàhÔhH44@¦@¦@¦@¦@¦@¦@¦@¦@¦@¦@æ@æ@æ@æ@Že589999÷5øvíEÃ)ö ¹^4<ûhéMªý6°«}¨ä¯·Õ¾µVì:xÈ}¡ƒê}‹}±Ýa ½/î0 ~k­ØoF»à'Èq3úPð[k…úù¨NÅOý²¡ûDøXñ[*~îlfJ~ІQ?UdøCÉoí]‘ýîŽXÍõæÎ¡Ø¶Öû|¸Úæ¬q#µiååh?qe«y®ò{CÎýõXéZjżoéªX¦ÿ…oëóXêZkE/àumj]^‡°ØÈã‡Z×ÚÙîh»Ê„=®hŠLk=±¯RW™¬ˆUz¨2=IlúiAýtÍ#™i鉈_Oo.v!:ü¶zÃö:%áÛ2Ób¶\!Ö‘äš+e¦µVìQqýc§=*Ž„¦ÅFlůì´_?Tš¾²â_3Cº endstream endobj 9046 0 obj << /Length 2179 /Filter /FlateDecode >> stream xÚåÝSã6ÀßóWøfzª>¬¯Gr”^¹£!)síxŒ# “ÄNíÀýë+Ç%D²‚19ž€àÄþiW«ÝÕ®ƒË‡½÷ÃÞÏBH fÁð"à8à¡¡$Áp|Ùù¸‹éŽÊÏUž»ï0;{óùtœÄ‹q–V/¨] wnv‘¾pšÍU^½|x=©ŸªßjªâBU €1@»íõ‡½zH? PuëpȃdÖûò7 Fúõ_ˆÁ×åU³ dBÿœ§½ß{ð!£0ð c’ŸÓ(IâäJ•7þù®fúJLõG-¯ý RX]ÄØƒ‹ ˆß]³¯Q(ÜYÜÎMŸ‡)à$|ðyè§%.Š’‡ë‚P° ×k/{Á—åç#I«7~}DùNH9 Þ!$¥+¨I6’ë¼ÈrÃJBÈ7O&[FX¿ƒ qt‘+Óc"Ä¥² /®Ód©ñë"Àe¸aÀ¸‹ •œsúüz<]¼§óM™€Šóq|>5¦nôÇ Þ7fpL )mäÑ<k%oÓ–¿¼“ÊÈ0!ìÈzn'ãyóൟƟ৭qk_e¢L ˜`qîkJQ80°xdÍ?ÞÓhÐ?0=˜”u!¥ˆFqÀ˜Ñ)׋v+àžäÔt„É5iµ*M¢yœ/Ú´áÛ«…Ó„[²§¡qçö;$n­}.AÁs{•~D(„œ­Jæ“a–ÀÖƒ¼ŽòQÃ(‰ÜÅšg§m5Ï#•d#ußQ¼ìPŠÇ©y}ã²8áá)@ea5ž…ó} ìÙ˦[1^~´ÒšÆV±Ë5»Íã¶sœ™Ã{Gú}Œå<]Ä‹N(í˜×Ö¥+Ôú#½§±¶£ÖáÓO^:fŸ÷Ž>ER£ýÏÇ'ƒþéi§3Yâ陬¥¨ªçTiaYAñºõÒ9Ï­½—e¯ÍQ«îÒ½™^ž@KL åw° ϯTn91ÁëVܰ¥ã½FŽÎÕãf…÷Ü“›4Û^æV˜­¥#÷зª¸ðWZUXÕ¶bÛ‰å!€ˆŸgèÒë9ëkøu©oÆÞ-}£N ÀÝÏÇß+¤0Ûøk…ŒßŠb íbõĸºm–/þŸ³:JG˯Bú¶òLúYþæ endstream endobj 8936 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2684 /Filter /FlateDecode >> stream xÚ½[]«¹}¿¿BÉ‹Fõ!•faw“@f×IŒï%,Y|Û ›ŸSê®qö!Ó†h.Œæv÷ÑéR©>T5½kO%õ®#‘(µ$næJZÈœªTHj­û7n—jÛS-QÙ³D\è£Èí*Àu>ÙJ¢6m”ÈD|ĉzk>’Ä¥8¦‰i»Zo„p oŒð•A s”[þ¿‘¸ÂðCü £$Åü ã$\ü%L’ˆ8Ó$Š Õ$m{¶%1q.fI@sXO2Æ|v$%öÙzIÊÍŸè“ Ÿ­sÒ*>[—¤­ù]“ÚðÙzM:¶«-Õ²]µTi ÌÑ;d<ß·Tu¾ï(©n²”ªÍ%X‹>ßw`1Êä<45šï ’çûŽ–š—=¨µ*†9@£5s鎑Z/xóa·áÈÙ\Á V>’„%*>ÒdŠEÁ¨&«cÞ×’ÙvÕ’añ0êɦ¬F1Þ|náæ³¨É¼JøZ·«x…eÀð6|ò[Øç –0ÏA– Ÿƒ:”Ž'ÊHC«£pI£GaJÃØQ˜ÓpuÄHÒÃQp á;†C†âbèÚ+ݶY©T.˜ô Óu‚B‹u /Le¾‰Ë¨¨¿™°q$åÿ¥>o€Ž3ûnq}ĴݹBùˆ+Ïǀ˭B“‡—mÞ þ˜¿†À•2T0¤IRÕwû ùl¢Û x ©f›S¨ïÂ>_sîqÈááÙ³‡Ë«ÿü˜._¿ÿôéáòý/ÿø4¿ÿùÇ÷ÿz¸|óôá‡Ç¯ ,CysùãåO—o_Óüòpùîñݧôú‘­¹ês†±Y[nÐ UÎPÜ÷uzö,]¾O—?<½zJ—çéw?¿ýçc¦VŸ¾úêÿ? .šV]¹dè 3e_@•’»êI$"ð%“Ѳú"éÈn3´´ ãx‹E[(ŠÖ3A»¥kVè÷šKsV‘³XTË ¶º—aÏ›æê¤Zrš(*gq3ßJ®æbdìD1‚DúÙ$´ç{$êÈDr6 ÁîlŸ%¡–©ž& ë¹ÂDk6Ø}5+ÜHÍ\älÍ$(8…ÐL–Ìz–(ð€Ä@PÍ„£OXp!ÊYÎ…fÇBt, Ü«d86]Äþ7 ®‹µ1[˱ OQ€“eé|ƒÃâí¡n¥šæ&}~º‹fƒ†²D›Û 9™†ÒIÀKã«b7$AuårPÍ>¹–lð ,û.©®*7$8e¥(à¿3÷lþY{ö8’eäÚn‰BʶBšŽ¨æ~ZÁnAÚY,B7âx†4M·ç8X(Ĥg±€¡ò„‡b°ÈàC‘‡²qS´⺂8œzÉŸ,–a”Mé,p¢æñ8"­ü hn/È ÷›²à;¬üYAÔ+BÍr:‹E¬ˆ"ÊD>{]‘ 3bõ ¹ÃŠˆøR^8´Ág‘ØA$díj´@(vSºÜ~#3ÍÈúÂ|“çEt…Ýnø3?´ÙÍ&²b¨ÊÉr@òãú°‹‰ÙM!¬ô£ †²ú±I–êÑ rÁ‘“ÑÍ|t%EôâGæù§ŸXÁvd°v3ÿYɢ䥦†h©_ªˆþý¨Ä èf´TÞ³pjž€"R䀆H¯ Éýf$måŠ ¶õÃSÌŽä/)‚\í~q3ZÊÞRISó´öT±16¼!²7S ±…,¦‹=ìU˜ ÜÙ¸™-%á[Iyó6Ê·HóÓ–Ë­ˆ¤/$A.¼º§ È€ÔÉø ®`§t>‹E줠Hþ>ïfÄ7e±0òWñcJÕSÐyŽŽ•P+D;vš,à(Òñêû“ýl^£:«ž™N“E°ð,Å•Eop¬|‹ÍZT¤¡È¯Ö¢rä›Y.Ì?´!€ÈÀóPdAjðiÈ‚0v6'%Çn¿;´BK‘nö1x­%Ë8MÁÂóP/Î ñ@‹Nb!~º-^Á‚/~ÈÚf®^Is½™(­÷"®¥È½Â‹Ô¹ÞL?–’ØD=È“Ï ¢£ä›ût­$‰yLáùŸÕ) 8µvS¼2Ø£mr¤^¡„gëÈÔuƒNâ n*áÉòZµÿÙÍô£®Œ±Zu½•Å † ÇIUÅl¥µB6ÜûVC ¢HÑ»Ôã¢Ûz»­ð4c ?ðˆ§÷³Ä€°Ê(¼,G³<Ę$Ërc% …»ôâ §€°PØðhÇe¹¥«±*¯Ê±`‹tž©ùaYn)‰Tƒí¿$qT–ã¾V)„zQN”zÈ-ÞüqT•[Êa·^”óÝ0‡U9kwX ¤å:ÝaUì Šrµ¯7^”ó>Ž0‡U¹¥¢Ø3 Y”+²y­jÇE¹¥$öŒ4jrKøQæaMΖnÑð‰®59WŠêՠâ\¿ƒ$ö¢ÜU‡E¹qIìE¹«$ŽŠrKIì»#Šr±;‹rKI0Éz-É)¸´RKrv‡h"*rWAUäV–ÂÂLDA.ÌÄaAn­$6ßõ¸ð‡õ8ëë}G”ã“–ã–.Çn&¢fâ°·Tû±Uã´Ò—ãìf"jq±;kq½¬?.ŠRœg_ÞòxP‰ëwØ Qˆ‹ zXˆëtµÜ qW­<(Ä-¥°ëÃ^‡»ªÃQ®ßá|f«Ãé´Vã ×yýÆÜËp±/êp¿¥ð<½îCÀߥË_ÿö÷„€ 5­ÿû_~úéMÜøâéý§ øÂmÍŽz<òÂ¥O½îß<–¡.q­y†Îó`./?<½ûþÔÓååóéòêñ×OéÍo¥ñ.ßb¶Ç÷Ÿ>z«qóçý¥?>ýòáÝãüŸnÿûËã?¾ýæé×4åÔˆ“Íøòí<º!ΧŒ?bâÙ¯ì|f·ò>è1û@K âfåH 45-¬¬\¹r äÈ5k ×@®\¹r äÈ-[ ·@nܹr äÈÈÈÈÈÈÈÈÈÈÈ={ ÷@îܹräÈ={ @<yòäÈ#G @òðŸnìŠÇ@b 1¨1h1°ô22222222222222222222²²²²²²²²²²²²ò¾ß,êSEP%PÉÙBU iÇë´¬<;‹ßÌïˆÜcpÜB°’Eô÷D 7ù [Vú³ètŠo®qQvô;t:EÁUG kIl}íÚ6»‘9l XJbouŠþè >l ¸GŸjô\Iõt]ÙÑÞóü9™·TOL·jÃqûÀê¿8poÀ–Ø~ütÜ>°”…ïâÙ>`¼uúï*ÛVw÷«ÿdÓ3?Âò³nÿyáaûÀRŒÙàQ½} S›Ê9›ŽÛÖ²ØÚT£} ÚT¿ }àÊâ?1pK> endstream endobj 9151 0 obj << /Length 2247 /Filter /FlateDecode >> stream xÚå]]SÛ¸¾çWøf­õ-]¦rØv ²sfNÏŽÇ$"xpœ¬mJ»¿þH6ÙA²ã;Ü4$ul=¯^=ï§ß›y¾wvða|ðëG= $CÌßxH€°ô8€Hì§Þ×ÃOGˆªôZ¥‹ìèqq8X.ãhæÑ")?8UGÈ?üvõ…ñb©Òòã³ûhª~)ÿ©X…™*ß@€€GŽ;Žþ:€z<¾=Žô£ à>÷&óƒ¯úÞTþ›ç,…÷P\5÷ú5ö®~?ðŸbaô s/èóÆ]zM•L‚»é$HÕ2X†iâ0Ëõ»¿ÌX~ýˆÅ“@*ñ‘¾}ñýÿúÔ/¯bìÉU`ÈWלhxÔ?œ«¹––å–ŽÉ“;Â_ !øù äú?ÌK5¬ŽÎ¼¯Å Gåá¯a?F>„bïB )­’À<œE|‚‡°—ð¡€3´ülä?–êý*@²H&êý*@¦ÒoÖÁBM‚’l‚_l…ï¿Ä@Ê~V?Ë ‘ÛôŸÈû*©mÌF Gs•½+ýÏïòºe„jÊã ¦ÜÁ¡ˆ¶6á¸1Òß ¢1ïóÛEý]8/Á4ÌCÛÌKD[J`lfþØ\ª‡Að¹|>»V@­gBì@F†eˆ&átšZ ³æ°F;8Ö³|øèq¤’|Ÿ¡;gý&göIGZ;eG@ tÆ uÈðÞ#¯0ýDû €ýZ}wZý½Ÿõ< “,ÊÕ´w>ÞÂçYãøÅTÆö‹LIF‰Ý7únî“In_NF²RöQ¸ö}} ÁðâäËàt0£áïæ]ðÅüùÅá÷3,¶Y×÷QœG&$ùá7“1 Ó(¼Žm>!£š[^' =ÙúùtÍ—APTJK ¨ƒÒËÜ5Ö&DX§ ­ðeÕ+êïé‘:×ñbrg ˜Ö€~†0!ê ƒâï…þ0OØ–‡Ëm­€D²‚Ë”j‹ZÿHq“Wiý£Dî”UJeG ©1‡&Œ«îöÿ:ìó“æ>=‹þVm†ÿ»¡;^3mükßALùýç]õK¢½\fwvÌØÍnI8·&v}|)º:Ë5.¤H[ºgÙ Ïò4Jf­òÙnÜ;ZÏhÜæÝF—#ËÈ´'÷|dÛxrÔ¯õäôío8‚²Æ¬# ¤uÒÓt‘¶‚¼# [›xA¨ ©;EÕ˜ºw·’ZâvänKÌ&X· P09暈Ʀ.lü]B¾ÏÔdŸ!¿œeåJÇwZ³é«4ÛÅ^{<Í.w{!;KÌ{ÌÙÙûãììýqv®¾Û|áIX?õZ;zRrâÀd’ÛDüóÝÍ åKÞïË0™·‹,ïe ‰aÓ8òû2JU0 ãø:œÜf°mÖÈÞ|Êuù¢BV„‘WcSøã|4õR@A¬’Y~kS~¨=(ºesL)Eøù2vî;ÅúbÉw Ž!b39ÏjíôݬáÝ6,Ò‡0ºàÂliÝÖÊ0Éž­! £oº†V¯ë?‘ar®lã_Èxù+ú.|1âódZü|Ç÷9ÑdÅ? ÖÎÛÓcùÁ늢 endstream endobj 9048 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2696 /Filter /FlateDecode >> stream xÚ½[ËŽ·ÝÏWp™lxYI@0`[P Y‹$‚Š<ŒCÀùûœbw]Ù ÝNzÔLwž.ëÁb÷QK*©J‰„]àÄV]$c¸ ©n—j23,µíRKc»ÔS—F"ý®+€Âï à:¯'ª£¹$‰ÚvUõíjM4¶«–˜Ä‰YK̸RO,éÙH\¹aŒVÀÖü¾F‰ÛðûÞ`°ólx…RhÓ$4œi«I„}´fIÄ!µ$u»Ú“´íÙ‘¤[Á½¸"üj§¤ÄΠsRžÈ]’Êð÷èš´Nä^“Zu”nIÛp~½%ìüzOµlWGªxuŒ[ªÿPUÕYaÈZ»?‹×ªüÙ¹è:ï«©:]H–ŒÈ@uÆê FO&ÛÕ‘¬ÝR ¦Ok‚DÉ^'@†$©m.ij„W…T¦h>wVZj¯©§Ö¶«#µ®cPeÌ«NˆæU‚êœ!áo $+þuÚDö×oÛ³n4Ÿð êL ÿPŒÁr¦ ’Z)ã±Ú}4¨¶àO`*0þn˜²áÉ`§Äó‘‘ë|Æ­Wú|æ[*3ÆùÁ¦ç °S*­;˜;•áã “Ï$DØ0ÑD1–Ò¼£‘VMÁhT'ÁhÔ&ñÅÒ«¦e®SŒÆ4ßA1óTæ†Xæ¼`ЉՇ ,_X¤«¤(èH•²iŒ“ Ñỏ‹¾Æ±^ïž<¹»¼üï/÷éòí»wï.?|ú×Çùó_z÷Ÿ»Ëwï¼ÿÊ=Cy}ùóå/—ï_ÑüáîòâþíÇôŠ©fLU•‘ ¶ÁÜrÃzªµd†Û¾MOž¤Ëéò§‡—éò4ýá—7ÿ¾ÏBLß|s‡?ÿ?êšapÙÝÊn§UzV¥/s ¡ëH@÷Ya 1¬D¶‘þ©²eí74A*À¢Hn06Íâ~†4ï|™E_©ŠÂÝÍ債È42‰;;εÕ/“Û•,4»…ÛÍî)™)vç[²ñù°¶¬±Q e8žÓ¡­ÃTëY$*Fñ dsðcÀf¹ÑY¬gÏ TÕ§9q¯ÙÜbnõ4Mç­>Å51à®@Š3ò˜3I ~+ÃGbœÄL ìT϶‰Ò³gwaÔsïgiyH ¿–ÉóE,ÍŠÄD‹å!·T1êBUÀC3© ŒÐ\¤=3"¶ 86Nò™ðN—‘tbp…È bÒñ?ßPE_© mpÜÈ•­dX%rk8îê™0ÈY?‰4áY¬(,“wM ¬‹“!9‰Ä–ÖˆØ â‘Ö…Üà`+XÍn†¬Y‘03µì9¸HõI:‹CÉ„TXy,ÉC:j(–Ìz–"Â,A‰Íg³$ʲÎÂÃŒc×…§)b+Áµ°ïE Fžv÷ÓT! ‚…♕æÎ ™ÐÙ¦á%ñN¢"Íhõ,H·yTߌ͊àl›Éà³9À´égÓ°Ó4¬U§oàÁS™YØð-6ÄS:Y£ÁOÿF¨ÈJ=MžÑÂPŽ{%æ1Ý /ÈNb°ïÞAÒ®{w^ŠÝ®…Ç:ŠÄÅÌ·½‘g¶>÷­,5D²v«èy6à X‚"I¿Uó,æPææ¡auˆµ¤žU6P$ýl¨9•øJql9{6PihmûlœöÐÓÜÞ·‰ +´ÎÝTX „Äjœn(:«~6 µ\n=kIžE¨¡èä×Jcî˜Àst>[¨: ù\¨‚Ü-U´²„Íâ?UTæ]ȎѪA9D·êžµ,|ÓV9U¨À›¤Šµjpœu ¤ÓÌ‹Ó{¼‹µ5ßèG9†V;Šã³g•g'»ÎHE&· Ÿ•ºPOd¼OL¹#í÷½}oÓ¢Ìr»ðYÉÕ… ­ònà@éS‘ʰ÷±ºc(=‘^]ó°¸Ö8w¨ÃÆoY¶—ªKÁ÷‹* ±¢³+X`‡ÝÀµ$vÛŒvàÕ6ÚkYpŸ»VÑTTbLý¸¸”ÄCÔ÷ñPýì1丸–Ä–ÜD;pKn»+) æš[‡Ñ ¬bn ÇÝÀ¥;gŠp…,ÿÚ œ­û*Çí@ĸ…ºÀ¢žZííÀŠÿ»!:ê.f10ÅýÚt?Eô Áµ,à˜À`6U)œT–¯i®eÁð–6ûêg'Ô·6¿¢ø(â Áê':ö 9l©=„XÁí× 9ì.e¾{¶‘[…ï>l R£G˜8+³þyFŽš‚KuáK£cζ {1„¼S¾¢-¸TŠ o¶« ®Ò äŠ4§·ã¾àZ{fáÛwÝKä=³8l .f¡[?¬ÃUº#7šÖyØ\kìA«][ƒžƒ7‘ãÖàÒóg ?á'#£78k2o õײ€¿°zmº»@QxܤÚVîZ4oß3¢‡ŠõÊ~.ð¨9¸Ö6½6fÙšƒmËÁýˆäaoPu}¶½ÁÈö{ƒkƒˆêÓD-Ô·BÝO>ö—Zt“$̃ŸVÑé?›ƒK­b¯Ó÷æ`”éÇÍÁÆëËozd+CŽ[ƒK9ì[H{k0vŽ{ƒKIì;HÑŒ¤ãæàjUÌéÁê·© ;î ®¤€Pž¾®½Áʰ ’¯è ®d!êÇ1-yôfÏ|mzÎã¶ÜRU xÿ¼ckËU¤UókŠÛm¹µ“ámó¾œÍtVd‡¹ßsxš^‚z¡¤éò÷ü35JðwÓ¿ûôóϯãÆgï>NÄgêßÖ ‰›³øQR=; endstream endobj 9228 0 obj << /Length 1874 /Filter /FlateDecode >> stream xÚí\ÙrÚH}ç+ôhW…NïË#±±ãÄc3@*ÉdR*Gˆv2_?-W·6P yñ¢RßÓçž{z:·tÎ/úçg9 (޹Ó9;‚J@qúCçÃÑëcÌŽtt££pvÜÄBµ¦ÓÀx±NNõ1†GwÇÈÜ„S-.ŸÏý¡~¶ø»«íÍôâ0èøcÿU£Ýo|i Óè Å«)P8ƒqãÃGè ÍõWDIç>½kìP.ÍïÀé5þnÀå08[ A‰X„ñ9ºaî­Ž]âÇî ÒÙNc0´7?¹?‹“=?#ré1HaÀ6/IŸò/dpqçKw@|¸çä¸I 9ëq3¹Õi"ÆÊü€blq—ÁÓö:„”KoCÏR˜ ÀP&8j~RÉÈþèb÷¼á|hbà‹~h &#€“µ&•È ôä6þdi:Q@2´úĸÄ\Iƒ \vH(‚Ð'€DR  . IøÕ÷nmëCÁÇ¢*e ÍÁ€l>½ M$Í+ù÷ðøâIEØú4 ’HOô½áÈÈŠ‰€HZÅäJÁÇ­Ù£4šyUaŒØ*Š*BSœ2ä ÂGŠ¥JæLü9Τ‡ "RÎy lÉ€ÕŒadÌ÷,{Ý}ÁÜóvß½¸ºè»'ÝöiϽîôÝÖéi·Ýë¹—½¾µôpóúJĸ™ûAÜô' cƒåjwI9÷¢,ñ"8m÷öÔÁæ%0¦Î—aŽëA8°!Ä(@b“ÔÍ'ƒÔ¿Ø“GÕ‘<¤(wÀr-w2©ru}õþ¯ë7½ŒäQoÄ“&6Nå:K¤Ñê5Qˬu™[ê  ÊZ äåÀ:Iк8i]^üÓþùyÅŸ:¯På¼Êêå¹Ûy{êvºuQêCªÝßiªP×ÓÙu÷m«{Úzqù'ñò Ú(ÒºV+¸õÌx8VÎ ¦—FžNŽïvfi5FÊ>† Êrð$ÿî?‡Rà;ÝvëMÿåÉ-’ÜN÷úÝE–à†3ĵ9ÃnûªýÖpê¬}€œÂå9U|½Ö¥5é°Äc:1‹°àÈ•Ñܦcv¶FÑ"l*Ls¹3sÉ#=›eÍïcíµÕ® I8ù6糌4ƒŒT.b4¢ù#ÕÖ½FFˆ™¶£Ÿc†xkÕ-£A’?ðÿ?ý‡D6€>y“[íN½Ùì>Œ†î4 ÇÓ¸þ•‡'ñ΢péW ›êßT~J¤–þ:õ#m2,n¼Áç=¥Œ¬•2éhk0ðŸEmd­j³„;ñƺˆ4|7I£ê'Í! ÑWáYÿ½âPANà˜–€+Œî½h˜ao÷¯msÌŸd+ÐÂÒ*ƒ‹ím!®# ‹m!)_»ÂùaÉ4…µRhêYûR ñŽÎ‹ €! ‘* ÜH™ëCqÕêþ vt8@e”·yioe•—áåîfú“c‘žMÃÉоùjo)„k¥PÖ~/A€’Õ÷:‘ÜbÅ€Bõïv¢õΛæíSЪœaˆ¯r†µ¾°K¤)˜vï¿îg®M˜%o¶’C¼’À¤üJª•œ+è3‚{·BZÀ•üô©ŽÆ~ë¡«MK¿Mµur ЮƯh~üR‰3ã‘o%¨ä ±«}Nòc&`)³cíÌìmdT«Ê•¶8ò:öÛÓ‚Þ6énßn9Rûe¨ž&¼5rS»Úç‘sãê²tn¦£;¹Qæ<ÉNG®¶ˆ<öÇÚ G#ãöìªÙ׿óèÅytÇ@¼§ynü®Q9[ìþ µ†SÏ5á['v ±Jn@öD2m#7öT'#ˆ)JTÙäm5jàűý ˜íç©!Y-ÑãÀ0n9"Í;Ñ„ÿõÇÈ’q#6³°°á$Ö_mC……;kcX!Ý’–]X‹1ÎõU¿ý®ï¾>=©GÙ—¶©±â}E)ž`ƒ¤ù!]Ÿãd7Nú'©í¬8ë×S ×>yÓm×Rãv”Ê(?¶Û¥!l¶ ŒMCUÍ%¯á+"C@R”Éþ4ð¬ïú]`>ÃæÃ*?pcô¬qÌø¾ÆM9P¢8îl[»ÓrÇ«Ë-xEaô»ŸŒé»ç3>ëÇnëœØ^ç’yþÏú[ìÝÔêëw!üÄØ+TþÞÎO9?½@2‡åôVóÓ¿dGn8?½¬§û—ø²zâ/Yût«×owܳËÖyjõ/®ÞâP²ÙДFo‚к٠‰ÜUYT.мˆÊ¬¨#o2 ÇIð{—…óëáLæÉ.ôœ¡Þ.Ïê2ëVÙõïëb`^ú뺬ß6F1@?©%ÒÉd‡&¬é]L†éWŒ}]i“iËÿ[,_Ô endstream endobj 9154 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2649 /Filter /FlateDecode >> stream xÚ½[M·½ï¯à1¹pÈú$Á€mAI€,’:(ò"0bìÒ pþ}^±‡³IÝ>P PÍvO±ºX_¯§¥TR/Ê©²„ ‰¬… I …`IÙBðd>nn©¡§>.YIµŒkVS¥"w*ÙãoP.ÛUIÕJ¬cšªs,d–jó’'*ECj‰êvµ'"; €¤Äj¸™”;ÖÀ²í*'jÛU÷Ä,ã-±øøFOlÏRZIìãj«‰›ÖhGlW9IÝ®Jßmp“lW-‰nW=‰u[K²YÕz’Îq_/I˰¹×¤TbNðñv•“ÊvU’ÚðFפ¾]Å^´áÉŽÍ(czKVyü­'#l@¯¥$c| RM¦_UÜl†­€ÄØH¨‚$É:õ4yl$K^·ïzr¦RK.›æž\aZ¯µ$wòjòfkTJÞ{¬Q9µJ±F•Ô("¥VM{¬Q-5¥X£zj¦±FETy5jO­S¬Ae‹;Hq¡5¬APÀã#a!ÑÐ7k‹5B©Ç-cñ¦aAÙávH qZ7Õ"•9¢—ÇÒŒðEN(ÖaÄ/Â4”2GxË‘$ðÁ0µlÃ0{hpˆ<–@ãé‡ùØ=<þ¸¡‰§«Õ¦±;(ØnÀjT·°mF V#O!X4žiÑÆS"“ñ¤m܋ըž"w ö±MsØÓ/^Ü]Þþû—ûtùöááñéîòæË?žÆç?ÿôð¯»ËwŸ~¼ÿô® 2”÷—?^þtùþ]î.?Ü|JïÈ9bîÉñ€ÔK&øÎ¬ç. ÷}›^¼H—7éò‡Ç·éò2ýî—ÿ¼Ïxðß§o¾¹Ã¿V´QdâYÞ°( bØÔ3¢ð,+¬å(lÆš‘º(CšK¤X.ì'YØÉŽ 5âÌ%ʧe‹"Á’QÂö¬à…V0aÿQÖ`¡„"só(P%÷$+™ÑP*³£ ¢’è–©úÙF¸fŽu5¢Y&;ÍÈŒ¨'jœ[ O ÐîÔQbg[¡57«ÏV\¤õ´ ñ³&‡Œ¦’>À´£Z2÷Ó]A(Qúì nYä4O\+–VEÔ[ÅR²,í4W´ˆIŒ6…³£fp)ÙÑÄ´b_xÏ" +*SCHClö輨hÃ‚Ž¶—¦TÛB#Ê%&]L(—Ø‚â483Ýq…Ú )’cÁH•;†¢šcr³ìgÅæm?¢o9=ï‡þï{VÈÊ4Å£c˜BqH¤-7LU°Nä,+®-DJC‰ê³…H…1í4W H¡DFâ%B‡wL|@b’=O¨/Œ ̛иIF˜¦ŠìTLÄܲ~š+¸fET°¦]øB¢jF¢’’“*ÖˆMd k&ôŽˆÍ¾ñŠª¾7{‹®,ðfn†0sbÞì9ÿìξ0.0×®a¶ŒØHµ•œ£Íj;1EböêC¡¤‘#1{3>Í ä'®[‚ù Á’v²èå-Ù4¢VàE>y?¨EÕöÛ~P ï#2]î rÃ`ñì (á}@¶~?bÎŒ“º›%B~ö~ Ÿu ÂÛ~ {ÅÏvÊg¡ÿr…FQ÷“ žÇ1æ4˜Dí4OÍQ±Q#Rt³Í!¶ eíÈ 0r6÷1ð)¶u}?¯qY`…ð¶@$¶ ¹®mçK£uu³ÑÎ5&œ¨è,O¦í8aÄ„I—–‘©Õ{ö=D¸´›à(ŠUÔ‹DÀ\U Ví!ÂÖ'Ö`âvÍŽŽÏE€f'Í»sÆ«ð@œIϯ"Bû^™Ð¶~¸ªØ–8۞à B¤êY¡I( Š¡³U•¢™•½è‹OŽ‚9ñL¦†Y ú !\õ$®¹Ñ4 àÌŒe'­‰u1ˆ±Â1æ(nÎ1AP”‚)ó€ž>â(Ô’£‘ùiÀG ÚfÑd]ô%¥(a ÄðYj…xÉÒ9Y@O –ƒuXŹéY¾èYhV茟ŒF +*Äðá…̇¨ ¬a×ÇUÁUqQKhÈDP»¦‰ô–ƒô;¤¢zYhº8£oÈ—Dmô®C&j©È#âXÂŽ‰¨¥FÌíîŒwnÛn^ÉÏ3ƒÕ Ã8Þ"#‚£?"ÖE“ipa‡¹HÕÞü˜ ëu}`/7ÌÀ<$Öq‰àÂøn1qÈ…-­¨ÛªÀ‡ºMYK;¦Â–zbÆRˆï9&ލ°•FÌ>L _Ò Hlõ˜ ë ·C #²"˜0‹€ n©zÈ„­4BL# nDXÌ5TÛ1¶40¥gõà½j >tQhx¦ @÷pÏ×ð„v¶`:Q1ȸ*ö¥8dâ–qm‚‰3n·!ï‰[ÙÒ‰ö1ˆ8c®ê8&â–Æ<Áq’+%û˜«à ÿ DÜÚJ±¡p§Û)Þ1ge}ŽÆËº tVŠc*N—N7–Mt#ã‡Tä iɸ•VÌÚ=ɸ°¢ñoà⟪Ư&§ªã-§’q1>t4ò ÁX0Ó ‰i?fÁªÛW0‚QøÙˆ#j© €}>~†¤¬˜)Š×$¸Ÿ¥FŒ ª%RUFŠÆô}Hþ|•݈×àô9$ŽØ—ÿ³áez׫Æ2?¤Ë_ÿö÷”ë²Hú‡/?ÿü~Þøêñáih|P+8Àñ•WkÓë§èb)z½fh|‚šËëOßÜÃötyýòUº¼½ÿõ)½ÿ_w¼†‘w—ï±ÚýÃÓçøµÊX)žúóã—OïÇßlûÛ_îüéÃw¿¦á(?5ŠH|ýá¾?€áíÆáäÏX¸OËqM§`Sð)ÜîéWÁÊêh <™ÂÔlS³MÍ65ÛÔìS³OÍ>5ûÔìS³OÍ>5ûÔìS³OÍmjnSs›šÛÔܦæ65·©¹MÍmjnSsŸšûÔܧæ>5÷©¹OÍ}jîSsŸšûU3•2…:šOA¦ S°)øÚ¦æ:5ש¹NÍuj®SsšëÔ\§æ:5ש™¦fššij¦©™6Íï×þ¦&GŽŠ|ýMÍ1áøœýÿ±W V endstream endobj 9323 0 obj << /Length 1972 /Filter /FlateDecode >> stream xÚí\ÛrâH}ç+ôhGŒkê~y¤1ífÜöÐ@ïîDï„BáV ٻޯߒ°{m\%IÍH°ŒBHu2OžÊÌ* :·t.ZF­_?Rä( 8æÎhê`I&ÊTªˆ3š8ßN.O1;ñ£?Z®Oϰ'íÕjŒ½8X†›çþ)†'§HŸ8_®ühsøâ>˜ø¿lþøsß[û›/` Ð韣ßZÝQë®…ôx ƒõ­)P8ãEë۟Йèã¿9%¥g-Ê¥þœ;ÃÖ—|‰…³X’k! ³è†¹A#žÜ÷×D¾8™é›*ª¯”žúOÈàæ$Î_œDAòùœŽFÂàIü¸ò ×à B^\ý’¢…C™Àúf€JîDzüo.ZηôúHˆÍŸpn<“HÊœ3„€bìÉaƒÌí]w¯Úÿ0ŒNèÑ!þ´âùœ›û`ŸáôCÂ/ ¼›¹ <ׯ”¢ð“Lðˆjôؾw}dàŸ9Nð±pœàcâ8 þH9¾vÇËpܺ«(ÇÁÊ›Ɖ°ïb†'ÆOïÃq:»½½&E:Šª`=åÙЈ˜¡GþÔ"o®ÿñæ p$Gª¦È•ÊFÎ1X™¡Çß5扻ö¦&b"ˆ€äò'à¦{ð8å@ î™;Ö¨cßù†*(„}ÎFy¨ LÌ„zâ£ÇU\‰ÀíÑϹ1Ôª&^kúkÈn°|0yšNêëi‘Ão}'jö´6ÔÓbO!7ÓÓ²°§§‘oÓ1 ¢¼©˜1™]­á&î¶äÑ5wµ*ìê¶þ»™/dzÆMÖùÀ_ÎÖ¯E|áÍ|wüÝÏÖ÷Æô €Xc‘3 07ç)¯[¤­ÖY9ÚŒf÷´|¦+‘©¹êVœÖÕÕyh!P0#Ü´ѪfSó„äPɺêCù$‡f’?øQ0}Ì ðZ×_¹Ø­Øì¶'Rß³©®—0…LÊ>kÚ¯L°¶TózkйÉÕ¬`<ü0®tú^ø‹?²¸˜Ð= N'o¤2`kasW^dŽ0 ¸»³ïÃ݈ ý»÷ÇYcL5ÓåZÔ8ʾðnƒq•éy ¼­ïÄ¥´+X¬o]‹6ÍWÞÄ‹½£“µ8ÏücSó»fMز̄}¼É$ò×kÝ8—e\¿¿/£à?é¾×Þ¢ÔŽŽWXeX`³W¢ŒÒœ“°­nBžEˆ’eY¤¡¹›,í`-–e.š‰Ù¾Hò„9ù\®毫l¹Ôº Š,–Ϫî«î#‘;$n&ÐÌVe©lõ®¹Ùª,•­Þ0åøºÒ.[pc€h&îe8>ºÐnhiRvÖŽâ`qt¾^ûãe8qíeYÑFj À'mT‚2ä|íGÆ16Ñã`>¯rO \­ÓSʲx~&}ŤB³i%@ ÔL—K Çøëà6ÌðZ¯’)Ut‘LZ*²C/ÜŒØËÒ(„ùíã.ãj(¥€"ËÀYý¦JpªìÍjºü"Ò¸lßÙ!’›TÝ\«&’³ ­”ž²DX §ëØãæ5×^ßþÜ~v†ë« ‡8¦&;Ø·3m*±f˜ÁX‰É,ÿÏýð6þÞ¸BL-ÄžqÛú ïOÕjÛžªù±wcZ6€âZ.äȸT nž®4TWkZTéÞòŸ¿N¢r·ÞZrÒˆeïÒjØÿp[ãc ¤ª<ž÷‚œ )ʃžùÄлËÊ™½ y ?i³¬co±:hø6‰áòˆþ~íÝú¶ ×±‘pç =}ò²ûÇ×aû¢ë¶ÏÝÞ¨[M†VÓ§"Ó¿&9F¸<ïô†Ã¯Ýs·s9üze\ Çé^‚B¡Šÿ0ÈYò³¤ ¤Y ¶Æe1JvÀóJŒE3¥ƒÂ<Â\50tÂp‹†½‹ëîy¿=údœ”N >R,1γE*H²‚M[[còLcÚC±e™¾;èöÝîu§ßŒL¦ÑÕĸMϧ‰Îjª­i¾¸í¯fÊv«•þªèa™vÀºÄ%Œ½Óvµå pÛɷbK´‚n5 ¾Ø²²bÛï»çíQÛn¦#ަ'Óh©üÑ7J=´˜ #ˆÑ[AÀhãfìá¡I2&+K¢Ä4_šÌ°ÒÙoj·Ÿ†’;n$••ãNûêªÝ9ºsß„$OíÏŸ»×‰I>÷º×FQQ\,.D™ E˜_¼U©ç؉àtÔUØ)g™Í•×fÒå従œ½E/UÛÃQb®R‹„y\å¼ÄD2À9Í5ÃÇÞuoø©{~5åYš—œ¥SËèæÿ¥3u瓵 €UðMfJäZcû1 ÊªÒɈ›æPD”¥ÈÅpèŽ~¿t¯zF·Ä-žeˆ¿ÚýäÝÝ kGW —úttEÉù÷•­úƒÞß6S)k©^û²;ø)6U`ñ~6FœÎpÓ6è׹ìVãW”œœô7·3èžgµ`£À–ÆmsÛ/­Ö1‚ù»ßYýö½Ûú„ðfĽp’¾Pûß)rÊôä Ð ‹×¯Ë{7N: endstream endobj 9230 0 obj << /Type /ObjStm /N 100 /First 1017 /Length 2647 /Filter /FlateDecode >> stream xÚ½[M·½ï¯à1¹pX¬’€`À¶ $@–Ny1vÕ pþ}^qºf僧uà6 h9Óݯ‹õMÎ ÕTÒ µD,>h©Z÷AORªFR6 ¬$k~³Qê…}€ë¬>àDe>f’¨–rƒ‘’É¿¸Ø| %àM°ž¨ÕùÄHÔÍï8áxR¥yµÕT«ÏCSåóUIUkÇMÁöü¬¥Ú†ÏÑð£ú­'. ÑHLÃQzIÌÕQ:%õ9zM¬Ã߬sâV¯K⮂9º&½ùw–/磖¤ªÏÖ!&î>[I”|6@‰©Ï6(Ië>&Üã#NZÔç’a¼–2ùŽŠL”–TûDéIùlkѳAÄI^ #JFT}T“UQq2† 0’dJXZ4™‰øw†…„p0jÉ‘zjåüìHÍÅ9*•ÔÿaD©É|5È ÔÚùª¤Ö…0ij£9²ÔÉ•¤âµzå‰×Sg×’ 1u->/ÄÙÍ5¯Bì½™ßWkê}ø»Už÷ÉÔ@ÌQý‚¯VõEžÆxbȼ€¥Å´.ÀŠ+T¤;®®ŸäàìªÚÎ7@WK?߀Ǩœo€¶ÉÀT u…úû0ô•„\@ …%ÆB• `6è”ß ˜ ‹ëS»9Ì)Ä-Ã¥1|Sú;`1©Š+AÌV&.f«ÍU¨\Ã* .®búCL®° «+™k$¬x"(fcê†hg7ó^ËÍ‹7§·ÿûõ6¾½»»¼9½ùüïÇùùï?ßý÷æôÝýÃO·ï œCyúëéo§ïßÑüpsúáöãczKÏS»eXl˜2” Œ5Ã}ߦ/ÒéM:ýåþí}:½LúõÃn3tëÏé›onðo *fšLF®îqjË VgÚò‡±àš‡¿{嬰thOî00(v.½Ä¢6ÎžÞ ´F’Ý¬Ö ¹¼"ÚG–>.+¢£ghÿQ,ïŒIs‡U#ÈäSÓ&™‹ý1 ø£• Ò³Â0U)+b˜/ˆKÆjf¥?&ÁKUÓðÆXè\Fv÷£Ü³]­_s§Å ɈzÇr^2"Wp,‰Õƒ)¨e€f¹-x,W‹ ©°Òq ÷T KZrAxBôÊì¤à:D2 e‡$xâ–k%gO?¤X|‰wÉž@N—=œ”ddwWœ¥•å:Á÷„¨:ÁˆìHêRÌÍQ1þšW›§biÅÈ5u½(æ€Rè"Šêd#±…P×7A뙹&‰³}TäyæÙïfHK³\Ë&¸­T LîB Šu–‘.‘ꕎ₠Ãßö$,‹]Ë%–’ðlÛkëLU’¥CPéev¬$Pñ ¹¶‹$P^çÖ–„(rk»H‚T‘sëý$QÉóÖ'I0Š;ŠÄ&‰ÑÎ¥O¢tªW8Œõ‚˜qL/rðpv5/¤Àð’ E— (DïZå†Zº(ñA$ ¯¹¢fd4^ îVÃRžA™Þ IìÃ+IhõL“²zÈD¥!Ù;×]®E¯g‘Ja„Ì'Iì•ÂBëIho1/$v+á¥$6ÅŒJ8s·~Iððù$ -°B;X¤Ù»ÌITËr-zÉÂ¬Š½3Ä^wb9`ltîŽ@"z-z-%±IBǽ™’Ö‘zFþa ð<1FbSÝHÔÝ…”ä*ò|vI .X…*³üÚ­†W B œ¢—bX 5‡}E5> stream xÚíœ[SâHÇïý¹«ÖÞ>.3VDLâÎlͻաu(œîÌ·;0:9@È q¼°$‡ÿ¯ÿý²ìïM<{ûdÒëš?fû¦o¢‘™½@c€öÿ ÿÚó½¯{ÈÞ tÐìÒ(œÎÝÞç¡Óµïÿå@@”tþ›~êΡ\Úß}'ػ؃Ïep¶ A‰ø!ÃÏô©÷ÏeàžxÚ¾ÒžïŸûúð4¸REë"Y0mäÈjßlKKå;Ú›©È—Œí`’åKÖƒèÎTÇwH8Ãö`•!|rŸ–W ­ýÙ®F®¹´8Aþ(× ºzd¾ê3®f²{‹º ³å@ •®cc²“4œìl’æE²í•hF’¶íü–&‰êŒH&íhXˆ]ÍÑó»W/0H‚2·=‹¸á/!ÈH²+#/`¹ÙÀ2£Ù¿DFw†ƒ±u|í’‚¸|˜oãüè¶»A¯Ý2dÇ&JÒYüÐë}k¾W2·Uñ¤`ÔIl*Gé-6wÇ윶ën'åݛѰÿ`²êóšD÷µêóÑ8ŠÇy•€`µ³>§­-¥iÊ'¶woWÙI²SILŒµía<µB ÓnLÆi ±yÃl²…a¶€#–¿úÑ(éÇ_sÂתC‘]Óœ<: PZèš úqV…†(¡âïÌÝ•‰3¼½ùRÁq±ü»è¦×©dvw´[¿ˆŠµ?Dý‰ù ´O— šþ…v›Ídý=ÔÞ§vØ8ój½þŽK®¿?‚hºAø¸ÜXkd < „ïµ¼¿– ⢚Ên7)Ø(!E“ðBBA7‚à2}…}å'äË>´´K›”Û¥ýˆ¦ý1/`lÛPÕ?\ T4#n¶Î[^%k/%¾`(H$`*ÃVúë©"è9#ñjªˆJ@¼†*¢"5¯"èùó‰Bí«ˆu(𠯱Š`嫈Ík©"ØUÄ󹈬‰foM±ÜÌƒŠž|””§*½5:šŒ¿t£q¤o»Ý&¦›ñä#xG— 'ЕX┉ֻ(}‰úº›®Œ{QT¿U2ºÆ*Ù\û›øæ§j¸á…­±áeNø­FI‹os“âVOw)ŠtÅ&ŽÓ7)î¶b^^ñ žm¼âû¸÷P·Õ@ÅË|^pl6ÚŸø2zeÉ Š3½ºÛ1uÛ{[¨9sqªùëoÖÆ_uç‹éÜŽ&w:¹Û*WÂ~ýò/*|p } ð‡rómlÝô"tÇ÷쨒{v¬òQtmj¸,¸G7>,-ø¥}­èô¹Çåau+ÔžýiûÖa£í6µÛ:Ò·‡'4žoÙÞOBoh¦h΂|$õyv­ñì φÓs¨–\Þ‘±˜änÙ#Ïë?ºðRÖ(ë0Â邳°­[nê4e]<þ^üžeFæ+Írê·DS<ýŠ·™ïÄô²MÞüù¬CÃÖ]ÉWC›»'{/ÿ£„o endstream endobj 9325 0 obj << /Type /ObjStm /N 100 /First 1019 /Length 2535 /Filter /FlateDecode >> stream xÚ½[M·½ï¯à1¹pX¬’€`À¶ $@–Iy1vÕ pþ}^±»f×>L/ž„Yîv÷ãëbU±ê 5ª¶TÒ¨Ú±ø`¤j+IJõ%eóAMÖüfãÔ‹ßløày³&*mÞm‰jÑŒ —«—åêHdÅÁDM­Q¢Þ·ÔRü‰Æ©’ø¸PkSiª²\µTUs´¶ËÕžj/ÍGxƒ1‘{I¼°ê”¸Nʽ&æù¦‹9—.‰u8r×ÄÉG–¸›¿Go‰Çrµ'!žx#É|û:`&žW%ÑyuÔ`Gœ¤-W%ɘÈC“sÎÃ’Òè˜c4Øxy¶']X‘Ô Þƒñ¡Í¯rÁZôiu,NV\892ãÍ—#MÒ>²d`uƒQK6Y1Œh}AÉ3FTR+X2Œ(µZjjÌŽGœš˜ã‘¤fe>¡©5žOXj½ÌA ž±\í©Óru¤îË=¸Jê2‘+aäë+Àë*ó*>dr© ©“KÅG[žÀ«vÆzp1¹0|¨ÐœïO¥Îù`(ü­ùC@£¢¾î¾äTl¹a:ë‚o-cN€K„çæ½ðW"ÃÂ0Ãa‰ç I$óÁl¤&Œ— j(,˜º‡ f£1_Z0[¥ÉA<6*ÏÇ0èÎÇ0[…G`6Álp+L1ÜÛSÌ?ódza™ý1Ål°·¯ŽŠGÚrƒz‹óUÌÆº x(6;žÞ¹ß¼zuszÿß_nÓéÛ»»ûǛӻ¯ÿzœ¿ÿõ§»ÿÜœ¾»øñöáCAz(O>ýåôýš¿Üœ~¸ýü˜>ÔZò€×s—,ˆ ¼OFø!Z$6pß·éÕ«tz—NºŸN¯Ó~ùôïÛL­ý1}óÍ þíÀ‚-›Gu«1„ÌÀÙàsxÉ\ªÅ¢Z®ðj¶’Õs‘p&Ø~˜‹õ£YHÏVù‰…Ž 7>ˆ5¬2 ¢+Ã7 Øa§w6—Xôm!”2²Nnø‰-.wqVškáƒX ¥dä7ìCðNß%kËÍc†(cw8Ê«_`ƒ ÚÙ/°Çd$¾£Xf*¶ïܱEV®¹!3aƒ…›Ô£HhÍìå…!I!W£$ÉØd`eRÃ^Ö.÷»r(ÙÛw¾œÄ˺JÈ—[=IØ,î“¡ùcĤôš‰§È2ü0S`PZz?Bd:×z ;Ù¸ØyìÂeMæ½ ^A¢6ø†!N‡ôƒ=ÓÐûi©«gv²1sŠŽl€ÌdèüÝ¢Ž)ØÊL,—ËÝÏŽ,NQï^9+ÚÅϺ×Xr¹Üþ\ƒúOƒžYTJm{…¢ÿDT„W W¦v”%Ù/®HS®D –Á»Q=׋ÍOßq ä%$ʤÍ÷-J ’§Âeë¥æ§VÞcö:’¢ïëˆ Æj ïIè¾2_ê:j•+˜}ß@×q6…–Ì—ºŽ]Y°Œì®úÞéʙƣÕÀîhn“.ÏX¸Št©ØÞ•…¢“±uÄ%û—@>9H•|Ù5uw×E<¸¨»º¦¸Aè(±ž©± ±H¹q”O¬–@yíßìœ-A¨7û8Ø1Ùó“>™bSòßuA"U„ä©bSò¿†k†Ö ²©µ_Ç®¢Y2Å–Ö¾¯)å2UíEÒu'-n TU.²°Ý$DîXM‘{W^\—ØW•[Ñ‘÷.Û*÷¾¦Xã´*ªÿêeÓMù:¶Xæ³-¶æëØÂ3eO¶Ø’v¯c‹UÚ=ÛbKÚÍý·ôvcOß”vwe±jˆª¨›ªêUH¬zæ™Ä–ž¹/‰Õ7É%?z›ZâUXx¢¬ÏHl)y×XUF‹åØ’Ñjý²û:}\+€H§¿ÿ㟠=6$´55Ý}ýùçqã›û»Ç‰øFÐ~jìùÈS¯¨týÍ‹_ê×PÖ²€æôöáþó»[PO§·¯ß¤ÓûÛ_ÓÇßZã-HÞœ¾Çl·w_ü¼ËÄö—þrÿõáóíü/ûÛí?}úîþ×4íd.*NUûí§<ézã´ñL> stream xÚí]]SâȾ÷Wp9Víô¦¿;—h4 & ŽSs¶RÑC-¢èÎþû}j v!N¢^(CÒÏÓïÇóöG°j×5«vrô%<ú½ÉpÍF¶ ¢^ÕˆbˆP»&™B̦µpXûñ©uLø§xzOogÇŸ‰TŸœ»»ñhПn'Ëø˜XŸŽ1œ8¾½‹§ËÃ'÷£aüÛòo?ÇýY¼|ƒ!ÿþq¤Ã£ŸGÚcÕpM¸5CÒ’µÁÍÑ?­ÚŽÿQ³µUíïÅY75&¼ŽkÁÑ×#ë%Á_`I®…-dQùÃÿÂ#/Œÿ<: Âäæ¿7©zñ e!› ¸ÜâüÿXÜZž$Ä‹“(¢X=sy?Ï?x‚ˆêOGýËql¸¼`J¾¸<þmÁ€…ˆ¥ˆ’Áo¦Dm ˜^ôOŽj?÷!T,?øˆ} øgÌlW‡?0²9 ßõÌøÂRn_–?+Vø/Nß/þžÛ0µ …ð*@—ÙЉB˜Ø)н–×ùæUÚóeÏ«ð¿év;#fÉ7@·ÇÄÜÿܲ¢®ïzu·ë´ ÍÄX"Îí7àŠ#!è* M/yt;˜ÇsCÓ dH›å1€úòüŸ;T‘¤tP±Â™PEŠqÒY4¾ôÇýápº‹|u?,”Ïëk2 $î4¶²û— 0se@}׆ýyßd|ÎKÙÃ4¬ÍµD:V4¸ÌãÉ|fôh‚(Q; ¾‰o@ñ¦t2eÀ¹DT­ÆòÜãxr=ÿ¯ µ…‘*O+j&íŒî¾é_&HP¹÷®¦‘PþŒà5ű%‘e«jâæP²”ξë¢iüs/r­$É [ðÆ–™xÑh2ßã佩»Eã’ú6Ù K’‚˜áÏâéC<®âé´?NKc˜)è|\ÊÎ߀^Jè|bè&ôèùÝC<F÷“ùhl@@m¤ÖËýJÙ…bȶr˜Å#1ñ÷Ç7”,(¹‹ÍîMlœ”…9&œx,Aœ¬©ìP8Ù–`GĘÊåI?ïãÙ,æn ñutÿ˜ôoâÓræÓûø½óò°Eæ¡^ÅÄ# ²pŠ»¬#GÏ–`â@%&¯Ø¶HúÿócLá1±V²›mƒÖQêA“5ëP“cP’R¶ƒË2…½ø€=4,¡QŠ›qFýá0º¼¿º2wÅÎ5妓½àÆxsU)MãÂ]§9aè»_z¡"×kvLè‰B;ª?0E2&,…‡zÛÕ^/Ž{T{|TåfÒL!½]R$‡OÓ4[ðuXpvºSäNˆå$‚@h£œ§ÑÐm}â„nÇ«~pP‚CCŸ»uýî‚C Õvþà𬮦±©ury—ýKz‰€9T¯"%'4{ívT?ÕõVÐ;«´õ3kǩäã¯ãù»’ˆ+ÀãQ<™G£ÉÕí^²ÀAŸmpwŠpV§'…ËlŸ“.‡AM6N»H¦R`&£yZãUE¼äÖs[»s’¡rò{wIS›€7Ò<?€Ÿé̘۠DÇ¢´±mC· )"Sº½ë»çÁ¹Ÿ™Þ*#õíRß×_{:;þ^]Y­îÄH öÏu¶%T¦Ø±ó;ÏQ`6ºžTOàÒüwqÿšWo©Í¿TêÙÞC·ÞÒá›°÷Mº>³¸ïu½¨á¥ôä_FUÖ_×Xá qв›nV=â!žŽ®þI[~"«ˆ@—)qo‰9%l¯UKœŒ)€†:‘Ó h8í0ÕÞDyŸ 4ƒ…n"ƒÒz ¬ a` ÈÎjW!nï°¡&°Y†%QÓ×Á©§ƒ Ò‰ïœ_w«­²y1•ýÌBÔi7*.x±tñDÄ×sHXø0×sèuñ~ÌÁ#¿¥Î VGP‹b‚Ú×S'ŒÜ„H§žè 2I6ÒíÆ†-7²‘<Ħ؊9èl¸ÿÚè0aÙ{L›_ Üt héïÕÖØª˜ÆöuSû¾ùùZÕ®ņ«ÖK7f§ŽáV&}ˆb3asöFªpQ,®c'³³v̦ŠM\¼Z¸¾·Ø) Å΄ˆŸ®¯ëa‘uÿw Ùfë-ßÄCÐ…ª\ð°äÁì(ÕÉ¥2G.5EO dèJ/Æ’;¯F_2ÐuZºÊ,e»>°ô‰€sÿYR¥.ØZuËÝU7/ŸêOR*ªS•©bULp]w›®nD­s¯“º:íf W§‰CM ªÜ“‚ ›§³8í±F¥^ÌÍì×r?AŽ®ÆýëÙ~o¸£[ŸÊŒ›wnG“¹qwò"ˆ‰2>³gí!™O¯ëߌLúŠ­¿áõ—;À%AÐíË»“áâ[~-<šq¨_Ô³¦"r5mA[þà[ÏÏ endstream endobj 9417 0 obj << /Type /ObjStm /N 100 /First 1020 /Length 2688 /Filter /FlateDecode >> stream xÚ½[M‹\ÇÝϯ¨e²©®ûU ¶…’@ÂÒ"‰ÐB‘‡`bfŒ4çßçÜê¾=rÀïÍ¢æ±jæM{ºêÖýx§zˆTÒZ û€Wó'âIÆs ©Zõ¥6æ,üÄꃖ¨X÷QODƒo0éP à:Ÿ6JdsjãDmÎm’¨ŸŸj¢1œE³ÄÄn«ÕÄ\猖XÆœÑwØhlAyH/‰ÛpkŸ`°ãu|„r~*IèüT“Èù©%ÑêÖzMX·Ö[·Ö{Âï6úÀB Ÿâz^¥AIÙ?½€®jñX,5q~ ©µÎ–´—9£&â FKVÎO;V¶lŒ‘L|®C™b91¢dÿÈ“µóSìE÷¹Z°Å‘µXªäÈZjª|~ÚRÕóÓŽM»Áh¤Z±)C©¤:Y)QªC樦VªÛ I ›™†‘¦Æ0‰ßqê4‘©§.“Ôu²â’ºÕL©·ù”1£ŸŸJêcÎõí¦i×Ý‚¥úh:”³b|h›Ö|{ªø0´æx¾)£øçøP)âSÀœ ŸÃ‹Š7«TTÜ"–¥¹IX£‚èC÷֮Ňp×2Úœ%üC<"bÅΨ¹?bkdÅ +¬QU'«°F­9[5÷}r: k\tNƒ5¦6§Á Íi°Æþl¨Á[wkkÜȧ¬qWŸf°Æ£û4ƒ5=Ú<_n §’ÄCX£9 ÖpVç4?‹­û´yÒ›/nNoÿûËm:}{wwÿpszóå_óç¿þt÷Ÿ›Ów÷Ÿ~¼ýô® >”÷§?ŸþrúþÍnN?Ü~|Hïp03wߎ‘±ß¬’™ü#–\õmzñ"Þ¤ÓŸîßÞ§ÓËô‡_>üû6cËþ˜¾ùæÿ­à@¹ø"´ìq‹¥åÑçþâ×¶A¢®$A–lºe8' ç†m5¶T2¶¸Ix3gƒëuͤúû´¯cΆƒˆ–|]+eÉnÔr«ý ­dY„4ËÁF{ËBZÁölm/dQáþˆLµKö8¯ K‚‡@›‘çŽb1(+xm”Àr:œá¾Ses-ävÄF&Ä£Øä¡<´ÅB5 yU‰âiq ¹‚Å£œÓrC.¬b™‘tpFQµÂ[ÚÖJèBÜ3¢deDj¯W´äêõƒh.7b¬ã€R(w<•É^Rå.NŠ3’߯Jô²6`¹/ØÙK2ly¬JFaz +-Ô †sÑP ¡ÐFúB¹7:Réak1Tæ.Š nØC)‡RI•fQá(G¯,No©Gí\QšQîèLÀª9+öøùû,öŸ… Nâ€^YX·Ö-ò ,qò+Ò3êâƒH(Žª¸ƒ!XÛü׋ZCñ©½Í¢ Rê# ÒlrÔRbVG£Èááý7Î+"è@磜Å>¡×Úñ¯Î} ÚZªµHáÖg*G·£ÍƒÍ0Þ6÷Cן¯/½stièìhè;¤ŒGŠ>dŒ£Y ùûj-¤ä¾Õ…,eÇT½Úõ—*—sªÔsïã`^éø«‚+ oŽä¨µˆh!ÈŸ^íF´ïKx“…­‚®ÈZ¿† A_R¶Ã¥,´xm9’(üUžÂ[K¯ý¼;Úª-håiÙÜ*Ά¿ó2”ÝþÆKЗÐvg¨ë;CaÍúUg(Þ˜lw†+YTóÚ2 qÖÙb‡pbÅ[“íÎp¥_Òœ³”¹ŠòªûÁEkÂCŽ%Á½góÆðB‚½3Ùî ëz a{<®£1‘­Îp-‰s{Š\zÉ«†Ž ‚”eÝì K[IB`͆\û|»ãhKt³1,}ý+ †õÆm¾OcW@ЖØfc¸”Åe)°-³ÎŒ¥@Wbõ°¥èeö…L(ùÄ«Ý6ûBFWR·ûBZÿ&‹ÑtÄ­x“Å3·o¾èË F[ØH‘\·ÚB¢•:B¶ Ø—l†U˜¯z y¥mµ…K÷#ªò ^{!ª ¿§ƒêŠ+ äNúª##•<ø¨âfà”ö©2!Bys Weq¡d/…g-î+±'Ĭ]ŠÖÐóTWb*Z!hÄ\ÞÜ”bXêzèG+Ú `°§Åü‡—éÝð­¤ÒéïÿøgriÅÚŒS`¾ ÆeÀ%ƒøc–h ,5-Ì,,,,,,,,,,¬¬¬¬¬¬¬¬¬¬llllllllll\¹r äÈ5k ×@®\¹r äÈ-[ ·@nܹr äÈ={ ÷@îܹräÈ={ @<yòäÈ#G @d+%ŽÄ@c`1¨1h1è1d d:#¿_¥±{‡(©•†"MÊ—U÷´Ý¥•Ñ ¶ÒÅ]4‰¨„Qò¾¶û<$ºd¿ôt!±+í®%mð@åÒ®ÇMF#ï÷®v¥]–¶òâÅÙ)\Úõ¨rqŠ]ew- éØ}Ê®Ÿ"6ËÍUî=ew- ô«^ »´kêMó܈}mw) Bƒê€‹»‚ØàõyéOw—Öå—«0SÜ•v½ ³/î®ìPÈ«/~wi”y#æ ⮬tÎ:ß „¸ËV4ž"î®dá—´¦Œzwý––_Åx‚¸»”šÅAWqwÞÓBeöqwéŽ b"^‡¸Ëþ:©WÜ]Ê‚:¼rJ»Õ_c”êéa_Ú]{L+Ú2—¬ÎÒ.£a*~átOÚ¥¾PåfDi¾Hº % »RR|WÚ]Ê‚½¹è¼ãñëŒ8 …]Á:šÅEV »²êZ8ž?CÑ$°©(’wÍçY‹‹–x]‹=-ñYX„Šwe±§â­=#JHe`ÑÏlØ\%)õ{–G-²8ò«ˆGþ®ÇE½=o±sòtÆñ¨zÕ'ˆx£.Χ®"^ÜzÞñheü>K"SÄkÞ xù75vE¼g)|]Äó*/ ß]uûÊ4â2ªMÏ¿ÖÀÞ)ï«xkY Ü®s Ð’xà2ÅÐ}o-‹‹_¸Ž×Ç£_ìêxkY\übþ‹Ú&übWÈ{¿p%oø·‚.~±«ä±,”l‘Ú¯»†’ÇðJ¿îº¯ä-±#> stream xÚå\[sÚ8~çWø1™Ùju±n””m ,Ðîìtw<®Q¦Üj;i³¿~eœ´H68†Úô¥4Œõ}:çè\ k:×£Æïç.r$ 3gtåpìpWWg4v>ž¼=ÅôD…ŸT¸ˆN_a.NšËåtøñd1O/œ©S OîN‘þât±Tazùâv2V¿¥ÿ¨©ò#•þÆþ;ú£Ñ5¾4^ tPúhpÈ`Öøø/tÆúúD çëê[3ÇeBNaãÏ| ƒÑ Hx ãsø‰zËE{¡ yòøßωxrDÀÕφéÿ@ Ó/1öäK$¿ÓÒ€(<‰ï—Êð{˜NÈ“ßC¿­@C€¡HPqWÿë æ„Ƴ‹ƒ‹†óqõûHôƸX_!¬ï BÿIéSÄ¡ò"5› ß0ß°[ `70¢Z†,€ýÛøÆ²Àã¼L6X…á"ôf*ŠükÓRÑJ- ÷Õí­eõɲ(ÚÕÔ¿ŽŒ‘£ÐѪh21G­Ô‚â­ôªsÑíéA»yùÎădZ©Q¡¨)ªu|3­›J¼Zöþ…c ßJ«ÞÎÅ1er˜Y³Ìf*=èÚ"Ç5!0Ï'[¶†›Xˆ+êŽæ% €eE)t{ÈY´ørˆÐk‹Ò Év{ܹsƵ:ع>¿áØ­Þ(I€ÕTèÅêlËÅn‹?EßÍ'Ÿ>ö†yÞ䝿y³ ¦ò<©£ð¼sBÜ-””¬nÏ;kŸç… &ë,+QÔŒ-ýKž[Õ údsKð?éùyäl‘HÉ´ÿ|ß9Þ&‡¦-"˜÷Ý”¨³Î°ÙüÛhƵ$rRLˆÄ蹺A ¥¦nÚöÈT–¾íóÄc‡b •ÅÔðMo02š%¬]#\Œ'Êò‹­Žöb–Ö¹ÙüÜà I q˜ÞF†Ýuª>˜< (skPƒÎË0iadÌ*/EÞguÿ’îÄŸÒ¢Çr@°0—&³¥©VàVZɪ{v€ ¤>˜*¸™ŒÇÊØa̶ôG*é'1a.Á®@[·ùh@v:TËé}™­äHzfm&O0{/í­>¼6³Ý{«Ω޻þÈýÝ×nOû/íS‡õgÖP£ ï³m¨±Twñ"¤™¯yÑìt0Ô@ECâ¶7œÕêC8Á¬hâ#ìH}¹Uó@yÁâּ녻d*€_ ¥iÎ&ôçãÅÌ–ÁH¦ø’ÁÀ @Ê nøÁªUC²bŒpì¡oÔj€éû˜ðjt¶Ì³ê0­ÄùQ-•ÜŒxNîê·Å¬ø‡jY¦ú/Ïý¡;^o”3èU%Ìv`þR¿=Å÷8ò¯Tý”XUbåk»åGÑ×E8.3Ë\ ØÉ“\S rUjõ^šÝÖ¯õ¦9xÑÜGÕ#JAuDéšw:Ë}©ôîç¡^Ûü5£¦‚»äm&‡ôMJ÷ÜÌAâ›0£¸·>$™Aïuó,ùüÐ Éléw"†o;}/¡¡ÓëZ:‹‘D©xÒœb§Â•/N˜b¾úh‡FõA ¼;FfÉ-ž`9Œ:Ü‹K¤Q ÎÛƒAóÒÞq³û<ÁÏÒ„˜þƒj9õïmùÄ ¿ÑIîPudfÀI’©v£Ür‡QnËFƒx2SQìÏ–u¦‡)ž‚¿TP»,²,–EU´\ÌÇ*ÔÎÝi› _%ª7¹ø#ÞêhqLÞýümmMz-ÿ£ì endstream endobj 9517 0 obj << /Type /ObjStm /N 100 /First 1019 /Length 2584 /Filter /FlateDecode >> stream xÚ½[ËŽ·ÝÏWp™lؼ/>Á€mAI€l-’Z(ò 0bh =çïs.«nk¼éN³àtUžº¼¼žî¡•RIC+'ö$®êM2æÀ’qõAMµÎ›[jÛ¥žwŒD¥úó­$¢Qï0"@ŠßßîÀI"ÍGš¨ ùÈõ9e«‰Æp¼Öo|ZOÌÕ§o#±ŒQ/‰MstÛyµsâ6‘;Þ`LäŽW(¹[šÈ½&‘íjKâ/‡QObòHÒęޒ¤×†9%-ÅŸœ”ÄŸ’”«?;¨–ù„%5q£&Øh>ÑØ:Lާœ&²“ +–-°•ÞD‹ÆÉÜ8I²Zº4YSòÖ¢oW±e»ÚR%x=UÞ®ŽT· £’ªIÇDX¾:?ómÌ‘¤Úsu”áïfÄ©ÍÏŒ:ÖÙßÃh¤Nþà›:Ï«L ·9gæÔAs°¤^·«šzÛ®Zêc{S·1n¡iw)>/»9çUw›óúBµyÕ¡Ï÷ðåóYÚ.É ÜÇð¢"Û CÛnè;k›7ÀäTÆ4ìK´±ƒ1‰¨&S8,mü³‘Î)³‘m˜6ŠŠÙ¨oÝwÁ|}ÅlLî!f˜7ãfÃÈßÑ0ƒ$f3ÌÆuNa˜7’†Ùx#i˜MÊvfÚúÜiÎÁ0›l$±UᬡúVlanô®åîÙ³»Ë«ÿþzŸ.ß¾ÿðéîòãç}šÿÿõç÷ÿ¹»|÷ðá§û¯ ÂCysùóå/—ï_ÓüçîòÃý»Oé5 Í}¸1G† 0Qî¾\r!Üõmzö,]~L—?=¼zH—ç鿾ý÷}†=ÿ˜¾ùæÿ?&ËØú£eÆVfáÜÜ0¥çbv‡fYáÑÝrÅÆãÁY<ÚÕ|à ¬e!¹Áï›ä ÇáVsÅÂwͤzUÍ‚M7˱™%ÃS£–[í'­:<Ë,Ä ä…ŒœVð’[,t!‹Ñ3ÞÛc+\¡%ƒ—" {„ÍÝúY+‚Ù {¬§¬ˆêÈÍ#{"¬ˆ×A 3Š°ÊØ*ÜNfº+Ã!¿° w¹i ^¾ ˜87¤ÒXëÕ£ÈY¦(‚€Y+¢j3ÔX¹÷YóeÔ¯'™"ö)J“ÜQ0Ä>EÅÅè$¨‘³Wæ(Ò£PíÂU%j§,£žÆb‹ß¨Só°køF™UO7fã‘)°0hcn±X™P{ÏŒ²õ}ö>y”ÐýxSgÝcp‰Å nf‰ÆÀbPcÐbÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈÈ5k ×@®\¹r äÈ5k ·@nܹr äÈ-[ ·@nܹräÈ={ ÷@îܹòäÈ#G @<yòä±#×Rb@1àH 6ä7kB¡@hu—#Aš }ßø9²/<*s‰|ê~–]µw‰|~{æP캞„WPþå˜Ä¡¹”WFƒ¥SŒD×ï_ÖAs¬EÙJ–(vÕ"Ù•QD©c-²®dÁ=‹/È®E²nªà¡¹”ʶŠp\ŲÇ^¶’ÍõÑ Omg‘ðõ¨vD}=Ü"Ç‚èR½ ›jWA”QÊyœ;DW² B¿ëGȾÙýKCÞk ç¨³©ì›¡ˆî¾y,ˆÖú$vA4Hê¡+I úåÒ¦êÙ˜ å‚jïP]5vgºÊ¡ŒîЬË¡kYø™)ŠŒ]eCèpñéH]L±Úø*‡¢‰ËâüGrèr6n§ê$Tû±ú$^¡èwKä~ž{ë`= Ô :39MLýP–]›Ñõ*k4~ö1}s¸6|$Ë®l#t«'Ïyþ€Z§ŒcAÔ~‹„°I] )§k_#EŽõ,B¼²8ÇÊodÊ´‹€„\ÊÛÁÈ¡¸t= Õ]µ7?2,hv¿B{ë=S> stream xÚíœ[sÚFÇïý)tiÏÔ[íy÷’b9¡Æ@‘ü6nÚÙ‘…ì0+‰¤þö] Û¯Á+ °B…›ŠŒöÿÓ³ÏiÙÖe[Ž~ñŽ~>'Ð’@2Ä,ïÖB‚„¥Å‰DbËXŸ/N=£›0šÅ'§ˆ‹ãÆ|>~2œM—ÎÂd=úÄñlFËÃÃAøÓò}?‡~.?@€€'y¿9ÞÑßGPǶ Å‘¾4ÜæV09úü—m ôñ_-`)¬oÙY‹0¡_Ç–{ôÛ‘ý\ £Ï´¤ßm`cþ £ÿ U}Çíu;gN_u½ž:o7>¸ªÙm·¦§¼î…ÓIÇôó9Ï¡Ø@ˆôe²ïùÓ¦öò,Æž…†âñœ›Åpœœ¦gY§q@¹Ôo ”.O¦àhŠL³õ£¡3 —&@)ž]þ”A³²EJ…ý/ÌŠ4†ûެÏÙu%Ë?|ÀµÆêT``“µ1æë8Ÿ<ýÉ0^ÈÀ6ÛUʃHöÄ㑦€s¼:®V¨Oùþ¬(¶Ö¸+×é5ú ÏQ½–ɶ d3¸°%!*@âa4lyJ‰Ua”úýIikz*—’êö/žj´{«K§ßj¾ÙiH+™†K`gN³uÙhç¡Ýæ!Âøå< ¹ïyH+™‡KXO`>éÖópÝP…ñ|6„‘š%su&*øâÇáôÎ|g1o©yrÊ>¾]Lƒ,[0Ì- ¤-_áêyƒéšyR\ÈëûEa)“X3ñ§ñ7Ò€Pí’8ÜHzÇŠ€@À%®À*Jœ3” J $³Q8Nog&:O”dÉýÜdbHÇ{\…x(x±zΔ[¨þøN &B¿_ M íLÂÉ£ƒ¥=Â÷qc6: ¸• Åþ†å„Š|‚Ø”mi‰F @ÑZ¨É™éhŸJ%ßíS [йûw±Ñ|¸Ž­dKó‘T¬˜ýÒ›šùÜ΢‰Ÿü˜`ù„ÒÉ•|Ù ¡µ¡ì]Ž›– Ä7`ÄŸ1Òá}…‘Lâú2b0úN³è‡='4 §Ã’ì—ý5¨–¹Ž(Éô4·†ƒpš “ahŠY¦äyà •87z§¹/&{@"t}l£­ˆ¨Û(4Ú…¦K°ÜÒ.(dYð4m˜[Å9¤€Ú°Š¡¤¾¦º¨B…õuï¢Õiy­®¬ª®Üôx«£šÝ«Ž§ÚÝß+´ŸgMŠò®ž¯\ðJÊëâRÚ<“±+©óV§ÑV^ÿú©RínóÂ9+ÃÄÞ$&³{*íÙH] ¶eÖù\õN õbù»{'²µw2#zˆd÷ÆÁJ@l´%²˜¾¦ÿŠ·Ñ @¼íòœm„gY;ä•éï(å)îyV˜nÝ^ G¿]9®×êvTΊ'I=Ým¥E TsxªWIæa2  Ñô®û{·VýŠ0­ÉŠ0[aµþºÆ =6N-†uÝ…H »,Ý1Ö›ØïFÚ¾DgJ6'ÇöédkxÅ+SÅÞH#F´® 0%YÙšcžø8×°Z&,²P­”€bžã„ÿÌà j:›a¥«MÅÑïA~Ú%(ZoÒú'þÝ00ɶ!L¦l€„²PvÇþ]¨r 4Ýz@ÜÁâ÷‘r•¨×—â›…/Â8QÉpò.Õç::¨c¥ò0­ž!À É×ÍÓÁbnê-PÇvL#÷Úº`¬XºÈØ´)Çmœ;¦{¢Ã# ›–èÖæÊ˜ÉÑÅþ8I}›Jf*N¢áôÎdíéÊš&2Ù%öÎ4ÞóKuyåz:ÉUN§Ù¿îyú˜±L Ø»nX£¬Ü8VPF­™v™YäVQ)×éœ=rqÎòÈdæVßö¦¨ «€Ì•ë¤8TÃUÎu5óå¿ò%ûÒþ¬$&¿Nþ¸ܿsPæ,*I ÊÊž´C,¹QqôU|ƒ0ˆîçiJŒtí7 ïÿÆX¤²µfâ&>“ذƒ®'%«ÞQ”¹ÐÜíˆiù;oýÅ8Ñy“?žääJ ÊšDI£)M–ž:,Gyr«PUÇÑ8w#&úö>swb¦Â(šEê¡Jª4QÞvXž*óé£A m>øª¾Ìf£÷'=ïPúÜão³È´‡KB ñº¶ûÊ*#® (­±®TøÁ—ðU+–5Dþ„‡Â<_?×µQ0œûãü8‡°EM½|Y¢ÇÓåÜýTp^ H2À°¨mhC%ý?}%’gôIä¡ üñøÆFW—Ýñ—UñšòÛá8œúæÆ_½•‹Ý”§bÕÄOSU#˜Îáx]“ØÅêδß`©9™ýß½ÞÝ–»Ýí¬Ù•JFñb’×ßO}:ªk-[æÞR§Ža¡øA8NÌ?k€`$Õ³Sžm{-’þP±½*}­åmÏM_Ÿ¤Âû¼X^×ü2¸k,’ýØì>À7ÞØÉ1£ô4}‹2ß§“Û‹ôÌÉ:µ^S]6¼æG…:gÊ»ðr}œx}Z¡ÿRh\yÏ^£wWW 0Vˆ!Û¸ýªm ugÀôŽJ(çS£éU²i©ž ¾£Ø¸›ÿ DËUnÎ Îáx±…g`& ÞuÏ9ì)!^;%ÜþÿT§qét;íëœ.PÂÍáÙfÇ|äõpA¼²ÙË-«(¼Ö¥ã¾ssȼ)v÷®×j^8^%­ÿJIk ýá€fýÝžÓi¶»®SI£¿®$ ™ƒƒ{ÕëuûéÖ,@¸•5å +_ˆˆÉÒÊé¸PÉ6‡šŠ×±ÊíÊmýáTÒ.¨)€ôJåè;½CÞ¹¦ýñuý¹–©'d?Öòå£9õW”=/qk:Èž¹ùOöÛBuœO~ñÕ1é±ü Ø”Óõ endstream endobj 9610 0 obj << /Type /ObjStm /N 100 /First 1019 /Length 2638 /Filter /FlateDecode >> stream xÚ½[K·¾ï¯à1¹pX/>Á€mAI€l’:(ò"0bìÒ pþ}¾bOäK÷á `Au÷ÇÅb½XV%•4¬j"QXâZ}P“–ù¨%ÛõTñƒ‘za ž‹ù€•ù¬q".t‡‘Ræk× Ú,‘ù^MÔ¶§-Q¯>Aë‰Æh>‰‰F½$æêïuJ,C|ĉæèâle×Äm{Š v”^“”J>jIhø½'šOGOGIbóé $m>œ¤W_@e _%^QbgŸº±“lß¶¤¶}Û–;‘GÒæO+D©“U-”l²ª¡Ñ°;Œ2öõÖ¢Ét{:’ùäÕ„}rð³)µZ,U3JäÛâÈÄ©vöoIRæ_¦VzÇd©1û·TS3µÔ"Á¨§V¹øh¤Öæ·øÙúDh/äüÐÉ…%u†ˆ1ÒÔ• æ`Kݶokêu"cѽÏy!ºíñ Ê|*˜rc%äÊäO}:œ‹È6å˜ËoV1‡+\ßžB‡JaŸN D…̹ ´¨ðöÂÀPç÷Z0´¹hÝ”ÕgRhkésa u-cJT¡¯øg(XU(,ñ”©b6ÚĦ˜6¹)f£º½€Ù¨Í ³QŸ/ù˜ÌÏÍ%bÀN’±²`6|KlÛ ˜kwfX´nNa˜·5Ì&e®€„ç* 98tæ¸POéî ª~}Û1ôƒÞ¬Ü½xqwzóß_ïÓéÛ‡‡Ç§»ÓŸÿõ4ÿõç‡ÿܾ{üøÓýÇ·桼;ýùô—Ó÷oiþ¸;ýpÿá)½U‘l®sb™1…ZÉ y@R¹HÃ{ߦ/ÒéÇtúÓã›Çtz™þðëûßg÷?¦o¾¹Ãÿ? Ñ‘;4:Ÿ5I­¹ÁAi2ñ6ZÈaP.~6{ËÝpö\ ÷°™éV,`K²k?¬,d6R³[\ØAìï±à•,4cýn±r‡Ê™P#x k|#*=7œn3ÊîaÔ,׿¬8‹ÑtS«Ÿ °ì ¬¸¶} œ;²X©Šãév ¾)»ß2ÎvÅ !UºÕ~PËÝÝTKEsƒ]3®Y{½Õvà`¸-´¢~þ8C?¡¯ÐÑ[j¼½Ï]©h‡‚›²Â~VoÄV;3"0í³cÔÒI•¼g'ÖJBaàŠµB3`¥ô€NjëØ¤=IÔ•‡£´ çáæÁ#YeÍì!»‘=+%ÁX1æVÉcþmÙCW5?#{‚ [i%`®· ô’¦+ïU9·1ö8\A\2Bµ/‚Q½ Ä<]8ä 0ÔÅ”ºÍ= mýÑ€‹È„`ôr4J…–ê­Xl‚®8øã" $;y´]Qôå*¤,3R€P é‚kWc¥Ñ†B")ü$& û€$X¾ÚoÄ ì2ÄôÙ“/Ã1éH{‘ºb"¹•#Y ¸”ê² <<½Ö–Évd±6º›ÆJ`­•äb­D¦sÝÙµîn œéŒeÎá¶àܰö[…ÛAñ:DàõœÒ&“1n¦žq@%¹÷lÈgdU‘e74YH“3 ›ÜDQ ~ÚIÁÅ÷ÝôGÖª¦'Å\5{–I1CDÊ»IñJ‹Õ0«ˆ—Ép:áÇ\ ¤`Ò߈„±´Ä 3Éi#'3¯Ý!'£Û‰b úAnAV¼EýŒŒÌê­$¡P†>41A5a<µC2N©yZx«€ûœ3²ŸþUJÌÈÉê~JÜÖ¦â…;lÃ(žzÄM`%¹î¦ÄKMwË^à&ä?Ãh&@ÆRíˆb©¥@tçIU(&rb#™Yµ‘Û~N¼p?<†0Ý„ÈJ ¬h÷Ú"´£ï'¤+Y óôº61Á@!ÎCZV«W8És¢[±8—Ým1;Âî6¼XÜ=ÙÑ ]_Jl8¦—J¢á{)ÿžÃËôvTœ®’~H§¿ÿ㟠†1Jî•ÓÃç_~y/¾z|xšˆ¯<'8ªùÉ+OÃê°ýB”ƒ_Ϫ§h<æôúãã‡ïÁ=^¿|•Noî{Jï~/Ž× ywú³Ý?<}ò›Œù½¯úÓãçîç¿•íßþvÿÓÏï¿{ü-MAùµFnª_¿ÿˆ¯ýEÝ^œBþ„‰ç}ˆó™×!çÇ@b 1¸¼\cÐbÐc0Î.1ddddddddd d d d d d d d d d d d d d d d d d d d d d d d d d d d d d äÈ5k ×@®\¹r äÈ5[ ·@nܹr äÈ-[ ·@îܹräÈ={ ÷@îò»56„¶"·_Âm¡yjˆˆû~¦¸Ð’‘gˆe$HYl»y^d ²‚ç¿ DÀ~CŠôÔ`³¦³…žC‘'ÝŒDlRC¿YŽ ÁéÎe?5±õbðo®°— ¡’©ÝŒÅ¶!qIòŒKª•$°ä3eobFú<ޝ‡V€Ü-Ã(Äí#šœŽ.‡j&ãð°y9ä¶”Âq¡ãÛ¡¥ ’¥¸˜!Ãü²îøj¦¯TL„{Fq)Bµg7ÐÇ—"}½ Ôp„$ï#®B»½¸8¼ ¸ DÀ2¾bqXŠ¿ ¯‚{ÃG°8®‚_…E……h_±8,@¯dÁÍ‹Iu ¡&÷Ô‘ ÐkeQa¡`$¼øÛ<¬@8A.›ÃâïÚñòž]ꮤ5#n=,».ub¶Ûú¥àé…or»mÁóÂâ\j¼°8ª5^‡Å¹ÊwaqTç[Ëâ¬ì¥goÅÚ´â°Â¶Ô£×æ×Æ[ §“a¹êÔŽƒÛUœ©‡w_„7}Fqë ¶"Š[a+žQÜêëƒMò‹!ïN<›‡Å­kD¼çÚ!Þ{Vmë*ȹ¸ Èqqke¿ —ÜXpL˜Ûsrãŵß:saqŽÀÇœ{ÔoT~Þ:²<;÷žæèÈ:ÌÎ×^‘*Bý`['R…ÙÚov=³5eE‘ š²‹W¹.óvZÓv¹.{F;í5XœKG¥Šµ;‚Ì/Ì*â)/xêh~avØÕ»–|˜WI£^¢Õóõg”Kj½B÷f´GûæqkñJ½B¶:«6ê’÷¢ ö>,Ú—õ×3Q´‰^ïâÍZÿ,`ª}Å⸟vegAÎ5K$PY¿ÁÍaC-[[Þ‡ãÚÐôK×àqÝf¥#‹ ™—êþ?ëœ7ä°p³R7}òâ­HÑÍêÑ÷l:èf]^ŵöìfuÄ6x¯ñQñh­ üJ]¿t³ºåÏhfeº‰s7ë™Ãaýê*¢›õLâ°™u) ˆÝËçnVWDY‡%´¥–Š]êíÒÌj3ÐäãfÖ¥þkl}ÑÌêK‘–ñ–ZËhŒfÖh#=lfe^ïÊ/ͬ$<Ø=¬%~Åÿ;tü endstream endobj 9786 0 obj << /Length 2184 /Filter /FlateDecode >> stream xÚåœ[wâ6€ßó+ü¸9§Q­»ôH²N–†5n·9Ûœ„nµìŒIB¨ŒÀÖn_Â%ë›f4#\çÎq‹£Óàèçs $CÌ nŽN ;ÁÀùòáòÑQ|ÅÓäøqñ¡1›†ý0N'ù£cä~x:†úÂÑtÅùÛÃAôSþÜFQ˜Dù ðø¯à—#/8úû꡸ÌoMw¹Ó}ùËuúý_`)œ¯ó«ÆaB?ŽœÞѯGî2£+Ð.æ ÿ”ªà¢§|ï×ìÎ?Ÿc±t9£Qª¿k~ñŸ.uó‹[º Åó57ÃQz2ÌD@3x-¥0†7£ÈôõšJ𥯇?Íñ]€\‘ñq¢ÿÁœXýëMÿâÈù2¿bnþÁø õ ÄzL?B 5Ïüvñ Ué°ÿ¥¦¡i!¡MÈ_†–#§ßg&TDÇd¨P®G¸¼D“¾š…±‰º¸Rl£îô8ë™`øJ56>6¤zîiçF&pˆF»'ç@ß¹{Þ û†JˆËë©kÌ¡ÏÌìßÌI?‡(`¸¦ÐúNL+Z?Œ£d—Š^çÉBŒÜ%5ƒð1½Ïž™æ5Ö+vMý™À€bhƒ&ƒBv ­';»Vö8šD_õóÑÈ„¯ƒ5I`=ù%R"’êå¬Hûa‰ø¥+š€3dtïãhz;¿†Çµ[‚¬ðíã¤?ÚÍÈr'È[]@ܨq­ê4Ïv‰¼ÿ®ÇuuàÏÖâªtª’Û$‡“»]zv›¶ñ!´ùv ­ø…ðHèäd¦¾xbqî@lbHU¶–GSn"€œ×Ñ֡Ρ‘X ™šÎ2Õ$µsæ°¬3_ÆÏ³í“©i¸JÄ¢ZJigG¨Åâ Ó49 TÖS÷ -à…;0!À…¬hg#ç@ò~ ÕŸNÒè[ºS•ïß×qKŽÊŠžc߯‘1^u!LT6|#VnÉåZð;£‘—Þ¨ÄRžÝ‰ˆßþ‚?«_CËÇ1¯ìE»2ÿuöád˜ÖpžÓwÏó$f5gۃ絣Ë@ùÞÇžê^W·ê¬Óšíß<“8¡’%Œ_*J'ÙDz­`°o]PAµI/«ðM1k_Õ&ÊëK0qØT?nÂþÃN­ä‡§9ØÊBèáävjJëô§«äæ4²laè’¯åÚõ'á]T»à• nãp’ ÓhP¯½*Tv¯ê·8y«tAmQPeFî4ÎÓ˜IšÔ­ú‚ÊV_–á l³Ú9;*™³kÖ„iø?qã/¼ ºÚ³—m—xåE“»ô¾vŽßkàk6ãöÓ'rsý9£?/rhÿIK*S3‘€2RI_¶ž” mØÔ Jþ “q'÷áhž‹g…p”Ô¯zÈKV'3©Ihì (Ýtj*­-_ ´*ÚP/ë¶AÎìý}›üöòÛQx—ì4Ѭ»Î4¥Mçsò"Í—®œb×ÙK§™Ú€“µ­0•žè6è≮éñ™ŸÒýqéÌ’…`0e!OQ<¼ý>/–fšzôÕ0I{,À0ª§â‘ÎÄ8Á?·Aÿ>ê?$ã‚øÒÊn®3ûN b²XûY-¥¸ˆV:;LaÛ³1¾ zÖ³ËPîÐAìêãêÁí³©Ã0 ›²v¡8ú[M¦·áÐÔýŠ .ÝrC&/¨(Z©ífqX_ü&/,/­õ¥fŽ!rS;…Ñ'À…xKsaŒ­Id)ï“À<¢_=d–@PøÖ[Î r¿{~óüZ5ÛÍçÂ\§¨F7;á¥ÚóF³eRäò×ÑÍ]ÉöǽÄ!Ž{éõ “ʆæRX¬Ö“oSHÄÖzV¡§Ùƒ½ ±¹½Ø%’D©²9“ VnùY/A²ç&©ÌâhM*Šãi¬Öò6Î0~Ì^‚(™b_õ¼3õ±éŸ6ƒ÷üÒDÕѵ¥CùïV‘ÓàùMj0; ev`×É·¶k³0I¾Ôì>³ÍíQ46~Ë XÕ<b?"°úëFêâž‹Ò Ö!zÈö‡ßÌøù»µ;ÈN¶?È^À?YþÕEs!€e¿à[ý‚žïÆB}Z‰W²ÿPíö'Ø 'È \Y°µj]Ü¢pX¤Ãb+Ã"œò} K–—E­ Ûß°ð;†%\VAiqJ7¬·†iW–•rá^zV÷Òk´‚> stream xÚ½[K·¾ï¯à1¹pX/>Á€mAI€l’:(ò"0bìÒ pþ}¾bwÍ:—i¨-gØý±X¬wqF­–JµÖD">h‰ñƒžd Œdsª•TçT£ÔæTã4¶)IT¶9MÄ¥Üad©þÀxµDµ°z¢&ó‘¨7'¢—„W¯Sbš³sõź$ÖmV›ÖèæÔÎÙš¸OäŽ 1a ¥úhHŽ7J––Fû"Ûs#)³Ó‡GTª£Œ–TGÅ£'­âôaÏÚ*vÔJIÚ1%+Â>âdäÄj4Ì_³©c¾†Õ˜Ù6¬Æb¾ž"ÖÁX Ÿ‰+O\¬Æm>P±÷á\¨XM ;W ¥$P&b5áá¸Ø‰²/\]ÿ¬úÂS»ë†€Õ¤s½{ñâîòæ¿¿Þ§Ë·Ow—?ÿëi~þëÏÿ¹»|÷øñ§ûo ÌCywùóå/—ïßÒüpwùáþÃSz«½f‚.Šö,Ø•Žž g"62‘à¹oÓ‹éòcºüéñÍcº¼Løõý¿ï³õ?¦o¾¹Ã¿Dèȃ$R3¶U¥lØ¿hËdý$"‚¬Y¡™WNˆe.·811‹ƒâ¬+8ˆ'Ì]f½Á ÈäB*še7Ðé ÃVp†ø Q†U>‹ˆ^ò€âqïÙ Â:Z†ŠÂúe‘vµd·vÜ*ÎYÜud·[°&xƒŠJëE“«æ*.‚m‚(Ë0·X!ëE“ ¢ÉU²6>ŠžÝ²Rvjd¹ÂR³ÁdÐ ^°µuTø xæ‘ —qÉÝH`È*ŸD…B3Nˆ fÑ‚Ë!en¹–z/hL¡d_žÊ`Ä q#Ï“¡³x±ËökmÏr“BDx‹Š¾þD¨ÃRÚõ@ªƒæ$"  ñ)Õk "v11µ‘[?C©Ïœ¨0âr'vÑ$5Xk»Š&¾ܛŊÆ0 3‘ʈ`‘sÀ©"ðSØ›¦be\ÑZn. #Þ<ÌÓì<¢Oø3;‰ #„VH“¨€ä))A8< †—¥³Xa‡ïq6Nœh’;yºÑs±³8¡]¦ûê°RÈ‘xáöJm®0qí(§ñ1¼«Gµž€9¹­ˆl‡žÆ öøTh›qKCÜ*àçÆ8‹„aò«Q0Luã…VHk;‹•¾«×´¡¡^U Bqܬ†,%Â<½„î›fsš8ŸÆ ÄM3»Â¹ÌNÇ(ºëuÿLí4VÀfx ë°”ìÝØ.ïf f:{†›7¯GÁ×x=ÂIÖ+dõ¬Ê!võfL…hzÅ®XámÍr«‚ä|±‚ l4/GÕMAÐbèµ²“8á:EHe2¼”öÒËêf%Ë­Z±®´XPKo¢A[«©àJàÐLzÖ[µÅç±+\É€º^„kÖ~šTÀ™{th"ª³¬îO‡MNc…Âw×{1¿xÏÕzîtáÓ¼(r ¦WA`3dV´Kó,á³h`Û8Q·Ž‚òd„¶I½Éˆ¶’G85C¡ð'ä]ꚤ¢Ì°‘ÈlÔKQÈ1fhÓhR—׳¨ØÍ•"¼+tµVŠcicÜ"¾^Š2{¦B „CÏ¢"„¢ôLÏ2AÐÔ>N¦A¼…¬ùJE©yÈMNÔ…ÞÃ[Áe$ñâ)Î…Ì –dÎô¤œÍAI’Tü…[÷Î !—äE¥ö“ìuÈâÖ¡G^Ê8ägÇz¼Þn{‹Þ¯…á>lÑ/¥bñf‹žû5Æ;lѯeÅž¢{Þ+<‘¢÷è—R±§bLø©=;îѯ•Š-¦ð}÷~èS7é×J…뇷èkéWý8nÑ ¡p½¾ú.Ç=ú!_á<à͆g¥q‡=ú¥TìÕ£èÑGõè°G¿˜ŠýDöýõDŽzôK©ðþç€÷ôz_È#¤£Ýô¸Gÿu¨@ÒýþfPqÔ£_{"{r ÅËf|OŽ[ôÄmmQ²IóvÍsðÚ÷a‹~eïÍdÞkDvê­yM/æ¶è—Æ6ðÜ`ýìÐu[1flsØ¢¯‹ XH&f‡¾l×gXqØ¡_y½*DB)éïDâ A¿–„’çmQÊ„¥¿yØž§ºÒ‡Á¿B[¢^D4k%GÝù¥|À†ý&è€lzB Űyaà 9¿–îE§Ùš>t”qЛ_k£´ÎØ®I–6wk‡­ù¥¦ZF™÷C¼†¸ÉŸWñÆ—4ÃVDÝAÔTÁW ñâHã/iC-¤B=!Fâ ¯–85‡  ¥©è•Œ1{æÅaï…WÞe*[îm׳\BÞ(> stream xÚå—YOÛ@Çßý)ö1‘Ȱ÷ñhˆLRBåˆ(²q«Háh€¶¿c;TIpR‹ÕìÌüþ{Ì.%?%í`Ï»-Ɉ§¹&þ;áVŽiA:Aüˆ\Ô:u®jÙô*›Þ=ÔÜØZx?_Çw·eC3«sZûUgh8¹»Ï¦esûi<ÊvÊï$›dǬüaÀ9°ú¥? "ü æC #†ch †r}\\R2ÂöCBA8K~V7Dj‹ï é_:Ï¢ÕKî‹Q Â”¾ãÓV·¶zÉY˜4£f~·%ì\Ç@blZöøF-´ž3 ˜}¶¹zOã\•+€R §ãáÕ$«p¯Íλg;…8µ9¤‘ø”V“)R½hLÚ¹(âpÍËŽ3ú%ôSãøÁÀ)µ(ÀÁYžøƒŠü,'õàKè½?>Š}v?/þiØ›/ÖÇÿÒã^ß7CU$ɨêìˆ`ö3ô¢½NöÓfÔÚ+d`”roÁ¬/ƒý¬­eõ\xž›] Äú•à8‰V– ̘÷Ã'ËVñ÷Îãp¯}Þ Ð;TdgÊ(0úòuxa·±Jö$:ŠÎ6~ðå þRðIxÔ=nƒÝxîDûʽi,ŠF¬'£œýÓ£‘÷ˇ…‚ZÚ”WH……ˆ¡É»HÅ“ ¤æ…V !©& Ž ˜BïtÆ9/*ÍO`ÜÌ"?Lá¡Ê§{±ïW-%†é-˜JR€åKiIò þæ*ñW½—¯«yyÑo¾­¾¼q£ ‰Wa\£A|;*®ÒŠ…"aù3Ö±…1—¿àW¢! endstream endobj 9818 0 obj << /Length1 3093 /Length2 23755 /Length3 0 /Length 25431 /Filter /FlateDecode >> stream xÚ̹eP\ÑÒŠCp ƒ»;„àîîÎà nÁ!Hpw ‚‡@pww'¸Cðo’+ɽ߭zïç+jjfuïî^-{ïS*2e5&sS ¤È•‰™• Ô–òrJ\˜DìÌì̬¬œˆTTbÎ@Wk¸‰+ÀÁêjP2s;ØYYù©R@Ь5˜z€®&ê^Ž@6­Éo ìàâÊdjâVA–Ö ØDÌÁÑËÙÚÒÊõ—¦_Žοh~ñ=] pX—_NE™²&f¶.¶Ö9@–Y èàZh@S •‰ÀÁâ· 5 U5€”ª’†²3@Óè 2±ºfV&Î&f®@g€ÇÄÜü¼¥M@u+ øc²bSTssttpþgVbjêRŒqEu P“ ¥¡¦ÎPT k~‘ÿȀ̭M~™+H¨‹¨ë(K°±üª€ àŽiý‹é¥C Nð'°©…³ƒýïZ+WWG~fK7WfgKfG;º_Ô­¬Á988ÛÀßÎ@;àï»ÌÁq'òÛÁ¯ä­ÍÀµþN ü­TQ”‘”PSgW‹éWÁ™~wžÙÕÓõw*ª"â ÿCû‹žµÐåw·~y2·ØÚÎ…ê{p¿Á|À!]ÿ3¸-®¿èÚýƒ À;úßɱX€9»°üs© ˯<˜$•Õ™äeÄ$Õ$~“tpþãÀÕÍò—íÿ'Ãÿ(œ•‰ËoÊòÊÊò{kxæL@f`~®&®n.òß2ðhNþ’bnÎοRSø—ÊùßÙý«¢àtôí¼}M<þ{lM@n.ïþêö6Ò <îÖ.®.ÿðüg¥íÀ"pg­Aÿ¯ûµþ—Gqy~+€üaïa ¹˜ƒ½=˜· ⯑·7ÈÕÁÙ‹åÿî{[ƒÈû(,¬Aæ¿J 0wsdÑY;¹eÄÿ¹,Bü#³ºX@'ð.6³bùð÷ø%fû%—Â×ÛÑÁ`abçôµ¶‚¿½]LÜÁÓéìôõþ[ñŸ‘`nmæ ÞñàÃñ·w…€ïb0“©þ9}´¿O2:ð1fî²óO¬"‹¢ƒ+xNhÿÿ~ýkI7;;E°ÚÿÓÿ^hbomçõ–þ×*-à¯Ôiÿ‡½µ‹¤µ'Ð\ÙÚÕÌê]ú‡\ÆÕ¼¿D@–v@p‡‹4~8và>è­]&6öÿÖgÜÌtqpóýVÁÅû/ÊàFþ" `Ñ–×TÑeø¿ø{ÈÌÁÜd nn€‰³³‰"+x¬Ø¹¸Þlà]bôü=wfƒ+Øàèæêû««ˆ¿fƒ› À"òKôÄ `ýƒx,b/€Eüâ°Hüñ°X$ÿ 6‹ÔÄ`‘þƒ8,28ºÜŽ.ÿ£+üAàèŠ8ºÒ¿/8ºòŽ®ò£«þAàèj'€EýsÑøƒÀ\4ÿ 0­?ÌEûsÑù7âsÑýƒÀv&ØÎôÛ™ýq‚¹˜Ï¤?«ÙXÁ®Ìÿ‚ༀÿ†àf³ü׿€SµøÙÁþ-¬ÿpü‚î<°q€ý[ØýYðËÜÁÍù/‡`Ë¿ ˜¢ÕÂàrYy9ZA­Ë¬ÿ‚`Ž6Ap1lÿ‚àjØýÁtíÿ@60¹?ž¹À¦ ð¾ùK®†Ã2`c‡ÿPƒ“qü£;s4ßSv@‹?ãdû§Ôù?êÈ fít¶vøS{Np!íÀ7àÿ`‰ÓøËÆÉÍ|~ýgKØÀ%û« làúüqÂõ Ýÿ* x¹‹µç_`¿Üq »Z9ÿšpb®€ åögÄÀ~?¹˜98ÿ]péÝÿ‚àêyü58`§q`Gõú ‚+ûîOeÀžÞO¤ß‚ÿ<À”=ü¾èXÿœhÿ|øûÕ\lZÖæàGè¿–(˜¸:[{걂o)6°ü÷¯_ÿ€êÏû—µ¨¨ƒ§7€‰ªÝ]náøtk$'(Òþ¦ôÖ{ȤwZcßšcåQWœ„ùþvçV›H ž¡zY“ ÜKôyõ”ˆp•ªX‚¾¹LlÔ‘HFd y«ÙFž›Nd,\s&ó<2Y¨ìFbóѽ, ¡¤Ž¶Æ;c¦×U }޳dl8O%·hS-'yUp;l’=ˆêGŸ9z/õg‘s&k©ü —ó5-ì½{zÈ‹q*Úvwò”¸éY´§É^ù]¯G©±¹š?“êéUlÏÍ_Éîp˪­žœÌҖͦIBWæ¹ ¸@Í:ÍÂí¯ÛI—Vå”ÃǨK/Ì»h;ÒéÐh.®}Ö¸((õVVú’‡&WžB¡µõj†Ô˜áHFBj…Ç/v>ùÌà°åæmÈM÷J†Œ8ŸÂ¡UiÒûV™äÖT®<¯æûôœ™ìk!~z8Lb¬Ußäò ðš ÎÔ¿óöû:Û\…ã‹úãa@÷®¾7¬¸}X¥Áƒ‚±ïûÃ[ÏwbÍÄÏáY ÏÓ„F¸åÖ­h(jhzïöT|'éšcº#O^†s´¥øÝð«ø‚ýŒû—OÜS›ê)è¤Ë£a˜6S2ÅÝéÏÖtc<^ì?9 ›Ìiüû»ù^št„ýí\ux† ^]wªØx¸ìšnÏu†•)Ï­qnÍñŠÜuç¹Ã˜ÜƒXºî>ìâ·ðˆ£´šoÞS}BÀ] õÕü Ü[A:öÇzüкgƒŠ²-ÌÚQ$¿G™ÛçÏ”õ/†ëœz¼ISoD#ø3fÛhUÌu1·öq::˜‡_»6¹A–cvCH 6yˆv|ëãW)_ÁÉ{ÛYþ…Š€Þ2Ë2©”ëË z&Ôg8jÆI‰iì/E°‰±û9R¾.Õ¶ƒᇘn¾ªh.çâÆ¾Üçr2 .5lPÁ&Ù£ÞL¾¨Ê¨MîÕ.Ï)ÖWº%ñ÷!Ë1GY_Z7WóÈKÃr¤ë\Y«Â îTØ ¶¬÷øÔt’¿”qÊÞj…;’„·­GªWÍx.ðMÌ$[I«ŸD–UˆØ|Ú°ó‘7FºŠtðÓö3Ö†šÒ´øðhÓê}¾ËÔ÷kTàæJOÈDÍm™bêû‡T΄U¢ [åSõSÀ7nOFÊt¼£WÚ„ ÛDÄøy¥Þ[ä—ŽVÚÉw‰UŒJ$ü›G;ŠâÂka-[–æ/¥Wf£èÊ2mŸFv†èù/Wí•K"n|¶Ÿƒø…rØùoUW 'íÞo‘ö£^w‰Ÿö Ðò¤”T¼w¥¬ÛU‘ì6¥(¨ö*j¤5þºÈÏ,¢Ô³ý@?CõîQ£F&þåÚb¯¨âEŒkòÎq/ó b8<Ó‡Íc²Ñ4Šóà…UánŽ©ÞÏxì°Î_r‰!èE’>g"mÝvؿޠF«ƒÑ„ºíûPå [.(IÜ5ÆÏ7J>–Å"¨}ð€{™ÝšM!9äÓ.Fu¬“í¦´§RŒˆZ¶¤Snbô3 ]Å… #¢Å1lc}²ßFK?{cåÊ»lâÑ·ð¯)ú^$´ý³¡‘ °:7€'Ø2/Ã÷Ž‚‚üK&…#çó>ìô ½ã C,&¢"â¦ø¤`#Ftáë™—ì¶>ÉŽ34h×’ŠšœqçÍc¯‚íA8>¾v¹³—D=é Òíw{äˆT[Ö}Ä…f—?Sy|ñSöy¡fFiqò†bð©Ø¥ìIu¯á‡CøÙ÷» ܶjYøÊÓUf½ònž>ÝÝê %{‚6.65fñ•ŒÞžõM…ô6ƒœ#X„¡ã÷K_Gp¤9fX‡_]‡§ÁÌ¥¾z¶\0HÑ•ËÒ–ü5Lm6/Êá±Í|N)›]fÃ8!›çÛKöÔŽ"ó+r×Yýi¸Ûer_Ãkn}çrY›6+©¿ÊwD$}ø2p<¾`·®”š7{i€>C<=VY Ì‹ÈWÛñd×I\º*¹C¼ºƒätuOAåÔïÇ›y´œd2þÌ¸ç ¶Çº8=!¿@¯áœújßPn|ÿË#R`™ö·@ÁÛÆ¯vÝt=w™5H¾Ô"}ž¸ù4ˆÚ»¨¡•w êÕš •PôŠ%¾W²­@\žêŽL•µûŠ)ß1Tâšél“X%wW9Ÿ/ÎáÔpdÚþ«‘Ó¤Ö8¢e Â0}8Å^k0îP{³Õ¼ÉiS“?VXê„ó†¸É5²ñ¥tÜ\)`áì_kÊð¥|,¢C\Él “¢Y ˆï{q†9—zåCKÙ°ˆºgã“î÷â,EèÉv4PQ¼õ@¥ãý‚†9¿®¿…ïd‰ÏæLB„º&źy`ºå|ï]"c9?À¶IÃ1€•Y…ðA¥kå̉âýkz’ ; ¬‡éç¸âĦÊÊŠmugÛ›óQºòø©iWÑ€Šêc9ÚRúÞÜ9E¢E.@u™†0Û¡ÍþPOîZȬ0Ê_ñgÕ)Ȥ˜}³úc‡1‘Öucµ“h1¥¯y-‹»…ÃW1›wú­äöm.à S QßRÍ©|?¡„­ÖxQ—e†!Ú׆Á3_¿hÇP¥ÚïF–1<(ü­=«-‘JJÄocÞ“££– Ÿ×FÛ—b€î;­—}¸–S$LÞ=ÃÇ@·gŽ)Š7Î&ÇGâø:e2ˆÔï [o·´3$uYÄ uVcQ¼«þI 5ǃOfËcÏBMâ,t‚M!Ék½ýÊ/¥ñ.‹³péÅ1 } 9Û"‡½%ø ò‡Wl_:ãº^µ×B@ÂŽÎE²EÈFéôG+Ý ¨†>bÑ’“\ôÍ#¯Ê^¶º m6Y©ËQóçÙY¼*‰…¼u\¾gð4ÊòÒéþ?,¿§2Ùvl6ÅŸŠ:Ø7”ž(âÎï…㑜LD‹1¦6Ž{W¥qŒ„j"Ró4 ã÷³±¸8¢WhüD áª~”›mÛÑFóì–Ãr“çUn€à’ìÊ”óög+¬?o|Vë †[¹Z½KÅø!ö9ÏôËÞ4¼è›Ëú UÝ%ÃÂ3w~6A³(8ÃsM8‚»ü…8åáÎZÓ~Çý8îŪ‰™YÎêG]äØŽWùð×"Dm7”ީܢ†È?F~P‘ÞŠóYâõ˜_:{r4Õ>lG-:v”»ÖìríÀQ¬±/g¢9K^®òx<›Œß/v~¦£êßRÂ>«„9Ví¥¾ˆèúøxè]_Nçæ1д¦h­Ì™W5?ç·Ç©/¬wjrñçRßB(  õq  ¾Ðý¤9̓¡f]?>|è‰Iñ³€· ˆ´€ÿ–Ürìõ«Í¸oˆª2Š>§\BÈÝá³>u‡í¨`MâaÏz&ð*zÁj”AA¯Ã훳hùC؈e—Õ×èF­&½æMžE?ïØIÜõqMv[Üó‹D\ ZBìÇ–¨‰E \˜I› MÌ“ŒžÈä—#„£"÷×1sغ~¥-4É^ë–J,ìH¼=©Ž•iQ+Dă߻°Ùí¿Ûe°¶lïO‘%èѼ¥m5§êF˜ rT8=r_šÂåXÓx€íú”0¹¡¼˜î$aš·ÂŒ–1·‘è4äÁOæ¡ztô[TM¨÷85Ñb°{…"e!ÇCÁž]åkñNþ«ôöÅ ðøZk#Â3!¯j£„ebkœ‰A¯j³£jp`Ï6yRÆ4xn–ÆJ¨Ù;šÌ‰%¿£â¯L ª¥#/C›uÈEV±Ì½Št`Ÿ L‰_\db1w:>Z¶)9ú%Önî·(pÞQ±`3™ˆ0çØ"{ôd@ã‰Uõ,‡c…G@ „±]Eôâ9xŽ%1ao¥gá™Úž)LÄh­&ˆfJ’ã‡#7¦ÝäFsIž+F´)p»óÕ‘Ùt¥½“fã¾Ì*4›ò0føøÉÊ -vÒávô^ÃA¬r­ïñ‚/ßFƒ“ùÀV(ᓚ0k[5÷ÖÚ¡v“•l^ÿX„Æ1¬weÞû)èÍÔQelsã5>›A]D*œˆ>  .šµBİÃgè¯Úü킯§ ï0‹øu¥ÑOj¦"£ ݾô¥¬1O=Ðyîf Øê¿*¬=#%x¥têu.+XÖâôh€Š<80‰u©‹”¶¥Mí–rË ¨—ÏߥŽÐÜ—OÁæ¡è›Ò–‹]ôrDÒ§ZA¾úQŽ!¤ ý4ƒ…ß2ah E‡Ú[¡ÄîZ¤á꓆7¸Gވ؛Yy·Œ§~ÁÕÕMÑ¿ýÒ~wª¥ï¢ Ȱä±Xo¨¼Â«¾&ü¸¨~‹—W°¹ ™ù¤Šw´—ì™ç,I+ó9{ËE MSùDöö«Æu´o/œ+ÁÍÚwhö‰~³éDè½)tœáŒÕîh-ÔÏK\êÐêçÃ^vw5ý…Io¤%OKB‡×θÇÈC¬¤ò!í&|Çat_™¥ ™VÌ;ÕÇ ¥äIö@8ë’Ø¢þÜâÇf¸,"‚§'¿Ÿ» ¨Ÿ{azªiþÎ8Ú—Û&±H+>ß*ª[6ÿxäH“ù)Š4¿öݧhõ®Á䱫&Œ¢bµNQ5„™q@_øÛd-ÝHD-g’ƒ9ÏbÏF­JìîTõ JjŽBˆᤃJ7•žñ" Ã¥.ðùƒž?°%b3ü:üêÏ%¡à]*¿Åc+PW¥½uÒ2lCœæ¦ƒt¯Ý¨—´Ž´Á¼¦\I…Fyæ-$)vÕ—Rtûnü؂經µ(\g£b„.Ì\Ô0HWÂH¹Éù>}ûñ½ðM’m0QÂôv®©Ù¦nЙrözž¿n:Ïì •"3Uˆ8ÅELY šU=E;3ŒeŒSe_e·”Î,ÇH•CájtXë›Ò¦`QµëuƒÒªDp¥t(fؽ<õ¬Ts,¢~V;¡qå´‹gMž?|ÔN„¸’ì³?TßžOªqï ZI™b˜{N“„²Ñu Û`ù$”íùU¨#±ZkÔ»_SZKЇ›²èСÝù)¹ƒî\ýž^÷ÔÙy:¥¯—ÉÔ$ç™û¡ >dy”X\nǺ^^èd@¥¬CFÓ ¿ÑÑ–»׸Ýc™çzÌK [yUóp´YüR«Vèa?­1Fqë}²ê|B°ÝeúRçÛî¬Þ« ·~MÚÇþÔ¢gDEd¹‘[ÔÒû»n_6-¿(«Â¦d®H¨¶XŒÛKŒ&P± ßI&cÐK)øÄ¥Àwÿnì1Rü]|{%'›c ÙÞ;ˆ ¥úq \=j%ó%6÷›<´ƒ9ÑÑÖº·|Ãζ_F©¼¤Bø-VÕ Eóñ¬½Œ³æ˜¯úYâŸÕrñ*uŠ«gxFö^=‹ÄÔY Y³É‰¦ .êþ8ôžuÆè➹ΤZÉ¥'-¶?4y}#@˜ã!–…p¥k¿Ÿ?mÿX«MdY/¬ŽýËØìnàÞ”õ6¡ko™‘GM¦túõzfav6õ Ë3«ÿz¦jÍ“ÙàÛöû8?k5ÈvµION2èñD„‘¿Bñ ]2"ã,TUªžzµÌ™òå kJw¸wr¸ŠÓy°Ih‰l9¬å„Ò"¾ žÀ}¯+¤Î0 …eÍïâÞßiÏ"]GÓïÙ¦HfEˆÙÇ.jL4Á“áèëîð±2ŸËÃÓEä±ÿã· 8+ [Úкg: w"3ýe¨Ô4Ag޵¸óGœ©É‹—5Çu/Ñ’åé>1sžËmcƒz$o«íç–[sýR-K®×˜ÖÊÄø›•–>‚^ædohŸo·ö"™—\ƤV‡—à©ê|¼ƒ Qn̾Z;²O±ÄÔQI!nó£3$º&¬€¤ìL9çò|%^:öÑB. &Öb×_ÁNÒƒ8r¡)‹,Ü>†g~Y#aF“,FÕ¤m·‹ÖI 84‡2prÏ_Âì½ é¤é×3 ë0¯©ÑyÝäïVðöù{þÖçŸRMÎ+-5%®ûi7 Ïqì~LCJb›‚ÕœžVîsIÛë#«²F9{ÁO{0‰(Ÿ;& l´xºŽ!!h{ ²-Â{YKºÝÞÇv —ZÀí'Ô|'Àåÿ×0È }ñé<ÍiF,ä™TüÈãó$¸m·Ü K/wÏ[å^â·*Üxs?i?rßÔ‚`‘1 øŒú¼`Û;ö’±>…¶?{.«‚¬#rÇ·´oJânÕ³K2¹4ˆð%'*œ''.|bÀ©sºt{É6JV¨£Ý–7ŒNYZ’>AãBi©FÄÄÁ›Z6z“>qTŽ»ˆ¦7så¡50Hx%«B»¥Bu*MZv‘+tÒ€ÐéÙnN·©Š9ÄÏ×5mQdóœò ûEýÜæeWêˆõi°Þ5/]|Ù¹–Å…¼D ÁÄj"i¢R/¥í%@ƽ*ÜHQB”žrkzær—Hm œ.Žqu×â×CýYÑäÞÍk–ìïf\ÑŽkÞ}_ŸGy¼¥Í!a趉.S¬!ã¦ö騅JnO|ù²¶†Eqe’'½¬`ß‹)DèGˆjHØ.jm/Æ9¬âT¾ÆŠ––ÿì|!²ÆRíx=[¯lRáœu±»n–÷z—ôúCÔí9c£ïÞ ®Â9àÙ¾MN¬ÚžîžXk+Ñ))lÜ@åêîÁ*6¿ùª5?Ö´k†« ë<Ö*¢QµÒða ؘg>ášCf^À¹,/iÍe½©«Å–ÆÑ÷5>:uI›¾mFÞäÁi$_Qø” oëº.æ¥PÙøTˆµÙl«@DHÇÝOcr¦‰I.üí½‘ÔÞ¹Q·­AxSª±Ó÷9ü/WÔŠ8|T_Ï6Ê© œù)lN^4ÝË×@{ă§XPàö/XM=ë>Ý©mB¡øÁíkv\àD¼Ššé .1°tÇ:•/¬ ØÅ3Ue ,h{DEZ”κigŸ*²ÜsNÚÉ Ž_cÛÎ' µëÖl¯}z3>MÈX%B­LÚ O‚Þµ$ ,@ m'm®tmZ¤üsè]Fêw?õ¶‡T2\<ñóy?|ÄÿélxÖÅY ‹¹j•¾¨æT>Ûêã¡ 6bVïï“ûÙeä9!&‹,étïh?Ã7<geœªŽ¬øy\­Â\<&žµƒ Y ϦÐatymb‘\>)ǕΠCÒäT4ތ̧h*ÊB>Kr©0| 3ãpãküC¹lÒ+7Ä+»ÔA©á• tñ#â@}rGM B)‰²`OŸ±OWuÚ&Ýí´±ŸÏ³3Y9ê$´lÁXˆÓà"I$-/ËÊi釂¢QÑ z-EøHgÕ1KQ}uó¸½v?31¦ vC9We‹ŸaQÜ\wï!½âÔ.K„ Y~‚»#•ýC0h~K¤·ðŒsÎÍÞPãêòŽ[7`rØŸ»°z¤à|Q%¥0Ûñ2Þ©“Þn‰•ú¿¾æŽQ<Ö$÷øÂóå1\Cm›,¯Á¸‘±x˜‚mî‹Âûcú{_ íê¬ÊÔSÙ±>ß*ûù ]»oš0‘ÛI|2Õ#1Ek•i'(WÍ{ïJäœX´Äpí)Óœ\ÄÒ/VkY”2›0Ÿ§4ù>k(QQüÌ8ýÚ÷s¨`©›bxç[û­Õ ”|ÌN€ŠšßS Ò•«ƒ¾w=$¤³ÙO|ã7 u ëvs†±÷Sýo‚ݿ⯠wÚ¦A5½ ù1×lk¯êçC~¼¥ŠL³‘ @[åÕž½ò j•õ›™‰i^„l‹^²4.DZ£\ù†£¹uˆŒ‡¯ú‚°ôYo ù•­j}wu"E%•«9¼È;™-ójâ\æ§ØÁSÁ»i$ÝÑ‘èb5¾AüÅd¥øì=A­G!2Ãn¤%ÛU5êg‹ã‘ò¸SÖ¤ÖäÊÝ‹6ŠHÚ;¯~Y}8›0SÆ[áR)æäö-N÷§­~˜.Ó*§g³øÜçoØ·@©ªš!¡U±V|ºÞ=5Wïwˆ » 'ßFAÿh€ Í}Øã‹'TÁé5Ò¶ð<àO †„–ßøpC¤hV;²œlŠ…ÎI·A+y:Û&ù¬¸ÿcqÑ©Š¦ Ï|ï¬<zÓÌRLU+Û,رÚä‰[TÓôBcÙ•Ô%ño¹· Þ¼cMT.”SY3U _ Lý‹R7Ñ[)‘à²ø–Øš,º£'gÞFy®‰0&¥›²zÂeo™žÊÅÊ!—#眠6ÙY&¢mHHële<| ýr¹UNûuv‡óM3$U\5aºâg¾U§}_ì}ëjÛ¨¾ú}ÉÄe®u‹þþ1~-S]“_5†Äî72|´\ój¨Éä¢Ýü׫ìþ!/cý5ìwºÊÆyF;½P0û…áUÖ8×)fm!áqýéÌ*\hüvoÌv)!_bØË™8Ú [ædûŸNX;x0|#Çí˜î#öAѳKÍËnJ<‰'U SåÏq›&ý·’kWÑbã*ºÑ¾!„ឺ³êTê.¶ò4‘ñbJ×Q~ÈÜá˜Eî/’ই‘ØÊ@g‹fGa ,5§Ùç¨Ä¹¶sªÖ Ç䃸8‡ÐÜÀúø8zƒ%uTitfÇãrÅU<òŠ~)QÞoi—ª«9 !fÎÈr†q;†i÷}Æ%ßVáÈ‚mmŠeÈ3äÄ$üu6ùvÀ‚!el¥v®v÷ îó†Ü¸`°\àN¸ßŒa ‡¢äƒ¼ØàµZ͵>S>éÿŸ‡xH.˃EgÏ3Q{–\ë/Ê–¡ö²w³U.3*Ó:Þ &õ„k¹¾ìÂáïÍ—FÓŒ>=ú*qÞFB%,w‡…å•§EmŒ]ØY Ñׯ¥Êû>p~!‰MA@£Íö6ÿ¥À´‚ãà]œ7Ö‰œ¯v¡òQ.¬”oDVroDêÚàø¨f5À¦,©Žµ£ì™`.AlfÕý»É^&QOž¦bö;©û(Oé×ú8Ò®È:r-8Þ¢ñÞI’vbI‰!µuQJO‚¢Ü®¸h¦é!j–i¯‚…ð]BÑ\,ÿüÏ NBÀ÷0ytÕ‰£;9ÓC‚툰Lƒ;Y=>2¨>§gÞ„þªRQ2µÜ7XÃ!R¸“?Þ¾tëD¢^Ëž2Çp”oÞÏ6çyØ©úxUç5ÎE¡b âuw:ÍuDQ޽3¦ÒØÅõP* &»¯_4ð;¸ «ü¼! Âç(ößvF{ @¢«d-\t¿çþ½O|¶i"©âð…M7áuƾötª¾ löÝâÏVze®ÚÄúœ@îÌ ÿÊ˦p!­èb®’äáEöÂ^ܯ>Pò{ñûÚdÇÂóîì.¦3œ,ð¢—qïZ,ÕǼCƒˆÆU ™¶ô£KH'ý€ñ“G—ëj·‰êÎDÒ]fIÚù¬«F³^#»/RuÝ?yó[µ†ôЂ—YÚåÌç†aV‡÷šH|)•âRB¸lËO§{kÑ7v$Y–ºnò„ G~²S”B®XrÚ.®·á¡÷f-î’Y·‰ž‰Ûº6N™&ó9'“ÕÊE§³ ú­Ìž¨ÐÏÃ_Vv'F˜ùç[(QöÖ¿‘â>ùd—0¡³SLÒî!`ÊšÊÚ£H§ïÊv‡=GBúÉÈWŽetÖGŸê‹à=eþØv%ù‘rÂ%Ÿ„›÷ÞÖÆna_ø¸ÚÝyßï‹°ÓQ€IÓ[hÃ8]ìVošºwM#ÂúÇið[7G‡êJUÝÎ&˜K m­ÖL¯R(ýƒàB{0Ûû£Dýb` Ó º‹3‡nUP2ÁF||süçbÜ’úúaæÏµ 7"–}œ:lž=‡Ž÷ïEG\<á5Vo:h¥ÝG3˜[©Ó/Ð{27°§ ‚8 Îìû}àKâŸ/õö‹Ä\rCü—2Dã{3ô+j7Þµ´Š£¡Q!/B¬ Ç*Ñ™JêÎi»†Ûó? [ˆmºÒ6Ío:ƒjžýõkW°ô”¬'ö'–+:…ª"7UÜ¿»Üóä3]¼Ùvšmœò·ñázÒŒ’#ƒ?5U2Þw¹ø?WP¨Ü>`m{™5d: h(g ý’¶·§~3ŒßwSŒ/îHc‹ rTzK>Øì3ƒ#7'ìx Íî²0×Ìššk mGÇ»Ve2o°šÉ(×ùs®öì†ÀÍZŰºüÆwq =p³Ï?6bÑ+ìa¨].ÞêQíü±®9j•¢g¾O‹¼p”øò¬Õ¬ñÌ=´]ùÞ­˜>äHQê>YÔ{’+wš49¶NÂD×"*[ßè˜/ŸVÈ“ÈÖë™1žY³öZÿm¶ûg•@Nªôð†j¹O@G1•`Al@J—|‘åþ89aºÍ b™–—Ùz+îÁüº‰<ÎftήÐ[㛪®GZŽ¿ç$6N²˜K™Åˆ(Òº€—opw?Êz g2dèÆ²{ÝœymV½1|»O¿ õj•ÿ¼O=çž’bg¬Æá{ØÉ‰lyŽêPD[Qç³`3P†%É’vAöõR¿]¥÷éÐó0rc´­_>Ÿ¶Žm¤²ðÆJý¾ï8¡ÛpÝ3EL ÊÓ·‹qý2`‡Â‡‰¤1ý¬“FSI‘n_®Ë%¡Q¤ïŒ;ñÃa…n"Únž0‡x³™èMPafšÇ^™Œ"A¡¼TÁ@ðÚÓ®!Ôçà]Ùë#ÞáÏzÚ=ÞšgA¼ÏBúá«îÁÿã-J†}¸éXTZÖ 9,c|JþÀûDú´Á68hûuùï|¬¹Î¼ÛØ%ÔÉÕÙZç—Ù7–Ùi¨¥}XøÂP 7ä©›©ÑßhVfMú|™Öë%°U®ºü¤ëFg/£2Lµôˆ6ãùÉÎÞ—×MèS-_hãò½vÒ€èü¨ ðÅÎßÀâˆ*/(˜0 `W I0x;‚•N_ém¿­M)Ï„(XÈ-4šH%†dÇ@õâxBæZÛýb1†Âcàá6 ¡9^¦Ï‰„ûz"ÚgŽ1Ÿg5JT?>!¥Î½s²?A|¥çêÓäg.Jöìæ‰ããèÔä£QEL¤ö,Ï|ù›†ïÊvr¬E·Žgfü G¸N˜õŸe„µWÞÈ¿Ê2@,mü^Üñé´ùž¦Ú“$NɆÙB¤“¶ýEB^ f&¤8°yþL5û š¦4v00‹ÑË®ëF a*²?‘?!õÍ@‹}#rø•L—0ì/9á7E=æoRŠYSf«¼A"–›MëòF 3tU mj<ÂIWÆÓmã³/Ç€“ú yµüÚB¬ý$+v<ìã„2”r¼ Ô'†CÈar¡C»Â‰BøTÏì¯Ã k¾²©ˆl¦‹Ð'[ሲ•—€OYŸt‰Â¼)Ϋñè¾ qÈÏ%c15EXÃ’ˆ¢òòçøÃ-–Ñ~„öH~?ð6u´ïõ×\‚ŒÎçpu·sÂÙ•zZÉòi\tNNÎI)Oì]Ùo¼s¸ó‰Æ(ív¥Zš …”LÛn©—P”ƒÆÝEÃŽ“r9ù“¢7Áí‘j¢…{?±w4Çi¬ß¼Œ:¢ûƒ/,½ÕÈ]ùA(%6ZŸ€{\/wýž‹Aý‘Ì:•\jÙYÁéFÎÊ\ñÐÕq[W”ÇÚ_¤f߯»OK ÷«.ekppÃbúä³¼ª.mi®ºŽFÁô\»z?Ø–s7ñÁ¯òؽ=¨ÍÎÀvXìÁS‰ûö«Å};^˜™õ‘&1#,[Qµ•ÂO 6±¸‰[>¬Kßù|9]×¹ášÍSø¡òSÉË“;»|‰X⾉ƒº.¼wTXº±YåÇ^v×5'ïF¡Ú®~f¨þu™ÀD‰ÚòÎX+`Ë)£ò²ä#ÑÁ¤<”ãÇ+üÈ#}XÑ¥ñÓ±ók-èª74ƒÜé(¥ú_ «´;ù°›¡‰îZ]ûíÑB¿ÃñŸÇD´ÈÖIØÂl)z¥çcˆDCwãp^ ÎsEÄš¦×ßzݳ ޏÄBƒöT(YÕ>‹ ÒÑ_ÖÞŽ{±pfçªü,(ؼ!2@¼òßÜ;Gepv.ìÇhÑ´`4Õ¦ÀЧXGÔÿ€—®4^¨¦¨éå5×±J4 o‹hV/¢!&£hÐwôHgFŠ‹IŽ‹ éÅŒî÷$=µ?7êwçvAS0L?c&…hHh‹¾ø¥[~bÑÎéùÚýf¤<ô¤(ŸûûSÞýÜ\/Á,ãÞët‡§X“Ç%–ð5µl£È¾+å¶Äg~N²{™ïDã/°y{¬T‹V×u¦Õ¾É7‹{à<ÐäÞ˔٠fD`ÜBX è˜`²àÓèUi)g:&rp«1?'TCÀ‰ÿÊ”|·*lV{ .x p Š5X¦¥K /ä>°/'’t€E%§ñ®mSs—ÖA³wìÙö}<†°?¯t­­d²°Må ÖmJ!çLiËåÊöFÄ¥”ÝnæJcîã4Ò@\gÙî¢M“}WtV¡åì)rª/MjV÷[^6þâ–ø4;B«"dJ'îRNOßNûzõ7o´ê½JµŸlé={?4V]‰³ÙU?½‡Ù¬`­n,O:ëgjŒìç>|Û½å:œc’Ûï ;!(#aRÿÐkÁ|w ÌøÊ[0žb ËD§Ùw{V¤4·}õŒt…†¬Q«7êha2™Ò`¦óJ }AVôþZtrkTW„~æŒK›ïô¶}j¾ïêÆ‡UðÉÅÚiÅ;Àë Øn$ÐõÎP8Xù¬v`‚t>éäû2Ð)vZßΟ X÷ÑÎŽ¶#IJ]Ûx"Å«UÛq±:Oéu!u¤-œ¢&Gë&H!®ÆomÜÇÅ4M* s§’•Dl )ª.Ž“¹GJ»q¬ëçFðô´ê¢b „‘~ùPoÒ?äh´Y¦Ÿnd—; /¸ôËRLð—| ¯ÞR‘CÐÇ0’è Ü•°àÃèæ2øP—Sn'À2ŒåhX{Êz—ò›Û’7—»+™WyÈôË)Z„#»toüG!´ßòÊK6»ÜR£'Þ}Þa 7."Öf+Î×bc àð”Ü¡údìÙ?×P°Ó¯9w²õöÐà/hQþÃ-Œ{ËóñM›) ›_Xx ™Ö<ºµgŒò~në”Û²úJ’~Ck“ZFÖNZËÞ8s ÆåÌù6ÚÎ!$æE€üY‘®ýŒºðÞ¯)ÅJ[4âaCÕiV[«k”Ì|¢ßÏ‹&o»ù I“„{<5)á|4o¹— :–«×Ü%ò§<‹g‰ïÍÎt¼„Ìð¡¬EÈïøçâ*œ–c»ßä FeV“–¼»_‰QŽ>é&ã‘·ö¨ŸË¿FÎse¸†sysÑ}Š{¹×äßöÃë“å×ZwÑ %ÏÚð©wöÇè»…°Âp£•!‘ …âQ˜by‚÷LJFgsYå [p«@ñüÚ@-Üh91§®‘\!xÄ*é‹¶^ÿLÛs/U?'î´àÆvGˆúü˜ùhwâòž'¾ºõº e©Dô¡ÜØ­/DHû=^{ì,K c8T†ŸTµ*ñu]íTÔ DÉ—8iêB°¹L_I4 Æ˜Ý»£JÞÅ:¡}g¯Ñٖƾ­½F!ÃòzbåjÛÁyš-É©#2}çûim Áƒ}z°Gpõ·DIÛ³4µ/Ê´ýTÚ[ÚQ±Bô“w׉ò¸Á#>Üq„âI¢Zë ñî6JhÌzá(ƒ‰ÚÄŸŠ’,M "8ìØ«ãu^¨‰AnܽùüA~Vê”ñÌZ€×/á8®HÑ+P§Àv#µäëú~n}©Êéœûl l¾(˜‚ñ`" =³Zídc!]µÂGâê ˜øNÆJRû~6æ4R4´ºÁ¬XáŠRÃõE7Rà5%¶œ¡û³ˆô5Cª´ˆ+9X!¸ès¿ÏgüJo2Fs¬˜Çdþ,ƒ>­8'¢—T¬¥ç‡?y-¤¼ßD¡Ä“ô14½iïMM;ôœ %…VÐ4Hû-aEqIß¹ïkVˆ$‹‡³‰ˆÉb@—Ùâ]Ä«â€ÀWOJ¯3M 3]— ¥TŸ¡¾¾?Æ?ÛÙgq:÷ã¿02h|Û‹ø´QH¾2r3÷ÚIJâ,Úh+~â™AQ©ƒD‹‚ñ”‡8l*‡'²¬Ûù‚'Ép´éÄ[ ÏÉY'LñU IžZNbΰEm}÷Å)‹¬b–¹¡/=? ç‘ee@þn¹-AåóÂ!¹æ8Zpኋ‚¼±»*èf`õ¦¼a¬¢'uÀû½›>¾•3èÿ†bà/`4ý€yoc~ÎX1"™vðÍ~ŸxõŽís'qA 0I¼1û§ìôX—² ]/ tü»M»ÖþÂãaf:1/¨½_±e×ôÂÄ'"¦Ä=©e>{ÍÒ€eúu¥ºó*§„—ž#ú»{ÿLÄÚÕP~µDB?ú%墇÷dTÜHW+âÉ>†[ì¼§†Zv þ&¼ý“Cq^Œdïlªô,‰)ú!£æŸb{FÂD4¾ÉÈï-Øû‡LáIJYÓ¢uã{#¶y@ÃXˆM ZõQÖ¬X8 •Zu}l^ÉëK¾zaÄ£)´‚ÃQˆôÝ\Çî—.,9µ>Îfvº‰rUs~‘y̵+MËYoÆ;Ò4‹}¿L§d÷ek^ÏÜA;U]H¢ê3î¹ÅMÓ;†íæz”“_âHºáOÚ Hˆ¾úÚébMš [»“™Tü1.ܰ€ÞÓ¦eÒ8ªÜÉç>ä0sدx+#]JôEäù™è òd‰ Û¦®ã9†Pê&Ðj­ÆœÃ` JÅS'Ç çÙäõ«A4€]RP“[Ž“Ø'2’ª!ïyœã{š™sø†‘Íϳ—t>¦»ë4fá>8TÂvv 27c¿ (a¬àmÇz£†K;æù,z}ðoGf•ÖŒ•×HÅ4„R^¼2·M˜I}¢­˜ ÔTc"s®e,wné®É?Åôq+;>ÎÇ'þ÷çÌ‹8¤~«6EYPôdT SNè·+ï3Ô¥ Ö~*º6|Ä>åÐè5¸;šõ ̤گ«©&¬Ãm}™¿å¯Å˜rÉ“nKZA¸á*¢ÊØiÞÁ¾©ög7ÑsdKWW?­)ŽÖÛÇtöïX—u@<$ _â@ ówl—Nûdi ·xÝ%/à]…¯A/@[ÂKR!êW7þxñMCAñmÚ¤MtÕcŸ¾ÖÔ¶mÓ`›HMIPÖhq1^ºgs+¥ßeœ­kô\ûÙTqµÅu+dMé[²1ªA/nµykX~ŭނ댔mÓ0îf•슩Ø:Œ‰vG6h ™i DÞ.´bÁn[ÞIéC¦ÈóS3*ú@‰A} %s†!­ª÷6dÏåõ'¼Û³èF¶þ÷ù=Ë—ÄôêÂÛ¨^•ïõêßô64Î^Û¾ Ék¯»á¼5æ¿Ø™Ød¿•@•m™0,3š±¾¥h!àòBjOXçñZF?%å„ÁŸHÿœÜÙÉ£ÑM ”âÿX“êS™p{Ȭ/.ÇÑ#TÑáˆL´•[CrØÁbVëåÔ†ÒÎ??7ÑoE%¢»9+GuKA@Ô÷É(ðí\çÇ­~µTeÙïËG7âÁ e{ÃúÅqVºÚp÷¨ãæâ®Ðò‰ÙöW13[nį?‹=oñ㯨ÃCókËn14 HjдÊxZDŽ:3Ö<ŽÉr¹¨k9Ù=Ò?Si£j|ckLü§¿Ï“|ã¶zŠÓå@ªiûÒJ,]ÚßQxtË4¹:;LaA›ʶ±³ à’"HìofpËÈÖfÁÁ¯Ì ˜¥5«˜ÔR^wƒ` ·Ÿpo Jj[Ôc§8Ü4Hß©£Æh¶â)‰j¦o0 ¦?!ÞÂ$ Wîîê ùʺìµ^ë#ã½á´¡­Žê¥Š›òŠÄ´«YÍ”ƒh=·+pB‹ “†«‰ž“Hà›&„zŽpÛCÊr¯]ëÀ.k¦¤aì¤GÑ–º5C®û4 ûX¼ì¡÷ý?6!ÉÞÙQºp-»ÿºCsÛ—-}óÃ~5[üT‰ÚìxöVêf¦ÈØ Û¼¬:,™$_'‘^õ!9GXÄÀÀVb°UŽ¡£ ]2Û\h´÷ëóܦګu‹×ú})Âfœ‘¢¥€J¸å.ýð½·u‰\GFìø@¢:„¬—»îïNxvŠ%Æ æ7.I×»M½4EÍ88‚¦jLø×±â€<ÏÁÉøÓLSê/Œ‘[Ù\¶}ž%ùÄÂvˆ²ÿóõ;¼+ˆ‘gªhwígÙq•=€©ãíÄ>h©(ÏÄ’p"Ø’ƒ›cÿÈM-6«3MþP÷+P„—F/§Ä?¹c’&Vf×W›N—™’Îë‡Ï~b«Vªéc@!¢¤2¬!LhŽÂ„:ónŒò4ô<Èu"l„ª ­î½­P8yùûïæ«H?rÁHi .tëà’…ñš¤Å¯ K8 „ZhÏEÎ,ãp  #OÝ–Qs˜ç(œ–¸zpqÌ’ ``ÛcÑ,]'y‰ù…ýutW|o¾•5¥ :M #úPQ³×C¯ïÙ ššìÜé™\RkÇ<äç¤èLgR[¯VÞuFNâd† n1TÉ5~haìzëX³M Œi2\ôù9šv~0š¾l¤PgïÆ’:_Κ›ò»&*ü¿Tíæ,½€˜VH›A—ö 4Ø.¾±Q;ÈÁÈ™(+L*ªiî/÷φI¼!Rmã,l©*P ›qÏu¾v'H…/Ç(lb¶˜ìöNMmµ5’.9È}æ iU›<¾õù»rj.‰æêü³f*x ÍøL¾ÞõK8P"}/mSî½Ö—Ôö󸻀jE:³nn2Zí¬‚eŽÐ|?K«Âô•¨õ6ÆÝÊ}ãU€€ñ6:úºôn1Ê„9 «Á%5—ý„—Ó»ŽŸPº>À3QŒ5åUTnbh:£V6cÿ4ê#v˜G¸ÆU+ÉâRÇ/Q°_¹ÊhgæRÆ~ÎúЇQ¦¥›¦ó5XX G ߆,âHY`ì"Õ&ŠÃL“æcŽZf2É©W°Ÿì.ÜG°E··÷<¦œ{©L‰ga9¹[ap¡…cgî?»»2ùßo5wèzÞ“jj¿š•'Õ ëºZݳ…¬‰Oüi²à :FÑl U~çf…(Û!a•>Œó]<¡ç sÄñš ™¹@׳±Ñ¢‡…òAçWB$Ô®K¶“¥$ù%󍨀ž|B£D6t¤Ñš[û™·êžˆ‹3Ýâi£çbj N6¾¸``AíXuà•ÍRÏ™Áž—îÓøxeèç~»eV)2¤ê´Õ}vƒ‘ªâŽ.Íx•!%ó¦:RàˆÈO`î©¶ÝNßÌ‘l.\[þôÝ™| êþY‡éÇÌ«DâïÁKb pj»”o-n¹ŠðßèS £ß¥&Mkd7pÀ§¿rheÑÊÿÏgXZkËâ-¥:K¿¥ÿήž—fG2kcÔ7îbš¥0ƒÍhi`Sé`.æ(ýLÿ4hB[¥-BÊ&?u˜ËN½E5^³Á‹¦o <:›Óù1îtýLWÿT\ hÞÇ*¢| ¡@õS]j÷aô7àt¬8¢ƒ~à¡Ù‚Ôâ?Ò«Ãr°\q†õº$IÙÑ7øwRÊø~˜1uúE€¤w `Ù>™ÍŒ 賿Xéqðw\à…Ù £ÊÔF3R‡éI²Ú„a¦«ŒHp4¶,.Š#³ï/¸)@Zc*•™#m_Ü¿=%EmnÃL¦l¿ ž‡èÉBON-¿ÆšÐÄO¸èäkéh›–+…à ÐÙ)šÎ§Ôª° Go´ÒP{â·IÝ4„Ö$R@iŽªÏÎ ÷/Ì÷À~F‹.Žv4ÒÆÉ¾|Ó ¶'cõAeCCªT˜•Ãü —Jý­Z¼èú“£@Öú3ˆ\››e~yIJ˜xò÷Сqö›NÉeò “¾þ¨ËþbÊÝÂÀ#Òn{­É‚IŠDqŒB‘¼N Ûìä§üXÜÂð _$Ob˜E;OÜ“åÝ/3p_©×Ϲ~̧µ¢Ü<ÖÃÄùxSEÜ=z_^÷¸ÚÕz=[¾Å õ’áb”lÝSTpe›áåZÊ÷T¨%Þn ‘ ¯ˆæ0œ° £\ô3uXª9Ž7¿˜O“Lf˜l.饥ùZn_ù s‚È¿¢[zd!]ø²BDh¿×àtwE¨Ü%çsà’[h<7(¥OÙáœÙ@Tçú^×yvÆz€‹âÿ\vþî¯-©xªÔérPV ©ºoŽC&ù«ÿa?{mžØÀZÒé·.Öæ! [.4ýà!Lù}S©ž3ÇïéßmÐ#ØôÈ„Äüÿ:㞺ôVu,£Q¸S™S'Ú™ä”ÙáþŽ·y{aÝôExóPçi§ë›õÍD¾dc‹m•'éÆu7+Ýs°±›ÑCƗѲ–™;µHlÊwú¢z3EÉÁa¢ŒZ2M1½+.÷!–œ{·F2éoæÊ²%•)P!(¡wÿ¾qŸmÒôBHÞf¶êÜTèKFßn›Ñnà„lÛ®”h„NÆ*`µÁ)ׯÂðI´×J~Hpa\¼`Q¡ðåïê¨ÇÒØÞç¯inõ½ºÎg=”ÝJ‘>ÏŸíÊ ;8œæ±ºû{ª˜“éÿÂHjÞ°ˆ<¬.GIÂtv„ËD°^e 0·ÔM‘Ák’–Aª·…¥£÷<Ü­e¾qŒr¨@ÅÖaá‰üQ[ö<²‰×¤4‘ÄÀƒ‹yrìö¹vßD„g¶%+£®îÆP„OS×ú¿pÊÿ€¶~5µ¼óYáS~öŸèÞ ×áX¬eîxš‡äRÔçÌU‡¯ï¸S¦˜j¸80œ6…>$d v$—’NŽ[GÄiØä¸½ýÖ¾ÑfÎI z®`L‰ùuSæt¾ LäóµÅm ù˜:Ýt¦r%4º4™óñ¿0šÝ Þ">v ­wòÉ÷RWÒTc;½‘î?Ö¥"(4Ø÷¨‰A÷¾ZÃ?½Ž:›µ¤IDNî4©#V*€ÎêÀûÜì¿åÍ |¿{$a«Rˆwƒ(§ß +‡še -ÂÖ ÒrÐ.“-,¾> ½?æ EyEîq Õ3Ü…ùÚü_ØBô&T'çYy 1|P”^}ïeù€€ñUëϼâLº¯ùFmª‘ƒŽ×˾i“»tUË7LE Z4mnK¸%oYøM‹-5HÅê•›·£òòuö.rLWæhóYHˋȬ¢ú³Š[q>  )ÙïþKö~ê("¬MŠÿyñtk¬ÛoÈ=E¹×87Á)ú1˜@®ûsö†Â/U·Ê^¤[§­l„–5ÿ›³N'RÀ¸9ÿžY¯&ì}’Câé;})4Ђº‰aáC$ãš)³Ò‚y`î*ÑþÜÇìžžœâÓòZ[\¹= ÚCÊes÷Ž@ª{Vëæ’Mjö É(+JÐÜVì¹³ÄB2H{Ë›¹FѦo÷÷°‹ÍÈe™Hø@ôbJOA¸Ý¡´(¼•ôÄxC(½M'W³ëúþ5ØÅf!¹mX 2¬ÆÓ&õ¦lüФ°ùv·Áž¤åàV¿/ßõÛd ýØ"4 BÀ¹¼:îef@¹ý×Ññ1ÓÂÏt}5û…ÙA»ÅUzo£ÍŸ´4ôÑ$„à>ÉÍßÊV;ÜÎ1£X“<9µ'Þ馱:>SÑ÷ºL‘"'u0 ßF>¦Üæ!ìÍG 7$F%z™”´ÿò¥šþ0.ýÉqä‚®‰¹äÍ?ÍØ 2vz3QÍý…ÄAÀסˆœ8NÊjÛC|èPíür uûøßDÄÏA¸Ô¾©´NLñÞãÔ,lPŠ{Ö h–!X7lðš·¦Í}–£ÖÁÖ8â·ÑÊàl´wâgˆ¬©ÉÅí3p ÀEXRô$Pp`eÛ «š«2%£ïÕYc,høÊéà7(—.¹Ï?¯«’H*æeFVÓ»1…V{ºí‰CÕ‹ù>c#Y£‚$•,eÉ ªÕÅ Ÿ¤m:[™óHB)bY.W%e0jfð©³l`‹n>ä•„‡È1}Üóæ¡™›DLbš"‚<±ö¶)¶± zótíxªåäG%5žèAFŠËeè›—Ž­öwLj ÿÃWØIgçÐW²F»$'¡K3„(ds8ˆmWÚäqglwëâÐá«q×É8ÛÀ’87M[Éï— 7!Î iP*ëø¥PÞ)ŸáeÚ¬‰ ®²–s8»¥aè.Ò„ÒUÚ«ÒSPðc­qçXëY FÑ®Ç0®`½£9[ŸÏ“_™*ܵ$£¤BÇå 4*à™]€É>ÉŠ#G¼u.°ï÷¾‹hŠ6"‚nÈ<Ä-΀:« =d¸Wãwz4µcªò,ßÞwLx ºõv‚J·ªèA&ÑÐsmIƒ‰ŒSP§¢Ø—ÿ'°d{4i!ê:‹ã¶…Š)úQ×rwˆyz$ˆn+L—•ÿ ‚û½1zÏÌ£ÇFêôiéšH§†*F±êÄûÌw+wêBy/Ä/MË7¯G¨”ì~Ê‚+²Á dÜË«œ#s¸q[ý0k gÔj“zÃÖQêÖ=9¥8,¥<º'W{­·a¶Ããá‰/#þû 9ëmß4èîÿ›ò[غÆôRÓ®\°D °<°#³Pn2²PÒ›ü'¥Pd–üÆæÆQhŠ&–OzMR¡‚ñApщWµ·–ZÝ ˆ¯¹¿†Á@9Ìß²?˜Ù¼;ðŸc5?Z^1ލ̶Œúmz¢Tç}I•Q¿š;Õû¸Héö±ÌdglÑ%jvCYp] Ùü|ž&õ­Dc€YzïÎ « '‰ÌJ¸0v©XR—ËÔ¶È6šP–/Ãï±€M&“ÕhuFößTÓWAäh Ì2x¨x'Ät邏Ðä.Cß¶ îj¡©Œ#ÍØ[}iƒ7k•Óº¤Š] µb)Í‚ì{I›çu‡íÓ…ƒ?©óèaLîSz~½˜î—ú#×hôޤbéÈ­ä[eÁ¥Š–[{°×þzDHo ÞúòùP'´Íæ!˜Tõ;¢–!—ÊH)%¹ó/RHóAèT ñ<ï|±îp•ô‡¥²Ãåj:¤%„Ú¢ÄLZ~<ñvÜÁãLp” ¡fyj¿,ÿ¤’²R•gí)Àß.ß,?RÓIGà–Mމö< +ä¾ÎŘͱ¿w¬‚ ¢ô“ ¡ƒ±ÑTš´KkªQºsbù<ê‹ùp懸Z2É¢p{ ›”à¾ùÔ}!Rz;€‡…Ê3àÿŒ®òGe¤‡Ê @Èò]³Ðô, Ê"¶@Ø~yÒL+8C‹nO*¸Ž–FçÁéÙqÆïc´.t ´…` ƒ"ôø7ˆE±¨ÇÌuzsqñê›–1"¡[f±+rÈÔTðT"ñéÐØ3ÒCþ‹Ñ²f*µZp¾R¾i1¬±zöô’âFcàB+!Ý*^«†tèÑo³DEÝ[ˆkYßèy^»8|â ð›MN ´Ê†w©Y‘}ùÚôœ< ÖJ¶ÍÆï…Çt|ýaïØN,Û_+†CŸÒeÉ É#x¹¶2¦ß¨xG?4ó ×*¡Ös_#í+ö: ÞÌ%Â.,“°Ìz;RíÙ¦j2ØPŸ:ëÔi_ Ðç!VÝä\­4ò™»ôìÿw%ì\±¾tΕ"Àh–¹æAg:‡´xRÓ€æá¸&ú¡¡•=³FŠ€X…‡ÅÁ6t:ªÐD<§ól"ÔÀ±°y¯O 1î&“#0ñ:Àâ>©}¬$ÈN=¼lu°u¥™á$œ±‹nåiѰÎÍŒÓ]¡w)®ÿý”‘Š ïRL¾Izè¢Òr%Ý?÷CU=ÓÁÕ=PS+–ú}ëpO²á?8L}hŒv85”Zó£Ób7õõ[¾»%–dûà×îxÎ%hÙZJ.›l5©ÉdÂȵÖe q¤?‹s7ÞÓӬɉ3e'~–8Øææ¹ÛS8/MO(v`˜T˜5Ó)–w¯«5Aùk#\£@ñƒÎB3ö—q;aø %Py¢!z—C?ÚîÉrŸ)™Òÿü22Ðr{‰ º´„ø¬‹ž¬gHw_èœàÑç& ³@Í·óûF›)YL™ª«)§/lb‰­†û’'ÃdzÍ­3v.c e³ºYâK°a¨ZñòòW1¹µ¸É}âÇ}ÎXRƒY´=lís4%ã‘XÑÕP\K¥Â¸Ç ­­ëFwÏ€ÆèÏ‹aÄ>Š=8VûÙv뽨 ÀèÄ P>™ÊYQv‰xOCñ¬2Ì©aõq4„-K\{} Nñ‘W¦¤+/éw¥N‰ÑñÏÝÕ@µ``» ñªq€Ïé\zœrçoSã}ÅôS7$×&Ž$º¹£kxãïÕägáû®îWª2?Þ5.~N]ÚÓ$á3ðJ©q›µêtZzf‚Œ'"{€ÿèðvнÀK•}ŠôϵùzÜœsX¼ˆa…MÞ4…Íkˆ+qøÓXB†´‡¸ÍÉ1_Èg†E 6fÞoçÏGÖ7´Ä³˜£Kœ±ê¯|;ƒª¾ä÷ z½2ï24ö½ JQ7-Kõê˜ k/gˆ3ÔèsƒnbÊ«î§"ž ­|¯·d‚ ¢ÓeW†h )ý©˜‹¼ÊŽÌ3¥‰aF :°…tñѲ”‚GÍV$üÃ%DR0ÃÃí1--)ßï"üèØ›úØI¼y€:¬ÀãLºL ¬~ %:«·3Ïh!æ´6¶ °­uc¹ð6›fºl bG.®J/]ΧƒöJ„FMo¤ 잊=–¹ésÏ$uuí5|Y§ú`-ç€ÌHÈ2ƒçïl¦B"½±9àòà ìmO ŒéƒÓW˜Í¡ãD¥­¬&h 2aZòI!ÙÃuÅú졬»¤Ð1 NÉí’Å×”.„Ö™HZ~çam)îÌØkHÿL*¬G/s÷óà ˜-k˜{rBÜUáʯÆ8Ía0u(aÖøÒp˜ÌŸêãMû³xgÒ¡]d°âùúÌ˶0Šj³Š¢Ñ@{ÀËÞ ¯Ò| Æëï±1ŒÜ ”°µQG_…ðm_™ó¯ˆ¸îÛfcº'‡D cH'ˆWY²H¼©­`}ˆ¤èïE»=’¦ ª#?ÝofU]gA0\9!? ‘{“åœBìóˆ^ç•NUù˜™Eí "£Í9mªí7”«£¹ôJÝÐañm"å·mNÂx`+ÉhrÔc;ï¦ÆXÄ÷¡(Æ(zÉ6˜ü9ê‰ûnz|“`ºn$l»¾Ëò‡”‡Ïíz=id{Ѫ/¨¤ËeÕï|:Â9«ÜAYrð»t ^S:Q>)õNLuIÙ6‡Ayuµø{^Úà T8M‘Ú^6¸8€k›%ª¡y,Ye5ž‘¤ù.„ °´ Í…~·CÌ4gôkôà$n´yB”{6%òV«X¤rã}~Ý=¦¿™!fR¬½ì}n×ê¾c©wœ¿û¯}ðTÕɲ5šVGËnÂârkp<çYz 4ƒq#hÄÂÇËÃ:ª!jư[þ,>9_oú¯5¸¿éÈO/µçÎm§ýg%Ô¹Sãœ~Óp7Ž]¢jÇЫÒüó À;r…øQ>t_w^ÝßIQ k°Š~¯Ö…ào‡A®o»Ág3á$,‚iH7ï 3KUAŒAßqªâmM¢d·ÏÖ¦n¨ÈÎpèÙh NDueÛ©þ{?á’­¼ͧO_%äŽ6q§2iÅÛZdcè9/7逆%T l€óÐzÓ:¿èH„>,Ï9>G¸Xæ³úÑ玜hqò—þŒñ³Xâ{·Î¬Ò‹:böåzì¡ÀÐt‚7L4h6ĉÒ_Fv¬"¨ /p–òÍ´e`[ ´Ä#Ê¥5:šhôâéðSó‘æŸ¹Á† £ÈkIž·øafÆé[=®,§kç¶nõ-I¡‹ÙDf»Y/œ•›i”CºÕ*è~ÇÔøYs‹rš‡ÿøŠœÕªd{ L˲ ÑczHµA„qfci$¶ü·´DçäRÊv·ëCCRëàv¸úm6œíLŽí}PÀ²ç!ä£ÝsE‹ÚŸ1ñˆp Êã ÉxÂ)ÝABî­Ú®Ñ¥ZHH}ïØÎ nZ¬•ãŽGmn„€>Ö¸ÑÕi:­ ¼)€iì¹ÛÊhúŸ­…‘G?‹ÙûQ63ÁS­ö|Ʊ_¼§ÁŠfvúÎ*[þ­Ù#¡Gsɽ9ôndù¢!6¡'~%–̺ZŸU Ĺôµ“'ž”&oœb#ÈH'ÛÛÕ Ú=š×¸:›²LøzÆÿÁj¡…° :³²ŒÔ6º$Öo‡;áäWã'ÿÝ4K)'' »¹¤“ñ“D85Lƶ’‰¨ Yº€úEà~ÃHgþ¡ÿèîì‚™®“P_i|cF;ÔüÅCÈzÜÄTâTdïo:@üºSx97…îP(K®XŒº¿¬×Œ; å® /Õýl.ŽZë¾æt2·lÐʘëCWÌ‹ÔÝ\%Šûý}˜ßmžË½Á4Nôˆ±—ŽiåE™;¯yÄ®çVqEž¯8äã.­+ÍS¼“MŠWDS 3 WUýò¦ŸuûuÍ4VlL^-ôGÞ‹ÔÃÇïô*+ħ- í-\nN-‘ÄÊÑšY`ñÄâÌŲ²b(ø­ÊQ¤ºÉUòS*¾º}¿+- âVå`Çœxîñ-^þXzÏÛ9_{6o4 ‚46‚µ· ‰E‰¥_W¢B@—£`ÊÓån¡vn¿ÁïfMŒ|YÄ#â×rýÈ( _†ŸŠ¤b³NÊÐôˆ»4åw¢2ÛŠº¼B¬H‡iD€D€ßç’Á½’yó2óRÆ#^Z׆оõ 4lã\aF¥R‘î ûÜa朾‡']Äa](‰dKªkÕ`‹(F+gÕIÅV˜J †"Ql+Ñrг(–H7p» ÐpWCZåA4…¥cnNt³’l ìsª›×¢tÁ‹>72Þ5°´Ð•õ›HÂI ^úuó ^ ÿW0ìÔA“t­ê„#™'ì[Á¿9¦äŸÝ;~³Øo¥h±Ð>¬? ÉèlÏ.jÃ6]™çŒì÷'±Þ<‰AùYï@Úâ`ýω<ËŒ)Ù6PŘªê :/8ÕîÓß²™=‚–_“Ÿ«ªE‘åãG®.ÊÁ÷×%¼þ,%sÅ.û‡>AÒh±"Ò2û¥©ˆ‚ÚaT !m¬ïý†ôR/s•ž¾ãÉ©Œ…çÛx¶ Ùcþ/íª§4¡ µp‹¼ÖT.ì0XtüßðÑê‘V)$”›y°%WUó`žÔʘa`Ç endstream endobj 9820 0 obj << /Length1 2145 /Length2 12651 /Length3 0 /Length 13950 /Filter /FlateDecode >> stream xÚ͹eP\á²6ŠCÐàwwîîî283¸[pw<—àÜ=ÁÝ‚»»ÃG²÷9ûì}¿S÷þ¼5µj­î~»ûi]µj(I•ÕEÌÁ¦@I0È…‘•‰… Ô–òtJÀÎŒ¢`;s;k3 "%¥˜ÐÄÅ 7qòØY\¬Jf.o&œl,,¼ˆ”) èô&5˜z€.&êž@VÉ_BììÂhjâü&‚,­A@Ú71°ƒ§“µ¥•ËÜŒ ,ÀNÀþ =\€ ç7·ÎŒŠ2dMÌlÁîζÖ9@–I  vcZhÀ €)ÐÊÄζøkBCMBU ¥ª¤¡¬FËдº€LìÎ@€™•‰“‰™ ÐÉà|ócbnþÜÒ& €ºðí2Y1½ATsup;ý3*15u )€¸ˆ¢º¨ÉÒPSg(ª¿1ÿJþ€z{Ȁ̭Mþ¨+H¨‹¨ë(K°2ÿÉ€àöæÓúÒÿ‡ê-À¿¢ySµpÛÿu ±rqqàcfvwwg²tuva;Y29ØÑþq neýØÉðvwÚÿ¦ØdþV—·@þøSf€¼µÙ[.ƒÿ De$%ÔÔ߲Ÿ'áŒëÏäâáò7U q‰ÿ‹ôWgÙ_ÞÛ4'ûGÊ1W'§?¡)ü—Èé¿£û¯bˆ‚ßÂÑ·óö5qÿ϶5¹:{ýjÿ{!ÍÞÚÝÚÙÅùÿÌ´Ýë­²Ö ÿ×Êý9ÿÇ¢ˆ¸<€›“Àöv±¼Í°È\ loÿ†ÛñOKˆ[¿ÈìäÉü¿M¿-ìòþ_ÅÖ ó?阻:0k€¬]2âÿTzc!þ‹g t°€ŽomfÅüÇùßyøÃfýÃ~K‹¯·Ø`abç ôµ¶¾Ý½MÜÞ:ÕÉèëý?ÿN!²rÌ­Í\Þ¦ÿm± þµ.²xÿÁ~Cò_¢v"Íß­Fû¶ÒÌÁ ;Ï·îµ@dV»¼õ ÍÿßwÒ –tµ³S|3@ó¿Ôè?›Ø[Ûyþ?þã”ðOhþXù‰µ³¤µÐ\ÙÚÅÌêµúÿÎD@–v@#+Û?˜¶ÝÛp¼-ë?/?"–ÿ½õ½™-èì àâý+¾%ñ?@¿ôd³†Š¦¨”ýÿÖOK€ÌÀæÖ Ë·¶ç˜89™x"²¼5''À›õm~Ì»ÀÌ»¼©\]|ÿÔñO§ð°˜Uÿ°þR¼Üf“ÿ¦XYXÌÀÿAò˜íþ›äà0ƒAÿsp˜€NÖ`ói°r˜ÿ›|›Kfwð_úßCVþ³WþŽË¿rðÏWÈ_ZÍÅ l Ô²6{ÿ# &.NÖz,oýÍúÆûýדÁ¿9 ü×hþmQQ°‡7#'+€‘…ÀÊñÖû¬¬lì¾ÿ¦köÝ÷w¶ÞŠõ_ôŸµ=€fˆ ³`3þ`›/ ¡%~y㥰”¼LGßqµe`ÒÇ[ ñÄs6È€BùŸ2¨òÁòÒ|~)Ÿ@…Ú”ÁØv/¿›’ËÇ®ÌU„7MüüQ%D~~ÕdÒÌP˜(m'£Ý—ýš«SÄ1™ÑœÐü ñó@Œ·µã>†môýâ3™~ióò7X÷‚iÖXNvóï ÚçÇÛ ]^ï±â¢MºE覌sCq~ÊÂ9tu`n;ÞŠ•š ¯õLn @,¶uã»7¥aÄɽâuN«â”›=ì² ˆ݆žYÁ¥f…¦~ #Î'äÜ\ÁB•ÚGsò·IÖî,µ°ÜÉ ˆt|,Øp ‰@Jt£1ö­9RPqÁNÌýæowfµŽâª”5šÀ½ÆœUWù ¶f®Žo«—»Rh«Cs­ú^¯(Œïì‹<æá¤=ÛõÎN*¨R*ìÙäz°Yu§Ž3ZÔ›%/»í%]B‡ßõw¡dØìþܬÞ2«Û¥>Ì8ŠåU b§]>O›_9$dû Ð,Åa°ÊØ(aÞ‘ÈxäXÓ1acbiÖn.y÷}ÚTVÝâ z.]ïø(­rB¡ VŠí–´Š ¯Òmh²–O9åRBc)ÿM&eÂIÑ<­™KŒ4ôr¿]Kÿ¤‰€W"©jˆÌŽ•¢¹Gω÷‰˜Ew׃pŠÄ¤QÂ"§"ã÷¼ t›5<{÷øØ²çè8mÝÞÕ8ì"ÈMôk‚ˆ›E7¦?ÃÓ'­‚’*4L¤Ê¨´‘NB†‹Îx˜ÃSèr«¯æÄŠ+{q5ñÊä1l´¶Žî"YÙߣ~¯«”Ÿ­|osÕˆ_[XÙ‘›Zœ0’Ð#°‰¥pþ­D#>YzáfOq}ꃬ4×áUÆNƒÙZGáˆrÉEÏ_}'Æ„ªÊØßFñ=:^ÍÙ($b£ ¯ðÃÀNºl™‚¾9÷fÞÍ>íLlwhD•Õ &-»/fQIuHy­ —äzc,¡½6×Y©rßÙÉ!{H5ºuê¢?s"a„ÉU~{%¹Å¤®4Á·gò–æ5š¯uäóûÖôU˜ûùú ÓT¶T+ã{%…誰f-SV¨ DüoW=iªÕÔÚÉÒgÃ6cô]¡ñÜùÎI×Fk¥»ªÜÂÃdâq‹O=Yü_E"ït6í%>•eÛÿSŒ2XRPæ‰÷På° ×Þù®vù©–%ë›D.ƒ¥ÙÚ|k$Ò…i„©å&m0ŠÕYù•P…¨„™#Šúâ ö}éÒ"ÀTúûÑ}N“®ˆ¥þ‰“Wóšf°/;gbý‘xŸ.c¬~4FúÎÊ`/M {©”/|Ëšk("çû­ÀÆóÛ–¬žh38æ±AùX%A\³(ˆpYIN„3)Ô×¹¹æc›×Í‘m4·¤™üÙÛâ÷?Ê<>(öÕð—æ…A°ùi4æíßY{‹ü>VNý®Ã¢®gVšM2 ¦‚²¨p#øè VZÞjæ ‰š?6 R>Œ›IxǪ¡iøÚZµ½RZ'±€ä¢my‰9Ìè‹Uz¼4Ñôàâ´k»Æëªï‘+ ×ÏCv1„‚­$/%5— «§ü¨€ÀC?»pÑèXY³ž²1½€’\¨);'ÿÓÞ¹¶”© '(²| ð¡3µK|ÑÆ?È;³±íÓ':³yË98îú†-垌bé,âj@ ”õGx Jr›ƒ x ÖÖ€Ì=[Ó<•oá“qºqM›}•="ÇZ›d.(ºx-J%#y( çwÁÒ-CiC/Ë—†Iº&ÂÖ‚°öSÊy£¿Åiï½H0¨<J±¸ÆÄZ·ª>¸öÅHë³uX8¦øHQì"°U' ö>ð% /z{5y?…tºX ¼1•_tæ~‚¾W¤S`‡XŸó¶: _.hEHønŸWˆ$ßRíì.K’à}(!7ODâ‰"PPSŸáJèÓõ!'–<ýW‹ú)ÂÕYp‡ Â>0û+0Å8!]\Žì¾v ééÑD”¬TpÜV]ðú¦E‰â‘Ùé5ÕYl»’nVL“JèÆ¹E¥œdy!ŸÕí%õdeD¹ôöÓ™]TTâ¤I `®hÌsc’ŒÅâ¤ÈF?{ØuÓ¬Ø.f(…/“)°}v—¿É©J-Ò¬¬2P·¿‰ISæâñûrI›÷XС'4ç%õÉTÉ…"+'Š÷§Xä©ÕÊÅÅ+fy ¼¯HO“@rÿÝĺê r »42Øk­Ö–…È*Ä[˜·XÎÂ-yý­Ž¦®ØWôú,ðÃǯï«ÂЕJü.¿Ämdר^ÁضT>Þ͵הµ+¿{*ÁAvE­œióõÀäxc:'Õ@üû}îU†}è¢ÞÙ®N´0 LJù Èi‚¡$ºòÅJ÷DßiGVˆ·¦ŽŠ(Gb{B¸iþÃ>âwÚ DV—)z›Àžá_iÛG‰Má83Ç=-z‹\øû0ZP¡•Š¿(äÃ̺úÔÁÓ¿KésßmHzoÿ´ã:”%–´TÑ£Náqíµîv§hÔO+ØÒ—ˆ / Q`ƾ-ÿô ¾µA¹Iy¦·^X³#ÕO¯±‰ìÉ­"…R3àañaqœy4}˜:Ððù®pª@tó‚ [O›6m{㘗ØÞŒ,ºé }Baƒ-óço2zyÖ×£˜+þ¤uÐ\Ú{¦‘Åí9œ>¯KËVÚÓÒ\iê‰ýªT2Ô’Ò “x'º_ 7›ë9¸ˆ—ȵõ›DÔ`’ŠEÃ[™Êû‘È 2†Ã=ɪqQ=HH‹Ô·0û ´0‡¦ŽU¥\Ìv7ïnOCdŒ‡WÝÞ½sê«Ö·ȡ«e?þ„ ÷ËˆŠ¼cñÚÒÊÝà2ÕñjwRê  ƒðHm2ë©•%­ì§²þ–¿ßY™ÏîμªìÒA\½‹ÝhäZP¥@d®êÓS„§=wÀðïì‚èž§§õû½ˆcöeîXí6ö+7€ì«Èã±7™† }ùF–e”Àâcgô€ÅŽØ†­ø§[o¼–®“:6ˆ%(,¥©ÐO¡(t5ÏœôƒÐ-ŽF¿á®r7ŒÖN‚\%ïû¬uà ú`ÐÍ£/B.k(º³±'Ä¿øµ~„³e(ÓWíò›.w«Ç/9Y¬lî±ëXÏ¥uŸO¹6q&ŒQüMi¾N†®xw)èz…Ã\gĶC¯cù%’ÌúHk.ypMÌb튼«óF‹S¸·ÎæÞ‡Ž>í%üæ«Øë†UmèHººëÚ 'Ãñ¨†ÄYž q =îRfD¦ð¨vó„¨7„ÏXB@ýއ)¿ÍöÃî†ç" Eé…χâqªÌRS"ŒƒêbSJËýx—ç¦iÃÙŒ'áˆ@¼žíBp• 2Užäø‚6ªy±õ-ÂIÀV3Ò’›«Qy¸d1Ý=‰x¢es¿ûÇÈñâ÷bµ¨8)N÷OkÄ?æ³ ÊH°–»vuyx[ë…†1ü×÷$$Á÷òrXl¥Ò l«Õ.±PÜSÎOð%‹Ðÿ (u†ÿ6äq…%—î×éW&Ú]a RŒ5aê3¯äŽPg/²vÌѽº¤­íÀ÷'Z‹Tål*Ÿ2RÇ-…Þ[Ïñ`Pë'4Y3Ç‚J#¸úOù<‡Î,«»f†ö±u˜ýË®Ùkäo-»¸/¤UoMšfN‰G˜juäBº.`”³T!ÕdԮњ1¨‚:ŒÄ–k3zkF›ýUÖÂ[W7iíʈ@Y éJ;5|7„ôtýÁ_I®÷ë9VûýŠÝ®^гpT|Ðc×2Q^øù‘ÐMÚeöíkSºÛýÓŒÖ/'*ðƒçb/x³CéÛÖZ‰Þ´gvyô•ìi*FD8ü×áÄsÛã{ìs­nëc•š}iz-; Æ7©—{¹ãàÓÈð÷žÄ¡˜Å² 1T± ŠJ1åw¿užå”l²• &voœ–<_ï2-l+q>¿lµuÕRµ¼-®¸‚¼H:ïcŸ}‚Ú $+€%ÎüW$C+ÊTä2ÍéwÔÑæïí*~U:€±ßÇN;þ®è“ýMñŠ€3\4£f0Õ®šˆu¡;Ó+ï–rÛAo…Í^~Ò}æÆÔêY*¥ 5¡hõ´»Þ«:I’ ×&vi…€,ærw̱¼C¸äf,·Â¾{—èÚñ{Ö v¦Ü]ÍQäxÌÅù}(œ*ñOˆqÄÖ4ÇkÆ÷q©‹á!uÙ‡pÞÏörDsîƒ1÷ØÆm ‘YMðŽx9¢‡ª‡Ô W¨ÅâL„€SZYÝ2i>½ì°j_Þ*FœƶB3åh*Õžó Uß]ÎÖ(±¥gáS>Q-bŒ¸ñƒ×&C×¶è(ì†YmôfÑèy'ÊWšç¥ÆÔÕœêBuü|=4˜®sSùˆÉ†ïO@Mö3¥ ïl™@ ú×,f¡ôÕ1!S½0ÎØ€f\ï½a ÒK¾Ðf,)É|jO=V¯vt¬B jTcY?IѤG¦cÒ] už–ª‘Ìu¨Ÿ¡UÑ(‚J¶Ñqªù"“(Þ±{&øöpO³sƒV䤄p=Fɹ&xÍ!ü0ŸÒ³ *ŠÇ[³§÷d°¿IµžžyÔÉ“¾~DW!•g*6OïTÞ…xQÓ¬5ËV‰F<öhË50`ÒÆi‡Û_` ;•<ùíw™¬¸X烣Z¯š8LÊxsïÙ[Ã&܇ãI´ÖôŠëæiW%ƒºxhpW`…‘y6]x”B¶Ï2hi³0j£ª.X;¯Sšð}M"±‰ÿ!¬ÑÒÕ }ØÛæké¤têˆßÝ[V©‚øX %œ'>„þŠ£c,fõ['Y¾äÃ7f_—í£ÏÃðúð >7CŸ ®'y›\iœŒ×ÖP1­oËväRð0†É0…÷“$Óy¡¿ˆ‘%Mq|~ûdׂOwÉÅ{‡4èyÏ­ðªÈæ›{‡³±Õm·Åõ3Œe…XÁðáúÁFŠˆbÌ€=—xÍ.3ÇïT–‰ôÛyµ±+VdÙœ có;ILˆ¤·Šäæi¿ÎžVNäQ™–©J?U‘k ®Ö„OýçHéQUŒ‘æe ©Âú¾<{Š™Ç½˜"’àô Þü!ëïIæ1 ÷°#“cßÌp1D³Œ‰soQŽá¹rñ.”= bîœ}rëþÆX¦ðFÿ•@)*Gï™6d[NÉy ÎŽ>ÓàFh±%e­D%Å{RìT3ß½vµu°ÒÜàg QÕqqbh8¸O’»õ˜ E3 Œ;YL÷ƒôÅ‚Œ?ÔŒFÔŠ~Dñ˜Ú¢0û¦ÉM£¬òJÁ–Tˆ#Ôjåv±döè½³¿®ê&’Á(XLˆÌ/€^Äx Ñ|i•&çW÷BôC,S‰ŠWß+A6{¹ª§&/þ¿I‘Î|›oÓê5×¾¯e„¥Lƒ{‘lo,†ÎÓʇ˜$á§<'gøç1Q8²CŽºÍFÛ9_Ñéss»I’3±"ÂʼxedùMt9PRïmD¨tWضh¾þÂ*:äT1šA{B=û/ÿõý)¾},¤#½Wß à‰ý»†°¢æ¢+h¥{ ¡¢©Y€†¨Šî· CÔ¯Å|R‡3ƶѶ³¥+zZÒ°½\¯…“·lç¹bEŸ=¨ž…SÞ©ázÈÖ\Ôµ††œ—Ãìo6A¥çyµù¬,l–!>ª‘Æ˜Ìøn?zØ¿a_×Pgs0zbñÁnl>–ó·búÏéù”ݲHÁˆÛóa`û®k[bcï=@S„0=í)ÊÀˆ[örrfopG!‘q£·» á!$7˜°^©ÃØ2ÍÍÏ!ó÷Wš5ñ_«^ñàÐ%šXrž– 1ØÎ!'‘åì)CðˆÕÏ/m‚ù¿` àtùLÞñy;¬Ôܹ!õ e‰xò´1#0ã¸~sÅøZLp}Ç)ž¤¬†=?±sæv r#Á ž=§3æË]>J2õf=´dd]üøgPC÷ã=µ—rÎWgȱrgéñ/Yv<iÝ·¨ëF©ùÈù{F.8_2'Í¥Ój­KXψ§I~åpeá›*Žø[> ·XäK!.ùædk”R—cïӚ©‹Ý ((Pû~sí@²–7Áh’ ¬BúñÅ#Xª]%’ûJ]êðxÅ;¢ô’#˜pVññrã&Ù/‘˜XM§$Â…ç&ºÈð™¡Â_ž.æóÛë­66¶D¡unVë‹ÇìsuÌlEî–í¹ ßêX,C??äœ2Žßz¯qyÝå,ßßqMˆãŠi~`øÎÄFåƒ0‘˜7{˧'y]×Lu´“­Í•1[éi¬ &¯வV02¥-~ìM—%ùÓ:ý Ÿ \÷B=#‚¶’ ÇË ä,î7õ¤SŒÓ"+9w»9ÒžýÏ*khÄμäÓùŸ=]®ø[àÀ´ Š–qLB6iFa2]¢L‡Æ«›ø„´ÖôYüJVqÍmv{¦¥ {éÊÉÊA¦^è§oÈAVÒ|æØIyÙ’Š’üÞœeüQ–¼Ò\k”aC,ª´é§²!ˆqôÙÝ»Nnaï%ŸỎ¾JüzUÁÊ•Á†i‹Ò%íÏ\V¿ì«Œ˜•R_8Ci¬;7UíB^Ô<ÝAg§ãļÅJ%/S¦ß_6~¦þ¤×_ÊYš+!}Ì/ÚÖGîEƒ´§BKTª] =+ŽjrËÀ–f5ç0gØ­û9!޼·.ìVÀc¡/"ž¾ÎÐB°vPŠ˜å[5l£lÒÚž©}´ë s­Ku) Ùˆë È)%Wýåõ4Kú°œtæž”·íœøHY°]½uëL…àƒL¬Òo¶TDOgåÙmT´Š³ßæÕæòqù®žVՉׯOï1¸X1©ìÓLè»l(k³ $„ýöñç;Á刵ÏGS³7×G$:'d~J6œt{õ.avëcë:äPö|B0®žÏ4-¯Ñ}LMáK¦êcspÁïæ:!1’¤8½ÎX¾!¶°")Xb"îÂò1yŸ‹‹~+ÇÖÔÑ!!]†‘Ì•áÖ§ÿµé–¼«þ¸ümCPªõbÈ&S{›WyIg‹ÞXx#2Ê~¥^s’‘¿Þ“-Vva¦GJ5ë§q\LÊjóÄ7ejÏžÕ¤_E!+ÙÍ|ñÕ}b7äÑã PcF§û£×/Êk‰Äè½lÃokÀº®DÍwt2Ìš¶ ¢ºtÀN_¥Ö–¸&¹5ƒWú8áû(† Gù‘übF*×þ\΢éÁ*lö[v]Û¾Ó5Å!pí·Ù}šš xÔœµV¢27w®«5¥[$°uµèX¯4^Ó:Ò5dFAmÒª`Í€›BïoŒ.V"g»˜Ð¼WÎh§íëžš€Gï F&i]¾º»…dž{v›ÈÜ(QÀ*!Ô¡TTœx}ÇŸ4ÅcŒ—ÌúáëÊ7Œ¸ÖÌ Q¹Zé’ŨÂ}–Ç™T¯éÿÌ;,Ü®ØéÒèçÛœâ÷K”ƒñN†'…:©SÈ$%&ÅWwŠp.yD÷1gfS×-¯ÙÛ˜'Ì)7'z™î•CÅâ‡B€ìh«‘žtoªTéÑ™¹_Œrƒu¡˜Å‹zjÝË5yü“Ùzín mÉ0£1 ™¿ç•“¸ë@”[¯QSÝ;pÂRêÅàsˆfo˜Ñ–fQ:)·Ä“÷€G­›(Q‚!UÊ&¢÷|LÑgÚ&‡4¹,Ÿù·/ÚšV¥…i¯Ô U3èPÌGÒÔçSzÃʱžÓ¶-Î9ø#\9Üêgˆöé?ص…é I㼺µñàäLÖß?ÿˆ)¸ $â.&ìó„˜vÃÓÍÂë Ñ—éh†ø†øë•#­¥³´?мæ]D :MS±ÏF|"Ð1µª!òºAŠDlžñ䛓¤fC8¦t¾ep{ÆêDiÔ:èˆ"[Ú;i6õ*BÃ5ä nùƉÏ*´V5õ¥£•äï¡ð«ÇøHÞ-XnѪë[²ŠØ¢fÐä@;Œ eŸØÚ røõ\qÑö´™È&I±jY~h³ÛÌ2–H/š iEo€8ñÍÛvÎhB½3Ïk¿yðýÚÜDDM!†ÄOÏL n“¨üüÍ©T_PƒÕI§Õ’±Wó„Ùîh8ªð‘Ùû«‚ò—‡ËYV·æsí¨QiÝ ‚øW24;Z–"•¤½ NÙžIÓÓóôdüX°Å‘†Iš§ †•ªÆšy–fA?aõª™i…PÔ¨Ó:;ÄæÙïÄ–|…ìÓ/:Ñ HÌ‚T.?W’2Ê~•úJ{ÜýànMý,‡Äì’²ÙÿMmP„G‘80’™ é Íã¸ìz»Æô‹—>üiÐ6$vB˜º»ëçJvÄà‚×õ«]¾ª¬!7tú¬dÄŒd%¾¥Qøkyµ¾!jc;s%`î×s´j‘B”EéR EŒ ZVá(Î%ч>9æØN<0®£#5Xh–໸êɇ¬n Éóp^*„×™5ÿaêW´¯’ŽIèmE%x™BÏ=Yy³ê©¬f|ŽÅìÆ,JÓ¸z­Ê—ðŽï ˆæ×w›cÕ)Ç‹ÓnHÊ Z‘wr`ó‹8ýNÔeÈ-w´86Ûû’Ä~b«àå¯(Ý Sb;¶F‚s7¨›Ø¾¥üB=-Þü"ÞÍjð«Óµ3¿„r9-¸«eÝM Ú•UÀŒœÃP,ï³õe?þQÐKdyŽk##XNgÛj@ÒÐ~$‰ïÉG‰;^lðäHçHRxÁÑ×µS"¢ºãÚ%e3a<¡÷ ‘ ¡ôžRd ^èç']ú 1?& üŒÌ2•>òщÐ!Ò°®Vû)/ZÒ])’'I½á³fµÇ˜Ù¾F'X02¦guT_ž½ 5–5šÈZqõúO¸µ]•fŸ…ñ³bC­}PGã+ÁþÙfs"FÏÑ<àÅ{‘»˜ÜKQ¯JùÆüpÀ¥JPn)þŽTé©ÆÎ ªë ]!a‡‘©Ž¡&¯ë!Ä! ŒëÀ Í:Ú‹ÝIù-¤\a+-¹óùfÓ¾Hn™ï@€ ë°ýn?mM&R‡¶IŒ–ëAV“-+ûæ¶AÐFx^VuXölžúë™´5ª÷Uûg-ö@ýUYGKñ©‰,5c…d†xòm‹kCÍþÍžU ·ãA8jc`±žv3€½~ÕN…`ÜWð¸µïò2§¹½áR_‰ö‚Âä4ž°îBH äÚÒìDLlž\a²öìK‚¼›bÔuô§L%®:/å>ô{‡NþÃs%ñÌÊ®2Mhy ]P?=MþÖÄã ¹ˆ[ [=l˜ôf•ÒXP‘Tƒ½9ÎEÄ °9½´†àÂ3ƳÙ*òQ½ }—âÀÎ(l„»ö8Íøò0ËØ1bFÏÕ³8¥v|y/Ÿø.@¢Ï©¸¢ï9N5úUÏ£ ‘>ÙæVù¶[ )í5ªï#Δtx>I4+Båô1ÅB6Áôîpq=z!ËV¤J¯¼ºæ˜êQª D_ .þi®ˆãÔ6Bƒ¯Uó9RŠN)«!‘™&^Ë˾ðh†÷ŒjÓNI¸ÏTÏÐü“ŠS@Y¥’]ÁÑ5Ük·»>å’ñwÍšÐÿF+ Æ3¬}Mo@ÅëeŠÎþýgSQwYÔ/‘“ñê©Ä>iáÚ±ü¿‹9òªn${#»ðqüc ÇŸXTßSE&߆mîRmðÓ 5/¸ÑÔûl{£T‚ÖmlO9á)àEÂ¥n9cOŠ„g„q·Œ­(çY ,ì\—¦òPÅÒ †iÁ4ã;w"ö&J4ÔFøÀÖ Fsƒõ¼~ºã­9ž4wFaÁÝŒ«)4]@¢Géà3/ÆZ\NËÖƒø®UÈ×ô®¶¦U¦ô«1P£íëdšÝQ«}ó艰SV™;št”8L½Vü­N¨n ÃVc‘ƒéÆÍÝŽj?Q&®ž„K”—/–ɪ֩º_øs”¥^Öl¬w®!¼Bs¶%{¥Ù':ùªZ=ªe®É­Ïg.µe¿­6­ _Z[çŽÃ!ÌŸV¤hLòÍgfÙŽgi d|FŠ]4©»#dÙTÞÉ4d¥RÿžðX|ò*­?»o@™þK“½%)ÛX M ‡¦ÉHK‹ëÌ»_™’)þ³Ø]‚”>•jj.f3Ïò#ôp¾þ „®M6—g¦ot`7™^™Á×ÚOÎÖla¯¼R¸§ÓÁЛÖÙÊ-êÔ"Üe;‡n¨ª‘‘>Õ»±ÑmFÉÀ/”y×Oçë!Gût§B‹v!ˆr—û¡±§ý`ñ˜Ê")Uglòz}F¢‰AfÙ®tçF'°^‘ø<Êõ}Dz¶X8#î>~Y* Œn(«Ó)ä4^âŸ|:wšÊ:¬rçqò–g-ѪìS‡v;SŽ‹^DpMâà …YlæÍ%‚› –Y® Ññ…ÀökòæÜÅ2…f˜fJºnÑuá9xVw×OŽuJÔå–Ìå…Šð'‹ ïEÛQªX Êa·¢XTÓ”Ô˜£ôô|³)ï{»ÝÂk^¯u¡¯Å…/õ󑹦Ðrùö†îUMد›!ö-Nê¦îÛF¨¶Ó„ß©ãÖEÎ¥¥;{íH³³Gš¿+¨¢vh¹Ày,³”zA6bezêr•“qßF ì8¤§7*ëÆzŒòHçÔêIvÄצÌ{ü2zÛ´}£V.4gãÐW«K¿=Éì )[]“:‹fNYyö[Ïœ&íGh¥l¸ñ ÞI›Ó~Ó•Íù;÷_ÿÍåÜ{ vBÕï(ýb>ÉÄ>Ã5é\ÂSQnZ9*÷?tàƒ½¿Ï0õNäô=¡”"]²þ‘‹É»ú¹š8ß©¢§ (¼/#Ì3Ø‹eŸ-ŒÈp ci®K“ö°÷,yE4ù˜AؾÚ5"}Ôþº–73…žÒ“ÛœG¤þÜV&ýtøvƒñàÙ4>¥žõI¡òÏ÷^gûËsèÐJægÆU›Ðd9þkÖ_ÃíäD®$Dþ¢‘YœÜ0*C÷[„éô|'éÊ;oŽñó1›ò3¸ /Cr½ìC™ê§ƒQ£FôåèêŸÉW'é_â²¢¡ø£v° ÛîËè`…ÄèXe~4ãDç‡ý$Ú±×ù9„Z™Ñrm8Œ³3HŽe6˜:*ƒ57O¤©%ÉM£»ošÍŒj%ÊñˆBKÎHbÜ3 ·+{hÂþ©ð÷~Õ¾ª†šÕ™ød“[—)Ð…»ƒ©Zq[:‡Scá9^(®,wKTÙÝåÜ&š¿+å’;•»MëbREÃÆôÄ Ê­Ô"› k›”À¸eùž§Üs܉xû”~/³³EõÄ~I«J0âæ(¬ð~ƒÆ1¾¦ G‘YÃ5ij<›”@ªëS>¾iâÙF&¤‘U{ÁIþÏ™/ƒeîc™ƒ%H&?;/`'}f\ª"ù“˜kàÑXЬ¡Òcæ’Èí †kv½×P[‡Æbñ.Þ(sˆ¢¾6“vQòð8ëþVÜ•ÝA5’VD°"jº|0ú´R¦ÚÈ÷F?#¤ëýX–;Éj@Ç:ÕáËgq4<%·c_f+TOl¨.µ¡E2ßã„é3w3Ô„O/6÷¶F\ÅÇSØ÷ k‹eÀ•Ù`´Ä&Œïä]¥Ï š±s²[|n†ÐG[{Ä÷2 A±’ `L{`ÿ¥Ø:Dg¬ºkF—x¤0.’,Äþ‰Ê q:õ4Š/ƒækº!\2ËòÜñäOôeˆe‰ 0ýÔñÊŠ×Fnôy.š·s ïì±ÔíØˆÅ0eÐTJlöÚôoÒì^¼-ÃàaŒz×'6ü(ƯÜ':Z/ ކ?FH¡Úбq$‹¦]gÁ$œW¶^E}XÞÿèá̉±×l$»>#t‹ÒL|tŒ•‡£P\ÎÄP@%}ÉwFõù—úÕÏøR4% $“çgË÷í7'ÔÊKò ¬Ve©Ï&†ÇŠãWÐm±ÈüˆbvY„ë÷î.1$ˆ)„·rn2º%yÄMeÙ´°µ=%8$VO,‘#X³ëH½…8U=»*p°Ô@™NØõ>crPóÄÙiºÇùÝùwDýȃžÓËO5Œ,‡ë´µI<…ml£+Š‘*Ý´SïÞï÷ü¾7^ã>²BoS¦4C0AnË·áø·ž –à9´Ö‹9ÃÊéäcãAºT^ït°ä-ZßµÂ&£æäM« 0 <8»¯,é »â÷~Ñ|&|ôú,t©¥ýb°À™Å±g¶ßŒ4Ë;’—A;waó~Ç£qL9®Ñî‹Þ¯Ð5èBTG1bÈóaº¤¿8Óq]j5üª~YÓ¬D´ò¼VÄY–óu¬ò—° 2#Ê“ßìNåB–Ø«/P”I«*¬êkî<¹›Y6C¢_ 8ãÍ‚±?ÅÈ~{¬äâH¥vÄQyO(“Þ{TÏ‹$]‚¡¥à뮩_8óf­Þ“¡«U|bH@þ®CvSY-ý´ñôû‰·–íSrLÀÙÅ»`é–›vl†+AüøxãçèüU'o¡”)óAž:2I¼X ƒêj%ïk##€'raasè$†棧Q¯ÕTfãå–õý„ÈS.nʶ|'Æ*RC¨Xš1Îgjs$ÙfÉ’~¾îͰ‰ÚªO"+ú¿ÅYk¹ŒmýèìA±FµW7E¼ž]/\xÌ;¯Q0H‘Ä:-,UQAÍ"…e{þëgj½×ŠÙ&LQ~ ’emfÁY¬ÀŠ OXDCð¿X ŒP#1‹3ÏI±›˜`_Ói}+Ðâ]‘ÑÊS´})K½¸)SLÇÌÚÊ8Cè— âú¨ìãÁ>«ý„ß.Œã”s õÒ‰æïßs$°U*›×«‘–*Q’ŽžëºƒŽ¿E èBË7Cx&Ëê,ó×Ì=~²2ª¿' ƒöW)_õjˆpâµ,dQ±H2ÉíW7|2) ´ì»ëN\}iÈ ;·îHIÖaWÈâ–Í$´Ë~înkð:ëeÁµÃÈÛ™z—,ùÐ  +2 B½­¢aTœ òPÛõsu®ç ØItÕW–Ú£6èðéíp Å?´æ0錗‰,‚ÛŽí¢E㵌°DÅ'L»œšaõÎD¢:&®e7dyÀ Û`ÌìÕs·Ô¾$½ìðÚZ©Îµ>´'ä³î†–ˆàtó{¾4Lw·:+T'z 8Û*ïÕ_C¡1¶.+˜¶’BL&úÍl#@7$ÿé u÷ endstream endobj 9822 0 obj << /Length1 2161 /Length2 16057 /Length3 0 /Length 17251 /Filter /FlateDecode >> stream xÚ̹eP\Ûº.ŒHàk,¸»wwwhÜÝÝÝÝ!¸»[pwînÁK²ö>ëìý­ªïþ¼EÍê~u<¯Žb61¾Œ<¯•PÈÊÒžŠŽš– Tv±Šm­ì¨ä€F溶zjZZFXbb~[ ®½‰•¥€®=À@ko Ö··W¡¥eƒ%-¶ïR€ž @h¯«àb ¤êþ!d¬ìì©ôtíÞÅ@K#K Ù» ¿•µ‹­‰‘±ýo,T¿ ­l#ü†:Û-íÞµûí” ¦«ofådgfе4ˆQKR¤¬œÞ™&R+K€ÐX×Ü`eøÇ…¢¼ œ<@XNZQFžŒ d´·ÔµÚúƺ¶ºúö@[;€ðý]ƒ¿p‹èZŒï®¥1õ;Dykk+ÛEÅ/¯ (L à•R•(Šò ”)…wæÉoPï_¢–&º¿Í%xTeéh~g@p|?Óä7Òÿ çë{0€¿£y75´µ²øs€ÔØÞÞš†ÆÉɉÚÈÁΞÚÊÖˆÚÚœì÷ Æ&ï1XÙšÞ?mæÀ?)v°4x/Œý{ ü®1@ÂDÿ=—À?A„’¼R¢B‚ò TïÙ¢úpª?ŧ¶w¶ÿŠœ ¯€¤à?HÃ31Úý©ÖoOï%61·£~?ê/†Å{½ßñ¼iÿ?1¿—Åþ7\ó¿ì€ÀwGÿá;f;š©ÚÑüŽƒJHZJJB”_PJ^ðH+Û¿Ø;ý¶ý¿2üÄëÚý,!##°Ð5±|ï9]Kýw|öºöv‚?¼÷h@ðWÊ~[Ûß¡Iþ[dû?Ñý»|Vïáh˜»yè:ýwÛêZ:عþ¯jÿg!õßÛÝÄÎÞî/ÀeÚüõ^YËÿßÊýÖÿí‘W@‚ÀÂD  hßgXÐÒ€ßÊÂâ·ìï–0y/½•­ Í?޾™¥•“¥Û?Ë M, ~'`à`M£hibãø—Å; öožÐ@ ڼϲ¾1ÍïcÿLÂo6Ýoö{B<ܬ­¬†ºæv@Càû¬›®ã{Ú:=Üþ·à?)X:€‰¾ýûÜ¿¯Ø?ÞE- ­l±ß‘ü[ô¯$ý³ÏÈÞ—™•¥¹Ë{ßÂÒHYÙ¿w éÿëÛè¿P 9˜›K½; ý§ý·®®…‰¹ËÿGû¿´”¿£'ýg&vB&Î@{}ã¿jõ_Ô^÷}Öx-ÌïuþÃRü½}Ì߇â}é›ü¾4Ttô,ÿ%{ïw}3K €é/3à{ ÿ õ{9cÐ( (IðQüc+þQ´Ô·20±4zïuf€®­­® ,í{Ñ31ÜèÞ‡Æèü§4Ô–Vöï&k{ßå…ýÝ$ÌLÞ߬¿( ÿ߀Fð(–wMñ¿)fÄßÔ»äÿP¬´™¿)zÜ߀FþoŠñ=¿©wŸJ¨ÿ̆ÌïUógvhÿNÏ¿n•?´¼½­•PÙÄàýnþ_*’ºö¶&Îê´ïO÷Îÿû÷7Íÿ8€øï™ý_Ö||VÎnTLôl*úwœt L ::FVÿ°Õÿkþº÷:þ›þ½‰@ 3Pö缕>‡¿iRC`±§`Þd $1õI—ŠX ÄÏÔÉ6, ì- w¾O“wÚ×|+ vMÏËbTó×µæøò‰kYžm]OIO,xAÞ‘,%jEß4ÉEï’²C±¬\ÕBÆé´–˜\€âÈ?[[çCýøÛçËD’–•H§ï³t(¶æH΋ˆ_Ú±'ÛAíßP¢Âu{x’Ïè䢈AYww"ïNÚÜñ—--^?¸¢SŸ'ŽaþJúy ޳ÿm¢övúVž.ßX¨ç3D«Ï™?·¦éŒÕmKÍäгܮ˔ÉúIQà¼Â–^Á(d’wSçÊuf´Õ’£v}{õ™EMEø-ÆæÖN\ÖB¾ÈÙŠÍAB¾©ýÓ.Ü4¿µàiÉm³òóxâ»äNâ Ë]G%âºùs¤1¸¿at]ëH$&)‘.Ðñ›ÌãCýEœLZÌY®¦›®³E¯h­Ù™ìÓê݆i/$`cøžNÄý¦›àŒ÷6Ï»¦¸’ U¥„©K]xoa,êÞlÁä’4‰ëT­Z( Q•ãŠl Øg%X9tòËÐêÚÓhD®QfñdãÔ/ÁT¹´•“‹8DMI6²R)äõ™ ^)nÏi½Jsð[³’<äàë@l¨ËÉW¯Z¤þRFÚÔñÀ]l8lPEi.36—+œ)á~Žqk”Û]}}Í®üïîß÷¢•e™l}×ÖHf'qÝ]bÑ€7ñÏ”8f¢ÞŽ0ñæ4` lüÆNtSGÅšÀØE’Ó·íWM*£1'¼¤:Ê•H1S% ùÔQ$’îÐŽì­žì(ŽtÔ£4¬î;…±œMê±uNÒx,Ž!ý'ÐÃTö‡»Þq´@ÿù™§iªÜ§nÑCê(ƒOË 0NT}ÈÀ>Y- ªÔª;-Ž^Qº5åL Ÿå‘û^*t¤3ž uòÞgÉìÙ.Œ·q#‰LfID6æ§"­æŒhæ(<ø}\Øv¢9¹Ûïñ†‡ø&£i Æëòvý¦Lšƒ"6€–˜Å{“zí’V7lÅ,ó:øó.¹Ÿñ…W¾Æd„ ëÈ>ÍçóÒ‚BLø¨•ôì-ådOÂKhÎê宂§ [0Fìè=¸ZL|½–_ŒXøÂPÒêúÇÇœ×K{F3õ`ù3Þ»}ø¯Ãô8ƒáKôW 2nˆÁY³%9¾q¶U„ÝÆ~)<¿•Œû„=Ï?…ÆíÌ™(ä÷Æð1®mõ¨¸Ië?0z6 ÓÜïò~%Õ‘\,­YׯŸžìâz"œ‘ÈœÒÈ&÷ú¶ÉÀzCCqG,)eÝ50·¤S¢‰³Ðaƒs¢Š<ƒn¨$X|û`ÐõÔ›حWH Ä¯ï¬ &ÿ@'öKhÏ€Xa›5±H–QŠZñÔÐõºìr|{j±þù.–±È»8µqәߟ‚ÂãÆx„Ǥµqé∊n Ǫ†êîš|N¥r~Bÿ´8ÌÀÏ],³¼1¥ìë1Õþ̲ؓTw.ŸKxéIð+#QŒ‹eÂ@\Â[üzÑÉV#‹IZ ã#ˆWˆOy6o¿Ú9ܶ>.ÂQ8Zt¥IX›bl;õÇ ›Æ–¶IöyV³Ò¦¶‘NY ö£ïnœj2*w—˜,50–`Šóå&e•ŸÞŠtYsapìÆÉÂ+wœªèÉšNñëPÚó-âÎk*ä‡Rן¦öîÜ3ç(„ ÄE„EážvxÎ ãc‰Ãb4U|C$ë~ø?€ß¥¿Ý·ÍŠé\¶ÄÄùSð¥}yb˜ôá Ð4Xâ[çP÷"KTu×$P—påþÉS߸4×Ê>«|L\s÷‹Å©•©Æ4Ç_ì;ot<ê´‡'sO ²bÄ4*±ŸàÜš»´ïlA}T0ß%9n(~Ï;¥+UNu‚:a\¸S,G8ƒ¥I1õÉV¼¾ÈE°rpºЉAÆ£§BõÙh»S0Wü(‰‘­ú5%|KžF_• ƒÕ³®º9W™ëKù•}9Ò€àü­ºŠ†°õ`r ‹y‡Ä·„ÙÊza5¬V½¦Õ‹±`5à¥+˦И®O/ Gä±Ê}ˆ¡=Yª™G“‚[I€yÃØÚ¢¥}Ðr+8/£:(s 2Oám5Ð-cÖ•‘%›úFéç®sŸ„Ã2é‘ÅbþE)äI!•E%§þ/8B»‡$fª%´ìô¨Æ;h¢=W@€šÙù~]ˆÄV ‡9¯m]„<Ç D÷ d ié– À5ªÉÒ1ñ`…å$ r}ü˜¬f-¡æQB1Y¿5ÙMÈñ#¾n1ÆÐÛ鮾÷¨ö„±JW Ø$–®W*æÜÒÉçWürÛñ¹g‘Û¥Hfa®7î»ê׳Qb–ÞóŠØìØöŒô|#±Kzöò|ç¸#3¥›ó€pR4„$Êc÷¤ïFèÀùPÅÙx>#$Rg%¤»°+¦AE'wm![¦ l§ m¾j0œ]µ†w_Fã­É0øð)Á¼©Ý,(#/Ð@M‘Îﱌf4¾DŸZ9ð)›è®UöÒ 6KÝ×2Æ$”øØ#¯x31Ù½+óm@ ¹G<~÷P[†¿D ¥(—‘d-À5@7Q{3ÚlŸ¹)” BQV½ ª9PÄnm'BhÜ‹_yE¦ì¾Ý8Úoýê+1ÒÇ„™¡ëïÍ‚ÅÊâA 70ÄZ Ï…4åp|Ÿ5 ú y™è xÚ±y¸/öaºH©rCðÉêa¦“œ‹€³Ö€Â`Ÿ8–«ÊÔh@Ø@ÝœÿT’§X|ÊÜBcKÚ^ÖÑYèšQ±‡+IAçÒ’LC¼þÌþýò§£‡³_Qa´Ù8k@{׫ðà’¨ïy¡än§î‡_jý>Œ0ððÆŸš£5pNq1ª´VŽw¾I‹®LÉ#êýduµˆO\(ž£>ËtæEnçÍùYLJƒTŽ{b­Ø+Ë`‰²'œ(wð.«ÕÑWÏíùìOë|ÏTï¬™Ò žœ¹ñ›òéÚWcek«çFòt&ð‘ õ¯Y§7Ü´ˆøæ„‚jƒYeHØìŽzÖB /’õk„p;‰öî7¸+n}ÞsÀ›êd=™@9£¹à¸sJÙQž‹&²a ªpðá€?eiírj HËðСjÃ'0äo–bòfÊF̲k>8–í£Uê™; ¾jP¶ñ¯v÷ ƒEñP'‚ÑY?ãÙLèƒ8Ñ4î&‡Òœ´é•é‹MSvÀq— l$¦Ö/+û¡ ×ÁY1Üxõ$žÁç?¾EÉP5T—ƒ,™QùÈÕiža&•æqéÑo.Å6á†Í…1”?V&RP¦œ½”ø¬M•ÒäDÐl!C»”ˆc;I‰©a˜éB wwŸŒ/ëîäµ[-áÀàþëÌ`Ø×VþÒ ©-ý•3ÄÕ®3Be\‹±ù“¤:L´ÅtÎ#£ÊŒWøôl¼£ß†|úvõwïÒ§½ÅÉ„ÃoA»FÍ@Ç fmÝ?§=Õ†èBym9—Ö3•_¹²Jõ³™„'àÆÛf¹7mUPL ,ª–½·6Qa`çÔ×¢ŽoÆë€ÕáŒ7$[(úʇÒHÚùŸ8š?ë(ìTzGÿ:“Ö^K lÚ Àî*ÐòHu{¼C®(4ñ­bÐ{e~ÊLN0äƘ^É ÇæïÛô†ˆÆ¿EÎYÆÊiö|“‰Þ1J-"»Fÿ‚ŠZзë™ùÑâdaÝ›A`Ä_bâ¢A5å¦s±E:tвçŽë7ôÑx`‹viÁ#š®è¶ èTË}âÎ?”8!ÏODÎÐZÀ^ÿ{G`úqÐâ¹.–7µ:ãØtøå¡ç‡þB#÷Ç_³¾@óFKþ³†À' ªÙcÍ0;ëé·’úDd@"ñù„-AÐc¿VSe6mÈ“A>‰¥¦:£©s¿hãE@q \aŒªLÝ ‡í¥xe´3mÕ‡BhÙ°Ì¢<°âd7‹c&¥.ž±&òàC€g¥ÀqÚ±ö½Â®+N)#††q6GiØö\fm6aóH^°~$ö9”“26ÐÜœúq°×ÈVªÅˆyê„qiÿg§ ƒ<“Ÿ/ÏÚB¨Äö,ÎëÙè®ÔWbbö^ÑI"À|_!šÅ[E)ñ™’±J½s®+*·ŸQzà;³1™Û„(ЏNÕëæÚUGË\× ²Ók8d¿ÉÈÏAN™DÔ «é##Œý²múÌÀm ßÙ†R{¤ô¥œ¨í—²UMÊ­¼ý¡=½q„áÛM šå b/a>;3®YEÃNtl$v°ÁÍg´×<´þÉòqÝv÷…©6ÇÙ ™þ—¹P„yAaKŽÖb3î{ä\¡…ûÑ#xî¬}ÑRð¬Ü`=ì’a5lo6Ë,ä:³éáŽAQ7‚íúdŠMG>Û&ã:I·&´”JS£iÓŽñxŸÃö…@)~½“gÑ™üËz_ô¶Èµ³" a´¸Ëõ¯züÈèt嵚´N 7 ZWÞ U¢WÄî`±ƒ9°1Éœô“ô^«X‘@ˆ#wd¨×P|2º/7F~½†ªNttr#¾É´HÄ}Øb*£ãÑØ–l‡+¿ü²›¥K²ÂQæ¾¹Ä)SË(N~T§š…ªEŽŸ/ŸœÙ8Žw’A·gVõ ¦Y®ˆ¬»Ö× UHÊ£çàúº‰ó- 7×ýR»t;µ¾´˜ïÁ»Çââ[Y5¸¢?¹hxŸ…[”Åö0ùeFÿ'mÆ å -F!‚‰ÏŠyÂ÷ëõÀL~ná*MlMÚÓn?2‹ó¦Ññq¥U²I° Ó­¤i 2sbuÍ‹)²‚âÚ8Þ±Y–?ÏZF— ]Ã6î†ð—ã¤8UQø~%‚¾ÎOMͲh˜Ç_Sçw‹î&DÙ¥`—ÚàÔ(ƒ²]jåD”ΈzT6 ê4BN°4z Iœ+á«óá’¼ ¥Õ™Z¹ãŒ¬SÊ`Ÿ¿9¸ÃüD¾Rkn¾ÃºÐQµï›]­.|³ûµXǺÖ2Ó3+Ï[C*¯ôúÒ·:ó‰§aF™/ÿãªT£‡•œZ|!R S^^m5H¦~ïüÙpÓIŽ[hK™ÂOnH&¯ïÛU0ù¸F'¡È_|OÁ³ÓàoÅk—€7˜«¢Dš¼È†oc×g,‰[¢; ºnJévÍ_ýý㿊ŸyÛ&Àêè‘j¸éû5wKÙÈBt§ÎsSËÄ F0~б½Üc×ã[&`¨ÿ˜ìQ=Þ¼¾ìAâ‚[ÖPبYzÓcsbÜÖ;qïÔâÏ9VÏæÇŽ J&E…N˜ (ŒR¯P¤VKöK¦`CéÃs#q\‰¸Ëé ˆÚ¶V^ûØWã’&f¦W<Ô:×EÂV2à ™ À”gφÛY¸ë[%s;ªò EÙ òüü2œßwÞðûÆ×ÍŠ!L°R·Æ­i?ÖµóÍïfñð@\FqG³Ý‘N|‘l Sâ-Pï W™_Î4 ˆÒ¯Ž$ß`ã{Ö”‰™æÔñœFú™Û™t:¤>iÕ×6ã…Ϫ 5[ ñ!1ì'ŽKVAÉõ„ëË»dÛ˜ž¸K€1ÎXÝ`•õ’Ž&§®êÆ|£›¾èå>9‚´ŸBãÃçäèf‘EÚH“|‘í;ü^z BÌÿ¹RE$,'CÇ]Ö>ÿYàz$mM’IÌœá°!dßc^WGENüOÁ‘ˆøÞsÐ\–cIFLH?:fjç@•®QÈús²“&ȉû*7ÅÃû •‚-ÓH*«K_õBFŽQ3y¬« @h†ÓälkŒrß5}~±ô<ß­Ú >JΫò9P¿öƒÖ®Éuáh^M`"QxÛt€ôû)~äBléÍ·êD.\§QØKT¢ FÔ˜ê0¶Ždݹ’ÀʼèÍÆfÃ<5ŠÑ3ÇV÷8 »Ú-wÃɆØW÷ô³Ÿß¥ötÜs”Ûy2ÄI!æš"C/¿0Qœ½X}dB˜FîVs_ åÉN«M t·³AWíîÈ[ã¯ûÚ·éP¥ ¢~ƒk¶'5P“ÿü+‡$ÞÚ½xc¡Á ÅŽ´“$ö¿¨ööQM’“ '¾ž!åyÎ!ƒß•Э_¤ ]Cmúžö~¯I¨€%OF¤%‹·J/š5 ÄOÈâcfÖò ˆÔi-ëz.ÇašLWDÓìǘ›L¢>% äöZ$fÅ; ›K¹•ÞÞ#Ã?©Ç°Š" ~†³ŠöòÇцùør^š~ð™Iž¿®… IÚ‚½Û¿½):{UÒ]¯Zs ¡­úhŸ[QOmê¡é!ÑX8$Vn:¥ßµ®õ±<rËÁÙ‘¢QN"¥/ÔPRlmÝÍ~“Ë"`ƒKWM'çIïs• mÐ@[ÆDÛæJc6>VIp¼I/1L~Ú|¦§sN»µmq™:7ä†^êƒÞIÂS>áèXüÒÞéabbð'ì¼‘Êø39;²Z>͉¸ÎÕ,Üø«.Mòe™FkÍB.]w©ÌÔÏH¾3Ìó‚cý<ÕØåD-ã·¦,«RuHÄ[ÍO^ ¤c?Ã}C±5üÊ…òµÍà;¢aøU)Óõ{sq‰ A¤2‘"Ý®¼üÒ1 ×¼1]bNö™5R 3ú-RU5T@ü *µŠ¯ÒÚ˽“Ü0Æ=Šg2ã ¤÷gø<^‚kÆ%– w’RÇ Ÿ*Ò@¦9¡±­¬öÀÔ™-d$yçtàpz¸ðmá’¹ë¬ÚÚö ãjÐÍ'×ÅG.®” 7Oxº¥­ ÌÇyf_OË^šŽrºŸ¥zÀ'³á—¬ŸZ°øóþ¶Í{óÅ -ÆHÁÒ4ç­3I¨n½Ïà]1ãý¦2ÅŒYµÕ= q°˜~$G°û{¾ Eª‹rÓ䫃u%‡—_9<«ô6¦_•ØHéXÀµ1§tÌ E8ÄËçîgÄ=D¤åøATàa\˜\GÀHKZ·È`¦A»º]ö—ÊoŽš¡ã×*/Î}ZÃæ_p‚c¸ñÚ1g>Ã2æ’U'I`uè5é±sƒ?ê¢]á¯!ÒÎ šùBwaÙtꊙ YÆ£§Õ‰ ”žTÙJoٛCÌZKãÑJ:M 3} ‡)EHØ^T â "¡¼é¶‚-Ç@ÍGßà·?SXùѳ!þFŠi„úÕ=ôˆËד?]o å¤‡„2?ªúd¾ôBÆ ƒ›•³-úšàžf±C\Õ Ê)ÑŽ(Q’Ôõ9¸4ç¢ †‡vëß*ú§ül}½‘X2σxz·5©t!qMëêâæ†6›,ý"À–±³¯(T¾×Y"˜~÷û²ÔgÖAˆôÛOÑõÛJë®Õ ²2YƲvϨîdŽH"û”hIŸë©ß¾ï̦:8¢—"Á¥ÙÛw±<ŒbWåY¼š÷ûgŸŠó~Ç c£½WF`§þªÖs‰ás&¦ú¦¡],CÜ›OˆN*¡4[2]ÐK¼OE¯ªã­¦æQ$NÆãRÿGª—ÞáZ0[S6¾j<Š•íoRDé ]ÁxJH@6r ª'h¼†sÙ—DpC¸Z£P°Œ« µÚmêyjbÜä nnÙ3–¤(8,5­U•˜©ûÿÕÉTïuk^/ñ*ÌùÄë¢ý—òwSÔŒœ¥ùn‰×·dÜ9ïšà®Ñ¡^޽”Ç>üÚ]—çwAàòÔ±»—aX>R¡ ãAöin2­ÞlÜèÙƒá&Hü.û‘îòšƒrðnlÄ‹¯T|ŽVν&üÐ=½²Lðp„=C[2q,tP)ª<ùœž¶âî3R€€¡œU¼ËŽÛ0%&âc‚Z°GeÓݶƒ ÛU%Æ[„÷D;1_üÆŽ’ì¡qZoãNð>¾³TÑ'#doûæFžŒ èí:~w´rëj·ÔWêOÐd»¿ t‹VÛEÉ8í¸¢àª%™Á JL^"€®Úkgæ/ŽIoé¦É]RDŸÁ¸ ÆÈÛ¢<)¾||P t#@‰Úlž#ãV˜õ[ütdìÝûÙW!'FxŠ5E¿û©ÀnqYyh—ÌŽ&e¥ÓÝÁ×riP©Ë@^êvÉ O#‹ &\æÜ¤9„ØxÉ?í3<S íOQ1µ)XÇˆÕø?p®ò|¦¦ŸL6ø´ÌäÜ¥ˆ§Ã×¹îò7Rª^TÛSf@µ-ÂGlìK'¤:ÁHét`•”H`å-5»-r…RèðQ©=]ùDëì\çHüúìÜðfѽ£G$|Jù5—E환eE+PUó|I0NV½s;“’Âî\5‡Nâ±í"£wy°ž±z†`ûG?­ð_Ìkâe¿äôµ¼MUãÆÝ"Løî_©®gQþ¤¼O˱ÔêÞ´Û=6s·w²ëÛdøy6ê9ñwïc˜?»·0ÑWxC…h• ¢NaËðY†v1Ú‹ýJ8_€ ð C³}ˆµ>Ï+׿õûDcgÅŽ.ƪ*Ûþ&¹ärá7±EÅC¸eöW"Ój_—Ü)u™Ü7}æÓ†·§#‚y¥C{=ߺžѱ9 Œz·0jmiœªVª©ÌÚ¦ö\¶]ôÇÇ‘i¾i[rÜ!W~ÓÖÝt¤Ÿ#®i»P%Xîkní›§Xª¯Lõ¼×f0»EÒÃÅåAT[a¥çÄœ{_:'3¿¤µ™ïLTLnf; ¢rXH»±n0)¨OŒHsFw6_*]¡Á²À·°8\“9WÎzH9Ù-Õw°Ñ(hê´LéòÍ©tvÕXóø}y¦ÍÚUMéÜôW˜ Zµˆ&Z8‡Ç¨û *YB¤¦c²/¾8&gÀ LìˆÌПwÌŠQ¹ì`3þ„nsî t­ÞŸÄýÆ4—0¨z}ß# d ©£{òßYmé¹óS•Üiœ×4¢ý¯××UIÊ%‚iâ˜WSÚæ¶¨þ° vWèˆw8p2Ø¥ÉÕ»‹‹‹ã„†Oüô]$mYH^.z4ÇìF>¸åÜ`ˆŸ}OÔÒü—p"ÈÒ5´•VMöõeì$Gäz,[·u¼qu"!EÍöuÓÂMn}&%âÏ¿‘¬Ú[ýåʤ3ôPL[ÔÈgçå67Š¢y„üÔ#Ç5ÇÕ,OœÚ¥„+²3Å*úïO¯ª1-=Ц‡iú“kѦGŽ‚8·ÔI)ðëþ£~¿*]ÄRSC–ÁÓ3St¶QGáÔì?3VƒN5µ®•çÀ-dÚô‘º5q Êš[|[ -õd!16Äû÷°lMmíIÀ‰ÐÇ‘U&2át™2–,»ç Aÿ8úéÒâör"˜3iêj~Ƀ ¬¢b];È¿ij§UŽêT$\ˆ%;la¢æË—Ú¼Óai©Œòú*²é“bØFä8[&Å/¼/“¥¿3<¤îŽðñ.Ià(™[á{uÖŒáèRbIVÛõ©´¦¨#Ã¥Œ”,2. ¤"&RQ½]Ư™N÷…uŒã’ó5*åÉ2dÞ ú¶4|Æçoå o¼ìùô—µs¸ª¡ø¦ŒsZI«i~ç]'„ΗЈ ‰ áüðzÈ#ùé`“5µ=ìRf:Í÷é ²°\ÀzDÂÍ/\Ž¡¯oZÞaÜŽpUŸ$Ýåªn8ˆ×îPðÁQQZˆu"Âú`‡|âŒ1`ƒ=`ù൞ €úJ°%ÕÍ'Æ,ç*ÿ‰žNbkšÏÒ~ô#r=A«Üü²ÏÄ Ãªûö”ZÐT³{EÎ(ÙO> ˜ Ȉ&öNÌŽ5/Œ½v¬ÝžôÖ|ªãEaƒÚãI–d¢üüO×^"ƒ"O}^X°žQV ½~¤T{È[‘°ÕûèHk±Úê´Ö­*Mî“þRJhÎ éÖ–yÌ÷ÉÞãêÞœ ¿îJVmÝ[îWâIäSp/_3©ý¦oÔJ}pÛÌ•ŠvDPYò>ŠùVª ="Áöz¡DŸä?2•Ç(žƒOÚ—*²X l×ÕíŸÓb ZèÎG¦L:ÌÃÌ;÷ôiÚ¡Š (ÇHê3O-ý$訠›"LÂt4Ÿ—©¤JC—¯G<3åka韛Øá÷s8­àb2š·Ú-òt¼Cªàù~`Ô.ŸoT… q°Ž?+Ü•X¦Øä ÏàªYœ¬u·|³ M%)> Lui²hÎÕ™)ÈXFªŠ»gŠ ÁªÁëþ‰áX¡1·ž˜dŠùÂ#UìÃu ³¡š÷Àj‰¢»â> Ãõ6e>mžwv;Aºd—Ô¶FÛž›v@çJx¼ÌRÛ˜ö¾XߢÝ*¯¨h¨¼'óáøp|¾s¬¡Y¢‰f ^sZü‰=¢6^ÀöÞø9]þœ(äkÃÅùÊ8Ÿ›CUmnÜfè)^nhEÇ[ßnëÞùa§SW[®<· •»z¥ÑŠ£^"ZRAz;9«¾dƒ5ûʼnIó(5âW'FʃHjBêÊÂéÝûTyv’²}»ï䇪DjÌÁ ÞÃØÈjǾYýZ"Àafw ­Õyû½íDDºD«s²ÂŸìΫúˆÒ»¨ b€ÎÇØ¤=&4£Ú#›ïXîØ„ÄÒl±?Žua ï?Ÿ¹SzÊ5⤭¿P6Q •mXk®Y² –ë¶ï®aÞKg•mïÖÉÃì¡k‚N¢A/@­~á“[ö°aS¥&·PÑ8å¯F7K¥S1ÌÈý–¬-°¦c}°S Ü/l¢´oM…M!¿<Åõ7ÞCçVû\4û`|¨½fn–è©[ЉN'h§«'¿Zw Ë4*H7YjzV²l»æ„6-#-äP£;¶6fdî”E>M_®ýìÈ0ƒc/Ë‘¼Úµ`P!nW°§s]  å øvܧ;V8Ca0ÕræÄôv^ì½|½µÝ}È ¼Üý*>¤ŸØüL‹¸„X–xkT TA—S-÷\îUéŸÌy€âĶÌ$0 e·õÈçæ§z% éœÏ¤=úíùóF|³lI»v,úüK™¬aëÓ•ùw ÛUç’_Á˜5÷¡÷­ÍMÝšÞu×ÿ~ÓËä6Ýa¯>Œq‘ŒVíOâÓLˆGJ÷Ã$íšîS­˜†È(ž]õ’ðG‰7ðrFìèWT~[§ü¸çÒékJÍDß²]’“VX5±ÑŽ‘§îúˆÓ"NüÚH’•~úç!Aî?/ŒU'”ï£*ý¸Èêf’Òî.ø–¡Ój–Г<ÉÐØàÝ“çEæÞ¤OJVa×»)7s›–ë¿@.÷Aºwð 2©“å&¹IYYv¨<3=êè‰.m*K5o‘IštÞ):¤Qv›Tâ\íÏýùakHÊq±êÇþ·KY(H «h)äfŸ¡IÝHtÿ ÛY¼©Žðíú¢Eê'üÃu±­Î4‚-ããDÝSý¥8ÔµCˆ¯ÄI’$¹C¬ŠV3 Ìò’yÔàÃ"É»Z&† <ÂJ£ñó';Ý7¼RüF‹6]Óð«¥: zJŽ÷º¼žid :Å„D¨ªÎ÷GgÅî¤ ˆ“šÖ ~,e~Ž©²BMk=,àˆ‹ŠÃÂZWMò†£™#ýYƒ|¿yeÊÿdÎm·ö±TÉ7R2ï³+ûÍ7?¯^lÈ>UÜÓîF9ÙÎ{e+ìô¾®]|öCïqÃ6³®ðˆÕzÞzìxè䟚4éÍtVJp_ƒOðU‘S¬ÐTÄkÒôT™jíÜŸjx•P*IüÏÎ _æãÝüŽW©dhÌpŽ½Æ ©’¡GENÂ"vøÝÍÏVî67ó,}Ûªáµd«é Ç#eðA_¯-)Ù[ GµòCð::°ômFiyް!aq^FƒïCáƒ^œ‘BP44f•³}±^.—<®éÖž?dË]A]´û_¡Û@Ó\[öÜ^ÚÔeÆdï« êSZ8Åïâo xÜÚ]‘tãñ*é5=4ä!lÑ•`Ì÷ádÌÌ@—>°µ³ø= «‹"QGUMÙ¨VsÚNÜÞrañyVxûŒµ‡é Ói/¿é̳­AE¨V‹­?Ѝ ’™ÿDù©a#¬Ù¬ªdê`xñaO¥GÑ~ŒÙíBÙÖ¨^w‘ŽEqµøcy¶_ZÃHþŒrU¿?nàê`1Ÿìy%ßñt}SKŸ6lë›ùúªèK…ÃóÚ÷‡­Bn0ˆ‘ùá©ó,E Ï]¥ÒwK5_ j!…QÔå'ºTo I^s‰Š”6iS“>£X”r©˜C¾’?Ö^|›ˆ¡Òi€æNÆæÉž𾙈U Ë“r\Vé²_p§CDgø?U_æ{kÅ—ºˆ*Û”Fþc6õ¥ÉyqI“KÒ3ùéÉu6ª†Rž yæCÃÂt³"ºÙÌ M˜bn?±¦Ïˆ7޹Y&Kž‰ŠMê¨1”iŠ˜Bò¼» ©Dú¬N£ÆNZ²¯~ˆq»ìËkª x¡Í.¿©fJ’p êZ·Kä¨ "ÌëøB<ƒu¨ I•î ‡f]ÅyìµP^·ðÕYI'•Pt‰·ã´£Ó~lÞgŽÙ §á ½‘œâôën® g¸«$lä •÷³QÔŽÜ3Kö„GêÆdgo‚Êw”Î:øƒîtÎâpw¥r}œŸ¢WÛSK:,í×®l ëø´k¥®¹+’ cÑwN#õ#’£Á^ŠŠÇ£xŒ¤të¥MCžëÚ žåèÂ[¡So NÛnR®æx=Ù&¦„¬,ý{6Bï=˜ ª)DbÚäÜ‚ùx#s‚(ºMÈC <¼JqÐûï½Z!?éCœ2†~–áæÌHÔäÀp…,rX-Ë{+oì°*ŠL^Þè‹­$- ´gå ‚ÜQ¸±Ž7ûØxuú…àm‰<'y)2¿µ§Á‚B„AïkYùP˜G&ÂË͸`= \ÑRCgÚô±æ8v›(x‹8Ù×£,™‰TÙDgu;ð4Ã#IÊʼ!Ë5Ô”±Ó>hü2ç%«˜N¤êê }è2Q‰‹©ÚÝdYi]ò-ÂÍ#«×°×•¢õ{Ty³|L º°0¶{ÌT± î¼¢«‰˜Ì?ÙÕõÉ»pàÖãýä–BÅö?yawOX’á”CD}¹±#W[3H@qa÷këß»èOɦ‡+hJ¤ ±£-ÁÕº?¼” •?Ñ,)å¼ “þxÝBÅ úˆ÷2Ù ÓŸð¹î‡r3šŒ5>jyÔ--Ó7tk5+\ñE"qC|Ñb±¶|/éXÁë•>)6ý… =¼,”‹ˆ•íøѪd(ù tˆûDް{¡a#•¶l^ÿP¿X¤Y¯° >ÇpØZn¶v¡ FK*)´Î–~êa ®Ë‘B“Á†}ô¶š\Ã2®¡õ[ù)߉DÈ} d£z—ÛLFxò7™ðýJq8)§€©søjÇ}N¬x,­¹¨#&ÇÉxÝ™ì<l ëX˜Å]Ž“5I"þcvXwÆæ½„RÄâýiáôÏ•ORpu]⃖ÿðC´wAµ¥Ú˜´Åtú«Š„D}Zå‰vlÞýIíª0nHX,O)Çà/éVe’´OÇRû¤ ¸†^R¡MËçF¨K^ç8q±ä}«*- z拏GÒ*}ÑA6e\>€¤Pü ËÇLMöÜB©x6ßÊùy¦ùÆèº[ÉÍÁÚVúËñL²2Q_š_‡ˆ ‘@QÒíkÝÑsTÔ‹ù=¨÷¯¦õ±#É*xæ•ò' Îx• ¦žÚz(?OH0ð6±¢ÕDÔ u–=ö¦Ÿ¹P*ÿX¼3; e‡.ëùAã§Ü×7_6Å}K þ·aÆñUQËõø '®»Š¤Ð0ds“º¨¹›Ó*ÙSxº Т£ÊcBoeˆ˜g7<°ëvTLO'þëpÅQ‹b³ð)t¶+oÒ¾E EéÈ,Bzú0]œ¹ò†_áµäØŸ'ôKv ¼Š³ZRâ)Íwê¬núÓJ‡½È¾”’ÖK_@M„#²ØÓç)óAGJÎI•ñ€“9Æñm‰ÙWédî—H9©tzF›UÝ‚4˜aËiÞ|Œ|^+?Ô ÓºUÕ_cõ§·÷û€–Ü^˜;²Ô2%ßñ­žmˆä®Ðd­8Ñ‘_4ÛS`Ç…zç¬&b“_ªÛî¨Eye]vÊ·R·ñ—81fO5[> :QPµÛ4òKÝtSßrâ › 8_ºYÁË*¤‚£*Úî$GÝd±ªoí gr•Ö%íÙ5K¦>ΰ¯—0/`‰êM”舖§“)Ùü‘E=BÝà~ØRšµ: Ãô ón–íEãæa« aGlr \7ñó“BAMK1a‘òœ+…;2ê®°¤òÜ[¿£õÌZ?3z© n¼Ý5/‚ÚÕx1³Ö'–Ñì’LÙð‹±ˆHwŠ—Ëû3n˜:+0ùV,>®*ƒxvY a 2#—À•çÁh8h‰n^t‹Bˆ>Rcš3Ê´.e€Fé!î7[¯|Ãüé7€‹H\ge†Ïv]-Ø °n&”^:¾p¤óã˜F0سV¢^‰b·Ymyô÷4ïÍÙÿ40ÆÈé,÷ƒ­¼¯ cE0ʉr4®Û¶wâš á„Nð¢ØkŸgMð8Åèc’½TNË"á"¼h¹RžÏóš‘ü—æZR=Fø#·pè"–›*iBÇNNè|Ї¢uÜìïßÁ'šìP:`§íõ‰ìèÛ\òNPyA5³bÈHÁrŒ/QežŸ—Gð“Ôn;¥Ö/ÁËæy]dºþej4Èdáóºì [nËY”‘ZHŠ}Ü¥éHV'£„-IÞŸ¼ñ»ÏÄe qN’ÿ°Ìsq‚Órâ2.URKG©ÿ„µñ1ÚG¶ÂÔõ–;rªƒ{Cžq¿!Z„`Ó´›ª’vS¨j·Õ'†A¢ïÐ#4 Ûþ-aEØbå>ÇÞ™ø¾Bª¦Bóʰi 3¹-±mÉbGùCècÚØꩃ‹Óªyà $“¶7yCƒ¦-WÍuëªAÇ4§I}Jåð½Iβo®®zaUˆã¶ÓGÏúX½•“_ƒ1 9ÓdÂ8¸§¦¢NDk+ÌXõ‹ ¶_VηŽká^ ±qáš9qMÃ¥òôÞÔM3™]Ò ØÂ}{ÈõÕK5³j}&$ûè¦TÁg( =,âÂÃQ›\*Ëçv5d˜ä:ÂËö•‹©Ðyaå%²}gk2®{DÂ=p†5EÑ –H\´^µ-鋲žúEGÑ÷èË":K›qF}½é©Km7‰aa:ÌÐs`ºß-«ËŽìD4íÒßj:ËÉüQ¾K¤9O¢u-9•‹tx©?7ñB1Cr[ XvÅ6eƒÛs¬˜,È×8>8a™HÓ„«ÒY¸]ÓÄæÖäá½|&˜fWüV»i[‹cº÷u!»®zŒÇ ¦¾·@‚…|´v¼Ý&󘵙ºtÅ¡óA0A£OäÈÔµ2Ÿ1Y÷ê5l¬¦Nø;#wY0‰h^ÿl‚†·é«üBÇv„i4µ¾[ÿ‹óÙ”!«úpœÎŒr eg'å–/x¶µÒ3¹ ¬ru§ªVÞ¦(ÙͬFj–êG«e8"/žàÖ4hÁ#H£pÆÔPÑϦ0­^ôŸÆ’/ïÖY"±J«Î>9ëhhQXŶ*nKDšiÇŒ¹Íôi?)Ùt/}þñü¶ßo‘ÉCÚ½û&ókÕQ 6 ¶7K-霺+ƒïÅa\c8°îxq· ±¦mÃèaÒ¢ÚÙ¬[`è°Çf︃³·xUˆþœðø¥Ù5^15$â‡Ùy:}§¸˜èbÍ9"„hØÉö#šüIm+÷ < ¦ÎÚ‹6Ì8õ6)"6ñ˜C;=½m|]CœSq$±o!vkõ%fnžæÈX+X ßoo&¶#jXkn4ãKø˜«¶…1û…"– ÂÐì2®zÚE&uGð¸ß o,~G%Ü‘²e#´äuRva¸ž/sõéì«\¦ÂWÿ»3ðílBåS®&w¹¿8í¯KJ¡HxäªYd`­è‚‡:÷k¹»·s-[+%ì@÷©m¡‡¿À&‰½”Qk;xŒËã™dÖHK3¾w‹Ù'as€J¶I™ÑæúôŸ¹¦.ða<Ži½^}Ý6j<¹YßñÉGˆ¬­òá]ÕXkŒ^0g>V‹í*ß½ v•'JD¿ºþyc›5Ð#,n—ûc!àœ©›e󦸋vä(8M˜ÿ¨:düèD)O=(³Y§ Z"Th>ãËñ÷Ø–ª†«y}ïpІÚu½g£Aß`Ù$¶Z²zÚÒ”X\Ëšd¾ïµKQ¬«ã`^¸0Ÿ§>«NÅ&äɶ¤µøi"·ž' ú1&yzðå¢fQ¤(iÓÿoŠ’?°ó¥¹Ü\Kf ¾L„gL»mÎýFðkê[dwu-Ý›ŸdP¾“šû‡+'3@_4œ¹ K5^¡´†­˜ýžQwsƒÓ—/5ØbÕØ ÿñ¬šñž dž(!Å·Ë3©kWÖêÛPèŒpðÀgƒöp³o(à^Á u¯hd¯ j…éÙ<âË9Ý«Êð°c× Ñ2•ÍÌõj_‹‘Ÿ×Ùy8ÅaOõ‚­ìÛÇ3ÑÜ/,1¨ã4T¡ÜEê1_›ñ.ø][ZRáÀÑî} ½•ž:+êx/ýi¿'ï’ÇÂÛq’@ÈÖÇr)Òc]&·…5xé=O€ß¶Û[½‘_ýhߥÙfNë¢N¡ï%Ó"N¦Ú\Qs?6Mœ†`å‡wÖG˜ƒÌ±ï¨ã1nŸaè¦Ì{L)‘v[ápQ^¤³í~îíÆÄëPZCQî¢5·Ü éÙǃ`hn§ ³ªóÿdræüì_Ý®Û÷UXƒÎ—i‹ÑY\µiÂŽC8fäI[í¾ó§yá·¦¶™}Ó@J†ìWñ¼~áÎÝImècÕl¡©ŠhÚ ö<6õ¬‰8íLŠ3±f†âVU]Ý‘šŽõug™VeöZöOéÙäk³@^ƒ Kýƒíf±;ÃÀm,ÃÅî…ƒ¥o± ÍMÖƒ<´Á ]ŽLól.šRHFüö ›[úI¹x9¤´òûþ´¾°´‘ì/‚j—±.£÷:µ1«Yœƒ sWüÝœ®ùFài3' .H[νýXÛð»g™’ê4ÝeoöOÉ­®ã)O ´xJÈuîdCŠ—­îsUÈWs;¹¡’÷WwDF(±üñ`‚ÒC²;t©ã—;F‹>¨þ}ð·ô䡸«Ép б7BF}×û½È™ø2O#õ®ºF!¼¹©G„ãgÖ2Š;%ë~‘jHÌ®ñ¼<Òc3º–Ý+¸ôb¾Q!¨‚ؾÚçç4¥›Á0Ãçî„dWáf|bÈ×CßûçÃ$ÕÆ4Ñ.€^º‡@µœ&z+ ä×jC9üÛ¢"¤îQ0w¯#X,öû8Ûà ‘>‹¡ÌB•;Ï“S:ñ–u²âœ‘Ž¥Éa|4¹Ÿz±ãQ'Åg'U²jŠÁð_)Òvƒ|*1bH’LÞö¼í1gH£ôâ¯mÚ®F~EZÍÁÿä{l¢¬…)R!圿 ýÉôÔ+þcf†ã!Åï„P—Ol3Àví‰Q+f™®˜58Ìdþ&4RS@\Õ›D·k)N0-Æqþ8’ǯ*ëõd'À¥6§xw³ßfùZ©\Õ˜Éñ·(¯ÞLÛ(šu ŠÄ(5F×K‡>î-i/TÝ}QæíœÂ” ûûJÚÕ5ܰm¸'0<åCT &”= ¿¹tÌL…¹û¿èVŒ%)Súz†½uy³\H¯¶À$*àø ÛQNqºÛ§ì/ •¹ Eê"bѶõ2û!ÎÇ8_öúŽGýõv z÷84ø‹:ó”¿oK) ±[äñ5¯w2 ž&i4÷z žD;éëÞɬp.®äþ³‰‘¦“¿yS"Kƒ–Þ‰–úL¥²Ø ­žß-QgפÇÄOÓƒŒ…À?®dkÁe£XûÆEÌPþaÌ´Mt>Lâw³t k™îŽ d Ì¨¬ß=£(Ÿ ¸ß«ö”÷âȽÁÃÉXv†À.}p=r ½‘ŽÞ5Ó,P¼OIÌ€ƒ†Ù©Õuó²aÕÇpÏË1sãNÚGþc×p7é-{Ó2µ ÙßTî`ÐE;`2òªúû§Po§ ŒN©tªó$k:Ð endstream endobj 9824 0 obj << /Length1 3069 /Length2 29360 /Length3 0 /Length 30995 /Filter /FlateDecode >> stream xÚ̺ePÚÒ.Œ$Á-ÜÝÝ5¸;A‡ÁàÜÝ%¸»KànÁݾÉÞï{²Ï¹§ê»?oQSÌÓ½ºûiYBäÄŠ*ôÂ& # ÈÖ‰ž™‰  Ô”twªl€Žô" k "9¹¨ÐÐÉd+fèäp:™ŒÀÆ&&nDr€$ÐèVšŒÜr@'CUw; 3€Êð/ rt¢72t«¶f¶@j°‰(ÈÎÝÁÂÌÜé·úߎ¦ ‡ß4¿y€nN@[GpTÇßNE2†ÆV WG+ €¡­ @†AŽ r -T [€ÐÜÐÚ2ýË…šŠ¸² @RYAMQ…š nt²5'›:;®@pC“¿yKÚTÍà¡­9˜¢Š³Èá²UQU“¤ˆ Ë«Š€êtI5U:€¼*Xø—æ7)ð€´­‰…áos9qUaU-EqfÆßÕ0\À1-~3ýt(ÀÉþd65uÙü@eîädÇÃÈèêêÊ`æìèÄr0c°³¦þ@ÕÜœÈÁ þí´þUbg[pcœÀ‰üåàwƒ²ÆàZÿJ üK)',/-!®¢J®ýï‚ÓÿÝy'7§¿rQ“ÿoêß-¬Žõë·/p“-¬ÀÁþØ€;fêô¯¬ÁqúMØúo.G ìè¿§Çh fíÈø?KgB/¡ ¯J/+-*.¯"þKÃNÎf¿mÿ¯ ÿ­t憎Q–UT”ØZØ‚§ÎÐÖÌÏÉÐÉÙ@ò— üšü]t @ÔÙÁáwjrÿ«røWvÿÛ8]kOoC×ÿ\C[gGôûß[i x G'Ç¿=ÿ§ÒÖ`¸·¶ÿÿ½ûmðÛ¥°˜,x¯²3XÀ&ð.·5ÙØ€‰;"þž 1 p‡œ@îŒÿeë[Ù‚\m=ÿ›ÆÔÂÖäw•&ÎvŒj¶öÎ@i±ÿY!þ‘™L =x+›3þù×Fø-fþ-WÃÛÓd05´vz[˜Á¿= ]À#êà ôöü§âß"3'ÀÄÂØ ¼íÁ' â_Þ¥mMAî¿Å`&ÿ«úŸ¤úë4£e& [kwðК"2ʃœÀ£Bõÿúaô¬%œ­­åÁ¨þÏöüçJC k÷ÿsí,ÓþNžê¿8°p”°pš(Z8›ÿݧ¿åÒN†àM&lkf ÷ø/‘ÚïƒÇ¼Àç½Åïë@ÏÌôŸ:ð [Ùì«€àòýgp+30ª)I‰ŠˆÒþ—!ük¡¸­1ÈÄÂÖ <áCCwD&ðd±°³<™Á{Åèö×èlAN`€³“÷ïÆ"þv£ðoÑ߈À(òqEÿ .£ØÄ `ÿâd0JüAÌFÉ?ˆÀ(õ±¥ÿ pô8ºìŽ.÷£ËÿAàè ÿB\àèŠ8ºÒŽ®ü£«üAlFÕ?ÌEísQÿƒÀ\4þ 0Í?ÌEë_ˆ¼Òð¯4úƒÀÌŒÀ“nt²š:ý‘³þKþ÷þû—ìÚø_ˆìÌd ©ÿ•üž,F“@pàŸõà€ÿæ™ \ Ó?ìßÔâëoèòÇ3+Ø¿©õŸ¿ÍAÎÿp61ûWÔü_ \Qsw;sà?ƒeÿ€àrYý‚S´þó³ù™Álþ¸b›Ú‚7Ó?ôàôA¢ƒAÿ¦³·ûS·ÿÙÀîìAà ÆÈúߺÃÌÆõGóïýafçûj0ƒ“süCð7ºü#{vðrG ·€[ôÇ;˜¿“¹ð-gìä ú‡˜¥óŸùGøë¥ãh røg¦`Æ.ÿ€àJ¸þ£ë`§ÿàÀŽêþ®’ÇŸ"‚=yþfðï'”âï{ÿ¯»ŒéÏ‘õ?¼¿°Š“È ¨aa~*ÿc‰œ!xÊÝt˜À3Xþùßozÿ€üÏúk›'=;x{Ò³²1ÿžPößçòþ7[ã¿ß&]‚à³õñïWt#.Ì‚Œy,ë‹}Äs'J`ɹŽÊ°4eb`R&ZñqŲ6I€‚y~¾©y Y)=Ÿx?ÛMò,ë—Õ¦¸òñ+%¡-C9üwâÂ#™ê j_Råæ}KÚI¨÷e2s´ Ù~¦6Ç4ÔFD¹[;î#XÆ^Ñ.HtKš—³a]ó§™0¬ÑÝæQß·áÏO´A:½ÞcF…v /ÐL}Ê Ä‘³ëêÀØÉhÞØÕ 2fÂhOåÿŒl* ™É¨ð¦—#”ÈÁEç©å˜Š?tCÌÔD¥›‘ÿË·òæ™ÀÃíã±0>áocÜ“™¯c'SÖWMö~ä2VÌË·×SU¯š$&Îü0A_´ýü%™™ÞY?‘àÇq’Th•D¡²¿ÆÆ\ã&ŽF6àIs}Öut‘êO‡:¯3‰HV8½—¢¨ã(\¹$ä¼oÐ~ûqls£$4uN™O¥*^AaïPYðã¿`¨å‹ü—7¦î-Åë3A£aC¸qo̓nØ ™â6_®ò*¿À°É¡¬„¼ê:RE‹º Ó„#í¶XT`acq™ìð/×±¾':Íÿïü¤Ç"x¯x±EKP›e?Óð¯‡d9І‰“·¿>BÐÖsC<ä´¨¡9Üê/™º•Ó[´£% ª^ƧpÈÇ©VbV¬+ì*¿œ | Çè¨ïð:Dè’®QÊ®=ã]¼P4fynô*”ẩ.£QæôÛj™Ÿ'øù­]FEj–êOnEó÷mKòœ%[ιÔ(„ÚlPx¾úZ½SPÚ­²'¦%?ÜyOȯ¨øâëßðºÛ¾ÀC–dÔ8îÊ"ùîl÷ûË Wk“QudÍ¥zJE>ò‹j$böϬ¶·•Wl¥“èoû’Aÿ>'¼+;„Jp*y"[K'c-™Qé1›\±zï\†to™倢$Á£åa©_ZS Dϸœf`‹åXÐn”yTK–dN!0Ìß5»ÔCzq‰ƒaT£FtË~d–Ñåç †}H~½'+ëŸ½Ž½fšÔím²ëu¡Ìèãɪ ûðæ*©?¢­íI2+$òIÌd_fdë—å£M:­k¦eu¤"UR æ#y"yЋÕ&7êî¹ß„Ô×—t‘wËæPÝøj†K]U©bÌ›}&nÉG"Ã'l "ß•­ ¬‚hÞÏ_qÝPIëÀ>±ÞqFy×6^ˆÄ§$…ó ”C¿åµØ!{@òË5û86“ú/D—q ˆõ£­„‹ŸÇ¹öaZ¦cµPM'Qªèg¼dmž o‹û?o¹íAt<Üèb'ª))ËCQIËl#™æ ¬f¬A…CàY“k~qé{Ø$©®’òñJ¦Tö)ãâ~³×ÌKØI‘²œj!÷’}!ÿá+nž›œ‘üZbñ7*ˆ|©ØoIt±*"vqZba!|Ãøʪ íi+û}ÉÝ¢ ê~´:$3ñ2uŒº.%(d(¹pªH¹¥n"Uw¢âNEe·ò¦äØ­¼sû`MÌC£tª»íﯯ9ª‘¢r ¬Õ¢•?näŽW*a{|k¯¦¾qyƒòà¥ØŸáŠ„,ˆú}Ôé0\9xÃ|#<0.ëŸôñŽ-Pc·­­ƒ•e#½íÐùܬ.øÓ›ó cYN¸¾8¶LÂø3™Á%‡A.ÏÁýÒ¤…à¨ÞÏ™Y|ÖÒ2 :—&é&›&G¡zûqY:ÈÁÏ^¸³ bYìüÌÔ‚Äó\i¿~Ì•×XÒÔ]áW  ìÊ8ØÇ•g<íë ´~ìÞföÿ,ËD”ﺞÇòŠÅý'¥›àYküÉÍP-zÉËçÅIˆl¼_»’Ê8Ž vÞ=1»~UõÊ‘~8AC²îtbÅ›e%,=Î4ßU€¼ÿ2¾;™Ù%½Û‚ºò€Ð”(§ñ¶”ß(„æ¢ãd¼Ìãyø¯vØÙ9$6»þq¼í Õ&±m²à…NXØen\Ðâ ¨#ÒóÊémÔÉQ½:®yAD¦sý6yC“¨n¨‹.¿K‡e¬¤Œê`VïÒ8C }û&µ˜)-MÔësœU,Í»3øÙõ‡_¡G&sÎxAx[sæ¤èeôÌ„îkö0ÜÏWWií²^…9lØ_å=ȧ/’T)ónÆð3¨nc•gפ ÄÈ âSŒ†Çµ®8?Ûœ´g6¿eÇC*èH|Æ(¦Q‹°€ª^F_ì9p5HœÒ1ú¸.´]ŽA±GLêƒJ%.”/o%©$½Cg†µå)½l“æ@ÕôÜ«Õ#Bw·—UÐ}ȲЩU§Ö2(Ö˜ÍV´V`Ó•jG„ð[1¢xЫk”)V´ =¾ÊHàœ™G²DOó®¿ž$ü>"´P‹§e{G¹PÖÇb‡#›¡_å‡>B0¨—¡(ÈüGãäoo3­b²{yê‚.ˆc"”2=UH=¬Î¢-m^¹v½‡ðtQvò ¦(@Úæ>¯2£+ÛÏþBR[Y¶Þí9ÅcߌMÎ{|6Òq”ÒƒÝÕ1×ÕeS¶Ÿ¥Ÿ¯˜‰rÐYC0äb04Jà¹õž!×`¦{ìּɮ 0 ÅHsT‰õe° ×±»)*ލÓw²r–¶ï lô3`Á„?fÌ(õÍšíüE§9ªôfr ©ÓíGF_fvæs,ígºå»WYÒ‹G2d‚Ûcãwþ0ԘŎÑ.›nÇé,ÂÏKÛ-#v™ðªDË4 Rœ¢ƒ:;Êø‘lÍQÍØÔ±óJ ¯¡3P“ ‰ô>ÄÚûúÌÀÈp~‚õØ1Øë „r®;ªš'8jl-·»ª¾QŽ˜ÞäÊß À&ÏD:_GPTmbé·¯ rFEv?",ñT‘\ÜÃU~q:›pû°¬]aŒï‘#%_¬V[èW>æ˜u|ï•F°5ŠXéîõ¬4Õ¸#þ*d{Ȫ ­èCgÓS¥&»êÐQ`£èïß`xƒÁý£MrhxXŸž}‹×]a^–RF.Bôð;t…È¿Ó.l:ïÝôOç\IÕÝ­=Ýló­D/YGΤˆtèa&c}Ál·Ll‚Ç0í'ª¶TŸm–+ƒIÞ6¹@ f”à`Luün!Ÿœõ5 ‹¤þD‡f1)uNØ‚ŠyF‡3‡Îün«tˆ˜`íIÍë¹S\b!y^°±Õ_÷§£áN„{­uJBWl™Tîx^w]á›Hƒ¤{âÑ-WŠwg–,øÖç 'Φ1J÷›¢‰EoúnFîø-÷Ò’À±oñ5ØêuÓ­% ~cë,tÉ“[ù~½®oþz/ Ë þ,'ã ÿÙÇØ?ŠÎY’ìËü‘»ùUÝQÔò]‹½ÛΕWÛæ-I[î&ßçÝ%¨eÓ÷Ão3óáØ¯D&><,[§:ÓxÜæ74» Jš89Îb2ësåÄsG:M¬½l}ßàÞðrk¤u-È̤šäË¿ÈBþ:,¿fŠç{$>d¥ab׳)æÿ&§«9Ó_¤ _­õt»a‚uE.Ω’g£"ÇÁà"C»ˆbO&bËD¿,´ãЖ~ŸqœRZø®BÇÇ×ã«Â =‘fo:Š)m5¿+ÌôF˜ù+ï¼K~ªRDÓ¡2ßsäÁ®!!+ãä»ÛeÖi«û t7¦X8þWÑ6¹!ó•¦K¯þúšx“)ÿQ —à×w§_ub}·˜ºDæþëFÄ 㣫ä{éØ(Ô@åBy2½û ¼8õVs㿦‰>kœéžrõ’¿/¢ø•=å¤+“ZHü`£óvX;Õ4’ò¼Ò$5í8õç%f­–.nCNç)‘6kc»Æehc—}ôŸÑÛ#˜)æ=v³g§jßÐpûa´\I Îk¯Mf$s2nzÈê*9Ø/ë2bDè`4V(ŸP¾–E{ÉNo[¥Ù”QNøEÅ]¦Q€¾(M+C©ÂŽMõ›2jé<k’Ç8~ðUYË%I1 „eÊîæØÛîH#ZCÑíÝ"g’ù¢ËãŸÚî”ØBqÞûf0EÁ”ýeO!›'qÒÚf“‹‹§/!i=ÐàrqN«›K¨“úsW[fÓϺИսŸ^_>-dÙ¤ˆ%Ïw÷Ú°BÑ­hÐѰ÷8ÆZxÜÔžWÎ^‘¨]²–ºÙyB¶¶45j—´ÐU+ÄkáÖ0Ûú L µºrÎß+(~.…µ%›¦ù÷ ¾ˆ´½ö¹5Fú”µðóc*­g‹Xm¼åëWô¹ø]‘Õä7=Ï.y8§_·úX­LìßX{o Ûg‚ÄbGû¬x.ü¹ŒÀ¬=iKª›XÅdPŸ~§nk+ÀL)5a7ttÂáž?$Þ¢=%ŸQ`cB÷Z;ý¸Ó²oI{¶c!L„åÌÁ±’$ø*? ß+}v+ê"hòSnõì'Tx‘Ρ˜j;èS ¥zpÓƒvˆ,'W²,’g)"¾»Ç§ÍwoZÖ}Ôm¥‘ÙŸßç:Vä ²UÌ¢2ã‹÷Èo C¦ˆæ˜'VÓÛÄeK§äžr¿•ú­p…K¨ GÆÔ hÅq&vË2»ŒÑ„À|KP¡`o WÄÍV¸oH™]r‰ÿ¼¿ß…ÃèuÅ99%»×X!ñ¡6½áMŠžÌÆär×X¥Q¦níúôHàÞÅDlMÓíš5úfŒ`+Áø"È ã5¿¾m·ÕäMñ Ù#6”çakd‰½CчYf[ô`Ð/ ‹tò ¸Á¶ 7Åw7§•ñÊå^[mçÀJ­ ”„ŒúÆ çÃ!¸4êÊÐd*!G'1¢—‘ìX9– -±¨éz‹Vྴ:̺lÍŠìõ†Ö—Žzü•[½&òëÐ÷P/­’ïgû—øfÛ;šµø¶¤Â1Qµçã©[›1¾ÞIÐ#/Èj¤:Cë¯}n/6Å +Õ¯ƒØxêKÙj¼?z÷Øû›õÑúƒ˜^†­ˆÓY”n´9^bÏÉ8†Ã¨{P/p4‹ÙQí‡_åâȳÂÄœ0”#î´fœT”–‡­ Ä’ˆ7çŒÇ†ÌFœšÁ½f¼Ü¥Kœ?›âÚÌZqÈßíÓÙV)ÒÇÉÕ7CéOë91I~L8CèÎØ¥t7 {ì¦8å¢Rù¨ÿå|ć¯мáWOmø*û±³ñÀid¿««§i"¬1¹öG/égìùGb׋³à™aHoiÉ;E|8 {EÄ ¦öÑ,æ0!»egÈÕôzärzµÓ\8jx?œ ßY–aÆ/<:؈¤š‰ÛÞ™w8MÀF¢ÜËÙGR.¾|d -û Ÿ@z_–¬³ˆïð¬žæÈÈ—ÛbHœk'wð´e¤Ýâ¿,üî…¬l ±LKx줊ߎ¥ßã\}ÕÙ‹xu Ò ªéÑ6`“ÓI•¨š9}UÐÿÎ L ‹ÿq8¬³×l¡e)Éœs<…l…m¸ ·ÉôÐ-†:q8XÎ^Ê…4rîÁ5[äD6kƒ0¼Îjí—žå7eöˆéй·§›ú.}ÕŒŽvDR–¸ã+ v˪99Vnš4¬×,RXde›ÝÝyT-lØÀ¾6>34õç®W²/è¬oÄqŠp8äX©#æwÿ8¸yùŒA#Ñhz5 eÅÏe6²]/”. =Îfˆ¾Jé:3ÀªíjÛÅC~Öhð.çQCqRÑB?W §ÄŒÁ&kNä`#HÓÐËî[`˜ü©³¯±ñÄÿËqž_tv²÷»¥ŸÍ^_÷EyC—‰›™d:šã=tEðàܳš¥*Ù •JX™¸JVºßÇl¦[ZzÉ~á AÇô‘EEf|§³ð(è¯[Y"ô£ðKPÄT—÷B,[Ý}¢6±³MÉøOâU†Ì8‚ÇÛ°ÔçJNk2ûp>½;®äfô@)cŽuÈÓÍF'¯‚ñè·,dÔŸ ‘s°¼¬¸Å¯CB˜ÞìÚããqÇsR›ÁLã9^MwÕ!D1„#ºîÞu#o¬DVd\›— ulܺ]mñ‘ÉE¸W¹v²8’‘•WÒ ¦ôC½Á 9¦û¶„Hì¿Ð2ÿ*‚D˵\VGÖÞ}óV­„·Í‡OÏÝ7hÍCúhs.…–iz”Ü*àIL‘ª‡s¡"¸ò×Bi]¶Œþùdï°"©hÆèa–i fk« å“xÇLÉÇ›þL2‰G+”Šx^Hu߇ŇŠƱ/hÔ_Ý/' ÃY3¨®e«é…,ЄFIœù+(¿fD CÛy™×æ]\T§Écb3d×-â$¨¯[X–époEU®ã^D™¹1hŒÈšzýSvƒžÉ¥¼m#£Fïº=ƒ¿Á\ô/ŠÊ Ž.}:ý,]Þ ]†›wÊv$5qL:qô™šË^†a*ÓË =i.òîY–W’ö3ÀŽßIQ E?²û@£ÖÍc¿A'ª^_¼‰‘ˆ]ÔØºIeW]Tm˜‡RV2M2øéYâgš›2æyiÞ„ÇÖ Bj°î/n`(Üq‰ÓWeÍê›øùh*ê{϶ùÄÞõ ¼®ö‡4l»Æ|ó›è˜”Ö”Y¼J/f1|ü&¸°ý—D |£E9Í\Ó 0–‚JªV5§e£Ù/£1 †¹à€¸Ž°B|émeý1µëÎÕ@<1-‡`Ê`€5…P˜³˜6DòÜŽÇ0IÕVÐ%Çu8ÕE‹Ò:ƒ:a»…ÿCêªÒAé*—òxh—až¯V–/ÎåÚ^!¯Ä>FS:`ðÈæuÓDUóÖ׿ĩüaJ$0Ú_¶©[Ä6âD4½uïk]RÛ£r»½¿4`äzÛ‘C˜Ô ù‘e¹èí2Åx,ßóÝð]ÓàcJ·WcàË ZytÌ4ògæÛ&<Ò3%Âì'áæ5³åa²L'\³Îg¢NÉÓ©|¸¯ Ã!P[Ú¼XF¥ ™é-œ¿èºˆ)P ‰­pœ¦`ª“m<”#& ¸KÔ>²¥šð¾…†|Ø¢V\÷ðo2Në- öˆüüá¾!˽hµ9MüUP¦€O'ì ={­X¦Fs%;øäC® ÖŒQjŸðœ¡­ÍË~2 þÑìC…ô)ž(aôœö6pOc6Vã-…’h$_:¿ÞõíèŒá²G+W”8·ˆw?îùâw¬RòìéqÇ'Xrñ^$BÒf>@±¼[n>Üêm„0B«·A)ơŠvWÂu%n}h4Á'ºã7«!§¥«Û ôªß=Óžš4ë=ôe,¦œèMœ·n£;—«Ç·ó2Z‘ &Nr^¸Ôd²L $×Á¬`C=Žèa,}]>ùPH}€Ê0»§k+ߎ<¢v4UÃlŸx³ 1{ô¡]ò×k„ñú‹¿ 6ëá„dÔöĤ€Iþº-W›Y?+ŸÁ8-¦]¯ãYdzx—£ƒóáp~j6„^‹XDýOíŽ=¦hvzg«.î¼ ˜‹êE‚C•ZqÈ¥ê¾9¶pŒŸb7)ªòŒ//–%VdÝ$qR;Kƒ§!r†¨–®WÛ„Iuãùºõ)’Þ™ ³ƒZá—­‘”2FïM¶ìïKæ6)¾·\g´tÉϵÚÏZ `w˜qc¼/ûæïm»l9®»JBG>7wŠ÷³žÿæ,Ÿ¥µ‚©žÚ*AV=»å'FZ½Q*‰À)Rø$¼æÎ#ãR^Ûá€=Ñ4!o4­Jù1‡ÕŒkÒY^rdâîÄè\¡¶6Í›X²¢U:™[Ë!úIÇ.†ìÁ4Öí8 ì¯ÅôœôòS÷Kn6>ŽÎ'9b÷úyÜi²ËãRÎéV*x Ù®˜›u*ø$\îÂdl7_\šÇ¤\}-¾o¸.»í štÕ¼c¶òdM™* SX»Ï{-«·Õ«M‚!‰túNKo©wtý£oHÌÙæFéývŒz3—wÈ– ÷v*ÍcÏfQ=ßVûƸsBï¤9¸Ï~LÃY§¯· ÖFˆ3^¬ÔV‘Uš•ýVã ;ÒgÑTüü³êãdìwö»¥p ¸øð´ŸJ¨»:W@¶£‡7çØ%|½Õb èSÉàð¯„ÇûpÄÌØ¤b•ßɵc^=Än`‡½¨_°'(f}âlž×—FÓÐ÷øÙÛI‰¿˜+Ò9÷`f¹~×îšk; jI˜>ª¦HlÙ·~àõ%½¿ò0Ù?£ ]OvãÊR½ÈE}¾¢¾·y;&|Òu@} vù¸x-o›°ï 8¡°%> vz‡º ÔÞúo·|Fˆ*¿£z@3ï¢;‹+‰­åâ0÷hŽë2ñŒü©3ïè´¢M(ú ­.X±4SeSËòVFƒ|É»jXÉœÂ>‚™½è4øï{|Õ1©Rʹî{Ìj‰nì@+=ß„y12Àº!–kƒÂ5»íc1*TóI….®óÒ/:Ò*;Á¢¯ƒrŽè¾9Án6O.å+úâ³¼yЇ-/_a'%IÝØîg!8bL±ü‹ùäÚÉñ®;È ¸ÀZt¼MÈç“ÒÖ¸w•n4ü >éi\µjqåæ'âû$O†]‹K< 3zÒ+«†D 6ôßc»ÛËún+[ÔðÂu¡òÅkÖ"3Zø5»²±jR]NݽFdVÍú}]+®›â,Ì"µp)QÜ«Sø3·åÃÞ—_’º):mž‘ŽS¨:AÒäÀv¸nØàCðM¥Ðœ¥*™9BÌ'žŠ÷‰hÒ‚Ôï¢ô÷VÒáUük¶~ô%ïuÐíÒ↓©zšçõHdKé½Z›U6Eµ­Ù/q},§b* FúÊ?‘Q+RQTtqÎF)šlß(ú¢¹Ù?'ÿµòÚ %éUjV=½¯Ë´¼K»„‘¼u9ö>ü5“_ÓA'á±æo%%^tÀ¥·Ø‚MèË#CëÛ•CÈoª:£Œ…ÖËį{ÄrWž=ª’‰wЧ6Å¥Cttý‹ƒ8'•ýÛ²p;Ú¶îW…WwÂä_?&÷î©7âØˆ½/Æ<#2–'ÎÛMñŠŠ6êÎNãÁêH²P%N#w…”ÝÖ=ÉÓaìÛX&oZ~€†ƒÒÒc'¶ˆ@Íï„%F:šj@ çK{Óöè“Åå(¿‘W?Áÿ"ᚬ£&¹©*ó ï„Z=ì̈Ïå Œûöм„áU·¨éÛ' [DÜüK×Ì´¶íU§?/ÄåKÍÐQºÿ„ØÜëÊ'µžãŒ°Ž¨Ñ—ðNy”eU®fBï_©bÔbÖ~5BvãöùÏLp2ÈI!Ë{$3aR§“_û•6e~ ~~v½d³2.“aþpLÙ¦’éf:WÓÈ‚€õ"2ä³BÑ´ü«Û¾G` YUßgšÚöŒuV>qÕ™›µÄÿòóô´Ðh¾,2¥ õ cçòÞ^9‹šJÆÍ ÆÊÔç]—Ÿà~­|Ê2@ßê 4êébWyOwOØŸ®Kïh\Ÿ‹ºÎ©ÁÛ$‘>-¬Ô%áè½G2=R;1ùú„+Ÿ>uÅxp¦úºá € ·Á -7î:¡S݃ŸëêŒÖvAxV@ãŒ>³ s…Ù9òK|݇"›Ÿ'2ÉK¿™ Ö³]}¦±/±pù®–DXRÌ5uvYÑgcÁ¬E9Ì›=G»1Îñ}-í)¹]Ï‘þbƒLç2æg(ý‹ù$ä÷öocãsP#0¢«ã½î Ø?IT·|¤SÈSE¨;€  €šwçjпDz\ýÌ[ý˜­µr&°¬A‘ƒ¼©c-n¤ÅUºÇø†wwý;ÞgÂÓí•u–’\Hï­¡—DåRŽ,ûß™vÞiåºçûYNâ0¯S'4_ê‡f©! ôXXÎóe+&­ñP „Wb\䯪¯#¤¿C°Zá/âš²Ú©•®Ïx÷ÈDƒh˜ÁvÍCKáµÂ‚NÐÂÎeÖBâ<_‚V£Çí:Û/+v%#õ5ߢhI…R,¸klïí^ô7w†XÜê†|÷8i)áùÚ·ÊÊMÚ²Z<y‡#âÍ>)fç†øA:¡ûz²“÷¸Cfr‹¹/+Lf¡œýºA?ºpÍè, ˜O<äv¢§æ¬0obIÎc§7äbR7(C§"„œøÎ]Šû LƲ<Œv×_ (vkÙÃ"á^ËŸ¾Tn|S,ú(§FþIP:à´ÃékL¢?.v<¹¤ô„|+ Ü ÓÔ-f®€ðÂÉü‚Zµû+æÂûtÕö&-¬Oõ{‰;Á0ð'¡Ký‡Õ’s5(¥ .ÍL¢ç\ܽ#þ%òø†P]mfqž?Qhs–ihë5ieéÎËƽx´ü 7DCÞ¨0˜w(Ø«S1±•¸6©Í£’ôÞ+LÎðõvpŒ¯…`;;[³ÀåTè¬êù›eUð€½[P!µÇÆäVÄ 9ú/Vz…(ûp§âÖMÇ^Æm¼£ŒhœŒ¥ÿ½œŸìrÉ ÓŠ -© dZxë)g…á¤nþÝî³Gφy)€ºÔÈ G¤éí¦n²r.÷OÖSü=däL•""cò¤ gBÒ~ÕËŒá})‰²¤üùPþ’q³•ubwØc´5¶LU,?IÚrÿæ—¡"¦’B¨v”VzÍ-ý.6x2’ ^¦àÝÚ…/ir{'¥ÎÜhôÃÙĬuõžïÞìº &x\7ÞX†¥æ·sBD?ÁeK§èú, ø!?\‚Zܲñ>£Òµ z6‹rh7÷êmËÂŒ—L±>ßÉ£°æ»OØÎfÔÑÁ µAË£í4â°—2íèëÛÞ¨êÍÕö‡ ºKȘlAáIó’Øìô67÷fû4Ñù@Ýbazy·Žb1[rûªŒqèŸÏÏÐi‚mxfω­¾Ì`u.´~±}Z"%E Wƒ³t82Wàöª¼Â™íE/:ûžºAôhÌÓ®30…4+´»éÈÑP\[ALž‘`0Ús½ùƒã0&w;Mw QXn~¥6à†¼½Î‡JHR>†Ö·66«Ò{e!o*c°^¯ùžì#¦…¿;uS»tÎhÍΘ&Më8ºø\ÞB¹çmähd’þ%¿'ß»ÿ=Æ3ý ЇÊâÃmôaòµ'.òÇ,÷{æ2šÞ•‰·w,h§ ´}Õãªz¥ӄƪ‘¥» y/+•Äu$õ‡,2’oJO5š\H3¤´Dòu­ÀÆ]Sï½j|äTgQWü&Ù\éVš»LͲ?±ùí* Æ5¼xRdÒájñÈsÛ¾“ÙºyròK õà³ ê†Ò‡X…B+¾ ™ÎþJ—¬5væ.ºÕéŸ,z ’žI ¼ ,€Qbg"†É¨Ž?>|ˆ¢]»byèýz2V‰Ë~ªI˜¹ŽPŠÝ´og^ aEfEòéé-sÚÐùžƒËé†ÑÖG®ÊÄ y  c…K©¯W¹ƒ"m°1N¸Þé.q„ñi/)<²u²,}>¢HŸötìj|NC‹TƒW÷L+•PÆrz½»¹¡„SÓ¿) ž·¡ò“èݧ™©*Ón-âù•rÖ$Z‡:T¢oÓ33Ü]hA«nmÄê˜äõ.3“a]õABQðŒ¹1&l°¢Ú]ä^gKAåb"¨5uàGeAtS¥»µ™î§£$usµ{ûÙñ§øÚÖ¶·ç]zf¦éÓ8,òýEÚÉÜ&ïî8ЃJKBÔ?pÆJšle¹iÚ_*žâ„®Ôxg‘MÓߥEÈ9Ê ¡Fýl¯ûNù½‚ùEÆìîFO#ÅëdÿµæP+û§ufŒ5ZÕSv—}C•ÿñ]:D²Y»w§õöp® spœæ@.ïMäîÎæè–*UÙ|ya ”2tIÝ·é¼Öã\† zúÀ¨ØFñÔ‘Œ³Œ¹:ÚØïH£Ö>ˆÐħ£ÎF憃–iHY»Èqy‰ûC ª¢ ÈÆG„{Ë_$ºÑÖ ÌC*ºaác“w" Oªm ¸ýƒ«rOÅ÷Ï){_V"ç>SŽê š©ˆ9Ÿã.Ê\ZÙªªò c~U5äòûq×]­‚#u´õ€­rTÓ"¸üPÝôÖ…ÌUõM6Y&³óŽ–ÉrÇ÷è÷á|€ÔÓE„Ûø¾™7µ°ýmð£>û›I„ÉdßN0"6zµý<·RßGe]^z °ì»»]T†»ú4þj%Wé[m_Qo†°ÛzI!™û&ß–œÆÃ¼Hêú¤s|¯ì¾ñðwš¹à}=«ú¦<ä¯d6u kÊô×TîôªÊÅùvjP×ú²ãö$†…€0yйrÜ…ÇJ³o6|9ìêÛq¨Õñi’Å*õÒ5Ç‘ÂUv\çË6ÒB&kabP+Hé ¾›Äˆçü›†A3[«X×P…e¯Ýݼ»t̸<Ȇ…úªÍÀ']àpÍf–ÇA_„ìÒÞFÑÛ¦¦y“–‰»DqGYÑð§ü (Ëfu¨´ÿ†䩚̘þüåmz²§ÜéÙ‹ˆW1L€=}&ׇÕéÏÓÀ-|Óù®¹½Å_™ ½ ®½\Ìлi0¯q}°©e¨qžÙÖCØýVï¡z`Ü®uålŠŒêP¢“ÝCƤ郥Ÿ<.ÆÞ¯ËYdXS~WôJ'_ȹWLÈbŒs—èµ´)„ò>cPm ÂOH.5¯Q½M w9@* }8ˆáÙÐ0Òþoo.ÁÃA®{ V¶‰Ï'ëZBñöŒ%ÏgÙ|ÖþB¶/«4t?aè¢ËS’JKÄl;#Ÿ,ä …?T‚ZÙÐuõÅ‹p¯ÞCøŽü²ˆ—|š†©ÁõF9Ž«kÇÐ¥ìífîøUsCžˆ¿õz“l’¼9®É_è:ËÄ»[éËÜñ|×(¾¹)€íûÎ_‘›¤á-2£]‚jŸ¶–•·¶ÂKÊݯþ• .Â;®K². I„¬ÃTZÍ8ßÙP·3¬½dF~"lŸGܨ2¡)äàÖä¼®—LM^Ö[ök¤¯åî P6–µñbµàë¯-hoauæ}i~  ÄËÌM°9ÑWê¿o»ãÒÊzåóÉPgãšôrÒÌŠ ;ÕLJŽ@ì;ʨ¸â—<"ã$ ,^c5†ûgF?‚‘3|„¢š‹Òêo;¢?É-’,ˆ ¢ôLXKó>ÃeËûô ýêvú,¤ÄÏãè?wçz^«—Røv)_wê¶½W ‡»s¸݇ þ#‘êÇÙD„azƒNóWªÂ,âÍC¬Úd%×öÇoÐàì¤^0Z3BîÑŸì¿¡»~á$à— ¨{‡߇ó¤ÞÁ”¹š=OT4q^¡¥Ø¡ñ9[*N+Þ[´9\'!2÷‡_¢ ±PYÿƒà'ý“#b©ÑecNMw»˜Tâž#aÎ#Fá#8J;7÷¤CšÖ>DȵÔ £Sœ±K_KnLäx[›‚ø_7iâëí¶rSJ[Ï–E-Š©Š_Å´M«™cµªÄï.é×ö¢†÷ý;);1mùŠ@|G(–#÷‡„oHBÚi­dÖÇ„{÷ð¤ïÏÆ(Z•TLÝó]m±kwÌ$Õ&ÆEžÙàõwšJaŽiè©l@G«¹]~´•DKúÁŽÖļ¦Y£ {‰Mƒâ´M±jò²DlTÍ[6?¤ˆ¹-äöÈ`èÒáÿ/øÀ3IÍ+;ø–„¡¶š+rUÇÀé~U¤–™âEs^EÚ„¾'Åý´_5ÏÓ ©k•õ6ŸÁ¾ñYÎTƒl,±nIåþë¦ýJòÖ%”/m:=š§nÉ í¢üö'Çz¿¹'çÔvhô…ŒñïTo¶å@W¾@· l(IÑ3 öåÑ£ìNÆç˜Þ§®oéL¥Ök|X{dú¶<8“ ¤Æ>Ä—å‰î^^Wˆæ “Í®ä{¼ÇIùÆ2.½mSÁôþúŠT‘é~P §6±óø—ÎÍ4#\¾¡al¥Ä{QMþ~tÚ‘°Ö“d‚Æ\ ˜ŽŒ{w{GÝ {€D]ÿ8Šõ¡¸˜ÛϽõ@ÓvÊÄémÛ¤¸Ë>yÄš°è2ð†BïTï5…¥+»—}l>xD Â"1rpùœvñÇ[ër[”9g2•{As&r·j#gœäXc·ÖïÇ‚èÞ}’]XY&ædw·š•v/ç½á5jxWÿa`ª²a–=F"x¬‘åõ£±ubÔú¤Ë\EÕ¹§óõ%Ê5Ëíš²Iì4Ѿ¼dœ3ÜOš•ÁÚ’ý ÀÛü[”ÏLSö¤ÃïÎUÒe •—I(SÛÞúO‹ñŸ0dÌ{Ô›§fG?¼¯hÏa$ýT(TÌ‚çl(å8ɪØnðÉóïMöÄ.8bÄ?:imÑg`†c}T&0ýŽ[‘ZŸ2Žš¥õýd±(MC‰`âŒKÑ*¦2ŒÎzް`ÇH†c5ÒÈ[ Y ZÓ}]ØœÌÝÂÍ8ˆ-¼Á:$ÙúCPzŠC7@ ðôi_ò&o™E2DÇoÍQ—˜·åø±GÒdc(‡wâÓ‰YÛ´ènni@Å„»ßÀ4œàubzÉgþÈê0Òë;Û×~òÄš'4UwU£óâU˜Oꈷ¼Bþ˜o=¾­§_˜&±VÁ”8ÂQ…%ìîym†hç!ÙjåÁ7ûîØÑ•£ùJ]Ê¢¡Ñ„z‚J^Æe¾¥N¨Ôp…ë4¨ÕA ªYÂ)¯<Är7S›·ýÎcú–ÆsšEq¥U;×-žc}‹K¸ìPÌ·D= ÛL®ám‹åybDÜ–…Ñ‚d¤˜u_ߥRÑó3ìDR¿@ù\8lÔñQ Ÿ{vl9€ÅÎnrê(Ç•iðgÓÒÜ®Tœ#Ý…æ¹>+³ÇpÉô—6S]£þ¹¶FU¶¬Ä½'€½b2ÆÃ̳ÑnnزÚÒë1²øÃÑMô„›ï÷ƒV?ºÁìaÔgj o!ñâ¶jŠ3ØÞÖf°ÀÑBR¹Ì¦ä¶Ehö»ÓN ‘ÊðäñjK>F… çΪC~et¯|tµt|W?íºû¡½z€w †EÊ.’JS*y>û*/$ jÃøþPò1&L7æ Ke R’I–ælËj¬}û8 _qŒ‚>QëáZ'¢ר®ûÎxaÇ3@éVXÙzÙ8“Ê ßÊ>‡Oɇž]"csJJìª+¿žš÷øÔ|TJš›€(Ý?§>ò,‡æ}ÄÙ%dÀ°åÁ©!Ÿ³eA  †JþQs7)JÙmžæNðE©¿¿¸wKä}>öc‡˜§„uypíÒñbÕð€šâXÕìþÎÄ=žÀ!4f(ãp~²'Çù·1q'¶ôÚàÞÏ> â÷…JŸ>VÅóœ3ÿ²ºÆ|ᯗ’¬_v¤xc’ÿ^¨Ö vvU?ÔþmºøE}öÖádÃï}Àþe¥3ÙLy­™Vºëœƒ÷@ú+\%”›Zv×µð/'âñºÞúõTe`“²XŠÄ¨öF[ñ‰k¹€Ø”˜Ý—ת̛CÍ5lÀ'±+»×þ[»-^x*ݺ•ç{‰í©%"oƒšJÉÏËÃF²Ú$ GŽSm1gc)¶Æƒ«äŠ4cá¯2ï´Å®o2ueëo_;´6…± $zdøòqŽ& •i…ªâu®¹Aê‰l?|i]·t…œs"‹ :Ãdyî@æúÚ„P ½ñþ¶9JΛ"LJ.÷¦®=žÚDfüÎù,ÂèÔðg¹Ë ¾»îß~eŸïÎØsŸñ›¤KuMTgø%*Ó¯–r·M"þÚZùDÓÍæ_À¢Z×n¯39tcfµª5 °zóç^/1ª;À2Àöä6JÞ@¾³ëØÅîÏ·•Å$ñ=Ã-!ÁR{Ÿa¸¿a»~2È’rkÿ¼Ú=ï$| í ÐPÈIežùj½“¡–OE3Éè^%ƽW†E £ïäÆÒ‚¥lÍnˆÁ–û\Ϻ†ËI¯ÑÙwãõé}w«4æâµÚØÀçW0×ËÉŸsJ»£ÉÁH±sÀÜý·ŒjUôÔïZzjôb]È÷“m^˜rœ$CÈß"@’? :‰“‘ÎTЇ rpj¦6óVâ<Æî5=Ñv9^£ˆ1ŸÁ݃#ΧvY#–"> Ø6²,›_eùNr ·ï“¾õEAf[Êv˜ÍF ÒÖÄ¥ƒ‚•Aß»ÐíuÓŠÓ~‹‡×"/OÇB4¿àâbÊ€­œ‹ à(ì}9V°Ê¿2èì I³X'¨Þ]j¹@Æ)ýxMjútQ¡9ð†>ùgà¾~ÞDs¨p¡h§Æ‡€µâž!¤gܲwã’º¤7ôt¥DÌyH“q»20ÇÌ#¯Ÿ†¹²ü¡h–#W„¹ì‡Kц(èÕø½ªX‡H|+ßOœÂ‘ ¡%¼CgíóivË«‘Ù™U}þ¢­"¹ÇRÊi+X±ÒQ£ˆ„h>³æëi…"–˜ Úc*ø(Ar¥eGx"|Ñ ¢’Œ«öõîCÒ›Š˜£E¶ìŸÌƒÎmòitgØ“°C»*ÖV02êósLÏÌ›¤Ç{Ћœ#€ z ½<ßd”ðI©·L¦»·uaåUû˜Q²F{KQWÛ{´ˆ•â;]]7j'çgDwÃ7ö;WIѪÔýýÑ/€ï×39Ùqo¼9ƒ–jOÆW²d·&¶ŒU_oÑÄ0í$µó²gð] U“LÑóÉÄÜݵ/Gw7‚2ç ³û‘ oË!ÕžµSе§µû‹2£7Ø[VÉÆàú)a-J¦­–d0{c¾biÐI6..æÖT×Ê$µ¼s)mÙ2˜! ;hÂóP/)øá“ýÆ”ŒÇþ^Ùb"ØÆ»=~} ©>%ó™þ‚ÎÑ.?ø—@¡Ÿ[ánCë·ÇFÎI]*Üæ‘’‘yêЪ¤”\rP×Ôi×W@Od&ˆ²²D»Q h»MO1%áZƒ˜Á³ÛJ†õ@нâIñ.d¦E[`·ûjò5Þã\=²¨ ª²B{V<ü¥i—´où”šÓì 9$LNÓPWQÄŠ¨6ë“xPîJ¨ŸP¸ ©Ò¿y?osPÌÓÈ…’mïÁµü‹;-|lü–ØTîOå%e¡ëv.©eØ©°)8¡¨ï%‘µ_ìIU¢ŽëÊ:93 •Ù),cÝæ¥¯7Ìðá¬i”®ëÕÓ¡ <Ü—ÞòXPÚÙPÞKdÂ+¿7¾èY¯µ][ÒK-MÓ¡mF&wZèÇúí^&q$5†ðcÑú2³eK•‘ƒˆw¨=wüjÃÖq ÐVõ{)™YM÷ ¢L~ާÊï“b‹ºçå•|­0–Ãé-ÅËh¡Ç]E‘_2ž& Y º6Ì4‚M—K4•õUSÿ8—b~ ütø–æ‡Æ·Ä·4Rj˹Jµr}u,JÄê _–Ù}1®¤çÏ)~ÂP¨Â`‡Œ¹¾y* MRlP컓ü®¡Ò©4ùù|†‡Ž„ì"AÏr¨«Ê+wî0Eº¬¸$Iü» |¬ÄY*QØ^Š*qìÍPX×W%ù3( ÷íÓêÎ ®C俣ÿ/2¸?C®&usúšës“bÃÎAS¿(½Ö‰ˆ·° û=Job´_ ¤6*ÃÃJµ Èå7‚D¬{é¾,Bd„ðÔæˆòýZýºbQºêË]Î#†•Ñm·/õÖêT¾£˜Ã/kZ:Ô®*-¾4'^obD7Õ»µr¡Ž›j©‰Íò±(|LÇ›´¬fJ@o0öëdajñ×ÈšÅËÝ&’£S—i½šä¬ÝoÁü|O²/烣ÍU† P]ã+"Ö !¥ó("\_êäå4³lÔirÕ ß»ëtÐÑCæÌð×l™;û"¾«€3åÜ%?T¬_1aOAc&3`^3 Gvt–ëc¡?à§(»S÷V7¬9¡GÔ=këÆLåíGê?;´¸ÓK~ZkÍ<*§ä Bw—K·½Ýˆô‡„έT #Û ËÑp2ùH}lÕdG3Mÿn è?õ4£º†Ø÷t¤\erÅÓßRÄ"ÓQCó`žz”õæÝr*¨ß7\|$5x=PCÚÒ5¢,[阪óÔTh6û‰ò³ÄÎÊ{†Y)Ž6”âT¿–«ãLC6HøÐÿ¯msÚ@tè¶mÛ¶mÛ¶mÛ¶mÛ¶mÛÆÙÖäfÞæš6«iš8 ½Ë%D‰…QÔ³i?€¯v¤Ç&ZËé¹ô¯ }ŒdªY;4Çö–+ûпƪŸí–ñ5¼Ê ¿Ptÿ¡2…:ÓhªzŠ®n#1ľˆ/ø‹ò^Yj-ª‹ÂÂ4”¬}¼„ŸZÁ%~£ÒÄQgR«öýÂ…ëa:$ñDìËíò"i¥p>΄]ø %Ñ- WÉ…Û~1ñèAV-ĩ칸1L?ÖŠ¡LÛw’º—ç}Òúš í0= Lµ7Ë2`~>m#h&‰<õÁÑžúWæÚnx‡@ü‚Ûæ:N=ÄíÓFOG™j·F"ø½Õ檘`MÒ›£™¬jùcIC¦3èÛ8Aô·8T+«-ÔÀ‹éÄYbNåc6ä ˆ|4 Ss%c5_¥óŠFÎNIiùÈuúj%Ó­ž©³åì”w¥·ÖÏnóüa¸²¨7oS”™Ó¹T àü„];Øñ=ëÜ*øÊœ—žkh:%6©ƒÏßޮΚóÀ3qZÄ>¿§ÐU0˜G£Ì¼…_v¥Tû›Þioªƒíû=3Þ}Jh£$ÖFú"çq„N‚(¦M Jd¸þpÃDhbå%85á?_ ÏvÐñ<Üj ²½ãzüF™Ÿpº›U¢àõÞ¢óUÂÆ9ƒø"kÏSµeô»—Ù¬ƒ)‚Õ$ç(ê"Ï10IÃè£ÍÆCØ›JHx³‡Xn¾ª™:»ê—3¼¸¶v¬’ÆüöÜ£ÿ¸&½HÏ<¶åÎÛÐv3! ß“ÍÔ;WBÍÈ;+^’0›£ªNÅñÇÊÝòqßX È¢a·I{1äÇsÔ'¯2åf*ÓËRA¯â!‘sŽD"^.!oSÙ«‚Ó!’¬ÔÁÔI«’{BÝ i:©ä à͘\Œ"™åðœü÷Â:hH‹_Aa¯$S'L‰bR^Чõ3&êÈ£;EGëözy!PyJ=®ÎÇ$®Ü ô½9ØXZ7㊃ü8% %-{=~Õ{þ éÑ~4Ûáéá“Øt1œ™\ “#–v(H§ùžÊƒã\ÌŒ¿µá†f­ADñá,È÷cÝ‹!_l,u\Æ·½ahPªIåhyÄ1C./ÔçójçuÑï$q‘[ûŽ¢ ”0—…N‡ˆ°¨È+4ú›är…MJ)KÕOۋîÔêÌ,xK£H àb¬ØÛRšã¹½¦,®˜Çln3jy¹k|uÓW®ßgAeôŒÛGòŸÎäolÖ¢-ÈB8ùþÐïÚ­ëpkŒwr)«¯£þ'Ão×8ª*€bWsa~ô\a£Òw­}Hσ˜tÀÑm…w ‰}d¶tŽ¢@]õdBÑ“¬>íkuÚ“Æ’¯ˆœGÄã»*Ž!JˆúŠMùSöPa S\¯ †ü?ç!”z˜íŒMxeØÛBÉçaÔ±ô²êá­\nF™2 L(VÙXN|!4KX|…•ÝÔÀ/ *Sl£ åmE€`dø§›¶«Ååï?^¹çŠØÇRô…ðÏñeN²/öYyòJ|e“=q`Wmª~r\ñoÍ¡î{ü‡ên™&îHM4_sʧ“6pH†Œ^aÁ–Å4ΦV¢,®”@8iŽö^.þB‡«¢”îžc÷rý¸[ã•8ìØ*<Œ0Ô\» ^ã9Sp}1ÛÍI§Aª”=5’u’Ãàý©µ…ë¼v•±|ꔆr oa˜íþe_%Žæ Ú J \ºŽÉYñδâ«yèØ ¥Q 7¯lÁ±ÒÛË3±Hu4$N|¯é9ØïŽØä´E:ð/Àô©Ëù¤>ú¿?ǰÇSÁG‘‰ñ3ì °+î8HIø›«Â¦wøÎÙ#£6¢ä{(ÑŒ/Ê¿¸B#‚sûÍáè›P-`E¯4›@~ZÞ²¨âñŽoï«6¡0 Ÿ û~nGåB¹Hâ—0bÓL¼ö£Æ-Ã%€÷iÞ8™LR “H§Ð §„s#Æ1{Vº.y$ÍÏl÷YözØðL {¹ßa67Ÿ ƒ‘ O—ù§2¦[³{8ï‘l&çC3ëê.>cW IÁI:8ÀÁïúmIEI‚wÈ-¯Ž²‚EËE67ñR,/2þžù)ËBk9p¤©²øè÷ªÆ€—í­ÈÚö:)©ƒæE Ö÷8¿Þ bÇ »?F]3=ÇKÍ>³/þO–>ÜVU3­ v<ÉnPjìO VèâüwÈRµÚ]Ñ›t5*¥¤3kˆ[4Ù/eù‰HM‡[ÚaKîïȲ€lSôBÿnŸ'V_XºäV *ÏTÑm&‹[‹ýÃÆ­[g± ´ˆõêo>ÕVQµî#äªÛo(ñó\K7Å»žR~S¸ÁTŠ(OÔ®SùRó¹È³_­ø>`'Eí~8;wŒ×ìú»ò1鉘åÁ#(õòVÒg‡ë®Ñé/*Õû€T(IL—Èèñ²àëÁ÷WêÈï6¨!䪡•ôRhI?…§vIVv Ñä\ÉöçÁ›ž†Z.’Ú(¶ —„ŠDLæô6 Mdp­7“Í"3‡kªØ41š×Xñú¯¢æÊ½ó(´š6ç¥ú’]ƒ¬…í X€á´Goú²:¡•ÅRCê²ØQ¨øPæ´Î´h<‚ˆ¦ÆÕ~ jÉ[Σvïõ+û¹fØ­ ž‘ö†Iš±3IÅØÈLb“GMDªu‘Øk=ƒšÙpÑÆiHQ™ãCË“‘9öbÅ@æW‚ô‰ñY× öÄg©Å+Z¸}Ø_ïøðçv˜Ô~<ð‹L²(p³À¼=†Ìu-ôîpß'w‹N,0‹‡ì®a‚^l¾ì·vSV{œËßuŽh›è×Énê¤ÓeL‰½ÚX©›sûð7dÌ_íµ<_CëŠ)Ü9¨Ý™Ü)ì[ ¶\uáÙc>Ì]è¢ãO˜¿rôfˆÖfUÍ9]r$ìpNðŒ/”=–ÄIw,ëv?÷P0ò;™¹­®ïpÏܽ´°YòˆìG5¤ó›`•e¯á¸\Ï}‚ÛX­ä±½‹È÷€+?“„^§ÑLL aD°z]Q]ŠMR¼†‘±g4€ø¾ûL%!‰AñÃÕ1>-NN.Õ¯.‹‚˜Ìwê6tÕ}#w¦«=U•G}q} X; ³˜GS’tìoA7Æœ<% j¯íhê~Ê!€ë:áåø4dÀ6ĽDb]%ʺ5.He‡JÀÑ;6õñ0Õ%ÀïùßæfCH´¤õÒºˆ`¡%÷_Ó7¬ê” ® uÕ@Kг(†V˜@ËùíŠ)NIX(Løâ–pº$õëNS FXÙ°ó$óÒ„ùµû1¨#’…ô‰‰×¢‰bo]R ÄàïªÏ±}@CT#0}™‡G¼Üñ~³È…½zóï•à÷,€™É®aÇ(1ähF)%H4ü“ЙU 37ï&ͯ¥X¬ ¨Ò—÷vöPsìAíDÖ lì½Î`Ré#è¤i!JÕêíÔÁ[!s9.¾!¥‚­Ëh8vls ³»ÇÔ<æG€Šjp½ƒ«b_g¨8¡`˜S›‡c¹uÜübÐÀJ!Ÿ|¼›£­êaÅä¬ètTy ʂș¢l¸„`‰Õ[Hƒ¾xÈOíÂÜæ1xtvÀÎr^öáÌ;ƒ™œñÿ—®³€­ˆ2z ~¡VÉ8Ó ¥1 óÒ‰ G­Ï™6ÿýº¿{€‰ƒ—½o'ÞLuúN 'б¡ˆêóƒ^-{ªÉm`,äZä^@*NÀ±bPÛšT91rYÝÏQýU£ÞíŒ|ÒÅ÷‡â°/PŸ‚dSƳ(³æþ4 •ó-¬ =DzÈ<2‘ò(vžù+"€”Æýpœª‘Æ[¾"íDËx:0ÔŒ¿e9´ç=e>;ÏóòjwÑ Ë“ñ1hJ+§lz âžÛyÅŠÑËÇ -Wy_œ8oDÞÞãŠPâ ¿‘ƒºŽ{©DÞ;Ö3½çßâ‘õév”ö‰œ¨[\ÌìxU|]TzÙyïYæMÁµze•^¡Xé ì¹èØž'„€¾% O£*¢ã”ÞNèòÊß|¢ºë¾9³i¾¥P¯ë󧸷Ü/bLÕ›ÅC•dÙ–Å [2TÛ-i† 1QcÕªÒç8@Ý¿Ï „/@É´…ùV(ÿâµs±/ÄVðî˜AF«V„§}@œŽ -QMPU,«Ú^iîF‘»Õ%M ³IA¸u#¬»Š°…C‡ðMzܵ6Œivf—<;Xæ„yìÓ2SQBx:nŠ»XäãÐø¬ÐaΩÛK«ËMç§fSÙï0ÞöA<}ζfÖǾd in²áM@6æÂ`PF"öÈÿIæ¦,§¢Çø* ˜´HJ?qo¯ÃÕù4ZÐ3’à†KÒ&]$“ÎS!ÐW£þ¨4½†Õ~9¹úß—®t‚eú*¾]¶óÿåzhâ]Ÿ×ŹèG†)š¤(Euo6ìQæOºÑȱª¿bž‹­;.º^‹Žÿ–ÕzçÎ’X^J‚’\ xg„iwæF90T¯:+,'/!õìît !Ãåôx„ß Méy–úrÇF²{÷vïá¸î|–à nxö’ö9 ÜnïL=æU 4™F‚ÏÖ|ÿ³ªg°$‰âgIÉÿhÏä­—Ò“ ’Y~úM°Îcôtkghì¾-§GíŠï'Ÿ»‹`š7¬ lÜ;L¡9à Mñòb:ÎãEo‰{šM7²4»ë‹^ÙÅöÉ< mX•Ï…4÷Ã|“Õ´úÇeÛ|ÿ£Ãàå΀1rî)æ"0/ÔtKRþ–MYz3LÛU@`‘J!ßB§†öO0ö¡Á)×"UÑ“ðÕ /ÀÓ‡ÎÌá•#)AáB†å™ZLýfb*üQYÿÎîzÌ?!ð?Ù¬µë,×ÍDú>õ¼æ ƒsG-ú¹cÒ*Ü?ƒH¶jz‡\•®à•!ø Á F3»mŽ=Æ»|âóø)rßU®Ö@œe У®.UFØ^3‡–ïñó]´®F`=Õ‹7Ècí„nuȬRè÷LÍøT’šÙ <‘¼Ú„S3_¦«l D1Z˜^@£ãQö¹6šU×¢Óç’ú>VÂÇðu˜×9tï«0\ö*ÃâèšTDZK±l54W! E01KîÁcsñЇJÙª4w}›-l˜Dˆ}2`ÿfˆyÅXÅæO|eš NPsæ×7KïÕÈ·1»¬ATèLné?Éu9Ímï™´ÈP[2ÃSê„ù:¿Ú¨„Ũ»ùÎ>æ™à÷šêŸJ§¹pW9,€íÈ—8l<ã>¯ý¯sz¦öϸï£B»ñ#öA¹;Àä;‰«Ã1hr¥/Z,“‰¡aÁÓý=žy±9ZZ­@{^.qö ±«99n» ¼È Ñ&à‚}Ç. ,Ré¡Ô³ž˜eø!ðáPW—¬œ^"=?†ð|Q1.L»p†_kØ3X_§§¸ó:•ˆKókLWGÿÓù%ëˆz¼r/eb}Y´Ð˪ìê~Gd{|ÈÆn‘þÕΊc.»*ÛS™HßQD ¶»%zvëô°i®A™f¾õªórØ&±M¶Ùý“ƒTeW…5DŽñµìÜ[ M»¾yµŒwŒÏÆhi¾àEÓ|É.]ЛiЍîÖgæÁšÿiÅ3XÍ1æÃŠ <~t?À~Tò‘ÙpûÂSªP“Œ×°œð Õ@èÑC)qº´‚ýõ‡°|c ’ÙTDÿªÉjòÚÞUâŒ×.øÍ’r3I¬©y\Þ¨§nªýùK:W(dn;ž†¹a®ã˜DËåuFÉŠ’óóˆ¡8—iS£ÕÊõÂËpÉÍ£¼æßŠ DEB$ðÚUýM›¨FCLóÂì[5ÀE«îS~>î™ý&(ÜDüQWµÚj²oÕ aìá?1=¬:ôsi躇=}óï³¾^ú‡ÒnÊØ{QÌËØÁÕ‹@fyJ÷Å#ع“ÒOúѲôCy6ÞŒ?ùU}šÇ È©Zþ1¿CzyTYò ±ÝvÙú?SŠË5е1ajÞfæ¢Óêè¾5néÕÞV?_“0ØÌ§>ñ¶Íø3Éäü¦´É´‚e²vÿ5Ñ­r/g^~)¾^Z5kR• ÷Îã¶ï67!òªéE%S¢õ‰@Z¼èè×ÅörÙ`V‡[Øxy˜ þ{àåiQ·¿À@߸ÿaXT•zÓ¯°nŸ8.¨qà²ÉQÂ+Âk“é´®÷ø.üc ê$òܧ¼/žÔ=¢= §d±ß òÕÃvÆéôÞÐ ¹E3 gNWñÒºI×¥¾ö”¬.W&ƾµ”ò.Ç"߉^ôæÍ®\DO“¹ë¥iStÚ_ž…ÿƒ¶Ÿö¿psàÙCbăRºq >QÀy¶›,-–fÔ¹K¦¨›GÂà ÖE8œå…<ù£Ä¿ÂŽpl†‘¶µ¯ßR‘Õ˜ôÿJC4+¾Îj¥ÀXO¸áQx\ˆ@ý‚Kñ§ Ç=t¬~¦;iøΙˣí"ØÑe_‡*S“›PáÓ±«î]¹‡}_ SíšÖ]Q<”Їy©Ûˆƒ;]‚Ú ŸSAý-ŸÚpƒ{_S»spÞÜ®!8ÆÞi'PZ=jÌ£FWð çbñ©¸ê}怀zè‰ rìÒÊ¢`GIuocžTÓ¶u8XùÉU8vŒms b¼Fû È7w[ć®cš€kVÝrZ’a |{¬`}žgš ÎØ¶ð] Ë<Sý$ƒ úõ‚©®›uÎÉÒ…œVhié£À[%««6)a¨ ×<(²È Šàr&fpž‘a&0e*%;óL¶±fÙâÜY˜°wŒ±1Ö‰½¶ :eBùÒóŸS‚ ž1Ü àÓ¶k<Qô í+°âªñoü #(-K ¥§ÃY´/qmðlbÐe¤‹ƒð¨ùHï(K~Ò§Éëi- JZ`µ™YØ«rV‚˜™xR¶‚åÑà«:W2Ú¡Lÿ Í?…ÔôNé-}h88ïèc‹cØ:³üQ“ÇA– )]'éªq2ºÊëÇeÓ›”û ÎiHØÎ*Oˆ;Êkf‰ä¯”Ó7Ö}ïlò÷W ´[Þ¹ÿ½¯l"uØ9E8εÙNå7â}Fyl’2Å=ÙýÒŠ7ñÙû'7¥UïZl×dE ßq`Pþ®–VO@›0Œ¡ï>_JMT)Ø\vTôýç&{¢OÀµ \ù;¶*—Y¼q!Øp«Êÿá´Þ+;ÚíœÛU.¶àê1í+*½ºÄÃoÚ·#¾ägc Çb;„¼³°Ñ\"@1÷ØÚ? ÀaƒåT‡…Ž6þ =•åNžö'>ŸÝ7à{ꕥΠ—°M)0ªúH|tÁgÈp£GbÔÉÛQ#Yˆ>ŠÍ±ÙÌ•D2ìȪ‚ÓÖÒ®7åìŸkJb ù&Ú‹m4:QÏ Þ§_ã¥õ~˜ÙÇqàÝOêszšP?•sÉdø´èåÀîKY„f}–…}‰á§&é~PRL ';¶*û²õìèd¥r4¦Ò쨔¹vÝðT6뀆at}m9P\¹èOÒ$^Cy?QÄ“å- ¢”ðdøù~å]vŒ!x&¯•q·½´1>¢ÇÅwH.ˆHs·„—a˜³œœûÜ;Ä&ûÎ,zT§A½ím.‡=tëã¾Áøß•v<’3+J[„@L –[r?“†’úàA"7¨¾¦/ ÓB;àc:X KaO„„¼0sR÷6/ ÅÐ\DÅG!­XÇw)ì?anè¨[+ãÐ#J«).–á(? ˆÃ.ƒ»t͵ Ôøà »V+ü¹Y­¥ÇCɤ‘C”õRÎS0êËñÖÏFNmRÛ¯¢e‰]"Ëà’Õ¥B‘'xkY£»žy¾ˆhÑo æ^®pЄ¦8&â/»ûN¸ãFb¤lV$Õ|\ƒ\¸•>D‡]‹!¼ÍË¿+$AZ¿äZÚõ©ƒÜ$íX™©5Þ}ë´¶Ÿ)P”;NÊ­ÍÃQã/â.íš_Â! µô ‘§á˜%L£”_t¾RÏšÕ¹–¨”‘¸] WÊtÚ™íRašO%çr{‡€Á `¸ìkϰnªË½aâ€òö\€K…¥Z×[µÌ#i§qOó*ÐO;´¦ïï„F«0cåï_}É^Æï%4ã4R­Ú/ù˜ßBq­Ô,L!¹è7 ?zK½ #éÚàб­j“5ʲ`O=Íç0^^‹T‡69ã÷¶¿¯žôކߵ›=_qÎdí×ûtŦa0t{¯æõ?¬%ÈïKˆÒ®Àü–…bO³ƒ»²‹íŠ/_ßÄjªJ/OM·öúÔ¦í•-MÒ"ylIF)I³‡¼ºŒûæÄ‹ÎY¸Œ'—®pɱl'¹Îû”¾<ÎrGÏòÜì_Ì4QÍÀ ¾)#®×ÍK^Ü䛘ºØ\°«=qPˆ>™xݶŒƒÀ=a(ÕÒ›V+ÈwÅûØŠ¨<Ó%1]ß/‡3ö>(PÿÂ@ÿ}Òíঀ˜žW‹®رQß4ÌÐò®M_°Z>çlrÖíüò ê|K+¯YÄ=£.\¶/¯,«…ž|¢ÆºòOØ&øâú’STc]M,ñ´­`LÐ`Ó¦2Žäh·»ûƒ®D±zg/þœ7NHÈÁ5”&Íz9þlC»ÄÎ"§‰ãÜg™%cçk·Þzxå“Ý\×ÃM¼aLÇ“+‰ÈÎ´Ž¥êa²6§ |½0“`©‚ü{Áž÷Dœç>kZG "Üòf–§ÚŽa¡ ÆÉ3–ÿ’ôá0ýf=´·›sìêº ÅcÃÓä8Ÿ[¢;!ă]³ýÊ  Öfÿë$eÜW(vâjÉÏZ‚‰‡’3Cgt umbKš¼ÓSŠ5ü¡†RŸ£KyÒùíUï"GQ ÕèÑ?;©c‘1]î®ß^Ùö/¿q«#Ô°Q½ÆÁ~8õabs\y9—ÅûÿHº³ŒHÓÕ–Å[Áî`¿YœBDoŸ¨õù±sÙ¯A9‡…ؤœÃœ¢ìšø,¬a”nãR\ßww¹LªsI\\·˜#j/^$œì«Ýô3“IJÿsöŸjÝ.*ÖBÙñ–w¨2 Ú鼪gµrFÆ:iô=c,É0!›C«…­pZûK®{¬ä-›ýõbÞR¿çÀqóíC“MÏLhr ‰ñÀ'0\C®ëÇ_|Ö²é'ÿÎdÚg_š¡š(Ècõhçתãêî}†õ!|  <íHý§c ˜‚ôonXø›“²6 ™@K˜-ëIâšÔ‰Wp‹B…a„ŠÙìÅäÎ'Ø¡½zkBÒß“Â![&ú k.Ü8Æ0b`w±¾›~³xÉH¶k÷Ò‘"¿dßÍ¥ášçæP=ó –JÂH„ÙE‚¡UÌô(‡ç¹[J1”¨ôÎÖjqJÔí'¿ÈÀfxÀ^Ø÷å±Ùð¨â]ÊþúK’F0.¡ÂóÿÜ•IË^‘ãß{l:é÷•H¹þ•ÈœL&:å¨'"Ø ÷V‹‹¡l– |²—¿D3Ó ]¬šh;ððCZ Ê{9‡¨CGA)Ú Ž8¤z7ÜG€Ëœ!Zͽ1Ð Ô2ìµ-õÀ‰ªŒ‹y6©&§ÞþETrœk*®«ÕgÜ.£Øƒ%„¢©Y»WH„<Ýú`UÝz-Û Kûo~×ÁÀGþ“ìðKAU“Þ¥ý-¶ë#õqÃ>nbìWÌì²Pâ9Ã¥P"DC W„– ª¢ Ÿ:röWÃ,%0sŠ|08jéšs-Yž>J§v)`µ×ƒŠÈ1VîBxUκAa5>Ê?<|·•8v‹­‰@K¤ÓBvÈ3Æœq­Œˆu–“1í¡˜.ýçüSœ†0%H~f‡À3{ßð¢…pezË0Ýw{†ì¹ Ž%˜s0U¨z¶ÍÆSÏy ê¹öó3¢ äeпÿ2ḠÖf~ _ýÉ4ˆ—¡úžn#©øˆözâY‰Ò5p€A¦0E9iÖͶbtÉHm<Îo¿ppδ_§R/‘aU6¿3¥eê,pưžÂ®^f¼2Ý(¼íp–<00Í”WhH*ðú ´.ǬƒñÖVk#—ì Æ{2!Ñ Èï°ñ;a‡hR­Ã_«¸#’k¥kh¹_ y’þ¤ärð©0y/®{|ÄôõÇtX§äÞË”T|XF\ø˜–Ó4@±Rïéºã˜]؇søJ]úÚu[^±ÌÛTTZÈCê{Ëybwܾþõ²0®(ß³§ô½ù'“c Š@ò•ªrO“›ðAñWEÍc¼ˆ/s³Ô?PDSù´ž0 ƒçܶ•ë·/Cf ÔÔFNµ¾"K)ôF{“_“y §!=®Þ;V XÛlñ‹,öïé\]Í‚Xð¤Éýþd¬GãßV3ßeè§µÇ í„㊖¹Á·Qà¦!l¬9$†}¥þ9£H½£xO* Y» õD.7ýU´L¼ýHÁ¹;h³bPß•YB:Ub:¼+!B95X‰\×/Š«¹PÛÖýÚy-ä騷âéPÈîÚ‡ EåR¦ j–H´aÜ .y}pHüI;l-É(ýJÐÖý´ 耪¢1âÍÎGY¿´8†€©ŸLgøºH'|¯œ«ƒ·áœ~Z,®ðÞÕðGEº·BtÐ!×ÑŸÅ+ÓzèL. k¬ŠòF½‰ä¶ïE¡>>€¬†ßG«3óa–¶ | ·Æ Õ‡Ómñ°Ü'Âp9ùêâK2†ŽSöŠS]õöði ùh.ñÞØ ܃#Ô×]FÝÏéæAwÒ¢ûÂÒ€f0üñêækyŽä5‚ñ’l ‡=±s™DÚ#¶HÜ4nhtáuL«ÿXŸÿ _µZ¨LUvP©i +hkÜB:÷RLÙ`íµÓç „ÜïüàÚrÝ8©CæQÓ-6¯3›§P˜i-•‚Há³mð%%òh|tàˉ7OÊ=ç#8ß2¾xúÇ(ž1C«ïjM›ó9} àYI˜ú'GE ýùNX½„P] º˜"Ò< €ý>$•Q„«ggÅLúZ¾íΑ|D¢îf¦ÇîŒ,<âƒ{Sóߦ-wÚ¼xÜD~ £ðv )ò:î;iÞö˜äÄŒ‚ s>"¢Q¾Ðå 8äÁ¥g{ƒv*˜˜}å†&[noeeÊ_e¼Y‰¼ZжŠÇÏ~‚ðìã E ‹Ç@°;,ö1ï % R³ü0¦ížÓUP…a¹glˆè‚Ø—z*ö)îx#8{¬âܺյðÄ /NöÍ)¿ÉþŒv{>GÂBª¶˜gÛ˜)ŠWénûc7@Ä0pkƒÅØ´/³è]ã%±@þQ˜Å&ÈkRm?šçN‡Çw^ s‰÷IÛ%xØ0ðj‚‹D=Ï®•b«acëƒæ ãlð]„3û1íÝêä·äÒf*$Ýìî˜ ž)ŽL ë£qyaÌ`D¿þtuG¿#Oç6ù´H•x¬œI€ÈÞ¦…ÿ*´©ø#œäçI&‹5] ¡;Ÿa”å –êó¥-ÒÕn8á Ôu1VÌbFØZS áû€ú6ƒˆîì6ù-A ÖYSDÀçÏö½%P eã0sPU‹”Á§Ö[øMÄ e RЛÁõË\Oi%þìÔÕ•†;ßÂ^~#?"ek+>ó*èߢB>>g³úI NÙf .ÑWG½¯âH%u¨—fRû¤JØ=$ACb«Y(ù³ˆR9ÎæRuÚ&ç” ùä<­hN8Á/íO ›…¿™vôûªtÜæa_^+6úÚPȃôÃͲø¡£WéÊ4p“ ôŸ‡Iy_kÙêĘ /†8È„±p C„°õ1]OÒhùŸ¨a$@<Â2›Ï§ö†áÉÕ’G\Œ~yÜÁ}3Ée¤.˜lD«}ÌÕ%¥‡µ\ozuFÆ»Á{j±TžÔl5¨ç±óq¯·Æž Ä9o‰²®\ܼ_öÃàS›Zår cÞú‚."ì—ˆ1a=3(€ãe2dõŽ6¶]€ Úªag1^]ç §¨ÀE°§ã¹=,5úÅâar,Ò“óì~þà3WL&tÆyû¡+S«%—¿ÍVŸ/ƒ:vûmÔ gXNº2Ûî~@j-éÕLÖã|2“B°3Üp% áw¥dG!ƒU¹H†öÁ‘ò—í3T4G~AæÇ ÛÆ¦±?Gné¹£Fa’wL¹™[DÒvv …¼ûæ‚r9¢(Ï@tZNäÓ¢çÐNÜÁ+8úb£³‡$€ežM]“A-n/ ¹ø<ІŸº}€²3©ÏùÒ¬MŒMÁ¦Àšºçc(ˆ!mD`pí,N "¾ŠÀaÓâ}/„äĽý:˜6¼Ž¬Ê9éǽè^SÓÌÁªÈVª] ˆƒ˜ÝÎé஀‚%†ôº?Åé H»Ñ¾A‡P1w¸(ýå‘»¤ýñöÊI%p eÓ5]p¬zcÕRŠ%¬¢W[–i‡¯ƒ»†bòÉÄSP†Jû®SVëe”´@è—kð¬(a0ɾ½!}Š@Þ¦bÖ>Ø0ê|Ãt©åÞÍÎ ©Ø Ѻ“ÊŸ°üÐͼ­n²ú™â€U Ezõ9dÖ‘”ýæäÜ[ŸïÊÏ„ä\sÉË\žòâòº±KKrÎ’Fús8¿Kß/[NTDû#³–º¹RŸ™ÕàbþR!žûøÝ‚V´áÂõxôn:U&=šwø™¨Ua×Î,< ÖÀmœµ˜ö³Y¬o;˜=m5›Êã$^¦YOCº³b(âçH=áv„¦²ÖèVo‘oˆ­¹Þx8]Ìk«3û Ìj#ƒAèQ*Ý#9™ðݯÄ“ç½íp´£U™à›­i‚(ßûVã:Ož­–àŽF!ói²Í锎†ý›7´xC±æJt==LŸd”¬ è¦,ÄSòùf~Ìnõ¹ãÂl…Ñ¢¿E'äMø5-ïhxú)™¯¸Üˆ4Z9H£ò á.ÊX &^ŒØë˜³©˜Âöuü0°&Û¿D'CÒaêèC|;hB"fZ¢ƒÏn-µ÷ 6¤('>vùè"ãw¾ÝîÝ[¨tJñøï6th`Je ðd‡D4ÏÒp,¹ôs3fïé¼ý¶nïfÞ™äo+¨ÐgüZgš‘œuïgòÚ ]|\ç‘­Û«(Šé㘑!nHÄ*ÝÚc—‘~èÄ·ÐP\3C“DÎXVcN½dÚôµ7:÷™aKmq¶bêË}vöƒµsÂZÒR‹Ôjc£bU±694³·f‡”Xz–ùçô²¢ØsÜ<2iݳÂiŸ>¦ÿbõGç;½ãA‚9­DÕõŽnÚ¹Cý÷JúÔ[‡‰÷ǃSßTÙ<¢> ¨Œ”§+˜Çá˯å3øÎ8CÎ#¬Ç«‹QýõÏæTŽ:3Œ?ð!rèTéÄä*1ÁÍ›ˆOŒ_OÂÕÄNË¿Çįv'Ÿ‚¼k°ó*\÷DEµÏÇÍ&îEøîN · 1…&H|̃êÛùÌJdBÕZ$püm噕}]T‚_Ê”³}Ï“¤ýSm:õJ†>_ô[ôãj ³ª«IfYºÀ8A|— i»*-ÿ2hà à l„*!ù3k¬ƒõŒ£DŠ.8j€zƒ¶“5G~.õ=ãb ôÌè…4Mß®úSÞu÷'@#Ôh L«v‘•ª/Àc¤axÒ¥ÿz—³ÊVð LçCLpAy|÷„á:\5O=¬…gÑ ‹á éŠÄºˆsp4§çÚÜÉR{À½ÆÌx%Ü»d‚‹5Á³uÂg¶2ÞrK¬òœúÜk«WþÊH=úr³¤LÐ*qq•×]:{ø¹œlgǦg<-Ò9ZÌ„•¸c¬¸¿…XG®cÇÚzù•Qšå=›4Xa¶ÓAíã&&VÏïW07M6!Ž@vù„†Q¥'ð‡¢cp£ï»«oÌQîˆÉs'n”œ¿qý•°ÚÞòšª{0æi&uøŽu÷A?“CàûaK–’ûÀ§˜&¶ø«¼hˆG±[m†Ñ ‚_gœ^x•'vÃj¶Ùã/ëP߸õí͇P0p2³×•wß•¥B'̹ì‰9Q)ÄòB®<|N5”yðúV£ÄMV¬$NˆÚ@#niA¼¤b±Agö¯z¨}?RrI%ŽÎ£éo®¸hñWÑ|÷Çž5ç÷ñ_}°6ƒîO?×j¬GÚcG>œÈcÉ61:Þä1‰ƒ¥bž½(‰¿Ÿš¼’•Ü›8 ³}2²}I8ù©vùÁLmQÒ[yQlzµýgaœs‚üË­úVjxhøë–ÖèÉÀŒÁ!¹”uXÄÄþá¸ÐÔ!ñcý &‡ÈvÈi­î7¼Û—GšÜ莋vAã4»l{ùÝ¿_“÷Æ,u¶µ^¶ûì Núß¹†1Bß—é'^Ée.râ"C‡Ð1Ò¥ EÀUºE­öÕñD>0v\ÛˆþŹòÎ'k‡sšÃ~ñ,×6žÀNf ŒGõ7ÚŒn5×_}áµW—XHTxOš<…ÂÁo¿RJµÖLÀˆÍu°îËÐÔýL•Óö ®Øä§O©Oƒmâw<}ï€5q¦ûXD%ô¿ é‚Eio¨–å< _ÝÝꇤJìd÷A«E¬í {ú…¸læ# &±¬äŒj:,œ%§U˜Ò!ìz·>_¹ãë”çEý1ÈY;(#ç¼OŠ` äE´bÉüÐáCFÚËAÞNòÌìD¬vönº›ZB~êÊ) 5Uè¹OÙ?Œvz¸SÅ[ÃÄÓ§½ôvÊol\Œ-.˜+ë­½^š3’YþêefkªQ³V¼x/LÁÀœ•œŸ‹há:°Ÿ ¡¡%¿Òàñ¥¾1ùÌ«T's±÷—\hÐp¨(5-M/ìÛ&ˆ@fOr}„’Û8Æ™`…TÒªŠTö_Ðpþhå‹nإʾÎ#$ì.»%ÒÛ™½}7ÆrÐÜmþ,Í=ˆ:Æ=¸æ‚öD`:D)šW“óí 5íÑEpâ_+‰F6Ðj.' Õ…¾esUÒÏßMáBX9¿7´¤zëôÅwS>¾X¶È• â¹Éœ5P“ìî8€N¼ÃFÿ¶§©'Âø+ÛO‚èÔW_Jûª{žcF +k¿î®¤K‹N&ƒX¼_‡¶ uŠ•z?74ŒçÛFCêý ѱP+`äöLëÎ¥†É m´¼@Æ5 nïJ©>…M¼~¼°©ŽYï %‘ ÎÜð]Œ„1†-zɺ¿*·gz\àG® '$scýkÔØ¼BDqê_@'‚Œƒx }å‚j`éZ!¨Û]zÿÆÌª‘d¡6ë>ç¢1‘ßwg–žÄâ86Â-â8]ïBçîmÙñÎm‰È5žB:ÖóÂ)¤ìÔ\&¦cGÄj_Í’%,¼>_“1Ü‘‰ñ­u¶¥%9] Ûó[ü ×'gU­Â2…?C¨.€¹bû¶"y íO vÁ…BëqÖ‡Ëå£Ûƒ+oR9œ·º7~¸¶|ï Ü`¯§ ‚•ÆÂñÔÜñfb´ ø*n}]b8ƒ>D´Ð‘«9‡`5?îEÞ‘ç=ÁXðÒ’c Ê7ò l§ÒÕ„/16ŠÄ‡ë·j"Ï mžFRzÈE\óWccÓ½ z·-B(ü¦æy’ع#òóëü0.G3YÌ!¾ªádf½òÎÑÏ—‡¬ï°;‘|¬+(ßµÀ’o/§Ýù†œTâÕ€}”8ìæ)Ä&çTžÄdà Ö½”Ädîdñ°¾¬íY¾;AÚZÛqãÀåê­ÍL‘·„³çu½7wh{Üâ{ŠíMrÉØCËd(„ã{Î WHN[‡&d¦¶E©Y2*ö|ëá‡+³ùyËb^4±¦Kÿ1 J,ÿ ,e`Ï·ÖÉ7„²VšøÌ~g†”]Ú>1Lúùæ^|"øâßP¤S ³ñ&Ë´• DLôΛ·_vEá«:®D8 ƒfEÀ¨c²]QÐbS=¿}X`ìøód"ÖB;ÛÌø—µ@ĽàîSj™ÕöY2Åü—ÉÁ endstream endobj 9826 0 obj << /Length1 3450 /Length2 32187 /Length3 0 /Length 34002 /Filter /FlateDecode >> stream xÚ̹eTœ[6Š;wi Xp‡àîî¤qh q nÁ=`Á!ÁÝ-\ƒC°àÁávΙræÎ]÷ûù-V¯î§ö®ª§l¿»iJU f1 PäèÊÌÎÂö  Ô•ñrj]€`fu •›½© €ƒ… …†FÂhêjr”4u¾ðºZTÌ]!úllü(4 #вh0ó(]M5½œ€ìzÓ¿€*ìÊlf †,­l  “—‹•µëo<Ì¿ ,A.¿™~S=]Ž`ˆWðo£â,ySs;ØÎ`êhgQb(ƒ< B=È`´6µ·€,ÿ2¡¥!¥®QWÑRÕ``hÛ]M!±æÖ¦.¦æ®@0Àñcjañ7oYSG€¦5ò2u´fPÔpsr¹ü+* M-&€¤˜²¦¨ÍÑÒÐd(kB„­ü&ùs´°1ý­®$¥)¦©§*ÅÎú;v€;ħÍo¦ÿ-$Às4UKÃ_ôÖ®®N¯YY=<ìѱzþÕƒVG+Dàäæê÷»Â(¿û„‡À*ö[ô7â°Š?#^«Ä3â°J>#~«Ô/€Uú±Xež€UöqX垀UþA¸(<#Ågá¢ôŒ \”Ÿ„‹Ê„‹ê3‚pQ{F.êÏÂEãA¸h>#­gá¢ýŒ \tž„‹î3‚pÑûâ‡pÑF=Óÿ .SÈùæb¶{N+„„©ë³ĶÙ3‚Äb; «=Ðò]œÿ‘ÿ=Èÿ^`ç‚°1ƒ ðÍ‘ù7Ä9ÈÒ©ÿ¡Åõ[âàðLôw ³Zü!4€Ï ©þÓ+÷ï ¦`ë?” ÑZ>C K›g#œ¿¡û³UvNˆOKûç ¿ÕAn.„¨X=ç ²nõû¾üs $”g \ŠZ{9YÿØ‘Ùü!±Øþ!õ²ûBrṏBÐþ÷?¯Cbrx†ì Ï®¸!¶!Óÿ'ĵ£›ƒÙïÚêJìäžICl‚þÐbg‡êô¼ ñád y*ÿ£¸Øÿ%ýg7pA¢s‚´è¹–\$:Ù»ý;Dâüäoäÿu–=wïo)òh6³ÿ‡cv.¾ç•ÿnEž-ý—œR¤?jÆIË3nHø` ƒÍ?[”û÷ û…ä†Ûx>Ça¶ÿG²Cü?»ýÝ¢®Ö.À?ú’JWÐ nÏcñù×lrù³ˆÝÿ€Â´9ĨçâÕë©¥÷3gˆ%o Ëß þù=æ(óßAæ!¶iõa%þRŸÆKáiøYÊñ…uåàæ?Œ·’Jæ¬SEò2hóAв¯üS uiBðìWš’?]X¨‰n˜ú+ù“`H‰ ek³he(Í”¶S1ìÊgçéqMf4'4“´†ö$ø[;nb8FŸ°ÎR© K›—rá= ¦Ùp]ì±=ç0‰ÛHæÆÛ ]Ÿnpã¢M»Åæ_M½É Ã’GpêêÀù™Õ¼#¼9´ž£u¯]¶Ðp²~í$BA·ÔL~YÞŒëŒÎªõ){MÕW1V gòÍÎû7Ü*º°"¿ ³Ñ!T›©ï¿n4 *‡EŸœD[ê ²µr—?ß…ë.ËòwœÔ¨`7;K_vù–G-B¥Ö˜ñªôÔu™ì×;Y+_­ nÝáH|­®Ë&°:Íz÷ÙG6ã…lCŸ9ÒV§p”„·ÑÄÁüÒ-rŒ©;Uðû)œÎ­…ÞÅÆt"9ó:"J«øPê7g·~7Ì·zû— —a/.s°§âQwFŠ2s­9•ç¢0RMë8ȸÉO©¬® uã¾øÏ¾Žf±³3€mNKž£†§Å(/-‡Ô»~ø«ÝéŽy` ãÅ!óëPt-¨+WJÅ‘q!Nivoz……ƒ*Ô,Të¬ m€íâD!F7#1uP|3Åt §ñ>T³c­?òŽK%Æ÷ï3;¬ø>Jøµ¿ÚD¿Ç¶V]“3`‰µwjüäZÍÕÜ~¦¾Õfóçð¶rf—üï)O¢Ô˜ÁÕ·qìR%?ˆQÔÚ c™JýjN %11ËYî¸Õ¬0RPkO¡¤på‹wò9u0sÄ-=!;¹Ò­5L ÜæÚK/ô…®þ)!ˆ!ZfÚöÓ†ÕMv0íc}mŸcz‘¢eô¦™»›¯ nßΫö0ö£š›ÒH³ý®•°¡ÜÅVwO¶8Âý9[Ýx-ÇÛˆ8@~:Fe§Ï¨ ü1é‰.)¸°Í›÷ó;ð†Ú9Ú%rhò+èì^þÖ“U°Jh‹䡦œ!BNކ ôVµ/Œ`/6¹Ïy›³:«*ÅaJNO:Ä×uΗöÊ"ìî3Tî5v뻽.zCâžXý·JL½°¶Â‘-uU0mBQ×`G¾Gf[iœ!ø6bµƒ‚Ëkný–¼—~²j—oô-ç_%;ðòdí‰Ø«ÏGóHªp  ’xœd­±}UwARA¶ÍµïÁ>TÑÇÝFÅíKú}ÎÄòµ GLŽñ ¶.D·‚§ºR"ua;Beì¤Ëu©õäºçUw!«YÕÌ@(† *|ï…uöéùïʧ`t‡ý¥ŽP¨›!>è\ÎX'xÖ0Aùo¸ì¯k5ßžÓ•fW”aL~ѼE×ð^"ñ!šÇ)±-©qìÐfâEZëžuGF–BMˆdUV =v+÷yßÞGü ±zü6›å…›Ë™)cÛëV6ﬗˆ om³ì77Ù4 &ú¨OÔæm•¢†pU&VË0Î6ЀY¥Ì ‚U¡Ÿ]E¾[°º|‚ê.üÀ#’ÎUSGöÑÈÏ­ ÑöT¸GæS·î/¼Hx ŒqMBle¬²Û³ز ¢Ék¸)?aÆC±Ñ˜‚>Œ¬Õ(™úɱüƒƒíá5æ{–EмƒÆh#rë>¡ü¯lžïâhIQ32<°ãÇ[ ¼ôwI¸¤­†õór8µ:‡Ú ØÖ‹¿<‹÷[NŽïѶΚʒ£ƒ³˜Š æuÌÉã†.[)Ó¸›)flzõõ=̩ԚŸ=Ô8gWvÔ®Äa¹¡€”q©£"¾L꽫©Ì=çÏÍT Dì\šTåCåg‰JT*.‘ñkVÝœg•Û§uÕ{ä·q{Ö¹Ô.ÌÂe6‚/=”³*7ýmâ/¿1Yƒ°™Ë¦¶ ú$0Ñ”ê¾ÅD/ºf.µ"Á_ü7Þ£wYÐ’Þ _¸ØZ¿‹Õ*O;`*ëGÒÓÛ¤î 'ª§ð·õ°¤m2O‹ò»U#æu|‰;Š”ša—¡’x5b:ÿ$>ÐóãÀS‚Ȳ¶'åé|!Uò }FJYâlñÜìÓ +;Ë ¼T;±(¹6ËOõ«³vÆ)ߺЅó®q©§Ð¿ã‘¶ :¹á}‹m“ŸóÉV|¦ÉO¤Å“ùP½)RInq®7©5°õf´’ Ö—LT|Àøø@n^Ù~{Ë–-Í”~ ]™ç×÷´ éýFÈ’f2áD|U_ -š·:ì!Ôw­ü¢ƒæÐæ rmN*¨‚Ùìq)ÆÏ¬Æ°*ûR»âFí—Áž^Ÿ“zÌ>ùnÉGá3ηÐâ¸h4¿Ó%ÛÖ+ôîV;¬ô’ŽCÂyqòÎ-JW¬i¨lvd­}ºLýÆïºmkvX$ˆ·ï'zÜ ºÒðG…è=ù÷z?dÔ´^n„ËÀ©M=ú3f·òåt¾öûâû±Ê;!ÖAR?$„ž\û‰Aì8ànO&”«²_€V†­½¿žaTFê— ˜¾:+“Š%™»×£yw9ÏËKå9)®ÿµ„UóÒáÈÿueœa’Žcm `1»ïW/†èÌ«fñ{('"åIÝkßú‰Ú·ÏÂBÎzÜ£+é™ì¬ pUlœnaSe]«9d»¦{Ñ¿e=ŽÑ×Ý[dk}úTD~&„óP±M+*á°Ò´ó¢£™õ K‹Üа@–ÃÞxgƒ:R¯Ëqk;˜ýÌÙYè„zù‘ÁÒ;ƃýs¬t²ÓåtB*»L–=»TKêÖR,dx’™½§ž¡Î ¾©3å¡Ýø®NQ˜l›sÜ‹mÓû·X„Ýž4ã =×tAˆ®‰þP©육µ%B‹·Ä×¥¯ÏqFÖ¹°L¯ä¹–¦lZrsã4©+É‚Þêkë¢*wné\Á»g³K^z¤B,¼v‹—ÊŽ©»n€#ZGÊ£W Ì Ž8tZß|$ˆñ“vkMŒ-™Sê¶w0/$‹?ÀøVv·5à"´^îýá{Ë÷þ©ŠŸîýw)£ –ÁKs wÑŽÌiV¯ZCt¬xìWÐy‹Y‘3¯upƒ”“­¨>T¬dFó½Å;±¸oÑóã:„¬µ¯Üéíƒù¶?•ø…zÞµi÷Id‘ôðÃç¢éEæ}K«zÙUÆ&LÕ? ZúÐ5gÛ²™lñáú¦_™§DްÔúncÖU'o¤ü§‡Â¨o¿;üÍëŽý9ؤܪŠrs7è7¤ê_[ä‰û”£ïDÞb²Yt0‹8¨ýÚmØ‘7j)KZ^QìlRöï39\ƒ $¤3h.x‰qTCM˜Ô¸¯–nðíìËë§ègÊõѺöE˜AŸµŒÙ+âŒñáä5e˜®@ûœÐӥǒÁ?lbäÄì:¯¸°æU‚sú å´\4ŽÇ[”Aqt yšL¬ÂVe±½Õ¬”õlëã3×W©?ºC+ÛS¦þ ®a‡±Ñ!½ÔxÚòR!¤î`þÂ=¶oì1º™ âå+pE¡92k‚nq †ÅíõHò˜Ïƒ#'‚¿+î¿k~½_Îè`Q˜„qrz›1E¿À¸,6ìñ”ÒÊ0R¬K§tZÇQ­ñš*>2Á”ô+3ÔÄÅžè¥=@®CƒïpíFó*îfJ^lïåv^y=0%1=]Ѿ`ÒÆ}Ö›[CÁ<þ°{iä6ÊWçɶunáý®þÓ-Em;|T·Ý5i”u|ðŽ¿ñDÏn]•Nžt|Õ…ZmŸiÙE‘Ò  L+„ŽÀ”ø„“õ¡ÆÐÕM@qöQ¦Þúc¬Ú§¬ÐŒŸwé{Q/¤íR÷²xžn™øÜú#Ç U÷ÜA_ÕêY`¢…TÛ¡ï3gfÎé¥ ˦[nÒEŒ§UΰåÍ´jájtåÙv‡¸F<ÑH>P¢7±3Þ¼bˆëÛBÏe<; ¥ÌuË»Ô$KÁM¥&[kª&Ñiý(‘ޢƒR9›|Ü5h9TýòîÆ fçÆu‘°äs“7³•“£ÚPêŽ6©…'µk] –@ª±LÕ°ðYç^,ÝǯN 7,¨Pfõõ•5üŸA“4q°¸ "¦SPô-/jET;î¸áö ƒ¹Ùìy:¤0û_–q8ÌÕG{v{ µê(Ž¿Ü‰q•dþ°,AwÙ‘uk¹L[”Û¸ ÅœIíš'ÝÛã îytûØõScem6>Pš…zÂ3ó®Xçö ­…Ü'81¢'d¾råRåŠ(ïÏ~õU w)–”tÏ ê—`AëÑ…‘%ö6 ͵‘$ ~"Ô÷®½¯všíp2œMnÎ%¢x¹{¶ }i]eD}o7Ï)ˆÃj©ÂiÎH{Â/ri¨Ì¯8ÎöÔo]u¸SåÁÑlžjäkrgN#¾”*"g§ý@j-ÅÏ ãOÃúà”…-¤.C¨ºz§Ô¬ÈW0„a·­ÙÕñD‹UT¹€=®4²º ÷«D¾ù¹¸ãÙ/,‘üñ¹ÏOãv˜èqTsPE¤}8KrWîÀÒt™Ì ¬˜@ƒ7‹]r`qv(©‚Z„ Õhª§}7ý²ÝB†JÄ•G¶”Ÿ Þø¶´[æ¬[rMWøZ2Ÿ{ãÑiý\ðA áÔyuQÝìš@άպ„¯`û¡i¼ ¡/¿ô2x•<‰kÉ=¾?Û ûmmIB¯6W­ÇT /ÇfQß‚emµÅx±­Ÿ`NDU‡Or¾· jô›]φ¶vÒ¬õ•'B‰^–0HkL3Ý+«’Ì'ÔP®%›¦^õ˜çȸ_¡.gÚ3j¥m̵i= ø¹„¼úsâݵe¼ rq©jÞN˜£Çâ;Øð¹6mš×Þ‹ËÆZ¸Úo÷aêÐyBc-D…‘’MíÚR~ÊrV ¦Ô¿ˆ§é%ýŒù´v¹DÔy(‘?h,ýQTÔÃ{ã/0»T ó:€ð£•t‚M_ ¿†„a©X‹¶ÔŒ}y²>‡†M½ííÉ£ÿ§¡áÛ%¾¤­ôf5VxÙ"ùnJ/Ð1=¡÷BÖfÔ ú(NšdM¾ßëM QÙŠd Á•쥊§Î ܖqäœÎêéïNöÃð¢øv}¶oIõSm=jï]Yïrqn iqÝìJÙŽ/׌^Ph†¿'aT6A3–¯kI‰s磯¹sø¬æàÌÙ¼»Ññz-ÑLëFºÜÚ3䓦__ ÙùÅcïƒNe$E3‹[›‘iԇ年µ{Þrãćoî½kNG/šMq¹êìb7ºF#ý…{,Wn‹*»}Q”DΫ^Wòœ³¾4$i]ZµYÂh±˜Ë|ìøq V Ž æhzâ‡&æ„:¹â¶(;ê·­}ë"5¾B{R#5Œ°¸·»Å¸*xýØExrÏÛ±ö}|PS"l9%6h#”j OØ!Í£”å÷ê“óÓë -OºìÖÌ Vó.­»°¡_…,ÝÓiú0ŒbßÚØ¥•ûÙ¿QY–øõ€üáeAÙé®E$^¿DN ¾¹ûøðð9㤇ª ‘lÞ'"ã}ž<ã>r.¯z*EöŒr] á·oÅ YÔÖFLÀM/X"SŠ‚OwUÓgI’d¨Óß)Îl½½}b~gwª“Lc¬=®¦EÕ+·Ô€aÈ6ª,õð¸‹ÌÇrò3ìS{‡Ð꞉’Ž?.µUcuRoÏÃ]çŠë»b÷NÞÑ•ü—N€…¶T,gÞh -ÝtâÈ©½Ø(ö o†dìO¯¯E‡~¿Ox4ײH6öSƒFŠpò ºP7ÿzññ ý^Ì 8*ê¤o¦*–S$ ¦ôÖ¦öKð6{Wû&UˆÂ¹iOÚJÍúårHý ¯Vz}/Þ.:\%xµ öó×O°Ãõ¡Ñ]ë`RÐu 4”Sê”0ðì¬FSçô,hJÝ )¬ÚêžÉä[Ú'2~`mÐÜNNŽ˜UyäÐ…|س³>#Àzfjï—¹_}Ðø"b\ôëë!“3™2 ëu7ß{gOn¼Üi0¨(±1¨æŠêcU¶Ë%€já å+ÍòÏÍ?štâïEÏ ã5a‹6àfÆV¸¬¬6öm(v(ªºæ(Q&½SO÷œîÛÉ9É¢Ô`.¾Óÿ¡Q˜RÐzNcm!d­JN›çÓ—Óè…‘êXáÇdÆ“NZ±hC<ÔÛ$”Éëe?:î§õž_ _|‰ë‡uïó%'dv-mD×âÍ ¿í 69ï8”ÿ•äõãmú!8*VåX´Íx*'_ØÊdÃÖŠ¿ÉðÛÔ Û¼h6tµoØí¾Ífi?ƒÃsM¯˜ÂU•üýè¡=âø¨ƒ·LŽ„ãÖæÄùPŽ æî€ùªà[_§O"xHK-Ùìà·*W«ëb„ˆ>ñ!j½‡Áb“‘lO‡áó*R&ü²aü/gιM\Å­M{E͉`š˜Ô@V¤m雚W꣮8úø?1ຎ0Ý´ ›ª xÅ¢? s3ëPW}÷ÈFj¤FﮨP$r7çùÉPÎsä†e_¹QF&¾·VäVqW0Ðu¯·Ê§2¦YD —Žå¿ÍòCçàáxXv½—õûôImY‡4nKU`%È#¬2;YMKUA— o!À,f‘€;°e‚Ý hJµ U,¿ôG˜÷L ›\XÔš f¹AÑiHBíú¼~^kxÞ»ÃÜ_±©¼ýá\™ôã©9ž° c#Q¨ÃT19_—^»™’>ãô ¢¬c Ooå„rè<ó#˜G§Ù—JpÍsx¢Hq®0µh‰“jÆ#¤£vI?èc½Yïu¯¼ÄG´îÒk:¹tß¹qÞÕø9b¿µ"TZÉäÁƒ+ª' œJ‡ ©à€s„ÔÙ=ê(þÖ2a× ‹ !U¢ï–ê¯Ç)¼Ý—5_6HÚåñ´³(éXÙ¹|0TEw¯Ès¨QüÊnEäowÐÜ?Ïbò./>ØñÂ]ÊëC¯¼sÒä¬ Tp:GC(žŸÃS"³ÛqÎR[Ï7ÜÈ–ð)´Ê7Þ©/k{+6{xo’! ËŒe‹`q+›‰¢hçˆà&±kî¸y“R†ºi‰1q„¼[´ùDØÙ*=–+@‡ÒUuJßšáÒ3Û—ÂçHé±»ÅnJ´Í Uè]f,õ I×ìIü¡ÿ0ÀšÎ¤Pôè+êÐgøB~ݹmh¿c.¬õü‰[;ª“l;Ù‡\†‹Ð-6ÎKð‰ "½•څʬH»Rɇ´Çó ýOÕ`á ù†ÝÓŽ+Ç섬ºãTåm‘Œ5Mørî6y™:_dê’doVúâ¦*Ô×õš {£~[yÅÍt_1Ã)ËÛáiºðË×¥ô{ÅË‚Êeáàß±k’Ä”GðÙzÕÈe¿¯‹J<÷g†{òÿ®6¥æ“:¤}÷¦„Of´ƒé‰þÄ,hjqbO­$Æœ–Ö-B*äÒàû†æØ¹DìTMâ$ƒ$·üÓŽLJàʯ.‚Î{aVSOÄ5†½›*2‘-<¦_/¤*¦®¹àˆêËlÌbÐ}aa­Ä#(Ç[©lK –pLOÆú_'Â[ vñË é.Z1î5íZ¡øuõÇ^Ã}¤â«Ý÷AH*xœõú£”Q­”šîÕæ\,Q6éþŽwB“äÖ‡¬ˆáêóªëv.}B—uÁë5}N\/W¾ïö´º’¬œǼ"«@€ÆßàýPìaåûÐ$2mô…Kÿ!-B²® '— uMÿÞžÕ«ñž:ÿçãäêPÛ˜‚ÀŒW&I™cíöîù¯îòdgóU.¹ÀÌá$ËŠí²ŸZKŒêpQ;Î𢣧;iKŒ¬Ü ó«ƒÖ-Ê÷£ËàN¼6µ¼÷(2 Çh^ô™t°úÑÁ,r3#¹J2\C³j“p:4âm%˜š‚ª>z×ãá_4¢oÖßthï„‘çz[œ."*À‡@ÃþñþQñ×Þ„Å’-yÝê˜@B“®¹KJªÆ–%ö^¢Ó{pí{„%š±%͉έ²oi_UC&{tI¾i›Mqo!)ÇÅ2—1ÑL›®/V”Xbî~+P!•Uw“\ ˆ*ÀwêùÞ\¹ýjK‡Æî¤¨µ¬\®UyRLXWÖʽƒá!w”ïñšGÌ—`!‹Ï›dYѶ¤;+pÁWŸf\ÉëÈ…[-ˆ×Q9äR—QHp×v‹Akd8…ØÈ|è5ë`|l¨ñK±µ 9ý„`?\žo™s]–d`Ùy"МEDÆöÛ`Ý¥to² Sæ­ÕÑâÊù4f•"a£Óô%fÉŒ“aY”&E”üüÀÔ3ÔëYÀû†®­|™,vó?†û ¡ötÇ÷«`‹€rÌΔ 1„ƒIo&Mð^è¼ùÒ)eµRv(ÿ(š93õ îl8OÚÙU=S×È`ørÀå{ÝðÆ6²Ÿ¬óPx jTÀ'WÈÈ7 ü½ñY3Ýcíu¬_÷ìëÕ¦·ÍX¹ˆ‚]‹°!·µÞÍþO1ÛƒeޝFOý˜ßnRÓ›u9Š™0RD ± ­üÒŠ±>Úò›]yé™Wù©q•fIûã—WªMQÕ“S…HÄuˆ´”SžIµ/Ù‰ókÂ¥óËK*­EÐŽƒ2½4ë°¥_‡U™ ÌHˆÕV^a§»\I8oà \Á¾•xÒdvI)ˆy?.4Ye‹šôàuÄB…âýV·…»Nƒœ,õn¿wÛ„U0Ûôe“«¶úÁí‹Á6 ˜/’\¥Èeºz˜ù_ôõÔEæÞfé{1_KïûmÛý˜‚åöˆZsë[G(¤~UÍÓ˜~úØÄLPáTÝÂ-oVÐRu‡6Ÿ£ˆŽ?ƒÖðtB Êÿ.ߢר©ñ2¸±üžP%Âú«k`‡Æü½b­Cåq°©U&óö>…-÷ÖKjÇœÍÛW¶JmÞ"xl—]_.7˜Í+9¾µ9Û½„~Ò;ŒpYö[Îàx©üï_:]L¨Î6Þrzûž;‹œq!ùôõ\óí™4\7ü1Ê'ïÝÞQ’ûÛ‚Å]£H…ËG1>øœWfäÍ¥4/¯¦„Ö{Î`šl+û>@­J¾ò|4íˆèaYÛy Ñ×ö%Áõ¤¹Snãæß©¬†¶ñÿf'ç®ý–tœ¥ÆôÇ¥#*±¯UÏc>K Õn[YŒ Ïý™DA³å°eˆ®zÍTàŒ•Ia$«¼[Phó*'¹6¥×× Otkzg"ƒ|2Ó‡n?*ä·ûÖVÛZ…—È%dûèFNôê½`j92Ë—зv;Á#mïÞ¼¸+èŠG]ÄÂ6\ï6oç}ß~¯ª™§Ø—V“²‡oÔqêÝT\Àã#.s.š×3¢³*K Uj .ÐŽÖ%\>RÈÒ} PÓ‡?vK\Ùb!“–ñĘ5ç5Í« ¨çB;²“vö¹x«wå/çr,éqT©/¿?ó6‘ñí+ŸwxÂzbÚ8o*ç-©?­ú8为ñ%Mf ½Û<éí²“n¸{[„÷ ŠÉgíÓ°¦Œ<É0׿•Û€…Ñç"f Ì~ŸéHÑ£ÅDó‘÷ÓqIélsíUÝ€ßÚ¼[eôõñÁcáó²vliÂÏ} D’Í÷x¼$·ÑÄ?­¶e[]9¯éW1giwæ û=akyÊëwŒ6«« ’š‡¼Êiν••HN±e^z”*fZžWxŽèåÛ|”ýP4¹™ÈÕs”üú¡œívr:©ºtËJœ•~VÉ“Øox)Çq6ÔÂÉèÔ-îŽAK­Ö$€šC,Öûœ=¢ëEð»¯~͆“˜á»—}”3å53€$Ú`}&´ýðõ/§q\¾ß:YT3»*$fºR9(µk1µ—rKµôí}ÅáÏ_–C"a|,~42ßj=m@`mgŠ4Gôå Î YØ >~‘–§‡§ó^ÀéÂC£ŸîÅÕKw·j~ iÌ‚è(ÂÅÝ>Å´Øôž@-;ŽùÏÙÑp‰ ]ê_‘›š°ÉÄÝÁë´³–ÊÅXáz™¯®’~6‹“1«¤ù=áG-ìä:Û Ö\…N"oF½¨åßõ©Óò²º4Bñ—jE}¢ÚLA½G²Ë[ ¸´GyQ!4µBRˆýÎÂÅ5¢Ëì¥.ß‹A“Í\}‡ jN……õ]ÅFPº‰¦º3•ãH8WTËa.¿`Α„î9¶ª">ËÂ@ïÝgÉ u ßá¡ì"ꧬb«mý õ®¢^”Õl甓f÷ú÷ÁcÏúL÷îh¶®ŒÝ3ÍŽgÍSS«Le,v‹ÕT#è㽩êžoÞ3œOéû1Jõ¡Q‚¤¥Ô8 ÞC' ˜j•Ò8ýnÿÌð8ÕsÏz‘9cÛ=\솮ª!j–—B|´ "½Ìü±".~LE¢X+"極sár[B¬QàÍîùCœÇx¹±e×ÔÏ&Ç›Õ7såŸçÑ.,È^“ßi¿­TB€UU„KÁŽ¿È×Z9µTH²µ‹þ©Fä€BI&»ZGù€ÇI\~mv &#ãlùE­m,d€n*shK-ïµ`VI'9ÿ#fÐÁLlgý:‰ã“í'žwØSz‡K¦ÅÃ"­ÍVÊQ±nM›éî-6roèx\ì~_g¦Õ•H¼¦ˆ\”Cú0ÒaÈlÚˆêIK̨¡û?~G˸ë2ÊÔÚ(Å7å$Þf&²F£ï•‚ö'ã+wžP¡·A]ÎÍf„[V× D%ÓFÞÚ\YzŸ7ÿ`J*ˆ‘š€<, ‚©LK‘ý@gæÎøö ;îxa×(ä’4¯ÿ«£èlxy½ŠærkÒ!]ûjm‚EòðZÖŸv÷ðþbþøŽÂ„SÌ@wF–ÄTÄGümK _&y£ONx‘y¡È]e¶n?§7¨S‰ ƒŒ±C´—XŽWÕCd3úÉÆnöáçÝqïÓkq[º <ë)\õ±æír™‰9¥®Å0‡ß cG ûŠ/Xtæ[ÄÝ}æ)æã4bÉ+P Œx ãuо…¢O¤E˜4]—¼8T(&§ÅÑ~'’ÙzˆDM%ôÊ!˜ÈSÄèÛ´e®{|MØ6}¸ªòìB~‹°ô¾ŒÀ³À¯®ÕGuÂn•ŒºÁ˜™ÆpKñ¶ ênàà è>B\r»ó©qþö†øµYÏ=ªäy/rãÔ`BQ2¼€nBT\ØGïËÍc¢È^ÿxÃ@EWÅÔ_éøO9^6Ëh{ö©6qÜC ¨· ªôd{ÇËLíyÃä¢ÚêèTÁ(|ýuQ¿¢‡ÙEt¤*êQ°GØ⪑V+x~ Ƕÿêöâ"âoëê¼t»(ñz‚;­éò´¸hbôX8jiÙ #’×þléNx¤­BÕ=ûÊWÆ„e¤ŸÝÏ6FáŠþ”õEè––r–Ö~뜑C' SÞÆñášj‚¥éãµ!n¥Ö8x—?¾º6ÌZlº´i¶ó{ {³îÅ’ ‡¶ýÑP»ð’a½Ä Û§Ó5îO§ÿã¿»$¬ ‹ÄÚî>(TçÜEŸù¬‰á³¡ÃerwÀ(eo×#{ªn°w ¢ù7 œå4zéyâŽDÁ>ü˜,^ÞÓˆñŒTÛ`4Ú"4ä;ú'5 OTbæ8ÓÖ½Æ.ÅäœâVÐ!âö‡‡dô—Z,ZL75<޾¸¦C4àBÖIâ®™6à¶z„aŠÉµÆ§ÉU{éŽã̽tðÍfkXœÉúQŠ¥f”ðM`Çøl¸‘j0(I‘ùR•6G‚z‚©UN G©qÄ´waœfÁX ÞЙQXIñûZj ”öÌ3ÉÂÁ—½ÈÅhYìѤK•e½PžwöËa48¾”ûÚ’X¿ÑØdÏ{3I#£­Û ÁX&-)—¦¼Ã: Oð\[hK„AaÝ[OÐ~|Sc»3C,¼ÁÊSnå¨îpÜ<ê..ÑE‡':ïjPÙBÏ]Á×Ô°#1ºç@+ôq¤ÝÏpzaá,5Í|å=Y—}_"½Gã@©wè=¿‹X©ž?ã’ ]%¡GØ´Û5¿4¡‘ÆËy…l—cbô‘¢Ķ‘ž&/lQŽEâ€ä÷h5­yì/%„!™©µfîƒèåš´“Ðçbg9éµÍl0‡‡x0ɩNJWïòV<òë1æ+>‚Ø)3Êu¾IoŠö®{-,#¾Ú@lÌÎÄ—š²Äj2¸”&NQP*}Æ,_žÎ„ׯž«›ùpºÌa¢aviöv>þØÍæÓ„(W~vêázÿ±V—~V4Ç–µ$°SÔC²?Ø0;ŽQÍûxæ±\ÆB6¸1'Ç4®h1¾ ŒžÚ[€wyÌä¹ûPŸÆrÂ(<î¡@¸j.ÅžæIb>éâë:QIa3ZKQéUž•²O¤ã5lälòÄí%4ð`ahډȯ‘øJ¸5þ†AJ›µÊŸ¨ß«9$™@J·Jûf/Éûk½Ådk§ˆš±yYÆË®[YÍkÿ~´&£cµµU8¤úÙ‚\(íÁñ|(Ôú¾¦IYŸ‰‹kcÛE~òOÓ ngæ! G¢ýŽçW³<áœöïÌusŽÌWæÂ©À²}L¤RË( ™áŸ83î¸m£g±±Òv~!¢$4jË™]R£XQC„»bx¬)ǯß@ cðޮ稦9ÞÜÏ/É;;<՛ºnÂ;þœX2¢¡è‚¾ñ ïºÛpsû}¸þ¥’»ýtHnÖ´j´ á²Ó€Ÿ¿¾N‘éôÕÐ;8ÝŸü‰ˆ¿Œðz”'á¿ÍÙ’ð‰€“–·¨Wãød?7|Ç(hÂ(¦H" ?xô5êQê¥Ï*UŽ&Of Gßè(¿Ý¦¦ÙˇC® x9‡HÀŸšÝ4´ê24®Uût&=–>.ëVv¾˜”õ¥ÉoÄT,MëÄŠ(Ë=)Ge[?¡Åcì½9=®Žd2í½&t¸í‰„æÇA*fßÊïO¨ÆÖð.g5¨l%CøÌ­f¥¾Æ ˆv)lz;gaL!×ñEÍaaˆ»(míÄ®vÌ$ ‰¿ª5 Òõ‡›¼–––È›… ³®x„·½ÓÀöÉŒxÃþXöĬõ~WX4µÌÎO0ŠßêÝ®êÖ#Éj5ݧfƒŽž¸?ð“E¦µã#Þ‚ÿmÝ—V[{M’r)&‹ht ¼K"ŒåÄÌ™¯Ì~à(Zv™]_šHo~”vQ­„;%3ÿµ+t 9ÛÍöT L5Ü~yùtÅùJ¿Æ›â[^-ÏßDœb”"°hz+MÖê°XÔϸÌöû¿Î´SÃW2¢û+®-Z¶ (c5rƒûQ¦í½r²ßkÊÆÈ¼¤-…úzë_¢¼ï?zÙ?úTàaÅ m›þnc,z¥µWF¿™ÂÛ ¸6eª¨l&õ% ¨=(ãoU¸*‰Ú×#>K½OŠÐ$»³–þMïí+Wd4g~‚ÚþúqÊh’8Ï»íÞ«õ½ãÊV°”BƒñÇ´PÁv}æJÚr«‡[‡®‡ÈãNJÖC9¬´„½ˆ¦ºÅbÜ,’šØÙœÒ‘[`W-žÓNU³Cþ°Íà‰™§ hxŠk†ñ#epiÁ,üö4 ¶y“.% ů#õ¾S|öËu‚² çH"üNh°b TíiØ;t‹ñöÇc>R †õõ5üµÁ‰TšÖ©ÖмV¹§ ¹/úÈBVïVõæ.+ÏE­¾bŒvÍkObJñP‡šsVíÃãò/­€†RP>H¤¼*ýb€º«²£2­90}J>ýJÅÞ€m…Σàpµ–7º’i}N½ÙB¢§Á$Œ²;æ¡w,ÌÚÒyäŠ6E¿HDœ<ùb9™hWüÕ˜…Oö§ ¹è7qc&YjËûÔñwùέi«×@ÂeD»ë ?“ÁfEá]¹ÔÙQ%ÛønÉV‚¦þ]QøðC%.êÏ$öÃV?GókïÂ#¿ÆŸér²x£ÃYêŒ4óÜ–ˆHÑO´mžPP„¬$2Û;Ÿ¾…Zá[ð™% X!ª})¤.܆jÿ&ðZº~ ËÈåü*ºCïÒ»º ,ÛÓ¥FD ò³¸S!Ƹ֢9Îì.¬³MCA÷> ý3l1 šV‘™£ÆÊÈ[(_†x÷dÞ0gµëC.Îì™R&PæOöåXßÓâ²ÈòYšò:µÖõAMí~ÔaSt¯7Øc•è`ÛÇOý0>L?rÝ€D…ä’>Ѩƒã„¹÷aÔ"¤ù©¾wÿ®ãÑÔ}Aû5úÃJ»ÕYqiª×ÆMÏÁâY€r!ŠcòCGÑ$§Ùi iÉÜ~Ïð´S)ÿ_`ÇÈç÷Eøx2eƒ ‚QÑ"Ø;PlsØß©Ó4û0–¡pƒägG#ü9ßxül\¡’•³éCØÄu÷‰'<|§Õ…Þø¯‹l^ýUê¤ g,¡ LÐ9×Tq¶ÛéNÜç²·¼n%hÇn4†e´?ë}Îàˆå×Hnx¬-ÛøÀy} žëfy_8Z]”¿ÎÀÎbëwÌ%j|=Þñ{Ô÷Æèùrü%³ž …ϳ–ñm´(¥‚ò˜Cw‹:ï:õ}|,ƒíçµnŸ8ëˆj´Uå醳Á¶žU+¸oÀ òµHòÄpô¢¹ f#+-LÉ}è‡8¶][r¢Dôã-Š€ŒlMF»ûgG ¡!¿ËS-{‚…òáôr¼«Ë[•6AXƒ/m„ÔË áTýè%B¾F¬õÇ ­šÁTX;·žß_3ˆËÙÅl£ÌFó"Þœ ñø‚½ž‰hªP”Hl%W5ù‚Õñ¥ÆVšÍ0E£úÁ 9yñ L!æµóúÅêsüº,Ÿ¦¬V7ʃ/×_¦e×y™Å­`UÀøu‰L œ2qïê³rÛÅä›æÆ‹D¤lQkÎ&dGSÈA£*ÏÌXÞ¬#Ït,&u¯6í){5 š±‰]ðh``*™ü•ãhé´Û]>ªŠ„#ŸŸÀÒÁ¿Yyoi¾:•$¡Ò/¢ezª=gD±¹á?B[˜{E—å)?Þ ïè8ø_µ“ãæºÙÿÅ‹ýkÄ–ñ—#šw¸<ã¨/Є­K–\Kfkðõ©Ìôç†Êîš`++õl ÿ¢XJÊ9ÈùŒÏËPÞLMúºù6j8–½â&»1¾µq÷”æûCäOÅ 8ÒOeÖ~A˜t¦Reú<|° ÞuWÀuã¾X°u¬PÄSË1…%_uáÔwÍi;ü»,îB°1—2N>cŸê» eÑ:`ÙLÖ~N?“ÒsO<agœ*V$¶è Tª«øhüMÙ‰ˆªt8"HÓû+Qž0òéäŠPœî¼Ž ŠM§’$HdŶ>Jwþ}KŸC0}âþîz‹Kn †ØãWSö!ù™#¤Aޤ[E» wþ{ë-èÀTI¦­ê.)Õ€_ yÍ[:퇻)w¢wu#Õ4ì<~ðM’^"0-ýò÷3žãËö¥º÷“c¤gF©­è– ¡aDŒQüW$‘äû_“Ü—¥åO>{+ “1vµ)œW0Îo‡â^ž¿ÂþÈ7øÿ°uN»¢(ݶmÛ¶mÛ¶q¶mÛ¶mÛ¶mÛš›Iæm~¢M›tõ—¾Sv”zfÛ-vÑ]š…8¹ò_³ÝôNÚ-)¤’¢ûnÀB¢¾s{ˆa¬¼hxË §“×ÀëpÝ£U¹|0F†­½M…6•Õû1üÊtj1ŠŠBãs'‡)†>ouì¼æs/‡ù²ìÞ¦xÅñ Ys íúêíI Y0Eø·ä^¦†'ØJJv­Ù\ÛÝj‹@’1÷´¹½'!¾‘nÓŠõàØE6ÈiÙ”}Ÿ)‚tÒþ˜:•ÄÑ¥+¼é ZKzävt£¥éÏt!„´u®B² R¿òó¥ìÒÅï··ù~Œ€0P‡Yø^¨4$ãÐE…rA¬¿C“+C¾4`6»œ‰;5¨ÆpÏ|ÔF³Êþ­zø·ˆ©üþµÐÅ ò€¯F{›É£O03y£"³³Bù•Ù{‘þIm#)~­4Xouͳ$Ö»ªa“JgÌrŸp£í oü·{‡`©B·ÿ{W÷íÔƒAÝh@€ó0téíSÒ Øè‘ÖFÁ—•µÍ${¸'fØÐ)°Üî¥^Ý«ÑFlvo6ÙQÉ5;aŸŠÜËìVÑ9ùdèªÃÐOlœÙ_ì#§û.4Y«0‘›°˜5èË›½GÂÛoË)P·ã\žüvÙ†z½ú f–×6É##?szs"ZA&:£¨³¡‘ÜNKHhÒ#ëäB\2"°ÆÌˆ|¸Ó: E³ØB*ʼ>Xº®"NOf’ÂÄ5h’¸@mÜ×ç&a;=àt< ÿilâ¸ß#‰A$ÆêêDC€`eªq'q ŠňÞÜ–¶~àÅru– #¹êp›pФtTùpYY»ÝN“ꪽä·lfê_ÍD°2ŠmEEÔ0e‰1O½8dNYO¾Œ²/,n›Åâ7q53ÓS€óP3õ›²kJöSÏïÒQý©BÎÖÀÉ*³×XÅùöî²w¹pMW.æTeÒÚÕS÷ô 3ó}«kY÷Á£„ð÷š.ÁS ª ö ~u­.½:µ;å`B¤=b«w·QýŸ;ÐÆ7š{S!“&’é† _ª±&/™AåÀ7Å D (ËU= ÇMú\ïÆB»gÌîjf³sáudôã|Vzã”þ88©Ív.<òŸ<³è OŽ€b°º\‘’‹³ëXÊg=ýý5ûaqPå $ØØÚ¼‘»‘@—Þð8E[“Xt°Ñ`ôYJº¨ã©§ÒàÍï:ÿ®Ö_}ß QÔ¿~ a9&….*œá˜'ª&jû¥¢®Íò}ÉOúýÖ¾åé•ë/vê„ktç·È3m¬z1àHi!"þ:oé$Ã(®º å¯ÞåŽ[±fà‹{_µ2[,öS=õkBÒuw…·0dƒ%$é‹U50Þ°>Ñ’±Þ#µsË ‡Y’#ÒÊ}ÀŒG±RtõÞÍ@)á†@®˜ö`Wñ|è¬.ècZ­F2{;èzLN˜Æ«~½Ò÷Xž3NÌPݹ‚¼¸ƒÕ±»C~¬ÙOŸ·“=Ê`³Òò@üUÖ²äFƒœõбÐrŒ§íÜuÍÖJÏÿlPrÒfÇ·"ã^ÑÂÜvTwRe/BÒ· Î?æMq»³V†¦óbÖh¦ h çð•kPà ÛS›sÜ ÈÔ¡/‡Ú3£µ¦AåÑ¡›±rz¦`%##Xc‡rÉX.ä·½`膈Һ¿o¿Ðä7£>²ñʱI"QÜRË €!¯¨.gþpUiRÚ]T`þçbÙ=^ssŸ.pæªÉfše›¤Æò`û/.bõ ý&Ae¿’ˆ1^­ˆ*L<ç­—¦ƒx&.54²€Xmº$\µ[Bùm[ÀL9”šñÁÇuÀI¶1aG³².×l¬N6b¿9Ÿ¡™å°÷”†os–* z~N~wƒbÑÚëq8:ü†ø6ÏMXÒâíò.S^úÁg¯¨j`Rªß4§,Àش蚃J††ƒëüæ‘“˜U3ÚšEþÓÁsⳚWš'@´tâ/ÏÖ‘ŸâÍ ì{<·¸´dä1(ö©¡(>]ß*vÙq€mÔ–¾µ®I$±58ž;š—¼×#sá}ôïûM u>U޲šÇ2pªìXFDØ)¿¬^¯NŽ·v7IŠ XñæiIÒ4­›KÄXÉ.Œ/!d(RwQ•MG\Ÿ‹?´4X.c©iÁNsýžB äjœ£»–ÇáômÇoû»ËrѾ½ÛÝß Äˆ„¹ ŸéØ«,‰YtÈ:*k–¦eÀl |ǿȄ¯=(Èÿöä_µ³¸-bxŒhÜ³Øø¥ÝºìùiqÞ©LêÅrIW5öp’»fÁ¹kºÝš³ÏyyÿK>2Yy³Ï–û Ïâÿ\œKz ,l(t©ávΣ`DÒ+¯Ž‹UŽçí²÷uÊ'¡„W*«}ƒ‹éÝPTŠéL8•‡Xêµ%’6gÅ·“¦6w¦‘‹^£Š\)´°ºþÈäßÍxeµÐ4˜Éoí[xv³eS!€ù¿<“XŠL©gÕõ£ .:„ëÂ0ô#IÜ‹Y¬/Xˆù“Ÿ³Ñö4ó~€¤ÑklSwîïo¬€pµèÎ.kÿÂ@ÓKB8ïJåzãQz‚ºƒìŽ~èÑÈòçŽ &]óׂ۬ÛÿŸFÑÓÛòŽYFUœ½ÆG3™Ø<í™!ØÏÄé/tñCdŠgB­'T`±£!Xü±£š7š\ªÜ¨ƒ-Yð¦óÕÉÊ”#µÕè RjŸúKTÄZyÞàVóÊ6è—Ct 7P£Å˜lêÄ,Fqg¯ ½0*e  ¤Ëa¶hC¡÷Iý‰é¢TôreˬZð·/)#R‹=0ÎÓZ¦}.$ÖtBŽÿÃr*ÓW!¬)ŒÅPìЗ¯±+ Ç—øˆ£T•Ä[!3zq¨znjÎñݯ»zØWsÙõIß«:Ÿigoàûg8TOxI¶À­a‡=lUHõÑš—lí‘¢ul•,hù×{´ZšÙÁl= » ïív¼ˆäpëhŸGîä÷®rlÙP%&ª‘äÆžíÑGOûÃtQâŽ[Ìé™Á£,Hž¼¿}©ì ò#GÆ;Ç!S¿€#œÜ©ñm5ý¾}éðÛÀ¹c¹¶ö𱜎VtYÉÓõçDú Åú£7aÕŸ«ÍC¯_ßo9Ù{ i°£=‘·>‘N*ß*ÍzÄÂIŠu±Õ ³{2<Ýs†]=!Û•ŠNPþ#•ý{жRýKˆ˜P(©vÒ°]M”R¾CPùB¾@½$ÿCÕÔhé{Q9›itTÚôµ²?R†ÉÀßÐOãAíârôøëZjÀN%Qy:±@Š›ÒEÑR+5yOÒÖ y¶" ôSFÀ†p‰ÃYFî zäqz_"RÖÝy—Û_‹ñ­#73šœ‰´@Ü5«KRG·jKÝG€Žæ.ÐCò±¨‰$e‡í9ÙOj-zU‚IÃ0œÇ>[åFx– ™öÄ’ÝUK5cåó(«N÷ œyu<i0uµ’žÏبÔn»êÌóõ„´ )Hó+ÈÛP³gIRS!~íYÝQ™œ}rø—,GÉŒzÓa 0û}¤ÌS2Û†v‰7dyn‰JîN¢R™@θ]ÙGÖKÑGÁ|—³-ˆ½fa÷кf¿T¾-û~ŸH¯pKTz\ç®C£`¥v©Ç1©ćx¼örÐÆóù˜QTºÏõ¾umÏS ~ß|°NDR©¬wu 5pp«fŠ"] øß%ñâx¥ÍÑ»êM±Å‚ï]NKzü§9ùx—n ¦Œù.€0‚”b Eæ«8Á7E†~ˆ;º¸±n¬w_=LÔæBìZh Ç8ô­(Èl~]Ëä˜~¸Ç~Õæ8N·jŸ‚†‹*–aáxŽ˜l9Õ2߬òYJw„þÁ!¥ÉÝÂ\ÀÓyˆEðÐ@— Mé¸ÔìÆ>m®ØýaéЇÚN[OñUëþ?g¬¦Š½3“Ë/P­=ûw±¦çšµ•ÏÜ»ÁÐdy@ÇzHþ0{L¡~môKƨâ¡ç³B§šµ¼Ð˜Ø!†ªá©Ö°Îf‰g&Ð5žd‘}rMKÍaÐl¬ÇÌŸ….{0çk ù—QXË.Ä ]{³öP 6d¼íbÁ'‹Æ’_ôâ¹bò¿ }•ÇPégÕ¾×Cäó6ˆ;JÜ“äþ¶$–Ä^«×Ÿ,ÒʰŠr=?J«‘oÙOÄ‹'ûЊ íïˆÝDqßIŽ&¤‡Áøn]‹°ðׂG€ØÝ™™¤> zXWJøÌd!Iƒ¬ù_û§o.Ôƒ\$D™Ø8ѾS˜,’µ˜rh§n³XN¬]›JVÇ»ÈáóTó^_CƈèøH2kÏð)1o`»üïa³ žzœ¥ÑªNw#lº k·lNÛ%‰ €ÈY¶/oß4N«úg~nbÒ9Å¥Æ80­œ”ïß…jÆÝß±Ð÷"-Òp¾½H÷rC:]~CŸúô.ú­ ¾£Êwô0Œ:,ÊúŽr÷J´Õ~¿Øä} d€JØZþc RÊ¿¿¾XÏS²ÇáB¨g+HüûÕ_cú@çÞ—ÉÅ«”Háy©2on³¯“Ù üT—CMðe ù4Z_B-K!#µ·õj>‡"žä¢Ž-Ûµóœç‘Z2iŽbµyפÎiN’a 1ß]®ý°RÁ*™™ãÉç%IçhŸ…âp~Ôœý@f¿ü˜QKQ–Ê-°ú‡ aW¢›¡m¢#„ô¤ƒø5öÈi…>.]‘‘½&ª§£¾jýÉü\üÇ߃Í_ˡŵiÜôìä®u­ÆvìÚœŸåPÒ…zkéïˆ#‘G*æ^ªŽÔ‘S€´†\¡…ü–·œJ¤ 5 r‹Ó^ë´z˜¿^vk÷2«-ô 1öÍD;xÚ>û<¿ƒ·:BüÞ9ìzøÛÊÔëœú,ý°óli‘2–% úÓÀá×±ÝÍIL0†ê¿™S®h³Uœ{\¼A¥G{Pjaú áK8}iÅ1ÔþU:"§ýîTòö1’ª(W8蟀TšdÁŸ? ÷ Ü ¹‰K— çÐ'£§·øþ”D&Ì|Y¯ó94¯K^6Õhn×°2åq«"4üFlžL!›¨öª²-yükÐä\þxÆ—lL©c½Ã$§’šŒ ]‡²g.h¥•ã/5.5~°Zf€0˜ ÝB¹Ø8èáD«ò 1PU‰º>KDÕ⳪L¦7¶ ìܪÞJÖF[Κ~m"ò9ÍÛ¨ìÓž¿ùÚ;ª–XUyù¶¥·Qq]*oj\-/°“ëh+€¥0Š_øn8ä¤X à±ÑéÛÂ[D£Êé‡Kõ¢|k~)Àä>uíݨÂÓ‡éü•%ÿº ÙÑžwÐ ꌩ/y71:¶ŽrÝÓ¹uijSÆ>–HÛ ­ÝÝïa ‚ˆ4 Ë~þ²•±ÄÞŒÚ|™à;úíÌÍøPn¸cÛæT.ËYÅÛôä¬>lB¢~icY±cø© de˜Ä³A Ss´õÈÑj¢äÍ-ÔYŸ5_žÒȬø&PÛ·–Ÿ<™ÖÕõ_aVm–¯YyÉ[i]&Ê¥¨}ƒñ y$¨ÞŸ|-‹|L¥¹á½]¢‚ÉæT܆±‘¤®7@4GCÖWþÙ¢ðø=/Ôë–)¶N”k, ¨&j÷[Sï²”õkýN‡…ƈëèû£Öët©ÔIâ_Yð¤ ñ‘€ïË’°Z߃4½åÚ ‰ë¶n\ã³Éø[!¯gÎRÚ® .È?‰a‡©Ý[†¶c£ÙRvj± ðOŒæ}´Þ‘Tⓡ4‰ë‰Œµ¨TðÖäDU‘½„±!MVD±8wEÙnN~YeY×¥: #eʼ:ZÞ½Ù£NN>êÔqhq@úp´ßÎ÷) gË“Hµ—€£ 1~I|CÎz™HÕçÔ%9õ+ñ²—µÑ8YìÔÍÊUÃvŽOf!ñÇ)Ë ºd" ™½rΣöA—pc†€A‡±vÕ©L[N0…H8~ñõQI'Z<Í›ž·§BÁË£ ¨´BüÉ۱öc¶ìVpsKÔÆ$ðãœ:¨2|Lã±›}Û¹f$¡8Ç`’Áù+_8eNqi‘΂U. ñï„ÿ|Ÿ.½,R펛> JV¦R°O ÜtVRÍP‹¨‹øç»ØámÑî±{4œ¾)ðÁD2T|gŽ„0ÉHñahð×G݃á’W”b™lmà`©_û®²„%9¦Q[ÎßÕ2Í$$ü*Í y·º6RÞäÔRÝÝ@ôéiÀwç(ê\÷45ù­°ê\À:dˆ¢GÎj©t 0bŠð˜á›¦¾Ü%èlY†ìxI¢¸~ÏïƒQЈÞUUe9y¨í½‹Œý—×`È15\‰Fù± Ú¶›ÑûºÁÔ1F`Í¡[û±æ!B%àËw °ýh!Ëå6Œ$ñÑk†¼)È‚‚œ q¯d<&G^c ¼A(À±ß‹9tíOsR¢Þ-Š‚+Ù^ Ò3™8Ž!•s·Rƒ–ìtÂYåuW¨^.”ó¼ªQWç+Çà'û`vB§ 6À1”’>ñ%ëY¡UÖMcíz÷È [\rÅ>x!=š£ï)%ï·ªVºi˜ñŸ5çMÞ‘BJà›Ë˹Aš„âæÈ>3!b÷²ºråÓØMÅ7•CâÐÅÄÅŽzfá¦àÅË#Ívéee óSi%ÔßÕgœhßQr(#'Ý»´6§áé1/¦ð¹¼<Á“õò1k–À n…ð`÷ã´ÌJüŒ»2a{¬œ'Gpsrâ)|?®é /Å~ûóÌïšø$XVMh.‡¦Ä¶›ÎŸ¯ì±éȤÏ5W~9ž"ï§!éו6ê nfQ¤[ Š›~ô OÁ~Ý–+E¼šÞ2K‡ùƒzŽT«ZdÏILý5ÿ%ùyV¹Ëüª´‹µ,9–ÊÜ‹©ƒVRoO§9:Ó&±Œ³Üƾ)vüù}"²š]ì´-MACº¬øù¡½i5 „3 &—°ïfüËj¡$¤<ñ¥ÚÆÐ –Ë{Ÿî fÄÆû×¼ÁGl™Ëø‚¨ç®¢gÌø70™`Yž¼½Óè.FÖ!»ƒ‚¦zM1x ƒ$×QRùå×!-¦ ÌT&‚æ~ù”ÚxIZ¹`;Ä*+J3ÿ™g#I¹šƒIÞÐiEé¨!ÿLÎ!Æó(Çj°sl­å)ñq.>h$5z;«‹ÓÃÑbc…÷¬¹ dU¤êLBPE™[å6 ×½ýñýÏ£AλË!aœAịäŸtÄcôµªN¨.ŠM¾ÛÒ=pGH˜®Vàø •]‡¢aÉëOÜå$@6ÃÃÚI­ žo>üðÂ;ô¡yf‰"4ãã<Ô•äO 5nÀÚûΜßTøÄMñ)Zó4ôxüýˆe— Í]´ ?-"$ãÐ2Vö$s÷gcm„;…âp^ïé»@Äé~‰§Õ ió—XŽü^ØõæOw RÜJÇ>¾ 1P78ân´§˜wZW‹¡m/4&ƒKhV²÷̤·Â¯ÑéysßÇeËé¹+cÂêääµi]ák_vÞnÁçþ¢ž­Ì.bFÓpÏ õ{&ëF£`÷SʘsÌ¡AGœh<¾¶ ;ÑGÓ¡{ýe_ÕÒ÷ã.ñ½Š@¯˜3¡ :&`Šø×–W®—x?m±ÅAƒ€ŠØFHÇ™B”+4¹:§ & ]ivgˆÆxÒéä¿Êh€ÙKZM—LCb¥Á—©±Ogóêž'þüIƒÂÏ¢z(0ˆø¸Ò2a¦›ã[E[3mtC¤ë–îöÈÚQxî›#éÃIü©;PŸ»#²L&Å;$Ç– Áÿ‡ÆÔ¼zD\-ë}g‡Aðñ,»x-££QΖù±f3* §õ·gQóîøn©€0ŸÊDÜÓKçˆv|fWŽ>Á““¤´)uã‡30gG‰[‡õâL¥Iƒ¥€Œ_r;_)ü•°ö¾[e÷òNôïœe+­èòcbëÐ|ãHèʃ´´ÏíÀ8,˜g)“êþ:KÑü_Ê-%ÔÖ3SPwIBîú—A: AYDA- s“-ƒ˜€.”¨Þ;óJTx~ê–ÔèôvËÐÐ ËÐ$=›P>Ø•}¥éô×$$|ºÖˆ2W ùMÒ¦SÄV(&ÊqVЧ.Y¶ÇG—| ¦z®¬Bùª¸ö—GLì`P'Äô¿R;‚`ˆæî2Œk´êñt,ÑÍYÓ#ßÔf(‡–ÒÕ,’ 1ç‹Ù-xC²lwåñæIÐÒéR“+àE ЉÕm–0Vg·æ÷‡ª¹G©vû,ÊMœ¼ü«Ätx}¤{’ÿAņ„< ^2tÐ5Y•k}¢ýÕz+È?Â[­J3VNÄ`ê³qþ|Q>ï)ÏD}Øè±ËÅÁ[×NûMÃ~¥œkµ†Îפuê¦ Éÿà‚w¿aƒ°ÕÕ¤érÜ.§zyÉqx½)ÞT”ðµ/±GH¨÷ײ4}$û€¨hC°Ä W"P7™ ¸çc@ä^ŠýÓ­ˆÐnƒ©±„+.«Ú‡ÏÁu…ø~*êø¾¶¤ßþÌâ¢\>¾!6¢ë&èò[»N¸¶S¤³xóìY'ì:j{ÎÞvP³•Í”j3š×Hahf`ó{mâ¿60R¾º.Í_*FË|¼‘þµjìëpè¢Ï¥bÑW&Ò*$ɹ~¦‡âQØÔhÖ-¦SfæU„±[`ïÛ0e­m%¤:'Û'ƒ]‚IÃÒsf‘|*æ`=‰†‰”ÑÙG z9x¼¢IyÒº³Å­zèà…û¶î…¼ÄBUNÜ;^6eÉ·”k¤ðì»hPÙ(¤]+ ÏjÎö¨"ˆköæ¿ÍÄ^øžfr¿ˆ£U>þ}U‘‘b•ô½µÖ«W—vyR(4ÂSÄôíÜJØmÅ$á«ÈÈ>–ùÿŽ ›hi€‹`‰g ˆN–¼2qÌHBj”g¾ù«rTÔ—-hçê ¹û“6#S2pæŸÁŽFS—lßElÕÐ;æ£9zéJ³‚_‰7o•P ÃxÕ»à&cb hPô©]dngBº7ñ “+"ð‘=Mæ*@àc¸I5'Åw‰ŽPk•ék¾˜³â¤¡¥Üß™iÇëK/­¸|WÖàÚÀ×ø|×롇¨2Š8ôøš\;g%âU3èÿ¥Í#n¾Þ`í_Ÿs9‹’8ºŽ2hOÿ Yá™rÚ†Gs‚4ÁÌ …‰+êòI¾iW Ùµ¥7œ@×" 2¤7Ž­a]؆9*£sáœFèL”×ñÙõp¢Ç™Dñëo3¡£ñv ÌĘ'Ò^ í^–°‡îå¼%%6’ù—œý.üßýE›PË? ×ï½ö°r¡xˆSkC|Fñ žžn!£B[óÜåu¿ˆÆ¥?¬ðÚQ÷&gÈPê¤*æ“Vk¤x ¢‰@öå›Þë¡ÍØBõ8ck}Á®ŠE¬ä\’}n¯À³É²$Š]û·"^™2zW&~?àîî#×ì^Ìé5Lk"j¸>QU‘ßi£A ä –'ášÛÔŒã„ÑSÅÙÒÈY¡â5c#£#áU‘àrö5\å}ÙþU_(ËC îä4_!ü†r†z^p¡mñü`#(ßr¼lÿá`&ÖÜ7`ATw¶]ÄDq!Á—$ôg©N?Xª‡õà;÷šòý2œåƽⱒT½Éï®û>à^…¥Š(µãü"Ù>«)³ŸùÁHÇ;£Áo-ˆÎr1V|¥ °D”Mš¦‘Ý]2Ïö;á: S㹿9£ê{OÁì`Ò×:æó#•w¾tƒT•=ª„Öø%Ç£¼r…oÍNü • ϯ{xž´ÂÏÍ'?nPtâ†øÉÐ=ˆ_4Ë€î¾vù ÿ}ûcñ3¿µœqkÉÂXˆÛ»µÒ2Ûlå—Áá\~ôhdY›vãüht@DiwV¿†ÿG-wvˆ¾hh|þ@Z"Ž×¯  ëœÔ‚«ÐO*¦J_mlÓÌHO³ŒCyÊò3¹œ«k58xÍEa#[âøÄViAZÝxý¾ Ø·â·¦£Oz•W»Í²dÙù ÌlOÆwîÕx.83í'uPdÝp SŸ[H•© Öè¿à@çù^¥½o¾šöþÒç÷SUô•KÁžý‡Ïß)ëO£‚Íh‹c˜ñU.Œ¬,Å…:ÖsÅ @µ}«ŠO-bdi÷ÝŸ9ò]!þòñÍïJ-];Ørqаkš)öbˆ—.‰#ÝÁž{%W‰Sa»’œŸÿ$[ZÖÛÊ(ip-úÞ»8Z%¦ë¢Ÿ*nDz!E¼±¤Õ'píF1îÌ B]Gõ\"ã.»GX³Â±·0ƒ06„Rèô¾™ŠËÈ#– 3Ó­Lt·‘¤ ìøGÀ°—cíÛ¥‡n‘×79Ð×QÓóõ8ÀÚ”{êã„XÚû c¿á<¶›·æ§qXƒJÑ H¾­›¹½«ÀVuÇS˜\È]ì®ñ¶¨Åúnjk²ÓáG­»·Lõßæì1Õ’Ï"]3Ö¡–8¤íB}=À¹·~ˆ¤ú̦ò¬LÌH'§‰×Ø–óʆ³³á/BÒYöØœ†®S“¿@˜:Föëo'*.%‡'°ÉN«Ä¹—`§cï*†RÀè Q"†¼ö^û¿5YÂäý/Ÿ«v@JNXHéŸôT7ìöÚ­Ì’¦iZ7ºy<62À(L”GÚ`¯ÐÕ6=ô]k:R.Ͱƒ?~“{ ‹wm¢ðÊ´eð‡üZ¢«MÇfJ£Š».XnᤸïS]*äg®b÷õ%0|šõ›0y‡d’@vûo—é~°´àb@'Xþ¨FZ·Í”pEd°æ"„E(z’Q…ÅæPnÚIÈX£»S†sVˆ)K¯IÃä•Áo*®žØMÏÊÂ…ßaÖš…ÂG¶¿€öa7}½q°•˜:Óe 0ó¿a ¤Ïs4á³~[BªbŽÌmÂ;j¡Î4Û×IûË áÀ¹;Õ±•þ 6˵Ç;rêð ¡§_Q8šåž¿´ùPµ$ž90T ¾Uô_ Cd\ •pjÚGV®ëø–ÂRÂÞ?Q °©§Âû°5aD"]4µ±~H¬·æ;ãs'rMµê ñAcZ¶[’—Œ6ÙÛäÅ)J3qB¦‹wÔlT̈ω[©u_ÕB²XÈ,Ã’»¤ þô/ÌU§×9N+9 ÒÕÝÛè'«ýÏ»F6 Q4ΰHšR÷\áhD¼ûšaŒ§++§èòñÑåÚJ[C«-M6ªòc¬àI¼Á-‹oûVîX<Ä,¦EÙXçÔºû+Û»~uÂálÇlw”'¿—Æ+Œ - šBY>ëLz¶$æ*á§õ.Y Ûç°»‘'Ï¿¾X—ì6 PrR?–ïšP’ø« žùez÷°Ê]ãÕÅé¯\󣢞…þp)ñÈN ¡Ewˆ4mhÅ…¯vÏeÞŒ½¿§×ox%÷Es-=b–ðXÈ Çϧîú€õR«—·H ¸$@ŒSy·‡XTH9a ¯êé 2GjÓ…/€àI}aòöÍB²Ý ¦þÙËÝy—ðá'áÙºÊÁ÷¨(‘(Ô˜ó¯v«lVìüR”ä'6´Ñ5ûH·.‘µx>?Æà‘Å‹!)Ô)ìæbw[)ãþs3gD†ÁÎbœÏñ2°ø:ƒL˦â½þ—ç]i´DY*"Í÷ÃY‹·X‹˜P»OVþ¾Ôõ½ùËŽ›âñé¯øÑœ:‹ÉS˜Ê†®–"b RŽE踚t·ààOTŒ]ôƳ]cÚ{iÁt¨‰T ]CG«FÊýtÍ¢ŠñÄ\øPƈÜëG·š#’6·©\q¢Œ=ð4áÞ×ù(ç9Lݧ¡›íŒ×œGÏv5äÎè¦uZÓîëœxFÈ~Fõ@Ä ¿C~*a†]Ÿ°¤äâL!Õ&‘X¦"ÐmãG,Õ,Rï±cØ \ë´ÊV›š¨¶ "7ée†>Ê™/‰‚ (¡.§k*›¤ùGdþeލH¤RzÝ#ÐÞùéŒ!rdÛ›|·E;¦3UÐÚ,ïú :µú©7ƒÝ™Ë å~PD2½åuŽ ã‡-нÇ?œãO ä0]i9ŠÍ õÄŠEtxå¼|¶²ÞBYòöêµÁð=/MĹåuÚ6b“ŽV«")9s…©h0᩼T™[Å–Ÿ¶ú¶¼é¼Lh¿{¥ªIÈÇç˜xÆÆÈnJÌ˶} &¢&3íÈ3+âUëÄõÚÄ(æd¶8ïì—›uö…X}‚H8çû:à’œ%ÛV“÷c†ûø™Ä÷ök³ôê5˜Zgñ|LjtS?·*b(æœöˆ†F|Gûyº6µCßø<¡¼Ùí&_–MÖŒ­!Ñ ÌàŽhÔ€ç!9ÒJ|NF Ê‚«Z¤Jºn­Î6D»"¢ÓTó0fæ´¤†¸Áy…!!Ц±Ä¼c…ûÃÏ£0аOÖÔ¥]9â"IfχGQ<w*ªÓa˜î?Ï3F1Mºî˜1>*@Þ3½%ÕþnÆÖ_‹ê <ƒÕÇøƒ†P+uí9(Û©àþ™êË"óMøkìv¨dêt`ÿ%INu]©çœÿÊ àÝ]å(,hš|5Hµ%V-¦uÕDì±× Íذ¦ùæ öÓ ÇÙáOŠŠ´Ñ¶üò¾ 8ˆÞ]V=yâ¦2"rì}ÖªîO ^ÂÍÉ߈ε3–Õ4Æîõñ¼ËÀJñ¸$ –¶FÌïûZÆÌÖõb² ðkåQáßp‘)—ðøÍy†(1p{nuœa†G1v8¡Uí’I£øšÆ¾ÏVÄi«·ÿ’-F³‚g\Ï5µ Y¦È ü铬Ë=Ù)Ç mIø;fßéoÈ}Úéï‘ð8‡™6`lÀG±2 ?±õØâ,]:$ÐÁuõ×e¡01ÆŒˆÍ3©ÕÕ,Fžx™w§¨[/QÿF/ ‡E¼£mˆ¡…"œÖ˜˜eÆj^Ý:VÅ"}üÜ:Øöªwƒg‹‰òò¸]™Uß+¸©Â’ÖÀº”Ý»˜±îûâå°q~"y I÷ñqO–@C ²Eï‰!³ N7•býô¼Ñ&;+Ù\½£Þ†tDüþ\iùùùõRË~Wsÿž®ôoÏ*'.0Œ­ÙÏ›žÎë>âöÛ£¹°¥‡fºÑ'˯Ä៣¨£ÅøN%¿ÙFU4 FÒ1w?ŠO]Î<x'§Jcø âŽàhåÄ®ÃÌ9æÐd²4_†³?©ÍYvÇ„)p]Ò+2ià~Y“íàÛb±z±Ê”×ÒÊ ê2‘ú„¢1qà.1ìß¹=´ÐÄ¥šå]½Íà&žOë”}Õšêܪ|”œœýÞ†G²!q˜ÖÂô»:š%«Ï¸J×ߟ’v…¤dåAÅì}ªz`|+åŽÎ©êæ‚>)ÝÞ祟] и´œžñ\u‹ÈÅZ­PÃaξ‘ jò¨¶Ëùíkeð³<+ep,Í<“b£Uþ´¸1v;ôØRŠm’?~ ®ðf.‰gÍâL6Òi&6ˆÀ¬e‰¾#•/”'2l´æûi7ÔŠ{‚LemBÿ t›sm̤Å9]âC—Ùfá<ØtwvXiTðÕ>Kø]d@W ñ4øÐ•!Wl¼•h(À°Qe±Â0L„¢BŽ»7HÕóIì‹E4êš@À)°,íþy‰+dÂØ½ð¼ó¤ÿÝÅ„èÃ=¼UÀêæ'·¿Êàõ¬¹ òrÍBè(€Dauér{Õ¦l7‡ƒŸ­_MJ®Ô(p8 N€8™!ðÓç(yj>„ËÌæ¸Cq.ã›/å áÿh³Dtµbž›Yÿ_ Wno¡•¹Z$&_×¼Ä=FÜZÄV‰4ÝF€ëO:Ö=ʯö(hîû6óæ§O„Ô¬¹ÛÎYØ8kRªB6®A¤àínÓ»Š;GñÒûÁR%–mŒÔV%¼v`ô™ë/Þ9Žo\OÑ:…;ªÒàsŠŸXÔü÷aP¦)IßmæÒ´Í${o€¡™‹½?F Õ­8ö›4ëÛ•VtEÎÒjÈ™'R9ÎBËÞ´¼EüÎùÂÉÈÁÃl®Blj—è‰Þ5†Ý:N{7S|ÏÄ Xí_¹Oã¼$>¢E½j÷LwÕ¤¦öJžg!Lã"6==D#?R/÷RXœ *o¼ÄY ÿX9 8¤XÁÀÿú œÆkU`4™S§½ÅJ¶×²J÷÷¿Xa¯]P°xu€|©Ÿf+¡‡(þ$“–',BBêþ§ö4"Ïý-)²%huŸÜ»Ùh{Î[`?[ÉÊì͆`H:È.RÒþÒDØŠýý®'¾žÚ­=È£ÑVË’³›;!jE¿^Œüt¦š#¯¢ÂÓÁ+ß¿‡µxóÚÿuX£Äð²Çp—/+®3’3ø@¹OKáèkû!õ†cÝå]¨ÕƒQçvù(ó¥EÿA퀩à‰W­á‚8€¤H9"m%ÝÈ&?PS ÿkê¬=Ið `©t6r§¸ßé`‰Œ¼â§]¼ðMëe3ï¯ øÞ(ÚÈvÏ”AÀ>£¯7ó”‹¶žÌvëelœjÒéÁôøƒ§ñhwI!¾í"$’Z ÿz´u¥%ŠttÈ–‹— èÎØlG»Ìš˜€#«@!5IDÑ‘vÒçE³A®±Lÿ«v©´gMµkó5'ì`4‚õ ÔŸqrÖ ,×½‚QÍ>a±ì4£¾¿C¤åmT”&-Í _£ÃõŸŠDa$¯Ú ÷*6QŒÅS>·P6UÞÔ(‚k‚2ÔÝœuëðxW1ÅåR)° <îüùC#«*Ǫo+”7‘È=Lx‡+šnÃ÷w uüŸ4ËývË|‡v>ÂæiÙg|[tz€üÕ24Pü]il]&Ql˜†´“ˆÀ¡„Ë%ݯz³ŽyäqT WÉI„¹ïׂLƒñ×ÕÅò¹èÿqP•ìùõ8›/Í£íCEqF9øPÏÃ*íæš%º±+S` k]KŒÇó âpÏÞ4ÈGÝqLæîÍÂIvü-ö÷¸C‹Ž“çÍš¢Çôºy”^Ì­±hGÉ,ãþ¶B…¥ñ;ûI_¬z yçÇ(Ø®ä/V.Ÿe.Òìþ¤TÞGéë"?ý<à ø1XkELÏÞþnóØ QšÍ6/öˆ„رÚ41Ÿ´kBZaª¦R~»Y¾) +¹v"U+ËüL-”_dsóvAv¾$}§Í·‡r’¾ÀÚµ‚¢Pw‘X¼ÿG¶sCSAã8gõ¹}ñGE<Ùa»`i²´b¯²Kñ¿ã<:4‹^ðÞ©ø W›`]h¶°]b߯pdág¤]``ó endstream endobj 9828 0 obj << /Length1 2767 /Length2 24614 /Length3 0 /Length 26132 /Filter /FlateDecode >> stream xÚÌúuPÜ_ò I°à»»»»3¸»w ÁÝÝ-8ÁB°àîîÁƒÜI¾»›üöݪ÷þy‹fžîÓÝOË9ç3dDŠ*tB¦öÆ@q{;:&zFn€*PSÂÓ ¨ t²:ÓI¹ÙXš˜éYaÉÈDœ€F.–öv¢F.@n‡‹@ÁÄdî`fdä‚%Hí€N ¥)ÀØ t1Rõt2(~E{g:c#ghgni¤™ˆØ;x:Yš[¸üòÁN÷ËÀÌÞéÀ/& ‡ ÐÎÕù—Saz€´‘‰µ½»³µ%ÀÈÎ M/G·w -”övc …‘ÀÞì· 51e€„²‚š¢ =@ÝèbgJ 0±0r22q:9Ü 8F¦¦ÿð–4²¨ZA/#; zEW{§e%¢¢ª&A ’WÕij*ª´yUð·æ)Ѐ”©¥Ñ/s91U!U-E1&†_Õ0Ü@1-1ý¯tÈAÉþd25s²·ý@iáââÀÍÀàîîNoîêìBoïdNï`Cõ+€ª…%({'kèÝ hü]bW;SPc\@‰üvð«ÅYKP-¿“+å„ä¥ÄÅTTé@Õ¢ûUpºzOïâáò;e1!Q9±ÿ¥þEÐÒèü»_¿|™‚šliãL öÀÔq#PP—ÿd jŒË/Â6ÿp8 Gÿ;=3kg†-ufø• ¸‚¼*¬”ˆ˜¼ŠØo–öN¸¸šÿ²ýeøJgaäü›²¬¢¢,ÀÖÈÒ4uFv& ~.F.®Îâß2Ð hJüOÑW'§_©Éý[åôŸìþÝa{P:º6Þ>Fîÿ=¸Fv®Î^õûÿ¶Ò4ð–Î.Îÿxþ«Ò6 ¨·–vÿÿ{÷Ëà—K!QYÐ^ec0ƒ^Œ ],fg*bok "î ûk*D-Ar±wòdøŸ›ßÚÎÞÝÎûëÌ,íLU`êêÀ fgéè ”ý—HûGft0€Ž ílbÁð+ìïÍðKÌôK ªˆ·ƒ½ÀÌÈÆèci½Áz;¹ÆÔÉèãý·âÿ"X&€©¥‰ hëƒNØßÞ¥ìÌì\ÿˆALþ­ú×Rþ>Ѩ@Ç™©½'hpÍ`äí]@ãBùÿõé¿X‹»ÚØÈƒPþ¯ý÷Z#[KÏÿßÕÿµLø+}Jy{'[#›ÿÒY:‹[zM-]L,þéÕ?òâ Ù™ÛtLlÿÕ~A6 }:ù-] #ãé@#obmtv°³ÿVAEü/Þ †þb `PTסùŸÃø{©˜‰½©¥9hÚÙFNNFž°Œ  cfcx3ö)Ðã÷èíì]@&WŸ_ †ý5&ìl¡_¢;€Aøâ0ˆüAœÑ?ˆ À öÄò"ó¼ÈþA /rÿAœŒ œþ fƒòÄ `PýâÙý‰Ò¹üQ‚ÈÿA 2&ÿA¿*Î`úd0ÿ‚ ˜f 3ÈÖÌò?˜åtûk= È›™ÍŸ¿Ìí]þr21ÿC¤7ÿõØü{ ˆ½Å +¨Zž@»¿V€d–APòÖAPº6AgÛ? Äð/WL |íÿ­µ·û+&A‡?jP¯€N–öŒ ”ã_Dþ¯\@³ÎàüÇDÔÙÆÈÙ⯠—:ÅbãbáüÃt*3¸¸Ûÿeòáú§™ ÿ¿¯rg{§¿yƒjàöååþWAN=þ‚ ¨žAPÎ^¿áÿÝgŠ¿î±ßç2ãŸ÷¯‡–ßXÅÅÉÞ¨ai zôûk‰œ‘‹“¥‡#èPeÉA?ÿþ¤÷ý¹þ²¶÷ð¦c;3h³²üúÅÈÁèólMþ¹kè âßø×-=€&°‹sö&<ÁV©Í¡e¾b“åoɸèO*1ø5¥ã!Ó'?ãb‰æn Zý3È íe%¹õ|“ìŠ5É‚Ñm^ÖÚ’ª&®M•·|å|qÄ„¾æ¨Ó«fÈ-ø—wSJçäk•°Ng´Ç·Ô¾‰p}î~ˆaE¾J!Ö-o_É{ë^4ÃÔ‚ædƒâ±€„Ó‰»0Ù æòú€mÔ'´HýÝ0?ã«ô;‡ÞnÔ½ìöþ-›ï‡bXyf=%ưÈdg×­éÓ¢"®Õp|îÂh̳ÍogE8ÝrB£Øx.’HŠÆ6÷¯†º­ªøQ‘Ÿ¯ÎqbQÁ !Á°Œ¼pàŸ8ß14r ÉEO~âxš‚7r-¼íô-”ú*¹`¥ç*+ßöáð»ÜXRÿ܌  Vò²±êS0Ûîhø Éܺà$=RvBÚ•îÅ3¼Pðu“:Ê-‘t;ú|ÐmÎ2rÙWʼn‹ÝnÒŸ€÷綉p”רaP/ÙÂâíåH‹Ž6¼hûö÷—¯‹ïÚ¢f}h¹¹Ñ¿ ³úÝkv'rˆªd2Wñò®#ë4rþKÕzöAiÿ½/ì2±Q~t›…á¶Å»­"Kn:x¹ YýìŨ9êj˜)J¬Ή¨ž~ÎZºc $ €ÔôÊ‚†˜Çâ—Bõ·ŒM$Zä<,ú‚Þ a+Üê÷å¹{>QDj,7sŸ,Ï$9xæ6h,:Ùk0…y³ßè±gOÉDš€v–»…„âüvë}-=œ`:K©Ã¡­Ç ¶vuð犫*aVN3#"1§Ô°Ìj±Þ'g+·žùh)훘ŒûÂ*`Y‡ãQ¹ßC¤ô÷úÔØÎjÛtªCFm'qIÕ},¢~…Ö4â1ñÃ6’aVQ”£PRÄCÞ½¹•6`i´U¶F ¿Y´æ¿°IªMóEÿ¤ <#f^\­´ž)ÑA.ù5èÂËæ4ˆ:6ØR—(Ü“X<ÈʴÓmÉÙs}†d”êY Û,E‹Ô1ÄDG‡Ð îTî«÷6ó=‘ LMçŽw£½êéüüϽfºÛÄîo~“Žšã£„HEóºQà?E„NÂ4k8×}Œ‚Ç Ò§€3y'c)ø=êí×®²gÜê³–¶õSÆ$ `=ÅG /fåýø»\¿¼7ðe±Ú·Qdêïy6ôŸHdŠí²‚otÄœŠ‹IŽœ<ïÔµé²HlrRj½v™™Ú ¥ÓOG2'Ò L­‹9#,!>Ö”Åô¦Ý}vÀ3C‹ n×Ñ…«f`cÝ»-,œØ×n¦ŒRÁ׃ö` ¢©eÊÅðIl8H‚¨…¸±@Í‘YäP;mÇzŽ„öxµsÉÛó—¿r"Š\3Z"!ÐCH«q<>½¢ VÈ~!pƒxº8gùXCÎÁŸˆFVÊ"I*mhG )X úM2d؉ÿ _ÍqbKñ½g%E`ׂk¼4}ŒÂ÷¼RØ’ ]‹a'š‚:¯Å×âpŒl£ÖÔ$»«ßü}Õg“ZW¾Ý)g'%€ñÁ,.KËÆøæî.R‘=—tó jkç±hp‹³+ <ÛâD¥ewÏó¡SÄŸVŠá-œ ã¿ èÛŠý”½+çî7Q/ÝÈË8vúüÍQú¥pØ6k›u¯¼‰êýÙXÜÎ|Bç¦MžÎêe¥J‡I¬’h1­ÕUh>Ú’ÈHƒ£G€ð^­CqÑF3òb.:øH^?BÖ¸¬bGÒf”ŒVœv‚\© 5©=Ìe>^èÐoîNË÷dÈ1ûÓ@Õ´ÀY3´h{yËE‚(JN†•3­Ÿ'aHÛ£êG¥¡1-U«¸bUà¹XIšE—Q¹â=k2¯éù÷r]øZ0L3§ έàƒz·`[ÇfèvbzkˆŸ3YÓÃÁS¢3­²­4c1¬ÄSƒÏuŽÂ5`©ÈA£1Îù æÌu¤-"¾ÈiоžjŒÂG|—*ì“^’òYésmp< Æñgîd*XÔŠ\õѰ1J鄨}¯ªæ‚ù&ª€ÌRÌy1¦†Sƒr{oaCìY´µó&úž¸ØþhI*Ë›2ïôõwÛqVÐù^¼Ú}E•ñ®Añ|¬²>Öö…(ó÷NÁ1øC :>lp2Ûý>=<­‰iâÜ­D‰¹7JÅN½O0æ£Ôôi7cˆuÙ”¬ÕuÓâÎF,Vœè×Jš/]ò®Í«T_P5n3GGE—òBè¼á(w¦±ÕÒµo>„cVÑÃBªOAT˜Ø¨8gÞÄht¥àepÈ¡4I™ˆ– }ºV•D^ˆŽ!õìr“ðU2 :º_ÅãCë}cœ.áË?¼Ï*éoUo®‰ÅRB4åR¬£´}P£”9q8HÑÿS/Õñ´Uÿq\„ÿ» †ãÂüuvZî¥ØP™}üÍbùS§ú…¨¸ç‡i(•Ë”ò jÃ'° èÙýSßðKL—ù`çdwt[üíX0«n »Mn¥{¯I’™°¤’ËX-®ÚÏP<‰>Ñ¿D›—Òù¸š2ÀìG^P¥I6¡°Q¹ÙªnÌ7ø¶)ò•g8SY&ƒøÔ¯¯¸ —±ŽŒ–²–’¤¶%Z”AqÅ-éœÔµÔ:R'0’Œ?é"Èã±>Ý;p £ûCì†öÉœ/c/£Ÿa»Ø=(¶a¥;=fÑ:õí&¬||e8Š©|$êÍnx#ã…}–ìiº«{Å “.3†áúÑYTñE„º<ñFÄ·«(×4¼ä«ƒ‹»U¿µÈuËU¬a2]âvEØà± '–µÛòKZ\ðqzw­ý&c\Bš’º³f4ª¼ wñ Ë÷ê”s´£¦VѼÃAÁ£ŽwÃ'1dÃS4&â]} »ŸüùT!mF‰|Vzs»ž¼ßv…L­«CU2“DíL/?)ÿ´à˜¬±¢häμ+qÙ¾pwVìJxÙAl­ð Ô.’#ÅùÙÝ5Éf¼jwÀ9ï³ü“ëÐmÔ† ?xfÒ±W\7yCgê¶"³þT‡²êýEI¿E¨pN–ÃÒ{µ²jL £Ñ|É·µC "KñÓx-…ù¬/$Ï0Q­ ´þUêÑñù¾âÔÓ¯/*w@;ÁèÕHÞ@ôÙ¤Á6äã~6þWá*‘ «ÞéÁ¸.èM*Rì‰Ñ¼œ§TsJ(ÊCgìšj¥ÉÒoóîS²ê?¿6y™Géë¦5‹(…“Å|IŸÌM çMƒòº‚¹M]ˆ˜d1Â\³å°¬š°øO#¢u]˜_© HBh@i޳ú~zrSßøÝÿǤØVpÅÃ6Ýs µÿÄöÓç½Z)_i‰ŸM™‘ÙßÁPÊÏ)‹« 8^ñà¼1\s´pTá¸K¦ƒãÃyBj>z‡PuH½Î‡æÖìmß¹âðîNôÜèõ"3aжx™Ëß<•88åœÃôkÕôÖÖ:k¹¯€Ç›^yÃí>BAl<º÷ßÌ‘±#gø¢|ÎãR¦}ølûjl>ñI)VDŒ ý«H-TÜI¥ã„߬ªpyƒc{Û—ZuN¤Vö¶~Zñ+aM~"¹¡¯Q–º³>MÞ­‡tÑuñ˜˜ Óû®_E[A.z¹¥ws{®£?u¾Š´öSÌ2ôÊ¢ªk¯«…QÐZ+@Õ;Ä1Ê;[‰±*BS-A—czÅßÛ*¿œF^ÕÌ»=P­cá´Fûð•XÛªÛé¦,;Ø$8Àë¹™BÇ5A~¯;–%Y‹. Ûæûª~åUæàÜp^WikS'ˆå"T;ã’MùÓžåÂ#QuE:ñ´¥ùBP€IÄgøsòç;CZnÈ[T?È%ºW¨ÒS^Ãhq){ú7µç[úÆIh'­%ÅÄ€ØÛe4†¬$© ºt]á·Ì›Ïp²˜Ø*éšÒºÃmÏw>Œþ_ƒ~Ž•¿ÂÑj¨ÔÇAÉbÝÙ\¦^›r—s:Ô?gq§^µþ^1¨@¹“Ö”õuaœÌÖˆ4S$^—ÁXžc,Þ¥¼;vÈnöé’ͼVb°AWÂk‚“ì¹öõ2®‚Ä‹W|eн‚ R½}Æ[ŒànqË}‘³®ÅDØ©K-¢œ! vÎî¡r/UHQκm±Ö[Ü:»î‚kÀh¹ösßgj™æ‡î´áM¶4¤¬ â—ª+‰Ï¯Ý…ëÛÏÒ‡9Ú!ÉGÁEì}¯°£ß¨Y.‡Ôç.xå¯s±#ƃe'¾ïÕAž"œ'rÆK5‹Æ›-†v;^~0wž¾·­Aì,›Þ¨0cÐÕ–¥,{E®ÊÏÐöÔ¥ªÁÔ,ðè8ýЈ(±L_Á<úY ¦(J1âYGSZêª8Ïó;ªÐ0×3±›¬·Ñ5¸UÕæcå¢òÐ3¨‰…—…îeŠ7ž` z‚êb¶{ڕÀŸ-¹sñ£pt·l©¼óEå¦jÏ—nÍ˰0‘-Ì254UZŒþ lLÎ'B !,€F QÜ”;ßaùÞšp®ÓbB%g rl`‹±ÖÙC¤QEYº•¾ã‚eÂÅqãvFj¨¥(¿±ñŽ=Þón99}º$Ù»˜;e0Ô ÄÚ×ÿVBEÈÐ!mU§[1céžMáûQ'Œ1?Ãd0/^²Qà%aZ9SÚA8^ºLí@´yÛvñÅ~LJÁ¿`|ÕÑÛ«©bd3¶2ùgx,I¿?¯‰Þ>dßšx5äVO¹¼@Þˆ WŽ7%Ò WáxìƒsÞyžAÿ׺=4,ㄹ1+ËY|­&ã6™Dõ´>í¸(¹þ‹iÈM8¦ÑW5‹‹÷}´ý,Q1ôÑÝMšO.ÑÁwð…-Ž9§ð–01{x…zj>Å kµ®Ù)³rìe©”2¢UN% U£|l)¤‹UÃZ;´[!›´`àZÍÌ‘ªìê>Vt×6¾×ÀC“†—ÓÜ)2•:*iLyj±´Â²#±Ë¦±b2(É&‡¾‡!'3€ô5x™w@«Ñêz¥~ȉ';÷X¤‰˜kŸ:£?•ÝŸ¢ñ[EÓáHü+ÒUþ]d„­ø¼rÃGøHÒ«Ù0î…û s¸”³`9Ë\f/ͨh¼¹D×Ü:¡[Åòi`vÆü«‰ÌÏ©“`ÆcQˈ×\3èw3¹Y·þŸV¨ÕR¾N7­¬.»éäßuo¼õè°Á*X6*;Ӷ̱o݆áÈžg…>ó9}ÿÆŒá+â²¹jÍ ˜ÈÌgfh‘ÂnÆjɪk“ ñ:àsbø‡·ÈîJÖÔý óm5 ×þÌhxŒD’aÇ£«‘Yd¡–ˆKm;óÒv›»>a©%û›È§ûˆ­Æ%ºÒ`DæÉWÝùæ".•¥ ˆl˜ü­Ó$'ÞÆ}å@“p4×í±mÓ¥d…Uöª¬ÖÌMoôð_1 o~ RÔT|™L ‹ÿ° »ŠbÀY0Äî€ÿ^Á ¹©i –5–Ù€_L3Œ:/¶²–ï´¹Òé ËëÓ0Z 3™ÉRQ¹´þ5Yq!ÊòäÕûe9ü²]érnA—¤ &ZÀ„“ørç´åiá¦×ªÅ}ÅuBÿ5ƒXe8¸dpÖÐä:ðÆØé)M›¦;Pi—m('’î>~ëÄÝ5tª7eÐòþÞ`åœ:¢ÒÎê£c¬†5-£ž}.Žõ{÷t,‘’º}¨0åEÅ-Sk§/|7MA[ _8ÄQõߤÌÍê(Bk½†à÷vñž+ÂھΦ³ÓmÏ‘˜'Ï\\l3DT„w#­ÿ¤|n÷Ec¸9•Þ7ÿM‡üaBfæYàñ¥ÿ†ª@‹†Ôd ¥3=Xi·CAfÊÚú8c¸rº.Í‹5Á‹å ·ÜV¿«±LkýZÕª„n§º‰›"Ó6ÓABÓ<ÊnO¾y—‚ƒïxbÃæA0Ý)q}g±ÁÈ™5Ä·Œ–®)aºaáép8 ƒ •ju2•(Zrç99ˆ±€R÷$9yä¶œü´¼ï䦚a›ªYzDbÿÝè ݦÊ[¸ÂB‰ìåfÑŸó1ž%ÞªÒ£ &\&_ÞŽŸŠSŽ’ª7†Î?¤7Ÿ=Ä|ÿ~mQÈe1–+|'/ðq?°½ýàˆ­, §2wÜã¶52ð‡7¼=Ìtb}_œž‘“õÚt“ÓÑ•@ØTã6ß· ß4¸Ÿz=ÉOùP¸ƒ¾bP1ßÁ ¤?#OÀÅës‘s—]ðõ^ë†õÕÑh“¼>D˜<©[@WF«]´àø¦áKÛú¢úEVœ¢é-:Cù„ÄAfVØ#ßPG—@ýmã—iÛ\ h¾@„ò­ø/¼Ø ýh<òþ ÷ÞH  G5³>åªSR¨ƒòäv äÍ0d¼°žš$e­svq¦ƒƒu%¬¤ƒ8x%X攞>©w¢,ö~¬çŸ‡­Â‰¸Ã3“ÅK†Ú!ú³i´šÚ[‰\ VÓoU#›*ÐŒh1–­s†Š?ûR¼ˆíÉÈk\æ­¤êL )#-OíÖˆ^¡UÄ“ƒ«Ó9ШùÑÆµ÷´i=I8hÁº§Ÿ”vfHãX¡ÀyS-AM£&›±f0º†jq©$†v÷'lbWÊbÁ÷®ÂK9,½¥Ç“|F•Sók3Ÿ‡¯£±5ÕñqYî퀞3?‹>Õ(Ï>Sײ±èAr/›(5%2ñÊ=wÁMx‹[ŠïcßéeŒÖú³ZbH÷ž|¯°Î G*¢ùò`.Gi? ¾^ÔÁÄ©hýæUhZí2™(Ò_†\©HÐsB\&z ¢åÞÈlðP‡Ï䕜®¦FÙcìà •ÍËœ|êš+Kyп™ÁoêvËÐæâžÙ=%w\ŸUxï,äÉèÕU Ø ;ϵL”… †]åd¶"}qEÈ•Á.Òå÷M%§¾Ê[ æ_Ä8ùåW?uIÓÕœÝÛ5;•¿sôÇÿÔE%Ìü>VRº8OàmÁs&q#Í67Ó*;ªw¦ëÕH‚ä<^DE2Ei'À9Ò¡#Ucñ»°4Dñ#¿5§çW.7]:×åÉ(Æ8Ûlb#RGÁ…6É>Á@[”`qn ¯„cõïì¤?C^`­ÿŒÑf§6©áw?¥qe³ƒÔ¿0S/GÆáÑ×0Å·‚ƒü0†d©ìê/—ïº0xrDl-‘T¹«Ù«;Àe³¯Ó£‰èÚйÊ]i§';8žešSŸÄ³|k»¸ñ8ñêJêém k©É"Q^àÊ€þ9$}YŸYfðÙT*Ÿr!3ÊÐXBÍ;>¬ü 1ÂÆ’‹¨‡’L‰CJØä Ã×WܵbÚý„›á ÒÉ’T— a¨ s¿p3 æ ‚ªFÏ»Ç O¿­Ž(ÍAom©*,mô’ÃæQ$r£nÏÜË>?ÕÅIØÓ¦u§(ºB&]“¹mIöürdž ¯KrŽk=Ø©çlŸo¦1±hEä2ÆîMŸhˆ4[^1l½¥Êo¥‡Äƒ®:lyeÖ~Ð~i\¯öøònWAÜÃÔ®R*c"s /½ÄèÇàmÆdÊ©YkÄ]ùæ1?khúlÙËÁ‡†^²j›[ßû‚º˜c𲼯օÓÛÆ°Ö±K°Ñîlâ[~£û‘”bî‚9ŒF‰Ú…(Ž¡«/ZBvbý8"=r„ÁŒKŽ‚h›/³xjZñ¢mVg λ ¹ü†»¿‘FOOÓÑo zúÂÇO)uÆðDšÑ“º–§Y›Û}ßuuK,D¯ëÓ«Qc‹jˆÏ›Ñ°•í ÇUµL)Í­háâé·„Xë•»¼¹¦¯7BR2òè»5×¾‚B…Z¦dš“»CÍÑÊYr_Ç(>s®œ#&Pã°Ù§";÷Nö=Æ)ïîÝâk¶!G½5í±£…­×KÇ—·—<îÞ¾úRu´Ó*ŸA„ü`ë¬Ê¯å›ÕﳚsŽE¬h#ˆ§õêq9Õ_Xçw`@ðHqk㌉¤Ïâål×ø¢Ò{9FÔCU&Òâ]]lÁoï0¿_9{pµ—ÕwÎÑò|ÑòÏ^#%çÏQÖyÕ”2Ù·"au¯"F©P»žõûh×gIù¦z°]1aŠïƒƒjµvÍÌ·‹xMòƒ{Y÷ïèšú®vM®ï¬î©Cê”\1ähÊžÊ|MåCKvcs]N)e¯ï¾‰/3ETGªPsx›xwȯÇÇ Ô¹x7{qy¼¨þÇi#Õ§ÑÃŽiQ BSlqÈ®öÕ/ug¡ìáù#ßÀŒ¯4xò˜3Ó ÌrÁnJòö—ÁªËÒŠ«áÍá Óñ¨Ò\v8Ê ÍJŸ|m1lÎöÓcÍv³nu¡·ffr{ffŸf•"‚´n6çhð§UëvCÀ7üö¾Ämnú»7´›/æS„†%gÁ8fJ ¦¤1AÿÐÒÆT½R|?2jÜÕ0w´cõ“{sIÐ\}Â#›wŠ62¤1©˜ÇË´r­ÞÙtLƒý…w,™ì}¾æÝ“}¿2¥Ìgy!‹ŒÅ¾~¡ûO38ñ}7[i=w—“ÃüãáÁ#oh…˜™¨¨éfƒž=µ§Ÿßê{sãi\atƒ™øZ©ÑrwØ£2@»ª<œmv"'¬éQ™7$œ*RWg„ȼ„ ê!~óªöؾƒO‰*¸™°H°º£ßq6ÎsüFgäåi۩̘*–Vð#Z*Л/,á€=ŒzÄü·ÊÄf6¢z}èy]×w€õìDr>5UŠÀÃTД–¤m°']»Ø\[•}ðk…¢¦Û6…Óšèµ@éã°´Í! B‘8Á^üªH¹ÈŒ>ž„“ ‹Aâ|3rJðbÆùít“Îõ+aâ=·žÃÚëf:å ’Aˬ’±Õ%²†26‡G gîìx#ÁñGò6ïkÊJŠÏL1ÐòÙöjVȆ¦©¬§ü¡Œ²54.Íàkiü[ùÚÎf]½?Ýð´Ž<ͨÐu‡(ÈDŒÀįUÅMÏ:cû>G]ÇmŠ–óÆÏ½Æt÷óÆX(z>è|0††=·½QÊë~Éï7;ëÔ$G<]‰>]]±˜à\3T›Á ;ØP¼iˆ¿ÞàþnÇz÷QžÈeg44ôSIíkж$‡ ‰ê0,MÁã 5M³&µ÷©)|]é ecÿ6æ:ÁÖ•ÍFmÇ™Ãçõ¯Þâs½×kÞHgù—Ó×lÜSÞTo줯­B-=» j$¤‰(°óµT³ï:µÏ¡#u¦Ú¦ú‡´#á?½»Å^zÖ–:7&ñû9K÷*:k§ Ûð,—¿ØMñIñÝ–N‰"mh.;–ÎQw0<ÔÜnÍ|kè g„*IRÛL­ñ{‡œƒ-¨ÿYù­VLgùó«¶ÛÌà,Õ—ú›ò$ `ËLÖ‹¢°÷¥çxC®³ïø=}ð‘¨^鈧Ќ©S ß {E¸@e³Ï9RõzÙQFeÖ‡“ u™ú~ˆåG¦«QîÌŒ‹j ’u¶.Ä%ߨßÍeeë=Eûˆ¼×¥«`—Kz¨&`O@gQ´ ¨¹“ /Ï;$N€ŽuiN꘥äÇÉ¡Q•UŽ¿ÉuO·Õ§z©.ÉM³ã¯ÄÌ7]£{ö"Ùã³*8ûøBívÈ{·Rx¨F…Ig5ME`_j!Ž-†ÃCyOllضÉî_€ðèM%j( Ñõª7ÿ,è°»í¸þ,÷³26£Cté¯RJµK×AD lýª–‘¼ab-ÅvBëwúÝ"Q5ž{ó¡;K¡FTî%Ñ®Ø÷‡ùÔŒ/íÅ:$´aƒÀ¤c*l :{îʉblÕYš…kïù;¢ïëÌN¤‘”žæýW/²Lož¡ r;•Ò-Ø%(ðŽ~ú“¬a@> ©…†ù¬ŸéX¸¨õØ—½$a\,éÅ€#仾ZÏëÃHÏ`ו¥gÆÍ éùß„¼ûá[¾‘%⯼åíú£û!Kè‹C©Vr›µé¡Zp÷›S¯˜ˆ\ÃØÚ²µAé¶ÒDß±Ü5÷ßõªð·t¾ýP×”õ•,†^Q+¶zZ¨rÄ W€ˆÚ]JŒ¶½f{UgêeæÜs µŠoÅeü4sG®è¶ÁøÝ¨à{tÁþo¯×“ÙZºéx¶»ËöÔ±?=|•$'=5å¼B?:ùU‹Kk/¦’¡[·ŽÇIµL¼Áä㼜M{–{ùXË’|ÚÚí”!ãb.icÎÿ”úáQ÷eqù©þ-cVžX‘6­¹ÉÆÂçH¸kRCª„îdAÅ`³6ZÏî|àCÂPûÔØó-5K “LÑho#‚²–ö§Õ„F3òñs—zÿ¾Éõ·¾è0|m±›5äWòíš7†ï\NlkŽ‘jO_²è“üV¶=ªmá›dÄ$szùštHgËgÙ\×ÄÇJÒž¬~JáØ= Ò+ÿE1ù=!ÃŒìoÂK’ RtšFn›É0ÞÕ¾(ŠqÖïʵuÆG³M;¶dµ¶°¶•$ì×v=ßäÏ/Ï<­ Ï)u=8ãSîÆìòù;>üT­™ùÄ{r¹Ë¥-"…z[Õ霟ýRHb<ð®³Z¢…e{!à³Xú¾ºrÀbö!¯—’íЫ±žMä˜õílEå'ø>Á³ÏQ¹Rz¯éS7»©èz-á|¤Np‹­ WüZPg³, )Õn‘‡nR¾­J‡WŒŸï‘WÉh ÓdÃ$NÀ1ÒU@Qoñ™GÈΪî=4e›ò\ôuÔqDœ¬®ˆô~¼¬ëÒÉ™œvŸ­iüè3Ùæ¹ÿøÁlþ²%†×ø"«Î«è² ½ß‡¿a`Ö¡/åL#‹ a [ж”M×w~ÙM3­NpÎeÏ^ƒ P_q,ˆ…w±]¯q"Ñ mçÆ‹euýÝÂ%箇Av öÃ:KŸPNu˜ã´Ö”óZ…Y,Tõõ Þó2¹48-þ bàÞäà¦H†¼þ‡€ø ÝY?;¼ÖZ7á÷shìÖåÚ=õZ*!k=?N¼J¿„â&8U«mˆ€ýäÕ‚”ú #ž¤´Í4­yÉA´Û|Á˜4ËÜHk½mõRî(m‡ûQÞü¡: exŠò©© ‹—f¸,øàX^ë+ZœÂãÍñUÎ`VÐúFÇIÆS%o¡^Êèaüü¸XŸï=sß)ŒiØ®øàKÑ.„ÂÅÙ46Xæûv´ÑJ»b¿›ì—¾ç-ÐS$1ˆú¨`‚?‘H®–½9ÞÙ)•3™?ñÑ." IR«&Ù„ÔÕSÜQ\ ½†e^ߥ8ƒ3º–û–ÀpšàR|¬!Éy’ÔêþÞs£ZN£u½¾«n…å &òD9n)²£Lá“ ~ÆuñÒGm‚è rLGÆØR™eÌ“³š$uô»ÅJY ONoΨ5!Ô';aHèHbkCl Ns1AOÒ"òzút>,Sì½ü8?ß ²½3¥<׊Êë]pÒ8É Öé¬MÙ › ´¸xÂs$Ò騋¿—Œ^TžÛÓ7´ëzȹ”„-ÖojŇ6áKó,à%îÛô¼}­ágÍu‰í‡:ÒCŠm€¦õ¤é‡ë5ô”Ô–ò“I: †&ê{zØÑþñ1èG‘ ê{E2D¥¦àý”Ʊ'>œø3ûæAÜ”<ÿ9h"¦éVeÑœ/²mœ´v‰_G„ùRlOô´ô²¶á0³!"VE:ËQFÄ®[´T å¸m« £’biõ›ã`;nuânO’Ûy»F‡¢é>QYp”74™ò¼!FÃbÁ׳.èŽ(ï1ñå*e¡üñÀüú¡T\zÒ¥E_§uðƒïCÐ !‚n¬zÙá¿…A9@’„YbŒ×[›¾vM]q³oÃᛳ˜°¢ TSUô«Y`Žý~oø'G™¬{n ¸|\(m&UyØéK¹.Gòçjþ83ì€áp’4¤bïf,Á9e —- ÙRÛ~º%[æ%Uè^ëH=…²P4˜sÞ§c¸ƒ¤±žnC”B©°W¸)¿#³S¡yŒ§‰Iß•@ªÝ€ ›Ü?m¼?XãÉ;p!á0!Þßÿ®"—=×óíV£cµ„ÙO²}Scz̲p$Ç'FÍú3vV\áǯ†¶h´óýŠòü µµ“k3¸¢šÎ›nåˆ'Ϩ•&~!ß+öyâØ}&'ÊÁ–ZŠ\)„÷ôÜ_ÊÂi×ÈoËDˆ†Ç‹ÑŠòßQ))ÃB.Š};ÏkF³-`"£™ûDb&Ô;Z΋ÒÞxbNëwKi/Üã ãŠCñq „?‘1ÜÔÏÞð]wḽ›BYáž©l®žŽ#…˜W§ƒ¬²1²ó‘EÒk:ÊOXs;î,…í9hõÆ s%3¥„ÈïîýʧÅü¼ñbÓ3ìV;étÔÞr9q’×Îë»C…Õ°9VÿRx“畎.q¹€†’ ùñ±bv”}ð Ü·úÏŸ/Á—ßÞ #lç@òk‚(x™¶ø(¤órFΞ'$Ò¹OgÉ·ÞnÒÛÏóͼ:̦d‰^‚¯1!‡"k=¶eð–®åNWÃ¥è@±±ÞâBÚ¿ ˜”¼â ÌW²qñòðÊbFzúA†eO®X÷ØÿXR“XØø^ÑÕNÛ@½ºlp`:°Î8ïÛ;%”è­dV`UrožçVß›™‰-ˆ%Ë­8°õ MïX'“mÜ@/åq4ÃŒ­š™ÏÏioû[FZÇ€áFž«Z¯3aZÄǤ×e³Ä+L(Wwâ3 UÍÒÕ!dàÄw½‹LZzŸ#Ç{ñW3£»Ý ¦¯æÎ4»w5{>¬ ‚C4P’WÅoR•}볤üQ—+ 0ó¨à › „+¥œ@¢ÞÅuêTzůÇËÔ“$®¶Á_.¨ª+¹ÛO°“ à@üÎÇ+iB[9¨¿Ÿ°º:­ÍÕÞô:´ÃJa˜ÒÊ‚^vªVãmèÐM/uZ¦åFz´TwDwxÙØ,a[vc«Ñ_1n=G 9Ê>c”Z²$lÚÛ’EcºŠDE¸iÏÖëC¼ÜMÞª˜WI%/ÇEOnk ñU–{Í~Ùûøû[)1cDÚ\\û„¯>DáÍãƒ]êÇ‚Z*[Ľ~ 5õƒTßhÞ¢lúæò~H‘ÍMzaOÍwCPÊíE[ˆá‚_uvÙšÆÙ ìƒM)ÿX¼º_<»1¶#ÿ•æºÆ\Bñç‡p‰µs¦z×®®´»MäÆÝ2¡{¢Q[Ý/CÔ:uò#/ßm¶^Çb¾ãEšõõ¶V>a)„[¼`¤"^ÄóBÉoÇ¡ÉÒWLÒ4÷™(Üè|-0ùæ„.Íe<|óÆS—ðò(pÛâKýe½5ÂA(‰p!BÙÁúPÀK¶$¿ón¾å&ÿ»WN’Я XÅP&+nèr´‚iZ[$”¢-9ÔüU`ðvïš’|++DÉêJŽŠ˜ø²~F7 £D<ú²zé·ÆM¨ÁX+Ž| €˜¸z޵¼¹‡x4eE&ݤº¿xßñ¤( Iéj{è§\ÌÁàÛ'w _DíëéÍËþØ]*¥+Ä<0 5ŸÈäüéñ eå„ì=i舄†”òl³r6¬É*Œj»¸lˆ`5˜W—ÚЗ…JãØœët£+ åda5ʆYR]ÆÔÏ\%³ðEonGr6ÆDÜ:|P1#¥ß3É›WîmÃ'ÓM¶Â‹q>ClÑæI­@>5æFX†“=,–psnpLað–½úG0›A¨ªw%«mW?µ–èkE1Çt›sîܲaí8Ó'닦ÞÏ àÂøÞ©Üc CºtQ¼ƒ6û±[Èä°X9ˤ ýnmbkÈRÜ_$ÿëž$ôÖ±­?š˜­]¿l± dwnvØ»ƒ—ïõïÒÚqmãÅ¿—uŽ}õí]WËÚÅŸñUåúx]³¤-(-3ÆÕUu¨ìÙ¿&Bú5×€Ka2œ#?ïô¼78‰à N=ÿ~GG3?Æw rî™Æ…Òt¾„Ư]TkbûP}éËû€º’|imì”Æ±;%Ù!V.©$*Ô6w"±1D›a]"X'úã&pÍV•IC%dˆ|wãö|§Uç°Ùan™ k0îMÆÖç|ɼ|ƒk²K_ζúA¨|®¦ŸŸÇµ‚WiªÀ r¾±Iüv*Ð5Á’ö,2Ç”‹Òsžý1@Ïæt¸¤ŒãÁ h6Xž\ªÆ ¿pŽ¦Ø´Ï©AUvÆËíS•‰¶Ž¥ÐK"YÞ~:›Fy7+*ßüpA×y!ëv5Hú£@[ÇG8¿ß3/ëd€êÅl¹¹LŸØh Ëº†Oqþ–Rz‚âÀΗÓ"ÿGHpòƒTÆ\À'g©Ã±a׃)ÒZ,ÌŽ$õâá-×U¢ÈP 7)/^ï«ú«¿9gf ëÁ|Ullì¢Äó´ˆë?Ò[ÆqäŽ?d¹ÿØU|3P"å¢Så lsáàÁ3P?×®,1Ÿ¯ªyƵsL6þMQ¯+¹>6˜´j€dþÒ „‡£¦¬;u™ä&Ñ>eá¶g>½Ç':ùl™!­/ÄTñ2ßSªTχÉÝ¥œËt*I0GÓÛGwK[ 4Yæ¹\ÙŠ2On•)ùzl/D;Õ³‡†° ‡,Dµ³^©Ý~Øv)WÈìàq5õ—ÉŠ;j+Ý5cÁ¨Sǵæ4sltÛ1~ ñ)¼ïÍGž: j­º´C›é:§yNë(³à¼ßS ð¨õ]²„ÞÏ<÷}¸ûÈEö®ü®h8Ÿà„Ÿe°É÷Ú£¼‘ä–©\¿‹;ð á`þtF°V°é&µ¥ƒ0n9Ÿ±oJå*JÉqŸmWò¦Aux[0 əÙTk1>ëwpà×ñΞ¥­=ð­ø5èòö'¢ní,MóFê(E Ò_ Ð÷Cµæ«4c4ØZòn3)àQŸ3«_öË뫤öhð=ü0XB9©»Ewp!j ô×ç¼h ZVÖ!˜WXT…Ç™ð¶q “2…é>“Šô”Ú‡<{“™ìÙ:ôn³nœ~q];zïlf‹r5…ÒÆ·19P¶!}úÐ8NE9Á‹Brû¥À ¢þå ªkk Ö}–ë›Ðx¦“»Ì$ø©–…MIöîò›Ò¡‡Ô¨õ/áši=$î&;[òñµš“êü™W¯y§ôoËɰ«:÷ð• Äv‰Û„K¯ãÔ û5ësX§¥°7.ÃÄã_©L΃<‘äc±™G 5×Ö2÷bË‘M”©½“náõ܉ª'ñƒ †ô,è!w_‚\Òª™_üþýý/0ÉLŒFÅÉõpÀeÝÈfºO½©ŠÂªM“£÷5[OqPqw·o¡±æ)òq±Òñ0^s7Y%fA“JNÏ{ŠEda{Kô½kCdkBNü 5µ+|´ ¤ó]ëŽ>›øڸƮL†™ms«Í¶mÛv®lÛîʶm{ãfÛ¶]ïóåþöþ‡9gpf†+¤Pêïµ×ÜHŸòzå>«-—ä¶dœ™’Öq„ôœNÅÊ!Å&oÓæÍÇóáq8ímŒ/!EVó8ŠÀÜõIRKMÄD¼íÕ ‚%ß^"&Rë¤ õDÌ duT›u0ªjD [ Ô7ýP‚J%2ü*sáÿS0’^лA“álBÃf±‚?PÒ™z~Û.¸²æŒH}]²•&fD¡4“ŸÖÆÅCKÚ„ %|3\’Íí¤ÁÃk×͘5/rt4 Ò‹xɃ¸[Ø*ÖäŽjÑ)Äå$mˆí¹Ã#"Zô~<õx:¿bÑêškôD=½bÅG‚´UÍþ›‘ÿxiHf¿ M*¢Ç¢#]XæÊ뢼J˜ÏP°?ð¥d?ŸàÞgF“Œ¹¬òÍñ2«)ÃNÑF?-”¸7Óèy3œ/l‰O;ÎìÞl¹'çó͉þæ£NçMâŬö D-è½jlöJak ç![Ð6ò»C,îE[þ𮺕3رØ[™‹=7ÜQ—«•ÿZV1ŽC#•kµ,y¹˜-Û^â ò4–Ðl=ßÄ•ã*šfSýí CªANóPþñò&Xù$š:Z#‡3 ¬ÈrMÀäÒΔÞP åÆï¹ìtýk€\–7Ÿdõ†&¢àX¡ò&Ρñozý¼ÅÅÃo‡àñ¥‰§J¨ÉÎE±Y%Ú Ÿ9ÿRgèh íyXk”>†LÂG5~ß…­O' »ªPCßÂ^ÖNAW ÍÀCTêzÒ«Ø¢-϶ 4–=DÎ~·ÕÞ å •ñ9UM ÊÏò±$ž <÷@÷aQXƒ–êbÝ 88䨷†h‚½kéÍÛI-‹ª—%ÍUØí„…h›lº5á4mYEÙŽ×4ÑÂ]µõ:e[A7`z9ªýHâUK»ùÝÇ!¾ø_Ä[˜€Í1ñ}EúÑÿRM•Â; ¬0¥ó’:&ýôKÍLÔî5qÚvóq¥òŠÜŒp¹“æÌà |™7â,ó¡š~ª½¨M:ÃTï]M£aMîiü„v` ÊçÅ×·X¬ÜAJ…T™ÿ¦²gì¢ÖUKs §%Þ—3™ßš,Lö¦ „“8=²0åù\ô«€z‰©ö-¸ðvmˆ6×éF}/³›Ú¾›œ=½µ-¯ÕÿÖ¨uõŽX_Å#† OçLÊ&„õŽž×7'þ@=åyÎLtäÊjàýl‘…bô,L¡7|åào.S'¨²d‚Û©d𞈽õQ%V•§—»ïpW”ß3¶äǘ2ÚJfw!ÅQgìhíö’J¨ é[’7ãçªHCý䕊¨W^n¥Ý¬¡WÑÄ"íûµDc¡Q(ìñÏÝuÐú$*Ôê·š°oÆòó#R²h ŸæúÎnK=ÇsN Â÷bI)oØ«Ô ™BÐ3aÍ[;U#^»`ƒÆÆy6#AÉlGå¡d]š'©z1cÒ¯ÉÛöTö:W I76~…‰iц‚,Fn´ò"ÍG¢J$g'• ¾ÿëËþÓx•‰Ž$=ó8óf/¯¹þEí˜É§ªÈðŸO ­7EV—ûåµ8¬n °è+w®ëå4£¬†*!ï6AнÿN$'KI‘ÝmÇ’î_Äžˆµ&R*z‡Z{‚ Œ”–v†=p Çï{záx¾F£ú˜]=SVL—3ôíU˘üJF‰mqlÑàƒzØ!ýE*L»ˆe Ø«pRjšUÂÌÑK®‹ B~1½dÚ&…ùo10%ØîúŽد¾dòÉ&Ã>ûᕵw¤êbN‹V¶&), õ‚ð.<°6C™„3e%iÌN‹bÀƒ\êCu%Ó8³½R#Pc¯Ä,Wû ßaˆôFÆù¼Éx{ˆ¨Ãàëõ,à Ñqj‡_7⹪Bº'>Ò¸ÅeŠüÑš'¸F°ƒ –,š‘:—Ú§¼¥¸?Ž{ô¢Fè¨Mvö#+‚™«íá$ãB¢+]͇§o:wK<¯Ý«[¼”ÿfäG¾ÉÌzÞL%/hš´çs='LaÓ7TŒyäê""&‹ÞÈT¡L%‹Bvc™•ãsáR7Daò½Tòxÿ5Xü\s(V2,é¾Uû®Ñè¨MÿáÞ†¹&ܹ½¨L+Í/wæH»:{Ê`9÷fÄÎ.ð5ˉÓa öWü â¹A6÷ÝЦ~i€¦&ÔP‹æù´!îˆte_Ÿ|±ÜB?º•òWÙ—^€ Á»•|‘¬€ß³’ŒYÌ=OƒhÈéð,~1H§æbÂä“¡P¶Ë¹ÄÉ[æyž½˜åÜ©Ào‚ÙÛ˜l-£êMÎ £Ô¥7ç1T!³‡‹‹±6XÊ_,ðxõü¥…~•é›N,_”Ó¾Oà1CbEJ©eátiCo/ è@ßkC®Ùô™1þõÈf¿ñ”Ýx¾·°Ëɪî,JVݪøkâN+G3ÉŒˆÌ²±ôšE/RDb `šd 8}áÌ&¢o/Ó$ÝàÈyED‰Kί—OéNà[½Wþ«·ŸåkJˆî¶}´¸÷½2 \×<ì[¤½? ÊM›Ô/õ~k%g)^iž°ÄÌü?ÒU‚7z¥ÀZööþ›SÆð ývŠlGq!g÷ô§Z{°Ø‰™ˆÂöã¸&Vaû_ÖËÕôØÍ¹¿Êž2A’b™ _y’í8ª(n¹IebK“L¿ÕO_ã—6Báô˜}¯´™´¯ï5ë•ü–}æ™Y5õT¼˜ú‘F¿V€>„|e២e<<‹ÚÍ‘S‚#¨{Ò„Ã.“«B7ðs¹¨˜*¯4½­yj›üê§ê9¡ß§sWB¿4ƒà}MÞâ蹇ŒìÕ“îKª1!bzd%ß`Ôp³öé#“át³Üêsô–3w2X†© ÈÓé÷6uüþW3Å$"Ì]{ú˜ÛØ—$`ϧr.¨ÓÀØÎ±‚Ó$e?cˆoÿÄÙ\ ,Pi°,ëÑU”aÒ)WêGŸá®g#4Ñ«>\½ãÔig=Õ1ß~Ø×FêÜòw~³3ÐmIϳèÛWýå*VùK›Iʶ‘¬Š·_!|Õ®¾2üÃsôRõ:¡yá¥G­Ô˜rh/ÇãâO6›ÊqµÊ2Í‘êÊ{†›2å×Ô§%j;íÎ(K6Î& 2´š¶­J™ÚÌù¬,?G)VC»sQúÙ<ÎÚó»|ÀïcâHc~êаTèÞ7[HJÞ‡ÙÜUR¨»L˜­Åo„7åg¦FœØ¢ /B_¤‡ƒl†¡PÒ"4ÝÇÏËr3¸i]¦ šå“ß™Ïåù†'èÓգ݆–=fýb‚Ì¥¯)rŠÉ€{4½ˆñg²’€Î'tìÙè]àì9‡-ðÄ +öÛiv_¡F&ü¦B¦S$ã<Š­Q´+³ Ý.9.bãD–¸)ÆÃÑM̻љñÁy“tU”›Q}ž"/ÊJ·?W;ຬçe2!ÎŒS:HM)¿Gm§Ô/ nÌ— =¥18ðÉsQ ©Ì cF"ën[vÙÞúqXŠº[¿élîrânÇþæ>_×Â’¸cN82.sL½¼Ó¤½jµûJÙPÿ ¯¤-êà˜kL”yv¨ÛxsræØ[ÝÕ!,Ö>X02Ô ØLeUnÛÛnô&”Í ¡ëÿb„¬ÁŒ•¢h7âÑr:ÎÊc"||_ySdf¼`þÒÕ¸'_z0g,ø5ެéK°ûJŸ2_¢¼aɬ]”Œªòˆ•\7§Å2.† Þ14@%¹òç›qçŸãÆðNµµg[äµy€ÑçXÅåQûÑÎ~Ž»Ï Uv¼×1ý£€Ù81& ƒÍ€Ñª6zTö:õ˜¹ 03!Õÿ‰â`»¾KwÉ:oY²ãWÎÇ$ÁµêkmÄj]¦ÜèŸ)ç fhÄL·—ç†{D#u™MÜ»ìî£7íR¶ž´«¡Á6Ž›è êcA‚µ­A³¯Wn;¢ƒI[ÇP]‡ç,ô®‚R¢G¶LG»;k*‰,²¸Ë€d@Ó˜d“å7)TÎëœIasìhuXyA•®Ô“c ·×Žö«í`GÐv5˜”#ʪó=$íiê,»îGÇÑ6NÈJðÀ>FÀHÞì¢éÇ‹ÿVuVKF…Á—¹ÌúÓ¶“Aº%ù¨ö%ÐܪùHåÿçžìÇ)fÁ3o!/˜þE 'Ô7÷c>²¾ôäºZ®&ƒ@¾ØÕˆ.}J¾ŒÕY§6–=„æ¾t¦íf¹Å¤M¦‘ð>õ7$\Y9^rí]TÏİ4Û¹ÀA“Nÿs,›fÐs·{æ]bZZOrH>X¿X;c)-âöUœ¤šù‘ÌNÙÉ6æ:í¨.¿§q(]ËTZ‚m6c€Np tÆGΛŒYö]çô‘bt‘%‚ÀÞpÝJÖÆzZ”%Ayþ¶Vèàj]Ï5’P¢|îAj@’ÃbÝĈ˜z@zùÂ·åª \¿lñÑ#Zák®Ô#Ï’*>bóÖ¬XiSoLNl1`Þ(›d©¹è¥ÙPÉWt&ˆU¯<ý\­^0Í€¤e'¥>úeý¹ý9(’¤]`²( „é´Ãô9ƒl®Ci‹»º´'¾uæ`zêx-Cç2º¢7 óëíYíy{|mz1Í=cZ?j¼‹–ª¥(5è·XjÌ#"ìÌn}A°«õºd™3Jw вúBÜûîK“ Ý#7 BŠm)—ò0š•úÄãJ$;Âw~·!‹[v=±dü⻑ՠ!<ðBaàÓ·IÜžÈ6ðüËï3ÿ}·xÙ’#ÃD~vëY]üp]ão•öŸûÌ"CÁº{î\(QU擱£‡º-պ鿒Öv—Þ§(ôß_G¿}ù\ä#îÂŽK”ÑpëúªjeÐ45‚ŽËÿ$ýÈâ&r੦ð»2S0/ߺ'7¬ª’c˜4HLŠxÆT]F|ÿv#Kô´Kö#?ž3³ƒŒhyóJ—<¾°ûgG4+±õ̘¼VŸŠYG ) ™Öëö8]í}êNX©Š¢³`";w’ŠÒÎÖÆb9Ü-¶ò?Ø(ÎQ÷kzœÛÉgîøKŸ*­µÊæ(¥Ü¡´À–IÕwKP­GŽ€sƶ8)¿´ðRâ.ITørNcíYÇYÚê77ê¡fŽò3L Þ”ÙÅCbEJîä°OŽkÔ¹>0ÒN‹¬n_Üô—ÀìCÈs¯8ÿl4ÊlG/Þ =R&_CA n =DB¦Ûú/_Øs,œ‰w`zœÂ×3þ}¿/FªìŠN´À“° û2̺.ÁAYd yùŽQ p¾žþ˜‡ª“Õ(/ã¤.'s–içÝ‚W“ ç¬tW£¡iRï§8Ér·å§…˜ƒ{/¹]ÌOSóoâl u>!ÓØ*0(IêÓ º8 ýðHÛŸ}éòÁŒ2¾ Bjgƒ–/µ|%3š¤r8ñÍ>¥®õXÚ·ËWOEbNœ²b§_œ"æ”àøûe೑Í1a‘ùµnR³y™ ¦a£.)‘QéjÊä~dW¢_¿›h?qÓ0†LRÐFJ ëàa5\.Oìï. ºAuÔþÞ[ó ÉfÝN2Ø(&}xäÐ/Kñb)ðy\˜¼ª¹ZÔÉ¿¦/Ùõ-‰Eµªf‰à®£‚RÈ\È+ÄÐ'˜„\ÄX`C}'gOÅÇþ¥Û¨tÎ(Qz¶rí¹„=(û&–±%x cõZÝ{vVû/E²vƒßwØJfêT'î†~UöŠ5ëü•pŒ?¦Hu& ÿ ªÈf–_`ÃÙèŸ*mmçüE*DsÓðyXÄyé&vQ{JÔ;ôîPdgÏHGŠšãZì×},ãÿE<œu÷¬×í ð\3¿¡qžOc)gÖ“Ö³eß’£Åòƒñ¬c™%ÕGíÁ®Áüy_…g @×þŒÀ‡þ¯†ë˜˜”OÜr¥ë§ùÂçg¢p§B}a’¡ÚÛÔ¶`co•7ZšO<}§ ú£D¾ý\{)­£hQHZãbÞþ x¯KÚàð•o“d{ŸSšðÂT…ÇòªÛøÅüË…„±d6 ´c¦ù(«s~+½ÏS¡Ìebþ²X )júAmý$éºÑ[÷òÊ2†k©*ˆ¾Í…­g4“úÉ£ãø’*Œd€áçhÚ¥ª0&F3TúÇ LqcÍ,z[çíélÏþÖ Ó ¼Ùøüg”—ÙÛM ¤û¬ /€áô²y‰§¬¨qÂ5dÃ0¿Ñ¯ ô‡TãÍ8˜µB’†*ÅS‚¸žÞëÍOÕ_„(ï èGïél$d V¹‘µy+Ó‹!X'p\úÇòqÌ)r×Cþþy’?V&'€w™½_g©Bå#c^$mg¼¹p·¸Ún–º»òؼýï¿ ª`Ö›IíEep-x÷P³½B !›)®þ™9Ϫ\–_ëŠ Ldæ ¹ý¤@YTn›¬,,~K«K=ü¨@bíqc¯«f?@%¤bìãŸi÷»žc8ÿ,‘—Û–YÛfÅ_ÁE®ž[#n\ó«DöËÆs^»dÉÎÏìÿ{ªÖ\\ÜœOê/ }˾ÈÎÂÃüÖ^ÇboK3qPw8bå<>ŸÕw€KN„G¶ÊóZ$õµ‰¸iÒÑfMjqšh¼ÛI•f´œ%ýßÒ¡f ®.—Ò{vvð_ÇŸ;¿ ?bá£ÙWÎ[ Œ[lC¤¶îÁÖc2½1`o• šë,J ÉàŠÇ¾µ.j'[7$# è 'û.¹,ËÍX²¿òƒ®1šË,¤ìÒgˆ®?j{°èÐkÖR¹HÐJ%e²¦s*ë†^W鱸qéŸå™ù¹;-4>êÂ|n–ƒ½TòÒ-'äÈo´b-¼"Q°æ7Dç5‰6ÞµƒäV8d›¼×ƒÜq·™‹Ç胘?X‘|¿—ÅÅÙþ|BÃõÎ. WåüS+æ,C§A}¶Á¶°¿Ï–.ƒ[‘þ Œ¾ƒ*•ʰ3ÇK„æIšŠ´v­rW„…u ¢yk­X[°L5MÀ’¥œ&=s›T€EùÆXÃí6Õ•n¾g_æYÆÎø”ùŠt»Ïþ_ÆO9 “üル€Í16ÈB`¯[nÞºlq0&cžu’ ’ mËÙ— b˜¥5¾&ª?O‡¿ŽgùûVeS>”ÖgìþhTš«9:‘“ÊNÛ¸ªæ‹úpœô£žÒï8jHËL œòWú±NüÚ)Ô¨áPã['!õ“«ÁÁFŽ×Ù Mðê@·ÌÓØÇ›€I‚¸k"ñ<´éÞùâTÔ çêy÷ÍÆ,L~m›qµDW¦˜dCæA‹´2ZµD,3MÆe}ñ²g5ç·&]î’ÕŒ;M >?ÖD°áèvo±|ÁeÎ|è˜jX͆j¡¤^Òõj L5yžnÉgð±qü3ÏP†Úe’±S×ÃÃA5÷¤¢­–&wO¯ÉÄÌŸïûÎû‰Üï*TŽç¬Ø žÛŒqÿP·4°F0\ˆb]{üØ{sºh9H>å¦I ¿Lšµ.VúÉÍcLùñ¾,½±j6®  °d°Vä}õ\Å#„P=9¸<)Ò̪F¤s)¥»ü©ëNmr )  \¦Â½`¬\ ãÁZÌuf ¶ÀKxžPtc>¡,˜ƒ‹gy^yÓiñgãp¢Rgïéñ­¯Ëˆ¼:Ý™¹§9£_T€×jB7’±ÅCÚÕN(¿ò~è]8âºñí§'âÑ| ¦™ÛjU‚’7.†÷ q\Q®UqÒV@=ÆœbTBý×¾£šPQ›ñóL½5lý” nQ lœ”ÛÁµÃi¦78•Þ8h`ÄÞ)ÜÀÙ†¢uP|¾ÜmɃUrPÅ⮞!ÒÒ¡ÇùÜ{#Û‡÷ã„n”ÇÀ“㢶Ǡµ½ŠoæÒ”+à6ÎÐ…+ï•ë bÛŶ_¨7þ‰KËþêØ¶ž¸Äñn·µò;%Ã\œ–ìÂ=‹B6|¿ý?Þþ¼]—D»¾ÙZ‹VŸ˜.ÖßS+.düÈL~š½V×»HÔ‡X•ÓyÅAײÆþÃ(´-EUÄçØ Q:Þ”´p03„Ë«‰.¢dõ¤Ñá<%ï˜+¦ûP–Ýdk”›j¢bÈ@ç h?ZÞtí#ö–Ÿq¬•¤¨³~ʼnûîÙ¸UrùöŒA4¹Ë`ã À/‰´3Þ¤¿`¾7w}-ÉÀf* œËä:c\„Ñ« ’5²ê8ˆÇÜ‹Ü4úoOoa ðH˜^)ØÒ(×V³»Ñ$@%l>T‚€–ñ¹ÙS£BRìQa‹yrèϤ°‡ºŸ„§HOö«OT8ïý4^»œö+чCI{ùìëÏîç!aX}.j”L÷×®«ŽK?æ˜÷¬bqÍuÉùHÛ§im¸ºÍ .nôy«+*îô=àñh±æµh5´8˜·ò)+ò)q꺼5¶Ý)U˜‰ŒýxNkî‚GP"Sinw$]óyç^:R^]•Kj!œ·”3lZ[‡h.+ˆhH.溿 Ë œ¼&Yl/M5¿{Z·Õö¿Õœ´smgw€2¶È^¼MÓ¡hP¼Ñ¢¡–X+EàM6UðÝí¯©¯jàà4§@©ÆâW·MƒþÐ}míY\uëS¯¾jl=åos#÷Ë;C VOµ1Ÿ¸¾' ÅyXœŸ~í»øQzÝPQŽƒ}±cŠœº|âÔ·r£òk9ÒÆ½)àΛ­P^ }司>Sl`‰Èär +E½f}ø~‚V•7Ë«?Z±¸ßf, cº³rwÔ³¥K&›œTK¢«^ìAŸü(™Q`½ŠCyеDõÇðÇʄ’ Û:E´|-Çä®U -/Ú¿¤¡ƒ#økOáHn¨<” i/Üê#s¦œ•Të @Fþ$R{Ë_ÄŸM8Å3ÞÏ/¼Ø¤6@¬kBK7uÊç^LH-£˜Ö8’[£965vÚOòŸØd3ûŸ“­&Øœ¶w•3e›(hIaàûbw­¯æ°ð½˜ïÊžìG ˆœcu`¾ßcÄ t׊Ÿo~Û.›óYWä[Ѫb‡ _îÀ*ýäÉ •wg?a=YnõWg ÄÈ–ˆ0¢(Z89ñ-!¶G$´o±Ož‡6âµ€¸òBE j³â’3S,´;àÊ‚ùÃ|Ä(„Z ‚H²¼ËMRÏdMá!ÜCqPa½°Sâ%˜–ÄB_-)53‹w7®ãUÛØ®Ú*™SáÞ­üÌ-¸k¢3rÏ=R;•̰É×BUýΟrÔ™G¾D:“Í©áöÊÀœýðÑ ôCׯÔb’f‘m»ÝÛNæP¿_.¿Iér“ƒ ;Åc$fÊÓ›x=787½h]Ô£;Î|¤=Iš*Þ}>CžŒ¸¾GW§´u)»×"E´zû8ŒµYÓ¶'h‡{È$G(&¡fHÅ?8¨hÿ¾U_·Ô¢ž+]´Ëßþ^ “)·f!úô"Í^*Í ?ü¾CºTa£²L'nÎÈzÊQ86l™ðFPÅHQ'ǯ/Wªos!|ÌçâöPñ±!cAN$zã¤*(_#ó-´¨úóUàDKÃõ$šE˜Õ;drX©èZp4wó¨¾ÇÑG$­OT*õ»‰=3ˆoh¯×æt ¯5ι eEšÀžm€Jó±BNP‰Ø˜3GAç¹¢|*Ú¿QHdð…µNX>nü¾HJx¼vÐíÖ@M‡Í õ4¯é–N„ÿÄç>˜Wçàt ß`}ÙÑð/âw!ð”&tй¼â6½þÉãkø­vdèo•q™C2<Á„.ÅšÏeLÇßÂíBM³ú›¶…¬†= Þh&Òá%÷|)1ZAæSpÏŒ»íˆ.K ‰—oi‹~8ã°é÷Ç…i•ƒó´7jó¶Éä8üFÒ’Óš–Ílb·"8˜ {ÁÖ¡5BÇšõ:ª¹àÈËsµ(‚Æ)w呆1É##)ùµÂ™akÕ»érn!äu.FÌöá”rüB¦âijì r­œ²3nMK^œ"[…¬³×?é·gA,[}:ËÝ}©óx >X8Ä([dŠ’¡Èw~ ]¿ð ¹`×JÖ« ûAÀ)n¶;'B;Ò{³åž¦¯âQYn¶¬¡–tÐ\§/ËTQAÇs¾Ê4í7€Ä_ó!å9zô¨Êñ‡ÁBˆL¢$õ#?qŽ`(¼–Îôå/Â8~•R†ßè¸Ê}Ë8OAmKµFâæIÞÿå»àS~»ƒ‰—-¡ÏQ#œ3ê•XohÅs,ÉäéËÆœgÔﬗÍå^ëAö…AoŸÐÉãK… wz¼èœÂDÝ/ ;ȵ—kÁ¨\³Zh ‰HX=A.±ü’²îÔNRe÷w¸·Ìºu HQ P¥’Ÿ7$`ƒè*ônŒ¼¯ò–™@»t}7ßñ_2mô³>!-[ÂsSÜ?˦Ø"#w¶ à‹ÌˆýàÍWO74ÛÏÖ ùìÊ-ÃÕ½¿‘g>:P×Ì7÷”òs6¸ëþÊ•U<º8$³`é@c$’:UŒ›*ʇ—TXgÕ¦E[ ÑF„ ¶:ÄÆñ HaõìªE ÿê0Œ†·S \á˜Ãè·`áü„sÂ'¹gËe›,Ä4æîÂQ¿Àþ’¨Má–Ñy2†Rþ»0«8Ë´Y-ü4]» ENò«ÄƒÿÛ<E¯·ëäeï6" CöµéŒe¬ìB䔿Š^Ë&ÿòõ;J™èKã/UÀ3ÿ®Š§CöŠýÑ»£I*fJ…3{Õ"ÏhY½£N>!®6ÉB…¬”O-òÓ&%ðèà‰ú=œbcpúåá·0º–Œ¥o£tïvß“å®l eS6µ±Üÿ;ëøq®èµ%!ªTÞ8ï0†˜S½#â~8ÈíûÊ=È´Zyÿ‡@¦]í¸ÞÛ=) + 7q›ì­vˆó⦚ð£Ó5ö=E#¡“ßêóýB@RϪPbîäû± K—\㊸ <€šÞë=F¡Z‹$‘s̾¿žØxò‘ûò¥¹XD¢ 5É·«§g^bƒ~,Ê}±ah§B› b6É};ÅGü´™– { xÈØÇû5¹Þôª… endstream endobj 9830 0 obj << /Length1 1629 /Length2 7287 /Length3 0 /Length 8199 /Filter /FlateDecode >> stream xÚ}–uX”Ýö÷iR@É$¤†îînf€‘éîéîié”îRº»¤ûç<çPò‘ø@©ˆ— ”~$vPæ‘8@ÙGâå ®®ðHpuÅG‚«+=\]ù‘àê*ÿ\]õ‘àêjWW$¸ºÆ#q€š÷¢õHp/Ú÷¢óHp/º÷¢÷ñýè?<Ïô‘àyfÏ3ÿ‡þúÜ€ ¼ Ð??Zàߟúãxa–à…Y‚ßÿ‘ñWâ ý#¾Åê„oý«ÿpã6 ܹí·n÷ˆìpëöÊðT{øuù#¯òrÁ“!ÿ†[uøá>ÿ@¸Ï?ª`‡ûtzÔ‚À®„ázl7\f ýѸU˜ ä¸[çÇ3¿Ýù¯ûîdþi^ÿû?^‚Ë#ÂÇ!ðpU·?^žûcõð7¹ƒ ;øïk®j ¶‡iº9ü3¬þº÷ÿbö¿Y…Ø€tÀ0ë?·(™Â `W6V6øGÃö×ï?O†ÿwŽˆ‹C\=X8ø,ðF³sÃÆÇÇáõ_Í¡PøDú×(‡O£ÿ°%>GA W9æÏ)ˆ¹`à»o—_ÅH]XÖQ—›ÃbôºB¹atÓÙÖŠh©2cŽâ&e/ú“TgŠƒG§Ómê“«ÊÄÁyèÜ vù¥‚Ÿcû§Ë?BÖAIcP£=—8Jö¹þ%.U4ˆÏx\ÿ&øy'G4>UQw³N^…óm¬ åÜÉH1Ï…x`·d ‹Ñ‰÷=×é”m~ªLCxö™Á›x¶ew–A¡URF½& « ŒSû”ûç­8hEàWÔÌ»ÕØE¢rr â áÏÞ¦G{`ç\ïd*.qe[ÝÏú˜Ü×þag9³W$Ÿv!×\¢8WØÁÇØg Zi>iôéD—Z”{Žc×ЛŸ‰ºŸÛ·ž’ÀÞ Üh4 œílWTŠzj¬;¢6ÞPªlÞôq0%¡ª/¨‰¦Gÿ¼wÓ;`]/¦.+“ú2Dmuâ}x)àf†Ì-7Í”q¼×ýù6ý­K\] ^,N*Mû÷£è$÷̓×€¶¡ÅèÁîí´vs5O¹À«iÔ’Úë[1`­û÷]vkA×kp‚8Ï×nÓfÒ$ßST3Ssg‚ƒþ¹§ZþWˆ9` á¢çyW«‡Ï•úåMxŠž¸Ö#9ýžeÙÍh<2ßß¿$gŠ›†S¡è› Ùnë'÷gdg~}3X‰EO˜P¿µA±É\¾Á(ŠtÎ78˜g`ÈHò=/6 MY`#gt Áz„ü˜ÿ|I¢ðÉEòüò^òÝÑÓMÙ ÄFäâ OþåBÿ=ùç­ˆóÑÈìk½VS׃oGÛÃ")ø-,|%ÒV/‘y¼"G@k^ÑÛ8¶`¤‰ùbÐÁ˜Aø)j÷¹¹g×®(­üÁN§jñ´zÂß9mXlDeÀaŠ©³©m?ÙŒ¢G(Þ 1 5—~yܱîL܈ËÒíóòbáIVÞGClG• †ð¨Ñ4JšM–pò×sMƒt£¸ñœì,Éþk™3 d{k„wjÜGO|ü%î6? ÝÜ‘WéÞ.ãÂ#DÀ.ÓœZM-ˆ¸¥"¥YÕiqœBÛÄ›s²è;¾EZš4߯)$³×òÞÐiȨRM™V‡lzFí¦5nøZ¬%µTB„@¨=©åýodlWzkñAtäBØ/A¤ºK Æšö>2|ï¤Öw{½¼¯£ø(ylË×ø7ÛÑ!þMêåj6 O]35ãMB3ÆCoÏDù%šÄûæé¿·u ÌÔþ i!nýìËC»¸·¡ÉözÄ—’s3¤¨Zúàµtz•RdÁÈ.£Ø‚,¡]€Õ«(Oô£qoÎU¬‹ŸQb¡Z¦íh¼°*ÃÄ1tûÕûfüØúÄ+?yõÃÚØ¹$ahŒS‰àùÁ â/C 4Úú ÉþÀ‘7QÙ`Ë ®—{Ÿ>6©™oˆùá$ ÖAX¾æ1me`‡¸Pº[(;M¹èú¦ŸÄb}=×Ù8Õ›ˆ¯˜_žÀVÖEqRÓ*û0©&÷²½¼¼r•l«@Œ¯†z¨Ú©Ïѯ £º>; “½’¸Ü’¦—¨gDO]nþuåvõlû ¸|ñê›æ RåÂê¼órx\FñàžéB§ […£P ¯ügÊŨ³M”@ý«ŽHP*€Â¨5¸8‹‚>ÚÞ“bš­G›—Ædès}hE4 BJ¥Û{ò¬ò…±cóôϱ ýËÛÃ>øºmi/».ÀåÑ=³ ÒÒ í¹¬´–of6€YÔ/N’¡#Á~‹Ú~,Û”Dߢ mŒ'$(N#ÈÑä^ã/8>hµpéNýÜó{e„ô£Ð'E½0„~KÑþ¼ì›Q@ŒnPÙ¨]}ÊT®C¼uüöx5Éíb'B~ó“—39òöûcùV]ÁüsEÆùyèY>¾r¶«¾³ü”ˆ¿(Üòës¿”Ró§÷­¶íRo~va8;Ðâ µ8,ØWj#o¸ò¹óaÿJ€\zO»žÜѬK狤Jf$.ŠQËåžÌ,¸ŽT;3ú#êÌÞ_c³rô~êÛ÷¯Io—Ùì:®Æ®s~[Qðüj"zg›¦+› ©±/]¬CÛ¿`оùíäN”•¡örò~VR6oûØg‘›éõbŠô‘JÆ[ß_D³ñF¸Ù¥·VKmrÊœIo§6ÜZŒ*óSŽåhDH BZð7ýYÒÓw§7ýyÀ1¯Á⎀`I æ±T-•ûz(õ4¡-öèºbš÷½qP!怭ˆÅd,Y[îÃQ/O†ØÓ¢ò ~ŠE›MX©©Ã² —R­ ×õ¨jQ}þÓÜÛšsCy¡s‰“}ãBþéO÷},­;ü ²¹Ïd*-zmüˆŠ½hâkã—!=ߦëP0ÓUIdzõF°÷¯‚×ve=X±Z÷ú­^ØQÌæa‡êOÒÓ’j®±J’‘ÆÞ)oX í#İŽy“ Q"„ko.(4öt‘¤ËÓN ÏŽZ®N´Ö%·í‡ WÁÿ0aFM;<ÛÏ·ÄYW·ý¥Ÿ¼,ÐåˆA>b‚çc,xùqm:ËQž´%½3…ꘓFÛ6 µU·}‡yvÌÎp.f6G%JåÜ |‹Šc=ü .Ã*L¹﬒3®žLì{Ïyéõ"Œ6tŒ„ò)‹˜fA˜Vªìµiæ¶®QŸJFZ…õ T#£Ê–øx{¸*O¯­KÄèÊž šZPAjëeaî×F»,ôƒg–c8lƒF~6UòÝ_”Uí&ÄìH@3ì_Ý—òkæ¯V°Ø%2¾.áÏ!äݤÖÜEeûò(Ñ£Í^‚|Jhn±mŠq£ÐŠ#L:Úe†SÏ·‹:j,E-—i»>àç%r—çv›¥_Ðëy¿GãyïR§÷ aH*Øv Ö )J¥A´ï-l,­“Lu¬(z—pÂü\\þÛç1ã²Z¥¶Ml!‘tŠJrJbÖ¬úÖ!VµÔ¬‚EYœ 4 fÉc‰Ãê@Ô¬"OéøÌZ¬Ü0,ž¢UDñص¢º‰ù÷ä®<¢"zÖ夛{ Ʀz1_5( `Éùí. Q2® æ¬Ú®Òäo+c÷̰P“ßæçpø¯éã?Ë}ìW¬H×<£yõF^ë‚è j}¸g2/skø™ß¥†¢Sô]‘F—¹:îIÛ“´Ë@\ bºlÈG'ŒvRMèJ–ë€E¡|Þ»±NõÍà°ŠJCÞ©3!â@¦‘ >ÝgÊÍ>ói“žþ5бæìaó°_–¨«Öh|ˆ&‰dÛCD49ׇ-.ÇwU $úœ¥®îýªù Œ¤(‡O§Ýí.¢_†€NY’KÃÃÆ_1nâùGó^læ=}yÎ|+oµgê•Y^'ߊ«¤D0G/]QJá‘ßY‹kùĺ‚…à’T¥7:ªÀÕÎr;廹#ÈA&’.î$,^ß:‰=¯»hg²C»§ªàû¢¦ ÓÀ§K*tà¸ç~¢Ì69 #¹JU¢ºÊâ z9.a¶øÛ¶0LQìÔ·ÛÏ” +ʘ™½{‘ü¤S¾ÿ´µVˆÉb—ñWþbÁôVÿmÖu† ¼ª)6«~©@ë0ʯˆDFc&޲¸u²?35(ÄæìžC^rNÞ·ÄÛ’XNFŸÁâ±'%Šßâ‰LbORFÝÕSÃðà ý›|Àݤã*¾,%èšúHŽ¡ÍsºIšû³C‘ØßÖìT-/G¹]« ¼)b‰pÔ8ãggÙ…’’ÆŠž½Œ~вRׯŸB—:=ï0o‹P|£Ÿs½kŸK€ëô—ìwa:YʰX¾uûwl†ÛÏ·|ÌRåS`3§J?ß–ßî;NAÀP–ïÈ[ˆy‹Ë"„ƒ+s9É!±\¯ùb;¡ÛWC|N F(kùžafØgTÞÌIß'¡NL‚é”ê^ì™'SN ±ôÑg:Ѿ'Oa²ÔûV@gšIÑà8EÔã3‘'eoÿ¿"¯µùi—ú¸^õ¢{VÚ!‹ú¶v?¡´ßGÔϓϏ–´úØ>¤=¨Ž~6v€Xfå+¾ÂÝçJ.É ߇ìÓ$¼ÖûЫ›.ƒI~©KŸ½¨Ò8_õ}g¬ëgy0oŒw°þ4ÃË*1¿>Yør²³ËªÀ ¯ ;F¾ûÓJÜaM®õé¾ízFeu‚ÒÐ]Ü ¿ámá#úÚêÊD;œö­Î£í³}T²3ê¦(ÓBÙsµ§W?ÜVo¡…!)qʲ.ЕD?ÏDìXMD:zZoÛ¦ò‰&Rí\-Í‘‘XyµDY>z‚C,}´—I˘‹ú®¯‰1~ ¹v¿]}?°É/IfRÁÞbû4Ôq!¨=1ü¶-Àæ“K‹T<øP4€Ï¹ ×°kèØù±ö¬ùnl·ÑljDC“GP•ò¥?^ú÷³£å–F]‡œUø3Íœ%²…ŠßmETš®oí¼ ­ Ë lƨÅ!Ä=Þ‘M¹ÙV6E@ ™JµñvM·ÄTİ‘×Õ¤<%ú^E$zaè¼R®:«»Éœt¶Õ‰…TGtA·>ˆsH Äf(Ålaç[Àö”” æÆ£Èi¶”¯¿|´µ>­ðbð›¼ït§õn¤,¬JÒIL¤0êr$0î~³UˆTñÂìÛkä¢îÜè—9šÖA?ûüæóÑT¦fÔ8z¾8ü=5· ìf ßcÜȲ/6Ünz‰ÒfÍ)ñ2¼$›ÍTƒ7ƒx"Ó9Ï]ªã¤m£9éz¯dyÈG¡äF¡}Ï2/~ÅX%›bÕ>xò€FVS"¢=ÏIå¿`çת§Üøágº×DÈ\4²x—„Ñ:DÙ'üªÊ%;∪bV~y5ŠáŒç>ÊÆ¶¯•®¤ RX%o‹„wå3×IÅŠÊR;#_}c#{XÐ*@ÝU׬w}iÈ{÷^‡òÉIæ.¼Jãº^§—tfŒÝ-ŸlƒŽIÎxì}ð ŸÒð ®!Õ‚ð{nõL¡ R¼úãšóS2S__UŒ3½±r† úJº•g»µõË5=Â_ÃØÏÜfǹ ‡\¾ñ€4|¹kêuèízÒ¢$Љn ²ejüW—s nήwK1÷})‰©Î1±øð^MHàøaZÌ©#O%¾á›D•ë`:Xs_JEÅi¸ywåÉ!=u,û~¾m½¹Çq¢¶d²Ÿ­ 1Ú¤Ü~¬1$#þSúìVÓÉ 0¦40w°>hA5EDMXd,yÔÕÔp£8£y–l9Üm)¥hxa‹”ô¢}‰ö~P§«àS`7õC»Q¤ ½7f^¹âÀh˜’ˆ´¤³Î¢ŽR»ùþaf3p‹¬hÙP°Ëã(‹gc '® ×$zàÚ82$‡"MNväC)Î htUüSñíãI*±|>Ñ{vÍÒb“°m_˜V=(X{§@¸¶'úüü¡aaÒAuèÇTçD>›>kcE(úXnýaæÇøõ ŠäLZ2˜Ô”AÏ“$5'(/Ã…ýâŸYV'9Ì^ôj9¢×Ý&©|Àh⺠¸œ*Õ @|qGsî}œì0Ôf†Ù¦Åi*ükâ³j'fX;]›3î·ËÄuv©¶Oá_Ud—H¯&°+ ¶B‰–Ǻ ÞÉJ»$BO•÷ãÙ)óC›³Ló#óà#ˆ÷¤m\°™õ͸Y€®è1\,Ý“ÔGÞ˜¢fˆfígÅ,pDv”Ê oµ+üê£gËBß}¯Oµç`Mü‹K@¡ëÅNøvFDYÉ€!MÞÞIé}Oh‹_ÍÇÕïäÖªN!ó8–Ÿ²V§‡ƒ6B°˜«Íx Ö­_W«Ét×ã·EšÞ}a=ÌhfúŠ™Þ¬°ÿ™‡zJΗ=2eJl‹<Ç.´‰ç¶ãTð:ëŠÝÓÓ'Îé9“TÐû¶òÔ®LÃJl梢Ÿ#=+ù­åßIºy^°¾×ÕýaNТ鯑¯x,²¡A‚‚RÐõšá}ùÍ®Xì|ðôF ~j‹“¤iBõk|Ä qš–)¢)¹jtš—­ól¡/^¯X&÷YDÊtF¢_€Ùu—dzáå»Ì6ÙrñüBV—6Ò¯ @ô:Ø]̾…¸yÅšwÛ¸cYD~087Ð*…G¢P«w°@Üimzöii.¢š8¢®Ã¤:NVE·TOÈñ÷âšN¼Ögù²¬‘6» è–ˆúÀf7¯Þ(*ÅÕ™*v…ÌXD¿±ñZ÷<'`C`;h¨F™C~g¥¿hØÃ;"–.·ô[’‰¼ÛHtìÍ»ËÒø[á4J«GYBѬ€ëŸÆý?”Å6lßíXnÐPɾÈ¥Çá^Jú5ÿe¾V»t÷ÔüƒÇ-³;êF4»Ù mVÏÁ©†éPâ—>1#Ùx9Üœ)añœq;Ü8äSr Ãfù½¯3!èžôK¬áÓÕ¢µ`åäF;o–å¡kÛ—…¢ˆÔ²¥á51‹µŸX,!1ÂæËÄ]+oÝóä55°R{â×_ ýün“»´;²M/¤«²a[æÕѽˆNv¶F£b³)º?m?3“4£Ð}…ùºDû(°y²™§ë¿,^qœÇ#Lgl’‘‚KΨ´(ó–DTúË öBM¼&úÉÚîRÛáfE[Ò¸jãðyïÄÙZ•Ѩ`äºÈ<öÚ^Utü‹žã儇­]nâuuÃëyýÄóø_/k;Â"˜Ÿèeƒ9Mþâþ‹ ÝíÖŠ¤‹”€Ÿ¿}v¥qù}ñ[sÛv® ‹,Ü+3}X?)þ ýö.ÁËŽª óÃÆr/ñp'£zÛwÐÔýíŠGýW4ÈÝ›ŽÑ¶ë»ÿ^ÂÛ‹HŸ¤’"¨Ü”6Ë7F+N1æQŒ{wSÀ åóB$dá ¢®qœ¯D,‡˜JÎ.|õl·žñ ÛÿØ’öÓß=Mi¥¢cH{òA¼?‘Âüs«ËOq;°a$Û ìÍÊÌñ®iØ® ݬ̶Bôð ïðzçû2Óó4ÛP¾·'¥²OrÆ9±óÈ•K¦D ágZö®nÛb=iÄ£y™Ô­| îí'ò×/ìÔ,Piqf"3 ¥}½ö²©ÈÐ/ÆÑ›ÄgªÜÏÇ4R«³wßWsR>üìÊ"ÃÃU:e¬Ý‹Ä~ë7ë¤!Õaì=­Wÿ+)r¯’¶‡"¶T/Ð)Û'âV“£=¨ ­ì£µ°ž¢Ô3¨…¶Ím~ •79£\„$>å•ͦ¨R¤Ÿsãi~øìœ¹~êI/n{qÍ öÚL>µw±T?ãD0Í­ï‹íá"/Òü•½èþ 픹î¹an@^jwÅÏ8S)ÒÁŠÂíXÈ1MÞO ˜‡•K’<„}õ»eÂðüJ\{'™"‘Ÿc¿ü䪉*šÛõ`6v|ºÌ«ë<áÓ¦L )…æg‘]é*«§=ÌmGÆù¶ì‡u7"‡Zõ“Q™mÅ¥¼Y×­æw!hDRFlOQoM(]~üŒÜz¢pR–ðôà¾æ,â¤Îez(9ï‚îj(¡WfÖšO¯øåsaz»¢ž9!£#ŒìÆÏÜ'(¸‡…‘ªwP^TQ2½^óh!Ìdj‚Cúo™çG7ŽÞïˆK•ÇmëÓþäëåŽe⌣üá)9ø‰¡ÓfX#Y’8÷^cß²ÉÂþªwhrø5Ï ÷ù:GáöújÄóƒŒEvÖ‰{Ì+œeÏæØÙ‘H– <†Â,sØKð¡Àm€ÆUeÔÅrœþ5s$ÞyͰ/ÑX ¹,‹eÈ +êî«.ØÝ(W™_{@xxo´½ø©Ÿç!ŘWí9µ½eïf.cKÔ<»•D_È’ÉÀB¥>ýYþsר]ï GIÞ¡M¼íÝÖË×v’š©úýi[¤ææskíϸoâPü«Ü1$dw|Rž1Å•­dRy²ìF‰[=/óI¿‘¢x.fÅlפ·ûž!_äã›´Ij¥Éí%„8¼Óà†QFÇA<lŒ1^ Î~ÒL¸Ýßí¼Æ`4ï4W“D¤¤z`甕VúÁc#‚Œ4ós)=†ûb‘Í|øöCï ”HR·c"Szwå0ÓŸ F> stream xÚ}wuTÔk×6]ÒH twww·ôC-H§‚€ÒÒÒÝ%-Ý‚€tã9Ïsð<ïZßš~×ÞûÞûÚ×¾cÍ+J5MfqKGs Œ£„™…Ma÷„@œ,lh¯^IºÍ G)3PÀÎÁÊÎÅÊÁÆÆ0ƒ@‘ôCM¦£ìæjfý;‚ƒ ÀÁËËÅ…ÆÁ°Y@æ@këïüòVŽvž¿í–nNÿõ¹]\¡EtТôhIKG°Àh]竘Ùtñú?n3{Øëÿ  YÛ@tÊ@K›ýÿzå!f`…¸ƒ5`ûÛr•y-Õ@ ÄÅ ø·YÛÁè9Õ]A¿%0³³±ýOËdaçtupÿÇ¥âY@¹éü§Eh‡LY5¥ÿ%´‡j÷ß|f®@€ï¿Øø·ã? ƒåÿÊU÷/X TÕ¥5äÿâ_>i GKƒ5€ƒ›`æâbæ…Æ`‡"n€;åî zB›eeqp„@—œÜ ¾+G´ß3âá°Šÿ6ýx¬OˆÀ*ù„ø¬ROˆÀ*ýâe°Ê<¬–@hIàS¨¸ÀUàùíwv3?‰%Ý·`3û?²@¥²zʰ¹ÿ‘ö·ÛÑí]Ø !ÖOE ~ëßWðÏ(w›§N ŠÙx9Ùþˆ€Ú@@(yÛ? tÄv@¨8OMð@Uÿ¾0žüP)ÿèˆðTŠšËzÑüá‡êâøÄºØñ_nhGNOnh2'3 Ã¿¦ÊÅþë¿gÊmºAŽìD¨ZN`·?زC-ÎOÝüFn@׿îÇæÄõÛèZšƒÿXµþ!2;T§´ÜÐ6\ö o"îß1@÷?”ç†&qy>ñƒÊã 6sµù#1´‹§ž¸¡­Bl\€l ¨$Ç?@s¸=mlhM·ß×»«…£ËŸºB§èþ„öøãXA“zþ¡U½þ€Ð™x?q†fòºüÍàß·ºšÈ¢ååôÏÛôûšÿ ³ÿ5!.Žv@]%ÄæÏe3èñô4dcaƒž*¶ß¿ÿ~½þ¿Ï†„„£§37ô9ƒÞ}ìÜÐ8>ßÅY¸¹@wä¯gúöü[ ¯&è ´@››v´ ¶­ n¾ª'ñ`ÞFZYkø ßÎ ¡™Éô±QBN‘p–0µ,}1”¨6[:>ý†„áçÕˆ§QGZÀr‚\FºgCâ˜ùËÀõi‡5ÜÒ‘Øz”71bç(V ËÔÁ6^wú.„·“s§l;ç¾ÕuÇ€ÿÀwM™@y/þ¹õ\”>åË5È ¾v4®‹a’›–¼öè=\0/õ½üóý£F¡<ƒ¯Cš™Ûýˆð–a>ûƒEvOÖ:²¸ŠHç›xZí—F•ïH-\P‡%ÒŽ3e•E+&L»Y£ê…|k š›`é=rìrŸÅÚΟå0’fnz¦ý|f{T§×Õ ÃK.‹ëèåW†ŠÎWmø,}!‰.Æñìy‹C«\jÈŽo'ã‡vY‹ö¿ˆ~LQ„ÕÛ©WPå4Š´Z<+ä¹”e6>õ{à:›ç¤È6EfžŠ}d[ófÚ aÐoae„pêœqÏÝI׿ßÏÚnÄ­ì“‘i†Œù™€œ‹Ù¼SC)X„Õõs ²è#ο,\üp¼áżF÷ =A?ŠÅm§.ÐÔ.Ç·,3‰^Kkq.ì}îpÒ~F ûv«ÙÚ8ßß«¬}£¹åŒÔ|K¡ºs;È}„˘ˆ¤±Œ«.š=÷à¥ÿ“e«ª4oBºl„Êú(ÌïèJ–NÝ[~&š1ýä ·è.ÍÈ#¾þvf ugãþqt¢÷ÎOz§b8ßï›P¼*>Tö‰“0Oh9M{}%ºÁŽïÙÄ>ŽXZ÷¡2„N¾ËJñt 䇫 ”9‘lCÖH”Þƒ$ÊÜæM'£éÛÛomÑu7Cù®M8*õÚæq­T¨;ó¥oÆÛo#B¯ýè`»]/i`+ç~ź0â:QÉÝJÏHð•HgLs$´›ó“ m•!^ë¾î“Vg2&õ¼×9Ç×0†”"ä._m‘ßû•ˆobq\ZA›»Ñ1Ì*IÞ Ú—mJ¼b,¯°´™Ê1`Z”MÞ̓ۺ­W£¨8œÄµÀË#q(3Ÿ‰ÍùޝA´XÂD°’CÕ–|•ìª2βùv´Õ9ýY¼„;5çØ’¾Ê6º2šÜ|jKÓÖ3xìþµ(ùÞ* 7e|Àë¦ Â’^cVpS¸A}TBìÑî»ϬRœÑ¼™ïÉ0Î>ׄM©VÞnaT Y“eì„ Îœ¦Žáö¨ißÙÊ)õv®„c ¯øºçÝBò7‹;Ï0NªWå§$Œ’ ,ËbŒ$/$…~ñõ Ú¿À*+˜Lî”"COÔã‹8!Qóç?ÀÒ?Çßûu'-eÒB°:ÊJ–SÍìjsðInî0Óã½–ÒWûf.]3„wÅz1þN.uÜŸÈíkÔ¹x•.˜—)™Ì&àú_ ŽÖú…H-`÷k5Â7Ö4OÜã¹*™2CÏopº00ø,IoLK†“mÒ·k‘ˆ×Œ5‹ÚíÉÍ=DŠÞzÄHõ‰z åì'ÉÕ1¬áb;kR‰Q‹ÜT@xQØDXám¯Z’Ïyl…¾izF´ö²´Ó´üåóeB…·OÈÕ¤B­DÍìâ]A93?Q^n²›„z+­\Š&¡Ä¶(3’·J³¹Ï†[“g‡¸æ6—&Gýkû›Ã[4qºX‡„ª 9i´Qdóô„e¯7(S'òuÊ7tj_¾˜üНc€øâ…á´Ò³=0ªí¶¡ÎF­ËÅwRÔÀ‡Ipa«¡“éåžlJ)¯îrq{9KòÓ®hv(SµÎ±o÷.‰.R\$c§grÜádâéÈ}ðÞ…¶é3«Ôw‹aáatÕÍIBS5áûÁ™/þuÚw…—Úî;2¯Ž¾¹™Û˜õÛšrß³Zy-÷¸Ê6)²ÿÜ»âÑ o°ƒ‡ºÉÒw »UáÖébP'hmb‰sëÊè—#œËÏHÇÍVÀw{Ýe^·N)°púqžõ„ÈéƒÙQax„ݵ¨!~ºŠ[ï„b'œÛI?nÖl;*¶=œiKžys"rÑ[Wǃôƒú¾Ø±idþ¢æÖ½ˆŽeîí_[´×5›õ»Á"–×–8‹û]ÔXTq¡¾JgUÔ»=‹Ú \ŠÙµh5Ûž ŸC¾®!ÐÁ6ºæ?jfÆñmSYièx´=~#ÃaÊnª+ÙOx'ì2ÇÒ nþJÓiË„5XCVÿ=u„T+1©å=?ñó6Öš9`áfl=6çÙYÙ—61ÿ7Ù[™>aÁ ² §}” [ ‹çvpH¨UåE|ëþóâ× åïÚâ³P>òL ó›ÉCégêOD R^ò‰k'ÙNŸ³}UÀ ”\]ß ›->]%ëøÕT|„$a_Á77µe"mó3<Òà ï'ˈ”eÔWRŸí H©ÌKƒ5Mt;¹¾#N±_ªß²½GTt¯D˜-¾ñ bozþ>†ŒEùÓ\bÉkùl<¶P±·Sð¨Éœ˜‚Ü’›ºf°hšH¹ÇáÔ¡?s€š ]X»œK Ä•Ç îdgk‡¥.Ѭ%탣ÉDŸLN:É“VëT…yÚîÆdè_® :ON×:?dø†§Ívz3¼tÄOf53 Á€à€ m AôVš:bd”\›ƒ‚ÐÆ¾ùáÐÆ-2€QY÷Éý‰Ò€Nr …ñ~GcçŒ\íyËöÍÃWÄÇÙ`÷ ñ2ÍZ„‹äŽcŠiÙz=–úøÅüÅ£VRî0tYYJJ>®{—HŠÚ¡ÑÍ4“ª¾4ã! ²%Ø„-ed©N nþ1\}üÍù$|ôE`ý/šÝ é]Àì§=ʪ— QQÖj-–J˵:Ñ·Ën۬黦uðŸ%”z¥ÒƒÈˆüC¤Foú =¬ –€`Ø&L¤×w°(†2±‘&‰¿–ÁÂþe) Ÿã˜æ¨Cèºßàï‡K’¶ÝEÌ?k6‹Œ?€].ÍÛf¨LUE€Üœ×)k`wNl,‡È"êÏxkÕEaDz’± É|¦ËTVDã*„<Џ\Ü€ÄX¾Æbá&ZÁ4ÑG_‹ðÕ"ÌÕr;ôN%÷autáMj+QW“ìfí €M¥¤9•ù+³Ú·xú±ïû¬vºvÚ8Ì_)¬þ˜ý'l=¬Ÿ¢£ïêaôý§’tÏÁ;T¢êvmþë Á_æx ” šÔ¢O¦?^ ïºuš"y†Ôƒ¤ü9÷ªíõÒƒËoÀïß®Ð4hà,å{*¢¡±s…+ ¼Úçë8>õÚ ^’Þ!W¬¬êͺr ž1‰ýäF´.¼Ã]SÜÕ G%2¦ÿ|õ9ej•öš›:8g}çò<‰D_c‚ŸDýl™ƒ^×͇©­÷|®.¸À”õKþ}|å›dÞKØgzÎðSé_ H¢šÄO´æww'ޱñUÇÜ]ù!š<æQ¤br<·âßÓ™*mý8k¾ÀmÏ›[— Š¡Ô} z˜­ýpÐ;_P¢¬«Ê°Ò(acû%˜Ù¦€ž£Èò‘hOðÓ=Ût pbþ cvìM‰%~/Ïò­›hÞ|øÐø˜jô·ä‰{¯¢‘³ ]JiOÂÏÔK©“Jäµõ]ÊäGj˜c¶Ø…ÌýùãȈ´–ÀΊº³„Ûe¦R>q³UX‡ìûå¤3ðNd‹ß MõEC*ú§^†Û¬)‘|ú#©ÆŽn~Á9Þ á$ÍÌdW×Ç¥Uº>Â>÷r«kä’î1œlÄI¼¥úåWëqçýd ¹¢9üñÆÿ!ˆ5$|&®ªÖÝÄ™gF$ÖÅ+!•^åöè£;lˆiÈKe˜<ú·GG©Zhɵ(c/«Ç4-„’PLëU€_ºÄ`ÆNYq4ót>c4ïw|Œd¨S(«X/÷›1EÔÛ‘pŸ…NàæÝot9'¹ëƒCa©ÔÇ™­³ÐLYäGgZ׊ºø-a¼²?¦UùF×_Yôï-ç ÅgLû—È—î¶a]N}“w|Tlky·ï¸jΕæñÌ­ÞèꃺbuÚªNqZ2¤CކwódTàVÎ&)ºtÔùáqD ‹ÓuôAçÏ2’, ÖŠZ:‚bø„åýÆ&‘q1i»î(ñØr.˜ŸmƒúýÅBÇšè&Ñxë$Öq[…2ÃĦôáÅ÷ð¼]®VçlŠKâ/ï>ÛQªýtC̃eÜÚxäײP#¼Õ1úÚ^¿É:·šÔ=$Ð9¯‘±y[é•öËuÈZÏ8®ÏygG§«° þ„1=•²<ÊmñGXºµB~5ÃAç¸Ø9^¸8ê¨5ä¢äºtÿY6¶M¶nVr,'m]Ê ½…wÊvµØû<•Ê;Š-ÙìHµT ™ý^ŸB’ªž©j ¹Ü¥˜Ç"ï¿.̾4cvÛam½‘>ìåxk¶:ÛaKYm"ë¥.SH»ÓO “ãÁR}cöƒF껾,é2Ç«‡Äi·ÒóœÀ Åï\T—w„N+µËq2ÞÃv¢n”áή3MÙ9Z¬h˜»’¾Ñ,M>Ù%à³AÅåþ+›‰ðÖ®iÞ»Œyйúœo6koƒýÛî¨VÊr¸?0Âê¹ÎV @}ÖQÓ„#¢Ê»Þmö«™‚ðÑĘŒ¸ÑG[Í«³h2|k…2m¹.ÓéçðøÙM*±Ïß[Lª$¥Ê,œ) ªæ˜ìM?^Á·™M¥¾¾]ŠmŒšbx<Á"¦²·_W+gþê¿> ý“ók³-H#¶ˆ=‡±rÏX’ȇ/Vy<7\5ŸÍ:ö"¸}–8–e<ÍU"^i³Ñ» Ϋj}cnãaUYBåö—U†‡ `{á}dÚç ¯zXå8C3â*ÏœoÒ¢´{ $?‰=3 NR¿“X{5|}ÁâOVœ´EjÊÐeKOkŠwcÜZ©O‡©êÁµ_' [<Û<¤ÈK*üÊq¥z×ì!H|lLH .{{Š;}j—Á²€Qf=•VCõbv¤D½Ó:k]ØÙìqíx`þL.ÈJlÉ/ÎIYò­‘=bD\Æ«Øj4t‹žqa[ø%‹éTp À¦Ø&Vž}Û}`f ©ZÝ%&mîLåx§áï->ár§>ôågH$-¾ÚEª¢ (¥£CMÄ$Ðmdžûº±»®Æézv%·›Ø{õ9Â[Vož²î‹âÖÆkeæ'à˜ Ôã•[v…œêa£Ã»„˜ÐæbûãT‹û!Œû,8wŠ|–n†LÖh…ôyÁòu,aœœËbiòv¡ „–B qì ¬l €,‹Òð`ÀL9V#cª¦[8Za‹ê®çøù„zÂ}Ö]ãJ¼â~más‰CÙ±šFÊ57yЇtrOîÁ+@H&ëG¦X¬Ý{ÂÉo0yÛl,€‚(æôü½ºã›ƒ·*" &D1xÓÒÁ…£!)u4û'p§#¥FøU!䊽¾¢^52ä‡Fœ¦ ±©{¬Y› Ú݆!gÖ¡ïj—he£kØ“:H@f ü\IßVeYKö Šqb©÷®øl¬\’í­G”®ÔÁ9s¨°\á\a]Ñ;éqV_œ1$x…¢G$‡65«×cõ¸+¶&QíjÐN”û”ŽºÝ¤j |}C›1ã=öÌ‚Âû4¢®ŽY cz«3;²N§ÄU'¼á+ ˜ '?ÇÌ7/”Eg/¿ÇÈ¥ÓÚÄöžÀ'eãà£%sgqJ<æ ¼2°šP»NpÏ`8èRF&±¨ Õ@2“i –>«d½à¡ñçSŠÌŒi7ד©^XKÜ¡U(y–~àC•âú^)-Ø}Ä#n‘k2õ¿ÉïY¤ðÓ‰l¹aúRž‘®À‘}^¸š©—ˆ{¡ ¶¤#²¥_X7Ræ‰_†ürá;ý­m”uàwGÌă=qÿº¨¥¹<€8ÓaŸôÔ©.¥¥öñm.…f>ªÈþð1Ó(«Ä\eÿ4èºvä—-!Xy($àÔ®ó‚å4*ê嫬áûŽå‹É XÍyï2l! ;><DùyĦ,¥Å…” Sš¦¯`ØÇÒ¯‚IqDbf£4Ò¯µ‚éšmòcúz˜BJ³ny¢a¾MOIî¶0éO7É}¶f¿Å–² ½tìЖŠ}³‡žj—‹…Á-0GeY6ˆù5"h!/h ŸdoçQ ¡Yóм»š.­Ù—ÖRÖ@ŠZírJ&出Êó·ùµÊ{¯qºëƒÒy¿8–€ •”n–ä¬ÙÝ‚?¢êÜ ‘2Ûéˆ}•´j-±]~±;âl𤰒hs&‘C~±£œGt5ðñozÚ¹Ž[›«ì‡ÎS‹ecm?*Ç7 ;ŽÈ÷†zw¬ç(©hDù¿ˆL÷éhç‹}Ù–>¯LöG´¹Ñ!vxáøüc|“EMý9Æ~÷ÎÂ0la=íz΂ÁR[Ö¹åZXL¬Ñ9JC‡bÑHË’>1F@ñ„Þê÷tntÁåyå*åÏ‘?éÔÄéä{z¥G&mâ1Zcï-ûê)ÀJÝBôDh߸5"_®Tû ×ñl6u@š1i PÃVYzdk¾†»_ÅcI’’ïïSpüp»“²íå_¶k¤™9wÇ ´²´É¸¯œ0ï°Ø%㊦YIQ•ĨE6Óuuu1NLÞÛú”³šf®rãûd\O.²Ùóû2Û àSšõâ¡X¸}Äq¥šO¬ŠÿbÐnYzgb/à¦^Ñ2\Ò#v¯M›‰ÔGBXÿíÆwe÷– s'Ÿ6úGÌWÔú¾® dsQ:Ùª$^Ÿ ]Îåº5(Š'k$ðÉãÙQpd.ôäqñ‰¿æ®íÏW~ÃAìýpñŠ cò^"Á3}¨¸b«ô£6Þͯ¯lgJšs] Råô’$mhA›tÏÇœE~²¶¾ÔØd±ý™V¾nz½užƒ–`#;?ÎÆè2ÖÀÌ¡9&r"þf€wƒ1ñ B£°ˆ‹?ب<ÿqeö< ïFÚÇ^;üNŠÃŽùœÐUd´E»6Á{‘Í„{ºB»ñI‘M`Ê,ˆÆîî=³mêå¥âÕÇD`î•„‡²,^•Ë­2ͧmXð’¬ë1aïTvgm¼,am3¦Žw#WVÓÉ‚ \øwGÛñ¦3«x’pÃî1c 9tTšÖº9NŽ~µ„µß*ïxÒðšòì§õ­bûõÛĵ ]¸ô»È.7>ìâECyäŒ\ÀíØB7»]Oóñ^í©êIe‡Òúº­´ê+šå%„%;x±ô31vÉd”ËiŸ¤áóÛÁUªÒÛ¢wôž§zKã n™YËd^¿n¨ pG5´¬e ̧;rnÔaP᳎”L§dA0KAç°ÏêR89n *Xž­d +H¥*)™OZ ­àç“[¹X?$ò¾w^ü€$ÆÇuÀû¢¯w2z1É3KM“ZµG‰Â7„kb¤˜,¶Y“.Ÿmµüm˜† ”VÑAµMÏ™™ƒý˜ÎAÊuÞ‚cʘVÌ`ØòaðPÖ4 HÒî`ÝÎQ÷Lõ}!X¤1ÍÆ2+ot›ßA»õv7Õ2ã8ä”R-aOÎú~ûìYô5QkAwaýÌQQ½x…{•7xÉN†BòçÏPᑉÇ.©Tnþ,F•y¢D홑²f@÷íÅP·×/§¢XÏ×”³·CA™¸[C¦°éoCÄCDÎyýÐXDRô.\íq”ûøªûɧ_èª'{,â¿C—¡8½~|úé+·±@&&ÃÿudñT–[p)°üκÔÈîG²?lfüqÁøö%ûøÌÔ~£N²üIL~©C6# CfÕ™qhÐæêwF¹·qET‰%VÙ Í$.ÜŠ±«öF&?$Œ¿æºÔ Âm„©—÷¿à(c[üúõh1–zNÙxòË7ý|'zÎf…ø["âMí¶ …`,¦¦¤5e´Y0ÿe×A@WÕ¼& ÅmPÛ³þQ’ qý[aì;M˜¢®w1%xrRm "òiâ²Æ?ªQq˜Ü¶øõF¬6Å·•DkÄp°¤‘xíßXEßÕ^i¥!—˜“<´× [yóoíø8|>}µ| ,Àp0ôžÝËžº?‘ô¸´.ñˆ~ ¾Oìšv^ð÷«qr ¤džyï"¼Ï›Ke\æèY=QÕX. à½Þmº‰¬S–¥“*iâq<0þv¨4¨É¶¹—O4¨ƒe`åFvX-fO^‹Ñµ£ZÓC7ís¦6âê$EE{ÎÁ†g~Mš±¾°Q7©vÕþùÿROËv endstream endobj 9834 0 obj << /Length1 1193 /Length2 3706 /Length3 0 /Length 4442 /Filter /FlateDecode >> stream xÚ}”y<”í÷Çm%ûž"¹³d73ÆØ×±%{B–dÌ FÌ03ö-•%eß·²dÏ–’}ÏB‹"Deð›êyž<Ï÷õúýußïsÎu_Ÿó¹Îu ž36•PGáìÑÚ8,Q" Vˆo"€J‚i5ðhƒÃj"ˆh"‚Hƒ¤À`0€ ’Hôbl@*37ð V€¥¤)YYiiZ)0€Â ‰€=Úƒ¥ýü¾.Ö@d~ÇQnç<Ñxi@˜´©@Ú…úø(´i‡‹‹! ÿÒõ?i„+ÆÅçÿ)°@cˆ€°…ñpýoV—ˆpÁ Õ±Ž.h@B^RZ,ÿ;!hc¼Ñ(c éñèßa3, wÁ`ÑÆ8æ§1€„d¿s—0ÈëX4ÀþJâˆ$I¡ù_’útŒõÿ+íJrðïï!H4–ÈýÍ(ôï€Ô_4õ_3Hÿ²dqÅXÛPGì—#¦.,ñDFöw•‰Ca°Ž€L@àñZ0! ðƒRÞÚ›Ô6H‹#’–nÄÀ‡§ýyfò²ñ3ô›äý’@Èè§3 Ô„ ô”@ÿ J"ŒçÑ<)âx¥Ó„ Ì$©º~I²\Ž I—ë„ta Iî’t¹ýƒÒ¤Z7uA;ÿD!Eñ¿¦ëÏZ’f÷#HÒŒ?‚$Í„#(€Ž®%µàñÇJR­Çω" qø#®@HyARg^té@ÞG$Óçþ{PŒ,ñ²ÿ™œ_ ùͦD<î:Úƒ":-1@ñok°$˜t–`àçüs®þ Wÿw"ápœ·ŸŒtSä F*”“’ øWÒOò’øë¿@ë¿ÙCº–h´7I;:ŒC*Þv~|»a§BÛKb®ÿø‡é¦;1–ÏÃaÄóï²üœô©Ót^¹ÃíP¥§z“GŠB‡†ý¹EWv^zÛ´fO&]x@$Óz>_“Èîù¾Þêˆ>‹Âq9È&ß™aY5áa²³¦²Š·þ"Û/ûôp¿‰0o%¿¸ù[Ìç’¸‰‘ê÷›–(îZž˜&¾°´aŽbÅ[§x\Ö5ا¸-Ë¿¯Ë¾˜0`*£ðâjHN¢%ð4Û$Ùý.* ë=Ó­¹@«ÞñÍY¶Ë-^Û6ØÊ{gxš~xÆZ–»Ž¾žjÅ+»ÐÝ¥€ê"цÀEëóYæòK+%D¡¶•r² „Ç»n9Äg¾õïUIýøñôå;ÖzÁîm…;ÍÁ’]!ɯð¶Ë^ñ¼üñÞ)icj\ÐëøÞy¨x1[5!MüÊ|ÍE#¨Mœ¢Ãøú`‘Ì6üv§fµ„ízàôưËÃ4úˆ¬Mkµð´¯D¿Ò ·¨e#HR‘5߀þ€£?*ŒEŽ8ÏÄ}8¹ÈÃcÊ2PˆX[ÆÐñ\Ù·½iLœU­5£µ19"7ïlf¿ÿÎU¸„Û•VeüNïú•~ón,k ¡é ‹¨rT¹ÿkúj!ä¦:º“ûµeƒ‹¨Ö·gÚT‡VØ\ü\Y¥êo:ç~¼a×h~ïl•U,ùø¥IVÕŒ¨ÑËɹ"¾ÒüWZe/ùWÃWwt„Mì©`ºï¢Ä2¿.wÿȰñН‰aŽcLão«[\‹Jö_qËæQ¼Ø¤YBç/jêü5®>G³¯±m‰2Í%„äuOTCè,ƒ}ë"b8ÒÜ:¾ÝK${’—=µGäÂÇC¨U)„kPûкb ²‡öâêjò꾜Œ^ÎçxÆ p’ìþTéøæ.9Ö²ÏJáÞ&žûž¹õïZ%ÔÈ®¡|Ê뙩ê8ø¸NQ`¬ô^ÑR…$wc’uªË¥Ž'ZE½[è“–>kS¢Î°ÿø|F(ÂŒ£ýs«þÙØd7íþ}ãº[ý-¢÷J¦ZÈ'Ÿ*_2æ^‡è_ÎìÿÞ¥Y¥cAUPnø} uqßÄkg…§âïøÓŸ|°îäsØŸtðãá¿9•;?Çôêº}úõýT›—œï-T)Ò/ñ~©ª›Ëzœ[Õ4MWq¢!jyUï IzœpFtL‘üí¹è/´w¸Ô/ª{h°fN¾xyÒOíÜ‚–ˆø£¬»ÆÖ†¿!Œf†®þM÷è——k&7.ùv„˜ò¬0œ\žIŒPõrbNÕp[¾w^û=¼Þ£MéÔÖöc€«üÊÈ “DÖ:œ2­àª’ȸo±Øèb7#‡¸¹­%à.ÖýEWN%°·“–bi`WV­OIDRÓë0~“V/ŸðC©¸㜈µ5N# '@­CõiÉ;ëÔ)Ÿ¸ä'žØ ¶Ü¢f˜±ªê¹cR«‹tî®hd ~1£–!£¶åu‚Ó!¸Ã묕S½ìa¾9oøF<¾2ãÕwhÿ޲Ös°fV£§|+ƒÚ1¹+¤_Ó«O€"¿£Q³j=öõò'Ý0)˜Öùè&ï8{hd¿'ƒÔ€Ù^ÉÎLHÌú‰zßE¸†`~¸r:φڿ\Kc‘ý²!…ïð³ép\ÌP'–Yàmúýãƒ[l‡J‰C&³p¶¨DÖÍ$‘h³Ã¾Ò7?>ï¡òšP‚ÌijLÑp®^Ò›‚&0‘ÓûÜÖþƒeŸÈõ‘á´áéÚ »kÍhÿ%ÀËÜd†¼ J)̾Ç@EÅ‹œõ±a¡Gdø‡òàAã—Ù§ÍC»Ô*cʄǽCÈ+f¹µ¥»™cäcy+E"Ï óï'SøWRâ‡Èâûì/Ðùæ$Öpr˜å†Uçðj ¦eë^7ܽÈÒÔ-SÏÍ]àq^Áñp¹÷µ…¦jðým6Ûó‹kº·mJÑYY™!Ä07R9Ó³?RQZ>w—t)U}¨0› ãù‹×ÒÜ€0îÏUÚऴ\Wa»ŸVs•ÐU#~íh  Ùûè@Îa&ôð8ãûápÄðD@|EdzWMm¦–^lp¥ÄÁ=æ§Œø+{-Ž+9Úz‚‹ôŒ{ØwC¸zTñk7É·ßÝÓ’_ï‚ÜW:C+4gÌ5›FÍ™[þ Ò•…œ›ü–^ñìm÷$¶Òð¡se‡•Q‡sœÑ‰MÖìŽõXãülý# ¨µÍ›1 ,ì¶û¾&ï;wýb»Õ'Hâz?ÙLÞXG*†‚—×Óa¥Œ¦&ÿ€ºætRŸ¯ûGBí3{JÁÓæA¡Bñ-aø‚ÏwK)ªåuª¼Ð]wÝ:næ|Å'ˆþ©q¯Õ'íêQ]v¾T#W× FçȵlÐ'e˜z8šÛ€šékWh¢/ ¯K³ “a‚¢Õ.ÆãmŒŽ¶ñälüغ3ªy¿©!6>0¤¼ª?×½ÂP¤ž´Þµi°­ ;Øññ‘7`| èZ›HÊw1ëêﲨ¯¬àp† œ‡ÎÁ²wàe2B¨už"Ü‹y-67Àˆ–x;ÊSÔ–lyäå–ãÂ)Ç“r.†®\’ȘˆOFT/€«"Ó»T>z3éFS{YÓè\5¶¼c^®ò ßò?èë³AÈ¢U £îƸ²Ã¹ÆçLË ¢¥¸=ª<|f@øížxŠ”—xJ#w=ìôMºM‡ènöô¢èb˳…,_$̺Õ0ø°Âæq5³¤F'Ê}T;A•½,=/Êu»iùŠédåX»ˆíHVT¥©„;xõÚ¾Œ­<&†Á}+/à Ï2ê ¥‰ÊdÇWærþ1š)š´7¾šþ%äùÅË‚‡»åÂxo²ø2þžB{"Y³ºŽs¸_GÂD¢MRHé@e&$èQdnÈYÊ>“$[bîÆƒË+ôìo³…Þ¨¶‡ÜœÈäpN`åîf\vR²æ¾êõ%"1yØ—\¹¼™QHLóW›1è»ÅVÙ6¹Zô7êHAÇ¢úFÂáÐ$ÚÐÑýÔmuÚžór¥õ¯ôÝ ÚSq¿ìŒl™#ë Ëœ°œuKPfDÝ*Te£a‰ˆÛ  *°výbæ¯BÇ.«ºdLNðH¬+Y¿æàÚ18âZ->«2cXÞ¯fë Š»n¨«ƒoÒˆÀêå÷dE˜dõLnŸé0Ê:ãEtÛ† ¨úq×J•¶×UÖœLqŒÌ‹êKò¯Õ±Ò[^‹¡Ùƒýx]}¾£øtÿ%‹&mI«¡aP‘PwwKä*:—å ˆ'LˆPç‡ó.„pó7¾òP. ¶ã-wR¬Ÿ–Ц˜eXÁê?ÏúKD>£91ÇÄå0ûÒiª:ïëågÛ¹xæBÏ0•ÚÎȦ‚¸½6ôt X9èÎ 63]󇡽¦,„*¿%ÄÞµ>Õ¨/sk†lÌ5ZŒhI”'S©X5¬Þ`0kPºU&Ÿ^’¦·êis¨ïŒœ/ õm4$&›—¢ÌUÆ¢»DºÚ…ÜBý}}·O=¾˜Ûê;'_z6ŽÍ¦V§(PJkh¢ÂjÓð‹˜ý±pi‰ n½ P=8,²žîšb æ’y‘‚ÇÁa{]‚QI¶Ok¡šß¬J;iµÊ)à–„c¹Ñ¨@Ø`~`¿O¥¢‡Ž* 5=6t/§çÇð:C.Œúôf‚t‰ÇèÓC‹½ã[3!,ȵöÒ¯S7sR ˽Zä÷ÚL'Å?$Ç<ôdð¡“[/býQÎðýì{¨NšŸd3·ÔŽµÔ¯²Ýy+,®hW«ùvõò²›}¤Sªˆî¤+R¿íŠAÈòœ›óè||±OºSZÖ©·ð®;\—RªjiÀ›™ç!d˜_Âhóœýe[&låö%z)pζC±ÊF°ë»4—&G˜fqK7]>ª‚)ñˆðyùœlž7¾^CRs-y6xièíÆpGôÐ}Òé‹/j›«>+Í¡¤ó}`ÔurW¨Py{v²Aõrú³ÕoƒHž.«ðÚÇ~Üëá<è^Ö ïé©vÉ µCf-"ÆTï4ûUã"£Õ+·å>uȆ{‹ Ù‡ÝJ04çÍÌ+¿ "¨ÏRDrV ðp—(ØEî(GÅE·>éלw<±—Š>]ýNR8¢†ž\õÔãŸä W!%Ÿô>÷‰,ã6¸¸{…)©§û͸&x今æ) ´b’kgÙ²"ví̱ÅǼ;/Šš:&wÝ!viqç2¯M |÷pÒr>ÿ°Ò¤VïG³à“×ÀÜê.¹Ë’@^°ð=2»ñx(²Ä÷’z±Ù\Ëž8E+KW[U뛟©žÑ¼QË${5†bõ3S<õ"\d ª–Ó:ö ?k²úM™' £™°YD©f~±…ÆãÐâ¨ï&Z#å´[ªd˜þ¶¾å8‰ý0Øz¬çºMä/½´}ýt±zpÿ0ÿǤ{Ë7(2_\ùްŒ|*q©ÈOIŒ³Kœ¼êT¼FçÌñððèÔ9ߺÌUËôZÝìX€b‚;¤|»Nœ¾)6µ}*KÇŒ¯Æò£lØ¢íK±|$Ã9¶71·DWŒ™Ë¤Oç•Ý_ÝŒ@DßMÕi¨”…¯Ýr\]m“‡©G8‰ òìò8rb–†8F*´òc™žR>ÑfSš£FÚ÷h|;l˜¦ŒKáÍ›.BÛ"ÏŸ'Åæ¾ÏL¥.`\3$£ú?#–”C endstream endobj 9836 0 obj << /Length1 752 /Length2 723 /Length3 0 /Length 1255 /Filter /FlateDecode >> stream xÚSU ÖuLÉOJuËÏ+Ñ5Ô3°R(I®()Q0Ö3àRUu.JM,ÉÌÏsI,IµR04Ò74Ñ7200PH,ò¬€Œ_ ²0ßÒâÄt ##cC#c.#…”Ìä…¤ÔôÌ<.}ùžyiù †fñ”Ò˜\YjQ1Ð  ¥š @+Sòór*RRÓ€úJsrüsS4ÀîÂNÌÍ̩ģ <53=£DAÃ75%³4]Ö³$1'3Ù1/='UÁ"”Yì–Y‘šY’œ¡PRTš ÍKI-ÊÉÌK È/Ή‚®¡š\HFfrv^jq±‚)TÊ/¿$3è¶0¨>ÔQpðAwHj.0ì`æ%'§æ•(XÀø)©#¨@j^ z0Cú‘N>¾þ^ÚH˹æ%ç§dæ¥+™š)$%Vr(y¦ Õ† ™@·W(¤V=«¯——_Ô¢PPZR«–_ÄŠ#cKýÂÒü’ÔâLp0%¹P-HÌÌ+ ©,€!È5`¾!„\R”Ÿž™R’¬Ä7±¤(³"Ú@ÏÀÀ(„0V,¦ïœœò+ªuM-€Ána + 3`ø˜×¢(L.-*†8yÃÆOË:;5µ"5™ëæµüdë–¬M-{~lp”.×}z–íþÃ}"v˜–¨]_PáÃ>ËýR¡SBÊZ‰ÓÓn¬l»x­FZëÝs1ç4Þ›æ1¿„Áõèc§º Oþü|0=U.%_*ý¼ùôÎÇ‚ï'Êò'D³D«O¿ö§ÕüñóuÏ–üÝWü<ÊòµB®Â²oŠÓ¤Kzçí{ÍÔ©¨ò°äTdŒ@ŸPQôŒÒÏÐó™ZÌ•ÿzмšr>¦ÍÌêŒUãü²mÊ\ÝmI—ß–Üçè{^³øë³ù5gxu¾z¥®ªNš~©.í­;sAæÊ’~·8Âçv®ïÚZSùîø…Ì-íBE9oöÍà=rî\á9™«=ÿÏŸ¢ÇºáçÙz¡ë§y. ›ÑØÏÚS4Ža{äêÒ‡o®=‘±°Z9èÖ±$æÆäŒËØ8|™ÎË?õ42_³\úÉãÕ›>+˜ž›Qaec°¿úêëe7 ß)ú¾®fÐ Y[X‘é3_õ¾÷ä›J¶ß|–ÐN´uXº?®ìê…›'ø¼&Om)jýÞ^¬ï­üxWé=÷v¦3”<¦6Ë*ëŠ9b¶»ÝµÜþó£+ÌÇïGÖÊVOLˆ6dcñ ²?pNù.G‹&ë-þ_ëWöœùG³¥¨RwHÝùÎP‡W9Çó~É|Íœm]÷pëíCŒ¢;V_Òôe½§¹iæúeÉæ8e‡>GŸŠμºR\ý#î`!_‚¤ÜËã·ªüäxßÖ{¼£{âo­­Ü(†I“çÞvý|c‰¦Åì¶ÿÍ\·âO7§|ã Wµž­Ío“u4æŒ(Ï÷k©NYê_ì×{³°'øôq?Çgzª;ÿº·³MÝÊìVÏÖ§~Z3‰šü&¹Kèá_¶¨ði®÷El³lŽºéJÁëÕfm¦Ììôšä·›YFlˆì{“ÕæTŸ®¸^q$1Åk}Så¼µO?ñ¬³zÍ!»Ò¶íí§‘¹ÎÕ“ÜnÙÆÍŸ¡t'Ó€:PW endstream endobj 9838 0 obj << /Length 690 /Filter /FlateDecode >> stream xÚmTMkã0¼ûWh…öF’Ç.! ùrض4eÙkb+]CbÛí¿_Í{NK—bÆã÷1oò¤›Ï»™©Úƒ›…÷R¼¸¡½ô¥›¥?÷]ps“µååìšñѹÊUׯÃxîÛrçFq›n³mSw>xÛ”§Kå®QßY÷V7Ÿ!è#n_ÝïÙXþÇÙáRŸÆº™IľÖãÉÇ|÷YxN|á¥ürýP·ÍƒP÷RJOäM•¶gÌ0óI‡˜_•ë¦ê'1âiÒ¢ªËqz£gyöf y÷>Œî¼mŽm°^‹ù‹ÿ8Œý;)¼ æO}åúºy·_”ù/»K×Tl6¢rG_ÐÏþ¸?;1ÿnÀ×÷Î MïŠU•må†n_º~ß¼¹`-åF¬‹b¸¦úï[‡㪖>TEþ¡¥ 7Á:Dn˜ø‡”ëxáq¼¤ ÂhÍŠ"<ö¢a"ñ„E a‘b‘n9ÅcO ÅrŠ¥”DÎDJʯ—««æòϾŸ¦“2Ba©8c ]R§05×Y ¼`e1ð’ù 8bl€Wœ»Ž™§x6ÂÀ†yÈ•–ûRLʼÎØIÔTšqŒšZ%ЬưNc½Ðp^³NY4{¥¡G£¯ÖŠpÊ<æÒì–F}]P¯rCÄèUmaƹèæÌCÿ‚xEõ—+Æðm™³6\0†¶ˆø(Â\1m‹ÖøcÊ%æA¯˜g”ÈÍç\±ý\›˜faböÍ oœ3†Î„=4ÈMÜ ÿ]Bû˜+̘ðöøŸL³ fÂzBÔL,ñ 3&Óìð-¡^˼ao ¼5ì­AŒê ¾µì'|°ì9Åg´K2ƒŸãb5m1m-N"n3^^úÞºZèXã@×û¸}º¶CýèÚº^’x{*‚ž©t[ endstream endobj 9839 0 obj << /Length 708 /Filter /FlateDecode >> stream xÚmTMo£0½ó+¼‡Jí!m0U ó!å°mÕT«½¦àt‘Húï×o†4ÛU ÇøÍÌ󳙫ÛYZw/nÞJñä†îÔWn–ý܃««¼«N׎÷ÎÕ®>¯wâ±ïª­Åu¶É7m3Þxò¦­ÞNµ;³¾'Y÷Ú´ úˆëg÷{6jö>úÙ;A òs3¾yÒ·ëÂÅ×  ¤_®š®½êVJéE[gÝÛ‚ù$EÌÏâöM[÷“ñuÒ¢nªqú¢wuð~ yû1Œî°i÷]°Z‰ù“_Æþƒ4Þó‡¾v}Ó¾Šë¯ÒüÒöt<¾9È2X¯Eíö¾¢ßÿýîàÄüÛ=~rž?ŽNhúV¬«êj7w•ëwí« VR®Åª,×këÿÖbÎxÙOÔÔ0ñ/)=Vfá±Yú—–T{œ¦ÄðØ ­â@á r 0,jؘû@†@ÁŒtD˳¢êÏ®Ÿ´K¡µT—M¤Î"`ê¥ó xÁB ð’ã9pÄ8Ž976'>ï;-SŽ'À–û'ã¸ÎÉ…šJ3† ½Ê('ŒúZ%ЯÆðD³N½h¶FCf=tÂu4ôh­ˆ“1ûÕì¢&NI¨‚£C ýaιè‡æ%ö¥ã.sƨ¿,X§.‡GÿœEDœ(B˜üW14yñÓ¨‹ÏF_ÎÂðÝHqÅ('bï ÃÄ„ùî¾vÐmØ; &½xgìå&ò…ý5|6)ö` Æð"ásJ‘›,¸4%¬!Ź&¤AQ߄¶„üR¤3əߪ¿$S>›gcYˆšvú§ Ç²~ ï¬å³!ÌçG¹9ÝW™Ã»’qO ýø—1y>ÇDuê{?Ah<Ñ`ÀHhZ÷9ÁŽÝYôÐè;ÏZ|=”Á_4« endstream endobj 9788 0 obj << /Type /ObjStm /N 100 /First 1039 /Length 3967 /Filter /FlateDecode >> stream xÚí\msÛ6þ®_×é˜x_3ÎÄNœ\.mÓÄMÓz27ŠÍ$ºÊ’+ɽô~ýí‚ Š”,Ųlß}è$Œ–¸ûì+™ %R€$´uH% Z؉0Â[š¬0D8RžìE2y2­|¦‚Ð:¦RYKcÈÜù€TTBûDÌ¢:âñŠè‰]tH%ä•F©|RÆ—h…±!%a¼V(#ÚümÒ ¤ðФIF²Â*Gœ­Õ´AöÖjMëœ'*ë$RQØ 3¿$lta€XB*'œ¦o£ÒHæ¨@¸l°ˆpõ™ŠH‘¥¢JÂA" ¹DF‹(ÜÛÌYùàÊÐNøóÈWõÙBœzm*ƒR0Ûª„!ëMª :ÆšX¡#qÞ#ñÍ7B¾òéôd*äcñ·ËáǺÒÉ}%¾ýv€÷GaTCÛ@¬tÎd[ÌJb…Ù¿Å=`ðPLš@…ß=,ç*;vð®Â\ÚŒ!Ýk*Jƒ3æÖÃÚÁ(´}ÇVU^o±ƒ½ 3kv‹AÇÊ{ÿ vÐ Ðöq‰AAõ0žpÉV.:ÌD,Zec`%ªâ¶Ä4p— b¬0-©¶W¸6b¡÷X&¨&Cƒ(`*Z·µ"4¸J…T)\—pa­‚ …"„ŠZ!ŒK]Mr!†š6Û@˜»tˆ­6’ÑaP5JU¢þÉaP„ÃÐEÀ2…Íd‰‰h*lÌnŒá±8ÅþÔ#çWB¾ýåW\‰iÙ­¨Ó™\ÇïÊÄãéd‘9S+B½U¾ä;•Ü5g6ŠÜKñwдS|¦›î‹Î©|9›ž½®Q!_>>ò¤þ¼ïúÆy‰òeדŜ:½Ì›l0Ÿ^ÍÎêyÓÜæ±ïêóÑðpúYd³v‚MD¼ÎðjŒl0óÄlò9 Îí:áÉÝ:‰‰¤ ¡ Q&§2¹áØ´éL@!B!b!˜3uèD¼»›@0k‘¦v*`+C‹¥¯‚§ž 3â…£Á†ÉR×—|E»(ì+ìå±ÇCpö¡A`~Zl6`þÁ-4¶¦u…½ï6w¸zSÇ„%A`]ÑVÖÜœáæ J.> pXq_è¢AS46@TØm§³'X_yÚ\NÕöz}§(l…[$Ü7á'íù=örèë*µ½`߇)´®ÀÂÒ×vó`¦Àʱ†â¾¸¢Í§AÐÆ°»Òa«-ÜÝÛÂG¬“fi ŸpaÕáPhK îØk”Ú}WtßÁì-<”-0(5Vmܽ£G¨pªJðwü¢)œ^ÛÜÓqáô7ƒÆÞµ4±tÿ/-Í)н<è"ù\#2\±éœVn{lëè¦Wž‹ãù:ž×^×Ðï§è³æ_ñ×±÷ñ—%wµÆ)Å-ts>ä‘JXÇLi¿ËñŒ1LãåÈñè–S3Ÿ>KÜä(|ˆG9hœn§RŽäƒs®œ—üËøœëå[wnù̲ò6«9ÏóhÇè°tsŸôŠtw©{ÁH2ÊgW·Ü©ãQÆ_ÛÓ/ßKíu/}º|‹.ý¯ÿ£¸'w¼óºÖù£ªðù³¹lý§)•ï%H7<ýì@L­Ç%ó´Ä@‰¯rä)$ÚáæôK mŠªøÅ%É·MÑ‚x”ƒ '£—ËY'íJª•¥ðoSéœ*%%9}»©»ÌâxÆÍz9úq¤èÞIÍòÙµx‹épÞc×&ÝTFž”¢¬SœM {ॳð<2  Ìûþ¥ñºX¡_D÷,¨Ä£=¨ ZÕZûÚ† `Öž–Ö tÞit²·:|²"]¦]wù¨û/ÎîâÏîx{ Ó‘iß ®ší¼ëÝÕ:ž¯úÒÑš-ºö€ü›­o5ÛÚ÷­¬/7èû²yKò¬yÆÀV(ÉÑý´¼†ÑÑÕ5[-¦åÚÉGv­Ç½È)ØÐŽR ÓѦSpËÈåT5ÝrB\¢kÇþ²òµVn¯Ëx»öQX÷—»,Ú½<®çg³Ñåb:kv3ß/ð›·/ÞüøËá×'õÛ§Îêgõl:?8œŽÏqÎxøq.\3ù0ß*=ðV‹›ȦߢµÉ¿'ÌÏè–i0a †—ÏêÑÇO|J2黣Ó@þ}1ÎM>Žk¡pÏ·¨/ÞЯØù–/òtrôi8£Ñßä#y(äcùD˧yøùB~'¿—?È—òGùJ¾–'ò'ùFþ,ßÊ_ä¯r(ßË3y6½¸ÊsYËÌV~ðïÿþQËcùaz5“å'ùéÏËOõDŽä¿äor,/äDNF“ZNåÿ½”—t7x\X4Ô,s»¬g£é¹¼_Íåïò÷«é¢n¾˜É¹œ× Ãùè³\ÈŧY]ËÅ¿§òJ^MpC;?›Îjù‡ü·ü,ÿ”ÿ‘ÿAsÕøx„FIQçýa‹¼Ùy?ýøæðéOëÎk ½Á…®¸Ð©ìBÛu¡ï»Ðosá6K'ÚN|…N©Ñ¸Ù¢éæd”¾âFí¢øÉ“Ço^¬Dí«úãÕx8Û µI¨A~ìÂ[Ôº¹«ÉZg¼K­é´£uܸ©«²qý¸=˜mbõ%Gé›}ÍnŽ~vtxTô=©gõÖ4€>¦.Ñ6O»t´…h»ÚæÓ¥¶ÊmJS›–ê:Ðû¤)%éûÙðì·z‘s‹é&‰({ÇÓÉNÙ{mîrjž¿g!åäÎRÕ¸]<øúÉó¯xð ! ²Ù‰ù ´N­íl'\Õ&ï)ÓñžÿB‘}~ƒ2;œSÕ›ÿ&‡‹mÞ|…Ö_:uµ0×çÃù'öpvñª—?ΆÔÕb®‘ª‡(s½jëù|éþÉÕÅ{tßèãd·*^Ï#D¸%fÖ*ýŨÑjHó1©s»p‚]ÂéåëÃãŸW ¶²ï°ö˜ òceAuJ¤^I ÓNIð«eß—°Š®UÖ\UË2xBq³È+4…À†¼¾ÆÏ%¿[‡6¾û½ñà m¾bîÚç¿}ôõB~¿X\o`dx@ƒi¯©¥5õEõÍë»æÕ6älϸIßE_Ô«©Ù꥔n¬¡Ù·-‘v§Eý×~|òêy“=Ú+æG±+7C€ž‰iÑÞÕİ·‰‡˜óáä|µ:g¹*Öm}ä2òÅEp­^þ~5ËúóÙxx±âÖÇ}jâ}”=»SôóÛ—Çß?mBäàõx8Yü3{÷ƒå Ý Z†Ý¢FNéçÔt“Á›üZ\k®;íÔmürøâ»ž½8ÛœJ‘Ì“ÐÂr¥Âí{‹`7š%Î|DóW´¹f±{29›žã\”8úð¡FÑ;§¶¬ÉÂî!p§\–“1µÂúN+ lê.ß×ú¢ÍÙþMæq*•mKsŠáœDçMÄçÌ~ÏÙó¢IØœs%]JâPF 0mʶ‰†Õâ6ÝX§Œà®¤WIDòÐ)ôBµ‰Òõât’mÚ¾»‘£,›5ì2€{¿wë1Ûù¹—1d‡ó:ÿºí~D/Ú›÷òZÇ£Ù|AA'è–Ë!Ÿhƒ ÉÏ£óŧyóšAž\À7/ä¡“éOôÌy-ôõ9¶ ï·à«¨^Eí ‹šº«%j¸ÔÛ÷Ïkí*dðÈ:ˆÜ—7ï€×ðúU¼6†¿À_Øð­a»`v÷ƒyû®b òNù§îòjg¾ Ò®§[ÜR¥;@´ÒÆ®ZK&k{€zù¯ïÐÆ¦i ÚZÞЭ°4ݵU¼h+}Ê µ¤ »P- :Yâ «xðúø?ÈÛÔË[Û-ŽÚ®%6×ÀNë°éáæ9=Ý|Eìò9åè8±þ1:ÇEØéæœ^,3L@KD&Bb¢yÊøÝíD™&:éŵÀD³RÁŒ-#/o+ʱ†¼r¦¨Gµ78°—(~˜Ë~(ÛYÅ:X]ˆ¢½x{Q¶@·PósäÎiþʆãì>¾rÅ\.°(Ǩ;¯ Á§9ï`'Qº'ÊëàCádz;0üX– ®[Š¢·6E™ x$X6`pìÆ°cXôEÑ;½™MyZÐñ-|$,ˤ}b/Q±D`,vKšGR±[*yö•";$ñ; ^±½bõ<½ÐÙco'Ê«Pó;^sýðÚÂ3 vÓÊôDÅü '7MD#ÊW‘G¬ÚG”åœñ–ÌÛÀ2m1©S<dz‡(Ç5³“up±ŤÞðˆoœvKQ¾ *d™®JX/4|ÜCöp¹õƒÝËZ.ž“𖢸ឺ¡åYfFQrÏ'µ[¹µ=Q‰Ÿ<[)(ŽRP:Ü^:&0®» øE#ÐlIжM‚ÝR”æµ4¿÷ôxCpX€)¢ŒßÀ`¸0áÐ˽Ø¢°åjâ¢ldœbÏ8ËÂg™ŽË¸äöå5+ãyÉïY_.‹%ÀŽÕÂõDWmÎeÎeªŤaÇ¿/*p_ åÝ@àͦ\!î諾¨X¢!qÓ©Ä[òl·Äþ Jï¡UPÎ3ö}Ðü*^ЦŒpI:ìá« ¹{ † S0ž%˜¢L ÿÀMã-EÙÀü0”Î08Nêà9>‚·»-"¾'Šþ_ŠÌ¸¥ÀMK(1‰-Ãóª/*hfx»·Ö! ënà༥(n¬‘M(÷ì!»¥âÆä–añ_­#±” endstream endobj 9846 0 obj << /Type /ObjStm /N 100 /First 988 /Length 1959 /Filter /FlateDecode >> stream xÚ¥˜_‹d·ÅßûSè „•ªT‹!òbc‡·C†0`œ°;6ö·÷QKš–f5£ìôËrº§uJU?Ý{î]+’C £‡ B-PÊÁ•À” ÜB&NÙƒ°çƒf‚P–KðLX! á1å‹ k5„µ”R2x«¤Ès(I8$. ¿­ÍÅCñC»*üN]«¢ ?Š©ª(¦xì5]W`×D׈ùº¢ʹ®HP*RâªÊJȉ±ÖØ«â@ Í“k¹@¡FA×P)p„_F73¨+Cyu‰u\èJ3 AaEf¬ˆ+?†ÂŠ:’±ŒÕä…†ñAa…cC9b`W…¥ FÔú& U7¤©*üCuWQ°Œ©ÖÀts޵f³×˜U­50ݬ¹Ö¨…Œj ttÕg/µ:ÏÅj ŠA¢ÔIƒÔ1AQzPr=:B¥Ö@Ia«5"Vd©-¬L +4¡éâXaø VXmº -q%(`@µi£ G‹ šb°¨ …³…S„Pr®5°IœÌZqÞj œ•Rkà„©Z­Ó‰Ñ×À£Îµ¡8™¨’Z7ƒu,I­Î¸Ö@çÆTk sËwA[–5€ÊUa…bìèÜŒPÃѹáj«ßa…ã"cGçV[…ÂÕUá±ã£'ŽUáÃq¯ —•Z£^s\H=ϸj tŽËO.?^>üã÷ÿ=„ûñ?Ÿ/þòß_~~ zÁçOP× (†¿_>|ûøïÏáŸVpjñ›º&t|ƒ³×„ áWñ¯Ë7ß¼§Ti6Ž+¹ ‚ŸÅø Zzw)âÝF‡Ÿ Qz©‡hÛù¿KÙR*§.ò2þ¤ã»«Ôè!ù¥÷Iqˆ4•;JÑà@£Ò!l¢ÜÓÇ>ÆUÖoÆHyŒ”Ûq}o©ÑÛð=ð)‘â.|G)ܪ» ÁC´ÃÚ®Ý&pËøšR¾–²>·zj¢ôödœq³Jw”êSª·÷&rïJ¤w%Ú»Ë÷”òáWzCŒÙ꘭¶Ù¾³”6või…›Àýº  ·?•Øè½¯T·„BÔj"Œ™’S›îÈ]èùò르‚b}’È[:ú-{/³a{Ï”¤‹ÏŠí8d<ç4‘Åï©%ÚK ²›0ïµ|ÔªOUHt¹£–P3žc¸æ6J<ÅX£.êm˜‚´¸§Vé%4ææ¬ÉZ-%oÛPî ¥B÷ô¥Ú>ã©§w¡%6a±£´Ô3ÙúðµL¬ÑÁ“Nz¨O'ýÁ¢ßb|eûªZm³Sâ>Ç`¿n©óº¾¦4¡ã.NÇ›óëµòÈwïú ßoýúJý®q}±9Ô¢´4––+¶¾µ µÇÝõe¨ "q¾•·jÙð9^¨„·‰ÛºÒ×ÉîÀüðËÓO?×¥}üôù)ôDzï~„¾¾v]?6[{^úøôÓCýs¿ý¹ê¾ò¶ê_|zø5ÔW¯úé¥Až Òbp}«»ä~ˆ¾pˆ7²W¾øí©½:nZ`t^H̦=xßc›ÕóžžÇÅó¸þD_”¢[©T^”Þ½Ýd»Í¦iâI¼tß®ó/ ')½mØÃWv8‰v0\ù¤-Ÿ8ñ‰|0L‹áþÐÅ…XÞ¦PÿO`1”a,>ÊÁp…ÓÖ0O†oC‰¾@~ixƒÝ†²î D×Ɇ ”±á—†;@1[ ·Pl‚b(Æ«áŠMPìEW(¶…b=@ÑŠm¡èEPt…¢[(:A‘Y¡èŠLPäEV(º…"9@É+ÙB‘ J>@É+ÙBÉ”|€’W(y %OPø…W(y eJñÈ(¼BÉ[(SªG>@¡ o¡L!éeÍü¸Íü8e~¡üªa\ ·!±‡ëÕpdôk†IWÃ-”®Í0 i5Œ[Cž ãÛ†Ñþá†ãi ŽŒ~Õ0¯†´5”Éð%®Pú†_>CáRÞ„rý/ðÅ0iˆÙd˜†+”·†<Æ· }†ò¼á†^n†®üÒÖP&C:ÆÅÐ}k8A±ÓÕp Å&(v€b´n¡ØÅPt…b[(:AÑ]¡ØŠNPôEW(º…¢9@‘Šn¡ÈEPd…¢[(2A‘”¼B‘-”½‚Þ× ÷mÐûô~z_ƒÞ·AïSÐû!è} zß½OA÷5è}ô>½‚Þ× ÷mÐûô~z_ƒÞ·AïSÐû!è} zß½OA÷5è}ô>½‚Þ× ÷mÐûô~z_ƒÞ·AïSÐû!è} z¿ýj]~“ endstream endobj 9853 0 obj << /Type /ObjStm /N 100 /First 984 /Length 1616 /Filter /FlateDecode >> stream xÚ…˜AªG Eç^EïÀ]UWWU` Ù@!ÈÀƒ@ÈÀ˜åG²ýxÒC|úôáã}ûû‹¿Úboøï>þâõüQÿöç×/ÿ|³›l/ýøúåßÿ |üõËßüqüü9ŽgàÚïíæ¤@Tãˆ&pæÀ» \!ð~8w ü¹á—Àyž“M rà,”9ÞŽ“g eÞÏÀ¡M äÀÊ`\MàH?7ü8Ÿ÷yxk”*ðÞ!PšÀ•GˆøŠ{-þÜðkàŠm3”ŸÎzW˜ <6üø„¢û=×u ¬ èÞ!PšÀ•GˆØ@Ñå±á×ÀE(*9°„¢Š6P4CÑŠ(l 0CÑ 6P˜¡h … (’¡°„ÂE(’¡°„"Š4P$C‘Š(h  C‘ 4P¡H  (+CA Êj ¬ %” ¬ÊÊPV e(³23”UB™Êl Ì e•Pf€Òˆ^³è~ PÑkýcÃ/AôÚˆ^³èµ½Ñk#zÍ¢×RôD¯è5‹^KÑk½6¢g½–¢× z6¢g½–¢g=Ñ3‹ž¥èDÏFôÌ¢g)zѳ=³èYŠžAôlDÏ,z–¢g=Ñ3‹ž¥èDÏFôÌ¢g)zѳ=³èYŠžAôlDÏ,z–¢g=Ñ3‹ž¥èDÏFôÌ¢g)zѳ=³èYŠžAôlDÏ,z–¢g=Ñ3‹ž¥èDÏFôÌ¢g)zѳ=³èYŠžAôlDÏ,z–¢g=Ñ3‹ž¥èDÏFôÌ¢g)zÑs¾ÿæàÕb`)zŽç76È%”!!p6éCÐcïÏA¼ßò/…)°úæÀ[C šÀ™ï2p…À÷Pü»e ¼«AržPä° ÌPîYJœM`‚òØðkàŠì÷Pücl ¬ ÈÖˆ&pæÀ» \!°¢ ÊcÃ/ hE‘K( hE3-¡h€Â 3-¡0@a…Š–P °" K( HE2–P$@‘Šd(RB‘ d(RBA€‚ 2)¡ @Aee((¡¬e5PV†‚Ê PVee(«„²”Ù@™Ê*¡Ìe6Pf†²J(3@iD/Yô ¿ÑK#zÉ¢lø50@iD/YôRŠ^‚襽dÑK)z ¢—Fô’E/¥è%ˆ^Ñ#‹^JÑ#ˆè‘E/¥èDFôÈ¢G)zÑ£=²èQŠAôhD,z”¢G=Ñ#‹¥èDFôÈ¢G)zÑ£=²èQŠAôhD,z”¢G=Ñ#‹¥èDFôÈ¢G)zÑ£=²èQŠAôhD,z”¢G=Ñ#‹¥èDFôÈ¢ÇSôÿuMù€ endstream endobj 9854 0 obj << /Type /ObjStm /N 100 /First 984 /Length 1616 /Filter /FlateDecode >> stream xÚ…˜AŠ$G E÷sм¥/…"ŒÁ0Æø^ÌÂ`¼ãã[ê™rI…(mfTMåÿ¡|Ùý E]¢r®Ãñ¿^lˆ.¨ø».¥åïKŠײíÝ—é‰a]÷'ØóèÀ}þx€w€ãD‡¯ŒÅÑá;cÝÑáKÃvtøÖØ+:ü8âð½qsÜ;_·øæBûÄä_á刻õ|¬Šø¡JÞß\ôHL~Å2É¿b¾¹ì>q;E‡o.çDG|å¶èðÍLtøæN-:|sG‡o®qHŸÖ¥²£Ã¡º¢ÃWÐ%Ñá_Vãè ãÓ¤—îDñPx;<½½Ò'\‹ü±ö-&‰I}ò|¢k}¬ÅÛ®%j1ù ï`G±–ùäW¬ãìñþ¼EÇò+öŠŽåW‰×ÍÑá¸×}G‡ßX£¾‚Åe>ᲸÂ8—ù9bRŸîèðGÊåèðÍmÅÍfßÜL£ÃdÑá›Û¡èðÍíPòÍí6‹ ×&õòÍwù¤þ»AÞAï¿%ƒ][6ÇäW¨/#ä›ïåx|ò+Œ5&¿ÂîèðöÞÑá_Þ'òÍ÷-Ñá›âûÓ?~úá÷?¿þõÙÿ-¦ë·O?ü3}›ýãËç¿¿ú“ìß·|ùüÏ·?ùüï×øº}|üé§(÷3PlÔˆ6p¥@ T¿ø5Ÿ8ïa5P»@$Ÿ:¢R˜ ðý>w D …O \C ÔÀ k ä÷t—Àï~ ¤g í!pÕ@éÉR  \¿ø5ÿúƒ·áµ¸š@¹O \C`…òýÀ¯šßC ϦÀÇ_ŸPäì!pÕÀŠK2(¿&({€²w l¡ìeP¶ÔÀÊNPöÅ*”ÝBÙ Š P¬BÙ-KPl€bеP,AY”U¡X e%(k€²*k¡¬e P´BY-”• èE+”ÕBÑE(Z¡h E H…¢-IPd€"жP$A‘ *i¡H‚‚ *i¡ AÁ Z(HPÑKýãÀ/Iô2ˆ^ªè~ LPÑK½´¢—$zD/UôÒŠ^’èe½TÑK+zI¢Ç zTÑK+z$Ñc=ªè¥=’è1ˆUôhE$z ¢G=ZÑ#‰ƒèQEVôH¢Ç zTÑ£=’è1ˆUôhE$z ¢G=ZÑ#‰ƒèQEVôH¢Ç zTÑ£=’è1ˆUôhE$z ¢G=ZÑ#‰ƒèQEVôH¢Ç zTÑ£=’è1ˆUôhE$z ¢G=ZÑ#‰ƒèQEVôH¢Ç zTÑ£=’è1ˆUôhE$z ¢G=ZÑ#‰üþC¼T+-Þ)P‡@ÔÀ K |ÿ"(^ñå@îÞ9€ž/‚@6j D¸R †Àò"èqà×Àç‹ ¾ßC‰÷–%°{Ä÷N:V(Dm ¤À÷Pâ-j |ø%ð<¡ð±!Pk ÚÀ•1(¿&({€²­¶Pv‚²(5°…²”=@± e·P,A±ŠU(»…b Š P¬B±Š%(k€²*k¡¬e PV…b-”• ¬ŠV(«…¢ ŠP´BY-MPt€¢жP4A‘ŠT(ÚB‘E(R¡h E  B‘  PP¡H  (¨PÐBA‚2ˆž«è~ L¢çAô\Eÿ8ðk`‚2ˆž«è¹='Ñó z®¢çVôœDσ蹊ž[Ñs= ¢§*znEOIô4ˆžªè¹=%ÑÓ zª¢§Vô”DOƒè©ŠžZÑS= ¢§*zjEOIô4ˆžªè©=%ÑÓ zª¢§Vô”DOƒè©ŠžZÑS= ¢§*zjEOIô4ˆžªè©=%ÑÓ zª¢§Vô”DOƒè©ŠžZÑS= ¢§*zjEOIô4ˆžªè©=%ÑÓ zª¢§§èÿzäñ‚ endstream endobj 9855 0 obj << /Type /ObjStm /N 100 /First 984 /Length 1609 /Filter /FlateDecode >> stream xÚ…˜KŠWEçZEî@ï½øÝaðŒ0Þ€ŒB/ßýQGAÅ@¥(ºòÞy²û@Ñâu­‹é…ÿŸkëñáà:L1ðEñouñ¶\ a_¢æÃ²K1Ðeçþtîûö¼uù îþn;>À®½„b¢kobŸì¾öñ\ŸÄ§[cÚ×&3Ÿ¼c³ &¿B( 䎃Fƒø¶¢Bü Ct°_ßaßt_gè Ù+:È/ÛˆŽã/G£ãøeÄѱï¸ÑG“ñ"wtøÒG-:|ëcâðµ"wmée{ÿ0÷Ê“ßÙ-ÞßÜo¯wÀ7':;&'ÁË;w—ýÃ'–!ÑèðÍI9:|s²¾9!ßœ€èz·F‡oîäÖëÑxÇÒð>;:|sö;]L¾9³DÇæ‹…¢Ãq²îèð[ÇzG‡’ͼÃü­?Þa·_qóŽi]²Žw˜?.²_n“ã‘ ï0¿rTbâKˆ5&¿‚…©_! 1ù‚èðGÀŸ·õz³Å$:|-E‡Ƚ£ƒýŠûŽ¥ˢÃ3ÝTE‡ß:¥~H¥;:ü­?ÊÑ᛫htøæª¾¹Z< æ›+–wÄP@bò+n?¸Oë²Åñ€øæ¶ã—I}s;Ë;Ô7÷ß’_FŽûÄZÆâê&D1ùº£Ã77GJ}s3‹ßÜ Ñá›ÛMÑá‡ÄÚ÷§/_>}þã¯óÎQ¬ë÷OŸ_o¼Î_ÿüþíŸþ$ãí‡_¿û÷õÏÀËÛß¾ý÷#.å—·¿üRýÞ}òxjàj)®ç%ðíÀçþ<:r > stream xÚ…YÍÊäF¼O¡0®Ê¿*1,†=-Æ,û>ÌÁ`lÏ.ûøÎÔ§Rgf—T—™Ò׭ȈŒJU Á¾• iëÕþ/[ÐÈ„¶€ tQûF…muýXʾ±4[ð&ÔmQ·ûðÞOyÇ­ïŠÌ}ßö¶à­F[խֺ몵­t[áVQÙË®+ý²®ôÚí^Ñ;˜P °Þ!bŸ*TmUù0é …ôŽÞ ™´v©F•i1mŒZ¼v«ú@CýTWúe*]kT»DSQOºÀªZ±KëEcCQÕЛ5LeÃÍV¸aQB@Jk)¶bm¥öSWUWMu*Gìö©*GêÊžT9²!“ DûT•c;•$6…וÞÑÙjh!Ü©r*h5T9i³´†*'0º¤Ê UNx ¨r½ËPT9*I•“}¯ÂFÍäkKÔvëÚh/G›Š®¤}î²q±Ž£Å•”3ªë8j³Í_“ʸ«6Ô†1›oªKW¶‘Pô9PDïhl¦ˆÞÑ¡j Ö;v۔ȰI1+´cºjö=¢Mª€Z\÷¯}e4“Q["ÄÊÙhÈa­mkánßÓK+¬5”´fßSåÒmÓ *—Ý:¤Žn­[E•·bTyë:¯«f[J•7T+t¥wiUÞtë}¨òÆ»}O•·fTyk6 Ê[·é8mm?PTy/Š*ïÕ6°n"](ª¼ã¢Ê•2|üðÃÇ÷ÿùíÛï_l¤wð|ÿ[Ëçú—_¿~ùãÛçžþüÃ×/ÿû| —?ù¿~*Çå?F@v€°,ðxÚ¼Ö ôg@H3@Ýá/@ZB,S@t€å°öxN€Õ™RyˆpjJ%XŸËëÔ”Z^€¥-9â °ˆÄ` €'á  MÓ G'€¼wÈ ÀhÊI8’|6ÅÎG8gÀ—)ÜÛ#àÌîâïL9ú>Ep.´ìBóm׳ä¤ôÏß¾þõÍQüׯŸõ~úó¿z÷wØ1kΡªcWò«PMµj¬Å¡¼UrÖµlL;Ñœ9’̡щÓIì:v¯Ë“]Í¥ÄÙ&Ù6™îEq>ñþÌŽÃær/²Â¬ð3Yv¦q+žnKvÝçúL–â>ÏåÈŽË[²ÎDÊFÓÇ93ŸÉbx]didÇåYržbž=œ>AЙüLâ#‰ÒôRdë3Ytžbž(˜N:3`1QV£Ñƒ,ÆÃÅ€óò€ÁtÀÀ™Qô«Ñƒ,ăŀUçé[˜˜Æìâ×Å€ÅÓýjô [ã€ÕÅ€¹\Áo¹b~.»äÀåyÀ(ôW£Ù¬,ÌE ʃ¦G4¹Aûó€Q:óK°¬<¹´A9mÐôð&—'¨·Ù0`W£O²´‡».ïȺàA9xŒRùgF»°“]E!i¼.ïØ¹œA9g\Éb N¥¢k’¶¼Õr¶å¤Aãl==˜rÁƒÞ‚‡„é¥6{Ë”òÄKàÉ!YƒÓhmŠ.or]¡·2°G©é„¹f ‚ÅT•×Û*é×UjTž½1¢ÂnN²¥O^/±pïêí©ÝêOŠCýYïN=îÍUNÎRùt·<[eolƒúÈÚ‹_Göº¼Sì/«°'«®R£òÌ*ììàᓬ½ž!8«Úª¬ºœê{°jÔ»µª9«Z¶ªM­jΪ¶°J’údU‹Vµ…U⬒l•D«dj•8«nN²2µJœU¼°ŠÂ‹×˹¡^¢U²°ŠUœ­¥ÎÊ> stream xÚ…YÑŠ.5 ¾ß§˜“&mS"x%"â x±‚(âã›v§ó'±3½ÙÓÙÓ$ß—¯é|̦Då€#%JGFý7É•ú‚D­/à ȺÀrpª}·¾ê‘sßtÑplí¨\ßt‘Aê¿Á£‘†£Ô£Ié :AtU›®z¬ùÀ42T<–«ræ¾ÒˆÜ1ôÍXR/5¢t¨¸5¾ga‘…5¢écÂÎ’âãGg }ßàSú¾¤[HzÔœ³Ö@ÝœSß§”SážE9§Ò:*%­•(ë$= (íÔzPÞ¬­%N º¯è Ô±€2'"­Êœ¸ceN<²èÊ#‹2§2²(Aª#‹2§Ñ[Pæ4š J•FwAAòè.(sÆÊZC·pY”9ÓȢ̙Sß§Ì™;#Pæ\#eÎEú>„ƒ+÷} úKíY õP´ÅMެoºb=@zhtºê‚v@9µÚWz¼H³`«ÁšEW‘G}ÌE“b+QG™këû²FH.ZCCî t‡´.r9Ê8ÓQÒÈBrYˆu5°FðÀ’4"÷#Õ’F”‘5¢fÔ¨2²(óÒFe^ÚÀ¢ÿQ!+fQæ;Qæ ™û ŽJ¦‡°èè)Ö•FpëûtsÍ…ßt¥Eze^kîû”yìû”ymܳ(óÚô éŠuœTs]®úàˆ2=¨}•¡>.¢Ì…QÞ¾ùæíë_~ûòû{íªþóÛ×ßö5¬úõóû_>æ¾ÿâÓ'B&\-ùñ‹Ïïÿ|ÜãñÇ÷{B>¿ÿíó_£@ùxþáW÷øÝŸk²¯0VV5®Ê©°³Ô¬Ì+ì)› é&à VÏÿ*¾2 <³‡êží¼ØŸ'û³ÞdŸbe4R!ì³ÔYq…Ó+´› 'X,« &C~dßoy×Πý q²ÇòÌØTFý*5+·%v¸2è­r“á ´È ÷ŽÉ@ÏìÅ·sv÷d?!Nög½;öz½*KPn– !"&d#UmìÕŒ ¬“êz¼S½rLå(UmK°F›Z7`Ñ•ÐY!Vèl5šVŠ`Wc„ÕˆQÚ3ØBìlô[³;ïÀ£iÉlYžÙbÄ(ø 6ûÎÎFO°¥:°óñ¬Ñ4Çy›¥få¼Âž6™n2œ`óò\e#o¤"?S¹É>{©Îz·ËF*ŽRÍRge^*ÇF9Æ› 'X^^l ÍT¥êÛ´g?U\ŸÙ“QŽ¢r©ú¾/‡ŒŒr©Ýd8ÁÒòô$£@Ú\€˜}Â0¦ä/@ÊÏì“Q.Eå0T^žÛd”Ãz“á›–§¸yWùWÿÕÝÉÝ»jÖ»eo\F—1K…c+pc+ ù“á]åmÅõxwI[ÑVÀÒG ñÐꬿ¤¢ ?Uðü®ã? ø«T y‰ò|‚¸wÕÕè,4w^w`ÿ€à?®R1„MÈó» ¼ ¸=ÁŠ{W]·`¦Á¼JÍʫی€è#"Ø¥c+`c+ÀÛŠK¹ÉÞÛŠYïnbÁØ ˆ¶–¶Œ­€­€œ=û •·°±`lD[KÆG@~¾ Ý]Á@vw!ð?°Æ@ðW©bŒðæ.$ßÙœXô`ŸïB0†¢á¸JÍÊË#l P½Ép‚]š0Æh#UòCÀþr'{~~m1 ÇUjV^*g ¤|“á»4=`Œ¤ÍT!ø„Aûä§Šð™½1 ÇUjV^™1€é&à viz_ŸV?­Œo‹6a cŠþÄÍÕTö_Á^¥Nö°ú(@&Üd8ÁÂâÓŠnº>néºl؇vúO+âdŸV4[6•SÄK°ø ‘T’ ØW3>ÀŽoÃ/°¯Çõ%¥Ùª©¥’´+dBàly©æßî†T¥Â¥Th¤ÂTàÙ§ z©p#©¢ÿ¸JÍÊK©ÀHõ?ÀâR*0RÁ³TÒü}…A*ðRá³Tbü‡Dÿq•š•Wʉñ}D+M–^ ÈÆVHõ×?xíÅÛŠYï–½±mÅUꬼtb\†D—ÀЬN· õù]%óí3ÛéoÔ q²—çw•—!Ñe\¥fßa‰Ý(]F»t:bÜ‚D·ÙûWÿÕÝÉ~¾¹Oö•ŸÙ—!ÑeÌR!ÄØ ÙØ aÏ~6c‚õ¶âz¼¹¤ÄØ ‰¶â*5Û´”ʸ ‰.#‚ÍK©Œ[ÞHE^ªàS&ÄÉ>o¤2¦C¢é˜¥Bˆq B©’gÏA*öRñBªÿk?o³ endstream endobj 9858 0 obj << /Type /ObjStm /N 100 /First 985 /Length 1844 /Filter /FlateDecode >> stream xÚ…™ÝŠ$9…ïë)â–¶eýØ04 s5,Ë0/Ð}10ÌBwï2¿RV8Kr(Ò7ÕÎ&|¤ãÏ™G•U{ãµ·r0ë¿ ?Ø ÔEíG{¤âѺ=SÆA¥Û‚{¦ÔƒQŸ‘!‡0¼é¢ôéãèmAG-•mUuÕµˆˆµ¢=&í¨ &ÁC;höë,öëS!ÝABZtk½*8ì‘f+²Îí%êŽAúCšP*­P*úÔaÕ€²jPhb½TÝ0´FÕôPQÏÀÕª©iànÕÔ5Ø<Ú€.ÕVºchÉÊj¼¶¢£U°çÔy«ÃžSç­Õö¦«¦+±çÔyC³Àê¼›Š:o¬*«ó&vȬÎ[/Ú3«óÖl¥;ÆCEcé¶WÛ@(¢5Ô9‚1«slÆ•µ!Ô¥­t3ˆdgÊêÙNƒ•4ÊÃGÁû£ƒR`Pë](JœØ­ÐÔû¡rh+<ÙªÔìr‘è,ŒºõáJ¬;ÈÀ“n#¦b+Ý!Íj(êÕjîèÃjè¥ÑF­âÁ…¬†¶¦}[ ý¡®¬†Þeõl5ô6òãœí"ñãœIï5›h5ûzÖ]kTÝÁÞSçü¸„¤Î¹ÛÝW¯Ûê\Ь®à½ÆºR3¢×ÎVx¨U]•Cš][Ô—‚Mk :ªZÕ¹ØqêJwØÑ•îÐw‘®Ô¹t´ZR†Ý]Tç½Ø­CuÞ‹u…ê¼W»/¨Î;`ûé§·O¿ÿñãϯöÞ&}‹ÿööég[Ãûúß_¾}ýëÇûþý?¾}ýßû瀽üü9*Ô=Ç\á__ÿ¶—”‹ˆSÀ¨`—×÷P1 žùãÛ÷-~úõËwWïÓ?ÿó_û\*7W¹,½ÏR³rÏzWPO…Ê7 g³©‚#Pëk÷¥FAŽîϧû³Þ­ûZ>*YzŸ¥feÊz/ìÚÂÙl©<dŒ—î-.¼à<Ýéþlqº?ëݹ—Ñ]eŠ•Ÿ¥ÎÊ£%½Ë@§PoÞ›µðË>H—×îEâqÖà~¶xºŸõnÝwv•rÏRóÜkÖ{wädÜ(œî{v{D¡×àˆîϧû³Þ­{qäd%ÇKå‘öîȱÜ(œÍJz{ØàöÚ=Å㜧;ÝŸ-N÷g½[÷ìÈÑJŽÒ‹JmPat?ãÙlD5_žÍÖKe‡ŠVTkå9T(7 g³”¢B‡ 7¨ZDE *Œ¨hƒ ª¶¢j)ªæPµ *ˆîqA…nP5‡ª­¨`©œ¢jÈÂÙlKQCT5¢j *ˆ¨Ú8TuEUSTÕ¡ªT%º‡DT°AUªuèx–š•STnxuxX›­)*7Sü¬US»Õ©¸Qˆ@ RKÈÇT¿iÉ¥:­©Ï¸ÅŽâwýφßs6<³] ;pkú?KMr©y÷¸Æý¢€1î){tqkÜ_#ž´Ctqkܯ‚1î1{tqkÜ_1 B*HN6‚áC Ó¸G÷((1î1{tq²ãÓ¸G÷((1î1{tq¼ãÓ¸G÷È(1î1{tq´ãÓ¸G÷H(1î1{tq´ãÓ¸G÷ˆ(1î1{tq¸ãÓ¸G÷Ø6PbÜc÷èâÛJŒ{üˆûÿšt6X endstream endobj 9859 0 obj << /Type /ObjStm /N 100 /First 984 /Length 1629 /Filter /FlateDecode >> stream xÚ…˜ÁŠG E÷þŠþ`éJUÕ ÆY…B~À / !{òùQÕÌóHmYµ²Þ¸uUêÓóÎЬ‚ƒVœÇÉó_=¸ct@Å î‡ÌŸ*ãPjVÐ8ôì³£õq°\×ÑõœE;®7V°åY°œã8íƒr\Ã’e\S“YY‹ÎÊ®ÛG™y¸ú¬Ö%3¾Y‡¶™ßì’&s@ãyÐ9Aí’AsÄ<ï8ç ±Žsˆu\:g Ì˜æ ˆUçœÁ×ô9ÃŽÑ9ƒyÞƒ9ÃVFã9ÃvF»0i}Ȭ¬c4•uœs$,Ô>õYYÇu͵lsK:gÕ›c3`›Ûíµ–uˆ`Þ;¸ÌÇ6éF³Ã6—¶¦ÙæÒçýƒm.CVe'ÏÊ6—óZ•u\Cl†m®ëŽÃ6W^¶¹buØæŠÕa›«¬¶ªêê°ÛdŪŒŸ|V]«ÒCÇœÁÙC1;ì¾zɪp4Z¶t£Õ1ôh¾6gÛ¼¯ÍÉ6ïks²Íû«²Žµ9Ùæ}mN¶ùX›OÜcmN¶ùà9ƒló±6'Û|¬ÍÉ6ks²ÍÇÚœl󱘓m>Öæd›µ9ÙæcmN¶ùX›“m>&ówïÞ¼ýãÓÓŸíÇ.¦ã÷7oœ5=׿}øüñ¯§çGíùŸ?þûü5°>þúñ¿§yy_ß¿¸^Ñ7‘6ˆM …À—ßù5Ï:{ Ô,‡ ÔM b ¥ ]u È):]`ÛJ L¡º@.ç÷¿|9ð=¾Ú÷Ò&°Å@Iåê.P6ì¾â5ð¬¡Ì¯çزÀótm(1Ó@u(#@yøè Œ ”Ñb` e8(ceD(#…2”¾Ò#”‘BéJß@éÊH¡t¥o ´¥§PºƒÒ6PZ„ÒS(ÍAi(-Bi)”æ èŠF(-…¢Šn h„ÒR(ê èŠD(šBQE6P$BÑŠ8(²"ФPÄAÁ "I¡ÀAÁ "I¡ÀAÁ G(H¡ÀAá ŽPBa…7P8Bá ;(ÑKýãÀ·@'zÙˆ^¢è¾:(Ñ#Š^RÑ‹=6¢G½¤¢‡=6¢G=RÑÉÑ#Š©èáDèETôp¢ÇFôˆ¢G*z8Ñc#zDÑ#=œè±=¢è‘ŠNô؈QôHE'z|Wô„”‚3;îfg¢¿þÚã—ôçOŸ¿<¹óþòáËúï—ÜŸþþÇ¢~èôÍ`GëöÀ×Q/·"õ)œñq3þ7N*|8áã&ü{^ôýwÎç|›ï¿É‹¤RÝÃé7Ýßó¢í‘ÚÎö@”=RÙÃÉRóˆ®Gêz8×5¨z¤ª‡S=Póˆ:RÓÙ¨yDÑ#=œèÁ5èy¤ž‡ó<¸æ5Tópšeõ˜—ò áò´ÎCÌKy¸<ªòæÛ=ŸGÙë¾^ßñÕë‡ËÓ:1Ò'çsª}NÑçœúœœÏ©ö9EŸSêsr>§Úç}N©ÏÉùœjŸSô9¥>'çsª}NÑç”úœœÏ©ö9EŸSêsr>§Úç}N©ÏÉùœjŸSô9¥>'çsª}NÑç”úœœÏ©ö9EŸSêsr>§Úç}N©ÏÉùœjŸSô9¥>'çsª}NÑç”úœœÏ©ö9EŸSêsr>§Úç}N©ÏÉùœjŸSô9¥>'çsª}NÑçôêóÿ¿Fã‚ endstream endobj 9860 0 obj << /Type /ObjStm /N 100 /First 892 /Length 1561 /Filter /FlateDecode >> stream xÚ}˜MŠ£GD÷}Šºë72 ŒÁ0Æø^ÌÂ`¼0ƒññêu*›$W*¡T¨âÕ'=ô¾zëmô‰Æ÷ÇÙ‹Á6÷ûb·5ß½íþXôÓöûpíhø^kXÔãj6ÎÛåmvG»<0=j½W»f˜«ÅÒâžvqÛ¦—qÚ˜[³m¬©á£áu5|4¼M±[Ãç<²4Œ©á­aë^6ÓðÒ0’§†ïÒðØ³´-ƒmo&[ºlYÊ–A¶7s-ݵ,]ËàZf®¥»–¥k\Ë̵tײt-ƒk™¹–îZ–®ep-3×Ò]ËÒµ ®eæZºkYº–ÁµÌ\Kw-K×2¸–™ké®eéZ×2s-ݵ,]ËàZf®¥»–¥k\Ë̵tײt-ƒk™¹–îZ–®ep-3×Ò]ËÒµ ®eæZºkYº–ÁµÌ\Kw-K×2¸–™ké®eéZ×2s-ݵ,]ËàZf®¥»–¥k\Ë̵tײt-ƒk™¹–îZ–®ep-3×Ò]ËÒµ ®eæZºkÙQf핱ïdzf™õúß›™kÙ?þyÛ­n„<î[½f%»íšgí2k†¬že-Ϫn€<îžyÖs—1‹w?Œ(³vÈšYÖñ¬Yf½²îòS–³·’½!deìÍÙ[ÉÞfÈÊØ›³·’={ËØÃÙ£dÀÞ2öpö(Ù#°GÆÎþ”ìO`Œýqö§d{dì³?%ûØŸŒývö»d¿û“±ßÎ~—ìw`¿3öÛÙ¯’ý ìwÆ~9ûU²_ýÎØ/g¿Jö3°_ûéìgÉ~ö+c?ý,ÙÏÀ~fì§³%ûØÏŒýpö£d?û™±Î~”ì{`?2öÝÙ—®µàÚç.?e9ûÒµ\ûÜ姬ö(]‹àZË\ w-J×"¸Ö2×Â]‹Òµ®EæZ¸kQºÁµÈ\ w-J×"¸™ká®EéZ×"s-ܵ(]‹àZd®…»¥k\‹Ìµp×¢t-‚k‘¹îZ”®Ep-2×Â]‹Òµ®EæZ¸kQºÁµÈ\ w-J×"¸™ká®EéZ×"s-ܵ(]‹àZd®…»¥k\‹Ìµp×¢t-‚k‘¹îZ”®Ep-ܵÿu׊ endstream endobj 9861 0 obj << /Type /ObjStm /N 100 /First 883 /Length 1599 /Filter /FlateDecode >> stream xÚ}˜ÍŠ\G …÷ó÷‚KG§þ B «BÈ xá…!$`;!UÛ=jµ­æömõ)髺óÍôÀºÚ5ÀkûÑ.鸆Œ öÆ\Úx¶.]VÖôbWßûê ûÙoïõ-×X|ékZL»úÒk©ÕÍ}mËè³_{YÝ”KÚàÕǼDh•C/-×û¶‹mµ½_¢ÃŠ»“–Êyº²bZqßV¬V<¦«OZ±Zñ²):¬x7+†ïa5²/´%vÑ/ˆetOöKoÓ.lˆnƒA­;Úd -H»‹“A› g`Úp6 m:LëŽ6–-H»‹}àXöÜ/´µÙ(´U¬;Ú€ [vW±I¹TíöYOi£ÐšÓÓm@=4Ï]–A‹Ð©–lëé²QhÍé²îhê¶yî6Ëà‰»Í³žìsöëN÷²¬³à¦­w2v³‹½_t ëÉFÑeÅãt7­xž§/Pg; öiê0:Ýáà“Ó¯‘µµÛ6È:£œmè–̳ggZñéNÕŠQU+>§@õv¤spä@:'ÇT±âuˆŠïIÎa´Ôf§¶Ù€Úα½á_ç8Û^Ù€Cm@Û»8kŽÛ^Ù€ãœ/Ø€cØ€°Ç<§ÀÓv6àX6 lÀ±õœ‚uÍvŽŒ 8Û96 uzŽÌ¸&l@Ø€SÏù²§ž#cÎs `N;¹/ßÿòæ÷Ÿÿxo}n{ø~{yóƒ]Ž/—¿¾ûøþÏÏ·ãûåõÇ÷ÿÜžÏÛ«_ÞÿûùLu{õömÈêž…2«=fÝžÿo²ä5KV•%#d1É’éY,³²Z–¥žÕª¬¶³¾v³š³o½ÌÒ•±oô,)²Î¬–±oížÕ÷,³zÈÒo³ÎïÊ×,-³ä!ëÞåS^³Ö®²Ö Y=ÉZ˳z™¥!K²,zVÉ~>²¿wù”åìgÉ~ö•±ŸÎ~–ìg`?3öÓÙ’ýìgÆ~8ûQ²ýÌØg?Jö=°ûáì{ɾö#cß}/Ù÷À¾g컳gÉž}ÏØÓÙ³dÏÀ¾gìéìY²×Àž{:{-Ùk`ÏŒ½:{-Ùk`¯{uö(Ù#°×Œ=œ=þ‡ý×Og´á´i‹wïÅýmIßÙMÏËúÆÈ|Zv>ldñ­-?¶B²­ߊ¶«¬¶"í«ùV<©÷9+lŒdãêíMŠ,õÞ»|Êz¥Í=ˬðdꥫ—[ˬGöÌÔKW/WÅžA½ÌÔKW/W/³4dI–EÏ*Ùõ2S/]½œ%û ^fꥫ—³dÔËL½tõr”ìƒz™©—®^Ž’}P/3õÒÕËQ²êe¦^ºzÙKöA½ÌÔKW/{É>¨—™zéê%KöA½ÌÔKW/Y²êe¦^ºzÉ’}P/3õÒÕK-Ùõ2S/]½Ô’}P/3õÒÕK”ìƒz™©—®^¢dDÌLÄt%{ 쑱w»²´+%°GÆÞ]ËÒµ ®eæZºkYº–ÁµÌ\Kw-Ë,„¬Œ}SÏjEÖù’é!+s­î׿u2‹! YV÷,”Y_}Ü»|ÊzýêCת²ÖYÉWº¦g±ÌBÈjY–zVÉ~>²¿w³¦³Ÿ%ûÉ•±ŸÎ~–ìg`?3öÓÙ’ýìgÆ~8ûQ²ýÌØg?Jö=°ûîì{ɾö#cß}/Ù÷À¾g컳gÉž}ÏØÓÙ³dÏÀ¾gìéìY²×Àž{uöZ²×Àž{uöZ²×À^3öêìQ²G`¯{8{”ìØkÆÎ%{ 쑱g/%{ 쑱g/%{ ì%c/ξ•ì[`/ûæìK×jpí½Ë§,g_ºÁµ÷.Cܵ(]‹àZÍ\ w-J×"¸™ká®EéZ×"s-ܵ(]‹àZd®…»¥k\‹Ìµp×¢t-‚k‘¹îZ”®Ep-2×Â]‹Òµ®EæZ¸kQºÁµÈ\ w-J×"¸™ká®EéZ×"s-ܵ(]‹àZd®…»¥k\‹Ìµp×¢t-‚k‘¹îZ”®Ep-2×Â]‹Òµ®EæZ¸kQºÁµÈ\ w-J×"¸îÚÿÙÅï endstream endobj 9862 0 obj << /Type /ObjStm /N 100 /First 910 /Length 2947 /Filter /FlateDecode >> stream xÚ}š]‹,·†ïϯèKoÀ±Túc ¹ &$¹ ¾XÌ’ˆcs¼ ùù©·g¦Õo¯47ggkªK¥GR½¥Þ#R¶´‰ÈVË&¹mÙ%~Z˜ZüL›¦øœÊ¦-ÜRÞÌË–{Ý\%~êVR<ÓúVš}ÊÍ#LŠßóÖ4üjÝz¿ª[oáWú–S±øà[Ξ%oYr¸z=|]·¬%œ-œÍ"ª9² g gïá¬á\j8k8Wkx4F•ˆ,áÜSBTäιFâ>Y1³0§ÓCää›h‰811±ð‰‰‰Å?11q÷-&&%ÅĤ„=&&5ì11iž¶˜˜ô Ӕ맘—¦˜iLK³•-f¥â-hmªôÂÏ’Åø¤"u ÊáW"똖¤Ã¯Zú³Ñ«“Ñ+sÑãÆT,’?"G@²·v ®ñÉ6³Tñ)¾õ€ŸÊfUû§øT#•´?É¥Û·GÀ Enû·5oîñÂÅ«î6ݼ'¿ÿë-ögsù—Oßü[õöñϯ_Þþý¾oèÛï_Þþ»Ýý·ïßþ÷»9í¿}÷ÅÒ+=‹çÿk/ ×X¹±ryË(–Ìbùˆ%Oc¥s¬{–—Xùˆ•Ú³X©P,›ÄJƒ}Ò§±2Åš±Oòˆ•{ 5õ+MØçÞF,K)VžÅ²+?‹Õú)Ö#ËK¬tÄjõi,§X:‰Õʈ¥OcÙ?²¼ÄìëSöµR,ŸÄªƒ}}ʾ*Åš±¯ƒ}}ʾû:c_ûò”}!öuƾ öå)ûBìËŒ}ìý){'öeÆÞ{ÊÞ‰}™±÷ÁÞŸ²7bï3ö>ØÛSöFì}ÆÞ{{ÊÞˆ½ÍØÛ`¯OÙ+±·{ìõ){%ö6c¯ƒ½>e/Ä^gìu°—§ì…ØëŒ½ öò”½{™±—Á>/ØßŸžÑ΃v¾Ò>óõGžüüå×÷‘ØŸ^ã7 üûŸÿO~ Çu˜±ù²‰Ð—Çn»ó˜Â>N4åFùu˜±F‰×¨7—3Øt^$;öåcT=*þ¨Ö÷Qõ2j«yQï˨\ÅÒl5‡z_ÄûñìhVL‡V_¤ºŸœIàPæ‹0Ó“$Ë3U¢|Ñds?ËfèñEŽIgò;Ô÷"¾…¼±£¥~¤³¯tçu6?ù¢Ç$À3ýò{Q_ZTÖÞDç žÁÄ=M¹ v,ÃEžy°ó2Ì¶Óæ‹2Ó&ž)ñâ‹_Nëðã@Þæ[ÎËr°˜¯Ëë‹V_Ç;/ÓLª‡R_„úè\'a¨ôE¤ýd¦}C’/ŠLžùÏÔxˆñE‹ÏQHˆg¹ ¾¨0EQª¢“(Ò‹þž£øÎ´wH¯¬’ìÎTwˆ®¬é’àÎôö$·kº$¼SÝ=5˜ë(t©šõ7'U]FáŽ~&9GqšÅ¸w1“c~Ð\œ•Ûù ¶¡ŸNµ]z†üÿýëOo¿nÿê?ÿøõ_ß_¿¼¿àeÓžÜöÕÿ|ýåýíËo~›a½•‰ÃºÙ"/Û-ŸaÒ06ÙËVv ?DrŸúü~ÿäøÃ5ÍÇWþ(/£ØÚÍöËë?ÞnYßê÷Ã’Â$·’q˜ÂæM Ù2l7hç,OÃÏIÞ¿ ¼€;ÇŽÖ*Ù‚‡÷Ìi:lʶÛƒïÝVa»-Ì9Ï‘Áp\¥Ù¢qšKtk¯¶¼“32%¸ÝNæa˰)Û¶›RM²l/'ÇE–Y¢Ó"el¤{ÏzØ6e[ÍÙVa«N¶Û­+û˜&2Ž«4îþvçá-;8â+wñwØN8s8)´ $¤-`"á¸ÈRN8"§¼–pÊ0à´r<Ð[{ù1Md0i*ÀÚ„ pƇ\Δ΅œ9ÍFÎ*Ç ë‹,ÇŠ«-“7𻂛-›‚›;±TpóÆ™ƒ[Iô¬í ú"ÉQ‹–I°ÞolÅ‘[)”¤[il¶šØU¥ ÇUšà†¿÷œÃ‚[å½eàV¹Š¸µL~nìæ Ñ4-²,/'ÇE–p+¡\ã,à:Ÿ2¸žùY€ë|ð$zY”"d0Wi\oTŠ<ÀÕ” °wØŒ†/×iyK‚ŸžyÔû%z’e}99.²,‚Âa6#HÅ`«lsØ:Û"õ*,æ¥Âvë>¦Y†H–¥H€†YîR1c$ÓÄ&€S®ÿà´R¸ vÛ“,‡HÖ¥HV€3Þ™à¬S=©ç||+À¹rêç…¶F‰’;³Ž’Y—"Y®pÖ.Óè à.Ũ\ap à · $j^Ôõ:D²-E²\e à*¯e¸zI à*÷T à.ªD³ÅjC$ÛR$;Àq£ØÑ=Û=Û®ó6è×ùütè¶Ø™ƒe_êO·îtÊ{Ùm<:¸u–ün½ò Á­Sg¿wYi±-û¡‘«³ƒŽÌÔÎó\ j§£#¸´”Ø&°e!›Â&l3Øt¾Úr$üVI:"^`£Ó$¸´TØÖ`«ül‡9¢Ï¿—«I’䪤 n-ÑVÜ Ú])°eƆ–«eƆö§Ýßì6€¸ÿ%åc–y°Ì¾LܲóPà– n¹²¸ñÍ­ºiq2ÄêB±'0Yb9šP!ªIfÀ‰° àD9K€ÞAhó›øb_J~99®Ò8) ·‚& ·‚&Ôñ"sSÞ.hó›\l ¡i±är4p\d‰[ASê¾·‚¦Ô€nMyÇ¡Ínjl8u¶„.îº{Ãq•&Àiå°§ ×£fNÐf7å’…F¿o!4úaë‹,fŽ‹,q/h×á.Zn²œ)ÛΨç4úÍœ*0ýf‹×{Ãq•&À5Ž8fB£ã^Ь±Û®Ó: ÑoÎ… ~óEç¶'0Yâ^Мw!îÍùøâ^WZKôÙa#Àhô›;O$¼Ì{¢=ƒá¸H÷ãâ{Asj÷‚ætñ’²ƒë”%ýVÛ@¢ä…þŒ’Y–"‰kA+¼ q-h…7!®­X'¸zo èó[åí‚>ÿÞhO’"¹<㸴ÆIâVÐ:uœ‚[AçÛ™ ÉîåB›ßEh2hó»Ê"Ë:D².E·‚n™V·‚î[pë%ñð6>>hóÞº Úü~¿ÌO²+Þ–"‰[Ao‰/úb£»áþ:)ŸÓ̘“@eÌõ|ÀP³í~¾>&ØyÔU©„Ę“8BaÌ ƒªÄ/~ /V¨‚¼XQJPËb3êQ#uU"!-V¨1Ü_8Ñ{]‹â ]±Jï­!+V阡HGù+µÑV¥’b•nP«í¼’ã=±Fï¼ 'Qã)cL¾ù¼(ÚQmU÷WLôJb†¿õ‡ŽX§Õ†ŒÄE¼0ù®ó¥=ªŒ¯J!Ä:] Ö9;€êÔZ@>¬wJ%@y¢ÕÞßé¼»õ#»UÏá!=¯tý’„lx¢³Õp¾´@4> stream xÚ…\ÁŽ%¹¼÷Wäѵ;IQ”þ‚…¾.|»Þ5lÿ?VŒì©yOÁ¢ç0H$%))H*»ÖºÇu_kÝë’>÷ƒÜW“rÙèñ —7‹‡vMŃ]r~Ô/ш_b«ÅÓ¸dˆÛOó’ÕV¼[—Šë~ÒûÒ6c\•KýŽ9U/Mâ©]íî1Çž¨éˆ9´_­ß1‡úÕ†Æ:®¶Lö:/“îñn]ÖFŒÒîËúŒw{P›7ÞéÕoÁ»vuÅlU7û~uw¼ó«Ïs´qù=枣ÍË6o0n+pØ}¹¯°Ïäòu‡Í¦×‰Q¬]£a6³kt…F¿ÆÐðÆžrÄ”ûi\SìÞsؼfƒ-¶®Ù{XÐïkŽ]®¹<¤}%#Æ‹Ÿ´鞼þ¾ÿ7`\²Â»}ÇãÖ»ïIv„wà`áVn—øßûñ‰ìvÈ çìh‰h „Þö£~°C/Þ#¾c/ólËDoøÏ÷lª>öl¾gSPÛ³í—aì^-¢sÆÛ,i÷ µHšÂŸÛù²ŽìÙvHc¶½¥-¬ÌKM°ök-8ölÖ[˜³ç‘=oü`Þ±,-`Î=[8vîÙöOcܹgë®Ý6IXAÛ™Ò–ß^G²ýæÌ=›·³Í=›wØ;÷l>ïwíÙÆ {7ª&,{÷‘±×R<îÙÆlx»g›·Am϶Cµ=Û܈¾!Ž2+aíÙæ ‡ßû¿½¿îpÝ~Üóím±ð¼ßlÌÏ{ÆíþÏ{Êmî£Û/Ý–6<û~n÷ÄóØÏ]Ú·ßÿþÛïþøÓßþ×õ?¿ùÇOýù·c|\½8/þtýx5ãÕz{µö+Û.øõÕþÑF¿^ßÜñ£½â^^I¼2¼úó·ßý÷÷¿ÿ÷ÛÔŸ?ûó·?ü­›ú{¥¾ ÙâÕ|{eûU&/¯z¼Ò·_y¼ÚûõåU€ï¾RóbîÏŸ}a^xªÏ7'„§ü~e…§ìÕ-+<åožZá)ßgÍË«ï~çÖÍ_–[·ÂS¾wÐËá)_¯¯ðÔ×h¯ðÔ°W®ðÔð7X~< óbîÏŸ}a^xjޯߞuËw¼Ÿ¦üó§¿þó§üí¿~»õž/vËD ¢™ˆZ›sR«×ÿ<±þõ˜ªe6‡(³¢ýí‘õõl@ƒí=°Kˆ3k!Z<‡¡+ƒ‡}Þîl@ìóv×Ñ [I­†‡C¢¥k ‡D“ ù„5:2Qœ·­eȱ™[Ë\ÐZ oÌV+á)‰–-³M¼õL§dËLqH4Oï³(D#P 5Kx°•Ôjx x3³Fcq¶l™) Ë–™â°;°E`wÞ“‰¹iyrÂVR«á™bÜääTœÖ’“SqH˜Ý™Z– ˆ}n=ƒ‡}n^óóä µ óÌ62xkÉfBn:0àÊ´FDï¥øxMˆf Ï Þø´®QUí>ó(ήä= lÔ#ÚÓÀâhéi`£LØlRf-°•Ôjx‘…ïU“`hwÄ¡'Ñ}ûz×î™dAÂÞî!I&gž/¡ÕBhUÈFd±{ÔÄ’(…Å“¥7pMöÿˆBX|%£Å"Ø5‡sD’µ%ÕŠ„•§R +–ˆ a×Ï8xeèH “@ó†ñÉ2ÒC’¬Ò)’Ö:ÒçPª`Í ÉŠšëfxbˆB'9xfƒ+’•;ŒŸÉh £M+`ÁÊS©„e0>9ʦ HxAÍ8§£—•H&$ `‡DF" XS«„VžJ%,ì†íž»!Zr,!Æ9ÌÄ>™–Œ†Å>{2ÚÂh^šç"\5¬uÃgCvPô´I"±Ôæ”D"pê²4öÖ—H’*?†•§R +Ê…]&†`7ÄÅI¢z‘•,¨……7 ,ÁhɪXÑ¢¸ (`EM(•°&ZbˆÃÄdÙ,Âò$Z&z2Z”²²ØG“SÖ(aùÑ' ¥Ö‚!Ù²Yœ-›…×ÀZèbýûýü—ÿ¿ÿE×n{bô_z}¯ ÚY°ñÐ!L¯bÅÊs5 cA‡ Á³]0\xŽmª ¡šå0ï]£~OÄ6Ç~ß¶9º[À6Gßd œÁ`A‡`h¾C¥„ãqñTp¨ò þßaÁ‚€C p™²Ë.S«àøÇ©RÁQøZÙ× _+ûZáke_+|ýKÖô*ˆöüm첆¥V¡Ñc©µLƒß:{ºÁo=Ý¿³§àw^œQwwvXC˜ŸÆÂhÚ±ÔÚ¬á`}t=89öàä؃“C¼åÖNÐVÿ‘J|g}œ*œŽhóLQ¸ï™ØÕQ¶ÏbÿU€=˜œÅ{pðè—LïæHg4QÂwi›¨ç6¶-2Î!I˜7kIh‚É4z˜w¨Th¶îb£ºxAM,ÁÅ *JêñYÞ½ ÆiçT±Gpf}DR½Gä] ÈðR‹d{ Ø×q=:à FßÑä)æ–*8aÞ¡R¡‰;Ð="Ç`MBE‘ÞŒ‘PÑs«¹Hœß­@ ¦ßt#˜õšP)À`›í•§š8h ¶Ϻúõýc´±hŒÉÀhEhÎS@êd@ Œ6y*D€× Èàço8Ø|t ˆxpò°ïP©à€Á‡ OœÎQSàôÄêØ8ÙJ Îo7L<¼H`Þ¡R¡…fjiã<ÖçÝÒp $«¼:¯Zƒ+G‘x¾C¥‚cˆÁàu`ˆÁdW[X½n¶LÜY¡+`rüã6ÝV•FüC¥BB“ÑtœÄÉÂqËbã¢bSA‡€ñƒŠgUãÀ¾C¥‚ô‘£h4m/B°þäZFÖg££39 #°Õ¼@æ*šñ8޵ñÀä¨!˜Ì8‚t`rñ#`ýi|r€£§UÁ‘Ȭƒ3aµq &‚c¤ÓØ×88ñ”üÆÃgRupæœUéÀäjJÌd[#˜\ Ò¾h­)“û ŠÄUpŽ„@ëšMѹ˜Ü Pt.æpàk/£½¦È8ùWt &ÒŠĬi˜w¨ThäqÜâ©à8>¤‡±2K)2…É ¢ 09ñQÔòs(ì;T*8È=&'†ŠÜcrÁ ‘)Øg7îU[j ;M€Éh,)rO˜w¨ThÀûÆÉŠF+u,& EM¿$ÑxаըÀŸ÷…öXZ$Ÿ°ïP©à ÅXÜoQd Ÿ}åWp6ŽצŠL!‰fd ~W‡4Ì;T*4‘bxs¶ ™Â²Äͧ·>™Âd4ÈëŠLaYuôŽ—ù"ÅX|Jk$ֹ㙴Y²?¢ÑÞ•{Wß™%a~¾šîÏÖB¥BônÆ5ˆ>ß;;{ß3æ}Å'È2? ®À5Ô~|³üšùÞíКAÏdWã£a½iG¡fáîE¯Ü·Hmy"À²ð ÌÁŸ¡R€i7¶3ÑòÜþLÞßP`4à®ÅÕOCA½8h(W• À¼C¥BÒ[œ 4´ÄgM«(jM†ƒbvñ lŠÉgG8Zv £Â³ÏÈ_ß Ÿ«í!½É0Ûƒ& h8‡kw­¢È9 ÐV·£ºÎ‹óކ"x-Fóp§ía¨dGŕ輹d®»M-ö Ì{רÀDÓyÞÜ"lÁlóNöt|À=“›ÁÝèy';­?`¥còªþ„}‡JÇa5ç#Ía5ç#Ía5ןÍa5×™‘$í°Â­Ðø{ÚÙFf2š4|[ÕÐdÆ ßVµùXÍgýÄä­‚38³ä›6auc8Vs‡¿MXÍ-Lô¡f‚fMK@cEs½íèV³g[@Ã…{[@ÃuY[@Üݰš38»a5W¬vcò^ÁYïpB¥€c7¬æ|ÌnXÍ×Rbå^  Ðð•Ƀ†a ÐxQâÀ¼C¥B#@ã‰q@õ)¬æTÅVsajúXÍp“W—lv4¤MËtÀVsæa VKÞ a h8±°4œXX{ÐÌ;T*4 h8#1ƒÕœ‘˜Áj.ŽÍ`5'f°š{˜uVpÚÇÊ|À@ɼÝí¡Vn\ØC­+ÑN ì¡VN ì¡ÖU¡yO£­¾Ïµ‡’ù¢ÓÀ¬Â‰‚Y…³ ' fNì)ýªcà¸Ï­oÚ Œ,œxØxÀ0J«pId VáÄÂ@¬Â‰…XEŠŽ'ì;T*8`dáŒÄæc5ñ @c VáÌW%–„Ä*Uâ ó• Y4™ h˜Üm=h&ˆU8±è¨Ö)4|+­³ÞÁ„J¦ƒ¨…•¢N>ƒèà[á+Ó~?`¨ÇÿxÔŒsßJÕƒêÇ—j¡R¡Q '*D-œ¨tð­XbÐð…@ß ç|ûãŸC~çèÞöº{ÛAÔÉ7*D|qÒÁ·ÂÅ—8;Âï4 |+Õu.Ì;T*4 já|¤ƒ¨…ó‘¾îttð­8[ ¾Î7:øVªNG?º·½îÞvµpBÒAÔ î`‰¨ƒo…; |+œotð­Ì¢ÄéÇun¨Th@Ô‰JQ '*„+œ¨ô‡p¹¡ÑÂå¼¢?„»ªàôN}ۦ愤ƒ©¹=ÑÆåD¥ƒq5Ù9`\͆rªàø{¢*Pµr¦ÒAÕÊ™JŸÕ Œ«|×ÞÁ¸ÊW(Œ«U¯ö*œ… rFªVI@éJ_† ÆUî^w0®jQâô÷"û*Á8(Y9Sq0«r¦â`VåˆßÑÎÍŸ8˜UÖ×``Þ»FŒ¬üQœƒX•cæ V刃X• — vbÕªÓáǧޡRÁ#+W™bU.}Īœ@8ˆU9p\-$hÚƒ¦(püø6:T*4`dåÄÃA¬Ê±*çbUÎĪœ?¸=“WR°ïP©à€‘•bUnh8ˆ5¹iË¿FbUO@ãUpì=ðúöÓûƒfòT@ɃX•;bUN,ĪœX8ˆU«Nì;T*8þXÍp@¬Ê¾zb«rbá±rbá±Î¢þôãöÓGæad¾{ñ‡X'[ý+§*þ+·@ü!VÎ8ü!ÖUÁœús(™/_ÄjÉû ñ&÷ŸbmœX8ˆõÇçŸ_ ™ïÙ€¯ ¹qyˆL¨ÂmÜ÷f±`8} ÜVu:`Ý¡R€`êÆŽo¹š`Ü&‰høK½ÆmœW 0n«:ã¸ÌõeîU7NH¨ºq§c€qw:†>V30n’ 0n«zã¸Ìõenü•[œª PuÂŒ›ûã&§Ýh† ÆmU¯c¼_æŽú2w€©g*LÝ8S Üäx ÜlqÚc4£áZ‘wŽã2w”—¹DÝ8ƒ êÆÌß¶äxß6Î`ð'fãNÇßþø«1_ 9.sÇ/—¹ÿ1+Ê endstream endobj 10009 0 obj << /Type /ObjStm /N 100 /First 1143 /Length 4228 /Filter /FlateDecode >> stream xÚ}œ½®õ¼qFûï*TæM‹äü€á+R¤ \ N ûþaré+¢ýœ=ÍÁ>¤Fœ‡"µ†#Jí¾ïyÝW»ïv_ý~µËÚàW¿¢-~kö§ÖößÑùéWëã©ßufÎϼZøsÀ¼Úôüíü\çô”öÝRÌz»º%f½_=&®ôqõ9i­Û5î…3ݯÑ×c×ðÇÙž×Èöœw^cµuZëkKèœwÜ—Çß±…ùH~öËrL~ŽË–Ñİ˛=¥~ùðç q¹Gãg^žñ0/_i§µÝÑòôËm÷#9™µ+<1³Ý™hÛ Å |0»²ÅcæWŽxÌâÊß[³¼2Ö¶S¹s»V3ÞÆkÝçq-Ä{^[Ïc6¯µ=éǸ=§r ñÐÞsYspD¬ÿG[kƒSÆv¸Ž˜ØghÞŸsî¿-ûsž]ÛVo§Ý3>zëØžžë£a{:´{Ã6w»=]qú¼/ç}.ÅhÏ 8ƒkìø½ÛÝã†îÈ}†‘÷sÎýw¬ÛO»¹k­ÝØžÑhãÆv¶3ÀŸá7w­ÅÂvîvm.údîv÷éñgî¿ÞŸ‘{†²ÛzιÛõXèšû >'ý<÷™ã~ý©>±]»Ý°‰í9CÄÄŸs昉?k·›¨¸i={>çÙó÷éµv»ÏÈ<žçÌ~Ú=Š&=¼ïûï|ff;ª§1Ôéçªíßû {n:¿w»ë¹ú{,ìßÝ“ßûÈeþ¿KV0FÛéí5½ÿöÇ?þö‡ÿøï¿ýåï×ýËßÿò?ÿøëÿýï¿þÛv¯ÿÚãyšûúÏëUaT¸V¡“Š”Šüµo{rHù} ’¶ÿüÛþý¯ûë?~pïÃäÏ¿ýéOßÔ$jRNÔ¤:¨ÉœFMN©˜x½GŠTÐø¬ä䇜mRÉ™x=UÎÄë©r&^O•³ö5Xû†%å¨Ù£\*P³F¡æ¸÷aR©Y¨Y:Ôj–Ê\¨Y"sÞÇk»›Vt*ºV•œõ–sL 9óÎhÚÔ¤Bä̶¯A_?”£¦ÝZš¦2jZÿ®÷>L*5 5mhS¨i*³?^/­Àë®r:^w•Ói¼WrÚ‡œmRÉéxÝUÎØ×à÷Ž{—£¦«šš¡jj†ª¨•šãÞ‡I¥f f¨Ãë¡^^›zmxmêµáµiÏ[1sðïä’ã\U㨱©•é¨Q´LGÞ念ƫ‹ã¿>-*1Ó.wÜ YÍUM,*1@:nuH‡€pW¦×j`t 0:†Êµ1T&¨¡2ãñZe‚Ú°JŽȉ^ÊÑa*F‡©P¦r’k ·@P¦2Amx¥&ì×§I¥&OØÛFHS (Ägî²Ní­q¸xܘézûo ¿9 !dz·E¡£Ñ•SÛ?2šÞOo’}í}P.²ûñ·éí¢'åßW4xö6(dtÜ•åLgm"I€>P¡Óa Bï>P¡{œ˜¯?ÈýYE!ÿ**$ŸÔ w%ä솻£tÃ] QºÑé:¨ì´Ûïï1?ž½ ,F$ÖêÞhE:×åÒ¹~Tô®çIÊ¥7Õ ø•ö;Ç"oeÕÒoeÑÒoeÍÒƒ!¢ÁWàmÊ|V…ˆx‡+å€Êçy„8•ˆÐP1ãe€œç{>4Pá™S×î<ñÑ ²ç[Å6(dœ”þ^y‹Œ“Çõ¡œ¸«<™<¶|”“[ZŒ /¢­ù¾Õ®RÅB…¤ÞúB…Η… Yšt9Cfý¹Õu¹ÑŽëû¿ÞßE "Ð!‘ù ,ÒçXã~†¿ºuD˜¬Ô˜”Ôà“g'Ì78ö6(T@W3mÜ (iBé%Mž (©Iö%­x~ŒgoƒBpµ©ÍãîÔæ».P?Գ߳‹¯âÆá]Êåßcñ¾ÓƒBpu ÁÇ«kRo@IÍé (ézQ¡¤ëE…’nßgž½ ÀUó"¸jZäœÛ4; ¤&KÆ¡¤ Iu(ùûâþgö ¤ŽA¡¸jJ`×H0·t.˜ Ɇ 0©káq0éÑ‹ îoQo@×Ð1’tºx›¨èZŽ AF¢BB'£xŠcoƒBE¢B–3¼†ÉÌ€“¡3N†$œ É38QÈÈ·ŒY…Rg¾š ½x ½©ÂÉî 8Ê=8™·–/Ê¿!ï öÿ]„ÁÑ”›¡Ä”Ç"SÒ!ÆÚ5%b1eu|njæÅN{§¯¬âžÑ”•¶ÁÔ…¶ÁÃŽ!³Õ"¦ž’Òv£Ýb»ž½ †»²Èöƒ²Èös¯ÝåÒ·çv°ËE<ÔÞ8ã%F5 ìEïcP¨8—vŸNF”£BV>î¨Ð‘ã¨ÐYxhCçQ°œïÄÀ³·A!ã`tŸN:=p7µwe•íðPçuϽÃÃQ„R8ö6(T€Ñ!A‚ÃC}€îðPw•;<ÔdœÃCÝdìðЊLxö6(d€Qs™ðP÷:ëCy*áðÐ$CîðÐä ‡‡VÐÇÞ… 0ª{š`:à¡KlðÐå™tÀC—GÒ«Ýqxö6ø.#À¨îc^ƭŨ•`ÀCÝÄðP÷0<ôâ9%޽ `ÔåžÑe%ñyQ7o@Ô½«´ž½ ƒN—Ö!¢f«"jZ* ¢æy"†éñ¨(2ñº×žã p4d]1ä^1–·KÇ[ ɸÅGñÇ^Ç"ÀhÊ­3àaÊ­3àa6uêˆH½tð0õÒíöâR¼ÂcPÈÜ•Dd㮬²¦,yx9$Ið0ó{j->FT–*Àh ¦lu x˜ÂÉ€‡S/<œzñàálÅMê½—â2ÀèÚ|R®Íã®<Ž Ö‡’¤x8«§ç^¼ßw9… 0:uÃÃukù¢üS]ÂÃ%O•.S W±lų·Áw F—,}. `yR®Ä.IE$<\²RJx¸Š¥޽ `tÉ* áá’€4áá’“ðPÓO —Ü›óð0ïö}cK¾·çd¹!FSóIì¡ Ùn“‡‡©i¦<<Ì[B©<ßËD„P—wÈw¹ŒóD„$£yõ}—Ë%:¯ ì‰*—(PY¨È倚\YÙeÇÛò®Û›sÒç²á…WÞw¹\‹É¼˜z®Ñü…àÙÛ ’A¯È:”=N;´–bvnêY\ ÙM” Õ²µ…Wãwy*Þ³{Uot䢳dÙš< Õ½ö¼NïMvóà85ÕÈKç©»òæÁZþ¾+ïgïeë,—­¼aŸ}¨[‹òÏ)Ë÷! P޻߇w)o”Koœvù÷E޽ çuK‰uf{¶¶HçöÇ]—òÇ]9OÜÕó Ê¿ÇRxö6(dsp>eõUÅ;š*÷|MÞÌ×—¿ùAêǘ&Ñ‘n‚æû©› ù¼é~ÄçÑú÷5~ýÿÿKX$0L Ëç öšÏ¥Ü)×ãƒò”ò¤|Jù¢ü;/Ö{Ë×*|s!B­|/ õ>ë$6R¿àÃgÒdí½ª%qÂ×vù÷Iñq%Z”"è+Ylò)…].}ÞèC¹/ó……].}N€¥ßâà iÅ;%ë©?»Àg \‘‹t‹IÄ7RŸ¤-ò)ú$O1„@•/1¤/Á|oá âŸcÂnë endstream endobj 10110 0 obj << /Type /ObjStm /N 100 /First 1149 /Length 4460 /Filter /FlateDecode >> stream xÚœ½’öÈm…ó½ †+?  J¥+P)pêR`»l +|ÿn~Zï ûL3™al²Ÿþxû:¯³Žó¸Î뺎« Grh éáå8²#ÊpäG•àh^sÕ…Ã8.Í»t—ç}Ëy"¼~š‡2O”â¹¹ ÷9Dã>ÔCÆ…ûŠ’?wœ‡ãP r¢)½æ÷%ýÔ8Q ï¿5poŸ¥f§Ü×ÌÏÚÜwŸ¯ ޳»ún».%r7Þ˜OKðŒù\ ½çݤê¾fžQ1Ðu#¨ðF™ðûšyÆÎ»Îýt~n7ù…kºï-îqóJ?ïѽïrîswcÌ+=Œ1ÏŒSÁØCîÁÚ =Üîk晥ýÜ¿qîßw)°§ôˆvÔ³ÇLä‰úä¼sžõìÖH½PŸœÏM÷}æ2ÏÊyfÔ³kR*˜&Ýbå‰zö諼‡ãœprž‰ûÔœ)÷Ÿ/§ß“uNT9ÓqÿyF®Ùó8Žy¬÷ œ-/×i6Ç±Ì v;Ï{"˜ÅóxÎÏ9+åÇ(â8žÏ•ÄÌ–ygÑžP}<Ÿ«Š:Ë]¢£SæŒý×õó¹0çsM=úÃ~úýŸÿóoýÇñÿö¿þ÷?ùûÿüîç9à?æÄñöJÿ~üö¼ôùÙÄ_Ï+Î_ó†óò8?>ætñëùêë ×ÿå§ßÿé—¿ýòÏgÍ>øËOü#Á°·Ó¯1àÍ~ûz~bذžÍêú˜3ûëù»ºþõ¼÷mjpŠ®Ø§ë¿ðâÑV~C<*åè£9ȾžGÕ£O½ûÈÏ´;Î_œÂ¿P|1p»ÇPðÀùGyöùëQ­1j&¼¾óGsŒù\óÔo0ÆÇ—ß`ŒêǜǺüyº;ÃõÑy¡8ÿ¼¡º@ghqŠ®ØçßP:ã9Ðayè {t^Î?:/OœL°¼pÞ9F|îŒYàŒDëÚ£u­øœ¯yã=Z7o¼ÇÔ辎ëA] É)ºbŸ |CQs,Ìyö|LwÒéÎ(4úø\ÛŸ¯ŸgÛæãfËãì¼Ô¾©~×èóå¬úÓ:Q¿Ô}žœ7¸Æ×“³WäüzrlyTp’˃evž²7Ã]OSåÙÝú¨]wö—ÚY·é°¯'ç“F~=ÙZ¾žœÄ×íY×uÎÏWÓ:®Éõµÿë kžž•™âí_ˆÿû_¿©f߈XæÍò|XÆ=´®‹½ÏîÊ=‹_1ç"Ëçõ𑱶u›ú¯ø³ÍÛ&º° Ưsá³MzÆðQágÁï)ÑÜâËfEƒÛ%¿©Ò¯æßaærÛ4êéÌØÓç<‹˜¥ËÖ·¬úk~)¹¤ý| þÛ~ýdV8e\ÓÚª{XŸ6˜Ovzëjóøƒ`Y|ßÚkjî“TÁQ…dm3>˜·.vëá0'3OO#óßÞåc]|=Ô{‘b]…~³K¯ ¬Íí“åbƦ»”Ñõ Yú£œ˜ÿ¢çc9êë|ÏV2!çw^W€ ŒzéÏ`bŽ|$óø2fî1'ûž¿Îué={;!Þæ’nüY?bÖîÙùËÌ(­¬t» UfìV—[~K¾ò]zOn¨ž³ê9j0‚™»ß%بiw ¬l‰$3c.JÕ–Ýòc]| ­뺞ÐFíÍTX×UW_•µ &´‡ Í-y¬Üü‹7œôT7R5Á»WÙˆ±Ò+¨Ä0³Ò=ÑŒ{&i];pYMô.½'Ç\Öb5èU ^a"枬®ÌØãÙ˜ÞL4SâÍnq÷-»¬†{ßÃc¶š“—w‹u6"1[m0ºÑÝnIÞ(ÉÌhöÚzx,‹ïá1×ýd½0[‘µ ¾·Ø°€+paðxõ»0øþt— ,߯§{¾x· ¼‘ƒ¯NF/ ‰§íM†3㉲ÉÌøÎËý°¯•°éâ[øù•gÐ*€®„™10ŠÌ[í…ˆ99XÛ\ ³1³Ã¼uõ`XßãÃ#6²êj0ÑÞËå:ŠÏ4ï|9Â̆ÜýíËâ{x<XSóÁÌà|L(Þƒ½HÂp°·ÝFmvÝâË_㾂9õþ’Õ`mñ9˜ÓS|Ê:ï ðtäàc¯õ±.¾‡Ççò7îHÆçàKÆçàKÆçà+Ö¶øŒþ±Øþ-¾-ñýÅ7M¨”†“Áw(bš<>Õƒ-Ï(Ä@°EíuþiÞïÞw]zÏŽ‡ Ž z#¨c à±ïA àQŸ%Ô§´’È­ÄÕ凼¾x×k‚:­;uZ+AV‚i`M°ScOŸKúz!rµÀGýRú%H >±ÀÇfU¯ë*yÏöצoÉïÀųðܰDÌŸ”V0fIÁü™A$óg‘ÅÚ")Ïm¿ƒaY|¥•Ìe”V2—eIÉ\–A$åE$¤µH¢M‘”²]»Á²øJ+ÙʤAi¥žÌ x¶¢mIÉ–. "){ˆ¤´íç –Å÷øPZÉVO J+Ù²ºA$¥3¾ItàC$å`ðI9öðºÒ÷]|¥•liÖ ´2O=NÞ÷ð±Òy]|Ÿ€§n+OÝVo0¾u*>êT U‹í–Å÷ø>æ™F¯:‘w=RÍ…Ñ0Ì¥ Ã4Ɖ†ÙGëQýeñ-ù8Ѻ̥ Ã\Ú€Læµd’œŒ2I˜ÃIrm; Ëâ{|h-aåΧ3¥FÀ³t„$,(= “„-fè$ÙǬA°,¾‡‡Øc|[ÂBÚ:IŒñA' ‹xè$q6q “dle.–Å÷ø-¶Ø’܀ؒAÍ€gA÷$Áà¡“$¤–R¿©¥Ô/A%)}B%)u)‰ße1#à÷ Z XßÃCj)uZZJT’R§•¤,‹g@%)u)PI:ö#?—øõBâH-¥~ RK©_‚JR–‚øÑ`FÀ3‡PBš{øZ üx“¥SʼV@ iQ€†7æµJȘS (!cN% „ìÚF°b™¥o²”rʘg (!cýþ¢±ÅØ€2í(!cÑþ€2Ý®kÄ2K)Þd)ä”±”€2Ñ(!cý€2Ñ(!cý€2ß~ÚÇ2K)Þd)ä”±L£þA©±à]@  ÷”±p@  ÷”Å~™¥o²”rÊXØ> …Œ…íRÈXì9 …ŒE/RÈXü+ …|¶e–R¼ÉRŠû·Í¤ÐBÎbú-ä,¦ÐBÎbú-ä,ñ1 …\öð«,¥x“¥ÐSN¤SÇ)ä, ) …œúH!§>¥¥ÐþçF±ÌRŠYJ9åÔiA 9uZPBN”³4¤€rêo „|l¿ìc™¥o²”rÊ©_‚rê— „œ¥!”3—2»öb¸õnût…Xf)å‹,¥„ÒræÏJË™?Kˆ$gþ,!’œù³„H,"œIãÜö{.³”òM–RBi æ²Jk0—•I4W;!’[çí_)‹è&DÒm×ç2K)ßd)%”ÖPZÀ³5„H,ØŸIƒ}¾%DÒ` ‘4|»¨‘Ë,¥|“¥”PZƒ)™„Òì]˜IƒÅó{¿cñø„H,ØŸI#öðË,¥|“¥”PZƒ×ð, )!’‹ç'DÒ`ñü„H,žŸI£¶_ö¹ÌRÊ7YJ ¥5XRBi èg‹$Ú6IÁ¢ý ‘,ÚŸIqíá—YJù&K)¡´â¢€§n *)X#¡’‚:¨¤ N*)ö z¹ÌRÊ7YJ ©Ô3µÔ¢#2)¨Û‚L öå›IA=dRø~™¥”o²”Z+¨Û‚Ö ê™ “‚¾´ “‚:Ȥ 2)r«rs™¥”o²”úgýÆüRA 7ž¹­‚ –†TÐBÁ-µ–YJõ"K© §’e ”P²4¤‚Jì/(¡dÁþ‚JÏÇþsÓ¼]Ô¨e–R½ÉRÂnzš, © „’Åó J(Y<[ìi²x~ÿ–Õ謀ʱ‡_f)Õ›,%ìÁ§É2 J(YRA % öcÃ>M³Ç–zÓÌÆ”PîcöµÌRª7YJØuo>ƒñA %‹Ù”P±˜}o(fÔ§A  èc=­k¿ÌRª7YJ9U, © „Š¥!a<-êµ „Š:(¡¢NJ¨tûy[Ë,¥z“¥„Ý÷´¨g‚*꙲w‘fƒÁC u[PBÅÒ°¡u*PBE ”PÅö§ÖµÌRª7YJØÔO‹x¦Þ²ã"ÉÒ{8Ñ Óˆ†!.mšÑ0$)ršÑ0µïøU–ŠïÈçEh]âÒz³NU?YÃ`+Ãód|-“ì¼_ˤivf˜w3,‹ïñ/ð ëÜÞ$¨¼i< ÷O3àI¸š¯läàíÜÂ_˾—7ðx:²|Æø|Îø|Îø|ƒµ­¢jöø²Ä‘¥$½ï—_ Þ?<ö*>ƒÁàƒÁà“ÁàsoëÒ{v^2<^1<^1¼–Iv ¯e’]'kùÞíùÊ-û*K© ïÙ[jÍç3vle|]Œ½†]c`ÆŽ Œ/ê3USÙÒ%ý‹,%é­þœ¬HIoCçd=Jzk/'«QØZËÉ·tž¯“E$é Žoc‹z¯Ên{C2æÄúÕîd Jº¤“(éý´ÜÙm±c9áíý˜|§’Ŷx]t‹Û[9Yu’ÞÇÉš“ô–*NVœ¤7´p²Ô'½1„“µ ÁޱÛ­‹µ±=nïMàdIúÇíN¾§¥íä{Lúǵƒèyl‡6˜èéŸÆí‡šØŠ×D!ÿ­öÂØ endstream endobj 10211 0 obj << /Type /ObjStm /N 100 /First 1151 /Length 3770 /Filter /FlateDecode >> stream xڛͮ$· …÷óµŒ d\Å?Àð*»Y$ËÀ‹‰=pfáØOÞ?"«%ßvë´0ƺ—¥"?IE*ê–³–ó8Òÿ_Ú®ÍJ¶Ú¡õjñáR³%G©çÕÔ£´FÙ´£ˆ]M?Š×ÍzýzzÍ·Ïnµ{’«[¥£ÚÕ­÷ rëÆ‘¤ß*É­›díjÚÑÎ[7?]Ýè<k oTAò·õàSòZ¢ƒéÔl¶ƒ¹Y6ù`õ¼/É!']Ýôz¹ ;„ëu­¢ÊÑìc¥g=Ã[+}˜$ïÛãS.y³NØ/õl¶ÃÎ3·ñaµ]×ÊaírÜaJ×µv˜_Ž›ؽÉçáM[xãr¸–¼–ëá./g Žc8Zþ[9‚¿.+½]×÷+Kñdîl¥QFÀ}&3Véÿö©¬á5¦£ÏeÞ3BçO_1²µO¶»µš_×t¿T®±Œ‰jFÃDíš0é‰oíî—äjk÷KZsÝh÷KvõÕî…z<Ùî¿éë)ãÔÞ«•’ñÇä´z»O÷ÛèâÒ\«œ¼ÚÓøZÎÚý6ÑluSË@³k|¬[ù<¯v÷Ë}ä²Ý½p½ë~™èjw¿ÜÚÕî~™/¿Öý²\ Ûº_VM.ï~ÙÌÃox”óÌ%kCÊuïWJ¬Êhw¿B׌{¿Rš$£w¿Â–,Þ¯ñχóÌ5+A<Ç“bEêIú.ÚÝ‹–Œ“âyÓœÁÞîW*Å(õv÷«Í¯¾Ýª’k€ÎîE¯%™—Õlw¿z­7 ïvæZ¥žrŠõ…õîÛoß}ó÷?üíø×Ÿ~ûß¿ã¿?|ùôË¿~ß×öW‡ô´sÿ8-ŒŒÒpm´0êÚØ;ö ¶³wìóÛß¿ûæoŸ~þô…½êûý»ï¾{Ê+ÁK€W‚—¯o¼¼ ðj0qƈy,+àÞw ¬ÁÄ€IƒI““¦në°¯^ ^ÝòFØ«¾[^ ^¼¼x-x ðz09`ò`r°¨<rßÛ ¸÷Ý{gêé8·0®™èŒ9lÀÖZ 0Ö020¶0ny#ìUßoOƒýþ ïô\FÀ[‚‰S &¨H T" +1<θW}·À%˜@n¡shÀ¼ ïP ^¼5xAÒ Èß*[Þ{Õw˹EAÞ¡X´ r Åh¨& &ºîFº´ £î€ë ¸÷Ý÷ÀºXûnÁ òNxa¼-xð¶Îk iP³0ÚŽw‘°¢ë—;’À{¼R¬Ý¥Õ©‚tzÄ*xNB¨ìp#ìE×-n(šPjk×K7äˆ5€rÄÀ 9b à†1®;^Yñê^bQ(úŽb_7 (䈡)䈡TrÄÀ]CŽ˜nyu¡°¢ï–7)àmÝ`dÁk€7äˆà 9bUÈóí‚¶°ï%…¢ñ0žî'` 9âçš)ûÚBÚºÑËvv}‘­¢ï¶…ÖqZh ©Å†ï…#R ¡â e´*N»Ù͸W}·À¡udZÇAÖi±ã;È:±UC¶àeÀBÅyË[V\_à ­ã #µÐ:2R‹ ßAFj!Tìê-„Šƒ”Ñbcõ+e<®+`Ú èû£Ç)2©£y ¡’N‹‡Ô¡1xðæmÏs L ·À!vº@j§[×B©Å®_ÎBÀZÓªÀš`µkFUwoÂýªó›¬°ðŽfDš´$4hIè %¡ÛšZ::o¡%¡€Öc¦ ÆLL˜&˜0°fT²{)ÎèW·Ø½_;r³„Vm ­ÚÚ´%´hKhÛB¯˜ífO.\ž\¸B”þ䫤p…ˆéÖõãm;b_HkÞG*ª (T ÈSb [Xs0@žâ3£"¿9u7É«—§è»e.ÉR—䩈KrTÄ%¹à*ÉòH¤ýzn™Ë z¯H¸&3ÈR\“d)®É ²ç§÷²çGÝ"€9?Ý}÷ÉèW·Øù-«€LÄù•¤€LÄù_@&â|=,Àú+zpòÕ£øšj;:o¡S¦8¥QiŠs‡!uÍUw^XS×Dåym­iÝ%²Œ~Õy‹Ò(JÔk÷ VXŒ˜Äl‚áL]Eéµ5¡i Í á·Ð)¢v½vŸÐ @§®‰úôÒšº& Òkk‚±kF%»¬Œ~Õy‹Ò(ªÍk÷ ¦ ôÐ5hcJ]Uæµ5¡ vꚨ o u!¾£ó:¥Q”œ×îÚt ›('¯­Åãµµ¥¬¢6Tv¯Zýªó;µ´’ßCÖ–6@bHJ*¬9Ý7‡£nçÙ"T^¨FIª#ÉHRH8’Ú†€¥¶!-$µ l!©mˆwó,«š”¼P“’”GN$Ò Þ;%Å d$)nHtŠâ†t ½*LÉ …)I}D UIê#éHRÜHG’↠€¥¸!K$Å ]¹äöª<%/”§"ïW À%õT%)nHU’â¦T%)n¨@KŠ›VvßV{–¼P£’”G }‘”G Ô %µMEhImÓ@ZRÛ4P†…PiW‡”Õ»Ö ŸN$ÕQUnIuÔÀùIiÓ@‘ZRÚ4P‰–”6 ”¢%¥MãÝË–¬ÊUòB¹JR5pFR5P–”6 ”£%¥Mõè ®àÝTRÚ4ÝB¯jVòBÍJR5Pð–TG …‘”6ÍQè ŠÒ’Ò¦ª´¤´ás÷¶%«Ê•¼P¹’TGŒ’Jª#.(tKë:tJÀÚÒ|eД6\·ôªz¥/T¯4Õƒl£©Ž˜Pp9 hJù@SÚ0ÈšÒ†ywÊOW5,}¡†¥©Ž¤MuÄàx‹¦´aâ«à«¦´a+4¥ ëzUÈÒ YšêˆAºÑëÔ¥¢ÐäMià hJù@SÚ°ïvj]•³ô…r–¦:bR”®ƒŠ,¤ #[gç4¥€S,šÒFÊîµCW%-}¡¤¥©ŽTž5Õ‘€Ò³¦¶P{ÖÔ6ŠÏšÚFÀMm#m÷EW%-}¡¤Ûm_>5%ˆ€B®Š¦@+ç1:Ð7vjðEU­|•'½wÈ+âÞwKœ¦‚ڥ枤àtB~cX#…¾¨à3°%Ï£­]Z¡°nÏèªÆwÄ–ÙYÁƒØù+øBm™œ<²ªyÌ Ü÷:Jò¡‡êöËwF¾èº%Îl¡ ènÌy¶ Ld<à“¹¥ì6ði;tZŸÓ-WµmkÓùªóÙb2 n̯?`}zöi ºVPð”[&Èš‡Èt'Æ2öUçt¨Û Š^)ÏÇ+ÅpPqXAÔsŸò‚¬yߺÓ$¾ÐaÑwKÌ÷BnWPùð|Ýtð~ä’qæùBéht#[âˆ|ÑuKl”ç*@d–ãž:Ï×GkÀ“ÙwË3#Xuž¡ÿõÓ½ŸÛMâú8qéãÉè  ‡Mý/¿üðç~ùðùKw÷뇟>¾/•NüvƒÛ÷ÿÞ(£QGc¢±n7nÓÇ[•0|è[GØ:¾}ŽëÇãÁªÛuúè³ôàÃFÔ6¢¶µá³Çc]ằµž #hAÛÚÇàùãQqÜn\¦^L‡ }í#hƒç#·µžÓAuáâô8!ê#oõF õŒ ò¸pýVñì  á¼ ç¥,=ÄÞxµÞ>ÕÃC–è­¤ÑÃy΋.=ø5ÛŸ?üôùïÿùú})TžlÜeD^Gäu [ÑTzôôöþú]+?z¬ƒ¤’:HêÆ:¢z<Øqwÿü«´7¿1z|tœ @4†—FPÄOÚõâ0²Z9ÏňҠ¡ACƒ†Æ·R{ÜÞܽÞ{k‹Ñl¥ ”6PÚß6"júÄß9+e±ðÛi„±åvVÊý@}| <†–GD‹´oî~ÏVicœÀíA"ƒdlTã no0öV¯?L™?Ç^=z$cƒçx}ìÝ}§é“E’qöög}Ììãpo $cï§{ãÉ"¹ý‘Âü¹Ñ‚mìy>ö¼ÛaâhŒ±»˜Û“U’‡ßüÌç‚mì~>v?·A26´qžØÝž¬þÃãÆ²`¡p9î1¶cks²JXîÙ„lcKô±%º’Û.ç–ÏÙz²N„îéÄèâuÞ‹f«ÍÏ–ÌÖ“Õ"~Ϩr®|Ú¸W™$·/äÑš•QiاÊ=§Õg™$e’ÜíDë÷ˆæ(×û´zÏï>ëdª“©N¦:G¹ÎØÇÞø¸çìÙrås2ÕÉT'Íñ¦UìÓù.k×>P Ÿ4™h2Ñd¢9Þ4c[yúÝÇuœoþü¸-Å &R›Hm"µ9Üm†ÖðªEïÆßå,üέ·Ì­·ÔI5·Ð2·ÐýŸôéZù¯ ïs.s.4 çfZæfZh÷Y¼¬ŽÀ÷Ûߦùÿ÷³ì endstream endobj 10351 0 obj << /Producer (pdfTeX-1.40.25) /Author(\376\377\000M\000I\000T)/Title(\376\377\000K\000e\000r\000b\000e\000r\000o\000s\000\040\000A\000p\000p\000l\000i\000c\000a\000t\000i\000o\000n\000\040\000D\000e\000v\000e\000l\000o\000p\000e\000r\000\040\000G\000u\000i\000d\000e)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20250820154553-04'00') /ModDate (D:20250820154553-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) kpathsea version 6.3.5) >> endobj 10312 0 obj << /Type /ObjStm /N 39 /First 419 /Length 1162 /Filter /FlateDecode >> stream xÚ­XMkG¼ï¯ècˆ¶»ª?A,„èÇvr2:¬íÅô…wuÈ¿OO¶,±ÏÍì«Wóº§j&x†à¼ ý?]@(:¤4Pr¬(»Ô¯œPq™m êJÎ5W[œ¦ZÀ€ýòüj‚˜jâèå¢ÕÑ‘8_ÛrªöŠe&Úi~p¡:xÎ?k!^èPG]‡8±õ’Hs‹¤CÎãgìªJR{Ô¹sf‡VfX}í°º®d´Óëp4í½cä`‹Á1¥0±E8æ2Ú‰t,mÇèØ0ˆcr]ð|Av1`°Åâ"‹U™fØ\Œw2ùSYŸ¯Ö¿_}Þ»Á‡Þ®wïÜ„ŠPjGÔ[=¢i¼ï.Wë×W7W‡^å§ýÃÇéo÷épuwûóYè}åNWë«ËÕfóœ¾k=–¥PJBj3–Eú ú~,~I’š$5!õ™¸Äßo²ÁŸ|3ø“´&iMÒš4’¤>S[âïÇÊâ/ÉàÏÒš¥5KkÖL²úÌi‘¿XãïGÜâ—Ö,­YZ³fRÔgYÜ~9ôÅ[ã/’Z$µHjÑHŠÚ,‹Û¯xkü%[ò‹¤I­’Z5’ª>ëâö+Å¥¥¿Jk•Ö*­U#©ê³.n¿JKm–þ&­MZ›´6ͤ©Ï¶¸ýš7è[¶ä7Im’Ú$µGï…w_ˆ|x”Sþ¾ªºŠBI( -m¿^³ü¨}UYI ’Ô\Ps!.ÑÓ¸ûhÑ`’$/!õÔü{˧ìÌ9‚ŠJ&$šÔ$ò9³!=»dB2!™Ô¨.‰öã©«5vJ'¥“Ò©@Ìà%vëÐ¥diW¤€"¢t*@yqiÓ¥dhÏÁš»”(¥SiJHK›.‡j°Wo°+O@yI:• ,€´´ërÅ){‰ÖSš€Ò’t* @Iyiוh¸æ­]§,e ,f‰fˆk-Yå5N (H@A 8 wŸ~yØ~=tÒûí—Ý­ ¬Ìe(3@™Ê 8Í suNâdÞ‹M” „%(!ÀHO8ðŒ“ÅÚ¦JP*€R”  T#<áxÎÙ_™ N%( @IJP€‘žp<ãì÷É¢”$¹?äþûSîOÃý¿Q<›f;e¤üžò{Êï)¿§üž†ß£xÂx΂ÉXUIzdñó›ú»Çwõ#ŠßaìøÑ÷ÊÜ)s§Ì2wÊܹhîßy¯1ƒ%åSþNù;åï\ôw3XšþNù;åSþNù;ÿ›¿›OZ’ÿ×S• T@ ¨/d{驺p>”¨D@%*P_ÓÒùø™Ê<ýºð¬ýŠ]ìöýúùãK/q\þëŸû[ÿ¶=l¯ï¾¬ÖöÿÞµ:'ÕúíÃáúêv^¼ôf{³Û?~º Óoþ¸û¼[ÿ½ß¯‹¯·w×ûóóõ›‡›ýßÁûõÅfƒ¾n6ñ¸rÙ›Y¿½ßÝþ::wññÃÎÔä¿ÃØå endstream endobj 10352 0 obj << /Type /XRef /Index [0 10353] /Size 10353 /W [1 3 1] /Root 10350 0 R /Info 10351 0 R /ID [<77BBECB432EAB21C1D5F9947E1820742> <77BBECB432EAB21C1D5F9947E1820742>] /Length 25105 /Filter /FlateDecode >> stream xÚ$½y\\Ûuç˪ŠAÌPE1 ! M$„˜’„T”“œ nç:í¸b;¡ªdÞK⸟›8M"'ÁÎsˆÜ7éNœÆ× ¸¡“‰'0!Ž»Ÿóàöþþî?¿ëwÎÙçÔZ¿µ÷9Eµ¢¢RÿßwLTTJTtTTL”‰ŠùMûWÊŸFGþpœ¢áºá*1c€Øè¨ÔaÜ5Là„sÂ]Åtqp©pW0ã¸t¸ ÌDà\.\9f 烻Œ™¤Â„+ÃLÒáNÃ]ÂÌ2áÎÀ]ÄtYpp0³¸pç1=€®îf.àƒ{WŠ™äÃõÂÅ, áúàÎ`örS÷ä—Ó˜ÅÀ)8\ ¦à4\Ü)L pNþÓa:ù9¸4¸“˜ºð pò©N©} .®S» '?ëråì ¸ëpù˜ ÔU¸f8}T¹®·)\‡»'7U5p­p^ÌZ îœ\|¨‡{ —ƒyh€€Sx&¸A¸,Ìf î%œB{ °§L{# .³ ¸ —'YÜîÂÉé˜íÀ=¸B8Iê>ðNZKÅì‚“~¸«pɘ'p•p’r'Ð'?ŸÀ Oášà”ÝÀ38ù9³è…“þ”B}@?\\æðNù«ô^À=ƒsbZ¯E­Ød?1Å ˜ü]!ÙWl²§­¸XL’}%.N¦vvÂI˜Ñ˜œm%N"ÔP\éJœœÈ$³Â§\9‡_éZðÐJ2Iüê&Þ]I…ñ¯ø+Df%ǾzŽITW2ápì+|°‚"V²àpâ«~LÔ´’‡0_á¿”¸â…» ׋‰ŠW|pwáðý °’wî&Ù³RÇĸЏ­y+'ázàžb’µ+ö£¦·ÄÂó’}å4“«.L’}å,À+ô²B²¯œƒË{‚I²¯\€ó¡µ’}å“å+?&ɾrî:]!ÙW*à.À=Ä$ÙW®Â]‚Cã+$ûJ%Üe¸˜$ûÊu8ù”üX!ÙWjàäÓ{˜$ûJœ|Jn­ì+õpòé]L’}¥ŽIáy¹B²¯4Á½€»I²¯ØS¦¿Ž‚#§WHö•V¸h¸VLm¸ —§]4è]8&…W-˜º {pò•†×‡y—ׄ)G<„cRx¥K“ýpèùU¦ðN¾ÒÇRðºàXl^Õc*ðOá¤g¹D¢y×W‡)ÁõÂ1ù¾’;%Ö~8&ÚW5˜ús¸‡p …’äœî:¦M0óq›ìîˆbC?ªà  ÷®3°:Í𜀻†éœpÉpW1]@À«+˜ñ@«Ë« ÌDà\\9f wî2f w® 3 H‡+ƒ»„™dÂÕÃ]ÄtYp p0³8fÖWç1=€®îf.àƒ“K1ó€|8V¦Wg1 «ƒŒ!‰ð fpN"L ä:Ü}8¹©¨cuyåŬêà4 ÊÅ7€z8M‚9˜7žŒmîx^)<@\<\f3Ч$Vho­pÙp™˜mÀm8œdq¸ 'ý¥c¶÷àJà$©ûÀ8î_¥bváJá$ÇG€N K2æcà \ œ¤Ü tÁÕÁÀ OáÀ) ºgpJØÌ N «êúḻy‡9Ø4Íl`a~¥ô^À±0¿rbÚ#¢ûm²E±!“ 8DÃeÁÅbƱpZ]djg'œéâà”°*H€SÂFa&'พе$Ép7á^`¦©pÌzƒ˜i@:·8Ï13€L8nq&0Ý@"œèÇÌìGÈœÃ9}˜À ‡s&z1s~™èÁÌòáðËÄ3Ì ¿Ltc'áðËÄSÌbà~™`–§áðËDæà,œ|ЉY œƒ“ž`ž.À1óO<Ƽ\‚“_ü˜eÀe8ùåf9P'¿<ļØdwçpç1Ñy ¨„ãÎcâfpŽÉ|â>f5PÇd4q³¨ƒc•œhǼÔÃ1IOÜż 4À•ÃÝÁlšà®ÀÝÆlZà˜¸'Ú0o­pLÜ­˜ÚpŽ; í¢Aï‘8-˜º {pò•†×‡y'_5aÊáH° ]šœh‡rG¤¡Là œ4¤¥àuÁICõ˜ üS8iH.‘hžÁICu˜\/“ù„Ü)±öÃ1™OÔ`JèÏá¸K›P(”$/डë˜öêcÎØd/íŽbƒ„Tg€h8 ©3ˆ…ãbâ¦pÂÉaW1]@œv3H€“Ã*0›ìî]9¬3 H†“Ã.c¦©p|W0Q†™¤Ãñl:q 3È„sÃ]ÄtYpÌü0³8fþ‰ó˜À ÇÌ?q3ðÁÉÙ¥˜y@>œœ}³(„“³Ï`'á¸%ž8Y œ‚«…+Áœ†Ó„w Sœ…S t˜N~N1:‰© ¿Ç 1¡SêC_‚c…˜(Ä”Ã.Ãq—6¡Ë•³+à¸MžÈÇT l³Ú¸C™ÐGU+ḙðaJ ×ḙ›ª8ž‰'¼˜µ@·ºrñ  ŽG·‰Ì›@n O#ÐW —…Ù ´ÀÉ í- NþËÄlnÃq72!YÜîÂq72‘ŽÙ܃ã{ Iê>ðN:MÅì¬;³¤SÉñà‡“_’1OàŠà$åN  ®îfx ÇńҠxÇíþDfÐ Çíþ„R¨è‡ÓD‡9<‡ãjBé7¼€ã®j‰I²Ød¯Xb·VäïÉ~ Ç—N±˜$ûý+»Œ[« ™ÚÙ Ç­ÕD4&g;ˆƒã6tBCq¥ pšù£0ù”'à¸e׵ࡃd8:þï¤ÂÐq>Ç‘9H‡#!ÆŸcÕƒL8‚<ŽPÄAz¼5äÀñyÇñßJ<°—›=Ãsòx/&*>ðÁ%Àáû2à ŽG™ñg˜dÏA!Å8q; óNÂñˆ2þ“¬=8WGÌHöƒÓpÜæwa’ìgáxG/$ûÁ98Vµñ'˜$ûÁ83ÆÑÚÉ~p ŽÇŒq?&É~`“=ûˆ$G§$ûAã1Iöƒ«p¬ìãhü€d?¨„cR€I²\‡cR'?Höƒ8’xü&É~PG“[$ûA=+öø]L’ý NŸ¼< ÙšàX±Çoc’ì-pLdãäôÉ~Ð ÇŠ=ÞŠ© ·áX€Æµ‹½ Ç—€ã-˜º {p$û¸†×‡yG²7aÊö”9/yTץɉ~8înÆ0€'p|W5®¥àuÁ±²×c*ðOá˜Ç剿œüW‡)ÁõÂÉr§ÄÚÇ4^ƒ)¡?‡cRW(”$/àøNkü:¦ýD±oÙd¯{Åž?Æ«à  §Ä©ÄŒbá˜ǯa:'ϺãW1]@ߎ_ÁŒlÎä¬s;8^™œ€S‚•c&Ép×eÌ Nâ*ÃLÒáX±Ç/af™p¬Øã1Ý@œ&” ˜Ù@·Øãç1=€Ž[ìñs˜¹€Ž{¼3ȇSržÅ, ᔜg0‹€“pðiÌbàœ„Y‚)8 'ažÂÔvdOQ‡éäçà”ˆ'1uáà$.RúœÄUˆ)‡]†“t¹rvœ|©@]…“ôQäJ8M´>L ä:œ&Z¹©¨ãÎcÜ‹Y ÔÁqw8.ßêáäƒÌ›@œ| ð4MpJº,ÌfÀ¦©g–v\¡½´ÂI/™˜mÀm8éE²¸Ü…“^Ò1Û{p¬°ã’Ô}àœ|•ŠÙ<„“¯$ÇG€N‹R2æcà œ|%)w]pòÕ ÌðN9£4èžÁiâNÀìzá4q+…ú›ìÞTi#sx'm(ýpò‹ÓzÒ1f“½u;Š rŽÎÑprN,f  §™F¦vvÂi¦‰ÆtqpÜêŽk¨x Ž/„Æ£0pܪéZ’€d8œ8ö3H…Écƒ˜i@:{Ž™dÂá°±L7‡ÃÆú1³+3oÑŒõaz/c½˜¹€ŽÙ{¬3ȇ#ÁÆža…pˆf¬³8 ‡hÆžb§àÍX³8 'tažÎÂɘ¥À98Vµ±'˜ç p$ÎØcÌ‹À%8gÌY\†c{„YTÀq?öó `“Ý»Ád9Öy ¨„ã®eìfpŒÝǬjàôyïaÖupú¼í˜7€z8}¶»˜78Å÷f#ÐG’ŒÝÆlZà˜PÆÚ0o­pú¼­˜ÚpŽÇÈwwÑ wáøŽ‚Qï^½ÒÜ w‡×‡yÇÄ8ÞuÄC8îðÞ½49ÑÇWïx7OàXßýX ^œ|U©À?…#gÞu‰Dó ŽœÁkŽw× ÇÝÍ»î”Xûá¸ÇãŽw…þŽ»×wC¡$yÇÝ+Ñr`Îv›ì¬ì¹ܲKg»lêæ.J蕘1@,œ„~ Ó8áXIгÝÄÁñr¶Ç pJˆ ÌDàœRŽ™$ÃI —1S€T89¢ 3 H‡cBÞÎö Ž/»Ð½³Ý dÁ±Â’Îöl ŽïÈg»ðµÁÃÌ|püëˆ|s¶çùpü눔t¶…pÜ‘«Îö"à$œì4f1p ŽÕŠª‚\ Ç¿˜úœíÈu8žMÇä¦j ŽgS¦Mg{-PÇϘ\|¨‡“Ÿs0o pü`Láišàäç,Ìf Ž{Ž)´·€V8î6™êímÀm8¾£“,îwá4¹¥c¶÷àIê>`“Ý׫… ³xÇj:&9>üpš’1Oà4)HÊ@œ&€˜à)œ4®4èžÁIÏ ˜=@/w–cJ¡> NZ‹ÃžÃÉJ¿Aàßç°;Ûí§teÚdâŒbƒfBœ¢á4ÆbƱpšAdjg;”oIBŠÆtqp<³i¨x N+Df"pŽ `T×’$Ã1Œ¾ÀLRᘠG1Ó€t8&€Ñç˜@&ÀtYp|û;Ú™ äÀñíïh¦ðÂñÉh/f.àƒãYh´3ȇÃW£Ï0 €B8fÑÑnÌ"à$èèSÌbàÿâ `–6ÙóHºÑ.Ì3ÀY8|5Ú‰Y œƒã;Ñ'˜ç pòßcÌ‹À%8ùÏY\†cE}„YTÀ1á>ļ\…#G;0¯•pLx£0«€ëp$âè}Ìj ŽÞìêàäƒvÌ@=ÏΣw1o p$çèÌF  Žä½Ù ´À‘œ£m˜·›ìy’s´SnÑœ£ÚEƒÞ…“O[0uA÷àäS ¯óNZk”#ÂIkº49Ñ'­5`*Oà¸ÕÇRðºàäûzLþ)+ö¨\"Ñ<ƒcŭÔàzá#¹Sbí‡SŒj0%ôçpŠ‘B¡$±®Ë[åÎcô:& ¶e“ýéG±/ F‰åº Ç7®£•˜d÷V,ý£è`‹dßrÂñ¼?z“dߊƒãÖt m‘ì[ pÌò£˜$ûÖ 8VÝQô·E²o%ÃÉ9—1Iö­T8naGÑîɾ•Ç-ìè%L’}+Ž[öQt¿E²oeÁuÂ]À$Ù·rà”°äÌɾå…cr=‡I²oùà˜ÜFÉ·-’}+N‰}“dß*„ãGI£äêɾuNÂLà…c2Šôbæ>8&£Hf‡h"Ï0 €B8DéÆ,NÂ!šÈSÌbà³r$€Yœ†ã–ÿUÆ}æ pŽÉ#Ò‰Y X×åOq»Ïÿ9ã>s¸ÇDyŒy¸Ç#@ÄY\†c¢ˆ<Â,*à˜("1¯Wá˜("˜×€J8&€ÈÌ*à:·ö‘û˜Õ@ @äf-PÇ]F¤óPÇ-lä.æM mDî`6MpòómÌf N~nü´ÂÉÏ­˜ÚpN>Õ.ô.w‘L]Ð=8 "^æœ|ß„)G<„ãŽ,¢K“ýpÜ¡D0€'p<ºEô±¼.8îP"õ˜ ¼UDþ¦b$—H4Ïà£:L ®Ž$ŽÈk?I©Á”ÐIöMò7¢P(IHöM¾‡‹\Ç´ ÿ¦MöÁó$û&_ÆEªà @²or{©ÄŒHöM;r Óì›$vä*¦ Ù7Ð+˜ñɾ©„­ÀLHöM%l9f@²o*a/c¦$û&ÿ®‰”a¦$û&·Ø‘K˜ɾÉGä"¦ Ù7% ˜ÙɾÉÿ%#ç1=ɾɭ¿Xˆ3 Ù7%šRÌ<€dßäùˆ_;Ä¿Yì›<EÎ`$û&w#‘Ó˜ÅÉ¾É )Áì›ÜDNaj’}“™?¢Ãtr’}“»ŒÈIL]8ɾÉÌÑ)õ¡IöM‰µS#Ù7¹Žèrål’}SbÍÇT HöMn§#ú¨ 2ɾ)±ú0%’}“»–ˆÜT Xédp7ñbÖup°\|¨‡Ó$“ƒyh€Ó$£ð4MpÜðë“ø7›8îF" í- ŽÿwóË•ø7Û€ÛpÜ©F$‹;À]8%D:f;pŽï›"’Ô}àßyDR1;€‡pÊÉñà‡S~$c>žÀ±@F$åN  Ž2r3<…ãß²¥A7ð Ž;¨HfÐ ÇQD)ÔôÃñ…_$sx§Tú /à4:1m´®Ûdÿ¿b·Qœ¢á”œ±˜1@,œ’N¦vvÂiåŒÆtqp|óÑPñ@·`‘(ÌDà·`a]K Ǫ~™¤ÂñŒÄLÒá˜ÑÃÏ13€L8’8<€é²àHâp?f6Ç3g¸Óxá˜åý˜¹€Žä ÷`æùp$gøfPÇ­Z¸³8 G†Ÿb§àHØp³8 ÇmY¸ ó pޤ wb–çàHºðÌó€ YŸÕ>üó"p ŽÕ>ìÇ,.шáG˜å@¿™?ļ\…#™Â˜×€J8’)ü³ ¸Ç#^ø>f5@²ûùQMøf-@²ûI°p;æ €d÷“$Ộ7’ÝÏw<á;˜Éîga ߯lHv?wá6Ì[Éîç.#ÜŠ© $»Ÿï2ÂÚEƒ’ì~î2Â-˜º ’ÝÏ¢Öðú0$»Ÿ»Íp¦A²û¹Û ëÒäD’ÝÏw<áL€d÷³…õ±<’ÝÏ®ÇTàIv?¾a¹D¢!ÙýüÔ6\‡)Á‘ì~GÂr§ÄJ²û¹ã ×`Jè$»Ÿ-¬P(IHv?Ïûáë˜6ÁMöá’ÝÏíe¸ Î$»ŸU-\‰ì~n…Â×0Éîg _Åt$»Ÿç™ðÌx€d÷ó<®ÀLHv?ÏÎárÌ$€d÷ó쾌™ì~V°pf@²ûY™Â—03’ÝÏmTø"¦ Ùý¬Bá ˜ÙÉ>ͳsø<¦ Ù§¹µ ŸÃÌHöiV¦p)f@²O³â„Ïb$û4_†„Ï`$û4«Kø4f1@²Os[.ÁìÓÜ–…Oaj’}š'¬Ãtr’}šU#|SN²O³j„uJ}h’}šU#\ˆ)‡‘ìÓ¬a]®œM²OsÛÎÇT Höiž»Ãú¨ 2É>ͪöaJ $û4«FXnªHöiŒ°³ Ù§Y0Ârñ €dŸæn.œƒy Ù§•8 O#@²O³`„³0›’}š#¬ÐÞHöi-™˜mÉ>­C²¸ìÓ|yNÇlHöi%Ž$u Ù§µ`¤bv$û´ Éñ@²OkÁHÆ| ìÓZ0$åN€dŸæ®/|3ìÓÊ¥A7@²OkÁHÀìHöi-J¡>€dŸÖ‚‡9ìÓZ0”~ƒÉ>ÍÝ\؉I²/Ûdï—Höi­äï2ɾL²ïhÕˆÅ$Ù—Iö­2µ3ɾ£U#“³-“ì;üK(¬¡¸Òe’}‡[µp&Ÿr™dßaÕéZðÐ2ɾêz‰w—IöVŸc™È,“ì;¬¡ç˜Du™dßá9%„–QÄ2ɾêêÇDMË$û«Fÿ-£Äe’}‡U#Ô‹‰Š—IöV¾_&–Iö~ýz†Iö,“ì;¬!â¶Læ-“ì;¬¡§˜dí2ɾê"æË$û2ɾêêÂ$Ù—IöþƒB/Ë$û2ɾêz‚I²/“ì;¬!´¶L²/“ì;¬!?&ɾL²ï°j„Ðé2ɾL²ï°j„b’ìË$ûâ¡ñe’}™dßaÕ=À$Ù—IöVù±L²/“ì;,¡{˜$û2ɾÂ"·–Iöe’}‡#t“d_&Ùwˆ¼\&Ù—IöŒÐmL’}™dßaÁ‘ÓË$û2ɾÂjÅÔ’}‡#¤]4(ɾÂjÁÔ‘ì;,! ¯C²ï°`„š0å’}‡#¤K“í¥³`„0€'p,!},¯ Ž#T©À?…cÁÉ%Í38ŒP¦× Ç‚’;%Ö~8ŒP ¦„þŽ#¤P(I^À±`„®cÚ«?ñl²G¢ØÀªª‚3@4«F¨3ˆ…cÕ]ÃtN8VÐULǪº‚$À±j„*0p¬¡rÌ$ ŽU#t3H…cÕ•a¦ép¬¡K˜@&«Fè"¦È‚cÕ]ÀÌràX5Bç1=€ŽU#t3ðÁ±j„J1ó€|8VÐYÌ ŽU#t³8 §Ä9Y œ‚cÕ•` Nñj„Naj€³p¬!¦“ŸƒcÕÄÔ…_€cÕé”úЗà”8…˜rØe8V.Wή€cÕåc*PWáX5Bú¨ r%«Fȇ)\‡cÕÉMÕ@ œÇ‹Y XÙ³`„äâ@= F(ó&ÐÇ‚Rx&8ŒPf3ÐÇ‚Rho­pJœLÌ6à6œ ÉâpN F:f;pN †$ux§#³xÇ3{Hr|ìÃÊ™dÌÇÉ>¬CRîHöa-'0É®ú !¥A7@²ó|JÀìHvÕl)…ú’}X Fæ@²kÁPú $û° '¦Mö¤^›ì?O²ó¥XÈg’}˜çóP,f @²ó|’©Iöa­ј.€dÖª¡¡â’}˜o»CQ˜‰É>Ì·Ý#º–$€dæù|äf @²ó|>2ˆ™ìì#Ï13’](F0ÝÉ>Ìj#ý˜ÙÉ>̯ïFú0=É>ÌóùH/f.@²ó|>Òƒ™ìì#Ï0 ’}˜Uc¤³ ÙUäbä)f1@²ó­îH³ Ù‡y>éÂ<ìó¬#˜¥É>Ϫ1òó<@²Ï³jŒ<Ƽìó|6âÇ,HöyžÏGa–$û<«ÆÈCÌ+É>Ϫ1Òy ÙçY5F`V$û<«ÆÈ}Ìj€dŸç‹­‘{˜µÉ>Ï‚1ÒŽy ÙçY0FîbÞHöyŒ‘;˜É>Ï‚1r³ ÙçY0FÚ0o$û< ÆH+¦6ìó,#ÚEƒ’ìó,#-˜º ’}žcDÃëÃìó,#M˜rÉ>îGtir"É>Ï‚1Ò€©ìó,#úX É>Ï‚1R©À“ìó,#r‰DC²ÏK÷u˜É>/ÝË+É>Ï‚1Rƒ)¡“ìó,# …’„dŸgÁ¹Ži,¹Ä&ûèC’}^⯂3É>/ñWbÆ$û¼Ä Óìó¬#W1]É>Ϫ1r3 Ùç%þ ÌD€dŸ—øË1“’}^⿌™ìó@²r·4’ŠÙì‡Ò½äø Ù¥ûdÌÇÉ~(ÝKÊÉ~ÈÝÒÈ Ì@²r·4¢4èHöCé>³ Ù¥{¥P`Ó¥¨^ºÃžÃq·4¢ô^Àq·4âÄ$Ù÷m²ø÷¢ØÀ-Óù»O²ïGÃIü±˜$û~,œÄ/S;;á¸e‰ÆälûqpÜ2h(®t?Ž[&’÷ù”û'àPׂ‡ö“á??ÜNÞÇ»û©pÅ$k÷OÁ!þ 1ß'Ù÷OÃ!þ`&ɾñÑË>ɾñóÃ÷ä}’}ÿ⢵}’}ÿâçGóÉû$ûþe8ÄD§û$û~âç÷Éû$ûþU8ÄDãû$û~%â>À$Ù÷¯Ã!þ ù±O²ï×À!þà=L’}¿ñÉ­}’}¿ñïb’ìû pˆ?H^î“ìûMp<*oc’ìû-pˆ?HNï“ìûö£M"þ`+¦6܆CüAí¢AïÂ!þ` ¦.èºjx}˜p<*›0切pè>¨K“ýpè>Ø€©ÉóB°3 Ù'y^^Ãt$û$Ï Á«˜.€dŸäy!x3 Ù'yTV`&$û$ ÁrÌ$€dŸä–)x3 Ù'yT–a¦$û$ ÁK˜É>É£Bð"¦ Ù'yT^ÀÌHöIn™‚ç1=É>É-Sðf.@²Oò¨ÀÛ+)_ÌHöI‚g1 ’}’GÞ|Iùb@²Or·ɪÔåÊÙ$û¤'S"Ù'ù"*¨ª “ìo+I|˜Éþ¶>›ÜT Ôµ&ê#a%õsïµð±/[øÄ;*pxÃD}ò±þ"du|XǬW× w¨7QŸÕ.@ ­-À- hî öˆ¿Ó·UWË_÷võé&m½tG€x <:gÀõ+Ö0UÕéšÑK®´èúà90¼^R•0 0@4(?zLÔg¯j+Ž­»ã·eƪ֘¨Fc ÊŒ@œ‰úãfíœ0µÔQ›oXÅ3MÔŸ|R[Ý€Š-z€< ÛDýoh«*.ªŸX 䛨oÍhk@!ÄáS&êŸ\\ p(5QßoG]D¾+HåËÔá Æ8Þ« ,u$bÝ-Ì+ÀecRÞ¯­åµ ‡¯ã©w ¨ªŒ)4â(u8\ P¸p¸Æ˜¢mP<ôK¬>ÌFà¦1gþH[¢¢R?ÿŽ…ßæß¾ü®…´–wدët‘­@p¸ÜšŒ)-ÔȬu*ÔAIœN ›"0Tõ™Ë¦ÄI…¬ž°spߘKs:öððÀCc.Çjëcаµó¬$žÝÀ3 è2æúŸêˆÊÞ]ª]øs`x Â=vÞC„{ˆpîQKtO'0¦é†vqp/㈠Oæ-þ¢–Gõ¹TÞaî!Ì=„¹‡0÷¨ý¹—`Là}*…©Žå¹ 4Ù€D÷²„¹‡0÷¨ó¹ç6æùsËm^]ŽÐ+Ì:îåóÃßÖ.TÝC¢{ªó‰v÷T݉ç@•âP•MJ^¾AË7(jùFºåÃÅ P¬òl€•ox¯ÝåçµK.@MÊ7ò*Q¾qÈ4æcy¾(Jìa×agRàœå~QÜyàpÑr¿!îP\Ê  8cÌ/tŽ+)þ)þF5/+xã¦Ôõ9 UÜê-÷–¸›@ ÖóË>×4·Uj½¨>k»`Y¨4ë}@Y;•a}¨øª*¡¶óú3ù1Ð €n ¨vØA×5¨ê¤ üK&-Ù)èsnFY¨ª–E«ºüŠØd€5¿gÍÿ)“诩Ö)Ñ_S…Ó$@uMU ÔiÌ~wä ÈàÍýG’eÿÚ×_ˆaMõJ=QQéQâTª1¬©@)bXSYR¢¿¦b¤Ä|ÍN__þ NT ‹µà ¿—Š'd¼Äˆ±#;5ò9m¬¡µ‹À%»µH[ÑÆÚXCkhc m¬•³Z«¡µj ¬!µz€è¯ý5½ÖÆ5«ƒ?ÿ–ŽEkH`诵÷ymS¯_µÚË8­Ë ækÄ|˜¯=¶*´Z»k„{ »kÄ|d_ë0fó:evר«»Æk ƒöØJ; †5¸[âPÄÚKVjf¶€J™-Н¾õ=mˆ´P¹¾›«»k¢³¾iš~÷¸@ ¤Ø Ú hUK2ì†gÚ ¸, H4æ_\:e6àr<{Øê°B€¹½å$P ¨ìl  b³g•˜U Øc¾_¬A™ù[Î2 œ÷4õêG—=ÇOè*{ PqØ*@%a«‚­µ;OjgÕ€½¨òëM@õ^Uy¥ kËm>¤ËhÚ€;¬e7 v¼ŸÓxÔgmétsrßDÇýF‘Ö¿ÝïcÚ¯àš§eê®¶tT[mé±[?£­Zmé(¯Ú2¨¨j,=1Ñ©ïº}¼ŽáªJMôýù7åµpYó 2ã€x p˜è‚~_MPÄkþ_Qgg¸ô/êtð¼Fo‰Ë´ýý…^#†×Ù–ûª¸¼öDúuª‰>­¡×€Vûbfj.wUÇ"†×ˆáõYË}]œ»L¤ÿ•LÄðš*ïQÄkj ¿&æ¯KLôù-•¼.®×ì±ßÔ±ºg@¯QÄëZ ÎnÝÓVñE¼F¯ ÷ë*]þ“¼F¯Uò—ÜÿgvP)_¼öÿ‰Sßû€j÷ªïm}= ¡ìTŸ~¤ýT‰¼¶·NqˆáµJïö*¸«Ê¹&ºaVôÙßážFw Üûx¢;mf¤jƒJå:ȵÈÈÕÕÆTW¡}i¢ÛÞ§¡øÎ²îž‰þÀWõú]è3Ju˜JÛº´ÍTÆÖ&ºóŽFÑk7nõ'í(5J1@Z½ȨGZÏ€²³žR (4Ñ}3_Κìõ:â @­XÏ5@'ª®Û]îh—j€’°žZ@÷ToõT˜èx®Ao<{ØCÆ‹§  „«ç@áV mÆSíBÍVÏ} ¸e¢‡ß¯ñ(Üê±Éž1 ý…V=ÝåU==€•{ưv騧êá¶ÖóÐíï îcÁ.ýcïocô;Ÿ³™’ñ&ÇÕ!`úŒ‰#ªCDu(HlŠ~ކ(v<Äëîs¿kÑa€ÍéŒI™yˆ ä!‚<ÄCÍPº‰þéw‡"æC¹öˆè•&ÒC*:\l7|\To¸P•a• .0Ñ?ÿZ£œa¡o¶;ÿ¢vVáà2à²åfÅ¡ƒ!U &æCDu袉žþ¼P¹àJ»óg´3‘RÉ_;f|Vœªýòl5Dß¡F»á´ò¾C´ü•@s*9}¸j7|SÐÁ:˜«À\µÝúmEsè`ŽÀÏÝòÜe“«ó"†9Ä0×ðêꦽeÏü €æÐÁ:øßâÐÁ:˜CsVn‡6 ƒ9t0‡æÐÁ:˜Cs­&Æ#Ì¡ƒ9¾? vÊp'j1‡"æPÄÜðÜnõh+Š˜Cs/ù²•:Ì9 úrŽßcb µ!p.ø1«÷©w0)­œ“PP9'  Œr5’sâMLYP¤vqŸÓaTKÎqÔHÎÑ×½9vk…¶zŠ"çPÝ8'ÃÄ\wh”\À Ä]¥ý¨sœS PÝ8ÇÞ1ºë´ÂÆ9gÊç”Ú w´JÆ9çêç\®E&¦þ›:EŒs¨ZœC™âþÇ\÷ÈpOTö.ÒýPf5 ZãöáÑÝ+NeÆo*.®Šà•&æÖˆ†¿ 4ÍÀ-bŸÞÝÏu¬J…ßîZîĵª ~x`7¼W:§‚wN›‰¹ûW:Ç#à1Ð €gö°×a=µ¼sì"âGâÝ9ƒ|íªpw›˜‡§AUÁ[ÕºUž;ÖÄ„~ðM ›—ÝÕÞŽìláþm@¼éæ}IwÄÎîim@¼éæÅL7olºy­Ô±³ÅÀÒ‰2TÂ;£n^0õ¥Øûl÷§4²y‰ÕÉ·ÜW Þ–uGìºêþ¼6 Þ¾uóZ®›÷uݼTìŽØ)ã{u6ôÂKÀnÞvóz±›÷“Ý‘r;ÊïjÁûÎn^„vGìs£û-m ,=/V»yíÚ±S†û+Ú€6xÛÍûÝn^üvó»;RfbÞÈÒyQ o“»yõÜÍ{ê§ëì"âþ €xgÞÍËôîȽ¨¨¬hm@ ¼œïæ­}7¯ó»yÏßQ)xÕt¿mbþ}—Ψ*à¦Aþ”ŠeÉWªóŽ""ªîÞ¨¦;bˆ¨’;bØU|­>øû1ìò×.bØ¥8û.ÅžR¬,~ím@»L»H`WõÖ‘À®ª¬ý]ÕV'ú»„q7ÎÄLžÐ±*°®Šê*¡®šé*’®ªè\ø®êžä]ä,nøÜ»yW…Î ò®Ê›«þx¾‰ù™?ÓÈy— ïä]‚¼[Æ·jøyW…Éí­AV±Æ#È»L»Äw—øîß]Ò~—üÝ-71ý²F&Ò»y—€îÐ]þQ°JÆïÞ²ƒjrÛe>ØE»$û®ÎK|w‰ï.y¾Kw[LÌ'Ò52‘Þ%È»ü¿»Î>>dUj(þ;²KTw»,W+Ždß%ú»Ý€Mû¬ÛÚ@w ò.AÞ¥–w›‚÷ØÄÌ|I'"æ» ÷K¶óu;pTÿÉj‹€pöÑ2ë™¶Æ @"Ę˜Ïý 5¿ÛNÉ@* w}y@Ǻ, ° AÖ{´Áx\À>Cdý˜6äù@Pœ2M̾ SÅ@ pÝÛI5ëƒàp¸\.e€}¾Ì i¿r ¸Ø;…¬ÿ[®*P_ÜJMÌ[]:¹ªÔ«,½êÐ×ÛÃ~V‡5ª/oŸk³~IœJËßTP¾ Pù;@Ð`b¾Ô ‘UK^ÅãíBõi ð (|Ûcà‰Ý0« Úø¢Ì@ø¶n€²ïm=ÅÞÛúÉb€’ì1üõÐÄ,}Nç¥Î{› »«ˆ;?ÿ©£ÊM‚Þ³>abc¾F@¿Ì‰PÉ*Y@% qY@ d!°³Å7ŒÆC vqÈúªHÒ„´`Ÿ4³¾¦ He©, •¤²£ He©, •€JPÉ*Y8¤š˜oÖ锈fá$p  üÒ*ŸhÕÞSg}Kƒ–Heá¼å¾#½, —ô²€^.ˆaᬉùû¿Ñð(gÑ,Øe"ëéXd±P  …Z,ܬJ²c´jZ 3ÁzY@/ (b¡ÊÄ|'JÃ7ˆf¡‡Ö&{lœŽE í*Y°÷“Ù)Ú@wÔ´ žˆfAì„’«]ÔDÑ,¨uzY}ŸÎ«þj ýöØ";H /©z»µüþŠbÕöwªèï’8칉9JÖa*ë¯:þúR¢ÓÄÞXâÛÆ©³v¼J—¨\n74kC úün@Uù³Õ⧨~Y²‰=ñqÈäyv€ @ý²"€ÊúeÅõôËJ€R ÀĺG4Eõ˸ª':ö<@±ü²‹€}ðÌîÖ†2€êøeå@…ÝðÃÚp ~Ù5€"øeU¥ï˪Fàœ‰ÍÖ)©_FÁû2*Ü—5ءޯ¡š*חݨW_ÖP¥¾ìph2±%ŸÒP”ª/³wÙ?¥:€‡À#À<ì„’ýaíÒ t x`b/uj¼§À3 ×1¥#€çÀ ð@ |o›=ƒ@~™ýfÈ ™A 3d̨OC¿‰­šÓèe&HøÙ`Åv6+Lì ·£²Uã¡´1C‡»Údÿº6 ´1“e¹ß‡@fÈ Š˜!ú3)&¶õGtJulP‹õd(´‡ýC3êµ€6fÔaá  ¾ HeæœÝùmíŒ6fÔHm̨}²˜A3Èb†V 3öö#û/t²˜A3ÈbYÌ ‹d1ƒfh^0sÒĶNWZ Ünv¨- …,fÅ ²˜A3ÈbYÌ ƒ{cýÚ™n3He†3Èb†ÀÏ4›Ø‡§t"T2ƒ@fžˆaæ©à; @3=b8Öô2Ó ‹d1ƒ,fÅ‘ÂÝeb»{tTrddqä0±3öN<*‡)2ûˆ9â1Q%Ú ©Ú@¯£$å1Q!†#ÄpD¤\&vˆu:ûm¡ˆ#+†œ, €Žˆù3Ã?²ÓCN±¶"£€‰â©1Qó£ûãÑm!‹#~ ]gה̈́Gô×8B Gˆá1!†#Äp¤ˆáˆÀ•šØ j<µÑ°·9×5 b8R{ Äp¤¦Dÿ¨ÎîÒ¨]ÐÁ‘º`¨E¥‰ø[ …6Ž˜UŽì=HN‹vVw‹6kÞ‘©ÆhãHí,¬6rÞ£ êd6ŽÔ¿‚©àè–‰ýÙ¯id¤rÄäqļq„hŽ˜ŽPÄŠ8BG½@ý߀‰ýDµ@GÈâHm%(Gy| xlb¿Îו9?òb5ŽpN»á mpö®4çM™ñ€}ÍùÌD€þ/iàð2Úľ~Km*’€ ÈÜö°Fg‡—kFdÒÔáe®5'dÒÏáe`ŸCs>*® ÃËs@¶‰ýìçu¢" (Îü,¾ÎfOÎÇuìà"p (³þ£6\Ê  8obçC#_®U@5·e|„ÏèØ:àPÜ´>« @#Рˆ·´¡¸´üŽìåmàð¨5±_ü'ü.px<´£¼­QjWÒ ¨IIPkõñ›Ø?lÒ(Ý@=vYǪÉ ¾#ƒvî6H/ùM‡­€Î"ëÈbY¬ÓäeŸ‰ýÊ_iT²nÓþ¸JuÐpÓºú„øuu!úëê ‚ÖsD»ñ“@AÔáC-=÷ºšvéuµê ´ëöa4‡{½œu‚¼®ÞDzX®ûLìNÆSƒŽ³YçGßuÝöØÓ±DzH¯Û;O”8â»~ÐÕWÚ ÉÚ@¸×¯Õ²X'–ëe&öÛ÷t¶Z€è¯ßù …Ä—¬¨=Y…p¯îu½®Ÿ îu½nœ<%ÚO?¬$Òë÷½Þлfø®ÛebwDçE%ëH`½“ëGœÒ®ož  ¬óuzÒ¬÷(b½ÏîR«]À:XGëƒÑ_I#(€V1ëvùîšLÄã8ÿ;exšÞÁŒâ 8$Ù]îi—d H²—q8¿¯‘Ó€ À¦•ǯ#ràrû”ê hköÆÁóm(NÅÀ) ¸d‡~Ýë©9 ¨o‹µ\° i€2@ Xʵ]Á±ÿN[ÕqÅ>uxÞ+SÍVª¬’©>+Õ€º«Ô·€KÆ‘õ W-VÔSEMTÔ5EßK=³£Œi”6€–(5w,÷QqtC©ièRs óIM@¿“—Ô´‡ïOt¢GÀc ÓŽò …>&5ÝÝKjzz–Ô ‹_Õ.ýÀ𤣉b0ŽSÓÈ/àøk6Ú8º¾‹¸ÿóÌ:'à²Üo‰C³hcmÌ¢Ùvëïkk€6fÑÆ,Ú˜E ³~6Ö8®üN”d(gÖ>›zþP ‹Y`ï#<ÿU²˜E³ÈbU²˜E³Èbö<à5Žš¿Ôð¨dEÌ¢ˆY{géùºC4³öYó&mÌ¢Y´1‹6fÑÆßj+Ú˜½ ‹Ù*EÌ¢ˆÙFà‚q4ºuJ2‹fì}Öðü“FiÔ8å̪]Š˜U“ñí§þ8öîÁó}™jƒ,f;&ãhû´N¤þ8jˆ£8©³ 7Z‡µ·A³jjƒ,fÕÊÆÊ›¦ýÅ,²˜E³’…tð’.jQ£ÀwǃÊ4@ `g‹ ~ûæÍ|Sýgì ‡×+S­g5œI’íÖmMÔa& ðvÞx·+ŽŲ́¯ŒÉXYxÏê°\ÀÎÞK2ózät„I-²[«µ•f0©Å-`RéÛ’jµñƒ:G p(ÎÛÃîé0z¹¤–tpI-èÛ’z [Kê5à&pÑ8Þø’Æ£eK*=ZRiÊ’J–TÚ®¤6MvøG¾ §Jê- Õnx® mMTRï´NImî÷N Á8þý”NùxøûÌéý! žÝÀ3 °ÏÞŸÐ.}€z ê\4¨_Ñ:øËþ'¿ÂÙ‚õûØ^ãøÝ#ú<æzƒ. ã¢$úA¢$úAš ‰jÐi?;¦ñÐA íã¦÷§51fþçÄ! º! øem@AµBA5*Ô ˆèó–•7è6ŽO´ê”ê¤@êøc'ïk uP'¢Tÿ¢´wÞ/h$À›f^^Aóònš——Ö¼¼6ç ÚY`fYç@¼çåÝ9//ßyƒv*ðþFA¼Ìçå-?/¯ÿyy/ÐË ƒÞ }¤ð.k?ÄÀ ˆ^ÞLôòÊ¢—w½¼äèåíG/¯hzƒõÆñú±ÎÛ<v…ð~CC!Þõò’¨—·G½¼Vêå}S//¢zyCÕ»¡Qì’ð[Ro²zƒ/ã/ÿ–Hó Ÿw l0lЙj•lÐj l $°aŸ!¼ß×è`l ƒ t°Aà7˜6ˆþ¿‘ 7€6ÐÁAÞ0Æñ_¸añnÐIj1lð*baƒèoØu!סS" $°6ˆù:ØÈ7ޝk&€ $°a%› ÃÀØ@—í†dm@Ìv]ÈM§ÆMè`ÃÞYææ‹C êÔT ß +‹¯ýšN©vMêϤ†LêÀdg†Ü3: l¨³SÁ†ú)ý uQ"ú÷ìÎUÚ l b¾Á,°Aà7˜ 6òF‹qüùŸê¼ˆaƒÉcƒ™a£›; òMôi;^½ÆC ò$b؈þ†}†ÈmÖ.Ì /id¤nFÆnà_º¹42êˆh_Ô¡øöÇú÷´Ÿpñ@"dßãËïÜN @÷¡Ž4€žCv*ÈíÖÚ u¸,Ë=— Ð_¨ÃÐU¨#°“Bî›Ú% PG@ó Ž"€–A€ãøv¼®¯(Î¥€] r?¨¡.eÀe ¨®WkøˆŽ¨®Õ@ P Ô7€zà&дv%ù‡º F   Y:TØe"wZÃßîwv@-µø }‡iujŸõðÛc_ëØÇ€úeuê’€6ãØûu]Ze©7–šaõÛ~S jrõÒrüŸ8—_;ä.@ ­ÐÁb¬Ýú»ÚJôÕÁ ,ÆÙ _Öݨ–U(bQª’µ§R|ŸÇᜆOÈb€"³óD"úªÆSw)t°¨žRö¶1*JÔN ,ª‰:XTë(¿H|=ÆñΗu"õ: œˆù"1_$æ‹Ä|‘˜/óÅJ€p/îE½H¸ ÷"á^$Ü‹„{‘x,–glNDô‰ôb@¸[İH|‰ê¢ÞŒ ª‹|©£¯wä:Z¡-ÐEºH@ è"]$‚‹Ýa\ìˆåb@;³Åf¹ý‘qºþXWEO³Eú¥€¦E).€D)¼J’Bã¡”Dã,àuG_ ý…RRº ¥¤ôJÉè ”B›ž”$ãÌÕn€ö@)¹MR(¬S§ R³®3€Zt•jÌuP;®‹€šp•j½¥÷Ôpë  6[×5×ÒïJÕR‹·˜RÔH«Pû,úL¥”göwu}7€›€šfñ䟢ÿþ7ju P[,zY¥tt°Jáq=…U)©Rxg*…~T)šwéB•ÒÐ{*¥PÇ©Dþzlœ¾÷è2ðå«|½jåø½¥ª|½ñÆYùCê3•jNù¨9å£Ò”JS>êKù¨/壪”ªR>jIù¨%壂” R>êFù¨å£Z”jQ>jDù¨å£2”ÊP>J-ùzOç™_×ÉõªA @ܨå£ ”²O> ;ù(ì䣜“rN>Š8ù(âä£t“RF>j5ù¨Ðä£B“¯Woš#ª1ù¨Æä£“L>*/ù¨¼ä£Þ’zK>ª,ù¨²ä£¶’ÚJ>**ù¨¨ä£Ž’¯W ¼9ûšqžÿ†>]Ë(—äëU2"Ø«ÎcüÌ´Wýƈe¯º‡·^õ #n½êö’¯hj‰œY"g–ˆÛq["nKjêEÜ–ÔÊK¯d©1_RÛ.¸¤f]„qI0ÎËO5²:vÕ%õé"ªKêÎET—Ô“‹¨.©ÃVžq¶.ë05Ò"xKjŸE´–ÈŠ¥ã¬ÿ9í¢Z¤ÕÑZÒ¯þðÕñX"KÄc‰x,%â±D<–ˆÇñX"KúŽŒx,%â±D<–ˆÇñX"KÄc ·/µH`é>@2-Š%B±¤ï¾Å¡XÒ¿ÎåÉJãl¼§«'2Kz)‘["Á–Ô1Z"…–ôaüÑZzÉ(Ì¢  SSB @¦Ó«º2©¥Lqöäjgº2%ÄôbJHèÀ”Ðw)! ÛR¯å&Ðc)÷ý謔àè§” ¨%™Ë8|OÃÓT)! ERB@c¤„"€vH Å€Z%hõ/;èµ¹‹€z•é§9êPV¨/Ù@ÝÈ®êAV¨óX5 ~cµ€ºŒñ³îõ» :ï$ð­dB©q>Ž×…«Õ˜^îmÔQŒÎ@ ÷~ÔŸÀº•@ „G½ h7 f] @—qvjä ×8ßdeÊ ”€ B B B BAOŸ<½!M'Ÿ¼€^½$BÀ‰BÀ÷ôïÉ£qN^Àaœ/þA§¤«U€ J€ J€ J€ èL(øAD@¯`”D†=y½I<Ä#@<ă~;y¼Õ“ â â âAž¼€ú¦Ù[ˆüOº>ÂCÓ<ºâäÔ‘­P6P÷5JeÔq»P“5|Pk5bPC5âP5âP<@@-Óú݆j¦ñhŠ £VÕŒZUï32jUÏȨUeÁ[Uw3‚·ªžfjô…WåX{#2´¦¡ˆê*]Uÿ2¸ª®e„qU½Êãª:”ÆUõ%#Œ«êF– ¨\Uç1;ëý††'d«„lU¿a!d«¤ä*q[%·VÉ­U"¸JWÑÆ*¹µJ,W‰å*±\%–«Är•_•¬ç®ë„v•0®ÆU¸JWõ7Òe•tYåŸu«tâZ%Œ«„q•0®ÆU¸ª—cpûêmãü©_Ðð¤Õ*‘Y%2«DæX4Îð†v!<Çv±þÔŸé¶‘¬8ÆÇª€;qç1î<ÆÇ¸ówãÎcÜyŒ;qç1î<ÆÇÉÆùÓW4(Þ=&xÇÄòŸ«->=V36|zŒ;Õ_ ׫ƒ®;Vß4|u¬ni¤Á±ú’]6Ο=Ò9Ô2M/š¨3Ò15uêôõÖ*®;V›2\w¬æd¸îX-Étëü’Þ4Ú=n3Î}[¦:”©]îJ>J>J>J>J>J>Jþ”üÒnœŸ{­³õ¼¦ÏÔ’ÏԒǵ`#dSx| gOáâ©ãüòˆ~Ú„w§ðîÒT@¤© Oáâ)\<…‹§pñ”à•Ê©\€–FSjfÓå‹¿¤á‰ÂT€ï§ðý¾ŸÂ÷Sø~ê< Þbúo¤.W-ÄÊ5#Sjv P“0B6¥Ö`ÄcJ ÁˆÇ”Ú€ÝÔü‹W¢§ðó”ôÿÀ¯«RÝb4¥~^DuJ]¼ˆÑ”zr£)uâ"2SêµEd¦ÔaK¿f&2SDfJÝ´ä]¿qþÑ¿êDfŠPLñ‰6õÿ_Ò`3Ú8¿Q!S½¬ˆÇ¦:XÚMõ­"(›êV¥–Pög%CG£M³©~T`SÝ¥À&ÎÞTè"@m¢ðø¦îxðø¦ZBáºM›_oÖ ¨}S= Ŧ:?]È€M¼»‰w7ñî&ÞÝÄ»›xwïnâÎM^XÝÄM›6þü’FÖ‹IzEï)›í€º#ÉƹöiíL…ö`”q¾óRm„Ô«Çúê¯ïËŒŠ€4ãüÖ_ŠÓÏyõ;P5ØQGµÐ¡š}ÆIãüŸ—µ_1P¨˜C)p¸”7rãü'u:È ô}µî3(nŸA5û u¡RÛ)õ™R3§ãüçFÑ4·€6àÐÜú€ãüÞ‡u„:?©Õ“z;©™“º7©]“J‚Ú¨1R¿qþ[‰—lÕ.8Çï0®bìw.ãŠ}ŸL5VQ'µNQ¯5GQ7µ?¡?˸âþ‡ŽÈ<@.ÀÃüÅÆubM;Ó²ÀO?M üt!ð«¡:©MÏeãJËÒÎåÀàPð“-pÀWþ›Æå>£#ÔÓGM|ÔµGmzÔ—GxTÖP]gÔãæqyþ›ã}?ÿ#à1Ð €n ‡v.þê3®üoé5ÄQuÁPÇ Fžæ½Åi§q݈£]ÄtœqýQ™ñ@"¤i@@(¦‘Þt¶q]øÏ:BdÔ9F­bÔFÍ`ÔýEí^ÔSå´qUdêd;l§‘í4²& Ó¸swN#½ékÆUùU¡,긢+ê©¢&*ꚢºyˆfZ IZŒ«vJ‡¡Ýi´;v§Ñî4ñ˜ÆÓ¸sýM?6®†Oêu/Q»õ'QCu Á;¨nú¹qÝjÕÎÈvÙî Û®`ÇŠxãzï/²ßúÛI4®ŽÊTuýP›õõP#uîPËŒãz¼®‘í²ÝA¶;ÈvÙî0 ìà°ãz*í†zi¨y†ºe¨=†Jª™‰ºQTWßguÎÞA»;hwíî Ý´»ƒ¯v¬v_Œigu­P› õ¥P# užP« õ–ÀW;V¶?”¢#ðó~ÞA¶;ÈvÙî ÛŠêËWV¶o¸t„üŒlwÔÏA½Ô¬Aݬl?î§ÆV¶ïÿi™ñ@"¤i@àJ+Û¥èuIP[õAPãu:Pk•žtð—ºXí†Þ§ÃÎ¥Àyà"P”W€fÀjwìXG¨Å€z ¨‰µ…‹)&\LõàbÊ«µ†•íätÄ-  ¸´÷à0XÙ~䌎P5ÞP§ µÖP/ 5ÏP}u£xa\ý¬Žx g€€J%ÀB þ[±¾õ*¥Ÿ $×/9dª¤½jØ«h½ªÔ«,½êЫ"®ªèS zØg\¿üu–E@1@<†qçpPj\¿ªO ¿ÂaJDS´¯p˜"ÐÃT}&Té+V[„ëÆõë3:¢¨n7F€PPK¯êv…ÃmÆõÙ¯éõPPÓuIP[õAPãu:P‹.ãúíÿGG€nÙ÷¡˜GzÃ/ë÷rU“\ Jä*=®Zã*.N+‡ ]˶z´ ^›?a\ø£2Ñî<ÚG»óhwíÎg8lÞc\ÿõËÚíΣÝy´;vçÑî<ÕºçUßÊö¿ÒÎøyÙÎ#Ûyd;lç‘í<›¿b\ò[ÚYµóU,_ÕñU_õïUð^•æŒëëùÚ?Ïãçyüôèþ‡æ×?þŠvV uÕLW‘tUEWtÕ=WÁñsƵ¿£ñó!~>Äχøùéáð€Ã«Œë_þ/í¬ÂäªD®Òãª5®ââZÚHÉCÕò¶sÄÿNÐ8ûgâìCœ}ÈqÈqˆÃ×ÿÿ)í¬šß*ò­ªÞ*ã­ºÝÔî­—›úMœÓÎøù?¾d«hÖP×È_Àeâê~Uõ¸Ý@¼‰Küy™ªŸ­‚Ùª­’ت­¢×ª@eâ2~D;g È €ó@‘‰ó~Qû©HµªR« µêNÓ!¨³©ôóW”§/e@9p¸4U&îl¦öSuh•ƒVýg|V…g•t¦–r}‹‰»ð×ÚùÐÜÚû@0<2qå_ÖÎÔ\®§Èr=U•ë)£\OÝäz9[•‘uáÏM\å÷uÄ €³'qöd €Ÿ']€õnÿçT_M&š¸Æ™ªU¬âĪF¬òê7¬êXžÈ_ªÝë5q­ÿ]‡áìIœ=‰³'‹€b 8T¥&®½ZG¨Ð¯*ûª”¯j÷ªX¯ªó€I¸¾nâ:ÞÒÕ@-p¸ ŸI¢0‰;';6÷ä=:BÕ°UþZõ®UàZ­UÂw¾-çt™¸îº  “¸óí(÷~ÞD/z›rÐoG›¸—Ÿ’‰wߦ׿B*z;°zþym¥NôÛxímmMpñÛ)~~; ÀÙogüŸ’î'f«*?ย¾//ÿEù§. ¨þ{ü‹"¢"‚ þA”Í$MNwcºéIWÏ⤻vÓ4tÙtÚE“³iÒEsÒÛäl:™t’ɬn:'inf’Y4mWmÒ÷s»ùæBÌ+<ŸßE|ÏóÜŸxÅ·Áàe õàiέÁ3œ¯øàÉ̓—}ð¼æÁk?¸!ƒ( }@1˜öÇ@pxFP îÇ`Ú(ƒ‘È æ~À3þÑàæç&£æ§%3ܨÁm0ÐÜ ²Á 1pܼÁãÍ‚óÁ]1ÀÜÁÁý1`Ü$Áå°u±ö£ùuö¬öåü/¿)³¯‰Ü3ÚÁ3ðÜ=äÁ-4ÜGîÁsŇÙÜÓćÍû¨ó½ Îcý;Ïûï,èlè¬è,èlè¬"èì(è,/èl5è¬;èìAè,HèlNè¬TèìZè,aèlgè¬mèìsè,zèl€è¬†èìŒè,“èl™è¬Ÿèì¥è,¬èl²è¬¸èì¾è,ÅèlËè¬Ñèì×è,Þèläè¬êèìðè,÷èlýè¬éì é,élé¬éì"é,)él/é¬5éì;é,BélHéìOé,Vél\é¬béìhé,oélué¬{éìé,ˆélŽé¬”éìšé,¡él§é¬­éì³é,ºélÀ鬯éìÌé,Óélèé¬ß9:lþéöÏ(×kéÈ|uCnÊçrKnËrG¾”¯äkùFîÊ·rO¾“ïå¾ÐŸ|ù‰þD¢?ÑŸèOô'úý‰þD¢?ÑŸèOô'úý‰þD¢?ÑŸèOô'úý‰þD¢?ÑŸèOô'úý‰þD¢?ÑŸèOô'úý‰þD¢?ÑŸèOô'úý‰þD¢?ÑŸèOô'úý‰þD¢?ÑŸèOô'úý‰þD¢?ÑŸèOô'úý‰þD¢?ÑŸèO×äS¹.†ab>Ažfó답?úí¬us±ö?Ÿ¯èOô'úý‰þD¢?ÑŸèOô'úýiSÿ˜Ãñcwò <$[äayD•5Y—­²!Ûd»ì²KvËyLöÊãò„ì“ýr@Ê!yRž’Ãò´‘£ÒÉ19.½œ“rJž‘gå´<'g䬜“çåyQÎËKrA.ÊËòм*¯Éë²”7äMyKÞ–wä]¹$ïÉûrY>+ò¡\•äcùD®É§r]>“rS>—[r[¾;ò¥|%_Ë7òÌæ·kú?³ïÝÅÚßýj¾ú^î ýâç ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ô ýB¿Ð/ôË]ùVîÉŒ<›ß[¬ýÕ?ÎÜó‰í‹µòýƒã;æ,äAyH¶ÈÃòˆ<*k².[eC¶ÉvÙ!;e—ì–=ò˜ì•Çå Ù'û倔Cò¤<%‡åi9"G¥“cr\z9!'å”<#ÏÊiyNÎÈY9'ÏË ò¢œ——ä‚\”—åyU^“×e)oÈ›ò–¼-ïÈ»rIÞ“÷åC™Gàþbí~1¿Ø—k¿¼:_]•äcùD®É§r]>“rS>—[r[¾;ò¥|%_Ë7rW¾•{ò|/÷es6Ž¿Œ@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?иìe±ö³÷æWò­ÅÚo~<_™ƒ`‚9—å¹"Æ"Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðôý@?Ðô¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯¸ë¬ÿÎbí×{ç×åÂbí:_™ƒjª9¨æ šƒjª?ª9¨þ¨Æ¢Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿Ò¯ô+ýJ¿nê÷g…<(ÉyX‘GeMÖe«lÈ6Ù.;d§ì’ݲG“½ò¸•ëò™Ü›ò¹Ü’Ûò…Ü‘/å+ùZ¾‘»ò­Ü“ïä{¹/ôõ‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~Âfý ‹õµŸÌ¿ÁgëýžùÊ$sÌA2ɤóò’\c‘è'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿè'ú‰~¢Ÿèû¦{ï¶é;ŒíGúNdû‘¾cÙ~¤?ÒwšÛôÈö#}DzýHßÙl?Òw@ÛôÒö#}Gµ½sÝÞÙl?ÎúÏ-Öý×ü˘¿÷ºc±þÊßÎ?4 ŽoûÑ08ÃíGÃà · ƒÓÜÞÑo?¹ýhœæö£ap¤Û†Á¹n?𠇻ýhœðöŽƒûÑ8×íG#àp·€Þ~4ŽyûÑ8ëíG#àÀ·w:ÜFÀYo?¾ýhœúö£pôÛFÀùo?‡Àýhœ÷ÎŽûÑ8îG#à$¸€ãà~4΄ûÑ8îG#àt¸€#âÞ¡r?§Ãýh÷£pNÜVÄ-çÕ=vM/ççªÍ‡óçR}»wi…âÒBݥʼnËyU‡ã¸åü,þùYócæýeå.ç98¸X?÷¯óWÞ±Øø-ó•M‰K{s—ö#.mË]ÚŠ¸¿œаضëç›Ù÷'›9|m3'îmæìïoæâÞÍ,Ûf.ùáU:±²žoe=ßÊÒÅ•U¤+;×V®ìu[Y;ºòЕe£+'g«Kâ‘ +›[Ù8ºú@ì]YÏ·²Ame{âÊ›oVv&®|wzå-Ò«ëây‘«b+âÊÇêW–ˆ®¼ÇkeßÊùåÊÂЕ…ˆ+kBWÞó´²teùáêžø_ÕÕ÷bÑáÊØæÍßåmA;‘Ín6»Ùìf³›Ín6»Ùìf³›Ín6»Ùìf³›Ín¶T$ãÉx2žŒ'ãÉ&6“Éd2™L&“É&6›Ølb³‰Í&6Ñll³ÍF4ÑlD³ÍF4›Îl:³é̦3[Í™mkÎÞ ™}”$[Ù½#%[¾™­¤ÍVnf Îmf7D6ò|ŸÁgð|ŸÁgð|ŸÁgð|ŸÁgð|ŸÁgð|ŸÁgð|ŸÁgð|ŸÁgð|ŸÁgð|ŸÁgð|ŸÁçMø“6áä;'m9i³ÈÉÉyX‘GeMÖe«lÈ6Ù.;d§ì’ݲG“½ò¸‘kò©\—Ïä†Ü”Ïå–Ü–/äŽ|)_É×òÜ•oåž|'ßË}7áÿÀç5NFð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ÁGð|ï¿jÉ[1O6ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |ßÀ7ð |Û„?ueþÏ=ÞèÔ•…<(ÉyX‘GeMÖe«lÈ6Ù.;d§ì’ݲG“½ò¸>>", ;; as the ">" is converted to "\textgreater{}" by Sphinx's LaTeX ;; escaping. ;; To fix this, Sphinx does **not** use texindy, and does not even ;; load the xindy latex.xdy base module. ;(require "latex.xdy") ;; Rather it incorporates some suitable extracts from latex.xdy and ;; tex.xdy with additional Sphinx contributed rules. ;; But, this means for pdflatex and Latin scripts that the xindy file ;; tex/inputenc/uf8.xdy is not usable because it refers to the macro ;; \IeC only sporadically, and as tex.xdy is not loaded, a rule such as ;; (merge-rule "\'e" "é" :string) ;; does not work, it must be ;; (merge-rule "\IeC {\'e}" "é" :string) ;; So Sphinx contributes LICRlatin2utf8.xdy to mitigate that problem. ;;;;;;;; extracts from tex.xdy (discarding most original comments): ;;; ;;; TeX conventions ;;; ;; Discard leading and trailing white space. Collapse multiple white ;; space characters to blank. (merge-rule "^ +" "" :eregexp) (merge-rule " +$" "" :eregexp) (merge-rule " +" " " :eregexp) ;; Handle TeX markup (merge-rule "\\([{}$%&#])" "\1" :eregexp) ;;;;;;;; end of extracts from xindy's tex.xdy ;;;;;;;; extracts from latex.xdy: ;; Standard location classes: arabic and roman numbers, and alphabets. (define-location-class "arabic-page-numbers" ("arabic-numbers")) (define-location-class "roman-page-numbers" ("roman-numbers-lowercase")) (define-location-class "Roman-page-numbers" ("roman-numbers-uppercase")) (define-location-class "alpha-page-numbers" ("alpha")) (define-location-class "Alpha-page-numbers" ("ALPHA")) ;; Output Markup (markup-letter-group-list :sep "~n~n \indexspace~n") (markup-indexentry :open "~n \item " :depth 0) (markup-indexentry :open "~n \subitem " :depth 1) (markup-indexentry :open "~n \subsubitem " :depth 2) (markup-locclass-list :open ", " :sep ", ") (markup-locref-list :sep ", ") ;;;;;;;; end of extracts from latex.xdy ;; The LaTeX \index command turns \ into normal character so the TeX macros ;; written to .idx files are not followed by a blank. This is different ;; from non-ascii letters which end up (with pdflatex) as \IeC macros in .idx ;; file, with a blank space after \IeC ;; Details of the syntax are explained at ;; http://xindy.sourceforge.net/doc/manual-3.html ;; In absence of :string, "xindy uses an auto-detection mechanism to decide, ;; if the pattern is a regular expression or not". But it is not obvious to ;; guess, for example "\\_" is not detected as RE but "\\P\{\}" is, so for ;; being sure we apply the :string switch everywhere and do not use \\ etc... ;; Go back from sphinx.util.texescape TeX macros to UTF-8 (merge-rule "\sphinxleftcurlybrace{}" "{" :string) (merge-rule "\sphinxrightcurlybrace{}" "}" :string) (merge-rule "\_" "_" :string) (merge-rule "{[}" "[" :string) (merge-rule "{]}" "]" :string) (merge-rule "\textbackslash{}" "\" :string) ; " for Emacs syntax highlighting (merge-rule "\textasciitilde{}" "~~" :string); the ~~ escape is needed here (merge-rule "\textasciicircum{}" "^" :string) (merge-rule "\sphinxhyphen{}" "-" :string) (merge-rule "\textquotesingle{}" "'" :string) (merge-rule "\textasciigrave{}" "`" :string) (merge-rule "\textless{}" "<" :string) (merge-rule "\textgreater{}" ">" :string) (merge-rule "\P{}" "¶" :string) (merge-rule "\S{}" "§" :string) (merge-rule "\texteuro{}" "€" :string) (merge-rule "\(\infty\)" "∞" :string) (merge-rule "\(\pm\)" "±" :string) (merge-rule "\(\rightarrow\)" "→" :string) (merge-rule "\(\checkmark\)" "✓" :string) (merge-rule "\textendash{}" "–" :string) (merge-rule "\textbar{}" "|" :string) (merge-rule "\(\sp{\text{0}}\)" "â°" :string) (merge-rule "\(\sp{\text{1}}\)" "¹" :string) (merge-rule "\(\sp{\text{2}}\)" "²" :string) (merge-rule "\(\sp{\text{3}}\)" "³" :string) (merge-rule "\(\sp{\text{4}}\)" "â´" :string) (merge-rule "\(\sp{\text{5}}\)" "âµ" :string) (merge-rule "\(\sp{\text{6}}\)" "â¶" :string) (merge-rule "\(\sp{\text{7}}\)" "â·" :string) (merge-rule "\(\sp{\text{8}}\)" "â¸" :string) (merge-rule "\(\sp{\text{9}}\)" "â¹" :string) (merge-rule "\(\sb{\text{0}}\)" "â‚€" :string) (merge-rule "\(\sb{\text{1}}\)" "â‚" :string) (merge-rule "\(\sb{\text{2}}\)" "â‚‚" :string) (merge-rule "\(\sb{\text{3}}\)" "₃" :string) (merge-rule "\(\sb{\text{4}}\)" "â‚„" :string) (merge-rule "\(\sb{\text{5}}\)" "â‚…" :string) (merge-rule "\(\sb{\text{6}}\)" "₆" :string) (merge-rule "\(\sb{\text{7}}\)" "₇" :string) (merge-rule "\(\sb{\text{8}}\)" "₈" :string) (merge-rule "\(\sb{\text{9}}\)" "₉" :string) (merge-rule "\IeC {\textalpha }" "α" :string) (merge-rule "\IeC {\textbeta }" "β" :string) (merge-rule "\IeC {\textgamma }" "γ" :string) (merge-rule "\IeC {\textdelta }" "δ" :string) (merge-rule "\IeC {\textepsilon }" "ε" :string) (merge-rule "\IeC {\textzeta }" "ζ" :string) (merge-rule "\IeC {\texteta }" "η" :string) (merge-rule "\IeC {\texttheta }" "θ" :string) (merge-rule "\IeC {\textiota }" "ι" :string) (merge-rule "\IeC {\textkappa }" "κ" :string) (merge-rule "\IeC {\textlambda }" "λ" :string) (merge-rule "\IeC {\textmu }" "μ" :string) (merge-rule "\IeC {\textnu }" "ν" :string) (merge-rule "\IeC {\textxi }" "ξ" :string) (merge-rule "\IeC {\textomicron }" "ο" :string) (merge-rule "\IeC {\textpi }" "Ï€" :string) (merge-rule "\IeC {\textrho }" "Ï" :string) (merge-rule "\IeC {\textsigma }" "σ" :string) (merge-rule "\IeC {\texttau }" "Ï„" :string) (merge-rule "\IeC {\textupsilon }" "Ï…" :string) (merge-rule "\IeC {\textphi }" "φ" :string) (merge-rule "\IeC {\textchi }" "χ" :string) (merge-rule "\IeC {\textpsi }" "ψ" :string) (merge-rule "\IeC {\textomega }" "ω" :string) (merge-rule "\IeC {\textAlpha }" "Α" :string) (merge-rule "\IeC {\textBeta }" "Î’" :string) (merge-rule "\IeC {\textGamma }" "Γ" :string) (merge-rule "\IeC {\textDelta }" "Δ" :string) (merge-rule "\IeC {\textEpsilon }" "Ε" :string) (merge-rule "\IeC {\textZeta }" "Ζ" :string) (merge-rule "\IeC {\textEta }" "Η" :string) (merge-rule "\IeC {\textTheta }" "Θ" :string) (merge-rule "\IeC {\textIota }" "Ι" :string) (merge-rule "\IeC {\textKappa }" "Κ" :string) (merge-rule "\IeC {\textLambda }" "Λ" :string) (merge-rule "\IeC {\textMu }" "Μ" :string) (merge-rule "\IeC {\textNu }" "Î" :string) (merge-rule "\IeC {\textTheta }" "Θ" :string) (merge-rule "\IeC {\textIota }" "Ι" :string) (merge-rule "\IeC {\textKappa }" "Κ" :string) (merge-rule "\IeC {\textLambda }" "Λ" :string) (merge-rule "\IeC {\textMu }" "Μ" :string) (merge-rule "\IeC {\textNu }" "Î" :string) (merge-rule "\IeC {\textXi }" "Ξ" :string) (merge-rule "\IeC {\textOmicron }" "Ο" :string) (merge-rule "\IeC {\textPi }" "Π" :string) (merge-rule "\IeC {\textRho }" "Ρ" :string) (merge-rule "\IeC {\textSigma }" "Σ" :string) (merge-rule "\IeC {\textTau }" "Τ" :string) (merge-rule "\IeC {\textUpsilon }" "Î¥" :string) (merge-rule "\IeC {\textPhi }" "Φ" :string) (merge-rule "\IeC {\textChi }" "Χ" :string) (merge-rule "\IeC {\textPsi }" "Ψ" :string) (merge-rule "\IeC {\textOmega }" "Ω" :string) (merge-rule "\IeC {\textohm }" "Ω" :string) ;; This xindy module provides some basic support for "see" (require "makeindex.xdy") ;; This creates one-letter headings and works fine with utf-8 letters. ;; For Cyrillic with pdflatex works thanks to LICRcyr2utf8.xdy (require "latin-lettergroups.xdy") ;; currently we don't (know how to easily) separate "Numbers" from ;; "Symbols" with xindy as is the case with makeindex. (markup-index :open "\begin{sphinxtheindex} \let\lettergroup\sphinxstyleindexlettergroup \let\lettergroupDefault\sphinxstyleindexlettergroupDefault \let\spxpagem\sphinxstyleindexpagemain \let\spxentry\sphinxstyleindexentry \let\spxextra\sphinxstyleindexextra " :close " \end{sphinxtheindex} " :tree) krb5-1.22.1/doc/pdf/sphinxlatexcontainers.sty0000664000175000017500000000160514577122106021065 0ustar ghudsonghudson%% CONTAINER DIRECTIVES % % change this info string if making any custom modification \ProvidesFile{sphinxlatexcontainers.sty}[2021/05/03 containers] % The purpose of this file is to provide a dummy environment sphinxclass which % will be inserted for each class in each container directive. The class name % will be passed as the argument to the environment. % % For a class foo, the user can define customised handling of that class by % defining the sphinxclassfoo LaTeX environment. \newenvironment{sphinxuseclass}[1]{% \def\sphinxClassFunctionName{sphinxclass#1}% \ltx@ifundefined{\sphinxClassFunctionName}% {}% undefined so do nothing {\expandafter\begin\expandafter{\sphinxClassFunctionName}}% }{% \ltx@ifundefined{\sphinxClassFunctionName}% {}% we did nothing so we keep doing nothing {\expandafter\end\expandafter{\sphinxClassFunctionName}}% }% krb5-1.22.1/doc/pdf/sphinxlatexobjects.sty0000664000175000017500000003402214577122106020350 0ustar ghudsonghudson%% MODULE RELEASE DATA AND OBJECT DESCRIPTIONS % % change this info string if making any custom modification \ProvidesFile{sphinxlatexobjects.sty}[2023/07/23 documentation environments] % Provides support for this output mark-up from Sphinx latex writer: % % - environments % % - fulllineitems % - productionlist % - optionlist % - DUlineblock (also "lineblock") % % - macros % % - \DUrole % - various legacy support macros related to author and release % data of documented objects and modules. % \moduleauthor{name}{email} \newcommand{\moduleauthor}[2]{} % \sectionauthor{name}{email} \newcommand{\sectionauthor}[2]{} % Allow the release number to be specified independently of the % \date{}. This allows the date to reflect the document's date and % release to specify the release that is documented. % \newcommand{\py@release}{\releasename\space\version} \newcommand{\version}{}% part of \py@release, used by title page and headers % \releaseinfo is used on titlepage (sphinxmanual.cls, sphinxhowto.cls) \newcommand{\releaseinfo}{} \newcommand{\setreleaseinfo}[1]{\renewcommand{\releaseinfo}{#1}} % this is inserted via template and #1=release config variable \newcommand{\release}[1]{\renewcommand{\version}{#1}} % this is defined by template to 'releasename' latex_elements key \newcommand{\releasename}{} % Fix issue in case release and releasename deliberately left blank \newcommand{\sphinxheadercomma}{, }% used in fancyhdr header definition \newcommand{\sphinxifemptyorblank}[1]{% % test after one expansion of macro #1 if contents is empty or spaces \if&\expandafter\@firstofone\detokenize\expandafter{#1}&% \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}% \AtBeginDocument {% \sphinxifemptyorblank{\releasename} {\sphinxifemptyorblank{\version}{\let\sphinxheadercomma\empty}{}} {}% }% % Allow specification of the author's address separately from the % author's name. This can be used to format them differently, which % is a good thing. % \newcommand{\py@authoraddress}{} \newcommand{\authoraddress}[1]{\renewcommand{\py@authoraddress}{#1}} % {fulllineitems} is the main environment for object descriptions. % % With 4.0.0 \pysigline (and \pysiglinewithargsret), used in a fulllineitems % environment the #1 will already be of the width which is computed here, i.e. % the available width on line, so the \makebox becomes a bit superfluous \newcommand{\py@itemnewline}[1]{% macro used as \makelabel in fulllineitems % Memo: this presupposes \itemindent is 0pt \kern\labelsep % because \@labels core latex box does \hskip-\labelsep \makebox[\dimexpr\linewidth+\labelwidth\relax][l]{#1}% \kern-\labelsep % because at end of \@labels box there is \hskip\labelsep } \newenvironment{fulllineitems}{% \begin{list}{}{\labelwidth \leftmargin \rightmargin \z@ \topsep -\parskip \partopsep \parskip \itemsep -\parsep \let\makelabel=\py@itemnewline}% }{\end{list}} % Signatures, possibly multi-line % % For legacy reasons Sphinx uses LaTeX \list and \item's for signatures % This is delicate: % - the actual item label is not typeset immediately by \item but later as part % of the \everypar which will be triggered by either next paragraph or a manual % \leavevmode, or if nothing in-between by the next \item, % - \begingroup \item[foo] \endgroup leads to errors, % - vertical space depends on \parskip and \itemsep values in somewhat % subtle manners. % % Since the 2022/01/13 version things are simpler as \parskip is simply set % to zero during execution of \pysigline/\pysiglinewithargsret % % Parameter for separation via \itemsep of multiple signatures with common desc \newlength\sphinxsignaturesep \setlength\sphinxsignaturesep{\smallskipamount} % latex.py outputs mark-up like this: % \pysigstartsignatures \pysigstopsignatures \newcommand{\pysigstartsignatures}{% % store current \parskip and \itemsep \edef\pysig@restore@itemsep@and@parskip{% \itemsep\the\itemsep\relax \parskip\the\parskip\relax }% % set them to control the spacing between signatures sharing common desc \parskip\z@skip \itemsep\sphinxsignaturesep } \newcommand{\pysigstopsignatures}{% % 1) encourage a pagebreak in an attempt to try to avoid last % signature ending up separated from description (due to voodoo next) \penalty-100 % 2) some voodoo to separate last signature from description in a manner % robust with respect to the latter being itself a LaTeX list object \leavevmode\par\kern-\baselineskip\item[\strut] % \leavevmode % it is important \leavevmode was issued before the \parskip reset, and % it is also needed for the case of an object desc itself a LaTeX \list % now restore \itemsep and \parskip \pysig@restore@itemsep@and@parskip } % Each signature is rendered as NAME[TPLIST](ARGLIST) where the % size of is parametrized by \sphinxsignaturelistskip (0pt by default). \newlength\sphinxsignaturelistskip \setlength\sphinxsignaturelistskip{0pt} \newcommand{\pysigtypelistopen}{\hskip\sphinxsignaturelistskip\sphinxcode{[}} \newcommand{\pysigtypelistclose}{\sphinxcode{]}} \newcommand{\pysigarglistopen}{\hskip\sphinxsignaturelistskip\sphinxcode{(}} \newcommand{\pysigarglistclose}{\sphinxcode{)}} % % Use a \parbox to accommodate long argument list in signatures % LaTeX did not imagine that an \item label could need multi-line rendering \newlength{\py@argswidth} \newcommand{\py@sigparams}[2]{% % The \py@argswidth has been computed in \pysiglinewithargsret to make the % argument list use full available width \parbox[t]{\py@argswidth}{\raggedright #1\pysigarglistclose#2\strut}% % final strut is to help get correct vertical separation } \newcommand{\py@sigparamswithtypelist}[3]{% % similar to \py@sigparams but with different delimiters and an additional % type parameters list given as #1, the argument list as #2 and the return % annotation as #3 \parbox[t]{\py@argswidth}{% \raggedright #1\pysigtypelistclose% \pysigarglistopen#2\pysigarglistclose% #3\strut}% } \newcommand{\pysigline}[1]{% % as \py@argswidth is available, we use it but no "args" here % the \relax\relax is because \py@argswidth is a "skip" variable % this will make the label occupy the full available linewidth \py@argswidth=\dimexpr\linewidth+\labelwidth\relax\relax \item[{\parbox[t]{\py@argswidth}{\raggedright #1\strut}}] \pysigadjustitemsep } \newcommand{\pysiglinewithargsret}[3]{% % as #1 may contain a footnote using \label we need to make \label % a no-op here to avoid LaTeX complaining about duplicates \let\spx@label\label\let\label\@gobble \settowidth{\py@argswidth}{#1\pysigarglistopen}% \let\label\spx@label \py@argswidth=\dimexpr\linewidth+\labelwidth-\py@argswidth\relax\relax \item[{#1\pysigarglistopen\py@sigparams{#2}{#3}\strut}] \pysigadjustitemsep } \newcommand{\pysiglinewithargsretwithtypelist}[4]{ % #1 = name, #2 = typelist, #3 = arglist, #4 = retann \let\spx@label\label\let\label\@gobble \settowidth{\py@argswidth}{#1\pysigtypelistopen}% \let\label\spx@label \py@argswidth=\dimexpr\linewidth+\labelwidth-\py@argswidth\relax\relax \item[{#1\pysigtypelistopen\py@sigparamswithtypelist{#2}{#3}{#4}\strut}] \pysigadjustitemsep } \def\sphinxoptionalextraspace{0.5mm} \newcommand{\pysigwithonelineperarg}[3]{% % render each argument on its own line \item[#1\pysigarglistopen\strut] \leavevmode\par\nopagebreak % this relies on \pysigstartsignatures having set \parskip to zero \begingroup \let\sphinxparamcomma\sphinxparamcommaoneperline \def\sphinxoptionalhook{\ifvmode\else\kern\sphinxoptionalextraspace\relax\fi}% % The very first \sphinxparam should not emit a \par hence a complication % with a group and global definition here as it may occur in a \sphinxoptional \global\let\spx@sphinxparam\sphinxparam \gdef\sphinxparam{\gdef\sphinxparam{\par\spx@sphinxparam}\spx@sphinxparam}% #2\par \endgroup \global\let\sphinxparam\spx@sphinxparam % fulllineitems sets \labelwidth to be like \leftmargin \nopagebreak\noindent\kern-\labelwidth\pysigarglistclose{#3} \pysigadjustitemsep } \newcommand{\pysigwithonelineperargwithonelinepertparg}[4]{ % #1 = name, #2 = typelist, #3 = arglist, #4 = retann % render each type parameter and argument on its own line \item[#1\pysigtypelistopen\strut] \leavevmode\par\nopagebreak \begingroup \let\sphinxparamcomma\sphinxparamcommaoneperline % \sphinxtypeparam is treated similarly to \sphinxparam but since % \sphinxoptional is not accepted in a type parameters list, we do % not need the hook or the global definition \let\spx@sphinxtypeparam\sphinxtypeparam \def\sphinxtypeparam{\def\sphinxtypeparam{\par\spx@sphinxtypeparam}\spx@sphinxtypeparam}% #2\par \endgroup \nopagebreak\noindent\kern-\labelwidth\pysigtypelistclose% % render the rest of the signature like in \pysigwithonelineperarg \pysigarglistopen\strut\par\nopagebreak \begingroup \let\sphinxparamcomma\sphinxparamcommaoneperline \def\sphinxoptionalhook{\ifvmode\else\kern\sphinxoptionalextraspace\relax\fi}% \global\let\spx@sphinxparam\sphinxparam \gdef\sphinxparam{\gdef\sphinxparam{\par\spx@sphinxparam}\spx@sphinxparam}% #3\par \endgroup \global\let\sphinxparam\spx@sphinxparam \nopagebreak\noindent\kern-\labelwidth\pysigarglistclose{#4} \pysigadjustitemsep } \newcommand{\pysiglinewithargsretwithonelinepertparg}[4]{ % #1 = name, #2 = typelist, #3 = arglist, #4 = retann % render each type parameter on its own line but the arguments list inline \item[#1\pysigtypelistopen\strut] \leavevmode\par\nopagebreak \begingroup \let\sphinxparamcomma\sphinxparamcommaoneperline % \sphinxtypeparam is treated similarly to \sphinxparam but since % \sphinxoptional is not accepted in a type parameters list, we do % not need the hook or the global definition \let\spx@sphinxtypeparam\sphinxtypeparam \def\sphinxtypeparam{\def\sphinxtypeparam{\par\spx@sphinxtypeparam}\spx@sphinxtypeparam}% #2\par \endgroup \nopagebreak\noindent\kern-\labelwidth\pysigtypelistclose% % render the arguments list on one line \pysigarglistopen#3\pysigarglistclose#4\strut \pysigadjustitemsep } \newcommand{\pysigwithonelineperargwithtypelist}[4]{ % #1 = name, #2 = typelist, #3 = arglist, #4 = retann % render the type parameters list on one line, but each argument is rendered on its own line \let\spx@label\label\let\label\@gobble \settowidth{\py@argswidth}{#1\pysigtypelistopen}% \let\label\spx@label \py@argswidth=\dimexpr\linewidth+\labelwidth-\py@argswidth\relax\relax \item[{#1\pysigtypelistopen\parbox[t]{\py@argswidth}{% \raggedright #2\pysigtypelistclose\pysigarglistopen\strut}\strut}] % render the rest of the signature like in \pysigwithonelineperarg \begingroup \let\sphinxparamcomma\sphinxparamcommaoneperline \def\sphinxoptionalhook{\ifvmode\else\kern\sphinxoptionalextraspace\relax\fi}% \global\let\spx@sphinxparam\sphinxparam \gdef\sphinxparam{\gdef\sphinxparam{\par\spx@sphinxparam}\spx@sphinxparam}% #3\par \endgroup \global\let\sphinxparam\spx@sphinxparam \nopagebreak\noindent\kern-\labelwidth\pysigarglistclose{#4} \pysigadjustitemsep } \newcommand{\pysigadjustitemsep}{% % adjust \itemsep to control the separation with the next signature % sharing common description \ifsphinxsigismultiline % inside a multiline signature, no extra vertical spacing % ("multiline" here does not refer to possibly long % list of arguments, but to a cpp domain feature) \itemsep\z@skip \else \itemsep\sphinxsignaturesep \fi } \newif\ifsphinxsigismultiline \newcommand{\pysigstartmultiline}{\sphinxsigismultilinetrue}% \newcommand{\pysigstopmultiline}{\sphinxsigismultilinefalse\itemsep\sphinxsignaturesep}% % Production lists % \newenvironment{productionlist}{% % \def\sphinxoptional##1{{\Large[}##1{\Large]}} \def\production##1##2{\\\sphinxcode{\sphinxupquote{##1}}&::=&\sphinxcode{\sphinxupquote{##2}}}% \def\productioncont##1{\\& &\sphinxcode{\sphinxupquote{##1}}}% \parindent=2em \indent \setlength{\LTpre}{0pt}% \setlength{\LTpost}{0pt}% \begin{longtable}[l]{lcl} }{% \end{longtable} } % Definition lists; requested by AMK for HOWTO documents. Probably useful % elsewhere as well, so keep in in the general style support. % \newenvironment{definitions}{% \begin{description}% \def\term##1{\item[{##1}]\mbox{}\\*[0mm]}% }{% \end{description}% } %% FROM DOCTUTILS LATEX WRITER % % The following is stuff copied from docutils' latex writer. % \newcommand{\optionlistlabel}[1]{\normalfont\bfseries #1 \hfill}% \bf deprecated \newenvironment{optionlist}[1] {\begin{list}{} {\setlength{\labelwidth}{#1}% \setlength{\rightmargin}{1cm}% \setlength{\leftmargin}{\rightmargin}% \addtolength{\leftmargin}{\labelwidth}% \addtolength{\leftmargin}{\labelsep}% \renewcommand{\makelabel}{\optionlistlabel}}% }{\end{list}} \newlength{\lineblockindentation} \setlength{\lineblockindentation}{2.5em} \newenvironment{lineblock}[1] {\begin{list}{} {\setlength{\partopsep}{\parskip}% \addtolength{\partopsep}{\baselineskip}% \topsep0pt\itemsep0.15\baselineskip\parsep0pt \leftmargin#1\relax}% \raggedright} {\end{list}} % From docutils.writers.latex2e % inline markup (custom roles) % \DUrole{#1}{#2} tries \DUrole#1{#2} \providecommand*{\DUrole}[2]{% \ifcsname DUrole\detokenize{#1}\endcsname \csname DUrole\detokenize{#1}\endcsname{#2}% \else% backwards compatibility: try \docutilsrole#1{#2} \ifcsname docutilsrole\detokenize{#1}\endcsname \csname docutilsrole\detokenize{#1}\endcsname{#2}% \else #2% \fi \fi } \providecommand*{\DUprovidelength}[2]{% \ifdefined#1\else\newlength{#1}\setlength{#1}{#2}\fi } \DUprovidelength{\DUlineblockindent}{2.5em} \ifdefined\DUlineblock\else \newenvironment{DUlineblock}[1]{% \list{}{\setlength{\partopsep}{\parskip}% \addtolength{\partopsep}{\baselineskip}% \setlength{\topsep}{0pt}% \setlength{\itemsep}{0.15\baselineskip}% \setlength{\parsep}{0pt}% \setlength{\leftmargin}{#1}}% \raggedright } {\endlist} \fi \endinput krb5-1.22.1/doc/pdf/sphinxlatexshadowbox.sty0000664000175000017500000001171214577122106020716 0ustar ghudsonghudson%% TOPIC AND CONTENTS BOXES % % change this info string if making any custom modification \ProvidesFile{sphinxlatexshadowbox.sty}[2023/03/19 sphinxShadowBox] % Provides support for this output mark-up from Sphinx latex writer: % % - sphinxShadowBox (environment) % % Dependencies (they do not need to be defined at time of loading): % % - of course the various colour and dimension options handled via sphinx.sty % - dimension register \spx@image@maxheight from sphinxlatexgraphics.sty % - \savenotes/\spewnotes from sphinxpackagefootnote % - \ifspx@inframed defined in sphinx.sty % % Requires: \RequirePackage{framed} \RequirePackage{sphinxpackageboxes} % At 5.1.0 the code formerly here in a definition of \spx@ShadowFBox has been % refactored to hand over to a more powerful \spx@boxes@fcolorbox provided by % file sphinxpackageboxes.sty, it can draw rounded corners and add a background % color. % At 6.2.0, \spx@ShadowFBox is so much simplified that it is now not % separately defined but directly incorporated into the \FrameCommand % definition done by sphinxShadowBox environment below. % Use framed.sty \MakeFramed/\endMakeFramed to allow page breaks for topic % boxes. Originally Sphinx used \shadowbox from fancybox.sty but it did not % allow pagebreaks (which was problematic for "contents" directive if there % are many subsections). % % Docutils does not allow topic to be nested within topics or other body % elements. But the LaTeX code here does allow it: % % - a topic inside another topic would be rendered in a minipage (thus not % allowing pagebreaks). Its external frame would adapt perfectly to % the *current (smaller) width for text*. % % - a topic inside (nested) lists or quote environments would have its frame % take the *full width* of the page, but its text contents on the other hand % would obey exactly the current indentation plus inner separation. This is % in contrast with the framing used for literal blocks, also based, but in a % more sophisticated way on usage of \MakeFramed/\endMakeFramed, and % adjusting to current text indentation. \newenvironment{sphinxShadowBox} {% \spx@boxes@fcolorbox@setup{topic}% % we will use the dimen registers from sphinxpackageboxes.sty which now hold % the values from options related to topic/contents % MEMO: \spx@boxes@fcolorbox creates an \hbox but does not quit vertical % mode; but in context of framed.sty's \FrameCommand TeX is already % in restricted horizontal mode, so no need for a \leavevmode here. \def\FrameCommand {\spx@boxes@fcolorbox}% % 6.2.0 adds support for div.topic_box-decoration-break=slice. % (it is yet undecided if slice style should inhibit a bottom shadow) \ifspx@topic@border@open \def\FirstFrameCommand {\spx@boxes@fcolorbox@setup@openbottom\FrameCommand}% \def\MidFrameCommand {\spx@boxes@fcolorbox@setup@openboth \FrameCommand}% \def\LastFrameCommand {\spx@boxes@fcolorbox@setup@opentop \FrameCommand}% \fi \advance\spx@image@maxheight -\dimexpr\spx@boxes@border@top+\spx@boxes@border@bottom +\spx@boxes@padding@top+\spx@boxes@padding@bottom +\ifdim\spx@boxes@shadow@yoffset<\z@-\fi\spx@boxes@shadow@yoffset +\baselineskip\relax % configure framed.sty not to add extra vertical spacing \ltx@ifundefined{OuterFrameSep}{}{\OuterFrameSep\z@skip}% % the \trivlist will add the vertical spacing on top and bottom which is % typical of center environment as used in Sphinx <= 1.4.1 % the \noindent has the effet of an extra blank line on top, to % imitate closely the layout from Sphinx <= 1.4.1; the \FrameHeightAdjust % will put top part of frame on this baseline. \def\FrameHeightAdjust {\baselineskip}% % use package footnote to handle footnotes \savenotes \trivlist\item\noindent % use a minipage if we are already inside a framed environment \ifspx@inframed\begin{minipage}{\linewidth}\fi \MakeFramed {\spx@inframedtrue % framed.sty puts into "\width" the added width (padding+border widths) % adjust \hsize to what the contents must use \advance\hsize-\width % adjust LaTeX parameters to behave properly in indented/quoted contexts \FrameRestore % typeset the contents as in a minipage (Sphinx <= 1.4.1 used a minipage and % itemize/enumerate are therein typeset more tightly, we want to keep % that). We copy-paste from LaTeX source code but don't do a real minipage. \@pboxswfalse \let\@listdepth\@mplistdepth \@mplistdepth\z@ \@minipagerestore \@setminipage }% \color@begingroup % workaround upstream framed.sty bug \ifspx@topic@withtextcolor \color{sphinxtopicTextColor}% \fi \spx@topic@TeXextras }% {% insert the "endminipage" code \par\unskip \color@endgroup % matches the \color@begingroup \@minipagefalse \endMakeFramed \ifspx@inframed\end{minipage}\fi \endtrivlist % output the stored footnotes \spewnotes } \endinput krb5-1.22.1/doc/pdf/sphinxoptionshyperref.sty0000664000175000017500000000210614577122106021117 0ustar ghudsonghudson%% Bookmarks and hyperlinks % % change this info string if making any custom modification \ProvidesFile{sphinxoptionshyperref.sty}[2021/01/27 hyperref] % to make pdf with correct encoded bookmarks in Japanese % this should precede the hyperref package \ifx\kanjiskip\@undefined % for non-Japanese: make sure bookmarks are ok also with lualatex \PassOptionsToPackage{pdfencoding=unicode}{hyperref} \else \RequirePackage{atbegshi} \ifx\ucs\@undefined \ifnum 42146=\euc"A4A2 \AtBeginShipoutFirst{\special{pdf:tounicode EUC-UCS2}} \else \AtBeginShipoutFirst{\special{pdf:tounicode 90ms-RKSJ-UCS2}} \fi \else \AtBeginShipoutFirst{\special{pdf:tounicode UTF8-UCS2}} \fi \fi \ifx\@jsc@uplatextrue\@undefined\else \PassOptionsToPackage{setpagesize=false}{hyperref} \fi % These options can be overridden inside 'hyperref' key % or by later use of \hypersetup. \PassOptionsToPackage{colorlinks,breaklinks,% linkcolor=InnerLinkColor,filecolor=OuterLinkColor,% menucolor=OuterLinkColor,urlcolor=OuterLinkColor,% citecolor=InnerLinkColor}{hyperref} \endinput krb5-1.22.1/doc/pdf/build.pdf0000664000175000017500000061642215051422770015470 0ustar ghudsonghudson%PDF-1.5 %ÐÔÅØ 1 0 obj << /Length 843 /Filter /FlateDecode >> stream xÚmUMoâ0½çWx•ÚÅNÈW…œ„H¶­ Zí•&¦‹Tàп~3Ú®öz¿™yóœ87?ž×Ûö¯nÝkõâNýehܤü¹=77Uß\®;?:׺vÜ==¨ç¡oÖî¬nËUµêöç;O^uÍû¥u#ëÿ¤Â½í»O ú¨Ûû=Ù˜‰a³?¿ûkLy 6FÑæ/7œö}÷ Ì½ÖÚ–][öH<Si£¦cãݾké¥^Ñ90¡j÷ÍYVôßü¬H^œÎî°êv}0Ÿ«é‹ß<‡ÒrLŸ†Ö ûîͯ_®/Çã»Ck¥ƒÅBµnç«øy·§¦Wý×øæãèTHkÃý›¾u§ã¶qö{sÁ\ë…š×õ"p]ûϞќòº¹KÏÕµÿ u”/‚¹A² )`JbD>`´öØ2ãš™$`¤TY'`”(ZqŠÇÁ¼BJÅŒ )KÒÌŒ%553<Æ,£è(‡hþl™×wBš6„‹0¦Ða™G„+L¤gıè«cŽWÀ c œrn œqœø9çÖÀ–ã°MÜ—8%Ç àŠCMq.â†5„Sâhr›ê›®®AƒáúI‚Öå皎­ú\SåþÈ©¿ÇÀ á]8 é`Y‡7ÑŒ1OÊyeäµñÖzlÃë,d mYĸ”S£SJfß-›1i‰:C&e c4ÎRÆÄÉØˆËÄ$D&™ Ë Æ&+ü¬bLõÉãaÉjÆ çÁbôÍy°üœ£‡+çÁbèÉYB¹ü‘þœõ§Ägý ñYJõYŠYrÖŸb–œõ§x(rÖÁèœõGT“õÌ›ËÁ`F+ƒÙ­L ,C9ô²â?d+þ£¯ÿ¡ÍŠÿÄÿ1£ÿ1—ÿ¡ÓŠÿðÄŠÿ˜×ŠÿT_ü‡~+þCg!þ£o!þƒ_ˆÿàâ?ôâ?åŠÿÄÿ‰/þ?ã«„°øY ñ³â?^ŒBü‡Ÿ¿\–jò‹UPñœŠ{Åð¡âxᇻLöó^U}9pQãóq½÷›Ë0øO}cèÖÇ}¿ïÜõ3tìÈ¢}¿Æ!VOuðÊñË· endstream endobj 101 0 obj << /Length 586 /Filter /FlateDecode >> stream xÚmTËŽâ0¼ç+¼$æÀà$0Š ‰Ã£­ö ‰a#A%áÀ߯«›ÀÌjDÕå²»«ífðãc;ZæÕÁŽÌ«Ÿ¶­®MfGÑÏ}í q•]/¶ìÞ­ÍmÞ¯¶o⣩²­íÄ0ZÇë²è^œx]fçkn{ÕÿE+{*ʧyÄpg6;5’PìŠîìVž¤pH8$hù—mÚ¢*ß„z•R:")󨺠ÊÖß3‰qŸûX”ysO'Hî)-ò"ëî}³‹³‹ÍÛ[ÛÙ˺s á3 4†{´¢p¿YôdšrýØëKæ‘+ˆ™ÇÞ a }ÀõàíÑ« W€‡Œ{ Fvm734…4˜‡¢´A­«»èGÞÿc Ú¤Þ_86 endstream endobj 102 0 obj << /Length 770 /Filter /FlateDecode >> stream xÚmUËn£0ÝóžE¥Î"±y$UÉ6 É¢5Õh¶)8¤"’,ú÷ãc\W³Ýsß/.7?ž·3ÑôozÆï(yѧþ2Ôz¦vÇèæ¦èëËAwçG­ÝŒÒÓ=yúz«ÏäVmŠMמåMW\=jý_Iê÷¶ó*ˆCn_õŸÙÃfö ¯íùÃ&1yØ+ü­‡SÛw÷$¾£”FÙ5ª? ÅS4¿†!ó1ð¾íšá‹¼!r3Ò´õùŠì»>˜Za¼ý<õaÓíûhµ"ó#<‡O›ËÏhþ44zh»wrû°1p{9?4B“4Z¯I£÷Æ‹©çqwÐd>å?ñ¯É»Ü=ûõó¨‰Ã±K«î}:îj=ìºw­(]“UU­#Ý5ßd¦kò¶u¥Ñ¥¥y že¥ÖÑ*†ƒx12+ƒ¹Sx¦æ,öÌÒ09Ì9Ô)5t´J N¦Š'†™™{fSÉ –2Œ¬Rà̼   KÙÀÒV i‰X¤¤†BÆRs>–^ÿÝ ×.¹¢KäCc†2—ÀÜc4‰&WÀ©o"²¦™ÇÖîq¼ð8^zlã p5u%†=c¾K(œq/‡?–xŒQ±Ôcøc™·/€s/G|¶°£•¨•-mõ„¥•鯝P/S8+8èÂÑ 4fÁR§SYZ"?.ì‚0»1Òшŕ[KŽþòÒñ­¾õÃúPKS6Ò×0ÃÔæ—eÈ;Uކ}Z8~S›gÈ;­ _™õÇàg®v»ói;K¹æÊcÄÌ g‡ÝÌ­oZ ÞÜú¦ ú¶ø’'ü êê„LÄá^ î¥àá^Š$ÜK‘†{)²p/Eî¥X„{)–á^ î¥(½ߎ‡¨> stream xÚmVMoÛ8¼ûWhÒCj~H”\HÉrhSÔÁb¯ŽÄd IJ!Û‡üûÕ¼±Ã¢ØƒõøÞ¼!9ÔÝ_?7¾?¼ÄûUe¿âép»øPßgwwÍ¡»ìãpþcûÛÛÓ·ìçxè6ñœÝ×Íã°;™‚‡îýÒÇ[Ôÿ…ø¶Rêd÷ÏñŸ‡§ï›…ˆçÝù}z“³ eÊäõßq<í÷LUJM롯{°<Íæ×JÙüVûu7ôãµ\ö‚â3m²~ׯOòßí§v1yóq:Çýãðz˜-—Ùü×ôòt?„Í—Ùüiìã¸Þ²û‰Ïô¼¹ïµ35[­²>¾Ni¦ž~l÷1›§>_\é“}~þ8ÆÌȳ&±îÐÇÓqÛÅq;¼ÅÙR©U¶lÛÕ,ýï g¼¼^Cs=…~úk*[4õ¢^Í–¥™žåO×mT·I:/nYº·ãµž1ÚLs*J`#¸lœ ne¼ÀÜ¢ì8W—Ìi+Á‹xAì€=±Ì ÄpM¼n˜?¯™SbZbÄhòÏ`-؃6‚+ÔÒ–µtΘ¸ 7 þÆûXøû €ÉßB[Mþ98hò¯ ›&ÿ ýjòwÐJ7Äà¯É¿”qò/1n„¿^ –ÑÄÈi 1z1–ùMN þ¦ F_ƃ›¡þ¹Ä ÝHþ±ä÷Ä’?K|M,ù愆fý[þ«þÐÜ e‘ÓRÿ©Õ S…xKýúµÂ¿¨e¹‚ä‘ýc­Ä íQ×Rþ–ú+™ëe¿y¬‹¥þ ëhÉ_Ë8ùkôh©¿G_–ü=âsêoSsƒ¹9µµ¨›S[‹<9õ”^rê©%æZ:ä¬kÁ³`Nø‚<åÜ'{¸à>© [AžkZ§&ŽûÜ#¿£Îùä· 9%F-—ËÜ‚µÏ©ì=WC'}•k‰_K—óRV³ᯌÔõÄèQàV ç$¾!–6n/xzjgÿu › endstream endobj 104 0 obj << /Length 1026 /Filter /FlateDecode >> stream xÚm–KoÛ0 ÇïþÞ¡@wÈbK²EÉ ‡=°î©­v;p’C¿ýLÒ2­b‡ü™z”é¿n>ý|ܘnxvù%‰¹óp[·)¿íOÑÍM5´×£ë/ßë\ç½ç¯ñÏqhÝ%¾-ª‡þpù< ~èÛ·kçü¨ÿ²îõÐóØ'¾}r6ßê?›F<.o“‡Æ“OVŒîßn<†þkœ~I1=¨û®Žå9ÚÎ;Å[¿÷Ë¡ïÆy»ø6Rw‡ö2þ·Ç)]˜üø~¾¸ãCÿ2Dwwñö×ä<_ÆwŒæs´ý1vn<ô¯ñíÏÄ×ÓéÍÁÞqÝßÇ{™–™rú¾?ºxË),Ž9|Šž?½Ÿ\LœR`íйóiߺqß¿ºè.Iî㻦¹\ß}𥹢9Ï/íßý8Öß5õdNœžrf=KâʳšXÈÄxΈ—ñ9ñ²¾&^Ößázz_/ë¯ëe¾%^æ—ÀI%À®Ð®s°k°‹f™×ûyé*ïx•7²`?¬Jö#+® rÆuAι.Ț낼㺠\dÃuA¶\är® ØÕ\°Wyã¸UÞÀb•·^å¼:oäÕy#¯ÎyuÞÈ«óF^7ò꼑Wçl8/a9/Qr^8®â¼WyÃù‰†Þ…lf™`…;%»[ mpŒ$[MyX[RŽÞ+Iù¨¥¤ÜL6§Ñ`ÓYÜË 9HKvvI6ä)+²K°k² Ø Ù§šã‡¹Šâ7ð+Š¿€¹Šâ/°×Qe\G…ñ›$Ÿû@if¨Â<„¨½¿`F¿¡ñ‰÷[fô—Ä©÷WÌ诉…÷7ÌàÏ0O‘úùæ*’Ƴ xü÷"ÜE)=+b¿~–ÑúÊsN~¦‰—ýv¼?ÆSðþȆ÷G¶¼?rÉû#W¼?rÍû#7¼?p>çïãËSfôcÊ¥~¹dF¿b†w4ψ}}òœÇkf¿ãþGÁýl¸ÿ‘-÷?rÉý\qÿ#×ÜÿÈ ÷?°žó÷z¢Sfô fˆWKfèUM}k¡5õ­…ÐsßBohÍ:¡çï0οÁÐÿšò¬ ÷4}{ÆCùU¸NµzŽçšVcC6¬¹û ¯&á9&ýà¡öj¯Q¡öš,Ô^“‡Úkt¨½fj¯)Bí5&Ô^S…ÚkêP{MÃÚk®©MCíµ"Ô^+Cíµ*Ô^›…ÚkóP{­µ×îBíµE¨½Ö„Úkm¨½¶ µ×V¡öÚ:Ô^Ûð·µLøÛZ¦¡ö–"ÔÞR†Ú[ªå=™njó îlpÅ\®†íu§[#ÞCñW¿Cï–«êi8Á,üá×ß™~4Ñ?„ãªs endstream endobj 106 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚe1o1 …÷üŠ7Þ ¸¶/çV¤R•Š6b ½!TUýû *Ó‹¬÷}v[0žÿËo'%S˜0µMÀÇÞ­ÖŒ¾Ìç`꺀ßKkbÉonyçš&÷0óõdÑéj¤S„ ¤bH=VÕôg7ô»Ã¶ž¨ÅjñœÆÇK­m•ïùøuª×i^\ Ä ×ú³K| ŽJ™b9éâzÍCÞœòhR%¹²rËÆHl BÂÍÈž7—îÝ?“û†ÇB¥ endstream endobj 113 0 obj << /Length 19 /Filter /FlateDecode >> stream xÚ3PHW0Ppç2ÀAc(á endstream endobj 119 0 obj << /Length 288 /Filter /FlateDecode >> stream xÚ¥’MO1†ïýsl[g¦»½J„¨ôF8 ,¸‰,Öð÷-4jBB¼´Óiç}Ÿ¶ƒ°„Àó|Å݃% «õ q Ö“ÆàÁ[Ö⦲§œbUáäDÍâP f¬µ)mmåa—Dÿ$ŸÉÂ:xöG‡ÂTádQ’ö²©´F”;E(ë> stream xÚ3PHW0Ppç2@£ ¹ ´‚¡‚¹‘‚©‰ž‘™¹Br.Wt¬B PØKÁ@ÏØÒB¡¬(WÁÄÌHç(sr9…pé»™*XêYš™)„¤Œ01Ò344RIQˆÖÈÌÔŒ ñ‚[åÂOz endstream endobj 129 0 obj << /Length 299 /Filter /FlateDecode >> stream xÚQ;oƒ0Þý+n4RëÚÆæ±¦J«¦jª6Þ¢ L°X"þ~ )J—Nw÷ùtßÃ.@ámzz R’F<UBQR±HˆHCPñæjê´—à‘Ç þxS¾y¸Äº;ëÎöúÖµÎzíF8',8©Ú*ôƒ˜ã¤À æî¼ 1!oÐñD¡pøsšÀ8o5 ¢ÄÕè Ñ[½ar£wºÅ(¡a쥪ÊôŽ]RÜë|0¶õC¡‡ÌÔËKeƒPâуõõ)þÌßt'„‹qÈs ñç^m÷N¹Ä‡‰ÚàDDç¼Âîõüí€ã endstream endobj 135 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚA1…ïýïØM¨v¶Ûî^ ‚ èM°%’Eñ÷Õ–ƒÄÁif^fÞ¼Ob‰>k;Öêi…B† Ü–`u.t‘•XòöýP•‡Ó>i’Íùxàb3J(ãþºñ×ó­¥¹¯üúæã ‘PÉÊ Y×± SᄊöZXi±=²åJ¢ úR¤EŽG½u„6y¨lÆä;ê§~yeZùÛê'­9EXz†V© iÂY-v’ŒO'®; è_ÔLŸ0í Y†HË endstream endobj 139 0 obj << /Length 936 /Filter /FlateDecode >> stream xÚ•UKÛ6¾ûWð(k†¤$Êê-]¸S Ù¬ÝE’-Ñ^a%QÑ#›ý÷r(¯dlö4ÃÑ<¾yŠ‘3aäóôûŠe„“T”3šD’äõêË7F ¿'Œf™$ON«&±Ü­È~õiõÛaõæ÷˜“ŒfRHr8‘8ãtÃ8‘™ œ%äP/Ám¸N‚woïÛûðÛá½3á1b)¬ O)眬ED3 Îä㇭U]mK€2IiÅÿà,Z a$ˈä1ØÝýö~ûé¯Ý~wØîa´™%µŽîlÖ6úÆ[íšp±M`ºBwÈÆÒ48ŽeU èÏP°@wGÝ™%Ÿ“`„žÃ˜fDéSYUÈ5Z{[Õ¶ £$øYÖjÐU(0rŸ$[§ ƒÕúlc¨c±àyÐ>Œ9!-Êþ¹¾U¹¦Ð &ƒÃƒF¡vþCòÁ‡­ÍØ 3XP¨èšsš%¾¥?,iCd€$ºÕMQ6g|šé`#Y¦­Ôpr)£YbÕÈ<=hÐí®¬~È“`@›ò8åä¾8š›º-+=¹)‡‡ Ðq<Ÿ/€úçúh*ï^+íÍÙ˜^RMi Lõo(N}²jP¦[ $›‚za="J|妹N,ìpدo?ìw W_YÂvûovÛ[”g›,û•g»±ïË7ºœÚñaÁÞÔõM«;5`¢à¯¶ÍA@ºîQ§ðÑ!KÔzPv^~Øö{7ª™œ÷\^ÖxVîÎfx³,!t­ì¦âŸÜˆŒÕpeæ^þngn,»© 8ˆC§.ê5ŒÆº*? ¦µ­÷Ú®˜Öª±DÞ6a/H—}PÿWZ¼³»"ÒÙFÂã©ìsk-dðèvY·(UHzÝ*¨¾Æ×´ùÖªÓÚnz,a´ËܶÃû\ƒ*m*NÏ­"¸™c+þ…d¾²(®¼{·,–ñk ÔùˆÓìc-ñœ:S/rë^ëlò\ãUºÀfórDÓ  €SHj…•ÁÜ,Dhn§j”,Ò‚~l[œ˜`èñÜÊhvnE,h,RéÀ}¾ 7ÐÜP²àðî•ëÁOãIÛßVëycÿ%ì­Æ^/rŒñºý8¯z”Vp꺋 [ÓµHšÁ¿oq(¡Řû UóK5q/˜ðG?ÔPzä^Æ6a/s/?a“¾›çËÏüúw™ÄTÈôúoe›ÿø;O¢˜Æ’ÃO~Ñ~Y¢ëˆÿwo endstream endobj 144 0 obj << /Length 224 /Filter /FlateDecode >> stream xÚ1OÃ0…wÿŠ7Ú5¶s±ãµ¨EU*à­êPˆ)‘Ò–6Tü}œ˜ H ]î|Oçç÷Ya…{6 ìvN^zk,Â;œ£J’/j¬ùôÒ´us؉‰q_>„|x¦äñüÏÇî&KϱÛ.æAKc¤›°`³ÀNL§çt¶'é”ÃÛž­7 uÒP²ð¾‡­=ÈV©·xaOLýFû¯’¤±W[ýKK)§6–úÀ(ÈKë)]Ä»í§(ù—èG:1±äù*ÍYMõÔ×KÓ5Ãf7°¡ÓüÃ÷S¿ endstream endobj 149 0 obj << /Length 1486 /Filter /FlateDecode >> stream xÚÝXÍ—Ó6¿ç¯ÐÑ~hõénP²ôÁÂ’¶ààu¼‰KbÛaYþúÎhdÇ ¡e·‡¾×,i43šùi¤E°%ì|"|ûy"¡L²X±X nuÄòÍäýGÁ@ÉOÓˆÝ:® 3Qíš½›¼»zwqùzÚ–KØ'ÞeMhDàtØàvU4G,ÆçCÆ/w^lj(2† kz>𱙚Hr Ð@”Á’Ql×Y^¬êõ¢hˆpƒöÔ~Ðaüag“¡Oöô¬BŸ¢8Ø”UO#dšàl‰RßPK»îl NbÀЊçHîÕЮ‡pŒ²Í–ÐÕiDŸ¨³ÊÚ“ÆŽ ;+„>¨ð®A§w ºc Ž€2)Êp°_Zcžj=:¹6Q?Üu˜Ä£\ám‰5뉛mS´-Æ ’=·òñ6H¶>’ËjIóˆ·Xy&º5¼öacqƒô@æ×“(Yq"ÄM*úÇîØYTè<¼øò› ˜$!ŒÜ5oÎßPÑɺ7ìÝÅþ`<*èVà9Iøkû]S ‚ÿl«$[O¹zÚ~žµ9ú€Od|@¦®„åj8ð© šöoST‹–ÆÝ îMÇyç|ØÙ‡]B7w=oA¬eÕK—K3ÊÂ*2‚ØŽ†ù†iJϱæÖZG^ÃÈB⑘±Mù ¸ìŒV#‚fùh¤ ¿¦ðsâ1åÆFqº×¨…gÛ¯8rP9 Öý‚EìÕ‰ýr9 4p‹žß7Ây–ÿïý»aoOj1cs>DT iâ¾é½ÃAñŒW.à 8§^ÖÏ xõ«©Øí‡jÀ½.-FËháÑã‚0x1äg¡xÈ9G…xßöPN£” ¨‡§x¼bDÓ±ñ¸Ü†BØŸª(¿À öõ†Z¼ýQ7}ÿq–P\‘Lʳqò`”*«@ÇNÜtËíòj"‡Ö=Ô¥/Eã®úÿ ãô`ùå·%õD »¥ OED»õ&£ m–cNþIé¿+5AQ Œ-TõÔ[”œ»šRÚ][|Ehe‚‹ŠD|®D!`¤j·hBA,·%VNHÍÚv×köIæ÷IÈ« %‡'PèQ·Å°b¯¡Þž4r¿W€§$ =iyŽÕ] .r(ú·ÃÙNž@üýF%šGIÔ pzk( W5$*†Í]¹b ?_Ê!¹=²îjöäÙ«Y_[SÙ‡ýýcd̽.ó¢j _­ä€Ö+Þûåª;*äkô*Z(¬óWȽÎúç±,«½9ð<Èpæ0¦ÿn°†Ã#éøßÌu?÷¿ˆÕƒ" ¥—ÒciWü AŠ$ endstream endobj 155 0 obj << /Length 234 /Filter /FlateDecode >> stream xÚOoÂ0 Åïù>&Í7Mš+Ó@cš¦Ü‡²¨Tþ¬íÄ×_ 0 i‡ìXÎóû=„ LÙØ³‡‰Và¤3dÀ¯ÁX]Jírð5,øø»iëf¿Ù’¿>ûÔ¼*xèV¡;ô£4úm¨úJI%–~Æž<ûb*žCPI^K‹>wl±D¨ã|(sWÂé²µmÊX[˜³w†W«·z§UhIæßRÒêèSQ‚5"ËsÅ·ÕQ|gÈDDRdF;þ¶DVðªÙÿ¦2l¯ÔýaäÃ)~¬ºó^¸dp3³øƒ‰Uô endstream endobj 163 0 obj << /Length 2016 /Filter /FlateDecode >> stream xÚ½ZYsÛ6~÷¯à£4Á8 ²o‰ã¦WÚÔVÓ‡´Ó¡HXæ˜"Uñ¸¿¾  HJ‘i©Í‹HâÚëÛÅb!ì­=ì½»Àöù÷'öˆ'©' F‚ù^¼¹øô'öhÿÁÃ( }ï±µñ¸À3ón/~½x³¼¸ü–/D¡O}oyçñ Ï)"XxËÄû4»š/Äì»×–×7ó?—?´SGŒûTÏY`Ä©·  …„˜Ëïn®¯õØ‹ëåC_H$)‡=rÜ'ÃpŸ0ăböËÏË럗šÓÛ–°ÓFDÈú ~™O¼:öoÞ]x „íÒ Ÿ!é[Y"Ã_¾ð§…ÀxöK¹ÖìEyúOT§E>_PÌŠ;ó¬ï•y©Š¦Œí{’–zŠŠë9Á³>¨˜= عü–=b0D€BA óoTVÌ™˜=ê™x–Væ™ÇJ/­êÎ|·C?ëez>§jΰ›]Øa†UÑ2DÄl=‡‘}© ‹Í6Sµýêd„wä+ Á§¹34_0Æfï‹Ò Qu”f*q_UlßjŠV¦»9º™“WbX禈‰=‘¡ì#aÚàIµ¶õcäp<ÄH½–n²ó( é•ʻӓ;¸|a‚BQ"Ü:‚!L|@—ã…Z—Ø\JÊxÁ­ï¶†¶ÛÌàd@w  B9’DŽ©s"Çl2y´öøþª\©²p˜ŽÒ¸‡‘8KU^ÛÎÜ·rÈëPÛ²×(£Må¤ ŒTÁX*£P)ÀÏÔ§ PÀ}#OGÛô9ÒBÔOÖgŸþU©ÐVeVyQ¬}ϹW§¶4VÕsv7‚Ç0?SE¾‚ÐšÜØ³šŒº!'k©ÏÂ>ê> ólªÃ`j›þÀß*µù„« `²‚2 p‚Àž©NÁQÈâŠüÌøz2膜¬Ï>W–‡ÆEâ^ä3*gc½´¹Âtµp r“¡Zš¼Þm§îÉÔt™s*›È]§±>{·‘Þ猲öÑwúìÅÁÓÇa¦Y ÎõZÒnZ-¿igM¢&ƒlHÿdà` ‹ö#Wóì¾P6eiÒ,åûz®žæ(U:BÖj3 ¨˜!AÏu`,!ŒQ²IóÉXÒ?Y³}^ëäM3‘UhÔ™Õ¦ƒym÷;­¯È¥dNÙG4œDu´Š*õÉÕŒ¬:Ž2_™AÉJüÕÔi¦;‚~GíZÛáhöœM„dçYˆ…Ý’x*îG´OµNŸú—÷ªÖl (öû~ÂtÛÛäGi“YLÏ{2 oÉM¸^5»e®Tkö)NÁdˆ|LR9zp =’Ã/|s7ÞXýH|À8ƒñ¼Yºäžõ¡»'[©ÏÆO验Ü9ipÔ(»|Á¼<¦õýåªgƒƒž„t_"ß?é°µBl³fæÕd´韬Çûºp<:N¦HâàL%‰ÑÐi©˜¬G´OVPŸúOEeƒCtšß•Qß›¸Ö™Ø$1$‚³ò.Æ%bå”E]ÔOÛɩˆƒ“«Ëy{$XQݺ¢ { ƒ tzUG°ÛåkÓÙÕTÞ¿4-q±mÔ:ôú¾66ªª¢µÞ•h"«~1€f¬î‹,ic0´ïbÀ®xÓ:®ìÕ+%®{õ#šæ Mœžé `N­¢ÀÚÛÉÎ0$²3ôø Òƒ´>p5o‘):ÕÆÔ}ŹÄd˜É”ª->ظüöÊ®ÛÊÙ%'£=µíLv½“ÜÒ/]ü9Ï0žK[ÛÔH×`zð²p²9úLÇ3ŒØ »Ik5 àà@I¿VAà ba¤³Ì—&#~OÕ߀ó€eƒ@ÑXô5G@ÞžsÝ—»#£™½ø¸HÔ+WÊ“nÀªYwØ·•㺲UO˹)¤B¡<Ï4HøJižØm{D›ˆê#'[¥ÏÊm¯ ­µxÄ G:Sï¶[öïÚEFv%¦Ju™â`ÄåÍõë·ï¯' "PD}:ª9==ŒæÁ“ÔM­{¿ø¦£»®iÍÒ^×hʰ‡û˜v×)ÿÕ…Êø„pà*„ûÅ.Ãèi‡’NW¡Ñ)„ó'm[Šv•תY &vþÙç£Î0T– [«bÓÝfh‡ÎÓ]¢×m9ë¬BÐH@)ú ö‰ÜŒ1[£SJ€¸BÇP%Ñv«ƒQõ¬^ªÁç€Ûtý&¥ÊíÁ5]a§~ÔJ-ʇ½ò58ÛQ¡F‚ÿ@h›”=m]’0¶ìqÑ¿ T¾[º³q¶;GÚK®ÿ]HFøl yí6ÕïlÈBÛ»MÕnÒ»ÅôÔ[7ó™A+ gimç߮ڦ׾eÞïSsGa>ÓÊ,™Ï}ftl˜2µw3\G·®,opÜNì‚3é 8uÕjs#±8x§¤©4¹­¯L7=qºJ&^ìcÙsˆ$a±ëG£²Ÿƒa—s|%'Û÷q(O?$cÔ™ÑèÅ•‚]t~HV_Iˆ‡r5Ùl_ã+±k’½müb¤‹Gáµ'ÚMÞ7…»×ÿP±J:ÿ»ŠÜ.ØVâ"j`ïjžÃ>/Ç ƒ4hÚ¿Wã âqбž*ÇÿíR2Œ endstream endobj 168 0 obj << /Length 1818 /Filter /FlateDecode >> stream xÚÝÉ–Ó8ðž¯ðœÆy«½;n0À4<†à ÛJâiÇ^è×?U*É[ÒL/4‡éC[%•Jµ©Å6¶†m¼Z<[/Î^ú޳8tCc½1"׈üócÏXgÆgóY—Y^n—–­Ì·çk¼Yº)êDÔUó„¦>ˆBðFà0×eÎòëúõâÅzñmáÀq¶áyŸEvd¤ûÅ篶‘ÁükÃf^¼2®$ÖÞðÃ| ãbñ~a+Vû/s€S›¹¡‡»BǨaáhòà œã°8\-c3Û‹H:£’Ëûc|¶Û6»6/NR:{ ؃‚mÃr`(&Ö;ÔX öËQ–×KÇ6EÚVõ5M¥UÙ.-˜äyÙÐhÚ³ÍïKíÀ‹HÞªM ˜Õ¶æ{µ‡— Š<©y‹†ÝÀrŒXöVÌ BÃr"{Ê/¾¸Ž=Ù{öÒ[ö€ I#Jä…tâXª¶RâɉC³kDF‹mE3 ìÛó·]­vI¶q%AgTÈD±3h‡fÓ¥(ñNíRð®­€äF!%ê×·M_J¢ˆÌZŒ0ûc÷üré‚A2q% ‚ØhFò+’×ÊŒyIßv—7½9¥)‘¨y½Œ“Í7Q¶Eš{ ²]7Be£ †s>$ ú•r)€öUƒúk ¿ÚÐlOoÓ•i›Wûj—ku#úטíx#ÕFQ‚°Ûr$EhÄe£À¾¬“€¡%NªZ;ñe–J$Øáü •‘3ðkÖR¯hwžb|ÉzuïÝÓ\("(³hQާ·–Ã}ˆ]b5×ÃÉâb–›æn,ßGõRZ9ÍD–¸ÏÅ¡]VY­ Ýìórq'ÚëÇç(é¶V-ävfKZý!ÂêDQfÖ¡~\ÏâtÖV–¥RÄâ ;ôŒÞägÇ8”p”`¦»îÓ ÌÒž UøíÔ-¬ÀÓ룣ÀJOMœP‰Š¦ætˈ‹.m;-6˜ˆtèH†RKò½ÝµW(¹ÀÑMñ'-rQ¶ƒó¥UQ@˜™E+ÈÞøkän«ª8!Ùw´/r¸Ì½|'D9Ê R&zË͈^U?þ]›ˆw™·'$¤ \ŠB›¾ú2£ÍÚóžÖE&ôÅHÑŽ°mkvœ6òãÞñ®W*æüý@œcTâië¾å黋A´=OÝW?áUÌˬÂrE)p»Úê ì[9âH÷WÓGÌÞ¾k ÎÄgžÊÎÄòC¶r}Âb;vuwò“z“?«¾ƒ#_†…¨‡‘Ÿ·WP©y­zö™ós˜v¡W9T×%9}X,”dgÁ’âG.](? ‰ÕsL aI¹C:§²@+_ÓR)d:‚ö)¸®ƒ²N£XÓ,PÓU^`´wc¬¼(þµËÀŒ \fg€¤ðí¨MŠ¡”ž‰· ÒÞ䮤mšØ@ð¡áйM{Ðb}ZF¶©ˆb?»ß iJdaÇ3ƒ’(ªê’FzYeøž—°ÿQ0QUîÉæw’ʪÕéZ#ew9Þñáábš \W³iWðz†uN™v-ô~!ùåƒsUBb§øûÒï+Ì‘}deÙ›cZÁisÌ“ÝÈØ(Õå­Þ­Qöõl?5¦Vt5zy’ÔtGr`'ëëúTd@÷ k,?6æ_GO-A4}±îâ πžœy‘ƒqÆ7pcŒ¾Mh30ݽÏE ‚@NÌṵ~ª2TÄg¤c(fQ r»žôæa}W¡ 'öS)ì¢?PÏØ9{8.E°m¯>¶”,ýßË·1ÞàœM* Ñ9w q¼]¶w `Í ||ñáâüÝßb¢8zëý³D4{;'Øaæòõyœë”•öüRΟ¬'c;Ô¯úù<•mTîÈÛß&'Í |(}oý³ÈÉ_n 88ŽjV’{/ÄÈÐ7?Ïwü°ÄüP÷…™eCèÇæsü‰oÚfÎæ¿'ûBâ endstream endobj 3 0 obj << /Type /ObjStm /N 100 /First 819 /Length 1676 /Filter /FlateDecode >> stream xÚ½YÛnÛF}×WÌcòBrï»… —º РFìm?È6c ‘EW¢»_ß3L´EZ¤%'âuv朹ír%)#K*#G"³ø‘P8 ’V‘Ð$N†”Ö$<)‡wŒ $%YaGR‘ÕÒdù¡#¬• ¯4Æ’w‚”vHyœ¡—B†@JÙ‘f{F‘† 2Ò@daÅ’50*H8+ȉ ž ô˜7ÐlF‘`Z þðKôÖ+YGRy ËHjÁ@Ipu iœ"gHz0vgc:ã<ôëF^—%v„¼AçP•ĸŠJ( `¬:°×2A€ª´ÂsP×x)2 0ÒàRÌPdµÌCÀiN²ÿ¡ÌK0f§{ ª° »ÑЂã$,|Çq‘p–"Z ? §5;JjÒ†M@©¶x,${Øð…‡‹;Ã=°ÄK{v;¨=ø „Nv<üd2mGˆ.à0w ×K¼×81>åÈ(Ö‹€ª¨"højc$_pøØ‚mlb8Ìxk/Ü!ÃV6ãÜ1H1Æ*#`ÂY”’_² :ÒÀV–,FY ½±– þ"ÍyÀ>C"Yçù‘õì< %y—¹ qNŒ@Ð$ΕNä ¼6:8 ô˜Òߊ“‚Ò7ôìâz|[æóD<§/FÏ>¢Hðs³,;âÜyóê_>,ù0áÃ"^•QdñüAK²méO>œG ã¨pÖ¼ºâÃÇLgQô:Z\=®Ð|ø¥¾F­ßH< NµÁ½Ž gMŽõmÛE~QNŠY¢º<ûg„r‘ÕTÿ‹ÏÊø¬¶¿âYSìe4{Ñ’ºŒ¦ê8_D­E|qßAuy¾Æ¶‹ï4*?ïÞ‘˦/¦Û¼Ý1üMdð¸L:o¦yEⲿì¢ÿªKÑ<_›uÝ]I[AÞP7m1*›ñÍ{ÉÈC¦º‚rÛ¬Ðq³Ò¶Fd—,žlkT>Pûû`ùPˆVÓøxA/2ÝFö6*Z4Ûé´Y‡+‚zÈx'š6Гzx³ºpyÚ|],㾉gö‡ tm„úògÜl“EÌûzÞø´­kªæ¨Û‡f¡E‹~±þdÓvÔpÕœ‡ú:Pçìù.*¯S§mø&jUî»+3o5“b»z¡w4Ï_ãð/ÍNUë½éX_¬}é(ÁqÌ´éàŠì øa3¿ÚDz¯0/I&ý]ªwýóô­^u5Ô£fˆ®šSÔÍ:¢Yóñ@›½ñ8¦é¢9Þ´|{st 9ûØJ¯ã²2ü©Ù*Ë’†Ãí£^3Tqÿo¯Ã?P¤wÍ`ÞöXTÚ‘Eu·êêŒÉÆ*¯¥ü”?»3zOéá¤N$Y¦É(—XÞÐÈ/I1¿J/'‹2Ì.ó»äº¼™>o¶s=0éô$ï뱺áýÿý2д{‡Q»f ùٽö—pVìšæÛr’ÿ$yÊ5”M‚¤œOø¿,þ“K… ®ˆÎÍî§Ä"ƒN‚²d‚¥ÿ[—g†`‘›++‡¥~C®#õ;dŒÃ—+ZLŸœ´.1˜Þ÷,%Ãÿ¢î—Œ¾Œv×R²n cÝÇ6et «WL9™x»âl¸rÓãCûÕÿjׇ endstream endobj 172 0 obj << /Length 2404 /Filter /FlateDecode >> stream xÚíšÝsÛ6ÀßýWðí¨™"${síÅι¦­ãör“væ( ²8á‡BRuýßwñE‚•Ú‰“ñtâ“‹ÅÄþ°bàÝx÷âì›ë³ÕEˆ½%œpïzëQ „^Æ(L¨w½ñÞøßòb“W7‹%‰bÿûËk}óÝ‚0_4kÑÔí3]u% ‘¶B0"áÅo×ßž_Ÿ½;Ã0fàa/" >DQyYyöæ·ÀÛ@ý·ŒœÄÞ­’*½Çp-¼Wg?ÆÞþŠ0˜ ©ìű×@ÃQåÕ0CŒQ‘S”Ãã4Ò³£ˆ ¢¬üða¼7KGÝæÝNßµbŸ6‹%óÓn.Ó•k)¬o7¹jY·À_7¹hG­.hì<¤À[’†fz—[­ånB烼5ƒwµ¾¾]ÀbvS[i ØQƒA . Q[¥»Ñ‘f Ì|£_¤ÝÐø¥\ 1›“¥•™ª±¦5×CÛû«Û w°¢¨”ÁDlû¾©3±94-–!Žý_¼”“ª;ñLúK:F?hí˜n—ƒùL#ÞIÏ`n¦¦ÛÁ³PwÆÎF—ÊTûI—`Hz6i©kÚÃ~¯&Ê|Óÿ—Ià½`Ì¿þÒu/^þüEÈüvNém^½z9Åßó°VY‹·‡*ëòºJ‹¼»[pæƒW)¦ÃƒBBöþCÎ,-÷…@à ¾‰©\3¦J˜k•,§*k6µzúpWÕ¾Ï^ÖH‹Ÿ™F!l¹©´¶³P3B½eJ¨Ùb.Ôs4†M¦eÔç[}Ö ì2—ƒÖf¹4aýNmYçUê.j©±’¦¬."wÄ AŒÉ½G¯¡r¯_%9z a£4´‚ö’Žs_¡»«Ëüfgœrh§†Î­~ý|ôêÿJo ° ±0ñ¦W³CÍ5Á>û°Ý…yŒ8¦‹åV¦vbﲉœ^h±I1+=ª7爂“˜ª. ÄÁXú,Œ¸iÀˆ†”8ÔËœÃ(JàOuï+) ’A# Ø0b_•ʾPØûš`P ÃeP  Xys Ô̲¿ýü¶ÞO,ž„ÉÐ"//ú¡ã¯üŸ.Ìâ‘~ 'ÕB`Öó8ïÊu]ÀTt÷¼zkdဠ iFýi¢‹˜ÿ‰)Ö@úWæ8ØhÆnëÂÂn{Ÿ*’†˜#`ý¹‘”ÓdãlŠlœ![_%¡¤/ôhÒ׃º`îs!éSßSERNGHÊÃ)’B̆‘§¼ãúEº!´HÊé“@Òv¬v¬SHF…$q‘T£Ü¯$í, ±¬Ô&“·sÑ@ñÁ}Že›luèòbÕÇp0–»Gu!{ÿÿÌiÖ4µíûÛÍœ†x‚ÿJG/°Bhep ÌOà !áxh5S|ŒS³’FÊ ‡1åAÇJ]ºÉûI2еé|{° ½}Úíª´n 0êc§Ìø‰,=ØLmn4ïÒÖ(µiÁ>5— FÐöÜÊ\pš3ÙÂFÓ8&Ƶ*‘Ç}›ÄsÆ:™Í#2_¦t5m^˹S‰Y¿ÂІݾmêR7èU`‚è} `{kUi1+×àÑ‘P"y¥E€mlÛZb×ÝdÌ×’„þ]W­å¤üPê“á×_q‰@$öÏ¡V4ÇöÍ,¢vW, ¬-&éí»t]ôx¸N)Š9p=|\¿¬ÚNåËâ8ý«Påž)pãªLÌ@͇5DÌùN­ãáç‹ig×ÇÎ#_Zñý,»©‡”©él— Ük%‡ª‡<.O‘8†‡øùS|°³óŸ oàøˆ7ú*QûBWûš`P Ã}.žzªó{ª<…Ùˆ§$åy ÇÎ0PÐÞqý"'Á-O¾§ÀS$N`;â# C1l¬CôWh[ŠÚNN£@äd$0q6'Œý[o«N7©ø×ñ6%Ô6òÓ㟶ÝR}Ù˜ ¢Ž‹Ðñ訩´¦fàÜèÒ§z‡a@„ä°J‹YÝr¿Å‰“aPBej÷C(¨°W€©a¯rQÍÂÁü±zp’s´vÎÑét¿³çë)h¸ZÌþ¿{8‡²«4Ð(¶Òå¡èr8ü›pdR³áf˜¼>‚?r  ‘˜~‰_bÀ—ð b¼^¬?hŒ‹NÅUx~þêúùåÕCùÿš€þ‡eÿåqìã~”©?ª;Ć®?à¿/^kp&Ä|BA„O<þŒR¦Q ÂØÉœ,–> stream xÚÝZÝoÜ6÷_¡·[YšEJjŸÚ -ÒC4u ’â ÕÒ^µÒFuýßw†CR+»IjÁùa%’ÃáÌp8óÊ<¸ xðÝÅ××W߯a±LE*¸¾ ’(Hâ”Å™®÷ÁÛÍ×CYíËúör%鿇W×ôòïËHnt»ÓmÓ½ ®7ºÒy§©²(báåo×ß_|s}ñþ"„åxû˜%< ŠãÅÛßx°‡þïÎD–÷†êÄ*…gü|ñÓ·¢ú' ARÎ"%p– ƒÎ:ߌʅ!ˤŒœv!g\$¤`“FÊO_&x»•œo®/¾Ñ]ïmÕ¬-vhÂÙ"Wߊtbsl£ØIêš& 42wF¦ž_%=÷ewÊMßB“oÊÝЗMMCEsÔ–ú¾ìô†"ôÛÒ’´D 9<»ÎÏë5±ìØå6æ!è“ñMc'˜eGyÐG³çÙ¦+§ ]áÁ=œ´'¢—›ËøTUs)$HDÖ1bóÚ˜õ§="ýïe“E”mPb!8qÃŽ¾9maVüùéŠÆÉĆb_¶ºèù†ßqÉK¦H-âlä¶F{Э~0¢Ôß麷2€’{ê<æwfœp–Ô2G¶ð¤±?GØšîì—Е M>Â"ž¢w%1üÆ©"Ç[v¾A/JøÜ‹¦Vœ\ÉÑ.aÇÆ Ó£C‚XnÐÞØ‡ù$ëÞ†SP³Ø6üÂJF2΂åÓœµ!Ѓ *e*1ãJa€Þ@›áÒà“†lÑ,Ž ˜‘&¥4Ý´$‹Â¥ŒeB&bM:DPL‡%K2ø3Ó}gÂb©’l䦖l\ÑwÀÒ7*· ïá#;>.W@C5÷ôôàF³âÿ^¿›à§œ'“èoøøÎ{¥úýXwˆXÂGÖ\1‹A¹ÈØKÚo/×AöòÃÒÚ6SÓÈ+L'Ë@ƒ¬3µ *a§¡A>ÔŸrŽÎ˜}:SnUÆxˆO8^±ŠÑž&C&‹ô¯âdF§„ q¬8èâÏùjòʸ¢ ¯1ÀdrÓA¢·æ¤ÛܦÅLmºŒÞ"õÁƒàj µ8ãc¢O=Yq²ODFŽ™ä°!,Lc–FÁ˺ëóªZ]ÁÖréfì4¥ªÖ®éÖªQôóõ,¯ö˜™dÄ÷ÒY­Mæµ(Y¢ž6 [eoîKÐÀ¼Ê“‡Y#Ø C@Ìœ…þá¤ÂhN™¨ª0aE"¶Fm1íwDÔÜÐs6€¶*wmn†¶Ô°“i¼?ä5õ’üðRkܹ{\Äà4ðÃ.WkD"J7ÿŒ$iÓa  fñTj§†Ù~Ê©ãÔêw\ĸÅóÞÎìjÜÁaFëÝÜQÂ)Ô°Þ:wF “©Ú(~˜BjÎÛiDq# ŠÐÍp{0 E›¯ª^ÓÄÞc%7vÆèéÀ‰”†%ЦF•nã}0b°›q#Àš£EiÆRÞúÑv H0ßUzÛ¢Pk>. ü„¿CaMõiu½Ÿ Ih/¡×b*|í[‚àor€÷™¿U€#-žEq¨eÏ5&Ûš#Z}AÝ]-"q‘v„àˆ=SïGgîòj]nå¶9ÒøŠA‹e3tÞ%ç☳]sgÞ_– á¡9…‡t“ÓK²É÷ûÊ+8G×ÐéѵCÄÉË †!ä³A2·XÝô–ùˆÄa|‡lV‚Sù=I>9-z†¢§ÃÓ¦fCÚŽžd5xº´ô›ôùÐ7Ǽ×{tB•Ý\-œˆÂý?î¦OI†¶k†¶0Q‰‰¯ÃXÓòžÄè:ÍÖŠ*öŒ£6…Þ“J˳3KEt2Ü4oøÉq±§§´Ï}S G¨^œŸC¸´…FˆÅl,Gˆ4µ…Æ¢“*\œwèûS÷ÅÕÖ+›;y_Þ•ìn’5ˆ ËßÓÛFÄÿÂâ)T•)Xp<ÕÓ:Ã8Þ¬ÿà|Y烑…`©c™¯ž§ÌYé¼ö5¾É´O×úc•È)\Q`ãt^ø¿‹BþTå•nËÜý¥Ó«(J§µsb¯û@º?÷&Ï¢¿é£9–Þß)>Ó æ©J[ߺ5÷@5"<ç^6(=â¸cÅŒ-{ ÀZÏ,µM$GrˆŸÁT‡êF› 2jÿ˜¹’ ñlj.ô‰¥¹ d"sá 76æBBg.Ãhf.ìaW3d€]]asÔ©g˜hÒxóÕÉ„Èî/P«ˆ‹!Oµ6‘:Æû:ȳàô”)âŒIå=Ç¢¯(2º+­ãH^î5ZC1^XrÈé•KÂMsçÒñÔS|Àks‚˜žåÿ™%j¾u7/­ÞOÖXˆô\‘f‹Õ ˜ø,Þ$Ïo~é|°¬…Ù©¸ùˆëD´Ñ«Ò|Ÿx¢]®¡<9Þ í§lX¾á¬+¾bª¹­›Öï”K<.1³ +hê•Íú´·$5ˆ²žÜö)±¼µ³ÐÒxoÑ™‡Âh¤Ä^#¿ñ­B‹ÊÂy«]Z;Èy,kma†ßÜižJB·>Ôç•ÛµÌß6õÑÜ)9&*Z÷TxÎNÚ‚‹lãð~X¥Oî²,†Ê¼c'È7ƒX»$pˆCM [‰s[9Êeð‡¡Áº«5!ºê‹Gîx½¹—^5 yöØÛl²¸XGñåš«Ûò³“ÇMw>'‘$yMú¸Ú£YË–S>tmñù¦Dc±r-L¦0!U#°&Xœ$LÄ‹”ö#îªÛéŒ=©0C%F\+ Üvv7™‰Ð89Ïðg¾£ºI‰eR¶xõø Ýî±Ï jü̬íg†©¿þ•Å~cW|J6saðX†5©ô2Së”Ó­HN{HNÆP:CetÌBbò¡H{.3©p]ˆ?6ŸÃ)úݶ7¡¿¾±b/K(Ÿ¼Øâ ˜Êéú¬Ç,”#a½ª †a:ev€}€ØrÎn‡’©lY½Ùó¾§÷=„˜^å,𓊥L&âC ›hc,ï=,è›Óy¢_Ï0 Ù-{ÞÀ•¥á?þÍ"JVîô¡è^Üé ~v§ï»ðÖÚ7üݵïá#;>.÷O}³ø\õû\¿YDÉì›E”.¿Y>YFpk©]Ð ©ûfü>‡o‘ ÍÐǾYD@˜¸o…-À¡Ð Æ#ɬǂlÂWË{ˆ!üçÓïÚüÛ%ƒ_¿yóó«×?þ-!œ¬e×y˜ý+m%Ó§©ö;àû¦Ó«ü‚ê&Vî¢'–,ÍbWx‰ç)»^Ÿ.8ÓW¼à1•%¦XL%y ÀgÔ)òy¢FÛºi[8k–’Óëåiqfk²z8î´-¯ q›““ðª½R™B/ÉŸ„Ú¾€:}Ʀo šöf~žr՚ɷëxqr9";ošå?A®‡jîCÿ?hõ_˜âˆ…¡5*]CDæ÷éå!7[|‰h€g›— :v×}·”óOGõ endstream endobj 185 0 obj << /Length 2916 /Filter /FlateDecode >> stream xÚ­ZÝsܸ ÷_±oÕÎDZQÔçtîÁNìßùziì¶7“f2ÚíÕX+mõŸÿû¨¯UœÄí‹E‚$H€À×îêaå®~>»¸;Û\ùb•8Iè…«»û• ]Gºþ*òcÇOäê.[}´.º¼Èòòam{Qlýv}G_×^`©z«êªyC¤ªPi£¨#ÏsÄúÓÝ/g—wgÿ9°§»«Èö¾¹Ñjw8ûøÉ]e@ÿe;'ñêIÏ:¬ü0†o±º=ûû™Ëçí¿Ž€ãºŽJ\ŠU 'ă„B8Ix("n/\Ç•I'ɧ|ý6«vàºÖoUÓ’ì»êp¨Êâ™z]£2jUÇu`µyU6‹;n®€ëpîÊö8xB'µí½*Ž“…›+x¾“€Zm—V½¯«µ ¬/y¦8DàZš‹nµ}wUùoWú]­œµ-¥´îö9Ï~Ê‹‚ZŸ×î5Å”êÞpÓ£y<…€sŽ$½îܯ} ÔÔÙV=0.×—3y¢#»—9r)¦ŽõZ”êÏŸpýæ*kJFph‘¤£—W×¼¤Y[xŽ'ü©j/@< ÷ž©{6íŠA or|šCjÄV^’SCÐšÄÆ1ÝáºÇôA»ÖZºÖ_Ö~`¡º’ÄBa ÅüêªjQ©ØN[–PLlâ&FÄM×Ô›¢Ú¥ÍHxÚëy*˜€Këúž¶}Ö·ÔQ›¼æã¢õècéNÍDÙæeŠ â*më+$ƒ åT…yil°·§ 6ص­~fÉÜÑi#ဎOïn&””NôB½é-Ñlg œLòe#t"9·2…×õ'Þ“Ú}Ó䂨IìË?.ß~‡Ù^LuƾéK>:¶= ÌI;úÚŽ/ j%¡QÇ´N[E=R9®­wh’û¼Íw5çe¦Ž þ”-M;Ö¸'Y§Þá¾®3fûŠìÛž¬–ƒùR'p êØÚ>Ü©“d‹zËÇ;ŒCë–]ZÐÈ1…Yä/ 0h¼p)ÿ (”˜{†V¯,¤Vôø"暘ûÍT y,ب ¥FË—=w¾Ø Ñï!Ï;P¦vb¨4>ÒœÜ00ƒ[³lÐ3vÝ;Ô=»èÔ¦›£Úå¨YƒÍ[4dv¸‰ù‹H:®Û£å]—<ÏwÜ ·ôïñ/O‚|!»—g¶Ñp…!U Æ)†%¿ !Ľo~‹âžßÜ¢3Ü­A®sݺ|wýáEWó!)ˆ’EW‹¢‘õÄñ˜J:Ò ´ôàÞ`‚–¥‰0z¨2­ýt[0¢_¡ìCÊ&¨ffi›¢Y‹Ðº.‰4Ž/Ú+‚ÞБ3õ°[l™1À¿û® š9ߨûØÄ@ÂVÇb‰¦ƒŸpdeHì…Ã!‚} þúî-5ðÌ46ø®ô}+mhWhkÓs88}«ˆ2rLå`¨÷³I”‹! óåèöáæïÎõmoëmð˜í,T¸‰ËxðpOûœTÏgà³~xœ@‹©•ŒòôˆV$á4\m¾¤õ ÇK|GøÑ€ /†&?q¼`™žòvoƒç´E¾ý¸è8žãzý.0«Yò}ÒòþôŸ^ô @ß@„SÝœÏÃRŒó> uÇc­š†ñ+`| ú µÒ Æ0x4ýCXí²¯êG"‚õy`6ëÇ:QÃÁi¢æá,QÃ9ÿ è;äÄ=¶}2ŒÞP=.Å­‘SÍì4‡}>be³”ŠA¢á'}Ö––Ù'¸jÏ85ÕîQµ Ì|áăs€2‚Dè¼NÊÐäu5õª£BAµÏC·y¦ûBT¢íµóB#¥Ï¶ úJêÃ-VúʼŌGòÌ[ñÝE^0WNÂ÷˜6†¢aŠNÂôE$€ ^ãÅÓëhêÝV·ÍFŸîË‚’bˆÔCüà<±Oz§%P©L°4iëkJ7v‚ä4¡,1ØYÙØ÷¨IPèͦp›‡-þ.K/Bp¬‚ªíH@x÷·[žRÑW·žÒ‰’ÒÇäv“Òè37‚…5•) CºŸ /p!ŸcÃ^^V-ŽCùš™ÅôEøtÀKï1— 8÷“ž°n•ZòÌCz<‚}62”éAg£ñ8RÇá×ÓÒmÕµ4©k¨T*iZ{0–©VñbŠá±Iôà8yƒ­( ï3+FNÙOÈk–d42¦u_O5hÓ$F†³¼¦ÆÖ1†@¦hó£&Ê™º¬Ã¯7ý8Ä€Â1"bËLÑ­pˆ !°J»5YUªEó ™o(´è— ˜ÑT÷­O 2~Èb¾ß2Žy¡>ë7ŽhZ-ÌýlÎy§³'ú^¥™ª—®‹r#,³} õºAü’?=4ÁÒ(Еzp¥®W6¼–nhäHÐÐn3°÷g–ˆÜ9ÁÓ¹šë0©1è<åÍž¹UôÕÅÄýóRúƒš×G´·ïß_Ýœÿ|û“}½á”Š'LÐê 6T/5ÈH¤üf„t‡¢êæoy³Ñ|+ÐAýî+î`Z»jç¯e£ª«Íìo©y8ÓïEᘒºÐO¦5޾9)Mð£’ÚD3w„‡œ<¡DÓ£@Œä©{À´ñ"×ÞÃè§fE^Kt‚®Þ©Æ¬Ð8my¾Îñ!ÈPñx3Gű¢Ò°8Ú•,n¡Æ¨Õø9ÑT¥}Õ:ÏÌ`¨VêÍÂËáéÌÅgcž†ë"/yÎ.K?€Þ×°i^~nDàçžÔ=84½]˜£U嚘„¦ÛÎó5ÇwX¸,» (”¼4‘‰\gÌP„óÃãçÝ!kˆÁþD`nw怾:~__5ͦiOÝÍæ‰Ë`À𠈄6Y^d¦¡ï0 Juy~cxh`„)e¥«êhp3ž‚cNÀÑ‹å£pŽQhÀ1 ù•)üÿcðmp 9<½|cǃףïxa|‚ް¥FGÈStÄABG=§èh‡ IÌÙhªbÔÖÄ!9tDØÃÿííç›ë‹eÂ?œ•£Ô\ÃÑ(ŸÑe‘0ï(Ø2P,¿ˆ€ c(–ÒãZž9«{D0BeäHø(Ùƒtcö«.1¨Œ~%µ[^ÀÙIF=í´uI…o¥ÙÒRaFÛù»¦Fbð†ª'oÿj'¥QŤ-³œC™þ©ˆžŸùeJ;êÿžwfÛ×Á.>G•æ©{zVšÂ.4ìݾu¡jRsaÞ²úÍ~ÌAØ€ÌtôÄ„“]¡7ªuˆGÊ[Ÿ¿¿¦^8¸%·~d—Ž ¥à,ݺùioô¦„–¡uå8A¦‹‹yõ°©ÅUæŸê7I:¦¼(ßu´Á«u´ŽÙ×iVVÑ—Í%´K~Òd]*&¶ôø¹Me× ‹Z³«26¿,Fá¼rAê¬;ûX¢ßÌÓþ'I5Nä‹Þª}:> stream xÚÅZmoãÆþî_! )BÖšûÆ— -`Ëvêœï啇kp¥¤µD„’:W(úß3³»|%ËA‚~1É}™}æ™Ù™•ÝÁbà~8»šœ]Ü :Iè1o0yølà‹€ˆ&óÁgçj'óx½Ž˜8ïï&æåÝIGeS•¥ù¹izT‰Šre>(aŒÐáÏ“Ïn&g¿žQXÎP#^ßõ³ÕÙçŸÝÁÚ¸„‡ÁàEZ „À3<ýó̵ªVOBAS—0ã,2èØk|¬7G) ¥dåî¨K\î›Ýq ÓZþþeŸGÒu›õ¹Î×8K×+µ. _‡T:QGÓDå½ë\Ü‚¬~w0bÔ ~ãñßpÖÅ­41Ø'a¬ƒ¦øøþáîþæ±µÄÅ-oÎ$l02h˜©?¹Œx·1ú$ XC¼Ûß‘*)ñÜjp”þ¥ëKe^Ææ1KW›8QÙÞIGÉÖþG¡îQP”à–ƒãÛûË¡ï:?<õ¡!$p§Tàö~8â®s9ôpø18F€¢øÛÁ%„„%àY¢#™3âóÃÌÕ3Z,Ú&…iÈ•}IŸûAÓ_ÿr¹Œùqô|I<ÖEïá¡—D’¸Â«¬üðp,`>€ÜÂÊj¹ÉÔ&Kg*ÏS«i‘šç6W¬Á9è.]EäÜêÑ 8” "ECRY¯ÍøU~Û#FÆËþÅl6IÀxtÓ#‹Sƒ®¬6§A-€îô(æÌe„Q¶úQÒJŸH¯¹ëŒÇ) Ìò¤"eeØßGUð×§-ªRj©J»T…CUj© cóè€6è J»ÎÄH¤Î*Íq›V 0|•®MÏ6WmÑÅ2¶ú¤›"6Ã\§lÓ$£è<‰šYífÆWœ"Š×¸ÙÁÈÀ<Úì/sʉµB ø½ØzèóPÀêYE^óòËŽ§•E…9Ñw’Ù—Z5%ÆëY²«ÊœÇ˜ º~›K×W_þqsy}óØG$Ï'”¥—*š«l­ÔQ dl–;„]øÎ|J–æMC-¸_©ÔCâÃÙÿxÍÈUZ×'•Œ êÖÉ &¼ 7|wQNâµq ÂËkü })h1Œæó…ã‘hæW Q¬ò2Ã>|/À|NDXç~÷߃SÖÏãìï}ä‡0S'‹X·¿âSÙ±ÁÝU/ø, <5ø+넇ó\"|ÿì£$ÑÌy1•¤é_wà­+šp–§ÕÑç%5˾ƒöJb›SõÜÁÀF¬Ÿ)Dv½8/½®8p^7Jk 3õ+škg‡ÎøŽ™N ©¶6IâY\$ân/ Õž®{àÈ-ï ë4+#uüÜã»a+ß°ðÙ‹ÇB­F½Ž)t eËÑ0ö¤E¿Î‡‹¬ÓêNˆþ„ÎÙ ºñ±àQ²Ö!¨Ì½ð¿qŸÀR&oÀ¦KÐo‰ñ?ÆöQ¦_ oluSŒŽˆ?´Ù2ÛÐXø4?±ÒCZEë#bi@À¿k±Ák?õ.‘n—UUü»8ÅBtãê9ͯ Ðé´`±EÊ䦫Xê-Ä;Ý$1oÚÏ¡¯J°­> stream xÚí™KÛ6€ïû+t”ŠË7©CÛ&[¤m°©ãÒd[»«V~T’‘äßw†”dI–¼ÞM=b.E‘Ùo¤hðÐà§«W×·’1‰5×Áâ>šAe`¤%2Áb| 8dù:Û>Ì"nløöÍÂ7~™q¦Å2-våw¾kžæiR¦þF8'löçâç«×‹«®¬IÓKb¨ V›«Ò` ý?°rlƒOnÔ&ÚÂo¼¿úíŠÖò¶¿„¸”p-ð-Í‚œtÎ;dŒÄJqÜ".Ï(¡ÂøÝ ÿœ”/_&ø)JÃÛl[ï½:l[…íîë¾Çúa¶-«Y¤Â$Ï“*Ûm}ï:+°3]U3FÃ]‘¥å¨T×·°òÑb4ˆ¸‚ÍÅ~7Q´Ì¶0Õ÷øîõ­±]ãZbc o¸‘¯ÞÌ{ó_ߊîàˆ [¿Nuþe B nÂt&Tøy&(|¨’ež–Ä×*|•Þ#É!¯J?¶ÚÕÂtIc\óFš×¿¿þñÝüõí›ß¯a~|O#'Õ Þ„4á§Ç´HëÉiw§‚()Nç™Ws¢E+FÖˆŒ¶܆û¤zô]å>]eP!ÓµïXâî¿ø){&‰ Ö6SFQ:ã´ÑU´/м)NôyDœHÄ”(ÛWûj·Åñ‡¢áE!{l“ {‚D\’˜¢ ‰…hä)§‘œs1!†XX¯'êû/hürÆTX¥›YÄb&ë ˜Ô5DZL°Á±ãØ(I8µ#Ø”Ü@ SºÃ §rš Û——qáÍš.7Nfä†Å¢æ»zÜ`Ç47”hÍ'¸ÁñA$™¶^ùRÜÉZI_Ì’âDpyÂ’·7Ìz?”RàçìR¦ÀÖÊþþæ.Ñ$ëh·Í±ù„¾Jˆ°ym’Òöèc/Óá:©’zÄÁ?ò%¥þw±TFò8‡#FÉãRÖ‚TC—V«£ª¨ì2Çù4sŒ0÷ç™Sh¢ëò†{ò9Dö¼¹MwxsÌ­ [5:Õ~‚Iäl+>—„*þÕpP‚5\¼Y;Ï–S©LCV*ðU6ˆ©wË¿0ÕB8° ö:õ-X±H l‡Yšâ! t*£AÖ‘œ„&˜õ’Œ†vj5r”«ú"r_Á¢¬oÃáUü,¢/þ zúá¦àGŒKÈc2ïö3P”>eýÓ}ô›’¢¯_5ö™¡®*ûŸ™-Dªãýý :ë„e endstream endobj 198 0 obj << /Length 1488 /Filter /FlateDecode >> stream xÚ­XIw£8¾ûWpü^£HˆõЇ¤³Œ{™ôÄî¹$yóÈ6 N~ý”ÓtâÄsB’q-_U}ª+““ÅäèÜ!FˆBÏöŒÅÒðmÃwä„ÔX$ƵyR§Y’æ«©eûùe¶P‹OSÛ5YyÇÊ‚¿SGW,cgjCm#2½]|œœ-&ÿN¨ÃQâäc߈7“ë[l$pþÑÀˆ†ñ ßÚŽÀ33æ“?'X›Ú>K1²=*þ壄~:¼êœ#…®k7ÞŒ0õ•wQäJ+߮Ƹ¶\ŒÍù㔸&¯¦€ËFP=n•~t:бaÙ.*«,ëN þ^üõèÜzoR9¾SçÛìó鎂£sÚÝ ‘ë9†¥ PúPä7˜:«º±r±¹œ:Ø,Jµ¹ëâ »"×6àžP‚dãð'#º)Aï6oÝ`3´Bï´À~ÎAªxAûfãýÀûÛs¬,ÍëÖ*¯GT@͵Þ‚pìàlQ‚é.â£ÒFáºàÕ(Ú*¶ßˆÿýr>¥®¹xpRd€7”·âb³M3x‰Qˆg¨ÀVËmYæ›e´á»o‰È`³ÎÕéxH|áÀëYºËPh{{E„";»ˆH€ö G8ˆåø¡yò¨ÌOØRPGTgð%DP n¨Dˆ„(y» þ媄ŒÛ䪴ÈÕáCšej•ÅýHRß`K¬aAtfoÅÿw³eÿšòŠe;(N³(EG;rñþr¹Ü­ƒ£LQËRÐLTÕà ,ÞF2IÊ£»ŒYÅv y'¤[±à°5‹EHî <“êËO ­ò¢¡•:/Y\¬òô‰%m\– GbùVë~0øóµÛê¥k«ÞnË•çgDzz¿]=[ÀÔ8Ê<-”yQ©EšÇY°‘Jô\nA_)é”t9P´$è×#6½ˆ1³„0W {Ÿ/“¡À«@r²ÓÒÆó‘×±é°t°âÜë1ö¶ [ò<¾šRl^ŒH’”Ñ¢pûlp‚Q@l'8³_Æü§Þ›bq æ:®yñþQ@Àøí HcàËðWHo¢4¯$·Ã‚•¢¶¬M¡,Þ«¸´£gRœJ‹’ .ê¥zò¢.cÖ¤u2&Û3Ø}‰î%Ñîž²*~EÕÑaÕ%,‹P‚mYb¥yZ¥Q–>)v~¥ƒ³æßÚ,½+#uû=6ôŸèßÖ,o8?JX× ¥Ô<í®]@•®]i*m%Õy•fN%¹¡«»æìPªu)•E‰Åëí¶(«×q Ø ¿ hµM¬|PÂuÀ¥±6«1PB’Cœ+·°ö+ý™ƒ‘%ãÚš^?;)¯‰ƒ­xðMä÷íŠñ·˜®ËôÀ굦ŸèM¶¥j ‚Åײø‡Å:DÇ¢¾”’±^åÔï“Ø½MÄÓ„Yq¤ïéWç•×d‘^tâte¥jßÔMê¨ÄYÊòª¡ ªŒr¾I+~ˆkÛ{AyòõÓì&"Û¬^5¹³[o71bz©{"0áìw«‡ûÝêÐ3¹ØùÅe3C廙.CX)Kň´a›¢»(à'¦À.å)쇭œJs¶il"ÓžvëãnØmäØ-©ÛVéwÙ4är¾@VÊF ƒª,²f¸[k笥žÀÝ÷¤ÏÔ°ØL8p ¨QMG¶cÃTêîÂõ]2~V·W¿‹Ûúî\:µºÞGI"˜Y F/w”Ïæ L¹Ëúéé®f·§ÒÚM„p%¿;5tÔ1òå|n‹[WXÐÉz‰†ß¦\Ư½?M~=ƒèˆ‘¾G†Œz!ò»÷Ã:’ãœáJ5ÎQÈGÏ Å·yœW|hçÅuÔ„ endstream endobj 202 0 obj << /Length 2602 /Filter /FlateDecode >> stream xÚ½ÉrÛÈõ®¯à¬2Zh쨔ò"Gr¬XòÉãrDSD ,q4_Ÿ÷ú=¬™±f’î·ï¤µzXY««³7÷gç—®\E"òmu¿[9¾%Ë]n(ÜÈYÝ'«¯Æ›6Í’4X›v?ÜÓâzm{†ª6ª*êW´õYe*®½HaÛB®¿ÝÿzöþþìŸgpZ+¹ lïŠÀ VÛÃÙ×oÖ*ý_W€9 W?ô©ÃÊõCxf«»³œYLoÿȵ„í;xË—« ><Ûü7Y'IzìÖDz4‡ìåÞjXß•JÚ-_ß ¯4Z•E]§› ]쉑°ÔE§À `0¹ XzPõZBp=-œžŸáÎ2•ÐV‘O¨ fPŸSLÈ¡Ý_P|mGÏÍ(§šJ¦ž1Ë#´t‘[ÝtœD³¨j4‚¿B/uý"8Ò%)à`èçT¸£5‹Ãã÷í!ás½ ªA®^¯|™©·P SæjpÀm&jÐ×vôÔ0!±­qoA#%±”RŠjÔÿFÉæeÎá±peá#Æp¨1p<Ñ.@ÖÏÁú½‘ŒñenêÉØöœösS÷¼™©{$c«fãu)ž¹‹RtÇRÄ2Ïý>­V‰¡Ž)ä=Ìl *ª¸úAå‰JþFêQQ{J9Üâ^.5ë¾üHóî‰1b즗`P­Hº#IÜĨ¾9 ÌäCšŒ{ÁÀ fÅqw"Í—PNq<ïõB‘áA±Ú§ß›oîNVŽ#ÂyEÁ6fuv ¥Vd(VG¨iFKµM³—,J‹x¡nu(\ç$Î+1XÚÞP‰ip#ÊÒz\C² †„šîf,¼=Fó2ox0öò·©Ê›‘¾á¹© 2ü´&%T¡\¬ͽ/H–ÔèKá}ïÖ¹?­G_ø=Õã[Ê„s{þEãd…µeIü`ÆïËõ%Éqýô  î— qhÜú2«,Ò¼™.½JÆ„$)¸sStš <ƒÉyót¤yßî´Õæc†Tòßã‹À^.ñ²„šœŸ‰Íy*U~óní{ÆÅí4l°õ@ÇjwÁ%g>EÒfêÅ!;ü|B™}óñÝ›ÿ±ä¸­2UUaL,ªŸ.Kžõ>uOÝ^eå®åª+ÅÄ·ú5›Ú%²×y·Âhðo4òøPfêÕ‘°rýŽK íG–t!¥iÉ’»$ëðžó9qC1¿HæË3ƶz¢n¥€îe]fK1't…ç÷MÕ‡·7'c4H¾ç/äÎRnlÙ·Kd 7R”+äï&¦”{³–o ô¡ç³üYgy‚5kÎZ?+)À9ë:[ˆ^D¯aÔÓM1¾žb ‰“@¤ù¨é©mB‘e%ú y¸¸ÖþCƒ<]Ñ@ëà9öÌäò¼÷õ=ˆ°}jÄʶéòì”È Ò¥ÐÉ4fT˜l[6A@:6Ôž’.Otx40,_li ;rÿ€j{F5ÚÅbÊisíQ«ƒ£©Z Nöò'¼HÕŒ†?}ˆ£,¶}, CnHa*ÒGZÅ(§¸+ »Ï90꺑qG½9ìSåžêPà~¤YÖ¡ã‹Ôš6—,ð^€·9ô")‡ž,–a1>x¾¨Î—ÝðN¶ô¼EmToËæ0«·:QNÒr’ÖX™%/Ž_z8ô Jõ§\ÜÙ(+·ž)6¯þþ¥ å„õU?ñb8üÌÅ‘>žŠ¦ó^½¾[äµ)^Ø4Êžìg½Ÿ7eý4V‚Qu ¼i·t|¦O‡‹‡éÌ$I[r¬†i9.y.3ätÙ·i³ Pê ‰Œ±ržÖ.ÝÒÇQ×'Áyêý’QkÚd@Éj÷´¶\K„~_ö¾½½½¼¹¸º{m~8Ç)Ú9”­K½‹…¥ßÇ:úÌ K8ãôÑùæ¾!À::ïØã)µÌ5q¢Ç[Gf9&߇¶âìŠyÊŸc>þ…¤²Lp:Ša‡³V•,#Ÿ{.\uM:®iÏ#uáÆ»AŽZ±N‹OÂh9í„i‚jzƒÐh z&ªÖq‡|jǸ5±cM,“Ä4¡6G<ÓÖLkʈÒÝì%°#SË)¤ÍÍê§Vìºj:lGDäŒ>ÜÀŽÊ»„Bmšìæ°˜T t¥h«­âN °Ú(‚¡+Ö³v49“z¯ms) I3™æG(L ÅærdÆÖÄúº2Ý~`@õÑV­g±°Ð1>õe´G&Õ ð•Šš^ˆr8›òÅüBûu›6ÜïÃ&eÂRã¬T™Å[]½09ZeÕ„ÈÐhK’ Äù±¯lu@<‹\³à±·Æ+EõØ ñÝ¡è#cÉ5VY ƒ#Ιcö4òÀ; O<ªœÿÈ8ùag(jŽ%ŽY0‰BUÝí¥mÜ>›Ìd: ²s4 Iq£úŸª’®s#‚<©ÓåTN6ð~$œ# ücµñÌ. .6;ކAÿ$ßÿrºé EhEKùUÚÏ:Æ;}+«‚~œ®´¥Á¡¸Y´Øž‚ùu²£kží}=¾³ÆéÌ6Š »£ìf¹°©Ão÷C|˜¦S8°­TÞ’j‚[pRÀ»×LFã9(8žŽj]A…§3ž¤éɉ8çPð\N÷GÿŸðüµ…„†¡ÿÁÚô¡îÿ"PÓ?ô¼ŠÀ[¶C2ò&OÁ¦ÿÚ%´ }ë%½9oÿÿ‡œÿ endstream endobj 207 0 obj << /Length 2487 /Filter /FlateDecode >> stream xÚíZ_sÛ6÷§àËM©™’ $oæüGN];kë2iÇCQ´Å3Eª$×÷éo R$¥$¶œ&—Nü` `±øa±»À‚w3^MƧÂ1B;”®4¦·†ï¾lrc:7Þ™Gë4›§ùÝÈrýÀ|}6¥ó‘ë™I9KÊ¢ú‘HWI–DUBÇv]Ûý>ýù`2=øãÀá˜á{aûÌ7âåÁ»ß™1úϳyªÕÒ2€ß̸>øõ€uEåAGÔPÚ!ðñf3y´L*{dÉ@˜ÓÃ¥oΓ[7Zg5ÒŠ~ë‚~× 6ˆ:>õ»P8.AQÅú¾œyV\ä·é5î #Û ¦ímY,õ«²f–‘®ZEõB‹z½Jâôöq—f)†±e=¤õ¢X×ÖÇÅqk(šn0QhcX‚{6®a9ŽzUÎÓ*še¸p#yñc]éâ–~›c\Ü)ÊçƒÆîë(£Ï¨Pm¥9•:‹ … Ò¬ðøTòÎ,W¨õµß9ßšÿˆƒŽ83×ušUV=4ZNY+Å&‘4K*déì~ä²kUQ­W«¢Äo³†e㜃†¥ºRcX P8Ÿ¼½:ûÙ½"B\&ó$¯Ó›8ŠGŽg6íëÇUÒ…ÙÌÙ.`›D:F [Ä«W´‘i†n?Îí@º4knC¡?À³2ÞYcæäÏh3*³g®pêY¦¤áR’§ˆˆÂR* =Só>hM¤k*u‘Øjžè†¸[ñ·ÑÁu™á\­#ÝK÷ŽèçºÈ"dÂÔÎGÊRãžæšÇº"#'›Õ“¸ây7c.WiÖH‚ 3h[¬êt™þ·•uMãåÉ\í<ÖW¾"ÿ‘œZ­óÞô§ˆÊkùWõFgnGäȲ} éx$Y‘Wÿ¤õõМ ~õZ廒ÞpØÒá†çƒ:8qãÚ†¸Ô‚Q³A1^œìºÏmÏó9ƒ’g»ŽƒVøRW8`Ÿ¸Û!p#îV{¶ŸêÞ}[xÒ7@7یؒb`Ù²fÀ–Â6ìØf¸ Z³¶=ý05³øo?¿[ãW”'ôpãÏ«V#ÈuÓÿ窃kû ¼«á¶€É¹ /O×´x5«­ö4к(méAð°áåa @ètqÁIènÈS¡ØgmÙÜÖö D©ù§˜ô(W¸-ÚÌ_Ü‚>lEÀ\ÅFþ Œó|ßvƒ Î?NåÓã¡•WgïÑÑ÷:âeÍéñ±6FOâö¯!7m—§Ó‹ÃW×ûs{b'k(›1k]nßÉ9!GGä„®YeéÝ¢Î0z¤Še àº˜,£\†"ìpŒL ”Uª|b—ï#²¬Ð¥ÕÉ’ªIâ3¨~¯"¦Cì³ÞGw*–¯¨):Yüé®ÙÍ©ýLDDí{\%H3Vš“Q–íö}àÙw„¹ŽíaŒAMÆëªßÅ ¼ö6Ξo{¼ m†À5ÎÖtPá>3’’¢¸,Ñb#õä#ï£ è&˜Ž`‘åÔ¤ª¨ a`©cݹ^D5}åI2×ÍÔ ÂǨ1¿×Œîpܨ¡é›ÐG¼.«d×>n5ØÛ®:¶¨`7z8ˆZ7A„^½¡â  ,QÝt®£„y‘·±úú3Gè²ùå£îðšÂzMányÍ–„~¡-´Þ¡¥° ;¶îKEÿ¯ó{RT~ù¨€‡½¨@°aT ÜÎ0P tº¸àp¬‰ xøÍD½¾Ž ˜Ó&cò×øöË˯ä“Ïž3äÖ4À弨ÿÆ]íÍ‚|˜Æñâä+Áxñ­Ã~• üÍáâ霚0EßQX/“ÙLÕ Üíœ:õ(êÖLn'‚JÙ^#ªCþsÅìyìì†ãÖjWFŒÏÀ{‹ER?£»Z˜¯ƒ­ôÁãxß¶UõÛ¿ Ûù ïã!nìœßXhs8[ôbîë뛋³£—b×kÀ“Î…&/;“çRÅÓzò?ìî‹%ć-3+Ã#ŽÒ”LŸF^(líÜ÷yž-7Y’“£›Ÿ&‡'“«ÝÌgüEîb>»qï9,ì!‹ óy¡¢ì§ÈhòÞAmhf{Ø„7—þ] u‚#ó Ó”Ÿ6KÊO@l{n1«gM¾‘Ûâó¤'Š S{A× KL°ÕuzdJw&.§¡Ë¥IÇe l½¡)™nð°H)©@ÅGu¿¦vËH_C¨†iµ ²Ji%™§uŸ£Õe‘Qá½Ê˜é @±Ö’霄U§K-Á**£eR'¥n¡’(\'!ñ£wC°ãnfžÒ­…j¶Æ™~Þ;'LA~Ï|Ï|Í;‚¿Gæ`ëüÛËCû¡ó?ÝàŽl®béÀù÷Ivöeî³¹Þy.[ÓÜ$è››UºÄŒê]éOºWM޾¹ÀÆï¼Ð¤I”WMÎoÙëDgfÿ³îSËÁsˆ6íJ7øj LoBÝÚôkÏv«7}õÀúïN&§£€™‡#é™ÿ¾À[âéÍåNäÍéÙÅäæR×2súÓs_@¢‚«‡(øp†JÊáoSÝú8áö|œàÊK©«î~UYP']AKSZÝç´T9Ë$Ê–ê1‘Ø(ÕíÏOŽjRÇêå…³‘½÷¶ „w¶Öõiµ#Û0ðzcà;Æç-v£ÊôÀTºná~üÕJ@øä~zÏ'o§#ᙇG7êÈáëÉ~ ¨Ÿ ^ätÖÔÓO'ºJÛ‡ Ý 1߬ˆwd?¼×%ý$Z][ÚÙÓoޱâðâõy:òàÿM'Z†*ÊàˆÅÚc¿2µ÷óx¼*!IWQ¶éPØŽðw#=|Qê 8>ùAéÎ7¯ÂµGµ[ÔAÅßìãE´a< Í£ÀYudIšÇà‘œ×ÕPÎÿèó¹¤ endstream endobj 222 0 obj << /Length1 2848 /Length2 22557 /Length3 0 /Length 24161 /Filter /FlateDecode >> stream xÚ̹ePœÝ²JîN€w.Á%¸»3Àà2¸»‚»‡à.Aƒ»w‚»Üï$ûœoŸsªîýy‹zkæé^Ýý´¬µæ-(ÉU…MíŒv¶`FV&^€*PSÒÝ(t´sb±³6°1±°¼G¢¤uAv¶bF` /€lP0CŒl,,àç i ø7]ë18GÿwrÌfÎNÌÿµÔ‰ùwŒ òªŒ²Ò¢âò*âHÚ9þuv6ÿmûÿÉð? gaäô‡²¬¢¢,ÀÆd ™9#[?°ØÙ @þGy€¦äÿ*9 êìèø;5¹ÿV9þ;»ÿn†ˆ$]kOo#×ÿ9¶F¶ÎNÿèö6Ò2î '°Ó¿<ÿ«ÒÖ¤³ Ûÿ×Îý^ÿÛ£°˜,/€‹ƒÀyX {XÜÖTÔÎÆÂÛ é÷Hˆ Û9º3ÿï}oekçjëù(Ì@¶¦¿K 0u¶gV³98¥Åþk9D„ôWfX@È.6±`þðÏø-fý-†”ÂÛÓÞÎ`fdíô™!HžNF.éttz{þSñŸ‰• ` 2Cv<ä0Aúã]ÚÖÌÀó/1„É«þkúhþœd´cÌÔÎÖÚ2±fHÌòv`ÈœÐüÿýú¬%œ­­å!hþWwþçB#µûÿZú?Vi§Nó؃œ$@n@SEØÄâ_]ú—\lÙ_¶æÖ@H‡ÿˆÔ~Ÿ8Ö9èA¿/ #+ÛÿÔAfÜÄÊèäàäù£BŠ÷?(Cù›0€YBIQEB†þOàŸuâ¶&v¦ [sÈpsŒÜ‘X cÅÆÁðd…ìS ÛŸ¹03ÙÚ!&{g°÷ï®"ýž N³ðoÑ¿'€Yä/â0‹þEÜf±¿ˆÀ,þoÄÅ¡ù±˜%ÿ"6³Ô_Ä`–þ‹ Ñeþ"H<¹¿Oþ/‚ÄSø7â†ÄSü‹ ñ”þ"H<å¿Oå/z`Vý‹ ÑÕþ"Ht#2ú‹ \Œÿ"“£÷Ÿ&ÓäïjV=Ó@?à¿!¤MÌí ”Íþ.€P6¹üÃâ·ÚÎÙñ%æÿ€ ÿ€¼@ÿ€T¬þ!¹XÿB’±ù Y!ÔmÿF†˜ÚBæõzH.vs‡Ûý‡BÕþ¯’ª=Ðd÷b°B¨;üB¨ÿ#1Vu§¿á#  ð„ Ë@nÿ0€„ø[I;°…#ðµƒävµû‡$%ç@H5\þ! ¹þ…Ëü`l÷îÿ€d=þ& ñäÙœÿ¹—_ŽÎ|–¿›û¿~ýÁ*`G;+ ÈòkòKäŒÀŽ 7ÈÍ ‘Cþþû›Þ ü{×üÃZDÄÎÍ“‘ƒÀÈ™Vvžß âðþ[“]à. È)ôßø÷Ý Ý€&H ³v&|A–ÉßBŠ}Ä¿Œ—ÀRò0•á j~Œ…YHo%z#–³Aüïßè—N•o'+Å«ç“èo[ I„ký¼Ò”P>viª$´iä#çC„&.<œ­Î¤.7ïWÒFN»ÿ1;O«ðýdzsl3 @mø@”§µý.ŠíÇ æ¯$rÝ’æå\XׯӬ 8ŽÖXnó„߉æÇ¿¿¿Üá|þdÔ%¼@7e˜‚7üξ³{{ÜáF´Äs­{rÚoñ{kS*Ög™—7ÓÊü2³‡–¢„¶7!°§piD™Á)ü¡ÄùD› CÂ8h’ûèŽ^vߥkw–ZØ¿ÞÈ·ó—„o¸‡#ǹÐz×É)Ž‚qãòr}­Ï,Ö‘À7úªý¥Fp/QgÕU^¨aJ•Ÿ ûfÓqÐF"PÄe-f¸®;Q°ñMMsŒÈ>Bg6›Žîf˜}Hèhk¸5ÖbÄ«Œë+·Ÿ!cÅ}*¾AŸl9ί„Ûf—èAR=¤(bïý¥;ƒ’5._Ké“¿”«nfãÙÓC^ˆ[apß¶³£ÀIǬ9E†èsµy¨Â 6}&ÕÑ)ßœ»ø¸ÍùQåçqþ—ãšÒi‰×9Î.„Ð33p;ð«–‡R%•YeðѪRósNcö´ZÔê‹þ+Ejç_J<ªârÐeÊ’(46§I i¥Å%—¹|>Ï%žê´\ _×y.§I‹ñÈ…¸\«L‘Ú³H'Q‚׸çútmjŽ ]í&0Wª¯³yù¸M¦ë=<}šgš*q½Ñ.ï”ðoë{C Û‡•¾¹R0ôm } tóm"~˘ž‚"ê¸7À/µ¢£ª ëxì*yOÐ6=DwFžÜõÅgiJºáô3ìýzâœ\WM ] ŲD˜”.ìN}ÑþHãrg{dEÖo4µ öí?èæyiÔòµûkq "^u*Yø¹:íoÏ´†ßpoL߸hÏÆÙq†2º00wÝÚ…ïà·pî‹¡¶šní*ã¡ÒÂ#pB7›î—yÊI}¾\m„ZõzÿMIÑ få0’×µÔ¹¨è]ý‹>Âê{î„Iþ‘Þ´™6%m¬=ÜN¿¦aUi&Þ=çæðéëíz¢›íÚùZƒÚ ‚àißTó+/!“W³¢„ 0´¼>©«öÔGL«P«ëà$©Ä[ÇŠÆ9ªbIÊœ·†q ÍòE1ìsCÒz—É0nðúÙæ¢ Õ{á¹e™« ¨þüÍR™æ0ûšïÙl–Æõ ªfÙŽˆxƒðª£±yëU…䜙_zÓ$ÀS‘#¥ÿœˆ\•m76­¤ÁÅ‹â[¤»€»¯Þƒ]’0ú}Ø?§Ÿ¿F^J0{fصÝeY˜—§SsÌAÜÓ—Û«z@ö/Õ¬rö¸ih¶6ë¦í¹M¯Aö¦òîsÃÏ¥FÒÜyh@ó ©ÈÜÒ«V«ÇV@ÓÉ{_|líâsUwt`)­Ü•OzÿàC#®™Ê4ú¬àb–ñªr £‚#Óôí´û9E Â)‚éÃ-t_é€qÞq}U͘19q¹Ì\‡ ”3ÄI®–I ©åϦ€…³ÁS—æIÊ+ Eš—No•¤^ñ‹í{v„9“Dô¡!zõmm×Ò+Õ‹gÙQ’Èõp ¼:qãžZËóknUwƒÀÁžÕ‘ä-ÚŠÌ'–õ3Ûú€kØ÷AžÅÒæs?üXשyc °Ó+•º–O(‚vYR\¥=ŒcòãëJËËVÕ}¬üg£´e±“S`'¿òê#šºÞìjù·Åzò?ªR5!Ö˽ ŽÌÕ“üO¾ò•¤¶F…lëÕy†o5®ª¼Äm’úšV²°9[ؽå3¹§%6o²éýßö-ÖœÈöø‰[iŒt™§é£7<õö‰²Q¨Ý20æjHCåmíìù©Ö©À®@,íALŽ^ˆV<|VeS‚i{× ZòâXJ7òx†~ÝžFôC^¬a&!06×+ß!^̯~O´ÙÒNŸÐe3ÔYMáQ?òúñô,+ ™— 3‰]à‡c nÐ&¢>ORÃmÆûüÅû |ŒEX”¸w8fYl-¹Àï¯.Ý?÷¥2¬êT»ÏûÅ­áj'š¯•LåáZh|h¡ï#)>ÎÆX?t¯èe­[Ód•û(ùkÔ4ï,3#[)>Ÿ»ŽÃÁìžZQVª3uß÷Ò|+™Ñª`¹.öTÐÁ ¸'Tx¾”ÇŸÛ {Cr<%ÊÜ0æY™Â>¢Žô˜£®»—‰ÍÁµLí#ü ®ò²ÌdÓš&Šk§ –˜<§bsÄ.ÁºT1ge¦T´V¤ÒA·|±nY˜£Æ”ÏQ?®K¡r|úx†£êaù0–ýE.ü•p¸ˆÕšÂ¥ó§!ò¼Èp%©í?¼¹]çOŸì5ÚÑ Žìe®Ô»À¸ŠÕ¶lK™þ莿~r¹Þ Ý-tÑRöo(àœVÀ)÷RžGô}È{8ð¬/£@‰qvh\‘)¾Ï©œ›õÙ}¯˯whtòåPÝBøBâe,x®½ >Å…©ª›Þ÷D'ù˜Á›ûEZ@ÁOl¹ t¿Än3좬øD—Uöêƒïª]‘—.U‡Õ€í—¨û]дÿEÔ¼Å(½<‚N‡ówG‘²EúÐó.‹æ¨F¦u®9­-œÎú†ÌFë ι…·qØŽÌÑâ l³a&,ÏÕ±ŽÓz"¯Q^‚… \ð¢gÙq´×ö}JZ¨ÝW͘ٹ{’í+(Rì>-¿%ÜêÂa³Ù²NciÙÜ›$‹Ó¡¤i5¥ìF§´—;9tYœÄg_Q»‡íú7±¥¸ê nœ³gKð%mj)ËשÏE2ÌEù`ï³ l;®ÚãÐH÷•ÞUÒL†‹‚-óK†·™‡,"‹Ôæù ÐØJký¼#·rƒ ”y|kŒ‘^¯r“½r Ï&yBÚþk.±ì µåêô8ñEŸÃ`âfÆp½Êx©È_!qMZäÂ?±MÝ ´`Ÿ Œ‰_œ¤?/`mwä™·)Øûüˆ¯]ßkÆQàzP²èá0¾5"fÊ!´BqíI{ýF´²g) ;,š/”õ"¢÷ÛFœÔŒ7ÆV§rãÑ?ãüDÒ%È B QR®³ˆô£ÞJœÉG´ÈqºðÔ‘Yv¥xH±rþÊ(0™t5¤¿<²0Æ¢¼=îp = R³­XÉçy8çɵT{Ï´oõ!K[5çÆÊ8‘f£ÅÇœþ>˜G°ž9A“¯×“GqL Wx,µù(q#ú´ìÄ&ìøè „ˆa»¢×Íš¼íxSD·Xó¼ÚR'5“‘ŸôÞty’ ¬W ®Û"?Öúf…|˜•gä8÷d½NÎ%9óZÜ5Û7?v,bmª…M)cëÅì2Bª¥3ä껲IØT]cšbÑó¾³ýöHjòd‹Wˆ—a˜Ô_?Mc4ëëIÒ¢õ~ÇT`¨½RÞ î’7 õ¦WF1æ×ŪXŸf’d+Ìw@ ÚQÐ~X®.qÓP|tÝZ´Þ—Äoò—QÍÁ1nÀ\?>´ppÌ ¼Ñ«Ú[x0 ¯Ñ˜’ûت#íû-¢qfÇuç)q€¶™à¯µòÞ!h«¦´K…e [nïÅÁ s¼`3iJMÃ*³ñ¼ç1å쌃[›Túëà4ò5 &Ÿ 6¿æÞdÖç¹<Ïj…k—sBí’Òr;Òám›^‘Æ/V<žŸà ÎðÏ9Ð[,²ì¸´5’¬kî1ΞZNÅR@²A;±D$s8‘™m•Ÿ3{àE«%Å;µ1íì-Þ¹jш='¡+ºɽ1Db|ÝC)'^ìä-~HI5Ž´Æ:n@+=¿<Äy±wt€59\^\1–wÔ8Œn£IDÊÏä¼ @Ód˜ŽR‘?kT8ß„ »ù…|ÐT ½o/(zõËs|ÊŒ ¶ù”y<4¾rbFÛÇÙÐ/óWn‹{$ÆIqz],ùSíÏzòÆÉtKX„›AN,½Uw{þ¼ƒÔ‘Œî…“!ºÏ4§´Ü>lc„ï¼)Y¿7=7Í=̽{.RöÈi~41¬U—L·ó¾‹<…—à†¯ƒmµñ•T§|*ÿ‰;ÍZˆÞ9uÓ´×Î PŠ|*—zcF®UŠ2ÂÂó*~€•rŠºÆ%Žâ~q¢¤OØ'é‹TØ¡Ä9¾6…@ærÀy2Ϲb8¿Úâ÷P èu¡}X¿(&,9N¡!Þ·ßX+¿R˜{Y¬äA½¶l¢ éád¦APVÓÂÆy%XC²ÈõFÞåS6Íû¾2{E¾‡‹«ã ÒˆXêÛú„_c‹ü¹ÔVá ÅTÊÌÃo%+ ®µ†^q6êñÇèÒéÆÖ¯Cã\SEiu*mþ„:?·Ø‘æ /†áó”6ï´¦«ãëD”4Lµ7wH¾äy4ÜÙ¯¯§¹}_w0°Ùçø«©åÂbÛŸŽÊÀ†|ƒ±Á¼v·/ÙIK±6á6nšÂ‹ç”š Ü8Èk \—Äïõeá8ar$Úü4¿58 qZV="Ž3ØÒX+[¿JÄ9 ôŸ¸ÐÏ¥VÌïå ¤¤Ü¬®SVÒªhòo5*cèø’†}|å3e@Â1dˆVË,U,v“”_FµOvÓÃB)={ËL\Ámüî§7í²—HÈ[L"RÏ×EujÄë“Ôè|xwø”¾œÌYë]ˆ•«XÈ@%Y®í™ã›q¿9àÖjšRá[±žd!u˜X¢¤ÞЃqØhX—WŸÀ6îÞô¹K?;®•CÍ1 ™ŽhYíÖ¢ŽhK¼ nfƒ®æŸ4ÞŽd¿´öôÔšyéQ R¸:{<ÛÓæ+†‡S.©ŠåêoDk8šÛÜþº~}!Æ´ÎDξe tÅP°žØ¶Ò{®îV8? ÊÙpÁ;«ísM¨Óìö]PŽïC‚•Ÿ_N}f¿ÉQáÉ{ãjä&½8q½P‰hÁ$8ç_¥õùNÛýóM!/Õ#¨äõ1Ëgš¼»…«¾ò;“–‰Üþ3›jt6cñxÉ’2Ÿþ—µz5*\_×ñÅÞuYecæ½2OÔ©­ëû¿†¼‡j™£lAˆóŒ·ÄJîñ©-éoÌ:iÚ¸ëk]]ÈçîDt¹û…W/ÓZÀ¶eŠ/ ÊûxFs<`4ðM-î¢òûBÎu÷&ßîÎE4g?ŒUk\Å8”˜T*N&Ù1è_WWäi‹ÍsË´Ì£9GÀÕÖ] XS‰c ćQ=Å MÝ”·`–Dë:v\á÷åXúX¼ìenbÁâ©1÷ Ù5:,TÒ”þHœÚ™Ñd Od r‘ëHÊ¿<1aD¥ÚñEVVß¿“NþÙðÊ2¶Ðà8«Ê÷t¾èQËdû‚«¹Cøm6´û…Г† ª‘7(«NhÄÅ‘½ êzóV_ ïÕáK¢ß…Ûf;“V²•bm©u N ;ѵ>ÒI—T¬w> «þÙCÿI´¹p:r8´ºåèÙÕî0™åÎfO 9Òé£" ¯ÖÅ7ÎÕ eíƒLéÍÛܬø‹oÇ–íÍ^dJ$\fÂà{dà^Ù^m˜#Å®KŽh'«ïù`.·Ö`ÿ²gœò)Ū:¬|V²ä?æï&N+CAaý™áÝ-+4Ú­8&Î>O® ˜BÒDÓˆt¼y­ ¥M²ÒšE¸Jïµ}p¤>­uuqØÅ‡Ié .U³¥pŽq®Õ,ÄmÚôˆÝS~«%NQ€r,a`Ÿ‘ O¬g÷ùø¤ÁL¦Î†U“Ú•$ô6øñt8=n²ÆÐ¸¶íÞ>®.p0ÿ,BºV}‰AL†Ñ/ÜÝøÁ‡.×Jq嫳ÉÖî¥Gñr}ùÙ&{O1ë"rÑ *…úщð4lºøXtÚ…°.ÏÚš¦#ؼ]Óp<ÕW¹#ªš™Giˆ`yí"•ñ‡(!MÎkñ°6a-ϾuÖÔô&¦¦¼Jîywˆ¤N»…mVáaSR»ºv¥;¸7ž»=ÇŠÅ4º,l3Ì|¨.…vðM¥m‡o0'¹"æëájöÃæ©8£fÔuè 4‹²ëXAKÞÕ~‚ýÄwç‰rÔNÖYFK¾è#pŒòlM“ok½R…ß•,ÖWÓEµ4x¦/‘¡Ž¸ð‰'¸ŸýØ·9ƒÎ¢È["•;ƒ`Xî‘‘Áÿ°@v6^Ú¶Ýf‡Rãä¤,ËïrK—gÌ®ÍØ4€ÖÐnŽADªˆ~8:g…AŽÞù£?æhM„,¨r?â×bF+/6-’¿òô.S>^é1Ò¼B˜+õM-Ÿ-€·œ(øfo€CϬ–ñ†Ï*ôçUа†Ñ‡ÂÇ‘>[O)ÞÂQìbÕÊK~y´õ:!Z‘³ªs :AõÑ”1Ïž — ÕsŒ|s…Ôã{¨^Œ0y4çt’^ >ÅӮ镟ѺЎýÓ`>ÛXJÚ§ÀØ3œ‹ó¶y ¦Ó׸dLÀŠÿ¨ú5¾5öšŠ —î ÁO ÷¸^¥Kß¶tƒpÏD¯%êÒ|?fä²ÒOÔŠ /gmÑ3'CH~ÙÑg™¥o…“Âw•-rR.-q©ùCÍ~'›†Æç ¦TȦiU%´mÜt½o ܸ/šwÒÉVNÜâQCO\ûé0݉ÙMÅøÅÜŽ¿ë€2R4el?,ÙÀ‡v†Îp!.2ÃKË+÷´xDT~³ì{ŸeƒHžKääŠÓû‚‡ÇEjüáa¼›û¨T¥_®g/ÐïsÃ/¿¡¤SfûüR$Áº²òG¬Ûž/]î–Hª€¶OòÌJ¾N«e„4y©{F~˹î@”¼:§ÔØÈS(Qf·”Dºm…òàu~F}®®8  N÷Së%P,m:Á±·ÀòiA#»wõÀµ;|ɺÊÈJ¶6Pgfí£~kêíâ7$þ&}þK5dz½bÁÏøÙa»£^w‚BädT5׉ç…Œš{Ÿ¶¢[T’£…ÐYÝpv”½ÑÜ>G&ݽ!ù‘˜žëB#6~ªãCç$]\V%Œtð9]—žžÅUÔ ¤¹é¶5÷s0kô£Mn—hô~hƒgwrÛX×ÜÆs0)ƒ°šì÷”²I.:ôè–ìõ a¼ä³Òp ùÉ.ÂQUDT0¡1uC.¼ø.Jðžû³AuücÄ +=õ6nŽHwY¦¼š¤Y1šmÃ+Úúò2NÚ[*t)R@»Ä¶ž˜’JåÔÝÐê•ˬ¦â£¾ºšc‚̱áç”G‹|•ËïäìYaCò¸NØo^žöŸ•Õ^¯RÖx"só‡Ý!píº=ô‡ß“!=ͧyåDÏ—óÏ#Iª&µWè{ãhµú5´ý0E E‡ž XÀ NA¶ï¼¤]Á¶þ6Jä"<í™áá;Ñ\T€oZ¦ßQ·LƒíFl‹¨é% ŸÚ¸š¤T_SÜ€Ö#0£y­€ÆÔr48Ï3Ç:½’@ï®´Jzš t!I“î¥Ö7«ÆN(–ˆd)õ¿³¹eÜž€áÞ4ë–KÄ_®;™„ȳ ¬Ê¢°tÇú°ÜÖVáW˜Œ$ø÷À.¹âôK|©¶f?À+NMØ?u©¾ÁæéâéIÂÑ÷žWXTÀ<9À`å2ògGMÔ, Ís­Ñ•ÈJäÔ´ž2¿Gdê-¡Ò}Õø->í\ÑeFä¼!Øœûõ%ù¸‰G\ ËÛ£aÅ::5È2á={ö÷úÍZ‰æü af;›‡êŸ%†÷®€Cô]ö[[0·9‘¶y×§å³%Á2…M>®§[¢ ¨–ygFxQTæ(wO•9!5ýA[”ñÜòlÅÈ $Yª@¬ŒXºÑ:£Í;7[Iž°ØîBù_êškãá/»«l<" ÞX¦”w^`ù¾·¥=æ)Iêhóßw×Ò»÷o`‚3Á‰ ëåïPtI¡é¶-¿Á}…ዜ*ìÿZ¡,D›D±™@Xt!†’>QD™‰èòPbʆ¸«üîîÆª’ÙHóÔ¶Å«%²Õ˜:m§kfmªC;Ó˜½"!yhñÆ\‹àMyä * Èqó9|.^<ñ{j/ë"…ë£Îµñ矖k1NµÑÑÝЃ=øW®üТio§ E†ìíKÖ{S"~ n:½g>.œGÞVí"ià«Oèdf¸PªO¿ÕRTÙ3Š-e/…ñ  KY™R’#]Š£’ô¡vófõfÚ+©Ç‘&}à‡`‰Ý'd´ü…ÏщNêaޝÃ&x¥âÌŒKÓòêºÚn5j1÷2ʆ¨Ÿz>~ÂË‹ÄÑ–ß“[—‹  öÞ|VFçV<î°Øf2jjƒ’“•6)\™}Œ¤Íñ8hNT¸ºŸñ榜’;”è)G%kï.ÎÅ­ OXG’©$ëÀÂÿ©©›]îií±ƒúˆ½¯ÍÍÓZÿaËÇFÌ_)"¨fþt{Ïgx¹+B]ÿ…¦ ažÔ¶:ÿTJšÐ¬úV>»æ¸½®1˜ãÝU”úyš³G³ùäaŠrЍw„Fyª®ÒNK‹7ƒØ$Ë=þq¯·W£å«ªÉÁ=»Yã…ûñ‚ݬå$­Š!Þ,ÏÔ ÁÇaþÓE—m$Ãõã¬'™<ÖÒ±2õo™}>QÏ‚§Å¶-ºO4CoFc°[ƒVºØ,¾š÷ä¶ŽžEuÖ¬:Ë8ðÚìP³¨pjh^Á¾ß!B½jóË 'MV&îѺ¢Æ£ç¸©é3,èw›Ç­ÑèÎFsõÜóJäJ ÷H$Lú¼¹4áFe¹uX·S¦E&õ2ñŸ¨ÁŽ_{O8™Gï7ìʵBɵ[¯ 'º %±ç2¼ï^œ˜°¾øu®+«f^ž{ÃEuòôCª3ü&ùßq,nz9÷i^CÙ¤`+…Ò_ý¥Y¼'9`¡&L”g>¸©+§ÿu‘d*Ì¥µ62VÛ…8û`ßþTî“5ŒûÀmZ_ÔžwÈÅG‹'ƒôeËY´IÌ~g‘3¿Aö _FM5€?;Ãù¬ûUkî#> UYSDºÊê>­Ù¢IZ÷8ÕŽ÷þ>òóÛ!â°\Ì7¸eŽb±ð_DJBlÔÞëýs²T¼yù9Q>°ú:qÌf*p ¨ˆ¤Ñh‘t¥DÊ/iaeÛáÅR/:²Cz#6½nÿþ¥XP†‡&FŒ¦dô–¤«S£KÈͯpýöüÁïö𯗲ŽÂ³ôÜ‹$bR¿äîúGTº›%AÉ"ö,\ ø!I¶ÊöÕêïœT‹DQ”ËYþB¸ÇÛôÖRÚ51ùá-ƒV°ø´9®ö£ö•ñ;zÁgË׺°´*‚ZŸÔ&Š|±¿ÕíÄçNh§˜-ë …à³w\üo½3aysqYjm›ìêǪ—¿‹1hç]É|“¡^Ô°ôœç@¡1LÚ8ÁÝFmÓûe#ZÀýàËAEJ‡Î_“Û³3Ü8ßGP GA3aÓj.¯w÷˜ypÀÎP0ƒ¬m˧½Ó:JžzêÄ^OEe@h¢¬êÌã‡}&#}í`zö¾=0²À/áÞõµ {4Nâ›zihn9óÀ2wÃhtU¹¸#ztΠ&YXÃÁ˜ÔÑO({µíšûg®ºkÁ« &)(.ÁBE-8S1Š‹(‡7qÞÚ Ã‚úf6'5¯§o-SÕ6ÃG‹RÈÎ%îŽèøsÆa6µ]¾4{Ò? _‡®Z&Õ³¬¥2 Æ<(½f€Ý¦Ä ÉÖtŽΊ?ÞÎ×ÅæÜi)Ê4œE®¦:ëf»c:çê–jÀM…=_è,ÁŠ:>6²V6wÒ½úD)1·à†b¦Oû\ý°ú-ˆï` Ç4Ø»°79ö‘:EšgŠÓ[ÆEðX®Æÿ¥$Ødu«¤ 7ˆFô3xŠ;ž?vî¨éóáÂöá]Þxt¿Ð/°ŽÛbS‚«°ÕƾJožì«Þb_V¥7¬³¡¤ª1#ScÐÅûˆ³”7¤†²ç8A¤Ö€ˆÊ&•7Ÿ3ÒÃês³ý·çÅeÜŠ¤*ÝÙy÷v%ÀqrÏÑŽKºÚÐì4uÒ7Ïš6¯úGXLkÝ÷ öómæˆí¡‚šô“ô7XV-fsÚˆádµnÝaôÏÑ÷`?G.yÿ’Ϻ¬DH1UŠy7 %Ïãºà|is?l9û¸Dz3\a¢¢úûÅs“ÄÄ»‚þbt6òõ¤VfW!NükšƒŽnÑu c´]ßÉu„ÃÏfb]/¬¯$]jOsËG’vžn™m⾜¿õÉ}Þ#A¾Ž›Âµ@¹À‚ª%\—ØædWΛ®¬Ô9´£ˆ™-ìíÁ¨l¹ÕÚS›$±óLxÓA;:¤DêU…=†Mì–NÿMŽË·èÄÆÓH-úÕëÙìDc[qÃT¢¾w®­‹àöòµÍ˜ñVaéD|a6™ÕÅ-=Lò>êbÙþ/nLZ.ÐÐnNòzŒ$šë¸›Xéjd=„,ˆïè}~8.ü^m˜sƒX9ãyÈ@ÑØîÝóš_ã&‚ŒÖçï¶ŠÛó€ô6²6½ ‹Ó>šÕ½_±-ì)¸˜ôV;Žñ’ „¹«¯ W»hm¢tòÏ›ðŸ_ΧùŸ5•”¸DÕOøøŽñ‚ÜgDw~àÕ‘=Û'έ檦Zs ­Ñ°Cª^ |‡+Ÿí~wilž…â|uYI¡} ›Mök¨STî–¾G;ë;»†m(«’@+TèêÛkÑl|9Q_È»ƒˆj[`t€sZÃÝ>üFÙ.à Àú½¦Ÿ@ÌðÓè4ºÁ¥9–Ijû‡vU!öŠ«u¸°\õA¼‘öÃÓdÊ­³O‡ÕàsBoc²d£1†oÛ6Ýâeßµë¯Ò•e °Ü’‹²BS;…ÆÞØu&iêi$Îר!_ÉŠüùÜ3yäåq#=Vk=·™€¹Y;ŠIͱk]x€úô8lä(*KñÙàRyjyçj63JŠ1»È2Çc<¨RÿûžŒã‚0¬X³Ô° ï tªóØÔ¾ügW\[~õZ¸s~®CAÎÒƒd´ š_GÝ*šT¤/²~@â¹Íµ0[ÃI†…U´_ì%:³aU©+ ‘dLbµbjÉh%ÉþÄDßÐ8¶ÏTøý*žôùV ‘Ƶ‡‹%µ%ña}Uýë|’—ÏIC÷VÉ”}÷Ü6Ñ÷$> 9«‚ns;ówBÃʤ¦ðìœzn,xZD*hõdo<²Œœ&JªB½ç­Œ8³O6ÒüC–0C¡ù ÷mŠÖAr­q-ÎÕô±¾lQrAÝŸúÉúaç¿€<Ãæ¾Õ®8Ì–›¯äšf«Ù4j•oØóÕ3 ý(ÄI(\3ë±óïÙ÷‰Õî´Jð¼D¦Äîû‰uã´ãزP6n‰òÌo¸]Œ…(,à¶ÏÓ5ÓØqšÓï2ÄÙ®e|fÔÙ[¨ªòÐF08ÝðyõŸöĦÏ~6LxÌÛI´î­‰ŠxÑä ‘êO!ÉRºY¬w‹xâdŽK|óã±L# ï½ü)3â{ÑÉ¹î ½îÕd £LÕN¡ÛSÂîãv,Œ¢ÔnÓ¬ÁK¥ì1)‘ªÏ˜*‡…Þ=g<­{Ì2½iè7ÃÍj»YùLƒUcî~mO$žË²=j“@ÁGrXÿ€QÎÙüž y‰Ëhfåû <¯ï\¥,n±T/¼‹Kºãòšâi·M$ÓÈâÌq}±QuL({6j2«eNMƒrÉ|¯m¿¾ˆi°Á :Öõõ%ÜÙXg‹»Ê›+>î‘φnBÉnï`ˆ÷Ç0“·C‘抙΀ùû¨À:‘ùŽ·ê2äT ùy\LG•¤.ó(‚ó Ÿ_îˆnÚçá¼J fï×U¢Å¤LùCÎÂ6²ý«¨L6ŠÛ‡¡Ò„ÁMùÃ#1!¥rˆ›Zuoo>ë8w`Ÿ&b]–—ž—ïf@q s I®ÊÊZï”Hò$—n±MTé ïdœ£}KúEzúq³=Ç¥3³!$]{UfñòžYŸÊ)W#)®?‘‡ ½ ÷©hiÀDýLÍsm»žéЉ# ø€CœYö‹ …XÙ(­åŽ>qôò¹^øl4ùN5â¬ç Ñ®Àð¦Ô2œ Lo¸ô{ú´>Ø¥o¢øÅ\Óª-8ä?Vºê‹®QÅÄóÓQÌ·»]øßöÞž½À¿Ó[g=0ìB‘ŽÁ0ïÿµÅ>–â^íjœOÓ*¦É´Šµ·â;p<—J®hàpªÐ´Ûš=jº aÞ”¼û†!Py5"¿îLIb><ˆŠú+ÖŒÏÙíŠàæöc忬¡Y»#s êË“Öe9ùû]Ê•qQ4X,ý !rÌ$ùq¥Împ¼1u¦Ibîy%Ôq”G]ÌßyÄ&Œ]-\Nœ™¼_ýøŠ† T ¥x†bC;¡ÔmæÇ ÿEá$4H{7æÃCS’“ìJõB›è¯õ¶øÜï\èk2m€iøÒ •³ó6#§<úw´éSö»äå¤I°Í”¼–nUmYsÚQá1m4¡'+c^e³äØí}_[Nl°;š"÷pµù^>\¬°ˆù~&àØ.&z-Õ(}Í(cŇÇEo7~Ô :úŽ €möxl?ʧ«™¾ášpåÔRWSˆ{o7vG½)vã;¸Ú„Ù ºyÚ`N^3füó¹ÄÕz­LZ½2š zÙn£‹ §wz­kokéÕÖŒ±¥ T'ŠÕŽg/* í5Ã1c‚5Ñ 9PxM´éÃØŒõNÁ¯b<)Ê\ãgn¾ßa+Ôï£Mµ\ÍØ<\qiW1×½ÿ•ólœ1îæ¯É—yŒÇ„q(ƒE·€õ`<øåHw\ŒB‡Ø6D·Qh$¯Â-K-²Þ`ñ®Èù¤ƒ—&H¹9¦·„û¾…=Ô„±î´§>ƒï»NrÈ+ÿåñ5Ücò ÂÌE¤éJñbI¿3| ELf@ÊüÔr)Sõ@ä¾Åˆ‡\•÷¤}Ô#ƈ±Y÷¼o9|6ó{,Jg•†˜܆ø\g³'Ž/Ñ,ì(ëžÛ~†ÂP‡Äš€6Ð)b–Ó¿\°.6eõwéx%ÕütF<Õ¾´~èöCámEÀYn'©Ôi¿WEÛv@ “ƼTî<9ŸOaŸ¿PpÚô:Õñ4Y^™ˆ²òÒR8íÿQo°e OYU‚éÁž®yüž ¼h1êLè˨°xø ' 7ÎÝ/ûL¯03!úOR[(…œù0õÅ#“7ò¢­`£4Û¶Ÿy3•µÛSÎ¥Rc= §U“fìñ€úÖgà-¬£ªT-‹R•–ó’;üšú$ÒÝO£ƒzƒx-¸vAfMÙN)n»L¿µo~nó°o¯p÷Œü¾¬Ñ¿âºõý ½Í&^”"Å»(5øŽÇÓ8zÅzK¼+? ­*qƒ’އV:t>‰’m â¹`ú"IwXžÿÙaîPdáYÆ*IZ6À˜ë]ë„ËvNÄC>ä@Æ^4¤‡Ö#ð­9Þ ‡nÌua™&ò‰¤üé=ûbŽ}@ËÔ¹˜U×Ý¡‰mëgåqšýÝç;O+î(ÿ¢OúÉ”¥wPíz†­,¯bËúR­÷ˆ[ÉV™nÁ1L7Z>Eãή9ÌÔýZ?ôC;Œhôiõ™·ñ$eVZæ·Ž_¢¨Þq}´FÊÈP<ï;æŸÆ#v[£eˆmŵÕVÃý„ÌžÊb”Q]øµÑ¨‹)Âr*Y"{¿“æËk± ¦GsËI AWãø–ªÌ8ÖÑݪVƒÌ½Ëú Îk·Œ$b³ múÎ2œ ¤#’}Ó¾­‘]ÎÇÒ a¯Ô‘°ÖJ²[xKïb Þ*‹”€æCg®Q¢ObBÆÄ¸N¶™÷¢¸3¨‘ñXÍêž™]êLJk%Môù'e/‡°l¨mbƒ„$£ ¼"¡ÆÈuÚ§éîÊù»ÂXMiš^L÷. ci_btWTNÅjᯂŸÊÕýrÔ:'ÊÔ rÁÞ}?º(XD²Îpœñtþw4Ün‰98uÎÙ%.E»þ•"5P›¸m$rà)$ͶkªÐA¸g.®FßäYRÑP òGQù“Ä’[ˆ‡M£½‡R߀„Ey_­†0]›š™ÀŸbò)lpþü©Çæ…Ó_Ìã ˜…Q[K».pÁØ_Çúñ¶j‡&èÃÌÇ ô¥–~{¡œ;„®²ÓÓg4"®©¼b /-¯Íò»ù€“§Y2¬ ¥¶Œ—ôÞü™ë¯³°ñ:H ð–[& [ïU¢_Õ·¯$é‚…9j>Æ€m¼ÒÙWñ¿|¨€ò랥[Â~ òÛ;E‡_‘ÉBK«DeeËånž^Úo<µ\¤±`…q/±DÐ4Ò“pIk â½éiO>þLM¶"±)DüñÉcõ™¢²ä¡W¨"kà|n Ÿ-¯Ws”°­ª¦Æ)ºá½ÏÜú±ÄÏ©ç˜wËŽþä–ú11°ñ™S¥ç%€Ð"6N0‹ùxìD7ž}?šPò–ø‹¡½t˜ÆKp.Ø·œ³:Ôå£X/Èý Ï_9ªdÿ]•a›éu­¾“É›•âmnÉOè¢?x‹?þªx®zÊǾ~â}yz·˜)¡ ÔP€‘)ï·i¸PÀ?8X}ù©¢+Žá4ðà"*KçÌE Ó<ôk† ”Ý‹ˆæ½çÖtè„£1£¤ƒÂtå‰M(—‡¯ý•Úªø^`Hš˜Ûó@:{ÝÑûtòëR:íc5îié«!†gþ¡ž¬®f+yˆ¯ñb­Ôy­bÙ›Ew5ÉMÝ¡jù‡!e–Úúˆ|@½©ƒnÕ¨œoÀF(ž¹ð­îfk÷ˆÉ›\/ÖÈaÅbYm¬’R¹)`/ Ž%/tMu½Ù ­ñdërlô¢6JVÁP÷àÞóñ•âÌ"F•ƒî.ïÓ­,8Ý"ž:8Žé®½ý’Í)æC%A,>yõm<Ä_ëé0Î,Æ@ kø˜iöâµ  ÑAêb5Bjòµ¯»u×+·ke²O´ØV–ÃÀ KOp”f2»$AâJ|{æv––„·½–Êv`)[6H{]^qªïYn¡ÆöVÛ|îÄC9ì¹ÝCRÀÕ‰2ZýÞ¦E‡³Ÿ}^úìÍé8g ŽÈ¢ö}š4PuáSá0n¢N–¦ÈºVdœÝóhµª.\):zÚóW7Ÿ>îgk'øÙèã)îÒßnàˆæJa UC+/G£ô c ¿TŽ·t,¿4ê‘ê•BÉ}B;JÓåÌ ðžüÜÓF#úÚ6”ž¦Ë\J}`py^ÈSÏF¼aD[ÝŸ$Ñ5LíX¥W€.Щí¯mUyÜ:¼*Þ‘ÃØÆ6xãf"ã Ò£%¼¡W›G=µÍ¡ªZõoô¢M/+e\þøÐ¶43(Ÿ¼¾àŒù^žW5ÃçþÁ´r—Hûÿ k”ã5œJ )>Žö`yEÚD4L0íFsoIܨüLÉ¢À„ ÌãÙü±q„ÉmÊëLŠR<Ö[y¼T˜ç#QIRý›¡ê£UÛ&`\¶|ÇöÉ¡·IiÚ¡ šÇ¹lzÓRµÄ9xrí ıýàÂw†èÙDÎåžèqñJUÑÈ<¬çíÏ‘½x&b´8pÕ’¯,ù‘F ² âWÎÉ30¡IÅÙW* ¶rõ9ã…ZR$æi‚¼ B£I}æPΞlÍÔ#>Çո߭µ0<ÐØ9øsnçâc5Ú $ªò|¨ÐA&/ÑKᆡ{[–j/‚ÒzçØ É†O"­]3£ ^882™uWiÉCp´ãÅd'ÀDsm¸wIѶó—A=ùl¶b³“¢3Xºå/í;'$cÐ¥l¦¢°}–A¯Š‡0›ú‚DN^ás5°ž°pøw9k¨8 Dm}>”gY<¼fÌÜRÕCDé—wm¨ièöEÿò^ÛJÏçh¸HÕb­³?éê+Wûý9TyP¯Q¨:?u_»…Bk´2Ëb¹?`ÍÅûf&•1ô¥5ÀíC6jn=ÈÆõ+ÌÙëeKñ R¡–Â0`µâ1á£ÓØpjS´qüÓsÉ~iÚlëÐy¶7vÊ+@ N'šªT¨ ¨áhÙwí_xnŒc^¸½QK×i.ͦUO|YeŒw°nf ê³ÛXuÇ›$6hÔ’ L¯YúÌ€ODZ’Î}U Â宅ÖI!Üç‰Âì3+…QÓhHZ•xâ Ê0#7‹ž¶Ê7cùœ)ǘÕäû“@#ó}«^¨†ÕŠ1¬æ1é9ƒU<ƒ ËC²cqP÷OÀ~†!˜«Uª5ßž†]|;—r„å þõ¨\ƒéÄ-RàœgŒQ R•€þZH‡Ò´@ö†í7õ¸;Ìh.1.Ç«´NNÔ‡ü4S¢ßÒ¼Hä… ²óêJƆ“ü¾Òí†û€>jE¶Xnã,›Å”iøç8}¸ÉRA€è<æðß ŸÙs¡Zº… ½Ï9õŸ,–ѲüŒP7«€!ÿ~+ð©^†SóB=7{I«¿ì§0;¦:*/ _†ŸŠ¤b³ˆ:g:—c(áð×$€UænÔû-´Þ…8"ÆÞ äQÀ¾Ö¶EÓôð„ß‚àÓg  íÀªâêä5U•õ¢¾Èœ):ÖË$C=:Ë®ÌG»è'–8 #ÎF_ýdœ<…¶ã3ÍÈ×­8ÀïDÀÿ2ðcd >¹v­< 2zá`’ç'Ë+ª(™^·É ˆý‘=w¶AØÌõªY’}«KÞÑB0e Ò®BQy—ÿ~Ö”ÿ¦d.Ú1#7¾d*Oèm˰i À£”èp× yÂ:ÙOýåÍÝo'3ö‹v„üjCDG¬mÏ7—Ïè_µ[V¬£ ƒÄ(nÍb$òS®vmÖùÿgÌàk³éeНâ6=\8'Þ¢r‚mó.–q…;Åà˜ÉP…éðƽ1MÃãì»3â)Lˆigs3Ñ¢.+T*»ÌKŠëµíï ïfb‡4dYN¿X ³Šc1îª ÂGcžTU\úæ„6™äÃ9O­4yºÿ¶€©9;vWžV¢écªËžtHQH kbv‡ÓîJ¶J¦n|{âçÈ%),@7·¬§‰êçDØ’w;è ûh˜¶¦?i"IC ü=„ÝòO€Ð—[Äj,SÒ &_è¦B•¼‘ =áuVäD·K³! 3c²¯ºü1š–=îæë<ÇŠÓÚÊÈg©6O%Ò;Ȫßyd¹Ù2mMœs°Šƒ_—Só69 ®|z`÷ëóMäl%ìëYŸ­ñû…ådaú0$t^ ¾‰üÉk3᥵Ä%ik~’Vxûôœ7£Q7-Û—«düͦø)3®Fý«“ô¤u%¹gõ¼6wScŠ•ñe2 ÒGÈÀ£ÁEDðh4=>Ì9¶‚3P†"á¶õø¤Šœ˜³MyÈ@WAoâÒch¼´$T½]éÐÞß/ö4.£½(µ(xý;C¡xÈošdÒa£™.\.ýi%FÏãŽÝæ?Q#«à ÖOÚo,½˜³Âpõà·Á€ÇwúPÓéºÄ®<$f=×Â8‘âBË}«‚Ä´2ž\ÿаòéÕÏUÔ&™`\äÊ÷ìåTøAyÖ õ&IHrf¹q¶Ï_Bw.‘ˤR¨ßˆ<¯£øÅYí‹xfæÓ«–‚u K³Gð£æGdØ5wÿµ yv¥½€6𫺿æüKå^Ì[¢§£Å»2îðÊ»†+mÀœIãv?Ú)á„’¿3i4DîÄ *a`dûVÕOÅA)·ß ¾,g®×²O RŽÉdŠ9ŽùxÑljvF±ò¹w“~p·!@i `Ù„Cd§ô"Ù;E4øï·µcŒùPwŸ‚ê™TXün®{Ë¢Öqh`ød³w‚Ó{Kx'ëc[ûm\ŒfÃÑ„pL†4:ÃŽ.»›vœ‹Àá‚8X”>QÇNS‰ÜôC„^éäCe~Šñfÿ úoSçÂZ9lÝ—q¶•¾;Í«üIyÿÆÑv+…'Ëã8S°†¢-jXÁÜIØ0¶ôzÿdùÓCz®°ï_´üàY}™í4-àĵТÔ•!\*߯œNÔëd—åÿÃô/’˜NqT0ßu‚â–ƒ}ÑÌרŸ!pöAëöL»]aCÉä:ì³$³›šƒè¤„oØØ]º”áÊ löÁ"Âì»q \!žÝ)˜IBÎ>ZiùŸý÷}…Ô4én¬}:”¬5Kª‡R(:××JnŠêÁM\öûXeN‚b’m$áfª× O `J´5ä €ËÜ©`Ó‚,ö }ùlñÞ‡•Ž”x—GtÓ5Ú`Œ>s^Þga××"Û‚þаGVi|k‰À/“гۨBL»`Íytºx íi“z,õjõ·¨8ƒÞˆqb|×vlZ <ú@®áµ7FElÓ”»½“3 õ”x$¦x²iÊN)°WÀÀ…tƒ T¹[âÀä/캫¬!žmÝ2UéMÀ»þÐêýúâňF÷%L´ó§¼ ÀñaÝì !@)TŽËò½GòHA¥Z! ucÓæŸ¼ÌY$n^ïv£ë@¹uá§ SšU”ƒÊÞPð‘3Mío×Áü¢f–ê¸A|èz1íXp™£Ñv3éªDì·dž3GTI¼Ù62íµÀh0rao)ç Œ‚Å…E köÉBTÖ ´5ÂhÆ» Ó¢ˆà+‘sU{ПӇÅÙé­ÐqêÂc)z3f t"ú ¹ŒýؤôX%Žˆ- `”³‡5³ÖÎ(”¨‘/Çç"×ú>ˆ$9ñà8mÅbØÕcKu™6/Ü›õ®çWÎþOΰª×äê4µÇ¨çËØù­´­ê¬„ĉW‰úÒHsÌ,uÚ4sÚ²ƒ#2ô,Z‘ía¾M(Žôq+S#)glXÎõÌ(šõoÌÞìY|ä7¥/ѦmüÑ‹!\—ÓYKR#Nb:TZÜ›“ÑWÈ)"Oa'°õ© %áµ)èk FVb “{€3kÏúüqC;GµSY­@Ô‡þí5P±GÀJÕñ͇ykog!¬åñT0R·R®ÊŒf ‚õœ=çc3[ìݳ,vš c±/#76y+<Êç=ï?t8î.*DÔŸ~‘öÎF¼´Nï00aõZu!k™Ö–5N–’æ÷§µIÀxŽÑ€6Ú~*×B®âÀ¨É&ëåÀ‚eAÂWc‡âŒ3?Ù~ø\ïˆ xêhÛ-›çv‡Aù'±·ŠçqŠ• Ò¶Ž¦ÁT÷-Ô¢—„s–Ú7Ñì2Áˆó¡ÌyþQ ÿ1IGkã=ýö ©³»TÒØ3uWñÿöê½ _«äF^ä›±ôqŸ-´X-K^“ láu’ .dz[Xò¤‹ÄÔ£„Í»ûªª!ÇÚœŒ¨ÓÑ"ú³Sô_$¯-lÛB—WÒÂL“DÍ(ÚqXŽTUÚ¾­·Ý΋öd*8:ÙÚóéø@ÏÊíÜÚG QöçYý&îù·.~Os§mm‡T°zóy4W>Ô+¤ÞiÏúë ;²F¢ , ücŸx¤-`‡L À›«ªð¡ðª†m)l$Èb– ¨Ïë(#¤ãB‹šLxKv÷¥ÿy~èË&õ.T”%oî1ÇßÅhÓ–øFèTÇì“o’VQPÈSBÐÜEÍdäÁµÌ3gñÉÍQç²¼ìvRHÂøc»Z7!?rŸ.ÖÉ5Ü¿N¶.Çå"AWž˜ÕØB:Kƒk–– ¥ŠQpQqÆ›6ƒx 1y=ÃXŠZ ² |~{p”²7¦›žµJhýíDV-H:è0¾ [—ªNS- †CNwJêÌʯ´pV,¢èÆÜ\’Ò+$t®¤ž6gîšîq.í‚1Ž®½Ó†žØþ¼oâøÒÞØbš˜åF[úel4LCÚä~ÌfKÏp׿"Ö†œ †Ý¾TŒWþ©u[A¼uÀä*ø¢§µKðæƒ#Â8_×/ÞI$¡$V3ûzq  ž¢h•¸†rÁ=û QÛ…Xòæ¹âÿÆ[ÊR¶ó-í½˜Ï@’†aò×Ù'¡»€É­°Ÿ%“óµ–òJ€‰W½ø’µ€«¡*æÛJb¥WìPÝ(-ÑIõ¡ú 8ý"t…NY̽‰Ý3(ÃK};ò]ž 8 ½£EÔ¨"Y7o±®·-i©ÞÍ­"×#©×RüÁâÎñH˜B‚ ÉÒ;ÉJ3ÀL¯í9oh¤<Ö)÷a{ááÔ÷›ÍÁ!¼K•W.’ÖÂÓ¯ÆH½ÎQœ>9Ÿ‰Y`̰ªLå÷ ;ÇY4 jVó¥lB5ËZq?ßvÚ¾ÿ?‰¨íÕæº3ºùº“%Pé.òw=¯%žm%.N4»T7÷Vq–-•Šo·7qóPûž¥Z/›ëlæ]Eu›NÔ‰žÚ?­›:7€™2Á 4R¬£ubcþð8”Ó9]¤X¼&›¬Œ\ì ´Ó›9M[™Ô`Ãc3òtœZ¾¿Fêù¼=†ã`x2Ô".:MZ`™ÏÙSS¾ºe:õêé¶®5WZ#|–7¼:X×»–¯Ñ½?÷ð»û¨6æûDͽsž†ëfþ/O°Œ\×ì­7¼·v¥FÑRdiÒ6Ã{½$[Š‚–™ ƒŒÕ±ù8͈T°) ¾ˆøN!K!gkܤ¨O{p„ï)[Cï¯!y3ç 9"wGVPáðÁŒ>#Ùe~:äí À柬vhuJŒuyLb #0ý[¸õ¼Y¦cËy~ïªvÆ­]–nóWBIsäËpÊÿa%vÜ•æºeÛ¨”ö-O—}ÿŠÚè¡qkϻ唱e,èE=÷ÀcÕ×4H7`bíAmwÔØ Bßú "?뀫…‡ZQé»í<žš²¨§›Z‡ã‰­â¿âv—ÿœj˜ÀùN$?"Í.ˆ…°^@œva‚.z1©o”H9¨¹xXé•F‚a&Î¥f&)ÖoÂÛu¬Ûÿ{‰<ÃyI]´ÆÆçÿ.Wޏ](€ñꉚS$=;$ÔÔvrëEVåjŸVcwÒÞ1À ÿ]ÛPŸ‰è¸Á‘ðË\|IÔ |{¡ü—o G´ò« üT¦¹hznI(Màº!‘yùϼqfEFÕãûà(ÕÈzh zS/S­QïƒÞq¤ˆ9Þ×›ã‹ÇDˆrÞC#‰œc|ÈmñLKüš¯B ÌŠëX±$r¯"ùÉ™îÔr²Â¸[`¤Ðä8o2µ¼ˆQ«ÍÆnô¦7k[úé$7ˆEïþ>‹ÿ—ñ¶K¢×Àd{å•& · cpºÊ@ÀØbd@€j²gX3§!Ñt¦[Qãè© QŸZp¦ÈFzFú1, ÷ îW;Ûâ[uibšõ¼÷.7Q¿`ñgR«¾õ<±Ú›¼Ñ0Z;¤³)ܯ*–³[«g*¶]w¾,B“O¿ô„#5Û˜)»2¨ríQ’ƒ©KK\SÍø§f¿îšòÆÌ™úÒrnQ€i<}öá†=!¹lµá²Ad©}£†Y@Ê º%\aY`¬3J^<Ë/Êc”»þк/+ÜŸ40ý1áÝ'á”Øi²YݓϟQ¢PÚôòÿ”Ì Xžj'Ÿ¯§jÃØa°ãé8Þ2TàrE‘öØ ê“G›±CUw½Îõ‚Ȭù¿V¯Q³ 8 æn@‚°RèÈ£µzð{Ct™&kwýéÛä­C)ÙwØB©ïåsMHÉãžj™X©W¦‹jk©r°Bê„ÄB»)×r©u”_»dQ¤¥+yè,×a}¢X¡ FÞQ%ðã ße£7¦ |‚ÁË; wnšupGÆ*n>ÜœZO¤§ÕÎúO‰áýqí0\¹òKF‘aØ6À»£n‰:‡Ð:™ÍgwŽªñ¬$†¡³4uù©2í명¾ (¹z ×w7øO(ã t°¼_Îg*fJ^Dp¸1 KâŽHþà/¸„l†À IKúÅH«¨«·/ÀÇT{þ‡¶$=èÖ]™â"áK_‘,º„"z¾nßÈIÃ,‹Žó¸RåÝLuŸ¡@=ý~XèÄöãÞD6špWϯ¾¸8®öœ±‘âøüÿÑî~›±è‹Fߤ¨–q3>‹AºŽï'ý¨¨à»Ê £óÕ5Ü ‹)x_á¦üÍ*ª¤ð§²ŠbqA;§v|“êá`à±@×ç=o±Ç€øä7ýji¬q1Ø…4=mïSW‰>=± @ p»Ýv0Ú„°mgýqÄÜíóÏr‚<"Af%°À…%õú8>„nÓf–;Õz_eøœ Y) ±À½#ÉE4Œ÷0ˆ&â§Ó­'„í$f]ÌcÖgÒ¿R®î«šnÁšc˜›¯ƒQM€&ˆ…PìFç,ãèK4lXŸ,ö–·÷”@o‹@6øº&D½˜áጎ>d£\È'»“¡ØWv†ç7ÏEßú4™ž«Tç½Êû óx¨Êa!5‚”KîžÆã¯=½|ÞÀŒ©Rb0Uùî ocýá& Û1p“Üh¥6pfh>l̉¬ò¡ðº´Lu±î”SˆÃ+) jÓíøy‚½w2"’,_%~ð;ÉõÝE;88ù¤ªÂ:[¶úÁä'£•K{´`« ÔW;ÉÂÆUŽ›GÖÛƒDJ·e—”™äUØtÞ^œ{†ú$©«ò—0©œ‰Eò á+uâ€+»Œžè©Ùb]g—–`wÙW嬔'"îäFß±{y8G=U®jì¯:D_ €öEúà%ª¥Ö…!)3ÒBÌlìIR"zN4‰ƒ‚þEÙÏÛAP³ëé%È…guN€”Ù4$ìí7‘ûc ÍÛ¢LÓ]!mŠÎÐgœE4øZ ú/ ~ýÀZ[Úd‹‘ž³b®QY©02ÆÔSæ~6ÕßDWÏÈd¨˜8I)VdH¸Å_W’ÑOTφPèÇŸèÁ鋬x¯d6ìŠ]ί•Mÿ|9-æ+jµ°pdÀ|Î8s01M·è‡tbÏþ4æfüÚ²‡Ô°ŒIåz‹tÙÁ£¤#2 «/ÿÉ3D„€-ÅôÂHÁÄRË1æ¨Á73Ö7YºUÛ¤¶Ñ@9Ëð!)î?Æ„‘Ø`O;´T_Ÿ3DI™Õ_^í¤°þØš°¡gÜ·”,`ÚÙ"‘,†™í™ò¶UçáÖíçóña½C5±ò[ƒX©¤:²ÂásÓi Î(}ÍãbßœO]#z8ʬ6Gå2®†á”å=× wjŽzãÀ&u6íœO¿î¸ØDh1Æ©‚Æ7àè&ËÊ Ê™é×\­À²êrü´½¨%ÝØ*› ufÈŽÉQPâÖ€\N³é%`gB1IÙóRRËî ê5| Œ£_ë¢ÌÏŸªÐZûÅvÝÃeî~7šŒÇSÝïȧø_'¸mœ¤gÎC¸®N„0ïÖ¤ÖÚ8åO—-jwÚ-Ž˜Ú× á\~ åÆ3´ªÇj,2Ü,-¹y1ÔZSý( k„?"À"!·ýñ%¤¢“YN©‘ÎûsÔåaýÇ#iÈQûÚrà›ã‡–E ³Ò…¿ ®Hªk>Ï3´:eªR.~óüñƒŸ‹õSÒ½]W¤%ï.DVÕÐßE¯òå9‡w7áv¿7§äEê¿¥ÄÔHÄÆ….¦*ó:>+·“³†ÙÁËâ•íZéÔÆEPµˆµñ•3.bTUXn  Æù&„;¿õåWóú ÝP¡h{Ùó=2vGÜlGó­lÊ‹±?X^,Æ“AœKÝr['¥ó-´Þ7`!¿yõ§\¾ÈêÈámÞ6^ŽÌ̾³äæA;üA6ƒ‹Ï 0*¢Üac¸§ÿdvHÕ¢:aМ³§Ôî‹:·+–€CX*q~àk” –¼jØîlÁåvw3xR endstream endobj 224 0 obj << /Length1 2250 /Length2 14129 /Length3 0 /Length 15476 /Filter /FlateDecode >> stream xÚ͸eTœQ²6Škp÷‚»ÜÝÝCkÓ¸{$@pww÷à ¸»knÉÌ93gîwÖ½?ïb½«»ªvÕ~ªžªzWCC©¦É"nád’qr„°p°² ´@z²^`ìäÊ"ádo!ÚÛ˜8YÙÙ¹Qhh$Á ÄÆÉQ  ¸Ø!ÖUsÈk0€“ý @ä¿Z-f^e¨åå âÐÿ jN®3 ë«äheãbxu‘tröÛXYCþÄàcù`éþð ä 9º¾^ëú'¨+@hnçäájg:ZX•Y*N¯J½“#À d ´·8Yþ ¡­)­¡ ÕPÕVÓd`èØ€ Ž@+`n Í! °+ÀôzÐÂâ¸å€Ž-kÐët´f}…¨éæììþgV’šZÚ²Ì)q-iH‡ «­©Å PÑzUþµüõú ïhaüã®,­%®¥¯&ÍÁö§€ûë6þG:´¯Éþ•Í««%ØÉáïzkÄY€ÍÃÃÕÊÍÂê¶bu¶gøs–µÍkN`;Àë'dú[b7G‹Wb ¯‰ü ð‡f€’ùk-A“þ•ÅUäe¤5µX^«Åò§à,ùg…xBþ¦¢!-.¥,ý±þgcrýËÖŸH¯ÛØ»²¾^õ…Ã+߯x^¯„üwί´@þÀµÿ€+ôèÿž›å+fW¶ueû“‹ŒªŠ‹’¼¤´Š¦ô_Nà€¸Yýñýÿäø? g tý YIMM à´q|í9 £ù+>âæ  ú«{}@Tÿ(9 éÿIMù¿LàÿÎî¿ÈpzMÇÈÞÇèñŸm ttsõþ7¶ÿ'‘æ¯ínã qýGDÐ?+mÿªzeÖÆñÿ•¹?çÿD—Rðñ°8_ö×–v´trpxÅíŠò§%¤l^ ‚8½Øþ·é·stòpôù_Í–6ŽÊ °psfÓv´qqÉKýÓéU…ò/`€\^'ÚÜšíÏåçášãúµ,~>ÎNÎK ½+ÈÏÆôúâã tíT°ÈÏçß ÿSBáàXؘC^§ÿu± ü.ïhéx÷õ+’ÿ2ý³éÿn5†×•fáähïõÚ½–(l*Nמ¡ÿÿûNúÔ2nöö*¯èÿŽþó8ÐÁÆÞëÿáð§tA @ÿ'ÊXl\el¯ócòüÛ…6VG'È« ÀÙ â÷‡c”?ÂÏ `Óø£ú+½ã°ÿ%½°™ÿ·ÄÁÎ`ýKä|µZÚü›™ Àfõo"?€Íþ_";€ÍñßÄ×XNÿ-r¿†rrüWln^›3lãdñoÜ6ð¿‰<6×ÿ_'ž âáôoæ×DÜþŠÿ³¶jØßYdÿW±ÿù®ú+kBÀNv ]‹×7þ¿QBÀ6ž†ì¯ƒÄñªýû¯oÆÿãší€ó–pòôaááæ°p±ó8¸_‡Œƒƒ“ËïøšÿcÉþâ×®ø/ùÏ~€@ž s”…Y'sÁPÛä¦ðRéü‰2xšw¬Çø"z qp i$„R9›T Ñ‚ –ÀtÚ'%9cÿÄ Ç"=šP<ûçÕÖ„Ê¿-ÔŶ€þÊþ$èÒâß³uXµƒÓ•ç˾R1(dçésO¥·Åµ‘´¿J¾ëèºûÄ9þ‚õ+‰Ê¨¬m9Þ£pš£lí9IÜI2?Ñ y¹Ã‰öŠ/0þ4Í Çÿ®€àÜÓ…³3ár#YÄZï›ÚD‚ \ìì%òhMÅŽQ|!ìžÖ Rœ=걕&þèxbF’V”"AV@³µ<"Ž‹.{€öuê”;ªß]jç*¼y¯(,Þ%T¹é‰úÅÞÔ¯îXYm ‚÷%/7ÀþÜz"4ÑúVÞDxùt^[ã‹Þ‘±6±£UéöVO –‡tÍïjEyb÷@ü!?õ¡Ä–´vJYƒFÍxß6Ï“ãØº7e‚Åæ°Ñ³uúf)Û®tú÷º#+èÓgúõëËw¾êkî±Æ}—nÁ·4Ö9á0P+%öKºÅE¿ÓŽlé3—UÎx”VƒT1Ø+W©dܡއ<ßíÔ3=ê –*|Ô0ÁåÂMÔÙgâ! "c7˜&ð$ùIlу²Ì©J_í´Aäêø±ì5>Áаÿ{‚Ñ~Dê.‘'înÙ‹Àü¤[XZƒƒZ½“:ÖMÂü«;îè ¶Ò:Û‚ìAlReE¨Ÿ@‡°\ ÛVwûøö#&zECµÒl•¦íï¢ú¢ê®üÏ)%qaq}ÂËq•/rKµcä®÷U6~’ÂËñýÎäÇ^Ço2_ï*zt¤Y‚hMâÒÖ˜ت`bÖC£ °@Þ‰ÝÛMS(W6²`æÛÊ¿>`˜ùÜÄ"]c=ƒÃÀå‡S\ZVYÌ Î+³Ñò™ÄA÷<ŸRmàüôˆ+¬Ë&e1€í I$ðœ¶àk5µåµŒ)qîu{Û:}võü S ÎA‘ãY IgеéªrtMD›®Ì*vÕÍPŽví½~ª¬ÏÕÖ¤ÓkBtâ(§T©{Ê­ÅFõ¶&¯è(lÂ2¨/Ó3˜[0[üã­òæ¼§(+µ}ú¯óp#Œ!Ñ©V…!¿oÀ‡Ç |ŵjräÛÃÈ6Ò‘$»ŽÕƒ 1â”)m ±hlÖüvš¾¨d‡–mõ6e©¤ýw´t£Â¯ío _KüP £Iaµ+c”UŽ3xöýSY}K6O@€vž©–Ãå ägTÐ ˜4aäFØøÇä瞆3Õr%qTr%*OüövÀƒé÷Ü·ÉT¢~†E6-^¢r#ÑTí–ýüõ 2B3v¸fm(Õ!æi’NÙÞ³M;zËJ)*ÑÝÌWKÝ0ŒíBszÜKgê$ŸF¼è#kZèË;ÛËÛ~–mPȸÂE¶Þ ÌŒ’„AЏÄ}ªüÈ=©Ò–Žó9ÔבÕö«kÙ–àÉÌ~RÃ%Môý/¬‡€!}A)ÛßMïð‡ì3÷¬Ûq¾ pcs zÐKbFkË•lgJZµ¤æ[Ç ê½£ƒ=.ÕJ½Ï]fkAZ—í‚VüZ=ê¾¹¦;ÕôàS6•_¬«cþ‚‡ŽŠÿ±)È5ä'œµÄA®†g…ï+m‘=wˆwý$•¨Ð×DÑ|`0ú³}¦w:„¢Ì^Ьöy\-©|ñØ„õýbÕ£ó¡oU9gœ— ¥~Œ)‰-*œï(¦F@x ržÛüàmØ!•cÏÔÓ¹h¤¸/½öˆÚI:³"s†\Û÷ä#[žë%rIuvûÃ>Ë›šåÒ'z4Y8‚HÓžV’8¦ýZA[7O‡»nü„@yî—ü3ü¤ ÞmB€GtzbN©‚YPx¤6'­%2=YØ9ª CÅ%›ðrÃZ”A_XÍA<Rß¡àÛÓô¶`ÈÅe_Ü>{¿q2ŽÔAÁÐ%ÝB°nh'¾U¯³û¦c£øå'ß,Ëá“™¥Š•ÔÎ¥œOÕÒ²ùcÎÒÑÖ!¯=²í®¡ÎÖÆ…mИri¾DÃx‹%µ„¥ê…Ñ*þ²-‚²³‡æ8ÖG Qœ þ¸I¶­d\¦wn“|ŒÉšãœ2ëwéŸëkÚ݃eÈQõMS½aÞÒ°è`å&©‘³ˆ#êT;ê"6"gòï?"+‹ÏÁ!<¸ÇX±#º?máJ€œê ¤„É`òÇô…ŸÎ÷óüM?å;êÿ*˜P uÿF’ƒÓáì&Û†¾–FH§1²kÔx™rNm¿O÷]GmÑÏÒC˜› iÎɪÃ.sŸêÏ=™å[3(~Œ£‚ná;ƒ§(vwìÍVtá…E@‰_DM=ê° „-0*fŠë^ÁáK Öœkƒ[·eÈ/ˆdŒF•„[áíµ_"Òv…°šuY-d=é½ëÎÌ.8º¦QËâÓ¶Ã3<,»xL){Ào´üjD¡ÌX ';^‘4!Ôí¸8„u¸=G~u#šá.à/nsdå¨äÎ*×&ÂH?ï‰ÆqÒLGKXöh‘5âáŒXåâÙu:Jäç)»ŽÍœÙSËíœ!¶µ±ž0²©#1< ÙÓ¨ûÏÛèOžØ‘¸FÆáœ ߃T¤2S곡0¾0G3ø«¼ùúæÃÜ·€Zd_;ÞYy}ü'›Z÷½—…ÓÛ/œõŠó“E±Mä¦|©ÕúÁ,|—…‡»®Æ›ýWu~ß—á|¸ÝÔ*u¬®êD+&÷(7¶—çñ¢ÎðP’G¦_x®Ä3´›"ÁGA(·ÉÝ?8s5S­ú_Lдx¢‹†úcÀü˜Œ ~pgĶƒg f¤&~ÅyúOÈØg=gjôÌ¢´Ž@Ï6ðøÎ•¾"?¦UiY|Új²Q`¿™ƒÝsöb‚YмUHÅ;/ÓÏZÊ_Ž™0xCGYù'1WQî_"¾=|C*^Ф;þa2¾ÚÁù³jøK 4„ÿÎl ßfû-œy½Ohå‹H¹d/—Íã >{–dg bÞÂMÑC¹u¬wiµš„c *uáćTG†vA‘z¶‰O›.S2†â-± wjBÑ˯´gvÖ§a—ÕÀÏŸkÊ´×®&?¯ s Ô1×2¶¹Smn«ø‚ø 0YÎññ·+C¡\Mj6RÍáEer,‘Dq_"pÔ¦¬j¿û‡/i¿Hào^y#­+Êàß6wÃtʼÈGöZ7v$®¡cWŸ‰´Î‰‡P¤mÃ6•èùlHË•ƒ›¦8êý›¿áòq”È Gr¡è˜ã “èòe1Í+ŒAé òY]ÊÖ;H™"nºaqF¥°†H%.Š#aÏXûMä,2R(üH‚­iN(`Iº5S*ëzM²’ËH‡ª°òõé¨Þü¿8~0}ý¨àñ“#°X[dŒ®žþ04hB“C[ór ¯.Ò©| ÃŽ#©-OW&›"Ëí{÷ûÆfpä0ü,yãZð1»±H$q°Ëé¨r½fÀ™CûXTM—Þ{*Ük _l•Ö²‡€V©Û¸vÎã iã‘X6ƾõüzÑ"ýSK .…1”ߦ86ž!§pˆå¨5¥%XES³áù˜ œY#Ûà¥`ò¼ºXx¡ôYLçcÂäè’ 51orRèòw·‘E¡¿‘;­˜Eliî˜îÕtÜऋéBrÃ#ÏÙ˜£o;üš›q¦rÖ˜Õ¾y»%tüp¢‹Ï™J¨ÛØÌ7SÝj”¾ð™G7µrmm“.1ÂÄø”ÍÐØ Ç®r.e¶ØÇâÐy&·¼+**g³˜é1r¤Ü“ølùa×ß{è€{!þ¬zàgoà ‚ÑÐf~7´­ÍjÖxtEWª¢¸,Çy™B7¹.¤ª‡yQÔºˆmæ%£0Ø“uý¾ˆ`Íß”ê`•ž ;t%«È×;Í’%e(òÃÞ”ç6ä¬{±Ø¤¤‚AwJÏeë%*?íŽyn1÷Ç¡§j¶º—''â¹}Ïso¿ðv§Ò'¶•¹J"*Ï ŒføÿJ¸ç\{i v"¢Ä­o=]ë¥qßê'Z^“iÎ…Égjö³“º'ó<„ë™J¨_¥õ’/öJÏà…qŸ¾-æ_‚»b:¾ªüõ]ÝÊœf¤†æ^ç.X¯4ÈaEäomU ·O,›ÿ²úÔ½²rM³%c,ŸK7B ¦_çÐ;НÀÿ¾#ß‹…î+rS1ÅB@¿]ý÷Äs8}°¸¡” Šc_§ë›~ö²·ÐUS5í^æ¹¹öÃc›hµI¤áÞBOš œUâ[Hœè§†£ù òb|̺Žu«» ‡ZO» Ÿ‘KuêâŠe69¸À¦A¤ ÌÃýjF¥êí*c¥){ûjDŽO>2"3Âȸ¨¾˜ ·òûsXb9C¢X@žÖæi×.¯¼¢µ’À4Ia1”"s¶ÍRñáWŒxÜÞttµÏú..Pm³õ,ÑXŒùIØ¡ÅLñ²5q•…¯¯5Ÿ$ñ!lþ^Çq̯̒QWd´>ÚYµœŠBŒæhyÃLpÇŽ{=2ROû½áQŽÈö¥0hoÞŠÝ Ó"q¬^´×, šøþ„ôÜìÀ’µ++úà®]iàÐXª;à]7y\L#ÓYì„ç£Hðê*96j«àqî©ûíÐRÍ:g”IkÏ•b›àñ+]c×ùxõù‚ùÌ~œªÁ;CuSžl>×™¦h§]“ MqâÁ½MGù¯ïw‰`Zˆ#R]Ošæ¨t ר²Šª¼ °çûÕC.œ>©ÞoãW®`IžQÁ£Õ†¤ì¿7ÃGí/®ª~ñ-ÿÜ£½ïŒÀ9²®ûýM*@æÙ§[-qó9|J²™IÄ#yCšT¹('Á~æL¼½I]ûÚÓé¡5¥‘@×b÷ãÝ3ÛÃý®.'œ ‡4b³qÁtFÀ˜ÆcuÑá¤Ñ¯p+Z ˜ |ÊÂ"ê‘JŠXz h%[Ó›qþàíÌ}Žï["¡ÇmË„–uZ—xu ò‚<×D)2,¶ s:/rínL˜’é¤iT׿ºh¯¶¯±€Çe+ã¼^͵6eV"ÍÁ›n']ëc–™³ŒCæñúZ1òW+æždâšCÄ€zP"U•zÿ[=„´XGžÎ"÷*ÆCJ¬ssÞ¾„"ÿgc“Ô‚jJÄ»¡.ÙJæ‡ø(”eI^l-×½{§Ör©jã>%-GÉ7íÁžŒøèo0‡ù¬Ü÷jh´†I\`¼£'v—¯íð«´ÒõîOJ,øDdÜ¿ø.`t2¨'î?è† ƒ–dU”ŽRËö1ytBÚÚ¤zu4pKTûÙ}¬Â‘>XôøéGØÁùÕ#è³ïùžÌºž'º^ íšK‰jºãL+Ťmîºam%vêl剻¯Éœw èëñÙy©$ó7ß0GVð t¼„0YT°,Wúª”—ÃìÓ†ø/Þ-uùW Òëu<£JVÄF›é¿Ë)JßgCÜ[G÷" €"?>vƒHH)âÔ±—ªÓ+!c’œYg|žxL~¨ õêZãÕJ!-[tÓUdZÒŒFþMÆpl¶9@Ãþ]ò‹eØ‹Ó×I”ÁPÁõÍÑI,ŽƒÅY±,Ù(ƒÒ`8ûNX*øÃ°•…R°Ö¼-Ò†E—ü—éˆÖØLS6^âMSO$´ÛkìÖùŠÔ;ÂY¨ES½3߬‰¿ÊW4Uq~°÷¦œ½ó:]®ÊâvtûÐ*±µC ìƒ§ÒàºVŠËeMÏÁ „ýX  D>ðö@¬írz±<&oq‘ÏOôsóé 0“Õ}û¾§|“Ô3ƒT6ZÌ=¸áÓ×DÁhDà$Nçí ¡&Ûmö˜Ë§ôîóåÔw´73fD`œ4zjÝ«ÓãëíѾŸj¬çî®Ñ†}†=QÁ©Åè×J†ž$›ø…|?¿ün®”t°““ÿ”*ÎáÑ´`æ~»á‹F€Xó Cñøü?ƒ£r—­•¥Q‚ÏôöÉsí¾öy–òÞÕ°9›Ê Žßa\?X,† Ô­3ËŸž,f~Ë«ÜݪËü(q¹Âã0«¢²tñæÁœ•6Ec"£t*8Œ²=˜±Y#Ù-–®ÚûÁAÄI8a`/§í%]視—½2°£îÂŒ1üÃiG³‚„ÁY(A‹°? ¾cG™Y4àà°!Sž‚o7$¯-Ƽ9eÕtíŠõ©ß«,šåÝk¸ÆrHšß˜·Õ:›ì¡xjÑày‡U銵JÎpªä“­ =«ÒÄPNøÕ¦6ó¸yêÝw:Âoj±Mâ½ï¸ål€=W£'EœÞ’ï_ÕÓbt­]öøHå3þŽ©c*™áÞn€Ž6yŽVœTEžÒìÊ'ˆ°‰ø-<}õ—)„ŽùOSô§k#¬n«!ÆÝíeX‚$“`ØÀ.ÜU}Yd³kÎ~ã㢣_P«ü‹>s«Dub‘Â"ͺ\‰¢ ÷Žu|·' ÕT¿Œ+3‚p¹…Èê”»}ÙÒ½Î,ÙQEÀl($Ê:xÙ÷¼÷d©ðù6¹9L;ù”X_{FçÉè¿®RÑ ™â£g—´µÜ,Gë=à.F¬ºT Tu¥f¥,à”ób°Þˆì%zçò7^ÚܸX$tñæ,KIÙ‰7U5ˆ-ʚ༅“ž¶¢-šVáûNË×wYÜ9Xtu]ý¿ÛýÓ`ÝxOx§é‘Ö‘Hè¬>æ²½qIBÇÁâÚäž¾Á¼‡µò—ïÅÁHvMùÎð/šBs6&RD9E-0æ¾¹Œ¡Î”.2™s×ãøX ð;ÏøÏjŒâgÈöbÜyƒÏ…~j¥Ç¿5Òﻤ¢†ñ×> H>ù/R—r lqz#í·¨:‡EŒMu˜+ö@}:m ‚²a;°¨$¡áÎêÎ"¹Ø‘éþޝòIãÖ_3ó;áGM)ídk¡ŠO±Y²À§:]V²éSÏ)åŠß„MäÒ€MÄëJsÀ÷'©ªµ@pàb¢oÒ¸®XÃUV{Ê\‡Ë¬ 2e—Õ;âŠøP¦=ÅœM/*ÿ•àòœôØ&ŒQ5Ð=[j;. ¢Iqoâ:O ×Íë<5 ÇÜùÃOÐÁƒá^TÇj¼·•ƒü¡µAb¸ø}‚Œx/|®'ì5-K+5t=OJ>n}ËTl&úº»L.ðÑcÉî‚¶¢‰‡²P–—v\o® $>ð梁>¬+1€px4"Z›ôïV D[…|éöÙoâ5pˆ¢‚_ˆhHÈøxš~[Œé2èÒWCˆè൉°K29]3/~vùέÝX·+õ‡,i{‘Q~zƒ|BåQüÌ1H˜‹†ÀK” Ùü‘ô#Ò\ÚÝÓ q’-¾E¬ê?Y\1Xù@|·r"ïáÞ'I5²%ù”Ê:†µ™î¶‰×´Y¸òæ—=Ü݈‡×´–ãÆ¼v÷xql`;ÔÆ¨³«Ôg¦dÓh–€ïhð{&3´:`{0 æêÍÅV«Ñ:2õ õë:Ûú?—½9·Gÿ‚‘ŸÒâ§bàƒð¢Œc:¶|2™ÁŠ=Ùä aÔéеl}1oA ­wr+¿$«³öñÀ Ôš‰«ý©ÂˆVð øà^™(vâWÍ¥ƒÜM3BžHmËÒ ¾Xú+~VŠ˜²Ç`"lþžÈêÃWWüi¦,<}7¾\~]×È3Lvã™JŸá=! ^F½Xß qcÌ* â;€ºÞ„„²Xw0kM)°ÎδöTÖâîâ%è.ãö Ì!"Ãhæûð„cüó.~²IÇð"èºK´~ßœùéJ[Ül«0WÊb$(©±27eò1š,„ŸÑï„òv£ßÔþ”ŽÑùMT1ÿcd®b‚v…UTÚ&I*Iq‹Ö:ÿ·_Œ²©ßÄÏÐy-tÏÖ"·ýDœÙh®vç:éf·ž7Ç}:Ú}°0Ø,(Y€¾ÌÏmæá-,¢ã¾?k:¹­±8£­˜Z_®»Õah·FŽÖ)uØ0)Vë#‘è8Øû•tVSIF ©²òˆ© Õ0p‰š¿ÛŲˆË1Â"# ²ŽjÆÛ娒žÖæÕS½½*Ï[4É~LŽÔ³ÂÔ½ôñ´Õ«òe“\‹PhÉÿ§Ü©øEzÝZžBãQôb;jØŒ€`÷âK&K}å$%2ya0ÜÏ‘´j7r&liSËÐМmÓGEÜ9øÔö‡ú/G›íà¢Kýš evÚM\D¾ÁÈb¶É$á Ÿ±Ûï¤þ»V…¯_´j¢ªOŽ#&¤ ªq5qSð~1ÿÄMÜ`&Ú»sçrÆ¡Üðí%kòŒ«„»×šlÅñûR±Ï°–zXäáÝ“$7ÃJkah–‹!ɇîzKs…]¾óîjZ…7î&µŒœ}áA\à•›¢‹-³–E­îÊDf˜„wøØsnWL+¡ù/ò% Ñcd‹‰>ȪzÀ:¡÷ QâôÜD a'h–ÆâÑHŠÖdðm:…ñØ'b¶LÝVV[$fœ­Ä¥u¦JµéLnHï1aÚVŠã=êÕŪ8f˜ªsj•vÆ;âíPwªxAΠË]ÝbÏ]+Ç£ Š2^0â“ÇéG>{ÖŸ À“w0ókœ”ߘ uy¢øKtËbù›¤=‡dTI%)%«"-)pÂf‡¢añ?{µàH ›Ü ð¼?ÄØŠÑ‘gŽõ†! N3.ŸÞQà,%rKÕeúÖÀé !„݈D€Ÿ[À3~‘%V†çµN²ìH^:Yt™¿Úm^Öyó;<£"ësÄqÕü«„bW`ÕX™}ݥߋ4”&¿ûO}¼jÆfÔäy3@o´Ú¦Úš¼á¶p])—õ}ÙŽeL7}›ƒ=[KWÓÇ—ÞüTÿxÉjÄ ×˜1NZcn~Ä»:ú[}-‰X#¨bGSVjf¹Tçbâá|)¢RJ³¾`HRÔŶT¿]ÝXl}©H2™#àÅEA¯ÔÅaøö¬T3[¦K¡ mó°×j_Ï@—ïtÕò抉µ* xûñþs™~‚Óœ«s|m/Øâ¬n*f:¿»ÀÄkç“ôöÊ*ǺX:R(4ÐóæÅžèâI+ì¥îQ¥*Ê‚žàH¿‹Ú·åÉã-úÀ ïÀ#Úù3_%’Ùrë¡rUõå£HêI•™ª{tÇBëÛ«G—UºJ+¶Š}6h²Ë-º–ÉO5 Ô=Ä’…[UÅèðSØÖ¾)OŒõSë§›ªIk—4'3¶ífh xÄ# v:Ý'53F`¼.)ÿnåFªÚÏ1zÎ4]ûïn{‹Ç¹ZfÆ ˆš·%Rv#¬mÙ•¹XúÈžÓû'ª¿+øöSD© À^gЙJÊ4QÖLŽXJôÊSØ+4g9¶’Ô+ëá(x ¹Q÷œ·å§VüÔOG *FŸ¤w¸ŸÀ¹*‘ŸŽ†EN̰,H ™Iwfº5dmøZ)ß{Et&§¥º€Rý{X‚£–§D+Jà•ò<ñGN‡©Zhvü[ªÄ–Zo¼|4·xí'ð»{ô_õwÜË®´bùFHÍÏ”Ü/álƒ!‹9ëÝð ‹›t‘£ -ìOl§pÄï([øc³~ l+±ïïNß—F±ÁÍÉÖ&¸‚"R³Ú5nñ?ù)ëÛ‡'C×ò4f|˃\[PŸ RŒ‘ŸnàØG¤‚ù"ž¢³ÉÇ›ULññ^Zv]讥,iÎ-ÏÀïë½+W†¥=$$åŸ$B ·HòŽâ ·“÷”pÙù2γHFÿ°“zQn€ôTÌ•˜²…Ø»7N\H‚Oíf?ª°JøHyÖK¡±Ù9W)¥€/ÉØ‘w—yr¼ÉTâ= ÔIÕ[œ[H< íµx ÇI™XßÂö\ù‰ËÓ6ÐaÌVÝ^€ºÑ¹¾µX¼± a#¶ß¡Œîìuœdšâ¦Ê ¨(7*N'¾‚ÅÊìY 뇇E‹ç5H S£›´Ð>qZYïøÇØ·Í‘8÷L õ–Œ=¡[×ÊC+6íï¶ËœÙd"nà÷ÉVî¼›YÈ ìJâ«-ß6£jšãåèßAAˆ¨Ê!’1f¡Ôi…W¸@+\ì¾þ uØ ¶ÁÑá1Þ3ïrÆò½ýaÙÌ…òÖ¨žïeí¾LÖ¸\IBÂä,ÎѾµP #¬yt<ÂÃ…bÞýî£éEi™&³ÄÓ:庘L`—f±Áƒé„œŒi‰fµû4E/|¿•ø\´œÒ'|¤úÀT!¦ðžKí¡E`¸ Ž—ÑðÚµÆeã,B"ÜnHKcvfÚi~þ¿ö‚#‹ ù²ÝÞ••—îѼ¸È­Ê»v¼|&>ääSro±gÂâ%¾BŠÂM¦lù _åË֭Э{in¥€ŸÓ?‹¢¼ƒbÆ­„V°ãD~dgž` ògl½è9zA‚vxnú~úðý}%hŽ@Ì{0g%wϯ"ä<•X¥öíò݃}Þˆ.ñ×qxó“Ð]îÏ ¾ZAj¬| ÞUJù¬¦$âwߟ$y'íÙ\ Øs:S«g.v–/k¼µ?Ma¶Ÿà`·9u„ß·KûNN\U¡}^?¾éžš?󚋼£<ÎEä°7ò}oÚRðiá+j6+Ím\Ói êÒ5‰)T©óÄÝ–×(œ²žCŽ&qOâ+V×=ëû‰DñN 7,áâÜ’v\1Òù´ô® >&öËȸ²ÚX·¹¸–抾¦QÑÓn8X[Á)®šÜN]ðÎxQÌ‘êóyw‹3õ¥æêlë´¶á®UŒ¥”Ø’§#2äîžþ15ª aâmM`¬ì;`¡ -áÅ|ƒ”Kâ {Ì9\™‘}ŽÎ„xã¯o @¦YíúO×°KRN×:ÂïÉ•›ñ4>'Ú´Ÿä¨`zqüèpRÉÒãg÷ÃÒ‹1]äŠèG‘¶´7Ò ‘4 BÓŠêÍ µÏQWîg$+`óÏCu{ç :‰ø?­ ʪjBæÑdÒNbÛæ‹@‘\yta‹W¦bg&¬q$y'Åãë¼þ!]èOŸ®ß*P4•ÆQuâš¡`C¬¼>à³Èä<4 µï:÷üGúkpQR¥ëhtÉL¶Vdð4Û˜dîѧnPR2ëñ;rhòZ,éïŒú¡•'½¥Öt0•¤Ú°1„xsۨݭ™›a~ öµ,­™¸|k˜É9&4`%gzY.ÈI@¶âO¨Pê9™nvœeHK`]d3äQ1AþõÉ+81ƒ°vÍíwþŒ;3ƒ‰$~躠Z/*¬ðÿ;Vº[°u›M:¿Šæ![tœá‚Q“_Í]¯û‡º—+ÝMŸã|›×Â$ÜäÃE -½þ—MgБE ÛÍzŒc ™¯"AÀÕ;9¬²4º±;±Ö6y¼‡[¹¬5G¦¼¦Ñ´Ð•™—Tã#mÔÍÙ·~Þ„r®¸Å yEJ<†£~Ãl§,JÝñ0~8ÒøWK¥½¿ÕÚñªÝtOËè\¶4ì"[zhkÇ׺/B~÷”±­+‚ªC©àI \6±Æþ<¯¤¿ NGœª(ôn¤ÊÐB G¤]U¹ÖîÝÈÖ…;éd|«CýÎ9~ ­©ñ±)î‹é‘ЍÿÄlÁÇ’1Èãrù@Ú~k»§ˆm Fß²qÀb `EàÉ®[C™Ï<ûuïϸLhª’ #s;ÛÊAB,úðnCð;ÚJÂ2cvÕIâ|ب§ÃÕ@à €éö OnWã ça0ûõSȧ¤¡þˆÚ¿ÅÐc:d‘1‚ ½ÕÛqZqvë*O¿f;û¦q{ø~ßæºÜë-…Tž8Ê%ö­ƒV/…bIÖÞjÿëL¹R\J_ŽùwçêÄ÷±ž»Pòré’Bc)‰ƒÔѸ¿ä.s Ûý>×:”¬ëŠÌ"ŽQº{±:%jxl".z *Ìø>cŽ‚IaÏŸQ>˜NMËÁi¥U°„|C¯@hóöâ'LÇÇ%¤Ô„¸r%$!‹»J{´D¥-ñ%i…x˜·•{ûdfã#ßÁJlK¥²;Š>mºFÏrJ..ªã ¶üèµ±Vîé $YºR‰Á A½,ý'“œª~ä¸ÕCHŠÃ[Ù:Šoœš;|ª€…è=­ÊUÜžð7ƒ­÷úñ"  |6?33ml<¸wH RÉéî¶e§|ÞÎWÚkÒû!áiRžÏC["¨rKb©)XŠw¬i|R{FŠ 2Ò%NïwSzßfL¹¥j€ÌÍ×Ê<ж¼'ÿªÝkWã¥Å'xp ½ÇŸ/m­^èz-å¾@š÷¬ÚñPÛ¤iVÉD½«‰ù‘qÍâÕÎC‰ý7·ÙxÆå·¢9*²î«üN;Bîåǰ±"u»>§ýÞÜé~)9ç}Úw*_@_¤ÕUB¾ÌtèÇç§ ì©(Šr¯Ó†‹zalÕ/µj¢gÝÆ‡tÛ:>ë„K"7£â©A ͇Ë×>(xfµÄ˜–g*8‹ sô^QS®4áœpnUË]®õí*‹á f^pì}ÛΉfåÉß×WŸ«c d‡$'çòÄ“ >IóbÉ)çÅ—ådQßÂK†ù€,²C™š ¢ƒsªpÇC3ÄŸí|”ETÇ ¸µì<"™#q"¥ñá5o]£|â'öL)p‰ºxK¿·/ŽX+8'&½UéS,8|ßù|oÿM µÉºëÐ;ÌáZ"hxÍXŽ ^)S<ÍÝ(>ðÞé?þþ¶¬ÛHqËĬŠ5ïY]Š÷·€·ßwÁ±ÝñMå 0®ÉM-œœilMeV—âü_IƶÃ=µ¾ùk¦zV‡Ü2¿ï @¸$n÷ê×™ZAyìT)Y _kr“½§o}`9Õ, å”{¡×"Î/à¿¥Ïâã%‡í¶3gCÓ¢—MG›õ–Ïô‚#(zÜ2ôó¾ëH¯ÂÇ[7VYé\FsFbéºgDúá Ghö¸ÙNqè`´GäzæÐ|YûèYd5úÕ¤´ªDShŸm£7}œ.–áTÒo™yÔBš|’{ç 32ýÖkOP­1jàV†éxi1Íëu Öö!6”ÒÔ¬‘r>Óè?Œ=<ò`g„‡KôtŸÉ‰}0Ñž“PAq½Ï‘bàTtûÜ ,ýM£§!Q_P!ÄÆÎç¡2ÿÞfý)8GVÿ¿þÏ™hµøB&Û|¨ù$,Ж-ôpÞ½Ênâ=]PÔ ÒË1®]uîŸÀ”ÄÒ5lkç×<y+Šƒ¢ ÀCÙõ.+ûììXfcfH%—TR¼zštšäáÈ©Ø%Á“êXx}Ź©sASŒæ‘‚ •íaNñí`7°Ü§Ýµ¤ßMÖŸIF::éÓÙ½ôЭ 4d]ËgCׇ‹ø[#³¯zjwËþ_2yB7i-ø2gþf®`+ {ÖØùÔOýYÓ3§ë*×daBÁÏá .Ú2zM¸ynQãm)g¶sŒ>El¢ª!¯T»hüÜ•ó7îÔ ”G~ üÁç}LábAcO¦—Ê_˜,ìmZòz—6Ô‚¾GÃ(Ì M³³Ý: &{_FŠÕÖäR#²äö#ùtO¤›†ãïWL¥–ã¤ââñù ]ªÌí±WÌ諹ä rã’µ®½¢Š[¨L"Ì­2¡Y²›ÝJÂ×§N2 ’3cå]¹é Œ^êöÌÅ«¿iÔ¨DyQ¾>@ùÉ€¡‚úS ƒT¾Iû¨9…Æ€tˆ;Í­Œü®ÓÙx¦Ê“tR•Lk{ŠëãwÓ7ü/‰cåj4¦©/[€ýê+ç¡¡ªµ×y7ÖVÉ:™qŸc­ð$äªêó~‡WõsKø¼½_f"`áÌ„²@0¥mãÞUAÐgÇCCi°fúlÍWÔìT³¬‚Ç^®gšÆ| ôˆñà°Èé¼`ò­=‘§qâ@ÍŽz.ˆÏ¤±Lä0rycë° ` ÔŠíb1¹$déôÆ8-ÅfÈòþÓfŸG'ŽŠaÃíü[ß xÊ*‹îìæóZ¯®Ò/#,‘Òõo›wRy§”?Ä*L ‹>\TwaY °iîIö¼ï®õúõ~–ØV[La»¬0›>ìÖ©µ…“”ÝR)füº#)öܼ^DG–@覇¤œ1t°¼)*cðXö¹ÒàntŠGx(c”NZ joàðXû¨SÚ 6ñ ~g±IS~ÂÖËÙ2RrÝΘ‹ðo¾¼ÅµÌâlíMxdxÒ1¶îŠìäËÛÎiúêRàcmI?É0´Ã÷çôý¤¾sdìWõíňšta¯ÙúÒÄÍr_<8``ØØ¨õѺ 6`M2€âè)˜ÆC'»·œ‡8Ž÷ëCÓ…ÿ§Ç/x0Dç½(ŠGVQøØ}^¡$ÝJ…3Ã{­œŽos¦½W« Í› Ó±-<é:œ°:˜…æÆÎ>ýf‘ 9z3çI"„*m¦¯ÏRCǪ¸ç±+¡>ÑM‘EÍÞÜšÙGb^È vµRRFY~ÎH ilä‘y¸ ”w[\»ŠyQ20½ZQWÿ4…¹D8ñ©¶@<öMæc÷Í –´ Y •ÓsƃÿÂ@ *nŒ)ÔèÆD”_FjÉÑO’ Ú eZΕB~ƒ¢êËË!1ÏlÿñÜS¶s)ÁÔmݙط.Üq%f¹‘]›º:à $J<Ã`1õØ7±( ;܆m”‚Â×¾uf.v€ãbûç2,=n8|†=nmwj4ˆ s6&"2E¼+|ÕÈ’µ›çE/gÍ¡7Fˆ-÷·¥(±c–„™þÅúÈÙG;á•oøŽÁAnßx©É§“rû y!Ý$§Aèt»“0UOMÊÝìnïw^¶ß(ÚõBŒÎwÒ$½Û·HUÌOýn %Ëk×õßúÓ9ìkPO°b<ó‡²JMxàÞAýšÍ—7c/» ¦!œÏV3ìjQÈ Á¤å«¬cxäÐp¦Ü Ò O¦À™Fœãçñ°›™F&GGK´W•Ú“·2îÑ'à„žãè1ÜMhöìiô-·Oñ2µ„R¼™ ð½£w:}œä±ç»"¼å|h˜ŒbÎ]ê¡‹0”3ó7µƒ Z«d]1¸‹ëÚÆ6˜»Ÿé ìŽÄÆÃ#®1Ê£ •ÚD¾9¡†œv »þØ¢ö ÉCUÔìŸ ½GÇø¸hÎӾ𣷹”u)߆…ZÑVì§ Äë×ú•1e9†ºƒÚJf6<'°‘’ÄFi›¼Ñ.CèWºìqÙ¿R6A›Y…÷3I =l eêOL‰äè0Q é#{ìš’åN¦h›ˆ[¹V´›¼Ÿ8ߡւK¹Ét&N vP›"¦ôSƒƒ :Ã1ĺ’eÀÛ·9ë½0©;îæ^3Î}˜+tÞIo–Æ?Ðæ¨Së»ÔhŠ(8{àOõQ·ˆÌ…F ¨-i¶?É¥‰ù*SQl#U¾ÍS­û5 ¼- ŽP6˜œ\zrÁTÓüCêÔY*Æ ¶v|„¯Dõ‹éûØ(pùëþïZ nÚŠnÌq“°«åÌâÎìGãÅÃX°À8ÍÞà•ÝL"z.Câ0>Éiqú±V}mVª·1œ¤‹ŸI• [ã§d Á†Ýçƒ/®3Ò¨a Ô!}ŒŠÐ»<³Ù*nQaµ3D ˰ˆc 0$ÿE#Ñ»õ ­úªð™†#0$}Éžµ¾·zã¾ ZRÿÒWõ3d!ç9>Š7vaH~åæ)Wb€u)és§¹mycËçÃ'äa®õ÷5ÔEÛ Ç«PWÎý7tõŸuŸèó­ù;+ ü}D³gXð µn³_ÞtÐ<›"ŸpKyñˆ:QºçÚ\oXñúé_ c¢HŽ^l'9ÙƒÆb±Ÿ÷¬Kû¶a¿ÛÁã¢ÚÊ«Ñ%Äk‰ £­z´¸n\~¡_äIÙ70 ìà¢QcvbL‡ÇÜ…l±¾{ëÍ•Á6 ˜y”¾¸Å­§ÒUîÙœPÅÖ˜DÄjW’UN§­µ¤1Á#ñå#Ò÷7žäÃu™à›Õ¥”áˆÑ\7E+JV('Ja~‘¾WoGû@(u;ž^[77çÖ}E·$tŽ4èðeŒžÁõI%d¢‹Ðt=¾^A‰výÚ©mËåË„R P¬³Ùù“héøeM~Ág®k«ªÃw¢(;_–ÇáÂ'“ô¼†D%XOïÆòYšP#s^¯¬ÐÎGr'·FUâ5—횤œJìÜä'îãcšÚÃìÒ²äpOÇE¬¦•d–íך×Úñ t>¾ 1ަ ¼]D£JŒ8} –€¢S¨:Ȭ3øÈ ÆmÿQptõ±•63ˆy/ÆcÒÓçâÿ6K] endstream endobj 226 0 obj << /Length1 2892 /Length2 27688 /Length3 0 /Length 29231 /Filter /FlateDecode >> stream xÚÌ·eTœÛÒ-Œ»»„и»»»w‚44.Aƒ»»E€ înÁÝ%8Aƒ;|½Ï{²ßsÏßýy£G÷¬Z«jΪZëy ¡P×d‘°™eAN`VvA€POÎÛ¨tuº±H‚,œ¬ììÜ(44R®@3°-ÈIÚ ðmj`ÈfW';» @èt…8-æÞ ØLËÛÈ 7û ¨ƒÜÀ,æfn7ÐÉÚÖ ÈÙ"rövµµ¶ÿŽÁËò;À äú›à7Ð trƒduûT’ hfaòt³·˜9YYUXª OˆÑ@r˜m̬ «¿BhkÊhhä4Ô´Õ5X:¶@°“D`acæjfºº<@KÊ¿‹H¹»ºþ–¦ò?.׫ûŸvH‚ rŒ|ýÍ<ÿspÍœÜÝ|þÑïÿÝJ ÈÀÛºÝþŽüW¥ &Homþÿ{÷{ÃïÒʳÊÃà„|Ø!§XÆÉR äè!î†ò{*¤m!ƒ\½ÙþËÑ·wy:ùþ7•­“åï*,ÝÙ´l]Ü ÒÿZ1¡ü±YÁvÐr”-lØ~§üë ü6sü6Cªáïë rX™9¸ým­€/_73Ȉººý}ÿéøß…ƒ`ik†{È‚òWt'+@ào3„Éÿ¸þ5€ôÝf «Ìääà Z+6U2*ôÿ¯_FÿÁZÖÝÁA€þÿlÏ®4s´uðþ?×þÇ2]àoñôÿ%€­›¬­ÐRÝlaówŸþ¶+€Í ‡LÂÉÚéñ_&íßä4@î{Ûß ûú ƒnaïtsðüíBÊ÷œ!­üÍÀ¦©&©'iÀô_†ð¯…2N K['kÈ„óÌ\]ͼQØ!“ÅÉÃð倜K ×_£`cu![Îî`ÿßEù=¼<6‰ß¦¿/€Mòâ°IýAü6é?HÀ&óoÄÇ`“ýƒ8lr'€Mþâ°)üAìJ$»òÉ®òA²«þAìjÿFüìê$ŸÆɧùqØ´þ Hví?’]ç‚dÐÿ7€p1ûƒ \Ìÿ ˆZsÈüÚÁ@+ð;׿ퟪ; ¡-þ~O›å? $ðO™#w3‡,€è³ú9!Ѭlÿy¸~Cà?ÖC,Öÿ€ØürCJ`ãíltúÇ ˆÍö¢Ýþ"þŸl éÿ@ˆ˜„â€ÐýIY rú5ˆç?nHœ®¶ TƒBÞåBÞõÂÔíôßèñO) Ïa¶qþa9~l`OÐ?6@ĺÿé$â_on ×ò†ÔÀã¢Ëóõú„dõþ„höù þï¯þû1ú×£ýÏ ð¯w¦¿°&ØdÔµµ„¼yþc‰Šd¼¼ Ù!÷:ÄùûŸ_Æÿ+ÍŸGÒ?vKJ‚¼|Yx ³ÏÂÅÍàà‚4Ò5~ÿÿµ×âïGý_ÏÈUõ?ø÷Cz-Pç@B¡véõïKdŠ'ÊàiX¾ˆê)&Â-fM´’IlRÅ>5fÓ~)Ë ¤9}Ò£ Åwx^kJ)¿´|#¾e @Š!#1œ¯Ãªœ­²XÖNÉðS1¿Hÿ3÷Tvsbók€öð”@kÇ],çØ öy¥QYóJ!¼çÇŽý(Ý&ü•ç{ÊkÚæ3òå‡Ê`8nÌÕÈ#7ú)!ÆÔ=³ÛŠOøøü–»Bd+u\$ä§ùÙí6}Í9-ªãåäQ2}«¤ëòÆ+ ã\üF:ú>Ý9@?Ïdz:³ÃQî îM)§Þ ^Æ·IÜÙ•Úã®{qÀ°§ro ¶ûR®š/&ž#Na°p¯è†4à sÛ³ÏGs ÏM¨ÎêbìÒÉÓý3%B¼—J„2]8Ö=ä¯:Äk#ë°Kô>ÌOŸºÈQl‘Ï0­´ì‘Tk ûöP~LëOÀ©$Ë’k°žè ©¡:–$}!N*Y†Ùü:•Czõ]™·dˆ"Ó}'슩^êþñ’m ãáVÙôňŠñâ 3£yõ )­ëGÂê7êuŸ;¿—_LÐHˆ!Å!°¹©¥º¾|'K÷ÈÕýÂc0ë_ºX2fwfþ"žç¹©£¨[ ~NjµûøAìºs^EvÖ”€º TÛ²*_ÙV§{1æknâ@“FýÞiƒV嫲Qo¡šKzáÔz$!o§gDè²¼·=eÔÀ×»;ý!ŠhÕÔôóÙ~¦€/’J"Rºéxý³kímå[YÇ”&;ÉÁiI±,$E1]…‘ôbƒô™…ú†yë™lo iÔ«çˆÏ©öWh0hË ‘ƒx[î—ÛIEaõD#u‰-ʶ8Åœ7@ùGµÔ6´¢C¼©]sË=T×᱄¸æ5Úä7Ä®Òø ‡4WûÊÊ!…?Ö­2ºý-÷ü®b5Ø|¹ŒàïIà.3úcÛÚå "ãF)'k‚ò㊰¹‚WŽõ™õ¯ØWtPK´¨d9ŽTÉUAÏö›X{gAòçüÁ¹’+60ݤÚfË]ß²ï¥96û,½2î%‡N¸$«4ÈìÃI.yůé á¹nùŽükÍÏ%S³2b„DËaÑ…@-Îh>ÐïETšÜš©BV¾ò‹J÷c¯ÆÈœ¥xö…ãÙ½ÏÅo¡ŸÉ Ó4É{.Ø<“Ø‘ yÚò,ه긿6"H×~£¡ C¯ ¸“L9#]Ë[‡‰"v Ñ öè»ßý.FYýM> 0>“NÃGñ«àw¤ýf¡×´Y+Ù¶*υ窯Âiú›4&Ü—ƒ{¬± ;wZÄíºú¡ì øÖÑ–¹¶½ D#‘T‘U–¢?Ü‹ò«C/‚Äo3ZCY©ÎìjéßòúÞN¤Kr/F‹Šâ‹(õÓøÏh¼±—#™e ²WKšXÓp&Þv¦!É0£þXtöõŽ0¶‡[$D\øõÁæé©lUÉIƨ‚,)0왢Æ÷q½Úüdx ¨ðdš$­©0­”kËû3Û«/ßM¾8}éÔkMáltJ#üŠØ=ÂÖcµ$x¨Àhá¯ßÌ\˜*ûi¼>Õ/޶º¦ÝÇÑøÿ²ô“·òŒx.§©å½ñàÓ”÷ÊÞD­îÄ"šŽ/l=Ê*r^Åðzå@!ÈøæÔh'$ÄDoD7KóX«Ï¤zÜ(ú¦Œûá^º½šAâNÒ óÞO½?ÏM g|£±a³ó>¥à•°+ìñ®Pw¯­­ƒ‹s#·ûÐý̺.â-ÒÙ¹…2B_ wþëÔ_ŠƒË®ƒü¾ƒ?®©2#â{ßå;((‚ê<ššàØÝÄë]†e”™ÍbßùͱJð¼ ²Ö—ùàɦT"/§¨±c¬»$­$ÃØStÿärœR^prtT¯35hÝ»ÉïŸúš5©Úuµ€ï—Dô.EÞ(-Ô·Öâ­¶™v4ìª_À3Xœz¼ß ’Æ"…~Á;½°~MëÒe¨˜YW®átbÕŸs5:'Å*”ÔS”¦ÿ"µ»Ã#·Û–¡òàµyQã+y?á{P$ãyÇÉøWŸ§¡+âÚñü• >9Én´€¸ž®÷,ÍÇ4a8¯y&sÒUÊujòië\.YÙ¼æÞ”ãëöôÚAY‡ˆ|Š¿Ëi{ñíJŠm’©ÐÒìʪF¸»G&Ö'S¤:ÍÒãQ8eŠ ÓFG_§„/À:âBðž`ÀèñÔGõ:D6ŸbóÝëwhš¤Œ¢<ŒD<:ì’äe± z—ÇYYÚ7¤­˜hã_žRìÃá1v­_¾èÜoGYλ‡oÍÛPá|eáxí½>ár'ðt{™Ó®ì÷¹ˆ› L嵻͌úy¦+ª݇ði*ýM’ÆÜº‚©45Tj–ùиþ%ß;Ç“öü×Íè<ĨŸºÒŸpKµcmaªWp–zÜŽrVos¶Øº-S)‰æÜ´X1¬â#u,~âG8>˜m –qCõôw„…]È—¡‚vK8®‹j×ÅB`Uï‘–¥YI(TI%Ç"ÉÚ™ç`wÊ¢Üd7ðmæáÅþù“ÿW?ûð»ÈG4ñSIú>ýP’·“T­è¦'ý®äëä ™ðÏx+üKRÍá÷óÖÆÂ¼™²=ÍÓD!Ærˆ?Q`Å[|íÚ;ÊÅ ”J]¾o—ˆÃ™b]Dñb¢‰Ó ßäÛ'ö Ö…Ÿ“&Æ¢¾É÷Õ¤ò±ÿ•`çøÂ¿ç?4*ØE×),a–¥íTü´Æ£á2·ª½ºâ°×s6B(ͳ™”™7öðdnè&/n ÿóÅÐFoĈ[ÃEfŽe¡`-ÅK/È÷<£µË!O¿å+¶Dó“¹jðS—ôòWòžÜ¦æ½y;î±Í›"}œyމµÜÆ6™^x^òÆñ{Œ>–KzÕ^Á©²ªwŽÞÅLë8/˜Í€×Ué¯U’v«b÷N7=ýU‘G›õoBó™Ô Ž¥šc—˜ÁÊ§Íæ/:³Éþe]4Ó¥ÛÈpÚò›Àôet…F¥ ^†³ý“_ÉŠý|Pµvxž…ù;÷Fm¡˜©æ ­£Gjæ…d—ÅaN×l›º&=w©¯•í"Èx,©5G¹6M”Ñ»ëeF1«-rJLPsZjµ2t}/KÑP|ø¶A²ŠÄqí»ý?Jïô,ƺêûB½ Wka“Ëã¿åkP²ØlÞþÒRÞÌ`(ÒËÍ9qßLÎåÿ°³†l _ +I;W·–Þ² ¦LéDþ%°5:b™T·ö~1q—ú ñæ»Ï á½–³?`2#‘µtßbá{3“UN›.aun¨à¹¡¬40·y-oÈ/¹Qg•Bá.{~)PŽP´¥\j4àxmbMÃ[ûfÉ ôûŒ— @S¬)Y4vJjUxdH«°óR?×`AU7å>À&TBuå UA—m6/ 3À5>¹[ïÒÂë ó»-ð¯ƒÆà•Ö§}&Óûöƒ ךèõ¡îwD÷Ò5BÔ9f¦ŠJ#Jóò{°nC>ðÚ B=„·Yˆ€‡i³¨†×Í,±CQxî™ó: n azÑ»¶¥yzQ'-ÿ—Ê·Ý£=DG³@¦wEc,%ÎÚ´ß«Èôufr~R€q&É‘o²¿Xš—0p9Á‰ZaÒâ(2ÒªH,L~yZÚVx¶!Ò¤#D…³§»Ê{ð"Ý­ xeøÍ²˜—XËã Êç4¹#AÊŒ¸Ãó‘TêÎf@ìDFZk·££’t\ÿ M"ŽëSIº¾x*žyóää¾6ÖÁ;K¬7¯’Ô>Û 0&!ôwæ#‘­ÃÀIí#|Ô©nrNxg/ÜòI#-[ö»5ôzK^DÄludÃÛú°×…¥Ó¯ u} h’r"º¢¹3žW%³IIÃÔÏ)òîF,3Än0Yº]0Ä]Ęd È™‚IõLB|c¢¿^Mb´Ã1$›*ÄuÍ­±Á¶[9•¥,`7M¡EÈ]„©ï}Ÿ¹'d>Ô@½%m„ª®A‡•U’gn4™R©q£EÑ3Öf^ÉÃñ$ºâ@×5’Šfyz£Æ¢mCÖ&¶p#ÌÏP0Ëj®Lq•z·z¾B%°ŽOe>inÝïY1ß<’°d¢,’:SYG)çýZ‚[^*£‘$Ÿ]yh¾l`1nÕ9¸ýõT;ѹïÇ ÓKÞðž]„“a¬hÞ)Ìö=&ì*oea„ÈÃö€…PÒõ0¶ãôÎóG‰Ÿªd¥õßÒSå³èÌ=˜Þ½å ¨ÿ™d—¦Ýðl‚f3[=¬„½.·@ýÃQUÐ8?†^}:PQlÆÑ!ðK“ôû=áqŸ¿¸_£ tÕÔ÷}ÐLÔ'‰¸ò¡pd³~ã¼}³k2¨v2hrô˜Ù !¹àö¦+-¼¶¢,ÉDz_3l¶Á©CÄåA‚;û+ûs7üùq0.@’V£{ ˜á[÷©hí Rñt??BŸ™Å)øQ‘ ¢|ýì™;ßv13Y°î8Åh§{9`¦r§‰Ê?äÊ% ÃˆˆÌ¸R c÷¬¸9íè\¬&0ô’Jªì’–°ÒÐ{dËõodÔÑg£{¤;›É5½léÜ0çô“H±rm¿wk&;LéúHá³ØK…øóŒŽ¢ Ì!u~Å8?õËdWþ=` ³Œ¸P¡óOî²ýÊTÒ ,à[}¥î×®œxVyytLí‚tN­Òµ»1—&6˜u… ™š¯]ñ6À–fõe©oÜWõ]ŸÛÅ­6~J|BšürÁ ØþË)zÍf¸‹.¯v4~±˜.6@­çYÊEHÕî°Í´6ßÈB­¢W°à•ðú<'æ5¯y ï¹Â(Èé <ÅIhiœ÷3Cˆ(±VN»fU¤•õ‘o}—@1tŽÈçØ9ü^ú€ùU©zïn ×öðѯ[²o´¼¨–Üag1üXS4.5§ºSzÞ€^ow —õhÿL-5_Lroä'„Þ³ÜjÌ‚¯‚wåú€XQÝ1ìØÙÈšÀ€®÷Ó¬iØ¿03Ü%øŽœ ¾)Þ›Ä9RýGc?¼[÷(æâ{otm Ž©éGãçŠ;EÚLö÷ÎË«ºNÇGF™7ºß:ôMŠ7ŒÛ5|Q ‡£ÒÜ B1 „ÉÂÅP|¾Ÿû…¼RÑÐAÈж0”úüØ1êöó­r²a°€ï a3Ì»VÄ‘aV]²ô‘‘[2ž§›êâo~–:% »&ý/OÄýæ¢õR;!“}'«ÏQlL¨ >¬t­¡Ã|Óy3¡™æßBqª|F%kËôüx9àr9žM4m³õ¶—¬x¨&®„(óU¸·mÞ2ý)ZÖ׿ÆTdáBÔ^EϯÒÑu)Ûeš÷;ÁJ„úšyh±ø¹D#òŒõ¨Ý©Û)O‡׿[N´š_þT YSuŒi7·GùEÅs‰ßW—<äÒè"ø ‡Ì ËðõªשӯUE¿ýfG$Z$Á¼3GòNI‰ð£É<íz#4¼D˹»ë†žnI½Ùx*@D½o{Ò«kÉ׊„Žf.ý¯lëgùëŽãÚ/²/eë‰N”Qˆ~5·_ö¯|øw‘ëv©…衟mÔ¹6XfIéGFUW¸M©óms5-[Š·õ'oøâk®D?ƒ¶Û&Û‡Õôd¦SŸk³†¾ø1¾þ Åù¡´-Y'd߀¶ë’é¤\â](àêNÑŠÈÐZFxú™'Qd'Kè$»¿‹?­pì™íåÊùÖðŸÛ‰ç‚È= ˜é¾¢-O…¶ò0CÔEפÍà^y×;¼†›h›9ýšlÜ|5¿-»R¤Z‚“ê~©mÞSºæ¨Ú¡/Ïâãâä6¯÷áæ‹D-Ãð…œó3,8³sðñ€Ð»Ýx,ˆ'©¨ó¥¦ò2»]!ó“ˆïdlK^ù¹õn˜68ÑIIÏ‹] XInÍâÉµÈæQ¥¸Ú•¶ ?|†úÌìÏ&X.a˜F®1ŒáÒEåÿœÿêïò>œ\“c@ÈÕA®iMFƼŠºG¨%HklÀîû{¯:U'A,‘Šð¬*u›¢†øs|c!\äÀ1 m[,ã¡\=YßʹK–¼\éAE¶'ÓI+'Îú ñÓwx-MÎåæ³vYê_|²²øc7’àôd#¯:s®”ÊÙ"ßñ»Ý*NßÕ}?l‚ëAl;l; C€©2i½ØÈœFV3BþÍ÷+[>4=× 7xÑ~G5`^ó=ÏõFæ{rö‰¤GûŸÅ(ÔŠïÓg>?Ç3Fgø &È,ö¯ÃearBH\JîîÔf{ú{ß#ùö±×:éY·&¶ºŠ‰9NÐK(Nzàtk–~` ýlñ q}q'I A)ý`/æÁ4ŸY±°_4˜‘q³¾ASÀqïDÿLƒ×••€ÚÉüT¶–¥NkáñÐSÁLˆžÕ$Qsl‹À,tSàB›iwà ÛÁwÊúã±÷‰ÑG§3„rÖ}Ò1RÂÊa¹%)!‘Ó’XÁÝ{/™rÛvô¾æf»•¼n¤Ø3.y!*+I¾¦'ÇNêx^Þ‘.}ò³“ªE7ý«vÑcšÒ‡ù®j F¾o*žR‹î‡Y éÞ8S_•ÇÓ<ø:°$ñ 70ÑzD|šuU}~].€Ñ\&vÙ5¯h ñ3]èÖï³:nõ>¾ ÑP  ׿vžN_ "µ°1ŒKAt¥¬pFYŠ­=´›OÍqTÀºó˜8`ûÔ pÇð»gëŸÞݤ±$¥uJ·óXZSÏ &3VÐ9ffjcƒêªðû'9ÉçïX'FÄi’xC?•«’Èо=…*Ô +·4g€‰jEz Ãí½§+å½ÑUæß[»’ç”Zˆc|uäÒbîºÖw[”ýôÇþ³æÌ'‰ŒgQ¯´¾c]ë쾎GïN'ÛGïð-×€¶aÚYëöï;Þ²T%u·—³öÝT¶hÇÁTK×mÐO¹•œ‚¿ÍT ÆÈîžÊ‘6n|olÙå¡÷ŒùÑ¡*T¡R0ÒÕèylõMØrçn§Ü=UyKbÙWÆD1Ùv‘T»DU’ÑÁÎ6é#Ê;Uj•m5¢{Sçå_Fb|hž†DmÑ{¬©/ä¦o¼ýTóðŽ\¡Ñ›„_ÿ´‹Qý„OÜÐÔ Ê’‚*ºëJŸÊiOô…bˆÍû¦X–®A/š²Tò‹?5¬†Ü¬my¸âÝúÐËM‡Ñ.š ¿­é:kZ Öô!àäT;¯ô¾""z\´õ滂nMsúÇ}Ì%…Fø¬ñÝ¥Öþ «´åsQûWDüÞÃF,îËq8~#|ÉícâcÍIsIOM² ¯#Î :f_÷>|V#W-ø³Ð¤¼„'®[;{÷$a·ŠGýó-뢃š_•Þº ³àˆßQs‡¿Vãq~0éÏÃ7ßüAPôjãÚïë|¸%ð푈ƺ…®œ£°‡$õƒ¢ØGiµ1ÚsM£å¶˜‘Ÿ\ÛÞËŽ×XP3Ÿ îK“ ¨®ÍéõñßõüidW‘c=TÕƒ}niv—‹Ž[f”)–¶]ƒïñý$á9%ߤ7)Š£‘Ëta5›`±|…}اكӿK”žžxÌ{:Ó^Xûëm©OÆXvò'™Y5X›õWC–?l'Ñw<{·Å0”ZaÚ(=ŒNð‰Äâ²_•ÞKÔòô¹Ð„lF&ÆðÁ¡Ïx¾Â!J"_ôš•Æš¼R:¨§ôòú…çZÃ4+^-ëz#$ñjýÔÔ:œ¼<“ZîÆá 6Q !þ-ïÈ´ÊPs£©mÀ££Ü2°š´(±j1@žC7š2㞥^ˆbvvLnÁF‡nË•¸öy˜væÑvC$¯ÿ QÓó‚ÁvÚPœ&Üh»MŒÎ™2­ß«zßòðºÃ¯g(t›Mnx¥Ç¢Ø2¸õ”÷± #:Ç^ì­JhÅ?ã^•Ç¥ 0­Ô„ºØvõ¸m’Ùœfu×[o(Z+b(WõÐ`5DmMéæèú:ÊÓ̆q] ¼OÊÕªÅÎ$Ç+%ÎÛŸbû,dC6í'13º2¡lóýžŸ/€GßE¦ÁoÇ™tb”‘_„« >vûO©†éí )jtfI¾¯½Nš÷D约S|=¡uè'Q¢UK‡P1ºXQpùaZ¼c¥¹ÌDà\tÎ߬’]y>.‚‚+¿,´µ:™Ù«³þrûzÔö-F|.b?@Ñ“šQz[?¾FE±Ê.ºF¼`¸”eflÄ)óÄø©8í’‘ Ô—x³3èrÍŸqqùš(Lª½»Š») ·¤½Èþðh‹o˜M»5ºy)ñsWWax¤{p8xÜG"Sf.Þ¤ÜôVÎå·Q~ÙĹdƒÓœ_¦ñ+Ä»´w„?€æØ1¦ƒ¸0Zä*¿IÀob`s&ÆÌwaÙòÑâ<ß!¸‰ïÏ£2ºV¿¹†Í²±œ#¤_ôg>iû/Wõ Õ®Ý(fK]i¸ÓÊæ²à‹¹“¾a 4‰¶jOÓ´™Ô˜R5ئ+ëv•02öHùÚZ¤H>#íù|ÜÙIí±/NO¨ûruÏÊû/¯Ð­”¹yç&# p«‹vÏ„êQÛãYà‡áPk”áÙVõ,ï§Ð°‚Ö¤„¬'F¹ŒÔü+³|zõa_ËØ¸¼L9-iÑÆ#˜ŒuYh_!.CÿÐL9äN'G21wŸÇÕørzpÓË’0ûhBKt¶P+í’‡Øïÿ ®ÌôÜÿý‘/;šGâkWªµ¦ÀF†]ë逽Ŗá¡“ݾš’sL6ÈQ~”m¡¢q‡Õ‚ïÍñ(6«ÖyM3å ñ©ò[æë{˜’k{Ô^øZÎÊ.Æ«íº˜ýgR—ŽdŠÉ9Ã/áêœúû•Ï„Ý׆g¾.¤þèq"ß0(Û|/ Ö—j‰šªï“¨™¥¦(®Vÿ¥qÕ©›¦µŒ¸ýõ€× egm>ôv2£ÔðE3È,ãâs%'Á眒Ÿ¡+Z)D“ ßú‚hÑ|4`‡ æÔ?šKtº÷®ü*’½jínÆé~WþŠ3ã>³‡÷ø˜Fʨ!î×eÉÀÝׯéÀµ›²÷ÔòÄlÅßí9WO¤kI6b7¯\‰½” ¹FÇYÛÞ¬+5.‹ÔÍÓ *°Ž3é0B" ¥ñybJ›"+ÛÏó~”{+ѧ|-ÏÉÀì?·oUÊ(ÃL£^°Ž]ÿ„¤Øýaâ ÿô~ åÒƒ"%œª&•så“Ü®}yð¯Øûô¼¬åLfÝ /ÉvŠÍûˆG™«©Cð bNÔºÃa×poƒ0•‚JΞ¶k¾3쵑§í'BÅÀ¾QÂŒW†_¼—2²ä+sb«_Â(–£´.Iä9ÔˆyBòÜŸÛ¼¢úS‹Àd¥&x%ìj]››6ßî+VIÛd-W²·’$TrêžYF4È‘Ÿz !ßÅÙ…[`“î"'KЬ!2úŠZ]VOƒŠrõ8F©6H$ÁÈ«–ÂA˜GÞó+6vÿi>ÞlI ëç·®Š»yuFqøQ–Ÿvžê)ÎnmÓŒ¡cPV7Æ•í®ÎYž«Z¯ªÉ9o`çRþÍn‡dÆŽü³¸1ôdlLïiIèœÅÊ^d÷SÞœiù4”³Âñf*à q‰ônɃ~üŽ,‡ ]¯0RCUS«jÃwÍ(¶H]¹“äô –w$0ª—“±îÂ0Ë ¢Z׃qû ¸šx¸F /ß©&G§åð½ÿÆ}ëüACp$ÉXåÕµôÉæ'39”x>vhO,ÈH‹s¹tqãÞγ¬Y~ô-®^G¿ÖÅÀP»-Šu™%,“± ˜<§(Ù3«-k™Ù ú%Î;“lýƒ#jºï…Zͳø—LÙ»¨ÔÖMhzM¢òÏ/vzô%i]ë,œï'D†µË¼ÒŠÀPt?šW݆&«Áv†dŠW€ÔÃJ†BÕrú¦ln <]f}L“·Ëû¡È5 žÂVW ŠT;VXÞ÷:oõPæî?~zuÜ:»éubs1æ–ÎÑAúÁç—±œ€Enï÷Õwßu„°ævFë‹Ã‡P7Ì௵´|Qpp¾ 'piy¤2QŸU¨ˆQºÍù;PáG£Û‘ÂÛ4YUe$k»g¥3ƒmýqNI¢¹w¬¬Y] >Ö‰: =¤iîÃQ^ÕÕYW»>8Ýø9yì Œp¨eŠWÈ{ЧdÞE…°óv ßha–Ь9¡&b¢UFì²çT¡|d¨òçǽué p5n¢ë-&GæRõUêGZË|Þ O“§±âF”­0BqÈ6{&ù:ó2í÷y%„Åýé~¤« ÝÌÄ™uº>¶Zþû³À¢ö³DI²¤w÷ý°§_a_sç}T Ž!Êp+çtˆ×ø7ý½<;c]n$TÝ NÀÚ“Gö“éS=(do-7S}¡ðÙ·š6ð5TZ®Tøîà„q>^òsá|âg§ŸV† `.º ޶¾DDE½éT¸òp îo§à‚Rj©.66ÊV‰ãˆ% ª™ã­ˆuq½Øvx>›aKF9«1Ûü*ºÚqÜ•¼°#K³G£PÃq—UÍüàâeÛp\o™›áK U˜oÒÚ=Ž+–ÛÊ@¾€7ŸÄØÏd‹0W}ÜæÅÙ "ðQbŸŠÎóÁ‡‘¶1.Îǘm!ðÝ*”©  PǽªÃÒUØBÃßì}ˆ;0q{ü&¹y=üæÅrcRY^†}÷ÒpÖÿ›íÍàé÷Æ{ìqÑP‘ÓË»Ô{¬‚ —~d¡63T`Ég’ʺ9c4í©MËñÄÑ›`Ùî¸`¤MŒsUh‚Q¤y7yÆ>Yg«ÈÆ"çuâƒ_ ŠÍƒU/ù×íßd3:?*rì[g8]¿{yÑ'¢PL‰ðïz8¬ö#çÎ:-kL /Š;ãØf !g>‡Á5~}8aÂÏŒ…aW#.Ì}ë§9­Ã7¡.»¦õYEyNÕzÖ‘±4•˜¶Æ>!ÄŒã[¬—éµZWVox ˆ¦¹O½;xÏ—öκ½WÞØQÐÓV|ЭqǶôMjÂió^²ùgãN£¯…ßcBá.qtjÖ){:7€˜¯ß>dgŸ;FÞ"U±Ê %ºÈ`(‘ÚÍdÁ‘îöÞâ£%Ö ½­`ËíBÏ…ZRªê¢y·é``º­<cõ ¶P,IŽÉ6ÿeÊ­??nÿû…Ç*Ùü ;·*ß)'s{p…Ÿ‡QiĜב‚‹:4ÉIp-Y;ëÀ™"ÛÈmÀÀg'y»‹ã¼éÚ´½²?ÏÛÇ:‹2‘£Ùr¨ßž£€Þ( ¸^I]Øã¦›§ŽQøqë¹&H‡ÃÚ8gi ü2ž"Ç{±ëî VäxøpðƸᥞI>±UÃ7ÂFR"®0œ©ËöŽ1Áß«=©;½D(ÞUæ­Ø1£åü-'—û“ûŒ !RY™Œ„Í™_ùxùŽÀìbQGß·/Ûæ”õó¼<‚½[S` ÍKD«û–ÿûôëÇkú"‹ãÿrÛGãV{·é3H„žjRË}Õ-©ÏV)¼8 t{_dtiñ~.ÝÐy f¬ OEÓt•ºC¸ü$ &ÕR ˆÙ¿xôÂZNO°] 'ï‚›pOïõ}”:k[†ÂĢ©ÅUŒ<Ö8© ÇX„iÒ'oçœç¹(5ÞöÙq6SG‡J$øu`;»>&Jµë/TS~ ›«@• ®Þ%4«m ºTa(³Ä¢¦É)¼:’š¬ÞŠâó"µZÄÒÛY•/ä¿Î£Ýùâûè"kmÇ´“~ä9Qk¨ý‰Öc@]Ø9K†Ä†g# ·X”0BH‚nþ;¨½LIºd¯ªSáH<ãïÅ#É7m3·tŸV ½C{­Êùœ&t–]"ܱڲ5ù Ï{òݪ¥¨nŸ[’Þ,Cg­é„w¿>·8C±~›p'bç‡{ôYÙ[H€°÷ç&•:Û÷&í4­ºúO„SW¶ˆhæoÒç›7>BU=êCûÀ â®®ö“B•cny¶\#põyœØ•cÊîõàËʆ|˜*š¶žšn›Ãý0mKv¸RÈ´éM^Ë€–"ÀƒhÍ„!Ùá½$ õ_Ç’†š4…¦h%ÛJLUPmYå¬TÅðWBˆúÈïY÷?<¿:‰SgæxѨØbËÍô,òtö2\+Éø ˜°3ׯ{ë!0j‚  ø"RFƈRz„˜E*r×¶ýh†9¤¦Ð#&CܨI«rJÒ!>š×Gð ´B:ΣÇ=ŠÿõÀãÛ]çÃV]Ú›7†S~½½ô‡Þ¨WäzìzVF ËœêýÀIþù$f-‹OPëψÄx-ßG/j"‰:,Çuã>V1?òK \†íh? mU~Z£©x‹„Ëÿ} Üü¾)g›Jˆ±uN!Ø›¾ß}­A–(û5‡SÍ×qÓ×àÀÏ%ôã$ú®Ä;³»ðˆ-úÒIØG%¶x,ó© Ò\ ³a©FüÛ^åç¦t *…,ÔSÕeqŠÏ˜{çÓ¯.ÕìæyÞœpÍ–Gþ¼Å ¢åbGilC˜°¾•xØ‚Efíè§¿  û’èD»DX®/ÏÍ«ÚÇ­Ýxò%çË=Üa:Ó8Óz0Œ ½çÐé7,¨èœB Mç†Ùç%GT"å(}ßÊ×QB5´úV˜ݛȽ3êò²Õô·î©é­6&ø-ÕNzt<&9XV£BÇ4½{I>““rPÓ …þ`iáSTUv‹j6?ÑÒŒyÐålÔ”lɸ¢Ã—@ Ú?îˆ]Šù9;Ü … «pTµð’«)œ¼î]òxìÃֱ׋ñóD ¹kùô *¾íjÛŽÍ5IUׂ©O6’€µö³Ä¶Ýü+Q¶¤Ó a´—|žÑHø#“j0/Udàbf쯈žsµä½š´{ÙR霖øuöúãÀQJõÛ–±•Ëð Œøw§¡ Ræ½·~:­ÝC±”\„wås©Ÿ‚]°¬}÷£?F ÈQ6%ÕÝÙþðmTö®Á É]«RÇIy*fëËÒ@ªß¬%¯"ÛõzËŸ»ù} ©¨•/Î|ðÞ ³Ýc'Ü‘w.Ã͸«#×9L…@Wˆ¤î©øk}r$ŠûEMa]+ê­*sAs‰‰ž9\Q§”(Å^<{±µ ¹Ê¦Sæû´ZŸë¥»˜ºª¹…X›¼öI]eô$Á²O åû”*‡žÈmºvZgŠ».îÏÆâ Ñã9…ÎkJ_z¥ãÒ•íò–7ÍK#0‘tIEM­2 ƒ¤~øÃáæÐWX}–ÌqÏtõxnúa€dW•Š‚z%<¤ÍCú®gF±ó‰ ` ¿vkpGkÔK%pÎL¶Î²É F%ùаP˜9ɨU6Î Ês…cðÒ.©ï}/µëîÓ4†)å¥Ð¥‚q¤†ž„/°µ$¾¹„ͳ=3ÿDs²ÈXqGw¥/`Œö–¹ü‘pò½õvÁÁ^Naø·(Ý/O;W$\1“¸IçÝP? s^ÉCg” Ý6JªÞÏñÌ®^¬Ž¼Ý“=˃ÑÇ·Ü* ¬Išf“!ær?”9²Ð×Ù ¡$Xærž13‡5êõ=ýPåÃV¢Ò5.ýô1ˆ_ÐèL èê‰Ú,\•'ñ%f ›Ôky™JZO—®‹`ß1Q_yì )l|âû<è‹Câ’[šÎ¥æ6ïlLý©K[•wî°Íˆe},çpÅ+¥_e*M¥ ±ýœ¾Qƒ Þü °É¼Ò¼a›Òâ°6Õ¿{ê–`“ÒŠiŒd—ÜÈHûÒ=ÏX o&ÿzÛ||/ÄàtÖ±ôW^µz-k«ÂÕÓcI;¿VÖŽ˜k£¶.j÷9ù¯Ç¹—#Ô(Uÿ`ix“«jº s¨åXš—C7ýªýR¶ZÄ ¥ g¾¸o¾àB;~Ò:#&B“*â6ª©7ñ”¥ºáÍ‚Lz‡T?ºÉcápÎVŸ©ÿöï‰T¤ÉeÆ;WØÕ±dB8úa­Ó%‚ÖÏLgiœÝÖz© lvá[¹w½ýdF‚/²9‚¼ûXW¨|ãl+Š 3y¡Ô’ãÂviƒCW2âãc ©« ‡RbEÖzñóM\iÝ^N E×kNM^šc§W”,Yš¿¶¼²©zؘÝWÅânù ef”KÍŒ‡<|kw÷Þ%¬Â~aiÀ?r ,;ÀàfÓÚ“ÿÞЗ?”’t&¼d9`ÛuÝHƒ§,í9®¾åÌŠFP0ïŸ/ìÎ<Ô) éÁò¹.ï©9ñ©h\ÔcEgºÈìÁ×"Ä)(ñ£v !B½¦WŸûœÉAîì@ÂnMÏ• L&ÂRkA œüJúo.;þ|¤ ù‘DÜéi05jŒI‡=ˬ›ñÅ…ÎîãåÝWÇ5:ãxÃD¶QöÅŽä®ÐYÈb³´-°5ľ‰z½’ÔŽvÈ¢Éb€ˆãâÅ’&&=BQÉÛB:Âu'C¼ÂÂv§YwiôCÆ ¨Þ誙òñ[Qä,‡ó—HÐÈ–ºÇbQûòn¨Ñ»™Þ<;˜¢cÔ\sYîe ™Ñ=0"ö:øßÙs¼Î_š'˜Ôf±²¤¬z}Z}~j·×6S-y÷°=¤h9ƒ'ÿÑóõ¼7ç…F¡©Œñ å6Û/¾š”ûW¯~MfÁIE•«¿¦Þ㇠”Xâ(61ÿ(#páB' ’‹v6@i±£'†ö9É›%c¤„™gÅW¨Ÿ¤ö…™Ju}V´¸¥\GCìï²›Þ&´Ê|€JïðΙê²ÏÎMººBàòŧҖ’z™TÏ4êG¶IsÒq6ÁCjû¡³Ct¶§Å6€‘*AˆxÏÄ™Òd‡°Õ{Û8K)q+‡º ŸþÕÎ"³¾ì8–-µú6ÿ½ `¯—Ö‹K¯GÐChV©[,‚Ã^f‹¤b j﫽Xèš¼¶b·Gyk54ÙþüÑ5Ë:2˜o¦É>ü²”ÖUÉì’/«8b ÀüùmW°TÖ°Rm³"Wšk5’ u‚•ÌõÌÑü„¯¯ôª‹²¡åzZí½±d"Q›c4»ÕjMhU‰§SïˆÒLôïóß{’íøÏ7È•/©†E$a ­‘Ç ¸”&L‰¹c7騒–n\„yB¶þ FºõÖýTh깱ɑ¹g(Ä–µåÃõ˜ÿŒ²ÔV‹ÿ!–µðµ'º9¦¥ÀÏ‘O8+>c>“lrñ4ÓFowȾ 5`b°¬\‹ĤÚ.:¢¿0×ê (% dâ–4ÜÐÈ*+@›Ìþʯ)~P‚£OñÃÒÍ£ÑýERº7ðШÊz9•dˆØ˜5¶qHÛÃx¥À=wÑTHã›uHÔøIÒ¤™¸ô»T4¸Aúíí§a7œ/¹™iÅôFýÂ_ÂT«"ì‘>3‘y€[}ÿ¿6î!A€`Ù¶mÛ¶­.Û¶mÛ¶mÛ¶mÛØÓÞæùñòм‹Í– Ëb0–ëÐãwrBpá%ôÂÛ‰^µ«þ‹Ë2‰Â`z~¨‡ÜùË]™o MvõZ²Ì„‚)¶‡b½ÍE_-NŒç…ÀÜü‚ß' ÓÙl¯5 W£?ÏçzÿÉE3—?_Àáï¬I‡wÞ…G޾S¥äÂÍf¯¦ZµÿÎmá(§•…µ€ÃeYyÁŒ×á{z;D©k{¶w¹/Ö¨ãµÇö¥ƒKW'mZŒã‡Dšð!ùÏŒúÃ^M¢­|;îeL=„.jà%¹_o6Œ?P³sU}F[„$‚ÇjqëùXd@à¶[8¼³0E®müyS¤\âðôM¸†àõ™áÑP/ðØO‹$âCõ'‡NvµºšÑ÷ì ªçwÜ®~~é³=#r4íöB9Êþgæ¿A‡\é´,aÃ:ò7%•:µ\jm}“îàv–”ôoL3H ;t­UÙÈR;­í¿VÞ6" ÇZÄ6ù f Wæ W}ep›,š¸;›ÆœÛ',&(:ð{Ÿà÷ŸW;™åHÅ´8V¼¢2¥¯w€œòN> ùœ ¤8|߀˜…š?ÄÇtjía¬Iw~Ñzww¿|l¿àö†$€§…\3fDœ\åFÒ0üÉkx`æ`ÿ¨NÀs y(¼2ô´’ óªmæUÀk£Q/£äµ)?Iyêì‘ÓGÛú!ÚÇx¸™d(%•Å#ÿÂOVúqˆù³$@z8Iî1‡Ál ö¿¯¡g€ Ác¤[]sƒ_LMפ[ i1¿R£–FTä‚[l_ÂþŠŽZåCóF+ IÕTë9NN µmBqûQ,£à6£øÌ²TVs5¹áj70üjxÂ^È/†ÑÓ‘sò<›w—Šœ ÈàXöò¨ÏûM£.Óæ¡Ø÷ˆ’â1©ð®¹¼˜({‰”\´—ªlx‰†Ì ÏG‹¸×ð%1¤-÷ú˾ª¥ï?fAû~Ê.¼B€kŸcäµ Ç÷3}ZYà$Ö N?Ò¤¯Ìm#Y, Šp”0„Õ•¾sCÆ£8„jkíîV…ÊéûŽ‚¹·~÷¸›³vÚ6EàGßQ]7où¹ V$§‘Å}o⚺é«U†FS¬B) ª¤Ö×µ ÁG!ø³Ôå–¸—<±(=ý:X°˜–<îiµ›s8! |`d>™õpëÂce’hh)á¼°`¤î"aÄG_ Óz„lO;pé=ºIÕY±$‘Ètb¬âùŸ¹ôšffŠe‰¶ÓŸ\G5WÜÖoèG&ªY±)…!½´`îõQ/²1¥6ÃØJ:ŒµƒgúÙˆ‚¤Ï7!Œªµmp~#zžËÒ˜Íñ¿žr©x©g½ õÔ‹©#‡ÒèáËÎKäÁjÙ†ßeJnªAj-%{ÒvH(×§4ÈÔèœ .àß”ûA"j•air\×·iUÇŒå õZS§Ùp­©x,tàÚÙË^öaü9ˆ:vº·‰êÕÙQ³l‡JòÈbSå6­~â91}˜¬­ j,Ò[”¢¬Ê¢4iûhƒvÕ>¾­SCò;2iuc³É‚âŠAãD¸ú¶?8Òc¶‰|õ² {ÅdgJi£*Z‡qýÇô×UÕ „¹6;L¸ju&÷#òë;织‘àûÅ„Âû`[_ u|ËÂLÑC’­…ΚØ&×võçU‘Åä%X†Ö¢3§= 8ugLA ìsã"œHqìH ¿"ÆD£šf<ͧ´²».ªxeɘÞLîiŸ™’BáHÄòN ðB°·ƒ'¦±X–½W¹´÷{ìü'5ø>9–ÇL/(fe„Þ8á~vÁ³È´bf³šå3`’××a'3XÈÚÉ8´¹Àô缄2mâÓa)¹Á/F Yýý¨¡Æ‹‘íÒI8­½&Àaćd-ƒŸE>CÖÆ½ EA—µùÏ™@à긹žL^W½c]q8¸!Ÿ`º²‡!¯(ÃIÚJɨ½ìÉË/ö}玬ñ¥‰ír×4K6 Ã8SÊñâw£©­5pNüþ¾D/Ð*Ớyó³Þî¬ÄÙëdCÞ§¦:Ñ"Luß}ì¯ñÈó;°ÒÊÊR7ÀÅ’{bªþÔCd ¡{¡úärØ´nlèÊ~~޼m882˜ž»™ 7ñÑ OœìΖiM¡åƒEÍZȲ½…h½ÙÒ#x?2€©N†+ÚßÎBJ,ØÒÌH¾9†Nì¸*¦íÉ@9†ô¹4QB"ÇÖäã«ó4}¯ö%&’…Â…(Á´h`³þ‹7*²î§¿¦·bX0‡ÝÑ<¢Àb5Ww×+9XÂÚ‰sv¢êUÞE41E_e…õpyÂA×^Ýúä¤sø.d Ôˆ¿ò.š‰ÄP11ÁÒ½eäc€Mîž·KGÖù¢dt ¬$Ë#=©ä¢^ßló¾ˆPp"s…b`¨Wõ¡ò„¦+;Ë—û.œ:^GS°¿Ë¦Ç)_Ÿãi½0@m±9 3Á¶=âk»SVŽ…vÞZ_(¶ZÆ ¸æ‹Àù?>Óðr RÕ´™‹~‘fg‘"`\Q˜¤Ø¸ì¬­~ÏÆ3ê”êU,¸IM+Ó ¯ðK›C¡FÇû}ô9Œ"Y2£"1LäÎ×<@€ßž–wˆK—æNdò®%©ü°iûÃá>wuXº ˆ;àûïùÛÀ|Iõ¥H¸ÅÓ´«Ò{À97E|˜Åe§ø‘u¦×©2ÃÛ¸ò0d=}7òz°žj÷¥û¯†21E ¢7âòóeE§ÔŸH¦šÛÌA¸‚y‚Nꢣ(”ñ~HbâZX½Š`¿…÷ù³â«œHÂŽƒÝ‹„ {GhFÖVðŽâü$OÞ»¶ë PÙ³îG¾þé½Fò ^TôÂ`ÕÙp4æ>¸™†ØÎùCBzõÊSr)€75÷J˜©±fìkìSh!ÊnD@}L13KŸ}Žî$ÚÉäê"äÝ9КÁM3Ä/žîÍQËsòs¯FaÔÄvu÷òE9(ÄÇÍEDá˜Öõl¸Çr[\Ms.õVæÜéuÏûB3“‚ÔDþ9”GC¢¢O‡Œ ]@÷Bä#óû¿÷¯ÃêW;³MêùžÆŒB/þÂbd‚¬êjͼñ‡JŸ±â¥œ&û2jHÌC'©R·b6Ò~”ßúÄI„ÜT¡"›šÀÞšáwF€¤ªŽ#ZÇxô_¸í½Yc;µ•wsé@–ã Yh»¸Š×%·= Ÿ!½Îv¨Z—í›*¯„No£v•Œâ’mƒÂÛœ†ÃéûCÇ20e±élÕãK`#†…NK:lg"%“c\”1ÁZýlèæEÂÔ¥æ/ ¨ªS~iÇëÕö‚iü&§|ìä²YWÖâß@'|ÆW¾†L†äóÜéÃÄA}Œ­q–FÝ€dFÔî&©Öé[èW–êÑr y•QÅVϵ åÆéÂA® [K„ƒ»Ò.î)…T@ÔÔ1- kQ”¶„ù.î ÷?&Ýð^iÓòªÑ'#î%ôÏö$­ù9¯äå1¯e»½ ÅCðŠpï ´ÆR-DÄ’ÉâiCåo[Û'¢u‡Ir¿ëOˆ}U]U|® O­¸ˆ|¨úSÉ9ÎVÚìƒÎ«èŒ¶ jÀîLî£×- }@8»VÛ'þyÚu€ét³â±Õq?‚QÚç\Øìή§ë~©!7’ë–zW¾¸u[ßÀ4Sõ¼Æ{1¤o=3g¡· ð3ƒëm£…<º)á±²À=Ðp{Õ4ÉõjÕ„´l;ü(cÛõŠÌ;À‰±¬æØ ýÏ‘çÞM¤µÖÃ\ Öp¼5· è‰ew2 Þ¨-­!ë®Ï¯Â"ËI™笢›œåÿ'ÀÉ"«wïì(´-TÆ»®y|Ú‹Uåïvˆ}tf6iõ Å’OM”Ù±Ûbú*^YÈÄ+1éGÍÝÚ?ØÖ‘X¬hË”ºwžMÉÈí5›–âÊî âðö¡øÁ®»à€Mü¬!ß+ŠS=‚B³R9@7[$¬T0bm’•ä•Zð"Êí½AIÁsoLŠÍ{ŒTh޽O,±wó`ý¸‰íP9Öy}Rؼ!Ú%ÚˆC!O —î#U—\Üeú ¿ºášn°w`ÎGÓõÔúìLj'̃-Åô€d©G½¢Oi)Â7'µ~ް­¤Ô[ýš) š’~“ýV«ŒA|êû\‘2ÿ£äEå%BU{ÁwBÝØåˆiß Š¦ÃBRáO}¯»/± ‚}(­·t«Þý¾‰Æ¢FŒ½Höl"LFGÆÐЛ\¿X M*åáY^=Û†‘5%VgŒÈÔSEÓÂß›–÷±·Ò9IÖ•jd±×¬Œdïxð„Øp}ɇç¤Ì!öùáEc˜§ +÷„HûþÁØ<®0|õ”…Ù=Ã8ÖØÍ-êÇXг,ÏÄV¯îÚEK0¢U%ʹìzØh³ß¤ 9XH­‚v÷uò¡)1@©Á¯å<ÔÛ éT›ù\|Qš¿šåß¿Q’*r¶èð=ÍŒüÅ•c2 DÄfIÐãq}¡8  &WÆ rÊ4¨4øÏÔD±€&½`€”ð0þCaã’$ o[>9 ©[Ëeªõ=.¡ï>õ;&C]âPÍ£K¢7šË½“ÞqþM*þÍ"çjsÀHç‚[C$¹¹Ù×Ú8Ìž×o™9¨éìÚ{ÿíîh¯:˜Ît?·€!Nh9I­•ÑM¥Ì‘>r¥…øÄ:Å@À›ÖF*DÍýñ ÆÊÇ 8wX£.5œ¬‘ $Å©…,/¢YK1bÁ(Ý,2hÛ£©ùé^wB‡e2|ßà¢ñäúö¸hÁùø¥6´¤ß¤%-~À¬­å‘7è)ü iëR}zr;ØÒ2Žmï£^0¿jS1".Ížè㌄½½KwÙƒGe¸¯m—,×&3Ú¡ ]«i TÒiÕ¶f(fÚ±uù9˜ûy*äŒF)íù¥Àô4¨JL®{¸¦¿N¨I‘Ÿ9>†&T0nV1‹×ó൯þª@ºG'ÑZgëQÖzGðo.ñ€FjPí§Úè¬þ$çe|K]v¹ybGé\ôs„qŽ˜¦Ìk&þÕ”o»{ñˆíõÖ°FO"eJ¤…õS­'à‰<]”½¿´¤‘mäBìÿ5OÎù6¢¹‚”,0¼£š g¾a,µÕ“ íé\WÞ èœ”³c|€¯m©&”AŒóÍó'®G¥ vS¶FÜþtKéYA'«QîÐPqö›ÁÔ¿;þ°»‰7¥Ëüƒm»E¡!ZñªëÅ¥†˜F°Ç*õ"¨¨ÇÓoìªÚu—‚ùÀ·»uÄ7ž„cnA ‹ÃƒñWrœÝ¯lÉý!Ž©ä²Tg*›‚nµâx¦¶¼(Îs:ö )”Ä(¿Þß*µ{¾þ¦Îì4ïÔE­ = 3…HÛv® @QfO[îï-åyDGÙÉ#á ‹ÊRá‡7ÕPðqÐÔÊ2«àÔ[3Tÿ 1-:Ù3y‹o[%7Ë€|™µQ¨»^uçOËÍÓçGy>¶¬©­j¿5hóÚ+–L~)âh×–Ú¢+ÿrÕ–òE? í†ã&›6ô»Úlþe_· ‚€«6†&b\«ãïÐ̨ Äûcá IGƒ“VrЮ>}å"i)œi¾`Ú.™¶ÁCì˜ËM) âçSïPe%˜/b9 vLƒ[þ êŠ08 €òç³|P]Ybo},P¬™,¨X‹‚ÏÄM(4&_nU*(;ÿÀà„7ëCûhžn´ìh¿~¦/ÑÀ'>/ Ä·Ÿ=²ÖâÞ™’Ž«|1„âè—î|äyH‰WIÖñ]ˆÜ1Î/«&zxDö}!)¶LSßfý¨Ì`†• ,r:üSo@¢mnh²ýa{9Š —-þì4m â§n}©)@ªš· Ÿ‰„'¹x‹‰ùÆv®ÝÎúñá¨aô“¼Ú¯ž_°Š·ÜQƒŠ‘£lû,?$–ýÚ¯ESƒþÓŽðDqÁvÄîÀü–û] c{ eèþ¡¶”,L ›¬lg˜xuõX´L!ª}¤³ëŒÍ"r¤]Ô<ꤽ¦‚Éþ¼v_ˆc¶‚ìðß.[íÉ7zßyO ð6K@öGòÞЇóMæÚAïä‡Ýü­,ÝÔc¤5aE®9½¹8ÑïDSgJyôC dþùÓËÖ§köC%ÌÞ‘ˆº€°âL*."Í¢ïVB¢ópÎYJï™búÞ³†õ;²,ÃDœ”z*øÃÍ·Ú#oÛiÖ[k<+/saºiO³vQx^ßã{RœûúY±ð æÁ@ÃÊÖU"tÞ}ÖßR‘è×CØ÷Ét¹x®ÓÿÈï~ w˜AÊî…¦a¡*çœ_÷ù“dCXV%ãT¡÷CàE­43H¾WZØÚAØL,|Ýg•)kÔÙõhĵÄCçÝPsþ„û2¬úüY(ËxOîáÜ®ýêe Æ› ‹dÓYìýŒ¨‹¨EÅ­nR‡¨ÎJA44¸&ØõlŽ‘*Ñ[-ªdwsÎb´äa…6xhFóà{ùç3(Àýž6uÈP¢3rÚ,0Ü }À¡v2°FÖ€RIýÍ?Cw­…“` 6 >»< ::¾¸…àBÛ›`1r{èÙŽJ†cë_ÕÃg·çs!ï5&¯·s´<Ø£lÐBiyÑ+ß:Ùô,ìã|žÁÀÚ!œ¾é,K¢WÔ 8DA³’}/Ã7þ¿Áõ;0®M£'Ö‚k©øm»s+šñÅ…‡>¥ŸýF;UMœÎw ÀeìwMêšÊ_V/+äñp¸²”²ÅãD:€¡Ûd®Ÿz§<—û‡E…µ×}OmÝY­î&`üê[G{¬"+£”g¿½i·ÐE?y‡á3:¬_*º·gvàºÕ9£?ŠŠ(ã o©T˜3øxªÖžI¤«¿å)f1äf+É@ïð ë´¡SˆÖzR¦‡æü;$º¨¸Ò÷gt†³œ]Lkœ’Á9$¹§D¡QÏë‡) ?-ßêŠR‚S=ç@{¿‘ìË+¸6ˆoj:àâÊuó‡)±-›ø?vNº:(dJi,¬åW³ðfR¸û€B|¡Ttæã{çÅœwü^ãËN®™XYžï,—T°Ê‹%øy¬DxŠ«‘‹zéžSÈÞM»ŽÀ3„ž¬‡‘e-R_ßò§e¸únå–•†Öá3ÎN¥“Ü^†ÞRèé„:íâªBÆ‘²_&¢Ó¦YøË³§“êOX çnô aÞyŽÉóEoØçò7ó­à¬ßêO:s·€¢Ü•KŸm2Ô„’TúJ\/<&nT¹$·FfFäׄ´tÐçÇŒ0wÑR—ótÎǽóÏ®‘ ”Æ2¶RÎDÚBg9¶ùURx¡®ýGÅ=;É;Ùr"J˜)÷³™ xD0¤ËBî;}-Õµ¿!±œÓ,êáèú­Ëˆa¢w"âNŸZ<º±îšæ0òL‹/1+ì 7ð^Y:ÅwÊ›bPƒ)$1Fð¹_דÔdÆJw›‹þ;®¡»͘…);ú lû}º8b:‹xõ¥µ|Tßæ7ìâ î –©ë‚¢#ysÂÏ|„Gi½«Mô€,A²?y­iÙ!I7’#]ÔƒJŒ·‘Ûͺ ¾mAæubB´ò;ÒJøIž¢‘O¡«P´BÇÕÓÞ‰ß<ç!Ç ;{:4ž[nnRÚ­Í%×z×l‡êrv>h¥+9ÜÅdD]`?‰@S6 O ÙwzÄA›eÉ·ì2¸KÊZ·µuš  QÇèh1Wù’?ôSÃŒÜ乫¶ª‡³>ñ6duÔ+0Ú¢ªî€š•ãÈ<*5 $ßWàä‡ûCB$¨ÿbQì1íú•JÄ ‰´õgåCR¯ÜØÚûÂŒ…1FÆýoÜ›¹ÞE¡“QuŒe¤ªzЮ+[7=¼¢ñÃX Xàh—ÝÄ;p|ÍDó0þÅòP¡TEÏÓF–À½€äðæ'‰£®ëº­j J ì¢Ù×-Æ6Þ{ý0ï:zC8›ªó¾X;j«ÕÊ “×$–XŠŒmœÒס HDyW·Vt-aðƒ™b5Ë]Ç*%a' UÜÃ7 Ôô«X‘ÿs+÷§¾ÌtÜ…ê’…¬I¢„Bµ]à[WÙÊDãµ½ ;Uy/á®…3wލêòYc"‰`fõá[ÖÝL>‚ìƒqBôxM§èà±ßd%§)·”º[ ³?©7ÎÁ:i\ÐùGVÎø+eöþª£Ëæq–z¿þD¿RÅÅûÚÚ‡h#Óá=,1*wtªæ>Ü2Ëȼu©½P&‚°ê-bOÀ.À©ãhìòJ[ÂÒ-‹M®Xí·þRâýš©ò%ÕSê¤øe2õjÑXý½G®t– $ôÀú•kÒÙ@ŽÜµÊ4¦1OC»öö€£ó)OLv!n!2¶Yº££’8‰ž¡f:¸çu¤Gaýž»T\QÊc)ERQ‘!ÍPNÞ'ÇÃõ J †fˆG$£•Ûf¨¬ × ´éÌåœ5ªØÇzJ˜ÿ€HŸüã¥;\/6iè-^t-{-®?S¢­Z€fÊĘbþ¾ähý­ý'Ê=Óolbćà"×þD°oÜïÇÌùÇF©w‡PŒ4’%I—Yjþ;ûR™¸µ¬²7:DNÌÐÏ8ëæhŽÕ»á:`;ÝS‹Vh?dè=í~¶¸®åá ªŒ´ÏíêmNr¹äÐ{]#Åq#uKnp£P‰vãDᣥöjå)¸Ê&1¤Ä/)¨’X½{7Â"‘ô!îÕi×´¸14».ª·„yµ½î^„M†:âªÊ°ç[߈TwšöªñéÕO8T ›ú†3×=}*f—ª»X<€Vø,ebWÇ­ ¤&QáX° >ÿ›ÍmCßyßñSb°€ù— RÔD÷êÛ$¬>ìï;&H>Ü 9‰\?áÉeˆÜÅÊÒ©‚Ãó.0H¾X»ê~ Èhª¡n$²PRÅKåØýPÂÃ^xò`†Åþ~ãG5£„$IJHsÔ2c+åÃ+@™r*È$ê/޳Äßšm8¾_·×è^¡ü­?lm”âÏìIÔRÂBu6–KdK‰ñR•¹ñ ©ïÃjƒWZsƒ«؃Sárþfÿ0¹ÞܦÂB¼çdÿ}ÚƒÂãªx=ä¾ÏH-ÏF`//¥³\o X®1yv£é>Ã4b@fP)3E…K=›*ÊF+æh+ºàîC¯{aF‘IKD .sWÝ—ç à qH¨G„°©²÷žáÌPI%ÿj?=˜@ ù‚ é"óc—gŽ65yͬÉUÒ À]nþጊÞb~!(ÙÒ!¹ Kí½5€{¤ü·’Ù/i§ødÑû¨­UY!µ0‘Ž*F™m¬¹>Ç¡ ÔÕN›·ã¼ÏkåÜö::b2÷ÇÃô§I›7ìFâ>á4»ü9ÿneìà8´ŸNKw,ƒÅäAŠÎmWjh¼£9fÙ1Áÿ3äÐÂ(  =§ƒ `vÍ<å:XêH”æª@õì9Ä+¢`J {ÿÅyxwxúü•w9à´¥¾_¥ZìýsSÉóA]$@q ’ tE:Ìr· €ìÎb‡ï3nwçêÅó¸*b]í_…Tì{ÇPQ˜¶šjѪéN=ÞoéHý65ÅzÚ!¬&}E>N<öâBBf¸/Ò!@abY¨Qœ¥=ö»;¦›š ”\dì»Ù*¸¥»´©ï¨©Œ¾7ÑsU?‡›ñ‹|^¿\Ê­>§ñ5úÙ†D«…ÓàWÕ§ÆVü~xBOE:öÀ\ Êæ°÷u´E”EÅY|ÇZ¾äòhíöYEQe¼<ùÆÎñóÜchúlxúUnF¹‹¾Š}ds™ïW-²*þpv’Hžä²UH±h/HV{ò(“õ¨²¦‘²<õ©€®“ C‹RRÏY+PYý€3Žëµ:üÇSùc\W¾ê>“<4&,*På[²@xMdSs´üï9ü£¢%5¾z¦ÝIé`ê;Ù+Z[k•å/9Â÷ˆkœ¸Ó$ÚÙ¤%ù|Áƒû8 CûãYÏU»²>óÿÅj»¦i·ð¹¼Œ­…Šþ@„4œÁcÝ|-lÔÜ|iE_¥ä»wd0oÈÑñ½/.Rl—*”â©‘¥izYQòÈç™ k „Æáú½£˜Û Àõpg×¶4¶y88$6¢×hXr¡§ªê?ªã¹mÅüŽyTJu×0á€{òƒ±'à 4gÃ-[´](\’‘d4.ã«X`Ýü¯{9Æ ÜÍ©‘¼$¯™¸/˜$z{j f'ë…“ãþØ¥ùçRЗì'$ãeBÔ„¨ˆA¬‘g"ì€x6-FÕ=äÀ$¡g3ÔMë(®êþi½ºœ®Ä‰­úÿzó¦uÄ®a)®ïrå¹Ðõ { ƒ²ƒ²@ñÎÂr·Šë –[÷튺¶˜lõ%Ÿ- —#CçX4…w 9g9b› »º@¥.ÿ $£uëúý$ ƒŸ¨àîS‘-}š ¥2³àx¸º‡Ð‘[D`T•ÀÝûÉõ¿l/“ÁíÃCc+¢õÁé½Êf Á§–½‚j£áF‘4ºŠ(6XKÛVü:ZËнԷѭåè{©ÊD&.½î—kêÍÃ3ÚÞh!’êšçߌº@An’ªöL;qäá—*Ý ƒ³K^â £±LZgYã(ÛV€¨ g?nªú¦¿\x 6þ%›ýz›œžÅbï-5ÞÝØ… v²pbQêmнM)JOM"_(¶½á€Ot¾Õ…f`óq6¹_Þ‰Þl'®Ïò¸R`¶P*³Hx`€y*Ü @¼KÛýé,±e$`/aCð­ÈHj®”ÙpÖ*,³›õò©GᓽÊ‘.±Eɰ£ Ÿ¼8¾¢<Ôý<¨gk endstream endobj 228 0 obj << /Length1 2546 /Length2 21903 /Length3 0 /Length 23346 /Filter /FlateDecode >> stream xÚÌ»eTœÛ²6Š»»Ó8wn î¼q×àîÁÝÝ=¸K°à$¸»»ç묵÷Î:û~gÜûóÆ;ºŸª9ë)›5ûý™¢ £ˆ‰PÒÎÖ™‘•‰…  Ô”rwªm€NŒ¢vÖ&2ΆÖÆ6&**1G ¡³…­¸¡3ÀílP0v™p°±°ð"P¤€¶@GÒ`ä:ªºÛY´†E;'gF#C'hkfa ¤m³³ww´03wþmƒ‹ñ·!€©ãog¿½?;m@¬N¿Š2>[Ù¹9YY mM˜ä˜òvn ¡€ÖÎ`47´6Ø™þeBMEBY ¥¬ ¦¨BÇP·:Û‚ÂŒÍ  ŽN7 ˆÇÐÄäo¿¥ mªæ@ÐchkÎrQÅÅÞÞÎñ_Q‰©¨ªI1ÄEäU%@u€”šŠ*@^$üKóÛ)ЀŒ­‰…áïírª"ªZŠ¬Ì¿³`¸‚8-~{ú_áPƒ‚ü‰´ÕÔÑÎæ/­¹³³=3³››“™‹“3“£“½5ÝoUs P vŽVЧ#ÐøWŠ]lM@…qò—ßeÈZƒr ü+( ð/¥œˆ¼Œ¤„Š*#([Œ¿Îøwý™œ?;ÿ‹²„ˆ¸œÄÿMýÛA k Ó_õúmËTd k'&ÙßPÅAHÿ5¨0ο¶þÛ€2ôÙäµó¿–:1ÿŽ„QRA^•QVFLB^Eâ//íÿpv1û½÷ÿÓÆÿ‘:sC§¿\–UT”ØZØ‚ºÎÐÖ䟳¡³‹€ü/èšÿt @ÌÅÑñwhrÿV9þ'º—CÔŽ®µ§·¡Û7®¡­‹“Ç?êý?Ki jx 'g§¿-ÿ•ikT[ Ûÿ÷ÚýÞðÛ¤ˆ¸,è¬r²Ø@ èKØšˆÙÙØ€wBøÝâ  9Û9º3ÿ¯ÀÊÖÎÍÖó×›ZØšüÎ8ÀÄÅžYÍÖÂÁ(#þ¯] ™ÐÀ:€Žµ±9óoú¿Åo1ëo1(3ÞžövöSCk' ·…)ôàédè jWG ·ç?ÿ!°rL,ŒA#4]þ².ckjàý[ òäߪ5#í_“4ÖLìl­ÝA lŠÀ,oç jÚÿ¿¦ÿòZÒÅÚZd€ö+Ò¯7´±°vÿîø¯eÀß) ýmæ¿4N’Ÿ&ŠÎÆæWëoùßl"¶fÖ@#+çßBµßÃÈtB@w€Åï+¤baù/¨ù­lNNž¿T@PÿËkPIû `–û ,&¦Eÿ¿¶ä_Ë%líL,lÍ@½Ï0tt4tG`õ''À“tŠL€ŸÿjD3“­3h ÀÞÅÙûw™~7 '€Yä·èoÄ`ýƒ¸Ìb€Yüâ0Küq³˜%ÿ V³ÔÄ`–þƒØÌ2ˆýãb—ýƒ@ìrˆ]þ±+üñ€Øÿ ŸòâSùƒ8̪ˆ]í1hþñ‚Ø ÿ Îè±ÿý.2³É? (zà? ˆÒüÄiñ¢±úñXÿ‚ˆlþ@V‘í? (Pû@‘ã? ˆÈé”[ç? ä¤û_ð6Ÿâï1ÿ׸bùÓÿºÓÿÂ*ÎŽvV@ Ð/£,‘3tv´ø¬Ãš5¬ 9èïßß>ýª?cò»EEí>{2r€*ÀÈÎÆ`eçäù 6ïÿ±×øï«è¯9:6ÿÆ¿/øhŒ°8ggÌd™ÒRæ#Q0UMÅËtR‰ó^óCÔbúT!žxî9P¨Ð¿Å/ƒºÐNVšï“O’¿m±&U¶õëZkbÕ䉒𶡜!Š„ÈhŽ:“Z@†Ü‚_y9Ýᇜ|­Žmqm$µÑ#1ÞŽî‡(¶‰7ô«drÝò¶•ñÒIrÅ ÍÏÓ/”ñŠ[F¬Þówg«ö}*Ö3د'R÷ö­u6ÖÔ‹jGgG–°fß¹Ææ`÷ðzà¿îk§n]í!æ‹<÷‰h+"§ ;`ùI2‘í¾öLkyÆ ìmJ¡ˆ ™èÔ K·³ÁÖRJnw}$O1+ç²Þ·Ê¶OЦðw-®püpgqÔ¾nåT÷°użν“ÅÓ.=ÚeAº‚õþ¦p'‚?KçJN¢pžaYª å„E£âõ¥Er·›¨D²êœ]ß 9„¥B5à?ï]97±^ÝZë:ï ÛnÚ¤nãÉW¦4À„ +39·¢xùÖ]h«+><;I´Òd¼à júÞÚ¼,n“¿fÀÜHqƒ_û$rWÕd¼—ÞZL+9“ "t/¢ù1wë£\Ã)÷J¤}W7CÑ㋹ߓ“®ÆMÛYÀÎ&VŸû«Œós/¦asÎó3—ãL£®—ù Ã|äóûÍ à£â?M”Û÷Ô“/¨—Qü3lǘÞÊ/¾,nr²Dìš=nFš×…Ÿ;»÷—3Óá#DŠ r¦Ž¢ ãi_1>‰p‘À³¦™ÆK2ø$GsD¤‘wŸC“+²FzJ<•šVèT*Ï~n:Ëdœï&‰Áú°ì"¿ÑyAÿ¨ü´ªã!½xµCxÔ×Ù°ž^„›sÇMK{ZX% ‡·‘1-¡@­î§sè¢í Oó¼&cÌïQ{üI9vgž‡¢«ßÑÒ,ú…mYTýyQ9R£–¼Ý‚ùŒ€M){ ÜØ¥Ã¨±|sÄeÙ]ð°×´\G…(!­T.æÒ0ùëŒ`¤/uiß?5'nZxûé}`~»ßTý]ù+Ѿx¸ŒJ¢r½çxÏÍ»úМt…æZnûØq"ÒÅÐÃÒ%í¯ðˆPH W¬Ã™§˜;ómÀ(óÐ ²yßW|8W/Õk9Ô¬ßh§$Uqf¬=Ýtõ³ µ.”÷hØ'+¨õpÒaØÕ¡‹’˜÷“Ã1ô®%ïàNZ˜(Iü¾µO ÍSO›oéqôuÛ-¼'Oÿeõ^»€Ð$^3@¯µ@¼XÚ?áñ~P® _U]_¹lù™ë0÷}'Q)ع±29=ÇVqö…–‹l–LxÖK=E|Ã{ˆSGÓ =¶ÅtUK2Æ&deIޝWY*ÚùÅ;î꜖b噄±82¶4»$ÇéIöA´©8¢ÏZu®:5lr2Í̱ »Å7PÊÐj䟇ϻܰr¼VÏ×-g:2îQYÊ´hê«qœÎª°Š±"±`e:~µíñE˜c,Ke›£>éõL3ØŽübÄÙsu°Oùþq­q5Tï¨}r2öxFål¨ü bS—=Þº”ž@!è秤ômp“P×ï«Û²]Ó„ªÇ,_Ìù²Zoj‚ÂmÑNÛ»±¸·íÍ››3#Öóhm¼úk_=Hš±– ”Z UÞ㨶sdÚŽP~ÊX] ?K‘Ç31v2 ¤‹ wãÚº'ò±-+V.þU+Ê5•Vœ‚MёϞtäe0¸À¸ÓúaŸ4Æ=Ü5#¼<°-pÞO¤¢•sBV…éÎW"ܨý‹êeªú‡ð’ߢMøU¸™;[çMu°É9-x¸<"–â6m—åÙ þ€cÃýtËð@¬â‘ÆX—Ü;GèœX™‰aöõÑr6âê^-îRE%;R·Kçǯܴ¨Ž´› ÎBQž<Þ„Â~¼}FÞýÕ°Û¡ïæ'Á8­ÚB"FjÐC8ënÄÊu"Z:Q?»Ìv¢ýÄSkêÝó;m—0PI*T w:O ´©‘wWÀ[ÖJS¬‡D•¾ ìA[ hK(©X¯ŽŸ%ž,C±†%Gd¸JÆY2QMÈT›!"Œ]Ž PU m ÈiG!±¥½p»î›jfšP¥×ýjXHWçïÙUØ…Ës •«¦Þý‹d,è#½CpêE€îš;å”t]Å/» Ǒֻ–'Búx飅HÿEfci¢ ÄÉ·wv!Œfl°iŠ /U1ÜTEO 2ªíìMuµ=‘™_íwááOÜsêKe{Ȩù¯o‹“ÏBBUxÆØ¬îøóØ 3‰3_3BõbV¼•ÎFl +ÇŽ^$v9^'¡œd‰r¡XGð.ÎCtv8ØQçZ4(Å6‘÷µrý¿NÏL´î >v2BÞFÌ›ÐÉ=mTã¨#¾é†{`¹‰B:âõ·_­ëÒ?=mV~²ûÞgõð–"åû…ŒÐw hý(nˆÍrè­¯XÛXhŠÖÏìâ¶Ó> yO½õ“~©×+s>®Òœrï¶Ã¬§¡rárŒÅ¼5»ä|5PMåôpì‡÷÷!¯ÑÏ‘èꡜƒµ¬e,4g1T,׿ÞìÂÝ õn:ž­|‘Ëù,Í)åzï29^ñÞÅZ±EòÕPT˜`rrqâ eó‡Ì„%,u$±ñGç—¶|œ‰í>µ²&zo'›Úk*‘–Ÿôº€êŽ(Qvâ÷ÑÄä¨%(e£õQ6åèÖ¤ý»ÜoYÖg»41™÷" õFŸwDÒ'õ[9ÔJd}Àù‡XÖ(ý›vÊ¥ÞD8èêGרi Àû«Ïn›2»:ÙãœdWŠÝ¸8°•Mh=éwìz Õ—¦Ä!H fðzŽñ ´/åÀKÂG·Oˆ‹ ž·B[lyd Ùo›zKº„M7EŠá¦+Θ#£?Ã,(àˆÂÔë¢Ýû³Ÿg¦5ÛŒ&ä¿ë,]ÄKÞç{–ËåS>{±í{ç'©îzœ¤ú†J•'X%FÁì³³ ÜÀEæ#{øÜ_)Ìv«üîÊ>J±~'¿p™Ý!¹ù³‡¼¶×ÿ -AŸÚ‡§[):å§|âYÂóÛxÉŠ—†á€aÀ8?gZ`õ½1Š)ïF¦Ê¹ïF¼? þ±pJ.©ÖÓt–C&¤üÀp:xÃ.T¤Ú®Ýf)3ºs‡Y¥­Ø…T2óÅj³Iª?Rµ7K?ÂÀ÷ÓJÉ/> Œ×äïÇ%²£Â˜Sã}m./Ó©¦øW¯Ì³Å"ù=¯¼OOKdSeWDúŠÏKàPz—ÛæÈ·n†;Šƒz˜QRœÊÏKÒ ·|múZËË)ÁÒÙ¤e‹Ö+]!!£LƒÄÒÄe\¯XHéÚd£‚ûÔò7—ŽlTNŒe#gKŠ…Ò†lò…꺌žŽlsÞHˆqˆ+¾®é6¤jÁª:çNª4̦ýE±äÜÚ¾ž"ˆKi"ñ™•A0Nˆ@u,rÅ%2%èF3ü,H颿İ,Y¿‡}þ¤sò6è`ÓÝg.%_ˆ—Œ>å^|q© h´Ã:ûùä½)=zbÓ/Æ4Ö…ïЛì$ë‘tü·¬ &5SÈ{„wq Û€'ç ùàþ‰Æ˜Ò;i›º€f§*vé~ø^ÂEWøkC‹lOÁ]ar´®b>wV“Ÿ{µƒôíjfŠ„$`^hD\ãBZ˜ö¯H]j™¾„ΈmšçilûáeG¸~˳ôCc‡ÈêÑqúÁ«Â 1tpF¼GÑÑ·²ZÊ!áÚêü/IK8˜³ÌˆÐ"ô§_[o¬ò†Õs…% m6®ž:u_çÀ-}# /¾fœ©L _w™«ø{éç,“¶ ÅYzì8G9kwظ¿t±—åÒêݶíãIÔÞ¦õØáÌËf׉ÃÄÏ5œÄµ°¦ ðCðB°Ôâ+>[>îÕßTø¡Âã[ŽÑÍk7€‘½âLž7½ßÄ8C‚;(ý\“XÖW#3Ó8÷›CïÀ—V†1ƒ7‚MÐ?×,U-†–é¡4èK)Ó/ò-Â^]—=UU(ŒOobe‡IÐd¹#ÓiR†õGàÀÖÕ¹Ë]‡›UÆIq/]Ïó‰«Ä™ȼ £i‰àL@æ 2p/Ów_£±ÅòÐihr^P²Æ…–´óG†'ïŸË×}J …XI÷d ~e©†¹HéÅ׊«t(¬BæZÌžiïe#:GǪ_ÆÓÍG áv Ü–¤P¥˜ëܦ·ß¬êñŠ‹ ¥+\G¡:3Êø÷†p%¿ž;n+aì·­)@æfÊ›’€Ã~Mü”zpØ‚¥¡pjj­«#a™Zo5ŽÎú¾§ïƒÚÿâÕ~3öàÚ¥Rºuûƒòõ™ñ<èä1–k®¾ž”Èñ•»ú³„awûx@«Åp}íÄ·žö%ò&¢ßÙÛ6ïÌê;c¾ÓM¥QS.7_‡ÈÍ‹·ö7&îÆ);6­°1²ñ=Í &Õ~Äï„zÎCŠt'¡QKüÂ{;¶1 ‹xå¤ŵÒ1íW²ùhüWs×e Ú©×°«1ÍXݪ“7E‰þ—•^€:·/Òƒ¬Ê“&ü7= 7v†1KB7¹Ù°VÀÏA¨ò†«…áNãñö™Wµ/- ëš>zÔE÷ó“I>óî-¬CAyýËWþÄïT…·QÜ« ‚tj'[áp.&­V2D±±n»Œ‡½èµ\2iÔyHèL®·×!¥,à ­ÐÔlTbwÚymtJ†ZÃj'Ë_‘¥­¤Šò¢ö9¦ÆrrL×èwtíðÇá2%ÏŠ®I¢a«uC˜ñm;±adLl±R `>·“ñ4¿A«Y¯úÖø®QWç+aMPIj«Tê§>ãbÄžæv¡hD¼9©]Ì¿‘Z½s|Úr8e®úúJò6:„ßÙ'Ù=ºe^_ɤÁ‹ªDM­vø¶E4¥b¾ìe@Þ1PP¬•$¼Â½ Â¾üJ©uµ× ÎÊ™Îk{WwY»Þ'&OÔ(÷ÚCœü4?åÊé» O}v׋P 7·f@[oK#̾U-2«}„ˆïO´ïè&@¼ˆ[´&›Œ¹Ý™ß%Lù­ŒY²!Åùž†_/µ3TÔ†~uÖIEõHQå+­nãº)注'+– Må^æËi½f¦˜Ãò * ´àÃ4ýõ€ß¼Æb<&Ó¢xR^|»ù…«ÈóCð{ç=rßgSn_smäê ÖŠè²SyÝ›ÀÄw<Í(Ñ]‰¸ý5$òn^¬ëÆy’6ÎÆ×ëîÜ¥Ù;>5 g@oجZTvw÷%¨ö™àNuä’Ä£ÉëXJ¾˜D½0HSò4 þ©‚%î{ÃèÍøhÅ'!¿XÝšráñ’€Ð¨q4×úÏO®œªìnÍE`h\evpw·· áê”*|“ÆÉ2Íž¬21D¦TÖj²ÆCMë¥ãFÌHî;ÆÚh“õÙ[ŠU¨;0ÍD¡-º·9&ͱKkQš.†ÐB~ËG’,Í$T»¸ƒˆýÒáh,m?ëÖy¾T.Aq“ëEç=ë©s|ç­Äü²ø‰qÖ(¡tò˜–¼p["+]Ö÷ÝÕ§^ šÉ6ŠJ× ˜¿34ËÚ0ý° ‰ð¤Të!™®Á¿ªDRØ)§!C²~]ë. TD2f£CQfÀî­RúEJB–$ñȇÝ¢êø²K8¾9G§Ú_È XœˆKX"3"»}Aèþnèn%ŒBW¡7í gFlé3MÜ%#®¾sˆ1ùÏcà]@ ™QR3 ý~Z‚ŒeçÝ5Á»‡ÐÆs߯…!í%!íäWE‚ΣV6:3á‹Õ ÑB$ì•î ãõ±8…ÆÀ¿Ù/´¼aJ€!­“{H$Ú†]Y´·+Ê7׹ﯺmì7NVA¥8[ÞsSõxŠzÓJr>Þă —Oó¢å\Ô ½óûêŸw½7í_“Ú§tÀ¶Ü¯ZÁüŒ0W®AªnñtÕj]OGS`wÛž*a&hÄ2{åfÙ¥9š¹ì…`NÙÐðèÕ{–ÝŠPÈ=-ŸÏíõ"°m}€Ô¢ON~>)ÁÒ=,MÄ…M¾Ø5˜[“¿7Ìå¨jy}ºÃÏéÎè7]Üu9¡‰¾Â0û¸ë¿ñq‘{ùã¶èÅF VVÎØÁžñ»ø¹)‘D!vjc„™ÔóH¾ì.±ôï2Ú$ÖCÓo+='l2à!¯‘Ú0×TJ‹¨ÍúØjÕe˜‰§æôSË9ûF¹’Ê5Ö+¾`JŸ ÆÔ¶+`3µ:á¸[ý¬³EŠ"ÎKÔ¹F;atæ g.Ã+O¹b‡áfQ¶ŸTèsøPšTÊ"7o‘_?% Vw`‚í’‡ÃR:_¨"‡šÙÆ7:¿‰–ѼÝs3ÊPº £H8íóúQÕ¹+á +A8|+™ÿI5ë_ÑÁ„Ù³µóÄ¢To.ÿ]àm·Á6¾1§3±n`lðß qí•Û]ÕåGY®Â^„˜g L‹$›Ôå®xSHN–>XȦÐv™(µ'¸Sû$˜Vœ‚Éãlöè‹ùÚGGboô4XEŠwÝd¶‹?}-÷GžÖG6øºg5cà09HPm|ñ¼&(úÅ&óc§nÞN¤òm©Åâ>ÞZ‘f–Ò¸…=®)ÇêXàJH9àÍ&)Ü}Üö³î¹¡…“ÕpÂù‚úëu¯ÀéÆìôïæ$êÀÍukjz§ý®ò^:‘œ+ÏÍ„¦âÊ€/YÃQiêš Ç8²Îu:ŠßH?–ã`§7]°ÂîÅ/€¹~4ÝYåçìN ç‡áÿUK¬gõn®œG•N®˜Yã¾gÊtô§Ca®=öC«ßITЪ >É$ŽùÇ»»å>„tü^«ij=ߌ™=’M¿â¯8£–^6ÔÖ\ñ“­ž‚ë´d½‹¬ûàìk’ê;c½•F]Ò·a5²ô¬A¤FÄÍ•è¤Ï‰û…ƒ•nãl ¹ÌL’Œ¤ ™sE/äü"Öî8$c•Ö8Ú¼ÇX‘TWZ?Ò,?'¬äÆD‡OªÑÞÛWã"‰zkF Ò hÅÍQ¼àØì+X†è y¡f¼gœ«XYr”/OgnäúF)ÊQ5BúñhT™ÆvK™C~B°ªð–Ÿ~µ@¼îUlikÕLθà ¼I¤¾_È7eP˜LpjNÍâ„B±0/ÄÒ¯wÕ=igHû*_çfµ«“Òo#R1á‘1×ÍIÖ}akÔPbÚ¼Ézêh[ëU¶Œö¿ZI˨Mc[&@,g<^dNÀÐãžvâ{Þa†Eè^< Kjˆ¡¨„_ÖKx. ï¡Ïc¡¬}ü²ya;LpÍäY&cø¾·p´G)„=²=Í=}d”¶@”0­¯îšµ©-s£Ç5õÔ ½ ÝðÚDnZSä„lû¶\áz"y95Àì¥÷•Òc ÁÃåAyÔ½õQ´7åôãõ!Ý:m4a]ÇDØBúšò¶oôHî{ÇžŸ^%+Œ./ ùhy:iÕª[ZÇ9ßöP p}8}ÊÜjß±Úè®7êÏ©§¼!¿ðv®»âÂ71O…T2Xó&}ø¿Ÿnœí¯YKçäJ~ Í„çÊìÅ’86µ¹ {^ÓÚCž¡’½L‚Yl§'¥ÁjŽ<ª{ŒS· .Y¡ùã¨â–Ýúã3QrqL¦êEüÎp#t‡|µúÃrüÞpÉð= ½,Ç 5tDÙ¶žÍîÂU]½”ƒ>×3$ç“b=7RâTù3Ñ™.nRr£÷+8ïõ‚óšÚ¶qE&.ï«Bšpµ´›ŽpbªÀ7"…ûúP.b(7BÓÊß2§ëó[r7‰À,MF,Þˆ²‹ä…V¼ÛäzQ"º­BÝÄ€.Îçja}ø5.ÌE‚óql0™ôŒö'ù§Ê£IßíµÄqÅ>‹³ëSð`ßâøÀS!$H‘×ÕrGµY~ôOâÚ§/)‚+YMk>.ÉÊQT-Ìm9ÛÜéæ—ˆ_Ì b-½0OJdÝùyqûÏÓ³;aù„Q¼r[ìÏl»!rí½Ž:£½©Çs %î'Qê[µ´Š¤‹¾Û yZ`}öaú6.+ð³ù˜ì:6æ$5ä!ý³~°Þî’2¯ÛV’ku‘j†á€”6\™”¬C‚@ìd|›µv[]ˆ\pùiF¥DG©~¢l~BÌŒ3xFÖ¯ë›ÄÝãuJ{úùL-o™nˆwŒÁRùS±¿Hc‹›p¥xEòNñ×™­Õz̨óšß¬º-°ûª~èu»éðšhoŸ¦ÀÙÓ`ŒQ^ùÒªfŸ‘4Ì%\=~è„ ›–c³Az*F¿/s³•j_æHmš”†TÁ³ž 0 åÃÇŽ¢qE…¡Pˆù™±Æk„˜êd’¤¥óÃÒáÙ–owKï6¢#Œ˜Wâìàþ=~™m˜óÌî÷ê/JenNi¨¼ÄhdµÝÓ¹ÍùO ×)7S¶ÌVp¯ªQ‰œ%Öd}mé ?jíÑ-±tœZV2ÖûL ‡1~bb¼t¢XëM£¬Öغù] SA|ÿ€vzµœ—ÔI:b@nߪâ}ßíK/cjÑöí`«q/âúGM9åp?ó®¬U¢1š]YPDÍ€PºÎO>HW¸ÙlJgþ,søn˜ÛÕ>Ë|å}Z»lq‚~ûçØ}¶ª4ØFGô…÷£'æâ(Ç‘·ï¬¬»”§Œ-"`™PòÄ¢1®sšòŽŽéÝVjߨ²D„KÒB³{P¤ÎÕ‘1bÛæüCÓš½®!¢féÂ>‚õî–À³$Xä#]!–1¯¼‰‡,¥GÛ›Xû£'—f+—å3ë™ÊÐ]g¿•±ðiÙª„‹Ç æ«4Lâ)أ݋gÈ»ŸO¿È“uV¬JࣶûûUø_~H#î |ývùÊ>bgÅvlkØÐG® }”l±úœ±$µˆ®GM#Ÿ…KÐë‘¿%â(F–Ù•ÛênQ½¤FšàÕ66ža ôÞ‚•OÃWÌC´þ¬˜õÕô "âb›ÀBB’2XÅ4ÄcL7‹ˆ?g.¿CC³îñOÍÁTÎ|\*ƒÜ“ÇJEÂIüµá_jz§ü_såe/ŽÏa 6ðó~,‹ÁÏ\‰}§/®sž±7kaÀ9”fOŒ¨³ÖçÈò#Ùø,og¸_&KÈŠÓ–Sº¹"±æq芡ôI{C¥Œ>©Á¯ãšÊÜDÐ\‘„ºlH2FÙZ',^¢ÝÔÐ,Çç߬†hÆ8¡²ºå†?wo{ø2Éínì~¯lJCÓQÁx&øù{hÉNwÊF1V«Zg›YsÝçD"©r€vÁ𻩺܋0»¶¶Ó⺘5šÞ(û&(`rÖ‹íxIœ(”zÞ×°åü†Aàä}óï¿ïp ¶EŤÁ÷´¢C}Ÿ@Ñ/‘ÏHòÚ{„”þÀ<€/¢xj ñn޽+È\ƒíë‰A¯‰/A¤gN¢+ňKgv0)Öwæ}sΆ™G´R!XˆöTL—iT#/j¦ÿ¥cQ\Ú‘¥Àž’v¬;ê^h‰$bŒ3¬Ù5÷:ª€ž»~®ÅaÀÿn{Ì_Î\ü€¢‚­‘¬77-…mΤ°Yly,&ÙÂcdH‡Ä¢+à ͡¤Xï‡^¦¿ÿ6É1ö‡Rù$*‰5šÉÈ×,«Þ¥únìùÚ°6ðìW‰ûwi£âÁ4l&ÜIô,Œ”DÑ¿7KÓàÚ÷à·X+£ÜUY²7- ÞKðùír‹Ã$&òTRJÅ=.Š»æÊÐf‰ ÿŒ\mßÛOæŠeMEá}Ä'z»®Mx*%ú¾Ò½uOßìÄŽÝ[‹çÍ[R$"’D- $Ïz'›¯ÑŪ5)}”Á>ìÙ»ÖhŽQÄùã^­#9&ÍÿðžêÙƒ'H aì^ÿ¢ÐûÈPªèxèÿAÀãâ:Ÿ¥ë|ùûX/âÆàVJírò 0›} õÝÁç§qµšÙ'–DùËRhüÐzIVïiÆ»öÝâ«ñMï mn˜)}Ÿrª åp :¸';í'‚‰HVpžd©7b0Ënªþ²VîÇÙ1m8®ÁÔ…AD · k«w½ûkß¹f%ÑèR%ÊVû¼{ù£EwkôÄËrÃÇGò+‚óTWíÏ#Œ:[œtº h,‹±Uý€¦wðƬ¾ì:¤|™B/Ü>éÿˆ…‡RÀÒ7s‡-òá"( LnF­|[ÂÛâè¸îû°»^HF†ƒ’|aÝ—É5D×Åó>AÏ©“DF_6¶92ׯÌ-•¼„î**—æ¯ü7uÇô‡Öðz§ª2ƒ¬9Œ­—0úi)•a&ªê1§y%â<çˈêj§½ÞûwJ{»lA÷d‡7FÓ³qék*¾ä’ÚEìäv:M|#‹s±ÌN½ uU—}¹2T‰1ø’Pu!þ-ãG‘A³rf'Iž]ÎÃþ¥Tí6wö»F|u³>{¶møï3€8L'F‡¢09ëMÏYµ9EÝE}-C6X«Y0”H|Íá%m¿Öž2OH9Œ1$jLJ?'±PhÊ÷j;.ÐuÈwuKEÀuâ4\Càyf$,èJHxÞ%ÏÕ‚ŸìYóÚìú̃ïÆ.ô³Ã2¼$÷fVo hNö€gX³ã ßFŠ#Q?ºÍrÚZHú²î$û˹uN˜®xœ;,·ž©ú{(ÏŸ³1ÀÕ~‹•g5rØØÇ<¿÷T®.Älÿ@Bô…@É' Â¨ø¢>Äg åJ³ä&GÑÿò¹еsM"IF›K_ìÃÝà-8ØeJŽ‚(Ï*ø¥¢ç¯:ê;Fô ‰¢‘ÙÞ˜³ ì-!Ü`t&ÖÁõ…Ã3ôm~•a|%J¬IpÇýCúûuÙ‚Ó­˜rX¡ºù;20‡>ÙÄ59tys!…_ßÍ0:ÿãΚ}g-îQ€Ê%’æF¸Žø-º´Ž¨/¦É‰õ@Hã7-º“/’zA`UHÉìA.=ùÙÌ‘`èð‹‘2ÈðßͿˆ× f¡ƒ¥(:{±-í’ nâ…1ε´‹ðºéÞ4ÐDð†iÎ0Ó˧Ú|¯óõz~ŒÑÜ.¾vѺ2ëð°5€Îõ[ø ¶]˜F÷¹ âͧ’æÊ ¥í™3úq9ü»y0­ŸðÍŒÒ'”tº ¨_-ïƒn µV“ŠYž\&[ŽÞ·âcŒ»ä]3nœ2}¸Úý~ é]Á~ß)ߘUÇkA„ön±ýñ¸§_<=Ôf° ’´—7Uj}XË%$@mâ9ýIALÞ×N>ŸO¨F—ö²ÜIrYÌäEª™îq8jKqORBÀ+€š]¹Jü¶¦’¨ÕºUæUÐå՛̖ªê˜¦m<•câ¡DÃu#WÝFŸ2£Nº‹Cê<(zŒê ´*s‰éˆ¨àrç~•¼¶Þþ¨$½aæ=ë‘Ö2ɲ˘·UÂDWZ¢¸+ÚK¡z"hïgË¢[òàõÄMl.›j+UåG¡›®F¨1xÞ/æ)ú“<8¡~¦‚³pQRÃɘ½uGÐÿ÷ S¥MÁžýÞ4ÿøãëÏW2n;FyÍ(™£ª!ܸ !Ê9Ò§ý¨ ðsæzÞ sሃ²ù‰‚ç« |Ÿå=HtÝ6µ®³‡¨+‹Í'J˜ýušV>øÂzëâÑt…+âMþÍv×ýŽ!tþUGˤ_ì²çWŠÞ”kx—Tw'M¯’B¦òùU‘Fb•Aµ*`Snå—² ó"üQ^fÎiøw¶ ÝZô-¸ó‚fNI‘ŸÑi)¿ Èå7¶Úo½Æ“O¬Uðlm…!â Å[ÜÿöÖ)ÂõéM³HWþáxp iÌ{‡õaœP!Ìü½ÂÖ*‘&rbò#0«?Ž»yÕ03âÇ­5²bÁbùÇa²îøñð-¦”ž×¬ƒ‚_7ÕÌ~ ¢h‰fVtÁq¢•†”)­K¾z•ú¤³ûG 7ö‚6dÛ ®Ó}ΓJÈWÆæ |ÈQ/;vn<>¥'"A*f•iCþ|O€ùøg«REd¼Oɱ°¿2iJ¿Mk""-›5˜D a¿MºU—¼)Û÷èfz…óÏ fŸX5>ƒ«õBÓ@Þ¿7 `Ä6h.¸ÎEj~mØOhÚè?°þ:U¹ýª7ñÆ H‹¨H?*Di>ûnÝæJXV=ÄDÖ=X#•Éàb@gºÿƒ« ì"ÿd-[´´¨¾‡)§Ýñ÷¯¦¶OE­p³iËÝY×ßzÏ÷w&t³|®íÙn-;æå»_´Oõ§Efí%«.ŽKUÔæ{ ÆB€K—‚Ô}û\;ô+1ÅÎdæQF¤Uå¦iÄ«è×÷ÊŸëö26}N®‰ÑWläZz¯¢èϤ¯ûe(šwÁU{î"?0Ÿ¬-ò0m~U •°ëŸÑä§uÞeíPŒÃ±,¤g|$“füy„Q¯Í'1Ñß]ïâÔ¾0h?+â<1|€xr•'€.œS˜ªp6&ऀ§øÈ’øó«Ônpášû}†LEuö4zu¼»ª´ñ×¼ÂõjwwÅ=Qó+»ÍìZ†aóÖÓÐ`èøÉSÀJØÛ|%ÙÀÁ[%_.SÞ}v­Q“ {·y Ï«s'TJ1î9"ðQnbMË—ÈÌŒèò®­ƒ¼²Ýü¨ÑOýQ+”âqü›)PÉg wØ ïI°¯¦ÔÀËQ DÁò<µì7ŒÎ+Û5ŒŠ2ÕГ=™¦¦\†<5ìqàš¤vŒf…Å-à„òÎJEvOåÚ‡ØX— [¾æNM°l7ªÌb:dˆ›½1µë:‡sÃåÑêgŸ1Ò¼ ~bG»FdýÞ©¤¶Cd/Ûƒ‡2…pÞ¦ýÎ3ãDGîih!çœ4ºÃ¦YŒŸ0”ÀhRåóÄ0t¥Û»,ü˨I—[ÞJè!ç»/y§Cj›I±4v(;WÑ;ñK«‡%+ÌÂoIíáþ9>)fe·kL~ëMb|­ KùVÖ]±QÔãh¤­ô}ª¹òM2uèf˜¬Â8¼åÒO>:$ÈÐÇâìËÝýŸIÅZ¦4í*—8r•¤ÕŠ5i>*w•I]ÖYî|n+‰9õHÌüZº9‘¬0•~ËÁ¦,9â*un`!(r ª³.®åa\JΓæ¹\ó™…œBòº„¹ñ^¶õÚ PZ˜½ª«ÚdiNnÒaÓ–6E¶·jÖ)<‘Çù»äÃL»6¥0Ñ\Lé\®,0r‡:Ä ºñ}/Â0dX¢ý­„.ÏDŠ\Dz1û"ˆ ·;™Å æýZJÏUúþö¶5«)ˆˆðmÜž­1Áf”8׈…<ŠzG?vGlYK?xL•ÛtFËÇ8 é³R#iÏî­ <âsµ¨l3f»øÏÀo2ש°·˜š[˜™½H<6@x … @I3ªmü_^H 3_–Ê“:yx˜«cj†Þm;P“UÜbá’`ùÂ&áõ…àN¬À-5!U+b)~²M?¨-oÙ”{ª(Úy‘;ŒS!TÖG ߟ7Mð@{ü¸9KµÚhdÆÊ¤…W'Ú˜èöÍ|[׋{¡Â!Ç*h½Có3‚ÂÒ8?âO ™"ŒuĦ±4œdÄm’eƒ,Ó׎tgƒÊ† ›­Î#ž[Â*ð–ÄÃ"ˆv×&¾§o¤ìO˜!ì"Ó4¥9„… ›žá"chkÄ`ö ¿SŽür~Jmwñ˜H{*.Nb!UÇlð¢å~ g,kŸu6,x<øÂ92/Eç=¢Ùtà%¸|÷0%×À ÍñÎ:ÈÕ¬2y©è±3%Ì–¤ Ñ¥ªr’PصEî°ÿKQߥWÓ@€<àe.“æS¾úN«]ŸDÐd$!7ѯŽwGDN;¢xÅ9"EúÉÓLU GRYߣ€j­±W7Át½;#ïRôŒâ¯€ýe;ÒnÖŠéïÔ„.Ý$Mk÷V˜ íÍ?”¯‚Eãöð¼p“k¿†ãÎü|W3’›®$ṷ̄Üç*Áz­ú ÁZÙ{Sâó?÷]—>ÇK¯ÚQmó¥!büÖ½ÞÙ1ÛY³ð6âÁ AzPA®§,®ä úá·”>H$—Íù›…êK2éh_¦ï$,=¶hÇ(Òó ¨I°ÓϺ"#Ê®ãå_LZGBC‚|%oµé­Ã”B»÷ 0Ôý•2­C»Dm÷JÃfôÅ”PÆ;ªþ¼!Œ;_YÄwSy|ˆqÝ*ídÈÇÈ:S`q3™ú0払¼'„Ù–“Ï™%H#QXw­ 8íL§)šJèÇGC½¿–.j,å³f ¶Ö£ŽŽ·©çëÚú撽͚¸j†ZÇn¯ö|ö˜kOÓåy(S‡¾ÝõL<ü'£>ÞZw¥èp»º”Ó ,Ž.T9[GkwŸð±Uæ×üZW?ŽP<ï~ÕciøÝ˜’‰UúÒœ…½gǺO‡¥þÕ—&Nƒ, ‡øzM5XýÞ¯T«'©JM6›ä$³ÖŠÛá²–Û¹Ws(ÎÅ•¡Ñ_ŒÚ޼; ã×oQ,6ɺ•ùÇ¢¯Ä84ÀnÒ%Ä^øŠp›FþÎì„„%†š¾ƒ¶Ìn<²b›·JD#ÖV½Og-ð”á%¹/Œ%ÇS®ZÂg¤EèZOv¯Õ©AI‡U*ÙPp6!ç«æ¶RE¸íþ;®ö|;zÏ|cÈJ¡Kƌǔ^5Ÿ©×8bÀªj`ðÔäÏÓŸ"¾¢¢BwM¡Nƒý ¶'ÆXqëäìÝœ®‚ódƒähO¼D¢M±\nrîPú÷ÿöŒ¨¹ó8‡`ħwÖ´EÀY[Lµ£vZЇ²\TÙò†¨$©˜Ó.…§Œ<¸M¿ÓõÜh:Ý´¦ÚX<†¥HÿvÅäÙoã+@½)pÔçcf~7ŸŒŽºÇÅ$þvYÿ¹26»(¥ 7Mu嚢ëîÞ• Û…£CEI gë’U¼Ý­—-‘>Ô~±¡Ç<×A jžÆÂi9èûSs†ì:ÒHw묊”˜vk«B°í(Ju?Ãw×Q3Tœ:FgšR ó–=/»t6ŽpºñÜ>$åf~×nÓ¾óç‘!.jâÏuV{¸v]¼î@°ƒÖS¸ÊC-^rê¾ÅštÂsï÷öÌT·{ó4s;‰¯[žíÞ7²A"gðM™SYX+³Q.¬;³`€.©pC¼±P‡`>ièŸt ‡ö%H'Z¸éßVú‹©+âÖy~¦È)¬Á»¨¿ +’¦ÆÂÃĹùËïúq ã^®æ:àÀÞ4 ùp•ß ‰­g~€)8&-ä§|t*;hLìˆVµ1:M @Øú€5Œf»¾$ôa§²^Þ×fâ8)0àÞp(Kƒ;‡À÷Å viÒäáxÄá“Îi:»úþ‹§èi&½MÚ9óú¢µO±C±(¡D—Ó"ëŽÒVkÝUx—@ÿzõ›´P€\Û'•%'17^j;AæÆ*Þ“§^cÒfW…P‹Žbr…o9œ•ú¤b„c¾¼9ó³‡ÇÆšë®7ŒEª‚ç+\x`²TÔÍȹˆ6¤pLlðtxÛà$ÿ'sŒæ,øv­o,ªô„iC¸Í†ïÌ`PÚ¨²Ĩ0¿@¹f$Ü„2,YÕ—<ü&)ÕííñæQÑ6_Â'ÆÇWÊtèîHH’߃Iº*·¯«"úö¾}-T2ãéËë£ MD87ÌöI¿÷±‹"æÌ”ñfL{oú‹¿=¬-Ôný;WFo÷®b%˜ˆIÈp†+…(…ç¶¿¦,K-…óð~Âü}r-‚HÉ·1;Tl±å2C»ÛnŽéaÉPƒÚ7ÍTʶQbMÇŽjÄjk5[,%¨½?(¿¹Â½Ÿla¡Áo­T6Aàø£ç1IÃT’tÁ’šMæ}ƒÆð3F̬ÅÐ$ó“ Ý®wЏx­å¾ÒiŽ4²¹™­"*憃ÅH~V©yÊ}¡%óhÐFáMÁ{®F›D”÷»C1¶²éöèh‚7qê燋uzh¿Å:߈×ô„J¤ANó>EX†ÁgŸ­óâÁ+4ÆÝT_zVWÇŸI‹à8­Ñú@áÇ‹ŒvVxˇÁ¹'Fè&§‹“!·Iq• Ð”ú4—lÅýðR2.!üu¡u% æûiÍ:ª|Ú„´˜§2ò¯À7Ö´Ò3† ñpÔ4åQ4.# ò•4îO-ÿl|¤s¡ý.Ë—™ß„D̃ñ¯~¸hÑHWˆyObS€áí'˜|üM ¹Ëº‘S¬ü¿¢\ˆsùzèë&[àú¹Ó-bÛjyå$v)<¬CcÒ¥/ábbædµÑµú˜{Ážç7þùBà’Ù]WÍtésâß$p+àלY}I¿*-…G¢×}À ð9ãÍÌk”µÞ†Ù‘æ$«_Ãü°€8iq‹Õ'ׂ Žtg+ê5]ÔGÈÀ£ÁEDðh4=>Ì9¶‚3P†Û¬ü ØŒû©(ÕÔ2¼±›L)Î>Fhuøþ0W¿nŸ¼óö5ñý _¼n-õ q)ýO:Þ«ýîíw~‘$2\µö¡]ëƒÃùÇ}Š‘UÇÙõƒï6’Pyi›é¤ÑknæYkžø‘ÓûÑ®Q¸îj&óXÁ·øÿ¤Dš€)TœNùáðˆo¥nÖ3Ä—JÙ0RˆMJxC8™c¨ž4âõågˆÍÙºÔ¾¡•îÏ^ åuÂbpë<­‚C‹ 1z™hxºy„¼ðV©Ó‹:ï±  ÖÆzÅ0W×·Þô22þc¥±;¢ÿ³  Ú^ ¸ûd4qœ‡ñ$kWàÝçÙÇŠ…y¯óe(ÒÃÑÕhp;Uiž[œ«šË‡³©EǹeÙ®‚Ño ß 0k& \ÔÙ¥‡€Q¼èé7—”À8à傿KŒÈWÔkˆøüÒk¥Žu]ŽdO^½…׌O¨Öñ 3ö݃im"þ£!D6!Ïà<ÿ¬ßci¾õYÊh:>xÄôO`æZÄåùÏbCNXÄ“îì›éŒŽVφő°½:לë3q<´µnë„•ÍæA6œÌéµmVNý'[eäGÚá’«Y¯Icá´¯iœ²¿p*CÂ÷ý»ƒ7pŽ~ã Rn”!ÛOïÕ|Ò°·r¯+!«i6öÊyü̾±GG6ž°{Àm€¦ï ¼²XêëV üù9R!iæ L¿Xnf'µ–‹[ÆÀÚ,´m6ênêªñÇðTÌÝX­;F!û€×õ¨À†s3ülP!è= MæxìVû<¦Q(™MtÊÒ+£‡€X©Ê.+}sm°ó%A¸Ó+\ ®¼ùÕ]˜üªß€|…œÖ®vYd È})ÍbNau鳯gfÝŒ_[p"³Œ·Ù¡iÙyÃ?6¥ã¾)~ýóØèÕÎÔH@A]º >4nv\Vä6¸é‡L¬JiEg¤ ÙêÄZÇÔ'‚Bp(B b–¸…µÓäöbª+dzÿr.ˆæ2 B,p%І%‘ZÏÎÛ¿d×úó'[Íe†|ÖwAÔŽÀh¶§éZP™Ü}È|ß “‰†£EVp;'vçÞHKáe·îa¯ðF´zØ¢/Úƒgë˜.õðRN¦eèšM±$áúÝúóÕ•ä}U±Áq|œüt[,Fóá\}Öt "v^%çl%YfãÆîT<˜zÆ”t¡ŒÍWÛÌÖ)%„º*GÔ|%q$ïyNõ+\Öýà ùÆ»š„y‘&÷´šŒuë«S÷Xd¸+Ã{è‚_rÇ:_‰ÞÆ73 :fJäô>~€æE÷®¥ÐÜCYÕÅ~À‡ËŠ×"žÖU˵±jƒ‰ÒAa9Fà—Îw¨/hÉ-¡¿Øí1ɾU,…—‰w!.ñzåxÀ´uOËç*¿ð+ýW+ñ{»º»N¤?À›'‡"WRE׌ë*xær<Éjl#iïF€òúZMKÚZ–á…¼ª!«`ýÎytK*Þæ/ æÜœž¡¸UíHDXìzG…nÝ/D‚Êëª\#÷’e¦îø¡.bcÎ,zu€lA½ŒÌO»dÌ!J‹Ô ¬ÛË2…®^ªYw ‰Pœ(†ÞëíW*[xsÌßô*³‡Ÿœ9Ê7%ûp~ÙRnÐTÄq¸*¥+l K¸Åë„ãÇ:à—î´K?ËS€ŽE}P-JuO½za`JM_ðÝN±fa}X`X C¯®1Öxo±¡ÐÕqŽoF!ôÂHsá`vóH/qÜfŸ¯¬¥‘n¤è™à·­2â*C.âø}S„ZQι„ÉŲ:Q쥳g5dwYDXÎuK¶a1ñWr©,|ê¨pö‚ñzoG«›äW–hÐN$´­é¯l“&Y6¥Û½Ùì¯*Pýn?¯ÍrDÿí^û¦*–ÆöLfWVØ8Ü•#â;븦X0׋±p­ß™{ÏïÇÏ™KèÞ†r wÐ žj$„•N­:ï¤ØƒÁ´Æù‚V¶n`Ší±±ÎÑå#ì Hû©AG¤¯‚û£ZI²‰©°ˆ½žÃ¶X(Ö=é×é‘ÞvUïÜOÿ¸Æ w67oi¨ŠèÕ8m˜•0"[SkÍeÜÝýGª;ÐsÐçFuœ×u”³Á‡á”8v¸Üö¹kv—®â&PGÛÉŠ…{>=*¬ð~5Ñ>'.ÔB>Ú2€šËáüÛ~|Ћh’™óÅpçCû±ŸO„9`›:=.àéeÀÖj™:ºóK²C¼Þ9 Ú2aú -,¶žU–šçLÓ£nRóh‘‘ÛÁ<\W$®<ž+Œ¤Ã‰ÇΊ®&ü(€¯ì¸©#¿7Ƥm£7¢:ä?¶¯'^.„Œ€´âºß—ÑZ“òe@g[Ì…8à8ÝŽù$5§+ Žuí}§G4H HÑq›Õ³[Á•±ÒQuÔÙ¨w¢*­Â¯­¿?`s:9IVÇ-Ɉž‰l„û ¿M^äö´çݾټ:v½üw<Wâ3GÄÇ 7aña¹™ÈZ¯:#Fê“þ{AKqÖ&»×eRé#Å_ªÄnÚ™„DOÇP“tãù²!šemƒ—iõkFk•ÏMA-ò:²oq-M*»¼^Áãùª¾óXˆè~:õÚ/lÐLÌK&M×o1ðàz1¹“QºÄÖ}Ê™êL}ev°’}K‹j¥(àí©>ÎØ>%[^•ï¥s _Ș¿¥S.Š#s¼ŽJy¸T`}bÅ›ÐÚœdQ*;µg7_‚² m‰0`¹Ëøù±øïYIÔ‚|¢ÕlŠP n4Þ»Ç4=Ëâðª%ˆÐ†R(ç¬uYØÎÁÚgôÊ“}Mˆw•¸LŠTÈ™Å1ïÉ›“{GÀ-¤há±@TFÙ…¹çZ‹y4 ²éµ­è=÷8¤Ÿ‹áª¸¶mr®Õ‘qdOzPçÀÿ0l€€y€´ZÁ|rôV‰š° -@Å‘oÝ6¢.ab?óËöš>œË \Ül`Êy#\šK›…(!ÔXµ™x›ŠX,“L¾×²‹!~“mO¾V¼Þ°ó)*ŠÑªdÿë Äl˜…B|BF{77`¼W§/ªÐhw}4z‹aËP³4KDñÚ}#œàP¤mÚ«(3ñó;XÊiVê†Ðv,3 %Ÿ„ûÖ$ñÔ¢jbׯÛ"ãjWãõ·¨.óưlk+õÂØºy¸YÅÍQóŸlx©çµ¢h¿àª/Ùì¥þ0ŒÝí¶N–ŸšCñ|üö“ ìåò=^ð¦X<ÁöÔÁÒå‡a–s¢dª: ×¼fpRdýEª¹ä¦n“–Al„Ä(u#ü?žkx0•{¼Pjª¶±?}*‘ßD˜•]Äš‡ó‹!ÚÙQ^xpÏ༠B¡fel'ĆOö˜"ˆ?Ø FbX^” ïš|NWYógUÄ¿étm'Œ “úêkr÷óIúðw¯Ûœ~_ZŽúÈç #ñ—nõÁ#ì¹ 3Œ_ñPkk7…º—VÝ3ôÄë_zFÑïVOJ{UŠañ£ƒß·øê·í-ô‘ÂÈ÷éò MépÉ2V ,Ï7*%žÙˆÕfk­m.JNÌß+§¾¯"(I˜p»¶¼;‹õdÈ[¸í·Gv®Ì—ÒŠYm°7í7ÏŽC¡T«Ÿ»âPõ¦ÉÑ¢dëº&W#µÖé³ùÙ$C ˆÚ`ÕÝæ;hÀ4p.yç€_¢/3dŠBôkóÿ@Q$n¦ùXÄÔ%´±ϵC)†3fÖ¡Ð2c±bÙX0øEú€–ÅXçkÚ†ozm–Q w.²è—hÙþ@/·b¨‰¢X¦J€ÉÏA‰Šoæ}9Ú‘Å7ôíƒT.»!)ƒ|8M8ä*pÞØY‘ sàÌøS/åù£ý¡{xë{AÏ ¨]01Ó"áZ¯öG”?¶ v–‘$ÚS>Iù†a\<ÂA1^ü!¦UÉ©¥Z[üM‹3g.¼|6øâ™ëÀ°˜˜Ð+)Éú‚ÌÉ}⩦ù×Hpeï%Æw§ýLW’bå>-³n Í^Œ|¢¢1þEå{ÕÎ züÓ¤KµþŠy^yu;£Å³¶–!- ˆiˆ­–Y¸æ*Ùî]ú䀅Ÿòµ[..rær·% jšb¹RG™ ,r ‡„ñàg£¨Õ µæË;h@|†zå— m†ï4Ýhnü±>šSŠWÍ2”€C@ÆçÅõ ¦ilˆ |«Kl'¨|éaàÝÎ,ÅWÑCÅLñifªçÎ|¿ÂãÎE°Øp%­U41ŽíM^Ö‹›[mêcgÖcû*ä³e„ŠdÀÛ]eÉÔ›ƒì$ â×lUCËÜj‚î!¥+ÜCÌX¾µø*Áº JÚ,/øç÷9Éœl÷šÇæý Pí^9Á6ôÞÏ%«É­€3z$GÙê½G6ò]êÇ¡¤Ÿåà¡e]¾½öاvK/ú¿<ç^M½Ì(Τgý42£©¥J´Ê“­røÈ=ÂÏ^4 r>ÃR¾|T—AÎ;hQŸEÜ ".@õtW˜Næ&†ºŒ¤¦£+<9eNËç"ÂÏ9AÞíÑÎñI°§·?Xˆ¢ðÊqÁ QQáßåSÁ7Ê_1:˜0˜p£À÷X˜Ü»‰Û䎟×Ü}ª5=Ðóýzž¶¸#bÁ÷YEº^·§ïd¿·^]YóLÑÚOF‰Êd§?1K·N¢4•Ëb&¢CR Ä»{ì_ñÎíþÚì¨Ñ(ªÚJ{+d0€=`_üœQ{ !ùŠì1í9X­‰ÕìØÜÎßlLÅ“Ô8» ï¢ϰבáJ±ßd< ö8ÌÊÈLû¥4w1m1JÓ¥Ú?.ô¥½*{Z7õ4ÿl*1?,S ¿¯‘ª#YÅWª·ýiCf¶ŸÐ~?Œá‘…HˆÝÞÊ0~uY«3ÓœS©ú$UûzcK¤Àk^%´¦í—r>™¯D2jº‹,4;Àôêiå~§bKô±ùÛA6»©¦ÓEÍ6ý0‘ª?«p¤Î}»™1Elœ%È]hØ%Û}i¸(Oé¨X-aæ ÒI{Ý%H2/õQ±‰üQó¾S´‘®¡P.¬h•­ß‘ü"Ò²å][¡l±öþŠ6 9Nˆ/«ê"«Žö'åNM ¨a”%u8]â¼u,êÃq6† ÍJ…pI^ÊÉŽ9ʉ;HAœÄèSS€.â’cq@”5Ç8Úbs[ïd?qny^5!ˆù»üu:”ìÕÚ9&ÿŽHzÊ; °"DTÜØmPÅhUÑ:îàãtšþãj²ÜQЃ´I™J£è(„aõËjˆ£âÐ>Þ\ª™ jÖ’RÎQ¿m“ìL³Zø³eíÎøê mãoD…-¯ð}üC©Á¨8`ž±G=Œßƒå:E„ÅÞ¡'ö¹Ä¶ó¨¯Î¯U“ñdüí¨šè’×Ì åE)†K•  ý'´3V :ÁÿðеX§2ÆVåžI,_/?×)’G[èYëßèdíj`Ø"ûëI\’n€þC½4‹åžvYÂÝWùœnÞÜõLªœƒ…ðh¦ÝEq¾(è-7ÙÜ>òÓ‰òß? endstream endobj 230 0 obj << /Length1 3380 /Length2 31403 /Length3 0 /Length 33166 /Filter /FlateDecode >> stream xÚ̺eTœÛ-Škp÷Æ-¸»»;Áhww·× Á Á]‚;Á=÷Àíì}ÎIö¹ç÷~¾Áè³ÖªªYUs­ïc-¥º‹„%Ø$ vrgá`ehƒôå|\AÚ WG‹&ÈÚÃè àdegçF¡¥•rÝmÁNÒ@w €ÏÝ fáñ‡ì`g@¡Èœ@®EK€¹@äÔöqq€u°›;‹9Ð ² r²¶u1B\¤ÀÎ>®¶Ö6î¿bð²ü °»þbøEòv9¹A²ºý *É PZ؃½Üìm@'K€"« +@ì1ÚÀNs ÐÁ ¶ú+„Ž–Œ¦@NSMG]‹‘ k rwBj,l€®@ w«À É´´ü›·<Ð  m‚|€N6¬ŠZÎÎ`×U%¥¥­#÷ -¡ª-é¾Èéhi¿¨jCŒ­ü"ù àdi üå®"£-¡ýJ]†ƒíW7OHNÛ_Lÿ«:H1€ßÕ@\­\ÁŽ%0ظ»; ²±yyy±Z{¸¹³‚]­Y%ж±…Ôvµ@¾»‚@µØÃÉ2wH!ø5c€²­¤— ¿ŠþZT‘PU•ÑÒft‹åWÃYþ>«»·û_µhÊHH«Èü¯å_m@nÍëW,KÈmÜX!Éþ68B&aIêþŸª!ƒqÿEØáo.7è—ÇfaíÆö¯­nl¿*a‘USÕfQV’QÕ’ù‹%Øõwwë_¾ÿŸÿÑ: Û_”•ÕÕ•Ž@['ˆê€N~î@w7Õ_6ÈdIõwÓA)W×_¥©ü{Éõ?Õý{’`H9F~@¯ÿ.ÐÉÃÍ÷yÿs”ÁÛº¹»ýô¯N;@LÙÚ:ý¿Ïî—ïÒʳÊÃà„|Ø!§XÆÉR ìè!î†òKÒ¶ ¹ƒ]}Øþ÷é·w{9ùý?,ZÙ:Yþê5ÀÒÙMÇÉÖŤ ý/ˆ å·Íä`€\ Ú†íW⿎Ã/3Ç/3¤'~Î`g€ÐÁ `k‚|CñszB„êê ðûsៅƒ`iká9ü{å¯è NV`€Àßf“/ýK† ÝiŒ Íìäà‘® ›*Ø"†ÿ¿_IÿÅZÖÃÁA€áNè¿7m|þïíÿµMô«~†ÿÃÖMÖÖd©nënaó÷´þ¶+¸!NÂÉÚ™ô_&_—äd@î~Û_ û¯ADoaïrsðü½‚4ñ¿hCú‹4€MZRF_R–ù«ñ¯½2N`K['kˆày@WW  ;Dbœ<<?Èѱyÿ¥A«Øâpöpø5a”_:áå°Iü2ýxl’¿€Mê7â‡Ðùl2ÿA|ì6Ù߈À&÷qØä#.›ÂoÉ®ôA²+ÿFì*¿$»êoÉ®öÄÉ®þAòiþF|Z¿7€Mû7‚d×ù Ùu#Hv½ß’]ÿ7‚dõ$Ù üâ†dBn-W[7ûß[ îæ¿¤=æåÛƒÜ@Vî¿í\ÿ±ÿ}ÿ½ÀÁ IhÑ=èÍ“Å$Ø"¸ÿðàþeqtüÍì—Ù,ÿ¹ åZ‚~éè÷3Ðï  (– "W ›Ío!üòqñ:üŽ ©¢8 ã‘!m±ú 9!ì­lgâú=§æà‚$²røÃ²Ãú©î7nÈm|œm@Nì€Ølÿ€Zìþ€™Ùÿ!íû3„ÝÜ9 \~Gæ¸:AŽñïr!™œ<ÍÝ´Ö0à€4ü›#$&ø/HGœ/Cr8!×(‚›ã_ÖêRŒ3Da`Ë?ÂAäò‡b ,]<À§§¹Ã?Brpóÿ^ùo™ñüké¿1Šj;;}§mX»2&þì,ÞÖU óökÕC”AÉW9aþ²®Óz5ìVéW=þ•±+Péõæ|j} =¦GÎ6ª7k#;8Rk& ˆ‡¬Ïòãªüäs0ä‹›ø-vºEc¥|§—Vï‘€žTaY³8Ý;Ë]r|+Í™bŽD ^ D”ÖÉÔfç?ïîXî_])]ENc\bÏ&£î—æ¾µáR]ŒEO7%làZ—óPœUû¶6Ú Jª\Œgµ…³7„´ #/ÔÀÓaV”U@êßü~ÝéüÀ2´ƒ€‹ŽñE0M cíF¥,&)Ü9ÃÞ¬_T4´FÃR½Á¦ÄÔ)éxI$.e|7žÐÅÿ¥Œ¾Ièì8yÚJ(¯ ÑæÝß”LjÒÁ#ǵ€’'©€N¦m´Glõ CÖDçæwî °Z;¿»Qßë²rz ‰‰Z»pHW'{+’¨„6EsÞúáZ§8‚^ÚÞc•NÍ´¨‚ˆ‚˜šï¢ð£Ý¼$FX ëPéCÉZµ½ï› ê0–è{Br•{˜…QÌ ­j†÷À´pÄps]‡9£-ö0“Ÿ;ªú‘â徚cémIuº5¼ZRïcDµžÕʰ›×IÙRíaox$[ ç©*Ð4Ù(ôÆ6& ‘Ÿƒ r0äÔ†¬Ïx£I /ïñí΃î¨]â]cFgÀçŠ÷ÞlÂ%hT";l`/ Õ1rZ·xø§_u‡’äŸe¦…A…ßÔe8ä ¤£ü-±üL–‘UPPoo±Ûã{Œˆ‡ú ‚ºT^öÃډƴ5ÔÁ wˆÄÞº9ñ?±ØÉâŒÂw )i_Ýò´ÑÈk\]šX-1½qäãÍ?sÐ\Šç•VãB%÷ºÈc«·cj¸$©!Ûã>òâ­ˆþÌÓAÅãO:?gj%(ì•PèL¼~ÉÞ£•êQüÜPN¤)jO¨ŠýújSfóͺþE݃aø·ü, (Æ*|ßåM޹¥yÕ374Ç£Õ®ÂØ»­Q~è·\‰Îðl‘Šø‚Ÿ´ƒ.ÆhCË j*Ðg'BæÅ´ÅÑ´|WIüˆÅÜ’TØW58÷érñblôÏ{cbÊ¡¦%Žók? •>õªŽ}ö »Œ¾·}^È÷Á}Ë•+g×ïQ±ä¢…—‚``cûÕe„²nËWwÆZõÌÖ¡éþnˆ<²ôB7œ«9q}Iø[;³PŠÔ– êÜ1Uø9MâX­F׌ î†îø€Âï2ü¢TÍ…A¹dæ%( ÜÍùú îý~þ@ôÒ;@zÛš¯"t:D8¡ãª°6PV±9¬¸*ä5çþË£‘®¦Pv)˳¥U^|‚Úçµ[“Ü9át(¸ÊLÒ]ãAƒvÙ÷+ÑF·Bšà盾L¾ P dJ4¾¼pÉ€W&¶~ ê¥¤Í É8ïd- *ÖôØ0¡žË þ–Þ˜ ÛP¡JTë¡hÍÄe}£0-~èp†C™Eë8ú£“²Í…BJó”¨q’¹´ÏHF†Õn8øæ“Ïk|BÂ3ó¤ÖÂQPßKí™kæâž§?ÛJ€5âÐzµò;˜±jß²+•aÐ×#•ÞpTQŒ]X˜n›‡åÐ…vøZ§iG"ÜTH|bu+0Ò‚ùFù~"XV!jáÚØÃ²õÕ3ToI6¯X&w}Yžq€G¢Ý™hŸÜ»^ýk¼x ô)mBlU¬ŠûóØŠK¢™[¸h™Qæï ÅŸÑó¿5AÉ5ÎL¾?>ÞÛ`y$l[/9jM4#·*^ðŽû–ÅK‹›“á¹9åÝKá}A‹{KÚ¾eÔ¸¤pù3çS·ÞwÝl›•kï²£¶ÓhŒ;ç­'•BoâÃò_– -!êY'^µ;Qfð´R|±í70ð2¢òŠLG¿`ùTRqþ#ÿÞðóÒàªKF!-‚O°…Ãkã'½ÎOþÑœW±ë­ÊÁhýboéÃ_S¿„•µÜôåË{é8Üx¿p·ôS†ö cÑ1‘>f„LÁ¦zo$Â| ¶ÿzš¾([êLáÏ™’®DfŸ²s1a¶ûIJtÊ<]L…W“ùë_ÉÈ' RøðD\©žˆù†1ŒßŽœ3&¸Ó B#ÁËSéþŒ>¿ýsùs,x9`êí“ ?â ‘®ÞMS)=j/Œ†×IFMa‰®`L9 ÖZù( [MH·“Yü’ÝF ý—S=r·Ô8SVïú;ÅŽ¥'ÛﺽQø ~I‰ãª•2p[¼ù‚b5ýþVì¡9h—oª¾òßn0 ä—´û”¦lµ{‰¨låŒjYí,"fâÅâšÊd‹e†Y.ˆj\OuÍÒ¨}Fßì3và 0²5¦Ö7hŸ‡î®_+‰$>r«®àÚWGw,fÊè@»v÷£ŠÚU‰/·EÂíyÙöÒGs¨$ëP±súmÙnÆÄû+´N~…—›åÒÀ *ëóœØv¤‹jбçJ¾m_÷öì¨Â"ØÝ@oî¹gþÚ(t«Ògê–Ïâ¥aLW´íD~(œg,i»‰mk[ ˜Ø² HNK6 ¹í~´[&iô™“s—iLØ ƒ6æ× šòaD/[³Ž<ì¹ÅFN›l×íå ¿ƒåçÇF%8§Lû˜<$aä`ñ<>.¦÷­Ñ#ª‡óFTÒe„Ð9!õQKöÃ'™·Ü]põëãÅ3 êfEÀ§ÅóŒ$üã‰Ê„çʽñ#®9LÇtA£ñ×ô·â„#ÝE•“°“OHÕM^vn4Mú¨S¤xÚGRÓ…â –°Ø žÖrÙ"´CÆ­æAx›NCVéòóïdÉ?ÏÕ=&CÈÙ Qev}¡DEÏÛåIÚ’›¬KBë©°8-å, -øA¶Ôп¼êÓ5ÇðCz uJ£Ñì²³y§5½Æb‰~¿ b‹N¢—Ó›cä”zÌWb¼Š*‹ÌeÁ¥Åã¯n¯¡Ð‰¼?ìîiÎÒs5"ïx¿ïm»›X_m+Qôääës:=g¹ºê \ŸëªžÈ¦£¡š¶ÑñÅݹ³)k&H|d/§o]ý‚`H&Ä_^,ê<Ó^­—æÓøÄÜEüôÈs×ów¦ñqaÜ—Ÿ ´6Ó®Y'¸6B¥¨ˆYcëFãÂÜ/gRö>„ÜêŠgDdÉ^Þ!¶X(ŠZ×Þ…æ­÷†G¡.òNѹk<‹Éf3vJ–â*ß wàñÐøÔ8‰ŽjËj÷ —v×Ã×µ]‹,m.Í/¬x}žÉ7Æq-k„¡j9 BÈ]oWo5ù¿ðã­ßK$í„…Å2z/ž:=’³aaê™ÏÔ#“ƒ*سŠåý•cœ.fö\gÀMU›>âClÑ ’_A5 þ`B‹÷HVÓ¸÷Åš¹nNÊñÚ«Md©®z_J–y-Îä·M8?ñã–òW)*œ£?lõ tÞWHàhSGp¿FÂ3q¡’Ôº2·å2§žáS®Ûh î_LŠÏáþùªF3w3Åvv—‡À­PÛG‰¨4é¥Vk£ÈåýÐÚmùÆ©HâþìûT*€?Úvµ Ãt¼Õ:ÐÖ±MzÚ-ŸµþÞÀ™]^\`ûÔáÔîÑaŸëKŠ•A<Ú…PýâlZöÙÅÇ^RÄus©¥…w­eöLßöø B+‘”xØÍéÄ~ØÉn;Üà4ãœdÖ+#ŒF’„íë˜Ô©ö·:bq Î6Ì”Y*Dj|v6${€>ÛÌÕ‹‘ñ‰ú¡K©oŒ[ýOéÍêÀÊ÷¦Æ°ßTŸP"Üo (x”ËQ¾¢ïjStñ‘§•ëÊ&:º ÊÂÅý¶µ‹xÛe™Ú<ËäÃÅz2 Ÿ&4ZlVf¤Qœcà¶z»^_wxÆÇ„GofAÚc?úOŒ©’÷j{BKˆ†*|M‘b„5µ×éýÃ|²œ_Ò3_Ý9Ùôv6êf½دGI{ Í'ܦ¤—ȱa·³Üqʆ&‹N®îo(É"®µ9t0úxúHC_ÊkÄQ¡ÉégF3þÑb—\‚÷j9¦ªóP^H§Œ ñ.‘¥*–œ Oo×õ㪨û¯õÖæ¨Ý2ÜS•.f§(Y.?UJ„ ã ±ß~û X¯ÿõmô é;á¡j“ž7pÄþ༾h:1 Ðå7DÖKg<\"©2BºÅæÜÅ‚¦ ‚ñÐDÇO¨‘ï}黹6ýʇOê¦gyf:±íí–:ÊÞƒïèе+y0}¯3p½«òO#ÑÊåâÌÞÒ6ùÕzSpò1?3î†üô{„b¨·ôÑç£#ôâwffç]ýÓÏä  ö¸žËãZPÒiÖ ¨)e@t Fäøzžl„2BüÃ3VUQŽc þ;ï¶ïþ]Œ€ C±1˜hù¤¥o€‰™YÂ<ø-9a]¨[×%÷Éi»ò·Èá6(Ôí¡Ñq¼z ìõ•˜P®ØŽxy0qT€NˆFxÐSÇòÚ‡¯v[Lþ•uwÎåìÀF] 2[”äí\XÌs(îYuð8ø“6%Z† ƒYo/êÁ áSnl† x–³"³un÷5¾Ýp &óãò$ÈÍ>쉛§J,NaVpÿcÇXüôq´<£èxZÖHUC¹ò£Í¡¿ž¢—]Dàãå·ç^3í—O2Kïµðª#'N=c¤\›U`§ÛlÍ–5SDö7ä÷kÌ‚ôÌhÞ'ã•ÊE-¯$;úÁÙ /4¾Æ4rŽÜÍ šŠÉ1?.ƒ2d¿a]f3äQ5Ar­íóI(.I@_ŬgOvQ¡Õ<¾ñ²û‰þ½ý‘ÄÁDdÔ5FE\±ìF@Ìõü 'ì •-¹Åúí! øEŸU 5–}ìIúKUÁ²„mÓ$çy”“dóÏ ÓÚ9n°îW´¤p»Ð½*ZÍ&BŸÈK ,?ÿð3-ûŒ_ð.­}!DàKˆ¦¡Å×AûcìK»FïÍ}¤Ó»8p¦^ϵԠ#œR¿ÉÆaÀ mÞ= k* õŸÒ)HYtW]˜RL§Aq"¸0i“„Ç/¾%,Â^±B¤‰³5ËÀB¿ÅLÎC—&èO2?ô×}ñy]k½ÍÕßIƱŒZöZ÷øDb¾Cf2(™ ‹ž…‹&À¹}åjɼã\Ý %²-n-&_:»†>=îïx-Òa›ˆâ.Mn=M:4°wÂÂë­†×I…’D&û0¦opº’†,A§%³@^ źñÜ¿¦`Çn=›NÜT)û¼Æ«7]«ËBI‡½z% Ý¢*A}Á¾¸ñ ýM‹:œ>Ï "FeFji?\ˆ…²—3aïÎíñ•åIå¹ø¸ !BYªé\XÙžDºýVc›9Ãþ¨0±™y/Ûà‚Èñó»R»«:§ÉGíIš¦ÈK±OV¥étDxõªØ<b¢^YÖ¯p|š“6šì4‹j Ýg1 ;Ìó>\&ЇaÛ.H*Á}sŸŽ/1=sÿñJ{_a~GR¹_5Vtµê[Ò¸C.Q)¼c)¾ó‹7‰6È~Ž›î)¹CIµÆQdRo•ìãÑ^ñ82¿œ“r™bCKÂ&Ý"žb€¢«¹¡Õ°±4Y÷h¥6­Ö픟¦e#µ^›?ì{.~†‹Øf÷ðæž6©Š¯Rž<`óN£,wvÕ36pRŠÔ“YWŠ)*¦oêÞ ÍšÊ=‰aÌºŽ«1¢‡± ŽKQ™íCÂoM^gL±è^N'xì4U‹êô‡lPUÚuñò~`b]G•ÛQ¼•YdÁµág¬Ê€ªH±ãgŸËѺ2ÆYiõW½»XŠzнš`õcæ@³’ŸŒz{­íÖ¦Q&ªÙçÚ@V–±GÕ†3µJSOFÖ;™›w^ëy%T·Œv”ýÉQè'€!¼ûbœÆijcd#Ø3Õëj.*Œ®±²ŽZΡ®Mô|$¤5Dd©Aã›7 íºwÀyûM¹ˆ!’¥"ñIþuKMàšmí°±ZM†ÿ/C–³[—TåÍn¹ü²¡>>uµB¤×s‘yÒ“KÈZ¤6'O€qf£GÊŸð‘j©7á—•ZGmóÄ…C¬³=yHa¼S-©ÇÍÈÓ÷¨VH¶93}è’͈h»f·ƒé$,ÌG¼ÈEZÉ2á&‘X:q"-á_+Y(Vn÷§±µg$ßÂg1˜¿yÕ^ì‰7&RñvÔÏ)pìlDFÀ˜òHdTñªžðíõ·Î0M‰yðãáNr dO_µÇ]Ç”jõ¤raGò½4܈ū‰ŒxS=9u>ˤ޾ëģεIüx)ãºÂA–_M á×o‰ƒ^‰W×D:ýä1eŒ.–¨•\œ5XîM‹-ñÉFR¶0I•]YóÞìTƒí+Í(ï'T_÷ É/2Œ^>?T3»Èô£—»ÇˆÄ*ýËN6¼¯iÈkGGÉð=Ä8$²2ϱ΋ M <ÌÜšMhð“^Ä5ìM£rQ+ž'êxêëÞ DGí~ë èJ”ÜV_Îd»¨4Ÿ;@§š_fˆÏßõ¼Yäªv»×Ì*áBÂÍ}6)öT4—î*äŠC÷œ»ÂlJˆO›"b Þ «ñ¸_ÉQ>l¦Søù¤¥£ž” [Ž5èå‰~UîNS3Ï—2|îq˜%rgeƯ|¸ŒúÑø-råé•7Æa¦å]•häÚ%®•¬×nW¹.+þçk8æÖ(kúÌ“RÄhXáÔ?G$ #/G;¬úÒQGÑsï“,wˆ1 VRr"ZÛäv› nZëóèß=Žy^}W†KÚåfo?ñoâÎïv‹/õ­Àþëî†`h~páeT½¼øa)j-ÖN8ƒ–3èXëìR‡%`V ÅN€GR€{¯%M3ž9ÄÊT z’Iª{¹ÄpmF_bø…îÍF"@AåÓÏêOá®Ñ».ã“>zÜnŸ%ŒoµöðdK0ûtt0Ë>üM&¨ß‡€C:5K…×}[Bbü}ª¯ÔüYwû†&ߎí4ÐHÐúÁrPùB ßk 7`á5péäè>ä±ô]ž\sJÞ$—Äí¡ê¶ŽýÞx›*0«`ÐtXÜæ¼•¡è+õ`žóþ8^,e”ÉÚŸÑΧ ìc¾°\Dx*9¯Ù̵Ÿ…ŽRêÒÀJ¡’±×óÜfÍKãÔìÞÄÀÅuó‰‰ !X/¾ ÕŸßxLÞË–* "3ºº¯è ~¸]¯aºTiÊf–y A4kQ[ŽÑU¯ñ¨þ}:Vw±6²QÆ,ÃÂ.Šž8êR¹‚4g{Ÿ¢L>ý‘ïÈMü~ÂIb·¿ú|Âïî!zª`{ú±»¡ûì$™:8< ጉÞx*áòä=ªÒ­S»£žLÚK¡/fÃ͈ˆŸ\¦Å–”]·%?Kõ¬¢+Ñ(¾<Û¨%ÒŽ‹¹)ƒ‘Û̓°mf†¼¾Ü÷ôöWð6¶¼Š’¦m­ÈSØ~&à“ƒbÖ;g—ŽGFt»¢TÜK•µB‚‚ýb.º€.·~|"ðYF÷ý‚1XCæóÊRbŒó<ÍÝM5¹e…ËüøT‡Z—¦[>gÿ•f‰—CY|°ã2Ç)urºh,˜ÅÜ\-i;ÚÆ^O¾{V Ïô•d<ÎöTòRäâÙ–µ>šù;8•ÈÑ>w¦Êj>ˆq[tSùw¹´V¸ïãÒ>/^G!ˆ§KÈè¥ÙÓì6¦ÃeP…| ·’y¡»'BvVŒï*Ãr©ÔàïS›ÝîèVCÇ<ƒ+Ä[\¤YdG£ÀÙ¾ÈXþN»¢³[ Iu\Ô•IÕŸ™nE“66ñû€5ÔƒvvjX¿š:ÒÙÜÌð%’q̯>ú§à~b¯‰Š×†FE7ƒ09åy 'oàG·Ñ_cÍ–Ê[© ],×~–}Ãí‡tȃÑÁ×㼤ºâw¯ô{Ö±Žîâ*Þúé” )öúÕ@J˜Eëw½>ejŒ§Â ég²:Îè»Í~£wf½'BRŸºi±Ï{^;ê8‰²Ð¬òµgè™tÙá6Gé9åM†ØKR š2§ñ¢ZÜýº`D³äÖDhÃBD¡ ŸëV Ä+õ=?"ÍGøÃ±V]-æSͪv0 'ÿ0Î>-\ù‚kŠQ,ãm>ðÛB˜¡žðr¿7¸s[ŠŒ®S‰—´•DöÉ!CËWåYH#öÎg3‰K~”}Á~¹L…õµð›á<œ=5_:Ú]Äžc~W(¸íˆ8sÅ/èw¯ê6o’¦Šv÷YmÄwHøûõ Z´øÄ è+§Û‡#ã_s”ž !-´^Šã‘ÈÌ”Ô<ýSAŸ¬n^|d¸k\¢§Üïÿ8Ãö¸dÖ¢¬#‹¢ÐxB9nïZö7|Àu2ä·dù@övÉfT5ATæÞHÙ¥:z”s꫇²éô§££Çi÷¼ðš4óQ¬×c¬‡4vã¦*3á=š_y3 gÆðÄ*àÎRâû‚vɦwÿɺòŽÑI¾Š![¿èÍÙ\‘ùE Å Õ–ÞÖUBS6Z^Érð¬È™õÇ/GÁï ‚ÚjPˆ›œÎÞTÅÏþn°f“N…º¯¸bHÆŠB̈ñ©Êàz¨“Z ˶<.ŸÚõôŸ_¤à·¡A5nJâŽ}L‰{SÐzsØ;¿yÇàjÓEŠÑ‚u3,áýfqeŸEâhjÌÑ¥h»A34}1Ô/1«’N9‰÷E3z0Ù­G”Rxs<] \$O±J–ï…g>ôE9¯ë€CH}ÓîœG?cykäçM•éwYƒ£Ñùô§¹äkÐÉêYWHäÇ[áòj¶~t”.•úYöÚExÒ·Íål©ù±–tWríP½ÁßFa{‚Íü$¿û$Û95£*—¶àÌ”‚9"„“'3¯†ý¢…u$÷à‘ÉÖ|p.а°êóŠT„•Ï^cËÕ‰s§‡±ë CÞ0”R^˜iÎe„xÜô›[W€ÉÎCðÅavCNˆŠ:(‘XЦ¯¶g©$(ÛõSp ^^Ì1çpÙ#–1ÿ§p@@’3Ÿ)—FTzêQZ²©{š£×7 'hŠëéŒáÎB"ôû÷$§¥çLôJd eº°ýÓoyÞ|Êxï1+ úLGùL" B›5ÄáìnË'yÑM&Ûvòýsù.N¡ å=ð2?ϘÌHH‹EŒ½¶f¶³:ïóð #:Ï+N?'I;fŒS6ÊD’ Ò©É¡М†žŸ0›.üàŸõ½þ~9|‚=Š [ºá¹ïE2ŒÌ—ÕmÐÖ¤ð¾G³çˆsÝàâµ³gð ©ûV³$9õ¥ëaÖ®A÷ý—!_¦õzö}V~R[ÍQ^”S£µä`‹%i)ã¹gu ‹±>•_èÎÔ6Ââdã­D­›gr¯¹ïb?ñ¦ЬtñM2ˆ±Ï`LóÄ·ËáȈ ,[E)Ÿe¬ ÀÑ\‡é49‡ýzzéà_âL=ÏÊ™^õ‘ê‰RÛ½(§O‡"r<ç#'©næ§$~b‚+³ž½VÔLNÂîZÓ›$› ús5Zg†Þ÷Ñ9²g£æÔÕ6•fñB…ºH XÖpÕJtª¹OPLã±çY*¦]Ó‡{ï7_E8ý4j)C#­ÒYZÃÖDà ‚éö‹ˆÌhSç ça4?O$¡çƧzŽeõ–~€s×ÔTÙ Y*Ýò±jìßÈßF|V¿œ¡©kÓÙ–rYö’ O°Lö¥<¥„{Œ9ØÍ[n¼zâÈ|Ó8Z/©Mxò#§§¾åŽè*? 'ç«Ì$©Ð¨ÚÝQÜhrÀJËì†üÆ2Ù1þ¯zVŽMªãkh5]O±ýe>Ñ-ùŽwKÜQ»ùÞÒOÕè_As[=ñ”ëÓ‹… zûôóŽˆÏ$>ÞŸÐú’ªskó/ñ«G´öÿRj”ÑŒp7Á§Ù!;½ç=|ú©ü;Rå2%Ÿã2MïÚOÓ8ïÖò{„¤ Fè‚Ù‹„ômœŸ@ÆHØŽ[/”íjNÅ<ÒíŽ76ÉÆl;UR­:[,å8š»’©vNø*BdœVé­v⑉î€4[sj>Dˆt¯ØŒ•&¬ùÇx‚ÐoDBçaN߬°˜Ì÷®¶»¿TB 8â}„ͺ*œ(ÿ)ÑŽ`MîÊÛ¿Çœ»RþÉ(yÕâÃÕp¼l‰No)iùwôZ_N\ZŸí!8^»”¡¹[¹«U“OÍÇQ(|i9I÷©f?+ëÓN Šðzä î?šx"®ø$ωœE >Ø89‘ÿˆ³ŒuàÀ¸Rýr¨0œ®ÛjË&Ü–õÌ+@ÞK‰Ëq#Þ5§$Z¸g#ê¬mÝ“|yõ…­» .ÑÇ9Š\ÉlÉ”‡ò¨•.}k®#…CÊÏŽl:ÈëÂe¶I´ôý€šR“!¥hž¶Ã(€†¦ÝÙ_ é3¿çlxôe—>û¨tKº*fæ&BUÈâò)cù‰Kf63é’aGÅWÒ¦ 9ÕvÅÀïÕhTôL…t.ªª›ñGàÁ|Ji{ÃòÙhýð>! hß®é< þ2‡Ð¬^–ü¼m¯Œû…Y6¾½®øô+=¨ÏO‰”ºmÀÁw¸‘Nª²ItÁP÷5÷Hk[à‘üõK=Um<ÚõOfHâ(BÅó ]dHÂæW)¨(íöFLÌH$fI΄ÂñN‰#Õ8 ìÃè å\L tU´S‚|½p«ñsYþGSä÷"™žÓ^×8½ñRÎ÷I¸w¨ó|4÷AhJНê9—ßËú|—jB&½xßв¾ðÁt÷ºÆÏaçOKY9«Úïm×2‹8ÝxpoÂÈíЉJõG¶ȉR’"Î{ÆÇ­Ì¥n~8YU\\ݤŠzcñµh2N4Èšwâ ’Ihóá)µ"ñ>l|ta:êíàä?¡Jq|´´ÕØúˆ¶“ºÐÓõ3ÚÛh äæ×@tõÎU°zoн9Ûp)fO"d·Šyc§â‡CÐ^¥=Ò€/•lWyR• ‰`8;Ïà0îI(œV•Jì±pKTi<±…ÃêàܲŒÔ<¢Ò9Uún÷ƒ½HZK#.ŵ~fISî5¯/Èÿ+¦¶$ ÖŒêf[ G ©QÃkíi©qâüÕi·ƒn]ÓÌ‘ïàì^ô+Û]ݳ|Wµ¾:[%š»ÿI:à¸hž&ú<=%§2Sf"gß·³¹d®áî3jÖub,ü«ÜÃsK mÇÔ1_Ä› »Í¸¯ÊMbŒpè’YÖ‚NªlŒìȨ‰Kî½\ñ²š_,ßwÇ.àì€ZEÁ#vÝe¬ÆÃ»ä•Ï#ù4î‰''NÃÍ©ü*œž!س.]AhÕ”SQTÙºqº4WÎEωô[ç°,œY«÷8éÆžÒH¢ü‘鳕ÇF~ùUIuÅ~cU1ÙˆWVXsDZ³Ïĉw^E‘åÓª¥"½ë°˜+5 ÉÁI•Ì‘m|ª‰]BåΣ}‰‡žëIõ5qúMé"EYóÔx—WB  "\G7½“ ×ºÿ¼ù`eÌ,5jo"òñŠ)s—.ûSìA–.gˆÜkC !drðÚ´éËÜê&>—’sR$ÖÄ;f Ö˜ØÜ›Â(ñÙÉ1%‰ü¹ü€ä\W˜E¸+(:]Ö4¶×]*b{ÈæøXVÖpµS¿›È§…õ³¾ñ0©P°˜QÛ ¼õ ¨³f‡'_~ÄœùÖP4?NKüÔ…ö=ú*GÑ/(mJy»ÐU*3&FÙ˜ósŒ­ÛÀPlzy„ bK¸ð ©ëˆ߷ ™Ê4inz³­)`)S(7ý¿cÆöD*§'ôm¦ì¦üàÉÊ2‡õì*•¶¿ýðq’Ös )%ÇÆ}ûÕ''»ˆÝUb¥<)šo£`˜C:u‡ÂN¯_%ÂØ,ñð®ˆm.i !‹Oi˜¢®ñpéŸWîÐÒ\sޔɛ‚ôõ4 –äIîàÇ7ˆÐ0u&,˜ÝÊŠ)_iè}—űC0æNvŠ*DYåèiFV%\¿:híSÉ!Y@º;ô~Ðé6â¼Âœ§û@mäùÈŽc¸]sõëïÕä°YÂX2»Œ †‡ÏxÍ›ïÚ½^MÕ(d@-†C++Xu:7.ÐÆn‰QÁjö½˜vYy­ó[x š|ñÑí†U„~Û<±Žr˜ôÍ„j¸HdÙ%Ní<Õ`i+ÜÝ~?ÔÏèµñèù¥è 6Û”øûØ3Jb,õ†ÒÃû;ëçí[U૦ËR ÷A°q…UÃw_g3$ÉByô/ܧÌÛ¨ÈþÍ0úŽØ<Øi¤ x µo {7©Œð±Tq¢jÛn³íPÄëëÍË…¼âÇY `ž÷S{ß ) QVŠÏ¸î«6 G¾¯RÍŒfÆjõP§Zp­d¢Si([_­òÁsX®åþvŒéœšÁÚš*RAè¯Nµ•Ø¡FMQhASÙÏØÆJøcy@¡A¿t¯lË·‡Sɬ¯ß1/ìLN7zÉ-Ä,×Cq(ó î‰iõuÖƒ¡}S–øUtlí{/9ëå–ž¦ïØAõ‹¾7P&YgT¯ÞLå/{±ô7Æ©Ç ê€ |Øú,_|ÏYÛÌbª°iWjì¦D YÓ^Þ¦+EÔHL6¦ÍF JÛ¼ -ñà{üU¯¦°»öðÞ[´tµ®/ñYÓ¢.vüRàFR ‹ê&màøÌÚ§ižÃü”‘TÎÓOém´¦\®ÔÙ‘³Î;<ÎÏ8’®T øJËkÅ$c>¦ÈÛ¦cñ¼É0:íW’ñ”­ì:XR±éY0ÁxU³b’ùyÕ|$,ætö‰XÄ×§ÈÿÞŽýŠQÞ ,~Ì7 ]Õ+ñ <‰É,…hõp mš“õ†Y–sqpÛä5V‹·ŸÏ&ÊÄõšðýõüžj8C[›|€OAQÕ×ËXÐûðÞ}Ù͈~œ@‹B± L©SD?Y0æŒó½ ?é-`ö6—÷ Àù’’zÈ•Žâø¬ä0º™d˜•2à‘í$I`›Ò¾3æ7÷ˆA©åä){¹·—ðÙoË:y–y2$EˆSžä•m¼ä/Y Ú²èƒdàŬUwÅk¡å¹q<ž¬dé¬ÎZ Æ„»:ö‹Ã@ Â'Œ‘ãW೚¶X“@›TXò—¨ue=È,™øòùæÜ‡J?7¦æ| wh‡q³øú¨n3B¾Vì-U)xubXyƒNŽ^¼´Ü_)­ ï_ÅúÒ5 CÈ6Ä”P….#4ðœ„øþ|üžÀö¬Êp_&Q¯\{¯Ü[O “á~wþ9C¾mÝ‹ØÏ³æq <¯'ñþ`FxÉΫ*&é3«×£ø‚ê–ÒÚÚ²~ïÑ+AŒ‘@\—¯®Ã-Îú/Öµ¼Ïe…ycxðž^®«ÊéÌ”ê‘^Š—è dÈsG~žRJvã°¿–ï›mT–oäÒåiâŽ|ˆªCì2„z•ÇÓLgQ82lyŠF…AY=Üîvçò âã®Mg`µGPë‘y£n3"ÈûÕS/ª0/?{s•åá ÜÚ” lUsÞ}6ËÒ—‘ÓivñqÑŠ¯èßÉvÓød I–dÍã8®?èB1à™œ€'ÓÎGÑÙ3F‡&NOâŠÅðüæ1ªÜðø©n¼Bôƒf ºÇºú|é ®šŒš/3ST †b_co†iPµq™q€Ó±‹ „ó½åÍvà28Ì]FÀ#­5`Œtø|÷$?8¡Þ‹’¾ŒÞ¹*ž¶b6^t~ß’•ùšp.te>9uïº,»t•…ÎZwRëÚw1gˈíÓ.§U»dE­k„‹–p±d„<‘w#z ÑBé Û~`ÖcHÁ=Œç8&Æ|7šõ5Æ%Œ-ñšo+q^#…qh. Å{®·a©…G²Ú‡25¶R.WpŸ¿Æ7­âí9`Ñ”OÓo´Ö`µk§ \sXwNtµà†ÞVÿßÿ°@Îò$8rL §-à=ÖSÇ!SâüQ©‰æ2.½\ ô)€cÊ>x™'‚ÚÜÍM_i[-»{êèWÂg“éË.#ªö)Œ‘­ìê:ןîÖu¼¢H„Û~»³…žïÆcrcøý'ît)êæ@Åá;„¶Ñ¬=xe½h’BôÙ ¿¨™„‰ô|½opÆ#BÆ ÍÂ<ÅGò½J¦"DµÛójÚ5]?77*Ưô£¤¢ñÓ:7&U!.ó‹|ÜÖá5ÍŸ [ŸeíTWŒ/ݹ°&‘±" ê]UE›pŸµáÚR½U¬ºM/\ö¾E0ƒ)V(|®±@B÷«/,},+øäȽ,Zó.R=Ú¤Ìø˜¥F¸0ñÔŸüM$„Tð>·®Îeâãôò’ £”gßv(Ú¢„ÿ|‰FÐkk!Rm=ˆóT˜ÒI…·ùs(í@w†ƒ^Ç›OÝNH›ÁXèÝàW/E¾²<,ÜÄù› É{Ãt¤X¢9jp¿Û„K _ ç·DÕ«4ø|/½v˜kË Â­> Q)móOsºèãWÉÍPNDhc?š‹L9_@äWgk;|iÙØM£­ø2 \vQZ.ìÚ°6Ü‹ôVëVÉx¢ËCéʦ¥+Ã~§®jp˜\{×ñí0Ÿ_$Ô°¤ªˆUU¬­/æKÒ²2ÉjK‡´jPŽY…/iáÄ¥* ÅsÏHíE[Þš¼ù:»T2öí‘A‹™ìMþÛw^óWùºˆzn0fBÿ§­sê@¶mÛ¶mÛ¶mÛ¶mÛ¶mÛ¶mókwß™›ÌÛù •Jj?¬½ª-YS:ÔÐ{íšv†ïu¨ÈÁIà`²K_Ókª'‘Ciï:×Þ”&…¦®€O%gxÿ´I¨*&Ë|À9å 6ŽUEátœ½]ý+(#HïmèóÙxÀx‘ q5þšo/ ÂâÕŽmçJê9;ÚÂYÕ:fÁÕ>U×á‰]#\ C¹MÙìeñ™?ñ}Ù?£™à ܸ‹´|¥…v JrÄ™úO–N:‹¥3ËV/! KXµòŠKpì†ÃK ê™\Ñmb)Ÿ4­æ²c†yïÁ+ ˆª¬F^Û˜Žû}è!÷~å{?Ö?ñ0ºJó¤sDþ 7”Ì£q íl¿Ð?m@dbÌìãoàíÛ8Õùøšó ”ÍšHðH„çu DÓœí9Ðg®;Î4™’m;˜qKÎËdç¹^ß'ôD±Þ³›v1ëì„w(š¸]‰ hYµsÇ2â[g”ü@—«fÃÌãIï?e!ÔO}JN¼tç›Å,ñ‡¤äfU$žssÁ|ÿ^C›b=‡Ø› ÚU:‘&A§ÿ‹ 2ý)u¾‰Gó‚=º'?ÿMzZ§œÛCÀsbj "£#îp“£‹›&ÄI¾JÅŸBmÝ ñµ¿óG¡ƒ¬’vm9Rï:¾]ΩŒ´$…ÈtAH W(âÊ_ ë)’$à÷÷¦ÛB‚æu ¬LTCéCòþÝK4p'„,²Ã®ƒñ ß‚Ê ½ê0ÐPÙ*zq1ñí¥Eq“ ª5Ó8ÄÄoÞP 8V.c-ê&CHÝ;!ü… Kø,…A9‰üãÂ,ãñÔi†× üdО‘‰ ÓhŽ:·º³=9œìÆ®0q*õƒ«> ºzfÉàÍúoçþMB›QF¢È<å`2}Ei `¤í@´çc_m%VIµàwy·AîɈôsîÝÖ>p§êÐÆqÑKÑç#ÆÅnÀ½mâ‹Rø+²ªÂ¤ëkÅh%!ãU[»\‹2a¼M/A¢o¦Sx—é4üð¹DÅ{*©_ùbB¤Tí°{¯ãÄbuD¦§ 8 tñIJC=ä ¿N+*ÅskÇ‚K\Î µGì#|FÛ”›žÚìe6t¿OHVß/û6ûµºà+隻ǕƒƒlZìô …Q)å•ò…‰ÁÜã8Ë,[¦&g|"½aUÿºÅU}ÎÒ.ߥ•ÈJÝ/“ììtlÙ,0¢Tn_’bâx<ð°øTÒE’Pµ\–‡(»¢ÎíÛþ®ø3Øe®˜ÂðeD!øíö±•vݸ`í‰~ö­Nz!Ÿ»ÓToÎiw&ÃTUÌgøø´ZçYYávò Õ]A[RMáfõGŽÍ_&R³€:e¬Ky˜*|îŽûüN6rRGi‹Á<: 1;-Hf_¬oh£zä|ôݸ"ö‘ë]z6åîf7=ˆ÷(jÐq¡©$´[±M%`ç$†–'WÝ5‰ÕqÓQS] 2ǃÁ J6gõ|ˆê?”žØ¤En"sÛ­õ¢T‡]EäaWgÆò t•W§8 ÷>"n WJŽŠw”Î+m2K$­­J×]´³ ë^åŒ1s{õÃ}©ëUB?Š0× û£ kÖ&©ƒ28ýIúü¨‡4)âLc|<:Hk'¤Y™¿KÝÂ1– Çž­-ošë_ß±x°ÒUî–¹ÓÆ¼¨¨5+_ÁÒOÿ„ýXaaYŒ`bwté·n©àÔqúÕú%ñ Îí0ëíÅŒíÔ¬ú›Aª˜5Ã¥½íü¡StKmN‡ˆQš œº„^ߦh¦=öœˆ_™NûÜdŽÍÂoЧ˜‡”)cˆ%>+îÉÅwm(yÑ%‰LÀnÔ-£—‚\$ۻˤH)ò›¥âCú¶Ëºè¾ü¾®ŒèÔ… †uñîG/4±Kgjଠ@ý+ˆ–ŒB Pqõö±‡7,·Vµq`©¼_cØäžX‹ ¦ƒgRà ù“»70]B‡É0ËAš}+ Û™vÕ£º2Ìpã9!v…ƒ@-;}£æþ³iî­kÂŽ‹¦º¿zì‘g´_©–¹‡ ÞA†ceþ2G¹ŠMB%Rû‹Âa“(‘¥šõçdÙ©áv³#Èb†ü,Þr+~/e.gW':üò?ÉžEQa“ÖÊR°ï¸¢Ü“7”Ê—=ay™ÝUhæ~ÉÃ0ø‰1§Êú÷—õÈkÕÙÚ6VÍñzÌ-.?R/+žàRå¦Íò˜ÛF{ŽÎZéCp¬ÇÚOÙ[µëè¬tšÐ¤ˆ 3‹Â7#ëP׋ŠË¶uñ ä@Z¼÷âΔÆÚ^ReªðYU†‹ÇH;¼w ~ùObâ¡s\u”®øm³`MøüÌꕸ/B)b?÷'“4ë'jÑ 6¡Q&Z¾ÔývQEÀ‹çÒ^± V ,Â@§·?˜»« ÛµÙX«ýA²x±—ŒÕ.÷|m‡ìϱ3Þ)IËâž{Hz×2Ëk …`nÝ1©½ ­§W?æJ³Æ¤YºÏ"u÷F³¬›&[¦¤q‰¿tÒ½eÕ_t§ö☦õh†¦-ú-hXœª ÆB˜]úM¼ùÚ«ìôñ¼±dÂ6àt©cÇéýdW¢iº6ò‹ÃÆ[:ZÄæ¾&I çÁÖp*›s+@1NNÄq¡ò¤±Bx¨?䆇Ríái÷aõcÈ÷h¶L”F^óž~°•.<L}w½^ –ŠI^Ïx_¿Q­ÙtCQ)ã.KV­B£“ÊÙRÆ(¥«ØXØ ¦©yÚkZ–˜ß"OÌSþòí&c)O3ÇŸ»u‡œ¼Étë OžpEÐÓ_õ!Zµ¶SÛÔù® ¢¶ÍxG•Yj_lßê)”Wö+u@åcìb²µ%B•ÂS®äô¨.±êÅ=62•µ5ÃíCSP|›’WS#(ÜÜ&¨Gr Û!ݺpù$©Í¼êÅqÁRްʽ«ceT<¤”´SðCƒƒ¯‚’í¥+“¶ DÁš­1ËkÐÌ*sÂ:PBÿ*b”:ªêc¸.¢ô(à "´¨À?˜$‘8,²oªn‹D-ÀÀ|ƒgr$¤IRáÇ–Ñù…ÿU€qk¨…Ü…-أʴ5‡Áâ÷ïìè~5ª¸ ¶O#ì±ò"Tü¬°Þeœ Ÿè_»¡êÏÀðÁGªzC´O}+ÅËV¼¤ºÝòW•žÏj\江¸s«áè,Ý!Ê ß6¹3`óƒ”'g©š4I6¸Š§¼¦¶qð7ÏgF‡xZ­<šÌWìqJN‘V7mí]Å&÷§Ëçc…‰í5Èd*›'YªPA0Ô­âéS¯b›Á¡Û‘=ZWøÚTÿ‹¬ä!9l;±QêCPÈ£J¶³ÔUù{Å“„Þ¤þðÿHC´*Ýë]NŸWrE“CK¯úžG’z®ûT( Lñ!ó‡ áÇl‡ÂcÛ8ÎÙá~ßQ„´ë°ïiiÁ3ñqìØK”õ¼÷ƒ'8i`‚[¿G%íä(’««}tlpÀ€•|ºª×KuLÝî´Ý½ ŒJ«§$V[ ]·šV?bû‘÷:^ 7ŽPÜïù?ªDZoÇ”.VS\,ÃQ~‡]wéZ¡Žñt¸ l²>¯MT …"€y±)ÁQákµï0®Úf Êv¹ awDÇ%A¨Êñ‘,ðÀ1SßýÑ\Ð.&Ú¥ƒÀ\>ÿšŒù4(Y‚eQ=šFž–¡%!3l—á'‰Š£À ¦ÖÉ]…oJ§ôo÷¬}ËíM†çCÖ:íšÍÔòäSO4Wvq9ܬ­¾æ9j@aÕ7_æwdðßý—¦è°(¼oã½ÿé3¶`Kl|xøÖH,ÚYIÑ^ßðuœ õ+áB þrÒ²ô°‰èžH¨¤›¢ofè%̧6X» 9ŸÙݽÎqa¹iÓ7²,Q2 1•Üy÷c+ýº<,xàìXBá”jv‡°ÐZ î¶ë:;îÚ˜`ö ùf©,c= “…:Ír#—ÍGRÀe)%ØÉa/Mâ¶[ïóUdýFrfmá¿2äp>æ„ÅN$u.îzŒtŽ”Èj® ©>Yó’­?:Õàðó ÒmP\öÆvk\„Jtã´ü–^žÔ•(Uµb†ËW4wv1Ÿ6Ô‚¹ï¦,{¾?[vJ êh¹Rá>ÞìÁyW7V9f,Ϫ>È_“‘ñç4uŽì^µ23º`T\šÿc­-à¥û X1·m¦+¸iïÙh3*hÌ9ü â)ZPcîºbÛ ¨rqïKÞ ä]Èkª«¨xzd!ÎtìŠúÕ7*WzOÏñÒ)]¥/l‰Ixèd¹ÖÐct¹c{õÍ«Óïû7 KŠdÉè”ï" ‘*lw—3/×0(èGRU c'Ÿ¢ï÷æqáheõ¥­G¢)«¨Ý´eà™‚7ãJd¡¦ ýÁQ®ãù<Ù>Ï÷-ú $ÃÜËšÐÇDüeÞ¨S½béžGî§ÎP”†f¤cƒ3ÉMuò!Jz¦»Ó§Ckto1ÖÏ0ø‹ÖKGÜš0wSVÿCjDo7–“K•“Ýñ…M˜MÉéÃ+Í=é3|÷ŧî#Ѫõœ6PO„¬Ø0š“o3ŽMê,:6ÏœË̬1©³bïéï£|,£P>¶Dü"ŸÌÚEQö‹æÕ.Õ„ÿzà9ÊêÅ÷AŸt¥Ðk†°ÅÄ…gùkr=;mCÂÆB¯èv ‘5ÙK&ræ‰ _×–7y“dä¤)¦ÿ•ЭÞUܾ¤çyxö©˜XÓíØL0@ØtêX˜…Ƶ@Ùàyf4P\6½u1Ù`Š<ã$àg}æêasB~£‘pe²§X4²ëÊÛ¼ƒ~ÚÅ N}gÉÓ\æw-L¾Ê«²ƒcN`+f®*{FÜíáW´½+;ØòFxÕÏYª¥#ZJY«‘¹è þµ;´BMúEm¼71ò=µš‰(;Xï9¸ýI-‡á†w®Ëoˆk@¯í cªçf…ÝÌ” ksmÄ$ê…­C’üÎ^\ô: X/DÅÈ-¾sã˜zª5†$•3tì|‹oÏW׋£Ì—Âé^éCj‚:§Õ©åÂÞqéjDüô§­f}3»%@8´å Ýúš OÆL 'ˆô¯ üQ¦,¯¤N.VUj‡´øëOä{Ë~¦D¥øÑhIªM +ðw¿ˆ<·ÀþS¼«M£ŒWOê²ðp&]a»Y?³DZ¤‘,Úë‹D÷ìî ñÉ-µ‡³F(Qø 1lÝÜcÛ ñNÐÊPVÊB¹kêvÞ˜úà©ÇZ7Q&eÙê8cúÔkÛù 7öºj€¡Yáþ “Ǫ»Ó!‚éÊ—LÎ6f-ë¬W°$@ñ$`Åé:BNÈÛ*º#möµ&[fEQ\KâOH¢êÚ!bÀ ]ï/=&\r®’~, zÑftU¥r0-¤œåÙ¸¶óKå átlYäÝó¼Í»XúïÝ£=QB?CŠrFçN`¢$+ß`i?½YOÓ=ÒTËÀmc©K·'éz¥  4‚ºÒüž(À¤Kî6h6,t)]©Â®CÖOìPQ´ÿ&µÏyJj²¤>ü|#,7.¶ƒäŸ¬&˜®`@–hƒ.!&u§ L ¼®*Þù…÷*æT3Ųó\s½ÞÝÿU®äøEa…HÊ#ƒÚYØÏS¡ XOq̹ûY-¾›{ŽEÒWÕÁ'O¯]Òõp2’5¯qKºpµ–ÜGrL@%¾‰A…l+髹àÝUñt7õs%ž¯*»6ÓÈ1!Íj|kÙÈRãæóîk†îC©ŸAýJñ‘Í…¤Š|àÙƒ3Ùb ‰½/ð¦ÕîfüdÿÏiª†9Mý½ ¾1‘¸n5îEQõ¢´#/ÜÇp„r"ý›Ê–%d2Â}ºŒ|G¹a–½öó«—;¾ÛZ±ªõTr²•3t½l®77ÞÑ×v jŽißR(r¤o•}5¥Û'îM†«RvE+«K ¾5oöp˜63¢‡sªYÏËUY]\&ÐØ¸5ö6$×%>('oš´©î®XkÁð!ÇþþU'µ/=4UR€ÜöDdûÕ1–ñÜå÷o -¨3=0é-,‰¨¤_QíÎ÷o²-â˜a>òÄ©ÜYèŠÏ(5O·ÉÌNKµhas®€…QsW½vòŒ%o)*ò™-}ðª XÈÿç©Å˜ ›($êT$÷M¢.ÔÂ%ì”b—Üf‹Ü©¢ìÞaËyúkþDÔ»õ+'MÙº±q…›`â•«êE2kb¶_žNò½&pçæ·}žð׸á|qej>Øö±E }2™èÏͺÂ_®«Ž_dJOÛ–ƒƒsð/!aŽ"IùQòcè àÆ#ø ƒÇ] vð'P¾g¶6¿Üð] ßkBP€sC€Ð+>’ I°oÚ{Ù5UÃW±76•¤üwBŠ;·–ðr„ñn•0Û3ZÁ:ÅوƘDH¯î0ÞÑ5)‘ÚäáÇ;qULrǾ‚Dñ§ÀA†žâ]Á)4:kGWy»ÕÜXß”ŠßÊÛ$U³-›íæœF¸u.¢}>LqQ„«Ã:VæÌ>È2H‘jCìÆË¸D†îaDê)i£0h5–D"f‹©ÓZò%žú/õ(9üûWµðBéNsŽ£3YN»µ:gÃØš¼¹$ÞŸLâ00Ó¬‡Äm¥FNXü\41ˇ­ ²(dyg´ztŸ‡RIÚxQ“tD).g¦«‰eÝì +™N¶@§‹eºž]ÁÎ~wa?w±Áß“›5FZüËÒõPÆþª½û-ékˆ E!Cÿßžƒú–˜ù{ö’Ívux=%É@ïQÉo§ý/ ôM]áƒ%úÞå?[1¨¬ „'¦R†Ñ)i³Ÿ~¼ú t”v5=ëZ'·§Âœcy5x´ý$t l°*_LÁµæœ€Õõ‘kÃ9­nlÏåã\_mÕ-=ŠÂŠ8Š.¾8#î'íÀ‰S$¿Sªì)ôj]=•Ï €} ì­7ßÑt*‰Ø@Ö\ÊõÏ?Æþ~_)þvÏ2½¤Ï· ÷^Æ{|ðûB }òJ8k.R5cÄíqÏ\ü}gÔ“Åé•“B~°òGsȘÇAoêuóŠ M!Žmy·l1ŸôÐwwv¸g_K8¬;K²æ{Ë£µ¯t·§~ÏW“"› BVåîLÛW‘‡p¯ ”6«óüˆÈ¾¸3'Ó¤ q]þöJ©Ép{uN³$aQšOa„›"­†·j³’àŸâÏ5M  2žèæx÷ÉxÝ?ñw#gð²`‰¦Â’ÝØ6“NüU_ÿf¢ÀÆÉžÔ/Ói®–Rè-³ãËFÙ6}Š´­^b|NRþqxË!ž8¹×Bk 'ƒÆñá¶'qžCŽ|ÞÞñ…‘ƒÝ?ø‚fr‘+»ûö«Ð&ŠM%pƒ‚bbè(‡ºqÖâÚ9k]üÏÌ5üâ=hk•?Õq-µ<†RÓè1³ü*C÷Ór\´$…n$\ÌÚ=“îTAÖYE!GŒˆ¹^9‡d ¿n-?RHL%Ä,IYw81ÕêW2‰’ý2]¯•ƒ(mVíØâî¼ñ¹ÖeëgVù¬lJ¬éùh˃úù⨛½J$E{ŠJ XCOKýjE)+01c«~k*d0lïwÅyü²7N”KìB·éœñ쇊HœN¶QC#E*ÅŸß)£2‰ü-Ew–uÒ‰³ü™èû©¹Ð±¥úCdЧPÓç7óLJÖ<-ݘk÷jG XƾT%Ï (^)Õ‘Yøc…ʝa1å·¥ÞþGKþ9C/QOpŽUÊ×P•ŽqÛ6*¹ˆþºÁÄÁ€ú{5 B›º³ÅçÖ—‘ÞdO‘CÈ<*ÜÓÎòªÔa0”š‰Ó™^| ŠcÏ¿³ŒÊì}ˆà4q h@j€hpÒ_a‹ÝÆzQãbÂÆÆåðtnq`€(Òv\O$m@yKO«9{«–*ûÍò÷© Ã “-diÖÓ`ù›ŠÉæ6î½½w_U£9…˜}!gÅOÑ„2–TÆÛ ~ _A4áß*}^odeT05^‡ ¶zR¶–oE£Dý~ú%ÊÈ 4Yq=kÃµŽ…Ò­+ Ï3j~¹•©ôú¡ Ñ º«±þÐûé ÏU+ýÕ6/ëtcÜ ]Å‚ŠR­Pø™»hð½L¼X—¬ÍÃÊþñ®~5Ïõh\¼Iqꘂn5Ù&RíE<CQ-i‚ÀÔUuRÞ‰n¸¶{²ÃËgÍé'ï¿ÀI8ïæß|ɾSÏOH š ²û¶ntÒî4] îiò˜¦½Cv¬š¥µiÉuÝ`ûç¸óàÅuú˜fW„âg¤=¾Xß^~›KVZÄl Øfgy‘ðY`îcëq`&ŠîÑh[$p–ÞsŽhH™ÉD—±R2Áw´óÖ}ëí7nÆEØÚÓ$)÷áËê ÞÈ}4ï £gïÏ#ì]¦•Söçæn-“J@ŒÙCÛȵ(Œ“^±= $dÇ“*nꈖ»âÅÂ^@÷ª¶ùL †ç1*ãtI'ì/ÛŠ Õ¦#)dá0þUC‹«mí©çÁÎHrÑïQMœžÁæààX©õ¤±˜‰Ÿ¸Â-H Úö]Z­Ý½•ÖôýfZ¤$ùÉ>ëÙ®ÙPXã8 ’mˆ* vµ^ßÛ YÐY)†‚¤ð³ˆï‰Ís,ª%zk™¸<Ë$½ã¤Þ©…ºÜñ&˨ÃZ»P±¹²‡vã3Z*ÁÝå2¹”ÁI÷Dà’«±B攀Þwq3[X¡„J+ÝN;e^ûJáIÒ¯™Èd‡Li6²ê ]q…¥Ñ4¯šžOÿ8l¨¿QŸòàâ£X/NÔ‚jÞ†¯\K8LRÌ\] }¥¸óoa*è•WìQ}=ƒÅõ@áGó♨Ċ0NËEŒ•›Lp…Ñ´VqùãꔃbóéÞ‘ö]™›ÚV¨®( â½FÎÜ–­¦¦qÔºEªt@C Â.ü§ÂB ˆ×·ñ¥ÎŸ–îe#ú徸pô/¶>:n€t0ëQKl$ËŒ+">NoPQjË9=. í2ÁÌËü\ˆi´˜vTáúÍWÌaïÀزÿ ¬+ åþcÀžwaVìçæ’–ѤÄ=š?q€Ú÷Ï©úðÈí\;‰L¢²lÑRè['{iTv˹(ûZ–7@‚­I‰òÊëë5OO-ØÅ4”¦†«Gö Rs± ñL÷í¡yF¾i)qØ·åõÅê˜2?dI³MÙt–|" ã`ïÒ ]]Áhu_Èzi%—RB¬œSúÉÛåq ‚[ºL$©Éª/¯®y|y&ì+ñØÙƒ$Rz6‡ÂTÍ–‹4éÚÏ® ªoA¼æf'J 3åš*¨©}Œl&!tc|Éü´àH AØ`:¢ü¾¾Eì1Å/þÁ‡¡’÷‚é:Ìs€ct5e»"x¨â²ä“åÜÊ‘AÍ‚©O>ð~/)Ÿ|\W|YÃYo¦çâ«–˹ûï,‚‡²!M³÷46S¬`£¿Þ¤WÇÈâ†ìàv˜íVŒ9ÄE"ÙÖ“Îð£ŒÒ-—ëyÑɘ@p_‡65cµm»rìþ\Ò%`”‰ûìn‰2ªÜ þ•ãÉb5y>®ôÄCÈöYêõ1ðÓ^pOVôÂÖçBjLŽ×³ñM¥Õ€J7¨WåÀ,¶Ê'B 'êê=¯Ø/ˆyZG&RÏj´ ²È ÊÂF”ÙZË«õu²xe  G;Š»£À.ü+¼—BÜG“™xkZ³&YÐý< p°8Ê5´2šLü!,æÞeq£k}ƒZ¦9úóG®øX¼=lE¼i¥ö¶¡&ko_¤=cüSDWûäÑ(Ò ƒ£ÅÍxh2¤§¸ãîn`fFªhžá›AÂ-{}מŸP]; Y~P€\)zÙå"@ö÷âtñ­òxj¤k­=ð©ôÙÍLQ*lj¾VÅ´/6~/¦—ÆÍ¿·eñ§“àXä6),Þhó‰Éå„{f²VbÏ¥kòÝï^YSÑîkßœº§ó"„|IÜŽo¥±‹üsáL{*xzQ‚ßá‡ß¥srL”f §ú-VóIþâ,-õþ’GŠÍL‚ɸ‘Ekr9÷à‡8¾¡ó½‰^'ÑÏÝ™™.Ià¶»ôòÌsu†·z ½{ëêœE¹[«˜zÃ%¤ï—^ð]ŸKzù!°ˆ¿ž÷ÆýçK5kZ©lfZ*Á«r¿÷tkÒ f’?¨ë­©•Þ“JrwbòtºÛ>˜¾ÙÌó`$7«"ÓGëcßÿmÂg%xîÒ„?‰ùÕîäSw ÒÁ‰6#ÔÆ þö麑ç$&ǸØÑg7†fça¶Ê¼yZœZ]bSdlD–ê¾D÷/ƒwsÅ_– '–Íx fn ¼E¢““%›2]>ìWõä¢Qÿ{1€­<‘ØO”%7«õä^àU@TòÑNïE—Xøxý‰jPjË u¶ýÈL1ØYD»]¹è·ÅeŠ€ÁáÑU°;£cŒVn?e ‹– U äÃ8›Ž*‘´f î€ÃÛ'l„\߉ݎ:zîÉÇìŒü—=€ÆÈ©ùϵÎÿÌd#Zíìc®Îð«Ca8ƒÝ+š× ïùïV ¢¸Ë–LjŸ˜?µ¾Ìv¦`Ç#ȧ-0KÞZþ}¯UKËH"S)E-6Mµ†´Á}ÅËvëÃUJ‘@¼]p@HijòËNlT¸š¨L[9Øúµ•‡–ê~1”îÆÀ{÷°Ö…Lë»n?,yÄT9³ÜCéŸj‘8®§¸M¤îŸ;FøŽñv‘qRä²0±+\â>1OfB(tLþ Tñ¯mwn™7 ü@Ï“v š)‹÷f}õ*÷I‰é"¯ 4Îf{áŽÐK†õ/³|KÐ)œhºÀ;ˆ‹åUÓÊðÝZR° þÃc\2§FOE<¬šÄ*£tXtöz[ gŽž©{'½>`ã )/½6üOWψt h”Ì Ëpï=u³Y1‰¬¯æ"Žö­ B÷{“+¸vÉWHq~Î÷œ.¥`¯l$Œ[(ò»°R>f”/"gÅ:¯oCAù #êK8@]zJ[-TwÌÚ>XìñùyptA¢“Ú×–3e£¢¨é{Ý}áå)álQ°™ß„'©è__a^9Œª®ˆäxÇéÍ;ný+‚—…Ûç’ƒy>ÿ—hqþÕ—ºv°z†[XpË¿ÂD¤I·þáØÑ}î™òZ'}°ÊptÙ‡ÍÒŸúÕøÄ2|¤Žovˆæ Þðçâ”o޳Ló`8žº{kJ É´x‰ü‰õê£Ò ƒÍ tQ˧£DÁyWûò­™À円î]¼ÝD®¾£èO¼ƒÀ@ü+¬ã¡*±ÑÚà6ߛөbƈñbîqWggè½ù2Sˆi=`t %§½‚Ë@mft¿¤"lÿ82i{‚ £Åu_G%廢¹ ãžÓ+½Aà Û4Q^™ a°À§å‚¾í'ÅêB´Ç8…/è\aÚ[•þ:ò¥) ©7ePÉ5¹~¥ÌCû7jµÒkvû·§S ãàŒln~ÏnÚjÕôÜ“ —ÿ„4·ªúò[ V Š†jÑòŸ…Ìnªª=ŸGÚ›=ã2¶H%gÅ%Ÿó¨íYcÇt0å_¯àÝ>”Yw-}÷ô?#Ãød®ÿà@½ßêð‰ú>¨Œú!­­ÏøO Îø´¦Å¢0ü¨¼*ƒ‹3Öa¤ÊQq|u`ÞvFÍa)D£ Ê×—oc®[]?Ř¡áBÒ¯0¸°Ø]ÜÎ8ʾ—x¶Û…ë"Û}ú ¥Z×ç3C“¿ˆð‘Õÿ!¡xa_Jz‰dþäF„þ= —° ÉjÊYT÷mXÜ)Gúβ§mh?M¨fqïȺö L¾=çá€H¯p[Tzì€ô{s·5] ÚìF^öÎ$ôC. .Ę·‰€o³?e+ðÍc#€<°–OO•8Ä€twAs9[èêqÁÈ%] ´=Ä5SåÃ~Žæ.¤XˆB|B 'œ¯y¦ v醸óÙsÅjwi}fo5OGŽ›T q#PéëiÒÏóõÌÕÏÞ‚TÃÿÖvÔ¥_.Ü{óÓãÕ½m1ƒ÷›x¤ÁµŽ7 @Šoeo¥Á•êªSXAžS*6Üw¬‚HU¯7£ æù9ýÒ†ˆñ3âjt+8|Öªž©ª¦Û‚¨ê©¤Â¨n#ü°)øÄVïC?M礛ô®Èº"9ÓyØŽ±0üU[Ú²”9²)èŸï.v$¨âÄ8CÁ-¨Œóð׬`:Ùm©AÚé+ÍlÒŒÌÛÐÑDN¯Ýúÿ ~ÓÒ„Å˶F'òMÚ…ì`÷ŒA~š7k4/úã.Ñ4mO-þgR´M ©Kl±ÂÑŽ„  ŸÚßQ©Á…Œõ€`XàâÜEö³Ú‡ü³½áFƒQ­Teµ9`M )2Ý«\©#0|Sõ¿wÀ*;?@M‘¤~j(hZá~eò Ó€õ1ó‹Lâç¢úª,o¦„„fóÊPY—æØ ÔÚ ×Óe^Åî¶U²Ù¥Î/ç#§ZÖ@·Æ‚rƇn·$Š_%woëÀª{ÔU©]Ô©ñ(½“ %?~™ÃN»‡xö‡i„°ê|„“Ü%”97m¹5™ÅÇ’„HVùa„‘žÊi©¤™Ó7 3à¸Q£§²g"Ù\±ÃVd¦"|ùµ¸»ÚÅ´Ø…úO4é " —¼÷ƒ¢.ð¨+Út«á8«&B]¼ ˆøçÙl檥KŸï¥bM°ÎIP¯“ ¢BœW«‹0ö{Z5TïÕŸ\ÒØû>ïÌ—?®_1 Þ™+Û¾‘ÉpyËD©'f—ÏijþÄ®z‚†¯ë ¤ÊMmÆR‘®ZóHVÚ—Z¨2]d9öÔã>A÷U4˜›+ÿ‘Ù-¡\f'Ö g*léV0?ø©vâújRN×þ·ö8),¦Â€ý¤‘–ƒÈG6BàkhìËpàö¶êÜ1z–P0:5kÒ'ƒÊ5‰¢¨çÊñ5¸ø©Û™ï`’ ÕUªu—r^¬ŒËxTU]RZ´}Z¶Ë[ì»7óç)*€¿ºÍ4'C`}þý‘ärC~R‚XS:s¼Ù&¶0¿Ÿ°3ÅæZÊʹª J£ô‰×Ciü 4ýº#f6þ{5a`ãiÒOÖëç£×ØëÌõw¢Š¡QÖ3óè/ ß'±-©e0ð8ÉEO­i~›uÅv²âc(¹;HÞ}t\“Ÿán:± ±äR\H,™r дty6‹Û½§¹¡Ìg€k-ÃW£P=rCcnÝÊð¤÷opáX"µ’pé ¹ÕLŸ Ðæ;N9þežJj6`âaÍL-ZÑ·b'©<Ø´)v¼~êãØ¦¥{UBgMÑçK¾ „ƒ‚‚äÐJBPëâ6y^ð€³Gçp^xë]ñ§\zd,ÅÙžz1&1k.ð[q`®ûp>~9},”£,Ñ,ª¦u&‡…¯Nɬշ¡† b­õ|)é‡2Îç#áTЍ@.¥¢¶w ïyy|z¥@^ÑRÌW‘—7³Y4pÐ$MfSÆ~³µÐìœ K:ÜdT÷‡¦\‹± —œ÷ é‡ÕUÛd‡à¯Ù+ … 7ƒÌî§L禣%3ú åx8Ðz*V°’9 ¬p§R7£dãÿF=²ZêäÎeè>¾X"LÒn ¸Ý/‘6Á£çåÉ‚ªú|ìžK6çxM¹9õù¹6)þù8†ûÅÚ«ÐÿÐ6ù§¬÷ë¬KŸˆý–Jú—¶üî53»š-ÍÍ’(Ö×®µ„/ˆãDÂ5—Ø)®ŽB|Fkª*¸TW¦Œ2uÚñ²G˜îšÿëÕ2wÁ¼÷ÆAú D@EtÐË Ý”,PÌ©<;ÃÂS%Çî-ò!ÛМWü×u†»¼Èõú1²eÙ‡¿úà›£2µ‹ñ¼$Ì *Ùèž9ÅÆþ¤3ÇM^5 Zi 6„%÷÷X Í„S"¢o¸Ü&"Úº›Ž÷ÃÎô,••jº{Èãóv·¿ù\òzãìnãÓûAÑtÈÖ¡¼k= BXCËøÒ(›wÔ4ßÚŽT$Kò@gösŽP"4á@ÄêÉ ¸aæýóºÎN,Xù÷*ñ͹ÎÁKŽ,…:x)s^.PE$’5þù†Ó-‚`0½ù_éÄ–„aOªá< x•]©ìxN¸’äê“] ²êŽväa·ä¤è(ÿ`14a$éù39µ „oçg·ÚÊ}y"е“ÖCì­;>e‰ƒá>v¸²¨q:œ+ï·¸IÉ@i[lw­øÞ¹8KÆM–οÊ5 +¬-Npͯ¾?…‘ŸùdÙ2¿óýýèÉ‹½A²-e\  àEÁ„…Î9憬ÆAü\±ØÏª‹.ÈV¢mµÛ{Ì[ŠRäþSÄŠáiÂ#— ú‘ƒѪà èQ’˃P×@ïlŽ‹¾üÆ\íù´°ÇÉ1Õ‡çPKnÓ~SÙäJ>i¤YÑ—E‘6[ꡪ&;Ï¡SÕËÝîŸÁ¨ñ”Aå4ÔŽæ ÂrÙx÷ þpa,32•…Åa æ$yf¨ïËÈûÁ²Õ‰ fÕºÃ{(ô²£fÍ©í]®ÏÂyKbYðæ_t6¨ºÈµy$°4Bõ–áLÔù¾¶gbUTJýo¶]¾ª¼º¡ær¾¼ïÝAxÞL çF:ˆCœ¢é²Rî—'H¸_1|u`OòøFâÏc¦<àêt÷J½cëcTäÎÏigˆ< GãAÅb¶Ìä9+¦PÚ`FáAN3 ê ’!Ÿ\s ºj@ìÿ`N‰å=ŸÐvJËòjÀÆß,s`²®ú0f°O¼$ÒQS_Ó?…0Á_º/ Ç8àmNÛ,ÊóÃË` ¥ºõ5‚Ø2ŒEž÷{Êßê”LÁ®æã$Çb‰-¼Úx0h¾\‡hêyÌk“¬'ðñ½]ªû_ T²î+&&qÈU¾ÐìÞâWíë­õ­ݧåøÀaa<€¼+þž­ß¯1Cï€!;”b^û%@ÀÙÍ÷O›ôhöN²* á›™{W; Ô%Î0Øy»æj³z=-¢ð /!&9Ÿ ²2§©Zs|äœÁ:\- .?åÈý‘‹Q¹ûUäql+mKÉîÉ EÐd+L’þÿ¦í_°ç¡,½‚D±…#VÏLƒ]k¥–„W»±pŸlD®á AV‹–-Ox,V·|SÔ’éÆS­°¿øöô{3ÄÅø`ñV”ßó ’WPç´£ì™ÇÞ®AÙLZz„–a¯Œ<¨iÕò´j"VØ®R¨¿v‡dŒ]6Ðß&X‡×ƒ¸«M@Hù”.4¶!üÙ¸G–W™èéÆ@5vÏÅÌíλúÞW©c΃°“j³Êj ç²¶b߈NÑBd)46BàARü«Ø`xø=ý€Õª¼³;[µbx¶ˆÐ°lÆVúÎùMúÁ öü°CýÊiLJèŠáÊôRЖšý7NS9]CB)lêH<-CF¶05‹ ùß1Ø0Ä‹6GÕü Ë«\‹Ò¨ ϦulÀ{.‰u>bµ;M/°yø¯r^:ú•û½pÏ-T —h3¸Nò’›¶Ö›„9g­,Ž] Ôà О ²Æò7 ü%‘Ó Ô“ðTßÉ´WÎê^"ë'6H2LZsŠ),¢388eàÙV¦™&º§æNÄüÌ]ºôð/L]¦¾° ¬;IAµÊF9§FÅ'.—Štv  }Šé%V'Ÿº"‚ Uàlê…P¾uw*Uˆ;_¾7a Ír†Q«Ñ€î¨E%ÅübÒ"`ý4Úøy™TÝÊŠeœ2]+VÅ™½{8ˆ•ÖY׺Ý äžw3‚m%BMéÅ!Ÿ–ÞSñå’õ_„k{9†¼%ΚÁòŸ\£O4[~Å¡J-êN£XŠ9ùFup£ðòÎõ.pÚW‘è‹ëÝ>=Ù’í&þ«L!]"ˆWàÇuj‹“·ˆ/mi’·côyÛŽ€‘¬•¬„¦h©(7̦ôH<þçk2Ð I¬W@ò›ù2j-:A]I,Ð4ƒÿf-¢™ª³kðGªÚ <åÝiwµ³¶X°|¬¾¬ÒJ‚\;iûÁñ5%2¨©Û}Ü"9‚+’¯T^’,âícc:T*¹ÙEµinIÍ› UiÍwòwZpÑ©üç…4[€[UoIÕÌÈ<„aÔ¹VƼv䜂V´Bù“jŠCètsU÷y§Ü ‘’:`|ÒÙT›'4óϹd»Â„+=‚/€ßF«˜ÙëÞ·œr?^Iu¢MŽ‹¦óÊýj¨’/(ÅËT?7ÈžévÅOÆG´+–·`&©p@€:/O~›˜ehFØçÞ/J2µY-_¨ûe_¬Á<¼*(q]Ð)6Êz^½’1ý¸ë‹`Ö`ê˜ï°dů®¾&î•kqq‰,g+¤•G¡nû$á*èC`E±š‹vA'ÍÐ’E&gþ¾ü›‹\·PMäFz2÷E´BptfÞÔ> stream xÚÌùeTœ[Ö Cp‡Ü wwww‡`A ‡ÂÝÝ Ü-¸»[€îÁ‚»¸•sº;çí¯ÇøîÏ;E1×Ú{͹dï§JRuFQ3 P dïÂÈÊÄÂÐêH{:5€Nv@gFYc[+S "%¥¸ÐØÅ d/aìäp»X”M]ÀÛl,,¼ˆ”i =Ð ì4˜x.Æž@Vñ_@äìÂhbì ví-¬ì´à-â O'+ K—ß1¸˜ƒœ~ üVz¸íÁ¬Î¿ƒŠ1äŒMm@îÎ6Vc{3€“"@ ä6Zh@ö ¥±­9dþWMuI5u€´š²¦Š:-@Ë èbo N 0µ4v26u:9Ü`c3³¿uËÛ4,à—±½%X¢º«ƒÈé_Y‰«khJ3$D•4$@-€´¦º@IlüËó[ø€¬½™•ñï튒¢º*’¬Ì¿«`¸9­~+ý¯t¨ÀÉþdÞjî²û‹@céââÀÇÌìîîÎdáêìÂr²`r°¥ýM aiÎäd¿;m•ØÕÞ Üp"øÝb€‚•)¸–À¿’ÿr*Š*ÉJIªk0‚«Åø»àŒ÷žÉÅÃå¯\Ô$E%%ÿ—û·@+[ ó_ýúË Üd+[g&0Ùß;pÇÁŠÀ¤.ÿÉÜ—ß‚mÿÖpÁþwzÌæ`ÕÎÌÿZêÌü;F)e% FYqI%uÉ¿T‚œþpqµø½÷ÿÕÆÿS:Kcç¿$+¨¨(쌭ìÁSglo Öçbìâê ûË~ÍÈþ.: îêäô;5Å»œþ“Ý¿Û!§£oëíkìþ߃klïêìõ~ÿßVš‚ÞÊÙÅùïˆÀUÚl÷ÖÊþÿï~oøRTB|V9Ylà øKÚ›‰ƒììÀÂO…„¸C. 'OæÿyømìAîöÞÿÛgneoö»Ò3WfM{+GW ¬Ä¿v€Mˆl@ è>Φ–Ì¿iÿ: ¿Í¬¿ÍàŠøz;€æÆ¶Î@_+s ø ÑÛÙØ <¦N®@_ï:þ/Bdå˜Y™º€>øVAü+º¬½9Àû·¬äß® !Í_7-ø:3ÙÛz‚בY äšÿ¯_Hÿ¥ZÊÕÖV €æ5è¿×ÛYÙzþÿ®þ¯eÚÀßéÓ(œìŒmÿËgå,eå4S±r1µü»WÛÿæµ·°Y9ÿ6jþ¾‚lÁç|ó[ý~p€],,ÿ弩=ÐÙÀÅõ— .âé7ô·j³î{y u9úÿ9Œ-•´7™YÙ[€§ `ìädì‰Èž06NN€7+øÜ˜=þA3“=ȼààêâû»Áˆ¿Ç„‹À,úÛô7â0‹ýAÜfñ?ˆÀ,ññ˜%ÿƒ¸YÌR+€Yúb0ËüAìfÙ?Ì.ÿÙþ 0»âfWúƒÀìÊÿA<`v•?̧öùÔÿ ³Æf×üƒÀìZ˜Oç?ˆ¬ÅøûLþ °Óÿ ßíf6û×ø–cñÖcùÈÖcéé` ´ÿÇ °ÍêLmû²‚Éþ±˜LúWÂáLæôŽìü‡œ¡³­±³å?€ âò^áúNÛýdS{þÿï$«ü~Rüuó±üí},ø «»8l€ÚVfàWÿX¢hìâdå¡Ç¾¶XÁvð׿2ø?”nÜìyx3r€ÛÍÈžMVößßX¸Y|ÿÏ^Ó¿Ÿf]™à3øoüû9=€¦ˆKó SþëÔæ°2?ÉÂÉrJ^¦ãJl!¹襌ÉN\‰¼m2 pQ`k@&UHA†ÏÀïS }‰e–íËz[rÕĵ™ªÈޱŸ¢ª¤èh®“fP¦âb@y7í¡\nîgŽéÌö„vb€æèOqÞΞ‡X¶ï¯—)dúåí«ù0îų¬-ïœlßz,¢ãw,NvAº¼>¼‹1î]¢›ùP†=*ëÐ׃¹—Ó~ ´m;x(‰›_ÑaÞûÙäñƒòôº5cZBÜu³IÐ]ìÛ\3Ìœ8[nX4'1ÿy2yñØVøááÎåpu•&Æ/ÇË3üxÌ$ÈиÆ^ø(¿x`‚Y y¨œ%ŽŸð=ÍÞ4ò.Âty(ÉŽÊ,Z¸*(µùÎ(B&ÌÏŠ*ÿ´!Ê\4VóB±†p.| ~óBM>¿!2É„ž“˜~©þŒâyÝ¢‹vK¢Ø‰9r›·ŠšÀðSwâ岟 xÚ1‹öúö!¸r-\­Ó&CäÂù+¹`/õLØZdôHoÛ«÷‚¤è”Iy,Ôù-Ÿaœˆ¯˜T{9úù’£­À»}ÐýÅkÇl[ôœ/ÖŒ‡ßÏ{ž$n õ,¶* ½Fž'ÉT]ØpÕ}d?Ä2ãØ6Ë;ö–°ÛŨFìVoùQ+ s–¢ç骦hpy&¢{•ùxj°Ñ±²Ó«‹Ú’K_ŠðÕµ`XšÈu©øÙ E¼ÃWù´îʃòö|£I5Ùoæ;ìÏ乄¶ïØõrÖŒŠºòçÆ™‚ðæN(Å›€öV»E$RBöüЧ‚3¾½*oØ-Ò^9Å Ónç¢nL§ÝF3ó+ºoN…u)Åõª¾Û¹+àP‡û×¾"–£L•Sr™ãøQÎÅŽ6ÌN™ê`bùoÓ˜iÕ?:—y)zr®¿/(Êi€ '@‚å/ˆXì¸cY(0dãÇœí.²QÉåºH˜<5öB}Ó›Â1ón±èaz[Ë÷Ä6^-Ü‘žñýÃdîõ×ÂJT9Ÿì§tÜ7Ù."ä¦síHî¨fã*zªÛЛE˜€—]H2•àðàâù½Ly³ñùìî÷÷=]b8$ã|b—Útb×ÙŸŠ_¼½¾‘:˜ãòÏ¥ùŸa¼³ƒäzl–ÜA«ÒÜiÆcá$r18ã4Z¼lòïÅéº F 3;ë³a[7ñÂÓ¦ZBù߉% r…Ã0¶Öd­àpAÆ2kÙ4î…Ç,¿®$ºåX`¡ÊX'côRì1Ð]ŽùÒ?rN|™!Þ¹ÓÞKÕÖ ‡BÏ©¿öiZsŸó%Óš~­×QØ’%+/Û‘´žG-SØ üÊç.e +C}0V´|7Oþ³Í¹$“9;YiåÍm›SÉ"‘ú.ÃhÇ£`+¢MÞ~>‡©]MÊÜÌܱûi¥«DË-è¤ÜÅr½ó d_ÊA2FBû¥/Šýž‰2»,è¥ÿúÛ¦8-ËÄ€ÒõýòTŒ! "¯\Ñôá¢Mt¤:™"5úàÌ@M¼„ šË˜Å‹DO0“â¬ôdZ¸fÁýÊyZÅz8ÀTk•u‚J![Gï[œ5UƒÌf&ù¹ëû¼üë%Qe‚b!‰8¤˜qE·’áñ¸œÏÁݼTf­³˜ ù37ýWkI=E7Ê|FáôG­£È¡V‡¢Ôu±üå dC¸ÍYûOŽ0¹äx! šŸE¢—Á'ASFcÂË8ïB次]‚IvJ+ÒKÚí…rxLO7v‹Eé¶Ñ`bfâh§×â³ÙŠˆÕº; Ê;ƒZ-z]å«t7$uoœP†X“â]¶íIl®Õ.Íæ‹.ªã†ôߌU{µð†ô­ÅÐßå⎉˜N*š$5}Ãl÷îùH‡÷V}¥Ý ^Q²M>ˆƒL¼æãçº%É ,oá…MÅ¡ŸgÌÈ7à¦çÂÛQ˜ˆo [Ä@,$gùi¨te(ùÀ~!&•»Îà #]ò×+Šn‰ç5Ý /J†V\¼ƒÊÖÆ]ëŠKà/ÎaHܤUæ3e"Ú¥|¶má[½Œ¹<ê»Í B»ôN‡‡\_PhšúBy3¿ô«¾õ¶W½5¸>‚”¹ 9X›5#ðüþ&VmÙ±áCôÏ)-£y(òŒØCrOÏTYÁ ½wý/> ïxÑë/Z¶'¸—ÔBcõÞ?O¢0îüih¾/Fwûk¹=žñÿ¸àÔ—Dª¯ÞlÁ¸ke|#„ul?:rÛ¤°Šm©XÔÑiuŠñòONÙØü‚~ì +'1=—rW11©0 ˜HóñÚ ~ï{ß7‰æú>…±FÜR1ÑG×÷¡$¤Òë=Û¯' ¾¸û©,f@é†Ãµ n"ê\jorÐ}R©ëxüeA*É+¦É¡W~çΊEθèØU¶Ÿ8tŒ? Ôd‚ÞŸi‹œÏ!î€S£nýQŽUõy²_yݳ˯jÖöFȯž:–’½¿”F çïL“¯]²Hç{뜂Ôl…ìç@Ê'±ç=mkoüZa)Y²#óšìžCiÒ{Œ¸ÛÐ\î­§vS„žJµîìDN"A\§qÐ7A†a\Ãúcº6A'7 |·_Þ>tw˜:ޱˆµÌé8£f—dt:ûM#)žÏÙé7,!d²“sáÒ#UF5ÞQÈEi.°=[Xä[wÌŸÚ&¥%lëWvHð?(÷2x6þ,Ko'VB[eüÔ¤a ·Sü‚s¹SÇxxMw®uâÎÍ¡kžþ.:UÁÄÄÅkâ9 ;ŠÌóggë:pL’+ÔÁIôÜKd›…¡h&Œù.Íoö°¿®½í=;.â¡gHÜ72Ü'Çõýè"ãǘDzÖÌc‰Ç[Ò—aÛÏ×åœÚ÷lë#aÆD!GŒӇ~©ÝÂÅ?{Ãüw¶³T[u<ôN‹—_߸ƷÀdÎ|@ö„bµ¯šØe¤ËFVHu04ݘ®“$4D‘~©ÓG¨Å¼–±¼¦Ñˆ7>óS´á¨)œ}ñŒˆµë2ëº<2ÅpÝ÷µ½%&^¸wefç‡ ¸«w¿üº’¶nÖ"Š8&13žÐVùéMPѸÈ@ë¢U5aâÞßR§óâiE8ª~ê$Ÿˆj Úð#”ÍüX½}Õs³î «Þ¶óîB@;iX=žª?;QÞ¼ipN«v(ôD“Û¯ ¿ÓEÚ$B†–_Xâ 4R¬X­j«o[´øPëfÉ—|“oµŸôqL‡ì$iÔíf!ƒ´B#ÚJÎÙQ8o5º–2Ôýõ?M‹öø{$ÆÝ/ªÅÄÛµ4À-(/_ 2RžÏ=£ÄSÙÐÜm´0ë|*éLº¡ Ô¢i?<Ë{#II6^c…U°A¡8g 8 ø8œÎ¤Ê‰ô²î-QmZ³›6p’¯ß!ç—I±Ž³§ Å ·¢@Ù;µeÈþ©Ö¤ýHóùŒc•ÎcJ€ÞDR£jS‰1ò« lÙ#WÓ¼jóÀ Öhø:{ºqØ šCãfÆÐ'ŒPñyÌc¢›â’Ñ(3f…QlEÔ©.Í>Ëf‰æ?4Ú$ÒÉyh†«bfÔQßuÐ= éÅz'SH¤êGÒ ­þÀ`l©OìÈ šÏÈŸÿøIqÁùk+„—÷P4P/Ÿ©_ Þ™L¿ò!ÑC/Ö)ªS Ä® ­¡"V/Žž!Îg/›_@ò^5¤%Ž ©p¥VÊVÅÙêžmŒëók3C\aúM+$GØÌ÷}mÞ¯oaÊâÜ.GZS ]1'±ŒµkÜB6¹zï²Ë2¦¯¸ßypOYE¬ô«¹ïø™Lf™HUÎ8»Ô0‹>FÛݶ¨ªïôë¬Ú*Ô”CÚmƒb)`c í2áb0©úƒ`—*ü¯ýhœï“D‡ã¶ Xq´ÄKK';´ °}(̃éÙV¡ o!·Ì±vÕŠŠC"Ð$ú$k‚FN®©6në¥ïšà=>èÒƒ;4wâ!mŒƽgúAØv:ê;BM™Â? ™ GªRUÒé‡Õ܉kUJR5£†`鯳‰Mää\ › %ЩŒ{<ó.úý5–&OšÃ'Z}–sÈ‚“e(|Eêù¸7*üEW:,žÇ(Ný…›Ü§·)›(‘b‡\+½$#ó(T¿HcOK 3\SQ™þ¤¸Y'K£Tqë›ABƒéCŽØç¯ ,O¦²aË>Æ<щ%G´ND63ûF)¶å¼\»@q‹£Es·tÃçTسڒEŽV-rÙ#ŒTNôB7ÈoÞ¿ëj4HäΪü)þÝy°¥^¿¤²œ¶†Œhu™Ÿ„y¾™œX=•õ|ÍrÏ¥>¼wãˆÖÎ!ˆ=毃 »ºækô2ü»g˜¡¦zê(ÈÆH¶á9ðp=•ÄïîkÏd!`înÁ?WW†÷;oͯC. ×YDži\ʼ±þ¥˜Ç8¦2U¯/¯ø9ìUjžZ|ý™Ÿx:+*`±|{ê¢ø\@…èLU¬˜7Èi9J|ё˞Úm]2ÒÑÖÄñ#g%Î…¯ ³glõaSÎqz]†ú¾(Þy³<¯ÿÚ[€KR>—ûŽßºˆRMÆ"}"­$MÁRS¯Ç¢”«­nûx÷ ŸfÜÑ^š&nCføª“ÅÍÀµÃr(z²ÝÀn¯Óƒ²¡mì› ŽñB¢‘æ×Q͹I‹¤˜JR­4 HúЦªž„_x¸)ůÐDõmLÁq1§qü9 ÉéZ…§QbÔ¹B0GêÝ`]sâ¤ìû†ào7 m€ÓEQ¶Ì~×âS&jº¹ ¨,ÔNhFÙ0wòòOª¯sq²\,ò“zU¦waÊü™¯¥tÄg…¶âã<š¿¨Ig«+óox{›²Ñ} ýë¯Bv ‹ ø‹¦„b ®›¡C=˜¯ 5[ö$|ñ¶ yQË3žÛ…V[8°µ< I!ÞMίEÖð fG§õ"Ip P¯Û]—âfýJGy#Ž×ÞqÜ©qA,¥QÆ(©WÊDš@?U‚5Š3óö¦¢¾å#uš:C˜ˆs£Š'”«¸Œw:ãèÓ+D~!«÷Î0ï*vô:sޏ»?ô‚åæ‹{p§n©ÒîË£ ű´Q®}d­Ažzo€5Åž´Ì•áªÛj¸N=a¯×ºGÖÌÍ7ZrÎã“ÇWÃáïwntÎ0xÚh~« vŽS¼Ü:-¡¶Æ«8ùü‘¢¼·µ9<4ñíb€T‹Cø²âûn“n¹Øh{Ìzî5ÜÈçÝ—Ü®GËëƒå¶õÑŸV ÄnÞ½MÝ´®žó9ÓðG8ÈíñD¤ͧÃŽª€@iÌ*?òÈ|ö¾¸m—0bE$¬húEñL´®ë¾mib<Ž(œ†¡ä2¥dTœôìhŒÄ°îŸ]ÑtÐ̯2JO¬ô°UzP;G óX1-(÷´m|?«–tù-¶óFC=ÿQÑÂDùôJSâÈ Ïœï¼›Ão‹gõSÙZ?º:_ô<í"ègžpÉü€Õ[¸}\õŒ(®àÈ]ÇC+øüöÖcIÜöŠú~3;aJˆwä4‹3\Wv-'T>š£štœÒÙ®J*Ë)Œ(Z^‰…ÍûÞöNÙ›b×rT+Ýëmÿòè-f5ŽâO9¨­¨#þa.ëîU\JW”8W!äœì0îVü‡1¸%MC4 Ón[»4*b…u’qe(–õu|rž­Ô_yiÌr;Îe_”£Å‹½ñ&í8<œõõ²&éhÓ˜Äe.’/‡™Ð¿L¬v2ÂÏËo PÀÀÉ*û£7B~-°À« ¨+î?bS¾Ñ0@>He `%qF6À*1ÇóC¾µCVÔ‰Žf¼|aÓ¹~²ï¾øž×l 15R”#Üa_¿Ñ6;¤Ú§Vmiá ëëåUÆ×"ÎýBàЃ»µ¢ˆS€xüI².žgFö=äm! ‹Ë¶¾ÊÃk}7ÛEÚÐ 4MlÚ €ƒ_rŵ½xÛ_šÍ(hÿÑ;R µ`³@/ËGY_ÔÊïjlW4•e‡†1®ìy¹OøçÎ19ò7’È|HÛ™hÒõÀq´[[ÌMuynýu’5G)™{ï„}j^WجŽé3ÆÀ‚ á¡C„:"ún*1²TÜØ-±¢ÚQ³ÚVí©c9AÎíbï£UÞýŠÌ([ÏRʪ8€S#û.4ÑƒÕæì¹Š9š*Pš:0Ï+”+b§œÕd30q+E­ð¬B¥×£µ‘Jö-nFúëQQ¼• Úø£ìòôü$:Ylt8¥œ†OípjÜ$„îûtzþéÛå¾0½ï⊯“ÆeWÁšº²:/`bŸWšú‡Î”“«¦~SŠWeïÉh¿ì ÅéìYŽEN1bäˆH·vUnÐ"±‡j jAÁþz|ÅUÜÞ wÖI@šŒ«êÈé–'nwø.¨¢†½IµžGï‹%O”ÇZà<\DCvÔXÑñþôžß0(LÖy.¯àŠÁ@­Î(…´=;BJø§ø¸ùt…ÕÕ…$©;ÁÒÙ"t]c ϸaË´oDØ/®ÇÂÖÇ þ"?óÖ$ “T NmX¬û »Ås[Å­rJC+ŒaTɵ±‘ÆýÔC‚õ5癢Wp²^ŶðA±>7Iß'–T{ì¦ ùÐ.‡¿Ú ¦dÙêÜ•…RTã†Û”þÀÍp\O.º©Zûfp³ÓµGŒ‘Æ;¾¹“E`€Â©sÔ20ÏL \·ÌK §o'TÏ–ÝCù¡}*j8zðááiW£‹ÚÃ&‰ÒÉÏ!¤»´‰½ˆ°çíYy ùçìY¯Lá2¡˜Ä;nvb9ˆh¡™u¦Ç%þÁÿ{ãÍ×5„±Y'üÓƒPó§HZ{©Uœ‰W }­vâOZƒf?oÆÁ8ÔôC¢àÉ“yNä,Q˜{‹íraô¸½ Íw (è!ºþÄaÏž·×ð9µ j l%pFã(œÎ¨(úoõíøaó‰îí·‡cKï$ÆÒìѱôÔK­ÂœÇÕVMw_Óëbõæx3E8ØŠÞ…Bõƨ¥ÁETaT`Æ«jÒÔÇóäõ¾w%i¶‹²Ѹ¨ ö…:ñ<ѳ];KTJøLç ŒI±?ª²A=NÑ4•ÿá‘)œT}v¬bw7©&»! ŸŸ‰êУ5›N>Ïê<\ $ãÝ.!Ï-/Û#,[aŦӸu£0wÎãlǰ#U¹ñxTÀ•è…ý¬WA2d‹Våû«Ö'Ts›U¡ËÏìØ³Q¶o-a8Ë‹†1zHM^;z‚¡¤·q‚Ûšo”¹e°Ž%µ×»@ÚIu;±ÓKc4•t ¶.«ðâ Q´ÃLØ÷KÈŽIëPç¤Î[ÑçÒˆ#‚ÞqTHÍÊ:¼p :Etb‚'¸‰‡wxßUÁ„ kÑZ¸x ®9-’›ýv”²/mt'œ“ž{•C™óòçŽ{Nz¥ü7¸ã³Üˆ¯Ùp¾.‹Ã«ÓwŸKð~&Ù!™ðÞQzÖ&9,geü¼Uý†‘†øêiúÎ=éä €—øëÀEĺá‚Ô:o/·!3·ó;@´Ã™®×–‡Ä;¼£Ö‡¸=F}7y‰ýç:•éñx`Ì‚oZ8~×¶\Å]ÜÈ—ôsÕ{\’‚å¸&xN]ÓÑVŽ; ± “yh MŒ‚Ë-u»üM»Í±™\e[^ÞÒ#:oÚJXºOÖ]jMºzì|°#ÇrbCãiù„×B¥î%2Ïmé< cËA´)ËÐâÈ»l¡ÂòÕ}a#ÈÀ®­]õÇ8äÛJ›YÚ+¶®WV[y|Þ/<¬Ìó²Ãá–Óƒ#Áò‡Ç¢×q»ˆ·ž.‘ä–ÕBoL[±ùyX¾Fnˆ<œ¼¥ßšL¢©¿µ¯»WÊ­?éil 夸‰U"n‹;úI¶ªºÃ/‰w=®ƒ§“ÆKÔ°«.ó#×O]áΛÒÖ:€{„è1€Ñø ÷ëÞòè¾$Ý—°ò,ÉT¤pª,Êt®%¥EµÓ‡†¼J}ã”­ãCÔûÌ¢ÅxŠëìýÉè]B¸¢ Ú.xϽ|Ì¾Ò´Õ ’CbšKL²lPÓ«•©Ë¼ÖL¦SÂÎ=¿P. ªk'·oÞ]¿,&¨—¾ì‘~oË?ŘÏRéRØ(ÅwÛZ ÄáÛévʧ{KÀšŸ)ïŽ"˱LÍl P]—zÛ¼¨"€%øMA<˜Š«Ô¢öâàãrô2’<©°ïäeúÝ­Õ'ôîŸÒóaíb© tðJË0¶âBQ-EÒ±î/˜Z­:.ÃqÉÄþÚ‚1fx’ýÄ¡PFïéÜ%k… æ\ykäò‡úÓŸÙÌVô?~¥Ç¤ÎÈ{bïTÚÔÚí÷Žg(Bå ç’Þyñ±w¿À— ) (®v{s. 0ñ&G 1L³ý:~µÿìΑµeÌd2GTö[ŽÂz¼¾ Ké%ó×ÜØy²õ+óñ]EÃ'ŠÆJ¼O†iÜò¹ÛÈ7ÏLTï^AðßT1Ì'®´ÆPÙþììÐ=›XÚªpOîÅhö ³19Gæë²t»šp»XDœ>uÜßê΢Äëª}“!©h5¿\>±¶ Ø]H@< ¥Ogb©þÍÀ©%ãKŠGÐæ[ü·1Î\O”¸hç‘mêÉÁI½£á$8W–ª+h·â‡^ƒâu½èžãíF;=yJk!t²¼ÏP1d$¤³D<ß'ÐdĤ¡öN½â”œð“Sù|•É ›¢Ü‘’i€¯iö Ú© ÍE5_¿IËœÊiÑÕ|‡²1°%°êÿ¾rðÉnfÚ†‚å®”pMÈy¢Aû°Wæ^˜}+ÊÃóW~s 5’‘¶ñ­¸šÁÁäxÉ//%wˆ"h7"Y& A„`“¿…Wâêóªo6Oéaiøaï›RÔJäÉ%ÿ¹‹²C@d¿7@Tûì$<ÂÛRÉÉžà™r¾œ…Ì…Å"`‰X¥³Eô[Ÿæs{œ…;‰!7Å‘ì$¢UØŽP´DfZ¼×G¤¤mSe¼Ê»Í½“á¨\—¦î¯™ThÀ.ã aæ–Ëã#AË»Wi ï"t~²ÙiåDËÈÄì …¬ž Ò©yYe¼Ç N¾ š¤»ï ð8†ØS1!Åy±´dÈê±`_‡¸qsÆ¥{\lß}–î}®@f@-›] †êŒŽŒ šCØ*!å¶æ†òË],fX³'‹›+£k%Ñ«…Âm3?òH Mý¡è(ãFþ ráþS íÎêGÓëk• *~ý¬¾¸'`ŽÛ‡”¤zŽ)Ê ºÔ6£Ÿû®0Sý¤V†‘á–:l­l4ËK·ˆÛ«DïýdñF˜9ßSƒ"ó°³HÓ0Ý)…sR°¨*v`¼#ôö9Þ*Ó|M2.²ÈZÑú)Ç›[”Mƒ9{¬ßãL![jÒÛ}<ÕM¬³©ó¸†–13¤$„+s¥EÍüV€[p0FŽrQ£Œp¿T!ß<#‡ƒÖY—©@û03›Tßw˜­æ¦YoÕÎG0ù%#2Ü©ƒÅ¯ŠÈPßHÚý½ÅPF€¨ýz8•…p wYN¯Íèý^¨"ž·=3w{Å”xÞ‡"ø½ì5«P ®«ç@äP¥lM¦kTXý'ùõﱃ(tsa¬,@u<úk 8²¾ÈÇj$7+R4EÄ9 1Yß äkøù·Ò6Š>Kat©–©t±.=Ôû!?t« ×ǼKé>¬Pf‚RÙí½-Èlp5Ôó†YÏȲ¯VÝ‹ÂU´Þ"Õ'Ȧ[¢k7®Ø;\éqG•~”©¯Ç§çvœTÄB$VIGb­_ï)$PA6e£EUcÀ€(,ªÅ|Vò A«ü˜±zôÁhÔ3+~5]Íxûðu\~Ï VŽ˜c–6wÕ6t9ŽQÑÇÊV2¿‰-i5F¹ûæpÖ[W¹ÅB¿”†È>Ùfê ¾c(\ÁÉz,ÌÉŠ(›1-úx©w¦åË£¥Õ¯¾BÁꆎv©¥ú°]¶7®‡€1 Ù‰k+tË÷ø¾¨S%þnƒ±;Þ0Òi/1ü—$G‘.1~\OFWæ6³¹t<.\›†ÛOß"!̼†`ìqzR6#?H£i-ÏÒy&ª)g<5ð´,DÞ¢“66KƒÈ©Ê¿ÅªñZLû:VŒþÞÒÛe¹ï{d¶øäy¢ò¼=²¾qYÆÜÌQ0»n#| ý#]ŸƒÓOÛ\µ4Ø#ï¯HI ]ÕüF! Õªw‡ìÜÃg«SçÏ¢õóµÏ®«&Wmrú>lýN¢Î©¶Q\sLœÒökOT Ž%©u<ðRN~a¨è¡‹áQ‡vöØ:ÂeȲeÄöwïÂeÕû)ðr÷‘ŒÙP%q „n=õ0r†øçø"‚iiqœL“WÉ4Ý@ÀšoÉ“ þ9Î?7ô™VÙYÒ þä¹5Ót 3q™Gv.}ùPß…^ÄÀDD±NJa 1ÄHædïiü¶"ئ¿=¬X›k‹;\Ù£ÕÕ¼~æ#Y4eI$)ŠôD–£§î[bt~ ´xàšÝòa¦éW\À9¦’Ýx×Tcn˜bM’¹í³@¸Á]&ù¼‡âj£ï{FL¸þkñfúSÛÇ#H¯·Aú(fÔVâ^~LØÔ!£ÃÜ3¨9y³!é&uaçç·ðJãéø0¢îïÃ#¥Äšƒýå³G”Vrâd ;³Ì4 g„P|‚é’ŽH œ|ßvðþKná–·êQ¤ Œ& áNÂöɨ÷ì)å”q%”6Š®mŠº²ë²ÑÛA>˜N¦2ø´®Èèq¦ï¹RQ:.±´~Êuä;ÁÉî×uZzçÎt¯kÌwð}EùˆÙ¨6'7Žuð½[¾ «3#èAz!}þh¨×ðdÄé7ÞÒռƲ)Z?'3¥s¦õ(Úí º¬˜Þquþ¢þ.·8Ó-©òŽfDUWd 1é:ò‹4Õ@â„5©Å9Ò1„Î"í˜v»ThtV¢0à‰™Gô¬‰Ê0š·=nUÍ6ݹØc^ž£»CŠíza·çÖwY¿þW•ÿ’×x¯è¹³×kÔzŽÉ§eÊz•É&Mõ+ýCk[O¤RÇMŒE‚Ñ9‹.Vμà_Îû?ZÓ5O¼²M½~%1ØÐÄeÎÿ|Á¯œÿ6aNþ…Dô%Ãh/3¤Ð-BŸÊ{œ³§!§î7óìYV¿Âþ ûìÄgUÇ@·Ó+FËõvx›^éëƒÂ{»/±«¹úκÑXÏsÈ4ä3SÈF†‘ $æ¦F¥:°!‹’xˆ²yÉG]L}ô è†V Ǭ†mˆß!d‚Š[¥ýR#¾Ph$¶Ÿ³}"±ÚÇa£ÆO¤oç:deLÐÀk$(‘3õýHab̶73,h˜@êía¢ÎÑÔX ÛŒ× ®ÿº¦ôHèÀ{LbÓ™~xJ´š¶P0кñ¶ïp˜ÞñäŠÒ2lÛ¿—C.¨>…%má…–s9Çý²Ãñ:Pâ“\Od‚`Ξ'£¸Y Üf˜ÏV+•q‹þÛ‘+…H$'Ûg6Û.·S»*_­F„L×3&®ªZØ?A”7R¯³‹jGˆzŠÁ©‰/Ò÷õŒÊv·\s=(E¿‰i·ÿ.ü‘ÕßÕ"Ó’n¦a…Gبë//(啬¶ôiqMïéà¦Ú©ÞÉÊÆé+ÄíêV¯r¹b¤ Ÿ¤¦~Íyü½§vI¾Ñ>ŸÝ‡άBH±:>1HQo¿ç·Î¼g–½Dž>þºÃpl¯£|¤ÔR½olÙÑ÷½®¬Ÿì Ib·˜ghKÃ_9m^|zfø‡FG]šE¢ø-mÎH_°x'*¾}êžÿ&ÜO:¬Ç jZDI[Bü~Zyþh Z£F`É.•ÐäJ™1ëÁüÜÁ9ín¨©mÄx‰+ï¯kJmçÛ½ø¸g·1ñÈ+“O5n^…eGLúÔïë téo$•'Äß\h¢i5aJ°Ê¥XWû³÷×1•ÝßH•d*X”w·¥On¾×ý@Y Lðu'Ä7÷PÍ|†UÒkðùxïB¡Êq­«x–1вc¼0„»RŸu{!cz›&:¸ úIn)˜‘ÚH'Tu…z¬"³$VÀ»ÊÏ‹ÝÚ™KgG,‚W¤šîbðì¡ ÜoX;±,ksÜ¿ŽÅýøþæ×ÅLò›&w¶ýØ‘”‹Åäþ„÷¨ÛÔ½ù<œÍ-ÙZ œa/ÑîÆïå}=22g½ PÆ&&.”tññß-Ùбg ?QéL”`fFd¸i~3m%WË*z DSùá_of x²?êgBFûƒÀJenV>‰±F¤°q.¨üñç+/‡$%Eü¶¡Ô(싌8cÍdŽCá‚ùJLj¶äÀ©`ïžGo±¾T]Ê‘ygeÃc½‚ˆ‡Šôý⡈YàºÇsâHÈÔ&+ä9Ëô'¯àžó\lÂÙ»cJè'¼QÖñ³ëmº]åšJxD‘“Yš™ç:×­ŠCÔÙT©›^§‰mIá^öe_f͇<‹³4äbƒCeˆµùD1gt²íÜ)»täг ßQœ¸X! ¥œxµ¨?Ýt\Vc‡…çZ®ÓKèå{àÜõ®ÄQOÐ&!¨ê¶¸°WMx½éªqt,Ò3ãX"8wØb’ïG2ã·Ÿ±û–—)úò܆Š>R­·¡¨gˆd¸qÑKúmó4è]ð|ÈÌṏ6¼~‰Yw^5JRõuwF®\‘¿x“ü˜?–÷¤'œIdâôRVNW…ôÓ¨{u“XĮճÍ.7³¨ctvW.¨Ä?¾Rìjª"XEÖ7gâJœ ÝžyÀFqUº´/ÞZ¨!\ÂÂÒîoßTÛÝzíEâVû°•.BQH*ãî :šQù¡p ƒýá Z‚‡»`—Úk?kÈ&È¿¶ Zõ Ù­-hôž_^!ÒFÅHˆ[úêìZü`b–ÜÒœ'B—ÿD™im7RçGb,„­ Žƒ-!ò^^L˜¼Œ @V\O͈JÕ³›X¿‘µ·ƒ.˵ïõ¤#;l7𘌟 ^ ¹¸2o •ô½¬ó;Å¥lŒÇÑÁ¸‹Êô¸& íY„ÙƒÒœÊJÝ=žÑ|½}†Óú™ çïÞz{‹¾™Jì. ¿’. 5óø~­&mV8ë*=¼Y5†1PÔºéâ÷-yŽu¨ð4?h@º=0ˆ¨†‡óãÝG˜T¢|E~P/·ˆŒ]p×™¾È¦±Y‘ЬĢÞˆº:ú½Ÿß¸üf…·_Eg̦“m-Îf]˜¹{v é#ÒzlG%f6,š„€þ˜ÀÄÌ3 ˜ 㚪5+&²•.‚ŸbvíçÎV\%ˆ¦ðºè‚ŸêþÕ~°7s¶Éï{›BøàŒiæ"¹Û×:f âà^1yŒWcrTñ|7Lû­ÌŠY¾7žnõ6O$æ‹¢°ì65¯m»2ø@Þ”O‰=hŠ$¨w5ÙéÒ6ØÐ^¡\Tž(ÄÃíÓ“¯BÁðç5pð„heâÈø&ý g…Å€ÍA„I®³ ÌáŒô°Ýð$»…ýJ­–ó Ï»ÈEÙsXÊþ5.I•ÂÞõ ™±ÞäMÍU›žü&#o+ŽýŽâ°| ,/ó\OÆÅl½›•ý{2Ïà¯ídWÇ©¼f}c(ty,™K;æ¨Iýf5>Ë£dáLt­ª&8MWáË©Nm±Ö˜Ÿˆ«ç²HTD’´Î1“ý‘÷ëðß‹£LK×°ƒ6S~À<m­wΫas9«˜cDÞUä7ŽZU˜&ë™5ïñIž Bm‡Å0íÝÿíú15{g*­Å…æ¼ç`qÁäv£ ,ßq¨Dó(2ŸÁaY6á´/íȼ e! ®¶Ì ;tôÌà"Eù¯FÏÃüÉÅà\ Woü½>l´›^¼riqÇËå加^§buWÌžåu™—õï‹l$ø±…å˜ð¬öEœ€R¥ŽßC4m±‹²ä•"T—ØY_Y <‚½ƒè{ <ßÞ¢l2!Üž,¸ÐËR_eñp•É-æª>ÍE^ML¦Ößëžàáâkâ½-Ífsξ˜éñYØÀ=zÐð(ÈmÔúbEÚ+¼[,CdÕÈ·™ý–üb^•[¿Oôöâf%È#¯ óœ`¼‡ÿE—y1Fí­ãâ¶ùv#Žÿ¹ë¢N ‘ü0àk:\`Šv­á³GDÔ¢¨êû¦äˬ‰åŸùÔ6¿"­–3SïI Wóaa¹ji/˜,ƃáóU—ç\Wb—wa?=ÃçZG¾Ëì­ˆ˜…(¼øŽYHüVŒlw]†]ãR&,œåx9T,oÕe—ƒ¹I:˜«‹tÉ?€}Ÿ±úl­º<Æ;1á`,ªÒ^îgoö¼iÑ(¬ÃÖq«h¹˜éqÎÐÊs¡1ñãÉXç—øxçY_qÅÁ¢Íþ¯Ñï”Úén9'г–×ÞðpØ'‰•Žª}®2z%_p%)Li؆e˜e"«—âyCM¶÷v‚vnlò,B|—B‡+tšù=ÆÐ®ùØÒ~xõÈB• ÎkÉõ¹JˉFŸ$ìœ.cýÒH­ì ¤k¾{iæ*žùUùp`â.Ë©d„ ½ßzºXvZ@®±>š¢j™õ[˜xj ¿‡š|&r«@P-‹7„©FWvÊõä-à‹_ÜŒºzSgG ƒ"+j/!Âo9ĹÌÙÅ{Ãé’~é -g\kÛiØDƒ9H‹ïhÎÚ®ª‡)Ì>â+Xx³ÂJ¬åÃ3P<Ö*} ë4ï²~/=†£“ထi¸QúJçÒEû¶ ­"a¿OÈ™% ×ÚõžeôÝõ]ŒêÏÒ5k"«!÷—Z¸¤þ3é_¤ªqXÃ2· ó\¼3Âd‚<{i«Jâ­QV îßXîÂG¯ìnju)E|ØEy˜£êLÝr­Ç S]Jÿôƒ}óÔÐjYu²RE?×Q ®P]+âRðFâ-3— §¸ÛCÚ¶æúxbu^¦ÎÇb²;â´?}y†|³^׬¥ Â`ÿyP`ÖCíµÓ½Õ§œH ô žî®odŰœ²ÝÊÔÝþÆýݦˆ Õ_üïŠ7„PÍsšY…—²›ýòïÎjt _yt³ê÷êù‰–]JñÚ¼„ÉOž‚F"!×¢^ïn‡ðÌrkø‡gÎÃ| b=ÚÊÖ³?'µ–-hðWƒìÄæø&ÏCKj£!@PŸB(àð)ûB×A ò¥`ýKéç÷n ÚxÂ|s¹ª§œüîojb*¥9÷ºËŸnÎùWãŽ{_OÚüq»2¥¤8=Y­Èíý¼¦¾ +^[v‹~aýù£aœÂù«ç!F$—MJ÷–JmE_²ö˜-ò®:5{oyñÅIºâ­nâ%Rìcæ=håÔ”;b½R±Hܪ„W6~%ŠÞIûôŠ+W—z/Õ–b>׎;ãðݼ2BZtZkZ¤@ÈâÉAV×[·VîÉ—ts©Žì_¾›º×ud'Þב©y¢ƒ©?½’̵ðo‚øgdaà¯' i±wxg°ðX :WTÊQtfùÄséÉdi4z(>DÚP?Ÿi£™m*F6Ì`H/Eu›à)×wÜð@Ê÷‚É#pé‰EÌkßpô𙆭k—Ì‚œ~çØºšq /ç§ xÙÖ]EèX™gÏâP±) •¾Oç5C}æN@§„£S{SuÖX‹âï^µûÉöÂ7jÙ õ´v˜ͼ»ÞT…z–ëÆÚS;é}e \ÖŒi牦ˆq„#=sVR9ñõxks‹gàˆèS×ÓŒ…¹Óø~«(Óy]´92¦‹žuφ£u{fý9@^–qÙ…‰Úõ}Ó ÷Mx”Zfl/´–åw; <¹Šú„q#›xbþÒ^î÷„1Ï’.솶jkÆØêY–7SÚ>/Ï=©Êç šŸ7©Û j˜‚ÇΆÊDÉï*Ï Œ¤è¬çüé_È™0J©<–a‡z- RPê$‰Øy"dÏó¦Ï ¸¤‚ÅUtG«Å‘ÏyÌ5º”Éý"Æx>ØÏîïñžQ¤åjºuj”©>Íf„騖pÓ ˆqR+Ho‘®òEß¿‘º‹º”B—´ÐiÌ’w=t úŒè ;ë&;zlà6ñ-+§[K¦VÈ3>Z²#§uë~ºXL¥ uMؾ?ËÉÿÌÉÄœOÙÝÀ!¡ÐVœ­ÅC¼=6ÕRâÙcú0ˆ•Ù¦öõ†Ž^6¤UˆC1ãZ§¤£@(v/aææ#5n3Î1ʇﰒ5vÚCsß[DmžÙé°V&v8ïqÍzþû¿$zæÈ£ò Í¢ôcyÏ雓ŸïZn¡KÌE Îcü ªuË0ÖœÞÛ7;Un/¶LÉVÕ?DZ2:f©ø.œ§ESÎ Ær E¹CŠE|eú8QuŽKûÚûR XÉ;x“p§K¹îc)æ_xrbSÒêUµÖîqì³nóDx—eSêzUòížÍ~£žXjÄ—¿XÀ8“çp^àý‰…εvK ªï»´âÈR"v˜|¯Z,5ð™¼ð•ð8ÍSéð­+N–(ÞÙˆ• ùý‚ñÞ†À#Éa%-ç*hvE€™Ãi™«ý=Ì“+ëð±K55&•e„ßD?›â´œÏ M¤ú"J-ITæþÃe¶Šé01µ»€F7Dç•ÈZÊ’1¿Ú-sÿ:s^Í&—ù Ü®Ýe8]±/ B·ˆB€X>·1@¨Æ%©¦5-‡ÎÎU…âÉ7hÖùüÕ³Cˆ±¦U.ióÀD%xÁ×`ÝÏXhýn¡ñú§6WlÝ—;¤Ðج„÷fÿüºn]—I®t:…««ŒÇl÷³²ZÆù¤ oªTK/esÎ#]Úe»L±¸Ÿ-æ—‡zvÂ,xj)‘î@uÅö©HÐÔd™®3$ñŒ™iˆBęЭË2 µ×ÚWt^-~†)šO•†ìñÑS.ôÌv‡‘Ìë[ž¸„ÇAö<(çôRgWÐ*N˜Þ¿Tò£–P¨ä™E KÀâ›ngѦëÝ)Äbã+@ñt6²ñ ò$|…UèaSüÓ€-MüÍ.´ ‘I5ÔœFø»‚Z)ZÍûǸ0¾è¸Ù+g¿ÞMåEq¼îí¿{½šS Å‘ÞHLúÎè+š|œôù‰_›¤ÊH‚Ú#¤É,ÍiâÀ[© >ôÐg_Eöô¸›…Ì{ ˆ§ÛØäóT@¬ëXoð!QxöºCÅB© n­‹ÛN#$.˜.‘pí ÆUÏá~Nõs |7ÞË‹dWºYÀ‰h¥?êØöüUij–W }ÜG¶¦âËÙ -ßp*cw•a—›ò€öf[—ºzõ]9’jé)uÑÉ"›=~6JQ"1;l=j5Ó‘ÇÆÊPQÀxú#å»R½–—“¬M{Åa3gˆ8Ž&4¦O)¡ »"æLñ±Ò>§ yhµ~¦Ÿ÷2¶+Œ¡éeˆ¦1fïüš–vÜ;úLÊ]¨ç—毽1Ñ5-ƒ»ÑûqEÞжl¼~ÆÌ=UãÙX*·ƒêÐGB[n/½ òH®~÷yÚî‹mÁ·bõÉÒV)ßXUÔÃžŠ®jûÔ˜ûê:¼tÏ *wÑ~zúRúŸ1»ú_ð~ËxšSË,ãO¬ Éž´tnZYRýB/œ¡ÕJ_em-jÚâ»ÖŽ—ùKå«hEXÊãQŽàék/|$=×8;‰¡©–}‰b…¸Ÿ®d:oI>Lü€Äø­A:ÿ¤C!¿<ßÍTI®wrÊSÚŒ§Æ¨pëKbÌI²ÙL´+¢JÕoOåF”]уÄÀòƺ ÷ÿ P¯ãѾ9³Îñ,N˜‡Rªlu“ Sp.b“|ƒŠC `™, \Å1´¦?i"IC ü=„ÝòO€Ð—ZLºm_Ï590­®RI³ÕÊâØóˆ«Ãa7Â}à×ë¿##ÇPÆtNplø%ÛwNý:ä×ö¶•秤íwî@¢ºá:©W:ë& wAƒÂè1W‹û ôjêi…EÃv`>4¹˜–Y0MÕÆJ$–^{¦Ç¤ÅÀqøæ;"˧þú‰sU¿öâè·{à²ÒK¹ËᎬÌ<Õ×%\Ï"®UøP·½Óh¡÷w§u^wÔ¹•á‚/äÝœô [¨½õœò°ÓÉy%š>b¼¨|z  #¾U/KÁüÖ³ïö' 60¯+Ø—Û<}ÙÕ©Õˆ0"§ôYÏGöö¬÷,ˆl“ó™Ù¯°pÂíÈš õ°Yßj£šeâ,ÚL)ÙüîùFVYǦ]”NF˜§ $X¾ ÁZ•”)ÊÁÖPÃÆl\þÅXå°¬ë,æ¥SfÍQpmb³ƒá¡éðÙ•yÿÜ„G¬ã;"÷FÈQ¤?Ì>K0ÓÇëì‚ÂB8a ™‡j`«î¨gëmM¨”IÙþV²)J¤-óu®‘@Äס£Ñïlâ̶i«àÃ!CÔ˜„Ï$4¥:8uL A­h„X4b4À­æX ×1\Œ™,Ya³‘ÝŸ<ȶÕóCÁL ÅÏŽA<±xïµÍV©Næ_T!&±+VS¢Õm>aÈÖ„Î@–´K2íTÁ§o;’ù£÷MEz‘bB¼™2£ÆÂîeóA(%áZ¶ãÇVÒ.l í°tœ¶ˆ3·­Ú†£Nƒ®}þ“ À~ô¯Gjœ²SëhðnCQæµU üIrˆgëCiôr@#ð)§hHP?À9þ¸uÜœ“‚5õ2c ¥ö‰Ìm‘Q~¤³ùkê‹§¨¢ÚDЬ©â9Dô¦]Q|#HR“„ú¥­,´©Gšë2°Ì ¡w”û ðÙådÄNÉ2BOÇÜæ4^á’A™l/è9yyÅrª¶µ“±í÷a×ix¹!ªñå"°E'Bi—Òä%«õ cB†“)—²u@$r›»($Çy†T3ØEì— wÝâ‹*"î§OíüÓ6 Tû2ƒ­gY Þê?[îBžÈך)éq¥2sü¯mR(SÏhè¤LaÀؤ2|¿NBДlkÚWË$ëÃb 3.áŒ;Œ]';Âá¹hå`Ÿ{˜¸ÑO²i2÷Žb8M kÊ\w:ŒqTŸ$-„H±é™BE%ÖÙÎß5g%ùö¤~I÷gˆP?ÀÌIÜFs“ÿÛ~)û¿Ct1Mk·"A6W;Í—Q\-1FŸ{©šçvä‚ã2üoN½^)RnMçk£g=Ô4°‰jî䔈 ŽÞì&ŒÀã<¥ó¦H~~ ®-~P‹+¼{Yg¸d+±»Ü7eFæSwkÀÀÊâ£R›sP1í ?õ=ç¨úEìØœÆlœ½,†ŽþMHÝ*Dåm߇¯Œ/Tt+PÔ¡Q)y¥FønÒ,”Lökæ¤9C+T<‡ Òˆ^qï)oÆm싾ªá2®å½÷Ú4ÕG¬Êa¾mAì1Û/a—SVz8èH<üž MÂô¤ˆß úÿQw»r‘mWŒ,nr¡Œ@ÊÜÕíìO^Š‘ù%Öµ(¼•p-"ØË{e~îØ_'ýX^®jRT°ã;æ˜#Éä6}~Ì–ÍSç¼Øí­%.ÑðG‘³Aç„Ö’ûKúŽ.O½xf}y·2šj·#®í`¿.XðU1´+„ï/~M!|RR&Ïn a ÎJÌÆŽ8>ñÜH½‹ m a)Í™ÿý<؇\â k·=‡!&˜½ß®ŸogôÉéìµòê‚ýõýÝ£àñ,U-_üT×ýxÉ­š>$íUûAØOc½6}@ÜÕÅK’4av˜ œ6Å´“zU‚Ä·C½ibó¼qp“„@ËvuÒŠyg%ƒ5Þú-x ã{g==ŒY½£ÅZdž»TQ¿ÆÛ †ÔíJâab6¨¯¡8¬áVÔkȲ¦fZ¤²· ããw¢\(ÍšV/å˜RëÌÚ£ËyYä79}—£;/B,ÓØQh„n>S†¡×Ph˜m¼¡½¶D‚0Äa3v})˜°z ©Mºæ ÿcŒ%/ €ëÀ/!¾|ÔùNÌúuájü+™ 8XvÎr1††ížDŽY§4,!·ËÞÎÚ‹HOÔÚ @¢Ò!hÑ€‰-žÕÓ{¬ÛÎé{—l›fîA“e X»N ¥(å»d&§UÝ“e!¾Ó›TØf2w§gþ Š3†ë&¤àØDÀkÌX×7÷]z©,üßPµtŠŽ\àùjfÒåg®JÁR³HÑkU¹`íçBõ¹QCDï¬ùZbØøõ¡ÁÑq>w>·ø°Ò`èû}JËÛaý½“îÆ«ÍÔˆK¨cä‹=7?ƒ«Â<ÎŽMÔv_ùÂ×)ŽÀ‡1žˆ¦µ^_‡ûänÊÍÝ:[Ì9Æ‘56 GSª_ã2öYÐÑžI¿Ws¤Ó—[´‘¬IàŠÙßru%T ‘ÏÝ ÜÀkűÏxX»NDÀ$¬Ë¥C«±àY$~'n l° í\x¢o„ö¬GË0"Óukq#ûq@>AT6à–úóyo’.iõꃿƒ4!”|ݦGÙ5ê}!V?3Kc¸/y޳–Œ¹&’ ΛtŽgxøÕze§Z•c£³Ÿ7èVáãšÝj·KKͪxBÖ ´¢jpd@çŸC1Kœ.Þµ¸fèWéè¬-Õ×’(IeðY¿`+´lýZU®ëÝÙïo{G-{R°˜(CI©i¦Vçôçmv4«—zr ú×ç‘«^iúOYkLXçýûµÐ¢ $¤*]Bp~Aôíu"i1dب…Y¬MOµT€®7T6ŒÝµˆ ¼Ó‘À¹i­Ò^¿wÛÃø£‹À`ðì¦?†cýé'—»< Þ7SÚÓ6‹½óú/NÊTã±¾ÙLÕ<_ Pµâ¹s¨ÉWCÚØ}ÿ 5!–Ûì‚Qod5.ðGt€7yAxü|z¬üŠö±õ¤¿™n#Jòj]§ ³]èÓ_>êW´,pÜqò?ŠZ,ø±Ò½î†+%|PÚ³Ïò%±dù.ÊÒd§D©ýäO˜6 ^lŒM…¢¹¨=Ëü~MñâN ,=¬ò»MOÅþBCà2Ë&7Ã󧽯¦õö¯ýæÀÓZàZ]Ç9ÒØA©v©Ì®Ö²Í •Tñ…ù¬õ ¶ ~FJ¸¤K]YloÓÎÔm¹ <Ú‰`0š†ÿ XæÔ£ëÞq7)Ü·¥H= VéUN?}d€cájÝ?ÝT/E'ùí~X¢„HUÍ€‹ YæÌ%|µb3ÜY)ö#Ì!pÓ±Q”<ÁÙ{ Ð…ÙE­WÌÆJš›1£È;ò ¤úKù§Õ€bÓÄ”ãõ+íë£eN¬=~jË»úº9sŠñ,cDGX|››Vá1yÇ«ˆ@ëßý¹ù±ÄßÈi*û0à] ªÖœ8˜| (´ëÍ<»®_DO2È Íw÷Î0Ãa£ä;æ7· ™ffNïGö±ÿ´JœhcÚ«:õ$byÜG,À>'ÓUëá ?ÈÙvæåLލ®ª—'Ó2¦~W½ǽas­$n}…OQ=Ì¥>9Õø[‡=D´Y²‡Ê4æ¾ÿQ'—ˆÂ¹p¨‚ö~7¢BÅàýö¯Î»!¨­çR™^Öï‰?Å0‹ë z<ô†¬íí””•<Á££0f-!–þ…(K5Gpÿ9gµ§A²R÷d¿¼ž ”TñÙOÚ¹ Sô1îöåË6òQJøíã´”ó€›ÂäÚ7Ú«Ð [½c0ÔL5%)Õº£žcû0X:öƒÝº ¨ôV/2 Ü4>+1…CR¸"ÖÛ-BPÓúAê TÀ1fEªnyú‰V å.sQ”‚ò‡¡Î2°ä·¬ã%ÇWvÁq_Ü”ÜÏÈVY®A‘¨Yë/«}sïrˆ?ÐÐiŽËã! 5NàÉAJI†À@sÑ>¸Ê­¤C6‘5ÿÀp‚÷³B:/´ [89óà{fÞG¼Î˜˜•zù/,Ž>‡yPÓÎ Èm¡d¨@œà8m™C;V ¼Qj@sü½A%n¦3dˆö†Yt’ºß_óRNË©aõq4„-KÒ"é¤<»?ïj@’ÃfaпUAî¾ôVÿ›†{i”â½N/°sMÀ…R²‹³vŸÅ£hÇ^9Q{sq`în£æèû1·á¿L+ÓÜŠ‡vH$éÏ!{›W;l½•Š€ú"šÈÒ6ߊj A9EýÎü‘ù;Åa3ɹv‘X@Žû¼Uú?>ª_œ²OÒ+ꘞ ¤ê5úÆ0© sþ2ä~"Ÿ8ÉB X9œ³Q7ö‚]0 ÔYV‡ ¶Z—Ònïô÷ØFáò´ò‰$AÈš­~tt_ùÛòºvRq(›“jÌ âX< …Z¢ÒtrÊ´ÖÀ’( f)²'az+¦CæôÎû`+¢ˆÒA¯­›!¸§V}¡ÛNkƒÞ½Š%NÅáêX ÒÔ˜¹š]2«–*A^GÑæºnÆÏýf!’ Â+$Á„y µî[T)œ…áy‘4ƒÓáhq¡vÁPú޳ìù»ÞŠÿˆLœÐˆåMÏSd…~¢ µÈo™Ùóœ N1œ’ÐöP¾+Ìfc©šIN÷Š“¸èAÂ1=™h³ˆØdÆ•´;vÈÖT†8MÙp,TÒà"èmߥl˜½_51$ßbú—å–6:¸ð&¥bâ]$ [t”SxŒ0ZéHk„3ú -;}‡ãVFšxàBqåÏv†/Z§bÉjcÃÖòÂcÊ,k¦Û}àÊE5aÑz´ì 8+ª-|Ì¥¹Ñ,Øû>ì\”"Xw‘oZÐH“GŽ=¤n¾^Mu<äò#–b¬üç@ƒ Ñr"u7Œ”_1Âf—§í›R’v™R’YÀFÔU²Óõ\¿ÈËÏ×ù¯¶+KÃiÏ̽Œòœ_  ­2y1m,b£ö¸„L±âoò uï dûT‚ç …Õ|im‹LäÎZ"ÈÞÛ_a´^ÉÎ5ld (B£DU/–³Îà! «0*÷_oÏÌ kˆwpV\ä@’ù¢#V SäÂ}B4M;þl˜î pCN÷°úÓaÄ• †Ê5g3ðIguTûçìîôJ4õ@LyŸÂ+Ø{á°ªÖv2ë³l¹%‚+'ëïÝ\Èœ> ••—eÖ0ªu Ð4 iVÇߦ$} ®%ÉäüïöÒi¦ôF;ÂÙžhñRÍgºKíøY,‡jƒÏHä¢÷é%Xå~”½{Š­Ó˱ÎYj M 1cå1³Õ v-Ûá0/ë¶Å§âP‘•!ñ¤”×pçª×ÛQp0ÐŽyxtå(i@_.ÍÇ1}jK÷(ñ/…åUNžUéÆô€ã †]ÉŽS³Äå q8Ó-W£:9ã-”‡Œ:qóð, +©z«#½ióòI¨£ŽÃ…X*Ù ¼¶8*tŽ‘C Ìí8-Ps3Ä Ð릋àR|Ø ‚ù#’¹"L#(ot1 ùÁ]±=C|)#Èfν*üAþ>óи®§Y]WÈ@çù 0‹ìÆ3¡Ô{G}ø¼*¸í…Cñy[õaíz;¦ã¸¼z`xwzh§hõÅêªð7ó\/%5±·[-¯ÔXðÜ?F<¥Ÿ>橯|Ôó@ a\[ý}FôÓwN7vÅúáb]b‡žKZ7Š_¡h¼¾,O(ôŸ7cšºcÁŸá&Ãc š‡zákà V ²ÚTi¸¾@©#¤þÈ”Áï0æ±ZÎYù5;‡´åXµ`1)Å'r+N3%j˜…©d(›UvcÕ=äÅxö™?Á‰¬o¦~é»–F¡V±ã\ûÇC*Ygô÷±.öœ6 Ô×6‰7˜¤¢`P•g*ð‰“¸qi¶å_.»#ˆ¿éˆ/8G­¥Š÷œ¨ ("Ò?°ìCîq„q#WÉÍwü·»|EdûTülë92MEÍ#4Œ/VѦ‚XÔœŒa†7˜­³Äp»Ãx9ŒMò¦‘ ïr |fж’þ|gf¼i“…è@Ÿø‹¬úâÍZX Ž9öDØÀö’¢#«¹[Ú},>ör ç÷x…™ªóÿFÎZý¡  N5špÅŽƒô¹W¥ø{R:"ÆÞ~.«Š%RÕj£Ä|ÍŒncžp#,èëpiÉæ~–ê‚^»©.Æ! O½•‚’}ù”'9»)W_ r‘jô³€Æõ(Ï„R〦Ïû¬ ¡áÿ•œ :9„ŒJìôUÉžÖ>p©=6Œ eµÂòŒÄï訑N<šˆ>®{3ÑÂ.ªU¢í:ï_Á\¤eï›;º Ç*•R€áôà¸ÄПN™B {³w0[:ªPͨJfœà«D:OGjl÷$_žŸoLuj'7Ð¥¦þIm$ÌæO¾t+8C¡œ–YF]3µ¾O|—ånýù)eCÓVg³ä:[Æ¡a*kéûê" Ó˜w…`j‘Œt¯áˆõ›J{•è€e}¿^ô æh@dÚ}ÕÃÅÕ±º«£‰'ýd‘—‰çAÔÒîîÇ;N*®ÆÏ()IPÉþl;W(víéZ¾ZV~LcÞ]¹ÕºêÔt[,qøf”5o‘¯­ìŽ˜×Ž~ëÂ<Öu)è$h¾{pNȪ(K1Ì¡“Ìï»"R>N:ÊÒÆzXC˜RþtðÐxÜÓ’4ÄiH®î=y'{ÌÌâfòYm`%d²“¿ô§W+ :)A1")Ù‰“ÝÒåæü9ý™o2ô7 %*û3UÖ…=«ðF Ùµ!.^Ñ߸H8¶4³¼\c¼gAn"€øÉíVVKÿC;Ó¢ÎLø)ö h{óÛ­/uKÈôf[;+H¢‚ÚeeO=° ÿFW:ÿZ¢Q5|O÷rDDÌ¡.îbEc’åÜ­lU‘. p݇ ñþ]šq±L„ѰSõ"ffÕÐÀZĈOÓÖïuvŠ6CÁº<Îöð1üšžYÜ)ÿiœ 3ÙþSFšç™bùèÉ£I¦û.}Ã"'d3ú¹î=¿‹`ÚRén¬:•|‹˜ÚÙ@UjÎq¤°¼×†ZÆ&°Þ¢TÜïs¬vlò!"þÕ¬‰Àù¤^Ió¢7½=ÓU‹éMÖjÇÝ•#ÃVŒ\ <{'ßÕF_1-e5­æu(!q¬6™$Ú«~úº^ïš(4ž]³/FɃ°l7S‚Á%³vä¦|²XÆ,e(˜e¥A&€­0AÓü@„3•+i…%a²Br\mLWï5r“ׯَ…¥Æy€BööÈôÀ“#bœÃÕÓs3þt«BõtÃuFNE¬ØŒ(HñiŠ*ŽfHž %wsù€W =¨Q†¸xÚ“-8¶$ )™¯(û´’{üh ’é-¤ÐMC–-û;i#u0ø9¯÷ZrÚ»ðòåÒâEC+†P| Ë…g>/„n¦ÃWÚdÓ˜Qãt¶€ù±æC‘Æ•U{àQU‹RÊ€‰ºžèµ8oŒ°ÙN~OÕBš¸ÂÓoŒ!«½AÆßµ÷­è²¾†­,E:Rûô©p7èÏðÜ…?ôíæ(K¤ÞX%”!+QK?ϽçMBÒ(x]¹àCÒ .†P¿àÐ)3Ê-jÓIÎfÃÁA컉%Ѫ‰²¼I²RöƒŠ¼¯GˆJ†ª…Ì‹x°n×ïGDÛ˜z¤üàzd8…éõq”Ön±œ;+¢jÿ1•ä¡bE·£,Q¿tCV,PMlE§?Ú˜ñB½Ç9éÆkb!'I}Þhþ£¬cBù€zF5óÌÕKÑ„Ö/|äÑL1Úo)Kƒ‘-ÌÛ¥C,úR¾{§äí”%ðø&ë÷ƒ?àÕ5 j²Hìç§.òrl`K÷ñ9õ9LDêfˆß¿&†hd©CC4Œéš\ÇïbC,SIÕ¦Z£¬¯·À'é©T?5=q—šï7môŸ$WdÊ„ÓÒr¤fzûÄdÑÀLÃá•bñ³¨-ÕÁ *°bÍÃo€RÅ_p[rVôßëqæ4Kº!…ÌaA€2•WZ‹s Wr©­‰SmÄOðMˆqéÀ–)¨5ë£,zÈTbôà3¢…W{Ò É±ãcjÍxÚ5 $ƒøhòÅ:zÖ&NX¬ºïfMšA€ixã&‘§Öåf‡9öDá9rÈ÷û/ñ8×K±ßßžç™R!¤Ù 3¨Ön ‰ endstream endobj 234 0 obj << /Length1 792 /Length2 1117 /Length3 0 /Length 1671 /Filter /FlateDecode >> stream xÚ}R} YŠP’ˆnnî*Ea#ð0‰ò‹ÍdÙ2Ù˜¤Ÿ:¼¨2_/¹ ÏW@l[Àæ98ØÓÙ@0 BQ1†Ó™ó <ð0°ìyD¹¬E£RÕXRM­Õ!pI,@Ð0êž\"ùŽ@墱?èp&‰ý~(&'¥Š`òˆ·U–`"g\,A´Ha²˜E) ¤TŽ.Òûp•J02l>À`AÐ[šO8&:€£2à.I$&¢Ìù. IÍø!px¾m Ò[þ,¡8 ì—1‚.ì%Å‘·s ò]Hé¾Ó_èú‰õÒD7\D .l®€¥R8–…¸à `”y@Ô´Lœ ©+ RN&€0BJŸ_ ²Ìðyn rû¤6Ê$3fþÞ¡ÆpÒ'6ò¿9Ï[^À¬E,$¥ÄÔCÈðß–xÁ¤SB6Ä¢xê[>ÿ1BqÁ¶ 6‹X\Ê›½=;áw…"¹TJ…¹ð © —qF=U "zO!Ú–´¿"©fúª³q c¨CëÉ@]ZV@S*—üÓ£³Ã=Wå¹ß‹r A®¼ß¦t—¤ÜíŠ7ÞªžîT5äêËùè ©áÖ4è2Î(j™™l£ÂH|‡§L\;vl¯Éš@Z E¶_×›d^#g¸ìç ³u²áOžƒpñ•žYŽ1™á\X÷\3=ÀlËÙ¤—©/ <%÷ñØwgV3‰·yÖÃ`ôÄ ;~kpr Á¸™¸a]ŸFáç’¿ŒLε 4œú»µ¦ž®ó¹ók~íÈ"©v‡KþøÙ(wÏÝNWï…Üb¦W;&T•l­©·gõʽե¤E£º\cΖû‡|g?Û49S™Óñ£´÷'òéÀ݇¢‹§ë­·¹¬¼'ýT“mʺØÛÖo+XE|v?»m˜`^-r:‘·{…ÿpõ®=œ ãÛÂz'¿/±ûÕ%©yGãÓÉÄ9Û—]’ yîÿüÛÙ©Àí' 8F‡ã ñÖ€Z¦Í6’ãû’ÛóÆý‰ÿ8£{ÿàñ'†£&&Â÷’ï\J„ÇUàôžç=lË[ó^eCuÏõ¬sV‡Ó¦Š~˜1*~NüËÖIwFç`Ê„ÎTú1ý››‹…­~™åë‘òøû:U¢)g´ÙŸ¸ùÒˆÜÞþZXwåO>»Vé/ŠÒªymºgøu+wLßZ©åݧ¿×)?³g.6@m3T²éÊÅ{ne›Äc_&ŽM»[î ¥q=eZL¨š/½ÉŠÉ®ÎÒ;®›·¹ñÆèx¦2nXmyQG·öpR2)>JÀzfÙ_Áë5$+÷®2¤O“G4©TE'_äÆZ ×­ã5ÉnìÖ)ïÿóTèï2¼Óå@óÍ¡in0ûN;AɶüúVÕOžªMÛcŒø “Ï›Þòö7ZyF³3v]§)ÚumNaú«± àxZàÙíú˺W‹OŒgÄz/¼×î¸2.lz'RÇ›÷î‘Âê}x©§ee[h}óTpqŸ÷gÇŽŠ[òŽ”7LؾsÅÝßo=µÙîlñaèifëÿsƒˆª^Û¥1w©¨mW®¼«‚¾Ã髊ã^¹ªÍ45ˆž—¿81髨Ìuý}Á—pØj¥²07˜?‚0Cêó¾þ¾hQ=ò+ r7ì²¢[Äæî³ËIšFê´NËVDW:z ݪÕïÞ½õôg26cëó_®ó£Õß”œžyuíÇ¿ï×=“½èN3Ù.êX¤ˆï¬Ø•µú0V&Ž3}ÐCÏX“ÆyæPee©_`¦_­íÜ~®4gKáÉÎ9N¡o«J6ÑÑÏ›ËMë¼6}$Ѩû±Û>uJYÖSÃÙoGJ Ëêò‰Šêâ·„µx”=nÅŠîµvmµ6U‰" êÞ?“ ~ó„©÷ˆŸQœ‚c¯V¹[üÒi+> stream xÚ}—uT”k÷÷¥S:e鎡¥‘n阡˜:%¤[@¤AZ‘î’.éPº[@Àw<ç9Ÿç·Ö»æŸù콯ýÝ{ß×½g ãcMNik¨%èÔ ÎÉËÅ# €ózÀá~.\FFYWu’³€ƒD¼|ܼÜ|<<< 8’D‘_4ÕaÏÕ0 Ûß<|>!!\>€5Ä °ÙBœp¹çWr²xÿ¶[#œÿñ¹\aH R”€”´†:9x¬A6Èsu G€å¯ºþÛÂâàùÿ ÐAlÁp‹È‚pü_¯ÜÂb%ídëðüm‚ÀžA<@Öš¸wE€þ6ë9Yƒ\ N M( ò{$N^žÿñé‚!VöN  üK ‡X!k{þŸ‘r4Uÿ·#rvÿä³€YœàáØô·ï?“õÿŽ9Ý¿†À­¥$«¢¦Ìþ÷CüË'ïdµ†8Ùø€‚ WW O\/’€o^Y»äl–›Ë G8#ྨ+îïg$pKÿ6ýM‚n™;pËÞ‘0€[îŽDÜòÿ’€ûÙñ¸îˆÀ­xGün¥;Bª«ÜR]õŽêjw„TW¿#¤ºÆ¿$ŒT×¼#¤žö!õtîHÀ­{GHu½;Bª?¿#¤Þ‹IY‹Å!}–w„Ô³´°²‡9XÀÀÿZyù–®V  ü3ð?f׿.î¿I YýK@¤€Ôy¡þ=‡¼ÜÖ rÄ »xdé ÿÊ'øÛï‚°pøã²N›»#Èòl näøí†"\ÿ8€ ±½ËˆôÛþÞ ?Có¼ëYÙØÓ ú³n¤ ò"iÿ"½+QÙ£Ãï×ë΋ãò"îr‘¹œ¯å~d×лr‡¡ÿåF¶àü/ò#;ƒ\ÿzõþ="ø— ýcÔ¼Èÿh™ÙÐ]…@¤ñ¸K€Lú?¹¹ï€Èá`WЃG6w‡þq™qw3zˆßfuý³äèÜþ@d³î\3dR?©êù"áõþ÷žÑ´€8Áu=ÿÝ–¿Ï_Ìû7ëÀ]¡ö }ˆ5ügˆšÜâaÄÃѼ—<¿?ÿ|3ù¿‹LFêáÍ D.Xä»É DÆ óñùþWœÂÕùXþú!AnÃØ‚Üã È wf j%lWÜxñAšÆsmsi¥9<Π+ gúší VÅJSs‘1·~Oõ%Esº8ttʇ†mÿbÈø-=p1Y1 ~O¾ë»Ì!gNßåI›-è‘5ôí°PJøwâƒx­‡„æFèF̉úS×!Bíüåëù7Ͱ C‘€# àœèq2 ·µò?¸Š—@Ê׬žæFž­ÑÐSloBWQÝâÙÑØù|tƒT®­©—¶Ûaç+æ«Ó÷Ç#Š ª¿žåQ0¶Í¾ ZÒË3½Í:‚‹½F:'Òª“8¨W¤è:I¢|LP²Î¾]ð¶Å.Óæ’¸Ûì5:”÷<ÊG:Yí0ØÏàd2YXEÈå?UrŽûÀ½Œ=o—)—4óvg²È£›P1»bPZ ]ã×ôUÕå†}C)¹vÔj7™M€>n+sI‰¾b ÆÄÁ—)~÷cº,в¡]O«?nwZqcØdô4á$ÞAçþº]¥vf ÊܸhöÍ9Éã ¹ÎÝE÷tÌ–-Õ­cÇ„pþÖŠ´eiל9=]ܦ ¬¡Õ öжÄ QÀþܲ3fºÎõ¯“.hV›-üqT¥·*dtø jʼ#^ÒÜWÍ4¯oç]ƒ3gXl¼ÿ\Òì˜úáÀ—4¸þqS«}™R?}ø± ÎÉ/¡_AÆxÊ;bëØïWªô×upsÜô'öÄ|v}™„µ®ÓOë>ð.v÷`äŸók튃ç.ÉV|P9—Š–—­ +×,ô<"Á0HžN® « JÜÍ¿ßQõþCµrN7„ÏtïyyuÆÆ@‚c÷ç\ƒêòŒ@Þ™kãU:ºZ7Yºw¢G÷ú§äžEø‰ÒëW“‹Rc‰7¾ h|зŸ€µÈ꿹ö•&U7ÄíéoI 0¦`BI›rü5Q«"` šDk Jàr3ˆ]y 壋•ë̸+b NÛµ8Â\ò3æ¥bœæýrî_~@…Ý„Åh5MMg{3ç…ÇÒØ-[ÀAÝÆsye'æe¯‡´ˆ·([t°ªÖ¿¢p˜\¦Æ©µï¿70ÎYèx•¤j·ëú€vû@ÄØ½í€˜¤¶ÙÙZ€d<#ÝÁ¡ò~'‘ –ò޼P2ZéÉþhñÞ˜Ÿ˜í|>§ë-b³ ÃYÁS’%å"»ðnొ{ ƒôþ7DSzê5Ïô·n6Q•¬êã~R:áe¦.ßκ¨tégå+÷†Ý^æäªXÛÍ = (q3.öhºlµÒøÊNÂ`…ó1ù£ã¶«à3ÅØ¸BÖö£Yf¥W=[ŽßLäßh>‰ÐX%¿çGÀ#¸}ÅÞͽ¸4|Iƒ«Ï'×”6Ä<’®×Gã§µzDÐÎ7Ú¸†dª2Õ®Åvqõµß:¼#æ=s“q›¢£)w˜/åOgØÛ‰+RÒ¾”£Ýwê)yÿµÔ7¤Œ:hLk"¨±dÞÿ., ,5‘‰o}ASÚ·ü¬\§œíM€Ô÷ ü ÇÀ"RŤÙ㦬¤€5 ½V¨%KÓS1ᘗé ì„&‰‡‡ó?ÃÖÌÂù"l$vmÛ¹1Ä’ÔÕ@/ú’f°Íz:ŸXîÕpPƒAµ°Ø÷·;g°><üöà *†J‹?ð°6Ýë„ +H£´gGi|«I݉Vǵ½¨zÕN8Õ<\3 ¥*¶v™ü®œ)†Ê©òàÈ*ÔY_ýDQCrtЦQVna†i_Æýš4þ¨<—‹:h9à %¶!PmÖ§!º0mžµÈ^ùέ.G¨=½oNm%‘LM4§ˆ Rgò-20S7u *äu9ƒï¦1ªŒÏ¯CǨè%[ Âö)3®3šÞQd_ùû«Õ¼ ¯ÁŠ1h«ˆ¡îê,]Xp«¾/§zoM!`¨ÊoU ŸÛ£ôûK?G<Þê½…Íš°œ–ž¤-›^óqñCa¨6üp§•³s=’© ³§¥ªW0l= öOGÍÍ›†§h’uyf[;Ì-íYô(ÁŽ~TyjêÓs¦ítûa‘aÜœŸý£áAJò);¯­ò©6ÿeDOaè§žAÍ4!ã¤LH¬ÖÐÇ=bï×^Þ"毛ݴãî¥ b™^JcÇœuÈ$h¬3x':Ðtफ़—.„Ê-6VMkǺNض”¥„´ÝÜ#ýj½ŠH&.Ç4k§wŠ(J¬ ‰ùÌ»?ÅáÏŠ ¢B«§¾JAÔã-'„ ðu¡¼"î~ž —sêmdî êó0;×V¼q×Ï+jZ&öi¢KµPïiá÷8ÿjÙ+5Û®p¸ÚЋÿkBoáê™ÊáÂ`Ï—>Åu£í@nº4"jÂQ¾¸fA¯¤Œ Jêu¼–ûæèÜ'3Ì9­•®ÒÛgŽÓŽíw(‡sÕ C5øøAŸÍkŸôp†ªWŒ¶3fMUülNQ¬@eVÉS5ÞpñŠù÷WémªMþ(`ÆÎ\-Px³!3ģ󭈔åšGîjYWàá&L+éåñ³ÙϪZš qùãÖeqµeGêRáŤešó`ªOªWÔD•vù;šÑ·y9ªÑ»\ov÷WöUÒd9Êßžmä^71ÁÐÄÊÔC£ìAφ±ËS3¿:<©Œl·|ÆÌ@ÿ€@O„¸pL\ß:m‡,€ XØ4‚_¶€MZ…{º« ;#Ì|$J*rAAž)ôË&„w>«$d³ ŸOw¤Ám*^Ñ Â’ÀfzèÅÞ'…ðàÇ0á Æ t-ž©»?ä^mEÒ ÏŒ‚!Ò…Þ¢«8»LSÜÁL*ÇgÛ=¢oWiZÃû͔؋O”Ëï; s$gðŸÞw“¼F'­Ç„cŠ|°'Lb*ذjÐ ®þҔݣ)¤B°ÄÃv[À4”t?µa°õ ÕWË2R Nj_J_3Qsçíoò¯$ëhJøÇ5Æ ¸¸ÒອoãKP2œhÉ2FI¾ñY:[Í9¾Ì–cß2Hë_[à¦'x+õ9â)#g¢ÔnGY9pÓ>Xõg¼’HØYÚ(º~6U:±=fœ XHùê½áã¨"¶Ec˜çˆ7nubV¯Þ½%¢1üÜ ‹¯áf¯8/¼øÒƒŽÄg­{ 6‹ªtÕV€»i\G&"»èkž«{1 ëN[ƒu½d·yöÚ_‰‘¿©í¾YrR«¥+^ÁOú8+ÏáæUÑM|nÖaÙï,¡M‘Ã%ˆéé*áÕÅ }ZQ”ZzÂ&×ì¾íÅüËÍv¡z]‘cÀã#'^ýw_øÁ¢Z¾^ÔŠ eÚ7¶@¡ »óÑ·½=Z¤öˆçÙxÁy©‡™3ÌmǶJöVTNç¿àFæeëôo Ç\•,NíG3¿ë®W–xW¨xùQÞ½Èþ¢ÜIy¥lû‘@]b(¬äSbu}B˜Ô9þ+W,áÞä\9ÕË7“G×›¾ù/“âP{<’®T+òoóŽ‚è¥ËqKO&ÊÛdósdW¿©HkbnøFvï˜ô“©bb&Üfùþp“P•º±X|ž9÷M`Ÿb¤8¼¬… *豿懶Â͹ çÆ6Q ç¿‘¡&>TädØ"zUʲ_ÙÌ8„B.ÝÆóÁOØÃä–•ŽBµqíËXÔ§ÀÝ/͠׉NŒž;B ê®¶ôÑê¡ãóÕ°Å•¨À‘s–CK”Ä@ázØs…ˆC¯çæñ³u Z7CšÉ)ä$RgóÝ$²Uos–Îpê‡pèœ^ º½*¨•¿¢kàèïY—z†>Òä«/wù~B˜irä²Â܃ùrYÏOe)Ð$½íøbJ«°Èp¡šN) Of»pµ¼‚”ÖǪgiÔ·EflúLqY=<+ÚGßÇ7¥“^©kˇ³Ý-cI^¨\ v¤¦ã³´žœtÄâ¤rÚ§êaâ“Ý8>¿±Þ:ð»áÏæ×{ÿÂÖ‰£ŒL"«¹z…ØLÊP£Ò*}{nЈ;óî6Ù5Ä”6Z}®{ãÏðnÁôse²Ñyd@®.œæ—=¶Øs™/wС åL2ý[èÜ_ÎzôóŠ¯ '¤Ckkê<‰Ì„Lw!àôŠàjxAkešÃòâÓ×xÇVÍRX}ä^–?+šê7"Êà‚D‚˜ðËá„ÆŸE…˜áY|úe,x#”÷£§b^!?:·¿ëh^‹êw™‘®X–†8‚o©±1ûÍ]ÁÆGï-ýÊ7¥ŠîSkߨ’ Z({r¯5Ž+ 6’Ó.qÚúŸtÇÉñùëÄ­Ÿ:|·QXyiª.¾è v&“ëÏÖr.:\Iíª â¶1x=V„zìïg¨&©Þ|Z®1 4âLÚ*rÍÆh"WÔtr8ÇLˆ`oWöºwý©OdGžQLŠ^D¤´ž¦s¯½ˆ!:µ+ßD(,±TÛ¨ÿcXÝê‡a£w”ußílã¼gNl˹Áægâœå/7”ŸoFDß•‚—³Ð•(.ŒXÅ/ÞwTrú70ý´3íÎ(I(Þ»4Ä÷j”}:0ÜààÎ÷£$ö9ˆÿ˜9”'½žƒNXÁ¹rcÇŸ­¦q[õQ'DG”VZÍJê&pó%JU’äîѳKô÷¼úðÝY ­ÔåʼëQf\b)²/ój¬ÄîsE7’Óq›lë÷\­D‘Vù;V¢\PújMlD¶âhŸ zñÊR ±>9L¸· ÞUê>ßz¨¿"g” ê$LM ¢üA9ÊZdgGX˸é©)b©q„.BtiúÓFb¯Þ“äE;V­{n˜ô.%o%-ýZ[‡FÑ AŽÑÛp+<̓Fp9MdÛÛ퉑áT«ôqû v‘ŠçÖ(ÚïPî3¢fßÔô©“Ï^ë$L¤m[pýhÝû^HäƒE6L8ОãÓ©Eç›Ížý2ÀD?¯ç‚‚‰<ÜšOž¥o²ðëd×ŧªÚÛÃÑü× ¤tñ÷c§ðŽ#ëu%9— )©¦BäÄÇR 0uý‚ž zæ–Y”1z“¡ÅÖË#¢­ö¶ø¶DsÕ>€÷ñ$hOIñ¬#7Š% {±Áè#b¹ÖÙó>dÓNyö.ÂØ?¯ÉlyÈý•{ÆÍê,&sp xi¿ Mu6xi!¤— Æ”.ß•Åchå)GÙs~‚Ñ5oäL¯" 6•?›Œï$f¶1O¸‹¿˜ãá›GŒ& ™7G<.$² ¨yÃŽVuCÊ¢‰4žöµ¡p1"ž~kŠ¢ÔøÙСõ@cšËÁí%Õ[QþñZžK§^ì„ ƒ¡"D¯†Wµßcñô‡âNŸÛ¶ÒºÍÍŽ4m‰À߯ÖTËT*–$=§W;铵 \I²u´ñʨ#L”8 X°Ÿ¥»ã^à#}ϕܢšröÐîèŠ ù¯‡oÇè‰i䙾½é³¶ù®0î•3y vÝž üÛŠ¢Œ§«O[“ÔÇuÝMì ©vãûZ ëܲ𠲤«[¦?’áá4™‹ë)ñO¿ÑµR?™S7H°y˜äŠ^”¹q÷­°‡ý¹{¢¥|Êñ‡ˆ&ëž2mApšP!Ù¬Sÿá);žO»ÎÅÜ@bV#a9¥s^’Be™›´¹‘gÍ·æ}ªrZà*¢)#¢s¡ÔÙ5a}X EL³ü²ÆT‰ÆI$ý§¥ hÍ–Jôûã&¿Ê±§Mædµ-Tî± ¾ iM³‘UM~c–šÅå(ÇÕ—À@¥ûÊJ'ì=éîMK¡–Ö_cÛôí”Ó@Š¢_”Ї8J!3Ka\¢TRÁaRÀB¼~ŸüFÊÜ£¼ ÏÛÂkƒ?2÷fÒ]•x´šO[^ŽÙ²&ŽØk¨XÖ¿vY9H±ñäÙ?§ YU½hþzc%eÏ|r0Sq|YÃáLJ•³è«²ºgí‚¡oG÷ÁyªGKÀÔ0{Í#öõ N¶$Ž„¦Í,8ËùäúŠj„¥Áœ±8%óìôÆgïÅÕx»WÒËIùO‚¯x$Nâ­°F‰Ð“ó=¯2Î/Žö|=®æäÐÙ44ÂÚ fÖ¾0æƒÏø8i9 ^¾©PûÂU´ú°âFÂî}Z% ‚_]î]ßKû²¦G^Ó×{5;›j7ÙŒß;°ë’ñ{çž3 JGpñ9°·óª¬?÷^–Øcìï%¶ÇÀ¶'f1'SYVl¤š7±meDŽáè/É8E‚/)‰SÒ>K3<ªÅaWÇb|ÂøÉÇZI÷v¹ï89n¹3jàµÏƒ7odãLÒÅCªðícEeP¯í '$bt˜ãߌʀUTŽìë„"bn¸"5ÌL\³Üx¯ ×¢wô“d^œP©³ÈÔzz$ÆŠˆÒ™fN¿íÁ•J ¤©‚Ê;14Üt²~ÀûðÖ¦Nù6ß?¨Éi¿ˆ^ž¤¾1€À| m^§õëOüòÚ{"yE±Z}Õ!EçéÊ#߇c¹Î:å;DI±,zÁ÷nE©HÔ¶0×@hh²BórD8äŽäÑ¡O~ÚDøP¸y±yûNSM-´Ú.ÇïU¢¸úŠñ›¢ë¥ÐÙS¦Ðµ[¯¡·é÷¨@F´BÍGq"õ_Ú¾Ts3ûĽ•-]qÀ3·EI,9ð¸ìhy4Ä“¸<È8·“Üž£Bì  vd@P™ôéÉÍ®(Ʀ@iòøF‚8?6¾÷§“Ÿ°ä­Ko”®1íÓ~“ŽÙþz'Ó‡èÒÉ.Ùþùg ¦»hä’ocr¤0 ?Ô¢çÞ$ð­W†š¨È‹±4U˽m¿¥K°‰ãÑ=½É}u®žvA¦¿L!ä¨n•FÖ§ûUÄ"^1 jílZ _7@KïœëÙî+/ŠM²Uª¹Íb¯ÚeÇBe&f‹â8ŠíÙºí[Ž–Ø‹~·Ê’¸¼Ü³)²•ÜI–(¨Ö—oÇ$ƒ5ÊÑ£w 8_}m,¸²Ì°½Ðr”ïìšÛ°á”@]L¾sÀö¬ïD¬¯ÔBà}ðâã÷a³PËh-ÎITY´[¹Žc´§Q_.rÕAöÑ6ã·DFÁ{+ul‰1ÝŽv|> \ŸVÇñq`ö ˆ¡Cß‹U±Ró€èûn¨?\ÏH÷‡d,ĺ©2g›Z±¹ÝŸõ{oe‰ÅXþ<ÈìÊ'×@£¬ÛˆÍpÃç9?õGÓéö÷Éú=Ô¤¢wööuO1¶•³Y@+8ÇÂ[ýƒ:¥xîC^Xuù.¾ø(tQ•ëÕgÜÌÊ·>¼uþ endstream endobj 238 0 obj << /Length1 775 /Length2 772 /Length3 0 /Length 1317 /Filter /FlateDecode >> stream xÚ}RkPW#˜É¢UG‹â )V^É&˜ððÁÃ"FI%¼ ¥„äVÂ.Ùl0B‡6€ø,òP["­¥C©ÆAQ´A°X‹ (ht”R|´0h-XÑjÛMNÅ™Îþ¹çœïÞï|ç[¦$Ê7T§Àµ8FúrÙH å:’~l„á᱆€2űwd$ \‡»œÃCÈH Q‰ˆ*‹i52¥µá-#®FÏÚtÖëûZž¼É¾Ö‘.¢¹t/¹+äùó•ëÁzIÃ(àwUé‚V"gô½Ãµõ¦h8Jïç%=¤Ö¡‘&þ e÷UOZFx+ãW…|y&)«÷’å¼óú²r#‘ÿ¤PÃÙÀ<¥½ÍÉ[ͯr_WÞ&Øœµ=nn»àÛÂð-Á£wxW7Ò:úã ‹õ»“¸ŽÓ#7·t±nÑž7f=3×íjÝûœs4pžûinwQtȪ£Ãi ¦¥¯Èh¼yÖ~ÒTßã)r¸íÙ°×ÇZøq+¤84ò<³¥sèªF?žÔªvN^èökÇ­žÒokß'ŒÉ¦IŸºs=éZ§}-ÍÍ­ž™˜âÕhohZÝN«/ )­yÒx™ýypÁi—áüg'Ív.bÉNôÿ Œ¸·=î ’™É\ìXØG+Óþ¤ºç'Gqï—d‡MÒ…Ðñ1P]xÜpËXÐkØkš¹hf‰[‰·;½)bVYÈ_Cæ¤ruùÍ“#ãCN†@Õxi…ëì ?l¹[ááÂHÜëÜñg¥÷ì°|qpNnsè|Áâ¡¶éDßñ°Ë|•]x—óÖ™âÝ&3ý‘ñ péïcG=Y‡ùާ•û™}µKÞ Žm›¡¼VRmùœÍnY endstream endobj 240 0 obj << /Length 690 /Filter /FlateDecode >> stream xÚmTMkã0¼ûWh…öF’Ç.! ùrض4eÙkb+]CbÛí¿_Í{NK—bÆã÷1oò¤›Ï»™©Úƒ›…÷R¼¸¡½ô¥›¥?÷]ps“µååìšñѹÊUׯÃxîÛrçFq›n³mSw>xÛ”§Kå®QßY÷V7Ÿ!è#n_ÝïÙXþÇÙáRŸÆº™IľÖãÉÇ|÷YxN|á¥ürýP·ÍƒP÷RJOäM•¶gÌ0óI‡˜_•ë¦ê'1âiÒ¢ªËqz£gyöf y÷>Œî¼mŽm°^‹ù‹ÿ8Œý;)¼ æO}åúºy·_”ù/»K×Tl6¢rG_ÐÏþ¸?;1ÿnÀ×÷Î MïŠU•må†n_º~ß¼¹`-åF¬‹b¸¦úï[‡㪖>TEþ¡¥ 7Á:Dn˜ø‡”ëxáq¼¤ ÂhÍŠ"<ö¢a"ñ„E a‘b‘n9ÅcO ÅrŠ¥”DÎDJʯ—««æòϾŸ¦“2Ba©8c ]R§05×Y ¼`e1ð’ù 8bl€Wœ»Ž™§x6ÂÀ†yÈ•–ûRLʼÎØIÔTšqŒšZ%ЬưNc½Ðp^³NY4{¥¡G£¯ÖŠpÊ<æÒì–F}]P¯rCÄèUmaƹèæÌCÿ‚xEõ—+Æðm™³6\0†¶ˆø(Â\1m‹ÖøcÊ%æA¯˜g”ÈÍç\±ý\›˜faböÍ oœ3†Î„=4ÈMÜ ÿ]Bû˜+̘ðöøŸL³ fÂzBÔL,ñ 3&Óìð-¡^˼ao ¼5ì­AŒê ¾µì'|°ì9Åg´K2ƒŸãb5m1m-N"n3^^úÞºZèXã@×û¸}º¶CýèÚº^’x{*‚ž©t[ endstream endobj 241 0 obj << /Length 708 /Filter /FlateDecode >> stream xÚmTMo£0½ó+¼‡Jí!m0U ó!å°mÕT«½¦àt‘Húï×o†4ÛU ÇøÍÌ󳙫ÛYZw/nÞJñä†îÔWn–ý܃««¼«N׎÷ÎÕ®>¯wâ±ïª­Åu¶É7m3Þxò¦­ÞNµ;³¾'Y÷Ú´ úˆëg÷{6jö>úÙ;A òs3¾yÒ·ëÂÅ×  ¤_®š®½êVJéE[gÝÛ‚ù$EÌÏâöM[÷“ñuÒ¢nªqú¢wuð~ yû1Œî°i÷]°Z‰ù“_Æþƒ4Þó‡¾v}Ó¾Šë¯ÒüÒöt<¾9È2X¯Eíö¾¢ßÿýîàÄüÛ=~rž?ŽNhúV¬«êj7w•ëwí« VR®Åª,×këÿÖbÎxÙOÔÔ0ñ/)=Vfá±Yú—–T{œ¦ÄðØ ­â@á r 0,jؘû@†@ÁŒtD˳¢êÏ®Ÿ´K¡µT—M¤Î"`ê¥ó xÁB ð’ã9pÄ8Ž976'>ï;-SŽ'À–û'ã¸ÎÉ…šJ3† ½Ê('ŒúZ%ЯÆðD³N½h¶FCf=tÂu4ôh­ˆ“1ûÕì¢&NI¨‚£C ýaιè‡æ%ö¥ã.sƨ¿,X§.‡GÿœEDœ(B˜üW14yñÓ¨‹ÏF_ÎÂðÝHqÅ('bï ÃÄ„ùî¾vÐmØ; &½xgìå&ò…ý5|6)ö` Æð"ásJ‘›,¸4%¬!Ź&¤AQ߄¶„üR¤3əߪ¿$S>›gcYˆšvú§ Ç²~ ï¬å³!ÌçG¹9ÝW™Ã»’qO ýø—1y>ÇDuê{?Ah<Ñ`ÀHhZ÷9ÁŽÝYôÐè;ÏZ|=”Á_4« endstream endobj 175 0 obj << /Type /ObjStm /N 100 /First 877 /Length 3323 /Filter /FlateDecode >> stream xÚíZ[o·~ׯàc‹Ââýv°:MÒ4Ží´N ã@–×¶YrtÉ¥¿þÌpÉwµ’e9éy)zI.9~óÍ\‘[NáV¯‰4„KMVp¢³Œ OLjÔÊ–(‡õŽÁ¡^ë}G9â¤'Zg5цx®‰a WC[O¼—ÐVÎ ã èm B”o…ñή$ëpµZ€ OBd ƒZ”d%ôôX+<±%¤z•*¼ÂŒ%‚¦Ü{˜•ÐÆ•4BÁXÞ@D ,ÃŒÄ CÈk†Àƒ¶– ÈÀ+Ç,q„S¶ƒBœÃ±4^Ø€œd 3‚Hâ R¢8ÀEjø#¸ €ŠépîˆB÷Dî:B0¢¨4ÑÒ ÖÐuXƒøjœ%Fâ…± ºKN,C]¤$V[èvµ'--qÌËŽc9 *ÎÁdrFC¤azõå ËËÒV`È`˜´…®:xjr a €Öœ +:`7È)Žl31 <([† `8rAa_94T‚‚¡2E(lY` d—ÖuÀC/\y“ êè@(7ðÊbc f²ØØ"a±±³£2ÀF{ÀGÚ`WÓÑÈDìGv´ 8bª+Ð $6VÂE1ƒäÂÆ^ ll š2V W1ãxçÉ“=ùzWzØ».:t<š£ÙZð£=*¦ãù¤_LƒÛ…ªWÅå ·7þBΰÂpô6qÞè€Ãv?ÿÄ?%g<¸ô¡§ïÞȃý»Î2š‡ç+ÛX@ã¾6Ú˜.Lù¾fR»®ñ!`¶äÉB‚Õ]Ùã@ºÀ¥²`ƒÏ§‚ ô‰˜†G'ãþq1#g€åÓBOŠ/3R Õ²ãË ûLwG£1ˆ: QuÁ(ˆÏÆÐ¡]‡Ï/f¡üÛ`ô¡C÷Æ“Ëb†`çôWúœîŸñP@¥ú0Ë» øo? ±€;Ý5ÊÆw•—Ðl7 xLè³ñɘö?LçSè;º²+ºüGħM™¶ÑT«Ñ%×]q\KxB×\v­p£L—k}^M(̇î>yF »axzLß=ÇôÃÍlv7ý¥ôçÁ‡A÷C1¹(&ãiw<¹¦XC_õFóÞð¿'Åt6]ÿ¸ÐÉäØfü­µ[ÁßF-Dfyo;%U—ŒûÚA0èº-h¾ sƒóF†Xßè5Ë‚*Ãñ£@/9,»[F§6´’Zo¥xÕ€¨ƒçÂ*Ô0rX¿^ž-ãå¶ÆËoˆ—<^5ˆ6d^m·ÆK-áåŶxy¹^µv+¢@£ l$ºÂøoŠëwå¡[ÆÕl«ÝW»®õ6†CÔ´ÿ]·DR°¥}nî7A·¥u$ñÀ° ’õvÿ G?žyptZÆKo—Ù/Sg•]æô½íà¼Ôu°kyܦ³Žº‡šÈ3<µ>"wÎŒ#]LÔÉóxŽ‘°JÀ±°¬Çó›óå;l åÔGyÛ¥>˜$læʃ§¶á¨YæY™Wp JϪ^›Ð–ñ‰:a}êäÀX˜D|‡2‚N¥¼ó'$OùÜ1ÖèËÖü[ŒÔV¿RÐUjvþhËþ›6b`¥fÃ6IØ“MsJX_žñK¶WÞËÉc°_ÅN`ªC9YÛôLìOåÐë‘ùÛñ© Í:oÊç–¼)ÕÛØw¥7E¨#>Koйj””8 Kœ” ·5q"a²Â†””ÅO`©+NÐÆðRx‡ß¡tÙþ¡†ªBÈH Uö‚/…ºnn(C]3ìU†i„=Läçá1{ÊøÅÜ3-…½\÷<ìµ13¦Ü 1ô%ô¡µ‹#„‘´®ÎeÐWªÄO²ñ“íSB?‘¬‚¯‚*®6N5­:áK¼«`ÅrjM‘Ë É…Ö–Ç뎗Šôl.;%JeÞÅ¼Îøú ³dï–ñO!Y‡©b€U ψì¹ NUu#bŸûR?ÈH)èá*!Ô Ô£~*øîØ®êó>†ŠT_G_Uh&¯ÉŸ2†8Lù\ú¸™H¡5m(ŸE?@ú_¤6BªÔ7LJÁ†c±3ÇìÓbÚŸ îfãI¹±ý½w‹oÞ¼üé¤8}öuRüŠÚvöÆÃKh3ì]O‰*ï…½úŽ–œìHØ×s©}ø¼Ž_§}ܳ[aaóß»ûµ\ßÄ"މïv÷ú|Öú»£ëaAX‡ÏŠÛ?W=4öozÜÿ@wéݧOé/ô€> _ÒWôwúšÒ7ôˆÓú–þI{ô‚öi|{Û£—´ A½¢WƒO½‚³½¦7t@?Ð!½¥#:Œ :¦cø{GïŠÉ`|I?Ò Òiñ©Ñéà ÑÙͤ(èìó˜Îé'ú™~¡_éßôo€èÇ”ƒLD”ûýúIh5Þû¯Nw—ñ.±YºJ¨+P—9꺎º^‡ú ÜåJÜÑ>àx5à†XĪD q ¨ÔaPáøõÞéÞûÃI1¹-ÖòÎ@a ãÜ-0Næ„â¦VñNúÅüáôwï~«˜—x÷}˜w1éõ?³aq5KùI `¿$ãÇyoˆd4Ãà$ÒñæëÝ pmÁÊ5„¬“q>º,&ÓþxR,xY·…yˆ-^½8Úß×b‹uœTÎEÀè žEÆI^㤱bEv°u´ Ïm¢üÃmrcŸ{ü]ÉZúµŽ“{NO÷~9Ý;hàtT\χ½É Ú‚!v„ ´5øKf.Y[ÄVñ•‰ Ͷá럀r¶7ǦÖ‘÷b>³V‡ãQ\/ÇC˜nc‹Ñeoz9^|é{·ê5¶_ ë„ÿ«ˆGóÛ àóà:sü t ¹R£Ê/>Îdzâòb¤BÙ&”õeeéG·ƒr&‹?¢î÷ûÖrÌ—ì!Äy÷þåÉñ‹qÖ;—Þà·9‰˜eY¸3¾æ\XÌœK¯t.§2þH± rïªY´\#J'K¨Î¾º»É­”ÏN÷ßÿ4ã_.f³vœÀwÂM¼‰àj!ˆÕQÒ9JÜØNVÃÈ×ÖŒ&3ú¹>¡­yožï¿|õ'´j>të,šÁ®SdÓ1ÖÔ¦ÃÝç³ÝWšüCiWŒE-Š´Ð•®µØ{U‹^¶»ž=pÉæÒ7,¦ÓÖ]Î.ßs<ÄeëfzÐrx¼ÿâðäíO³þj39´^Mm‰cvû nåJõ¦ýÁàzÒüB(›°k}^-Ë×/£þøšÂ؃««‚'~w?ãfMÔ$‚Ç@ç¼³!„Ãù"Fu"u¨Ëe€HŸÇÙÖ¨ÖXÏã"­-[Z#l°<š´4n`MàO0|ˆÚ%¹QR0a|¢$øú2¹‰Õ5~¿i.ŠÄó|)$^ÖVCâuN³Å*³ˆ‡WñŒñW¶Ÿ»‹›¸Y~‚8ßÌ`ÒÄ%ø|™¸ÙݬÞìõ¦EøµbÝ®Fùp,üs0˜LgH<0Q‡þÖ‹.`øsp9»™†ûc¡mÒ6Üû 5'ã·#0ÁeAx»—­SöÞÓPSeÝTY¸\en3•ÙwQyÝÉ¥©­]¯m0÷ßEÛû÷öM}Sg£k:óLgñ]t¾gŸÝPXò¦ÂܬÙ}…×ïïšú.{Ýj€íwÑ·¹³jj¸ädœÕžÒ*Ù7P¨±3jê³äFÒÖÓ™:æ[¸x}ÐTgÉCðKB¥Ž7™6²©Pìÿà²æ2×P/1L-ëÜ‚!þÖ?Åûç¸=]üp¯bLx9¸ÄU¬¼߬â³ü —_‹àËåNú|«1d”¡d|ƲŽc˜8¶±Û¯¨¦|é^Zºo•îÅ;-ëÆ«ÆH7=âÍ„µ2X¥ ©¨`ye'] hy=Ÿ aï4ä ÑøH ’¸ZŽ «ŽØ‘t‡h/ú‡\º"{NŠOx:çIÙSU=y­§áYÏÆFO–z:»¦gÔçw¼@QZ¡.Æ™JŒ\#†gbÚ´q"‰I·~ÛÄX›‹ÑËbl¤ÕkÄÈ\L ª¶BÕ®AÕøLLT­.¦‚جØäÛˆM±i‡8ô4-¨š UíWóJäóðùjPé(ìkÞqõ±t½®CŸÄ‡±tËüt…¶æ«{ª\KÝ‚¶®ÐVv˜í6mT…¶’kÄäЫèU½ô«ÅȜЪ…вBU®AUæ„V-„–IJâÐS¶ *+T…]M!žÏÃä+d¥[ P´[¢­%*èEú$¾¤kËüD…6÷­=ƒb¢`^ÌÛCoÙ3ß”$ Ê)¥3Sœ’@ñÿê iƒ endstream endobj 258 0 obj << /Producer (pdfTeX-1.40.25) /Author(\376\377\000M\000I\000T)/Title(\376\377\000B\000u\000i\000l\000d\000i\000n\000g\000\040\000M\000I\000T\000\040\000K\000e\000r\000b\000e\000r\000o\000s)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20250820154600-04'00') /ModDate (D:20250820154600-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) kpathsea version 6.3.5) >> endobj 244 0 obj << /Type /ObjStm /N 16 /First 128 /Length 653 /Filter /FlateDecode >> stream xÚ•UËnÛ0¼û+xŒ$â[$`bôÒ4)šöø 8„+À/XrÑþ}‡”dPã´ƒËÙÝá )šLJ,±Š(´"\âÇFM„¡s¢„ÀhˆsKŒ„+Jå# U®8aRk T4G ËšÈsã‹5aFY9C'³Ù$û^Ö‡^(ù6ÉîcMôµ8º]%E;?º_ÐâO屪AÚÌ Ll;¹ßŸÐu#'óyLO;úü»jâG÷äM¢Ç¢;ž& 6î{,¶®"/W‹ýêæ¹.ŽõR‚rµúYjw¼¾e9ë“}„O‰é#Â÷5СX»À#‚Ñ%6¥Ü–õ`é®l9”×àý¦G莨`–ňWaUŒHØQS©*;¯z®zG˜öí&"ô*D¬Ë‹4¼«‚¦â íÖ¤§ç¢´¤ÍZFlƱg PúÓŠ”i]TnU—ûÝuc%eaѸn¤¬ÍÝŠð%ô‰‚™›!ˆÓtból×~zh=qçañìr(»§hÜ1vWpß$xb5îW:™!I“¸’2™Á·!M2ƒAñ‘«‘ÊqÛGÖp–*e ì”–É Lk“ÌÀtΓ˜ÎÓëÀ´¡X˧‰¶ËÖ„ß3“6:“6€ëc/ïsà·Å|.ßÐÃÛ;ï°fÌÛÑ´csG¹ºø?ùþq¶Ë(ÖÒðÿßÁ±h%Z6ùÏ¢z4 W¡Ú¿³ñ“õçàHv_ÔÅf¿öoÕ‡Åeût=êM¹ H÷x…ÓäJwoÛÚ}Ù¿¹ìGåºâ>¯nSÍfÙãi[½PÏÙb>ç!8Îç²C–’=Üî.ˆ&öü2þqí4Ö endstream endobj 259 0 obj << /Type /XRef /Index [0 260] /Size 260 /W [1 3 1] /Root 257 0 R /Info 258 0 R /ID [<96DED2B9C39B2F9E5710183E86BB58D3> <96DED2B9C39B2F9E5710183E86BB58D3>] /Length 651 /Filter /FlateDecode >> stream xÚ%”»saÆwωˆ8äI܃û… $"$Bˆ fŠVeÆ¥e¤0Ì(U;”jÿ€¡Rj̘Qù:E|¿Gó›}v¿÷rÞ}ö˜Ù›57+ZÁ,™[÷3Egrd"Š.“L \%§ë@)¸–#n•õ`‰Ü Q9Øn’»ET6dPH•``YÜ *‚ÍH.ËÈ-  É­â:²Ô ¹dpxªuH.™êA’?&5‚­H.‹Èm  É­â ²lGrƒ¸Œl;œ ÈV°ÉÎq ÙÚ‘:hÙv!µér7؃dç¸ˆÜ ö!Ù%hJÚ Y³ÈNp© Î#àË-½ÏÛ]:–£|5Gåµñ¨[U»¢#,;FŽH= Û­zDŸô~0†Ao^}§ê bí "¶J#nµUª§Àhžû¦œ¾;É &À˜[ý¬ªãà,˜tk¸§Üi>Vî˜rkZQaèGëÕfÜš_¨ÀãÄÐöêÇœ[ÛGUçÍìíZ[Cª«j·|µàÖþ[ßa‹àð$£/»unWŸ³ù›=&ÌLLz*›‘œŒF0Ç£Ôm|@Uæ#äç¢Ûì´r²¼ÞE®v[räqÜõnwZ”“ŸeÂ&·ûÊaÖáZÝÜUNžä™KE‡Û£*È„> stream xÚmUMoâ0½çWx•ÚÅNÈW…œ„H¶­ Zí•&¦‹Tàп~3Ú®öz¿™yóœ87?ž×Ûö¯nÝkõâNýehܤü¹=77Uß\®;?:׺vÜ==¨ç¡oÖî¬nËUµêöç;O^uÍû¥u#ëÿ¤Â½í»O ú¨Ûû=Ù˜‰a³?¿ûkLy 6FÑæ/7œö}÷ Ì½ÖÚ–][öH<Si£¦cãݾké¥^Ñ90¡j÷ÍYVôßü¬H^œÎî°êv}0Ÿ«é‹ß<‡ÒrLŸ†Ö ûîͯ_®/Çã»Ck¥ƒÅBµnç«øy·§¦Wý×øæãèTHkÃý›¾u§ã¶qö{sÁ\ë…š×õ"p]ûϞќòº¹KÏÕµÿ u”/‚¹A² )`JbD>`´öØ2ãš™$`¤TY'`”(ZqŠÇÁ¼BJÅŒ )KÒÌŒ%553<Æ,£è(‡hþl™×wBš6„‹0¦Ða™G„+L¤gıè«cŽWÀ c œrn œqœø9çÖÀ–ã°MÜ—8%Ç àŠCMq.â†5„Sâhr›ê›®®AƒáúI‚Öå皎­ú\SåþÈ©¿ÇÀ á]8 é`Y‡7ÑŒ1OÊyeäµñÖzlÃë,d mYĸ”S£SJfß-›1i‰:C&e c4ÎRÆÄÉØˆËÄ$D&™ Ë Æ&+ü¬bLõÉãaÉjÆ çÁbôÍy°üœ£‡+çÁbèÉYB¹ü‘þœõ§Ägý ñYJõYŠYrÖŸb–œõ§x(rÖÁèœõGT“õÌ›ËÁ`F+ƒÙ­L ,C9ô²â?d+þ£¯ÿ¡ÍŠÿÄÿ1£ÿ1—ÿ¡ÓŠÿðÄŠÿ˜×ŠÿT_ü‡~+þCg!þ£o!þƒ_ˆÿàâ?ôâ?åŠÿÄÿ‰/þ?ã«„°øY ñ³â?^ŒBü‡Ÿ¿\–jò‹UPñœŠ{Åð¡âxᇻLöó^U}9pQãóq½÷›Ë0øO}cèÖÇ}¿ïÜõ3tìÈ¢}¿Æ!VOuðÊñË· endstream endobj 93 0 obj << /Length 586 /Filter /FlateDecode >> stream xÚmTËŽâ0¼ç+¼$æÀà$0Š ‰Ã£­ö ‰a#A%áÀ߯«›ÀÌjDÕå²»«ífðãc;ZæÕÁŽÌ«Ÿ¶­®MfGÑÏ}í q•]/¶ìÞ­ÍmÞ¯¶o⣩²­íÄ0ZÇë²è^œx]fçkn{ÕÿE+{*ʧyÄpg6;5’PìŠîìVž¤pH8$hù—mÚ¢*ß„z•R:")󨺠ÊÖß3‰qŸûX”ysO'Hî)-ò"ëî}³‹³‹ÍÛ[ÛÙ˺s á3 4†{´¢p¿YôdšrýØëKæ‘+ˆ™ÇÞ a }ÀõàíÑ« W€‡Œ{ Fvm734…4˜‡¢´A­«»èGÞÿc Ú¤Þ_86 endstream endobj 94 0 obj << /Length 770 /Filter /FlateDecode >> stream xÚmUËn£0ÝóžE¥Î"±y$UÉ6 É¢5Õh¶)8¤"’,ú÷ãc\W³Ýsß/.7?ž·3ÑôozÆï(yѧþ2Ôz¦vÇèæ¦èëËAwçG­ÝŒÒÓ=yúz«ÏäVmŠMמåMW\=jý_Iê÷¶ó*ˆCn_õŸÙÃfö ¯íùÃ&1yØ+ü­‡SÛw÷$¾£”FÙ5ª? ÅS4¿†!ó1ð¾íšá‹¼!r3Ò´õùŠì»>˜Za¼ý<õaÓíûhµ"ó#<‡O›ËÏhþ44zh»wrû°1p{9?4B“4Z¯I£÷Æ‹©çqwÐd>å?ñ¯É»Ü=ûõó¨‰Ã±K«î}:îj=ìºw­(]“UU­#Ý5ßd¦kò¶u¥Ñ¥¥y že¥ÖÑ*†ƒx12+ƒ¹Sx¦æ,öÌÒ09Ì9Ô)5t´J N¦Š'†™™{fSÉ –2Œ¬Rà̼   KÙÀÒV i‰X¤¤†BÆRs>–^ÿÝ ×.¹¢KäCc†2—ÀÜc4‰&WÀ©o"²¦™ÇÖîq¼ð8^zlã p5u%†=c¾K(œq/‡?–xŒQ±Ôcøc™·/€s/G|¶°£•¨•-mõ„¥•鯝P/S8+8èÂÑ 4fÁR§SYZ"?.ì‚0»1Òшŕ[KŽþòÒñ­¾õÃúPKS6Ò×0ÃÔæ—eÈ;Uކ}Z8~S›gÈ;­ _™õÇàg®v»ói;K¹æÊcÄÌ g‡ÝÌ­oZ ÞÜú¦ ú¶ø’'ü êê„LÄá^ î¥àá^Š$ÜK‘†{)²p/Eî¥X„{)–á^ î¥(½ߎ‡¨> stream xÚmVMoÛ8¼ûWhÒCj~H”\HÉrhSÔÁb¯ŽÄd IJ!Û‡üûÕ¼±Ã¢ØƒõøÞ¼!9ÔÝ_?7¾?¼ÄûUe¿âép»øPßgwwÍ¡»ìãpþcûÛÛÓ·ìçxè6ñœÝ×Íã°;™‚‡îýÒÇ[Ôÿ…ø¶Rêd÷ÏñŸ‡§ï›…ˆçÝù}z“³ eÊäõßq<í÷LUJM롯{°<Íæ×JÙüVûu7ôãµ\ö‚â3m²~ׯOòßí§v1yóq:Çýãðz˜-—Ùü×ôòt?„Í—Ùüiìã¸Þ²û‰Ïô¼¹ïµ35[­²>¾Ni¦ž~l÷1›§>_\é“}~þ8ÆÌȳ&±îÐÇÓqÛÅq;¼ÅÙR©U¶lÛÕ,ýï g¼¼^Cs=…~úk*[4õ¢^Í–¥™žåO×mT·I:/nYº·ãµž1ÚLs*J`#¸lœ ne¼ÀÜ¢ì8W—Ìi+Á‹xAì€=±Ì ÄpM¼n˜?¯™SbZbÄhòÏ`-؃6‚+ÔÒ–µtΘ¸ 7 þÆûXøû €ÉßB[Mþ98hò¯ ›&ÿ ýjòwÐJ7Äà¯É¿”qò/1n„¿^ –ÑÄÈi 1z1–ùMN þ¦ F_ƃ›¡þ¹Ä ÝHþ±ä÷Ä’?K|M,ù愆fý[þ«þÐÜ e‘ÓRÿ©Õ S…xKýúµÂ¿¨e¹‚ä‘ýc­Ä íQ×Rþ–ú+™ëe¿y¬‹¥þ ëhÉ_Ë8ùkôh©¿G_–ü=âsêoSsƒ¹9µµ¨›S[‹<9õ”^rê©%æZ:ä¬kÁ³`Nø‚<åÜ'{¸à>© [AžkZ§&ŽûÜ#¿£Îùä· 9%F-—ËÜ‚µÏ©ì=WC'}•k‰_K—óRV³ᯌÔõÄèQàV ç$¾!–6n/xzjgÿu › endstream endobj 96 0 obj << /Length 1026 /Filter /FlateDecode >> stream xÚm–KoÛ0 ÇïþÞ¡@wÈbK²EÉ ‡=°î©­v;p’C¿ýLÒ2­b‡ü™z”é¿n>ý|ܘnxvù%‰¹óp[·)¿íOÑÍM5´×£ë/ßë\ç½ç¯ñÏqhÝ%¾-ª‡þpù< ~èÛ·kçü¨ÿ²îõÐóØ'¾}r6ßê?›F<.o“‡Æ“OVŒîßn<†þkœ~I1=¨û®Žå9ÚÎ;Å[¿÷Ë¡ïÆy»ø6Rw‡ö2þ·Ç)]˜üø~¾¸ãCÿ2Dwwñö×ä<_ÆwŒæs´ý1vn<ô¯ñíÏÄ×ÓéÍÁÞqÝßÇ{™–™rú¾?ºxË),Ž9|Šž?½Ÿ\LœR`íйóiߺqß¿ºè.Iî㻦¹\ß}𥹢9Ï/íßý8Öß5õdNœžrf=KâʳšXÈÄxΈ—ñ9ñ²¾&^Ößázz_/ë¯ëe¾%^æ—ÀI%À®Ð®s°k°‹f™×ûyé*ïx•7²`?¬Jö#+® rÆuAι.Ț낼㺠\dÃuA¶\är® ØÕ\°Wyã¸UÞÀb•·^å¼:oäÕy#¯ÎyuÞÈ«óF^7ò꼑Wçl8/a9/Qr^8®â¼WyÃù‰†Þ…lf™`…;%»[ mpŒ$[MyX[RŽÞ+Iù¨¥¤ÜL6§Ñ`ÓYÜË 9HKvvI6ä)+²K°k² Ø Ù§šã‡¹Šâ7ð+Š¿€¹Šâ/°×Qe\G…ñ›$Ÿû@if¨Â<„¨½¿`F¿¡ñ‰÷[fô—Ä©÷WÌ诉…÷7ÌàÏ0O‘úùæ*’Ƴ xü÷"ÜE)=+b¿~–ÑúÊsN~¦‰—ýv¼?ÆSðþȆ÷G¶¼?rÉû#W¼?rÍû#7¼?p>çïãËSfôcÊ¥~¹dF¿b†w4ψ}}òœÇkf¿ãþGÁýl¸ÿ‘-÷?rÉý\qÿ#×ÜÿÈ ÷?°žó÷z¢Sfô fˆWKfèUM}k¡5õ­…ÐsßBohÍ:¡çï0οÁÐÿšò¬ ÷4}{ÆCùU¸NµzŽçšVcC6¬¹û ¯&á9&ýà¡öj¯Q¡öš,Ô^“‡Úkt¨½fj¯)Bí5&Ô^S…ÚkêP{MÃÚk®©MCíµ"Ô^+Cíµ*Ô^›…ÚkóP{­µ×îBíµE¨½Ö„Úkm¨½¶ µ×V¡öÚ:Ô^Ûð·µLøÛZ¦¡ö–"ÔÞR†Ú[ªå=™njó îlpÅ\®†íu§[#ÞCñW¿Cï–«êi8Á,üá×ß™~4Ñ?„ãªs endstream endobj 98 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚeOOÃ0 ÅïùïØjì$MÒ+&†&ñ'·i‡AÃ4©£Ð©ðõI×;=Ëþ½g›±c¡øŸ~)ÉÊx /Lµqx;¨õ†ÑæþLMãðs¢°.díð¢ž.²®£ºº³mÉ/ˆïÝ«ÎiÒâ[¬‹‡R×E^ÓÐËJûP> stream xÚ3PHW0Ppç2ÀAc(á endstream endobj 125 0 obj << /Length 819 /Filter /FlateDecode >> stream xÚí™Ks›0€ïþ:ÂUoà˜:©ë´MÓš[’éPLl&Œ›¦¿¾NêØqè´‰}±%Í íìÇ>X!0ô:Èü¿ :oÞ1 0ƒ” ‚KÀ†È@0‰A0gV׿Öç“àè$°n ì‹à¸ƒ A@ºLþ2O€B>ôÁâמVºø¸©„&€ ©HÁ óeqët§§.$0" "¢OL–ü ‚¢u9 endstream endobj 132 0 obj << /Length 113 /Filter /FlateDecode >> stream xÚ3PHW0Ppç2@£ ¹ ´‚¡‚¹‘‚©‰ž‘™¹Br.Wt¬B PØKÁ@ÏØÒB¡¬(WÁÄÌHç(sr9…pé»™*XêYš™)„¤Œ01Ò344RIQˆÖÈÌÔŒ ñ‚[åÂOz endstream endobj 136 0 obj << /Length 536 /Filter /FlateDecode >> stream xÚTMs›0½ó+t3µªO0×¶i¦é$mjnI¦Ã‡Œ5•!ìŒÿ}WH7Í¡Ø]=­Þ{¬ ¨A]GòèýgÉPF²„'(ß"žR")C©\™ ”×è¹Âº/uß ñЧküÝÓúø¶«Vûø“Ž9ÅǘÞvϺ÷å냩õ;ÿÐVCÀ3Â9añS~]åÑïˆ-Šàx $IiŠª}ôðDQ õD‰ÈÖèeBí‘LÖð¶hÝGôR’X_Hr½%T¤³z¡†%øù¬âý¤&,Öv±PøÅ§¦­zǽöiÕµcßYŸL¸£{L¢¡rû%÷Á¯¾T>²¦ì ·Lñ)œÐ†fƒöõ¿Z”zWÄЦëcE1‰W‚sœïL Ø8c}Xë¡ò-Lyæ¿ ìÁ_0gÅÉ”ò.Œ@ ¥S4j×§¶Ø›Ê'³)/¦@â)C0î¾êàV¸×íhݬœrâî …±EiõÒ¹qa)™v ú·¼Ò™Y§$a7Úm"°û Ÿà‘ Ù¸"‡½’â®÷Ó.)((FÓµ~Å¿ùìÎTœü€b¯0æ×‚•Å•ù\]\ïÊÛ]ÖmÐ €€„Æf8WÅÜìOu4…wÉ ÉÛGª¨‚›LšgÿõR’ðä¿oп?h!áz2îy|Œþv—_ÝÁ\+¼™¨Ê„™¸3'{Íçã!‚ endstream endobj 141 0 obj << /Length 225 /Filter /FlateDecode >> stream xÚ1oÂ0…wÿŠm©¸ç‹c'kÛ€D¥Åb(ÄE‘ iƒ7†¡C§{zzwúÞ!ìaž{k¥, p_` ¬.¤.3p5¬ø« œûnã»ö(Fd ¾ý®9$=kë>ø¤_¼ ä'¡b>´ß¾Kö¤ojÿô‡þóxÍ+I$•X»)«ûa*!¨D ¥E Û=[­êèOeVpR{Цˆ3À’½3¼¶¹Í?·r-ÉüûÔ݇èÈ©(ýƒ~A«Lš¸6˜Ï"çosWÍå|9tºÁÄn‡\RÄ endstream endobj 147 0 obj << /Length 2623 /Filter /FlateDecode >> stream xÚÝ]sÜ6îÝ¿B3÷¢‰R)©¹¹™4±Ó´©“&›»‡´ã‘%Ù«Z+m%m߯?€ ©˽¤sOç‹AÀ2ïÆcÞ«f¾œpø2{qèÅœR(/ߟ|úyÀôX¦Ê»ÓX{/R |kïÃÉ/'ßoOžžGÜKƒT…ÊÛ^{Qʃ„qO¥aÀ™ô¶…÷ɱ9•þÏßmÏÞo~Ûþ¨·ð(‘ qιwŠ …¯Þòöâ QOζs•ŒƒXDßÊàä´Hñ€ºâ"ˆ,Üž]l‘Ñú`«pŒ¡ð_(îu°ðøþÕ‰w*’T“>U"ˆ•‘„|NðÛ :•Œù¯Ê¦ìÁ¬Þœ†qâêãMÕÐ8o›¼<€C?;íé¹H&×Ã@ËIÊx{¾9,ño»+‰£Ô/î›l_å¶ôq¼o‹c]RÕ,£éÇ`~S}!`¿Ëº² q{õ{™„Õvû׆K¿jŠv#¤· ¥o¨½|ó& Ô톃¸÷‡*Ïê1î7JúO`1þ°+ÍAí±ËÍ8o ÃÛõ&bî¬l.èÀ9(ÀX¦Q¨QD÷»öX£"öëê3òjV,v5ô4 A ôеFdØxW ;gô¹:VD¸'ÑAC¹'üc_57t{AÈÑ "‘¢$ ÙÆH¶¡8í>»Ý„ øœÞ¿]oŠ¿F¸®®†¶­4õeÈ„ XˆbÔa…Žý¾ÚWuÖ­©ýúØäCÕ6Y] ÷›XúʃTg!\Ÿ3sÎÜéñ‘ÔGXEù+QcÖ2ö‡2¯ž¸¿ß_µ5­M”Oœøw;° µ³¤eSô´¥m¨íÈÎ *:»Òœ C‡{ìp &7›åf 5?gÝœÆØçHª]ÕÒ¾µò$Yž‹ ªYžÙ£Dà<š[D)Ñ:¿ð¢B4µ‚ÀV<‰µ;#,£½š!§í˜MI¨d 8Ø ±ú¢çûóç/Î.~ûò㛳˪©†ÏmœE ‚¹¥‰Ýhø½Û•]iŽ™>'‚ êì”MÌÀ4$ó_œ­Ð?¸ÎÄ\•(c)s‹‘Ôr¨½&ˆYR.8R+Ц=Æ­Ls•qè¸&¬°EA$ ¿…E²%´ : ²(ý£LkëÀ•Á|{Úthû¾rÂÚŠ –+žH£ME¬¶ÚÍXä‚=Žm°×㎾Ói0´ô­ö‡ºÜ—Æ“àÂõPjCÍ9:ŒIBÍ0~ A¥44]„×tw–R–¡2óÏhýú&lNHJ¿À€!À›aÍ)Aö^»n4Q…‹NOð€9=<§WÁSÍÀôªÅ0Š8?½|A Š$¸«®Þ¡+!öï`¯%¹-‚÷%´¬©ú½Öb˜úWøPßOÙuqÁ<<Åi´p¸Ç‚Ø{ÂCkÈ·En¸ºÜß#»? IÀÜÆÑ›¦ÄáE`Ê9S^=íY ¡& 8¦hˇ& Gû‹ø­î®Æ*`6A@ܪÉëcarWf…¶:âT—kaT";Â2ùwÌÄžŽÁ”8 vÿX“bc<†íÚâñ@Ê¥øÿ(&VL˜(#¥¦KKOÐCO_ŠÀ6G_ÒXôðeÓ¢\)=è°’ç}Y“û$“ ƒ±»°dåÂ’É…ÁøØ¯ÝEª€ËØêèoöZµÝØÅ™2èº,O~[¡ d˜.¬ÑBgÖh,Z{ÜÂwº°MGBÊFLÃêšÒQôg †„th‡ûCùÉÿàÈ(õ–_Sz¬-A.E˜-ÁÀÕÑ&‹•è:Ñûã,T#´Å4ß{‚*³XRJ ®a&!ñäè¡Q¬Ì‡:M„€ðòé, âþôv Œ8¼£*NGŠQhÐÆ(’nR»-„äØx\ŽÀfß|˜–,ÿ¿—ïÚûÅãI%–øyå,*Œ²úÿ·š0̇F]p¡Ö—4+N_@úr³Ô(𦤋Êÿ‘VNŽ igª<ÎlC…|­*þŠ=h˜¯Uå©J†(^–è.‡î`ÌâT b‹$€`DÏ-Ġ˲ëÚî’Ê`Jг×^/!.bˆ6ïä¯L2½!oãË@ØfòÄ„†WEȹ ‰f,C Žäâm ŒiZ{"õ}öûåç²û꟬ «äªÆ‘[æ+Z4 ןzvpAxþlí¥sÒ„Q²xÌFtu/Œ‹ö¿…Ýïæ<óœMÌ<È%ЋälðÞb‚†e@¦S<›õ¨?úÞgø‚‚jõkÐ ”ÛðpÞm"ir|l5ÀæiˆkcB89e¬-úúšV«µ¦FžF²øX 6ÒkIKŠÄ{Ój‰æ—וÑrƒ†tûÓûïåå»7(æÇW¯/.ÿyöþòUôvûáã»wºK´På©#<Ñw¸®ï̵b[HÀ`¢d˜Y#Âñ¡µÙKl šÙ>MŒø?æ ‰ãÛK£Üè©+ûCÛôD¯‘27Ûš£Ì÷ GÔoÂý¬§•¢ÍõM[n©H”Óò2)=¯–G˜mØ Æ”Á~¶Åª¶ÏuÛ¯®Á¬tÿ¾ÔÌãrU{ÇcË{183½%.í]8j¿ûrص'™Nµ7'Ab˜Ó¼È† »Y‚›¥öpÐW£w > ?VŠ‹®ÒL7=¦xº^N-L gú¢aarÑè~17Z# ÆX¨ÂÎcãò\")øºj†´V‡Ùšg A¯ uy=$«¡¨}†ã”Vµ£Ã9:š2/û>£+º§EÐûJÆ—¦ÊêêßcŠº7#=/>b¯—ú qgôZsª&ý/œåYOý€ØâË¥KY/ Â†d]ÓÈÈ¢Œ Öj\jk)ºìˆM—{Â3R„~´Ãq¹o­†À“žYw¬š[BÐ5’2ÜÞ¶×ySbº…©ï˜Ç놫‰Ú;¬étý³Ìu6aïÒùù#­-@µýÔžÐF[‚µÑ ¹Ó…3X4 Oþ]Y:èØ¸UÎÍIÕµ9±}¤ ѳ©lbiŠîî¯óZ¹¹Òh~·P‹Xm­âBŒñ|ò»„Áµõ¿07ùô\‰iñ'ȳ¥-þtÉü0 Z0f®Bt‘†N0‡ï {î]kñ„:Ó¶6âYû…ýWf¯ëu9;&1q–¤Ñ€ñéC&Zf¦†M¢@²E°›òäjѺ:8Á=7›µ‹îΜ¥˜†ÓêýPê‚…æÇ¨ÐÏú.úpD· 5¢#úݺ;ŽGwÇÙ¾ºÙ™…ºmoͨ2¿±Ð†ñÇ&N?6Q«'·Q Ÿ£Cú©¿fHã[ÐPÏV¿gãYáz¸X*®°/wÈî*“Z"ï@ø> stream xÚíZYsÛ6~÷¯àt¦3ÔL„àäÑ´}hš¦9šæpú’d44 Él(R!);i&ÿ½‹ƒgèÆRÔØÓÆ&°öÂbù+ì¬ìÜ=úéøèæ/œ8! =ê9ÇKǧŽÏÄCæ'Î ÷ÁŒ W–'²,ªÙœúû8Û®ÒÜ´+’m&Mûg9£Ø=›˜ŸYòÝmšÈ¦ýTf2ªì|‚(EdöêøþÑã£7G4Â1päc߉×G/^a'ú}#ιžµv¸À3sž=9ÂÖŒAzªÚ5ëT+›kIöŸ–= t[ôÃ)Z3Œ„šÇˆÜ>¥[IFÎwµ3õñSèСÚm6î†NÛYï©­o£w BéeZ·¦ŽÁN²ÝùÈ]—ZôãØUy´–Ÿg1†£Þ“gÃk@é~³ÇB×d…}V~36öÚx½Ê¢º:H Ùœ©Íó®Î¼“2‚ ?¤}†£1p®Óàè<Ø7ÕôÚü%³JŽ\pùwÌ?¦IøÙ£Wš'é§ò䜀òäS™rqF¿@²)_óå×|© 먖ee‡L) Ïk“5ÛVu¹ë´ÈihŸïç ÂâÝ$¼«Uß6ÓíiºB£œXÊz[æ;k7róàbÇ?áéÓ7>>¿ú3¸,Š:ÍW‡ŒLËò”ì¿”W˜3£ÍFFe°áqÙqí#NrHÄy!àmõ-l|¿¯Ì9È ?0SÁÐJðô'±xüðùÝ{Üyºxôûñ³ç÷C‚ÈGø_ mºO¾ý0 ByJóé#¢V€Ç0¢Ö,ŽQÀ|Ö ‚†/v¡"c÷a±Z©ì¬¿Ö/ËbmZ~¾mQž˜Æë(Äg;›^y`­ËÕ(X0ú,ÄA°õJ[\`¬]­;ËÇnQšN}*MÃè 3Â{ª1‰ä€ŠéÄ‘e{®¦b7­-º1pó3¾Ú–Ò2ÊZO(QÛz³­-W•ô+)ÓÌHis2cØ}×ÈÏ2û®#C%È7ñgZ ´Y3.Öê‹§™7ð  É›yËm®QšÍ9î±6*ல¨¬Tq¦6„¨TÕv-óº™"°áï÷+B2A#àü´ˆÖé”Øë½ ‰a›Vö¹Ê ð¨UìÞÒPëFÁJ‚ß“]uq¿óQ"'#(^¬Ø_²,T*¤6]¸auS¨!ÌmÖ÷ ‡'y-«*Zé:Ì¡aìašœzTÛñ|Äö ."z R·ºϘªºÙ@}§H·Oî ¢¡Ÿ§•®«yÚ°zBm­É´ŠðœThÂ-5¯ Õ2Kr+$Íãl›˜ã>ζVÃ1ã4Ã= Ó.«¶›M–-±Þhˆ#ÇêWYÚ)QÓJË·3¤õÈwö±OýâÎñ¸>HE>Äù—®N–Í&ªfE³AÍìã’YW1ë̾x]ðºÚw]ë£ràD5pP ´µÀ~)PiÔ¯I †æÖ©OÇÄà¥Ø¼öû(µï—¬¦Âwé˾ˆÃ¿ûñî6äÍÜÖ:M¶•]á3Jój|k²«TR{ÝéS öú÷ ÂÙÍ öÛdg-?¾V{^ûV ¶®´cÚî\sT8 ¹ŠQ‚`ôõÿŠcKk w”³(û2ar~š6Ë X¢ñ®“‰ø9„íLÞBìwŸU4Še„¹'ò4R˜ú,UAQoÄœ(xÀu£“BAƒVÌ4…wÔ3—jù¹%ææY6?KR¸>ùHYKÜ{v|c42íü v‰Ñ ƒïhÊàT„Ôÿ4læºòd§ ‘o_s‹®¬‰-JRCUa O9׿¢Drw{áÔÞ^T›¸õ»6‚ò‡q€aÁ !)ô ZyaYÝ Õr¢î¶ÚjT Ne”häÇ{ª«ŽV]Oé£Å ¼TÚ6|/¢=Þ´Ò(ºó Jì®qÐI«X®~ UÚ‘Md€kmW/Gµs²B«§ŠQ¬±ý CMäR©m³º©/Ÿ°xÚF_¸¨ûÂgÒøÇs‚ÃmþÒ¿›ü *,jüƵ3¼Ÿý°½Þ>63å «žþ9ßlîñн oEÎëj¬æß8ºr endstream endobj 165 0 obj << /Length 3273 /Filter /FlateDecode >> stream xÚíioãÖñ»…>J€Å}¯¶(àf½Éæ@6^m‘ ФmÆ©T6þ÷y3—(ÃYo€¢èñÝofÞÜ#±¸[ˆÅ—gÿ¸>{õÆÈEìÅ ×·  ϹMä™X/®³ÅOËoVÊ_æõ&¯«fµVa´|·=Ü%µ¿«²Ã6§öë|¥Äò·•„õÛjŸ×4üå¡Èòsj_åÛÚU»… "ønïÏ~8ŒR÷õ$`$<hÜÈE GƒW=¤ñ´ R¯¡gLH0-ŒŸ~Éâ§µ/Äò‹m‘—-á¾â™’C{cEš´EÅ$-` Rzby›¤L­Âév°ä°Wot4xM±X«È‹}Eh¼>ЉEy‡ªeRÒ·(‹¶H¶ÔPðð'·°Êeÿº’byÈ|Ú–Ÿ2¡ ß¼þ‚»d¥Åò‘¶$Í_BŸ´C®¨è»¯«•ö_à'gPÚ†¥ûˆ?Û<»³$‰„eðÌ¥0ÚÐZâJh$YV°LÌ´0ÚÉŒ5‡ýÞ²ÈÍ2×ÒôÑëÒš]ž¢Þ'Ľk)€ ã·(‹f‡à ’@B‰çZ®0È…•eVheº=dyæzn©% ‚¡ïÞ^Sã¡ÞøÔJ«Œ'7 Ñ‘„pÓ‹Œ'ôÉò6)¶î’/î+Ãô1N¨Íø ,hÓ'@^7zÙäùœÓ9¾XÞçIfwBûƒÐfk—¿zŠ7ø±'Dì¸áoˆã«€›½5wÞýßi爤֞òÝNTÑ€üñ`]ŒÆ<ëx0aÔA6Òk€PÝYSèH°îÖò°/†…Qkãì–/z¾Ѥì'í4 bOv î“¼ðkgÔ7žÒaÏ/ÚäÛl |ÂomÒ‘™°$ 8¤í¡Î½§(²(½(^@ó·efõŽ%¸—爐–…Õ$0fA†ïœª‚áNU¡B¢½EKSÅn¿Íw°¡A9–Áòcaß –ÌSYƒšÓÀÎ=åüä®™¡°’Àl…w9h;kZe (õ7€UÇ=ÐK«Ý®*ô^ˉk²vîÉ Ý@í_Cn¬ó–]®²™Ó èuºãÝÅÍÕåÅ·3éÀ ¤vëÎOžÇ”ðµ…ûv$ILYL;ëñõÂ2z<›§yLÚóƒð{m¶GÈçä¢ì«í¢3–FpdÃÎÎíã1´;!@6dhy;ÅG‘IµÛÚ©ìA±]“,Zè[ÏVkT ì;„'µžÏ2Ž<cê^¨^â' ¼ÏxV¯Á0굆šï 2PÔøã0R´çŽÈé VÆÑ°ê¶®vÔêßй8iEyº±óxã‘Á¾cäáo€œ3Ã"ùY¥Þiž¯tÒÞ…S@#?Ž——.h…j¢ÁTëÌsÖóùI xð°‹ÂÚúÉ•Üáù ŧS¦ŠÀÉ ÿSiz:x S]YO8Í‹ß:rVûÞNžÐ26Üðò„|cOsÆ¥Dd=`Jfµöáâõ¿fÈ`Œ´w«Ý« ýØ„aHðzbŒ Ο)èvè {˜»"½©öøøí¬¤‡ž fÞd±6ðÀ¾qÄW} Zb0ÂË>Îö{Ÿ;À×*y¬hyØ3fºBÚ?Ò,&Áú­·Å¦N8‹ƒo·N+ˆ!Åí|N¿eÂÛ´ŠÚÝåÕæ—<µÎÌu´†‰ÎÑ"þüT5›ÉÞ‘³o<òÁÛÆAïퟳ6ïù"fÑúX¢,fCT/2ÑSÏ×»×H$‡ähoN€é /‡>©œÝšÆGÒ¾:uüI°}åÉ>&'¶j¬#o–ï(%mŸnô¸2=›DÏ=ÎÝÛ¥Ë8â4»›>‡‰8„ÑùMþW¢ÖàhW9Öá,ŒQž’ÑXsÀ>ä*©\scðpš>Lq+çÀƒ{lòPb«áIÍë“ ËJ’¶4µ¯\:…nþ mX3ó"¸÷ÕÁF¨´´H»|Àœ‡’ 㟖Áf唥Kã”.üpöxjƒ:S7$ê^"˜×Ý?Ðë×óÚ,Œžïµ„Ñ$;9=/ôDð‡­–š°2§§Æ/&>I9éëȆcœ¶ÚoöFÉ38”iop:ëw¶åólÙÀ%Ù°ÃJÔmi‹ dÆ^QêLɆ´‰N=†€Ø$ñV‘œPþˆ3.jß³ó6S7Õ¡Eé` ìQæFf ÒÅœ°ðûý¤öÀ5–8T#y‚%1÷Y‡GøÇN¾úfZ×à¿f$›ù˜rè—»ã"~1é¸]ÄÐÞVåÝÚ ÌŽÆ†çØ|_ðöv{6?r(GÓáÝxhR0‘¢š)sd>g<)›hS' ݘíHI ($3Šì2l’‹$’bÌž?•°íÝÍ“q ©’iºìDcš„B9²”Ó:எ]Èç×õ¦•CÀ d=V®n¨?OÝKlŸZ4|ÈÒO¯RMD†K{ŠsÖ ?[ñ£¢ŒµîAQDrú¾„4&Œ Xy>Í('iF¾ñ¨îa¡ º‡ž3œˆé­Øôje¸ ‚C¶ ‚ ª‚`‹ª Øâ*ˆïë>Åñ„Né« 8x\ÁQ$®å«õˆèØŸ-ƒh£ldµî Ø>Yø06· ì»óÔX‹uð<]¶Ã â迱,¢ vR±ž-‹ŒXüÿu‘ÿýºˆzi]$Ö®.-®‹ÄŠ@†‘9…ÃS“CŸ1ª‹h¡]¨ëS9ïb?£.JìÕEL —ooûf¤‚¨qÌ94¤ôŸø”Võ~¤ÎÈŠ«9/Ègäav7(Ÿ€J­¸åòcýi0˜jTBy÷íÅ—ïo¾¹ü÷ "ÍpL,›ÈЉ¾«@#4SÇÿOßY%Ï^ö==ð“UÜ­â±*¥‡Õ>F}uf­¥ Ù4lm+"Ti¹ §Ð1(!ú_]\½þçÅÕå ê†áþuºj±-ÖŒÀä„ M± ùÀ=ÆG[/ÅæGÓboÿc§û¨׌ã\0ÏÞ §Â3Q8 ¬I„‚:ÍÍ=ÑõÛ1ö!Xš`мU yû´Æˆ8t/)W¼û£©X,oœŽ£€`”·KF ýÆDEí”÷ › †èüù Ù“äª6ôíçô‰?üͳR±Úx¾|‰îV~" ã9ahHθ#_4ÈÆÇD@êÂ-<ŠÔ÷‰ºM»kÌ5Ö(ÿ…­¡±S]‹Ù”E.Ûôl]9y¡Ç(X‘Öùøoj¬zù?f§sП!?/ ¾èÜ8& êäv=Ù;’Ï*÷°\`‘>’…<¡OWe…6»e9õŒ¡Í LÆ9RxÚõ.þÃËVrñÐQqÏ®ë«qšŠ‡tá~¸è¸@<Ç•Z,=ò—Þ[¬FÍ©7™°)?›š?ÔåÅý¤È˜è}ò¦ÃE·,xö¿pÿP GŒÑEÄ I`â?寰k¥B#—þ£ÿIïŠÇ endstream endobj 3 0 obj << /Type /ObjStm /N 100 /First 831 /Length 2135 /Filter /FlateDecode >> stream xÚÍZ]oÛÆ}ׯØÇ¤À]î÷Ç…QÀIê6H[q.po<È’, VD_‰®Óþúžaè•(R¢,3AÄ©áÌ™3³³Ã¥Ì1-˜gA2)˜”¦ŒeÒ0“–Yå˜ ÌÚÀd„ ~P,7PQ1ú]*\öLêH¡4J0 NI¦ F«™†Ö`<ÓP|d:2%¡Ä@…´v`4SrÆa –AT9é˜MdÈ Y‚æ L9üN&#~‡J…›ÂÌÀÁ¤vADë0má¥4 cм°ÌŒt}`¡ZG¯ 5 F)7€fáWp3x@„Q`„Ò(™ °JL€“€d"Hˆ‹!…/ĆÐpFűf¥%ᆎ$ãá1(à s–(†‡‚‚#à¢&²%sÁ:œ… ÅÍi͈ŽˆDà‘'%9ê¤ôÌ…@Â(hF8="Ä$œò p%¢&ðBì-’®'’$¢ë½±Š˜÷”/pͺ]ãJ´}艑¾X„¥Ÿ(µL™øè‹¡”:L*p†\a Ë $¸ †² A †L *Á6 ß‚÷tôD¦1@, 8&á`F£ `5J ­È˜(=´Z ‚(‘0Q#Ê ª0"“¢¡üv†EK˜…MRâBñ…‚##Dª¿ƒ“–³ìçü}βWìÙèzx[L–\>g?þ8xöA{‡ÿ „xI‡œ :t˜ÔOWÏ W“Q1Ë\¶©ü¹®£ü¶¤Ãs:|FÐx›®ÜÑaJ‡YºóAjTÇ8JZo÷b¼»Ü€ÙôפwÚb}º á*9QÊÚüí ^%2.“¦ñæå›ôÛ8išµ‹ÆÎ§„jœD牢½ÁS;òaž,m¥B Ù2 “áRêºåÎYŠÜ°~-o84kÉÆe °ž7}v+ó1â&¹ÝägG°¿_BnRfŒzbÅìÈšµÖñ.›`TwáºáÇ*]Y'õèë§Ð¨ÛvO¶ÉÓÛd~•÷É…e£ü?…gXŸ—%€¿zsù6i³Øå¨Û1MNÓ\ùvÓòuò:OYÚ_¾oÕ×/–±äï¶¼ßCßôp¯-[ókëRþïoTöqrLMN~IØWI׿ҷÒNv÷ÇW â4±¸üú~ÝÖÛÏ5ŠùáΩúy:œ¦%êu£ÁœÔ—èus;Kí¸ÜÕ¸«¶Îý÷¤sšHù‰ŸŸÖoYn¡ìõ.¿nëU§9žÐ§Ký ‹Ãµ¦Iôr;™ŽHÚNBu[(ßÔ_ÖOׄ>@×gÛý°Î}/ónÝí¿Ø3ǶœlÉšÓ¾V„6ï{ñ´mQh7ÖQfÌŽ®÷MJÚßÓ·÷'5è5 W»—&ßß¢ÛæÄQë­}Ü£g^<õûxÐö ¹Çâ×~à{KÙúÁñsCÅETL°w,;›IÇÉÉ {ÿ×í„eo‡ÓÉ {™/ŠÉ¢X±Hp½›¬ò»åh²¢ÎòÊo“ñlø"ÿÌ.í0KÚJUP°ÄLŠÒÄ R¾aó¿ÿûƒÑÆ«lq7Ÿ|9ƒMF@Ï íS‹ ¡¡SYž@0{»ÌGç“‚]ê«3–½Ÿ|.XÒÑêƒvÛ Úœ=‹-ãfUÓ¬zœÙìt±È¡ê¢Ü;& hëøËª1~¥¨FYªu5šj´ÕXé“•>Yé“•>UéS•>õEß–Ë%¾Av~wY”ç¿Î7ƒìE¾O–¥kâcöKö:{y!Ë"cþ¼ä‚6ÊuäŽvm•ã´÷lMàÆkˆ²ý¯½ –G˜U–[Cï)w8ÕŽZAloÖö ëmƒ«¨¹¦72†›¨;`¨þaÉéEŒŠž+z1ƒæÍê.:tï8L¼|ñpDà܆.>Lÿ8¼ç^ë¹ŒŽ™¸S]|Øþq8Ì‘>¼à4kw˜;ª‡ë‡5\a®ªh8½º2Îp/}ß?ƒ‡ /Ëé’±Š{×ÅGè‡\cž(ÃD±2píèµnY6˜QÛEGµÑ+mƒ2È>eÌñ»‘ý×S]ÔS­x@Âap]v鿢꠸˜1 •«ŽŠÇ຀ô_R5J‡5L+ªè¸° ëNBú/©Ú.=1D0í"¾“KjÕ~hv£|wÏé½±µ¿²ÿP_èÐÕÒÛýu[+é…:§÷åµÖ¶!wxûëÐþªPП*T|R/¬U£)ÕâÈŽžþÐé{«_G£wMôæhôö°ÈÕä\Á2²én<Ö]#¾q°Œo 7ö0ôÖl?ÿ˜ê9Ƙ=Ï!m3_0x’f¾F·"£D7‰žß™rQðÔ]b•2ŽºËª˜”µ$;=9)-d§åôÏγÿ¼{MŸg×Eq»úw–ÝßßóéâŽçËi¶Ê¯Š{x ïŠüÓðf’=ßQ±º¥y/ ¨•å*Ö/Ðùì²Èóù&Î2UÜa3£&×23Zd¬×åÃV—œ í¾ì–³ÔŽw‹aí Â>vâfgžþç–N f[*ó±3Ä6gˆ}Ü ÙðØ4[gF{tRÄL ú“Ul㬶fÕ8£g}÷´ªâš»*N[U\µ»áÔ“ªJÕO8ÌQCÄ`Ã9ÅuÙè=r®Ž‡Å°XG7“%ŸMŠ«rÒŽóQv]|šgË«‘‘Jp:9¾ÀH­¹£?>€öÛè¿"hXÓÛ )!Ý”ÛÓAý¸Q³” endstream endobj 172 0 obj << /Length 3346 /Filter /FlateDecode >> stream xÚµkoÜ6ò»Å~;-àU$Š%Üá7qriÐKê¸ÀíÁ%9«‹VÚJÚ¸þ÷7/êµrëp_Väp8çI®·ù²ñ6ï.¾»½xõVû›ÄM"mn6FmŒŽ]›Û|ó³óa«B§hï‹¶é¶;ebçSuúRÖÜþ¡ÉOUÁí7ÅVyη­øUs,Z¿;•yqÉ훢*ÒNð}W)×ßþûöû‹ëÛ‹_/|àÈÛøÌvg6Ùáâç{›àßo<7HâÍ#a6:Šá[m>_üxáMwÄ‹Ýøžë†wsµÝÀßAØÆv–ÖÒh‹´`ZçÜÈ‹7Ô·ÍV{Îqo:tvÞ¼fã ³›ûÿYßqç~ Ëñ*EÝ—õ†ôû%ðêmL؆×è6E\—uÙ3Öls¾qcO[$dùœàÀùÅ t]®“ò‚È¢Š~ßä»Ý… Λ5๱Í.ˆb7ð‚ÍÎ÷Ý$ ™Ì •$Î>E9|Û@ !1m†ú§£´¾¶÷áÝ×<;ÂQœúýœSžöé%®é;û2Ãe÷<¿Êx~ô½—£J³ž1ŽMY÷¤‡² nI›ÕAV ·Û7§*PË,­*Üøƒ²”‰Óv½ù>û=±zNßð—X‚¯]Þsê´Þ,´P£šVÀ{NT »,CwXÖ¸I º¬@*Ã& MºL Ñel§ü±JÛ¿n}Ï9‰bóàtUèòªÜ¶ú‹í¶èO²Ò`­eR)k¯«´2k’ت+B[><­h£Š\Ì•ˆŸYQ~Ö.û—,í{¡ƃ´¸ý`3õÝ1Ûî ›®°²Ó^äú¾šŸøÀSÇâ+"oé+ØÆ#æÇ‘Kü>ÃeºQ0Øü³Y  pó×öÂØU:œ‹ t<Š´óOôÆ ¹$Z3í™X½àÔmEþÄmÁXS[õÇ^z<Ž]ŸôÜî„ǶɊ®Ã-“?ð“ÀAäsð€Èü…ƒØä„tõ™¿gʉÀcšá^¾âOÑ£ÔãÔŒ2/1ÙöÑ»¶Bö³´/›šñ Ô¼ßð‡I <+rJ8ã/ô€±ÌIç„Ì:¤ÖïÃô¶Ø­9ŽCJ*¡|çT³kîö*ltÊ1C#«Jà‚Ûè9q\H‘!X/ÛTS‡‹ƒ‡SÕ—G9ÌËKX2(Ú ûvhì–~Âð1€Û˜óCR3‚ÔG]B‚é’•aGäWD³ `ÙKvŠÓ@€^¶›{ÝE Èį:ÔÛu» H#ÄÄŠßs*p= ^®Ónâ%/óÚ u<ÒÚ)<ã•¶þOî-Ò®W‘¸k- !i†6ÎmŠtšƒ‹ÆÀSU÷ÖL òpª3¶BC©À+‘Q"ôÑÞpr‘Ïèýâ)\ у¶šÈ#ãÙ³£ ë{ GÃa0TÎ=EQ0¯Žè„#´ï°©ö Ló¼D^9F£± Lö˜÷ÍI&IýSH ¶$ZÈ%CÁ«T§œcWèÛù èÿVN†‚(ù#ò—ÞW‚“UÍ \èvì ñ€·Qè\Ž,Mm)q°×ä¿ ý’µÄNÕÔ_v6=¡Õ3’}Âõ;¤ ɉqÞ\ßlÁ‚vE59‹4>÷ÙˆyßäO–³)…·[ã¡·‡unyz*p&4ça$ M¨"Bðν…ÜŸúBöÅGeì’ñ3ÛǼòk‘çèLwàÀQacÞ¨5ÂÆ ΄õ˾+ªcXüœÃØ&úe^¸A°ˆÿÂÙð“v{>:á„ -AôY†9œ_Ö9ö›¶“í7ü½—Ô_)ÏMT2— ë:k'>³$·ìº“„Õ&Ña§NÎx’,o*£JÇpð¤`Àw&fWd•D_ ¾ná±BvEµØÔŒív¨Z¡ã»¾æ¸È»‡ZÙ$æ<3Ÿ•‰T™ž'ާ.ZN¶ahš{C÷çƒeIÃ_ôjHj"d€>–ý^ðlaUsŠÒ3ºMpäÜfh¥.$Î¥˜ªÉAê]ÑßeMóµ,Ö2ÓÐUcPšI›§!Ýõ–Ž{~AÌG˜Éñä …Hœ‚ÃÛ†ñqÛ<õÌkë}ax8$˜È6CsÒœARÛAkzL€òÌ1¢£°´&F(ÜÇ<áËïŠQ»‘ñ×ÄèZ9*7ô•÷k&'ö»Ê(ŽEƒÕÕ™ø¨c_P¥e"0˃H,=¨8A“«º;”}_X@#_öŽu3RŸ¡/Z“dMQ2”{Ÿ®voÿµ{ýñã‡÷×k KèêhÝ1Ý¡»•Eúâ@Ž5t>VyÑÊÍDœ€§ ñ†Û÷ô˜@+/ಡÝéxlF¿ C¦.$ØŽ, À…=·…H¹à± Q=µRc€3{\Ð&QM'Ú à…6ÿ•Ëbž¤­¶"I°–ËikªÌ$z‘îí,òLve%W¼­Kݢʗ÷“ôqçš¸šˆ¿‡BQ)EÉ R£‰B{¸Aëæ(…­ÁÊîÀ i‘ Æœ jC™:–C4Þœè8±&‘¤âHùŠ1h¯]ÒáÍ@è¿ôF#â³8­lœ&»cS Tœ¹²Ù"BƵr »@/âïB¨çî®onî~øxs}÷éæúê§Ûܽ¹º½º»¹þñ§÷7×oÖõ|WA<›\*ÂÙ…$gøTå˜äETÐ#t4CèpÔœÜlvB‹úÅM\á#™ªé1mSç1¡$ñ¡¤÷‘½}(„×áÆjäÅ…B¼æþ\-éÖïׂ¡k¢è.gQ+’+PâŸjÊX 2,TWk#$H»§šm¡mêæÔÉUŽ  ¡¡ó]‘¥§N¦Ó©*CÎ `%™Â@Þð—í_™éµ “øFÕKu*„Ŭ.ëeY:ŽWqJt­ëSšÂÞ9xŽâ=_0r8 zÊš{µ 0^ƒH=AÓÄÆHÍÖ¨w­Ñ‘C/¦€ŸèHPš2;ø,ä)‹Z±Û 09½ÆÑêM2•ÅÑŒQmfÅt м„Ld~ŽpNW5ã§ç Ò¼ƒÚ* òñCCx0g5}$E¿™Ï:â[×ad®e(k@‡è…ûÿ¿R¤žl‚-§0¦þž«|°$W£­¸AoÚ/›sàÍ»‹ÍÏ4±*ïGf$†7LJ^ŠñêÓ{w÷\_!Uv T#Ÿ—Za)z6óµ`:êaªá&Óv|WÏ ÿé€Å²ö×À?†P,Ëè~Â`žšíå ªÉª†Á|¹ßÊž=ç!Í‹nY2Æ¥«”)k OQ°‘PŽJPe™==yÙx [ÏkvÑ1Œã·t¸ˆÑ¤mS1p/sx¡v²[짬ÊLA;ik9"pÓ5÷÷ÜÒ­ðîóg¤ §,† ( õSyÒìÁ—ÖØÉ¿•YA8oéR].SþäEŸ–•Mrò¢Ëlþ`ï<‰”“ôh"ÍÙ;‘•¦ÜtvE±˜¸'go2ñθZ­0`Fáâox›úÊ.yw¤\wÿ÷µ‡@ˆ[¡bÒPdW™óINù(Û=¤ãM†¥q‡€4¦<뎕XH)ÒX0òÙ6ÝZb úé™pz7,ò½˜.+½ÄŸ”aÃŽaÂ~•GR9 ˜Ik¤xL•èi#çU-§é’6+ûŒ¼¼·œ sòº »œçljò¸ŸL÷íµ‹O÷û¸Ÿ¬=î'Ã;)‘vÐh0ÊÝ,š!æìÕ?ž¾ú'“WÿäìÕ?yîÕ? ÜļäÕ4íç_ýCõ¢W£W^ýƒÄ¡+ÚñŸA#=÷À˜å{Aw,òæ QGqDãó>>L PK¡Ëw2ÑòUFÆWYƒ’´˜’´ÙÍN4¾î3æìu†‡×}¹µ±ksÖ°ÔËÿïëþ¨Ì˜B ›Ðᘫ-ŸfB¹ÓÕR’ ¤T“ÖΤò.û² Ì^zhÁ›ÓarC&ŒÏ.B¼e2ˆ»/ÄñI!XfˆGÑÑwn(/¤|™g<´Íi¬¯1Ý#sçþ0ä•Rr`§]õ" ™e…¯%D#¶wÐêÓ!ÿ׿\OŒ5w{ˆÙŽÛˆ‡m€’ŸmŸ1d 6 gäñìÀÿ4‡Ã©Æ»iJc`´´ÔŸc*Ä”»Ìƒø”ãgüˆ·¼‹Îøa´üëÀ41\þ+ b•Š^ü§¬Õ¿–iE¦ %#:Ñ J¦ÿ y½O[´D9 úŸØvéÄyÝpr[ómÌ”ÍÿØ!> endstream endobj 176 0 obj << /Length 3368 /Filter /FlateDecode >> stream xÚµZYsÜÆ~ç¯Ø·ìV‰Ð`0¸Wªä²äIJYbžd Ä‚$¢]` `Íп>}Í`€ÅŠ,—ò„9zz®¾¾¨ÕÝJ­¾¿øöêâå®ò Ot²ºº]éTF…«ÔdÉ£ÕÕvõiýv£ãuÕÝT]Ûo.uš­ßïŽwuÃåŸÚíqWqù»j£Õú÷Mô»öPuÜüý±ÞV/¸ü¡ÚUE/ôa un~½úáâõÕÅo!,K­`z +0AªÒU¹¿øô«Zm¡ý‡• ¢<[=Õ~e’ ¾»ÕÇ‹Ÿ/”lÉ}ƒv¤D8* Wtœ4~!4Ad§€Ó«40&åƒ˜Öøç'Y}ºŒ•Z¿ßÄë¢ï6¡Z·Ý–á·Íe¼>»zx䆺6xàPSëÛ¢”ÃúEÅêð`©¡NõòM”y7©V—: òXó®îK¤’5r€Ù×a2;^3͆íÅn×n¢xý€­=·í骩¯‡–˶ºV¸=܃ÌCû°O^t'¼#µ®¶vhÕH7Opìqa4 Ô}ÑÜ‘ ö p**\¿Añk;ËŽÏ! áb>‡m5õçÔ±‚Z_òæëÃP· ·¶·üð̰àŸÖOÏìwôU5z_[¢…ò/*2 )°ª—oRåk] ZX+­ñ›ÏÝMü&… ¯¤jÁýßyÜäŽÃ0) h×Q’ÚhØwäQäÝ¿†S=È~÷Pæ”™nÈöÕpßn¹¯îynhonQÙ¹ùŠª/àóÂRµÛUhàºkÃstUYÕ¿ãuâýâ Y˜wÍÒÑ˲8ÒÜl-«áÈ{k„U,˪—a¨FŠ´‡úÚŽ›‹3÷’hmWþöÕw?Å×ï_}üxýóõÂ/RRñTâXDêݱ#=ÎAa¶RÚV‡ªÙÖ × « w 7ƒ&€üt\aI‚Âì  ¥îyÜL@ loüôÚt¢É†>÷Ú¡ÐR;¡€É‹]ßrivu™òÖ,ÂÖ”õ$ Úšb/½xc$±:˃HçÓsŠì(±bFc×”ÿ_6†LõLO [Ú]]>r¹*'BÃ:\Ó6x¼»wÓt2Q-š–¿=ŽŠ›í_°¢Ø~»1l&ËÞ[—‰Â±½ÃÔŒ„ ¶ íGµÛöç¬ÔlËÊn9‰×bŸê¿eÑXˆL›Êv[Þ$NB‰îŽ]áÙH±iÛb(ÄöÑ‘´ðº'/˰cÆ•º«Pt»Û­g±^A”Žge²lh,»ª¤‘õÁ˜Óºý‘{1©¸›/iOá‘Ü‚ †#Éb¬E*;¬T¹žr'´Àä%¥áÒ@Ô€*s¤ä2é³_ðj&‘£5leHd BFˆ·Ç’t#¹ƒÑ&¥ `¤Ù;D W¯ ‡S¡“½¬A%³ô"`ÂQfÂ0¥’% u)´lª„Pr( kè­EƒÀ‰ÌJm#§¡oln qwÀØ¡øL¦Œ’$zvl ¢LKù³¾©Ä¤VLÅ‚`lj!¶•í~_§i"·±}dWÜZMåÃæ|ŒÉ#Šç€ÀÅs0žbxl<Àì@ÍÛj†³+1ëÛ®Ý/íöʧ…b'˜KMB/àH-ö©äÜ-”\Ž æhqåݹtÕ%ˆz ö7ç`L˜‡îÂ\óPA` йbã ŒÁÞƒ”^HŠ4Æ`Ÿ=ì˜Âì=cØ“íƒô K–= â1WuƘ17D³^bvP% 8&4>Ž9Ùܲ°cг ÉÍRKl%ϱ¡UmXÈÊéIJ ­ç/É ~'0[Œ±“ ØÇ)AWïαlaŒPú0›FC÷vn ?Ýô ¸,éo5ö£&_€}ƒÑ±À˜Áý¶* Šz£H‹^BÁ÷ÒX_Lc{/k2P"0ë vµ ¼Ñ"‰/: nzSU(ÿ=ìê²üyŽÍ˜­A³Ž·)›»÷…¨ VšvX:Õ®Úvýä$,)Jˆ¥E³ë9FõGµ’ÙC[r¼µZóu¼»C‰÷aÎüú¯…<”`ŽÐbŽôë`{ˆ)Š#hsWÿasFÏA8æÏ Ì㎰~&|:œ­©ðÊ,!wŒ14B Œ9â9bÑþ[ˆ–·üB„/“Â9«1›k“Ú èBM.ÏOÈ»)®ÉæÀé¹ÿ ' &[Ñs`)g‡G6hä:°¹–/ƒ 1޶ÍЖíÁ˜FñNlˆçá`u «uZ¼V‡Î¼ó}b›[‘µú6Ñüa²;MþY$’j™§F'ÂñxÀ…ZEK 'ýò#NObcög: B€l‘µ %ÆW8~#“h*q¡=|5ò¤vJлÙ<”@>ž[@çm±bC z-œ„ô ¸J60YöT(‘i¨Ÿ%Ò ÑáÓ¡&NÍi(fÉ %üÍIJ4Òä‹)Qâ{‰ÝØ¿†.” ë† ~(£êÞy\Ÿ†¡JØIH!"µ>Ž¡DxJptiC‰Ð…Ä´®á|(‘|µPbb¤ÍÌHþZ0Ò&Œ…¶™€,nô´pA<‹G„c­qÁ;1`ˆk;í¡èMÂÔ2K¨ÊE«ä:™ó£y¬&\8¶ñå4” (x8„ªÚ:…p­øÃN$œ}i£Lz: ×o?|_¿ÿOìßßÿóÝõ;”ï]ÿãÕ»ï~|=嵤YŸ+bÌíeݳcö¨ÛqMâÞ^,¹Z\ŠPЀÊM¥üÌ Ûo›I¨ „¯ß¿þð“øÖTÞ¿™·ëÁÁÝq 57Ù!=Ü µ:ìo*ÏuðE¸Ωh¾RÏ-3Ãß°Ž>ßFÞPeyK½': ¹ôËð[&&l)o^äǧ>õÔé9®©mæÙnp!4?óÞѳ¿µ¦Ûí¡g»`+MĉyÒì‚Îx¨³Ì ¬Ôsà ;Hìs]’Ù— (ÿh)Æ‚ò™˜»ZÈò …“ ‰Æp«öëìÇE,%?zgÖݱd@y¥$ÌNs½bóaõCg½à09¦\k|.Ê31‡©ö„LÊöm]þ–«Ã™‹ÏÉÖÊ\·œ0«®ùûÅeâ“N˜ž¾ïkQÍ")XŒÇ¦Ø×—â5³8ãÙS¯ç1ÿ•P‚wèm&fù¶çè|ÍɵÇÓ˜qA7|ÅÆûg)6.ák;ÅŽÞSbŒÉAôWæ3cýXäýI@m¼v|¿‡qµÁ –{¶òEŒÓþy?Ðîj|õ¼œrwÜ.E›3ûó mù%y¾å3 ú¹`Œs jÍx³¶Ù kÅrå(\Å¿:Ðþ•%w¿Ôö2sÿþˆkû˜À¡ ‰Y¿ê'3xÐ/‹™% µôI*e›“ÃA@ÿeØþe`¾€Â_ø–]Fû©#´ã­•j!pYvƒKOº¼BÙî ×7µü8K)<åæMÆ€ù³š<ýÿX„¡{ŒI²ó¯þç"´«(Z§óÝü1n'm endstream endobj 180 0 obj << /Length 2981 /Filter /FlateDecode >> stream xÚíZ[sÛ¸~÷¯Ð[å™!$g:Éæ¶Ù8nšõN²;J¢lÖ4©ŠTÜì¯ï¹à5²7íã>œƒsùÎE 7‹`ñö쇫³çot¸HEj¤Y\í±\Ä::U‹«íâóòý¹Œ–ùaêæ|%ãdù±<Þ?ÔÛc™óøU~.ƒå—óÖ—õ>?ðôÛc±ÍŸñøS^æYcׇBJžÿvõÓÙ뫳Ÿ…ÀQ°™-â ^lîÏ>ÿ,¶0ÿÓ"*M´ê~¡MÏrñóÙ?Î{ÿ!\&Ò(ÜeÂÅ>L&?u÷µPÚH'€ ZÇ,€P$Äã÷Y|^EA°ü±nÚU{Ëz²)eå=‹¢¨Ús”2¼Ë]¶±ú5ˆ‚[ØåWÃD8`æù•ô”,V2i$™õ«[8H©x ‡ Z€ð‡Ìmh³¢DYáä6o6,ñbßuųpZk©$ž{Ïj<£+ô©4^6yÞñ8'‰<ÛÒÎ( ]–´êù›8èŽFû×°•¶üõî°Žž“å!×{òxqû7Þ90¹P"ŽR·U «0ŽD(ˆTY(yQ¶·õñæxðeaàµI/9¬Ù6üB(Ó_:– ­™Ú0ÎòöÈóöŒeálßHòø¬ì6ÒòQüA@«AaƒaÔU‰T¾Žøøˆ”f9`°[<£ž?  ¢áç†xGâUë)Âü±!K‚ÑíÔ΂c”ù¡èjù’ßøÓ}Ö[·Î¸é 9 ˬuöqÈ›}]5¹Ýìó=a°;‚PsáïÑWnÕ#Ô©_H¥3ì Uï?ý]¼ÀûþòöÝåõ%úÓ߯|qùêâµe¥æ'ú¡² ¯ûC½É›îNnY6¹"#Îü`…Iì o2dÍ&F[;™U[€7³9Öçšo“ø Ve±>d|½¯x£ÂZŽLÿ§å•¼Ù[¯ÿ•oÚ†é9ýï×Ïß@LéüN¡ˆïwEU´sÞ 0 ·ŸžkdçûhÊU1w”‘1n™õS4¹Ä,ßí:V'2ÜÖ &BI¶:@U[Û¯rgÛYß–¼”žY£´ËéXÞ8=Á鿸ߗù=8‘7ä&ï[e34„~Ü”ˆåÒv¦Rƒ«˜À‹±òú€±*=Š8IiŒÃ¢”!cUÐIQÚI4|‡w÷ƒ,?Âq6¬€¤Š/ä¼Þ#‘÷JKc‡6Ëp8‚ý¨‰ª•ÊÉ"`c| …J"«McMì[¬ŒQÁ!]‡hmöçÛyµÉ‡ú|ÿê¥ÃŽžÿ/Yi{¸Íí17”¸¶­§ØX¹})Ü©àÔ[°vÛÂ8>ià†Z:ÅîP> Ñu¶Aìº;i&’c›@zc› 9|o8…RÁçØ&pŽ£aÇ Ïv&€gyðçÇR'3 s³DØ0uQ†á•¦š”ÏÖZ šÍïð©ÐO1üö—V5?¿e`øm@£»îâ9âH1Šã$ÙR³)> oÉIqmYÙs< Ð7ˆvÇÒQl U<2Ñi”QB¡3 z!'Ÿ§ KŠ '`Í€M#=Ø ¢ìlúÉ€MÈ]4î²â(pY±5‡HH¨Ü±–"†b¤ƒ‡'cÙ]â£&`vs_×t!3xC;¥lÇ œ=úD ·•MÍ'v!b*~™F"=lïXèù5$msÑVy¯-"Ê«æxÈÛ™c'¿¯]vÀ×n˜TÑÂÝÖÆL…q>ÆLÎ@HðÝr†4HßlFÙ¥ŽqÄyùwÔ®ãêlXA…)]mœþjã kKPô²ƒ¿g¶>:]“â–ï)#“.ýü:WNà¼/‰#“ qÐîò%1¿óÓ—ÄøbKâP&)ÕÄ87öGœó51¾ áÓ×Ä4阇óILÍm±Ÿ+.ÖyËõ,Eƒ÷Ó¾›cd ÆXZmŠ=!.#û¯ÖÇq®ùÊ<’iÝÛu›M}GÅkéX.ÿIÑ7f– rYl¬.ñÖ*ÍLª°ŒÀ§ªX^ßArp¨ïPÏN½#­Æ©Ðiâ6CM^ér/Ñdèü ƒÜu[_Ó5ñå©Q¡KÕ·ì›LT§;|ÉÈëMN ÐÈMejŠ®°Ô¶”+ %]¯± ¸± =m,0ôZžW'¹½åasJ Æ!àI½…0N„î`‘› žæw4 'RýY»ýY»Íñì:‘'³ªX$¡?‚ òYßÍ…t%¢d’£ãùcè¦9|tÙ Námðéœ&“ëü–:"_ ônÜËíÌ‘ I©E”¦!y”¦s¬Ø’N@}.ùʪ9IiÓ@Í›Ü¦ÙØ¨M­ÿã (›€à¢(VÊ®6XîZ¸©ƒ=8m)@ì-fqZÚlO%¯Æ%ƒîNä– <,åºãÓ ¿çžHÔŸÍ…ÍÇúPšã²ÔÉ ¥mdæùMÑpãW§Ëš9Ä6R<³ìþ¬ê-q…ˆûˆª†ë×UAÔuaáë¯?} #PËŽ«Áíl%6W?ùÓL¬{6NLˆ&”…4ÁK ûÄ’ 4’Uã`[±ã/”îÂó —~›Àö[M/ñœÒôiÛƒ¸C*ñcç|Q8ºTa¡l¤lwÁoUh*R'±Šv(-ËjÆe,´š´ðh¶g< ÏõáŽßèG•‚§yr[Â+ì‹´n5¶• S¨&£%A:mvü;Yá¸ÉQ¼8r”3WðZµÓíÇ=ÄÄ ÿ¬Óí×½ñO'„‰fÜ*ª¹h ⨮ñÀfF`QEF?ÙÒ}À²-¤èÐÛ0þŒÜÍ ÕD‹4Ôj(J/œ=x(ð× ¤Úuÿq~ólAîB&!ók»Ñ¶èg2"‹XG8ÿƒ¹¨IguèlH0›úJãϹa2²zL½µ¹TkÆøÂ}ž#Å_c;u11. °íÕÈPdºFJÃë8¢ëõ0Á)¨q‰¤™ª‘÷¡q6Äw•ÛRدh•”WôÒ¬8Uïa⽎lwF–©#9I³'Aþ”jo*©šb{œª=3§ÜâæÈ ò-0:*„­Œ—ƒ¦©ÏµÙõ(U¢pÉÉÖÖÿpÃìôÒ.WØÙög?íŸqͲMo‘O±Ž šX‡ÍÏA9BGÑLÃG»¿µrù Ö6„ÀÔ›A$Œ”OÄWòÅáúhOîˆjý$P®?ë É~E¨£ÉOAS”Pgì1*F¨ÎÙ};HX£ÑÚJrŒpA×î‡Lf*eHadü¿WÊP*tJ¿‚p—ˆ‡PU%GuS‰Ïܘ- ÊyBüc$Kk!á¸ÅívÛµÜöEùK” ²3`Ö¤ú10HDlÂGÁ êÔñPwžb{€(jÔ“p…Ïå/‚‡¾GÜïÎraûÍP/.‘¥^»¼õêÓ‹ËŸOþ|:øeÆ­™üh:_pq'—ÛªçÖ0ÕëäNm?5Í“> stream xÚÍÙŽÛFò}¾BÀ>¬fá¡»ÉæµðúZÇŽãØcä! ŠäŒ¸¡HE¤<ñßo]ÝÝV ÷¿k‹S]rÿIyé«õ‡K ß×í¡<òôóSU”¸ÿ¶¬Ë¬“ïµçûž¾üåúÛ‹§×¿]h@K­àx00^¬âU¾¿øéµ*`þÛ•ò‚4YÝÑWû•‰hëÕ»‹.”\ɵž†)ÏÜéÕÎ&ßDÐÆ Lä#ðx{ÆÄLíiEH~ý)«Ÿ®B¥Öïˆ$–DBžºÍ³¾j…žUÓ_ÊšZßd¹êg*úa '=|$#6ªÕ•Ÿxiè3þ×;’ú|’ôá{ò—Jõ:«ëö2×w8Ûñ·{â± ú–Û¼múc[ó`'{hðòÉãN€5OuÕ¾ª³£ ,ªÜÍŽe×ö2Pë *¯«²é;ïòÊ„éú Z+ð2nŠ²ÏªöeZ B&AQv9Z„Ö!¸á¶'A'Ï;ϼçÑ9‰ðBW–³»2+è[èÿ¬X<|«±vù ]¤‚qúæ×ã6|ÈÞH¥¼Ý¿xß„Z‡ž"a§}]ð*B/Ôî{i ºúèò* ŒctLÙ‹‚b¿D.ý~ Â…ë¾ã¯3^ìP({¾ð)ïOGÙÔnÿK$¡þ oé?d/ÁÈoÆ|ÝȽnúl[#ÝÒD¯ïª~Ç»ˆpØi²ý©fìÈPÀþœF1¬0Hä Dð‘a W#~ƒ gUÓñ(ãf_5­°òÒ«"ú¥c›“ØZLƒƒ@§. À~ž¡‘ÐÉ:¾õ2ɦ:`»Øq¶Èê!³r7V¡8¼·Ì)²Ñ|•ÌLÓc€Ç´‘CÒíP2rìÙˆºè dîíÁVü”-(áAð2ù`l Ñ] Åø¸/ß#Q›êwu»ìÈöh(4P_pù…»jŠ™ ×O^½zÀ½í©ªiWÚlÏåb`X¾9¶û%³%l2ŽM²DÃe"[:¯N˜3¡Í"a­øin…™˜=7´YÁ=1‘fÍ"21`<1kf 3ô ¡Ï‘e(‘¥Á »èô’5KRˆ†„ƒ!-Xˆ§´Ký ÈSs›Eð^¢?€¼Á,#@º¡àm¬H9´ÿÆF1Ý™ÅßZ/P533/±utŸ h#Ðý£dˆo±^ðÂÙŒ›!MÆÖ)Š¥ª‚œÉ¸`Q<ÆOÙ|*…pТPðÅבð4"vºê¶É¸"…C$ÞdΓä-ÐÊK“`Ê¡Ö›Í E>\£ÃôtàzGJ“Ãqäê:4à2žª8‘õ†Ñ¸rÈ?`;ÎSà£}f# P\“¨‚HËí®¬Üs…h\ÝIgÓŒu6’:`{:椢±üñ¢€)Rw¼Drq‰Ö>ôâKpŠt:öðEVw-OÛŒh´Ý¦>c­…ÕqÀ C0’/nxko‘uj ýçÒ°¼‚Ll­YÂÎj¢£\ÀePƒ:OzaulE2o¨— ‚X®ˆ?›A©ÈÕ[óºÌšåÒGèÅ*š¥PÓTeŸ5Ù-½19ì÷R"ÕQžÛÖHý!’m³„ºh¯ÚÆÚ^œ±‡.ç…~SR zÓ-#"±…’ =ºþ-—ç0öÚ| ¤>•ÝL [ðš&Úš›#‚-Ë?†jϨä‡%*¸™b ZqUz^}\àZä%~4*ð‡§n·ê&j¡Âø¡ä~dz¢4WÈœ(6ôX±ýh¦Ø01Qló³VÈŠ ã»±%rïÆ½€%ž’o¨QUXí›×_¨Ëòs‡yI‘ƒ5CĸàMñ_Ä@&3o:]E@Zü¡á ‚ôÀGÓ†4õâ eEü[Õäõ 50ýù¦ë °1òšöEHÌCË3ÀÆŸ?ã‚»‰‰RO•˜Œ(°±A¨°FP5ƒŽ‹î7î× äõ¤HuöXlÛùã ØnHKîû æócã;ŸÉÈðV®°°ùòŸù3b¬çúñ:\ ®ò?Ó¼ endstream endobj 189 0 obj << /Length 1929 /Filter /FlateDecode >> stream xÚíÛ’Û¶õ}¿‚MgR)Y¡¯â¸ÎÌ6¶·N7¶³–§¶g"!-RŠ”Ij7n¦ÿÞsp@‰¤)G7ÇîL$ç~Á… mÍ-Ûº<ûûäì¯Os8Gßxa`8s=×i\+nô¼ÀaÐÚ–«ÿ ¡yØZbüÙäάŸ,pvä£ßñq¹ö åýïë>‡… ŽcÌð˜f8Úߌ¬í¨dGÝík+vµá„Ù¤›ãÜG›ü€ˆZë_FAÄlOÌ­€Gè]aЮù ‚¨¸ÆŸU§«êÔ‡„ÿÛ²Èg*•ìö»VÚ»ÁÄ!.‹8±(+Q©˜¤y6GJDáçÎ\V7w"]É+ñ.W ñgRÿiûZ°Ïz­9ÓRXÆÓDTâœäBm—•iÞŠâxæšß±\2±åù©ÔÚðDX‹·Âi²æWc‰­™x˜º.ñnA®uæ¸Ìq 6aÚk冚},×xÀt¯§qíÔ×FbŠÁ妦š2Îî÷vß@üéa‡…†>{uuµ/§¯‰Î×}Ò˪ˆËSyäÜëÙEÇ/póM ÙòUÇ]©š&r&ViUBþUWíÍú¼{>ì®è;xLSÚÄîdA÷`¾uÚ…³Üù•ð›ù}*Á”ÁM!Eºø¿¯…Z¼úuw-:»„-«ÐÞVõ%ÉB¤ic’ì“Ρ%ÿMo¢ªÿÈ|¦Ï"§Ø¤ Ëñ÷ oÇÕ°ôØÀï¼Ø>ÜRãÉjÙ0ê€"Ù‘èbòÇÏ.ØO'ìñ£W'«Í}©Ï%þi¢„ëÀƒC÷†.dµ*²½ç§ÎöÑ Xà;õþñƒä¤ Œüù¡×–ÿßOgGŸŽn­ã‹ëçOnž=¿¹~|u1yúüÙo©¸>õÇêƒVW§Y!å§=}žÓÎöƒ‹ß8¸ôžB>£ÆÇTLã>Ë‹e™6Úiž¤îNRóäðGç¸øí3~{H¾Ý¶uêÎÎX&ÇÏЛÉdbðA-êh¬·‰Ì?VñÛöÎż˹Yè·7*S•y zÒW%…,U²©©|X¨W±á_kpW‰i*ÏÍFïÏ-n{,°Ãv¼ŽŸÇ r<…|ÕÞZ¿?Õ ”ÿ媧¾×[;ˆè+Ò-BO»Ãê&ÑÞ¡Œqèw]Û6ovOb߆ÝeecÃt3ü¾Àý²{Ä~¹qQàé(@ynPKïµ·¸Ç\¼S!³<Ÿ#Ør isÞ[úܶ—/_â­åÅ‹§t)¹0­fª\PWeÕ¯?¡gf"–Í”;îì¼Æ`»CJNn%]¢ ×72 Ÿªi!ˆå{‚èëTxÂñ’ÿ.¦>µbaÆÒ\˜KJÐ/Y×z"H¯梲Êé)Vó…XkSJÉgôœ®TZjZÌK¶®·E®¹¾ŽxävÕà‘gÔ aULP÷Õе™ú…z%¬]xçŠùôg‰kÂa·ªaÿBÎ*KrtÜ=^»–„ðèêêœP´Ú†›\ŠBT2EÄ÷£›\DÔ–#ˆœªAPil8r¹gn° wPŠÐÙ²÷”$â8/‹vË×U3ØÛ¢‹÷Ûõ )6×1KdSJ¨i}]‡d^–b©n–úÞý¦fÒš'˜ÌèD‡;F'‘ÊKT¥"ðRçtñRÐ[YÊ?/¢ÔáŶDä_–¹áU‘é J±0­Ù*‹+ÛÂ%ï‘>_¥‰÷)á Ôb™JLb,UU¥Lgç}Á¹WÕíï:"Ð0ŠxÁZWóLÀä(KL×1å #]ÃY¦²A› Læ÷¨©ž„’u¼@ÐZvˤk>@ô–N¤©ySí7¶c׊ÌaE€>ßv~½Wi T$ª\ŠŠ¨‚ÌKjšo ER !–ËTŵoq$ï`¬Cm5ë_üeèéÕÐŽÿÒ òÝÛ\01e¾÷ü`ðÔp Mriˆ³¼ê·¾D[ƒ”‚MÒX´ SW2+Ázý} èY.Mºf ð2³ rVeCÜ)šCU†±ÈÂ$ß›,ÃàÒ #2F‰B™ðŸ°øÌV©Q¦ÇjÖ™‰ÚÁÕK å‚Ff¨«‚µV¶î9¾«çÎßãô~Uä9Œs³4r½‡€}EÄBünƒ ßߊå§)SVú¡á(ð¢Á÷9-ÄYçŽôüî§e[ endstream endobj 193 0 obj << /Length 3249 /Filter /FlateDecode >> stream xÚÝkoÜ6ò»…¾Ý.U%RÔ£w8 mÀ-š&±qwER,d‰^ ÑJIÇÿþf8C®¤•sIÑO 9|̃óâpoçÞË‹n.¾{…^æg±ˆ½›;O$¡—D©eÒ»)½w«_ÖB­tw«»¶_oD’®^×Ç]ÕPû×¶<ÖšÚ?éµVŸÖ!̯ۃîüòX•úµßêZç=Ï}!üpýÇÍÏ—7/B +ð½ "? ¯Ø_¼û#ðJ€ÿì¾ÌRïÁÌÚ{QœÂ·ö®/Þ\c–d:b ÷ ? qssoËÕ^Hèý®>ˆX•­îi¬i—9’jÕ~@æxqÎ{ó0åoëH­zdå»±á“Ѓ ¨3èw}¿ÍËr[tëv+iÅ„b•øQÙÏöT¾€þ;nï:ä«Ý/lJ_†ÉŸßºÚãÖp°}ÛäƒÞ6ù^/  #陜àñ6Q¬|’Ø„¡Ÿ)Ecm·$³ÐO’èI*ªá~{ÈûþÁœ‹awI¡È@a„ÝçîØCÕ6þz£d¶z¾ÞÈ0sj7U¿'PÛÔ¨òÔk´.{l¦«¡%Pµ?Ôz¯›ºª6Þ"È‹Hæ±ê4tCZø ÷ËÑ‚U•7Cψîìm¯IHaêÇS!YÊ{ßL `4ñ3Éö‰ŒˆÈê¢i“&cËh²iÔ2\À·hÛ®¬ð©_ ¼f_5 TÓìQ6C>{»¦´;ã)ð††|Ó4ádÂ[LÜ£ðU¼ºº³KõtY£áAo·#Y º0tªˆiÞRUï",ÐÈCUר Wûü@  =l¶f`«ٞx…fÛ¡AëØTt¾šö§“¢- yS:„ cѰ§Öm^ 7ù@½|‡¼jhÏ\yn3A Y”U¨säáqÛï@˜¡Áò?ÌœªÐÏ!‹y]ëÒh•s¡0–ä|‡^gÀ·/)xIqlÉFJ?Y;A­w¾“÷n£‚`õÊÞµ—Ÿ)€Î÷“ÝgŒƒÔDû°Ô®Û=ºðL¬þÇ]5e‹Nä…’…«—××zþúŠ&N˜`EÞÐ䓯@ð­&h4XVIðOUNœÆ­ ¦íÝ@Pø>ºéÁÈ „ú†3¯_¿º|ù›EЧEíW&È¢$ü%+ùAC€nªfGçL¶Š­ÎÅ_èÀ٤Ϩ9sƒÄÂeMi¨ÑôÀô@)ÔÏyÉÝ:˩둀¿ŸT’ŒÝuìGptßö^„Á—NÒ”ØiõÕÈ-Ö-)ZJ¨¶l·ä…·{=äÛ2ò÷ àøŒüϦ3Á?V0;“=±N²áާм­’ŽÝcé ¯__±$K]ÔygŽz;‡$ "N@Ç]dÿЪïè³ÕŸÿþŸK2ÈüT¦v™ÿ¥ãÙ„©òcËÉ…AV5.^n{]lÁ©lÛ[̬·mU:9ÑB#knaN¡cžú¹ïi ™ËHÀÄ·?n¯^½Ù¢u]þgûËåï‹y fœ.A¬ç[o"‘šTurxgþuùöêÅïO!J@¤™;‡ß®~‚“W"1n¿‡ÎXÑ'H¤yàž¤UšÂIÜ#4^q®ŠâcφsIç:ê´Ça×=#QlTMÑî7œŒ0YÎÈ©$ÙfŒ€"MÀÅôÒ•Éš5»GˆŒú#˜Ê x69:ìï©g\ij´ÝôJöxð_Bú=˜xÉÁî à¨sÛÀr;“Iå‚0Ûó–vÕXZn¨©åˆþ,¹g? zÛ6l#„”¢X„6ÁÆ!tS°£8 púãAO]j>ö¬Çÿ†Œdà™u5 µÞ覬¬Ç®€ò]ݺ/0(fFiGÆüP¦˜zÝ™´æX 0K&>üÀYLÄU”taË$ØÀC4‚uƒ”fÊ(Bâ†&Bâ<Ÿ:˜&žÖ'Lw1"C@ÕÓvv^eñèœ%ˆ(2êðºšßV ¿Çu¬Vxò ÝQ¦3ç+†®ßòfÎÅŸœ®1–e}¯O6'u€r¿>·¾âù«Ÿ¶Ìæ˜ö˜Ý ¥›ÄíÑ;¢Ìëö<ÞçÍHËòᮊü¶æUo_üH ¥Ò„§L6ï‘¿*= 81£ÄPü5‰áê÷¡ímÑáRÃx\ˆâye ¿oilœþôÊi·Š:6— üÖm^²°qWCÐ3ê¸T×7ô5jhv¶lÀ®£U \ *¢l´ Ð"D™M™¦É¥HZ‘GDϽ` gù-¦‰9]àÈk9Ob­Á%–ìãËRÉåëÈ3M9vi'·O!AÌÌ,û<9áÇým[/U oIÔ¤¨aIÜ ùyTÎB?>UKN6åPN3\'”¾ÚÁ­úØiNwAqU”yó/ëôÒhöå+‡Å)Ð!=)ð‘aIÌûèÁÜ ÅrN›u‹½'©J–H_)eÀ5ô”/Â3(‰y ôe$Å ½b< âËàŸY©8ÉN;†)O;at ¶tÚ"tà´]pBW@GÂìÀͧO`8+þïù»óÞx <™Bï…Ÿ—N#¨Š¿]P‰T X\‘sÂÈKñˆ“—¼Ü°bAs7öc§£½Ât„:$±\ ^†ùZQü;:‹-üµ¢ÜÄ™„!Æ&é‡*Eyš*òäz•€dæ'Öƒ¡,n,¦ÍÊz•±GÁ˜ÌóhŽǤ£êßNÀi™ H˜ÎHpü¶ˆ½xe¡çÅé’¸4Å|!¦B79sœWE”÷´“û ól‹Í”­¢Äî/-¦R]´£6MP“Ix–\3ój2“=GT;¹ˆ$‡YqVº] °E+3‘˜q[Bž)ehC¿c¥ð,HrÄ£¨àûÜ‚¶¸tC­¢Ó\‚α§T¾Ù#Ääa©ÜGÛmõþ0˜[1©¥y|ý°ÅrÜßÚÈúDYŒ‚rš-eº œNîiÐ;ö &ž²îªøóB•"LÀgÉ(WÛ;`’òT·w¹ºÃI•úŽ9æ‚É›å æF—!“ăÎKšg”é+¹ˆG/4(ò%&À q*­l"…‰*¿…(ðBMU~ߎ³"ïMQY˜ªóŒûp4¡+Sàöäÿ.d‘œ?Šôöâ€w8*öpýs'ÎwðVXÕÚ0 k÷.'ªÜ—ˆÄ:\‹9ëœËPH?˜»H«„â&™ü–¯¯4I@x9Wa°ª…LZžT8²å[ÖUóZ®²my²Ó‰¶ÁuuÛñ{ΣÅÉ^©+-Fë{ö¹{:¨ËÒ턚–ï^»ªÉëïfÝÕ”×–üíÛgKnÔ¼ˆjd´Ø3>üî‘:ù†XÍô™ EhŒn!Ø5Ñ(P¶ÜªÐ×9–O(`ÄÄœñ”ù çùh¾É§›ÞS¡ÃkØay¡_5¬P VÙ*à܉ÎåûÔsßNJΤÀ2ûx¿ya 'Ã2å¨SADzcF¢ ¼Ãq›æÌCZ`^²;r1 Ó¢ .U=,úº³ÅìZ‚Þïз„ÒÞkìñ`cé^¨Õ¨$®M™Šêùó@r]5Åb Vù±œ¾-#çHñ0*ý‚\?‹µêÐO;ø‰3âÇzlXAš6}ÎR9$¦ 1ÝÀå’ßxb kL¼¼âålú’,›*¨"ñU8/ žÿ¦@F©ÍŸÒ¹–"hùѬÿ6ÉŠ`¤8žÓ2‡-Òîçbê±µ\ÊYÂicÊ– |w·Ëò $;ÕÞ“ñJ¢(ó£Ô=|¢šoÅ5f;:ñZ&½ìðÅ_š£²K¿4À( œNò.ßëaRçä_«¡Áô§üƒ‡¶žú­܃è¾ù…ŸTHõÔ¦_ø®RuÚÒ“ô‰'ÉDüН±,³B,‹Jçä Òðä ÒówB9©÷L¤u¾à‰…/„˜ží5ÆP ´ÜµåËR§‡Ð’~¬ðÐÕõ±ÔÔYú94Ç ºe‹?6cä{†÷Ék$c¸×ÅÜúE0úU…¥%\}hx“%¬S-Ä þ¾=Öö±€ƒ $Ñ 1)Á´4Öéy©k`¿Ñ˜|ÔöIw–ÏÍ.'ßR¼š=ÖΠ¥"_Ä_ýû¬óŸšÁ‘ÓWƒ×›8¢Ì¸£\+1¾Ï©t+®õšÓ¿Ë ºdá* çÿd;ú‘ endstream endobj 197 0 obj << /Length 2121 /Filter /FlateDecode >> stream xÚåYmÛ¸þ¾¿Bß*kßôÖ~ºæe‘+rÉm|@ÜÁ%Ú«F–½twÿ}g8¤%kí½M{Z4@–äÎ >CÊÌÛyÌ»¹úËêê»·Š{iF"òV[/^¬’@¥Ò[Þgÿ¯ úºÝè¶éK'þÇjØ•5Õß7ÅPiª¿Ö Áü,8Œ¯šƒnI|3”…¾¦ú­®tÖÙñ<"à‹_W?\½Y]}½â`ó8Y ‚˜Å^¾¿úü+ó ÿà±@¦‰woFí=%PVÞ§«Ÿ®˜õ†\„*õæe»ó.uÝÞ×’ âÒ ã8ˆ¥Âµ½¯ L14ŠÑ°Y3ß{’̉e†¡WÐ Á9Z¨âÈvð@*)&éåÓnq ÿÌüQ*ŒâtÔÉebދ޲ÔŽ­Ê­:ŠØD'›¬šCKÂvœB3æÿ7~n½Ÿ<@R"¨°B¤¿ß Äà°aS…‰[h{ŽqsŠÛ±[†6â®Q§`ÔÎOV–ÒI|L4ì\˜—†ä_9\Ç£9+]H—Q0e'‡5!®†”b6#%¦¦DJÞ¯‡²î¥X,C §]וërhÚ~Ýé|7u¯úõæq½×ùÝ/,dã ä(Ü+÷Ǹp"˽ÏF÷i‚5ÖÞ—uÓ®»>ë‡î;=».ÀÎ.!Y&­?¼{Möº+[]c®&¯7Ãv«ÛuO°N·‡¶É5tõÍ]“vöTqÞ?¬Ë&þ»¾¸@ÝeuQiˆÿ³Ysé\2Haw~+èu¶×ÿ5ÑF#ÖýãA?êÃàŒ6#}T:™2SM2j7Cï†] æoÆ2G¤üïÄò R£ Rљߪ¨i†ÓïÞ›,1Z)³V¬)ó›Å’'±ßê¥ÆSF­þNS¥Á› óK¸Õd‰Ào¼ÇÀze·'Ñý®©f6 ¦€óe½³Êš/xûÑuGííB1£˜'ѸR¶i2„;ü±¢íPç}ÙÔ^‘Ç–d)¬rh:góÞÞ·L}èÐÆÞš×f‡Ñ¯3pž¹$ƦðÍ¥ÅhVÜ”]5è…dþ*ô;|tì³­±?t&"'Z€dò¬×5ü/h®v!¾5ãÿäúГ,1ÛÉÉöJé<Âd~„W¹GûŽtæ2‘¸9ˆœ`±”Bú+2Oœ:iΫb"ˆ’øÍÓX…lî~GÒ¬Õ:.ä±xb æ-y¤ëÈ&ÁÙlΉÉÔé·h,û4: ’›[ǹà“"NèÏĉ3¸ÖDÒ͇í”Rù<±Î-nÿrƒHxU¦Ël¥ä±_éz×ßQ„›r®(3ÛnÚ€ º¬zÒ[UæPÜ£^Dj Eh–VN„Ã`u¢Ø*‡:ݳóúq£œ~¬P¡2?!Øçv=xn[—´Gÿ‘m)’oÆ<1'S ë¥r®÷º£&S¶ävà… ©IРžQÑßã¨f ”Òù†ŠÖ » – („9D#(^¾¾#¹eÊ¥¢g©NrEH1µK SÐYä«Ëȧ„€#Gü+‹5ÿšáŸ½Ð‹õÔ­p†ÏyþµÔUIc p2 ⲆÈ× o¶TB ¬Äl˜´yß|wMµ£h~ddl7út7¥9L×-ë¼ =ÓöúÍ­•d;ùž$G$Éd½ÐÈêsÉ®Ùü]ç¸Vɤ€¤_þ¤¢|Ji‡ES"Ê|Â.™A…L 'С‰ÝtÅ ‰)ö¶Qï0]SùiT”Õ­F›,7áCÓ¬BÆÂµF3ÎÄäÌY Ùh*9„ÙQJT…$3½ò>µX êë¨íïtʛOŸÖ¯Ö?®ÖoþöñÃ-Z°Zÿˆ|ÿþÍËIUþÞ¤FÑRÍÛ7 8C¬,“pJ¬Ql˜0ºÈØE!ŽFŽÀºÙ¬HžÒatÊ"J.ág:|F–#°2»lEŽùFgª ‰&pygï§ž'!úˆÅÍwdCé<ÅzYÓ©§(ŸzÊÓKžâÈÑ”ã]:|zE?aC`Gw<ûeG½þŠ;;/9ÙÄÇõ¤Õm¢wî=T}y¨,Öûr¯»S ã—V ð**î>œ ooè³+WT‘ Ç >ZàÒ)xÄÐr<àòTý7/ƒÏ)xU¼«û~Æ5üøz¨†p,líÆ}¿-íCOÛ,‡ÌðÌQƒÈ°4ÓÃæ6ϰ>ò\ˆéª·±¬§·ÔQ”]>À«·Á š- $Ã`(FdÔ;«ðc´±ÌtÜß•„jÞ™ít+TV7=u=¡ml´IÚÐ¿Ï »ÆaØTe¸ ó6èž_[ÏÎ Ä=ç²Ê|òþfèé Û#šœWi˜¤µ#\Æ®°ÿÑNohýÎ|—w]™7ûCÖ—´§0úÞ¬@(ôvCNi›=ÕÚãùÉVˆ‡ÎÃ;«¼köv\u¯´Þ¹£t&$&5À‹«Öøi+#×Ñ+¡hIèË›ƒc3Þé¬0!‚Ì•‰4¬áˆ¾´›D0Sn¥}«]­¡Þ¡³C´BM¶…8·Ù汨üŸi²YÖé¹/ •£ñ°qæý›Ú<éU{ÀKȹTl“c­ÝƒÄI†C‘¹Ôüèè–2¯yúwóç'4tæNéÄHÞScÜ_hÐ5…ùïß­¨‚±;å¯ù1¡:yñï0gMR^#ŽÐÌG,OFi§ÇÊ«»ì°À;…eóÛÐb©ÔÕ)Õ}7·óŸŸê©È endstream endobj 201 0 obj << /Length 2944 /Filter /FlateDecode >> stream xÚ½kÛ¸ñûþ « Ä )Q/ (°¹\îr¹Òì-;,d‹ŽÕÈ’OlÓ_ßÎzX»·Mƒ~YSÃ!9œ÷ W¬>®Äꇫ·WÏ_)¹J½4ò£ÕíaåÇÂSB®b•x* V·ùêÃúÍÆ׺Ùé¦n7[?NÖïÊþcQÑøm÷¥¦ñK½ñÅúóF~YŸuCàú"×Ïhü^—:k_z¾ïÉÍo·?]}{õû•²Ä Ž÷åÅ"^íOW~«à?­„¤ÉêÞ`V*Jà·\Ý\ýõJð•ܯ'áFÂó£WErÕÀÄðýÀ)½4 }ä/…'‚˜ =0™_ÎêÃ6b™yÖm¶á:Û9¶U·A$øëC¶gð¯"o^¾€Ÿ)-Ï_ÉH†bµõœñ×°ØOÖ°ñúdåÀât.õIW]Ks"K wÙ¥ú‰æt•ø°Qb]7v÷ïhp&¢‹j_œ³’w¥%0Y—Åþ ‹jØ@¬OYWÔªHàøû¬âʶfP]uM]ÒÇ æ±þ‚ÜÀk“éÚY{Ö{s¯N9Ð/‘ ƒ>f¸ôsÀ··ÙA°~…5$,£ŸC_–4Êu»çë‘ÜéÞÝQÓ¤gE‡²ñ=£‰VëêQg¹æã~¹ÀUž¿ŠÅHžAf ª›‹ýùS¾óŽ!ĉàƒÈ‹¤oñ<ÕmÅ^ob/ Ø oíù¤08ƒAÄËg»òÁk0Üñ´ÓÌ‚F6+l_9_³fF¶³k¿ÜDáúúg{ïP¼ ×(™ý^·¼î猤lŽ@í÷¦¦ødœÛ9¨LxIŒÌÜÿ6f~½‘bÝwǺ)þ±²Œlýí<ƒµù¿4x’n­yŒ¾å‰XeY#kïj\Ó ®ÆF˜ð{n ögðè@jM}b4{8˜š¡ÛìgL €`½m-¤ DœÏà£"°¢õ3I½µ{Ñ­ØkXÖ.˜?ß¼‰±Ï@®»/gÝh§I¡Ðÿ_0ØÔè`Á•šá;BeÆØ×&ÐÛ×·4øÔìBíëœÑP¥Ñ³€#¡À좷`ÚrŽ ²Çv.€º e\ÁÈeqÏÉØ©©³dM¹;›À¾ì^RåIÛ=Ù§Ý‹=†ûãÔ9Tug½H‹Óh™u Ž£c—°ë‹2ÿßìL@EÆ®·Lê6H¼ÔwÆ­¾i¿{óú#u0Õ=˲+P ÀhÏ4•]Zÿ#öî62KŸbôp»Ð} %S„‡M´ìÉÕX<:gDBú’Íhó~b£oBll‡@àjJµ~ÍëæþÄÕÓÎõÉñ·BÓÄ鎈ëx¡Hg÷°œå³®cãßõ^2ýFÿnœoÑØÔF¦à·ÊÌ\E¦ñÏGØåŒÜ·Õ*+B­àq¬+Œ”9ïSxš:ÜÒ%¸>#Œ\wYáð/ CÕf 7&ä‘(g)·X`ÁWf±‚|ÜŸz œÿ¨kØòÊI–‰gšÎo W`ªÙ¦DÛŒ%Ço[Ò2«¥Ûii³c÷šåù¼êq®¶§úþèÎs×¹Ê\kÛƒÖ +üM†P‹@µé3 µ¼5ÂæBÁEVÓpÞдÓÄi–ô§Ý†Ç¬É)-hx»9‹kWðº/k5ŠÊn½š§¬IRaƒt¢'ÈŒKç§ÞàÛß¼Þ}® è½E+¿Æºòo·?Þýøw¸­pß ®OB¬Òd(– -#9 9&åðò$(_€”ÏæŠˆs9 ž•Žf\¸ÝÖ‡lÊgQáÉ×¼{·Iàëæfé¾Qâù*´÷E% |ÿR/_²^à4]S½@¤¹^ –Ñ 3àeF/»¨f^h —¢Éº;Ú0ÉdOÂ~ë¾0›B:ôàsÑ¥¨€,ç¡:9Zäyz¢¬ó7-!i²XëR5ñßðÕ[*Èï.¥¿C]ÆV™~€j>ÂE“Ù8$lGµuN(×7¿ ‡¨ù8·¦ÅLÄô©0¢p_kÁÛ\SŒªû;mX©Ïý)Ví¦½±3`/ rV Yqn9tî ÃY€-'w>„w²n¨Ñ‚ÇDT—Ö ¹OlòÆ1…t±h ^¤Ó±5;µ³‡+[vÿän"|”Ù¿C×¥n› ½4¹Lël"=튓~ yè:”  Ø[àk\%(¶ÁåºÄª/.d †—¸ˆÀÃâ!0âòÚî<ŒbyÓôYfâ{"|ZþIýüQGArò·êÇ„qɰ}>P/H¨Ý}çî z9­ï «6ÓòE¾%þTl.eõCsQYY~«æ…˜·-Âoôð`4+uáïH|Ê÷„ù5¬uÜàHÅýd¬¼\B̺¦ªw!…d„»ŒÜ…P gœl“.„³“vZ‘QÁcâ! ØÀࢋÁ@Ë‚)¸¾á*ÜþpóX‚ý¤)©ãû“M˽)‡R[:%3W.Špieú—÷ô9`˜vÊx8¤/;Jg æ4ÝFtÝ sý Ý úšw+†Ã\±7÷3¾õ›ˆ”XºÎZŽ‚G{2£’_I||mŒü¥g’d(2MxqªìnÔ ÕÄæ»¬]öyÑà˜chÁK›vÛå¦Gª;}µGŠ["°óÉEæ¨ “°ƒƒß³ÓèqŽ·±O2°”ŸáÐèü€lò¼˜¤“¢ŒzUL\˜¢¼. ½ØW³|Æ$!r”pHûx(£…„CŽ3¢5@9áÑCÑ!VžJþ(߈¼dh†= ¨È‹ù”|C„ê2ßÀ\÷íâ †|À£|CŽß]¥}nè,µ€)ÊÇ(HÙ}0ždÞN¡|EùCgÁäûX°ÏrSÛIˆŒzŠužÝvã÷ÆÔ^ŽÙ¼€ï342]šÁ˜AƸŽ)›<8L[;^¿·üZª@çÕyv†›Ù.”K¡çY{Hô-fcã8†C”Á*üBu‘Wã¤ëÚàÇüáa®MUhde¤b(¡Š¬i:çßîX Ü‚ÄvÒÃ!dz‡L g(“¢ó÷eŸ/¾ùIŒÝëCOÎàÍFoBÀ\zcŠ Qé”ó¶aÆý3çLÂËæÝÅ?lÚ² '}™~É­¶í42CîBaîºíOÏÞ±zàM4¤^.Š*ÿ/|š,º¡"Rü¼SÞ‚îVÑã9^áÖ$õÜï`Ÿ§Ç–£ã±\>µåN“í£Û)½¬¹¸ƒ9÷¶öõé ý®(‹Žñ²}SÛ‡vNªÚi*;ÿÏœPA~ùä̹ü#ØBùž”£‡9£Üéÿóem+“"” æWý>Ÿ" endstream endobj 205 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚP=oÂ0Üý+ÞhK`lçÅŽWh‹DU©Þm E2 $¤ýûub2Tb`ºÓéÞÓÝ Øƒ€%™;2{B –[­4¸ Ž6Wš>3•Sß|ú¦nÙT™‚¾†n¨©Ë.øÄù&ÉËîPúIâï>øm{õK®—lãVäÑ‘3‘1‘™ 7ÂÀב¬7ʨ¯@ðÌð;¸Ž€ºˆàƒ¼qm3â¿_9r¥ï~usŒ9¥J{HìC¦-7¶¿ÔÅ÷öÄrzaýVc=6Õh颮¹º´C×1dìü»Y° endstream endobj 211 0 obj << /Length 251 /Filter /FlateDecode >> stream xÚ½‘?OÃ@ Å÷ûo,¹œûþ¬@Sщ’¡RÔ‰ :ÀÂ×ÇIª–XYÎ'û=ûg9à+.âMçêV$¾‘Èè^ %zÒŒ¨Å'E·G¿¸¸[n¯vÝúd¬Û8sUÂ2Úª|CiòmOݦ€âKä8(*ó¥rT´·ƒdV+‘/ªçZ¥¬ !S§&ë$ä³4ÖpT_O|žC†!$±WrćÿHnV}Åz±ÖŒµ:Žø+5ÿƒõW\vîÝ‘}‰¡â9&<\¿ Ø[z=ô/Ÿ£è‰6oxr§ãŸÑ•³!ì‰xZ€æ(6ò ËêzÎ endstream endobj 227 0 obj << /Length1 2923 /Length2 22666 /Length3 0 /Length 24257 /Filter /FlateDecode >> stream xÚ̺eP\ÑÒ $Hp |pw·àîîÎà0¸;Á-hpw ÜàÁ%¸C‚»½I®$÷~·ê½Ÿ¯¨S3«{w÷jÙ{Ÿš‚œXQ…^Èd Ù9Ó330ñTšŽ@I #ȉ^dc `a`bbƒ''q9[‚ìDœ<V&g €‚‰3ØØÀÂÄÄ OÚÁZS€±@èl¤êadPýŠ 'gzc#'°hgni¤›ˆ€ì=-Í-œùà¤ÿå`rüEð‹èî ´s‡uúåT˜ mdb rs²¶Ù™¤äò 7°Ð@²-ŒlÌ ³ß.ÔTÄ”UÊ jŠ*Ô uK ³‘-Ð 0±0r42q::Ü€à8F¦¦ÿà-idPµ‚#; 0E{{ã?³QQU“ ˆ ɫЀêt 5U:€¼*Xø[ó‹ø @ÊÎÔÒè—¹œ˜ªª–¢3ã¯j˜®à˜–¿˜þW:àd²›š9‚lPY8;Ûó02º¹¹1˜»893€Íìm¨Pµ°çr´€?6Àß%v±37ÆœÈo¿ µ4×ø;) ð·RNH^J\LE•\-ú_§ÿÝygwçß©(‹ ‰Ê‰ýí/z–6@§ßÝúåÉÜbK'p¨lÁýó‡tþwÎà¶8ÿ¢kó&' ìè'ÇhæìÄøÏ¥NŒ¿ò WW¥—•“WûMäøÇ³‹ù/ÛÿO†ÿQ8 #§ß”ee¶F–và™3²3ós6rvqü– )É?Jˆ¸8:þJMî_*Çg÷¯fƒÀéèÚxù¹ý÷ØÙ¹8yþÕíÿl¤ xÜ-œþáøÏJÛ€EàÎZÚý¿vî×ú_…DeyœìLðÃÞÃbv¦" [[0o'ø_#!j n3Èуñÿî{k;›×ÿP˜YÚ™þ*1ÀÔÅžQÍÎÒÁ(%úÏå`ü™9ÐÀ:€w±‰㯀¿÷À/1ó/1¸>^ö {€™‘ÐÇÒ þ€÷r2rO§£ ÐÇëoÅ"xfN€©¥‰3xǃøßÞ¥ìÌ@îˆÁLþ¥úçôQý>ɨÁǘ)ÈÎÆ<±fðŒò gðœPýÿýú/Öâ.66ò`Tÿ§;ÿ½ÐÈÖÒÆãÿ,ý¯UÀ_©Sý{K'qKw ©¢¥³‰Å?ºô¹”³x Ù™ÛÁþ-RûuâØ€7ø ·üuQè™Yþ[žqk; “€ƒû· .ÞQ7òa£’„œ¤²$íÿÀßëÄìL@¦–væàáæ9:yÀ3ÇŠ…àÅ Þ%¦@÷ßs`d°9ƒMö.Î>¿º ÿk68ØŒB¿Dÿ@Fá?ˆÀ(òqEÿ n£Ø¿'3€Qâb0JþA¬F©?OæÇ“ýƒÀñäþ p<ù?Oá߈‹ À¨øã)ÿAàx*€QõûÔü7âÇ3úƒÀ:ã?Ïä߈ ìÅ|büYÍ̦`úWøonãïaúk˜¤ÙÈöofùÇ€õtýËïå Ç¿€—˜ÿÁ”,þ—ÕÂÃÞh÷× °Ìò/ÎÖú/N׿/æcû2ƒ³ûãŠljÛ¿ôàtA¢ƒAÿ¡³·ÿ£;³7_6@³?acþ§Ôñ? Å.=ÐÑôWq™Á©;üÁ©ÿUfpžN¸þB@׿ Á^îdéþ—8ÄŸ€ì`ÎŽÀ¿jæëìúËœ¿ËŸÑGøý^ádrü;ipE]ÿ‚ࢸýÕp°Ó¿8°€£züÁóüS°'Oð>ÿ-øÏcAñ×=ûûú`úsNüó•ê7VqvY5,MÁ/¦-‘3rv´t×aŸýÌ`9øï_ßôþ#ùŸkë/kaa»=;+3€ž•Þ |ký‘3Y³Ã<)Þ¯zDZÂÚ®;‹˜5)_Gî[°œ«nfëÕ×GRŒùÙà¾cw'Gƒ†QsšøïÕZä‘ ³³é3‘ŽNåÖÜü…ô‡´Ê÷ù?f©ÊgøSÄ_}ÎqrÅ…šu˜…Ù…]³:’,«Êª€Q•\˜wÒ˜°§Ö¢T_ X-Q;Ë/óRT¨ŽÏA‘©H&ÕØ|3CdH w$%&±Âé;Ÿt¢wØzý>øºÞk%MJ”[.\àr½*Erß"Ä’ÜyóÍü€Ž#½mÝ1Ä£h mµæ:›‡—˔拧—oËls¦òåýöí—þÐâÎ¥7Rºí¯´ïÝ=Eš žÃ2ž§!ðºî °+,ÛPTPt<÷”|¦¨›bz£OúbsTe8½°ßqøéöÏŸ8¾m¨&£-…¢[Á}“*îM}¶¤Oãô`yd EÐo2ñSú ör¿4i úÙ8hqŽà¾¹êV²)òwsÚ5Þžj(’Z>`Þ˜¾+rÕž‹·Âã¥w¥ dì¹…ïb´ráˆ"µ™n•ì)c!QÃÂqCµ˜TxÉIÆ^®5Á~]ófkPR´~½zÉãVîRRBöåEnM‡+ñ_£pOÚl•’I€6úæ>f·Ã–s“ dz/„Ø1“›pWûWœRÅ fÎûjr\óvóú2öêÔt¨ º)B±é·ÕEÐ ±ûYþ•>N5Öìa‡è.>ÊÝ(NC§¢†>¼§2Rg NµÌPAF™c^ô>ÈŠÈM®5NÏÉ–Ú¥qwÁËh1GÕm+9ÄxeañY’õÎLUaù·J,z›–{Ü*ZIÕålÒ7a ~Â°ŽµHÕª÷ÅîÉ™$ qCU‚‘åUBV…ë6Þ²†‘öC¾š¾†šPÓ@ÊVoNM*pÁÛt]¿÷ù.Î4xôæÉÆ>žï8‰dŒ˜ÄzPß*~d¦xòo—â t§#ûúîè&žÜ>>v^¡ÿñeµÍNåǶØw´2œë%9Òâ‚+A kÆæð—² “‡±TÅJ©ŽîÂѯ4<çßmåKï#®½·žyä²Xxn”W ¦l>¬  _õˆüà¥âL.­üàLV¿«,ÞkLš_ãQÔHeزÈà ¤Ð·uO3Cîù V+÷re¶WTy‹$‚‹1uk¿—ÎËJ¾qL\*œBz´ð]°—õ‡D‰Þ;8–3èðÓ—l¡Ä’t„¢›.[¬u ”ú×êP7áUÎÐüâ=ã<Üc$ãŒü:P¯î±Ï3»_‘ŠõŽé!?ÖÊtÑ ÜS*†G._Òª02xÌ@UòB"FD‹hu†]c]›´ÒÁÉ~»¾ráU>ùàSpõ®)ûÕPœÝÖcC#nAM¶?g5dNšÏ-))Iu:©=Û¥éÀÛÔ@ãu} zü"‚|ú¸Ä :TÁ{Ë™—Ì¡ŽñÖõ”WÎ¥•µ”YŽÇù[Ã0ÜÜ2'/ :’“¼D[ž{$ðä›–&ç—Ÿ8}p>ö¹ fF©0s¾Æà³HØ,i_ÁŽó°ì÷ä»lÖ1òøW$¤*Í&xäÜ=ÞÞh¡$¹Û­Ÿ­7ªÍâ(¼?˜nô4œÁ]|MÍ㛺gOyÌ0´¾º1”ùèX³¿!D^–4ç©¥ê°zQ ‹mævHÞè1Á Þ8ÝZ²¥È·š_‘¹Ê€LÁÞ*—i ³¯½ñ™ËfjÚøLÑ"Û‘`^=t<±`³¦ð)gö\u†x"|¬´‘«²ã΢•<¼tQz x7ÉæìšŒúÆaЗ56ýìÂr¢ÑÄ3ÝHdiqzRvFÍ1#ä;¾ÌÄ~õB@¹fµKÿMc‹Y/ußmz-‚…¿Ð€;v.%¼æîC#²Èç<À-­jz<îg(ùRŸ é¶. 6gMWºÒê]å7Ÿq^d‚ÚéL£XW#gïjÇ0 bM¿nÐ÷Èi"KLáòÁטū]¯]¡öfÝ !j¸’R"¾M]®0Öà æ|å QËÄ‘ÐrMàu&…†±ÅR—âNÎ+¢†_Jo • \õxr|}*ñÆ÷5dÃ"òž•wª7÷Š£ž;óÑPeMÒæ=)”–× úüšî&Žƒ9&,³#!>òªLÓÆ©Ýmà54Û¯R)óùqæ JžCéUpáJ=+'¤ö˜Rù]éå}ôò“J++Ö5ÝÌ|§cÔqߦ„ý+kŽe¨Êhú³_(eäñKõäÙþåj‚̇VûC@™+“‚(?ùǪ ";£b–š¼.C|«Æo1»ÅäæÕ, ŽVVùL®é÷â[7Ù´ÃôøKµ?eûüðĬ5&ŠzÌÓôQZ†O||£íCê¶ Ìc8ÓxÚºû¾«µF*°*¼ñ$ A)F.9­‹¶-C³»ë¶\öf_N3ò|†yÕ™†7./Ú8›‰é]àN+êÿe_Ðr«µ“6±Çìã×î RÏ/£¯É æ˜_ã[sÚ2R‚‚~¼%ç²Üz£ÏÜx›ÁV°ôbŸºOöÖ,‹¥5Øyé;J·¦Sã±à¿Ž©u–d¼^6‡i¡5ÔJ;@ \ú#uãÈãs?sýº&³œ´Äù˜iÞifF—RBW=»œÙ ,¥¢¬dwêߥùö'zën€Õ†èSQ3à:WáùR{~/ìáÉhºO^U)¬£!êðdÀuý¸ýL vÖèJ_!H˜ªË “-ªhÎÝ hV’œÏ[£v0‰6åŠ9{ˆ³•–%ë%*]0++c·ŸÐ.e߆–äWïMà óÓL*kß+輘¸ò0ó³šDÁ蟪ÃàÞæñ`V„9jLûbº+'¤Of8ªõŒ Û_äÂ^ … [¯+“»D}%É‹ W’܈÷^âr›_:y²7Ö<ìD.:¶—¹RïqîÂT䯱cYÎ @q?ÿÎév/h4q·Ø]BM>¸©ðöäóëcå~Ò ³ˆ¼‡C¯/¤ˆ]܆šVå-Ùrªæç|÷Ø4¢_šœüØU7¿ÂåS‡xÛ ioªOs¢©X~™ø¼ï‹Iö5ƒ5÷´…€mOj½ ò¸Äè0øJþ9Š&«BBÀo Tâ­KÑe=d—¿Êq¿g9p½`1F+§ÓåÒî(\±D:jÞcÑݨѤӼÁ¹(竵ý6‘ãKãG´&›MŽùEünöx –csä„"»ì×SVgêè?Òú"¯_‚„àŽŠ\±bæXßj¯ø–µR&y¬™+0² põ}²ÿLšŠZÁ'ÞîyËb»m“ÆÔºµÿ8^‡ò=U›)y/Ü$¹½ÜÏ#×¥oج«j÷Ð=…ñSûŠ‹©nbÆ9ûv8ÑR¦V²¼Ýúœ8)#œäö¾‹Êv“ª}M4…´6o$Ìd8IY2ó3|Ì)¾55\å¶Öæ…'njЉMX±Q,}á"F@%¯Z4y:ù±¦ñnÑ‹x´%QÔ~‹ŒÒwøÐäIX¢ÿtCå¼ÅógþÒ¢Pðzõ!Þã“^·N÷²œyfŸš]‘»?+:6E‘–¤1ÍRv.Åò©ç§QÊ»ŠoÐ9HºÆTe"g§‡¬‘”$Ÿ, ß\~CPõ4ƒÓ<©¯'AÜŸ‹¦Èâ\¤æìònx¤¾?ýóQÄÇåwªgì= ™¤ƒ[/·w!ºNÚ€4s~N³µ†Ïïj®ðòUoÞåTÂmlA¦?)¿;ÚKrÏq§x+U’¹éÄ›¢®øCú¦Em‡"Ú§Æ÷+åêö;K -†7ÓSijù ï²ÎÌëÓi£èÎâ’<º;ê`>"é£ èQ¢ñò~lùxï(èq%QµO9.2ú=$ß¹s-I#ÝÑ=ŽM½ëœ÷=úŸþ~í¢ä*ÜCS½NoÖÏÿ1òt+±]•P\Ø,µÍš>ÖŠ»7õKS,)ªpafšŠ>Ú:鿥ÜóÆU5‰€ÜO¸ëÔ"ÝíÁéP5cÒŒzث”|q¨˜.#$ŸÑ“ õ»¶¥ LPÐàÛýˆXÙÊ Ô'õ¨›£21ém†cïbf³I÷Uq@äñ–¼eáÏ'ŽCÙÌšF&Aý¬½úŠä{‹F_³øÜ™y¡/VUÕM7-ëZ3nÂ}ªöMü½üHÖzÚC4¶h_•T;3ãt7÷¡°ü ôŽ9AaØ+l¤zÞ\DWªÒ’B@LÇʽæs N¿|aÍÛtfŽ oZ¶©S´ãÃ’mÀ€rÂ]XŽÃë©v_‹ˆ\¢–‹­ä®<Êgä†ÔØ@|€”çü¦Þñ¶Í­ÌÑLÔ ½o“Œ]ïU©Ñ›CK;›^&¾^(⸅'ˆÒ™ƒ0Àìës‚ºbÚ׸Ã;jXqªëØ¥ÈD×[nÑðq(l6òÓü.|‹ÖsÆ/eðV;n‘4xŽ“èÃÕÊ:IÑ5á)ÅÇÎkÛ͹’‹ËÊòá5OòM³á,ÏùÆ Ü¬Å5Ÿ¹%ɺÞÓ^{½¶5o¢Ã 9d}O€ ³ÚãÈô-ÙPó® î¶Ó)yÂdäx9Ì|´õÔÐ\¹-(¶ëK¼i £PªJVÁÄ„ÖÇù¹ÒŽö5âIÈ×PzU/A|rZ݉8ôcH&}}× Êʹ ¯ìë®Nt[Œ¦.–‹ÏÑzáåº"ÉœDiª_qPØÕm¾L¤Õá _´åH¡5z½‘í‘(¯ ©¶8a×-`ˆ²¥d4öd¹M½÷§‡’‡wàƒ»wb8»$œ*56‹Û,{BÞÞ~Ùáû%[«T0a%!èã ÂÒø(=ÂjhèjU›gQèŽÆVp¥8/9ëù~d4!‡eœñÌËz|¬44^<‚debø:±Ö½uˆÈêao`[`<®+g,iº}N¯œ¬áyˆ9üïY}ò^Í.'Œã¬6ÀˆVŒÕÿøÝ1”B³ >g]nî’fB’½‡P/ÔÖŒ„7­%õ¥{߃ˆP:õéá@̘5Á#ׯÝâyß nijÈb(‰¶¢ëšÈŠ#Íjé¶×>¨¡ûFÀ1Ì6Ä vN¼ãñÊV8~\l%Äéï-ÞhVÃúÉC/_¬…JЩÙQåx*tæ£VŸp1E™IðE½“`ã#¥(æÁ÷WОÓ#6ˆÝKBøÉƨ7h{µtúNu‘ŽwSI°wj‡Ñ½·‡™Í"îi8˜ÂpYÄ1—+ss¾¶­ååÓ§îHmÕçˆ5Ÿzõ±Îèñ¯ç› (i¾àpð2ÇèP¾Ñåx¬ô\^žöÛ'oãRiqÂÈ÷|jH0NµÆT9š>7„H”j ’‰·peçV äö}܉.Âa‘¾ñ‚ kÇxÆ!O½êîP®ößD¾Ž‚ ªšË0Ô˜DwÐç—âm€h îDHršµ|¯ä¨[Ç% ¨ÜÃ8h6å6—µÕ)ÖÜM$öHˆ÷>åúÑ}ˆ@Ó䢠ÖÇk3TÊ=Ý99,ü¶°ºWeiwÕB‘ËV†:E×Õ«”Ê ÅÞ‰°âÏ]ÅÔ‚”Cܼµ£ÃÓi;Siv¯Œ{6Çè¶ôYRNĘÐÒ§"ª¿ñ:OÓ^ ´˜ûlíÀÍ %WJ[ƒGÖ•öc¯HÛžIR{ûÔæÔêQ‡jŸu6ÎL;D¹ÍøKÙÆ¡UdCæªcðY÷ ½†’,-.‹Ô>_:ou†ÁV”ç­ !yf‡ýµ`Gq¥Ô–HÐ.Ÿ„—ñ,üª®bÍüdŸMP‘7*NSn´{éøJ†å—`„º õŒ1„–K#=02!Ý¢×ÔȺa¬л^?Ó^%A'jÌÞ'_ÄðÆA㇪f 2^de“(“ݾKóé+Š 3&½ÁxC×X%‹±Oô¦|w*kwå 7Kµ¸EuÐoõ[Ò·ÑÅH$ªÆ*YæR(8¡"|jõ} Ð-™ˆ#œÞÌ”¾Xõ&‚_CÝb2cY1ú É×ìšñ QÕy¤FßË”ñvCwîDa.ê È{y1Q%Aû៕;%° mÌ<ú›‰„ó˜âK%ƶ¸·°ºá¼¹ ±wb:ný+j¿ȄP,$¸ìnGýÆùîžê15²f’¬¯¦6'Áp’WîÓ`!݃¸Ž "ñ¸¥°,…£žÌ¸9×(»rà à$ˆÕ¿°‹»J¯0JE˜ 9Š _Òê¤äS€_"ßK†n%þ—ܳ†’)+$~8#Öa¬f××qš‚1mj÷xDï¡U.h%f‚ìF%G?5.·ÚÍÛ¶Õ#èxñ·j¨€ð3}Ú{MvÛѱØEg †¨,¤Ïë}`…li”šxŽ0Uv+ÝÈ&“ù^ÿX`çHvá=ÀIó­kºEí³[²HÂršã’·™¢½µÅÓ¿ø9'¼ä•Zï~RÓ\¼g®ÎØ2Ûøy(j5mWL«o(: gÒü$ËÙ³2¢TñüaœƒàïQŸyÿ'kuôNÏZÚ¿»³„rûLߘ'ù^VÜC°3¶Ü«Õ©¤ÏE—N J,*ùÕÞþb²Þù¤R‰ïùz¾{#V E î,Ý-ÔCXI¦ˆý ÕHo)åý¶ À×DCKêÙ¹š–Ñ:€ÏÓ?ÆŒ]U˜M¿â­·feWže<2 ß~µ$º©Äw ý¾{Vž²GŠbí7#ïïs(~Vä¸dõº'J)¯ è Ð6 ƒÅt5“A±pðÞöÕâÈ|Ô©9¤èúi¤ÊYÕÈ„”NèS6G¦ÓžzekÕÂ{ˆ—œ²ªèÖ0]ñ~‡)ë%½e™é®øAy¸AfG&ç/— ãæñgóTÓÞÒ–j» Exa¤²Î£­Bˆ$S ÉÛ•KÏ” Ò²7 ób ´Õ8˜¼èŒ¬¶µS‚îüg¸ ´‘{q˜öäù‚à*´·Øïò ¡7â(ÇxÒ%¢{MV!²Ìãµås†ß^ÕXqççÕVªFúZw±½^kÆ1nðmÍmõ9#`bWmùLüË­XåiŠ3.Zâ^ÕùsÈeŸA #Ìò%» å¬Mª§v ‰ÆÁë†à‚ug”€¤Ñ°§ñ¬ ~‰!Þ~½+>UÝU†ÜÝ 9ö0ˆšöžÃ­ü™ò;qµ39Ü“ú#Bœ§i¿):öBÒÔýz"•ô~D¶‘×?úà²&Ô=H?Û¶ŽD‘YÁÁ®`ûéï}å<ûuÓT¼Ãžµ ZCp'Þdo^ZÞi¸Ž¡ a6´ê òˆËÊ.nÝ7¯ÔhËcј™ŒUÃUìfœÊ¶Ÿc&Û©J¸„#>Eª(·c#Ã’އï tP^w瘈k¨xTª³žÒ®]Mo*ee’þ0G¢ÏûY(ÙööxüÔ!ÈB˜A¾oZPliŽû…ƒˆt¬¿Ž¨Ôínyü¢æŠ!¯£§G@Díh`êâ MOЛrƃ[ó&Û_ -S‰~•ØáÇ+hp¼$Sqý[ÇB»•õ'«Š¥i*x~AÈól$76;&Ö$¶RÔ?½3ޗܹÚì‡×Ôvl'ðÿ$}<:Y6Daù½k‹Ð‰F[¬'÷Öö;öv¶ÀBe¨ó‰ð…m£"ð št4mªrÎ^!fú”™#ù¬‘ÐøäII °j®+ ¤ì $=‘›I›É@ׯ§q?ðÜœíäÏEਣ^çg»R ÁxÃRMSþÄzá9WjK}ž3¹«éž>³ÇéõîÖ}™á¬?—úçšXh¡G9•é‘ì}뼑œóAñ¾çåÁÜ |6]–£rYDC’ÔÞ6ZS Yr~VîVƒÓ íMó{Ž Îêµãœ)Ëg½Uí1—„˜ Ù긗7aAeñýZj“@æÂŸÓ6Le˜¶j^/~s\öu1BsžYõ]ŽÓ8 Ôç´»›’ïÚ6Ϥ¾>ãE9߃ú2Wr¨œçwøë1õyÃ…ÉtŽ]™1Š£Åé]ºžÁïöÐÂ0ÇW­?•£µ¦•<ó ¨‹,Äí /›bçyÈGw52MOaQv|°ÆÐ1ù÷/Ü ÈQì~”(qr눞ŒßSgÆL³šH÷ÖJ3À¾Ø.ëq +W‡f \ø†¬+·‹{¼ ùBâM•Ø›Y)hÂ0]Þ¸<”5Xy¥¿êÔ/iÃg¬Å­HÀæ®ð±áî*Ù …êY*0åšo<9Zq³Ùëyˆ÷fTZ ]×ñy¤åÍú6ïPòºj¿&·–Ñxí"va’ .DS:1š¹G`o ЉHS¯9û*ÙÂ/î)µW=_'ßzw' ÁnONykí*6Â?l  »«éôX‰’àzáõ§­£}`rÔh!³[ñ‘zL’8´ Z,,7ì3ã³!àuä$OÔp¡L¿«›ÞëkÅ »ªôšx&zyŽÕaÓÄ« QˆjØ®>`æ”ÚæP¾S¥i¦í2IìèÙõBNóж3~iÊ{ðòr~º7(ÞdAˆ«>ÄÁ™ǯᯙ¢ç.0îfå÷–ª”0ä:ÍÐ2PxPÔy÷Am€„ã%K’²Ù‹eݨ[oºwö²Ï>÷™˜ûb]}®„o)ÑV0³ÝK{ÞFÇíõÞ$·7R­Q6>Íz&ƒRÿSÏ­¤ÑI4ÙH©P¥dÉÔW-GIfK©iÞçCSz;Á²åoÊL–Iy¨Ç/•u¥lšÔ[!0çá=ÄcÆY®NÆ=ʱ§ÄŸhm,9õ³ð(i•ZßQ?¯æ¤!bÑ6sx^îæª«ì7æDÜe¿ê•Ä¢} ëgûˆG¼”H›<Lü}1{I.rhòô$o®ZîªÇD—iëx{b*F„âNו‡Û"õJF/ \‡l¬^CÊzÀ“¾¡¿ÀºÄ ½Õ.p~kñª£ÒU4ÑGá ™3;í:ìà4ÖH‘Äüœ-›¬kJº†.LXnCF"”Ÿ‡¾›®BÑ”W_vœâºx¦]5Â…{(ÜSg9È[:(tÝ:¾ …æ÷YÞ­Ð$×è±>{«kõŸâd/éíS*"§IÐâ·IcPðw3˜O^u‘VUH ¬zøöë ˜s«Rø œˆ‚=bžd“GÁð…v=5KÞÉàŸ^.øwßP-Þ´,Dí[7Nå·jÇ?Z¼ØU”$çôÚïèrž`ôÇ…¶ìÄA–Ô¯Ã|´f!¼ö;*}ÏRØ<£º;ÉQ9»ÊˆtÊO[¥‘ÇZO8%Lƒ–e]ï°­‰RÛö?iG¦'œ¾ÂóÒÏJ!‚…4–‘ˆxéÅ7­COj´¤æ^‚ò]ôºSj_ëœMYÄŃo¥m|ž  c¾¸^¶‡r®&±÷GÆé{¢xw"~8”ÕÓŒ¬Ÿ3>5ë‘T×v>`ÅicË‘;¾'ýœñ .;Òà*ú3=Gl ŸÚ§©…(1.\”8Wè‚:ƒ"O(GÛXl†¤ƒP*Ž-o`G-ª‚  ˆGãYmô;P.Û¦†×ËeuŽd²P½Rxqµ~– mIZr>‹â ™7n%F ŒÚñÊ‘»Œ»†&.çù|ì_OáØ+™ ÿRë¯èôÈ‘(ñ]f?Ãvc¬«ùó)¬ý·Ìâ—%O\HÚÚ¬zT¸;’²@ Ëþe%À•žJòâYD ßÇcží!ÕZæ)«ñjnÅ3“£6øß—âRØEu{Ùµ„ÎàãÙ¶Ä ¿5¤ùÜþûÓI¯ö™ª>¿¬ãUëpââÝgžÏˆŸ{ôaÝv&õ(”îk¢ÜZj©q¨†§4×ßÅl4¬c6Ú¥±”)™0hD\[ÜúÍ‹©ù ¯ïÖìµÊ£> AŠ1ä]”Ûc*K·‡1¦§ˆÔ<©/K»Ÿ¿k–0‡íÐk`s ž ûa%`G78óÑŠi¾“üA½<$ÿl©Èð¹kŽ¢ö.yZœ vmâ´ûakZo†ŸÜzέQ£¾$Ôä¼P¨“¼ðàEßu¦Ä߯W´|ø¼èÚÖU©[+@jV‚ûª¿“æ´5OWu8É)ì‘eiNó¾^Zíî,jöjº >_1£'Óm¬µžÖÕíóŠ‘Â›º²µOT1Ù¯§je×Ô¦1°¥ÀP'· É”j ²…¯ŽŸWHJC£uûÌ †x3­}þ‰ÐÔMEíÁË·µ Û牕; pÁleÕ.í”æ”-qNµud}¥f~êñuHoNßø·`Æóã&h0[:(5•mðéYÌ÷}ñæ7Éñˆq§P†x0½ˆ±– ²i×f Ìs F%ѬttízÔh £3óŸê{1vBkpôáL&ΗGn“ÞþAawz þèR°Àg{ ê¯xoH%gå‚ÍùfY¨)änÅÎÜ»“Oÿ´‡Ô“NââSé¨6)9H ŸÝ¦¸"È«‡à÷‘6óóoÏ^âkdL9 â!^-Ÿü¡0IH.¸aŽ‘ü#Õœy³Ü ˆ&=¶Ué6*D¸‹þAihW±r%ÛòÑAbîFj01;—€XÇŒó£=ôŠýª£ ¿¹ñ{8‘VJâºO’©C·ëu!Ó/§°²“½½4äÌ !‰?º„þ ~´ÿÚ•:^ádgyòñÑѧ»üÊTFWÃø$zè1³šò–&–$rß0yì}éjfs+cÝè,*{ú .¢ÏxЮrÚtº˜Œ@í(Ri&,³à5R‡®8QAõª­Ø×HdX.Ã3-Â`d`×cI<‚€(Ïý÷érPë[t˜W~®ÇŠY Mè[Òä]n)81gsÜ:#î„Ò¶á ºÈ1™›k2Xë¡BÇ¥Q‹’µWú[sž¹½V›«_cäsÝ‹,Љ˜I½•Ãsn'ø°Fòˆ‹è_£—Us¡yõªáb•©}1s1dŒ Yþz¸Ï¸ûñ¤¬´}ΉúŤÞå}HÏâ[Ôß3iF¢²M© Ó£ËecJÖ–°ï}-GÝhƒ%}+Á‹§ÊÍGvÌÊmíz [w••±c¤M­J–ïƒÜ>)2<ïv]€kÀðæ$c8ù†÷AŽ}ˆô“ú+«;Ùk–åùmS%Š\Rüû:ú’ç(;Ʀé/a>ÁO±n˜ku,oGÑe3ïL˜ïšßÐ7Š6–y¿f9o‡ØJÊÒ)/¡©>Q¤%‘ú©z1ú¹ã`¿¾ÈÂ¥8Uì­ï–0’ªP&d•ÀP#Ûñ ´aÔ]IçøÉTîº7¼šüŒ…Hå>xÑ@å6ã+Y¢÷a|ðMãØ¸4Pz ^*u3ØâÛr¬ž‡²µtž$ý†ïêd©ú»90–H$´ü=•ŒbÊŒ§¬»x½ ÞïŸRÂʺ3ó~™šacG¯ÌmŒq€G…Í&&*S¦Ü…ݨl>çÇËôºBeÚà<°­ÇȰ"Ï(CÕë¶âÙ/Ý ¶Aåé#,êȹI§5y…½Ÿhuv·¸ƒLu¡ƒæÖj_”þ¹0âª*ASø³sÝDD»éK)µÃ&$ÞUÊ9­mOB_‡Œ"ï×7æ,}ÒŸ>ü¼6 V1ˆŽ2ßYII^ØÜÐê ,È;HN¸›Z¤PÇ`X–Æiv‡&» £?-wíê•í Í5 Üy¶ø!»RùçC0}2óômÜMqêù7µéÐÔ°Îýïçe1§c˽º¾²Pí0Ïà+×ðÄžðǦ±*¯±6ôM³@Íšz÷|;Ì¡àOÅ­££!¾¶NütK:Þ°äIš”èU̳ ZÓÖv[U»²äó»(ë߆³ÉʹSµN!IH}#|ZƒcÿÉKÐ˯p)| -ÛhiDh@;¹Ëys¥)éÒ‡‘ü|⸥„¾×²ª3t㘧ÒPïÖ#mÌÀæ´?ðjŸK aŸ(Ó®SÇÇXÚŸ‹@µÀ¸´ÓâƒØû4¥›þYàÎmž§1¦ä3ƒ†.|¥KÛ›Þ̪†3ðiɺÄVó©&´?€þš\‹™Ë_ÐG¸LJ;¤N__ž¼žé„ÒK¦6ÂrŒÅNtЪ°æ¤ b,_=Câ<\>î«ošcá*%ZlíP‹¢öe*%ÅÊ]äƒ5yaÆZ~ý7:vå=¤ÐO7)9r I’îjCî»ý݇Ov°ãA#uòè_PËÞ¬ADÒªàtU8Z· 8¶I K¡±¬+LE“[t˜3vàìH·sÚTøD~·0/ö‡ŠTÑ}§$ði)„°å§ü"ÎZCåÁ«š­Ûd¾Ê!¹ÒñÐR˜Ó˱°ÀYMÛÃܸ}”‚ÐFRþ·JAZ–½ÔQ£öæx…l£s5âçz¤K,ÎîŒ÷ LK)ß„ÑÙgX`Â|ßÂ{Ñ“FöêCÙÛˆ¶{ó}Ž¢qK¿öR€C’ÿ˜,’½v²‰XA·œ‡‡7‡rƒWOß ¬“”¶\ëÍL`>!¦BfÌ ¶K–¢”kuÓáèÒÙÎ&0ÙÅ*MÓV<ò˜ß gÇݦ‚e2Ü$ÑzñÒ¥& ñ ß­LF¢Ó7é@Ö®J©2aÊw4bšÀ¯Ê6“½UD$íï><.¢aGyÈeÚÝlÄÀ'Ã#Cû&f×iŽ5t¼!!(οÈeÑÏ·"uÂx5ˆÚ΢ž lŠwÀ™ÉY«6KO¬qËI̱F^¬YÅÄÔyã˧DØaðÚw70¬“ƒD/ŸÊ¯´S$EH£wÉ´éËXáÎŽŒWÏÑrNäAM¢ÓYCžÂµs>®Yq&©2Ö±°‘QÙ+~í'¬³2¿[¿Ã0"ªQ…qâÁ1cY{Šºú¼î’H„Ÿ [„Èéz V5kƒ¯S4N(=ÍÓ¸D;ÌåeFá@[ØéŠÕnk“ßq 4>¦¾›ô-6¾ø:Ÿ|—)Ãé¾å|Þ„ÛBxŒ'µ®<0Ò¤ÚyC¨ß¿n7ÍC{çJó:»ºr¦P;úÑ{+’ƒ }jmx'ÖÏ#™àMb•ÚÕÙÄ%üìð]žóçÝÆaæ=³L´HH`©§õ²ÿØé¢d¯¤~¥©ÀÞûó†êÖ¯©ÒËÎXº‡¥V§SW÷D 3ø!Ä9£ŽÅÅÔ]Qz~hß_ÜöŸ®Èºlb]To€å!m" ÒZ&¾W’µÎ:‘Õ|½÷ôðe2‰¬€G© 2:©á:Fð8YHL#Çš”e·M—zǰĦ]§0`„ Í4z6 ï†B£cúµ•õu«ÆK™ŸÿµÙ¼rÝà‚r‚»µ•øFV¯" síBbEmyµ›¾6ù,ÎFþ¾Â¤˜‹†N5¢œ¿¾aêmìûå ŸúqÛ)£D¤Þú澕þ„²Ð®—ˤ‘)Ðà²>•:oW>ô ¬c®:B¾<³W­Úo¸{Q7H_¶’[)Ê4n"45qlù^«ó  9¶«_)R¢á>ËYÛãk‰í˜¯"$ŽNÑÑÁênª6Æø­j A27™}ÑŽ>ðoùòcÃåÑWò“=<36žqÉ}«O¶²ë°G791ûߪâÌ>¶R(©AÂÐaÖ­éè,•GMöâBO«Œ/fÐý î1“2¾Áüæ¹O…BÒ»P×NˆŠ;wSJMéÆCk6.³4"üG‹òËü9õ¢!BÎ-t i;MÂðŠ{»£ÜâŸç´“ìB˜ÛÆè¼ÇÓ@GñÇyɸ“oÂ=×oË~"ÌCòãé'¿øFjÑØÞ^dÄð5®´w.BÚßÉ0J6!´Þ^«ýqsf/V Yð.xÃÑA]5öÀ‡ %£·a†5Ía¸­··Ç…ù4qcÓBAÂÒ*[STÆ>s€í•þc;»TÕ uÛ £A4l1%fe²6'lõ. ö-ñt„’i€l œr½ÍnßÝ7Œ;÷Ë}ÕÈPñ<))Á/+AsâˆlfV«æ¾ ¯Ö¤ úJ ~&,²ù¾’|¸§ƒµ[ÈË" À§Éæ˜-ÀXEKvö!v´á% 7º±¬É^¡?o®”‘h1êÕðšuŒ¡Æ¼ÈÉT`iåI òZÅkN˜bÚ©O.}a& Dhô#ŽmâÜ«•kšwïÝ×\äöiv8ø‘¾Ó-¶lì°¼>øù‚)$…ÐMŽv»žêÔdo}k:Źv( …€b8¡XR–ÂØ 0ø0ò“{Š"ã*)n=A‚MðžÄõÿ[ÔÛôЊä]èMs(àclÙCÙša0,ëàé­ó„Ëo&…•Ùlv¨¼˵mþ)l·P>Û IS Mµ: ³õ.zì)Œ}7£¦½îŽ×Xö–Ï^>l0’s±á{1ÉPsüiùû$¸×GC.Z©LÐ*t3¥Ûµ¯¯eÅîŽëÔ±ežöXòãrB“bŠñ©xQÒ!º™ÇáÇÏ|Z!Áüƒ¶ájk Œ‘Vª´ ÄÌ$2uµÌ´6k [ã¹ Ü'“tºÂÓeï+qi!ù˜º¬B¼a[?¯ë‚ÆIÐÌh¹ºö=DþWAçp”os¥þ»Û7^ ¥ä°Ð/ÿ÷¿*t¸Cêšï?Þ1ÜÅ“úÂîØew[jå¶}’áÐå¾¼êÍì¶½ˆ™ÙtÁWŒ¦œQŠ(ŠÃrÑ‘u’Á†q!¾QøBóAÉŸ^’¸„6‚Œ`Ú¬7µE7*·/ïÓ¶;íGÎlS±¶3ÑÒe-Ü)²dé®~?¤×¹Þʬ=#Ãô“|¸QN1*¾ûÝÍx‡+Œ"¶)Ñ™þyñÝù`ìgç³·ÊIÒråØå©ê‡ÀºO¡ë°h¹Ùm¶ÿO›ö°]‰¢(P4¶mŸØ¶mÛ¶mÛ¶mîØ¶*ªpÇvRq^÷5îO¬ÆËÂVq™+„G1ÛdWbNUò¯o‰Cƒ¯`#í'Þ²¸·$©cm2öBƒD’¯BÚ)9;ˆ|¹iϾ'Z=®XƒQ|åºßÊê9|ƒ C¬ ‹E[&*#£;’ƒ£\ÄèN:o q Òã—™2<É;rð¼ž>BɌв¶NåLÌ_Ç'4À÷}Ù ¨À±S¯ÿ¬,ä«<ñ¯Ë?âU à uÎ: ¹•†¯|LwSó’o?ùˆžjg„€þÞäù›ÿ¡úýªvSdʾ)Œù©g%gj OX[‚H¶,q/â.­êÒ$Ô1^ÐÏ€¾ì ÎÙϪ‰WÌep«£­¼yÆ~û‡ÀQfï7ðHið5Îk=_ý­tk@\ûwcWãf¸#䪜¹7%¯uWˆT@ ©rF¹*Þg p:‘ñm{}7 È}ƒ6«ãœŸÒ±6»†j4ÄCNþޏ‰¨Ü‘tH²vԌ̨®GŸ-€÷Ž)"·ÌcE|š­Ñq$Yóx;$±zTž‚úÖÞ ªø¨á>wq>ÅØ—)°¨a¼@¹c4—îPÕŽî—Ëý;æÃ¡Û4ZÿÍ„ 9êx+&‰¼ˆôi6b†ÝãDß»›Ç‘ÏÝD YøÌ_ô¢ïp'…¨ý÷ÚæÊÞϪ魔öMwì3k€p¸ÐÄqµ[ÔcBiy/þh€n诓ÖÑg§îháÀjvs)h³‚Vj”Þc+;¾žå.O/ôˆ$:,ñÃÕú±ÚNW„¿þ[ÿKŒT£h—œƒ>Ô7^/waŒ•,¹\Ž˜Ñø²ÍoÁ¼-ÐÉü$á ªÞ³RGë!Î~æ{¢·Ù¹ýA\*Ò¤’ñ—œ¹ô¹("+æ ™5æ@þËTjþ(œžcû9ªg•”$™Ô%©µ¨ÜIÔvmô¬ô¹÷KßÖou]:ѧGOÀÁ»Ú¤¶çÒŒß`¿¬v&•V‘ÎóR§šëÊCjö^C§-åÃ9™íàe:ñŸlôøIˆåü×ýa2ÿÿç(;±‰ “ ´ßœ@Y‹äv/@üxàÅ :šÁ° VÚRPõf(eÊMÝ¼Æ Píò Jù‰nUÃÎ禓f=螺ÛÏáßCòSUÕÃKfas­ÉŸ@(é”khlÞÌæéÇz³ºˆó¢]£ÝÍBìë”îØ 8‰ì~šÿtó¸´<óhÄwð3i®Rë_×0jT¸Ï9rœÎ?Lê¦-"Û‰¥þ–ìNaãm±.Lrm:Š|Î`wÝ=O°ŽÐÒ<»Ü?"Öþ IT¢‰†—\Xî¢*[ú9æ%ÿ in~ƒÎäŠi¨¢ÐFeK|ï¡— _*΂wf˜‚ßö›Ƭâþ×ßÃc%÷$ÓQÞ!ß–/Ár]—úcªó­¸’G KI—âÜ颉nËt.-Ϊ¢ÅÞ6Z£M“-€ )0Üò#`ÔGh¯u´Íë†\¹=¦Q%¡~FŸez©Ñ]/JÈÝ|¾ÿÄÉ_Ø™ú$Bä©9A+ D>:w¥ÂçÝÛäÒÖ³ÁçùzO}|˜S}@4p¿Š 'FFÏkñ€¯ûE¼¹fÁsûž=ag×V!Ì)—ØÖA‚|‰ž¾äºyÏ/b߯áï-oL U2c:ÙÆì9 ·ÛÎ(ãkXTv,ªi AXEÅ¿„ñ™=_‡`„c'\¿ö·'TIïùo"im¦ÞÇÂWñ.Ÿ¹ngõJ³Ðq-Uºíÿ]Â6D„(»«a,¸\Ù‘eZ3dejjÛŽQ±ð°dHÏzJÝŽi#C´¶Ãô_&`Ëoè$Û‘RàP­ ÉÅÇØìq|â|±¹,J»¤Ï¡Y~Ç8IAÛ‡5 !ÿ@h©oŽ$ eFÜꆞ&§”xÿ«â™ €·¨8=Œ;_ØLsÅ{yÙ\NßÁ~B I8¯÷”Nz9ªW†‚g \™ö—"'çë†øˆv{£êa¦Ò²„¥ïönr_Ô„Ž‚@‚Ð+ õl^ פʶÂB=+:Š‘ö¢íü ¹€=Ûª@Œl§K%YÚ¢±6{6õÙ,Ñ,#2éÓ²›‹Y‹“È–Bâieï D.7û×+‘J<†¬ªß§Š‘~(挔;³¢rJµ,Eë³êjáeQ=ž.IEi¬d9÷©¿¨k!! üòóüϪ¥*•!ÆéägMcySnÍp¤sOvøá.g´þ´MY4û]¥ÓëÎ6" oA9"šÕÞgd‰IŒ…ðPÛ²O*LâÞŸØïúíiÄkS¨ýf­u1eÆ{þ±gi‹Çw8 \ æ±$¾;ÆeZ†¶ü‹Ð#ÁÀ`OþÿªR寽Èêë+¿!SÚÐãq†Á÷8©Ž|T4 Þ~’(â[ÉcÏr_.vlœ#ÅUÚš|‰w_}빑wñ8äßÙ=û8Ç`ÎXGæ‰kDÛb>P(Ùhd˜çG:p†CÚ[>²ßFˆ] Jq›P9û7×ÁçbäƒÃ®šürF+[ ¾èðhí†~+Ÿ>ܺw€†é ©çR]:Çè:%ñÍѲ¸%ºƒí˜8à ÎaŸ( êÂòêJ±>à(/ä$àܯuÃdZlV,8Nùn©¿ WQ¶¥2¿+gÊ·Š×"˜+úíEyí2ø;[EÒwšÈá`8¡?.oÍdc€WWw§²Òžífª-ÌÆcÃz©Î“/_Šò”èfy‚­Äj©W»AöÌ/u¿Ù)'™cxdù7"x.Wš‚Òkâúèþ“ ˆ‰›s×|RF4!æÝ4í_¿Ñ!Œ-B=#AZ»dË5õå 4´SÕÈÚA%íº‚Ñ« @këxhʰ˜«*3`»ƒÓ‘r#ˆ1ÓCõ’SxòC±‚ $BG ‰$ dìì*éÞ̯k¢êWüDÉ‹[Ñ^žH‡Êë/Ø„°üyÍIë°¡ß’÷†ï4„dx+\Ø]¿ë™åã‰\Ç q$6ëÑÒFùç”æËzl#vá¨5yzÍôºJýÞHûF¿e¡Ïà!¯JË·,Ÿ%æ[»< lìUMnij"&Φ÷-BzÅÕ»´BÒwÓ–k‘î'™;çÙLÉÙk4º‰Ò˜êgÊëq<ˆÔ¹ `ߎzðÞ ÐÑÏýµÝ: Ù;L—2î·ÒJÃVÚMÚ‹ä Fç¸äFpóg‡3øâ@LeëÁ*÷§QYº ˆÓJ¶ü’•ülùÂp—«G™ƒ ¨MÎéàDºKÅì_ ÞsMoˆë äz¢ÿpMÊ#Y~Õ`l†=%>£5qaŸZqv2v»ªV ƒ¹|Îmí×v\%ó&]ƒâÞà¡Ñ&rÎ+ 3; œ@{D”àc£L,F2Ä"çÒm•!&}˜ &ïæ Cè»ÿ¹òÜÞC„ò³El8º[„Õ-‰ºbµŸ² "ÐÍ´õj»ùrgú,A¯$E£0ï[ë ñYU€‘FÆ#(qbdJRÿn,ÅØÀh+IÚå¾âí9ºÓü$PAûoöТÔ÷T{m"ž©„fŒF' „χ¦ã_‘F8H/¨1£½9*=þÈ1 `SÉÕÖJˆX?èsu>Š‚ vìpËӨ¶]Lµ…DÒ jÉ|ˆSª#v3Ñyõ¥ÉÛƒ›±•6@“®½9(ýFž÷¼ý†Æn»dØ8¦|òË-ãG8'Dì@×±'›At. ½ær#5W§eç0+þ!„^‘T}€nëÿ¶¢ØéŽWq+R8#Ã}TÈ îWÓÛŸ€kÚhÆÝ£r›ú‹ÜsÍ&°>W老eÈ´×_ ÃÜí¬/èH»ñ«»q Û©íEOë-·f2sŽ K€ÜÄœ‚6+R:Ïø*õ<.Â5ÝFȤ-eß¿øÞ]²-ÙÆ“4[e¢×ix I[-~íñ˜†y®jc*±ÈÖ ›Å½÷ãƒ×—:ÕHýµé¬!"à‚ÞC’OZTgɼwä¯6´‡YÜRöƒ¢—Éšú' \öî\ŸM*¨™ƒ#_ÛDZ|Ÿa•_)‚™ùÕmÉ[ÛäÛpj&RÃ&“×s³’X½É«iûŠn¯µž3ÎØ^ŸË\¥W£€çs o¹öeƒÿtIk±I~áv:ó‹B¹t½­0Ea”ß…wߢµG*7¥¢= ˆQ5PéJ ÈIvKuÂÙ/c6‘nm8ò½õ†rïP±’p}ªat)qª,º¬¾FãØ/êsJrïÕÕh+GÃô¡Oy5MË®=Åñe¶³6ÄoÆ^ ꢹL&‘Sà¢/ÁÚߨ÷kdp–ÃÚI>gß›ý 9ïHb¢r$›‚åó¤ÉWw¦þ ‡à{>‚I»DWõ|µæQiÁþi t>ñsÙß.jøy6$ɆŽ&ECÒýz̦kRË|ÌÑN'²º–·êÇæµo´[§ÔV³ÁªÏWNóµsl0jV(©ø¤ýs(™l*˜c5ÏÏÖ ØÙ“®CÒ±¶NþišñêxŸ;½Ë‹9ò!ëžß! НS>Vט¸qÇï‹òt\xùÈ75âòúi˜‰‚.ŒÃŠø£Ñ²GÈŠaÀsö]ÿÒ¹ðœñ  DiGÛ‘kÎÜÓ1¥eTMݾÚ ®_y0ë’­ôšJwß~б¶“½©{ø"s×·MC«¬K¡X5¾N8áÇraœ- že sÀœ8µÜT]ÖÜ÷òÿ³ãGûFs…Òâ_QD¬4ïå#/²·E…â>»ãPótË‹Ã<'êAEÆÆG³Deˆò®1 ƒ´¬n;¯È`ÙiCgªJ2•ÙÒÜðÛr|C—c¨Ï¥ì-ÑßßB^m¨;¨»ê@4ÅÀi_6¥‡¿Ýåæ› ˾cÞ6Fg{­ÔøÒôø¸u€Ì×'"! À»Bq‡³ô’þåy¹¼£/‰“Bš8JPL/z‡°8ÒXÖ~¼•׉½,iH0ëñ…Jßk0ìkááUhŽî=ez°“ïfG «{¡‰o*Š8FeÊŠõ,”q…?Ö’IŠæ|È,¦ô»_¹h“Øït´=L/•ØÜqÆ×±Y¡NÑŸäPPd±W)¢u9™«dÑÉøüÖÑÄ÷‚3ÿ‡ ïD·9Lã~t¿õHˉ6¨ÚD.ìcI|˜Ã×Ô]2P’xÔXyø”I„´ŠÓÕiB0±÷Þq½\í¬Ï»µ¾}éjyý÷jÁ´{±Â99ãØ)OAa¤ãã‡p*•‰Ïå È _˜2eþ« ôz˜¡Ñva´=Ê ƒ#S-ïZ(­:JÍp’ëé±Ó¶<”ð$”DýQËÌ3ËR°½/’ÄÛß9/Ç)Œ#CŸ§±í£ãUëÚ$PSøbîhíF¤ÓmÛˆ£}^û;|à˜ïªØV±vìÈ}HñMÐIb¬‹â…öO6ñ$;`a’ÖÓºTå\r);=¸ÚÚ™©YZs²ÚY¨°ôàõY·Á‹æúùÐì5èûÛ; ÀúžÆ¶8«\yÏYÉÏý?&ŸÍ5 endstream endobj 229 0 obj << /Length1 2145 /Length2 12651 /Length3 0 /Length 13950 /Filter /FlateDecode >> stream xÚ͹eP\á²6ŠCÐàwwîîî283¸[pw<—àÜ=ÁÝ‚»»ÃG²÷9ûì}¿S÷þ¼5µj­î~»ûi]µj(I•ÕEÌÁ¦@I0È…‘•‰… Ô–òtJÀÎŒ¢`;s;k3 "%¥˜ÐÄÅ 7qòØY\¬Jf.o&œl,,¼ˆ”) èô&5˜z€.&êž@VÉ_BììÂhjâü&‚,­A@Ú71°ƒ§“µ¥•ËÜŒ ,ÀNÀþ =\€ ç7·ÎŒŠ2dMÌlÁîζÖ9@–I  vcZhÀ €)ÐÊÄζøkBCMBU ¥ª¤¡¬FËдº€LìÎ@€™•‰“‰™ ÐÉà|ócbnþÜÒ& €ºðí2Y1½ATsup;ý3*15u )€¸ˆ¢º¨ÉÒPSg(ª¿1ÿJþ€z{Ȁ̭Mþ¨+H¨‹¨ë(K°2ÿÉ€àöæÓúÒÿ‡ê-À¿¢ySµpÛÿu ±rqqàcfvwwg²tuva;Y29ØÑþq neýØÉðvwÚÿ¦ØdþV—·@þøSf€¼µÙ[.ƒÿ De$%ÔÔ߲Ÿ'áŒëÏäâáò7U q‰ÿ‹ôWgÙ_ÞÛ4'ûGÊ1W'§?¡)ü—Èé¿£û¯bˆ‚ßÂÑ·óö5qÿ϶5¹:{ýjÿ{!ÍÞÚÝÚÙÅùÿÌ´Ýë­²Ö ÿ×Êý9ÿÇ¢ˆ¸<€›“Àöv±¼Í°È\ loÿ†ÛñOKˆ[¿ÈìäÉü¿M¿-ìòþ_ÅÖ ó?阻:0k€¬]2âÿTzc!þ‹g t°€ŽomfÅüÇùßyøÃfýÃ~K‹¯·Ø`abç ôµ¶¾Ý½MÜÞ:ÕÉèëý?ÿN!²rÌ­Í\Þ¦ÿm± þµ.²xÿÁ~Cò_¢v"Íß­Fû¶ÒÌÁ ;Ï·îµ@dV»¼õ ÍÿßwÒ –tµ³S|3@ó¿Ôè?›Ø[Ûyþ?þã”ðOhþXù‰µ³¤µÐ\ÙÚÅÌêµúÿÎD@–v@#+Û?˜¶ÝÛp¼-ë?/?"–ÿ½õ½™-èì àâý+¾%ñ?@¿ôd³†Š¦¨”ýÿÖOK€ÌÀæÖ Ë·¶ç˜89™x"²¼5''À›õm~Ì»ÀÌ»¼©\]|ÿÔñO§ð°˜Uÿ°þR¼Üf“ÿ¦XYXÌÀÿAò˜íþ›äà0ƒAÿsp˜€NÖ`ói°r˜ÿ›|›Kfwð_úßCVþ³WþŽË¿rðÏWÈ_ZÍÅ l Ô²6{ÿ# &.NÖz,oýÍúÆûýדÁ¿9 ü×hþmQQ°‡7#'+€‘…ÀÊñÖû¬¬lì¾ÿ¦köÝ÷w¶ÞŠõ_ôŸµ=€fˆ ³`3þ`›/ ¡%~y㥰”¼LGßqµe`ÒÇ[ ñÄs6È€BùŸ2¨òÁòÒ|~)Ÿ@…Ú”ÁØv/¿›’ËÇ®ÌU„7MüüQ%D~~ÕdÒÌP˜(m'£Ý—ýš«SÄ1™ÑœÐü ñó@Œ·µã>†môýâ3™~ióò7X÷‚iÖXNvóï ÚçÇÛ ]^ï±â¢MºE覌sCq~ÊÂ9tu`n;ÞŠ•š ¯õLn @,¶uã»7¥aÄɽâuN«â”›=ì² ˆ݆žYÁ¥f…¦~ #Î'äÜ\ÁB•ÚGsò·IÖî,µ°ÜÉ ˆt|,Øp ‰@Jt£1ö­9RPqÁNÌýæowfµŽâª”5šÀ½ÆœUWù ¶f®Žo«—»Rh«Cs­ú^¯(Œïì‹<æá¤=ÛõÎN*¨R*ìÙäz°Yu§Ž3ZÔ›%/»í%]B‡ßõw¡dØìþܬÞ2«Û¥>Ì8ŠåU b§]>O›_9$dû Ð,Åa°ÊØ(aÞ‘ÈxäXÓ1acbiÖn.y÷}ÚTVÝâ z.]ïø(­rB¡ VŠí–´Š ¯Òmh²–O9åRBc)ÿM&eÂIÑ<­™KŒ4ôr¿]Kÿ¤‰€W"©jˆÌŽ•¢¹Gω÷‰˜Ew׃pŠÄ¤QÂ"§"ã÷¼ t›5<{÷øØ²çè8mÝÞÕ8ì"ÈMôk‚ˆ›E7¦?ÃÓ'­‚’*4L¤Ê¨´‘NB†‹Îx˜ÃSèr«¯æÄŠ+{q5ñÊä1l´¶Žî"YÙߣ~¯«”Ÿ­|osÕˆ_[XÙ‘›Zœ0’Ð#°‰¥pþ­D#>YzáfOq}ꃬ4×áUÆNƒÙZGáˆrÉEÏ_}'Æ„ªÊØßFñ=:^ÍÙ($b£ ¯ðÃÀNºl™‚¾9÷fÞÍ>íLlwhD•Õ &-»/fQIuHy­ —äzc,¡½6×Y©rßÙÉ!{H5ºuê¢?s"a„ÉU~{%¹Å¤®4Á·gò–æ5š¯uäóûÖôU˜ûùú ÓT¶T+ã{%…誰f-SV¨ DüoW=iªÕÔÚÉÒgÃ6cô]¡ñÜùÎI×Fk¥»ªÜÂÃdâq‹O=Yü_E"ït6í%>•eÛÿSŒ2XRPæ‰÷På° ×Þù®vù©–%ë›D.ƒ¥ÙÚ|k$Ò…i„©å&m0ŠÕYù•P…¨„™#Šúâ ö}éÒ"ÀTúûÑ}N“®ˆ¥þ‰“Wóšf°/;gbý‘xŸ.c¬~4FúÎÊ`/M {©”/|Ëšk("çû­ÀÆóÛ–¬žh38æ±AùX%A\³(ˆpYIN„3)Ô×¹¹æc›×Í‘m4·¤™üÙÛâ÷?Ê<>(öÕð—æ…A°ùi4æíßY{‹ü>VNý®Ã¢®gVšM2 ¦‚²¨p#øè VZÞjæ ‰š?6 R>Œ›IxǪ¡iøÚZµ½RZ'±€ä¢my‰9Ìè‹Uz¼4Ñôàâ´k»Æëªï‘+ ×ÏCv1„‚­$/%5— «§ü¨€ÀC?»pÑèXY³ž²1½€’\¨);'ÿÓÞ¹¶”© '(²| ð¡3µK|ÑÆ?È;³±íÓ':³yË98îú†-垌bé,âj@ ”õGx Jr›ƒ x ÖÖ€Ì=[Ó<•oá“qºqM›}•="ÇZ›d.(ºx-J%#y( çwÁÒ-CiC/Ë—†Iº&ÂÖ‚°öSÊy£¿Åiï½H0¨<J±¸ÆÄZ·ª>¸öÅHë³uX8¦øHQì"°U' ö>ð% /z{5y?…tºX ¼1•_tæ~‚¾W¤S`‡XŸó¶: _.hEHønŸWˆ$ßRíì.K’à}(!7ODâ‰"PPSŸáJèÓõ!'–<ýW‹ú)ÂÕYp‡ Â>0û+0Å8!]\Žì¾v ééÑD”¬TpÜV]ðú¦E‰â‘Ùé5ÕYl»’nVL“JèÆ¹E¥œdy!ŸÕí%õdeD¹ôöÓ™]TTâ¤I `®hÌsc’ŒÅâ¤ÈF?{ØuÓ¬Ø.f(…/“)°}v—¿É©J-Ò¬¬2P·¿‰ISæâñûrI›÷XС'4ç%õÉTÉ…"+'Š÷§Xä©ÕÊÅÅ+fy ¼¯HO“@rÿÝĺê r »42Øk­Ö–…È*Ä[˜·XÎÂ-yý­Ž¦®ØWôú,ðÃǯï«ÂЕJü.¿Ämdר^ÁضT>Þ͵הµ+¿{*ÁAvE­œióõÀäxc:'Õ@üû}îU†}è¢ÞÙ®N´0 LJù Èi‚¡$ºòÅJ÷DßiGVˆ·¦ŽŠ(Gb{B¸iþÃ>âwÚ DV—)z›Àžá_iÛG‰Má83Ç=-z‹\øû0ZP¡•Š¿(äÃ̺úÔÁÓ¿KésßmHzoÿ´ã:”%–´TÑ£Náqíµîv§hÔO+ØÒ—ˆ / Q`ƾ-ÿô ¾µA¹Iy¦·^X³#ÕO¯±‰ìÉ­"…R3àañaqœy4}˜:Ððù®pª@tó‚ [O›6m{㘗ØÞŒ,ºé }Baƒ-óço2zyÖ×£˜+þ¤uÐ\Ú{¦‘Åí9œ>¯KËVÚÓÒ\iê‰ýªT2Ô’Ò “x'º_ 7›ë9¸ˆ—ȵõ›DÔ`’ŠEÃ[™Êû‘È 2†Ã=ɪqQ=HH‹Ô·0û ´0‡¦ŽU¥\Ìv7ïnOCdŒ‡WÝÞ½sê«Ö·ȡ«e?þ„ ÷ËˆŠ¼cñÚÒÊÝà2ÕñjwRê  ƒðHm2ë©•%­ì§²þ–¿ßY™ÏîμªìÒA\½‹ÝhäZP¥@d®êÓS„§=wÀðïì‚èž§§õû½ˆcöeîXí6ö+7€ì«Èã±7™† }ùF–e”Àâcgô€ÅŽØ†­ø§[o¼–®“:6ˆ%(,¥©ÐO¡(t5ÏœôƒÐ-ŽF¿á®r7ŒÖN‚\%ïû¬uà ú`ÐÍ£/B.k(º³±'Ä¿øµ~„³e(ÓWíò›.w«Ç/9Y¬lî±ëXÏ¥uŸO¹6q&ŒQüMi¾N†®xw)èz…Ã\gĶC¯cù%’ÌúHk.ypMÌb튼«óF‹S¸·ÎæÞ‡Ž>í%üæ«Øë†UmèHººëÚ 'Ãñ¨†ÄYž q =îRfD¦ð¨vó„¨7„ÏXB@ýއ)¿ÍöÃî†ç" Eé…χâqªÌRS"ŒƒêbSJËýx—ç¦iÃÙŒ'áˆ@¼žíBp• 2Užäø‚6ªy±õ-ÂIÀV3Ò’›«Qy¸d1Ý=‰x¢es¿ûÇÈñâ÷bµ¨8)N÷OkÄ?æ³ ÊH°–»vuyx[ë…†1ü×÷$$Á÷òrXl¥Ò l«Õ.±PÜSÎOð%‹Ðÿ (u†ÿ6äq…%—î×éW&Ú]a RŒ5aê3¯äŽPg/²vÌѽº¤­íÀ÷'Z‹Tål*Ÿ2RÇ-…Þ[Ïñ`Pë'4Y3Ç‚J#¸úOù<‡Î,«»f†ö±u˜ýË®Ùkäo-»¸/¤UoMšfN‰G˜juäBº.`”³T!ÕdԮњ1¨‚:ŒÄ–k3zkF›ýUÖÂ[W7iíʈ@Y éJ;5|7„ôtýÁ_I®÷ë9VûýŠÝ®^гpT|Ðc×2Q^øù‘ÐMÚeöíkSºÛýÓŒÖ/'*ðƒçb/x³CéÛÖZ‰Þ´gvyô•ìi*FD8ü×áÄsÛã{ìs­nëc•š}iz-; Æ7©—{¹ãàÓÈð÷žÄ¡˜Å² 1T± ŠJ1åw¿užå”l²• &voœ–<_ï2-l+q>¿lµuÕRµ¼-®¸‚¼H:ïcŸ}‚Ú $+€%ÎüW$C+ÊTä2ÍéwÔÑæïí*~U:€±ßÇN;þ®è“ýMñŠ€3\4£f0Õ®šˆu¡;Ó+ï–rÛAo…Í^~Ò}æÆÔêY*¥ 5¡hõ´»Þ«:I’ ×&vi…€,ærw̱¼C¸äf,·Â¾{—èÚñ{Ö v¦Ü]ÍQäxÌÅù}(œ*ñOˆqÄÖ4ÇkÆ÷q©‹á!uÙ‡pÞÏörDsîƒ1÷ØÆm ‘YMðŽx9¢‡ª‡Ô W¨ÅâL„€SZYÝ2i>½ì°j_Þ*FœƶB3åh*Õžó Uß]ÎÖ(±¥gáS>Q-bŒ¸ñƒ×&C×¶è(ì†YmôfÑèy'ÊWšç¥ÆÔÕœêBuü|=4˜®sSùˆÉ†ïO@Mö3¥ ïl™@ ú×,f¡ôÕ1!S½0ÎØ€f\ï½a ÒK¾Ðf,)É|jO=V¯vt¬B jTcY?IѤG¦cÒ] už–ª‘Ìu¨Ÿ¡UÑ(‚J¶Ñqªù"“(Þ±{&øöpO³sƒV䤄p=Fɹ&xÍ!ü0ŸÒ³ *ŠÇ[³§÷d°¿IµžžyÔÉ“¾~DW!•g*6OïTÞ…xQÓ¬5ËV‰F<öhË50`ÒÆi‡Û_` ;•<ùíw™¬¸X烣Z¯š8LÊxsïÙ[Ã&܇ãI´ÖôŠëæiW%ƒºxhpW`…‘y6]x”B¶Ï2hi³0j£ª.X;¯Sšð}M"±‰ÿ!¬ÑÒÕ }ØÛæké¤têˆßÝ[V©‚øX %œ'>„þŠ£c,fõ['Y¾äÃ7f_—í£ÏÃðúð >7CŸ ®'y›\iœŒ×ÖP1­oËväRð0†É0…÷“$Óy¡¿ˆ‘%Mq|~ûdׂOwÉÅ{‡4èyÏ­ðªÈæ›{‡³±Õm·Åõ3Œe…XÁðáúÁFŠˆbÌ€=—xÍ.3ÇïT–‰ôÛyµ±+VdÙœ có;ILˆ¤·Šäæi¿ÎžVNäQ™–©J?U‘k ®Ö„OýçHéQUŒ‘æe ©Âú¾<{Š™Ç½˜"’àô Þü!ëïIæ1 ÷°#“cßÌp1D³Œ‰soQŽá¹rñ.”= bîœ}rëþÆX¦ðFÿ•@)*Gï™6d[NÉy ÎŽ>ÓàFh±%e­D%Å{RìT3ß½vµu°ÒÜàg QÕqqbh8¸O’»õ˜ E3 Œ;YL÷ƒôÅ‚Œ?ÔŒFÔŠ~Dñ˜Ú¢0û¦ÉM£¬òJÁ–Tˆ#Ôjåv±döè½³¿®ê&’Á(XLˆÌ/€^Äx Ñ|i•&çW÷BôC,S‰ŠWß+A6{¹ª§&/þ¿I‘Î|›oÓê5×¾¯e„¥Lƒ{‘lo,†ÎÓʇ˜$á§<'gøç1Q8²CŽºÍFÛ9_Ñéss»I’3±"ÂʼxedùMt9PRïmD¨tWضh¾þÂ*:äT1šA{B=û/ÿõý)¾},¤#½Wß à‰ý»†°¢æ¢+h¥{ ¡¢©Y€†¨Šî· CÔ¯Å|R‡3ƶѶ³¥+zZÒ°½\¯…“·lç¹bEŸ=¨ž…SÞ©ázÈÖ\Ôµ††œ—Ãìo6A¥çyµù¬,l–!>ª‘Æ˜Ìøn?zØ¿a_×Pgs0zbñÁnl>–ó·búÏéù”ݲHÁˆÛóa`û®k[bcï=@S„0=í)ÊÀˆ[örrfopG!‘q£·» á!$7˜°^©ÃØ2ÍÍÏ!ó÷Wš5ñ_«^ñàÐ%šXrž– 1ØÎ!'‘åì)CðˆÕÏ/m‚ù¿` àtùLÞñy;¬Ôܹ!õ e‰xò´1#0ã¸~sÅøZLp}Ç)ž¤¬†=?±sæv r#Á ž=§3æË]>J2õf=´dd]üøgPC÷ã=µ—rÎWgȱrgéñ/Yv<iÝ·¨ëF©ùÈù{F.8_2'Í¥Ój­KXψ§I~åpeá›*Žø[> ·XäK!.ùædk”R—cïӚ©‹Ý ((Pû~sí@²–7Áh’ ¬BúñÅ#Xª]%’ûJ]êðxÅ;¢ô’#˜pVññrã&Ù/‘˜XM§$Â…ç&ºÈð™¡Â_ž.æóÛë­66¶D¡unVë‹ÇìsuÌlEî–í¹ ßêX,C??äœ2Žßz¯qyÝå,ßßqMˆãŠi~`øÎÄFåƒ0‘˜7{˧'y]×Lu´“­Í•1[éi¬ &¯வV02¥-~ìM—%ùÓ:ý Ÿ \÷B=#‚¶’ ÇË ä,î7õ¤SŒÓ"+9w»9ÒžýÏ*khÄμäÓùŸ=]®ø[àÀ´ Š–qLB6iFa2]¢L‡Æ«›ø„´ÖôYüJVqÍmv{¦¥ {éÊÉÊA¦^è§oÈAVÒ|æØIyÙ’Š’üÞœeüQ–¼Ò\k”aC,ª´é§²!ˆqôÙÝ»Nnaï%ŸỎ¾JüzUÁÊ•Á†i‹Ò%íÏ\V¿ì«Œ˜•R_8Ci¬;7UíB^Ô<ÝAg§ãļÅJ%/S¦ß_6~¦þ¤×_ÊYš+!}Ì/ÚÖGîEƒ´§BKTª] =+ŽjrËÀ–f5ç0gØ­û9!޼·.ìVÀc¡/"ž¾ÎÐB°vPŠ˜å[5l£lÒÚž©}´ë s­Ku) Ùˆë È)%Wýåõ4Kú°œtæž”·íœøHY°]½uëL…àƒL¬Òo¶TDOgåÙmT´Š³ßæÕæòqù®žVՉׯOï1¸X1©ìÓLè»l(k³ $„ýöñç;Á刵ÏGS³7×G$:'d~J6œt{õ.avëcë:äPö|B0®žÏ4-¯Ñ}LMáK¦êcspÁïæ:!1’¤8½ÎX¾!¶°")Xb"îÂò1yŸ‹‹~+ÇÖÔÑ!!]†‘Ì•áÖ§ÿµé–¼«þ¸ümCPªõbÈ&S{›WyIg‹ÞXx#2Ê~¥^s’‘¿Þ“-Vva¦GJ5ë§q\LÊjóÄ7ejÏžÕ¤_E!+ÙÍ|ñÕ}b7äÑã PcF§û£×/Êk‰Äè½lÃokÀº®DÍwt2Ìš¶ ¢ºtÀN_¥Ö–¸&¹5ƒWú8áû(† Gù‘übF*×þ\΢éÁ*lö[v]Û¾Ó5Å!pí·Ù}šš xÔœµV¢27w®«5¥[$°uµèX¯4^Ó:Ò5dFAmÒª`Í€›BïoŒ.V"g»˜Ð¼WÎh§íëžš€Gï F&i]¾º»…dž{v›ÈÜ(QÀ*!Ô¡TTœx}ÇŸ4ÅcŒ—ÌúáëÊ7Œ¸ÖÌ Q¹Zé’ŨÂ}–Ç™T¯éÿÌ;,Ü®ØéÒèçÛœâ÷K”ƒñN†'…:©SÈ$%&ÅWwŠp.yD÷1gfS×-¯ÙÛ˜'Ì)7'z™î•CÅâ‡B€ìh«‘žtoªTéÑ™¹_Œrƒu¡˜Å‹zjÝË5yü“Ùzín mÉ0£1 ™¿ç•“¸ë@”[¯QSÝ;pÂRêÅàsˆfo˜Ñ–fQ:)·Ä“÷€G­›(Q‚!UÊ&¢÷|LÑgÚ&‡4¹,Ÿù·/ÚšV¥…i¯Ô U3èPÌGÒÔçSzÃʱžÓ¶-Î9ø#\9Üêgˆöé?ص…é I㼺µñàäLÖß?ÿˆ)¸ $â.&ìó„˜vÃÓÍÂë Ñ—éh†ø†øë•#­¥³´?мæ]D :MS±ÏF|"Ð1µª!òºAŠDlžñ䛓¤fC8¦t¾ep{ÆêDiÔ:èˆ"[Ú;i6õ*BÃ5ä nùƉÏ*´V5õ¥£•äï¡ð«ÇøHÞ-XnѪë[²ŠØ¢fÐä@;Œ eŸØÚ røõ\qÑö´™È&I±jY~h³ÛÌ2–H/š iEo€8ñÍÛvÎhB½3Ïk¿yðýÚÜDDM!†ÄOÏL n“¨üüÍ©T_PƒÕI§Õ’±Wó„Ùîh8ªð‘Ùû«‚ò—‡ËYV·æsí¨QiÝ ‚øW24;Z–"•¤½ NÙžIÓÓóôdüX°Å‘†Iš§ †•ªÆšy–fA?aõª™i…PÔ¨Ó:;ÄæÙïÄ–|…ìÓ/:Ñ HÌ‚T.?W’2Ê~•úJ{ÜýànMý,‡Äì’²ÙÿMmP„G‘80’™ é Íã¸ìz»Æô‹—>üiÐ6$vB˜º»ëçJvÄà‚×õ«]¾ª¬!7tú¬dÄŒd%¾¥Qøkyµ¾!jc;s%`î×s´j‘B”EéR EŒ ZVá(Î%ч>9æØN<0®£#5Xh–໸êɇ¬n Éóp^*„×™5ÿaêW´¯’ŽIèmE%x™BÏ=Yy³ê©¬f|ŽÅìÆ,JÓ¸z­Ê—ðŽï ˆæ×w›cÕ)Ç‹ÓnHÊ Z‘wr`ó‹8ýNÔeÈ-w´86Ûû’Ä~b«àå¯(Ý Sb;¶F‚s7¨›Ø¾¥üB=-Þü"ÞÍjð«Óµ3¿„r9-¸«eÝM Ú•UÀŒœÃP,ï³õe?þQÐKdyŽk##XNgÛj@ÒÐ~$‰ïÉG‰;^lðäHçHRxÁÑ×µS"¢ºãÚ%e3a<¡÷ ‘ ¡ôžRd ^èç']ú 1?& üŒÌ2•>òщÐ!Ò°®Vû)/ZÒ])’'I½á³fµÇ˜Ù¾F'X02¦guT_ž½ 5–5šÈZqõúO¸µ]•fŸ…ñ³bC­}PGã+ÁþÙfs"FÏÑ<àÅ{‘»˜ÜKQ¯JùÆüpÀ¥JPn)þŽTé©ÆÎ ªë ]!a‡‘©Ž¡&¯ë!Ä! ŒëÀ Í:Ú‹ÝIù-¤\a+-¹óùfÓ¾Hn™ï@€ ë°ýn?mM&R‡¶IŒ–ëAV“-+ûæ¶AÐFx^VuXölžúë™´5ª÷Uûg-ö@ýUYGKñ©‰,5c…d†xòm‹kCÍþÍžU ·ãA8jc`±žv3€½~ÕN…`ÜWð¸µïò2§¹½áR_‰ö‚Âä4ž°îBH äÚÒìDLlž\a²öìK‚¼›bÔuô§L%®:/å>ô{‡NþÃs%ñÌÊ®2Mhy ]P?=MþÖÄã ¹ˆ[ [=l˜ôf•ÒXP‘Tƒ½9ÎEÄ °9½´†àÂ3ƳÙ*òQ½ }—âÀÎ(l„»ö8Íøò0ËØ1bFÏÕ³8¥v|y/Ÿø.@¢Ï©¸¢ï9N5úUÏ£ ‘>ÙæVù¶[ )í5ªï#Δtx>I4+Båô1ÅB6Áôîpq=z!ËV¤J¯¼ºæ˜êQª D_ .þi®ˆãÔ6Bƒ¯Uó9RŠN)«!‘™&^Ë˾ðh†÷ŒjÓNI¸ÏTÏÐü“ŠS@Y¥’]ÁÑ5Ük·»>å’ñwÍšÐÿF+ Æ3¬}Mo@ÅëeŠÎþýgSQwYÔ/‘“ñê©Ä>iáÚ±ü¿‹9òªn${#»ðqüc ÇŸXTßSE&߆mîRmðÓ 5/¸ÑÔûl{£T‚ÖmlO9á)àEÂ¥n9cOŠ„g„q·Œ­(çY ,ì\—¦òPÅÒ †iÁ4ã;w"ö&J4ÔFøÀÖ Fsƒõ¼~ºã­9ž4wFaÁÝŒ«)4]@¢Géà3/ÆZ\NËÖƒø®UÈ×ô®¶¦U¦ô«1P£íëdšÝQ«}ó艰SV™;št”8L½Vü­N¨n ÃVc‘ƒéÆÍÝŽj?Q&®ž„K”—/–ɪ֩º_øs”¥^Öl¬w®!¼Bs¶%{¥Ù':ùªZ=ªe®É­Ïg.µe¿­6­ _Z[çŽÃ!ÌŸV¤hLòÍgfÙŽgi d|FŠ]4©»#dÙTÞÉ4d¥RÿžðX|ò*­?»o@™þK“½%)ÛX M ‡¦ÉHK‹ëÌ»_™’)þ³Ø]‚”>•jj.f3Ïò#ôp¾þ „®M6—g¦ot`7™^™Á×ÚOÎÖla¯¼R¸§ÓÁЛÖÙÊ-êÔ"Üe;‡n¨ª‘‘>Õ»±ÑmFÉÀ/”y×Oçë!Gût§B‹v!ˆr—û¡±§ý`ñ˜Ê")Uglòz}F¢‰AfÙ®tçF'°^‘ø<Êõ}Dz¶X8#î>~Y* Œn(«Ó)ä4^âŸ|:wšÊ:¬rçqò–g-ѪìS‡v;SŽ‹^DpMâà …YlæÍ%‚› –Y® Ññ…ÀökòæÜÅ2…f˜fJºnÑuá9xVw×OŽuJÔå–Ìå…Šð'‹ ïEÛQªX Êa·¢XTÓ”Ô˜£ôô|³)ï{»ÝÂk^¯u¡¯Å…/õ󑹦Ðrùö†îUMد›!ö-Nê¦îÛF¨¶Ó„ß©ãÖEÎ¥¥;{íH³³Gš¿+¨¢vh¹Ày,³”zA6bezêr•“qßF ì8¤§7*ëÆzŒòHçÔêIvÄצÌ{ü2zÛ´}£V.4gãÐW«K¿=Éì )[]“:‹fNYyö[Ïœ&íGh¥l¸ñ ÞI›Ó~Ó•Íù;÷_ÿÍåÜ{ vBÕï(ýb>ÉÄ>Ã5é\ÂSQnZ9*÷?tàƒ½¿Ï0õNäô=¡”"]²þ‘‹É»ú¹š8ß©¢§ (¼/#Ì3Ø‹eŸ-ŒÈp ci®K“ö°÷,yE4ù˜AؾÚ5"}Ôþº–73…žÒ“ÛœG¤þÜV&ýtøvƒñàÙ4>¥žõI¡òÏ÷^gûËsèÐJægÆU›Ðd9þkÖ_ÃíäD®$Dþ¢‘YœÜ0*C÷[„éô|'éÊ;oŽñó1›ò3¸ /Cr½ìC™ê§ƒQ£FôåèêŸÉW'é_â²¢¡ø£v° ÛîËè`…ÄèXe~4ãDç‡ý$Ú±×ù9„Z™Ñrm8Œ³3HŽe6˜:*ƒ57O¤©%ÉM£»ošÍŒj%ÊñˆBKÎHbÜ3 ·+{hÂþ©ð÷~Õ¾ª†šÕ™ød“[—)Ð…»ƒ©Zq[:‡Scá9^(®,wKTÙÝåÜ&š¿+å’;•»MëbREÃÆôÄ Ê­Ô"› k›”À¸eùž§Üs܉xû”~/³³EõÄ~I«J0âæ(¬ð~ƒÆ1¾¦ G‘YÃ5ij<›”@ªëS>¾iâÙF&¤‘U{ÁIþÏ™/ƒeîc™ƒ%H&?;/`'}f\ª"ù“˜kàÑXЬ¡Òcæ’Èí †kv½×P[‡Æbñ.Þ(sˆ¢¾6“vQòð8ëþVÜ•ÝA5’VD°"jº|0ú´R¦ÚÈ÷F?#¤ëýX–;Éj@Ç:ÕáËgq4<%·c_f+TOl¨.µ¡E2ßã„é3w3Ô„O/6÷¶F\ÅÇSØ÷ k‹eÀ•Ù`´Ä&Œïä]¥Ï š±s²[|n†ÐG[{Ä÷2 A±’ `L{`ÿ¥Ø:Dg¬ºkF—x¤0.’,Äþ‰Ê q:õ4Š/ƒækº!\2ËòÜñäOôeˆe‰ 0ýÔñÊŠ×Fnôy.š·s ïì±ÔíØˆÅ0eÐTJlöÚôoÒì^¼-ÃàaŒz×'6ü(ƯÜ':Z/ ކ?FH¡Úбq$‹¦]gÁ$œW¶^E}XÞÿèá̉±×l$»>#t‹ÒL|tŒ•‡£P\ÎÄP@%}ÉwFõù—úÕÏøR4% $“çgË÷í7'ÔÊKò ¬Ve©Ï&†ÇŠãWÐm±ÈüˆbvY„ë÷î.1$ˆ)„·rn2º%yÄMeÙ´°µ=%8$VO,‘#X³ëH½…8U=»*p°Ô@™NØõ>crPóÄÙiºÇùÝùwDýȃžÓËO5Œ,‡ë´µI<…ml£+Š‘*Ý´SïÞï÷ü¾7^ã>²BoS¦4C0AnË·áø·ž –à9´Ö‹9ÃÊéäcãAºT^ït°ä-ZßµÂ&£æäM« 0 <8»¯,é »â÷~Ñ|&|ôú,t©¥ýb°À™Å±g¶ßŒ4Ë;’—A;waó~Ç£qL9®Ñî‹Þ¯Ð5èBTG1bÈóaº¤¿8Óq]j5üª~YÓ¬D´ò¼VÄY–óu¬ò—° 2#Ê“ßìNåB–Ø«/P”I«*¬êkî<¹›Y6C¢_ 8ãÍ‚±?ÅÈ~{¬äâH¥vÄQyO(“Þ{TÏ‹$]‚¡¥à뮩_8óf­Þ“¡«U|bH@þ®CvSY-ý´ñôû‰·–íSrLÀÙÅ»`é–›vl†+AüøxãçèüU'o¡”)óAž:2I¼X ƒêj%ïk##€'raasè$†棧Q¯ÕTfãå–õý„ÈS.nʶ|'Æ*RC¨Xš1Îgjs$ÙfÉ’~¾îͰ‰ÚªO"+ú¿ÅYk¹ŒmýèìA±FµW7E¼ž]/\xÌ;¯Q0H‘Ä:-,UQAÍ"…e{þëgj½×ŠÙ&LQ~ ’emfÁY¬ÀŠ OXDCð¿X ŒP#1‹3ÏI±›˜`_Ói}+Ðâ]‘ÑÊS´})K½¸)SLÇÌÚÊ8Cè— âú¨ìãÁ>«ý„ß.Œã”s õÒ‰æïßs$°U*›×«‘–*Q’ŽžëºƒŽ¿E èBË7Cx&Ëê,ó×Ì=~²2ª¿' ƒöW)_õjˆpâµ,dQ±H2ÉíW7|2) ´ì»ëN\}iÈ ;·îHIÖaWÈâ–Í$´Ë~înkð:ëeÁµÃÈÛ™z—,ùÐ  +2 B½­¢aTœ òPÛõsu®ç ØItÕW–Ú£6èðéíp Å?´æ0錗‰,‚ÛŽí¢E㵌°DÅ'L»œšaõÎD¢:&®e7dyÀ Û`ÌìÕs·Ô¾$½ìðÚZ©Îµ>´'ä³î†–ˆàtó{¾4Lw·:+T'z 8Û*ïÕ_C¡1¶.+˜¶’BL&úÍl#@7$ÿé u÷ endstream endobj 231 0 obj << /Length1 2021 /Length2 10194 /Length3 0 /Length 11422 /Filter /FlateDecode >> stream xÚÍvuPýÒnpw'@îÜ5¸{‚,°È.Ńw ®Bp Ü Npw÷ ß’÷œïÈ}«îýóÖÖÔÎtÿºûéî§{†ŽZ]‹MÒb”ƒ€¡l\ìœBm ¾¼‡PèqfÓZ»Ø›9¸Ù99yÑé褀fP,c x8¡65 (Ìv„“S `ZK€¹@5ÓöprÍþ<¨Cœ¡læfÎ05l ™`&ÒG'µ ôɇۓ#€Äé à è‚aaŸœJ±”Ì,ì nÎv €Ø Ä®ÂP…¸Á„ # 0Ú˜Ù[ V\èhÉjjä5ÕtÔµ˜Øº læt,lÌœÌ, @'g€ÇÌÒò/Ü f`€¶ v™mØaµ\!NÿÈJZK[Gž #©ª- ê²äu´´YªÚ0áÍ(Ø @l 2{2W‘Õ–Ô6P—åâxª€ à ‹ zBú_éÐÃ’ü+˜©•ÄáO£ ê(ÄÁáææÆníâ e‡8Y³;Ú3=жÁr€8Ù`ÿN@{àŸ»€-aÂùãà©Çe¬–À?I”*’ªŠr²ZÚl°j±=œíOóÙ¡îÐ?©hÊJʨÈþö Èèü§[Ož,a-Ù;³ÃBý%p€õ†ú¿9ÃÚ}‚kÿ€3sô÷ÉqXÁ0;süã¨3ÇSlrjªÚlÊŠÒ²ªZ²@Bœþåêbýdûÿdø…³1sþYY]]à`Ã8g¶€áƒšA]œ4d° hIóWÉi'§§ÔTþ©rúßìþÙ ),c{/o3·ÿ¦­ØÅÙóߺýŸ´€Ñä uþË#𕶇‰`ÿ¯{:ÿäQRFY ÀÇ à†]œ°–[JC`¸ÑŸ(!‚5 qòàøÛÑ·CÜÀ^¯³-Ÿ °tqäЃ޹eþa¡ÿKf „8Àw°Y¶°áx ûgžÄ\ObXA¼½!Ž+3{g 7È ûC÷r6s…qÔÉèíõïŠÿ|BçX‚, °¹‡­ô?ÞÁV€à_b’ªþÁAÆ?ûŒ ¶Ì,!`{o­Ð9T!P[ÿßFÿ…ZÎÅÞ^æ€ñïôßgÍ@öÿÇéÿ:¥|Êžñï]€œå@î@KuÔÂæ¯^ý%W„šÁfMlm„õùHçiûØÃ†¶ôAO/ ·Àé`|·°|™a%ü/Ô°v>apH*ëËËh±ü-ÿ•[@,A`k×ùfNNfèœ0~qóñ¼¸`Cc tÿC@;…™] ÞOíE"É+n‡æ“ý?¨?÷¾rþ Ò?6ùŸg-¨Ä¨²„½ÿ툊Ô änÄ #LûýóÎä?ÐýkNþÍZJ âîÅÆÇ-`ã~Å àâáãpqñ¾òþ[‹¿VТÃj÷Ïç§éî@ ôÙ)ˆ…p mr]p‘lÞh1 û~)±˜¾RâlÚhósR™œU x¾ƒ_:}>DYAÈÄç£?ø³>] ‘ýÃâ·Ä²ç–kf>*>ϱe%³uÙu>¤«Ìø·Ò0í(e2(äý™Þ×HÐÜ•ln»‰âyÄ;M¢1.nœÏEr+˜àª't²ÇwŸÁ%oy>3Ú}¼!Œ‰4딜eû)˜xP Ù±£`côÝ•téÜÌù' ûQÒ0YWH2^ôökÊ-Ñ_1¥s2Vó4©x¤†Ã}6ù›üÅMlÇ-!—5=£ýwšc ¥ý/ÁØÚ«æŸ‡’ýJEæÏ³b!s® µ-U‡íå‘}œ¤+«ë ÙÓù ‡s„ï¶?æÛBo`ý”v”=(¾ü¦w7’ô[H¥ž2iŽA`š«µwÉþ®SÅ!Ð*¶¦i0šŒñ¥ÐUTýö¦ö8A==î𓉗™»C¶¤âW»Cß WËæŒÝÄH€åkq,…÷4‡’—y~MhE<ÓJ]23ºØÚ÷9ѸØÖ¡Š>‘ßø<’G©Üª, 5àñ+s=ÉBApˆÁ=ÙŠþý+Èy ™õ f½úÌþòA@Žœ^I“ˆÀsº0C]è ݰ‡;&lEü„Mü¥J“ï¢ßtµ¾?ôŇ˹œÑ°1Ðû~Åï-áåì#j}¼AE§£F(f'èqÆAy¯*ß+<âHx¹aaaÒž_ð¾`3VOƒÏéÃââGFë‰Qª÷ñÄÀ‹Dï;VJ;E?W´D{ø‚Ò6n\c»E&Àø†ƒÇµ6ëa·w? !wÐ$Wû&czÍcÿj«ÓQTÝÄ ^ÒãñüQ.<—P©>)+Fò"íÜ#½f¯þð}¶‹Š9ÀæØ7ßx4ʃïÕÕ³-¼£’Ï´dØ1]ÜBeL¿åçˆoû”·Ý¶+æèq‚ÞÝ=fÒ® ÜXS;l'Á=vXÔ‘½hçebûP) õŽRUá€]³(L¯›€$æA“lÏ @äÍ·Î&­ï ,ýW‘£òöWÄ{ÀŒdQÍê¨}^±n…†‘%u_Ì Y<ÃÞdÖùJê³aúCßÊ Þ ‰-aÑ 7áào½¾¥vËÈqdµ«ýu<Š©grßÜû¬h.ô¶æø$tQ-Ü„Øo¿w›)•…‚Ò[úÇÐÖÓ^Ë}>ù]H_X;À˜ó>2qm&F3ìt ¯Žç#L Ç„½ˆˆ#ÉýnøêÏV*”÷@Pâã ½2µÊÅ0Ñn„ÃMÞ²šzù·ë¦Z…Û:%·B“ŠþàôX–_‹³,Ž2ÍkÏ63¦[íUJ[’ø½EcCE¾ÌÕ ecˆ¯„P·s¯é0u Ñš-¾Ân°¡ûí¦ž öõ'#-=Ô‡=Ê-Q§ ‘î\j<ŽºhàçÞ4BiÿDi®¤Y¶5Ù ©ÛÔÓ0Ïk?OÐö,ª%vnB I=.Ô<»Z4Þðpïs×ï,>•BJ+ œö ×íæAÊ HF!á×Zq”ní¯qµ÷Æ´-ýV[³õ™UNçö͉áñsøŽüíVÿEÏSwÛÂèvM×·¨Œ¸ *øúü<ŸGÔ-ºç™R Æ —ŒpŽ•¥úrââbo¦ì‹c¾bÜxŽª¤«Å«ŽHÜ9O]€Gl¡ø?ƒ¾ÕfG†+þ–6‘ÀxN†°®‡rRä{Qá:ŽÔćpfü"ˆr;Ø0h‹ §Ò#Md/Òe-çì5ºŽÉ_ƒjdk=Ú-ŽëoUE½Ü_ïÍ뽃Ûno|Ô@ù! ¸t6ÓWp¿DKz9‰´}«ù‚²'T§Ír?½Oë]‘ßÇAVß”õÞ©ðN4ÎÂÞ¼Íý-³Þ~ ñ¤u`Ò®<Œ©n&EÌž8jωŸh®_}ö ˆOÞÐ$¦õê#8?;Y!¸ ôØóDãß,!E”™ó[OÖÜ‘tä”^Û&ñ:t;š8­À™uR øÝ…_ÊóûU­JI"˜IÀÌ;žu;5¯°*­¡«6±Íò;1÷²Ë”Ý'dñôE¹ û•í ~a7¹éT J°x F ¾m'¸(0ß ‡f<ÖÀ¯èÙÃØ²×狪òõwŒîÏìüY[göáw Lî‰.:ü§‚x¤îÓJÑ–19›e:úËm»¯g<ã~¨B¸™Î¿a­Å:e; òýøF(pq+n€3¾¢w/ÎOGG˜ˆÅD'8ôW:ÑÕŒn6JŠc»ÿ–áÀ‡ÏÍSÜýs®4ÔÆ¯þ‡T[¥›Åë‚~p®—ƒD0E*»ÿ!êöø$p)d¡Œ‰±)„QÔ*|ëǃÁIŒ!)”*w9E°)€ìvù37bV¸¸Íÿ½`¢0M,ˆ²Q÷Í­âdF â‚«…Á‚Q)u7šÿKå]¬ÜÝquî/Ðh—ñÈâ‰}”Jo•þÒ)i‰ï!?ªwôÆ`úW„3KLÊ}~NVâ8+,%…*’ɉªDk©Lî·Y'ÝŸâº&ÉF·?qH÷8…ñ¾ÿrÐÙrœ„ý]Æ<·»ðYhƒ÷¥Mô+çß}9º„Ïg{œ%h"ô })ç†Èî.Äðqš±È*ŠöH2ù7½biÑv-_`èÍ£hÑãŠY1#(l¡'ç[ŽÓ‚⤻šD .«ä4eÈ¿uÀŸ}-CüÑû%¨( “ëF¼–‡b…™uòÉ(lP|ÖQ4kð°ÕƒhS%•Ó‘ÎpRŸQ¾!CǸûN2ù«ÃNf¬qŽÄ¨÷P@ßEmêû½ihftp¼}¤×ut³uÛLüš)HbG!aeøž!™õ2©oSGhs­Ò—ª:ÝNvv#«g×£P ì.üX§ò·pb%=Òxi/’TQ÷W8_^jcxa«”4ß4ÜZìË£ j©îUŠ¿S~¨x›ÈÕŽµE§Ò?¥AÉYÚêÞ -paLŒÉ ÔP±>xðÀ[?\n/“¦*,sâ|ƒ\B¢r<[pŸÁ1W,¯“BÃnNúõÜM‹ù€™4ØoâP‡íÂÖ´pëÕN['×§ªèEsxêP5VUi{b¾XŒ˜µKûü;áJwˆDõ-×T@EãµA7¦®ÿü,7Ú¼QÎ5 ‡µ1‘â%À8›$ CÒ'c|C= ñÌ^²úÒ‰:Ä‚ü½=é¼íãùpVºééópôÄŸuü\ëSw”s‘Ù±ƒ…Ž—uŸuæ¿#] dšã»hÁÅÝã›5t9Ó_l$"úÀX*}OjgWRøXè@ÍÔÒ´7Q@hnO¬ ûö™•:Ð^³µ¸Uî¶Ë€ÆYÝ}öµëG¬1hrÜl&›=lÛÞ¬ÂQ=œUù•·va}†G³­ï0`äÔ.6›@GoôVi5êœ$î¤ÔíÇv†rõªWøî¡mlf‹—Ž(F8õ¡ÝR Ÿk®¦cú‹”&ÌßÇJ;Ú”ÜÇš¾Ý’ËV¬!T/ÉxNªr±nƒKöé¤KÂ61õ{€0y1h#[0£:rï¤æí´m=OÛ¹{FÔ6ÿMeíç­>U¿±³}Dúº£˜ÍŸó¤{Êð½m#][T€ÍÙ yùo%…³x׿?15¸('ÀLùÈèó#HšæÜÀ.‘êPò´^K?,•T'èš"­æ%/–릀 !|u¤Ž›H^ïø´‡cë±™‰gk‚ãæ£;2¾}vk‰9]ðˆÂÚ.<öªR'SL?¤~7#Cûšç΀¿è¨:ê¶ÒëC…~:èWgÔܬ=Â=Ëʬ¸8TXI£Á ¬S^'—ÎédO´ÛÊîÌhˆwP!AÔ’÷Ä£‹6`ZÓþ‚$‚zcÑ„å™ýJÏ_‘NŠšðÓ!E)MÅÆ÷hñS& žÒõ~cd3[€Uj£+­{~ñød‘‹ðÃi«dB¤¢!ö¼ Rå¯ÖÓXáõó¾/{ÖtŸ/]Çñ¿Òg¨OÁäX.­ê†‚n%9˜ã¼’‹!D¡c+ƃ/®ýVIu…ŠÙð‹Gç&Uº4y±ìÝz¾l—Swv`§3wa"¿ì ÝWÁ;½’éæí;2òtâ9ÝE /£ç‡çók5»×_ÊáòÍ}9øí»eðjyܸme´az÷˧WïhSO»RW*gkp~þú$Ü`Û;ÚdcëQVI±ž¬ñ{¤y ŠÝl㦰¯e'EˆõR‰®›äGîuΘ6â…8¡ÖÕˆ[ªeÿ»äkÅr=%LQ%ýnAð ÃB2gœ& n.“Ãû¨œ3\€MÒ¦œ¾S¸®Í,7þÔl„À¾H¦ý2Ù+ã@Mæz&5¼‹‰pÖ* ‰áï6Ö•óœ;‹×©Øé“àHµ9·yWDw“¨ßˆUisá íL;ù[üR“ôý¹F1.×d_Bt–‘ëSr„オ§Ñ¢šÅS &ÒÛ8 Ó¹‘ØÏ¤Š6éÂFü㡌š2©í“ŸçÏFV!I`†ò†˳röû7$mwVIx Á¼b´6 =Æ]º< ¾¬8C_âÞ½»2rEÆZ=K]öiR•_®•¼-ØBTå±^T©'Àl0\ žÌ½Ãï&Eª¡ !'‰mì.ÓsBX©öì~ž:ÏŠa¿¡`‰ßÆ ª¼marp‰p¹Ø¾@x%@t®¡ÿЪėQ`$¤.#¾ÈWšUt}‰F:P¸¶ Íˆ¿©ñ«©QbØb¤wÇVxÖãõ<޳[RûP»Œ3¿tÛž8&àà3YH2 ưh“f¿îØrL}ë˜+`ì-¢—K6Ô]5[ë Œäö+–vLUıu¼ÂÂñ7ö§Î%Ü4Œ§ÁcH_&Ï„òdrü.8ñ91B‘)kÁJ|Y‘ð˪ÿå®ÌÌÿšCZu~ihé^볎Ž.jÚ\ÍÜM}³Ö¬—tÏ©Âäê<µ~3iJÓg×!†T”µt›²óXÝB‰«È¶j!1;‡*úâÐ HéOíàæëØwý{F{4‘†ÏI¾ñË)RÀ¸ƒ¿“=­z‰É$ÉseîyÔþŠßò+ŽØ3ì´ñÕ§C nþ›¹€žÉ Ç2_‰Ó•Ä@U×:ºûÄSÿºíóÓùŸÌü—2x/ãDꔘhÂsÁ¸ÇœMagxgÑ~Ò·ü¢(¹HÄؘ̱…þuãÄCõjº.©cmÝŒ‹ËÚ&QÁÈÖÙeg«¨x,¼¸½ Úo|%Òƒ… ޳‘^1!pïØ(ƒÓÅ&W]]4'#¯T3·;ŸxÄŽòûíù¼j¥Mó»uUãRê°«‚b>OãÕR"ReA„wfÖí޸髋ÔÌ”W‘Gèy1ÄÁЦíûšókŒ`ªäý,4ãÇÁåzDZe4Ù.QO§êì RB«] ‰£¬WÄí4Œ(²%òîvÃî",w{]ˆ5|;‹êEL]¯:‹Ve‰¶óPùü•žáåEzb­Ã|€+Ã;'C¶U”V•’¢ft¾!3¯¬ˆºD×#êŽe¹¶]„3¢FÂïØ~/CÉšÇz—К ×£Ø®[¨­ój£FõÃÕ¶-&¿ã7K ®@e7…¨‘»˜&Ÿ°9Òsöç€ïÒ—âäq^¨ËÉJ4¹”¹Š#œl €×Á>Ôá¯lrÏ4âë>e53—<ŸÜ#Û¬æ &Hîcq)‹îõ2²ËJP‘·„\Òºv»RëIyuA+Ï’ÞË Æ’ûåF|]z»D™ñ‰Þ /v;~¦ÜÒÿä¬}§úp ‡ª cißÊÿ³¤TxÚë¡+ìâ›ë.o.=ŸH,›ü†|Ø©$8y÷µqš¨™Û†pw¼–]ø´„¦uÚ±Þ&¡@`¯ÒÛ"¶Š¨954ÜF_Á³ÔNzY >Ì I¤këÕbqÜ®i”5Š/ÊK-ÄûÅus«3±®ï^Ôäø†ÕFX‰/"‚´­³‚4Ï(Ý"Hßð"·Ó‹ÑóÎÕAR#æŸ)¸§™¼bɦ÷Áq6Ê‘ ÓÖ|™‚j?BR$­ÉðnÜî63¨‘ðÖ‹h~»=2\Í‹™åg¥ßȳ?‹ÕšstŒµ‡G®ìƒì-„±+5ÊW×äŽà.C [3å3-™”Nê£ÝÍZ£ØS¤¦Z&µ5˜¢,Ìg¨4tsm(-qJÍvÙplÊŽÍÌïRb²1_™=ƒÙ·?úê_j'éö¡XT[[0ìS³µ^㤇[,%K¾¯ÔöÎV€¾do\*±k;RBlϲVÆkò}è»å–N[GÚóÝ8ùžõê~ðV,8¿âóÍ­QçmdÜ”»#µÎïoÕ˜Œ¿[üYëìVqNPuk °d¶3”×¶#ÝiŒà¨óöÓwò­Ìë cn! ÅÈËTÙ•ze“í¶|'®BÆdØÐpÑZ'nbÎïßJs“|x¹ÙÍ@[Õ)‘o~¤ä³â&|Š\mŒ\_té¥pÅ©¿Û“Ã×â"…CB©à f£ò~Ù$ÚšÓß{¹iqR@eôd¸ö¨£!,¼Š³9´÷ ,ÄŸðô¸”X÷x'ßgû?; 5ß‘•^”9ð“šÍ¡¥þè‹yСoÁÔO4µý…E[‘‡òýI>HKØú•ü®,¢ˆ¤Ÿb¬˜8¨á„Ú8•:Å~LÈÎùœ¾_ïVïŒÑÛñ½†¯]ƒ^³f¼Yƒø´BQ5§rŠl<ó š~.;P(‹ëHòK9cÅyÊË©—½a'ƒR€ˆAè‹¡Ø¢$ûâš6D­ wn Ô‹hS2ãu&´…ýÓðŸ¯ym{?4:ê?²h€7s/™§C§ >¬Bqâ 7ëÕk¸kp ,õ&mI~]ܳ2ïÀQnU²ŸR²¹Ø(„ÄgÆ'ü€‡/MÆkÏ‹Ø~ñ7êJHâ]Á Û†õ°ÀEËímò×QKºLua}ôøÚ¯ôÎüöÙå²)ƒ°IÃGE.“1cEÁƒB3HÅÐK«®~f‘ñÂ%_¯À5|F~ÍÝ5qÌ](vÁ¢Á&Að‰¿º:CïéÃòIR¯¾lk×é›8ÑëŠÉŽÑX×súÍÀ·:KÖžoŒa"U cܾ* øm"ž ¦Ï¯NA´éL_åHÍKû€V¹’ìíjš$ݱÚïé²?¾ÞD¡.ó^'f¸Ýðñ—£Ÿ ÇpÓp¿Ý*:Õa‚S=OóøéV/ñ úoÖò_¶æã…¿Ù'Ç´ö²Ð“Ka„ÜÆÙ{çwjïPâÙŒêWQkrÑ!~…‚ Â;¯7¦v¯Óx/GPÍ©áSó¥D„†v¬™Äó{Þì³ ¿Œ3À9¦:>ÇE¥ŒÈÁs5?´:eXã3!v_Z&تR?Ï6Ep\‘,”„r{JãùøÌ¥, )þ*›BÿrQÝI=Í«<³ý¹ß²ä å¦8.*&þt/R3tÅf%281çEÍ í~M$Rù›HJqôæB£[Ä­ø²¤ÍÅÛÙI¾Úp´üìMÀÈüQç×®>G„ÿ·Ûª•úåv…MTTöŸß”¾«¾óî3c—*Ò½ U’ä ¨’1f?/ê‹Ä@Q‹|毧˩ptÈݵôzËøë®› ÑM4ÛpQì±Z®‚MÄÁ.lÀ>»nÝ(YíLN{2iºè?œæ}°â w,É'ï9ÊüCµºÃYob…è‚o@wÚ,˜XøŒY CõüAóõi·v‹´ø7½¾ Ã×tǤ×Bá5âÔUÐsM0bâºÃ/ hðEA9qCµOš¹aAþÆ#’NÅrŽ0ñ#Yƒ9Øé5CÅ^°?…!&ç(–²ùI¨!/°îukµeV:‹f¿ªQ"±ã›qð– é2Àð‹MÒÎ>=åô‚¹˜f_V9h°hžCD¼ŒAý†¼=ôøÎzôBgÏõ®ÇÒ§á.Í_ÇIÚ8N…Åš•hËwIm¦_"r}B¡¢>kØD@²¸ÏEÃøÈ6îe¢«R¾”o (w•øòxvk‘IGc|–6ÉX¤BlåßÎÿ|-ÁaÞ r©ÿ@zjÓƒº•ºE~‰§aÙ’~ÃBîÑ߇"üœƒJÉT —¬Ã:ð4ÿæ°Ê” qf1'R»uHDµ“fö9¦ó·§?Rj5-<×"Tèm36â±uA‡¨´œõq8è£(æšruMÔ׬2Û0A2•ÊßXKX¬5%>Eä~,¼RF+šiÅ9¬¼Zz¸Á¹G¡xht±þ W/ ~RèT‘¿G ¹`ŽïÌŽU'À¹ê›YHDJ‰!Õò±ÈQ“´D{ekô†•±èãĤ#ùþÚ¯½ãþ´–Ù4-_ã¸,Q€‘‡Åæ~œWïÕf§x›óâêò/”c´×Ò¯wÞÍîû+ÊE¶Ÿv8FRŸ¢0;ßœÆi)ù.H––ãËG ¾òä[Òt**u5Äh‰ÜUš™#…¶Ò°/1ep¾#-} ä£Þ5˜rÁC”͒䪔èš$&ß³| •mp°]w¹É²~ëÍëÈúz3D '‚~ƒ"šŒ¦b±K²«fX°žó=e0L“í²Ì^œÛ£Æ¡Nžë„¤ßíJX„`ê…GÀšå`"YÇW)dè@VM’9&¬&zµw\ò‚Å8¹`} ß ¿„æ £Þ” \Ʊ{¸“t¢õ PÁË©@ vÇwùñY‡íÑÚçߨ•8»'ã”‰Ž¥«_OIÞ¡pœƒ;¯ OßÕdÅe‡néãZ.$ÉÖIÿpT#i鸲‹RËÏ_-Ñæ˜°ž–Ïö¯6Žpn5]ziv)R·ª5aÝÑ‚´¦ÿ\ƒÖŽ$èª=|¤¿35ÊœjJ_ w_w ÌëÉC)#2™ š¶Ô[å¿ÇTóí\›’ ±Õ‹Ä֘ű@äJjü¤w°€d(p'jaî±Üš"®õcŸ‰râê ÷Œº°PÊFò*JÛr]ÿ°Æ}Qm1eÒĵI â‹Vœ^(ô?¿9Eoš™ª¼Þ(ì§ÙÔå(dˆ wÛÚŒ±Ÿ*j¥Ca‹ÖaÎÄÄÓHGÞ“!€‡´|,£ô#iÌz@ÓwéànŒó~¹î"‡²åÊÅ)ÊPŽô矀»øu¿ö‹‹·#jün;”0fLÌxßà1ÉÔ­X®ó½÷¤sJ±¤]ŸôØ®…©¢>ӕš7ñmÈÛ1¼s9ºê7òèâ§)ö øuôºfSÖý©ˆTÿêÖ“ò™Qt¡ gƒ·ƒº(7 AEÜút÷ó—Æþ#4vîGf5©þ»ó2 KOÞL9aÏ8–~ýVPÎ×Þ ¿²É-ŸbßUÅÌáÏÃz2åqÑÊN´ËFhÖÔ—C¾^ë+ëbõ*×Î}þžë-°‰¡é^ºÁ(Äi±¬à½ñKÛø|+UHSÃþ+Þx¤q7êÌŠÑuâÃmòe™ß$÷U/¢u7©Cch»üD,L(¶;åJsÞÜߤ9&¥¤êFñ¢©È|žÕâáOäð0uÁSë.ú’ûã¶ZQp¢Ï#ÕK%¦Aቋ%KävâNX·g ê¾­ÍnT3¨ú¥JÿE”áéÍ Ëõ¨ú%ÊÜ&ÉÙÀ="Êc\1tCqLË(³‰®ŠAµøRÚìÈ [ðºs¬\rú×±>¯›ýÍ"<©Y„£ìIªÅ>ñcwÓǦ‡VýÄ>ö:èFWâèÌl2.bû5;•†§k½öô¨è\õdÚîf*®]çf%œÕض½i|G­u¢{ÇŠ£ÂEG_Ä¢=ÎHÎ *—¨˜7º°ÿÜ&ëÑÀA¨ãkii=Á®•·xˆ³Ä¤Kâp¯e“^5KvÂ^ðñÿ¥:–jØù0W‘{¾µ<§tǾ<îr#¥ÖâíË ”ížoK·lÊŸø.Ï:©?½øäNxšh4FëÚgDʲ*óø\†©À²$È—Š–ç½ËË̳¤úˆ±ÉB1"ÏýogXÎ 9gep)¨CÀDëö‡KÖ3ß³ÝËœz!M,îÓª¨9ƒÇ]òX§…$%KýM¥Ø<Õ¥.GpõV"?BDõXÍûéÇÌPbEÚ†ä< ±×¼C6ç8˜*!Å &åÕI©'¡÷¬µ­)­aírÈC¯õëâð»>ˆÍŽÝ=Úi}ž„nd¶”úQ墧gæiúí>¼D`üÖM/€Ðb÷c)ЈåÜ¿_1ÉMÒÒ­.Py­w¯-#)ºqy9SÚOsÕËÅÝs›ª(‚wfî;tôký&IöyÏ‚D)ƒ§SFo ƒÖ‚Žt# e2q©¨òÏŠ/³5ˆí*,~‘)óÒ¿hzµ=üSVÇ+eŦéêÚ(ÇtÂo5>ß— ]«|à&1Å{¦óŠTÓQ°ŠN¦\m”›Ç{¾µ©Xy‘Ú«±êyŽÅ:Ó+¡öjrôõÉ:KÉò÷¥|ÃE·[Û¥ á“ÅaòõûKfãpø›*ãww·ðÁqÇ¢LùN¯SÐYvªvùí• ¤¯[çË7!ñR !‡ó›ülüJ“‹uÀÛP¿þÁظ£¶žQô2Ѿi7ha¶ÈIoÆuÅŠ<  ÙÐã$‰!6$WûUÍ fÞPI`ãÌ/r"pæKs~Iz—‹q—`Ûë “üÇJn‰óÖ,Ê·º…v y÷¢"ÏŠc­8U}¯ˆÛ(ã[þÉ%®Áöáæ5£M­UÚù³iï—ý‘Ú9²…XfÅñŽ:ùŸ;Ý>ê+-xî飓!tþ²§*$k•ã8-¼{Xa†”<嵸Y†B¦–1eÔ«ã h1‡ã}ö¨,Ëõ„Gçô£­üî’4Uö·‰êÌóÎïô¬èù¿ø~Ä%Ï^Ö“Ó¥¤:)­Pð²$ÍØ’Îx‘ø J ÌrôÉ1qýÎ=Rñ¦_Ðß2#‰ÊbÕTmì÷îŒZgZÐüý/þ¬xñ×z•bTÆ1AÀ»ÏßõQʾ! É¨“ØÅÒ"!Jøí£F1ÁBáù{k‚á endstream endobj 233 0 obj << /Length1 2872 /Length2 27904 /Length3 0 /Length 29466 /Filter /FlateDecode >> stream xÚ̹uPÜÝÒ- Á%hp›àînÁÝ‚Ü%¸»Cpwww‚w‡@p î.ß$Ï{Nòž{ª¾ûç-jŠYÝ{w¯µ»{ÿ†ì½‚2 ‘PÌÆÚ‘Ž‰ž‘ Ôwµªí­€tB6–FfzFFVx22a{ ¾£™µˆ¾#Àáh 7tm¶032rÁ“ÄÖ@{Ó`à :꫸Ú™”ú¿‚ƒ#¾È ´61³R¶Ûغڛ™˜:þŠÁN÷+ÀØÆþ À/ ‹#ÐÚ”ÕáWP!z€”¾¡…³ƒ…@ßÚ E/K³qÍ”6Ö ©¾¥1ÀÆøwUeQ%e€¸’¼ª‚2=@Í èh­šêÛë:íÎ@P}#£xKè[TL —¾µ)=ˆ¢²“­­ýÿ¨VVQ§ˆÊ©ˆ€j´qUeZ€œ ÈøÛó‹è @ÒÚÈLÿ×vYQAMQ&†_§`|å4ûÅô?äƒÄþ¨m5¶·±ú@iêèhËÍÀàììLoâäàHocoBokIõ+Š©Hƒ½ôÛh ü}ÄNÖF Â8‚„üð«À3CÐY‹;eå$ÅD•Uè@§E÷ëÀéþ©<½£‹ão-J¢‚"²¢ÿÍý‹ ™%Ðáw½~Å2ÙÌҔ샨â F ¤ŽÿV *Œã/–ÿp8 @ÿ]ƒ1ˆµÃÿ,u`ø¥„NL^N…NFRXTNYô7Kû?L~íý¿Úø¿ŽÎTßá7e€•¾™5¨ëô­ AüõÄ¿m ЈøŸC„ìíI“ý—ËþßêþU!mKwO}çÿl\}k'·¿êý¿Kijx3G‡"ÿç¤-A&Pmͬÿÿk÷kï‚"2 Yec0ƒ^Œ )µ6¶±²w€ÿÕ"f  9ÚØ»2ü—Ñ·°¶q¶vÿoc3k£_§ 0r²ePµ6³sJŠüÏz þÍè`í@£lhÊð+åïAøefúe†§»­-ÀXßÒèif ý‚wwÐÿ jQ{' §ûߎÿà™8Ff†Ž ±Ý(ð¿£KZÛ¸þ1ƒ˜üËõ? Hùû6£]eF6Ö–® ¦5†g³qµ åÿë—Ѱs²´” ü?ËóŸ+õ­Ì,]ÿϵÿ±LøK<å `æ fæ4R0s44ý§NÿØ%õAC&hmb Õø·Iõ×Åc šÐ}oöëq cbüO¨Ñ -¬¶\@ÐñýgP)10HŠ+ Òü—&ü½PÔÚÐÆÈÌÚÔáì}{{}WxFPg1³±Ü™@³btùÝzzkGЀ­“£ç¯ÂÂÿjv6ƒà/Ó?ˆÀ ôq„ÿ .ƒè¿#€Aìb0ˆÿAÌ Ö €Aòå“þƒ8 r(ƒü¿'(ƒÂÊ ø2(ýA  Ê+€AååSýƒ@úÔþ >õ?ÄEãqÑü7â­Ôÿƒ@+ þ ÐJÃ#6ÏÐÆT÷Y~•ŸÁè/Rü ‚¤ÿÌ hÆf±ü‚ŸÿZÏŠflùgÁ¯í6Nöm1ù ‚ŽÃôßt¦®¶¦À¿ùlfAV‹¿ Hå_ÄÏêd±ù+H›ÍŸd µ6Öqg‘µý ‚˜ÚýALÿÒÁ¢åðG'Èé`æò—TJÇ?nPbGS{àŸd Ébpt¶ùkH—ÓŸª¢ÿþà`hcÿ7EÜÏA翪 úfPV׿ HžÛõ Hn@ûüïáVøõÈüý`ü3íÿóùè7Vv´·±ª›>eþµDVßÑÞÌå##ègÙA?ÿz§ó¿ýyüüµ[HÈÆÅŽ 4t,¬L¿:‰íWÅ8=ÿ×^Ã뿟 ké_ø×º á—æm yÌ“ƒJ¼Dó&K¡È¸èÊ1ù5¤b!—R'Ûñ°E²7‰ò}›}ÒÈómd$¸u¼|­ 5È0,_V[â+&®Œ¶ô½d½ðDG²ÔèUýÒd}J;‰©~Jeåj±N§µÆ¶TG„¹Ú¿ÞG2¿¢^$k—¶®ä@9Ì25½³·DsYDÁíÀ[œìw|½¡ß#¸D=ó)7sD Ú¶û+únfë>ÿž:¥!#zgŸ7¢±$xƒ<ì7ö0"ûÏjXOmÇ”|a"ÆFòÈ=ðx~q­sA‡;ÇEãἂqã\SY¯ã'3à–W-v¾dR_™Vn¯gj^5ø‰œø ƒý´|ýÅ“˜ø‘,Ÿˆñâ9H*5Ë £QØ^¿Ä^c'ŽF5áHrzk;|–èÏxsÞ`™"nójX†¬†3"õ91·IëzìØêFQ`朢€R÷T´’Üξª6éžôë5^áP›ŸŒ¬±k@[Éú\ðhøvü[Óà¶BDÆøïô‰›/pWùU~¬²È?B_µ(c„?SG ìé·™Ub`bpíò®4°àf¤ušöµ¦·ÉMT…‰öý8À[“xÒY‰™`áÔVÓtëIz8œX7èF`ò³ú²n [Û`§þô…5­JuÂ~/ ø\ájÈðà…ÇRW¦ëg¨—±iÍy–,›Ÿ¼ d:oªI©W¢:¾|i7/ÈÿàýÖ6³2-[ešKÁ—¬cYŽ£t«Ë) ™P‹õ Žn³æ·™7Zí2'Æ¥c®<'dW”¼ °<®Ö/0ख़u{2>„»;ýþRˆµZ¤”_³Ò<ôeBÒ|ÂêIïúçV;;**·R‰uwâü¿DÒáæFtç„R~¤L™ÌÑü˜¹– ø˜C¦P;s.E²¿B†|@^šçËÞö°Ü‰Ç¡ÁªŽcXA=°Å|üÁvÃ&먞4Ù”œ˜=¡{~¹—ä&8ò Ý N•è–íÈ$)²Û Ç^#æìz_FÆ?gsÍ8¹ÇÓhÏã:R‰ÁËEêò*¹?²£ãI<;4jŒ8vªÎ7+*•Åoå(Vƒ›VóšqE ¡X…DŒéHŽHÎÊæÅb“ eïÜwRâ‚Ó/CiÅôMžªþrwMÚƒÓfŸ‘KÊуÐð k“Pµ’%E05îâ»À ¥äG¨'–;Ž˜#Ïzýæ ¡„Ôäþ ˆ·<6m¶ˆnàA|²­^­$þ+1åœü"ý¨?"DÏãû‚ß™e`´QÎ&S(ëf¾dož îˆú?o9ïƒ}}¸ÑÆLRUT’{C))µG<Ë÷“(Žxd›·Á…žõS$–ùh’ÿe ±íDzå^8:Pš$åXuùÔDuÃ~1š cÑ zàÕK2œGÐ@âªÕ×Õ1ÌîÝ ý¬×¿Ã}uÎe„º©x{=sz[¶ŽÇâåȰÜ*7dZÜNÿ<¢ù>Oš`Z¨–BÀCÎFsGJ ½µaË*ÍßWIó”•!•N® ˜ú±%Ê=”ï»·?â‘a?ËîsPZ·)ŸVñd†CE„G=–ÜXtÊ­Ža à'¨A†õÃÄ‘^Ÿþ|üÙÛ´U¤Ñ<S£a¬ÉÛ•Æ¢° í®LI¸Ú¼œ”w÷1R­£S“ j­ñã¸Eï~¼« R¶­+å)Êä3xž:q¯uͧ0ƼQØ8ÈLã´Œñ .iu4ÆJ«BµDO¢ìo¶y´O·åL¯gìzÌyõ~­<|LÆ%¸°ªÏâS‰ÆFˆv¸…ßÄ>ú\ú¡@ðT/ž“‰¿¸mc,Öïäô‡±å¶q-·žÔ+ís‘?XQ‰ÇžŠ©éó%GtS‚Ñ›WTiϹ±ÂJ8Ë5ƒw÷kªGªòR4Lóð¿ÃuMy“\Yð.óÃü Ú8¢ð|¨A+×mWýÖfºb³®©ÎOðZ>Õ´çkQ3¶;ëTÇÄ%mß ¯{lsr,ãðMAôì»ÍÓe½Ø—à™.¸Çè ǹÁ%é•~x”Òx^~½·½–CÇS8:±'ú|W,9‡£Lß:ºX5 ¸&`®-ÁCMÂÑ÷„·G,y>ÄqQ@šÃ…¹Ñw÷*˜ã^±¢”§ùä ¡•XûÓ}1f+5Cìe4Ú§¡äÎÏXe4ùvºÝG¿‚·¦˜;BU%©‰{UUî„J¢Èß*„µÊÕƒïés´ç`ñŇIê‘«®ÅEIŠÍ¥¨ ö]µz[ ˜‘!}…Ðç”@id5 ÅçoPþì¶šãÈæÝÎêã5ã< H“õ:;$þU_ú/©`ÈÎψº}Cëˆ.ßJMG~MAOfàšì^ pXRù ]» æ¿ >h¬FóNäúùeè8\bé¬Ç óù cV÷+3†j-$¬ïŠj)Û´G›Ê·ªê zä5ð[C1£ÆéîP]ç8Ò®òœp<@˜†,4/?Æ T?/YEPîÛF4M݇½¯›»t{%ƒÕ¢јySDú,0’ýe<Ý¡äÚÚà|¾‹¹+7ÎÚÜVl®´( ÑüÞ³¸LÊQE•NÍÜõ1<Óº¤«ÝΨܰG‡à”´£c$ØR‹Œ|KÅóÓºÉwï³­aÞ†o¢­ßîb"öÔ _]É?SðˆH›]3@’ÃêÀ;-s6ƒôÎç^ n ?ƒž/߉ìÏÆ( ’Wˆ²ku73Ï)ûmóåôš*ªtísxû/âm‘âbeÇPdݘ团šV2ß„Êü­Ê%`*×?Qj!Z>vy~x‡qéKb¥áô¬,>À#CIÅsA_«eD"Ì Ó‘£åÈ–ƒ,;évCb‡ÎǪ–“˜N³zƒàæ{Íë¨`ñÒsiMZb7rý”?‚­7ïqHU ÎˆÑã>à+VÑå¥nHÂÊ»+h¦†¢p>Ÿy3¯–Q‘ê:Ý;pãT32© ¤…|'¿sÛ _{c*7ɪ>åáëø¶jÌ5Œ"ØW˜¥¾¬ž‹Ñô!CjÙ©3•{Bd·~àŽÏf(Q;¸9-‚ IÉçö¬õ¹úbPéû É-Úr Ô ®ý€c™‚ÄÓMt˜åGÑÜËÀbéFiŠïêæî‹lˆ”Ÿâi1—çŸÞ0Nkm^â)5ä`ÕHãl;wöGäù(ò¶€€J{¬,¬\ Ú™ªœx_•=·„C`p†µ®’} ¢¯!‰£m¾‡^Ù 'ð,kõH8>IØ+èPo»®BEûb…‘Ž^P‚toR1Þ(V>媈ûÙ‚yºå‘²¦E}BÚÄçÒˆÞÚ ^e(ˆ3¹ÔX¸©MÌ a½ÿE‘”Qù½NÍb÷6 æùbñ¸ìù¶îXsVL´\Œ!Ž ©Ö Â×"ûÚ¯­Å2ißàøß+è_sz…^Fb¢À6A½ßî½<½“ígôͬ­`ðÊ·ûùF˜ÿñŒ¾áKV­ÔjC0ý)e(ÎDsÒ>ë"Š«ê59œã¾´Î)$uY‡ŸYzÐn$™K¹‡”nx½k=e+Å!P:csÜÃðéÇDž°ÿy)ʱ+~=LQB–±éŸ„¦Û[ZfuŽ}ÑWð ÷ ù§àFãDJúµ;G¯˜4'"™ øý%Ô.nǾ:²(¢óŠ'»¬öö¼ÈE=Â0ªs¤&3öõXá[°'¢OÀŽ ‰J¥œÇ’`¨ 0æ/{‡:á¶Ó¯¥ ­(è€D²Ó!=¦[’Ñ1:Ž;*ø] Ìv÷²¦¾\ËWn³èQ­_%qõ+®‚Khü¬gbÆñ($ÉÞ Ù»0 ±ÄrÆ|1äzüÜáló¸-õ6Aa®+J¨Ç}Kú+ "â𲦗ŠJhZÆ…I¾Á̸¹¯ê:¼ï*z™¶3¾Ý´Ç%¹D4ö^‰tÈ Š)ÛD¨7hñçÜá°ä8]¡£ìÇÐ ¥)ñé%D¢t«˜Ø;O~wŠ_}q+£½ç`tŽDFÞ -œÂ`µpúäÊUVœÛ5t9j Z“ˆ‡ÍYi_s%™7”c0äP[*¸æßZ¦Y-ñ¢mg@®ÀàÎð ú›lbÖEOhZ'£(ÅÓôÌOÒš¿Auq FW9N=lÌ–°ÀˆåÝ'k6¦‘|6-5»»r‡M-©Ì¨&Þïh[:;ïåu34|°ÙùÈ‚A€"DçP': ½ü3úçÍïÝK7öÙI¿Ìa+0eÙ<Ó ÃË»ãÈ}áÊùmò{ÿƒy™ÃHô›V)°5ûÕÄ@¬õOôiŸþäöåæñ©°RM×)bø’±l“D7ẩË'yM¼¤œbèqi°Ç.­ïÛ«÷H«²¯ñ¢h$¡ŠÑƒ]‚”‡³tgîÜÇ,œ¡¸:âºïÜö7O>IvVÇtÔëb6ï9¾øÌÙ Ár’ H2Šƒï¡©«ÉÓí£MÀS\ÉqGnëEÛÎßąñÒ@L]ØTªÙ^z†ðó*wÏš`ÀØ}Z&:üQ¡{º¦éQ¿>ÐO$¡‰L¹%°=/ªWKÑ5QÀø~/e ‰¢tÛ('îû„]'CÙ×ÏŽþX\3ÐØé8xI^´YK"ˆ‹tî’MÏQÈb½¯ó>ß|бZMʼnÉZ*ðAÅ(¬‹ª›r­8Öï.Aµ¦´ áÝóãÊmÔ¢äË@6P Ûî†ZMU»ÒbF֫ܲþi—-ð6¯1È&n؈èí×ÊM—]Ì×F<»·ß-ûa IžE4‚÷h‹”'ß]_ò¶W@ïÀkj8¹¤ 4Ý Û®¿{‰f*xfqÒ¶ÛF''ÎgIA¡O»#gQA‡µò Ÿ8eø¨Ð>I9ÓE‹c_¬¿º©–à̶8Èf5%S«ykAˆeiæí'sìv2LUµúñp’^ „Kdg’æ…l-H†A0°XÆ÷·Ð|èÌZK, «–&É”[o…ƒl©»Ö*šˆ^Tz?wÿž«ãœàHá#`§:Ú†mƒ :¥AjΡ‹Óúž×ÕZLdר»i}àDXׂ«Ô¶äTÄÆfzŠÃWWdF6ǹæGð¼ê…ùÂu+W÷³|'ƒí‹Z w ’KU(­i#i”i=­¬KÌZ  4åƒU´2¬Zà!ÊLrÄ` V¦Ú‡¥½ô¬6d“jÑ\r¤Cã*S½¥,f[½Gm¦˜ØˆÆkkB+»H…ql\¨Äôª™ò¨díÅX+þÎ7çg5ÖLÇ*¹˜'‹²£ qJ1š·`˜4l·µýŸ \¦Bô±®ðô²î¡û8NÇNd̪^îÒ>·©€‹†e¹–ãàEÁ=qZÉ „l¼ôÈ#2z‰±$Ènx-l—ת´²jLJzXúΘÙc< €`ñ»ÁÏÍrz+Û;¦¾—(AVªëPÈ£Þ Î÷’È\áóÅc%Ýl!úü®ç%Ž‚p糨TPvf-éúªï¼ù¸5 ­VJg:½Yô Ë«;D|c™ƒyªÎ©.ìb°:Û>É>æ³/žòË b%V ìmâÝûK¸ô1×t ”ÏeT”_1Æ¿pÊĺ¡Ë-©Ò ¡ “â´¤QÄ1×Iu™½6O†!1¹2®å„­5ãG5}Dxä¦c$¼Í`DÕ:©Cüa­ëè½à’ Iký!-5ê4³ê±=`Ú}ªl>hŠ o®ôLò}Æ÷èEÁKŽs´Ý]ÉNÀ™æ·î1ˆŸ§Þ*&®^”tÓö,Òu³E\Ú©ÿ¤úzÆ*UID·¾ãs<दÉß‹†˜ðmhHrO ’\ÊGI¼·(G¯ß7†fÉ¡A‹sdÿá›GŠõ–Ú@™ UDÖ5êþ*.9l'ÏòW h‹³xuÈYÈŸ¹ç`$‚åNÈ9¸)r)"–«;燱ûÌÑbÒ¨›¦œæ¤ò %µa?¤ ¦ØàªTpq5(Њ­I¡–Èã‰K2Oë"ÕUÐ(™xŸ .ŠdëžÈoV’íœõyp&ÕyÊ=«Õ76!p½òšJìö šøœÝRv‹Æ€Q·Ò2êÂòãû/VÛ‹Êp|ElË&f¢fûy¨ã_'8³ÎÀŽ”)mŸíw˜Mðï!éíGå™c´ÙÑ´È å·$ h-¿g•ã’/Ÿ¹ÅçTè>ƲõEG;Ìz Ë~Ë_ï %Ζ2ªôãÉ9—lŒ¢Á¿ç@-!6n×¹WïgOö¦_ıûùdŸúDèÆ M?±ïÈ©ˆ ¤¯óhzCäãJl?}Í„-íõ‰Á«ëý¡<¤†O^þºtcf7â˜"©Ë!ÃIv’ Zø+CtUß·øhѾ—Â[xäk^tk4ÒÍy§?GÚöï›Ì[³lØžŸÔéü›ß ê=¯œÂblŸ}>㷈Ȇ|YB(C{å~#Cšõ&kÃÃòusj•;]V/Ùâ#ªÌ¶ ¶1Ôàñ&áhâMªvÚ â!‚ùšÏ‹ ·ñD¤Wå<‰I‰'Æ)€ú:,ú,8 ÈhÙ€^³åE|avÞƒ75Uh¦.<°¡5‰Ãü†yu£¸§&iÌ}Ñå4¯¬í¸™Ga„ÎZÂ*oUÊ”©É’ëÜ€q=<è>y™÷¥A5jÏ ?ÕF%«•”mž·Ë("ã!ýÕŒ§£0Àëñ.K¬‚·K÷¡S^ê›_MÌÀKµúS"/¤Ë.¥ý¶PŸp÷Ê’49hî±ÀTîûûs G½O`ÖùÍY,S¾ÄHÁõž,ÿb‚S‚ÅñÓUgU8›fá³ìçÂÊ©åç&)åmAT—±·‡&õô´)ã׈$–ŸÄ%c±t×=&3Y»?ÿË?\àˆ{ÂóoåínÆ{¨5X¡KÍ_EÚT3XÚÅ8oÀ§LЈè·8B¬ |p7†•$…—©0tâÆº>v½ˆ6úð*´¦ %Ÿ&ÛÛZP!Dd–U§§Òv.¯½œ¬·Ç‹Ýª G)±kÓ~¦Æ‹AïpŒtiÚ¨tp¡2@ aÍHáÔoúV¸Ÿ!n3ý¤ö´\èìÎôµžTˆpÒuœ`ŒQºóe¡%{šC­·@kíîEŒ]ì=NoU ;z}`+ᦺI/j_kä[û{è÷(àùo¶²=‘R<ðÇ+vsɨÓzß…ƒ´Ë¢Â%ÌV4 ­ ºhcVþæe‹bD"÷æøY˜Ö6Ûž3罩kDìì¹ánòƒ{#¹ºþ*Ü©[ÌíͯÇ2JþBh°8|ò±MîÄ­X4[œúaUÜ iÓUºÛØï(uW»Ã)híÐkP£§r}¸\m´¾Ö"nÊ-Y{íQsÏ•¥©:õ6ZD˜y»ü—æÎFI$ù’ðøÚ÷ùS2xJsÕ]ý²M•×ë,¡zuYW5ô×+#¸"°2ÁÜ,_ÞDm1>ͦ¯Ûõ:x‰´¬¿öæ[y¸bŠ dGIâò§r /æA¨B;% ,ºJ#äX—牽øâOKž°—ö Fç:ètÂåÃÂVÓž^k»‡ŸEˆÙ¾·(b;£Th¤ÈŠîÃUxw+¢<È Gv[a ,§ò-îäÈ;ígD”ÚDP_lƒ‡"Þq’ÍuÖó'\}’üÈ:¹í$í[ª¾“<¸ø”PI_Žø: ¥6¨ñUPJô*„lÇÇ\Ý©–€ p’eÅ)ºQ½ÝJžÐ;/TÍœAKå%H–®<¡jªæÔƒø¸Ø 8\Þ "C‚0ßñ¤¬7\^ìja&CN¢Nö1ÞòÇ*z_;\pO“˜WF3Ê7ñ0ÂiàÉnáàaäûn_Y¾^6I~ÓJ0 tÊŸ–ªM¡‰gY õß»DÄ6ž÷·QU¿ Xrà9 kêîZå./:àIz^®¦HñQe~oQØ8øäkÚ‰ø!ýì²eGÓÞsŽÑŸ¹)—4wA£1}-ÆâÆóá¢ú±2-A˜‚É«M<àõ_ߌYL “²psÚsõ32^VøìïZl¨$Ž>!>Ê™ ±¯aeP\¿Ó$ñåN+òzÞÐ3äo4{“¬¶²º{&6DöG„_Ï *¦íK®¦cFV÷ƒVÍiɯ‹D]4=Tt\“ßgb3ºäÿOhç­Î•äz]ñÝjrääf ø¤‘*ƒôîKd¨ŸæÊeQMW´—iqW( b¥úˆiCMóß™"Ç~ÎÖc®SØœkEŠ|ÅH3Îä¢Ã@'º_^L~É<¨ß¬iߤ“:m˾Y8è´Ã¾ÅR\)xJzég¹ZP¾E†ÀrÅTÅíçu¹†iؼiõ‰jœl,6aTc­ìh5-E§9lÛª†ø6dÑ>[þ´ïÔ^¢Šøîƛ埔”럔)ÊŽ*!›WZd°h( f˜½gŸ<ÌíÑhƒN‚þ—áû–›+ Bêè Ju(sžß¶„=tg*xf%Ãg¯"ûáÁ¨¨ïe§³¦,b@ÔK†$7…0£¨/MœË‘ïíM…ã¿üyòÀ Õ ù3Q L>ç+KóåÊ èðø®¶“×G¥‰«È~®©¡³µ(íù¹*L*YùÇBŽD)‰ m„ïr/‘ǽlp{Â!¿ò•GÓ;±~æQ³9ëe aQ>?c~ÕñöHÊ&ƒvõq°j&"à¸^°‚!àè¥9pý‰þ®üDþnâ¼"ëîuB:riÜÞ«­s›ÖéÀ¸´øŒ[4ä´ãRì]اÚIJ¦ yŠ1 ÷¤è¹·iÃd°lÚê6e¼T®V4S«Ò&B×µŒIÿg#á‰Òb,Æ–ÜV› ¼Œñlç¥=¡ëF ;ÉÁYòsø"߃ˆö¹ ³I}|üÚp1ºƒYnÂ-è,7Q‰Ðoϯ†€üý‘u¿B"w»U×(#Ã̤ŠÏ]Bîz7A/­•]Ó(ç½j¿Í€b¿0•Š`йGÂçÓx’|G~Ý©ÙÇ>´ŸW¦Š•mÜÜÒ4ë×Xû¦tú^[(EéñŠäÎfókûÄ£ß=îhkµoצuÂ=O=|8  1æp3eýæXÙZŸÉén'1®šØÊ|¨„ ‡´äÛ ú8yéº"ëLÄäGü©Ú;Hµ¤u[‰â/dYÌCâöìÆ{ßHZ1Èô‚i}‚Ìæ«0åjHâ´¤?ê$dÒ`mFcœóÀpié¸ô'°[â‹~XµŽï#Û1I--dž,Œ´QeÎ(ŽÞÏÀX¶ezÛŽJ¿›“žáÌäüþ9]8­¹ˆmŸ¦80äÛX·2Ù·ˆ#:¡m£Ë‡âåì²Ã(L:úܲËáš+ÚÞ=ÿ)Ûw¸û`€ê£o­—°ÅY%áí3É`•{WÅNìáA?ìtlÝ÷ "ý'úÝ5Å I³ýLŒ—å·™zýçÒ”®1q?¢­ª)˜’‡r#9Ñš–Ô†‘ÜÔH!0Ô¼™ìœš&~‘ŸF#±¾ŒßƒM—Û}ógèšg©’¬‰ÁPÛå™çÂãååõùf"®eŸÐæüªrön”ЇÊs#²[WüÍví !U>'t—lÃJöµy ?·Á‹äJemr8JJ}ñŒ×¹ þRuQ©ÄÒ«QWqB:ÝJ¸ž¼½îŠeÃm¼‡Æm ‹ŽxãGD˜6ï ª]ZfK5ä{¶ÛdÇà£[™üÞ\BQ«N-ŒçÀ‰/¡k.'h—«õ[|c‰ž˜^i÷³Ì>·vØ<Œ ×j&\ð[ïÚ£³ÖÒÒ‚I¼ÎCS™-îŽ÷†pkÉ¿bw¨jܤga/“ßQG6½ðª‚yϤ4g S¬@¹Ã.GûTØE¯-Çù¢±ú³ÊIw´7 &|‘ë™\ ¾d¨$§=¯[äÅàM+XŠ|–—©§® J9Y¾ìî˜ÉÀÇÓ©l'¸’Ž0ŽÄjXÅ‹Ôd^Ú|ÿÕÄt)ªÍ0“qUë¦ðˆ(.áÝÓ ËŽ^cŽå<š7gîçQ¸ùÕ–‡{O€/0ÍÌ=(’ Ù›´!¯ÝÈ—ü*ujz\¿Re£t˜ýdÀ)FœLòµ«î²cûc¦G¬˜ã·›™¼ä-½ì¨ÀôöÚ‹àµÊGa\+•ˆ„P>zvÿØê0ú±‰ÝBº¾¦_—ù|ÖÞ—ø^8ÃU9s8\á[½.€8o¤Äq±6ïD±¨þ,î^t$ÓTFÎ=É%D, ñ­þ©á¸Þ[}k¡B*¶»cpÙ·WÎ`nÓ6R¼dùôþŒŠÌŒ®FHÚ:ÆÅ’‘OFüSØåØ|žŠ“YÏx±4<`pŒÂ…×rÿê½µ²yvfa.Ͻ¶w(óí¬Øk˜§ô*^ßÜý¾ðª`Sè¹–µIq«åmäw+üæf¸ÄOµc ®)öeæí³6s»âƒpU•J2ó:"“̬¢ ÕS|l²Ç°ÄH²ëU ;EfSM5]tÚSªÃê¨ûYñ …|‰5W^‰•z(ëž©N?¯ÊðŸ„Æ‰ S~VëB²kë&ïå…º–42KD°9‘smÉ&~Þþù%vΣV½‹2¦üSW¹Ý€Ó«hUK’‚üÈ›&ogÞP¡¹ãÖlGµ`íÖytQOˆæ:E'&éP_>˜)‡)Ï cŽ^ôU ;zXwn47âþ›^@¥Ù:\EfNÑxh{«£¥lR(0 dÓÇ~bg,YLÌ%0F£7ˆê‰U¹*ò%g©>ndø¨y-ppáH¸÷eÚ yÜþ N<$s^;Õúºp”sXÃȨ“¹Éu-e/ioqÆvbè mKƒ§‚7E½“ã²å-ÿ`üæDlÖÆæù].U8Q${÷’ßÞpQå*äÙmŸÌâ5â©[žª–¼àB(D=„I¬ŽÜáÏzb[ù¥g­hMͽ¤v¤ìì.ù´›<*DdÛÅ0|wÙ7-ŠÓå°l']„½D/ßžÕ«C‰Zé:tt°ôÃRüíô-؃c5Õý1XÆzÕ…ÜLÈٕϼHËÍ&h±'P øÖ¤j‡á›Ù(’U†Ìñ0Ïq,zv!ãyQEõ|%<¦@Áy€ê¼VÀáŠ#›¯Z¬é¦ûYÑñúÈeª–#{BV#BÚ¡'–%zý@Óîvn¾¢¦®±÷KÕ¢¢»ú»†ö‘˜'‹¢[Ùp/q»tßç[ª©~ëúã´+©ï!Zµ}‚¾°s,`äQ–çi•Œÿ¢n¶gëf½ë%ؤ¡?ôxbÝØŠ©ûÃë¶k²ÆdÑsä€>”Ÿ f7Ó/š×Kš/ÄCØú¬\ŒC“…‡b ^# f(Õ‰ŽÓ›ä]T÷îæˆ›VÙÁ[“×7±ãm‹gu¼Qw'l¨éÂcÞë¦g˜¥+²bz¸Ù죾æm~<½b>çjTïÕ‘Bó_]ôÖd»s›‰ÍªÚ=}~ûj–¢ñnd²ðºs¢oÖÃjÓ¨:N»‹ æcÆèx½®y€Õym“->`õ›q=ÿ€ ‚?ÞÉ×!‡‰-g² iåññ`GØ·üÅd$/ݹgÓNáó3–ö[2 h‘/’·ZDÞÕœŒ‡Ÿañ QÔöÞ$L3sØÝÆÊ‰¡£C:üØxðpÿ°|­kë!æÄßB|þÿߪ“rP²7 @ïô- ù9 6ãÞŸðíbõ6õ6å$Ù‘qì“X=Š.#©ù-Qèùë݇e©„yÜÖᨽ[zbc²©nÅÀUòV9ø z2|á‰-š8ýÝ3²Ðqß/Žá”J")]®s…+7Ê¢øFý’›ÄPƒ7„›Ð°šÜû%h0®‡Ö~\fÀÚNS F…`þ–ôßôERžÅ7:õÉ۫Ùmô7øv tЪÚVÑgü“~v¶Aø¿—{òç­óÙ\ v»Ä°²»„_¸®V“úòJ+%R‹>…W*”¼Ðëów]9ù€†'èQðGgêÜ*:eœ9T ªŒ´·–g± °ŽÈâþ4Ckï ¡šwc+ö¹ØØ|áßñù!8dù6wÙ3riÄ|½¶)7ŠC B©Ú—Þøú]ÊŒò-Cbw­Ûã³Ù!»±¶ÚEæ·6GÈp•öïl ~ŒÝ^š:HfÞG–©d­AÇ^|/¤å¢zåü]„Wc÷ØM¶"âÒÃ}C^{œÓl™Ÿm,¶äÂôž=FOÕ¶bÜòi7{Ø»X kÔ¨õôo|‰3 ñëc?éyß_äc¿ÛUFŒ]ùvþÓWÌî¬ôR€‘ÿ[—‘ì1Sá‚‘–(t?œÎ…mÎ^›[AiÓȹUðh¼!â&2„TowÝÑLDØCj CMõv”:B8Ç>Xi@1öûÅë©<éïõÃFŸl‚^^‰áp‚L¡eH\l¤PÕr4™ØxÇÀiDwû³,\*µU„ñ‘--lµpèjk3òAAL;÷ŸE¥|¶™5*æ´ÔGà¾ìiè'`Ùbiܳs•Ÿîû4N½×JlÈwïòKÅÚx'–ÔˆyAÿlÁ5&bE¡›J7q€Ô žØ‚Qª›µvé–Ñd†Ú¾ûNþ¨ƒªzݲAŒnþ>å®ÖŽT—*=ÏÆwб Rv5ýöƒ9åŽG+5 ÆeÕ6"ºž°hw$ó\Ó÷æÄ¥ï 5ÂD®HÈ›,·”uŠ*zœÐ9žà:IÙb]< ↆŸñ†¤^ [mQã0„]Ãüdy1l¿Óþ8G>~,;)‘¢5“^×úø#Il®¢Ç5•$š“§ã+Û׸* ®ˆ’4â2—×#ì;÷YÇšduK¤%1†+xrF½Ð'‡bÀRKBÀ@l3šÛŸ§&¸¢ÒÕÐz0|KÙÈ]-(eÞ…éx½à­Ê²œ(Wc§¤Lǃ«ð†•,|y®ô»÷%mŠM¤â÷.I:zÌH’ÕÎøÑ#ïnY6©(Pß ’£P_æ’ãspkÍyU 9_Œ$|ùx÷»ïSýE-œÙ‘î=/\Ó=¬¹jßÐ'k¦QæÆ`%<¦î÷ŒSðó¸øYßÛ‹öÛ­ðÝÂ5èmÃ4fUô8Æ £B h 2Ö6ëkßJWû¾ ÃTczùè-›Ï*ôá¶AåUïÁ¼È‘×Þk¡“ yüì%hµ”k£^ùé·‡ }w4ĸz4P$ã¢Wë'óÊN«ñ]áµÕ~žm| ìSµcú¯7ý/›„ðÉ2¹U"øÅ-ùìÚ¨o¯N|ªÍd9£e¾È«RòüFÃL…É#*†Ìßcôýëô<ûNL ‹ÄxÛ'Nùè^|é6YŽNw¼Ç´£aD2·µ¹8¢óYíd!pöÚùn1fJ´áž…§™yÔÁ¡å_ïJÌnÍe7ÜÇýa¶Ë‹UG?}ÍíHýŒÆº€œrÎ>ÔÅh/°Jæä1tøPô6ÑÝšd“»„²°!Ä#—œçòº0ñ$(¨*ýÎ ·BV`Ÿ Ï/üco–ØOM¨jŸ»Ë¶¥ÜÚoÙ§–6MðÊ™ÆWUŽó„9¦À0í3WÛ‡d6®Šá\f«² ø(~ãuªvžãÆOOSÈ—%ñ_šØP¨õ¿ñeG<¸iÐ5ga!µ0v<è½æ6S©¶=pù©\Šöî«ä—YêcÏÃøAƒÕ°Ú  ùHŒGÇV&ÒJ“Š é*?.ؽM³ïmBuÄy¯ŒT`‡Aß  +ýJ¢dÛ[ý´[ tL‡…‰süêÝK΄žQ¤åϸSú3TË­,¤6ˆ¤gQûºŠ+l—òL YrØfM†‘BÞG­©Tò?¯Eî µÆ–{µ¡¯°MѤ…oúsкlŸû`èIÝ$aéUœt2þDšǹ <ÂŽùIÁ-J¬š½ëaÇjå‹]Å2Ô*.¨`À?Õ?LÕÖYÖ3[LöQ]öÍ«ƒcW¨`ïÒKnB±"¿±…†w 7~!aN¤(ï÷‡"w4žåÛ‘ýÁÆ|6G•þw–Õ+÷DÖ™Ã_Å^Húüú:Ù©¼2 –­ ÂJ°ýLxS”¾Ä uÒ!·¥“SzxMŸ%2N9#@šÀïau´Ÿ0C{Ÿ³qŸ'’ÑIêÏÐ\ê9êu$´@úÑðÙáÇ1 Çv(Tã¡)†±Y~hiÕÍ Tð®Å±>»3„à)bð¡ÃùĶL¸ 9w®Ÿ!'ä#D—WR©Àþó¥£sê;‹ÉÓZ¶g3aw.Ø‘ç6º:ËÀa1{A8¬w¸ß+[£÷•ј:•:e‰¢qÃé5Èü…ú<ŠiÊÙ4<3g;T±!R㔘ԮO+ß>©ÄÈ·ìµg)3GÞx׆J¼¹Yß©ë팢Ss¹%`³–ufO.Œ†hħ–ºÉ]¡<Íœ]ÏñàTG÷öL\‰&s2¤!È&| 0þ”àí°{óÝÿ¸äºÕ@ªçgAb©aƒƒ2Qad2Õ°b£#ê_P?Úݽ±¼Yü€GG®âUã<ßlÖ#·y½fgÿƒ–¹=kçx÷1ë0ûûä‚'œ6WX“ïl?ÌÏ= Œê¬~ÑK´‘»‡kÞnÔX† k;gæRC¦ÂŸtÓb-÷îQ:Ö¹ûÏÏ>§m‰¨z0rZ¶`¹§¾ Ã_Ú‰&ÁX~*D}ó©ð÷:ì‹Éç„ÃJ¤Å>}2q¼Y†mJéK4CT_‡r‹”Ûè[¶½ªq—ÝÒ6‰VF3Åá=†[Ém5\,¸UæÍâk5;·TuKâÒõ©nq)ˆú1Žb˜’Eß ˆ(ù8c­­ŠIÿaÓZç1>L¦”¯!µïú–Þoýžxe.ó4±¨T»gWÝ&²ðN”:ë YînS¦Ü«ÅÅOðß§ô›ñxIèw³÷‚!'EF¾l§®V `»¤l åÎ;L£[ÝÉ£t¼÷æ:S³ÍFœAŸH4'SƒL:/Ãú)=ãg™R3ÙÆOlz&ô ËnOgdÖ[3$Ég"‚O7]I sØÊ}Á§!ÙÃ))2,ò!$[— sŒ¤%fÔ€OÂå'Q›py¯}•kŒ²sD ‚"ŒeSy¦¡¯åhÍr£ø\¨Ð6ÊD¨Gº1„ßÈ…|r‹ìóÁËÛŸ‚iÁÒ ¶fƒ¨S@i–‰Æ +©äÇBq©Ÿ—Æ3pw‹®<Ó©`‡$¾ÎR0Ы̘ ¯ëÍ ¤q¿èQTi/"9ÑtÂÎp@0í®8ïÉðÆo“”àâ//Þ&F_f›ò¢Š$%çÿ1#h3}¸ã}÷ÃIƃÛüìGì 2ÃÑ™ÿ$ìAü\¤î7Z¬ÏñÖ#o>m.BXöîS¯ý0¢˜èˆ|ÕMDžÁ™Á Qfܸsï ] ÿ*£˜º«©š™@d›“i›³D'¡¦Sí/þ“µ‡äºÜ^¢v™‡WýÖ1jd_d‚Ì*ùXFþ½LÄ–-œò\L!õbr’ÇÒ“ùÇØ¿i&Xt}Y£•#f½šcGÒÝ0 WH 7ä,ÏR^‰dx1„jý;Ä„*1eýâÞÒÀÝ>VˆÂ‡j£ó}$vªA¸`ÅÊG%yf‚±N°x2-ßPóž¸pÌ&ˆ´Ç½f¤â¤¼­[W­.[¨§ZÎåZÄe7mš/Zø›ÇaküN5ä²ÍöÉ™3O|ÎĬk»»;nƒ€BhZ䊦?õÚ½t´¨]žòímÑ-Òë:¯4<jÌ,·‡ Ù A?ÛIwž4ž‡bz—Rµªð WN§/k¯¾ƒ¿µI|¯¤›ÈÍv½¦Âk"Oqúõ’ò½#=‘ÙUpàè³lƒÝ¨IË(RÏDêaïžgÀÒá_wJ›¾¨½CØÅN +ÓÊcKÖƒòUQƒíu×·€®Öÿ/1äÎ=*ødœå*`Ut©ë9(ßáP€{fÓô­¬š§oÞ{Í"¹¤\š¥Õ\!y¨åêˆGÂEz›î(à:Æ¥âÈ>òÄÔ”Ô²ÊÏNò¯Tx«¨æhËVàÏX›I$–ž„Ì_­SûÙ¤¦.GOó¦Î;fä)æ±Áº§çœ-¼fÅ“ºÑ9³â§øà•–æ»æÑô“I8~¢˜ ᘂµ£Ö •,=éþC·~Í–Däç`” Åuyvx˜‚tÎ*àc1Lÿà€€ *åQ(®“‚Ðöñ°˜g[ó*>VÈCŸ‘½@Αóvî¿ÓÀOù3ÎH®aí\y³t=95˜gƒQ犭FwŽÌp2¸ƒs í¬vs,Âù°9P§¸O »E¹›L âžmÒ9Òò4׫ÔÇ\u¹Vi©áó…wô‰]5÷ëcï21lÔßEåù–šdÔèÖ¬ØV(ƒfoPIåÉœö*p Ÿ‘²XáñÚ[†ÈÒwøM6Ê/D½G3nĤ¾Qý-FªùIs^¶<Æ! ‹{Ni“W®} œòp v +œ_˜ù±;![ ÆKÔËúç_ÝKÀ`s‚þúNëa‰ ÌÆË*x%Ø[·üFÿm{UR}÷•OÈxl¡ñ—qh3Ý{$mæºLHý©ƒÂîWè’!¬0–}†¥Ù!"€%3#ËYIn“*Q¢O×vk6‘mºœ–¿Gˆþ†ß&ÏP7:·Ô{Pšæõı¾ƒ4«ækŠà‘~D,vÈœ~FtURÅ2.˜Eè'\—Ë%ûù)ô˜|3t8IyÉ "XC=˜vî^dŒwÆ1“'ëžK”¿½Âj)¾Ì^C‡çë¾¶Žk$åhÇÕǘhOMUX%²ÒÔ†u&YÉ †¤ôqžfîh´'^j;B¯ªÊp¡Øí@ho¼Ð%ý°'ò&Ãa¾_N¹DvTt‚¡»sMSñàõvX;øÿî>ÐÛW}¢~C¼RÖi:(OÖZå;¾…÷rÙÆz,¹(æñ¿NóSñæ«´¸ôêä#h3 ´ ¥}a3j›j‚Ù´53Ï'¹:r"(¹Çg?Ð>瘭¬°6€}î+/×ùžÒÏÑ:|O©NótŠD1qç^ ‚¾˜ãHÂ!\ /ᙆ0Ð’ük¨zÙŠ ®ÉÓñzéÊûïªßƒŽZ6Dz”A@OÍ¿ÓGam¬ªKß͈mk+B|}±EÜÐr¦Þ w§°¬XåQ@{p¡¦ˆš1ðK˜FjÓcD±÷T´GP¯»·þiÜû@?»¾Åˆ¿zC·\37€îŸ–dJa!Ø%гÎêÚíxÊkwÔÜtëù„o^íÙÁª*W¤³¹Q¿šŽ½ÑÆgXPÊ•¤ùúœS›bÉó‚Q±E×Ro™6,v“°HöóˆRó5Ÿfõ¸ÏD£¢m ²—lÞÃt̘t‘…íIi¢2õ¤ÕÔ+nñ¬D9¤6Èþ6µ(Š"¡ÿ.œsF.}t- . +éKqyÙiê5A_ÄŸ¢hÀ¦µïã ïÚÓ5âÒÝ àEJÍõ"¾‹M¸±ChSÔñ3V® Áñž4#‰ØXÎS0`~Ôˆü‚úüè}¯ØXR9Sû[­Pr~Ê•¶öU)ä_D.-Ñàž¢`y”‘á2>/_ƒêy´»(­¦šá ó^ô—¥.˜¤õC­V»ÒA$†L ¢ø‘3C¨¶ z ¹8/â﹉ìå³S¼m–CæËr¿Î À *ü5{þõa´ß $Òø2Ä!F]£É)…Öž¸IÀõ¸Ö6.š¯Tc†F"g›Pj“ç7&܆2‡°ö?1í$¥¯î¹(cßPä­‰žgWO>ÿÓxRy1lŸªý@a‚µö-&†hÎo IF)ƒÂÚp[µŸ¥€uS»LA]Û‹› „vdŸ‹¶[^FÜЭ*«rf‹×Ï#}Ž›}J·/ƒbya€aÓ Äç'ºMB%~Цö?‹Ë€°=Í•™Ê­±oJ–Únm1q¦›-Ba‘Ž¥ëöÑ×ú¶;©öcF×dµ0Òèg àùü¹šÐ!ŠB«ä,Þ°ÐÁ·¬‡ GéמI!Gˆš –éÃ=+½ä–‘)´…èéH¯ÃÏzæHC›{!d¹¾×:|úåª2Î*1“‡•v*ˆ/Ö£âöÖ³gê§Ò±8¨ §bŸù"dŽma‘¿¡2¸¸²ùThÍÇ3°q'‚‹.Z´»«x¨{Þ¤Éh½Ìj´3Ë7Ÿ¢“ÌÆàšû©7”1TsFpv¸ÿqY,£×l’ÞHOh‘4–(òâ߇´Ò¼cgsû1"t‹ ÎSŽMCË–Ëݾ „%kÍ‘£»_C¿±S\ÍrûÔ =lÞ1ñrË/ª ý­@½:çÖG°ÿÉ-ÄÑ2ꀌMÔê9Që,›©FˆUå‚Å’d,Á>¥¦#Ê­¨(a;Wkzh"S>a¤Áâ糫EmÙvž©T¶ªuÔ*}+vdñùÁSUX8ƒàéä 4±ÁbÄbC9ħÛÄ_ÖÂS­³;=žÚ+Zo‚ÕØªk vY`ËVùåio¯‘ä×Ä$\Î$ÁfBDs„³cr˜ äñ´ø%×ñ d©ÂÄC ϲÍdͲïå|˨Å@²ãç2ò¥¹fõƒ[ê4N7zTÞ0d±í‹™^>'ñjLy¬«á¯×¿‚’1][„o,ï…P;–&F0P=(#Æ9P)[>ÎðúÃ?éü«q mÀŽ,rŠÀÄW¨1’ú¤FÄ4u¢p%ÿ©õ7Ú~w?Ew^Ûrc?ðjšÐo®‘óØV£ŒuÚµ/$ØØ1ÕLíÕðbŒ•–­Ä—xQÿzznUb³X34ƒ¢Ão-ëƒGŠÑ_Cä6’Œ¤ êñ×ÛFi-ÜP£zs û€füfÿ|ÙS…eB]Í Â1a ¹~CªGU;:µ/.EI‘¦/°4s©ŽÍÈ´k*ûÀ ™¶=¨‹ä¨_V²F)À-¤9K®1ykbÉê,h,‰¶šÛp6 „Ä™ÕÂóOÁ€ÏÇÉ’-­ãW{ç=Mqqœƒ ß“e”wOŒ±ð}T˜¶ŠXfª´]æJÍ+r`-*vá<¢@†_bX'´ƒøÇw‚ûš¦œsä†ÂTÿëPD¢÷¨b¡5ëÉ8»×E÷²YùÇ—U“„¢ÍhÌ Ìç”ÜKqkNЩBᩔߟÝÅÅ©¼ÔXAÎgúÛÏ<>¼LÅ%ó°L;UŽÀDô¥0;pgäß ôxÂ6Lüë¬Ý ÎyŸqBhsbüWN·›:KÂQZF£üûö¥0±¼LxTÅDë 'PüOÄŽ‘6NrêåD΂D‚y†t—u§šË03Ór'˜GÙiÅl¢-¹eºGµAÀ\XæiD˜<7§˜Ü¦3•4À)ž¨C8´cZÂîUh#±·!ÝL a”(Þ²-z[LÍ8Û5^1}Ó¯DähþÙ|¤R€jéîL‹á€-a€#§7ñG`ü#¬ó˜ºì:•Z2A_£†lû¹9. ú¼Îºy Ÿ2£Ar¿Å ü*m‹b½^…þ–ëÔl‡:èU‚õFeR8ë²a’(–¬,üÝx›;§b_-SWgÆÌ Xˆ.\©†kî$“ä`KÄ ©}?³äàš—ü=…X`5 }?`»/áZ¶jüšÛâýß¼E¹Ä–Õ}Vi†,ã_ã_{ØZÇ!øÆXÊÄ×1>@õ»^ƒ„¨DüãÈý íÓ1uXvöIä±} Ï¡oº½ºž½ôÞ:sMUA}D™Ò),Œ¤wZ|ówk Å lE)7±§O\Sëø#ð˹¸ˆ”&ßÂq_7ŠÁ^H\Ÿ?úÊU©öû® »2ð'0 "G¾Y½N­¦È´mðtçÝF“ ;Ñ ¦IYèú1±Âkü%jð…>ÜñÅ (Ý–r-ì?#9w¥ê;@|:ÑêH‚Mž¬ ³Ž;ÿ&{½À‹òK"F•Þý~*ÓÓš]ßÑŸ'Å>a±„Õ#±ÀŽƒÊƒ'.èà\ª¼-çÙ{ÆÀa(é_x~[´uvÀ¯Í®š–‰†Äõز´ˆœËÅ•X6_:Æ` ‘g‚¤œ¸‡˜+f‡¸åð­7‹…ìë@Enr™;ò©95eÇK÷©ÿ JÔjW9d•IÃò¨ÍêÒiº7@Iu½šÙÊZlÙ­)™ÚY뺽©9&ö˜aÓVM Dé¸Ðö¬"Tì}»:X„6ºÕSØlòÚ.B¾¸9ß^«l$àK üëmïL‡^:ÜPôFW“AQ0:3¹°·ï²ŒqkfXöO—Ul ÍŽ¥â§ƒQÙÊõv:”˜ÑŸÂϨ¦÷ØaénpÛ¥Cu’àõ‘W’#ážÊ nçýw긥Á.ò´•'袠̨ÔêžG(èþ~úX— Ûë¥q…Jºk«°[¤F2Ôƒ–4¨ÏZ"+ïw£‘xP~AÜ–ûC0Å„¿å÷êt”ßË1(»’Œ±æs¡òÿñaÝì !@)TŽËò½GòHBXӭЀò²»,qh°,@ ü˜ÖS”“Ù•µ‘*@‡´…ñÎT¬ ¤´UÐa&ÒŽÂj-&ÐÿްfÃ}é¢þ;؃ˆ$> ¹#sÇ?›IÅóÈóËÇ–N›ò±ÏÐN’ܺT jD³]¨(フªì¹<ÿ/F«'p)šN®tÙMÝ<ˆ3–àÍ/¼ºÇ‡ ‰É:uh3*Ý¥¹«§õë.¬TÛg¿œÔLIC .†¹ù—Þ¦b·4.ýÉ ;ʵ‰¨†F¼_ÿeªGÕ›Þ˜ß÷,gd0«š`ò ”ìqà‹]Em•‚ÊYø¤˜Fä@ûîQhÍöxˆw£@pÂ#@§Qmƒêh8OÖ%e ¼›Þî‰Q*(1“x¦ÁÍ‹4%…#àj{µ°B‚?ê#™–g@:üåî`ƒ° ­Þ@¡46NžòiSŒòpŠÄ§à ®f[ûòðP.wi·QºnèŠÄ†#Mg…¿QŸO ½l¾s¼ðµL Ia^so£…™/V¥Ö>yfZŒ•H¥Õñv”äyœUÿœ¢—*9­x@R•>PœÖßO*ˆ¶k›ÌòZÞU”ÓåS„u™°.Zp‰G>òÖ"Ac¡Žp€ T‰$FëÞ’Ùø´ÎÃ`=)ÊÑœÿ!ºég ¼D ›Ã¡Yˆ½Ó¹RqKãˆÉB]\ÜÝ(`°ÛL†Pç|¬Uý£ªœ?<ó{øc]^ ƒiA7d¸ÓçGÁ49zù&®kéoÖû™ ®„À…F\ô%sÈC_Ï“‡)!LhÿïÊÉ—ì(o0­Eñžž1UË”c<œ¢­Ûܽݤèz™Øö²?>0ã9aþYƒ_!ܺ!‡kR%€:ÆÃS,ƒ’yr8ºN@K}m+ö6pO•czW`‰­ö©€O½Y‘ ùÕfîö™€Ë;ÀüúQk]„r: k™˜‚“P×lº·¨aqëÄ<ͬõbŽ¡÷ø^¸`ugÚÒ¼ùGâ.§,W†Ž*«a£ÁÐí†ib…|éR•³——ÂìCÐϦ$,&¶í~mÊvȉÞÞªoª³I扢ٵv®NŸÊ¨S4L‘{ØýÕ:'€ÉXÓ[ñÕç'ÖIáJ“Y¦†fÂ>}ܾó>+™L` ÎßõÓ†dVVk<»€k}FÍ×µ¯/â¯|ˆ$Ó(r/ÏNoê|N­‰P~ï¹dv£´¢Q%B•;3¤[8Íj";!™xÓ¹ú7è‹‚dz Ê°èÑWö¾ÓÁÐþŠO€'S¿þäé]š ݽ­(ÓoÊ­áZWMä\ÍS AP»"›(±g5^æøJnÖöÀÆ 5@”þ= bp‚oìGøgÄü–m#¡,Ô^šck•®¶³Òl;è§û$¸ßR´iNŠMßÒÃN›í§1½µ ßDŽ&JªñDÙÜ#.¦ù‹Ü!ê˘JÁƒ…WQ“&¡{à“k=Ã"P°šÏø-O+Û;Zþ·žTzîäèó“ÌÌuàà—ú”Þ"dppi.jëêØ#ª¦Åÿ¼mð FP¼Q‡†ï8õ¿÷=õ?¯>b½†î¨ºÕ¹…ª¸§E6"wäm£N»]C “ÍÛ},vŠAÔþ^»´ñ:Á½Ö`:ð¯ê@mØkI6XRDz_ÓÂ"ˆ‡°ÿ ¤Äô_-’Ïêdze¨íœ3älewOlÑåkYtzßç®uûËg(‰"ï]¯-ÈpöSãy÷­nh'‘"¬Öñ¸¨:èOŽÌìÐÍútý ) K–+×T‡PÞ–Ü2VöHÝ›M5ž5ªŽëŠnètµ”/îKšB»–K3ô(ü|fó>ùaã͵Q38[ÃÐxI2¾–¿ RßÃ:ÅfðþûÙžš TEx\c?"Ðòœ-É»p(5 r·°gМn¸³#á´@)Bð°˜g[ó*>VÈCœ C1rEþ—z}"QwBb¸N¨ü벓ØÙÕZ Ȭæç—,Ý“¢G iŽ³ÕŽz UXý™"MÉ 5dÍÒHÛÿ#kÖb²i’œC½¥qãR>ZôeBƒ›Mð씋€T§„Þ‘“½í£×A}]¨ÕÓ•HÔ¼äÌ«Ðj1¹‚ z¯|x[Õf"&3Ä(B5DêϯoNÿâXÀQ¼ , „!²õ~|YÉ’zE_.àH)xÑñ Ú«{: )çw7ƒNÀë´Ka4sÿrI˜K¬ >^"R—ÞY¼ šÉRñÏ»Y±e¸zv רÝ¢8Ÿo/2w{½tÏùÇ— ˜*±ÀÔ™”°S½ÊGÓn ¥!W ÿi2-BÈ“£,«Š¾Þ÷j×ñL´Ì•~jLr¦§â.ËæèqDêޝ¿^©XïàâOíñȥ%±ÎÑWÏc{YºÙ)ããå!uœ]Ù¬+P 7–ŸgTÖPo¸}tPãDí®’$ZÃL•·Pd@ó³L2žoØùà ôÞïc5@>š#Ìâü<‡0Ø™#ßÜWJœ MÎ×(ºÍûcNÌÁ=T~q ¥tõ\úhWxZlŠ?e ¤E¹ÞËÊ5ÌèŽq3‚ª€™©Z¬F{ã „^¾»;¨œcŠçxÉ2µP,FßJ¬¥M"D"I2Ò^¶;ÎôŒPXV3øney fhÂTŽêOŠÖ+§ŒÂ‚ædeŠª—O¥zô³YáBO|#âÑi%˜Ý*¤\ôÜø›6¥ñÆ!ó¡ØBeB#Ã+½ýÛ¡ÇdFF­|ò$•(û˜.4{Zn/Rkˆq…ûìûƒd¹cDCwWŽs"i|DÔ«‡OWä34ภS÷xL ŒòdéyPñ€Š!þœ['r”Ëe}»ù¦ã%)Š¢²lŒô(d¢“`@c$¾…¢_ÂïxÿJî-WO/´Æ±[ô Ô¶›Ú_h%s;HúÛùȾ¸á^ kƒ’ÓãŸqcáZ‚ôÔ¬U¿µ1"+$Ü`VßÁÜ#€…ÜNxÁ9ÿ:·P)ëìp†ˆÙÉ3X/°µ¥×$ Ïc©ÝÅÆ<~úTÁ_Ô'ª^ݯ€MÕÙ'Œk8~‚bäh'¼±"T“*IwN¼ØøÂB\&¦x¸èøHØìäXÖJhb7ä… 4ÖsrýÁÆOjß°Ft/rì{åÉç9¾ûÚžÉÈøøb™ Ík¸LòvdÀ”“ÔtîëÒÌ¿˜œì>ÍïŽÈU+®/Ø'…˜ãÿÅ?½›˜KOq|‹.’À¡€Oî~\Zb›Åµ)åØRmŸ$· ÑKvµŒŸÉ$Î`øëüÄãóØ*~òp3/´uIW[úôŸ=iWô æCopL¼ œr™¯,ÐFÅb—û[bzùHÒFëb¢âlÊ€ÆÁO.D_2À—¼@Tß8^€0Gª[YØÄûÆ[%×ø<ç-¯Âø,Í‚PôºÕ ›mz±Ðy¿µ=t&[^b)+‰^—¹ß-ÂÏßy Nþ¯à¤ÇÂ;¥õæ„vJó-ëï“!;ÿ-¶Y­Ñìn©1÷è]M=¾ p¯m±¦³KÚjR¤Þ5jî*”¨g é0" `„*6kt ™&«µ[ í¹#¨‚ö²ÕÏ<Û¢ xÕ…^ÙFìÚø™ L¾Ù^ ˆÆ£*:` ™ ÄIm§= @/<¯ÇÝsk°Ä‡–$s sˆFãŽ7MàwÁBàí1ƒ38.¤D­šêõѧƒ‡MqmÇ=±Ë¤]6wcþíœÀi¨¾‚r'Gôõ÷'ñànyx™ðÚ1ThÁ(!" ²ÊçšøÂyÔÒ 1W*á²¹¢4ó”ëaOÙïïCÄ“ýш·ä@t3üš!mǯÎZ›™êäüÌ)8bTÞYz䯍‰žDãâ*Ô µ÷ª©VQ7DfÌÛï!‚ÚGo”»¢š øD®ÏIÒ7Ñʺ&FŒpnêÊúä¸Íõ½w`9ŸùŒç;Šuˆ%íclj}ØÛ^Ü_¥G(þ«äíµ,ˆSè"3ï¹?~Yf¾0]V`°MPL•ô;¤UÞõ¯‹io)š!ä,—ÌPæÄÖÁ«Ú EÜš(—¬mˆ+ÚŒ&iø°qœ!­Õ.¶Ååu󂮽à %›ˆ^µ§©ŒU ÉòÐ`÷õ«¡ã¢¨gu„º²Ú& §ÛÖɱAª–cº#‚(Âhã^Ít3>ˆ>I ‹qºÖØ™ÙRý…ï·çÁ¼G®Uñò7ð6¬Ž" ‰ªîÖõÑ¢ø39 ¤åñªK/ÈY=ép²ÈƒûÞ´ªåƒ†×¦ÔÕK dcáó¶^y¹i4 Ï‚,vH)T5}vøæ#7 ‚ä#¤ÿjVNý'[eäGÚá’«Y¯Icá¶_•¬)Ñò\>ó`ìET¤U’ø &Ûi“Qû:zÍg¤%ŽÖX •!š¹¤îõÕà*Åû!Ýräa”[Ó)¸Ì*ˆaZDYŒG2zIª¸e09JKi¹&+ê˜?r¨Õ…n8ë¯t>&£xxVL›·öfÏ®œ†:Æ¡qeæHqpí&Ù„ÆÊc†öȧr‹ÕìZ61ÓÙ®«0ÃÌqѶ¨»Í„ üB_š>ȬD'¢ðL˜Øø´,‘é·vëêîoÏ5Ëøz<¬‡_;|£r—®è.01HkÆ}²Š^„YԬߔ†fZÜ3ƒA9CÙƒ˜›Ô{] ÌÏϬùtMj©Ç2 + >XE$ }…ÞíÄd¼LBa­ph*öÉàÇ®ó0†˜w0&k|?#¹B”k3<ônÁA1hâK‘Í.]¡Úxë|¶­)ÑGg{{T£°O&X½}3kŸycµ|~»=)"`„¹«à>÷µÓŽÉìv3<"þ)ÕĒߥ·ùî!ƒÂÌë{1gî…|-¨?:T˜Z¬ú¸9•AN9’o¨za8>æFVA½?«GÔ¿…ÿ¦#æÓ´ÏôÍ?ËH “ÿÑ£jW7Âì(Å]fˆÅ0 ‰&ò»§!¶°ÇÛáªkCµ—U²yqɚϓ­g%sAâ8¯óÆM)¸Õ1YuU6>*ƒ twðY#ÏÇ>ü?‚íP…î÷™>£~ ¢Ù¾à«J§H€˜û|ö˜²^Í¡‚"˜Û±ëÙæð‚ë:DØÁ¯ê¶fU*ÎqÔô¯øH ¿³QüPíèÑŠVا†¶EyoE9fLuÏoB$<#Dul¦ŠZ|ÝÊ“AHdP­p‰*u¬ê‡H˜¡‰2‡¬‰­„b&©¾àU ížÔ™LöâÔÏotwh¼ÌË.zWž¬R„ZDÿ´j“Îãè &8‚T/=ªoÇá0`˜qd6عÇúˆpwn®çƒcRêˆôSdРŒŽ®ç- õœ³:ËL‡iD€D€å”ýÇÀÔ\ùž¾å,*—ï°ØmÙ¿/:³MâM¯Q–ưQîÅ‘3þÅÌÅ ñ°j4%‡ 1êšã 5$ÿ$«ÄÓxí@Ÿº‚MvÂÁòvÔ¬|ÍdÉ-ª‡¾ð|ô]|psSõX[™N:qN4ÒÇÄþÍrªŽÿd¾À'6Daž‘µ iP±ì©¢ypÒ'4°'·îqZ&ÕÉM½#†è@j ¢Ö7B`¢ßX?¬~P% ~ÄÞ]¿zFÁ÷ôYDÎ`û’6OC¥ÓÝlí#«E­ ”ÄX$mçHÎN‹‰œ2Ÿ…îa#°émwµ""n÷/×Àj·c@ ‰GãuºÆ@«û|æU(Žo@­óOÊGæÃøÃh/üJ8€‘ )¡ÿÀi{Ôï:ϨKnÎÇóñ…E¡2ÀtLõ ƒHÔ'‚°,ØÁ@‹ìÛvŽV-%ò××\ù 1íûÂûèÊ8uÙ?ÝjL”îï³Óu¨ë¸t}Iœl-Ñ =-$–íñÆ­`/¯²,Áí€úQ"ƒd=›§¾™Çý>–ÿ†ÂÎJƒ}'¯]mPFÕ G‹(íÃ,Î߬Ó>xEfþõtN›¹ Æ n9Í»ÏД>K–«/!]—l3¤Á¹Õ×pÄŒ{$>æUEá¦ë‚š¾Rr)Pñ!käM(oØ'3܉+ÿ¾‰Ø8ùBªÂYù‹¥–qЇµ[EèJï–ÚCøVoPZz‚—\wLa7/:Ɖ(¿¿sè]¡J†´ówÆs"ÞZŽÍ›k2Ô[ËE9,5¾iR5yþ¢UUO`(V ck³£¢æî&º“o‹:žêÄæâ¾‚&BO/i ä<×Skø–ëCí—¢4/©™Ùr‚ÿ­ ösr<®;¡Å…*­&ìà;ºµ ‰½­…ãŽü2߈ýƒ2˜UºŠŒåZ¥.ù×ÚÖÅ3® Ì1.1a_\)'Åî@st¹§lÇ-ˆè^ˆ¦p/O˜X*Õ^¦@óÜ0÷÷$£ÄÛÞDˆÈ Þß&Ó˜E; 3gõ±ƒÇkЄÅ/Cï>”jpnÓj^Âq C?pߨ÷p<⪳’ò ýòˆRWrPÒ€]0,·NªéOìŠ; ß½˜áoS\ ç„Öó¬GË0"ÓuûÞíÎ[akBï¸Ý O‘ïß3æ\_Ä(œVª´T¹¹ã' G>[ß| €Êb êiñÈT1Á(‰üf©3c܈š¾½G|iüò>lrCf9I¼Ñ±lnÙÄÏHÅ%/üWÂ}_gg) fMfèlÇÑ`x–G1Ç”bî?ÅúiT”Þ›ãj0ñ/h dêbÎô ê æÿµô|ÜZ|ŸLkcdu?«oKô×³Ì 2¯k;b~ á„ÏÐZrêê',\$šÊJ+ý0õFiàNôŸXXW„5Q×{}:=ØïQýÓŠ^EI¨ZH±>ó¢˜/5wñ#Íí2LQ÷]v$óx*SÑdÔÚÁÁ{Ðäê–›¤&ŸC&¿M¾ ²dîr ‡EW‰ù¾ÞÅ길Ŕø67aØ©E70ÏÓŠ jp…EÚódÔn¤ )®Æ•pïÜ ²§È&(E×þÙbfûÀJ”ÆFFHª'„nŸ“ÀÁ›r3÷Èrê^¥†Ü¿"¨ÜsªìS$ƒNÞAjâx\T-Õ¨†°8î¶Ø æoG‹²m½%Žª@üàb … V£ÎØþÌÚÞ ¹ŒÔ/¨Œì»öjFé?t6mÓvì0~ŠPPŽeV74[º,¾à/¬‹¹NÍÄ»{ì_ñÎíþÑßÔõngFÁ‰6Q6(šCNê‚ÍFG|5©d•ÁNž…žð¹ƒâ» óYÄÁr©#šß8ßKoí1µn6’1†Ö®ÔF q¿"éi/"Éâ•ìì¡ Õ4UbÖ勤›pö{¶ ìp1->³Vu˜ «Ë¡äh^×!à e8ýõF«û h*ÈïÆÅp1•Ÿî’=G#äŠtòdz9ÔqÙ)öŸŠa˜¤—Í p(<´+ïœþI$åÞMä.3FìÉÙóßépË›êL+yGè¥Á‚½ Adð®ŸÄç¤Â'¹F™ßœ¶yBíf>8 ›ðæ¡„<·PËÜŸ¦‚'¹ê"AºÚ­òÞÍäýö*\ #0¢#nu^ýz;3z gÕÒ µæ(ÕþÚר5†Øü…-.Y‡4Í^"\ž¶ÂŸ¹­«Ã!ÄãÁK_ÜM, ¾5ϳºsª„msÒ¸ †bÔt=Zq•§>?›­(˜¼ÌgûÕ¡†¡¯:XFÇæcV@•(+dÕý’× éö•¶_Ö Ú‡ì$È‚hÉ6‡±ÄW0Y%°eE$­˜Æ„ø´:;r¿KļÌl‚Ù™§…(š~ƒ¥Yh fÄ•#«A$¿å¥ÏËx?’sèHL e¦WÔ! ùÂæëyQhŸvªs$GÛ\¬(¦nC£ŽÄ˱ú…xO­c-ÖqG£¥ð Me£nn¹l4±èHm$y 0?Ðu¾À VÌyœ š/_¥+Nxä2DË€T ]bLð∰\ endstream endobj 235 0 obj << /Length1 3226 /Length2 30543 /Length3 0 /Length 32296 /Filter /FlateDecode >> stream xÚÌöuTîöŒ’ÒÝ=”twww#] =t‡t)Ò!!4Ò¥4JwK‡€4rG¿çwôœ{îºïŸïš5kæ³÷³÷þìx‚žZS‡MÊÆÅ (ïâ aãbçè |ݺ@w' ›6ÐÎléàfçääE¥§—qZB@.β– 0@bа†@í¡+89…Pé @g ;Ti°ò¨!–º¾®@.£åo éâa³²ô€ªÎv g ÔDÆÅÕ×dgù僟í—#€­‹û/&€_T@ÐÙÕã—Siv€²¥µ£‹·‡#`élPfWc¨»xC… £‹3À ho ¶¸Øþv¡§#§­PÐÖÐÓÔab胀gKhn@€µ½¥»¥5èîðBãXÚØüÃ[ÑÒ k„~-íÙ¡u<]]]Üÿ••ŒŽ®ž+@VJ]WÔg(èéè²Ôu¡Âßš_¤ JÎ6 Ë_æjrºRº/4å¸8~UÀð‚Æýbú_é<‡&ø“ ÔÔÖÝÅéw£=â*ÌÁáííÍnçéawq·cw3ý  k‚æàâî€þºÁÀß%öt¶6Mä·ƒ_=¨‚¬¡µþN ü­T“RW’—ÓÑeƒV‹íWÁÙþi>;Äò;m9)Y5¹ÿ¥þEzüî×/_6Ð&ƒÀìÐ`ÿœ ‡2‚…ü;khc ¿ƒÿáð¡Žþwz¶PÖÿZêÁñ+6y u]6U%9u¹ß,]Üÿ8€xÚý²ýdø¥³·ôøMYUSSàd r†N¥³5”Äâé ù-ƒ~64ÿñtwÿ•šÚÿ©ÜÿÝÿµCÚšŽ Ø?ÐÒû¿×ÒÙÓÃï¯~ÿg+­¡ò€xüãø¯Jƒ¡"hoAÎÿÿ{÷Ëà—K)YUè^åãpC¿œÐ],çl#ãâä%îúk*dAÐA\Ü}9þ÷îwtvñvöÿÿ¡´9Ûüª5ÀÆÓ•CÏäæ T’ý— T„úGf„8@7膶¶çøø÷vø%æú%†Ö$ÐßÕÅ`k ö‚lÐTK/è º{ýÿVü'B娀¬!ÐÍ=WP{Wr¶uý#†2ù?Õ¿Æñ÷™Æ=Ðl\œÁ¾ÐѵEåPw@†ñÿíGÒ±–÷ƒÕ¡ÿg‡þ{±¥ìûÿ½ü¿–åÏø¿}€<äA>@MÄÚþŸný#W‚XB7œ”³íôo‘Þ¯C Ýгôëê°qqþ·:ôÖŽÎ@ß?* ´ˆÿEÚÐ_¤FRÚ†ú,ÿ{¯•s¶v±9ÛAž`éîné‹Ê 1n>>€?tëØ}~Ï €ƒÝÙ5¸zBuõלðó8¤~‰þAüé?HÀ!ó 8dÿ !‡Ü¿‘'€Cþâp(üAÜÅ?ˆÀ¡ôA£«üAÐèª4ºÚ®þA£kü B£kþAÐèZ4ºö®óñ8tÿ (½?ÊEÿ‚r1øƒ \ ÿ„ :Ë#^h¨©3tký¥‡VÃ娱˨¡É¸þQC¹ZBï60ÐöOÁx¹þ%uÿ:òBY»BÛëòWí¹ •pû«¿P:nž.Ð«Ë ü.¹xÿhþÓ-×/¿¿Uÿ%ç‚–õ¯¢sAkèñ'qhb@'Ð ߯5@¯¿JÏuâòù“”¡ØÒÃþ/ÇÐøÂòA“‡Ø»ÿš(h‘ Þ.@}xþ`hÌßo0k÷¿+ ÍØë/%ìý×Búü¡Q}ÿ‚Ð.ùýá õätÿ‡Áž—š¿^$¿ïWÎ?连Ÿ¿±ÄÝÅh²>âÿZ¢f qùsB/G.¨úù¿¦ÿ€þϽþ—µ´´‹?7?€zè@7 ÿ¯ç ü[ë^M¿/fèIÿø×{ú­Qf]¬E"Ò›"ßÉM–#Ò ±UŠ*¿BXÈœl'#–ÍߤJ¼ m ÉzþÎEUQØ4(5Ô¹Ä>‚üsµõMÕÄ¥–ä–eZ¦œÔHž>»^X–Ú|Hy' Ó¾r^á‹RÞ¯Ym¯Ú(z#2Bí]· ÜãO8çi4&åmˈÞÅÓ\Íøî`\ŸylÒ²ùÉXÈÓ-~R¼e¯Ôó”Ea$áˆò3מ.¼o¹m{âÛ#›ùF8—„ú‹Íg›7®´Y Ëm”?*ÛðÝ08ôŠò64T¥ð¾ZìÝs á×1D–† ¦f¯nuk—F%Ÿ\%?6Âäé¬TÝG•¬(ˆ –uÕkඹɞþè ¨Œ]‚I«·Ðèkì1?lrµW¿^޹ǓüP3‘GúÙî{n\•¿b–b!S³ 5òN·x¬ŒŸé—£…å;”K/šð·SxÝ;‹] K-N$JÞÖ$ÔvÉ/i-ÎïoÙî^þPùùëG>îT2ÚÞXiv=ú|,fš9q#Ϻ‚§ò”ÆÚêH70©:hN8ž„àhŒ(lýœ2_‹@EY^ ¹óøªÓõžíóÎ3|L¬c6á—z0X«×je1I®éŽýââa5Z6šö% `§´Ó%‰H„ŒéíXB#ŒàLC³È÷£ä/þ4"9y‰öEã“r¯“N?²9­–ü” ìdÞÆxÀµ×ÜP2fO»¶AÞà á´u{ÐÞésqûˆHˆÛ¹qÉV'û(“©…µFólº×)c–¶·ÃÙ¦Ñ2Ï«!¡†"½ÎuS:m·*‰ÕÀ9Py_²Zíè÷æ‚6œ-úŽ‘˜‹RíÎ.Ti{ƒN§š±”¡g¥ž6ùÐê×91ÐQ•ÐL¯øøbš­·õµóñ]ð‚fË'4ë¡)t‡Y½W[ê=œ«¡c|UyÚfù>¸¦dÀÏ”ç.§h\ŒYµ¡ë_}0dEw ¿ÍoiÝâÝcF¾ºœ?(ßùpˆ–`Јíp¸xk©gIPÒ{Ä#þ õÓ—$?r•™?äç¯ÍiÊq[R2’¶Æ^¦3ÛDÞWÁÀÜà¶Çô0š~îK4 îRcí‡wùØX‡Ù!{ãá,ø“ÍAo±ƒTDEë¨øÇ ŸÑÇBº@E­—F¶ Ìoœøs$ÀÚ ñü²ÜŸÑ(Ƽ/r8ê˜/Éj(vy½¹F*¢ø:høÈg‡Ìm…E½ò]I×/9{t^{?5–“h‹;«ã¦üØ”Û|³nxQwo±–û ÃTCCè·¸É5½0«þÝÃép¹ë%qìíÖˆ lO¢+"G¤¨ò>—pƒnðÅ(}Xy^MæÔx謄îƒ$†Žß2™?ɼ„G’ç²÷Þól‚{ÃóÞ˜˜r˜/RG¹µDJöªø†ß=D_EØŽüšËõÅ/àÉVpè÷¬XpÓ!Ȉ}fdZq¦®ÛòÓÿj§þn¾»ýLê2¼€®ÁÓ’¸¾ ºÖÎ"òJfËmúˆ&âœ.q´V«ë«þ†þØ Ò$ÿ¢`ü>’LÍ…Q¹tÆ%0Õ¥›;e?îÝ^î`ôÂ$'@vÛN "ìK¨hBÇü&ø yå–ð^Ëí0ïiÈ ŽgÓóš|ù…·ÖØ­mŠ’ã´¾)Í çÄ_Â\ª,¤!Z÷Zô‹~+$ÝDJ©FÂ×}Áa–Ò/Q£ Å,§øåbëGá`X¥í—ÈÆø'jáÐp¾Œƒ ÜfžI ¶öƃÂD*ÉÐì>Gk'.š„ëÂF0È¡®cáŽLȷ䋨ÌR£ÅIgÓ?!›W{àZM<­ ˆˆ~%·‚9.ud©™Ž{ú2’rÑŠÃèÕÉí`Á©-àT)Ãb¨G.½æª¢½°6ß¶ 'É1zÖág—ªùìºBªiÄ#Ï\DnúÝxˆ¼cÔÜÆèý¢Ý'˜Þ’L~‰ ÞúFŠÓ@Ï $‡ïâ} E½†W1ˆT˜“ºÄ¸ê8wç¯à+.I¾Þ DË≳K'`æ®5Ã(4}xwt´;ºÁö@üqÉeÁIg¼¥ýXù*̯,^VÒŠ‚ÀÃ9çN†`#.Ÿ¼}ˤiAéò1 ¯¡ÛàXÿ®ýÒ•OÙádzÓ ¦ó¶“J‘7ñṬe&" HÖ”I#?Ú©ÓùÚ¨f@ýFFÞV?i|\òžD£³"—Ô½<ÿ£ˆøÎx`áÓ²[p@z>ý3ßTr,0ÎÆ#ƒ Þ£àHÖ‹X®õ6ÕŒ~‰†ð ZVxy›M?V§O!M7ñs· rôo˜ H ±_Êåmj~äL˜ và XÏs&Ò0çx}š!Šþ”!íNbÑ™ ·Ý'‘ÙtÚ)÷ób2¢šL$@Ïò…œbU@ßËê'~áŒc7ÃçL aXdDÅýÇèó»”ÇÅ+ìÑ1”ÀY˜‚ŸöT‚H'$ú×Í¥Œ têüpžXÞ'qX5ùudúÂ1ål8«å#p5¡ÝÎñ ¯fÎ (=^Ç™³ûÔß*w, †þë÷F26ù'%Ž©WÊ!lñç KÔôØr†ea\¾©Zá 1½Ù`DÍ-i¨L‚t{Iæh@ ¦ûµìÖ/¿ÆK Ç5ƒËä‹å†Ø.HjÜÏô-Ri-ûLÖÓwò°”Þ>h!O®oÐ? ÍÝ^¥¨ˆ%>ðª/á;VGwÍgÈéÁºw›ö£‰;T#H.~ŒÎGØ öõ2Dó «%ëјprûoÙ“oÆÆ(µM¬ÀI»Xd3¼Ç.ëóßv¢u×zΙ} ]о(é/êÕQ…Côm³¥çŽe-¬IñðF­ÏÜ#—Í[Ëôyá¶3åhŽ©4hÊSNì:&§&‘Ý¥@¿•I› pscµÅ")âùŠ¡:Iü²—£EOþÜz#ë£|×Íå§°ÍÀC“ ‚ó)ó6Yxe ‹dŽó»¶èaõƒYÙ2bجÎÐú¨Ç¡“ŒÞ.„úõ±â¯@Ú%e@ÃüyzáÑø5uÂSåî+ÉCžil§4a“±†IâáîÂÊ øû‰g?‘«›½<蚇ŒôÑ&É t…e¾äKÙÂçàµøÚÊå 1˜¶Z>!Úw³Ë–ŸS$?Þ2kzŽzñ;3V·³û–Y+Ò/½FQÕ¤ñ1xÕª#¶&,å¬ÐJ«íoÂnŒCg柕¢«2$¶ }©O‹i²O3rê2çKÌëyß¿Ø9jØ^¤9JE­ñ¹éúBr}˜dàb9Õ1bå×Ü[f,:¯›è~®†q§*R­»è‹ÅEf!M-|pxÛö@Wϳ»'"o=޽µ’ÓÓrò‹_ ñ]Gï6Ìû‘‡ë`Ä»®½Ã<Ët¯KM%Ê·F}Êe&[°É$7`D9‰¤Š¼†O° JáGܯyº·Á}<åøá?œõ#|ZÖ;0qÛf*bÐN®‡KÔû¡ÕM“‰tîz÷ öœø8nÞ·{çLé MlCÔõ­©+'Ñmúd—íJäIܽs$=ëÒí±‡PÞØÿ˜¡n$C TT%)‚|Ý$zÝŽÞyC´¼Ñ¦ñžò‰Ž³Oi}ð¤¨!ÜÈfuoºµiêGî)Õ;Öå£M×´z£wTýká$}+þH•Ê*Ño Ü"ï zžc"ífõg,µ!QÅñÂã¦äÙcV÷`+_ùÒT±æöF2…ŽšýX];@\ÛoÞªñ„!Ýû à§ùÄ÷i¯õ‹ãžt)©‘tñcOÌíe ê÷=H>ûìo|SB­êu¢ø©ÒÓ¸ûVÎÈO*t$¼Lšôìxg›oKw)ÈÛ‡`Õñê°Ú•tm2îÇ–û“tñ Ùc`&êôê…jœ_m󬟘µ&+5MòÜô‘Štô#:Ó–‹ÚÑYse³õÙKëÆ“;}?ÒË \/,s˜m¶KmŒÉÉÇw5uo^WU]ÕÏà•ΩDùb4<– d·’2ʯúj—ö•2@ão>DM¡÷–#ó åõnn†C^9óÅË ]ăµ®d(Öo~6õ¡ÞŸtßKpÁEè'5Ä, øxúDEy| 1ô+Ãqæ½u°„1 2ú2ö–™´ÖFµ“°”s¿`ëÄ!N—‚¤¢/õU ÃÅ QŠÂÒûsÅ~¹Ÿç2؈>œ©äþíšåMu̯Ö(eÓ_\ž*‹:½JF!ã|·šÚ—tx[(—”™¢wLÉR<óËŽæ‚ï^—É¢Å?§ sìúÃ*r¢]Z*lÌ÷¶_¢òÎz¸?ö j8¬ÕÊC8 ªV{/p¹:­S<0_…•îG8¢g'|D¿b*ô«™÷Ú˜9ÄY­G».¥ê¥ô¢1Å£•>Å‚cû’•Ň®± \‰|k¡:M¼¾÷Tù¢÷;Õs§ûoU Ê!gK#l2ò%ýñüwÈ@iáÖó‰: ·yÂÎ=ãÂ’?˜àÌ`E³x¼”¬Ï’Û$C»ñóÐ:w~;Þ32¬‚*·æF~Â|-Ù‘íehù^óuóøWçïÖoI¥âÈÜnSŸ²«kïˆnâÉúó°Úз1 ?Ep ³ x âUÞãiYp{?ò7 ç"Î_vàqÅ YéŒäjNiš²‹ßMƒ¯ u7GXªz»©Q´†œDý [xºw:(•U©WŽûºUg“+Ý®J¥ÌMãÜóÁÕ´\Ô<Öódm†EÊÆÃ}ð•©Ò4 ç ‡mV/ÒíÂNTäÖdT`mÑŸ$bÊ“cø)òç*âÒ³(ºdÌk 9n’ÛÅMŸ»Õí¿˜OòøBIHqvˆÆÜÌ«¢#¼ƧǾ+¦xÆ¡±‘ñØõgÌÎÞâ 1NßÈ^‰€¥¼.#·åZPÎ}ªŽë5Ò6Kôµum>MdÖ“ ]´ç+á4û00¨¦–ËqÜóÕeIÏ-»ï:¶t+÷üT‚•õžŠ[8µ+i/ëm¤y8̾mÿÔ”1LÆg]&Ã*¾å×Ê7÷÷‡0ýˆÐ´Ç@ wòŽ]4‚Û’Û)ÅU~¹·é¹ab–AD{òTD@°[Ûù0·k‘Çn|çÿ˜Ñ9à"FyºWQÿµ½p̸h̺KŠ×¶àº¨¹DÕGw@ç»Æòü A·¯| ’gÑ­~0üv?ˆ ž©åôË’xýÛUZ»œ´æþ°Ò·i8qƒ?ï68DÀ§_3r‰±kñ–h‰p…T*\: øs wð ‘ãCzªi³;ßò ¤ýÛ¢èð´]#ãm /6Õqå¾:ÃЫ֒û Ä9éVâ{<îÇãCR‡«qÎ;ä‹ ûâ³v¼ÞFì4J¥Ä;{Ñüº€Þ?ïÇ!ñÇi³NMkïuf™ÇvŸm« ¹,ÂH¶”,I˜F›tÃLó‹ÖCT²=€ÍóaY’éwi ªå‡éeNÞ[š29ÒWá¨R#EW!ù^J#hŸÊŒú%râ² ï¸ì°~¾dÛØÇú™B(ž÷R…˜ké¿ó- ¸#h$fɉàƒáýí 3¡å(Ô fuE3«ê·ÐxBÝç£õˆ÷Šßôæ°Ýœù£z®ôœ#œUÃ'«ãðÉ$Ñ$pXuëÌ“¬¥wT÷1hß<M7öÚ÷Å©9·çQÀÁ黆0ó·Çè–Ù#§«6ûiÙâ?åG> ln™ËmHv#ÁËa.ë2ý6ÕicJ¶D¹¨ âÉ ÖǺå»Î€D]«Þ‘÷RÊ9µßâvkÇíq·4ÕÁA’3ߘ¸~L% b^Ô,¹‹ ¦çG»XÆ‘M X76/’aÑBÿmævÊä2è„ {”tq¿lz?ൂ×Ôãýݶ‘ éÊ¡ê¦øÍöÚ®˜‚Tÿ7ØF;U] ©Èß74Óßë=ßqÙ¾tÐ)çfì^ÎîÈ£>[ˆÂ•:õ#1UPzZ1$°DKmìê"±nʺ͎L~—¨hè¬áØDû:PÜZ]ä £ª$a†i›.YsWCŽ|öËAb÷ȶÜnÐó1áÄŒ9²6áêPî ¹¼qŒã¾Åa– 6ë4ïÁžoe™‘”ø÷¡:Ÿ”N1¾…GÅï÷¥eæÐqÏ—„¥ oòl‘]c²c­ñ´8,hî· ŸY¶?©syܧû~—J«¥³§~ S›¬DCÓ·ª™TýjÃGQѬł›bòÎàò|^zŽf¼·Ý fÆ ~®7jç»p?VNS2÷èdpëcÂÜ—ï\S¸½@¾û—«2ä<¡óð9HWyvÇéAqF Œy-»=/ʪ^ž)E šø<-sÁHÅÒ‡)Ø{…qQRE«kŽŠ~5{EòHY¸z½,òá¾ÀnåL|Ùày!qô¦±3µµƒ- ù=k};žj¹ß•^JZéËRÔYæÑG[!BWôÔu8¾·Uq?vÕn÷Ð'QÅæ÷E³’CžªÈèÛ=rnË;«BϰâzcëZ‹Ëïƒ[Õ˜ž­ß—| ~º·Ò,eò¼Ú© ¦%~1bt…úî¶>]H2I ^J8EM_ÅÕËf5¾2¸†½@Ýsog>PGµ± ¿ÉCŽzw@»ýC4«NÇ^ü' e6Œ¡gFºéœù/àÈ7Øwà¥2äX6srQ¯9P+l×>ÆÇÐ#œ§G±>ì€Ç ŠòMÚµlž<,ÞQw+[dï[©\|>§Ó‹›”“;ëÍú¾ŸÞ °>T/-3ð¡2[Ç}Aåòo”{ø>=Êô™‡Cþ >úÚÌòyä$N˜GÄzZý<‡GÙfÄfüZÜwÑ@¡‡WÛŸ;¯ÑG­RÏ î ÀQE7iéië[ír#GÖ»´ü)3{ˆÂö:má=N€üÐÍWV¢ÆFj±¬iA°™ØPÿ+ù@Χçð/8RÜkVNoZ0IÕc%f¢‘úUžÁ:ÿØ´C}Eº¡0j”nL;ߓޥ¢YʰEp"ÃÉÃVHë+¾áäÑft#‰­ß×=žÓ|ÑõQúý§Ô€Öu˜7*3YÍFòWꃌ+ƒc‰>MÚ Y”ZŸ4D6\„ºs°ƒFxié\¤1™ )Þ¼Öw"%SeqMµ‡G4V×»W5’ЊM¤äÞâŒfñEPŽ2q!;"õ³4Ùø½ËÞCÁò§Šzòbññ–$¿ ‚aëøoÒÚŒ^„Ih¦ ;E²µ³^ÉzçNÏì!ˆJ°Ç‚%K¹=÷ÊÅ5\.݆WU|õr]E…vrn‡-©ªÂÉ'½6ßp^h>¼š\S}Pšè%o†SgKRDšdrÝá-ö'ðI ÆzÃÊ%{ø0 Ê>ñ¯©~–˜vjþ$;V¶t-÷ºéž·Íô«^oó dô@®£öY}ñº*’ý—œ´è«©ÌhÞïªùŽ!Û$ÅW]…rkn¸/BÂg‘x´WÕ+ p×[Ò?ø>"2ƒ/r¹LR›é°|îyÜÒ9M­ÕÔ_ÈËe.½Þ?1À§3N¿±&yj֢ؤÍ/´ä–Š9®Oˆ;·Õ´yAé â¶‹îæR2Þ8´sóB,ʽ9ýÒ¼»Ë:!œ ,“ÙhˆÐ±4@oÖ™~îˆf˜.þ¾qý ÎÂÁ0½TÄÍž§ô¢yOOÙᤘeå—¹ÕéÖ",‰Ü‘€qÑ{qÛ[U¶R[êìÊ8Ÿì;³ZZ¼OÂàE%ä'Ÿ£˜¾AÐ+¯T;%fv¬h»mï(-Gw´šù¸­KlN$-!N§³€jj2K±z?&é3¹_ÊQ^ßGãE~’}¸Èå³ô•;ï y²Nj;-(”ñg^ìgauØ Ü¬ÞÕ…³¦·WJt|ÁBG¡Õ*\áBäá‹Þ5`b®—¯º÷LÃ0„U½Î^èzË5©(åXDÞßέ!]7Ÿïôè:¶”âRÖüÝØÞþyã¾ÔMÁhØíq½­WؕԻàE;M¯aírÈ@$P>¸!c/0:|U »Øÿ30xîaÿ!€éx´µ–ó-±ß(–=ªíûÅüã–ìÎ43:ç|;m›×™ßîÏ\õPöÄyóß?—g*9¢oU7Ì _µ¬H*÷ÕŸR©â[j¨>G”¥Þ×ïG©dä;•¨!i—½>©—‚ÑŠÂÑ!<ÇáÛðÏ` O­»9–1^2yPjÑb˜µkýA¸†8BŽA§µ‹ë#ò>^SĦÊz]=±­¼õ3a5 ÌYÈÏò驆2Œå9JX,-3uÔ0U¶]d¶HBxçlñiØW¿A—W¡™´Û…LGQüQzø£­¾‚ë¸5jö=’ƒã´Øk3·i:{4?]œØWzJ?9_8{§¯¯çmë“öŸÇ²úÏÖ‹„¡•ÊhÒât‡¼Ìâh³KË$VÖf LÈ’H+¨Óž€LÃÞ*7G¼·sÓ~¤K ‡ m£ØûÄÕsJÞNµ8…ò¦z´?øÐþ½˜¸‘« »méU8EFìYéåDžÁüv^´I,Ö©ªhUïzNýn êžj¸\¶(µK¨7m¹^U™~ÛP•¡¡nO|ÔÞäÒ÷̧÷ÀWU~zÒ÷n„َ͋ɀµW“^4 øaÁ,}.„È;¼æOÏ_½ì Ú»Ï<ÂŒ,™ôRËÏ1kâQ}dÑëô¬O|Çáßùä&Æ4¥é#ÅD»T_DíuçõekºF(.->ç>Ž'¼+ƒèBo ËLêT(ȶ±,ÀŒÉ?ÇÕ ‹Ô}¾+ÒÛ¥D€YTšAUaƒzY8îNþr4Þö|¸»þƒ÷««ò‘Ùæu QÎúYdžѳ¾¯D ’Mã¨i)I¹"._û–ïÎ_øWõ«ƒlÅC=Y „Š-yè—¿¿øàÉZáèUªýN¥%rŠÎ÷HÂrñãqûÄd»‡¤ õ¥v roùËyOcØ1‚A:í£#„„1üPu…•!dp¨W0…˜ø*_¡í]]²ÎZ çè‹ú³©û–ëÞQ›ÍE~®ŠÌma„µ.'½–ˆ7\‹êø«¾6‡,¯Y›&¸ ¯WÌ?V¥ê¿ñFŸyD{.Àþ„ñAˆQL³)d×!-¬Ð*i*=üŒt\±ü®aƒúá %ð^Qcà¶¶·´ ßD-?M5K±°ø6éZx¼¶­'.Š.éS4e'£M‹›Q±T¹—Ú×唑ØoaRÊ&î¦R³ê×ÑšfH»Ô§Œg¶6€<áµ;]ý³Iøä")nÉáÈß–ú{ƒ V%¶Ùù£ª¸Ç Œ~…l>åh•³JԜ͋YÙðžù&>Ö¤`æ|©«ËjÒ!¢”3zIƒÏî3o“†ÃTý™·–Ÿ«fî#pM„ûJu/˜\p„Ú¯ìúð¸ÑÜw࿼Q?z®õ)ï•RI¡Ñó­5.<§Ç ËNøÓVŸ,Z¥‰=Bõ"oVõ¦ÒÝóà‡¨‰cön0Ñ[ƒó‘¯{Ç$/PÝpÊe؇òDI)pD[|AµKa¯Ó–k/±’=ŽWYµ£«e?­Ê'¿lïËßaxñV­z¨èkÜBHÞ Ò£|NFü×B ªhî’<®Ò ÌÈ@ü*±+_cœÜÁ‘áè°y&&"wëòµúÿåwÛJ[ïçR •o3’™¡îOó×V À®:-±—¼ÌQUJWÅíG¸o³Újá|ÉUÄ'åÑo˜˜Å«[)#Ú`Ž$¼ÚM¬:QöK#¢F,$"Erˆ®X(7MTm«ç‚gŸŠy¼0?î¨ó×U$™gmˆ:8„mÒ¤-yH:Q¿ÌmG¼ð‹­žørÍò„[s…õ6dD¤/äV›nŽS`ì¥Ç«G4Š{F^"ج¬É‹8fE÷Ö¦„ⵆ?ÑB.¡o3žŠdçÊÔë[ 𓊕¥Óu ²Ú´Þ–JN…¼S=nsk)Š6¼® ì"™Zý¤Ð*@ Yýõ¡%z°PÂ{˜R¬F…/ËTšT üçùÐ-Òö"§‹Š\Cç´óÞ(‰7xd?÷×­/ gëÍêZHHŒ ó<ùÐú‘HÑIó‰VÎP, NÖæÆ³è.0â,õ¦aË@_sz|[îðÓ =å˜Ä~²ùL»Û=7øCÆ{§Â÷Ó7»z[zÓ(|&aÙ˜ŽÍæ3l¡'M4®4¸h§Šð¡T,C¨ùfÆzë­“Ò«ùjŠHØS "Op )Ær·ÝûRWŠ™C/o›Ìç Ïà":ß劾çR/ç·ZVКœ¢e´ö.&™ Ãy$‡¢#h4d gÊH*æ<«Pp¸Œµñ|Ñ'³~©ƒ!Ùv—+¥òQ&€°ÊµÎ?ó';:ÓÎw˲•öWZø\“è®Lq:šZŠ ÛAA²õí¦'DZ¹Ë·(%&­8noï¿ ð%Ç8ŸZ'&“or\aUàR§Ü +ÕP{IŸ ¨Ó5“‡QÓZzaå•´ý¸‚Ç5J$?{§½yjP(•ŸÒ úˆòñé6xVе>Q fÖo"·¡Û}ŠÄåíÏÀ¥:»3§îèOÑÑ'!CÌ=`FbÂTQ¡¹JDM`9McrмØþ¬¸Mù8bTpBQ»U‰Hi«»ÿEÞUÉ—*›ö›J¼šõæœvÛ½XÓ&æÄœ@±€œZŸ-RT€" ®š‹î‚Ø]0Õ µ¥ñÌ‹üÇÜœZЕ®¬›˜g«¹T[¾b2mî(ºW=Þ(‘–ð% MÏ秆¦ú¸¢w%ð|‹_Ê¥‚ÒŠ£å¿A߯Õx Ì\/EºæÖ³ˆ££hÝø8,Ñ75R"Ëéxšbù°Ïm8E£`ÝâXº•JBºßnïE.ktï¶²ð@÷Êð\ºÊ]mz¢‹%÷ËR¼|DˆíÍO tHˆ=™Ø‚œUÖAø75P½Ó[ª*†#ÖeNØwÏß•ç^r{€Ô#Ò(i®ÜmÒ«õÓÑóÏ$QÆÇï„Er«ë§=û_Ç}oÙµ‹(©J<|ß©¸ Ù ñ¾šuuffv‚"ö¥i£ø|½6ÂÚ)Z´ ø ÔÌ3½;À;û³W=/‹ÚEJr‘“0ìæ£á v`Ýv8t›mÊVGÍák+î@¾ÝÕ…| Êô¡ÝäÊ5¼ïÎºÈ þHŪoû> rt2c²KæK Òñ<Ìß¹A¬Ñ=!8»‰»{V{ÅkýCXªr)Ú7øÙðB‹ÅIp©[›ÕûùÌ(žZã$F8Œ'OÛ+Ø ùIܱäW8…¹þލÅBŠL 9\ù¢ÔX2Õ$˜ê¾o¡Ö ôh`pìIXHоHJäG} –XO6c9 ´7|L¬Ã/©öÊÔ"¸îZ&sõºé“8ˆ0wï|¥øÌ¿I8Í—åóµH‡ç¨nµúvÔ ½”]!qBÈÕOX~òÅ~½÷4”GÓôOÙ«A¢{´€”=)ØeœRãÖÕ2«“rU%/=%’ˆÈ it˜À”[c(ËŽ…M$£:=g¢5ö™4‹ŒpƒœšiÏ}ûßLÓ•ù l¤À!…2î·Ý?bV®DðDfÂLëµ$ƒ3Q_LæñÙtªák}§é˜ùD7BËí<óqXéPŠkÁ×É,<œ1ÕVÎíÄü î#éËŒñIjü –­fç)ÛçC‚åL”:.QU]¤ ås«€4)á–ú¡ãÖ¥;+„¤pËpåÁnj¿þŒ¨žY“)X“õ¤·S£.ýî;÷\ª÷©Þõ%þ½êqQT/ÇCÕŽßÔ¯SÕZ4ï–ûãxÚÏ"Nz¬SG©&ÑŠžö²\ÑŒË'Œ‡,×JßÏ¢öÎÁµÕwøÂ¶M8}Ñh|í2CCt理 ðI­{ï‰pª"RaV—E<, *ñJv,¾<Ï=Œ¡ýF¼Wgúéàa˜ÎMájææûm8¿³wÏã¤ä ™M–‹¼†CBŠ)»…jL‹ãu¤)ÒâéÈN«Õ••}0ÔãÙ©1MŠ^J hs2b›p E?œ|µ¶Gùò wö}Ë4¯ò&ÆMA š)'«ài<Ü%`'êúbÓìyÎ+ˆ‘œå1¤'Øüøä9Æ»³(–˜635sä}ÂU|+æ+]`>ç¸}¸¿Qìãß„%õ9Iˆ%ä4ìR(K‚úØ.:'Á \::_Æýnø½‹ sZÆ4ùŠÅì6b¦ážó·ß ob–dÇ‹¸v÷°@„]Þ”³n·Ÿ—¢&bI u‘.b1~,¦æ6»…û•¤Çy`xd¯ÍÎ*÷E’ÂebI+Hˆ}Ò?M}ò‹MKº‚óÁ H~2×G‚ƒ%f§ä:V÷ÊBÅþÞ@êÆÿsÜðVåèYœ¬ªáS³¡ei&ž;ý<_4ÍÁ›õ–Ø]¸h]dpaî3Íy" A¥åŸ£l©2*èÏ0Í+öcÒ=* Ê;`>¬Ê¾ìë•Ü.4®ùÙТÚ]t%^.Céïî¼¼ÝðÓžåü»»Ž›Å¸ÑØ|Ú~ª¢j_ôTk8Á…ÀPý\÷¸H½Gœ=Ýìþ›ò¯ÛÏ*<°ø­J¼‡øäAñ(JÚðþ aöÓsó•›É>ßÉPñ àꇋZñ«l°ˆñ\‡2Ma`-×R,úšpV^˜}£ý&­÷Ø×¸€T+)®dN.ÚŽj”ê:ojjxЧ,Øz!¿sß§Œ‰ÑbQ]¥õ,L ’l\™ºÎÝõZZEd¢‡9 q—>v¶ãÅÑ{úW J)„ê…Hýs‹ ‹Øæq‡—…˜äÅ7Ñ™p|h^'·P#&‹k6OŽhQÑîXm31`™CÈCH‹y6_óKøÎ{9²ZFʆëY57?ÂfêÞ ­ÌJ8eåSèXã¶E\Ì)D´¥ÅÂZ´âŸs( ŽÑ-âsô)Âæ#"ãWû Љé%gjéãx3/í!àÙtöÅ58;á9]te%ú5xº™·—&ã\È꽺ÎQ\¾Éœ2¾eäöà4¦´nyØ*»µb³4æì0¿%í*°Q}æûVÐy±¸Jýòi(ã)íÕ4¨~áávGó`ÜnŒ>bhP÷§Qm/q!m©ë4N%ºžípHˆ ¿Â{dk¼³FR†ï·B÷¹£÷¶RŸa úU^6ìOà³ãÒòîÏ=é¸ÉK8¥†ƒ¿ñ 6µ›±Íƽ ýÐù½z~Uxs“iß)Ö@àLd,/ï¡áóÄÖ¬KÍÍûüÜ´d¡nµqÃjDê‘}mô8QÙþÜEñÑ[âQrùÃΣ7îK–+)ýX2·ÒLºðI©6\ô9¹Òž?2,±?\±8\1/÷¹q`q (Ž ãÑ‘b`ÙKÉD°¼n#—jëO‚ŸÍ v…ñ_Æ«h£kD’é÷ ÜÑJÅ,Š(*éÜ!QÒån½®9ÝE„*Á˜ÞH'œ [ Ù…u¶ÚÎæïÅæç™VØw—{Ó¥âŠ= nO³ÝŸ¨ÜއȪîSik ìï^¬O%‘‰Þá°—e⣗QoØ!sy•w¬à•”Al?š`„÷cÃeÂÑqÀ[w$7àSÖ&=DëŒb­æfè }ãù`¢xØGÏÞ•pÍ÷ÌéS"N´nÈÂ*6I§œm2ª“Ý ’¡ˆ¦h¯GFIОëÄFSôìT¢žHú‚¢=º\cî10ï’Ý+qÝØÙj—qáíÇÄêc¾-¿á]\ÝQ ‡‹=]ÜÔöv6Yv’‹V¥ Óˆê<Þ8œ×Oæ§qW –¶©•_TøÞD³(‡úa¥öʺÑã#P‡`Ý?\ °à 7ÎùÙ a¢Ð…ÉÁÀqsk»3DiAË-j‡N¥œ¯Ï©®‰arÚ »dˆA‰rô‹Ÿ÷f³C6HWœFã¢?EÜP<3ÞF—}VÊŒ!îØìiOŽkOu¢À>]³ï:Ø\S£‚$Q;UU+Þè6ò… ÄÒ}ÍÜÂÃBe°K.ª¬äÁÌE=î?kÁ¯©Þô ó"> ÑŒÛuROK4~œäÛŸYé'EPGÀÖ ÒZ*¹¢åUk}Ëä"åñ5L’Ïþ0¹wó€Ê¨€„|Ѥ[­›,NˆúI7É;PÓN—ÿ­{ŵÅ–`î$¬9ÁnLO+3ûÇø)™²ž† UmàÐBm º6¡/:ζF#¸áœ?cT@ŒÐü3AMȹ‹0)©ñjÓ8‰½i;Ûm1S·™kì¨ßÖ¼€™H„¯Û½·Ï­çÜ5ÊC™²œX¤¿‘¯LR¶õ–šc”>Pþ\ÈúŒ‘+”'§$@¾ ÍíÍt\edÌŒÎL(›ÀèùϰïŒé_q¬å–Ìã˜û„šâß©v/¾hç6¼½JJüÊI¸Ý®ËH¢¸-Ýs°µ F}‚¨X‘ïé³¹ãå'éaä‡òLöN0Ž-ܹçÛ`2E¢âSÛGL0;uü ãÑr,°:ý€l'^LÀÈcô-õ\ß 2Rz‚*î³Þ㶆’yÊgå¼ ; z—¦7®K¾7]îmù‘¤Æ÷OQoø¤>Ä cñ{Æq§ #Úqg§™¡Å°-§Qž í™(sq0ÜëÈo"x³2q4X´’²ëp=,ÏÇbøU»8ÄŸ§š1½fg(µ¶Í=w²ö¿Il·ëš½e’ÜWLÙ{dHU¬Ûã݉»ï”HÖ~¢:}*öûG+ÁºNk Oޱò݆X_µ¹Æ_jö›£›ÖFkÞîë¢~õ¤DÔe æÎ+Œˆ@fþŽÔ´)jKÓZƶãÚƒõ*±°B¼È1LªáZwjõ}°›î;yg‹k±ãÊ’&÷ œsŽ?(mmñÀ“ñ ,veÒtÞ,‰°¨¥0aðu²–@’ø¢×G²šÂ‰ÕX€.pÊc×Ù>Í }ͦâùY.¥}êè»Ö[²M1$7V ë¯òFâh•ÊÃEòÖmÔ-Aå÷7UÜ¥)–üzô:e©ùÝeŠ;»å’Õé+6VFŠÙðZ£´jUƒÎV±ï¶Ø?l¶ÈÑÑ0qòXp|…9‚ë‹ñ£nÉšWŒ}aYÙk×Ê¥f§Exïj§2‚KL~9:Z½œAó¶™UTX «1a¦½©†ÖþÞv7é·’Øoªàb½_5®»oˆwíêl,"CEe@ eÇ(Òû@s 'ž;ðM˜7îa¾z½‚D¶cqãÞ"ÏŠ„±¨˜òTçy˜hì7¿’¼&œù§JÅÄÕ*¤®Åýè®|ñçn"EKjT€úׯ¯ª8¢"œˆöûöÍ ¥gîýô*;>oc†Ph¾õ2Ú¡ýx–˜bÿ×}íS»OWG.ö9%V/Ãø|qZÊ]gŒòëIHÀÈÌð¦|§+*O7¢ä¯å*alq÷6Õ„f„uS÷{î@ºÚü¶ðgÖw~Ý÷Š,Ï—%FÓ/²äÌ…¬6&E2úiû¸š’¬Q†ÚaéBü6ÞTEò¡¾ßõe'¿Fg azwÏnÈ¡¯5ÿ•Èöe]q$Jõ¦{õ×r!‚%¦Ñè®öä8ì«™ Ý;ÄQƒ-/R‘×\¢BÁ¨€Ä±‡Î}þI&QXøj6Pëþ^89c'Ž©³`àª%8¦ë$¡¢ Õ™àG¡Ê‰ÙH¤ý¸èéb‘ ãFÙ+Ò´’åA³ˆ!€Œ©~¿A—[é-Ñó=CLóìª x ݵkË@ˆ™0³9 “ÔKR§þQr ìï¢ÚÏ~Ƽ–pr³Ùˆ—3xUICdàH¤”TI¯ùC«qélJÓrÎA"õ@ÆöÂ)gÆ}l7Ý2®k+wE/.©æ½n¼sŒNšBë·ZQ,õ`»­[‰û1Q¤]CPËHZ­è qyêlBjýÕŽHbi0ºË»‚âó/Ž>9‘ÐìÌé…Ë…îÇ+ äæ/x*Î4é~¢5)á ,ðÛ“­E2è]Þä¿Ú|V9†fÊ!"w/ñnÂîÙVpêʼnXÙ&ß÷døÚ/Ϲ¿™—„¤n†ÖÚäLŒ?¦eûM/VÖee¢± Mk¤¼¥ ÀÓæ9í¨lúd»Ê2мhzY°i¾¯0•ë(ößI©.e"¶çz޾ý'k\ê[¯ýÏúXÇð Üi²l…ØÞ9;.5˜Î·fá ̺t£5exƒŽ:±`ÿ½o¹|Îà‰(1ðlvñ®àËRì(£%Üžèœ7»TÑ<§3›XsïÃg)ÕyÚF‹ùí+ƃx3ÊRRõ ½n·Ö!Äûû'ù’q -w÷Ha™ÇŒÔOåT4]…žœñRã×ç ÂpÄZÅôØsðL%– ží¢Þ~Ûîïy"k%Kèõ¯[ˆ_n¾øG'oÔvÐŽ`‹;)Žó>¹G¼@ßóÊÄ÷o±fÉùÁùŸZkÜlGZ{1›i6ð[#'¦¬ÈÒ:àVšÙX¡ñ$c^C²JØY9Ìyk:føóçš^¸8:œþד ¶Û’ /t6iz*‚çk> 2± þÚ8‡îL…ÙÆ¶mÛ¶mû‰mtÔ±m›Û¶mÛ¶óÁ}g÷?Ô`×Zµ eßO EGR}Ì5†l÷Vßß¹€*Ë£\‡b,ZãF´1B*wè2»M›wzÔl? uj­o[‡jÃË•QÄ|¹Ê7]$€Dœ“4Hðm¿!˜ˆ+.Iéï˜@þN4ݘÝ8BÆëò¹4ø‚¦v)óÃcröÐɃ›âÿ[Tø×ðþGs¾¿‚»º,—Ò…6}•ƒz$†s‘b÷p:"ÏöMB™qYOÉc£…±Ÿá»Ë¸5beD·t¤,´–Í=qClŽK: ¢Jr¦ù²s£þX3)<!° _¡.ªy¤ޤ=ç¶Þ×ï¼qí5™™ççB§#Òí åk©F‹=âØÕùì/ùïP¸úQ¶¶ªå­iêçipøŠõéµÎˆ}¼ÌP·~ÓÃIlÖ?C°[ì"°nÜñ©D1¥t6ÚÚ3ÅÜžx#’³|ð·ShÏ!+]p™ ´ÑÄZ`Ë„´êT;—’åÊ Öir»*+Yîßö>…ʽ;ÚZ¬-ÈñЈ#·=;‹·û׿ é+˜CØeè¶«ºÜ!þ^Ó‡%l s¬žÜš O 7`5sÕ¢J•/{áøÂ‰?)Þ: jûRûÃá<¹ê°é(JS:¼F’Ñ>«óÁAoP*´W*FÆò>tGÝXÄWÏÌ«ô¯â^†UYÆ]šÌ:ñÏ%„123BÃ’ì¢e@âtïœÙ0ãGWUOÙ?ñ:ãm W³x& ‹ä&ÂÊê·^º•au„×aÇT¼Û¾á°î[›F^së <boɹ•¨BN©šÝZ]ªóâ§"íú¯3<ÏB­Ûåç;É2fý)’¦4ÄUü§m_0mQ÷¿1O¦jÉ<>ÊåÆºåó¡׃+¿€|ôƒòñ",´HÄáAjJÆ·×)˸üÎÎÿZºßõÙ0pMk¡8ìÐÿ®S‹ƒü&[„ ¥jÆ6ØGW{¯Å ”‹´Õð4§wÁ.}Ásº |¤û9ð´¤HØ.ø…-€=‰ÕÓ÷‹S‚‚©¾}º¸ €¼ÚŸÝÕ“mSRÉ"B  ÇyOfŒþµGÈ×s—é8 r=úÛêIM3gÞ“÷ÔðéÜ»<^ìŸÖ1ý~¤§IÞ0"‘F«òòžªë¯l¯'Üx«bÏͱl­ªB¥È!Xɵì{Rt°è«ï‚éåjÑßm‰ë¬l›=ù²>©1Ûí€ñß§¢0cXþE ŽWÌgµnønh, C{£ÉÀœfÌa`ÌsØmëÔ$^ÀE?V$jµìÖÕjˆžÏ†îá³á‘ñ,é´`VfÖM<üÌGÝiZ{záçÛº›B×zÝNvQFû…Ñ:,òÌÝD@üQó¢'ª#ŠžíM1ÏGÀ“—ZEèÑø!9âDÃê²ðÎÆ…|“RÍv9¸7éc¶ÕÞWªtË%ËÚÅÉ ½ûìüqJQo¡»´..5ˆ¾Þ±¹ñ2P=¬Gõÿ¸6Ç„qo‹b>ÒÉ¡“‡îœXíÒõà8`u´<¾º„{í4 îZé‰x| Ý vÓ‰÷iýÀ:Àõ.ËNY×P뵉swF¯³¾ñJ-oþÉ ì%éÓ¹¥jårj§)4Ä2µ >Œ5`Tþ¶¡“•nG6jšGýÅEA:A#9NѰQ(6©à[Óû 9ƒŸ»BZA$±W"a,Ø+ÿÕGÐd«^·§¶+>9ùK¢â=ïƒ:/j±ô§p»ŒµB>ž®½S;¶Jè„ÂÞU™‰<»dñ¶$õXu/Øu;³ËBhå 7KL•µgºõgÝjkD‚ÃnÌì·¥*·LâabT6®P8E#“Ûbw¬Eèt̽ÖUp¾Oäœ-f½‚]€·Âæ„5Z êX¹ß<‚¦PXt¡r… ÚZä_äÖæ('ÚÜÆ²ü J0æªò¶ðšˆ÷’x€S$_×Ý×—*ö!‚ýuѹ‰iýÜð&‡+³ÌÌшežkKù3«ÉWªg7¸ÏÿÊ7¡óe/b%tÊÖ†€{OzZ÷îó¼ï–Éÿ³Y¥ø?\„tšÙuÞ•ôˆ<ÿ%ê"hí9$)Ö»Åû¹gé5I‘·Ž¡°aŠÙ±k³SG.¼‹,—‚½­Á¬Š>¾éH-"ýq¤W@ïƒü•÷D´V ¦ÂCŸñŸØY:¸ÅÚVáN¦.f|D‚'ÔÁ9^.i¸{O©x¾ï êP.žÓ«úþ¿dÿˆû†´-P¸>[Î2þÕœNœ.Fv ™ÞbþôûsÌO©=SµcF|2d¼Ô‡’¢Í÷÷¡K?ήÿ©‹'œeÓ#îGÛKoûfZÓ¡˜ð´¾Í[{ñó“Ôp{—«½ãj¹a@I¾òÞ²¦õ¿þHÂzJõˆ@ëŠz-ðhÝúZéKAßË-5‹Çö;nEÍ -Ó(¡è†xÛ¿d‹šH6 óʳéê‚ ,ƒ„fhZö}KäÀüßÅ”Œ³ÈiôûîY¸Ûë ó^] µŸs„³Áúãø‡¨rDˆÈËä²öc¾ +ù·ŽŠöÓ½ô¢óYz'šáÛ´Ò`Ú7¡o«¿¡ë?ºŠg[Àk/$W?‚eƒ´j%”±-Rm“SÕ¿– ž“Š1óó €¼Æ'Fÿ|¸¦r~¢?™•OE¿M—.¤¿(ã»ã>ݨ~ªŠÇ œ¤‰¦K•£ 'د$B ?“ >òÙÁ3ÕƒŸªõ—÷–[0Ew ݱ0ÕÄfvÙŘ-Ô'BÞ«T?Xµ2‰Ëß¼3¡e³g•c–{]ê÷Ý&H/6è•îk›oŸy½f² Bë Â3Ëô;òÄÇ,ëÝ*ªu Ë©@²¾ÍI:Å>µ´­W©7®©Ùàv!üˆ…,¬ 5êkîé#ðz[³ËLE|3SÝ*¶»@(yUèî²¥ª9PP~îQ˜Ñ´õ`­2¼Ýf3Ï>»?áxJËrIC¾$$P× ¿sQñ%J£Lˆà÷ B.×àŒœEX|!ðê¹°à§vx™jyuÈdì+|}ŽÆL=…¹ˆ¶Îr+[ÉKƒXÒÖuq~l}RÊ~5–Ùx¥o>›8û*nç\n·&æ\û­‚éNwÌuªÝOÍ^“+ºâp‹hòÍ6XSŸ-¥3>Ö@Ð0i|?'“´(ó$èÑÎ|VÍ¿%•g­yzf$•ƒžË°?I¹r*j/1&þ ³¹l>üG¡Á¿X72á?š6‘ÄÑbAàZç ¤=š>÷CMZû#?õÞ‹·5j,¶J ðQT—šì€¿ee>[î¤Bó—òŸ³p6ãyU)ë=!Ê#aóFÇv"Ô¸GÒ:  ÷NhËÆ·•x ?œò;ylNºðždZâOk1ÙWVýÅib™¨¥üªÍI–„ƒ ?m¢Õ^8mô øC«üUdÚ_Ûɬ—Œ6žYàdl2?#ql†È5Z/üY­!âàxŒ}mx£æ±#ÌZH/Ìú¢ô5}š!{üÀ"‡¼>x(ybV}!‚µi²9 ñ¶e#CÎbW¹ñ×¼¿ðÜár¡ä“ØU@ìö ˆß„Ý3îŒ“âØ½FñYÖiGþÿωXuCÈÍæžÅð†÷î×’omåÏÙEÞ:,¥&åøDxA^ hBÙ__·aÌÓèóÆZg-4õW°wÚ³Dø»KíG€ô>ѧfXhœ¹òP]»Âx€ÎT z¤±©mXϳŽN¾¸4‡Ý€ÂØz'¤PäCªÓI4 /“äå¡Úâùè½µj_ÐB0j•¢äüÒ &ºÊÇp°«Ã5œR/·±]SH‡½¤dÒ{F´tc;;¤Þ%¬¸p[ÏB–ìâ±tŠX,Ú§‹¿ƒ7|/EüÃË|„ÜAM•0ý#"/ ¿D¢Å%ñ‹¡ô’°¾w,þØGc$'Ž*µ7ú£°X¾*àw$äŧžQthC]³×ÌÝz¾ÁÔº ÜYGH…B ì¯Í ªäÆÄÒH§àÎBüŒ Q²r“iÑî÷~@;œò*¸Òå¨4sˆËÛ¯6ý%âôw\†no•õpÕHè: ~VOKïºÜ•R=7HÐeHbˆÛ4Gå”Ç•Ñån\Ӝʜ‚X óxQ÷¦˜ìÈöŠòš·ò.$Ë! ÛìVh)|ÿ‹iLò³n°¨À`Ë6Œ]ÏÐ'.ñÎo”’XC6 zØ0ýtø>VJSÓJ´Î'§FÑåý˜žºîª,èm2Õ# îTú•Y)¯¥ÊJÛb‡ÈËP*óT¢Èî»Ì"ÕK´qþñKQ÷¡`i!  ²k—¬CVøf1ø+þ/9RHÇ^•hàúm.ˆ¢{T%— ™äoŒMÔ¨q?L­cÊÄ‘f)†w#íÕ@ÁhÖÈ™yëjS3õª: òeº=!ÿ®Î©ë#tE×Ihw­ùìHÛß>q–H¢ç•÷5ÝdFžÆÒéeYQ^Mýì¸i'ˆ ÁÚǰöæÃ¦ ³P…Dz Mäéø\1IU·¡tlCr’v¢HÊõ©T@óm| £a{×”œû$p¹ÇÃÍ® í&ÑøëZH·HŸü8¼ÜbD!Ó=CÔÚA]ÝÜkÖ¨éhO€Ï×e@XíOšùü9Õp¨—´a¸†nÙ?hˆ›S­×¢Š“8ßpr*ƒÞ¸zŸzåc’ðфմUÞ•ðC)Cb–¼xs®›X³Í µ÷ˆbÞÚÚóª ' ÕCkTÍ/¾™`?ºÙ;ÀNšª—Ñ—d“ÊUŒ–È5$·) µÓ+¥$©öÎ]­i‚p‰´¼R±—МÍçôÖ?}¡KêmËZ›óä0<>A ‹dƒ÷q2–ÙìB(¤éæïþ%MkcL‘™“@Œxìtê3•Åȸ}Þ$‚P1Š2Ê~„ ˜9Hr g?•'—- ¨†á‚G?ïjiˆêÔ Ç ‰{ìb²Ü†Í†Îà&—é2¦ö^¨¹ü:jTÚõXOÇÎ?ChŽ Ä¡;g=lôbƒú±-4}ŽÖ§ªÒ@Â?€z*3÷ûå_:Öúá«øŸC(ons×öžm¼äÑê»hƒ—a)[ (›mn%¬Ø·•2³ÍMx"pù†Õ€F÷3ªü@‹zÞ`´©ˆ6– <·l}wލ>x‹õ9à±ä48D9¡s–82ÀÎK¶:¸u+›Ë¦­Ü¯VF~¸HR÷¥ü8Uiìo7r+éŸ!ŠW$ ˜¬¶˜î‰ûÒš-m®½ˆÇtû NIÇ]À®m(vxvÚîw<¾A}…IVL«†HqݤiÓÝÿ¸Œ"W!£»Ï3pg¬š`iò-u'_†™Bî€âúúWbô½¢¯ß¤É‘*À¹ü2o1rٔϣHS…ÆèÆÝtéhrÄÀàá¡5»½UªðìÊ>§x SjÑBÎz¡ÙQ×0.t¢y‚ËSHÿÅlN™‡'ZK8ò kE²t#§ë¹N ²º‡e?Y;8I;'7ÝÓßo6°83AMÊ™Q±žcÁFøbvG™ëüjò·&虋«On*e;¡£¶k޾÷tëÊ2ßã•HŒ&B§† ?{·¨iŽ]å>,í5=ž#߈$ͪ÷HŽ›¢9MªõÈšüi'’êˆ-'•sÆÊ“YïìÆ€½²rS.a‘c´ ýPŠúž_$Ö:yMós$%ƒÍvøÝLD‚Õݸ].éyrø­â>$¾hVCéç+UÀi}4œÕ‹bôۚж!ªîa\ØjX¤ Š^ø;óL…&Ù:zÚj˜&œFž‡Nì[äJª†)˜q–AÁª¾:_¶Û‹>úS.ee5qÓ¦¤6Cnû¶Ö¤Š6@ê8uéÕcÇ—"®PäVÿ€óà {ƒ§Ñç—³wLyÒûghŒvË÷MØéß 7îËššèa2”þ‰kÞãÀ×”1êú¸ü6µ´k”¤àòSM6‡z†í?¢…&ŒÌIo?öüsRÚÂyžzq»2úˆS|„át“x!ÝÍ_…à%h 8cÍóO#LGr¿á Ô…—4I¹eݯwi‘€¾ê¥²í Ff¦²B¿f5;ÜîÝhàh·k\ë*@Ÿe×£WšˆCŸå`mr¸ÌOi ål&:xX—fñÚŠkOL^óeB&~b}=߆3\;-Ï6˜þõ}Å›÷Q•µN²¢*cmùïÑmñÓ ú½Édª ò 'Å@|¥#ì]b˜ D‡Ž5Ê3ÙV(ü;óêò³#Ç/kIZîÌ((7ߤ×Çëõ›ïWãl,SR¬ÿÌŠâ.Í£1¡8|¶UÎè=ø’’ìP!BÆðca¿@³Ò!öl‘¢èK¤Òn†ù€ ܈Âö"•†u–¸Êë»í×?[j®ZÀªþZ<‚”-eß;Ú‰ÙùÚœ ª>¿EPHG©á­Úí)ÝÜBw+û|”0hÿæÖÚŬ*¤ ˜È9Ò ½ò&¾£¦­•«EÞŸªìB“}cÆ ½in )¶Õlü'Î"[›ÁàÂb ´'Ƽ‡]¿}ÔKf…«ÆY¼ÝV8é^0ùb2ºî7Ç2žÓI`X§aG~[Iç’¯¢ÏdÈÿBhNu&¼èíD‰{ÿG¼[úãû†VWþ!pðmŸ þù| y¶szqfº¯óRÌ]&ÝÕÆ¥bô«·t„[¯–Õ9_æ‰sžB\÷´H®ýgÈÜäד·÷UzÄ Í¤äœ¶”4wý"1:tG-­ç)g­l}G<Ú†F¹àx­v2\¥†¡=>£Q*ÿÀ­2l¿¹C´rz^ö-õè•°ŠJ…ÞwÇýÀ–KH2™ŽiÎRBõ™–›ø(ºIâßóryd '̧ ÇÉÄÅMC…¯®Móú‚IÝ(ÊO­¢ÅkЃ3YÁ§]$lW&º¡î²úël½$™!t±…®ÔˆãŸVY<Ôµ (k;´#c%c€ úÖoh¦ï`·hóß]ü± ðIU6!µ:†ðk1|ø•OÆÉù©B‚\\[ ñ¯{!  ·÷¹Š Sf"9×Éc*Rô"l|°ûÇ<ð¸¯Õý"3KL>ùh7O9cXR¦oݶç.íRD“IÏ¿7_ÿ²h9m–PÆnhÂë4=?"Ȥ¤îI´ZŽïÉmËóÍ—´¬{Ê(§s€Û]º_u>`Ç&Áå5 œ×`¸[€ÒÎØ¯dƒw ¸MÉös)9zôood%ÃWM-×ò·áä=M¼× þjÛµ¬Ô“toÙ}¿l¯œõâÙ]Ý–H&œp'Ä^]§$¸Œª {°ƒú¸"í­³˜¾DóúsPÖÇótraV2X_…Y¿AKiKê(‰§ ™1í>¶L ½˜&•XË US:xÞ.·pZB™^×zµ <2dêØyVºXt&°Œ óÐìbv¤ýíGêU;Ôï“ÏÓ[®u™G4}ô Áµ/É4,ì“ nøÄn䷨ĉü^JYØQ#>”(…0r¿œú“…³‚è@%œ°&V¦ävrä~ì:pËû«s•N:Ýœ© e`ݔͭ»Šháp”€)'¹Ê€¿ÇoQ;ëj‚2ÐÅ…ÿ!ïdž˜Eâ¶KŠÅx¼ÿ j´éõîQTº^dú2 £©f)É0×òûõðŸ;6®9Þ4°„h.GQ±ûŽºr ±Š¤·ÿÍ—†¸Gd‚…ˆÈ” ã¢%qx`°M1ö¬°¯Lãz4Ñ<£Ÿ{cÓkM~TºË¡ ¯¨xÈ÷žQ}•]¬$Le‡² `KDa¦b8‚›øŽèÊx™f"XÉ^ÒÚ>´^(Š·¾ZÁìœqQT†š!lnÀ{#¨­I pt¼}¡÷äMbÀÚŒ̳©ýöüHŽšCƉyÝ«<Ûò(BB`RSý*ï¥áp&üãZ;G¯º.3–„WÓ;iÛ!"Æwsg¨+c™p, ‰CY°áTí]•±wÙ—Í ôÿR²*EyYÌ|ôiì~ YDÞŸ‘؃n;k©jn?PzUEî,–;ÿ³„B„êæc'¦–:k®'×Ð8]TÀ¡.G}½¸£Í<•Ô’I\[}³Y5eK}¯:üx[wÁäô&<Àën‡åäkí¸“&F;1ÒÓ\Ê­ó„:ð¸EDµÒ6ÔiÿaJOà?TêhsóÊÚæx¼e²¸¸||]jÀlûiJ´Šwv\[GþfexwÕ7‘¦Ü“aÈñ¸˜ìá§Äã_ð¡zUS!pÒ½@mK έzyyïuLŸ™´— ñ¶î•Cú$ßP…„£íC^7ŠS¼kØwŠöt¾þÕÄãpÏ2Ó¶Dox×ÊCG¯rò#7ÖWݺk?à²é…ÚÛC>«~³¬°uMIŽn:À­g•íæ®½`>˜7‡üoü ÒAÎó\(j+W¢îÈxò§ctGµçzaõÉR]«[*xî\…NÙâuâê)p3#ŽórQ¤¤ÙÕ‚ý ¬;|…Aä(ËàD#  À³aµ’L¬¿†8XùU8â[!¾eùé¡m\Ñ“Å\€ xj,™úÒ˧†åeã1v… ääš_µ!rkìèú!±ÉtÁ öгf¿ØêÑV”à'©>OôúIkøD "ÆDܨ§ö@ Iݤ?ÍP-Y]¥öÁD‰úÛ#u¬Ã‹E¡ÎïéX¶¼#ãƒp ½|ÊnÅž9“hÇxÇ´#…'$õwiƒ ®2£¿+¶’Aí«Cf õÒR·’0&¤¢™\ÿÌÖÆmyýîK«õ×lÖ,ñ~t¾ßT÷Aà}' OƒT[æ#hîs”fïÇNî‰g$½ûI 5Ï%ö¶ãD§´@P{šsÐa¿ƒZödn·*âÈç¸5=ÛèŸf)† W°·¡´®}ñ›2+8.]pø4Töq…$ æmŒŒÐSûZPD+öòp!ÛXWËyëIP‚L=†Ÿ˜‹ÐÉð9:¸»P„òÈ £hÀ¯î=ð™ì'~VÕÉ¢¼x$ƒË‹d]#¯ñVV°;ôúõ™2uùÂÁÀA10(K~Q³zÃîÑ0|ü"LqÊÃÏ´ª‘!NÖÆ”m¹«T‹ßõJnû¥OÊišèLãMþÝvé’ÎΚØZ‘:êá?«/ñD-~ ëCœÝLÈÄ‚‘/äfȳŠç/žíÈT\ˆ£æ1‡:k¿žÀùNJH`K1 '(¨oqü¿RŒ­ãH9Ov ‹Bдi Ï(Âè9+5ä· 7Ãx¼¢çø}2eÉú¤óê¨DÒ8R;  NÖ:K‹ÝÂc¥ÞÛÝÚÞßÇÊÑÖ"6‚ÁTúº0Ÿ¶×¿k{Ü%¶.ëbÿ)5%R\ÜÉ4öò#­è*á)%6Å×ù2ëCO\êQ=¯xŒ{ š< i™H?Q+Þn@z8â?i^¾$ÊR”?em,š-q‘«šÒV=Gã€O>‘ÅU&LS,“Tž-*–^rÔ³?7|zCüÖMcxØLôô†#sèþ€)Šeò4”£fwÕ÷5f€4³bU M!„i<]äçÍe ô̓gå(÷3S¤žBìî…‹2I?Ç5<Ú.a Ï–xì[mMÔ³öJ5ÕÉBQ+K=?}¦ÈG½ù3zÀx¸^! ¦©aœsðÑ}^§”ý¹5O|¢·Ê䢨Œ¯“ìE=jâ7¾ó¬auV4Dز¡?²Óê4—˶§uÖœÜ`ÿxˉcÿ,./8*?!ç_PŒ‡¥Œ,t€ÿHCÂ$ðl¢æþ›bBüOF¾õà¶¡2xz׬µ7RtvfS°¼Ëù¥ÒÊÅJ­Å·^h4´K°\ lÖ3”M•8ú ˜6gÀ~WÔVUŽqv,úrôZ¡}1« VJ«‘gã¨ÉÌ}=åÖ2`Ä—~·YMùqà¯TÓôòC¸¡¹%}“&.êB¬–^![ÏZÄ>±ºÏ4Ãö’\&TÂqAžù•°`é8¼¢œ¸ãá4±öÏÏ[û‡ÿ\¬“¹ÁÖ•Ó·–ìh©{:úµÔƒÓÝóßxëÃ{CºâÙÛ¢w,tIe:á®~£O|O~e,§·T†“ñómµE¥9ùCÁMÓ„;°pŠAÖ¦ú*}xg£¿ šÑRÚͺ fW-?Îø¿³çX÷Ž‹(]SYáFy‹Dmä™Ð÷½P°SˆS>v@~ç£h… 1Û€ÍѲTå•ôý½IÇÓefùÁÀ¾(‡Pƒ¢L›¾59_ª÷òÄÙ¿ÓO6뜧ֺ; Qí±ê²/ÔÖÈ >¶ßÔS2­«pÔ>4Fçm56á0õºEí6 éTZËmO›“†”ÛœžÇ´XÈÌxóHëài¯äþ¿&€/z@“¹íüq,_š½é€B=uãrrPBºO±S­˜ó™Õag·tP¿é ¡d Ô,qº[å¡1À_óÚa²x³"“[ 5¼#c³ÿoôÆË¶· ps rÝT}j±)„-ݛͻØd'‚weŸ° E Xž†oñk*ãÉ ‘ {KXtäh1‚Ü*&À:Ǿsïtæ¿Öl dOþï¦ßÅU5óûf˜ã7æÜö G/’\†‘Æ%véö’Ü®â›SÓõÚœUwÌlBLÊHÇëÆÄ†HW>&©¸hÖ%÷”ɯÛèËÝÚÏ1=ò­DÈá0«©c”m´|ظ‚%wÝì_šRçüWË©ßñ©ššƒ­ù+%këc“¢Ôiö>Zy÷8¿lÇðµQ®€ü×òm~lºe¢¤^Ö¹òˆÅ ÓÛÆé9j‹ã¾|çÜÇb;ôÞ2!I’/Œ‡ÚЀ;ÑÊŒ6y|Þ*Ï6‚ 7Šj -På\èÄ{K¡¶õ†«˜A(Úb¸¼¶>9ÿ÷+3^q^;É^luœÂ†„lÜ9®ñF9ˇ(r½m4:T«è5ôPò×gÆø+G .HGtüŒ‚tó:€}y!aN5Xk–ïϙ֡lôï–JÔ´ð½¸ï–™mªoI™Ÿ­pŠ; ½ª4ñz·®]£ lTB³•Æã»X‚ÑÎé…½ º®,uÈ&su݃“•ùîùöëö¹^ía¼]JIñ7ø¶9%}ˆzVšßì$H8q/„çR×]ô+ÔÀUú_Â.“–•Ö(䑞`º³¤%kƒÊÅ <7¦ªŸŸ3+žÿØåý·°mXæ*³M…Ö…©töUzy&H‡úÙ¶ÏŠõQJ¹³;’šÀïñ¶ÒïÀ×F+ påOÕì±S™­ [XŽiN¬=ÏÂRÁ#—«£Ô‚”à]ó~B£"¦NQ ó¡vr¼Š¶ÉÑݽӬe&î‚Þ <¡-œ‹ø¾”DìB¹6Qå1HŒï[þÞ“ÆÍà«g«k¨SÎKy ¬²Ñ±¦gŽZõÎpq“¬.‡=Bõ¸]&ØÄ?Nád•±Â>8'1ÁIÐy°ú DX¤…%ê½±(ªBuÙÛ­Ô‹ ‘|û*³CðÍ ¦7*W… V×ÙRX{Ó„ÚC° o-ì¶I9#…ª .]Ö7åÁ·còö9ø†ÁòJ–ü<-rM.ƒ¢³t.Úô¥X¤+löÚÌ: &ÒòÜ#¡q¥©²šK7¾ +¼5“pê$û“æI’C]íJ"{¡ÙÐfiªn€Qÿܼ›Ežd¤knï"ªúÐÎ,™ÝWçÊÁÕ&/ ©Ä¿À¤B4ÎÉβ “e¿WOœKó*ˆ–º--‡·ÝK$öÒ9˜4³wðô”£5pÇTȧƟ­¢JW6^ñIëE£Ó]"/ÜNˆ“Ü9 ]ƒÊ±ÃÔI4ÒÞ˜™—1x¾¨g•ö ”?H‹àÞ™’Ü#^³c¬;iu8äéÎÒfæG‰÷£máÎçeYb…¸½þWI¯_?O¯„\'üG¢f‹ÌÙÄlM&$¯—Ž1´Ð.?~sÐ&‡À˜žH„¾F©‡øs2ò37_Möv+š’ÿDc«Æ ‹f½´m›OMF©­‚ ÓS].î[Û‘v”ÕÊWt]ãá÷/RÚ>»ÎÖ$6Nä³%þdVáÅû©¥j"“Mgç}m¯‡.s "Ýá3+uÛ´M˜ êô0ÀWÊd7T˜ÝYUq;îøË—#ƒT¢O Úh`cøºÓbfÆõ»|ç•¢=9\Ûì3£Ô䊔昶0"øÆýÕ½¼Ù‚>çÀ/aëÅ]ÁÂaðµç ·vPîmˆZDJEY›M·y% }´PѬb12ôf¯¤†Ð\Ðr:ü*Ê|§[Ý({²Í-·°Ñ#{Ûñ ´Lž¡!zà Ó_ÞÎþ%Fì8· ¼çʪ{¿-“¶3n£û…=C+mM`Ò‰4¸³¤Rüï³µ©Imb2ð<% €¦»ïì ‘ÿyQ+S㟕òí×)èСF_¿D@ÊXçÅqm€¦ˆ—Òòƒ1—e1?~S˹²}v§gU 65c“ãæ6ÚÝæuÕÊ^A/ÃØ‚ ú±‰“Ån cK€O r¿ ´‰Í!¯)#¸Gïái#càÛ5ª_ A~ç—…ÿVµ/P(Vëšäë4Ô(½ÿý0ju€ºgÁ,ÐqU °)zœËÁŒvq$o溶ìíÇd…%Ž‘âÔî8Þ«¼Ô<¸Ï­—÷p Þ_—[V)‹uïŽl 'B&+‡ä$åkóøáŽô£ U@ÊsS7ØHÿ Z‰Èâ!ÜÆ¦JÔT”]Å’²gÕñWJ‡:/ÔE$â;k8K«tk #¤û¸—ir6M*Ãü (]n-‚»bFœd2Ÿ-¼­È«Õ¢LûÐøÔçË1ÞŒ† šB]¢XÞµFÿ±/43Éy¨é瓪ôª‡dû[¥dÚÁ3ïÝg 7•iLaߥ†¢ cl¥…}K0w#|2³Œœ~Õb·dG¯µ•ÐtÞJX‘¸%Ï;ùI(À¾H²ƒ5æ~ :&§ßÁ,¶=—&š+ÿ/jÞÕ½–‹ ¾ò5ŒG”ëä•ð„Ÿ@R^iäã1\zór0O 3HÃzA> ’'å­XÌ…*‹[ÉÛüw  µÏkòÏt¤è"¶î1¬œ$ìõöîúë:.™„ð)k’Nô˺·¥cз³sž•œ*ø–I¡kJÏ÷· n§kÃÒű£I¯·h~— Ælµ®¾7Ò+zù¬:7 \Ï,AwF·µþIîý÷Â6E5ÿ0á·É>•#lÑÝ~¸œ‰LÆÉ3M6Ì‚mJ†·O©¾eʽ¹­o ô<)iØ/Š|Ù"¹Æ%’ô6µnpwü$‘-·Ël­k‘U>.Çñþï…<­¸Q!ÎñTlŒOkRá³*ã¶1É¡TQnAÊ™ETý‘}¹z)“:˜é±^2àäÝþEåPI°Ò$žNƒˆzg²VSy¶Æõ‰›\9t²¥ªË¶$2ý;÷e´´SæÞr—¨OÈ[ùDÇÉož °ÆåÕõ¾ˆ²©5쬚rh9§²ê_ï»ã KCÑð?lˆÿ¦ŸC‘¾1H©sÄÊrªrœ»Ü©Éº-À@d=|¯.–¹wp×|bïó£—'òðK_Q꿃Cà¥xꫜI¾(Ba较{Š[†÷Ÿ‘ÚÄ*‡ü¿ÞAK\z/v‘àE%3Ñò¢Í›Š¾|¥_2}µ»Üî kAë1eÞ" ‹Ëµ”3€~¾ªL.ûy¨‡ª³ý®9r¥q9õ?+oØ4¼ 5x¥ãYóý0(ì«Ö›HÈÞ¨–ÅØAV¥s‰.ê=Ô©v5‚àXþÄJå#t9U8d Nk/fw 6Û"ŠÍº»Ú½ˆgU§Ùç·x5üûìL‘²«¦1©øj?›å›Qtba;¸¤zwÚ\IòÉØPC5;ýðäºÏßzjX¦¹öÜôè¨ø¡ï›±Hze«S¯ë À0ÛCáa™ÞñQb¡y‹ˆ>G¿x ÷bŒQ ”•ÅAw{R¯&ª¾öÖÑ-qMŠ-L¨ÑY ×Œu:òî ;16Èß³%ãe;ÑV×~$ö½\Vm”ŒÖ-e¸5{õ_ (V_>‰îø¡Ê†$L‰ÚÞ»Yn)nP!c% ?EE†]Иw³‰@#!A®™ï¬y!e§»·Ê j@¿[ÒJQ³qùØ‹ÏG1kÖ<#=A3ÂRÍÞŠ—BÂû嬉¼ÆÑ 7D=""ÝêŽWV$&m2Öþןéð‹ô:XjZ•ò²IäDÝߺW§9ó‡NEWþ±b®Ã!ߢŸíî5 Ùn5 g1ÎÔSãõoEÙ± Ò¿z·Ž¯Å×é8ö«Q}H_¦6(+éé¯Lǘ<ùÎc6øgyì.ë‡3h8ÙU%Qx;™R MãZ·W±BÍü å ^ï#\ŸžeE¤zÑp'× —Ré¸aj8!g¾`w|¡UÊRž`˜ŽñÞ€.?¾·,NMGÜ$k騲œ¨›Dèaä´r/¥çÚ½ª£ ¬“ë–þ*N[.¹$)£WšƒÌ¬%DórªMˆ•±É£fX Òýë{ñüÙP²)i”IEƒ°E%r yò;ø\ŒYyŸþ%›Õˤ¶b‘Fé`“âV^`èlÓi$ÖúìöWìó'ä˜ cuOñš!5¤€ï›öëTEB$ à8 ØÌîþØyA‹ ¥}åš^ ú×É´˜wÅË嬬Tè@;4¶à샔º¡¶þ2´s-#‰hœ´Î»¾‘ŽŠ¢îÝ=ÞoB³–Ù»õ+‹Oë•Ëýx11ð‹ÉB¥_Ýç7áB$­@Óêñ * ·¶~¾ýí{’„Ç*ªènÆÃT¬"—Û\-A ´ J#~j#rÔ¬±McU#è Åp¡ >7ò),û¢ÈEEgt‹sˆ7T%*Šû%IG¬Ç9²RjmÑ·‹q[÷HïAÃ¥6ƒÀ”¨ì7^S Àù²ƒÔ¿*ih&qðŸß¼¹4ÙY[ÓLeIÛDW:ƒ]h•vKßr7ÓÝa#÷E•ááÇ<°Å¿±áeB”¾=vf† ŽG„Ê [MÉÓg€ù[ÞŒ<&,/%ÇfÔ×lV6&ð¦%fˆ¯O*ÁÀ4G§ÀSZÏqRMÒYBW—m,T}ä?ñt+B1HÞ*V06Ê¡þ?ymþ‡OËpWþ¿‡èýf±ù„v8‰q~^–Hö’¯Æú2à[EY³+“ýøën£í©RW¡·lÑpN¢þ—*Þ¢˜çÂ61#¯˜ƒþ•þ»äN«è0xv§3ÿôƒÅ3S Ô¼_J­2êp2øLòaQzÐí>9õhÑ4<ÝåÈî0çB‡$ZeRVto_£áŒNƼ¿6kq"WÄêÅp[äðÛ“$wÖ#Ãý‹³óú’Ç!r•Ð\Òn{0r%ú`žùµ±G‰à| Ø!eê²9,Óôf·Ÿç㟳úÇÎ:×ót±ZˆÅS5ÁeHtÍñ-¿1\…þŠôN‡ÞN)m”#ÛñÞj\z3QË8¯X‹'š¢®ŸAįzjé z¨ù%v_æš2¹ ášcâ!X?ÃÙÊ1oÿ¦´ŸñTЄΞça3TuC%†ãüžÛÔÆ¼×ùî>Ò2T_’¸xê@U4BÜ(…-˜ŽS»m¤ó_ƒ ØÏq‚®ýNi^ã3 ÏIÁWÇ£-Lëà­0 Ú¸ü™8ðUJùTøÔE~fî}@qù(5Ãén§À„PVº× rò_:ðDô‚TþY•1ìR@&âÉvQ 5\“Á\Y5(%Âk/Xâù\yÑîþÐ'Db«ƒz¡?{ ûö/IÚ ME­_!Â>n¥¦4¡n©OTmÔøΗǫZ"Qœ†¹{#_eUꕘù¯ÅÚ "Wž÷F0˜^¦ûÒ–j€›¥Õ~Ç=桤÷$Á1ߣ‰–g>DKå]ÿ®ÍÀ%AÕúóf©wfLËÂCï6“ʆèr`Æëúœ'W:ÇÇ;Ëå;cIIbbʤg6¼í[ ¡|± ¾´¯Î~C;iJŸ´k.íôö«Ö‚úĸA³èï z)ÒÌôŠCkÔ¼Wí½ØgyÖ÷hiÿ ¢ÌËÁ`›Ýð -|op–Р W‹õMrB¢¯L-ÍtÕ?“ýev~ÆÞ³.i7ç ¢ÑŠ‹ß=µ rLf;p(8ÂÏc€MLYàÞJ§D“‰Y”mœoƒñ…Y84­& l÷Ö¤L„­‘#Pý’Úˆ˜>ð£K!"|vhä‰mÀ°‚솔é#ö‘ÏÌÄÁŠjø³Rrqo÷¥Ö^Puäó–êH²Hn¨_ÞÁ3eIº­‘¤Ð->\4«¤8º3ad}툵û˜]Òb÷ÍŠ?Ù…ú™È)á {ø&“ؼX ¿ÛÂÃéš¹^ ûUª»†àÆ7CœÒ´Œè_€ ã:Õ†)t.sŽê§Å³ œ_¢ÞZÒ%Od>ê­º ¼h0†6œ&s¬åÈåÝgc=qd¿ýP/÷‘ÿ@s<´©¤—œ:M<×ÚCŽ;pì±&@]þ’rIùÔ! ;æ*HT—„šC,ahœmÎ.–!ûòRZ¸±íÈÜ$HAñ3gÜU9í“ (È9T›ÔµÎÂq|ð0l•ˆ§W®Åx­|kú”2M¡äÄ…úlGe“ÈyζÏQŒ4D= šf .xþ` Õ WKí*Òƒª¿ãþ×°¦zÄŒSn¯-¦§.U6ÿ|ã4&~)»€àØ9²y©)k¼ Üþ¦p——Ø\)‡[v ·ž”ç<˜X-'5Ç7šP‡^¡¸ÃMHõ^SR“Ôû;xýò¤¤ò¡¡ûïƒS¬Ç÷¨kLà’?PëÕÞo¨þy°¢AÃI6çN÷ò£WŽÿªÖåš;¾Æþc² ¥ùCËü wz9q{é¨Ñ¦lúŠ2”‘ƒÓžî‘*>+ާ»ªW´vïÑcG¥»Ê1³>„?E =DÖ¨][þùI¾e^TEÒEØ/í ÔuÔGKtx°xÑùÿ8“ÑUY9NЏ33s¥¬Dn¨RòÃU™½º)dü‹Qàa’—[ý»ç¹¢!š¶iM6€ ÖõGN00FSõ0¡ßÞ¨Fu¼y“$§"¢SYó„ÁÕ ¥Íñ-Ç(¹0«¤à >0«¸É³¢?›É„À=ÓæÎ@LN`CC Ãx?€AúÉIöÐYDMœ9º‡ûc?Áø…ç×â·©Bm³HÑWôû;¹‚BªF^ÑK•|€ú?b˜ò‚:ö ØýÅ4„pû„Ô¥JúëùØŒ2Ø,Ƈ”æÂ)}pÔûo^4Àg¨d•fþ³ra‘…COë‘í_8É¢2rçcÜg]`^ÇòÊèq"ÁZKòDEºù9ôQc8Æ-C…µ½Bˆr`"¾K´Œz=˜q“u½ƒyÙ÷$Zšroƒ¿I­žÁ¬u4§-eÄZ.«´ËKèîV†f!ƒ)„‘œ ‚ánÍ?Õƒ\Eé,’ ½£!úWÙÐóŒŒÇmyN[<9a/½+²»c/¹nË¢EL4fxù¢ß jòŠoe¹ ûÞ:©÷ ¸ÎÓÙ¿牮·™­ ¡ù,L=YúIuFÔôŠ(ǵîã Ãòv§ÇqófÓÿ˜Sr endstream endobj 237 0 obj << /Length1 2519 /Length2 21494 /Length3 0 /Length 22933 /Filter /FlateDecode >> stream xÚÌúeTœkÒ ãî$@'¸»»»§qw'—àÁÝ‚Kpw÷àÜÝÉžwöžùf­ïü<‹õÐ}UÝUu•ÜõðòŠ*tB&¶F@q[=#7@¨)áîT:Ø餜 ­-ŒÌôŒŒ¬ää"@C' [¨¡ÀádP0vz3w032r!$€  Ã›Ò`ä:ªºÛ™T†€¢­£‘¡ã›2³©ßLDlíÜ,ÌÌ~û`§ûí`jëð›à7ÐÍ r|‹êøÛ©0=@ÚÐØÊÖÕÑÊ`2HÓËÑäm]ß„*[Àhnhm °5ýãBMELY ¡¬ ¦¨BMP·: ßRŒÍ  €ŽWà[C“¿xK‚ªæÀ·ÇdNÿFQÅÙÎÎÖá_Y‰¨¨ªIÐD…äUÅ@uZ€„šŠ*-@^õMøGó›ÔÛ€ÈÄÂ𷹜˜ªª–¢Ãïj˜.o1-~3ý¯t(Þ’üÍ›©©ƒ­ÍŸ*s'';nWWWz3gG'z[3z;kêßTÍ-Þr°u°¼}:­Jì 2ykŒÓ["ün1@ÖÂø­–À?I”rBòRâb*ªtoÕ¢û]pº¿zOïäæô'e1!Q9±ÿ¥þMÐÂèø§_¿}™¼5ÙÂÚ‘þ-Ø_›·Ž¿1z êôï¬ßãô›°õ_\Ž@à›£ÿƒékG†udø ¸‚¼*¬”ˆ˜¼ŠØ–¶;pr6ûmûÿÊð?Jgnèø‡²¬¢¢,ÀÆÐô6u† ã7~N†NÎŽ’?²·hBòWÑg‡ß©ÉýŸÊáßÙý_;„mßÒùdíémèú߃krvôøG¿ÿ³•Æooáèäø—Gà¿*mý&zë­èÿï~üv)$*ûvWÙÌoãÛ-™ˆØÚؼwDø=¢or²upgøŸ—ß dë òüß:S ÉïJLœíÔ@öÎ@)ÑY¼‰þ–™Œ ýÛu66gøöÏeø-fú-~«ˆ·§­ÀÔÐÚèma |û@ðt4tySg ·ç?ÿ‰˜8&ÆNoWÿm« üñ.2µpý%~còª !ÕŸFý¶ÎLlAÖîoƒkŠÀ oëô6.Tÿ__HÿÅZÜÙÚZþÍÕÿjП5´±°vÿÿ=ý_Ç4€¿Ó§’·u°1´þ/…£¸…ÐDÑÂÉØü¯^ý%ÿ+žÈÌ cbûK¨ö{Y¿Ý‹·ÍoñûÅñ¦bdü/ÝÛÈ[€ŽŽvö?*à[ÿ‹÷[C³0H© +iÓüÏaüsT dlkb2{›vv€¡ƒƒ¡;ãÛ„1³±<™Þî ÐíÏèA¶No&;g'ïß Fø=&ìl¡ß¢¿€AäoÄ `ýqÄþ8 â#–7¦#vƒìßèͧÜßèͧüßèͧ¿'3€AùoÄ `Pý½ñTû7âzóiø7zóbüoô»à &ÿ€Làßùí°©Å?ÔoaÌÿ Yߘ»Û™Aÿ8ñ&û§Á[Öÿ€oþlþ†LoÁÿaËôÜöð-C»À·Øÿ€oÿßÊèôø–³óß9¿ýóÂs4¶uøGzLoì\þߨ¹þ#ù7:îàΛâï}þg?1þ=€ÿzyÿÁ*N¶V@ “·?þqDÎÐÉÁÂM‡ñm¹0½Éß~þï›î ÿ{/þÃZXØÖÍ“Žõ­ÑtÌoóÄÄòû#£÷ØÿõÎù³ØÞnÊÿáßÛºçly-“ꃊ}Är'J É¹èÊpø5¥c S'Z pE¿m’òüýÒ(òle%¹u}üAšäØÖ/«MñåãW&J‚[†>r>(bBÃYêôjir ~%m$ÔûÒY9Z…¬SiÍ1ÍDµá®ÖöûHæ±Wô‹D’O%Í+ÙЮù3L XÖn hø?&~€;½ÞcEGv -~œ6È Â–†±ëlÇÜÍlþÅ¿i=í¿/†›]ÚbÚQhtp†N~rÕ˜:%*â¼^Èç*ŒÅ<[=+Âé’ÎFÄsOš?²¼¿¿uÑßnYΉþdqŠnŽkèüÄ ý™1·ðÍ€ÂQôèßÝ¢–kú‡›lžÔ°ä‚¥®³¬|“×þ´\x|÷ÜŒÂ6  Aò¼¶|” ’)m`è3Ä %éÜšà=ZflÊŧ³gd7 àëÆÇp—8²­ˆÓ>—9‹°qt.vЄïã–±p¸ÇÁçNòyæ`åzL«TÁsÇAR¾Ê{è Ÿ¡ÕP!Ì\M¯ü#ðbB“F%‘g‡ÔÜzQ‚ÞÂâÍ%hg‹öÖ¼X{¶wç¯-‹0Má³Þ´ÜÜØÓ¬>wšíq¢*éÌå¼¼kè:µœbIZ0Á^J{H>Ë$†•zMæ[ s˜Í|}x n:d¹RY½ÌÅð¹ð“T¸Gœãá <ÝœUðt‡8h8©©• 1·ÅÞ<|uhÆ:R- =AÏØ`ÿnõ»û’€o»ÞáÔX®çZv,ϤYïͬ±Xt2Wáõó~dÏŽÒàÍ“‹ÔA;yÄ-âü 5¨¾iïŽZEæ³äW¶a½ä›Ù°k£÷S.ÃiÙ¥?è®O´ÈEtÊÇl\eßQ~!ò­zE(†+$fù3Dñ Ÿ ®™œÐWCGÚóÜ$û1PŪ|u,ösg[ÕÎÉK¬ &@„áɉì^h¹eœ/Ðf¼;Ê 8ÝY`¦È“Îr5z>¬í€4Ò™|mâÙ`ÖNQÅýÈØ™âòÌ&ûž¢cŒØ€³?Ô‹m¡Œ”ö©mÕã1²: êžrjÍ^Öyv£´\ùBÐ?1ãXÖqÁQ'™Cú±„cP؃¡é+Ó—ß±ƒG2¨[ÕîG,½.ǺdZ` ‹™&"tAè¨ïýø¸S¾²÷NmÝjìÆÙVUö}šUyíT³ä8㎧6ü®)»!ERR¼%f9‡R",»ë?Èí*n #Iùk$oévŽô É1G¥—ÂTu²„ø'^ޏÓmÑlY„4¦€ÏvRýÁØ;%›¡Ÿ_•õÅ }ƒcu_˜¾a@³ÏÞÀÇ;È ìÕS{ø½lTò j²/{æÒZ~b£jP¢\v&Yyr–Ñ•³ÿ²öJyYÜÁ¤‘J9\%‰Ötf­ÎË–“ï|ga)½ðÝÐòA¢¹÷V‚º5;Nò ×^¤ºŒëüÊš·ôj—þjª€Ç/›¨¡…ù ½ ¿ˆ‰¸JÑ=8lÝ“)¿¡‹ƒ©H’/úh–L¼JÇx 5™¹âæ={ð·­/.¡"r“‹ç!gèË̳ud(å‹ß ºÆk-ƒÚ®K6í\rnø¬7<{j!lÞ]ÇãâEv)¬V5Î÷Õ ܤSy“ñá’‚%Ã.Ñè/5à|ÜþùåÜ&/f“ò€TfE(tCJ ·PÏœfÌ%ýŒÍêÝ_‰)q=`˼MNaÔ‡‡¸lbÚÝÌ"C«‚ ¤1x]“ s'ÐQÝÙ_ Ÿ­)2ßÞòtOÕh‹‹MþzXsÖi.‘f>+V·úC•é,úøCpWAZHŸV«¤ ñ¼}ÎÕ5âdïF*Z¤ Eˆeœ·¾¢#j°8¡¿éŒc»"_ÃIXaÛºÚróC«ëW7lŸØë¬ mæ¸6%SB4½ÄW†}óÊ}Ÿx—ö–WôIpÄþ›nacãÜõóÄÒ+í—²Ù°ÂâgJmšè'2ÄŠ.„™•“´:jò™®i8 »ªªù}MI=Ê'Lwš»)BöÏò™*NŒ–ÝIÀŽt§üSÈô¨Ü‘‚}h0-ÊK™Ëd¼6t´ÓOûiˆ,Sh3DÌf>+æzvÞ‡Âùáù)Í¿¼ž<À>DíÅŒ ™ Ô¯l·,quCÑ^fó(ø$2ñ‰[ ÜÑ7IáÎR¯ÃÁÜmfóÝ–ü‰#RŸñh&vþæ ÁrERγ½Î4 Þ¾›8Õ¥ 7¶s¦™QŒ nQ,;¾JÉ®€®ú>=;Ä·—føQÉ¢ÁOà#ÝÁŸ.°{îbë|iü%ƒ7„9¡ÄäžüêÊû£2Ç®úV³nÇdÿŸFÝ â€Ç|2—gB·:Ñü5s0¨T²<›èùrΟð§|˜Rõ4hØF>ÿvJºVcÉ ½ áÝœ‹gÙ7æŸkO/·JW O‹· ~žÚ3h¼©¯Öå=*–÷Ñpz9Ìc+—'1Âä×ß“æ¦BdÒÅi„±P1jûü4L;­ÓAÚp{q)-PQöFZ§ EœçU-É Îe—Lðw«RªÕ~Æöû¨B»u#1íõ¶!Dø§m‹ÇéŽn5^¼¯ôq÷6G½.ðѹ5üö0\úPJ}È;É%ܨm`†8RÎ<}P˜®Õ7×ñšU š|@¨VŸßÇNoeÙoh\Í”©µ×1Ú-ñ¿5CĈÈ»,¢·á&GÓs£Ó·t6!³Žë i—˜l®j[ÕÜeüé)@¹m€ì‹Vd–^±ÌÇbJÿ°ª¸jO­ÂMú,Q.ÓžÂM_d€ŸÄG™æùj8°Ðo™·’^:¤Žü¼Ÿ‡ðh_Ðó= û<ì¥qHÚ!ƒºÆá©ùÐ’¸>S{„ñ Vbœ’~)¼J#b)äÊ ÷ôVOŒÊ˜þ¸R–ü¨l0uÅ‘¨=u¶cÐX™*ðbiÀƒEBRijŸ&SH—ûñÊ‚fM1íðÑË‚ê^r‹ tìÛŒ QÖôþ¯ñVFd—»˜•÷­˜ý®¯‰Ü+¹‰‡s|2 | ¾ô‹)*)‡¦©µ©"Cd’ÊöjûZ*”[’Œ(=/jZ`³­w/ˆ-Œ”/¥ïQ¨7Åû‚ã„ïì®·?}…’g/Ñ=†¼¡Í5Dõý²ëÛéåƒy9)ÌÛ(y[m•h1Ø.»ˆŽ" .aµõ9câ3ƒ£y ±Uéåvrjw$Q®"Éð"zîGW¡Èë-¢‡ãÇp­9é„wM5!¹€•ï°¼‡ª½¨ü Úâtù[qÊDÃ>Κø[E"u¢ç ygì¤þÞ)½ý)!Q/#q–ƒ4––ƒÖŠ„ØW$hü‰Àï±b(Ï`\1&Âm.cT|óÜ•®ÙÅ wOQî‚ðaå‡õEr÷dÅ,p@üÄø<ÿ¡˜ë|;Ô¯v»H¹Pº]\3¯—Äz+Ù00ìUÔçôæð£Ÿá²•(y;’?æÓŃÆ:ÆöÑ–L;›„ X0—í •i”T,粂ólPÇ®à%B2ç>¥‚® F8‡4M,ò˜I4hä®`¥MÈCÉÿZl‘hé–•séí]ýÛ§a•˜$æc{¿~~haÒõxîb¿–‡r–êPðî›1B¼EæG‚EËFÚ»ÆÂù÷hÖþP­‘õ%(ܦr‘GUGæ…Ñè[ ŒuúqŸŒ•~Ú”ÆÉ}—äüçZóOÔó¥½)Û¸"-#ÊF9{ˆvCpe^L…:¦åzo}9DéÓ›Ÿi²6Ǥdíi•Ô¬ÍöP"ó7^¹þß!1훉sñžÏ0‰ ã*˜G¢²’M(‰Ã¤ó¯'ºefjwÔñ¯qw¤bTUÅ'K“v²K"¹Ó’ÆV#CJ¦°,fôHI¾‹VŠEèHuc„Qþö:ï4J ª¤³‹ÔˆX%Œiþ@÷SÆ£¥T§1GëJ5·uγ®ÅÕUpVIsç®y¯Y .F÷Ë £B;›³?›“­>¤!CÝö]¿joø¹«®!ºæ„i™¯Ÿ/RléÈw>-ß}>@{Ÿ4Ù’¤ôÒì³2xAÆÍ³¶_Å„…ѽƒ@3S‚›.^ƒK+xzñ²Æ|bÅÒÊV)œ®²Yв»× ßEZ­?<Ðn¯bKqˆ¹Û’B²´Þ ˆ‰íî}^P¼ºÝ¹Ì­™º‘‹HuCÚûDð $0®u´4J®Âh’/?ÚÈc2¸FÎË=mÓκMဠP8»ØAÀC¯)ÙRÂ~Yj1µ3ÔpE¿n¿‹tcÍBÕuÊl;rD`mŸ+ÛŒÛp¦±©Dõ‹EÄ·.…_¨ÉK—ÓÄ’}’~.B~ï‘-JÂC)fÜA“QŠ•‡Ó͆˜ñDxô>ßYŒ,ðžÆ¶µWHI«7gåãl²IÓ±£oôÞ …é£eþý=Ö÷²Wͤ㬜˜:ÝnRÌm‘‰íxåÈ5‚žMþ• n¼ÚW Æt7C€ÛZÊÊ¡½°ÜêH´çô)’;›ˆ*uú— ÷ÖÀÏkÁßâ`Tu+„›³YÏ&g‘“{ª}èVx8¿×µiáK›ƒk·ýš ŽQà:²Jœ`Ìtoçìÿ(€õãjÛ %¡[Ç@ãA;kpg·Õ–ƒÉÖBèq“·àA`8Ózqηtgÿ „ý/VžËˆÕš†™kâҳ羣DÁîV¶fÊvΉTÕºHCHŸÚ¼$ç-ø•~Eãïð€å íjd~Á…g¾iáÚ,!l¹”€{nDXlÿya¡^VoÆO¥ÕùþB¾’:âa;ÑGaæýOƒ¹mLèTÍ5Ð%‡ÑWb¾.Ó4r¾¥ÃÞ1 ÒòÒØÁtK:áué9%Xi߯“ò@ó[24m•ñ=}{—l¡õM‡nŠ»{ ·Îó˜¹Wz~·I¸íþwŸ8Z¯kGó·’ʳ,ã‰>© ‚åùÔ-n¹¶tUúŽè·%df M‡tOPðø0’reRÀ÷GÎÖ/¤Ì‹$b„#a#Ö‹­PfÎòÕoÒdè‡u?è¸sfRi±¿2Í /„ BI:D¢l Ó ™ ÌäšãNÚ ¥fè3®%¤*|žlïX¢$§u0¦Œ£ uœ@IY£&cn“ûøœ§8¨25^t‰O•lÍx‡šû\£ 7”¡õKü‰Õ¤ƒ9ýœV?Lk©ÑzOÂE³nØ9šÂ5e¹»î¥ÖÁ:ã&V‡ekˆ”^¯¶÷Ʊ˜ØDéfárp^ßt€?DÇ­Ùu S:ÄÚD/“ O¿±Ëãnë3¥³I®†t:Dqhúz§KšyNVF›GÏ‘V>ι>I|jŸ&¤#ØùæíyûÏg5lYo)¦æ—Ôöî’uû*GøÂoÚÜù°Á6 – à¹J4_>XSxý‡”ì’<äp¶2¥¬Â ¨èFwztiDíÞŠR&iYw= ¸´óÚ)T•¬Ô+j˜Ð³Còï¯x‡îïã}¦*·D·&_m"žaj¸`wjïÐÕk4n(ྦù(lˆâý`‘Ñ º1Œðlq¿GÙAë•™¾EœŽtt*~Ù€0ÇnšPXÂl"DT¹"@e:¹Ùf¿ÈPÂ@ jkz?}-ÿ±ë²9á/W„èà&æ9Í–#ã.jõ ~gæFjL®ç@ùkà™Câ¦J[ÏCBÙØm&d•1\„ÇAÊØ‚#F̬.ïÄA÷Úë9ƒ¥õyrGý’'­}“Eô+ß§°Kª¯(?µF¨­æR·¶hçCK×íT7Èm- òU?Â}»@:›ÁúNKÈJ;¸AÙ²Îs^«¢~‡¾zHà‰¿¯gz<'slòú³ïs*NnÉØÔÇG¯Æ0¾ëúÎÂ6AÓ}¡¸ÉÒ“†ð(Zƒ VXÄ;ÚmCønæÖ„ïŠ?g¼¾é Øœ°©ºx«sFoÂ…ãSÝPÀ‹²éÐx©SP—Ü%vïNÉÅÚ®Eñú¸Ê;‰ 2V#¼Xc†­»Gé 2ÏF×Ò–É·²ÊsJˆÚÕ5(Dµöœi£`PYžqëTßo%³jâÐVDänQŸµ|i‚╳7x z$Ã-ïl[.wŸW“f†Ë}£¥Iá¶ŽÌœÆ¶Ž„]±Ùn³åT:Ó•mäþ¢ô^ªnž+îÀùá¯m0„žÙæÃQæ?ï#Ë"Sp(ï•-¡ž^jøÉpãõ[ÙjÊê­œH­*Üì#:îR!-{F —›ÿî7BÁdÊgLîA‘ŸÒŒìI&‹]Ÿœ<1¿ø†òüBél?´Âñ¸<`•jßà)±“NÊ ?v½{ x|Z?lÒY÷ð!ç¸c¢éÖƒR÷T÷5•¹+AÖ<­J£0øÇ³ÈBî· øÃ—5¦¤|wKÒ&J¥_ jLz†÷†—©™mÁžª‰}Êõ›ùäÁx$Êbóµ hFXÔX´S%¾Oöq®„|’u( ½ïžÔ›£$I-.êpD³[*J<ÙÕˆg_o9S÷¥MoöÌ/µr|ÜàdW„Ñ5ç½qTGwßšû¡5CEVÕÔX×à H1ÆÍÍoQ³»¶Æ¶Ht”¦1?•Þ5K”y6k|zñ•”µ·W2äF¬6"ÏFâµS^§WZ;–Ù £ógÄøIÙöüœ¢Š Šn¡΀¬áÈÆwïì:„Ò¡Cç±vZÁÛrˆñI'èB1íñ&ì‘æ-tÒKïÄÅÚ%¶% K0Ì£ÎVØZ*Ù<˜GÇ`ÓÑ$Îwô WtdÑr}•¶v‚Ž'Fæ"†§Ï fU™‹xÏ>- AT°sò.Ù¶ÐéÐ?ñ ÁH<›«DD‘ü =‘½¾T8sšîrG êÇ :wÀXZU92KW—D&Ï¡šWž­ê˜PÅ£Öw¦­GOÅ ,×ìüzƒÚÄ>Ù+\ˆ±ËQµ+:ï7øx+a³ÐY¾Ã%ÁuM&ü™¿kŽ„ á ±0¼+#Ôzm[8§4Ej"@,|´ÅU_AƤ ­uH¦nŠ#’Ï>á=‘[¡:Æf$ WEëï‹ìQù\ ðÁ$2 ¦âÔ ÉÔMׯYËòÛ(EJ5Æ€¯1tÜ ¯J©KD;¦Y¸Ê1‚E"íyD7˜tÈû£ØHŽt¯Þ×#Éí²NM•‘PÁ=}ä÷–vòñV*.áú±å±5¡õ¢Ú)«IáÈþÛÍÅôáøDÄv£†Å ׬bäW"û¯Ú¦(°õÍB–!ž“5™§Žêú|Èôcã·¾@ù<yš´Å ¿“Âï‘âWVÝÏò‘Ìœ_›×C?ˆäâ€Âç`¹†™$%!„hy¾ûm¾>J4?ÞSèô[LˆíKmê£]\EØÀÞë[½ÂW»tèݶ0ßN¥Õ%hbØT–³¯ð”~“¾ÐG8G—îHö»ƒ£\nSŽ~&uÈ´Í]–˜µÓÅç§;½´Š¾Ñ(ùï ‰ÆQOTœ›Æ°€Knd[ø©¸ï]_õ>üT½PÇwSÈãºxâá*¾Õ”ªT°/»š¡Ú¸(ï âÔ «èߢ|²,/“¶éaá¯'Qœï釸6£+‚¥ÑùuµÙÙó@ìÉ^Q¹‘ë6§xË->iœÝ §Ó'hªÉ³åEŸY«ì|×J„$R3¦»›¾iÁ?xž †â’h¨¾Z°y[²mÜÇÚ³úùåõK\± Y¿Ë^ÉPw\ðµç’ˆ±µž8ÄšEµ¹¨Iîà‘Ê}'qºð4žÅåg6)8Ë…ævŒKwÅe †OìNª[¸eh½æ£u0çšÆ8fúEÈãA°AÌ‹½=Nü[/˜O¤CÙÅ4ýbòÕÔ¢Eµ“àPêy¾¸óð|éÅ÷«”ðñ¡¼¶íT“@e¨v]/»‰n%$÷kÅkôÙŒlàw–C÷‹ì3EHF¤ºR-]/M Þu"쯹ઊÕþÄU`#Æ d®/“),ù‡®­·Š]î_8ŽñËýÞY/ ñô¤—ñÅ}ÏîÙn\èë„!Ńš´i5S€ÜPk]«´!`”Ê$L[š¦G[òµµYí8〄mµÎß“P0š=H)Q3¢²ks2Q\ˆéñ/>}ƒôÒ.¬QÍ»P4ÚäK‰1’N¢6Ók§Jà/md*T­ñâu‰Âz_éò1«-˜Š<(iM׉1íú8#ˆ¹ç¦u(N†˜}XHó×tõf݆§z8‚,&êɺClÍÀn s¢WÅîüÙ¹!oT-§¦¹·~ª ÿÕB&É´üÞ¯§º©gß–g±ôQ+ª0X‰išD·~–ÕÔ÷зºp>­öŽjüǬk‘…]©'|ÏÉt¸ôA5ÃÆƒæ"p NÉ#L*j,úÙçûBóó’,÷I&84ÞU?ü,ãÛ@T޼[é—_JW¥«UÁŽ‚QAû…d¹LH¼¿XQûÛ*%µh^Ñ»½Ö£Ž’&æ¡6qrvú„×÷¼PÔ vP‰—òª.Ú—±Ðw7©¼N‰sŸHaWÌ*ÍH?’Ú Ú+e g}Œ&ÆÆZ6ŠàM™8,C{·ø.XgæÜß7iò1¢úÂÞĉ$xðL§4ñA¾€g¬D-­ æ…skšáêKJ¾þKÈ ñÖõºLß‘gÚ¥ØS†ZòýdÏ!ß¹ÕIÄ©>z{k{'ÛK¤×Œc.e}iH±üMç4œŒo!*;•ѺAÇǪè~8QPþð.RFRk å°è8”õ9F ÓI•Øsì¢ÐR,aÓÍ*¤^˜JÛ[•)rÍŠàE1/ÜN¬;T2–qúÝÚÈýQ7ÈëºBKT4ˆ²$‚XúâÍ$Õ°/פð8p‰/dç]˜g5„¥+(Æ× ¿W*O ‡¶ l2OŒ¬Þ,04=°RÊ>H>)¤¦“Z¿Æÿucê¢5’bQîÓ]ž­(Ž€4=-žÅž ,„¾ØR¦¿¤2³t®…’Fn©+ÇòÕV}< ªX{MÀï²gLëá^U‰Gëê¥ÀCº±©Ó{ì¾ß—@Ž¢ÏQ×R¬.Û8ïÖ½;¦¹ÈåÝd¿œ¶SŸ%¶‚¡Ž ÝN-D„ð5²v£µâökuG{}={âùé©rÑÚò!Œm|_±{¡J K­i–: )爫pŒì'Ò;¬^³YZëí©¢Ö±"8¤¯¹³!œ…Œ0Ý@8%­"SyšóÏ)Gæ¨|Ø”1Åa£ ôÔ.±O¸^`™&?‘tblÄóI›¥W™?ííJÆ"_½f¨ ù´GîÝú‡éå fQ׿Ðe¦N21:µâ}«šÁ@”¢…Åo·©@þÐS$á‡Gk5ˆÝÉ•ŒTí œœø|X[~¶˜€€§oòÌ ß7ã)Þ`ýEÚ©¾ø Vžëë†Å·á„lƒ*7aàÝSIŠ 3ÿŒ*“¢s|ÚWœzøxÕáèl€ó61Þp°2Ä‘äÏfÊ«O=¥†Ë{ý‰]~ íÓÌü»š<()ˈ«äqÈŒrä²|#K¼“,¯RÉ‘6)Z…RŸH·n³Ù»Ufíq¤uhbÀ+ s@C u®ªZÇãÇ>‹€RDÔy B¡Zf¼)m$ôꈊÚèuJ-¬xv=ô{€æ‹Q5×ZǦkµÇM’ªkÂkŠŠnÒ…ŸÓmË÷Å2Ýó¾òÙ-báBn9}–« 6­Ë“º‘Ûà ëP&V”I°0¦ÆìÜì ÆpÓ…9r*qsмN^;⸸2P½æLˆM¸ÅN£s`j“cE~UT—4|/5.Ú€4üé•PzûáÇ¥Ôªú }ž S³~U1éD¡ày»?3/–\íR*žîho:ƒåÅ&À^–cƒ0:¥NzÖ±ƒtÏëÝ55hÁ»LíÉ?úàÖuLŒºézMÛî¤@#ÖÙ2Q0}þ$gp(‰Üßd½z³ŸýÕºäý¶JaAÔyîá·–û¦¶âÕžTO‰"äUo¡ÇjÚWLÚ[ƆŒ¦ýh´N%ó×A̓>Þ› u×î0þ&÷Ã._# ˜V&z<çV'b×­D;`Øë7W~[‚ éböä~w‡FÝ\°ÔRøØaŸMxÖjÁ'ô¸i Ö€D¸¿/§3iç€ϧs}C+7êókÉl±­ã²eeOÝ—éašê&[\r]S_^æz88×µ¼@‰Û´íIØ(¢ã³i#“V7b8xHQr%&Ó¾'xz#ç7ÿD2õ}GW';)ßOoÉK¢hëÕLòIÓÄ‘gC1òS¤AVÄÎlñ—¤‹ô6 ã˧Ϯ8r”OÎ ®t ¸á})AÎ,ìå¹"Éù¸±Xü_®}“w‹8Þý` ‚®o¤e6) uÆ_:”toRLŠÃ÷ô†Ö#Št¢/šO/] Èámëìa Žl °óíxîæ¥¥‚ÐÈöå¾£í¢~ö9_þú#ªÉõrbÛl9l^&ìlÚñ|LH [²ïǺøL°eòÀõÍg'"M(|òzÀÁü,IA…»»éZÙ-q †xeç@èEÙõfqÐQú±„%ûfû`ê1G€r õ´}V‚ZÜŽp¨Ëªcm•&ÍELÈûy¶˜Ëû^rmºìÅv!ŽÝj#7ógæéâo鸬ٛrS°«iV8…³{£âÈp`‚×sx©Ð¤dAçpÐÜp/Ï¿lóU¥kíB8+Ë¢’ç£À · £mÏÛ<ÔÃ7ýƽ7ù•Í1CQÓ3ñ–øIÇŵ„Ô9¢w†2Рø#3”;r? u[utkðª˜ÑGœHŠa©âÊÀh´ÅúúÏ@–*ºõ–ŠrU25z§{’¾<›îê3h¹ÍlìÄ©Jȱ?N¡±¿ß äT¡ø|èøc26Ì}:ô¢¹èû™"J‹eóf™- NWëgø¼ûw†Ÿ;"_ö?ã „Ÿ<Ê-„Þi0£kÜm7J5¤júoB ëœ×¿ty!È \V“éU±_3©+â4>a2ûÂa'ê;ôHxÍÇÓ‘‚NÄœ>P¹’µ4îêo`aCt~ˆPsåÍí›ôJ­L6Ö¬7|ÅL:Sž¢tÊ?1yºLy Mãc®A&͇ãh…ŸLùùuØ–87« uhÖNÍVâ"~ÝÏ¿½o ú™¼A°AÕa~ûë§>I†WËôGÕS#ë}ŧÁÏ)K2Ñì',Š›î~Û!ÝI”uS!Á¸\XeÈÔçå Ú4”|â§™}àõ­Aˆã½ êÞÕ/páJtâ˜_h=g×Ù:2íRͬK|³ä€Î§ä¯ÈBë\±€ åNû=­E|c½Â"^§ýú_b¢•A‚· :ŸtÅâ ÷î,ÝN;í“ôýHXÁ„¹¿Tµ µ{Ùì•Æ·HKÖ•R¶ îMŸ»ç}.qtPÌÅ1‡´ÃJÊP9SÄ‹^³„ŽŒüxDˆ×7Ðå4Z󑜢­"Ïo“Mõh„&5øg¿înëKç³]žˆúA}iÆGÅWlÙ:ЩÍ3rKL±-· æSׇ¬Æø2Üš½3T™©(gk+mš¢÷Ù78œN{Á¸°­öâšêõCZüvK^ƒ+È£ÎH½ý)æ&Valb‘ù—<ÅìÊvïJ× ÉÔGÙƒcò‹#¹ u&uÕØ-spô&à‚Ô­zÙXâ,¢º…è!×¶Yº¤9žs©ÔÓzPžÂØ¢[‘ó5^»¥>½‡âüJá~ˆ[ñ³®[‡šÏošThñ.K\W5J´#«Uwrt‡\5Ûs6åùRÓ¶†0¿€ØË¿À™N>ÔÍ€ó“1ÒF{šÞ&ržhðç$ÁŽIÀ…è7¬äºÔr˜õLÝö€ù9³¿¨¬‹ÌîÛµlà’Ô¯ÝÙ“6çó·KÒ“+¢Iãoòâ’ƒzNHޤ9mupF·¸Ð]n_&øp¿LgbâÃÕ"p× me_•1è”b‘ ÜË8–ßNhCFñ‹®ÂBqç5]u³0¨™¦ Š£]ÚEù{—äKÛ7³¥‘¯±2!´AQ-Å"¯*±¨ªÌ‡M^éÙqÔîÑ &3Ä„q˜“ËЧΦÛb̨#AÔ"dª¿†ôæÂsLƒñ =¨ž~ŠòAôƒ7û¹Ç¢&8K düÄ!¬e§>ÝfÍèð“àÆ?ÀÜÝâËÏ÷ÃF/½¢ûF°H¸ z D–ݰgÓè¤ý¥å騸 â—y˪MöïO+åDä)P&ªÎnuúu8öí¾þ@ËQr^h; U”%ÜÉÃ…î–%šºB±eèÈ?Ò:>ÖfŸòCwŸ+ö´¤§ÏpõŒ&au&LÑ£·?вô¶ç0$5V!®6Ã|msù—Ù7"ô-uÑÒL5Œ½?¸*ê>ãA–ž{Çi7D… ²Pe´ÎéÛ$«,é¦ \½¶oé5¦åIXbH±Ñè-¬†óÁQ²ÅdŠÇ‘nʹ¾3®aߊÃj4kyõ†ƒêŠÝ0Ý*nzçÀí5Ác[×éÖ4nîknWS˜x\êT«Xå¿Âü¹j6|¼Þ°¾û¬ïûK³UyÈ~7=•ºîìZ5OWãÑjj˜«VYL¤ ÛÌ¥ Ú÷*U§¤(ä4Ê ”t¬Ä‹þüØýö¥'Ç\yÿÊpäw˜ŠöˆCòæv¤,祥΋õ\·Xñ¡d0ãD¿d´'Ø‚´°‡·,¾Í£Ó¼ZW¨§Ý¤,`X÷uÜî¼ìˆ½¢`gÓ&DµÜÀxÉ ä}ŸIfë–ÛûT)ÅlÁ3–ª fe½û oõØ­Š*é}‹‚¹±›²ƒ@†y¥²‰ Ø—º*´+¨KF÷Õä9®^ìû÷®Ï:ÄâaQ ž/÷%¼†ëx¢­wŒÛÊP”~6ê‰g¿4…ÁD‚\¥Ÿ ª¶ê6˜M+ác<%»0EßËw=5ž#ñĉú°C¯ŽfHl›¦‘# ß GQ.Ë<(ÐpÔDF8£+›4»¤^"¸Ùãf¹š¨N—À.V‚ÒEn´ÌÇ{º„Š•M(ä~ùÁ„äOÖœzŸ±h|^Ãt-K-í¾ºbœSâu;„5m“¬ê{T䘽‡À<Þ‘T¥ŸñuDÆPzï:šç ´ ΀Ӯ´©¿ºjp¦BÏãotÉ>¥zž5\aMP6ÀµB> ûLéA¡êØ Õmsì!¡\dÄ’ÿ(p™¹Ãg÷¸E;ÔÞa´*EaJZ™ZÛÂîÓòcfþ@éÉÆ ÓL””¡ÌÙ}©My¥± ˜S¦‹cYP¡P]_\;5™)–ÇÐaI«”ƹ3hXSb§mÀÜìx¸8é¯mî­D´²qmbi~q;À:@û®ÈU]Z­r ¥Æ-ƒ_uMœy`†ÔëÝ•E±å—Ç ÑÓ×âHP¢(¨óêSp×H5>'ʸ£‰Ú²s÷ºôÁÖ…Óç¤|Ò—ÃŒ3+øö€Œæ£]ž°^øü&È‚—ªW8ýI5`0‹&&ÁuiŠêµc§5M/ªsÓÜôÙD•û5œ´Rº…@Þõ*,_:Ðù*™Cæ€!}j‹°· O¢@IËô%K†~á"K]ŽøTPñœ±ŸàÊ>^n9WËá+cÏHxm·£/£Õ$ÊŽˆܪqã}úäµ<ÉfµÐ¬oÏŽ‚ @xv§¿Þ­ é*ü¹O³çNùר>ûK(¢3ùÃ…¡sbÝ*ƒyû¤"ŠHHxÄz1né…U&úû¬{z½á–†`5Lcxìós18>îaŽD»Æ!°<©²^º¹%±CÒ/(Üh]ˆû_&G;IÀшÁäjèòµëmÜ€"Ô£ãªX£jYÀj‡È—Ål~®$딿­k¶²êæ üw5 †“+°",h86·Bu^I‚Ôy¼kc67už/ÚJ•ædéú?\žOæÁ-¿Â*¦bbÀR!D .j ôŸ{ Árëîr'ŒÎTosÌãnIm g` wUA˜Cqׇ¿0‘¦|QƒâøeÔ[=™[nËhL“ȧ%-‹†Örïnºª¤H="•3\Êj5bö¾ÔYæ7>C¹¬_Ò œ`l£¯®?Øb|W4æ¼ÄÐ"S}Ò‡ÅZžð~X:ê>?W‡r±+.2ŒÑ?ø›šŸüóô¼¦MÂÞÚê³,È¢ÍíÁ•´¾žï‘wïÄEyĶüJü¯‰„%?þüåEɲžTç Ç,?9æÝÌÒOf®È"q€/Æ*-²¾â††ü’¯=(Nƒöª¸oU<;±Í&5ßëU’ñ¿Çz¬§T†‹XâK|}„õ÷¶ã£Œ±§ìÃ}z¥½W9ëçCÀ­ÄQŠá'\Ù{*ùî±`¡Ye8F(ò$kŒ¹Ô£Œmå-ÓD³Ù’¾–"˱AH#°îæu•þe ±ÚH(Ÿsû¸ˆ?Õw…}@ \&3ÓÛv@g¹\øŒ“t›w±gµ­Ú#ž=e~]Rz¹A¸¥ç7¾N%ÂÑÀÚ„™àßÒ8hw™ÁÆÌŽãyï+A¬ÉãÅ[™ŸÚæNÃá™´®5ýmçóŠZ•sÄæúñÚ]˜Œì fP'Ø7\OH÷Ṉ*­xµÛËŸR.ÁbŽ(”!TÃwó;¿ÊŒgˆ ŸÒT¥+öbMÝݽc¨$3u«]ÙnAuÊÓ¾9¬¯Æ,ZL‚ƒN"„Á¤üª$§°ìîÞ’c¯Ø<ƒ+á½ñ7±Ì·C€ÅK·Ëxø­l¤vSͨ÷0Šƒ ™°hIt|Ê¡N¬‡5]YOøàG{{> g•Âf³Áž “¸`+ÕGŒf´†ú* žðO»'Æc‹¯^Æ“{ ÚÉ£‘öÍàCNÓÂ…Š!p4¦†>5ÝÛò'ÃâÍ5·ån‚$2¶¶ ò/ü4Õ'h;Û$ýòˆá*uX:¹Ãm¦šŠn‚æJ P¤ÞÑB,…D®ó|GßéÔ2]^­^×?âE¨/¤>CãqH“8ì*L${‚¤‰›g©ÊkEør#ñ?c¥-ãdWîÍÇTùÔ § Ú+&¡¡Â7uÕ³«Ó~òúAÇš"LùìÙùr Qø;9D¢µ®ŠêºûÏ”HBÞyކâ×Ìbc"¨o¦]™«w>ï^ƒöZJÕYàÝ›Bï;ÆËšAAšsS—Rœ`Ü…¡î‚º¼~8½$eÞ¿.À#NŸWÛ8Eç3‰Ñz.ÉÓÚ'Q4<7AMJ‰û6;ÆúÒ¬½'?ÞÂi¸Ðš™ž›<«2㘾4o¿d.T.;‡¦ùTŽ($îð…ÎîdÊaÚ´¤÷$9wרtœÎþcïiRA>8Íà³¹48ØùrqÚ¤ÙSôu·F2¸°ÇS%þÓÿ·ÌΗ¹\¢àÐËo:4;_ö! F]„ãy>»ò Èšÿˆ–™uŒÉalVƒ|­ÙOBÆ?ö ¥9ÿ>åƒÖ™Û½ëÔ–¨8Û@Cvx‰!ƒÖ*Nz¸rn„·çÐKÑßC’åG‰Ô¸¶äHB›™ W×eænüÂÔŸ¡«DÈ{¯v—.g&å€=ÝW;YéAܬ2Ok½4‹ýuž#ðx Êž¾¡­_3~×Ü“_H º°¾z×ÊÏæ q«Õ.ϳ{6ÊüÝ/[yŽx[$,« EŸ½ŒþBìq9à2À}ÃŒ¨èc[þœ¢Šs/ï{Õ §œÒN½ÖÅ܉J®,±ÖÚ'rªôp¦ô¶ÒݧïLšË`” …ɨ[ £A•"££ñ³ÐRhà_S0)QÀ ^H7–Ò¾#]3¢KN¿tLÁ‘rC€ûFl^N"ŠE&l‘ô 476}üÐ݇ å#]­K·ñUdòq­nÉÍ]×úZ縵p‹È 9_ÉH#AoP»éjæö¡«ã_OeCà¢ìhöajJÓÄ÷›H÷‡Їռ7Ø>^Ä’HdŽ>áçÖLvñ‹Øûê¤0ùèqBE"¦DZ}…)x˜ÔœS’3‡§ì‘ðISpsŠâ¶+E”Yü âË%y_¿_‘Ö(LJÖ%•U‚ËôÉú(~*‘ö¸Œîï·›|—ÆäÝCicÇ‘~9ªùåÑÊm •W"Åî3Ñ.A‚¿dŽ«wö™t¤Ÿbûžž·æc>׬Sž =Ô6 Hs¡ù¤ÖŸvE*7ïgDôe¿Ð󹤾;Bµßö “¯–©L¬úÎPÍü2#døª<Ï™¹üø _©/Ë|?ðœ6¹Æê”ƒÐ¾öÎNýxaÌ;\ϯ&µÕ.¨µ¶Æšmœ^Z¸«ÃU> 3Âß|y«ƒÐ†Ýƒ‚ú²>îÇÖ¤îöPÁ±¶ÕwÃ0ûK¼>l iÐti|À¢1¨ Mf-Éì‹#[Wø,ßf´¬p¯·¸UañCÐ×`ïeG³'¥–¦*!§Ï–N¤ŸÚ+Ù=×ÏwrºxE…­Èíb¿P÷ï/ç_qÁ)UáÒfR﨨òzláŽK7ipèŠ #HrÖ›58ÓºfÊ#¨,]ÈÈâ÷ÛM÷ZŽ«*²l×cß\ÅÞM—`4lÆF‹òÙ®[Ø…K ?ƒŒ`‡JOœ ­l‚>+dc®5«‘[UÄvn}!£).²$<Øàã·åA0A¤ëƒèW¯»;¸R)X ß¼•\œ “w1?6Pe 1òõÊ0bä˜N™Z{†þìgøÅñ)æqRSÈÅA³ýË…i'^TI¬]E8TÂõX¯Rþ‚“ŸQM“1ù4ÈKðé€?ä€cÃP¡­n 'aˆçìAüý¦ä¼Ì>ãûŒÐÅ­°³ðâxÒô${b)&/«í­©CÅeÌ$'^ÎùÍ]ò™"åêÍV:1Ÿò‰_s\º?$w1îëÊ+~åú•oã¼ãqëßÂð¥†qâhæÞ¢”ʼ&f^ÑØ\‹`Ñ}NøYbÞÌ«\' V5|üH'X· /^#ɯ6|¿„BŒZ•[‘2wurâ—6g{Õ`³@ôzÖKµ¦`¶yú(¦¤QÝ®¥—»!E §ÛLˆÖ´¥'C´˜Œº˜ÒѺ <oÞñ·r c¿SÐær(ëk…Z“Ã(ÓúnÀ×U/+ªÕpb9<`®Jïš°+Ù¶<–djÂnÜ$6ûVjt 7ÂR‚¶„i°b -X'ÿýÿÛ$èb-cã'èù”±Àij„&\Ì×Lþis‰É%Ó‚<(<¤e\Wh*÷+0Ï{HûÜPK÷ýö•ÃCŠÑg­l9ª/å̦Œ³§êm;ó”Òœð[¾ê`H=§a3ê\Êi’Üêó߬(²(œ&þý§ìzþì5zŒFEÖ†J{$ø`Çf5”&ç§Ñˆ|þ?­®jûׄ%xÌ}]t_ æ,‡Yi‡¡”¼ß$ºKAîÓ„ü~%‰¹4~tŽ8“޼®^*öNÝ sˆ<jZˆrá½xœ}ÅÿÕÀ‰ð£ª #ÛHWœ3ÌâÅã’ÛÀ°Õƒ³ÔãPBDBÂX¼Ç,¯®Ñ놮è¸wÁœ›ÛD&òæå/d½väBò ßЙ]…Åez„Þ¥ÃüÙ\¶Œ‰ÃÜÒFæŸb,ìôàŸ%ØuµdÝÛ€N—:'Uq' a(&°æSøÝòʬ8fÐî*éu„”ûG…@yDŠe=7vlW¼ûd¿ç \G $´w%quí£‰k¢QÉÅò¤”Š¿OÿÓ•÷'€Sé±J]Ÿh‹IT•°X 6)¬õ¸_8*-LJí>dôx9ÖvêÃM—§‹-/èÎÿ"JÂcÞeq"*[, 9i] h%ÛÒÉ':ëxÌâ Vñôq‚[y]Î%OÖØœHz´§àï‘w.éEI§e–Ø‘kì6‘$ {é!­¸2ÉéL?“'"û ©¿â˜¥ê§–žº½·©Þ›4spå¯RzÛ|ª2¿\)yÔ äÖ‹¶ßÊ1™íH„Û>ÌiŠk!!pˆÊü"îz|UÛð{U2Ée5o ˜œÔK(Ù[êįÞá0,ë«K­þéí̉[#[d±¢:€"xíf5ó¤-îá@ É–.)ùO;6 }û4S˜éyÊ›3záÄ™¿¿f´}g$Öæ!КÑÀßð5 /"~6÷èÖÑÌK~ɵøàâÍÜî“$mÅÖÀåúŒ‹!ôZ*m\ùò‘TJÝA¬®@5Íq)@›ÌáµC(æ Ç#GxƒÞ bωñœ€í‚žòèæô.zÿ“!"ÌþÃZ#ø!’8E’­pÿ·6ñÇȯG9¢âïŸ' šó OuVäŸù2åOŒÊfQœ½:…“‡V’p’n©Å(¡˜¸ì†T­i̵ –J/wFI“"V6™Ô' œo‘ƒÄã}âRlij#€ñ_fA"ÍNi©"þÙ,f%®ù#æv 5ë^–Ëá®?êÅç’Xȹ*RÔàc)›êaÒ‰LªJ×»°ò‡F`苉ÿÖS 裾² #’e¦F*LÅÓÎÏ^jóšTØÔY}—7Åç’žU¯–õ¯‚û¡û}DüµHî.õm>Wò! Ò"JJ`j1u÷X#wŒÄS$‰sáRõ’? :5öÎÂõÓ–õùéò×nibs²3¾›NâÏ?\u(ç¤V是câHàzÖÑ *[ˆ$£Ó\×T AÆí¾¿tÍÖƒ@Õ.{¶ÿ¶ihàá‹"WŸôæŽÚ‚›L‚5†Æ]Ï~ºa°Qé0ú~Ì qPYœ™—íýC6#ÒÌI2òy¢·Ô¢ôWäŸÕ)þŒÉšžžJw“¿mLå[ÿôû»ŒØ4„Zå¬Ä˜‚‰zb%BŒÇ“Ú~cƒˆažº¹Æ,µ§#Åò,1+‹b®~xV«ì‘¸ÍÂJÁàÁå ÖgëÌwæPø.Üg5ÌLç•x¹Ç®_tGâ‘W^;Û·é–¬‡ ÎÁ ·SˆýÅDa™:§(W'´8ϧxć^$•€·qÍ­²-»ÁqPªÍ1í‚5È–Õ=L‰AwQ’·á{°è_æ8¦ÚghY :lÝç#~yRptEä?)+(6üŸ]ÄY­ýýóÊpͧ.ÅúÆL.ÎûÉv,¢!o¢F*ØÝƒ X‹b·+¬,>U ·;òFÔz‰~í‘Ñ\qœÄÿwÈ“íÎo»Ìêž«Eª ÁÞ9ýéb¨‘+ÊãvòÔûíx 4ë4ôhHê šÃ5‹·l¨F¥EÔ·Ø+@|ú8NËýgpAѬ•UÞOx¸ o2ü‡x@5ú]Î[õÕSv¾0@8Lüº sÿ/–XS?áv0(½™0'ˆ@Í»Úûs@8؆"\S4BƒØL1ã½›ìûÄ¥.Ô ºMŒØuQÚ·\ÞF4K¯xÀžé¨ öòN9÷†mm”‡1ç¹Ý´áèmo Ìe«D-¯IWË”Žüœ›Ü|˦WŸ©áâÀöÛØ?gtÌ"ƒ²I°uG–Iñ±û õ×Ô³]N$¬Jö×hÈO9Ö_y|=íI_ã ˆœ„ÁâŠqšºƒPFdùö­x<ïâ™ît]´™'uÁN£6n³Z°¼H›gö>¬S¨‘¤=£MU;¿Ÿ&…Ä+KÔŒ'ÿÙÎU'½}¯ÞŠÊ„MÓJ.ÁõÅÇpP«½ª†y0b7rŽ[ê|ëu½‡é}¡‡çÀðƒt Q^GýÕºûÏ“háTXîU_4»÷ûçTÇ€ûsiÄéר¢›Ö,7ÍlUTD`ÞÚO‚D²ö¥4¿Ö.}n<ˆjoQ¿²…?<Áž¦˜6×m"Š´£7wUíŒso—.g¡-H“9É*„²y‚|$Ýqÿ4(ì>:Nñ¥Põ‡’ ¤íÕžÒ¤çÆ‘œ+X4µ º»íÎñhŠ]úϹx4à¡ès+H$PV#„ @^†a4c}Ìä„+ŽǸˆré©{ã$,å¾jd\&SþUÐb·†¼) ‡‡Ùm/R~|8T§˜‘]Ê4ÛJ‹˜È#WI7, x 'Ä:U)ðí¾2fý\Œ£×ÚA|lºõ¤óÁ®ù÷+yù}=i€rˆ›À‰U¬XS˜©ïíhn¯ãËöî©͇1á':Ȳ¥öM'·æsàŸ­üŒi·›ƒk¼dŒÀÌ–üfQr…Ÿ©5¾WFñqt26ºAˆœViÃ!ozÊa7Èîü´nmÖWG©CŽ­È_£ÏzW‰‰}1K¿’ÓñʽĎ‘V1‚¨É5ZÌ5 ±4Qر?ú€¿qx3ði.-·£Ä‚î'ç-£œq`/8ЊÞXRZ[¹íÕÁ5¿?£2ð(ý¥‘D+‚û«Û^0ûnÛÝîQžÑ®ÝáiQàôl"‰M–X:æá‰Æ(ba–ª14:vÀ&ò4~Âe©8¸ÆU{»ŒD¿Dd+áª´È ”¯UõñÏô )Ì\ÜQþùØU`Í"¼ž~+ÚM–¼—‡¢7µ–´q‹—Ëô‡’”ùÞâ’u³†ák,Ǻª½ùP¢|iK²(ß2tk¼>vŽ|½£¹Ùa:£höôW¤UÚÀžR‡Ã˜UcÜÏÓÙ°½“\:B^bäQ¹ÏBŠq\³ÿEK,1Ë{ôSzPܰhu%ü“X5â& !ϾûeXg tRYþãÂU³æºþŒ.\©†kî$Dçw¢_²ÞHT =uó좖Ў[_b½Œ¦LØo¬Hi¹­^<5zRàiNQ"1ˆÕ˜P]Cjµ%ß64gv÷âÅÏë“ó¢5‘"óé÷ mE¿å÷ï“(ïßuò3¶xÛˆéØeLühpfzý³`7ÅÚ­Ri¦]Q‹çlËŒJ¢×èÈ-¶‹–,®ŠdMÕX]j‘Z´LÓÈL*DæwE–j†~¢nò‹¹ ÿ‰Ýcòsk†Æi6¹y£Á¸TýxSà#2È–Þ{Ö×´äFúñX1±Ç5£Bžt8ü°LA»<ÜÆ® §øÎ@=Œa€“o’~I%S&„¤äÕ×éWOµ;¨h”8@¤c¤AíTk²ZÂqrRÖTé€f¨ ’®Ÿy!¡¶´®òbþ9×¹ÉÎóÓEÍ™±>™šæù$^½®óc¯}Iéð4O|À+T¾@’BÍØ"qÍ)¥¾+2„jaÂ`ÞLÜ’’n#P³™NËTØzúñž‡Ç]”VÎUcMÀxÕW;Ã3Ù°±w2æ>»øÙA÷ÑÛX Ã}˜~ìâx£]ü÷óÛ9ÍxŸŽƒNpûüƒ~£Ó.¯x™ÿöN“¬ì¨”³Õ¬ êš·c ‹ðºgyÔ9pŒ`Ÿÿµ-ìM§“®²K¬]ï$e@úu”rù+ßå•eèljãGÇpbë¦M+lH„Å|ìà«€uèˆrFe¤«ec»x5öð%#"·oÈ€ýäÌÕ~Ó9šÊ'uL†ØzöÇ•‰ÿ‡3,5&®©BNˆÏ| >RÜÁ_Vø­òcܱĹzäËR‡™; !QóZèq„“ü Gû«çV¢’î±/M£ï³@%©ÔÅ å2_kî,²j"•é`9|çƒWê€íÎëá1ÕlöUâæHZê;ž4¹ÿr$ºÝ¿¶.¥Ç¦³{ôw½5öWjý —RBD–ƒÁèÛ‡$ÑMM¢”xº½vÀ"QѸa4¨y¡}8‡€2K–'à ‰:,ʼn¹]Œ¤ÜjWýo:å%x€µØ^2ºÕ‹é#-`>È”â‚2k®ÂPçéý¬Äžù±Ü™{?½Æÿ†.±¢º÷À 9ª}‚-rVÙ®ýªAá endstream endobj 239 0 obj << /Length1 882 /Length2 1728 /Length3 0 /Length 2316 /Filter /FlateDecode >> stream xÚ}’y8ÔkÇ£¢„(…ƒ‰ˆž€ ÂT&KjnMX  ¡9ÛÄ4u4¼Mšþ?Äbš±E©˜ РY P”нY€&ÍùŽÿœÝ3ϰ ÿnpNŒïŒg„ÅÜùÀ„¶0Ä™„°`.£ ˆ™;?o»ÿ-®­-“™k°F¢ÞLMq¼’9,–hMßÿ·hE?™ ‹>q!²Tg“lq$ àHéxžJ(êMDÏ«ò¸$üãFˆV{fm»d†cs°-‘rC¹6Í­#;¦©m¿Šžp¼žë[qöà‹Ô­ç‘EûlGPOŒVøCë(̵þ &iq}òÃ'ÝÕV KÚ|Ÿ¶éh“Jƒþ›o³fÊÙý»ÌÞƒ@pù‹œFª ’`#(/~¯ñû+¤ï+—¨À"œæx:y5̈1ÑœqRLið16¯Ù]ÊDÝ‹\³òÅ"ÁúæÑÙǯ*.J…mc¯WzÞ ýêËÈW%³–×ÙžÉ vܾÍ*¯™ø}¼È’W˜­WZ èïÖÉåî^C´+…¹‹fíHœÄjSÒ»õ£·RëºY]½Ò¹ã„mƒ+¯Žß=¨¤ÿ(:­™µg(”¯Ž½ÜUûÒÐM’Õ¯íg¢s/X¥dlÛÙ_ôWßd j×hc¶ñWÛ#Uö…¨=£‘³†ŸÛèYŽ%Ç2ÇÖ)˜Wá¨:Ë>=|Zß1ðþlÔ9m õš?KèèKîY5¨¦æ±:º!'’42ƒ®K&­µ+Vߪ(ê,Nº¨{(nìÂó‰µWß3' ­d'¤#b>J?©pOóªGOb®%w‹t¡6y̪Rd|¼÷y-býdÊ£üd>6ø.ÿ–Õ~7Á¥Sê®ýS5Fà Ó$v¼Pp·:›Ø9†ê¿É^ãr³ÃÍúõþñ‘ÃãŽ:î~KŒœÚ7žû8T•3}Ö7”_”$—,›¡Yygp$1-¼_¨t±²wÖj’ÓõúÓDkS}ÍJO]“W‹!;¨þ!EE²ô“¼°*'}×þUJ ã” œMBpþhŠINµ}LÖÚLÁ]”‹w’•öCÙÖ1‹¡´Y™¸û’ê—w>ŠiSð –÷D‡èn K3ž¼|É›¸¢úÕðYÚìzǦDóÜŽ‡e×/žR]ógÖRé±Ñ}›2¿ñß¹Ÿ)bÔî¶5‹Ç¥Yoj>jVœ° üV3åí@ÜÖ`s«›i—FWF)÷œ(T++ŠüèµEñvÖ©º-y–Äùºý^¶šË«ùKö¦j 7[>(6f{úHÇ´¯?V~0Â"çZaÕѯŠ<J¶å"s7r×aìíû3E:áºædዉüPªLzÍGµg¦ûÎÙîé‘ÉGO«v·(g'† ¬éV p¥égΔô¬UvÔn=Å_Ùpä#&ä§mÍ“ :Ê3y»¬ÐÃñ-!š439òLóéq˜ƒñAzCÖDÈz4®ïq¡:%›/‰ûvóÅÚà ÐÝ0ÍÄk™©DàWŸ^Ö¹×1_ ™J/¾N#äRU ¢É—ýêacËŽ=U™„N(¿¦©(54hGœ‘-…»;Î]ᙆ]xŠk¿;]¥s„Ô1fïM ÓšÜú%ÞÝÆW¥ v‚všBw_k`ÿÉS2%£›£o©5Nþ•¶ÝUv Qü«3'ÂŒ»-A®Ê“z0™vZÍÙ¬íRÀ!:?Èm°n2Ð- />d*>Àò«íy^7ÒyCž½òåûÌôúoÏ:_‰[å¼Ý^áÉþ¢îõ9×Gó⯔©ÿ:Ý0¥ß¶ ¯E:¯Ê4Ø,ÖY?¡x˜µÔ£Ž¦¬ÇßÝ[ðº…;%ñœq¸:äT®Íœ‰Éùòz×ð/ž2c‹‚7=x¯ßíé]vx§VoÈ+çF±²sÖÜeþý‚b~e&!™÷éyíí´Ö½©Ž9®ˆ:÷ƒóª õãŠB¼K|ëf¾·dÈ;µw¿÷Ø=3! ŸŒ¤v·__“mM\¾â µú69TrMN>ßåOÆûâý?¾ \ç v7ìëÃÕá;Nêî z~)Yb1¢ìUbtè~/ŠíY-ÉÓJªökI—8Yb®î|Â;*,ÀI }GkÜß2éÍ·<­5–ÖV _TÛrÁMÙqÌê î1þÒ¹ÖLªôÙRÓ«]¶Úª;»FˆÉH-;¦!¯rô·«S_Nž‹šYÇ‹o!ññ§–ß8–b¬S“eULsÏ¡k}²o¿M 9Ÿrç¢hs9г¿ýR¾›R—Þàì«€(KVl±œÆJã°ì_âQ’kÑBü°]À¶36")W¼cñæÄr|lÂ& “/ñJÇŸcМk} YôT¯®•'Òfî5-•·³7xû ’ÈJ>zŠ·<öZ¥¾ÛÁ‘1!,®8ÿek$_¢10Í€V—B¼; VÆñynÕY¶‘ u«v¯èm³&0þ>¼Ñ endstream endobj 241 0 obj << /Length1 2005 /Length2 8626 /Length3 0 /Length 9738 /Filter /FlateDecode >> stream xÚ}—uX”Ýö÷‘îF†’†¡;¥»D@@`ˆ†.é)A )$¥¥Sº»»%ÞyÎs΃çü®ë½æŸù¬µö^ßµÖ¾÷=ÃÆ¤gÈ«` ³«À ^> $!à@„ø€¸llá`ƒ*`I€€ ¿€0¿ €H’D~ÑÓF†k{¸ƒìÿŠ ÅÄ„…q[ˆ ` ¶‡@qùÿÚ_jˆþm·õpýÏ wG&p “r)maPg€-عÎÃÙYäpüK×ÿqƒ\ Î>ÿŸ€§`ˆ½À¡ ¶…x¸ü¯Wr†Ø(@íÁàß&ˆ» Äl«AØ8pðßæ'P[0ÜëÁÜ!µÀ+þÏÈbã»»DþíÒ! 6HmÆÿ.Y!@UOë…€]½ûÏ~ w0ÿÛ‚ÿ6þÛ†ÚþoÝýWøµÔô u¸ÿâ¿|ÊP˜-j€àp. €$€Ÿ‚Ôî {#‹åçƒÂÈ%WDÀÇýkF¢"~…¿L“(€_ñžÄüïIÀ¯tO~åH àW¹'¿ê= øÕîIÀ¯~OÈìš÷„Ì®uOÈìÚ÷„Ì®sOÈìºÿ82»Þ=!³ëß2»Á=!³Þ“0€ßèžZžÜR‹ñ=!µ<½'¤“{Bj1ý‡$‘ H rqEžr¨ÿ± #5Ü`8ÄÝé~!2ÔúD*µ†ƒlÀÎ`;Äf‘›áÿ:÷ÿ,øÛìFüW¼„Ð?öÿY€ms/Ù˜‹Ë½ð¿?¿íˆL¾þ_äær¾/™yÊœA.¬A–i÷Š #ì ž÷›ˆüå†yÀÿX€ ±¿O‚ôÛÿuAÿ A*u¸×솃«úGÒù‘stü‘ãqú‘M¿/BY³ó_÷½Ù¦?*@ܧBf‚z¸XÿõìÛÿ¡@ÙؽFä0(ø7².×{7rKW ý¯¹ üÛúßSFƒ1²“îÎ w‡?¶AÊ»+‚¬áÿ1qd­/Ø {xÜŸI¤ ¿îZwüφ!‡äù"åyýñD 7õþ‘Y}þ@d³}ï5#wòÃÿVðßW¬Eù¸þó¢øëÎý ü͆8Ì üb‹pø3D„|²¼Ÿù€ÈGø×ç?ß,þﮨóöãA¾[‘€2N\P0à¿âl<àȱ#þõE¾þÃvä+ öÛàNOÀl¤Â?‡5^V(Ðzñ®`..‹N2íŒA<šÌõsÐÂÊTuS´²-¥ê{¥7U12áOËup9èmÞš¼®ö¢Ü¹ªxÄ›×suÚjf°…ÑØ‰½Š^%9|©OOdõ ý{ÊÓ‰ëp±6¡Í²7ßÜ7Í$v.€‚ b¦tZD¼Bη]ÔXS&ÖeD¯©9q)üÙk#õ'C7¨ab,7êä;©C梒½á0Þ–@j²”œβ[§·=Ë­ïm¤š˜çkdF-^?Í¡•qt6pœŬ£\7U-M¹ŠQ«þØZ通"®ÆF€³ò6q¹ÁA ‚½í åö1ÈÃĪ[´Í|zU•>0Ÿ[Á/¿|¦ìÖVxÙLÁ×þjn¹ç•Â(P0×·$¬‡ ú‘Ò· ã/ÞÉ“KÍÔ|`²Y«¡+dž,e7w:\$úS1ì»R ¯åià­ðÙ„ó‡LÕ†˜Üógò©Àe_ÞéUZ.Ó&~>)„ñ™Èôµ"xEr&~Êq5yñá=½!eøPq èhš{/6Þ—IDYÕZ;]—ôŽ3$ú?M¶Ûnç_ž÷gß7Û)¨­"¯Âð'oòº‚ö¼ÃZœIngŒ=õ4^´6²¯°z„²Ó¹gdÓ,'[*z¤6ÞöZU6¥5»ÇŸ.G<í%UeÅN5§álÖ/ÏIÉIUæÅåPôâ¼CE? ;dLNNù|Ô]>²uŠ8éÁÿõ1à“„¿SäUô@††à[ÿ€Wæ[(·Û5…?<á&ŸŽ)bï¤ì'ŸI->gû p°ýþõéã„?Ál'¶¿AÉt ç§;OÎGÀZ. or±2ÿ'½øæ´$Q…züõÙ!m\l@Eƒ<1Ž,v-a¾ÝBãgÇš’ò9ÉÜj)¼ÆŽ+iu¨üa˜¢ë"'S/mĦJÈÚïZX.' Ìr„ÞÝ«œ p©qbÔ~ôrÏ™UP°b ;óyi6»Yo[ùuå™óxa5óFxˆxcΓ+`Ðy!;?Ì»÷õƒ°"QG/=iãYµO× ¤—GªedlLLñªÇß-š‹Í) Z+ŤïüRQB™Øë«B'iiÔ6˨“y å ŒÎ_k=0³­Ú‡vú:4Ê•uÅPQ}ÉËáME›zˆ['MÓÔ'ŽwCEf 2n›¶I  Í~戆`ÞYˆžÞº=¸´Ì®g?ýÁM¥ØnÍÑ•vDøëýºÂ¼FìöÀ†“q}¼V0†(òŽ0Æ"Ü'LiȨc¿(ߨmÒI]Þ`¡©m"Ûú†Ågæ3é5~Ož¥jîwŸàî ¯}_Ã$FËÞóÇsÉUol+ÑÛ¦Þã<¨>£ÓXkÿjøÙµ§~ôÓ£NêZŸ+B²UZ~y·ªÀ<N5a<3*®ìÔÚ£µîXÑAây"k[—‰•ÿnYNfÂd3þ—»Ë#KìµpžÇ¹]Ò¶’ øêdìÆVz ]$t‹Zé¬V(¨¬C±£ª‘Ãlw õ ãB¢W¬jjãœ*ïjF’2,r¿÷tOÖ¤¸ªÑ˜Dˆ[ë¹–´hZËÕ.A¡¤QÂ(]4d+ëÝ,%'ÑV ç=ìCòÛÎâŸO›¯Žœ£r¯WZÒú.Ãñ±›Ô{cSœµ3Šû[å]üdÕïd‹aßÑ,áÈÑ’-ù®HGóŒI1¢Ã,9òç+àî#·imþœÚn³ÇžCtÑhZÂV]$ÞIi$¯@¤´)¸ÓítR/jÃÖX¯¼^~rþ@ØîV¤Ø¤m$Æti ª“[F O¿¹‹[ÇÛüâ?1åê󩸌ùñ×Å(¡º¾vϧï9ûä™!O õL‡¶©TÈ:!Ê}Nü3Œ61j‡u#ÖÍBo~¢ÛX-·’G£E;ß} ¾)1 1#Ø…k ½ ^)sŒ®!|Ð=Uœ¹ }ÖZö}h“ºý—¬½÷ÛÖÎø‡ZlÊ`Á·—l[ðÛ¦®JÃ㸠ï;Ûuɯ잫%ˆÏk×k }³a¥œJa”ç±…ƒ4£ÁÃ$?0Ž~œC­ý’çÙÛÕ-t·µJ¸¡dÖ¥OE»ž¦€b9ðLXsîW}±’²üŒAp‰›Ü†åqîû}g7 ¿¡Ûˆ#.V&úë£< ßRÃPKyq»Á±¯,QôLçÔØÒñ‹ ò(Úž¢DÁªcø jf\o!}G×* G´Òª ÇÞŸŸ¤n’4Šxâ­ŽádŽÓyçáMíU^1`‰ð¹ÔVȼú*ïú_óRŸìKû,•o»Åç£ü”¥ÀKìŽXÐ(‰¨‡a±žÛWö–{ôäŸD‘ÍÌëëÇŸÌ©Ú9åt ¸Ò/zJ8Ŧ_¤˜¹e”?2“2ÄgýTúhé JÅkL¤eIx€|gÇX)Û:Ù©1×Ña'« °÷D×ó]jVk׊íæmeú 20ƒC•ß0d},=ÇbvÇHS--kŸ¢ú‘ˆ«¤Õž<µC1a(8£™>]$Ï#;šøòeí%Ýl'‰ñ¡º:…ÅUNH§ui‚iáÏÁÃg— 9üë»7QIò`X’Æ”Tþ©ªAˆ·!ùœŠ{ýâ8Siil¤rªRÃò6t?æý6Ý(«—äVyA¢ªßmµ›PÇzn`HÎYÞ·:ÉÈàµØ×ý;]P-&{¶ s#ç‹×È]߇P ù™ªK#¥ŠàÑ%Ì £]LÑgï›.ùÖÓï·3‡®@‡ßAÙù/I·EG¦YÖßÞ¦۸ÈrßGôÚ%4}AAM;yŒ–gF*pmá6ˆK9.±ð”˜–>ç\#4ÇÙD‹˜¤Œ|äë‚ò3A6‡3MŠÜ´Ajj«).@úHž§ŒŽ^Á°<üS‡xû›°#­Ä®P›M6)ÝÅP~i-è § ×ÞYꙕínƒFš(Uóàp™ên×)»V\ˆ»—cm*Å`9U>¤Æçé¶æÃëôS5fEã[X_ãžm³ö«‹qÿx‚šÉ,ù:MÂ/ZÊ3J™•À ¯©Ðößt¤â:.í¾ ýð7ŸnøEJÍ­D¢õ˜tsøóS®´˜\AíÉŠâï±r ÜʯµM!Lˆ …–c\u™ð2§bG‚[›6ø£7ùjùîÕ>§àŒ±»dÞÞÝ«Uƒmü˜H79X–º?g*»øÉügFZO§M±MX5XÌRë·Z-–x@g~ã _Vß~Ï °RÚT?÷~7ÖuB\˾G»p4ßfÆ4ÁÍ^Ä\°>£¦N°¯,GËöë—Kû½BèK¥ÇVrüÌI™¡•~]î²ÿðêc‚»éâæÚˆæ­xè&gÇ‘sCö¯Š%å‘y’UŽû€Ö“¾@ô]ÜÇŒÇÄëõ¯Ä˜¿}Þ7gJPÆ|î"Ü|YÞŽ"–Œ0­ŽS±ù¦]¾ ¯NÚ+±‰äàÏŠ}ÅnE‚3s6±SR±oûà`lî‹5„Èo )úXàååŽÀ)4¿7¼6aª/8Ø8²ˆüŸ»œ…ÞNAêj;£‡VበDZâgo襽ÊöñB¢7½úqü®:cäWñì(Ù‰¿â€×—³èDW4DLnÚéRš ÃÄ„íÒ+o´¦{“ÙMNïì›I«9¿Ýí:¦HÞ î8]48÷¨àêÞžÿN÷®½úÄwÈ Z•Ë^ÐâÈøÆMžýÖ×[[ S+%k•nYÈð.ö®YNg6É$›íI_@º›åÅï~ãeÑ·®*Ïæ/¾“Ár#Â…ÎfL24sËé{äá~ÂÇ©&3ü;&+‘¯+„nÜ@”Š–!ê\?áËqçúÌr×ä™Õ®/%Òãý=›ù”}Z=Âñzñ}µÓt2#%ñÎñ­‚†C3šÄë|§ž°Œ„ ÃÂÏO¯`m›<(¬Uœ˜t°}Ý©,7™¶ïÆ“š&nñëV 7r›ékŸÖíjÎêí¾Ç‹qŸHÇ2v5ˆq)äG˜iBö©X´´}ÿªVW7©ýTÍ çíj9G±èrÔ¦0p*QÑÀs~H©µµöLp¹KÓYYçbi žSþÞ «3Ò1{餰Ó|| ¼¸Ž+<ạe©·ÉofȵÑð2âÃ\öÈÕ©·X…˜q£>I'œ—N$žït¿¶×VGêqI™ Ür0ÝÐceü²ˆüeæŒ%§–é&Æó¢»l¹¾T>ß^ih@p—M=ò˜k¦žW¹¤ùLqmAGP«gzjôþOÐçËGµ Dí‹#&‹\,Ý”ál•ó2ŸÊYÍ«)#äs-¡žœä^Ú¶ÏjºP9οÖ"ì6ŒÇêÖ6|öÒ\¯odâŽÂsíù>ÈFÛ5áÞç ¾® "­è¡op)÷–÷™¦'æyŒ³<mžµBÍO,H _“›–ËpÕ  ØÁÅ}T‚Ç[À›œôÜ@­ O™èÍ Ày"¡;ùºˆøÀ<¦ìéoM\os×câÊu`Res*ãDäoP¾²*ø¦Ï/4ÝIÀ~‘o*oÙ5w‰Ë šîô‹uREdÊYD;`ó1P†Á´&»]d˜}Cð²GžLng¤˜W•3¾axõðÖÜ1é&_vʇt1Þ>ޝ4èˆ[læì4QiW‘x%è¼;Kf<+Í€'>h|·PüqøNDÄkl9׳Ñ9  ‘³ó¬Äxûnï®;}êkƞÀ‰‡H¯U¡GÝñî똰¾C?¡3mÏ âüŽüÊD¯‹âªîqt®LV=¬õL”Y&¼Ý;;öpÆ‹an#¼Ö>Ì6lÇ ¹Ù>05ïNÆœòZ,RcΕyƒÁ ÚN´pøÐº°ñ|ÕŽšjß~3rZžºT›ŒÔtî¡?• †°Vþ=×–)_ö³ëߎŬ*×hCEÓ ÌiXšÅ?ðrýV1¼"EÁH`$›obßiŒÜò–Ñ}çœe™æJeÈœ6ç4æab6­¬«Áôà~=ÙײÿY×èf7r蜡þc¼8G¥Sìí[cKç˜DW®Ÿjç<“¢¥¾F-Ge®í¤ÐÚ¨£e“.·ϳä>E[—±öFìýÀ}TþbìNÿ‹6BáÒ6:©óšZëg“Lf‚‡ƒ ™¦N+CéÁ ­”-ײG¦éÃÃŒ£Äû¢%¼X²¡Õ:F—\ß|iµn0­&2&WÂÛežÃš>®eUC¬¦…”nE×_s,mÛwaÇá—SI†’=3¥[2gH þüN×Å¢ºïפ[–9{0“PF…Ïúb sèU\Tк¯cã™Aå¬qžSº«‡¿hùiÄɸg÷EÁôž±,Fðï/žÕJ[‰)Ö74Ng?xfKƒD‡TÌBEöûw{ÚöÙ?Ág¥(äÝœ^Í’*q£ënoŸ'éèÏ/•»hç½&íW¥d7Ñ"öúÍd¸TÒ"ÎéU0¬ªíHýr…6³KJ`UréËÙ·ÈetŠWæœÉÄ(DçÇÖ¤c úâæ¤žu¦øLŠž#ÜJ–4^ÂÙ„˜S¥s‹¦}JWI<"hB.ëén¡Á‚Ûì©Qiªw—ä\3ÖÚ«÷HNªæL B„`™ßýð>™±¾u¿Ô¤×öæÉ-)ŠÌ¬Lå6™HΙbƒ =[$Hµ2îxˆaª÷jZüfUì¾ÝÕ,Jµ=‘á{]­6±ùC£½ÚÎÅí¹1ÓôV¸­NÝ4W ë´Q´¤L «™!ñQ•¤˜3Pª’þw¾õ»¬›é¨ó±C5ô¯Ö8k»¶bèäŸ/mÞ­…³²)%m{dft¡éík/ñ»ªjÜ!âûmiÇÞSc÷’|à€êúUkEs%J¨–_𮩒-òÄ“v!›[.*ã°à}XýrrÐPAoO§;‘Iì™ft3<¨‘["uPØã}ºxf;³^¨øš™‡ «à ŸhâÊ4Ôð‡$…ãÀ¬ILÑK¾ý–éIŸÝ‡Á\¯×ç…ß±~ü,ÁK» BÁ•EÝ/…+|·ólþH§5{!³–Üô‹J¿ï« vÙ¬ï±(Vš #MÌRµ™ñÕ¢ÃÞH^=퇒«¨1† W ^,ò…‡Çk¯ÙdOPÙvûÒžy­p‘Ù;Èü® ŽñÒX?V<%W䊧ܪ™éZØ ý”¨xt¨È·$@ÔôÆï¡S!ž‘€NÉÊÝ踢0>¼Ù¯Û©™×ù•[(¾jOÜ‹);õ¤•@q s®¿É§ÆÃ¹ÅË×"ä½T¹.„ÓÂçi‚êWµ¾åRº–m%Ìùüà¾äg3æ’¿bgNú<<Ù ¥y¦¢¸&šlîŠòÛêå¦ö‰Ê‡:ßbŽ?ÚƒK{Ŷ¥®’íï„, ·<µ<ÑDcžù*8d5ýQÈnnÃfÁ›–uZÔÄYtÎbsÈú>PI{N_(Í÷7guÔ6wA}¾šÌ¸ŽÑ “˾=yZ¨œ™sV­Ê7㌑$ß aše±aßzT»|Q] Ì4*K{›!Úc2 À¶£Hš.‰)a(ðжäÍZ~ë¤zMö«2ñ7tÅ.¿ëÊž ÊÉå–ˆ¹NbÚ ú¨8üÌ$ÓÝKÑ*Êz‡i_Ÿ ½¬¼Z*£åh™³ÈΫ¹>˜*vM‡†yÈÔZ½~_ȧ@BµïœT„ú—Ü{?d|M`¡G>š~À¥I-J*´õ6ø{§N*ÍÚ¶Áäð4Ç<#Û¾½ ѰãzMeÿGÐ~oücž†ƒjê D½J,òßõì@XdÝÞɪ ˆö ûš›½u°Ì/¯£W>˜™>4:¸WfÖ•Ìaúe#×~@ÜN…Ý~VžÜ£UjK­‚ÚŠ}ëD6 ¹"ƒZõÀr>¾b:œÒ’=0j¬ØEÓq2¦f„Óø€ ]ð×¼kíeq@~B&VnÝpÿòÑ5“>ÅuÉ™®æ¥â¢QxžÍÊHC®l‰ÚÓ‚)æá•Àæ(IEÓ÷œQ¯¡H;®˜ß½þEøÖtÕâ/?½ú.k±qÍò4Åë1¿yZ7‰^Á Xíz¡yí³Ù*ÍX¯¿¦ëI‰]K™Ù|Å%µg6úDÞUGð§V‡‡Cç~_èöÛržfßåˆ(ðZþêç/ƒ "øÉÌÙsrâf!Ífýe»;?E¾üU?úølå"ûç5x4k§ÞÔUhNŒö ôÞ¢þ«ÏIlfІEÛ®W¾U²?ê–×IÏk¼ÀTOÎý‰þxÓ(owXt¡b¬ºYw÷¡^t[ãµ'¼Ñ|ÊKTþÒi»<öö…Lì¶Ôëþ—!ï”Õ6O†t<ýÖÍ™½Í£- èzٙדæB/¦!¼‘䊵ð?¶Ô¡¦—ò|“ºÚ ýÆáê.i¢zZQ¼@Îæª%¨°ä¬×âÄx(ÎkœŽ¥=‚”grÑ|gê|A=ü[Õ÷»GÜfZ£ÃìBýÅC-©³ÛAšF¸ÙüÅçE¿¢ZC†Ç> ìÈ£l¹Ï›†YËož†—æ=Ñ)ˆe‡±è'•HrÏ~èÈ}ÁÎîŽÞ4^™pûyp@›*b¹­'•thô1ªØî‘ä¦ šRÞ¬÷†Ñ§KÀ²—þÌ?•vveU}““<&~SQYe:XeNXÉ’H wýV§ø‘;ˆ£«ƒüAÆÕs)KJ`Á‹’&û“ß‹¢(-²øw$úï…(9ÌGùÁh@ Å›â 6p 5åy•µ£¨d‘#3¶«¯Â¸¸.qN<Ëïg€Ðü¥#Nf5Ã:ñæ×aNô¦=¡Ô“üÒ³œéI’b²ÉÉ÷Áõa\zÞDy•sºx³Ô0¼LõVo׆hn§OPÕ”üMÖ7ÂcSÇò6tjw—ï]V§ÜM*:Ë’s÷p›Ý²‡ÉºÑ¸ÃŒäƒ>»ðN±¸·³Î¹¥œMሙ‹10ä)~ûz (¾$w=‘ƒÍy÷@Ë´‡qƒ#OÑM…Nàõ¸Ð0½^ÔŽýðD£+ë+Éc‘«¸ É!«×ÅæÏŒèŸ¢h+àjsÕ÷„м´C ÷ŠjHp9—Û4œÒ‰2?ž0PÊ~ÍLºmž(^Ãz³'‰±¥P?É×Mtøø²û74P\n”έ;ÎÈœN¦×¢}fóThšjI®Þî–Døá¼ÁrBîMBž<&QE Úw7É‚•Ï5•¥8šª”Þ´Ý2f Û%IáÑݼ‹¼Ðɼ$ºôPÌÅÝ&“¼ÇhRôR- fëjY \ÛOÇìú.³-@_›4|»Do‡Ãæ¥V§#1Œ„+ŽçøešOËN@e´‡‚ì~|þGÊÒR×–ÄvzyЍvÏGPE¬ž®'gî`S×_“¿¬³/õ]”;ºE,EZ±”"F˜‚€Y와±Äùù`‡&HiÔ Ì:^ŸwUwíV©ýí tÄ{'€Bk€{¤•мÝ3…Me¹–ÁžÓóx×ÿð«ðõYU’ f·°:¬Tê3'5ÌÜsC]÷âjhZ¡7<{>ÑS‹=×҆˓`&°ÔÆ‹­Ì8ôù/ÿw¦Ú<Ÿ¾?ã2Ûô7¢žài:ÛY¯ßGM-Ìqrªee`k-ãÁ*EpÊOÄ·{ Kð* &6 &Õb—Ÿßùv$™·†q n …-Í<·LJ¢÷ Ðv&Ût¶Vîì¨ÕàH© b3XšÌ/ÑmO4#Ë,t7›üÒÅWÝž¾Ù ô—å¬9,ÕÊ ‹ôŒåàcwä¿owW*aŸï?v]ä­õ£$æïFTãð1íÖELºÐR7:%Ž/´3ñ˜T-V½?‹P~×w¸¥ŠŽó¤e¸ÍŒ‹i¶sî}XÁâ¤é–Õ˜ð²&õü=‰£´½0ƦVñ§ÿg58ð endstream endobj 243 0 obj << /Length1 1088 /Length2 2896 /Length3 0 /Length 3596 /Filter /FlateDecode >> stream xÚ}“y<ÔëÇ%KIö}ýŽ’uÌ 3v %ÑX³3fØaŒ]®Š$)„\Q˜äZ2%û’,W){ÒØ*YúºuÝ{_¯ß_ßïû,Ï9çsžG„²`Iž8c‘†©@µ ,ŒBÔT ²²Fdš‚'£)8m¦ Á!ªP(@S¤ÍøAY0Âì-‚ƒÐÞ;PU8 ª¡‡s¨B,C'Ù³Lú =°e"/2P¯J.ô¾ŒW\üÒæBË9;žnšGaB>}gHßz¾¾BóÆIaIbÞÝ ïx?¦ZIr{8³8Ë¥~¹§Ñ¬6S>]¸Õ4ã¤õðŠ>ñ€ÒÅ)— rß3':‚OPÚ]x’ùÈΙÁ¶fvÝ[̱‡¶Ìæ¯u»\P×nw«'›¢EùÇ™rcGgW¶ŸOÐnÍ|ælk“ü¶M¡Ÿ]ˆIòþNÃz~ ÉIsýû}-ÄZÝ3Õ%Šõõ9'ÅCµ^¼G‘k^¤2m¡ƒ<ži¢çdVÖ+Ó;ÿ$½å¤~q6?Ø\üåñYA•¶¸Œ>²ÛBhš4¬hìÅ8Šô[Ú‹äîü-ýkYæ{fjOœRs¹ªã5¶ÒS¢þÙ0¶õx5Øm%z¾ú’P˜eòèRþšó±kЉp§î;qELjŠEÍ~1¼iˆ{«=rù•ﻫ¯…æ%%m„ãºïF£é x@mì¶Æà‹,náJZíðÔ…s k·F×ÅŠß“¾Âõ¹Ö9#/,q®%¦ò5*¶i?LÄR£ú9«å0k¸VâRÓªåXdžMcN{m~®¢R?Êf*­~CúÔÌF;â#ŸR›õ8Ÿ•~Nòðv¸ã¢ÊT‰LYQ²¼KÆûc|ôÇ/&òVž,³¡d¥›K ­w7s\BÓjSx®rej®›§'gDÌ,*ܲ½¦2eP0°èE‹¹ò<÷)äíè45ÇÇgÒ"D°¨%߉,y’Ä Ïy"¼²§ö&¼˜ó édK]Fû¥‘›óN‡ÐÊQm˜%6PY)€³²2^˜ß)zu(ŸuãÜ¡+Ú[iFbZqmZD^é^‡eH[óáÇÔµ,…ûç^~ã§ ó½GìüœðJ+Ïñ³üã¼Á3ÝCw\k¨z]ÁæÝ S'uÌÞñ¾äòᩘðœuÂ]ý1ö‘S¯\U—2ê¾Ò¢ç¡wïKõ'²¶sev#g_\oT%!c`K—!@?„öàÜèõc²‡¼¯ëFœ):cSL—lä'zÉÖK¹„ÝÁ¹»Ä± øg`[gö¹¾™H*)­|ÆfÜìxb€ÑËá³g±ÝËnµA¢Ò0Gr". ”zE€Vš87Z°fÊ.?5CÅ]äò-\mõ³ºIêöå@²*òôëT¤®ŽN*ŠS~’L°ïŽ'ª'ZOÛ±€FÏÛW"¨2¤w¿ü·¯‰™¨Ò ¯ âÇX ÀÙH‘!“Ù)ÛÑsöe½Kfg C¤¹ÔÏÒ*б¾;fþÚœ’0¼Íš WÖña”–›®!¸j¤Êq†xõºû_œk1GGÝ¢r~ì‘5ÀY@RÐs²IšÂ”®•~„,Kî…#öñê±Û¬؉>» O6ÑûfÀÕjçüðòE|»»|°ÒF€„ìDyÛ•´øw›ËÄÌy¾µ‹‰]’ÇÒ¿M?;šu^ôõñ²l½ˆ Ñßòês+z•z~K²Ç˳§Ü/È]WѲ>"ÁÌJ½²Ð–‘»çæÿnþÔ£Ÿ*p¢ž )ùy$qi•kÉßü(ªBdJ”UuÐÓ‹S}¯kÑ}|ÂPMûó¬}¤øìE'¸qkò™&ŸáSgRTú=Jè=]£\ó³ÑmÉhiýýB¡êþE‚_ûª”òã]ÃDÑ[mQÉÍÍÓ͆µú²‡Q[þ ©"_WüèÈ—Õ%w˜XBçÙÆ¡_¯õ(è@¦ø—¹LüUâs¹[Š”«ß ö2£̪…mo÷C½CŽ9{_™´ãËUf'Šfvö"ñ~5ÅÒt·>Ø|>"µ¹–r`¡ƒ4rxÕ´Ð ¿š®äã~Gä·ÂKÖ…" qLŒqêq!±o„€‡h>}SG?ç^jþ¤XÀš}£­,гñmHC×m=u¤•Yp bî¸ãŒaèr£Ií:ûØI)¡Ž¬ª·)ñ«Ï™ª¹«z@gUÑ` jWî`Á– þ÷~6˜I³41Å…§f–4 ‡K¾<“³ìŽi˜;Ä÷Rô@9æx;…£ÎPb¦››@dðˆdß~£ï³ÍѾÉ4•0mîw+kC-1×[Gûj­éJ¥ivª_2ªø ãìôfñœª{žoiö<æQÌoªZÆ”²…]×öƒç¹3¬M_(DX™ïã5¸Z΢1_PUI„µ°«Þï¸Ã»Þàw¯–€³¸wSË鑊J®¦ô*ø×ßi*Š3û4î[m¿y5–mð:mè]û˜Ý FI ¹»¨¤£Ã¯NRÁ5"Å›·É&ò~â˜0–ý¹ŸQ¦Öy–Å9ferRãó™ÖžF!í\S2Á/ ÕÑÍËU¾QzŽÆ¿ê\§0•okö}“«f»…1õî´ÐÑÉi8âHõØÚ¢¹@ùz0ºþÛ¾&-ˆÈÔÊKîPêQaÞPÀ,„nJzhO´HL‘½Œ9½Gîåp(òW1^êw‰9]1¾¥®{òõž9ÇDÁ­¥Ü¢…rç’þX[ å5P¿ì[eÚ¬vR_Ž™êØ;À£ØúéÆ õDµýï®U âàV;mWâX«üT¾·¢íüŠÚ¯í^Ó'¿¸„dé¹+ŽC”–9¤D¢ÓF-¢_º †5ùÔd£*ý©ÎÖRwãù=)ØŸi[eýp—Ä’½œòmˆ(ò9£‡HzWsîÍõeVìBE9þÔ ÙX‚­¹¦ô“Ü£âA¯âÓYW Ïr]Ü€i€Ä –ÿèh—‘Ð~ôdŽI [éð­§Ÿ„Ëf›'›†6e¶ÆaÔŒpŒù®ïÏšµŸ©-_?üö(–\¤ÏKˆöb-x&èé+CëXD×ì©‘Õä³§~J± MN§]­Lµá^AÚ…xüOT…á^8ȹqf¿Žºî]ÑÎU”XxµV§#Æky`—©Ò±EÞ;Ë~ Jn_R I_°+€]+佄C¹˜ ³Û¨ÝIÞ®€ öeõdÈÈìgc}VÀ×ÖlPZûõ„©Ö¤6ÝÕØr}À9‰ë~t7}0»+”Úãõµµßµr­a2•VסÛ'–> stream xÚmTMo£0½ó+¼‡Jí!m0U ó!å°mÕT«½¦àt‘Húï×o†4ÛU ÇøÍÌ󳙫ÛYZw/nÞJñä†îÔWn–ý܃««¼«N׎÷ÎÕ®>¯wâ±ïª­Åu¶É7m3Þxò¦­ÞNµ;³¾'Y÷Ú´ úˆëg÷{6jö>úÙ;A òs3¾yÒ·ëÂÅ×  ¤_®š®½êVJéE[gÝÛ‚ù$EÌÏâöM[÷“ñuÒ¢nªqú¢wuð~ yû1Œî°i÷]°Z‰ù“_Æþƒ4Þó‡¾v}Ó¾Šë¯ÒüÒöt<¾9È2X¯Eíö¾¢ßÿýîàÄüÛ=~rž?ŽNhúV¬«êj7w•ëwí« VR®Åª,×këÿÖbÎxÙOÔÔ0ñ/)=Vfá±Yú—–T{œ¦ÄðØ ­â@á r 0,jؘû@†@ÁŒtD˳¢êÏ®Ÿ´K¡µT—M¤Î"`ê¥ó xÁB ð’ã9pÄ8Ž976'>ï;-SŽ'À–û'ã¸ÎÉ…šJ3† ½Ê('ŒúZ%ЯÆðD³N½h¶FCf=tÂu4ôh­ˆ“1ûÕì¢&NI¨‚£C ýaιè‡æ%ö¥ã.sƨ¿,X§.‡GÿœEDœ(B˜üW14yñÓ¨‹ÏF_ÎÂðÝHqÅ('bï ÃÄ„ùî¾vÐmØ; &½xgìå&ò…ý5|6)ö` Æð"ásJ‘›,¸4%¬!Ź&¤AQ߄¶„üR¤3əߪ¿$S>›gcYˆšvú§ Ç²~ ï¬å³!ÌçG¹9ÝW™Ã»’qO ýø—1y>ÇDuê{?Ah<Ñ`ÀHhZ÷9ÁŽÝYôÐè;ÏZ|=”Á_4« endstream endobj 168 0 obj << /Type /ObjStm /N 100 /First 879 /Length 3157 /Filter /FlateDecode >> stream xÚí[koÛ¶þî_Á†˜â<(8í’ëš6I»¬Apà$JâSÇJ-¥k÷ë÷¾)Sò5nŠʈ¤xyÞç½´Xž‘Œ0-ˆ„‡a„IEG¸æP†jn—Dj¨6Q>ÑLÂÓ“ASKŒt=Á‰±ŠM,WðR«ñéˆSŽ0 cgJúy2O€ œÔB†fVÆaL£0axOÂÉ8QEbÁbÆb’rÐÌ!xø£4¢ÅAŽæ8 s1g8Ñáã=-á‰C:læ4áœaÆ.@BO$¦à†ät–{r•uŠà }µV= L¦ˆ…6F"2 ùàÔX`gÐÔC‘œeA²aNˆyf‰_q"¤Ò=THD är¦c•3‹¬WZBoã9㥞%f8ãqP¥Aù  87=JRš\H@ÆÍ Šœ­AatªH lÔCF£ÖXb3ÀÂA¡V¬®ÇAµ.S0SÄ Ð§QÀ#èèÉqñ0µø¦gGÍÀŒ,“€‹)´ „1´!hæzLbÎ TÊà5Z,$†òÓ0ShaÒ¡íÁH0 F³ƒœÄ:£0‡}-Ìj…Œe@°AÐhA÷ñø2°+ƒFŠPAm‘ÑÈ9þ46Š…%(Lac$!d0Ý{ö¬G_3F˜‘#BOÿø€¦$xÖW ÿÉÃx|Þûùgßn¯˜TäÙ3B÷$óÌù{@<T´ð¼Õ4{ߘš,ÀxôÍ´¸<Î+rFè›{„žä_*ÒLuòõ>‡Û¼GŸÃ´ù¤*Á8vïÑ£¼,¦—yéC€¯ú-¿ w‹/ä +4X«qü¦N¡¯çÞ·L& uæc béLéß÷èn1½Ê§~¬ìœЗô9@êsœý`×} †%ïs´%ûÜ¢™g}§4´;~¸¨`Lúj4ùHÏžùèà²zLß½ÄôÃmUÝ—ÿ¡ô:¿*¦ÃÛ¢¬ò«~1½¡ãÑÅç|ZôG@@¢ª (ÎTÅÀúMßꎪæÚJí£¯>¥J™wˆoR©žW©|”JS‰Õ†Ì¨3Üt]%y_AŒX×NpÕwÀÖ£Yn›P¾-±6›'ÖnM¬ÛX·±í6Rñ~ñïÉ{³´rŽ=Ë7cÏê.{°Øˆ½V»%ìuÚ(Æúæ)ÙÓ~û&öÜ<{fköì†ìÙ3°U€pǶ`f&7ÜÕ«þ·0ãÄ3ŽmËŒã›1Ój( “kÛI`PêoÞÌ–ý§_=œ™§SmM§ÞNÝŽø–õa—µM-ù7âlKfà`1όےñ¯a¦Ýnqë¶ÑÂõµQkÛ)¥ÁåÚvp\è+ÃÿñõNt]à1k[Èõ X(ä¶è›G¿™ùà‰¦½ÓÆÃ$bÁ³äòwØ-¿]^¼g¾ÐlÀ…é8Ð(™ÁÆÛà‰¼o¸KÉú’9h7ðtº_œˆüáÄì«ÉlCýD ¤Â1y†AX´Ö 1 †Ù†.Æ:na³~&7Û=Áq·«#Ñjƒ93T}&Pp¦ðÀþozŠô4lâ(þ$–£-$îóBà¯fu=& ec¬¯ ë1 sU·Ç'‡6±ÏºÇÁ1bÂzÇ1D°:Á’öÓ”1Éビ4¾‡0ïñ¥mãÓÏïcÙ·Ãz¨Ã$¬ÿ…Ë?%ŸÉ1âñ™Ê†yL±Þ„¾-ù`Ì8~1âÒ¿ÞðyMà¿ÑmL,óaÏÿÖÔ«ƒùxƒ©qÌ®u…¿ÓnéŽBv<˜7˜RjòÑÌ£{ÿo0û÷fÝ!¸NêVÆy¬÷¸ƒ\R»™ì‰[Ägê6 ö7 äŽSNR7 .Ù‡Ö6ÌàgRª­8›Pß@ë[£ŽÑ$ŒN"kèk¨BU ATË‹ƒ&ïZ±ÛU¤ãxAÒASþ•eíð=ÿá™Ö7}BÞ†¼JìÙ÷Á•¼›ç¿Ñdèµ.5´YÙ$ÙAp’-¤ófž4X7´!M¡]Ó/ä]¬±¾ÍšlXˆÖž>EXüG„DVϰÓ,D!yÕâOµg±ýSãFÎbFð;žÆÁʦî_†2ÜôóxS~2ØHζá¸q}‘——ÓÑ}ULëìëá¼y»ÿÛÁÑÁO'ùéþ×i~O‹rg·_A›ñð¦$²n¼ëÏ%;J0²ƒß͘À¯4 — :(/ñ|Ûs8è ïòÑÍm(âœøn‡3×£/«áxt9˜ÜŒs’Á¡ ÊïÞÃf²§¡“ÂÂóÛáwÉ?ÐÝ¥Ïé ú Ý÷§„_é+ú}MézDé =¥CzA/éeqw7¤W4§~ zM¯GðïsN¯á˜Eoè-½ýz›Oèˆ~¤czG't2šä´ ü½§÷xÈç×U›úQîó騸¢Ÿè”–´Ì?C÷rô…V´ºæ9­þ,è}˜ÀY¦¼,¦9ýLÿ¤_èWúý ˆü±¦noârnÒ£ç:­¼{û~wÿݼVj—èFFÝà)ÐHu£ÚºQ«t³ÃøL;b©vŽ€û¸ôÖL•ÈI[n÷¹¯N÷_·å>ÊoÆÃé¡aüÎ)ð# M„öpgBc1Ú.1H—JÌeKâ–h‚=F´ƒÁþ›çƒ(ÚI>½ËWzšÕ MºªnKÑÏ·hý=_sR¼›§W9YâJ«À®=–t ‹¬ Yê2®™ dõ] ¯>Qtñò.^˼6a˜}†Wº`å#ìA~´k6Ø]Àº ˜é¥€Åw¼zƒØÅ»ÎáX‚—}¼Ý-Z¡œó/–±–ƒ™bö€:Ûª.ž9ÿ¢ÅXêïü à,]á»Àæ|E¨e<1÷ÿà¢åXjðÙ9S3]Ä\.87áU„ï"<à¶fv¯@†Ù]ÁJî*±p3‚ñð¬íÀßYêgm{çÛLÁê"l¶Â3Ü‘ŽkãÕÏp£q»9Â}¾x{-ÞÁŠ—Œâõ–pdÕlÙáÎÀʾ®”*k¶ÀáC5†}Pl‚„`‚Aâ%ÀzÞtÁ!€¸àå/6Øcyš&móð=Ãåì)Z=UÒϲyìhÜÒŽ:¼zWì‚éãZEµF‰=ý0F,è)›žlaO?§1 z6di³¹2)r–xjDS«%LÔ²ÓÑ‹nØÕvSµèôê†^åöôÀôJUC©RËÅé(./ ©Å ,¯ù_D±¥SÉTj>T£¹\!´…Q{øUE@ endstream endobj 262 0 obj << /Producer (pdfTeX-1.40.25) /Author(\376\377\000M\000I\000T)/Title(\376\377\000K\000e\000r\000b\000e\000r\000o\000s\000\040\000P\000l\000u\000g\000i\000n\000\040\000M\000o\000d\000u\000l\000e\000\040\000D\000e\000v\000e\000l\000o\000p\000e\000r\000\040\000G\000u\000i\000d\000e)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20250820154602-04'00') /ModDate (D:20250820154602-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) kpathsea version 6.3.5) >> endobj 248 0 obj << /Type /ObjStm /N 24 /First 187 /Length 777 /Filter /FlateDecode >> stream xÚ•VMkÜ0½ï¯˜c6®4ú°ËBH(”¦IiÚSÈÁIÄÖ°_ìzKûï;ÒÚîx%zëiæÍó“lI %TRSP€R:À’‚e(HÐ(@ Æ8p`…š°Îj… ùœ.)J‰A¨)èÀR4HSJz0Äh©Ÿ± ÉEhn&hˆE˜" ‚-U*ê‚–*U!&óùdö½nVˆ]À·Éì´:=}­ö~Ó€iG{ÿ+¼dÜûß ½E,œ;åFYÈ$ÆbRUö,fœEq™aÑ=‹eAÇXZaCѱ`1Îb8‹JY°wÇÝEî.fÜÅÞ]9î®äîbÆ]Ù»+ÇÝå¶`Æ\Ù›+‡æfdËÞ¬ƒ±G§úc½?4á㈣»Š n¶G*º’CòƸQsJÇÙ#/ÍÜtì÷ÕÚàéâvûzõØTûf .ÂŧƯ?È)Ù'€@¨¨ðú³Ú5~ËN©Ý|&MõºnÎÚ²¼çsu»jé#§j9O€ Ä Ž„§9ôº’#$rDÄžkëšöI#² UKÎZj‹4× ƒg i-,…ÊK2Ó>)/©ÅÜ©’€R2ÀÀ0  ÆÔQíºükSo7—ñÕN¿­D5åy‰²~ŽÜ(Ëï|N1Z_¢”Úm@†’2c”zÙD.W2LfiÍJ‘4 µ(õ9\J´Ämw†—”‡ 5&ºU2È~G5m#•xE+¥y´Et"¶‰îä_˜„Óž›Á0eŸ|;Í•¤ïp–BžÚ¬˜Ÿ¢ª"ù°3Ô™Â^Ñçúªðtˆ·–S”mÄ6ª6¾û“Ë®[ÛÁ˜–Áþ{9­¦h™ÊwµŒóÜú¥‡?æþì<Ìnª¦Zm—áZÒJaw£z86«z‘îLŠK‰VtGÖÒÙ¾ùÙƒï’#xW½øÕa>ŸÝׇ'A³ÛÅãÃ~±ÐòLBf;¿¹ŽªÁõ'ö_F§f endstream endobj 263 0 obj << /Type /XRef /Index [0 264] /Size 264 /W [1 3 1] /Root 261 0 R /Info 262 0 R /ID [<45C0D67941E48A8A131287F6495426AD> <45C0D67941E48A8A131287F6495426AD>] /Length 647 /Filter /FlateDecode >> stream xÚ%”ÉoQ†ÏùnE• EÕPTÕy¢(­©Uõ3¬„½XúlDìDbÈñHl؈•DboacaK"wÇïy»yrÞsî½ßÞýs³:+Ì’¹ p I”ö#ûÀ"²]némù«ÆË¨yZFíW¿Ç­¾MQ7ÓNƒp‘ÜAÐëÖ°¨!‡@?8 Ž€£à8N€p ‚!0 FÀ(ã` ô•¿ñAߘ“ìà,8‡dWiÚ­qTCNfÜš’rg3Ò0ëÖr_…ó`èDº«9·Öçª^â̈YäU°¸¿ šôZKnÝšÁ£‹ÆRoŽB+¹u/k¦‰y/þþ@> Œ…ÛÄ rø9dïj·¹Êé¯À»QëVjVNn—EëÝîé— ¬ü!O6º=ü¥‚l‹á¢ÕíÑ'ådQÌmn?+‡ÿB~iw{VR¯Eèt{Ù«ö‰Ð °@t»½Òí î>è1 0HðFK—. \¸$pIà’À%1èöú½Ör¯ø­hØ}`åD#îwMѨû÷'ŠÆ¼XêW4îÅ»1E^|\9Û¤?§Myñç‹"ž6 $(ARCHIVEPREFIX)docs-$(FMT).tar.gz bz2: tar bzip2 -9 -k $(ARCHIVEPREFIX)docs-$(FMT).tar xz: tar xz -9 -k $(ARCHIVEPREFIX)docs-$(FMT).tar clean: rm -f *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla *.ps *.tar *.tar.gz *.tar.bz2 *.tar.xz $(ALLPDF) $(ALLDVI) $(ALLXDV) *.fls *.fdb_latexmk .PHONY: all all-pdf all-dvi all-ps clean zip tar gz bz2 xz .PHONY: FORCE_MAKEkrb5-1.22.1/doc/pdf/LICRcyr2utf8.xdy0000664000175000017500000001041614577122106016555 0ustar ghudsonghudson;; -*- coding: utf-8; mode: Lisp; -*- ;; style file for xindy ;; filename: LICRcyr2utf8.xdy ;; description: style file for xindy which maps back LaTeX Internal ;; Character Representation of Cyrillic to utf-8 ;; usage: for use with pdflatex produced .idx files. ;; Contributed by the Sphinx team, July 2018. (merge-rule "\IeC {\'\CYRG }" "Ѓ" :string) (merge-rule "\IeC {\'\CYRK }" "ÐŒ" :string) (merge-rule "\IeC {\'\cyrg }" "Ñ“" :string) (merge-rule "\IeC {\'\cyrk }" "Ñœ" :string) (merge-rule "\IeC {\CYRA }" "Ð" :string) (merge-rule "\IeC {\CYRB }" "Б" :string) (merge-rule "\IeC {\CYRC }" "Ц" :string) (merge-rule "\IeC {\CYRCH }" "Ч" :string) (merge-rule "\IeC {\CYRD }" "Д" :string) (merge-rule "\IeC {\CYRDJE }" "Ђ" :string) (merge-rule "\IeC {\CYRDZE }" "Ð…" :string) (merge-rule "\IeC {\CYRDZHE }" "Ð" :string) (merge-rule "\IeC {\CYRE }" "Е" :string) (merge-rule "\IeC {\CYREREV }" "Э" :string) (merge-rule "\IeC {\CYRERY }" "Ы" :string) (merge-rule "\IeC {\CYRF }" "Ф" :string) (merge-rule "\IeC {\CYRG }" "Г" :string) (merge-rule "\IeC {\CYRGUP }" "Ò" :string) (merge-rule "\IeC {\CYRH }" "Ð¥" :string) (merge-rule "\IeC {\CYRHRDSN }" "Ъ" :string) (merge-rule "\IeC {\CYRI }" "И" :string) (merge-rule "\IeC {\CYRIE }" "Є" :string) (merge-rule "\IeC {\CYRII }" "І" :string) (merge-rule "\IeC {\CYRISHRT }" "Й" :string) (merge-rule "\IeC {\CYRJE }" "Ј" :string) (merge-rule "\IeC {\CYRK }" "К" :string) (merge-rule "\IeC {\CYRL }" "Л" :string) (merge-rule "\IeC {\CYRLJE }" "Љ" :string) (merge-rule "\IeC {\CYRM }" "М" :string) (merge-rule "\IeC {\CYRN }" "Ð" :string) (merge-rule "\IeC {\CYRNJE }" "Њ" :string) (merge-rule "\IeC {\CYRO }" "О" :string) (merge-rule "\IeC {\CYRP }" "П" :string) (merge-rule "\IeC {\CYRR }" "Р" :string) (merge-rule "\IeC {\CYRS }" "С" :string) (merge-rule "\IeC {\CYRSFTSN }" "Ь" :string) (merge-rule "\IeC {\CYRSH }" "Ш" :string) (merge-rule "\IeC {\CYRSHCH }" "Щ" :string) (merge-rule "\IeC {\CYRT }" "Т" :string) (merge-rule "\IeC {\CYRTSHE }" "Ћ" :string) (merge-rule "\IeC {\CYRU }" "У" :string) (merge-rule "\IeC {\CYRUSHRT }" "ÐŽ" :string) (merge-rule "\IeC {\CYRV }" "Ð’" :string) (merge-rule "\IeC {\CYRYA }" "Я" :string) (merge-rule "\IeC {\CYRYI }" "Ї" :string) (merge-rule "\IeC {\CYRYO }" "Ð" :string) (merge-rule "\IeC {\CYRYU }" "Ю" :string) (merge-rule "\IeC {\CYRZ }" "З" :string) (merge-rule "\IeC {\CYRZH }" "Ж" :string) (merge-rule "\IeC {\cyra }" "а" :string) (merge-rule "\IeC {\cyrb }" "б" :string) (merge-rule "\IeC {\cyrc }" "ц" :string) (merge-rule "\IeC {\cyrch }" "ч" :string) (merge-rule "\IeC {\cyrd }" "д" :string) (merge-rule "\IeC {\cyrdje }" "Ñ’" :string) (merge-rule "\IeC {\cyrdze }" "Ñ•" :string) (merge-rule "\IeC {\cyrdzhe }" "ÑŸ" :string) (merge-rule "\IeC {\cyre }" "е" :string) (merge-rule "\IeC {\cyrerev }" "Ñ" :string) (merge-rule "\IeC {\cyrery }" "Ñ‹" :string) (merge-rule "\IeC {\cyrf }" "Ñ„" :string) (merge-rule "\IeC {\cyrg }" "г" :string) (merge-rule "\IeC {\cyrgup }" "Ò‘" :string) (merge-rule "\IeC {\cyrh }" "Ñ…" :string) (merge-rule "\IeC {\cyrhrdsn }" "ÑŠ" :string) (merge-rule "\IeC {\cyri }" "и" :string) (merge-rule "\IeC {\cyrie }" "Ñ”" :string) (merge-rule "\IeC {\cyrii }" "Ñ–" :string) (merge-rule "\IeC {\cyrishrt }" "й" :string) (merge-rule "\IeC {\cyrje }" "ј" :string) (merge-rule "\IeC {\cyrk }" "к" :string) (merge-rule "\IeC {\cyrl }" "л" :string) (merge-rule "\IeC {\cyrlje }" "Ñ™" :string) (merge-rule "\IeC {\cyrm }" "м" :string) (merge-rule "\IeC {\cyrn }" "н" :string) (merge-rule "\IeC {\cyrnje }" "Ñš" :string) (merge-rule "\IeC {\cyro }" "о" :string) (merge-rule "\IeC {\cyrp }" "п" :string) (merge-rule "\IeC {\cyrr }" "Ñ€" :string) (merge-rule "\IeC {\cyrs }" "Ñ" :string) (merge-rule "\IeC {\cyrsftsn }" "ÑŒ" :string) (merge-rule "\IeC {\cyrsh }" "ш" :string) (merge-rule "\IeC {\cyrshch }" "щ" :string) (merge-rule "\IeC {\cyrt }" "Ñ‚" :string) (merge-rule "\IeC {\cyrtshe }" "Ñ›" :string) (merge-rule "\IeC {\cyru }" "у" :string) (merge-rule "\IeC {\cyrushrt }" "Ñž" :string) (merge-rule "\IeC {\cyrv }" "в" :string) (merge-rule "\IeC {\cyrya }" "Ñ" :string) (merge-rule "\IeC {\cyryi }" "Ñ—" :string) (merge-rule "\IeC {\cyryo }" "Ñ‘" :string) (merge-rule "\IeC {\cyryu }" "ÑŽ" :string) (merge-rule "\IeC {\cyrz }" "з" :string) (merge-rule "\IeC {\cyrzh }" "ж" :string) krb5-1.22.1/doc/pdf/user.pdf0000664000175000017500000076672715051422775015372 0ustar ghudsonghudson%PDF-1.5 %ÐÔÅØ 1 0 obj << /Length 843 /Filter /FlateDecode >> stream xÚmUMoâ0½çWx•ÚÅNÈW…œ„H¶­ Zí•&¦‹Tàп~3Ú®öz¿™yóœ87?ž×Ûö¯nÝkõâNýehܤü¹=77Uß\®;?:׺vÜ==¨ç¡oÖî¬nËUµêöç;O^uÍû¥u#ëÿ¤Â½í»O ú¨Ûû=Ù˜‰a³?¿ûkLy 6FÑæ/7œö}÷ Ì½ÖÚ–][öH<Si£¦cãݾké¥^Ñ90¡j÷ÍYVôßü¬H^œÎî°êv}0Ÿ«é‹ß<‡ÒrLŸ†Ö ûîͯ_®/Çã»Ck¥ƒÅBµnç«øy·§¦Wý×øæãèTHkÃý›¾u§ã¶qö{sÁ\ë…š×õ"p]ûϞќòº¹KÏÕµÿ u”/‚¹A² )`JbD>`´öØ2ãš™$`¤TY'`”(ZqŠÇÁ¼BJÅŒ )KÒÌŒ%553<Æ,£è(‡hþl™×wBš6„‹0¦Ða™G„+L¤gıè«cŽWÀ c œrn œqœø9çÖÀ–ã°MÜ—8%Ç àŠCMq.â†5„Sâhr›ê›®®AƒáúI‚Öå皎­ú\SåþÈ©¿ÇÀ á]8 é`Y‡7ÑŒ1OÊyeäµñÖzlÃë,d mYĸ”S£SJfß-›1i‰:C&e c4ÎRÆÄÉØˆËÄ$D&™ Ë Æ&+ü¬bLõÉãaÉjÆ çÁbôÍy°üœ£‡+çÁbèÉYB¹ü‘þœõ§Ägý ñYJõYŠYrÖŸb–œõ§x(rÖÁèœõGT“õÌ›ËÁ`F+ƒÙ­L ,C9ô²â?d+þ£¯ÿ¡ÍŠÿÄÿ1£ÿ1—ÿ¡ÓŠÿðÄŠÿ˜×ŠÿT_ü‡~+þCg!þ£o!þƒ_ˆÿàâ?ôâ?åŠÿÄÿ‰/þ?ã«„°øY ñ³â?^ŒBü‡Ÿ¿\–jò‹UPñœŠ{Åð¡âxᇻLöó^U}9pQãóq½÷›Ë0øO}cèÖÇ}¿ïÜõ3tìÈ¢}¿Æ!VOuðÊñË· endstream endobj 3 0 obj << /Type /ObjStm /N 100 /First 833 /Length 1158 /Filter /FlateDecode >> stream xÚ½XÛNG|߯8æúrú&Y–ð%ØJl"ØD±Ä‹ ›€°YëXþ{׋3;lÏÎ/ûàž™ížê:UÕ݃Šä %²¾5d“%kÉ•L–É£Ë O™ã©P2Žœ£äÝÄyÊ£#åèÉÅC^2ì=Öa°g\Ñø€Y2®‚m1/f %†Úèâ„=¦w™8â 1ð2ÈàeÆüÀ+`€Wð9“ …LΚD¡à-Eð³%O„’s…bÄMLä¼sƒ+£0÷%Pbrìñ;ð‚ñ”€@6/dÔ¼èü$/æ‚ZQªÔ ¼”àeð*ÀË1S^1†í æ…–Þ·\£È,Ú˜8±øÑÛ€ò Ô°Yºy'BˆŽ.É… 2¦ñòY8âYÄ„'ž“t9À _|ˆf½ÉCSüä¥ ÈÉ` Øã“h ¼ð·â`ês6bܱ?R‰ðºøY AŽ c0 Ø$àÀ'¶ÐÕÂ(¶,®Z˜j$;ŒxÅåZ˜Å^‚·ØCJXOŒA –Ì"4ã äáô[XÆúI<9 ˜Æ1C¸  ØÆ ð¾q–Jag†ÎpŽ‹0Ä|\„!¼ãƒ,̃çN’…‰=ì ¢2†Yø58Y`^ˆ ®ðäéSÚ;¦½ƒùtN{/éÉéù‡ëÅìf×îгg“''>EüK'Ƙߥù Í­6_¥™Ks#Í™4'†\?ëø+½ûGš™öδw±³Båvvº¸˜_íÚ™ÒœwghÀ/ºwd¾)Ñ/Êö®ïzDaëè¹UzúfKo±†^3êT›Y—Ìݨ…’SÖ=ÌvÔ°àþçÝÿW§k^ú¤Å/”÷ÝÐÿ´äõ·Þ*F+`3çÕNoz+ŽL»€—:çâ12ëj™ýµ[çÇîã¼n÷ åë.ÂuµÅø‘©u”+ª*Ñ…êÑF¸'ÌëywJüÚÅùrßee²µ’WRûg·ü¯[bݦýv5¯²~ÙÝ]‡¿m©ˆ³õ,úW_Ň?f¶²Oµ»ÓUwåw*kþ4&;¶/G,À ä—K¨5ÜÆ¯WÒëÙt$ÍÝ9§úØ,©wƒÓTc3Ã;õæP;ÞvÇM—l^ÚïrkŸKó[[à ·ŠÁÇúú«å9÷ºp8]Y Ï5@ãè…UŒ}Åh$y­ªƒŒ«¯UÄcÅm!ßB¦UÈ£nަ]¯^ÔrÔG_'ªähW×BÐõ4¿÷5@ßmg¸Þeð—ºúVÁÇGØm6Šëžèî¬÷> =;k‡¼ßŽöþÚBnRö»ã†zÜ|®|ñ œ+Ü{®üïãrI®Ÿ+MåïuªÚÇíÞ3ˆë?,\?{ÑÆ1¯Ûê0×Ï‚£ƒÓT·_|ì¾ÄõSá§÷%®e`ì×õ2=÷H!uÛ ©Û|H«Ÿï›˜«åø!sµ¤n `¾'`#þZ¦ç)`~;ó›˜ßNÀü¦æ)`ܰÞÿ»;Û™|»âÒ endstream endobj 382 0 obj << /Length 586 /Filter /FlateDecode >> stream xÚmTËŽâ0¼ç+¼$æÀà$0Š ‰Ã£­ö ‰a#A%áÀ߯«›ÀÌjDÕå²»«ífðãc;ZæÕÁŽÌ«Ÿ¶­®MfGÑÏ}í q•]/¶ìÞ­ÍmÞ¯¶o⣩²­íÄ0ZÇë²è^œx]fçkn{ÕÿE+{*ʧyÄpg6;5’PìŠîìVž¤pH8$hù—mÚ¢*ß„z•R:")󨺠ÊÖß3‰qŸûX”ysO'Hî)-ò"ëî}³‹³‹ÍÛ[ÛÙ˺s á3 4†{´¢p¿YôdšrýØëKæ‘+ˆ™ÇÞ a }ÀõàíÑ« W€‡Œ{ Fvm734…4˜‡¢´A­«»èGÞÿc Ú¤Þ_86 endstream endobj 383 0 obj << /Length 770 /Filter /FlateDecode >> stream xÚmUËn£0ÝóžE¥Î"±y$UÉ6 É¢5Õh¶)8¤"’,ú÷ãc\W³Ýsß/.7?ž·3ÑôozÆï(yѧþ2Ôz¦vÇèæ¦èëËAwçG­ÝŒÒÓ=yúz«ÏäVmŠMמåMW\=jý_Iê÷¶ó*ˆCn_õŸÙÃfö ¯íùÃ&1yØ+ü­‡SÛw÷$¾£”FÙ5ª? ÅS4¿†!ó1ð¾íšá‹¼!r3Ò´õùŠì»>˜Za¼ý<õaÓíûhµ"ó#<‡O›ËÏhþ44zh»wrû°1p{9?4B“4Z¯I£÷Æ‹©çqwÐd>å?ñ¯É»Ü=ûõó¨‰Ã±K«î}:îj=ìºw­(]“UU­#Ý5ßd¦kò¶u¥Ñ¥¥y že¥ÖÑ*†ƒx12+ƒ¹Sx¦æ,öÌÒ09Ì9Ô)5t´J N¦Š'†™™{fSÉ –2Œ¬Rà̼   KÙÀÒV i‰X¤¤†BÆRs>–^ÿÝ ×.¹¢KäCc†2—ÀÜc4‰&WÀ©o"²¦™ÇÖîq¼ð8^zlã p5u%†=c¾K(œq/‡?–xŒQ±Ôcøc™·/€s/G|¶°£•¨•-mõ„¥•鯝P/S8+8èÂÑ 4fÁR§SYZ"?.ì‚0»1Òшŕ[KŽþòÒñ­¾õÃúPKS6Ò×0ÃÔæ—eÈ;Uކ}Z8~S›gÈ;­ _™õÇàg®v»ói;K¹æÊcÄÌ g‡ÝÌ­oZ ÞÜú¦ ú¶ø’'ü êê„LÄá^ î¥àá^Š$ÜK‘†{)²p/Eî¥X„{)–á^ î¥(½ߎ‡¨> stream xÚmVMoÛ8¼ûWhÒCj~H”\HÉrhSÔÁb¯ŽÄd IJ!Û‡üûÕ¼±Ã¢ØƒõøÞ¼!9ÔÝ_?7¾?¼ÄûUe¿âép»øPßgwwÍ¡»ìãpþcûÛÛÓ·ìçxè6ñœÝ×Íã°;™‚‡îýÒÇ[Ôÿ…ø¶Rêd÷ÏñŸ‡§ï›…ˆçÝù}z“³ eÊäõßq<í÷LUJM롯{°<Íæ×JÙüVûu7ôãµ\ö‚â3m²~ׯOòßí§v1yóq:Çýãðz˜-—Ùü×ôòt?„Í—Ùüiìã¸Þ²û‰Ïô¼¹ïµ35[­²>¾Ni¦ž~l÷1›§>_\é“}~þ8ÆÌȳ&±îÐÇÓqÛÅq;¼ÅÙR©U¶lÛÕ,ýï g¼¼^Cs=…~úk*[4õ¢^Í–¥™žåO×mT·I:/nYº·ãµž1ÚLs*J`#¸lœ ne¼ÀÜ¢ì8W—Ìi+Á‹xAì€=±Ì ÄpM¼n˜?¯™SbZbÄhòÏ`-؃6‚+ÔÒ–µtΘ¸ 7 þÆûXøû €ÉßB[Mþ98hò¯ ›&ÿ ýjòwÐJ7Äà¯É¿”qò/1n„¿^ –ÑÄÈi 1z1–ùMN þ¦ F_ƃ›¡þ¹Ä ÝHþ±ä÷Ä’?K|M,ù愆fý[þ«þÐÜ e‘ÓRÿ©Õ S…xKýúµÂ¿¨e¹‚ä‘ýc­Ä íQ×Rþ–ú+™ëe¿y¬‹¥þ ëhÉ_Ë8ùkôh©¿G_–ü=âsêoSsƒ¹9µµ¨›S[‹<9õ”^rê©%æZ:ä¬kÁ³`Nø‚<åÜ'{¸à>© [AžkZ§&ŽûÜ#¿£Îùä· 9%F-—ËÜ‚µÏ©ì=WC'}•k‰_K—óRV³ᯌÔõÄèQàV ç$¾!–6n/xzjgÿu › endstream endobj 385 0 obj << /Length 1026 /Filter /FlateDecode >> stream xÚm–KoÛ0 ÇïþÞ¡@wÈbK²EÉ ‡=°î©­v;p’C¿ýLÒ2­b‡ü™z”é¿n>ý|ܘnxvù%‰¹óp[·)¿íOÑÍM5´×£ë/ßë\ç½ç¯ñÏqhÝ%¾-ª‡þpù< ~èÛ·kçü¨ÿ²îõÐóØ'¾}r6ßê?›F<.o“‡Æ“OVŒîßn<†þkœ~I1=¨û®Žå9ÚÎ;Å[¿÷Ë¡ïÆy»ø6Rw‡ö2þ·Ç)]˜üø~¾¸ãCÿ2Dwwñö×ä<_ÆwŒæs´ý1vn<ô¯ñíÏÄ×ÓéÍÁÞqÝßÇ{™–™rú¾?ºxË),Ž9|Šž?½Ÿ\LœR`íйóiߺqß¿ºè.Iî㻦¹\ß}𥹢9Ï/íßý8Öß5õdNœžrf=KâʳšXÈÄxΈ—ñ9ñ²¾&^Ößázz_/ë¯ëe¾%^æ—ÀI%À®Ð®s°k°‹f™×ûyé*ïx•7²`?¬Jö#+® rÆuAι.Ț낼㺠\dÃuA¶\är® ØÕ\°Wyã¸UÞÀb•·^å¼:oäÕy#¯ÎyuÞÈ«óF^7ò꼑Wçl8/a9/Qr^8®â¼WyÃù‰†Þ…lf™`…;%»[ mpŒ$[MyX[RŽÞ+Iù¨¥¤ÜL6§Ñ`ÓYÜË 9HKvvI6ä)+²K°k² Ø Ù§šã‡¹Šâ7ð+Š¿€¹Šâ/°×Qe\G…ñ›$Ÿû@if¨Â<„¨½¿`F¿¡ñ‰÷[fô—Ä©÷WÌ诉…÷7ÌàÏ0O‘úùæ*’Ƴ xü÷"ÜE)=+b¿~–ÑúÊsN~¦‰—ýv¼?ÆSðþȆ÷G¶¼?rÉû#W¼?rÍû#7¼?p>çïãËSfôcÊ¥~¹dF¿b†w4ψ}}òœÇkf¿ãþGÁýl¸ÿ‘-÷?rÉý\qÿ#×ÜÿÈ ÷?°žó÷z¢Sfô fˆWKfèUM}k¡5õ­…ÐsßBohÍ:¡çï0οÁÐÿšò¬ ÷4}{ÆCùU¸NµzŽçšVcC6¬¹û ¯&á9&ýà¡öj¯Q¡öš,Ô^“‡Úkt¨½fj¯)Bí5&Ô^S…ÚkêP{MÃÚk®©MCíµ"Ô^+Cíµ*Ô^›…ÚkóP{­µ×îBíµE¨½Ö„Úkm¨½¶ µ×V¡öÚ:Ô^Ûð·µLøÛZ¦¡ö–"ÔÞR†Ú[ªå=™njó îlpÅ\®†íu§[#ÞCñW¿Cï–«êi8Á,üá×ß™~4Ñ?„ãªs endstream endobj 387 0 obj << /Length 199 /Filter /FlateDecode >> stream xÚe1OÃ@ …÷ûoL†Û¹ø.k%¨ZÄ@9¦ªC!W„Ô ‘¨âïsm*:=Ëzß'›ñÆÂñ¿üvR’!Š Lmcx?ºÍ–Ñ—ý L]gø¹´ŽðKðâžo\óäî¼@=…ií”,´0SR H=6Õc­m•‡·<|õLC¬^Ç> stream xÚ3PHW0Ppç2ÀAc(á endstream endobj 420 0 obj << /Length 875 /Filter /FlateDecode >> stream xÚíš]sš@†ïý{ l÷{ÙÛ¦ifÒ™¤mHol.RèÆÉ¿ï®|ÁNÌ5©Ü²Gž³ï{Î*c€ÀÙ•ÛÏÞàÓW†f2A€÷0!RF Qx#0´Nln]^x§žípëʾñÎä©dú•¹¤ú¦­ƒ?Ïô‚• ÂŒàPW-‡p0ÂP`UŒmý!ë»MågÙ¦ÜJRskd;„#kæÇþØœ gaœA”_D‡M!Ò·BÕÍ^"uŸ‡È˜ ‘ä:D çåM¡‰‘êHNîüxÅã"®'›!+™§Å»ûUì£õ‡“‚úê¯ùñ6L©ÝŽÐxXXY¬òvk úò;R²;Ký8¯ÙùAfY±Ÿ'›xê+’y3݆ŽÀ=®6.Ò.ZâjÈA)¶~üsåOÅGs:4ÈýF”~%q3HŠY?åvİ)óÚTcÀ!š+v ®¤yÏÈz¶“%9Ã3µÌÓ]È<©eþÛ2Šô6L“J"ª˜Í‰2Þû4¹_fקìùLå®þ?™G;RR‹ýåmîGq­öëøJ¦‹(¿+ö&úÒ–Ð+!{p/€c«dÿ—A…65|¶Å72£+m„¬Ÿ‚[’äo%)*’¬$ù%, ¤‰)«ž¶†9Zÿ\3ZNh¯…Oî»ee¶…w_gaYIlJ­¨Ù6ý¯aتSÃ.sÖ†=ynØMòãö^ï67%¡êÈ hmãp§‰n¸[å jÕꪜ,Xiý¤¢»€í^˜ÜÑÚƒ¼bšÞr§î"›SØí«¿]#%MSQ!Íæ­ð#®§ÞdÚdYC^Dy`Œ÷®µ.ÇYÏuŸVKÜÎðºÞÇ8iùl?m3{»«¤T‰7 ¦QØþGqUö˜¢uÂåöÔ< °ÞEI×Í­ ˜ †7Œôásƒ\¹`±¼h˜ÐI¦àjð£þg×jU„S Œ@ŒI‘ÑÚÀzÀ¿`Gf\ endstream endobj 204 0 obj << /Type /ObjStm /N 100 /First 874 /Length 1396 /Filter /FlateDecode >> stream xÚ½XÛRÛH}×WÌcò°ÖÌtÏ­ŠJ•CpB-Ìnà!!Þ„JÊNÙf7û÷{ZˆIdˈP¶‹r4—Ó§O÷Œ„¬&¥•ÕAQ@UŒÊ£Œuh­2ɠŵ•~¯l`´IæX«± Ë,)6\XËŠ=æÙ œÖÕ籆ŒòðcÉ*ï°žœò‚K^‡õ”THèg­"~–IÅ ˬ’øå ’ŽÊh8·5Œu`¨…‚sÊ çq!“]BÚ*ë5.Ü{R†Œ.¬g\óA62d È|m²‡,6Ù³ 9B€4¢(‡`m„öP Š:ݽ†eHôˆðU …l²1º“„D2ä%$鑨‰zÞZ\9¯ Ò9Fpb™…нME´’+þIX2È©d,IÊ´äK~I!+½š á„yG$–¡ˆB„K$7„H‘¯ ~©2ŠX†9b€;EΚ‚ 9(A‚¼øAÉLDò(HÕ!ƒ¨!YÐhd QD) yd n’O!ƒ¬%Àp!È #€)F©L«¸ d©)I9“*Bb‹bÃ3.j _ìDäŒüÀ3ªZ€Ö CL2è´!œ<%”¾äAìXÂEN‹Tìì¨òT•/'É*_¨'³›³ÑÕüz2î1þÌSõìYñä$ñ ZëS1oÅŠ9sœö««§]¸v÷…˜½ ´+æ$CV†ù¶òzØé†–Ý­D{s^†ÜËËÿÌ'MÜ×ÍyÃN7n…ð{Ù\hÖÒöÅä G-зõ‹˜©˜bœ˜ßÄ\‰™ˆ‹ù[̵˜Oä݆ªÆm§jÜú«Æ­¬š79ƒ¯³‡ƒ!uân¦LüŠ2™‰¹é å7”~ß–þ“çbΚûo¯më=Ìm£Ô|[]ôs Ú«úûÙÿQ^Ýü5#|÷x‡þ¾òßËÑœ­Ú`wE\õ ~îYШÑÝÏü_æ ßg6W»ã 3˜°Ìn³äD:Ì›ñîæ0¯ûk‰Ü‚6?’1ÌênþnS²aSäagXqݧžï¥eÈ‚œ6ótM¿« Ú0N²F»çkôŠ“k¿¹ÿïˆìår4“õÀCƘ_݈«7Âï™ìY·_»—ø¡<žÂ}§ó{Ê<¿Å|î`6ôÈ Ûyc ëc ÛyÏ m¢Aø›Ph{Ĭ¡ÔâŠRû'¿O:˜Å ÕVÜNmÅõ×VÜNmÅuÕVÜPmµ<gùÈúš±Q.µyÑ´¡RKÛ)µÔVj믋ÔV~Mç¹|¢ÑêD•ƒëù¥Àîìåð¿o#U¿ÿ4*ÊÝÉx>ÏgŠb™Ey2šMn¦W£Yõ5§êz=úxýþùä»:×èðƪìeˆ)Ö*J•“¢†ÿÙí›·ïTÀt«Õøæë×Ë»9¸UBvÀ~RMR¾7%]Ý`by<\Žæêl_ T9}Ÿ«ŒÑFâ¥0’}L ÎïwËV/ºeÉmÙ'€:¯¾‰òì¶ uëöV/ùwÛšºµuKuËuëêÖ×m¨ÛX·5ž©ñLgjšÖÌZXÀk⨜u='Ÿ­íèáÿsleq·‰Í&xê¹ês¿éY5,÷8Q»~Úô> stream xÚ3PHW0Ppç2@£ ¹ ´‚¡‚¹‘‚©‰ž‘™¹Br.Wt¬B PØKÁ@ÏØÒB¡¬(WÁÄÌHç(sr9…pé»™*XêYš™)„¤Œ01Ò344RIQˆÖÈÌÔŒ ñ‚[åÂOz endstream endobj 434 0 obj << /Length 2439 /Filter /FlateDecode >> stream xÚíÛrÛ¸õÝ_Á—N©™ŠÅ… ÅL_Ò]¯›ÝÙ$›h¦ÓIö!!‰c^’ZÕßspÀ«×N'íØ&pœÎ ˜³u˜suÁì÷ã‡/s¸ 'äÌS2p’ââÝïÌIþ³Ã¼( œ£™U8~°‚oî¼½øíâïë‹¿þäs'ò¢@Îzãø÷VŒ;A$<Δ³Nwî‹¥rÿñüõúòÍâ÷õÏf ÷=é×ðÐãœ;K!½¾fÉ«——8õâr=e0P¡Jÿ¾ ލI?ò¸\9—žOÄ^/å>ûvÁ•ûÏ…`î«7?.–"\¹¿>¹€¡…TîÕ寗/×Ä?,D†‰¡Á¸DÞVç¿ ¾[j@Ä…»›æˆhª:Eˆt³†FÚ¦FUæ ¡Ü>b;^HFáþ‚Œéúƒ®+»rÛFµ¡5 ™›mn²rKã7 Ÿ ¬d©.Û¬½Y„ÊõK)¸ûbCCMU誴ü¼gÒ/KC{ßX´¿ˆ·»¸%–öºnªµ{²äÜ‹”5Š$.‘¸p‹¸ùÊrºŽSM0”L ÙQzÏDÐè2¥A]ÄYNM"„­X·‹6uUÐ.®$4j§¶©Ó¬5M\ÓÜTçºÕ“uv‘ëf6?¯¶ÔÈʶ¢V{iGw°I`M­e ä9£‚‘t1 ‡WVø ]Ú³<§Ö ‰?äš&µAZÝÍ!k‚FšÛR׺L4ì²Ï÷'´ dß,Ý„™ Ø"ܹ•r³–€4ºY±7+@”¸l;±mYhj‚ïªªéØ¤Ï¶ª¬hSC9£RBÄÝkcëz=F<´ÑI­[F)2Y,@§ÔÚb0šµÛŒœ‚ q’覙Î3ͨe;žÂGnóuÞh46£mì©EÜØÕí®®Ûuf^ ÷L±Fkí˜'/O†>ü÷WSC>¾¹‚¨²Q š)òª6ÑÜÜ„D½äÐnÑÛ*jß঑ô4ËHox±ùaí¸Xy‚c„5”€{ŽA„¯úˆG¨š]uÈSjƒê€QtRÅzýCo'q¦åÔ+»Ý*q÷Á÷’üöRNq57H–üPKZdeF°:nÁ¶aã²m¢ÊA‰¥èy0òAñð0Ô mr‹Xd‡r@åInȦÖ6$–­M ¡PfÀtëYrÈ¡ Õ'Ž9mVLIZð.+¯-«½mK ÅýZ :tvÏhÚ¬›ޤCU(=¥”çÐS)Mà‡à¥¥¤“Œz°$ŒàÏ,ï¡ç« ŒŒáÊN(ö Pö¼#ØCØ€Ž äèH˜ÍºùöÃŒdÉÿ½|ç7Œb7 |®z‹€™Lhîi yaÕå{>'Œ¾”éõÕH_]/TVѶx‚“û€+\È@‡´3Ö ªÁ.C…ÜUŸãG'†ývª\‘ÇÌ%F$=†¼tù0 !(AEž/lŒnvX“wû¨íîŸaf1µŠû§IŠÆâ‚Û({σÙkéëdX@ 04&ªäø:'aú2aCsT"L¤`-BL‚á³{y*±¿Í*Å;©eyN-k“{°uc+¶L™ýT1w¢2-baËCð5Uøeije²ëqJë{SÆ ƒ_  öI5`NÆo¼³ò^*€Õ×QIµç50°úÊfNh'X÷éÔõ‘3§ß‹˜åýÅæLÕ-&ïWôØ"mRèÀá}T§¬êÊ¢ù­"€ºu³ŠUí«¢\覉iÅ—U°%˜µ»¬RüLÙ¡ä¼ìPþIÙу0±ö>½ö6 c¹Ç*«¾WùîTV­¿¬R|RV)1/«”?"ÒÎX/¨Ñ•U€ï»(«À½Ôê“Uàó˜àOUÕ·È¢&ŽS”ËîÌ3¢2Í®/Ÿ¹7Ü ôgõ]–ëÛvG‚/ ÷h[ÝÒ•;±’µYœ[eeɵ¶÷UŽq+)#‹‡}7Ùo¸ÆTØ_·`/¶@{7>+û»Š1˜‹®.á{˜¤ÞþZižÇgóš¸è3úøÇNœƒ·D6íwŽH3é×°îŠñD¨¶»M¡_A-:Ìøð¨?&çƒkya>]¥<]¥<]¥<|Îç,ð8ÝTžMúDR"|Júß"éÿïܤ|‹k„»;x‹\õ5Ó'Í6|hÒ~õk¥Û*?¨\ЏMvŸ_øqop¹»~ýt|ZÔ~c¹±Úƒ³„ÝÇ«ö^•‰yÂ5. sòóÉK®Ó;¾¢Ÿða¨+ê⯫„Á¾0àlôR‚wEÞ'¨š" éÕÕÞ–f­îÖueÆH¦/9Ì“ æþ¨÷º´o?ð×ù’ïèÆç–÷VÈ¢ÏOŸ‡ø‚ž=ᘹOòñGaT„/»÷R0VdÛ5/²|Þ½¹8ÚŸzýþwf£Ï†~±´…1Ì(²òÐj‹ÓhÄ77L×siŠÓ«”•øsû†††Ý…qûôi„k¸óù¨&÷gO Çv5m §j„óÇ–XéÜí5¨’PÜñ…ǹ}ÁçÿÔÈJ endstream endobj 443 0 obj << /Length 2165 /Filter /FlateDecode >> stream xÚÝ]sÛ6òÝ¿‚oGÍØ<€àgŸšk\7í¥ieæ:i` ²x¡H…¤âñ¿¿]ì‚)Mêæ®/çX.ö{ Xî®þ±¾úû·‰ ʨÌâ,Xoƒ<ò¤ˆ’RëMð>üa§¡éïMß «›8/Âwƒéivw¬7æšæ¿˜ÆèÁÐBFqÉÕïëï¯n×W¯$0$âI”‹<¨öWïÁàß"Reo:3´(ËßV ÈOhŒòá¢(úu×uKê>ÞH•iÊ–²¤ e³áIk"ë-gnI°²ˆâL¡s2ôðá øË…L"•d1ºx©"*cb0§û§éïoR!Â;Ð4 u;’Ÿ ÆtU™Cr\IP‚æOhòauÇvœ ±$8‰SI"[?‰)p‘ƒ¯Ì†ÀcGãCý }ah5t{F$äI2½éhR·Êý@“ èX™ùÌ‹°Ò-M6ãFÆ]ßvüÁ>%*Sy¬Ç]wYÓ4d<\ìXðƒé‡®EIFv8‰§Î:‹Uø¶Þ\V÷ê7z4„®iøM¨¤aP¥›ŒhktqžÀoRdäý%ÐFW.?¢2Á%$Ë¥CÔíæµˆMÊNÞXPÂÖ±pHöœI+äõxæÙ«—פʡ·m³qZêñ¤¯¢îV;ͳ–‚Ï®>¤¶û Ð:êå ÆæG¤ao†ô `6eî¯pŸK©–•“xÔâlwͲ¶±Wi —2m½ÅXïyãà]\¬JVoöœÎ4ÓmùRTl{Ûy?+.¢Ï™ì†ôÿr“½hð®g/ƒ¥&\r`¶Óh«R†Û#f‚& ⎎FO°×g»Ñ†ti_ h­>=®ÔձюO7]JT=Œ#´£²õö’ž)K/ÞL=\Jça§{ã¢ÕDOÉ­~*üøí[O^O‰Á9À6ƒ¾ÁЬíFWl=Ã@¸˜2^ ›‡Í§º1ö1møk#a^ÏTœóÁ`v™Ùb Pû$ktàI“îo²Œ½8\®é¶;0ª&¤á 5#oš=Úìë¶&\ 1 \ñ•v¡3Û ó<ŽLºÞÒ×Ö`tjwÏÒ&9)á/FA¥ú~ªÅ[çØ)«çN;yüÕK.ã¬èžG:W”ˆYjmÈiüöõƦI!AãýÞæÌõáÐÔ•k 6ˆóÖ;[À¦k:n¡ÁËXº&IGè;Rņ“³O8[à†¤ékÌ\.Ïx”fY×o^¾™¡/ÿ­’& Ú³ÿ«rñß>IIÉüb> stream xÚ•ZI—Û6¾÷¯àm¨÷,H\æÖãqÇÏqÆ£y9xr Dv ±D*$åNÿûT¡ àªûÒ±jýªŠlá=zÂ{{'ø÷»~…zi䥡”L¼ÃùîóoÂ+aþ'OyžxOf×Ù‹“ ~OÞîþ}÷ÏÝÝ߈C/ò$J¼Ýƒça‰ÐKò(…òv¥÷Ù½Ù*ÿÇû_vo>m~ÛýdŽ„q ã$Â30LTæm#äaHGv›m¤ü_7‘ð?â™»7»)§‰JƒTÆßËéèZ™‰@f±—„2ˆùÖw¯ß¿Á«ÓÌÿpÿóFù÷©ü·o>¼ùyG¬Ël$íVŠÌÐØ"7SùX#់z#…ÿ OIîwϨۄÊï«s÷ ÷(ÿ=JXµûªm::¥;Ú¿¿êSÏSußШ?V485º¦—¶yÜlCá·Å™©uIÛž7±ð›+m|D*¦Ùë^ýÅÜßóÝŵoÎ,§nfÖŸŽU=§G?ᆠyøŠ`$ z–¡ÿáÝŽN¶Õ¡9Ÿ«ºì,Ý¢Ÿ°3¾àrÒÝ;/Mß ÈÌÛñŽ›¢­¨jâ}EkB­Ñ6×Ç#Í>éþèB…Â!ñ¿:+âÇÒžC©»¶•ñß"—i’›Y­Ž«Ó…FU- …%~ÔKÇâr=´ÁNZ2EYÚ“•7DÐ*i ã,ñZ€çÅä§·c©A„ §U}1V€‹Z” A±Ÿé†û‚É$*²§Ñþˆ¨ûmeA*Ò© Œ‰Û5 ý  ¹ö´ô?!ã“Ñh#~ ¿,u¯›ÚEA¢Œï%‘¯ˆÀ§¬eaðØèú‘6Ø{÷¼dl3µÌ>´ÍyB°¥ùsAP£k{ÜäpBI}¨cêÊ.îP‹`@1mº–ëHwíˆç…ï_˜úYw(à p®9ÄŒ‡`‚(L„:Å i8ò´Á×Ûц6;0¤A-£÷Eà17 ¯^ ¾íšçîÐVàÌF×AšFœ"ØÙ…j|4˜8¡Bp?pïD¢{'!yû|Òxû4iƒ¶eä)jŒ)Ýï¦ï}Þ*!˜Ô8 gF?Pµ|A%W ñÞ²G ¿ZÀ*DP®˜×˜®â¼c_)›rº¹v4ëîPt‡™dE+1Qµ–Ëa’Ó'Ñ`µ8—Mƒ\Jâì B²u2Ï68£wšêT7®õ ÜrÈó°1þà ÕVûSµR5)(SwîÕ=¥3¸‹<yÿ¯×4 Q`¡s­FÌÆ«78W€FJpRD,5€”{Ô½%Ó?¡‚šö o,˶ê:fN³†êê“l°g Òñ}ÑUŒš¡@馘ИDÙ˜ÈW+£,Ú6Ãäñ܇"Ç çœnêIsd Pv€2±ì@Ô½}#Uf’&!ìl«?0\5»¥ÝTÐÏ¥è:VUI2‚f|~¾…)Í·(K¡ æù.ó‚« ä 8_NÕ+FGƒa!1!žx;›6¢b. _T­ðwoñ®=@ÒêhÄöp+ a<-Ü_ 5—9@N ÛÍõT29vÓ«ÁMçLŒ,ç‚ WtÅòf`35óÝÌù.=ôÏâa» ÆKÑ rþE¦G‚s‡Bºµ¥ å¯o؆§ãP/#‹ ýÎØë¬\¶…aËf¶dm«‰ÒXŽš™’ N3ÔArE´AÁí‡uÍŒk¦È†0€TUô•m†èg0Ý¢kâ:Ò¿6Ü’ñÑ|qA‹;7ÍD;דq…8Ã^)òüäð%@šAoœ8I{ @P#ÖS1*e_Ü”ËÒ¿çþÖŸTPJæñ¬\\ËLC*s‰ÏÖ´ UÌ•íÔVÔ¯(kOµ®wKÑɬŒ’- S8áEܼMÓ¦£o@ñ›nèÜÁZν_±iÈ¡¿+6ÈßúF"#ÐxnO,”#U•"ö;}Ö'Ê[–‚’!ü¼à¥pr•j̈́ȰKóÊ"7 ×t\6}ÕKšùè ¢NOÆäÂÞV"öôϼü`ïf*‡“†uôÈ0óÿ‹úªOš Ç„r#VáÔ/‘§L¾$z­hŽ/^ì§sJ!pª8êÄ-A¹Ô%l3‚µ¦v½4<™ RÒŽIXè.Õ‹—ø@‹c­v „úw5“än¶ÙŒÝyœ3´µo2@Ýý+¸»PœÕ ÷)ŽýïŽæôP Oôˆ$¯¼Ç]|Ë«`=ö2!×bïy%î¢4Ñí¸1ßÔÕ\.b¯ûE­¨`ŽÇÁ€î ä7MµÂ6]_ð]˜8Ãì¶  0* ¢"Û U1¤mwNº¤3+ÂÉ­Œsÿþ¡§æÇO¸B)lOTó¡^Ÿ™þIsÃ,“e,«”PKÙþ{¾ïõ€Š¥@EH"ƒÀ±Ýǧ Á¿mb87³›"VöUUÓT[@Q¶”ĵQ.ÃGç–¸{x• hªÊ‘LüBȇUçÃêç«¡°|tœ#Î÷—Q~p™Ã}Š;ªK?ëã¾Å©ëµü¦‚hè‹æµÇÒUeQz«Ì‘"I!I³mõ{u`ÍBŽp–q¦.KõLù¿˜¯4“lˆÇÉI-_{í®Ã÷YÜnÃ)”qĨ){#XýÈPúÇðp¨'f]7›Sâ¨YÛ¢ÚWìoC =Ú¿Z6|s»Š@dù¸febµ¢MÁ5dr³¢MsþT—qéžæîH>Â.x5læ#œ,¸‚5g™u©4¶oX9Ñþ¤Ù°y­cQÒ`*¡9¨û®:=ðY®U3ÈHÝ®U§dæÿ]¡â Лýs…̳oü7%ã NB|C†ÜvÉùKW×Å endstream endobj 457 0 obj << /Length 3254 /Filter /FlateDecode >> stream xÚí[Y“ܶ~ß_Á—”9U J¬Ë²¤È’­u*)EÜ!w‡Ñ£þ}ºÑ r¸–VZ«”Ôº\²qôF÷× –{÷ŸÜ?=ùþÇPx)K#y§ç^,½8LX˜Þiî½öŸ­¤ò‹ýY±o»ÕZƉÿ[Wìééñ¡Ì‹;ôükQYWЋ`R2±zsúôäÑéÉ»̸'hòÅ<ö6õÉë7ÜËþÔã,HïR÷ª½0Jà·ò^ürÂ]Aƒd&¨àŒ1 zº-á÷?FÓK$L7N}¶Ù~%”Ÿ_¢RøÌ}”XÁË¡ßM_n²¾lšhÂfa‘fú7TvAcK4Œ ý®è‰hBF¯0ëJrÿ-þC]Bÿr DeK]öÅ;æP:€8ÔtÐFJ{NPÂ*`ZÎW!÷Ûý’&lµÂHg¼Fõ¼µŠÅA‚¥J‘^îÄÜh†F ”ÿŸ]±éI<î÷-ýž™ž»¶ë øß4·M…}0V·ÏF/îoªĤç‰5ø`¢CâÈÓ´cZŠÄ, Œß>AkE´ðs´@Ûf¨^è‰]',ŒC»àý>kºÒŒÜµU¹ù°à%*ežÌÒ©p8ç4~ðžH{ n¡(F1#­Öž=|`)YO–]w°óô[½BWèWÖ»ª¨ÁÈÝlV£K‘¯÷EVÕÆÎÔÔ¦ò¯e˜XÍá9õ³&'ⲞÐ@¡ëŒcGÍUI L}ô®%3ГƒÀx2¶~”›¶é³²1mÝ. í*l¬*j.›^Ç7î×Åzð,Ç*y™õ…uTÃYï„þý¼Ð‹èº+™öÅù¬XS²Þn:³Àn?ð˜p?È}´ˆF 2™ìˆaÛŸÄpsÐñ„o9²%Ó<¸ÙÈ1ÆÉ1š4­™Ñ¸>±[-Ûí*ŽMoZ–÷Œô3ëƒk”¹ÃN‚†õ—ã¥+û®¨Œè­™¸¨ºaù~‡À÷‡!h1]™¸”6B´o³UHq¢´ŽGð›C.½@UÐÑŽƒ &®‚£LË&G“f³Äú© ‡c#""{‰Fûç™ ;ò6ìd¸t‡²ÏΪbªC檣hÏL”öYÙXÆC¦0ÌudJ ¨Æ³Ð4Ä¡HGrˆ‘‚DÕWm]Pûq ‡ã]µÖ™å Í”táÁFXéÄlAÙ~s°[nf¿Ü ñÞí ÌÌmjÍMi›ˬuÛ›é·-9ú¥}—Uý¶=\˜ôYg“pgš%ogûpÛ6ÖíËe_¾×,¹²b¡L¬fMKlëöäBjL…c:9T BíP(DiBC¿<Àví•Ho²i;²qÙlÊ]V¹ói€].4’mŒÓÁŒºqià°jÄ-3òi¯ú+*À|†–·…᢭‰²MÀl¢ñvà(b)ÀÕÉ’é=w>E¸ß—ù%™é˲ª¦ëЕÍÅGÂ’I™6ò.% ÛV™ôSôf¡^W@N(Ü–ÜdRc³ƒÍ‹™ÑuCø&¦ä˜±òµ› ðž3°‰ÀÁb ÞŽˆ¿>¦rE„ P­D·G ã šU29øÚ ¼×kŹÿâ ŒûµlÈÊ1á ½E‹èm ¢Ë²ßÒÓ[èÝOøÏ6H+péäË4‹ ÃaÆ €5f)¢BM ”€Š÷™NaØï™¶èPšA·(ú%‰°yªöBGuxì>àl]ßA¯•V; ÇÓ¦é‰ãàṴ̂8×TÏ;6K˜˜Úd~&y‚΄• “ˆülNÔŽsÇ3‚ e±°áñ£Ž$9‹ÕÐ}·o­wÔÆl¯Êº¬ ÄÒ‘òÜåùLk¥‚dƒ=0Y¹)––|,¡|½cƒS1 M¤‹Ž¸Ó3® ¤',.غ\ç®Rh…NR¦R¦@±Læ2E!e  *$ëлÿ°3x+vDD˜²$’Gk3_’„áÇt˜›I Ú¢T8½¦9e]w‰l÷fLÖÏôáëŽç2ðDÓë„ -dy,—3,÷ŒfO‹¦U¶O"|Qü@„ÁT"Np˜.öÁ¢CL¬ÑbÌÇQP)†ÃQÈïšW±_0I(X:HU šÕhûÖÐ%AÛýª(v¨FúOš èB Bñ3ê@uÓ—h Ù€qF̃ó™,¤B’ö,x¶ê%={Vä"Ó’¹ƒ&Þ¯í–J¤S«9åݽ•RþéO~FYî±çONW ÷Ù£‡¿¡îŒ:½²;‚¬p¨léîq×!U˜zó_“²–š  <:ÎÙ¢„E"ð‚$fä¶M}â½ó oŠ rê6{ÝÔ^@ÇoqÀ”Rš\Á›bR„ya™é7x¸oÊRøO·Dð…PEq:ÎJÓmä860åðR -…Óñ‘Ý_ 7·ýÍךmþïõ;÷~ñÀyR…9A'¬øozmw¡@xi̲”“Ú^Ê´ ö²²×ð–CÓkÈY¤¢Ä™+”x!ë¸vAvfäSMñ9ûè:š_kÊuõ¨ˆ;¡–‡¼öÔÇÓñì=„Zã$áýmhˆvwˆÖ¶ÿha& Bý¿LÒ?¢RHTCî™ã¦—˜C0®§B´a@s˜P~¸µ\C=Dêóv?Ý|¤ã†ÿu ±´ùG³žPXO’Ä÷0~Þ›U·ØLÄ ‚8ˆÈf¶ô12_c-ŽÆCD¿{ ôÚýíÚ:£õ—2ì_Ÿjø³“ʺFdVlB!ãª Š 8 è󻙌Ÿ4ßO09¬G"î¬?ë7¨ öfªÔ øò Â|á6[(×B–òxz¼éTÜ¢º‘lNRf¨N÷›Öªnú)*Ÿ䱨¿(é¤n‰±ÅŸªªÅž—á@axÙ£ªñŒê¹†<ä+¿:ÌDuœ†U0OÃ*´ „fQiL™R6¹K¶cæ_ª‘‹£ÎÊJõESA…>Üž0w½$X:›…AãéšfR›oݨw3á,†%[0™^ƒTýóÞó—Äà±ã‹çæ\맯u¬%RŦïÛc­Ûc-‹7“Ûc­›¸½”ºúXKʈqÈr7Ž7õcža´ûLŒ—†LŒ&~0qêKAÞ9a/žÛt œí›Ì_dIXc¡ä×·äÿ0Üuí}ý#5ž²$ˆoôHM|Æ™šÂ»eÉWùdÊ£¯½Z€Íä¾Ð yé 4‘ºïb›#šþÆŸúg‡žšìå¦@㽿1)ÞWmLG­ë¤Ý\V0¶·ŸlQó8™×#‘ÄiµèÑ^^£·)ÜËq5]iv†ÏnäSc»d ãË´åü2ik.‘Ø‹Ÿpe> stream xÚí[ësܶÿ®¿‚_:¡f,/>àöCÝÄqMš‡’¶ãd:ô¤cuG^޼Èúﻋø:Æ‘tŽâfdψäØ]ì‹Ýq<ºŒxôòäoç'O?Ö"2̤2Î/"•¦ÌHe:gÚ¨è|½Š??•Ilw¯í®nNÏd–Çß5vGw/÷åÒ>¡ûoìÚ¥Á¤dâôÇóÏN^œŸüt"@"D”I`®YƳh±9yõ#–@ÿ,âL™<ºv­6‘Ns¸®£oO¾>áCmU>Ðy θÊHÑ/O%ëÖi âvU´xÇ㫲*[".kÛ±ª=©µë5‘nN5ôß»‹¸ôlê×mQVvIÔ ×ÍÀãk´P±[¯×–ڶ啹Â?¶mþ Ô\Œ,ŠŠÚþ|ªÐ¾ŽSyqÄ—^Ñ}SV—hE9“z ´ =W;ë[ ¡¤aY’ŽÑo>9b0ºÞlí3Ç…L4ÈÉÕEóùWÓa‹|š³T¨(1’¥™Û䣟"hkpäšS³Éãb)Ú÷3Å’$qä5<% V ¦:Ký Á”Vr@PÑbø#7ðÏuD-˜NÒÌôµôÍz‰i,»‡u'0PxÏŽ÷âø­yhï/Ülñ‡ßEôu“Ç$¸íâåe7#(µÃ¿æÎÓ”å¥7—f'½ÿ¦³W ½º'ã Mš³4ä²ç¥å@ œº2 ^M½½G²L2JÀ [Q]¶òÁDÁ[ñ£lWö5eC nÃ\tO+È÷Ùã1AÞ! cÌýNßI¨r›‰këþSf2üòÙ ø o>ŒÒXä•âžJE(jW~R&5É÷LǼ›ä}ù¤x†å“C#ð~S¾Á›4ÞC´EÜ@©4R®Æwµ—IH©/èªVŠoèvéa×m\ ‰¯0ÆkᯃHâ¬|È !¿N¸€*®éº©éŽRV§rMÕ! ˜Ô‹>!¥Ñ]ªC¥Œ‘Æ"ûM¹Ùoˆ6­ ‘62(˜rzA¯ºüvö'ôÅÞvªiW‚:5ØQä2+Gói%­R‚ðÕu‰xvÄäÜ)BT›Xu0ñ¦ c_-Š‘#G«‰‘¯d§UsgLÌÇ㥩þ«S\aþ–ÝuŠ÷@À”…UŸºˆ†ÍuBü¦Ç…†“ ·*tžÃN£i0’©É½« ~œÇß—ö4‰=”Q…vI ºß´šô@Ü!ôV(ì.s°»Ï’Î×DÑ@Þ\“iz®)‘°FÏ_Ójr¤VO“Õ—Ãÿ\9dG ÁF…PÒ»°ÐÕ‡œ\Õ¬ÇýiÒãÝÊ•à„YzVU˜ñŽ™Ã9ÔØ9¿5vEÕ’äºdÁ 3²Áöà׆³)Œ¡ƒ'u캮¯ÂÂ!¶¾¾]•Í»­odKé×·y6SþåfZþ~Pþu$,pº‡®Ìé(¼gÇ{qUÞ¾¯ã{_ËÛ<•·z'å­á1†{ë í‚fÈCy üÞ‡òViØCRó‹å­†šAeÉ;-oÃv1ÝÏËŦØhQ,VöÎuÃÓiñÑn¶wÑ÷ ÿÕîu²Xü§mo¶ÅœÊÙ úPàRñ]Y-Êm±~FÏÿµUU^ØÝ;ª|ŸŸòâËçÇVk*uQõ—ªµ/>=¿‹Áú¿øè;_8gÔ>P8KÅ Ì4úØT¬K_©4m±ó»K /ÞlË~1Lä ßÚÝÏåÂNÌz{8bâ%žÞ§4|:ét$æÙÉÒ÷èå,*ÌÔmÏîõÄú¸îRÜGo(ãøƒ:2ÿ?p$O~OGL#rÄÌö²=*ìCÝ=Ñ; d÷‰ÛŠç,1¿Ià–¿}àVR?¨*ǘÛùgêAÍ ÏúzbæK;Þ ¯ê¾ }VÅܬk(øKú¢.,ƒ×áÇþy¾X§­­ûÈÎãO«W¯]MØ_ðnæ‹'~Þ_ˆáPKWÅÆ.g>cª6Ç~~ iÊÓiª1ý¦tÿáÓëÝ•pZ§,› Ôム°0·þä‹ßM­ô<ƒ§Ï¥ºƒH}Y— Îp87*%Á’ûoï¥Cb”G© ‚½pÛ‡6‚Z»:> stream xÚí\ësÛÆÿ®¿_:…fÌó=q8ŠkËŽ“¸Il¥ÓŽ“éÀ$(¢"-ë¿ïÞOBØríÊ3€ÃÝíÞo{Ý%ö.<ì½<ùÛùÉãœx ©€ÞùÒ“Ô“}ýËOgèÙϯ{ ÆËºÈvýji¯•44;»ÝÊ–ŽÏbUò^ŠA›áf3î_~%Ãó8ù …»!»~šz’ñ‹™–7öó(-’ô¢§VaË–†P^²[˜‰¢(Ĥ ³A«,*§b Vz°ûÛõ~gï4æ&O…+ûP«¨©Ó”•£è‘$ï–NSE)cÌ¿\'M>œT4³åç§v+÷ò~bL F„ ®¼î5¿ðnzõæ¥6@¥ù Bæ Qà òþô ®Òürl«uçY«$ДÛÄ%(6!ÚPq¸1Îh£€yóækÊTðÏ´¯KAì"ªî“ÐÀU¬‰Öesè¶~Z—Të"Üè7¨Îá‰A\5±lF8ÿ¿çÒûÕeRBÏ-úò²Ò;é¿êhõ H¨ƒ#C¤7áÞT¸•·ê5eñò¾“aÝ ¾AI?9”Zø4\[ÌPHÆ|_å ݽ–Î…0«°,`LãjfsÙYv;¹[Å`ìWÏ5êåÃL«x€±•qïÝL€ÝЖ¦0–·Mðy2¿Ô6OWšGóUüäZ¦Õã=¿Ølá÷ ýeþ^Ìçÿ.ŠëmÔb9°,?—Ñ~íxÞæI:O¶Ñú‰}þOœ¦É2΀rýÇpÐ*~Ö4Ô\/ÙJ;ýÝÓóïÏþþ´Åáau—/1·•ñï øõ«óc;höü77ÉJ öœy0á#E,µDëda±ÙQîæîÏ>n“<†y2`ûoãüC2;¨–ÓÆKh.q_A³DóÕÑ+ Ú. ¢ ¤äý‘â#ZD‰êJíÉplßù|ZsJÆðM0¬>îSáW H,¾¤ ÔÈ LfqQL²ºMK7Ò}";6Æl3"¡>‹Ý¦ŸÛn“ýŒqX,bþ`foû:)žf'餿 ?˜ÙoÙÌ®²Ý4#»ˆ–Ël‘¬'™MRLj/öföÁÌ~I3˧}კ}XÍÞjhÝ™ñ$»áÎ›ÇØIª(Ræ`ìÛµ“T!Å­£™;ù`'ìäW³-WÓ–“Öñ5©ç4µ$uv¨4µ-Ë?ÞÖr‚B~ó‘­›À J‚˜¿Örqâ™}Çwˆ½å0TÇßÛ8]˜c\¦¤Ÿ¥öZ;ú™ k'Ãþ_O¹ðw¶V”.ìq½6ß̳ôwÌøÅ>Š$Ó¾yÎÎfÝé&:5ŽdÛ“që»]»"{éºSuÓ«¤X¹·«¸l¦}ÄØ·§Îºdk GÏ]¡©„¥T´þ?v^|÷¦5õùf¿ëuÎ*²°áœ „2þv&B—, œk]mâ(5· £ÂÞ5 0ïú^§™+¹¬\¼ºøªêźÄMaáàpcÐÕ?žì×~fÓ"qœèx ëpÃi«¤•~RØk´³òYØGç§ïàPDjW·]Ä Xf ·T袈‡•+þÇçÏlßU@€¡k/y¼41zˆÂÏ£5€.áŸí€ ©¯ã¶H6®¼VHjt6çe¬/’Úiœ³>lÄ0Ô¡ œ¾ag‡˜-³u–]Z÷ ç8uò»î:÷ß»ˆ„ýN£o2{5ß— ÆÈ’E¶/ª>«z ¼V”‚km.к·ZÞQ’¢Ê§&‘b.¸é_ X†‡@Ýy”V,Öa¨ i{µŸ’Uq³e–殬‘mµiiåCÒ Ì¨Â5À‰è¢ âˆ\ˆD´Ý®uÄu»“úÛ;Œçع`‹óÞ®£Üy<[áY”3˜‡‰ÇŒ$|-©d£¥=ï’©:N )jÝéLyO—BÂWb¾°sÜëæTJzyì-±^·õ…u_\ ®e_ 1.=§–¾ãÆ(è15×úLIhEôÂM[MÂmhŒQP´±FN;²K›:mÆ6Ú%ÊÑûji¡BËRxÀR c(ÁT8˜D4pßÅòNÚ%Ú#áhÓæp€Å¸K>%” I'ë¨'Ã.°ð—ÁºÑ¡=ŒíÜÌ—“£fBLVÂ`‰G-ÛÁ Ñ¡=ƒm‡ÁõP€E ÉdÀ°ÄUNχê@—öÈñ7ioÝšêyTÄǨ  ê4X¨çN‹¡jÐ¥=†í†À0Ø0ÉšŠ€´S—áâÍ`EhQ9þ6eˆ]Æsj»xŒ.@šOÖXùæäñj°.thÄ¢E;MФ Ó¹[ €5Y CBº=V2X Ú¤G޽E:µËe­:Æi¨°®“56œu1VßÖ€í‘(´hêÀ­Üú6ÚÃ*:…EðQöËɪA 'Ÿ§ƒU£C{$*MÚÛ<~ªµ£Š;„pD(Ÿ l¯$qB:¬ Ú#¡hÓ&j—¸=Ô6['s·²™qc¿4\c0°LÖ¬ƒ|Ô~¬1Ú#ajѾ,O·ìÛ^ñ:¶çbðC†=ÍTý¡Š™„ Ã\4Tº´ÇÓ¦fÆÐ^o²ýnz—KC9¥º»\KÂ>ú[“c6ݽIQ°‘‚F¥™ŒyTÍíkd/;{zmîËtŒ$½@§3.1̯öK«»Î9œ>¡;·PBŸ˜”I#¸uÅ‘¨ó?l”²Fµ¬Ýbž•÷0{_DIjΊtv•9ØÑãpS¿å¯›Æ¥ Ç÷œÚP‡Ú7ùª>ÜUÇ:Ð yd;¬S§,‚%¤};U³(»• €¤q6ô¢‡˜BÙäÃÀ!mÀ™“mkÞšËcwâÓË>Ü©c½}ÉEH˜ôŠš{‚·/Ê<¢<€ÒGnî¡Z’ÜÉ¢(•—!éá€ÂÓâàÓfŽ÷Ÿ¤T_b löº‰1`ècª2“òQ=Õ‰Unô‰k¢÷•ÿó¿=ÊAÙ?áýgÿ8¼ªÚ$ÿ`ÚLþÿ£:\&ÿ 䳿þè.ôÆÜÊ"0ŽÜŸc²zf]çòëÊb6ô¢ËðCîаܡے‡ ­N áå'Nbä› #_(y¨Ìst’Fô ÈO*HòIù<ô Dµ{°ýdˆ_Vx±Ž.vnZ{±H^¹“ jº‡X%YOëí1wA?˜¹bùó"v:÷=›jR† Áë6Õz¾e´šч¤oGa“Um¡ª'Ì7ÍšÃ+»+w”oðÁšw7îke“«¾ ½½ím¥á'³,¸@#Ì›QDš™ÜÄü@êWHš•ô‘…â.„Fws8û]ù°g딨ûÓ8‚#j]§C~§÷§{8…e´s’fÍ`ÿÙ*Úžj8]xŒ }ª£½¸Ò+YøZ,¢ Åþ$‡Ô!oid÷$ÞÄiÑåú¿©Ï™Š endstream endobj 472 0 obj << /Length 1764 /Filter /FlateDecode >> stream xÚíZYsÛ6~÷¯àK§ÔL„à$‰<õˆIÚ´MâvÚq3š‚$Ž(Q!©8þ÷]ñ#èíç짪¬Š|B±mâaäWiñW"|5~åŠKWiµ´­Õ¬ÖÓãñ‹:kZÓ¼H­ÖL`7øùΔ¨„._ánùŠÉ@[™V¬ðãBÙÆ¶Èó¹mV˸²S®'ËÁÐt3SjÖQ”*›ë‚XDüx3s|Æ&ù.sï/•åQj_Ty¦6Ž¿Ó£Ì×*߸A Í%N7µÞI¢J×®rG»žÚî*]¸Ó7Ÿ«¥ÒVèfµT¦]lzqMvÊj†&S1ÿù¼Ÿ–¶µŒ·[µ)Á\F˜ácÈ[U”ù¦–“×cËFÜÚ¶’Ø ZÇå;X4§Šxæ˜ÔÃÏëÎnS¥Ù˜Öо¹Ú¡1ÛÏ´Ïr¢Ö_· ƒ¢l§]bè”K·:І(4®€HäF`g´c9ˆ1-doÉ…qúfD˜'ÝÐ]érkìlÓÔyh8"´YPh·V‡H2Vßù{ŠÛ·ÇfTÓÚCà ë D„cÌ“´kýœjÕõÖ©¾z 59í¥¥Óóaé–s@]ϺçÒ- G*š€òƒ‚&Ã{õ̆¤ uM§©Ö5ܲí¸û*Ù>Tûj©–†½J-džA¡–ᎆwº~Ñnˆê-ð{%Z½½BJn,Ñr!­Sì'*ÑÚü~=†ØGJ9!p¸ë†–ùóú^K± £kNQ`™‰ö0ˆ;ì$"QSð´ÈXXhÌË5~ô´Â’íùtnÐ>Í Þ6ƒ‹p,ç=܆¸m²Xä§•}{'yËêR©­¥Ùó4é{/•o,Õ|Ó~‘;k8WÄ óñOÿ Ý4¸”«-7çýZþÜ2]Z 3>ô¾žpxcIbÆk½à-sg=s%°zQ1š«¬Ïöót |—Ú­SpãÜó€=KØTk<œe¹~yÕ$ÌŽ'>mNc"Bî=§19‚ùp#`>§{˜ß4ª5Û nÙáVÜ}å´‡jßA9MÞNc²—Ó  r§1бÞéúE‹ÃuNcòAä4¦s½ù³#‹`áȽå´ú«ü”»OˆpÅRp±‰uh¾)Úæ<ÍêV¾ÛÔßè°ÑƒÛâQ¯G)4‰‚0¨“ÎÕ2­ 4MŽêù†Áb™2ÃÚ[ýl Y„Eô¯”1†ÿ7"8¢ÁÁÿ6²ÿÏ-¡Ù¾¤^oŠ8¤µ€ËOQ€û~ù¦_%þ¾®¤I endstream endobj 476 0 obj << /Length 224 /Filter /FlateDecode >> stream xÚ»N1E{Å”)6c¯Ÿ-ˆD `ª(Å’5!"›„Ý ~³&Õ•®¨E£¬#~óÚžÐò3~“W"-Q8yÚmPXþ†ªÌ¦iÜ·‡v‹BÏ}>œ'ò‹åò/JR‘ endstream endobj 484 0 obj << /Length 2881 /Filter /FlateDecode >> stream xÚÝK{Û8îž_¡ÛÊßW³¢¨çì¥i6íd¦¯I<ßÎn;E¦cmeÉ•äfûï @½ìô9§ÍÁAÄ‹ ÅsîÏy~æñóÙ„§çH'öXz"T‘“ïÎÞþé9k€ÿâx"M#çÞ`íœ JàY:7g¿=]=~H'iäGÎj㩉'(õ…ôBgµvÞº‹eèþ|þfuy½øsõ‹Y"¡‚ÈÇ5KO¾³ô•H¥¤«Ÿ¯//÷ìr5å0 c«à[9m§ÒPÄ)P’J´Ýï7ÀÙÒ`5t_¿zvõœ†Ï®^\ÞÏ*‰¹TÀ-Y"; “Ym5,ó}w³<·.Ëz¡B÷¾¨î¬Üwž JÝNQÑó“Á=4„²­wLc]4:ïj„{€d`yVÚ-#Z½¦·®f”ºêšº$´Î2t«·ÙByîÇÂH½!”_@^7·º©™±Ì2ØF¶ß—…åÚn3å:ËóúPu¨(ÐüRJ‘†lûw^è* „žaI‘@0b®PMš ·ZWô¶.Úì¶4ò!|´j´9ÒÆeèvˆð·Eº¼h~wh²®À÷Pþd\Êz¾'$XÓ~¤àWEÒi`âxýüÈ…@F•0¿Q 9¥ûÍô·ËÐóÜ÷(‡µÅQ$ŽzŽa”ôÿU<ÿãòæâúêÍêêõ« ÁÙý}Ð_ŽNŠòü™û)Oºí§…6D“êaep›ª+ò¬ÓŒVTëâc±>d%¡ÀIhZzÅ“…( +ÝÝ£ƒÕÍ{‚ƒƒ™£ÐÔÕ¨ŠÅ2H÷|Óéæh;svq‘õ¹V—£0=o99Éjd{4ñ\vÐŒ=x§—±6–º¹ÿ¾©é¹M¶cÿ¾/ºm}è&‰B ³Ú®Ó-ˆÂƒ¬mYk&Ró!ʵyq»Ï ëyLö²\Nx½È±HŸˆ«Í q!œéb|Ô):ÁË©pi´ûº²»nšzG&|/A?Œø ’ˆ\t4‡ öF>(c M Ì&ßUÑ}Îge"$Ü8Œnbˆ™¤"LS–WHýî ”{ÁÒ*¼ª»±„‡Š­YTÇöæ —uÙmfe¾ß%¿Þá©Ð]×k·,Ðûù½FÍÊvbæob‡qÌ­pÂÍn~}Wð)l¬fÌeöûx 𤋭OEìù7$×;ˆ`°k&sB˜sð½4™m.ÓØ­2¼;qîÐB\(q“OÀ[1+*Fì¶fÌ}Æ~ß"Ë2¢È„Hx¾Y jÑÒÝÖd gñt®Èz˾)vYóéDê BÈÞ 1.x :Ç­¶Ó­frĨx‚ƒšýáºCždDi5¥ ‹\¯DÄA 9C#§qh?ŽD¨é­ÝjÐ]†|ž–;T"Œz±AÅ Y•ëSÂ𚎅WñXxœÒÞϼätàÍ$-€’Ñð@²Žxœ( 1«CY¢Ä~ìÞPj@¾+pÁ.³y fÙ@ö¤K¸iJM'Ð*¥"×@9MpW $"&~! ¸D¨A×DºNȮÙªVx¥Lòe´“j¥8£ÕZS×Ý ÕÂõêHà Çtp[¯×¾9q§EB†}Øå…‰ç^Ut¢QQ2 ¾¡Qp*£áØÿ@1*ì©‰Ö 7¡»9ôöÃá‡8ØÔ\K¨|D¦ƒ>Þ»_¾ËH›EÅ[ÖM Nf,5€òÓ©%0áÅ«žø?TíßÑq"·Úä!nÓhB2—7¾Ü2ÀŽÛvË/ワ'\õYEÍ‹ˆx™ò€ó§´i{ÿIÌÆ•â…—$|ÿÍ€&ECn‰'×—ç/^N.;ÊÍå#ÚftMvÅYÖõ®@èŠucoáyšO‡5‰H|ó2!Sñ‚âã³_=ßÿñ¯ÓÌ÷‹$_õ•e ÛÍš^û«yÝÐ3£Çìîy%¾í ÖqÄ OIJ?` z¸ÎÊÝé3§ñpëQ(Boæ»$@œÂµ¤ÌkNÉçQ&ã¨IèðiWÌ$ÈÌt”ƒ$Üd;“dcG€QšÓÌ6°A´Ê‹}†Ñ8€Ñµ‰¦À+ï™5Úr]ò¤ÝGôÉ5Ì-û½n0™8 ¢› Î>¤ô½î²n¸c|{·(ءǥ[M¢5[š*˜/ò{+eÜrzâ˜KÒ“B£TÿE‹g»}©E^3]q·íˆú­žnÛX瘟¹Ë?Î_¾yq).Þë—äÎ'¦ndêÞ³%8‹ô)““G>”ù÷íé”sCx4[ðÊVÃÉbM`1ÌDOgz ઱ØÐ,%ÍH®ŠÀ}`àº-³vËL’Ñ¥u;ß{Xoýfã ½/FÊ:·Yµ¡À•)&…}ÔWY9$à'Z¶Ä{çùÞøaRmqWq޼úBD#Äœbâ;¶€cA>"?pO®JÍCsêù0Hù“KýSSN/W}.JD$H±cÓ‹s>8Ô…ó£À#´Ù0ß9ŠÚs1¤ŒahÀ%ŒBˆÝ;vd¢4!…  –ÊÉG#ðó8…?³¼*„QœÀц{P$ûAi7ì!Þ@ζËa Û³øüðŒdùÿ½|ç7œ' ñÅÇóÞ#àÒMþýVwðE Ìû¬®Ê#™øF_!Ïôú²Ò—…’ÍC_Da”Œh…ÁhvÆzA5ð2TÈתâ{ÎÑQËŸV•Ë(ž”Øj€ û¨OÓÆžäò÷$<’ƒü:ƒËùT´û†„k£>ùZÂþF'J›ÏS¥¾V8¢^kS…qeúƒücˆO Ô’çB*2„œ'O_\^¾™õh¿Ìð¼ZS%þ$i‹rñú%åQh7cùmSßW?¤*[ž}:Bˆ§C ÷äÙïOϯÿuŸQÇëëç§¾o$胑iÚ¦^<É#’xÔO„xÔœLs¯q°WIsÇyóˆXlÛ\L™·Z]óÄûD&Åþ\//°…øï©¦‡»ód鬄 Ô¨â ÊìÎÊõ{²8Ñ1—í”k]åüñfÉñ9åCšw ¹îêÜ|³Iné6#5 Ûff5ÊÂKéš  ÓD\P¾ÞœmÓ0áEPç0ìX”`”ÇÃ`Ò?7Tº¢ƒh&040 7Ún±ÁµÕÑN§ªÈ&«Ú,G9ÚYö³®+Û6F$H1Af® ¢ÐåD¬­O4žaé¼ÍyüÝÉö¹YT*œúooÈÉmßl}ÜÊÜe‹>%œH¿_¡¼ug²é@~¾Kd0Øà*™iÌ”#)çû¢1­ Â苌ÊúŽÊ]ì¶-5°<7*†*~Íôoùë1.¶¥{_ÌwÅŽßÊbWt\~±&î‹Ò2=kö²]MÁ½œÝi#~Ív¢aãÇqáeg†« «±Þ1ãÈþæSÊð1úH?ðå+L!}õ¿úË—ï‰(ê/ļÞA˜[OS‡ùÿe@iáGñüß2°øº¼G‘t_HÉŸÓùŽÿGdž٠endstream endobj 491 0 obj << /Length 3220 /Filter /FlateDecode >> stream xÚÅZYsÛF~ׯà#™2¡ÌàJjIö*¶e¯ÄMU*›Rd¡  Zñ¿ßîéÆ1 h:òVíƒÄÁœ=Ý_Ÿ€˜}œ‰Ù볟Wg篴œENä»þlõ0 ÜY CGGj¶Jf¿Ïß,\ožVë´*ëÅÒ Âù¿ë´¢Öë}–¤/¨}›æi\§ô ×uäâÕ/gW«³?Ï$&f’6×N ‚Ùf{öûb–@ÿ/3á¨(œ=™YÛ™öCøÍgwgÿ:CBU8"T G¨€½+·xº§çM¶Y¸bþ ÿ¥MMq•"=ç¯|5ØÄ©"8ÁlQ-$¬(Ò…ó'¼w¼Îy•u´ö?òÛUk3ÿËB‹yY$LÂcšUÔÌŠ¬ÉâÔ<Ï øÙdÛÔY,•öæ«ÇŒIܦqQ·ëㆆ‘¡pÜ0hOþ„{/–Pº¼¢S;*íìM\Ðæ)’ðW“kÓGƒOYóXî 1³¥R„Œ¥”Näy̵ôOäÛÞì!à¾qeË‘==4%ýVé2ÞÃ)n€¸¯€ 'R ¹ë‡‰ ž²úÑÞ*Ä5©5µ¢§¼ÜÃÅ /¨w_ó: Ä Ø*B„a á¿ýY¸;è¼} ( „%‘ÀqUØI$IkdFS!|Ê…ô€4sãx$!å9¡× ¨Ünã"!ž,]W9" ™5n§b ~8v?`QÃè:¥ŽÃ!»JÒúókž\B_Eó ¡kjÏ8dlàD‹·ûÐÐS “”;•QÑý¯¨VeÅÇâ¢äˆ>zÚñu·n‚#áü G„[$ b†« p<á2¸}Úì}±A 5X'ôü1Fâ>]¡á)NrÍü nI5ß–ƒ`‡‘laÕ®*A—€iU¼­iÒáÁ1ÍeðP_ž|p¹k²² ^#Tè;"Tœñ˜n™à²ë¡Ž*Ý–MÚ©ë@ÿù€&íÊÖž…‚QD„Bøµ{Øç4Øÿ‘a0OŽiús¢m_dL`:›:Ü¥ä]:ö:Ûxƒ=`Œø# ¡ZuýØíæ¶Ð%LáÛ΄ŸéeõÉÜÓß ¸Ž°Ä˜o60dÝż3š'Ô†c¨±f;””·ÌíÐD s¸›òÒÁåÚ3Â(›3ã‹Ødæy×ÏÛŽðs`:G@u,ã% fÔÌ"¨ª±’ãNc%A‰#.j¨@ßÊÍ^9!Ø[ÿí#f¿/=!æW7¿^ß.¼ùû›wW7+ ?~]bþòöúåÏo¯î¾f~,|¤Ïb»KQˆ9UëA€sȱ¬*‹-¸-êüÌFÉ8²ƒjü2-p–²¥ùh¦•ÅJ[·Ï÷Iúãèn–59Õ7·?{´/ß]})À‘4 З郹ñ>‡«©@Í‹ðŒ½5ÁnscìÝTi‚N>ÎkÙ0nyø¤sŒµÀ‰:yµmL· ½®« ¼”ªµø vÙo®&|ÜFv®áÇ©½œ è@uZgɤ¸œª¼Î׃XaÄÂÔÙ1ù(_ë>‰Í>msALjKŽ?’pŒ´@¨ÃüÈŠt/Öim  fŠÖ‡ÀŠÀŒ[hâ5õuNÓõ|ã4­-N;Mà¼pÿïNSiŸS|ÔÈ©ÍÇú´®IåÚŽ3&ˆ‘ІYÔ©Š%w/â½S::úcž€e$õÖíÅu½ß¶!\ïI†wó!Å•úÛUªçÚ¡•â°I%8D`q@ÙÖYö{h_^½Bô+Bÿ(X÷ê•|]µ$¦òžžÐ-Û<_·Â¨õ”áP· Û0zy8'Ö04á㢞7Z‡Õa¯­˜°6ãÓïI¿-´7¿»ÀÂÜ©‹3,“¯täx¢ÓcP àaª’ÊÒCßÐÍßÁÙÙ.o($@ȵyC´#ê6Ò+l™Õ÷uîb¸‹×õ sìö²ø‰»Zô¡bã1£0ƒ'U-4I¨Jãä¹¶ùòâþÃ-Òú¾UÝçƒ(r%Ѐž ˆ†Ãp.5±eVµ˜B š8+ø¼8I2\g¼Ù±í’¬Âp™2Q^Ø›w&k¢îð¦Wy¬oyóËŒªœ©®÷|†ïÏ/@>TîÃÂZºmû©X`ÍÊMÆçƒœ4ˆXM`•­&0Û¨ ¼}/ßÞ!m«8ª—øouuD[Ï‘­-Ÿ’Í9üuu:šaÕéŽè“J}rÚsBw\oÈÝ¢è‹Zÿ¼úÛÑßÅ·âåÁo@”!ùñ(h_ DøE† Ãд­iƒ‘!hCmk¡Ã–Š9d—Ç->`B—%˜(SvÄt;œ *”Š œ;ûŽ×ËôPhâDÞ"íÓ‹‡,O݉ —è‹Æ1'¥ó®'Í+l¹d¥åx]à)“jÆj;ìÖXœ‡g+o  Qd×ÚèàŠT ‚^º4fÉ…ŠíBÙ.t‡FŸFZ¼˜ <µ‘Q)°69¡Zàá#e ~)1òž%؃¦Àü~,Ê*Mר‘d5×Îd jl Y%‡ u(A9"kÐõ '(y˜Âè¶ïÑY‘˜WWcªºö‚ 9>d·:²¹9ò˜JÕ–Ï% ¸­Ÿ‚æ ~“ÖÒ&ÝîÊŠ«’¼‚¯›$­*£ÚSê+Ù—Ðé¥3½8°pM¯²Iôº³bRJÓÚþïúÈ܆r¼@ÚÙLwƒ£Ølõ©Á”O‘p¼î¦ ™4Q O k#'Ã[ÕÚï†,8c?#Ô|8Äß.up6…<,Sô>¡«RAÀç¦÷o¯¯nVßQX¾_o“g]åx¥YoOÔü.¾­è‡Qð3ê6\¯ùpÿáý-ÞbõwoÿiW•;ŒÑÛ¤KLíôõÌ@º@&_uÀ²ÚžxÚ¾Åø#EwýoþFqò#Jo¨R =ô<0Öñn4c>G+(Œât4ø¬²- ÑS[oÑû_Ixi™ endstream endobj 501 0 obj << /Length 1721 /Filter /FlateDecode >> stream xÚµXÉrÛ8½ë+xªÊ‚ àrt¼*™ÄI>¤’TŠa‰c. —hü÷ÓµY£rÆö…ÞðÐhÀ±æ–c]÷ÞMz§W‚[‹|×·&÷–çû,r#+!‘gMë«ý¡ïJ[USU•uà¡}W«ŠZ×mš¨jT¦âZQ‡3×e¼ÿ}ò¾w9éýìqÐèXÜ \.XàÖ,ï}ýîX Ðß[ó¢ÐZi®Ü~ÿÌ÷þê9ÆZgÛjßÛ²er‡9^@_Ç?>^žßü8ïsiß~º^kC: §W^¸5Ý,sœ³HJ1^ªYúÍñ„—})íÂFR¦Š8WDž•E§EZÌ©ªûž´Ï>‰?W3´aiK^&m¶™Žçm7iY°þ€KØ“…¢é‰ºÇàÇmÖЄԘӔô¯Tœ oà×®ý}ϱ¿ô…´Çƒp1!çéU°½â>gž„ÙzÖé¼®OÁä1îDIDLú¢ãŒ‹ÖY:& 5uVi³ V|H•ªÜNßïèqCò5WÝ‚ÿŸø´ vƒ!ÂF’VjÖ”ˆGÇ~$Ú³½ç~À8à|ß–°LLzë0ö. ÀÞXä™ó6 ¬:¬™?U 9¿Òª,rUâ/½®duOu‘WŠIZ#9Áž°ïû±ÑIšéÝòcŒR–U O«8¯a;z‡ÐôŒ\#?+çݤúm KU~@™Y$†_5°Û*<€ÀÕ"íôk@TÝz©:ÊÀqŒÿ©­Õ¬í8W e›ÂÔOa›[4†Éøcäƒ3Uxî-ÛI ã°Ìs!µ@2ò¹UÁÀâèšr&¹ê".ÀqÏc¡oßc°¥vEÿ¶ ëë@:€ãËKʦgŽo÷¬uù$¡O¢ö‰ÚÚÀÙ1 ùÎóÍ*=ÀràèJŒÝã±\ Žz~·NˆóÿšBBYËz€$ÚÓÌCÆ÷UkÕYJ18ªFÿm<¯Ð3Dæâè)1_ˆ71`×õ*9ºì¼÷íѰÞ¸Ü(ø°PÕTêãã›# Þ $³Ãô8ÉÓ©¼£:‘¡&Hw„Lå¶I³­êy2ß‘»imµkÞ·Ë)âurÊ»»ëñK%añá07ÖÉ×±î ÷ÁÝäævôF†É^V÷á$h¦´_XŽ™åcšeptÂIzbà 5>WåßPEPçLφÃ'>½HçigD¿ü‰Y¢M—tŠ#鼤“xYRwÐf}2z,Ywžaeé••9£>aÖUmÏ4븳(וšÓÄ›6©Ë'²? ¸MU¯)jãO“¶ù³´Œ0¼åtššߘ’f¥éeb´Žô"éxC³×<„nCÒHÞ Ç}iO0\·ÚÝ/ÇV‡DŸìЕ¼ ÷ÐÛ;P$q¤ù2S-B’¦­t•hø’-@gåR‡xↆQC 5´q&•â@Ç+Š©3§-Š®‰ã¾*sâäá¶{$zÙ65\êhhw€P5ÜN„'ì¡Ñ—9P°a¥=8TVàN†V›Â<‡Š«Ö ÓNïvEÿ|ˆ¾a¼xF—<£áùdxûiüä˜Ð—K³tó…I< åɺéošÑ€GQ×wÇ]79ß4C㸎©lÉ06L̘҅gß:Ýû°’yNgO€‘}@wuè/³x¦ˆE£¯?à¶F RÖѦŽV•eƒêÐ…cÆ=ˆ.7òÑ›J­ àìŠF?»¡˜ý§ mV÷„P•U}8yÙå:m =+Ì6¯ÝÅú|Ú^`|NˆŸžV»Óþ¨žýþùô•DH<|“3a}í$=KH|Ë]ߘ9ß·é_t)@ endstream endobj 505 0 obj << /Length 2894 /Filter /FlateDecode >> stream xÚÝkoÜÆñ»~‹~(Xë}òa @ìT6œ8±#©h'¨;JLjGžIž÷×wvg–¯£-Y6Ü ú rg‡;³3³óÚãÁuÀƒGÏ.Ž?×"HYÉ(¸¸ bÄ:a:UÁÅ:xþx,M˜7—yS·Ç'2N¶yƒo/öÅ:„ïgy™gmŽÁ¤dâø·‹ŽN/ŽÞ Æ‹kó8XmÞþƃ5À8SiÜ:¬m £žep~ôË'Fû'À'g2Rö«H Lφ­ ÁRc¤ß›àŒ«÷¦˜dÒqùp2ÁÛÃyxúï§?½yuz>Yíñs•ŒD˃©á;ƒÔÏ÷»]í$fxØmèeo¥ ‹<~OÔ9ÇO³²Xåˆ5¡ iå±6Ù×ÌðÁnLY_Ž~åJ—DÔÃ6N³ö¥ÞÒÔºhòUW[8? lUW]VTEuã?öí±0a7ÛÊÕ±æa]–õ±2ám]Uþå5: æO’õÒH,ÊÛSû*ˆLÌÒ8²6¼ 7µÑÑfÃÕ6Phf±bÆ.ad˜ÂZžŽ#šLi%G¬ÆÓ†Å)ü¹Ï{`Ì´‰âtXQ$„6PìA+X²”ž`áÃr| ·‚lÞã・­þï÷wü€ñ¤Æž3ûxÑ[züÿ¹æ Y ÌK—f6'¼ Íôòò”W?mHÐ4ŒXdÀ— k‰dD(±\ì&è3+ûŠâ!çèÀçÑÓ‹ò$Jöi¦bmåéœj<‹Q¤­œÏ¹¬/éh+ç$éŸãd9³î1V£•@ýQ*¼óúîùë×ÏžžM½3ÓVþŸ[tÁEÇ쩈ÅBúEÙd9¼>{±àFOŒ„Õ”s×)§`q±) *ðõ·ÖŸÕûÒz×4gLnÉm+aï¶I83jp¢8ö8]Dö.2Àò€ù€íT•wÈBsƒ€l·ƒ€uE]µŽ•a»_Y—¼!é˶ÝüÊá|Â?Aˆž^¶Zåm»°i"–(qg艘0½ ÿv¬MØö+×ûª#zûÖ‚Å—$É’šXÑ´àDGrœ`´ïS—‘ä`aW¬,ìÆMt-– ½¬p6ÃÇ:¿²9O¶/;@¸³Áòzß8#ÐÊñ¶è6Èf41ä4†܇aŠº¿gûnS7,*@(]ñÞêpI”©f21þó6'6¬¦ÜcñÞEYC±; ošKÀÕ+Ë™±&-K“@L.ZD'‘Oœ e ²F&2ÛºˆÃªî𥮕h4$W÷HR”è·‡v+‚püëÄÀ-`là„m…!o¶†Ù‹Eï-NJ‚Á­rÄn7D¡hçû)0…É×£2ü—Zý>GÒƒJïŠ/‘à™gèÒ¦4 ?b(J2žÊ/±“˜‹©1'š4ÑŠË6w'³@OÍðÉœ\.hy{·8Üå8¿-üòBÜáH·Øeå’ç€óšpy§=¤LˆÞÿ9Ùdâp›¡'ƒ¬ñXñÞ³XœñVœT,œ»G%D¸b“gå–RÓšbo5”®.¸£T^¾MfÇÁ!ôhxBn Ûa¼r:â¬Þ>£ðjïnËDƒ3m_Àt·É–Ž™à1ãÑ}šp9 –HfDçƒýaÙz Y=ÂÀ¡Mümå`-( Ÿ:BˆZ­=‹©ý¢{¬ ë;cs´Mf•L&ï  ‰TAÆÍÔ;5ÃvZÐ45ð±Õ|² ª –g}ðtµrýuk…h,“o^³¨t!§×bžÓkyÓ÷ ›µöƒ>wí!|XŽä¾UÍògÝß½j–ôÛ×,*Ô,šÏk-Gd`€ÒËÅ’ã¾fQ韢f1à"„Œ?Z³Ða$äÌ>¤l™&¾ß={uzúæ‹«Xòñªåû×?¡C413 bŒT òb‡üG;WKÛ¹›4|óxNÀ¹ÍÊ#‚x—šÿ…<æU\šBÙ/Uq2–“ÀáŠsü pïáÌ¢ÏÂ]‚O0øâÂÌhVÅ&©ìã ñƒ…‘G*hÁY c'§5Œ'Cìe´úŠˆ`<–®åðižÚ}ØY¦ΓMÀvYÛR:¾†D@kþl‰×¡º,Å¡^æ«Ì&ô )KlKjqg%l´ö8Mn›ŒíŒ¯™@’hA IL½Ç1PçE W´¯Iâðh)å`w*1M] ¶Ü7€P"eoú|ij˜áéTàn7ROŒ†XŽÀË, HVYÈ,iœvØùuü^Þe~í:ö­ÇÈhÉ&w UÀ¾hòÅ­j&î‘«/VùŽÐT ®öJÇm»Â%Û²ŸˆÃ¦Ü™îTî´-ºi`¥åOQuz§°´UœA™ê »,Ê¢û0­ ݬB!. Ò7“¨Ê LOÓÔ/Þ÷Îa~¯qb+Aµ§R,‰Ôp¹¡¾ÎåÆùé)Þë<}uþú3n8nFgµï;}ÑžaqI"¥–J¿Ù¯´U(Šu^uÖ0¾lÁ¹’,Ã0JDÏ1_‡çœžöòÍÅË×?†r.6Ô`oÙ|[øáí¦w›¼äX«§ØYHñêJŽKôÔ_$ÁÛì")2!ué6©¬åû18r^ÀR÷­ B¼< Ú¼醅Ve{Ã÷y©¸ /³6_““­È/¡ëQaK­tËÎÇHyHæÑ™å6H*ð>êaf·ÅlhbßSCï§ÈÕµÿ4C2«&w:ÊJB£•°lƒ©˜ó;ÃYÕ¥ß×í&¯–D°«Û¶¸,sÖOÚy•geVÝ ÷xäÔ°0…]æPcw„C l𨻿ÁŸþu)ªB<´Ÿey]Õ ÊZ©ðtR±[.¨vÏÚÅKIêi=Y<€À"ç‘έLã© vo|9ÏhÏLaü}ÈÑGW'Œ ¨Dú$ã=víö‹QÜû( >²hx`‡©\‡dÄêK{z"C2€—CCà¬ç`۪Ȳä`žÅñj~ën°ª+Ÿä(µ¸ÕÇ©D‚L¿õ¸Y;£ÔŸåƒ…¬Ä)ù4˜=¼z^0tbÜÛ°·,pSõuUü'_?™¹ÓIó–O[{M®\§ñ.˜*‘IÿÊjGùck_¨_©(û™ÌhÎç2µ_º»*˜»©(çµÎ2wÛŵp?¿Í:rkd×Ö…g¾ X0W i®Jîg°ÂŠ>vŒ 2@Ùž\Ò63ÜÄ.ë:Úp…T$9Qlò²ô7ÿˆYŠ}[”ëUÖ¬Ý-OªÃç®fqe•è3Æïïc¾p*q2Ü]¼E´ï-ÇÖÁ¹@Ì«¼±g^? B] #á¶j¡½‚\\!ØVŸD VìßÃp]oA;¿7ÞÖæVÝö>~Ô=¼yåñoD¶Ùn×ûìÁWŽ=¨—]•msö©rÒ›ûÈ”ß÷Ý–{œ3òaÚK^ëméï¢É»À3Ãï4ð™Õ±Žà¤Ð‡=%l~ëz»³ÝñºBw¤uOeržÙ;Ï“2šECÙø9çÉò9Nоz®œ‘¹½Óõˆq†ûÉ!ß õ€‡ŒL¥?OŸ«sy÷0…{³ÓKÇ€‡ ç¤ ´hÍΗ.½Â§Ž«ð^Ù8PC™N9ž„Ëçàé»JŠ÷L¯ðwrÚçMšOÌfáLßÈlQ=Ȇ¬nG6䜀·!—ÇMÄšËüç€`û2º÷¯®¨%¾“+¤ ƘðûM¶;¶²ò¾<’ëø$ÒéèŒþfÈálŠ>ã÷¿‡ÀÑR endstream endobj 425 0 obj << /Type /ObjStm /N 100 /First 868 /Length 2014 /Filter /FlateDecode >> stream xÚ½ZQo¹ ~ß_¡Ç»H‘U‡:IÝpI ´ òàæ½ ©÷`;Àõß÷ãxz½Ifv=v…fv)éù‘"%K)©$)”¨ZNÜmŧá#I%Þ5YS´–œhü­KÈ{¢âŒ‡žˆÉVB#)¾‰;8‘±à¡&j†ÙHyGwÒÄ¥b<²„Þ˜Zâ ”X*º3 IsŒì‰]…!£h¸'¶ŽÝ[ÅC­xpü„î@'½A¯ª©’c.¬³2†4ÚVަc¹•SÅ¿$‚ †OUÅ`è^­c=ø¥a@ ­-ÔÕÔQ‚Qz,dTŠ@ëtÀ xŒ6€k‡D àxPˆÖ˜9´¥Uñ1N¢UÄä-zD`E!ßC« Ëãw(TÙ(z&­½a9°YÅ,øR¥Åƒ%5ƒ&m%:)$F‡Œ›®ÄzÒîi5Å m`la-Àj0cZíÑ$Ùh$,Ô$ÖÒ<™´Æ̆1¡;¬ºoÅâASc0 úÅâÐ Ú˜Ú´Œ‡ÐlÛb$ñ–ÀœPdZŰ2¬P^ë`–xÇÔ£`´— ð8ƒbÒ%yU¨¤ñK°9 }y ía9î½­³ôR¡KC ,©ÅúÐb|èË©€œ:ƒ/ r æL`@˜§ãa"á$eur²Þü÷·uN/.6׫áõ§^ï?}¸ø÷jx¶¹üe}ù6±¼þ2ü8<KãËjxµ~Þºæ.AŠ–[]%w ‹x6Sˆ¦““4¼Nß7o6ix‘¾»BÇ›‹Ì™¾O?ü°Âÿåp¨æ =3çfA'Ë&`ðò0¤f×P‡f¸IøDn:¥Žº<ŽJ‘H ê`>ÚÖû YE£\›¨dy ZèÇÂ%wý²UÞÿzþÛõúò1tQ€@Òð;†g¸Ç7µQ¢Õ-p‚ÔŒà ™ h}ŠÖ&™°§!æ ¾/d8êâä¨ EE¬ì±Aéæß$‡,¯ )9~ÃB &g’úMmÈc£–»#ÜÖA^P{&÷ Àò¬H©xû]å–±¥LàXÞi‘ åêá´ž>€K3Ò¨ Ëóƒ;#r%²’‘”|§ô¡ËãpÎØî æ0d-Ü)Wk0ly­äHI0:²n=#›žÀÑ–Ç¡ž‘àP­ØíñŠ,DtJ¾<ŒåÈA Þ:nûÈB­Màèwq¼Ho fI¯Òð·¿ÿ#!"6m©`ºøôñ㻯Êqd¬»2g›‹ëqÞ³± ØJŸ2@Pøæe¬_d|A¯áååæýë5V”†—/ÎÒðfýûuz·«¤—çÿZ¯†ç|}q}…îÝCW›O—ï×Wcµ3~õóú—çÏ6¿§QyF‘ ‡:^ž_¢/ö<åî¬ •ÓäÚ¿¸®cÑWÙCéô7¬¹Â¬QÓ–(é¢}·è‰l=”Í…2SW`×DâBKî ¬œ{Ô&ÄÙQF²÷ÌQv1ÜNô`¦®uÍwä¾@ó#ePjfV³\掗 g-ªøvûåºß¾D‘þ0:JÝ££Ð±t”²$ {¯cy¨¹s‰`ïÈG)#ø¹’¸†5„çYGŽQÛVdÍuR®lœ=Žuñ‡ú0S÷}S·Y¦Ý7µ-ijAòmê1–ÕÇ”n²8’¶ñ™¶öi/¾'30 1}˜ïl‰ÇZSÛž5Uµ¦ò¢ÖDÝÝâXñºQœé!™GÉ©¨„á̇aµyÖܑ㤑 Õà µ“®ÌõÎ8™|X ¶ý@lt´=oðÇ‘èØZYÖ[‘ýþ­,g‘(b¡F-Òá§+Ö¶‰Šul°5FÔPàŠÃ¸ú„§^¨ºÞ:ª¤=¨ÜúAÅkðØfîT¶»)QîXýb‘é± ¿Àì°vWvd__]ñ×±Ëo¼·üVŽõwëKú·ÇeÜW!ÝfNy¿Œ7H™˜ÝŒÍ£óŽÇeL¶6o£ýºÕ¾Fô£­fûV“cIÛô‰kO߯=}^í)n÷9×n—QcëÛZÔiÙ"€³Œ÷¡šQ:³q¾¹è´Ìµ}>ù¥‰K¢DŸ'®°F…ÃW”ÖÆ‹Iˆ“Q¤¨-’˜íZÆ¥ §''ã Ãé8ùðzøë«ãóÝÎ?|¼Þüáêê×áôÙó?¾úÓéO?4,’Ä}-¡F5µ.qP wéG¡ý¾êp£!RTT±/Œ¦%cwJHêÍê¡éŸÏ,Û}FI~OFÁ"ä÷Sb‘ÇÆmèì¬Çzöm-~׳û±žímëɾ¨'«gxsÜ£~3ä WFöæ0¨?Ý’ÅøÃ'QþÅ­˜&RÊ(j%g/óȹ#PuñÀâd‡DÞܴ쓨M¢¾-Aú¶éºmmÛnIÖý1Ž.»äŽ“P¡TÔ…†Š  ?Ɉ8CŸqÔšKp}ŽPãfÀâo\nÀ ÛL –Hdšû ¤£v¬s,xƒÃ¥æøK¬[ È"rxä, ^ðÅÝ ÷ÿS•QT4ˆÝ DZæ¢]9,aꤘ6lèªÓrBHŽlRN0­c›™’«ÖáF3äOm†·8gÔ][=BÜÕûqWK=(îbøÿZŠØë endstream endobj 510 0 obj << /Length 1288 /Filter /FlateDecode >> stream xÚåX[oÛ6~÷¯à£4T )^$ ÐtHƒ^‚¶‰ Hû Èr-D–RInš¿CÊ–d¹4ÀÍyÈsåwxH2ò•0r:{5Ÿ½–œ$4Ñ¡&ó%ZÓ$LH$c*Aæ ré½óCååÍUÞÔ­„QìýÑæ ¶N7Å"íó¼ÌÓ6ǧaH¹ÿeþvv2Ÿ}›qÐÈ'QÂ%XD²õìò #  ¿%ŒŠ$&·vÖšH÷$³O36´VÄk0äDœQ&"4öÍôKéu+cˆšÊ¼ï¾0^àè ÒŠ*+nÒië´Ë|®¼UÞNDduÕš‘®I‹ªs£µS´Þ”]qSæØ+‹ Ù‰‘½V¬ª+º;$|fB–6zRí´²mÙÔë‰4ÃÜ Y&Ê¢€sš(…qØzST_kk¶ c!¼M›/¨ˆcØ`¨ªqh7yciáhrëFZ¶8å¶(Kl]9¦ uùÂõêuŽbk0¿qLU©/˜wçkå9Ùí•áœÔ)@§¡Ñäi¹FQ«|ã…A(²Ca¨ÍÅœhd–K¤ªCJïuŠ;71unS â…Œr£¡³š“öˆç§˜ZhKhÐ «fáAcírKPAñ‚G+"—bÌ;ùóøìãû“‘°IÂ0k„Ð.8s`]ú’yuYÖ&Gn1@ÎM÷‡Ï™—®áŒOP ³ÅØÆuo±ƒ1–¬,0ÚŒMÑ Æ½Ž†[P¨ «…IkcZYþòÝù«ùÉÅœþþá YÆû£ ç=G±©gv°i/Ëü€ïmÑAÚX8BF4–ÉUÝ*µî8@ìò>ƒYt¿°q…q4rñ¨©ëî¥[ÿñ“óÖ?;ªwz8ª½Uí6 ÛCuï¢eK‘4ávÛÍÕ¢^þçœL«ÅDë½ÞŸ ’Mbˆ^ƒäò^+•ô^ß®ò 34Ͳ¼m­Ãsvü[[—@Rêê€\AFź×`l¢ù‹yšÁÆ»oS,h$· ¿bÎÁÚ(@ÊôëÒöÐ$/Ǿ4ê˜j.lTÄ¡)义Ñ*N›t³5X1#QR–\BOÑs“E2Òn€S!E8 ’ { øYöž(9•JGÉN¢ Ý´Æ-)‘ÛN¹UØSØNÛ©ËLf³~¾û0ëYöŸ÷oI>O¢Ìžm>§[Dà¡Èü'†Ƈ.\’Jp.´ñRnd¯ž€ñÚöhìJFµ‚cÙN– j ƒÑÆÅ¨sl&  ÅSòh¯|ºoÊ@'”A‘LzE17ñ´'ÊÑN§S¹j=ؤ\v [rÝŸ5fD±?ÃJ¦)WÛݺ¯a“Ó„4kØÿY©# Jš‹¥è¥Ž'@0{h t¤ÜY m¿_ °þ6•5²øa2Úc ©Žªê@ xŒø£©xS5Ÿº>fŸer»>‡ÎOÿÐúp¥ s÷ôåy Ó/OaÚ3êèws"ø ¸‚úS2\1&A")—ÑsƒÉþÿ%˜Æ¾ÿ»ë(¸À=r5÷<‚ ÝÍs]Ýz¼A5‹û—suÏsu»89ÁW“ã÷q»öápë^f> 8üñxÒ½n®œ^«¥Pf`$xú(£$Xöà7™ý—£Èžƒ8wÁñ-“Ñ}Ñä®4÷»Ý%†‹©Y;6„ endstream endobj 514 0 obj << /Length 216 /Filter /FlateDecode >> stream xÚAO1…ïýsl¶¶Ói»½j”Nh9d+š,»þ¾…J‚‰NóÞdòæ} Ö `È#{x! A‡âxOµ¤` 60ãc–§î=uÛ^Tèk>íSWÔðøÕ¤Aѯ©MË>£%¢ÔbGì9²=Óù™]ÂIzåaµa³…‚&ïG ¤ 5œ.W WçÙ›0õ[ô:ÿdY’èîŽú—•rOU“¨ ZkùÓçr',?ˆ3zA2RTŽÂ ýjû=W†ÖÅe›ú óµlfÿg­Q endstream endobj 518 0 obj << /Length 1412 /Filter /FlateDecode >> stream xÚ­XYs›H~ׯàmQ•5™¨}r|d”µä‡-ǵ…ÐȦ‚@(.ç×oÏŒ9ëzúšî¯ {÷ö>°{~xbxõ‚‘`ÒKV£Û;ì-€þÙÃ(Ф÷h¸V—!<3o:ú{ôq6úpʉ¡HRéÍ– 1ñdDÁ›-¼[ÿh<þ_‡W³“ëñÝì³!1.©– PoBб§c"üËÃ>:™u”$«“-‹®IdàI·o¦àÜ„!x ¦ÏÏ/ާÆ|(;bD%ƒO&‰·ƒgÄëO#oÂXh L$Ct—âˆt¾]ñíD`ì[¨²ÚcŠý§ÿ©ÑF† H ¾Ã·pçò{9=sáÿs1žì_^MϺÁýp ";Ò%€ì…5& ­åÉ¢ˆ…- !,8[ËÑÑÉ#AÍ09СÁOHÍrpxPU÷ªïªB±`OM²Ñ”XŽwbAãT'c†ýõo¯Ô€a!ñ7[^Y&P0Í%Ö›4O^´ ÑÕß«›>'‡º–P\ éûàñødzt}v5;»¼è!±s³g BJl j@ê:äº u[¥YZ¹/}*üÒžTV ñ·¥Úè2þCÃÚÆI•þ3á;K_4ƒÚÌÕ¦¨9¶ÕC±wì§?ã*-r§6M4ï7#P9æ¹Æ‹ó¨Ðj­n+þè´Ti~ïtç‹ÚûLíÈÇÉF-T^¥qVê°éøØŒíð w6ÜB‹Å•}KмŠÓ¼¬éj…ÆZæŸ-’ãlY°„®ÎÔ‘ó©.×*I¿bÆÕâ §k¡–:ìñ6«Þ¦¼Ÿ;²z'\ãç fïêKƒçé ²+À¥¨Ý_ª(ÝTÛI?Î2ýì‚ëÒÜÒm~€Y¦`9ùéÒrÄ­¯awúÊš0þÃd:Íây¦4¶hèŸÇ5øyî”@Í-,å1­v L )a¿=÷g¨ªYŠõιª°º <—ffAÞ‰ôgIi¥vÐoßO㸰ϹÚ•½+LšÌ0‘h{bí•kçᵎíV{E©ÿ}¬;]ªªLSŸÆðM¼™¡;ëL+sn„ú%%p1µ.-ƒÉ¼~VöhéÒéŽM(à9¨ÆNŸõS-ÙíŠÎÕÙpƉD!%¯Žvˆ áÍ„…¾#â{k©Ü®×U–îÆ­Ôù0W£)DùzΘ („E·›´z9ˆ^]hg9x)ǰ ë5¿SÏ7¥ZÀ)÷^?(”QÍëëóÐå‡G½ö '_±ÀÝ…سvñƒ¬±hìŒRV$füýi¿s©SßÔ£>u4;7àE7‚{æ {C{Ü8aêWÂU™è‡sLÔÃ^jÇyãεEÔŒÍVríZòžýõ"í¨À×UÓâ€Ù¶@[Oö|®ªGÍ¡Tn ¥ëÔºˆÔJ—gÜNaÐ0Ü©m²úåú£8:2µ~x~2‚€#Lv0l¿)òÜÄzÑö4ÕÛšOÝ%KU¸†É(b8êF<­Ü˜¶j²moz»ßê »½¼tqØ[~£Ë®‡ ¶·SÃÏ!á·ë+–!Ñ+Ø:gzV†´ Ö%plCËžÏJ]h¬ T5ںʗšZÙó~A©ÞIöûÕ 0â¸aÕË¡e¼°FŠeωµÃ˪ qÚÎ`™´¦>È̬„A 0 ‚Þv«€ÃÇÀ`€óèW›@«7§Âzèí»¿ú¥Š7YßÿcDpX ƒþÿ", ÷üóFPøÙJ©Ç)"Ä¡˜ˆ¾Éÿ,e* endstream endobj 528 0 obj << /Length 1978 /Filter /FlateDecode >> stream xÚµY[oÛ6~÷¯Ð£ T,/¢.öÐ¥N‘vMºØ+6¤E Èt"D¶\Yn ?~‡Ñ–Ìdvê¾X"E~ç~xˆ½[{oL/OCâ¥(häMf^L½8LP˜2o2õ®üwCÊ}Q߈ºZ 'þß+Që·7ëb*^è÷KQŠl%ô€ J~ž¼Œ&ƒ/›ahâ!ŠqìåóÁÕgìMaþ­‡Kï›Z5÷Â(gé °jŸˆNŒhÄä¿"âÕðagòrÃ!(圶¼Œ0‹5o!"(T(Ÿ¿wpŒýóa@°1¤ØŸŒ:$_ž²dK¾Ø hæÂ{*á~‰_,ô(+ˬ)*©éZäÕ|.S=lî2³þab¿ZëÁ²ÌrÑ®0/÷S¡)Ö•\ú g±/©e-µbÑ¡Uë*«Ûjm¶ù„YXJE“$öWÕ#(Ì?›"—R¸—?¢1dµÔÇÃÀ¸¦R^R0ZUZ0Ùº©æ „d!M SŽýowb¡ß,ïrhõ `F]î­É¾µ ÆP±±ðãËèüãÙåûçïG瓬e,„^(N$Ù8„ß0‰ôŽýIÅTŒ·è‘%q d¹{å×Rº`…O `1" ó¯™|­åé¨5—3Ø/–Òp2fúùNÙ‚!0JdØÿZÔÕìºÑ“_%’ÌÉnJ±:–*‚×Ó]…FÇQèéÙŸ£±“ÔËSXÞÕ'X©†ðztzrr.¥óêý“QŒ … Ùñ×b¦¶.›Ö òlásýÈk1ÙYiæó,—¾y'Ž%õu_êñq¤>tºyõçø¢‡ù™þÑú[d¤XÍSz! "UŒg¼ø9çi%ÄúfY@¤ÄþÓÛGðÿ’í Ï5 ji³9"˜€Y$(%ikô8F±«²ãd¢¤Ób5ÅÍÏ›ð0äþ¿¦xø0>÷´½<¶’å´+ÀÛ¬I^é: 1’´ ‚P$q»âó0`sR‚uÔæ… Ô+:F•¢˜[0e1“a_¨  ˜ ø…á¾;[k VŽ­aI‚-Ú™dv‘ÏëG¶Á9pzøþµk¨XÔ.©ç ñMÅlHn×V»0xžJ‡±té’¢p¢~hZƒx#µp?8(E°Wt°UÌ\˜ÂIr(¦S'&œÄ{b ­bƒÌA =üªõˆÿƒ%ur4J#%ùÆ—ÔW·¤è3$uéæ/&éÁ Þ» =¢¾Â)¤­põ„]BK†dÚ©ÈG€‚›lÜMvs­ÏS®ðàÐÞ^)ºÅ+«Î wÇB¬ôeqÑæN\/2wèƒÈ›vBï#[§PÌm4±pÚÇVU²7¥±‹ þm€j<¨sCþ(œ+½ºù™;pb­¡X,×ÍunåèÚ›Bæ¥ï=qí úM­~UÚâþ¼ªÿ@ŒØÞ:´b þqˆ­_fMS7ëF&n×¾ ªúM¾ºúÝAl‚Y›Ð'½rí¬blËdo #¢ ínÑž.þ S^˼/¾Häk±j‚e–»G6ùá BÕ̶ /ª`?ÚQf´yåYëÊY+‘M²[ÖÅ"/–Yéw'¨|>ÖqÄh{J¦›b÷H¥ùëÑøäòìÃäìâ|ŸžGç 4ò«›&+TS º/öØj?è§ünõ Û• nUXgpü]ܺVè¹¶Õ±«+ …*KøžÚâ‹Fà”€ölæò96ÙÏGÖ=‹–ó›èeCÇÛrÓò©ªU_DÙrYW˶ãÒílàApngÝÜÖ®2ÀFˆ¯B0¼Qÿ&[‰©ž”ýù²·÷½Ðí>%e¹pÓtЫ6==¬ |^éŲÉ$g›ö³ìp”úÛZw¡±ATÇC~²ËõùVè~“„TÝ[0JD Çþ¸Òé¤ß‡¬–¦+½v^M‹™éDª]TÛDK·ÈE·ñÒ—˜œ“`Y’"vG½P>úœ†–>MÒÅš«e™Ií<´]@¦.ª•°-Ýe¿«Û/Ç,åÒ ëGÓNŠhÒ9Âfíað‰6 *ÜŸ0ÇÓu½Õp3m£ô[+ˆ´3æ_ª;”/2[¬Mÿ{ÕiŸöcêtÍ]ÏÒúxû1 'ž´Yº KÊõ)‹ÕlG§VÛðÕn-YÉæKy) ql_!qÈ•›0fâ€FÔ“ÿưQ,;S6¤Ú°K=8ºHß1+K½Êhˆù•ÜÀD$iÿ¾qï©ha~ú»nà;rŠËÝ·™éƺþ *¸ö¾@uÞð†ކ¦À#‘<&pÎý“»l9”w‘†Û8¤2 ¢0ݺó5w‡«>Äÿt‹Ì endstream endobj 533 0 obj << /Length 2330 /Filter /FlateDecode >> stream xÚµËrä¶ñ®¯à-œ* – ÀWr‰×^¹âub[VN›­-Î#±Ä!i>VQ*Ÿn4À×P³+E{™›Fw£ßôœ[Çs~¼x{sñæJr'aIè‡ÎÍÁaÈ?q"3™ç&s>¸ï7~àªf§šªÝlý(vÿÙª†V?öy¦.i}­ •¶Š8ó}Æ7o~ºxwsñLJ=‡;‘Ä%‹¼ÈÙ/>|ôœ à?9IìuùQi6-ý7W"žìãH"œ-ç, Úþ//ð²¾I»¼*AÜÐwÛ Ü•â¹yy˃o¶"LÜk­½?6pX¯­¥=)ýÕA³´Sº|¿B÷ø£:F„~EB_µ¤E‹¼m{‹ùwwfÏ" ÍÔ(g‘ÕP^n„ç~Æ3Ó"Ï}¦À– yϪDé­Q†êÐ$BØZš³K5ð[!-DŒÃþ™bwÈvà¹jûÝ1ïHJÀ.ú¿3ïøž‡ôܪ¡‡_{5Û)ƒbvö­bÆ>¼‰8p±D£oñÂN­d¡é³8I«ªÕ>EHÕ.¸ ˜‚¹&Cæ_¡ #t†Û"7ëxÉ–!Þ\âCS¦U•CM2Ó†Ê^pïž{]£ÒnYM,U«(µ)+5è¶.ñuµ ûZ5îyŸ_Á<´”íÞ3×­A3÷ØÞêâ«IË*5 ‚åå‚Ì>ÝãAö‹ “õ Öiíë‹y2|FõëFøIõ ÇAõKE ž¶3<ÔiÛjoF*«EHTËd’èâE-˨jö±A‹úýÛá+êļëŸÜ˜F>FÚ…m[:Ö¨ànuýu¹8jªëÉ)è§éÞÒk®aßDºñ´y×ólü~Ôñ¢œDÿ’ ÕìðOÈ/Ú*¢žtqÂwÿOU§,5í@N{+@”NÑuÞh­È‹$Á”4àýιÆÊ3»´ä@†Ïº¨- ??/½ÌÛµèHZÊ‹â¬%­Öâ¶²fÝÉÅMtùV'_¥­u¼€kwùî]J¾«û ™ëuˆ„`¥Ô9“IµÚ¸!&°Ôg2,ëx¦6ï$g>Zéû"§nòlw”°pì¦C;,µÐÖ¡'IwÊ2?»pö-™ŸÖHnĬjŒ —6‚x,Ž“eß½O{L h¢”}7Ù i]Cmͽ´¿7»je²K•2!¦û}Õë À!Âáåæ­9†ÃsenV¿né†IÆÈƒfiD±û»2'Þ7»€í«ò€>Ð1÷4°KÏcѨØá ® D? ï[»oîªC÷~Ahº§yȇmŽæ¸ÿ%·Øv+ͶˆXÀ‡¡Â½zìÒÝ'+k™KJæ½èÇs6¶Å~2¿XäùtɾX¸–n’»Õ®Kó-1©dBä”ã­=c¾ »€©Ê¶V¸#Ê„H7Úº™0¥'ÐÐ¥'2K¯ýÅfz9x"ì q`“ÍâéHMu)Ÿ˜…,Їša¸Ko>8\ž¹Ëù8)dž|jlë¶[–£}FúOâ žbyñ`<`n§§$,+:ÄHYe­–Ãã(º^P|Fßãáfê #t_tôf(ºåò2þÀ8†`gÂÅV£:0ñX0á-&­t†Çgàä’ö s®vf0 uúVÆûöñ„ê–Km¸ðb°Eý´L‹£"kC“yJã/þŸTWæÜ]oÓÒ'<œ4N³Ö»’”É–ã©-£»„‘û‹ö„ü2Æh~I+ã(f¹b¼â5ñèhdÙÓOà˜õýoÿ¼bk ÇP¦G•HÖòÜ·E¨&F^ó2ƒÖ²S–QLêš¹¼ÌͲ½«úÂl«jUŽ2Q~ƒäñ\IfZ ¦š‚lô‘žh<H³º'P_Ó¿)TÅ<œ!nuľ3]h`ZB;¿¡t ;€wyMa$L;ÿÙd1~ÚQý!ÌHC˜àJ'­L „iïÄh3úÈ“ŽP’òÖª¸¾ªÛ*ö .T®ûéØÕ‰ÖÀ³óaùÜRýéé/Ž#4+Ǫ'q{Õ¶:UëÙñ ìä|;:z¬í”ÞŽãW Mõj´sù©&Í8`YÚ^éÒp$‡ðÑvx‹óô^+–>µ³ÊŠ¢ªD¯¾íñTÄ©/àoÿõÍhhèD<£ÅtÿJ ã1óYã¡DûSZRSW5íŠO‡1㡜´ÊsLð:}î‰C&’Å¥žVpx_~ˆ™mNx”up±žî¸³0sp¹Â/œèñ2á!MÓ— ú V&+˜‡°Ö/æ“óãJdä"a\Qï¯×ï¾ûùïk#%¿G—¾Ô±îŸæÈÌzV† šm„7écÀjÙp%³jsî¶m~[ZÈfG•ÇqZd¯\Êê1Ò­Î+§_ì.ç“©‡[›\< çøy°ëéÔr9†[~l <¿ú[óéq !}ƹùVÔ@þZdòBÔ¯ ð£ùÐbðhÉÐÿjÎß endstream endobj 537 0 obj << /Length 2548 /Filter /FlateDecode >> stream xÚ­YÝÛ6ß¿Âo'±*‰Ô×}H“¦Øíõ’=\$´‘%G”²ÝCÿøÎpH𒵋4¸["‡œÎÇo¨hóqm~ºúáæê»—<Þ”a™%Ùæf¿É“M΋—lsÓlÞ¯¶IˆáV ½Úî’¼þ£Ä@O?M²OèùµhE¥½Äa’„ñöýÍÏW?Þ\}¾ŠY´‰isæQ¾©WoßG›ÆÞD!+‹Í¦:nxVÀ»ysõï«È”ž e–°OGaÄrö°çI DÝw =ï·< z8 Ž8Ä‚~OSU×w[÷Ç~R44Êz „ŸðGŒfP*Z§¦ÓIhžâ ƃÐZÃü ªö¸[–œz%šGö<€åÌôÁ,‡‘n”ã= [!ÍtÔ­„y"½F4.XfÇa™¦¤~×ã|‘›EEa’ÿØò4P4­ ·;C/Q,­iHŽ=l™è̾{™û~geOqþ$; ¼S0Í®#êÙaéCwÔwr<›Šøvö€ª–ÆOô.»Zžh ˆª£0B_ï‰l~"Dv«ta‡W/ž?ÑÛ%1©²¹áˆ..ùÂØ»(Ðàú…L Ú†0Óël ù­°§¶ªµT8j¥‚gÇm逄î”ó°d&"ŸRí!š‘ÅŠäýI Õ(û.¤óϘwþàµ:ZgŠì®_E~X‡yά£Èî4꺪‘ÙAû¡K öájqÆŒN íóæ$jù.b\€°ŒÇd|@§¢'4'þWôWBÇcÕê% Dœváx¨F³ _hîͲ¾+Ù©Ù^ó >œEYð߃è ç[\"»Äè¼ó|œ+Ëx ÷k¡/»Y¢Ó¹d¸íµóÂì¡ÇÜtGãćçlhö»RôBR>‹æS`žžžZgìK6ö– gÀ'6³U†ÙC»°š[³Ë„yÕ7@fBÙåYPÁ13QãÎyêi S@/º£™Ùùê…ƒ «-ŠY$ŠíÔèÓA²Óù¾n„„…JûÅxèeöÛPǺòÖök‡éBâ3œùüW…Õ «ÒŠ$ä©‹«j8öÅUrWËx•|.à,žf«þ+³_~\9ó -O-¹ÐÈì‹úîHÃBTYݶ‚Ä•¦ø) /’º@|ÚÄ,‰Â¤\¸(mÓN°<.3½<¦¡¡̃ø¯­f¨ô©"ÙÌÔ8ãLž®ÇñŠè—h§¨Àœ™ƒì®5´L'B1<ÜŸÌS¿'7õ°LD8ÇÂ+9±2!Ñ·›Sø¨‰¶"Š‹X|qýÚŒ€x\& *³u’’|‡éeì™i¦Ù2޹×û¼/™< |£ó&PÚ¥FO ¢V,Ñc½byþƒ,•Þ‡ÞÕ§‚£·Ð…!! œá‹•îx.ÜÂw—4âÁ¿`5ÜI…°’%1Z™ùŠ µ\`3°‘¢]5ð÷E™¹„¦÷ ?¼"R\A )íC¿×%}¥ûÓ­òߨ>¦…Ù½Y«>qÈxn_c|‘õW ¦Ù\H{×áÙº=šm;кd{ŒLÕ%Ø—FM¶hßé>Ÿ>ꫤqt˜-!m›½¸&ù ý¾f!FçL ˜ $‡C’ÐЯe^–†QRZò·ß¯ìX„eén2¾ ´:®dq0-s…ûýc‡±Kyk}¼p:Çù<Ûù}Dß­!€ìYÂ|¥Q_tÎ5ÄÀ²N# Ó•-³0+KOëÔÓz¶[ÂÂŒ;ÞÚ€Ì-;ò¦51ðœÍàùІzàÜÔ eÀþñU]‹Ó¨ š®ZqQB»Ï›ŽŠ>ö]’1ƒ–³Ä/i8î^•?}®ñ@b`hf…¢Q­ªC9óäÔI¦B"`B›ge 'Žä©5Ó£< åsbÎAVR±·cx¦¿Eê×{‹˜éß7„‡ <¹LÓ"Ç9E¥Ôt´©ÎÆ¿m‘ÞEID¹PÁcüC€¯kÕEû²ßvZ®G¨ûüߣWm¿½ºþÕÞƒ­ºØ²Ÿùçcù'šgžßÓ¨ü oøp¾Ã-‚ÕäQ„yž¯fsC–…EöPj ;,’/W׸D< w c(°9Ãó¥³NÈ+1æa*^ôIÚUG¶ìµfЉÇñß³ç!/ù·ÂøÐd°x³4ÅYäÿ£1©09}ØØý uè„Ro¿¿Ç…z´(¸í<}Ív¶ w‹‘ý`6· BÚ©ó%öY$>®Ä¨˜Lbî• 1{+¬¿Ç4‡~¥Hø\sˆö””þŒŒ ¡Ž»)H]<øÓ%‡´ëwkdÆÿY§Ê]QŸ¡þÔí¤$]±hà¨Sße½.“0/\{Hü•Ž;sæ|Ùb_ê¨4 UŸh:€©/-4äì `ÖwŒÂeûm[B¿·MÓà¹%2óºšj¬žbÏÌ}ðöàÐAΔyØÎËn2dXzúèÂÊ&ðb~Ô6rFJξWÑÍ > stream xÚÍYÛnÛ8}÷Wðmm bI‘”Ä}Ë&N‘^’4öX¤ÁB‘èXˆ"»–Ó6‹ýøŠÔÕ²§^ /–HŽfÎ ‡ÃAwˆ 7ƒ?¦ƒ×§œ"‰¥çzh:CÌó°t%òy€¹dh£ëố+†ju«V‹|ä¸~0ü3W+s÷æ1‰Õ+s¥RæÊ (v]LG7Ó·ƒñtðe@áQä»Î±O|= ®oŠaþ-"˜É}+¤÷¸¦h2ø8 VÛêŠ)(K°ë1ý”GÑ þؘ¼ªí£K!\m ~=%˜0ßØÆ±‹y¡åË_ƒ®AÈp|þéìj$†çÆçÓæëS4X&Èq9<-Œ¥Œ4vI a}¿<ðÌ»“WÏ' <êáÀ÷¶€»/\¥}îÚ¡ó1¢|j6âd¸Ð^dšK¬òHÏa²\'‹ÌÌ.fæ aAa3*12üš¬ÙƒÊÖfò«Ö$´0ámªrÜæûÙ S;…шŠá\u4iYàTªøX2VÙñnú?ÙÑ ·õ\Õ2©¹ƒ] öZGÔo#.†ÖœûÂp=û´oJ¥ ÝPòJ“ñؤţ÷“‹ŽÎ/\ô$rŸ&@p¹ËQ(¤ç•KþÕÏe`,p«¤¹¢x½I<ÚuO;“Õ¨ýaö{iÇÜ3Aâ@ !HØ$Ëa‡‰í¿õA®£B„Á(¨Tµòχ³^ðøÅåäl²+·”êÕZÚM"’yåÆk#Ñ‚¡A)ਠ¼¸1ù⺉¦Ï+I'ê‡ ºP=HÒ°dÒ SæïtÔƒu‹ {#Ízã¾»7RÞ‹D¡LÜ)ì·Nrù#ÿWL:YFÐLo77;ô¡û^E¦s¼îýù¾ïƒ¢PMûÏ·-9X­{‘$á{#½ë·Ëõ2ÙÅ·^qU 8Ÿ¶ð½ÿ’‹ûÀn¡ªµqh¤ªÖuTsõw>ô%.Á‰•ø¿=xke½#*] lP¥z…s 2†I‰=I»u ÃîaÿÉxr|uv9=»8ßã€cj]Ì™*ÏŽòNõ·YÓ.í±!‹’eY†Y¼M|DzΔˆ%ü\¥ö$kn¶Wʯl­Ý-Oµ§.0~ô‚v©jæ>ÆSu¨²•l:ú@åÈEáã—œ~µïQá$É—iØ¢Õu-ëp£2{}*¡úß§¥²‚Å‘¨ù@®ò¼lú¬˜0ñÓ”o‡žcó‰ÖÀ†ÕqcÆIÖÁë ´âÊ 6a/Íb““¶ÚØê ÆÑõœ“ž)\öñÙÙ¬½–ªC¦.ÒTEõi/ÉKiV6’T÷ìJ‹7# Æ^kAs›?><”­„’ì®CI¥E•>T^õ!6¬•|aG¿"a Ó²5ž·{aš¶'¶wX®¢}¹zßÚ.•Õñ’%Nç%¹I—¶žEb‰ÊTB«žbÄõ`ÃõƒG ª¯U!™-úpàdNü=jÈR÷|©¢D/{ïö cPq¸¬ãšÙ¾®™Ì#&†ßú¢ÔáÝóÖ^í%Ñùæz6I8MÍ+«ÿÃÛÛ•Ò |MŠŽRþ»í@5§O«Ýéúþ‚ýn<­ZÓ’AÁ/QæºîN£/D¥æƒ#ÕFeÃZP,Ò´­ë‘/0oOø˜/€Øx)…Ðñá<(ô0BÌܤPT2Î\3"ÕãÄ GÅëÓ_C‰úˆÀ P#kÆáò¦¢Vw÷eÁ×~¤ìƒ>ÒÚSŽ|ÑzØ+¬Ñ:X3zà—Ö’¦Zwû˜¶¢kÃK"i£æ²×’âKÒ9u€(üæékŽ‚'\ßVT§öT÷£«oá*.¶Ãž’afÅfFLÅ-!Û}¹´B—«Å÷dÒÒ -Aè©Oà¤Xäë“p­¶Å ¹äâÍtÙȿߞ ßHnÊ’ö3DïfIöXnNå™)¾Û³ ïŠÏTð@“«ûJp(|ŸýjóS@pSZ7aƒñ¸¬\¢úkZu"¤²¥(ô‘ŒM+ endstream endobj 550 0 obj << /Length 1685 /Filter /FlateDecode >> stream xÚÍXKsÛ6¾ëWð(ÍX(H|×uœ´ÎÄQsI2˜„,Ž)R!)»þ÷ÝÅ‚)Éiìx¦=ûø°/€{7÷Î'¯“_~“¾—°$ Bo±ô¢À‹dÌd"¼Eæ}ž¾›jjêkSWÍlDñôÏÆÔôu¾Í3sBßW¦0º1ôã³ `þìëâíäl1ù6ñA÷|b.YÄ#/]O>å^óo=ÎD{÷–jíÉ0†±ð>N>L¸S”±±$â>*,EÂÂf|Π"­¿pÅÓªlórk2ÐIñé²®Öôµ© u—WÛÆÍèk&l#­{±Ì”L¼ý±¾ñ[º:G›;‹Á”Ÿx!W,ŽB´Úûæm‚xKNd{¿éÚ„ž‡Tœ¾áŸT¾[ñ™"L/.ó€IØÌ_‚þi£¸™þw‚—ÞàN"Ãy!zGâ|ä©F,u²C&L‚‰µƒ»•ÞŽn‚ìè—yÐYñ£6<Çe:‡ëlžƒã$~ìÍC² ’h¸õýh¬IȈ¥F%Brý+piŸsÈÒÜëë CϹ﬊ˆ.ÑE™·¹.Ž‘äŽ$/ït‘gÇHÞ8’7ºÎî5DÕ\Aém»2z©nÍx›Óð•ÛqøêQZ'báhµ.›¼% ›ªÈÓúNW&½=¾÷½ÛûþV?PT3޾"%"/èDF3p€° ¬&8ž®å¨›QvØ; _±0ñ;Ú â ˜e5›‡°9ÖO;ýtY•kLFcæáP‘y íYw£å0ßß™q·¥Û1”yª·¬'@îm‘73_M[úm+1¹ó鶤¿&/à€ L4ƒ¹uSWÙ654QºÕ¶Ýl[Ì¡l6—±ÜpŸ}™™PÓ¿ó~¾]9a–Z·[§¡OC¾t®œÄ´6º.aªSÜگ벬,wz}4j£]]¨jsW H·M"NhF—Ž”ů¡¢øÏ/Ðà»ÏÃ~è<}ð áŠí\?õ<Í›M¡g‚ãé  ;È­BKgB–Õ¦±'om-iàø e˧*ûqU!¸÷$¼Ü®Xyúˆ–dÊ5®~#/S7f›ª1¸ËË›=Vϰëô©vý¾Ã\¨Uù… y³­u›Wˆ´ô§™n5-·+ÝÒÜJ74umŒ##>Um›éJ:ÏG‚‘ç[i;ÏÇõû•q[Á‡ ¦L«mÙ^Žs A*³×4‘™åÌfï¢E¿—¢7d~,€vÖÚκAÙðú£Éžq·?q ûvØxÆàÓœj+Sdã0Ðä­¾¦9 xN$çOUý•I$ ¾¾ÎËÜDQÖf{bc裣¨«6Õž˜˜Åª§8Át¹!˜÷Qζ¡èÁ)ëN07 vÚ9¸-àëã˜"³ße©ÓÔlZ›†˜:¥sÇ*­¦Ð…b¯š–zmÆ>x“SŠ(Ÿq|íO'b2?òN1@ŽÞÃnÅU’õÆ)½œÉ]M2.¸÷Ï}–K÷Ò_Ô©ß½*wÖ Š­§ö~ò•3l³Ë3À™û*{9 °Þå×öaÓ•GìÃò®¾—v«½¿þ› ˆÔôÆ}z9ãÞYÐû×ëTÕû3‡6áÚÔ{X×@2ÊÇÔ¼XRFŒøðÂÄ’ ïбt ¬ÙÜq˜?¡ùâžШ>]:LZ‡¾¦ŽøÚÞ]dÿeTI@÷‡F¾ÜÊ€ù~@vÃ[)5=]éÍ ³&Vz •¡Lo¹Ðv®!½6û*þ T endstream endobj 559 0 obj << /Length 1337 /Filter /FlateDecode >> stream xÚµÙrÛ6ð]_Á·’3 Þàô)uäŒrÈ©¥v¦ãø&!›#ŠTxÄõßwOɪË/°X,öÞ©v¯QíÃäÕäüÒ1µ€žåi«µf{ ¬@óFœÀÖV±v£2,WçÅ/òÒ˜Z>Óÿ*y³uó3œ_ó”‡%Ç…I,‹˜Æíêãd¶š|Ÿ˜p#ÕLÍ·€¸C|êkÑvrsKµà5Jì€ik«9ƒ1Õ–“?'TqÛŽÄf)±<[œòL­€=àu'Ÿi’Àu-! ¸Þ¤„Ú>Êæ›¸’Ë_¿F»™º”ê—óϳåARç—€Þ)™jSËŽdáýìòâbaXT÷e68~i³Þ9Ë!¨mŠâ¨Ã|-¬Öizw©žæQX%y†«|ã'A¾3!@\¢‚Ç<«’0Uð(Œ ÓÕøˆ“Ó–Ÿ¶ÝÊñiõFr¬ „)pQ=ð'ÅéÈlW†Mõß ÇÕ•8)¸€>Uá¾QÛI9šêÅÖ{T« Û&̳;·òNãVËÙ #êÝçåÕˆg‹2ï;ðu˜‡¤Æ@ɳOGzJ÷›$Kªc31!p(¢Ÿ!ê¯^ÚbfCks°˜´ÖÏ… ŸŽq:¶½7aD‡d¢|¥ÝÐA@¿Ž‡â™Kp¹µñç4Þ±Ù…eùŸ„åΧÁAlX±–Y•É_ïÌ"4ÿYS°ùÕ×å|y,Ë4nê)u¢Ž½" Š•2å b l nc²aW$Y”ì u åfú æí©r„@9d*Gt>@¬Ó¨õýlyq=ÿºš_-ŽEÏH¡+‘G! ´š……§Gùvf1î$%ë’+H•+4Y%Âì^6¸âְ؈ÈÜTWjoò³À•76„]cêùÁ‘« •Ú©|»«Ôé¶,HÎP`­–…B/ ° u¹ûµf¿ö¹8k‹Œª=íƒÚSc $@IÄ•©LÖŸÇg¯’Úœè#!$iÊó@í1iåëâ9}Ûö•B`2T?¤ea¼ÏÅ=?ć#Z&M [w²lâGñì¸âoXûðµ†uXúpŽ endstream endobj 564 0 obj << /Length 1517 /Filter /FlateDecode >> stream xÚÍYKsÛ6¾ëWðHÍ„^|õ–¦‰ÇÉLâFê¡ãø@‘°Å1Eª$'3ýñ]<(>DY+™ž‚À‡Ýo» [¶®&¿Ï'¯ßsb…(ô¨gÍï-ŸZ>™5O¬[û㔺¶(¢,ª©CýÀþ«¥n]mÒD¼Òí/"Q%ô A”"2½›˜¼›Oþ™X [DƒsäcߊW“Û;l%ÐÿÁˆ…õ¤F­,îð̬ÙäÏ 6‚nŸˆ€œQÉY±Jø°Óù¥UpĸGݰ8÷µn¹JÆó±ncû±\¸N\ä_1ã/„ÔBº®[ƒ·`+²!öÅBϦܵÿþ4u¶?ßÌ®g=Ø×ïaJë "=O‹±£ðë÷,è w ò†ÇPÀý8SŠíïS˜ñ!p—£„'€'â>Žóh%ÆÁØa³ôÁëý`ü¥\Rï½x‡Mèƒ;z3>‡ÌÖ"ÇÀ=Tc¦¡(¤LÓÃÊÒÅlE v—÷í.)eÊTŒJÅ!JlGßÝõÃËÙ â CÄp¤Gz¬ `ô2ìw³·_®oæ×Ÿ? BWO½&t¹c¡Ëa^h×"Ë*Ù ìz)t_´^giÕ2¨ŽuY<¨XYF«•Ì€røÓ2ªõçÆè°ÐŸ7•èv„v\¬Öi&ô×(Oto–滋‰¢é¦QšWSâÚfµ­˜M7Ä=‘H¤º]‡ý(g·ùÛÅÊ"™Á± þ€.dm¼kfv3Vž‚d)D ‡ieŸo€c„PŒô[nòÚéǦ’¦€8®_W¢j:Ø‚1{¾LÍŒæ©Ì$mÔÜdµîXˆe$#î·´(uÏÓR井úY¬¥÷5B”ªZ‹8•Î+ô\Æv¶ºù(dl _DÈV­Nš|ÕíQ™ŽcÛt®KOÌ«ò{Ùrp›xô s”¤ë‹+gì²Y-„±Vq?½»Ï:[S…‘ók ‡Ëè¥òݸå~¥–Úã2z6¥ßî¥?¶{-¥ÔË“Õ3óÕf6C›4«ÏQûÙºë§sÐÝ|›:Zd¢úß2Õ+"/ÃŒ’ÅIó=ñ9.E"ò:231Ž4fzVÄg»{¯Šý%Ú<*kI[ÿK_DƒAñükŒ’¥`ÝþŠ]œæ)X¨.Jx!?GÓn1u ØÙ"ÛÊQÂ$Ǻh9I~f¦½Ã†BkŽaÿ(ÎÂþ™‚È3…ÒóÇÈQ&ø²¨3ÇŠçt”~Ä3zÇQ¸MÅÝ2)°o êòZUƒZz÷àDÂáöÆ¡=:A‰·UsxEÑQÓ”‚o²¬ñõIÅפɮ)Û í®œß<ÿ!€?Fi3jÅßv/ßH %åñažïoà|0nsG=‚¸¶·ppl•–“«QHy¡D”ýÍlŠ‚À·JaÝw/òžò$”ÇQÀxƒP~˜ƒÆK]ñ .zò1 yâ”´'>í}½µ{äP"JÙpyŠ1ÂÞÑËSN=ýÅw·ªk|±=`VmHëÄ<ÔŒØ;нeͲý𥬹âÍßoÖé!¶¼õ8·îòW³™Ü@on®÷Ñõ”ÖË}áÐp¼Hó$Í›è½ßú[¹üúbçãpú%óEÉÊ1‰ëXìKq—]>‚ MRí‹rЯhÀ/ö+F‘ÛdFEˆþ…°=cíe}qÎc¦+L—™=2ôH¢˜¼Øg(FÍÝz²8ÚSúkŸÇG»ò›=V«û-µÿâXTÕÁ:$‰ ì’ÿŽ`Oeâ" | RAÙÑ`l62'%²(ŸÊ›cêýGjô—§ˆSHQ i¸uí·Ëh=•u†ò'õgŒCàñ°ó Š™U”'ý ¸úAg‚¥ endstream endobj 569 0 obj << /Length 2992 /Filter /FlateDecode >> stream xÚÝksܶñ»~¿tz7“ƒH<øH¿ÔeW‰_±ÎM[;£¡x<‰<óQ×™üøîb¾Žrt–¦‰=#€Àb±Ø]ì ç:׎ë÷õÖ¾Ï"9 ™Œ„³Þ8ï?,¹Z¤ÕUZ•õrŃpñ®N+ê=o³Mú õߦy×)}xŒsæ-^r¶>ùxâÁŽ®ã9ä’nà$»“÷?»ÎÆ¿w\&¢Ðù¤¡vŽôChsçâäÇ×PÛµÌb]Æ}«|Ï©`â`ðm>Ïc‘RˆÛ{.sE@g“L1©©üúmœ÷+庋³¿?yùæÅÙÅÛé3øë:+.a¢Ýo«+µJÊâƒ+äõr%_d5µû9¬M–´9ô¹»ÈQŸiº­Óm›cß[l—Ò]”M$ånŸåYaÐÅ׸2Ίzé23HÍ8ÕÉUonÀâ<›¬,s›…Ÿ‚ø8ÝØ¡ÑEY¬ L±‰« rY@ò äe¢·b°?Cšð,œËEºjñŸ¥Øís­fÂEä ÇÔãÈ!õ8JÔëùC8$w¶ÓgÁð2pºÁP¬)=-÷Í)Jì”`G‚U HRZЫÖl b2›æÙU¥Eê.²´#df× b*è7mëêy”Ÿ†¹W"ŒôÞ#¶v:Á•»hˆ‘ }ilÙ/–E0ò §Ë6ßÐç¾*7m’šµ7¦Có¼DàOZÁp¸l›}Û|KJ·CÉÈ™¶æâÌMÁõó`ƒ2ßަÃCûà|t4³J— &ŸÉÎd2Á”Rz8‡/Ÿç¡‘o&<&¤àƒá$ƒ/° ‚zy71©ü ê1 ×€õ;vC  ì>r»a7âöèÜ~»>@»Þ4®>Yò»?ßÖùÑ݉ÚLlžw A^ÿFG«gÏ »$“p8®ù¥ÌLÇ/;@ü²_<0Œ6Ÿ œ üRK¸ƒm„k¸3ä ²Á,C†Ü—_sü—i-+W~Ä\[¸]ÊÕüÔrl}¸ãKücDv¤¾IóÜ\n‰Ü¶41£í ¹?t`èÐjƒd5A^­Øf×G ÐÛŽÑ|íÞ`wÁ^Œ‰£;Àû⎜NWƒ3zÐúcEr:Ö‡Épü”ó µ¨öqsó¿¦â÷)Їi#D);Æ$ÿwäGJâ.,*©>ï›òᘠ˜¿L«jbÆî›—Ls0HÒe¡ðûÔG=NêsqvFYß“¯'ÔrW;ð@âqCŸPM5µ;“)bou¤éDû_H°„d¾ßEÏßPŒš$\cà÷ V=ÒçtÓ>|C¾lùé?7o1ã©Û"›‘¾€¯°#–y$ü¥T‹¼Z®€ê×o.Χ 0,¹;¦cN„èÌ #+Ä÷&Ij‡Â4”_#©Îì.[,P"–ó£N;~ÆlLYü#2=ˆhñÀÆu3$k]†}•I¶óË"Þ¥3ÔD¸*ïKMÐQ“ÌP½žÞºlõUIÒË$N–3ߤwr°âx–ÜÎÉ X¢øñ¸æD…½¢Év)aÓHýY¤‚L‰EºŸ#²·#ð×$Bß°Ãñf–0ÈãϸGå…÷§æÙ, é~…Bç3*2ʨ,“mQoH•³YÍYI0~Ê7Q®ß“w–’ûž„_òWjþ9³ŠñÙ¾„¸¿ç5Sö7èþD¦s  ð,¸è]\læŒÇ‚``Åôž`&€£×5}10špOûFª©BØfŽH2¡: Vñš.²ùã„+/.@ÄXYè÷ž’ñÇq>oÏ~|wþöìåÙ«5äh‹{_ª¾lmM¹q£¾ÿ‹[¦à5)0*;[Õ]áLQ3-(bÙ¬4¡‡.ÇŒàíñ÷·öŽ% òÝ< ÒP[]µÎ’ÕÖC’-¼œ Y<ŽŸž]|÷öüÍúüõ«#䋱Ŋ‡Õ}ÃP3>{¦R5ö-3˜ó Ë-µT‹q_•×:Þ©â͘*3ÌÝĵYEeUšße5â­¿…kææÂ`Ì,°«Ó¤­R[éÇ™å& rR!AU i“B¤‡Ò®iÒdFŸfjîmm5äüéX/Ì1°®»Ôc=4M§F–…MœM4 •Ð3[eõäfíÍXÝ)«ÑF£$¡æ³½L…-e[¥Åÿ¨=ú?“GoM ¡òÞšäo¼5éÂØÈæ.ݵêý ™Qb¤Þ¤ßÎ9/pîªóÝý³†”†;Щã[­‹ô¥9.Å"ÉãþܾÒÌ•þŒ ÍWé–5-ý’€(KjIØiƒäªm,í0 À( ͊Ε·d.†€…‡‘Oѧ Ûgž«ìlsC½.w1M@/¹Î8à–oF:‰ZÊ®™Q¥~Y¯iˆàŽi sñš¤˜´I¦|¬»‹„yÓ|‘Ö£Âeuj5X Mç”ÉÍíÔüÉ÷½8q’”ma> +Q秬Գš•æÐcdxÚûÞîSt~äMx¬WWÎ9óUÐû†Gzu}‚|·þ+çßaÿÉ2tGºŠõ2rµ¥ÑbÛæø«EŸ$Fèà`Õym0&]_On¼ —û´ŠIà _D5šÎÀÇ|DŠ®@pðJ-lQ4Ybä€4 ;0YZ?Õ¿“F‹·Zê2××–.ìÚ¥“ø®Gˆ(+s :G/NÖ[;£ãCükt5Ýø‚Úñi€XˆÅšxÆÞ \›iF.ûõ>M²ígú¸±$LÈÖˆzBézXRg²Â\LSùq°ÌW]¦QîÍÓ·>µµJ‡µŠ3)&ˆ!)RS"óõ_÷íUž%~wñ;{ún.Ìï³W]ªZq.Ì[8§Wo±Ø€]Â7ø6oh|Ê"î`Ϙ€»2#1(íuAïÞø3Rœ æ&µ^—œ%¹IëÄ;Z-H¹aŽ´^ëí‚>j BJÃs¼“_§sBó"HpäoÊl,1²õ+¥£p\\Á­ÓÃY£EÐÛuñ8B\ÙÕ„FN”ùOhÛ]Z˜t vàOÐóù2hÚ¥4 Z½•þ¹ÀV¥Òº>Üq gs¦óíŒJ°ÿBtjÃæ‹É¾ šÕFKÁÃ(wÑÁRƒެ]Á¡©]1E@Ϩ,¸J;Ôé¼õ`AôÅûÅ$^WšÒVéLu&Úò™×WžŒ&È D®ÝEG4 \§Ð’D°WVGœDÖ{ñ¹füHãû…cgü­ ¶Þ¡;€9úŸñ´¦1qdM`û–ÆV\5±¦dhhôÆzþ!çøOõ9_vØ;Yb­ ïâst6²èîÐ,Ò¨CzpÖ Ì0Î!0v';Å2Õ± šLÇèÖ\mÖ†rÏÏÖ—kLÀŸ#W×—;rùƒÿ'?=-‡¬/o°P" ÒZ›êM*Œ7ƒ±+£` w½ n—‚`jabÿôÈ.%™&hJB‚sï_ÅþvPHüÝÜ þ¶\ù2¾':Rá|;OÉÅ”¤ÿ9Õb— endstream endobj 574 0 obj << /Length 3750 /Filter /FlateDecode >> stream xÚÝÙrä¶ñ]_1o™II4V¶v;>ÊEÍP;ôrÈ1ÉYeýõéF7ÀS{8v¥*zâhF߀üÅ«…¿¸ù䙋ÄKB.Ö÷‹H."{* ëíâ‡å+©—Y}—ÕU³:“Q¼¼m²šJ—Ç|›Rù&+²´É¨"<)=±úiýùÉÅúä׋ù A“+/ò£ÅfòÃOþb íŸ/|/HâŃÚ/T÷X¼<ùæÄï#Ä#D…ïùADˆ>ìòÍJèåPbù•Ú]VbÉ_ÞeÔrl²-÷Uô}evÙR%¥Ïúr%ýåzûKÆ_Ý»ÝD5•ò†¾EõŠæâr^ºÎöU›Øõ–W)d[e<¸¬ƒ]º üå›UÑxÆ©É6Çš§Ý¦e™x"éð:¤M󀣫z‹§$<ÂK´&ZíÍüˆˆfªÀ7Ãÿ>T@Øo´_è)³¦®©Ò™.¯ñÇP ÚÌîñ[2ÌŽçܤ„%WqÏ€Î'Ï w’Ò½$IƒÜåÅúçõ ö|¹R@ÿŸÿyõäç¯ñž¼|ùíg4~À BD^’Äv¼E†¨ …mö£¨2Ûž2Gd ØGÚæc|'“æE㮵lç{Öð= “†bQCǤñæ’Ĉh,©³@†°+…À‹CI¸)/ôôp…^iñÙöx„·ëç×7Wß?Aò¬¯®_ ¦‘ x@*˜$$TÖ;C( 10B!±š ž4æ]ÆH°ŠK;Ø ù#°|‡3UÇzÃe– (=Béus¤‚]Æ2zEµå1ÀqÕ±¥ Î?e›Ô”–Žmβ9ÖÚ‚TÄÝ0·¿|†ËUŒbJémþ0Ø&ÊÐY c/ÒÑP”æq ä”~jÁ5fÐ&ËFrtý5žîKÛ½¡}¬¤öü(¤@VÚ·HÕƒÁ?ÒËæ¸ÙdMs,¨>ä\3|4‘bµ’‘74NT),¤5ÂvºÚL¾r“Ò‚fÌ›n]ÇFæ q’Š; ŽƒÔì XËNQùñòªœÓo4A8ƒbcY)  Áíª}F½Û¼ò2šoWЇ &@¤m›í-4øc«ÅÛH÷rÇœðê¤"kþF"ëDü*P†FúÇFÏD~_Dìù*±lä½Ö`òò]z †‘Afð¡°A41uƒ"%H\ÚÏŽ‰ÓŸå!Ö“CÒÓ¶Ø¢¤Î"C­ÈKkª²Mó²1y™î¹T±áIé3a*3*Ÿ){!XÅöxú :V²,Ô¡N=8Óˆ6)ÝŠÌž™I?ú²Þžë‚óÈzCaì…"Xh6Ahñë`<)åبºÙ/r’¢ÀÓZ›æjÚÃ6PE!w/Pì5‹M¿–xQf¸mTÂS:Œ’nF%¬[Ñ5m`JW)Ü‚¶Åï¦ó»å6XhßÂóÇ7;Ûüßïï~ñ͘'Ñ(žø¹tA~0ý~,;R€¼dr)OÁ椡—æG/Û@ôrµ„ MUå{¡O¼›KÉÞ2P!êôé‚Ëñ0$ȇ’â÷ÈÑÄâ¯%åY˜x¾€/ŠW"4ÒÓÑ(ÚÑ*òœFêùõp¼+ÀÃ%ŒÛÅ?ŸA ©ã¾Ý~ˆ•Ó­ÿ¸}y>r'¡ý13ZhF1p޽D:7aèBÃÅg·¤ŒC8˜P uñh7ï_Æ|2^CŽßI(Fù_$IÀpFAÒíÞØßABcý‡ÓC¾#à,QžP‘‰?²ÚEA0¤Øöù*¶Ôhl2|ÑO@k!_hmíØŒ8zL´V~6Ù¡%x7±éÐÆ”º*w´Š¢Â)ÀXy„pСñ ©ÌÀ÷!¿©ö{ðxÒvs¡5ã[~»a·¥Í±ewãG_û×~&n‰‚làðHø=6ØxWuîÍ6k1ôü¬Y¦ià­wG¶‰e~O_üÄÔφ¶É +iOXq¾„ÈÑx¡Šó%ý™Ëijλì@d/êt™ÞÓsRœ÷ÁNë¾{3rê*ö8âšc#ŒZ1&â¢,U…Q”ˆµÙ6™…°Ð‰Öhoèz aR/Ø1RØ6¦0.BÆÞœçíQ«.²Fè´dÉ1KÔÀyùŠj¨` )ØM6’ÁšT¥Ëu…Êʧáåò ¤§ddyù¯3Üyq'œÊƒ]„çùð¡Õ>´ŒßÄ5!åµÊ¥µ²Çg¡&É V«ì FRÝ)¼39 \‰G¦‡C]ÙƒI[Æ ÂmQ¨Nüº½LÂ]#‰àOÉD ‰;>÷ó6&‹ˆ%“÷ÂÂÝ€2)%¦?ÇùgcÌY™"…>%ÿÌt–JX±ò7™¾¡Yy~Î٘²”œÅÒC!ÓùË:-[Qlé#ˆât‰ ÇlœÊbá삺zkظ¯‘» %äìïEmîáÌQþfÑŸæÃ?&xñÝÅù­Éš”ýõ3ú®Ÿ_paúáÉÍJcB–š^>¿øòËH1öÒP"¦¡ >IÊÄ&Åã#å¥â4 €‚˜m²Ì˜r€Ïy‘”×Ê÷y‘ÖT¡Civ¹Å„²þ `„g,%{>ГQ>2¯«rŸŽÂ¹?–ûj›ŸÍ©;” c[|i,–æ9ì Ðo¼è¾}yqsJMϯ¿º F"ˆê¦÷Ù‰U.w̤""°¼b0µaÐÉêzÍŽ …RäÐPWU{Jwˆ 5ò`†m2†5Ô{ÇZ3äérÁ(uœ€›MìæÅ•¹0áæ’K{ÙÁ—+<ÅÓÊ ˜nÊgºAÁÒ Í|mÔ™M)W]j™ £ï/É ¨^ªÐ(Iâ§cÁ~JqÌšYïàŠ]—t»Í-+ÕyS–wcrг9æ‚MwíñÅÍS}~þÓVO€3–4ðtwKÒ;\%,]¤sŒœsÕyl†[•|·Ÿä.|ø„ָά˜Z_¯etJù¢‹ÒÙ2ð” gùG«åÕgøÕ|¢Z-GŒA½¤ô•KjÎ(Z²ë™Ô2™e´¹î Tȸë™,²VÓ,2´5»Ì\:jv@h½’[f¯:ÇVo k 8-Í!ÛäNÕ`Ïýˆ]\‚·>&9úgJÈÁM„A,àZ¥ ƒ í"»˜AÒÜöÞ ¹(²ÖÜõA§üpp)hpÒþ±,8ûu3æ<Ù<å’5-¯7•…ÑmèXþìõìå¡édMõ!„^$Gi¾:ë_|bZÅׂw½ V$zíœFŒ·*çn¤ƒpìuwMj–Ò6MËSõÑÜYºfÏ9ö™6›™ï£ÖñOsb¢?Ɖ9¿¹à»ÏƼ$Gå }^\|ËŽ ¸:7WàÅ9þEMçàØ\¿X_|·þ‡†Y3f‰¹ãü¤9¾bÐx-÷¦ÔTò>P›É«‘‚oßR?Þ‹Ð1µÓ… ‘ÍQ@ëT¦bô†¬ ½'p+àà¨ÇE2îI´âõb2@Oõ̹7yÚ%RfnøcïËj_ÌÉ!xhºËMM°7I›Áæ¡%/­o‘·œìa›lœª³-º¡iÁ€÷uµ'µl 徑žr’ªçpú«ÝÙä˜[‚ â¸Í,FEÁi‰çëÑ=)]km¡0Ä3 Hù÷!–‘êX¹<Gå"~l¶> ÝÔNÖËê/ꈵårkÖh/œlàÂ#E’„j€O@T{,›Ôø8¦DH¸,À…o¹iÇ}Cü”æt‘¶´FSLžHØ©2…†Qžq¡’мt²ŒùÛ#OºëÒªž›Fx¾êØûû¹Y¤§|=~ˆ0ó¨AxRGP‘’ç“ٴ͘fÕÁQ‚m9v^ñðæüþè.·¦{잢â‹„šWØ9ûÍáòÓOˇ3ËϤžÎÅ% ÎL =ðwÞ{È"šdffêLÂìMNÂ?ØÞ œ´€yÑЫc¯§{µr<°{$Šîµ) ]VÜUS­8wÜËã†9-œ,MtQµ6d"ï1pvŠž ôƒ)lª²9¥€ß½çátÛWBR‹ î>8æì9ieUžQ ;=Þ02wðï“»h>ï>~X0Œ1ÅTmGOªCV§½g<œsîßîr£¥Zš“zš4‘Êl4r(Ò 2yziÅ:C¦-$ÇÐÂt–ìHc¤ › ¡á+EÎcî©eæ5à¸Lò&Ú9§…`ò­p-£Øòbö†^-о…Ò¢­acX=¨BÛ0PÕ˜A™ ±Á+éå|¡ÂpøøPŒC5ûÜS :ID``Ë F%ìÖ@sçË¥ÝÓ騻=Ý"@®Ã@ÍdLÛVûCkïKžÒç sjîe0ŽÆ›æ¾ÆÅv3Ô’þÛ¥ÇTjÐÝ©J(Í„}±ûÁ÷œ´sEs—ƒrïH­F øI0*0—Ü<í ?)—t/‹MÅÌŸ jlŠ{ˆPÑ;1OµŒž¥üIMÄhØkħªí”FÃ÷'œ°P2 ¥Ãiö;ðùú/v;£cïí‰ò‹ÒÙ¿í|þø„õ¬ž³ª³–M‰‰¨—‚0T.ååÑ꽜ÕaJÕÒ]`ÔÎ:Xr2µœÕÁÔÜ%bÑf}K üÄܬÕv(¥y9ÒŒ`ôs:Œdè𙇰ûª§¥ghóPW6[0¢tßô¼=XU‘Ûg¤D¨Ço%ÆOóµ‚ûƒ_æÏþ뀒žæKe"$­—ç»ô°ÂDs)Ä“ o™TÒûgwß8Bñ?ã" endstream endobj 507 0 obj << /Type /ObjStm /N 100 /First 874 /Length 1567 /Filter /FlateDecode >> stream xÚÍYÉn7½÷Wð˜\Ødm$Á€( †íCÁÇFŒ™@–çïóª5Zf‘Ù$V“dm¬bq4YH¡Jü¯¡XhrFc!«Mró¶F·æ9¥ ê-¦¶FÎFeCÕµZnrÃÀ%5ÅËpr2ŒÏ”†÷"Œ¿ÿñgp–XÁáòÓ‡¯‡Göãh:L=ŒHŠ¢÷p\slPX'ÝK7p§«åE89 ã©{km—3NáçBëé§Kбþ€Ëð tůGC`%ÿÀâãóóÕÛ—‹‹pÆçÏNÃøjñù"\ïûê¿xó÷bŸ‚‡Åòâ#Ø3/…ñ’ò²Íë–¾Af„¿ú]ò:3Â_%ñƒ§F\bÇÔ›Wˆ 6X.)5ŠSa¿fG÷4™ÉÇÕ‘Ó3n±ý%d{’£Ì¬SeFº…1$)¯”{8”Õ±¶ÚÇ¥ õy8Œ¿ªtqMý}=Pû£Ë1ÓÞׇSÝ-‰¥O¤?nL~™è:näóµ|oY­ËfNY#kþž5´íXPË< ÚŽu]+éºVÒu­¤ºn혾 É5M±x]­(Z3~ðr劌۳¿ÆÌãã¨!W:D°kFù¦gõŒ5U^ž<Ê-šÜÔ²Ä íÃq_@F2¨!Çšý9^ÅŸ°‘2é¾@ë¼°»#EmaŒÚɺ85óÛ…Á«H'PDÑþ¶li&ÛÂBmj}X²X¾³#Û}¤4ºW¼%¯ñ> stream xÚå]sÛ6òÝ¿‚òL„’™ëMÛ|›^Ò&îÜCÒñPmóL‘Š(ÅMî·ß.?ÇN®o—™X$°ØÅ~/Œ£«(Ž^žüx~òøE£œåZèèü2’Z³\äQšd,Éet¾ŽÞ/^ µ¨v«j×õ§K‘f‹ßújGO/õºzDÏo«¦*úŠ^8‚ñÓßÏ:y~~òñ„Å8âQ*yÂÒ8ÊÍÉûßãh ã?E1“yݨM”è ~›èÝɯ'±ÝmlævW=¼}9ÃÊc&2=ǚ܃ÕÈ@Ë‘ —Î3g‚Ø}ÊÕ¢;åñb_=A†¿ÙXf1Ó±dúÙ%/êö ¡Åa]µûº,öu×¢¨2¾èÚ…úA’,@ÂÚüSí{;x]ì ®ìÍšWvE·Úu[­ à¶Þ_w‡=MmwÝ©T‹OõzØ m‹¾¿Å¹ngÑ;‹¯,Jd÷Úa¬[·‰ Y––Û%ç,WŠxî»Ã®D*0£ûc¥Í­A§XƒúZ½ù_ÆA  zÐ!Øæ†ØÑàÛÁÚiç©:€8'F¦Yf÷ý­d¢÷KÇ‹7¿œŸ½yý.ˆlfpq’ƒ=ÙM,[2²4ÁÀ¦•:#Û»«S‰6r±sy×mYo‹æ¢-6Õ„æÌX¹ñ;Ö®‡ÉÎbüs°½† bwÑ]ÒïM0ö…²ã)Ë¥ Ugü¥Üû€¼>£'÷²TË‘OÔÂcÎ(%žªe"ÎŒeƒVMD¸®.QVÅ¡¹GZÓ‚kÖW­ÛݧÚb£—§ ˆ¡iŒoß’gÃðuåâNj?™™AšŒö½Ì!Îët*¼‚Ç_²H Æ ðSŠô@š?!u£ÀĈ¯¶k—»®Ûß­¶\X.ñanm9w8aÖàÀù@0mª €?RYUŒÐ÷Žò¾û„Ýœ)»KÇÿÈGAs™ˆ„ä‘9­g£¨Jéc݇ÈP¬{z¨Ðþ°Ú÷«[‚÷x¦ÏF ÐV™Uü’$egcÓ¸h-e6 N˜Pß7] AiWÍ&à=\@ì̽I‘i,ž1Í‚I$sœdƒÊá™BÎÎÍ&K=ông¬ë±”ÕbÑ C[A< p ÛJ‡ÍþgÄæcv£ˆL€G. ½i·¬íB¸¹fI’†QÛ´›€»(>Êjº«:—dÆrî÷:· ÉmHgž04µ 0jé½fë>ĈR,NdÀ.ÌVM~ºÏ*Ò”eR V±”"]¼1jÁýÜÖ=Tœ$•”ƒNä¬1l&þ@ Ä)cm=>¥Ä1$;'˜sŒÐ•†d„YU6öžj…!_ ›nØz)Uq=-¨/é×’MT´ñ4ü$A"™šøc&˲êû¶™Í£‹&À²î`,]¸tËóÅíueE*L¨0¾ãÆç¥1xmª«z_oŠ}e!'%*ÁPNò¨ ;|d?ÂV0GVÞap¥äô³êPu¢k×5–n“»`<ݸ ÅnæŽì»ªÊnãJ Ÿa÷ý¥ÍüÝÄFi쪳Hº™–¼2ˆMÒpÅaœÙŒi%ŇXñ)Õ*;\å7¬à§è—1TCÙ4o¯îÚÅTdÁ\0, .ïBL "Œ–c9+‹X,ŠeI$ºA­Çr±'é|¶P¦J´/G‚3«¥ÃËíuM’¢WçC±­ {agæ>ƒ ­_E^ðD’c¶Ið—·g¯Ñzž^üüæÍ«‹þñü‡g¡ÔóÒ¯=´Ž©øÂö ¬Þ(‘ªr¸;"†bJч(¸®ªù_ ?(:ž&‹ªpžÄM¢üÚ¤n{ܵIða¦1\â4¼ñ,÷6i [9RNÎ9!:Åž–\#SÒ½©ð‰âŽký Ñ<>Lìa¶® ™ Åcå$®Vþ¬<ÄnÔÁMèñê éÿAoGȽxÑÓlЄÁm²â/6ÛÆ®¨/g+é•’¡¬¥’ŒgÜ™ã¿?n«¦.¿?{wæÊZ 1‘Æóg¿…l;c±J.t°ŽÎe:§÷¸¯Jp8CöÜB0­ýF·ÊP4’6ÉQ4’îT"ÑHŽ£‘L}Ýkfu÷Q¨4‚â*eZÍúnîlÝûr't<“â[…r|:»³ŸÀ5Tâ±üK âA …/7´SŠœ uêði›zà×5(üâ– =š©ž`àÈI 9)á "gðÿ/8*/e¦Ï›žšï’\ÔnןT’‡;µRêq‘!¥š{£CÀNxÇ™£3 ï8kN30b Ó êh`ï¨ÍŽ^’"×dUpû •Q’vÀ®p)½u•oRYGšãÑÿÔÐû²s‚¿³,öMF4À\&÷XC†Ç{=ñÌYýê—Vý#×€"˜¶OŠ¶â¡œM(²QL[‹Ç]å»ºË SROiúö2ϵ×>´ÀóÔ%Ñå*®Ø{Šðxÿà{XÔ+Øì‹³ŸŸ?y¼ßlo>ã¶ÉÅQ6BÌ]èFÜ”¸öoÆ`nDé#âóZè¶Ô²FP÷økì ™;˜V8Q`±OÊržúuÝjIN „is¦™ÔìöÆ'±Õíñ擌e¹O–¯Þþ¨ž>5äÿ|`lE«¡]D½òz×µê¡OÆö­Å«Æ5ùò‹!Z m ¯¤o<H’7&y±œñBiÚâ7ÐôC%àô/£èGâ_<Ð+áEtìáé'6¼•ÿ^F¿F`@@~^z«ÀÏ$rû÷kMB°6¯­À–pŠ È)Íx¹˜ŸVVÔöUCÔ†~Àųx!éŒå‚LØe(‡Šâ[|éè ßþ:Q.ÁÃð’d‰.–rŽò4ßLB(^”Æ)l•›¯KÆq”çYâ|?P(|é¾ ˜ÏL<äkÈf†"ýZŠË›/£ÜŠq{†ÇT‘Øp'°ân*jâ»NðažŠ„šDN9lÍE<Ûæö¦nÝõ¼°í…ûpö×UÓÐ4Ý$&à#µn³¡~™HLå('$~J4ô–áêŽÅ©/×,VWãêážî¼ë‡ õPìÝ<äª_䦿Gw–èi6½w!‰Ï¯B· GÍ|Ù2ÆË?lv[o eJg¶ž+­š¬±O¹up¯bø< &mu¼Ú×eskÒÔ=`UÀZôtíoÁð裩1µà®\õ;hjªbö»ïæ‹nϼ(ç*©„Áû¡_­[—b`eœ‹á[£Ó¥NÀаt°–¹‚åÂp„šoé¿í|å‚ endstream endobj 586 0 obj << /Length 2696 /Filter /FlateDecode >> stream xÚåËrܸñ®¯`NËIy`‚øØ”NÖVÙ[•x×JR¯ËEÍp$–9Ã1ÑÚ‡|ûv£àp´–œª¢ƒ4^ýîFc¢à&ˆ‚Ë‹?_]<})y³<‰“àj¤qÊŒÉ\WÛà]øã*VaÙ^—mÓ­Öqš…ïÊ–Z—Cµ-ŸPûç².‹®¤gqÌøêýÕë‹WŸ.8œ6—,Ò`³¿x÷> ¶DLäYp§gí™dð­ƒ·?]DSDE6A4OXû¤ˆF[3^XØ¡q¶U-r{0íÔÃÔêà&&NhÁÃiÔ ž†hØ67V7œ‡ö€yˆ|N 9Ò«ƒ‹[†2“Kà÷c7`#Ý”æðK$äÍТûÓË @ãþØ'™.©ÐˆÒçGM³MépûcÑuw¨”M»]¢ô—HEKªÊO­†]¾¸úpµá_â‘Wþñêù‡7«, Ÿ¿}ûÏS© â¯Scí q)<”[8”cr™~Ɖ:5RX0·å3ÓœÊé äâ¬ÕݱÜTx´,0箪kº6§_·¹ÃœL{sH<2Ÿ_&öŒÎ¥8ïc¾ÒQŽà¹K_ŽÚK–¤æ%Œ¶ÝçÍ—|æÃ=Ø9÷Áˆ.ù©*m‡¶01Kk·®ÿ†¡Ü!•IøÖ‰éˬÀjhäÚôÛò*ãPÒöZp0<&ÙÓí|†ÿ Œ"J)¡ÇAm 8ß…q€ZØ¡é £þ Öæ©ÝÞO×—üÈ‚¸gÇcjß‚[éˆOÓ¤Ûè'B†ìbûøú˜sVònɽ’çâŒäô|Ésa –Çç®ÚÜåd-ʾ<”˜yÓìº.|T,Î’“4 q×[:RëÀ–t À£NôcOª¨1ÞÌšÎ'p²n[vzwò. Åó¸ÓëvQMlÂ伄Ç#´áøÐìΧMãRô÷%ªIÆòÌéÖQ§ï Šî×êœÜb¦Ô‰ØÐZ±AûÚp`IlèQØË.¸0)²¿Þ|¿2nù•åWβ\>_ÙÃà,Ç08Íø2nœè2ç`xâD-ç2¾ ðàúJ4> Gæ@r«“uþEFÆ$§ñ$«o¿dpÃJå,¸ÝÇÙBj¤/QÄœ)w°ŠÝC¥ìiéC-‹]ãs‡²nZrlZúÛ3rWà‡“äo(iÂD”ÏXøòÑ,rÆBá"„çY8f0â ˆâ"–ƒBË&UË¡†GV sËПXŽHç–óµåú4À·™XÎÚ˜‰Š˜Êæä¤\§³'ÌS hìØhÚnÿ›¶T.çB¸˜°iö{Œ§b•p ‘N®ïvòn)E{Ó»,; 74TúŸ÷÷^”O…Ïf}{‹3…hS–[íÁ¤­è€v›ÞUH3[Á‚FGU1hf 9MV=}I ê£V•†¤°¥UX j†~Ü}p%íb].‰’4õM@§¸bZ*½EÇåžh òv2 ¸Ìm'“#Ù³ÂuÁ²HÍæmY×OHûˆÉ“ú2í^ÎkKþõNEV¥°¦ô‚²?Ö³"Á¶cÎSìIÅÍ{ñ ‚ÍtX±4‡?½ÞS¸Ã&`5ã–p9§yã™´=]§¶':H4îçm #`väæÓ'Ò´mþ(Ü? @¹B‚ŸK§ø–›ÿU‰”¥€|N “9^Ó4^H)8†Y1Ì +ÃjÓMX¢’l²Ï&Ç@‡¸3å a–!C¾–±%ëç_ËÊ5XXa@d2æÈOýz˜òÓ×ÃXj¾Nüµ[¿n®±Kd¼ý§ñò €NðN/Y{ÑA×í5¼î¾y§ЩSŽL,M&EYÁðùæJý¥#}QßXp»÷ãúÂu:ÎX’¥¿&ÚfE7Ý»®uê­Ã•ÑñÖ”³ˆÏnM¯°âÉM \Ž•S®¨rª¡º ¶Á„ [M{~¾ Ÿ=£Ñ“'-; Ä-Á©\ S—¨1+(¶v4íXö8}©÷·éІZœ'j½T¨¥ÃQkvÄ*wTÅId¨Bhµ%ÈžÑ7ÒeRº ÉSu.Kâÿ¼¸)û¸ÝSöQQ±x©<ƒù¸œCgm0Ù6^s“÷&6úVù5:ñUÌCJZ«º3Äþͼuã‹VW>Y T=a<Ÿ¥±¡DŒ9Ž£D?SÛgQ]V+\"e­ÉZÏÉ‚N9¦xõyé¢4†œ>pÙgÈIêíMôXWnÙxçEBü'.kùަ\8R9Íß÷Eÿ½Ó¾É6Ïaß!-ÓË }‚-À<’¡¯eŠpóPB½º:è=ÜÅ`ûÂ<ƒcçÚ1óÂä®8c2»°»:aáÉ;ú[ë¨7žG™ß2*3}Æçs¯<±Êæù%ê.@ŸÓà©`3û¶­²sT‚)8*¾Î,Øn*Y2–zþ¸ Ý)äÇîwû²ÐOÊýÞCÙ27œf=Hf¼uvB?Í_¦˜öp¿fÀ“Z¥ ‰C÷ÄÖ-Áyä³ë{u˜åä>_ÜóÇä‚„ù¸ÿú:ÿ=ÜÏãä«N´ø{'3°,Â1N°­” ÿr[W¨mú%Eÿ¬Iâ)d>ù”S¾Š¿{¾/ endstream endobj 590 0 obj << /Length 3338 /Filter /FlateDecode >> stream xÚå]sÛ6òÝ¿‚Ó—Rˆ!ð«37W_â&nzM+íCšñP-³¡HU¤šæ~ýíbà‡'r{¹ÎDb .û½KØw6Žï<9ûÇâìá×J8©—FAä,nE^¤N¬O¥ÒY¬Wî³Yºù~™ïëf6âÄ}Ùä{º{r(Öùº‘—yÖä4^xbözñÍÙÅâì×3+úŽpâ+/öcgµ={õÚwÖÿÆñ=™&Î[=kë¨(ké\ýpæ3µ¾'‚P¥Îøºß8ï{ôâ‰]7•^(R'Š¥'ã×v~u`bŠ[W>M W[G9ÀŽQ*ô½@ˆG*üDxRÉ Ϊ?J½8…?ý¾*á©0ŠÓJð¼nM ZN;(íŠâwøün½`¶oæóÅ×{[ýìðÆùÁíICT$¼tZZ—²îª±ñ)1L¥ž‚Ýia§ôÄ2̈av”2«i¨|/ Aï;\*è-âNŸ/¸¿† ùXVÜǬŽ®†•s°°T$ÎM,Ž%òS;˜¸ï`Rð/`ú±¯¼ LÉ¿üòëî°,‹•v ét?š¦Hœ²‡t"Q¸?í«—W“õ Åh~4Æ„0ö© @ê0½:\<~9›‡àˆ®Û¬(™ú¯å¼Òï<c-ëUv –c oŒ“þCHÊ¢i’»‹”3¬&œÖýÖhòÕaŸßWÞ1Ä& çÏ–wp§¼O”îCó4…°ÿX™­·EuoNJˆÒá'¶­Z©ò„Šœy ´?ðéðxæÃ¯eÒCŸDž ­©˜ŽD‰[W%¦(ïh”ÚÛÓß-þ•¯»mMó™ ÝßgÒwAÛœ–ì<¯'ýÔ¬Q6dØ}dwù`Kè¾¥Ó¸‡–R’Ä.”Uë)jb/è|›µÍ1¦ÄK¬ú®êí5Þ:-¡Ÿ˜™†áÉ5ßIlA5Pƒ%§“’/Ñï6VdÉò’ÆÁÊ yÁCBQPAj3ž}›ñœLs@àÂlÃK“öITà]A…ÜÌ )ËUê-©L›gôømaÐ-sƒ@Ý7#?¥=qiràÝSfÄNᘡEÕæÕ:g‡FTí­¤›¡~íöù*_O%ÄdÊ#íaІœ*T•À ¨Êb2ôÕ‚;ªí•]wÆ7KæÓ¡1û6,lŠ-$GmÞ1t‚ȶEˆÍ˜ß7ãµ³¦Ï{£¨~Í—\*Þ§t±wS±ƒ§Dò黩"œè5‚°Ç½Fî¸×hAØM³ÛS³¿Ãçwë}²nê_v‡ÕMM?}7U„ƒnªˆÆÝT‘ô–A¥ÕÜéó7™n*àû/tS?¦årÔqEÑ'"¾³ãªÂäb¢æQéÔþÖ†uB_ÙI öRØ|ýú”.×y€Ï™Çªùê=Þ2ãB#“ŽDqZã-—¶Œï¼Õܹ/Ÿ¨”û¯ôšƒVP÷xA¤›p‘0z1êFšå Nwdè`àËyIĹ¾ò@šÃN^%èûîåwW³Ð]Ì’Ð=ÿö[‹cM¶¸|þ}Âã/àçå#_Ý•F‘XdÄ” õG1’ (Ã}ìŒ9•ÈXðS Ή¾ü€¦ô ¥'‹ëÅ öù1-®¼<ç2ôêê§ÇwíÍfž½ñÒTôÉî*NÔ³d·¦´§Ð™7}xƒ?TàáÔ=?åÍQe‘€¦Òõ´«µôŠT>NçôúŽ“½^i$mwÜŒHzYYW©<Ó”Ùϼ°(&ˆoQõžÔz\nQë#ð3 ¢m.¦t l~°=~/#†‰?°ÉÌ£J¡jI&§ ÷¶ÈO ]£=Á ášˆ ¯ý TI§áªÛÌ:«ˆ²=u âVØØL×fC뢪O$ѬÙ{|šR¹Ûlµ¯ h@:}Ó“rXQ%ŠÓ‚”õ†ˆ[3¼"ø>ßB aûàáBA¹ë:ç—©Û  Û ½˜->q6/N_f4ˆ´,«ª\§þ]IŽå-ñ¹Ñ -éõÝÕ  'T{lÁß¿¸ÔÅÒ£ëoŸ?v}þôâüd»}ÜŸ4æ#uEÞÔåk£ÜÖù n%;”-Æý;„a;Õ ÃJ»Bå}[9jèú^Ô}È«lY¢4q%íb%wðªWëIÒ¨«@v£‚!?L£PÇÇ‘'öÞ„¨u¹ªÌ‡%Æ:oV¼ÒÒ¸ô#4Ï¿§èAQ¾êjì×4ùdåK]º™š¨šd¤¯ñqOønÅ’ÀÒ †š5Õ’#ªu_£m‡èXm¯²í®´Yª öºÕÿ'õM¢Dî ¿1‹S‹dp‰aj0”ºqˆ-ÝTˆ#~`jd Ð5r÷¸×T耶©`0v=»â'éšüÏîï=“ä~=“8ðb >`v)ìsèc¸QzbùeÄ/û8dFóÐôL,.ì™Øeþª=Û‰RÏ?Óâ÷œÉnHŒ›VPX³|võòÒ“«Sû;ù Ìû'uYú„ËÑ^)úGpbvyœ$ÿŒ:A:7‰ÑǵqÆL£Fž‚PæE|>i¡ÓDa?ö—›ý~~|£S9Ùg'#ÃãWKŒŠúøÞ¡Ù?<¬–<Ò‡÷ôÓ{`ýì®Ì?y!ž‘蟕²í•æ¶>”ëa‡…'ÕTƒ‹¿þb²h>9jÁÁgŸA8¦Èk&Œs=e—«+oð™:èQ,…t³¶Í·;LƤ S(µÑ_Oág£"ÙΨ2ƒ™¹.{2.ï5°û‰s³† ]o —1k¬yYåf²A¬³(¾ ؈\º‹ÛCó€>àáÑœ¦mK-Š-0¼vß–é¹ÙÌDÑÌç &v„@›¥ª›5jtdµÙ’zS0Âô0÷6ÞÔY5ÅàÀm©u[7íê(¼¢)¼|}øêòêò}ǂР[ÓR± ×[ÂHxZ¢Ú’©Â|Ã짯º¥†§RtÒïú„ ßÃ#WÒ‰¶_ÌÙaõ2þ_ŒÑGÿ+Âñ?LÄútºAןÍ#•¾¡pãÆä ýó¥A<&éßóÅ£F endstream endobj 599 0 obj << /Length 1088 /Filter /FlateDecode >> stream xÚíXKs›H¾ëWp„*k2O`Ž^yo¤DÈ©J99`4Š(#Ђ”Gíæ¿oÃ’0öÊ1©½ì…a¦§_Ý€Ï6®¿Í¯FœI›ÚÆ|i8Ôp¸‹¸dÆ|aܚצÊîT–æÖ:®y“«Lß]í¢…:Ó÷3« Wú J±>Í_¼ùàÏðA´pŽìázpû  ˜m`Ĥk|-W­ n»0Ɔ?x7À•¢Íˆè‰µY±Ë&F/LÎö¦‚¤´¶`„™£mãÈF—jþü9ÆíP`lúãKOïFÞÅÜ Ó?ýjÄÜGccH9Z—û|Û6àÈ­ÊõCÇúFYL˜ß6Q¦zb…Åæ}qQÛjù2K×Õë•Ò7yºËÂê> B‹s¥Ð±Í'ÛÚv(ØÀrmvàOÒ?Ï-†Í›ùïÓ™öêt¤ÇëbÞ¿y†g¯¼É¤Øt~i9Âü ]ñ |>Ã@ôÄ^cóýxâ_ø…î¡ý¸Ç›¼Ï,aN'o¼ÉüÞð•Ò«Ån!Öápå®­OlO–V9ø@±‘ë8 Vö¤†‚#€žÐ‚9ˆQïZZ›iVa¼Æ}3ØŒ6Û(MôlºÔãu‰ó††ŠŒHŠ ~‰²4Y«d«'¿š•˜à.Vy_P ÄA;"Êz"¯âó?üiKéŸ U›bN˜e7±:{\8’.iÐ%Ñö…îÒ³¸­Ã$²¹ £‹$­ãâô”{‹…~¶áªµ¹žÜFaÔqú–›XCÐ|úÖ·‹lyˆ».B…©e(vµq!²Žå_zÅ‘80Ã¥õ‚a¨W³G–EA‚$^©$X«Ž¡W„Õ«ÿî8\(÷'nºN$·^²É¢$Œ6AÜe0i˜íG_ÄAÀ ×­™cPÔS)¸ôü‹Ùøí|<œR:B]Rç:нDÞn 6*Œ>bÆëÎ#„7 âVWÑÚ¸©hx]ññ÷ÎåG¥ Ù¦q¬Â¢ œé‰hyT,ZBöË«ÕuûT–ˆ²&DqQ~Yãã žÊÀ´ ¤ß)¬#y¨$[ù&ŸÌ7z˜oøU0àTm²Þ| Íg¸ o~oC£ šÃHªÇ;Ucoñ(h gCOQXj Câ ÉX‹ d› œ=E ó€uC¢å‹‹`—k£em´<6R¶@éVFËÊhiæ*Ȫ =s R#½Ch²  Š&Ÿ«çÆÑ¹>¥–ñ|“QÌOdBÁÞEÖÙØ/õ iRéå‡jï’E‘«6‡e‘‡.r˜sì»Ç’õY x×xi'0ÿ¿3ÿ;óöh·©}òo‚ÎÿœÂ×hUo© ¦Bóbl <[«ø­¡;n·¹<ø³¦ëu,ò¶ŠÿîÑíÜ endstream endobj 607 0 obj << /Length 2145 /Filter /FlateDecode >> stream xÚµYYsÛ6~÷¯à£4!ÄÅã±MíŽ{$iä8Ù÷„ƒE±2á»ó‹7oÞΉ?ûæçóÉ÷¯/h4úŽ0ƒÛj;úãl#N'éŠüÎýYQ¥I›W¥z«6ê÷G!~8Báê'­³uV¶yRèñ4Iç˜Ï¶Ùt'Ov†íðEo5¥( èàõàe¼¾ ÔhßæeÞ;! ¸òÕòWjés•ƒ·"Ü˺]gÍû³¶‡\‰ƒ¹?f ø˜ÿ‹!E® 9êàŽ ü_ÔKèJ4ÿ6 Ÿp¼,PøŒ(bŒ>#`¾žÑË€óökY½ˆ½C<8)–¾éMÕ,ûß#iÎøì×·óœó»÷ËË¥uÖ6޽Q›±±AĵZ1‘ pÔ/X¤jÅÀÖx‘ ~¢¾æ'[]ˆ(7K?/PêÔ GÍ ¸ÙZQ™ˆ¼ö~ïTê£hˆþG”šu‹[—RŒ(!èïÛdåÒ ß§ä Ûüâ+hx²¤Î! l— RKþvȸø±‘±tï‡FFS&;§Ã9bœìð÷Q1â!;uûŸ|ÂM–\/ª²ÉõÞ!žsP|ª¥B~Y-š¶ªåº\@c±çÈ­ºv1Éð6ë›ÄFòÑX#®ÿrXCäÐsáл`§34õPùõлÂB|¬Ü4]$ä’˜R«p³Ý3äܬ/ÚŽy&<êh‹Å%H™Jrôn›«Ýë×¼(Ôª•^Pg*$E壌!B ÖjÑ„i£/Ó˜mÏFM$JÇȤqxksÅùi]JàHMZív*:á¥ÈËLÆÞØWÛ\Ÿpÿ Gºé =¦ãR¦g!<éGV Œ·wò\kM sŸ´ù*/òVÇx“·¼¦hÐéÇ~ë:vŒØ†ÒùÁs‡®ÛW)©råýÞFêˆ\×.5NÊËW] ½%%øñÂ^]ºée}4¥U)À¨lÛËòº§Káë"_ ç†vƳŠcŒB‚-~9õÚiÙí÷häu`öÜlÀÝ•·`9zWÚü¯Énó.NsÓº` ›„DKGSí‡ûÊ7ýÑ 2É õ¬G< /GP@2»µ´]ÇC‰xÌÏŒäÛòþä'Ê"ðwÒöO®Ö êKþ@ ,>z´†nUh7}s2éOmd>–ˆž“c/±7¹,²/rŒ@Ž0eÇš LûÄD‰À„"92PˆZ+ú«%ûH–Y±‘-”Í{I•úJ¼ëDjfè˜gÕÒDÏÛUŒõ:WÙ6)6j9´%ŽtÌb¨­ñÓo¹X0$Ve!È·©^B‹FE¡uU8åÿiïb*Šƒâå•}ßq€ž¡Úuê+ý–´¦ùKx¬EN‹¦]ÈœÓþŸ9gˆOþ—ùá?öA#ãá?\2GÆæ?7ãâ_ÿ澑Ķ=ÿªtÂ| endstream endobj 615 0 obj << /Length 1702 /Filter /FlateDecode >> stream xÚ½XÛrÛ6}×Wð­ÔŒ…àÂëcêÈåb§–Òi'Édh ²9¦H†¤’q¿¾»H‰0£‰[%/"â²{ö,ö€Ô¹u¨óròûjòìÂcNLâ€Îjã„Ü ½ˆx±pVkçƒûzÊ}WÖ7².›éŒ‡‘û¾‘µn½Üeky¦Û×2—I#õF8'lúiõj2_M¾LlF¦÷HHC'ÝN>|¢Îú_9”ˆ8r¾©Q[Ç "xæÎròÇ„Cé¡Á° f”Pjƒgïqßga|0ˆ BC´B ÙLuËúó=A#»ÕŸ]ˆèp#‘œ> stream xÚ­TMoÛ0 ½ûWð(±J}KÇ p‹u[Š%î.ii¢ F{³³îïOŠÒ&q®hweZz|â#‰ð.²Uvv.8ê4×P­@hMw`¤¥Ò ¨–0#Ÿs®ˆïî|×öyÁ%×½ïÒîâw½ô£´ŸøµŸ÷>}0Ê9eùmu™•Uö+c!"ø¤ ,6Ùìaü—€T8 v§6 µ v Óì[†{¶O–²@)×"ÞÒ ºðã™srxcÔ)Åãcx†…Io“ÔQ±cùö00+")Çß?MrE®Æ_Ëqu‚yv.ìQ– .Ãm•8L½O§)Ga «´:E:'ÏàÓÔ`wp÷;©¢fA®XC™R·V¹DÒFU’y2Kß/¢Iýs[·Mò¶«dCYàQYorä¡îÚfã›mr>D&ó=Ìüní{zšïWçy¨e¡d’C!µZ•ÿGÐiY¦Zþðez5àüF¥Êß×M½}I#f) %»×h”2Ú§î‹©±1oP¡ ½¯Œ¤£ZÊ–Ñ£¶uPƒëWwõóÙ dŒ„Ì -éë:–S RÅõ”ÁN¨JQë endstream endobj 636 0 obj << /Length1 2908 /Length2 22863 /Length3 0 /Length 24450 /Filter /FlateDecode >> stream xÚ̸uPœß² w nƒ»»»»»3¸»KnAƒ»»÷ Á]ƒ;$¸x“œ{O~çÞ[õÞŸ¯¨©™Õ{w÷Zݽ÷÷$Êj "掦@IG7Ff^€:P[ÊÛ( tqteu´3°223³ÃSPˆ¹MܬÄMÜ€¼6f7+€’™ÈÙÀÊÌÌO:]@«æSo€ÐÍDÝÛ È 6ù”]ÝLM\AË@Kk ÈEÌÑÉÛÅÚÒÊíw .†ßŽ.¿i~ó½Ü€® ´®¿ƒŠ2dMÌl=]m­&æYFF€¢£'Èh  vt˜­Lì,ŽBh¨I¨ª¤T•4”ÕhšÖ@7{ +`feâbbætqxAyLÌÍÿÅ[ÚÄ n}L¬AÕÜœ]þK•˜šº†=@\DQ]Ô¤Hi¨©ÓÕAÆ?+¿I~dÌ­M~»+H¨‹¨ë(K°0ý®€àÊiý›éÿC ø«äjáâhÿ'€ÚÊÍ͉—‰ÉÓÓ“ÑÒÝÕÑÑÅ’ÑÉŽæwu+kG[èÛhüSbwsPcÜ@BþøÝ`€¼µ¨–À?¢€À?‹ "Š2’jê  j1ü.8ßÎ3ºy¹ý‘¢*!"® ñ¬þ¦gmtýÓ­ß‘ÌA-¶¶se¥ú—ÁÔoPJ·kµÅí7]»1¸ @ÿ·8& gW¦ÿÚêÊô[ƒ¤’¢:ƒ¼Œ˜„¢šÄ’Ž.¸¹[þöýÿäø…³2qýCY^YY`obíš93?77wWéè4'ýWÉ1w—ßÒþ{Éåßêþ»¢Ž 9úv¾þ&žÿslMÜ]}þÑíÿl¤hÜ­]Ý\ÿø_•¶™@µvøíÜïý¿#ŠˆËó¸8˜¬ 3è K8˜‹9ÚÛƒx»Âÿ qkPƒÜ]¼™þ÷¹·upôtðý?,¬Ì—`îîĤá`íì”ÿ¯í ü_›%Ð À :ƒN±™Óï„ÎÀo3Ëo3¨þ¾NŽN ;W ¿µôïëjâšNw ¿ï?þÁ³pÌ­ÍÜ@'t™Àÿ‰.ã`áàù—Ää¿—þkú¨ÿÜd4 kÌÜÑÁÎ4±ðLŠŽn 9¡þÿû=ô?XKºÛÙ)‚Pÿ¯îüÏ&öÖvÞÿkëÿØ¥ü-úÿð·v•´öš+[»™Yý«Kÿ²Ë¸™€Î—ˆƒ¥Ôá?&ß7Žè €.zëß  ëÿ\͸™­ÐÕÀÉóg *Þÿ  jäoÂ&5MQY5ºÿ=öI8˜9š[;X‚†›`ââbâ Ï +V€/ 蔘½þÌ€‰ÑÁÑ äprwóÿÝUøß³ÁÉ`ùmúâ0‰þE\&±¿ˆÀ$þñ˜$þ¸˜L’ €Iê/b0IÿEl&™¿”]î/e—ÿ‹@Ùþ"PvÅ¿”]é߈”]ù/eWù‹@ÙUÿ"Pvµ¿ˆÀ¤þ¸hüE .šˆ‹Ö_â¢ý¸èüñ€¸èþE ?“¿ägúüÌþØA\Ì@wÒßÝ,Ì Pæÿ€ ]ÀCP³™þŒëß ¬ €Öw°ý†ÿp•ÂÂÑÝå!A[,ÿA¬þ2ÕÃÊÛÉ èð ›õ? Hží? HŸÝ? ˆý_È’ó7ÈÕtþ±Òçø7;ÈÙñ?–Aìþ.ƒä;]¬ÿQ ç@šheQwý›þ7züCh»«µ×?@)þV—ÄÎÍÊør‚ô¸y:þÃ$ÉýT @ Ï4 Ïû¯Ð^ÐÁþcøÏ{@ù÷ƒõÏó‚ùïÅð_ïP°š›‹£-PËÚô&ú- &n.Ö^zÌ Ëždýý÷/ƒÿH@ñ÷9õoQQG/_6¨Ë,l<¿[Àáÿ¾fÿzøÿyЀn°ÿÆ¿Ÿ» Ð h¿²èhÆ÷ÑæssXy€DátãY– ¶läJÆt'>ŽxÞ)P¨(¸5(“²ÈQ^š× %Ø¡D›â#¦ÝëF[rõÔ¹Šð®I€B>²„ÈX®&£Æ‡L…å ŠnRšcÙÜRöÙÌö„v"€ÆØ‰OgÏc,ëäÚU*©~Eûz>”gñ|y,uŒââçØ%}Úx°ÖÁV|o$' ÒÃ_¹ã‰èAmìßp¦ <ᆙXhwaµâªW¶š@¿Å^Ô×ù!EE¨ÔÆã -f¾G¦G”·ZháºëCÄÀ6g0Ï3!‘…Èn!"4Ÿ8̲Jîíny0ÑaÀªMªvZ aÁüU~2Ûñ#oºzŸeZr^ý”¬ŒmðJ1gZ±‘" h-_ÓÂÞw`€´³Æè©û`?O‰“–I{Ž.àv3úTÅÍü•XO¯zwqéZvŸSVíû¢Â Ô•ói’ïjòÜG<𠜠`6mN¥+jsª`âÔ¥——\µ¦œht¨4Wƒ7Ê4. +|••êóPäªRÉ´vàæ‰i`Oe$¤Ö¹â—RÎ N:îCïš|×3dÄy"…n¶jÓ¤¬2I­)ܶ¸à–†ô\ìéÏÀ^<gÐ6êïryù¸Íæ¿øø´/´Õbú#ß<¨`?| /íSiö$£Úû&D'èå#ÖFø‘µü:†ßûd„]e݉‚¤†¢çs¨â?CÓö÷0þËÛPb‘º÷+Ìw\aú£«_œ³ÛꩨÄkáè6°³2¥_Ó_­i&3¸¼Y_ØÂ [ͨ‡O¾ò¼µêÚ¹ëpáÁÝö©Ø•yº˜î/tÆ”É/¬Ÿ1ïÍqJ%§eª©¿±œ ³D?ê{•âO,”¿‚ºd8©¼èÉ âœÂiã+ìàSa–”ïß–Ù:Ô~ìI|G{#GÀ½{¶SQ +-ºÖ²ej‹|«¸6{žFU®–éî+ßÿFË{õÝ^Q¹ü)êÎo÷õ¯¢P+ï½êzÑŒÝÇ-!ÒÑ!BäÛ~1Ÿ£C|Ô\©åÕÝÈ›”C%¿š’Ö{—´P·¯ð2Š( ì>ÑÎSøç-\ ÎÏEÏTV‚ó¢òÕö½XuRGW¯Ëà?—n”!˜`hµá§ü@ ¾„­ÖTI¿e†!J{óè¹@¬S˜Rãž‘eWKogßÀwŽh%6%BÁ8BR”Räò±‹ÆXû 4‡Ç>ë5?޵T ŸW˜¸w=ø“Šâ- É! ј~EΙtâA_Ž„­w;zè’û->}ë«Ç óù2þî…b‘—Ä–Ëž‰’È1DèÇ{2Inë]8CžÔ–‡,ö¢Õ7§,lÔU(ÄDò÷9¬ùÀ.ðïø¡túM½zïå Ä-LË‹Ð­Š¹L+Ý1#tC„¢å?rQ·O½kYš¶´Yd¥®&Ì .²³2¸U’Џ›8üa-Îa¨”å¥ûÒo,÷>3Øöl¶Å•ô²î"ñ”^o±—#pˆ~LÇŠÑn™ò­McÓ„'æi&ecp°Å®Sˆ€C×ÞT™íÚQÇrTA±’æÕìŽ;@'ÛU*ç".T[—m•©õRB¯_¯O<|F»‘^–gZw8#ÊJ;­ªû¤dXôfæÁË"Àfmx¡ ÷PÀ[„Yá¢5p6ŒéQªš”9å¢~ÚO:†îts+)j»¥tFáó´ :REz_(jÒo•Ûsiõü—“©öIrÉ™“Ü­f¿[零@½ëZv0Š‹äÕw.Ï'a“©Ç•¾2Šá¥÷ç5gªƒd!—QCBÏ'¾_ªÈ?¹{Ž´n(Z+³çÕ.-²kÄ‹¾8·ºr¨ï|ƒ-¤ ós  ¹ÔÝû 9Ç…¦fýejø4—`cm7Ó•Òñâ}ƒÑm<ô¢&†6§JL(pÓ±ÌOŸ²×vÄ¡pCìéÐz>ø:vÙj‚NV¯×½ËE´j•.|ܲߪ=¶E«U¯m›kE!@gï}2ç—–Oh­v;œK+}‰ZB¬g–ÈI%¹36—šè?2¢ïßBOE`OK<°âÙÞënTtP¥xoZ*1±"p|vª!KsŒY' ÝëÏj¿g—Áܱ{4K’¨G%HÝiNñvšÂIáç©Çê,6Û†ÆTqâ̘òJºç Ó¼#ÜçXsy¾>C.Ü´1.Šg§€U‡iõçVÚb:;8$) 9.2ÖìÂ, y8féÝËQá©Îºeh|nÕ90ˤÎO&ƒªmNª!Á»¤ÉÇï¸Äs³4ÖÃÌ|ˆ¨2%VNC Û" j“襣¯ÂOÚtHE¾c˜{—è@ý3%|s•‰_Aßï-°ìVr ˜LjÜ>ê&’aúP0¼g 0!aÌóEôÈx‡#V;°ÁÎr5ˆãè5™Ìð~'= ÇÔö\a:Në{bh¦$)nx)bKÚ]¾a,û©ä…bT§‘§O‰Mš4 çUV‰€Ù¬§1Ý à…™!ñØ^¯ðÓŽb5E<Ï—<ù6ìŒÇ¶B‰ÅjÂÌÝõœ;ÓøÚ­V²yÓQhgP¾5ygßmžP~on¼Ác3ªËO5¤ã(4cÃF±€s,{×®ÍÛ#€5‡ÿ€^²Ì«+úÓ¨a6:ÆÐàO[ eþÓ•ëa?ˆåK»RäÆ+B¢÷gƒ>½¾5ËFÌ ‡¯ 6tB]Ê¥]iSz»ÕÜ*<ʵ ŸÏãTU³PyHú¦Ô„b—CÇ'lÑT¤Ÿ­Àánj"Є4ßýšÇÀm 64¢A,„ASýÀêV¢áæ—†3zHÚ?˜Ysõi Gý’£¿9›lx÷­çá1LKßUa)Àe±Ù\sS‹_°¢~“W »½ žùKçô0Å+ÏE’'^¦,{Ç•/MSù‡ì}»Æ>e¬ÿ ´Þ7ª=kJF¸¹’…ÂOÆ9—–M™t1ô— )Þ½'ÝÐ…È HP†„ ¨Ðøø>µzrvꂪ=¢š[ ÿ–†GàÖ³™¢ˆ‘€îâ•À®Ù{Å'ˆ¾Êox”B·"½{ËØÚ¤÷5 ëçÿ1òôëñ½ÕÜØ¬Ý mÚþ¶Ê÷MÇ«3Þ¬iêB°ÚÊþκz™–åP+Ó…À´ Õ‡€Æs"ª¸µoIXñ©‰/уº¼¬×=¢ö¤ýúAoP±¸þ£³}& g£ûÌÚY’ñqÙžqppÑ çÉÝLG€UT>ñ³£Ž«½ô7.½¢Iöœ:fOÌ:ì·JcÈsI;§«t¦Lª–­f±(F¡½ˆÉ¶¬$¸Ž²¦òÃï!Ä(=† °Ž,˜õ¡cwצ}’³E÷’¹ÎäqTÄ»±­ä¥Ñ–& ô{›5Т`IŽš†{¦ÞBñŠå‡«\>­tá~]úZºÝ¦õ“šA±T•°#Z/³»ÖåBäÒ_£)3øz†*›ð‹f7&áö'b*qÌãïï |æÆìûVERMQïÑ¥è ]£]¼gR`><‚kœÄ~}8ÉnóÊÀÅ…Í!‰»GX_\ °ï¨¬š»ðBꬻB¬ïùÌøÕë’Á…àne©Šö .'Kœœ>çKƒ°ÏÚÚ\àE'·Z»+F®¤÷°ð¯æ$Ót[LµÓ%Ñ+c°d™fj¹D+¯xœ¡/û±%¸¬²Oq¾Ð]¯¸é·}ݪÕÀÁûhÈ0êÚÅ,c­itgC¾D¾fp€®ð~”4—Eû÷z@ž¦ÍUBÊÚ¬‘3©vk~[Eg£rýãTr¿”ä×_ùô£¤Ð´¹)D ñ;Uò/öÏOʆg—7k­nÛ)óÙ+Pgè{¿ê…¤³Apô`lò·Þ1·£„ä‘´íîëñöØÏW[<©â].2y® "K+ˆ™YûWÅ ¶Üh •—ò\n{µçËèjQá Ã8³Ñ]`–è:1K óì]Ø]ؼèQ±-$Xè†i² wš~©Ø"²‰nnÄÜp ½ìf0ÂP‘§Ãc•9âÏä«Ë2Úñ¡&¢Èîvºîn%©–Ù 9à—Rú2™CPÛ[Š¢]˜ê¿ã˜tꇊۚ+ÂQ>¹žeý%á“þrX‘õêX?´\XŸø 2¥~TÔïÏ“Œw)PIÆZ O©×qF| @ÇÉu‹$9_òŠi”é¾î­Õ¥ÌueG fƒ¡ø#wXe+ñ¿ÌùÕž7+•îWðJ¡¤Þž´gî¡KJÕ-OT³.¦QrADù7ú¡[3;“D¹ÂÍ—¿Ù|M½†zÆedza ƒSl 9´á£jòÊŒ ÊUðõAõìdž`®è )úú2S§@â]V†º&qˆlÏ¿YˆEòšÈ$Ç·{µ ±yâÂ=†9¹2Ÿu|Ž7XaF(^ór s{|¢~In‡ž&¨oÈK2žæÓ‚ý<\Lÿ,©ƒ+ŒH2)Ee'ê C©Ãd 7iÉ=ΈÜ|/ðaÚ‘-¨˜¨—§Ö 8FM”05†œ@Úæ¼ìsp`7"ÿ[–~5Á—v¼Ëæ²!$¡AX¶Q¬6Èmá¸çN'|b!Aeµk:©ù‡qéñâ–µ‡%ûÎ&#_-5G‚,eÿ箯+f]èXâó`#ÔVβWMþ0"ö´*­¼§˜jÕžäÓ©ü?–Y'9SÝùŽqS&[Ï2Óš0.LsÃvJZDëDòhœ2ŒÛ³ÕOàzw^Ž”M²V媞d“×û½ÔǤ0(½Ÿ+/7Yfã RF8šM°8ÞúS”´Êâ’LÀ+ÊbŒÛㆡÏDÖÕ£ÖýQÂ%ÄYJ>Xö•Ä·Õ‰ %ð:eEI8éëO§ ìO'd¬'¦„ÞøFßøº¢§ëlJÓ¦rVhî¯ÌZ=¹×w—¿bóŒ:º|Ìc öfxE‹Ùφ\–4áú”*T+IÔ´î×]b)ù38¼Î¡tà¢!ÍÔßGÞZX@è‡ÊQ« ˜o<-véÜt…5#˜Ò^Vª½Y§sر]M‡î"nëÂ4çI&Ûã×ôFü|ô“4Ñç&ÜàÚØï®7‡ê+ŠRÈ¢ëWGØÀL•Ôˆö¦¶r¾³K)Ø©DT `Êq¡R–õnÜøìºÁדS¬‘Æø™Ÿ:i¨ÂªÉðdý‹S”7Ã!gn¾­¡ùGŽûzNm1%Áˆ¨ ?/&½ï‰ôK›Øoû¶ÅëË̼Ó1 æÜº(OM­³fN´ò(ü*Ûš±Ö/ÒØ­‹i\ß¿Ò~¢¿ š2¸}Aα°î*»[eøÓB{)ñÔƒˆð9¿ ¹ô烵‡ X-÷ôüe¸Å&ÜkXÏÓîžewyÇE`e—[dàæJ¡×“Ü[ 9îc¸g™ÄÝÞmè„D©B¾‰”vƒ@õFf} ¯°Ô àû!QÔ­ô»¾}†™YÃÀàbó$òݘ×*4·øL²kvÊNÙÝ ÊŠ`/ D‡suù)ʉæ·×\1MIß(¨¦¡E˜ Ì %VãQ„¬õ„•8ˆãf™bM„¯Ân¿ç|BÐÛ0'G_Q»‡°¢qÜ»è pXµJÁr]äV´›¡°ÇŽÐ½ø¹%½”Û| ÑÐ^yb©ËÚµØþy (é0ïÒÎhj.9f`6þ,ÃÕ¿6¦Tóùaš‡äÝ”ýô+osŠc`+Ô×SFµwihÊ›ú$/é-Ü_éÛáZ6à.@«!“zŒêät=Ýäv^­Âÿú½Ð«…W'Ž‘²oþâ9¢,[ÌéžzÙÑ`5MpO`¦¥£ ñêVG'€h› àœ`ÁnH€(NƒbX„2Ø´q¨Ì1[€ï޼]ßQ¸†?¸¬L;$C±õ‡H˜W ò?‘¼,qYµì‘D*( 9þ`Áj¾‘ͨ\<üdÿnel)æÂ\|ë¢\í²vlJF/üW.g¶ëa zuGí² Ø[^XE3'ulG„¾ä óÇ´­²¯×Ù™!x!§YfœWo7Z¢Œ“Ý–‰—KÔs~²ÖœÞZ„ŽÊðî¢Hcä=§»Å`yHæVÐÒë7>iYdQ`ž¼V–¥h ÐÇø±aY9›„}…¯°!qhcO’Ð]©KE¡µhï±M ¡¶¨&x3e⇭6Faò,“ •‹Æ³Íïêm8Ï ªÕ£lûˆÙ!7ÛpM›:ò;ü/ ™9ÔÛ¡kH~by–ª#ÍpåÁ¦AI=©»Õ„ÝÄðµ3A¯ÝpØQ-Ø¥ûè¶“jC>ƒ1†m¹¡§ŒGüšÌ á4¸åW×ß dÌ?¸VàˆÐ‹ªïê? Ö)œ¯|”Ô¸TÀ;o:%Âý68CÏññED–fÐ@¬š!°ŠØ>úîÇlÎ4£¦7Y}ÇxQ ¹ ,Ì:öìÏ ¿[·…o;æ’ÝNðl½PZÂû‰f‡K²Š®£ŒEI0áµpÈcîëx³¾é±ÖgbâqóYÆØmzyÕ?'ÌöÒUðZˆÆŒüKÔQ&ÆF¥¥\NpŠôP ûòÌMå#g›«^4€šlt›·s;*9Ùd?,‘ ~Kw¾?›¼p±eT˜–X]äyã$&›l$.qìó²>{SŠðÀPÔ30 &¦q43÷r‡Çg&̸áÃnz‡’­†W¨Å¾Kî:$*ýÊInqth[ÎÄô¢ì.Ç@íåË×-é»6iV` “¸‘눑š÷zÅŽ¨õˆ?~åucߢî•mø¢ÿÔñÞýLdôà ‰1ÈY'õªge"ÄV¯"O=9¸3ß;‘<Òp§ †è¼]oûBì:†ˆ¿›E•DàÆcSº³¶FˆŸÁ2| ì§©¼:¸XACÞõì·Ý«^êÁsòìB‹+šÏ¨œú®—ÍSQ¶;ÖTvøx¸–jÄå…ɸ6"€d´\;ßdÒ‘|_”\ò·g%Ë–š=HhÉ” Cc¿.„ØÂ#ãýÆT¿PwÞdg À袣dÙ"?K£r6ˆu×…kçÎû ÀÊ~?;.ÛcíQ¡´÷Lo>œ¥èëy<è²®T 9~VETÎÑM¡¦f&ßb#¿ý"k.rÍ«ñy‰þÃ^WFè˜$G‰¥Â»ý"¼uhÎÚ'ÞO,¥ ´s!ÕçgÛ eâ¡d{Ï&ªt*j6‹¹aHEÐm?±}>4R.r@Dhfi}A}²ùbtš2}*yÉ92 ¶eƒ™¤=\Ü`Hf÷ÖQU ¥ÆyÂÈ«qa\¦œv‹ŸÏå5ë«kïœÉg1±NÓ0Ëh¡‡êù…¥)•"ía*ƒ*˜…ßà,™j/h*\£«ŠW™§ÒÙÊ¿Ïë¸+Ë9@´s5ö¼¤yH_™g@d,öú8ù1QÆ[0*„Mç&Ô©¶Ù õ†xE›rE†<Çä®Ü’dñhÙWÜç`xÿ‘êÅšËaŒ¦ƒc:ûWsÀÊ/Œ´€`ÜÄVgë@Âæ}#Æ2∞ã&n©2LûQÇAæ·“OÔå*ßUѪ?17oÝ?Móù£Áò‘Îp& T7o<+—g¨á† /±“ÞÛ탛ق“ÚËÐüôË,{ô‚1;ЬjèÞKøIörz¾fŒÂúêÀ¡®Ô@ññ;Œýwì½\¡å"ªp·sÑkûeàq,ÙxÆL9ø¢“>BÜÜ gêe ‘éù/ À†¥Œˆª³ŠìT~6]6#}'¿ÖÓxhðk[z¬k7¡‹žfcP‚ÌzÓ%4k!tå/–ðû(ŸÅr{š«¼ém¯ÌùC._œ¯5ÆËÁ|šŸ›ÜŽËýªéÌçˆä‚K&¾°nÇ¥G>7Ç‹Ãð¹ô9.ªÝ„äQÍ)2‡{h½Ìõä©…9ù»Í®ët÷I,Ç^õzj¸w.‹æ¬5íêºîIq!òu opQ-Î!‰ƒ:ÛÓ@–âŸsv̘Cö¾o‹ÜNq"`‹>S9M½.s¸Žé¯ËveË~ Iì>)¦+ ÇMaäy¯8U[qM=£Å©Rô.„½ÙqÊã¥U™½ú>¡8‡h˜'¶Ÿ+Ñ:s*>.F4%V’Æ7­ñK¼ãZÙæn0(ûþXè˜GמÁ(?*ƒU¸xôÄÏ'Ÿh²ãæØÌ¤Ï¾6|e>‡ys:Y3àDV­ ϺÛRí’ôÆ ûBêEü5»ZØŒq4¶²em$g¸ú"ÆpÃuPÚŽ Ö6T‡G™%ÍKéSóãmª+ õ«Ì‡48€D ´Ò6 È%!0A jå޻IJàÊ6C;#”‚>„†o©¥´¾ˆ½˜dÂ˱T®L^QØÛôb²Ô$!n*ö0£+‡*]µ¯w©~}I#0{Ó3~:Ê-ðÏ»£Æ¢^úÁýF¶#â¤x¾øƒ[h™]´ÚÉÖýe^R¤NlBVŠ+,øíùMºóR§ê¹Qæpª$æ%:0èïEª}§^‰ß^ãõصñ«H•bš÷êŽY¸dö8U€8ê´mt½fcÉÝý‡ã¾È)Þº¦8Ñæ|Çoow™‡Ã’­VDxš#œ\ù †QA*Ñi^BKWž6ï©ljÂî> [Ötìyü¨1DÊù–#MÕæËºåEÜg0÷uáfÀ>ÿ•˜ÿf[w¥B`-ÕY4¿÷•žÇWÐ,ÿk´F‹|&|†í|•áçþ»)ãÓhòÑ2á*©ÒéïÚOS‚-VÓ3ü®Ff ¤öCå+á*ÌÖÈxi&oTõ‡eìZ›5;À0—–‘á½%ã&YoÏ'½+±g$ÑÙYsæ àSÑ©tàмne bÑvòxßëj¶żä¿”Å£}Šdÿ„–@²šLŸ::UŸl/‡VáÏý£±Š]jÖ0s@×Mzǧ<ÀÚÓ¬Þz¦ ~éãÇöy¨IÆO>ã¡+ˆ#Çîgƒ Æ&ëÒó"áá÷Ö~tR}ÀnçÏl¸oúÆWt0W²”ß?¶½6mtOæ¿Ò"? [„ð1®înÿJ³ ¹¯æ¿zæþŒIë'ÏœEFË!)XÊQ–ž:7Í—¯‘¿á=ÕkÞ1ÙÕ‰˜Ž¥¼ß{ëí¹B³žõ•¶[>Þ 9m+ø—¡‘³€Ð–Ô0ƒÍpaweÕEå6Šø“è5-˜Ü¥ƒn#vh[´XraÞ®]Ö}s/& 11ÊÏ“€‘XªÛoËû® ½¼sZ‘¢ý”^é./ œí=Ç”JúžÝ³#á…Öë´©õl¯~š:&ý¥¸9À§´ª¨È¹R´Ä=²8g‚ƒ,fŸ4õ%9îõàÓ¨ËPÉCÉLÆÃóì—iÞb rüÞVûÒl曋Œl— £ã~]ÑnO,áÅHDÔ`jb½©¤äó»á KzõCèÁ‡ªi³&'k)ÏœúóMÅo$¶ËjòŠ‹72çÈD ¥V²§dó·ü°,‚˜NÕÚ{ëH¨¨û²àȘ|ö -ÈGê >´´´hËÍXJˆ <+§T¼æÞ'QÈ3Æ–\Qäà¡ß'L™Où.¥’¥2Õ1çX'ÃsµŒ\+ü:üÈb-kû¤ߎ¢tÈ¡ïÄ´kP01󔿓oªwlÖ‰(TÌ^ó~Ý–à9øˆ»Í÷Lš É:Äf|SI þ–~us@¦©£jÃôôÔG½ÚàéóØü\¹"+ ÿ³™§ûG­ÃW|«"DY½ð/¹6Å´ªòc©Ô{þèð ´ÅúS­Oås¬søƒDçd6k&õŒknwÛ­}ó½Ì«¸¦pm[š¥{ Ñò!ØÁ~m¬c:·qlú&t,NÊÑ\!Â/4ð㪂Ycv×!‘µvû9PDUJ……»¬£ö.Æ7ÊÓ8S#×üÂÑn ´jwÞ¦°â9³¨ »-–+b‰Ö‘8 õ$»«æ´ n !Bp¸÷:—[£â- JGeþþþ”Åó›õÂÿ—oc´M-R3›Ó‚Ї`Gè05K›rø)ܨ¢CÞT³áÈýn¥. 9Nwk¾éП¾„VpíË1G¶-3…º‰/ÃVpâQšÂÒ¼ŽDÁ_öõ¹Î1ÂÛ÷ÀËš¶ ?Ù²݉ž– r†·Í«oÅO3FÕG/l0!]ÐÕFå%°5-ĈҢåÄØ69oBi£4t~HÙ—ëÉ×@x]ýY-B¸œÁ:•(4·×1òKƒŽÌÒW8JH±—AFã›r£›9«¤d¨Ëƒ¬ÿ/ˆâ¸/îÂ7]á\)ƒÑ †>(~=ˆOä ´£«OØbdç»| —ÏPÀÒ?žil5…ÿ:m¼Q®°ÔWåÕ[«9LrÉx`fjý²þB-Q9¶ƒtFXlü²ÞêÀÃÿAÆxuË?܉n®Wãa‚èîå±+† NüQ¨RbÉ\>%Ò—·fµ…¹¤×JýÔ¥ÚàáOBýŽâè´·8ÆÝPïád]À]¦¸J{¡(µür~Ÿ“[Ø Ž^Enp'æ‡.ØRW~On­YVœŸóg š„£ÖþË9&ír9÷óZÐ »€N?$¶•¦¼þH“æQ¥ÜöèC±}DõÀ›µŸþPòÖÿñßzëú»-6×{¨´÷}dßL¥³DùVxøC5yÏi.TÏ0´®R­"ºu¿ÙUõeÿúŽ(Í@ë»óñ¨zÆ¿&ës›i]CÏ/B¬]l A²…š¬Ì°¹ÑF·±5 œÝ0iüŸg–?}l¦Â¸vWáÚ8¥é ‰>§ïbµ‘ý‚Ruf}3nUZ°RBì>ÌédÚ‡pß37¾[«ht!—ÿˆê›Æ‡§ó³ŒmWÚšë5TÄ|´e79jhÜOÂ}Ò#xàt 9M¨°ÞBeË€ ZÖ£›j€.<µôõ«˜<˜'¿÷ Úsº­Ü¯œ–ÛÅu?ÌlΆÐgÊQwõ½-d2z£O—{FRö°à–‹G‚Ó¾]óµ9g¶‘$¥¯¼5ˆ5ýŒ†0žûÓ”*B/õ1ží 4¸Ô£3Ú[8qÛÍ[XŽÛ]2ÃXªTÌ´bížBƒ–%É4'Dw›N:•1ŸG >H0Ü@W:aªÊvE0e¦‰Õ‹š¾›h®É”ºS\á´IYÂt4³;ÓL‘ÿpÂr žÿÕi¹ŸúQ³2¬ðrµÄøµw‘²á1uN’fsì¢ïawÎ`^€ÂjѳE«©,ÜìªX¤‡‘¢øøM•Àc¾,È.@¼rôªäÎÞC©O'XbAŠçj«æœ-oo]$éÌ3± Uy nÛ‘AFÃÁjîF¦°!)‹óC¼­Öí½«ª±âc»ÆŠÍ2T ùow4æq0åÀOçÍ©TŽËß\þcàTÆ&[NÙÛŒ‰:GSáé;ʺÃ7ïÁš÷Àº¯’«öaC«¬Ø+êÜ»¨,©Ú\ÉÊ-5‘àΛqÆ'Û1ð’´X¬UZ+¶ù O­–úC¾ø ˜;*ðJð¤Q–|óf~“`+Cd×5mÈZâŽI¡Ýè éŸ9ôkÐBÅfþjúбÞ€€kûl6uµ6öòþ§ã%v7â^M!+vHxTÿDå{xÛÔ 6\pk"­aÛ(–ž<=ü†ýŒŽíq™¤.aþMÑ.ÓÒÃ$𹚀[‚&0^I¹Q‹À ®ÜUþ¦´óN9’ÊéáJÓDÂÛNè©?Ò-Yv*m€h²»Õžã"DèUF”ëÀ×s­_œ¥ e†“só Iô,¸>9A­¢8m¸˜@ Xš ŠuP‘4~–N/yøÔ¤žy3犕›êç«¥`` NòÉ=ü͋ӷÞôÉ*WëóO8ħŸ «Ó™<ŒS &,ê+Û[YS("±dëX,mLÝyõû¡r¨¦¸‰kð¡<téõÁ1™€º1d²ÌX¡Û›dν ⎄uFöߢ•a¸/u숢€Ñz_Êñ‚‚Åéýg¾ÏU:v¼7B‡~èq¦œµÜо+KÑ뙆+tw¹È£0áI*ïݦž»¿#‡Áµ‰#rY·*Û|7ª¾»è“ÿÕæzgcû[œb¾W‰U)1 ™¯°jdÞÃ?ÖXI© $z9q7šïW <¬ M“/ncÆLñakßÎ>1|:¯(ïZ„u¥™¥œ6¸y ë_ñŒ™á%ËJ–¢wE¶+·c~q¿iIËÙ xjàlo¶f(`c&|óQ»ÿdÇY½§ÛD”e略>q†´£LÅú}˜Ç?MŽçÀ¸ ŒlK1…Ul ùà2 ŠÈ0m(´¾±/4š½i]™UØ9U¦Ì-Su-p¤g(}…²ojžùáú+Þs³‘õý8º|ö£Ëc›0p}»d{ï[ŽÛ^˜½´<]ˆê*šúëeFJ Y@‰º/S g).6äuå…º˜ðצ>)£™*U"6) òýÀvLú뙜?yC*=—ÎVƒ§k°©½†¯›©=Ç ¤Ë >NfµÎLË?È®Âˤï„"X}„«Äúá~"ß Dï³]E:hŒÓ(O=ؗ̉±J*¥ä£bWa:gbÛ÷Ìçg$xtA#ïÅÂ÷efž½:¿%Î&—„¸B•êf»ºí’€?Ûè‘m‡û2ľ'dž<¯ ѤgÜooºú$Ü Q@lˆ°¢§àõ%“ÎìöQ²ÍåãÊ>2q̵ršgs¸SIfMqÔmm’¶h[ãTT7‡ù-/,k9¿ó8þmÚ}Ò@·œ2ß78KÖÙÏÞC‰š„ªÅÆXî¯:ÊH_ÛÝÓ-+º^Ȇ„ÎyZÛeP' YW'NhF¦{c^N>¯õTŠ,¶ =ú´"{På—‚1²ð• í¼Ìq›vtéÑ4°®‚ž–ä1çâ+}{¿—sQï³Ì¨Öó&ŒŸó›Æg°)™n²5̱B,˜ûõÏžäQ ¤ã5ÒÓ’ÜÙ&~ ›lÞKò¦LËõ‹+8„lêêznhÜZ ÜU "YÉ弨;æL¤df‰~m‚Epüä#ü* t#z'ßbmBdD7}Àu«-t>€Æ™úz‚~ؾ¡=rïR ÖÜäÙ/kÊÈîºM0ôîˆK¨ùˆ8Ó¡GÏßT6ˆ‹P½È´¼Çê£Ä"Ç•§áˆÅ‡ýºÊ¿>Å]›S̻󿼔¯îíø±¨ÏÃg¤ê“Ø,¥›Ñýicp¯d¯}Aã6+ïF¹€¼9‡œï0H¥±Ár‰ÇNvÖ©²å¢a*ƒß¸Dâ:Y;hj—„3‹ò/ŠB¶unˆGÑø2“–fã%öÑ–¢8k³°i–žCõ)üó}Ú'ί†µÿT\ÁÝEk®>~W¿ûÊ_=¢P>¾L¨D}q3ñaAÛþ$? öH¥(¼…L`ȳZ˜Žõ0}ܤ«-Q)×äÙEƒäµIé‹«/K°™™r5mVcžu:"à=¼/YôWÃP';ñ.?þšøºaGYH_%X$ÅO©b¹›çG˜¸€utë%xxKOxÍLÁfQ蔌µ?BÛÈ)¡ 5rSF‰ò4•|›ûn÷ž.v¡é^pYÚÎÒ±—¾lXžN5,³ÑV©ŽkAp”úD8þ¹¬d×Y%Ùl½Õ2¢T8´SÚÀoªvÓ_k‰I»…>¾¬ aÇx+d;ÜoÇÁ§#˜¢Ã¦¶hÏ´ô|•ÁÏÀ(¯¾(ä˜0,u õ@û6‹Û/ £ž~jMô˜ÂÏ[ů³ÈL®÷ÈKγE^©ßÇÆÖƒ àW!ê6‚ 8øÑ#°MjF@XÞ†)–&"†ñuÕ¼õËDñ"î¾´oÿé-r½^ôq}‘²ë*ysˆÒ[!žyi6™*Ö™¨‰IÅ;9Ý_D9—'ÄÔãJ“F$÷¦ÎòN”M}eÑ?•v‰3 µlê7‡ß §iSùXf$q‹w[*ÊÃ:îbg*×ynNÇÖú”Ž3Pjzým)õ1[ŽËkÂí.³¯è _fKu8x¬U½çžÈppËaŽ—îу2·®z¾X7öÅo™;š“`Ÿcfst?>Ð#•.¹Vãörê~aˆSàVsÐ2Êrh±Ÿ ,×à²] º—¸XÑÿjnXí@N&t(ølÙ\×±î;S~ÓOÿ¼Úázáá•,¥d?‚øßÁhâñÇ1õ×U^Ÿ»ŽVö‚æªrnZÙVT&›axɺBÈBtÖHžTämsÎåµ!=™.@"/¢CÁU)ŠŽM\¾ ‡>K‘ÐJŵ%c=èÔ£Ù7.³ëÒ+#Ì0O†ZˆÀ¿§Ôꞃ ¤¶½ëÐz« º³Wm^VMò² ¤–ÜÎùª èÙ@»–Z×XÛèchH½L°S|ª2+妥Wªhjžy/¸ö©ù3Ò ^%QŒ˜Ìû€ü÷²ŸQ–# ò™µ²…šöfÒ—*>%XjO‘o.í'Õkšß42×6Êrm€û(mm\{~HMa"—.Í[e*4¼çR['‰}Ë „äñzzýõ–¸À ]p–V‹/º±ÇAíBr_~l»¿HvâUdÁÆ7 ){êðÏUõõî£ aç˜àßPž?ÂVÉrLiD3v^ðl=½ŒEåÕ¿¾ÖÂשà¶Fÿû’M•Ølù }Â2 F)íW¬…ç BÍ“¿…)£¡rï­³†Yù£]õmé ƒfÅ¡@êêeUË0ÑÖBòã{¹ïB}WT¯cX¬– Û÷ÓØÌų ›ÔøâªÚˆNÄIÃ4Êí3,F{§>±ßѳ¤-”…ú`v“ʼnÓ@)î†Z׉=?G[yY.öîõ#œNÍõ®(ý-¾}6±2ä à¹6îFŒkƒhòì­Êc ‚fn,ÞŸÆu–0)•^âM¸—‰Ÿ.à"ÅÆ”=üsÆLÚ:tß¡jÁ´ø|WåNAfÙ'ŽœØíî‰cFðÁ²{©=ò³4Âf­$÷£ÈUÆXˆ×¶ËàÇçjø¾Â¶jTÉLƒvÊ6ui…ÏŠ@os—½žï-dОj‘ôóžŸwj¾ÍÄ•·á\°}¬ç£G«c¸(×)B•<ïÓå¸v¹S¼² ž<@ã³3ÂåêéÉ£˜fxâñ¬—µ¥2'yJ­¯¯/ÊWË‚«æçð-ÈÞ1)¿g [6˜¬‹.!?}µ/Wü×x&úh?ãªÉðÎK8ðZö\8 4ê¤êâ2d çÕ,Plã_*,¹§NCžª?N¿ÙÚ¥©7Ú§¼b¢ËY™ïî ÄŽÈ„œ$Y"_ Ø´¼(ZŽA&ýÔ^B“~ BìHis}ÿÜMôÄ}š`ú«9M e²Ïòþ×QhØF7h`,¤%}‡~ì_$ýJª±,@,ka÷ñAwùºÁÀQ öðÄý'Õ™šfg"rÁà/Ê—gØEOBûÍ9àêÑï ƒ5œ  Ï?ûøm_;ð€‰s4äæD£¼c|ªÂ,°ßPéM@1Òg+åç?g’&"˜éh'"‰á çáp¤ãÕkŒ×>r¹sJx Çnˆÿô*Ã;¹*í¾GeúS»AkvÃiV&™&á¯&½%\0ꘉ«Ÿu,nd:‚•óIÇÄÑȃ„yä. Þñ=ŠëóPk|ïQn"¤wÿ í“Âø^¢ çÉ¡ó‹-ZV-bEK¨“d‡¬ŒH½C£bÄÁ ÏR¨kB‹KÀÆK R{°±óÉ^T8ù¤êÍì×ÀoíÄi"5Þ]HLʯEü´¥ÊI¾whGìw’ÒÜzf7RÄ»ÑÎ|ä=ÆŠc«ÅØÊM­®ºã+Ôs³p(ø,Z÷ä)“P}íŨewBh“9þkXú\ód™hIÉõ:ýÆå‘}-Ü<,NÅ{®­'vl‘¡z‡Â½mZ~ˆé÷g\µ2Íè]>Xÿ,/DÒpô¬‘k¬ñ–á^“ˆ¶ü}p˜;aÁPÒ”ÄÒ¬¼U¾ðê~rv­­AMå Ú¨£°b.øôÒq4€ºÜ™ÊQS+äYü '©î3«ëÛ(I…R œGńŠöŸU¿`¼ÅìÍÓ¥ÑM†ÕÒþ°ƒ[É iàå·#P\³ÓDo€ü– ¯8•‹Uµl*­òu¿$ìeÈüà|§êœžF:kn3É®óÑ)tC›fÖ¨ð"͸ô¬ô8Îú OéíöµÕ¡Çe€²FZ‰6 )»ðÖ-*S:ýŽö®Éhü3Ùj²8ã%»Ã`xŽÿ<Ý$`ÒþµJ—Zí¦+Ÿ1t²JÆ]̃1íKãÌÖuõNßçl˶‹îzsUQÙÄ9ª³o¸Õ>z~†¡î b,÷!ë]9ÍsAÁÖ}¯¢±ÔùlV VHŠPô Ø_í‡&ºžr²saBÞ§?ìKäVWÁüP6dösÕø\ßõDÈtãsý—)YE,zÆHÅ™;Hó<–I·bÃÃ~Å„ÖÏ´rõ¨ì]Ó§qç=¥ºÉ‰§È¹~›Ë ïËõ„½FF~güY…m|5HŸ(‘ë'ÝÃTb½Ó ¢!µÞ~¤‡ëÓu>hÊ$鉿žŠmè¸óM-âH>)OTÁ?õ€õ çâ!mƒÉÒ Õ‚ú 6 Mž^Zå%_ª†ƒ¨ÇèÅáŽö½’æÇðé÷KnþFxíkíOpûŸ·¤è'ê Ž#B¨À#0`ÊÝx-F–EQ}KI˜Ýꢳ–«‰W÷$Cm§Eõ²»áSÆ<C´Qúî&eæëä%Úì]Ëö¡–b´Ö]Yp‰P'%†2Š¡ZD5’Âw)³—Žî)$•zôŸ73¶ôUšt-=¨]U¨Ç»ŸaÕFŠ!øBânìbko ^9..27nðCëQ®c‹/~•€eW³¢sËO_ ¤#À’YEm‹òøŽ„9, ä»ÝžÊ«§ÕH^êEÀGÙǪšpø‡Oð:2…VaïñÕÑeˆúí(ƒrö@Ç Ód*@_ô棡šb–m)8à~…tˆSW‰ñéÝt†”-ò#ž§ÄöÄ›üú/jB/„1zÌ=–>tx°Ðë+V”öá©ó§Ü Ùzù`ÞzòaåÅu S歊Ë“’€2fŽ£¨(EÓ¹ÇÃ^ÚbÒîäëEé5ç k“¨“ÎYXǘZ±§5ê=-ŠÀÁ¡Ì‡ëëw¶õšæÜ¾¯ülÂ{Ž@÷èÔr¥\ÁCÔDËö¢ßù91óþÍ#5¥D«eâglä9.Kÿ¸Í(|,A Î ¶òä-Í×RH6Úæ¿KÓtøÅÏò}‹²ÅežF2úá…'„;»ã€•õ:wFVÆHôŠê/ƒ,/90À ª:lZg†¢}Ç©Á•>±üËW°$N\!èës¸~—þPðq~Yš¸¦é˜]~üƒ,A(,©v…õ'·VµÒõ ¬F{¥‰¼ mº$ÐÐã6”»™®Þ þK‹œ:ÉìLË!òJkp¾§c­JõêºÕEG–†Þz6NòŒöXó@' Lh<Èt=Ajú2 +DØÕy±ÐËÕ-\Ì~MûQš(Áò\É1¬´=¯ã“0.ø¥wb2miItø6êNˆ$…gÜe!bñYj»Ì©ô¯@wÅÐTº4šñ¾p%½Š•éÄÈÁφXœíBÃï/P;\-ã+¿³ªèÇí¯'üE”$ß0[ElYP6×ÝÏ;Æj™+úÑX« ¡—ž#þÅ)Àâø~œ9ùB%S{pý°p0Kø›0òÓšëw\éY€ ­:xàj³ðB¾î–nK+&Àt9iËtî¤Ý«f²ø_À{®# S˜CŸˆœíOŒ«MwõbŠop¡lWsÔ¡àÜÚk¬¶ššÈI\?yj½%Ýà/Èv›áÖPzsS•ßPv^®Õì‹d²-0½ud‰ÔPñÌ´™´nÕ åÝIl½' |Ý£T_äýà¨DêÊ‚ú…è¦'U¶·lBMrøMÈ8EŠö|ÇѬËêê`šZà²y kOUD¤î~O‘unH¬’Çg‘Tè-2Qw›h³’DyÕñ‘s95ywhaõ‡‹ùéfq‡;^Bú¨ïÖb7A̳ÍñRâ§àTÿNA â1û/Ê`iNQ/>m"ÓÇÖ¶áŒþÇif‘˜ÌJóÄ»•%¯ÓMÆËL3‚VÂøjÌÐô|Ü&Âö$GF–È”‰ÒB¹è%¢tÙðq¡Awc—êp©´Èæsg³·hçIµ¨(ŒñÐÒŬœ‹}ÉËž“²q5ô»}Cr™èýžŸ‹cæn¬ŒÐ¨tŸ¶W}f}•F’Só2bÖܸ¥÷:sŠ$AsPsä¦ÃŽ“N1‹ÊDƒK\†ŠzåkfŸ¥îc;³6NËw5)&\ÜÄy»<±Èß-ðãö?5·‡2‰þT‚xdÔDØhÀ3#Ôh7Rb2–œ&Æë¿n'¤l¬ÑˆAJ‘¦éÎÖV{9hDZ qd+€è$TÙV›~ΨnŒ­Ï+mÞ/œ©0a?+w¾>ß;úxyg^†þëàêø·`ñÓ;”Í ¨  e¶Íª››CÿU“Ä·J#iê›<…=<ó½3.N#Ö(ëZ±Ð Œ]¢»>Ì“\æQØÆifñ‚'#‘8¶g¬lmÜCæ ê®ï=*ãò ˆf4ï‚NɽKžå¥€9#EV(ýLCÇUK0(ETª©ueT’J}˜ºÙÄTúñÓ: ×AWùÛ‰yzXý*8)=m«ÿBºÝâĪÕx)øôz5Úë£"¶‚óˆcT‡û‡–Är××oŸ'½î újÉëšiôXFûéßæšÒºk3 댣T5. ÙÑ/Wuáhˆq>›.V]MÕ¾\ÓbjEáãþuÈœ²HÞñ"ÃÊø+’ç5½¢\“Fª‘¶HÆ•}f¾£kb'ÞI‰(â~VGn! 'ìù™jïûñ»[ZT6"õ[*Ëò'wà©ÌCجÚ,YBOVá¸Ü˜%t>þ1ëplÙìçXÓ·3†S¬EÎ]¥_7´>zZ‚B¾ò¬?(à3Ñ\ã™æQ$v6 °Žƒ3¡ûK6<¡Ëëe¿]·p ÚÌf©ÿ«Ënvžc«§I$3:`ŠÌ÷´+(<~Y½Úå…‚Æ„oz@©²#mUs¢w™Ø§”Ûf©•åAïZ[g2gøÇ]ÖL€À=ŒòœUš0/›ÅÕ)àÜbüêÓ³‡]˜e˜™5RyŒèþ_‡„ìó˜øŽ/:1–ª’úI{ªÂÞœ^y¼d‘ÐoÿHºSy/·--ˆû¥5ƒ\ųϙ2YÃW²½&ç_Ü9Ž@œ D6®uÉ]éЈtέ¿ÑCîM1!’Ó¹Ø$ûÔOgãŽC¢)ÂÐÈ„´?Ë()õ |©ö@)rD‡1ÍJ'he˜é׋_4qÐí)‰F·•é{+G ö3æ¿Qó,lšÁú1Ø?Ì(ÊA\\n\töA¶°¡>‘Ô+ÃýÑäÔ¯úr oçXE¿Jç@,t°Îîqü]æÕQÁ|ßF3Þ&´®L¸56V µ¶SÝtóMHVE®’ÓI9å¨Rö«U¬«ܷӌݎšJØÛs1Í´ë r:½V²ð´&Zí“BhòµQµ/¼?9ðd9O[ÑæÂ™êÃzíLÒ5P ‚+¦ÔkÌ%þ$²öµËÃi—Ê¢ú•›˜ÑD‘èÙVS.HÊ3’µ@{*èÃ%¶>Ù5NT›¨³™Ï”÷Ü’Ô¹S_­Ê(6"ø¸åh7ÅBWl|oïg,Z¹CÛ]í=OJJ?˜J¬[óÂmlïÆïOk¥eµõHX>6²óÊT¸à=¦´þ>¡ÅÕÏü/*àΈ£˜S“¸XÈ)JšSô‚¶X@Ÿ¨ádb‘Ãvÿø´9V´`²Æ[ÌË9úà–õ<ÁXûŸ ÕX—´Åej•ØEâ2ta/¿ÓoòaÐ!ím÷‡·BLxD²“ @\‰£ÔɾdŽ=<,uu•uçç(Cihwœ oj*å;*«8#Þñ´Sº˜ˆg^]½Ó¸õºE°QØî%i´}ø½Að]$“”WáLÜ⊠Ð#úþÂü¢z³VL%îËÐþJ̧ÞÞ÷¨?–¾ñIJº»'°¸1æÿ´~H©Òð¦*»–Šá]1ÃË òïýÎo~±gÔÐ% Ÿó²f^käMépɵî#²¤Þ'˜Ýþ¥ì²H¢cBA´ºþYŸŸÒâñûd @[ðÊY`ô,×Ûy6š8(¥'ÿ¦³x ô?:\V“[;oq·ŸŒÙéÀ‰qƒ§ó»­ù©p½MK. ¨ß4jz«Õ”3Eÿ¢DLaU|%.Os'{s~61ß‘r¡n=ȻҀ„%¢¹#´ËÕ_ë¸/èx÷ìD8©‰Z›È)ãöt¶µ'ù†…&‹&°âzy5ê#Ú³¢ëÒVËpüÒçôYC]»wÂÚõ%౦Aårª ‚Ù{‚‰ˆ$ç+wJ´áy|ýºÜ=£O£™;O„¯z k´dÕ¬'ªQþt¦›9:쀕¤H‡Á¶N’¸•¹¯E:?£ð¯"a ¾1ì;º<œQên5ó&Šg´§ü+kœv>+´uƒrý7»íß<ÄkÿãÂ1ó–™–× ¨\‡_ŸþÄn2d@®òP¶$bž)`v.Ò}¹81Nio0.Ëe2•ÿރ—é>¨RlΉžÿhãÛgìŸ7pUŠ™…3野÷Ør'·ꄇ8›ÜØ— wŽ÷ÿ™t(³éʪ¶&l®. Õ^hŠ×=°AKÿÑþkƒå ¡·¼‚Z1`ø }¡Îök^ÛS9ÃüH¬å„£R¯“÷ö¸‡ýÛŠwÁS›_u§UÐ 67Œá,ß ?…H|Àîö Ø'4ØO±5µ»c]émoiÏËFæy.r¢ãƒ¦œ Û§/Õ0»0 Ó¦Á¶3P™•4 QËîlðöTÈ<€{÷Aì0uXzüØåUSCùÚA>¿ÃÊdË× Ùl¶³ºâ—hI†å´,ïÝbvº ’CÑRßæè€C¦§¬›Œ˜\Å[Á¸‚µµ/9¹gÀg‘g™`eç©'Þ­ªE‹ÿÖÒ¯sŒÇß<ÄÓ÷ÓVÏoÙŒ¼ çfÀ$¤¦AÇÐcjWnÏXr<{c‚m|¦Wn¡róܶôYâEòJ0ºÀüUo~Â5ÏC^OÐ[Cl_ryÿÃ¥BO*ü>gcõä‡DÅ좷µY3®˜i“ßÿý-QŠ‘¢¦È#û‡Á¯rÕ7Ï´ŒC.s›7) M>H4 T6 )¤“‚µÇ–²O:N6Coû%žùjwÙŒËzmGµ‚VÉ1gÔ…Z-A*¢Ý#Ñ–¶Ä„ù5­¥ƒBéì­Ûãå‚|‰Ì+ÑVáø³õ‹ …¬ýô%òF ,}þPÞ´ž$:äD”šýÔþ>ÒÔ7%Ã>Ìáú¢Fþ£ð(ÐL!Úzó»ðÇð`“ÕàVÇ{„Š#üv}æ6,B•á¬{X\xGëÝÒŽ\/:i Žât[ )Z‡4rE „ïú ZF0øI²R‰ MO©ÞºÁvùýY‹ª{à!:½ Ö»1Ôä_)z;‘«`:aû˜Âù´ñ$ 4Î$!î­âÖïêiƒ¢ÚCŸ¨xÌgM¶ 6›‘ ’[KB›5·ÇJË1!ùÅ3ÛÏñ÷ùÂv4Õµ†¥ÖH_ ®Pt“»¹)>ŒÉú—â4AdÌ ä?¥Èèç;Äl ¨ì×€6?{7kÇò?¾Jï„]ÿèä«w3Fú•Ü7žÊ"ìY!:tѦ+˜L‚WÌò8ÿûo“äªCJ·^ÿÇIŒ!÷еáçzr{ZŽ`4@tY§,þ4.¿¹˜íÚFiN&`ënWÃhW»$óÎ% `ØíUD] ˆŸç Ÿ™˜`zpfIb–7‹‰º]<ú­AŠ#î)Æ2Àf¥@¼  ÿM9v±_ÕÙ7nòò5–‹ø›yNÓy˜Iê7><‹M¬TådLiOÁ[9¢œm d±e¡€]+­ Cêië£cú™¿;ð¯_óåúû#¬ üAZ‹Nt ß)!ÞݰCûxÜD;:=<ÙQ&Â0A¸<ïöÔ÷Ÿzÿ!ü¿83oþÈÀ_°0e3ðŽ?·ºÜ¾0–FÐ’Ik® ÉÛa2¨•"LC#pN›¸¢|?“ÐÇtJ¾Ø-‘ÿ¼Uê_¾PqµG¦Ì´÷Ï4ȽˆVìcÿÅð»ýp3zaX_ƒñù`±>3í÷Rܪ~ÈkÐVȇçrTjÄx_c1¬eP‚hÑïŒ3èr)ͼ;Dù…¼m/(›y…oæó¤ÑB„­ÔÁ‡¼¼ ¬&©âÌ8_œ$bžç–²·e¯I x n„âb©6l&¦×qÔ„Í­BøKš²"9ö;eßü#^b¯¬5?œ_¯H\Šë²jËÊaJ¿^p&?šh=²s|ŽÅàüYü:2{s,s©) =×QÌOzfÑ€GGy )¿tîqúw0û)ãNE7²}‘fˆ5>Ù·k´OfÉ’tFm–©ÐìP?ÕHÝ{ãçÅ-Ò™©\( ­„§í3@â)Ê Œd¬UžÛàŠ_ºþY!ßft)7§)Su«ò`Ž9¯[ì¸Wž( f༭F¹wbV=–¯ÃmQzòHI ß ¬LÝLŸ¯™ÌÈØÜÂâèOhg@âä­:»˜©.]À©KŠ›>vöhO†à«òXÓÇþÍÇ”2@ )B¸¾;ä®\ÿO8$6$7ŒëbfÄŒ/r¹*T@ i.ÿÀP‚%›µÏÁ‹ÁùëxËb,1- f ƒÔÒYÆý°Ø%è,AF‹³¾ÕLÓ¸çn¿ªà‰·¿ØõÕPO/÷[Љ+‡èÄÁè“Fˆ¹˜÷[¸Vçá’àuÈôi.™ðV+“.@ëŸ1ΛÉ7¸?f1€X¥?Íû~:'ÊC˜5>Ìr6²Ý"„°lèÈT#˜#zB|™xöy¿Åø‰¶ð_ß_Õ£‰¾%áãá§O5(±€Z>Ád²9п54E=6*ÔÓø÷Áž†F—B¬ˆØö#D–æJ~÷[9Õ†ÆA˜ØV ÷Ío³v-„ièîüú0âò‘‰ fÝû øÌPЇefÇcôœNc±¡]Ä#öÔA(÷Üøþ(@îɪT¾…Röà'ª¶Qê@ ;Hiّ٭7MŒõÅõô§FÌëpÚ¨ìûÁìÜÕ^Þ+ï’ Ú0”Å uï«B¯^:Œg¬ßñJªíK°)r5U ¿íÏãÖÒ‹Î ;Öâ±éìÇìÀw¥õÄ6ôÉõMØ¿lM^ÝíN³Ù[šzÛ…(Ky„t.²•èveþðå؆«Zû|ròW£O™ƒ—çC\˜ùéÛŸEæ<9ù(³ç‘žp~YóË¢(úÛ„‹GêÚDkiô ß_ŒŸ/ožc¢‚„I"»U*ÉÏðg­“gÁÇÃÝì5­×ÀÐ̨#¼…Õ`+s¨¼o¥œð¶»®¡øßjSD˜Xò…à»'$\Sx¶¦3Öц0 @lŸJíªœË/eÜB¾²ŽùoeþC·}×l øU?÷åE€î'6¾jm•êëœEyÿ°Á3×~™¤´šÞ¨}ÚŒôÆÀul•³öBœpsÛÊ3ï÷æ=øIîÅAŠß߉Îê¼\zt¢Ë«²†AÉH^ݦ…"@>ÁøK-¹1b 1c ‰ê• ‘?WÕÝM¥!X¹h:O0ù½¯®yoõýŠ”†ù&Æêñ†¹Õ{CÓþx›McÒqF1‰°~®¬x0QîøÝÝÙ1‘R¯£=Ç'[î¶ŸÌžXû GßY£Ô7A,C4¥+ä†{Œààµa•ߊÄâǪÛlJ“ÚÛEqiØVއY½¢5@yÒû?^/Ô endstream endobj 638 0 obj << /Length1 2145 /Length2 12651 /Length3 0 /Length 13950 /Filter /FlateDecode >> stream xÚ͹eP\á²6ŠCÐàwwîîî283¸[pw<—àÜ=ÁÝ‚»»ÃG²÷9ûì}¿S÷þ¼5µj­î~»ûi]µj(I•ÕEÌÁ¦@I0È…‘•‰… Ô–òtJÀÎŒ¢`;s;k3 "%¥˜ÐÄÅ 7qòØY\¬Jf.o&œl,,¼ˆ”) èô&5˜z€.&êž@VÉ_BììÂhjâü&‚,­A@Ú71°ƒ§“µ¥•ËÜŒ ,ÀNÀþ =\€ ç7·ÎŒŠ2dMÌlÁîζÖ9@–I  vcZhÀ €)ÐÊÄζøkBCMBU ¥ª¤¡¬FËдº€LìÎ@€™•‰“‰™ ÐÉà|ócbnþÜÒ& €ºðí2Y1½ATsup;ý3*15u )€¸ˆ¢º¨ÉÒPSg(ª¿1ÿJþ€z{Ȁ̭Mþ¨+H¨‹¨ë(K°2ÿÉ€àöæÓúÒÿ‡ê-À¿¢ySµpÛÿu ±rqqàcfvwwg²tuva;Y29ØÑþq neýØÉðvwÚÿ¦ØdþV—·@þøSf€¼µÙ[.ƒÿ De$%ÔÔ߲Ÿ'áŒëÏäâáò7U q‰ÿ‹ôWgÙ_ÞÛ4'ûGÊ1W'§?¡)ü—Èé¿£û¯bˆ‚ßÂÑ·óö5qÿ϶5¹:{ýjÿ{!ÍÞÚÝÚÙÅùÿÌ´Ýë­²Ö ÿ×Êý9ÿÇ¢ˆ¸<€›“Àöv±¼Í°È\ loÿ†ÛñOKˆ[¿ÈìäÉü¿M¿-ìòþ_ÅÖ ó?阻:0k€¬]2âÿTzc!þ‹g t°€ŽomfÅüÇùßyøÃfýÃ~K‹¯·Ø`abç ôµ¶¾Ý½MÜÞ:ÕÉèëý?ÿN!²rÌ­Í\Þ¦ÿm± þµ.²xÿÁ~Cò_¢v"Íß­Fû¶ÒÌÁ ;Ï·îµ@dV»¼õ ÍÿßwÒ –tµ³S|3@ó¿Ôè?›Ø[Ûyþ?þã”ðOhþXù‰µ³¤µÐ\ÙÚÅÌêµúÿÎD@–v@#+Û?˜¶ÝÛp¼-ë?/?"–ÿ½õ½™-èì àâý+¾%ñ?@¿ôd³†Š¦¨”ýÿÖOK€ÌÀæÖ Ë·¶ç˜89™x"²¼5''À›õm~Ì»ÀÌ»¼©\]|ÿÔñO§ð°˜Uÿ°þR¼Üf“ÿ¦XYXÌÀÿAò˜íþ›äà0ƒAÿsp˜€NÖ`ói°r˜ÿ›|›Kfwð_úßCVþ³WþŽË¿rðÏWÈ_ZÍÅ l Ô²6{ÿ# &.NÖz,oýÍúÆûýדÁ¿9 ü×hþmQQ°‡7#'+€‘…ÀÊñÖû¬¬lì¾ÿ¦köÝ÷w¶ÞŠõ_ôŸµ=€fˆ ³`3þ`›/ ¡%~y㥰”¼LGßqµe`ÒÇ[ ñÄs6È€BùŸ2¨òÁòÒ|~)Ÿ@…Ú”ÁØv/¿›’ËÇ®ÌU„7MüüQ%D~~ÕdÒÌP˜(m'£Ý—ýš«SÄ1™ÑœÐü ñó@Œ·µã>†môýâ3™~ióò7X÷‚iÖXNvóï ÚçÇÛ ]^ï±â¢MºE覌sCq~ÊÂ9tu`n;ÞŠ•š ¯õLn @,¶uã»7¥aÄɽâuN«â”›=ì² ˆ݆žYÁ¥f…¦~ #Î'äÜ\ÁB•ÚGsò·IÖî,µ°ÜÉ ˆt|,Øp ‰@Jt£1ö­9RPqÁNÌýæowfµŽâª”5šÀ½ÆœUWù ¶f®Žo«—»Rh«Cs­ú^¯(Œïì‹<æá¤=ÛõÎN*¨R*ìÙäz°Yu§Ž3ZÔ›%/»í%]B‡ßõw¡dØìþܬÞ2«Û¥>Ì8ŠåU b§]>O›_9$dû Ð,Åa°ÊØ(aÞ‘ÈxäXÓ1acbiÖn.y÷}ÚTVÝâ z.]ïø(­rB¡ VŠí–´Š ¯Òmh²–O9åRBc)ÿM&eÂIÑ<­™KŒ4ôr¿]Kÿ¤‰€W"©jˆÌŽ•¢¹Gω÷‰˜Ew׃pŠÄ¤QÂ"§"ã÷¼ t›5<{÷øØ²çè8mÝÞÕ8ì"ÈMôk‚ˆ›E7¦?ÃÓ'­‚’*4L¤Ê¨´‘NB†‹Îx˜ÃSèr«¯æÄŠ+{q5ñÊä1l´¶Žî"YÙߣ~¯«”Ÿ­|osÕˆ_[XÙ‘›Zœ0’Ð#°‰¥pþ­D#>YzáfOq}ꃬ4×áUÆNƒÙZGáˆrÉEÏ_}'Æ„ªÊØßFñ=:^ÍÙ($b£ ¯ðÃÀNºl™‚¾9÷fÞÍ>íLlwhD•Õ &-»/fQIuHy­ —äzc,¡½6×Y©rßÙÉ!{H5ºuê¢?s"a„ÉU~{%¹Å¤®4Á·gò–æ5š¯uäóûÖôU˜ûùú ÓT¶T+ã{%…誰f-SV¨ DüoW=iªÕÔÚÉÒgÃ6cô]¡ñÜùÎI×Fk¥»ªÜÂÃdâq‹O=Yü_E"ït6í%>•eÛÿSŒ2XRPæ‰÷På° ×Þù®vù©–%ë›D.ƒ¥ÙÚ|k$Ò…i„©å&m0ŠÕYù•P…¨„™#Šúâ ö}éÒ"ÀTúûÑ}N“®ˆ¥þ‰“Wóšf°/;gbý‘xŸ.c¬~4FúÎÊ`/M {©”/|Ëšk("çû­ÀÆóÛ–¬žh38æ±AùX%A\³(ˆpYIN„3)Ô×¹¹æc›×Í‘m4·¤™üÙÛâ÷?Ê<>(öÕð—æ…A°ùi4æíßY{‹ü>VNý®Ã¢®gVšM2 ¦‚²¨p#øè VZÞjæ ‰š?6 R>Œ›IxǪ¡iøÚZµ½RZ'±€ä¢my‰9Ìè‹Uz¼4Ñôàâ´k»Æëªï‘+ ×ÏCv1„‚­$/%5— «§ü¨€ÀC?»pÑèXY³ž²1½€’\¨);'ÿÓÞ¹¶”© '(²| ð¡3µK|ÑÆ?È;³±íÓ':³yË98îú†-垌bé,âj@ ”õGx Jr›ƒ x ÖÖ€Ì=[Ó<•oá“qºqM›}•="ÇZ›d.(ºx-J%#y( çwÁÒ-CiC/Ë—†Iº&ÂÖ‚°öSÊy£¿Åiï½H0¨<J±¸ÆÄZ·ª>¸öÅHë³uX8¦øHQì"°U' ö>ð% /z{5y?…tºX ¼1•_tæ~‚¾W¤S`‡XŸó¶: _.hEHønŸWˆ$ßRíì.K’à}(!7ODâ‰"PPSŸáJèÓõ!'–<ýW‹ú)ÂÕYp‡ Â>0û+0Å8!]\Žì¾v ééÑD”¬TpÜV]ðú¦E‰â‘Ùé5ÕYl»’nVL“JèÆ¹E¥œdy!ŸÕí%õdeD¹ôöÓ™]TTâ¤I `®hÌsc’ŒÅâ¤ÈF?{ØuÓ¬Ø.f(…/“)°}v—¿É©J-Ò¬¬2P·¿‰ISæâñûrI›÷XС'4ç%õÉTÉ…"+'Š÷§Xä©ÕÊÅÅ+fy ¼¯HO“@rÿÝĺê r »42Øk­Ö–…È*Ä[˜·XÎÂ-yý­Ž¦®ØWôú,ðÃǯï«ÂЕJü.¿Ämdר^ÁضT>Þ͵הµ+¿{*ÁAvE­œióõÀäxc:'Õ@üû}îU†}è¢ÞÙ®N´0 LJù Èi‚¡$ºòÅJ÷DßiGVˆ·¦ŽŠ(Gb{B¸iþÃ>âwÚ DV—)z›Àžá_iÛG‰Má83Ç=-z‹\øû0ZP¡•Š¿(äÃ̺úÔÁÓ¿KésßmHzoÿ´ã:”%–´TÑ£Náqíµîv§hÔO+ØÒ—ˆ / Q`ƾ-ÿô ¾µA¹Iy¦·^X³#ÕO¯±‰ìÉ­"…R3àañaqœy4}˜:Ððù®pª@tó‚ [O›6m{㘗ØÞŒ,ºé }Baƒ-óço2zyÖ×£˜+þ¤uÐ\Ú{¦‘Åí9œ>¯KËVÚÓÒ\iê‰ýªT2Ô’Ò “x'º_ 7›ë9¸ˆ—ȵõ›DÔ`’ŠEÃ[™Êû‘È 2†Ã=ɪqQ=HH‹Ô·0û ´0‡¦ŽU¥\Ìv7ïnOCdŒ‡WÝÞ½sê«Ö·ȡ«e?þ„ ÷ËˆŠ¼cñÚÒÊÝà2ÕñjwRê  ƒðHm2ë©•%­ì§²þ–¿ßY™ÏîμªìÒA\½‹ÝhäZP¥@d®êÓS„§=wÀðïì‚èž§§õû½ˆcöeîXí6ö+7€ì«Èã±7™† }ùF–e”Àâcgô€ÅŽØ†­ø§[o¼–®“:6ˆ%(,¥©ÐO¡(t5ÏœôƒÐ-ŽF¿á®r7ŒÖN‚\%ïû¬uà ú`ÐÍ£/B.k(º³±'Ä¿øµ~„³e(ÓWíò›.w«Ç/9Y¬lî±ëXÏ¥uŸO¹6q&ŒQüMi¾N†®xw)èz…Ã\gĶC¯cù%’ÌúHk.ypMÌb튼«óF‹S¸·ÎæÞ‡Ž>í%üæ«Øë†UmèHººëÚ 'Ãñ¨†ÄYž q =îRfD¦ð¨vó„¨7„ÏXB@ýއ)¿ÍöÃî†ç" Eé…χâqªÌRS"ŒƒêbSJËýx—ç¦iÃÙŒ'áˆ@¼žíBp• 2Užäø‚6ªy±õ-ÂIÀV3Ò’›«Qy¸d1Ý=‰x¢es¿ûÇÈñâ÷bµ¨8)N÷OkÄ?æ³ ÊH°–»vuyx[ë…†1ü×÷$$Á÷òrXl¥Ò l«Õ.±PÜSÎOð%‹Ðÿ (u†ÿ6äq…%—î×éW&Ú]a RŒ5aê3¯äŽPg/²vÌѽº¤­íÀ÷'Z‹Tål*Ÿ2RÇ-…Þ[Ïñ`Pë'4Y3Ç‚J#¸úOù<‡Î,«»f†ö±u˜ýË®Ùkäo-»¸/¤UoMšfN‰G˜juäBº.`”³T!ÕdԮњ1¨‚:ŒÄ–k3zkF›ýUÖÂ[W7iíʈ@Y éJ;5|7„ôtýÁ_I®÷ë9VûýŠÝ®^гpT|Ðc×2Q^øù‘ÐMÚeöíkSºÛýÓŒÖ/'*ðƒçb/x³CéÛÖZ‰Þ´gvyô•ìi*FD8ü×áÄsÛã{ìs­nëc•š}iz-; Æ7©—{¹ãàÓÈð÷žÄ¡˜Å² 1T± ŠJ1åw¿užå”l²• &voœ–<_ï2-l+q>¿lµuÕRµ¼-®¸‚¼H:ïcŸ}‚Ú $+€%ÎüW$C+ÊTä2ÍéwÔÑæïí*~U:€±ßÇN;þ®è“ýMñŠ€3\4£f0Õ®šˆu¡;Ó+ï–rÛAo…Í^~Ò}æÆÔêY*¥ 5¡hõ´»Þ«:I’ ×&vi…€,ærw̱¼C¸äf,·Â¾{—èÚñ{Ö v¦Ü]ÍQäxÌÅù}(œ*ñOˆqÄÖ4ÇkÆ÷q©‹á!uÙ‡pÞÏörDsîƒ1÷ØÆm ‘YMðŽx9¢‡ª‡Ô W¨ÅâL„€SZYÝ2i>½ì°j_Þ*FœƶB3åh*Õžó Uß]ÎÖ(±¥gáS>Q-bŒ¸ñƒ×&C×¶è(ì†YmôfÑèy'ÊWšç¥ÆÔÕœêBuü|=4˜®sSùˆÉ†ïO@Mö3¥ ïl™@ ú×,f¡ôÕ1!S½0ÎØ€f\ï½a ÒK¾Ðf,)É|jO=V¯vt¬B jTcY?IѤG¦cÒ] už–ª‘Ìu¨Ÿ¡UÑ(‚J¶Ñqªù"“(Þ±{&øöpO³sƒV䤄p=Fɹ&xÍ!ü0ŸÒ³ *ŠÇ[³§÷d°¿IµžžyÔÉ“¾~DW!•g*6OïTÞ…xQÓ¬5ËV‰F<öhË50`ÒÆi‡Û_` ;•<ùíw™¬¸X烣Z¯š8LÊxsïÙ[Ã&܇ãI´ÖôŠëæiW%ƒºxhpW`…‘y6]x”B¶Ï2hi³0j£ª.X;¯Sšð}M"±‰ÿ!¬ÑÒÕ }ØÛæké¤têˆßÝ[V©‚øX %œ'>„þŠ£c,fõ['Y¾äÃ7f_—í£ÏÃðúð >7CŸ ®'y›\iœŒ×ÖP1­oËväRð0†É0…÷“$Óy¡¿ˆ‘%Mq|~ûdׂOwÉÅ{‡4èyÏ­ðªÈæ›{‡³±Õm·Åõ3Œe…XÁðáúÁFŠˆbÌ€=—xÍ.3ÇïT–‰ôÛyµ±+VdÙœ có;ILˆ¤·Šäæi¿ÎžVNäQ™–©J?U‘k ®Ö„OýçHéQUŒ‘æe ©Âú¾<{Š™Ç½˜"’àô Þü!ëïIæ1 ÷°#“cßÌp1D³Œ‰soQŽá¹rñ.”= bîœ}rëþÆX¦ðFÿ•@)*Gï™6d[NÉy ÎŽ>ÓàFh±%e­D%Å{RìT3ß½vµu°ÒÜàg QÕqqbh8¸O’»õ˜ E3 Œ;YL÷ƒôÅ‚Œ?ÔŒFÔŠ~Dñ˜Ú¢0û¦ÉM£¬òJÁ–Tˆ#Ôjåv±döè½³¿®ê&’Á(XLˆÌ/€^Äx Ñ|i•&çW÷BôC,S‰ŠWß+A6{¹ª§&/þ¿I‘Î|›oÓê5×¾¯e„¥Lƒ{‘lo,†ÎÓʇ˜$á§<'gøç1Q8²CŽºÍFÛ9_Ñéss»I’3±"ÂʼxedùMt9PRïmD¨tWضh¾þÂ*:äT1šA{B=û/ÿõý)¾},¤#½Wß à‰ý»†°¢æ¢+h¥{ ¡¢©Y€†¨Šî· CÔ¯Å|R‡3ƶѶ³¥+zZÒ°½\¯…“·lç¹bEŸ=¨ž…SÞ©ázÈÖ\Ôµ††œ—Ãìo6A¥çyµù¬,l–!>ª‘Æ˜Ìøn?zØ¿a_×Pgs0zbñÁnl>–ó·búÏéù”ݲHÁˆÛóa`û®k[bcï=@S„0=í)ÊÀˆ[örrfopG!‘q£·» á!$7˜°^©ÃØ2ÍÍÏ!ó÷Wš5ñ_«^ñàÐ%šXrž– 1ØÎ!'‘åì)CðˆÕÏ/m‚ù¿` àtùLÞñy;¬Ôܹ!õ e‰xò´1#0ã¸~sÅøZLp}Ç)ž¤¬†=?±sæv r#Á ž=§3æË]>J2õf=´dd]üøgPC÷ã=µ—rÎWgȱrgéñ/Yv<iÝ·¨ëF©ùÈù{F.8_2'Í¥Ój­KXψ§I~åpeá›*Žø[> ·XäK!.ùædk”R—cïӚ©‹Ý ((Pû~sí@²–7Áh’ ¬BúñÅ#Xª]%’ûJ]êðxÅ;¢ô’#˜pVññrã&Ù/‘˜XM§$Â…ç&ºÈð™¡Â_ž.æóÛë­66¶D¡unVë‹ÇìsuÌlEî–í¹ ßêX,C??äœ2Žßz¯qyÝå,ßßqMˆãŠi~`øÎÄFåƒ0‘˜7{˧'y]×Lu´“­Í•1[éi¬ &¯வV02¥-~ìM—%ùÓ:ý Ÿ \÷B=#‚¶’ ÇË ä,î7õ¤SŒÓ"+9w»9ÒžýÏ*khÄμäÓùŸ=]®ø[àÀ´ Š–qLB6iFa2]¢L‡Æ«›ø„´ÖôYüJVqÍmv{¦¥ {éÊÉÊA¦^è§oÈAVÒ|æØIyÙ’Š’üÞœeüQ–¼Ò\k”aC,ª´é§²!ˆqôÙÝ»Nnaï%ŸỎ¾JüzUÁÊ•Á†i‹Ò%íÏ\V¿ì«Œ˜•R_8Ci¬;7UíB^Ô<ÝAg§ãļÅJ%/S¦ß_6~¦þ¤×_ÊYš+!}Ì/ÚÖGîEƒ´§BKTª] =+ŽjrËÀ–f5ç0gØ­û9!޼·.ìVÀc¡/"ž¾ÎÐB°vPŠ˜å[5l£lÒÚž©}´ë s­Ku) Ùˆë È)%Wýåõ4Kú°œtæž”·íœøHY°]½uëL…àƒL¬Òo¶TDOgåÙmT´Š³ßæÕæòqù®žVՉׯOï1¸X1©ìÓLè»l(k³ $„ýöñç;Á刵ÏGS³7×G$:'d~J6œt{õ.avëcë:äPö|B0®žÏ4-¯Ñ}LMáK¦êcspÁïæ:!1’¤8½ÎX¾!¶°")Xb"îÂò1yŸ‹‹~+ÇÖÔÑ!!]†‘Ì•áÖ§ÿµé–¼«þ¸ümCPªõbÈ&S{›WyIg‹ÞXx#2Ê~¥^s’‘¿Þ“-Vva¦GJ5ë§q\LÊjóÄ7ejÏžÕ¤_E!+ÙÍ|ñÕ}b7äÑã PcF§û£×/Êk‰Äè½lÃokÀº®DÍwt2Ìš¶ ¢ºtÀN_¥Ö–¸&¹5ƒWú8áû(† Gù‘übF*×þ\΢éÁ*lö[v]Û¾Ó5Å!pí·Ù}šš xÔœµV¢27w®«5¥[$°uµèX¯4^Ó:Ò5dFAmÒª`Í€›BïoŒ.V"g»˜Ð¼WÎh§íëžš€Gï F&i]¾º»…dž{v›ÈÜ(QÀ*!Ô¡TTœx}ÇŸ4ÅcŒ—ÌúáëÊ7Œ¸ÖÌ Q¹Zé’ŨÂ}–Ç™T¯éÿÌ;,Ü®ØéÒèçÛœâ÷K”ƒñN†'…:©SÈ$%&ÅWwŠp.yD÷1gfS×-¯ÙÛ˜'Ì)7'z™î•CÅâ‡B€ìh«‘žtoªTéÑ™¹_Œrƒu¡˜Å‹zjÝË5yü“Ùzín mÉ0£1 ™¿ç•“¸ë@”[¯QSÝ;pÂRêÅàsˆfo˜Ñ–fQ:)·Ä“÷€G­›(Q‚!UÊ&¢÷|LÑgÚ&‡4¹,Ÿù·/ÚšV¥…i¯Ô U3èPÌGÒÔçSzÃʱžÓ¶-Î9ø#\9Üêgˆöé?ص…é I㼺µñàäLÖß?ÿˆ)¸ $â.&ìó„˜vÃÓÍÂë Ñ—éh†ø†øë•#­¥³´?мæ]D :MS±ÏF|"Ð1µª!òºAŠDlžñ䛓¤fC8¦t¾ep{ÆêDiÔ:èˆ"[Ú;i6õ*BÃ5ä nùƉÏ*´V5õ¥£•äï¡ð«ÇøHÞ-XnѪë[²ŠØ¢fÐä@;Œ eŸØÚ røõ\qÑö´™È&I±jY~h³ÛÌ2–H/š iEo€8ñÍÛvÎhB½3Ïk¿yðýÚÜDDM!†ÄOÏL n“¨üüÍ©T_PƒÕI§Õ’±Wó„Ùîh8ªð‘Ùû«‚ò—‡ËYV·æsí¨QiÝ ‚øW24;Z–"•¤½ NÙžIÓÓóôdüX°Å‘†Iš§ †•ªÆšy–fA?aõª™i…PÔ¨Ó:;ÄæÙïÄ–|…ìÓ/:Ñ HÌ‚T.?W’2Ê~•úJ{ÜýànMý,‡Äì’²ÙÿMmP„G‘80’™ é Íã¸ìz»Æô‹—>üiÐ6$vB˜º»ëçJvÄà‚×õ«]¾ª¬!7tú¬dÄŒd%¾¥Qøkyµ¾!jc;s%`î×s´j‘B”EéR EŒ ZVá(Î%ч>9æØN<0®£#5Xh–໸êɇ¬n Éóp^*„×™5ÿaêW´¯’ŽIèmE%x™BÏ=Yy³ê©¬f|ŽÅìÆ,JÓ¸z­Ê—ðŽï ˆæ×w›cÕ)Ç‹ÓnHÊ Z‘wr`ó‹8ýNÔeÈ-w´86Ûû’Ä~b«àå¯(Ý Sb;¶F‚s7¨›Ø¾¥üB=-Þü"ÞÍjð«Óµ3¿„r9-¸«eÝM Ú•UÀŒœÃP,ï³õe?þQÐKdyŽk##XNgÛj@ÒÐ~$‰ïÉG‰;^lðäHçHRxÁÑ×µS"¢ºãÚ%e3a<¡÷ ‘ ¡ôžRd ^èç']ú 1?& üŒÌ2•>òщÐ!Ò°®Vû)/ZÒ])’'I½á³fµÇ˜Ù¾F'X02¦guT_ž½ 5–5šÈZqõúO¸µ]•fŸ…ñ³bC­}PGã+ÁþÙfs"FÏÑ<àÅ{‘»˜ÜKQ¯JùÆüpÀ¥JPn)þŽTé©ÆÎ ªë ]!a‡‘©Ž¡&¯ë!Ä! ŒëÀ Í:Ú‹ÝIù-¤\a+-¹óùfÓ¾Hn™ï@€ ë°ýn?mM&R‡¶IŒ–ëAV“-+ûæ¶AÐFx^VuXölžúë™´5ª÷Uûg-ö@ýUYGKñ©‰,5c…d†xòm‹kCÍþÍžU ·ãA8jc`±žv3€½~ÕN…`ÜWð¸µïò2§¹½áR_‰ö‚Âä4ž°îBH äÚÒìDLlž\a²öìK‚¼›bÔuô§L%®:/å>ô{‡NþÃs%ñÌÊ®2Mhy ]P?=MþÖÄã ¹ˆ[ [=l˜ôf•ÒXP‘Tƒ½9ÎEÄ °9½´†àÂ3ƳÙ*òQ½ }—âÀÎ(l„»ö8Íøò0ËØ1bFÏÕ³8¥v|y/Ÿø.@¢Ï©¸¢ï9N5úUÏ£ ‘>ÙæVù¶[ )í5ªï#Δtx>I4+Båô1ÅB6Áôîpq=z!ËV¤J¯¼ºæ˜êQª D_ .þi®ˆãÔ6Bƒ¯Uó9RŠN)«!‘™&^Ë˾ðh†÷ŒjÓNI¸ÏTÏÐü“ŠS@Y¥’]ÁÑ5Ük·»>å’ñwÍšÐÿF+ Æ3¬}Mo@ÅëeŠÎþýgSQwYÔ/‘“ñê©Ä>iáÚ±ü¿‹9òªn${#»ðqüc ÇŸXTßSE&߆mîRmðÓ 5/¸ÑÔûl{£T‚ÖmlO9á)àEÂ¥n9cOŠ„g„q·Œ­(çY ,ì\—¦òPÅÒ †iÁ4ã;w"ö&J4ÔFøÀÖ Fsƒõ¼~ºã­9ž4wFaÁÝŒ«)4]@¢Géà3/ÆZ\NËÖƒø®UÈ×ô®¶¦U¦ô«1P£íëdšÝQ«}ó艰SV™;št”8L½Vü­N¨n ÃVc‘ƒéÆÍÝŽj?Q&®ž„K”—/–ɪ֩º_øs”¥^Öl¬w®!¼Bs¶%{¥Ù':ùªZ=ªe®É­Ïg.µe¿­6­ _Z[çŽÃ!ÌŸV¤hLòÍgfÙŽgi d|FŠ]4©»#dÙTÞÉ4d¥RÿžðX|ò*­?»o@™þK“½%)ÛX M ‡¦ÉHK‹ëÌ»_™’)þ³Ø]‚”>•jj.f3Ïò#ôp¾þ „®M6—g¦ot`7™^™Á×ÚOÎÖla¯¼R¸§ÓÁЛÖÙÊ-êÔ"Üe;‡n¨ª‘‘>Õ»±ÑmFÉÀ/”y×Oçë!Gût§B‹v!ˆr—û¡±§ý`ñ˜Ê")Uglòz}F¢‰AfÙ®tçF'°^‘ø<Êõ}Dz¶X8#î>~Y* Œn(«Ó)ä4^âŸ|:wšÊ:¬rçqò–g-ѪìS‡v;SŽ‹^DpMâà …YlæÍ%‚› –Y® Ññ…ÀökòæÜÅ2…f˜fJºnÑuá9xVw×OŽuJÔå–Ìå…Šð'‹ ïEÛQªX Êa·¢XTÓ”Ô˜£ôô|³)ï{»ÝÂk^¯u¡¯Å…/õ󑹦Ðrùö†îUMد›!ö-Nê¦îÛF¨¶Ó„ß©ãÖEÎ¥¥;{íH³³Gš¿+¨¢vh¹Ày,³”zA6bezêr•“qßF ì8¤§7*ëÆzŒòHçÔêIvÄצÌ{ü2zÛ´}£V.4gãÐW«K¿=Éì )[]“:‹fNYyö[Ïœ&íGh¥l¸ñ ÞI›Ó~Ó•Íù;÷_ÿÍåÜ{ vBÕï(ýb>ÉÄ>Ã5é\ÂSQnZ9*÷?tàƒ½¿Ï0õNäô=¡”"]²þ‘‹É»ú¹š8ß©¢§ (¼/#Ì3Ø‹eŸ-ŒÈp ci®K“ö°÷,yE4ù˜AؾÚ5"}Ôþº–73…žÒ“ÛœG¤þÜV&ýtøvƒñàÙ4>¥žõI¡òÏ÷^gûËsèÐJægÆU›Ðd9þkÖ_ÃíäD®$Dþ¢‘YœÜ0*C÷[„éô|'éÊ;oŽñó1›ò3¸ /Cr½ìC™ê§ƒQ£FôåèêŸÉW'é_â²¢¡ø£v° ÛîËè`…ÄèXe~4ãDç‡ý$Ú±×ù9„Z™Ñrm8Œ³3HŽe6˜:*ƒ57O¤©%ÉM£»ošÍŒj%ÊñˆBKÎHbÜ3 ·+{hÂþ©ð÷~Õ¾ª†šÕ™ød“[—)Ð…»ƒ©Zq[:‡Scá9^(®,wKTÙÝåÜ&š¿+å’;•»MëbREÃÆôÄ Ê­Ô"› k›”À¸eùž§Üs܉xû”~/³³EõÄ~I«J0âæ(¬ð~ƒÆ1¾¦ G‘YÃ5ij<›”@ªëS>¾iâÙF&¤‘U{ÁIþÏ™/ƒeîc™ƒ%H&?;/`'}f\ª"ù“˜kàÑXЬ¡Òcæ’Èí †kv½×P[‡Æbñ.Þ(sˆ¢¾6“vQòð8ëþVÜ•ÝA5’VD°"jº|0ú´R¦ÚÈ÷F?#¤ëýX–;Éj@Ç:ÕáËgq4<%·c_f+TOl¨.µ¡E2ßã„é3w3Ô„O/6÷¶F\ÅÇSØ÷ k‹eÀ•Ù`´Ä&Œïä]¥Ï š±s²[|n†ÐG[{Ä÷2 A±’ `L{`ÿ¥Ø:Dg¬ºkF—x¤0.’,Äþ‰Ê q:õ4Š/ƒækº!\2ËòÜñäOôeˆe‰ 0ýÔñÊŠ×Fnôy.š·s ïì±ÔíØˆÅ0eÐTJlöÚôoÒì^¼-ÃàaŒz×'6ü(ƯÜ':Z/ ކ?FH¡Úбq$‹¦]gÁ$œW¶^E}XÞÿèá̉±×l$»>#t‹ÒL|tŒ•‡£P\ÎÄP@%}ÉwFõù—úÕÏøR4% $“çgË÷í7'ÔÊKò ¬Ve©Ï&†ÇŠãWÐm±ÈüˆbvY„ë÷î.1$ˆ)„·rn2º%yÄMeÙ´°µ=%8$VO,‘#X³ëH½…8U=»*p°Ô@™NØõ>crPóÄÙiºÇùÝùwDýȃžÓËO5Œ,‡ë´µI<…ml£+Š‘*Ý´SïÞï÷ü¾7^ã>²BoS¦4C0AnË·áø·ž –à9´Ö‹9ÃÊéäcãAºT^ït°ä-ZßµÂ&£æäM« 0 <8»¯,é »â÷~Ñ|&|ôú,t©¥ýb°À™Å±g¶ßŒ4Ë;’—A;waó~Ç£qL9®Ñî‹Þ¯Ð5èBTG1bÈóaº¤¿8Óq]j5üª~YÓ¬D´ò¼VÄY–óu¬ò—° 2#Ê“ßìNåB–Ø«/P”I«*¬êkî<¹›Y6C¢_ 8ãÍ‚±?ÅÈ~{¬äâH¥vÄQyO(“Þ{TÏ‹$]‚¡¥à뮩_8óf­Þ“¡«U|bH@þ®CvSY-ý´ñôû‰·–íSrLÀÙÅ»`é–›vl†+AüøxãçèüU'o¡”)óAž:2I¼X ƒêj%ïk##€'raasè$†棧Q¯ÕTfãå–õý„ÈS.nʶ|'Æ*RC¨Xš1Îgjs$ÙfÉ’~¾îͰ‰ÚªO"+ú¿ÅYk¹ŒmýèìA±FµW7E¼ž]/\xÌ;¯Q0H‘Ä:-,UQAÍ"…e{þëgj½×ŠÙ&LQ~ ’emfÁY¬ÀŠ OXDCð¿X ŒP#1‹3ÏI±›˜`_Ói}+Ðâ]‘ÑÊS´})K½¸)SLÇÌÚÊ8Cè— âú¨ìãÁ>«ý„ß.Œã”s õÒ‰æïßs$°U*›×«‘–*Q’ŽžëºƒŽ¿E èBË7Cx&Ëê,ó×Ì=~²2ª¿' ƒöW)_õjˆpâµ,dQ±H2ÉíW7|2) ´ì»ëN\}iÈ ;·îHIÖaWÈâ–Í$´Ë~înkð:ëeÁµÃÈÛ™z—,ùÐ  +2 B½­¢aTœ òPÛõsu®ç ØItÕW–Ú£6èðéíp Å?´æ0錗‰,‚ÛŽí¢E㵌°DÅ'L»œšaõÎD¢:&®e7dyÀ Û`ÌìÕs·Ô¾$½ìðÚZ©Îµ>´'ä³î†–ˆàtó{¾4Lw·:+T'z 8Û*ïÕ_C¡1¶.+˜¶’BL&úÍl#@7$ÿé u÷ endstream endobj 640 0 obj << /Length1 3038 /Length2 28601 /Length3 0 /Length 30235 /Filter /FlateDecode >> stream xÚ̸ePœÛÖ-ŒÜÝ:Hpwwww§qwwîÜ!xp î,Ü-¸àëìý¾'ûœ{ª¾ûóÕE¹ÖœcLYëy€â½’*½°™ƒ PÂÁÞ•ž™‰ Ô’ôrªí€.ô"¶f&&6x Qg ±«•ƒ½˜±+Àéj P4u9;X˜˜¸á)’@{ 3hÑ `⺫y9™TÆ%WzcÐ2ÐÞÂÊH rupôr¶²°týƒƒþw €¹ƒóo€ß:@OW ½ ˆÕåwP€Œ±©ƒ‡‹ÀØÞ à ÏPpð­Tö ¥±­9ÀÁü¯êªâ*ªIEu%Uj€†ÐÕÞ”`jiìllê tvxA<Æffë–2¶¨YAc{KDU7GGçÿÉJTUM]’ &¬ &jÐ$ÕUÕè j ã_+¿E¾¤íͬŒ»Ë‹« «i+‰33þ®€àâ´ú­ô?ÒùJð'«¹³ƒÝ_*KWWGFF 7Wg G[êßj–V œm ßÎ@[à_%v³75Æ”È_~7 ge ª%派À¿å…¤%ÄUÕèAÕ¢ÿ]pú¿;ÏàêéúW.*âÂbòâÿmù·@+[ Ë_ýúË Ôd+[Ùß;PÇAŠ@¤®ÿÊÔ×ß‚mÿÖpAþ{zŒæ Õ.Œÿ³Õ…ñw&ôŠ jôrҢ⠪â©tpþÀÕÍâ·ïÿ•ã¿•ÎÒØå/ÉrJJr;c+{ÐÔÛ›‚ô¹»º¹Hÿ²>@3Ò¿‹ˆº9;ÿNMþ—œÿ•Ýÿ¶CÄ”Žž­Ÿ±Ç®±½›‹÷?úýï­4 ¼•‹«ËßÿSi[ Ô[+ûÿÿÞývøRXLtVÙ™, è‹Û›‰:ØÙ„»Àÿž 1+P‡\œ½ÿËÑ·±wð°÷ùo+æVöf¿« 0ssdT··rrJ‹ýÏ~ þÍè `@GÙÔ’ñ7å_á·™ù·T ?GG€¹±­ ÐÏÊúïãbìQg7 ŸÏ?þÁ3s̬L]AÇt£Àÿ]ÚÞÜÀý·¤ä—þg©þºÍ¨AW™™ƒ½­hhÍá\A£Bõÿúeôª%Ülm@¨þÏöüçNc;+[¯ÿsïlÓþNžê¿°r‘°òš)Y¹šZþݧ¿íҮƠC&loa õø/“úï‹Çt@÷½ÕïÇ€ž™é?×@ƒnjctq°ÿ½•ï?4ƒZù[1€QG^^\R•ö¿ á_ÅíM̬ì-@Î0vv6ö‚gM ;;À‡tVÌ€ž€‘ÁÞÁäptsõûÝXøßãÁÁ`þmúqEþ N£èÄ`ûƒ¸ŒâÿBœLF‰?ˆÀ(ù±¥þ V£ôb—ýƒ@ìrˆ]þ±+üA vÅ!.»ÒâSùƒ@|ª€Qí±«ÿA v?Ä®ùصþ »ö¿7ˆ]çùÿA ?“!f½‰±óŸeP¡L@£otµš»þ±³þËþ÷ü׈Ùô_ˆÝÔÁ4cÿb£Ù? ˆø‚¦4jÆ.–úø{‡“›±í?œ@4ÿ‡h§¹ÕRÖßÐýQYAQÍÿø³ÿvwpsþG@‹Å? ¨ °š`éåh üg ›Õ? ¨¦6ÿ€ ´ÿ)¤Ïîd©ùŠäj:qÿX%ìð‡äìðoË õŽ–A3át¶røGM™AÙ8ý‚²ùG®Ì é.ÿ€ ÚÇâvµtþáûÝW‡8€»ýé7(Ú_¯2.¦ÎÿT *û? ( t ÔóÄêõÊÐûO† HÞ@ç¿üû¤ôûÁþ×ÊéÏô?oqaUWg ¦•è]ø[äASë©ËzÒ0ƒì Ÿÿý¦ÿo’ÿðqðô¡gFzV6æßÓÅþ»i\~ÿækú÷ËÇ_O9ÐDÿ/þýØž@SøåESÞPëôæð ñ¢™Jh n†Ójl-™D¨å¬™N\±ümR `qPk`ö‡b9)}ÿÔ ûR-ŠP,Û×õ¶”ÏÓ7fÊB;ÆþòþÈâÂãy êÁÙòß+»I©dò µËؾe·'¶ÔÇE¹;{cY¦ÞЮÒHõ*ÛW  =Jæ™[0mÑ=¿£âw|Ÿéw}{ÄŒ1î^¦™3* Ç—qìíÁØÏm?8Ф2eÂèÎæ@4—ÏcT|7ÀMâì®ó«ã'ô–˜¹™"J'<'Apòçö…𓽟eSù„“§¸góÞ¦ÎBçÀmoÚœ‚®(dlz˜Wïoçêß´HÍÜø¡"‚u‚B$™Ò™m‘¤p’…ÖhW—Æ£²¿%%ÞâfœOĵàIs蹸K }‚¸üb›©xéðfZ…¢7®xãžVˆß¢ó 3ùÓîNYhî’²„Êà\¼æƒ“smCò#yÏ-AéhG°7lð;s¯ÐŽŠÍ…ˆ‰£¸)H–w쥈L)+ iÛ¯p7ŵÁPlò(kQoz.T ¢îc41ÆV5¥XØX\fû¼D¦«_XñIÎ󎳻-Ûs:¦?“D‹®lHýÒ_M˜fåÒÓÐöîËúz ŸÙ]~1>‰Á` bÛµØâ 1JbË®UŸv>ˆ†½|ö2e|ò'`m¬2𘰃„"†¡S.øÔ}5™Spe@vù%Æ:}„$Ý/S8äÀq#‹#žß‹n1ÜOBØ#Ôyò­\«xiîÜIòýÉÒ±íúDÇ~ƒ œO?iIÚPz-Q–d‹ÅÌ`H?ÙO¼Ð7¼¤òÛÕßrnGå8ÊÇÞgºí…=ƒÑ6sƒ=ÿ”µj¤9Ùªœ»ž×_q¤%"iX%øà\‚Ӡ̬ô¥ìëèçë aÁwq0Œ.Š©Îo£DéîŸ4«Øuü*–˧¬/MÞ„r=¶5d4kÐ\_“:­KŠsk²óÕ¾q+YâuýPà¬ÜùêVDB¬ÃhЪ=0¡Ó)wf^9éÅ{FqCÅ—ÚüŽ×Ëþ¼2·Ñå@!xo(D±A‡œª')Û×P%"Ë/ª™Ž9´°ÞÝõ¹f'ë'©Á^rpZR,=~aLoA•àUæL¶nîF&£òs…RÃ"Þ¥ Ùá*Êñ‡Ê¸ ŽŽ§ÝZQšx¦Ÿi†wX~ :n9ä6‘gX~ãHí]üÑOv{ƒaÒ¨NrÏ~j‘Ûëç,†•pBq{('R°‰½ažÑçgvà{«Âèïêý„u“1ÛÕõK2?*n’4q¶1(/®5xõ4Q‹‡Nû–iU¡\L‚ùTDÁÎáÕf›õà2hFêŠ+ø“òª%DºñÞúì'1æíA3ÏÌÓ'‘±3¶‘:["›üï7BwTҺпX8NýšŒ[¯DR³2bx>C"ñ:t8"zƒ‡óË·û»´“…¬'Ts ˆ ¡­Åˆ_¦x F`Z‡ÂꠚϠT5È}Íß¾ÞyÙñ(?ëyºÓÃNWWVQ€ ’–ÙK&çqXÏÝ€ˆó¥Ð v|Ú$m¨—òŒÏ¤Tñ–©æå~wØÎKüõCÖj¶•ükÁ•a,ÅP›ÊŒÛà~ Ô‚¯{BÖ½C`6:œˆ?Xw½ò¢Þ)ÀÉÿ€‰ælºæ5„^ =êÓ˜à™+Ìï«i8|fÒEØ–? `àáñëÈQøÍ«([-IâÏ:dÃ25ˆXPN°$>|M{'N‡°¹ìèã7©oµE2»6|QlùòR¹&ë·"®WC”`,£2:­Õ”ƒ• ­‘L‘¤6!¦–rg6csiuëïé³Íǯ-–z§ Ï—Dª‡U{€ÓùS1 ,ð#ßpu½±míP …gBióòdçˆsÚS<¾ß…™¯p„¹`ÂãGšb®²;§ª”gö6BÃWTܹø‚ÎÞ¬BÇ5dOBÛ÷<4Êçz{!!ZšYªçÀ&mZ…Ÿ­Ü©Ê•lÏObÝ ÔÂ"îïPž|•†r=Qß!¢O¸žÄ¨DnYnÅ„§äò9CþÜ·jtuõ°²l}êA;q»´øiôîòÊTŽf0…-8õBfä‡ó—ÏÈÑðYÆrdü@@^>Ÿ­´ŒÃ÷6é6»a(&¡f§qq9:ãØ‘_ÜE±|v õñbÚ0ÙB’Ïï­i¾ÜÔ¡ ȸ•:ýLùœötQúb¨Ó2ypŸ7ô­:uV¡÷ö;–on@Š”^Z¨O“©‘7š±z8ä"‚¯ÿ««ùôN- „i ôw¯ô‚æuµú±"l8Mɘó™5?–µ è)æ¡Cש}ˆÌîŸú¬¨k‰ÍI [ ±¥|ùž¢h®zΦ«½_Ænñš¦óVƒ†%UfóÙý{ ú{÷ ܲT¥ñAy.Ñš¬‘®*‘“ÌYøc°JH䶤lNoØP©Õd•ŽázJª{rî‹nÉ Ø—Pˆts‹J*hN~Ÿj¿@5ŽùÞ>SpüƒîÇ×E)+gP=q!˜/®Hñ㤧͸–¥±ynÍ{-m¢zÑîzüî=ÖI’2¨#ù?¦é»·©ÅÌi?ÐÄ¿½¤ØD@Ó ï[À„4žv£OÍ–Üð"ðv–,ÉЫ陉½6fœž ¸_nborºå|Ë Ù°Ãä‰Ý¼)æ•®2Ô(‹ï]§r¨î“T7¤ ÅÈÁR³LƦµo8ìκóˆÛ‘ØñJû†Ó_0*hÔc­ VÑWú]NsÖrvûÌRIqý]ÔÍã£4Ì`.α"ížwu*Ùê<üì !¿gGˆ“»$üüÝ­‰ àÔ/&E¨Z‹ È[K&I/Âð5×Öúœ^®Ís¸~þæÍæ®Ô¯šÛ×&â1ê¢Ð¹U9§öªC’)›½h“À¶Õ¾qr£)¼xÄ›G¼9V‚=êxø’…>G¦Dûnˆ¾$ì<¤P‡uwÏg¡|Ù çS»áÑÝÏ'þBP†¨×Ñ(ˆü§ÓH÷y6‰<_"®HNc”ó|Tɼm.¬íÞ¸üÆ&yz)¿ò g)‚Û½¬3£«8-î"¨¯­Úô_Nàˆ±o'eæN=¿˜èºH éC½éZjM豩8‰/ÒoXˆrÐÙ‚1a0´Jày_ ’L7b~ò>h|WÐj‘㢚È`3£+âxW1ZûÅÀÕÆMÚi ¼5Èö'ƒ `nU`þâ×Ýx"­ åw³S_=q4¡„d¶ ’hèVžM ³|¬â!TÐiYo æPav[À>5ÀAoûI^˜Èd›¾Ý…L_,Xªt8Épu?³Á¿?¬ï4™¾zy™m‘W"y†òœ•cÂçrŽV©TÐ=j½0X$T‰ß%ùúÀ9y¤r˜¿äÚ/”A׋ògãÄ­ž©ŸRZŒP˜Þƈ Š÷1¿ÏuöÓpWÀ‘“>¨CŠìÙf±á¶C;xkÊZ]E•5çiŸS îú áýƒbñ&9wf#q·[ìü¸Å#TQæ†Ò&@¯h¥ë&„\:r9EꬼšEw§ £ßáÂS­KÇ)Œ¥·ª2ååíp@³É«‡)¯}›‚}<‚ ¸q¬s´Û\ŸÂ‹[õÖ=Ô¿½ŸX0^õîäŠçá½ÜèM_ˆa_öÐÞ™âÆÌ@:/\L[Ç‚KÙ«G"]ÃUû¥3Ö…P 8U-N@fϤ¥ƒÚýÐ…¥¾Èâ°“N­ü¹1Š„½„ áÀqWθ=‚zÙŠô',y…VÔûl,Á}åÀ~°:\J|åŸîßÊ÷WÔ´¹bÅ&ÿÁ§Ì¢4eIÍKßBn„èwpÌUýÍà˜Æ˜"Üÿ–¬oqš®v<7¬4A¦¶QåAèAœÁp÷΂î²"ÐÈîÑÏÙ¦H0 7"%„@Ì‘ÒÇÞQQ€t´ÍwKvQ,Ä'F†åd~›u½' °µèêÖ‰)ÿY²[èɵ¡.Mí´»!QEAºØŒ¡“²æÀ9_¾ªÛ2†y“þ§â9­ÅpÃì¢ *¹µ¡&aÌ—ëó¡e¶=ÒbìµÅ-M&bP7õÕIkB˧^š°âÁN™im¾r­4¦÷%Åv¯‚­ÙG‰ò¥f÷÷4dŠEa±ýƒ Q«`/ ]²¨•”î¼}ã£Y_“ˆÑc±vð§Y›¼Uô³¤sP%ÇÍ11 ý#ÇÆ;>ˆìo'i3cw磱9·–^â†ãÈpv|ì%}¸^:cùRl,ÁJhå‹E†‹y̘¾èô6tçRAb¦|7=ºdh>"©ƒíHÞlŽ5»…XÛÖòÑÌ R¿lâiqˆÏ?lÒš‹*–_7ªè;<Ž\´,‹¾Èlµœqt™9Ë}APlT¯Õg`…- eQ Ά˜îl±úþ¦ZZ™¯€~*«Ñ,'È{CõÉ›³¿PöS*ÂxWã„Ô"0«_ãV‹ôìéDâ¼JõÏÁ™CpI\—ñ5n‚mìΚ§Û^ 6Y{áóÓ"UÖ«øržOÔsóY¤ÑîQÇn5ü²AûžÕÏ‹¶&ŒVk­ƒU8ôã7™íÜwì¯}–ꃪÌç*xº“=’é"β9'1l7s&6¤» ÿÄ»)‰Î&4OäÐØ!ð)þB06t+ÊŠ½lŸ¤7ODa#;Ö¯.Ùq>*!Sà|¹p9< F£e4JyžK7‘>iF_¿[“vk c䣘ܗøhÁð¥U#yj»Èópz[? žÇjÁ ¾—ëÐÄ?ÙÈJc’e…²­*G7ÖóH«ø¾¯IÒ§êÆU¼¢'qÖ§óöVn-Ë"­½µÂhaÊälèÇ‘š‰²ábh}VðGµWd•]GÄ!ÓÉì­/³²fëä <‰O³M=êÝç™}â<”/7­ž‘^]Jàè ‹0B‰ús ˜gÖëþô¦S‰ °œÝÑ·=éo7 Y?—ì¶[;ž•í”·TÅÖ-Y24ƒ„ •HÙ–( ]³†r_˜‚TÇaË'¢tûíáá ›´ûl"²rïæ¹â§„Æ{ûc¨’…u.Ü]—ÍLYÀÊrI9ÆåÔÈ+X#ÏgaÝ4•qd§^2¿—MZa8¡Òs¿±E6Rh%ë`?@gùTJäˆz²ý¥újB>`ª€´ÈΩÏTÅuÔÚ×ßãù9 ——1Kc âæi yœérÅà ¾Â4Q$áRÀÓ•ÛtLì w»oZ’u™{®“Þ¹ë)l¿P²0íx`¥ lÁ¨ç ¦x|–ÿWÿ/’ã7H.Ôx9*Û¦–CÌä4J]}ùGõ‡p^-R>…ãžF¸Ûðê•̾dü&f¬Ç]ß¶¾‡5ÙY‚ïd2_?9 ½ÅAØ 6'ÕÙ1ËdÉ<»™wüºrE2Ïâÿñ z­¡4ÝcÂ3Uð£s›šP¢´UÁÕ xÉÒhùZB óõ—iÀ0Pfù&`a&oOùR$U7rʃ@h>æVV§TÇ;Û>óuA娫]àÇd Z„‡?æ ¢É Âˆ>ÓÛúÚà½ÍuRð ™=\ˆ§ÝñU¢ÑCÈǾ›BýD~‚ó²ï&•8šZKœÒa’¯:Ç]‹ÇTØÅÚ#­ô˜bFqÖšñ^¶mðî&óWÌ/i9Þó+Õõ§‡bUå_…RÍ:ˆ'Ñ¥µbpgˆ¢ç7/ÀåÇ-G'Áù+Ï%íõŽp½©Ë*]vnö. z‚ýƸÆ‹åÜ´±j¢Úv'ñ&±¿#²¸{³*ó‰\¨÷¼1mE‹ øÍ<ï¨f8) (Wé—Pd' K;¶t¼¬yj)LʯVµ{¯4]ÝáÌ×Íô™:©FåTÆLšD°¦òÕìfù•Ÿ.‡Á»GæQë°ø,+;³,çäÎÇ«D¶!ðé#Œk}Oµ0ºQÖìzЃ>5–%,¼/³‡!u­ËEçT»w£€]÷iÔ+(ºŸu_Å—ûäùÍN¼ûÀGhj+Q,’K¿[PѯöbÍþÞÏ›îev¦é¡°ãh7ã>ßò(:Žq!òP&GÅ·_ÞtöõYQN$ÿ¿ÕA#R'i95VÎ’¤.‰‰ÉÐIsï,32`Rßð¸¥y¨ KÁ!θ¡µÏšøÍP(½šq‰Pû“º¤Hg̳J‡ é»Û8r‹­Dä|_Uÿ mI¹›«›Cþ#úÉ‹¯Ð:ù®æâìÏKö"8Ô-? ᱚÑt>kìå­³¥ÉÓ#4«°÷ê¶Àž A«f90©,©¤[˜]äþ|3õëC8qCèðã+àÊ`´àCö« Ð -ªDfÎŒÎÆM¦;'ƒæíŒHÖNf[ ”Göû ׈Ó{¹'ÂþBbq»Î»8ú!U]Ún Ͷ†,ƒÙsу4µ‡õ³ÿ¦ÌÌJå#×YcSü…œ{²–üþ|Á5,‘†Ú:Œs7ž•hËF1Ÿ_ V”³ÂÄ]Áüi[U¡ T—MžËq›B4p×c˜ÁvS«3¶ukÅdžQ,Š5ys2¤«aìMàL\¦U=n¸¾áI$“°:ù^æã|~õq–0ätƒÊm@œÞž¼uS›Ï³Œu©u è5í»ƒ2L‰‡eùJ…À¬øe3¥5—íÆ˜$Ú¯mdd|»/›—×ÍÕë1”Œ™žÌ€Â›`YXa#D»ú…¼†Ÿ=M­aìä·± Ämq'Ç´Ä: }`úk¤[Ð75òÔ£m#ƒ3Þ×3M*ú~gÛ¨ÅdŸŠ?‘Ò~9æ/†æõÁäc‹Üqy;iN!n»Y"ê*>–&ºÀ^?¨ ›õDdb8üºØQSjñ±±É°»K:òKõ‹S½þÏúe¼h¦˜´ûµ" u»\lXŸzáÖʽÎÖäy ϧ£/:Œ¦ÎI üáóD…ÅD#.Ÿ¡–¾‰±ŸlÞ¶®Qî)x•Rg¸àÆ%íT:¦’¡_ú?^LÁ™Ž&ùÒ Ò((e2Ã8_8·¸ôsM´¾©G'Æ]¼Ö!;è ½%•Z@Y«¿KßïØŸE¾I–æò/Ì me)‚Yç¢ øŒœ#UÐú’±{Ì1ãñ8Ã臵˜zâ3ì^gÂEHpœ0È]CãT+¯|-ÛžíéNr ÷’8a‚«ˆ’<šŸ,Í×'þl(-amë@ãY`^ÕÉà"¤äÐ#•„ª÷³ù±Gã0œ¸ÀÛàxYwæò“¨UØ.·Ô£QZ€tj4$^4(ö<ÿ¹ù ÀC,ŠJðº}Á¢/-UPq»­¼¡ÖK••Ó¾©7| ? ŠJºnm²¯ÍÒ«Ú"é]ÄšuÒ³\ A×,jý´Ý¬+XcÃÉŸ?%fÕ7¹Séçú¸ê£™1Y$N;»”‹žÔDvŠf.|ç; »Å©¥hé`b‹oWGõ¡ØE÷\§ˆy}ìˆWixo×`m:ŽCYÄø<õ½Ô±—´_dªsX)^.Ž£1Ž·–íýhxª²Ô݆{‘6'ˆsT,‹ztåÉï2(—ê†ÓæÌµ‰Jø¦¹$›ZÉB–Ïš°ž«PÙ“b._^éFŠ:§VÆWò¦Ì3«¢sÖ9ã!/l©ÜU&Ûh£ÑÐÀ©:6%4Ú]®ÙWæ+Y©šXŽ2Ö9ç|(µh€,ÖC¶Ec$\(qŒNÈ7ÁÆ¥¯'™ ò„io%Yt¶ÛïÆÿ%Du별1µ§QæÀ¢õQ£Èy'‹‚ßú]çeÓ7êîcÃ.7Ìã|¾lf§®Þ‰ˆSù7cwÕsTsÍØNpjI8 wcôü)“ï:\0E±çíÕM?%Nã$zº« ô+Y ˜®YŒ.g-b„Ã~Í'ýשU$}öïmjƒàh‰•ÅÍèGLé«"\C¿^Lȼ iè ÷~•É=X•žz¼œ¯bí›ì˜×ZÏü\6Ò0Ù¡ŠˆVÉÀˆ­¨ßàâG—™)úõ™Þô‡p’tµÉ¥G >‘µtÞ°C+ùaŽ^ÇÉk†"ƒ¨î²’óĬ¹ýxùÀ ,«ªˆ)Åý¨:²±åâMïÙÓøârP‘ë{ðÚáúv4lÅfñ{ÑÍqì­#ˆò¢ùË ):©L®oµÓLcßLQŸï­n K× ù­‘,ó†È±BZå°,cŒåÝ—wµH.~t|¹Ñ¯âVáW–Ÿ»÷ŽÃðoÆñߣ\Ž “($œÁQIgTe\®)@ÑZ¤rÈ[pö•âóÆkMš‚ «ÿ€”ýX#G$þí¶ y&ÿð ©rîµxØœ(ÅâüVá'ÇNdxÙ.T9¯š—à¤ü°I£ñ$VŠÄm?¼1l?µjìe†“0Í$ý²)÷^ŽF¨»ô>šD\{'M¹¹ÂߤVßý}R`XõnÃIAs]LŽ †¶À‚éAnŒ 6zO[y¦—BS«ÂÀ0qâwçú¼þ»8Yç›öï!¨¸!B¯‡ÄߪHf;9[Èòýú8Áo×d)ðºït­žÔ_ Ì<Â6J© `S८XKÎ.h$·4Ú€¯Ô‘½ÓE)›éÙ O‚G¹*¥¬Ì±dÞjœ·µ,Ù}惛{ãG£õ…Ý8ð–Åž •ÒðÚKê­Bl·Êæ­,qH@F_\1R™Øítñe̲?¯ùMŸÃ>²š×|¸6˜ŽÕ)ã†û䊱y’Ÿ9õ¶"? }÷e6?G˜$ƒϿq†è’GäHÓ6œuA¨ji¥Ýã-(H-ÿ ò8ÍYû—®Ô©c» œÖ²—A¢ã¼¢­szør3º‡É&èW,ëjwÚEFÇÕí°G5Õ!ËZ¡ŠjJFC愸4Ÿd¢ù7ת6¥/¯ ×pî°l¼$$ô‰”§R“ófl‘éÛ>‰ ¤Ï›M»Ý£Øª[Z¿ðmÚ 8ùd¸{³3,'e>" =jIƒ,9È,ÔƒòzÊãV5¬¬%x"‡ÿ·,€…^—6üÈmB¤Ýç>1nè÷8!½M«j~?Ђß'B5¼O?†"nêÒŸjžñê¤Ø&bZÝ®«ÏPÑTV/¯ðbiw{–·±H‰56—lÆ®¨ÜTϵfƒóp6ïùRÖ¯´Ü%ª$¦@ËrÂ)Å30Ô…[_Ç£VÏqá,µŸø¤êUEÚX LñpO’Nå0òëB@=á\}úŠœ:åÎàð7"=Z@ ¢E]Ë-5æìKÄ>ߦA8ßù¨c&w{K¯ˆƒ?j•-Ž÷]fÝ,Òߺ¸:a~_Ðx®ÑæôÈÓϦƒº†Õ3ȹ Á‰H¹ÌšZÃ\RúKGùà2l Õ]ÂO­*T½›!"«3/ÙH·hÑñàtq}gVÌí kY¦Ÿ˜µš$·Ny7 ¾4þÒMV~‘l"Çÿ*åQ˜cv}ÁÙƒdÒT¯o´fíñz9 ìYãvŠÁ‡–±qzã×7ž†Ød†ó+]}Ç%Ü$ä…ôELÚ67³Sk²ÑØÀq¡©·ï`‰‡iɵĔ–7ßMÎèë§&ÂÃãü4 Ö¿¿¯‘KÎV±”…‚ ±%Êö<8†óÔ}8¸WtØ”7¶Äj†“Js¡Hør`1«®]Ó]$ØsîÑît»“ODQϦǽÀ 6ªþd]ÜùŒà„ï%ÕKðkVbãr/^açé¬genõ›ïñc8’~IêxÓëQiØt9Ý#®ÚÌtpZuSn™÷Û7ÜK“ 9Ã0vì^áOÔßrkÅ F?0ïFIðË%gZ¬Jü<ý†.XuÎ:÷I»Œj𫜪30Æxé§` ykËyaöN X³ƒLrÆîõ!ÆLêˆ é…ÄííNÚ1vÌ*­xVP}|¡A,‡¹5ëŸG4~Òdø's¤~.`ËAŸN0¶Ö°Æãô÷—Cdie¥Yq‰Ïd˜3ï· ñ*Œ,hØr$S¶ZË!‚ík?xJ„L™Âµ@As}9Xl^‡Öï‹!hN7{©›ƒz<ݯ@YVO>Ï[ ÎæBéÿD³çja¯Í(Íàt¸£º°³‚úcMñ3¯lÁÕ~JÔ¹Ñè­–ÉcŒœ6j³Æ\õRE ÖÒÆcÍë}7B÷Çù¥)àÄb<8‹ƒ;¾m¢äôRuê<}(ßÚµwÁ9n½·ß q¤w»’)3g±Ô§¾K‹¥®žTúÏO²3 O6%5ì§ûÕÑ~ÓÅph€h+â—¬r QÈ_(?x¢zϘø}ÿù£ZŽ6™+•ÚÎɇF5V®Ù—¤÷{v7õÃ@æË¯2B§|ÈzŽçä¶€®%ä WUÍŒ'òq·×R.X‘CT›ž«¦í«øð¸wðSÞ¡&Çòð |;? NµÏDŸ ._0D©7^ÐÞÑÔ«*òéA¥Ðñw§àvh÷IlåY-[ž¢¡´´šä&Ñ%ZxšWßCaRPð±›ßšÚ”´quÛ‘V{ÕŒvz;ãñ’ÖQ58Ð¥?EïÝJ˜#Hm7üR)]ý'†²$^3õPÎ+ò Ÿ5¿9:lzy»»Mv97_b^Jñ¨÷©Ôë×ì´[$ãkÃASHÍ•¤• UyŒÙ$jL—àô#ÔïÅÀç£@†¦êj#úç7itcm%PŠa­AB{ÏÛ"öwÊéÝûx¹j»DVu_´« †ÜIåÚýyZ%Ò˜„¼¾Å ß’J-Álá¬KÛz]üjt¶ˆG,Éq~ž'+bG²¿ìçþ¬f:BÌóJþÈvoäi<î­™`Œö¡{ãÃ¥ÓàÍÈ;§ê¥Iß´ƒ¯N‘½¡ì…oíÚ†ˆÐ ib÷ËíQ9d-5úFh;x…üôjšÖEDuäê›]á˜UŒå釤ÞK*6Sƒã{sï#Òss¾&i¼~}eÄÙ´ø.Óû±)k)ÇZÐ?L[ž‚’++À§2íSïTÕ KjZØg ©^FyYZ?áyŽlXå,|å"[ñÆ}M£‚.)L.y›1=næõ¦ÌaüŽÍ¤äf¥_ö qðôrm“„g(ÝSbªÌ·³u(|Âû”õ?2ÜÏ€1JUtq,_>|0Ä7UQsãĸ•¾s2»`ë 4"­„ê´‰â-àÇÅ2¨R iç ô‰\Ù– g~k1%óR Fuˆñe}ÉÂþ|!¾YË'± /J)x8E3¿ŒGWQ_˜VÖ°ê´þy¿(Aš×U{Œ LÏ…^ž%®è h–ˆ3=ù4@Ü—¯ì$1ž»mù7Yo¬¥",³:[=´ªíö™«ëô©°B‰U£"“¶¨ÍaÂ"!¿¼÷ý`{æ?ûùŠ»^\(k¢±”Xžõ=ðì’i£LOF@‚Þž ïÅ6JîÉ;Óø¹(.ÑÅh|¯P÷™¦ùÌû0?˜:‹} »“ýܲ(ÓÞ¶ˆªgX³×ÿÎ*Eã"=ßw”@ H)9¥Cñ*¨%»cü”†û^ü‚†³©â»‡ Ø›0•2—ÅÏ—ÂMŒN7yåç…ÉÔèQcZÎm/Z¨†«¶‰j\ ½ÌÜ–¢M5)U¶y}bdüáOàzðë²û+šH}Wûëq²ÛìÝð÷WÍÉL ­Eòé4UE! ‹-ëfë8‹¡)½7ÊÁgß|+Ž5âZ“­•ûj)öNŠÄæc6:y¯:À»ì§PŒmƒ7¢¦ÁËbµ¦iŸê¼’›‰ I2Îm“|€ÀНàDÓ:®·K[œƒ]ëuB^ζłcÝÒì2†?Õ뭈ô-iÆ88àG³“ w¿#Þj9†ú \ŸE^eùt@l„¶&“ÀÚ@Ï®=;¦€•J·¢l²úa³ú-é Pß\«R¶ÜG0Ø#–S*¿9šÄŽ;eè’ Y£sõ#…ù ;ÑMS†húk 0{dÃãYÈç6á ;–¤bá-¦k£vÌ\ïÙù쮀ºy&[å†o¬1p»:Ÿ–D~_çÕÛöùSrNÅšØ÷8j<+W/Ë2 !)/Tr˜C,ò•9·ÌþS€&9CyÙJ"Æ™¢…é€Ó¯ÍìC¦óJ\©ï÷QÝ cÈ*Ei“Òô1&óh\¸5ç|Ù[óklHAÖZǯóÆ´ÉuÕ3Òuâç¬`¸†µu,9?iæö׬DŽþÊM§:„#M Eñl»$ifñAƆZãù8¬Á½†!±•ºØ4Òé3™¥FÍîFÚ?Ï´À™)šìOF“4‘謔EãxÞïöoÝ0¸d›…Iò +N/ô¢ÜZ¢Æ¿õ…D÷ÙJ €V8~6„¾ï9æÜ¶†­’?À›Ìó3×¹]ðÎÆÚN¯Æõ|¥ç‘â}¯b¿¦!@kƒÍ‘ÛzˆÁØV_µštœæ^6Æ£|$‡žžµ‡‰Æ’¥\­À^ÍUÝŽF ‹SŽ.ŸÞq‰¿ŸH:]FR•$9N¢£\Sª_ŒƒýBØüVCé"æ÷†%(œD±0ØGóËóÔ¼ægÒ0Z²âpFÝJ Q¿þ¾ã_ž“_:·ž³0/Õ)3w>±Šà¶eˆr™sÉ+pw(„39yc-}h`—À®L­òÀç^xq33%m„_;nì»?4t´G\”%6ž°§×D—Ãi(Ô f«[*²®fÏ3»R8Ÿû­‰.ÁvRÅ,hÄ­<~Uå §7Mݾ®Èí{WÚnޤѶŽYM¤8ر3%GÙáÌÿÚ¢ÊvÒÄzÀñmK¯›«‰¦´°PSö!‰Íï,ÎΔç¾a«ÇåeWÇ ÞÞêãÙ8üT÷ÍG)1È‹ëæô”Ò' ³vûž 9ÑfÒÁqCïŸTŒýôË0xƒÏÓÇ>ª\!(¯¤ÖèÖߌ,‹ë UïÓ¿•ÿ:‰w»þšÿ®ýê³ß@cN¥¼:oºƒ:rq åD~ȇ6µ±<>.í"8ö½²¡d)0‡Dp¦CÏd1ô—8Ø2SAD&é•U‰¢épO,ÖóËyª»D uõM¡Êþ{ ͬZ¶bŽÙÊ]búÅË‘>¥©'¹sоBY¤µf¢w.6šQ3«"¹‡š9¨M ”PuCò6„›$‘-±pÊÀˆbÿ-KƒêËO1ô˜˜ü<ýC+侸\ÄOO!Íc½·õݹ¯áʬ¤0·2u–äÖº~ ²ƒ .÷JÜ ßÊ‚LŠäNi½ É7J>„D𛦣º¡ùr ¡¬ªW`'ú¦ëg¿ä̦üÃ#Y ØõNˆy[û’`F~¡-˜‰T„éK÷€W]1ôÙ» q(íc/Œ”-G¤œø1ÿŸIÀ †Lw´ŽoPe>‰q@i?zËHÞs>²šj}Ø Œq©Oaâ+Úš±ÌÞ3 "”cŒIpñ/EÎ6E£›é)†Ý£¬t$?ï3‹{—uÇ 'Um16BvùÛ¡×µN°$‰:Ž1Ôâ4ÉÆçyh??J›qwS±P/uF Î͘•êÌ ˜y‘}Zjæ ¤7ç ¶šC‹”h·`ƽ¤w®;z@ywú#ø©Å!äZ- Ò ÿØ!„Eáa ôW¼ÆQÚ¢wðÔÿ†%LþìâUáseA/qû®Ÿöþ²œó£{Å6,Õis22ÿ–°J CTtYðWjuŒèZåMÿÙ¬SO’Gô•ñ¨Bu7š”ËýoEe=f×øh97ÈËïüObt] Š_ñò>~ú8Lò`.V£qcš´¼â›úQk¿"Ыý{…×Ð Õ“‚Œ'’B ƒï»÷ÈzEa‚p*LT¨zÔê©òd7S¿0v ݧ#“Ù‹ÓçæC§a8ÍyŽšX9ˆîLÃ$I”¯T”#Ä,jn½+[5ÙhU…†µ*F£^kß±¼oºÏÇi–3 a%"jƒuR œ•Ö]³¬š:CëEðCÒ}zëJëžIF;‰,«dÒ¨ÓWÒÚ #M*:Ù^TK„ã–±R @„¶ûÞ>>>yA ‡‡¡à .7ú#Ê ùt½ß·Bµ¢¤±ÞU¯çʃGPÀ;ÝÏ‘_]0ªÿµ|ÃYàyº øÕƒƒÝ‚Š‹Άïq{)Ò̰¾”Ð%ýtÉó_ô•ë·ˆd÷‰”™¦'g!ß^²‰V`¡°WšðŽ×ÚÎÓ8Ô'xO-Q› Y·¤”’Q67ÂÏ ˆmDX¹#»hÁ^w ÒȆ ¡ÒqH/”µ^¼“=šX®5Æ”â½ÚÊŠ¦¬6Á/ûÚ-a‘Îx™|Ù¿­Â{-*˃gQÅÎÝëb¦lFy&]to‰¥ DÅÈ¿)[®X&ß9☓»ýíî•p&Äh GÚ|½}¦M¶þh—ÛÞ4¸å¡”î–užî1Ís#s½•k¤Ñè䋯Rª›eáJ"´"™1ÀM» ¾Ža®É`䔵ž¤ñ‘w3¤øÇä6ÙñcöN¢@4K€¤B„Ö/ÞQ4ë[aœåúÁéÞK¡vñÆþ=ÌuqM?1| ˆThºI¬×àgWö଴ÀQŸc‰=«s›<Åô@2Õ*î.™W)k“ú¢ÌdØÎ³Ž”°¶v«‰(ìâ—ôçXº r²{ASÇGw~wúJ©I©“LÔ…:>_­g­±/Ô…¾ŽÄzu¼{߃Îg=„«ãïŸe)ê7#ŠÚh(ú9àW—ýàðÀåCm[¥á(+ÂŒ‡Ü­èõt~qô“͌ǛÀúç*ê çÄ:ÍAPj–P¾üh1¼ˆj™sö³YCš Ž·ÌqŒáᇓØ eÉ<à¡­ÈònñíM¢ºNE ¹¨ËÎ@5íŸèݶæ¥uÆ-ÏÓXÎ õÁx é®]2–à9|>¥7¯ìó©šý–fü9ˆ@cÜ•€\îuÕí°Ÿ¤š‚¿>אּ‰ZªK31ûj¦¼}mé“ IªßO7)>"Š’ c’U;…ìÛX‰\#z¯ìúXéÔZ#?q³»÷˜KKŒ“5Võ>³ó®¦‘/N»ÁyÑΆÜsÝøYΚ¦.³y5v…[Ë^sc¬‘•-ÐuÍàè<«N܃G–Ô< :ƒTŸæ¼¡:ýLu{.\O¾n›%ši?ñžÆ ÏG“)øJ`­&”pbÔ? Uf¿dzîÄЛ e<丽‰á/TÜlæ “Ä¬f Ñ“Nz^‘ÇXpJq0–5Õ¢`Yü·Âºâg•"„ú¤‘ŽP&Á ¯î¯ozÒ³Ÿ3­-ªà0¿ó‡åÀTÂ7¼"óªL¾—‡Î 9ðüNÒ9t0tõ“•¾E‹ÿí%J!ê$Kf•Æù©%!H@±…:ΛÎQ ȶï3=USkI#Iïö*…¥ E¬XžÇê2÷SoÒ™¾F§}aŠ:¯á³n£°™øÌq“œüä›Õ@h]ôù zíÛ=F¬ $ ×xÜÅkyšM;.ØÔ++NbÝK^G ¦Þ£4lnÄþ'ÒKŸlNÍÚ¿ûA¤õ·˜Ú;¿jUU [¶’÷$5ÉÚFº|š=üîŽ>×n£~€H’9…[Øp˜Íœ]<ÝË Á3DŸÅëù8q)ð(Åìô/ã)ýÙ‡_ǘ·ÒS}?`Uì*¢ˆc¤›ÄŒnÍ«If=8&ØJ¾weüWP‡¾oYŠQm8#ü]x©x´-F7á,[× <ָ뾊Fög뻂§—\p]ôü[×”AK‹ÆvƒyÁV 1ëòP4H¾·íõØOVzñì{QF’‡K§~ÑSï¨åé^šÎô¾þŽJØCŽ£á×ÄLã¨×üë‰$Ò8Yîã7â5Ù5Ò†qŽ[ÌJ 'ý G¶™cE’6wÅ«F—.} ìÈn`ò{&¬t¦D OƒxÅ™eãÚa‹™Xåki]ÛKSz˜l$;˜y¾ð›'igÖ fz”¹øJ|Mhîžl=¦þlˆ‡‰á†)‡l ÝÌD4BJ½´^™_L—eüý µ\¤§û g7|P܈íÐU=uaËžßd9oî"O?Õ‡í7ð´¹8JsÔ?8!²F@¡í£åXû¢ÈÐÇ{·ÉC°¢€Ó€_»!÷Ì7Þ®X«¯³[ŸA[=>ï©uQzÚD P8û;†v—aÇž¿Bp¦gýx¹ûSŽQtUøÇk[\¶@´ðÝC·<9ãŽí+&‹¤B•cBª:s¯™µ²¢æÕE„\šñ 9jœÛ‘BP£Q^$ĸÈaÐØ8Ä|Œu~ú«IëúÉÒ¼3†òu*_d±ìÃÝí=Apœ‡›á¾¤¦-·»L@×±\‡·ÞŽèD9õ BX±Ï/tùã@íþ¬Q$ éÐF*‡Ê^’ÒO«J€‰¯‰InU Þ•9 ç9ÊV¥~ûƒŒC&ï§l–§ó¯X˜?£üz>ÿ¬òåÎËä3³et¶xýgF&ò¯*€­üåã¯2¡¨‡ûÀ•o›8šßQñ‹ìÎïj6s×B «·ma£KhäÕ3·f¥2^ZGR¥ßôUqµÏÁ…æöõ¬ð„²L?oö»ßËT·)ùxÓ–iª‚«”šrXàl`Ÿ=kˆ)ñhÂÔ°‚E Žzé*ÄÅfò’y^Á¢‚§¥âƈ"›`Œç@,¡G¯@Žðna4S+hJÖz§¨©µì Ä6…‡_.ZГñ~Ôõ2b|8VSohvô}¼3eUð²É8q™¿‹µþ\o†ÿ!Îèt¯:'¤)ÛÌ`º`ØaºÞ[íè=âé9й¿r¯ÐŵcWl›6?Z²ÚªLòÏ–æ[¡\íMÉPãÃi¢1zoiÑ¡Ÿ¼^æ©È9ÈTÊÒ‡õ#MnIUb-cÂ\1~1¹§IØ@OŒlJL‘_§ÎbKâ^À!©C¼LœåZ4QV‰mY‚³òh§I€yHÈùuŒêî-¿'[Äp²ýC©DÔ­´NÜÊ–ÍMI=)ªË/w78¯R‚*aBÄ!Þe2Çãª!yõ{Ž¥+'ÖãC\¡-EÁZGßgBE:›Ün‚¦PßY~=1 &¾î¾ÕÓ7[°GºÐ_R;N¿ …I@Âc°øyEÈôf{íÏ åQäàî~|Œøæa43Ò5 »q£,äK@°u}éaá| ±±|hè§©ƒÏt;ntŽf‚[{Ø@  ÊRLy]õ²C|UvG”3À]8nõ“Ìа¿äåMcÖ3ÿô)šÿlߨZLJA™禔,]DaŸeR?S\c£î›B@‘žÂHÃ1§ÉAž…e×U§'#7$ºX°_{Œm«M©>y抆L—¤^§?æÅ:Ð|yé:vUÓù2 ±Ø„l¿¹¥_üðDÃì:Ä8äˆæ8v÷ l‘‡.TBÉ·oâßé¦`zyxiè+˜Y컈óÓJØé¶‰U–öñ·ZTYÔ* =¦x玲F[¡R†9¯&lÛ&æ׸¾-Åqû5 šx5{ò̈EœçÍN¥ Bbp>òY°¡½ÂìéRMp5Çɺô_Ý^X2‡÷Ygq.ü,Ø ÓCHÕ&Î'3[…6‡kÆ %K’OOÐvšaœN5ÌÒ«Ï/ùÿ 4ûˆfGÜr—Ëžðñ™¡4âÅ8؉Õhò÷õàÉWåñŽÞZ€ÄȹŒLÀZ¶êeP ŽËŠŽP^ž1¬ r0’Ri°‹7léÝøT ®Åd¸ý g…ʬmÿ¢Hù_ÝÈøx×eYWñÑÐm¤R[ÓA´Iº«­Ã;ÈË“=¯Õ6CKµå‚»Ï+dV>´â˜ŸÖ¾i¸òm%.¢Ô=ŠOÁã5_eÃC añŒ%ŒyÓ™^WÙæ`@v ·+†LØ`G;Lz æß‚ÂèfñM4OPI‹è±ó5 ã(Hë¬&%ÛTËŸ/©”øoïOF—CШ’}sc¶­÷mê`„GŸVŽå\ê$-"~ÇžHqt”OO¼ÉÆŠ¬ z ‹@ÀˆB-[¶îÙÖuØÙ;dzÈÅDæ„È·& °î:, §î)³*Èêª7}ˆ1îb/M JÔ¬kŠ:ÍËÖÒËíp«\ÕèþG»ÏC ‘iÊvšæc`ªaæ[ôíK-ÆïÝx„k À”}u$Ó}Æ:@ é÷a×ix¹!ªñå"°E'Bi—Òä!q§Dc¹•ÏcydX%”‹~çЪqÌòc>Ü®¹¨c;½`°¨Ç˜ˆ¢çÉæbÎÊËráL/Û‡©GB\KJt0„5¦LšEmÖ&] ¿ýA$ò¯Œm1¨›é`9,ùc©éü¦Ki³ƒ FsoIܨü̱$áúÝúóÕ•å$)žŠ™°·.™ „ƒ6ûn }dœÐ®;µiwðèÒXÍöR<÷¶2\LÎGhHC z„Ñt•d’ÀÈ©ãvžY¤è”6±€àª/Ùì¥ý”‰3/`jí©~§I ÃÌ8ЧßOYì¯"N'@sˆ×$XÊÏu¬/7¤LJÚÙ"Ç´d€à~àq¢‘îÃS$>"cÌ)YBœ]ŒyŸ¿B.Æ‚hâTOz×½mÉx×erؾÛ}n‚-ur@ˆ $ ¿©T;–wôÞ©˜¦0Z¤ç P“xoÍÌ \ë?Ä,é ¼ŸêúúÏâ Xvªç¯‹µ"d¶ìÅúÖãÐÜW£‰»³ÈÂÙB¨óé}z4Pu/œºHö n÷¿‰Üy§¥QÌÔåæ–Æ”m/?›Õï'ﺚüÓ þF:²ªþÆ«ü—büóÊÔIr“BkOÕ­éÙ¯*]#p×ò±\îJÿ Òíó¨¶Y·'-Æùeà-¼êÍ\ˉº¶ÃCï`g Cúз Ò i¼qJ‰xëqÔ o œ„(eðu÷QuÃßüöcY3†í¶ió±™»ƒd55æ¶gâÄVë@ùÇ[sÇ ²ι½ÃÙ²cä\8H) ¸Åv®@_0 Þ6ÙïÍIÅšØÏ©·ñ½¶èÏ­ãïÏ Z¡‡èªj~z&˜“þµIo|kÞ)+´› õªºöq°,†È@„QtYlnžÝz2D$¾:K ¤±5̇ ³8£x#ØÐËÎLT·ÎUÀ±è2¢ P^ÊvqC—q -H¤0bÚLÁ[—¡\àœg]î/½i`?ìWîÿŽÝ]c°†ý fßxÕ"V5(Úu–/Ë>F>©Á/â»ýÄ6cÓ2EJK-‘sÕ“a\DYƒ¨ m<Í'.Š[ÅþÔßÅ0UKÇ!ö…¶ mÅÌ~èº!7œþUQei6ÏPñ0%”‘;T‹]sU:ß´y>÷ð31Øÿ“'èw&oß×fF½‰(-Ý5[¦"œüâ^æ~P_øÐ$dÄ9ºEØëú ˜>ÂÊ‘Åü‘ß°4iî6|ÁüÙ ‘oùä²ãÔ„ãižP»T'A1\Œ%HÉojzÖ—eK›{à¾weeû/ÖC§¸+<؋ﺬDµ#‘ýuË(NP&µI5Svߊˆ!»)ÏÍÜ Ñ ù-¬Ùqh—îÛ&ÿ#(îí£¯óÊzõ§%»¤o÷] êÓᄉ3 JgT²’fÄ. p?‘.‡Ýà_)_]øp/£ªŸÉ?‹„ÃÆ÷ ¡^¤¾œºEºõ)|÷T5-ßp6×ËÐ:‘%×übtŸû¡ª°¥&òTV´Dž˜‰f wïÐì¿J¤z†ŠJï/Ëö^Kó9:á­¸pO…(fبð¥R"e¥ŒQÑkŽõÈ’–jÜšÃÐn$Û²Ïûï"9K(„ð´$ª`q(Óu\l¾Ývy`,‰ëq×ÊSú]m±L Ê¢d턊$$n§>ð6&Ì Þ±0†44g uµÏºµuÏ©– ©U2wpÜ£.j±=<ÛfÂy4 OYÚ« Ýÿ,·äß5iµ¼N‘Ì!ÂÆû&Eº¬‡U}N"êvÛâèo vIÙÅ 4¡H´¡\ðqâa¼‡T,ÿãÔ4A’{«¤à¾¤’ÛÚd-΄f`ýYÒ\Öv¼ñel¾ê2 @±Ê›â[óùãoìMøNîøÕqëã-zªÕ±[ôraMøúJ'5L^y3£b×&…^4N¶=U‹$¨®i%ðB¿rRžîìŒ?¤õJÞeÊì œŒ澦pÅêâØäß„AS&lÏO…ìêË#7q¿jÕÕ´ Rb¹*=ØÐõ9—æ$¸{ªöHí uŠ¿æ40¼î|·4˜/‚ÿ,2¢£ŽS“EôµkŽ>7 ßËÆo6é>dæL“Mß%ÐÇÜPÚbD’ÏA{!‡Xñª¹×c£Jy!s_f=—ópV¥ÚrD+ÜFØböÉ`O¼ø€![MЧpÔ¡ruXx"ÎCE3RÕÅ«>”Þ(…¨b~2H©[Ï•@3ÀŽˆ.õ0WVúY¦®‘,¢Kæ˜æ,ïï¨îç·h­&M"0Ë1׌σñ(‹Pc¡ÈtÎ*¥>„ÚZMã\vw¬;û^л»öANå…ŠF=F°Ex&['¸Ÿ­* ø2^ó‘%¿ —=8ÐÄÆÔÀ&©]gvÊîL¤²‚Èåð{O%½e!}—{5’Ç‘—éìÔëQ¬n= J¡ªØvÕÚúÒxq œKõŒÛecÊâÅuHà/i.XWµý"ü”úôè˜Ô§>H U2u^çþ 2j'¦SÒ™_ Éø•œJ½ôþ|$\ Ê™ú8©Ü°û ßSò€ê¬÷])Slÿõã´¬÷¹w°@ —jfwEFLo½AK«Ñ“.Ö)cŽÞ‰td«ÿÚ×Gdž_[®K8hÀÝw7ŸPÄÐéÅK\­èjña¬à[VKC¼ï­„îX:4j«ìq0:µg †°1 q-nç”;r0ÓòìE_Vó:B¤äÉøè öŒY N¾9¥ó3&™q:&Ã’"2û ^†b¬ÈùL[É»ë24n¹[äÐ7º¼É2ìŠà²ÉÞ瀿™öâ}íb3NyÚ–ÔÄpÞ=M2XúÀ…J˜›¼]Þ˜ 7PkÝï 0Dü€ÍºbøµäPÓS¤~éSþ"·UʃN‘d0öiwØãc#w‚ã²®>`–ƒ‘}‡ð7î…ùÛþ@kè¤F²EôN”LØF‹i&Ö ^¿D4FLGøßM¶’Gžñ¢#{,ôóÔ/Â)Î*‘ÿOä5Ãåj޵yI‡ÀÎ}õÅØñ-þ¯X“ÁÑxçJ©ÚÛ,®§ˆßñm \уÖ&ˆ=] Òf¡´N6ŸÅ‘Ôs•3Q< .©Ý‚‰(á¶ãâC¼2pÑ×RLöîWWÈ΢j^t\Dà1ÒU³ð02‘DçÄc‹Á3^íµï5†89çÁæ+dwάáŽHñ¨Åüµ.÷‹ ˆÔ•ªw‡s_ÈK&‰Êzk$IA.Æ”Z=@îÆ‡G‘Z:YrO$~V\su2±k +ê^m&WñÄü '}¢Í—B·©¢<,uŠ#.f‚w2¦ža»bލoȵóæ&WŒÎ"â,©Ï^ÎRbË´G“9Õ³@ Ed5rÇAõ&áÍj£‡’£› %aÈØ7Þ<Û ÕFÇ-ŠÍõJ1UÔ¬ÃL­¡$àžÿX­ æÃ´ÁÐqè A&^BÏdÆzã¢ì\²*š²‡[ªUe>î‘ËíòÿP m[ä­ÀÕ¹Cyp#\€[ÛëäɨÆ®6cû}›r°°{GR®¬fû6gþF.5»ëá·ÆˆDÂz ¢ƒÐOr`ì+éxb¦sH³ò޻庑Y¾çêO3&2CDXß´#¯*n–öì(¼gúÚ€´Ù±Å­“Xç`ÑäÒDÔ¿W=ý½a €Í¹.#q2z1Nç;+âçêIªºu®îÅÝáØ¿hH<=!5A×þO©»à…Ìwàq¿àPœ¢p”Z"ú Úš(%…ruÄôl3Lë$ÿ¿céu$¼ïèôè¬KÀ=Cô|oW&uÙÛ~Ñ-Q°4*§i»_ gʌ滋Íß°ü'‹Rœ[mCµZ?:ÊÛ©”‚g%ÿ;í&§ ÞéçnΈ©ÒWž0¹¶lT0›á6âz7*ôÎZaÚFÜ™ý†¨<;â˜7= ÆöÜšR%Â.,“°Ìz;RíÙ¦j2ØPŸ:à:XŸEØ~x}Àì5bè¨ù_’/:攇¹³F¶!™¡ª¤ ‹5¬/QŸ§©ãÉ´— Dæ©J4±%b¬;Pt1¶ëlG«G@ô·÷dÂc‰qé9²´†hAߪ¶×ÀÖ»1§/;¡*ÅR¢^yÔD¥‡~ŽoB97\ÍFê¯> ’Eõ6 âò¬+"7€îU#€³ÆX–ÞD ÆŽä?( þf+­íºdpÅYÍÇlNÙs@9‡µŽýê×Vu@^nH»"ØA”ÝJ³¨^0 Ð: Ú"Ɔ6ƒG;þÊí9¹#—X•A‹ýf—À_ˆÚÄbþ†BÛb>€S~L?VÌóN¸jÇvÂh Zô¹ÏÙÕx#XÉûk†»70íq¦}§Umü•!zýÆN-]èI(;A*_ÓšøÉ×1Jó’ÝÜÓ' y1È4ó ‹¹M‡ Ç!ZÒÌ~ùŸrÓ©¤°<7HóË©¶!S?j8èº9àunµ¯Q -MAè}ŸôúxU;Lz æß‚Âëö‚]®$ø¶=²:ø C}½®d»«ž(nÒÌ¡l¦`ý3HŽI#äâÐ`Áù$©é5ýŒZ9w(†ž2¤ºK§;JsܮгÓÖ¤ ;¨åŸ›×G1žË[,ôøêðsI|%çP@áù¥mwˆ¤MÁ¢ÕªáÌÒ»àbpµ¥ ,tž¯ˆcÉ¡Àµzǵ”F¬V¼×äÁó°tb/Ì¢ÅF.©+ ]ÒûmT~ÓÕY@‡ r ë¾{pÈÎ åt&W'•°‚hn«³U³Út{ àÎ;Ê”ži ÇXnO_¯¦Ý"­B(iâˆ(|pk Ç$ÅÏgó@ÍUhÕVÝeÿß Ø™–û ‹µçÐ¥ 3#JòŽUvXVùÂBåF7tÞßÃ’‰IñžîÁ å¾ž:æ +[öB•ÖÂm¥¡Ø™âh|+µ®ŠÙR¿«Ì×Ü‘ýD7H(×\àt§‚®Òã\Â[j8-9KË1>\ˆjÉ¢Sì@+kÖŽ*S&mÝPÙTo(³XWä¸ùÖi^ó2½;ªžåQ¤±BÙŽ@[mÁ²E B½9œÖˆSÈ ¸¢—§M‹ ÎfõH˜s‰[Ä!T¨uï,6ó³qÍÍÇB¢ Z†©ÌÓž†Ã"{N ŸYSÆ8xü¾0Íe}xÕæ†Ü>¯õy±²1‚½@î&rVr lä´ª% œ¿Ï´Ï=§Ò2ÈZ¹ÿ·(»ÞP¯̧3(bsX„/<î]<*>^1}Ó¯DähþÙ|¤R€jéè–˜³Ò¬$À5f]ÙŽ&`l±£¨Åzƒ|£´·¬©kþ†!&D˜á‘éa@¶I6ûBîöh†ø2a†Gæ¦f”(øn-Å!JØ£â,»ÍÌ•8»Š¥Wà‰žd¡xLÞìÊ=bφV(eæ‹Ð²¹†JƘ´îï›z¦è¿QÁ;¡PQ ÎÓðƒf.˜·Ž"ã³çý.ùôÐã×Õ$Ç‚^¥gûf¦z²é§84*p=&9Sò´w®Üú"ø<ÉoSïÁÄûBI4Õ˜ô½æ vÆ[ÜZ¸­3Þ™MUÑ´(få —ÉV‘ðqä f÷1¤?~…ö@Ï¥çø½Ç¦A¿þÅüË^ŸmF*<29É9|yd^áBÛÿpl¦å:³K¼äQäžÂ C5gï ªúAl ×Ö«†æ3rd…gŽÍ«‚øÙXÜÍ'Uµ!Ø•¼–L8xCÃGw¾¶Gãù˜^‹`í"–¯¼gS,ÂT¾2DŒñ8õµ×¸‘‘GÆž'†}œùT›;Y'ÙzAÒö›L²$í½¬ è5T¤¾ –ú!ùNœœÇ½0Ç>\eÞ˪՛©N©pÕz©0‰âhŸ$½=@ÁÖªÔ¨IâÞçŸ$uÈÉÄ ä¾Å€(ÙØn~³mžîALl‚‚§l³Ð:›âéóv-ÄßÓ…íáÑ~ù¯)˜#i à’M¤Ve%šDªH 4"ž-†’Mwk˜ò{cï´‹°ki• –D¨cñ‹ÀgQÇ=¥´!æ ¡@3‚öG£ÈMöAåÒEè ì•é›nGËáÓˆøû–€rocÝ´ì¡çtßÖsSúÔŠw&k·VºÎµüÓj56Ú׊ûÚ·‡ó&$ÜX|]ïoð‘í—©m¥-˜Á`°F|œ:G¹E†];—ÏÑÜ+âkghB>b×dEߘ4 |‰gbA_á¡f滨ˆãŸH0Å {°½™nâ²T3!+NL¢ÒÕç2úy{8o+©Ø‘q¾3f f„ÓܽÊU7«Èµ6ÓCýt}ˆ§|\P Ú()íxµG¤Ø1Gª?é|¥EÏÀV‹œ &p»?C'nÐR$ÉÛ§š„ÜWÂëÚŽB*•P¢ïo7èÐÙ/Ùk6|5³PTYÀîº “!Þ¤©4,\_ÒÇô€¢\úRßÚÎØ»wþà‹x\z¼•8”шy GZWºðîâZ¸G°AÞ%zÒ£œÞ™^¨.=Mîî>ßÿ'©Š&·¤,ø¬æJ=ȃwæ[G &$†¯¦a…ožPcuÑà‰Æq­Škè´±7ÎË>XÙ¬ íÐm”ûA@ ¾búDòg3B¼pfõq vˆP£Nàw %2šR*AþÆSñ1ËJÕîÊ2“úOLkÕia‰)TÚ§µOžR}jbV;îr ÏiH³xÝmµhï{#wGâHB^ÑC&0ÝŒZÉß§8_ ŸqKÚ³]hëtÕ|¥@WÌ¿ñŠ è:sN4(»ª·ò.Š‹{÷PMzèi–9ôOÚ’å¤ÜU8P#Ö5~aØTAný#'Ý×àyqî6›dæo¦?4€ÁCÃA?:s-Ø\QÖ’@ZPèÝ»¦FmÑæêö™žØ6ǰÅqd›O·°7p‚D¡ÒXS_ô[l ³ªwY"*ŸUêw»µ¼ŬދÞA_DQzî¸@ŽyÇð —¬D³ž@Õ+±õçÓ VFöä§ç‰tÏœö-y»5!ˆ¡·]ÕqðßLzWP}K„Šÿ >Á«nùš3I†ž·yØÅetožêÃÍó>È‚VÝbGÀ‹R Ø"ܘ-ÊÓÎN¾\ÜÉȧÊ}<:d¹§g]ÆžØaªx¦DÀòã¿«n8Ý Ž¢LËBܪ!J‰CT–c÷|zd¼4öÕæ9Ä!ˆ7€[àè)Ú"O:|\RšøhŒ»T9âÄ ¹yëØD”={ÿz2ŽùWÈý$7z!¸$_+}üã7Y1*° 4ÐßU7*‰ϸ—è4Øyuõ& tèK[§sÇ/jÜ^¾e!µýÈYL¤ 8òRé,Ü:ÚØ-*«àÙZàiܪ¯u^`®ÔŽR¨iĵ\ó‚ÞQ苬À±,pÿíEºÙ1eKúwñÂO 0~F3•Mῦ¼OZ®mm³Vœ¼ûÿ Õ –´'ÝΩ_åòò¡ˆÐ਄²¬¾U¡¼¹AŠ–™C^%D‹0¨æÂ$>óÿm§ñu å9n'tlÈ'±à‰uù˜´Ä>¨N}ìæ÷œ5CãY"ƒÆw @‡íž·j¿µc;®Q;R§jÒ+øÀ¿>Í„ø ݬ< ;¼üÚ)¨¸2iÍ…‚]zV>ƒ˜HW‚ëVÒ–2s‚Ó@"ïíŽë‡‡ÛçÕlêØ~6/^³<žvcMX:UÃÈnRäÆBÎÝ/lÛ5u¶)lÝjQO-¾Ø_µO5­:WˆÃµHQQôÞ«ta`Ö›§»Ý†+_Ú·È*Ìó.Ï?%=Íþª¸ ‹¡ªWpPjÆ”°@‘”K7 P*×Zj5éò„M»ÜŠÿ°Þ´I=+îÜB<†?`*4lgÜbT‘¤*‹õÙ:î¾õ=åÀ5AÁOM'%¥¬Íƒ =lŠð˜í¸Š éë|Ũ²í¤bFÒÄ*˜×¥Ù™XÊ^¤I^—z}+Ê'Rä.ˆÎÜŸp «‹´1 jD UçâŒÍl¤Ä • õͨ_Ý‚+bo Mñ±n3†“^jiņŠ&>q×WÞ4wœà'#ÕŠcRö7¬‘­kÔ©‰â¤•¹Sy¼+4ƨ/!×x¯Ùþ.'“}7¶&çȵøp›ÉÌQd§1[§æbz%Di„2£x’Å#-Hg|#4MGMzdI×QˆóöÕþpWn¤%v-DôãYêdÙ›1 ¹º½Ò’³jè ŸÒ?dŸ•*RL³œ6 ;¹»‚¤=¹lÅ 4È6#ý8¡(^‘¹]uei»òb1è…‹þ^ ŸõGwãs7SKèê3Ù•[-*Ò²Jv«H¥ó ¨ôKÃÈyKÝæ÷(ŒžÑÉÖ°êÇ`¤Á îø3$A—_ õþHöu Mo¼Åoªg”ÀåkÞ"6¬ê/¬™žß”Þg`•çqÀú¹—Èiš¢ËWS7P{3Ðòaº²¡ÓÈ’äÿ§éTÉÝZ’¸·ÝKŒ}¾›Š;,Ãħôã¤OnI“³¤'~ûOÌ·ž;poÊÓ0nS:¥™Z¬¡3žwuw«–ƒS±°¨ªôw:ÄT¹ï47AZ<ƒG†Y,/ò¥嬡cx2¢*ÿÿñaÝì !@)TŽËò½GòHC”Õc4±n½ám©üÌþi3IžÜò1¶:êR¿¶ÛQ-3¡šÕòYA÷,zTç$i —«ÙJ´\¯??ãMùÉŒç DÚxIr ȇ ø+ î–í?fü¨* „zÜÅÙ$~)ÇmÖ$‰é~ÝúyI©ÖÕí6»¹® øƒª€LÊŠ…OžE®ThQ+Jé»ü0~z‚ ÁJè¥õò*% ýZ°Þ#‹@[Im õ†š5¥ˆDÜÛ÷Üà=mùÀ&E×9œHü˜zUíXØufÈÜñ3"äÏ”“{ID¤Škq²UµÑ˜˜jxC„h‘æ´­x*­[ÅC'«·1¬‡¼Ó¯ºußý5QK` EìlÃØÜ…GfÕû˜£4ôáøŠÆ¡¨º\ŸÂ¤ò@LhÝѸ&$"NOàûˆC{z1 o4R‰½aM}ÿP,@‹N%1Ð'Gø¾fh¶)¢èþ‡K‘±’UHk»“@wô­ó ÷÷{’‚v›Mï4‹Œ ÄGhã¶ Ëè _õ8릛3óÁ55á|ˆ&âa^Þ¹ÃJø;ü¹’nÿŠ÷zUõ¤tÉ·òyµœƒ(Íú8Ð ÕÚÿJ H§Æö·NÑ«TŠhŒOxYbø ÆÎsö2¼éò#÷’Ï1[¯§Ø2J‚·‰E‚_ïï/«áˆй)S?°\]ÑpuX^£2Ò–0U‘ØÚgÖ¡Ð2c±Â‹&êÛ•>Ò’¢ÄFªÖ<ªi«½âYç;ÕôT:$Ê;¸!ÜbP14qQºÓ&XZqñ…+,_ìòƬÀ×:Ï8ò=÷võój—G‘iêÒˆ0"§ôYÏGöö¬÷,ˆl“ó™Ú\Ì}J²b¾¦Xªg¸üPxzW»7ÖÞbÊsÐ/¾ƒ/ñÔ_kθF‘¼yÃÒ.Âo›'aF›Þèº"ð)˜X›iË÷H4Ü4n 4ÒB"&&NA@²Üþòÿy Ðm_¤dÓȱæX‹=Ó’3«ÊI+ѱc HÜ[ƒ*9G¢xÁ%°ªú§,¼ÀäËSXå!¦ÅmmáF®-œ¥†Žº¹¢~ÔDJø°MµÏü C3OGÂQ…ŠÅä¼åSÑ#M¾äfv©]¦ÙL}[]åWç¼¾ZmŽ'‚¬úiyÀ®¢5G6L¢ ¨ÂÁËíc+ÃGêAõCŸr§b(ë‘t˜Å犵1—ÎG‚^tò s#Íî+ mw†H æywNw¤aŸpR·ü'§A,ü@¹SÒìV‡c‰›Y›¸NM09RÃòÒY–â˪߂#,«ÈÚò9ž·†=ðØæí<±Cvî±w>´õrRùUŽ@b'Ä×úËx÷p‰ëÿ㳦¼ÛÕLï,ͽ¸\ x+ý¿^õ\?„˛֒„zå|…g\ðKýµnaohÓ)ªV.kEг2}ìÆ!ÙV’tPw !Ū•uß?ðj_;Q®HPÆýÜSǘeøiz܃‘r‹] ®Âÿ½ô2ø©áQjʯó/jíÍõ87ôQXþ¾CRCÞ: ãW€”¥™·¼[“«6bÌ ÝpŒ4渕£Õ—FÀŒIç#Ñp@êÑ(Û7Ê’¦·JUnYýDÕ¡ah6Öµÿµ0.Ýíe1 FÅ4^æMÁ uÿ‡”‡šñPé©P4Ôx¸#Y ©/O%ª˜´g_°Wf£{o•ÄM‹fKm„EÖ5Ó'w^Èf‚åíZPÄýŽóh{šÕ09¡¿ê@ÜêÀ•’2CÚ§•wXW™È%½K—†G>, öøÃÌ»¦!ϳ=|mN¸S ¡„ÊŠ^Ã/d1 ªdÄF/÷µ4v[V,»IUô…™Å‰Á…*X³ } ¹Uðà/ûHt¢k¡&ÐHÄ߯A·~ wù‹ð,úh1í\OêÝ{²hB«ŽÜ$Ã6D­±óOœ?öI¿aŒ”~™³M"Ÿ@'à›÷¯yôÏI.gK"7æ­©á €|ê_ÿ€ùLç%5çµ N ×7vtÛÍŸ¦Ö¡BÄâ»Ô‚Áâ±UA¡Ç6u¹©|Ξ@Pv"BG°µÉŽÞÜêY*kvª:^þï0**CÚƒ•XÌ,¾ (*’ßžLñÁ–ˆ‚ûu¦Žß­h¦…Ç|¼nýpà!ÜaÿeÇün†mgNY|E4ýiøÅÅÑõ`å¦ÛH7‘4“ZÔÏŒ)<ÌÊ‚NÚ÷SS¿ ³çDÕ:E²LÝ€{ÐcGv}”Ÿ2: àÐnµœ×Â?ÔŸw¸o(ËÔ;Ì&zXÈsÙÚö¾þ6’ÓU‚Fu\zµ±.™ÌzØz8–Kf*Ë’Á±íÀ5Ò<òÁT&äúIë–°[Ê›3×7Z©Ù^ƒO¯„%Ù L( y³•™ØœokôÖÕ)à—ë òÏÛÞbÊsÐ/¾êW2šÿ2ù3$±>×ÓÛŒXRé”1~:ø^ðàZKÊ—ôwle°ÎRæ÷±!½ñ¨ QÒO6[85 TÃ&Ä9$®M7ÉPm¼ë '‘Fwg'×$þ´\EI>­£rx2}%dU41ãhÊ«¹|bºíÀ.1š7P®‘%Ú>¤Hc%G=‹üˆÂ+¼)þÞã“YÃú¤Ö6X@¸qÉXËM’`_Š £àÅ‘k·64¨Âfã×ᢚ”£‘!Q§Æp=~Ðôb73ƒ×X†Bl µ(ŠÐ4ìNºW!aîÂ^r¥­,ãa»ËrRééÖ(T µŸdžüÿJhÜ\fÛ,N”›aèïHÓMSƒ´>¥r‚3‚ÖÛóz$Z”jhQÄ‹«³r«qÊq­À…ppºÞÞUüÎÖIÛ툔À"lo&CÐØøœÀŸo‹ ]?#ü} g×n@q"UŒ÷õ¹Óz£—sù®¤Àâù 0Ž¿ÀQ‚ŽÚa±^§|·[§d2ø¦HÍ7êÕúE¢lÛè£éDníJ¯Žz±J¨Zßl‘“ð‡g6Ò`ܸdiT€îÆ ™§Aæ‚›!\kS.HO{ßXîË&Á!˜³‰s; _õ8릛’%òI2½ß†N!ÿèkHi|‡êàD~ÚÞ°—Ñmˆ,Çð#ÒÔ’&äÅ‚{_φ‹_=l­Y«éPÑ%^þDáùÞ/x11³~ñ¿ ŠgS5Z¬´p¦@F`åLÝ o2"Ç„ûÁf;†1—Oòñm$~>ülW̘ÐâFÙo»û˜ ©Q”oì®M˜Þó²UÞG²ùO3¸¦þù3ë{Û,~Ì8„"#Þ¶Ai‡Ã"´~ÙÊF.` T¦P—÷(1=+Âc¬w%ñ°c(ÛÌÉû‚—%4'i†»AÜ áülÛ0Ã%Фõ= Cö›§w $#”ÍaóÝy_±çQ}žkl‰+ÁÆB`éJÚµå^¯«tÎ]ÉLÛ)áç C`=2”Kçè¾$$Shel$¡5.C3Ìv’!ZçkÜë©Q¶38ù2Ë8 `¬­i£9ÈÆýlUA4Rk'=«Ï錚Ô§¼†Ž%.›)ŽOûe-t?ûÑJoÈÿÏ’QáÜB¡á1Ù’@ ¯!y€#^í”/åÔ lÖíÅaèW’5ÿÉ;I¯ãÑÎh#L§ eÜÜf`{U¤uûJž† £ÈkGhmf–iÍÖz–)I>åný$ŠÚ³"j ì,çq_¾òY†m#ún}Ôm%¥sQâûÒÒ;ýÿù[0š”J„ˆg|×D+VWF½U'·üúŠã]´“ât}›½iöGM(*I¾A¾ ^ZØ(‰ܯõÊî@Û²Æ%ãøÒ5äu•ëi†±‹»Š%­¨àÅñ~m(G¬±ã¤Ö‘hêb¾eaäçSq™º÷Ä€§Ÿ_Öq7Ä%”>k—Š$ŒÕMc©‘ïÒ13r’›Rò8#øæ²û«×DÂf*§EÇ)¤ 8k_ÉSÝsË„QÕ÷ßY gríÓu½~väÙGqsª£z”xZ8 ¸ÈÚ2L”å±ýbi"'2”*˜‰!R; í+X¶²… <„§¾Äm×C‡§cß:ÐÕÝBÓAüY´uùR# N@ ¤³2†*wf¤«¼qüÊ‘$‰"­r[• ^³fv'@[Õ{ñ¥pE ¿þ‚wàsÚ“çÆ—œ¦ÏÿìÚð¸õ“|üýšš‹2ùÏ”]8D.#¸¼SÇ?ˆ1_Eã Iá|Ö”‰æ ñ­Á|Û9¶´hÆ%‹0&Ö¸ ФÕ_‰¼óÅ>&i5\/Ì,¢˜%QL²$ÇÞN æJù ÖÚ÷ôµ>ßߊz(•W[¥.‰Mí»‚œ¸…1꬀GŒ‘F‚m¦êŸ øiŽ1 1æü`øÇ–»]WàÍÏC/BδšÁšö YPÚtßäÏîvq˃‹ˆåÔ ^ñT ¼ŒÝ2sã‡ûæðͪ¸0Å镞;ÙÃ3Ǫ«]FŒtwÔýPn&ê¿ÉÙMÚð&GC¨P2퀰$s‹{“ÐçòçNõÏOkZ•f¸[öŠI/‡Áè¨Eè…ÀÖ©Í#u#ÀõÚ/;|Á+ /¾›¤Þá7ô?Z¯Ô”¾%àaùôÕ`˜Ž ç#Ge;ÿ®ì2æFÑ”´rëÖ‹FZ²Q×Ó/#ª~ÛÝiÏôºiv" QZgÎÛé6T22¿©Ód2ä—öq ¡ÄšÁŒ8œæŒ¿W =µôÓÁþNün]Ž¿:a²j>’º¤#y¶©†F)­ÍŒ4Ç«ž~g6—¯L–’Z¼ ´fS£c}L¹Ù9p~/š°9¬XðÈÛDóT±/0©³ãG`›ÿFÛ X}´n¼<Ç6]±VŠ 3AÝ¥¶“*ƒõqéÙæá»éŒèSF¸×â©C¬\ êò"‚Õ¯£ˆ½ä\‘Ú«·±?µØñZúCÀ)k’wß,•БmÎÛÝa^ÄáN§ð, TqÌ9ÏVÒ endstream endobj 642 0 obj << /Length1 2395 /Length2 19986 /Length3 0 /Length 21366 /Filter /FlateDecode >> stream xÚ̹eTœÛ²6Š»Kph‚»»;Áh$¸Cp‚w‚Kp÷à‚»»»;YkŸ³×Ù÷;ãÞŸw0ÞÑýTͪù”Ìš/£)I•UDLíŒA’v¶Î ,ŒÌ¼5–”‡#H ährbµ³6•qZ[šX™™Ù()ÅA@gK;[q 3ˆÀålP2q~wá`efæA HlAŽïJS€±@ä Tó°±h€e;'gc Ó»dkni ¢}7³³÷p´4·pþビá#€™ã2€?l wg­Óû®NœŠ2d&VvnNV– ­)@–Q hçö.´ÐØÙŒA@k3€Ù_.ÔU%TTR*Jêʪ´Œ K³-ð=<ÀÄè4q9:Ü@ïûMMÿæ- ´¨Y€Þ ­ã;EU{{;ÇE%¦ª¦.EQT“€4èRêªjôEµwá_š?¤Þ¿dlM-Ì$ÔDÔ´•%X˜þdÀp}ßÓòÓÿ‡ê=À¿£y75s´³ùk…³³=/“››£¹‹“3££9£½5íŸ Ô,,ßc°s´¼:‚¬A¥ØÅÖô½0ÎïüåàO™ò–&ï¹ýô—RADQFRBUá=[ ÎðwýÝÿŠEEBD\Aâÿ¦þCÐÒäôW½þø2}/²¥µãûf lÞ+þÎè}SçÿŽú½0Î[ÿÍà½;ú¿‡ÇdöÎÚ‰é_K˜þD ©¤¨Æ /#&¡¨*ñK;Ç;pv1ÿcûÿÉð¤Îèôeyeey€ ÐÒö½ë€¶&ïüœÎ.N²¿dïÈ”ì賈b.ŽŽBSø/•ãG÷_åµ{GÏÚÓèöŸ ´uqúòzÿÏRš¼7¼¥“³ÓßAÿÊ´õ»è½¶–¶ÿïµûcðÇ¥ˆ¸üûYå`°¾?Ìï§XÂÖTÌÎÆæ¸Ÿ®·|¯³£Óÿ:¬líÜl=ÿw½™¥­éŸŒL]ì™Ôm-\@2âÿ²z!ü[fr0@ïÇÚÄ‚éÏöŠ?b–?â÷Ìx{ÚÛÙÌ€ÖN oK3Ðû‚§Ðõ½]]@ÞžÿTüO„ÀÂ0µ4q~ïÓá/ï2¶fvž¿ÅïLþKõ¯f¤ùk²Ñ¾5S;[k÷6C`R´s~ošÿ¿¦ÿ`-ébm­øî€æ+Ò®ÚXZ{ü?-þc™&èO hþ¸ù¥“¤¥;ÈTÙÒÙÄâïjý-ÿ{7[sk€…ão¡úŸadý~BÞïË?WÈ»Š™ù?tïÍobe rrpsÿ¥½§ñ?X¿—ôg“Š’¨²’<ÝÿÚ’-—°5±3µ´5ï}NÐÑèÀüÞg¬O–÷Sd rÿ«LŒ¶vÎï&{gï?eFøÓ,<\&àÑ߈ÀdüoÄ`2ùoô'&Ó@èÀdöoÈúnkfù5€ÉüÀdñÈ`úçâwRVÿ€ï¬¬ÿß]Ûü²¼Ó²ý|§e÷øNËþð}_ÇÀ÷}þ9LÎÿ€ï4\þ÷µ]8N&vŽÿœåë?à;;·äáŽÇ_ðVYùÏ<ýk.0ÿ»ìÿº<ÿªΎvV MKÓ÷W,Q:;Zºë2¿j–wùûß}ÓÿPþ{ýÃZTÔÎÝ“ý½÷ØXÙ,lÜÒËêý?lMþžù ”÷þü/ügÚ@ w ¬ _àçä†àb‰¼ñhJÆã²‚Z²±P ©ã­¸âÙ›d ¡þ?ýÒ¨~ØÉKóêû$úÛhQb[¿®6%”]›~Þú(ø Hˆ gi0ª¤)Ìû•´“ÑÈfåj²O¦5Ç6Ô‡ÅxZ;"YGßÐ/“ÈôJš—s Ýò§Y±­1ÜçÑðÛæÇÛÀß°¢#€Ý" §Œrƒ? ËÂØwu`îf6ï î\µ¯“•âëÎNX=bó›å2œ„®Ûu[.S¯²Sjd°LÏ]I®%1ÝÜ”;½J¼ £D(–à˜¤@ âfnÙŒ…$ñ1AÅ&¤'Yvþ¶Adº'Ñæ%g%„!Ì‘úœ¨·W8âÕuJâ'¨Pßø<ñB§¼iÌâ=§y{ú°bß½¯j=ýz,uoßTmcMµ§~xº~øÖ|sdvW ·3¾fO'eórÇ1”ï¹GHS>l…åS&NG¶¨é<˜UqäÙÛAõý`B Uw@€.ÚÊ[M.dpºÙñ‘<Á,›Íl’o¥Iæk_XfŸô`vÔ¹jâÐøbëŠ'p•}+«St¸ÃŒt3ëýKéVo†Ö•ŒXé:,ís‘”µªWD3³äNa¡dù›¡Qc0s©ZÀ~λöbvt­¢=¤ÊµÞA¾Å¬AÃ>Ú“·øS/#2¬ÌØì²6àåWÇ[=ñ¹›1Âå“yQ3Ak‹âdpL¸ ¾z˜^pc=Äu>ãð5Óß]tÖbÚIé”!»ß³7åêN¸–ÃíÛ;è«_4Éüžœô4¯›O"8X|î[­ÒÎμ,4Û΂!Ì]ŽÒó8_ær‘Ïî7FAÊÛ|Ô‘nƒ)Ǩ‘m½|Ó¬G˜Þ*/¾ÌFn ò„lZnÆZW?ÜÛ:ö–ÒSΈN‰ p¤ £ ãê\2<‰pñ|:4‹“¤÷IŠbÿö¬ã šL™€%ÜSâ©È¬4O·Leƽá4{Œa®ƒ8KvÉEq½íœîí«ÊÓŠîé…Ëm‚ÃµÔ|œ¬[.rœ“å’p¸ëiJT~º.ZQ®ðÔÏ«2&|_ªŽôÕ™b¶ç¸) Ú{= Í£^X—D5žTÂ5«ÈŠÐ-™NñY?en‚›ÉQZëK6úˆ?£,yt™•èªÆç¢)D?P“j¦CÝ)‹{þ)Y±Â[O‚y€ø­3%¯„{âa2ª *µž¿;¯?Ö†d¥*5VqÙLj’ä@“Lj©F^kMªKÈdgÞíð¿Ÿjzv+«·ýÊCŽ›Lçi‹«kžÀ‡ö šuŽ&ï„εħ°^­¦Ë#h¨Ü{0:ÌÍI.Y×Ô x0¹ñˆbŠÙ}”Lt=âŒö„±ÊA;nð^Û¸V›8¹Ws-è¢àë<@põ¤ŽåñèájlÁp&b½{ܯ.›ŸªÝKòÑüþß!‘ÏHž9ØSÜÓ™Ø3È×:õí®ÌáGa.««{Ú¹-CÂèMóšcQŸÀ¶àwOUx=†È̤D´Úm2|u_(VùXDä\NøÆáÿÔJô åX\š½ø•~Y. òÎ/£Ñçizùc#ø…ÝcR¹Žò±0“ýuw¤sýc€zÈÛ첦œ½¥J 6æ ±šÑX6[äÅ£…ñã646›ˆ5Æ¢¦T»ŠkV½»B™ºfÄaŽO(õúšErl—pªV®sK6±ÍwºÈzå9épZ[Òl÷€êóÐOV.m°ùêÈÙ»µ]:ÀÙô'¤ÆÍ^’Âì4Ìêkh²[g܈-\¼vñB¹‡–±e´/V¨Ù^‚Ž/2‡“´m}KbVæúJÃç·ÓÕ[ ,jC‡|N§:tR©Ð)WŽÍÅb/˜]¯0ÈÞ¾1º‹?A¿öÈžL1‚Ø«/îÜÒ^U.×m.~ÞÚq²ƒD:ÛHü™gÍCøØ Sçs(?ÆaPŒE‰á"¬©Ñ½‰8Óˆ¼ùCžÚ¼Sü¨›VøD»ž¶É¯‡Â3§Æä¹•4´—Ê„E7\ð¸!ƒµ bÉêÑÞ»p¨0šÊiκöo Ú7i“0–.Éx$êx¸¤çkæaüD0wM zà‡À#ŒA—0 rÝ““\#òJø|ÊH¶oø±X½›îµžôù_³'åÐÄÎ> ßÁ š¸•B‰¸·!·úᥧR$“šƒ€Jé«°QAýîJDéóÓÅ9¼‚r#ÁEB \ !ÝnéiCâD"º‡FÈ –/gÚ†ê`³ø^(:b¤ŽBó=_?ÔwÖ%VpvÏ6{çŸbò¹ÓÄo˜àp€¹ÚÀ5:þøúFZ0!p¶= ‘­‡f —ejhÂgXH6m¬ó{ÐF_Ü¢N žxÆ©\ÜY[„*‚#MA¦œ¤~;çOyª–ŠV¡gCEE>[€ª&°®‡"É,u¦G^þÛ‹Q"¥•9é[«l„ËIߊ=[é¼)¾E$b«-†¿4nâ–ËC¿5šÇImMk:_ wÿ„×ÌDË o¤‰[íz›´Óœÿ\Å®wJV¯‘ô)Ÿu—-‚“ïsŒ;§«Ž)²×£JTw&zÕµ}¨.«²â@Ùf-õe ­ø´B‚+É öjw¾›Àܾ-4º}OÐÐu_upú “X×*µ„“2ÿY¿ÈLXhno$²,XhMG®ç Ö[&Ðg„»ßHmŸ"ŸƒÿÁiÇþ‰ßné#ëDó+?ÆV$CBˆ¯ÃÕ9=2]ñ—RÀGÊR—`îW?KaìÃx`w]s ˜Ü—CjŽý}ã‘ËÀ¤Š>z›±8ìpæßk”["¥&Ê>\ÿ´Æ?ºuX)N6>¹Ï‰–>'æÐ j,<õh,µŽS†|ëQh"a›Ç.Ëøu-šœËd—w´Föú(e7Qåp#Fµ£kpLI¤mÀ=ƒM°‘ JÖ5 *ˆ¿ë!«à^ÜŒyQk %_‰fízHÎ .wð@ꨋÒå0…ÇsudËêŠã"°Ÿ#ÖYÃS¶ýœb’€m%¢<§j“9xÕÊŽÈïÜFæ !d í}@öËn·µµO³ì¼±¿=Âσd\õ ÕÑg¯€^V)­˜¹ÿ¹ƒ„®I€qç—ñ¹šöúîRÙ§¬²‹XQ¦ËÃæ‚œÙ¥:F¡Û÷ÖçéÓ–sÇNÝ*• ®“†ãïݽ Å:xZ§Õy†¤ÔDhÏP†j‰Ä B^‡_aÜYœU¤I#__…!÷Ò¡Þz¡ÓÊÐû1V©Èø­²I7:=-´±>'Ëßxg^BΩjÔeÛÜÖôÇšÖû«¤$‘gêÙçÑiÎöšíœþþш`¬ v6¨¼qª‡aÑÆ x²ŽpóQy´õJª“lø¶ŽÅÏ(اŸD0tœï²Ê†‹ çÄ<7x …ó·éjH5?îír8KÆk÷×Åf»=*cä ûe3Z<}Ž3y›¢ÓèiJ1$ò…¬&=Jœ!uWäÕmûÚ73èœf=î(/¶ªà ÖgCV âyO}µÁ}tþȸ%œÍš†t;5µ¤~«Í¾¯³¾ÊÊÃõÙ}õ‡žséÌ™Z&˜ÑɪÇÇb·×´ŒT«¨* ¥ÕUóÎïS! ©X=C£0ñçâZŽà¥ß'ŸoÚÒY‹¸¶X¸ó™4¯L©™‡’xå³oËÀ0ü6MÐÔÝëöoÊl1Çlù ³SÿcbùWYG!t¦ Ãlvw=jåêö¾Yèfü7{®8ß i„qxv =R¾vG=¦O)2§#Àº·¢Ïp¦’%¸s$VÈ Œ·¹:xÔÒ*èÌë-€¾1ƒô ‰ß:X—ðHq©Ñé;Byœü§0\Öp(Iuû҉ƞîÁ7nNÝ0ÑÎX8;… âɵ¤-þZúž ­ñ±:Õm2Nš ÔOÙ³à5–lŒ-úÆPrãÕº6xŸ8™ VÜ*… +‰Ï¢‚¾2yæÂgçσ¶ò˜¤ªOýÃqƒ^.²g¸(@,ÁLç„ÃÁ¾>‰ç=Á^+vã\ëí §'ën¿, öñmUõªòhÝÉ6Ù$@JÃÿ\Qó7Ú‰0ÆÖë.60âŸ:T,ˆøÚÖ•‡!Ã…Q+üÐñ“Œ^›FŠt¢Rã æ+êÿo+Ô[kÌuU9.½Uþ‚ ùë’|¬êI•–ëÝùVäoÍÄãÂô™èn¯‹7z¤×b¨ÍÊ=øÆù™s7ˆjLJ~Ù`Ķð9¬ wÀì“vpy+4J±?N(sòg¼éqå°¥–#±òŽðB~·½ù¨[1(‘D^×kð´Õ3–6’~ÃÊ*!‡Õ¥gÀ¼¦…á a®WkrìÿéA]gKJÞ¢äýCýµÍnÞ’Ú¶ŒEÙ#[*ezH-(.WÙ |Á±ùX5Yä¾)ýxÒÉkŸÛ¬f¹4ÍjRžgCŒ¡=ÈlŽ¿D·;ÔQ3ÁM mÆÑëü¦GUPχ¿·1äúvÏB5œèØÂ§³Ô»þ5g‚°²¢c‡Àt}ª–²KÝí i+í¤æÓ•Xáâž»)ãMHÁl§Â¨™Ü={Ü„é8þ'­¸‘TûÛ¸±vÆo|¸ÛÛߢŸ+\q$puÛ œL[ìþ®…F-4ñµ*j~øBª„ÞMÓB‚I~¤MU—FÚ¦0㌕0 hjHOGH2¸Î¥Šp´ƒ…–`ÐwŸ»îéþ¼ÐÖÁ^hÌ–àS`HðM¹U«ÍK×É´ü<ˆáí÷â.HMÔ¾–pŸ{ð`§ä¿Œ.ªžÇf8éÇ­ù $ÞAMþ&'œ‹‹¬ÿÛ~B¸.¥Y,˜_bAÑLtjx ×ðÇ´Üžr¦÷æ%GêL§ì#’vOûQ„g*MêĪ»¡± ùLY(Zb?,F®½²‚Ï5\¡†™?ÝòkOQš÷w@äî%ÖEJ-ñ›Y]þÿN ›*(q9(Dªaõ=+‡ì"ž" ‚M›„ãÖò´9çJó0fq\äúfý¼qºB -²6H×5‚P—Ƶ¦' 庶&^­óÆRWZÌSÕ%Uµ–:?(fÌKÏâÊ K¶êa®3mð«ldz—… CâNboOûÇyHùíâþͲÁ¤°ò²AeC«x}™˜\ê#U…Ò³©9³1‰ sžHƒ?)À¾x·°n–¹·©ü ö?k Ê4;Î ¸*UX‡„Ñèý$i*[G4cÒ¸IÇ[ê×ËJ¥‘ò¡£ûu.¹C¨Ã¨výGG“¾–n餤–á´¼ïÓÌOweYñóþ³°‹œJ LõhÉV‘m&b@N²E…ŽÊÀ)OzާƒÞ7›ð»ÉÏ´2陓ž©Rú›Å3mÞ^¨$m Ž*Yš CW£ç6m„–B-<+VÊòÛ¯ç^Ï›uöë#NèÑÂÚò‘´| 3&™»=<À0¡sÌ~H=Òç bÐ#¤´RïCUw¡å‚\D½7‹zBÃÃw–ùAè 6HâúµpFŸTôðâÞ”½êýѰ|=ijzæî•Ì[¥Ó«ô˵ëLÞTJsîC^ŠïHjGUó¹ëØO©1öù5YV– ¨"Ú†P´.OýD.†ÑÞÓ7›ß$ƒ¤%ËHùƒÍ¤5¹óðˆØL¾ð„;4ÛÇaD‹Ý«¬Ã’-qTž™$?Dm QH÷õ ¹q!æ zL:¶KÃ6‡icOq‰z·+aíï2!ì¾u‹xº2ÇÖl™©w2éùÚòí®š kÃeIjKŠ£fѾ:˜èOÿª”'Zz í°/ $Мè?O¢B?â],‘†xø>Çó†Ü5‚*IJf¶€L:±×_7 ='{E—}=:q/UŠ}î³MŒIè„lJn4µj²ñ»î÷îhy‘÷‡«‡›•&øCJhðMpU}Ñ2Ês˜5ÙbÐNÙr}%^ÏÕ)‹*|þ2Å4É VIx_s~åõ=äGe"v#í⺶ •#kÃ$4Õåªpp,`ˆž›5ânÈmýàbr;³q/Ê”awÕr§Øa"¤ûcmõMYÂÏ %àüÒö\|Ò/—ÀŠk¦Õ[^U¢4û·Ñ\)üº!mTŒ Ý{šG¾Ü­¼D©ÏKÉu Ü=áuø††ùú¯²T¨ÌÁNV8OñÉepÆzÆ´š"l·ìæÏd¾,G5nôéI¬ù8°ŠQ„õж©ªçfbÛŠ8;1k8°"ÖH÷IÒ‘ÏÃw‚VcEUa ²ÝÂÐ÷ÜdmŠºŒ­Y;.±C\d“[‰°GJ&¿•¦$»Æ]>cˆçm87Þ°'û'™šWL|Ž/ ãnÙ#’ ¦¸ÛÉ-C,ÞÅ?²†7†óJ¯ Èë:ôÉ*6QúEi'YùxN¥¶t×G&w¼Ì‡pƒÃ“‚€½¼.ÙOþÎ:Þô|aß•½ŒRgM6&•RÔý¾åF#ô"…rä[8Gjdêà-ëY/gÀ8F'™X_GÊ—¿óÝø#÷˜ë{î{<¯× ¤·ð(epc§ºþÆ·£uÂ4ÚÒ™sRQ殲PfHå¬BÈ|ˆ ì_aø)‚þiÁ;etøc¸¹£R¿ƒP6ãO‚Ö"´Í:ÌáŒQÀŽ•SiÛżÈx5y…ËB勉éêٯ㈛+¿–àÃû­s.µt‰.ª1ØÙO]*Mí®€)‹Š#9Âd´Ï´?lNúxD2µ•犑zW4ÑŽ)³€¸8&X'•V¯$Œ±!qŒAßí>µÁ 2ÝÆÉw¢ãûó?¨WÈå‚…߯!/=~ÔI¶_¢ +î«»È €¥èhš"Ò¡k&“ngÜ|ßNùÎ%K}õñBóæoå‹ hX‚Ýew` áÄÙø¿“BªÛÎg¥(Ößn"˜B(kÒ¶¯å“'g«ÖúŒÐN®«§c(ã!ì¢ÅêèÑÚö{>ÑHu‰Ý %#(g4üÈ~+Ûúf´¹<ÔxÓXNˆ’‹ËŸñ¼Ð<ö•7Cë*p™ºš€ÙâËdc!ΦVKîè\…Ê„N ú®íôCÝj7Yß*üö§Îö ÅldÏB#ªPBë¡2² 9zâêž` þ°¿q±¢ú›"¶6!Š/ZþäVŠF•·ÿRŠ9ÝBz¬°žÇsß'?¿]Õ?¾ÀÑ¥·˜«Rú“—×ÀHzR#Y¹ ›ø¥ºKÏŒÎê É­*c«¦³Ç6$‹[øøÃ᮲ùœ?—A}‰àaØhn ¨$dÿçq¿¼5…¬ŽŸüõóqΫìXJöjÞâ>.tÛ³±ž&Îô¨ ¥‚°1¼@#1#܈è篼|ï|ˆâä9šU#ô nÌmZö@”Qòfõ_š…O:*P‚oMd™}«Š3E‹Þi4îœÑßœÝl2ƒcÝ‚(#†—BùHNÝ/O°*+ä '®&YV2í|sLä@V×÷%´îa?‹ÌíÖjI†YÖÊ\\fBèXÆC¡mfã±ÐŽRõ „͈€ ~6m‹°xÈÀ‚ô «{\F0(Ïj¤B»X=ä™´Œñ`w‡½üµ_+Ýàþ¼¾ášß†ìQ2þ½³#â²n¯ü2ÉšIò¥žÕ¬õ›NRNÕ ]þöL3`i¥å«6$¬ßÈþý®·`›)àÂIoâë,U¨€>Â$°Ð*….êÓí¬úš¾{ÅDÈÑ4ûÁBêúŠÂPðµÿXkÉ· ×ÛÜȇˆ6 •ŽÞÚ˜c9þaŸßËÄßÁ¶ø¥ˆ+£2_DŸ†ƒü[Ç@—çevjÀ ¡¯QÄ9S)q¨Äú‚æ3’MårÞ!'¸OI4‰éè˱G8w»ñ^ªûd\ô©÷ñ2MÞH'Œ‘¥€hásm—;’bø,L´44Û/ÈðäÕ$¸¤ºäÝ“éº ¨)ãU}c©ü0ú뜅äfn ¸='ÿ–Ä÷y(~%Ž*–\é(OL(ã¡®>â@º5|Y!ÿÁ™ú Ñk¥*ô•\ɃxÁòWš ÷i ÛœGœ€€|vùí>:Æ¡Ýø+êIý”Ár<¡nÂ.Ùð{ÞÍK#Rm]Gß¹ú×ñúô¡¯›Gm¡XDøûA¸Úíƒjí¸dþí$fÈîëïÿæ^]ÕïŠF‘Øv<ô ¡N]Äh¶.‡œÜµLPK†t6ñðWãQVµôØ<Ën“zÖÅ ž¦FG¯âÜÍ¡ vDÜ—ó[‹®ãzNH›9DQYܱvU¼QܣÓp‰GÓrÜÃÎðsŒä¡LëL#A)Ïj§Þ÷]-•) [,ë™-Ñã/Óä;ÅÊö’ч)ð\e¶V,}c–[¼[V§{ÒøTÿ6wz•ɵ„‘Jà»#ó3R¸RÖ ÝP\‘'fÓÞUô¡'ðx+q: -Rúj5+YõßÍÝ žd%x°`¥Y?òÿ ar%«éœÁ&œû¨Å9$…™yÿJW£‡Í?àY­#Ä?5x`,§Y ù-¡ÄS!«@iSQ5¢bW" õ4þã‡RÉé"¼œûh7ˆ\cLW–e-[ÄxèLÙà§¥.Lelêüë‘Û1ôšG{pîHs†ìe0{²Â(›¸öËÆ®¤¹²½ä\Dhy3K! Ö¼üÔ#n Ò1çÊZµ,¸h}Á.Êm7ÞÖ‚‡Vt±\M1<…¤¬!8®~3t1„Ë/b ôoW±}y ½ã׋\e% h ˜Â-ÔÓ+­¶ ‹âktLUš3¨YÎ+-%4à†}óu‰Õ°ÂõOÆÀžGfáµ(ø„0ÛrІê_à }³§ ¤³…K–¯ÇýòÉ ë-;Æ»ñç\f]Ü4 Ëi&ëŠ÷ÀçR²2:wH=ª)>¢‰Ü{VWÑ¥"Ý ˜kÒA)ûZlPäªÃéÁý4˜`â=K‘o.öîâ@/Ž‹›‚bHÓÇ`Ês<ÄnûYÊLêèáøÇo¶‹Fâ¼þþ]ŒÊ§——)› ¾}j^ލ :ÃB·°kÈyÄ_om’$1”nü>ùHãD¼¢2X°Á¬LÌæ-w—.·ŒŽPhaÄ1& ÷.‹57L j Aº•B¬Ù¼÷þ$Jëa‚ôfŸ9{VÔ袠Eze=ÈO€yTì‡û—Ud^™[,‰› 2[Ay(Ë7›®¹olê$ jËJ‡£T)—hëîç}ë*‰1þÔôðe­ÊêÅΨ(íVIý”æ •Õ5Ú…Õ©8‹1òbÖ*“15â1ÌJnþl_wŠ•o\ Í"BŸC='jfž9i 3Ý‹O«ÖLÝèu Í=T6ÐÉý².uЗs‘·™0Ø4eA@´„ªÕ( i¹ð$ÿÄq{f‰_$5&½}AIJDfêrS“µÕ+ÝŸ±qö& —)`èuhyqîFzÔÓY§nMé@®kGÖŒ«³¤QõþhñaÛoÈHS™6dµ!³'O¤“/æ× µz¬]‹’¦'Eþ0úrƒåy±°±È8½T…E;5„‘D5À¦DBŸÕmöU©b&梋-Ž¿">ݺ²;œë˜TÍÅý†ÂQÇÍÇ~±6—ëJX™gŒ¿mPïiCÔ{Œë“Ô$ æ_»º©xzNÂóò„¯œ”´Þ€ÊRc_Æíø†TιóH½~ú9Ê7¯å¡KEþƒ&eŃÓÖõÎEŽbG€÷÷ðÃy7žvRu‘­îçñ‚Õ´‡Ûâëm«¾‚š4„‘"šÌ:îù{kÀ‡eeìû4 m¸kŒÊ œ7­ú•=~‘áï'4ƒ+Åýçú8Eð;ÞD»¡ä/šñ‰‚Ô©kÆ™ÒnË*Ÿ‡W­{¾æÅGÃkÔ2mɈúw–O®|Uºãqýìà'DÐà)¹­È¤çïÈ>1[9d’  ´ƒa‘pöÐÔ%§®™‚ã¬yÜ€(joÕ7‡ÿê{/€/™Ê™,F?Åž$Ü&}p£Éäo±²çÎæ@öÔ†tǧxLõ©?jUÁè»\Šˆ»Nã#¯ë@šÈÒ™•H¹>n®6âÄxÁt¦±Tô¥õàgá<žµÝo±#¨Ÿ|Õ¤ BK¯[m ˆEMÏä‡ëÁIª#c:P qÕÁ5íÁRÅUf/í&¢XiäBŸ¯žÙ€¥kX<ÖÅwQ 'ãgMÅÆ4,^¹îO:’yÏ/§ˆ7?Ž´ âZ‹OÂì˦Ï^Ô{pO¼Šë¤oHé)Èf¶ã“¹­œ –ãÁ´tòv¾õž|ou¥„t—Â?9ýÐrgš\¿õÁäUÕN9yAìá¸63ÓTâtÞµ7E¤ù  ÃZ£ÈþÑÇþäõ7ÍÓ©Ñ¢kt§ˆ™EùâLº¼^Š Óýæˆá zY´þ:,ÛÕG˜L;Í'`þ“Â’åuü¤‰¨|ÀFˆª©ÊYÖ%5«¤­ÄiF2ÌŸÌcаñÇݾðŠê ;¼‡1Ãy½ÆK¯h6µqþ2*Í“´*vCý#;ZÄ.v¶\q³øc=bL.Ÿõ Ì«{k›VÛ]b0‘,OARl%Ö l=‚KüF¾rW“wÎqz¬¸’ ýÔbHðàZ]…b`ˆh žÚþµr^qä'gÅÛVOõ৤ÇXážmÚ7£­~tQ¹&ê=ßzò¢}Ãg’åCE“¥ßH²>nø3zøž¼ÌXJÖ[>#ˆçáÀO15 Œ¹,ÓU¸zCLg)°ÔI:¶AêuéèÞôÛmRL[i÷ LG,;?†íĵѤhÉ”ˆºÃ@Þe®IÔN$•¥-Sð麞Fº6Õ…<]¡)†Jx!’,ZË…ÓvµpfšKÏio¶ˆXzFûµNÀ]!]Ó\ÝaäúHϲ L7Xv¦Q³x¡Î²Çq¥l®&¬tF +nTuzIBñN˜_å½ÉÇþàÉî·6ÝYE~ŽY[zlÂÛ×™é:*¾xXy)\>.gªG\}K¶íy}¿EÞÈ g2Ÿeü`õÉßÜ“¾ØƒoªO¿tÌ·Ú8g¶-ÖCGáqBÓ ïzáà· ‰JY]꣸:zü¬ýŧ’¤[÷²C{0®Ú Òž”Içò®…/hÌgM–+èš…~àÁB—*v×EWZÛx¹ë®ýÙb~½ãë„”C\Ÿ \¤2OÐ+^î^EIÒÅU.5·œx½JIH'ÃïØDÕȲ˜0ªZbD2%0ªÉ|lÐG¼4ë»ÈŠÁªc½Æ‡›J®ñ˜©¸ÚzZàÝ™ñ!ÁµÁ_xéçfÃÍQ¹ÈTºË”uª>ÿ„;4“/¾ˆÒ©d¿4qöÄ´Ï€<ÒªUèFаdÕ»~›ö‰ÉC¨‹}ŽiÕ sËOE¿Üœbü²_õå¸Ibä¦ï“'NT‚ò+ qË$†`­ê:Œ Nßdùõ¹1êp`)}Uõ4kQ‚ÚÝüíIðác.«Åg9¡Ž\ÁÔÛá¤O’^qù8Ñœ [’ñ×N&ÁòCÈ=Xr9ÁrqàD¦ã™¦ó©*¯ãXP¥¨B™Ã^£üO‚flò …f¤é $õ—Qù-«R¿1šIøåM…ÂP×ðžH)êSÊ´tž=˜˜ ¡^j qeèßsÈ‹ ¯BJý:q3õ¬Äfdý­‹W 6øñÍB9Ø+URÙÓR¦u)ëSN‰#ÊÇú˜0a{ìj"#ŒYÅÛÞÛˆË+.z›=FÊI‰¤•»˜J¡¨¶§ˆö÷má”s¿gý6À.&üáün!¸zšƒÚÁéƒé±:𻵇3Æþ‘ï–q…!œi#†I-íöçÄ´ûÞŽU›¸+†c’à Á&þ NowY²@ûU‰1Þn/ˆ ƒÚãÜžô$‰GS@aC.]@¿C­7‚I!p×%U¦¬úEZû±^:F°&³ ˆ°†àm“^Ò5˜=¢ñƒÉŒª`ol` ñʼn}ÙÍ—–éºxp¸k®úJŽ8ö:«[%÷rÝåw¸A•6ZÖÅÉÝV:òšHˆ …£¶á'g¦Lȇ­x)iÇf¨¡l|ÞâʶŸG¤|ÀoJ=húK¥6²Kéͦ¿zÏOl‹;}±˜ÑS(Ïg 2s²¸[Â)¡.ÝŒ¼¶¼ÎL݃©49ñ1‰µE!+Á˜Oa-ßrb1í];”Å"û‚(œ'ÖÈõ÷3$¯•èã’;h„ÍŠÙŒUŽ~t3СÓ– Ð=ðÁ²ê?z;N ÝCã¡H/ûÅ ÐF–@'Är%SNG««œ§aQAímêí–èùg\C8N¤·Õ²—®U—ÍBâþk•èORé‡sRï7;Ťèvõi>•wâG®43Ô­bs¢ Ap1!&ËïMäMò3úpüG8HÍûƬ{_N‰—\\"˜®ìK­~¤žºi‹#íÄI¶mÌÊ—ŸJÅU«²Ð"Ñm€ ž•s±]HÔ)|O+w…ju£[Ëïæ´m¿é)«Pòdþª6>Ú7y"ÚÂÙÕæeMm¶[7·“çn)¼ï hºîÒ=l¤ƒ>(§yó%¡l¹\,Ë—ެeo]RçP£¤Þ¶Í˜\óE…/ò¦‰Ùà`àÛÀåÁ&÷¯Ù„–÷¼Yzéõ%¦7{Z¥S/ª‚$ÚVoÿ)pŸL8¼N¥n/rOj56â³@S»™KÉ,‚ƒ~ƒü|åPÔo\©;ד¢ñ½áA+& œMxìP™Kßy÷7 >X×¼º¨2^+á~³ùxƒÑMªhÐa¥ G‚Æ—«§µ(!iŠ&5mY’d<9¼ÇÈòÉ¢®7‹”Ö ö ʼ]x+F·Ý#Šc lr^=Ö‚czÜÛ|{à5&ÍFƒ>jû¶÷&&ØzpCãGYk—zbÅL"[©¾þ ñØè[ãüS¼.NDa¡ÓKì9„&©Os¤lgl‹]´Ô!¯SºŒéÝ¢y[HUyHþû°8æ e•UÈA³ÆìÝ–äÛ:á’ýÛ‚eý!É~\þ‘X„^0 ‚;)'ñ‚æ8Þ⊻pø~“¿.œ×úž‚•¨nÞ€S«¾å‰7ƒÕT][îÖ_ýQç2½ñ4çŸþYºr^é5¨Ç×Ôµüf™ö$=ån°LM"Y°njÍÜjœ®£úò€™íñ_‰ü ñó¾’£Šé_ÔØL‹Û»J€rMÅ+ßèi8` ()~¡óŸeø½¶síÿ( •,ßû”øù–;‘± ¢üf‡²“âgåÇ´Bi) ‹æÎMÒL¢DCò¶}Œ0Ì•M½êtá&_B5ÈCfý¹"»%ˆlÓ‰Fྰ­.3×$Îï1ÄÌ\Jˆ§¬Ì°,¡ù nð¸µG¼‹ÂÔÁy2w/™ÎéxL~Lѹró®•âbvÓ³_”­jrŒ õ,"£ ”éÖŸ—¯œµvß-êDz–Ñ—³×#á¼d7Ïäû|Â=dk–^ÖxÃL#bLyŠ,„éØž ˜ú‰A§ÝÍù‰ø7RcIšì÷ù-Æ( ¥+lzZà¹È‰óhyîTK p,ƒí &šEŽK+Ð^6Æu¶Ò¤Eç*ÑÇp˜I1‘¹ÿ¤æ Ý‘8,9á`3ÛŠè_ˆË6ûbpÕ4Ë;­;mrª.ñZX»¦^^¢¸8Œ÷r«–š/È’z+6ôIÕåÉ¢  ÛæAa@fèhd­i8Õ÷ñ¡é…ªô±pRÝé,{¼ ôálw³šZ{Þõ@Ð}CiÎ*™…ùx}úÅy¿»×äg¢É¸ªäô›£ç•ü«·mOG"Á–¡>co£žËg›Ço{'µÎÌç4 ª»svç¼;¼B –±ŠMßO«ÙßDpÌÓ³Âé;e !…þJúŸwJóŽ…gJ@|ô—ßiJæ]óŸ;N†¢KÁè3}}ÁŠ’CAgØcƒÙ<Š]Õü¯Ÿ›aʃ)„z }…ÑbìNfÌ:”0 Î±‰µXÎK?!':fþÐR<½"Ãk)îjJBàÎ`rÕ+Í]¶ã…Z‰—ƒ7Üj¹9 Þ寳£g¶Ý8 ÆmûË»ÚÚõƒ¸Ô&>DÀLݬ®ãhÉ(©[zÒë5b´hÚîs0šÎ_!Î&ì¥Qn"L´P xu<±;%þþËï 8›ï¾(g3?…ÏGž`T–«¾è£“Ñá‹jHçK«òr‰^0…ñ˜½Ë*´ª|±tBùã_Œ(¢í›¢Pîõ?Æ£ï–E© /–U¥³–ýD¼lB\štÅ™‚—3ŸÍ%a`ažrHwì~ p.U+èsK)håé¡÷žN\†ˆ“Ë!šÃ„r–`Yº»‰ËJ!’ðÞú >o¹÷$@B¶Lk¼°ŒÓ´ÔãÌcìtæš·+ÙûŒÆ×nì·ƒâȱÝBpkS§‹tœä¾_šùUéûÝ:u[‡xb4©ZÍžDß’úöFëLÄS_n´G½±ÚÎ5><'† % ‹‘«\¤jH—¹4Izñ´{WS`¥×‰æzÔ4†9Ižãî7iÇB vœYjúR&†OÕ“¢NÛJcËú$ó†qåCao×ÝIîÉysïmá[º×R3ô@h·°?0³.QJìÊ•¥?ÌÙí~ ’ú³ðÜ‚)ÜKÞ¿)EÍUiðRî^¢\+›jH’U5`AÎÆzlªãæ<1¿¢ ¥é.]Š9 `‡¾ñÞ Ý)˜Ë2º6Aí™ ?^4³­L ú!c¾Éªx´’ŽïÔL„<}nheb–Â/40`ù%kR)äßZtuã‰Åó¸Fçx±Že¾ªÂ+ž)»ÊTrù½Ql8[*>óò Sz:JzÆÇñµžVo¦6Ø=þSN\ ‰ðƘÓz>Ý26yW Hi¦ÍÑgÐAÆ®„}éû †ÿ¦À*RrnSÄÿȉÝTƒnô)ríˆ>§›¨Ëj'ö#}ù=&Ø¡:?ò|)ã…$n¢|” g\”òþ.`<ÛF‹3³Ë„%@IÃe–$ÌŠhéT‘–;áz>!˜‹é×ËSW ¨7˜p”q+Ç1sŒÃMöøF$6ôëox›Ñ’¿w¡R>2ªi .åFRnÌÖa}0ö“ˆ¡ÎsäëMƳ† 1çøò[Q:¼ÙŒòÙ(L+Ó“Ñ£}rž"€´~Æ Ùð†W\°˜MRû‰˜ÆXsB9¶b ).øXÁÂCçm²#Ð"Ù.šŒÿÛÊP˜*üPÁ"³qðvþùj§ `­l0Ÿ˜«c!eR3þkl8¶×‡4ÿt´þ†ÊJÅo~p a¼ÎBÉAÀ8mÝ åöMÖDyÖsþç@QcBq|à” ´´ Õ·›á9¡ˆK¼eWú ´Åž mø5³žDòR &¢XÛÙ ߆ýáÛ'¿ä„¯i™MQ|è”…°bºg-ÊßAÿ—Ÿµgë!"ÏEhîM¤ŸR?‘ ö^þHøÖ!«aH$¦D€hK¼^N‰6[Cd ®)‹]Þ>Ë'7?ÓVïãmƒüð=ð²-APöžöWF­Õ£9†°ê\FuV`XHWqK¼õ¶…I:ëL^qY¦»ƒa±†S™¬nÙ3†™—e7©5@ m[û%Ë‘YHQ×ñ›2­»nûtcÌ2–xñåm´ŽŠ°VâaÑ„M*ƒ­iOfû³ä[3Ù¾†®„º› tØG[^d çÒçQÑ{T&j¤ ùõ\j º)w¡äÌ4I#!¬ûÀíÏå¥?OÂõ~—büä±O¨Î[JNÕ10\%<Ä~£Ò¡A“|(/0ÎøÓMšVõ›á?YÑ?¯ À#+›ó§>.»ßÔð“GªOëI£!‹Q³Ó€gŸ¦U1–Qm®Zîñ‰ð ĺ!% {åIѰ„u§‹¡DÖ{+&»RŽ Òöt*×™°WIc×#…uT^_v…^ñ9cz"½‹S+ƒne^ýwk«÷Ç»1`Züª ^¾³ÖFQšôE ÆT•_Ïœâ!5SÇê@LÍë"‘»Z.ã¼âKO¢õЙD4wFeiÍC’Y öHØ2¢–}¿ÞÕ dçE$K'£’œ®­fÓ­D^ßÍóràZ»¬dËÊ“œjG9¹öÍñÞšt‰i“úÌMŠÃ]‡b¢Ó}ªnléÁmCÞà;·˜/€Ç•mïœàÙ³ý%+ÌsœÉ|"Àa領Oáâ¬ê‡&—’ÛÏI* ƒñòÅøeSûeD£>‚J • :'L5õÛ­¾0¼Ù‘ô»_¼ð–XP:+åg†®p¼¨d•£'Ö…Y¼dM/gýqî ²NÀ%9øLéôÍpoBŸ†;x¾NYåCEQ )g|ð6le©ðÈ×Å{Î9g*#Ö(?×ÔO·ã`ð½fÍ“0ßñƒÉÊWM *cÁЖC ë¡¥Pïš¡Ûx‹„YöçÉ"s´êûüåÌc¡Ù0_?Œ/v ˜˜í¥¼™›dÁFÖÅWd/ð®·!*t®®L5‘­‡zIš{üž³A§$AŸ þt>Òׯž/<‚XÍ^Jå¡Mê¿Æ5‡Òâÿ¶äCû„Òâx‰%Щ k :¯åþ5³J/ZqÀ`0¢Ìj©ÙðûZ†þXyCð å:Äå¨TõNË4ú'Ý/Ï}¢CLÇÿÃ<îÇ:^Ø7ÖžêKfàˆ~Ð7±º8ž%99”*nMÆ·Rˆ•¥k¤»í Hx³r>жLì3sžÚ‡íh&‰¨8Ì'lþ¸"s›w IÞ­ ¨Ã¥0>5k-üO—’ŠEíýOë»¶ãYâNª1ÝSÛùœ—¯Ÿr°`Ì«Ø×‹Šz^8ñSÚ‚˜Lìà`¡ W˜ÛÎmœ+ÀÞe¶I¤Ü),¢«x#!Ô!OVß/e‘º‘Ó¯«¿†·*„ùë¡2õf/—½Â?yyøÕH"Ìï·/1¶Ë£Ùçêw[º.É|É’lÇn´ã¼:A±~z-~M{Ÿ^¹¼{á^·¤@ÆsÖ%Üðˆ£†Ëw `µ)ÿQaÑþ*ÆB ¾êöj gAÀ` ’bB\š@.XyQÜE¡W,F‰C&·¨¤û[ <©|ß&$´)(Zëêa»@U²S2Äò¯É0žÀ«tk>j›|®‘UÆ¥³ºµV\ŸˆîmòZ‹}¤/Ñt¤,P²o¼6]›ÒtÕ¤° ©ÀÚ!Dûà.Øäc5pÞ{ƺþÍ7{Hc=qp’¸YŠ­¦BT•æÄæ?R/_:ÒiNüB”2úˆ´"Z#_Ûšíÿƒ&–õÊ K×ÅJx;ñ%‹ Æ}$âÍækƺ˜ž»>ÈäCcíTz(kyLaGzˆi¦b´dUÁ§6J²ÎT>¢IeÙŸSÀú]2T¸¹‰—×ÂdïØ‰ZŸ&y· Á+¦dü/Õ*}ýÇ‚éG‡ÊÙ¶WÅ?{ñåÎv0®2â¥%}BOá0wTþÛò9÷Q¹ªU+Ô{ˆµ˜†Í·ª³¿yÑ Ç!´¼ÍÇï‘IæºçÆ*A½j ²æõ‰ ü˜ ÌÂùÜŽŽ¦¾x#ܵòT|:{”¼Ë^Teð8üÞ*yn˜`î×GˆŽúã6&CŠög iƘáEK ÄÛ/—>$’jáê—´øßc|©F¿—ô„ Åhºš}«À·RœŸ÷Åxµ¹¤á¨ö k‹.8¸0LBGWà)ä=ùÍV[8 ü=˜¨W{¯i“hg…«è°hªó "ÑÕ¯Yv²k#c&%Es"…Ç~ºÊ=}²&«W–’Ç•9!¾ó ¨ÛÈcVðWÜ׎÷HÁ$ŠÐ2Ej*M™ÿ—µTûËbù €& Ïcªåao&‡‰é Ø–ìým¹¥¯³Ñ]ÞĦ8 Ö'Ài  ù¸s\;qZ°.¹v;»1¬‡¼Ó¯ºuÞ͇@9Àÿ\IÑ­™jg« Ø=…œ¨‘K”=‰Ö9fü˜ÙÊ2¹y3„*½Ë|Ò™=¸1úȳZp½á³€J‰ß®x<—N‘>#›RåÚØb^*e»Öñ‚†OÓéŸø`2»´K‹Ù/cHÎûô&NØ Ù`—6*ˆ¯ëó…A­±.8ÃKi^hPÕrêí¢ÜCä ¨#絚6kÇoàÖ+ôö½rƳޏ*æs8ÌßÌ lS[¹rSøI¤'¥‡4ãhÞÁ¦¸ÕßtXoÁk«ž™ îRÏÙÝ¥nC´>âw(æ@¾²®ÕTK­HÚÕãwÂóuÊÑ:De>]iÁժߖRÒþ'çRã·‰ÜÇ6‹žÎcÕ²3&Û1› ¶m˜YçàFâ‘‚ððÑ÷Õ[Bké³²‘FS’ @"ýÖcý×?!ÍC†¦½>ò|¼oê;Õq˜¬œ™Ðè“ñ]+>3r²s=Æ/¤P¦ÿòAkÊìÞÆ‘Î0ö]ÛC%A)}œ²Î€Ž8 Aëê…÷i¶9{Ýü‹ŸÅdJænÐM›Èÿj*i¢ÙØRlûÓÇFzkòt‘é–**<àõ =ÔøxìŸÛÜ ×¸ãëX~’Š­…2h×?Voþ¾‰G5ŠÔ_Î äƒß=üuÄ3 ÜqlÕ˜?a§¿H.DËÚ-¯Á­Î!g~Úä­xÏïõÝ«”R´(b?Ñæ!U[¼¢l˜jÊiqNâ„1uôçÒG꥿ìSÝü¼0™«ËQ Å¡ÏU.×.xÉ[s' ŽÇúN&Ü…W¯Ëš¤*@æ«t,†åN8;ù ^ì+sš›7°~ŠfŽhѦhׯoÑ’,ì ÿ˜= Z¡H¦!„D"ЩK gˆ6ªiwwDJG ¾(à]>jû#Æ­ö &ºáz”Eu@ô£`2Ñ;é›â=0ÎAÓœ ÎFÌÿ'sž™¤µ‹µ>8'ôe'˜pʇ°À'I@ Mš‹êP+S•Ðt§d-^0zûÔœ­ÿÇ­ƒ‹‰z×(³]†œ÷„8ëu¤Ò±Ñ*¤uUfe‹™Âé#+çà>¸È(ÊáuP¿n. _^{t!‡†HÁ‡åB¤\ÙßÇÀ\®%”Ô÷._·à3@+&yâal‹Q»œxÙÈHgÌ©öyC߉?,¼ÐM¨¤” tåæ²Þ;™ð¡æ´4€û]9µQJ[†â™0¡Ú¿Pa%Cþ^ìª2 XÒIâ6ÏCÝ]_#d”¿6£Øš ìÍÍ@ÎzÄ—ؽ hرNuRÅÔÄ„/jC54 þ› BüþõµíÜÏ“›âgÌ1 ÞÞõ.¸´[Ã)ñOñqEIïÑ0"wTú¸Lšž’§ß“ÜàP’ a6ÖáP=s¹"æK18‚&µ­CÏQûÔß}Âð«âç YëTQ¢/Ð4‚iC·ß¤<}Œq-ºv"âäN|e7tžp““¤øÝȅ函cèM¿#|A 饕í‘TGè´°$ñ £ôrCÖ äó·åï—/KVÊ’q@1è22õ˜(¨)'«ÝÝÆ”;=i’c\ê÷S:¨„e~]âdvF'"eǤÿ<-"UåŸÙ±ß;ÃnLôsº,íH6ëWf å”±e,èE=÷ÀcÕ×4H7`f'Ñ|ÿ6=lXˆ)ÂRZ5lÌË]à èƒ^4:Ñi„þ0+•U»å½?ÚÆo‡ì0{F»°P<¨Þg ùø‹•nŦËY‰Õ¯¿q¾•Àù~³Q‹Fã&4«N¢…Åø{–G~ÝCÑ‚»(ÅðAË4 ÷ïƒP©r8øˆ'ç#‹æ|¥QƒÕJ9Fwš3Óú¢Ü–È)=¯ǺtÚes`7 4aÚ)WeÀ¼âSA"`éÄëÌ8ω„œUæ41T'—4À.þÿ·E.B¡O)ßÇbÝÚ[Õ ž·•¤ÂË™QEñ¦õëÛÓ1JJµÐÔeK4»IQ“ÚìÎE)/½ìU®0?Ê(U¬[ñ€ð)Æ\)y‚S2¢"í6F÷´ÞCh> Ma@,ŒÁo.O\éI°®Õ°<îʽ™<åôCkþ¾ÑZ8tcùd!Ûæãå¸ ÷Z¦ÝéZ’sÀŸ €˜å«zçTDá„V„LŽ’»,óÇBEY“Œ˜SnÍܽ‹Å+ÜÓá½³I`Ž`hU&GféòŠÝ.Ð_s4psj‰ðÙÕ“—®sþi¹‘TJg AÚ"ARä(}¹áQ¨€ï}s€,R‡ÞfÍ|KÑ Hµ™­`6§?G·`çˆ3W¿¶ç«ß2¿KöfïºRómLÓè]*ÙÐsG§+4‹N0çN2ò½—öô> ѼA5½ðuºÄX»ù‹ÜÈÞq\¡[`¸€ä5â;[nÕDtDƒ…WÿÄŠe6Új-Úhs÷¦B™p©_§ÔL* {1ÕˆP¬·ƒä"~X`àk‹¾âÀnDt¦‚Š;Æð‡,(~=Ë>¼=Oƒ4sW­að'†°Â ÖçWªñ´ïÊýÖø›CÕ×µ\­Ïó/Kr±°|; }•9U¦B"†Qü¬àbB´Ñ³Îq 6e1ì*­ÛÈÍ9­\–y€IÎY¾„ß#vI.=ªº\¤Èà4þÚèf<Ž ˜€¢®õIRØBûÂ)Èã;ìÀçö²(Ûû}δñrC¨“¸ëpÄé·º$¨)LE*½´=¿V‡µœx1óÙÑ¥<Ë¥+"©A³¦âR¶zè «ˆPè:Ôä{/ ÍoU¥ÛnA)à:Îa™™£M㺃yÕÇöYGßkA 1B¯Û›ä!4sö1$HGÀªŽf÷BSH´ƒÓóš€ÎaÝ5õ6[ˆ¬-T¥©uŽ!˜ÌP kàð£å+D«öC‹í‡Gk£ô(›1˜é“ß©G¯rNº¥‚ŒžW¨¢šaj­Du#˜ <½"+UïÙ £LÆç"%­Ñù6¾üVoû8Èùê O ‘Fî,7¬*< €t.J ;ZÅþ·uôQx²TÝ^q²£?xçOô|xwÇ8\:wÞ€@2õI¸†S V‡€ÂÙ õ öåJ™ÄËÃŒø$dRÍöØ’ãl8o(Âî!À–kogª£(óöƒÖaÁ$ú˜Lƒ÷ýú9áÕûS~‚ú:µM£º(‡Uzñ>)kYž*cS¾É«U`hÿXVô° VØYˆbÌ Q÷A  +· üñÒô¿ÜšŠ&Ï;ë`è ïxÉHÛ VàR®xxËðÌpjDãQ&>üÅ»vÿåôS[Ÿ×öb‰Dqª]> ˜»BºÙI”;°ü©¦Zq)õ øE¿È)ˆˆXÙ†UPø7(ŠÐ·’¿õ¾§ À¨È”¹¸C¡¡ó€¶ÃÃ7[gÜæéu`c=ˆ ¨~b¸¨™Ì&"éb |t¯ÙÞx¸r ‡¤’Ø×åÍs±î# U~åü¸£»ëž¼ˆ÷˜5xej&Y±ÁýòëRÒ§íþÅï‰zÄ(®0•µ²åš‡fÐØbÊ1sr ¬±*ïÄßJoÄ_F¢N bq.&EGçr00@‡aJus•pNø(%¼Ð­Zí¬žÌoÂSŸát»HÓˆ–¥7iÆÅAÜÁqêÔÍŒëC7sø+VI¨5È—¸ä5»ICëyð#õ¬×Âqœë~¦ÿg¯äTø†sè»ZÂöJ=w\5Ÿ0ᛮмôüf/*ä´”º;lp´ß endstream endobj 644 0 obj << /Length1 3480 /Length2 32330 /Length3 0 /Length 34152 /Filter /FlateDecode >> stream xÚ̹eTœ[6Š;wi Xp‡àîî¤qh qw î   înà‚w·sÎÌ$gîÜu¿Ÿßbõê~ªvU=%{¿»iJU f1 PäèÊÌÎÂö  Ô•ñrj]€`fu •›½© €ƒ… …†FÂhêjr”4u¾ðºZTÌ]!öllü(4 #Т´˜y”€®¦š^N@v½é_@ve63CÔ@G+G ÄDääåbceíúËó/GKË/&€_T@OW #üË©8 @ÞÔÜä¶³˜:ZäY”XÊ ˆÐ@r˜­Mí- Ë¿\hiH©kdÔU´T5XÚ6@WGSHn@€¹µ©‹©¹+Ð ðBâ˜ZXüÍ[ÖÔ i „¼L­Y 5Üœœ@.ÿÊJBCSK† )¦¬)j3d´44™Êšá_š_¤ rŽ6¦¿Ì•¤4Å4õT¥ØYUÀp‡Ä´ùÅô¿Ò¡…$ø ÄÔÒäðW½µ««ÓkVV+7°+ ÈÅŠÅÉžáWMkH ;äÝhü«ÄnŽƸBùËÁ¯mÌ!µþ•ø—RILYNZJC“R-æ_gþ»ù,®ž®å¢.%&©$õ¿Ô¿ÚØÁõë—/ H“mìÁ,`  ‡0‚uýOÖÆ¸þ"lÿ7„8úßé±ZBXƒYÿµÌú+fieMfE9 )e ©¿X‚\~;pu³úeûdøÒY›‚ÿ¢¬¨ªªp0µq„L©£9„Ÿ«©«@õ— òZPý]t @ÂÍÅåWjJÿV¹ü'»·CIÇÐÞÇÏÔã¿×ÔÑ ìýG¿ÿÙJsÈÀÛ€]Á{þ«Òö¤·6Žÿÿ½ûeðË¥˜¤"d¯r³8 /6È.–r´98@ˆƒQ~M…¤ ¤C® /Öÿ½ûíAŽ>ÿJKG‹_µX¸9±j9Ú8»å$ÿe¡ü–Y]l 3dC›[³þ ü×vø%fÿ%†ÔÄÏÇ ä°4µýl,7°©;dP]Ü€~>*þ‰PØy6æ®Í9WPþò.çh ðÿ-†0ù·ê_cHÿ×™Æ9Ð,@Žö^ѵDaU¹B†þÿö#é¿XK»ÙÛ+CÐÿÏý÷bS{¯ÿ÷òÿZ¦ü•?ýÿöa–¶ñZ¨Ú¸š[ÿÝ­¿år®¦ 'æhe„tú/‘Ö¯CȲ3 g¿Í¯G€™í¿u¡7·s‚Áî¿U@Hÿ‹6¤¡¿HX54¥Ô$ÿ÷4þµVÊÑdaãhx€©‹‹© dÄ8¸¹>ì­côük¬,Ž Wˆ ÀÉÍÕïW‡Q~Í 7€Uì—èoÄ`ÿx¬¿€Uò7â°Jýñ²X¥#v«ÌoÄ`•ý8¬r¿€Uþ7‚pQø \#¥ßÂEù7‚pQùâƒpQý ÑÕ#Htß]ó7‚D×ú ѵ#Htß]÷7‚D×ûâ‡D×ÿ v¦ÿA\.¦ÍÅl÷»¦®¿- ¾ÍþƒØ9 Z3H« ˜A¶ ä¹géú‡˜û_â¿wò¼±ÿ-¶ºþc=?çäÿ4`ç‚dcÙbÀ?CDæÿAÜ‚æ {Èlÿ'-®_‡ß‰þzV‹? „ð·HiÿŒÊýkƒ…)Øúw]~‰œÝLíÿ#ᄆL²½©Ãž!%µü£ ª–6¿#qþ‚î¿C³sBˆYþvÉýËäöG}Ù &V¿I@ôV¿®À?—@òýÍ“ Ryk/'k ã+ 2›? $aÛ? d(ìþ€‚Úÿ!)ü‘ ;„ðoÏÜSGÈò‡R&Ðo2cÐ?Ôœ~«!ΜL!ñ û¿¤ÿ.k'È<þh$;¤:ο«ó ¹Át¿'ˆ÷—yp›ÙÿsH¹ø~kþ{ìxþ¥ú/9;¤Ö”žRXðïj@²lþ9ŽÜ¿ÖÝÿè7Ä ØÆówf†`û?‡ÿwØ_ãèjíücf!•sõýañáö{‹@bþu›ƒ\þ,?$c÷? „°ÇÓ qêù„DõúBZçý›3Ä“7Ðåoÿ|Z¨þºýu»`ûýøø×åû/¬áê²êØX@¾Âü±Dɲù= Ø Wvˆò÷ïOFÿ@óûV󇵸8ÈÓ‡™›ƒÀÌÁÇþkgñü|n¿Øšÿ}güëZyÎýÿº­€@O 9ÊÂ7¹@¨mzCx©¿Ôlj2x~–à |a]ùD¸…÷m$„’¹T@‘‚ ¦ÀLÚ¢ìk#ÿÔ Ç"]šP<û§Õæ”Oã—j¢›¦þJþ$RbÃ9Ú,ZÁ™JóeT {ò9ùzÅ\S™-‰-ä­á} þ¶ÎÛXޱg¬ó4*ò–åaáàJ5 Õzë"`‡¸Ã%‘@¨„Ñíhl=ßl ]£ÀÙa¤•À‡œ8ëc¼RIñ'Ì«~EO~¯¶Ð°­U×å Xâìš>º–Bócµt©ï´Ùü9<D„­œÙ%?'xÊ“(7åGrõož¸TËa·µÁX¦Q¿šWBD BLÊv–;i3+ŠTÁÚW(-ZýlçrAÂyGOÈN®tg $7Œ¹þRã3}‘«j(b¨–™¶ýŒaM³LÇxû§Ø>$‚ÙG½æžæ$ǃ»€Õ^ÆTó¯Óé¶ß´7•»ÙêÈVƒF¹?娯çzb‘ÉÏA'¨ìô™UAß§<Ñ%wxó|ÞR;ǸD O}?Èßy² ¡S m³‚<Ô”3EÈiÀ1ðOAÞªöE ì%&¹¹ksªR¦äô¤Ã|ÍÑ|é¯,Âï?AAåÝ`·½Ýï¦7$ìÓèTbꃵŽj­¯†Áhо;ò=1ÛJã ÷ (¨^Ýpë·æ¿ô“U»º|£o¹ð*Å—'{_Ä^}!†GR…c•lÔãâk­í«úK’J²®öáòÈ~îv*n_ÒoCp&–¯=bsˆ¿_²uk$¹>×—© Û*c'_mHm¤|×½¨¾7]Ë®aB1TRá{/n°Ï,|S>£;,w†FßnóAçqÆ9Á³† ÊÅe]§p1B\–SYŽ1=ôMDóA]Ã{™Ä‡h^¯Ä¶¬Æ±K›…e­{ÞU5)v˜]U#PüÔ£<Òïr÷ù3Ôrøéë\¶ng–ŒmŸ[ù‚³^FL‚¾µÍŠóeõ¦·ö”•ò™}ãÝí 1hhM;”³)îû‚àZ£@¢Ä¦5êÌ!Uèù˸‘*µÎ)gÜuíÑ/r<‹|1{ˆ•úeâ—XÀTPGòÞÛ‚Ýì/‘ lÉ-+ÞòàÉ ÁØö«ÜdXiù¦Ó­`×Y,·ÚÊ\é…wæ˜Í-²¢cÔ^ÉàF™sÂÉ`Ч7â®j÷j4‹Þ+Dë]oäRõ_÷_÷f𛊇¡DâË ™N#éóHE׎À@1‰[/‘ŒòŒWÁ bMŽ|%´ÇsžEãkî‰ ° ¨ AµŒT[Ô5 Ñàƒ¥ß—BËÿþGwx\º)W@á%ê[ñ,šg$CƒÏ`|³ñçU^Á©o¤V‚PGÅvŒ•3oŸ'ûmÄ@joÑ{4²Û±ªòØJ^ÐÕ"_³¢¹07Ù2 !ú OÜîm•ªŽp].VÇ0 Î1ЀY£, ‚U¡˜[C¹_´ºz†ê)zÏ#’ÁU[OöÁÈÏ­ÑöL¸WæcîO¼(x Œ MBle¬ò»óDØòK¢©¸H)?aÆ#±±ØÂ~ŒìµF(™†©ñ‚ÃÑuæÂÖ%ЂƒÆXrÛ¡üÏžQï’IQ32<°ã‡; ¼Yô·É¸¤m›† r—™8u]:GÚ‰ØÖK?=KZOOжÏ[Ž+RbB²™J uÌÉ㇯Ú)Ó¹[(fmúôõ=Ìž¨ f«Wä}ÃI‡ÔÓÅDèg_-S=)ÙXT ßî°+åcïúÑ›¡s†XWº×ÐHð²TÚ‘çwÉ‹?1GG‘ý¾Aå=YSð!ië\7ÓÓ½T®çq{áqüöEen5‰öë¨2f¬Õ²aÖÊ .Ç71 ¶ë‰t³§:äष&,žµ·òí _‚žlŽ´{"ðé|âãF•+¤à6y²_‹TöùZ²g¢_¦|Zá 4ºY§GÉ.jó(LØhöÍQÙÈíU±Øš‡Mň ½m´/‘.”úÊ|ATérªý&•Ú´×pÍ.}.ç…Ü»5¤‰ïë4Ï_çn&+Å=p)/áÚ}ŽìПÏÒ‚vé2êC¶-7€]lÌ…Û ð°é¡‹äRJТ2dãðÙ´&݈ùã+×2¾;*z“EWŠPÒë>¶å@ V£eËÚÏk[õtoÿ„Eðc£©ûŽq-¸AöàF©×œÍì¡fD›¿åH¾/øÁHÜfÛÆ&G>®hë—š Or—ìzð£DܰŸƒãÇ«AËD°Q9§Ð'ÃzXóµdaÏÍ×3[¥;o.|í-úàO^íbr“„ø“ûD?ðr¾*h‰RÞÿfH%YBÙT±`÷õ8ㆫ®öûháºINP7ž8vMû\±“(zÀ9ƒéöÚp4™îF”p¨+¿bö~á és£‡-øeãW}mÔ R‡Ö-l›J™Ù¢Ù¶¾ Y¸1šG(ñÓE%TxPߣD‹¶¡D€Õy@Ç éG­ýÑKs~mGíJžHÚ5*æË¢Ý¿žÎŠÔsþÔBµHÄÎ¥IU1\qž©D¥â•°neÐÃy^µsV_³O~¿oGéÂ,\n#X˜ùÒC)"»jËß&áê+“5›¹|zÇ _ÓM©þ[qlÌ2 {öJ+òüÀë=vŸ -éØù™‹Ý©í›X­¡òŒ¦²~=½MÚ.r’z*{ï!K*ÙóŒ(¿[ b®Qçç˜ñã(©Yv*¹ÁÇ1#¦‹âƒ½ß=%ˆ,ëzSŸ/Ó$ŸÑg¥”%Η^Á}Ï9›´²S±¼ÄK³‹–k·üذ6ggœúµ]8ÿ—zýi;á!¢“Þ׸vùyŸuÀ'š‚4AZ<™÷5["UäzSZƒ{Ñ/ðhƪê|ÉDÅOå”íw¶=aØÒMéÇÑ•y.q}Ï:ø×‘Þm†.k¦N&T÷Ñ¢y«ÃB}Ó*(>l k™$×Fà¤"€*œË™büÄj «r µ'nÔqééõ)¹×ì£ï¶|4>ãB+-Ž‹FË[]"±½â!ïµ£*/éx$œ§oÝ¢uÅš‡ËçF×;fÊ5ÜkýnÚ·çFD‚yû Ç¿ +‹xRˆÙW‘§÷]FMëµàf„ ̱Údñ“?0sn»@NçË€/¾«ÜÜb$õ#Bè©õïQÄŽƒîöôáBy*…håØÚè™Få¤~i0Aks²±iX’yû0š÷W ¼¼Tž£Qâú_JY5¯LŽýïPW'¦èØ8Ö GsúöaˆÎ¾ú.`–°r*R‘ܳþÍh€¨cç<<ô¼ïûº’^±ÉîÚñ QåæÙŽ6UöšCŽk†}ëI¼ˆ¾îþ[ÛóÇbòs!œÇÊZñ0 ‡ÕæÝ-¬ÏXZäV„…²öÆ»›ÔQzݦˆÛóØ!ìçÎFÈB§Ô+O –Þ±ìŸâ¤Sœ¾+gRÙe±ìÛ¥YR·•a!ÓÌî?÷w÷OŸ+ï%tw‰ÂäØ\à^î˜>`öTzÒL0ôÞÐ#º&ùC¥!°s†Õ• - Üßh”½¾ÂÝàÂ~4½–çZž¶iÊÍOФ­¦"x«¯oˆªÜ»ep…4í #Ì-{é‘ ±ðÚ,]);¦í¹Ži)#]10W:âÐéý Q ÆGtL Øu®u1¶dN©»¾¡üÐlþ@ã;Ù½¶À˰Fx¹wGï,ßù§)~|ðÚ£ŒN4XY/ÏƒÞÆ8F2§[½vj Õ±â±_Eç-aEκÑÁ VNN²¢z_¹šÃ€wjñЪæ1Æu]ïX½×;óí|,õ ó¼o×0î—.Í&3í?å‡ÏCÓ‹Êÿš^ý²»œM˜4z` ´ü¾{Þ¶u+ÅâýÍí€2O©8a™õý末NþhÅ…1ßwøÛ×ó°ßI¹UåæoÑoIÕ¾´5Ê÷+ÇÜ‹`²Yt2‹8¨ýÜkÜ•7j-O^]SînQ09Ü€ $¤†2i.y‰qTÃL˜Ô¸š®—oñíì+¦ég+ôѺD˜AŸ´Ù+ãñáä5e™®AœÐ3e'’!ßmbåÄì:¯¸°TBrû å´\4Ž'Û”Áñt ùšL¬ÂVåq}5¬” l³7×iß{ª:R§þ‰®á—AGq1¡}ÔxÚòR¡¤î`þ÷½¶oì1z˜ ä+qE¡9²jƒîp FÄíõHò™/B¢&C¾)¼my}PÁè`Q”Œqzv—9M¿È¸ƒ,6âñœÚÆ8Z¢K§tV˜ÏQ£ñš*!*Á”ü3+ÌÄÅžè¥=@®SƒïhýVó:þvZ^lÿåN~E05)#CÑ¡pÊÆ}Λ[CÁ<á¨gyô6ÚWçÙ¶m~ñÝžþó%-E]9;|tÝ i´uB7ðž¿éTÏn]•NžtbÍ…Zí€iÅE‘Ò  L/‚ŽÄ”øˆ“ý¾ÖÐÕM@qöQ¦ÁúCœÚÇì°Ì÷ûÑ/¤íÒö³yžï˜øÜ¢Æ‹T÷ÝA_ÔX`b„T; ²fg/é—¤ ËgZoÓ‘EŒgTÎñåÍ´ëàjtåÙö†¹F=ÑHÞS¢·±3ß¼bˆïßFÏc“Ü‹q•f}·,Ew9ˆ•sk½J_’Û¼¤ÅœMë^ ŽˆÛß…ã é}rûÐýCcu}.!Hš…zÒ3ë¾Dçî0½•Ü/89ª'd¾zíRíŠ(ïÏ~ýE o‘)Ž”tß ê§`aÛñ=…‘%ö56 Í‘$ a2Ì÷¾ ½¿nšíh*‚MnÞ%²d¥g®}yCeT}/ß)˜Ãj¹ÒiÞH{Ò/jy¸Ü¯$ÞöÌoCuˆ¸KåÑÑljôKJWn¾”*5"g—ý`8jÅLã#úàÔÅm¤nC¨ú§´Íì¨W0„Máwm95‘ DK‡ÕTy€½®4²º kD¾y¸9/,‘üñ¹/Îâw™èqTóQE¤}8KóVïÁÒtYÌA‹‹¬˜@ƒN7‹]]r`IN©‚Z¤ ÕXš§}ýŠÝb¦Jä2•GŽ”Ÿ ÞÄŽ´[Öœ[JmwÄz Ÿ{Ó2ÑYÃ|Èaá<ÔEMqý>ìº@άͺ”¯pç±y¢°±¿ ì*d<™kÙ=a Û ' ®4±O›«Îcº•—c÷cl‹¨o኶Ú{ƒ¼¸¶0§¢ª#§¹ßÚ5ÌnæÂÚºhÖû+’ D¯*Ф5fF˜€Cî•KÕÉæ“ê(7’ÍÓ¯ÌseܯQW²ìµÒw ˆÚµ¿œþXF^û1ùöÆ2AHÐF¹™¸L57ÜÑcé-lÄ|»6Íkï¥c-\퀘ztž°8 Qa¤S»ö´Ä²œÕ ƒi5äÏâézÉ?b?®B.õÞ†ƒJä+pFoÔ£õðÞø Ì-*ž$¼ˆ“,,[dÇL%li_¿€®u*”9¯»¬†#[„Ïl#dÓ(¨%aX.Ñ¢-3c_™jÈ¥aÓDo8}òÿ8綈7Ðî”ãørÝè…fÄ;Få4cùúÖÔxw>ú‘{‡OjΜ-{›¯×“Ì´aa¤+¬=C?júåÂñ¥’-“S<õ=êTEQ´°¸µ˜F¿_™Oß] Àá­0ŽD|üêîÐ÷¡Öá xü¢Å”—«Þ.n³[`,ÊP¸×rõ®X ò©ÇEIä¢ú¥qÏ0›ásc²Ö•U»%ŒF1‹¹Ì‡Îï÷b%਎V '~XRn˜“+n«²£~ûú×¾…aRãk´€ÐZ©„¥½ø½mÆ5Á›§nÂÓ&ØÎõoCšáSÈ©qÁ›Yø 4ëD}ÂNi¥¬¸h¸W¿›öZoêl{Òå´ bmj°šwk݇ÿ,bé™Iׇ1xd#ø6ØÎ.­<Àþ•ʲԯ·ä/ ÊÉp-&ñú‰ rFðÕÝLJ‡Ï'#‚P‰dë! ïÓäÐ9×ȱsEµÐs²—`´ë" ¿}nè’¶6b"nFùà2™R4|†»¨šî‚8K²$C½þnIVÛýØÝ3ó[»3cí 5-ª>¹åF C¶1e¹èǧ=d>–Óá;:…ÖöMütüq©­šj’ûz/éºV]ßÞ»w‰ðŽÝª¼t,¶§añ8óÆHhéfGMïÇE³_Òx3¤`|}#:ìðü]âÛàùÖ%²ñ4R¼€ÓWÐEº1ø7KOçèb%Ñѧý³Õqœ"É„0ew6uGXz€€Hì=íÛ V! çæy|¶Š2f“$D¯o1ú8ÁXlÊ€®ÔÝzç3µùr·Ñ ²ÔJÄ v„+ºŸUÙ.ª•+Œ¯,Û?¯àxʉ¿=+œ×|”y<Æ€›u[9ðªªÆØ·q"²Äy°x¸ú†£T™ôV=Ãs¦7÷4›Rƒ¹ä^ÿ»F)cj]`Ûµ…µ*9m¾O:`\[ FJ¨s•“O:yÕ¢ñHo‹P&¿ýHèd€Ö{a5bCð%®Ö!¼ÏçÜÐ)ØõôQU\‹7«ü¶C(Ø<æ¼PPþ×’ÇÔOw߇á¨\X•ãж¨œ|a«R Û*{ý¦"îÒ6mó¡ÙÐÕ¾bwø¶˜¥ÿ‰È3½fŠPUBò÷£‡öˆç Ù69Ž_ŸçC9!˜¿4©‚ï|>>Šà!-·æ°K€T®× 6$Ä}BÕúŽBĦ¢Øž=0Ž"T¤šLøeÃù_Î^p›¸Š[›0ö‰šÁ43©¬HÛ3¶4¯ÕÇ\qôñaÀucºi5W<òŠÅ|æfÖ¡®.þ摃ÔDÞSY©HänÎóƒ¡>‚çØ Ë¾4,j³œL|½Ø­ò¾p°ûAoOe\;«˜.ˇå»ÎáãɈìzë·™ÓºòNiÜÖê *GxUNŠš2–ª‚.Þb ;XÌ"!vpÛ»Мfª\yé°à™H7µ*°¤5Âr‹¢Ó˜ŒÚýiã¢Îð¢o—y $r5Jyç1Ó%¤39øûsKa7Æf’P§©bJ.½v %}æÙwDYÇTž¾ªIå°æ'0N‹/%”àºçÈd±â|QZñ2'Õ¬Ghg)ì²~ð‡³¾›>y‰sŽÝå×,tr¾ó¼k ¥rÄ~ëŨïµRÈC0†VUO9•Ž@Ó!isûÔÑümåÂ*®›™BªDß,Õ_OPx»¯h¾l”.²Ë-gé`QÒ±²syo¨Šî^™ï.P«ø…ÝŠÈßî°e`"Åäm~,|ˆã[…ûÔ×G^ù±æ¤)Ù™¨à )Ž`†0câ}7<¾dú‘±«MzBmJ3Ü'mHûöM)ŸÌX'Ó3ý+ ‰YðôÒä¾Zi¬9-­[¤Tè•Á·MÍñ ‰¸éZ›¤)InùM¦C™Ô ÕŸÝ]¬¦žˆë û·Õd"ÛxL? _(HUNßpÂ5”Û˜Å}§û4ÊÂZ=„GP·ZÕ6ž2"ᘑ‚õ¿N… vñ«@ énZ1îuí:¡„ õ§>ÃE}¤’ë½wÁH*xœ úcîŽG”Ñm”š]î5æ\,Ñ6þŽ÷BS•äÖG¬ˆê ªv.ýBWõ!µýN\/W¿íõ¶¹’¬žǾ"«D€Æßä}_âaåûØ,:cü™Kÿ1=R²®°7 u]ÿÁžÕ«éºàÇÓÔÚpû¸‚À¬WI¹c8íÎÞÅÏžŠgóEU.¹ ¬‘dËÊ÷²ÛJpŸP;Ïñ¢‘cfºhK¬Ü †Ž j‚7,*b*àN½¶´¼÷)²Çi^ô™t²úÑÁ,q3#¹J2\òë’q:›4m%™›ƒ«?x—4àá_6¡o5Üvjçy[œ.#«ŽÁG@É1ñ™7Þ„%’­ù=ê˜@B“îù+Jª¦ÖFeö>â³pÝ;„ešñeÍÉ®íò¯é_TC§zuI¾j›Mso#)ÇÇ1—3Ñ̘n,U–Zbî}-T!•Uw“܈Œ®ÄwêýÖRµýj[‡Æî´¸­¼B®MyJLXWÖʽ ƒá1oŒïɺGìç!‹O[dÙ1¶¤»«p!×g]ÉëÉ…Û,ˆ7P9äÒVPHp×wƒJ@ëïe8…ØÈ|èO4ëa|m¨ñ˰µ 9ý„`ß_Žkw]‘d`Ù}&МCDÆöÛdÝ£to¶ Sæ­ÓÑâ*ù8f•"a£Óò%fÊ—aY’&E”üôÈÔ; Ôë]ÄûŠ®­|•"vû?Žû¡öl×÷‹`›€rÜΔ 1”ƒIo6]ðAè¼õÒ)u­ŸRv8ÿ8†9+íîü`$_ÚÙU=K×È`ørÐå[ýÈæ²Ÿ¬ópD: zLÀ'OÈ<íä¥S€ˆ8¿‡rÿT!oªçÙlu.é0îÀg\BùÙ 3‰ ÂX‘Ó®Hð›¦ØCf¨ëÃ~ ÎÒ¶k Úè;²óÎ&MºŒÊß#šQ玧Ÿtªßs-ýåŠÓ¾zŸT©=T\[µrˆÙ¨ ΢Sé>½úàþè ^>ò)Ålv¬Hâæ°CQ= VÖKŸ?ô+þÁø¼‘™î©n:ίgîõZó£[«fœ\da ®Eø°ÛzßÖÀÇØ¡rÇWcGg~Ì[ÔôfÝdGb&ŒTƒ‘H¬B«?µb­·ýæV_zæW}¬C\£YÖãþðù•jstÍÔtq="-å´grgÝKvGâ‚Ú邊Ò*k´“à,/Ízlé×áÕf³"@µÕWÅØ.×Î;pƒ×°¯QšÍ®(e±ï&„¦jP¢mQ“½Ž€X¨P¼_ë·q7hS¤Þô혰 显lvÕV?¼{1Ô®óY’« ¹\Wó°à³>¢žºÈ|@¶¾ƒðôߎÝ÷iQþY¯¨5÷‰¾uÔp¡BÚÕ<1™çÍÌ•N5­lÐòf…­Õ÷h Y±Šèø³hϧ) ‚oò­zMš/Cš*U"­Ÿ°*°wiÌß)Ö9T‡˜Ze1ïPØro¿¤vÌݺ{e«Ôî-‚ÇvÕÝôùj“Ù¼Š3ñëx»³ÝKèg½£HG‘/±•LŽ—Êÿþ¥ÓÅ„ê|3€ÓÛ§èÂY´ðœû3ÉÇ/šçÒ@r݈§hŸü·ûÇÉî…K{FQ WOb|ð¹¯ÌÈ[Êh^^O môžÃ4ÛVõ¿‡Z“|åùdÚÙ˲¾û ª¯7âK‚ëI;z¯ÜÎÍ¿[U/lãÿÕNÎ];€t‚¥Öôû%¥#*±¯UïSK½ Õ^1[y¬ ÏùD0A‹åˆe¨®zítЬ•IQ«¼[pXË'¹6¥×—LOtkzg"ƒ2ÓÇ?jäU·Dû¶6Û:…—È¥dèFNôê}`j92Ë—‘ÐwvO»!£íoß¼¸/ìN@]ÂÂ6Üè1ïà}×ñ ª™¯ØŸ^›ºoÔyæÝ\RÈã#.ó€.šß;ª³“&K Uf .ÐŽÑ%\‹9VÈÖ{ PÓ‡?qKZÝf!“–ñĘ3ç5Í ¯¤hàB;¶“vö¹ лö—s9‘ô8®Ò—_‡Ÿ Hb xå£ñãOXOLçMÕ‚ÅáõÇ5‡\W7¾ä©,¡·[§}Ýv²3÷Åx¯Ð¨˜|Ö?ŽhÊÈ“Œpm]» Z r.a Áô›ŽO3ZL¶{p?Ÿ”’εÔmSÕú­/¸UÅÜœ|<¾(ïÀ–&üÔo°H„ ÉÑò€ÇKrC,ñCÐjG¶Í•ó†~5s™vwÞ°_Ðf©Ž§¢a×h«¦Ú ¹±eØ«‚æÂ[Y‰ôÇ4[Öe‘G™b¡åYH¥çè¡^ÍÙ÷ÅS[I,P½Ç)¯«À9n§gSªËw¬ÄÙ™çU6ùé^^¿tw«á§Æ,Œ‰&\ŠÕíWLËè Ò²ãXèõ¬•‹Ö¥þYµ¥ ›2IܲA;g9¢X‚¡—õê:ùG p©$å'³Jºß3~ôânž³ÝPíuhÑòVô‹:þ=Ÿêq-/ûç+#©6Ô!aÑgª­T$Ð;$»ü¥À+{”•B³Ñ«$EØo-\\#»Í^êò½x<ÕÂÕ/|Ôh¡æTTÔÐ]b¥›dª;[5„sMµ^èòæÂIèc»:ò“, ôÑC¶ ZçÈ=ÊRœ{ê¶ÚöwZïjê•°(PíÖHniNŸ?<öœÏLß®fÛê¸ÑÓÜDö5µÊT!QæRXm ‚>ޛꞅ–}ÃYñÔþïcTï›$HZËŒÃá=tC¨Ö(­3oÎ O"Q=÷­—˜3wÜ#Än骣7`y)ÄÇê"Ò+Ì*ãÆU$J´"cïXÚº¯v$Äš¾Óã^<Æ{LT[vO¿÷lv¼]{3_ñ‰qíÒ‚ì5ùÝ ‘öØ*%XUE¸Tì„K­Õ3K…d+Q»˜jDH¡”d²kõ”xœÄ7fw`2ÂqÎÖŸÐÚÆ‚Áè¦2·A¶Ôò^‹fUt’ ßc‡ÌÄæp6n’9~2Ù~äy‹=­w´lZ2"ÒÖb¥çÖ¼E‘áÞj#÷†ŽÇÅîçÉMVz}©ÄkЍ%9¨ï£†Ì¦M¨ž´ÄŒºÿãw´Ìûž`c¡,­Í2|SNâf"k4ú>)hr0¾r×Ð)z;ôðÕüüYf¸±eÕ¡1p£PT‚1}4ÀæÚªÈû¢å;Sra¬Ô$ìÐQq0LUzªì{:3wÆ€7ì¸EÝcKÒ‚þÏÎâó‘•jš«í)‡ íë=´IÉ£Y_|Ú½KÀ»Ë…“{ GN  Ü9Y2S1#ñ×m-|™”Í~9á%näÅbw•¹úƒÜ¾à.%‚Šô½%%ã2k…¸Oý“Ìù1ÉÞ굓švlÌ íx°è>¢ft_‹O«»iÙe ®ëªcJL‚3s²Q•y E7N¢·CްßR÷VÕø¿ybŸR¾Ò~x4u¾;<«Ü’#bË›i0k£ìÿòàcLò¯Oã%HÎ݉hµÓAwx]§ao¾+­û©’×.±×¯ ÙÖ}›‡ºÖ.9D"NU×B‡­âðº;´½)!wEÉ׬ڨ{X³C¶×Úþš%#Ì1VY…Q„I 1ýPþëÉʇ|AFG–¸"B|!*k°2á£tŸuŸÄ½êK¤#çüƒûAÆåƒ%ÔL}c‡/±\¯êǨôÓͽœ£O{6Þg7â¶6t“xÖÓ¸êã-;2“óJÝKዾÁ'Žö•Ÿ±èÍ·‰{úÍ›RÍ'hÄRV¡‚ñ'ê }‹DŸI‹1iº¯xq¨PLÎJbüN%s‚ô‰šKé•C1‘§‰Ñ whË]÷ßûš°múq52UåÙ+…ü–`é}7£fA_2]kŽë…ݪuC0³Œá–lÕ5ÜÀ!—Ðý„¸ävÓü› ësžûT)»ò^äÆi!„¢dx³ÝÄJ¨øðÞW['DQ¼þ †AŠ®Ši?2ðŸs½lVÐöíÓl⹇PïTéƒÈöO2W˜:òGÈEµÕÑ©BPøê£Æ< #³‹èHU1*4 `!†3Å× ­Uò|GŽëøÙã=(ÅEÄßÞÝuåvYêõ wVÛíiq?ØÌè±xÜÚº;N$¯ý#ÄÒðX[…ªgŒ Ë軟m¬Â5ýë‹°m-ål­ƒ¶y#‡.¦üÍ“£uÕDKÓ§CÜ*­ ðBM]¸µØtYÒ\×·VöbfÝËemûãááeÉ϶ÏgëÜÏþÇ;öHX—ˆµÝ}P¨.¸‹ ?ñYÃç@G8ËäïÑÊÞ®ÇöT=`ï Dó¯8+éôÒ ÄI‚ýø‡0Ù¼¼g‘™¨vÀh´ÅhÈ÷ôÏj@Ÿè¤¬ ¦í7Œ=Š©yÅíà#.Ä÷)è/µX´˜nkx}ßs7΄j&Â…nÄß0mÂm÷ ÔkMÌ«öÑÄ›{éà›=ÎÕ²8“  ”HÍ*á›ÀŽóÙp#ÕbP8’.¢ ¤ªlŽõÓªŽÓâ‰i9îÃ97ÍB°½¡³¢±’´Ô)탘gS„C®úK<Ђ²ÙcH—«Êû <ïíWÂip|)ß)‡ô·§ "²~¥±É‚¸i3Ê ¾)oŠŽî-,#¾ºP@\ì­ÎäçÚò¤2¸ÔR&NQP}æ_¾Î¤×澫›ùH†ÌQ’aNYÎNþ=ØÍæã¤(WANÚÑÆÀ‰V·~­V Ƕµ$°KÔCr ˆ8p87YÃûtî±RÎB6¸5'Ç4®l5¾ Š™Þ_„wyÊâ¹ßÎrÊ(<á¡@¸f.ÅžîIb>˜åêë:YEa;VGQåU‘z@¤ã5lâlöÄí#4ð`ahÞ,¨•øB¸=ñ†AJ›µÚŸhÀ«%4…@J·Zûv /ÙûKƒÅT[—ˆš±y°Y"ÆËU®;YÍÿ´f£µõ58¤†¹Â<(í¡‰(Ô†¢þæXIYŸ^ÉË÷ëã;Å~òÏ3‘ n…çæ¡‹Ç¢Ž]×s<àœïÍusÍWç#¨À›²ýL¤R+(› Y93ï¹mcæ°±Òv"¢$6iË™Ý R– XVC„»fxª­ÀoØD cðÞiਡ9Ù:((Í??:ӛƺiÆ;ù”T:ª¡è‚¾ùï¦ Ûpkç]„þ•’»ýLh^öŒjŒ áŠÓ Ÿ¿¾N±éÌ5Õð[8ÝüIˆ?ðz•§’à¿Ï Û’ð‹€“W·©×âùd“>5~Ã(lÆ(¡H&8|ô%úIê¥ß*MŽ& OfGß踠æ¶ÅˇC®x5HÀŸ–Ó“<¼æ:<¡U÷ü&=‘¾)ïQv¾˜’õ¥)hÂT,KïŠ,Ï;­@eÛ8¥%`ì¿9=­f1í¿&t¸ëƉ‚æÇA*aß.H¬ÁÖð®`5¨j#CøÄ­f¥¾˜Î ˆq)j˜·0¦ëü¬æ°8Ä]’¶v®†rðÁŠzü=!"=ã÷gòu ’Þ[œœ^\T:®[[xfœ» Û¸Lw½½³VïYÏ€€4„£vâtRüˆÖ@L´¼M£9ÎP— wwø¸ÆÛ×92¨Œqk ‰hâ¯êŒ‰týá¦n¤¥%òç` Fí+Ÿàmï5ðc|²"ß°?•?3k½ÛM«³óŒá·yw¨ºõJ²ZÍô«Ù £'­& þ`‘©Díü€·èÁWÿ¹ÍÖ^“¤BŠÉbï’c99;Mæ+s4†–Snן.Ò7P­]\'áNÉÌã ÝJNÇvû™=°S w@^>Cq¡Ê¯é¶äŽW …$ÌÌET¸8Íkåíq¸™†4­ˆÐ~ÄNj¥ÿç ñãˆW[§DŸ¥d6ôÃ#_j) ÝH8JE²˜r/â)I)Ïa¶Töü—ž9ÉÚ™gj4ñ?j1aؘZ½Uú÷måÔùÎ&g«ò¦Dkt0½kž¸ ´»ßj7×7¯0R3©gÑ~ê­ãÛPŒÙ-w÷*Å0)ø|hí{`TÏ}¡‡^}‰E^éÀ(.›>Ks¹gx'„7£—‹¿ãB*PÉ/G’B?tY,¹±œé{ø¨3Ð+ÝÕnŸÄŸ¸±u ußÀ¯ÉU°“(»;—Ÿak…÷_Y* ÇÓ޼đ‡}³w©$EÁUËÆ£%£ÊãmŠÜU_R¢ùˆ–Xª+iœj-€ö:Y6´¥pÿÐ@âùÀAˆ3^˜œúzgV™Þi·—²tõÈðC¥“ÕOÜ£ñö˜x4"ùõËãªÇýMï–„s¡†ê5¶-5çëñ!âÊuhm¬kïþ±á !4'T¼ûDoiKp=ëöµõò€÷[îfWwwšˆ00ac³ÐÕš²u5.fÌ|¤“‚+5ø_9ŸüPùqœŒ”vuã†-7*0…ã{´í²‰FÖãsŸ<SÎèìú‰€wNÃß‚­;;.ØörÑËO®Ñ¥×WbFehëM®:<üú{ÂÞ*jHcÍ¡_ûkHo¨M5çå…¹& CÖ0¤˜ u@„ã¥ÖÛö»‡j%BTÛSà:ðù›‰SRV#ƒLï¤ÉÚ–ŠWØÞaÿä·Ó™qj\'`âJÁABtŵMË6 e¬Fnðá Úô²°£ONö[mù8™—´¥@_Ã+C”wÇ/Æž =¬x¡m“aÀßlŒE¯µöË)¶Ry×§M•ͤ¾±„µ‡dü­ŠÖ$Qû{Åç¨HšewwÁÒßá¡i¼}…Ãâ‹æÍOQ;^?MMç{·?xµ½c\Ý1‚Rg0þ&Ø¡Ï\E»* BnëpGâÐ]êuÒEÉ:h(‡•‹°Ù\¿T‚ˆER7—[6zì®ÃsÚ­nq(±:5ó´á—HuÍ4~¢ )+¼Wƒe‚ß™¡Á6oÖ¥¤Q¡øy¬Þ†Ï~µAð^¶2ñBI„ß VLª#s³‹#ûC§n ÞÁDìŠâapሾ¾†¿68‰JÓ:Íš×*ïŒ@!ïE?YèÚýšÞüU%á…¨ÕŒ±îÙí)ì1)ê0sÎØá x\þåUÐpj"Ê{‰ÔWE¢Ÿ P÷TvU†b4ǦÏ)g¢_¨Ø±­Ðy4®×óÇV³¬/¨·Z©Qô4˜¤‘ñB÷Æ=ôN„Y[»Ž]Ѧ闈ˆS¦^L §í)¿·ðiÆþ¸) · ý&~Ü$[måñ€:á~³Àù-}íèA8ªŒèq³ég2Ô¢(¼'—67¦äo›0È-ÙFPÈtÊ¿' q¤ÄEý‰Ä~ÄêÇXAÝ}D¤ãד „s]Not8KÑž»R)úÉö­S ŠÐÕ$f{糨U¾EŸ9ŠU¢Ñ€(!uáÆpTû7‰„7Ò%ðÛXF.ïéTÑú–ß¾Ð]dÙÜ™¡(3"bŸÃ5ƵÍufwak~ðI˜e‹Ñ´‰Ì7UEÝA±Øø2$¸§ð†;«Ýqù³pæÌ–1²~°¯Äùž•œúEUÌÑTÔèµm Êjj æ³+UÓËjð  ¾©«»+­x¾…1íu(Ê,}§òZùŽyFwÕ¡C†5„ïƒko“€+ï½äX²1©mMkÕ°ÏêTÓM¥°ç;ú7/Z©R°ûtGCXlée¯ÍjÒ T½§_2‹`nR²xÅOb¿[G“-iÈë;iò×wy¾Ï©õGä\-Fk3Ù·X¦ÓÉXþˆMѳÑhUªƒmo<ýÝø8óÄu ’KþH£ŽþéÒQ‡ì§úÎý›ŽGsÏ%ýÝ—˜÷«ÍìVç%ei^‡X·½‡KçÊE(>Œ)ÅSœfgA¤¥ó½#3þÍeüû|A£ŸÞ[àãiÈ”# 18FLj`KìB±Îc#|£ÎXÔìÇXY‚ –Ÿ‹ôç|ãñ£iu”JVΦa ×Ý'ðè­V7zÓ¼n²õWiS&œ°„&0Á\Ó%9ng»ñŸÊxÝJÑ‚NÜh Ëi4ø&žÃ)˯“ÜòX[vœ4òó= ú<7Ì6ó?s´¹(™…ÃÖïœ=NÒør²ë÷¤ï'Ðûùä=JV'@ Ÿg=óëXqj%å ‡î6u,ÞMÚ»„8ÛOë=>ñÖ‘5hkÊ3çCí½k þVp_ïAäëQäIèÅó“ ÌFV Z˜’­úÐñl{¶äDIè·ÆÛ ½ÙÚÌ÷iÎÎZBC~—ç:öD 壙•W—•vAXƒÏí„Ô*ŠáTšüè%B¿}B¬õÇ «žÅTX¿°^8xW;„ËÙÍl£ÂFó"Óžœ ñä’½‰hºH”Hl5O5å’Õñ¥ÆvºÍE“úá 9yñIL!æõ‹†¥š üúlŸæì67ÊEƒÏ7Ÿ§›d7x™Å­`UÀøõIL‹œ2ño²ó:Ää›ç'ŠE¤lQšjÏ'eÇRÉA†¢«ÎÍXÞl Ïv.%÷¬5ï+{µ™±‰]òh``*™üÆ•ãhí²Û[9®Ž‚#ˆX˜ÄÒÁ¿]}gi¾6,¡2 ¢ez¦=oD±µé?J[”wM—í)?Ѩïè8ô_µŸ“ãæ¦ÅÿÅ3‹ýkÄ\–‰D—cš·¸<¨/Є­K—]Kgkñõ©Ìôç‡Ëï›a«~…(õîÿ¤XNÎ=Ìý„ÏËPÞJK þ²=Ç^y›Ó”ÐÖ´wFóí1ê‡ÇR.éÇrk¿`L:S©r}žM>Xïúkà†qÿ ,Øza V(â镨¢Ò/ºpê{Gæ´þ=‰–Š ÷¡Ø˜Ë™§Ÿ°ÏôÝ…²i°l¦ ë>eœK銹'‹°3N—([ t*ÕW~0 ùªìDDU6¬éý…¨Oy”tjU¨NwAÇň¦ËI$²jÛ­€;ÿ®µß!„>é`o£Õ%/–Cì鋯û°üì1ÒGòŠ¢]ð[ÿýVt`š$ÓvM·”êÀO†ü–mŽ#‚½Ô{ÑûúÑvžA¿&øfI/˜Öù‡Yωû2݇©qÒs£´É6tKÐ"Ƙ ~£+ ’HÊÃÏ) ŠgŸ ýU…©®X»ºTÎkç€áø—ç'¯°?ð ý?lcs% Ó­cgâL8±mÛ¶mÛ¶mîØ¶=±‰míØç®Sõ|{ÿÀú¸V_]Õ½¾ºäFif¶<â=eXIR&Ý[ì7á·1oˆÉ`••Œ9v‚(.aFñ b‘­O\~È0Ì>Až‡ëÖêH àXYv¶•:È—Ö9ŽV®eÒKÐU›»8Ͱ øjâçµû8-–åvÿIÔ[ ™·”‚Ù­¯Þ›GSF~JífkzCM¡§å֙ϵ߮¶z€4¢ “ðœÒËX8x8ë5o¢Ûl‚Ž·ãBœ”O9ô›!ˤìið:RKŽ_¸!™½Ðb¶fFŸâÆ6Y ’}MÁÈØä)ö*^ò2ò¢ )¨<^X".úZìŠЀušGî†ËÀ2ý=¯T "Œôalvc,ÍE~•%õ¤Ôîåý«³Ñ⃾w£ù)a¦°w%üÁLù@Š6(Ê'Ž•ÂÑÈnI ô Åâg¡hRbqQD®8§6-68Ž¡k"#¨“ˆè«©}”ÂyU30[¢rÅMð¢õ‹4Ù­ð%Îc„$ nc×ruq‹h¡n”,7=âè Õ«æÝ'#å…ûÞºi%Mè3\¯_’¦^G5ŽJA3FT†º1"_$ÔŽŽ`hÖGª¯›!Õáp#³Ú“„†Ô1„€M-¾å²èæúI¶91ð·sÆx! ´ ï‘Ê(·ÌàVóÿÒ×€Œ>:™ï6 i¶-èì‹sœ„~f×kÅFΕÜFÅ]Óý5³b¿L(ƒ¼êµúKdzš~eWS0äéçÏR2x’_W"òËñ"ãÿràGNÍÈÙ™–AÏ©×n–ÿ¼Cg{ùM H¾¡=Â,üÙò:«%±4šo9»¹·j«‰ÞçÁngy<Hjµ‰±:Ñ$T•nÒEL9dy¡?·©c|¾\“£JÊD¡6Ü.ò+ÓM(]1\AÞa¿Ý¬¶ê õ)þS;ª‚nWY3LU@ÂÛ  (ï-UGóâCÄo·\|ãæ!©aa~rùn¡yQqKËÝeîý^:l8Ql¯²HrUžmí,ûVø×vçaOÕ[¥¬]>ôL’²°Ü²¹•÷ìõaôÁ?×lõ‚1„¤¹qŸjòé„áøñ 5h,y=©†’¢PÚ|{Œ~<Á6>1…=›‹˜µPÍv±\ùÓM´øÈ «?)‡$[!Y/¹âœƒ3wøà’;“],ØõXPÑgµxã­E·»3ÿÝØ›/‚g ;\äØ#Í®9YZú™ª g°#ílh„ |!ý‘ Ķæ¹CJ<îûÓºR¿ý<)uIaâ@þóá¯ucjŒ°Ý ¢€¡O-mr£ F)ˆpè,)\ÄLQF¡‘2Ëʽ@LçÐv…ÀâÒñÇÑ ‰[—ÖˆY¢­N1ð®0¡umÎ÷­-²DÔ«V&³p2øè®hõúíç¾µ­pqéHž—z}ZK¤a1{z¤š¬§L$eeNýâ³L#ÜÊáñÒ½²ZyÁåÂ\õ™e–?YDì7e¯šq ¶>và'pnjgam©-%­éø£ c+Â.u¯eÜIàøuÊ¢Y×Ùsu¦{‹Þåx?ÝGõvOhwá¿F<{/ø“4WÑÈôƒa©Â¿æêÛkýÄ«—ä×(›Hv+”(çÖ¬íßø]¨q[Úgç®f9û¤Õ#BAöÀtº: oW?>‰ù>`?ð´ñ~ͨµGSÞu|i6 ýä—ÂŒf-kvc§B­ñ“ïÉÚÿZ Çøq­yNø—Ò±Ÿ¶Þe¤0oàOGßÉÎ"8Sktݜڽ7öÄ-†K¢ XBmH‰èîÁ;¼Iµgéjé: ì¶°½±¥é¹}`¹:ÂêÁú`tOJ‰ 2q"D^®t]››XÇ‘¶>©aÀŠQjXžöqÓs9±yçýaG 6j¡~qE¿@Â] å-Û”>šls T&‚FäLzÓq‡B\Q`mzÀ©Ô¬ %.?ÙüqâÎW§ãžŽt]³×ð ^µ™]žÎŸ;0Û2õ“­ÕÔ÷Êòýº¬a:°«vVæ¨zŒH1…‚*Û‚¿#(Òê»îÐI¹ÕùÎ!M$Š$§¦¬iAþ|ã·3†˜Vcõ N“¶…þƒ$Ñ´ JíQ~åQtÉˬ3ÞW_ØûHdäaúðtU„©¡…ºÂÚúòí³p>1PD~@i¬“ÊÞçq.Æš/™·ì‡èQ;*âJÖ÷.Z7¢Ôòw5š'hÉW@E"L ÞÓÆòtÊ pþ‚ϩéjû”8âr`¢¢ã4Pü9•L[hÁ`Ò~¾šÁ˜áEàån|QD¿|¶Z¥CŽŸa¡Bq nMìÕ2Íñ¶Î—óNÛͧÿ $OzI<]ïSºãcJgФéô_9£1úxr$Xþƒ€þ3œgXlñ" ’â›FÑìC|K¿ªÛnb{2Zaý¶ùþå5˜æˆ¥U}X†g&>à?T'Îdѵ¥ÏO‘2ú«ö#Úu|ßGaÐ¥ ó{‹§ãŸ00¶‹8/ h{8ÆÏ’¸h©öÖ⳪‡×À¨ËãÇDoÇS¨HTŸßéwFéú­éAü}•ÛvhŠäŠZ|×þ5¯5›Í8šqï/9DsõqEÙ+pšy‰çÕÀ¸u¦ýœ¶QĹ$nšÊôêÇøÅ.¥onÖâ¼JŸ;Îø©ð…’¹, V»B¤]ïð̶yè4¯ÎCˆÏ.Oe„¤dÌ«Õ9²¬ÎªÇÿx(b(;Ñ:t¦l4jHáÀIêÑÚÙlc\‚YÔ³á0@ ~*Q×Hs J4ó|_MoB¢¤VtŸE(žóE}‡Ôð[nò9˜›¯þÉÇJ­j,ƒ2íFwáÊ &å&‚Á¸Œ˜fã™ÆþtÖ“Íá³ë€oc-{=,[†?÷¶èÃëqHøðaÏŒA»Ä÷+ÍêxË8pS®Ô2淼ػ%ÃÍÆ‰ÝuÅ7'?UÍ¥PÑ{FäüÍ® 3ÜÁU°9_Å)²S –ÅCrþè–Ÿ™eNŽž,lC3x\zdÊ",M-f³…·Û‚A9¡àw@ýd­b&: ÚkH˜UÖw« %,n„V;:ñÄê!š‡ô‚D0¹¾W«Ð™í{½z†6Õ¥¬ÂpqÚÁùí]³¥öN9˜ãéFÙ!<ÊÃgN}NL¼¢¸@®%ÝH…€Ÿó‡6s®oc¡Ã;n 5»Å¥è*:8Ÿ“Ù4e0Mf»•‡‡„ö£À"¶Â Tj×–/VvuqK{o`¸»bæ8( ©‚…[û@2ö4ìÖ§ bo 5Š=MËÔ†t:ñVºþ^ØÑžãoè?&ŽqÑ‘gVl妯[q‰{ n¦qX*îþW±#õöΰ×Ö¿'³rÕë£ËA“tõÛå{Ь#ŠÓ -#L,Pï+“bÃ]®òÑ·Üy#Þ^kyçϨ^n‡Ãq¢¯±`CDV¨á©øf¸„*3c¹ªÎˆÅw/Õ/V:Öw¨îÎ9² q#5‚,£ÒÎt/MoØàÛ–iæ†íu™Èÿ›Íõ÷؆v›±ìîöýo}fg ¶Éj@ŸÌŽ÷Œ3 \OžþPM¼áÎß6`îÃûÍd¯ Ô¬L°§@µ…£¤ñWƒ—R|¼<ÓIO}‹ò£»-: cv|3:á3ƒq[m5]î<,ÓtkîìqÎÉ ¿'gåïtHÜíÑJ-ú¯¢Žô€§!¹†üÅߎìXíiH'…ßpC-8€Þ)D©h¡(¶ø¿yä¬ç [>ô‰3z>oœ>0þÅ:¾åþ©À%‹F'ôH¯ø*;Â^R_̸rWkQÙŸWbÿ—b¹½>ss﮿,ÔR-͵Êÿ‘™(@9î=¹Š7(˜†”K£üÄù´¡¨2óžµ]˜ ý1u­¥í’Åi×#åÞçû ÚøY-Oïñ«Ûî,hßg†Pj%†Õƒ§ØÅEÎʹ^±³9ÛŠ‹ðjC³Ø ¬Maì.>KRl•;o"JÄLb,aÎÛ²DZ—šéÕ—¦nßç1þ;VƒÄq É+ÄÍ}#=·éÚŸÞE}Uî/ú['|ˆ‡:©ì&~§•ë1·[šŠb¯Ð8;¢cŽÛ’cÇÀ¼ÓǰUÖ œ3P#ÜÙãñ^%ÞÇóí8ˆí€iOXÁqé~k )[ ­ œ[DObWÿÌèhN †ÎItÍjE]jïw‚ÑÑK€<=FÙD¿K´@pìòÞàÓ‘SÄ¡;¤‡£kúuªÚGå&€¶ÓXù×¹¥Æ×âyokQ^ð]ÌEöo8 2¼î5'ÕûU;ÉiÉþ¢TãÀ1&ÆMûfóyvvº±¿NiRjÄI´ÈH‘¡mû·D„“jãÊ„õôFŽŽ|/}SÕ|Èý¾˜õBG‹ã:–žê<7ð³ï-œD¡Î5ºcuÉ Ù~ô2¸·³,ëß·ÕóÉH‚òÆITˆ•‡œôž‰[¹Êú–œC¦«ºfeV^Î~ÏÈ_xôFôÜ‹DsßUxÖÉáù¶Œã%4&¤õÌañèvP Ã{¥94mÏ#[ÕÜcÄKAéž…æ©íñhÉ= æãû|dsòg­ö%Ü]]Jû†-m)õhL~mŸÅ ˆf U]•¨ÍÛçîéVL‚3Á‰¬TÕ0!'¡ø‡•Ð=ÐÕ‚JèM¹Tþ²6èH¦üs™•ØJ™ú¾=VüSìF©ÓýCÎ(?ô‚ÆdÎ'§©uÏBqãÐÊ»“+—.ðáu:œÂZlF3«N¤Kx®Ø)ReMêYÂjsÎöE"êòp‹¹«•ÿýå&8“,¤LÛ]ÛÚ®·2Ò:ÅP½¨”jyßê&FðÐfíe¦2¸û?Éâx•íá_eŒë,Ëÿ[@kf1Ò»Å)t·^¶¬Åˆ²´Reö³á'e–A %„ço ½xßþ„ ¸ ñkᵜãð7b³õORc‘^{ÕÿÆñzÔú5]ÕØqÌ‰ŠÆârùxÔohü³*§i=Qûsä DT¦›ô sAça–¡»mqhËÆ¥g7öèòħÊþ¾©o§°÷–\öºíýàŠ×Rupav£÷«sàø,Ñò^³±ö›{5ü;YÔ¹V0ÌWdPû”5ªtàý¨Øåˆi£`(<¦u€¥ft¢=¬û¯Tž+ì ù­Ô@±CjmkíAÈ=b¼×Ì¥G8×s-9Ň"qDëÌ}G‹Îß zPØD»ÅÂwVÍ¥€ØÅ3¥T÷=U`x L˜‹ZÿóÚY;Ì-þqê@{ krŸõóWYUDe…~•õȧܶ7ÊùƒCxe%‚ÎgÔN²„ÿ$g3ê}ØPbžå>Täs!$~gf&¥‹Ñ );UXÊ0gþÛëîá“c?E6>î—Øÿ BéZ\¼sŒy<ÎŽm›Ó¶}tžÈÙ“#†EŸ¿STlb4¹£w䔸/¸}Áç°yoÞÒhu—§1.}È•G.²Ý’dHô,û‡¯ÿ“+¦f—uã :ÙœÒÒ S”6 íó{¡†•—iç{,¼Ð³X›,’7ڳˆ^OÀȯ!³›a3‹ÿɸêõwV=Ž`UCç…gæê@@|j£$HbÀ)%UPÀÏö¢÷ 9p¸îÑ–àn{uûÛ„!ØÀ÷t-µx™+2/=BîuíËcþq<;HIîz ½ ¶ AçO¤m%l̪~ì±^Ãɯ{_Ì›Zܹi·vx©#—á,!TŸwKéšæ"‘÷ßáŽ3ˆ$ª–9ê•zT–q‰õ‹S$‰Àì³ÄZ‰±VmúND4ÜŸ‹¸á_ÿÔ!n5FÎLÙO\㈜VìçÖÙ b¦~8ì¯1˜,$ÈC'~ïÿû¶zû»¸¶-ƒŸ™›:½½®ýÄËÔ€›FøZ'+Tl°‘ùŒ “5R³ôQw¦œ€,`6æ /´¾ªP+ÕÁ*`,Oúl2~ú8l<7Ê­7Ÿ‹süKB±G¢ëwȧ xÛß~©'"è›Ãm@º©J¿4´âDœåʈ–°.I2œ?•ê-xiMbC1ÖüÌœpwÂÀ›¯â8àÿR:@zш0Lˆ\ü2QÃX¥'vÞëI§è#­þ‚ãuûÿtáH›*ôõæ927qáše¨èþ`üð’8–ÌŒG çs6‡ésèרÖÇ®ËãQ®2n]ŒIЄËû…-**l³ÆQ]¾©@p™š'Èô”‹-}¤â\Z›5x®çXþÈ ¯ü¤zô¡.ªÈ­.UÇ0á¥W$Ÿ?œl]±!©&Yßo…¢VrZÍüÂþvŽ›ç®æ«lc¼é¢õÐ.ªhÙÂà˜öþ.ÐÙV³Â©Î/°+»‰IèV}Qçn}Bœ\Ç\-CPú àôÀ£ ÃQ„ŽÍÜÙ$Uq¤ô ÊȨ*uï)âÀ|ÜþM¸PoBsÁ÷ë¾kaó0Ï3“GH[—6ö¶DÖndãéy‡‚B¬ÙhTòõ“«‚#þ’dÜ1èÏŒÔ9`oaÎ~Íß>§zQÁ&l×—·~³ oŒù¦‹gàF†‘“e'Ê…0JìëèS`ÖÆÈ7YXj°=j==d ’[óOÞctl.?x3¯k<#¬Ú1._±¢¸ðQ´Ñ¹NTHÓø‡ñJR¿>ø[û™*Éð ùºÆ„’Ï©z ã¢J_m@h&†­¯»Û¡ó<.4è•+µMTh. ©%ë ØP‘ì°–hOG„ÇIèb4èv«’ÖK\Zò¦ýå? !+„Þ“#e³¹ƒh yɳ/1D•Ðk?Ù¸"`— ´F¦XÏž¥²[Z Rx/ÆP%¾³ ïÀÅ´¢êÒf˜Ík»%‡¨|ÐÑë?¸¨ý:°‹Hl•°uã$¹T¿R,·é×/Û®Ë[Ú2Ÿú??«Öé©fZ_ëÁ”kËn™¯Ð|-n7qÿµ†Y$ êß’¿Rz(ûVnÂîs¶±h» w1ïxóp†Åö\Έ¬/À¯å™‡n¨{à¡…¹w9g%hÏ¿]2 JàýÎŒ-•$b}Εóc­W« $!öUÂc…AþVŒ|ûVhü ^›MÝ5 øþ›¿ìXbÁF iÌÝù-Žk®~!û¾¯³ ò¼æi †Q’ñCäÂÊ?~d{m¶E»fÅb_Å6®£G:`Sð:;f:Ñ™ôì!í,¦fOî×>Õ]-æ"}ö´ZÔ}±©Ã *—"ì·ÒŠè›¼gªIYb¤ñ“ÐC öIBYþwÚ  ¿¸<$6çS ¾åˆª™"©¯–ÐÎ;1\Á_^ïËØý“-²eë-¥ì߈ÿ#Aäè=ýGìh©tݳ¼×¶Z«£Ö´¨–ºÍCnƒ ^‹PSÍ«‹† º]-˜'¾¼]aQzðúAî.åÀ’ä~ÙªÖÖR¿£Ürg‰Ø†µUÌß^_óŒŽ4šÐ>ðz$~%"*Þ'Ýì¹æòD²€¤ÞÅÆñ!)]ñQL°–Æ è„ô¤3ñµl¼-l:Ø 1ÝF¦"Øw`ô#Þ í•ûž“½GÁPG8¤tÊ‹L.&‰XØ¡ À«{CÏ×üÀ’“z×§xå áeàaÄí‡kò]¯ ά:öÕí~ëEãpU|qCH¶6i“.Uö¶¸õ¥à md%»ÕfèÐ¥A`¯d* ´¿-w”åw,5 6ùÏ:¬“ ò ‰;ðܱY,Ë`°Î!5Ù`ÂR*òˆ ç®n`RUXidiV³«ÌœŸŸß\UѺ«Bgº vJàÙéLû‚´¦bnöò"“Ñe¬× úƒ°·`RÙy¼åKÄô©yD'e¿Ümêaê/)¹X'm&%¸èó)—× î/dÊèo2[$ŒKátç×e@¡«î;G׈ôÀS `'Yó ÇôÃ73¨±“¶Ì!ä<@qŒeï(ÿëÌ.X„^b’D8m¹øÒBÌ,ve’àr‚íIct™éê ¥¢NǘµRŸx³™-¼)Xt1É»¿I„ Ö]y¸[رÄ{µbzœƒý6t¦²¸å™0~LñLÿ"B’(Ç©í‡ñÄÜ6î¢Ö§Ë€)¬yO/Ƴ¼ÕyŠ´S=:Ryq±éq¬Ò˜© Åê@5,®ß­§døEªœtWYrƒsÔ w” þá–i/‚4Lo'Ây£™†3f¨â³§gC|ñ¼¦j â‹\…;³¥Ae. ßÊŠ•v•‹X, Å’Hz:ðƒnÕ#ŒKr®øQ26ÄÏ?¼ÓÓ^à÷EÚ5§ýLb’¿¤D°¾ð†o0«¢?ç±ÔKºÖ€+×Ú †QD./ý‰"èÐt¹¿XL‚йð“êStUá@=Þ_×ûrfýÇÛ3MUáZËf‚f«nÎ`$Åò?f¢†a¬)KŠ ¿Ñ#Ú\’êLñ¶LQ#ÛQ01V¸QN5åð"õïågAÐÖ.G;–1ïuÉ’/¸²Á/!æ¬Vß$çG&ÿùHÐìò¯g&R1È"#ÂTAqòåôB84޳ÂIûAiMX}íÞ­ÉæÇ-\XjÂLr#†ç“‹ëõRPáx×¢Ÿ‹¥xóízÄæäATvÖï–Ù»œ´¿«íuõU†ï¯ñ¡¸Uãz£?ìxäòqFMKo(–ÿR4µÊ¢ìf½%Ð.›³$þH‘ìEB²Ÿ |â?¿òqÙHæèVÕ4ôëåû :ïÝ øo’´ÔÈÃ<µ oàúÅ ‘OÖG›ZA´´„'îþb(Ê ù¯ñ½0Šaë}]£Kƒ³õé-šð’PWØ!cÌ(´öˉ} Ó=´—r4*PË-Bl¦šÊâê9³Ø0b‹g]Ô8DÂQƒíÆ $5iô2ß`µ+Y­\à„ h¤abhºæràOMƬm›— ˆ«}ìEcUÍ÷ª†ó³ž}L©$¿ÓÁE«jÜM¶YU“Òµ«!Њ]*÷¶gíš@B-8ˆâ©f²&‚ÛŠC—TµrÕuëJBoi Q¹ ¥ÖF™í@>z¥Ü&þè…#ko¯•Š•HÙ¨KÂb›)¸q›ó j݆2)eðWöž}„H0îç‰â (W®ä~„iœ…]e$nmÞÓ™@:’ÌrÖ¤[*:®‚µ»6I=ôƒt’,ÕB+ÛM„ }†ÿv FNí³­DRT ÿÝ@y2z‰“À€æÍe\ ”’3Á´Ú[tz!Œuú`ô"`‹ªxâÁ’Å;t”ý·ät¡I­ª=¨Àˆ ʳ9ûN˜I M¨Ÿ‰£h>‰=vf_|wb%D€áÆÎ¾)ð#? =t¡7Oº¬­´&Ø\iïÝ^-¢ÊO°ž;É/oîìwðüçÄ.êÆ>r!¹µ¿/Ž®OvÛ~µ+–ìj.8? Ò·&€÷?Õ]a5‰­‚ɠц`Óýb1#ó >§wû2íâWí®!E!˜lgÕÄ;Þ}uf~³þë-ôgФ ›` y™=Ewü"z“Ç¡E?i)äû`ê\ÝpN~I | VÁýãë£aCÝ#ƒÝ;½€{jÏ!8>ÍTo²µX̪z##¥Æú:TËCág,o­xõRö´.üî_ôÅp(y&-¦×?—w…ÿY«¶‰>þD…ûçÉF5ölÜÂ|x'´/E#Øò®­ª=‚ljU>j;Ó…,ÿw<.HKw}³>61c‡ïEI˜3ƒúù}ƒÖëø:¼¡1„Ó/¹Ìß Xã‰(–âÏW n2d$û[úÔ§h…­ÿ‹RfƒZí–ID¨= (›¶ß Û-bf^XA ¿´.áBÙª<‹1Q„&ºéâÚˆ¿·K5—äð w=t5*Ç ^¸Í}:ÀÑ/¬ÒîúÒ€esBáô¹M¬øEÍY¦$ñ‘?Ñ«:ÎÉ4Y ‘ vÊÌ^ÃPx¤ë.ýŸ!š#6©4hÎõ¥Fl}]›6Õý’`ÖŽAŠŠšdÒès’â£Ïšné¹”“QÛôÝÌj´ïÈÏžK|§ŒL%6d{}‚&J¢•U{ý¬;yýA ~7Ak4Ý›`‹VÃü|!¨ÕÔs›i.2ó~Áb—\°½2VÂB’{õ‘%$âÀ+¢£F¶_L麙sL`JÓ ¨•NY‰°»±ZIc‰q%”S‡ÕmU£÷l)’øù€ïmŒc… ªj,AË‘±ÝãµZÍÏ&ÒÍ´—º*¥_drâæxŸ c>V&^|_ËñØ©̪֩œFO(áh’ý¥}I'ÑÀϦãæïÊWþrN|¿®©û»ÃŒá¬XÔDgï<*ÃQ˜ó›tŸ´Ûî~–{Gƪò†¢ÙopCT…EYÃÍxA6å!íô¤(’áXܘÉûט­kןkq¸Õ2Ì–§ÆÏvC4åHw椌îõ¢ºÖ@]:ñYžƒÀ· Uý0eƒsãÅý)Èb›yý¶–ƒyÚžùbÝ’^f{¸Î8Â×–W¨Ž´½ 4Ü.r¦ÖuW:!UÊ•–ñ ™Æ™‹(÷'âñ¨*É`¿ JDöÕL}Mñ…ÿ iv{Ï[ŠêƒB*®§ù-ü®¶*;ЉXî­ÉŠ­›v ­ð=Í–Ú|ß´”Œ­þ¼TèülŒ-¨çœ+í&+z 6gY²_²OWä¨P£ÎÈà¿Ôí¯R¤YÒÆ³”c¸jËNÐhóAEë9œ5&0·k»Jþçxõ>7„lŸ¹7äkšU5÷ã&8¶ø¯²Ö^?Xoa\ƒQž~±زlìì"<1„ÅFzuT·•=Hü:]¾Üh"·’Ë™Í1gD7¿l÷Ä<ø† ÇW»Ýܾt¬×øž‘¼G{1ã— YÚ°³ÊÕÛÏ#c0"yòÀœ¥š%¹§Ööm3FJïŧd è· ˜U$z ÔŠA¦è7žš¥#³ùÔ69ùTkXVÐóÚÂ{‰¾¿6Âçàè/þ'd¢¦â¢Þ¸’•…ãñéé+ºïIœŽÑ´R]ÎÝx8>äYR‹BV„mç×<t¶÷šîÎ8Ï/ÙÝž>ä)vÝE›/›/”C‚~a›>Épê*…Éÿh$±¿sÏu¶ÆRïÈŠ¡éèàmÓ2œ2 ±ì¯}_üÚ³*Rz\¶í;§iÞF!’åÔ!ý­®þÕò{²ÍÐŽ‚Ó\Áæ_¸p½ãñu™ö ºcXÜ,m»™ åøAöt!Ònùu³äQ%47^ærØG4‹Oƒ!oíésÈ ÆºyÉÓ0~ét<õh•!™Ly$`d‘^ÄCîH&ÚÝîówÂ_nl³“ÊFØ7|‹u¬c} ÒÂßvµõH –,üÑXÄ[‰ºNćÜÊ+Âhd2ÌNø9(är.m%>ÁŽùM‘/ð™˜WtÆüç‹wˆ&¥·f$°ôš¥µk }jO—·P-‹­Æ²åu¥¿MBÛM·³ËS¥ü/N¬‹2¤9ýï wÂKìLq®‘<s?ñÒziçÝ£_½w¤Tç÷Iª†L–å_û:e‰øÎ´¸>@¿«u¤„#šË¸BÁÒC'Åw×­9ö¢tÞDI„``k²LTýÙv<–h#ñ'힢T÷Ø2–äâ‚-E¶ãC¶ƒX­ZžA£.”žµ.¿Õ,ûc ãá>.Ga þ\Œ¦çϲ“Ý8ªPCë–3LdÓ2n5ʶªØñUºÉš[y-³Y†¨V•ùv/,¹n„¿¶e.ý÷˜°ótKSî^ÂB­e¾z­èúˆ_ÂÏýU÷ŒU48pmÔÃó˜ëCØõp h’åƒdψ6Á—ëš½‰fÍ Yùëê`•´ ôæ%p¶z}B³[ê\ôÔy°?Zlõ :ÖyËÂ0˜I×ÒÇâ/ài²jQ3ë 8üØyæW¿®©Ì¥ò¬av6n3“äÊoQ=×€Y͉ëIÆ!óµ÷e–¯¶§'*%ÓwŸzÐ/ è¨Va蘩~B¢Y&§<çâ"ÇØ\}IehÛà9ZAÅÊlÒé¤k•‹ã4¼¬˪”žv1ÏØGƒ›GÛ1ùÜ×qú¡ò õ6» ¹|!g æ™­Œ,û¸5¥âŒðm<1jõœ_Ň£*°ÆoáO©÷>Èݨ $~âÍQ¾ Å6W•!°:rîÞ@þ“;±ûIŽC cåm1rl 4À>|g‰Å³¦ãÚo¿WÙ Ñp±ÿæµ­6¥c…ÚL|@IÓ£ÀTR•Us0Øæ”i–\炜-®ßZ%BB€V` Cc®³—>.>Å ,#ˆ¼o&ß°ùÃïQšhéý¥; ÊVD– ïÚŒr‹2mf)ñÝ}Š>rq(i5_«©Âmíšù0ÁNœ\ç Jr>?vŠ’ $†ñÙ™€Ùäª,0a,¶˜G”WÄ¥jË;\E”Ô–Ïh>R ŸÿêãÁùÇîì‡ñ¥ö%*DÀgjþµ‘Ô 5v¾¿#ºÇhÑ èm¿ËkNð­°ÍÚh¸¨[î%®Ä‹üìóWË•ýVбN]¦«àNû©ÓY–÷œb‡åN9_U¥ u Û®üG›Ò¢N”…_I²F[uîòŸ5V¼×éë'ÈÀ‚Âߘ¸xieé* ö+ñ:²hc΋°^KÏGCËuª¹¡µüq¶ï`Û¶/ÇA, mGëÓSaYgÊÿÍmVÙ2ô@¼Á#Æúz‹MNsx²GÂäX–¢&Ë­+ØïR‚ÿì'é @îCÇõ`°Âý”$  õÿƒ/4à.(•Å#̲^NÀ0j ¤úEáHóÊUà€opÍ;ñs=Üd¿$ FB$‡÷»,ïW;•HOð&&¿ã;¬n‹K);‹ÀÔÍp)}ÍÞþß<Ýÿ Cº ©uB"ÉÕ`ðf*ÿ!ã>Є ý÷?ÝÏb|0ÀG®T®r¨TÔ*aÀ?q_7ç]»_¸›KC§ð¨ù*=LG¼>Çzבã þƒE”™;Ä­dÚß&˜1bÏ7}èf˜E?ЪšM¬ˆ[CúG<Ž.OŸwBÿÿ8£3NÔ9=ýϳ:ì¯úcÜYVïPŽÛú¼!МœÝÜq ¢:‘FºÄÊœœf¼”<õ¯ÇPÛdf¹žä|8èÇ It6s¢Ïhõ]L`i¦ØºL2 ¢ÃÀ2„‡ÞUxÓG†Ùö7 í-3ïGÝS”¼¨‘Äu¦îÑÜãr’ËÎï f˜Nø¶Sо9àRŒN ‚BÙGÂæ•$»1vQsù>žõÑ’ÚK#ÇcÜéÜA.k¤¤þVÔ Ñ)øð |ëèÿø î—ù'/@ïéuþêN¸U³»3Â4ŠÖ©J·péúÍñbVBS„R§â‰uE¡ämÓ÷¼4ý_ä*晆­0w)¹UÍßVË.ž’àùóÙ4Ÿüü€7 ¤û;ꨖ£ÝÇ3­~.»:„qÉ&ˆh=*à­5…ÛC–澌Ú-"¤Áäs†®àRXôÈH0­Ûj6à™°3Fê4<Ƈ>9YM|^ØðCiÚúêúPmE$ù¨Ÿÿ~ö8“%?›ˆú©Hwé1ÍY(Åi,_á3cú¦±I*Ë-”™52›z ôÍ2A€³ì})B/ qü׫Éw^òH™à+J:®cQU5 \œùšŽcÁ5D° xN'´òPAËgBlHÎ(¿]uÎÀ>` Ç9à¶s8=(‚æn bkÉ ó°þ³øôWpöûfåzŸK§HTv@ü'†²*U­é•×9߶ߘØl€’¸çʪ;Æ“þð{ÐE$ Él[ì þ„Úº,ûüE±¿¡Ú®\WÃâÁ-F:âÚãA&½xBG¡É„ت…07ŸoÛÝ¢úœ‘¸ÀJ­@Du®-áT.ǽ¿:É*q•gD‹B+½{YðQýE-jÉ÷V*ß ‡³†îi–lCÎ;¸¬#‡âÆ{$IŸ[Ú8ÃR(P{s®^6Q; ± ži*Ì©_XGö— >" #áÁdÈ(´È SÖ¬y0ÅHô))2]ì71îõ›ržÄ2’.]ì;çÐ;7ÛM;W›§²ä“’WL2Žv]=Ù²® PžE£ >HßMá·¾O56UD!žYºÑX;#V²íök¯ÓÇ ×ߨ\çIøéùwßÃÔü“¿rP¿ï©Ò“Ì7©lÒÀ]‰0O’ïˆp2)k`[<Ó-¨gg¤‡Ì‡P-³Òõ·ã@¶ù ²ƒ"xM¸®UýCÕ ÐæfpÆ3îÞtÛÈiZ鑜†töqÒ„Ã8WPïbÏA:½hJñ…Éöü^ üö Œá¬#¦)5?y?³e07™gTsÈÉscB~y°Õ’ýæïÍ Y£X…ùÂa“Fkžiò˜[40Å€Ñù1‡.;ø«Ø_^ ·ôš£0±y ™„kò'ÏÉí[EI–ÍëÀé³WÇä2§Žã¦[U,ÿÆùçøL„ >бÓ0 )«gu"Ç[ËÇ©a1¬'ÊNÂS; øöcø9å9¢åÕÌP’1à"Ÿ‘x)€¤¿6¯íà $Ú¡lÔ.9gÁ’ù!M©#™¨ðŽÏ”šäPÎx­6/È=›nŽÜ Xͪv¸ý$w3 ‘½Ïùƒ‚‹2>ŽP>(¼VßcŸÒ“`³yÀ<¢¹ûfm[«ïnñ…ƒ“}“§¼‡áÁÉŽ›u²ïƤoÈÿ|›+=ڬܔ"¨<ï(wP?T’Wñu„=²Ù­²FøVrGÕÇd 7"t¬1< gQ²³¢Éµ $Õÿù÷LJ¼|@'’nKQÙÚšSÍõ{>®¾ådçô¨ÝfÉéU!+ÀèÖÐSðEÚSeТ¬Þt·8ˆ¬T²[U 8 †„L‚wäÿTý¢¥]¨"YqTù‹b3ËðÙøÊ b½@Ø•K2ŠÞuèv`/Ú;ú’©ŒJà!ãkTùÔ{•ÆNœÿøJGÜB¾ð!Î!¹Nþ‰íòd@tE ²´hΫh$ÑJ‹Ü¿9çšsÔ*¸ala¡t× Wܹ…i#7Î~çdúi:=û¹ ëbŘæ8_òN€¨yS]£ËÊm±clÏa&J¹Uéil‚qpR÷±)*PËð_c “usjØüVƒõëpS¿«Ð¿a…Ë‘Îìîù}CDÊÓüGÔ÷®7OuR&þ Ç~-Ú(§üfÈLÃ?ÆÊ’ ž#v*´ç’mhv¤ì‘E1°ÐR¨!¬Ë¼dÊHVºw=‘Æ,˜Ba´« Z85 펂$ÿv0CîT¶Ou°~’xìßÕÆ)-­vÝØÇŒr$X@˜-u«üF?vN2”&UG©Ä¦P™KoLLîIͦZ®AMEŒ6ƒ’8Âm¡I¿ ‡M4šx»/¤S¹ˆMnÖlvH4 ëYêá(aB6Ū‚ FŠèüz£¿ ¶ !GÄÞüå-%gø¹Á>î‰Å,=s\{;ßIœ.K¶Ì¯ÿö4t¹kž©ÂVýWxv Yþ´†öðLÎé×/hæ½6á8Ì~9g2ê€eÐ@=L|A­ñ3Ê@N æëüJ²P¥Ž¸ÀŠ÷ Øàø2*E‰¾‡-i"Ω9˜Ú>K*ÛC 9·öæù­æ!—îï(ÿ¬R¢÷r¨,_óû|÷ÿ»Dýªüÿ„9>Á]r˜}ðÒê£%·JC¸Õ˪u›ix =„ÙbXQ_>…i¿ÿΘE¯½& ÿ2U¡açÍ‚².£·ö×lÈFKãù^Z™»nj  uÊäší¢ ïºZW×a®=5iþXNË¢!o¼»Þ¬F ìõ"ÎLøÑa* Y„õ÷¸°¡uiÐXÓá³þètÛÖÏ®ëË"že„é¯ßþeÇæÝGʰå‰ j6—‘»S?uܨ¯Šî0gàa;ê¢Äk…J&ç­e.m^uKš¡MÐâ–gÑÚÂÛ’&:ï> stream xÚÌúuTÜ[Ò ã.Á·àîî܃5î»—àwBpw îî$Á‚{€ÛÉ™™sÞùf­ïþy«é~ªvÕ®§ªví_/ &WUg3w4J;:¸2±1³ò4€:2^.@  ‹=Ä$çjbgm`gfeåD¢¦–pš¸Z;:Hš¸ù<®V3W°¹ €••‰ tº€•æS/€ÐÕDÃË È 3ùTA®L¦& °è`ií¤›H8:y¹X[Z¹þöÁÍôÛÀÂÑåw €ß‘€ž®@xWÐo§âÌy3[G­5ÀÄÁ Ï¬Ä Pvô ­tŽS •‰ÀÑâ Mu)5u€ŒšŠ¦ª:=3@Ëèê`¦˜Y™¸˜˜¹]@ xsó¿â–5qhXÁ/+fpˆênNNŽ.ÿb%¡®¡)ó )¦¬!j½Èhªk¼(k€…4¿ƒÈ9˜[›ü6W’ÒÓÐU•bcù À¼§õïHÿ‹ ˜ ào6`S Gû?è¬\]øYX<<<˜-Ý@®ÌŽ.–ÌNvô¿7а²spt±€ß]€vÀ?)vs0ÆLäƒß%(Z›s üC ü£TS–“–R×`g‹éw™þª=³«§ë.jRb’JRÿKý;@k; èO½~û2ÙÚÄ Þì/=¸âàˆÀ›ºþ‡5¸0®¿¶û+;úßôX,ÀQƒXþµÄò› “´Š²“¢œ„”²ºÔŸ(]þvàêfùÛöÿ•áÿI• èOÈŠªªŠ{kp×™8˜ãs5qu(þÈÀ/ 9Å_I$Ü\\~SSú·Êå?ìþ]qG0;?ÿn\7÷?êýKinxk+è/ÀeÚ,×ÖÚáÿí~üv)&©>«\¬vð‹|Š¥Ì%ííÁƒ~w…¤5¸B®Ž.^,ÿóðÛ:8z8øüo…µƒùïLÌÝœX4¬Ý€r’ÿ²‹þ–Y]¬ 3ø8›Y±üÞöÏaø-fû-gÄÏÇÉÑ `abúY[ÁoH> wp›º¸ý|þ©ø¿‰`nmæ >úà©‚ôÇ»œƒ…#€ï/18’«þÕ„t&=xœ™;:Øy׉EÙÑÜ.tÿ_Hÿµ´›2ØÝÿ*Я5±·¶óúÿ]ý_Ë´¿éÓ);ºØ›Øý—Î$mí 4Wµv5³ú«VÉÿÚOÌÁÒ`bãúK¨ù{ÙÏxò[ÿ¾8À*VÖÿÒ[ÞÌÖ¸¹ÿ¨€à$þWÜà‚þŽÀ"®¢¡ ,Çø?›ñÏR)3GskKp·sL\\L¼XÁÆÎÅðaŸs çŸ°0;8º‚MNn®~¿ Œô»M¸ù,R¿E€Eæ?ˆ—À¢ú7â°¨ÿ8,#n‹ÖßìS÷?ˆÀbò7â°˜þÀ+Íþƒ~§ŠÅü ðÀbñ7dÛZXÿsqü†îÿ\–Xþ‚#¶úää#/'+ Ã?V€eÖÿ€`R6ÿ€`¶ÿ€`"vÿ€àhìÿ†l`&ÿðÌfâø÷Þൎÿˆ” ÌÌéo5ØÖÉ©ÀÖ‘O€Yɘî —ÌûF) j ̤)rT”å7ôO r(Ñ¡ű{ÙlM®œº6'ºkâ¯äO„&%6–«Å¬œ©´ø¥‹‚þP>·@·”s6³-¡ 9v$Á×ÑýË>ùŠq™Jað¥m=Ö£xž­ÛÅÓsù a'Ñòt'¤ëëv|ŒÉW±†9ã‚0Ü1y8§Þn¬ƒœ¶Âßìæ‚¥ðóËÛ-zJMÎ1¨^·dÌJJ¸mW! yˆc³/4Á.Hðºç†Es‘ œ'Sï„î^uÛT caür¾<#ŒÇJ‚4†Ä7ñ&DýÅ ÂZXÈ3¦Iž<z™C5ð-Ãvz*ÉÉ.Ûº)*·úÎ)õC&÷-΋©ìZ‘d/*'ø ÙB¹–‰FC ^h)·D§™ßä$~º48Fõоî0D»'QíÆœ º/ZGMaø«»ðq;L’ >횉G{‡ôR/±‡«5aÙfˆ^€F(…zh`Ã6"ka†#ØùZ_…yÆ¥ÄfL¿ÄBŸÓóʼnú‰K·}ys¾âl'ˆýÝñþâµ}®5zÁï-??Μ8§ÿѽNw¤z{¥ à†~ï“Tš.\¸ï»ï(þHk&ÕF1­VÆ»VpߊÑÞs Zcò3¡*•+å¬D/2T!ÎÐáŸðNE÷¨ôñÖ 2ã¾ÁÈÍ®/kKy® ªkÁ²6RêÒp‰ú$†­ókÝ?| Î;ð‹&×ä¸Yì:qI¡+²kÓìc~#CÓ@âï7Ð6êN¬$Øúõž˜f8>ü]IjCQéóeb,†o>AÇ9‘Òûâ„ÂñöCŸéª€ÎQûb¶{ŠWóÃÕ®r­9í¤ÑÉ_ûeºAÝ1ϳœÀw%!v0¬e½­ˆH¸°H‰Ã_;5…¤g:à ³7ÁÍiˆfhç–Y<¬‚÷mŸr¯)d£°Ø…;;ÄM ì-sæ—"ëæ^ #ª= Ú¾‰çBêe°f/<°oœ:?dq>âXxj¿Õ?~ÞL#ÙMDˆ¢G‘¯çƒß†ê#%Ï,tÖËýuÇŠÇIåÚߣðÝàõW?V#Œ‡PG¢Œªò½doÅ3ëî`ùjyMÈí¥ÈC_ªì¼#­X}Y¶ÒϪÏŸÞ>öDe>2AÈ .è"Tq…›…(ð=L­ æn,}"šXͳӠò™‰öÆTBH6)d¶ßE‰O¨ÿDtü¦–¼äª08,ÞÓ¿ØÎ0ó);jìöºÈˆÅ½—u®ÅGç„‚–dè৺Y±U³Ú1!…·óÍ[eôþ9Cy* ¶âhHéØz.L!,Šcž}[¹±Á+‡¹’V%^õy\ïW—­Ÿ~¹AóJÕ—2ËHâ“ ¤öÜFŸøŠ¤@œ¾}ì]n²œUË©R©š>K}²¨ˆ‚‘¶ƒ[Óu8Ç&;þm”j›ô ÜÅojòY>£ÓÖ?R$ë:Âñ•× ‚þõ±ˆG£ *k´äy.}Ú2¡w”ðdv·>+ì~ãvÏ(tØôý$ú-Íœ½;ÎÔçÙÆøhlT骜§ÏG{‚fÇ~Û7_öî³<áˆÑ‘ÝO)?Sî»T`c¦¸ ’,?1å÷5´©Ž˜—‚ÎO¿5ó`=ä9dÖkfÁ~ý>*=¥`ë8e·ž÷N–=õƒ×ž¾^—‡}bÌúÆÒðw-þYN‰çìE–7ÛÒ)ˆÅ/‘V/18ŽÒ},P‘_T{á +» F2ÑW|—å!l¡ÏiHCUfÒsÐiV¯ziÈi–ÎöMÂfq® h¡*½j—Ð+Þ×òÃ7x¸¥àÄ´u6IüRºõ{‰Ä’¬¿t¼Wc„Ôûp HÆL/6’L¡Î‰!¬?Ø16©ôëæ ý5sÇeÆÅÕ°ÑË—2ǯýòÓ*FeS™²S]Å(ª«çcÈ:¡fw$9ì„}î>²™txübojý½™ü»ÆSÞZ:ã[ú"bv“!#–@•¬‡¦@Þw°bÂò?˜ „Ü|12Y™G¨J¶Îw蘒šz(swÏë²è[?Ñ÷YÌ élù;­.²¶›º|¸/È6lÖ:Íw… b#¯ãÊÎÈÕÇoý¡<ÖŒ”îNžÚeÁ­›ù#É%b­ÿÁbT·%Û^ïWýKšèàÊk9jƒòtu¨›®e¿.<Ю %Ïe¦a‚°'À·#:cè!«KX$ƒ—K W½T›$Üó‚ü+îB×Ú;eÀ»nÓ§6Ê€À&Âß ÓsI¾è܆氉ýP*©éëQ–Թė1•I¦°T?[*+´à(i+"Ûõ#')ÍPveø[ÉbT¥ƒb¸[4|l¬ãüò±Öà¶™£ÐÖÄy=šÀ6¥‘ü$rþ>§N™Ni¤÷ü¸óÒ±ÎÁú^†“Ô*3èÇ“FŸ+¬+»­L/lÊ®(g E„5¼jQÈGÿÝUÓ÷>ú³÷Ã$¸vxï(C¦üœÙ=h×Üð ^ãüôž™£8WG¼‘ö*}=<hÂüwGóÑÆßp{âñmó@¢nã´rÞ´”x¨ü rsÕ0í©ôxÌTÌ38ÒÞ ¥ç0ÝêD6üX¨Î¶"ªÚ3’<û¯¬šD‰Œ‘UÁ?ñÑ›iG–ÅÙ¡*ÏÉ÷¨3Òõô†ch™÷)A64¨¤öòITóÄûNN”›¡»atM¨ÕàÛRM®þtHad·jàöÇçåëè°´ Žw5QˆNJb.²ÄIwŒ3j¡Ár&©ùlØÑö‚BhÊÂ8ûS,çäS6׺f¬‘"]í·bE›Ív;ÍÃSË#&ÝÒñÔÕ—jǵù¬Âá‘É:Ám× ¹¯?ë’u*0ªç U SnÕttŽ&.…MƒzÙÞ[hÉùˆÃÎáM&à.D©4@PdIåø¬ßxÅ Á÷Qñ×å—Ñ{5*i½•WJôÈëTæóœ/zT$Að½;>ßø%!D–q²åfã9d;©@úæ—ÍCj{CÐ %f…™E±ã ÂJ„}¿‹XéG°åôðŽ½«Ã ’Béw#«¬²ÕlgµŠ$ŒUæTFY†Šµ¶0A5ŽÛö£¯ý(®ûpäæfôGòöƒûµæåFë>\£àðíwîý9¢z¯»üe(ÛrDhó‹³ O¸õ.ÓªtÁ¼W&¨/_Vð¾_~<ÀûÈ“HÁÏPÀÿÕ³H¦FG‰îöG/îen´x‡-ÄÙý %¿i.îÖ:n“•êî°ÛÆ’ÿÌÿNöÙú ¸€"bXÚM KšOOÎê †´Ö÷6\ÒT}ÄV¥UÙ¹R‡ŠÛ…kž?º~Øž dºi«NeùSîò–hRùªf¤ ÏöULM9ßFSu<5 Wq4}_0û–j¢î:ð£úÎ/È?q¹)Îe€Ï¢>ó˜æ¶öøØÛÕ}™m¶‡W„ „u+X\whqýPpS<¿/Ùœ^­Zjës\–ëdùP]è Ê{ŠQÝm¼(œéœ†.—ß>YH9bôz%g¿'–†OÙn¤×1ì¾X㎠%û¤ÈV¬´ž<òù‡©¦vw^/eÏÚ(ИÀ™}¿)µ?\Ë„‚Óå+ë<{ãÒ®5@õ2з€õ£•Õ®õó~L9¦“ˆô\s­91'Õâ†>]ªÏ'”½“p©l"…ñ5¤ ßIü²ù~òWs:~É¢1õWäD¥N¡Ç¥óÍ-+Ô4óLu|ÚÛ‚€L<‡™k3ºI1˜Žî„dæ$ƒ¸·s…i]ŒŸ©zBVk­Ž÷PÃpã^鷺.Ú.ßï&¤ZiC «oÈ÷kÏRì›ô‡‘¡~Ïáb¿'ñŸ_v$§`ìnJJYþ*!¶‚Oüb-’zëšGkÝtF´&Ub8ˆ¯Æ‘Á»Ô‘ýþ™®Ñ ÁÓ•3g—pŠ¥Á[MØ0C.ëLßôQn*Wsè7Ê0/)bÀ¬¡ Õù°i0,ãÎ qeúôQ ñívNâ"¹ÎNX£g•‹é¯Ð÷ãwáâ¹ò|)“&<Œ&B^r¬u[kÊvNÍv a±T~P"Ñ"ÃÑ_wò$‚H Ëeô–_£M*oi¸G~™ Á F¬í*üà›»¼rØ…KÙ‹ À)QoðÄeëò¾ÈG[¨T¶W¥³'ûz‚Gµ6å >m+ï;8/$Á©„àº?zE^»¢FÕ]x£1!MUVê}ä¡|Í)ØeK®@Ëõ©RÕ!ÝK*Ê b5H&PAu"ÅoÿkU6Þ§ºLjœàliâ¡ £$–›zQ³}”gßq®|PŽè´urÇ—}„G٪͔f»´?‚’k{úëCi Æ—_¬=úpÎzôg ßÑ á…Ø \d/Dgâh;ÏûW¦ØŸ$1æù¨ùÁ¯È ý¾°)I¬â”MXA6…üêŽÎ¬W›º®èq8d?['z.}Vgó”«GP³º÷ú¾ž—Igøme¸JÐÈbç¼z¬y¿wÖ°6˜œ­"6ŸYÁj\Ó(­Š mÍM2õN#ý[di-Sä$߆Z#Ë±'/ÄV‘.×®ƒCayBß¹tI¹ü‡ô>üÏ/ÜÓ PhøE©Ôh~ÐúÛ[=j쳺Žçã‘=²/C¼/±Õñ7¼èÚL›_‹ïç&8…ñ;â¾xr©ÙÕ.S37^×%ÌNúö3Oèv8Ù«-¡â-}Êß­ó §; 2‹t@öƾŸµ˜×£Ú í LÒÍOºÜ g‘1V c…37Ÿ,„ ßoã¨)ÿâÿØ~£Äó#ˆY|ÍËY$³n'²ç†yý¤ý!^w(fØ¿m.Æ8øŸ?ây-Ÿáßãßx.3x2H ¨óf»Ë>H•ÍÔØè|`¶ì€V§ÅVÀ.ecãØ’Ëc£c|Ü£(Ùœ‡_/zKßöIÆ& ç´‘è¿Êˆ}ïBõx¦æLwÓCS}eC/Wo ó¸%>+ {°fyY5ïEá1¢Ñ»æbí†Ñ:V= ƒ„èdÅ_U>‡ UòÝd¶ÓPÜ`zåV²w˜MÔ¤Y{à«¿GÞArKÓÂUËéÃüŒT?of(ª]•œÎ÷—È+BÆìKÔiÀðÃÄ’ÉÓŠÑX?¶9 Hh,¸>§ÐºÈ@ªî^ÙM¸òfi*ÆßR?ò£ÁÙ£BàÉhºüD¦¼ÿ!JZˆGº!¶ëfú]„s÷æã²vjLKšÖNGõ˜ DƒŽ¸‰vUHŒ›Þª sßć×ïxddgA@1t]WnÉœíI}Å@cŠä}LùWà£Ó·‡r¸™‘ýkÖ&ÜÂþ5t¿ei̪F¾pOï‘j—{‹!hï¬FhÉ—6H¯Hè­GãÛ <ß$9ù·ò<:Ç>ÒvŸ Œ=ͱOÂR쟨5ÔÉRp½“uJX—H´šY1!T†o=4 .˜„å ;,”'u`йô[¿W-'f(Ÿêòr¯'Ë~S2|Ψò§ˆ‚"gËú6óM>:ü+EŠÉ.}áAåYɦœovª5Õ•9|1w¢;»æ€Tâ}ae–U\ÝÝ4Zƒæ×ŸÁöÈŒøxH÷¤¿qý:àn‚„Ë æÔW^«£Æï¨ÇÀŒ8ÓÈRfŠV•TGæ@ÔÖ|¶.ÊñlWçÚ?“²qrº v°ßP«-bU 2«vA°µs@{k€@Q)?Î["‹®y`’ùð/e(øz¤!Ë€›$\jŒÍЭ¥T|‡þJz•µðe휩D¿ïçOsÄkæ8ýȶ9xº•”²ŽûØŒV9Óñ8N¡ Ø4R:àÙspÞFäé3ÊIv,³X·±!µÝá€8»ë~5ŽLÇXD™™èÏV¨-[`ê%ØFŽ•‹¿“Ù,&‡Ëã¾gtð› L QÊ"㇈h9­ª´–²ñÇ Ã ÎÑý Òæ0ƒ°Óº‘ä²È¢-AáévTÝsAwÁ ¸I¿‚gó·:{+¢©'~Ê ²¯€~%óíò°ôþ¦1f%‡aûµa rÊ¿ë .ä™\eð«rAñ§£²~— gã×½º‹¹ ¨}ÌžEŸ¤ M›yÇÖ)Êëf¯5)iùàcï«¶ão…uy½ï×°êåç…׎§©ÅªFÌlûpÿ@T CÌ~0îg.8 ”œtéežÅʘ9/][‹œþ)@%`T[ÂÏ–l“˜x>© Áf˜pªÂC÷Ó‰bØÍ–:†Qç“iÂÙ·^ø& grvH:¦³ÅÌ-–(㦾b_(½s!ù J´’Ú²ùH²k4ú9‡9Zá x—ieá-ë Z­½§ EÜ„KÒa츌T…Í3ñ úîO{ïjžÒýª"µ/„Aá*Ÿë[Û8ök*!=Ö†Œ7]ÑÁ[•,‰,_Še•úrû"1¤rN"ÿ€N/ö°Wì4ª¶¹¥·ØBˆUÆî Š7N€ƒsB%l9ðùÈ’®Z»íÌÃh;ÅGªÓì7¶1ŽS}FN­‡@Éü´°p§jû ‹t¾z]nX¤’ñT_ÀÛ¼úe+˜AÆÄ<"WŸþ‘ãˆïLˆá%IŽ-IÛ«ý Hþ6SR6Vgm1=à‹ÆÚ<—ÐR`·qÁ*etˉCåv©AúÖçéøJaÛ!%Æ2q®¶-N˜K«Òjº®Š f«ÝJ>ÿÀŒ‘bá ˆšÆnZK"Ñ]ÿ‡â04‰ª¡õZãM¥t]‹xÎÛ3’í·µ•z­ ÏÁü‡<¬Š÷ ²•9¿F;ç–B¦»ögªA}Ð k]^þž Êr  O)q<ð‘ *™\?yÖ²_–/Œ[¤Ó’®®™1k>.\‘´Q3®f÷{è5êñDK#áS3Þ­h`<±×7̽Ȃ[CmšÓ/BxôÀQnösT“ÅM›Ô<ŇœÝÙŽD#tv·£ ÊW9΃ÌTf±Ÿ•nï±}ýÖg±s^E¸)y‘ëCèÌ)TÑOܱޯzùÝ~̃‚0Ó°£O6 æ’vÆé…4 3ùéò§ò¢R×s@—| WbSs_š6~g®{oÀDÔNüîú-•Ye >Y 'Ÿ>öÈ&WÂôwšÚ#’¼Ù¹¼~½µùÄó‚”wŠÚyäB‚6Â#wæ å·m`1à”>.B@«Ö°LNçÏõN¿D©Òªw?Vø¾È/XÃÉ$ ÜQ+]©š4ˆÜÐ >O–?wš 4OÆ¿îÌÍÃøôa{¢Ô4qįܱF`Ñ|óéãä.ÔMiD‘MmªýÔ½æ`:rùA÷™õ+ `ç‹W©r®“¯ fóüªˆÄœÖô·c˜jõ.D®‚¾~2·p ‘É…¸„Pª€‰©ÿßB[@¢~îæ÷5ïº~XD¾gáFݪCùd¾#'ÿBžŸŠB±LÊ­òTÝ"Ùhʧz+aÕaþ“§É»7ã© Q6“|¦Îƒ3Ô÷òÁ¼aä`›d9MÝ)œ9¡¿šˆï û2/©a(D?o;‚>Ò^C—vOðä†MÂÄ+†#I:ÔoÛ>Ÿ¥ÌxŸT6!êX¬­²/ü8ºÕØyËÌÁq½ñ„¥ñÃô= G¥œ#Íý&Σ®edúâ©F+9–L&u Ž™X„8^?C?3²¯hFècˤÐé@­!º6i¼ºúë~óô${#‘¶ým!¹7ZÍgo·\¾×RkÚ9CyÇL¬ß8ØâV~þ%„¼+‡á,0gwÛuzùñýζ‹Óê0Î(WóÙ}9sN¤ßüÅ[/¼ý@2*F“Dß:¥;s-?ëž{“=ú†®HëÔ6uk$Ÿyl?N )¶ΰ°f®…_ûô £Ñnä2ÇqTìÜrkp¶zʲ|ƒdX ‚³ã‘JT]6Ž`züVÓú· Ô×øÁ’Ÿå0–u})pÕ)ùÎp±·;cƒ¼»ÛÚ&N7[JÇ{Q’CLzÜÁU ¯»ŸZùŒ|´‡Çˆ…ÇšeÐ Öbè±ã%ó o8 Ïð´9ga/#evi¬#`¤L©8³[®W;-jÍøE®•û°õyÿº›¿d©{º­YRm›pÅ}ׯ˓”dºn(¼]Ö´¨ªR_&Œ¤ûjÛâô9ÄW£9]“½Ôß» X3ÙÔ˜“ÌnzypVGYg€{^€F{ãù"¦ઠד<ó«þ9Xcï×PßEÝæÌ7Zlø÷®²_¥È]½sîÖ›ÖðÌð5ýkŠ¢Uf_y)ë!Öä–{¨ØÞ«¥t£"a¯hŽsóFÄuŽ mt,ÞÜr$<–91ëïù~.j÷ŒNz{ƒ‡’Ô¤óP]Ø&ÂÙ@º'iEôE;¢Û¦É WçZ=e£ÐRÅ@‚D³|Ó¬‹ŒfSs¯™9W…•µ›©WSȸkUޤ—xgO{ì¥]"®t’÷Ëên¸~˜±Œ:ô•8í0' @˜$æì9Òãdª./:,ÓÞ’®¢ETIW'N=Ž"pÁÎ}åP95÷«Ý©f¸ê"Q!£‡"¼0ý#.LŽ €h5Û”­LB>3±l¼okwSIÑQ,Å.¾×Ìâh<ãüæâwü‡L2þÒt¡½å?Ó¼/-·ìçàñŸõ D’Ú§B¾pXSÇÓØ'Yi2BQ&6‹+ _‡Ô¡µ†Ëm÷Æ/¾–yŽ|^-èP; ÌlލÅ*vó¦ÀQ„!þ•pÎßÌ‹ÌèrxÈÝ>€Jרû/sàë;L›°dtUÂ$)-É“{1 ‚Œ6¡Úª2‡_NÔ­Ìš†:iÂkõ\Ž9ŒÙ;ÏZ {\s=´‰c’ÈÔq‹ÎÉå‡kL^‹3ÄÆ½y#¹Ñ‡v£O™\›HÙSh²¢å‡fæinÓf·ÞC‰õHfÇîKèƒ\%É^Æò•اu%ã盬;€cü™a_Ø™£’“¦1J©¿haŸTªñ%Càa³‡[ûç%BÕ‡ÙB«f;Óâo|¾1ºÞÐÖž`zdÖ#:‚½ð'¦üˆd4Ä£tšÂí ú.p¶ÉMxÙÈÆB¬0Ž,)e$Áþ¼ê(=ixEÝ®àG»ëþ-¨ÀüÍM¿üŒ¸^äÖŠ©¼öô³ÖÔ½´]ÿ[9W\?øùhT•yÃ4X‡Õ™úTÄ1ù h±”„HåD­t¦ôã¬Ö]V‘™V®:Íf˭̾à.ö3ïU{W pßÐàèÔ­eõ#ÑM±@Jà‰? Kd|‚'kS”}oY™Mp ÀOŸ´B—qÖwiàŽ5l^f,r­u#×Ó@2§¶ ¶§”-¡HÚ§5Ç¢ºkŠ“©PUíK/à±Ë9^`n–úò™IPu™:=ëc7a²v9}—(qYÚoN@ÔW¹µ]ò÷?ÊBu²AƒÅK5~â ôCÜv´mÒÄaaøDw©f±¥òÅ o2£ð¥ÂÀfÎÉ [3íYmIØ5ÁÅh„'àsg°¬×§; 5¹ÔÅ­cvuQ”ª}¢ÏÈ? k­!þ˜L‹š€R¡ñ­åŒ)ܸJo³c¼åúgßžt>‹Ø k€FgUÐIgeŸ˜‚í¥Ç3û#¦v>êðij0ç±}𿻥¬:Ìiª?ŠÐׇCÙH#VGg¬8Qv0ãøû.ò¶/DÆôä`+ôe¾QŠ¡W’ÄøÙ¸qÒ¶F¿•äjŸ‹Æ¨Ý¡íÃè2÷1GÓ§À̦+žWL{ XÂÖAÔÍŠ7ú²˜å²ÐÈm‹:%sþ«Á=*½Ž×Ò@PDT=±kÞ-­Ã~É;hköOÔE~öaÀãÆ® Ë,´äÁ…¶³Ú‚¢…ÒëHÃàáØÇx ‘…÷ófßš²ö[¤ÐÆ>o¡RL´£c~ïjLî‘•ç>»Ûï S:hT_ö:y?Z”7Ù¦žë3­Uð2LÉÏÒL§†z(uùwþÞL4Œðc7m‹ç¢è¼Ý~F£ÖúùC ðv#Ø:йºê7egŒ,¥ü¡ãZâb޼ðRc]²Žü7nÄ(–o íÒ$£Ú·‘¦ÂLŠâÖ=øYé'w÷ ZOi_g3lçDïé y®"Ex9^|,[Eë)Uúø#?æÅž¿ä­ŠNãLQ¦ÇëªèŸÝjÌ«~ Ul­sÊuXnUJ¶©È7Õ:oµ~nHûÐ},…RÄ—Ù[½@ÒBÖC°t± ×FNÙÔ¼û*¡“Ð&^ŠáF“ÉNÍQܶ‰Ž—¦w¼îâØdáJ¨ßyÂÏßdk½˜évÄõnž;ÎYx½1açƒædÇø´§åk7 õÉ(–…² b!)ä46ík©gòê¹ l…$™›ô—–ÌHvriº¬« ôpT5ÇN·4_/ý´»Šùõ°fá6–x‰èËÊUÑìF8y¸VÓæoQ .dZ¬­9¦£6záŸU7š²S»4ö5Û×±’}^gSЇÌǃŽlÌ>E—"Éi§û´öÌn{¼é¿Žd`,'}l &ä!ŠÂìY"ŸxÄ{¦5\CʱÜ=aéL,³ÏÝ"tÅ×ê|Ç‹–Ü„‡á/j½ ëã`Ñ:²Í–$¨|ŵAS> eî½ÊlÞ6àž@= ”ù8f2¦ÑâÔ ¾žÔ]·‡w&*4Ù`–lèÏ"ìËJždšPéœ LI b¡}1ŸÆúxxÈÒä­¥âå-ïÓU†Á|¥ú$~QyÖDR©&D¾‚+X]ùé&f•|zùÆ0ÇÙ<7_@%r^~‰*_ò’Å—”~ò•[ê .ýRw¾ª*-²éÒU;&þ…@ŸKàr‚f¦5|øjeêµ¶lÅ÷Òž‹'y†u$q˜ %âH,ÉmN,“¢-¸i_w›\¥¿ÒG"δ3y&9AA’ÕùÐd¶2«ÀlÇ”åÈ ,Í :Å®’S¨þÀ£ž+jY±²&Œ•6Ä`æë:ÐM‹Ç[‘•T S]Z›˜ø\=/£É BX¶A~d×@—Æí5dô2X*ZBßÙ~ˆ*56*þ½m†º¦,WþLœg¹Š ð²bU•¾ò`}èÏïS¶ —Ó•ê8‰ÜìÊò’ÜZ AZdéþÄ7cÒŠÄNW¾Ä8?Œ5i¥9Z¬¦e‹ê¥ Âïºæ‡øV¦§Ð|Cze÷ì¶CÎ2˜ábIÍÈßÒÉü¢—ž Ùó+<Ðl­.K ¹ÿ¯ Ýo×"„zZñQN–ƒqG§5«M7G©OÛ‰N¸bês„Zï ÅLt’ˆÑM¢`·µ(¤Qø4<òuQù cÆ@ÍZm¬LŠšèKîöšœCTUoI/Åã árEæŸò±†C†šºˆ-€’•Máe³´$ÿ™W®/¼X] #‘é0õA´KóV¸Ð6;“ˆ>*Œ_ òïk’~ Ð4? yœ1x#뮤œˆjÎøIGÍØEðæRÉýN¨)I‡bCÆUλ‹É¿k«~1°Ø Çsuº Yݽ³»]{UÞÏÆ1•Lò\Ëe d”¬kFÎwÞóMmÞ«ÍàT ͨ®Ïë~($…Ë7¶ôŠiÌZÁY3Xg6|¹ÏÇJ›<©ß»Qyçy ù£Õëöu:…Jù¯¸W í6"Ž­o<=¹SÕ'ð¾JcUð·„MŽäO°J¾…‰¾k?—ÞÖQQ~#Hv&¾ ½ÏRzz÷m<°jôLÎIËÃĘÿ(ÑRÐ,¦QH%=ÚñÁ2R^€†þSûÀ$ˆŠvÆ3EÎ)5–÷‹… NZ%¥<¬ÿHV+ÝĘÛðþÁšŽÓl´4ìˆU7²“Ò‘Ør‚lº(íSûÆ›ñ§G”Õ‡SD"e¥V5”w^MÔP%| ·è¥ x;ÅóõìVìÈR¨ñ LœÙ‰.ã0Ñ\Õu;ûD'ï,ÑD¼”`8Xݧ"}ØFÉÞ/DC=I&„pŸvõ*ªiµ&£#@lÐ@í<+i+HxhÇ‘(¬}%çËÃU´÷>rpî]|AÔjÙå<ȲܘùQ¢ö[§‚kkìÿÕúœ:”=áv/"Ì…!¹ÔAEE7níN"MñsÙwûø=IÙ/êVÊ¡,ÈžpAî=¼öE>·8/é«»:xß[ðÜàæÓZÞl>!–µ¢b,þÔD?h$¥Iîú·èB¬ÅwŒ7ì=ûL=Ò"…ÎCÞ¬=ï®±q AÊ“ ^ «ñfë8ÿàÑRÙmê+ölu,ðHq›ö=xéäbýý¼\yµLï‡PôÊÝ+yä_ßäiñEyäq4¯ÉÍÀstq‚Íq"J”®: ‰7ú~U¤K¬nÇ%lŸcEö飽)aPÓžYí»´gIò‰Û‹òbXVcDfõiqû¹6è66Ï·¤MöÊúœ)h¤2:r=z 9ðA?‰„äì"xN¢é´.ªQµn³EÔß]žEêÇQØ nòBfO±s–màobÖ\î'¯ì¦Ü\5öË2Ó„B!¹¸?–¾ÅÚ ³k†.n6vVãm"”*F#½Yö;÷*¶l«wV§ëö¥S¦ÿ¾±’¬œŸÚmk5…ˆ#$ˆðŒÏzŽƒ+¸¹¹ÔYî¶…m`®u80$\¢›å6.ÚóÌåjX¬.è¥5Ãî|Ó½í{oq’+A@eŒ¿Ö”æ±Þ‚#y˨íD˜JÑéSr®áôdfÐLK½Ö¸ðXRbU§£'d gÅNqîS{î²ÂñùŠbÕð‚õûëLš!äãOö#N}^„Ã`ë¸3–dØƒÕ >+ûOϤ»çÎûA¤rYбš0OF®ßCÖÂßܶÚò¿ÌRSù2f&Z'‰ÞDÃf…ëN0W"+’²µLß©íó݇èõýºHÐ1ŒZÌ78 ¯ÝSRš¨Ö0nö0 K.X ÿQVÝ¥Žˆ›ñŒ‚o±⨩}º8¢n›éíÙ:˜.SƯ!wéNvSË1l ØDEA¡| &‰DaŸJ)Þ3[6·›ŸM¤=ôÞÃiÙj\×ä­ÆyHZ6Àv•ð}س‚ ŠrÕNÃÅŒ 3zd¡P)õ²L:w‰¬¦h<mâÒ¯E1X*‰MjÀZfdãû‰2@e‚áKV_O¿L¡¦MjÃRb±&Mãú ¯×A$_¹©] ¢ž†)Ì:7@Ši×®$a.i †À”œQ.ÔCn$値Ìqý(Ê$y·gªˆ­YÿöÛzj·¾KåI&}AÙÅ­Òr/Œ*îŽ5Ù&êÔ˜å×AÄ£=µ„c!-u,è*¿^o¦<ЍòSöV±øÝ/%¬ðkXÄ'Nõ„åN6§Ãž“ŒÌT莸Ÿo‰£LăÔíçñœµŠ@Q¬kEìëå›H„o!B=¢`cL û/ªu§IêD"…Ô„›ƒ çùêX ‰.BIçÚ NÚᬆÒ_ÞîœädÈe‹Z¾ëÞ©ݦ…4æc ëuÞÇ´Ùw5#7` Fm/w á6v3TE‰g¯CÍóÌ`\Ã~ž¸R™±FÆèʰ³Ž Æ^áÜ? ¨ê=gþ¨»Ö¡Ó€­2¯ÖÜ­2þ"aÿ5h;o·¾ŒUp„ÖBX¬âƒEpŒb9œ¿#¨0\q wfcbÜW>x)æJ#=•¢CM¼QCf±ÙçìùìŸM«§…R”_¨’•‰_¤ ñáì›óÒö¬´&sžrÃQ÷%Œ~þ}På׃A— 铚Þ–Æ5ò 9ºXÔþ‚éIõÜx燘\ …ýÌ‚‹ôéàùUZO›]ó.¯[ AUíÙ®7·ÖHœe­vþYÇË%ù ®?è° ™²º6}›äÛ‰q@¥íy…€>àTÂÄ‚}* ŒÌ˜›µãΘ2¤Æ‚cdWP]R2÷㤙œg´~!3q¥EâÞ Zzê\h ž@‡3>ÆfÕ¦é·Â•‹ãô ÚÀ™Ëðg[ËzÁ®ËÌÂvßÏÕD)ȼ&‹Y§5ÓŒIªp., äL})YT&þà@^J‚–!mïî.§8ýÊ…J|V¡^€‘¡ñˆL¦ˆ·Rðx,}ó ØíC+<¼ˆ`sÞäÜú„OÒq_{ó%‘'™ªãbù9òÓz²tœ‘)-‘&$”«–?oÌî ôeo>_S 7l FWÈ7r·gŽÍ— Ëе!; WóÓ§ »CtD>Ã!“d­Ëà3õ”H÷¼l¥xœ1GÚÀžùÐý¬-‡¥ëà[XGYó£Á,0”±·~÷ï^ŒÚ?1ΙϡÖDä êéÛÜ÷Zˆ–³‚— O°o?`œÌÈ÷ÑV±ÔÏ…øßcªa}}ѧɿ´ªàè(ž`_Ð+< Ýß÷ÎæŸÛœ¿8½CÃéªÍ‘¡ µ Â÷,ºgûFƒé`2S»~Eå«`v;¤åÎGsr(`Y.­ZÍ/IèA¼ÓÓ"´òhrÜ8YÐ?KI4eÈÉv7\ðôòg„±å±ãVèHÝáa#ýk~‚ƒUALõð›^ÿ–œ¤QñÆa ó¢ Y“i¬–Ò´¦é"RÖšì¤Ûí|KG jÔ«C½±„°±–úXê<‘(÷/HkœV£Z³EÇòiƒâ Š7îSë' rrðËÄD.G}ãée £Ú§ì1Ç׸†±ëŽ@±»‹7tݤæ1¯iâ ™H Ñá”Lª¥ØÏÈ.q|„›vŸu™¤,›Y1kYÕmW{ÇÛP½Õ¥·jßdÇg0Úz•»ßp«›ê€ë;ØÇóØÑÓA&Ë’caþ2¯«¥÷øëÖ”^ƒ>ŠÝÍ©ÝQBÊÖ“Cí´”Iv Ö!Šs M—7&ÍÍü0aÖ5ÍÞ¾Pwõ°7S·GÚî6®ˆ5t|'Ênæü“æ‡í’ oþoå¿'Y%ÑhiJùû‹#lXê ödr¨îÁE·9ê•_}‡±T«€RÖµC‘æÔ zøYvc}ñÝ]ÒÕ¬¸+,ë8|óÍ™ Q ³>çÄl¤±}ßžòÏ1é¶ú»JOQ GÇfe†«:‰ÍÊ!ýµéÔ®i¥S†Ý¹,ñ›‚³Ðw¸Ù,—tEßÔåÐ ¿æÈd""GððžœùjÁß>×f¥®å1ìÖl¡àFªkaMì!¯zAâx¿ß^rˆÎW‹ü1Z˘®ôKàI[­xýNØÑ"Î {¹jD)CFk_åË£7ktÊÁ3BMìfÜ2KK«¡bíÊ˵ƒê\ÎkiÁAo†ÐçtgOØj†wÝ¡YçÒǫ̈þש¶=\7óÅ“aÌÍ_Qwaà ‘÷zVò*ÍØJ#ó¥HøÅ •Ý’ É¢RµRUúêÀßq¨né-‰SS‰Žâ%l‡TŽ!ÄpÊm¦îíôaÚ¢dïšø\"Åi©v¸±?·¹²°Ó“ÕÛø?ÉoŒ"pÒÍŽ¥N‘;?ïÞŒ6Ýúª5Óya5Âàú…C:1ÎõhÞOÞ ß¡tÆh’ð0,|h‹ô2ZÝbÀÝMÍ¢¡gãGgóh4è]ö'K‡¬\ªT:úRTïâ¯{aN™ïþ*Y!Î*[û[ÈdELUmNy(Ã) >Í„D½Èk½ÞN;êD;W#ëXÌÈŒ¬†)Ä*ÇŒ@ûò§ ¡–Ãä.†/7ËNÏDÕS›Q àŒÃ²«cž]TÐ(ûsÁs¯ NÉ"‚l„Pül±ºj£«³¤åŒ=®tÿàVg9Vóº®ú89•§•—Hq…WOïuÈÌIE¢Ÿ‚õéìfêSòNÅ»4¸ðCm¸)rÅWžè›Äʳ®Æ˜§Ý‰ï¸øÅÝc™¹Õ’—§á”-úzúäfÙ ¿ôõ#8¹~½}“O*]j°o\UÔƒwü`ÇÑ!o”„d·ã–ˆÂÅ÷pt3ºPGppTêaˆ‘zR¿òã X³x³Ê“ÞlV³»bÄ"Ç’¢b£]CÉ‹ñ‡aeŒUXñâ¨îÆj~\ß[^ÇÖ˜7©³"¬Àµ¹eÊ.çÿf]Êž@½ûÂp@ÅC´Â朥—qwÜ8u«ß®R6QˆÚäÝÉGIóÙ1øê‚ýüÅW]‰â³†hî€ØXm޾t„(ó*ñdAÒ^t–À(ŠÝ×n+6~W÷bâ°ï]œî‚·‚¢Ó“÷yÇ€²˜í·a•'Nºr8í$Š)æÉäŸT©ÁR=ë Rê³\YZk¨2Öôó|æÇŠš!s¹h‰¤/˜¯Ã*Vä½É˜DÕÛ~̲)¦€Rïo¹š°ç—NkEW?›ð,^ˆ÷N9ГTÂÄÞ€ô¦9¶ã$ÓR-4Å<3…6°‹pð•Bö°àE‚¾¥}¯*T¿;0š›8Epèìå+Ä•ìÆ*]Äé§ó_Úhò2>oÄ^µß6f‹- ×+ZXv_'•z^Qû_ϨVaáµnz¢ü\Ö®±{­âæ)¸¸ùî²¾f»Ãž##ÿzËWõþl!AæÍÐ1+FF¯€óü:ÂI—Ñ9>„’åÓ×jÖ¦U¤ ²qÖuìâ–.U'1ÙgRääNéǨ¸µlß7•ÄÎí)<§5÷î <Šf•»0øŸ8±îDƒÔÑ;?û[<| רªlñüR´ó_ñ™ÑÇ3[v2SÒU#zw‰âlÜ|¥õÙöÿ-Òã‡æfÊ@Aκ’Ö’ý¹F؈ò ¿ÕÈÃ0~’æ*ºè(úÝw¿ÂìÜV-¯Vd ^^« /`8ž”øjªò·éã±Wø¾gò`þNõge…U$Õã…9n|];áÃlyÕå ü~iö°¹uü Ø¡ÍÀzDUä’Æƒ›…© #ø*ÿµ˜‚gÒÝ ö ~If´úë·/ö½Ò“öD9“&ܶƈØ^J«ñ í("úÍé‘+4aršÄ×Jz ePúÝÇ#ȤZÇ?2ÐíÈý 2]û*4£ÅÞV¯Qä®­Œð\Е¼c7¹ý¶‰ÁµÊ‹7KgNhÕľ[Z þôLõ6ö”Y•й¼“ÁV-îDN©Ú'z ¼Þz0W*MÂQ7?¢k1(Ô³9ªÍ7Þêí`¹€¼Š×öàtþˆMæ«ßšn-x®’šñÙ¿…¤=\oPÄy¯ãÃnß–9ä%ep—[%ÆÁðlý²ý3Y8§™7'k3iK?˜Š°Éíàxö 6”½~ÉC •¾2ùoêÉÞ8*ê:ük"T«ûz—.Tãë&³T38Ñý’!åmô±Çe7®º¶6Ä=+Pñïá-#R¨ßÛëo”ÀöŒÿ/ê‘Äɬú!ÃÊž³ùÌ!< ÿ9ÊÞkÝ¿Šƒ×/PÄ%wt‰Ñ}?Ô?V7Aß%¿~¾u:+‚ÿu)øÓÃy€À¸31V) Xéa¹Ëp¡™ƒ=e^žk×›•´TƒçLnc(¶µn€1&3³\dH’o£r`FCíP{UîïmTè”רð*«k…—²ÞFõ¡r­ã î·;ùy·fQ·}­Ã©‘óPX« ã>ÛUÙXáþ€¼¥DåÐzë¶·¯ð»S¸îû‡é–:e80zölù×” TÝüòÛbq@íŠÕÛ÷ØlˆÏïD{À-²Ÿí'I›ð¥Zž kƒ"U‡cÀË»\4 !´Sz˜4Àµk9Љ“‚ø^¥Öeö¾ýGÃÒÐIzóêúD‚XF9T›Áx‰½µ:—R¥›v•gIiœŠ<¼fÂúi–TÌ© õõ#ΖÍ\Ý!~ܦqåT³n\Aùf§nýû단¨×àB5Së$­kôsœRÀÊRßJ›Î´Þ}óû…û¡Zpþ¨~ê •Ä¤¥¯zmª@ÚáÆ8JW° Z«‡%ŠY£Ú&ºä!|”×3žYxU¶|A…§‹0ô~ß›;rï&$Â=ö[†çÅ“O:„MfߪÿG\I åËØzbÉKÿžÚ‰nÏû™Dë~êÞǽ.‚:7 cµè`)3{ôp Èè PÔ_¨@Ó`œ²jQVzÑ|“šœE2z&'¥ï–fëy„ˆHá¶ËaòÝŒ…i@œ«·Ý.‰êãÏÿÿozæ—™g¨Âƒëç Ò¹D9#·vAVØæz5ý--·X"í]é"xó.W?Øf–ÙˆD?2ÈœSºj|§”òÇèEüðOâ³gßmõ/Õ6 úÝþG$Hf]¶ Oõ÷êÁÖ¯œœÀweK¡]Î ›ó%œ‚g%ÿ;í&§ ÞéçnΈª˜ yD G+Ü´¹&uˆ¦Að‡¼=çJd¹›j"½VÁg f&ÿS-Ô:> va›¤Òæªó{/fŠm- é +ª°ƒL0¼_XZÂÁ˲Ø{ýÿvÝ`mqóÜSH²¿~ËšäWý΀ÎÖΛ÷ÖöŒ‡r’kÒ$ElGz‹[ÎT•nʼn^rtï"Î^œw’uƲJ·lQ­çø—ß̶®{lE¸û† %¾Z‚í²Ò7¯øE€”¤F"¯*kƯ¤"Øó±ÛG¤‘´?0zÜ0²×Üó°2 ÿWÐg©9ë$ãNIUGÂ](“ã^$C_U¢ÖléýëXû´ªÚ-Þ>ëÁgl§Ñ<~Š9âjT•€Ðõ$Àj“Í“¯—¦á,AÄãÌŸÏâeÜd}L¦û”KBÖ‰° ±8­ËÜ×÷Z,bÑÿ›i&ó`Xj\&É‘•¦dk6ñvª€Gj/<¢iÌÏœÐø—ðân/®!j ‰xt‡Tíšë¶ Hq F§=E:îr½\ôc†Ö—[pãΰO,¬§]ÑBñMÉS-Àûv“)¼!l½B¯GV J{BãZ^a¦B8Ó™Äu³zÛ©YŸ!ù­Tà_˜d2d(/Ì Ð–#^‹1èI¿ÇYŸÜz<õ¶¯&çð`Ìz“ "î‹,ÔU¯›_*cCä](¬kíåÔ“Lß6ÀîÂÓòýçnÉ>›‚Šôízò©û,æbAÅ,®Ã™+îñÑÍ¡9h•BZØ´Üæ:XEÌwmòÞ5ëRÖQ%Ø¡‰ûíC¿Ö &Çr·¯´Dòƒ<=j=†F –à –EN|ã;̶¾ÑòK4%©ÿ|8¿a•c‘÷Ü%Ëö>„œHƒ^ š¬>—|"ÄÔ‘±W‡0»ñÕT`Ï 3ñõrhbúù3E·/¡ñ= CÌñä–ÕÕdÉX50ÈÑ( {›è3£F„^17JEJŽ¤Ôø0ئ[‘ó½±nxÝ8´í‰É/­ Š Üââà×Çn‹¡R‰ê«ŒÜußGÌö!f&ª¯¤ßÄùÑ#Æ¢°€^Lu×¹BoAš1½ž>î ôµ(M °ÏUšŸ/ñÃa_د”ðt|Q¯F†t?6z̬ö~c¬Ñ­%…“²:AÁøû•\oí®{TÖ-yïóêØ‘Ã¤Ü¥<†-7pÖÂå‰M¦ªé.±²ó¥² ÷´ß4#=¦Ûò¦ÿk3½>;<²¼|Ô•mVì]£bh\QÒ>è¥n?ÉÕYUëô¬ßB}ؼíý]õ;f%ŒPÎ,¥Ñ‘ÈV¶äÊø!h¨5ö\p°ÑÓ5Ò¾kjÙ½¨¤où&T¬5Ö5Úl‹p3ð9S9åNnW2ÓF¼ªPäûãåyÑ çV_g#-ýÖ¯ú‹©s4zy+=´x”\¼çŸÇM" ½Nñ úf—óÔÍ݃jÑby?7ú^9“C›‡êýv»z—h¹f°˜“UuŸ™y¡àíßGH³›¾vÓ´ùÇdåñûoqæ ¬ ?3DÌBpÏS;½Nͺ¡áy“ì*àýëR»; Ó\ “¾`‘ÿÁ÷Vþàå:Q—¢o–Š-˜`^ö(2"¤þ=‚¶'í4îiÃ>°7¦®è‰±Îþ×È1ò±¨ãeÐ@üR«‘Ž ?Xb²ù[þ µ‡@Üĺ˜LUÏÓÿ½Õê*Mhžo ’»?7(; ^WS ç¹È pŽŽƒ#éòõúÚ!7/Ì4?á%Ž’Èò$c ‚ì÷ $õSÂ;y^çÁZ‘7ãôª!èR;‡ºý LµµI¶šÉOëtˆEht€«éOÁXè]?C 2 _‡ €íåpH¥…Ô˜'S^žþ å6B’Ð}¥ÉÎäï±Gxe†¾Þ›AIÿ˜î“F¡V±ãã_>ó¦#‚¿‡êη#ò^;º:|MÄ–d߈qrOš…ŽAÞÑ[ ‚%¼†Ö é‰Mû  Òx)•gþ·«rd‰ÈI€ l™Ž“ æ5™B’_à„çuC=LkòC¼#­JÌ8¦HUæa“þ¾äzñÞð̤«!B(JP÷¨Êï 7o.Ü·x CT'ɆÇCb(%Á+¯¹ØÀ#†EÂSç᪽ÑË!÷2g!—A©Ð¼+»`ÃiÄ?b=9Ų´6+£¢Ýòœbß¼·†ØxÞ‚64³‘¦m©f§×õZ¿}Š·êÍ}y¬•Ýd–á¤Ïú;#˜öQdB[ZÝð‚ õhæΔž &@!’îç-,Õäê\(ôµ7Ñ\f²óÛ®m ð²½u¯¢»8Ý—Æô&¬uŠ\‚Úè£Þ¾°–La¬.œ#âbÜJ`œÃ¸>åZ`Òò€Uù®ḛ̈ðßð\7òëTòÑ= ÃjÝ1Ô•ËFyÞõ…e4¸$©gÙ~{³ñ&o¸VŽKÿÀwS9Ÿd&7ëIá{D Eš‰d/E©>ƒècÚë/yl&~N+‚ 3#˜æh¼UôÖ{“ëdX+}{ŽDì–Ê(ˆ¶ÒøC0Å„¿å÷êt”ßË1(»’Œ±æs§­ú¿©åµn)ÇŒP&®rà’!``3Ì·s b]£„§ÍýΓÎ}ï¢gðþÙ¶OžíHÉÎvø5mÃg7á²X2{¾ÌN¾¸:«ë´ÉaYŠAˆÈ ¹µÇçëkñâG/%­Æ"šr?#tÜ‚+š“­Ê—¥Ð$—ëùjúf‘£Ê“œ´¸– õ˜DçЗ9$j¿5ÝŽ†&‚F@MVR鎦ƒÎD¡#ì²ã7 dYæ<0óX¯:V F óðÆxîæ>P žàF`W^Ç‹ðŘ› :èf{O2TÍ&^à ®7L¸Ñ–Q)h²µŸ!ɄƃÛUy! ¢¥§Q‚@Ý9¸(¸å¬ eÇ×’´ŸS®ÜuTuf üÈs˜P᩹Ë>±\kÆf­9F’ñWèÛc0ueؽ³ùrfæ£@®Їÿ§-sBô°åºÛnV÷‰Å¾ðøþc­X DjÓuH«r”5Vpš½ìí8ôä²KÅ6¦Ž/À7… T0…Þ‰Rõ[ë„öI¹EµõÂ]°z;ûo¬òX™"¬;ÁDöÂþQ<“Çë%(Ì‹rµ¥yìˆè¿ ¹¥°Ãí¿ô¦ÍŒÂúfÊÃKÁ÷7Òu,š_ !ñnÄ }±+bsZ|77ÓÑ(îCz*ûAƒÚE³êQU<Ÿ›ð鳓¯pÛ¡3æ´ÙþsæUl4ÂYç1ª¤Êt¨ƒLU c±!¦Jíø6ÒÒ·õé³,Xa¾C‰B¾;öß=&ýažˆqÑ%1~¸7Ñ„åÄå ÇN@!MWwÎþ“ª¾kÄž°aô*  ¦éÓ¯ô'ÂüѳFÝv–GìíÞ“pøN }ɾÇ1­`@ý›€O¡Cv\Wu¸#GŒaQVeß23ûF3þ²ÙZ\&Þ:) çãàyµÜƒuM| ÉäüïöÒi¦ôF;ÂÙžhñW5š‹ïhŽp¬4z(1ø‹"8–ëVCÔâPã·I_q_€ ,0L{ƒKé¥Ù}„€ï˜ÏüjTpÿ££¹’@¸ßÏa.ª %¾¬™ÀC¥ê’ íeƒ=”cƒ!&§Uø´™1X‰80³T* ¶hÌèÚìüìóõÿ‘I~Ò&2Y%‰útÛ+TÙjóøœy}˜ì;‘ŽñaèZ 0D\=‚ý;9Ž"ékf‹ÝµÈw-HðPX³ÍZ,’Ùé?žb4shßü¾òS?j«\z/„˵h‰ç^M@UXÝ»ð:].8¥±Ì¦ºeEYv„x¬ÑˆÞ¥íá²ESÒø™FÛ‘q{%.ô®Ó¼wQx&`HMòø~\ò›Ù|ã%ýT„ÐY•LÏG«°Ì8¾¶ìf ²þØì10»@ï3®…@>ðæ:rM°˜æÈ‘2˜‚¢â‡‰Îï0ûËAL¡ïieX5¶væ¨æ ¿¸W¹ð³×Q?q¾+§%nwîéGù;MYDîúÆ`¸z2²œ©ï ­:À[›HÎ[dÑvøŸœ–N¬ÚªŽêh榭ikáÎ,K¡P¹‰W¤Œ°ˆÉÖ` 4ÿ/;`Pûêz÷í#ÙXÇr³´õÀ¢*’r sÈêþnô2¸) ·cÃQ•orYkÒÚ»ØÝoŸÒ²o+±dt2ì*ûm¡ý:ÞPó#uÃQ!þuB¼â§ìJ*âV¶®–`‘¯`b‚,ÍuŸ,¡Z1±JÁkTßzØÊ«|¤âSV”Ð~ç»:"z™ÁôjGvàåÉÝÂ&ϧ ¬EÚA·vS +;R^*¢¢I|GHy?*Yhy‰õ;r†BÍ)3Ó.[+`JÊGrÇBü»új‹´E%[q ‡ò¨_Ž= ï ¸ì¢ï‚èu©¹vù:Ñ`{u8ÀvØ}©"ÐbÑIøô³%´ï™ãæ„;°Íj3?Ä—w>p tß:=ßô³¨$ÆN 6Ç{åNƒVsŽb¶KB$Ž:ý°@Ï3)ÔsžTŒÃ¡\;ìÖŽ 7¢^¹¢ŠC‡¸èZÒQzÛë ‡Vð­ÔÎE‘ûK>¶Æ4.謻“¨zªœÆØM… t/X¼[(“v»Ï8U­2W[(‘þ{,ö޲¼n‡¯õHí_²¼{î -hp•ƒ•d¨½¢ù¢I›kN›Õ?µ©©šµ2ñX× 2L*\[ˆ·”ÊêðG·„$…¿ÐF‚Z<ý&›PŽ•*×»;èb°ÏØüX/й~ 4jzg»ÖÿùB{.x.M«dRjq—>§aÏç¥.?Wt3òb¨þbY¿Ç¨ážèzp{ŽüU3røMvk_­äuˆ#¹¦ÎžÊ¤gÏÛ á‡úz´gü±`‘í¬Ç¸®‰<š¾@)75?𯓠–³”^;ìë±ã5Syà—S‚»ký¡+ÂbÞœCí|uÌ8QݶúÄËwªÛ‘xõIa³\àöE_Uëô¬ßBïú¶ìkoSr".XÛ¯ @¯üµìÑu§:¿'ÑX‡€I¨¿øàU§Š¯Â%ítuÁ°P™m“ x‰¬øYñ¢¾ûØî|dµò›GŒ@v‚´pAàß <ó§®Ë“ˆUj¬ggPÜîÐÒbZ%«¦l¢N²Ü¾í[¾©»ÓÍà q­#l4€vv̸îßüÉÏ™ºõ$nTÀÿÊR]Fx ¿¼ÿµJß,%VëUY,I{V‘©aîGÀ{¡©„“Ĥ ÆŠ-ÒÖÂEÀ<–Š«Ïoæ*‘É—‰X‡±áͿƤ†¥Ó:iÿòd´‘üX4 ±@­á6ŒÊëXT-ÍLªP> U4icã6ò³…ÕYŠà’Ú{!"öŒ·k; 3Íz÷æ€ÎpÖFs¬&¥Œ™: ±¯üÙ¡úxŠ.úW±;—ÁŽ­ŸH‚ÅY©§1IºR+rÁþk´5B»l}³nÇ 6ÖV‘ÄÑe³ÅI²"2R«O9v:_-IL—£ò$^»á|e|ÓX“MO“hÿYb A€ËõÊçeæÚPÉSxe0!ú¹wÛð\›ûbÓ¶9@àÒ×¥åï'ëMìäêˆý£g´¼ì¦W´pâhê^‚RˆàëA‰¬dŸÊ¹PÇ2ðÙ±®­7³}xµYyèxÀG¢Œ_Pà¯OŠ@ûæó©ôÀ×):§í\Ù6Á†€w”Uì{þ«4ŒMƤ´Ó³”ES30‡¼@^˜*ê2*??µ€p|³9ÌëÃ*=m®2[óÉï¤ÞjpðØ6äíå+E뉓ÊQÜÇÆ\q¦Õ'e/ãÁ¦lTÎ1þH:ðgÓ y"ƒWH˜å’÷‚ÀÞÓØþztèZhÃ?™‹©Ž2œDRÁ¶]S‹£"ÂJ…™*ŽÐà^Dcõ’¼»÷¶ÓG ¡‚÷TR†€KߢœöCz~x5Ót6¡ëI©žJQ¦iÈÑ^§ÉÇ^.É?Œo8[å¹çŸ¾’㣪 bf… ý†ú]ÄziaÏ”¿ÿÌ]¢ª°Àþwð‰¦H×’²ÞˆÇÔéms.ZH­%'ÇKäõÛA#µsÇ[}â ‰•X´V”¡Çòcfâ4̛ɔ¡žélÈ®&µ*ˆYÞ˜ŒÇ„˜.·…dV™wú}|.bîÜxÝë3æËÄW²J¢p>GÝéÅwC?4ý2…V7¿kL¿uiûc¤,>Nh>’ìNy3ªW«-TOdrδ»À#7FßNúM÷ægí%~ÄÁ&ìD½buìïŸ}"àjs‹:[ ð–, - ³'56Y¶¾ÖÓ™°F¡·S×ÜÛ«oÿ#i§ÅøŠHs“Á$1ÿ'@ÚçV™ù õR9^‡gRpUÞ—^“Q:ëB¤Ž¢¿çùÒÙt¤þyÍœŽÀ>9n¸¯Öc›×eÑ_LFßTU×Õ NxÂJHËþ6¿ÝO´™H ÍelPiÕ‡Zó6ÎÁŸÃvxKª0º1‰® U;+¡i5Þ½í(3þļis ð[e ÀÀ##ëá!ïŸ5á¼´OtS^htmcøý~m>9'2 9|`‡Ñ×6xoÈÅQWM¦wýÔ ÃËUbÅ׆¹ü­½/‚è[!Ï©­8­ÓÙ¿Œ¶Óqã²úÆÜ˜¡œºš+g[ZÔ÷ó q(h~ÛõÃŪ€•`ißÙL[ïZX˜GI“¬üÖBq«›v¼í—«b7jÕyÍýòI³$ E+üÿtQXBîÛ“„„mS…ªEäõ’ kn cÓ"JQ†ÏIÇÈ>zí>gsæuvYƒääàÌçÞ)5KLδ!IÁ_¶Dg"Š"Ž3<úø5·[>¨å endstream endobj 648 0 obj << /Length1 1134 /Length2 3826 /Length3 0 /Length 4532 /Filter /FlateDecode >> stream xÚ}“y8ÔmÇ…dßK¶üµ†ÛØÊš%K֬ɘÆ cì#ÉZÙÇR²![vYBIv‘­P’¬Én"z§§§Gïó^×{ýþù}Îö½Ï¹Ï-"hbÒ@`:X ‘+xˆŸÈJéED´pH…ÅhÃðHe"# ‘“–ƒÁ O&eò‰9첑·ÌågXF*))ÒË€ Žœ.( ½ôO}Œ3€(ü²#¼=~û|8/² N•È’,í Îä?ûÖô©½,<Å…öÍUPNç·Vä)–Ç¥šzk†ík‚)?‹£µÑjä{8´Mv®ôóÃýf¯9[¥%ÀÈßfLáÅÇhd6/QÞ±<=ï²±geÇÙÝõ¶Ð·ìß§ ƒ ïës.&õÛG((w] oÄ‚Z®ssLQdÞ@ŸŸß8èœn}´±Ðl}â°hñݱÇ<‰æƒãèz5ÓW³=u ÔÊ_Hß©S ª)”llÐN±–™­<Æ‹µ­”QhÁ¼­_)„6¾U¦ôNâ&>2–‘ì B<Û HÏBŽKu„§â–}‰ü‰îr&ǰÁCÄî9¬tÑbŽZRšÁ빺‹—díUœ'6 v4Ã^j×€6®ÈmŽ ¦é6ÜÎÞ²SOO€zUgx%mš¤¥Tð²—7åÇ¿k"?*¿sI|b‘Ÿßœ+¼¿è:luÈN<€w§±pU¶Ö×ÇçJܼµ•óîOÁvWNùc`ÄãÖöáó.«Ø²ãˆ2Âc|Kù’³Ö²ÉƒWïÙ3o~ŠTÞZ\xR©F0Ÿõ¤iܸ4·×%ÿ•ýL*Ù»©Zzìø¿ÍŠÔl¡PIþà…Ò>!—¯‘׿’tÅM¨åõGcÏd¬-¿,úžnïK¬‹gMdNn{º¸›0·"á‘ïr±Yû1AÒÜu-±!Wµoöòî°2óÝ%7¶a"A2UUJ×rhϺPqðŽçî‹XV“ÊpxÂÖ,«ï´ÒmƆ>=BžÎ>ÓtàÁ²0Å8·‹Ö»›ï×Ä<„ç¡¶ÄíS[´3È5Ýphóœtðëeä\1³¬´=âõ0Žg›ƒÿëÁ®ã§½L¨Þ޶°¦´¶â[J ?…UÚ)0W€¹¶âÖ$Ý1»8§¨‰(wo´Û÷©¹äpU¥F†ø'ܟƆSÂåa¥3S N©Ü$ÎÝ8ÐîIõÙŒŠ"©«8²5›¸ó´6ù–žÇÌgiñ {$¯4f§ÐýÑK›°£¯-UÂ% ù×/o¯ÀÐí­–8<¯Æ&Ÿ·óoįß6s©Ù|š[‘Vg†?¤ë¬ŽOI*E÷îÎû‡ìæU5KÈôñôËŒ;êú'EÍÊ­l ¾®ÂÖò!·hÇ9gu¹¬%JC\tU¡ÉðС ±¦G Æ/³1TÙ,QÚ† /p†«1˱”g20Ÿ£/{?ZsµZ:fS£îض²}ôcEÃ5Ò\þ[3 ZúäB‚![Ý+©l'Úˆgs=mÚ T¶ôú4Úï¸.€¾¾äø:ìnnKÂ[F¸”=†ÕåZ@|n<çÈ,É¢Þ‰‚ì¿bBin9Ú.–øë|zø_ަØE;a4QV7Ë5B_^p¬C¬ª˜3ó}“V^ln-`fýB8ùÀKÓiàóÁ)¢ØåÑÓXA–/ɈþتssÁ;bÖ (³áNG6džÍD:WÄ0r¯}yØÖþÀÓ€ K oÜ.7/[ ÜΨ8~–žž9ºáÙ‰öoz†?䙸¾oðÁ’/æAÇgÏ/ÐWY°Î¡Lm;2Æ fä?ŠV•¾F玦lm¸vÜóx´ž÷Zbˆ‡HÒ 5¦ÿðˆÔ‚µFo1,ÿ˜{áÍ*dHíü³lлGÓÜKß ÔßÏ{ÉLëbÀ½P)©5R5Så’VšëmSO½ŸèÒvÕ·B5‚ãïs^Æ·QíI¤¨rOhcœ.>yyàû¬D²½=ÎùEÊe€A/À•Åá ë“çP–T›i®~ëi͹7XI~ÜùÃeY¯L«‘OcŸ!·ž´š×sʆÜÿf~ÞÕÇó¤qöŒ”´4ñjÞøõeI_*jbá`š¿´xû lÒ\=…Ú@ûI¾·ÊŠb¿Šþ^{Ò‡HÇ“6’›JL׃^f»oßoF}V.72È¿V&-ص6Z¡+žöø—¢W&\ÝZ¶¸€[?X®ÍŠ™»Õ –ä•gËÞä»siû×þò§Áoæ±öè«×û0'±Õ§äñzú †ïêcï×]Š ÆB´MüV2zFÍm€ ÔTq5Òi«êE•Õ,´¶Ê÷õ¡ÞQý¥ænûˆA± þ§û"Ü–O„·Ô€*øArpsàÕršˆ÷}õ‘c\GÛàò»Ì[š“¯ê©+“un[î+Ï{Ëy—áÖìñ‘)Bj0Ñq=Ó:/¹»3öœ1ÁYÕ=K¤¡¸r«‡³šÏþvºŒ»Ú½èj8äl½&ÖÊ(UY¬ò=y[t‹%ì|TÐÀVuNŒüõÞg"ºÉú\H&[ΆïªMÓÊøæzN>Þ¬Ô—bLåÖ†ÁЊ²<‹¾¤gA„N£J•q‰-¸bUxý‰Õ˜b¡ÜpÒ6Xì|VGo¤TªõL¦î%&X’ñÂYúÓJËFªˆ’ èâÑó™lÏ0’2aìÄБ3ú&êñ‡6Ö˲Hù¬{—u®,Ý<ÑÄìì™ê.»Îê›8löÜE¬…Ô? çå™Ë"7C×DMÌòd_*¥M„‰-?…~æ ¯“Ö=†Êvê±_YŒé7ÙŽ_‰˜JŒK¹‘YØ—P-Euí”í—Øô=Ú‘1÷ÐÒÈĘ  ÝÏŒεÏn´·¢ò«¶/òœ…-Óùñ>Ù‹näEérYµB¦ˆ*»t>¨Éï¤ú|™á²†îpikÝãt•îpõ¢šyôF°bÕ±¶zW•.Â¥iìðEȼ{-~~6HeP=¸Ì’A(N¢ÖÈ5_väÞO;†Ùé^ô>ZlϨd}uŒt‰ŠäjÁEø4h¹{35rtÿal…YJm-íã²°Äjí2aç`ìõÞcóÃqbIã{·"žm°Aªz»kjx7.u~Kq¹a+ÍÈ00½ðšk¤¥`|sè2×ÍgãAë'ÖŽú•ÍÇu{ éæÎ"|Ìú|™”ï×Ü’o Ð}þæÒ™úçPI O„HOïSWFo±¨WÇNíÙËÛ'ްßsÒ4-–ÃÏ”EÛ‡Ýà-‰¡Éî{¡V>DÙçF/`z@—Œ+¾Î9ˆ³Y[P¡« ´¿’ÍZDiÚ»£:™VèüÀa«Ø‹ñ“Fõ„Ü ¼ßx¤CJ ¹ +Z¤²à;70úŒÒõ)½ mNÛ<]-‹–ð€m>×M:%¿Õ0‘ ÛÛëÉ÷ºŠ ‘©,šW;c÷¿„¡·9T‹'Ï»&ˆ‰_úÿýªXIû: o_¸*x–u_Ûš§½t~Dr)Ä6‹{–/Ís¾Øžšæ#¶Ï´9äYל»ÛîàöÅÑþŒ2(֚î?oªŽçmåô%·oÌ%ß§˜"8¾'ú§Ï˜)—aØG{)—‰¬º´l\htˆz턉2¼t(GL'–Bù£þ`?*Gï[1ä@®éy‹1º9»Jø©ÔUưXaÐ95º>FªÅ…µ´ìG„#”„ÿµ%^þêElá¢ä‡9 › ßQ¼ºqÄb…e½i»Q§+ëf_4ŦÉr£û>)wogQäPUI—hñ£°=÷ùmB ±…¹ƒÿAÖɧ„ó¥•nƒ¯Uùæâ "f(¨¿™úK Õ*8kÌ<9й?9¹"2,â"©½¹Ï8ÂXû êð>„!{å6©“Ê åæü†ÂÚ˜õˆl™êS賄äOX6´u‰&´•‹ è„ÆÇßÔ=;™‹©>š…Èkróæ í¼H°[+~”Ôì«o|VÔ¯[&}‹fí‚øôœÃP=ëY«j¦•n7U±¨ÄvÚÔåOwW=Ï÷,ŠôË'1pVHP?0óbÍU×§féÞ{¤â'Oc.@—æ­ÕÉÈå|vSŒ»yÁP£*ÛÌ'Ù/Ó‹û4I¤D®âÆíU¬ø#2•…Q¦”i\þáü”EYîÂÆÞ|iª ÇðvŠ&Ó Þ]ö=÷ü­Û_…¥½=Z–Qù„¿#Ycm]—긱G”èÔÒ\Íâ5±ŒÔ¯¦V RÎ tÇÝÉZ×ÚVLz‘”»«k¢s-à]´„¬Èýl¸ ˜Í·Ÿ¤×mغ87FÄŸ:ÿ ~Ä}eô#[‰Þ£¼YŸ¬ËK¿4­a*ixˤHœÈò¡Õä[âñË‚uwÀùÄåÞ¶ÇY\Y‘ó·Š ð®P s;Ž˜´f~ê ƒ‘bJ+àžB÷.ŠNiQ/ÆÑåSÍTk/¯J.Gd‰?/Ù³2y<ÿ²ÙæKÔ}ð­:‘„ØÄÙ7ßIg=‰ï}âu¬ ‘0ˆZ;N»î”nÕ}qw×bæR‘”'I}$þrÛë{WÔ´ùcäØQ™EëµÇ+¾HÚü¨*­Ž%•j¥Å¾3ÊXË•§µz=cº3µ#êš4Ü8‘½ÖÀWu]»{îMžè„eIPÿ •±É­îÏ*\%ýöTYñ?n6CtB"''ð ‚&(N> îø¨ÉFšÎ PòS_¹Eç ‘ÓÅHÊx';,`îÌ2@ê=ý.$¿É-2½c.\™–\¬˜“òéåböDØ6ˆ'ÜL(pÛ.”P“[¯G‡M¶‹—l…*²¦g•À{nlÙ‰'¡luP‘Ë£ú§nU§Œ*¿P"•çjh°x¼|¤C1 Ä\ïxÎz%4ß`²/y¼(ËéÇ…¯-Ûs]MRì»…#›òÝ~°ãMÁ\6KñÔ9ºMú4à2B[ÇùÔ[nQØqE´¬(óh.kðVa°³‘®|þ]úyJE+Qöáå‚™êJB• 5g2¶­@ï~Àß1wªe¬6vØh żb2kú:ü× endstream endobj 650 0 obj << /Length1 2001 /Length2 8651 /Length3 0 /Length 9756 /Filter /FlateDecode >> stream xÚ}vuXÔÛÚ6 HH‡„ÄÐÝÝÒ%]Ò 0ÀPC % twwJ7ÒÒHHHwK}ãÞçlÜç½®ïš~÷S÷k=kh)Õ4Y%, f Yˆ”•“Cåô€BÜlh´´RÎ  qBABN.vNv. CB°5e˜™Ž²« Ðê·€‹ŸŸ‡‹`6‡Ì@V`4ößñ,!N¾¿å®ŽÿÕ¹œ]`$)#Fiq°óX€,a~®vv*@{€á¯¼þh¶óüÿè‚ÀVÖPƒ2Èìjÿ¿Z(Ðl.á`epü-»È‚=@j`¨¹5êì ú[¬í`r¶;€Ô .àß-°rrpüNËlnërqðþG¥‚Ía¹éü§DX…,9µWÿ›ÈÖ»ÿƺ˜ƒ ÿb Ðß®ÿ@ÿÛXwÿj»„¶®Ôk 濇ø—NÆÁbv°pñò€ÎÎ@O4' ñ¼8`Xî¬Xv6æpt…ú,!Îh¿gÄÇ ú[ô7â°K>"~»Ô#°K?"A»Ì?ˆŸÀ.ûˆ8ìrˆ À.ÿˆ¸ì Æ®ôˆ`쯌]ùÁØUŒ]õ$cW{D0>GãÓ|D<v­Gc×~D0vGc×}D0öׯ®÷„YÿAœ\°0° ƒa§ÈÎôœ‡ë· r»Ø>6–ìªý Æböˆ`f@s[; ‹õ£Ö[3g˜µYþáËýÜù¯+ñ–¬ù?ˆFa±ƒÕãù-±·ÿ£Ø9d·øÂ( 2vпø~ë\v¸Àr·|tåf vû#Æo5ÄÕù˜‰ÕcD˜Þê÷nýiKô±<°ÙY{:Zƒþ°€ÉÀ@X¦6@Øœlÿ€°N¥œ°g€ý1/^X PkgÐ'V*Ôò‡,†ëã¡…qºþ^».æç?ûšÛÖO÷?®,¨ÇÆêù˜$Ìõ ÈùoʯW5 تåéøÏ#ñ{ßþ…9ÿÆšPgˆ-HlµþÓD»kl°+Âñû÷ß/£ÿ»¿%%!^¬¼°w¶’8yav\\>ÿ²3wu†ú×û {þ‹-Á°ç ò™£ÍÍ@Ì…ƒljƒÚ®ª%^¸³nŒ>]þÑ£× ¥›Íñ²~…œ&7é$ijQA4œ¬ö­ôÝÄŒ÷ ¦ƒ«1¥$ùl(œLßšäkîàõi—ˆÜBb5Οº†s«N†ej€h@¯;sÌßͽYù³à®ÃeS_p`(ºÀ¦Lz”ÈêØE×£¤ùÒ3ÄŽÂu6HqÕRпCâ§¾SÀßI7|Ç'4dÜaíô%Æ[‚Ëò·Û:½üÑ•èÆUzz¾Ž§Õé~ièPAjîŒ:*™q”ã$÷JI¼zÒ´—=¼Yħ±”©­ `'³MŽ]¥qP¥ï>¨‚»—º¾6nS^×%~w^\E¯º2P pê.¹ú@Àö98yÒÙxÏ=ž‚³hqx…G â7?¼ a/ÛÉOHS‚½Ù¬¨Êm'l¹xú¥”ïR2¨_º‘ÕøÔ÷žçlÆ® MîcXιÁËŽoXGEÖ^0éµ³³ C¹uÎxçn%A«Bó‘ßlÖâ–Ÿï‘i—ùöÀîÅ|þéá4,º®æ¹–˜<ÆÀÐóÜ…k’’]È/qÌkt¯wÇèçᱸÔ%šCºQUUÞSèôæç ~|‡ãÎ3èˑ͎VÐùÎvM¸·æ†ÓÓ¶ ÕÍ›!ÞC\æä§K¸êâQs÷žzl¥TE“2•cTV‡ï}¯äÔÍyf£˜3÷úËn3 Ýã›c°ã0Ó¨»[wŽ¢’ßl0:4‚)i „Á#ЦQ“X=-µ'ú+~8z"1BúñLºx@βm±)•g¿4«Þ[²pÝ9`¶ìUñ§]+ØX«Ë]íàrÆí9ŒJº|©Ð;ÊÙQ؈wÏÛð¯Ö£òßü9Š_ÞKýì^œ¯9Gó#"^åö莎yº!³R|試Zèu³ªR©3¢c1û¹[P~ʽUÉñDeÒšRá,žr 3¦à‰|þkAZú¼úuW[DJ+uÆ'IÞs v[DÀ=´,ÔÒeÂSýM ¶sH*S\^Æúú[´+ý‰àïîøaîƒ`Ìg=ÛFyº¸­^y_ W¿…ÆÜü,ÙE¥ƒ ôÂpC夃z’u–ÖÏu ëZì¡ûlUì~ÕëôoSlV:­$ýF­¹¿.ä9Ý œ®´cªù²2I‚·r­¡fve“†BW„Å9×GÏTæl;&hy…tû]¤è)`É0W¸˜œêœÆMâ–ÅÏ·ÈlµêG÷£Iry5„OÕ&넌î@2ö!käOÔÆX]±çãÊâþ8HÅnêÇD¾õí¿2!D>¹ÝÌ‚­¯¹ÚÏ¢Qìz{ÎwædãÆÄÒ6›ôržHQ³ž(îý4š÷êÏ%üµ·3š¥p8ûȳ¤SÆËx.؃‹²ÓàŠùlñ³Þ‹¸Ò<©.&^¸"K„ž˜`GS7ßU,.]ãø;v»8KñÝ^žÉ0ûjÆ ñþ» ZÉ.Fô!>5…*“l&Ä´|`(D£¥®<†cùIûâ3C]]zKЀ|q͈þÖZ‰Ô×±jøZ¦÷¨Fã÷Þv扌újÒÓ„«±DX/·qÉ…ò²ó8¥éõ±”h Ñd© ³êa¶dO›·v õøY—ÅŒÏÕgñ‘Èè2zÇ©œ†±Þp%}xUMb2`¥©îÖ:îbÎ20Z6›6Pq 3ˆ’§>¥Í‘fîy)ì1 b(þy1)BŒ®r´‡ÝÜ”œ®Á˜¡·u€YêÇtàÀ¾YŽ-áðñH8¥@oiq¡³çãý—»_«}{aôXàÓ=Lzj¼/èGµ!ÄÉšŠ‹¿zƒ˜§£ ø{.Î*5É8[Þ,g']¢Anjù?—o·N°­‡Ó&ö„ذ$@MåFG.Ó‘¹—;Ñò¢¸…6¶»áά‰X´óXìðö+Ž›<—syJÇ Ö'[¸ÆÈ!j!†7 p)íñ™PËVÄiñ—…úÐ:ÊÃ#cEwNŒ¹;MEà»Â³®›AéÈy¬ I¹êë&Ï/²*Uú²o&zïN X#q·ÝÙ©Ž,”ƒÍúWhý¥:…(î°òUB)Šž íú®DÄêd&h’Tz¾#¤¿wZæ9ö?Aëe¸ÝÄ a»—K–ÄËù°þ£\ò'„ïºÐÛHÀÔ§zƪȨÀÈÑ rGi°€‡Æâ;'òe·£t-½­Zšy!%ò b£ Áo%(ìvì}7{Ú\é".P< -X E@U½ºÌØß³†BÎý"ÎE«ËÅø>ÝÓ“ÃÄ(®Ïò׊@ÛVävÍ~q™òµÆðþ0µmOMµé0`è<þõÞ,[áEpk ©Ù[nÿÈãŒýùÂêŠ íûu5¶Ëž}l.>]‡.Õ²ð-»¨T]’­Š æ>ªÛ]Ÿ…E7š1$oâäCôÖâ_§ÈÅR&ËçJ06fí¯Ø×¨Ù]L+y×+”ÍâýâÄUO nö7 ë ›W¼GÉêàZMëžÝÕ5«¢KìJ”¿jÒXÚèFËÛJéÈQãÞTeïà ï.Ç;¹¶Ñ$Mìû~Exg\PXžXƒˆ—¸V7$ÕPFg+85!·à(K‚HH£×neÎÒ>æ¶ð–Z.ºÛXkœ‰-»aMLÀF.áFVÛ©”R—'‡ï6+wñ~6Y·†oÖ0»Ù,ê`CÆÖEV€ôjä+k< ›‚/“vÌÜ ]¤ yÅ6þ„÷ÊðÊsˆnIñæ[”O4åĵ3ésµL'ùÏãßì `J¿<áSª4¯Q2¨–„@õôR-Y;´€³¢oƒãý…ñ,é ŒqëôWÏ wBâÞÅq.FP°Î}’ b³âMʪ þ8ú³Áë¦izbIqd]Ù4ú6#"Î!ÿ20ö]™ÓQWÅ©ƒûd…ÌÈÔÐa%¾POªÌýPáÐÒ“žöèQá˜/Ó«ud‡+ ˆæ¥-Õ﮾þd ¾ª l mûF¢âÈMÙÖzŽc‡î)Á|Œc¤~8f\„ÁÇ©D_hÏâ&NA¸¹ì\м½™©Åêæ™óÒù³^l‰è+¡î)=¥Óý†Vv|› ™´ÞZZG;‡WéïAˆa>©f'%YAIJÌ%^Ý(Û c{îa\1«Ft·¹–i-)t%Zéðˈd¡9¯Ò'¢"m÷øûb:hIÆžÊHêµv—ÂoW©Î^¯g~_AÒt`¡¯èD—^š‰÷œ?"øð:ï=ÝmŒv‹—…¬:ÕÖËö,ó7ªK*X¼;CU1²ÑLÕ¢§Ü¡Qµ7Hðþ#$Y"-—ª{xRˆÄÓf#h©¤|9¶Æp"çƒÂæ¡ïϱ.2f.ž°m ß=ßž1£„¶¯• V”¥®Ø FxUOž¿|È›D=oÏ”8¶>OÛ63$Âîor¯½ƒOvWàfŠÈÝíÝrÕ*.‡÷ÃE­KÔ2h%b?g>*láøî²‹uÜ*ž ¾Ò#K}ÎG´ËÞÎU–Lþí~ßGµø¦P´#v 16Ú–y/CëÛÊñzqümrÒ Ò§¨ ’dÃŽ©¥“ŬÝ[Í:PĤ_ßßPÁƒÂCàü¯_'L=VȸôE<êòoöžÙÒdî{L­Qe ÄŒP§ÞˆzÅ[7­NtÞ)&Úò(ç¼Ê/†¾•LXø¼¼ì0# tÇqÙ^,á÷mç·ŽøV½'Ue87}è¼rœä¹|‰ Ï]r$¹…HæÃò¦—-áÃ6N%¬L$§; ½#¤¦;%­Â»zk;èÝd!KbfŸ«¸ò’à Em¾Á>«¸©cqZ–ópD¼p{ô ÿ%õ§¥DÄÛgéT6dlµZlÕyÔßÚªOð.á9t®È¾äóQðÕ•_Æ/§Lm?©î¢N¯!ËHÈÒ•†Îöê­¹ÞÕ"áÓx²àèØðú]6&g÷šjgJ} ò‰lˆ‹N/vÖV^÷®#TOÌìÜ «â `’KO\lí§T?½:°œvº9»ó>u…àí¬’›ëÄN^|³¹2p™;νŸF°zªÍŒ×½wTÕ¨3<" F£½¾_:úlæú“Eý¶ƒ« îâ¹ñ¼d)‘®ïáSÀh¾`Cï‹äyÚøþvÓ(¥ðÄQáVi×´,ÖæMîaÚµ«ô› ñ˜ŸB;Ü+âB)„½[]Ñ ö¢Ý8;Õ+Eµò¸-'òA°,oõ1vžˆ+zf°9B¾÷KÅ– ÚÚ`먹 Hb|Ô›<Ã.–o*R}K©½¤¨4)‚8¾¾™Îuìôª©9à>áp,­;uþ½ýk„AÞÃù´yÿ[ú_FÈ6ã‘>*^ñßê9_qS¿œëtë«.jlÏÊnÖnXÓ` ÊëiœëEÿ2ê#…x##<£ŒTÊ«Ngh ûÉx§œ™9¦I×Ò0Çgí¿y8$÷žýý×<™ ¿Ž“·œ¥³xw©_õŠø¢'»œ<Ô´R].|óûÑa¹¹é3>PêZÓVGbFäá4bõÐ0ˆ8oÆ‹Â÷5=Ó#Ü’F3¯%ðäS0¦Òò.Ê7—ˆ»/ÏyƒÝê[«›S€ÅŸ–#J<ÙIzXø9Œ7¾/ãàé—¯™E'%˘ÜÌ>lSº‹Gsgöž¼–#¾c­ !o¢ž^â!ûY ó·=½[Œ™G¾L’èð%(=Z§'Ä-¡àáøä¿'ñX$šnr¨ËÞK„‹²Â…gkˆJœ ÙÜbÚ¬­læ>»è°ÐQ¶£Í¼øþ˨êó1ò}$ œOÒjTñ±9Šál‡ãVs³-îõgú]7xÒËw‚ß·¢m ®Ù 2l¿à¢~¢ñ:ÿ$õžÈ“̾¿]ÓdpãýJsºÁSMºL4b„Þ ê›{ù&@öqsC7”höN3{@—u•¦dkºm¹ïÌ1ÀçüŒliŽnfïcç½¢yÄ[ÖJ8ùÓ“¸ÆâœôLèÁ…÷¶˜“þ¸pò ûé͈Ñûb߯ßUÒ(SNúf¯§ëõÚ¨%øJÐ çï¸à|QÌ+ç¨::ÞI3‰o%[h½çOÊÒñ°¡ÌB¬ª±l3¥ ʘRssã8'S¶³‹%÷º½où ý­&Ϩ¡dä:Z#_g¤u8CÁK¶},Gå……wŒÁôgT¤Hêä18¥|񠮾Öãý¸™ªòŸy;ŠÖiô•M íVpîïñKfI*Ž^ŠJT€÷1ÐqáÞ…ù…’ÈýmÖ‡Ó8 [§jO¢³ò'§Løåë¢.îø'æv™à E #û ʬÅFúÞ&åm›éïWÝ =X¬aXä¸T–Ü0%ÀÜ/LG¾Bž¯Kã ¾½±€§D¥}÷ÔÖà×6 ˆ ï]äŽ]÷¸q1ø.¿I$yf&Cú³ -<Ë6ª’©:öéx· i¥òc^ýaIþ“!,ŽáA=£Ôžã´Só†oè=­åhöì~SÌæO!§»´‘wjDR0s¡2Eg#1=ÙN[µº§|?é¯^šs1´¯\œ­(g3(¢º ¥‘ 'Xz‚Ü«Ò6\‹w˜vì<œ<Â5DÕÔšC¹*1ÈÝjãõW=Ü’ÐÆŒvã‰0ã]qèÔÊZb_ê.[d¼ ³t‰ðMg4& Nkƒ2¤H=É4ÙâÎ_ ®rØl‡L\0’f¨QñŸKX3)~[—5‘ôÖàó.)6K'çÚZ»½Àä}Wô ôyxBì5w4ªíöÔÛQ¼»–Q(þkßQ›ÙäqÕÖµäç$ãÂö÷HîaÍDó%⺉'þ0:sÙ¸‹zGAÏŸKÏW—§4jЬ}þ®'½9¦À•h„Vfv8§ƒ$+@i‘ˆ³rªh7B×gS¡©c,¬Y(Ü´Vh=?XvGÎ9n›‹`‹¡Æ³Ÿnª‘A¿ÆÏ8âDg­Õg›ÉõcSË&¡ž‘0¶Ï‹Ô]÷´iØZ@²wñ5Æô«$º>»öeZ$2 RÉþ.ÓjÕ2ï龡œj·è§îŒ&‹îÒVØáxSl:ÝiN9iìI9ÀT˜«äµ”óq‚Pu{§‰å4§vz¾Gë\g"¿§ ÍFоç›ØèI!Í\7 Šgâòxª†)Ó,ÿŒcŸ’ÆÄ¹)ÙÁkÖÉÓ¡ôîPŠ}ýÜ7J—Ϧæ\BŽÐŒWÊžýê2´Xûq6Àݨª  L{%,Væ]ŽÇ€Ož7æeQMË*Ç5?ún)Tà…D L§óÏíŽÙ‰¥Q,×O­xZO†Ï„%jôàÛé~.u@–=#Eá#¢ç¤úÁ©¹t0ø¦¦2Õu`ŒðŒþœÃ·?ók’µå(þÌvŽÆâʦ·„pßò bnK™–—¶ÝÅK?¦Ôh§Gl¾õ'4äÁCù),×RnÂïÇYíqØË}°6÷C/·'m]¶L[Ó~‡ô ñw°)o¥R¬MG’“FþV˱bhÔt…c’H¾AJÔóÞÏ 9ˆÜOÁ’FPi‚¶Ez€rà@¼†²òÑ–2ª/°Â‹ÂD³4Æ“¾ª38‰dXЦÕ\Ö“¾DtüöàÓàId_ä÷wÖœ%#¦1¾öîöèégç8Bå ˜ÂÉ:ØÈ ¯ÖW*x²‹­&—ýˆ)RYy¶þa‡rÉ´UG**É:A<*nÒIxŒC/§ªÐxšfˆÑzqm§…2µæD 5·YD›ÓxÁ õ±Ö'¼a(™.nï“kht£:44¨{ÎE ÐJᛋ¹z·›ÎßÇ)="™>!¥÷ì°ëÝ“¯{6 CKÜü½(2#…ÛükìDŽÆÕr‚/ùiå6ˆ.GM½5$‡pF𴯼LgY´çôšÙ.ëß§9ˆ[»ÿŒ*6Q(à„–Væg 6«Æ^/-}*lk˜î»RŠ@òjX`kÛ© º ozùqmƒ£ù®ž#r/êÜØÇÅUœH2`"Y8¤¡ƒ¤XµúfÍäF˜Z`§7/(ÆtÇ[’ùMÓ—ê «r=IšøžÕ"_ÏXáÐ^Éè¡Lñm£s«€öPid9Y{y¦üR¯§ˆYàÖeÅ"c׫wš¬’úH¾£c‘¹®Órls¦nVv¯é˜SŒc  &d;ž)¡L ŠŸ5Þ5ŽûËÍp ¼Ï {õ!ð< ¾ÝØ8zê[…ë|a»…*4%ž/q°°Ö¹±7‹½3|ùÙi7"Ö&_ž„+5*û.بQ"ÿ‰G:†Iõ.Ùj²ï5/ÆHa{g²‚xRhÄy•lP|ó4Ÿ`˜ÍňçÏN<C9'½¯‘¢ÐçÝ£™Œ_é$á@t½8ÛTO(ýIü÷Æ€¸ ¸ñ/Ù¥{PÓ"cæE_­ž½Ví !¦±èϬ¨é‘Œ·B¥÷ me_6~öfïòHDìÉç Æââà‹,&ª1ç ²P+èÛ*úw}*¡_÷¾ÈP"­F›P®–†ÎAÁ%âÛ|0º—þ®©Ë ê’.g4_ ~wiÉP¾5@€¢Áo&¶ò™´Û˜û­Zw„oè+ÔKöª¡s{©Ìý’5œ“#n¿}i2“î3€¡7CÛvÛ3‘ ó!‰£ŸB)xßòètÔ„œ·)Ah>2¼÷ˆ\?¦)¯Ô/£¢iöJ['% HZ±­›Wce+]xqó~î ³.±•½Y ©™ç?•;{ F=·ëkfŽ©Ú3n ÖDð6Þkí0™®c¦—æÄ¬µŸ‹ü-cR”Fžµ#Çæh½'ÁØÌâåº"s¿ èìHSs;·Ã’К:äòGZç!wùô0¬4@oŠ6‘«I®º?oø}õØõ²!Îd_&yÊ™Lùy‹8v]•¬.¢ù‚Á] G4­jƒ3jyè‘jzÚÖö æÓüwùT‹8_µGõ'%à÷Ðʬü•C5ߨ8%ÆGºbjrž%¡5ø*GÈ ½¨z“Õ€Ÿ&SëPff³Óôಆi'ì¤1Îÿ]'ßq­qÜ+òA® ùüEbiðΉ5_§õCNç7K}mãMeê¬*¬|צ냸õÊ'1ÊFF=C‰Âõzô–E(ôiÃu6 ü÷c^†°Ò$c±ëqhw|ºCxŸÂx4q›(3¹h1N=gÈG³Þalž‚±†g6ƒmmõ5àÄ7{ršÄÂkA|!^­Æç¿t$ÇŽnøFÜVå®o"û¾Iž-V‘èŠ{ï%FÕ’@¤„nÇSÖu PØ:ô‹MÆôèÏŽ—Ê›Ü>òŸ6rñ*Æ.4^ä™{Q£"ýj›•åÁéRÙ“ŸÅÉb 3¬>½ÄC`Ðé¸.Š¥„"œ&£K´+‡·¬4 ¤š¨­ :eNM—\Œ»m2™~ãW ¼ÚÙÌ{µý<–¯ä7UÅ}M¬•}Ÿ¾PæøÍ,‹‰êü$…e×å“ñiHîH¦¨Ã©$jèj8ˆÃmH³”Ü€wó+©÷ç— Ð—(YÕàÞžµ9{üˆe~d|RËå/î ¼³pžÄ=BûMGÆ)·¢IÍI;Wºzb×DŸ#&ÎqÈŸál]ÓP7,¢aú—™%ˆË¹ËðÈŠÓÎ38ÑšÍsý8fõbs%ó¦d®M_/Ç8bèpµ95 ìvÓ•i>¡nQÏÙ6ažÙ,ÑVÓ ÐUïcu€÷ / NµÉ3Ãßõ(š5n1m±“Ö›âV C­LÌñЂãá…¯H­jD׫&ÕX3œP›šu[Šõ´¥ÞøÛùPl®#[¼TÚÝv7jõÕo–ý9ž–Güý›^ûfÂTðù¼gƒÑTŠÉS%£(`‘LQ@· %sñygÄA8cZ€ÝË¡øŒ}oøeŸ¶>éÞQ2Që+íöë“ÞF±Sª¤ŸÖÄt˜xÛ,¯wJIáÔIáC2v¶%æî OŸ©ÊL-ŠýJë÷ýeU±ÌÒ<<ÒsùÿÂk`i endstream endobj 652 0 obj << /Length1 752 /Length2 723 /Length3 0 /Length 1255 /Filter /FlateDecode >> stream xÚSU ÖuLÉOJuËÏ+Ñ5Ô3°R(I®()Q0Ö3àRUu.JM,ÉÌÏsI,IµR04Ò74Ñ7200PH,ò¬€Œ_ ²0ßÒâÄt ##cC#c.#…”Ìä…¤ÔôÌ<.}ùžyiù †fñ”Ò˜\YjQ1Ð  ¥š @+Sòór*RRÓ€úJsrüsS4ÀîÂNÌÍ̩ģ <53=£DAÃ75%³4]Ö³$1'3Ù1/='UÁ"”Yì–Y‘šY’œ¡PRTš ÍKI-ÊÉÌK È/Ή‚®¡š\HFfrv^jq±‚)TÊ/¿$3è¶0¨>ÔQpðAwHj.0ì`æ%'§æ•(XÀø)©#¨@j^ z0Cú‘N>¾þ^ÚH˹æ%ç§dæ¥+™š)$%Vr(y¦ Õ† ™@·W(¤V=«¯——_Ô¢PPZR«–_ÄŠ#cKýÂÒü’ÔâLp0%¹P-HÌÌ+ ©,€!È5`¾!„\R”Ÿž™R’¬Ä7±¤(³"Ú@ÏÀÀ(„0V,¦ïœœò+ªuM-€Ána + 3`ø˜×¢(L.-*†8yÃÆOË:;5µ"5™ëæµüdë–¬M-{~lp”.×}z–íþÃ}"v˜–¨]_PáÃ>ËýR¡SBÊZ‰ÓÓn¬l»x­FZëÝs1ç4Þ›æ1¿„Áõèc§º Oþü|0=U.%_*ý¼ùôÎÇ‚ï'Êò'D³D«O¿ö§ÕüñóuÏ–üÝWü<ÊòµB®Â²oŠÓ¤Kzçí{ÍÔ©¨ò°äTdŒ@ŸPQôŒÒÏÐó™ZÌ•ÿzмšr>¦ÍÌêŒUãü²mÊ\ÝmI—ß–Üçè{^³øë³ù5gxu¾z¥®ªNš~©.í­;sAæÊ’~·8Âçv®ïÚZSùîø…Ì-íBE9oöÍà=rî\á9™«=ÿÏŸ¢ÇºáçÙz¡ë§y. ›ÑØÏÚS4Ža{äêÒ‡o®=‘±°Z9èÖ±$æÆäŒËØ8|™ÎË?õ42_³\úÉãÕ›>+˜ž›Qaec°¿úêëe7 ß)ú¾®fÐ Y[X‘é3_õ¾÷ä›J¶ß|–ÐN´uXº?®ìê…›'ø¼&Om)jýÞ^¬ï­üxWé=÷v¦3”<¦6Ë*ëŠ9b¶»ÝµÜþó£+ÌÇïGÖÊVOLˆ6dcñ ²?pNù.G‹&ë-þ_ëWöœùG³¥¨RwHÝùÎP‡W9Çó~É|Íœm]÷pëíCŒ¢;V_Òôe½§¹iæúeÉæ8e‡>GŸŠμºR\ý#î`!_‚¤ÜËã·ªüäxßÖ{¼£{âo­­Ü(†I“çÞvý|c‰¦Åì¶ÿÍ\·âO7§|ã Wµž­Ío“u4æŒ(Ï÷k©NYê_ì×{³°'øôq?Çgzª;ÿº·³MÝÊìVÏÖ§~Z3‰šü&¹Kèá_¶¨ði®÷El³lŽºéJÁëÕfm¦Ììôšä·›YFlˆì{“ÕæTŸ®¸^q$1Åk}Så¼µO?ñ¬³zÍ!»Ò¶íí§‘¹ÎÕ“ÜnÙÆÍŸ¡t'Ó€:PW endstream endobj 654 0 obj << /Length 690 /Filter /FlateDecode >> stream xÚmTMkã0¼ûWh…öF’Ç.! ùrض4eÙkb+]CbÛí¿_Í{NK—bÆã÷1oò¤›Ï»™©Úƒ›…÷R¼¸¡½ô¥›¥?÷]ps“µååìšñѹÊUׯÃxîÛrçFq›n³mSw>xÛ”§Kå®QßY÷V7Ÿ!è#n_ÝïÙXþÇÙáRŸÆº™IľÖãÉÇ|÷YxN|á¥ürýP·ÍƒP÷RJOäM•¶gÌ0óI‡˜_•ë¦ê'1âiÒ¢ªËqz£gyöf y÷>Œî¼mŽm°^‹ù‹ÿ8Œý;)¼ æO}åúºy·_”ù/»K×Tl6¢rG_ÐÏþ¸?;1ÿnÀ×÷Î MïŠU•må†n_º~ß¼¹`-åF¬‹b¸¦úï[‡㪖>TEþ¡¥ 7Á:Dn˜ø‡”ëxáq¼¤ ÂhÍŠ"<ö¢a"ñ„E a‘b‘n9ÅcO ÅrŠ¥”DÎDJʯ—««æòϾŸ¦“2Ba©8c ]R§05×Y ¼`e1ð’ù 8bl€Wœ»Ž™§x6ÂÀ†yÈ•–ûRLʼÎØIÔTšqŒšZ%ЬưNc½Ðp^³NY4{¥¡G£¯ÖŠpÊ<æÒì–F}]P¯rCÄèUmaƹèæÌCÿ‚xEõ—+Æðm™³6\0†¶ˆø(Â\1m‹ÖøcÊ%æA¯˜g”ÈÍç\±ý\›˜faböÍ oœ3†Î„=4ÈMÜ ÿ]Bû˜+̘ðöøŸL³ fÂzBÔL,ñ 3&Óìð-¡^˼ao ¼5ì­AŒê ¾µì'|°ì9Åg´K2ƒŸãb5m1m-N"n3^^úÞºZèXã@×û¸}º¶CýèÚº^’x{*‚ž©t[ endstream endobj 655 0 obj << /Length 708 /Filter /FlateDecode >> stream xÚmTMo£0½ó+¼‡Jí!m0U ó!å°mÕT«½¦àt‘Húï×o†4ÛU ÇøÍÌ󳙫ÛYZw/nÞJñä†îÔWn–ý܃««¼«N׎÷ÎÕ®>¯wâ±ïª­Åu¶É7m3Þxò¦­ÞNµ;³¾'Y÷Ú´ úˆëg÷{6jö>úÙ;A òs3¾yÒ·ëÂÅ×  ¤_®š®½êVJéE[gÝÛ‚ù$EÌÏâöM[÷“ñuÒ¢nªqú¢wuð~ yû1Œî°i÷]°Z‰ù“_Æþƒ4Þó‡¾v}Ó¾Šë¯ÒüÒöt<¾9È2X¯Eíö¾¢ßÿýîàÄüÛ=~rž?ŽNhúV¬«êj7w•ëwí« VR®Åª,×këÿÖbÎxÙOÔÔ0ñ/)=Vfá±Yú—–T{œ¦ÄðØ ­â@á r 0,jؘû@†@ÁŒtD˳¢êÏ®Ÿ´K¡µT—M¤Î"`ê¥ó xÁB ð’ã9pÄ8Ž976'>ï;-SŽ'À–û'ã¸ÎÉ…šJ3† ½Ê('ŒúZ%ЯÆðD³N½h¶FCf=tÂu4ôh­ˆ“1ûÕì¢&NI¨‚£C ýaιè‡æ%ö¥ã.sƨ¿,X§.‡GÿœEDœ(B˜üW14yñÓ¨‹ÏF_ÎÂðÝHqÅ('bï ÃÄ„ùî¾vÐmØ; &½xgìå&ò…ý5|6)ö` Æð"ásJ‘›,¸4%¬!Ź&¤AQ߄¶„üR¤3əߪ¿$S>›gcYˆšvú§ Ç²~ ï¬å³!ÌçG¹9ÝW™Ã»’qO ýø—1y>ÇDuê{?Ah<Ñ`ÀHhZ÷9ÁŽÝYôÐè;ÏZ|=”Á_4« endstream endobj 576 0 obj << /Type /ObjStm /N 100 /First 898 /Length 3287 /Filter /FlateDecode >> stream xÚí[ksÇý®_±“Jyçýª¢R…C„—!$.>Èòb+ÈHr÷×ßӳͮ$¯d u+uSlvf¶g¦ûôéž™ÕZÚñL:•iº¹ÌóÌ8™ IwŸI4´)e2éE¦œA]dZÐ]fÚнƒt7Šê&³Öãî2gîÃÒ=dA`¼ 2Á9 hPÐÔ〚 (H%PP™PŽLЙ0œAØjzd3á0—å<AHŒP0(P¯€Ádp™äÒgŠ ,0æ@!  ý@ …„•€°$a aIšSwaË- €­–Æ1F£€i,&´°HzI4æ³…8z(´bô€ŽšR4: MÁ<¦B|LãÄÇ(VO¢»…R¨á‰X^>P °ç  gXê2-¡‹2p‡ÔTp(|eá0%©`P a¸]k[€ ñ߀¦3idô²4»ð™ö‚¦ä_´H8‘Ãv¾AÆ‘ËFµÄÉ©WIoQ°™±–F Öq´*à‘"H O[[P±/€r°X¥3gµ˜Ì¹@2`§pÔ2o `è=Y¡Uˆ6`›¬v`”J¸Éà1C¼sd ‘g¨LH”|0JAó `˜„LRâ)¬DI[K £d5JPM€ ƒn&1*+ ÑÜB&ê ¥a¾¢€_øàλŸ@ʳ—{ûÇŸÐz‘´M¯&“wƒŸÞ&'æÊôÉI§sÏ][îh6]fwîdìHG^•=Ž 9ÙVVli|YÉÖª"¢‘U¥´*œ=ŸÏF¯Šev’±ç÷2v\|^fͼÇ_>x0`/‹Åìj>*¨É•MO‹³ñðpö9;áh ò» ßašá}Á*åRó}b¾•\î£ë0ù6ì–çÔë“Ó€Ó†äŒÍæï•S>÷”]ÜÓòHËW@èYUtäÛ&_­¼xS_Ì]_y}S_yÓï«ý©ÚÂbeþM-|Ýb¿›ÅÈ]‹ÃnìlÉ%BçÊÙÙ»cÖŠuÓØW¸ÞÁí »;Î0ÔIÜ.´;(了G^vU‰ýìÕÕé2ÖŸŒ§ìp6?+æqJþŽ=b¿°{'"VHɬóp -^6ç†6&:7Ï8›í u7âþ*cgdz ûa~ãÙ4W¹ø‘º5œÈ9V9,½9í©°†åQd„Ï­ÖßO!x޵¾ÑCñÜc…ÞEËÛÓ£t‹ð2×~å‚c/·Pˆ…ŠÐNØqÒ'cmÈͦ5¼+'Dît¿œ1Ð_¸^9€ˆÓýrXœhÛ'§BÈòýrZäÊ÷'¥ÃžÅìŸà[)i[æºa~²ÜuóíÈo–Ÿè¸@ºÐi¡¼«ê®o3?U‰ÛÈÜcsD.pzÁV>ÇNþûÅ#è&ŒkÔÀþ778ºì¦Çmæ'…Œ®5Š‘kRl'EÔ-*bt®q.h!Ï€»(²ž¢èºKŠjËmNQ]k|.6„lW kî7¤€59C©¢_7°”lHQkrp)™¿r_ÜÚÊ|}ªf-UuãTQêOgüò^¥!o+ƒM`N‡ÝzÍÔ†çJšï¾•Q)‚ÎêeÆR§.m¾{ƪը3Önz|ƒŒÕ(‚ƒ0v'E6$ ¡wK-9™×¹ª_NZhkzåí+f}r2°°_?‰$…¹ûå8v€ÞîŸ,Zçžm™ã¦ÉBʵd!ùM“…pUrðÕ=Ü~’°ØXÓ›·:IXl¬5Wß=IXÌo½n¶5ÊäÂ}Ç$!茘<×ôÞyE6§»gKnË*Þ‘ÙxÐØsC}=½O ²]^éŒ@1œÇA ý€2]ž^Þ:_¾í®®ø ÓHÃcî2uŸ¾«ÇñÕç"³]s9)[娇/õŒí‚Þ‡ò™Œg®¦Ù•ÖI®î߸“Þ•]õüm¸´Öͽiǘԧ¶•î¤SÄ1µ^§ã’Õ3#êTŽ÷ÈÓú|¢ /ËÙ¿øú÷[ø¿ŠzÅF‡<ë”j†kÉ{£Û:óÕÑMcԵɛèk¢»ª×õ«£%f&Õ’­ïu4Öõ(GíUF«£îZÊk£;µ­ŽîºÝU}·Fw5éH÷2º«R3K} ÎiiRj•FleH4Vºx5Žâ¾? [}cG5© cÔ©¤XK½5¸©£T•z»i¸qL' Ó0~š®Ó4¬mXÙž8h- §º§ixGÅ`H]äÑŸÊžW!S;ÉËF1:Æ­ÖJ¯†QÉZ»úÄCßr± Š7(7ˆV œ«©K*Ó³}ª×r•ÇÒq¢!é ­ÕÒ‹vö¡˜Jžuݤh.ÉEã«Þ}W6{õE¦d¥ÚÂðIÙÌ“f™>‚«’kúUåPe„º½žnШƒ#½«*“Ñ•ÚÑ£=LAë}LܯY S·PøÒÕ„’Ó+öVa*ÓTB#xÝ´ýá7ý¢¾+|Þ%§Úžß/£ùøãr6/·ë¿ /ñäÕ‹7‡¿¾úé¸xûð˼xTÌg‹ƒÃÙä 2“áù"Ó¥ða<8%²ÅéçúÎ@”os#:@:ép~|TŒÏ/ª*ÍIϤöËr8îNÏ'EÆqFZ—o2¡Q|[u2T¹w1œÓÁàv—²{ì>{ÀŽØÃxlzÌž°§ì7öŒ=g/ØKöг×ì û½e°?Ù²Í./‡ìŒ,ËÞñïǙ˜³ vñåãE1ecöMØ%›²éxZ°›áÿÙÇb>ž±OlÎlQü ÉÅø3[²åż(ØòŸ»b³Øööc ÑÑfYeÓŸ_ûÐ ô¾^G¿Dj‹tíÍ£TêÓö¹ÎB®¼ ¶zá%P-€S§„fA ´íöûØýçÓ§6¬;.æ—ŵ´ó&kúŠ…˜,üÊdëUjr¬®LæzíTX¬­Øv›Iw:œ³Óùpô¡XNŠ÷˺<ü#FNfÓ’‘Ó³á₟®†ö~EÍÉØÙæäÕô¬˜/F³yéù™ºNQÍ÷qÕËg‡ÏŸ=Ùàªë8J?•ÐG`Èñk;™pT´8j¼Îa$]¹L¤.Ó!uY÷„o„”P\Á7j%Xk}i##÷Aæøññƒ÷:ȼ,ί&ÃùKð˜¾l-`1Iúä)(| ßF`.4LOÞüµ—ÂÃÅÄZ|`ÃeBç¢!sQRy+ÇO¯&“bEõn ..ÚŸG“á%¹Šþ!ˆýkp>/†Ð) ˆ¿¶„½ÂŒ*ÅR©P'Ÿ®Š½'Ca¶,ÎN'Q²®”±Vˤ9.íX¥ÿÅ„ ¸QÀé}huøìøño¿thu}°i° »oú†•>ØàIv´¡lTM‚Íl 6¯v)™²ë8õ<2è ¸Ó‰¼èÃóÍ>ÛÅ]½I­±{-·ÏŸ½xúæÍOKñùt¹Ü ¦ô´P*ú9—v¥iÞâm(M ¥°nKœ¶€ Ö ÒGÃó-…å2"Ké +p„çŸ6{-¼w_ÿ~ïí]B`Æx²Ÿc×+û­³-û…ßßþ¯Yg)EÆãåxrV¬e«Ñ‡2<{—ർԬëýáÖÄ3)‹Uö™^]ž‚™ãó~fHiB*SOg¹k‚馳×zþÇá“§Ï~ýi9ÚÎOдl#¸»ùåÔVßG c’o³a ~0ÍÎ Š Çïß–~Ø:öšŒžIÑlµâÒƒcT\nÆq…)ªµùt ØèÇšsØ{T4ªèQoŠ£ÿÈ=‘ äÀÒ•‘V‘`ÑÍÑá%û"ê…¦ZrY+k6 ÈÞ·´o:%A‘ÕŠ‹,˜„c8·òy¹ú«µ‘úÔl¥V+^²S¨÷ qôw»ùQÙj÷ðnÄÉOiÔEü¹éº³k‹þñkþøÛæÑx¾X 3‰ìõdXU„ĸ¿Ï–‹ø'Q¶Ö6~¶[Žg¯§ðÑY‘‰Íw²½G½®Ê¡«²¶©Ê´T7*ëo¢òu§´Ž¶Z¬,ZëD[õM´í?¨tuV»“B~Rô!º ›®Â¢E ™RB~…¯ßœvõÝ'êÄ7Ñ·»ãëj¸dV·‚,$· OgÿÕQǬE‘j©#m¿u:›®:kB/MuT ŽíjC`õýãAµB%xI¿F0·®³Y×™>±YÐ76W´ n¾—±¦2ùñø ‹˜òåWªúc]},£ËYp†ªÚËw q¥û/ÖI^f endstream endobj 657 0 obj << /Type /ObjStm /N 100 /First 862 /Length 1854 /Filter /FlateDecode >> stream xÚYѪ$7}ﯨXÆ’-¹ !yIH²oË>ö² „l˜™„äïsÜe·Z^µÃæaÆU·­#é•OݾEèHG9õ ”a:¸¯JGîkã£`UÑ£àZå<¤Ö#×óÐ,XË¡­ß§£Ö|˪ÇYÚ‘•FÀÀ~Jĸ(¸Àî,é ¹ %³â‚Ê {26w䜱¹ìÉØ,"·Œ}¤„DŒÍÚò‘ ›«"aóYP asã^86·{Ê©÷¤ å`Ί Üdâ£sÎ'>?±¹(>G,ÈÎ(—•ð9ºcEû¬ýFñ9úã³àséèœz.>ï½%9oCM æ{ÒÜ{Œó=i¾Ñ‹ÂfÁŒ³È€AkÆ6×ÚpÍ'Ø`4˜[îR¡Û6J 7…P/í(½:å(wÚNÂEë´asAaT±Yr§›UèFŠÍ•r'À ©}:ØÜPA_IЂ@º$Fø©¨…z!Ì å|HÎHÊØ\Òy#ÆærbÑ>ج=;ò‰öÂ6×À„Íçý›6£?ME{š *S:ÏšÓÞ%zS!ÄZå@gZ0hLå¡U0¶Tñst¥’¡)=QzÒ³é -iÃÏRSd@’`ÍGeà£Ê]¸žBº&G- ìCçh+& Û:ŸŸ}v{÷ß~;Þ}ÿÃÞ>ÞÞ}ùß_~útè ÷ÞúÈJÇßoï¾~ÿïÇ?K9û-TÑkÅœ]븯4Véë¿nŸþÿç@ûw <}•4×2Öv­”ÿrw kæ±^}H¹Jûë9äâ 34Öq_Ç}÷çŸr%/sœƒ‹vaiºêWºêW¦?ÃÎ2ÁrâÉXÏAÆr?t¯d€~÷˧ßÿÔq¿zÿá#j¾êüæ\Ó%ÙLY‘ï?ýø†Ÿ~ËÑÞh7_ó…ûo¿ÞOó~·D‹Eó6:]wß¾ýöéî=°.µ^a©:¬¨.­†Ub¬¢èlÑÉE?ȼ*ÉûbýQØ÷Ùäàýo+ñbÄËBü„½’HÔ ñÂÛhG¼DÄ‹_ÎVqću#¾”-–“A"ŠÉPÒ+ŸÏX£J•íü‚íÍQ´±y7É14GmŒÇ,óñã¡kJ…Qf’+%Gí²ÉÀeídÈ‘ l2pÚa‘“!¬‹LÒ-–…#QÈD!Þb¹G€¢G€Œíô‚í }2¶SÙŒû‡q9=f™×x )^G2Q’å‘äJÙ‚vñ.:£¹é6ÚÉ8ÂÃâ-Ösó/êzÈÐߣ6X§:¬@>«a•-;¬aeÃÚ²]ŸY¥Ç2Ãåºå¾‡qoöËu˽³_Žì—Í~Y·Ü;ûåÈ~Ùì—u˽3cŽÌ˜ÍŒY·Ü‹ã^#îÍsY¶Ü‹ã^#îÍY^pEGžËæ¹¼xîrd°;~æat2¯#c<žóÈ ¼ä4oæÅ›Y®œ‘²¹1/n¼D;7æÈÙܘ7^±œa]æÍ¼xóŠåTÉ‘*fº¼˜®×aÖå£Ít™·6ÈÍGršæg˜ôMMeMi¢,ÞüHr¥Œ\Íyqã5Úɹ1›óâÆ+–“!®ËdXÜxÁrÞÌ‘7³y3OÏ\±FttøÌGꋃ¦g†’RÍŽ!ÿ˜¦çß &}/$¥aŒ÷”âSÎ$WÊ–ÿ·`š†Ý£i}¶§‚ûWDVz`M3}%+ªkvÇÊ[¬gQf• –‰RÛ«V‡%V5¶ë ¶G4EÑÆv¥Ýx”g†ƒwÇ£Ìë×õ!Å‹?ª&Š.¢Ì$WJÚU“Aó6ÚÉ ‘ j2HÛa‰“!¬KL‘-–E#QÄDÚa÷Hôˆ±]^°=¢£¡/ÆvÉ»ñ ×Õ¼1³Ìk<´mÇ£˜(y…ܳ‘£v³Éeí .‘ ÙdÈ´Ãb'C\—ÉÀu‹åDÉ‘(l¢pÞb¹G€£G€mÚ²Mîàè ãž^p?¢#¶Éئ'ÑÐJÜp‘;{†s¸êšÄdH^ð½ÝâÏ·Yþõ–ªÞþÚ’#™<‹_7ÇhŠX0»^ÜÚÅ6'F Ä0^,¸9%¢Ì€ÿ-Ïo.óÈ¿jN„QÐ$hy‹7S^O}d¿æ¾‹ù:· 0¯]¬ÖQãÎÕæŽÂYÛ§³íh2g^ŒÙY@äkf°‹¿úÈç*kpΘÓ.FëažÙŽª1“]<ÖÁ8‡ Öüu±Wó<Ý‘·šµÊ†Uç«‘­š«–˜â+2`Õu1ÔòL¤ºœNoO8sÏÅ<ýùæaž¯#Ûóß^ZÞͨ¹íb¶LîÛíè«qûêóu¤3ÖÈWÍVWõ0â¾´Œ¾¢±ßÀC˜ñÍZô+³ý¶²áû¹ï-,î/.»?¸<ù«gÛ½†¯qf­/ÇF¯0ªk„1ÞWfÜCgž- endstream endobj 690 0 obj << /Producer (pdfTeX-1.40.25) /Author(\376\377\000M\000I\000T)/Title(\376\377\000K\000e\000r\000b\000e\000r\000o\000s\000\040\000U\000s\000e\000r\000\040\000G\000u\000i\000d\000e)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20250820154604-04'00') /ModDate (D:20250820154604-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) kpathsea version 6.3.5) >> endobj 659 0 obj << /Type /ObjStm /N 31 /First 267 /Length 1316 /Filter /FlateDecode >> stream xÚ•XMÛ6½ûWðHÌá‚, M7E“ž‚=8ak`¿°Öí¿ï Em(j$£'Êo8œ÷žHš¢WZ!j•5FYo©µ ÃNydT0žZ¯"FjQm=e E‘PãÀl“2Þ…A+4ÒƒQ&5XeãSÖy/Õ‹T(xe£f•ÓŽ‘ œÍ}¢raƒ!) ¥S‚KŽFކh"#Ä×EFœü õ* ?>虬É?>>¾PÖ;·ÙïóàW‡û½¹|¼y÷¥?<÷[åbR½ùµïîß›­òÑT€eÀV€cÀ ÀÍ߇§¾{~Ëi`íÌ#×Äéx웺U¿ë–Þ¢âVOG¥òÐ@°¥ÉPD<n»\ÙùЄ$[#,TÛ–_UøµßŒÝ`c4ÖC²3ÆÔ02!âI5‚„Ø q3ë^«¾öZ 9}bG"jª4 Ôä}ÍݲA¨k„£—yÅíÏ^2/Ëö„É€lO¨í±lOœôa{b¨¶'M¨RqÔZ$ÆU_{-Kœ^ÆsÌ×,Ùƒ¦vБ=h]…'Õ£@ù5rɱ“L 9¹TC¨ëEjchLˆµ›G^”µQÇŒ$‘nvšQ:u7ýññámž8®øPÀ÷†×[l1êil ’±¦É¶œm¡yåÇ–hMcÒw‰0©¤³íèô®Z.ïЂT)ÌzÒ˜©8Ý»@y 2é½È²w-Èæ…YYà-R·(Í=k}‹";Z”f–Ó~‰8LÌæÞ+ÄiN:çÚ‰Ý.óðôò½r<{Åo6VŒð>‚bx!/ á=j–1W3íAN"ˆÕÈM”¹“£Aâžçú¸½5ÒAŒÞ8_ 3–ó´uiyÂ'ÉÈ<ëÖbˆg¡ž…áeƒb(ïZ ñ€Võeªó¼5}0Lc£X”ü2Ί!ä¬"ðº”Täk Š!ÖîíŠÀÂuž·.0Ï ãQ,ÊÚQ¦ÊÚÄkGIE~& bQ¯ ,Û_›·.p˜lÄ¢,0ÊTY`²bˆ&IEÞ¿­öb(CÓª@7gæ=¾HÄ¢¼±› †òîn„Ï*ÆÓdbΉ!¦áª@˜ ôg× Ï*@¦Ê*@2³ ïäæ“A’cœ—òX~Z×èçË0'®‹Ä|òwÚˆu¹¬bˆ]G9‹mCÙ¶ eýüÿ>œ%dç‰ç$Z–ù…È2‡$_±ÓI ‘eN\!ŸæL8£0l…¼u! Å5ØqgeÈ!IEÌ]C,P\1 ¿*0Ìgi<+0f Seâr‹Y 8}S(ÎÑ”Šs4egæhœ Lg¦,0¬Ï$\;þ ,œX'ßF ­+-”Ö¯Ýo´ßwãàX’Cici¿°|"ó­ÕÒwÚòI¯Ô(§O,Œ|Í5´¾´…ê]â¹kºŽåŠ„P$”#.–]£ýß{’ôZÊ­––…/ÖV^Ãò°—݉zãp»0‚_ÿ}êÔîã¡?Ü=Þò½Û-Í5ôå>îóKw|ÈÈx—'#Æ8ÞÓÝv¿?þèvº±s?¾ww§‹‹ÝÕËý雦‡/»ËýÞæ‡çýF䚈ì>?u2iå7™ßý)œ endstream endobj 691 0 obj << /Type /XRef /Index [0 692] /Size 692 /W [1 3 1] /Root 689 0 R /Info 690 0 R /ID [<712100D84F6F0812654F7206CA422B95> <712100D84F6F0812654F7206CA422B95>] /Length 1633 /Filter /FlateDecode >> stream xÚ%—KlUU†÷º§--¥Oè .¥ÚRèƒ-}Ò]Êú~@K)-5Æ 80Îq !iŽãÀ¨9ãHãÄC4!ÛDF81M8QãÄd'êý~&Îÿs{ïÙký{í:çÜæ\•Ë9—8sIV¸²lÎåR1Cr°æÛÞÂ&Hìì¶)†mbw ¥°Nض Ù ; »-GvÁzaëØ ¤6»…­Bªag`kؤvv»Ù»[ÅÖ!õ°«°lÒ›ƒÝÀ6!{a7a×±ûè]¯Ð5bé¦@Ÿz…NKG'zÒ+tõXº8 Ã:-; £0^f{–ôöl¯A ’‘¼àaµXRÎÂŽÁTnÂÎÁxéíj,aô½ï†©U{ Ç½BW‰%ìVö ÚŒ°ÚÖ+t»°„=LÃ:µ(a³°!ØN,a´­ç¥·ÕÞ„=Т~VŠ%ìaÆËl+„=0bйÒ ñ+*Hå[©ý†YnškhÒ­ìéq¯+–ć5s}z„°Fj â!¶˜à†hl'ˆ†u1¢½Ñ`.C4ŽË á D£· ÑÀ­ATËõÂ/xGß¡©Ë.ïI™¿eîýÝh@ê̵Èjê6!š«ÆÂÝtwB;zò晈þ6ì Ò†´˜ëú^+[ìfYr i7×ÿ®îªátÕ0Õ²“3/ë2çŸè®’²ÉC.;ô™›zª»ý,4·z_la‚eãȈ¹ßÔ1„ñ”ysw‰M Œ§ì<ÂPÊ."Œ˜lÒÜËé9mÈ*s&›A˜$Ù”¹×îé†MÆ$É–æGvajd+ˆVcÁÜ/éªô–¹¯hƒ/tØ¿u¥½¸ÄÜDzôA¤Ü±ÜÜ'_Šik®C*Í=üE¬ŠÓ¶©á@}£¶Rªµrœ‰õæ>ýBŸ ª‘ãLÔù¥ÍÜç_ëu‹Ô-vš{Ô-¦ã %‹:°ô":¦°ì±P·'ÏߣAtp6÷´Y7t¶ÐÁµ:.L":$hŠ›û¡HŸç=HEdM㌹è†&;«5C—ÍýtC#úk mšûã;ÝØ²äIۿ߉™/Ê#;NZž£•¯@ÊÍj^×#»ÎR¾Ò,¿$Æ:os^óЧ%_‡Ô#b|­Yçgz¸áÀâ5]Ú͵w«YÏ„žë@4úmÿœ_üÒk6ð·žÓ à€áµS#“È¨ÙØïzDÛõuD2+éo Ú‹9txíÀœ(¼ö]Î ^»í”™¯Ô_™6û°LW3fÏœ®f-7õ¶®æ,÷Ñ=]Í[Òñ‚®,¹ÿ§®-y/¯«%K¾z¾Ë–<®p–|[­I\lɳ»º*±äg8—2ŽSæoÊ 9e‰Sj”2S •R¨”B¥Ô2-G¨QJÝÒJ„ò¤L町¥zS •R¨”B¥*¥2);eD§Ìä”!œ²Í¥úߪْŸò…ßüÛ«îpj endstream endobj startxref 255606 %%EOF krb5-1.22.1/doc/pdf/sphinxlatexadmonitions.sty0000664000175000017500000002535514577122106021254 0ustar ghudsonghudson%% NOTICES AND ADMONITIONS % % change this info string if making any custom modification \ProvidesFile{sphinxlatexadmonitions.sty}[2023/03/19 admonitions] % Provides support for this output mark-up from Sphinx latex writer: % % - sphinxseealso environment added at 6.1.0 % % - sphinxadmonition (environment) % This is a dispatch supporting % % - note, hint, important, tip (via sphinxlightbox) % (also optionally via sphinxheavybox since 6.2.0) % - warning, caution, attention, danger, error (via sphinxheavybox) % % Each sphinx environment can be redefined by user. % The defaults are customizable via various colour and dimension % settings, cf sphinx docs (latex customization). % % Requires: \RequirePackage{sphinxpackageboxes} \RequirePackage{framed}% used by sphinxheavybox % % Dependencies (they do not need to be defined at time of loading): % % - of course the various colour and dimension options handled via sphinx.sty % % - dimension register \spx@image@maxheight from sphinxlatexgraphics.sty % % - \savenotes/\spewnotes from sphinxpackagefootnote (for sphinxheavybox) % % - \sphinxstylenotetitle, ..., \sphinxstylewarningtitle, etc... which are used by % default in the corresponding sphinx environments to replace at 6.2.0 % formerly hard-coded \sphinxstrong{#1} % Their definitions are in sphinxlatexstyletext.sty. % Provides: (also in sphinxlatexliterals.sty) \providecommand*\sphinxvspacefixafterfrenchlists{% \ifvmode\ifdim\lastskip<\z@ \vskip\parskip\fi\else\par\fi } % Some are quite plain \newenvironment{sphinxseealso}[1]{\sphinxstyleseealsotitle{#1}}{} % This \dimen register is a legacy relic from Sphinx 1.5 which is used now % only for sphinxlightbox. It is set in the sphinxadmonition environment. \newdimen\spx@notice@border \newenvironment{sphinxlightbox}{% \par \noindent{\color{spx@notice@bordercolor}% \rule{\linewidth}{\spx@notice@border}}% \par\nobreak {\parskip\z@skip\noindent}% } {% % counteract previous possible negative skip (French lists!): % (we can't cancel that any earlier \vskip introduced a potential pagebreak) \sphinxvspacefixafterfrenchlists \nobreak\vbox{\noindent\kern\@totalleftmargin {\color{spx@notice@bordercolor}% \rule[\dimexpr.4\baselineskip-\spx@notice@border\relax] {\linewidth}{\spx@notice@border}}\hss}\allowbreak }% end of sphinxlightbox environment definition % note/hint/important/tip notices % % Since 1.5 these environments are named individually to allow user to % redefine them entirely. % % The Sphinx definitions were done like this, prior to 6.2.0: % % \newenvironment{sphinxhint}[1] % {\begin{sphinxlightbox}\sphinxstrong{#1} }{\end{sphinxlightbox}} % % The more complex definition below will branch to sphinxheavybox if a certain % boolean associated to the notice type is true. This boolean is set to true % whenever a CSS-named alike options for the notice type has been used in % sphinxsetup. The old coding as above would still work, with the new options % being then simply ignored. A user redefinition will probably either use % directly sphinxlightbox or sphinxheavybox or something else, with no need to % test the boolean. % % 6.2.0 also adds one layer of mark-up via \sphinxnotetitle etc..., because % the former \sphinxstrong{#1} used a too generic \sphinxstrong. But % perhaps the #1 should be passed over to sphinx{light,heavy}box as parameter. % Unfortunately replacing these environments with one-parameter environments % would be potentially a breaking change. Anyway, sphinxpackageboxes.sty does not % provide a "titled" box; the caption of code-blocks is handled by extra % code in sphinxVerbatim. \newenvironment{sphinxnote}[1] {\edef\spx@env{sphinx\ifspx@opt@heavynote heavy\else light\fi box}% \expandafter\begin\expandafter{\spx@env}\sphinxstylenotetitle{#1}} {\expandafter\end\expandafter{\spx@env}} \newenvironment{sphinxhint}[1] {\edef\spx@env{sphinx\ifspx@opt@heavyhint heavy\else light\fi box}% \expandafter\begin\expandafter{\spx@env}\sphinxstylehinttitle{#1}} {\expandafter\end\expandafter{\spx@env}} \newenvironment{sphinximportant}[1] {\edef\spx@env{sphinx\ifspx@opt@heavyimportant heavy\else light\fi box}% \expandafter\begin\expandafter{\spx@env}\sphinxstyleimportanttitle{#1}} {\expandafter\end\expandafter{\spx@env}} \newenvironment{sphinxtip}[1] {\edef\spx@env{sphinx\ifspx@opt@heavytip heavy\else light\fi box}% \expandafter\begin\expandafter{\spx@env}\sphinxstyletiptitle{#1}} {\expandafter\end\expandafter{\spx@env}} % warning/caution/attention/danger/error get more distinction % % Code adapted from framed.sty's "snugshade" environment. % Nesting works (inner frames do not allow page breaks). \newenvironment{sphinxheavybox}{\par % 6.2.0 allows to not have to distinguish here between warning type notices % which always use sphinxheavybox or note type notices which might use it. % (MEMO: it is not a problem here if there is no sphinxShadowColor, % as it used only if set) \spx@boxes@fcolorbox@setup{\spx@noticetype}% % Those are used by sphinxVerbatim if the \ifspx@inframed boolean is true \setlength{\FrameRule}{0.5\dimexpr\spx@boxes@border@top+\spx@boxes@border@bottom\relax}% % MEMO: prior to 5.1.0 \FrameSep was determined as 0.6\baselineskip - % \FrameRule, and there was no possibility for user to adjust padding. % Then \fcolorbox was used with \fboxrule set to \FrameRule and \fboxsep % set to \FrameSep. % The 5.1.0 default calculation of padding parameters maintains PDF output % identical to legacy behaviour, as long as padding is not set by user. \setlength{\FrameSep}{0.5\dimexpr\spx@boxes@padding@top+\spx@boxes@padding@bottom\relax}% % "setup" macro has prepared the \spx@boxes@... dimen registers \advance\spx@image@maxheight -\dimexpr\spx@boxes@border@top+\spx@boxes@border@bottom +\spx@boxes@padding@top+\spx@boxes@padding@bottom +\baselineskip\relax % will happen again if nested, needed indeed! % MEMO: the next comment is before boxing was extended to allow padding and % multiple border-widths, not to mention shadows... % configure framed.sty's parameters to obtain same vertical spacing % as for "light" boxes. We need for this to manually insert parskip glue and % revert a skip done by framed before the frame. \ltx@ifundefined{OuterFrameSep}{}{\OuterFrameSep\z@skip}% \vspace{\FrameHeightAdjust} % copied/adapted from framed.sty's snugshade % but now using in place of \fcolorbox the Sphinx sophisticated own \def\FrameCommand##1{% \hskip\@totalleftmargin % "setup" macro MUST have been called before \spx@boxes@fcolorbox{##1}% \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth }% % 6.2.0 adds support for div._box-decoration-break=slice. % (it is yet undecided if slice style should inhibit a bottom shadow) \csname ifspx@\spx@noticetype @border@open\endcsname \def\FirstFrameCommand {\spx@boxes@fcolorbox@setup@openbottom\FrameCommand}% \def\MidFrameCommand {\spx@boxes@fcolorbox@setup@openboth \FrameCommand}% \def\LastFrameCommand {\spx@boxes@fcolorbox@setup@opentop \FrameCommand}% \fi \savenotes % use a minipage if we are already inside a framed environment \ifspx@inframed \noindent\begin{minipage}{\linewidth} \else % handle case where notice is first thing in a list item (or is quoted) \if@inlabel \noindent\par\vspace{-\baselineskip} \else \vspace{\parskip} \fi \fi \MakeFramed {\spx@inframedtrue \advance\hsize-\width \@totalleftmargin\z@ \linewidth\hsize % minipage initialization copied from LaTeX source code. \@pboxswfalse \let\@listdepth\@mplistdepth \@mplistdepth\z@ \@minipagerestore \@setminipage }% \color@begingroup % workaround to an upstream framed.sty bug } {% \par\unskip \color@endgroup % matches the \color@begingroup \@minipagefalse \endMakeFramed \ifspx@inframed\end{minipage}\fi % set footnotes at bottom of page \spewnotes % arrange for similar spacing below frame as for "light" boxes. \vskip .4\baselineskip }% end of sphinxheavybox environment definition % - Since 1.5 these environments are named individually to allow user to % redefine them entirely. % % - Since 5.1.0, sphinxheavybox is more versatile and four border widths, four % padding widths, four corner radii, optional shadow, and three colors can all % be modified via CSS-named alike options. % % - Since 6.2.0, also note/hint/important/tip notices can use these options % and then they go automatically via sphinxheavybox. If only the legacy options % are used, they keep using sphinxlightbox. % % - Since 6.2.0, \sphinxwarningtitle etc... add one level of mark-up (they % expand to \sphinxstrong{#1} which was former hard-coded mark-up). % Example: % \renewcommand{\sphinxwarningtitle}[1]{\textbf{#1}\par\smallskip % {\color{sphinxwarningBorderColor}\hrule height1pt}\smallskip} \newenvironment{sphinxwarning}[1] {\begin{sphinxheavybox}\sphinxstylewarningtitle{#1}}{\end{sphinxheavybox}} \newenvironment{sphinxcaution}[1] {\begin{sphinxheavybox}\sphinxstylecautiontitle{#1}}{\end{sphinxheavybox}} \newenvironment{sphinxattention}[1] {\begin{sphinxheavybox}\sphinxstyleattentiontitle{#1}}{\end{sphinxheavybox}} \newenvironment{sphinxdanger}[1] {\begin{sphinxheavybox}\sphinxstyledangertitle{#1}}{\end{sphinxheavybox}} \newenvironment{sphinxerror}[1] {\begin{sphinxheavybox}\sphinxstyleerrortitle{#1}}{\end{sphinxheavybox}} % the main dispatch for all types of notices \newenvironment{sphinxadmonition}[2]{% #1=type, #2=heading % can't use #1 directly in definition of end part \def\spx@noticetype {#1}% % those next three are a remnant of legacy code; they are not used at % all by sphinxheavybox, and their usage could be disposed of by sphinxlightbox % but we keep for backward compatibility and also because it may be simpler % for user redefinitions to employ for example "spx@notice@bgcolor" and not % the more bulky "sphinx\spx@noticetype BgColor". \sphinxcolorlet{spx@notice@bordercolor}{sphinx#1BorderColor}% \sphinxcolorlet{spx@notice@bgcolor}{sphinx#1BgColor}% \spx@notice@border \dimexpr\csname spx@#1@border\endcsname\relax % trigger the sphinx environment, #2=heading is passed as argument \begin{sphinx#1}{#2}% % 6.2.0 support of div._TeX{color,extras} options \csname ifspx@\spx@noticetype @withtextcolor\endcsname \color{sphinx\spx@noticetype TextColor}% \fi \csname spx@\spx@noticetype @TeXextras\endcsname } % workaround some LaTeX "feature" of \end command (can't use "sphinx#1" here) {\edef\spx@temp{\noexpand\end{sphinx\spx@noticetype}}\spx@temp} \endinput krb5-1.22.1/doc/pdf/sphinxlatexgraphics.sty0000664000175000017500000001135014577122106020516 0ustar ghudsonghudson%% GRAPHICS % % change this info string if making any custom modification \ProvidesFile{sphinxlatexgraphics.sty}[2021/01/27 graphics] % Provides support for this output mark-up from Sphinx latex writer: % % - macros: % % - \sphinxfigcaption % - \sphinxincludegraphics % % - environments: % % - sphinxfigure-in-table % % May change: % % - \sphinxcaption (at begin document) % % Also provides: % % - \sphinxsafeincludegraphics (default of \sphinxincludegraphics since 2.0) % - \spx@image@maxheight dimension (used by sphinxlatexadmonitions.sty) % - \spx@image@box scratch box register (also used by sphinxlatexliterals.sty) % % Requires: % \RequirePackage{graphicx}% done in sphinx.sty \RequirePackage{amstext}% needed for \firstchoice@true(false) % \sphinxincludegraphics resizes images larger than the TeX \linewidth (which % is adjusted in indented environments), or taller than a certain maximal % height (usually \textheight and this is reduced in the environments which use % framed.sty to avoid infinite loop if image too tall). % % In case height or width options are present the rescaling is done % (since 2.0), in a way keeping the width:height ratio either native from % image or from the width and height options if both were present. % \newdimen\spx@image@maxheight \AtBeginDocument{\spx@image@maxheight\textheight} % box scratch register \newbox\spx@image@box \newcommand*{\sphinxsafeincludegraphics}[2][]{% % #1 contains possibly width=, height=, but no scale= since 1.8.4 \setbox\spx@image@box\hbox{\includegraphics[#1,draft]{#2}}% \in@false % use some handy boolean flag \ifdim \wd\spx@image@box>\linewidth \in@true % flag to remember to adjust options and set box dimensions % compute height which results from rescaling width to \linewidth % and keep current aspect ratio. multiply-divide in \numexpr uses % temporarily doubled precision, hence no overflow. (of course we % assume \ht is not a few sp's below \maxdimen...(about 16384pt). \edef\spx@image@rescaledheight % with sp units {\the\numexpr\ht\spx@image@box *\linewidth/\wd\spx@image@box sp}% \ifdim\spx@image@rescaledheight>\spx@image@maxheight % the rescaled height will be too big, so it is height which decides % the rescaling factor \def\spx@image@requiredheight{\spx@image@maxheight}% dimen register \edef\spx@image@requiredwidth % with sp units {\the\numexpr\wd\spx@image@box *\spx@image@maxheight/\ht\spx@image@box sp}% % TODO: decide if this commented-out block could be needed due to % rounding in numexpr operations going up % \ifdim\spx@image@requiredwidth>\linewidth % \def\spx@image@requiredwidth{\linewidth}% dimen register % \fi \else \def\spx@image@requiredwidth{\linewidth}% dimen register \let\spx@image@requiredheight\spx@image@rescaledheight% sp units \fi \else % width is ok, let's check height \ifdim\ht\spx@image@box>\spx@image@maxheight \in@true \edef\spx@image@requiredwidth % with sp units {\the\numexpr\wd\spx@image@box *\spx@image@maxheight/\ht\spx@image@box sp}% \def\spx@image@requiredheight{\spx@image@maxheight}% dimen register \fi \fi % end of check of width and height \ifin@ \setbox\spx@image@box \hbox{\includegraphics [%#1,% contained only width and/or height and overruled anyhow width=\spx@image@requiredwidth,height=\spx@image@requiredheight]% {#2}}% % \includegraphics does not set box dimensions to the exactly % requested ones, see https://github.com/latex3/latex2e/issues/112 \wd\spx@image@box\spx@image@requiredwidth \ht\spx@image@box\spx@image@requiredheight \leavevmode\box\spx@image@box \else % here we do not modify the options, no need to adjust width and height % on output, they will be computed exactly as with "draft" option \setbox\spx@image@box\box\voidb@x % clear memory \includegraphics[#1]{#2}% \fi }% % Use the "safe" one by default (2.0) \def\sphinxincludegraphics{\sphinxsafeincludegraphics} %% FIGURE IN TABLE % \newenvironment{sphinxfigure-in-table}[1][\linewidth]{% \def\@captype{figure}% \sphinxsetvskipsforfigintablecaption \begin{minipage}{#1}% }{\end{minipage}} % tabulary expands twice contents, we need to prevent double counter stepping \newcommand*\sphinxfigcaption {\ifx\equation$%$% this is trick to identify tabulary first pass \firstchoice@false\else\firstchoice@true\fi \spx@originalcaption } \newcommand*\sphinxsetvskipsforfigintablecaption {\abovecaptionskip\smallskipamount \belowcaptionskip\smallskipamount} \endinput krb5-1.22.1/doc/pdf/sphinxlatexindbibtoc.sty0000664000175000017500000000402214577122106020651 0ustar ghudsonghudson%% INDEX, BIBLIOGRAPHY, APPENDIX, TABLE OF CONTENTS % % change this info string if making any custom modification \ProvidesFile{sphinxlatexindbibtoc.sty}[2021/01/27 index, bib., toc] % Provides support for this output mark-up from Sphinx latex writer: % % - environments: (backup defaults or get redefined) % % - sphinxtheindex (direct mark-up or via python.ist or sphinx.xdy) % - sphinxthebibliography % % - macros: (defines defaults) % % - \sphinxmaketitle % - \sphinxtableofcontents % - \sphinxnonalphabeticalgroupname % - \sphinxsymbolsname % - \sphinxnumbersname % - \sphinxcite % % Requires: \RequirePackage{makeidx} % fix the double index and bibliography on the table of contents % in jsclasses (Japanese standard document classes) \ifx\@jsc@uplatextrue\@undefined\else \renewenvironment{sphinxtheindex} {\cleardoublepage\phantomsection \begin{theindex}} {\end{theindex}} \renewenvironment{sphinxthebibliography}[1] {\cleardoublepage% \phantomsection % not needed here since TeXLive 2010's hyperref \begin{thebibliography}{#1}} {\end{thebibliography}} \fi % disable \@chappos in Appendix in pTeX \ifx\kanjiskip\@undefined\else \let\py@OldAppendix=\appendix \renewcommand{\appendix}{ \py@OldAppendix \gdef\@chappos{} } \fi % make commands known to non-Sphinx document classes \providecommand*{\sphinxmaketitle}{\maketitle} \providecommand*{\sphinxtableofcontents}{\tableofcontents} \ltx@ifundefined{sphinxthebibliography} {\newenvironment {sphinxthebibliography}{\begin{thebibliography}}{\end{thebibliography}}% } {}% else clause of \ltx@ifundefined \ltx@ifundefined{sphinxtheindex} {\newenvironment{sphinxtheindex}{\begin{theindex}}{\end{theindex}}}% {}% else clause of \ltx@ifundefined % for usage with xindy: this string gets internationalized in preamble \newcommand*{\sphinxnonalphabeticalgroupname}{} % redefined in preamble, headings for makeindex produced index \newcommand*{\sphinxsymbolsname}{} \newcommand*{\sphinxnumbersname}{} \protected\def\sphinxcite{\cite} \endinput krb5-1.22.1/doc/pdf/appdev.tex0000664000175000017500000630366015051422736015704 0ustar ghudsonghudson%% Generated by Sphinx. \def\sphinxdocclass{report} \documentclass[letterpaper,10pt,english]{sphinxmanual} \ifdefined\pdfpxdimen \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen \fi \sphinxpxdimen=.75bp\relax \ifdefined\pdfimageresolution \pdfimageresolution= \numexpr \dimexpr1in\relax/\sphinxpxdimen\relax \fi %% let collapsible pdf bookmarks panel have high depth per default \PassOptionsToPackage{bookmarksdepth=5}{hyperref} \PassOptionsToPackage{booktabs}{sphinx} \PassOptionsToPackage{colorrows}{sphinx} \PassOptionsToPackage{warn}{textcomp} \usepackage[utf8]{inputenc} \ifdefined\DeclareUnicodeCharacter % support both utf8 and utf8x syntaxes \ifdefined\DeclareUnicodeCharacterAsOptional \def\sphinxDUC#1{\DeclareUnicodeCharacter{"#1}} \else \let\sphinxDUC\DeclareUnicodeCharacter \fi \sphinxDUC{00A0}{\nobreakspace} \sphinxDUC{2500}{\sphinxunichar{2500}} \sphinxDUC{2502}{\sphinxunichar{2502}} \sphinxDUC{2514}{\sphinxunichar{2514}} \sphinxDUC{251C}{\sphinxunichar{251C}} \sphinxDUC{2572}{\textbackslash} \fi \usepackage{cmap} \usepackage[T1]{fontenc} \usepackage{amsmath,amssymb,amstext} \usepackage{babel} \usepackage{tgtermes} \usepackage{tgheros} \renewcommand{\ttdefault}{txtt} \usepackage[Bjarne]{fncychap} \usepackage{sphinx} \fvset{fontsize=auto} \usepackage{geometry} % Include hyperref last. \usepackage{hyperref} % Fix anchor placement for figures with captions. \usepackage{hypcap}% it must be loaded after hyperref. % Set up styles of URL: it should be placed after hyperref. \urlstyle{same} \usepackage{sphinxmessages} \setcounter{tocdepth}{0} \title{Kerberos Application Developer Guide} \date{ } \release{1.22.1} \author{MIT} \newcommand{\sphinxlogo}{\vbox{}} \renewcommand{\releasename}{Release} \makeindex \begin{document} \ifdefined\shorthandoff \ifnum\catcode`\=\string=\active\shorthandoff{=}\fi \ifnum\catcode`\"=\active\shorthandoff{"}\fi \fi \pagestyle{empty} \sphinxmaketitle \pagestyle{plain} \sphinxtableofcontents \pagestyle{normal} \phantomsection\label{\detokenize{appdev/index::doc}} \sphinxstepscope \chapter{Developing with GSSAPI} \label{\detokenize{appdev/gssapi:developing-with-gssapi}}\label{\detokenize{appdev/gssapi::doc}} \sphinxAtStartPar The GSSAPI (Generic Security Services API) allows applications to communicate securely using Kerberos 5 or other security mechanisms. We recommend using the GSSAPI (or a higher\sphinxhyphen{}level framework which encompasses GSSAPI, such as SASL) for secure network communication over using the libkrb5 API directly. \sphinxAtStartPar GSSAPIv2 is specified in \index{RFC@\spxentry{RFC}!RFC 2743@\spxentry{RFC 2743}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc2743.html}{\sphinxstylestrong{RFC 2743}} and \index{RFC@\spxentry{RFC}!RFC 2744@\spxentry{RFC 2744}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc2744.html}{\sphinxstylestrong{RFC 2744}}. Also see \index{RFC@\spxentry{RFC}!RFC 7546@\spxentry{RFC 7546}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc7546.html}{\sphinxstylestrong{RFC 7546}} for a description of how to use the GSSAPI in a client or server program. \sphinxAtStartPar This documentation will describe how various ways of using the GSSAPI will behave with the krb5 mechanism as implemented in MIT krb5, as well as krb5\sphinxhyphen{}specific extensions to the GSSAPI. \section{Name types} \label{\detokenize{appdev/gssapi:name-types}} \sphinxAtStartPar A GSSAPI application can name a local or remote entity by calling \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.16}{gss\_import\_name}, specifying a name type and a value. The following name types are supported by the krb5 mechanism: \begin{itemize} \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_NT\_HOSTBASED\_SERVICE}: The value should be a string of the form \sphinxcode{\sphinxupquote{service}} or \sphinxcode{\sphinxupquote{service@hostname}}. This is the most common way to name target services when initiating a security context, and is the most likely name type to work across multiple mechanisms. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_KRB5\_NT\_PRINCIPAL\_NAME}: The value should be a principal name string. This name type only works with the krb5 mechanism, and is defined in the \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_krb5.h\textgreater{}}} header. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_NT\_USER\_NAME} or \sphinxstylestrong{GSS\_C\_NULL\_OID}: The value is treated as an unparsed principal name string, as above. These name types may work with mechanisms other than krb5, but will have different interpretations in those mechanisms. \sphinxstylestrong{GSS\_C\_NT\_USER\_NAME} is intended to be used with a local username, which will parse into a single\sphinxhyphen{}component principal in the default realm. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_NT\_ANONYMOUS}: The value is ignored. The anonymous principal is used, allowing a client to authenticate to a server without asserting a particular identity (which may or may not be allowed by a particular server or Kerberos realm). \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_NT\_MACHINE\_UID\_NAME}: The value is uid\_t object. On Unix\sphinxhyphen{}like systems, the username of the uid is looked up in the system user database and the resulting username is parsed as a principal name. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_NT\_STRING\_UID\_NAME}: As above, but the value is a decimal string representation of the uid. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_NT\_EXPORT\_NAME}: The value must be the result of a \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.13}{gss\_export\_name} call. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_KRB5\_NT\_ENTERPRISE\_NAME}: The value should be a krb5 enterprise name string (see \index{RFC@\spxentry{RFC}!RFC 6806@\spxentry{RFC 6806}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc6806.html}{\sphinxstylestrong{RFC 6806}} section 5), in the form \sphinxcode{\sphinxupquote{user@suffix}}. This name type is used to convey alias names, and is defined in the \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_krb5.h\textgreater{}}} header. (New in release 1.17.) \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_KRB5\_NT\_X509\_CERT}: The value should be an X.509 certificate encoded according to \index{RFC@\spxentry{RFC}!RFC 5280@\spxentry{RFC 5280}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc5280.html}{\sphinxstylestrong{RFC 5280}}. This name form can be used for the desired\_name parameter of gss\_acquire\_cred\_impersonate\_name(), to identify the S4U2Self user by certificate. (New in release 1.19.) \end{itemize} \section{Initiator credentials} \label{\detokenize{appdev/gssapi:initiator-credentials}} \sphinxAtStartPar A GSSAPI client application uses \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.19}{gss\_init\_sec\_context} to establish a security context. The \sphinxstyleemphasis{initiator\_cred\_handle} parameter determines what tickets are used to establish the connection. An application can either pass \sphinxstylestrong{GSS\_C\_NO\_CREDENTIAL} to use the default client credential, or it can use \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.2}{gss\_acquire\_cred} beforehand to acquire an initiator credential. The call to \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.2}{gss\_acquire\_cred} may include a \sphinxstyleemphasis{desired\_name} parameter, or it may pass \sphinxstylestrong{GSS\_C\_NO\_NAME} if it does not have a specific name preference. \sphinxAtStartPar If the desired name for a krb5 initiator credential is a host\sphinxhyphen{}based name, it is converted to a principal name of the form \sphinxcode{\sphinxupquote{service/hostname}} in the local realm, where \sphinxstyleemphasis{hostname} is the local hostname if not specified. The hostname will be canonicalized using forward name resolution, and possibly also using reverse name resolution depending on the value of the \sphinxstylestrong{rdns} variable in \DUrole{xref,std,std-ref}{libdefaults}. \sphinxAtStartPar If a desired name is specified in the call to \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.2}{gss\_acquire\_cred}, the krb5 mechanism will attempt to find existing tickets for that client principal name in the default credential cache or collection. If the default cache type does not support a collection, and the default cache contains credentials for a different principal than the desired name, a \sphinxstylestrong{GSS\_S\_CRED\_UNAVAIL} error will be returned with a minor code indicating a mismatch. \sphinxAtStartPar If no existing tickets are available for the desired name, but the name has an entry in the default client \DUrole{xref,std,std-ref}{keytab\_definition}, the krb5 mechanism will acquire initial tickets for the name using the default client keytab. \sphinxAtStartPar If no desired name is specified, credential acquisition will be deferred until the credential is used in a call to \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.19}{gss\_init\_sec\_context} or \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.21}{gss\_inquire\_cred}. If the call is to \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.19}{gss\_init\_sec\_context}, the target name will be used to choose a client principal name using the credential cache selection facility. (This facility might, for instance, try to choose existing tickets for a client principal in the same realm as the target service). If there are no existing tickets for the chosen principal, but it is present in the default client keytab, the krb5 mechanism will acquire initial tickets using the keytab. \sphinxAtStartPar If the target name cannot be used to select a client principal (because the credentials are used in a call to \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.21}{gss\_inquire\_cred}), or if the credential cache selection facility cannot choose a principal for it, the default credential cache will be selected if it exists and contains tickets. \sphinxAtStartPar If the default credential cache does not exist, but the default client keytab does, the krb5 mechanism will try to acquire initial tickets for the first principal in the default client keytab. \sphinxAtStartPar If the krb5 mechanism acquires initial tickets using the default client keytab, the resulting tickets will be stored in the default cache or collection, and will be refreshed by future calls to \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.2}{gss\_acquire\_cred} as they approach their expire time. \section{Acceptor names} \label{\detokenize{appdev/gssapi:acceptor-names}} \sphinxAtStartPar A GSSAPI server application uses \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.1}{gss\_accept\_sec\_context} to establish a security context based on tokens provided by the client. The \sphinxstyleemphasis{acceptor\_cred\_handle} parameter determines what \DUrole{xref,std,std-ref}{keytab\_definition} entries may be authenticated to by the client, if the krb5 mechanism is used. \sphinxAtStartPar The simplest choice is to pass \sphinxstylestrong{GSS\_C\_NO\_CREDENTIAL} as the acceptor credential. In this case, clients may authenticate to any service principal in the default keytab (typically \DUrole{xref,std,std-ref}{DEFKTNAME}, or the value of the \sphinxstylestrong{KRB5\_KTNAME} environment variable). This is the recommended approach if the server application has no specific requirements to the contrary. \sphinxAtStartPar A server may acquire an acceptor credential with \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.2}{gss\_acquire\_cred} and a \sphinxstyleemphasis{cred\_usage} of \sphinxstylestrong{GSS\_C\_ACCEPT} or \sphinxstylestrong{GSS\_C\_BOTH}. If the \sphinxstyleemphasis{desired\_name} parameter is \sphinxstylestrong{GSS\_C\_NO\_NAME}, then clients will be allowed to authenticate to any service principal in the default keytab, just as if no acceptor credential was supplied. \sphinxAtStartPar If a server wishes to specify a \sphinxstyleemphasis{desired\_name} to \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.2}{gss\_acquire\_cred}, the most common choice is a host\sphinxhyphen{}based name. If the host\sphinxhyphen{}based \sphinxstyleemphasis{desired\_name} contains just a \sphinxstyleemphasis{service}, then clients will be allowed to authenticate to any host\sphinxhyphen{}based service principal (that is, a principal of the form \sphinxcode{\sphinxupquote{service/hostname@REALM}}) for the named service, regardless of hostname or realm, as long as it is present in the default keytab. If the input name contains both a \sphinxstyleemphasis{service} and a \sphinxstyleemphasis{hostname}, clients will be allowed to authenticate to any host\sphinxhyphen{}based principal for the named service and hostname, regardless of realm. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If a \sphinxstyleemphasis{hostname} is specified, it will be canonicalized using forward name resolution, and possibly also using reverse name resolution depending on the value of the \sphinxstylestrong{rdns} variable in \DUrole{xref,std,std-ref}{libdefaults}. \end{sphinxadmonition} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If the \sphinxstylestrong{ignore\_acceptor\_hostname} variable in \DUrole{xref,std,std-ref}{libdefaults} is enabled, then \sphinxstyleemphasis{hostname} will be ignored even if one is specified in the input name. \end{sphinxadmonition} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar In MIT krb5 versions prior to 1.10, and in Heimdal’s implementation of the krb5 mechanism, an input name with just a \sphinxstyleemphasis{service} is treated like an input name of \sphinxcode{\sphinxupquote{service@localhostname}}, where \sphinxstyleemphasis{localhostname} is the string returned by gethostname(). \end{sphinxadmonition} \sphinxAtStartPar If the \sphinxstyleemphasis{desired\_name} is a krb5 principal name or a local system name type which is mapped to a krb5 principal name, clients will only be allowed to authenticate to that principal in the default keytab. \section{Name Attributes} \label{\detokenize{appdev/gssapi:name-attributes}} \sphinxAtStartPar In release 1.8 or later, the \sphinxhref{https://tools.ietf.org/html/rfc6680.txt\#section-7.4}{gss\_inquire\_name} and \sphinxhref{https://tools.ietf.org/html/6680.html\#section-7.5}{gss\_get\_name\_attribute} functions, specified in \index{RFC@\spxentry{RFC}!RFC 6680@\spxentry{RFC 6680}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc6680.html}{\sphinxstylestrong{RFC 6680}}, can be used to retrieve name attributes from the \sphinxstyleemphasis{src\_name} returned by \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.1}{gss\_accept\_sec\_context}. The following attributes are defined when the krb5 mechanism is used: \phantomsection\label{\detokenize{appdev/gssapi:gssapi-authind-attr}}\begin{itemize} \item {} \sphinxAtStartPar “auth\sphinxhyphen{}indicators†attribute: \end{itemize} \sphinxAtStartPar This attribute will be included in the \sphinxhref{https://tools.ietf.org/html/rfc6680.txt\#section-7.4}{gss\_inquire\_name} output if the ticket contains \DUrole{xref,std,std-ref}{authentication indicators}. One indicator is returned per invocation of \sphinxhref{https://tools.ietf.org/html/6680.html\#section-7.5}{gss\_get\_name\_attribute}, so multiple invocations may be necessary to retrieve all of the indicators from the ticket. (New in release 1.15.) \section{Credential store extensions} \label{\detokenize{appdev/gssapi:credential-store-extensions}} \sphinxAtStartPar Beginning with release 1.11, the following GSSAPI extensions declared in \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_ext.h\textgreater{}}} can be used to specify how credentials are acquired or stored: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{struct} \PYG{n}{gss\PYGZus{}key\PYGZus{}value\PYGZus{}element\PYGZus{}struct} \PYG{p}{\PYGZob{}} \PYG{n}{const} \PYG{n}{char} \PYG{o}{*}\PYG{n}{key}\PYG{p}{;} \PYG{n}{const} \PYG{n}{char} \PYG{o}{*}\PYG{n}{value}\PYG{p}{;} \PYG{p}{\PYGZcb{}}\PYG{p}{;} \PYG{n}{typedef} \PYG{n}{struct} \PYG{n}{gss\PYGZus{}key\PYGZus{}value\PYGZus{}element\PYGZus{}struct} \PYG{n}{gss\PYGZus{}key\PYGZus{}value\PYGZus{}element\PYGZus{}desc}\PYG{p}{;} \PYG{n}{struct} \PYG{n}{gss\PYGZus{}key\PYGZus{}value\PYGZus{}set\PYGZus{}struct} \PYG{p}{\PYGZob{}} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{count}\PYG{p}{;} \PYG{n}{gss\PYGZus{}key\PYGZus{}value\PYGZus{}element\PYGZus{}desc} \PYG{o}{*}\PYG{n}{elements}\PYG{p}{;} \PYG{p}{\PYGZcb{}}\PYG{p}{;} \PYG{n}{typedef} \PYG{n}{const} \PYG{n}{struct} \PYG{n}{gss\PYGZus{}key\PYGZus{}value\PYGZus{}set\PYGZus{}struct} \PYG{n}{gss\PYGZus{}key\PYGZus{}value\PYGZus{}set\PYGZus{}desc}\PYG{p}{;} \PYG{n}{typedef} \PYG{n}{const} \PYG{n}{gss\PYGZus{}key\PYGZus{}value\PYGZus{}set\PYGZus{}desc} \PYG{o}{*}\PYG{n}{gss\PYGZus{}const\PYGZus{}key\PYGZus{}value\PYGZus{}set\PYGZus{}t}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}acquire\PYGZus{}cred\PYGZus{}from}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{const} \PYG{n}{gss\PYGZus{}name\PYGZus{}t} \PYG{n}{desired\PYGZus{}name}\PYG{p}{,} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{time\PYGZus{}req}\PYG{p}{,} \PYG{n}{const} \PYG{n}{gss\PYGZus{}OID\PYGZus{}set} \PYG{n}{desired\PYGZus{}mechs}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}usage\PYGZus{}t} \PYG{n}{cred\PYGZus{}usage}\PYG{p}{,} \PYG{n}{gss\PYGZus{}const\PYGZus{}key\PYGZus{}value\PYGZus{}set\PYGZus{}t} \PYG{n}{cred\PYGZus{}store}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{o}{*}\PYG{n}{output\PYGZus{}cred\PYGZus{}handle}\PYG{p}{,} \PYG{n}{gss\PYGZus{}OID\PYGZus{}set} \PYG{o}{*}\PYG{n}{actual\PYGZus{}mechs}\PYG{p}{,} \PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{time\PYGZus{}rec}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}store\PYGZus{}cred\PYGZus{}into}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{n}{input\PYGZus{}cred\PYGZus{}handle}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}usage\PYGZus{}t} \PYG{n}{cred\PYGZus{}usage}\PYG{p}{,} \PYG{n}{const} \PYG{n}{gss\PYGZus{}OID} \PYG{n}{desired\PYGZus{}mech}\PYG{p}{,} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{overwrite\PYGZus{}cred}\PYG{p}{,} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{default\PYGZus{}cred}\PYG{p}{,} \PYG{n}{gss\PYGZus{}const\PYGZus{}key\PYGZus{}value\PYGZus{}set\PYGZus{}t} \PYG{n}{cred\PYGZus{}store}\PYG{p}{,} \PYG{n}{gss\PYGZus{}OID\PYGZus{}set} \PYG{o}{*}\PYG{n}{elements\PYGZus{}stored}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}usage\PYGZus{}t} \PYG{o}{*}\PYG{n}{cred\PYGZus{}usage\PYGZus{}stored}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar The additional \sphinxstyleemphasis{cred\_store} parameter allows the caller to specify information about how the credentials should be obtained and stored. The following options are supported by the krb5 mechanism: \begin{itemize} \item {} \sphinxAtStartPar \sphinxstylestrong{ccache}: For acquiring initiator credentials, the name of the \DUrole{xref,std,std-ref}{credential cache} to which the handle will refer. For storing credentials, the name of the cache or collection where the credentials will be stored (see below). \item {} \sphinxAtStartPar \sphinxstylestrong{client\_keytab}: For acquiring initiator credentials, the name of the \DUrole{xref,std,std-ref}{keytab} which will be used, if necessary, to refresh the credentials in the cache. \item {} \sphinxAtStartPar \sphinxstylestrong{keytab}: For acquiring acceptor credentials, the name of the \DUrole{xref,std,std-ref}{keytab} to which the handle will refer. In release 1.19 and later, this option also determines the keytab to be used for verification when initiator credentials are acquired using a password and verified. \item {} \sphinxAtStartPar \sphinxstylestrong{password}: For acquiring initiator credentials, this option instructs the mechanism to acquire fresh credentials into a unique memory credential cache. This option may not be used with the \sphinxstylestrong{ccache} or \sphinxstylestrong{client\_keytab} options, and a \sphinxstyleemphasis{desired\_name} must be specified. (New in release 1.19.) \item {} \sphinxAtStartPar \sphinxstylestrong{rcache}: For acquiring acceptor credentials, the name of the \DUrole{xref,std,std-ref}{replay cache} to be used when processing the initiator tokens. (New in release 1.13.) \item {} \sphinxAtStartPar \sphinxstylestrong{verify}: For acquiring initiator credentials, this option instructs the mechanism to verify the credentials by obtaining a ticket to a service with a known key. The service key is obtained from the keytab specified with the \sphinxstylestrong{keytab} option or the default keytab. The value may be the name of a principal in the keytab, or the empty string. If the empty string is given, any \sphinxcode{\sphinxupquote{host}} service principal in the keytab may be used. (New in release 1.19.) \end{itemize} \sphinxAtStartPar In release 1.20 or later, if a collection name is specified for \sphinxstylestrong{cache} in a call to gss\_store\_cred\_into(), an existing cache for the client principal within the collection will be selected, or a new cache will be created within the collection. If \sphinxstyleemphasis{overwrite\_cred} is false and the selected credential cache already exists, a \sphinxstylestrong{GSS\_S\_DUPLICATE\_ELEMENT} error will be returned. If \sphinxstyleemphasis{default\_cred} is true, the primary cache of the collection will be switched to the selected cache. \section{Importing and exporting credentials} \label{\detokenize{appdev/gssapi:importing-and-exporting-credentials}} \sphinxAtStartPar The following GSSAPI extensions can be used to import and export credentials (declared in \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_ext.h\textgreater{}}}): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}export\PYGZus{}cred}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{n}{cred\PYGZus{}handle}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{token}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}import\PYGZus{}cred}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{token}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{o}{*}\PYG{n}{cred\PYGZus{}handle}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar The first function serializes a GSSAPI credential handle into a buffer; the second unseralizes a buffer into a GSSAPI credential handle. Serializing a credential does not destroy it. If any of the mechanisms used in \sphinxstyleemphasis{cred\_handle} do not support serialization, gss\_export\_cred will return \sphinxstylestrong{GSS\_S\_UNAVAILABLE}. As with other GSSAPI serialization functions, these extensions are only intended to work with a matching implementation on the other side; they do not serialize credentials in a standardized format. \sphinxAtStartPar A serialized credential may contain secret information such as ticket session keys. The serialization format does not protect this information from eavesdropping or tampering. The calling application must take care to protect the serialized credential when communicating it over an insecure channel or to an untrusted party. \sphinxAtStartPar A krb5 GSSAPI credential may contain references to a credential cache, a client keytab, an acceptor keytab, and a replay cache. These resources are normally serialized as references to their external locations (such as the filename of the credential cache). Because of this, a serialized krb5 credential can only be imported by a process with similar privileges to the exporter. A serialized credential should not be trusted if it originates from a source with lower privileges than the importer, as it may contain references to external credential cache, keytab, or replay cache resources not accessible to the originator. \sphinxAtStartPar An exception to the above rule applies when a krb5 GSSAPI credential refers to a memory credential cache, as is normally the case for delegated credentials received by \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.1}{gss\_accept\_sec\_context}. In this case, the contents of the credential cache are serialized, so that the resulting token may be imported even if the original memory credential cache no longer exists. \section{Constrained delegation (S4U)} \label{\detokenize{appdev/gssapi:constrained-delegation-s4u}} \sphinxAtStartPar The Microsoft S4U2Self and S4U2Proxy Kerberos protocol extensions allow an intermediate service to acquire credentials from a client to a target service without requiring the client to delegate a ticket\sphinxhyphen{}granting ticket, if the KDC is configured to allow it. \sphinxAtStartPar To perform a constrained delegation operation, the intermediate service must submit to the KDC an “evidence ticket†from the client to the intermediate service. An evidence ticket can be acquired when the client authenticates to the intermediate service with Kerberos, or with an S4U2Self request if the KDC allows it. The MIT krb5 GSSAPI library represents an evidence ticket using a “proxy credentialâ€, which is a special kind of gss\_cred\_id\_t object whose underlying credential cache contains the evidence ticket and a krbtgt ticket for the intermediate service. \sphinxAtStartPar To acquire a proxy credential during client authentication, the service should first create an acceptor credential using the \sphinxstylestrong{GSS\_C\_BOTH} usage. The application should then pass this credential as the \sphinxstyleemphasis{acceptor\_cred\_handle} to \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.1}{gss\_accept\_sec\_context}, and also pass a \sphinxstyleemphasis{delegated\_cred\_handle} output parameter to receive a proxy credential containing the evidence ticket. The output value of \sphinxstyleemphasis{delegated\_cred\_handle} may be a delegated ticket\sphinxhyphen{}granting ticket if the client sent one, or a proxy credential if not. If the library can determine that the client’s ticket is not a valid evidence ticket, it will place \sphinxstylestrong{GSS\_C\_NO\_CREDENTIAL} in \sphinxstyleemphasis{delegated\_cred\_handle}. \sphinxAtStartPar To acquire a proxy credential using an S4U2Self request, the service can use the following GSSAPI extension: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}acquire\PYGZus{}cred\PYGZus{}impersonate\PYGZus{}name}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{n}{icred}\PYG{p}{,} \PYG{n}{gss\PYGZus{}name\PYGZus{}t} \PYG{n}{desired\PYGZus{}name}\PYG{p}{,} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{time\PYGZus{}req}\PYG{p}{,} \PYG{n}{gss\PYGZus{}OID\PYGZus{}set} \PYG{n}{desired\PYGZus{}mechs}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}usage\PYGZus{}t} \PYG{n}{cred\PYGZus{}usage}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{o}{*}\PYG{n}{output\PYGZus{}cred}\PYG{p}{,} \PYG{n}{gss\PYGZus{}OID\PYGZus{}set} \PYG{o}{*}\PYG{n}{actual\PYGZus{}mechs}\PYG{p}{,} \PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{time\PYGZus{}rec}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar The parameters to this function are similar to those of \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.2}{gss\_acquire\_cred}, except that \sphinxstyleemphasis{icred} is used to make an S4U2Self request to the KDC for a ticket from \sphinxstyleemphasis{desired\_name} to the intermediate service. Both \sphinxstyleemphasis{icred} and \sphinxstyleemphasis{desired\_name} are required for this function; passing \sphinxstylestrong{GSS\_C\_NO\_CREDENTIAL} or \sphinxstylestrong{GSS\_C\_NO\_NAME} will cause the call to fail. \sphinxstyleemphasis{icred} must contain a krbtgt ticket for the intermediate service. The result of this operation is a proxy credential. (Prior to release 1.18, the result of this operation may be a regular credential for \sphinxstyleemphasis{desired\_name}, if the KDC issues a non\sphinxhyphen{}forwardable ticket.) \sphinxAtStartPar Once the intermediate service has a proxy credential, it can simply pass it to \sphinxhref{https://tools.ietf.org/html/rfc2744.html\#section-5.19}{gss\_init\_sec\_context} as the \sphinxstyleemphasis{initiator\_cred\_handle} parameter, and the desired service as the \sphinxstyleemphasis{target\_name} parameter. The GSSAPI library will present the krbtgt ticket and evidence ticket in the proxy credential to the KDC in an S4U2Proxy request; if the intermediate service has the appropriate permissions, the KDC will issue a ticket from the client to the target service. The GSSAPI library will then use this ticket to authenticate to the target service. \sphinxAtStartPar If an application needs to find out whether a credential it holds is a proxy credential and the name of the intermediate service, it can query the credential with the \sphinxstylestrong{GSS\_KRB5\_GET\_CRED\_IMPERSONATOR} OID (new in release 1.16, declared in \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_krb5.h\textgreater{}}}) using the gss\_inquire\_cred\_by\_oid extension (declared in \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_ext.h\textgreater{}}}): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}inquire\PYGZus{}cred\PYGZus{}by\PYGZus{}oid}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{const} \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{n}{cred\PYGZus{}handle}\PYG{p}{,} \PYG{n}{gss\PYGZus{}OID} \PYG{n}{desired\PYGZus{}object}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}set\PYGZus{}t} \PYG{o}{*}\PYG{n}{data\PYGZus{}set}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar If the call succeeds and \sphinxstyleemphasis{cred\_handle} is a proxy credential, \sphinxstyleemphasis{data\_set} will be set to a single\sphinxhyphen{}element buffer set containing the unparsed principal name of the intermediate service. If \sphinxstyleemphasis{cred\_handle} is not a proxy credential, \sphinxstyleemphasis{data\_set} will be set to an empty buffer set. If the library does not support the query, gss\_inquire\_cred\_by\_oid will return \sphinxstylestrong{GSS\_S\_UNAVAILABLE}. \section{Channel binding behavior and GSS\_C\_CHANNEL\_BOUND\_FLAG} \label{\detokenize{appdev/gssapi:channel-binding-behavior-and-gss-c-channel-bound-flag}} \sphinxAtStartPar GSSAPI channel bindings can be used to limit the scope of a context establishment token to a particular protected channel or endpoint, such as a TLS channel or server certificate. Channel bindings can be supplied via the \sphinxstyleemphasis{input\_chan\_bindings} parameter to either gss\_init\_sec\_context() or gss\_accept\_sec\_context(). \sphinxAtStartPar If both the initiator and acceptor of a GSSAPI exchange supply matching channel bindings, \sphinxstylestrong{GSS\_C\_CHANNEL\_BOUND\_FLAG} will be included in the gss\_accept\_sec\_context() \sphinxstyleemphasis{ret\_flags} result. If either the initiator or acceptor (or both) do not supply channel bindings, the exchange will succeed, but \sphinxstylestrong{GSS\_C\_CHANNEL\_BOUND\_FLAG} will not be included in the return flags. If the acceptor and initiator both inlude channel bindings but they do not match, the exchange will fail. \sphinxAtStartPar If \sphinxstylestrong{GSS\_C\_CHANNEL\_BOUND\_FLAG} is included in the \sphinxstyleemphasis{req\_flags} parameter of gss\_init\_sec\_context(), the initiator will add the Microsoft KERB\_AP\_OPTIONS\_CBT extension to the Kerberos authenticator. This extension requests that the acceptor strictly enforce channel bindings, causing the exchange to fail if the acceptor supplies channel bindings and the initiator does not. The KERB\_AP\_OPTIONS\_CBT extension will also be included if the \sphinxstylestrong{client\_aware\_channel\_bindings} variable is set to \sphinxcode{\sphinxupquote{true}} in \DUrole{xref,std,std-ref}{libdefaults}. \sphinxAtStartPar Prior to release 1.19, \sphinxstylestrong{GSS\_C\_CHANNEL\_BOUND\_FLAG} is not implemented, and the exchange will fail if the acceptor supply channel bindings and the initiator does not (but not vice versa). Between releases 1.19 and 1.21, \sphinxstylestrong{GSS\_C\_CHANNEL\_BOUND\_FLAG} is not recognized as an initiator flag, so \sphinxstylestrong{client\_aware\_channel\_bindings} is the only way to cause KERB\_AP\_OPTIONS\_CBT to be included. \section{AEAD message wrapping} \label{\detokenize{appdev/gssapi:aead-message-wrapping}} \sphinxAtStartPar The following GSSAPI extensions (declared in \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_ext.h\textgreater{}}}) can be used to wrap and unwrap messages with additional “associated data†which is integrity\sphinxhyphen{}checked but is not included in the output buffer: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}wrap\PYGZus{}aead}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{n}{context\PYGZus{}handle}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{conf\PYGZus{}req\PYGZus{}flag}\PYG{p}{,} \PYG{n}{gss\PYGZus{}qop\PYGZus{}t} \PYG{n}{qop\PYGZus{}req}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{input\PYGZus{}assoc\PYGZus{}buffer}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{input\PYGZus{}payload\PYGZus{}buffer}\PYG{p}{,} \PYG{n+nb}{int} \PYG{o}{*}\PYG{n}{conf\PYGZus{}state}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{output\PYGZus{}message\PYGZus{}buffer}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}unwrap\PYGZus{}aead}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{n}{context\PYGZus{}handle}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{input\PYGZus{}message\PYGZus{}buffer}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{input\PYGZus{}assoc\PYGZus{}buffer}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{output\PYGZus{}payload\PYGZus{}buffer}\PYG{p}{,} \PYG{n+nb}{int} \PYG{o}{*}\PYG{n}{conf\PYGZus{}state}\PYG{p}{,} \PYG{n}{gss\PYGZus{}qop\PYGZus{}t} \PYG{o}{*}\PYG{n}{qop\PYGZus{}state}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar Wrap tokens created with gss\_wrap\_aead will successfully unwrap only if the same \sphinxstyleemphasis{input\_assoc\_buffer} contents are presented to gss\_unwrap\_aead. \section{IOV message wrapping} \label{\detokenize{appdev/gssapi:iov-message-wrapping}} \sphinxAtStartPar The following extensions (declared in \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_ext.h\textgreater{}}}) can be used for in\sphinxhyphen{}place encryption, fine\sphinxhyphen{}grained control over wrap token layout, and for constructing wrap tokens compatible with Microsoft DCE RPC: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{typedef} \PYG{n}{struct} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc\PYGZus{}struct} \PYG{p}{\PYGZob{}} \PYG{n}{OM\PYGZus{}uint32} \PYG{n+nb}{type}\PYG{p}{;} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}desc} \PYG{n}{buffer}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc}\PYG{p}{,} \PYG{o}{*}\PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}t}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}wrap\PYGZus{}iov}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{n}{context\PYGZus{}handle}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{conf\PYGZus{}req\PYGZus{}flag}\PYG{p}{,} \PYG{n}{gss\PYGZus{}qop\PYGZus{}t} \PYG{n}{qop\PYGZus{}req}\PYG{p}{,} \PYG{n+nb}{int} \PYG{o}{*}\PYG{n}{conf\PYGZus{}state}\PYG{p}{,} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{o}{*}\PYG{n}{iov}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{iov\PYGZus{}count}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}unwrap\PYGZus{}iov}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{n}{context\PYGZus{}handle}\PYG{p}{,} \PYG{n+nb}{int} \PYG{o}{*}\PYG{n}{conf\PYGZus{}state}\PYG{p}{,} \PYG{n}{gss\PYGZus{}qop\PYGZus{}t} \PYG{o}{*}\PYG{n}{qop\PYGZus{}state}\PYG{p}{,} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{o}{*}\PYG{n}{iov}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{iov\PYGZus{}count}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}wrap\PYGZus{}iov\PYGZus{}length}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{n}{context\PYGZus{}handle}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{conf\PYGZus{}req\PYGZus{}flag}\PYG{p}{,} \PYG{n}{gss\PYGZus{}qop\PYGZus{}t} \PYG{n}{qop\PYGZus{}req}\PYG{p}{,} \PYG{n+nb}{int} \PYG{o}{*}\PYG{n}{conf\PYGZus{}state}\PYG{p}{,} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{o}{*}\PYG{n}{iov}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{iov\PYGZus{}count}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}release\PYGZus{}iov\PYGZus{}buffer}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{o}{*}\PYG{n}{iov}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{iov\PYGZus{}count}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar The caller of gss\_wrap\_iov provides an array of gss\_iov\_buffer\_desc structures, each containing a type and a gss\_buffer\_desc structure. Valid types include: \begin{itemize} \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_BUFFER\_TYPE\_DATA}: A data buffer to be included in the token, and to be encrypted or decrypted in\sphinxhyphen{}place if the token is confidentiality\sphinxhyphen{}protected. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_BUFFER\_TYPE\_HEADER}: The GSSAPI wrap token header and underlying cryptographic header. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_BUFFER\_TYPE\_TRAILER}: The cryptographic trailer, if one is required. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_BUFFER\_TYPE\_PADDING}: Padding to be combined with the data during encryption and decryption. (The implementation may choose to place padding in the trailer buffer, in which case it will set the padding buffer length to 0.) \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_BUFFER\_TYPE\_STREAM}: For unwrapping only, a buffer containing a complete wrap token in standard format to be unwrapped. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_BUFFER\_TYPE\_SIGN\_ONLY}: A buffer to be included in the token’s integrity protection checksum, but not to be encrypted or included in the token itself. \end{itemize} \sphinxAtStartPar For gss\_wrap\_iov, the IOV list should contain one HEADER buffer, followed by zero or more SIGN\_ONLY buffers, followed by one or more DATA buffers, followed by a TRAILER buffer. The memory pointed to by the buffers is not required to be contiguous or in any particular order. If \sphinxstyleemphasis{conf\_req\_flag} is true, DATA buffers will be encrypted in\sphinxhyphen{}place, while SIGN\_ONLY buffers will not be modified. \sphinxAtStartPar The type of an output buffer may be combined with \sphinxstylestrong{GSS\_C\_BUFFER\_FLAG\_ALLOCATE} to request that gss\_wrap\_iov allocate the buffer contents. If gss\_wrap\_iov allocates a buffer, it sets the \sphinxstylestrong{GSS\_C\_BUFFER\_FLAG\_ALLOCATED} flag on the buffer type. gss\_release\_iov\_buffer can be used to release all allocated buffers within an iov list and unset their allocated flags. Here is an example of how gss\_wrap\_iov can be used with allocation requested (\sphinxstyleemphasis{ctx} is assumed to be a previously established gss\_ctx\_id\_t): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{;} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{4}\PYG{p}{]}\PYG{p}{;} \PYG{n}{char} \PYG{n+nb}{str}\PYG{p}{[}\PYG{p}{]} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{message}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}HEADER} \PYG{o}{|} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}FLAG\PYGZus{}ALLOCATE}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}DATA}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{n+nb}{str}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{=} \PYG{n}{strlen}\PYG{p}{(}\PYG{n+nb}{str}\PYG{p}{)}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}PADDING} \PYG{o}{|} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}FLAG\PYGZus{}ALLOCATE}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{3}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}TRAILER} \PYG{o}{|} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}FLAG\PYGZus{}ALLOCATE}\PYG{p}{;} \PYG{n}{major} \PYG{o}{=} \PYG{n}{gss\PYGZus{}wrap\PYGZus{}iov}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{minor}\PYG{p}{,} \PYG{n}{ctx}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{GSS\PYGZus{}C\PYGZus{}QOP\PYGZus{}DEFAULT}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{iov}\PYG{p}{,} \PYG{l+m+mi}{4}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{GSS\PYGZus{}ERROR}\PYG{p}{(}\PYG{n}{major}\PYG{p}{)}\PYG{p}{)} \PYG{n}{handle\PYGZus{}error}\PYG{p}{(}\PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{)}\PYG{p}{;} \PYG{o}{/}\PYG{o}{*} \PYG{n}{Transmit} \PYG{o+ow}{or} \PYG{n}{otherwise} \PYG{n}{use} \PYG{n}{resulting} \PYG{n}{buffers}\PYG{o}{.} \PYG{o}{*}\PYG{o}{/} \PYG{p}{(}\PYG{n}{void}\PYG{p}{)}\PYG{n}{gss\PYGZus{}release\PYGZus{}iov\PYGZus{}buffer}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{minor}\PYG{p}{,} \PYG{n}{iov}\PYG{p}{,} \PYG{l+m+mi}{4}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar If the caller does not choose to request buffer allocation by gss\_wrap\_iov, it should first call gss\_wrap\_iov\_length to query the lengths of the HEADER, PADDING, and TRAILER buffers. DATA buffers must be provided in the iov list so that padding length can be computed correctly, but the output buffers need not be initialized. Here is an example of using gss\_wrap\_iov\_length and gss\_wrap\_iov: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{;} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{4}\PYG{p}{]}\PYG{p}{;} \PYG{n}{char} \PYG{n+nb}{str}\PYG{p}{[}\PYG{l+m+mi}{1024}\PYG{p}{]} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{message}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{o}{*}\PYG{n}{ptr}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}HEADER}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}DATA}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{n+nb}{str}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{=} \PYG{n}{strlen}\PYG{p}{(}\PYG{n+nb}{str}\PYG{p}{)}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}PADDING}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{3}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}TRAILER}\PYG{p}{;} \PYG{n}{major} \PYG{o}{=} \PYG{n}{gss\PYGZus{}wrap\PYGZus{}iov\PYGZus{}length}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{minor}\PYG{p}{,} \PYG{n}{ctx}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{GSS\PYGZus{}C\PYGZus{}QOP\PYGZus{}DEFAULT}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{iov}\PYG{p}{,} \PYG{l+m+mi}{4}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{GSS\PYGZus{}ERROR}\PYG{p}{(}\PYG{n}{major}\PYG{p}{)}\PYG{p}{)} \PYG{n}{handle\PYGZus{}error}\PYG{p}{(}\PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{strlen}\PYG{p}{(}\PYG{n+nb}{str}\PYG{p}{)} \PYG{o}{+} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{+} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{+} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{3}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{\PYGZgt{}} \PYG{n}{sizeof}\PYG{p}{(}\PYG{n+nb}{str}\PYG{p}{)}\PYG{p}{)} \PYG{n}{handle\PYGZus{}out\PYGZus{}of\PYGZus{}space\PYGZus{}error}\PYG{p}{(}\PYG{p}{)}\PYG{p}{;} \PYG{n}{ptr} \PYG{o}{=} \PYG{n+nb}{str} \PYG{o}{+} \PYG{n}{strlen}\PYG{p}{(}\PYG{n+nb}{str}\PYG{p}{)}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{n}{ptr}\PYG{p}{;} \PYG{n}{ptr} \PYG{o}{+}\PYG{o}{=} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{n}{ptr}\PYG{p}{;} \PYG{n}{ptr} \PYG{o}{+}\PYG{o}{=} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{3}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{n}{ptr}\PYG{p}{;} \PYG{n}{major} \PYG{o}{=} \PYG{n}{gss\PYGZus{}wrap\PYGZus{}iov}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{minor}\PYG{p}{,} \PYG{n}{ctx}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{GSS\PYGZus{}C\PYGZus{}QOP\PYGZus{}DEFAULT}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{iov}\PYG{p}{,} \PYG{l+m+mi}{4}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{GSS\PYGZus{}ERROR}\PYG{p}{(}\PYG{n}{major}\PYG{p}{)}\PYG{p}{)} \PYG{n}{handle\PYGZus{}error}\PYG{p}{(}\PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar If the context was established using the \sphinxstylestrong{GSS\_C\_DCE\_STYLE} flag (described in \index{RFC@\spxentry{RFC}!RFC 4757@\spxentry{RFC 4757}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc4757.html}{\sphinxstylestrong{RFC 4757}}), wrap tokens compatible with Microsoft DCE RPC can be constructed. In this case, the IOV list must include a SIGN\_ONLY buffer, a DATA buffer, a second SIGN\_ONLY buffer, and a HEADER buffer in that order (the order of the buffer contents remains arbitrary). The application must pad the DATA buffer to a multiple of 16 bytes as no padding or trailer buffer is used. \sphinxAtStartPar gss\_unwrap\_iov may be called with an IOV list just like one which would be provided to gss\_wrap\_iov. DATA buffers will be decrypted in\sphinxhyphen{}place if they were encrypted, and SIGN\_ONLY buffers will not be modified. \sphinxAtStartPar Alternatively, gss\_unwrap\_iov may be called with a single STREAM buffer, zero or more SIGN\_ONLY buffers, and a single DATA buffer. The STREAM buffer is interpreted as a complete wrap token. The STREAM buffer will be modified in\sphinxhyphen{}place to decrypt its contents. The DATA buffer will be initialized to point to the decrypted data within the STREAM buffer, unless it has the \sphinxstylestrong{GSS\_C\_BUFFER\_FLAG\_ALLOCATE} flag set, in which case it will be initialized with a copy of the decrypted data. Here is an example (\sphinxstyleemphasis{token} and \sphinxstyleemphasis{token\_len} are assumed to be a pre\sphinxhyphen{}existing pointer and length for a modifiable region of data): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{;} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}STREAM}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{n}{token}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{=} \PYG{n}{token\PYGZus{}len}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}DATA}\PYG{p}{;} \PYG{n}{major} \PYG{o}{=} \PYG{n}{gss\PYGZus{}unwrap\PYGZus{}iov}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{minor}\PYG{p}{,} \PYG{n}{ctx}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{iov}\PYG{p}{,} \PYG{l+m+mi}{2}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{GSS\PYGZus{}ERROR}\PYG{p}{(}\PYG{n}{major}\PYG{p}{)}\PYG{p}{)} \PYG{n}{handle\PYGZus{}error}\PYG{p}{(}\PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{)}\PYG{p}{;} \PYG{o}{/}\PYG{o}{*} \PYG{n}{Decrypted} \PYG{n}{data} \PYG{o+ow}{is} \PYG{o+ow}{in} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{p}{,} \PYG{n}{pointing} \PYG{n}{to} \PYG{n}{a} \PYG{n}{subregion} \PYG{n}{of} \PYG{o}{*} \PYG{n}{token}\PYG{o}{.} \PYG{o}{*}\PYG{o}{/} \end{sphinxVerbatim} \section{IOV MIC tokens} \label{\detokenize{appdev/gssapi:iov-mic-tokens}}\label{\detokenize{appdev/gssapi:gssapi-mic-token}} \sphinxAtStartPar The following extensions (declared in \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_ext.h\textgreater{}}}) can be used in release 1.12 or later to construct and verify MIC tokens using an IOV list: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}get\PYGZus{}mic\PYGZus{}iov}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{n}{context\PYGZus{}handle}\PYG{p}{,} \PYG{n}{gss\PYGZus{}qop\PYGZus{}t} \PYG{n}{qop\PYGZus{}req}\PYG{p}{,} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{o}{*}\PYG{n}{iov}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{iov\PYGZus{}count}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}get\PYGZus{}mic\PYGZus{}iov\PYGZus{}length}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{n}{context\PYGZus{}handle}\PYG{p}{,} \PYG{n}{gss\PYGZus{}qop\PYGZus{}t} \PYG{n}{qop\PYGZus{}req}\PYG{p}{,} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{o}{*}\PYG{n}{iov}\PYG{p}{,} \PYG{n}{iov\PYGZus{}count}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gss\PYGZus{}verify\PYGZus{}mic\PYGZus{}iov}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{n}{context\PYGZus{}handle}\PYG{p}{,} \PYG{n}{gss\PYGZus{}qop\PYGZus{}t} \PYG{o}{*}\PYG{n}{qop\PYGZus{}state}\PYG{p}{,} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{o}{*}\PYG{n}{iov}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{iov\PYGZus{}count}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar The caller of gss\_get\_mic\_iov provides an array of gss\_iov\_buffer\_desc structures, each containing a type and a gss\_buffer\_desc structure. Valid types include: \begin{itemize} \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_BUFFER\_TYPE\_DATA} and \sphinxstylestrong{GSS\_C\_BUFFER\_TYPE\_SIGN\_ONLY}: The corresponding buffer for each of these types will be signed for the MIC token, in the order provided. \item {} \sphinxAtStartPar \sphinxstylestrong{GSS\_C\_BUFFER\_TYPE\_MIC\_TOKEN}: The GSSAPI MIC token. \end{itemize} \sphinxAtStartPar The type of the MIC\_TOKEN buffer may be combined with \sphinxstylestrong{GSS\_C\_BUFFER\_FLAG\_ALLOCATE} to request that gss\_get\_mic\_iov allocate the buffer contents. If gss\_get\_mic\_iov allocates the buffer, it sets the \sphinxstylestrong{GSS\_C\_BUFFER\_FLAG\_ALLOCATED} flag on the buffer type. gss\_release\_iov\_buffer can be used to release all allocated buffers within an iov list and unset their allocated flags. Here is an example of how gss\_get\_mic\_iov can be used with allocation requested (\sphinxstyleemphasis{ctx} is assumed to be a previously established gss\_ctx\_id\_t): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{;} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{3}\PYG{p}{]}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}DATA}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{sign1}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{=} \PYG{l+m+mi}{5}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}SIGN\PYGZus{}ONLY}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{sign2}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{=} \PYG{l+m+mi}{5}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}MIC\PYGZus{}TOKEN} \PYG{o}{|} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}FLAG\PYGZus{}ALLOCATE}\PYG{p}{;} \PYG{n}{major} \PYG{o}{=} \PYG{n}{gss\PYGZus{}get\PYGZus{}mic\PYGZus{}iov}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{minor}\PYG{p}{,} \PYG{n}{ctx}\PYG{p}{,} \PYG{n}{GSS\PYGZus{}C\PYGZus{}QOP\PYGZus{}DEFAULT}\PYG{p}{,} \PYG{n}{iov}\PYG{p}{,} \PYG{l+m+mi}{3}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{GSS\PYGZus{}ERROR}\PYG{p}{(}\PYG{n}{major}\PYG{p}{)}\PYG{p}{)} \PYG{n}{handle\PYGZus{}error}\PYG{p}{(}\PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{)}\PYG{p}{;} \PYG{o}{/}\PYG{o}{*} \PYG{n}{Transmit} \PYG{o+ow}{or} \PYG{n}{otherwise} \PYG{n}{use} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.} \PYG{o}{*}\PYG{o}{/} \PYG{p}{(}\PYG{n}{void}\PYG{p}{)}\PYG{n}{gss\PYGZus{}release\PYGZus{}iov\PYGZus{}buffer}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{minor}\PYG{p}{,} \PYG{n}{iov}\PYG{p}{,} \PYG{l+m+mi}{3}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar If the caller does not choose to request buffer allocation by gss\_get\_mic\_iov, it should first call gss\_get\_mic\_iov\_length to query the length of the MIC\_TOKEN buffer. Here is an example of using gss\_get\_mic\_iov\_length and gss\_get\_mic\_iov: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{;} \PYG{n}{gss\PYGZus{}iov\PYGZus{}buffer\PYGZus{}desc} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{2}\PYG{p}{]}\PYG{p}{;} \PYG{n}{char} \PYG{n}{data}\PYG{p}{[}\PYG{l+m+mi}{1024}\PYG{p}{]}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}MIC\PYGZus{}TOKEN}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{type} \PYG{o}{=} \PYG{n}{GSS\PYGZus{}IOV\PYGZus{}BUFFER\PYGZus{}TYPE\PYGZus{}DATA}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{message}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{=} \PYG{l+m+mi}{7}\PYG{p}{;} \PYG{n}{major} \PYG{o}{=} \PYG{n}{gss\PYGZus{}get\PYGZus{}mic\PYGZus{}iov\PYGZus{}length}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{minor}\PYG{p}{,} \PYG{n}{ctx}\PYG{p}{,} \PYG{n}{GSS\PYGZus{}C\PYGZus{}QOP\PYGZus{}DEFAULT}\PYG{p}{,} \PYG{n}{iov}\PYG{p}{,} \PYG{l+m+mi}{2}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{GSS\PYGZus{}ERROR}\PYG{p}{(}\PYG{n}{major}\PYG{p}{)}\PYG{p}{)} \PYG{n}{handle\PYGZus{}error}\PYG{p}{(}\PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{length} \PYG{o}{\PYGZgt{}} \PYG{n}{sizeof}\PYG{p}{(}\PYG{n}{data}\PYG{p}{)}\PYG{p}{)} \PYG{n}{handle\PYGZus{}out\PYGZus{}of\PYGZus{}space\PYGZus{}error}\PYG{p}{(}\PYG{p}{)}\PYG{p}{;} \PYG{n}{iov}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{o}{.}\PYG{n}{buffer}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{n}{data}\PYG{p}{;} \PYG{n}{major} \PYG{o}{=} \PYG{n}{gss\PYGZus{}get\PYGZus{}mic\PYGZus{}iov}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{minor}\PYG{p}{,} \PYG{n}{ctx}\PYG{p}{,} \PYG{n}{GSS\PYGZus{}C\PYGZus{}QOP\PYGZus{}DEFAULT}\PYG{p}{,} \PYG{n}{iov}\PYG{p}{,} \PYG{l+m+mi}{2}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{GSS\PYGZus{}ERROR}\PYG{p}{(}\PYG{n}{major}\PYG{p}{)}\PYG{p}{)} \PYG{n}{handle\PYGZus{}error}\PYG{p}{(}\PYG{n}{major}\PYG{p}{,} \PYG{n}{minor}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxstepscope \chapter{Year 2038 considerations for uses of krb5\_timestamp} \label{\detokenize{appdev/y2038:year-2038-considerations-for-uses-of-krb5-timestamp}}\label{\detokenize{appdev/y2038::doc}} \sphinxAtStartPar POSIX time values, which measure the number of seconds since January 1 1970, will exceed the maximum value representable in a signed 32\sphinxhyphen{}bit integer in January 2038. This documentation describes considerations for consumers of the MIT krb5 libraries. \sphinxAtStartPar Applications or libraries which use libkrb5 and consume the timestamps included in credentials or other structures make use of the {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_timestamp}}}}} type. For historical reasons, krb5\_timestamp is a signed 32\sphinxhyphen{}bit integer, even on platforms where a larger type is natively used to represent time values. To behave properly for time values after January 2038, calling code should cast krb5\_timestamp values to uint32\_t, and then to time\_t: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{(}\PYG{n}{time\PYGZus{}t}\PYG{p}{)}\PYG{p}{(}\PYG{n}{uint32\PYGZus{}t}\PYG{p}{)}\PYG{n}{timestamp} \end{sphinxVerbatim} \sphinxAtStartPar Used in this way, krb5\_timestamp values can represent time values up until February 2106, provided that the platform uses a 64\sphinxhyphen{}bit or larger time\_t type. This usage will also remain safe if a later version of MIT krb5 changes krb5\_timestamp to an unsigned 32\sphinxhyphen{}bit integer. \sphinxAtStartPar The GSSAPI only uses representations of time intervals, not absolute times. Callers of the GSSAPI should require no changes to behave correctly after January 2038, provided that they use MIT krb5 release 1.16 or later. \sphinxstepscope \chapter{Differences between Heimdal and MIT Kerberos API} \label{\detokenize{appdev/h5l_mit_apidiff:differences-between-heimdal-and-mit-kerberos-api}}\label{\detokenize{appdev/h5l_mit_apidiff::doc}} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \sphinxthistablewithvlinesstyle \centering \begin{tabulary}{\linewidth}[t]{|l|l|} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_auth_con_getaddrs:c.krb5_auth_con_getaddrs}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_auth\_con\_getaddrs()}}}}} & \sphinxAtStartPar H5l: If either of the pointers to local\_addr and remote\_addr is not NULL, it is freed first and then reallocated before being populated with the content of corresponding address from authentication context. \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_auth_con_setaddrs:c.krb5_auth_con_setaddrs}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_auth\_con\_setaddrs()}}}}} & \sphinxAtStartPar H5l: If either address is NULL, the previous address remains in place \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_auth_con_setports:c.krb5_auth_con_setports}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_auth\_con\_setports()}}}}} & \sphinxAtStartPar H5l: Not implemented as of version 1.3.3 \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_auth_con_setrecvsubkey:c.krb5_auth_con_setrecvsubkey}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_auth\_con\_setrecvsubkey()}}}}} & \sphinxAtStartPar H5l: If either port is NULL, the previous port remains in place \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_auth_con_setsendsubkey:c.krb5_auth_con_setsendsubkey}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_auth\_con\_setsendsubkey()}}}}} & \sphinxAtStartPar H5l: Not implemented as of version 1.3.3 \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_cc_set_config:c.krb5_cc_set_config}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_cc\_set\_config()}}}}} & \sphinxAtStartPar MIT: Before version 1.10 it was assumed that the last argument \sphinxstyleemphasis{data} is ALWAYS non\sphinxhyphen{}zero. \\ \sphinxhline \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_cccol\_last\_change\_time()}} & \sphinxAtStartPar MIT: not implemented \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_set_default_realm:c.krb5_set_default_realm}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_set\_default\_realm()}}}}} & \sphinxAtStartPar H5l: Caches the computed default realm context field. If the second argument is NULL, it tries to retrieve it from libdefaults or DNS. MIT: Computes the default realm each time if it wasn’t explicitly set in the context \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \chapter{Initial credentials} \label{\detokenize{appdev/init_creds:initial-credentials}}\label{\detokenize{appdev/init_creds::doc}} \sphinxAtStartPar Software that performs tasks such as logging users into a computer when they type their Kerberos password needs to get initial credentials (usually ticket granting tickets) from Kerberos. Such software shares some behavior with the \DUrole{xref,std,std-ref}{kinit(1)} program. \sphinxAtStartPar Whenever a program grants access to a resource (such as a local login session on a desktop computer) based on a user successfully getting initial Kerberos credentials, it must verify those credentials against a secure shared secret (e.g., a host keytab) to ensure that the user credentials actually originate from a legitimate KDC. Failure to perform this verification is a critical vulnerability, because a malicious user can execute the “Zanarotti attackâ€: the user constructs a fake response that appears to come from the legitimate KDC, but whose contents come from an attacker\sphinxhyphen{}controlled KDC. \sphinxAtStartPar Some applications read a Kerberos password over the network (ideally over a secure channel), which they then verify against the KDC. While this technique may be the only practical way to integrate Kerberos into some existing legacy systems, its use is contrary to the original design goals of Kerberos. \sphinxAtStartPar The function {\hyperref[\detokenize{appdev/refs/api/krb5_get_init_creds_password:c.krb5_get_init_creds_password}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_init\_creds\_password()}}}}} will get initial credentials for a client using a password. An application that needs to verify the credentials can call {\hyperref[\detokenize{appdev/refs/api/krb5_verify_init_creds:c.krb5_verify_init_creds}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_verify\_init\_creds()}}}}}. Here is an example of code to obtain and verify TGT credentials, given strings \sphinxstyleemphasis{princname} and \sphinxstyleemphasis{password} for the client principal name and password: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5\PYGZus{}error\PYGZus{}code} \PYG{n}{ret}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}creds} \PYG{n}{creds}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}principal} \PYG{n}{client\PYGZus{}princ} \PYG{o}{=} \PYG{n}{NULL}\PYG{p}{;} \PYG{n}{memset}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{sizeof}\PYG{p}{(}\PYG{n}{creds}\PYG{p}{)}\PYG{p}{)}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}parse\PYGZus{}name}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{princname}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{client\PYGZus{}princ}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{n}{goto} \PYG{n}{cleanup}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}password}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{n}{client\PYGZus{}princ}\PYG{p}{,} \PYG{n}{password}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{n}{goto} \PYG{n}{cleanup}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}verify\PYGZus{}init\PYGZus{}creds}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{)}\PYG{p}{;} \PYG{n}{cleanup}\PYG{p}{:} \PYG{n}{krb5\PYGZus{}free\PYGZus{}principal}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{client\PYGZus{}princ}\PYG{p}{)}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}free\PYGZus{}cred\PYGZus{}contents}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{)}\PYG{p}{;} \PYG{k}{return} \PYG{n}{ret}\PYG{p}{;} \end{sphinxVerbatim} \section{Options for get\_init\_creds} \label{\detokenize{appdev/init_creds:options-for-get-init-creds}} \sphinxAtStartPar The function {\hyperref[\detokenize{appdev/refs/api/krb5_get_init_creds_password:c.krb5_get_init_creds_password}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_init\_creds\_password()}}}}} takes an options parameter (which can be a null pointer). Use the function {\hyperref[\detokenize{appdev/refs/api/krb5_get_init_creds_opt_alloc:c.krb5_get_init_creds_opt_alloc}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_init\_creds\_opt\_alloc()}}}}} to allocate an options structure, and {\hyperref[\detokenize{appdev/refs/api/krb5_get_init_creds_opt_free:c.krb5_get_init_creds_opt_free}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_init\_creds\_opt\_free()}}}}} to free it. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5\PYGZus{}error\PYGZus{}code} \PYG{n}{ret}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}opt} \PYG{o}{*}\PYG{n}{opt} \PYG{o}{=} \PYG{n}{NULL}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}creds} \PYG{n}{creds}\PYG{p}{;} \PYG{n}{memset}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{sizeof}\PYG{p}{(}\PYG{n}{creds}\PYG{p}{)}\PYG{p}{)}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}opt\PYGZus{}alloc}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{opt}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{n}{goto} \PYG{n}{cleanup}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}opt\PYGZus{}set\PYGZus{}tkt\PYGZus{}life}\PYG{p}{(}\PYG{n}{opt}\PYG{p}{,} \PYG{l+m+mi}{24} \PYG{o}{*} \PYG{l+m+mi}{60} \PYG{o}{*} \PYG{l+m+mi}{60}\PYG{p}{)}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}password}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{n}{client\PYGZus{}princ}\PYG{p}{,} \PYG{n}{password}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{opt}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{n}{goto} \PYG{n}{cleanup}\PYG{p}{;} \PYG{n}{cleanup}\PYG{p}{:} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}opt\PYGZus{}free}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{opt}\PYG{p}{)}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}free\PYGZus{}cred\PYGZus{}contents}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{)}\PYG{p}{;} \PYG{k}{return} \PYG{n}{ret}\PYG{p}{;} \end{sphinxVerbatim} \section{Getting anonymous credentials} \label{\detokenize{appdev/init_creds:getting-anonymous-credentials}} \sphinxAtStartPar As of release 1.8, it is possible to obtain fully anonymous or partially anonymous (realm\sphinxhyphen{}exposed) credentials, if the KDC supports it. The MIT KDC supports issuing fully anonymous credentials as of release 1.8 if configured appropriately (see \DUrole{xref,std,std-ref}{anonymous\_pkinit}), but does not support issuing realm\sphinxhyphen{}exposed anonymous credentials at this time. \sphinxAtStartPar To obtain fully anonymous credentials, call {\hyperref[\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_anonymous:c.krb5_get_init_creds_opt_set_anonymous}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_init\_creds\_opt\_set\_anonymous()}}}}} on the options structure to set the anonymous flag, and specify a client principal with the KDC’s realm and a single empty data component (the principal obtained by parsing \sphinxcode{\sphinxupquote{@}}\sphinxstyleemphasis{realmname}). Authentication will take place using anonymous PKINIT; if successful, the client principal of the resulting tickets will be \sphinxcode{\sphinxupquote{WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS}}. Here is an example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}opt\PYGZus{}set\PYGZus{}anonymous}\PYG{p}{(}\PYG{n}{opt}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{)}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}build\PYGZus{}principal}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{client\PYGZus{}princ}\PYG{p}{,} \PYG{n}{strlen}\PYG{p}{(}\PYG{n}{myrealm}\PYG{p}{)}\PYG{p}{,} \PYG{n}{myrealm}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{p}{(}\PYG{n}{char} \PYG{o}{*}\PYG{p}{)}\PYG{n}{NULL}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{n}{goto} \PYG{n}{cleanup}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}password}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{n}{client\PYGZus{}princ}\PYG{p}{,} \PYG{n}{password}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{opt}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{n}{goto} \PYG{n}{cleanup}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar To obtain realm\sphinxhyphen{}exposed anonymous credentials, set the anonymous flag on the options structure as above, but specify a normal client principal in order to prove membership in the realm. Authentication will take place as it normally does; if successful, the client principal of the resulting tickets will be \sphinxcode{\sphinxupquote{WELLKNOWN/ANONYMOUS@}}\sphinxstyleemphasis{realmname}. \section{User interaction} \label{\detokenize{appdev/init_creds:user-interaction}} \sphinxAtStartPar Authenticating a user usually requires the entry of secret information, such as a password. A password can be supplied directly to {\hyperref[\detokenize{appdev/refs/api/krb5_get_init_creds_password:c.krb5_get_init_creds_password}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_init\_creds\_password()}}}}} via the \sphinxstyleemphasis{password} parameter, or the application can supply prompter and/or responder callbacks instead. If callbacks are used, the user can also be queried for other secret information such as a PIN, informed of impending password expiration, or prompted to change a password which has expired. \subsection{Prompter callback} \label{\detokenize{appdev/init_creds:prompter-callback}} \sphinxAtStartPar A prompter callback can be specified via the \sphinxstyleemphasis{prompter} and \sphinxstyleemphasis{data} parameters to {\hyperref[\detokenize{appdev/refs/api/krb5_get_init_creds_password:c.krb5_get_init_creds_password}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_init\_creds\_password()}}}}}. The prompter will be invoked each time the krb5 library has a question to ask or information to present. When the prompter callback is invoked, the \sphinxstyleemphasis{banner} argument (if not null) is intended to be displayed to the user, and the questions to be answered are specified in the \sphinxstyleemphasis{prompts} array. Each prompt contains a text question in the \sphinxstyleemphasis{prompt} field, a \sphinxstyleemphasis{hidden} bit to indicate whether the answer should be hidden from display, and a storage area for the answer in the \sphinxstyleemphasis{reply} field. The callback should fill in each question’s \sphinxcode{\sphinxupquote{reply\sphinxhyphen{}\textgreater{}data}} with the answer, up to a maximum number of \sphinxcode{\sphinxupquote{reply\sphinxhyphen{}\textgreater{}length}} bytes, and then reset \sphinxcode{\sphinxupquote{reply\sphinxhyphen{}\textgreater{}length}} to the length of the answer. \sphinxAtStartPar A prompter callback can call {\hyperref[\detokenize{appdev/refs/api/krb5_get_prompt_types:c.krb5_get_prompt_types}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_prompt\_types()}}}}} to get an array of type constants corresponding to the prompts, to get programmatic information about the semantic meaning of the questions. {\hyperref[\detokenize{appdev/refs/api/krb5_get_prompt_types:c.krb5_get_prompt_types}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_prompt\_types()}}}}} may return a null pointer if no prompt type information is available. \sphinxAtStartPar Text\sphinxhyphen{}based applications can use a built\sphinxhyphen{}in text prompter implementation by supplying {\hyperref[\detokenize{appdev/refs/api/krb5_prompter_posix:c.krb5_prompter_posix}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_prompter\_posix()}}}}} as the \sphinxstyleemphasis{prompter} parameter and a null pointer as the \sphinxstyleemphasis{data} parameter. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}password}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{n}{client\PYGZus{}princ}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{krb5\PYGZus{}prompter\PYGZus{}posix}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \subsection{Responder callback} \label{\detokenize{appdev/init_creds:responder-callback}} \sphinxAtStartPar A responder callback can be specified through the init\_creds options using the {\hyperref[\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_responder:c.krb5_get_init_creds_opt_set_responder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_get\_init\_creds\_opt\_set\_responder()}}}}} function. Responder callbacks can present a more sophisticated user interface for authentication secrets. The responder callback is usually invoked only once per authentication, with a list of questions produced by all of the allowed preauthentication mechanisms. \sphinxAtStartPar When the responder callback is invoked, the \sphinxstyleemphasis{rctx} argument can be accessed to obtain the list of questions and to answer them. The {\hyperref[\detokenize{appdev/refs/api/krb5_responder_list_questions:c.krb5_responder_list_questions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_responder\_list\_questions()}}}}} function retrieves an array of question types. For each question type, the {\hyperref[\detokenize{appdev/refs/api/krb5_responder_get_challenge:c.krb5_responder_get_challenge}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_responder\_get\_challenge()}}}}} function retrieves additional information about the question, if applicable, and the {\hyperref[\detokenize{appdev/refs/api/krb5_responder_set_answer:c.krb5_responder_set_answer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_responder\_set\_answer()}}}}} function sets the answer. \sphinxAtStartPar Responder question types, challenges, and answers are UTF\sphinxhyphen{}8 strings. The question type is a well\sphinxhyphen{}known string; the meaning of the challenge and answer depend on the question type. If an application does not understand a question type, it cannot interpret the challenge or provide an answer. Failing to answer a question typically results in the prompter callback being used as a fallback. \subsubsection{Password question} \label{\detokenize{appdev/init_creds:password-question}} \sphinxAtStartPar The \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_QUESTION\_PASSWORD}} (or \sphinxcode{\sphinxupquote{"password"}}) question type requests the user’s password. This question does not have a challenge, and the response is simply the password string. \subsubsection{One\sphinxhyphen{}time password question} \label{\detokenize{appdev/init_creds:one-time-password-question}} \sphinxAtStartPar The \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_QUESTION\_OTP}} (or \sphinxcode{\sphinxupquote{"otp"}}) question type requests a choice among one\sphinxhyphen{}time password tokens and the PIN and value for the chosen token. The challenge and answer are JSON\sphinxhyphen{}encoded strings, but an application can use convenience functions to avoid doing any JSON processing itself. \sphinxAtStartPar The {\hyperref[\detokenize{appdev/refs/api/krb5_responder_otp_get_challenge:c.krb5_responder_otp_get_challenge}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_responder\_otp\_get\_challenge()}}}}} function decodes the challenge into a krb5\_responder\_otp\_challenge structure. The {\hyperref[\detokenize{appdev/refs/api/krb5_responder_otp_set_answer:c.krb5_responder_otp_set_answer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_responder\_otp\_set\_answer()}}}}} function selects one of the token information elements from the challenge and supplies the value and pin for that token. \subsubsection{PKINIT password or PIN question} \label{\detokenize{appdev/init_creds:pkinit-password-or-pin-question}} \sphinxAtStartPar The \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_QUESTION\_PKINIT}} (or \sphinxcode{\sphinxupquote{"pkinit"}}) question type requests PINs for hardware devices and/or passwords for encrypted credentials which are stored on disk, potentially also supplying information about the state of the hardware devices. The challenge and answer are JSON\sphinxhyphen{}encoded strings, but an application can use convenience functions to avoid doing any JSON processing itself. \sphinxAtStartPar The {\hyperref[\detokenize{appdev/refs/api/krb5_responder_pkinit_get_challenge:c.krb5_responder_pkinit_get_challenge}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_responder\_pkinit\_get\_challenge()}}}}} function decodes the challenges into a krb5\_responder\_pkinit\_challenge structure. The {\hyperref[\detokenize{appdev/refs/api/krb5_responder_pkinit_set_answer:c.krb5_responder_pkinit_set_answer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_responder\_pkinit\_set\_answer()}}}}} function can be used to supply the PIN or password for a particular client credential, and can be called multiple times. \subsubsection{Example} \label{\detokenize{appdev/init_creds:example}} \sphinxAtStartPar Here is an example of using a responder callback: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{static} \PYG{n}{krb5\PYGZus{}error\PYGZus{}code} \PYG{n}{my\PYGZus{}responder}\PYG{p}{(}\PYG{n}{krb5\PYGZus{}context} \PYG{n}{context}\PYG{p}{,} \PYG{n}{void} \PYG{o}{*}\PYG{n}{data}\PYG{p}{,} \PYG{n}{krb5\PYGZus{}responder\PYGZus{}context} \PYG{n}{rctx}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{n}{krb5\PYGZus{}error\PYGZus{}code} \PYG{n}{ret}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}responder\PYGZus{}otp\PYGZus{}challenge} \PYG{o}{*}\PYG{n}{chl}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{krb5\PYGZus{}responder\PYGZus{}get\PYGZus{}challenge}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{rctx}\PYG{p}{,} \PYG{n}{KRB5\PYGZus{}RESPONDER\PYGZus{}QUESTION\PYGZus{}PASSWORD}\PYG{p}{)}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}responder\PYGZus{}set\PYGZus{}answer}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{rctx}\PYG{p}{,} \PYG{n}{KRB5\PYGZus{}RESPONDER\PYGZus{}QUESTION\PYGZus{}PASSWORD}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{open sesame}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{k}{return} \PYG{n}{ret}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}responder\PYGZus{}otp\PYGZus{}get\PYGZus{}challenge}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{rctx}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{chl}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret} \PYG{o}{==} \PYG{l+m+mi}{0} \PYG{o}{\PYGZam{}}\PYG{o}{\PYGZam{}} \PYG{n}{chl} \PYG{o}{!=} \PYG{n}{NULL}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}responder\PYGZus{}otp\PYGZus{}set\PYGZus{}answer}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{rctx}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{1234}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{)}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}responder\PYGZus{}otp\PYGZus{}challenge\PYGZus{}free}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{rctx}\PYG{p}{,} \PYG{n}{chl}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{k}{return} \PYG{n}{ret}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{n}{static} \PYG{n}{krb5\PYGZus{}error\PYGZus{}code} \PYG{n}{get\PYGZus{}creds}\PYG{p}{(}\PYG{n}{krb5\PYGZus{}context} \PYG{n}{context}\PYG{p}{,} \PYG{n}{krb5\PYGZus{}principal} \PYG{n}{client\PYGZus{}princ}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{n}{krb5\PYGZus{}error\PYGZus{}code} \PYG{n}{ret}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}opt} \PYG{o}{*}\PYG{n}{opt} \PYG{o}{=} \PYG{n}{NULL}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}creds} \PYG{n}{creds}\PYG{p}{;} \PYG{n}{memset}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{sizeof}\PYG{p}{(}\PYG{n}{creds}\PYG{p}{)}\PYG{p}{)}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}opt\PYGZus{}alloc}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{opt}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{n}{goto} \PYG{n}{cleanup}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}opt\PYGZus{}set\PYGZus{}responder}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{opt}\PYG{p}{,} \PYG{n}{my\PYGZus{}responder}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{)}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{ret}\PYG{p}{)} \PYG{n}{goto} \PYG{n}{cleanup}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}password}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{n}{client\PYGZus{}princ}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{opt}\PYG{p}{)}\PYG{p}{;} \PYG{n}{cleanup}\PYG{p}{:} \PYG{n}{krb5\PYGZus{}get\PYGZus{}init\PYGZus{}creds\PYGZus{}opt\PYGZus{}free}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{n}{opt}\PYG{p}{)}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}free\PYGZus{}cred\PYGZus{}contents}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{)}\PYG{p}{;} \PYG{k}{return} \PYG{n}{ret}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \section{Verifying initial credentials} \label{\detokenize{appdev/init_creds:verifying-initial-credentials}} \sphinxAtStartPar Use the function {\hyperref[\detokenize{appdev/refs/api/krb5_verify_init_creds:c.krb5_verify_init_creds}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_verify\_init\_creds()}}}}} to verify initial credentials. It takes an options structure (which can be a null pointer). Use {\hyperref[\detokenize{appdev/refs/api/krb5_verify_init_creds_opt_init:c.krb5_verify_init_creds_opt_init}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_verify\_init\_creds\_opt\_init()}}}}} to initialize the caller\sphinxhyphen{}allocated options structure, and {\hyperref[\detokenize{appdev/refs/api/krb5_verify_init_creds_opt_set_ap_req_nofail:c.krb5_verify_init_creds_opt_set_ap_req_nofail}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_verify\_init\_creds\_opt\_set\_ap\_req\_nofail()}}}}} to set the “nofail†option. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5\PYGZus{}verify\PYGZus{}init\PYGZus{}creds\PYGZus{}opt} \PYG{n}{vopt}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}verify\PYGZus{}init\PYGZus{}creds\PYGZus{}opt\PYGZus{}init}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{vopt}\PYG{p}{)}\PYG{p}{;} \PYG{n}{krb5\PYGZus{}verify\PYGZus{}init\PYGZus{}creds\PYGZus{}opt\PYGZus{}set\PYGZus{}ap\PYGZus{}req\PYGZus{}nofail}\PYG{p}{(}\PYG{o}{\PYGZam{}}\PYG{n}{vopt}\PYG{p}{,} \PYG{l+m+mi}{1}\PYG{p}{)}\PYG{p}{;} \PYG{n}{ret} \PYG{o}{=} \PYG{n}{krb5\PYGZus{}verify\PYGZus{}init\PYGZus{}creds}\PYG{p}{(}\PYG{n}{context}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{creds}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{n}{NULL}\PYG{p}{,} \PYG{o}{\PYGZam{}}\PYG{n}{vopt}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar The confusingly named “nofail†option, when set, means that the verification must actually succeed in order for {\hyperref[\detokenize{appdev/refs/api/krb5_verify_init_creds:c.krb5_verify_init_creds}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_verify\_init\_creds()}}}}} to indicate success. The default state of this option (cleared) means that if there is no key material available to verify the user credentials, the verification will succeed anyway. (The default can be changed by a configuration file setting.) \sphinxAtStartPar This accommodates a use case where a large number of unkeyed shared desktop workstations need to allow users to log in using Kerberos. The security risks from this practice are mitigated by the absence of valuable state on the shared workstations—any valuable resources that the users would access reside on networked servers. \sphinxstepscope \chapter{Principal manipulation and parsing} \label{\detokenize{appdev/princ_handle:principal-manipulation-and-parsing}}\label{\detokenize{appdev/princ_handle::doc}} \sphinxAtStartPar Kerberos principal structure \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_principal\_data}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_principal}}}}} \sphinxAtStartPar Create and free principal \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_build_principal:c.krb5_build_principal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_build\_principal()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_build_principal_alloc_va:c.krb5_build_principal_alloc_va}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_build\_principal\_alloc\_va()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_build_principal_ext:c.krb5_build_principal_ext}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_build\_principal\_ext()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_copy_principal:c.krb5_copy_principal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_copy\_principal()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_free_principal:c.krb5_free_principal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_free\_principal()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_cc_get_principal:c.krb5_cc_get_principal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_cc\_get\_principal()}}}}} \sphinxAtStartPar Comparing \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_principal_compare:c.krb5_principal_compare}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_principal\_compare()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_principal_compare_flags:c.krb5_principal_compare_flags}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_principal\_compare\_flags()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_principal_compare_any_realm:c.krb5_principal_compare_any_realm}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_principal\_compare\_any\_realm()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_sname_match:c.krb5_sname_match}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_sname\_match()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_sname_to_principal:c.krb5_sname_to_principal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_sname\_to\_principal()}}}}} \sphinxAtStartPar Parsing: \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_parse_name:c.krb5_parse_name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_parse\_name()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_parse_name_flags:c.krb5_parse_name_flags}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_parse\_name\_flags()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_unparse_name:c.krb5_unparse_name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_unparse\_name()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_unparse_name_flags:c.krb5_unparse_name_flags}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_unparse\_name\_flags()}}}}} \sphinxAtStartPar Utilities: \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_is_config_principal:c.krb5_is_config_principal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_is\_config\_principal()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_kuserok:c.krb5_kuserok}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_kuserok()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_set_password:c.krb5_set_password}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_set\_password()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_set_password_using_ccache:c.krb5_set_password_using_ccache}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_set\_password\_using\_ccache()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_set_principal_realm:c.krb5_set_principal_realm}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_set\_principal\_realm()}}}}} \sphinxAtStartPar {\hyperref[\detokenize{appdev/refs/api/krb5_realm_compare:c.krb5_realm_compare}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_realm\_compare()}}}}} \sphinxstepscope \chapter{Complete reference \sphinxhyphen{} API and datatypes} \label{\detokenize{appdev/refs/index:complete-reference-api-and-datatypes}}\label{\detokenize{appdev/refs/index::doc}} \sphinxstepscope \section{krb5 API} \label{\detokenize{appdev/refs/api/index:krb5-api}}\label{\detokenize{appdev/refs/api/index::doc}} \subsection{Frequently used public interfaces} \label{\detokenize{appdev/refs/api/index:frequently-used-public-interfaces}} \sphinxstepscope \subsubsection{krb5\_build\_principal \sphinxhyphen{} Build a principal name using null\sphinxhyphen{}terminated strings.} \label{\detokenize{appdev/refs/api/krb5_build_principal:krb5-build-principal-build-a-principal-name-using-null-terminated-strings}}\label{\detokenize{appdev/refs/api/krb5_build_principal::doc}}\index{krb5\_build\_principal (C function)@\spxentry{krb5\_build\_principal}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_build_principal:c.krb5_build_principal}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_build\_principal}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{princ}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{rlen}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}\sphinxparamcomma \DUrole{p}{...}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{princ} \sphinxhyphen{} Principal name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rlen} \sphinxhyphen{} Realm name length \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Realm name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Call krb5\_free\_principal() to free \sphinxstyleemphasis{princ} when it is no longer needed. \sphinxAtStartPar Beginning with release 1.20, the name type of the principal will be inferred as \sphinxstylestrong{KRB5\_NT\_SRV\_INST} or \sphinxstylestrong{KRB5\_NT\_WELLKNOWN} based on the principal name. The type will be \sphinxstylestrong{KRB5\_NT\_PRINCIPAL} if a type cannot be inferred. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar krb5\_build\_principal() and krb5\_build\_principal\_alloc\_va() perform the same task. krb5\_build\_principal() takes variadic arguments. krb5\_build\_principal\_alloc\_va() takes a pre\sphinxhyphen{}computed \sphinxstyleemphasis{varargs} pointer. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_build\_principal\_alloc\_va \sphinxhyphen{} Build a principal name, using a precomputed variable argument list.} \label{\detokenize{appdev/refs/api/krb5_build_principal_alloc_va:krb5-build-principal-alloc-va-build-a-principal-name-using-a-precomputed-variable-argument-list}}\label{\detokenize{appdev/refs/api/krb5_build_principal_alloc_va::doc}}\index{krb5\_build\_principal\_alloc\_va (C function)@\spxentry{krb5\_build\_principal\_alloc\_va}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_build_principal_alloc_va:c.krb5_build_principal_alloc_va}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_build\_principal\_alloc\_va}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{princ}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{rlen}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}\sphinxparamcomma \DUrole{n}{va\_list}\DUrole{w}{ }\DUrole{n}{ap}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{princ} \sphinxhyphen{} Principal structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rlen} \sphinxhyphen{} Realm name length \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Realm name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ap} \sphinxhyphen{} List of char * components, ending with NULL \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Similar to krb5\_build\_principal(), this function builds a principal name, but its name components are specified as a va\_list. \sphinxAtStartPar Use krb5\_free\_principal() to deallocate \sphinxstyleemphasis{princ} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_build\_principal\_ext \sphinxhyphen{} Build a principal name using length\sphinxhyphen{}counted strings.} \label{\detokenize{appdev/refs/api/krb5_build_principal_ext:krb5-build-principal-ext-build-a-principal-name-using-length-counted-strings}}\label{\detokenize{appdev/refs/api/krb5_build_principal_ext::doc}}\index{krb5\_build\_principal\_ext (C function)@\spxentry{krb5\_build\_principal\_ext}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_build_principal_ext:c.krb5_build_principal_ext}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_build\_principal\_ext}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{princ}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{rlen}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}\sphinxparamcomma \DUrole{p}{...}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{princ} \sphinxhyphen{} Principal name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rlen} \sphinxhyphen{} Realm name length \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Realm name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a principal from a length\sphinxhyphen{}counted string and a variable\sphinxhyphen{}length list of length\sphinxhyphen{}counted components. The list of components ends with the first 0 length argument (so it is not possible to specify an empty component with this function). Call krb5\_free\_principal() to free allocated memory for principal when it is no longer needed. \sphinxAtStartPar Beginning with release 1.20, the name type of the principal will be inferred as \sphinxstylestrong{KRB5\_NT\_SRV\_INST} or \sphinxstylestrong{KRB5\_NT\_WELLKNOWN} based on the principal name. The type will be \sphinxstylestrong{KRB5\_NT\_PRINCIPAL} if a type cannot be inferred. \sphinxstepscope \subsubsection{krb5\_cc\_close \sphinxhyphen{} Close a credential cache handle.} \label{\detokenize{appdev/refs/api/krb5_cc_close:krb5-cc-close-close-a-credential-cache-handle}}\label{\detokenize{appdev/refs/api/krb5_cc_close::doc}}\index{krb5\_cc\_close (C function)@\spxentry{krb5\_cc\_close}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_close:c.krb5_cc_close}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_close}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function closes a credential cache handle \sphinxstyleemphasis{cache} without affecting the contents of the cache. \sphinxstepscope \subsubsection{krb5\_cc\_default \sphinxhyphen{} Resolve the default credential cache name.} \label{\detokenize{appdev/refs/api/krb5_cc_default:krb5-cc-default-resolve-the-default-credential-cache-name}}\label{\detokenize{appdev/refs/api/krb5_cc_default::doc}}\index{krb5\_cc\_default (C function)@\spxentry{krb5\_cc\_default}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_default:c.krb5_cc_default}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_default}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ccache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Pointer to credential cache name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KV5M\_CONTEXT Bad magic number for \_krb5\_context structure \item {} \sphinxAtStartPar KRB5\_FCC\_INTERNAL The name of the default credential cache cannot be obtained \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Create a handle to the default credential cache as given by krb5\_cc\_default\_name(). \sphinxstepscope \subsubsection{krb5\_cc\_default\_name \sphinxhyphen{} Return the name of the default credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_default_name:krb5-cc-default-name-return-the-name-of-the-default-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_default_name::doc}}\index{krb5\_cc\_default\_name (C function)@\spxentry{krb5\_cc\_default\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_default_name:c.krb5_cc_default_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_default\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Name of default credential cache for the current user. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Return a pointer to the default credential cache name for \sphinxstyleemphasis{context} , as determined by a prior call to krb5\_cc\_set\_default\_name(), by the KRB5CCNAME environment variable, by the default\_ccache\_name profile variable, or by the operating system or build\sphinxhyphen{}time default value. The returned value must not be modified or freed by the caller. The returned value becomes invalid when \sphinxstyleemphasis{context} is destroyed krb5\_free\_context() or if a subsequent call to krb5\_cc\_set\_default\_name() is made on \sphinxstyleemphasis{context} . \sphinxAtStartPar The default credential cache name is cached in \sphinxstyleemphasis{context} between calls to this function, so if the value of KRB5CCNAME changes in the process environment after the first call to this function on, that change will not be reflected in later calls with the same context. The caller can invoke krb5\_cc\_set\_default\_name() with a NULL value of \sphinxstyleemphasis{name} to clear the cached value and force the default name to be recomputed. \sphinxstepscope \subsubsection{krb5\_cc\_destroy \sphinxhyphen{} Destroy a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_destroy:krb5-cc-destroy-destroy-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_destroy::doc}}\index{krb5\_cc\_destroy (C function)@\spxentry{krb5\_cc\_destroy}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_destroy:c.krb5_cc_destroy}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_destroy}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Permission errors \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function destroys any existing contents of \sphinxstyleemphasis{cache} and closes the handle to it. \sphinxstepscope \subsubsection{krb5\_cc\_dup \sphinxhyphen{} Duplicate ccache handle.} \label{\detokenize{appdev/refs/api/krb5_cc_dup:krb5-cc-dup-duplicate-ccache-handle}}\label{\detokenize{appdev/refs/api/krb5_cc_dup::doc}}\index{krb5\_cc\_dup (C function)@\spxentry{krb5\_cc\_dup}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_dup:c.krb5_cc_dup}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_dup}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{in}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in} \sphinxhyphen{} Credential cache handle to be duplicated \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \sphinxAtStartPar Create a new handle referring to the same cache as \sphinxstyleemphasis{in} . The new handle and \sphinxstyleemphasis{in} can be closed independently. \sphinxstepscope \subsubsection{krb5\_cc\_get\_name \sphinxhyphen{} Retrieve the name, but not type of a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_get_name:krb5-cc-get-name-retrieve-the-name-but-not-type-of-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_get_name::doc}}\index{krb5\_cc\_get\_name (C function)@\spxentry{krb5\_cc\_get\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_get_name:c.krb5_cc_get_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_get\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar On success \sphinxhyphen{} the name of the credential cache. \end{itemize} \end{description}\end{quote} \begin{sphinxadmonition}{warning}{Warning:} \sphinxAtStartPar Returns the name of the credential cache. The result is an alias into \sphinxstyleemphasis{cache} and should not be freed or modified by the caller. This name does not include the cache type, so should not be used as input to krb5\_cc\_resolve(). \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cc\_get\_principal \sphinxhyphen{} Get the default principal of a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_get_principal:krb5-cc-get-principal-get-the-default-principal-of-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_get_principal::doc}}\index{krb5\_cc\_get\_principal (C function)@\spxentry{krb5\_cc\_get\_principal}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_get_principal:c.krb5_cc_get_principal}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_get\_principal}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{principal}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Primary principal \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Returns the default client principal of a credential cache as set by krb5\_cc\_initialize(). \sphinxAtStartPar Use krb5\_free\_principal() to free \sphinxstyleemphasis{principal} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_cc\_get\_type \sphinxhyphen{} Retrieve the type of a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_get_type:krb5-cc-get-type-retrieve-the-type-of-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_get_type::doc}}\index{krb5\_cc\_get\_type (C function)@\spxentry{krb5\_cc\_get\_type}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_get_type:c.krb5_cc_get_type}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_get\_type}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar The type of a credential cache as an alias that must not be modified or freed by the caller. \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_cc\_initialize \sphinxhyphen{} Initialize a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_initialize:krb5-cc-initialize-initialize-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_initialize::doc}}\index{krb5\_cc\_initialize (C function)@\spxentry{krb5\_cc\_initialize}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_initialize:c.krb5_cc_initialize}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_initialize}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Default principal name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar System errors; Permission errors; Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Destroy any existing contents of \sphinxstyleemphasis{cache} and initialize it for the default principal \sphinxstyleemphasis{principal} . \sphinxstepscope \subsubsection{krb5\_cc\_new\_unique \sphinxhyphen{} Create a new credential cache of the specified type with a unique name.} \label{\detokenize{appdev/refs/api/krb5_cc_new_unique:krb5-cc-new-unique-create-a-new-credential-cache-of-the-specified-type-with-a-unique-name}}\label{\detokenize{appdev/refs/api/krb5_cc_new_unique::doc}}\index{krb5\_cc\_new\_unique (C function)@\spxentry{krb5\_cc\_new\_unique}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_new_unique:c.krb5_cc_new_unique}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_new\_unique}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{type}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{hint}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{id}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{type} \sphinxhyphen{} Credential cache type name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{hint} \sphinxhyphen{} Unused \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{id} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_cc\_resolve \sphinxhyphen{} Resolve a credential cache name.} \label{\detokenize{appdev/refs/api/krb5_cc_resolve:krb5-cc-resolve-resolve-a-credential-cache-name}}\label{\detokenize{appdev/refs/api/krb5_cc_resolve::doc}}\index{krb5\_cc\_resolve (C function)@\spxentry{krb5\_cc\_resolve}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_resolve:c.krb5_cc_resolve}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_resolve}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{name} \sphinxhyphen{} Credential cache name to be resolved \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Fills in \sphinxstyleemphasis{cache} with a \sphinxstyleemphasis{cache} handle that corresponds to the name in \sphinxstyleemphasis{name} . \sphinxstyleemphasis{name} should be of the form \sphinxstylestrong{type:residual} , and \sphinxstyleemphasis{type} must be a type known to the library. If the \sphinxstyleemphasis{name} does not contain a colon, interpret it as a file name. \sphinxstepscope \subsubsection{krb5\_change\_password \sphinxhyphen{} Change a password for an existing Kerberos account.} \label{\detokenize{appdev/refs/api/krb5_change_password:krb5-change-password-change-a-password-for-an-existing-kerberos-account}}\label{\detokenize{appdev/refs/api/krb5_change_password::doc}}\index{krb5\_change\_password (C function)@\spxentry{krb5\_change\_password}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_change_password:c.krb5_change_password}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_change\_password}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{newpw}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{result\_code}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{result\_code\_string}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{result\_string}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Credentials for kadmin/changepw service \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{newpw} \sphinxhyphen{} New password \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{result\_code} \sphinxhyphen{} Numeric error code from server \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{result\_code\_string} \sphinxhyphen{} String equivalent to \sphinxstyleemphasis{result\_code} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{result\_string} \sphinxhyphen{} Change password response from the KDC \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Change the password for the existing principal identified by \sphinxstyleemphasis{creds} . \sphinxAtStartPar The possible values of the output \sphinxstyleemphasis{result\_code} are: \begin{itemize} \item {} \sphinxAtStartPar KRB5\_KPASSWD\_SUCCESS (0) \sphinxhyphen{} success \item {} \sphinxAtStartPar KRB5\_KPASSWD\_MALFORMED (1) \sphinxhyphen{} Malformed request error \item {} \sphinxAtStartPar KRB5\_KPASSWD\_HARDERROR (2) \sphinxhyphen{} Server error \item {} \sphinxAtStartPar KRB5\_KPASSWD\_AUTHERROR (3) \sphinxhyphen{} Authentication error \item {} \sphinxAtStartPar KRB5\_KPASSWD\_SOFTERROR (4) \sphinxhyphen{} Password change rejected \end{itemize} \sphinxstepscope \subsubsection{krb5\_chpw\_message \sphinxhyphen{} Get a result message for changing or setting a password.} \label{\detokenize{appdev/refs/api/krb5_chpw_message:krb5-chpw-message-get-a-result-message-for-changing-or-setting-a-password}}\label{\detokenize{appdev/refs/api/krb5_chpw_message::doc}}\index{krb5\_chpw\_message (C function)@\spxentry{krb5\_chpw\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_chpw_message:c.krb5_chpw_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_chpw\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{server\_string}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{message\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server\_string} \sphinxhyphen{} Data returned from the remote system \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{message\_out} \sphinxhyphen{} A message displayable to the user \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function processes the \sphinxstyleemphasis{server\_string} returned in the \sphinxstyleemphasis{result\_string} parameter of krb5\_change\_password(), krb5\_set\_password(), and related functions, and returns a displayable string. If \sphinxstyleemphasis{server\_string} contains Active Directory structured policy information, it will be converted into human\sphinxhyphen{}readable text. \sphinxAtStartPar Use krb5\_free\_string() to free \sphinxstyleemphasis{message\_out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_expand\_hostname \sphinxhyphen{} Canonicalize a hostname, possibly using name service.} \label{\detokenize{appdev/refs/api/krb5_expand_hostname:krb5-expand-hostname-canonicalize-a-hostname-possibly-using-name-service}}\label{\detokenize{appdev/refs/api/krb5_expand_hostname::doc}}\index{krb5\_expand\_hostname (C function)@\spxentry{krb5\_expand\_hostname}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_expand_hostname:c.krb5_expand_hostname}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_expand\_hostname}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{host}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{canonhost\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{host} \sphinxhyphen{} Input hostname \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{canonhost\_out} \sphinxhyphen{} Canonicalized hostname \end{description}\end{quote} \sphinxAtStartPar This function canonicalizes orig\_hostname, possibly using name service lookups if configuration permits. Use krb5\_free\_string() to free \sphinxstyleemphasis{canonhost\_out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.15 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_free\_config\_files \sphinxhyphen{} Free a list allocated by krb5\_get\_default\_config\_files()} \label{\detokenize{appdev/refs/api/krb5_free_config_files:krb5-free-config-files-free-a-list-allocated-by-krb5-get-default-config-files}}\label{\detokenize{appdev/refs/api/krb5_free_config_files::doc}}\index{krb5\_free\_config\_files (C function)@\spxentry{krb5\_free\_config\_files}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_config_files:c.krb5_free_config_files}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_config\_files}}}}{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{filenames}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{filenames} \sphinxhyphen{} Configuration filename list \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.22 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_free\_context \sphinxhyphen{} Free a krb5 library context.} \label{\detokenize{appdev/refs/api/krb5_free_context:krb5-free-context-free-a-krb5-library-context}}\label{\detokenize{appdev/refs/api/krb5_free_context::doc}}\index{krb5\_free\_context (C function)@\spxentry{krb5\_free\_context}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_context:c.krb5_free_context}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_context}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \end{description}\end{quote} \sphinxAtStartPar This function frees a \sphinxstyleemphasis{context} that was created by krb5\_init\_context() or krb5\_init\_secure\_context(). \sphinxstepscope \subsubsection{krb5\_free\_error\_message \sphinxhyphen{} Free an error message generated by krb5\_get\_error\_message().} \label{\detokenize{appdev/refs/api/krb5_free_error_message:krb5-free-error-message-free-an-error-message-generated-by-krb5-get-error-message}}\label{\detokenize{appdev/refs/api/krb5_free_error_message::doc}}\index{krb5\_free\_error\_message (C function)@\spxentry{krb5\_free\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_error_message:c.krb5_free_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{msg}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{msg} \sphinxhyphen{} Pointer to error message \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_free\_principal \sphinxhyphen{} Free the storage assigned to a principal.} \label{\detokenize{appdev/refs/api/krb5_free_principal:krb5-free-principal-free-the-storage-assigned-to-a-principal}}\label{\detokenize{appdev/refs/api/krb5_free_principal::doc}}\index{krb5\_free\_principal (C function)@\spxentry{krb5\_free\_principal}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_principal:c.krb5_free_principal}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_principal}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Principal to be freed \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_fwd\_tgt\_creds \sphinxhyphen{} Get a forwarded TGT and format a KRB\sphinxhyphen{}CRED message.} \label{\detokenize{appdev/refs/api/krb5_fwd_tgt_creds:krb5-fwd-tgt-creds-get-a-forwarded-tgt-and-format-a-krb-cred-message}}\label{\detokenize{appdev/refs/api/krb5_fwd_tgt_creds::doc}}\index{krb5\_fwd\_tgt\_creds (C function)@\spxentry{krb5\_fwd\_tgt\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_fwd_tgt_creds:c.krb5_fwd_tgt_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_fwd\_tgt\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rhost}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{client}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{server}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cc}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{forwardable}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{outbuf}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rhost} \sphinxhyphen{} Remote host \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{client} \sphinxhyphen{} Client principal of TGT \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Principal of server to receive TGT \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cc} \sphinxhyphen{} Credential cache handle (NULL to use default) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{forwardable} \sphinxhyphen{} Whether TGT should be forwardable \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outbuf} \sphinxhyphen{} KRB\sphinxhyphen{}CRED message \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar ENOMEM Insufficient memory \item {} \sphinxAtStartPar KRB5\_PRINC\_NOMATCH Requested principal and ticket do not match \item {} \sphinxAtStartPar KRB5\_NO\_TKT\_SUPPLIED Request did not supply a ticket \item {} \sphinxAtStartPar KRB5\_CC\_BADNAME Credential cache name or principal name malformed \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Get a TGT for use at the remote host \sphinxstyleemphasis{rhost} and format it into a KRB\sphinxhyphen{}CRED message. If \sphinxstyleemphasis{rhost} is NULL and \sphinxstyleemphasis{server} is of type KRB5\_NT\_SRV\_HST, the second component of \sphinxstyleemphasis{server} will be used. \sphinxstepscope \subsubsection{krb5\_get\_default\_realm \sphinxhyphen{} Retrieve the default realm.} \label{\detokenize{appdev/refs/api/krb5_get_default_realm:krb5-get-default-realm-retrieve-the-default-realm}}\label{\detokenize{appdev/refs/api/krb5_get_default_realm::doc}}\index{krb5\_get\_default\_realm (C function)@\spxentry{krb5\_get\_default\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_default_realm:c.krb5_get_default_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_default\_realm}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{lrealm}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{lrealm} \sphinxhyphen{} Default realm name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Retrieves the default realm to be used if no user\sphinxhyphen{}specified realm is available. \sphinxAtStartPar Use krb5\_free\_default\_realm() to free \sphinxstyleemphasis{lrealm} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_get\_error\_message \sphinxhyphen{} Get the (possibly extended) error message for a code.} \label{\detokenize{appdev/refs/api/krb5_get_error_message:krb5-get-error-message-get-the-possibly-extended-error-message-for-a-code}}\label{\detokenize{appdev/refs/api/krb5_get_error_message::doc}}\index{krb5\_get\_error\_message (C function)@\spxentry{krb5\_get\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_error_message:c.krb5_get_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\DUrole{n}{code}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{code} \sphinxhyphen{} Error code \end{description}\end{quote} \sphinxAtStartPar The behavior of krb5\_get\_error\_message() is only defined the first time it is called after a failed call to a krb5 function using the same context, and only when the error code passed in is the same as that returned by the krb5 function. \sphinxAtStartPar This function never returns NULL, so its result may be used unconditionally as a C string. \sphinxAtStartPar The string returned by this function must be freed using krb5\_free\_error\_message() \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar Future versions may return the same string for the second and following calls. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_get\_host\_realm \sphinxhyphen{} Get the Kerberos realm names for a host.} \label{\detokenize{appdev/refs/api/krb5_get_host_realm:krb5-get-host-realm-get-the-kerberos-realm-names-for-a-host}}\label{\detokenize{appdev/refs/api/krb5_get_host_realm::doc}}\index{krb5\_get\_host\_realm (C function)@\spxentry{krb5\_get\_host\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_host_realm:c.krb5_get_host_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_host\_realm}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{host}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{realmsp}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{host} \sphinxhyphen{} Host name (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{realmsp} \sphinxhyphen{} Null\sphinxhyphen{}terminated list of realm names \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar ENOMEM Insufficient memory \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Fill in \sphinxstyleemphasis{realmsp} with a pointer to a null\sphinxhyphen{}terminated list of realm names. If there are no known realms for the host, a list containing the referral (empty) realm is returned. \sphinxAtStartPar If \sphinxstyleemphasis{host} is NULL, the local host’s realms are determined. \sphinxAtStartPar Use krb5\_free\_host\_realm() to release \sphinxstyleemphasis{realmsp} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_get\_credentials \sphinxhyphen{} Get an additional ticket.} \label{\detokenize{appdev/refs/api/krb5_get_credentials:krb5-get-credentials-get-an-additional-ticket}}\label{\detokenize{appdev/refs/api/krb5_get_credentials::doc}}\index{krb5\_get\_credentials (C function)@\spxentry{krb5\_get\_credentials}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_credentials:c.krb5_get_credentials}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_credentials}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{out\_creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{options} \sphinxhyphen{} Options \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_creds} \sphinxhyphen{} Input credentials \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out\_creds} \sphinxhyphen{} Output updated credentials \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use \sphinxstyleemphasis{ccache} or a TGS exchange to get a service ticket matching \sphinxstyleemphasis{in\_creds} . \sphinxAtStartPar Valid values for \sphinxstyleemphasis{options} are: \begin{quote} \begin{itemize} \item {} \sphinxAtStartPar KRB5\_GC\_CACHED Search only credential cache for the ticket \item {} \sphinxAtStartPar KRB5\_GC\_USER\_USER Return a user to user authentication ticket \end{itemize} \sphinxAtStartPar \sphinxstyleemphasis{in\_creds} must be non\sphinxhyphen{}null. \sphinxstyleemphasis{in\_creds\sphinxhyphen{}\textgreater{}client} and \sphinxstyleemphasis{in\_creds\sphinxhyphen{}\textgreater{}server} must be filled in to specify the client and the server respectively. If any authorization data needs to be requested for the service ticket (such as restrictions on how the ticket can be used), specify it in \sphinxstyleemphasis{in\_creds\sphinxhyphen{}\textgreater{}authdata} ; otherwise set \sphinxstyleemphasis{in\_creds\sphinxhyphen{}\textgreater{}authdata} to NULL. The session key type is specified in \sphinxstyleemphasis{in\_creds\sphinxhyphen{}\textgreater{}keyblock.enctype} , if it is nonzero. \end{quote} \sphinxAtStartPar If \sphinxstyleemphasis{in\_creds\sphinxhyphen{}\textgreater{}times.endtime} is specified, it is used as the requested expiration date if a TGS request is made. If \sphinxstyleemphasis{in\_creds\sphinxhyphen{}\textgreater{}times.endtime} is set to 0, the latest possible expiration date will be requested. The KDC or cache may return a ticket with an earlier expiration date. \sphinxAtStartPar Any returned ticket and intermediate ticket\sphinxhyphen{}granting tickets are stored in \sphinxstyleemphasis{ccache} . \sphinxAtStartPar Use krb5\_free\_creds() to free \sphinxstyleemphasis{out\_creds} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_get\_default\_config\_files \sphinxhyphen{} Return a list of default configuration filenames.} \label{\detokenize{appdev/refs/api/krb5_get_default_config_files:krb5-get-default-config-files-return-a-list-of-default-configuration-filenames}}\label{\detokenize{appdev/refs/api/krb5_get_default_config_files::doc}}\index{krb5\_get\_default\_config\_files (C function)@\spxentry{krb5\_get\_default\_config\_files}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_default_config_files:c.krb5_get_default_config_files}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_default\_config\_files}}}}{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{filenames}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{filenames} \sphinxhyphen{} Configuration filename list \end{description}\end{quote} \sphinxAtStartPar Fill in \sphinxstyleemphasis{filenames} with a null\sphinxhyphen{}terminated list of configuration files which will be read by krb5\_init\_context() in the current process environment. \sphinxAtStartPar Use krb5\_free\_config\_files() to free \sphinxstyleemphasis{filenames} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.22 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_get\_fallback\_host\_realm} \label{\detokenize{appdev/refs/api/krb5_get_fallback_host_realm:krb5-get-fallback-host-realm}}\label{\detokenize{appdev/refs/api/krb5_get_fallback_host_realm::doc}}\index{krb5\_get\_fallback\_host\_realm (C function)@\spxentry{krb5\_get\_fallback\_host\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_fallback_host_realm:c.krb5_get_fallback_host_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_fallback\_host\_realm}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{hdata}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{realmsp}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{hdata} \sphinxhyphen{} Host name (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{realmsp} \sphinxhyphen{} Null\sphinxhyphen{}terminated list of realm names \end{description}\end{quote} \sphinxAtStartPar Fill in \sphinxstyleemphasis{realmsp} with a pointer to a null\sphinxhyphen{}terminated list of realm names obtained through heuristics or insecure resolution methods which have lower priority than KDC referrals. \sphinxAtStartPar If \sphinxstyleemphasis{host} is NULL, the local host’s realms are determined. \sphinxAtStartPar Use krb5\_free\_host\_realm() to release \sphinxstyleemphasis{realmsp} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_keytab \sphinxhyphen{} Get initial credentials using a key table.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_keytab:krb5-get-init-creds-keytab-get-initial-credentials-using-a-key-table}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_keytab::doc}}\index{krb5\_get\_init\_creds\_keytab (C function)@\spxentry{krb5\_get\_init\_creds\_keytab}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_keytab:c.krb5_get_init_creds_keytab}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_keytab}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{client}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{arg\_keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}]{\sphinxcrossref{\DUrole{n}{krb5\_deltat}}}}\DUrole{w}{ }\DUrole{n}{start\_time}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_tkt\_service}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k5\_gic\_options}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds} \sphinxhyphen{} New credentials \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{client} \sphinxhyphen{} Client principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{arg\_keytab} \sphinxhyphen{} Key table handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{start\_time} \sphinxhyphen{} Time when ticket becomes valid (0 for now) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_tkt\_service} \sphinxhyphen{} Service name of initial credentials (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{k5\_gic\_options} \sphinxhyphen{} Initial credential options \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function requests KDC for an initial credentials for \sphinxstyleemphasis{client} using a client key stored in \sphinxstyleemphasis{arg\_keytab} . If \sphinxstyleemphasis{in\_tkt\_service} is specified, it is parsed as a principal name (with the realm ignored) and used as the service principal for the request; otherwise the ticket\sphinxhyphen{}granting service is used. \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_alloc \sphinxhyphen{} Allocate a new initial credential options structure.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_alloc:krb5-get-init-creds-opt-alloc-allocate-a-new-initial-credential-options-structure}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_alloc::doc}}\index{krb5\_get\_init\_creds\_opt\_alloc (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_alloc}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_alloc:c.krb5_get_init_creds_opt_alloc}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_alloc}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{opt}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{opt} \sphinxhyphen{} New options structure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 \sphinxhyphen{} Success; Kerberos errors otherwise. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function is the preferred way to create an options structure for getting initial credentials, and is required to make use of certain options. Use krb5\_get\_init\_creds\_opt\_free() to free \sphinxstyleemphasis{opt} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_free \sphinxhyphen{} Free initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_free:krb5-get-init-creds-opt-free-free-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_free::doc}}\index{krb5\_get\_init\_creds\_opt\_free (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_free}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_free:c.krb5_get_init_creds_opt_free}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_free}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure to free \end{description}\end{quote} \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_get\_init\_creds\_opt\_alloc() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_get\_fast\_flags \sphinxhyphen{} Retrieve FAST flags from initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_get_fast_flags:krb5-get-init-creds-opt-get-fast-flags-retrieve-fast-flags-from-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_get_fast_flags::doc}}\index{krb5\_get\_init\_creds\_opt\_get\_fast\_flags (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_get\_fast\_flags}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_get_fast_flags:c.krb5_get_init_creds_opt_get_fast_flags}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_get\_fast\_flags}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{out\_flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out\_flags} \sphinxhyphen{} FAST flags \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 \sphinxhyphen{} Success; Kerberos errors otherwise. \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_address\_list \sphinxhyphen{} Set address restrictions in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_address_list:krb5-get-init-creds-opt-set-address-list-set-address-restrictions-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_address_list::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_address\_list (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_address\_list}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_address_list:c.krb5_get_init_creds_opt_set_address_list}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_address\_list}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{addresses}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{addresses} \sphinxhyphen{} Null\sphinxhyphen{}terminated array of addresses \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_anonymous \sphinxhyphen{} Set or unset the anonymous flag in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_anonymous:krb5-get-init-creds-opt-set-anonymous-set-or-unset-the-anonymous-flag-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_anonymous::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_anonymous (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_anonymous}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_anonymous:c.krb5_get_init_creds_opt_set_anonymous}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_anonymous}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{anonymous}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{anonymous} \sphinxhyphen{} Whether to make an anonymous request \end{description}\end{quote} \sphinxAtStartPar This function may be used to request anonymous credentials from the KDC by setting \sphinxstyleemphasis{anonymous} to non\sphinxhyphen{}zero. Note that anonymous credentials are only a request; clients must verify that credentials are anonymous if that is a requirement. \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_canonicalize \sphinxhyphen{} Set or unset the canonicalize flag in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_canonicalize:krb5-get-init-creds-opt-set-canonicalize-set-or-unset-the-canonicalize-flag-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_canonicalize::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_canonicalize (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_canonicalize}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_canonicalize:c.krb5_get_init_creds_opt_set_canonicalize}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_canonicalize}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{canonicalize}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{canonicalize} \sphinxhyphen{} Whether to canonicalize client principal \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_change\_password\_prompt \sphinxhyphen{} Set or unset change\sphinxhyphen{}password\sphinxhyphen{}prompt flag in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_change_password_prompt:krb5-get-init-creds-opt-set-change-password-prompt-set-or-unset-change-password-prompt-flag-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_change_password_prompt::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_change\_password\_prompt (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_change\_password\_prompt}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_change_password_prompt:c.krb5_get_init_creds_opt_set_change_password_prompt}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_change\_password\_prompt}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{prompt}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{prompt} \sphinxhyphen{} Whether to prompt to change password \end{description}\end{quote} \sphinxAtStartPar This flag is on by default. It controls whether krb5\_get\_init\_creds\_password() will react to an expired\sphinxhyphen{}password error by prompting for a new password and attempting to change the old one. \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_etype\_list \sphinxhyphen{} Set allowable encryption types in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_etype_list:krb5-get-init-creds-opt-set-etype-list-set-allowable-encryption-types-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_etype_list::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_etype\_list (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_etype\_list}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_etype_list:c.krb5_get_init_creds_opt_set_etype_list}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_etype\_list}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{etype\_list}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{etype\_list\_length}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{etype\_list} \sphinxhyphen{} Array of encryption types \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{etype\_list\_length} \sphinxhyphen{} Length of \sphinxstyleemphasis{etype\_list} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_expire\_callback \sphinxhyphen{} Set an expiration callback in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_expire_callback:krb5-get-init-creds-opt-set-expire-callback-set-an-expiration-callback-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_expire_callback::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_expire\_callback (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_expire\_callback}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_expire_callback:c.krb5_get_init_creds_opt_set_expire_callback}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_expire\_callback}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_expire_callback_func:c.krb5_expire_callback_func}]{\sphinxcrossref{\DUrole{n}{krb5\_expire\_callback\_func}}}}\DUrole{w}{ }\DUrole{n}{cb}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cb} \sphinxhyphen{} Callback function \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Callback argument \end{description}\end{quote} \sphinxAtStartPar Set a callback to receive password and account expiration times. \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{cb} will be invoked if and only if credentials are successfully acquired. The callback will receive the \sphinxstyleemphasis{context} from the calling function and the \sphinxstyleemphasis{data} argument supplied with this API. The remaining arguments should be interpreted as follows: \end{quote} \sphinxAtStartPar If \sphinxstyleemphasis{is\_last\_req} is true, then the KDC reply contained last\sphinxhyphen{}req entries which unambiguously indicated the password expiration, account expiration, or both. (If either value was not present, the corresponding argument will be 0.) Furthermore, a non\sphinxhyphen{}zero \sphinxstyleemphasis{password\_expiration} should be taken as a suggestion from the KDC that a warning be displayed. \sphinxAtStartPar If \sphinxstyleemphasis{is\_last\_req} is false, then \sphinxstyleemphasis{account\_expiration} will be 0 and \sphinxstyleemphasis{password\_expiration} will contain the expiration time of either the password or account, or 0 if no expiration time was indicated in the KDC reply. The callback should independently decide whether to display a password expiration warning. \sphinxAtStartPar Note that \sphinxstyleemphasis{cb} may be invoked even if credentials are being acquired for the kadmin/changepw service in order to change the password. It is the caller’s responsibility to avoid displaying a password expiry warning in this case. \begin{sphinxadmonition}{warning}{Warning:} \sphinxAtStartPar Setting an expire callback with this API will cause krb5\_get\_init\_creds\_password() not to send password expiry warnings to the prompter, as it ordinarily may. \end{sphinxadmonition} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_fast\_ccache \sphinxhyphen{} Set FAST armor cache in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache:krb5-get-init-creds-opt-set-fast-ccache-set-fast-armor-cache-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_fast\_ccache (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_fast\_ccache}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache:c.krb5_get_init_creds_opt_set_fast_ccache}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_fast\_ccache}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \sphinxAtStartPar This function is similar to krb5\_get\_init\_creds\_opt\_set\_fast\_ccache\_name(), but uses a credential cache handle instead of a name. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_fast\_ccache\_name \sphinxhyphen{} Set location of FAST armor ccache in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache_name:krb5-get-init-creds-opt-set-fast-ccache-name-set-location-of-fast-armor-ccache-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache_name::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_fast\_ccache\_name (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_fast\_ccache\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache_name:c.krb5_get_init_creds_opt_set_fast_ccache_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_fast\_ccache\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{fast\_ccache\_name}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fast\_ccache\_name} \sphinxhyphen{} Credential cache name \end{description}\end{quote} \sphinxAtStartPar Sets the location of a credential cache containing an armor ticket to protect an initial credential exchange using the FAST protocol extension. \sphinxAtStartPar In version 1.7, setting an armor ccache requires that FAST be used for the exchange. In version 1.8 or later, setting the armor ccache causes FAST to be used if the KDC supports it; krb5\_get\_init\_creds\_opt\_set\_fast\_flags() must be used to require that FAST be used. \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_fast\_flags \sphinxhyphen{} Set FAST flags in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_fast_flags:krb5-get-init-creds-opt-set-fast-flags-set-fast-flags-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_fast_flags::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_fast\_flags (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_fast\_flags}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_fast_flags:c.krb5_get_init_creds_opt_set_fast_flags}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_fast\_flags}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} FAST flags \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 \sphinxhyphen{} Success; Kerberos errors otherwise. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar The following flag values are valid: \begin{itemize} \item {} \sphinxAtStartPar KRB5\_FAST\_REQUIRED \sphinxhyphen{} Require FAST to be used \end{itemize} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_forwardable \sphinxhyphen{} Set or unset the forwardable flag in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_forwardable:krb5-get-init-creds-opt-set-forwardable-set-or-unset-the-forwardable-flag-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_forwardable::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_forwardable (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_forwardable}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_forwardable:c.krb5_get_init_creds_opt_set_forwardable}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_forwardable}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{forwardable}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{forwardable} \sphinxhyphen{} Whether credentials should be forwardable \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_in\_ccache \sphinxhyphen{} Set an input credential cache in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_in_ccache:krb5-get-init-creds-opt-set-in-ccache-set-an-input-credential-cache-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_in_ccache::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_in\_ccache (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_in\_ccache}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_in_ccache:c.krb5_get_init_creds_opt_set_in_ccache}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_in\_ccache}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \sphinxAtStartPar If an input credential cache is set, then the krb5\_get\_init\_creds family of APIs will read settings from it. Setting an input ccache is desirable when the application wishes to perform authentication in the same way (using the same preauthentication mechanisms, and making the same non\sphinxhyphen{}security\sphinxhyphen{} sensitive choices) as the previous authentication attempt, which stored information in the passed\sphinxhyphen{}in ccache. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_out\_ccache \sphinxhyphen{} Set an output credential cache in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_out_ccache:krb5-get-init-creds-opt-set-out-ccache-set-an-output-credential-cache-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_out_ccache::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_out\_ccache (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_out\_ccache}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_out_ccache:c.krb5_get_init_creds_opt_set_out_ccache}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_out\_ccache}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \sphinxAtStartPar If an output credential cache is set, then the krb5\_get\_init\_creds family of APIs will write credentials to it. Setting an output ccache is desirable both because it simplifies calling code and because it permits the krb5\_get\_init\_creds APIs to write out configuration information about the realm to the ccache. \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_pa \sphinxhyphen{} Supply options for preauthentication in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_pa:krb5-get-init-creds-opt-set-pa-supply-options-for-preauthentication-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_pa::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_pa (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_pa}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_pa:c.krb5_get_init_creds_opt_set_pa}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_pa}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{attr}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{value}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{attr} \sphinxhyphen{} Preauthentication option name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{value} \sphinxhyphen{} Preauthentication option value \end{description}\end{quote} \sphinxAtStartPar This function allows the caller to supply options for preauthentication. The values of \sphinxstyleemphasis{attr} and \sphinxstyleemphasis{value} are supplied to each preauthentication module available within \sphinxstyleemphasis{context} . \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_pac\_request \sphinxhyphen{} Ask the KDC to include or not include a PAC in the ticket.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_pac_request:krb5-get-init-creds-opt-set-pac-request-ask-the-kdc-to-include-or-not-include-a-pac-in-the-ticket}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_pac_request::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_pac\_request (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_pac\_request}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_pac_request:c.krb5_get_init_creds_opt_set_pac_request}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_pac\_request}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{n}{req\_pac}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{req\_pac} \sphinxhyphen{} Whether to request a PAC or not \end{description}\end{quote} \sphinxAtStartPar If this option is set, the AS request will include a PAC\sphinxhyphen{}REQUEST pa\sphinxhyphen{}data item explicitly asking the KDC to either include or not include a privilege attribute certificate in the ticket authorization data. By default, no request is made; typically the KDC will default to including a PAC if it supports them. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.15 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_preauth\_list \sphinxhyphen{} Set preauthentication types in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_preauth_list:krb5-get-init-creds-opt-set-preauth-list-set-preauthentication-types-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_preauth_list::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_preauth\_list (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_preauth\_list}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_preauth_list:c.krb5_get_init_creds_opt_set_preauth_list}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_preauth\_list}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_preauthtype:c.krb5_preauthtype}]{\sphinxcrossref{\DUrole{n}{krb5\_preauthtype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{preauth\_list}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{preauth\_list\_length}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{preauth\_list} \sphinxhyphen{} Array of preauthentication types \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{preauth\_list\_length} \sphinxhyphen{} Length of \sphinxstyleemphasis{preauth\_list} \end{description}\end{quote} \sphinxAtStartPar This function can be used to perform optimistic preauthentication when getting initial credentials, in combination with krb5\_get\_init\_creds\_opt\_set\_salt() and krb5\_get\_init\_creds\_opt\_set\_pa(). \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_proxiable \sphinxhyphen{} Set or unset the proxiable flag in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_proxiable:krb5-get-init-creds-opt-set-proxiable-set-or-unset-the-proxiable-flag-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_proxiable::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_proxiable (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_proxiable}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_proxiable:c.krb5_get_init_creds_opt_set_proxiable}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_proxiable}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{proxiable}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{proxiable} \sphinxhyphen{} Whether credentials should be proxiable \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_renew\_life \sphinxhyphen{} Set the ticket renewal lifetime in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_renew_life:krb5-get-init-creds-opt-set-renew-life-set-the-ticket-renewal-lifetime-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_renew_life::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_renew\_life (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_renew\_life}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_renew_life:c.krb5_get_init_creds_opt_set_renew_life}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_renew\_life}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}]{\sphinxcrossref{\DUrole{n}{krb5\_deltat}}}}\DUrole{w}{ }\DUrole{n}{renew\_life}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Pointer to \sphinxstyleemphasis{options} field \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{renew\_life} \sphinxhyphen{} Ticket renewal lifetime \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_responder \sphinxhyphen{} Set the responder function in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_responder:krb5-get-init-creds-opt-set-responder-set-the-responder-function-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_responder::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_responder (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_responder}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_responder:c.krb5_get_init_creds_opt_set_responder}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_responder}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_fn:c.krb5_responder_fn}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_fn}}}}\DUrole{w}{ }\DUrole{n}{responder}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{responder} \sphinxhyphen{} Responder function \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Responder data argument \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_salt \sphinxhyphen{} Set salt for optimistic preauthentication in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_salt:krb5-get-init-creds-opt-set-salt-set-salt-for-optimistic-preauthentication-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_salt::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_salt (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_salt}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_salt:c.krb5_get_init_creds_opt_set_salt}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_salt}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{salt}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{salt} \sphinxhyphen{} Salt data \end{description}\end{quote} \sphinxAtStartPar When getting initial credentials with a password, a salt string it used to convert the password to a key. Normally this salt is obtained from the first KDC reply, but when performing optimistic preauthentication, the client may need to supply the salt string with this function. \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_set\_tkt\_life \sphinxhyphen{} Set the ticket lifetime in initial credential options.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_tkt_life:krb5-get-init-creds-opt-set-tkt-life-set-the-ticket-lifetime-in-initial-credential-options}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_tkt_life::doc}}\index{krb5\_get\_init\_creds\_opt\_set\_tkt\_life (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_set\_tkt\_life}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_set_tkt_life:c.krb5_get_init_creds_opt_set_tkt_life}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_set\_tkt\_life}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}]{\sphinxcrossref{\DUrole{n}{krb5\_deltat}}}}\DUrole{w}{ }\DUrole{n}{tkt\_life}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{tkt\_life} \sphinxhyphen{} Ticket lifetime \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_password \sphinxhyphen{} Get initial credentials using a password.} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_password:krb5-get-init-creds-password-get-initial-credentials-using-a-password}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_password::doc}}\index{krb5\_get\_init\_creds\_password (C function)@\spxentry{krb5\_get\_init\_creds\_password}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_password:c.krb5_get_init_creds_password}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_password}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{client}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{password}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_prompter_fct:c.krb5_prompter_fct}]{\sphinxcrossref{\DUrole{n}{krb5\_prompter\_fct}}}}\DUrole{w}{ }\DUrole{n}{prompter}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}]{\sphinxcrossref{\DUrole{n}{krb5\_deltat}}}}\DUrole{w}{ }\DUrole{n}{start\_time}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_tkt\_service}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k5\_gic\_options}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds} \sphinxhyphen{} New credentials \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{client} \sphinxhyphen{} Client principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{password} \sphinxhyphen{} Password (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{prompter} \sphinxhyphen{} Prompter function \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Prompter callback data \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{start\_time} \sphinxhyphen{} Time when ticket becomes valid (0 for now) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_tkt\_service} \sphinxhyphen{} Service name of initial credentials (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{k5\_gic\_options} \sphinxhyphen{} Initial credential options \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar EINVAL Invalid argument \item {} \sphinxAtStartPar KRB5\_KDC\_UNREACH Cannot contact any KDC for requested realm \item {} \sphinxAtStartPar KRB5\_PREAUTH\_FAILED Generic Pre\sphinxhyphen{}athentication failure \item {} \sphinxAtStartPar KRB5\_LIBOS\_PWDINTR Password read interrupted \item {} \sphinxAtStartPar KRB5\_REALM\_CANT\_RESOLVE Cannot resolve network address for KDC in requested realm \item {} \sphinxAtStartPar KRB5KDC\_ERR\_KEY\_EXP Password has expired \item {} \sphinxAtStartPar KRB5\_LIBOS\_BADPWDMATCH Password mismatch \item {} \sphinxAtStartPar KRB5\_CHPW\_PWDNULL New password cannot be zero length \item {} \sphinxAtStartPar KRB5\_CHPW\_FAIL Password change failed \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function requests KDC for an initial credentials for \sphinxstyleemphasis{client} using \sphinxstyleemphasis{password} . If \sphinxstyleemphasis{password} is NULL, a password will be prompted for using \sphinxstyleemphasis{prompter} if necessary. If \sphinxstyleemphasis{in\_tkt\_service} is specified, it is parsed as a principal name (with the realm ignored) and used as the service principal for the request; otherwise the ticket\sphinxhyphen{}granting service is used. \sphinxstepscope \subsubsection{krb5\_get\_profile \sphinxhyphen{} Retrieve configuration profile from the context.} \label{\detokenize{appdev/refs/api/krb5_get_profile:krb5-get-profile-retrieve-configuration-profile-from-the-context}}\label{\detokenize{appdev/refs/api/krb5_get_profile::doc}}\index{krb5\_get\_profile (C function)@\spxentry{krb5\_get\_profile}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_profile:c.krb5_get_profile}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_profile}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{struct}\DUrole{w}{ }\DUrole{n}{\_profile\_t}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{profile}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{profile} \sphinxhyphen{} Pointer to data read from a configuration file \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new \sphinxstyleemphasis{profile} object that reflects profile in the supplied \sphinxstyleemphasis{context} . \sphinxAtStartPar The \sphinxstyleemphasis{profile} object may be freed with profile\_release() function. See profile.h and profile API for more details. \sphinxstepscope \subsubsection{krb5\_get\_prompt\_types \sphinxhyphen{} Get prompt types array from a context.} \label{\detokenize{appdev/refs/api/krb5_get_prompt_types:krb5-get-prompt-types-get-prompt-types-array-from-a-context}}\label{\detokenize{appdev/refs/api/krb5_get_prompt_types::doc}}\index{krb5\_get\_prompt\_types (C function)@\spxentry{krb5\_get\_prompt\_types}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_prompt_types:c.krb5_get_prompt_types}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_prompt_type:c.krb5_prompt_type}]{\sphinxcrossref{\DUrole{n}{krb5\_prompt\_type}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_prompt\_types}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Pointer to an array of prompt types corresponding to the prompter’s prompts arguments. Each type has one of the following values: KRB5\_PROMPT\_TYPE\_PASSWORD KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD\_AGAIN KRB5\_PROMPT\_TYPE\_PREAUTH \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_renewed\_creds \sphinxhyphen{} Get renewed credential from KDC using an existing credential.} \label{\detokenize{appdev/refs/api/krb5_get_renewed_creds:krb5-get-renewed-creds-get-renewed-credential-from-kdc-using-an-existing-credential}}\label{\detokenize{appdev/refs/api/krb5_get_renewed_creds::doc}}\index{krb5\_get\_renewed\_creds (C function)@\spxentry{krb5\_get\_renewed\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_renewed_creds:c.krb5_get_renewed_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_renewed\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{client}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_tkt\_service}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Renewed credentials \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{client} \sphinxhyphen{} Client principal name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_tkt\_service} \sphinxhyphen{} Server principal string (or NULL) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function gets a renewed credential using an existing one from \sphinxstyleemphasis{ccache} . If \sphinxstyleemphasis{in\_tkt\_service} is specified, it is parsed (with the realm part ignored) and used as the server principal of the credential; otherwise, the ticket\sphinxhyphen{}granting service is used. \sphinxAtStartPar If successful, the renewed credential is placed in \sphinxstyleemphasis{creds} . \sphinxstepscope \subsubsection{krb5\_get\_validated\_creds \sphinxhyphen{} Get validated credentials from the KDC.} \label{\detokenize{appdev/refs/api/krb5_get_validated_creds:krb5-get-validated-creds-get-validated-credentials-from-the-kdc}}\label{\detokenize{appdev/refs/api/krb5_get_validated_creds::doc}}\index{krb5\_get\_validated\_creds (C function)@\spxentry{krb5\_get\_validated\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_validated_creds:c.krb5_get_validated_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_validated\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{client}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_tkt\_service}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Validated credentials \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{client} \sphinxhyphen{} Client principal name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_tkt\_service} \sphinxhyphen{} Server principal string (or NULL) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KRB5\_NO\_2ND\_TKT Request missing second ticket \item {} \sphinxAtStartPar KRB5\_NO\_TKT\_SUPPLIED Request did not supply a ticket \item {} \sphinxAtStartPar KRB5\_PRINC\_NOMATCH Requested principal and ticket do not match \item {} \sphinxAtStartPar KRB5\_KDCREP\_MODIFIED KDC reply did not match expectations \item {} \sphinxAtStartPar KRB5\_KDCREP\_SKEW Clock skew too great in KDC reply \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function gets a validated credential using a postdated credential from \sphinxstyleemphasis{ccache} . If \sphinxstyleemphasis{in\_tkt\_service} is specified, it is parsed (with the realm part ignored) and used as the server principal of the credential; otherwise, the ticket\sphinxhyphen{}granting service is used. \sphinxAtStartPar If successful, the validated credential is placed in \sphinxstyleemphasis{creds} . \sphinxstepscope \subsubsection{krb5\_init\_context \sphinxhyphen{} Create a krb5 library context.} \label{\detokenize{appdev/refs/api/krb5_init_context:krb5-init-context-create-a-krb5-library-context}}\label{\detokenize{appdev/refs/api/krb5_init_context::doc}}\index{krb5\_init\_context (C function)@\spxentry{krb5\_init\_context}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_context:c.krb5_init_context}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_context}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar The \sphinxstyleemphasis{context} must be released by calling krb5\_free\_context() when it is no longer needed. \begin{sphinxadmonition}{warning}{Warning:} \sphinxAtStartPar Any program or module that needs the Kerberos code to not trust the environment must use krb5\_init\_secure\_context(), or clean out the environment. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_init\_secure\_context \sphinxhyphen{} Create a krb5 library context using only configuration files.} \label{\detokenize{appdev/refs/api/krb5_init_secure_context:krb5-init-secure-context-create-a-krb5-library-context-using-only-configuration-files}}\label{\detokenize{appdev/refs/api/krb5_init_secure_context::doc}}\index{krb5\_init\_secure\_context (C function)@\spxentry{krb5\_init\_secure\_context}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_secure_context:c.krb5_init_secure_context}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_secure\_context}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Create a context structure, using only system configuration files. All information passed through the environment variables is ignored. \sphinxAtStartPar The \sphinxstyleemphasis{context} must be released by calling krb5\_free\_context() when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_is\_config\_principal \sphinxhyphen{} Test whether a principal is a configuration principal.} \label{\detokenize{appdev/refs/api/krb5_is_config_principal:krb5-is-config-principal-test-whether-a-principal-is-a-configuration-principal}}\label{\detokenize{appdev/refs/api/krb5_is_config_principal::doc}}\index{krb5\_is\_config\_principal (C function)@\spxentry{krb5\_is\_config\_principal}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_is_config_principal:c.krb5_is_config_principal}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_is\_config\_principal}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Principal to check \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar TRUE if the principal is a configuration principal (generated part of krb5\_cc\_set\_config()); FALSE otherwise. \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_is\_thread\_safe \sphinxhyphen{} Test whether the Kerberos library was built with multithread support.} \label{\detokenize{appdev/refs/api/krb5_is_thread_safe:krb5-is-thread-safe-test-whether-the-kerberos-library-was-built-with-multithread-support}}\label{\detokenize{appdev/refs/api/krb5_is_thread_safe::doc}}\index{krb5\_is\_thread\_safe (C function)@\spxentry{krb5\_is\_thread\_safe}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_is_thread_safe:c.krb5_is_thread_safe}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_is\_thread\_safe}}}}{\DUrole{kt}{void}\DUrole{w}{ }\DUrole{n}{None}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{None} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar TRUE if the library is threadsafe; FALSE otherwise \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_kt\_close \sphinxhyphen{} Close a key table handle.} \label{\detokenize{appdev/refs/api/krb5_kt_close:krb5-kt-close-close-a-key-table-handle}}\label{\detokenize{appdev/refs/api/krb5_kt_close::doc}}\index{krb5\_kt\_close (C function)@\spxentry{krb5\_kt\_close}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_close:c.krb5_kt_close}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_close}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 None \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_kt\_client\_default \sphinxhyphen{} Resolve the default client key table.} \label{\detokenize{appdev/refs/api/krb5_kt_client_default:krb5-kt-client-default-resolve-the-default-client-key-table}}\label{\detokenize{appdev/refs/api/krb5_kt_client_default::doc}}\index{krb5\_kt\_client\_default (C function)@\spxentry{krb5\_kt\_client\_default}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_client_default:c.krb5_kt_client_default}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_client\_default}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keytab\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{keytab\_out} \sphinxhyphen{} Key table handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Fill \sphinxstyleemphasis{keytab\_out} with a handle to the default client key table. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_kt\_default \sphinxhyphen{} Resolve the default key table.} \label{\detokenize{appdev/refs/api/krb5_kt_default:krb5-kt-default-resolve-the-default-key-table}}\label{\detokenize{appdev/refs/api/krb5_kt_default::doc}}\index{krb5\_kt\_default (C function)@\spxentry{krb5\_kt\_default}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_default:c.krb5_kt_default}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_default}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{id}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{id} \sphinxhyphen{} Key table handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Set \sphinxstyleemphasis{id} to a handle to the default key table. The key table is not opened. \sphinxstepscope \subsubsection{krb5\_kt\_default\_name \sphinxhyphen{} Get the default key table name.} \label{\detokenize{appdev/refs/api/krb5_kt_default_name:krb5-kt-default-name-get-the-default-key-table-name}}\label{\detokenize{appdev/refs/api/krb5_kt_default_name::doc}}\index{krb5\_kt\_default\_name (C function)@\spxentry{krb5\_kt\_default\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_default_name:c.krb5_kt_default_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_default\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{name\_size}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{name} \sphinxhyphen{} Default key table name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{name\_size} \sphinxhyphen{} Space available in \sphinxstyleemphasis{name} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KRB5\_CONFIG\_NOTENUFSPACE Buffer is too short \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Fill \sphinxstyleemphasis{name} with the name of the default key table for \sphinxstyleemphasis{context} . \sphinxstepscope \subsubsection{krb5\_kt\_dup \sphinxhyphen{} Duplicate keytab handle.} \label{\detokenize{appdev/refs/api/krb5_kt_dup:krb5-kt-dup-duplicate-keytab-handle}}\label{\detokenize{appdev/refs/api/krb5_kt_dup::doc}}\index{krb5\_kt\_dup (C function)@\spxentry{krb5\_kt\_dup}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_dup:c.krb5_kt_dup}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_dup}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{in}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in} \sphinxhyphen{} Key table handle to be duplicated \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out} \sphinxhyphen{} Key table handle \end{description}\end{quote} \sphinxAtStartPar Create a new handle referring to the same key table as \sphinxstyleemphasis{in} . The new handle and \sphinxstyleemphasis{in} can be closed independently. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.12 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_kt\_get\_name \sphinxhyphen{} Get a key table name.} \label{\detokenize{appdev/refs/api/krb5_kt_get_name:krb5-kt-get-name-get-a-key-table-name}}\label{\detokenize{appdev/refs/api/krb5_kt_get_name::doc}}\index{krb5\_kt\_get\_name (C function)@\spxentry{krb5\_kt\_get\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_get_name:c.krb5_kt_get_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_get\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{namelen}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{name} \sphinxhyphen{} Key table name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{namelen} \sphinxhyphen{} Maximum length to fill in name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KRB5\_KT\_NAME\_TOOLONG Key table name does not fit in namelen bytes \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Fill \sphinxstyleemphasis{name} with the name of \sphinxstyleemphasis{keytab} including the type and delimiter. \sphinxstepscope \subsubsection{krb5\_kt\_get\_type \sphinxhyphen{} Return the type of a key table.} \label{\detokenize{appdev/refs/api/krb5_kt_get_type:krb5-kt-get-type-return-the-type-of-a-key-table}}\label{\detokenize{appdev/refs/api/krb5_kt_get_type::doc}}\index{krb5\_kt\_get\_type (C function)@\spxentry{krb5\_kt\_get\_type}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_get_type:c.krb5_kt_get_type}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_get\_type}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar The type of a key table as an alias that must not be modified or freed by the caller. \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_kt\_resolve \sphinxhyphen{} Get a handle for a key table.} \label{\detokenize{appdev/refs/api/krb5_kt_resolve:krb5-kt-resolve-get-a-handle-for-a-key-table}}\label{\detokenize{appdev/refs/api/krb5_kt_resolve::doc}}\index{krb5\_kt\_resolve (C function)@\spxentry{krb5\_kt\_resolve}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_resolve:c.krb5_kt_resolve}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_resolve}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ktid}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{name} \sphinxhyphen{} Name of the key table \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ktid} \sphinxhyphen{} Key table handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Resolve the key table name \sphinxstyleemphasis{name} and set \sphinxstyleemphasis{ktid} to a handle identifying the key table. Use krb5\_kt\_close() to free \sphinxstyleemphasis{ktid} when it is no longer needed. \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{name} must be of the form \sphinxstylestrong{type:residual} , where \sphinxstyleemphasis{type} must be a type known to the library and \sphinxstyleemphasis{residual} portion should be specific to the particular keytab type. If no \sphinxstyleemphasis{type} is given, the default is \sphinxstylestrong{FILE} . \end{quote} \sphinxAtStartPar If \sphinxstyleemphasis{name} is of type \sphinxstylestrong{FILE} , the keytab file is not opened by this call. \sphinxstepscope \subsubsection{krb5\_kuserok \sphinxhyphen{} Determine if a principal is authorized to log in as a local user.} \label{\detokenize{appdev/refs/api/krb5_kuserok:krb5-kuserok-determine-if-a-principal-is-authorized-to-log-in-as-a-local-user}}\label{\detokenize{appdev/refs/api/krb5_kuserok::doc}}\index{krb5\_kuserok (C function)@\spxentry{krb5\_kuserok}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kuserok:c.krb5_kuserok}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kuserok}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{luser}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Principal name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{luser} \sphinxhyphen{} Local username \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar TRUE Principal is authorized to log in as user; FALSE otherwise. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Determine whether \sphinxstyleemphasis{principal} is authorized to log in as a local user \sphinxstyleemphasis{luser} . \sphinxstepscope \subsubsection{krb5\_parse\_name \sphinxhyphen{} Convert a string principal name to a krb5\_principal structure.} \label{\detokenize{appdev/refs/api/krb5_parse_name:krb5-parse-name-convert-a-string-principal-name-to-a-krb5-principal-structure}}\label{\detokenize{appdev/refs/api/krb5_parse_name::doc}}\index{krb5\_parse\_name (C function)@\spxentry{krb5\_parse\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_parse_name:c.krb5_parse_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_parse\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{principal\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{name} \sphinxhyphen{} String representation of a principal name \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{principal\_out} \sphinxhyphen{} New principal \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Convert a string representation of a principal name to a krb5\_principal structure. \sphinxAtStartPar A string representation of a Kerberos name consists of one or more principal name components, separated by slashes, optionally followed by the @ character and a realm name. If the realm name is not specified, the local realm is used. \sphinxAtStartPar To use the slash and @ symbols as part of a component (quoted) instead of using them as a component separator or as a realm prefix), put a backslash () character in front of the symbol. Similarly, newline, tab, backspace, and NULL characters can be included in a component by using \sphinxstylestrong{n} , \sphinxstylestrong{t} , \sphinxstylestrong{b} or \sphinxstylestrong{0} , respectively. \sphinxAtStartPar Beginning with release 1.20, the name type of the principal will be inferred as \sphinxstylestrong{KRB5\_NT\_SRV\_INST} or \sphinxstylestrong{KRB5\_NT\_WELLKNOWN} based on the principal name. The type will be \sphinxstylestrong{KRB5\_NT\_PRINCIPAL} if a type cannot be inferred. \sphinxAtStartPar Use krb5\_free\_principal() to free \sphinxstyleemphasis{principal\_out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The realm in a Kerberos \sphinxstyleemphasis{name} cannot contain slash, colon, or NULL characters. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_parse\_name\_flags \sphinxhyphen{} Convert a string principal name to a krb5\_principal with flags.} \label{\detokenize{appdev/refs/api/krb5_parse_name_flags:krb5-parse-name-flags-convert-a-string-principal-name-to-a-krb5-principal-with-flags}}\label{\detokenize{appdev/refs/api/krb5_parse_name_flags::doc}}\index{krb5\_parse\_name\_flags (C function)@\spxentry{krb5\_parse\_name\_flags}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_parse_name_flags:c.krb5_parse_name_flags}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_parse\_name\_flags}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{flags}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{principal\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{name} \sphinxhyphen{} String representation of a principal name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flag \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{principal\_out} \sphinxhyphen{} New principal \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Similar to krb5\_parse\_name(), this function converts a single\sphinxhyphen{}string representation of a principal name to a krb5\_principal structure. \sphinxAtStartPar The following flags are valid: \begin{quote} \begin{itemize} \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_PARSE\_NO\_REALM \sphinxhyphen{} no realm must be present in \sphinxstyleemphasis{name} \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_PARSE\_REQUIRE\_REALM \sphinxhyphen{} realm must be present in \sphinxstyleemphasis{name} \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_PARSE\_ENTERPRISE \sphinxhyphen{} create single\sphinxhyphen{}component enterprise principal \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_PARSE\_IGNORE\_REALM \sphinxhyphen{} ignore realm if present in \sphinxstyleemphasis{name} \end{itemize} \sphinxAtStartPar If \sphinxstylestrong{KRB5\_PRINCIPAL\_PARSE\_NO\_REALM} or \sphinxstylestrong{KRB5\_PRINCIPAL\_PARSE\_IGNORE\_REALM} is specified in \sphinxstyleemphasis{flags} , the realm of the new principal will be empty. Otherwise, the default realm for \sphinxstyleemphasis{context} will be used if \sphinxstyleemphasis{name} does not specify a realm. \end{quote} \sphinxAtStartPar Use krb5\_free\_principal() to free \sphinxstyleemphasis{principal\_out} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_principal\_compare \sphinxhyphen{} Compare two principals.} \label{\detokenize{appdev/refs/api/krb5_principal_compare:krb5-principal-compare-compare-two-principals}}\label{\detokenize{appdev/refs/api/krb5_principal_compare::doc}}\index{krb5\_principal\_compare (C function)@\spxentry{krb5\_principal\_compare}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_principal_compare:c.krb5_principal_compare}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_principal\_compare}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ1}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ2}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ1} \sphinxhyphen{} First principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ2} \sphinxhyphen{} Second principal \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar TRUE if the principals are the same; FALSE otherwise \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_principal\_compare\_any\_realm \sphinxhyphen{} Compare two principals ignoring realm components.} \label{\detokenize{appdev/refs/api/krb5_principal_compare_any_realm:krb5-principal-compare-any-realm-compare-two-principals-ignoring-realm-components}}\label{\detokenize{appdev/refs/api/krb5_principal_compare_any_realm::doc}}\index{krb5\_principal\_compare\_any\_realm (C function)@\spxentry{krb5\_principal\_compare\_any\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_principal_compare_any_realm:c.krb5_principal_compare_any_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_principal\_compare\_any\_realm}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ1}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ2}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ1} \sphinxhyphen{} First principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ2} \sphinxhyphen{} Second principal \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar TRUE if the principals are the same; FALSE otherwise \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Similar to krb5\_principal\_compare(), but do not compare the realm components of the principals. \sphinxstepscope \subsubsection{krb5\_principal\_compare\_flags \sphinxhyphen{} Compare two principals with additional flags.} \label{\detokenize{appdev/refs/api/krb5_principal_compare_flags:krb5-principal-compare-flags-compare-two-principals-with-additional-flags}}\label{\detokenize{appdev/refs/api/krb5_principal_compare_flags::doc}}\index{krb5\_principal\_compare\_flags (C function)@\spxentry{krb5\_principal\_compare\_flags}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_principal_compare_flags:c.krb5_principal_compare_flags}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_principal\_compare\_flags}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ1}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ2}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ1} \sphinxhyphen{} First principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ2} \sphinxhyphen{} Second principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flags \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar TRUE if the principal names are the same; FALSE otherwise \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Valid flags are: \begin{itemize} \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_COMPARE\_IGNORE\_REALM \sphinxhyphen{} ignore realm component \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_COMPARE\_ENTERPRISE \sphinxhyphen{} UPNs as real principals \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_COMPARE\_CASEFOLD case\sphinxhyphen{}insensitive \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_COMPARE\_UTF8 \sphinxhyphen{} treat principals as UTF\sphinxhyphen{}8 \end{itemize} \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_principal\_compare() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_prompter\_posix \sphinxhyphen{} Prompt user for password.} \label{\detokenize{appdev/refs/api/krb5_prompter_posix:krb5-prompter-posix-prompt-user-for-password}}\label{\detokenize{appdev/refs/api/krb5_prompter_posix::doc}}\index{krb5\_prompter\_posix (C function)@\spxentry{krb5\_prompter\_posix}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_prompter_posix:c.krb5_prompter_posix}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_prompter\_posix}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{banner}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{num\_prompts}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_prompt:c.krb5_prompt}]{\sphinxcrossref{\DUrole{n}{krb5\_prompt}}}}\DUrole{w}{ }\DUrole{n}{prompts}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{data} \sphinxhyphen{} Unused (callback argument) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{name} \sphinxhyphen{} Name to output during prompt \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{banner} \sphinxhyphen{} Banner to output during prompt \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_prompts} \sphinxhyphen{} Number of prompts in \sphinxstyleemphasis{prompts} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{prompts} \sphinxhyphen{} Array of prompts and replies \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function is intended to be used as a prompter callback for krb5\_get\_init\_creds\_password() or krb5\_init\_creds\_init(). \sphinxAtStartPar Writes \sphinxstyleemphasis{name} and \sphinxstyleemphasis{banner} to stdout, each followed by a newline, then writes each prompt field in the \sphinxstyleemphasis{prompts} array, followed byâ€:â€, and sets the reply field of the entry to a line of input read from stdin. If the hidden flag is set for a prompt, then terminal echoing is turned off when input is read. \sphinxstepscope \subsubsection{krb5\_realm\_compare \sphinxhyphen{} Compare the realms of two principals.} \label{\detokenize{appdev/refs/api/krb5_realm_compare:krb5-realm-compare-compare-the-realms-of-two-principals}}\label{\detokenize{appdev/refs/api/krb5_realm_compare::doc}}\index{krb5\_realm\_compare (C function)@\spxentry{krb5\_realm\_compare}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_realm_compare:c.krb5_realm_compare}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_realm\_compare}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ1}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ2}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ1} \sphinxhyphen{} First principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ2} \sphinxhyphen{} Second principal \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar TRUE if the realm names are the same; FALSE otherwise \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_responder\_get\_challenge \sphinxhyphen{} Retrieve the challenge data for a given question in the responder context.} \label{\detokenize{appdev/refs/api/krb5_responder_get_challenge:krb5-responder-get-challenge-retrieve-the-challenge-data-for-a-given-question-in-the-responder-context}}\label{\detokenize{appdev/refs/api/krb5_responder_get_challenge::doc}}\index{krb5\_responder\_get\_challenge (C function)@\spxentry{krb5\_responder\_get\_challenge}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_responder_get_challenge:c.krb5_responder_get_challenge}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_get\_challenge}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_context}}}}\DUrole{w}{ }\DUrole{n}{rctx}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{question}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rctx} \sphinxhyphen{} Responder context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{question} \sphinxhyphen{} Question name \end{description}\end{quote} \sphinxAtStartPar Return a pointer to a C string containing the challenge for \sphinxstyleemphasis{question} within \sphinxstyleemphasis{rctx} , or NULL if the question is not present in \sphinxstyleemphasis{rctx} . The structure of the question depends on the question name, but will always be printable UTF\sphinxhyphen{}8 text. The returned pointer is an alias, valid only as long as the lifetime of \sphinxstyleemphasis{rctx} , and should not be modified or freed by the caller. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_responder\_list\_questions \sphinxhyphen{} List the question names contained in the responder context.} \label{\detokenize{appdev/refs/api/krb5_responder_list_questions:krb5-responder-list-questions-list-the-question-names-contained-in-the-responder-context}}\label{\detokenize{appdev/refs/api/krb5_responder_list_questions::doc}}\index{krb5\_responder\_list\_questions (C function)@\spxentry{krb5\_responder\_list\_questions}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_responder_list_questions:c.krb5_responder_list_questions}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_list\_questions}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_context}}}}\DUrole{w}{ }\DUrole{n}{rctx}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rctx} \sphinxhyphen{} Responder context \end{description}\end{quote} \sphinxAtStartPar Return a pointer to a null\sphinxhyphen{}terminated list of question names which are present in \sphinxstyleemphasis{rctx} . The pointer is an alias, valid only as long as the lifetime of \sphinxstyleemphasis{rctx} , and should not be modified or freed by the caller. A question’s challenge can be retrieved using krb5\_responder\_get\_challenge() and answered using krb5\_responder\_set\_answer(). \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_responder\_set\_answer \sphinxhyphen{} Answer a named question in the responder context.} \label{\detokenize{appdev/refs/api/krb5_responder_set_answer:krb5-responder-set-answer-answer-a-named-question-in-the-responder-context}}\label{\detokenize{appdev/refs/api/krb5_responder_set_answer::doc}}\index{krb5\_responder\_set\_answer (C function)@\spxentry{krb5\_responder\_set\_answer}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_responder_set_answer:c.krb5_responder_set_answer}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_set\_answer}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_context}}}}\DUrole{w}{ }\DUrole{n}{rctx}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{question}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{answer}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rctx} \sphinxhyphen{} Responder context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{question} \sphinxhyphen{} Question name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{answer} \sphinxhyphen{} The string to set (MUST be printable UTF\sphinxhyphen{}8) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar EINVAL question is not present within rctx \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function supplies an answer to \sphinxstyleemphasis{question} within \sphinxstyleemphasis{rctx} . The appropriate form of the answer depends on the question name. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_responder\_otp\_get\_challenge \sphinxhyphen{} Decode the KRB5\_RESPONDER\_QUESTION\_OTP to a C struct.} \label{\detokenize{appdev/refs/api/krb5_responder_otp_get_challenge:krb5-responder-otp-get-challenge-decode-the-krb5-responder-question-otp-to-a-c-struct}}\label{\detokenize{appdev/refs/api/krb5_responder_otp_get_challenge::doc}}\index{krb5\_responder\_otp\_get\_challenge (C function)@\spxentry{krb5\_responder\_otp\_get\_challenge}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_responder_otp_get_challenge:c.krb5_responder_otp_get_challenge}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_otp\_get\_challenge}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_context}}}}\DUrole{w}{ }\DUrole{n}{rctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_challenge:c.krb5_responder_otp_challenge}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_challenge}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{chl}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rctx} \sphinxhyphen{} Responder context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{chl} \sphinxhyphen{} Challenge structure \end{description}\end{quote} \sphinxAtStartPar A convenience function which parses the KRB5\_RESPONDER\_QUESTION\_OTP question challenge data, making it available in native C. The main feature of this function is the ability to interact with OTP tokens without parsing the JSON. \sphinxAtStartPar The returned value must be passed to krb5\_responder\_otp\_challenge\_free() to be freed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_responder\_otp\_set\_answer \sphinxhyphen{} Answer the KRB5\_RESPONDER\_QUESTION\_OTP question.} \label{\detokenize{appdev/refs/api/krb5_responder_otp_set_answer:krb5-responder-otp-set-answer-answer-the-krb5-responder-question-otp-question}}\label{\detokenize{appdev/refs/api/krb5_responder_otp_set_answer::doc}}\index{krb5\_responder\_otp\_set\_answer (C function)@\spxentry{krb5\_responder\_otp\_set\_answer}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_responder_otp_set_answer:c.krb5_responder_otp_set_answer}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_otp\_set\_answer}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_context}}}}\DUrole{w}{ }\DUrole{n}{rctx}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{ti}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{value}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pin}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rctx} \sphinxhyphen{} Responder context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ti} \sphinxhyphen{} The index of the tokeninfo selected \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{value} \sphinxhyphen{} The value to set, or NULL for none \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pin} \sphinxhyphen{} The pin to set, or NULL for none \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_responder\_otp\_challenge\_free \sphinxhyphen{} Free the value returned by krb5\_responder\_otp\_get\_challenge().} \label{\detokenize{appdev/refs/api/krb5_responder_otp_challenge_free:krb5-responder-otp-challenge-free-free-the-value-returned-by-krb5-responder-otp-get-challenge}}\label{\detokenize{appdev/refs/api/krb5_responder_otp_challenge_free::doc}}\index{krb5\_responder\_otp\_challenge\_free (C function)@\spxentry{krb5\_responder\_otp\_challenge\_free}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_responder_otp_challenge_free:c.krb5_responder_otp_challenge_free}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_otp\_challenge\_free}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_context}}}}\DUrole{w}{ }\DUrole{n}{rctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_challenge:c.krb5_responder_otp_challenge}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_challenge}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{chl}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rctx} \sphinxhyphen{} Responder context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{chl} \sphinxhyphen{} The challenge to free \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_responder\_pkinit\_get\_challenge \sphinxhyphen{} Decode the KRB5\_RESPONDER\_QUESTION\_PKINIT to a C struct.} \label{\detokenize{appdev/refs/api/krb5_responder_pkinit_get_challenge:krb5-responder-pkinit-get-challenge-decode-the-krb5-responder-question-pkinit-to-a-c-struct}}\label{\detokenize{appdev/refs/api/krb5_responder_pkinit_get_challenge::doc}}\index{krb5\_responder\_pkinit\_get\_challenge (C function)@\spxentry{krb5\_responder\_pkinit\_get\_challenge}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_responder_pkinit_get_challenge:c.krb5_responder_pkinit_get_challenge}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_pkinit\_get\_challenge}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_context}}}}\DUrole{w}{ }\DUrole{n}{rctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge:c.krb5_responder_pkinit_challenge}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_pkinit\_challenge}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{chl\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rctx} \sphinxhyphen{} Responder context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{chl\_out} \sphinxhyphen{} Challenge structure \end{description}\end{quote} \sphinxAtStartPar A convenience function which parses the KRB5\_RESPONDER\_QUESTION\_PKINIT question challenge data, making it available in native C. The main feature of this function is the ability to read the challenge without parsing the JSON. \sphinxAtStartPar The returned value must be passed to krb5\_responder\_pkinit\_challenge\_free() to be freed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.12 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_responder\_pkinit\_set\_answer \sphinxhyphen{} Answer the KRB5\_RESPONDER\_QUESTION\_PKINIT question for one identity.} \label{\detokenize{appdev/refs/api/krb5_responder_pkinit_set_answer:krb5-responder-pkinit-set-answer-answer-the-krb5-responder-question-pkinit-question-for-one-identity}}\label{\detokenize{appdev/refs/api/krb5_responder_pkinit_set_answer::doc}}\index{krb5\_responder\_pkinit\_set\_answer (C function)@\spxentry{krb5\_responder\_pkinit\_set\_answer}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_responder_pkinit_set_answer:c.krb5_responder_pkinit_set_answer}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_pkinit\_set\_answer}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_context}}}}\DUrole{w}{ }\DUrole{n}{rctx}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{identity}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pin}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rctx} \sphinxhyphen{} Responder context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{identity} \sphinxhyphen{} The identity for which a PIN is being supplied \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pin} \sphinxhyphen{} The provided PIN, or NULL for none \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.12 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_responder\_pkinit\_challenge\_free \sphinxhyphen{} Free the value returned by krb5\_responder\_pkinit\_get\_challenge().} \label{\detokenize{appdev/refs/api/krb5_responder_pkinit_challenge_free:krb5-responder-pkinit-challenge-free-free-the-value-returned-by-krb5-responder-pkinit-get-challenge}}\label{\detokenize{appdev/refs/api/krb5_responder_pkinit_challenge_free::doc}}\index{krb5\_responder\_pkinit\_challenge\_free (C function)@\spxentry{krb5\_responder\_pkinit\_challenge\_free}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_responder_pkinit_challenge_free:c.krb5_responder_pkinit_challenge_free}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_pkinit\_challenge\_free}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_context}}}}\DUrole{w}{ }\DUrole{n}{rctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge:c.krb5_responder_pkinit_challenge}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_pkinit\_challenge}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{chl}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rctx} \sphinxhyphen{} Responder context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{chl} \sphinxhyphen{} The challenge to free \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.12 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_set\_default\_realm \sphinxhyphen{} Override the default realm for the specified context.} \label{\detokenize{appdev/refs/api/krb5_set_default_realm:krb5-set-default-realm-override-the-default-realm-for-the-specified-context}}\label{\detokenize{appdev/refs/api/krb5_set_default_realm::doc}}\index{krb5\_set\_default\_realm (C function)@\spxentry{krb5\_set\_default\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_default_realm:c.krb5_set_default_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_default\_realm}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{lrealm}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{lrealm} \sphinxhyphen{} Realm name for the default realm \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar If \sphinxstyleemphasis{lrealm} is NULL, clear the default realm setting. \sphinxstepscope \subsubsection{krb5\_set\_password \sphinxhyphen{} Set a password for a principal using specified credentials.} \label{\detokenize{appdev/refs/api/krb5_set_password:krb5-set-password-set-a-password-for-a-principal-using-specified-credentials}}\label{\detokenize{appdev/refs/api/krb5_set_password::doc}}\index{krb5\_set\_password (C function)@\spxentry{krb5\_set\_password}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_password:c.krb5_set_password}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_password}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{newpw}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{change\_password\_for}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{result\_code}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{result\_code\_string}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{result\_string}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Credentials for kadmin/changepw service \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{newpw} \sphinxhyphen{} New password \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{change\_password\_for} \sphinxhyphen{} Change the password for this principal \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{result\_code} \sphinxhyphen{} Numeric error code from server \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{result\_code\_string} \sphinxhyphen{} String equivalent to \sphinxstyleemphasis{result\_code} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{result\_string} \sphinxhyphen{} Data returned from the remote system \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success and result\_code is set to KRB5\_KPASSWD\_SUCCESS. \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function uses the credentials \sphinxstyleemphasis{creds} to set the password \sphinxstyleemphasis{newpw} for the principal \sphinxstyleemphasis{change\_password\_for} . It implements the set password operation of RFC 3244, for interoperability with Microsoft Windows implementations. \sphinxAtStartPar The error code and strings are returned in \sphinxstyleemphasis{result\_code} , \sphinxstyleemphasis{result\_code\_string} and \sphinxstyleemphasis{result\_string} . \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If \sphinxstyleemphasis{change\_password\_for} is NULL, the change is performed on the current principal. If \sphinxstyleemphasis{change\_password\_for} is non\sphinxhyphen{}null, the change is performed on the principal name passed in \sphinxstyleemphasis{change\_password\_for} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_set\_password\_using\_ccache \sphinxhyphen{} Set a password for a principal using cached credentials.} \label{\detokenize{appdev/refs/api/krb5_set_password_using_ccache:krb5-set-password-using-ccache-set-a-password-for-a-principal-using-cached-credentials}}\label{\detokenize{appdev/refs/api/krb5_set_password_using_ccache::doc}}\index{krb5\_set\_password\_using\_ccache (C function)@\spxentry{krb5\_set\_password\_using\_ccache}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_password_using_ccache:c.krb5_set_password_using_ccache}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_password\_using\_ccache}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{newpw}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{change\_password\_for}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{result\_code}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{result\_code\_string}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{result\_string}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{newpw} \sphinxhyphen{} New password \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{change\_password\_for} \sphinxhyphen{} Change the password for this principal \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{result\_code} \sphinxhyphen{} Numeric error code from server \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{result\_code\_string} \sphinxhyphen{} String equivalent to \sphinxstyleemphasis{result\_code} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{result\_string} \sphinxhyphen{} Data returned from the remote system \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function uses the cached credentials from \sphinxstyleemphasis{ccache} to set the password \sphinxstyleemphasis{newpw} for the principal \sphinxstyleemphasis{change\_password\_for} . It implements RFC 3244 set password operation (interoperable with MS Windows implementations) using the credential cache. \sphinxAtStartPar The error code and strings are returned in \sphinxstyleemphasis{result\_code} , \sphinxstyleemphasis{result\_code\_string} and \sphinxstyleemphasis{result\_string} . \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If \sphinxstyleemphasis{change\_password\_for} is set to NULL, the change is performed on the default principal in \sphinxstyleemphasis{ccache} . If \sphinxstyleemphasis{change\_password\_for} is nonnull, the change is performed on the specified principal. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_set\_principal\_realm \sphinxhyphen{} Set the realm field of a principal.} \label{\detokenize{appdev/refs/api/krb5_set_principal_realm:krb5-set-principal-realm-set-the-realm-field-of-a-principal}}\label{\detokenize{appdev/refs/api/krb5_set_principal_realm::doc}}\index{krb5\_set\_principal\_realm (C function)@\spxentry{krb5\_set\_principal\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_principal_realm:c.krb5_set_principal_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_principal\_realm}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Principal name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Realm name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Set the realm name part of \sphinxstyleemphasis{principal} to \sphinxstyleemphasis{realm} , overwriting the previous realm. \sphinxstepscope \subsubsection{krb5\_set\_trace\_callback \sphinxhyphen{} Specify a callback function for trace events.} \label{\detokenize{appdev/refs/api/krb5_set_trace_callback:krb5-set-trace-callback-specify-a-callback-function-for-trace-events}}\label{\detokenize{appdev/refs/api/krb5_set_trace_callback::doc}}\index{krb5\_set\_trace\_callback (C function)@\spxentry{krb5\_set\_trace\_callback}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_trace_callback:c.krb5_set_trace_callback}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_trace\_callback}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_trace_callback:c.krb5_trace_callback}]{\sphinxcrossref{\DUrole{n}{krb5\_trace\_callback}}}}\DUrole{w}{ }\DUrole{n}{fn}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cb\_data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fn} \sphinxhyphen{} Callback function \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cb\_data} \sphinxhyphen{} Callback data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Returns KRB5\_TRACE\_NOSUPP if tracing is not supported in the library (unless fn is NULL). \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Specify a callback for trace events occurring in krb5 operations performed within \sphinxstyleemphasis{context} . \sphinxstyleemphasis{fn} will be invoked with \sphinxstyleemphasis{context} as the first argument, \sphinxstyleemphasis{cb\_data} as the last argument, and a pointer to a krb5\_trace\_info as the second argument. If the trace callback is reset via this function or \sphinxstyleemphasis{context} is destroyed, \sphinxstyleemphasis{fn} will be invoked with a NULL second argument so it can clean up \sphinxstyleemphasis{cb\_data} . Supply a NULL value for \sphinxstyleemphasis{fn} to disable trace callbacks within \sphinxstyleemphasis{context} . \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function overrides the information passed through the \sphinxstyleemphasis{KRB5\_TRACE} environment variable. \end{sphinxadmonition} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_set\_trace\_filename \sphinxhyphen{} Specify a file name for directing trace events.} \label{\detokenize{appdev/refs/api/krb5_set_trace_filename:krb5-set-trace-filename-specify-a-file-name-for-directing-trace-events}}\label{\detokenize{appdev/refs/api/krb5_set_trace_filename::doc}}\index{krb5\_set\_trace\_filename (C function)@\spxentry{krb5\_set\_trace\_filename}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_trace_filename:c.krb5_set_trace_filename}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_trace\_filename}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{filename}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{filename} \sphinxhyphen{} File name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar KRB5\_TRACE\_NOSUPP Tracing is not supported in the library. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Open \sphinxstyleemphasis{filename} for appending (creating it, if necessary) and set up a callback to write trace events to it. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function overrides the information passed through the \sphinxstyleemphasis{KRB5\_TRACE} environment variable. \end{sphinxadmonition} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_sname\_match \sphinxhyphen{} Test whether a principal matches a matching principal.} \label{\detokenize{appdev/refs/api/krb5_sname_match:krb5-sname-match-test-whether-a-principal-matches-a-matching-principal}}\label{\detokenize{appdev/refs/api/krb5_sname_match::doc}}\index{krb5\_sname\_match (C function)@\spxentry{krb5\_sname\_match}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_sname_match:c.krb5_sname_match}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_sname\_match}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{matching}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{matching} \sphinxhyphen{} Matching principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ} \sphinxhyphen{} Principal to test \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar TRUE if princ matches matching , FALSE otherwise. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar If \sphinxstyleemphasis{matching} is NULL, return TRUE. If \sphinxstyleemphasis{matching} is not a matching principal, return the value of krb5\_principal\_compare(context, matching,princ). \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar A matching principal is a host\sphinxhyphen{}based principal with an empty realm and/or second data component (hostname). Profile configuration may cause the hostname to be ignored even if it is present. A principal matches a matching principal if the former has the same non\sphinxhyphen{}empty (and non\sphinxhyphen{}ignored) components of the latter. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_sname\_to\_principal \sphinxhyphen{} Generate a full principal name from a service name.} \label{\detokenize{appdev/refs/api/krb5_sname_to_principal:krb5-sname-to-principal-generate-a-full-principal-name-from-a-service-name}}\label{\detokenize{appdev/refs/api/krb5_sname_to_principal::doc}}\index{krb5\_sname\_to\_principal (C function)@\spxentry{krb5\_sname\_to\_principal}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_sname_to_principal:c.krb5_sname_to_principal}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_sname\_to\_principal}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{hostname}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{sname}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{n}{type}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ret\_princ}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{hostname} \sphinxhyphen{} Host name, or NULL to use local host \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{sname} \sphinxhyphen{} Service name, or NULL to use \sphinxstylestrong{“hostâ€} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{type} \sphinxhyphen{} Principal type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ret\_princ} \sphinxhyphen{} Generated principal \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function converts a \sphinxstyleemphasis{hostname} and \sphinxstyleemphasis{sname} into \sphinxstyleemphasis{krb5\_principal} structure \sphinxstyleemphasis{ret\_princ} . The returned principal will be of the form \sphinxstyleemphasis{sname/hostname@REALM} where REALM is determined by krb5\_get\_host\_realm(). In some cases this may be the referral (empty) realm. \sphinxAtStartPar The \sphinxstyleemphasis{type} can be one of the following: \begin{quote} \begin{itemize} \item {} \sphinxAtStartPar KRB5\_NT\_SRV\_HST canonicalizes the host name before looking up the realm and generating the principal. \item {} \sphinxAtStartPar KRB5\_NT\_UNKNOWN accepts the hostname as given, and does not canonicalize it. \end{itemize} \sphinxAtStartPar Use krb5\_free\_principal to free \sphinxstyleemphasis{ret\_princ} when it is no longer needed. \end{quote} \sphinxstepscope \subsubsection{krb5\_unparse\_name \sphinxhyphen{} Convert a krb5\_principal structure to a string representation.} \label{\detokenize{appdev/refs/api/krb5_unparse_name:krb5-unparse-name-convert-a-krb5-principal-structure-to-a-string-representation}}\label{\detokenize{appdev/refs/api/krb5_unparse_name::doc}}\index{krb5\_unparse\_name (C function)@\spxentry{krb5\_unparse\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_unparse_name:c.krb5_unparse_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_unparse\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{name}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Principal \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{name} \sphinxhyphen{} String representation of principal name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar The resulting string representation uses the format and quoting conventions described for krb5\_parse\_name(). \sphinxAtStartPar Use krb5\_free\_unparsed\_name() to free \sphinxstyleemphasis{name} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_unparse\_name\_ext \sphinxhyphen{} Convert krb5\_principal structure to string and length.} \label{\detokenize{appdev/refs/api/krb5_unparse_name_ext:krb5-unparse-name-ext-convert-krb5-principal-structure-to-string-and-length}}\label{\detokenize{appdev/refs/api/krb5_unparse_name_ext::doc}}\index{krb5\_unparse\_name\_ext (C function)@\spxentry{krb5\_unparse\_name\_ext}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_unparse_name_ext:c.krb5_unparse_name_ext}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_unparse\_name\_ext}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{size}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Principal \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{name} \sphinxhyphen{} String representation of principal name \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{size} \sphinxhyphen{} Size of unparsed name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes. On failure name is set to NULL \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function is similar to krb5\_unparse\_name(), but allows the use of an existing buffer for the result. If size is not NULL, then \sphinxstyleemphasis{name} must point to either NULL or an existing buffer of at least the size pointed to by \sphinxstyleemphasis{size} . The buffer will be allocated or resized if necessary, with the new pointer stored into \sphinxstyleemphasis{name} . Whether or not the buffer is resized, the necessary space for the result, including null terminator, will be stored into \sphinxstyleemphasis{size} . \sphinxAtStartPar If size is NULL, this function behaves exactly as krb5\_unparse\_name(). \sphinxstepscope \subsubsection{krb5\_unparse\_name\_flags \sphinxhyphen{} Convert krb5\_principal structure to a string with flags.} \label{\detokenize{appdev/refs/api/krb5_unparse_name_flags:krb5-unparse-name-flags-convert-krb5-principal-structure-to-a-string-with-flags}}\label{\detokenize{appdev/refs/api/krb5_unparse_name_flags::doc}}\index{krb5\_unparse\_name\_flags (C function)@\spxentry{krb5\_unparse\_name\_flags}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_unparse_name_flags:c.krb5_unparse_name_flags}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_unparse\_name\_flags}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{flags}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{name}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flags \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{name} \sphinxhyphen{} String representation of principal name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes. On failure name is set to NULL \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Similar to krb5\_unparse\_name(), this function converts a krb5\_principal structure to a string representation. \sphinxAtStartPar The following flags are valid: \begin{quote} \begin{itemize} \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_UNPARSE\_SHORT \sphinxhyphen{} omit realm if it is the local realm \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_UNPARSE\_NO\_REALM \sphinxhyphen{} omit realm \item {} \sphinxAtStartPar KRB5\_PRINCIPAL\_UNPARSE\_DISPLAY \sphinxhyphen{} do not quote special characters \end{itemize} \sphinxAtStartPar Use krb5\_free\_unparsed\_name() to free \sphinxstyleemphasis{name} when it is no longer needed. \end{quote} \sphinxstepscope \subsubsection{krb5\_unparse\_name\_flags\_ext \sphinxhyphen{} Convert krb5\_principal structure to string format with flags.} \label{\detokenize{appdev/refs/api/krb5_unparse_name_flags_ext:krb5-unparse-name-flags-ext-convert-krb5-principal-structure-to-string-format-with-flags}}\label{\detokenize{appdev/refs/api/krb5_unparse_name_flags_ext::doc}}\index{krb5\_unparse\_name\_flags\_ext (C function)@\spxentry{krb5\_unparse\_name\_flags\_ext}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_unparse_name_flags_ext:c.krb5_unparse_name_flags_ext}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_unparse\_name\_flags\_ext}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{flags}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{size}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flags \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{name} \sphinxhyphen{} Single string format of principal name \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{size} \sphinxhyphen{} Size of unparsed name buffer \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes. On failure name is set to NULL \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_us\_timeofday \sphinxhyphen{} Retrieve the system time of day, in sec and ms, since the epoch.} \label{\detokenize{appdev/refs/api/krb5_us_timeofday:krb5-us-timeofday-retrieve-the-system-time-of-day-in-sec-and-ms-since-the-epoch}}\label{\detokenize{appdev/refs/api/krb5_us_timeofday::doc}}\index{krb5\_us\_timeofday (C function)@\spxentry{krb5\_us\_timeofday}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_us_timeofday:c.krb5_us_timeofday}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_us\_timeofday}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{seconds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{microseconds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{seconds} \sphinxhyphen{} System timeofday, seconds portion \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{microseconds} \sphinxhyphen{} System timeofday, microseconds portion \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function retrieves the system time of day with the context specific time offset adjustment. \sphinxstepscope \subsubsection{krb5\_verify\_authdata\_kdc\_issued \sphinxhyphen{} Unwrap and verify AD\sphinxhyphen{}KDCIssued authorization data.} \label{\detokenize{appdev/refs/api/krb5_verify_authdata_kdc_issued:krb5-verify-authdata-kdc-issued-unwrap-and-verify-ad-kdcissued-authorization-data}}\label{\detokenize{appdev/refs/api/krb5_verify_authdata_kdc_issued::doc}}\index{krb5\_verify\_authdata\_kdc\_issued (C function)@\spxentry{krb5\_verify\_authdata\_kdc\_issued}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_verify_authdata_kdc_issued:c.krb5_verify_authdata_kdc_issued}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_verify\_authdata\_kdc\_issued}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ad\_kdcissued}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{issuer}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{authdata}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Session key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ad\_kdcissued} \sphinxhyphen{} AD\sphinxhyphen{}KDCIssued authorization data to be unwrapped \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{issuer} \sphinxhyphen{} Name of issuing principal (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{authdata} \sphinxhyphen{} Unwrapped list of authorization data \end{description}\end{quote} \sphinxAtStartPar This function unwraps an AD\sphinxhyphen{}KDCIssued authdatum (see RFC 4120 section 5.2.6.2) and verifies its signature against \sphinxstyleemphasis{key} . The issuer field of the authdatum element is returned in \sphinxstyleemphasis{issuer} , and the unwrapped list of authdata is returned in \sphinxstyleemphasis{authdata} . \subsection{Rarely used public interfaces} \label{\detokenize{appdev/refs/api/index:rarely-used-public-interfaces}} \sphinxstepscope \subsubsection{krb5\_425\_conv\_principal \sphinxhyphen{} Convert a Kerberos V4 principal to a Kerberos V5 principal.} \label{\detokenize{appdev/refs/api/krb5_425_conv_principal:krb5-425-conv-principal-convert-a-kerberos-v4-principal-to-a-kerberos-v5-principal}}\label{\detokenize{appdev/refs/api/krb5_425_conv_principal::doc}}\index{krb5\_425\_conv\_principal (C function)@\spxentry{krb5\_425\_conv\_principal}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_425_conv_principal:c.krb5_425_conv_principal}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_425\_conv\_principal}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{instance}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{princ}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{name} \sphinxhyphen{} V4 name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{instance} \sphinxhyphen{} V4 instance \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Realm \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{princ} \sphinxhyphen{} V5 principal \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function builds a \sphinxstyleemphasis{princ} from V4 specification based on given input \sphinxstyleemphasis{name.instance@realm} . \sphinxAtStartPar Use krb5\_free\_principal() to free \sphinxstyleemphasis{princ} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_524\_conv\_principal \sphinxhyphen{} Convert a Kerberos V5 principal to a Kerberos V4 principal.} \label{\detokenize{appdev/refs/api/krb5_524_conv_principal:krb5-524-conv-principal-convert-a-kerberos-v5-principal-to-a-kerberos-v4-principal}}\label{\detokenize{appdev/refs/api/krb5_524_conv_principal::doc}}\index{krb5\_524\_conv\_principal (C function)@\spxentry{krb5\_524\_conv\_principal}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_524_conv_principal:c.krb5_524_conv_principal}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_524\_conv\_principal}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{inst}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{princ} \sphinxhyphen{} V5 Principal \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{name} \sphinxhyphen{} V4 principal’s name to be filled in \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{inst} \sphinxhyphen{} V4 principal’s instance name to be filled in \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Principal’s realm name to be filled in \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KRB5\_INVALID\_PRINCIPAL Invalid principal name \item {} \sphinxAtStartPar KRB5\_CONFIG\_CANTOPEN Can’t open or find Kerberos configuration file \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function separates a V5 principal \sphinxstyleemphasis{princ} into \sphinxstyleemphasis{name} , \sphinxstyleemphasis{instance} , and \sphinxstyleemphasis{realm} . \sphinxstepscope \subsubsection{krb5\_address\_compare \sphinxhyphen{} Compare two Kerberos addresses.} \label{\detokenize{appdev/refs/api/krb5_address_compare:krb5-address-compare-compare-two-kerberos-addresses}}\label{\detokenize{appdev/refs/api/krb5_address_compare::doc}}\index{krb5\_address\_compare (C function)@\spxentry{krb5\_address\_compare}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_address_compare:c.krb5_address_compare}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_address\_compare}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{addr1}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{addr2}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{addr1} \sphinxhyphen{} First address to be compared \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{addr2} \sphinxhyphen{} Second address to be compared \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar TRUE if the addresses are the same, FALSE otherwise \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_address\_order \sphinxhyphen{} Return an ordering of the specified addresses.} \label{\detokenize{appdev/refs/api/krb5_address_order:krb5-address-order-return-an-ordering-of-the-specified-addresses}}\label{\detokenize{appdev/refs/api/krb5_address_order::doc}}\index{krb5\_address\_order (C function)@\spxentry{krb5\_address\_order}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_address_order:c.krb5_address_order}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{int}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_address\_order}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{addr1}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{addr2}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{addr1} \sphinxhyphen{} First address \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{addr2} \sphinxhyphen{} Second address \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 if The two addresses are the same \item {} \sphinxAtStartPar \textless{} 0 First address is less than second \item {} \sphinxAtStartPar \textgreater{} 0 First address is greater than second \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_address\_search \sphinxhyphen{} Search a list of addresses for a specified address.} \label{\detokenize{appdev/refs/api/krb5_address_search:krb5-address-search-search-a-list-of-addresses-for-a-specified-address}}\label{\detokenize{appdev/refs/api/krb5_address_search::doc}}\index{krb5\_address\_search (C function)@\spxentry{krb5\_address\_search}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_address_search:c.krb5_address_search}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_address\_search}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{addr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{addrlist}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{addr} \sphinxhyphen{} Address to search for \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{addrlist} \sphinxhyphen{} Address list to be searched (or NULL) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar TRUE if addr is listed in addrlist , or addrlist is NULL; FALSE otherwise \end{itemize} \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If \sphinxstyleemphasis{addrlist} contains only a NetBIOS addresses, it will be treated as a null list. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_allow\_weak\_crypto \sphinxhyphen{} Allow the application to override the profile’s allow\_weak\_crypto setting.} \label{\detokenize{appdev/refs/api/krb5_allow_weak_crypto:krb5-allow-weak-crypto-allow-the-application-to-override-the-profile-s-allow-weak-crypto-setting}}\label{\detokenize{appdev/refs/api/krb5_allow_weak_crypto::doc}}\index{krb5\_allow\_weak\_crypto (C function)@\spxentry{krb5\_allow\_weak\_crypto}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_allow_weak_crypto:c.krb5_allow_weak_crypto}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_allow\_weak\_crypto}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{n}{enable}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enable} \sphinxhyphen{} Boolean flag \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 (always) \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function allows an application to override the allow\_weak\_crypto setting. It is primarily for use by aklog. \sphinxstepscope \subsubsection{krb5\_aname\_to\_localname \sphinxhyphen{} Convert a principal name to a local name.} \label{\detokenize{appdev/refs/api/krb5_aname_to_localname:krb5-aname-to-localname-convert-a-principal-name-to-a-local-name}}\label{\detokenize{appdev/refs/api/krb5_aname_to_localname::doc}}\index{krb5\_aname\_to\_localname (C function)@\spxentry{krb5\_aname\_to\_localname}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_aname_to_localname:c.krb5_aname_to_localname}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_aname\_to\_localname}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{aname}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{lnsize\_in}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{lname}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{aname} \sphinxhyphen{} Principal name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{lnsize\_in} \sphinxhyphen{} Space available in \sphinxstyleemphasis{lname} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{lname} \sphinxhyphen{} Local name buffer to be filled in \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar System errors \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar If \sphinxstyleemphasis{aname} does not correspond to any local account, KRB5\_LNAME\_NOTRANS is returned. If \sphinxstyleemphasis{lnsize\_in} is too small for the local name, KRB5\_CONFIG\_NOTENUFSPACE is returned. \sphinxAtStartPar Local names, rather than principal names, can be used by programs that translate to an environment\sphinxhyphen{}specific name (for example, a user account name). \sphinxstepscope \subsubsection{krb5\_anonymous\_principal \sphinxhyphen{} Build an anonymous principal.} \label{\detokenize{appdev/refs/api/krb5_anonymous_principal:krb5-anonymous-principal-build-an-anonymous-principal}}\label{\detokenize{appdev/refs/api/krb5_anonymous_principal::doc}}\index{krb5\_anonymous\_principal (C function)@\spxentry{krb5\_anonymous\_principal}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_anonymous_principal:c.krb5_anonymous_principal}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_anonymous\_principal}}}}{\DUrole{kt}{void}\DUrole{w}{ }\DUrole{n}{None}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{None} \end{description}\end{quote} \sphinxAtStartPar This function returns constant storage that must not be freed. \begin{sphinxseealso}{See also:} \sphinxAtStartPar KRB5\_ANONYMOUS\_PRINCSTR \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_anonymous\_realm \sphinxhyphen{} Return an anonymous realm data.} \label{\detokenize{appdev/refs/api/krb5_anonymous_realm:krb5-anonymous-realm-return-an-anonymous-realm-data}}\label{\detokenize{appdev/refs/api/krb5_anonymous_realm::doc}}\index{krb5\_anonymous\_realm (C function)@\spxentry{krb5\_anonymous\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_anonymous_realm:c.krb5_anonymous_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_anonymous\_realm}}}}{\DUrole{kt}{void}\DUrole{w}{ }\DUrole{n}{None}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{None} \end{description}\end{quote} \sphinxAtStartPar This function returns constant storage that must not be freed. \begin{sphinxseealso}{See also:} \sphinxAtStartPar KRB5\_ANONYMOUS\_REALMSTR \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_appdefault\_boolean \sphinxhyphen{} Retrieve a boolean value from the appdefaults section of krb5.conf.} \label{\detokenize{appdev/refs/api/krb5_appdefault_boolean:krb5-appdefault-boolean-retrieve-a-boolean-value-from-the-appdefaults-section-of-krb5-conf}}\label{\detokenize{appdev/refs/api/krb5_appdefault_boolean::doc}}\index{krb5\_appdefault\_boolean (C function)@\spxentry{krb5\_appdefault\_boolean}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_appdefault_boolean:c.krb5_appdefault_boolean}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_appdefault\_boolean}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{appname}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{option}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{default\_value}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ret\_value}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{appname} \sphinxhyphen{} Application name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Realm name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{option} \sphinxhyphen{} Option to be checked \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{default\_value} \sphinxhyphen{} Default value to return if no match is found \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ret\_value} \sphinxhyphen{} Boolean value of \sphinxstyleemphasis{option} \end{description}\end{quote} \sphinxAtStartPar This function gets the application defaults for \sphinxstyleemphasis{option} based on the given \sphinxstyleemphasis{appname} and/or \sphinxstyleemphasis{realm} . \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_appdefault\_string() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_appdefault\_string \sphinxhyphen{} Retrieve a string value from the appdefaults section of krb5.conf.} \label{\detokenize{appdev/refs/api/krb5_appdefault_string:krb5-appdefault-string-retrieve-a-string-value-from-the-appdefaults-section-of-krb5-conf}}\label{\detokenize{appdev/refs/api/krb5_appdefault_string::doc}}\index{krb5\_appdefault\_string (C function)@\spxentry{krb5\_appdefault\_string}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_appdefault_string:c.krb5_appdefault_string}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_appdefault\_string}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{appname}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{option}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{default\_value}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ret\_value}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{appname} \sphinxhyphen{} Application name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Realm name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{option} \sphinxhyphen{} Option to be checked \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{default\_value} \sphinxhyphen{} Default value to return if no match is found \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ret\_value} \sphinxhyphen{} String value of \sphinxstyleemphasis{option} \end{description}\end{quote} \sphinxAtStartPar This function gets the application defaults for \sphinxstyleemphasis{option} based on the given \sphinxstyleemphasis{appname} and/or \sphinxstyleemphasis{realm} . \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_appdefault\_boolean() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_auth\_con\_free \sphinxhyphen{} Free a krb5\_auth\_context structure.} \label{\detokenize{appdev/refs/api/krb5_auth_con_free:krb5-auth-con-free-free-a-krb5-auth-context-structure}}\label{\detokenize{appdev/refs/api/krb5_auth_con_free::doc}}\index{krb5\_auth\_con\_free (C function)@\spxentry{krb5\_auth\_con\_free}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_free:c.krb5_auth_con_free}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_free}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context to be freed \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 (always) \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function frees an auth context allocated by krb5\_auth\_con\_init(). \sphinxstepscope \subsubsection{krb5\_auth\_con\_genaddrs \sphinxhyphen{} Generate auth context addresses from a connected socket.} \label{\detokenize{appdev/refs/api/krb5_auth_con_genaddrs:krb5-auth-con-genaddrs-generate-auth-context-addresses-from-a-connected-socket}}\label{\detokenize{appdev/refs/api/krb5_auth_con_genaddrs::doc}}\index{krb5\_auth\_con\_genaddrs (C function)@\spxentry{krb5\_auth\_con\_genaddrs}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_genaddrs:c.krb5_auth_con_genaddrs}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_genaddrs}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{infd}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{infd} \sphinxhyphen{} Connected socket descriptor \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flags \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets the local and/or remote addresses in \sphinxstyleemphasis{auth\_context} based on the local and remote endpoints of the socket \sphinxstyleemphasis{infd} . The following flags determine the operations performed: \begin{itemize} \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_ADDR Generate local address. \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_ADDR Generate remote address. \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_FULL\_ADDR Generate local address and port. \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_FULL\_ADDR Generate remote address and port. \end{itemize} \sphinxstepscope \subsubsection{krb5\_auth\_con\_get\_checksum\_func \sphinxhyphen{} Get the checksum callback from an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_get_checksum_func:krb5-auth-con-get-checksum-func-get-the-checksum-callback-from-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_get_checksum_func::doc}}\index{krb5\_auth\_con\_get\_checksum\_func (C function)@\spxentry{krb5\_auth\_con\_get\_checksum\_func}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_get_checksum_func:c.krb5_auth_con_get_checksum_func}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_get\_checksum\_func}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_mk_req_checksum_func:c.krb5_mk_req_checksum_func}]{\sphinxcrossref{\DUrole{n}{krb5\_mk\_req\_checksum\_func}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{func}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{func} \sphinxhyphen{} Checksum callback \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{data} \sphinxhyphen{} Callback argument \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 (always) \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_auth\_con\_getaddrs \sphinxhyphen{} Retrieve address fields from an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getaddrs:krb5-auth-con-getaddrs-retrieve-address-fields-from-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getaddrs::doc}}\index{krb5\_auth\_con\_getaddrs (C function)@\spxentry{krb5\_auth\_con\_getaddrs}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getaddrs:c.krb5_auth_con_getaddrs}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getaddrs}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{local\_addr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{remote\_addr}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{local\_addr} \sphinxhyphen{} Local address (NULL if not needed) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{remote\_addr} \sphinxhyphen{} Remote address (NULL if not needed) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_auth\_con\_getauthenticator \sphinxhyphen{} Retrieve the authenticator from an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getauthenticator:krb5-auth-con-getauthenticator-retrieve-the-authenticator-from-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getauthenticator::doc}}\index{krb5\_auth\_con\_getauthenticator (C function)@\spxentry{krb5\_auth\_con\_getauthenticator}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getauthenticator:c.krb5_auth_con_getauthenticator}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getauthenticator}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{authenticator}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{authenticator} \sphinxhyphen{} Authenticator \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success. Otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_free\_authenticator() to free \sphinxstyleemphasis{authenticator} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_auth\_con\_getflags \sphinxhyphen{} Retrieve flags from a krb5\_auth\_context structure.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getflags:krb5-auth-con-getflags-retrieve-flags-from-a-krb5-auth-context-structure}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getflags::doc}}\index{krb5\_auth\_con\_getflags (C function)@\spxentry{krb5\_auth\_con\_getflags}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getflags:c.krb5_auth_con_getflags}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getflags}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flags bit mask \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 (always) \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Valid values for \sphinxstyleemphasis{flags} are: \begin{itemize} \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_DO\_TIME Use timestamps \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_RET\_TIME Save timestamps \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE Use sequence numbers \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE Save sequence numbers \end{itemize} \sphinxstepscope \subsubsection{krb5\_auth\_con\_getkey \sphinxhyphen{} Retrieve the session key from an auth context as a keyblock.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getkey:krb5-auth-con-getkey-retrieve-the-session-key-from-an-auth-context-as-a-keyblock}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getkey::doc}}\index{krb5\_auth\_con\_getkey (C function)@\spxentry{krb5\_auth\_con\_getkey}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getkey:c.krb5_auth_con_getkey}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getkey}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{keyblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{keyblock} \sphinxhyphen{} Session key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success. Otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a keyblock containing the session key from \sphinxstyleemphasis{auth\_context} . Use krb5\_free\_keyblock() to free \sphinxstyleemphasis{keyblock} when it is no longer needed \sphinxstepscope \subsubsection{krb5\_auth\_con\_getkey\_k \sphinxhyphen{} Retrieve the session key from an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getkey_k:krb5-auth-con-getkey-k-retrieve-the-session-key-from-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getkey_k::doc}}\index{krb5\_auth\_con\_getkey\_k (C function)@\spxentry{krb5\_auth\_con\_getkey\_k}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getkey_k:c.krb5_auth_con_getkey_k}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getkey\_k}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{key} \sphinxhyphen{} Session key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 (always) \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets \sphinxstyleemphasis{key} to the session key from \sphinxstyleemphasis{auth\_context} . Use krb5\_k\_free\_key() to release \sphinxstyleemphasis{key} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_auth\_con\_getlocalseqnumber \sphinxhyphen{} Retrieve the local sequence number from an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getlocalseqnumber:krb5-auth-con-getlocalseqnumber-retrieve-the-local-sequence-number-from-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getlocalseqnumber::doc}}\index{krb5\_auth\_con\_getlocalseqnumber (C function)@\spxentry{krb5\_auth\_con\_getlocalseqnumber}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getlocalseqnumber:c.krb5_auth_con_getlocalseqnumber}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getlocalseqnumber}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{seqnumber}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{seqnumber} \sphinxhyphen{} Local sequence number \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Retrieve the local sequence number from \sphinxstyleemphasis{auth\_context} and return it in \sphinxstyleemphasis{seqnumber} . The KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE flag must be set in \sphinxstyleemphasis{auth\_context} for this function to be useful. \sphinxstepscope \subsubsection{krb5\_auth\_con\_getrcache \sphinxhyphen{} Retrieve the replay cache from an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getrcache:krb5-auth-con-getrcache-retrieve-the-replay-cache-from-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getrcache::doc}}\index{krb5\_auth\_con\_getrcache (C function)@\spxentry{krb5\_auth\_con\_getrcache}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getrcache:c.krb5_auth_con_getrcache}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getrcache}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_rcache:c.krb5_rcache}]{\sphinxcrossref{\DUrole{n}{krb5\_rcache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rcache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rcache} \sphinxhyphen{} Replay cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 (always) \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function fetches the replay cache from \sphinxstyleemphasis{auth\_context} . The caller should not close \sphinxstyleemphasis{rcache} . \sphinxstepscope \subsubsection{krb5\_auth\_con\_getrecvsubkey \sphinxhyphen{} Retrieve the receiving subkey from an auth context as a keyblock.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getrecvsubkey:krb5-auth-con-getrecvsubkey-retrieve-the-receiving-subkey-from-an-auth-context-as-a-keyblock}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getrecvsubkey::doc}}\index{krb5\_auth\_con\_getrecvsubkey (C function)@\spxentry{krb5\_auth\_con\_getrecvsubkey}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getrecvsubkey:c.krb5_auth_con_getrecvsubkey}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getrecvsubkey}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{ac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{keyblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ac} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{keyblock} \sphinxhyphen{} Receiving subkey \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a keyblock containing the receiving subkey from \sphinxstyleemphasis{auth\_context} . Use krb5\_free\_keyblock() to free \sphinxstyleemphasis{keyblock} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_auth\_con\_getrecvsubkey\_k \sphinxhyphen{} Retrieve the receiving subkey from an auth context as a keyblock.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getrecvsubkey_k:krb5-auth-con-getrecvsubkey-k-retrieve-the-receiving-subkey-from-an-auth-context-as-a-keyblock}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getrecvsubkey_k::doc}}\index{krb5\_auth\_con\_getrecvsubkey\_k (C function)@\spxentry{krb5\_auth\_con\_getrecvsubkey\_k}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getrecvsubkey_k:c.krb5_auth_con_getrecvsubkey_k}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getrecvsubkey\_k}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{ac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ac} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{key} \sphinxhyphen{} Receiving subkey \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets \sphinxstyleemphasis{key} to the receiving subkey from \sphinxstyleemphasis{auth\_context} . Use krb5\_k\_free\_key() to release \sphinxstyleemphasis{key} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_auth\_con\_getremoteseqnumber \sphinxhyphen{} Retrieve the remote sequence number from an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getremoteseqnumber:krb5-auth-con-getremoteseqnumber-retrieve-the-remote-sequence-number-from-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getremoteseqnumber::doc}}\index{krb5\_auth\_con\_getremoteseqnumber (C function)@\spxentry{krb5\_auth\_con\_getremoteseqnumber}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getremoteseqnumber:c.krb5_auth_con_getremoteseqnumber}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getremoteseqnumber}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{seqnumber}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{seqnumber} \sphinxhyphen{} Remote sequence number \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Retrieve the remote sequence number from \sphinxstyleemphasis{auth\_context} and return it in \sphinxstyleemphasis{seqnumber} . The KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE flag must be set in \sphinxstyleemphasis{auth\_context} for this function to be useful. \sphinxstepscope \subsubsection{krb5\_auth\_con\_getsendsubkey \sphinxhyphen{} Retrieve the send subkey from an auth context as a keyblock.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getsendsubkey:krb5-auth-con-getsendsubkey-retrieve-the-send-subkey-from-an-auth-context-as-a-keyblock}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getsendsubkey::doc}}\index{krb5\_auth\_con\_getsendsubkey (C function)@\spxentry{krb5\_auth\_con\_getsendsubkey}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getsendsubkey:c.krb5_auth_con_getsendsubkey}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getsendsubkey}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{ac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{keyblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ac} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{keyblock} \sphinxhyphen{} Send subkey \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a keyblock containing the send subkey from \sphinxstyleemphasis{auth\_context} . Use krb5\_free\_keyblock() to free \sphinxstyleemphasis{keyblock} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_auth\_con\_getsendsubkey\_k \sphinxhyphen{} Retrieve the send subkey from an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_getsendsubkey_k:krb5-auth-con-getsendsubkey-k-retrieve-the-send-subkey-from-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getsendsubkey_k::doc}}\index{krb5\_auth\_con\_getsendsubkey\_k (C function)@\spxentry{krb5\_auth\_con\_getsendsubkey\_k}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getsendsubkey_k:c.krb5_auth_con_getsendsubkey_k}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getsendsubkey\_k}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{ac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ac} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{key} \sphinxhyphen{} Send subkey \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets \sphinxstyleemphasis{key} to the send subkey from \sphinxstyleemphasis{auth\_context} . Use krb5\_k\_free\_key() to release \sphinxstyleemphasis{key} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_auth\_con\_init \sphinxhyphen{} Create and initialize an authentication context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_init:krb5-auth-con-init-create-and-initialize-an-authentication-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_init::doc}}\index{krb5\_auth\_con\_init (C function)@\spxentry{krb5\_auth\_con\_init}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_init:c.krb5_auth_con_init}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_init}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{auth\_context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates an authentication context to hold configuration and state relevant to krb5 functions for authenticating principals and protecting messages once authentication has occurred. \sphinxAtStartPar By default, flags for the context are set to enable the use of the replay cache (KRB5\_AUTH\_CONTEXT\_DO\_TIME), but not sequence numbers. Use krb5\_auth\_con\_setflags() to change the flags. \sphinxAtStartPar The allocated \sphinxstyleemphasis{auth\_context} must be freed with krb5\_auth\_con\_free() when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_auth\_con\_set\_checksum\_func \sphinxhyphen{} Set a checksum callback in an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_set_checksum_func:krb5-auth-con-set-checksum-func-set-a-checksum-callback-in-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_set_checksum_func::doc}}\index{krb5\_auth\_con\_set\_checksum\_func (C function)@\spxentry{krb5\_auth\_con\_set\_checksum\_func}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_set_checksum_func:c.krb5_auth_con_set_checksum_func}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_set\_checksum\_func}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_mk_req_checksum_func:c.krb5_mk_req_checksum_func}]{\sphinxcrossref{\DUrole{n}{krb5\_mk\_req\_checksum\_func}}}}\DUrole{w}{ }\DUrole{n}{func}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{func} \sphinxhyphen{} Checksum callback \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Callback argument \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 (always) \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Set a callback to obtain checksum data in krb5\_mk\_req(). The callback will be invoked after the subkey and local sequence number are stored in \sphinxstyleemphasis{auth\_context} . \sphinxstepscope \subsubsection{krb5\_auth\_con\_set\_req\_cksumtype \sphinxhyphen{} Set checksum type in an an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_set_req_cksumtype:krb5-auth-con-set-req-cksumtype-set-checksum-type-in-an-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_set_req_cksumtype::doc}}\index{krb5\_auth\_con\_set\_req\_cksumtype (C function)@\spxentry{krb5\_auth\_con\_set\_req\_cksumtype}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_set_req_cksumtype:c.krb5_auth_con_set_req_cksumtype}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_set\_req\_cksumtype}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{cksumtype}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksumtype} \sphinxhyphen{} Checksum type \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success. Otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets the checksum type in \sphinxstyleemphasis{auth\_context} to be used by krb5\_mk\_req() for the authenticator checksum. \sphinxstepscope \subsubsection{krb5\_auth\_con\_setaddrs \sphinxhyphen{} Set the local and remote addresses in an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_setaddrs:krb5-auth-con-setaddrs-set-the-local-and-remote-addresses-in-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_setaddrs::doc}}\index{krb5\_auth\_con\_setaddrs (C function)@\spxentry{krb5\_auth\_con\_setaddrs}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_setaddrs:c.krb5_auth_con_setaddrs}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_setaddrs}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{local\_addr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{remote\_addr}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{local\_addr} \sphinxhyphen{} Local address \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{remote\_addr} \sphinxhyphen{} Remote address \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function releases the storage assigned to the contents of the local and remote addresses of \sphinxstyleemphasis{auth\_context} and then sets them to \sphinxstyleemphasis{local\_addr} and \sphinxstyleemphasis{remote\_addr} respectively. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_auth\_con\_genaddrs() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_auth\_con\_setflags \sphinxhyphen{} Set a flags field in a krb5\_auth\_context structure.} \label{\detokenize{appdev/refs/api/krb5_auth_con_setflags:krb5-auth-con-setflags-set-a-flags-field-in-a-krb5-auth-context-structure}}\label{\detokenize{appdev/refs/api/krb5_auth_con_setflags::doc}}\index{krb5\_auth\_con\_setflags (C function)@\spxentry{krb5\_auth\_con\_setflags}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_setflags:c.krb5_auth_con_setflags}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_setflags}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{n}{flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flags bit mask \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 (always) \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Valid values for \sphinxstyleemphasis{flags} are: \begin{itemize} \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_DO\_TIME Use timestamps \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_RET\_TIME Save timestamps \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE Use sequence numbers \item {} \sphinxAtStartPar KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE Save sequence numbers \end{itemize} \sphinxstepscope \subsubsection{krb5\_auth\_con\_setports \sphinxhyphen{} Set local and remote port fields in an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_setports:krb5-auth-con-setports-set-local-and-remote-port-fields-in-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_setports::doc}}\index{krb5\_auth\_con\_setports (C function)@\spxentry{krb5\_auth\_con\_setports}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_setports:c.krb5_auth_con_setports}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_setports}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{local\_port}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{remote\_port}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{local\_port} \sphinxhyphen{} Local port \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{remote\_port} \sphinxhyphen{} Remote port \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function releases the storage assigned to the contents of the local and remote ports of \sphinxstyleemphasis{auth\_context} and then sets them to \sphinxstyleemphasis{local\_port} and \sphinxstyleemphasis{remote\_port} respectively. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_auth\_con\_genaddrs() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_auth\_con\_setrcache \sphinxhyphen{} Set the replay cache in an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_setrcache:krb5-auth-con-setrcache-set-the-replay-cache-in-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_setrcache::doc}}\index{krb5\_auth\_con\_setrcache (C function)@\spxentry{krb5\_auth\_con\_setrcache}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_setrcache:c.krb5_auth_con_setrcache}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_setrcache}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_rcache:c.krb5_rcache}]{\sphinxcrossref{\DUrole{n}{krb5\_rcache}}}}\DUrole{w}{ }\DUrole{n}{rcache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{rcache} \sphinxhyphen{} Replay cache haddle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets the replay cache in \sphinxstyleemphasis{auth\_context} to \sphinxstyleemphasis{rcache} . \sphinxstyleemphasis{rcache} will be closed when \sphinxstyleemphasis{auth\_context} is freed, so the caller should relinquish that responsibility. \sphinxstepscope \subsubsection{krb5\_auth\_con\_setrecvsubkey \sphinxhyphen{} Set the receiving subkey in an auth context with a keyblock.} \label{\detokenize{appdev/refs/api/krb5_auth_con_setrecvsubkey:krb5-auth-con-setrecvsubkey-set-the-receiving-subkey-in-an-auth-context-with-a-keyblock}}\label{\detokenize{appdev/refs/api/krb5_auth_con_setrecvsubkey::doc}}\index{krb5\_auth\_con\_setrecvsubkey (C function)@\spxentry{krb5\_auth\_con\_setrecvsubkey}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_setrecvsubkey:c.krb5_auth_con_setrecvsubkey}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_setrecvsubkey}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{ac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keyblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ac} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keyblock} \sphinxhyphen{} Receiving subkey \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets the receiving subkey in \sphinxstyleemphasis{ac} to a copy of \sphinxstyleemphasis{keyblock} . \sphinxstepscope \subsubsection{krb5\_auth\_con\_setrecvsubkey\_k \sphinxhyphen{} Set the receiving subkey in an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_setrecvsubkey_k:krb5-auth-con-setrecvsubkey-k-set-the-receiving-subkey-in-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_setrecvsubkey_k::doc}}\index{krb5\_auth\_con\_setrecvsubkey\_k (C function)@\spxentry{krb5\_auth\_con\_setrecvsubkey\_k}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_setrecvsubkey_k:c.krb5_auth_con_setrecvsubkey_k}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_setrecvsubkey\_k}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{ac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ac} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Receiving subkey \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets the receiving subkey in \sphinxstyleemphasis{ac} to \sphinxstyleemphasis{key} , incrementing its reference count. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_auth\_con\_setsendsubkey \sphinxhyphen{} Set the send subkey in an auth context with a keyblock.} \label{\detokenize{appdev/refs/api/krb5_auth_con_setsendsubkey:krb5-auth-con-setsendsubkey-set-the-send-subkey-in-an-auth-context-with-a-keyblock}}\label{\detokenize{appdev/refs/api/krb5_auth_con_setsendsubkey::doc}}\index{krb5\_auth\_con\_setsendsubkey (C function)@\spxentry{krb5\_auth\_con\_setsendsubkey}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_setsendsubkey:c.krb5_auth_con_setsendsubkey}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_setsendsubkey}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{ac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keyblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ac} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keyblock} \sphinxhyphen{} Send subkey \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success. Otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets the send subkey in \sphinxstyleemphasis{ac} to a copy of \sphinxstyleemphasis{keyblock} . \sphinxstepscope \subsubsection{krb5\_auth\_con\_setsendsubkey\_k \sphinxhyphen{} Set the send subkey in an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_setsendsubkey_k:krb5-auth-con-setsendsubkey-k-set-the-send-subkey-in-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_setsendsubkey_k::doc}}\index{krb5\_auth\_con\_setsendsubkey\_k (C function)@\spxentry{krb5\_auth\_con\_setsendsubkey\_k}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_setsendsubkey_k:c.krb5_auth_con_setsendsubkey_k}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_setsendsubkey\_k}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{ac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ac} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{key} \sphinxhyphen{} Send subkey \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets the send subkey in \sphinxstyleemphasis{ac} to \sphinxstyleemphasis{key} , incrementing its reference count. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_auth\_con\_setuseruserkey \sphinxhyphen{} Set the session key in an auth context.} \label{\detokenize{appdev/refs/api/krb5_auth_con_setuseruserkey:krb5-auth-con-setuseruserkey-set-the-session-key-in-an-auth-context}}\label{\detokenize{appdev/refs/api/krb5_auth_con_setuseruserkey::doc}}\index{krb5\_auth\_con\_setuseruserkey (C function)@\spxentry{krb5\_auth\_con\_setuseruserkey}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_setuseruserkey:c.krb5_auth_con_setuseruserkey}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_setuseruserkey}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keyblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keyblock} \sphinxhyphen{} User key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_cc\_cache\_match \sphinxhyphen{} Find a credential cache with a specified client principal.} \label{\detokenize{appdev/refs/api/krb5_cc_cache_match:krb5-cc-cache-match-find-a-credential-cache-with-a-specified-client-principal}}\label{\detokenize{appdev/refs/api/krb5_cc_cache_match::doc}}\index{krb5\_cc\_cache\_match (C function)@\spxentry{krb5\_cc\_cache\_match}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_cache_match:c.krb5_cc_cache_match}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_cache\_match}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{client}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cache\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{client} \sphinxhyphen{} Client principal \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cache\_out} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KRB5\_CC\_NOTFOUND \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Find a cache within the collection whose default principal is \sphinxstyleemphasis{client} . Use \sphinxstyleemphasis{krb5\_cc\_close} to close \sphinxstyleemphasis{ccache} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.10 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cc\_copy\_creds \sphinxhyphen{} Copy a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_copy_creds:krb5-cc-copy-creds-copy-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_copy_creds::doc}}\index{krb5\_cc\_copy\_creds (C function)@\spxentry{krb5\_cc\_copy\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_copy_creds:c.krb5_cc_copy_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_copy\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{incc}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{outcc}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{incc} \sphinxhyphen{} Credential cache to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outcc} \sphinxhyphen{} Copy of credential cache to be filled in \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_cc\_end\_seq\_get \sphinxhyphen{} Finish a series of sequential processing credential cache entries.} \label{\detokenize{appdev/refs/api/krb5_cc_end_seq_get:krb5-cc-end-seq-get-finish-a-series-of-sequential-processing-credential-cache-entries}}\label{\detokenize{appdev/refs/api/krb5_cc_end_seq_get::doc}}\index{krb5\_cc\_end\_seq\_get (C function)@\spxentry{krb5\_cc\_end\_seq\_get}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_end_seq_get:c.krb5_cc_end_seq_get}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_end\_seq\_get}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cc_cursor:c.krb5_cc_cursor}]{\sphinxcrossref{\DUrole{n}{krb5\_cc\_cursor}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cursor}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cursor} \sphinxhyphen{} Cursor \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 (always) \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function finishes processing credential cache entries and invalidates \sphinxstyleemphasis{cursor} . \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_cc\_start\_seq\_get(), krb5\_cc\_next\_cred() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_cc\_get\_config \sphinxhyphen{} Get a configuration value from a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_get_config:krb5-cc-get-config-get-a-configuration-value-from-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_get_config::doc}}\index{krb5\_cc\_get\_config (C function)@\spxentry{krb5\_cc\_get\_config}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_get_config:c.krb5_cc_get_config}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_get\_config}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{id}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{id} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Configuration for this principal; if NULL, global for the whole cache \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Name of config variable \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{data} \sphinxhyphen{} Data to be fetched \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{data} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_cc\_get\_flags \sphinxhyphen{} Retrieve flags from a credential cache structure.} \label{\detokenize{appdev/refs/api/krb5_cc_get_flags:krb5-cc-get-flags-retrieve-flags-from-a-credential-cache-structure}}\label{\detokenize{appdev/refs/api/krb5_cc_get_flags::doc}}\index{krb5\_cc\_get\_flags (C function)@\spxentry{krb5\_cc\_get\_flags}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_get_flags:c.krb5_cc_get_flags}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_get\_flags}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flag bit mask \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \begin{sphinxadmonition}{warning}{Warning:} \sphinxAtStartPar For memory credential cache always returns a flag mask of 0. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cc\_get\_full\_name \sphinxhyphen{} Retrieve the full name of a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_get_full_name:krb5-cc-get-full-name-retrieve-the-full-name-of-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_get_full_name::doc}}\index{krb5\_cc\_get\_full\_name (C function)@\spxentry{krb5\_cc\_get\_full\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_get_full_name:c.krb5_cc_get_full_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_get\_full\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{fullname\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{fullname\_out} \sphinxhyphen{} Full name of cache \end{description}\end{quote} \sphinxAtStartPar Use krb5\_free\_string() to free \sphinxstyleemphasis{fullname\_out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.10 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cc\_move \sphinxhyphen{} Move a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_move:krb5-cc-move-move-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_move::doc}}\index{krb5\_cc\_move (C function)@\spxentry{krb5\_cc\_move}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_move:c.krb5_cc_move}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_move}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{src}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{dst}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{src} \sphinxhyphen{} The credential cache to move the content from \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{dst} \sphinxhyphen{} The credential cache to move the content to \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; src is closed. \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes; src is still allocated. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function reinitializes \sphinxstyleemphasis{dst} and populates it with the credentials and default principal of \sphinxstyleemphasis{src} ; then, if successful, destroys \sphinxstyleemphasis{src} . \sphinxstepscope \subsubsection{krb5\_cc\_next\_cred \sphinxhyphen{} Retrieve the next entry from the credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_next_cred:krb5-cc-next-cred-retrieve-the-next-entry-from-the-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_next_cred::doc}}\index{krb5\_cc\_next\_cred (C function)@\spxentry{krb5\_cc\_next\_cred}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_next_cred:c.krb5_cc_next_cred}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_next\_cred}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cc_cursor:c.krb5_cc_cursor}]{\sphinxcrossref{\DUrole{n}{krb5\_cc\_cursor}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cursor}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cursor} \sphinxhyphen{} Cursor \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Next credential cache entry \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function fills in \sphinxstyleemphasis{creds} with the next entry in \sphinxstyleemphasis{cache} and advances \sphinxstyleemphasis{cursor} . \sphinxAtStartPar Use krb5\_free\_cred\_contents() to free \sphinxstyleemphasis{creds} when it is no longer needed. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_cc\_start\_seq\_get(), krb5\_end\_seq\_get() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_cc\_remove\_cred \sphinxhyphen{} Remove credentials from a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_remove_cred:krb5-cc-remove-cred-remove-credentials-from-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_remove_cred::doc}}\index{krb5\_cc\_remove\_cred (C function)@\spxentry{krb5\_cc\_remove\_cred}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_remove_cred:c.krb5_cc_remove_cred}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_remove\_cred}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{flags}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Bitwise\sphinxhyphen{}ORed search flags \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Credentials to be matched \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar KRB5\_CC\_NOSUPP Not implemented for this cache type \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar No matches found; Data cannot be deleted; Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function accepts the same flag values as krb5\_cc\_retrieve\_cred(). \begin{sphinxadmonition}{warning}{Warning:} \sphinxAtStartPar This function is not implemented for some cache types. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cc\_retrieve\_cred \sphinxhyphen{} Retrieve a specified credentials from a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_retrieve_cred:krb5-cc-retrieve-cred-retrieve-a-specified-credentials-from-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_retrieve_cred::doc}}\index{krb5\_cc\_retrieve\_cred (C function)@\spxentry{krb5\_cc\_retrieve\_cred}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_retrieve_cred:c.krb5_cc_retrieve_cred}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_retrieve\_cred}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{flags}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{mcreds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flags bit mask \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{mcreds} \sphinxhyphen{} Credentials to match \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Credentials matching the requested value \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function searches a credential cache for credentials matching \sphinxstyleemphasis{mcreds} and returns it if found. \sphinxAtStartPar Valid values for \sphinxstyleemphasis{flags} are: \begin{quote} \begin{itemize} \item {} \sphinxAtStartPar KRB5\_TC\_MATCH\_TIMES The requested lifetime must be at least as great as in \sphinxstyleemphasis{mcreds} . \item {} \sphinxAtStartPar KRB5\_TC\_MATCH\_IS\_SKEY The \sphinxstyleemphasis{is\_skey} field much match exactly. \item {} \sphinxAtStartPar KRB5\_TC\_MATCH\_FLAGS Flags set in \sphinxstyleemphasis{mcreds} must be set. \item {} \sphinxAtStartPar KRB5\_TC\_MATCH\_TIMES\_EXACT The requested lifetime must match exactly. \item {} \sphinxAtStartPar KRB5\_TC\_MATCH\_FLAGS\_EXACT Flags must match exactly. \item {} \sphinxAtStartPar KRB5\_TC\_MATCH\_AUTHDATA The authorization data must match. \item {} \sphinxAtStartPar KRB5\_TC\_MATCH\_SRV\_NAMEONLY Only the name portion of the principal name must match, not the realm. \item {} \sphinxAtStartPar KRB5\_TC\_MATCH\_2ND\_TKT The second tickets must match. \item {} \sphinxAtStartPar KRB5\_TC\_MATCH\_KTYPE The encryption key types must match. \item {} \sphinxAtStartPar KRB5\_TC\_SUPPORTED\_KTYPES Check all matching entries that have any supported encryption type and return the one with the encryption type listed earliest. \end{itemize} \sphinxAtStartPar Use krb5\_free\_cred\_contents() to free \sphinxstyleemphasis{creds} when it is no longer needed. \end{quote} \sphinxstepscope \subsubsection{krb5\_cc\_select \sphinxhyphen{} Select a credential cache to use with a server principal.} \label{\detokenize{appdev/refs/api/krb5_cc_select:krb5-cc-select-select-a-credential-cache-to-use-with-a-server-principal}}\label{\detokenize{appdev/refs/api/krb5_cc_select::doc}}\index{krb5\_cc\_select (C function)@\spxentry{krb5\_cc\_select}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_select:c.krb5_cc_select}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_select}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{server}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cache\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{princ\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Server principal \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cache\_out} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{princ\_out} \sphinxhyphen{} Client principal \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar If an appropriate cache is found, 0 is returned, cache\_out is set to the selected cache, and princ\_out is set to the default principal of that cache. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Select a cache within the collection containing credentials most appropriate for use with \sphinxstyleemphasis{server} , according to configured rules and heuristics. \sphinxAtStartPar Use krb5\_cc\_close() to release \sphinxstyleemphasis{cache\_out} when it is no longer needed. Use krb5\_free\_principal() to release \sphinxstyleemphasis{princ\_out} when it is no longer needed. Note that \sphinxstyleemphasis{princ\_out} is set in some error conditions. \sphinxAtStartPar If the appropriate client principal can be authoritatively determined but the cache collection contains no credentials for that principal, then KRB5\_CC\_NOTFOUND is returned, \sphinxstyleemphasis{cache\_out} is set to NULL, and \sphinxstyleemphasis{princ\_out} is set to the appropriate client principal. \sphinxAtStartPar If no configured mechanism can determine the appropriate cache or principal, KRB5\_CC\_NOTFOUND is returned and \sphinxstyleemphasis{cache\_out} and \sphinxstyleemphasis{princ\_out} are set to NULL. \sphinxAtStartPar Any other error code indicates a fatal error in the processing of a cache selection mechanism. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.10 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cc\_set\_config \sphinxhyphen{} Store a configuration value in a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_set_config:krb5-cc-set-config-store-a-configuration-value-in-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_set_config::doc}}\index{krb5\_cc\_set\_config (C function)@\spxentry{krb5\_cc\_set\_config}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_set_config:c.krb5_cc_set_config}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_set\_config}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{id}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{id} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Configuration for a specific principal; if NULL, global for the whole cache \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Name of config variable \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Data to store, or NULL to remove \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \begin{sphinxadmonition}{warning}{Warning:} \sphinxAtStartPar Before version 1.10 \sphinxstyleemphasis{data} was assumed to be always non\sphinxhyphen{}null. \end{sphinxadmonition} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar Existing configuration under the same key is over\sphinxhyphen{}written. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cc\_set\_default\_name \sphinxhyphen{} Set the default credential cache name.} \label{\detokenize{appdev/refs/api/krb5_cc_set_default_name:krb5-cc-set-default-name-set-the-default-credential-cache-name}}\label{\detokenize{appdev/refs/api/krb5_cc_set_default_name::doc}}\index{krb5\_cc\_set\_default\_name (C function)@\spxentry{krb5\_cc\_set\_default\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_set_default_name:c.krb5_cc_set_default_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_set\_default\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{name}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{name} \sphinxhyphen{} Default credential cache name or NULL \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KV5M\_CONTEXT Bad magic number for \_krb5\_context structure \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Set the default credential cache name to \sphinxstyleemphasis{name} for future operations using \sphinxstyleemphasis{context} . If \sphinxstyleemphasis{name} is NULL, clear any previous application\sphinxhyphen{}set default name and forget any cached value of the default name for \sphinxstyleemphasis{context} . \sphinxAtStartPar Calls to this function invalidate the result of any previous calls to krb5\_cc\_default\_name() using \sphinxstyleemphasis{context} . \sphinxstepscope \subsubsection{krb5\_cc\_set\_flags \sphinxhyphen{} Set options flags on a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_set_flags:krb5-cc-set-flags-set-options-flags-on-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_set_flags::doc}}\index{krb5\_cc\_set\_flags (C function)@\spxentry{krb5\_cc\_set\_flags}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_set_flags:c.krb5_cc_set_flags}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_set\_flags}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Flag bit mask \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function resets \sphinxstyleemphasis{cache} flags to \sphinxstyleemphasis{flags} . \sphinxstepscope \subsubsection{krb5\_cc\_start\_seq\_get \sphinxhyphen{} Prepare to sequentially read every credential in a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_start_seq_get:krb5-cc-start-seq-get-prepare-to-sequentially-read-every-credential-in-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_start_seq_get::doc}}\index{krb5\_cc\_start\_seq\_get (C function)@\spxentry{krb5\_cc\_start\_seq\_get}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_start_seq_get:c.krb5_cc_start_seq_get}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_start\_seq\_get}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cc_cursor:c.krb5_cc_cursor}]{\sphinxcrossref{\DUrole{n}{krb5\_cc\_cursor}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cursor}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cursor} \sphinxhyphen{} Cursor \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar krb5\_cc\_end\_seq\_get() must be called to complete the retrieve operation. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If the cache represented by \sphinxstyleemphasis{cache} is modified between the time of the call to this function and the time of the final krb5\_cc\_end\_seq\_get(), these changes may not be reflected in the results of krb5\_cc\_next\_cred() calls. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cc\_store\_cred \sphinxhyphen{} Store credentials in a credential cache.} \label{\detokenize{appdev/refs/api/krb5_cc_store_cred:krb5-cc-store-cred-store-credentials-in-a-credential-cache}}\label{\detokenize{appdev/refs/api/krb5_cc_store_cred::doc}}\index{krb5\_cc\_store\_cred (C function)@\spxentry{krb5\_cc\_store\_cred}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_store_cred:c.krb5_cc_store_cred}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_store\_cred}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Credentials to be stored in cache \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Permission errors; storage failure errors; Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function stores \sphinxstyleemphasis{creds} into \sphinxstyleemphasis{cache} . If \sphinxstyleemphasis{creds\sphinxhyphen{}\textgreater{}server} and the server in the decoded ticket \sphinxstyleemphasis{creds\sphinxhyphen{}\textgreater{}ticket} differ, the credentials will be stored under both server principal names. \sphinxstepscope \subsubsection{krb5\_cc\_support\_switch \sphinxhyphen{} Determine whether a credential cache type supports switching.} \label{\detokenize{appdev/refs/api/krb5_cc_support_switch:krb5-cc-support-switch-determine-whether-a-credential-cache-type-supports-switching}}\label{\detokenize{appdev/refs/api/krb5_cc_support_switch::doc}}\index{krb5\_cc\_support\_switch (C function)@\spxentry{krb5\_cc\_support\_switch}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_support_switch:c.krb5_cc_support_switch}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_support\_switch}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{type}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{type} \sphinxhyphen{} Credential cache type \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar TRUE if type supports switching \item {} \sphinxAtStartPar FALSE if it does not or is not a valid credential cache type. \end{itemize} \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.10 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cc\_switch \sphinxhyphen{} Make a credential cache the primary cache for its collection.} \label{\detokenize{appdev/refs/api/krb5_cc_switch:krb5-cc-switch-make-a-credential-cache-the-primary-cache-for-its-collection}}\label{\detokenize{appdev/refs/api/krb5_cc_switch::doc}}\index{krb5\_cc\_switch (C function)@\spxentry{krb5\_cc\_switch}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_switch:c.krb5_cc_switch}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_switch}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{cache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success, or the type of cache doesn’t support switching \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar If the type of \sphinxstyleemphasis{cache} supports it, set \sphinxstyleemphasis{cache} to be the primary credential cache for the collection it belongs to. \sphinxstepscope \subsubsection{krb5\_cccol\_cursor\_free \sphinxhyphen{} Free a credential cache collection cursor.} \label{\detokenize{appdev/refs/api/krb5_cccol_cursor_free:krb5-cccol-cursor-free-free-a-credential-cache-collection-cursor}}\label{\detokenize{appdev/refs/api/krb5_cccol_cursor_free::doc}}\index{krb5\_cccol\_cursor\_free (C function)@\spxentry{krb5\_cccol\_cursor\_free}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cccol_cursor_free:c.krb5_cccol_cursor_free}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cccol\_cursor\_free}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cccol_cursor:c.krb5_cccol_cursor}]{\sphinxcrossref{\DUrole{n}{krb5\_cccol\_cursor}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cursor}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cursor} \sphinxhyphen{} Cursor \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_cccol\_cursor\_new(), krb5\_cccol\_cursor\_next() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_cccol\_cursor\_new \sphinxhyphen{} Prepare to iterate over the collection of known credential caches.} \label{\detokenize{appdev/refs/api/krb5_cccol_cursor_new:krb5-cccol-cursor-new-prepare-to-iterate-over-the-collection-of-known-credential-caches}}\label{\detokenize{appdev/refs/api/krb5_cccol_cursor_new::doc}}\index{krb5\_cccol\_cursor\_new (C function)@\spxentry{krb5\_cccol\_cursor\_new}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cccol_cursor_new:c.krb5_cccol_cursor_new}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cccol\_cursor\_new}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cccol_cursor:c.krb5_cccol_cursor}]{\sphinxcrossref{\DUrole{n}{krb5\_cccol\_cursor}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cursor}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cursor} \sphinxhyphen{} Cursor \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Get a new cache iteration \sphinxstyleemphasis{cursor} that will iterate over all known credential caches independent of type. \sphinxAtStartPar Use krb5\_cccol\_cursor\_free() to release \sphinxstyleemphasis{cursor} when it is no longer needed. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_cccol\_cursor\_next() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_cccol\_cursor\_next \sphinxhyphen{} Get the next credential cache in the collection.} \label{\detokenize{appdev/refs/api/krb5_cccol_cursor_next:krb5-cccol-cursor-next-get-the-next-credential-cache-in-the-collection}}\label{\detokenize{appdev/refs/api/krb5_cccol_cursor_next::doc}}\index{krb5\_cccol\_cursor\_next (C function)@\spxentry{krb5\_cccol\_cursor\_next}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cccol_cursor_next:c.krb5_cccol_cursor_next}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cccol\_cursor\_next}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cccol_cursor:c.krb5_cccol_cursor}]{\sphinxcrossref{\DUrole{n}{krb5\_cccol\_cursor}}}}\DUrole{w}{ }\DUrole{n}{cursor}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ccache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cursor} \sphinxhyphen{} Cursor \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_cc\_close() to close \sphinxstyleemphasis{ccache} when it is no longer needed. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_cccol\_cursor\_new(), krb5\_cccol\_cursor\_free() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar When all caches are iterated over and the end of the list is reached, \sphinxstyleemphasis{ccache} is set to NULL. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cccol\_have\_content \sphinxhyphen{} Check if the credential cache collection contains any initialized caches.} \label{\detokenize{appdev/refs/api/krb5_cccol_have_content:krb5-cccol-have-content-check-if-the-credential-cache-collection-contains-any-initialized-caches}}\label{\detokenize{appdev/refs/api/krb5_cccol_have_content::doc}}\index{krb5\_cccol\_have\_content (C function)@\spxentry{krb5\_cccol\_have\_content}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cccol_have_content:c.krb5_cccol_have_content}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cccol\_have\_content}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 At least one initialized cache is present in the collection \item {} \sphinxAtStartPar KRB5\_CC\_NOTFOUND The collection contains no caches \end{itemize} \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_clear\_error\_message \sphinxhyphen{} Clear the extended error message in a context.} \label{\detokenize{appdev/refs/api/krb5_clear_error_message:krb5-clear-error-message-clear-the-extended-error-message-in-a-context}}\label{\detokenize{appdev/refs/api/krb5_clear_error_message::doc}}\index{krb5\_clear\_error\_message (C function)@\spxentry{krb5\_clear\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_clear_error_message:c.krb5_clear_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_clear\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \end{description}\end{quote} \sphinxAtStartPar This function unsets the extended error message in a context, to ensure that it is not mistakenly applied to another occurrence of the same error code. \sphinxstepscope \subsubsection{krb5\_check\_clockskew \sphinxhyphen{} Check if a timestamp is within the allowed clock skew of the current time.} \label{\detokenize{appdev/refs/api/krb5_check_clockskew:krb5-check-clockskew-check-if-a-timestamp-is-within-the-allowed-clock-skew-of-the-current-time}}\label{\detokenize{appdev/refs/api/krb5_check_clockskew::doc}}\index{krb5\_check\_clockskew (C function)@\spxentry{krb5\_check\_clockskew}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_check_clockskew:c.krb5_check_clockskew}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_check\_clockskew}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{n}{date}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{date} \sphinxhyphen{} Timestamp to check \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KRB5KRB\_AP\_ERR\_SKEW date is not within allowable clock skew \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function checks if \sphinxstyleemphasis{date} is close enough to the current time according to the configured allowable clock skew. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.10 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_copy\_addresses \sphinxhyphen{} Copy an array of addresses.} \label{\detokenize{appdev/refs/api/krb5_copy_addresses:krb5-copy-addresses-copy-an-array-of-addresses}}\label{\detokenize{appdev/refs/api/krb5_copy_addresses::doc}}\index{krb5\_copy\_addresses (C function)@\spxentry{krb5\_copy\_addresses}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_addresses:c.krb5_copy_addresses}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_addresses}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{inaddr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{outaddr}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inaddr} \sphinxhyphen{} Array of addresses to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outaddr} \sphinxhyphen{} Copy of array of addresses \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new address array containing a copy of \sphinxstyleemphasis{inaddr} . Use krb5\_free\_addresses() to free \sphinxstyleemphasis{outaddr} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_copy\_authdata \sphinxhyphen{} Copy an authorization data list.} \label{\detokenize{appdev/refs/api/krb5_copy_authdata:krb5-copy-authdata-copy-an-authorization-data-list}}\label{\detokenize{appdev/refs/api/krb5_copy_authdata::doc}}\index{krb5\_copy\_authdata (C function)@\spxentry{krb5\_copy\_authdata}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_authdata:c.krb5_copy_authdata}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_authdata}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_authdat}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_authdat} \sphinxhyphen{} List of \sphinxstyleemphasis{krb5\_authdata} structures \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out} \sphinxhyphen{} New array of \sphinxstyleemphasis{krb5\_authdata} structures \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new authorization data list containing a copy of \sphinxstyleemphasis{in\_authdat} , which must be null\sphinxhyphen{}terminated. Use krb5\_free\_authdata() to free \sphinxstyleemphasis{out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The last array entry in \sphinxstyleemphasis{in\_authdat} must be a NULL pointer. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_copy\_authenticator \sphinxhyphen{} Copy a krb5\_authenticator structure.} \label{\detokenize{appdev/refs/api/krb5_copy_authenticator:krb5-copy-authenticator-copy-a-krb5-authenticator-structure}}\label{\detokenize{appdev/refs/api/krb5_copy_authenticator::doc}}\index{krb5\_copy\_authenticator (C function)@\spxentry{krb5\_copy\_authenticator}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_authenticator:c.krb5_copy_authenticator}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_authenticator}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{authfrom}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{authto}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{authfrom} \sphinxhyphen{} krb5\_authenticator structure to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{authto} \sphinxhyphen{} Copy of krb5\_authenticator structure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new krb5\_authenticator structure with the content of \sphinxstyleemphasis{authfrom} . Use krb5\_free\_authenticator() to free \sphinxstyleemphasis{authto} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_copy\_checksum \sphinxhyphen{} Copy a krb5\_checksum structure.} \label{\detokenize{appdev/refs/api/krb5_copy_checksum:krb5-copy-checksum-copy-a-krb5-checksum-structure}}\label{\detokenize{appdev/refs/api/krb5_copy_checksum::doc}}\index{krb5\_copy\_checksum (C function)@\spxentry{krb5\_copy\_checksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_checksum:c.krb5_copy_checksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_checksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ckfrom}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ckto}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ckfrom} \sphinxhyphen{} Checksum to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ckto} \sphinxhyphen{} Copy of krb5\_checksum structure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new krb5\_checksum structure with the contents of \sphinxstyleemphasis{ckfrom} . Use krb5\_free\_checksum() to free \sphinxstyleemphasis{ckto} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_copy\_context \sphinxhyphen{} Copy a krb5\_context structure.} \label{\detokenize{appdev/refs/api/krb5_copy_context:krb5-copy-context-copy-a-krb5-context-structure}}\label{\detokenize{appdev/refs/api/krb5_copy_context::doc}}\index{krb5\_copy\_context (C function)@\spxentry{krb5\_copy\_context}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_context:c.krb5_copy_context}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_context}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{nctx\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{nctx\_out} \sphinxhyphen{} New context structure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar The newly created context must be released by calling krb5\_free\_context() when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_copy\_creds \sphinxhyphen{} Copy a krb5\_creds structure.} \label{\detokenize{appdev/refs/api/krb5_copy_creds:krb5-copy-creds-copy-a-krb5-creds-structure}}\label{\detokenize{appdev/refs/api/krb5_copy_creds::doc}}\index{krb5\_copy\_creds (C function)@\spxentry{krb5\_copy\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_creds:c.krb5_copy_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{incred}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{outcred}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{incred} \sphinxhyphen{} Credentials structure to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outcred} \sphinxhyphen{} Copy of \sphinxstyleemphasis{incred} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new credential with the contents of \sphinxstyleemphasis{incred} . Use krb5\_free\_creds() to free \sphinxstyleemphasis{outcred} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_copy\_data \sphinxhyphen{} Copy a krb5\_data object.} \label{\detokenize{appdev/refs/api/krb5_copy_data:krb5-copy-data-copy-a-krb5-data-object}}\label{\detokenize{appdev/refs/api/krb5_copy_data::doc}}\index{krb5\_copy\_data (C function)@\spxentry{krb5\_copy\_data}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_data:c.krb5_copy_data}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_data}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{indata}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{outdata}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{indata} \sphinxhyphen{} Data object to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outdata} \sphinxhyphen{} Copy of \sphinxstyleemphasis{indata} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new krb5\_data object with the contents of \sphinxstyleemphasis{indata} . Use krb5\_free\_data() to free \sphinxstyleemphasis{outdata} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_copy\_error\_message \sphinxhyphen{} Copy the most recent extended error message from one context to another.} \label{\detokenize{appdev/refs/api/krb5_copy_error_message:krb5-copy-error-message-copy-the-most-recent-extended-error-message-from-one-context-to-another}}\label{\detokenize{appdev/refs/api/krb5_copy_error_message::doc}}\index{krb5\_copy\_error\_message (C function)@\spxentry{krb5\_copy\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_error_message:c.krb5_copy_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{dest\_ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{src\_ctx}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{dest\_ctx} \sphinxhyphen{} Library context to copy message to \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{src\_ctx} \sphinxhyphen{} Library context with current message \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_copy\_keyblock \sphinxhyphen{} Copy a keyblock.} \label{\detokenize{appdev/refs/api/krb5_copy_keyblock:krb5-copy-keyblock-copy-a-keyblock}}\label{\detokenize{appdev/refs/api/krb5_copy_keyblock::doc}}\index{krb5\_copy\_keyblock (C function)@\spxentry{krb5\_copy\_keyblock}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_keyblock:c.krb5_copy_keyblock}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_keyblock}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{from}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{to}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{from} \sphinxhyphen{} Keyblock to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{to} \sphinxhyphen{} Copy of keyblock \sphinxstyleemphasis{from} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new keyblock with the same contents as \sphinxstyleemphasis{from} . Use krb5\_free\_keyblock() to free \sphinxstyleemphasis{to} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_copy\_keyblock\_contents \sphinxhyphen{} Copy the contents of a keyblock.} \label{\detokenize{appdev/refs/api/krb5_copy_keyblock_contents:krb5-copy-keyblock-contents-copy-the-contents-of-a-keyblock}}\label{\detokenize{appdev/refs/api/krb5_copy_keyblock_contents::doc}}\index{krb5\_copy\_keyblock\_contents (C function)@\spxentry{krb5\_copy\_keyblock\_contents}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_keyblock_contents:c.krb5_copy_keyblock_contents}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_keyblock\_contents}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{from}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{to}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{from} \sphinxhyphen{} Key to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{to} \sphinxhyphen{} Output key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function copies the contents of \sphinxstyleemphasis{from} to \sphinxstyleemphasis{to} . Use krb5\_free\_keyblock\_contents() to free \sphinxstyleemphasis{to} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_copy\_principal \sphinxhyphen{} Copy a principal.} \label{\detokenize{appdev/refs/api/krb5_copy_principal:krb5-copy-principal-copy-a-principal}}\label{\detokenize{appdev/refs/api/krb5_copy_principal::doc}}\index{krb5\_copy\_principal (C function)@\spxentry{krb5\_copy\_principal}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_principal:c.krb5_copy_principal}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_principal}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{inprinc}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{outprinc}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inprinc} \sphinxhyphen{} Principal to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outprinc} \sphinxhyphen{} Copy of \sphinxstyleemphasis{inprinc} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new principal structure with the contents of \sphinxstyleemphasis{inprinc} . Use krb5\_free\_principal() to free \sphinxstyleemphasis{outprinc} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_copy\_ticket \sphinxhyphen{} Copy a krb5\_ticket structure.} \label{\detokenize{appdev/refs/api/krb5_copy_ticket:krb5-copy-ticket-copy-a-krb5-ticket-structure}}\label{\detokenize{appdev/refs/api/krb5_copy_ticket::doc}}\index{krb5\_copy\_ticket (C function)@\spxentry{krb5\_copy\_ticket}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_copy_ticket:c.krb5_copy_ticket}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_copy\_ticket}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{from}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{pto}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{from} \sphinxhyphen{} Ticket to be copied \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{pto} \sphinxhyphen{} Copy of ticket \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new krb5\_ticket structure containing the contents of \sphinxstyleemphasis{from} . Use krb5\_free\_ticket() to free \sphinxstyleemphasis{pto} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_find\_authdata \sphinxhyphen{} Find authorization data elements.} \label{\detokenize{appdev/refs/api/krb5_find_authdata:krb5-find-authdata-find-authorization-data-elements}}\label{\detokenize{appdev/refs/api/krb5_find_authdata::doc}}\index{krb5\_find\_authdata (C function)@\spxentry{krb5\_find\_authdata}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_find_authdata:c.krb5_find_authdata}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_find\_authdata}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ticket\_authdata}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ap\_req\_authdata}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdatatype:c.krb5_authdatatype}]{\sphinxcrossref{\DUrole{n}{krb5\_authdatatype}}}}\DUrole{w}{ }\DUrole{n}{ad\_type}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{results}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ticket\_authdata} \sphinxhyphen{} Authorization data list from ticket \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ap\_req\_authdata} \sphinxhyphen{} Authorization data list from AP request \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ad\_type} \sphinxhyphen{} Authorization data type to find \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{results} \sphinxhyphen{} List of matching entries \end{description}\end{quote} \sphinxAtStartPar This function searches \sphinxstyleemphasis{ticket\_authdata} and \sphinxstyleemphasis{ap\_req\_authdata} for elements of type \sphinxstyleemphasis{ad\_type} . Either input list may be NULL, in which case it will not be searched; otherwise, the input lists must be terminated by NULL entries. This function will search inside AD\sphinxhyphen{}IF\sphinxhyphen{}RELEVANT containers if found in either list. Use krb5\_free\_authdata() to free \sphinxstyleemphasis{results} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.10 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_free\_addresses \sphinxhyphen{} Free the data stored in array of addresses.} \label{\detokenize{appdev/refs/api/krb5_free_addresses:krb5-free-addresses-free-the-data-stored-in-array-of-addresses}}\label{\detokenize{appdev/refs/api/krb5_free_addresses::doc}}\index{krb5\_free\_addresses (C function)@\spxentry{krb5\_free\_addresses}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_addresses:c.krb5_free_addresses}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_addresses}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Array of addresses to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the array itself. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The last entry in the array must be a NULL pointer. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_free\_ap\_rep\_enc\_part \sphinxhyphen{} Free a krb5\_ap\_rep\_enc\_part structure.} \label{\detokenize{appdev/refs/api/krb5_free_ap_rep_enc_part:krb5-free-ap-rep-enc-part-free-a-krb5-ap-rep-enc-part-structure}}\label{\detokenize{appdev/refs/api/krb5_free_ap_rep_enc_part::doc}}\index{krb5\_free\_ap\_rep\_enc\_part (C function)@\spxentry{krb5\_free\_ap\_rep\_enc\_part}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_ap_rep_enc_part:c.krb5_free_ap_rep_enc_part}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_ap\_rep\_enc\_part}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep\_enc\_part}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} AP\sphinxhyphen{}REP enc part to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_authdata \sphinxhyphen{} Free the storage assigned to array of authentication data.} \label{\detokenize{appdev/refs/api/krb5_free_authdata:krb5-free-authdata-free-the-storage-assigned-to-array-of-authentication-data}}\label{\detokenize{appdev/refs/api/krb5_free_authdata::doc}}\index{krb5\_free\_authdata (C function)@\spxentry{krb5\_free\_authdata}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_authdata:c.krb5_free_authdata}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_authdata}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Array of authentication data to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the array itself. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The last entry in the array must be a NULL pointer. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_free\_authenticator \sphinxhyphen{} Free a krb5\_authenticator structure.} \label{\detokenize{appdev/refs/api/krb5_free_authenticator:krb5-free-authenticator-free-a-krb5-authenticator-structure}}\label{\detokenize{appdev/refs/api/krb5_free_authenticator::doc}}\index{krb5\_free\_authenticator (C function)@\spxentry{krb5\_free\_authenticator}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_authenticator:c.krb5_free_authenticator}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_authenticator}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Authenticator structure to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_cred\_contents \sphinxhyphen{} Free the contents of a krb5\_creds structure.} \label{\detokenize{appdev/refs/api/krb5_free_cred_contents:krb5-free-cred-contents-free-the-contents-of-a-krb5-creds-structure}}\label{\detokenize{appdev/refs/api/krb5_free_cred_contents::doc}}\index{krb5\_free\_cred\_contents (C function)@\spxentry{krb5\_free\_cred\_contents}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_cred_contents:c.krb5_free_cred_contents}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_cred\_contents}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Credential structure to free contents of \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} , but not the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_creds \sphinxhyphen{} Free a krb5\_creds structure.} \label{\detokenize{appdev/refs/api/krb5_free_creds:krb5-free-creds-free-a-krb5-creds-structure}}\label{\detokenize{appdev/refs/api/krb5_free_creds::doc}}\index{krb5\_free\_creds (C function)@\spxentry{krb5\_free\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_creds:c.krb5_free_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Credential structure to be freed. \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_data \sphinxhyphen{} Free a krb5\_data structure.} \label{\detokenize{appdev/refs/api/krb5_free_data:krb5-free-data-free-a-krb5-data-structure}}\label{\detokenize{appdev/refs/api/krb5_free_data::doc}}\index{krb5\_free\_data (C function)@\spxentry{krb5\_free\_data}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_data:c.krb5_free_data}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_data}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Data structure to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_data\_contents \sphinxhyphen{} Free the contents of a krb5\_data structure and zero the data field.} \label{\detokenize{appdev/refs/api/krb5_free_data_contents:krb5-free-data-contents-free-the-contents-of-a-krb5-data-structure-and-zero-the-data-field}}\label{\detokenize{appdev/refs/api/krb5_free_data_contents::doc}}\index{krb5\_free\_data\_contents (C function)@\spxentry{krb5\_free\_data\_contents}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_data_contents:c.krb5_free_data_contents}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_data\_contents}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Data structure to free contents of \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} , but not the structure itself. It sets the structure’s data pointer to null and (beginning in release 1.19) sets its length to zero. \sphinxstepscope \subsubsection{krb5\_free\_default\_realm \sphinxhyphen{} Free a default realm string returned by krb5\_get\_default\_realm().} \label{\detokenize{appdev/refs/api/krb5_free_default_realm:krb5-free-default-realm-free-a-default-realm-string-returned-by-krb5-get-default-realm}}\label{\detokenize{appdev/refs/api/krb5_free_default_realm::doc}}\index{krb5\_free\_default\_realm (C function)@\spxentry{krb5\_free\_default\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_default_realm:c.krb5_free_default_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_default\_realm}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{lrealm}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{lrealm} \sphinxhyphen{} Realm to be freed \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_free\_enctypes \sphinxhyphen{} Free an array of encryption types.} \label{\detokenize{appdev/refs/api/krb5_free_enctypes:krb5-free-enctypes-free-an-array-of-encryption-types}}\label{\detokenize{appdev/refs/api/krb5_free_enctypes::doc}}\index{krb5\_free\_enctypes (C function)@\spxentry{krb5\_free\_enctypes}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_enctypes:c.krb5_free_enctypes}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_enctypes}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Array of enctypes to be freed \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.12 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_free\_error \sphinxhyphen{} Free an error allocated by krb5\_read\_error() or krb5\_sendauth().} \label{\detokenize{appdev/refs/api/krb5_free_error:krb5-free-error-free-an-error-allocated-by-krb5-read-error-or-krb5-sendauth}}\label{\detokenize{appdev/refs/api/krb5_free_error::doc}}\index{krb5\_free\_error (C function)@\spxentry{krb5\_free\_error}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_error:c.krb5_free_error}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_error}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Error data structure to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_host\_realm \sphinxhyphen{} Free the memory allocated by krb5\_get\_host\_realm().} \label{\detokenize{appdev/refs/api/krb5_free_host_realm:krb5-free-host-realm-free-the-memory-allocated-by-krb5-get-host-realm}}\label{\detokenize{appdev/refs/api/krb5_free_host_realm::doc}}\index{krb5\_free\_host\_realm (C function)@\spxentry{krb5\_free\_host\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_host_realm:c.krb5_free_host_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_host\_realm}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realmlist}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{realmlist} \sphinxhyphen{} List of realm names to be released \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_free\_keyblock \sphinxhyphen{} Free a krb5\_keyblock structure.} \label{\detokenize{appdev/refs/api/krb5_free_keyblock:krb5-free-keyblock-free-a-krb5-keyblock-structure}}\label{\detokenize{appdev/refs/api/krb5_free_keyblock::doc}}\index{krb5\_free\_keyblock (C function)@\spxentry{krb5\_free\_keyblock}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_keyblock:c.krb5_free_keyblock}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_keyblock}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Keyblock to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_keyblock\_contents \sphinxhyphen{} Free the contents of a krb5\_keyblock structure.} \label{\detokenize{appdev/refs/api/krb5_free_keyblock_contents:krb5-free-keyblock-contents-free-the-contents-of-a-krb5-keyblock-structure}}\label{\detokenize{appdev/refs/api/krb5_free_keyblock_contents::doc}}\index{krb5\_free\_keyblock\_contents (C function)@\spxentry{krb5\_free\_keyblock\_contents}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_keyblock_contents:c.krb5_free_keyblock_contents}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_keyblock\_contents}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Keyblock to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{key} , but not the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_keytab\_entry\_contents \sphinxhyphen{} Free the contents of a key table entry.} \label{\detokenize{appdev/refs/api/krb5_free_keytab_entry_contents:krb5-free-keytab-entry-contents-free-the-contents-of-a-key-table-entry}}\label{\detokenize{appdev/refs/api/krb5_free_keytab_entry_contents::doc}}\index{krb5\_free\_keytab\_entry\_contents (C function)@\spxentry{krb5\_free\_keytab\_entry\_contents}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_keytab_entry_contents:c.krb5_free_keytab_entry_contents}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_keytab\_entry\_contents}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{entry}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{entry} \sphinxhyphen{} Key table entry whose contents are to be freed \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The pointer is not freed. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_free\_string \sphinxhyphen{} Free a string allocated by a krb5 function.} \label{\detokenize{appdev/refs/api/krb5_free_string:krb5-free-string-free-a-string-allocated-by-a-krb5-function}}\label{\detokenize{appdev/refs/api/krb5_free_string::doc}}\index{krb5\_free\_string (C function)@\spxentry{krb5\_free\_string}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_string:c.krb5_free_string}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_string}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} String to be freed \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.10 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_free\_ticket \sphinxhyphen{} Free a ticket.} \label{\detokenize{appdev/refs/api/krb5_free_ticket:krb5-free-ticket-free-a-ticket}}\label{\detokenize{appdev/refs/api/krb5_free_ticket::doc}}\index{krb5\_free\_ticket (C function)@\spxentry{krb5\_free\_ticket}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_ticket:c.krb5_free_ticket}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_ticket}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Ticket to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_unparsed\_name \sphinxhyphen{} Free a string representation of a principal.} \label{\detokenize{appdev/refs/api/krb5_free_unparsed_name:krb5-free-unparsed-name-free-a-string-representation-of-a-principal}}\label{\detokenize{appdev/refs/api/krb5_free_unparsed_name::doc}}\index{krb5\_free\_unparsed\_name (C function)@\spxentry{krb5\_free\_unparsed\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_unparsed_name:c.krb5_free_unparsed_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_unparsed\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Name string to be freed \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_etype\_info \sphinxhyphen{} Retrieve enctype, salt and s2kparams from KDC.} \label{\detokenize{appdev/refs/api/krb5_get_etype_info:krb5-get-etype-info-retrieve-enctype-salt-and-s2kparams-from-kdc}}\label{\detokenize{appdev/refs/api/krb5_get_etype_info::doc}}\index{krb5\_get\_etype\_info (C function)@\spxentry{krb5\_get\_etype\_info}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_etype_info:c.krb5_get_etype_info}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_etype\_info}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{enctype\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{salt\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{s2kparams\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Principal whose information is requested \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{opt} \sphinxhyphen{} Initial credential options \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{enctype\_out} \sphinxhyphen{} The enctype chosen by KDC \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{salt\_out} \sphinxhyphen{} Salt returned from KDC \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{s2kparams\_out} \sphinxhyphen{} String\sphinxhyphen{}to\sphinxhyphen{}key parameters returned from KDC \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar A Kerberos error code \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Send an initial ticket request for \sphinxstyleemphasis{principal} and extract the encryption type, salt type, and string\sphinxhyphen{}to\sphinxhyphen{}key parameters from the KDC response. If the KDC provides no etype\sphinxhyphen{}info, set \sphinxstyleemphasis{enctype\_out} to \sphinxstylestrong{ENCTYPE\_NULL} and set \sphinxstyleemphasis{salt\_out} and \sphinxstyleemphasis{s2kparams\_out} to empty. If the KDC etype\sphinxhyphen{}info provides no salt, compute the default salt and place it in \sphinxstyleemphasis{salt\_out} . If the KDC etype\sphinxhyphen{}info provides no string\sphinxhyphen{}to\sphinxhyphen{}key parameters, set \sphinxstyleemphasis{s2kparams\_out} to empty. \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{opt} may be used to specify options which affect the initial request, such as request encryption types or a FAST armor cache (see krb5\_get\_init\_creds\_opt\_set\_etype\_list() and krb5\_get\_init\_creds\_opt\_set\_fast\_ccache\_name()). \end{quote} \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{salt\_out} and \sphinxstyleemphasis{s2kparams\_out} when they are no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.17 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_get\_permitted\_enctypes \sphinxhyphen{} Return a list of encryption types permitted for session keys.} \label{\detokenize{appdev/refs/api/krb5_get_permitted_enctypes:krb5-get-permitted-enctypes-return-a-list-of-encryption-types-permitted-for-session-keys}}\label{\detokenize{appdev/refs/api/krb5_get_permitted_enctypes::doc}}\index{krb5\_get\_permitted\_enctypes (C function)@\spxentry{krb5\_get\_permitted\_enctypes}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_permitted_enctypes:c.krb5_get_permitted_enctypes}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_permitted\_enctypes}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ktypes}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ktypes} \sphinxhyphen{} Zero\sphinxhyphen{}terminated list of encryption types \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function returns the list of encryption types permitted for session keys within \sphinxstyleemphasis{context} , as determined by configuration or by a previous call to krb5\_set\_default\_tgs\_enctypes(). \sphinxAtStartPar Use krb5\_free\_enctypes() to free \sphinxstyleemphasis{ktypes} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_get\_server\_rcache \sphinxhyphen{} Generate a replay cache object for server use and open it.} \label{\detokenize{appdev/refs/api/krb5_get_server_rcache:krb5-get-server-rcache-generate-a-replay-cache-object-for-server-use-and-open-it}}\label{\detokenize{appdev/refs/api/krb5_get_server_rcache::doc}}\index{krb5\_get\_server\_rcache (C function)@\spxentry{krb5\_get\_server\_rcache}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_server_rcache:c.krb5_get_server_rcache}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_server\_rcache}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{piece}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_rcache:c.krb5_rcache}]{\sphinxcrossref{\DUrole{n}{krb5\_rcache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rcptr}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{piece} \sphinxhyphen{} Unused (replay cache identifier) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rcptr} \sphinxhyphen{} Handle to an open rcache \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a handle to the default replay cache. Use krb5\_rc\_close() to close \sphinxstyleemphasis{rcptr} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar Prior to release 1.18, this function creates a handle to a different replay cache for each unique value of \sphinxstyleemphasis{piece} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_get\_time\_offsets \sphinxhyphen{} Return the time offsets from the os context.} \label{\detokenize{appdev/refs/api/krb5_get_time_offsets:krb5-get-time-offsets-return-the-time-offsets-from-the-os-context}}\label{\detokenize{appdev/refs/api/krb5_get_time_offsets::doc}}\index{krb5\_get\_time\_offsets (C function)@\spxentry{krb5\_get\_time\_offsets}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_time_offsets:c.krb5_get_time_offsets}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_time\_offsets}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{seconds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{microseconds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{seconds} \sphinxhyphen{} Time offset, seconds portion \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{microseconds} \sphinxhyphen{} Time offset, microseconds portion \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function returns the time offsets in \sphinxstyleemphasis{context} . \sphinxstepscope \subsubsection{krb5\_init\_context\_profile \sphinxhyphen{} Create a krb5 library context using a specified profile.} \label{\detokenize{appdev/refs/api/krb5_init_context_profile:krb5-init-context-profile-create-a-krb5-library-context-using-a-specified-profile}}\label{\detokenize{appdev/refs/api/krb5_init_context_profile::doc}}\index{krb5\_init\_context\_profile (C function)@\spxentry{krb5\_init\_context\_profile}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_context_profile:c.krb5_init_context_profile}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_context\_profile}}}}{\DUrole{k}{struct}\DUrole{w}{ }\DUrole{n}{\_profile\_t}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{profile}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{flags}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{profile} \sphinxhyphen{} Profile object (NULL to create default profile) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Context initialization flags \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \end{description}\end{quote} \sphinxAtStartPar Create a context structure, optionally using a specified profile and initialization flags. If \sphinxstyleemphasis{profile} is NULL, the default profile will be created from config files. If \sphinxstyleemphasis{profile} is non\sphinxhyphen{}null, a copy of it will be made for the new context; the caller should still clean up its copy. Valid flag values are: \begin{itemize} \item {} \sphinxAtStartPar KRB5\_INIT\_CONTEXT\_SECURE Ignore environment variables \item {} \sphinxAtStartPar KRB5\_INIT\_CONTEXT\_KDC Use KDC configuration if creating profile \end{itemize} \sphinxstepscope \subsubsection{krb5\_init\_creds\_free \sphinxhyphen{} Free an initial credentials context.} \label{\detokenize{appdev/refs/api/krb5_init_creds_free:krb5-init-creds-free-free-an-initial-credentials-context}}\label{\detokenize{appdev/refs/api/krb5_init_creds_free::doc}}\index{krb5\_init\_creds\_free (C function)@\spxentry{krb5\_init\_creds\_free}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_free:c.krb5_init_creds_free}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_free}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Initial credentials context \end{description}\end{quote} \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{context} must be the same as the one passed to krb5\_init\_creds\_init() for this initial credentials context. \end{quote} \sphinxstepscope \subsubsection{krb5\_init\_creds\_get \sphinxhyphen{} Acquire credentials using an initial credentials context.} \label{\detokenize{appdev/refs/api/krb5_init_creds_get:krb5-init-creds-get-acquire-credentials-using-an-initial-credentials-context}}\label{\detokenize{appdev/refs/api/krb5_init_creds_get::doc}}\index{krb5\_init\_creds\_get (C function)@\spxentry{krb5\_init\_creds\_get}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_get:c.krb5_init_creds_get}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_get}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Initial credentials context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function synchronously obtains credentials using a context created by krb5\_init\_creds\_init(). On successful return, the credentials can be retrieved with krb5\_init\_creds\_get\_creds(). \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{context} must be the same as the one passed to krb5\_init\_creds\_init() for this initial credentials context. \end{quote} \sphinxstepscope \subsubsection{krb5\_init\_creds\_get\_creds \sphinxhyphen{} Retrieve acquired credentials from an initial credentials context.} \label{\detokenize{appdev/refs/api/krb5_init_creds_get_creds:krb5-init-creds-get-creds-retrieve-acquired-credentials-from-an-initial-credentials-context}}\label{\detokenize{appdev/refs/api/krb5_init_creds_get_creds::doc}}\index{krb5\_init\_creds\_get\_creds (C function)@\spxentry{krb5\_init\_creds\_get\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_get_creds:c.krb5_init_creds_get_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_get\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Initial credentials context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Acquired credentials \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function copies the acquired initial credentials from \sphinxstyleemphasis{ctx} into \sphinxstyleemphasis{creds} , after the successful completion of krb5\_init\_creds\_get() or krb5\_init\_creds\_step(). Use krb5\_free\_cred\_contents() to free \sphinxstyleemphasis{creds} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_init\_creds\_get\_error \sphinxhyphen{} Get the last error from KDC from an initial credentials context.} \label{\detokenize{appdev/refs/api/krb5_init_creds_get_error:krb5-init-creds-get-error-get-the-last-error-from-kdc-from-an-initial-credentials-context}}\label{\detokenize{appdev/refs/api/krb5_init_creds_get_error::doc}}\index{krb5\_init\_creds\_get\_error (C function)@\spxentry{krb5\_init\_creds\_get\_error}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_get_error:c.krb5_init_creds_get_error}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_get\_error}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{error}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Initial credentials context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{error} \sphinxhyphen{} Error from KDC, or NULL if none was received \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_init\_creds\_get\_times \sphinxhyphen{} Retrieve ticket times from an initial credentials context.} \label{\detokenize{appdev/refs/api/krb5_init_creds_get_times:krb5-init-creds-get-times-retrieve-ticket-times-from-an-initial-credentials-context}}\label{\detokenize{appdev/refs/api/krb5_init_creds_get_times::doc}}\index{krb5\_init\_creds\_get\_times (C function)@\spxentry{krb5\_init\_creds\_get\_times}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_get_times:c.krb5_init_creds_get_times}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_get\_times}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{times}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Initial credentials context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{times} \sphinxhyphen{} Ticket times for acquired credentials \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar The initial credentials context must have completed obtaining credentials via either krb5\_init\_creds\_get() or krb5\_init\_creds\_step(). \sphinxstepscope \subsubsection{krb5\_init\_creds\_init \sphinxhyphen{} Create a context for acquiring initial credentials.} \label{\detokenize{appdev/refs/api/krb5_init_creds_init:krb5-init-creds-init-create-a-context-for-acquiring-initial-credentials}}\label{\detokenize{appdev/refs/api/krb5_init_creds_init::doc}}\index{krb5\_init\_creds\_init (C function)@\spxentry{krb5\_init\_creds\_init}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_init:c.krb5_init_creds_init}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_init}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{client}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_prompter_fct:c.krb5_prompter_fct}]{\sphinxcrossref{\DUrole{n}{krb5\_prompter\_fct}}}}\DUrole{w}{ }\DUrole{n}{prompter}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}]{\sphinxcrossref{\DUrole{n}{krb5\_deltat}}}}\DUrole{w}{ }\DUrole{n}{start\_time}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ctx}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{client} \sphinxhyphen{} Client principal to get initial creds for \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{prompter} \sphinxhyphen{} Prompter callback \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Prompter callback argument \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{start\_time} \sphinxhyphen{} Time when credentials become valid (0 for now) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{options} \sphinxhyphen{} Options structure (NULL for default) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} New initial credentials context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a new context for acquiring initial credentials. Use krb5\_init\_creds\_free() to free \sphinxstyleemphasis{ctx} when it is no longer needed. \sphinxAtStartPar Any subsequent calls to krb5\_init\_creds\_step(), krb5\_init\_creds\_get(), or krb5\_init\_creds\_free() for this initial credentials context must use the same \sphinxstyleemphasis{context} argument as the one passed to this function. \sphinxstepscope \subsubsection{krb5\_init\_creds\_set\_keytab \sphinxhyphen{} Specify a keytab to use for acquiring initial credentials.} \label{\detokenize{appdev/refs/api/krb5_init_creds_set_keytab:krb5-init-creds-set-keytab-specify-a-keytab-to-use-for-acquiring-initial-credentials}}\label{\detokenize{appdev/refs/api/krb5_init_creds_set_keytab::doc}}\index{krb5\_init\_creds\_set\_keytab (C function)@\spxentry{krb5\_init\_creds\_set\_keytab}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_set_keytab:c.krb5_init_creds_set_keytab}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_set\_keytab}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Initial credentials context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function supplies a keytab containing the client key for an initial credentials request. \sphinxstepscope \subsubsection{krb5\_init\_creds\_set\_password \sphinxhyphen{} Set a password for acquiring initial credentials.} \label{\detokenize{appdev/refs/api/krb5_init_creds_set_password:krb5-init-creds-set-password-set-a-password-for-acquiring-initial-credentials}}\label{\detokenize{appdev/refs/api/krb5_init_creds_set_password::doc}}\index{krb5\_init\_creds\_set\_password (C function)@\spxentry{krb5\_init\_creds\_set\_password}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_set_password:c.krb5_init_creds_set_password}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_set\_password}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{password}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Initial credentials context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{password} \sphinxhyphen{} Password \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function supplies a password to be used to construct the client key for an initial credentials request. \sphinxstepscope \subsubsection{krb5\_init\_creds\_set\_service \sphinxhyphen{} Specify a service principal for acquiring initial credentials.} \label{\detokenize{appdev/refs/api/krb5_init_creds_set_service:krb5-init-creds-set-service-specify-a-service-principal-for-acquiring-initial-credentials}}\label{\detokenize{appdev/refs/api/krb5_init_creds_set_service::doc}}\index{krb5\_init\_creds\_set\_service (C function)@\spxentry{krb5\_init\_creds\_set\_service}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_set_service:c.krb5_init_creds_set_service}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_set\_service}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{service}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Initial credentials context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{service} \sphinxhyphen{} Service principal string \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function supplies a service principal string to acquire initial credentials for instead of the default krbtgt service. \sphinxstyleemphasis{service} is parsed as a principal name; any realm part is ignored. \sphinxstepscope \subsubsection{krb5\_init\_creds\_step \sphinxhyphen{} Get the next KDC request for acquiring initial credentials.} \label{\detokenize{appdev/refs/api/krb5_init_creds_step:krb5-init-creds-step-get-the-next-kdc-request-for-acquiring-initial-credentials}}\label{\detokenize{appdev/refs/api/krb5_init_creds_step::doc}}\index{krb5\_init\_creds\_step (C function)@\spxentry{krb5\_init\_creds\_step}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_creds_step:c.krb5_init_creds_step}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_step}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_init\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Initial credentials context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in} \sphinxhyphen{} KDC response (empty on the first call) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out} \sphinxhyphen{} Next KDC request \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Realm for next KDC request \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Output flags \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function constructs the next KDC request in an initial credential exchange, allowing the caller to control the transport of KDC requests and replies. On the first call, \sphinxstyleemphasis{in} should be set to an empty buffer; on subsequent calls, it should be set to the KDC’s reply to the previous request. \sphinxAtStartPar If more requests are needed, \sphinxstyleemphasis{flags} will be set to KRB5\_INIT\_CREDS\_STEP\_FLAG\_CONTINUE and the next request will be placed in \sphinxstyleemphasis{out} . If no more requests are needed, \sphinxstyleemphasis{flags} will not contain KRB5\_INIT\_CREDS\_STEP\_FLAG\_CONTINUE and \sphinxstyleemphasis{out} will be empty. \sphinxAtStartPar If this function returns \sphinxstylestrong{KRB5KRB\_ERR\_RESPONSE\_TOO\_BIG} , the caller should transmit the next request using TCP rather than UDP. If this function returns any other error, the initial credential exchange has failed. \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{context} must be the same as the one passed to krb5\_init\_creds\_init() for this initial credentials context. \end{quote} \sphinxstepscope \subsubsection{krb5\_init\_keyblock \sphinxhyphen{} Initialize an empty krb5\_keyblock .} \label{\detokenize{appdev/refs/api/krb5_init_keyblock:krb5-init-keyblock-initialize-an-empty-krb5-keyblock}}\label{\detokenize{appdev/refs/api/krb5_init_keyblock::doc}}\index{krb5\_init\_keyblock (C function)@\spxentry{krb5\_init\_keyblock}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_keyblock:c.krb5_init_keyblock}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_keyblock}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{length}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{length} \sphinxhyphen{} Length of keyblock (or 0) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out} \sphinxhyphen{} New keyblock structure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Initialize a new keyblock and allocate storage for the contents of the key. It is legal to pass in a length of 0, in which case contents are left unallocated. Use krb5\_free\_keyblock() to free \sphinxstyleemphasis{out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If \sphinxstyleemphasis{length} is set to 0, contents are left unallocated. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_is\_referral\_realm \sphinxhyphen{} Check for a match with KRB5\_REFERRAL\_REALM.} \label{\detokenize{appdev/refs/api/krb5_is_referral_realm:krb5-is-referral-realm-check-for-a-match-with-krb5-referral-realm}}\label{\detokenize{appdev/refs/api/krb5_is_referral_realm::doc}}\index{krb5\_is\_referral\_realm (C function)@\spxentry{krb5\_is\_referral\_realm}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_is_referral_realm:c.krb5_is_referral_realm}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_is\_referral\_realm}}}}{\DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{r}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{r} \sphinxhyphen{} Realm to check \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar TRUE if r is zero\sphinxhyphen{}length, FALSE otherwise \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_kdc\_sign\_ticket \sphinxhyphen{} Sign a PAC, possibly including a ticket signature.} \label{\detokenize{appdev/refs/api/krb5_kdc_sign_ticket:krb5-kdc-sign-ticket-sign-a-pac-possibly-including-a-ticket-signature}}\label{\detokenize{appdev/refs/api/krb5_kdc_sign_ticket::doc}}\index{krb5\_kdc\_sign\_ticket (C function)@\spxentry{krb5\_kdc\_sign\_ticket}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kdc_sign_ticket:c.krb5_kdc_sign_ticket}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kdc\_sign\_ticket}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{enc\_tkt}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{server\_princ}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{client\_princ}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{server}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{privsvr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{n}{with\_realm}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enc\_tkt} \sphinxhyphen{} The ticket for the signature \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pac} \sphinxhyphen{} PAC handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server\_princ} \sphinxhyphen{} Canonical ticket server name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{client\_princ} \sphinxhyphen{} PAC\_CLIENT\_INFO principal (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Key for server checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{privsvr} \sphinxhyphen{} Key for KDC and ticket checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{with\_realm} \sphinxhyphen{} If true, include the realm of \sphinxstyleemphasis{principal} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 on success, otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Sign \sphinxstyleemphasis{pac} using the keys \sphinxstyleemphasis{server} and \sphinxstyleemphasis{privsvr} . Include a ticket signature over \sphinxstyleemphasis{enc\_tkt} if \sphinxstyleemphasis{server\_princ} is not a TGS or kadmin/changepw principal name. Add the signed PAC’s encoding to the authorization data of \sphinxstyleemphasis{enc\_tkt} in the first slot, wrapped in an AD\sphinxhyphen{}IF\sphinxhyphen{}RELEVANT container. If \sphinxstyleemphasis{client\_princ} is non\sphinxhyphen{}null, add a PAC\_CLIENT\_INFO buffer, including the realm if \sphinxstyleemphasis{with\_realm} is true. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.20 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_kdc\_verify\_ticket \sphinxhyphen{} Verify a PAC, possibly including ticket signature.} \label{\detokenize{appdev/refs/api/krb5_kdc_verify_ticket:krb5-kdc-verify-ticket-verify-a-pac-possibly-including-ticket-signature}}\label{\detokenize{appdev/refs/api/krb5_kdc_verify_ticket::doc}}\index{krb5\_kdc\_verify\_ticket (C function)@\spxentry{krb5\_kdc\_verify\_ticket}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kdc_verify_ticket:c.krb5_kdc_verify_ticket}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kdc\_verify\_ticket}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{enc\_tkt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{server\_princ}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{server}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{privsvr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pac\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enc\_tkt} \sphinxhyphen{} Ticket enc\sphinxhyphen{}part, possibly containing a PAC \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server\_princ} \sphinxhyphen{} Canonicalized name of ticket server \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Key to validate server checksum (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{privsvr} \sphinxhyphen{} Key to validate KDC checksum (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{pac\_out} \sphinxhyphen{} Verified PAC (NULL if no PAC included) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar If a PAC is present in \sphinxstyleemphasis{enc\_tkt} , verify its signatures. If \sphinxstyleemphasis{privsvr} is not NULL and \sphinxstyleemphasis{server\_princ} is not a krbtgt or kadmin/changepw service, require a ticket signature over \sphinxstyleemphasis{enc\_tkt} in addition to the KDC signature. Place the verified PAC in \sphinxstyleemphasis{pac\_out} . If an invalid PAC signature is found, return an error matching the Windows KDC protocol code for that condition as closely as possible. \sphinxAtStartPar If no PAC is present in \sphinxstyleemphasis{enc\_tkt} , set \sphinxstyleemphasis{pac\_out} to NULL and return successfully. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function does not validate the PAC\_CLIENT\_INFO buffer. If a specific value is expected, the caller can make a separate call to krb5\_pac\_verify\_ext() with a principal but no keys. \end{sphinxadmonition} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.20 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_kt\_add\_entry \sphinxhyphen{} Add a new entry to a key table.} \label{\detokenize{appdev/refs/api/krb5_kt_add_entry:krb5-kt-add-entry-add-a-new-entry-to-a-key-table}}\label{\detokenize{appdev/refs/api/krb5_kt_add_entry::doc}}\index{krb5\_kt\_add\_entry (C function)@\spxentry{krb5\_kt\_add\_entry}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_add_entry:c.krb5_kt_add_entry}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_add\_entry}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{id}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{entry}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{id} \sphinxhyphen{} Key table handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{entry} \sphinxhyphen{} Entry to be added \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar ENOMEM Insufficient memory \item {} \sphinxAtStartPar KRB5\_KT\_NOWRITE Key table is not writeable \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_kt\_end\_seq\_get \sphinxhyphen{} Release a keytab cursor.} \label{\detokenize{appdev/refs/api/krb5_kt_end_seq_get:krb5-kt-end-seq-get-release-a-keytab-cursor}}\label{\detokenize{appdev/refs/api/krb5_kt_end_seq_get::doc}}\index{krb5\_kt\_end\_seq\_get (C function)@\spxentry{krb5\_kt\_end\_seq\_get}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_end_seq_get:c.krb5_kt_end_seq_get}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_end\_seq\_get}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_kt_cursor:c.krb5_kt_cursor}]{\sphinxcrossref{\DUrole{n}{krb5\_kt\_cursor}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cursor}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cursor} \sphinxhyphen{} Cursor \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function should be called to release the cursor created by krb5\_kt\_start\_seq\_get(). \sphinxstepscope \subsubsection{krb5\_kt\_get\_entry \sphinxhyphen{} Get an entry from a key table.} \label{\detokenize{appdev/refs/api/krb5_kt_get_entry:krb5-kt-get-entry-get-an-entry-from-a-key-table}}\label{\detokenize{appdev/refs/api/krb5_kt_get_entry::doc}}\index{krb5\_kt\_get\_entry (C function)@\spxentry{krb5\_kt\_get\_entry}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_get_entry:c.krb5_kt_get_entry}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_get\_entry}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_kvno:c.krb5_kvno}]{\sphinxcrossref{\DUrole{n}{krb5\_kvno}}}}\DUrole{w}{ }\DUrole{n}{vno}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{entry}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Principal name \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{vno} \sphinxhyphen{} Key version number (0 for highest available) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type (0 zero for any enctype) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{entry} \sphinxhyphen{} Returned entry from key table \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar Kerberos error codes on failure \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Retrieve an entry from a key table which matches the \sphinxstyleemphasis{keytab} , \sphinxstyleemphasis{principal} , \sphinxstyleemphasis{vno} , and \sphinxstyleemphasis{enctype} . If \sphinxstyleemphasis{vno} is zero, retrieve the highest\sphinxhyphen{}numbered kvno matching the other fields. If \sphinxstyleemphasis{enctype} is 0, match any enctype. \sphinxAtStartPar Use krb5\_free\_keytab\_entry\_contents() to free \sphinxstyleemphasis{entry} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If \sphinxstyleemphasis{vno} is zero, the function retrieves the highest\sphinxhyphen{}numbered\sphinxhyphen{}kvno entry that matches the specified principal. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_kt\_have\_content \sphinxhyphen{} Check if a keytab exists and contains entries.} \label{\detokenize{appdev/refs/api/krb5_kt_have_content:krb5-kt-have-content-check-if-a-keytab-exists-and-contains-entries}}\label{\detokenize{appdev/refs/api/krb5_kt_have_content::doc}}\index{krb5\_kt\_have\_content (C function)@\spxentry{krb5\_kt\_have\_content}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_have_content:c.krb5_kt_have_content}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_have\_content}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Keytab exists and contains entries \item {} \sphinxAtStartPar KRB5\_KT\_NOTFOUND Keytab does not contain entries \end{itemize} \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.11 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_kt\_next\_entry \sphinxhyphen{} Retrieve the next entry from the key table.} \label{\detokenize{appdev/refs/api/krb5_kt_next_entry:krb5-kt-next-entry-retrieve-the-next-entry-from-the-key-table}}\label{\detokenize{appdev/refs/api/krb5_kt_next_entry::doc}}\index{krb5\_kt\_next\_entry (C function)@\spxentry{krb5\_kt\_next\_entry}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_next_entry:c.krb5_kt_next_entry}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_next\_entry}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{entry}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_kt_cursor:c.krb5_kt_cursor}]{\sphinxcrossref{\DUrole{n}{krb5\_kt\_cursor}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cursor}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{entry} \sphinxhyphen{} Returned key table entry \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cursor} \sphinxhyphen{} Key table cursor \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KRB5\_KT\_END \sphinxhyphen{} if the last entry was reached \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Return the next sequential entry in \sphinxstyleemphasis{keytab} and advance \sphinxstyleemphasis{cursor} . Callers must release the returned entry with krb5\_kt\_free\_entry(). \sphinxstepscope \subsubsection{krb5\_kt\_read\_service\_key \sphinxhyphen{} Retrieve a service key from a key table.} \label{\detokenize{appdev/refs/api/krb5_kt_read_service_key:krb5-kt-read-service-key-retrieve-a-service-key-from-a-key-table}}\label{\detokenize{appdev/refs/api/krb5_kt_read_service_key::doc}}\index{krb5\_kt\_read\_service\_key (C function)@\spxentry{krb5\_kt\_read\_service\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_read_service_key:c.krb5_kt_read_service_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_read\_service\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{n}{keyprocarg}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_kvno:c.krb5_kvno}]{\sphinxcrossref{\DUrole{n}{krb5\_kvno}}}}\DUrole{w}{ }\DUrole{n}{vno}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keyprocarg} \sphinxhyphen{} Name of a key table (NULL to use default name) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Service principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{vno} \sphinxhyphen{} Key version number (0 for highest available) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type (0 for any type) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{key} \sphinxhyphen{} Service key from key table \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error code if not found or keyprocarg is invalid. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Open and search the specified key table for the entry identified by \sphinxstyleemphasis{principal} , \sphinxstyleemphasis{enctype} , and \sphinxstyleemphasis{vno} . If no key is found, return an error code. \sphinxAtStartPar The default key table is used, unless \sphinxstyleemphasis{keyprocarg} is non\sphinxhyphen{}null. \sphinxstyleemphasis{keyprocarg} designates a specific key table. \sphinxAtStartPar Use krb5\_free\_keyblock() to free \sphinxstyleemphasis{key} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_kt\_remove\_entry \sphinxhyphen{} Remove an entry from a key table.} \label{\detokenize{appdev/refs/api/krb5_kt_remove_entry:krb5-kt-remove-entry-remove-an-entry-from-a-key-table}}\label{\detokenize{appdev/refs/api/krb5_kt_remove_entry::doc}}\index{krb5\_kt\_remove\_entry (C function)@\spxentry{krb5\_kt\_remove\_entry}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_remove_entry:c.krb5_kt_remove_entry}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_remove\_entry}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{id}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{entry}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{id} \sphinxhyphen{} Key table handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{entry} \sphinxhyphen{} Entry to remove from key table \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KRB5\_KT\_NOWRITE Key table is not writable \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_kt\_start\_seq\_get \sphinxhyphen{} Start a sequential retrieval of key table entries.} \label{\detokenize{appdev/refs/api/krb5_kt_start_seq_get:krb5-kt-start-seq-get-start-a-sequential-retrieval-of-key-table-entries}}\label{\detokenize{appdev/refs/api/krb5_kt_start_seq_get::doc}}\index{krb5\_kt\_start\_seq\_get (C function)@\spxentry{krb5\_kt\_start\_seq\_get}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_start_seq_get:c.krb5_kt_start_seq_get}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_start\_seq\_get}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_kt_cursor:c.krb5_kt_cursor}]{\sphinxcrossref{\DUrole{n}{krb5\_kt\_cursor}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cursor}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cursor} \sphinxhyphen{} Cursor \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Prepare to read sequentially every key in the specified key table. Use krb5\_kt\_end\_seq\_get() to release the cursor when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_make\_authdata\_kdc\_issued \sphinxhyphen{} Encode and sign AD\sphinxhyphen{}KDCIssued authorization data.} \label{\detokenize{appdev/refs/api/krb5_make_authdata_kdc_issued:krb5-make-authdata-kdc-issued-encode-and-sign-ad-kdcissued-authorization-data}}\label{\detokenize{appdev/refs/api/krb5_make_authdata_kdc_issued::doc}}\index{krb5\_make\_authdata\_kdc\_issued (C function)@\spxentry{krb5\_make\_authdata\_kdc\_issued}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_make_authdata_kdc_issued:c.krb5_make_authdata_kdc_issued}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_make\_authdata\_kdc\_issued}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{issuer}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{authdata}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ad\_kdcissued}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Session key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{issuer} \sphinxhyphen{} The name of the issuing principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{authdata} \sphinxhyphen{} List of authorization data to be signed \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ad\_kdcissued} \sphinxhyphen{} List containing AD\sphinxhyphen{}KDCIssued authdata \end{description}\end{quote} \sphinxAtStartPar This function wraps a list of authorization data entries \sphinxstyleemphasis{authdata} in an AD\sphinxhyphen{}KDCIssued container (see RFC 4120 section 5.2.6.2) signed with \sphinxstyleemphasis{key} . The result is returned in \sphinxstyleemphasis{ad\_kdcissued} as a single\sphinxhyphen{}element list. \sphinxstepscope \subsubsection{krb5\_marshal\_credentials \sphinxhyphen{} Serialize a krb5\_creds object.} \label{\detokenize{appdev/refs/api/krb5_marshal_credentials:krb5-marshal-credentials-serialize-a-krb5-creds-object}}\label{\detokenize{appdev/refs/api/krb5_marshal_credentials::doc}}\index{krb5\_marshal\_credentials (C function)@\spxentry{krb5\_marshal\_credentials}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_marshal_credentials:c.krb5_marshal_credentials}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_marshal\_credentials}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{data\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_creds} \sphinxhyphen{} The credentials object to serialize \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{data\_out} \sphinxhyphen{} The serialized credentials \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Serialize \sphinxstyleemphasis{creds} in the format used by the FILE ccache format (vesion 4) and KCM ccache protocol. \sphinxAtStartPar Use krb5\_free\_data() to free \sphinxstyleemphasis{data\_out} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_merge\_authdata \sphinxhyphen{} Merge two authorization data lists into a new list.} \label{\detokenize{appdev/refs/api/krb5_merge_authdata:krb5-merge-authdata-merge-two-authorization-data-lists-into-a-new-list}}\label{\detokenize{appdev/refs/api/krb5_merge_authdata::doc}}\index{krb5\_merge\_authdata (C function)@\spxentry{krb5\_merge\_authdata}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_merge_authdata:c.krb5_merge_authdata}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_merge\_authdata}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{inauthdat1}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{inauthdat2}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{outauthdat}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inauthdat1} \sphinxhyphen{} First list of \sphinxstyleemphasis{krb5\_authdata} structures \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inauthdat2} \sphinxhyphen{} Second list of \sphinxstyleemphasis{krb5\_authdata} structures \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outauthdat} \sphinxhyphen{} Merged list of \sphinxstyleemphasis{krb5\_authdata} structures \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Merge two authdata arrays, such as the array from a ticket and authenticator. Use krb5\_free\_authdata() to free \sphinxstyleemphasis{outauthdat} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The last array entry in \sphinxstyleemphasis{inauthdat1} and \sphinxstyleemphasis{inauthdat2} must be a NULL pointer. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_mk\_1cred \sphinxhyphen{} Format a KRB\sphinxhyphen{}CRED message for a single set of credentials.} \label{\detokenize{appdev/refs/api/krb5_mk_1cred:krb5-mk-1cred-format-a-krb-cred-message-for-a-single-set-of-credentials}}\label{\detokenize{appdev/refs/api/krb5_mk_1cred::doc}}\index{krb5\_mk\_1cred (C function)@\spxentry{krb5\_mk\_1cred}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_mk_1cred:c.krb5_mk_1cred}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_1cred}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{der\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rdata\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Pointer to credentials \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{der\_out} \sphinxhyphen{} Encoded credentials \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rdata\_out} \sphinxhyphen{} Replay cache data (NULL if not needed) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar ENOMEM Insufficient memory \item {} \sphinxAtStartPar KRB5\_RC\_REQUIRED Message replay detection requires rcache parameter \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This is a convenience function that calls krb5\_mk\_ncred() with a single set of credentials. \sphinxstepscope \subsubsection{krb5\_mk\_error \sphinxhyphen{} Format and encode a KRB\_ERROR message.} \label{\detokenize{appdev/refs/api/krb5_mk_error:krb5-mk-error-format-and-encode-a-krb-error-message}}\label{\detokenize{appdev/refs/api/krb5_mk_error::doc}}\index{krb5\_mk\_error (C function)@\spxentry{krb5\_mk\_error}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_mk_error:c.krb5_mk_error}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_error}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{dec\_err}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{enc\_err}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{dec\_err} \sphinxhyphen{} Error structure to be encoded \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{enc\_err} \sphinxhyphen{} Encoded error structure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates a \sphinxstylestrong{KRB\_ERROR} message in \sphinxstyleemphasis{enc\_err} . Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{enc\_err} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_mk\_ncred \sphinxhyphen{} Format a KRB\sphinxhyphen{}CRED message for an array of credentials.} \label{\detokenize{appdev/refs/api/krb5_mk_ncred:krb5-mk-ncred-format-a-krb-cred-message-for-an-array-of-credentials}}\label{\detokenize{appdev/refs/api/krb5_mk_ncred::doc}}\index{krb5\_mk\_ncred (C function)@\spxentry{krb5\_mk\_ncred}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_mk_ncred:c.krb5_mk_ncred}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_ncred}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{der\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rdata\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Null\sphinxhyphen{}terminated array of credentials \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{der\_out} \sphinxhyphen{} Encoded credentials \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rdata\_out} \sphinxhyphen{} Replay cache information (NULL if not needed) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar ENOMEM Insufficient memory \item {} \sphinxAtStartPar KRB5\_RC\_REQUIRED Message replay detection requires rcache parameter \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function takes an array of credentials \sphinxstyleemphasis{creds} and formats a \sphinxstylestrong{KRB\sphinxhyphen{}CRED} message \sphinxstyleemphasis{der\_out} to pass to krb5\_rd\_cred(). \sphinxAtStartPar The local and remote addresses in \sphinxstyleemphasis{auth\_context} are optional; if either is specified, they are used to form the sender and receiver addresses in the KRB\sphinxhyphen{}CRED message. \sphinxAtStartPar If the KRB5\_AUTH\_CONTEXT\_DO\_TIME flag is set in \sphinxstyleemphasis{auth\_context} , an entry for the message is entered in an in\sphinxhyphen{}memory replay cache to detect if the message is reflected by an attacker. If KRB5\_AUTH\_CONTEXT\_DO\_TIME is not set, no replay cache is used. If KRB5\_AUTH\_CONTEXT\_RET\_TIME is set in \sphinxstyleemphasis{auth\_context} , the timestamp used for the KRB\sphinxhyphen{}CRED message is stored in \sphinxstyleemphasis{rdata\_out} . \sphinxAtStartPar If either KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE is set, the \sphinxstyleemphasis{auth\_context} local sequence number is included in the KRB\sphinxhyphen{}CRED message and then incremented. If KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE is set, the sequence number used is stored in \sphinxstyleemphasis{rdata\_out} . \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{der\_out} when it is no longer needed. \sphinxAtStartPar The message will be encrypted using the send subkey of \sphinxstyleemphasis{auth\_context} if it is present, or the session key otherwise. If neither key is present, the credentials will not be encrypted, and the message should only be sent over a secure channel. No replay cache entry is used in this case. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The \sphinxstyleemphasis{rdata\_out} argument is required if the KRB5\_AUTH\_CONTEXT\_RET\_TIME or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE flag is set in \sphinxstyleemphasis{auth\_context} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_mk\_priv \sphinxhyphen{} Format a KRB\sphinxhyphen{}PRIV message.} \label{\detokenize{appdev/refs/api/krb5_mk_priv:krb5-mk-priv-format-a-krb-priv-message}}\label{\detokenize{appdev/refs/api/krb5_mk_priv::doc}}\index{krb5\_mk\_priv (C function)@\spxentry{krb5\_mk\_priv}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_mk_priv:c.krb5_mk_priv}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_priv}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{userdata}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{der\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rdata\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{userdata} \sphinxhyphen{} User data for \sphinxstylestrong{KRB\sphinxhyphen{}PRIV} message \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{der\_out} \sphinxhyphen{} Formatted \sphinxstylestrong{KRB\sphinxhyphen{}PRIV} message \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rdata\_out} \sphinxhyphen{} Replay data (NULL if not needed) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function is similar to krb5\_mk\_safe(), but the message is encrypted and integrity\sphinxhyphen{}protected, not just integrity\sphinxhyphen{}protected. \sphinxAtStartPar The local address in \sphinxstyleemphasis{auth\_context} must be set, and is used to form the sender address used in the KRB\sphinxhyphen{}PRIV message. The remote address is optional; if specified, it will be used to form the receiver address used in the message. \sphinxAtStartPar If the KRB5\_AUTH\_CONTEXT\_DO\_TIME flag is set in \sphinxstyleemphasis{auth\_context} , a timestamp is included in the KRB\sphinxhyphen{}PRIV message, and an entry for the message is entered in an in\sphinxhyphen{}memory replay cache to detect if the message is reflected by an attacker. If KRB5\_AUTH\_CONTEXT\_DO\_TIME is not set, no replay cache is used. If KRB5\_AUTH\_CONTEXT\_RET\_TIME is set in \sphinxstyleemphasis{auth\_context} , a timestamp is included in the KRB\sphinxhyphen{}PRIV message and is stored in \sphinxstyleemphasis{rdata\_out} . \sphinxAtStartPar If either KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE is set, the \sphinxstyleemphasis{auth\_context} local sequence number is included in the KRB\sphinxhyphen{}PRIV message and then incremented. If KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE is set, the sequence number used is stored in \sphinxstyleemphasis{rdata\_out} . \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{der\_out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The \sphinxstyleemphasis{rdata\_out} argument is required if the KRB5\_AUTH\_CONTEXT\_RET\_TIME or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE flag is set in \sphinxstyleemphasis{auth\_context} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_mk\_rep \sphinxhyphen{} Format and encrypt a KRB\_AP\_REP message.} \label{\detokenize{appdev/refs/api/krb5_mk_rep:krb5-mk-rep-format-and-encrypt-a-krb-ap-rep-message}}\label{\detokenize{appdev/refs/api/krb5_mk_rep::doc}}\index{krb5\_mk\_rep (C function)@\spxentry{krb5\_mk\_rep}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_mk_rep:c.krb5_mk_rep}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_rep}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{outbuf}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outbuf} \sphinxhyphen{} \sphinxstylestrong{AP\sphinxhyphen{}REP} message \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function fills in \sphinxstyleemphasis{outbuf} with an AP\sphinxhyphen{}REP message using information from \sphinxstyleemphasis{auth\_context} . \sphinxAtStartPar If the flags in \sphinxstyleemphasis{auth\_context} indicate that a sequence number should be used (either KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE) and the local sequence number in \sphinxstyleemphasis{auth\_context} is 0, a new number will be generated with krb5\_generate\_seq\_number(). \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{outbuf} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_mk\_rep\_dce \sphinxhyphen{} Format and encrypt a KRB\_AP\_REP message for DCE RPC.} \label{\detokenize{appdev/refs/api/krb5_mk_rep_dce:krb5-mk-rep-dce-format-and-encrypt-a-krb-ap-rep-message-for-dce-rpc}}\label{\detokenize{appdev/refs/api/krb5_mk_rep_dce::doc}}\index{krb5\_mk\_rep\_dce (C function)@\spxentry{krb5\_mk\_rep\_dce}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_mk_rep_dce:c.krb5_mk_rep_dce}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_rep\_dce}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{outbuf}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outbuf} \sphinxhyphen{} \sphinxstylestrong{AP\sphinxhyphen{}REP} message \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{outbuf} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_mk\_req \sphinxhyphen{} Create a KRB\_AP\_REQ message.} \label{\detokenize{appdev/refs/api/krb5_mk_req:krb5-mk-req-create-a-krb-ap-req-message}}\label{\detokenize{appdev/refs/api/krb5_mk_req::doc}}\index{krb5\_mk\_req (C function)@\spxentry{krb5\_mk\_req}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_mk_req:c.krb5_mk_req}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_req}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{ap\_req\_options}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{service}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{hostname}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{outbuf}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Pre\sphinxhyphen{}existing or newly created auth context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ap\_req\_options} \sphinxhyphen{} Options (see AP\_OPTS macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{service} \sphinxhyphen{} Service name, or NULL to use \sphinxstylestrong{“hostâ€} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{hostname} \sphinxhyphen{} Host name, or NULL to use local hostname \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_data} \sphinxhyphen{} Application data to be checksummed in the authenticator, or NULL \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache used to obtain credentials for the desired service. \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outbuf} \sphinxhyphen{} \sphinxstylestrong{AP\sphinxhyphen{}REQ} message \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function is similar to krb5\_mk\_req\_extended() except that it uses a given \sphinxstyleemphasis{hostname} , \sphinxstyleemphasis{service} , and \sphinxstyleemphasis{ccache} to construct a service principal name and obtain credentials. \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{outbuf} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_mk\_req\_extended \sphinxhyphen{} Create a KRB\_AP\_REQ message using supplied credentials.} \label{\detokenize{appdev/refs/api/krb5_mk_req_extended:krb5-mk-req-extended-create-a-krb-ap-req-message-using-supplied-credentials}}\label{\detokenize{appdev/refs/api/krb5_mk_req_extended::doc}}\index{krb5\_mk\_req\_extended (C function)@\spxentry{krb5\_mk\_req\_extended}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_mk_req_extended:c.krb5_mk_req_extended}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_req\_extended}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{ap\_req\_options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{outbuf}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Pre\sphinxhyphen{}existing or newly created auth context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ap\_req\_options} \sphinxhyphen{} Options (see AP\_OPTS macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_data} \sphinxhyphen{} Application data to be checksummed in the authenticator, or NULL \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_creds} \sphinxhyphen{} Credentials for the service with valid ticket and key \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{outbuf} \sphinxhyphen{} \sphinxstylestrong{AP\sphinxhyphen{}REQ} message \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Valid \sphinxstyleemphasis{ap\_req\_options} are: \begin{quote} \begin{itemize} \item {} \sphinxAtStartPar AP\_OPTS\_USE\_SESSION\_KEY \sphinxhyphen{} Use the session key when creating the request used for user to user authentication. \item {} \sphinxAtStartPar AP\_OPTS\_MUTUAL\_REQUIRED \sphinxhyphen{} Request a mutual authentication packet from the receiver. \item {} \sphinxAtStartPar AP\_OPTS\_USE\_SUBKEY \sphinxhyphen{} Generate a subsession key from the current session key obtained from the credentials. \end{itemize} \sphinxAtStartPar This function creates a KRB\_AP\_REQ message using supplied credentials \sphinxstyleemphasis{in\_creds} . \sphinxstyleemphasis{auth\_context} may point to an existing auth context or to NULL, in which case a new one will be created. If \sphinxstyleemphasis{in\_data} is non\sphinxhyphen{}null, a checksum of it will be included in the authenticator contained in the KRB\_AP\_REQ message. Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{outbuf} when it is no longer needed. \end{quote} \sphinxAtStartPar On successful return, the authenticator is stored in \sphinxstyleemphasis{auth\_context} with the \sphinxstyleemphasis{client} and \sphinxstyleemphasis{checksum} fields nulled out. (This is to prevent pointer\sphinxhyphen{}sharing problems; the caller should not need these fields anyway, since the caller supplied them.) \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_mk\_req() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_mk\_safe \sphinxhyphen{} Format a KRB\sphinxhyphen{}SAFE message.} \label{\detokenize{appdev/refs/api/krb5_mk_safe:krb5-mk-safe-format-a-krb-safe-message}}\label{\detokenize{appdev/refs/api/krb5_mk_safe::doc}}\index{krb5\_mk\_safe (C function)@\spxentry{krb5\_mk\_safe}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_mk_safe:c.krb5_mk_safe}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_safe}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{userdata}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{der\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rdata\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{userdata} \sphinxhyphen{} User data in the message \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{der\_out} \sphinxhyphen{} Formatted \sphinxstylestrong{KRB\sphinxhyphen{}SAFE} buffer \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rdata\_out} \sphinxhyphen{} Replay data. Specify NULL if not needed \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function creates an integrity protected \sphinxstylestrong{KRB\sphinxhyphen{}SAFE} message using data supplied by the application. \sphinxAtStartPar Fields in \sphinxstyleemphasis{auth\_context} specify the checksum type, the keyblock that can be used to seed the checksum, full addresses (host and port) for the sender and receiver, and KRB5\_AUTH\_CONTEXT flags. \sphinxAtStartPar The local address in \sphinxstyleemphasis{auth\_context} must be set, and is used to form the sender address used in the KRB\sphinxhyphen{}SAFE message. The remote address is optional; if specified, it will be used to form the receiver address used in the message. \sphinxAtStartPar If the KRB5\_AUTH\_CONTEXT\_DO\_TIME flag is set in \sphinxstyleemphasis{auth\_context} , a timestamp is included in the KRB\sphinxhyphen{}SAFE message, and an entry for the message is entered in an in\sphinxhyphen{}memory replay cache to detect if the message is reflected by an attacker. If KRB5\_AUTH\_CONTEXT\_DO\_TIME is not set, no replay cache is used. If KRB5\_AUTH\_CONTEXT\_RET\_TIME is set in \sphinxstyleemphasis{auth\_context} , a timestamp is included in the KRB\sphinxhyphen{}SAFE message and is stored in \sphinxstyleemphasis{rdata\_out} . \sphinxAtStartPar If either KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE is set, the \sphinxstyleemphasis{auth\_context} local sequence number is included in the KRB\sphinxhyphen{}SAFE message and then incremented. If KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE is set, the sequence number used is stored in \sphinxstyleemphasis{rdata\_out} . \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{der\_out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The \sphinxstyleemphasis{rdata\_out} argument is required if the KRB5\_AUTH\_CONTEXT\_RET\_TIME or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE flag is set in \sphinxstyleemphasis{auth\_context} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_os\_localaddr \sphinxhyphen{} Return all interface addresses for this host.} \label{\detokenize{appdev/refs/api/krb5_os_localaddr:krb5-os-localaddr-return-all-interface-addresses-for-this-host}}\label{\detokenize{appdev/refs/api/krb5_os_localaddr::doc}}\index{krb5\_os\_localaddr (C function)@\spxentry{krb5\_os\_localaddr}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_os_localaddr:c.krb5_os_localaddr}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_os\_localaddr}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{addr}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{addr} \sphinxhyphen{} Array of krb5\_address pointers, ending with NULL \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_free\_addresses() to free \sphinxstyleemphasis{addr} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_pac\_add\_buffer \sphinxhyphen{} Add a buffer to a PAC handle.} \label{\detokenize{appdev/refs/api/krb5_pac_add_buffer:krb5-pac-add-buffer-add-a-buffer-to-a-pac-handle}}\label{\detokenize{appdev/refs/api/krb5_pac_add_buffer::doc}}\index{krb5\_pac\_add\_buffer (C function)@\spxentry{krb5\_pac\_add\_buffer}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_add_buffer:c.krb5_pac_add_buffer}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_add\_buffer}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ui_4:c.krb5_ui_4}]{\sphinxcrossref{\DUrole{n}{krb5\_ui\_4}}}}\DUrole{w}{ }\DUrole{n}{type}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pac} \sphinxhyphen{} PAC handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{type} \sphinxhyphen{} Buffer type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} contents \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function adds a buffer of type \sphinxstyleemphasis{type} and contents \sphinxstyleemphasis{data} to \sphinxstyleemphasis{pac} if there isn’t already a buffer of this type present. \sphinxAtStartPar The valid values of \sphinxstyleemphasis{type} is one of the following: \begin{itemize} \item {} \sphinxAtStartPar KRB5\_PAC\_LOGON\_INFO \sphinxhyphen{} Logon information \item {} \sphinxAtStartPar KRB5\_PAC\_CREDENTIALS\_INFO \sphinxhyphen{} Credentials information \item {} \sphinxAtStartPar KRB5\_PAC\_SERVER\_CHECKSUM \sphinxhyphen{} Server checksum \item {} \sphinxAtStartPar KRB5\_PAC\_PRIVSVR\_CHECKSUM \sphinxhyphen{} KDC checksum \item {} \sphinxAtStartPar KRB5\_PAC\_CLIENT\_INFO \sphinxhyphen{} Client name and ticket information \item {} \sphinxAtStartPar KRB5\_PAC\_DELEGATION\_INFO \sphinxhyphen{} Constrained delegation information \item {} \sphinxAtStartPar KRB5\_PAC\_UPN\_DNS\_INFO \sphinxhyphen{} User principal name and DNS information \end{itemize} \sphinxstepscope \subsubsection{krb5\_pac\_free \sphinxhyphen{} Free a PAC handle.} \label{\detokenize{appdev/refs/api/krb5_pac_free:krb5-pac-free-free-a-pac-handle}}\label{\detokenize{appdev/refs/api/krb5_pac_free::doc}}\index{krb5\_pac\_free (C function)@\spxentry{krb5\_pac\_free}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_free:c.krb5_pac_free}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_free}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pac} \sphinxhyphen{} PAC to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{pac} and the structure itself. \sphinxstepscope \subsubsection{krb5\_pac\_get\_buffer \sphinxhyphen{} Retrieve a buffer value from a PAC.} \label{\detokenize{appdev/refs/api/krb5_pac_get_buffer:krb5-pac-get-buffer-retrieve-a-buffer-value-from-a-pac}}\label{\detokenize{appdev/refs/api/krb5_pac_get_buffer::doc}}\index{krb5\_pac\_get\_buffer (C function)@\spxentry{krb5\_pac\_get\_buffer}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_get_buffer:c.krb5_pac_get_buffer}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_get\_buffer}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ui_4:c.krb5_ui_4}]{\sphinxcrossref{\DUrole{n}{krb5\_ui\_4}}}}\DUrole{w}{ }\DUrole{n}{type}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pac} \sphinxhyphen{} PAC handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{type} \sphinxhyphen{} Type of buffer to retrieve \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{data} \sphinxhyphen{} Buffer value \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{data} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_pac\_get\_types \sphinxhyphen{} Return an array of buffer types in a PAC handle.} \label{\detokenize{appdev/refs/api/krb5_pac_get_types:krb5-pac-get-types-return-an-array-of-buffer-types-in-a-pac-handle}}\label{\detokenize{appdev/refs/api/krb5_pac_get_types::doc}}\index{krb5\_pac\_get\_types (C function)@\spxentry{krb5\_pac\_get\_types}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_get_types:c.krb5_pac_get_types}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_get\_types}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{len}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ui_4:c.krb5_ui_4}]{\sphinxcrossref{\DUrole{n}{krb5\_ui\_4}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{types}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pac} \sphinxhyphen{} PAC handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{len} \sphinxhyphen{} Number of entries in \sphinxstyleemphasis{types} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{types} \sphinxhyphen{} Array of buffer types \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_pac\_init \sphinxhyphen{} Create an empty Privilege Attribute Certificate (PAC) handle.} \label{\detokenize{appdev/refs/api/krb5_pac_init:krb5-pac-init-create-an-empty-privilege-attribute-certificate-pac-handle}}\label{\detokenize{appdev/refs/api/krb5_pac_init::doc}}\index{krb5\_pac\_init (C function)@\spxentry{krb5\_pac\_init}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_init:c.krb5_pac_init}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_init}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pac}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{pac} \sphinxhyphen{} New PAC handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_pac\_free() to free \sphinxstyleemphasis{pac} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_pac\_parse \sphinxhyphen{} Unparse an encoded PAC into a new handle.} \label{\detokenize{appdev/refs/api/krb5_pac_parse:krb5-pac-parse-unparse-an-encoded-pac-into-a-new-handle}}\label{\detokenize{appdev/refs/api/krb5_pac_parse::doc}}\index{krb5\_pac\_parse (C function)@\spxentry{krb5\_pac\_parse}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_parse:c.krb5_pac_parse}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_parse}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ptr}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{len}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pac}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ptr} \sphinxhyphen{} PAC buffer \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{len} \sphinxhyphen{} Length of \sphinxstyleemphasis{ptr} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{pac} \sphinxhyphen{} PAC handle \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_pac\_free() to free \sphinxstyleemphasis{pac} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_pac\_sign} \label{\detokenize{appdev/refs/api/krb5_pac_sign:krb5-pac-sign}}\label{\detokenize{appdev/refs/api/krb5_pac_sign::doc}}\index{krb5\_pac\_sign (C function)@\spxentry{krb5\_pac\_sign}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_sign:c.krb5_pac_sign}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_sign}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{n}{authtime}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{server\_key}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{privsvr\_key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{pac} \sphinxAtStartPar \sphinxstylestrong{authtime} \sphinxAtStartPar \sphinxstylestrong{principal} \sphinxAtStartPar \sphinxstylestrong{server\_key} \sphinxAtStartPar \sphinxstylestrong{privsvr\_key} \sphinxAtStartPar \sphinxstylestrong{data} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Use krb5\_kdc\_sign\_ticket() instead. \sphinxstepscope \subsubsection{krb5\_pac\_sign\_ext} \label{\detokenize{appdev/refs/api/krb5_pac_sign_ext:krb5-pac-sign-ext}}\label{\detokenize{appdev/refs/api/krb5_pac_sign_ext::doc}}\index{krb5\_pac\_sign\_ext (C function)@\spxentry{krb5\_pac\_sign\_ext}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_sign_ext:c.krb5_pac_sign_ext}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_sign\_ext}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{n}{authtime}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{server\_key}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{privsvr\_key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{n}{with\_realm}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{pac} \sphinxAtStartPar \sphinxstylestrong{authtime} \sphinxAtStartPar \sphinxstylestrong{principal} \sphinxAtStartPar \sphinxstylestrong{server\_key} \sphinxAtStartPar \sphinxstylestrong{privsvr\_key} \sphinxAtStartPar \sphinxstylestrong{with\_realm} \sphinxAtStartPar \sphinxstylestrong{data} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Use krb5\_kdc\_sign\_ticket() instead. \sphinxstepscope \subsubsection{krb5\_pac\_verify \sphinxhyphen{} Verify a PAC.} \label{\detokenize{appdev/refs/api/krb5_pac_verify:krb5-pac-verify-verify-a-pac}}\label{\detokenize{appdev/refs/api/krb5_pac_verify::doc}}\index{krb5\_pac\_verify (C function)@\spxentry{krb5\_pac\_verify}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_verify:c.krb5_pac_verify}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_verify}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{n}{authtime}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{server}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{privsvr}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pac} \sphinxhyphen{} PAC handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{authtime} \sphinxhyphen{} Expected timestamp \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Expected principal name (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Key to validate server checksum (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{privsvr} \sphinxhyphen{} Key to validate KDC checksum (or NULL) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function validates \sphinxstyleemphasis{pac} against the supplied \sphinxstyleemphasis{server} , \sphinxstyleemphasis{privsvr} , \sphinxstyleemphasis{principal} and \sphinxstyleemphasis{authtime} . If \sphinxstyleemphasis{principal} is NULL, the principal and authtime are not verified. If \sphinxstyleemphasis{server} or \sphinxstyleemphasis{privsvr} is NULL, the corresponding checksum is not verified. \sphinxAtStartPar If successful, \sphinxstyleemphasis{pac} is marked as verified. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar A checksum mismatch can occur if the PAC was copied from a cross\sphinxhyphen{}realm TGT by an ignorant KDC; also macOS Server Open Directory (as of 10.6) generates PACs with no server checksum at all. One should consider not failing the whole authentication because of this reason, but, instead, treating the ticket as if it did not contain a PAC or marking the PAC information as non\sphinxhyphen{}verified. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_pac\_verify\_ext \sphinxhyphen{} Verify a PAC, possibly from a specified realm.} \label{\detokenize{appdev/refs/api/krb5_pac_verify_ext:krb5-pac-verify-ext-verify-a-pac-possibly-from-a-specified-realm}}\label{\detokenize{appdev/refs/api/krb5_pac_verify_ext::doc}}\index{krb5\_pac\_verify\_ext (C function)@\spxentry{krb5\_pac\_verify\_ext}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_verify_ext:c.krb5_pac_verify_ext}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_verify\_ext}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{n}{authtime}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{principal}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{server}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{privsvr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{n}{with\_realm}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pac} \sphinxhyphen{} PAC handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{authtime} \sphinxhyphen{} Expected timestamp \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{principal} \sphinxhyphen{} Expected principal name (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Key to validate server checksum (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{privsvr} \sphinxhyphen{} Key to validate KDC checksum (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{with\_realm} \sphinxhyphen{} If true, expect the realm of \sphinxstyleemphasis{principal} \end{description}\end{quote} \sphinxAtStartPar This function is similar to krb5\_pac\_verify(), but adds a parameter \sphinxstyleemphasis{with\_realm} . If \sphinxstyleemphasis{with\_realm} is true, the PAC\_CLIENT\_INFO field is expected to include the realm of \sphinxstyleemphasis{principal} as well as the name. This flag is necessary to verify PACs in cross\sphinxhyphen{}realm S4U2Self referral TGTs. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.17 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_pac\_get\_client\_info \sphinxhyphen{} Read client information from a PAC.} \label{\detokenize{appdev/refs/api/krb5_pac_get_client_info:krb5-pac-get-client-info-read-client-information-from-a-pac}}\label{\detokenize{appdev/refs/api/krb5_pac_get_client_info::doc}}\index{krb5\_pac\_get\_client\_info (C function)@\spxentry{krb5\_pac\_get\_client\_info}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_pac_get_client_info:c.krb5_pac_get_client_info}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac\_get\_client\_info}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}]{\sphinxcrossref{\DUrole{n}{krb5\_pac}}}}\DUrole{w}{ }\DUrole{n}{pac}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{authtime\_out}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{princname\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pac} \sphinxhyphen{} PAC handle \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{authtime\_out} \sphinxhyphen{} Authentication timestamp (NULL if not needed) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{princname\_out} \sphinxhyphen{} Client account name \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 on success, ENOENT if no PAC\_CLIENT\_INFO buffer is present in pac , ERANGE if the buffer contains invalid lengths. \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Read the PAC\_CLIENT\_INFO buffer in \sphinxstyleemphasis{pac} . Place the client account name as a string in \sphinxstyleemphasis{princname\_out} . If \sphinxstyleemphasis{authtime\_out} is not NULL, place the initial authentication timestamp in \sphinxstyleemphasis{authtime\_out} . \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.18 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_prepend\_error\_message \sphinxhyphen{} Add a prefix to the message for an error code.} \label{\detokenize{appdev/refs/api/krb5_prepend_error_message:krb5-prepend-error-message-add-a-prefix-to-the-message-for-an-error-code}}\label{\detokenize{appdev/refs/api/krb5_prepend_error_message::doc}}\index{krb5\_prepend\_error\_message (C function)@\spxentry{krb5\_prepend\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_prepend_error_message:c.krb5_prepend_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_prepend\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\DUrole{n}{code}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{fmt}\sphinxparamcomma \DUrole{p}{...}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{code} \sphinxhyphen{} Error code \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fmt} \sphinxhyphen{} Format string for error message prefix \end{description}\end{quote} \sphinxAtStartPar Format a message and prepend it to the current message for \sphinxstyleemphasis{code} . The prefix will be separated from the old message with a colon and space. \sphinxstepscope \subsubsection{krb5\_principal2salt \sphinxhyphen{} Convert a principal name into the default salt for that principal.} \label{\detokenize{appdev/refs/api/krb5_principal2salt:krb5-principal2salt-convert-a-principal-name-into-the-default-salt-for-that-principal}}\label{\detokenize{appdev/refs/api/krb5_principal2salt::doc}}\index{krb5\_principal2salt (C function)@\spxentry{krb5\_principal2salt}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_principal2salt:c.krb5_principal2salt}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_principal2salt}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{pr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ret}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pr} \sphinxhyphen{} Principal name \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ret} \sphinxhyphen{} Default salt for \sphinxstyleemphasis{pr} to be filled in \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_rd\_cred \sphinxhyphen{} Read and validate a KRB\sphinxhyphen{}CRED message.} \label{\detokenize{appdev/refs/api/krb5_rd_cred:krb5-rd-cred-read-and-validate-a-krb-cred-message}}\label{\detokenize{appdev/refs/api/krb5_rd_cred::doc}}\index{krb5\_rd\_cred (C function)@\spxentry{krb5\_rd\_cred}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_rd_cred:c.krb5_rd_cred}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_rd\_cred}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creddata}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{creds\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rdata\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{creddata} \sphinxhyphen{} \sphinxstylestrong{KRB\sphinxhyphen{}CRED} message \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds\_out} \sphinxhyphen{} Null\sphinxhyphen{}terminated array of forwarded credentials \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rdata\_out} \sphinxhyphen{} Replay data (NULL if not needed) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{creddata} will be decrypted using the receiving subkey if it is present in \sphinxstyleemphasis{auth\_context} , or the session key if the receiving subkey is not present or fails to decrypt the message. \end{quote} \sphinxAtStartPar Use krb5\_free\_tgt\_creds() to free \sphinxstyleemphasis{creds\_out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The \sphinxstyleemphasis{rdata\_out} argument is required if the KRB5\_AUTH\_CONTEXT\_RET\_TIME or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE flag is set in \sphinxstyleemphasis{auth\_context} .\textasciigrave{} \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_rd\_error \sphinxhyphen{} Decode a KRB\sphinxhyphen{}ERROR message.} \label{\detokenize{appdev/refs/api/krb5_rd_error:krb5-rd-error-decode-a-krb-error-message}}\label{\detokenize{appdev/refs/api/krb5_rd_error::doc}}\index{krb5\_rd\_error (C function)@\spxentry{krb5\_rd\_error}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_rd_error:c.krb5_rd_error}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_rd\_error}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{enc\_errbuf}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{dec\_error}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enc\_errbuf} \sphinxhyphen{} Encoded error message \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{dec\_error} \sphinxhyphen{} Decoded error message \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function processes \sphinxstylestrong{KRB\sphinxhyphen{}ERROR} message \sphinxstyleemphasis{enc\_errbuf} and returns an allocated structure \sphinxstyleemphasis{dec\_error} containing the error message. Use krb5\_free\_error() to free \sphinxstyleemphasis{dec\_error} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_rd\_priv \sphinxhyphen{} Process a KRB\sphinxhyphen{}PRIV message.} \label{\detokenize{appdev/refs/api/krb5_rd_priv:krb5-rd-priv-process-a-krb-priv-message}}\label{\detokenize{appdev/refs/api/krb5_rd_priv::doc}}\index{krb5\_rd\_priv (C function)@\spxentry{krb5\_rd\_priv}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_rd_priv:c.krb5_rd_priv}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_rd\_priv}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{inbuf}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{userdata\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rdata\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inbuf} \sphinxhyphen{} \sphinxstylestrong{KRB\sphinxhyphen{}PRIV} message to be parsed \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{userdata\_out} \sphinxhyphen{} Data parsed from \sphinxstylestrong{KRB\sphinxhyphen{}PRIV} message \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rdata\_out} \sphinxhyphen{} Replay data. Specify NULL if not needed \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function parses a \sphinxstylestrong{KRB\sphinxhyphen{}PRIV} message, verifies its integrity, and stores its unencrypted data into \sphinxstyleemphasis{userdata\_out} . \sphinxAtStartPar If \sphinxstyleemphasis{auth\_context} has a remote address set, the address will be used to verify the sender address in the KRB\sphinxhyphen{}PRIV message. If \sphinxstyleemphasis{auth\_context} has a local address set, it will be used to verify the receiver address in the KRB\sphinxhyphen{}PRIV message if the message contains one. \sphinxAtStartPar If the KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE flag is set in \sphinxstyleemphasis{auth\_context} , the sequence number of the KRB\sphinxhyphen{}PRIV message is checked against the remote sequence number field of \sphinxstyleemphasis{auth\_context} . Otherwise, the sequence number is not used. \sphinxAtStartPar If the KRB5\_AUTH\_CONTEXT\_DO\_TIME flag is set in \sphinxstyleemphasis{auth\_context} , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in\sphinxhyphen{}memory replay cache to detect reflections or replays. \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{userdata\_out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The \sphinxstyleemphasis{rdata\_out} argument is required if the KRB5\_AUTH\_CONTEXT\_RET\_TIME or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE flag is set in \sphinxstyleemphasis{auth\_context} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_rd\_rep \sphinxhyphen{} Parse and decrypt a KRB\_AP\_REP message.} \label{\detokenize{appdev/refs/api/krb5_rd_rep:krb5-rd-rep-parse-and-decrypt-a-krb-ap-rep-message}}\label{\detokenize{appdev/refs/api/krb5_rd_rep::doc}}\index{krb5\_rd\_rep (C function)@\spxentry{krb5\_rd\_rep}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_rd_rep:c.krb5_rd_rep}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_rd\_rep}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{inbuf}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep\_enc\_part}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{repl}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inbuf} \sphinxhyphen{} AP\sphinxhyphen{}REP message \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{repl} \sphinxhyphen{} Decrypted reply message \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function parses, decrypts and verifies a message from \sphinxstyleemphasis{inbuf} and fills in \sphinxstyleemphasis{repl} with a pointer to allocated memory containing the fields from the encrypted response. \sphinxAtStartPar Use krb5\_free\_ap\_rep\_enc\_part() to free \sphinxstyleemphasis{repl} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_rd\_rep\_dce \sphinxhyphen{} Parse and decrypt a KRB\_AP\_REP message for DCE RPC.} \label{\detokenize{appdev/refs/api/krb5_rd_rep_dce:krb5-rd-rep-dce-parse-and-decrypt-a-krb-ap-rep-message-for-dce-rpc}}\label{\detokenize{appdev/refs/api/krb5_rd_rep_dce::doc}}\index{krb5\_rd\_rep\_dce (C function)@\spxentry{krb5\_rd\_rep\_dce}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_rd_rep_dce:c.krb5_rd_rep_dce}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_rd\_rep\_dce}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{inbuf}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ui_4:c.krb5_ui_4}]{\sphinxcrossref{\DUrole{n}{krb5\_ui\_4}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{nonce}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inbuf} \sphinxhyphen{} AP\sphinxhyphen{}REP message \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{nonce} \sphinxhyphen{} Sequence number from the decrypted reply \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function parses, decrypts and verifies a message from \sphinxstyleemphasis{inbuf} and fills in \sphinxstyleemphasis{nonce} with a decrypted reply sequence number. \sphinxstepscope \subsubsection{krb5\_rd\_req \sphinxhyphen{} Parse and decrypt a KRB\_AP\_REQ message.} \label{\detokenize{appdev/refs/api/krb5_rd_req:krb5-rd-req-parse-and-decrypt-a-krb-ap-req-message}}\label{\detokenize{appdev/refs/api/krb5_rd_req::doc}}\index{krb5\_rd\_req (C function)@\spxentry{krb5\_rd\_req}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_rd_req:c.krb5_rd_req}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_rd\_req}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{auth\_context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{inbuf}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{w}{ }\DUrole{n}{server}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ap\_req\_options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ticket}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Pre\sphinxhyphen{}existing or newly created auth context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inbuf} \sphinxhyphen{} AP\sphinxhyphen{}REQ message to be parsed \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Matching principal for server, or NULL to allow any principal in keytab \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table, or NULL to use the default \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ap\_req\_options} \sphinxhyphen{} If non\sphinxhyphen{}null, the AP\sphinxhyphen{}REQ flags on output \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ticket} \sphinxhyphen{} If non\sphinxhyphen{}null, ticket from the AP\sphinxhyphen{}REQ message \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function parses, decrypts and verifies a AP\sphinxhyphen{}REQ message from \sphinxstyleemphasis{inbuf} and stores the authenticator in \sphinxstyleemphasis{auth\_context} . \sphinxAtStartPar If a keyblock was specified in \sphinxstyleemphasis{auth\_context} using krb5\_auth\_con\_setuseruserkey(), that key is used to decrypt the ticket in AP\sphinxhyphen{}REQ message and \sphinxstyleemphasis{keytab} is ignored. In this case, \sphinxstyleemphasis{server} should be specified as a complete principal name to allow for proper transited\sphinxhyphen{}path checking and replay cache selection. \sphinxAtStartPar Otherwise, the decryption key is obtained from \sphinxstyleemphasis{keytab} , or from the default keytab if it is NULL. In this case, \sphinxstyleemphasis{server} may be a complete principal name, a matching principal (see krb5\_sname\_match()), or NULL to match any principal name. The keys tried against the encrypted part of the ticket are determined as follows: \begin{itemize} \item {} \sphinxAtStartPar If \sphinxstyleemphasis{server} is a complete principal name, then its entry in \sphinxstyleemphasis{keytab} is tried. \item {} \sphinxAtStartPar Otherwise, if \sphinxstyleemphasis{keytab} is iterable, then all entries in \sphinxstyleemphasis{keytab} which match \sphinxstyleemphasis{server} are tried. \item {} \sphinxAtStartPar Otherwise, the server principal in the ticket must match \sphinxstyleemphasis{server} , and its entry in \sphinxstyleemphasis{keytab} is tried. \end{itemize} \sphinxAtStartPar The client specified in the decrypted authenticator must match the client specified in the decrypted ticket. \sphinxAtStartPar If the \sphinxstyleemphasis{remote\_addr} field of \sphinxstyleemphasis{auth\_context} is set, the request must come from that address. \sphinxAtStartPar If a replay cache handle is provided in the \sphinxstyleemphasis{auth\_context} , the authenticator and ticket are verified against it. If no conflict is found, the new authenticator is then stored in the replay cache of \sphinxstyleemphasis{auth\_context} . \sphinxAtStartPar Various other checks are performed on the decoded data, including cross\sphinxhyphen{}realm policy, clockskew, and ticket validation times. \sphinxAtStartPar On success the authenticator, subkey, and remote sequence number of the request are stored in \sphinxstyleemphasis{auth\_context} . If the AP\_OPTS\_MUTUAL\_REQUIRED bit is set, the local sequence number is XORed with the remote sequence number in the request. \sphinxAtStartPar Use krb5\_free\_ticket() to free \sphinxstyleemphasis{ticket} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_rd\_safe \sphinxhyphen{} Process KRB\sphinxhyphen{}SAFE message.} \label{\detokenize{appdev/refs/api/krb5_rd_safe:krb5-rd-safe-process-krb-safe-message}}\label{\detokenize{appdev/refs/api/krb5_rd_safe::doc}}\index{krb5\_rd\_safe (C function)@\spxentry{krb5\_rd\_safe}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_rd_safe:c.krb5_rd_safe}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_rd\_safe}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{inbuf}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{userdata\_out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{rdata\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inbuf} \sphinxhyphen{} \sphinxstylestrong{KRB\sphinxhyphen{}SAFE} message to be parsed \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{userdata\_out} \sphinxhyphen{} Data parsed from \sphinxstylestrong{KRB\sphinxhyphen{}SAFE} message \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rdata\_out} \sphinxhyphen{} Replay data. Specify NULL if not needed \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function parses a \sphinxstylestrong{KRB\sphinxhyphen{}SAFE} message, verifies its integrity, and stores its data into \sphinxstyleemphasis{userdata\_out} . \sphinxAtStartPar If \sphinxstyleemphasis{auth\_context} has a remote address set, the address will be used to verify the sender address in the KRB\sphinxhyphen{}SAFE message. If \sphinxstyleemphasis{auth\_context} has a local address set, it will be used to verify the receiver address in the KRB\sphinxhyphen{}SAFE message if the message contains one. \sphinxAtStartPar If the KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE flag is set in \sphinxstyleemphasis{auth\_context} , the sequence number of the KRB\sphinxhyphen{}SAFE message is checked against the remote sequence number field of \sphinxstyleemphasis{auth\_context} . Otherwise, the sequence number is not used. \sphinxAtStartPar If the KRB5\_AUTH\_CONTEXT\_DO\_TIME flag is set in \sphinxstyleemphasis{auth\_context} , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in\sphinxhyphen{}memory replay cache to detect reflections or replays. \sphinxAtStartPar Use krb5\_free\_data\_contents() to free \sphinxstyleemphasis{userdata\_out} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The \sphinxstyleemphasis{rdata\_out} argument is required if the KRB5\_AUTH\_CONTEXT\_RET\_TIME or KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE flag is set in \sphinxstyleemphasis{auth\_context} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_read\_password \sphinxhyphen{} Read a password from keyboard input.} \label{\detokenize{appdev/refs/api/krb5_read_password:krb5-read-password-read-a-password-from-keyboard-input}}\label{\detokenize{appdev/refs/api/krb5_read_password::doc}}\index{krb5\_read\_password (C function)@\spxentry{krb5\_read\_password}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_read_password:c.krb5_read_password}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_read\_password}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{prompt}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{prompt2}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{return\_pwd}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{size\_return}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{prompt} \sphinxhyphen{} First user prompt when reading password \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{prompt2} \sphinxhyphen{} Second user prompt (NULL to prompt only once) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{return\_pwd} \sphinxhyphen{} Returned password \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{size\_return} \sphinxhyphen{} On input, maximum size of password; on output, size of password read \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Error in reading or verifying the password \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function reads a password from keyboard input and stores it in \sphinxstyleemphasis{return\_pwd} . \sphinxstyleemphasis{size\_return} should be set by the caller to the amount of storage space available in \sphinxstyleemphasis{return\_pwd} ; on successful return, it will be set to the length of the password read. \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{prompt} is printed to the terminal, followed byâ€:â€, and then a password is read from the keyboard. \end{quote} \sphinxAtStartPar If \sphinxstyleemphasis{prompt2} is NULL, the password is read only once. Otherwise, \sphinxstyleemphasis{prompt2} is printed to the terminal and a second password is read. If the two passwords entered are not identical, KRB5\_LIBOS\_BADPWDMATCH is returned. \sphinxAtStartPar Echoing is turned off when the password is read. \sphinxstepscope \subsubsection{krb5\_salttype\_to\_string \sphinxhyphen{} Convert a salt type to a string.} \label{\detokenize{appdev/refs/api/krb5_salttype_to_string:krb5-salttype-to-string-convert-a-salt-type-to-a-string}}\label{\detokenize{appdev/refs/api/krb5_salttype_to_string::doc}}\index{krb5\_salttype\_to\_string (C function)@\spxentry{krb5\_salttype\_to\_string}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_salttype_to_string:c.krb5_salttype_to_string}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_salttype\_to\_string}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{n}{salttype}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{buffer}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{buflen}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{salttype} \sphinxhyphen{} Salttype to convert \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{buffer} \sphinxhyphen{} Buffer to receive the converted string \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{buflen} \sphinxhyphen{} Storage available in \sphinxstyleemphasis{buffer} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_server\_decrypt\_ticket\_keytab \sphinxhyphen{} Decrypt a ticket using the specified key table.} \label{\detokenize{appdev/refs/api/krb5_server_decrypt_ticket_keytab:krb5-server-decrypt-ticket-keytab-decrypt-a-ticket-using-the-specified-key-table}}\label{\detokenize{appdev/refs/api/krb5_server_decrypt_ticket_keytab::doc}}\index{krb5\_server\_decrypt\_ticket\_keytab (C function)@\spxentry{krb5\_server\_decrypt\_ticket\_keytab}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_server_decrypt_ticket_keytab:c.krb5_server_decrypt_ticket_keytab}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_server\_decrypt\_ticket\_keytab}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{kt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ticket}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{kt} \sphinxhyphen{} Key table \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ticket} \sphinxhyphen{} Ticket to be decrypted \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function takes a \sphinxstyleemphasis{ticket} as input and decrypts it using key data from \sphinxstyleemphasis{kt} . The result is placed into \sphinxstyleemphasis{ticket\sphinxhyphen{}\textgreater{}enc\_part2} . \sphinxstepscope \subsubsection{krb5\_set\_default\_tgs\_enctypes \sphinxhyphen{} Set default TGS encryption types in a krb5\_context structure.} \label{\detokenize{appdev/refs/api/krb5_set_default_tgs_enctypes:krb5-set-default-tgs-enctypes-set-default-tgs-encryption-types-in-a-krb5-context-structure}}\label{\detokenize{appdev/refs/api/krb5_set_default_tgs_enctypes::doc}}\index{krb5\_set\_default\_tgs\_enctypes (C function)@\spxentry{krb5\_set\_default\_tgs\_enctypes}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_default_tgs_enctypes:c.krb5_set_default_tgs_enctypes}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_default\_tgs\_enctypes}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{etypes}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{etypes} \sphinxhyphen{} Encryption type(s) to set \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \item {} \sphinxAtStartPar KRB5\_PROG\_ETYPE\_NOSUPP Program lacks support for encryption type \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets the default enctype list for TGS requests made using \sphinxstyleemphasis{context} to \sphinxstyleemphasis{etypes} . \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This overrides the default list (from config file or built\sphinxhyphen{}in). \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_set\_error\_message \sphinxhyphen{} Set an extended error message for an error code.} \label{\detokenize{appdev/refs/api/krb5_set_error_message:krb5-set-error-message-set-an-extended-error-message-for-an-error-code}}\label{\detokenize{appdev/refs/api/krb5_set_error_message::doc}}\index{krb5\_set\_error\_message (C function)@\spxentry{krb5\_set\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_error_message:c.krb5_set_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\DUrole{n}{code}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{fmt}\sphinxparamcomma \DUrole{p}{...}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{code} \sphinxhyphen{} Error code \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fmt} \sphinxhyphen{} Error string for the error code \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_set\_kdc\_recv\_hook \sphinxhyphen{} Set a KDC post\sphinxhyphen{}receive hook function.} \label{\detokenize{appdev/refs/api/krb5_set_kdc_recv_hook:krb5-set-kdc-recv-hook-set-a-kdc-post-receive-hook-function}}\label{\detokenize{appdev/refs/api/krb5_set_kdc_recv_hook::doc}}\index{krb5\_set\_kdc\_recv\_hook (C function)@\spxentry{krb5\_set\_kdc\_recv\_hook}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_kdc_recv_hook:c.krb5_set_kdc_recv_hook}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_kdc\_recv\_hook}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_post_recv_fn:c.krb5_post_recv_fn}]{\sphinxcrossref{\DUrole{n}{krb5\_post\_recv\_fn}}}}\DUrole{w}{ }\DUrole{n}{recv\_hook}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} The library context. \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{recv\_hook} \sphinxhyphen{} Hook function (or NULL to disable the hook) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Callback data to be passed to \sphinxstyleemphasis{recv\_hook} \end{description}\end{quote} \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{recv\_hook} will be called after a reply is received from a KDC during a call to a library function such as krb5\_get\_credentials(). The hook function may inspect or override the reply. This hook will not be executed if the pre\sphinxhyphen{}send hook returns a synthetic reply. \end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.15 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_set\_kdc\_send\_hook \sphinxhyphen{} Set a KDC pre\sphinxhyphen{}send hook function.} \label{\detokenize{appdev/refs/api/krb5_set_kdc_send_hook:krb5-set-kdc-send-hook-set-a-kdc-pre-send-hook-function}}\label{\detokenize{appdev/refs/api/krb5_set_kdc_send_hook::doc}}\index{krb5\_set\_kdc\_send\_hook (C function)@\spxentry{krb5\_set\_kdc\_send\_hook}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_kdc_send_hook:c.krb5_set_kdc_send_hook}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_kdc\_send\_hook}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pre_send_fn:c.krb5_pre_send_fn}]{\sphinxcrossref{\DUrole{n}{krb5\_pre\_send\_fn}}}}\DUrole{w}{ }\DUrole{n}{send\_hook}\sphinxparamcomma \DUrole{kt}{void}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{send\_hook} \sphinxhyphen{} Hook function (or NULL to disable the hook) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Callback data to be passed to \sphinxstyleemphasis{send\_hook} \end{description}\end{quote} \begin{quote} \sphinxAtStartPar \sphinxstyleemphasis{send\_hook} will be called before messages are sent to KDCs by library functions such as krb5\_get\_credentials(). The hook function may inspect, override, or synthesize its own reply to the message. \end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.15 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_set\_real\_time \sphinxhyphen{} Set time offset field in a krb5\_context structure.} \label{\detokenize{appdev/refs/api/krb5_set_real_time:krb5-set-real-time-set-time-offset-field-in-a-krb5-context-structure}}\label{\detokenize{appdev/refs/api/krb5_set_real_time::doc}}\index{krb5\_set\_real\_time (C function)@\spxentry{krb5\_set\_real\_time}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_set_real_time:c.krb5_set_real_time}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_set\_real\_time}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{n}{seconds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{n}{microseconds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{seconds} \sphinxhyphen{} Real time, seconds portion \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{microseconds} \sphinxhyphen{} Real time, microseconds portion \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function sets the time offset in \sphinxstyleemphasis{context} to the difference between the system time and the real time as determined by \sphinxstyleemphasis{seconds} and \sphinxstyleemphasis{microseconds} . \sphinxstepscope \subsubsection{krb5\_string\_to\_cksumtype \sphinxhyphen{} Convert a string to a checksum type.} \label{\detokenize{appdev/refs/api/krb5_string_to_cksumtype:krb5-string-to-cksumtype-convert-a-string-to-a-checksum-type}}\label{\detokenize{appdev/refs/api/krb5_string_to_cksumtype::doc}}\index{krb5\_string\_to\_cksumtype (C function)@\spxentry{krb5\_string\_to\_cksumtype}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_string_to_cksumtype:c.krb5_string_to_cksumtype}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_string\_to\_cksumtype}}}}{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{string}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cksumtypep}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{string} \sphinxhyphen{} String to be converted \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cksumtypep} \sphinxhyphen{} Checksum type to be filled in \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} EINVAL \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_string\_to\_deltat \sphinxhyphen{} Convert a string to a delta time value.} \label{\detokenize{appdev/refs/api/krb5_string_to_deltat:krb5-string-to-deltat-convert-a-string-to-a-delta-time-value}}\label{\detokenize{appdev/refs/api/krb5_string_to_deltat::doc}}\index{krb5\_string\_to\_deltat (C function)@\spxentry{krb5\_string\_to\_deltat}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_string_to_deltat:c.krb5_string_to_deltat}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_string\_to\_deltat}}}}{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{string}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}]{\sphinxcrossref{\DUrole{n}{krb5\_deltat}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{deltatp}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{string} \sphinxhyphen{} String to be converted \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{deltatp} \sphinxhyphen{} Delta time to be filled in \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} KRB5\_DELTAT\_BADFORMAT \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_string\_to\_enctype \sphinxhyphen{} Convert a string to an encryption type.} \label{\detokenize{appdev/refs/api/krb5_string_to_enctype:krb5-string-to-enctype-convert-a-string-to-an-encryption-type}}\label{\detokenize{appdev/refs/api/krb5_string_to_enctype::doc}}\index{krb5\_string\_to\_enctype (C function)@\spxentry{krb5\_string\_to\_enctype}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_string_to_enctype:c.krb5_string_to_enctype}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_string\_to\_enctype}}}}{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{string}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{enctypep}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{string} \sphinxhyphen{} String to convert to an encryption type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{enctypep} \sphinxhyphen{} Encryption type \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} EINVAL \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_string\_to\_salttype \sphinxhyphen{} Convert a string to a salt type.} \label{\detokenize{appdev/refs/api/krb5_string_to_salttype:krb5-string-to-salttype-convert-a-string-to-a-salt-type}}\label{\detokenize{appdev/refs/api/krb5_string_to_salttype::doc}}\index{krb5\_string\_to\_salttype (C function)@\spxentry{krb5\_string\_to\_salttype}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_string_to_salttype:c.krb5_string_to_salttype}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_string\_to\_salttype}}}}{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{string}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{salttypep}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{string} \sphinxhyphen{} String to convert to an encryption type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{salttypep} \sphinxhyphen{} Salt type to be filled in \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} EINVAL \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_string\_to\_timestamp \sphinxhyphen{} Convert a string to a timestamp.} \label{\detokenize{appdev/refs/api/krb5_string_to_timestamp:krb5-string-to-timestamp-convert-a-string-to-a-timestamp}}\label{\detokenize{appdev/refs/api/krb5_string_to_timestamp::doc}}\index{krb5\_string\_to\_timestamp (C function)@\spxentry{krb5\_string\_to\_timestamp}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_string_to_timestamp:c.krb5_string_to_timestamp}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_string\_to\_timestamp}}}}{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{string}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{timestampp}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{string} \sphinxhyphen{} String to be converted \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{timestampp} \sphinxhyphen{} Pointer to timestamp \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} EINVAL \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_timeofday \sphinxhyphen{} Retrieve the current time with context specific time offset adjustment.} \label{\detokenize{appdev/refs/api/krb5_timeofday:krb5-timeofday-retrieve-the-current-time-with-context-specific-time-offset-adjustment}}\label{\detokenize{appdev/refs/api/krb5_timeofday::doc}}\index{krb5\_timeofday (C function)@\spxentry{krb5\_timeofday}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_timeofday:c.krb5_timeofday}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_timeofday}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{timeret}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{timeret} \sphinxhyphen{} Timestamp to fill in \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success \end{itemize} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function retrieves the system time of day with the context specific time offset adjustment. \sphinxstepscope \subsubsection{krb5\_timestamp\_to\_sfstring \sphinxhyphen{} Convert a timestamp to a string, with optional output padding.} \label{\detokenize{appdev/refs/api/krb5_timestamp_to_sfstring:krb5-timestamp-to-sfstring-convert-a-timestamp-to-a-string-with-optional-output-padding}}\label{\detokenize{appdev/refs/api/krb5_timestamp_to_sfstring::doc}}\index{krb5\_timestamp\_to\_sfstring (C function)@\spxentry{krb5\_timestamp\_to\_sfstring}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_timestamp_to_sfstring:c.krb5_timestamp_to_sfstring}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_timestamp\_to\_sfstring}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{n}{timestamp}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{buffer}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{buflen}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pad}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{timestamp} \sphinxhyphen{} Timestamp to convert \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{buffer} \sphinxhyphen{} Buffer to hold the converted timestamp \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{buflen} \sphinxhyphen{} Length of buffer \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pad} \sphinxhyphen{} Optional value to pad \sphinxstyleemphasis{buffer} if converted timestamp does not fill it \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar If \sphinxstyleemphasis{pad} is not NULL, \sphinxstyleemphasis{buffer} is padded out to \sphinxstyleemphasis{buflen} \sphinxhyphen{} 1 characters with the value of * \sphinxstyleemphasis{pad} . \sphinxstepscope \subsubsection{krb5\_timestamp\_to\_string \sphinxhyphen{} Convert a timestamp to a string.} \label{\detokenize{appdev/refs/api/krb5_timestamp_to_string:krb5-timestamp-to-string-convert-a-timestamp-to-a-string}}\label{\detokenize{appdev/refs/api/krb5_timestamp_to_string::doc}}\index{krb5\_timestamp\_to\_string (C function)@\spxentry{krb5\_timestamp\_to\_string}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_timestamp_to_string:c.krb5_timestamp_to_string}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_timestamp\_to\_string}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\DUrole{n}{timestamp}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{buffer}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{buflen}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{timestamp} \sphinxhyphen{} Timestamp to convert \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{buffer} \sphinxhyphen{} Buffer to hold converted timestamp \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{buflen} \sphinxhyphen{} Storage available in \sphinxstyleemphasis{buffer} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar The string is returned in the locale’s appropriate date and time representation. \sphinxstepscope \subsubsection{krb5\_tkt\_creds\_free \sphinxhyphen{} Free a TGS request context.} \label{\detokenize{appdev/refs/api/krb5_tkt_creds_free:krb5-tkt-creds-free-free-a-tgs-request-context}}\label{\detokenize{appdev/refs/api/krb5_tkt_creds_free::doc}}\index{krb5\_tkt\_creds\_free (C function)@\spxentry{krb5\_tkt\_creds\_free}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_tkt_creds_free:c.krb5_tkt_creds_free}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_tkt\_creds\_free}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_tkt_creds_context:c.krb5_tkt_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} TGS request context \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_tkt\_creds\_get \sphinxhyphen{} Synchronously obtain credentials using a TGS request context.} \label{\detokenize{appdev/refs/api/krb5_tkt_creds_get:krb5-tkt-creds-get-synchronously-obtain-credentials-using-a-tgs-request-context}}\label{\detokenize{appdev/refs/api/krb5_tkt_creds_get::doc}}\index{krb5\_tkt\_creds\_get (C function)@\spxentry{krb5\_tkt\_creds\_get}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_tkt_creds_get:c.krb5_tkt_creds_get}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_tkt\_creds\_get}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_tkt_creds_context:c.krb5_tkt_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} TGS request context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function synchronously obtains credentials using a context created by krb5\_tkt\_creds\_init(). On successful return, the credentials can be retrieved with krb5\_tkt\_creds\_get\_creds(). \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_tkt\_creds\_get\_creds \sphinxhyphen{} Retrieve acquired credentials from a TGS request context.} \label{\detokenize{appdev/refs/api/krb5_tkt_creds_get_creds:krb5-tkt-creds-get-creds-retrieve-acquired-credentials-from-a-tgs-request-context}}\label{\detokenize{appdev/refs/api/krb5_tkt_creds_get_creds::doc}}\index{krb5\_tkt\_creds\_get\_creds (C function)@\spxentry{krb5\_tkt\_creds\_get\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_tkt_creds_get_creds:c.krb5_tkt_creds_get_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_tkt\_creds\_get\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_tkt_creds_context:c.krb5_tkt_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} TGS request context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Acquired credentials \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function copies the acquired initial credentials from \sphinxstyleemphasis{ctx} into \sphinxstyleemphasis{creds} , after the successful completion of krb5\_tkt\_creds\_get() or krb5\_tkt\_creds\_step(). Use krb5\_free\_cred\_contents() to free \sphinxstyleemphasis{creds} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_tkt\_creds\_get\_times \sphinxhyphen{} Retrieve ticket times from a TGS request context.} \label{\detokenize{appdev/refs/api/krb5_tkt_creds_get_times:krb5-tkt-creds-get-times-retrieve-ticket-times-from-a-tgs-request-context}}\label{\detokenize{appdev/refs/api/krb5_tkt_creds_get_times::doc}}\index{krb5\_tkt\_creds\_get\_times (C function)@\spxentry{krb5\_tkt\_creds\_get\_times}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_tkt_creds_get_times:c.krb5_tkt_creds_get_times}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_tkt\_creds\_get\_times}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_tkt_creds_context:c.krb5_tkt_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{times}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} TGS request context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{times} \sphinxhyphen{} Ticket times for acquired credentials \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar The TGS request context must have completed obtaining credentials via either krb5\_tkt\_creds\_get() or krb5\_tkt\_creds\_step(). \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_tkt\_creds\_init \sphinxhyphen{} Create a context to get credentials from a KDC’s Ticket Granting Service.} \label{\detokenize{appdev/refs/api/krb5_tkt_creds_init:krb5-tkt-creds-init-create-a-context-to-get-credentials-from-a-kdc-s-ticket-granting-service}}\label{\detokenize{appdev/refs/api/krb5_tkt_creds_init::doc}}\index{krb5\_tkt\_creds\_init (C function)@\spxentry{krb5\_tkt\_creds\_init}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_tkt_creds_init:c.krb5_tkt_creds_init}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_tkt\_creds\_init}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_tkt_creds_context:c.krb5_tkt_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_creds\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ctx}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache handle \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Input credentials \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{options} \sphinxhyphen{} Options (see KRB5\_GC macros) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} New TGS request context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function prepares to obtain credentials matching \sphinxstyleemphasis{creds} , either by retrieving them from \sphinxstyleemphasis{ccache} or by making requests to ticket\sphinxhyphen{}granting services beginning with a ticket\sphinxhyphen{}granting ticket for the client principal’s realm. \sphinxAtStartPar The resulting TGS acquisition context can be used asynchronously with krb5\_tkt\_creds\_step() or synchronously with krb5\_tkt\_creds\_get(). See also krb5\_get\_credentials() for synchronous use. \sphinxAtStartPar Use krb5\_tkt\_creds\_free() to free \sphinxstyleemphasis{ctx} when it is no longer needed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_tkt\_creds\_step \sphinxhyphen{} Get the next KDC request in a TGS exchange.} \label{\detokenize{appdev/refs/api/krb5_tkt_creds_step:krb5-tkt-creds-step-get-the-next-kdc-request-in-a-tgs-exchange}}\label{\detokenize{appdev/refs/api/krb5_tkt_creds_step::doc}}\index{krb5\_tkt\_creds\_step (C function)@\spxentry{krb5\_tkt\_creds\_step}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_tkt_creds_step:c.krb5_tkt_creds_step}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_tkt\_creds\_step}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_tkt_creds_context:c.krb5_tkt_creds_context}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_creds\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{out}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{flags}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} TGS request context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in} \sphinxhyphen{} KDC response (empty on the first call) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out} \sphinxhyphen{} Next KDC request \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{realm} \sphinxhyphen{} Realm for next KDC request \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Output flags \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function constructs the next KDC request for a TGS exchange, allowing the caller to control the transport of KDC requests and replies. On the first call, \sphinxstyleemphasis{in} should be set to an empty buffer; on subsequent calls, it should be set to the KDC’s reply to the previous request. \sphinxAtStartPar If more requests are needed, \sphinxstyleemphasis{flags} will be set to KRB5\_TKT\_CREDS\_STEP\_FLAG\_CONTINUE and the next request will be placed in \sphinxstyleemphasis{out} . If no more requests are needed, \sphinxstyleemphasis{flags} will not contain KRB5\_TKT\_CREDS\_STEP\_FLAG\_CONTINUE and \sphinxstyleemphasis{out} will be empty. \sphinxAtStartPar If this function returns \sphinxstylestrong{KRB5KRB\_ERR\_RESPONSE\_TOO\_BIG} , the caller should transmit the next request using TCP rather than UDP. If this function returns any other error, the TGS exchange has failed. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_unmarshal\_credentials \sphinxhyphen{} Deserialize a krb5\_creds object.} \label{\detokenize{appdev/refs/api/krb5_unmarshal_credentials:krb5-unmarshal-credentials-deserialize-a-krb5-creds-object}}\label{\detokenize{appdev/refs/api/krb5_unmarshal_credentials::doc}}\index{krb5\_unmarshal\_credentials (C function)@\spxentry{krb5\_unmarshal\_credentials}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_unmarshal_credentials:c.krb5_unmarshal_credentials}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_unmarshal\_credentials}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{creds\_out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} The serialized credentials \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{creds\_out} \sphinxhyphen{} The resulting creds object \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Deserialize \sphinxstyleemphasis{data} to credentials in the format used by the FILE ccache format (vesion 4) and KCM ccache protocol. \sphinxAtStartPar Use krb5\_free\_creds() to free \sphinxstyleemphasis{creds\_out} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_verify\_init\_creds \sphinxhyphen{} Verify initial credentials against a keytab.} \label{\detokenize{appdev/refs/api/krb5_verify_init_creds:krb5-verify-init-creds-verify-initial-credentials-against-a-keytab}}\label{\detokenize{appdev/refs/api/krb5_verify_init_creds::doc}}\index{krb5\_verify\_init\_creds (C function)@\spxentry{krb5\_verify\_init\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_verify_init_creds:c.krb5_verify_init_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_verify\_init\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{server}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:c.krb5_verify_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_verify\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{options}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{creds} \sphinxhyphen{} Initial credentials to be verified \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Server principal (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table (NULL to use default keytab) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache for fetched creds (or NULL) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{options} \sphinxhyphen{} Verification options (NULL for default options) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function attempts to verify that \sphinxstyleemphasis{creds} were obtained from a KDC with knowledge of a key in \sphinxstyleemphasis{keytab} , or the default keytab if \sphinxstyleemphasis{keytab} is NULL. If \sphinxstyleemphasis{server} is provided, the highest\sphinxhyphen{}kvno key entry for that principal name is used to verify the credentials; otherwise, all uniqueâ€hostâ€service principals in the keytab are tried. \sphinxAtStartPar If the specified keytab does not exist, or is empty, or cannot be read, or does not contain an entry for \sphinxstyleemphasis{server} , then credential verification may be skipped unless configuration demands that it succeed. The caller can control this behavior by providing a verification options structure; see krb5\_verify\_init\_creds\_opt\_init() and krb5\_verify\_init\_creds\_opt\_set\_ap\_req\_nofail(). \sphinxAtStartPar If \sphinxstyleemphasis{ccache} is NULL, any additional credentials fetched during the verification process will be destroyed. If \sphinxstyleemphasis{ccache} points to NULL, a memory ccache will be created for the additional credentials and returned in \sphinxstyleemphasis{ccache} . If \sphinxstyleemphasis{ccache} points to a valid credential cache handle, the additional credentials will be stored in that cache. \sphinxstepscope \subsubsection{krb5\_verify\_init\_creds\_opt\_init \sphinxhyphen{} Initialize a credential verification options structure.} \label{\detokenize{appdev/refs/api/krb5_verify_init_creds_opt_init:krb5-verify-init-creds-opt-init-initialize-a-credential-verification-options-structure}}\label{\detokenize{appdev/refs/api/krb5_verify_init_creds_opt_init::doc}}\index{krb5\_verify\_init\_creds\_opt\_init (C function)@\spxentry{krb5\_verify\_init\_creds\_opt\_init}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_verify_init_creds_opt_init:c.krb5_verify_init_creds_opt_init}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_verify\_init\_creds\_opt\_init}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:c.krb5_verify_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_verify\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k5\_vic\_options}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{k5\_vic\_options} \sphinxhyphen{} Verification options structure \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_verify\_init\_creds\_opt\_set\_ap\_req\_nofail \sphinxhyphen{} Set whether credential verification is required.} \label{\detokenize{appdev/refs/api/krb5_verify_init_creds_opt_set_ap_req_nofail:krb5-verify-init-creds-opt-set-ap-req-nofail-set-whether-credential-verification-is-required}}\label{\detokenize{appdev/refs/api/krb5_verify_init_creds_opt_set_ap_req_nofail::doc}}\index{krb5\_verify\_init\_creds\_opt\_set\_ap\_req\_nofail (C function)@\spxentry{krb5\_verify\_init\_creds\_opt\_set\_ap\_req\_nofail}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_verify_init_creds_opt_set_ap_req_nofail:c.krb5_verify_init_creds_opt_set_ap_req_nofail}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_verify\_init\_creds\_opt\_set\_ap\_req\_nofail}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:c.krb5_verify_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_verify\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k5\_vic\_options}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{ap\_req\_nofail}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{k5\_vic\_options} \sphinxhyphen{} Verification options structure \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ap\_req\_nofail} \sphinxhyphen{} Whether to require successful verification \end{description}\end{quote} \sphinxAtStartPar This function determines how krb5\_verify\_init\_creds() behaves if no keytab information is available. If \sphinxstyleemphasis{ap\_req\_nofail} is \sphinxstylestrong{FALSE} , verification will be skipped in this case and krb5\_verify\_init\_creds() will return successfully. If \sphinxstyleemphasis{ap\_req\_nofail} is \sphinxstylestrong{TRUE} , krb5\_verify\_init\_creds() will not return successfully unless verification can be performed. \sphinxAtStartPar If this function is not used, the behavior of krb5\_verify\_init\_creds() is determined through configuration. \sphinxstepscope \subsubsection{krb5\_vprepend\_error\_message \sphinxhyphen{} Add a prefix to the message for an error code using a va\_list.} \label{\detokenize{appdev/refs/api/krb5_vprepend_error_message:krb5-vprepend-error-message-add-a-prefix-to-the-message-for-an-error-code-using-a-va-list}}\label{\detokenize{appdev/refs/api/krb5_vprepend_error_message::doc}}\index{krb5\_vprepend\_error\_message (C function)@\spxentry{krb5\_vprepend\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_vprepend_error_message:c.krb5_vprepend_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_vprepend\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\DUrole{n}{code}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{fmt}\sphinxparamcomma \DUrole{n}{va\_list}\DUrole{w}{ }\DUrole{n}{args}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{code} \sphinxhyphen{} Error code \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fmt} \sphinxhyphen{} Format string for error message prefix \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{args} \sphinxhyphen{} List of vprintf(3) style arguments \end{description}\end{quote} \sphinxAtStartPar This function is similar to krb5\_prepend\_error\_message(), but uses a va\_list instead of variadic arguments. \sphinxstepscope \subsubsection{krb5\_vset\_error\_message \sphinxhyphen{} Set an extended error message for an error code using a va\_list.} \label{\detokenize{appdev/refs/api/krb5_vset_error_message:krb5-vset-error-message-set-an-extended-error-message-for-an-error-code-using-a-va-list}}\label{\detokenize{appdev/refs/api/krb5_vset_error_message::doc}}\index{krb5\_vset\_error\_message (C function)@\spxentry{krb5\_vset\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_vset_error_message:c.krb5_vset_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_vset\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\DUrole{n}{code}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{fmt}\sphinxparamcomma \DUrole{n}{va\_list}\DUrole{w}{ }\DUrole{n}{args}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{code} \sphinxhyphen{} Error code \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fmt} \sphinxhyphen{} Error string for the error code \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{args} \sphinxhyphen{} List of vprintf(3) style arguments \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_vwrap\_error\_message \sphinxhyphen{} Add a prefix to a different error code’s message using a va\_list.} \label{\detokenize{appdev/refs/api/krb5_vwrap_error_message:krb5-vwrap-error-message-add-a-prefix-to-a-different-error-code-s-message-using-a-va-list}}\label{\detokenize{appdev/refs/api/krb5_vwrap_error_message::doc}}\index{krb5\_vwrap\_error\_message (C function)@\spxentry{krb5\_vwrap\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_vwrap_error_message:c.krb5_vwrap_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_vwrap\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\DUrole{n}{old\_code}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\DUrole{n}{code}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{fmt}\sphinxparamcomma \DUrole{n}{va\_list}\DUrole{w}{ }\DUrole{n}{args}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{old\_code} \sphinxhyphen{} Previous error code \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{code} \sphinxhyphen{} Error code \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fmt} \sphinxhyphen{} Format string for error message prefix \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{args} \sphinxhyphen{} List of vprintf(3) style arguments \end{description}\end{quote} \sphinxAtStartPar This function is similar to krb5\_wrap\_error\_message(), but uses a va\_list instead of variadic arguments. \sphinxstepscope \subsubsection{krb5\_wrap\_error\_message \sphinxhyphen{} Add a prefix to a different error code’s message.} \label{\detokenize{appdev/refs/api/krb5_wrap_error_message:krb5-wrap-error-message-add-a-prefix-to-a-different-error-code-s-message}}\label{\detokenize{appdev/refs/api/krb5_wrap_error_message::doc}}\index{krb5\_wrap\_error\_message (C function)@\spxentry{krb5\_wrap\_error\_message}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_wrap_error_message:c.krb5_wrap_error_message}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_wrap\_error\_message}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{ctx}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\DUrole{n}{old\_code}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\DUrole{n}{code}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{fmt}\sphinxparamcomma \DUrole{p}{...}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctx} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{old\_code} \sphinxhyphen{} Previous error code \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{code} \sphinxhyphen{} Error code \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fmt} \sphinxhyphen{} Format string for error message prefix \end{description}\end{quote} \sphinxAtStartPar Format a message and prepend it to the message for \sphinxstyleemphasis{old\_code} . The prefix will be separated from the old message with a colon and space. Set the resulting message as the extended error message for \sphinxstyleemphasis{code} . \subsection{Public interfaces that should not be called directly} \label{\detokenize{appdev/refs/api/index:public-interfaces-that-should-not-be-called-directly}} \sphinxstepscope \subsubsection{krb5\_c\_block\_size \sphinxhyphen{} Return cipher block size.} \label{\detokenize{appdev/refs/api/krb5_c_block_size:krb5-c-block-size-return-cipher-block-size}}\label{\detokenize{appdev/refs/api/krb5_c_block_size::doc}}\index{krb5\_c\_block\_size (C function)@\spxentry{krb5\_c\_block\_size}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_block_size:c.krb5_c_block_size}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_block\_size}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{blocksize}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{blocksize} \sphinxhyphen{} Block size for \sphinxstyleemphasis{enctype} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_checksum\_length \sphinxhyphen{} Return the length of checksums for a checksum type.} \label{\detokenize{appdev/refs/api/krb5_c_checksum_length:krb5-c-checksum-length-return-the-length-of-checksums-for-a-checksum-type}}\label{\detokenize{appdev/refs/api/krb5_c_checksum_length::doc}}\index{krb5\_c\_checksum\_length (C function)@\spxentry{krb5\_c\_checksum\_length}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_checksum_length:c.krb5_c_checksum_length}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_checksum\_length}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{cksumtype}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{length}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksumtype} \sphinxhyphen{} Checksum type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{length} \sphinxhyphen{} Checksum length \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_crypto\_length \sphinxhyphen{} Return a length of a message field specific to the encryption type.} \label{\detokenize{appdev/refs/api/krb5_c_crypto_length:krb5-c-crypto-length-return-a-length-of-a-message-field-specific-to-the-encryption-type}}\label{\detokenize{appdev/refs/api/krb5_c_crypto_length::doc}}\index{krb5\_c\_crypto\_length (C function)@\spxentry{krb5\_c\_crypto\_length}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_crypto_length:c.krb5_c_crypto_length}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_crypto\_length}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cryptotype:c.krb5_cryptotype}]{\sphinxcrossref{\DUrole{n}{krb5\_cryptotype}}}}\DUrole{w}{ }\DUrole{n}{type}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{size}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{type} \sphinxhyphen{} Type field (See KRB5\_CRYPTO\_TYPE macros) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{size} \sphinxhyphen{} Length of the \sphinxstyleemphasis{type} specific to \sphinxstyleemphasis{enctype} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_crypto\_length\_iov \sphinxhyphen{} Fill in lengths for header, trailer and padding in a IOV array.} \label{\detokenize{appdev/refs/api/krb5_c_crypto_length_iov:krb5-c-crypto-length-iov-fill-in-lengths-for-header-trailer-and-padding-in-a-iov-array}}\label{\detokenize{appdev/refs/api/krb5_c_crypto_length_iov::doc}}\index{krb5\_c\_crypto\_length\_iov (C function)@\spxentry{krb5\_c\_crypto\_length\_iov}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_crypto_length_iov:c.krb5_c_crypto_length_iov}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_crypto\_length\_iov}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{num\_data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{data} \sphinxhyphen{} IOV array \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_data} \sphinxhyphen{} Size of \sphinxstyleemphasis{data} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Padding is set to the actual padding required based on the provided \sphinxstyleemphasis{data} buffers. Typically this API is used after setting up the data buffers and KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY buffers, but before actually allocating header, trailer and padding. \sphinxstepscope \subsubsection{krb5\_c\_decrypt \sphinxhyphen{} Decrypt data using a key (operates on keyblock).} \label{\detokenize{appdev/refs/api/krb5_c_decrypt:krb5-c-decrypt-decrypt-data-using-a-key-operates-on-keyblock}}\label{\detokenize{appdev/refs/api/krb5_c_decrypt::doc}}\index{krb5\_c\_decrypt (C function)@\spxentry{krb5\_c\_decrypt}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_decrypt:c.krb5_c_decrypt}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_decrypt}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cipher\_state}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{output}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{cipher\_state} \sphinxhyphen{} Cipher state; specify NULL if not needed \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Encrypted data \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{output} \sphinxhyphen{} Decrypted data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function decrypts the data block \sphinxstyleemphasis{input} and stores the output into \sphinxstyleemphasis{output} . The actual decryption key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the encryption type. If non\sphinxhyphen{}null, \sphinxstyleemphasis{cipher\_state} specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The caller must initialize \sphinxstyleemphasis{output} and allocate at least enough space for the result. The usual practice is to allocate an output buffer as long as the ciphertext, and let krb5\_c\_decrypt() trim \sphinxstyleemphasis{output\sphinxhyphen{}\textgreater{}length} . For some enctypes, the resulting \sphinxstyleemphasis{output\sphinxhyphen{}\textgreater{}length} may include padding bytes. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_c\_decrypt\_iov \sphinxhyphen{} Decrypt data in place supporting AEAD (operates on keyblock).} \label{\detokenize{appdev/refs/api/krb5_c_decrypt_iov:krb5-c-decrypt-iov-decrypt-data-in-place-supporting-aead-operates-on-keyblock}}\label{\detokenize{appdev/refs/api/krb5_c_decrypt_iov::doc}}\index{krb5\_c\_decrypt\_iov (C function)@\spxentry{krb5\_c\_decrypt\_iov}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_decrypt_iov:c.krb5_c_decrypt_iov}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_decrypt\_iov}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keyblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cipher\_state}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{num\_data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keyblock} \sphinxhyphen{} Encryption key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cipher\_state} \sphinxhyphen{} Cipher state; specify NULL if not needed \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{data} \sphinxhyphen{} IOV array. Modified in\sphinxhyphen{}place. \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_data} \sphinxhyphen{} Size of \sphinxstyleemphasis{data} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function decrypts the data block \sphinxstyleemphasis{data} and stores the output in\sphinxhyphen{}place. The actual decryption key will be derived from \sphinxstyleemphasis{keyblock} and \sphinxstyleemphasis{usage} if key derivation is specified for the encryption type. If non\sphinxhyphen{}null, \sphinxstyleemphasis{cipher\_state} specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5\_crypto\_iov structures before calling into this API. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_c\_decrypt\_iov() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar On return from a krb5\_c\_decrypt\_iov() call, the \sphinxstyleemphasis{data\sphinxhyphen{}\textgreater{}length} in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_c\_derive\_prfplus \sphinxhyphen{} Derive a key using some input data (via RFC 6113 PRF+).} \label{\detokenize{appdev/refs/api/krb5_c_derive_prfplus:krb5-c-derive-prfplus-derive-a-key-using-some-input-data-via-rfc-6113-prf}}\label{\detokenize{appdev/refs/api/krb5_c_derive_prfplus::doc}}\index{krb5\_c\_derive\_prfplus (C function)@\spxentry{krb5\_c\_derive\_prfplus}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_derive_prfplus:c.krb5_c_derive_prfplus}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_derive\_prfplus}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{k} \sphinxhyphen{} KDC contribution key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Input string \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Output key enctype (or \sphinxstylestrong{ENCTYPE\_NULL} ) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out} \sphinxhyphen{} Derived keyblock \end{description}\end{quote} \sphinxAtStartPar This function uses PRF+ as defined in RFC 6113 to derive a key from another key and an input string. If \sphinxstyleemphasis{enctype} is \sphinxstylestrong{ENCTYPE\_NULL} , the output key will have the same enctype as the input key. \sphinxstepscope \subsubsection{krb5\_c\_encrypt \sphinxhyphen{} Encrypt data using a key (operates on keyblock).} \label{\detokenize{appdev/refs/api/krb5_c_encrypt:krb5-c-encrypt-encrypt-data-using-a-key-operates-on-keyblock}}\label{\detokenize{appdev/refs/api/krb5_c_encrypt::doc}}\index{krb5\_c\_encrypt (C function)@\spxentry{krb5\_c\_encrypt}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_encrypt:c.krb5_c_encrypt}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_encrypt}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cipher\_state}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{output}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{cipher\_state} \sphinxhyphen{} Cipher state; specify NULL if not needed \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Data to be encrypted \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{output} \sphinxhyphen{} Encrypted data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function encrypts the data block \sphinxstyleemphasis{input} and stores the output into \sphinxstyleemphasis{output} . The actual encryption key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the encryption type. If non\sphinxhyphen{}null, \sphinxstyleemphasis{cipher\_state} specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The caller must initialize \sphinxstyleemphasis{output} and allocate at least enough space for the result (using krb5\_c\_encrypt\_length() to determine the amount of space needed). \sphinxstyleemphasis{output\sphinxhyphen{}\textgreater{}length} will be set to the actual length of the ciphertext. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_c\_encrypt\_iov \sphinxhyphen{} Encrypt data in place supporting AEAD (operates on keyblock).} \label{\detokenize{appdev/refs/api/krb5_c_encrypt_iov:krb5-c-encrypt-iov-encrypt-data-in-place-supporting-aead-operates-on-keyblock}}\label{\detokenize{appdev/refs/api/krb5_c_encrypt_iov::doc}}\index{krb5\_c\_encrypt\_iov (C function)@\spxentry{krb5\_c\_encrypt\_iov}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_encrypt_iov:c.krb5_c_encrypt_iov}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_encrypt\_iov}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keyblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cipher\_state}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{num\_data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keyblock} \sphinxhyphen{} Encryption key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cipher\_state} \sphinxhyphen{} Cipher state; specify NULL if not needed \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{data} \sphinxhyphen{} IOV array. Modified in\sphinxhyphen{}place. \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_data} \sphinxhyphen{} Size of \sphinxstyleemphasis{data} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function encrypts the data block \sphinxstyleemphasis{data} and stores the output in\sphinxhyphen{}place. The actual encryption key will be derived from \sphinxstyleemphasis{keyblock} and \sphinxstyleemphasis{usage} if key derivation is specified for the encryption type. If non\sphinxhyphen{}null, \sphinxstyleemphasis{cipher\_state} specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5\_crypto\_iov structures before calling into this API. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_c\_decrypt\_iov() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar On return from a krb5\_c\_encrypt\_iov() call, the \sphinxstyleemphasis{data\sphinxhyphen{}\textgreater{}length} in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_c\_encrypt\_length \sphinxhyphen{} Compute encrypted data length.} \label{\detokenize{appdev/refs/api/krb5_c_encrypt_length:krb5-c-encrypt-length-compute-encrypted-data-length}}\label{\detokenize{appdev/refs/api/krb5_c_encrypt_length::doc}}\index{krb5\_c\_encrypt\_length (C function)@\spxentry{krb5\_c\_encrypt\_length}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_encrypt_length:c.krb5_c_encrypt_length}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_encrypt\_length}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{inputlen}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{length}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{inputlen} \sphinxhyphen{} Length of the data to be encrypted \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{length} \sphinxhyphen{} Length of the encrypted data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function computes the length of the ciphertext produced by encrypting \sphinxstyleemphasis{inputlen} bytes including padding, confounder, and checksum. \sphinxstepscope \subsubsection{krb5\_c\_enctype\_compare \sphinxhyphen{} Compare two encryption types.} \label{\detokenize{appdev/refs/api/krb5_c_enctype_compare:krb5-c-enctype-compare-compare-two-encryption-types}}\label{\detokenize{appdev/refs/api/krb5_c_enctype_compare::doc}}\index{krb5\_c\_enctype\_compare (C function)@\spxentry{krb5\_c\_enctype\_compare}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_enctype_compare:c.krb5_c_enctype_compare}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_enctype\_compare}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{e1}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{e2}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{similar}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{e1} \sphinxhyphen{} First encryption type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{e2} \sphinxhyphen{} Second encryption type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{similar} \sphinxhyphen{} \sphinxstylestrong{TRUE} if types are similar, \sphinxstylestrong{FALSE} if not \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function determines whether two encryption types use the same kind of keys. \sphinxstepscope \subsubsection{krb5\_c\_free\_state \sphinxhyphen{} Free a cipher state previously allocated by krb5\_c\_init\_state().} \label{\detokenize{appdev/refs/api/krb5_c_free_state:krb5-c-free-state-free-a-cipher-state-previously-allocated-by-krb5-c-init-state}}\label{\detokenize{appdev/refs/api/krb5_c_free_state::doc}}\index{krb5\_c\_free\_state (C function)@\spxentry{krb5\_c\_free\_state}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_free_state:c.krb5_c_free_state}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_free\_state}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{state}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{state} \sphinxhyphen{} Cipher state to be freed \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_fx\_cf2\_simple \sphinxhyphen{} Compute the KRB\sphinxhyphen{}FX\sphinxhyphen{}CF2 combination of two keys and pepper strings.} \label{\detokenize{appdev/refs/api/krb5_c_fx_cf2_simple:krb5-c-fx-cf2-simple-compute-the-krb-fx-cf2-combination-of-two-keys-and-pepper-strings}}\label{\detokenize{appdev/refs/api/krb5_c_fx_cf2_simple::doc}}\index{krb5\_c\_fx\_cf2\_simple (C function)@\spxentry{krb5\_c\_fx\_cf2\_simple}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_fx_cf2_simple:c.krb5_c_fx_cf2_simple}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_fx\_cf2\_simple}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k1}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pepper1}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k2}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pepper2}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{k1} \sphinxhyphen{} KDC contribution key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pepper1} \sphinxhyphen{} Stringâ€PKINIT†\sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{k2} \sphinxhyphen{} Reply key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{pepper2} \sphinxhyphen{} Stringâ€KeyExchange†\sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out} \sphinxhyphen{} Output key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function computes the KRB\sphinxhyphen{}FX\sphinxhyphen{}CF2 function over its inputs and places the results in a newly allocated keyblock. This function is simple in that it assumes that \sphinxstyleemphasis{pepper1} and \sphinxstyleemphasis{pepper2} are C strings with no internal nulls and that the enctype of the result will be the same as that of \sphinxstyleemphasis{k1} . \sphinxstyleemphasis{k1} and \sphinxstyleemphasis{k2} may be of different enctypes. \sphinxstepscope \subsubsection{krb5\_c\_init\_state \sphinxhyphen{} Initialize a new cipher state.} \label{\detokenize{appdev/refs/api/krb5_c_init_state:krb5-c-init-state-initialize-a-new-cipher-state}}\label{\detokenize{appdev/refs/api/krb5_c_init_state::doc}}\index{krb5\_c\_init\_state (C function)@\spxentry{krb5\_c\_init\_state}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_init_state:c.krb5_c_init_state}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_init\_state}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{new\_state}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{new\_state} \sphinxhyphen{} New cipher state \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_is\_coll\_proof\_cksum \sphinxhyphen{} Test whether a checksum type is collision\sphinxhyphen{}proof.} \label{\detokenize{appdev/refs/api/krb5_c_is_coll_proof_cksum:krb5-c-is-coll-proof-cksum-test-whether-a-checksum-type-is-collision-proof}}\label{\detokenize{appdev/refs/api/krb5_c_is_coll_proof_cksum::doc}}\index{krb5\_c\_is\_coll\_proof\_cksum (C function)@\spxentry{krb5\_c\_is\_coll\_proof\_cksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_is_coll_proof_cksum:c.krb5_c_is_coll_proof_cksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_is\_coll\_proof\_cksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{ctype}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctype} \sphinxhyphen{} Checksum type \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar TRUE if ctype is collision\sphinxhyphen{}proof, FALSE if it is not collision\sphinxhyphen{}proof or not a valid checksum type. \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_is\_keyed\_cksum \sphinxhyphen{} Test whether a checksum type is keyed.} \label{\detokenize{appdev/refs/api/krb5_c_is_keyed_cksum:krb5-c-is-keyed-cksum-test-whether-a-checksum-type-is-keyed}}\label{\detokenize{appdev/refs/api/krb5_c_is_keyed_cksum::doc}}\index{krb5\_c\_is\_keyed\_cksum (C function)@\spxentry{krb5\_c\_is\_keyed\_cksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_is_keyed_cksum:c.krb5_c_is_keyed_cksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_is\_keyed\_cksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{ctype}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctype} \sphinxhyphen{} Checksum type \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar TRUE if ctype is a keyed checksum type, FALSE otherwise. \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_keyed\_checksum\_types \sphinxhyphen{} Return a list of keyed checksum types usable with an encryption type.} \label{\detokenize{appdev/refs/api/krb5_c_keyed_checksum_types:krb5-c-keyed-checksum-types-return-a-list-of-keyed-checksum-types-usable-with-an-encryption-type}}\label{\detokenize{appdev/refs/api/krb5_c_keyed_checksum_types::doc}}\index{krb5\_c\_keyed\_checksum\_types (C function)@\spxentry{krb5\_c\_keyed\_checksum\_types}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_keyed_checksum_types:c.krb5_c_keyed_checksum_types}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_keyed\_checksum\_types}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{count}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{cksumtypes}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{count} \sphinxhyphen{} Count of allowable checksum types \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cksumtypes} \sphinxhyphen{} Array of allowable checksum types \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_free\_cksumtypes() to free \sphinxstyleemphasis{cksumtypes} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_c\_keylengths \sphinxhyphen{} Return length of the specified key in bytes.} \label{\detokenize{appdev/refs/api/krb5_c_keylengths:krb5-c-keylengths-return-length-of-the-specified-key-in-bytes}}\label{\detokenize{appdev/refs/api/krb5_c_keylengths::doc}}\index{krb5\_c\_keylengths (C function)@\spxentry{krb5\_c\_keylengths}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_keylengths:c.krb5_c_keylengths}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_keylengths}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keybytes}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keylength}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{keybytes} \sphinxhyphen{} Number of bytes required to make a key \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{keylength} \sphinxhyphen{} Length of final key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_make\_checksum \sphinxhyphen{} Compute a checksum (operates on keyblock).} \label{\detokenize{appdev/refs/api/krb5_c_make_checksum:krb5-c-make-checksum-compute-a-checksum-operates-on-keyblock}}\label{\detokenize{appdev/refs/api/krb5_c_make_checksum::doc}}\index{krb5\_c\_make\_checksum (C function)@\spxentry{krb5\_c\_make\_checksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_make_checksum:c.krb5_c_make_checksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_make\_checksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{cksumtype}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cksum}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksumtype} \sphinxhyphen{} Checksum type (0 for mandatory type) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key for a keyed checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Input data \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cksum} \sphinxhyphen{} Generated checksum \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function computes a checksum of type \sphinxstyleemphasis{cksumtype} over \sphinxstyleemphasis{input} , using \sphinxstyleemphasis{key} if the checksum type is a keyed checksum. If \sphinxstyleemphasis{cksumtype} is 0 and \sphinxstyleemphasis{key} is non\sphinxhyphen{}null, the checksum type will be the mandatory\sphinxhyphen{}to\sphinxhyphen{}implement checksum type for the key’s encryption type. The actual checksum key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the checksum type. The newly created \sphinxstyleemphasis{cksum} must be released by calling krb5\_free\_checksum\_contents() when it is no longer needed. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_c\_verify\_checksum() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function is similar to krb5\_k\_make\_checksum(), but operates on keyblock \sphinxstyleemphasis{key} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_c\_make\_checksum\_iov \sphinxhyphen{} Fill in a checksum element in IOV array (operates on keyblock)} \label{\detokenize{appdev/refs/api/krb5_c_make_checksum_iov:krb5-c-make-checksum-iov-fill-in-a-checksum-element-in-iov-array-operates-on-keyblock}}\label{\detokenize{appdev/refs/api/krb5_c_make_checksum_iov::doc}}\index{krb5\_c\_make\_checksum\_iov (C function)@\spxentry{krb5\_c\_make\_checksum\_iov}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_make_checksum_iov:c.krb5_c_make_checksum_iov}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_make\_checksum\_iov}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{cksumtype}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{num\_data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksumtype} \sphinxhyphen{} Checksum type (0 for mandatory type) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key for a keyed checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{data} \sphinxhyphen{} IOV array \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_data} \sphinxhyphen{} Size of \sphinxstyleemphasis{data} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Create a checksum in the KRB5\_CRYPTO\_TYPE\_CHECKSUM element over KRB5\_CRYPTO\_TYPE\_DATA and KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY chunks in \sphinxstyleemphasis{data} . Only the KRB5\_CRYPTO\_TYPE\_CHECKSUM region is modified. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_c\_verify\_checksum\_iov() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function is similar to krb5\_k\_make\_checksum\_iov(), but operates on keyblock \sphinxstyleemphasis{key} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_c\_make\_random\_key \sphinxhyphen{} Generate an enctype\sphinxhyphen{}specific random encryption key.} \label{\detokenize{appdev/refs/api/krb5_c_make_random_key:krb5-c-make-random-key-generate-an-enctype-specific-random-encryption-key}}\label{\detokenize{appdev/refs/api/krb5_c_make_random_key::doc}}\index{krb5\_c\_make\_random\_key (C function)@\spxentry{krb5\_c\_make\_random\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_make_random_key:c.krb5_c_make_random_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_make\_random\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k5\_random\_key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type of the generated key \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{k5\_random\_key} \sphinxhyphen{} An allocated and initialized keyblock \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Use krb5\_free\_keyblock\_contents() to free \sphinxstyleemphasis{k5\_random\_key} when no longer needed. \sphinxstepscope \subsubsection{krb5\_c\_padding\_length \sphinxhyphen{} Return a number of padding octets.} \label{\detokenize{appdev/refs/api/krb5_c_padding_length:krb5-c-padding-length-return-a-number-of-padding-octets}}\label{\detokenize{appdev/refs/api/krb5_c_padding_length::doc}}\index{krb5\_c\_padding\_length (C function)@\spxentry{krb5\_c\_padding\_length}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_padding_length:c.krb5_c_padding_length}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_padding\_length}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{data\_length}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{size}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data\_length} \sphinxhyphen{} Length of the plaintext to pad \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{size} \sphinxhyphen{} Number of padding octets \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} KRB5\_BAD\_ENCTYPE \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function returns the number of the padding octets required to pad \sphinxstyleemphasis{data\_length} octets of plaintext. \sphinxstepscope \subsubsection{krb5\_c\_prf \sphinxhyphen{} Generate enctype\sphinxhyphen{}specific pseudo\sphinxhyphen{}random bytes.} \label{\detokenize{appdev/refs/api/krb5_c_prf:krb5-c-prf-generate-enctype-specific-pseudo-random-bytes}}\label{\detokenize{appdev/refs/api/krb5_c_prf::doc}}\index{krb5\_c\_prf (C function)@\spxentry{krb5\_c\_prf}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_prf:c.krb5_c_prf}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_prf}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keyblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{output}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keyblock} \sphinxhyphen{} Key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Input data \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{output} \sphinxhyphen{} Output data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function selects a pseudo\sphinxhyphen{}random function based on \sphinxstyleemphasis{keyblock} and computes its value over \sphinxstyleemphasis{input} , placing the result into \sphinxstyleemphasis{output} . The caller must preinitialize \sphinxstyleemphasis{output} and allocate space for the result, using krb5\_c\_prf\_length() to determine the required length. \sphinxstepscope \subsubsection{krb5\_c\_prfplus \sphinxhyphen{} Generate pseudo\sphinxhyphen{}random bytes using RFC 6113 PRF+.} \label{\detokenize{appdev/refs/api/krb5_c_prfplus:krb5-c-prfplus-generate-pseudo-random-bytes-using-rfc-6113-prf}}\label{\detokenize{appdev/refs/api/krb5_c_prfplus::doc}}\index{krb5\_c\_prfplus (C function)@\spxentry{krb5\_c\_prfplus}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_prfplus:c.krb5_c_prfplus}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_prfplus}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{output}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{k} \sphinxhyphen{} KDC contribution key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Input data \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{output} \sphinxhyphen{} Pseudo\sphinxhyphen{}random output buffer \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar 0 on success, E2BIG if output\sphinxhyphen{}\textgreater{}length is too large for PRF+ to generate, ENOMEM on allocation failure, or an error code from krb5\_c\_prf() \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function fills \sphinxstyleemphasis{output} with PRF+(k, input) as defined in RFC 6113 section 5.1. The caller must preinitialize \sphinxstyleemphasis{output} and allocate the desired amount of space. The length of the pseudo\sphinxhyphen{}random output will match the length of \sphinxstyleemphasis{output} . \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar RFC 4402 defines a different PRF+ operation. This function does not implement that operation. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_c\_prf\_length \sphinxhyphen{} Get the output length of pseudo\sphinxhyphen{}random functions for an encryption type.} \label{\detokenize{appdev/refs/api/krb5_c_prf_length:krb5-c-prf-length-get-the-output-length-of-pseudo-random-functions-for-an-encryption-type}}\label{\detokenize{appdev/refs/api/krb5_c_prf_length::doc}}\index{krb5\_c\_prf\_length (C function)@\spxentry{krb5\_c\_prf\_length}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_prf_length:c.krb5_c_prf_length}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_prf\_length}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{len}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{len} \sphinxhyphen{} Length of PRF output \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_random\_add\_entropy} \label{\detokenize{appdev/refs/api/krb5_c_random_add_entropy:krb5-c-random-add-entropy}}\label{\detokenize{appdev/refs/api/krb5_c_random_add_entropy::doc}}\index{krb5\_c\_random\_add\_entropy (C function)@\spxentry{krb5\_c\_random\_add\_entropy}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_random_add_entropy:c.krb5_c_random_add_entropy}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_random\_add\_entropy}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{randsource}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{randsource} \sphinxAtStartPar \sphinxstylestrong{data} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED This call is no longer necessary. \sphinxstepscope \subsubsection{krb5\_c\_random\_make\_octets \sphinxhyphen{} Generate pseudo\sphinxhyphen{}random bytes.} \label{\detokenize{appdev/refs/api/krb5_c_random_make_octets:krb5-c-random-make-octets-generate-pseudo-random-bytes}}\label{\detokenize{appdev/refs/api/krb5_c_random_make_octets::doc}}\index{krb5\_c\_random\_make\_octets (C function)@\spxentry{krb5\_c\_random\_make\_octets}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_random_make_octets:c.krb5_c_random_make_octets}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_random\_make\_octets}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{data} \sphinxhyphen{} Random data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Fills in \sphinxstyleemphasis{data} with bytes from the PRNG used by krb5 crypto operations. The caller must preinitialize \sphinxstyleemphasis{data} and allocate the desired amount of space. \sphinxstepscope \subsubsection{krb5\_c\_random\_os\_entropy} \label{\detokenize{appdev/refs/api/krb5_c_random_os_entropy:krb5-c-random-os-entropy}}\label{\detokenize{appdev/refs/api/krb5_c_random_os_entropy::doc}}\index{krb5\_c\_random\_os\_entropy (C function)@\spxentry{krb5\_c\_random\_os\_entropy}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_random_os_entropy:c.krb5_c_random_os_entropy}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_random\_os\_entropy}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{strong}\sphinxparamcomma \DUrole{kt}{int}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{success}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{strong} \sphinxAtStartPar \sphinxstylestrong{success} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED This call is no longer necessary. \sphinxstepscope \subsubsection{krb5\_c\_random\_to\_key \sphinxhyphen{} Generate an enctype\sphinxhyphen{}specific key from random data.} \label{\detokenize{appdev/refs/api/krb5_c_random_to_key:krb5-c-random-to-key-generate-an-enctype-specific-key-from-random-data}}\label{\detokenize{appdev/refs/api/krb5_c_random_to_key::doc}}\index{krb5\_c\_random\_to\_key (C function)@\spxentry{krb5\_c\_random\_to\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_random_to_key:c.krb5_c_random_to_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_random\_to\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{random\_data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{k5\_random\_key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{random\_data} \sphinxhyphen{} Random input data \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{k5\_random\_key} \sphinxhyphen{} Resulting key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function takes random input data \sphinxstyleemphasis{random\_data} and produces a valid key \sphinxstyleemphasis{k5\_random\_key} for a given \sphinxstyleemphasis{enctype} . \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_c\_keylengths() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar It is assumed that \sphinxstyleemphasis{k5\_random\_key} has already been initialized and \sphinxstyleemphasis{k5\_random\_key\sphinxhyphen{}\textgreater{}contents} has been allocated with the correct length. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_c\_string\_to\_key \sphinxhyphen{} Convert a string (such a password) to a key.} \label{\detokenize{appdev/refs/api/krb5_c_string_to_key:krb5-c-string-to-key-convert-a-string-such-a-password-to-a-key}}\label{\detokenize{appdev/refs/api/krb5_c_string_to_key::doc}}\index{krb5\_c\_string\_to\_key (C function)@\spxentry{krb5\_c\_string\_to\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_string_to_key:c.krb5_c_string_to_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_string\_to\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{string}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{salt}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{string} \sphinxhyphen{} String to be converted \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{salt} \sphinxhyphen{} Salt value \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{key} \sphinxhyphen{} Generated key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function converts \sphinxstyleemphasis{string} to a \sphinxstyleemphasis{key} of encryption type \sphinxstyleemphasis{enctype} , using the specified \sphinxstyleemphasis{salt} . The newly created \sphinxstyleemphasis{key} must be released by calling krb5\_free\_keyblock\_contents() when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_c\_string\_to\_key\_with\_params \sphinxhyphen{} Convert a string (such as a password) to a key with additional parameters.} \label{\detokenize{appdev/refs/api/krb5_c_string_to_key_with_params:krb5-c-string-to-key-with-params-convert-a-string-such-as-a-password-to-a-key-with-additional-parameters}}\label{\detokenize{appdev/refs/api/krb5_c_string_to_key_with_params::doc}}\index{krb5\_c\_string\_to\_key\_with\_params (C function)@\spxentry{krb5\_c\_string\_to\_key\_with\_params}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_string_to_key_with_params:c.krb5_c_string_to_key_with_params}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_string\_to\_key\_with\_params}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{string}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{salt}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{params}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{string} \sphinxhyphen{} String to be converted \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{salt} \sphinxhyphen{} Salt value \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{params} \sphinxhyphen{} Parameters \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{key} \sphinxhyphen{} Generated key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function is similar to krb5\_c\_string\_to\_key(), but also takes parameters which may affect the algorithm in an enctype\sphinxhyphen{}dependent way. The newly created \sphinxstyleemphasis{key} must be released by calling krb5\_free\_keyblock\_contents() when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_c\_valid\_cksumtype \sphinxhyphen{} Verify that specified checksum type is a valid Kerberos checksum type.} \label{\detokenize{appdev/refs/api/krb5_c_valid_cksumtype:krb5-c-valid-cksumtype-verify-that-specified-checksum-type-is-a-valid-kerberos-checksum-type}}\label{\detokenize{appdev/refs/api/krb5_c_valid_cksumtype::doc}}\index{krb5\_c\_valid\_cksumtype (C function)@\spxentry{krb5\_c\_valid\_cksumtype}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_valid_cksumtype:c.krb5_c_valid_cksumtype}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_valid\_cksumtype}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{ctype}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ctype} \sphinxhyphen{} Checksum type \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar TRUE if ctype is valid, FALSE if not \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_valid\_enctype \sphinxhyphen{} Verify that a specified encryption type is a valid Kerberos encryption type.} \label{\detokenize{appdev/refs/api/krb5_c_valid_enctype:krb5-c-valid-enctype-verify-that-a-specified-encryption-type-is-a-valid-kerberos-encryption-type}}\label{\detokenize{appdev/refs/api/krb5_c_valid_enctype::doc}}\index{krb5\_c\_valid\_enctype (C function)@\spxentry{krb5\_c\_valid\_enctype}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_valid_enctype:c.krb5_c_valid_enctype}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_valid\_enctype}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{ktype}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ktype} \sphinxhyphen{} Encryption type \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{return}\begin{itemize} \item {} \sphinxAtStartPar TRUE if ktype is valid, FALSE if not \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_c\_verify\_checksum \sphinxhyphen{} Verify a checksum (operates on keyblock).} \label{\detokenize{appdev/refs/api/krb5_c_verify_checksum:krb5-c-verify-checksum-verify-a-checksum-operates-on-keyblock}}\label{\detokenize{appdev/refs/api/krb5_c_verify_checksum::doc}}\index{krb5\_c\_verify\_checksum (C function)@\spxentry{krb5\_c\_verify\_checksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_verify_checksum:c.krb5_c_verify_checksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_verify\_checksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cksum}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{valid}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key for a keyed checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} \sphinxstyleemphasis{key} usage \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Data to be used to compute a new checksum using \sphinxstyleemphasis{key} to compare \sphinxstyleemphasis{cksum} against \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksum} \sphinxhyphen{} Checksum to be verified \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{valid} \sphinxhyphen{} Non\sphinxhyphen{}zero for success, zero for failure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function verifies that \sphinxstyleemphasis{cksum} is a valid checksum for \sphinxstyleemphasis{data} . If the checksum type of \sphinxstyleemphasis{cksum} is a keyed checksum, \sphinxstyleemphasis{key} is used to verify the checksum. If the checksum type in \sphinxstyleemphasis{cksum} is 0 and \sphinxstyleemphasis{key} is not NULL, the mandatory checksum type for \sphinxstyleemphasis{key} will be used. The actual checksum key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the checksum type. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function is similar to krb5\_k\_verify\_checksum(), but operates on keyblock \sphinxstyleemphasis{key} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_c\_verify\_checksum\_iov \sphinxhyphen{} Validate a checksum element in IOV array (operates on keyblock).} \label{\detokenize{appdev/refs/api/krb5_c_verify_checksum_iov:krb5-c-verify-checksum-iov-validate-a-checksum-element-in-iov-array-operates-on-keyblock}}\label{\detokenize{appdev/refs/api/krb5_c_verify_checksum_iov::doc}}\index{krb5\_c\_verify\_checksum\_iov (C function)@\spxentry{krb5\_c\_verify\_checksum\_iov}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_verify_checksum_iov:c.krb5_c_verify_checksum_iov}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_verify\_checksum\_iov}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{cksumtype}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{num\_data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{valid}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksumtype} \sphinxhyphen{} Checksum type (0 for mandatory type) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key for a keyed checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} IOV array \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_data} \sphinxhyphen{} Size of \sphinxstyleemphasis{data} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{valid} \sphinxhyphen{} Non\sphinxhyphen{}zero for success, zero for failure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Confirm that the checksum in the KRB5\_CRYPTO\_TYPE\_CHECKSUM element is a valid checksum of the KRB5\_CRYPTO\_TYPE\_DATA and KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY regions in the iov. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_c\_make\_checksum\_iov() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function is similar to krb5\_k\_verify\_checksum\_iov(), but operates on keyblock \sphinxstyleemphasis{key} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_cksumtype\_to\_string \sphinxhyphen{} Convert a checksum type to a string.} \label{\detokenize{appdev/refs/api/krb5_cksumtype_to_string:krb5-cksumtype-to-string-convert-a-checksum-type-to-a-string}}\label{\detokenize{appdev/refs/api/krb5_cksumtype_to_string::doc}}\index{krb5\_cksumtype\_to\_string (C function)@\spxentry{krb5\_cksumtype\_to\_string}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cksumtype_to_string:c.krb5_cksumtype_to_string}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cksumtype\_to\_string}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{cksumtype}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{buffer}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{buflen}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksumtype} \sphinxhyphen{} Checksum type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{buffer} \sphinxhyphen{} Buffer to hold converted checksum type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{buflen} \sphinxhyphen{} Storage available in \sphinxstyleemphasis{buffer} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_decode\_authdata\_container \sphinxhyphen{} Unwrap authorization data.} \label{\detokenize{appdev/refs/api/krb5_decode_authdata_container:krb5-decode-authdata-container-unwrap-authorization-data}}\label{\detokenize{appdev/refs/api/krb5_decode_authdata_container::doc}}\index{krb5\_decode\_authdata\_container (C function)@\spxentry{krb5\_decode\_authdata\_container}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_decode_authdata_container:c.krb5_decode_authdata_container}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_decode\_authdata\_container}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdatatype:c.krb5_authdatatype}]{\sphinxcrossref{\DUrole{n}{krb5\_authdatatype}}}}\DUrole{w}{ }\DUrole{n}{type}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{container}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{authdata}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{type} \sphinxhyphen{} Container type (see KRB5\_AUTHDATA macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{container} \sphinxhyphen{} Authorization data to be decoded \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{authdata} \sphinxhyphen{} List of decoded authorization data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_encode\_authdata\_container() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_decode\_ticket \sphinxhyphen{} Decode an ASN.1\sphinxhyphen{}formatted ticket.} \label{\detokenize{appdev/refs/api/krb5_decode_ticket:krb5-decode-ticket-decode-an-asn-1-formatted-ticket}}\label{\detokenize{appdev/refs/api/krb5_decode_ticket::doc}}\index{krb5\_decode\_ticket (C function)@\spxentry{krb5\_decode\_ticket}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_decode_ticket:c.krb5_decode_ticket}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_decode\_ticket}}}}{\DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{code}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{rep}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{code} \sphinxhyphen{} ASN.1\sphinxhyphen{}formatted ticket \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rep} \sphinxhyphen{} Decoded ticket information \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_deltat\_to\_string \sphinxhyphen{} Convert a relative time value to a string.} \label{\detokenize{appdev/refs/api/krb5_deltat_to_string:krb5-deltat-to-string-convert-a-relative-time-value-to-a-string}}\label{\detokenize{appdev/refs/api/krb5_deltat_to_string::doc}}\index{krb5\_deltat\_to\_string (C function)@\spxentry{krb5\_deltat\_to\_string}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_deltat_to_string:c.krb5_deltat_to_string}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_deltat\_to\_string}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}]{\sphinxcrossref{\DUrole{n}{krb5\_deltat}}}}\DUrole{w}{ }\DUrole{n}{deltat}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{buffer}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{buflen}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{deltat} \sphinxhyphen{} Relative time value to convert \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{buffer} \sphinxhyphen{} Buffer to hold time string \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{buflen} \sphinxhyphen{} Storage available in \sphinxstyleemphasis{buffer} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_encode\_authdata\_container \sphinxhyphen{} Wrap authorization data in a container.} \label{\detokenize{appdev/refs/api/krb5_encode_authdata_container:krb5-encode-authdata-container-wrap-authorization-data-in-a-container}}\label{\detokenize{appdev/refs/api/krb5_encode_authdata_container::doc}}\index{krb5\_encode\_authdata\_container (C function)@\spxentry{krb5\_encode\_authdata\_container}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_encode_authdata_container:c.krb5_encode_authdata_container}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_encode\_authdata\_container}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdatatype:c.krb5_authdatatype}]{\sphinxcrossref{\DUrole{n}{krb5\_authdatatype}}}}\DUrole{w}{ }\DUrole{n}{type}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{authdata}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{container}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{type} \sphinxhyphen{} Container type (see KRB5\_AUTHDATA macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{authdata} \sphinxhyphen{} List of authorization data to be encoded \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{container} \sphinxhyphen{} List of encoded authorization data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar The result is returned in \sphinxstyleemphasis{container} as a single\sphinxhyphen{}element list. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_decode\_authdata\_container() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_enctype\_to\_name \sphinxhyphen{} Convert an encryption type to a name or alias.} \label{\detokenize{appdev/refs/api/krb5_enctype_to_name:krb5-enctype-to-name-convert-an-encryption-type-to-a-name-or-alias}}\label{\detokenize{appdev/refs/api/krb5_enctype_to_name::doc}}\index{krb5\_enctype\_to\_name (C function)@\spxentry{krb5\_enctype\_to\_name}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_enctype_to_name:c.krb5_enctype_to_name}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_enctype\_to\_name}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{n}{shortest}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{buffer}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{buflen}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{shortest} \sphinxhyphen{} Flag \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{buffer} \sphinxhyphen{} Buffer to hold encryption type string \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{buflen} \sphinxhyphen{} Storage available in \sphinxstyleemphasis{buffer} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar If \sphinxstyleemphasis{shortest} is FALSE, this function returns the enctype’s canonical name (likeâ€aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96â€). If \sphinxstyleemphasis{shortest} is TRUE, it return the enctype’s shortest alias (likeâ€aes128\sphinxhyphen{}ctsâ€). \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar New in 1.9 \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_enctype\_to\_string \sphinxhyphen{} Convert an encryption type to a string.} \label{\detokenize{appdev/refs/api/krb5_enctype_to_string:krb5-enctype-to-string-convert-an-encryption-type-to-a-string}}\label{\detokenize{appdev/refs/api/krb5_enctype_to_string::doc}}\index{krb5\_enctype\_to\_string (C function)@\spxentry{krb5\_enctype\_to\_string}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_enctype_to_string:c.krb5_enctype_to_string}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_enctype\_to\_string}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{buffer}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{buflen}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{enctype} \sphinxhyphen{} Encryption type \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{buffer} \sphinxhyphen{} Buffer to hold encryption type string \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{buflen} \sphinxhyphen{} Storage available in \sphinxstyleemphasis{buffer} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_free\_checksum \sphinxhyphen{} Free a krb5\_checksum structure.} \label{\detokenize{appdev/refs/api/krb5_free_checksum:krb5-free-checksum-free-a-krb5-checksum-structure}}\label{\detokenize{appdev/refs/api/krb5_free_checksum::doc}}\index{krb5\_free\_checksum (C function)@\spxentry{krb5\_free\_checksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_checksum:c.krb5_free_checksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_checksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Checksum structure to be freed \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} and the structure itself. \sphinxstepscope \subsubsection{krb5\_free\_checksum\_contents \sphinxhyphen{} Free the contents of a krb5\_checksum structure.} \label{\detokenize{appdev/refs/api/krb5_free_checksum_contents:krb5-free-checksum-contents-free-the-contents-of-a-krb5-checksum-structure}}\label{\detokenize{appdev/refs/api/krb5_free_checksum_contents::doc}}\index{krb5\_free\_checksum\_contents (C function)@\spxentry{krb5\_free\_checksum\_contents}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_checksum_contents:c.krb5_free_checksum_contents}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_checksum\_contents}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Checksum structure to free contents of \end{description}\end{quote} \sphinxAtStartPar This function frees the contents of \sphinxstyleemphasis{val} , but not the structure itself. It sets the checksum’s data pointer to null and (beginning in release 1.19) sets its length to zero. \sphinxstepscope \subsubsection{krb5\_free\_cksumtypes \sphinxhyphen{} Free an array of checksum types.} \label{\detokenize{appdev/refs/api/krb5_free_cksumtypes:krb5-free-cksumtypes-free-an-array-of-checksum-types}}\label{\detokenize{appdev/refs/api/krb5_free_cksumtypes::doc}}\index{krb5\_free\_cksumtypes (C function)@\spxentry{krb5\_free\_cksumtypes}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_cksumtypes:c.krb5_free_cksumtypes}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_cksumtypes}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{val}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{val} \sphinxhyphen{} Array of checksum types to be freed \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_free\_tgt\_creds \sphinxhyphen{} Free an array of credential structures.} \label{\detokenize{appdev/refs/api/krb5_free_tgt_creds:krb5-free-tgt-creds-free-an-array-of-credential-structures}}\label{\detokenize{appdev/refs/api/krb5_free_tgt_creds::doc}}\index{krb5\_free\_tgt\_creds (C function)@\spxentry{krb5\_free\_tgt\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_free_tgt_creds:c.krb5_free_tgt_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_free\_tgt\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{tgts}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{tgts} \sphinxhyphen{} Null\sphinxhyphen{}terminated array of credentials to free \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The last entry in the array \sphinxstyleemphasis{tgts} must be a NULL pointer. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_k\_create\_key \sphinxhyphen{} Create a krb5\_key from the enctype and key data in a keyblock.} \label{\detokenize{appdev/refs/api/krb5_k_create_key:krb5-k-create-key-create-a-krb5-key-from-the-enctype-and-key-data-in-a-keyblock}}\label{\detokenize{appdev/refs/api/krb5_k_create_key::doc}}\index{krb5\_k\_create\_key (C function)@\spxentry{krb5\_k\_create\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_create_key:c.krb5_k_create_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_create\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key\_data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{out}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key\_data} \sphinxhyphen{} Keyblock \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out} \sphinxhyphen{} Opaque key \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} KRB5\_BAD\_ENCTYPE \end{itemize} \end{description}\end{quote} \sphinxAtStartPar The reference count on a key \sphinxstyleemphasis{out} is set to 1. Use krb5\_k\_free\_key() to free \sphinxstyleemphasis{out} when it is no longer needed. \sphinxstepscope \subsubsection{krb5\_k\_decrypt \sphinxhyphen{} Decrypt data using a key (operates on opaque key).} \label{\detokenize{appdev/refs/api/krb5_k_decrypt:krb5-k-decrypt-decrypt-data-using-a-key-operates-on-opaque-key}}\label{\detokenize{appdev/refs/api/krb5_k_decrypt::doc}}\index{krb5\_k\_decrypt (C function)@\spxentry{krb5\_k\_decrypt}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_decrypt:c.krb5_k_decrypt}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_decrypt}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cipher\_state}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{output}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{cipher\_state} \sphinxhyphen{} Cipher state; specify NULL if not needed \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Encrypted data \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{output} \sphinxhyphen{} Decrypted data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function decrypts the data block \sphinxstyleemphasis{input} and stores the output into \sphinxstyleemphasis{output} . The actual decryption key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the encryption type. If non\sphinxhyphen{}null, \sphinxstyleemphasis{cipher\_state} specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The caller must initialize \sphinxstyleemphasis{output} and allocate at least enough space for the result. The usual practice is to allocate an output buffer as long as the ciphertext, and let krb5\_c\_decrypt() trim \sphinxstyleemphasis{output\sphinxhyphen{}\textgreater{}length} . For some enctypes, the resulting \sphinxstyleemphasis{output\sphinxhyphen{}\textgreater{}length} may include padding bytes. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_k\_decrypt\_iov \sphinxhyphen{} Decrypt data in place supporting AEAD (operates on opaque key).} \label{\detokenize{appdev/refs/api/krb5_k_decrypt_iov:krb5-k-decrypt-iov-decrypt-data-in-place-supporting-aead-operates-on-opaque-key}}\label{\detokenize{appdev/refs/api/krb5_k_decrypt_iov::doc}}\index{krb5\_k\_decrypt\_iov (C function)@\spxentry{krb5\_k\_decrypt\_iov}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_decrypt_iov:c.krb5_k_decrypt_iov}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_decrypt\_iov}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cipher\_state}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{num\_data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cipher\_state} \sphinxhyphen{} Cipher state; specify NULL if not needed \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{data} \sphinxhyphen{} IOV array. Modified in\sphinxhyphen{}place. \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_data} \sphinxhyphen{} Size of \sphinxstyleemphasis{data} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function decrypts the data block \sphinxstyleemphasis{data} and stores the output in\sphinxhyphen{}place. The actual decryption key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the encryption type. If non\sphinxhyphen{}null, \sphinxstyleemphasis{cipher\_state} specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5\_crypto\_iov structures before calling into this API. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_k\_encrypt\_iov() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar On return from a krb5\_c\_decrypt\_iov() call, the \sphinxstyleemphasis{data\sphinxhyphen{}\textgreater{}length} in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_k\_encrypt \sphinxhyphen{} Encrypt data using a key (operates on opaque key).} \label{\detokenize{appdev/refs/api/krb5_k_encrypt:krb5-k-encrypt-encrypt-data-using-a-key-operates-on-opaque-key}}\label{\detokenize{appdev/refs/api/krb5_k_encrypt::doc}}\index{krb5\_k\_encrypt (C function)@\spxentry{krb5\_k\_encrypt}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_encrypt:c.krb5_k_encrypt}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_encrypt}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cipher\_state}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{output}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{cipher\_state} \sphinxhyphen{} Cipher state; specify NULL if not needed \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Data to be encrypted \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{output} \sphinxhyphen{} Encrypted data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function encrypts the data block \sphinxstyleemphasis{input} and stores the output into \sphinxstyleemphasis{output} . The actual encryption key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the encryption type. If non\sphinxhyphen{}null, \sphinxstyleemphasis{cipher\_state} specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The caller must initialize \sphinxstyleemphasis{output} and allocate at least enough space for the result (using krb5\_c\_encrypt\_length() to determine the amount of space needed). \sphinxstyleemphasis{output\sphinxhyphen{}\textgreater{}length} will be set to the actual length of the ciphertext. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_k\_encrypt\_iov \sphinxhyphen{} Encrypt data in place supporting AEAD (operates on opaque key).} \label{\detokenize{appdev/refs/api/krb5_k_encrypt_iov:krb5-k-encrypt-iov-encrypt-data-in-place-supporting-aead-operates-on-opaque-key}}\label{\detokenize{appdev/refs/api/krb5_k_encrypt_iov::doc}}\index{krb5\_k\_encrypt\_iov (C function)@\spxentry{krb5\_k\_encrypt\_iov}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_encrypt_iov:c.krb5_k_encrypt_iov}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_encrypt\_iov}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cipher\_state}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{num\_data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cipher\_state} \sphinxhyphen{} Cipher state; specify NULL if not needed \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{data} \sphinxhyphen{} IOV array. Modified in\sphinxhyphen{}place. \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_data} \sphinxhyphen{} Size of \sphinxstyleemphasis{data} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function encrypts the data block \sphinxstyleemphasis{data} and stores the output in\sphinxhyphen{}place. The actual encryption key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the encryption type. If non\sphinxhyphen{}null, \sphinxstyleemphasis{cipher\_state} specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5\_crypto\_iov structures before calling into this API. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_k\_decrypt\_iov() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar On return from a krb5\_c\_encrypt\_iov() call, the \sphinxstyleemphasis{data\sphinxhyphen{}\textgreater{}length} in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased. \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_k\_free\_key \sphinxhyphen{} Decrement the reference count on a key and free it if it hits zero.} \label{\detokenize{appdev/refs/api/krb5_k_free_key:krb5-k-free-key-decrement-the-reference-count-on-a-key-and-free-it-if-it-hits-zero}}\label{\detokenize{appdev/refs/api/krb5_k_free_key::doc}}\index{krb5\_k\_free\_key (C function)@\spxentry{krb5\_k\_free\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_free_key:c.krb5_k_free_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_free\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{key} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_k\_key\_enctype \sphinxhyphen{} Retrieve the enctype of a krb5\_key structure.} \label{\detokenize{appdev/refs/api/krb5_k_key_enctype:krb5-k-key-enctype-retrieve-the-enctype-of-a-krb5-key-structure}}\label{\detokenize{appdev/refs/api/krb5_k_key_enctype::doc}}\index{krb5\_k\_key\_enctype (C function)@\spxentry{krb5\_k\_key\_enctype}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_key_enctype:c.krb5_k_key_enctype}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_key\_enctype}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{key} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_k\_key\_keyblock \sphinxhyphen{} Retrieve a copy of the keyblock from a krb5\_key structure.} \label{\detokenize{appdev/refs/api/krb5_k_key_keyblock:krb5-k-key-keyblock-retrieve-a-copy-of-the-keyblock-from-a-krb5-key-structure}}\label{\detokenize{appdev/refs/api/krb5_k_key_keyblock::doc}}\index{krb5\_k\_key\_keyblock (C function)@\spxentry{krb5\_k\_key\_keyblock}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_key_keyblock:c.krb5_k_key_keyblock}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_key\_keyblock}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{key\_data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{key} \sphinxAtStartPar \sphinxstylestrong{key\_data} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_k\_make\_checksum \sphinxhyphen{} Compute a checksum (operates on opaque key).} \label{\detokenize{appdev/refs/api/krb5_k_make_checksum:krb5-k-make-checksum-compute-a-checksum-operates-on-opaque-key}}\label{\detokenize{appdev/refs/api/krb5_k_make_checksum::doc}}\index{krb5\_k\_make\_checksum (C function)@\spxentry{krb5\_k\_make\_checksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_make_checksum:c.krb5_k_make_checksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_make\_checksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{cksumtype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cksum}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksumtype} \sphinxhyphen{} Checksum type (0 for mandatory type) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key for a keyed checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Input data \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{cksum} \sphinxhyphen{} Generated checksum \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function computes a checksum of type \sphinxstyleemphasis{cksumtype} over \sphinxstyleemphasis{input} , using \sphinxstyleemphasis{key} if the checksum type is a keyed checksum. If \sphinxstyleemphasis{cksumtype} is 0 and \sphinxstyleemphasis{key} is non\sphinxhyphen{}null, the checksum type will be the mandatory\sphinxhyphen{}to\sphinxhyphen{}implement checksum type for the key’s encryption type. The actual checksum key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the checksum type. The newly created \sphinxstyleemphasis{cksum} must be released by calling krb5\_free\_checksum\_contents() when it is no longer needed. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_c\_verify\_checksum() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function is similar to krb5\_c\_make\_checksum(), but operates on opaque \sphinxstyleemphasis{key} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_k\_make\_checksum\_iov \sphinxhyphen{} Fill in a checksum element in IOV array (operates on opaque key)} \label{\detokenize{appdev/refs/api/krb5_k_make_checksum_iov:krb5-k-make-checksum-iov-fill-in-a-checksum-element-in-iov-array-operates-on-opaque-key}}\label{\detokenize{appdev/refs/api/krb5_k_make_checksum_iov::doc}}\index{krb5\_k\_make\_checksum\_iov (C function)@\spxentry{krb5\_k\_make\_checksum\_iov}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_make_checksum_iov:c.krb5_k_make_checksum_iov}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_make\_checksum\_iov}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{cksumtype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{num\_data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksumtype} \sphinxhyphen{} Checksum type (0 for mandatory type) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key for a keyed checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{data} \sphinxhyphen{} IOV array \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_data} \sphinxhyphen{} Size of \sphinxstyleemphasis{data} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Create a checksum in the KRB5\_CRYPTO\_TYPE\_CHECKSUM element over KRB5\_CRYPTO\_TYPE\_DATA and KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY chunks in \sphinxstyleemphasis{data} . Only the KRB5\_CRYPTO\_TYPE\_CHECKSUM region is modified. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_k\_verify\_checksum\_iov() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function is similar to krb5\_c\_make\_checksum\_iov(), but operates on opaque \sphinxstyleemphasis{key} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_k\_prf \sphinxhyphen{} Generate enctype\sphinxhyphen{}specific pseudo\sphinxhyphen{}random bytes (operates on opaque key).} \label{\detokenize{appdev/refs/api/krb5_k_prf:krb5-k-prf-generate-enctype-specific-pseudo-random-bytes-operates-on-opaque-key}}\label{\detokenize{appdev/refs/api/krb5_k_prf::doc}}\index{krb5\_k\_prf (C function)@\spxentry{krb5\_k\_prf}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_prf:c.krb5_k_prf}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_prf}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{input}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{output}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Key \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{input} \sphinxhyphen{} Input data \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{output} \sphinxhyphen{} Output data \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function selects a pseudo\sphinxhyphen{}random function based on \sphinxstyleemphasis{key} and computes its value over \sphinxstyleemphasis{input} , placing the result into \sphinxstyleemphasis{output} . The caller must preinitialize \sphinxstyleemphasis{output} and allocate space for the result. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function is similar to krb5\_c\_prf(), but operates on opaque \sphinxstyleemphasis{key} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_k\_reference\_key \sphinxhyphen{} Increment the reference count on a key.} \label{\detokenize{appdev/refs/api/krb5_k_reference_key:krb5-k-reference-key-increment-the-reference-count-on-a-key}}\label{\detokenize{appdev/refs/api/krb5_k_reference_key::doc}}\index{krb5\_k\_reference\_key (C function)@\spxentry{krb5\_k\_reference\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_reference_key:c.krb5_k_reference_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_reference\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{key} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_k\_verify\_checksum \sphinxhyphen{} Verify a checksum (operates on opaque key).} \label{\detokenize{appdev/refs/api/krb5_k_verify_checksum:krb5-k-verify-checksum-verify-a-checksum-operates-on-opaque-key}}\label{\detokenize{appdev/refs/api/krb5_k_verify_checksum::doc}}\index{krb5\_k\_verify\_checksum (C function)@\spxentry{krb5\_k\_verify\_checksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_verify_checksum:c.krb5_k_verify_checksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_verify\_checksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cksum}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{valid}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key for a keyed checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} \sphinxstyleemphasis{key} usage \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} Data to be used to compute a new checksum using \sphinxstyleemphasis{key} to compare \sphinxstyleemphasis{cksum} against \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksum} \sphinxhyphen{} Checksum to be verified \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{valid} \sphinxhyphen{} Non\sphinxhyphen{}zero for success, zero for failure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function verifies that \sphinxstyleemphasis{cksum} is a valid checksum for \sphinxstyleemphasis{data} . If the checksum type of \sphinxstyleemphasis{cksum} is a keyed checksum, \sphinxstyleemphasis{key} is used to verify the checksum. If the checksum type in \sphinxstyleemphasis{cksum} is 0 and \sphinxstyleemphasis{key} is not NULL, the mandatory checksum type for \sphinxstyleemphasis{key} will be used. The actual checksum key will be derived from \sphinxstyleemphasis{key} and \sphinxstyleemphasis{usage} if key derivation is specified for the checksum type. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function is similar to krb5\_c\_verify\_checksum(), but operates on opaque \sphinxstyleemphasis{key} . \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_k\_verify\_checksum\_iov \sphinxhyphen{} Validate a checksum element in IOV array (operates on opaque key).} \label{\detokenize{appdev/refs/api/krb5_k_verify_checksum_iov:krb5-k-verify-checksum-iov-validate-a-checksum-element-in-iov-array-operates-on-opaque-key}}\label{\detokenize{appdev/refs/api/krb5_k_verify_checksum_iov::doc}}\index{krb5\_k\_verify\_checksum\_iov (C function)@\spxentry{krb5\_k\_verify\_checksum\_iov}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_k_verify_checksum_iov:c.krb5_k_verify_checksum_iov}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_k\_verify\_checksum\_iov}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{cksumtype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_key:c.krb5_key}]{\sphinxcrossref{\DUrole{n}{krb5\_key}}}}\DUrole{w}{ }\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}]{\sphinxcrossref{\DUrole{n}{krb5\_keyusage}}}}\DUrole{w}{ }\DUrole{n}{usage}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{num\_data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{valid}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{cksumtype} \sphinxhyphen{} Checksum type (0 for mandatory type) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{key} \sphinxhyphen{} Encryption key for a keyed checksum \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{usage} \sphinxhyphen{} Key usage (see KRB5\_KEYUSAGE macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{data} \sphinxhyphen{} IOV array \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{num\_data} \sphinxhyphen{} Size of \sphinxstyleemphasis{data} \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{valid} \sphinxhyphen{} Non\sphinxhyphen{}zero for success, zero for failure \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Confirm that the checksum in the KRB5\_CRYPTO\_TYPE\_CHECKSUM element is a valid checksum of the KRB5\_CRYPTO\_TYPE\_DATA and KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY regions in the iov. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_k\_make\_checksum\_iov() \end{sphinxseealso} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar This function is similar to krb5\_c\_verify\_checksum\_iov(), but operates on opaque \sphinxstyleemphasis{key} . \end{sphinxadmonition} \subsection{Legacy convenience interfaces} \label{\detokenize{appdev/refs/api/index:legacy-convenience-interfaces}} \sphinxstepscope \subsubsection{krb5\_recvauth \sphinxhyphen{} Server function for sendauth protocol.} \label{\detokenize{appdev/refs/api/krb5_recvauth:krb5-recvauth-server-function-for-sendauth-protocol}}\label{\detokenize{appdev/refs/api/krb5_recvauth::doc}}\index{krb5\_recvauth (C function)@\spxentry{krb5\_recvauth}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_recvauth:c.krb5_recvauth}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_recvauth}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{n}{fd}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{appl\_version}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{server}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{n}{flags}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ticket}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Pre\sphinxhyphen{}existing or newly created auth context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fd} \sphinxhyphen{} File descriptor \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{appl\_version} \sphinxhyphen{} Application protocol version to be matched against the client’s application version \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Server principal (NULL for any in \sphinxstyleemphasis{keytab} ) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Additional specifications \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Key table containing service keys \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ticket} \sphinxhyphen{} Ticket (NULL if not needed) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function performs the server side of a sendauth/recvauth exchange by sending and receiving messages over \sphinxstyleemphasis{fd} . \sphinxAtStartPar Use krb5\_free\_ticket() to free \sphinxstyleemphasis{ticket} when it is no longer needed. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_sendauth() \end{sphinxseealso} \sphinxstepscope \subsubsection{krb5\_recvauth\_version \sphinxhyphen{} Server function for sendauth protocol with version parameter.} \label{\detokenize{appdev/refs/api/krb5_recvauth_version:krb5-recvauth-version-server-function-for-sendauth-protocol-with-version-parameter}}\label{\detokenize{appdev/refs/api/krb5_recvauth_version::doc}}\index{krb5\_recvauth\_version (C function)@\spxentry{krb5\_recvauth\_version}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_recvauth_version:c.krb5_recvauth_version}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_recvauth\_version}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{n}{fd}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{server}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\DUrole{n}{flags}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ticket}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{version}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Pre\sphinxhyphen{}existing or newly created auth context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fd} \sphinxhyphen{} File descriptor \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Server principal (NULL for any in \sphinxstyleemphasis{keytab} ) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{flags} \sphinxhyphen{} Additional specifications \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{keytab} \sphinxhyphen{} Decryption key \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{ticket} \sphinxhyphen{} Ticket (NULL if not needed) \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{version} \sphinxhyphen{} sendauth protocol version (NULL if not needed) \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function is similar to krb5\_recvauth() with the additional output information place into \sphinxstyleemphasis{version} . \sphinxstepscope \subsubsection{krb5\_sendauth \sphinxhyphen{} Client function for sendauth protocol.} \label{\detokenize{appdev/refs/api/krb5_sendauth:krb5-sendauth-client-function-for-sendauth-protocol}}\label{\detokenize{appdev/refs/api/krb5_sendauth::doc}}\index{krb5\_sendauth (C function)@\spxentry{krb5\_sendauth}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_sendauth:c.krb5_sendauth}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_sendauth}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{n}{fd}\sphinxparamcomma \DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{appl\_version}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{client}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{server}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{ap\_req\_options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_data}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{error}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep\_enc\_part}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{rep\_result}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{out\_creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}inout{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Pre\sphinxhyphen{}existing or newly created auth context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{fd} \sphinxhyphen{} File descriptor that describes network socket \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{appl\_version} \sphinxhyphen{} Application protocol version to be matched with the receiver’s application version \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{client} \sphinxhyphen{} Client principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{server} \sphinxhyphen{} Server principal \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ap\_req\_options} \sphinxhyphen{} Options (see AP\_OPTS macros) \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_data} \sphinxhyphen{} Data to be sent to the server \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{in\_creds} \sphinxhyphen{} Input credentials, or NULL to use \sphinxstyleemphasis{ccache} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{ccache} \sphinxhyphen{} Credential cache \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{error} \sphinxhyphen{} If non\sphinxhyphen{}null, contains KRB\_ERROR message returned from server \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{rep\_result} \sphinxhyphen{} If non\sphinxhyphen{}null and \sphinxstyleemphasis{ap\_req\_options} is AP\_OPTS\_MUTUAL\_REQUIRED, contains the result of mutual authentication exchange \sphinxAtStartPar \sphinxstylestrong{{[}out{]}} \sphinxstylestrong{out\_creds} \sphinxhyphen{} If non\sphinxhyphen{}null, the retrieved credentials \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar This function performs the client side of a sendauth/recvauth exchange by sending and receiving messages over \sphinxstyleemphasis{fd} . \sphinxAtStartPar Credentials may be specified in three ways: \begin{quote} \begin{itemize} \item {} \sphinxAtStartPar If \sphinxstyleemphasis{in\_creds} is NULL, credentials are obtained with krb5\_get\_credentials() using the principals \sphinxstyleemphasis{client} and \sphinxstyleemphasis{server} . \sphinxstyleemphasis{server} must be non\sphinxhyphen{}null; \sphinxstyleemphasis{client} may NULL to use the default principal of \sphinxstyleemphasis{ccache} . \item {} \sphinxAtStartPar If \sphinxstyleemphasis{in\_creds} is non\sphinxhyphen{}null, but does not contain a ticket, credentials for the exchange are obtained with krb5\_get\_credentials() using \sphinxstyleemphasis{in\_creds} . In this case, the values of \sphinxstyleemphasis{client} and \sphinxstyleemphasis{server} are unused. \item {} \sphinxAtStartPar If \sphinxstyleemphasis{in\_creds} is a complete credentials structure, it used directly. In this case, the values of \sphinxstyleemphasis{client} , \sphinxstyleemphasis{server} , and \sphinxstyleemphasis{ccache} are unused. \end{itemize} \sphinxAtStartPar If the server is using a different application protocol than that specified in \sphinxstyleemphasis{appl\_version} , an error will be returned. \end{quote} \sphinxAtStartPar Use krb5\_free\_creds() to free \sphinxstyleemphasis{out\_creds} , krb5\_free\_ap\_rep\_enc\_part() to free \sphinxstyleemphasis{rep\_result} , and krb5\_free\_error() to free \sphinxstyleemphasis{error} when they are no longer needed. \begin{sphinxseealso}{See also:} \sphinxAtStartPar krb5\_recvauth() \end{sphinxseealso} \subsection{Deprecated public interfaces} \label{\detokenize{appdev/refs/api/index:deprecated-public-interfaces}} \sphinxstepscope \subsubsection{krb5\_524\_convert\_creds \sphinxhyphen{} Convert a Kerberos V5 credentials to a Kerberos V4 credentials.} \label{\detokenize{appdev/refs/api/krb5_524_convert_creds:krb5-524-convert-creds-convert-a-kerberos-v5-credentials-to-a-kerberos-v4-credentials}}\label{\detokenize{appdev/refs/api/krb5_524_convert_creds::doc}}\index{krb5\_524\_convert\_creds (C function)@\spxentry{krb5\_524\_convert\_creds}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_524_convert_creds:c.krb5_524_convert_creds}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{int}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_524\_convert\_creds}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{v5creds}\sphinxparamcomma \DUrole{k}{struct}\DUrole{w}{ }\DUrole{n}{credentials}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{v4creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{v5creds} \sphinxAtStartPar \sphinxstylestrong{v4creds} \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar KRB524\_KRB4\_DISABLED (always) \end{itemize} \end{description}\end{quote} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar Not implemented \end{sphinxadmonition} \sphinxstepscope \subsubsection{krb5\_auth\_con\_getlocalsubkey} \label{\detokenize{appdev/refs/api/krb5_auth_con_getlocalsubkey:krb5-auth-con-getlocalsubkey}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getlocalsubkey::doc}}\index{krb5\_auth\_con\_getlocalsubkey (C function)@\spxentry{krb5\_auth\_con\_getlocalsubkey}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getlocalsubkey:c.krb5_auth_con_getlocalsubkey}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getlocalsubkey}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{keyblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{auth\_context} \sphinxAtStartPar \sphinxstylestrong{keyblock} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_auth\_con\_getsendsubkey(). \sphinxstepscope \subsubsection{krb5\_auth\_con\_getremotesubkey} \label{\detokenize{appdev/refs/api/krb5_auth_con_getremotesubkey:krb5-auth-con-getremotesubkey}}\label{\detokenize{appdev/refs/api/krb5_auth_con_getremotesubkey::doc}}\index{krb5\_auth\_con\_getremotesubkey (C function)@\spxentry{krb5\_auth\_con\_getremotesubkey}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_getremotesubkey:c.krb5_auth_con_getremotesubkey}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_getremotesubkey}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{keyblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{auth\_context} \sphinxAtStartPar \sphinxstylestrong{keyblock} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_auth\_con\_getrecvsubkey(). \sphinxstepscope \subsubsection{krb5\_auth\_con\_initivector \sphinxhyphen{} Cause an auth context to use cipher state.} \label{\detokenize{appdev/refs/api/krb5_auth_con_initivector:krb5-auth-con-initivector-cause-an-auth-context-to-use-cipher-state}}\label{\detokenize{appdev/refs/api/krb5_auth_con_initivector::doc}}\index{krb5\_auth\_con\_initivector (C function)@\spxentry{krb5\_auth\_con\_initivector}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_auth_con_initivector:c.krb5_auth_con_initivector}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_con\_initivector}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}]{\sphinxcrossref{\DUrole{n}{krb5\_auth\_context}}}}\DUrole{w}{ }\DUrole{n}{auth\_context}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{context} \sphinxhyphen{} Library context \sphinxAtStartPar \sphinxstylestrong{{[}in{]}} \sphinxstylestrong{auth\_context} \sphinxhyphen{} Authentication context \end{description}\end{quote} \begin{quote}\begin{description} \sphinxlineitem{retval}\begin{itemize} \item {} \sphinxAtStartPar 0 Success; otherwise \sphinxhyphen{} Kerberos error codes \end{itemize} \end{description}\end{quote} \sphinxAtStartPar Prepare \sphinxstyleemphasis{auth\_context} to use cipher state when krb5\_mk\_priv() or krb5\_rd\_priv() encrypt or decrypt data. \sphinxstepscope \subsubsection{krb5\_build\_principal\_va} \label{\detokenize{appdev/refs/api/krb5_build_principal_va:krb5-build-principal-va}}\label{\detokenize{appdev/refs/api/krb5_build_principal_va::doc}}\index{krb5\_build\_principal\_va (C function)@\spxentry{krb5\_build\_principal\_va}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_build_principal_va:c.krb5_build_principal_va}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_build\_principal\_va}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\DUrole{n}{princ}\sphinxparamcomma \DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\DUrole{n}{rlen}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{realm}\sphinxparamcomma \DUrole{n}{va\_list}\DUrole{w}{ }\DUrole{n}{ap}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{princ} \sphinxAtStartPar \sphinxstylestrong{rlen} \sphinxAtStartPar \sphinxstylestrong{realm} \sphinxAtStartPar \sphinxstylestrong{ap} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_build\_principal\_alloc\_va(). \sphinxstepscope \subsubsection{krb5\_c\_random\_seed} \label{\detokenize{appdev/refs/api/krb5_c_random_seed:krb5-c-random-seed}}\label{\detokenize{appdev/refs/api/krb5_c_random_seed::doc}}\index{krb5\_c\_random\_seed (C function)@\spxentry{krb5\_c\_random\_seed}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_c_random_seed:c.krb5_c_random_seed}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_c\_random\_seed}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{data} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED This call is no longer necessary. \sphinxstepscope \subsubsection{krb5\_calculate\_checksum} \label{\detokenize{appdev/refs/api/krb5_calculate_checksum:krb5-calculate-checksum}}\label{\detokenize{appdev/refs/api/krb5_calculate_checksum::doc}}\index{krb5\_calculate\_checksum (C function)@\spxentry{krb5\_calculate\_checksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_calculate_checksum:c.krb5_calculate_checksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_calculate\_checksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{ctype}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_pointer:c.krb5_const_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_pointer}}}}\DUrole{w}{ }\DUrole{n}{in}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{in\_length}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_pointer:c.krb5_const_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_pointer}}}}\DUrole{w}{ }\DUrole{n}{seed}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{seed\_length}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{outcksum}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{ctype} \sphinxAtStartPar \sphinxstylestrong{in} \sphinxAtStartPar \sphinxstylestrong{in\_length} \sphinxAtStartPar \sphinxstylestrong{seed} \sphinxAtStartPar \sphinxstylestrong{seed\_length} \sphinxAtStartPar \sphinxstylestrong{outcksum} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED See krb5\_c\_make\_checksum() \sphinxstepscope \subsubsection{krb5\_checksum\_size} \label{\detokenize{appdev/refs/api/krb5_checksum_size:krb5-checksum-size}}\label{\detokenize{appdev/refs/api/krb5_checksum_size::doc}}\index{krb5\_checksum\_size (C function)@\spxentry{krb5\_checksum\_size}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_checksum_size:c.krb5_checksum_size}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{n}{size\_t}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_checksum\_size}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{ctype}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{ctype} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED See krb5\_c\_checksum\_length() \sphinxstepscope \subsubsection{krb5\_encrypt} \label{\detokenize{appdev/refs/api/krb5_encrypt:krb5-encrypt}}\label{\detokenize{appdev/refs/api/krb5_encrypt::doc}}\index{krb5\_encrypt (C function)@\spxentry{krb5\_encrypt}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_encrypt:c.krb5_encrypt}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_encrypt}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_pointer:c.krb5_const_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_pointer}}}}\DUrole{w}{ }\DUrole{n}{inptr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{n}{outptr}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{size}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{n}{ivec}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{inptr} \sphinxAtStartPar \sphinxstylestrong{outptr} \sphinxAtStartPar \sphinxstylestrong{size} \sphinxAtStartPar \sphinxstylestrong{eblock} \sphinxAtStartPar \sphinxstylestrong{ivec} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_decrypt} \label{\detokenize{appdev/refs/api/krb5_decrypt:krb5-decrypt}}\label{\detokenize{appdev/refs/api/krb5_decrypt::doc}}\index{krb5\_decrypt (C function)@\spxentry{krb5\_decrypt}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_decrypt:c.krb5_decrypt}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_decrypt}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_pointer:c.krb5_const_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_pointer}}}}\DUrole{w}{ }\DUrole{n}{inptr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{n}{outptr}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{size}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{n}{ivec}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{inptr} \sphinxAtStartPar \sphinxstylestrong{outptr} \sphinxAtStartPar \sphinxstylestrong{size} \sphinxAtStartPar \sphinxstylestrong{eblock} \sphinxAtStartPar \sphinxstylestrong{ivec} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_eblock\_enctype} \label{\detokenize{appdev/refs/api/krb5_eblock_enctype:krb5-eblock-enctype}}\label{\detokenize{appdev/refs/api/krb5_eblock_enctype::doc}}\index{krb5\_eblock\_enctype (C function)@\spxentry{krb5\_eblock\_enctype}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_eblock_enctype:c.krb5_eblock_enctype}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_eblock\_enctype}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{eblock} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_encrypt\_size} \label{\detokenize{appdev/refs/api/krb5_encrypt_size:krb5-encrypt-size}}\label{\detokenize{appdev/refs/api/krb5_encrypt_size::doc}}\index{krb5\_encrypt\_size (C function)@\spxentry{krb5\_encrypt\_size}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_encrypt_size:c.krb5_encrypt_size}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{n}{size\_t}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_encrypt\_size}}}}{\DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{length}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{crypto}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{length} \sphinxAtStartPar \sphinxstylestrong{crypto} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_finish\_key} \label{\detokenize{appdev/refs/api/krb5_finish_key:krb5-finish-key}}\label{\detokenize{appdev/refs/api/krb5_finish_key::doc}}\index{krb5\_finish\_key (C function)@\spxentry{krb5\_finish\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_finish_key:c.krb5_finish_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_finish\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{eblock} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_finish\_random\_key} \label{\detokenize{appdev/refs/api/krb5_finish_random_key:krb5-finish-random-key}}\label{\detokenize{appdev/refs/api/krb5_finish_random_key::doc}}\index{krb5\_finish\_random\_key (C function)@\spxentry{krb5\_finish\_random\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_finish_random_key:c.krb5_finish_random_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_finish\_random\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ptr}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{eblock} \sphinxAtStartPar \sphinxstylestrong{ptr} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_cc\_gen\_new} \label{\detokenize{appdev/refs/api/krb5_cc_gen_new:krb5-cc-gen-new}}\label{\detokenize{appdev/refs/api/krb5_cc_gen_new::doc}}\index{krb5\_cc\_gen\_new (C function)@\spxentry{krb5\_cc\_gen\_new}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_cc_gen_new:c.krb5_cc_gen_new}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_gen\_new}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cache}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{cache} \end{description}\end{quote} \sphinxstepscope \subsubsection{krb5\_get\_credentials\_renew} \label{\detokenize{appdev/refs/api/krb5_get_credentials_renew:krb5-get-credentials-renew}}\label{\detokenize{appdev/refs/api/krb5_get_credentials_renew::doc}}\index{krb5\_get\_credentials\_renew (C function)@\spxentry{krb5\_get\_credentials\_renew}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_credentials_renew:c.krb5_get_credentials_renew}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_credentials\_renew}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{out\_creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{options} \sphinxAtStartPar \sphinxstylestrong{ccache} \sphinxAtStartPar \sphinxstylestrong{in\_creds} \sphinxAtStartPar \sphinxstylestrong{out\_creds} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_get\_renewed\_creds. \sphinxstepscope \subsubsection{krb5\_get\_credentials\_validate} \label{\detokenize{appdev/refs/api/krb5_get_credentials_validate:krb5-get-credentials-validate}}\label{\detokenize{appdev/refs/api/krb5_get_credentials_validate::doc}}\index{krb5\_get\_credentials\_validate (C function)@\spxentry{krb5\_get\_credentials\_validate}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_credentials_validate:c.krb5_get_credentials_validate}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_credentials\_validate}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{in\_creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{out\_creds}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{options} \sphinxAtStartPar \sphinxstylestrong{ccache} \sphinxAtStartPar \sphinxstylestrong{in\_creds} \sphinxAtStartPar \sphinxstylestrong{out\_creds} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_get\_validated\_creds. \sphinxstepscope \subsubsection{krb5\_get\_in\_tkt\_with\_password} \label{\detokenize{appdev/refs/api/krb5_get_in_tkt_with_password:krb5-get-in-tkt-with-password}}\label{\detokenize{appdev/refs/api/krb5_get_in_tkt_with_password::doc}}\index{krb5\_get\_in\_tkt\_with\_password (C function)@\spxentry{krb5\_get\_in\_tkt\_with\_password}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_in_tkt_with_password:c.krb5_get_in_tkt_with_password}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_in\_tkt\_with\_password}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{addrs}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ktypes}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_preauthtype:c.krb5_preauthtype}]{\sphinxcrossref{\DUrole{n}{krb5\_preauthtype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pre\_auth\_types}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{password}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ret\_as\_reply}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{options} \sphinxAtStartPar \sphinxstylestrong{addrs} \sphinxAtStartPar \sphinxstylestrong{ktypes} \sphinxAtStartPar \sphinxstylestrong{pre\_auth\_types} \sphinxAtStartPar \sphinxstylestrong{password} \sphinxAtStartPar \sphinxstylestrong{ccache} \sphinxAtStartPar \sphinxstylestrong{creds} \sphinxAtStartPar \sphinxstylestrong{ret\_as\_reply} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_get\_init\_creds\_password(). \sphinxstepscope \subsubsection{krb5\_get\_in\_tkt\_with\_skey} \label{\detokenize{appdev/refs/api/krb5_get_in_tkt_with_skey:krb5-get-in-tkt-with-skey}}\label{\detokenize{appdev/refs/api/krb5_get_in_tkt_with_skey::doc}}\index{krb5\_get\_in\_tkt\_with\_skey (C function)@\spxentry{krb5\_get\_in\_tkt\_with\_skey}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_in_tkt_with_skey:c.krb5_get_in_tkt_with_skey}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_in\_tkt\_with\_skey}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{addrs}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ktypes}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_preauthtype:c.krb5_preauthtype}]{\sphinxcrossref{\DUrole{n}{krb5\_preauthtype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pre\_auth\_types}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ret\_as\_reply}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{options} \sphinxAtStartPar \sphinxstylestrong{addrs} \sphinxAtStartPar \sphinxstylestrong{ktypes} \sphinxAtStartPar \sphinxstylestrong{pre\_auth\_types} \sphinxAtStartPar \sphinxstylestrong{key} \sphinxAtStartPar \sphinxstylestrong{ccache} \sphinxAtStartPar \sphinxstylestrong{creds} \sphinxAtStartPar \sphinxstylestrong{ret\_as\_reply} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_get\_init\_creds(). \sphinxstepscope \subsubsection{krb5\_get\_in\_tkt\_with\_keytab} \label{\detokenize{appdev/refs/api/krb5_get_in_tkt_with_keytab:krb5-get-in-tkt-with-keytab}}\label{\detokenize{appdev/refs/api/krb5_get_in_tkt_with_keytab::doc}}\index{krb5\_get\_in\_tkt\_with\_keytab (C function)@\spxentry{krb5\_get\_in\_tkt\_with\_keytab}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_in_tkt_with_keytab:c.krb5_get_in_tkt_with_keytab}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_in\_tkt\_with\_keytab}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\DUrole{n}{options}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{k}{const}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{addrs}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ktypes}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_preauthtype:c.krb5_preauthtype}]{\sphinxcrossref{\DUrole{n}{krb5\_preauthtype}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{pre\_auth\_types}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab}}}}\DUrole{w}{ }\DUrole{n}{arg\_keytab}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}]{\sphinxcrossref{\DUrole{n}{krb5\_ccache}}}}\DUrole{w}{ }\DUrole{n}{ccache}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{creds}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{ret\_as\_reply}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{options} \sphinxAtStartPar \sphinxstylestrong{addrs} \sphinxAtStartPar \sphinxstylestrong{ktypes} \sphinxAtStartPar \sphinxstylestrong{pre\_auth\_types} \sphinxAtStartPar \sphinxstylestrong{arg\_keytab} \sphinxAtStartPar \sphinxstylestrong{ccache} \sphinxAtStartPar \sphinxstylestrong{creds} \sphinxAtStartPar \sphinxstylestrong{ret\_as\_reply} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_get\_init\_creds\_keytab(). \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt\_init} \label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_init:krb5-get-init-creds-opt-init}}\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_init::doc}}\index{krb5\_get\_init\_creds\_opt\_init (C function)@\spxentry{krb5\_get\_init\_creds\_opt\_init}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_get_init_creds_opt_init:c.krb5_get_init_creds_opt_init}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{\DUrole{kt}{void}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt\_init}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{opt}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{opt} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Use krb5\_get\_init\_creds\_opt\_alloc() instead. \sphinxstepscope \subsubsection{krb5\_init\_random\_key} \label{\detokenize{appdev/refs/api/krb5_init_random_key:krb5-init-random-key}}\label{\detokenize{appdev/refs/api/krb5_init_random_key::doc}}\index{krb5\_init\_random\_key (C function)@\spxentry{krb5\_init\_random\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_init_random_key:c.krb5_init_random_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_random\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keyblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{ptr}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{eblock} \sphinxAtStartPar \sphinxstylestrong{keyblock} \sphinxAtStartPar \sphinxstylestrong{ptr} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_kt\_free\_entry} \label{\detokenize{appdev/refs/api/krb5_kt_free_entry:krb5-kt-free-entry}}\label{\detokenize{appdev/refs/api/krb5_kt_free_entry::doc}}\index{krb5\_kt\_free\_entry (C function)@\spxentry{krb5\_kt\_free\_entry}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_kt_free_entry:c.krb5_kt_free_entry}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_free\_entry}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{entry}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{entry} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Use krb5\_free\_keytab\_entry\_contents instead. \sphinxstepscope \subsubsection{krb5\_random\_key} \label{\detokenize{appdev/refs/api/krb5_random_key:krb5-random-key}}\label{\detokenize{appdev/refs/api/krb5_random_key::doc}}\index{krb5\_random\_key (C function)@\spxentry{krb5\_random\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_random_key:c.krb5_random_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_random\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_pointer}}}}\DUrole{w}{ }\DUrole{n}{ptr}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\DUrole{n}{keyblock}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{eblock} \sphinxAtStartPar \sphinxstylestrong{ptr} \sphinxAtStartPar \sphinxstylestrong{keyblock} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_process\_key} \label{\detokenize{appdev/refs/api/krb5_process_key:krb5-process-key}}\label{\detokenize{appdev/refs/api/krb5_process_key::doc}}\index{krb5\_process\_key (C function)@\spxentry{krb5\_process\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_process_key:c.krb5_process_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_process\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{key}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{eblock} \sphinxAtStartPar \sphinxstylestrong{key} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_string\_to\_key} \label{\detokenize{appdev/refs/api/krb5_string_to_key:krb5-string-to-key}}\label{\detokenize{appdev/refs/api/krb5_string_to_key::doc}}\index{krb5\_string\_to\_key (C function)@\spxentry{krb5\_string\_to\_key}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_string_to_key:c.krb5_string_to_key}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_string\_to\_key}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{keyblock}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{data}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{salt}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{eblock} \sphinxAtStartPar \sphinxstylestrong{keyblock} \sphinxAtStartPar \sphinxstylestrong{data} \sphinxAtStartPar \sphinxstylestrong{salt} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED See krb5\_c\_string\_to\_key() \sphinxstepscope \subsubsection{krb5\_use\_enctype} \label{\detokenize{appdev/refs/api/krb5_use_enctype:krb5-use-enctype}}\label{\detokenize{appdev/refs/api/krb5_use_enctype::doc}}\index{krb5\_use\_enctype (C function)@\spxentry{krb5\_use\_enctype}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_use_enctype:c.krb5_use_enctype}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_use\_enctype}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{eblock}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{n}{enctype}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{eblock} \sphinxAtStartPar \sphinxstylestrong{enctype} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED Replaced by krb5\_c\_* API family. \sphinxstepscope \subsubsection{krb5\_verify\_checksum} \label{\detokenize{appdev/refs/api/krb5_verify_checksum:krb5-verify-checksum}}\label{\detokenize{appdev/refs/api/krb5_verify_checksum::doc}}\index{krb5\_verify\_checksum (C function)@\spxentry{krb5\_verify\_checksum}\spxextra{C function}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/api/krb5_verify_checksum:c.krb5_verify_checksum}} \pysigstartsignatures \pysigstartmultiline \pysiglinewithargsret{{\hyperref[\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}]{\sphinxcrossref{\DUrole{n}{krb5\_error\_code}}}}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_verify\_checksum}}}}{{\hyperref[\detokenize{appdev/refs/types/krb5_context:c.krb5_context}]{\sphinxcrossref{\DUrole{n}{krb5\_context}}}}\DUrole{w}{ }\DUrole{n}{context}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\DUrole{n}{ctype}\sphinxparamcomma \DUrole{k}{const}\DUrole{w}{ }{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{n}{cksum}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_pointer:c.krb5_const_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_pointer}}}}\DUrole{w}{ }\DUrole{n}{in}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{in\_length}\sphinxparamcomma {\hyperref[\detokenize{appdev/refs/types/krb5_const_pointer:c.krb5_const_pointer}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_pointer}}}}\DUrole{w}{ }\DUrole{n}{seed}\sphinxparamcomma \DUrole{n}{size\_t}\DUrole{w}{ }\DUrole{n}{seed\_length}}{} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \begin{quote}\begin{description} \sphinxlineitem{param} \sphinxAtStartPar \sphinxstylestrong{context} \sphinxAtStartPar \sphinxstylestrong{ctype} \sphinxAtStartPar \sphinxstylestrong{cksum} \sphinxAtStartPar \sphinxstylestrong{in} \sphinxAtStartPar \sphinxstylestrong{in\_length} \sphinxAtStartPar \sphinxstylestrong{seed} \sphinxAtStartPar \sphinxstylestrong{seed\_length} \end{description}\end{quote} \sphinxAtStartPar DEPRECATED See krb5\_c\_verify\_checksum() \sphinxstepscope \section{krb5 types and structures} \label{\detokenize{appdev/refs/types/index:krb5-types-and-structures}}\label{\detokenize{appdev/refs/types/index::doc}} \subsection{Public} \label{\detokenize{appdev/refs/types/index:public}} \sphinxstepscope \subsubsection{krb5\_address} \label{\detokenize{appdev/refs/types/krb5_address:krb5-address}}\label{\detokenize{appdev/refs/types/krb5_address:krb5-address-struct}}\label{\detokenize{appdev/refs/types/krb5_address::doc}}\index{krb5\_address (C type)@\spxentry{krb5\_address}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_address:c.krb5_address}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_address}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Structure for address. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_address:declaration}} \sphinxAtStartPar typedef struct \_krb5\_address krb5\_address \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_address:members}}\index{krb5\_address.magic (C member)@\spxentry{krb5\_address.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_address:c.krb5_address.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_address.addrtype (C member)@\spxentry{krb5\_address.addrtype}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_address:c.krb5_address.addrtype}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_addrtype:c.krb5_addrtype}]{\sphinxcrossref{\DUrole{n}{krb5\_addrtype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{addrtype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_address.length (C member)@\spxentry{krb5\_address.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_address:c.krb5_address.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_address.contents (C member)@\spxentry{krb5\_address.contents}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_address:c.krb5_address.contents}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_octet:c.krb5_octet}]{\sphinxcrossref{\DUrole{n}{krb5\_octet}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{contents}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_addrtype} \label{\detokenize{appdev/refs/types/krb5_addrtype:krb5-addrtype}}\label{\detokenize{appdev/refs/types/krb5_addrtype:krb5-addrtype-struct}}\label{\detokenize{appdev/refs/types/krb5_addrtype::doc}}\index{krb5\_addrtype (C type)@\spxentry{krb5\_addrtype}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_addrtype:c.krb5_addrtype}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_addrtype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_addrtype:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_addrtype \sphinxstepscope \subsubsection{krb5\_ap\_req} \label{\detokenize{appdev/refs/types/krb5_ap_req:krb5-ap-req}}\label{\detokenize{appdev/refs/types/krb5_ap_req:krb5-ap-req-struct}}\label{\detokenize{appdev/refs/types/krb5_ap_req::doc}}\index{krb5\_ap\_req (C type)@\spxentry{krb5\_ap\_req}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_req:c.krb5_ap_req}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_ap\_req}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Authentication header. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_ap_req:declaration}} \sphinxAtStartPar typedef struct \_krb5\_ap\_req krb5\_ap\_req \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_ap_req:members}}\index{krb5\_ap\_req.magic (C member)@\spxentry{krb5\_ap\_req.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_req:c.krb5_ap_req.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_req:c.krb5_ap_req}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_ap\_req.ap\_options (C member)@\spxentry{krb5\_ap\_req.ap\_options}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_req:c.krb5_ap_req.ap_options}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_req:c.krb5_ap_req}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ap\_options}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Requested options. \end{fulllineitems} \index{krb5\_ap\_req.ticket (C member)@\spxentry{krb5\_ap\_req.ticket}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_req:c.krb5_ap_req.ticket}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_req:c.krb5_ap_req}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ticket}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Ticket. \end{fulllineitems} \index{krb5\_ap\_req.authenticator (C member)@\spxentry{krb5\_ap\_req.authenticator}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_req:c.krb5_ap_req.authenticator}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_req:c.krb5_ap_req}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{authenticator}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Encrypted authenticator. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_ap\_rep} \label{\detokenize{appdev/refs/types/krb5_ap_rep:krb5-ap-rep}}\label{\detokenize{appdev/refs/types/krb5_ap_rep:krb5-ap-rep-struct}}\label{\detokenize{appdev/refs/types/krb5_ap_rep::doc}}\index{krb5\_ap\_rep (C type)@\spxentry{krb5\_ap\_rep}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_rep:c.krb5_ap_rep}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_ap\_rep}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar C representaton of AP\sphinxhyphen{}REP message. \sphinxAtStartPar The server’s response to a client’s request for mutual authentication. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_ap_rep:declaration}} \sphinxAtStartPar typedef struct \_krb5\_ap\_rep krb5\_ap\_rep \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_ap_rep:members}}\index{krb5\_ap\_rep.magic (C member)@\spxentry{krb5\_ap\_rep.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_rep:c.krb5_ap_rep.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep:c.krb5_ap_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_ap\_rep.enc\_part (C member)@\spxentry{krb5\_ap\_rep.enc\_part}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_rep:c.krb5_ap_rep.enc_part}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep:c.krb5_ap_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enc\_part}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Ciphertext of ApRepEncPart. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_ap\_rep\_enc\_part} \label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:krb5-ap-rep-enc-part}}\label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:krb5-ap-rep-enc-part-struct}}\label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part::doc}}\index{krb5\_ap\_rep\_enc\_part (C type)@\spxentry{krb5\_ap\_rep\_enc\_part}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_ap\_rep\_enc\_part}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Cleartext that is encrypted and put into \sphinxcode{\sphinxupquote{\_krb5\_ap\_rep}} . \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:declaration}} \sphinxAtStartPar typedef struct \_krb5\_ap\_rep\_enc\_part krb5\_ap\_rep\_enc\_part \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:members}}\index{krb5\_ap\_rep\_enc\_part.magic (C member)@\spxentry{krb5\_ap\_rep\_enc\_part.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_ap\_rep\_enc\_part.ctime (C member)@\spxentry{krb5\_ap\_rep\_enc\_part.ctime}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part.ctime}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ctime}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Client time, seconds portion. \end{fulllineitems} \index{krb5\_ap\_rep\_enc\_part.cusec (C member)@\spxentry{krb5\_ap\_rep\_enc\_part.cusec}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part.cusec}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{cusec}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Client time, microseconds portion. \end{fulllineitems} \index{krb5\_ap\_rep\_enc\_part.subkey (C member)@\spxentry{krb5\_ap\_rep\_enc\_part.subkey}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part.subkey}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{subkey}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Subkey (optional) \end{fulllineitems} \index{krb5\_ap\_rep\_enc\_part.seq\_number (C member)@\spxentry{krb5\_ap\_rep\_enc\_part.seq\_number}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part.seq_number}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ui_4:c.krb5_ui_4}]{\sphinxcrossref{\DUrole{n}{krb5\_ui\_4}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ap_rep_enc_part:c.krb5_ap_rep_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_ap\_rep\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{seq\_number}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Sequence number. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_authdata} \label{\detokenize{appdev/refs/types/krb5_authdata:krb5-authdata}}\label{\detokenize{appdev/refs/types/krb5_authdata:krb5-authdata-struct}}\label{\detokenize{appdev/refs/types/krb5_authdata::doc}}\index{krb5\_authdata (C type)@\spxentry{krb5\_authdata}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_authdata}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Structure for auth data. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_authdata:declaration}} \sphinxAtStartPar typedef struct \_krb5\_authdata krb5\_authdata \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_authdata:members}}\index{krb5\_authdata.magic (C member)@\spxentry{krb5\_authdata.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_authdata.ad\_type (C member)@\spxentry{krb5\_authdata.ad\_type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata.ad_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_authdatatype:c.krb5_authdatatype}]{\sphinxcrossref{\DUrole{n}{krb5\_authdatatype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ad\_type}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar ADTYPE. \end{fulllineitems} \index{krb5\_authdata.length (C member)@\spxentry{krb5\_authdata.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Length of data. \end{fulllineitems} \index{krb5\_authdata.contents (C member)@\spxentry{krb5\_authdata.contents}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata.contents}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_octet:c.krb5_octet}]{\sphinxcrossref{\DUrole{n}{krb5\_octet}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{contents}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Data. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_authdatatype} \label{\detokenize{appdev/refs/types/krb5_authdatatype:krb5-authdatatype}}\label{\detokenize{appdev/refs/types/krb5_authdatatype:krb5-authdatatype-struct}}\label{\detokenize{appdev/refs/types/krb5_authdatatype::doc}}\index{krb5\_authdatatype (C type)@\spxentry{krb5\_authdatatype}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authdatatype:c.krb5_authdatatype}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_authdatatype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_authdatatype:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_authdatatype \sphinxstepscope \subsubsection{krb5\_authenticator} \label{\detokenize{appdev/refs/types/krb5_authenticator:krb5-authenticator}}\label{\detokenize{appdev/refs/types/krb5_authenticator:krb5-authenticator-struct}}\label{\detokenize{appdev/refs/types/krb5_authenticator::doc}}\index{krb5\_authenticator (C type)@\spxentry{krb5\_authenticator}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_authenticator}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Ticket authenticator. \sphinxAtStartPar The C representation of an unencrypted authenticator. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_authenticator:declaration}} \sphinxAtStartPar typedef struct \_krb5\_authenticator krb5\_authenticator \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_authenticator:members}}\index{krb5\_authenticator.magic (C member)@\spxentry{krb5\_authenticator.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_authenticator.client (C member)@\spxentry{krb5\_authenticator.client}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator.client}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{client}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar client name/realm \end{fulllineitems} \index{krb5\_authenticator.checksum (C member)@\spxentry{krb5\_authenticator.checksum}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator.checksum}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{checksum}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar checksum, includes type, optional \end{fulllineitems} \index{krb5\_authenticator.cusec (C member)@\spxentry{krb5\_authenticator.cusec}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator.cusec}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{cusec}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar client usec portion \end{fulllineitems} \index{krb5\_authenticator.ctime (C member)@\spxentry{krb5\_authenticator.ctime}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator.ctime}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ctime}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar client sec portion \end{fulllineitems} \index{krb5\_authenticator.subkey (C member)@\spxentry{krb5\_authenticator.subkey}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator.subkey}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{subkey}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar true session key, optional \end{fulllineitems} \index{krb5\_authenticator.seq\_number (C member)@\spxentry{krb5\_authenticator.seq\_number}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator.seq_number}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ui_4:c.krb5_ui_4}]{\sphinxcrossref{\DUrole{n}{krb5\_ui\_4}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{seq\_number}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar sequence \#, optional \end{fulllineitems} \index{krb5\_authenticator.authorization\_data (C member)@\spxentry{krb5\_authenticator.authorization\_data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator.authorization_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{authorization\_data}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar authoriazation data \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_boolean} \label{\detokenize{appdev/refs/types/krb5_boolean:krb5-boolean}}\label{\detokenize{appdev/refs/types/krb5_boolean:krb5-boolean-struct}}\label{\detokenize{appdev/refs/types/krb5_boolean::doc}}\index{krb5\_boolean (C type)@\spxentry{krb5\_boolean}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_boolean}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_boolean:declaration}} \sphinxAtStartPar typedef unsigned int krb5\_boolean \sphinxstepscope \subsubsection{krb5\_checksum} \label{\detokenize{appdev/refs/types/krb5_checksum:krb5-checksum}}\label{\detokenize{appdev/refs/types/krb5_checksum:krb5-checksum-struct}}\label{\detokenize{appdev/refs/types/krb5_checksum::doc}}\index{krb5\_checksum (C type)@\spxentry{krb5\_checksum}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_checksum}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_checksum:declaration}} \sphinxAtStartPar typedef struct \_krb5\_checksum krb5\_checksum \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_checksum:members}}\index{krb5\_checksum.magic (C member)@\spxentry{krb5\_checksum.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_checksum.checksum\_type (C member)@\spxentry{krb5\_checksum.checksum\_type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum.checksum_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}]{\sphinxcrossref{\DUrole{n}{krb5\_cksumtype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{checksum\_type}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_checksum.length (C member)@\spxentry{krb5\_checksum.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_checksum.contents (C member)@\spxentry{krb5\_checksum.contents}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum.contents}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_octet:c.krb5_octet}]{\sphinxcrossref{\DUrole{n}{krb5\_octet}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{contents}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_const\_pointer} \label{\detokenize{appdev/refs/types/krb5_const_pointer:krb5-const-pointer}}\label{\detokenize{appdev/refs/types/krb5_const_pointer:krb5-const-pointer-struct}}\label{\detokenize{appdev/refs/types/krb5_const_pointer::doc}}\index{krb5\_const\_pointer (C type)@\spxentry{krb5\_const\_pointer}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_const_pointer:c.krb5_const_pointer}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_const\_pointer}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_const_pointer:declaration}} \sphinxAtStartPar typedef void const* krb5\_const\_pointer \sphinxstepscope \subsubsection{krb5\_const\_principal} \label{\detokenize{appdev/refs/types/krb5_const_principal:krb5-const-principal}}\label{\detokenize{appdev/refs/types/krb5_const_principal:krb5-const-principal-struct}}\label{\detokenize{appdev/refs/types/krb5_const_principal::doc}}\index{krb5\_const\_principal (C type)@\spxentry{krb5\_const\_principal}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_const\_principal}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Constant version of {\hyperref[\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{krb5\_principal\_data}}}}} . \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_const_principal:declaration}} \sphinxAtStartPar typedef const krb5\_principal\_data* krb5\_const\_principal \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_const_principal:members}}\index{krb5\_const\_principal.magic (C member)@\spxentry{krb5\_const\_principal.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_const\_principal.realm (C member)@\spxentry{krb5\_const\_principal.realm}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal.realm}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{realm}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_const\_principal.data (C member)@\spxentry{krb5\_const\_principal.data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal.data}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{data}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar An array of strings. \end{fulllineitems} \index{krb5\_const\_principal.length (C member)@\spxentry{krb5\_const\_principal.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_const\_principal.type (C member)@\spxentry{krb5\_const\_principal.type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal.type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_const_principal:c.krb5_const_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_const\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{type}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_cred} \label{\detokenize{appdev/refs/types/krb5_cred:krb5-cred}}\label{\detokenize{appdev/refs/types/krb5_cred:krb5-cred-struct}}\label{\detokenize{appdev/refs/types/krb5_cred::doc}}\index{krb5\_cred (C type)@\spxentry{krb5\_cred}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred:c.krb5_cred}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cred}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Credentials data structure. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_cred:declaration}} \sphinxAtStartPar typedef struct \_krb5\_cred krb5\_cred \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_cred:members}}\index{krb5\_cred.magic (C member)@\spxentry{krb5\_cred.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred:c.krb5_cred.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred:c.krb5_cred}]{\sphinxcrossref{\DUrole{n}{krb5\_cred}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_cred.tickets (C member)@\spxentry{krb5\_cred.tickets}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred:c.krb5_cred.tickets}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred:c.krb5_cred}]{\sphinxcrossref{\DUrole{n}{krb5\_cred}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{tickets}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Tickets. \end{fulllineitems} \index{krb5\_cred.enc\_part (C member)@\spxentry{krb5\_cred.enc\_part}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred:c.krb5_cred.enc_part}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred:c.krb5_cred}]{\sphinxcrossref{\DUrole{n}{krb5\_cred}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enc\_part}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Encrypted part. \end{fulllineitems} \index{krb5\_cred.enc\_part2 (C member)@\spxentry{krb5\_cred.enc\_part2}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred:c.krb5_cred.enc_part2}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_enc\_part}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred:c.krb5_cred}]{\sphinxcrossref{\DUrole{n}{krb5\_cred}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enc\_part2}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Unencrypted version, if available. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_cred\_enc\_part} \label{\detokenize{appdev/refs/types/krb5_cred_enc_part:krb5-cred-enc-part}}\label{\detokenize{appdev/refs/types/krb5_cred_enc_part:krb5-cred-enc-part-struct}}\label{\detokenize{appdev/refs/types/krb5_cred_enc_part::doc}}\index{krb5\_cred\_enc\_part (C type)@\spxentry{krb5\_cred\_enc\_part}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cred\_enc\_part}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Cleartext credentials information. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_cred_enc_part:declaration}} \sphinxAtStartPar typedef struct \_krb5\_cred\_enc\_part krb5\_cred\_enc\_part \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_cred_enc_part:members}}\index{krb5\_cred\_enc\_part.magic (C member)@\spxentry{krb5\_cred\_enc\_part.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_cred\_enc\_part.nonce (C member)@\spxentry{krb5\_cred\_enc\_part.nonce}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part.nonce}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{nonce}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Nonce (optional) \end{fulllineitems} \index{krb5\_cred\_enc\_part.timestamp (C member)@\spxentry{krb5\_cred\_enc\_part.timestamp}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part.timestamp}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{timestamp}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Generation time, seconds portion. \end{fulllineitems} \index{krb5\_cred\_enc\_part.usec (C member)@\spxentry{krb5\_cred\_enc\_part.usec}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part.usec}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{usec}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Generation time, microseconds portion. \end{fulllineitems} \index{krb5\_cred\_enc\_part.s\_address (C member)@\spxentry{krb5\_cred\_enc\_part.s\_address}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part.s_address}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{s\_address}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Sender address (optional) \end{fulllineitems} \index{krb5\_cred\_enc\_part.r\_address (C member)@\spxentry{krb5\_cred\_enc\_part.r\_address}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part.r_address}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{r\_address}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Recipient address (optional) \end{fulllineitems} \index{krb5\_cred\_enc\_part.ticket\_info (C member)@\spxentry{krb5\_cred\_enc\_part.ticket\_info}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part.ticket_info}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_info}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_enc_part:c.krb5_cred_enc_part}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_enc\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ticket\_info}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_cred\_info} \label{\detokenize{appdev/refs/types/krb5_cred_info:krb5-cred-info}}\label{\detokenize{appdev/refs/types/krb5_cred_info:krb5-cred-info-struct}}\label{\detokenize{appdev/refs/types/krb5_cred_info::doc}}\index{krb5\_cred\_info (C type)@\spxentry{krb5\_cred\_info}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cred\_info}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Credentials information inserted into \sphinxstyleemphasis{EncKrbCredPart} . \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_cred_info:declaration}} \sphinxAtStartPar typedef struct \_krb5\_cred\_info krb5\_cred\_info \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_cred_info:members}}\index{krb5\_cred\_info.magic (C member)@\spxentry{krb5\_cred\_info.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_info}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_cred\_info.session (C member)@\spxentry{krb5\_cred\_info.session}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info.session}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_info}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{session}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Session key used to encrypt ticket. \end{fulllineitems} \index{krb5\_cred\_info.client (C member)@\spxentry{krb5\_cred\_info.client}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info.client}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_info}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{client}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Client principal and realm. \end{fulllineitems} \index{krb5\_cred\_info.server (C member)@\spxentry{krb5\_cred\_info.server}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info.server}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_info}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{server}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Server principal and realm. \end{fulllineitems} \index{krb5\_cred\_info.flags (C member)@\spxentry{krb5\_cred\_info.flags}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info.flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_info}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{flags}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Ticket flags. \end{fulllineitems} \index{krb5\_cred\_info.times (C member)@\spxentry{krb5\_cred\_info.times}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info.times}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_info}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{times}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Auth, start, end, renew\_till. \end{fulllineitems} \index{krb5\_cred\_info.caddrs (C member)@\spxentry{krb5\_cred\_info.caddrs}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info.caddrs}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_cred_info:c.krb5_cred_info}]{\sphinxcrossref{\DUrole{n}{krb5\_cred\_info}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{caddrs}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Array of pointers to addrs (optional) \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_creds} \label{\detokenize{appdev/refs/types/krb5_creds:krb5-creds}}\label{\detokenize{appdev/refs/types/krb5_creds:krb5-creds-struct}}\label{\detokenize{appdev/refs/types/krb5_creds::doc}}\index{krb5\_creds (C type)@\spxentry{krb5\_creds}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_creds}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Credentials structure including ticket, session key, and lifetime info. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_creds:declaration}} \sphinxAtStartPar typedef struct \_krb5\_creds krb5\_creds \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_creds:members}}\index{krb5\_creds.magic (C member)@\spxentry{krb5\_creds.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_creds.client (C member)@\spxentry{krb5\_creds.client}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.client}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{client}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar client’s principal identifier \end{fulllineitems} \index{krb5\_creds.server (C member)@\spxentry{krb5\_creds.server}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.server}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{server}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar server’s principal identifier \end{fulllineitems} \index{krb5\_creds.keyblock (C member)@\spxentry{krb5\_creds.keyblock}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.keyblock}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{keyblock}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar session encryption key info \end{fulllineitems} \index{krb5\_creds.times (C member)@\spxentry{krb5\_creds.times}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.times}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{times}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar lifetime info \end{fulllineitems} \index{krb5\_creds.is\_skey (C member)@\spxentry{krb5\_creds.is\_skey}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.is_skey}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{is\_skey}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar true if ticket is encrypted in another ticket’s skey \end{fulllineitems} \index{krb5\_creds.ticket\_flags (C member)@\spxentry{krb5\_creds.ticket\_flags}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.ticket_flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ticket\_flags}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar flags in ticket \end{fulllineitems} \index{krb5\_creds.addresses (C member)@\spxentry{krb5\_creds.addresses}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.addresses}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{addresses}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar addrs in ticket \end{fulllineitems} \index{krb5\_creds.ticket (C member)@\spxentry{krb5\_creds.ticket}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.ticket}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ticket}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar ticket string itself \end{fulllineitems} \index{krb5\_creds.second\_ticket (C member)@\spxentry{krb5\_creds.second\_ticket}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.second_ticket}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{second\_ticket}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar second ticket, if related to ticket (via DUPLICATE\sphinxhyphen{}SKEY or ENC\sphinxhyphen{}TKT\sphinxhyphen{}IN\sphinxhyphen{}SKEY) \end{fulllineitems} \index{krb5\_creds.authdata (C member)@\spxentry{krb5\_creds.authdata}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds.authdata}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_creds:c.krb5_creds}]{\sphinxcrossref{\DUrole{n}{krb5\_creds}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{authdata}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar authorization data \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_crypto\_iov} \label{\detokenize{appdev/refs/types/krb5_crypto_iov:krb5-crypto-iov}}\label{\detokenize{appdev/refs/types/krb5_crypto_iov:krb5-crypto-iov-struct}}\label{\detokenize{appdev/refs/types/krb5_crypto_iov::doc}}\index{krb5\_crypto\_iov (C type)@\spxentry{krb5\_crypto\_iov}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_crypto\_iov}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Structure to describe a region of text to be encrypted or decrypted. \sphinxAtStartPar The \sphinxstyleemphasis{flags} member describes the type of the iov. The \sphinxstyleemphasis{data} member points to the memory that will be manipulated. All iov APIs take a pointer to the first element of an array of krb5\_crypto\_iov’s along with the size of that array. Buffer contents are manipulated in\sphinxhyphen{}place; data is overwritten. Callers must allocate the right number of krb5\_crypto\_iov structures before calling into an iov API. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_crypto_iov:declaration}} \sphinxAtStartPar typedef struct \_krb5\_crypto\_iov krb5\_crypto\_iov \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_crypto_iov:members}}\index{krb5\_crypto\_iov.flags (C member)@\spxentry{krb5\_crypto\_iov.flags}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov.flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_cryptotype:c.krb5_cryptotype}]{\sphinxcrossref{\DUrole{n}{krb5\_cryptotype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{flags}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar iov type (see KRB5\_CRYPTO\_TYPE macros) \end{fulllineitems} \index{krb5\_crypto\_iov.data (C member)@\spxentry{krb5\_crypto\_iov.data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov.data}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_crypto_iov:c.krb5_crypto_iov}]{\sphinxcrossref{\DUrole{n}{krb5\_crypto\_iov}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_cryptotype} \label{\detokenize{appdev/refs/types/krb5_cryptotype:krb5-cryptotype}}\label{\detokenize{appdev/refs/types/krb5_cryptotype:krb5-cryptotype-struct}}\label{\detokenize{appdev/refs/types/krb5_cryptotype::doc}}\index{krb5\_cryptotype (C type)@\spxentry{krb5\_cryptotype}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cryptotype:c.krb5_cryptotype}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cryptotype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_cryptotype:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_cryptotype \sphinxstepscope \subsubsection{krb5\_data} \label{\detokenize{appdev/refs/types/krb5_data:krb5-data}}\label{\detokenize{appdev/refs/types/krb5_data:krb5-data-struct}}\label{\detokenize{appdev/refs/types/krb5_data::doc}}\index{krb5\_data (C type)@\spxentry{krb5\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_data:c.krb5_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_data:declaration}} \sphinxAtStartPar typedef struct \_krb5\_data krb5\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_data:members}}\index{krb5\_data.magic (C member)@\spxentry{krb5\_data.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_data:c.krb5_data.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_data.length (C member)@\spxentry{krb5\_data.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_data:c.krb5_data.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_data.data (C member)@\spxentry{krb5\_data.data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_data:c.krb5_data.data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_deltat} \label{\detokenize{appdev/refs/types/krb5_deltat:krb5-deltat}}\label{\detokenize{appdev/refs/types/krb5_deltat:krb5-deltat-struct}}\label{\detokenize{appdev/refs/types/krb5_deltat::doc}}\index{krb5\_deltat (C type)@\spxentry{krb5\_deltat}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_deltat}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_deltat:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_deltat \sphinxstepscope \subsubsection{krb5\_enc\_data} \label{\detokenize{appdev/refs/types/krb5_enc_data:krb5-enc-data}}\label{\detokenize{appdev/refs/types/krb5_enc_data:krb5-enc-data-struct}}\label{\detokenize{appdev/refs/types/krb5_enc_data::doc}}\index{krb5\_enc\_data (C type)@\spxentry{krb5\_enc\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_enc\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_enc_data:declaration}} \sphinxAtStartPar typedef struct \_krb5\_enc\_data krb5\_enc\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_enc_data:members}}\index{krb5\_enc\_data.magic (C member)@\spxentry{krb5\_enc\_data.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_enc\_data.enctype (C member)@\spxentry{krb5\_enc\_data.enctype}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data.enctype}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enctype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_enc\_data.kvno (C member)@\spxentry{krb5\_enc\_data.kvno}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data.kvno}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_kvno:c.krb5_kvno}]{\sphinxcrossref{\DUrole{n}{krb5\_kvno}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{kvno}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_enc\_data.ciphertext (C member)@\spxentry{krb5\_enc\_data.ciphertext}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data.ciphertext}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ciphertext}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_enc\_kdc\_rep\_part} \label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:krb5-enc-kdc-rep-part}}\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:krb5-enc-kdc-rep-part-struct}}\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part::doc}}\index{krb5\_enc\_kdc\_rep\_part (C type)@\spxentry{krb5\_enc\_kdc\_rep\_part}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar C representation of \sphinxstyleemphasis{EncKDCRepPart} protocol message. \sphinxAtStartPar This is the cleartext message that is encrypted and inserted in \sphinxstyleemphasis{KDC\sphinxhyphen{}REP} . \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:declaration}} \sphinxAtStartPar typedef struct \_krb5\_enc\_kdc\_rep\_part krb5\_enc\_kdc\_rep\_part \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:members}}\index{krb5\_enc\_kdc\_rep\_part.magic (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.msg\_type (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.msg\_type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.msg_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_msgtype:c.krb5_msgtype}]{\sphinxcrossref{\DUrole{n}{krb5\_msgtype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{msg\_type}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar krb5 message type \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.session (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.session}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.session}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{session}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Session key. \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.last\_req (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.last\_req}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.last_req}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_last_req_entry:c.krb5_last_req_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_last\_req\_entry}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{last\_req}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Array of pointers to entries. \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.nonce (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.nonce}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.nonce}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{nonce}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Nonce from request. \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.key\_exp (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.key\_exp}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.key_exp}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{key\_exp}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Expiration date. \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.flags (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.flags}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{flags}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Ticket flags. \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.times (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.times}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.times}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{times}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Lifetime info. \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.server (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.server}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.server}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{server}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Server’s principal identifier. \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.caddrs (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.caddrs}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.caddrs}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{caddrs}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Array of ptrs to addrs, optional. \end{fulllineitems} \index{krb5\_enc\_kdc\_rep\_part.enc\_padata (C member)@\spxentry{krb5\_enc\_kdc\_rep\_part.enc\_padata}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part.enc_padata}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enc\_padata}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Encrypted preauthentication data. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_enc\_tkt\_part} \label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:krb5-enc-tkt-part}}\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:krb5-enc-tkt-part-struct}}\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part::doc}}\index{krb5\_enc\_tkt\_part (C type)@\spxentry{krb5\_enc\_tkt\_part}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_enc\_tkt\_part}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Encrypted part of ticket. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:declaration}} \sphinxAtStartPar typedef struct \_krb5\_enc\_tkt\_part krb5\_enc\_tkt\_part \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:members}}\index{krb5\_enc\_tkt\_part.magic (C member)@\spxentry{krb5\_enc\_tkt\_part.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_enc\_tkt\_part.flags (C member)@\spxentry{krb5\_enc\_tkt\_part.flags}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part.flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{flags}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar flags \end{fulllineitems} \index{krb5\_enc\_tkt\_part.session (C member)@\spxentry{krb5\_enc\_tkt\_part.session}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part.session}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{session}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar session key: includes enctype \end{fulllineitems} \index{krb5\_enc\_tkt\_part.client (C member)@\spxentry{krb5\_enc\_tkt\_part.client}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part.client}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{client}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar client name/realm \end{fulllineitems} \index{krb5\_enc\_tkt\_part.transited (C member)@\spxentry{krb5\_enc\_tkt\_part.transited}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part.transited}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_transited:c.krb5_transited}]{\sphinxcrossref{\DUrole{n}{krb5\_transited}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{transited}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar list of transited realms \end{fulllineitems} \index{krb5\_enc\_tkt\_part.times (C member)@\spxentry{krb5\_enc\_tkt\_part.times}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part.times}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{times}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar auth, start, end, renew\_till \end{fulllineitems} \index{krb5\_enc\_tkt\_part.caddrs (C member)@\spxentry{krb5\_enc\_tkt\_part.caddrs}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part.caddrs}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{caddrs}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar array of ptrs to addresses \end{fulllineitems} \index{krb5\_enc\_tkt\_part.authorization\_data (C member)@\spxentry{krb5\_enc\_tkt\_part.authorization\_data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part.authorization_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{authorization\_data}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar auth data \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_encrypt\_block} \label{\detokenize{appdev/refs/types/krb5_encrypt_block:krb5-encrypt-block}}\label{\detokenize{appdev/refs/types/krb5_encrypt_block:krb5-encrypt-block-struct}}\label{\detokenize{appdev/refs/types/krb5_encrypt_block::doc}}\index{krb5\_encrypt\_block (C type)@\spxentry{krb5\_encrypt\_block}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_encrypt\_block}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_encrypt_block:declaration}} \sphinxAtStartPar typedef struct \_krb5\_encrypt\_block krb5\_encrypt\_block \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_encrypt_block:members}}\index{krb5\_encrypt\_block.magic (C member)@\spxentry{krb5\_encrypt\_block.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_encrypt\_block.crypto\_entry (C member)@\spxentry{krb5\_encrypt\_block.crypto\_entry}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block.crypto_entry}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{crypto\_entry}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_encrypt\_block.key (C member)@\spxentry{krb5\_encrypt\_block.key}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block.key}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_encrypt_block:c.krb5_encrypt_block}]{\sphinxcrossref{\DUrole{n}{krb5\_encrypt\_block}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{key}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_enctype} \label{\detokenize{appdev/refs/types/krb5_enctype:krb5-enctype}}\label{\detokenize{appdev/refs/types/krb5_enctype:krb5-enctype-struct}}\label{\detokenize{appdev/refs/types/krb5_enctype::doc}}\index{krb5\_enctype (C type)@\spxentry{krb5\_enctype}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_enctype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_enctype:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_enctype \sphinxstepscope \subsubsection{krb5\_error} \label{\detokenize{appdev/refs/types/krb5_error:krb5-error}}\label{\detokenize{appdev/refs/types/krb5_error:krb5-error-struct}}\label{\detokenize{appdev/refs/types/krb5_error::doc}}\index{krb5\_error (C type)@\spxentry{krb5\_error}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_error}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Error message structure. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_error:declaration}} \sphinxAtStartPar typedef struct \_krb5\_error krb5\_error \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_error:members}}\index{krb5\_error.magic (C member)@\spxentry{krb5\_error.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_error.ctime (C member)@\spxentry{krb5\_error.ctime}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.ctime}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ctime}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Client sec portion; optional. \end{fulllineitems} \index{krb5\_error.cusec (C member)@\spxentry{krb5\_error.cusec}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.cusec}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{cusec}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Client usec portion; optional. \end{fulllineitems} \index{krb5\_error.susec (C member)@\spxentry{krb5\_error.susec}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.susec}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{susec}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Server usec portion. \end{fulllineitems} \index{krb5\_error.stime (C member)@\spxentry{krb5\_error.stime}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.stime}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{stime}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Server sec portion. \end{fulllineitems} \index{krb5\_error.error (C member)@\spxentry{krb5\_error.error}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.error}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ui_4:c.krb5_ui_4}]{\sphinxcrossref{\DUrole{n}{krb5\_ui\_4}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{error}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Error code (protocol error \#’s) \end{fulllineitems} \index{krb5\_error.client (C member)@\spxentry{krb5\_error.client}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.client}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{client}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Client principal and realm. \end{fulllineitems} \index{krb5\_error.server (C member)@\spxentry{krb5\_error.server}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.server}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{server}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Server principal and realm. \end{fulllineitems} \index{krb5\_error.text (C member)@\spxentry{krb5\_error.text}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.text}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{text}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Descriptive text. \end{fulllineitems} \index{krb5\_error.e\_data (C member)@\spxentry{krb5\_error.e\_data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error:c.krb5_error.e_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_error:c.krb5_error}]{\sphinxcrossref{\DUrole{n}{krb5\_error}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{e\_data}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Additional error\sphinxhyphen{}describing data. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_error\_code} \label{\detokenize{appdev/refs/types/krb5_error_code:krb5-error-code}}\label{\detokenize{appdev/refs/types/krb5_error_code:krb5-error-code-struct}}\label{\detokenize{appdev/refs/types/krb5_error_code::doc}}\index{krb5\_error\_code (C type)@\spxentry{krb5\_error\_code}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_error_code:c.krb5_error_code}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_error\_code}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Used to convey an operation status. \sphinxAtStartPar The value 0 indicates success; any other values are com\_err codes. Use krb5\_get\_error\_message() to obtain a string describing the error. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_error_code:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_error\_code \sphinxstepscope \subsubsection{krb5\_expire\_callback\_func} \label{\detokenize{appdev/refs/types/krb5_expire_callback_func:krb5-expire-callback-func}}\label{\detokenize{appdev/refs/types/krb5_expire_callback_func:krb5-expire-callback-func-struct}}\label{\detokenize{appdev/refs/types/krb5_expire_callback_func::doc}}\index{krb5\_expire\_callback\_func (C type)@\spxentry{krb5\_expire\_callback\_func}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_expire_callback_func:c.krb5_expire_callback_func}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_expire\_callback\_func}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_expire_callback_func:declaration}} \sphinxAtStartPar typedef void( * krb5\_expire\_callback\_func) (krb5\_context context, void *data, krb5\_timestamp password\_expiration, krb5\_timestamp account\_expiration, krb5\_boolean is\_last\_req) \sphinxstepscope \subsubsection{krb5\_flags} \label{\detokenize{appdev/refs/types/krb5_flags:krb5-flags}}\label{\detokenize{appdev/refs/types/krb5_flags:krb5-flags-struct}}\label{\detokenize{appdev/refs/types/krb5_flags::doc}}\index{krb5\_flags (C type)@\spxentry{krb5\_flags}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_flags}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_flags:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_flags \sphinxstepscope \subsubsection{krb5\_get\_init\_creds\_opt} \label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:krb5-get-init-creds-opt}}\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:krb5-get-init-creds-opt-struct}}\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt::doc}}\index{krb5\_get\_init\_creds\_opt (C type)@\spxentry{krb5\_get\_init\_creds\_opt}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Store options for \sphinxstyleemphasis{\_krb5\_get\_init\_creds} . \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:declaration}} \sphinxAtStartPar typedef struct \_krb5\_get\_init\_creds\_opt krb5\_get\_init\_creds\_opt \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:members}}\index{krb5\_get\_init\_creds\_opt.flags (C member)@\spxentry{krb5\_get\_init\_creds\_opt.flags}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{flags}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.tkt\_life (C member)@\spxentry{krb5\_get\_init\_creds\_opt.tkt\_life}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.tkt_life}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}]{\sphinxcrossref{\DUrole{n}{krb5\_deltat}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{tkt\_life}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.renew\_life (C member)@\spxentry{krb5\_get\_init\_creds\_opt.renew\_life}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.renew_life}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_deltat:c.krb5_deltat}]{\sphinxcrossref{\DUrole{n}{krb5\_deltat}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{renew\_life}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.forwardable (C member)@\spxentry{krb5\_get\_init\_creds\_opt.forwardable}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.forwardable}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{forwardable}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.proxiable (C member)@\spxentry{krb5\_get\_init\_creds\_opt.proxiable}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.proxiable}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{proxiable}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.etype\_list (C member)@\spxentry{krb5\_get\_init\_creds\_opt.etype\_list}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.etype_list}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{etype\_list}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.etype\_list\_length (C member)@\spxentry{krb5\_get\_init\_creds\_opt.etype\_list\_length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.etype_list_length}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{etype\_list\_length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.address\_list (C member)@\spxentry{krb5\_get\_init\_creds\_opt.address\_list}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.address_list}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{address\_list}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.preauth\_list (C member)@\spxentry{krb5\_get\_init\_creds\_opt.preauth\_list}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.preauth_list}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_preauthtype:c.krb5_preauthtype}]{\sphinxcrossref{\DUrole{n}{krb5\_preauthtype}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{preauth\_list}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.preauth\_list\_length (C member)@\spxentry{krb5\_get\_init\_creds\_opt.preauth\_list\_length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.preauth_list_length}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{preauth\_list\_length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_get\_init\_creds\_opt.salt (C member)@\spxentry{krb5\_get\_init\_creds\_opt.salt}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt.salt}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_get_init_creds_opt:c.krb5_get_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_get\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{salt}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_gic\_opt\_pa\_data} \label{\detokenize{appdev/refs/types/krb5_gic_opt_pa_data:krb5-gic-opt-pa-data}}\label{\detokenize{appdev/refs/types/krb5_gic_opt_pa_data:krb5-gic-opt-pa-data-struct}}\label{\detokenize{appdev/refs/types/krb5_gic_opt_pa_data::doc}}\index{krb5\_gic\_opt\_pa\_data (C type)@\spxentry{krb5\_gic\_opt\_pa\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_gic_opt_pa_data:c.krb5_gic_opt_pa_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_gic\_opt\_pa\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Generic preauth option attribute/value pairs. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_gic_opt_pa_data:declaration}} \sphinxAtStartPar typedef struct \_krb5\_gic\_opt\_pa\_data krb5\_gic\_opt\_pa\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_gic_opt_pa_data:members}}\index{krb5\_gic\_opt\_pa\_data.attr (C member)@\spxentry{krb5\_gic\_opt\_pa\_data.attr}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_gic_opt_pa_data:c.krb5_gic_opt_pa_data.attr}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_gic_opt_pa_data:c.krb5_gic_opt_pa_data}]{\sphinxcrossref{\DUrole{n}{krb5\_gic\_opt\_pa\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{attr}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_gic\_opt\_pa\_data.value (C member)@\spxentry{krb5\_gic\_opt\_pa\_data.value}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_gic_opt_pa_data:c.krb5_gic_opt_pa_data.value}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_gic_opt_pa_data:c.krb5_gic_opt_pa_data}]{\sphinxcrossref{\DUrole{n}{krb5\_gic\_opt\_pa\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{value}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_int16} \label{\detokenize{appdev/refs/types/krb5_int16:krb5-int16}}\label{\detokenize{appdev/refs/types/krb5_int16:krb5-int16-struct}}\label{\detokenize{appdev/refs/types/krb5_int16::doc}}\index{krb5\_int16 (C type)@\spxentry{krb5\_int16}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_int16:c.krb5_int16}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_int16}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_int16:declaration}} \sphinxAtStartPar typedef int16\_t krb5\_int16 \sphinxstepscope \subsubsection{krb5\_int32} \label{\detokenize{appdev/refs/types/krb5_int32:krb5-int32}}\label{\detokenize{appdev/refs/types/krb5_int32:krb5-int32-struct}}\label{\detokenize{appdev/refs/types/krb5_int32::doc}}\index{krb5\_int32 (C type)@\spxentry{krb5\_int32}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_int32}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_int32:declaration}} \sphinxAtStartPar typedef int32\_t krb5\_int32 \sphinxstepscope \subsubsection{krb5\_kdc\_rep} \label{\detokenize{appdev/refs/types/krb5_kdc_rep:krb5-kdc-rep}}\label{\detokenize{appdev/refs/types/krb5_kdc_rep:krb5-kdc-rep-struct}}\label{\detokenize{appdev/refs/types/krb5_kdc_rep::doc}}\index{krb5\_kdc\_rep (C type)@\spxentry{krb5\_kdc\_rep}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kdc\_rep}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Representation of the \sphinxstyleemphasis{KDC\sphinxhyphen{}REP} protocol message. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_kdc_rep:declaration}} \sphinxAtStartPar typedef struct \_krb5\_kdc\_rep krb5\_kdc\_rep \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_kdc_rep:members}}\index{krb5\_kdc\_rep.magic (C member)@\spxentry{krb5\_kdc\_rep.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_kdc\_rep.msg\_type (C member)@\spxentry{krb5\_kdc\_rep.msg\_type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep.msg_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_msgtype:c.krb5_msgtype}]{\sphinxcrossref{\DUrole{n}{krb5\_msgtype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{msg\_type}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar KRB5\_AS\_REP or KRB5\_KDC\_REP. \end{fulllineitems} \index{krb5\_kdc\_rep.padata (C member)@\spxentry{krb5\_kdc\_rep.padata}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep.padata}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{padata}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Preauthentication data from KDC. \end{fulllineitems} \index{krb5\_kdc\_rep.client (C member)@\spxentry{krb5\_kdc\_rep.client}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep.client}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{client}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Client principal and realm. \end{fulllineitems} \index{krb5\_kdc\_rep.ticket (C member)@\spxentry{krb5\_kdc\_rep.ticket}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep.ticket}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ticket}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Ticket. \end{fulllineitems} \index{krb5\_kdc\_rep.enc\_part (C member)@\spxentry{krb5\_kdc\_rep.enc\_part}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep.enc_part}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enc\_part}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Encrypted part of reply. \end{fulllineitems} \index{krb5\_kdc\_rep.enc\_part2 (C member)@\spxentry{krb5\_kdc\_rep.enc\_part2}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep.enc_part2}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_kdc_rep_part:c.krb5_enc_kdc_rep_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_kdc\_rep\_part}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_rep:c.krb5_kdc_rep}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_rep}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enc\_part2}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Unencrypted version, if available. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_kdc\_req} \label{\detokenize{appdev/refs/types/krb5_kdc_req:krb5-kdc-req}}\label{\detokenize{appdev/refs/types/krb5_kdc_req:krb5-kdc-req-struct}}\label{\detokenize{appdev/refs/types/krb5_kdc_req::doc}}\index{krb5\_kdc\_req (C type)@\spxentry{krb5\_kdc\_req}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kdc\_req}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar C representation of KDC\sphinxhyphen{}REQ protocol message, including KDC\sphinxhyphen{}REQ\sphinxhyphen{}BODY. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_kdc_req:declaration}} \sphinxAtStartPar typedef struct \_krb5\_kdc\_req krb5\_kdc\_req \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_kdc_req:members}}\index{krb5\_kdc\_req.magic (C member)@\spxentry{krb5\_kdc\_req.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_kdc\_req.msg\_type (C member)@\spxentry{krb5\_kdc\_req.msg\_type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.msg_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_msgtype:c.krb5_msgtype}]{\sphinxcrossref{\DUrole{n}{krb5\_msgtype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{msg\_type}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar KRB5\_AS\_REQ or KRB5\_TGS\_REQ. \end{fulllineitems} \index{krb5\_kdc\_req.padata (C member)@\spxentry{krb5\_kdc\_req.padata}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.padata}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{padata}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Preauthentication data. \end{fulllineitems} \index{krb5\_kdc\_req.kdc\_options (C member)@\spxentry{krb5\_kdc\_req.kdc\_options}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.kdc_options}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{kdc\_options}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Requested options. \end{fulllineitems} \index{krb5\_kdc\_req.client (C member)@\spxentry{krb5\_kdc\_req.client}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.client}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{client}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Client principal and realm. \end{fulllineitems} \index{krb5\_kdc\_req.server (C member)@\spxentry{krb5\_kdc\_req.server}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.server}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{server}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Server principal and realm. \end{fulllineitems} \index{krb5\_kdc\_req.from (C member)@\spxentry{krb5\_kdc\_req.from}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.from}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{from}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Requested start time. \end{fulllineitems} \index{krb5\_kdc\_req.till (C member)@\spxentry{krb5\_kdc\_req.till}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.till}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{till}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Requested end time. \end{fulllineitems} \index{krb5\_kdc\_req.rtime (C member)@\spxentry{krb5\_kdc\_req.rtime}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.rtime}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{rtime}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Requested renewable end time. \end{fulllineitems} \index{krb5\_kdc\_req.nonce (C member)@\spxentry{krb5\_kdc\_req.nonce}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.nonce}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{nonce}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Nonce to match request and response. \end{fulllineitems} \index{krb5\_kdc\_req.nktypes (C member)@\spxentry{krb5\_kdc\_req.nktypes}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.nktypes}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{nktypes}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Number of enctypes. \end{fulllineitems} \index{krb5\_kdc\_req.ktype (C member)@\spxentry{krb5\_kdc\_req.ktype}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.ktype}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ktype}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Requested enctypes. \end{fulllineitems} \index{krb5\_kdc\_req.addresses (C member)@\spxentry{krb5\_kdc\_req.addresses}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.addresses}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_address:c.krb5_address}]{\sphinxcrossref{\DUrole{n}{krb5\_address}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{addresses}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Requested addresses (optional) \end{fulllineitems} \index{krb5\_kdc\_req.authorization\_data (C member)@\spxentry{krb5\_kdc\_req.authorization\_data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.authorization_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{authorization\_data}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Encrypted authz data (optional) \end{fulllineitems} \index{krb5\_kdc\_req.unenc\_authdata (C member)@\spxentry{krb5\_kdc\_req.unenc\_authdata}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.unenc_authdata}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_authdata:c.krb5_authdata}]{\sphinxcrossref{\DUrole{n}{krb5\_authdata}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{unenc\_authdata}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Unencrypted authz data. \end{fulllineitems} \index{krb5\_kdc\_req.second\_ticket (C member)@\spxentry{krb5\_kdc\_req.second\_ticket}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req.second_ticket}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_kdc_req:c.krb5_kdc_req}]{\sphinxcrossref{\DUrole{n}{krb5\_kdc\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{second\_ticket}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Second ticket array (optional) \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_keyblock} \label{\detokenize{appdev/refs/types/krb5_keyblock:krb5-keyblock}}\label{\detokenize{appdev/refs/types/krb5_keyblock:krb5-keyblock-struct}}\label{\detokenize{appdev/refs/types/krb5_keyblock::doc}}\index{krb5\_keyblock (C type)@\spxentry{krb5\_keyblock}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_keyblock}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Exposed contents of a key. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_keyblock:declaration}} \sphinxAtStartPar typedef struct \_krb5\_keyblock krb5\_keyblock \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_keyblock:members}}\index{krb5\_keyblock.magic (C member)@\spxentry{krb5\_keyblock.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_keyblock.enctype (C member)@\spxentry{krb5\_keyblock.enctype}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock.enctype}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enctype:c.krb5_enctype}]{\sphinxcrossref{\DUrole{n}{krb5\_enctype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enctype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_keyblock.length (C member)@\spxentry{krb5\_keyblock.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_keyblock.contents (C member)@\spxentry{krb5\_keyblock.contents}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock.contents}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_octet:c.krb5_octet}]{\sphinxcrossref{\DUrole{n}{krb5\_octet}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{contents}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_keytab\_entry} \label{\detokenize{appdev/refs/types/krb5_keytab_entry:krb5-keytab-entry}}\label{\detokenize{appdev/refs/types/krb5_keytab_entry:krb5-keytab-entry-struct}}\label{\detokenize{appdev/refs/types/krb5_keytab_entry::doc}}\index{krb5\_keytab\_entry (C type)@\spxentry{krb5\_keytab\_entry}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_keytab\_entry}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar A key table entry. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_keytab_entry:declaration}} \sphinxAtStartPar typedef struct krb5\_keytab\_entry\_st krb5\_keytab\_entry \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_keytab_entry:members}}\index{krb5\_keytab\_entry.magic (C member)@\spxentry{krb5\_keytab\_entry.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_keytab\_entry.principal (C member)@\spxentry{krb5\_keytab\_entry.principal}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry.principal}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{principal}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Principal of this key. \end{fulllineitems} \index{krb5\_keytab\_entry.timestamp (C member)@\spxentry{krb5\_keytab\_entry.timestamp}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry.timestamp}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{timestamp}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Time entry written to keytable. \end{fulllineitems} \index{krb5\_keytab\_entry.vno (C member)@\spxentry{krb5\_keytab\_entry.vno}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry.vno}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_kvno:c.krb5_kvno}]{\sphinxcrossref{\DUrole{n}{krb5\_kvno}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{vno}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Key version number. \end{fulllineitems} \index{krb5\_keytab\_entry.key (C member)@\spxentry{krb5\_keytab\_entry.key}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry.key}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_keyblock:c.krb5_keyblock}]{\sphinxcrossref{\DUrole{n}{krb5\_keyblock}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_keytab_entry:c.krb5_keytab_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_keytab\_entry}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{key}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar The secret key. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_keyusage} \label{\detokenize{appdev/refs/types/krb5_keyusage:krb5-keyusage}}\label{\detokenize{appdev/refs/types/krb5_keyusage:krb5-keyusage-struct}}\label{\detokenize{appdev/refs/types/krb5_keyusage::doc}}\index{krb5\_keyusage (C type)@\spxentry{krb5\_keyusage}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keyusage:c.krb5_keyusage}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_keyusage}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_keyusage:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_keyusage \sphinxstepscope \subsubsection{krb5\_kt\_cursor} \label{\detokenize{appdev/refs/types/krb5_kt_cursor:krb5-kt-cursor}}\label{\detokenize{appdev/refs/types/krb5_kt_cursor:krb5-kt-cursor-struct}}\label{\detokenize{appdev/refs/types/krb5_kt_cursor::doc}}\index{krb5\_kt\_cursor (C type)@\spxentry{krb5\_kt\_cursor}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kt_cursor:c.krb5_kt_cursor}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kt\_cursor}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_kt_cursor:declaration}} \sphinxAtStartPar typedef krb5\_pointer krb5\_kt\_cursor \sphinxstepscope \subsubsection{krb5\_kvno} \label{\detokenize{appdev/refs/types/krb5_kvno:krb5-kvno}}\label{\detokenize{appdev/refs/types/krb5_kvno:krb5-kvno-struct}}\label{\detokenize{appdev/refs/types/krb5_kvno::doc}}\index{krb5\_kvno (C type)@\spxentry{krb5\_kvno}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_kvno:c.krb5_kvno}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_kvno}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_kvno:declaration}} \sphinxAtStartPar typedef unsigned int krb5\_kvno \sphinxstepscope \subsubsection{krb5\_last\_req\_entry} \label{\detokenize{appdev/refs/types/krb5_last_req_entry:krb5-last-req-entry}}\label{\detokenize{appdev/refs/types/krb5_last_req_entry:krb5-last-req-entry-struct}}\label{\detokenize{appdev/refs/types/krb5_last_req_entry::doc}}\index{krb5\_last\_req\_entry (C type)@\spxentry{krb5\_last\_req\_entry}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_last_req_entry:c.krb5_last_req_entry}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_last\_req\_entry}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Last request entry. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_last_req_entry:declaration}} \sphinxAtStartPar typedef struct \_krb5\_last\_req\_entry krb5\_last\_req\_entry \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_last_req_entry:members}}\index{krb5\_last\_req\_entry.magic (C member)@\spxentry{krb5\_last\_req\_entry.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_last_req_entry:c.krb5_last_req_entry.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_last_req_entry:c.krb5_last_req_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_last\_req\_entry}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_last\_req\_entry.lr\_type (C member)@\spxentry{krb5\_last\_req\_entry.lr\_type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_last_req_entry:c.krb5_last_req_entry.lr_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_last_req_entry:c.krb5_last_req_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_last\_req\_entry}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{lr\_type}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar LR type. \end{fulllineitems} \index{krb5\_last\_req\_entry.value (C member)@\spxentry{krb5\_last\_req\_entry.value}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_last_req_entry:c.krb5_last_req_entry.value}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_last_req_entry:c.krb5_last_req_entry}]{\sphinxcrossref{\DUrole{n}{krb5\_last\_req\_entry}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{value}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Timestamp. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_magic} \label{\detokenize{appdev/refs/types/krb5_magic:krb5-magic}}\label{\detokenize{appdev/refs/types/krb5_magic:krb5-magic-struct}}\label{\detokenize{appdev/refs/types/krb5_magic::doc}}\index{krb5\_magic (C type)@\spxentry{krb5\_magic}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_magic:declaration}} \sphinxAtStartPar typedef krb5\_error\_code krb5\_magic \sphinxstepscope \subsubsection{krb5\_mk\_req\_checksum\_func} \label{\detokenize{appdev/refs/types/krb5_mk_req_checksum_func:krb5-mk-req-checksum-func}}\label{\detokenize{appdev/refs/types/krb5_mk_req_checksum_func:krb5-mk-req-checksum-func-struct}}\label{\detokenize{appdev/refs/types/krb5_mk_req_checksum_func::doc}}\index{krb5\_mk\_req\_checksum\_func (C type)@\spxentry{krb5\_mk\_req\_checksum\_func}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_mk_req_checksum_func:c.krb5_mk_req_checksum_func}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_mk\_req\_checksum\_func}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Type of function used as a callback to generate checksum data for mk\_req. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_mk_req_checksum_func:declaration}} \sphinxAtStartPar typedef krb5\_error\_code( * krb5\_mk\_req\_checksum\_func) (krb5\_context, krb5\_auth\_context, void *, krb5\_data **) \sphinxstepscope \subsubsection{krb5\_msgtype} \label{\detokenize{appdev/refs/types/krb5_msgtype:krb5-msgtype}}\label{\detokenize{appdev/refs/types/krb5_msgtype:krb5-msgtype-struct}}\label{\detokenize{appdev/refs/types/krb5_msgtype::doc}}\index{krb5\_msgtype (C type)@\spxentry{krb5\_msgtype}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_msgtype:c.krb5_msgtype}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_msgtype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_msgtype:declaration}} \sphinxAtStartPar typedef unsigned int krb5\_msgtype \sphinxstepscope \subsubsection{krb5\_octet} \label{\detokenize{appdev/refs/types/krb5_octet:krb5-octet}}\label{\detokenize{appdev/refs/types/krb5_octet:krb5-octet-struct}}\label{\detokenize{appdev/refs/types/krb5_octet::doc}}\index{krb5\_octet (C type)@\spxentry{krb5\_octet}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_octet:c.krb5_octet}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_octet}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_octet:declaration}} \sphinxAtStartPar typedef uint8\_t krb5\_octet \sphinxstepscope \subsubsection{krb5\_pa\_pac\_req} \label{\detokenize{appdev/refs/types/krb5_pa_pac_req:krb5-pa-pac-req}}\label{\detokenize{appdev/refs/types/krb5_pa_pac_req:krb5-pa-pac-req-struct}}\label{\detokenize{appdev/refs/types/krb5_pa_pac_req::doc}}\index{krb5\_pa\_pac\_req (C type)@\spxentry{krb5\_pa\_pac\_req}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_pac_req:c.krb5_pa_pac_req}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pa\_pac\_req}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_pa_pac_req:declaration}} \sphinxAtStartPar typedef struct \_krb5\_pa\_pac\_req krb5\_pa\_pac\_req \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_pa_pac_req:members}}\index{krb5\_pa\_pac\_req.include\_pac (C member)@\spxentry{krb5\_pa\_pac\_req.include\_pac}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_pac_req:c.krb5_pa_pac_req.include_pac}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_boolean:c.krb5_boolean}]{\sphinxcrossref{\DUrole{n}{krb5\_boolean}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_pac_req:c.krb5_pa_pac_req}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_pac\_req}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{include\_pac}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar TRUE if a PAC should be included in TGS\sphinxhyphen{}REP. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_pa\_server\_referral\_data} \label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:krb5-pa-server-referral-data}}\label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:krb5-pa-server-referral-data-struct}}\label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data::doc}}\index{krb5\_pa\_server\_referral\_data (C type)@\spxentry{krb5\_pa\_server\_referral\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pa\_server\_referral\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:declaration}} \sphinxAtStartPar typedef struct \_krb5\_pa\_server\_referral\_data krb5\_pa\_server\_referral\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:members}}\index{krb5\_pa\_server\_referral\_data.referred\_realm (C member)@\spxentry{krb5\_pa\_server\_referral\_data.referred\_realm}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data.referred_realm}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_server\_referral\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{referred\_realm}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_pa\_server\_referral\_data.true\_principal\_name (C member)@\spxentry{krb5\_pa\_server\_referral\_data.true\_principal\_name}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data.true_principal_name}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_server\_referral\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{true\_principal\_name}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_pa\_server\_referral\_data.requested\_principal\_name (C member)@\spxentry{krb5\_pa\_server\_referral\_data.requested\_principal\_name}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data.requested_principal_name}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_server\_referral\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{requested\_principal\_name}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_pa\_server\_referral\_data.referral\_valid\_until (C member)@\spxentry{krb5\_pa\_server\_referral\_data.referral\_valid\_until}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data.referral_valid_until}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_server\_referral\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{referral\_valid\_until}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_pa\_server\_referral\_data.rep\_cksum (C member)@\spxentry{krb5\_pa\_server\_referral\_data.rep\_cksum}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data.rep_cksum}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_checksum:c.krb5_checksum}]{\sphinxcrossref{\DUrole{n}{krb5\_checksum}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_server_referral_data:c.krb5_pa_server_referral_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_server\_referral\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{rep\_cksum}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_pa\_svr\_referral\_data} \label{\detokenize{appdev/refs/types/krb5_pa_svr_referral_data:krb5-pa-svr-referral-data}}\label{\detokenize{appdev/refs/types/krb5_pa_svr_referral_data:krb5-pa-svr-referral-data-struct}}\label{\detokenize{appdev/refs/types/krb5_pa_svr_referral_data::doc}}\index{krb5\_pa\_svr\_referral\_data (C type)@\spxentry{krb5\_pa\_svr\_referral\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_svr_referral_data:c.krb5_pa_svr_referral_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pa\_svr\_referral\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_pa_svr_referral_data:declaration}} \sphinxAtStartPar typedef struct \_krb5\_pa\_svr\_referral\_data krb5\_pa\_svr\_referral\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_pa_svr_referral_data:members}}\index{krb5\_pa\_svr\_referral\_data.principal (C member)@\spxentry{krb5\_pa\_svr\_referral\_data.principal}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_svr_referral_data:c.krb5_pa_svr_referral_data.principal}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_svr_referral_data:c.krb5_pa_svr_referral_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_svr\_referral\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{principal}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Referred name, only realm is required. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_pa\_data} \label{\detokenize{appdev/refs/types/krb5_pa_data:krb5-pa-data}}\label{\detokenize{appdev/refs/types/krb5_pa_data:krb5-pa-data-struct}}\label{\detokenize{appdev/refs/types/krb5_pa_data::doc}}\index{krb5\_pa\_data (C type)@\spxentry{krb5\_pa\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pa\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Pre\sphinxhyphen{}authentication data. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_pa_data:declaration}} \sphinxAtStartPar typedef struct \_krb5\_pa\_data krb5\_pa\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_pa_data:members}}\index{krb5\_pa\_data.magic (C member)@\spxentry{krb5\_pa\_data.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_pa\_data.pa\_type (C member)@\spxentry{krb5\_pa\_data.pa\_type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data.pa_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_preauthtype:c.krb5_preauthtype}]{\sphinxcrossref{\DUrole{n}{krb5\_preauthtype}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{pa\_type}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Preauthentication data type. \end{fulllineitems} \index{krb5\_pa\_data.length (C member)@\spxentry{krb5\_pa\_data.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Length of data. \end{fulllineitems} \index{krb5\_pa\_data.contents (C member)@\spxentry{krb5\_pa\_data.contents}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data.contents}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_octet:c.krb5_octet}]{\sphinxcrossref{\DUrole{n}{krb5\_octet}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pa_data:c.krb5_pa_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pa\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{contents}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Data. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_pointer} \label{\detokenize{appdev/refs/types/krb5_pointer:krb5-pointer}}\label{\detokenize{appdev/refs/types/krb5_pointer:krb5-pointer-struct}}\label{\detokenize{appdev/refs/types/krb5_pointer::doc}}\index{krb5\_pointer (C type)@\spxentry{krb5\_pointer}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pointer:c.krb5_pointer}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pointer}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_pointer:declaration}} \sphinxAtStartPar typedef void* krb5\_pointer \sphinxstepscope \subsubsection{krb5\_post\_recv\_fn} \label{\detokenize{appdev/refs/types/krb5_post_recv_fn:krb5-post-recv-fn}}\label{\detokenize{appdev/refs/types/krb5_post_recv_fn:krb5-post-recv-fn-struct}}\label{\detokenize{appdev/refs/types/krb5_post_recv_fn::doc}}\index{krb5\_post\_recv\_fn (C type)@\spxentry{krb5\_post\_recv\_fn}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_post_recv_fn:c.krb5_post_recv_fn}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_post\_recv\_fn}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Hook function for inspecting or overriding KDC replies. \sphinxAtStartPar If \sphinxstyleemphasis{code} is non\sphinxhyphen{}zero, KDC communication failed and \sphinxstyleemphasis{reply} should be ignored. The hook function may return \sphinxstyleemphasis{code} or a different error code, or may synthesize a reply by setting \sphinxstyleemphasis{new\_reply\_out} and return successfully. The hook function should use krb5\_copy\_data() to construct the value for \sphinxstyleemphasis{new\_reply\_out} , to ensure that it can be freed correctly by the library. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_post_recv_fn:declaration}} \sphinxAtStartPar typedef krb5\_error\_code( * krb5\_post\_recv\_fn) (krb5\_context context, void *data, krb5\_error\_code code, const krb5\_data *realm, const krb5\_data *message, const krb5\_data *reply, krb5\_data **new\_reply\_out) \sphinxstepscope \subsubsection{krb5\_pre\_send\_fn} \label{\detokenize{appdev/refs/types/krb5_pre_send_fn:krb5-pre-send-fn}}\label{\detokenize{appdev/refs/types/krb5_pre_send_fn:krb5-pre-send-fn-struct}}\label{\detokenize{appdev/refs/types/krb5_pre_send_fn::doc}}\index{krb5\_pre\_send\_fn (C type)@\spxentry{krb5\_pre\_send\_fn}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pre_send_fn:c.krb5_pre_send_fn}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pre\_send\_fn}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Hook function for inspecting or modifying messages sent to KDCs. \sphinxAtStartPar If the hook function sets \sphinxstyleemphasis{new\_reply\_out} , \sphinxstyleemphasis{message} will not be sent to the KDC, and the given reply will used instead. If the hook function sets \sphinxstyleemphasis{new\_message\_out} , the given message will be sent to the KDC in place of \sphinxstyleemphasis{message} . If the hook function returns successfully without setting either output, \sphinxstyleemphasis{message} will be sent to the KDC normally. The hook function should use krb5\_copy\_data() to construct the value for \sphinxstyleemphasis{new\_message\_out} or \sphinxstyleemphasis{reply\_out} , to ensure that it can be freed correctly by the library. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_pre_send_fn:declaration}} \sphinxAtStartPar typedef krb5\_error\_code( * krb5\_pre\_send\_fn) (krb5\_context context, void *data, const krb5\_data *realm, const krb5\_data *message, krb5\_data **new\_message\_out, krb5\_data **new\_reply\_out) \sphinxstepscope \subsubsection{krb5\_preauthtype} \label{\detokenize{appdev/refs/types/krb5_preauthtype:krb5-preauthtype}}\label{\detokenize{appdev/refs/types/krb5_preauthtype:krb5-preauthtype-struct}}\label{\detokenize{appdev/refs/types/krb5_preauthtype::doc}}\index{krb5\_preauthtype (C type)@\spxentry{krb5\_preauthtype}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_preauthtype:c.krb5_preauthtype}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_preauthtype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_preauthtype:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_preauthtype \sphinxstepscope \subsubsection{krb5\_principal} \label{\detokenize{appdev/refs/types/krb5_principal:krb5-principal}}\label{\detokenize{appdev/refs/types/krb5_principal:krb5-principal-struct}}\label{\detokenize{appdev/refs/types/krb5_principal::doc}}\index{krb5\_principal (C type)@\spxentry{krb5\_principal}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_principal}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_principal:declaration}} \sphinxAtStartPar typedef krb5\_principal\_data* krb5\_principal \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_principal:members}}\index{krb5\_principal.magic (C member)@\spxentry{krb5\_principal.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_principal.realm (C member)@\spxentry{krb5\_principal.realm}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal.realm}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{realm}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_principal.data (C member)@\spxentry{krb5\_principal.data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal.data}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{data}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar An array of strings. \end{fulllineitems} \index{krb5\_principal.length (C member)@\spxentry{krb5\_principal.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_principal.type (C member)@\spxentry{krb5\_principal.type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal.type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{type}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_principal\_data} \label{\detokenize{appdev/refs/types/krb5_principal_data:krb5-principal-data}}\label{\detokenize{appdev/refs/types/krb5_principal_data:krb5-principal-data-struct}}\label{\detokenize{appdev/refs/types/krb5_principal_data::doc}}\index{krb5\_principal\_data (C type)@\spxentry{krb5\_principal\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_principal\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_principal_data:declaration}} \sphinxAtStartPar typedef struct krb5\_principal\_data krb5\_principal\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_principal_data:members}}\index{krb5\_principal\_data.magic (C member)@\spxentry{krb5\_principal\_data.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data}]{\sphinxcrossref{\DUrole{n}{krb5\_principal\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_principal\_data.realm (C member)@\spxentry{krb5\_principal\_data.realm}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data.realm}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data}]{\sphinxcrossref{\DUrole{n}{krb5\_principal\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{realm}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_principal\_data.data (C member)@\spxentry{krb5\_principal\_data.data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data.data}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data}]{\sphinxcrossref{\DUrole{n}{krb5\_principal\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{data}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar An array of strings. \end{fulllineitems} \index{krb5\_principal\_data.length (C member)@\spxentry{krb5\_principal\_data.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data}]{\sphinxcrossref{\DUrole{n}{krb5\_principal\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_principal\_data.type (C member)@\spxentry{krb5\_principal\_data.type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data.type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_principal_data:c.krb5_principal_data}]{\sphinxcrossref{\DUrole{n}{krb5\_principal\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{type}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_prompt} \label{\detokenize{appdev/refs/types/krb5_prompt:krb5-prompt}}\label{\detokenize{appdev/refs/types/krb5_prompt:krb5-prompt-struct}}\label{\detokenize{appdev/refs/types/krb5_prompt::doc}}\index{krb5\_prompt (C type)@\spxentry{krb5\_prompt}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_prompt:c.krb5_prompt}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_prompt}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Text for prompt used in prompter callback function. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_prompt:declaration}} \sphinxAtStartPar typedef struct \_krb5\_prompt krb5\_prompt \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_prompt:members}}\index{krb5\_prompt.prompt (C member)@\spxentry{krb5\_prompt.prompt}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_prompt:c.krb5_prompt.prompt}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_prompt:c.krb5_prompt}]{\sphinxcrossref{\DUrole{n}{krb5\_prompt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{prompt}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar The prompt to show to the user. \end{fulllineitems} \index{krb5\_prompt.hidden (C member)@\spxentry{krb5\_prompt.hidden}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_prompt:c.krb5_prompt.hidden}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_prompt:c.krb5_prompt}]{\sphinxcrossref{\DUrole{n}{krb5\_prompt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{hidden}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Boolean; informative prompt or hidden (e.g. PIN) \end{fulllineitems} \index{krb5\_prompt.reply (C member)@\spxentry{krb5\_prompt.reply}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_prompt:c.krb5_prompt.reply}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_prompt:c.krb5_prompt}]{\sphinxcrossref{\DUrole{n}{krb5\_prompt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{reply}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Must be allocated before call to prompt routine. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_prompt\_type} \label{\detokenize{appdev/refs/types/krb5_prompt_type:krb5-prompt-type}}\label{\detokenize{appdev/refs/types/krb5_prompt_type:krb5-prompt-type-struct}}\label{\detokenize{appdev/refs/types/krb5_prompt_type::doc}}\index{krb5\_prompt\_type (C type)@\spxentry{krb5\_prompt\_type}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_prompt_type:c.krb5_prompt_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_prompt\_type}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_prompt_type:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_prompt\_type \sphinxstepscope \subsubsection{krb5\_prompter\_fct} \label{\detokenize{appdev/refs/types/krb5_prompter_fct:krb5-prompter-fct}}\label{\detokenize{appdev/refs/types/krb5_prompter_fct:krb5-prompter-fct-struct}}\label{\detokenize{appdev/refs/types/krb5_prompter_fct::doc}}\index{krb5\_prompter\_fct (C type)@\spxentry{krb5\_prompter\_fct}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_prompter_fct:c.krb5_prompter_fct}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_prompter\_fct}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Pointer to a prompter callback function. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_prompter_fct:declaration}} \sphinxAtStartPar typedef krb5\_error\_code( * krb5\_prompter\_fct) (krb5\_context context, void *data, const char *name, const char *banner, int num\_prompts, krb5\_prompt prompts{[}{]}) \sphinxstepscope \subsubsection{krb5\_pwd\_data} \label{\detokenize{appdev/refs/types/krb5_pwd_data:krb5-pwd-data}}\label{\detokenize{appdev/refs/types/krb5_pwd_data:krb5-pwd-data-struct}}\label{\detokenize{appdev/refs/types/krb5_pwd_data::doc}}\index{krb5\_pwd\_data (C type)@\spxentry{krb5\_pwd\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pwd_data:c.krb5_pwd_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pwd\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_pwd_data:declaration}} \sphinxAtStartPar typedef struct \_krb5\_pwd\_data krb5\_pwd\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_pwd_data:members}}\index{krb5\_pwd\_data.magic (C member)@\spxentry{krb5\_pwd\_data.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pwd_data:c.krb5_pwd_data.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pwd_data:c.krb5_pwd_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pwd\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_pwd\_data.sequence\_count (C member)@\spxentry{krb5\_pwd\_data.sequence\_count}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pwd_data:c.krb5_pwd_data.sequence_count}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pwd_data:c.krb5_pwd_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pwd\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{sequence\_count}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_pwd\_data.element (C member)@\spxentry{krb5\_pwd\_data.element}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pwd_data:c.krb5_pwd_data.element}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/passwd_phrase_element:c.passwd_phrase_element}]{\sphinxcrossref{\DUrole{n}{passwd\_phrase\_element}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_pwd_data:c.krb5_pwd_data}]{\sphinxcrossref{\DUrole{n}{krb5\_pwd\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{element}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_responder\_context} \label{\detokenize{appdev/refs/types/krb5_responder_context:krb5-responder-context}}\label{\detokenize{appdev/refs/types/krb5_responder_context:krb5-responder-context-struct}}\label{\detokenize{appdev/refs/types/krb5_responder_context::doc}}\index{krb5\_responder\_context (C type)@\spxentry{krb5\_responder\_context}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_context:c.krb5_responder_context}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_context}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar A container for a set of preauthentication questions and answers. \sphinxAtStartPar A responder context is supplied by the krb5 authentication system to a krb5\_responder\_fn callback. It contains a list of questions and can receive answers. Questions contained in a responder context can be listed using krb5\_responder\_list\_questions(), retrieved using krb5\_responder\_get\_challenge(), or answered using krb5\_responder\_set\_answer(). The form of a question’s challenge and answer depend on the question name. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_responder_context:declaration}} \sphinxAtStartPar typedef struct krb5\_responder\_context\_st* krb5\_responder\_context \sphinxstepscope \subsubsection{krb5\_responder\_fn} \label{\detokenize{appdev/refs/types/krb5_responder_fn:krb5-responder-fn}}\label{\detokenize{appdev/refs/types/krb5_responder_fn:krb5-responder-fn-struct}}\label{\detokenize{appdev/refs/types/krb5_responder_fn::doc}}\index{krb5\_responder\_fn (C type)@\spxentry{krb5\_responder\_fn}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_fn:c.krb5_responder_fn}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_fn}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Responder function for an initial credential exchange. \sphinxAtStartPar If a required question is unanswered, the prompter may be called. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_responder_fn:declaration}} \sphinxAtStartPar typedef krb5\_error\_code( * krb5\_responder\_fn) (krb5\_context ctx, void *data, krb5\_responder\_context rctx) \sphinxstepscope \subsubsection{krb5\_responder\_otp\_challenge} \label{\detokenize{appdev/refs/types/krb5_responder_otp_challenge:krb5-responder-otp-challenge}}\label{\detokenize{appdev/refs/types/krb5_responder_otp_challenge:krb5-responder-otp-challenge-struct}}\label{\detokenize{appdev/refs/types/krb5_responder_otp_challenge::doc}}\index{krb5\_responder\_otp\_challenge (C type)@\spxentry{krb5\_responder\_otp\_challenge}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_challenge:c.krb5_responder_otp_challenge}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_otp\_challenge}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_responder_otp_challenge:declaration}} \sphinxAtStartPar typedef struct \_krb5\_responder\_otp\_challenge krb5\_responder\_otp\_challenge \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_responder_otp_challenge:members}}\index{krb5\_responder\_otp\_challenge.service (C member)@\spxentry{krb5\_responder\_otp\_challenge.service}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_challenge:c.krb5_responder_otp_challenge.service}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_challenge:c.krb5_responder_otp_challenge}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_challenge}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{service}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_responder\_otp\_challenge.tokeninfo (C member)@\spxentry{krb5\_responder\_otp\_challenge.tokeninfo}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_challenge:c.krb5_responder_otp_challenge.tokeninfo}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_tokeninfo}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_challenge:c.krb5_responder_otp_challenge}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_challenge}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{tokeninfo}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_responder\_otp\_tokeninfo} \label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:krb5-responder-otp-tokeninfo}}\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:krb5-responder-otp-tokeninfo-struct}}\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo::doc}}\index{krb5\_responder\_otp\_tokeninfo (C type)@\spxentry{krb5\_responder\_otp\_tokeninfo}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_otp\_tokeninfo}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:declaration}} \sphinxAtStartPar typedef struct \_krb5\_responder\_otp\_tokeninfo krb5\_responder\_otp\_tokeninfo \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:members}}\index{krb5\_responder\_otp\_tokeninfo.flags (C member)@\spxentry{krb5\_responder\_otp\_tokeninfo.flags}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo.flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_tokeninfo}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{flags}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_responder\_otp\_tokeninfo.format (C member)@\spxentry{krb5\_responder\_otp\_tokeninfo.format}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo.format}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_tokeninfo}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{format}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_responder\_otp\_tokeninfo.length (C member)@\spxentry{krb5\_responder\_otp\_tokeninfo.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_tokeninfo}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_responder\_otp\_tokeninfo.vendor (C member)@\spxentry{krb5\_responder\_otp\_tokeninfo.vendor}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo.vendor}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_tokeninfo}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{vendor}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_responder\_otp\_tokeninfo.challenge (C member)@\spxentry{krb5\_responder\_otp\_tokeninfo.challenge}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo.challenge}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_tokeninfo}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{challenge}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_responder\_otp\_tokeninfo.token\_id (C member)@\spxentry{krb5\_responder\_otp\_tokeninfo.token\_id}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo.token_id}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_tokeninfo}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{token\_id}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_responder\_otp\_tokeninfo.alg\_id (C member)@\spxentry{krb5\_responder\_otp\_tokeninfo.alg\_id}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo.alg_id}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_otp_tokeninfo:c.krb5_responder_otp_tokeninfo}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_otp\_tokeninfo}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{alg\_id}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_responder\_pkinit\_challenge} \label{\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge:krb5-responder-pkinit-challenge}}\label{\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge:krb5-responder-pkinit-challenge-struct}}\label{\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge::doc}}\index{krb5\_responder\_pkinit\_challenge (C type)@\spxentry{krb5\_responder\_pkinit\_challenge}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge:c.krb5_responder_pkinit_challenge}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_pkinit\_challenge}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge:declaration}} \sphinxAtStartPar typedef struct \_krb5\_responder\_pkinit\_challenge krb5\_responder\_pkinit\_challenge \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge:members}}\index{krb5\_responder\_pkinit\_challenge.identities (C member)@\spxentry{krb5\_responder\_pkinit\_challenge.identities}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge:c.krb5_responder_pkinit_challenge.identities}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:c.krb5_responder_pkinit_identity}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_pkinit\_identity}}}}\DUrole{w}{ }\DUrole{p}{*}\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_pkinit_challenge:c.krb5_responder_pkinit_challenge}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_pkinit\_challenge}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{identities}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_responder\_pkinit\_identity} \label{\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:krb5-responder-pkinit-identity}}\label{\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:krb5-responder-pkinit-identity-struct}}\label{\detokenize{appdev/refs/types/krb5_responder_pkinit_identity::doc}}\index{krb5\_responder\_pkinit\_identity (C type)@\spxentry{krb5\_responder\_pkinit\_identity}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:c.krb5_responder_pkinit_identity}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_responder\_pkinit\_identity}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:declaration}} \sphinxAtStartPar typedef struct \_krb5\_responder\_pkinit\_identity krb5\_responder\_pkinit\_identity \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:members}}\index{krb5\_responder\_pkinit\_identity.identity (C member)@\spxentry{krb5\_responder\_pkinit\_identity.identity}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:c.krb5_responder_pkinit_identity.identity}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:c.krb5_responder_pkinit_identity}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_pkinit\_identity}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{identity}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_responder\_pkinit\_identity.token\_flags (C member)@\spxentry{krb5\_responder\_pkinit\_identity.token\_flags}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:c.krb5_responder_pkinit_identity.token_flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_responder_pkinit_identity:c.krb5_responder_pkinit_identity}]{\sphinxcrossref{\DUrole{n}{krb5\_responder\_pkinit\_identity}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{token\_flags}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_response} \label{\detokenize{appdev/refs/types/krb5_response:krb5-response}}\label{\detokenize{appdev/refs/types/krb5_response:krb5-response-struct}}\label{\detokenize{appdev/refs/types/krb5_response::doc}}\index{krb5\_response (C type)@\spxentry{krb5\_response}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_response:c.krb5_response}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_response}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_response:declaration}} \sphinxAtStartPar typedef struct \_krb5\_response krb5\_response \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_response:members}}\index{krb5\_response.magic (C member)@\spxentry{krb5\_response.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_response:c.krb5_response.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_response:c.krb5_response}]{\sphinxcrossref{\DUrole{n}{krb5\_response}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_response.message\_type (C member)@\spxentry{krb5\_response.message\_type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_response:c.krb5_response.message_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_octet:c.krb5_octet}]{\sphinxcrossref{\DUrole{n}{krb5\_octet}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_response:c.krb5_response}]{\sphinxcrossref{\DUrole{n}{krb5\_response}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{message\_type}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_response.response (C member)@\spxentry{krb5\_response.response}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_response:c.krb5_response.response}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_response:c.krb5_response}]{\sphinxcrossref{\DUrole{n}{krb5\_response}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{response}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_response.expected\_nonce (C member)@\spxentry{krb5\_response.expected\_nonce}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_response:c.krb5_response.expected_nonce}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_response:c.krb5_response}]{\sphinxcrossref{\DUrole{n}{krb5\_response}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{expected\_nonce}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_response.request\_time (C member)@\spxentry{krb5\_response.request\_time}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_response:c.krb5_response.request_time}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_response:c.krb5_response}]{\sphinxcrossref{\DUrole{n}{krb5\_response}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{request\_time}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_replay\_data} \label{\detokenize{appdev/refs/types/krb5_replay_data:krb5-replay-data}}\label{\detokenize{appdev/refs/types/krb5_replay_data:krb5-replay-data-struct}}\label{\detokenize{appdev/refs/types/krb5_replay_data::doc}}\index{krb5\_replay\_data (C type)@\spxentry{krb5\_replay\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_replay\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Replay data. \sphinxAtStartPar Sequence number and timestamp information output by krb5\_rd\_priv() and krb5\_rd\_safe(). \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_replay_data:declaration}} \sphinxAtStartPar typedef struct krb5\_replay\_data krb5\_replay\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_replay_data:members}}\index{krb5\_replay\_data.timestamp (C member)@\spxentry{krb5\_replay\_data.timestamp}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data.timestamp}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{timestamp}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Timestamp, seconds portion. \end{fulllineitems} \index{krb5\_replay\_data.usec (C member)@\spxentry{krb5\_replay\_data.usec}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data.usec}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{usec}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Timestamp, microseconds portion. \end{fulllineitems} \index{krb5\_replay\_data.seq (C member)@\spxentry{krb5\_replay\_data.seq}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data.seq}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ui_4:c.krb5_ui_4}]{\sphinxcrossref{\DUrole{n}{krb5\_ui\_4}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_replay_data:c.krb5_replay_data}]{\sphinxcrossref{\DUrole{n}{krb5\_replay\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{seq}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Sequence number. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_ticket} \label{\detokenize{appdev/refs/types/krb5_ticket:krb5-ticket}}\label{\detokenize{appdev/refs/types/krb5_ticket:krb5-ticket-struct}}\label{\detokenize{appdev/refs/types/krb5_ticket::doc}}\index{krb5\_ticket (C type)@\spxentry{krb5\_ticket}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_ticket}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Ticket structure. \sphinxAtStartPar The C representation of the ticket message, with a pointer to the C representation of the encrypted part. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_ticket:declaration}} \sphinxAtStartPar typedef struct \_krb5\_ticket krb5\_ticket \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_ticket:members}}\index{krb5\_ticket.magic (C member)@\spxentry{krb5\_ticket.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_ticket.server (C member)@\spxentry{krb5\_ticket.server}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket.server}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_principal:c.krb5_principal}]{\sphinxcrossref{\DUrole{n}{krb5\_principal}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{server}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar server name/realm \end{fulllineitems} \index{krb5\_ticket.enc\_part (C member)@\spxentry{krb5\_ticket.enc\_part}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket.enc_part}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_data:c.krb5_enc_data}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enc\_part}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar encryption type, kvno, encrypted encoding \end{fulllineitems} \index{krb5\_ticket.enc\_part2 (C member)@\spxentry{krb5\_ticket.enc\_part2}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket.enc_part2}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_enc_tkt_part:c.krb5_enc_tkt_part}]{\sphinxcrossref{\DUrole{n}{krb5\_enc\_tkt\_part}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{enc\_part2}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar ptr to decrypted version, if available \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_ticket\_times} \label{\detokenize{appdev/refs/types/krb5_ticket_times:krb5-ticket-times}}\label{\detokenize{appdev/refs/types/krb5_ticket_times:krb5-ticket-times-struct}}\label{\detokenize{appdev/refs/types/krb5_ticket_times::doc}}\index{krb5\_ticket\_times (C type)@\spxentry{krb5\_ticket\_times}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_ticket\_times}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Ticket start time, end time, and renewal duration. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_ticket_times:declaration}} \sphinxAtStartPar typedef struct \_krb5\_ticket\_times krb5\_ticket\_times \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_ticket_times:members}}\index{krb5\_ticket\_times.authtime (C member)@\spxentry{krb5\_ticket\_times.authtime}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times.authtime}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{authtime}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Time at which KDC issued the initial ticket that corresponds to this ticket. \end{fulllineitems} \index{krb5\_ticket\_times.starttime (C member)@\spxentry{krb5\_ticket\_times.starttime}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times.starttime}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{starttime}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar optional in ticket, if not present, use \sphinxstyleemphasis{authtime} \end{fulllineitems} \index{krb5\_ticket\_times.endtime (C member)@\spxentry{krb5\_ticket\_times.endtime}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times.endtime}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{endtime}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Ticket expiration time. \end{fulllineitems} \index{krb5\_ticket\_times.renew\_till (C member)@\spxentry{krb5\_ticket\_times.renew\_till}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times.renew_till}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}]{\sphinxcrossref{\DUrole{n}{krb5\_timestamp}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket_times:c.krb5_ticket_times}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket\_times}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{renew\_till}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Latest time at which renewal of ticket can be valid. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_timestamp} \label{\detokenize{appdev/refs/types/krb5_timestamp:krb5-timestamp}}\label{\detokenize{appdev/refs/types/krb5_timestamp:krb5-timestamp-struct}}\label{\detokenize{appdev/refs/types/krb5_timestamp::doc}}\index{krb5\_timestamp (C type)@\spxentry{krb5\_timestamp}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_timestamp:c.krb5_timestamp}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_timestamp}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Represents a timestamp in seconds since the POSIX epoch. \sphinxAtStartPar This legacy type is used frequently in the ABI, but cannot represent timestamps after 2038 as a positive number. Code which uses this type should cast values of it to uint32\_t so that negative values are treated as timestamps between 2038 and 2106 on platforms with 64\sphinxhyphen{}bit time\_t. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_timestamp:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_timestamp \sphinxstepscope \subsubsection{krb5\_tkt\_authent} \label{\detokenize{appdev/refs/types/krb5_tkt_authent:krb5-tkt-authent}}\label{\detokenize{appdev/refs/types/krb5_tkt_authent:krb5-tkt-authent-struct}}\label{\detokenize{appdev/refs/types/krb5_tkt_authent::doc}}\index{krb5\_tkt\_authent (C type)@\spxentry{krb5\_tkt\_authent}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_tkt_authent:c.krb5_tkt_authent}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_tkt\_authent}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Ticket authentication data. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_tkt_authent:declaration}} \sphinxAtStartPar typedef struct \_krb5\_tkt\_authent krb5\_tkt\_authent \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_tkt_authent:members}}\index{krb5\_tkt\_authent.magic (C member)@\spxentry{krb5\_tkt\_authent.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_tkt_authent:c.krb5_tkt_authent.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_tkt_authent:c.krb5_tkt_authent}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_authent}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_tkt\_authent.ticket (C member)@\spxentry{krb5\_tkt\_authent.ticket}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_tkt_authent:c.krb5_tkt_authent.ticket}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_ticket:c.krb5_ticket}]{\sphinxcrossref{\DUrole{n}{krb5\_ticket}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_tkt_authent:c.krb5_tkt_authent}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_authent}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ticket}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_tkt\_authent.authenticator (C member)@\spxentry{krb5\_tkt\_authent.authenticator}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_tkt_authent:c.krb5_tkt_authent.authenticator}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_authenticator:c.krb5_authenticator}]{\sphinxcrossref{\DUrole{n}{krb5\_authenticator}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_tkt_authent:c.krb5_tkt_authent}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_authent}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{authenticator}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_tkt\_authent.ap\_options (C member)@\spxentry{krb5\_tkt\_authent.ap\_options}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_tkt_authent:c.krb5_tkt_authent.ap_options}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_tkt_authent:c.krb5_tkt_authent}]{\sphinxcrossref{\DUrole{n}{krb5\_tkt\_authent}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ap\_options}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_trace\_callback} \label{\detokenize{appdev/refs/types/krb5_trace_callback:krb5-trace-callback}}\label{\detokenize{appdev/refs/types/krb5_trace_callback:krb5-trace-callback-struct}}\label{\detokenize{appdev/refs/types/krb5_trace_callback::doc}}\index{krb5\_trace\_callback (C type)@\spxentry{krb5\_trace\_callback}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_trace_callback:c.krb5_trace_callback}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_trace\_callback}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_trace_callback:declaration}} \sphinxAtStartPar typedef void( * krb5\_trace\_callback) (krb5\_context context, const krb5\_trace\_info *info, void *cb\_data) \sphinxstepscope \subsubsection{krb5\_trace\_info} \label{\detokenize{appdev/refs/types/krb5_trace_info:krb5-trace-info}}\label{\detokenize{appdev/refs/types/krb5_trace_info:krb5-trace-info-struct}}\label{\detokenize{appdev/refs/types/krb5_trace_info::doc}}\index{krb5\_trace\_info (C type)@\spxentry{krb5\_trace\_info}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_trace_info:c.krb5_trace_info}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_trace\_info}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar A wrapper for passing information to a \sphinxstyleemphasis{krb5\_trace\_callback} . \sphinxAtStartPar Currently, it only contains the formatted message as determined the the format string and arguments of the tracing macro, but it may be extended to contain more fields in the future. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_trace_info:declaration}} \sphinxAtStartPar typedef struct \_krb5\_trace\_info krb5\_trace\_info \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_trace_info:members}}\index{krb5\_trace\_info.message (C member)@\spxentry{krb5\_trace\_info.message}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_trace_info:c.krb5_trace_info.message}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{const}\DUrole{w}{ }\DUrole{kt}{char}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_trace_info:c.krb5_trace_info}]{\sphinxcrossref{\DUrole{n}{krb5\_trace\_info}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{message}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_transited} \label{\detokenize{appdev/refs/types/krb5_transited:krb5-transited}}\label{\detokenize{appdev/refs/types/krb5_transited:krb5-transited-struct}}\label{\detokenize{appdev/refs/types/krb5_transited::doc}}\index{krb5\_transited (C type)@\spxentry{krb5\_transited}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_transited:c.krb5_transited}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_transited}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Structure for transited encoding. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_transited:declaration}} \sphinxAtStartPar typedef struct \_krb5\_transited krb5\_transited \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_transited:members}}\index{krb5\_transited.magic (C member)@\spxentry{krb5\_transited.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_transited:c.krb5_transited.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_transited:c.krb5_transited}]{\sphinxcrossref{\DUrole{n}{krb5\_transited}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_transited.tr\_type (C member)@\spxentry{krb5\_transited.tr\_type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_transited:c.krb5_transited.tr_type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_octet:c.krb5_octet}]{\sphinxcrossref{\DUrole{n}{krb5\_octet}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_transited:c.krb5_transited}]{\sphinxcrossref{\DUrole{n}{krb5\_transited}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{tr\_type}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Transited encoding type. \end{fulllineitems} \index{krb5\_transited.tr\_contents (C member)@\spxentry{krb5\_transited.tr\_contents}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_transited:c.krb5_transited.tr_contents}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_transited:c.krb5_transited}]{\sphinxcrossref{\DUrole{n}{krb5\_transited}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{tr\_contents}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar Contents. \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_typed\_data} \label{\detokenize{appdev/refs/types/krb5_typed_data:krb5-typed-data}}\label{\detokenize{appdev/refs/types/krb5_typed_data:krb5-typed-data-struct}}\label{\detokenize{appdev/refs/types/krb5_typed_data::doc}}\index{krb5\_typed\_data (C type)@\spxentry{krb5\_typed\_data}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_typed_data:c.krb5_typed_data}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_typed\_data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_typed_data:declaration}} \sphinxAtStartPar typedef struct \_krb5\_typed\_data krb5\_typed\_data \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_typed_data:members}}\index{krb5\_typed\_data.magic (C member)@\spxentry{krb5\_typed\_data.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_typed_data:c.krb5_typed_data.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_typed_data:c.krb5_typed_data}]{\sphinxcrossref{\DUrole{n}{krb5\_typed\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_typed\_data.type (C member)@\spxentry{krb5\_typed\_data.type}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_typed_data:c.krb5_typed_data.type}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_int32:c.krb5_int32}]{\sphinxcrossref{\DUrole{n}{krb5\_int32}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_typed_data:c.krb5_typed_data}]{\sphinxcrossref{\DUrole{n}{krb5\_typed\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{type}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_typed\_data.length (C member)@\spxentry{krb5\_typed\_data.length}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_typed_data:c.krb5_typed_data.length}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{unsigned}\DUrole{w}{ }\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_typed_data:c.krb5_typed_data}]{\sphinxcrossref{\DUrole{n}{krb5\_typed\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{length}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_typed\_data.data (C member)@\spxentry{krb5\_typed\_data.data}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_typed_data:c.krb5_typed_data.data}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_octet:c.krb5_octet}]{\sphinxcrossref{\DUrole{n}{krb5\_octet}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_typed_data:c.krb5_typed_data}]{\sphinxcrossref{\DUrole{n}{krb5\_typed\_data}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{data}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxstepscope \subsubsection{krb5\_ui\_2} \label{\detokenize{appdev/refs/types/krb5_ui_2:krb5-ui-2}}\label{\detokenize{appdev/refs/types/krb5_ui_2:krb5-ui-2-struct}}\label{\detokenize{appdev/refs/types/krb5_ui_2::doc}}\index{krb5\_ui\_2 (C type)@\spxentry{krb5\_ui\_2}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ui_2:c.krb5_ui_2}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_ui\_2}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_ui_2:declaration}} \sphinxAtStartPar typedef uint16\_t krb5\_ui\_2 \sphinxstepscope \subsubsection{krb5\_ui\_4} \label{\detokenize{appdev/refs/types/krb5_ui_4:krb5-ui-4}}\label{\detokenize{appdev/refs/types/krb5_ui_4:krb5-ui-4-struct}}\label{\detokenize{appdev/refs/types/krb5_ui_4::doc}}\index{krb5\_ui\_4 (C type)@\spxentry{krb5\_ui\_4}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ui_4:c.krb5_ui_4}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_ui\_4}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_ui_4:declaration}} \sphinxAtStartPar typedef uint32\_t krb5\_ui\_4 \sphinxstepscope \subsubsection{krb5\_verify\_init\_creds\_opt} \label{\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:krb5-verify-init-creds-opt}}\label{\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:krb5-verify-init-creds-opt-struct}}\label{\detokenize{appdev/refs/types/krb5_verify_init_creds_opt::doc}}\index{krb5\_verify\_init\_creds\_opt (C type)@\spxentry{krb5\_verify\_init\_creds\_opt}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:c.krb5_verify_init_creds_opt}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_verify\_init\_creds\_opt}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:declaration}} \sphinxAtStartPar typedef struct \_krb5\_verify\_init\_creds\_opt krb5\_verify\_init\_creds\_opt \paragraph{Members} \label{\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:members}}\index{krb5\_verify\_init\_creds\_opt.flags (C member)@\spxentry{krb5\_verify\_init\_creds\_opt.flags}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:c.krb5_verify_init_creds_opt.flags}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_flags:c.krb5_flags}]{\sphinxcrossref{\DUrole{n}{krb5\_flags}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:c.krb5_verify_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_verify\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{flags}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{krb5\_verify\_init\_creds\_opt.ap\_req\_nofail (C member)@\spxentry{krb5\_verify\_init\_creds\_opt.ap\_req\_nofail}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:c.krb5_verify_init_creds_opt.ap_req_nofail}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{kt}{int}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/krb5_verify_init_creds_opt:c.krb5_verify_init_creds_opt}]{\sphinxcrossref{\DUrole{n}{krb5\_verify\_init\_creds\_opt}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{ap\_req\_nofail}}}} \pysigstopmultiline \pysigstopsignatures \sphinxAtStartPar boolean \end{fulllineitems} \sphinxstepscope \subsubsection{passwd\_phrase\_element} \label{\detokenize{appdev/refs/types/passwd_phrase_element:passwd-phrase-element}}\label{\detokenize{appdev/refs/types/passwd_phrase_element:passwd-phrase-element-struct}}\label{\detokenize{appdev/refs/types/passwd_phrase_element::doc}}\index{passwd\_phrase\_element (C type)@\spxentry{passwd\_phrase\_element}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/passwd_phrase_element:c.passwd_phrase_element}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{passwd\_phrase\_element}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/passwd_phrase_element:declaration}} \sphinxAtStartPar typedef struct \_passwd\_phrase\_element passwd\_phrase\_element \paragraph{Members} \label{\detokenize{appdev/refs/types/passwd_phrase_element:members}}\index{passwd\_phrase\_element.magic (C member)@\spxentry{passwd\_phrase\_element.magic}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/passwd_phrase_element:c.passwd_phrase_element.magic}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_magic:c.krb5_magic}]{\sphinxcrossref{\DUrole{n}{krb5\_magic}}}}\DUrole{w}{ }\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/passwd_phrase_element:c.passwd_phrase_element}]{\sphinxcrossref{\DUrole{n}{passwd\_phrase\_element}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{magic}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{passwd\_phrase\_element.passwd (C member)@\spxentry{passwd\_phrase\_element.passwd}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/passwd_phrase_element:c.passwd_phrase_element.passwd}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/passwd_phrase_element:c.passwd_phrase_element}]{\sphinxcrossref{\DUrole{n}{passwd\_phrase\_element}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{passwd}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \index{passwd\_phrase\_element.phrase (C member)@\spxentry{passwd\_phrase\_element.phrase}\spxextra{C member}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/passwd_phrase_element:c.passwd_phrase_element.phrase}} \pysigstartsignatures \pysigstartmultiline \pysigline{{\hyperref[\detokenize{appdev/refs/types/krb5_data:c.krb5_data}]{\sphinxcrossref{\DUrole{n}{krb5\_data}}}}\DUrole{w}{ }\DUrole{p}{*}\sphinxcode{\sphinxupquote{{\hyperref[\detokenize{appdev/refs/types/passwd_phrase_element:c.passwd_phrase_element}]{\sphinxcrossref{\DUrole{n}{passwd\_phrase\_element}}}}\DUrole{p}{.}}}\sphinxbfcode{\sphinxupquote{\DUrole{n}{phrase}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \subsection{Internal} \label{\detokenize{appdev/refs/types/index:internal}} \sphinxstepscope \subsubsection{krb5\_auth\_context} \label{\detokenize{appdev/refs/types/krb5_auth_context:krb5-auth-context}}\label{\detokenize{appdev/refs/types/krb5_auth_context:krb5-auth-context-struct}}\label{\detokenize{appdev/refs/types/krb5_auth_context::doc}}\index{krb5\_auth\_context (C type)@\spxentry{krb5\_auth\_context}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_auth_context:c.krb5_auth_context}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_auth\_context}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_auth_context:declaration}} \sphinxAtStartPar typedef struct \_krb5\_auth\_context* krb5\_auth\_context \sphinxstepscope \subsubsection{krb5\_cksumtype} \label{\detokenize{appdev/refs/types/krb5_cksumtype:krb5-cksumtype}}\label{\detokenize{appdev/refs/types/krb5_cksumtype:krb5-cksumtype-struct}}\label{\detokenize{appdev/refs/types/krb5_cksumtype::doc}}\index{krb5\_cksumtype (C type)@\spxentry{krb5\_cksumtype}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cksumtype:c.krb5_cksumtype}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cksumtype}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_cksumtype:declaration}} \sphinxAtStartPar typedef krb5\_int32 krb5\_cksumtype \sphinxstepscope \subsubsection{krb5\_context} \label{\detokenize{appdev/refs/types/krb5_context:krb5-context}}\label{\detokenize{appdev/refs/types/krb5_context:krb5-context-struct}}\label{\detokenize{appdev/refs/types/krb5_context::doc}}\index{krb5\_context (C type)@\spxentry{krb5\_context}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_context:c.krb5_context}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_context}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_context:declaration}} \sphinxAtStartPar typedef struct \_krb5\_context* krb5\_context \sphinxstepscope \subsubsection{krb5\_cc\_cursor} \label{\detokenize{appdev/refs/types/krb5_cc_cursor:krb5-cc-cursor}}\label{\detokenize{appdev/refs/types/krb5_cc_cursor:krb5-cc-cursor-struct}}\label{\detokenize{appdev/refs/types/krb5_cc_cursor::doc}}\index{krb5\_cc\_cursor (C type)@\spxentry{krb5\_cc\_cursor}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cc_cursor:c.krb5_cc_cursor}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cc\_cursor}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Cursor for sequential lookup. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_cc_cursor:declaration}} \sphinxAtStartPar typedef krb5\_pointer krb5\_cc\_cursor \sphinxstepscope \subsubsection{krb5\_ccache} \label{\detokenize{appdev/refs/types/krb5_ccache:krb5-ccache}}\label{\detokenize{appdev/refs/types/krb5_ccache:krb5-ccache-struct}}\label{\detokenize{appdev/refs/types/krb5_ccache::doc}}\index{krb5\_ccache (C type)@\spxentry{krb5\_ccache}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_ccache:c.krb5_ccache}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_ccache}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_ccache:declaration}} \sphinxAtStartPar typedef struct \_krb5\_ccache* krb5\_ccache \sphinxstepscope \subsubsection{krb5\_cccol\_cursor} \label{\detokenize{appdev/refs/types/krb5_cccol_cursor:krb5-cccol-cursor}}\label{\detokenize{appdev/refs/types/krb5_cccol_cursor:krb5-cccol-cursor-struct}}\label{\detokenize{appdev/refs/types/krb5_cccol_cursor::doc}}\index{krb5\_cccol\_cursor (C type)@\spxentry{krb5\_cccol\_cursor}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_cccol_cursor:c.krb5_cccol_cursor}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_cccol\_cursor}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Cursor for iterating over all ccaches. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_cccol_cursor:declaration}} \sphinxAtStartPar typedef struct \_krb5\_cccol\_cursor* krb5\_cccol\_cursor \sphinxstepscope \subsubsection{krb5\_init\_creds\_context} \label{\detokenize{appdev/refs/types/krb5_init_creds_context:krb5-init-creds-context}}\label{\detokenize{appdev/refs/types/krb5_init_creds_context:krb5-init-creds-context-struct}}\label{\detokenize{appdev/refs/types/krb5_init_creds_context::doc}}\index{krb5\_init\_creds\_context (C type)@\spxentry{krb5\_init\_creds\_context}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_init_creds_context:c.krb5_init_creds_context}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_init\_creds\_context}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_init_creds_context:declaration}} \sphinxAtStartPar typedef struct \_krb5\_init\_creds\_context* krb5\_init\_creds\_context \sphinxstepscope \subsubsection{krb5\_key} \label{\detokenize{appdev/refs/types/krb5_key:krb5-key}}\label{\detokenize{appdev/refs/types/krb5_key:krb5-key-struct}}\label{\detokenize{appdev/refs/types/krb5_key::doc}}\index{krb5\_key (C type)@\spxentry{krb5\_key}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_key:c.krb5_key}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_key}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Opaque identifier for a key. \sphinxAtStartPar Use with the krb5\_k APIs for better performance for repeated operations with the same key and usage. Key identifiers must not be used simultaneously within multiple threads, as they may contain mutable internal state and are not mutex\sphinxhyphen{}protected. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_key:declaration}} \sphinxAtStartPar typedef struct krb5\_key\_st* krb5\_key \sphinxstepscope \subsubsection{krb5\_keytab} \label{\detokenize{appdev/refs/types/krb5_keytab:krb5-keytab}}\label{\detokenize{appdev/refs/types/krb5_keytab:krb5-keytab-struct}}\label{\detokenize{appdev/refs/types/krb5_keytab::doc}}\index{krb5\_keytab (C type)@\spxentry{krb5\_keytab}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_keytab:c.krb5_keytab}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_keytab}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_keytab:declaration}} \sphinxAtStartPar typedef struct \_krb5\_kt* krb5\_keytab \sphinxstepscope \subsubsection{krb5\_pac} \label{\detokenize{appdev/refs/types/krb5_pac:krb5-pac}}\label{\detokenize{appdev/refs/types/krb5_pac:krb5-pac-struct}}\label{\detokenize{appdev/refs/types/krb5_pac::doc}}\index{krb5\_pac (C type)@\spxentry{krb5\_pac}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_pac:c.krb5_pac}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_pac}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar PAC data structure to convey authorization information. \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_pac:declaration}} \sphinxAtStartPar typedef struct krb5\_pac\_data* krb5\_pac \sphinxstepscope \subsubsection{krb5\_rcache} \label{\detokenize{appdev/refs/types/krb5_rcache:krb5-rcache}}\label{\detokenize{appdev/refs/types/krb5_rcache:krb5-rcache-struct}}\label{\detokenize{appdev/refs/types/krb5_rcache::doc}}\index{krb5\_rcache (C type)@\spxentry{krb5\_rcache}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_rcache:c.krb5_rcache}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_rcache}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_rcache:declaration}} \sphinxAtStartPar typedef struct krb5\_rc\_st* krb5\_rcache \sphinxstepscope \subsubsection{krb5\_tkt\_creds\_context} \label{\detokenize{appdev/refs/types/krb5_tkt_creds_context:krb5-tkt-creds-context}}\label{\detokenize{appdev/refs/types/krb5_tkt_creds_context:krb5-tkt-creds-context-struct}}\label{\detokenize{appdev/refs/types/krb5_tkt_creds_context::doc}}\index{krb5\_tkt\_creds\_context (C type)@\spxentry{krb5\_tkt\_creds\_context}\spxextra{C type}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/types/krb5_tkt_creds_context:c.krb5_tkt_creds_context}} \pysigstartsignatures \pysigstartmultiline \pysigline{\DUrole{k}{type}\DUrole{w}{ }\sphinxbfcode{\sphinxupquote{\DUrole{n}{krb5\_tkt\_creds\_context}}}} \pysigstopmultiline \pysigstopsignatures \end{fulllineitems} \paragraph{Declaration} \label{\detokenize{appdev/refs/types/krb5_tkt_creds_context:declaration}} \sphinxAtStartPar typedef struct \_krb5\_tkt\_creds\_context* krb5\_tkt\_creds\_context \sphinxstepscope \section{krb5 simple macros} \label{\detokenize{appdev/refs/macros/index:krb5-simple-macros}}\label{\detokenize{appdev/refs/macros/index::doc}} \subsection{Public} \label{\detokenize{appdev/refs/macros/index:public}} \sphinxstepscope \subsubsection{ADDRTYPE\_ADDRPORT} \label{\detokenize{appdev/refs/macros/ADDRTYPE_ADDRPORT:addrtype-addrport}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_ADDRPORT:addrtype-addrport-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_ADDRPORT::doc}}\index{ADDRTYPE\_ADDRPORT (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_ADDRPORT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_ADDRPORT:ADDRTYPE_ADDRPORT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_ADDRPORT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_ADDRPORT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0100}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_CHAOS} \label{\detokenize{appdev/refs/macros/ADDRTYPE_CHAOS:addrtype-chaos}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_CHAOS:addrtype-chaos-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_CHAOS::doc}}\index{ADDRTYPE\_CHAOS (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_CHAOS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_CHAOS:ADDRTYPE_CHAOS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_CHAOS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_CHAOS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0005}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_DIRECTIONAL} \label{\detokenize{appdev/refs/macros/ADDRTYPE_DIRECTIONAL:addrtype-directional}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_DIRECTIONAL:addrtype-directional-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_DIRECTIONAL::doc}}\index{ADDRTYPE\_DIRECTIONAL (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_DIRECTIONAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_DIRECTIONAL:ADDRTYPE_DIRECTIONAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_DIRECTIONAL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_DIRECTIONAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0003}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_DDP} \label{\detokenize{appdev/refs/macros/ADDRTYPE_DDP:addrtype-ddp}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_DDP:addrtype-ddp-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_DDP::doc}}\index{ADDRTYPE\_DDP (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_DDP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_DDP:ADDRTYPE_DDP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_DDP}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_DDP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0010}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_INET} \label{\detokenize{appdev/refs/macros/ADDRTYPE_INET:addrtype-inet}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_INET:addrtype-inet-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_INET::doc}}\index{ADDRTYPE\_INET (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_INET}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_INET:ADDRTYPE_INET}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_INET}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_INET}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_INET6} \label{\detokenize{appdev/refs/macros/ADDRTYPE_INET6:addrtype-inet6}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_INET6:addrtype-inet6-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_INET6::doc}}\index{ADDRTYPE\_INET6 (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_INET6}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_INET6:ADDRTYPE_INET6}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_INET6}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_INET6}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0018}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_IPPORT} \label{\detokenize{appdev/refs/macros/ADDRTYPE_IPPORT:addrtype-ipport}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_IPPORT:addrtype-ipport-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_IPPORT::doc}}\index{ADDRTYPE\_IPPORT (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_IPPORT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_IPPORT:ADDRTYPE_IPPORT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_IPPORT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_IPPORT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0101}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_ISO} \label{\detokenize{appdev/refs/macros/ADDRTYPE_ISO:addrtype-iso}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_ISO:addrtype-iso-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_ISO::doc}}\index{ADDRTYPE\_ISO (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_ISO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_ISO:ADDRTYPE_ISO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_ISO}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_ISO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0007}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_IS\_LOCAL} \label{\detokenize{appdev/refs/macros/ADDRTYPE_IS_LOCAL:addrtype-is-local}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_IS_LOCAL:addrtype-is-local-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_IS_LOCAL::doc}}\index{ADDRTYPE\_IS\_LOCAL (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_IS\_LOCAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_IS_LOCAL:ADDRTYPE_IS_LOCAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_IS\_LOCAL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_IS\_LOCAL (addrtype)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(addrtype \& 0x8000)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_NETBIOS} \label{\detokenize{appdev/refs/macros/ADDRTYPE_NETBIOS:addrtype-netbios}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_NETBIOS:addrtype-netbios-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_NETBIOS::doc}}\index{ADDRTYPE\_NETBIOS (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_NETBIOS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_NETBIOS:ADDRTYPE_NETBIOS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_NETBIOS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_NETBIOS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0014}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_XNS} \label{\detokenize{appdev/refs/macros/ADDRTYPE_XNS:addrtype-xns}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_XNS:addrtype-xns-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_XNS::doc}}\index{ADDRTYPE\_XNS (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_XNS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_XNS:ADDRTYPE_XNS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_XNS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_XNS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0006}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ADDRTYPE\_UNIXSOCK} \label{\detokenize{appdev/refs/macros/ADDRTYPE_UNIXSOCK:addrtype-unixsock}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_UNIXSOCK:addrtype-unixsock-data}}\label{\detokenize{appdev/refs/macros/ADDRTYPE_UNIXSOCK::doc}}\index{ADDRTYPE\_UNIXSOCK (built\sphinxhyphen{}in variable)@\spxentry{ADDRTYPE\_UNIXSOCK}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ADDRTYPE_UNIXSOCK:ADDRTYPE_UNIXSOCK}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ADDRTYPE\_UNIXSOCK}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ADDRTYPE\_UNIXSOCK}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(0x8000 | 0x0001)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AD\_TYPE\_EXTERNAL} \label{\detokenize{appdev/refs/macros/AD_TYPE_EXTERNAL:ad-type-external}}\label{\detokenize{appdev/refs/macros/AD_TYPE_EXTERNAL:ad-type-external-data}}\label{\detokenize{appdev/refs/macros/AD_TYPE_EXTERNAL::doc}}\index{AD\_TYPE\_EXTERNAL (built\sphinxhyphen{}in variable)@\spxentry{AD\_TYPE\_EXTERNAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AD_TYPE_EXTERNAL:AD_TYPE_EXTERNAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AD\_TYPE\_EXTERNAL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AD\_TYPE\_EXTERNAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x4000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AD\_TYPE\_FIELD\_TYPE\_MASK} \label{\detokenize{appdev/refs/macros/AD_TYPE_FIELD_TYPE_MASK:ad-type-field-type-mask}}\label{\detokenize{appdev/refs/macros/AD_TYPE_FIELD_TYPE_MASK:ad-type-field-type-mask-data}}\label{\detokenize{appdev/refs/macros/AD_TYPE_FIELD_TYPE_MASK::doc}}\index{AD\_TYPE\_FIELD\_TYPE\_MASK (built\sphinxhyphen{}in variable)@\spxentry{AD\_TYPE\_FIELD\_TYPE\_MASK}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AD_TYPE_FIELD_TYPE_MASK:AD_TYPE_FIELD_TYPE_MASK}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AD\_TYPE\_FIELD\_TYPE\_MASK}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AD\_TYPE\_FIELD\_TYPE\_MASK}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x1fff}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AD\_TYPE\_REGISTERED} \label{\detokenize{appdev/refs/macros/AD_TYPE_REGISTERED:ad-type-registered}}\label{\detokenize{appdev/refs/macros/AD_TYPE_REGISTERED:ad-type-registered-data}}\label{\detokenize{appdev/refs/macros/AD_TYPE_REGISTERED::doc}}\index{AD\_TYPE\_REGISTERED (built\sphinxhyphen{}in variable)@\spxentry{AD\_TYPE\_REGISTERED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AD_TYPE_REGISTERED:AD_TYPE_REGISTERED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AD\_TYPE\_REGISTERED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AD\_TYPE\_REGISTERED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x2000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AD\_TYPE\_RESERVED} \label{\detokenize{appdev/refs/macros/AD_TYPE_RESERVED:ad-type-reserved}}\label{\detokenize{appdev/refs/macros/AD_TYPE_RESERVED:ad-type-reserved-data}}\label{\detokenize{appdev/refs/macros/AD_TYPE_RESERVED::doc}}\index{AD\_TYPE\_RESERVED (built\sphinxhyphen{}in variable)@\spxentry{AD\_TYPE\_RESERVED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AD_TYPE_RESERVED:AD_TYPE_RESERVED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AD\_TYPE\_RESERVED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AD\_TYPE\_RESERVED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x8000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AP\_OPTS\_ETYPE\_NEGOTIATION} \label{\detokenize{appdev/refs/macros/AP_OPTS_ETYPE_NEGOTIATION:ap-opts-etype-negotiation}}\label{\detokenize{appdev/refs/macros/AP_OPTS_ETYPE_NEGOTIATION:ap-opts-etype-negotiation-data}}\label{\detokenize{appdev/refs/macros/AP_OPTS_ETYPE_NEGOTIATION::doc}}\index{AP\_OPTS\_ETYPE\_NEGOTIATION (built\sphinxhyphen{}in variable)@\spxentry{AP\_OPTS\_ETYPE\_NEGOTIATION}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AP_OPTS_ETYPE_NEGOTIATION:AP_OPTS_ETYPE_NEGOTIATION}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AP\_OPTS\_ETYPE\_NEGOTIATION}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AP\_OPTS\_ETYPE\_NEGOTIATION}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AP\_OPTS\_CBT\_FLAG} \label{\detokenize{appdev/refs/macros/AP_OPTS_CBT_FLAG:ap-opts-cbt-flag}}\label{\detokenize{appdev/refs/macros/AP_OPTS_CBT_FLAG:ap-opts-cbt-flag-data}}\label{\detokenize{appdev/refs/macros/AP_OPTS_CBT_FLAG::doc}}\index{AP\_OPTS\_CBT\_FLAG (built\sphinxhyphen{}in variable)@\spxentry{AP\_OPTS\_CBT\_FLAG}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AP_OPTS_CBT_FLAG:AP_OPTS_CBT_FLAG}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AP\_OPTS\_CBT\_FLAG}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AP\_OPTS\_CBT\_FLAG}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000004 /* include KERB\_AP\_OPTIONS\_CBT */}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AP\_OPTS\_MUTUAL\_REQUIRED} \label{\detokenize{appdev/refs/macros/AP_OPTS_MUTUAL_REQUIRED:ap-opts-mutual-required}}\label{\detokenize{appdev/refs/macros/AP_OPTS_MUTUAL_REQUIRED:ap-opts-mutual-required-data}}\label{\detokenize{appdev/refs/macros/AP_OPTS_MUTUAL_REQUIRED::doc}}\index{AP\_OPTS\_MUTUAL\_REQUIRED (built\sphinxhyphen{}in variable)@\spxentry{AP\_OPTS\_MUTUAL\_REQUIRED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AP_OPTS_MUTUAL_REQUIRED:AP_OPTS_MUTUAL_REQUIRED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AP\_OPTS\_MUTUAL\_REQUIRED}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Perform a mutual authentication exchange. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AP\_OPTS\_MUTUAL\_REQUIRED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x20000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AP\_OPTS\_RESERVED} \label{\detokenize{appdev/refs/macros/AP_OPTS_RESERVED:ap-opts-reserved}}\label{\detokenize{appdev/refs/macros/AP_OPTS_RESERVED:ap-opts-reserved-data}}\label{\detokenize{appdev/refs/macros/AP_OPTS_RESERVED::doc}}\index{AP\_OPTS\_RESERVED (built\sphinxhyphen{}in variable)@\spxentry{AP\_OPTS\_RESERVED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AP_OPTS_RESERVED:AP_OPTS_RESERVED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AP\_OPTS\_RESERVED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AP\_OPTS\_RESERVED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x80000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AP\_OPTS\_USE\_SESSION\_KEY} \label{\detokenize{appdev/refs/macros/AP_OPTS_USE_SESSION_KEY:ap-opts-use-session-key}}\label{\detokenize{appdev/refs/macros/AP_OPTS_USE_SESSION_KEY:ap-opts-use-session-key-data}}\label{\detokenize{appdev/refs/macros/AP_OPTS_USE_SESSION_KEY::doc}}\index{AP\_OPTS\_USE\_SESSION\_KEY (built\sphinxhyphen{}in variable)@\spxentry{AP\_OPTS\_USE\_SESSION\_KEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AP_OPTS_USE_SESSION_KEY:AP_OPTS_USE_SESSION_KEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AP\_OPTS\_USE\_SESSION\_KEY}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Use session key. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AP\_OPTS\_USE\_SESSION\_KEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x40000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AP\_OPTS\_USE\_SUBKEY} \label{\detokenize{appdev/refs/macros/AP_OPTS_USE_SUBKEY:ap-opts-use-subkey}}\label{\detokenize{appdev/refs/macros/AP_OPTS_USE_SUBKEY:ap-opts-use-subkey-data}}\label{\detokenize{appdev/refs/macros/AP_OPTS_USE_SUBKEY::doc}}\index{AP\_OPTS\_USE\_SUBKEY (built\sphinxhyphen{}in variable)@\spxentry{AP\_OPTS\_USE\_SUBKEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AP_OPTS_USE_SUBKEY:AP_OPTS_USE_SUBKEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AP\_OPTS\_USE\_SUBKEY}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Generate a subsession key from the current session key obtained from the credentials. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AP\_OPTS\_USE\_SUBKEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{AP\_OPTS\_WIRE\_MASK} \label{\detokenize{appdev/refs/macros/AP_OPTS_WIRE_MASK:ap-opts-wire-mask}}\label{\detokenize{appdev/refs/macros/AP_OPTS_WIRE_MASK:ap-opts-wire-mask-data}}\label{\detokenize{appdev/refs/macros/AP_OPTS_WIRE_MASK::doc}}\index{AP\_OPTS\_WIRE\_MASK (built\sphinxhyphen{}in variable)@\spxentry{AP\_OPTS\_WIRE\_MASK}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/AP_OPTS_WIRE_MASK:AP_OPTS_WIRE_MASK}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{AP\_OPTS\_WIRE\_MASK}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{AP\_OPTS\_WIRE\_MASK}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0xfffffff0}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_CMAC\_CAMELLIA128} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA128:cksumtype-cmac-camellia128}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA128:cksumtype-cmac-camellia128-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA128::doc}}\index{CKSUMTYPE\_CMAC\_CAMELLIA128 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_CMAC\_CAMELLIA128}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA128:CKSUMTYPE_CMAC_CAMELLIA128}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_CMAC\_CAMELLIA128}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6803. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_CMAC\_CAMELLIA128}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0011}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_CMAC\_CAMELLIA256} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA256:cksumtype-cmac-camellia256}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA256:cksumtype-cmac-camellia256-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA256::doc}}\index{CKSUMTYPE\_CMAC\_CAMELLIA256 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_CMAC\_CAMELLIA256}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA256:CKSUMTYPE_CMAC_CAMELLIA256}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_CMAC\_CAMELLIA256}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6803. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_CMAC\_CAMELLIA256}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0012}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_CRC32} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_CRC32:cksumtype-crc32}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_CRC32:cksumtype-crc32-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_CRC32::doc}}\index{CKSUMTYPE\_CRC32 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_CRC32}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_CRC32:CKSUMTYPE_CRC32}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_CRC32}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_CRC32}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_DESCBC} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_DESCBC:cksumtype-descbc}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_DESCBC:cksumtype-descbc-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_DESCBC::doc}}\index{CKSUMTYPE\_DESCBC (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_DESCBC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_DESCBC:CKSUMTYPE_DESCBC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_DESCBC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_DESCBC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0004}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_HMAC\_MD5\_ARCFOUR} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_MD5_ARCFOUR:cksumtype-hmac-md5-arcfour}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_MD5_ARCFOUR:cksumtype-hmac-md5-arcfour-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_MD5_ARCFOUR::doc}}\index{CKSUMTYPE\_HMAC\_MD5\_ARCFOUR (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_HMAC\_MD5\_ARCFOUR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_MD5_ARCFOUR:CKSUMTYPE_HMAC_MD5_ARCFOUR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_HMAC\_MD5\_ARCFOUR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 4757. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_HMAC\_MD5\_ARCFOUR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{\sphinxhyphen{}138}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_HMAC\_SHA1\_96\_AES128} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES128:cksumtype-hmac-sha1-96-aes128}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES128:cksumtype-hmac-sha1-96-aes128-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES128::doc}}\index{CKSUMTYPE\_HMAC\_SHA1\_96\_AES128 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_HMAC\_SHA1\_96\_AES128}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES128:CKSUMTYPE_HMAC_SHA1_96_AES128}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA1\_96\_AES128}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 3962. \sphinxAtStartPar Used with ENCTYPE\_AES128\_CTS\_HMAC\_SHA1\_96 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA1\_96\_AES128}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x000f}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_HMAC\_SHA1\_96\_AES256} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES256:cksumtype-hmac-sha1-96-aes256}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES256:cksumtype-hmac-sha1-96-aes256-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES256::doc}}\index{CKSUMTYPE\_HMAC\_SHA1\_96\_AES256 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_HMAC\_SHA1\_96\_AES256}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES256:CKSUMTYPE_HMAC_SHA1_96_AES256}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA1\_96\_AES256}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 3962. \sphinxAtStartPar Used with ENCTYPE\_AES256\_CTS\_HMAC\_SHA1\_96 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA1\_96\_AES256}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0010}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_HMAC\_SHA256\_128\_AES128} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA256_128_AES128:cksumtype-hmac-sha256-128-aes128}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA256_128_AES128:cksumtype-hmac-sha256-128-aes128-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA256_128_AES128::doc}}\index{CKSUMTYPE\_HMAC\_SHA256\_128\_AES128 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_HMAC\_SHA256\_128\_AES128}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA256_128_AES128:CKSUMTYPE_HMAC_SHA256_128_AES128}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA256\_128\_AES128}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 8009. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA256\_128\_AES128}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0013}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_HMAC\_SHA384\_192\_AES256} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA384_192_AES256:cksumtype-hmac-sha384-192-aes256}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA384_192_AES256:cksumtype-hmac-sha384-192-aes256-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA384_192_AES256::doc}}\index{CKSUMTYPE\_HMAC\_SHA384\_192\_AES256 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_HMAC\_SHA384\_192\_AES256}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA384_192_AES256:CKSUMTYPE_HMAC_SHA384_192_AES256}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA384\_192\_AES256}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 8009. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA384\_192\_AES256}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0014}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_HMAC\_SHA1\_DES3} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_DES3:cksumtype-hmac-sha1-des3}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_DES3:cksumtype-hmac-sha1-des3-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_DES3::doc}}\index{CKSUMTYPE\_HMAC\_SHA1\_DES3 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_HMAC\_SHA1\_DES3}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_DES3:CKSUMTYPE_HMAC_SHA1_DES3}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA1\_DES3}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_HMAC\_SHA1\_DES3}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x000c}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_MD5\_HMAC\_ARCFOUR} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_MD5_HMAC_ARCFOUR:cksumtype-md5-hmac-arcfour}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_MD5_HMAC_ARCFOUR:cksumtype-md5-hmac-arcfour-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_MD5_HMAC_ARCFOUR::doc}}\index{CKSUMTYPE\_MD5\_HMAC\_ARCFOUR (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_MD5\_HMAC\_ARCFOUR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_MD5_HMAC_ARCFOUR:CKSUMTYPE_MD5_HMAC_ARCFOUR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_MD5\_HMAC\_ARCFOUR}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_MD5\_HMAC\_ARCFOUR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{\sphinxhyphen{}137 /* Microsoft netlogon */}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_NIST\_SHA} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_NIST_SHA:cksumtype-nist-sha}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_NIST_SHA:cksumtype-nist-sha-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_NIST_SHA::doc}}\index{CKSUMTYPE\_NIST\_SHA (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_NIST\_SHA}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_NIST_SHA:CKSUMTYPE_NIST_SHA}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_NIST\_SHA}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_NIST\_SHA}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0009}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_RSA\_MD4} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD4:cksumtype-rsa-md4}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD4:cksumtype-rsa-md4-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD4::doc}}\index{CKSUMTYPE\_RSA\_MD4 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_RSA\_MD4}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD4:CKSUMTYPE_RSA_MD4}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_RSA\_MD4}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_RSA\_MD4}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_RSA\_MD4\_DES} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD4_DES:cksumtype-rsa-md4-des}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD4_DES:cksumtype-rsa-md4-des-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD4_DES::doc}}\index{CKSUMTYPE\_RSA\_MD4\_DES (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_RSA\_MD4\_DES}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD4_DES:CKSUMTYPE_RSA_MD4_DES}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_RSA\_MD4\_DES}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_RSA\_MD4\_DES}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0003}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_RSA\_MD5} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD5:cksumtype-rsa-md5}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD5:cksumtype-rsa-md5-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD5::doc}}\index{CKSUMTYPE\_RSA\_MD5 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_RSA\_MD5}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD5:CKSUMTYPE_RSA_MD5}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_RSA\_MD5}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_RSA\_MD5}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0007}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_RSA\_MD5\_DES} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD5_DES:cksumtype-rsa-md5-des}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD5_DES:cksumtype-rsa-md5-des-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD5_DES::doc}}\index{CKSUMTYPE\_RSA\_MD5\_DES (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_RSA\_MD5\_DES}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_RSA_MD5_DES:CKSUMTYPE_RSA_MD5_DES}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_RSA\_MD5\_DES}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_RSA\_MD5\_DES}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0008}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{CKSUMTYPE\_SHA1} \label{\detokenize{appdev/refs/macros/CKSUMTYPE_SHA1:cksumtype-sha1}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_SHA1:cksumtype-sha1-data}}\label{\detokenize{appdev/refs/macros/CKSUMTYPE_SHA1::doc}}\index{CKSUMTYPE\_SHA1 (built\sphinxhyphen{}in variable)@\spxentry{CKSUMTYPE\_SHA1}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/CKSUMTYPE_SHA1:CKSUMTYPE_SHA1}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{CKSUMTYPE\_SHA1}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 3961. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{CKSUMTYPE\_SHA1}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x000e}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_AES128\_CTS\_HMAC\_SHA1\_96} \label{\detokenize{appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA1_96:enctype-aes128-cts-hmac-sha1-96}}\label{\detokenize{appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA1_96:enctype-aes128-cts-hmac-sha1-96-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA1_96::doc}}\index{ENCTYPE\_AES128\_CTS\_HMAC\_SHA1\_96 (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_AES128\_CTS\_HMAC\_SHA1\_96}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA1_96:ENCTYPE_AES128_CTS_HMAC_SHA1_96}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_AES128\_CTS\_HMAC\_SHA1\_96}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 3962. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_AES128\_CTS\_HMAC\_SHA1\_96}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0011}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_AES128\_CTS\_HMAC\_SHA256\_128} \label{\detokenize{appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA256_128:enctype-aes128-cts-hmac-sha256-128}}\label{\detokenize{appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA256_128:enctype-aes128-cts-hmac-sha256-128-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA256_128::doc}}\index{ENCTYPE\_AES128\_CTS\_HMAC\_SHA256\_128 (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_AES128\_CTS\_HMAC\_SHA256\_128}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA256_128:ENCTYPE_AES128_CTS_HMAC_SHA256_128}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_AES128\_CTS\_HMAC\_SHA256\_128}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 8009. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_AES128\_CTS\_HMAC\_SHA256\_128}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0013}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_AES256\_CTS\_HMAC\_SHA1\_96} \label{\detokenize{appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA1_96:enctype-aes256-cts-hmac-sha1-96}}\label{\detokenize{appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA1_96:enctype-aes256-cts-hmac-sha1-96-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA1_96::doc}}\index{ENCTYPE\_AES256\_CTS\_HMAC\_SHA1\_96 (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_AES256\_CTS\_HMAC\_SHA1\_96}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA1_96:ENCTYPE_AES256_CTS_HMAC_SHA1_96}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_AES256\_CTS\_HMAC\_SHA1\_96}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 3962. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_AES256\_CTS\_HMAC\_SHA1\_96}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0012}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_AES256\_CTS\_HMAC\_SHA384\_192} \label{\detokenize{appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA384_192:enctype-aes256-cts-hmac-sha384-192}}\label{\detokenize{appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA384_192:enctype-aes256-cts-hmac-sha384-192-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA384_192::doc}}\index{ENCTYPE\_AES256\_CTS\_HMAC\_SHA384\_192 (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_AES256\_CTS\_HMAC\_SHA384\_192}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA384_192:ENCTYPE_AES256_CTS_HMAC_SHA384_192}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_AES256\_CTS\_HMAC\_SHA384\_192}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 8009. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_AES256\_CTS\_HMAC\_SHA384\_192}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0014}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_ARCFOUR\_HMAC} \label{\detokenize{appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC:enctype-arcfour-hmac}}\label{\detokenize{appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC:enctype-arcfour-hmac-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC::doc}}\index{ENCTYPE\_ARCFOUR\_HMAC (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_ARCFOUR\_HMAC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC:ENCTYPE_ARCFOUR_HMAC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_ARCFOUR\_HMAC}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 4757. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_ARCFOUR\_HMAC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0017}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_ARCFOUR\_HMAC\_EXP} \label{\detokenize{appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC_EXP:enctype-arcfour-hmac-exp}}\label{\detokenize{appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC_EXP:enctype-arcfour-hmac-exp-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC_EXP::doc}}\index{ENCTYPE\_ARCFOUR\_HMAC\_EXP (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_ARCFOUR\_HMAC\_EXP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC_EXP:ENCTYPE_ARCFOUR_HMAC_EXP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_ARCFOUR\_HMAC\_EXP}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 4757. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_ARCFOUR\_HMAC\_EXP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0018}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_CAMELLIA128\_CTS\_CMAC} \label{\detokenize{appdev/refs/macros/ENCTYPE_CAMELLIA128_CTS_CMAC:enctype-camellia128-cts-cmac}}\label{\detokenize{appdev/refs/macros/ENCTYPE_CAMELLIA128_CTS_CMAC:enctype-camellia128-cts-cmac-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_CAMELLIA128_CTS_CMAC::doc}}\index{ENCTYPE\_CAMELLIA128\_CTS\_CMAC (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_CAMELLIA128\_CTS\_CMAC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_CAMELLIA128_CTS_CMAC:ENCTYPE_CAMELLIA128_CTS_CMAC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_CAMELLIA128\_CTS\_CMAC}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6803. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_CAMELLIA128\_CTS\_CMAC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0019}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_CAMELLIA256\_CTS\_CMAC} \label{\detokenize{appdev/refs/macros/ENCTYPE_CAMELLIA256_CTS_CMAC:enctype-camellia256-cts-cmac}}\label{\detokenize{appdev/refs/macros/ENCTYPE_CAMELLIA256_CTS_CMAC:enctype-camellia256-cts-cmac-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_CAMELLIA256_CTS_CMAC::doc}}\index{ENCTYPE\_CAMELLIA256\_CTS\_CMAC (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_CAMELLIA256\_CTS\_CMAC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_CAMELLIA256_CTS_CMAC:ENCTYPE_CAMELLIA256_CTS_CMAC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_CAMELLIA256\_CTS\_CMAC}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6803. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_CAMELLIA256\_CTS\_CMAC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x001a}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DES3\_CBC\_ENV} \label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_ENV:enctype-des3-cbc-env}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_ENV:enctype-des3-cbc-env-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_ENV::doc}}\index{ENCTYPE\_DES3\_CBC\_ENV (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DES3\_CBC\_ENV}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_ENV:ENCTYPE_DES3_CBC_ENV}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DES3\_CBC\_ENV}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar DES\sphinxhyphen{}3 cbc mode, CMS enveloped data. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DES3\_CBC\_ENV}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x000f}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DES3\_CBC\_RAW} \label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_RAW:enctype-des3-cbc-raw}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_RAW:enctype-des3-cbc-raw-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_RAW::doc}}\index{ENCTYPE\_DES3\_CBC\_RAW (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DES3\_CBC\_RAW}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_RAW:ENCTYPE_DES3_CBC_RAW}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DES3\_CBC\_RAW}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DES3\_CBC\_RAW}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0006}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DES3\_CBC\_SHA} \label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_SHA:enctype-des3-cbc-sha}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_SHA:enctype-des3-cbc-sha-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_SHA::doc}}\index{ENCTYPE\_DES3\_CBC\_SHA (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DES3\_CBC\_SHA}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_SHA:ENCTYPE_DES3_CBC_SHA}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DES3\_CBC\_SHA}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DES3\_CBC\_SHA}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0005}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DES3\_CBC\_SHA1} \label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_SHA1:enctype-des3-cbc-sha1}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_SHA1:enctype-des3-cbc-sha1-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_SHA1::doc}}\index{ENCTYPE\_DES3\_CBC\_SHA1 (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DES3\_CBC\_SHA1}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DES3_CBC_SHA1:ENCTYPE_DES3_CBC_SHA1}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DES3\_CBC\_SHA1}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DES3\_CBC\_SHA1}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0010}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DES\_CBC\_CRC} \label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_CRC:enctype-des-cbc-crc}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_CRC:enctype-des-cbc-crc-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_CRC::doc}}\index{ENCTYPE\_DES\_CBC\_CRC (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DES\_CBC\_CRC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_CRC:ENCTYPE_DES_CBC_CRC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DES\_CBC\_CRC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DES\_CBC\_CRC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DES\_CBC\_MD4} \label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_MD4:enctype-des-cbc-md4}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_MD4:enctype-des-cbc-md4-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_MD4::doc}}\index{ENCTYPE\_DES\_CBC\_MD4 (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DES\_CBC\_MD4}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_MD4:ENCTYPE_DES_CBC_MD4}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DES\_CBC\_MD4}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DES\_CBC\_MD4}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DES\_CBC\_MD5} \label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_MD5:enctype-des-cbc-md5}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_MD5:enctype-des-cbc-md5-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_MD5::doc}}\index{ENCTYPE\_DES\_CBC\_MD5 (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DES\_CBC\_MD5}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_MD5:ENCTYPE_DES_CBC_MD5}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DES\_CBC\_MD5}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DES\_CBC\_MD5}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0003}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DES\_CBC\_RAW} \label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_RAW:enctype-des-cbc-raw}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_RAW:enctype-des-cbc-raw-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_RAW::doc}}\index{ENCTYPE\_DES\_CBC\_RAW (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DES\_CBC\_RAW}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_CBC_RAW:ENCTYPE_DES_CBC_RAW}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DES\_CBC\_RAW}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DES\_CBC\_RAW}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0004}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DES\_HMAC\_SHA1} \label{\detokenize{appdev/refs/macros/ENCTYPE_DES_HMAC_SHA1:enctype-des-hmac-sha1}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_HMAC_SHA1:enctype-des-hmac-sha1-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_HMAC_SHA1::doc}}\index{ENCTYPE\_DES\_HMAC\_SHA1 (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DES\_HMAC\_SHA1}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DES_HMAC_SHA1:ENCTYPE_DES_HMAC_SHA1}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DES\_HMAC\_SHA1}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DES\_HMAC\_SHA1}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0008}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_DSA\_SHA1\_CMS} \label{\detokenize{appdev/refs/macros/ENCTYPE_DSA_SHA1_CMS:enctype-dsa-sha1-cms}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DSA_SHA1_CMS:enctype-dsa-sha1-cms-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_DSA_SHA1_CMS::doc}}\index{ENCTYPE\_DSA\_SHA1\_CMS (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_DSA\_SHA1\_CMS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_DSA_SHA1_CMS:ENCTYPE_DSA_SHA1_CMS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_DSA\_SHA1\_CMS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar DSA with SHA1, CMS signature. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_DSA\_SHA1\_CMS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0009}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_MD5\_RSA\_CMS} \label{\detokenize{appdev/refs/macros/ENCTYPE_MD5_RSA_CMS:enctype-md5-rsa-cms}}\label{\detokenize{appdev/refs/macros/ENCTYPE_MD5_RSA_CMS:enctype-md5-rsa-cms-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_MD5_RSA_CMS::doc}}\index{ENCTYPE\_MD5\_RSA\_CMS (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_MD5\_RSA\_CMS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_MD5_RSA_CMS:ENCTYPE_MD5_RSA_CMS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_MD5\_RSA\_CMS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar MD5 with RSA, CMS signature. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_MD5\_RSA\_CMS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x000a}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_NULL} \label{\detokenize{appdev/refs/macros/ENCTYPE_NULL:enctype-null}}\label{\detokenize{appdev/refs/macros/ENCTYPE_NULL:enctype-null-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_NULL::doc}}\index{ENCTYPE\_NULL (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_NULL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_NULL:ENCTYPE_NULL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_NULL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_NULL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_RC2\_CBC\_ENV} \label{\detokenize{appdev/refs/macros/ENCTYPE_RC2_CBC_ENV:enctype-rc2-cbc-env}}\label{\detokenize{appdev/refs/macros/ENCTYPE_RC2_CBC_ENV:enctype-rc2-cbc-env-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_RC2_CBC_ENV::doc}}\index{ENCTYPE\_RC2\_CBC\_ENV (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_RC2\_CBC\_ENV}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_RC2_CBC_ENV:ENCTYPE_RC2_CBC_ENV}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_RC2\_CBC\_ENV}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RC2 cbc mode, CMS enveloped data. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_RC2\_CBC\_ENV}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x000c}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_RSA\_ENV} \label{\detokenize{appdev/refs/macros/ENCTYPE_RSA_ENV:enctype-rsa-env}}\label{\detokenize{appdev/refs/macros/ENCTYPE_RSA_ENV:enctype-rsa-env-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_RSA_ENV::doc}}\index{ENCTYPE\_RSA\_ENV (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_RSA\_ENV}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_RSA_ENV:ENCTYPE_RSA_ENV}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_RSA\_ENV}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RSA encryption, CMS enveloped data. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_RSA\_ENV}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x000d}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_RSA\_ES\_OAEP\_ENV} \label{\detokenize{appdev/refs/macros/ENCTYPE_RSA_ES_OAEP_ENV:enctype-rsa-es-oaep-env}}\label{\detokenize{appdev/refs/macros/ENCTYPE_RSA_ES_OAEP_ENV:enctype-rsa-es-oaep-env-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_RSA_ES_OAEP_ENV::doc}}\index{ENCTYPE\_RSA\_ES\_OAEP\_ENV (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_RSA\_ES\_OAEP\_ENV}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_RSA_ES_OAEP_ENV:ENCTYPE_RSA_ES_OAEP_ENV}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_RSA\_ES\_OAEP\_ENV}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RSA w/OEAP encryption, CMS enveloped data. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_RSA\_ES\_OAEP\_ENV}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x000e}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_SHA1\_RSA\_CMS} \label{\detokenize{appdev/refs/macros/ENCTYPE_SHA1_RSA_CMS:enctype-sha1-rsa-cms}}\label{\detokenize{appdev/refs/macros/ENCTYPE_SHA1_RSA_CMS:enctype-sha1-rsa-cms-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_SHA1_RSA_CMS::doc}}\index{ENCTYPE\_SHA1\_RSA\_CMS (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_SHA1\_RSA\_CMS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_SHA1_RSA_CMS:ENCTYPE_SHA1_RSA_CMS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_SHA1\_RSA\_CMS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar SHA1 with RSA, CMS signature. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_SHA1\_RSA\_CMS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x000b}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{ENCTYPE\_UNKNOWN} \label{\detokenize{appdev/refs/macros/ENCTYPE_UNKNOWN:enctype-unknown}}\label{\detokenize{appdev/refs/macros/ENCTYPE_UNKNOWN:enctype-unknown-data}}\label{\detokenize{appdev/refs/macros/ENCTYPE_UNKNOWN::doc}}\index{ENCTYPE\_UNKNOWN (built\sphinxhyphen{}in variable)@\spxentry{ENCTYPE\_UNKNOWN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/ENCTYPE_UNKNOWN:ENCTYPE_UNKNOWN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{ENCTYPE\_UNKNOWN}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{ENCTYPE\_UNKNOWN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x01ff}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_ALLOW\_POSTDATE} \label{\detokenize{appdev/refs/macros/KDC_OPT_ALLOW_POSTDATE:kdc-opt-allow-postdate}}\label{\detokenize{appdev/refs/macros/KDC_OPT_ALLOW_POSTDATE:kdc-opt-allow-postdate-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_ALLOW_POSTDATE::doc}}\index{KDC\_OPT\_ALLOW\_POSTDATE (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_ALLOW\_POSTDATE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_ALLOW_POSTDATE:KDC_OPT_ALLOW_POSTDATE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_ALLOW\_POSTDATE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_ALLOW\_POSTDATE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x04000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_CANONICALIZE} \label{\detokenize{appdev/refs/macros/KDC_OPT_CANONICALIZE:kdc-opt-canonicalize}}\label{\detokenize{appdev/refs/macros/KDC_OPT_CANONICALIZE:kdc-opt-canonicalize-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_CANONICALIZE::doc}}\index{KDC\_OPT\_CANONICALIZE (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_CANONICALIZE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_CANONICALIZE:KDC_OPT_CANONICALIZE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_CANONICALIZE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_CANONICALIZE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00010000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_CNAME\_IN\_ADDL\_TKT} \label{\detokenize{appdev/refs/macros/KDC_OPT_CNAME_IN_ADDL_TKT:kdc-opt-cname-in-addl-tkt}}\label{\detokenize{appdev/refs/macros/KDC_OPT_CNAME_IN_ADDL_TKT:kdc-opt-cname-in-addl-tkt-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_CNAME_IN_ADDL_TKT::doc}}\index{KDC\_OPT\_CNAME\_IN\_ADDL\_TKT (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_CNAME\_IN\_ADDL\_TKT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_CNAME_IN_ADDL_TKT:KDC_OPT_CNAME_IN_ADDL_TKT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_CNAME\_IN\_ADDL\_TKT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_CNAME\_IN\_ADDL\_TKT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00020000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_DISABLE\_TRANSITED\_CHECK} \label{\detokenize{appdev/refs/macros/KDC_OPT_DISABLE_TRANSITED_CHECK:kdc-opt-disable-transited-check}}\label{\detokenize{appdev/refs/macros/KDC_OPT_DISABLE_TRANSITED_CHECK:kdc-opt-disable-transited-check-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_DISABLE_TRANSITED_CHECK::doc}}\index{KDC\_OPT\_DISABLE\_TRANSITED\_CHECK (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_DISABLE\_TRANSITED\_CHECK}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_DISABLE_TRANSITED_CHECK:KDC_OPT_DISABLE_TRANSITED_CHECK}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_DISABLE\_TRANSITED\_CHECK}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_DISABLE\_TRANSITED\_CHECK}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000020}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_ENC\_TKT\_IN\_SKEY} \label{\detokenize{appdev/refs/macros/KDC_OPT_ENC_TKT_IN_SKEY:kdc-opt-enc-tkt-in-skey}}\label{\detokenize{appdev/refs/macros/KDC_OPT_ENC_TKT_IN_SKEY:kdc-opt-enc-tkt-in-skey-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_ENC_TKT_IN_SKEY::doc}}\index{KDC\_OPT\_ENC\_TKT\_IN\_SKEY (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_ENC\_TKT\_IN\_SKEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_ENC_TKT_IN_SKEY:KDC_OPT_ENC_TKT_IN_SKEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_ENC\_TKT\_IN\_SKEY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_ENC\_TKT\_IN\_SKEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000008}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_FORWARDABLE} \label{\detokenize{appdev/refs/macros/KDC_OPT_FORWARDABLE:kdc-opt-forwardable}}\label{\detokenize{appdev/refs/macros/KDC_OPT_FORWARDABLE:kdc-opt-forwardable-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_FORWARDABLE::doc}}\index{KDC\_OPT\_FORWARDABLE (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_FORWARDABLE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_FORWARDABLE:KDC_OPT_FORWARDABLE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_FORWARDABLE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_FORWARDABLE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x40000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_FORWARDED} \label{\detokenize{appdev/refs/macros/KDC_OPT_FORWARDED:kdc-opt-forwarded}}\label{\detokenize{appdev/refs/macros/KDC_OPT_FORWARDED:kdc-opt-forwarded-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_FORWARDED::doc}}\index{KDC\_OPT\_FORWARDED (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_FORWARDED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_FORWARDED:KDC_OPT_FORWARDED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_FORWARDED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_FORWARDED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x20000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_POSTDATED} \label{\detokenize{appdev/refs/macros/KDC_OPT_POSTDATED:kdc-opt-postdated}}\label{\detokenize{appdev/refs/macros/KDC_OPT_POSTDATED:kdc-opt-postdated-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_POSTDATED::doc}}\index{KDC\_OPT\_POSTDATED (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_POSTDATED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_POSTDATED:KDC_OPT_POSTDATED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_POSTDATED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_POSTDATED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x02000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_PROXIABLE} \label{\detokenize{appdev/refs/macros/KDC_OPT_PROXIABLE:kdc-opt-proxiable}}\label{\detokenize{appdev/refs/macros/KDC_OPT_PROXIABLE:kdc-opt-proxiable-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_PROXIABLE::doc}}\index{KDC\_OPT\_PROXIABLE (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_PROXIABLE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_PROXIABLE:KDC_OPT_PROXIABLE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_PROXIABLE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_PROXIABLE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x10000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_PROXY} \label{\detokenize{appdev/refs/macros/KDC_OPT_PROXY:kdc-opt-proxy}}\label{\detokenize{appdev/refs/macros/KDC_OPT_PROXY:kdc-opt-proxy-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_PROXY::doc}}\index{KDC\_OPT\_PROXY (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_PROXY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_PROXY:KDC_OPT_PROXY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_PROXY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_PROXY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x08000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_RENEW} \label{\detokenize{appdev/refs/macros/KDC_OPT_RENEW:kdc-opt-renew}}\label{\detokenize{appdev/refs/macros/KDC_OPT_RENEW:kdc-opt-renew-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_RENEW::doc}}\index{KDC\_OPT\_RENEW (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_RENEW}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_RENEW:KDC_OPT_RENEW}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_RENEW}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_RENEW}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_RENEWABLE} \label{\detokenize{appdev/refs/macros/KDC_OPT_RENEWABLE:kdc-opt-renewable}}\label{\detokenize{appdev/refs/macros/KDC_OPT_RENEWABLE:kdc-opt-renewable-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_RENEWABLE::doc}}\index{KDC\_OPT\_RENEWABLE (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_RENEWABLE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_RENEWABLE:KDC_OPT_RENEWABLE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_RENEWABLE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_RENEWABLE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00800000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_RENEWABLE\_OK} \label{\detokenize{appdev/refs/macros/KDC_OPT_RENEWABLE_OK:kdc-opt-renewable-ok}}\label{\detokenize{appdev/refs/macros/KDC_OPT_RENEWABLE_OK:kdc-opt-renewable-ok-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_RENEWABLE_OK::doc}}\index{KDC\_OPT\_RENEWABLE\_OK (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_RENEWABLE\_OK}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_RENEWABLE_OK:KDC_OPT_RENEWABLE_OK}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_RENEWABLE\_OK}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_RENEWABLE\_OK}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000010}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_REQUEST\_ANONYMOUS} \label{\detokenize{appdev/refs/macros/KDC_OPT_REQUEST_ANONYMOUS:kdc-opt-request-anonymous}}\label{\detokenize{appdev/refs/macros/KDC_OPT_REQUEST_ANONYMOUS:kdc-opt-request-anonymous-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_REQUEST_ANONYMOUS::doc}}\index{KDC\_OPT\_REQUEST\_ANONYMOUS (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_REQUEST\_ANONYMOUS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_REQUEST_ANONYMOUS:KDC_OPT_REQUEST_ANONYMOUS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_REQUEST\_ANONYMOUS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_REQUEST\_ANONYMOUS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00008000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_OPT\_VALIDATE} \label{\detokenize{appdev/refs/macros/KDC_OPT_VALIDATE:kdc-opt-validate}}\label{\detokenize{appdev/refs/macros/KDC_OPT_VALIDATE:kdc-opt-validate-data}}\label{\detokenize{appdev/refs/macros/KDC_OPT_VALIDATE::doc}}\index{KDC\_OPT\_VALIDATE (built\sphinxhyphen{}in variable)@\spxentry{KDC\_OPT\_VALIDATE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_OPT_VALIDATE:KDC_OPT_VALIDATE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_OPT\_VALIDATE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_OPT\_VALIDATE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KDC\_TKT\_COMMON\_MASK} \label{\detokenize{appdev/refs/macros/KDC_TKT_COMMON_MASK:kdc-tkt-common-mask}}\label{\detokenize{appdev/refs/macros/KDC_TKT_COMMON_MASK:kdc-tkt-common-mask-data}}\label{\detokenize{appdev/refs/macros/KDC_TKT_COMMON_MASK::doc}}\index{KDC\_TKT\_COMMON\_MASK (built\sphinxhyphen{}in variable)@\spxentry{KDC\_TKT\_COMMON\_MASK}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KDC_TKT_COMMON_MASK:KDC_TKT_COMMON_MASK}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KDC\_TKT\_COMMON\_MASK}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KDC\_TKT\_COMMON\_MASK}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x54800000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_ALTAUTH\_ATT\_CHALLENGE\_RESPONSE} \label{\detokenize{appdev/refs/macros/KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE:krb5-altauth-att-challenge-response}}\label{\detokenize{appdev/refs/macros/KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE:krb5-altauth-att-challenge-response-data}}\label{\detokenize{appdev/refs/macros/KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE::doc}}\index{KRB5\_ALTAUTH\_ATT\_CHALLENGE\_RESPONSE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_ALTAUTH\_ATT\_CHALLENGE\_RESPONSE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE:KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_ALTAUTH\_ATT\_CHALLENGE\_RESPONSE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar alternate authentication types \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_ALTAUTH\_ATT\_CHALLENGE\_RESPONSE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{64}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_ANONYMOUS\_PRINCSTR} \label{\detokenize{appdev/refs/macros/KRB5_ANONYMOUS_PRINCSTR:krb5-anonymous-princstr}}\label{\detokenize{appdev/refs/macros/KRB5_ANONYMOUS_PRINCSTR:krb5-anonymous-princstr-data}}\label{\detokenize{appdev/refs/macros/KRB5_ANONYMOUS_PRINCSTR::doc}}\index{KRB5\_ANONYMOUS\_PRINCSTR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_ANONYMOUS\_PRINCSTR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_ANONYMOUS_PRINCSTR:KRB5_ANONYMOUS_PRINCSTR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_ANONYMOUS\_PRINCSTR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Anonymous principal name. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_ANONYMOUS\_PRINCSTR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{"ANONYMOUS"}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_ANONYMOUS\_REALMSTR} \label{\detokenize{appdev/refs/macros/KRB5_ANONYMOUS_REALMSTR:krb5-anonymous-realmstr}}\label{\detokenize{appdev/refs/macros/KRB5_ANONYMOUS_REALMSTR:krb5-anonymous-realmstr-data}}\label{\detokenize{appdev/refs/macros/KRB5_ANONYMOUS_REALMSTR::doc}}\index{KRB5\_ANONYMOUS\_REALMSTR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_ANONYMOUS\_REALMSTR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_ANONYMOUS_REALMSTR:KRB5_ANONYMOUS_REALMSTR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_ANONYMOUS\_REALMSTR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Anonymous realm. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_ANONYMOUS\_REALMSTR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{"WELLKNOWN:ANONYMOUS"}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AP\_REP} \label{\detokenize{appdev/refs/macros/KRB5_AP_REP:krb5-ap-rep}}\label{\detokenize{appdev/refs/macros/KRB5_AP_REP:krb5-ap-rep-data}}\label{\detokenize{appdev/refs/macros/KRB5_AP_REP::doc}}\index{KRB5\_AP\_REP (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AP\_REP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AP_REP:KRB5_AP_REP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AP\_REP}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Response to mutual AP request. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AP\_REP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)15)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AP\_REQ} \label{\detokenize{appdev/refs/macros/KRB5_AP_REQ:krb5-ap-req}}\label{\detokenize{appdev/refs/macros/KRB5_AP_REQ:krb5-ap-req-data}}\label{\detokenize{appdev/refs/macros/KRB5_AP_REQ::doc}}\index{KRB5\_AP\_REQ (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AP\_REQ}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AP_REQ:KRB5_AP_REQ}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AP\_REQ}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Auth req to application server. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AP\_REQ}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)14)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AS\_REP} \label{\detokenize{appdev/refs/macros/KRB5_AS_REP:krb5-as-rep}}\label{\detokenize{appdev/refs/macros/KRB5_AS_REP:krb5-as-rep-data}}\label{\detokenize{appdev/refs/macros/KRB5_AS_REP::doc}}\index{KRB5\_AS\_REP (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AS\_REP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AS_REP:KRB5_AS_REP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AS\_REP}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Response to AS request. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AS\_REP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)11)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AS\_REQ} \label{\detokenize{appdev/refs/macros/KRB5_AS_REQ:krb5-as-req}}\label{\detokenize{appdev/refs/macros/KRB5_AS_REQ:krb5-as-req-data}}\label{\detokenize{appdev/refs/macros/KRB5_AS_REQ::doc}}\index{KRB5\_AS\_REQ (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AS\_REQ}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AS_REQ:KRB5_AS_REQ}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AS\_REQ}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Initial authentication request. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AS\_REQ}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)10)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_AND\_OR} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AND_OR:krb5-authdata-and-or}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AND_OR:krb5-authdata-and-or-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AND_OR::doc}}\index{KRB5\_AUTHDATA\_AND\_OR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_AND\_OR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AND_OR:KRB5_AUTHDATA_AND_OR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_AND\_OR}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_AND\_OR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{5}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_AP\_OPTIONS} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AP_OPTIONS:krb5-authdata-ap-options}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AP_OPTIONS:krb5-authdata-ap-options-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AP_OPTIONS::doc}}\index{KRB5\_AUTHDATA\_AP\_OPTIONS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_AP\_OPTIONS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AP_OPTIONS:KRB5_AUTHDATA_AP_OPTIONS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_AP\_OPTIONS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_AP\_OPTIONS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{143}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_AUTH\_INDICATOR} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AUTH_INDICATOR:krb5-authdata-auth-indicator}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AUTH_INDICATOR:krb5-authdata-auth-indicator-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AUTH_INDICATOR::doc}}\index{KRB5\_AUTHDATA\_AUTH\_INDICATOR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_AUTH\_INDICATOR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_AUTH_INDICATOR:KRB5_AUTHDATA_AUTH_INDICATOR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_AUTH\_INDICATOR}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_AUTH\_INDICATOR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{97}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_CAMMAC} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_CAMMAC:krb5-authdata-cammac}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_CAMMAC:krb5-authdata-cammac-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_CAMMAC::doc}}\index{KRB5\_AUTHDATA\_CAMMAC (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_CAMMAC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_CAMMAC:KRB5_AUTHDATA_CAMMAC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_CAMMAC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_CAMMAC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{96}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_ETYPE\_NEGOTIATION} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_ETYPE_NEGOTIATION:krb5-authdata-etype-negotiation}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_ETYPE_NEGOTIATION:krb5-authdata-etype-negotiation-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_ETYPE_NEGOTIATION::doc}}\index{KRB5\_AUTHDATA\_ETYPE\_NEGOTIATION (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_ETYPE\_NEGOTIATION}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_ETYPE_NEGOTIATION:KRB5_AUTHDATA_ETYPE_NEGOTIATION}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_ETYPE\_NEGOTIATION}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 4537. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_ETYPE\_NEGOTIATION}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{129}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_FX\_ARMOR} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_FX_ARMOR:krb5-authdata-fx-armor}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_FX_ARMOR:krb5-authdata-fx-armor-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_FX_ARMOR::doc}}\index{KRB5\_AUTHDATA\_FX\_ARMOR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_FX\_ARMOR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_FX_ARMOR:KRB5_AUTHDATA_FX_ARMOR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_FX\_ARMOR}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_FX\_ARMOR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{71}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_IF\_RELEVANT} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_IF_RELEVANT:krb5-authdata-if-relevant}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_IF_RELEVANT:krb5-authdata-if-relevant-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_IF_RELEVANT::doc}}\index{KRB5\_AUTHDATA\_IF\_RELEVANT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_IF\_RELEVANT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_IF_RELEVANT:KRB5_AUTHDATA_IF_RELEVANT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_IF\_RELEVANT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_IF\_RELEVANT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_INITIAL\_VERIFIED\_CAS} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_INITIAL_VERIFIED_CAS:krb5-authdata-initial-verified-cas}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_INITIAL_VERIFIED_CAS:krb5-authdata-initial-verified-cas-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_INITIAL_VERIFIED_CAS::doc}}\index{KRB5\_AUTHDATA\_INITIAL\_VERIFIED\_CAS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_INITIAL\_VERIFIED\_CAS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_INITIAL_VERIFIED_CAS:KRB5_AUTHDATA_INITIAL_VERIFIED_CAS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_INITIAL\_VERIFIED\_CAS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_INITIAL\_VERIFIED\_CAS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{9}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_KDC\_ISSUED} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_KDC_ISSUED:krb5-authdata-kdc-issued}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_KDC_ISSUED:krb5-authdata-kdc-issued-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_KDC_ISSUED::doc}}\index{KRB5\_AUTHDATA\_KDC\_ISSUED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_KDC\_ISSUED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_KDC_ISSUED:KRB5_AUTHDATA_KDC_ISSUED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_KDC\_ISSUED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_KDC\_ISSUED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_MANDATORY\_FOR\_KDC} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_MANDATORY_FOR_KDC:krb5-authdata-mandatory-for-kdc}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_MANDATORY_FOR_KDC:krb5-authdata-mandatory-for-kdc-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_MANDATORY_FOR_KDC::doc}}\index{KRB5\_AUTHDATA\_MANDATORY\_FOR\_KDC (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_MANDATORY\_FOR\_KDC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_MANDATORY_FOR_KDC:KRB5_AUTHDATA_MANDATORY_FOR_KDC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_MANDATORY\_FOR\_KDC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_MANDATORY\_FOR\_KDC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{8}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_OSF\_DCE} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_OSF_DCE:krb5-authdata-osf-dce}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_OSF_DCE:krb5-authdata-osf-dce-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_OSF_DCE::doc}}\index{KRB5\_AUTHDATA\_OSF\_DCE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_OSF\_DCE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_OSF_DCE:KRB5_AUTHDATA_OSF_DCE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_OSF\_DCE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_OSF\_DCE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{64}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_SESAME} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_SESAME:krb5-authdata-sesame}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_SESAME:krb5-authdata-sesame-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_SESAME::doc}}\index{KRB5\_AUTHDATA\_SESAME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_SESAME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_SESAME:KRB5_AUTHDATA_SESAME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_SESAME}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_SESAME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{65}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_SIGNTICKET} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_SIGNTICKET:krb5-authdata-signticket}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_SIGNTICKET:krb5-authdata-signticket-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_SIGNTICKET::doc}}\index{KRB5\_AUTHDATA\_SIGNTICKET (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_SIGNTICKET}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_SIGNTICKET:KRB5_AUTHDATA_SIGNTICKET}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_SIGNTICKET}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_SIGNTICKET}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{512}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTHDATA\_WIN2K\_PAC} \label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_WIN2K_PAC:krb5-authdata-win2k-pac}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_WIN2K_PAC:krb5-authdata-win2k-pac-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_WIN2K_PAC::doc}}\index{KRB5\_AUTHDATA\_WIN2K\_PAC (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTHDATA\_WIN2K\_PAC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTHDATA_WIN2K_PAC:KRB5_AUTHDATA_WIN2K_PAC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTHDATA\_WIN2K\_PAC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTHDATA\_WIN2K\_PAC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{128}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_SEQUENCE:krb5-auth-context-do-sequence}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_SEQUENCE:krb5-auth-context-do-sequence-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_SEQUENCE::doc}}\index{KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_SEQUENCE:KRB5_AUTH_CONTEXT_DO_SEQUENCE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Prevent replays with sequence numbers. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_DO\_SEQUENCE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000004}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_DO\_TIME} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_TIME:krb5-auth-context-do-time}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_TIME:krb5-auth-context-do-time-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_TIME::doc}}\index{KRB5\_AUTH\_CONTEXT\_DO\_TIME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_DO\_TIME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_TIME:KRB5_AUTH_CONTEXT_DO_TIME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_DO\_TIME}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Prevent replays with timestamps and replay cache. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_DO\_TIME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_ADDR} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR:krb5-auth-context-generate-local-addr}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR:krb5-auth-context-generate-local-addr-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR::doc}}\index{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_ADDR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_ADDR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR:KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_ADDR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Generate the local network address. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_ADDR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_FULL\_ADDR} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR:krb5-auth-context-generate-local-full-addr}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR:krb5-auth-context-generate-local-full-addr-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR::doc}}\index{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_FULL\_ADDR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_FULL\_ADDR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR:KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_FULL\_ADDR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Generate the local network address and the local port. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_GENERATE\_LOCAL\_FULL\_ADDR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000004}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_ADDR} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR:krb5-auth-context-generate-remote-addr}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR:krb5-auth-context-generate-remote-addr-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR::doc}}\index{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_ADDR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_ADDR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR:KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_ADDR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Generate the remote network address. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_ADDR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_FULL\_ADDR} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR:krb5-auth-context-generate-remote-full-addr}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR:krb5-auth-context-generate-remote-full-addr-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR::doc}}\index{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_FULL\_ADDR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_FULL\_ADDR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR:KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_FULL\_ADDR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Generate the remote network address and the remote port. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_GENERATE\_REMOTE\_FULL\_ADDR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000008}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_PERMIT\_ALL} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_PERMIT_ALL:krb5-auth-context-permit-all}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_PERMIT_ALL:krb5-auth-context-permit-all-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_PERMIT_ALL::doc}}\index{KRB5\_AUTH\_CONTEXT\_PERMIT\_ALL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_PERMIT\_ALL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_PERMIT_ALL:KRB5_AUTH_CONTEXT_PERMIT_ALL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_PERMIT\_ALL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_PERMIT\_ALL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000010}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_SEQUENCE:krb5-auth-context-ret-sequence}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_SEQUENCE:krb5-auth-context-ret-sequence-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_SEQUENCE::doc}}\index{KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_SEQUENCE:KRB5_AUTH_CONTEXT_RET_SEQUENCE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Save sequence numbers for application. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_RET\_SEQUENCE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000008}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_RET\_TIME} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_TIME:krb5-auth-context-ret-time}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_TIME:krb5-auth-context-ret-time-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_TIME::doc}}\index{KRB5\_AUTH\_CONTEXT\_RET\_TIME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_RET\_TIME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_TIME:KRB5_AUTH_CONTEXT_RET_TIME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_RET\_TIME}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Save timestamps for application. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_RET\_TIME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_AUTH\_CONTEXT\_USE\_SUBKEY} \label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_USE_SUBKEY:krb5-auth-context-use-subkey}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_USE_SUBKEY:krb5-auth-context-use-subkey-data}}\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_USE_SUBKEY::doc}}\index{KRB5\_AUTH\_CONTEXT\_USE\_SUBKEY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_AUTH\_CONTEXT\_USE\_SUBKEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_AUTH_CONTEXT_USE_SUBKEY:KRB5_AUTH_CONTEXT_USE_SUBKEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_USE\_SUBKEY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_AUTH\_CONTEXT\_USE\_SUBKEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000020}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CRED} \label{\detokenize{appdev/refs/macros/KRB5_CRED:krb5-cred}}\label{\detokenize{appdev/refs/macros/KRB5_CRED:krb5-cred-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRED::doc}}\index{KRB5\_CRED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CRED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CRED:KRB5_CRED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CRED}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Cred forwarding message. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CRED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)22)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CRYPTO\_TYPE\_CHECKSUM} \label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_CHECKSUM:krb5-crypto-type-checksum}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_CHECKSUM:krb5-crypto-type-checksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_CHECKSUM::doc}}\index{KRB5\_CRYPTO\_TYPE\_CHECKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CRYPTO\_TYPE\_CHECKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_CHECKSUM:KRB5_CRYPTO_TYPE_CHECKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_CHECKSUM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar {[}out{]} checksum for MIC \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_CHECKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{6}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CRYPTO\_TYPE\_DATA} \label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_DATA:krb5-crypto-type-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_DATA:krb5-crypto-type-data-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_DATA::doc}}\index{KRB5\_CRYPTO\_TYPE\_DATA (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CRYPTO\_TYPE\_DATA}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_DATA:KRB5_CRYPTO_TYPE_DATA}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_DATA}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar {[}in, out{]} plaintext \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_DATA}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CRYPTO\_TYPE\_EMPTY} \label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_EMPTY:krb5-crypto-type-empty}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_EMPTY:krb5-crypto-type-empty-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_EMPTY::doc}}\index{KRB5\_CRYPTO\_TYPE\_EMPTY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CRYPTO\_TYPE\_EMPTY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_EMPTY:KRB5_CRYPTO_TYPE_EMPTY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_EMPTY}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar {[}in{]} ignored \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_EMPTY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CRYPTO\_TYPE\_HEADER} \label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_HEADER:krb5-crypto-type-header}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_HEADER:krb5-crypto-type-header-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_HEADER::doc}}\index{KRB5\_CRYPTO\_TYPE\_HEADER (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CRYPTO\_TYPE\_HEADER}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_HEADER:KRB5_CRYPTO_TYPE_HEADER}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_HEADER}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar {[}out{]} header \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_HEADER}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CRYPTO\_TYPE\_PADDING} \label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_PADDING:krb5-crypto-type-padding}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_PADDING:krb5-crypto-type-padding-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_PADDING::doc}}\index{KRB5\_CRYPTO\_TYPE\_PADDING (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CRYPTO\_TYPE\_PADDING}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_PADDING:KRB5_CRYPTO_TYPE_PADDING}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_PADDING}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar {[}out{]} padding \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_PADDING}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY} \label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_SIGN_ONLY:krb5-crypto-type-sign-only}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_SIGN_ONLY:krb5-crypto-type-sign-only-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_SIGN_ONLY::doc}}\index{KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_SIGN_ONLY:KRB5_CRYPTO_TYPE_SIGN_ONLY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar {[}in{]} associated data \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_SIGN\_ONLY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{3}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CRYPTO\_TYPE\_STREAM} \label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_STREAM:krb5-crypto-type-stream}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_STREAM:krb5-crypto-type-stream-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_STREAM::doc}}\index{KRB5\_CRYPTO\_TYPE\_STREAM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CRYPTO\_TYPE\_STREAM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_STREAM:KRB5_CRYPTO_TYPE_STREAM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_STREAM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar {[}in{]} entire message without decomposing the structure into header, data and trailer buffers \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_STREAM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{7}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CRYPTO\_TYPE\_TRAILER} \label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_TRAILER:krb5-crypto-type-trailer}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_TRAILER:krb5-crypto-type-trailer-data}}\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_TRAILER::doc}}\index{KRB5\_CRYPTO\_TYPE\_TRAILER (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CRYPTO\_TYPE\_TRAILER}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CRYPTO_TYPE_TRAILER:KRB5_CRYPTO_TYPE_TRAILER}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_TRAILER}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar {[}out{]} checksum for encrypt \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CRYPTO\_TYPE\_TRAILER}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{5}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_CYBERSAFE\_SECUREID} \label{\detokenize{appdev/refs/macros/KRB5_CYBERSAFE_SECUREID:krb5-cybersafe-secureid}}\label{\detokenize{appdev/refs/macros/KRB5_CYBERSAFE_SECUREID:krb5-cybersafe-secureid-data}}\label{\detokenize{appdev/refs/macros/KRB5_CYBERSAFE_SECUREID::doc}}\index{KRB5\_CYBERSAFE\_SECUREID (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_CYBERSAFE\_SECUREID}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_CYBERSAFE_SECUREID:KRB5_CYBERSAFE_SECUREID}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_CYBERSAFE\_SECUREID}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Cybersafe. \sphinxAtStartPar RFC 4120 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_CYBERSAFE\_SECUREID}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{9}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_DOMAIN\_X500\_COMPRESS} \label{\detokenize{appdev/refs/macros/KRB5_DOMAIN_X500_COMPRESS:krb5-domain-x500-compress}}\label{\detokenize{appdev/refs/macros/KRB5_DOMAIN_X500_COMPRESS:krb5-domain-x500-compress-data}}\label{\detokenize{appdev/refs/macros/KRB5_DOMAIN_X500_COMPRESS::doc}}\index{KRB5\_DOMAIN\_X500\_COMPRESS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_DOMAIN\_X500\_COMPRESS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_DOMAIN_X500_COMPRESS:KRB5_DOMAIN_X500_COMPRESS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_DOMAIN\_X500\_COMPRESS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Transited encoding types. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_DOMAIN\_X500\_COMPRESS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_ENCPADATA\_REQ\_ENC\_PA\_REP} \label{\detokenize{appdev/refs/macros/KRB5_ENCPADATA_REQ_ENC_PA_REP:krb5-encpadata-req-enc-pa-rep}}\label{\detokenize{appdev/refs/macros/KRB5_ENCPADATA_REQ_ENC_PA_REP:krb5-encpadata-req-enc-pa-rep-data}}\label{\detokenize{appdev/refs/macros/KRB5_ENCPADATA_REQ_ENC_PA_REP::doc}}\index{KRB5\_ENCPADATA\_REQ\_ENC\_PA\_REP (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_ENCPADATA\_REQ\_ENC\_PA\_REP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_ENCPADATA_REQ_ENC_PA_REP:KRB5_ENCPADATA_REQ_ENC_PA_REP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_ENCPADATA\_REQ\_ENC\_PA\_REP}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6806. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_ENCPADATA\_REQ\_ENC\_PA\_REP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{149}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_ERROR} \label{\detokenize{appdev/refs/macros/KRB5_ERROR:krb5-error}}\label{\detokenize{appdev/refs/macros/KRB5_ERROR:krb5-error-data}}\label{\detokenize{appdev/refs/macros/KRB5_ERROR::doc}}\index{KRB5\_ERROR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_ERROR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_ERROR:KRB5_ERROR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_ERROR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Error response. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_ERROR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)30)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_FAST\_REQUIRED} \label{\detokenize{appdev/refs/macros/KRB5_FAST_REQUIRED:krb5-fast-required}}\label{\detokenize{appdev/refs/macros/KRB5_FAST_REQUIRED:krb5-fast-required-data}}\label{\detokenize{appdev/refs/macros/KRB5_FAST_REQUIRED::doc}}\index{KRB5\_FAST\_REQUIRED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_FAST\_REQUIRED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_FAST_REQUIRED:KRB5_FAST_REQUIRED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_FAST\_REQUIRED}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Require KDC to support FAST. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_FAST\_REQUIRED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GC\_CACHED} \label{\detokenize{appdev/refs/macros/KRB5_GC_CACHED:krb5-gc-cached}}\label{\detokenize{appdev/refs/macros/KRB5_GC_CACHED:krb5-gc-cached-data}}\label{\detokenize{appdev/refs/macros/KRB5_GC_CACHED::doc}}\index{KRB5\_GC\_CACHED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GC\_CACHED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GC_CACHED:KRB5_GC_CACHED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GC\_CACHED}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Want cached ticket only. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GC\_CACHED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GC\_CANONICALIZE} \label{\detokenize{appdev/refs/macros/KRB5_GC_CANONICALIZE:krb5-gc-canonicalize}}\label{\detokenize{appdev/refs/macros/KRB5_GC_CANONICALIZE:krb5-gc-canonicalize-data}}\label{\detokenize{appdev/refs/macros/KRB5_GC_CANONICALIZE::doc}}\index{KRB5\_GC\_CANONICALIZE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GC\_CANONICALIZE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GC_CANONICALIZE:KRB5_GC_CANONICALIZE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GC\_CANONICALIZE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Set canonicalize KDC option. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GC\_CANONICALIZE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GC\_CONSTRAINED\_DELEGATION} \label{\detokenize{appdev/refs/macros/KRB5_GC_CONSTRAINED_DELEGATION:krb5-gc-constrained-delegation}}\label{\detokenize{appdev/refs/macros/KRB5_GC_CONSTRAINED_DELEGATION:krb5-gc-constrained-delegation-data}}\label{\detokenize{appdev/refs/macros/KRB5_GC_CONSTRAINED_DELEGATION::doc}}\index{KRB5\_GC\_CONSTRAINED\_DELEGATION (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GC\_CONSTRAINED\_DELEGATION}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GC_CONSTRAINED_DELEGATION:KRB5_GC_CONSTRAINED_DELEGATION}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GC\_CONSTRAINED\_DELEGATION}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Constrained delegation. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GC\_CONSTRAINED\_DELEGATION}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{64}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GC\_FORWARDABLE} \label{\detokenize{appdev/refs/macros/KRB5_GC_FORWARDABLE:krb5-gc-forwardable}}\label{\detokenize{appdev/refs/macros/KRB5_GC_FORWARDABLE:krb5-gc-forwardable-data}}\label{\detokenize{appdev/refs/macros/KRB5_GC_FORWARDABLE::doc}}\index{KRB5\_GC\_FORWARDABLE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GC\_FORWARDABLE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GC_FORWARDABLE:KRB5_GC_FORWARDABLE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GC\_FORWARDABLE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Acquire forwardable tickets. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GC\_FORWARDABLE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{16}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GC\_NO\_STORE} \label{\detokenize{appdev/refs/macros/KRB5_GC_NO_STORE:krb5-gc-no-store}}\label{\detokenize{appdev/refs/macros/KRB5_GC_NO_STORE:krb5-gc-no-store-data}}\label{\detokenize{appdev/refs/macros/KRB5_GC_NO_STORE::doc}}\index{KRB5\_GC\_NO\_STORE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GC\_NO\_STORE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GC_NO_STORE:KRB5_GC_NO_STORE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GC\_NO\_STORE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Do not store in credential cache. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GC\_NO\_STORE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{8}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GC\_NO\_TRANSIT\_CHECK} \label{\detokenize{appdev/refs/macros/KRB5_GC_NO_TRANSIT_CHECK:krb5-gc-no-transit-check}}\label{\detokenize{appdev/refs/macros/KRB5_GC_NO_TRANSIT_CHECK:krb5-gc-no-transit-check-data}}\label{\detokenize{appdev/refs/macros/KRB5_GC_NO_TRANSIT_CHECK::doc}}\index{KRB5\_GC\_NO\_TRANSIT\_CHECK (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GC\_NO\_TRANSIT\_CHECK}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GC_NO_TRANSIT_CHECK:KRB5_GC_NO_TRANSIT_CHECK}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GC\_NO\_TRANSIT\_CHECK}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Disable transited check. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GC\_NO\_TRANSIT\_CHECK}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{32}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GC\_USER\_USER} \label{\detokenize{appdev/refs/macros/KRB5_GC_USER_USER:krb5-gc-user-user}}\label{\detokenize{appdev/refs/macros/KRB5_GC_USER_USER:krb5-gc-user-user-data}}\label{\detokenize{appdev/refs/macros/KRB5_GC_USER_USER::doc}}\index{KRB5\_GC\_USER\_USER (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GC\_USER\_USER}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GC_USER_USER:KRB5_GC_USER_USER}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GC\_USER\_USER}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Want user\sphinxhyphen{}user ticket. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GC\_USER\_USER}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_ADDRESS\_LIST} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST:krb5-get-init-creds-opt-address-list}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST:krb5-get-init-creds-opt-address-list-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_ADDRESS\_LIST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_ADDRESS\_LIST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST:KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_ADDRESS\_LIST}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_ADDRESS\_LIST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0020}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_ANONYMOUS} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ANONYMOUS:krb5-get-init-creds-opt-anonymous}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ANONYMOUS:krb5-get-init-creds-opt-anonymous-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ANONYMOUS::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_ANONYMOUS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_ANONYMOUS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ANONYMOUS:KRB5_GET_INIT_CREDS_OPT_ANONYMOUS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_ANONYMOUS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_ANONYMOUS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0400}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_CANONICALIZE} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CANONICALIZE:krb5-get-init-creds-opt-canonicalize}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CANONICALIZE:krb5-get-init-creds-opt-canonicalize-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CANONICALIZE::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_CANONICALIZE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_CANONICALIZE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CANONICALIZE:KRB5_GET_INIT_CREDS_OPT_CANONICALIZE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_CANONICALIZE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_CANONICALIZE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0200}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_CHG\_PWD\_PRMPT} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT:krb5-get-init-creds-opt-chg-pwd-prmpt}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT:krb5-get-init-creds-opt-chg-pwd-prmpt-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_CHG\_PWD\_PRMPT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_CHG\_PWD\_PRMPT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT:KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_CHG\_PWD\_PRMPT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_CHG\_PWD\_PRMPT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0100}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_ETYPE\_LIST} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST:krb5-get-init-creds-opt-etype-list}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST:krb5-get-init-creds-opt-etype-list-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_ETYPE\_LIST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_ETYPE\_LIST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST:KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_ETYPE\_LIST}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_ETYPE\_LIST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0010}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_FORWARDABLE} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_FORWARDABLE:krb5-get-init-creds-opt-forwardable}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_FORWARDABLE:krb5-get-init-creds-opt-forwardable-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_FORWARDABLE::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_FORWARDABLE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_FORWARDABLE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_FORWARDABLE:KRB5_GET_INIT_CREDS_OPT_FORWARDABLE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_FORWARDABLE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_FORWARDABLE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0004}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_PREAUTH\_LIST} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST:krb5-get-init-creds-opt-preauth-list}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST:krb5-get-init-creds-opt-preauth-list-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_PREAUTH\_LIST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_PREAUTH\_LIST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST:KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_PREAUTH\_LIST}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_PREAUTH\_LIST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0040}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_PROXIABLE} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PROXIABLE:krb5-get-init-creds-opt-proxiable}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PROXIABLE:krb5-get-init-creds-opt-proxiable-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PROXIABLE::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_PROXIABLE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_PROXIABLE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PROXIABLE:KRB5_GET_INIT_CREDS_OPT_PROXIABLE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_PROXIABLE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_PROXIABLE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0008}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_RENEW\_LIFE} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE:krb5-get-init-creds-opt-renew-life}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE:krb5-get-init-creds-opt-renew-life-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_RENEW\_LIFE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_RENEW\_LIFE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE:KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_RENEW\_LIFE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_RENEW\_LIFE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_SALT} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_SALT:krb5-get-init-creds-opt-salt}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_SALT:krb5-get-init-creds-opt-salt-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_SALT::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_SALT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_SALT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_SALT:KRB5_GET_INIT_CREDS_OPT_SALT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_SALT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_SALT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0080}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_GET\_INIT\_CREDS\_OPT\_TKT\_LIFE} \label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_TKT_LIFE:krb5-get-init-creds-opt-tkt-life}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_TKT_LIFE:krb5-get-init-creds-opt-tkt-life-data}}\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_TKT_LIFE::doc}}\index{KRB5\_GET\_INIT\_CREDS\_OPT\_TKT\_LIFE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_GET\_INIT\_CREDS\_OPT\_TKT\_LIFE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_TKT_LIFE:KRB5_GET_INIT_CREDS_OPT_TKT_LIFE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_TKT\_LIFE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_GET\_INIT\_CREDS\_OPT\_TKT\_LIFE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_INIT\_CONTEXT\_SECURE} \label{\detokenize{appdev/refs/macros/KRB5_INIT_CONTEXT_SECURE:krb5-init-context-secure}}\label{\detokenize{appdev/refs/macros/KRB5_INIT_CONTEXT_SECURE:krb5-init-context-secure-data}}\label{\detokenize{appdev/refs/macros/KRB5_INIT_CONTEXT_SECURE::doc}}\index{KRB5\_INIT\_CONTEXT\_SECURE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_INIT\_CONTEXT\_SECURE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_INIT_CONTEXT_SECURE:KRB5_INIT_CONTEXT_SECURE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_INIT\_CONTEXT\_SECURE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Use secure context configuration. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_INIT\_CONTEXT\_SECURE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_INIT\_CONTEXT\_KDC} \label{\detokenize{appdev/refs/macros/KRB5_INIT_CONTEXT_KDC:krb5-init-context-kdc}}\label{\detokenize{appdev/refs/macros/KRB5_INIT_CONTEXT_KDC:krb5-init-context-kdc-data}}\label{\detokenize{appdev/refs/macros/KRB5_INIT_CONTEXT_KDC::doc}}\index{KRB5\_INIT\_CONTEXT\_KDC (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_INIT\_CONTEXT\_KDC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_INIT_CONTEXT_KDC:KRB5_INIT_CONTEXT_KDC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_INIT\_CONTEXT\_KDC}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Use KDC configuration if available. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_INIT\_CONTEXT\_KDC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_INIT\_CREDS\_STEP\_FLAG\_CONTINUE} \label{\detokenize{appdev/refs/macros/KRB5_INIT_CREDS_STEP_FLAG_CONTINUE:krb5-init-creds-step-flag-continue}}\label{\detokenize{appdev/refs/macros/KRB5_INIT_CREDS_STEP_FLAG_CONTINUE:krb5-init-creds-step-flag-continue-data}}\label{\detokenize{appdev/refs/macros/KRB5_INIT_CREDS_STEP_FLAG_CONTINUE::doc}}\index{KRB5\_INIT\_CREDS\_STEP\_FLAG\_CONTINUE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_INIT\_CREDS\_STEP\_FLAG\_CONTINUE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_INIT_CREDS_STEP_FLAG_CONTINUE:KRB5_INIT_CREDS_STEP_FLAG_CONTINUE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_INIT\_CREDS\_STEP\_FLAG\_CONTINUE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar More responses needed. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_INIT\_CREDS\_STEP\_FLAG\_CONTINUE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_INT16\_MAX} \label{\detokenize{appdev/refs/macros/KRB5_INT16_MAX:krb5-int16-max}}\label{\detokenize{appdev/refs/macros/KRB5_INT16_MAX:krb5-int16-max-data}}\label{\detokenize{appdev/refs/macros/KRB5_INT16_MAX::doc}}\index{KRB5\_INT16\_MAX (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_INT16\_MAX}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_INT16_MAX:KRB5_INT16_MAX}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_INT16\_MAX}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_INT16\_MAX}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{65535}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_INT16\_MIN} \label{\detokenize{appdev/refs/macros/KRB5_INT16_MIN:krb5-int16-min}}\label{\detokenize{appdev/refs/macros/KRB5_INT16_MIN:krb5-int16-min-data}}\label{\detokenize{appdev/refs/macros/KRB5_INT16_MIN::doc}}\index{KRB5\_INT16\_MIN (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_INT16\_MIN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_INT16_MIN:KRB5_INT16_MIN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_INT16\_MIN}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_INT16\_MIN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\sphinxhyphen{}KRB5\_INT16\_MAX\sphinxhyphen{}1)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_INT32\_MAX} \label{\detokenize{appdev/refs/macros/KRB5_INT32_MAX:krb5-int32-max}}\label{\detokenize{appdev/refs/macros/KRB5_INT32_MAX:krb5-int32-max-data}}\label{\detokenize{appdev/refs/macros/KRB5_INT32_MAX::doc}}\index{KRB5\_INT32\_MAX (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_INT32\_MAX}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_INT32_MAX:KRB5_INT32_MAX}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_INT32\_MAX}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_INT32\_MAX}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2147483647}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_INT32\_MIN} \label{\detokenize{appdev/refs/macros/KRB5_INT32_MIN:krb5-int32-min}}\label{\detokenize{appdev/refs/macros/KRB5_INT32_MIN:krb5-int32-min-data}}\label{\detokenize{appdev/refs/macros/KRB5_INT32_MIN::doc}}\index{KRB5\_INT32\_MIN (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_INT32\_MIN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_INT32_MIN:KRB5_INT32_MIN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_INT32\_MIN}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_INT32\_MIN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\sphinxhyphen{}KRB5\_INT32\_MAX\sphinxhyphen{}1)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AD\_ITE} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_ITE:krb5-keyusage-ad-ite}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_ITE:krb5-keyusage-ad-ite-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_ITE::doc}}\index{KRB5\_KEYUSAGE\_AD\_ITE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AD\_ITE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_ITE:KRB5_KEYUSAGE_AD_ITE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AD\_ITE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AD\_ITE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{21}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AD\_KDCISSUED\_CKSUM} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM:krb5-keyusage-ad-kdcissued-cksum}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM:krb5-keyusage-ad-kdcissued-cksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM::doc}}\index{KRB5\_KEYUSAGE\_AD\_KDCISSUED\_CKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AD\_KDCISSUED\_CKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM:KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AD\_KDCISSUED\_CKSUM}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AD\_KDCISSUED\_CKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{19}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AD\_MTE} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_MTE:krb5-keyusage-ad-mte}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_MTE:krb5-keyusage-ad-mte-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_MTE::doc}}\index{KRB5\_KEYUSAGE\_AD\_MTE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AD\_MTE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_MTE:KRB5_KEYUSAGE_AD_MTE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AD\_MTE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AD\_MTE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{20}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AD\_SIGNEDPATH} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_SIGNEDPATH:krb5-keyusage-ad-signedpath}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_SIGNEDPATH:krb5-keyusage-ad-signedpath-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_SIGNEDPATH::doc}}\index{KRB5\_KEYUSAGE\_AD\_SIGNEDPATH (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AD\_SIGNEDPATH}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AD_SIGNEDPATH:KRB5_KEYUSAGE_AD_SIGNEDPATH}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AD\_SIGNEDPATH}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AD\_SIGNEDPATH}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{\sphinxhyphen{}21}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_APP\_DATA\_CKSUM} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_CKSUM:krb5-keyusage-app-data-cksum}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_CKSUM:krb5-keyusage-app-data-cksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_CKSUM::doc}}\index{KRB5\_KEYUSAGE\_APP\_DATA\_CKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_APP\_DATA\_CKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_CKSUM:KRB5_KEYUSAGE_APP_DATA_CKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_APP\_DATA\_CKSUM}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_APP\_DATA\_CKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{17}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_APP\_DATA\_ENCRYPT} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_ENCRYPT:krb5-keyusage-app-data-encrypt}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_ENCRYPT:krb5-keyusage-app-data-encrypt-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_ENCRYPT::doc}}\index{KRB5\_KEYUSAGE\_APP\_DATA\_ENCRYPT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_APP\_DATA\_ENCRYPT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_ENCRYPT:KRB5_KEYUSAGE_APP_DATA_ENCRYPT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_APP\_DATA\_ENCRYPT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_APP\_DATA\_ENCRYPT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{16}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AP\_REP\_ENCPART} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REP_ENCPART:krb5-keyusage-ap-rep-encpart}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REP_ENCPART:krb5-keyusage-ap-rep-encpart-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REP_ENCPART::doc}}\index{KRB5\_KEYUSAGE\_AP\_REP\_ENCPART (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AP\_REP\_ENCPART}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REP_ENCPART:KRB5_KEYUSAGE_AP_REP_ENCPART}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AP\_REP\_ENCPART}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AP\_REP\_ENCPART}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{12}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH:krb5-keyusage-ap-req-auth}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH:krb5-keyusage-ap-req-auth-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH::doc}}\index{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH:KRB5_KEYUSAGE_AP_REQ_AUTH}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{11}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH\_CKSUM} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM:krb5-keyusage-ap-req-auth-cksum}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM:krb5-keyusage-ap-req-auth-cksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM::doc}}\index{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH\_CKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH\_CKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM:KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH\_CKSUM}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AP\_REQ\_AUTH\_CKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{10}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AS\_REP\_ENCPART} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REP_ENCPART:krb5-keyusage-as-rep-encpart}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REP_ENCPART:krb5-keyusage-as-rep-encpart-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REP_ENCPART::doc}}\index{KRB5\_KEYUSAGE\_AS\_REP\_ENCPART (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AS\_REP\_ENCPART}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REP_ENCPART:KRB5_KEYUSAGE_AS_REP_ENCPART}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AS\_REP\_ENCPART}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AS\_REP\_ENCPART}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{3}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AS\_REQ} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ:krb5-keyusage-as-req}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ:krb5-keyusage-as-req-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ::doc}}\index{KRB5\_KEYUSAGE\_AS\_REQ (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AS\_REQ}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ:KRB5_KEYUSAGE_AS_REQ}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AS\_REQ}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AS\_REQ}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{56}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_AS\_REQ\_PA\_ENC\_TS} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS:krb5-keyusage-as-req-pa-enc-ts}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS:krb5-keyusage-as-req-pa-enc-ts-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS::doc}}\index{KRB5\_KEYUSAGE\_AS\_REQ\_PA\_ENC\_TS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_AS\_REQ\_PA\_ENC\_TS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS:KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_AS\_REQ\_PA\_ENC\_TS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_AS\_REQ\_PA\_ENC\_TS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_CAMMAC} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_CAMMAC:krb5-keyusage-cammac}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_CAMMAC:krb5-keyusage-cammac-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_CAMMAC::doc}}\index{KRB5\_KEYUSAGE\_CAMMAC (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_CAMMAC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_CAMMAC:KRB5_KEYUSAGE_CAMMAC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_CAMMAC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_CAMMAC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{64}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_CLIENT} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT:krb5-keyusage-enc-challenge-client}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT:krb5-keyusage-enc-challenge-client-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT::doc}}\index{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_CLIENT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_CLIENT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT:KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_CLIENT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_CLIENT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{54}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_KDC} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_KDC:krb5-keyusage-enc-challenge-kdc}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_KDC:krb5-keyusage-enc-challenge-kdc-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_KDC::doc}}\index{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_KDC (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_KDC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_KDC:KRB5_KEYUSAGE_ENC_CHALLENGE_KDC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_KDC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_ENC\_CHALLENGE\_KDC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{55}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_FAST\_ENC} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_ENC:krb5-keyusage-fast-enc}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_ENC:krb5-keyusage-fast-enc-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_ENC::doc}}\index{KRB5\_KEYUSAGE\_FAST\_ENC (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_FAST\_ENC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_ENC:KRB5_KEYUSAGE_FAST_ENC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_FAST\_ENC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_FAST\_ENC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{51}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_FAST\_FINISHED} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_FINISHED:krb5-keyusage-fast-finished}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_FINISHED:krb5-keyusage-fast-finished-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_FINISHED::doc}}\index{KRB5\_KEYUSAGE\_FAST\_FINISHED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_FAST\_FINISHED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_FINISHED:KRB5_KEYUSAGE_FAST_FINISHED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_FAST\_FINISHED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_FAST\_FINISHED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{53}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_FAST\_REP} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_REP:krb5-keyusage-fast-rep}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_REP:krb5-keyusage-fast-rep-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_REP::doc}}\index{KRB5\_KEYUSAGE\_FAST\_REP (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_FAST\_REP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_REP:KRB5_KEYUSAGE_FAST_REP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_FAST\_REP}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_FAST\_REP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{52}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_FAST\_REQ\_CHKSUM} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_REQ_CHKSUM:krb5-keyusage-fast-req-chksum}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_REQ_CHKSUM:krb5-keyusage-fast-req-chksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_REQ_CHKSUM::doc}}\index{KRB5\_KEYUSAGE\_FAST\_REQ\_CHKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_FAST\_REQ\_CHKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FAST_REQ_CHKSUM:KRB5_KEYUSAGE_FAST_REQ_CHKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_FAST\_REQ\_CHKSUM}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_FAST\_REQ\_CHKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{50}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_GSS\_TOK\_MIC} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_MIC:krb5-keyusage-gss-tok-mic}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_MIC:krb5-keyusage-gss-tok-mic-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_MIC::doc}}\index{KRB5\_KEYUSAGE\_GSS\_TOK\_MIC (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_GSS\_TOK\_MIC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_MIC:KRB5_KEYUSAGE_GSS_TOK_MIC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_GSS\_TOK\_MIC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_GSS\_TOK\_MIC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{22}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_INTEG} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG:krb5-keyusage-gss-tok-wrap-integ}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG:krb5-keyusage-gss-tok-wrap-integ-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG::doc}}\index{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_INTEG (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_INTEG}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG:KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_INTEG}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_INTEG}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{23}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_PRIV} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV:krb5-keyusage-gss-tok-wrap-priv}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV:krb5-keyusage-gss-tok-wrap-priv-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV::doc}}\index{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_PRIV (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_PRIV}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV:KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_PRIV}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_GSS\_TOK\_WRAP\_PRIV}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{24}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_FINISHED} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FINISHED:krb5-keyusage-finished}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FINISHED:krb5-keyusage-finished-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FINISHED::doc}}\index{KRB5\_KEYUSAGE\_FINISHED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_FINISHED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_FINISHED:KRB5_KEYUSAGE_FINISHED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_FINISHED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_FINISHED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{41}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_IAKERB\_FINISHED} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_IAKERB_FINISHED:krb5-keyusage-iakerb-finished}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_IAKERB_FINISHED:krb5-keyusage-iakerb-finished-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_IAKERB_FINISHED::doc}}\index{KRB5\_KEYUSAGE\_IAKERB\_FINISHED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_IAKERB\_FINISHED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_IAKERB_FINISHED:KRB5_KEYUSAGE_IAKERB_FINISHED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_IAKERB\_FINISHED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_IAKERB\_FINISHED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{42}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_KDC\_REP\_TICKET} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KDC_REP_TICKET:krb5-keyusage-kdc-rep-ticket}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KDC_REP_TICKET:krb5-keyusage-kdc-rep-ticket-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KDC_REP_TICKET::doc}}\index{KRB5\_KEYUSAGE\_KDC\_REP\_TICKET (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_KDC\_REP\_TICKET}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KDC_REP_TICKET:KRB5_KEYUSAGE_KDC_REP_TICKET}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_KDC\_REP\_TICKET}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_KDC\_REP\_TICKET}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_KRB\_CRED\_ENCPART} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_CRED_ENCPART:krb5-keyusage-krb-cred-encpart}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_CRED_ENCPART:krb5-keyusage-krb-cred-encpart-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_CRED_ENCPART::doc}}\index{KRB5\_KEYUSAGE\_KRB\_CRED\_ENCPART (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_KRB\_CRED\_ENCPART}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_CRED_ENCPART:KRB5_KEYUSAGE_KRB_CRED_ENCPART}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_KRB\_CRED\_ENCPART}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_KRB\_CRED\_ENCPART}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{14}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_KRB\_ERROR\_CKSUM} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_ERROR_CKSUM:krb5-keyusage-krb-error-cksum}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_ERROR_CKSUM:krb5-keyusage-krb-error-cksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_ERROR_CKSUM::doc}}\index{KRB5\_KEYUSAGE\_KRB\_ERROR\_CKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_KRB\_ERROR\_CKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_ERROR_CKSUM:KRB5_KEYUSAGE_KRB_ERROR_CKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_KRB\_ERROR\_CKSUM}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_KRB\_ERROR\_CKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{18}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_KRB\_PRIV\_ENCPART} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_PRIV_ENCPART:krb5-keyusage-krb-priv-encpart}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_PRIV_ENCPART:krb5-keyusage-krb-priv-encpart-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_PRIV_ENCPART::doc}}\index{KRB5\_KEYUSAGE\_KRB\_PRIV\_ENCPART (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_KRB\_PRIV\_ENCPART}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_PRIV_ENCPART:KRB5_KEYUSAGE_KRB_PRIV_ENCPART}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_KRB\_PRIV\_ENCPART}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_KRB\_PRIV\_ENCPART}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{13}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_KRB\_SAFE\_CKSUM} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_SAFE_CKSUM:krb5-keyusage-krb-safe-cksum}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_SAFE_CKSUM:krb5-keyusage-krb-safe-cksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_SAFE_CKSUM::doc}}\index{KRB5\_KEYUSAGE\_KRB\_SAFE\_CKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_KRB\_SAFE\_CKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_KRB_SAFE_CKSUM:KRB5_KEYUSAGE_KRB_SAFE_CKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_KRB\_SAFE\_CKSUM}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_KRB\_SAFE\_CKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{15}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_PA\_AS\_FRESHNESS} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_AS_FRESHNESS:krb5-keyusage-pa-as-freshness}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_AS_FRESHNESS:krb5-keyusage-pa-as-freshness-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_AS_FRESHNESS::doc}}\index{KRB5\_KEYUSAGE\_PA\_AS\_FRESHNESS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_PA\_AS\_FRESHNESS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_AS_FRESHNESS:KRB5_KEYUSAGE_PA_AS_FRESHNESS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_AS\_FRESHNESS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Used for freshness tokens. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_AS\_FRESHNESS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{514}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_PA\_FX\_COOKIE} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_FX_COOKIE:krb5-keyusage-pa-fx-cookie}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_FX_COOKIE:krb5-keyusage-pa-fx-cookie-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_FX_COOKIE::doc}}\index{KRB5\_KEYUSAGE\_PA\_FX\_COOKIE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_PA\_FX\_COOKIE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_FX_COOKIE:KRB5_KEYUSAGE_PA_FX_COOKIE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_FX\_COOKIE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Used for encrypted FAST cookies. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_FX\_COOKIE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{513}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_PA\_OTP\_REQUEST} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_OTP_REQUEST:krb5-keyusage-pa-otp-request}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_OTP_REQUEST:krb5-keyusage-pa-otp-request-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_OTP_REQUEST::doc}}\index{KRB5\_KEYUSAGE\_PA\_OTP\_REQUEST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_PA\_OTP\_REQUEST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_OTP_REQUEST:KRB5_KEYUSAGE_PA_OTP_REQUEST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_OTP\_REQUEST}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar See RFC 6560 section 4.2. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_OTP\_REQUEST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{45}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_PA\_PKINIT\_KX} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_PKINIT_KX:krb5-keyusage-pa-pkinit-kx}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_PKINIT_KX:krb5-keyusage-pa-pkinit-kx-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_PKINIT_KX::doc}}\index{KRB5\_KEYUSAGE\_PA\_PKINIT\_KX (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_PA\_PKINIT\_KX}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_PKINIT_KX:KRB5_KEYUSAGE_PA_PKINIT_KX}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_PKINIT\_KX}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_PKINIT\_KX}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{44}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REPLY} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY:krb5-keyusage-pa-s4u-x509-user-reply}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY:krb5-keyusage-pa-s4u-x509-user-reply-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY::doc}}\index{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REPLY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REPLY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY:KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REPLY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REPLY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{27}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REQUEST} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST:krb5-keyusage-pa-s4u-x509-user-request}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST:krb5-keyusage-pa-s4u-x509-user-request-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST::doc}}\index{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REQUEST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REQUEST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST:KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REQUEST}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_S4U\_X509\_USER\_REQUEST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{26}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_CKSUM} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM:krb5-keyusage-pa-sam-challenge-cksum}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM:krb5-keyusage-pa-sam-challenge-cksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM::doc}}\index{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_CKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_CKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM:KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_CKSUM}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_CKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{25}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_TRACKID} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID:krb5-keyusage-pa-sam-challenge-trackid}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID:krb5-keyusage-pa-sam-challenge-trackid-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID::doc}}\index{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_TRACKID (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_TRACKID}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID:KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_TRACKID}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_SAM\_CHALLENGE\_TRACKID}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{26}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_PA\_SAM\_RESPONSE} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_RESPONSE:krb5-keyusage-pa-sam-response}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_RESPONSE:krb5-keyusage-pa-sam-response-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_RESPONSE::doc}}\index{KRB5\_KEYUSAGE\_PA\_SAM\_RESPONSE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_PA\_SAM\_RESPONSE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_RESPONSE:KRB5_KEYUSAGE_PA_SAM_RESPONSE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_SAM\_RESPONSE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_PA\_SAM\_RESPONSE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{27}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_SPAKE} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_SPAKE:krb5-keyusage-spake}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_SPAKE:krb5-keyusage-spake-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_SPAKE::doc}}\index{KRB5\_KEYUSAGE\_SPAKE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_SPAKE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_SPAKE:KRB5_KEYUSAGE_SPAKE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_SPAKE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_SPAKE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{65}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SESSKEY} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY:krb5-keyusage-tgs-rep-encpart-sesskey}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY:krb5-keyusage-tgs-rep-encpart-sesskey-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY::doc}}\index{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SESSKEY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SESSKEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY:KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SESSKEY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SESSKEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{8}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SUBKEY} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY:krb5-keyusage-tgs-rep-encpart-subkey}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY:krb5-keyusage-tgs-rep-encpart-subkey-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY::doc}}\index{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SUBKEY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SUBKEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY:KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SUBKEY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REP\_ENCPART\_SUBKEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{9}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SESSKEY} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY:krb5-keyusage-tgs-req-ad-sesskey}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY:krb5-keyusage-tgs-req-ad-sesskey-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY::doc}}\index{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SESSKEY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SESSKEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY:KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SESSKEY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SESSKEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SUBKEY} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY:krb5-keyusage-tgs-req-ad-subkey}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY:krb5-keyusage-tgs-req-ad-subkey-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY::doc}}\index{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SUBKEY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SUBKEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY:KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SUBKEY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REQ\_AD\_SUBKEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{5}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH:krb5-keyusage-tgs-req-auth}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH:krb5-keyusage-tgs-req-auth-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH::doc}}\index{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH:KRB5_KEYUSAGE_TGS_REQ_AUTH}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{7}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH\_CKSUM} \label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM:krb5-keyusage-tgs-req-auth-cksum}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM:krb5-keyusage-tgs-req-auth-cksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM::doc}}\index{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH\_CKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH\_CKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM:KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH\_CKSUM}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KEYUSAGE\_TGS\_REQ\_AUTH\_CKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{6}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KPASSWD\_ACCESSDENIED} \label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_ACCESSDENIED:krb5-kpasswd-accessdenied}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_ACCESSDENIED:krb5-kpasswd-accessdenied-data}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_ACCESSDENIED::doc}}\index{KRB5\_KPASSWD\_ACCESSDENIED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KPASSWD\_ACCESSDENIED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_ACCESSDENIED:KRB5_KPASSWD_ACCESSDENIED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KPASSWD\_ACCESSDENIED}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Not authorized. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KPASSWD\_ACCESSDENIED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{5}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KPASSWD\_AUTHERROR} \label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_AUTHERROR:krb5-kpasswd-autherror}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_AUTHERROR:krb5-kpasswd-autherror-data}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_AUTHERROR::doc}}\index{KRB5\_KPASSWD\_AUTHERROR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KPASSWD\_AUTHERROR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_AUTHERROR:KRB5_KPASSWD_AUTHERROR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KPASSWD\_AUTHERROR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Authentication error. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KPASSWD\_AUTHERROR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{3}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KPASSWD\_BAD\_VERSION} \label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_BAD_VERSION:krb5-kpasswd-bad-version}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_BAD_VERSION:krb5-kpasswd-bad-version-data}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_BAD_VERSION::doc}}\index{KRB5\_KPASSWD\_BAD\_VERSION (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KPASSWD\_BAD\_VERSION}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_BAD_VERSION:KRB5_KPASSWD_BAD_VERSION}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KPASSWD\_BAD\_VERSION}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Unknown RPC version. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KPASSWD\_BAD\_VERSION}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{6}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KPASSWD\_HARDERROR} \label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_HARDERROR:krb5-kpasswd-harderror}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_HARDERROR:krb5-kpasswd-harderror-data}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_HARDERROR::doc}}\index{KRB5\_KPASSWD\_HARDERROR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KPASSWD\_HARDERROR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_HARDERROR:KRB5_KPASSWD_HARDERROR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KPASSWD\_HARDERROR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Server error. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KPASSWD\_HARDERROR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KPASSWD\_INITIAL\_FLAG\_NEEDED} \label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_INITIAL_FLAG_NEEDED:krb5-kpasswd-initial-flag-needed}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_INITIAL_FLAG_NEEDED:krb5-kpasswd-initial-flag-needed-data}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_INITIAL_FLAG_NEEDED::doc}}\index{KRB5\_KPASSWD\_INITIAL\_FLAG\_NEEDED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KPASSWD\_INITIAL\_FLAG\_NEEDED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_INITIAL_FLAG_NEEDED:KRB5_KPASSWD_INITIAL_FLAG_NEEDED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KPASSWD\_INITIAL\_FLAG\_NEEDED}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar The presented credentials were not obtained using a password directly. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KPASSWD\_INITIAL\_FLAG\_NEEDED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{7}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KPASSWD\_MALFORMED} \label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_MALFORMED:krb5-kpasswd-malformed}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_MALFORMED:krb5-kpasswd-malformed-data}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_MALFORMED::doc}}\index{KRB5\_KPASSWD\_MALFORMED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KPASSWD\_MALFORMED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_MALFORMED:KRB5_KPASSWD_MALFORMED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KPASSWD\_MALFORMED}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Malformed request. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KPASSWD\_MALFORMED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KPASSWD\_SOFTERROR} \label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_SOFTERROR:krb5-kpasswd-softerror}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_SOFTERROR:krb5-kpasswd-softerror-data}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_SOFTERROR::doc}}\index{KRB5\_KPASSWD\_SOFTERROR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KPASSWD\_SOFTERROR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_SOFTERROR:KRB5_KPASSWD_SOFTERROR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KPASSWD\_SOFTERROR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Password change rejected. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KPASSWD\_SOFTERROR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_KPASSWD\_SUCCESS} \label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_SUCCESS:krb5-kpasswd-success}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_SUCCESS:krb5-kpasswd-success-data}}\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_SUCCESS::doc}}\index{KRB5\_KPASSWD\_SUCCESS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_KPASSWD\_SUCCESS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_KPASSWD_SUCCESS:KRB5_KPASSWD_SUCCESS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_KPASSWD\_SUCCESS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Success. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_KPASSWD\_SUCCESS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ALL\_ACCT\_EXPTIME} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_ACCT_EXPTIME:krb5-lrq-all-acct-exptime}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_ACCT_EXPTIME:krb5-lrq-all-acct-exptime-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_ACCT_EXPTIME::doc}}\index{KRB5\_LRQ\_ALL\_ACCT\_EXPTIME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ALL\_ACCT\_EXPTIME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_ACCT_EXPTIME:KRB5_LRQ_ALL_ACCT_EXPTIME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ALL\_ACCT\_EXPTIME}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ALL\_ACCT\_EXPTIME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{7}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ALL\_LAST\_INITIAL} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_INITIAL:krb5-lrq-all-last-initial}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_INITIAL:krb5-lrq-all-last-initial-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_INITIAL::doc}}\index{KRB5\_LRQ\_ALL\_LAST\_INITIAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ALL\_LAST\_INITIAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_INITIAL:KRB5_LRQ_ALL_LAST_INITIAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_INITIAL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_INITIAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ALL\_LAST\_RENEWAL} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_RENEWAL:krb5-lrq-all-last-renewal}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_RENEWAL:krb5-lrq-all-last-renewal-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_RENEWAL::doc}}\index{KRB5\_LRQ\_ALL\_LAST\_RENEWAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ALL\_LAST\_RENEWAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_RENEWAL:KRB5_LRQ_ALL_LAST_RENEWAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_RENEWAL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_RENEWAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ALL\_LAST\_REQ} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_REQ:krb5-lrq-all-last-req}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_REQ:krb5-lrq-all-last-req-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_REQ::doc}}\index{KRB5\_LRQ\_ALL\_LAST\_REQ (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ALL\_LAST\_REQ}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_REQ:KRB5_LRQ_ALL_LAST_REQ}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_REQ}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_REQ}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{5}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ALL\_LAST\_TGT} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT:krb5-lrq-all-last-tgt}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT:krb5-lrq-all-last-tgt-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT::doc}}\index{KRB5\_LRQ\_ALL\_LAST\_TGT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ALL\_LAST\_TGT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT:KRB5_LRQ_ALL_LAST_TGT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_TGT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_TGT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ALL\_LAST\_TGT\_ISSUED} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT_ISSUED:krb5-lrq-all-last-tgt-issued}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT_ISSUED:krb5-lrq-all-last-tgt-issued-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT_ISSUED::doc}}\index{KRB5\_LRQ\_ALL\_LAST\_TGT\_ISSUED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ALL\_LAST\_TGT\_ISSUED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT_ISSUED:KRB5_LRQ_ALL_LAST_TGT_ISSUED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_TGT\_ISSUED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ALL\_LAST\_TGT\_ISSUED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{3}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ALL\_PW\_EXPTIME} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_PW_EXPTIME:krb5-lrq-all-pw-exptime}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_PW_EXPTIME:krb5-lrq-all-pw-exptime-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_PW_EXPTIME::doc}}\index{KRB5\_LRQ\_ALL\_PW\_EXPTIME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ALL\_PW\_EXPTIME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ALL_PW_EXPTIME:KRB5_LRQ_ALL_PW_EXPTIME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ALL\_PW\_EXPTIME}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ALL\_PW\_EXPTIME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{6}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_NONE} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_NONE:krb5-lrq-none}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_NONE:krb5-lrq-none-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_NONE::doc}}\index{KRB5\_LRQ\_NONE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_NONE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_NONE:KRB5_LRQ_NONE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_NONE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_NONE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ONE\_ACCT\_EXPTIME} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_ACCT_EXPTIME:krb5-lrq-one-acct-exptime}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_ACCT_EXPTIME:krb5-lrq-one-acct-exptime-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_ACCT_EXPTIME::doc}}\index{KRB5\_LRQ\_ONE\_ACCT\_EXPTIME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ONE\_ACCT\_EXPTIME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_ACCT_EXPTIME:KRB5_LRQ_ONE_ACCT_EXPTIME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ONE\_ACCT\_EXPTIME}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ONE\_ACCT\_EXPTIME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\sphinxhyphen{}7)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ONE\_LAST\_INITIAL} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_INITIAL:krb5-lrq-one-last-initial}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_INITIAL:krb5-lrq-one-last-initial-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_INITIAL::doc}}\index{KRB5\_LRQ\_ONE\_LAST\_INITIAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ONE\_LAST\_INITIAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_INITIAL:KRB5_LRQ_ONE_LAST_INITIAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_INITIAL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_INITIAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\sphinxhyphen{}2)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ONE\_LAST\_RENEWAL} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_RENEWAL:krb5-lrq-one-last-renewal}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_RENEWAL:krb5-lrq-one-last-renewal-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_RENEWAL::doc}}\index{KRB5\_LRQ\_ONE\_LAST\_RENEWAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ONE\_LAST\_RENEWAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_RENEWAL:KRB5_LRQ_ONE_LAST_RENEWAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_RENEWAL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_RENEWAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\sphinxhyphen{}4)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ONE\_LAST\_REQ} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_REQ:krb5-lrq-one-last-req}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_REQ:krb5-lrq-one-last-req-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_REQ::doc}}\index{KRB5\_LRQ\_ONE\_LAST\_REQ (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ONE\_LAST\_REQ}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_REQ:KRB5_LRQ_ONE_LAST_REQ}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_REQ}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_REQ}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\sphinxhyphen{}5)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ONE\_LAST\_TGT} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT:krb5-lrq-one-last-tgt}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT:krb5-lrq-one-last-tgt-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT::doc}}\index{KRB5\_LRQ\_ONE\_LAST\_TGT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ONE\_LAST\_TGT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT:KRB5_LRQ_ONE_LAST_TGT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_TGT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_TGT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\sphinxhyphen{}1)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ONE\_LAST\_TGT\_ISSUED} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT_ISSUED:krb5-lrq-one-last-tgt-issued}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT_ISSUED:krb5-lrq-one-last-tgt-issued-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT_ISSUED::doc}}\index{KRB5\_LRQ\_ONE\_LAST\_TGT\_ISSUED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ONE\_LAST\_TGT\_ISSUED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT_ISSUED:KRB5_LRQ_ONE_LAST_TGT_ISSUED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_TGT\_ISSUED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ONE\_LAST\_TGT\_ISSUED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\sphinxhyphen{}3)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_LRQ\_ONE\_PW\_EXPTIME} \label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_PW_EXPTIME:krb5-lrq-one-pw-exptime}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_PW_EXPTIME:krb5-lrq-one-pw-exptime-data}}\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_PW_EXPTIME::doc}}\index{KRB5\_LRQ\_ONE\_PW\_EXPTIME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_LRQ\_ONE\_PW\_EXPTIME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_LRQ_ONE_PW_EXPTIME:KRB5_LRQ_ONE_PW_EXPTIME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_LRQ\_ONE\_PW\_EXPTIME}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_LRQ\_ONE\_PW\_EXPTIME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\sphinxhyphen{}6)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_ENTERPRISE\_PRINCIPAL} \label{\detokenize{appdev/refs/macros/KRB5_NT_ENTERPRISE_PRINCIPAL:krb5-nt-enterprise-principal}}\label{\detokenize{appdev/refs/macros/KRB5_NT_ENTERPRISE_PRINCIPAL:krb5-nt-enterprise-principal-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_ENTERPRISE_PRINCIPAL::doc}}\index{KRB5\_NT\_ENTERPRISE\_PRINCIPAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_ENTERPRISE\_PRINCIPAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_ENTERPRISE_PRINCIPAL:KRB5_NT_ENTERPRISE_PRINCIPAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_ENTERPRISE\_PRINCIPAL}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Windows 2000 UPN. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_ENTERPRISE\_PRINCIPAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{10}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_ENT\_PRINCIPAL\_AND\_ID} \label{\detokenize{appdev/refs/macros/KRB5_NT_ENT_PRINCIPAL_AND_ID:krb5-nt-ent-principal-and-id}}\label{\detokenize{appdev/refs/macros/KRB5_NT_ENT_PRINCIPAL_AND_ID:krb5-nt-ent-principal-and-id-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_ENT_PRINCIPAL_AND_ID::doc}}\index{KRB5\_NT\_ENT\_PRINCIPAL\_AND\_ID (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_ENT\_PRINCIPAL\_AND\_ID}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_ENT_PRINCIPAL_AND_ID:KRB5_NT_ENT_PRINCIPAL_AND_ID}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_ENT\_PRINCIPAL\_AND\_ID}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar NT 4 style name and SID. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_ENT\_PRINCIPAL\_AND\_ID}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{\sphinxhyphen{}130}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_MS\_PRINCIPAL} \label{\detokenize{appdev/refs/macros/KRB5_NT_MS_PRINCIPAL:krb5-nt-ms-principal}}\label{\detokenize{appdev/refs/macros/KRB5_NT_MS_PRINCIPAL:krb5-nt-ms-principal-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_MS_PRINCIPAL::doc}}\index{KRB5\_NT\_MS\_PRINCIPAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_MS\_PRINCIPAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_MS_PRINCIPAL:KRB5_NT_MS_PRINCIPAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_MS\_PRINCIPAL}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Windows 2000 UPN and SID. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_MS\_PRINCIPAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{\sphinxhyphen{}128}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_MS\_PRINCIPAL\_AND\_ID} \label{\detokenize{appdev/refs/macros/KRB5_NT_MS_PRINCIPAL_AND_ID:krb5-nt-ms-principal-and-id}}\label{\detokenize{appdev/refs/macros/KRB5_NT_MS_PRINCIPAL_AND_ID:krb5-nt-ms-principal-and-id-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_MS_PRINCIPAL_AND_ID::doc}}\index{KRB5\_NT\_MS\_PRINCIPAL\_AND\_ID (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_MS\_PRINCIPAL\_AND\_ID}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_MS_PRINCIPAL_AND_ID:KRB5_NT_MS_PRINCIPAL_AND_ID}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_MS\_PRINCIPAL\_AND\_ID}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar NT 4 style name. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_MS\_PRINCIPAL\_AND\_ID}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{\sphinxhyphen{}129}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_PRINCIPAL} \label{\detokenize{appdev/refs/macros/KRB5_NT_PRINCIPAL:krb5-nt-principal}}\label{\detokenize{appdev/refs/macros/KRB5_NT_PRINCIPAL:krb5-nt-principal-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_PRINCIPAL::doc}}\index{KRB5\_NT\_PRINCIPAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_PRINCIPAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_PRINCIPAL:KRB5_NT_PRINCIPAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_PRINCIPAL}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Just the name of the principal as in DCE, or for users. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_PRINCIPAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_SMTP\_NAME} \label{\detokenize{appdev/refs/macros/KRB5_NT_SMTP_NAME:krb5-nt-smtp-name}}\label{\detokenize{appdev/refs/macros/KRB5_NT_SMTP_NAME:krb5-nt-smtp-name-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_SMTP_NAME::doc}}\index{KRB5\_NT\_SMTP\_NAME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_SMTP\_NAME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_SMTP_NAME:KRB5_NT_SMTP_NAME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_SMTP\_NAME}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Name in form of SMTP email name. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_SMTP\_NAME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{7}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_SRV\_HST} \label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_HST:krb5-nt-srv-hst}}\label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_HST:krb5-nt-srv-hst-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_HST::doc}}\index{KRB5\_NT\_SRV\_HST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_SRV\_HST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_HST:KRB5_NT_SRV_HST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_SRV\_HST}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Service with host name as instance (telnet, rcommands) \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_SRV\_HST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{3}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_SRV\_INST} \label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_INST:krb5-nt-srv-inst}}\label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_INST:krb5-nt-srv-inst-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_INST::doc}}\index{KRB5\_NT\_SRV\_INST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_SRV\_INST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_INST:KRB5_NT_SRV_INST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_SRV\_INST}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Service and other unique instance (krbtgt) \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_SRV\_INST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_SRV\_XHST} \label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_XHST:krb5-nt-srv-xhst}}\label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_XHST:krb5-nt-srv-xhst-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_XHST::doc}}\index{KRB5\_NT\_SRV\_XHST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_SRV\_XHST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_SRV_XHST:KRB5_NT_SRV_XHST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_SRV\_XHST}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Service with host as remaining components. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_SRV\_XHST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_UID} \label{\detokenize{appdev/refs/macros/KRB5_NT_UID:krb5-nt-uid}}\label{\detokenize{appdev/refs/macros/KRB5_NT_UID:krb5-nt-uid-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_UID::doc}}\index{KRB5\_NT\_UID (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_UID}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_UID:KRB5_NT_UID}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_UID}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Unique ID. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_UID}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{5}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_UNKNOWN} \label{\detokenize{appdev/refs/macros/KRB5_NT_UNKNOWN:krb5-nt-unknown}}\label{\detokenize{appdev/refs/macros/KRB5_NT_UNKNOWN:krb5-nt-unknown-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_UNKNOWN::doc}}\index{KRB5\_NT\_UNKNOWN (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_UNKNOWN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_UNKNOWN:KRB5_NT_UNKNOWN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_UNKNOWN}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Name type not known. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_UNKNOWN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_WELLKNOWN} \label{\detokenize{appdev/refs/macros/KRB5_NT_WELLKNOWN:krb5-nt-wellknown}}\label{\detokenize{appdev/refs/macros/KRB5_NT_WELLKNOWN:krb5-nt-wellknown-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_WELLKNOWN::doc}}\index{KRB5\_NT\_WELLKNOWN (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_WELLKNOWN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_WELLKNOWN:KRB5_NT_WELLKNOWN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_WELLKNOWN}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Well\sphinxhyphen{}known (special) principal. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_WELLKNOWN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{11}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_NT\_X500\_PRINCIPAL} \label{\detokenize{appdev/refs/macros/KRB5_NT_X500_PRINCIPAL:krb5-nt-x500-principal}}\label{\detokenize{appdev/refs/macros/KRB5_NT_X500_PRINCIPAL:krb5-nt-x500-principal-data}}\label{\detokenize{appdev/refs/macros/KRB5_NT_X500_PRINCIPAL::doc}}\index{KRB5\_NT\_X500\_PRINCIPAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_NT\_X500\_PRINCIPAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_NT_X500_PRINCIPAL:KRB5_NT_X500_PRINCIPAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_NT\_X500\_PRINCIPAL}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar PKINIT. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_NT\_X500\_PRINCIPAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{6}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_ATTRIBUTES\_INFO} \label{\detokenize{appdev/refs/macros/KRB5_PAC_ATTRIBUTES_INFO:krb5-pac-attributes-info}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_ATTRIBUTES_INFO:krb5-pac-attributes-info-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_ATTRIBUTES_INFO::doc}}\index{KRB5\_PAC\_ATTRIBUTES\_INFO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_ATTRIBUTES\_INFO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_ATTRIBUTES_INFO:KRB5_PAC_ATTRIBUTES_INFO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_ATTRIBUTES\_INFO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar PAC attributes. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_ATTRIBUTES\_INFO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{17}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_CLIENT\_INFO} \label{\detokenize{appdev/refs/macros/KRB5_PAC_CLIENT_INFO:krb5-pac-client-info}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_CLIENT_INFO:krb5-pac-client-info-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_CLIENT_INFO::doc}}\index{KRB5\_PAC\_CLIENT\_INFO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_CLIENT\_INFO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_CLIENT_INFO:KRB5_PAC_CLIENT_INFO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_CLIENT\_INFO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Client name and ticket info. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_CLIENT\_INFO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{10}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_CLIENT\_CLAIMS} \label{\detokenize{appdev/refs/macros/KRB5_PAC_CLIENT_CLAIMS:krb5-pac-client-claims}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_CLIENT_CLAIMS:krb5-pac-client-claims-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_CLIENT_CLAIMS::doc}}\index{KRB5\_PAC\_CLIENT\_CLAIMS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_CLIENT\_CLAIMS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_CLIENT_CLAIMS:KRB5_PAC_CLIENT_CLAIMS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_CLIENT\_CLAIMS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Client claims information. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_CLIENT\_CLAIMS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{13}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_CREDENTIALS\_INFO} \label{\detokenize{appdev/refs/macros/KRB5_PAC_CREDENTIALS_INFO:krb5-pac-credentials-info}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_CREDENTIALS_INFO:krb5-pac-credentials-info-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_CREDENTIALS_INFO::doc}}\index{KRB5\_PAC\_CREDENTIALS\_INFO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_CREDENTIALS\_INFO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_CREDENTIALS_INFO:KRB5_PAC_CREDENTIALS_INFO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_CREDENTIALS\_INFO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Credentials information. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_CREDENTIALS\_INFO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_DELEGATION\_INFO} \label{\detokenize{appdev/refs/macros/KRB5_PAC_DELEGATION_INFO:krb5-pac-delegation-info}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_DELEGATION_INFO:krb5-pac-delegation-info-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_DELEGATION_INFO::doc}}\index{KRB5\_PAC\_DELEGATION\_INFO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_DELEGATION\_INFO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_DELEGATION_INFO:KRB5_PAC_DELEGATION_INFO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_DELEGATION\_INFO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Constrained delegation info. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_DELEGATION\_INFO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{11}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_DEVICE\_CLAIMS} \label{\detokenize{appdev/refs/macros/KRB5_PAC_DEVICE_CLAIMS:krb5-pac-device-claims}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_DEVICE_CLAIMS:krb5-pac-device-claims-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_DEVICE_CLAIMS::doc}}\index{KRB5\_PAC\_DEVICE\_CLAIMS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_DEVICE\_CLAIMS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_DEVICE_CLAIMS:KRB5_PAC_DEVICE_CLAIMS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_DEVICE\_CLAIMS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Device claims information. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_DEVICE\_CLAIMS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{15}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_DEVICE\_INFO} \label{\detokenize{appdev/refs/macros/KRB5_PAC_DEVICE_INFO:krb5-pac-device-info}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_DEVICE_INFO:krb5-pac-device-info-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_DEVICE_INFO::doc}}\index{KRB5\_PAC\_DEVICE\_INFO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_DEVICE\_INFO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_DEVICE_INFO:KRB5_PAC_DEVICE_INFO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_DEVICE\_INFO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Device information. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_DEVICE\_INFO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{14}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_LOGON\_INFO} \label{\detokenize{appdev/refs/macros/KRB5_PAC_LOGON_INFO:krb5-pac-logon-info}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_LOGON_INFO:krb5-pac-logon-info-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_LOGON_INFO::doc}}\index{KRB5\_PAC\_LOGON\_INFO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_LOGON\_INFO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_LOGON_INFO:KRB5_PAC_LOGON_INFO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_LOGON\_INFO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Logon information. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_LOGON\_INFO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_PRIVSVR\_CHECKSUM} \label{\detokenize{appdev/refs/macros/KRB5_PAC_PRIVSVR_CHECKSUM:krb5-pac-privsvr-checksum}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_PRIVSVR_CHECKSUM:krb5-pac-privsvr-checksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_PRIVSVR_CHECKSUM::doc}}\index{KRB5\_PAC\_PRIVSVR\_CHECKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_PRIVSVR\_CHECKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_PRIVSVR_CHECKSUM:KRB5_PAC_PRIVSVR_CHECKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_PRIVSVR\_CHECKSUM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar KDC checksum. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_PRIVSVR\_CHECKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{7}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_REQUESTOR} \label{\detokenize{appdev/refs/macros/KRB5_PAC_REQUESTOR:krb5-pac-requestor}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_REQUESTOR:krb5-pac-requestor-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_REQUESTOR::doc}}\index{KRB5\_PAC\_REQUESTOR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_REQUESTOR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_REQUESTOR:KRB5_PAC_REQUESTOR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_REQUESTOR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar PAC requestor SID. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_REQUESTOR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{18}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_SERVER\_CHECKSUM} \label{\detokenize{appdev/refs/macros/KRB5_PAC_SERVER_CHECKSUM:krb5-pac-server-checksum}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_SERVER_CHECKSUM:krb5-pac-server-checksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_SERVER_CHECKSUM::doc}}\index{KRB5\_PAC\_SERVER\_CHECKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_SERVER\_CHECKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_SERVER_CHECKSUM:KRB5_PAC_SERVER_CHECKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_SERVER\_CHECKSUM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Server checksum. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_SERVER\_CHECKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{6}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_TICKET\_CHECKSUM} \label{\detokenize{appdev/refs/macros/KRB5_PAC_TICKET_CHECKSUM:krb5-pac-ticket-checksum}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_TICKET_CHECKSUM:krb5-pac-ticket-checksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_TICKET_CHECKSUM::doc}}\index{KRB5\_PAC\_TICKET\_CHECKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_TICKET\_CHECKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_TICKET_CHECKSUM:KRB5_PAC_TICKET_CHECKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_TICKET\_CHECKSUM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Ticket checksum. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_TICKET\_CHECKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{16}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_UPN\_DNS\_INFO} \label{\detokenize{appdev/refs/macros/KRB5_PAC_UPN_DNS_INFO:krb5-pac-upn-dns-info}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_UPN_DNS_INFO:krb5-pac-upn-dns-info-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_UPN_DNS_INFO::doc}}\index{KRB5\_PAC\_UPN\_DNS\_INFO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_UPN\_DNS\_INFO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_UPN_DNS_INFO:KRB5_PAC_UPN_DNS_INFO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_UPN\_DNS\_INFO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar User principal name and DNS info. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_UPN\_DNS\_INFO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{12}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PAC\_FULL\_CHECKSUM} \label{\detokenize{appdev/refs/macros/KRB5_PAC_FULL_CHECKSUM:krb5-pac-full-checksum}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_FULL_CHECKSUM:krb5-pac-full-checksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_PAC_FULL_CHECKSUM::doc}}\index{KRB5\_PAC\_FULL\_CHECKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PAC\_FULL\_CHECKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PAC_FULL_CHECKSUM:KRB5_PAC_FULL_CHECKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PAC\_FULL\_CHECKSUM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar KDC full checksum. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PAC\_FULL\_CHECKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{19}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_AFS3\_SALT} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_AFS3_SALT:krb5-padata-afs3-salt}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AFS3_SALT:krb5-padata-afs3-salt-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AFS3_SALT::doc}}\index{KRB5\_PADATA\_AFS3\_SALT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_AFS3\_SALT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AFS3_SALT:KRB5_PADATA_AFS3_SALT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_AFS3\_SALT}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Cygnus. \sphinxAtStartPar RFC 4120, 3961 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_AFS3\_SALT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{10}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_AP\_REQ} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_AP_REQ:krb5-padata-ap-req}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AP_REQ:krb5-padata-ap-req-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AP_REQ::doc}}\index{KRB5\_PADATA\_AP\_REQ (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_AP\_REQ}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AP_REQ:KRB5_PADATA_AP_REQ}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_AP\_REQ}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_AP\_REQ}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_AS\_CHECKSUM} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_AS_CHECKSUM:krb5-padata-as-checksum}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AS_CHECKSUM:krb5-padata-as-checksum-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AS_CHECKSUM::doc}}\index{KRB5\_PADATA\_AS\_CHECKSUM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_AS\_CHECKSUM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AS_CHECKSUM:KRB5_PADATA_AS_CHECKSUM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_AS\_CHECKSUM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar AS checksum. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_AS\_CHECKSUM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{132}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_AS\_FRESHNESS} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_AS_FRESHNESS:krb5-padata-as-freshness}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AS_FRESHNESS:krb5-padata-as-freshness-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AS_FRESHNESS::doc}}\index{KRB5\_PADATA\_AS\_FRESHNESS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_AS\_FRESHNESS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_AS_FRESHNESS:KRB5_PADATA_AS_FRESHNESS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_AS\_FRESHNESS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 8070. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_AS\_FRESHNESS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{150}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_ENCRYPTED\_CHALLENGE} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENCRYPTED_CHALLENGE:krb5-padata-encrypted-challenge}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENCRYPTED_CHALLENGE:krb5-padata-encrypted-challenge-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENCRYPTED_CHALLENGE::doc}}\index{KRB5\_PADATA\_ENCRYPTED\_CHALLENGE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_ENCRYPTED\_CHALLENGE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENCRYPTED_CHALLENGE:KRB5_PADATA_ENCRYPTED_CHALLENGE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_ENCRYPTED\_CHALLENGE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6113. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_ENCRYPTED\_CHALLENGE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{138}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_ENC\_SANDIA\_SECURID} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_SANDIA_SECURID:krb5-padata-enc-sandia-securid}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_SANDIA_SECURID:krb5-padata-enc-sandia-securid-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_SANDIA_SECURID::doc}}\index{KRB5\_PADATA\_ENC\_SANDIA\_SECURID (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_ENC\_SANDIA\_SECURID}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_SANDIA_SECURID:KRB5_PADATA_ENC_SANDIA_SECURID}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_ENC\_SANDIA\_SECURID}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar SecurId passcode. \sphinxAtStartPar RFC 4120 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_ENC\_SANDIA\_SECURID}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{6}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_ENC\_TIMESTAMP} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_TIMESTAMP:krb5-padata-enc-timestamp}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_TIMESTAMP:krb5-padata-enc-timestamp-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_TIMESTAMP::doc}}\index{KRB5\_PADATA\_ENC\_TIMESTAMP (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_ENC\_TIMESTAMP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_TIMESTAMP:KRB5_PADATA_ENC_TIMESTAMP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_ENC\_TIMESTAMP}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 4120. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_ENC\_TIMESTAMP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_ENC\_UNIX\_TIME} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_UNIX_TIME:krb5-padata-enc-unix-time}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_UNIX_TIME:krb5-padata-enc-unix-time-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_UNIX_TIME::doc}}\index{KRB5\_PADATA\_ENC\_UNIX\_TIME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_ENC\_UNIX\_TIME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ENC_UNIX_TIME:KRB5_PADATA_ENC_UNIX_TIME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_ENC\_UNIX\_TIME}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar timestamp encrypted in key. \sphinxAtStartPar RFC 4120 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_ENC\_UNIX\_TIME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{5}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_ETYPE\_INFO} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_ETYPE_INFO:krb5-padata-etype-info}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ETYPE_INFO:krb5-padata-etype-info-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ETYPE_INFO::doc}}\index{KRB5\_PADATA\_ETYPE\_INFO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_ETYPE\_INFO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ETYPE_INFO:KRB5_PADATA_ETYPE_INFO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_ETYPE\_INFO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Etype info for preauth. \sphinxAtStartPar RFC 4120 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_ETYPE\_INFO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{11}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_ETYPE\_INFO2} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_ETYPE_INFO2:krb5-padata-etype-info2}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ETYPE_INFO2:krb5-padata-etype-info2-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ETYPE_INFO2::doc}}\index{KRB5\_PADATA\_ETYPE\_INFO2 (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_ETYPE\_INFO2}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_ETYPE_INFO2:KRB5_PADATA_ETYPE_INFO2}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_ETYPE\_INFO2}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 4120. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_ETYPE\_INFO2}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{19}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_FOR\_USER} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_FOR_USER:krb5-padata-for-user}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FOR_USER:krb5-padata-for-user-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FOR_USER::doc}}\index{KRB5\_PADATA\_FOR\_USER (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_FOR\_USER}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FOR_USER:KRB5_PADATA_FOR_USER}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_FOR\_USER}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar username protocol transition request \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_FOR\_USER}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{129}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_FX\_COOKIE} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_COOKIE:krb5-padata-fx-cookie}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_COOKIE:krb5-padata-fx-cookie-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_COOKIE::doc}}\index{KRB5\_PADATA\_FX\_COOKIE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_FX\_COOKIE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_COOKIE:KRB5_PADATA_FX_COOKIE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_FX\_COOKIE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6113. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_FX\_COOKIE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{133}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_FX\_ERROR} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_ERROR:krb5-padata-fx-error}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_ERROR:krb5-padata-fx-error-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_ERROR::doc}}\index{KRB5\_PADATA\_FX\_ERROR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_FX\_ERROR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_ERROR:KRB5_PADATA_FX_ERROR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_FX\_ERROR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6113. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_FX\_ERROR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{137}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_FX\_FAST} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_FAST:krb5-padata-fx-fast}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_FAST:krb5-padata-fx-fast-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_FAST::doc}}\index{KRB5\_PADATA\_FX\_FAST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_FX\_FAST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_FX_FAST:KRB5_PADATA_FX_FAST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_FX\_FAST}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6113. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_FX\_FAST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{136}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_GET\_FROM\_TYPED\_DATA} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_GET_FROM_TYPED_DATA:krb5-padata-get-from-typed-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_GET_FROM_TYPED_DATA:krb5-padata-get-from-typed-data-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_GET_FROM_TYPED_DATA::doc}}\index{KRB5\_PADATA\_GET\_FROM\_TYPED\_DATA (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_GET\_FROM\_TYPED\_DATA}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_GET_FROM_TYPED_DATA:KRB5_PADATA_GET_FROM_TYPED_DATA}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_GET\_FROM\_TYPED\_DATA}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Embedded in typed data. \sphinxAtStartPar RFC 4120 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_GET\_FROM\_TYPED\_DATA}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{22}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_NONE} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_NONE:krb5-padata-none}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_NONE:krb5-padata-none-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_NONE::doc}}\index{KRB5\_PADATA\_NONE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_NONE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_NONE:KRB5_PADATA_NONE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_NONE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_NONE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_OSF\_DCE} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_OSF_DCE:krb5-padata-osf-dce}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OSF_DCE:krb5-padata-osf-dce-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OSF_DCE::doc}}\index{KRB5\_PADATA\_OSF\_DCE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_OSF\_DCE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OSF_DCE:KRB5_PADATA_OSF_DCE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_OSF\_DCE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar OSF DCE. \sphinxAtStartPar RFC 4120 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_OSF\_DCE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{8}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_OTP\_CHALLENGE} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_CHALLENGE:krb5-padata-otp-challenge}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_CHALLENGE:krb5-padata-otp-challenge-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_CHALLENGE::doc}}\index{KRB5\_PADATA\_OTP\_CHALLENGE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_OTP\_CHALLENGE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_CHALLENGE:KRB5_PADATA_OTP_CHALLENGE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_OTP\_CHALLENGE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6560 section 4.1. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_OTP\_CHALLENGE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{141}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_OTP\_PIN\_CHANGE} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_PIN_CHANGE:krb5-padata-otp-pin-change}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_PIN_CHANGE:krb5-padata-otp-pin-change-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_PIN_CHANGE::doc}}\index{KRB5\_PADATA\_OTP\_PIN\_CHANGE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_OTP\_PIN\_CHANGE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_PIN_CHANGE:KRB5_PADATA_OTP_PIN_CHANGE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_OTP\_PIN\_CHANGE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6560 section 4.3. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_OTP\_PIN\_CHANGE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{144}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_OTP\_REQUEST} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_REQUEST:krb5-padata-otp-request}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_REQUEST:krb5-padata-otp-request-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_REQUEST::doc}}\index{KRB5\_PADATA\_OTP\_REQUEST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_OTP\_REQUEST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_OTP_REQUEST:KRB5_PADATA_OTP_REQUEST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_OTP\_REQUEST}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6560 section 4.2. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_OTP\_REQUEST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{142}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_PAC\_OPTIONS} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_PAC_OPTIONS:krb5-padata-pac-options}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PAC_OPTIONS:krb5-padata-pac-options-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PAC_OPTIONS::doc}}\index{KRB5\_PADATA\_PAC\_OPTIONS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_PAC\_OPTIONS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PAC_OPTIONS:KRB5_PADATA_PAC_OPTIONS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_PAC\_OPTIONS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar MS\sphinxhyphen{}KILE and MS\sphinxhyphen{}SFU. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_PAC\_OPTIONS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{167}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_PAC\_REQUEST} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_PAC_REQUEST:krb5-padata-pac-request}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PAC_REQUEST:krb5-padata-pac-request-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PAC_REQUEST::doc}}\index{KRB5\_PADATA\_PAC\_REQUEST (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_PAC\_REQUEST}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PAC_REQUEST:KRB5_PADATA_PAC_REQUEST}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_PAC\_REQUEST}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar include Windows PAC \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_PAC\_REQUEST}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{128}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_PKINIT\_KX} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_PKINIT_KX:krb5-padata-pkinit-kx}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PKINIT_KX:krb5-padata-pkinit-kx-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PKINIT_KX::doc}}\index{KRB5\_PADATA\_PKINIT\_KX (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_PKINIT\_KX}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PKINIT_KX:KRB5_PADATA_PKINIT_KX}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_PKINIT\_KX}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 6112. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_PKINIT\_KX}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{147}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_PK\_AS\_REP} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REP:krb5-padata-pk-as-rep}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REP:krb5-padata-pk-as-rep-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REP::doc}}\index{KRB5\_PADATA\_PK\_AS\_REP (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_PK\_AS\_REP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REP:KRB5_PADATA_PK_AS_REP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_PK\_AS\_REP}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar PKINIT. \sphinxAtStartPar RFC 4556 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_PK\_AS\_REP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{17}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_PK\_AS\_REP\_OLD} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REP_OLD:krb5-padata-pk-as-rep-old}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REP_OLD:krb5-padata-pk-as-rep-old-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REP_OLD::doc}}\index{KRB5\_PADATA\_PK\_AS\_REP\_OLD (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_PK\_AS\_REP\_OLD}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REP_OLD:KRB5_PADATA_PK_AS_REP_OLD}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_PK\_AS\_REP\_OLD}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar PKINIT. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_PK\_AS\_REP\_OLD}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{15}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_PK\_AS\_REQ} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REQ:krb5-padata-pk-as-req}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REQ:krb5-padata-pk-as-req-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REQ::doc}}\index{KRB5\_PADATA\_PK\_AS\_REQ (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_PK\_AS\_REQ}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REQ:KRB5_PADATA_PK_AS_REQ}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_PK\_AS\_REQ}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar PKINIT. \sphinxAtStartPar RFC 4556 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_PK\_AS\_REQ}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{16}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_PK\_AS\_REQ\_OLD} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REQ_OLD:krb5-padata-pk-as-req-old}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REQ_OLD:krb5-padata-pk-as-req-old-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REQ_OLD::doc}}\index{KRB5\_PADATA\_PK\_AS\_REQ\_OLD (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_PK\_AS\_REQ\_OLD}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PK_AS_REQ_OLD:KRB5_PADATA_PK_AS_REQ_OLD}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_PK\_AS\_REQ\_OLD}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar PKINIT. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_PK\_AS\_REQ\_OLD}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{14}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_PW\_SALT} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_PW_SALT:krb5-padata-pw-salt}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PW_SALT:krb5-padata-pw-salt-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PW_SALT::doc}}\index{KRB5\_PADATA\_PW\_SALT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_PW\_SALT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_PW_SALT:KRB5_PADATA_PW_SALT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_PW\_SALT}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 4120. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_PW\_SALT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{3}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_REFERRAL} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_REFERRAL:krb5-padata-referral}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_REFERRAL:krb5-padata-referral-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_REFERRAL::doc}}\index{KRB5\_PADATA\_REFERRAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_REFERRAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_REFERRAL:KRB5_PADATA_REFERRAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_REFERRAL}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar draft referral system \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_REFERRAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{25}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_S4U\_X509\_USER} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_S4U_X509_USER:krb5-padata-s4u-x509-user}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_S4U_X509_USER:krb5-padata-s4u-x509-user-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_S4U_X509_USER::doc}}\index{KRB5\_PADATA\_S4U\_X509\_USER (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_S4U\_X509\_USER}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_S4U_X509_USER:KRB5_PADATA_S4U_X509_USER}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_S4U\_X509\_USER}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar certificate protocol transition request \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_S4U\_X509\_USER}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{130}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_SAM\_CHALLENGE} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE:krb5-padata-sam-challenge}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE:krb5-padata-sam-challenge-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE::doc}}\index{KRB5\_PADATA\_SAM\_CHALLENGE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_SAM\_CHALLENGE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE:KRB5_PADATA_SAM_CHALLENGE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_SAM\_CHALLENGE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar SAM/OTP. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_SAM\_CHALLENGE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{12}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_SAM\_CHALLENGE\_2} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE_2:krb5-padata-sam-challenge-2}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE_2:krb5-padata-sam-challenge-2-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE_2::doc}}\index{KRB5\_PADATA\_SAM\_CHALLENGE\_2 (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_SAM\_CHALLENGE\_2}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE_2:KRB5_PADATA_SAM_CHALLENGE_2}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_SAM\_CHALLENGE\_2}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar draft challenge system, updated \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_SAM\_CHALLENGE\_2}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{30}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_SAM\_REDIRECT} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_REDIRECT:krb5-padata-sam-redirect}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_REDIRECT:krb5-padata-sam-redirect-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_REDIRECT::doc}}\index{KRB5\_PADATA\_SAM\_REDIRECT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_SAM\_REDIRECT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_REDIRECT:KRB5_PADATA_SAM_REDIRECT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_SAM\_REDIRECT}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar SAM/OTP. \sphinxAtStartPar RFC 4120 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_SAM\_REDIRECT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{21}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_SAM\_RESPONSE} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE:krb5-padata-sam-response}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE:krb5-padata-sam-response-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE::doc}}\index{KRB5\_PADATA\_SAM\_RESPONSE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_SAM\_RESPONSE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE:KRB5_PADATA_SAM_RESPONSE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_SAM\_RESPONSE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar SAM/OTP. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_SAM\_RESPONSE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{13}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_SAM\_RESPONSE\_2} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE_2:krb5-padata-sam-response-2}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE_2:krb5-padata-sam-response-2-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE_2::doc}}\index{KRB5\_PADATA\_SAM\_RESPONSE\_2 (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_SAM\_RESPONSE\_2}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE_2:KRB5_PADATA_SAM_RESPONSE_2}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_SAM\_RESPONSE\_2}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar draft challenge system, updated \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_SAM\_RESPONSE\_2}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{31}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_SESAME} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_SESAME:krb5-padata-sesame}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SESAME:krb5-padata-sesame-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SESAME::doc}}\index{KRB5\_PADATA\_SESAME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_SESAME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SESAME:KRB5_PADATA_SESAME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_SESAME}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Sesame project. \sphinxAtStartPar RFC 4120 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_SESAME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{7}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_SPAKE} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_SPAKE:krb5-padata-spake}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SPAKE:krb5-padata-spake-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SPAKE::doc}}\index{KRB5\_PADATA\_SPAKE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_SPAKE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SPAKE:KRB5_PADATA_SPAKE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_SPAKE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_SPAKE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{151}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_REDHAT\_IDP\_OAUTH2} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_REDHAT_IDP_OAUTH2:krb5-padata-redhat-idp-oauth2}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_REDHAT_IDP_OAUTH2:krb5-padata-redhat-idp-oauth2-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_REDHAT_IDP_OAUTH2::doc}}\index{KRB5\_PADATA\_REDHAT\_IDP\_OAUTH2 (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_REDHAT\_IDP\_OAUTH2}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_REDHAT_IDP_OAUTH2:KRB5_PADATA_REDHAT_IDP_OAUTH2}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_REDHAT\_IDP\_OAUTH2}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Red Hat IdP mechanism. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_REDHAT\_IDP\_OAUTH2}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{152}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_REDHAT\_PASSKEY} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_REDHAT_PASSKEY:krb5-padata-redhat-passkey}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_REDHAT_PASSKEY:krb5-padata-redhat-passkey-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_REDHAT_PASSKEY::doc}}\index{KRB5\_PADATA\_REDHAT\_PASSKEY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_REDHAT\_PASSKEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_REDHAT_PASSKEY:KRB5_PADATA_REDHAT_PASSKEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_REDHAT\_PASSKEY}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Red Hat Passkey mechanism. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_REDHAT\_PASSKEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{153}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_SVR\_REFERRAL\_INFO} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_SVR_REFERRAL_INFO:krb5-padata-svr-referral-info}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SVR_REFERRAL_INFO:krb5-padata-svr-referral-info-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SVR_REFERRAL_INFO::doc}}\index{KRB5\_PADATA\_SVR\_REFERRAL\_INFO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_SVR\_REFERRAL\_INFO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_SVR_REFERRAL_INFO:KRB5_PADATA_SVR_REFERRAL_INFO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_SVR\_REFERRAL\_INFO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Windows 2000 referrals. \sphinxAtStartPar RFC 6820 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_SVR\_REFERRAL\_INFO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{20}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_TGS\_REQ} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_TGS_REQ:krb5-padata-tgs-req}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_TGS_REQ:krb5-padata-tgs-req-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_TGS_REQ::doc}}\index{KRB5\_PADATA\_TGS\_REQ (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_TGS\_REQ}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_TGS_REQ:KRB5_PADATA_TGS_REQ}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_TGS\_REQ}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_TGS\_REQ}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_AP\_REQ}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PADATA\_USE\_SPECIFIED\_KVNO} \label{\detokenize{appdev/refs/macros/KRB5_PADATA_USE_SPECIFIED_KVNO:krb5-padata-use-specified-kvno}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_USE_SPECIFIED_KVNO:krb5-padata-use-specified-kvno-data}}\label{\detokenize{appdev/refs/macros/KRB5_PADATA_USE_SPECIFIED_KVNO::doc}}\index{KRB5\_PADATA\_USE\_SPECIFIED\_KVNO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PADATA\_USE\_SPECIFIED\_KVNO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PADATA_USE_SPECIFIED_KVNO:KRB5_PADATA_USE_SPECIFIED_KVNO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PADATA\_USE\_SPECIFIED\_KVNO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar RFC 4120. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PADATA\_USE\_SPECIFIED\_KVNO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{20}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_COMPARE\_CASEFOLD} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_CASEFOLD:krb5-principal-compare-casefold}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_CASEFOLD:krb5-principal-compare-casefold-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_CASEFOLD::doc}}\index{KRB5\_PRINCIPAL\_COMPARE\_CASEFOLD (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_COMPARE\_CASEFOLD}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_CASEFOLD:KRB5_PRINCIPAL_COMPARE_CASEFOLD}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_COMPARE\_CASEFOLD}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar case\sphinxhyphen{}insensitive \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_COMPARE\_CASEFOLD}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_COMPARE\_ENTERPRISE} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_ENTERPRISE:krb5-principal-compare-enterprise}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_ENTERPRISE:krb5-principal-compare-enterprise-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_ENTERPRISE::doc}}\index{KRB5\_PRINCIPAL\_COMPARE\_ENTERPRISE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_COMPARE\_ENTERPRISE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_ENTERPRISE:KRB5_PRINCIPAL_COMPARE_ENTERPRISE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_COMPARE\_ENTERPRISE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar UPNs as real principals. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_COMPARE\_ENTERPRISE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_COMPARE\_IGNORE\_REALM} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_IGNORE_REALM:krb5-principal-compare-ignore-realm}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_IGNORE_REALM:krb5-principal-compare-ignore-realm-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_IGNORE_REALM::doc}}\index{KRB5\_PRINCIPAL\_COMPARE\_IGNORE\_REALM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_COMPARE\_IGNORE\_REALM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_IGNORE_REALM:KRB5_PRINCIPAL_COMPARE_IGNORE_REALM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_COMPARE\_IGNORE\_REALM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar ignore realm component \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_COMPARE\_IGNORE\_REALM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_COMPARE\_UTF8} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_UTF8:krb5-principal-compare-utf8}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_UTF8:krb5-principal-compare-utf8-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_UTF8::doc}}\index{KRB5\_PRINCIPAL\_COMPARE\_UTF8 (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_COMPARE\_UTF8}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_UTF8:KRB5_PRINCIPAL_COMPARE_UTF8}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_COMPARE\_UTF8}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar treat principals as UTF\sphinxhyphen{}8 \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_COMPARE\_UTF8}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{8}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_PARSE\_ENTERPRISE} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_ENTERPRISE:krb5-principal-parse-enterprise}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_ENTERPRISE:krb5-principal-parse-enterprise-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_ENTERPRISE::doc}}\index{KRB5\_PRINCIPAL\_PARSE\_ENTERPRISE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_PARSE\_ENTERPRISE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_ENTERPRISE:KRB5_PRINCIPAL_PARSE_ENTERPRISE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_ENTERPRISE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Create single\sphinxhyphen{}component enterprise principle. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_ENTERPRISE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_PARSE\_IGNORE\_REALM} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_IGNORE_REALM:krb5-principal-parse-ignore-realm}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_IGNORE_REALM:krb5-principal-parse-ignore-realm-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_IGNORE_REALM::doc}}\index{KRB5\_PRINCIPAL\_PARSE\_IGNORE\_REALM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_PARSE\_IGNORE\_REALM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_IGNORE_REALM:KRB5_PRINCIPAL_PARSE_IGNORE_REALM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_IGNORE\_REALM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Ignore realm if present. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_IGNORE\_REALM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x8}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_PARSE\_NO\_DEF\_REALM} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_DEF_REALM:krb5-principal-parse-no-def-realm}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_DEF_REALM:krb5-principal-parse-no-def-realm-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_DEF_REALM::doc}}\index{KRB5\_PRINCIPAL\_PARSE\_NO\_DEF\_REALM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_PARSE\_NO\_DEF\_REALM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_DEF_REALM:KRB5_PRINCIPAL_PARSE_NO_DEF_REALM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_NO\_DEF\_REALM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Don’t add default realm. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_NO\_DEF\_REALM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x10}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_PARSE\_NO\_REALM} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_REALM:krb5-principal-parse-no-realm}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_REALM:krb5-principal-parse-no-realm-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_REALM::doc}}\index{KRB5\_PRINCIPAL\_PARSE\_NO\_REALM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_PARSE\_NO\_REALM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_REALM:KRB5_PRINCIPAL_PARSE_NO_REALM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_NO\_REALM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Error if realm is present. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_NO\_REALM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_PARSE\_REQUIRE\_REALM} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_REQUIRE_REALM:krb5-principal-parse-require-realm}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_REQUIRE_REALM:krb5-principal-parse-require-realm-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_REQUIRE_REALM::doc}}\index{KRB5\_PRINCIPAL\_PARSE\_REQUIRE\_REALM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_PARSE\_REQUIRE\_REALM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_PARSE_REQUIRE_REALM:KRB5_PRINCIPAL_PARSE_REQUIRE_REALM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_REQUIRE\_REALM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Error if realm is not present. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_PARSE\_REQUIRE\_REALM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_UNPARSE\_DISPLAY} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_DISPLAY:krb5-principal-unparse-display}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_DISPLAY:krb5-principal-unparse-display-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_DISPLAY::doc}}\index{KRB5\_PRINCIPAL\_UNPARSE\_DISPLAY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_UNPARSE\_DISPLAY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_DISPLAY:KRB5_PRINCIPAL_UNPARSE_DISPLAY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_UNPARSE\_DISPLAY}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Don’t escape special characters. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_UNPARSE\_DISPLAY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_UNPARSE\_NO\_REALM} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_NO_REALM:krb5-principal-unparse-no-realm}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_NO_REALM:krb5-principal-unparse-no-realm-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_NO_REALM::doc}}\index{KRB5\_PRINCIPAL\_UNPARSE\_NO\_REALM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_UNPARSE\_NO\_REALM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_NO_REALM:KRB5_PRINCIPAL_UNPARSE_NO_REALM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_UNPARSE\_NO\_REALM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Omit realm always. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_UNPARSE\_NO\_REALM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRINCIPAL\_UNPARSE\_SHORT} \label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_SHORT:krb5-principal-unparse-short}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_SHORT:krb5-principal-unparse-short-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_SHORT::doc}}\index{KRB5\_PRINCIPAL\_UNPARSE\_SHORT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRINCIPAL\_UNPARSE\_SHORT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_SHORT:KRB5_PRINCIPAL_UNPARSE_SHORT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRINCIPAL\_UNPARSE\_SHORT}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Omit realm if it is the local realm. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRINCIPAL\_UNPARSE\_SHORT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PRIV} \label{\detokenize{appdev/refs/macros/KRB5_PRIV:krb5-priv}}\label{\detokenize{appdev/refs/macros/KRB5_PRIV:krb5-priv-data}}\label{\detokenize{appdev/refs/macros/KRB5_PRIV::doc}}\index{KRB5\_PRIV (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PRIV}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PRIV:KRB5_PRIV}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PRIV}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Private application message. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PRIV}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)21)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD} \label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD:krb5-prompt-type-new-password}}\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD:krb5-prompt-type-new-password-data}}\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD::doc}}\index{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD:KRB5_PROMPT_TYPE_NEW_PASSWORD}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Prompt for new password (during password change) \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD\_AGAIN} \label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN:krb5-prompt-type-new-password-again}}\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN:krb5-prompt-type-new-password-again-data}}\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN::doc}}\index{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD\_AGAIN (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD\_AGAIN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN:KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD\_AGAIN}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Prompt for new password again. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PROMPT\_TYPE\_NEW\_PASSWORD\_AGAIN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x3}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PROMPT\_TYPE\_PASSWORD} \label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_PASSWORD:krb5-prompt-type-password}}\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_PASSWORD:krb5-prompt-type-password-data}}\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_PASSWORD::doc}}\index{KRB5\_PROMPT\_TYPE\_PASSWORD (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PROMPT\_TYPE\_PASSWORD}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_PASSWORD:KRB5_PROMPT_TYPE_PASSWORD}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PROMPT\_TYPE\_PASSWORD}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Prompt for password. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PROMPT\_TYPE\_PASSWORD}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PROMPT\_TYPE\_PREAUTH} \label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_PREAUTH:krb5-prompt-type-preauth}}\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_PREAUTH:krb5-prompt-type-preauth-data}}\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_PREAUTH::doc}}\index{KRB5\_PROMPT\_TYPE\_PREAUTH (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PROMPT\_TYPE\_PREAUTH}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PROMPT_TYPE_PREAUTH:KRB5_PROMPT_TYPE_PREAUTH}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PROMPT\_TYPE\_PREAUTH}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Prompt for preauthentication data (such as an OTP value) \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PROMPT\_TYPE\_PREAUTH}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x4}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_PVNO} \label{\detokenize{appdev/refs/macros/KRB5_PVNO:krb5-pvno}}\label{\detokenize{appdev/refs/macros/KRB5_PVNO:krb5-pvno-data}}\label{\detokenize{appdev/refs/macros/KRB5_PVNO::doc}}\index{KRB5\_PVNO (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_PVNO}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_PVNO:KRB5_PVNO}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_PVNO}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Protocol version number. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_PVNO}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{5}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_REALM\_BRANCH\_CHAR} \label{\detokenize{appdev/refs/macros/KRB5_REALM_BRANCH_CHAR:krb5-realm-branch-char}}\label{\detokenize{appdev/refs/macros/KRB5_REALM_BRANCH_CHAR:krb5-realm-branch-char-data}}\label{\detokenize{appdev/refs/macros/KRB5_REALM_BRANCH_CHAR::doc}}\index{KRB5\_REALM\_BRANCH\_CHAR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_REALM\_BRANCH\_CHAR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_REALM_BRANCH_CHAR:KRB5_REALM_BRANCH_CHAR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_REALM\_BRANCH\_CHAR}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_REALM\_BRANCH\_CHAR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{\textquotesingle{}.\textquotesingle{}}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RECVAUTH\_BADAUTHVERS} \label{\detokenize{appdev/refs/macros/KRB5_RECVAUTH_BADAUTHVERS:krb5-recvauth-badauthvers}}\label{\detokenize{appdev/refs/macros/KRB5_RECVAUTH_BADAUTHVERS:krb5-recvauth-badauthvers-data}}\label{\detokenize{appdev/refs/macros/KRB5_RECVAUTH_BADAUTHVERS::doc}}\index{KRB5\_RECVAUTH\_BADAUTHVERS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RECVAUTH\_BADAUTHVERS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RECVAUTH_BADAUTHVERS:KRB5_RECVAUTH_BADAUTHVERS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RECVAUTH\_BADAUTHVERS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RECVAUTH\_BADAUTHVERS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RECVAUTH\_SKIP\_VERSION} \label{\detokenize{appdev/refs/macros/KRB5_RECVAUTH_SKIP_VERSION:krb5-recvauth-skip-version}}\label{\detokenize{appdev/refs/macros/KRB5_RECVAUTH_SKIP_VERSION:krb5-recvauth-skip-version-data}}\label{\detokenize{appdev/refs/macros/KRB5_RECVAUTH_SKIP_VERSION::doc}}\index{KRB5\_RECVAUTH\_SKIP\_VERSION (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RECVAUTH\_SKIP\_VERSION}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RECVAUTH_SKIP_VERSION:KRB5_RECVAUTH_SKIP_VERSION}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RECVAUTH\_SKIP\_VERSION}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RECVAUTH\_SKIP\_VERSION}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_REFERRAL\_REALM} \label{\detokenize{appdev/refs/macros/KRB5_REFERRAL_REALM:krb5-referral-realm}}\label{\detokenize{appdev/refs/macros/KRB5_REFERRAL_REALM:krb5-referral-realm-data}}\label{\detokenize{appdev/refs/macros/KRB5_REFERRAL_REALM::doc}}\index{KRB5\_REFERRAL\_REALM (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_REFERRAL\_REALM}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_REFERRAL_REALM:KRB5_REFERRAL_REALM}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_REFERRAL\_REALM}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Constant for realm referrals. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_REFERRAL\_REALM}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{""}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_COUNT\_LOW} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW:krb5-responder-pkinit-flags-token-user-pin-count-low}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW:krb5-responder-pkinit-flags-token-user-pin-count-low-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW::doc}}\index{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_COUNT\_LOW (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_COUNT\_LOW}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW:KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_COUNT\_LOW}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar This flag indicates that an incorrect PIN was supplied at least once since the last time the correct PIN was supplied. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_COUNT\_LOW}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(1 \textless{}\textless{} 0)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_FINAL\_TRY} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY:krb5-responder-pkinit-flags-token-user-pin-final-try}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY:krb5-responder-pkinit-flags-token-user-pin-final-try-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY::doc}}\index{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_FINAL\_TRY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_FINAL\_TRY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY:KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_FINAL\_TRY}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar This flag indicates that supplying an incorrect PIN will cause the token to lock itself. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_FINAL\_TRY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(1 \textless{}\textless{} 1)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_LOCKED} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED:krb5-responder-pkinit-flags-token-user-pin-locked}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED:krb5-responder-pkinit-flags-token-user-pin-locked-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED::doc}}\index{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_LOCKED (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_LOCKED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED:KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_LOCKED}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar This flag indicates that the user PIN is locked, and you can’t log in to the token with it. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_USER\_PIN\_LOCKED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(1 \textless{}\textless{} 2)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_QUESTION\_PKINIT} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_PKINIT:krb5-responder-question-pkinit}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_PKINIT:krb5-responder-question-pkinit-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_PKINIT::doc}}\index{KRB5\_RESPONDER\_QUESTION\_PKINIT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_QUESTION\_PKINIT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_PKINIT:KRB5_RESPONDER_QUESTION_PKINIT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_QUESTION\_PKINIT}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar PKINIT responder question. \sphinxAtStartPar The PKINIT responder question is asked when the client needs a password that’s being used to protect key information, and is formatted as a JSON object. A specific identity’s flags value, if not zero, is the bitwise\sphinxhyphen{}OR of one or more of the KRB5\_RESPONDER\_PKINIT\_FLAGS\_TOKEN\_* flags defined below, and possibly other flags to be added later. Any resemblance to similarly\sphinxhyphen{}named CKF\_* values in the PKCS\#11 API should not be depended on. \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{\PYGZob{}} \PYG{+w}{ }\PYG{n}{identity}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{o}{\PYGZgt{}}\PYG{+w}{ }\PYG{o}{:}\PYG{+w}{ }\PYG{n}{flags}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{number}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{p}{.}\PYG{p}{.}\PYG{p}{.} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar The answer to the question MUST be JSON formatted: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{\PYGZob{}} \PYG{+w}{ }\PYG{n}{identity}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{o}{\PYGZgt{}}\PYG{+w}{ }\PYG{o}{:}\PYG{+w}{ }\PYG{n}{password}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{p}{.}\PYG{p}{.}\PYG{p}{.} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_QUESTION\_PKINIT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{"pkinit"}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_PIN} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN:krb5-responder-otp-flags-collect-pin}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN:krb5-responder-otp-flags-collect-pin-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN::doc}}\index{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_PIN (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_PIN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN:KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_PIN}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar This flag indicates that the PIN value MUST be collected. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_PIN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_TOKEN} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN:krb5-responder-otp-flags-collect-token}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN:krb5-responder-otp-flags-collect-token-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN::doc}}\index{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_TOKEN (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_TOKEN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN:KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_TOKEN}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar This flag indicates that the token value MUST be collected. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_TOKEN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_OTP\_FLAGS\_NEXTOTP} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_NEXTOTP:krb5-responder-otp-flags-nextotp}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_NEXTOTP:krb5-responder-otp-flags-nextotp-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_NEXTOTP::doc}}\index{KRB5\_RESPONDER\_OTP\_FLAGS\_NEXTOTP (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_OTP\_FLAGS\_NEXTOTP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_NEXTOTP:KRB5_RESPONDER_OTP_FLAGS_NEXTOTP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FLAGS\_NEXTOTP}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar This flag indicates that the token is now in re\sphinxhyphen{}synchronization mode with the server. \sphinxAtStartPar The user is expected to reply with the next code displayed on the token. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FLAGS\_NEXTOTP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0004}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_OTP\_FLAGS\_SEPARATE\_PIN} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN:krb5-responder-otp-flags-separate-pin}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN:krb5-responder-otp-flags-separate-pin-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN::doc}}\index{KRB5\_RESPONDER\_OTP\_FLAGS\_SEPARATE\_PIN (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_OTP\_FLAGS\_SEPARATE\_PIN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN:KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FLAGS\_SEPARATE\_PIN}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar This flag indicates that the PIN MUST be returned as a separate item. \sphinxAtStartPar This flag only takes effect if KRB5\_RESPONDER\_OTP\_FLAGS\_COLLECT\_PIN is set. If this flag is not set, the responder may either concatenate PIN + token value and store it as “value†in the answer or it may return them separately. If they are returned separately, they will be concatenated internally. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FLAGS\_SEPARATE\_PIN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0008}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_OTP\_FORMAT\_ALPHANUMERIC} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC:krb5-responder-otp-format-alphanumeric}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC:krb5-responder-otp-format-alphanumeric-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC::doc}}\index{KRB5\_RESPONDER\_OTP\_FORMAT\_ALPHANUMERIC (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_OTP\_FORMAT\_ALPHANUMERIC}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC:KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FORMAT\_ALPHANUMERIC}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FORMAT\_ALPHANUMERIC}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{2}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_OTP\_FORMAT\_DECIMAL} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_DECIMAL:krb5-responder-otp-format-decimal}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_DECIMAL:krb5-responder-otp-format-decimal-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_DECIMAL::doc}}\index{KRB5\_RESPONDER\_OTP\_FORMAT\_DECIMAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_OTP\_FORMAT\_DECIMAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_DECIMAL:KRB5_RESPONDER_OTP_FORMAT_DECIMAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FORMAT\_DECIMAL}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar These format constants identify the format of the token value. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FORMAT\_DECIMAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_OTP\_FORMAT\_HEXADECIMAL} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL:krb5-responder-otp-format-hexadecimal}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL:krb5-responder-otp-format-hexadecimal-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL::doc}}\index{KRB5\_RESPONDER\_OTP\_FORMAT\_HEXADECIMAL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_OTP\_FORMAT\_HEXADECIMAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL:KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FORMAT\_HEXADECIMAL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_OTP\_FORMAT\_HEXADECIMAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_QUESTION\_OTP} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_OTP:krb5-responder-question-otp}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_OTP:krb5-responder-question-otp-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_OTP::doc}}\index{KRB5\_RESPONDER\_QUESTION\_OTP (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_QUESTION\_OTP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_OTP:KRB5_RESPONDER_QUESTION_OTP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_QUESTION\_OTP}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar OTP responder question. \sphinxAtStartPar The OTP responder question is asked when the KDC indicates that an OTP value is required in order to complete the authentication. The JSON format of the challenge is: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{\PYGZob{}} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{service}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{+w}{ }\PYG{p}{(}\PYG{n}{optional}\PYG{p}{)}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{tokenInfo}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{p}{[} \PYG{+w}{ }\PYG{p}{\PYGZob{}} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{flags}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{number}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{vendor}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{+w}{ }\PYG{p}{(}\PYG{n}{optional}\PYG{p}{)}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{challenge}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{+w}{ }\PYG{p}{(}\PYG{n}{optional}\PYG{p}{)}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{length}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{number}\PYG{+w}{ }\PYG{p}{(}\PYG{n}{optional}\PYG{p}{)}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{format}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{number}\PYG{+w}{ }\PYG{p}{(}\PYG{n}{optional}\PYG{p}{)}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{tokenID}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{+w}{ }\PYG{p}{(}\PYG{n}{optional}\PYG{p}{)}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{algID}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{+w}{ }\PYG{p}{(}\PYG{n}{optional}\PYG{p}{)}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{p}{\PYGZcb{}}\PYG{p}{,} \PYG{+w}{ }\PYG{p}{.}\PYG{p}{.}\PYG{p}{.} \PYG{+w}{ }\PYG{p}{]} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar The answer to the question MUST be JSON formatted: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{\PYGZob{}} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{tokeninfo}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{number}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{value}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{+w}{ }\PYG{p}{(}\PYG{n}{optional}\PYG{p}{)}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{+w}{ }\PYG{l+s}{\PYGZdq{}}\PYG{l+s}{pin}\PYG{l+s}{\PYGZdq{}}\PYG{o}{:}\PYG{+w}{ }\PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{+w}{ }\PYG{p}{(}\PYG{n}{optional}\PYG{p}{)}\PYG{o}{\PYGZgt{}}\PYG{p}{,} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar For more detail, please see RFC 6560. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_QUESTION\_OTP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{"otp"}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_RESPONDER\_QUESTION\_PASSWORD} \label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_PASSWORD:krb5-responder-question-password}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_PASSWORD:krb5-responder-question-password-data}}\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_PASSWORD::doc}}\index{KRB5\_RESPONDER\_QUESTION\_PASSWORD (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_RESPONDER\_QUESTION\_PASSWORD}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_RESPONDER_QUESTION_PASSWORD:KRB5_RESPONDER_QUESTION_PASSWORD}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_RESPONDER\_QUESTION\_PASSWORD}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Long\sphinxhyphen{}term password responder question. \sphinxAtStartPar This question is asked when the long\sphinxhyphen{}term password is needed. It has no challenge and the response is simply the password string. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_RESPONDER\_QUESTION\_PASSWORD}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{"password"}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_SAFE} \label{\detokenize{appdev/refs/macros/KRB5_SAFE:krb5-safe}}\label{\detokenize{appdev/refs/macros/KRB5_SAFE:krb5-safe-data}}\label{\detokenize{appdev/refs/macros/KRB5_SAFE::doc}}\index{KRB5\_SAFE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_SAFE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_SAFE:KRB5_SAFE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_SAFE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Safe application message. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_SAFE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)20)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_SAM\_MUST\_PK\_ENCRYPT\_SAD} \label{\detokenize{appdev/refs/macros/KRB5_SAM_MUST_PK_ENCRYPT_SAD:krb5-sam-must-pk-encrypt-sad}}\label{\detokenize{appdev/refs/macros/KRB5_SAM_MUST_PK_ENCRYPT_SAD:krb5-sam-must-pk-encrypt-sad-data}}\label{\detokenize{appdev/refs/macros/KRB5_SAM_MUST_PK_ENCRYPT_SAD::doc}}\index{KRB5\_SAM\_MUST\_PK\_ENCRYPT\_SAD (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_SAM\_MUST\_PK\_ENCRYPT\_SAD}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_SAM_MUST_PK_ENCRYPT_SAD:KRB5_SAM_MUST_PK_ENCRYPT_SAD}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_SAM\_MUST\_PK\_ENCRYPT\_SAD}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar currently must be zero \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_SAM\_MUST\_PK\_ENCRYPT\_SAD}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x20000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_SAM\_SEND\_ENCRYPTED\_SAD} \label{\detokenize{appdev/refs/macros/KRB5_SAM_SEND_ENCRYPTED_SAD:krb5-sam-send-encrypted-sad}}\label{\detokenize{appdev/refs/macros/KRB5_SAM_SEND_ENCRYPTED_SAD:krb5-sam-send-encrypted-sad-data}}\label{\detokenize{appdev/refs/macros/KRB5_SAM_SEND_ENCRYPTED_SAD::doc}}\index{KRB5\_SAM\_SEND\_ENCRYPTED\_SAD (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_SAM\_SEND\_ENCRYPTED\_SAD}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_SAM_SEND_ENCRYPTED_SAD:KRB5_SAM_SEND_ENCRYPTED_SAD}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_SAM\_SEND\_ENCRYPTED\_SAD}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_SAM\_SEND\_ENCRYPTED\_SAD}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x40000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_SAM\_USE\_SAD\_AS\_KEY} \label{\detokenize{appdev/refs/macros/KRB5_SAM_USE_SAD_AS_KEY:krb5-sam-use-sad-as-key}}\label{\detokenize{appdev/refs/macros/KRB5_SAM_USE_SAD_AS_KEY:krb5-sam-use-sad-as-key-data}}\label{\detokenize{appdev/refs/macros/KRB5_SAM_USE_SAD_AS_KEY::doc}}\index{KRB5\_SAM\_USE\_SAD\_AS\_KEY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_SAM\_USE\_SAD\_AS\_KEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_SAM_USE_SAD_AS_KEY:KRB5_SAM_USE_SAD_AS_KEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_SAM\_USE\_SAD\_AS\_KEY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_SAM\_USE\_SAD\_AS\_KEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x80000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_MATCH\_2ND\_TKT} \label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_2ND_TKT:krb5-tc-match-2nd-tkt}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_2ND_TKT:krb5-tc-match-2nd-tkt-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_2ND_TKT::doc}}\index{KRB5\_TC\_MATCH\_2ND\_TKT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_MATCH\_2ND\_TKT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_2ND_TKT:KRB5_TC_MATCH_2ND_TKT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_MATCH\_2ND\_TKT}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar The second ticket must match. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_MATCH\_2ND\_TKT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000080}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_MATCH\_AUTHDATA} \label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_AUTHDATA:krb5-tc-match-authdata}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_AUTHDATA:krb5-tc-match-authdata-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_AUTHDATA::doc}}\index{KRB5\_TC\_MATCH\_AUTHDATA (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_MATCH\_AUTHDATA}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_AUTHDATA:KRB5_TC_MATCH_AUTHDATA}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_MATCH\_AUTHDATA}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar The authorization data must match. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_MATCH\_AUTHDATA}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000020}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_MATCH\_FLAGS} \label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_FLAGS:krb5-tc-match-flags}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_FLAGS:krb5-tc-match-flags-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_FLAGS::doc}}\index{KRB5\_TC\_MATCH\_FLAGS (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_MATCH\_FLAGS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_FLAGS:KRB5_TC_MATCH_FLAGS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_MATCH\_FLAGS}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar All the flags set in the match credentials must be set. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_MATCH\_FLAGS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000004}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_MATCH\_FLAGS\_EXACT} \label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_FLAGS_EXACT:krb5-tc-match-flags-exact}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_FLAGS_EXACT:krb5-tc-match-flags-exact-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_FLAGS_EXACT::doc}}\index{KRB5\_TC\_MATCH\_FLAGS\_EXACT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_MATCH\_FLAGS\_EXACT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_FLAGS_EXACT:KRB5_TC_MATCH_FLAGS_EXACT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_MATCH\_FLAGS\_EXACT}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar All the flags must match exactly. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_MATCH\_FLAGS\_EXACT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000010}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_MATCH\_IS\_SKEY} \label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_IS_SKEY:krb5-tc-match-is-skey}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_IS_SKEY:krb5-tc-match-is-skey-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_IS_SKEY::doc}}\index{KRB5\_TC\_MATCH\_IS\_SKEY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_MATCH\_IS\_SKEY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_IS_SKEY:KRB5_TC_MATCH_IS_SKEY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_MATCH\_IS\_SKEY}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar The is\_skey field must match exactly. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_MATCH\_IS\_SKEY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_MATCH\_KTYPE} \label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_KTYPE:krb5-tc-match-ktype}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_KTYPE:krb5-tc-match-ktype-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_KTYPE::doc}}\index{KRB5\_TC\_MATCH\_KTYPE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_MATCH\_KTYPE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_KTYPE:KRB5_TC_MATCH_KTYPE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_MATCH\_KTYPE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar The encryption key type must match. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_MATCH\_KTYPE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000100}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_MATCH\_SRV\_NAMEONLY} \label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_SRV_NAMEONLY:krb5-tc-match-srv-nameonly}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_SRV_NAMEONLY:krb5-tc-match-srv-nameonly-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_SRV_NAMEONLY::doc}}\index{KRB5\_TC\_MATCH\_SRV\_NAMEONLY (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_MATCH\_SRV\_NAMEONLY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_SRV_NAMEONLY:KRB5_TC_MATCH_SRV_NAMEONLY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_MATCH\_SRV\_NAMEONLY}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Only the name portion of the principal name must match. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_MATCH\_SRV\_NAMEONLY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000040}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_MATCH\_TIMES} \label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_TIMES:krb5-tc-match-times}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_TIMES:krb5-tc-match-times-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_TIMES::doc}}\index{KRB5\_TC\_MATCH\_TIMES (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_MATCH\_TIMES}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_TIMES:KRB5_TC_MATCH_TIMES}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_MATCH\_TIMES}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar The requested lifetime must be at least as great as the time specified. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_MATCH\_TIMES}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_MATCH\_TIMES\_EXACT} \label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_TIMES_EXACT:krb5-tc-match-times-exact}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_TIMES_EXACT:krb5-tc-match-times-exact-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_TIMES_EXACT::doc}}\index{KRB5\_TC\_MATCH\_TIMES\_EXACT (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_MATCH\_TIMES\_EXACT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_MATCH_TIMES_EXACT:KRB5_TC_MATCH_TIMES_EXACT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_MATCH\_TIMES\_EXACT}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar All the time fields must match exactly. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_MATCH\_TIMES\_EXACT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000008}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_NOTICKET} \label{\detokenize{appdev/refs/macros/KRB5_TC_NOTICKET:krb5-tc-noticket}}\label{\detokenize{appdev/refs/macros/KRB5_TC_NOTICKET:krb5-tc-noticket-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_NOTICKET::doc}}\index{KRB5\_TC\_NOTICKET (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_NOTICKET}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_NOTICKET:KRB5_TC_NOTICKET}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_NOTICKET}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_NOTICKET}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000002}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_OPENCLOSE} \label{\detokenize{appdev/refs/macros/KRB5_TC_OPENCLOSE:krb5-tc-openclose}}\label{\detokenize{appdev/refs/macros/KRB5_TC_OPENCLOSE:krb5-tc-openclose-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_OPENCLOSE::doc}}\index{KRB5\_TC\_OPENCLOSE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_OPENCLOSE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_OPENCLOSE:KRB5_TC_OPENCLOSE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_OPENCLOSE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Open and close the file for each cache operation. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_OPENCLOSE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TC\_SUPPORTED\_KTYPES} \label{\detokenize{appdev/refs/macros/KRB5_TC_SUPPORTED_KTYPES:krb5-tc-supported-ktypes}}\label{\detokenize{appdev/refs/macros/KRB5_TC_SUPPORTED_KTYPES:krb5-tc-supported-ktypes-data}}\label{\detokenize{appdev/refs/macros/KRB5_TC_SUPPORTED_KTYPES::doc}}\index{KRB5\_TC\_SUPPORTED\_KTYPES (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TC\_SUPPORTED\_KTYPES}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TC_SUPPORTED_KTYPES:KRB5_TC_SUPPORTED_KTYPES}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TC\_SUPPORTED\_KTYPES}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar The supported key types must match. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TC\_SUPPORTED\_KTYPES}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00000200}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TGS\_NAME} \label{\detokenize{appdev/refs/macros/KRB5_TGS_NAME:krb5-tgs-name}}\label{\detokenize{appdev/refs/macros/KRB5_TGS_NAME:krb5-tgs-name-data}}\label{\detokenize{appdev/refs/macros/KRB5_TGS_NAME::doc}}\index{KRB5\_TGS\_NAME (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TGS\_NAME}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TGS_NAME:KRB5_TGS_NAME}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TGS\_NAME}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TGS\_NAME}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{"krbtgt"}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TGS\_NAME\_SIZE} \label{\detokenize{appdev/refs/macros/KRB5_TGS_NAME_SIZE:krb5-tgs-name-size}}\label{\detokenize{appdev/refs/macros/KRB5_TGS_NAME_SIZE:krb5-tgs-name-size-data}}\label{\detokenize{appdev/refs/macros/KRB5_TGS_NAME_SIZE::doc}}\index{KRB5\_TGS\_NAME\_SIZE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TGS\_NAME\_SIZE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TGS_NAME_SIZE:KRB5_TGS_NAME_SIZE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TGS\_NAME\_SIZE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TGS\_NAME\_SIZE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{6}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TGS\_REP} \label{\detokenize{appdev/refs/macros/KRB5_TGS_REP:krb5-tgs-rep}}\label{\detokenize{appdev/refs/macros/KRB5_TGS_REP:krb5-tgs-rep-data}}\label{\detokenize{appdev/refs/macros/KRB5_TGS_REP::doc}}\index{KRB5\_TGS\_REP (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TGS\_REP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TGS_REP:KRB5_TGS_REP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TGS\_REP}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Response to TGS request. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TGS\_REP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)13)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TGS\_REQ} \label{\detokenize{appdev/refs/macros/KRB5_TGS_REQ:krb5-tgs-req}}\label{\detokenize{appdev/refs/macros/KRB5_TGS_REQ:krb5-tgs-req-data}}\label{\detokenize{appdev/refs/macros/KRB5_TGS_REQ::doc}}\index{KRB5\_TGS\_REQ (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TGS\_REQ}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TGS_REQ:KRB5_TGS_REQ}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TGS\_REQ}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Ticket granting server request. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TGS\_REQ}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((krb5\_msgtype)12)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_TKT\_CREDS\_STEP\_FLAG\_CONTINUE} \label{\detokenize{appdev/refs/macros/KRB5_TKT_CREDS_STEP_FLAG_CONTINUE:krb5-tkt-creds-step-flag-continue}}\label{\detokenize{appdev/refs/macros/KRB5_TKT_CREDS_STEP_FLAG_CONTINUE:krb5-tkt-creds-step-flag-continue-data}}\label{\detokenize{appdev/refs/macros/KRB5_TKT_CREDS_STEP_FLAG_CONTINUE::doc}}\index{KRB5\_TKT\_CREDS\_STEP\_FLAG\_CONTINUE (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_TKT\_CREDS\_STEP\_FLAG\_CONTINUE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_TKT_CREDS_STEP_FLAG_CONTINUE:KRB5_TKT_CREDS_STEP_FLAG_CONTINUE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_TKT\_CREDS\_STEP\_FLAG\_CONTINUE}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar More responses needed. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_TKT\_CREDS\_STEP\_FLAG\_CONTINUE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x1}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_VERIFY\_INIT\_CREDS\_OPT\_AP\_REQ\_NOFAIL} \label{\detokenize{appdev/refs/macros/KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL:krb5-verify-init-creds-opt-ap-req-nofail}}\label{\detokenize{appdev/refs/macros/KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL:krb5-verify-init-creds-opt-ap-req-nofail-data}}\label{\detokenize{appdev/refs/macros/KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL::doc}}\index{KRB5\_VERIFY\_INIT\_CREDS\_OPT\_AP\_REQ\_NOFAIL (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_VERIFY\_INIT\_CREDS\_OPT\_AP\_REQ\_NOFAIL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL:KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_VERIFY\_INIT\_CREDS\_OPT\_AP\_REQ\_NOFAIL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_VERIFY\_INIT\_CREDS\_OPT\_AP\_REQ\_NOFAIL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x0001}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{KRB5\_WELLKNOWN\_NAMESTR} \label{\detokenize{appdev/refs/macros/KRB5_WELLKNOWN_NAMESTR:krb5-wellknown-namestr}}\label{\detokenize{appdev/refs/macros/KRB5_WELLKNOWN_NAMESTR:krb5-wellknown-namestr-data}}\label{\detokenize{appdev/refs/macros/KRB5_WELLKNOWN_NAMESTR::doc}}\index{KRB5\_WELLKNOWN\_NAMESTR (built\sphinxhyphen{}in variable)@\spxentry{KRB5\_WELLKNOWN\_NAMESTR}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/KRB5_WELLKNOWN_NAMESTR:KRB5_WELLKNOWN_NAMESTR}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{KRB5\_WELLKNOWN\_NAMESTR}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar First component of NT\_WELLKNOWN principals. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{KRB5\_WELLKNOWN\_NAMESTR}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{"WELLKNOWN"}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{LR\_TYPE\_INTERPRETATION\_MASK} \label{\detokenize{appdev/refs/macros/LR_TYPE_INTERPRETATION_MASK:lr-type-interpretation-mask}}\label{\detokenize{appdev/refs/macros/LR_TYPE_INTERPRETATION_MASK:lr-type-interpretation-mask-data}}\label{\detokenize{appdev/refs/macros/LR_TYPE_INTERPRETATION_MASK::doc}}\index{LR\_TYPE\_INTERPRETATION\_MASK (built\sphinxhyphen{}in variable)@\spxentry{LR\_TYPE\_INTERPRETATION\_MASK}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/LR_TYPE_INTERPRETATION_MASK:LR_TYPE_INTERPRETATION_MASK}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{LR\_TYPE\_INTERPRETATION\_MASK}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{LR\_TYPE\_INTERPRETATION\_MASK}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x7fff}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{LR\_TYPE\_THIS\_SERVER\_ONLY} \label{\detokenize{appdev/refs/macros/LR_TYPE_THIS_SERVER_ONLY:lr-type-this-server-only}}\label{\detokenize{appdev/refs/macros/LR_TYPE_THIS_SERVER_ONLY:lr-type-this-server-only-data}}\label{\detokenize{appdev/refs/macros/LR_TYPE_THIS_SERVER_ONLY::doc}}\index{LR\_TYPE\_THIS\_SERVER\_ONLY (built\sphinxhyphen{}in variable)@\spxentry{LR\_TYPE\_THIS\_SERVER\_ONLY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/LR_TYPE_THIS_SERVER_ONLY:LR_TYPE_THIS_SERVER_ONLY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{LR\_TYPE\_THIS\_SERVER\_ONLY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{LR\_TYPE\_THIS\_SERVER\_ONLY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x8000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{MAX\_KEYTAB\_NAME\_LEN} \label{\detokenize{appdev/refs/macros/MAX_KEYTAB_NAME_LEN:max-keytab-name-len}}\label{\detokenize{appdev/refs/macros/MAX_KEYTAB_NAME_LEN:max-keytab-name-len-data}}\label{\detokenize{appdev/refs/macros/MAX_KEYTAB_NAME_LEN::doc}}\index{MAX\_KEYTAB\_NAME\_LEN (built\sphinxhyphen{}in variable)@\spxentry{MAX\_KEYTAB\_NAME\_LEN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/MAX_KEYTAB_NAME_LEN:MAX_KEYTAB_NAME_LEN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{MAX\_KEYTAB\_NAME\_LEN}}} \pysigstopsignatures \end{fulllineitems} \sphinxAtStartPar Long enough for MAXPATHLEN + some extra. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{MAX\_KEYTAB\_NAME\_LEN}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{1100}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{MSEC\_DIRBIT} \label{\detokenize{appdev/refs/macros/MSEC_DIRBIT:msec-dirbit}}\label{\detokenize{appdev/refs/macros/MSEC_DIRBIT:msec-dirbit-data}}\label{\detokenize{appdev/refs/macros/MSEC_DIRBIT::doc}}\index{MSEC\_DIRBIT (built\sphinxhyphen{}in variable)@\spxentry{MSEC\_DIRBIT}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/MSEC_DIRBIT:MSEC_DIRBIT}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{MSEC\_DIRBIT}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{MSEC\_DIRBIT}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x8000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{MSEC\_VAL\_MASK} \label{\detokenize{appdev/refs/macros/MSEC_VAL_MASK:msec-val-mask}}\label{\detokenize{appdev/refs/macros/MSEC_VAL_MASK:msec-val-mask-data}}\label{\detokenize{appdev/refs/macros/MSEC_VAL_MASK::doc}}\index{MSEC\_VAL\_MASK (built\sphinxhyphen{}in variable)@\spxentry{MSEC\_VAL\_MASK}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/MSEC_VAL_MASK:MSEC_VAL_MASK}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{MSEC\_VAL\_MASK}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{MSEC\_VAL\_MASK}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x7fff}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{SALT\_TYPE\_AFS\_LENGTH} \label{\detokenize{appdev/refs/macros/SALT_TYPE_AFS_LENGTH:salt-type-afs-length}}\label{\detokenize{appdev/refs/macros/SALT_TYPE_AFS_LENGTH:salt-type-afs-length-data}}\label{\detokenize{appdev/refs/macros/SALT_TYPE_AFS_LENGTH::doc}}\index{SALT\_TYPE\_AFS\_LENGTH (built\sphinxhyphen{}in variable)@\spxentry{SALT\_TYPE\_AFS\_LENGTH}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/SALT_TYPE_AFS_LENGTH:SALT_TYPE_AFS_LENGTH}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{SALT\_TYPE\_AFS\_LENGTH}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{SALT\_TYPE\_AFS\_LENGTH}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{UINT\_MAX}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{SALT\_TYPE\_NO\_LENGTH} \label{\detokenize{appdev/refs/macros/SALT_TYPE_NO_LENGTH:salt-type-no-length}}\label{\detokenize{appdev/refs/macros/SALT_TYPE_NO_LENGTH:salt-type-no-length-data}}\label{\detokenize{appdev/refs/macros/SALT_TYPE_NO_LENGTH::doc}}\index{SALT\_TYPE\_NO\_LENGTH (built\sphinxhyphen{}in variable)@\spxentry{SALT\_TYPE\_NO\_LENGTH}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/SALT_TYPE_NO_LENGTH:SALT_TYPE_NO_LENGTH}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{SALT\_TYPE\_NO\_LENGTH}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{SALT\_TYPE\_NO\_LENGTH}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{UINT\_MAX}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{THREEPARAMOPEN} \label{\detokenize{appdev/refs/macros/THREEPARAMOPEN:threeparamopen}}\label{\detokenize{appdev/refs/macros/THREEPARAMOPEN:threeparamopen-data}}\label{\detokenize{appdev/refs/macros/THREEPARAMOPEN::doc}}\index{THREEPARAMOPEN (built\sphinxhyphen{}in variable)@\spxentry{THREEPARAMOPEN}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/THREEPARAMOPEN:THREEPARAMOPEN}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{THREEPARAMOPEN}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{THREEPARAMOPEN (x, y, z)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{open(x,y,z)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_ANONYMOUS} \label{\detokenize{appdev/refs/macros/TKT_FLG_ANONYMOUS:tkt-flg-anonymous}}\label{\detokenize{appdev/refs/macros/TKT_FLG_ANONYMOUS:tkt-flg-anonymous-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_ANONYMOUS::doc}}\index{TKT\_FLG\_ANONYMOUS (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_ANONYMOUS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_ANONYMOUS:TKT_FLG_ANONYMOUS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_ANONYMOUS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_ANONYMOUS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00008000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_ENC\_PA\_REP} \label{\detokenize{appdev/refs/macros/TKT_FLG_ENC_PA_REP:tkt-flg-enc-pa-rep}}\label{\detokenize{appdev/refs/macros/TKT_FLG_ENC_PA_REP:tkt-flg-enc-pa-rep-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_ENC_PA_REP::doc}}\index{TKT\_FLG\_ENC\_PA\_REP (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_ENC\_PA\_REP}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_ENC_PA_REP:TKT_FLG_ENC_PA_REP}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_ENC\_PA\_REP}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_ENC\_PA\_REP}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00010000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_FORWARDABLE} \label{\detokenize{appdev/refs/macros/TKT_FLG_FORWARDABLE:tkt-flg-forwardable}}\label{\detokenize{appdev/refs/macros/TKT_FLG_FORWARDABLE:tkt-flg-forwardable-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_FORWARDABLE::doc}}\index{TKT\_FLG\_FORWARDABLE (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_FORWARDABLE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_FORWARDABLE:TKT_FLG_FORWARDABLE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_FORWARDABLE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_FORWARDABLE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x40000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_FORWARDED} \label{\detokenize{appdev/refs/macros/TKT_FLG_FORWARDED:tkt-flg-forwarded}}\label{\detokenize{appdev/refs/macros/TKT_FLG_FORWARDED:tkt-flg-forwarded-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_FORWARDED::doc}}\index{TKT\_FLG\_FORWARDED (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_FORWARDED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_FORWARDED:TKT_FLG_FORWARDED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_FORWARDED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_FORWARDED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x20000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_HW\_AUTH} \label{\detokenize{appdev/refs/macros/TKT_FLG_HW_AUTH:tkt-flg-hw-auth}}\label{\detokenize{appdev/refs/macros/TKT_FLG_HW_AUTH:tkt-flg-hw-auth-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_HW_AUTH::doc}}\index{TKT\_FLG\_HW\_AUTH (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_HW\_AUTH}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_HW_AUTH:TKT_FLG_HW_AUTH}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_HW\_AUTH}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_HW\_AUTH}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00100000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_INITIAL} \label{\detokenize{appdev/refs/macros/TKT_FLG_INITIAL:tkt-flg-initial}}\label{\detokenize{appdev/refs/macros/TKT_FLG_INITIAL:tkt-flg-initial-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_INITIAL::doc}}\index{TKT\_FLG\_INITIAL (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_INITIAL}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_INITIAL:TKT_FLG_INITIAL}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_INITIAL}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_INITIAL}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00400000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_INVALID} \label{\detokenize{appdev/refs/macros/TKT_FLG_INVALID:tkt-flg-invalid}}\label{\detokenize{appdev/refs/macros/TKT_FLG_INVALID:tkt-flg-invalid-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_INVALID::doc}}\index{TKT\_FLG\_INVALID (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_INVALID}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_INVALID:TKT_FLG_INVALID}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_INVALID}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_INVALID}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x01000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_MAY\_POSTDATE} \label{\detokenize{appdev/refs/macros/TKT_FLG_MAY_POSTDATE:tkt-flg-may-postdate}}\label{\detokenize{appdev/refs/macros/TKT_FLG_MAY_POSTDATE:tkt-flg-may-postdate-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_MAY_POSTDATE::doc}}\index{TKT\_FLG\_MAY\_POSTDATE (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_MAY\_POSTDATE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_MAY_POSTDATE:TKT_FLG_MAY_POSTDATE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_MAY\_POSTDATE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_MAY\_POSTDATE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x04000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_OK\_AS\_DELEGATE} \label{\detokenize{appdev/refs/macros/TKT_FLG_OK_AS_DELEGATE:tkt-flg-ok-as-delegate}}\label{\detokenize{appdev/refs/macros/TKT_FLG_OK_AS_DELEGATE:tkt-flg-ok-as-delegate-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_OK_AS_DELEGATE::doc}}\index{TKT\_FLG\_OK\_AS\_DELEGATE (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_OK\_AS\_DELEGATE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_OK_AS_DELEGATE:TKT_FLG_OK_AS_DELEGATE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_OK\_AS\_DELEGATE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_OK\_AS\_DELEGATE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00040000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_POSTDATED} \label{\detokenize{appdev/refs/macros/TKT_FLG_POSTDATED:tkt-flg-postdated}}\label{\detokenize{appdev/refs/macros/TKT_FLG_POSTDATED:tkt-flg-postdated-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_POSTDATED::doc}}\index{TKT\_FLG\_POSTDATED (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_POSTDATED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_POSTDATED:TKT_FLG_POSTDATED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_POSTDATED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_POSTDATED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x02000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_PRE\_AUTH} \label{\detokenize{appdev/refs/macros/TKT_FLG_PRE_AUTH:tkt-flg-pre-auth}}\label{\detokenize{appdev/refs/macros/TKT_FLG_PRE_AUTH:tkt-flg-pre-auth-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_PRE_AUTH::doc}}\index{TKT\_FLG\_PRE\_AUTH (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_PRE\_AUTH}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_PRE_AUTH:TKT_FLG_PRE_AUTH}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_PRE\_AUTH}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_PRE\_AUTH}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00200000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_PROXIABLE} \label{\detokenize{appdev/refs/macros/TKT_FLG_PROXIABLE:tkt-flg-proxiable}}\label{\detokenize{appdev/refs/macros/TKT_FLG_PROXIABLE:tkt-flg-proxiable-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_PROXIABLE::doc}}\index{TKT\_FLG\_PROXIABLE (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_PROXIABLE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_PROXIABLE:TKT_FLG_PROXIABLE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_PROXIABLE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_PROXIABLE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x10000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_PROXY} \label{\detokenize{appdev/refs/macros/TKT_FLG_PROXY:tkt-flg-proxy}}\label{\detokenize{appdev/refs/macros/TKT_FLG_PROXY:tkt-flg-proxy-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_PROXY::doc}}\index{TKT\_FLG\_PROXY (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_PROXY}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_PROXY:TKT_FLG_PROXY}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_PROXY}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_PROXY}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x08000000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_RENEWABLE} \label{\detokenize{appdev/refs/macros/TKT_FLG_RENEWABLE:tkt-flg-renewable}}\label{\detokenize{appdev/refs/macros/TKT_FLG_RENEWABLE:tkt-flg-renewable-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_RENEWABLE::doc}}\index{TKT\_FLG\_RENEWABLE (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_RENEWABLE}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_RENEWABLE:TKT_FLG_RENEWABLE}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_RENEWABLE}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_RENEWABLE}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00800000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{TKT\_FLG\_TRANSIT\_POLICY\_CHECKED} \label{\detokenize{appdev/refs/macros/TKT_FLG_TRANSIT_POLICY_CHECKED:tkt-flg-transit-policy-checked}}\label{\detokenize{appdev/refs/macros/TKT_FLG_TRANSIT_POLICY_CHECKED:tkt-flg-transit-policy-checked-data}}\label{\detokenize{appdev/refs/macros/TKT_FLG_TRANSIT_POLICY_CHECKED::doc}}\index{TKT\_FLG\_TRANSIT\_POLICY\_CHECKED (built\sphinxhyphen{}in variable)@\spxentry{TKT\_FLG\_TRANSIT\_POLICY\_CHECKED}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/TKT_FLG_TRANSIT_POLICY_CHECKED:TKT_FLG_TRANSIT_POLICY_CHECKED}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{TKT\_FLG\_TRANSIT\_POLICY\_CHECKED}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{TKT\_FLG\_TRANSIT\_POLICY\_CHECKED}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{0x00080000}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{VALID\_INT\_BITS} \label{\detokenize{appdev/refs/macros/VALID_INT_BITS:valid-int-bits}}\label{\detokenize{appdev/refs/macros/VALID_INT_BITS:valid-int-bits-data}}\label{\detokenize{appdev/refs/macros/VALID_INT_BITS::doc}}\index{VALID\_INT\_BITS (built\sphinxhyphen{}in variable)@\spxentry{VALID\_INT\_BITS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/VALID_INT_BITS:VALID_INT_BITS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{VALID\_INT\_BITS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{VALID\_INT\_BITS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{INT\_MAX}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{VALID\_UINT\_BITS} \label{\detokenize{appdev/refs/macros/VALID_UINT_BITS:valid-uint-bits}}\label{\detokenize{appdev/refs/macros/VALID_UINT_BITS:valid-uint-bits-data}}\label{\detokenize{appdev/refs/macros/VALID_UINT_BITS::doc}}\index{VALID\_UINT\_BITS (built\sphinxhyphen{}in variable)@\spxentry{VALID\_UINT\_BITS}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/VALID_UINT_BITS:VALID_UINT_BITS}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{VALID\_UINT\_BITS}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{VALID\_UINT\_BITS}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{UINT\_MAX}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_const} \label{\detokenize{appdev/refs/macros/krb5_const:krb5-const}}\label{\detokenize{appdev/refs/macros/krb5_const:krb5-const-data}}\label{\detokenize{appdev/refs/macros/krb5_const::doc}}\index{krb5\_const (built\sphinxhyphen{}in variable)@\spxentry{krb5\_const}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_const:krb5_const}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_const}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_const}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{const}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_princ\_component} \label{\detokenize{appdev/refs/macros/krb5_princ_component:krb5-princ-component}}\label{\detokenize{appdev/refs/macros/krb5_princ_component:krb5-princ-component-data}}\label{\detokenize{appdev/refs/macros/krb5_princ_component::doc}}\index{krb5\_princ\_component (built\sphinxhyphen{}in variable)@\spxentry{krb5\_princ\_component}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_princ_component:krb5_princ_component}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_princ\_component}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_princ\_component (context, princ, i)}} & \sphinxAtStartPar \textasciigrave{}\textasciigrave{} (((i) \textless{} krb5\_princ\_size(context, princ)) ? (princ)\sphinxhyphen{}\textgreater{}data + (i) : NULL)\textasciigrave{}\textasciigrave{} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_princ\_name} \label{\detokenize{appdev/refs/macros/krb5_princ_name:krb5-princ-name}}\label{\detokenize{appdev/refs/macros/krb5_princ_name:krb5-princ-name-data}}\label{\detokenize{appdev/refs/macros/krb5_princ_name::doc}}\index{krb5\_princ\_name (built\sphinxhyphen{}in variable)@\spxentry{krb5\_princ\_name}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_princ_name:krb5_princ_name}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_princ\_name}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_princ\_name (context, princ)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(princ)\sphinxhyphen{}\textgreater{}data}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_princ\_realm} \label{\detokenize{appdev/refs/macros/krb5_princ_realm:krb5-princ-realm}}\label{\detokenize{appdev/refs/macros/krb5_princ_realm:krb5-princ-realm-data}}\label{\detokenize{appdev/refs/macros/krb5_princ_realm::doc}}\index{krb5\_princ\_realm (built\sphinxhyphen{}in variable)@\spxentry{krb5\_princ\_realm}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_princ_realm:krb5_princ_realm}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_princ\_realm}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_princ\_realm (context, princ)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(\&(princ)\sphinxhyphen{}\textgreater{}realm)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_princ\_set\_realm} \label{\detokenize{appdev/refs/macros/krb5_princ_set_realm:krb5-princ-set-realm}}\label{\detokenize{appdev/refs/macros/krb5_princ_set_realm:krb5-princ-set-realm-data}}\label{\detokenize{appdev/refs/macros/krb5_princ_set_realm::doc}}\index{krb5\_princ\_set\_realm (built\sphinxhyphen{}in variable)@\spxentry{krb5\_princ\_set\_realm}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_princ_set_realm:krb5_princ_set_realm}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_princ\_set\_realm}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_princ\_set\_realm (context, princ, value)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((princ)\sphinxhyphen{}\textgreater{}realm = *(value))}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_princ\_set\_realm\_data} \label{\detokenize{appdev/refs/macros/krb5_princ_set_realm_data:krb5-princ-set-realm-data}}\label{\detokenize{appdev/refs/macros/krb5_princ_set_realm_data:krb5-princ-set-realm-data-data}}\label{\detokenize{appdev/refs/macros/krb5_princ_set_realm_data::doc}}\index{krb5\_princ\_set\_realm\_data (built\sphinxhyphen{}in variable)@\spxentry{krb5\_princ\_set\_realm\_data}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_princ_set_realm_data:krb5_princ_set_realm_data}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_princ\_set\_realm\_data}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_princ\_set\_realm\_data (context, princ, value)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(princ)\sphinxhyphen{}\textgreater{}realm.data = (value)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_princ\_set\_realm\_length} \label{\detokenize{appdev/refs/macros/krb5_princ_set_realm_length:krb5-princ-set-realm-length}}\label{\detokenize{appdev/refs/macros/krb5_princ_set_realm_length:krb5-princ-set-realm-length-data}}\label{\detokenize{appdev/refs/macros/krb5_princ_set_realm_length::doc}}\index{krb5\_princ\_set\_realm\_length (built\sphinxhyphen{}in variable)@\spxentry{krb5\_princ\_set\_realm\_length}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_princ_set_realm_length:krb5_princ_set_realm_length}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_princ\_set\_realm\_length}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_princ\_set\_realm\_length (context, princ, value)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(princ)\sphinxhyphen{}\textgreater{}realm.length = (value)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_princ\_size} \label{\detokenize{appdev/refs/macros/krb5_princ_size:krb5-princ-size}}\label{\detokenize{appdev/refs/macros/krb5_princ_size:krb5-princ-size-data}}\label{\detokenize{appdev/refs/macros/krb5_princ_size::doc}}\index{krb5\_princ\_size (built\sphinxhyphen{}in variable)@\spxentry{krb5\_princ\_size}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_princ_size:krb5_princ_size}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_princ\_size}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_princ\_size (context, princ)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(princ)\sphinxhyphen{}\textgreater{}length}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_princ\_type} \label{\detokenize{appdev/refs/macros/krb5_princ_type:krb5-princ-type}}\label{\detokenize{appdev/refs/macros/krb5_princ_type:krb5-princ-type-data}}\label{\detokenize{appdev/refs/macros/krb5_princ_type::doc}}\index{krb5\_princ\_type (built\sphinxhyphen{}in variable)@\spxentry{krb5\_princ\_type}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_princ_type:krb5_princ_type}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_princ\_type}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_princ\_type (context, princ)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(princ)\sphinxhyphen{}\textgreater{}type}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_roundup} \label{\detokenize{appdev/refs/macros/krb5_roundup:krb5-roundup}}\label{\detokenize{appdev/refs/macros/krb5_roundup:krb5-roundup-data}}\label{\detokenize{appdev/refs/macros/krb5_roundup::doc}}\index{krb5\_roundup (built\sphinxhyphen{}in variable)@\spxentry{krb5\_roundup}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_roundup:krb5_roundup}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_roundup}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_roundup (x, y)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((((x) + (y) \sphinxhyphen{} 1)/(y))*(y))}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_x} \label{\detokenize{appdev/refs/macros/krb5_x:krb5-x}}\label{\detokenize{appdev/refs/macros/krb5_x:krb5-x-data}}\label{\detokenize{appdev/refs/macros/krb5_x::doc}}\index{krb5\_x (built\sphinxhyphen{}in variable)@\spxentry{krb5\_x}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_x:krb5_x}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_x}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_x (ptr, args)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((ptr)?((*(ptr)) args):(abort(),1))}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb5\_xc} \label{\detokenize{appdev/refs/macros/krb5_xc:krb5-xc}}\label{\detokenize{appdev/refs/macros/krb5_xc:krb5-xc-data}}\label{\detokenize{appdev/refs/macros/krb5_xc::doc}}\index{krb5\_xc (built\sphinxhyphen{}in variable)@\spxentry{krb5\_xc}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb5_xc:krb5_xc}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb5\_xc}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_xc (ptr, args)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{((ptr)?((*(ptr)) args):(abort(),(char*)0))}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \subsection{Deprecated macros} \label{\detokenize{appdev/refs/macros/index:deprecated-macros}} \sphinxstepscope \subsubsection{krb524\_convert\_creds\_kdc} \label{\detokenize{appdev/refs/macros/krb524_convert_creds_kdc:krb524-convert-creds-kdc}}\label{\detokenize{appdev/refs/macros/krb524_convert_creds_kdc:krb524-convert-creds-kdc-data}}\label{\detokenize{appdev/refs/macros/krb524_convert_creds_kdc::doc}}\index{krb524\_convert\_creds\_kdc (built\sphinxhyphen{}in variable)@\spxentry{krb524\_convert\_creds\_kdc}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb524_convert_creds_kdc:krb524_convert_creds_kdc}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb524\_convert\_creds\_kdc}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb524\_convert\_creds\_kdc}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb5\_524\_convert\_creds}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxstepscope \subsubsection{krb524\_init\_ets} \label{\detokenize{appdev/refs/macros/krb524_init_ets:krb524-init-ets}}\label{\detokenize{appdev/refs/macros/krb524_init_ets:krb524-init-ets-data}}\label{\detokenize{appdev/refs/macros/krb524_init_ets::doc}}\index{krb524\_init\_ets (built\sphinxhyphen{}in variable)@\spxentry{krb524\_init\_ets}\spxextra{built\sphinxhyphen{}in variable}} \begin{fulllineitems} \phantomsection\label{\detokenize{appdev/refs/macros/krb524_init_ets:krb524_init_ets}} \pysigstartsignatures \pysigline{\sphinxbfcode{\sphinxupquote{krb524\_init\_ets}}} \pysigstopsignatures \end{fulllineitems} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \sphinxcode{\sphinxupquote{krb524\_init\_ets (x)}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{(0)}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \renewcommand{\indexname}{Index} \printindex \end{document}krb5-1.22.1/doc/pdf/basic.pdf0000664000175000017500000055250515051422766015460 0ustar ghudsonghudson%PDF-1.5 %ÐÔÅØ 1 0 obj << /Length 843 /Filter /FlateDecode >> stream xÚmUMoâ0½çWx•ÚÅNÈW…œ„H¶­ Zí•&¦‹Tàп~3Ú®öz¿™yóœ87?ž×Ûö¯nÝkõâNýehܤü¹=77Uß\®;?:׺vÜ==¨ç¡oÖî¬nËUµêöç;O^uÍû¥u#ëÿ¤Â½í»O ú¨Ûû=Ù˜‰a³?¿ûkLy 6FÑæ/7œö}÷ Ì½ÖÚ–][öH<Si£¦cãݾké¥^Ñ90¡j÷ÍYVôßü¬H^œÎî°êv}0Ÿ«é‹ß<‡ÒrLŸ†Ö ûîͯ_®/Çã»Ck¥ƒÅBµnç«øy·§¦Wý×øæãèTHkÃý›¾u§ã¶qö{sÁ\ë…š×õ"p]ûϞќòº¹KÏÕµÿ u”/‚¹A² )`JbD>`´öØ2ãš™$`¤TY'`”(ZqŠÇÁ¼BJÅŒ )KÒÌŒ%553<Æ,£è(‡hþl™×wBš6„‹0¦Ða™G„+L¤gıè«cŽWÀ c œrn œqœø9çÖÀ–ã°MÜ—8%Ç àŠCMq.â†5„Sâhr›ê›®®AƒáúI‚Öå皎­ú\SåþÈ©¿ÇÀ á]8 é`Y‡7ÑŒ1OÊyeäµñÖzlÃë,d mYĸ”S£SJfß-›1i‰:C&e c4ÎRÆÄÉØˆËÄ$D&™ Ë Æ&+ü¬bLõÉãaÉjÆ çÁbôÍy°üœ£‡+çÁbèÉYB¹ü‘þœõ§Ägý ñYJõYŠYrÖŸb–œõ§x(rÖÁèœõGT“õÌ›ËÁ`F+ƒÙ­L ,C9ô²â?d+þ£¯ÿ¡ÍŠÿÄÿ1£ÿ1—ÿ¡ÓŠÿðÄŠÿ˜×ŠÿT_ü‡~+þCg!þ£o!þƒ_ˆÿàâ?ôâ?åŠÿÄÿ‰/þ?ã«„°øY ñ³â?^ŒBü‡Ÿ¿\–jò‹UPñœŠ{Åð¡âxᇻLöó^U}9pQãóq½÷›Ë0øO}cèÖÇ}¿ïÜõ3tìÈ¢}¿Æ!VOuðÊñË· endstream endobj 81 0 obj << /Length 586 /Filter /FlateDecode >> stream xÚmTËŽâ0¼ç+¼$æÀà$0Š ‰Ã£­ö ‰a#A%áÀ߯«›ÀÌjDÕå²»«ífðãc;ZæÕÁŽÌ«Ÿ¶­®MfGÑÏ}í q•]/¶ìÞ­ÍmÞ¯¶o⣩²­íÄ0ZÇë²è^œx]fçkn{ÕÿE+{*ʧyÄpg6;5’PìŠîìVž¤pH8$hù—mÚ¢*ß„z•R:")󨺠ÊÖß3‰qŸûX”ysO'Hî)-ò"ëî}³‹³‹ÍÛ[ÛÙ˺s á3 4†{´¢p¿YôdšrýØëKæ‘+ˆ™ÇÞ a }ÀõàíÑ« W€‡Œ{ Fvm734…4˜‡¢´A­«»èGÞÿc Ú¤Þ_86 endstream endobj 82 0 obj << /Length 770 /Filter /FlateDecode >> stream xÚmUËn£0ÝóžE¥Î"±y$UÉ6 É¢5Õh¶)8¤"’,ú÷ãc\W³Ýsß/.7?ž·3ÑôozÆï(yѧþ2Ôz¦vÇèæ¦èëËAwçG­ÝŒÒÓ=yúz«ÏäVmŠMמåMW\=jý_Iê÷¶ó*ˆCn_õŸÙÃfö ¯íùÃ&1yØ+ü­‡SÛw÷$¾£”FÙ5ª? ÅS4¿†!ó1ð¾íšá‹¼!r3Ò´õùŠì»>˜Za¼ý<õaÓíûhµ"ó#<‡O›ËÏhþ44zh»wrû°1p{9?4B“4Z¯I£÷Æ‹©çqwÐd>å?ñ¯É»Ü=ûõó¨‰Ã±K«î}:îj=ìºw­(]“UU­#Ý5ßd¦kò¶u¥Ñ¥¥y že¥ÖÑ*†ƒx12+ƒ¹Sx¦æ,öÌÒ09Ì9Ô)5t´J N¦Š'†™™{fSÉ –2Œ¬Rà̼   KÙÀÒV i‰X¤¤†BÆRs>–^ÿÝ ×.¹¢KäCc†2—ÀÜc4‰&WÀ©o"²¦™ÇÖîq¼ð8^zlã p5u%†=c¾K(œq/‡?–xŒQ±Ôcøc™·/€s/G|¶°£•¨•-mõ„¥•鯝P/S8+8èÂÑ 4fÁR§SYZ"?.ì‚0»1Òшŕ[KŽþòÒñ­¾õÃúPKS6Ò×0ÃÔæ—eÈ;Uކ}Z8~S›gÈ;­ _™õÇàg®v»ói;K¹æÊcÄÌ g‡ÝÌ­oZ ÞÜú¦ ú¶ø’'ü êê„LÄá^ î¥àá^Š$ÜK‘†{)²p/Eî¥X„{)–á^ î¥(½ߎ‡¨> stream xÚmVMoÛ8¼ûWhÒCj~H”\HÉrhSÔÁb¯ŽÄd IJ!Û‡üûÕ¼±Ã¢ØƒõøÞ¼!9ÔÝ_?7¾?¼ÄûUe¿âép»øPßgwwÍ¡»ìãpþcûÛÛÓ·ìçxè6ñœÝ×Íã°;™‚‡îýÒÇ[Ôÿ…ø¶Rêd÷ÏñŸ‡§ï›…ˆçÝù}z“³ eÊäõßq<í÷LUJM롯{°<Íæ×JÙüVûu7ôãµ\ö‚â3m²~ׯOòßí§v1yóq:Çýãðz˜-—Ùü×ôòt?„Í—Ùüiìã¸Þ²û‰Ïô¼¹ïµ35[­²>¾Ni¦ž~l÷1›§>_\é“}~þ8ÆÌȳ&±îÐÇÓqÛÅq;¼ÅÙR©U¶lÛÕ,ýï g¼¼^Cs=…~úk*[4õ¢^Í–¥™žåO×mT·I:/nYº·ãµž1ÚLs*J`#¸lœ ne¼ÀÜ¢ì8W—Ìi+Á‹xAì€=±Ì ÄpM¼n˜?¯™SbZbÄhòÏ`-؃6‚+ÔÒ–µtΘ¸ 7 þÆûXøû €ÉßB[Mþ98hò¯ ›&ÿ ýjòwÐJ7Äà¯É¿”qò/1n„¿^ –ÑÄÈi 1z1–ùMN þ¦ F_ƃ›¡þ¹Ä ÝHþ±ä÷Ä’?K|M,ù愆fý[þ«þÐÜ e‘ÓRÿ©Õ S…xKýúµÂ¿¨e¹‚ä‘ýc­Ä íQ×Rþ–ú+™ëe¿y¬‹¥þ ëhÉ_Ë8ùkôh©¿G_–ü=âsêoSsƒ¹9µµ¨›S[‹<9õ”^rê©%æZ:ä¬kÁ³`Nø‚<åÜ'{¸à>© [AžkZ§&ŽûÜ#¿£Îùä· 9%F-—ËÜ‚µÏ©ì=WC'}•k‰_K—óRV³ᯌÔõÄèQàV ç$¾!–6n/xzjgÿu › endstream endobj 84 0 obj << /Length 1026 /Filter /FlateDecode >> stream xÚm–KoÛ0 ÇïþÞ¡@wÈbK²EÉ ‡=°î©­v;p’C¿ýLÒ2­b‡ü™z”é¿n>ý|ܘnxvù%‰¹óp[·)¿íOÑÍM5´×£ë/ßë\ç½ç¯ñÏqhÝ%¾-ª‡þpù< ~èÛ·kçü¨ÿ²îõÐóØ'¾}r6ßê?›F<.o“‡Æ“OVŒîßn<†þkœ~I1=¨û®Žå9ÚÎ;Å[¿÷Ë¡ïÆy»ø6Rw‡ö2þ·Ç)]˜üø~¾¸ãCÿ2Dwwñö×ä<_ÆwŒæs´ý1vn<ô¯ñíÏÄ×ÓéÍÁÞqÝßÇ{™–™rú¾?ºxË),Ž9|Šž?½Ÿ\LœR`íйóiߺqß¿ºè.Iî㻦¹\ß}𥹢9Ï/íßý8Öß5õdNœžrf=KâʳšXÈÄxΈ—ñ9ñ²¾&^Ößázz_/ë¯ëe¾%^æ—ÀI%À®Ð®s°k°‹f™×ûyé*ïx•7²`?¬Jö#+® rÆuAι.Ț낼㺠\dÃuA¶\är® ØÕ\°Wyã¸UÞÀb•·^å¼:oäÕy#¯ÎyuÞÈ«óF^7ò꼑Wçl8/a9/Qr^8®â¼WyÃù‰†Þ…lf™`…;%»[ mpŒ$[MyX[RŽÞ+Iù¨¥¤ÜL6§Ñ`ÓYÜË 9HKvvI6ä)+²K°k² Ø Ù§šã‡¹Šâ7ð+Š¿€¹Šâ/°×Qe\G…ñ›$Ÿû@if¨Â<„¨½¿`F¿¡ñ‰÷[fô—Ä©÷WÌ诉…÷7ÌàÏ0O‘úùæ*’Ƴ xü÷"ÜE)=+b¿~–ÑúÊsN~¦‰—ýv¼?ÆSðþȆ÷G¶¼?rÉû#W¼?rÍû#7¼?p>çïãËSfôcÊ¥~¹dF¿b†w4ψ}}òœÇkf¿ãþGÁýl¸ÿ‘-÷?rÉý\qÿ#×ÜÿÈ ÷?°žó÷z¢Sfô fˆWKfèUM}k¡5õ­…ÐsßBohÍ:¡çï0οÁÐÿšò¬ ÷4}{ÆCùU¸NµzŽçšVcC6¬¹û ¯&á9&ýà¡öj¯Q¡öš,Ô^“‡Úkt¨½fj¯)Bí5&Ô^S…ÚkêP{MÃÚk®©MCíµ"Ô^+Cíµ*Ô^›…ÚkóP{­µ×îBíµE¨½Ö„Úkm¨½¶ µ×V¡öÚ:Ô^Ûð·µLøÛZ¦¡ö–"ÔÞR†Ú[ªå=™njó îlpÅ\®†íu§[#ÞCñW¿Cï–«êi8Á,üá×ß™~4Ñ?„ãªs endstream endobj 86 0 obj << /Length 197 /Filter /FlateDecode >> stream xÚe=O1D{ÿŠ)]ÛçuZ‰D¸‹R„ÄÐäû"åï³wG¸j$kÞó,ᄹ¡y1¬I`ˆƒ0ÙÆGlfµ&ìô} ²ÓiĽobÒÜãü\Ù<ÌÃ+Iù žeJˆÑYÇ‚¼Ãªz©]S•ëg¹žÚzâ$UO§ã¶œë¦ºµõ:/ÕâÁ¢D: ë.íÚ¤czË{Ù—M[[§ý²ü—MÉ’L8².ñûºÈ]wtÁs6?ß…A endstream endobj 93 0 obj << /Length 19 /Filter /FlateDecode >> stream xÚ3PHW0Ppç2ÀAc(á endstream endobj 102 0 obj << /Length 365 /Filter /FlateDecode >> stream xÚ­“MOÂ@†ïýsÜ=tÙ¯v¯$rÀ(½!‡J‹ùj”ï®0!!ri·Óö}žNw^¡“`<ßÉÍ& -”¶Š1hK«¥Ž ¨`ÀZܰ‡^Ñî<5¬Ï‡E7A!1*Óþ¨s kú§øÔñ«À g¥ÝR•»="%$aÉqÈZkNÈêª^4ÓrÆSiÊ'Ã&u G{ïªú÷ñ'á2/HRIÂQbdyãʰš+dÛfWbåËY¼ù'>1*âCV³’kö—ô!»ŽˆŽ"›øõ›IxF¥gç Üu L4è¬VËuSWA *›:¬ÊE,5Óy,w?l¹ž—ÍæXq*/ŽŒ.Þ&xlu¿¨j.‘}´ÀäUvØŒæèv»HÞòK‚L‚ÑBÚ Fód0D¨|¹»ãº>÷Í}K½ Ì Ÿ<æôwˆŒÊ„Tà‡”Hâôø «ÜÙ3 endstream endobj 108 0 obj << /Length 113 /Filter /FlateDecode >> stream xÚ3PHW0Ppç2@£ ¹ ´‚¡‚¹‘‚©‰ž‘™¹Br.Wt¬B PØKÁ@ÏØÒB¡¬(WÁÄÌHç(sr9…pé»™*XêYš™)„¤Œ01Ò344RIQˆÖÈÌÔŒ ñ‚[åÂOz endstream endobj 115 0 obj << /Length 2800 /Filter /FlateDecode >> stream xÚ¥ÉrÛÈõ®¯À-`U£ÑXuÓØòDã±ãجJ¥ì9´À–„ GÑßç½~¯A4¹ìòEèýí+z÷^èýzò÷Ï ßÐ^y™ƒD¦^Ù\|ù#ôö°þ›E‘zOæTãÅißÚû|ñ¯‹_v¯ÞÆÂ+‚"RowçÅ…òPxi"L¼ÝÞûâ¿ÞlÿWwן6ì~3WDÈ8ðŽÈ!„·dPÀ×\ùç‡k1ÅxâÉ5~vb›±Ì¹{¬+âºga=å«·i<‹¬e!=¶½Z ¾-/{ÔþpI0Û\)$Žx®Õä‘D:Ë G¶”:|‚}`ýɱÂX_÷Ff0StgŠ`ãLPŠIº—D o¼tƒFȢɗò#ÆÀÞÐÙS¥ƒ<Ä¢çƒ6165ÑàQVäCF[¤dRèÆ)UFjXlÍ”写A …žƒûûÖqÑÆÍòaH6è-pÀ‰ºì2ºÚ@'¶€ë†­üç ë;PÞ8‹@yuÏpUo1¯MnÁ„L®ˆWhéí3ã‚azËéއƒ. öç.xdæý`ê8kóø9OŒºNIxÐì0ˆR e*¼6Î?ýz–Îi2Šˆ(pßýá÷½/Û³KÐ+#H‡N9Ï.Ìpˆ‡„‘Ø‘2JWv8Ÿë*j³õý¤Z%ÙJZE1“ޱ—¢0GD³þÆyJ4, ‡"`W˜Ywñ¨ŸGuû-z€I{Õöçà§Arß›\óP«çS`ŹŽQRN>ñœqs"à°âRÓ(Hå„Áì.ñÿóñú’«£^ñ± ªDaï†[‡u?°h:+I²ž“ÀhŠC^Y¦q‹3´áÁQœÏÔ$ Ùm˜ÁÌ*!¯èÀ,'‹]\;rè½[lG_`Ójg"Á‘*;æ ·)èÌ#P<Ð>R_·sà ^އƒñÀGD˜ª ½ö{³£Á¢ÞƒûuuÛ+˜²Ä˜HáÀƒèÐñ fð ìW v u¥’Xq– ©£ã¾0qÒ¿i9iêH7¬†“OµÞÓÚ:Ö©Î!¤z¨ÊÎd³ÈÜüwP¯è¹ceÁ(ºÅÅs–ÍMÌQ'ÒÕ,Ì|ãÌ’ñFlmâêãÍŠÝDaGùdª(½˜×ÚÚ gU5kÚbD’$Øø7²t‹Ò-¼1»Ó4òoF:©hslµñÓ4q¤è±³r÷ -MâŠ\8²-†¤`%L—D·%+fÒõhtÓ9uèIWæ¢0©9l°jôŠK: £¬JOì_œò·qÕc_ 9nY,Ž £ä››Ok‚à'§yè@ÁLR$üR’rŠÿ§Êv뎊LšQ•:Ý ȺƖW8™Ï¬‰ÄXTž2  „l€±~{óûõåmYÅ©=µÈN0¹J£qÛzaú?wÇš½{Y˜¸ŠA‰ #°_U‰â„µF§Þ Ζ ®\ƒª›`޽yç…ÿÖx¾Þ®µø-È‚Bq» p¨ÐÓœ4•°5Üó–FÓù+tÓ®ºGæÊ–€Š<±¸ 43(ˆ<ž÷zSànŧ&àäîÛX"Ž/¡þឃ%-FÍÀBx´ž–žŒO®·OLÀÙƒÂKŽƒq±åyeºy–¨nTYb&ÂÞKp­ºãïÈg¨¡#ªM`°”€ŒRÿ³þÙLjËø”½žL¡wŒ×”“}3íÍÓ ‹s#B‚ô¨ªz`¼? ¦#ûÄt·ô´'¨@|ag™GÖ5Å4"rÄIDyêr¿×Cµ?Ú$ʱinc([ ¸YÁåÒS&s–É "ßú5UÿcêÁ[çz :`1Õí7€méæÏchhFãÃ+löÕšËj }ˬ`FKk½šA¢£ªÚe*â*3 d 2éÏpÛö’îÝÆË¸³^ ¤]ã"§„Çtë7¿²/ßê²k–É“m24ê;¢ô‚¼ó”É µ\ïɵÖâQˆSCÇtÉ©¶çØY‘É Nñ(µÍ…Ä S VÍÕm­M× ¤†¸}ƒÆ¦#®Í^#­¡ñ":r‚Qã®mÁ?)à³³^L¹q¾ldQw#w'¶L=Ysj«Nj_€T8áæNݬ-ùr†¼Ô®“U¬gmw¶3ÌúÈ[ZY+xAsѶ¾GMâP“wH;_¿_×”8+V5%-|n5?ÒlêâÀØùaæŠ>{ùkKã).šóPKQû Mü[S-þX6k JðJSúÔÅJ—¿a¤…Û`‡8GMîh"HÁ¿PœZÝg¬cÅÐ ƒed0E°â¿6Ö¯P•Y:aüîõûËõÒ¦ˆ&ʱ}—p¾Š¯;Jˆ ó*U5ØsSËŸ~ÂE+*<8½øûø t%…'ž*SèJª'qåhZóÛ$‹h Ú0Õ]2´­oº2×ÜlfÜñ à Ò> stream xÚÅZKsÜÈ ¾ëWÌ-œ*—æË99^ÛÑf'–¶¶¶ì=pÈ–†%9Kr¬õ¿Ð@“ÝŽ,GNå¢iö €x|å­îVÞêÝÅßn.~x+üUæfq¯nnWI°JDêŠ,\Ý”«Î?ÖAäÈn+»¶_o‚$u^·M!ëÈú4óAÖ2ï%=øn¸þú÷›Ÿ.ÞÜ\üqáÃEÞÊ'ÂÂM¼dUì/>þî­J˜ÿiå¹a–®Ô®ýJÄ)üÖ«ë‹_x&“aj0™Åntßs½0ÑŒŠÈy}µÞ„¾ïu%›ÇÓ‡¶æ€cZ­zZiä:ôœžlè·ÓÂàßõCw½‰üÄyEËÆ5Særßò¹]ÞÓ iùâ/ëTÇwn¥lhºÚj¹ödiß|uyC;î»mª ƒÄÙT%èaãûnE$ì°cmkAqüPÕ5Ž2 8Àû:È.¤^v4Ž’àƒ–D6ÄÅ-ªé ÿ.«}™× á§Î>/Þ_ó{÷Ü„FyÃçvÕÝNvDôе¨ŽÏU)û%‰rØ–eS™Á, vñ÷¯Û[ÚJRá„’ºjîè±ÿ‚öÛ¯}8!÷/HÑÄ Ÿ^~x‡†uAæÆÚ-Vì!Kj£e†Aì&I¬÷y×hF†/I·TÌú±W 5„a®ARy‹|æÇšåšÓZv9Ù¨ ÇIl%ê|¸] ÏQöî9{T•§ sú±/ƒ‰í±ªKW¹¬ö9 ¸"ð›¸YÈÁ ²7ÍôÆ'´ÚÞüöáòŸ(Ä»Õ Pq:ªXiÈÏœŸ«æøç¦?È¢úä…¢Àø‚œª÷æä¤9ܯANIâ6²6'•ÕÒ Ù¬ØÁi-¯(i;¦[t²¨r&YæCN”6aæØôJ‡C¾­Ï°£Þ k½ª=˜6mûB/á\EÒ°mj$Ì $* Š#1Þ‘Çà 裣Q¿kuɯ“÷3WH¢å™¢}ÏF1€‡aèÜhúd9u­õTÓì«ò¨ô0nbóbR¹fÜÔ®,_Î%2%t…ÈlóúøÞìŒe4–Tz0í Øx÷²É÷ò±Ë6tòû\‘ µH—*±7ôà ô°h‚Oe1x&‹Ã®“yyÊ!Í?Î „0S?±µu»{•møÕ)­àhL›øi3 Ña…ùòýFüÄP–Ž¡‚Â*’6­§©¬WCÕ6=·—‘qãÒ‚qãôHméÓ‰ÉÒ•¼¸[ù)>åeù+ßø$M¾—éAøëA¸ÓË ßÁôžË"†¤Sþ¦@õõ À}Å` ^«²9î·Š5H®ÊÅö&F°€Éæ—Ëi“²4°GY¢!À;¿ XM]±ŒfŠÏ´ àì’ ™ ; &S¶ÐRLBõG:ù¹ú¬@&BÏ tòÛ/ ƒ€îÅÝ‹«u{×Ó\{ðBáCªÚ:šØç§LÈ·H¼òÏCÕI„ÆðNo׸DÞ©®¸eb3jücíƒAÀi>c¥ädxÛµûY&œeÙ¿rÚv<÷Põò…Nsœ^ « †I[?m½)Z‰r¼éqÃu&ÛèµäŒä^ŠENÈÈi¼êÀfO&?(÷bd즸|=E6ö–Að<íUŸõˆ¢P¢‰M‘M¡Á!¯êþþáýÞ, Ä߀ÿ®Þ\½ÿ°† ~[ˆé ^p‚œÑ"¢„ðD¥£8«Z~§JRÚ¡Ì m#… …”Õ–\Èüx ÅFªÚ+"ô‡3[I¿û¼dÊ9ªõ³²•ª&(…Àu IÌn'×A6Lˆ¦lƒ%µa:UC…Î[4,õ6’˜} =$Ç* 8 pO’f„ Ó¹ð´ 0Ï•ÌL¥[âÜçå¾j>y‘çß&•ÅÃFþ&‰®cGápˆ…ÅÞT±ï g ´__­)“m3äŰÆè–0 [pè;=û0]Ô¡¹T _YâéÂ4EF±DÈÇ9ˆw´ÑÐk‹Z.ÒÐÅáD ǡ݃è Æå° Y¥•Í‹Š}> X¾Ñ—2 ½ójè-Á8®$ßâ‚×?_#ï<0ŒÝ(¬lªEÁª¦$°¤*h£*›6=Œ˜TîªØ™f¹!ûYL] Î$Íš Q¶I[fÐeŒ1D‡ûRç“*¤ å 7 *‚‰ØhUG˜º+Ôw›ú7ß²ú^îÍBtBÑAõhòâ+á "Ž";Ú½B˜‰¥¼ËP:.£Ò{½ÒМ]á*"&c¸Ã…ý±ªƒÂ1&mß7ÒÞ?è{MŸÁ UcmˆMô¢ªž~Ágª»&ÇÎÒR¨ç’|±h„›ú‘¶ØCWí±QámÁ¼…'¡Þ<6ÀHÉÔRÐkä´¾~~j‰¡Jf°K[S~Ð^³š}îŒJr ùüÊô§ #õl0Ô³ƒ¬ ò¬ñúDë’Kà!µ•hww„çðqJþB(N`ŽƒÓ ž<jvÚ’‰†–z™wDMuŒJÓÁö V¦Oì¯B5”h )á¨BIúú ¿K\ÆOàÒOS7}JŸ}#„pÕ-4ÔZœE ºß=*èSÎsp„º;à|†n‡#„à/^Ï7kðë¶­ùK Äp‚7 lY X ´4>êo fðÐjœp5oÅÆ®}C`f¢§·XF缟Aá©Ä8Íâ"²VÜ,!SÐs:õ§º}Ž· bêU+460uÏG¸ö›âÔ ÂèÛ»a£6.öÅ:)Äb–‘aÅ4Ü8Ò†‹yK{¢´›ºDAœ:÷P‘ )9€:À L¬ÔºG>ï®FàYÉLÛx¯™écˆy3ÅÁó”ØcÂ0 väy.2½JÜ ™•Ŕݻ…G«¶Ç ìó¨Ò8ä›aŽ9Âieð›ÓϘÑðáØTÔž’ôåÉ|Saf€ö«Åz—x ïmZúå*¸#½ñL/óΗ٧ ÙFF4gïùÃΛŠbØþRlRH†×ÁÍ1eHóþØdqgzb„•d9s<÷«mÜì^u_³tÙ}ˆÙuDý›zÁÞ!åLeï$´¦>ß+ªà¿TÌ¿¦þÏå?]£Sô;.Ççò5Ãø¹Q÷¿Р.O“oïòOꙬöÑì#À»Fı9h:£ôå/èËŒË"Ï?˜Ný•Y|<í¦P(|Äñëí£ß¼ ­ÿƒû¯4Z̺Òç´š¨${ªÕ3â²Þì*ó|ð™ÿãQð1~òÿ-þS”ˆç³eª†Ñ B,@Ê©C¿ËÕ?E1`£…ZobÀY8£·5¢µÓÿGp}& endstream endobj 136 0 obj << /Length 594 /Filter /FlateDecode >> stream xÚT[o›0}çWøÑHÁñ¨´‡5—i6ioYUpZ$.°vù÷³±ÉB²jSŸlØç;çpl ¼ÛÄ›¯91Š%• Ùrròñ˜$[øÉ§ªv§Ú¦óFpÑÔ™:øöÝÌV6ªTi§ì‚ Jñï“;o•x?<¢›a@@H5°ÆÇ!È*o{A®ëw#GàeØU.#=–à›÷ÕÃŽèiDDóĈJfNIZý᪸ù#pĸ¤F›iCÄyhuÄŽoo¶À.Õ>ýYöV|–¥Ù“3¢N+5i1_³èÌm ¡XPK(Î sµ7ž;P]ÈZ•«º/ÒÒ­ÓÌ'Žû‡>ìèF„^µzŠaUÔ*·ÅÏ0<Úy?žÝûæ,Ÿ øRÔ3‡TH]¦ê\°ë¦Íd3ÝÛñ`;û£a3QE\0ÅŒŽ`ºÇÚilÐåùZ[}–LŒÑÀers+‹/¾n÷þóÊnŸX2$#>nWµ‘þ\´M]i-íçÁcÇ9Ý• ùc ® jã4*cË/Ÿ`˜V‡RÍ3yÖŠèLGWÔ4­wË››yuÌ‹vþŠ„„e<ž»ð"`’# 瘻‹ôÍŽ™L›©‡ì”Ÿ‡1¢Üb†D|¢vh›ï˜ñR½bÜ41e±; pw©‹PŽ´ô©.öª®ò)mó¬ÉÇ ŸÁ»´.Wk6ÄaŠuù ®/ñ¿@×O¤†àúy#§ kîäñ¿Ÿ ¬/$£­ì’çoD÷T endstream endobj 144 0 obj << /Length 220 /Filter /FlateDecode >> stream xÚ?OÃ0ÅwŠ7Ú5þs±ã•ˆ"• ðVu‰Û"¥-m*ñõqc2 10îùîùýNa…'öÙý’4‚ Î8Ä-¼§ZR°ˆ=ÖüY˜Š§Ë{ºœF±0¾æÍ騥OQñëxW”×4¤vL¥ÑÒ©Å&®Øcdg¦óG º“ôÊ£;°õF¡Ïú JÚPãkš:€\ë€7öÂÔOȹþòªH÷o«?9)çÔ¦`Ò-0¬µR[—×&±Ù·§¸]`¦ G7¹ÏjŸŽ×v(o]ÛíÓ>'ÎøÂQê endstream endobj 148 0 obj << /Length 1909 /Filter /FlateDecode >> stream xÚåÙrÛ6ðÝ_ÁGjÆB à‘7ÇqÒÄÍQGN&Édh²8æ’Šë¿ï B¤H§I›<õE€»Øû=çÆñœg'žY?ŸPX=‡:¡ï„Ô#‚NZž¼ÿè9À_8‰ãÀ¹ÓX¥ÃƒÖÂy{òûÉãÍÉ/O9ub~àl¶)‰<ê±O¨'œMæ¼wÏWkáþzöfsqµú¸y¡I('Œ¾¢m "gí3SŠ$›ÕÚîŸ+ßs_+š“‹ÍTÒ@„$dü{%±å%±N@áÈõòâðõ€{$ܳÇ(,‹Fú­¹kªµâº3 bÔ½UâÊóÜû>¹FØOxÝ®nµ>½‚yîvÅ=Wƒ4‚ïä…„ äAÝŠÂu+;¼¤¨«›u/[-p9`ì:„NØÕ•DúP•¸kð®¼Jó&):²Z3?t/'JæÉ@SÕF€¤(K#+TV½ÌpBAÁ%kŠ–×¶ûà1^h¥¢x«5tü‹:'U–´tQ<ûSØÄ€^ô»z³›^Ò¢”I“9„n¿³vÖ÷Ú`N]Va‹ ;¥hr°2Šs±`(À5"„î¾n,kT ÿÕÛ^VKvék@àèVÔ+&€+ü ÝÎxü‹‚é½Âiš"O“>¯«!–:MeÓ#i²ª~Џmëwi‘ÃiwŠÈ×ûÞ€µ‰yÑ™Kµ±`5:ÁÙÀ®¾îm1ØçUÞçIanie¦xÃ%H18rAsD%Œ7ÑŒXäÄŒ™”Y=Œ«{n•”ZD€í»¼ºÁ­Š½9Š&Ì÷€òò@-®è”ûF¬`ŒGÒ£…{ñÙpþEÇO±— õŧ„YDX>uÿèö6»æ7søt.ßäVfÅË» bÂýpÀxúü·‹%Ù => AV.Ù+$4ˆ¾ISN(õGB\ž_Öž7Žj’~§|‰ÿêí2ÖŒ(ZœD‚Ncjƒ.6Cî6u×åPgñà «þ;ŠÏc©º_|ƒÉÿ›³ÈàåÅË×Wï.b‘ ‰S”în—§ªˆìP“¼ÊT’è ]=aéeÙÔPuxß#lÖ¢€Úv– qt+z´wKYÖ“[ÐC¸é\«W{†¬Ï§^hÚ:•Ýr"«ê…s–Ö•*+þæ6-®¦ƒÁ¸›&u£XJÚÓÄÚlŒ{o™t9šb`´Å5Á¥ÏKiRÙ H5wc{,.†•!ØÉeVØ@ —;#qÿµ>•oƒÍÔBj@85µ—iG˜Ê)Ötä¶¡tPi ;¼†T4(ͬR£NÓ[l•/;y‘b&AÞw²Ø>ˆKÑ‹ý 6º+…ÌÍò®)L{V*exlë??öma<®9ÌZêκ,Q øs—÷;¼YÑÍÓØZ„MõõíR5`„Fñ€Rk+¨êîñ¥6SŠ«þ™ôƒ*µ)`Ðe• P( åhÔZûAD"¨“ˆ’Ê,õm’š¨ØÒäùÃp±¡Ô2÷òÉ9že ˆ s‚ëÂE½M²2¯Æ¦UÀ>É2D4VVv€ qa|bÃ|ÆÌ|æC—®òf_[Œ[÷'Ðm¿ïób,Æ8FoEgª,#!,ûbò¯BÛ  ,P§…ƒðêÙìÉ’±ˆÀ8¡ƒÒôÞï¾ßy¿žç>‘Ûd_¨‰)ŒÀ“ÐRýÜ÷êÝy2fr˜ ‘ Ü&9xWnu‘Âk0K=€é¦ ë0úCìéý¤êÏ&Uææ[<éÖ##K- £ª6Ò´òóŠzî^ÚQZ¾Ls5¤K’«W l­¢fªAê‘ a4µÈ¬›ÖášIû2Ë+iBízTëliÄ9c˜ñ!–MÍ«á&•ú&È…I2}³Ún‡‚¢iC•&îv¨O¸`ÓjJ§ñl¢hc«4*×åÕcñéróJ©~öriH #„v8‚–:ÉÛº*íL“–éRê¡{$Κ›Æt*´ÿ¯…Vž£è¹O·ÚPè´0‚ôø¤C`®I ãîa”…ѧÌt˜z­È¯GñÒ̈́ոQÐä{PA}åÞÀi Á4ºÞDÌ“‹§Ê3L{æGU¬õ?“ºåÿ„ºe_}?¦†ÅáQÆÆ#ñœ ç:{c|«ƒQ„‡®NÊû)ŠùJ€@l&…LÍT0bÝ‘cýð®áy Eíð‘ÈìcYÝoËJÎÉc9õ€Ógoߪ >{óü«gõ˜<žÕ§«á̧DÀ^XÁ|ÀW±ßÚb “™vþh&‚Ìç6a^|ö#@l}èÔwúÅ# 4›æŸ–lq°£.ûìMFÕQµyVèÇß#þ·Eÿü·ç¯6_¯ýÔ§ð2fÿ±ø ÊDü3Š?:ò{z€Ò(>|þù±M^4Uô4ó‡ºÀñ'tM(¿ ³8úÆoý‚q¡ s_ÉÑò‹cŽ{ä.¶ endstream endobj 3 0 obj << /Type /ObjStm /N 100 /First 819 /Length 1670 /Filter /FlateDecode >> stream xÚ½XÉnG½ÏWÔÑΡ§—ê  x `X:$‘u(Ê,“IößçÕÈlj8CEÈéYª«^U½®^,i ä4E2–Éh2>1dñÎ0Ù`ñ†\·Dl ™L#YK!æÊ:ŠÒ¾ÙH Ð5e&g(ÇDNÔB±óÐëð5¡© “.@)Ú*vd\¶Ä°ÏÀ#ÆC‡o09ò°u"}J<ô%mÉC_‚^ŸÉЍ¶šm….ÖTh½\€¨ÑB8Š“Ð᥋žð³>Ÿw4Ã/´ W ¢­úÇÀ” s&@µ)x÷³â$nœ×-7 v9"ˆ1 +èpF;X… Ühb­åSÄ ‰M@È´D OÙaQoà3£?n ±·©2F¢Ø|‚p‚2c 'ÁôIÉ"ÎFâŽ7ÙË ºfx‚Œ àÎ4lð1BÎzc*có†ȶwŒ4àÁ3<6’&/ä<ø‡^A,ã…DH|HòÉG+©³¡2o²°Úr%0”-ЂÆgAGyÃĶ+teOÁi/œÁ ËMÄMΕa¡*²W#]h£Ð êBÃu¡GC0t$Z‹ aYtN, %¯«£#ªO¨þ}z:¥ú½}¹¸[Œgʼ¤W¯ªŸ\ øÇOZë·r™Ée,—«r7‘ËB.7r¹Ë­\>iÖÒŽÊëæîKÓóeÇö|?”·%sk#dË ö¤xUfîŠÙ‹¢uϺâú¢þ¦­£Áÿ¹@˜–€LJÍ[Z¿)¯¯‹è¬èâiDw}Ùù¸žQÝ3ÇÜì0¨w”Ü…;o“o^L,µ_—ÌÜh÷]í'Åû»rY¥Ñž"—¯Ú¬wêv—a+ú|ëtÙι-éõ'• –®Š·³=ˆíûˆý¹Y …f=Û,õðöuS{ VSÒýÞæV3´ï/)+›—íñð_{48¯Í¾ªO ú—òmÞÉá´Œ¶ûv¦ÊøÆÈþÖØ÷mÊ6z¾wTœa‘¬é#ÕÇ7‹sÑqtTÕ§?îÆT¸ø<®ê·ÓÉbû‡&<4ñ¡yˆR~ЦFCUŸÜ_.šç?o&_«úÍtv5ž5¶õyýGý¾~{fšA;‚ƒÑ(=¢wYìâŒÏÊaç‚=˜âè öš¶ïNŠÂx­e°‰ö6(ïýVöà(8;•d§ÌZ–Í+«àÒVîð(¢S[gìšUBF8YÄf+><Î*GGÖ&£h„f; xN+ä´CÉQ»¤Râ^kÅrUä(eU E•,µŠRGnçÂ%'#Ú?§rºU$ìW|åŒgÐÙ>GöÅn|»qûU@9{(rôôÐÚCÖ;k±^€jç°s‘¬ÇJqv”váW•0°xÃYìF™w‚á #*'G¯åtˆFFk­V^ÇmC¬Û<¢áÝÆXK®gŒí)ãRRsæœÍ¬l ¬XÃGÞP¡Í°œa•Q(v('Ív©-Œ‡Ü-4xð˜ìòó¦}^ ²¹3ŒmÜsÛpÈa‹* "¦™“G rV1ÈQ4ËýT¢Ú´Q[rrŽk•6ƒbAÎÃr;ãå\Šàõ°>ëŒò.<`›9µ¢Þ¾œr-…œ¸ïÂ)Ãf}^s~·¼µä65¬~•³nXÎceÜG‚u9¬9¤g&ãùcš¹¶ûƟݯ]WpwMÄaoðq7ò´ä6gMÆ¥ Rð°ó&¦a9¥nÆf1ãõ’v]ÎcCå†í›òy¹€J“‡ñj*ò#¹ÿafGÞ endstream endobj 159 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚ½n1„{?Å–¶Ä-öÞžÚ $©HÜ!Š HpH(oïŠH4ydÏη¶ áUë>ÄLè¿’7ý—Õ0’}8ê.'瞆 ¦í Cí ZÍùÛ`NvíÀ©ú :BUYòS™löÇïYUl—ñ­j&¿iËNÐ endstream endobj 165 0 obj << /Length 2503 /Filter /FlateDecode >> stream xÚ•Ë’ã6îÞ_¡­Ö®kEQ¢¤ÝÓL¶g’ì&=}Ùšä@K´­==¦Ó€õ²3µ¹X Þ ïìÞ‡‡€Ÿ¿=xžð’ÐKDàÇRyyýðù×À+þ“øY¦¼‹U{‘JáYyŸ~~x÷üð÷‘ð2?S¡òžO^” ? „§²ÐAì=ÞçÝ÷ûC¼ûáíÇçǧý¯Ï?Ù-"òe¤BÜsü(ô¡ô3!hÇóOˆûðø¼–PʼnŸÈè¯J¸`…©ŸJQH?"vOÿ»?ˆ`÷vŸ»ÿía’‚Ô2fùIv™.Ž{±²Ä(VÊäÞ)w¹V‰¼Òw®ó½ˆwƒŸÑî— ÚŽ–~  ›ÖáKÀª µ/û0Øsíésè _ˆJ{"°®*~‡‹i†2×CÛõN’@Õ>ŒI–hwíL S0Ñ–7Ó£7(W°ûZæÆßd˜î~<­0ŠñZ! >ËÌô€Zõ„ð³˜`(Ûã$ùmzMGXöô,Ì`r’ ¡¼e° ³{ú„ïI_oè[ó+|¼ë¬rá»6}¯Ïxx³æ‡`톗¾Òù&Á¯]{¶.ÒéڟΘø™ Ùeq«áJLü^˜] ÇX»'Iç(>j¸*ÉÒ´kpøyg T­®î áÐ…“Àp{_&üF©ò:ˆïàÓˆ-\8”Â#Ìã‹yô‘Hr†Øø|˜ùbB¿=Mo“ìÆll#fÅNE¾JS·}x½šv¨,Ó—Åg¼±8öàä7IJlÎ=k«¥gÙ앨:Ô!Zê SHk™d§T3o²­¡o9˜ó¯br´I÷}›—zrÛͦF× &û·ôÚß@IþJ×/àÔ`7%ÑnJ·@kÆuZ ð˜A3:ôÅšð_fà}>ÄA°{çôg}óܵ£U¤Ç²9a$·]MQò Ñ çf1Gʧ¶6ä#ÿ±ßM×¢!CµÃ˜Å•Ÿ>aæ}ûñG‚/3R?9­iúîËúZ9МmãzmÈ0º)ûšÐ^.¦cQ4AV¹á%s£\(yÛ ºl¬UíÎæ^Ê[¥á}ì0IÉX–$~òg}¬Êþbzʦ”…pµÉ騝WÎD’-a¦º»/zpoœóª¤ÜÀ—’JCL× Dµ™W_ÈE‘u»¢ß+ïF¦Ü´Ã…wBè[€/5áâŒÄKÔì×½=ÚÐÔ¦mxz´Ø]{½ZÖ)ˆÛµ5á@!k»‚xÂ'I™®ÌÆT9·ÃÛÑ©jÞ³‚Ð&ÙÆqMƪú…>Àö ”(°o¥œ`%»[ù@ Wd¡Õ¸ÈUû)×À2|B±"N¯kC åÙþÌ8±Y¬EÆBµ´cí{‘œW‡¥E&NLÅ­çáòÊó0ùÑŠŠÓØ]uô=+/IXy Ÿ:L¬ªvoך" ·æ;5l9‚f–Ø0]f °zCÞèM.œ¥T¬-Æ0¸v*äÎÐë© x9½|iH,Ây!·ž¥ßˆyïôLVÅ6dʹOU£Á£ÿ}QWE„ÓQ—H WLn\bSPÄ$s`Et›K¸´è,ÕÑ8,—š}먔 »O“;¶%#ÏJàcü‹&¦õi¬X´vñŽŽFJ8jÑ+¬¦Õ•((ÎQÊ¥IxÙ‘{gØçPsM¹oÞµÈl6tº5íÞ0ÖÄ„5 oÍ£gd¬­º`v4 ]L·¬múLÔî=â¶ÌÏ óß±j¬^hµõ43¿“Q+s. wßÙ"Û§6áôÆ4S˜ÊZ ß2ꦾÖ±LÉÞ¸ ËêhýwLM(U$¨õO7cMæ²3¬hÞ~'¨`µ^nZÊ¥±Ž˜©H§¢Y%Ôæf˜²ßæË;γ8*ÛVqð±k‡6o+7dôå¹Y·açQw®·s¦\(ý8ÕlŽ•©yˆ¸h~9Ãd‹²ÏGÌ6Ó ÃºÀ&+’6YÐS‡¾R‡.í“ …/eì:à§÷ßÝH„Áw=•#˜L¾ÕeÐÿ†SÓîÛ±qêKÁ¯V£Ì#WhLç‘uF|¶¡—ë¤Oü²}¾};4xYcN˜$~Ó˜‰ð9ä@;§WRŸ@oÌÉ96¾Ã|ÀÐö´E›ª2}ë|q¦q!SêP¿Ù½MŒwn™&‰öAè[6Ë0r#ƒK~âˆ=ÖPgY„iB^0‚1é¡MptŠ(ü-6†ýX6bD…4k4,"’®yq‹ŽòðД—W;L ¦ã˜šÂ©ïæèk UüX™uQo¶Å7<ŒôR—ÍØ½NQk‹Ø&°uEí“ µáQþ†êßqAÜ]ñpÓ­.yRPÓàönDz¥ö3ÑÜ@NI(Àô6Âþj’¸ìîÍ@t0½Žè¦"°!+\ $RÉÅëZ‚£û4qÿ{™¸qËVbܶll BsÊÀ÷z¬†ÒNrˆ<ÇvOËTnð"p¸mÐ2°ð›È#r‰ÉgJ”×WÚ´i}Y•С ¨s;T_û7¥Œ@ŽîxQ/i‹ßÀ¹ ±u¦Øú¨®ÍŸxhÉšØ ´*ûU‰Ê¹N÷3x’|`Ká}ž5£µhˆ={6%'ïÔÕܺ¼##ÜMGeM;ò~ÇI7‡²9ÀAÁ·Š¢rÄnzk?ͤ7£ã=‹ÚØWÒõ#*ÜÔ\Ó|5H™ð+Åbò^&%oÎÂ͉r3¤º;;(tر*]Ÿ€Ü}ÊÅæMfTÔ«´ÐWÿúW CÆm턾vGµ¾µ½§ Ûô»jb –@—–øtÅA>†(î4€sd\M+ÜÌ6¬¶ 2Òºµ §.qfŸÎm+,CUªÆÂ0+L—îjë¶3n¯­,ÛÜðÜó¼÷Q,¾¬Š Ö—=UóŸ_¼6´#ˆEl7´o}8ÆÁâÂG*îZ“·uÝ60ÑGöü,R»ÐU¿~Ãí&ÐhQî®:ÜÕhÓå< ±Å¹˜F«øöÞ aGÃc>oå¥fûÅj;b˜ê‹¢ÄÝši.Ç%nrúE®³$ëîñ¬<9Ó§+ÚÄýoÁWªêÏ&¤;}‡»3>“(û€F[Û¦L¤þéÊVçó_7H¬{,JëóεGë{ÞíßZqä‡*Ùþ«%³ôÿüß-–‘)áE¡/·ñÉ–ã4Td’ endstream endobj 169 0 obj << /Length 1701 /Filter /FlateDecode >> stream xÚ­XÛr›H}×Wðˆª¢1s‘·\œ]'•lÖ«ÔÖV6•B0²¨ в˿=Ó3r'OÌ}ºO÷éî!ðn¼Àûmör5»x#¨“8d¡·Úxó"±$"æÞ*ó>ûïæLúª^«ºjæ -ýWU™ªý\úmó G®U¡’Fa‡ÆY½]®fÿÍ(\x$ "/ÝÍ> ¼ ÆßzáñÒ»3«vž—ð-¼¿fÎ+d÷%d  ¹ÞR¯†‰“Áë£ZT.Bæô ""D„zqÂŒŒO¿Äû¼AÊï‹dN¥ú§IºµP´÷{Õ n¹x×=°oÁ–$– eú4ç_ù·9 |}å~»µ´V™*Û<)t_è{ô­n:)3lØÍpÒ}›¬q,/[UC3ð7ÚœIªŒéõk#½^ložŠ˜û’Z¹Ãð[Ts.ý;½YÕ)ØŸÌŽ\¹Í›¹üª°ëòòft&wg ?Sÿ\”*{>€Ë£ŒɽHÌ-J”Œ £!5;̘µeU*½z„;ã$ˆ¸[”åM².ŒL2°€Cc ô;h´žœ[=ÍÂ&ÏÆ.л5;™Ûcó›² e÷\É"« ¥û5l…bS:‚»Êø¸N¥ñŠ;GÄhE#¼ã.t(¡KXIqÉ¡q˜$8°Mšíb «3F£cí’µN6¬¶2†á1šµJ«:k –ìˆ%êƒí]·öƒóPØe}-UáT’¦ÕnWeIkl œBÕ”·$ e·v—Ì›¼*›'²ŠZ&;56ª5ÑÀ¨üŒšÁÑr¤”“0îV¡@ $DÈîCÑâ€f®É78RVØW¥†ö6¯«rA'Qa4g®ka:­J­òÍ¡NZ@'›½Js=Œ®"«Àx¦¹ª»Ãµ,oúWv¨ó«ÈÐE@Ÿ¤MРVñA'}k°ïP»wy»Ø¬M‰ýžWåÈìÊ(–¶ù­vE;xȳŸŽ à·‚ÄÁ(¼ÑáMÐ=ÇØg£é¢J;ÁîÍc#Û) ™rd——›¤éÇ赦ÍCqœOÆq›N?®=BDk£Ë=ŽiàÛ&˜åJìnêj§[Ò¨hx3dH$oÞ]¿”×ZÒWZÒóZ¿_¾¾ºž`Ü2&4ÝÎSÖÀå'¬ÑÆàÚì¼HPšH°µ=yõþã´‚‘#ã¿ÿ‰G@>Š€N6!Q6!0®œj·¯ê䵘€_8>£ÅïixÐ'ç†RÐjècvSc1 ûk)¡\cNÛ‹Û¤¾hwû)T(YŠ.[¥òÒIÙ¤ªÌ°Þ:~eÊêk˜ß}­6*AÒ“C¨tÜJÖÙN<Xò)½£ð¨3ò·z-¿^~ºzMjSJNåö˜qtž»­ªíùzß™tu.n‰ûº‚*±9Á *-郹mBÄñ$b(ŒU{…mŽ«C‹©¢ö5÷»uUä).*òò›{|`á«4;JU7Û|o‡6øE­à˜£(¼ñ°2©,ÃŦ¾€PÚt¾{<ŒŸ ªý©ó‘ž7™äp6ÀÿnKcîÿ­¯ÈˬDµ†Mð4>å¤ÞÖÕ`ºcWr—̘)tK+èòêÅûË©GH¯DFÏ×$SŒsÎÜ„ö ™|„ž¤NIÈ£Çæß§)¾2ÏÌ>NiGDJñcŠÛPsÕ¥WçWg rÓjŸTíxP@%×NÄ]¼,É8õð'ƒ§yE‘W_kÝêxôÕQu 'Bt¿# ºèG¶s`X÷(òuÈÍ/q&ÆA49ü³$&ñp¶3ÿ’¦‹¥d݈vÈ•d–ü©¨4‘x¤$Á1—d›âùôÿ øHÛ¡¦ãµR@Ä~ôÚÉŸÈðp¡Ôâº4Õ—Œ„²«Ú_móyn ˆòà‹Pÿ+:› FBÿEf¤4 endstream endobj 183 0 obj << /Length 1141 /Filter /FlateDecode >> stream xÚ•VIÛ6¾ûWðV ˆT‰"µô–¦3ÙŠ.÷”-ÑcÁZ-˜Î¿ï#ß“-y\ ¹˜âÛø½Ý!{d!{» éü¶‰à YÄRÁÒ( Tœ°¢Ù|þ²èXäyžœTÃd’ÁY³‡ÍŸ›Ÿ·›ïeÄò OD¶{&ó(Ȉ%¹¢P±mÉ>ó7ž¯ø»×lï>y_·œJ$ƒX&Âê¤AšFÌqGjÜ{‘â¿ÿåÄ7wÛ5ÈDF,¿äâE ˆ'QH|ñÁS|ëeŠ¿~xçù"Íøýû_ïnœ-<ôãL9eßÂÈH}{0 §|°ÈG=ì5ã_ÂXÖΤi¼Ö]¡k¤ÝÉ‹CþŒŒnÔq¶Ùh´jzd=r³ÐzDVo†ª4=Ø"Ñ´…ÕñÓhJäí=òÉ ½Û^½ûñ—7?xRqÂ}œò²ŽçÇ"Ÿ=ÏÖž§ Ï3ë92âGQ+*‹ip`x±ÃSOðv;V…­f’`–µl5¦Þ£èu¶zuí åÂ";C^’ Bh†³jÉâ;격ÚòK¨Â ~"ÕÊc¿SDz¸b—Ú4]; Ë3ÁcðÊ–PÌõM¿O3+$1Ý Œ0€ÐèÂ=T­Ëñ9ÀÚu݈҃ùæE!Ÿ ·Æ‚lÈPR6@r™ ¸b6¬œ×Ucß]”Õ¨wøÌ9‹Î† sSøo”£¨ÛÕº^OÝhóêÊÇ]«vô»½DªÌ[ºÔ¨Î»Þ裗(îW­uG¤” àU{<‹®9õ]SA}9‘Œ?y±âÝT“ ”Ig)OxZh/SØ&V²(Ì0à·«<QÀ€ðÑÅ ß™¾#‘RC0ô`\oHþž=;G&Bç’ÛuƒYšô-嬮goÄdÕeb‘×8–°'ÔÆ\A„­Ô;lH­~îàíΣDð*ŒÌa\¯ì·*„ì¥1ASd.g ¬¦H|™"â2EÒyŠ, ø—wcÞºÂ_8té¢Qr=•äàÂìšÐW°£çöé„(yù²û¨‹§¶Æ°Ã`®œ'ÑYõÆ™+ dWdc0ÅÔãèËíˆ@#Õãa¼ ¯™‘/^œg_~™Š«ÍŒ“¬õ¾\Å%Á¸àÐ ÜZ Ý®ì~|zûbÑÊ$ D(®­Ì³›‹vþGán/v¦µ¥`½ƒ¢ƒñ›ÝÙù5šŸnìX‘*ÍÁ˜“v]$“EÁeÕEpÇú€#8×íDzàzi 9o â¶§jV·å4Þ@r™RöõÙÂ*3p_ïl ª3Ò«R¬ÆN*ò‰ÓÉö tÁö@;Õ§X­ÒÜí6’ ç¿îËà:ä|aôàcG24*¬Z‡çI½Ø»0˜_‘ütöÏJ½ÇˆØO’{¶š¬i½±‹î—i,ƒä»«ôæÿ_%Xãצâÿ0õòï¯(2‰˜„¿‘Àdää>àÿçÒÝ endstream endobj 188 0 obj << /Length 217 /Filter /FlateDecode >> stream xÚ1o1 …÷ü ‰Ôsœ/¹¬ ŠSÛlÀp@ Ã… õï.e¨ÔÉò“ýü>ì€`*FA¼¾±Þ á œÇ-²¯!la!çÊ42^ÖñrJª2®•ãÓq¿U#¯é¥(±]Š¥Ñh jµ 31 â,t>D ‹1£#›ƒX¬¶YŸaí[ø¦À¶Íµ‡Oñ.è7ä£þñj}Úê_NÎ9µ)˜šî‰¡¶­óyoPÇûnU÷> stream xÚÝYYoÛF~ׯ úDáfïÃoic;I'±Õ¼8AA‹´%˜”QÊñï;{&)–å-j\rvwæÛ9vgÇ8º‰pt:Á¡ý:!ÐâˆDŠFŠ`$˜ŒfÕäò3Žr ¿‰02FFßݨ*âRC[F““_§“ç'œDIe4½Ž¸!HcICÁ"šæÑeü[’ŠøÕ‹÷Óãóäóô›B8b\R;‡HİŠRÊ!ÄO9yýñØŽOû¥PH1þX„qTRÄ´Š$aˆ{i¼ÿî|zü2I©ÒñË„‰øE¢q<=ö”g¡kúúm $DÄïÎßúqv…p£WŒ¨#*<™$Ñ:vˆç§“(%;H©dHÉ HŸáã_¦¸EUxÌùvmf›ÅjÙãýü„éŽ1C##¨G2/ê$eØÄ× Çñ ˜PWÙÆ›Îm]äþm³²­Ž «È_ÖE†d¡ß!²o€È£ñœB»™‡îßT¬¯Šõ*p˜­–Ÿ0ã7y:¶”²hd,óϺ™TU@®¬ž€BöYY®,Äï 1¹U‰];!°öໃƒ *pœ­‹£QãôÜ•h‰„bqŠÏ*£ZŸ¥L#-xë·àÑÔ²´ÍéK­!²´ÍtŠ4¸Ñºˆ®-ÖaîçÅ-/%ÀoVƒ2èõJðrñÔó‘ã¸\†èµf븉ÓTEOOôƒ±á ÐѽqP#Ö´äøGöΪ/eñÆ‚€ÐQnöÁ8Cl¨‰ å¶… ==æ/Î ° 0ÌŸj)‘6a3™U—Gõ燴–è#8Ô]LaüüÖ}ù‡Z¡/߇î|µ]×9Ck AàÜ0Oµ„àȰà gùÙü¬:«÷Š>„CMÑ… ç ×{ÇC_þ¡¦èÉïZ½2ìÛº€ý=¯÷f3ONAFp“3äx¹­®ì b¿W×=€ÐMöŽ¥>ÈC ØÉä#B©/þPûuÅ“;ûíc)w^©Ìð¼‚d‘ì ŸMõcÎÏÝ•€Î9E¨Ô¼*Ö…ÏF%ïê q›?op#ú^f%ª‘ËÕ¦hÒßÇÄáوő–íôa*š©g™g6Eù™P×cL!]˜5“æ#\T ¸ºcÇ@Q´Y°3Hi=`W-–[ÐÅCpÆi3¾aMüB°¡iÙŸMuÝïütçjÀ œÜzÇM8xåØÕ çô6÷\…iaÇ/€Te3‰OûvbIbð.»´ð}–kßËM᳡oÖ‚YÖú/óà3«ñ9³}ÌŠ"tRÂ×Lru˜b ¥‘’¤˜a 1Á1»éUòa¸‡Ø_†m¸¢ŒuyÀ \©A—,¢ÂÞ„Ü~}üJ›D»Uö?gUÄü*ƒ ]8ré39B´Ûteè°‡£‹f/H«•?7½%ąݽZއaw[Ò X¶e#°¥à;vøNÜ >ŒÆÍøÐ`·²Ùÿ~}×чȞ#Ÿ#ܯñ¸Î‚£úçcÝ"àiPGG¾DèiõÕ¼¾š/¸M•ÝOðN!u‡—Á1ítõâ]7Í*d_UG;¥‚Ð6ªL¥³ Z˜€ˆTVŸ~û“ƒ(‡Öè£ü¼øº-jØž„Ý»|³YÌn‹@ú–•‹> stream xÚåZYÛF~Ÿ_Aäe%Àêéû°YÇq0A’G؇õFäDBDIÑgòë·ú"›”fDQïÆl’Õ¿ª®®C8û9ÃÙÛ›Lnn¿æ$3ÈH*³Éc¦h¦¸Fܰl’gïߩۇb»Þ GTéÁëõjVl†b°ß½ò#ïŠe1Ýþ‚ J~˜Üݼ™ÜüzC`"œ/˜#…U6+oÞÀYãwFÌèì£{ªÌ¸Ôp\f÷7?Þà²}¬eṞ‚±A’™¶`eT%˜b†¤µp¤¥•g§EJij"íø:EZ«l[d)Àda% Bu”%5"Ld„ #DgYŠ" ܵd)ŽŒ2ÏÈrÚZjí‚‚Ö¤Ø#÷*þzHñ`½-§{§µ&‚†—Hé#’ FÔÀ¢äMo~1˜–Ñl–Å9$QMÒP@t¤&‚49BrúmÁxÛnxbÇvc¨Ã‡“"µƒVìÆS£Sý T”Rã©ùjº|¤s7ùˆæ¡œ^`ú”y¤Ó—åmžß>=ƒPGBãЧŒ#…€Õ-U·„FÚCÐϲ Z]Ë‚4 ÒàËõj?'ð Ï_ù“§§š•ç U¬4!õe%…twXzT@×µ–É®¶¡%Úr|Àv1*ËQžw¶—&¾Ì¤@,#¬`?² ²áà%À!Œ‚T÷ЗÖí=ìÖËþðôíeÑÙÄ8ARÉkéãQôùÍ7ã²|?Þí>l6ͪ £/y) ¬Ç {Bþù]gk¢)J®¥ƒ1ÄpPâ|éèlIM}ÉHAPlÉ8gqŸ' ));íó/ø~J\äáæç¯åt¿ømÈଇ¡6AõÕL êû€bßÙJ[ÄôTLŠ!šè®˜½°Æ'v[²Ü³¬WÝ7R, †¸Ú ±qá­óïÎvÜœ»/]éÜoî-“®F# CZ\k4Â(Ä!pþèj,­¹{~}cîæ¸Ó*¶œ€ ðž¥0)ütÍDŽ¿ÁÊ‘Ÿ[ÿø¾ˆ¦KÁ7AÒ¤¸T!2ÞÚÏi¾{ B†D)à] Ü›ßÃÃvÈð øm¾e½Úùrع?[¬Â"<˜/Âý|=;”Å*,üÀB =ÍKgB€ž„%*í6G…Lü6÷cˆû!æßÃ*À¶î;OßzçTu~W©$Ø2uIaökfUnrìk]ÎÊŒùT1$„pÃK¸Ą؜”+n€â¯Ô~$WðŠ2ðϽ^ ‚:A§¦–kÄ?VÏX Í@du±ŒV#¸‡ëéfpÁàiŸì¾lö?ÿ}Ù™]߯o–-Â×üßKÍvO]÷ÂÇQÇ—w*¾â€ç+^)ˆ—Ò®~ÈR:™.<;)/–†ðš%¤+}ÖÑsE—Hå2 {ÓÈ./N]Bã<¬ø¦£ N¶Ÿ×ÛÂ&±#ÑÌÔ6ÛÅj¶ØL—þr?ŸîýYñûf±-vþb½Š·ÃÛy%g±Ê3¸ÊÛ°þÍ@ìרþ§yî¦ 2ŠÝžíÊãÇHcˆÈÞ»—F W2=¼è‹…}Þ:]ˆž½#NGj1_4Ät{qÀBÖë$<Æð_ù«7÷“>›0àϺèçD×Ýtu˜nŸûV:ɾOÀà`ï3"$“*zÞN·ÅÒ&ôOíhÛîj£}•¨>¹­ÈÃز¼œMCHþžZ­÷íhÝ&¸þä1„ïó†ÈårmË«ŸýðÇ¡[‘ ¸Ê] Á[œ5ò$›hKÈg„4šÊ—RF!jÁâlÓ¥I‘¨R¯øöE=+J@˜Ç$ä AÅˉêÜ£ ’ˆ´˜äˆ*ri£„ ù¢“\§o+úR·æØàNwkj‰¶*ßÕâž—å,Ž3@g.±8}Ê⸂íGÔõ²Ìóù¼,w»³µ«hu-$¬NŸ²º „Q°“1ø/Œƒ´ý‡ènüfÝSp_EÕ”çj/‡Œ@ÒÀ¯æ÷—ISB‰*K”çh>·'5—ÏVƒ"—-D}¹LY*a¿n…Ôò)|N³?Ä*}5?0/Ç•õ°°޾¬¤8öÕÕ^0à‘ìj>à^Ñqµ´ðôå%ÁÓÛV¨Èà«m….6€Éó‘k„Žb«oìº4ãî–ÓFÕ“¡*FF_³‘]WcÊÆÂŒ»[Õ f¾Ú‚¨V°Ëš¤s5în5m }9I1P_.O ðø@‡°ÐF›-×3ÊüÒ*õÆX±°šõý¦•»œÀæzƒS~OT^â–Úú™" Øþë (¨‚$BÓž•àV5¿$¤>Ù=  %þ¯ºnó€ÀZ2†|òæU'ŠëÔ´‹ë ׫![>®.ª"r5‚kq¸žîS5þªßשy`>}ó€ªFó€êvó€ád†;)/–›¶`ÿh­‘ÿ½æÉÞÅÒúX·Äï‹}»PùCgØu ffÛ,”K)¯çS÷ëf[ðÛúŠŸ@Fq3¸?l6¡,çnçþ6Ø\]œ®ò¤LèÎí&åêFÍr)|ÒÏ‹«T endstream endobj 204 0 obj << /Length 919 /Filter /FlateDecode >> stream xÚ¥VÉ’Ó0½ç+tî­^†Ó@1lÅ’3splA\8vˆm¨ðõ´,e‘â‚’ƒd[ê÷zo‚¾"‚^ÌžÎgW·‚¢ g1‹Ñü â‰À‰@‰H±È8š—è.x2¨ÍBmÚ.ŒX’ÏÚ¦PëP}÷ؼù¨j•wÊIP±šÝ=TÂû׈`ž¥èçxj…DœÂZ£O³3b‰îWL'Á,æúVLÑ>œ¼üxPRœIÉ´nžLxbô’˜[–ÿƒî"IHp³Xl¬2ü¨ò¾jk«¡S¥ÙUYûee¿•m1¬TÓO“°ëÕm,Ž"댪zåÒ’™¡eâÇÞ,óÞ»yâÆ‹LiX:¦|7¥ ä> stream xÚ1oÂ0…wÿŠm ܳ¹Øñ j‘èÔâ 1¸Ä´H„„$¨¿&C¥Nïõü¾Cø„5[zöôB œtFðG°,•’Ü|;þ*tÁc÷»¦smK¾j.‡ØŠ‚ý,;ïñC³PRk©ÄÞoسgW¦ÒG*“´háP³Ý¡JþP.\ ßã«È”ižaËÞN%óWVAR›GýÉI©§ÒSQjOƾú #œ¸cg¤Bй!Ç··¶mîæu•×UUá2¹Ã©ž¬£PÈ›®C?žåÁ“ÎóäyYÐ endstream endobj 213 0 obj << /Length 252 /Filter /FlateDecode >> stream xÚuKKÄ@„ïó+ ¼Dp&Óž×UÝ,îApÍA{ÚU\Åø÷í$²ÅËÌÐ]_uõx<Âcnü¯û¼3u+×Hdt…ŒŠKÝ}uu}9»;]u‹X·M9¤¬°Œ˜-Þ5”&n90u#Š+‘ã ô°Ê¥ò£h/ H´E®„°ïÙÀ¡bòq¿þ|z}±ä'Ó&˜–âš”Ô{Ϧ¨Ž}†¦I¢§äˆwÍþ§¸œô–ƒ¯ÒцÿݳμÒ§!1‚8Ž ë­éW-/ÿ’ñ5ж¨ñŒ[s³ûð}ôÀYWg;"ž pEG~Vr_ endstream endobj 227 0 obj << /Length1 2832 /Length2 22313 /Length3 0 /Length 23860 /Filter /FlateDecode >> stream xÚ̸eP\ÛÖŠ» xãîîîîî4и»Ü‚wwî,!A‚Kp‡w{s%çÞïV½÷óÕE©cÊZ{WS‘©j0‰Y:™¥ݙؘYùš@]W ,ÐÕÉIÜÉÞÀÎÌÊʉDE%á 4s99Jš¹ù¬î6 w°³+€••‰ tº‚µ–s€ÐÝLÓÇÈ 5û ¨:¹¹3™›¹Õ@Gk#ì"áäìã ²¶qÿƒ‡éw €•“ëo€ß<@ow £8­Ûï âÌy3 ;'/7;ÀÌÑ Ï¬Ä Pvò AZ'G€9ÐÆÌÞ àdõW- )u €ŒºŠ–ª3@tw4sº6f®fî@W7€œÇÌÒò¼eÍš6@ðÇÌцLQÃÃÙÙÉõŸUIhhjÉ0$Å”5¥@mF€Œ–†&#@Y,üKó›ø @ÎÑdöÛ]IJSLSOUŠåw7lOpNÐo¦ÿU5¸ÀŸjÀ®V®N%ÐÚ¸»;ó³°xyy1[{¸¹3;¹Z3;ÛÓýN i×àäjÿwÚÿj±‡£%x0îàBþ ð{ÀE¸—À¿ŠÿR*‰)ËIKih2»Åô»áLMžÙÝÛý¯RÔ¥Ä$•¤þ‡ö7==Ðí¯iýŽd 1ÈÞœêð¼Á|À)Ýÿ]3x,î¿éÚÿƒ À úßűX9»±üÓÔåwLÒ*ÊšLŠrRÊR‘trýÀÝÃú·ïÿ'Çÿhœ™Û_”UUf GðΙ9Z€ù¹›¹{¸Èÿ’?@Kò´ðpuý]šÒ¿T®ÿ®î_Ãw—chï`æõßkkæèáæû·iÿç -ÀërswûGDà?;m' rüÜoûßÅ$ù<\¬vð‡|†¥-%œÀ¼Ý~¯„$< w'W–ÿ{îí¼ýþ‡Â ähù»ÅKg-G‹PNòŸæ`Ò™5ÐÀ º€O±… Ëï„ßb¶ßbp+üœœVfönÀüÉÏÍ̼®À¿¿+þ!±ñ,Aîà¾LþŠ.çhåàû‡Ìä_ªní_7ø³tr´÷o¬‹²“;xOhÿÿ~ýki{{epÚÿ3ÿ64sÙûüÓÿ²Òþ.öøƒÜ¤AÞ@KU»…Í?¦ô¹œ»ø|‰9ZÛÁþK¤õûƱðEúý 0±±ÿ·¼ãvŽ@777ß_* ¸yÿE<Èß„,ÊzbÚzŠ ÿwÿ²“r´p²9Zƒ—›`æêjæƒÄ ^+v..€ø”X½ÿÚ; ³£“;Øàìáð{ªH¿wƒ› À"ö[ôÄ `ÿƒx,/€Eòâ°Hýñ°X¤ÿ v‹ìÄ`‘ûƒÀùþ p>Å?œOéçSþƒÀùTþxÁùTÿ p>õ?œOãâ°hþAàìZ8»öήó³ëþAàìzÿF|`K³?liþ--þ8ÁÙ-À7Ík6V0uË¿A6 ðß2ž@ìO‘ÈÆí–NB4A£GŸø^ÛõDƒìÝCôxÆ ¯ÔìË‚½ÜöÌ·€gz㪔g Gœ[Ë·ežúóÉÎc„Ü‘LžŒ¡,ƒwNÑ{xÄ]¼‡’¨Ý–Ûû긨tðÜåP–‡5~J²‰Wëíð_Öý9[ÕTí`ÖŽcù½ª=**([^Ö9 xS¿ ¶™ˆÇðgÍõÒªY„ècmà ÷3㺷{@Ö`}‚:j÷ïïáMR«YÅ)(‹j " ·Îà²Î`ªâjXÅȆª€£fœ&‘šyÓP›’x,SàÖh÷™#êË#@}ÝmìLÒ4@€ûLAî|Ñ ²‰ *Ì,÷›Sš*Z»g£ÛK:èR¿2é>üq3á8§¡{sµ­€Œ°**9O¶Ùµ>ªøNÝh ´Ï§¡—ÖPÍ)«å$DÕ»«Y?ë½tÈ75›f#mªIü3¶ºþP̶tÃÞ_Ñù2Öy,P7ÐTjHÓåÏ£Kk-z—m$lRìáNOÈDÍmnàû–‡TÁŒUjãZé{6êçà9noFÊŸou •¶‰Héð *÷(¯‹ÝŽ?w¤~`¾R"ãß<Ú«)Q”—\‹êرtD¿V]Z<~ ÁP­•ë(ýºû…žÿ⇃²jåCÌÿöK(¿²H;ÿ­újÉ´ý» òÏ#Äh׃Ä¿>Ðò¤WÖ¾s§lÞS —þdNQÜèSÖFkÚ¹ÄÏ,¦2´ý@?Kåû¨Õ$—ôzmµ_V{‡*A€=}缟-ˆÏÁ½yBV)žAq¶øCôÇO™á £·ìç°Ñg¯ùÄôb©ÙÈ›e·ý¸ÔèÍ0ÚP·#Ñõî°5BÒăü|ßÈ'rX„   ð.rûÑR¡)¤¿ø'ôIPèåzè†î«•#¡U/ëÕ˜™<å`¨ù¡’¡`Æt¹#E®s¬OÚê(àç¿ÙX½ô«žz (¹~Ûž}/–ä¸ýÔÚFPÒ˜ÌfYpGAAÞMáÌye9ò&3ÔàdÛ‰¨Œ¸˜))5Ì„Cô4ûš;Ö;"=˱qŠí^YÛD“7éºyâS¼ýޝOáô5Å@vJ€tÛwŸ‰j 4B\bqqxÕö'ÿƒÓ/Ôì×%Zœ‚/ øTì2ö‹G¤ú×ðãáüìƒÅ[YøƒkR2ÕæR| nŸKïnõÐÓ¼7Î7Ú´æðUL„OGf:!ýE- ç%–`èø3לiN˜ÇÖ!À®£_aÌUv\0NÈñu+²ÖüMLc½¶¯ªQ‰|.雃ã8á›gÛËÔÅÎb « ×9£xÛÕ QÎM·óù¬í›uÔŠý1)&Ñ c'“‹öë* æ.Œ0fI€§â'jK!1…»Þìz韗/+ïîCï' 9Ý=Ó1]F9³Ï¡‘WRÍ&_÷$öY—f¦éµ\s"Œ&‘CªuÑ Ýe7!P‹xãÒ éî=¶¡GÔî4µ“ ê è•+.å»ûx<ýýXjk÷µß&Ј›frÍU<ÍÜü\£¨áÈtƒœ~Ä΂pÄ«EaFpÊ}Öúa<¡öç¼ !yÓ2b¾O_­²4#ˆ|á&×ÊÅ—ÑóLp§€…sÀÕ–ãK/*£CZ”Ën‹”¡Y Nys…9“A „¡%„l]BÛ·õÏôç[u•!ôf;«mLÛz €Òó{EÇZX7ÜÂw±Ægs%!B[SˆcÝkfª' zˆéiRyjSmuÕ®q`„Mðì]MÒ÷w7ñàÚÆÚ*úáüWe¢J#e.@0uµ–(Û‘íÁÐ@áZÄ¢$.Hù©þ’ÔѬœ}³±¨ß”H纭ÑÅ_Êq)}¤c-›»‹#@9—wFXzû6Ÿá3SÑÈrÓ/Å¡ B);ɲAë,côÎÖϧñÎ*wL¬xÚ²Pù»†~huŪp¨ 'ø“£—£UŽŸ}Œw¨Ât¼­øs­¤K™ù¾À'@÷eN(K¶Í¥†%Åâø—¸d3H·ˆ‚¶»úR­ÞhĦðmù ýD 5σOfÇãÀBMâ&òó …4/hј/½í.‡³dùÕ9c%™òU{W!°òÊ'q$“qÝ Ñg18yGï<Í*|£j¦ÇF?4n¬‹a„X¼òg>Ææ±OÝ0[ó†.›’¼ÌÅ7Ë¢³Üœ,^µ”Þf®«SxUEÙÌà+ëLvÛMÉç²~6ÀM4ÊË•2ÞÂ~Ô[’ŸSñŒÚ&ýê38¾Fh#Q ´“r±¹8âWiÅ áê¯j,¶íiãyöj`9ˆÉ ê¶¿:Â¥ÚW«ì£ÌÕ‚*6*4ú©áV/W¿Ý}À¼R|YQ`Þ°?/.xN?¥®ÿ b\òjáÉÏ&Äag|¦ GpWÄ_‚Såª3x2ŠãY®ž’=•ãªyŽå|Y--n·¡rBå÷…¼(6ZMvW$f™×kaùôÙÙ\÷¨­ìÄYáZ{н GU¨Ñ‘}%7ÝUúâ׃¨ÙäýÒ@Õè–Ê›Ó:˜õaа󘑢Ç#¿– ”÷^cíkÊ U΂ú…ùÀ}N€dI‹K»[—æÖ„bºçp±°sýPíL PËäwàÃPBz ¼up¬ýWøž´®»0Ÿ+ì^Ó‘/Tuqôy5""AëNþ†ÔývcŽÅkBû ÙËøE›o Êý=®â5Ë ‘_­m:ãÛtÚ :6y–”õvÞ¤r·´½Çl·ßâ^X"àJÖa?±FK)ṡ™¶=ׯú™5{ƒò~,†p\扛0ÏñFã0°ª‹&ÍgÝZ……™wèƒsE†SÜ*ñçÁ7ì;öY¬]ÛßÉ’ h„i»-©>!LQ9+ý:ö\þŽÇ±¦õ;Xš<}¡º”é*e^pàˆÿ/gi«(0`̃Ÿ1ÎCõ踤î8¥9äÒN_Ê`ˆ*c¥ÀCÁž[œ`嫈È*»}þYtr­»aÑŽW½MÂ:¥û½™Ñ°z‡³zXÈÐ6yjÖ!4d~ŽÖj„…/ Mv²Ôràq8q'S´Q} £lìEDòQ‡¹ØlKŸ2=ØgóÏįnr‰KX»ýEÖ½*Î)7zÉ8¾T¬Fo˜ˆÌHĘ ìP¼†² ßJÔ­DaGÅ@ D²]Æ ¿uòžHez³•™óÖÜîTi*AçGr°x¶49~d9J[ÆM¡q<ç±ô™rL·‰·'_3™í`†¯,÷EN™Åw/S†+À+S ´ÄÏ~ïÈãwZNuk%|ç|…¶ZœÌ‡v"É¥¢¬½Ü[kS„ºí6ò£1˜'°~uï¾Co~ø¦úÆÒtÏö³¾N̈ž“Ђˆ3îTÝ©Ëß'„;Cx‡U¶È¯/‹ñˤé{lœ± €¾H„õË ƒçnŽ0˜­¥S¥fí9ÙçƒÑ€ÁÀŠ’õGœ!-Ç2ï`,b}ê2•mYsFûåüê•3ß_iîk¾Ã šÓVKœœqÄÒ°D¼ª‹Âц~žÅÆïŸ26’¡C.†ÇTew/Ór÷ÏxûyŸ¼ i8»î8æýÊ[Ís®ÁÖ\ŠÑí×¾»ûC7}@–µÕzkÝåÛÆk¢%ÍÛ·µ›ÛÙÏêo÷Ó¼ \¥©ß&ÊUän¹ dh«þ”¿íÔÚ¥Ž†s'øB³¶óD­ÇŒ83M6WüÞô>ïܺ9›!Žñ<)ͧÿ¨÷#Ü; T#2ô#L÷ï\E]r. dêh&$æ#DdB¹÷­§)c'a¹z'qj÷_c- ¤1,É®!\3·7|ŠÀýõ?Vžq5±¿Š½·©C7ÀNuï¶ùpyÚ‡=CS!ÊJW5ÀEß Ûº’ÏdÁ\ç±¾1Pø!‡`ƒNb€»'œ:ªù›<Ë¡QÞš¸ àe† ŽÇ8yÖR¬qÿŽ\‰º &RO)gU)²ö”]G\.“=êçÄû„Y×|ŠM‚ŸEoØ…ŠÉ’зòfÐÈ1êô× Étê uHÏŸ[—âÖgÑÞ°2p¬w¤:é)±;Èîùà#¡×¡µf‡é„d¼·šèÞÚÎýš‹±iô}Š¥_X“«#²²¯ýuòË¥*¾WtŠ$£µ6ø‚…¹ Na,g€!ø¼«…+“¤¹W‰FÚ{³í¿‰”„Îi¯<#ä!¸d7oþZ…d»ëKOè:…õ¹AÝ -¾1:£üÄ}}§£PviE]ù2ºñY¹]|.šý¥Ø|‘£¦¼±ŽO–²_˜ÁôÆÆ^Òº?âP–C˜Ù`mЕõ{º©î}Â]Ž[ú¤ÅøÉJ”õ׌3Skõî°Äþ–dË j±0 ¼’ÉI½÷ ó•½=­ZdS0P:Fõ¯a‚Jz©øLßP- ‡†nÕÕ U ›U®O ;ÍfŽ/WÊ/0?!)õÇRºIÒ7@sӚؗ}ÜzÌúˆÿù²»@³Íèæ¸„Js K»Í¿aLú˜/§ ³¯(Êgé0s4–þy)|` #…¿GΣÑh¿´Ã¾/æá”}P±m³F U51’".O„>(®…‰¥U¿u‡åjn‹P‰ÿZ°QDIqÔRœ̶b$ÈAOïÇ/JY%UBdhwøé# šv"|'œÏMhí,ˆ~ àìÚíЉŸŒ;ø# zn%e­mN²æ[óÏ_ñ½cô+€Ï‹á=âýJŸYQ T¢Ku™a²Ä+Ï÷ŠÕ4cÐÆ‘øãW!%÷ºpÓ¹h`m6Lký.ÈXÝW.Ñ]˜î4ÄëŠbî •Ítg4qúâV¾T“™ÂœJÛ;Ùd²Lãдm´JÄ0‹ìDM qä¤ vU4Wîÿ#Eï3fBpbÃi ¿¹4.ú^r+ïB™@Cºÿ±²<ÖÚ¬‰qgýV` 3Ùá\kÒhßäk8¡P©âhëû¥.üO ŸÊ7;´pñÂ1)—ëawÅ$ãôÖ»ž‰h5g‡\NÓä·h÷âo¾'¥‘Ä9ü ë;3n2°,F”nŽq‹¹/ÓÄhìö1ÖÕç~: >ôRë(þÓÝQn‡„w>Ž8BYÂ$òêü| CWuõÈÌ™7jwÃJcßæOƸçL®D7K Ä4ô-øÜl 4ˆ†ÜOM¢¾++3ATݼnØùÒ>£¢Ï­)æ™v8Ç â¦©r­´ É6Þ‰\|Z¡ÜáO»ñeøìò ~pQ=Ø/øT™×½êµÀáÛX˜8ÚúùS),cd9VH€¾ènŒ,UçF@¶íERڈƂ‰ ¹n{aGU÷GÕÆûÉÔAéOÏ…AŒïbd0uy©™Ä »MÕ ÏvO*F¿/®í׃¯;© 9«0¦û?„er@qõal… 7 Y;Ñà È:¶w øûfk­Ô ÎçY¼–…Ñd•$ÌI@5qÃm7EºAH"•å|çë‡^&…rú:4ø¢ð. gØûeúά²¢|;gög¶O´sIVúÚlhÝæ-U›#$¶±­qÖ\ÃÏF™L°ÕØå³rL¶ã|ÇDI¨r{oD{ÛÉjå¶%ÂöeTZ&òˆêûËÑu‹Ó¶œRŽý1ðÛ ãŸ*'Vs@-áÈï ›Y H@Ëãƒp ’7thÔ†1Qذ{~¿Ž² Ó`SLuæÒ/L’€NGšV) ~”USèS½:Ë Ù«ªNV¬F?à Çnp+–Ÿ™,ï5×ï«Un—›Ê>Âʼ1>êÌÞÁ’"—iXüVË>ŸAÍÐdP‚bu!‹qCœ­|µý” ~ õJÈMäÀ ¤Úqì ,ÅÐæ—û*¬P%0Û·†³d(¢ìçÇLJ›Dpr^î–Â%¶9ûl%ÍoI$—šØéÝ)Âá…xáìÆzÒõ!!QÒBh‰¹\LtÅÛ‘Ñýþö)3¶nŠr¨±© ÅtJ@áÃh)㣴¾( Ù„ ½¸><µ‹‘„5ïW® ´Ö[¡Ð)'ŽàR’~¾z£Ò8 qâô8J"YÛÓŠ!A½(‚¯9†µD-ç­Ó"¶¨"ÃfŸq;TWÀÙÁ1ê4f…³è;o|É—ßpy4Äà㺤k†Ýµ6±"–\—™$ç›L¿·4YuDÂÙžáVåà‰ü)áaËñ¾<Ý«Cֈ份l2¢ô§:ãÇÀŸq:—䵺TòyÒÞ2[A}Õ@eiqìæ'÷•ÊÚÁæùí¸ÛRhˆ¬›í›!lt&”a¹æœ1}Oß)s)L»V>ÇüîË®óçø“®_ ´¸ù¢i~ñRΓÀ×m¤¹Uç*õá*42 ÛU×xjÁ,.ïSX=ÄX Í7Ñ×VVP†á ´"B–kó=zW=a­Èæ AçÕê&/E& ÌQ.{Ž‹©ðmÔãM}øÖéTºþ¨_€A²fÆü¤«·!ŶÛ«­áÀª’4ŠØÆå1%K5- ²ƒ¹‚ß÷…î4¼t&UÇ„pëFwÞ@BNý€ÛÑ1îØÇÄé_zŽ¢ê©Hƒó“ÔW£a'î~íØáAQïˆÇÐúŽíp¤!Hhç?̧¼é‹öÏø¶Ûñeƒß•u«kH-Â¥}^‰–VoÅ’dé^ôE¾=kePìcœ>ŽiãàRç‘áœxÚðæ%×ܪ›üvñ/+Ý…äcslâÇÂÁ¡Ôò_wž´z\Âõ¼S³{ÖVëˆWn}Û;Ö½•]{T1€¥mf<±¡« ¥N~/jH´„w‘^R7;×áߤʕ Ídt³˜„jײËøEeŽ?öˆIb®e¡ßù gåŒCJ‘m-S(·ã^j0ݳ).9©»å·Ï¨«B¼Ù¬PO5'©¿µ¾†^òÄ5§|¡¢™‚c%²$–ZNDˆªp‘&|g‰7½ˆ`ºþ‘÷UÈ`Í’kIãʆÎiçl ü›ã²M®Û<¯²ý4ä^”øÅÏ=嵨Ònï]˜–îÒ[CÎ¶Õæ¯s@Y—e–hVskÙ!«±èxžÁíˆq5 †ïOóä`ŸæÜ‡§8EÛã·FvòÁ}4;çÆæüéŠÒ>¢}‰Õ~]nC2$zPRqé‡ÎΗSÍî§µj‚/°Š½Ûøõ˜© æï £*r%œoiŒ–3„wD:zªP/î B(vÙ"þáolxMIP¥°L«A°Fë¶ŽÕyæãsH½Ñ×Ë’[ª@"·È{çÕûèvPI³ÊÁGÒçe®Ë¶0ƒqÒ¨E%a‡¡QØì–k¹Ìª¥£ÐKã qgÖ’g­çõã“r‘ÏùܹnûAXµ]õ‹Â¯U­Ü´ñ]Q†ÒÃ.ï26*>U]æf{…„YçXp_¼^éˆ3OôZ'Ÿ/ÐÎøËƒ¸µ|tˆ÷œT‘<ÄQÇ)ûŽ·K! P-màdïV¯|3r(ªb ¼øm¬Ë±1×’à ã#ròº×ψŠ_Â0ǤázÒJÂë1ßà ››Ân&Ñ|ãÏT Kî·ÛšD(²M4UÏ›~o…n´å>).jªÕŒ ´ å„YïÀ7o ì*ì 8'fåÒì„«#û…ëU®qŠ:ÍS€+ó é^q'hÒÉ·rÅeO3gŸé«ßI®sóÁ^²áŽ’ö5êy"/LHfL`ØèZPÓp˜¹pïR‰+Ê ¦±gð(D¯x¶ú^Zë\‰à´ù˜ÿ9b&hš‘ëÝ“˜<ݰ‘D-SP ©CìÍÏ!„¼)fmŠ:‡®¯%q”¶ð«xßû_»Ï}Ù²”îuFâè‡ÕÝM¶Ø_Wvûü‘¹$e>²mÜcuàãw¿ÌxЉ„dÂlΚé^‡AAm÷¯o;™jm$ã&ešèw߯?Ëʸ½-1@‡(°4WŒþÞZó¤Ôæ8cX¿žÙRËË¥øiÊTô«T¶ûÍÉÄ™K˜8³òÐŒ¨Ôò<ß+7)Å·á¤eNÞ “W•(Ole##âR:@+k?odbvŠÑ´;!ºO8åÁrd•F?µ®ãžoèGê y.¸¢(íŒÛ“ã´©cÅósî±!‰¥[œÝÑÒ&c û×®šRX î#f~­3cà"õ”{âl¿¸Å@Cg÷tÞW63[Ñ -‹¬6FؾgäÃh™4YO»p‰8 1榀étasÑ:u‚êµîvÁ]~'ÀMEÞн›©×9Ý]æÒ, sù¨÷»‰wÉr.xÂ1azWáÎõ­W¤KºÔKèJð|yf7•Ödó‹~’¾{£»÷4O Çqº.®©`¼çÖÀ¥gìŒÀ[üävPqë® siTßa ¯LŽÃg§a"Öןßh+Õ~¨cÖÌ¿;`m=ܸ}˜â6 ÀD ŸæNÞ>Û«m>]{T­ÌÒ C[à$¿µß…´°ƒ$w£ûåŸ;"\qï oqÝ(ÒÔ»“"ô‹âéøtÅýìžr&C¹‘òýx‡x;ù"‹%4‘î§â—mªÀÃxНYÓ•óÎ†È 3glÜéçm$æ§ÏjR€5k#x1u5ùÉÂ\†\fÆnA‡¯á!/™ñnÁ¼Ä®Úƒ“œáW XÎáØˆáªŸÙ"oc|ç+è. ¦öt½³g÷yüÞÞy¯0ŸÒýZ—ªâuZTÏd=E¡îZ0óCp?,?ð½:œEÊgÌsUï%¦ŒiM“ÛßÁìgm¤L/Î+Ünu[e¸Ma;ôn4ÐÀ_»q·d¯3êÔÔÿæ‘’¦ØôŠÕæV•<¬§µ9d+ý5cÏZ…3â å÷4Ïëü1A bÞw2¯¹ßuß)ó%ë~ѾbÑ¿)…Ó7mhÈ|I)ð°9‚Ò“ ªàå-vÍFBsQßçÒtFWâþÜÕ¯å5Ùý†¾áo÷1£p¾­Ù}¨Æį̀ù¹šÐ•ÙH;š^µ'.ðS}ÝÓɵt?ƒGß Àý†…#tpéB…îø³:D‡Ï@òtâ.7a†ÃBöäSS¨<ë)ü«óÑŠ7šzCdžÈe`Ćz´ÏÛˆrXÚÔO¹µ¢ÌŸã«ÛVÆòFkÏâŒ×܆eíù!àìÂõøT‰Ù’1½UÞ·Þ_§»¡Ó¾È…f j&Sa–wXÁ,ˆ@[Ñê-öß$Q„TwÛ›¼E/@nú’^ÞUEï·‡ÒC!ºOãÆb僷‰Ì(!OK¶æ¨æÿyi_­§þå&ýÎ e ~gjÚ_oOµ éqû³©¸·–aÈ ‰Ý˜$9ápÖæ;VWNJÇÕ¹§4™#Û°¥ÒjÓ!+A{b'³Þ‚ôÉF^ô™·5R3ûÃR]ØŒ·bµ~“/¤¯/‰œº„5ä*q­; ‡lÒ ì×§>ÕxÓÒÏ ö ã3%P¨U¸æ3ÙoÙ5ÑÓ’‰£ºÛíãµD·šóI¡W1Ѩ5c#äÙX‚ÄEHdCf”Év8‚Å´½ôÃUí:–ô½ø%=„¹£þG¼ð,ŽX‰Ôâ‚mû ÜÆÖ~x>SdRô_G[žbñ4×_wÝ’úùgõï‰rz`‹,E%¡ „ÐèO'§œÝŽbZ0hÁ ÙWÏønv´Ä•öÃm8Û\úJf·¨¡¨<%wŠE’Tn#L1{-ˆÀ&ÜÕ…ã\«»³JFC;ƒHÁâ»KlE9Öhôn¨­­M'D®dÚ†XJ ùQ5­ê%ÿ6…J‘9¾ì‚*ë6iÒrÒo!"¥5”ú‰§mì¢TéyÿHÞîÁ©]eŸËЙeÛ¨èÛôcp†o¡¹Á¡D7ŠH)gÝ›U;¢ÇÞ¿M8:€4û‡éI\5‘äkräÅÕ…¶ž†-ËÃÐãbgˆoÀsýCõ’¼P’â¯V¾ÞŸõŽŸmJPä "[òmKéÕÇÓiw°˜èK 'Û*gØg¬‡IN)lWÌ™ßÕ]ow‚ü ½-kxˆçî&ñíÚZe†û‰1 ¡8!ž×Vq\:N¸Öý’ºæ'è.PæšñÕ!@8½ ¨ƽþŽT1Õ2‘#_]W1úç[?Ë™Ò ¹P“¢Õ=¿5|® µëvß§±¸°i¢¹ÏW*ãŠ79‰ô¥z¨çuˆ­¡¢@qyô»ü_¡á/ÎDgýñé˜ „íÕË~ðì÷1Ö¶µ•ÈÈyY$4Ä .BÃÚ¶i?¦dŸŒ?ÝâI4z·W¥ÇHKÛ$0þËØƒèþ;† bçbÜ]Ûtq—~òÓ¨ ¢dÌž¶¨,¿IÈ'ç]CžSìá¤ÈÎÝ$ÈŠæ ¸÷vì$7âAÇ•ÂÜ¥³š‰SÌ1±sk,¨gB õÆ1IÍ$sqâô˜yqvÍ.ë°ºèMÝï„ÒvÃÁåk!¿,ÿª#^ÌbI™YBì{Öb °öQîg2œÖú¢úÑÝ’]Z:ÜõNÞ>àª4¡ÅCôª'’g-k86ÉØÝ¿åÝ‘¢‘nlíGœül/Üâ :Ä^æ»­æÈçãWªUÖ†êüz+uû)®Yw¬,í-«O´"PåÑã[¨'Ä¥¦O[‘íŽ|‚¡r¦Ë;$0¸‘Î 3ýZwßHnöÐoQzâˆ$ï…¹jeaö0¬•“b+6+°8 ʈíD±=êMžd´ÐTÇý¥qÆwG«Þ åe¢ü3e™Å§ÛÈÛ¼üâÞtH¬J£½ ,ᶆâÈ[JvEiaÞ]Q’zRÊ[Îg?´¸4ÌóÅü/¬+ÁO Bzƒ0x6ÚŠÞ„cÍÚÕ ›ŸïJ¢j‡^Aþ†#©ÿã×zPã͇Û-lÆ›Š/æ2(9âÃK|‚áÚü§tgê'Ø:é6Q½ú‡N_ìkrŸ È2Ñûm½;¨¨ËùÐaDÞÐÔ÷LŒ›¤§Då*L1W—óŽ!?Öä:¾Ž‰»>CPëÃôâûw­4Ø—jÇtáX樂ӮŽ(>_.3}韧nºOŸ‘¦„_Ÿ‡88CÞž1š¢ò÷jÓi®ˆ´¸(ëc¦*=|U'òœ­¶”¬þ|Qvã੊: b5'Ã÷#ØÍgÆŽ¿¿!šü þ‘ÔŒ¦² ¿ãÀ(«io#-[ÔX°ùÉ—õ.ÑÎÈ÷úçÎEÍxé¡ýǪõ _ )Å/gZU7t– ð•À÷P§w­é4ZNU‹_\ãžÈ4¦fι›ÌÉVzB“‘™[ªú£Wo ›Zw z/Rk‘w™Âkl8«RUZi'DE™, †µø Y:)ñKñeP—…Fø°¾JqT pê›7åŠ,ð‰Æ¥Ñ¯ EF Oµèaãs‹Ÿ›?aïF6!ã#~Í,»{ßl™}5㆛Ÿîï§£d…l IöÞ#ò'Ý“ó—þ̉7GÐéû·¤Çî‹k3Y^^–°’+Ø”oï(=…¶ ôÝ´û„ª] :=ßÌ ùÆËÊ0™¶F“þwHµ­´‹ÝPñ…_>ÿÇ­'ëbrðs¼´H‰­à³ö×ó t´4¥—¦Çä—ëR>Tù¶¢#Êf_Ù&hïÇ<ÌVEîó› ‰'ŸîŸ³ßUs‹èõó‘nì†â¶á3ßK¡<ø¿~ƒûD'þÀ-§þÁÔÅSýÐÝá›þÔ»þçuCßüÌöMÝ8^òßÇðÎ5ºãC¡A~ üߙּi;? XCo9,^Ò=©'Ü9—×Û?äGt]Œ1ékZ ¹´6¿‡}lvóQ4G¦`}6üØ"ï’q…ÖõœF¨xHè¶Ë>ÍÇø×ÕÆö-â Ž!Pøë!4—¦²#Ò5ûpQ€Ò®›Ðˆu`pÕÌS<ÊûçG¼Wyvå鉀NVüúY'«4V‹xròXŒ4 OMÎu“®â×K±8Çܦ7!I(i.Òn¹6&µ­më ÃöóÚíú'¯6\Ïw}ñÑO ûƒÄ‡…#9*LŒð´;>¢nÃñ(s–)½X¥žAai@²Y‘­"ÂðõpÞ>Ýc…Ï''i˜¹=‰‰êùe¹V|ð\†[ò1ÄÍZC½¿¥¥¸˜½Ÿÿ$™u-\òؘí¾Ö'e·òqð­?÷ML™•´í<Õ¯°Ð%²‡ÇØG§ŠÅzƸ9úzC©JJülØ€zæ3îâ‚í‚àqI Ó"Hh¶®¶’Õ=©\ˆ"Õºâ+9Rq.‘¥½–]_‰Š†™ƒ …«©ÿv}üçÉÇêÞo7‚Ÿ}wvðú!ôH½Éð·†ì)‚ž¬x,ƒLmÎ)Q)GïS d‹ÊŒxÖ¶Ü ¬!ò÷%!V»cb‡ÎÊÖÅTvµL©&‚NÚj–9ŽŸH—÷JZ…$®ÚElöQ™ò×½•Å#ggYVlT† °„Ùž âé!R?õfÕ©<…Ur,þx&N"Jë7ŠÐœž3oÞl¡-Ìb˜ÈÒ÷¡¾“>Ø·Û˜rÂ/:ÿ$ê”1ŸTÌ‹TñnœºHb¡JÎÏe`KìÚäÇM"uËzNlÏèǹiɈìÝ|4ôgÝÁ Ì-?µï•'‘$¥=[‹}}²]¢º‚MÎ3˜3Òö&¦²©>ÑUU•bTØ`üج²S;ÒKQtäRûV xàâdDp (òì-ͼ~Xµ ³ì1~ñV9µTz^Øà¾€B0NªÏM]«ì@yþë×õxðÌp´×3 6L}¼b^Ü–m âI®ó¹=|†y>”ÿ;µMr3·/‡rÏ´(q…¦N§$ez1€NFÒ¯O¦Îßp õü­9ŠA ‰ß¾ú¦¶Zcs [éz?8RÇûzê>Q¾>š PR³0 I’§û˜l„‰?ª”Þq$7·(KT× 62Ôè51^ê;ŒNGä)ÇsÔ8›Š÷z¾Cƒ ¼]ëd¡jè8YŒõKÔ,R„þÙ—=Â{Ã’¾†µ¬P? gL#—cÇ`z̹»P”ðaS° ªß1ŽzüTS¥ Áž)ï?ÅÁJñ(«Ö^¤É×;q!ŸOaÕ ™Hðw O/׆tì<-††¢…4WÙß[jž­»SÇÕ—®Ã†Œ[+¬A§›\‚@êåÖp‘g³MDߌŸÔËw"fòÏ)ã.Í-,\D×~BîÉ¡b)Æ’x»?%obMù¢Éß~“çbe©ÀgÕÐnV977yÑó–|Ê›|IqžØˆÖAê§¼²Õ¹)$ßbñ—j5åClH<óúQNÀ‰ï¦²€a|üA­™ôК´É°°êyf¹ ¡òˆ›|–üK{*2ˆ@*¬˜¢+°K¨1’µPðò¬rSG{"/^JsudO.2ê¢-yb˜&”¾›öòW( o£ØL¿ ÅŒg”e¬ˆÉ*;N}â‚y …ÐKHð\RN©5ÙsžîJûñÓ ¤&ÌÐr¾”:ÊVÖôm-u nlôáÁô¬'Ô˜@º×ÁLe¦V«$‡sŽe+µ8×y?M0EïŒùÙ`T©,þpúaý3Гü¥UЙmÕc>‚ý½‹ézÆ*Úý=I(Ð0ŠÈÑuŸžYq)n¨ýCÌÖ €gsSa¶ˆò0.Ήupo!´øÚ£:d4 (Q].†>>*¤XÌ%bAh”Þ:]"w<›R\Ç=~ÒrÑõ®¥$õ²¤bÌB`a?n´{„Nÿ¡UŠ ~«|=âuVeÊë-ÙçºD¦±N°$¨t¬%×wê€HJ§Êþ 3Y6Õ¬×c²)âôó=3[ëö,! „£÷æUß¡ËÛ!r‡àKÛ‘+CÖ×±>§÷z|œoãtpÌV‘0»R ÐY¢u¥„ ÷~€ÇÞÊk8iÕ–ˆûL¦+r~k`'âYþºàRe9ïpìYPº¨õ”ï é{!ÿ‡nWMÛËŸ;\>LÁ8e½çºo¬‹Lµôë1xë$ôiê»U´…ƒ$`ä©j®žjq`ÚY “¬/»Ñ¾/yÁÔ÷ß’dbp‡w߇׽ÁŽóaôgçUŠýb‡ÖiCâ¢M—R%Ðà€ÆìíÓ¨„äêàµ{ZYóI]sý«B±ùºÞ*ù»ÍlÝéãÛª÷µ³è·+#5)‡‰PþˈVjcܦB/KV"¡ùW¨X•-Ë´£¢xß+èÛ(aºtiŠÌ¥5³ëZø"½}?×»ÞY ~U2JÀ†¡Ž›u1ôã%ø!çÙ?¦–«#hÝͳg?™*ò¢”X(­‰ý«§M#UÝH-f3ÓÔŒ /ɪø¤QŠŒç]Í Í“_Ëz&Q÷DZêÇÚOc½Bz¢ˆ?ô|ËJ7X»ƒñyÔGà'ŽÇªƒ3zPEcp¾ÆVâóEª-îÆÐùÍ!<Ÿz÷ß/˜²³.Üê¬'H¥—Î¥Õ` 69©¦Ò"xîîÚCä2pë±Àâè:l|ðÛ¾G-&6±ø›(v  9½-”𠤟ÉzõÕæÎ×(¼MüÓšL¢è,3¸™^ãmìy·ñD#ñp{1Ç¡??O®ñ@ô,×ÍÍÑ´_á$ŠyÕ5+I›A÷Ô¡:\‚‚΄¯ÈIBàÊ:ÐƯäY­²®¶PæFn³GÔÉJÆá 7OÚŪÄ-NòFV«|³à«Ó†)è#ðó[žÓ©ØÄpÃ>¡ç[š$8Óu“÷^íC|ŒÜÖ>Œ×úaCœ#9±²«ªîÖB¢p&û¾wøéJáD\ÕME‰¤ÔqýœÞø«ŸÚ£ìîsx.Ö>î×{›ÕšÍï)m ×w÷S!ðƒ¹Ø3&‘{‡˜¢f±-™ øHö”éqñgÏlˆi·^jÇø¤ð¥….f%‡ÆÅPËU¸ 8.ï‡ò“‹Wß| }Æ  ›Ñ1»æL~¾P>_@Á¨ì¡d¤A𼤂h E`úI={…£u¯Ó„Fm–á>Ñ+1Mus`!ʬ[â•ñ¸Ü<0Lþ&G{[ÑHR·«¤F>ç_•NUj)!Žíx†âWã= 8~ã¤%%Ùy±EŒL=ö:@S.ݼ€×îù"3ãˆZJB¦ƒø bgK)F58ì %µXWݩγÖQ~Å›ÁóÖø¬Ž/4R”î7‚¹Y°Å^ðª3e]Éwäivµ@Œ[¡ fÖ\™ÿ5ñ $>lÝmµQ‹+ë—%)(„[Îo³,Íò¦Lù­÷Dk¶øYÍ ÖĤò·XÉë…²X&pöŒgO³fÿúUú“Œ'–³K1"çý(”OóìRC²V_ìï>ÙÄA©Þô£M­#]§³^înL&¶3`ŸS'Ä™¯yï}P·í³†Ž¨‘ñNbXsìûÉ7g¹±uÿë·î!Óy_ Šó€$ïÊÐè” ‚ÐÖÍ/?ÑÆ‘EÝdŒÝu kû¹Ãüàë~¼Ñà5Æ|å$À*·Ì‹QfO¯ÂF#@eWë }"‹}j¤A¢U…Õ X =9Út%òÉÊíÄ:„¼aíTµ®ÔN>ÜçòÓs宄þÉU·D¸çu~án\iéYB™Õê‹=÷Ùà‘Ä-¥öR¸X-'Üè1º<é{7—òç vê7ã5¤…_[~øAÆ{ÇÊeÁ/×0xCRÏ÷þRÁ«:¥k<ÆŒù|ִó}¸³!mæ;°œ·ÂÏœ*ÅxÒžœ?»,ƒËZÿ#RƲ5tG‚ó|B Ô!ßLé:€R˜_.r5鱺åŸqCŽË¥ê›€}°©T…:¡[§a»óÓ°ùlûµÃ‰>XÓ`d°Ütf(¬ °«\Ó ¿ªÛc#Ÿ®ay~†T.Ù¤<:¸JÌæìÔtµä m| +ïC¼7¨Õ’,žZƒ}¬›NfÈå =_˜ÞG«QÝwL)$εVÿ±,pÿíEºÙ1eKøšôÐ×íu/{ºbÙxg¸¯ @{µùQ/BžŒì"ʼÍþx•¡±¢Ôcô’KôI®=tSÆ0ü41ú³4›÷ΛMÿÙ|!¥4ȧ^¾ÀœŒ°}%f˧®n?'WìZkmθøËfÌuò)ÌÅš„ÝåÕÿ™]ëU  SÖ$}z¡moÜÊΣÔÓFùÿ‚“繇›Øòf¥7›€9—q°²‘,‹àBŠÇvÔ¿Þ×îˆéŒÝ”‚KÖ>&•¹SœdÒÚ![ãCYìü)gv/&©ç±åS`§‹\—š“~7ÈA“=)ò‡³Ì¢h¡%gÐX×·¦$¢NšÝBFöB/v×ÉìCMÞÌ{Óï y5CT)œ…áy‘4€B%¤TIz|s‘Lka‘³6¬O[¬úcZ¼Ž€všQöÐ a†øW²û/@;ìø¹›(½öoü A•Òƒh×|=t9t1ʵ7§”9µèºùâëð ñv÷­§¾¯¤QOø;%¢Xž]ùÖúܰ6L£;×—B®·È ‡kÔj^üùÐe­ÔhÌ÷sóUYS‹ÑÿpÔ?’)Ä›Q«9nÚ¼Ð]æ’'¶¢9Ž`—¦d¤Ä³#¶­Ål¨")çç;ÉÊ^ ±²Å¬·ˆÆã1…É>ŽDæÖ\Ç¥pöá¯ÉEÔ¥’lÖ ÉLø¬2hÌh…«”à÷mt _ñEG0ú±ý9@‘uBlnËj¡HÅéh ÅgÙ[- W¼Ÿ‡ÃhÈLë+Ôþ”—”ð¤‡ù´Í8‰Z·çÄò…ù½aJÞh%W!‰¡“­8DŸ¶Ž"ŽjÉåõz{/"tšSâ%ƒÍ!•ù+C˜ú.lá󘬺½µÞïÿôÙyH´å\Áâ¤ã¤ßìB+ôº˜ƒf–|¡v£}ú×\Ù Ýtwàiò±î JÅ$`²§ô÷«²œgêÍñL “鯫'éû‹ 6³³E¯6) —;Úus[(œ,}$lk»ÇyøKmûàæs`M!¬a§]¾›“+3ÌáéæG:é ì_6¢Y|9 A€;Òây”ÏC’&ÀÈ9á“ùÚÐgx}–—}ÜðñˆBR˜qNÄQ«YoÄFôÓ›m_ÅáKÛë«™]øUÀ€ƒ@Cvchµš˜µÝûÌ ,Èm)Ü›u•• Ør®æëd EFS²bÍÂû Æ #>ÚÚ™@]«ç}ÕÓÿÍ+[€æLp” ¡fyj¿,ÿ¤’²R•gî×ï5`Zžâø6W.+ÿÝšVâ °‚èc.J‰íC_O„:ë âЇFáŠp•ø¨¬Õ‘uö„‹ÈÔéy/)„ñæD­"s›w IÞ­ 9­}:zð\+ÝÍyÒª_ÍH7\d K$#€ƒŸ2qÈtl3+è ‡{Y¥»ø<ˆR›2àÚò‹žHö@VˆnØÁá^p¼õÇX8¯PÄ@þbèâFE´—Rf‹|Qhð|î2Í·4ŠJ‹h¹GWL²ƒDƒÄ`¥²BšÔ›Ô`d\Çè& ¯œ  Çqÿ8¤VGÓ¨ñæwÅ_ÌÿŽN…—.¶ á/øÉZö\gnöGì&.LºBèUâI¦8$4Ü.1àÒ”Àlÿ¾ÙÒî—{³ ÎIñ¼—ó,”c®÷Sâøcªõâ†sé\©¥]/Œ×ú°³oùl"Ps@ú ŒúŒäÑÿ£¹BÞbðNo¿Ëa׬.E7'NQVNå†ù|ÞŽ{Îd_öµmÉYÞ‚éF|˜%[6ûg¯‘$ó\¿ÙXŸ´'h¯Œ¯ÑI J “L[Îi Dµ8÷e¬wß8÷ëWŸ£=bžB µH‰A-ü}‘±‰û¬FØ"N‰RßS?éËjë³ ~lŽ^ƒíN§ñz2?*_OšZÏ ´+ß+VƒX{rb<ÞÇ=?c çr ÎÐï¢ÂX»—Û¢â4?˜ ¡g•ð Š,ý^3hÜ‘ô¶Lî9ˆò4«öýšP{Ø; à™¢«;‚ÿ*w4l†¥ÑHpGÊÚ¶MSg˸2 .ÖÕëû¤Ù½ ­=®T®‹³ŠOºïG¾7ºV8èãôXŽ/%Ó?„6£Ïëž3Žð×°úr}™P#.øGµ¦¶á¯O°« çõâgÑüv)f‹O5„[DSЉÿÇ{iÕ8ésŠÏì‰Iúá\T¢LÅ—³•ß$%,‡ö35úb© ÑÖitw%Ø]M£;%=xôjôð£Š9(*@‰ðLî5À´GÄ:ŠÜxטQ™l©J.¶@òâIDWÄ2!J1rô¾¹·AŽ(ïYòØVÈyäì„üC²aáµ7âlš}ôïùÚFRÎfaA/†61e´™ßU®„Á†º=ߊ–,+€ž°È\WéH‰ÕŠðì69LÁ•Ùyœ&˜Ùü 0Ô/äè {Xð³§΋ÃËÄi‡cwÛÒ:Ùâ nô'D6H4ÎÊŸìº-ûÝÛh¬pJot$žŸ^·Ê7€žïÃ?Í¿ž—òOÐIò‹‚ôÂ×>AÌsÁÉöh“¹ÕXà0“»Î;­¼w´œç‚== Ú j®Õû##×#œ"SOîdJélW°ï’aêÓõBåу †%ÂÊé2‚iHö\†9Ôú„+êŒK<êu¨L«­æ}õ­y9äçT¾°.0¦xTœÙC"¨{þù¤!-š’T¥ f§ðæÑíuwÿER™”¦–$àúu™Ð–ü’„qÒþ)Lsè+PŠp޳üAÓjVw~w‘:þWƒWðÙM]yÐëNØ¢€ÑôÉS—fiqtÍiÈ«o³­jÅUuæg!õÃcN€Ôà’Ø±’â]#©}øæ ¾AñG–ñíæº£cdΑªઑfÉÎ=_n±Å×RL\†¦?zò“Íi\^©ið¡@|í«iº>î0—Õ±#Âé|Üu73©Nä7­Ò±ðHN†à·+˜èm訩#yÈÞ#ÇZõ0»¬õT¶m7Þ ¹ôŸž x£¹_KÅ!ÐŽ½?¤GPj¼ÃÆIî!†>LBmäXDTò»Üç@61úÓ(ö¡[HàRV¶k­TDQÞÔžÈõÚ¬«c`‚çï -É#Þã2`Œ¢¦™ŸŽ'Ƹ<íÛÆûÞ#¬Ä–ð@d“É|ÜÝ¡ÿ¹IwKÐWÄR—ƒß-äB)À슂æ 4Â3ô¤þL˜&7 þÙ“˜¡í‚&,P¿W¡H”Y—ÑV0ãüÿyXŠ ¾]ƒ]/&‡Ùav~PFm¼Sû—ÿÍœ ï¾9@¥ä+²!XÙKóE¹ î­·‚ÿ©)h ü¦.ôs pøIyÕÙÔEþÔd”¥m*C??Vewu6òŒ–ßÿ&œØ>IZýŸäú>¬þ†1È …"ÕÃo\ÝE%‘(FnW¹ j„Œî(3éá Ùª}gZßEª]W³ßÑyŽ-ÏÍ#×%¾—1lÒãÕèJr¯šf'­‰tH2ì½±GÅO»×WѸàÐËûj.C*%ÏK'iƒnܔϻ ‘ZÕlÙ…{^ÐÀ©ðQNE,Q0b¢uýOJwþOdDÂíH$/®Š®¬N7Ÿ½Ø.Mn,G›ÉÇaW'ˆ¢•WO÷Ç¥þ™Éäe§‰-]ýKeM)sª­€¬üý]ÇëŸ*»4ë5˜ñt„Ò #olzxÊÞ䉻 L°Ÿ!$íÔµŸ}iÊÙ±»ô<ÞõÒ¤\ÞÑ©Õtq‹œx2ÂKÂÖnÝ.DŽá¾b>Ý]«‹0sÚ^äjHéÄÔžqn‚°íjdñqd¼Yz(Õàn3ÇJ‡¢Fw“Îûýb[sH@«s:D]Rgi˜d61šÕ‚…ké ç½áÑyÎEMÿ“a‘ÎâoÕlÓ¾Êk½Uèú¬QGÖyWÇT‰‚$(ÿV¬Ê°9™Á£ìÔz²g•R%ë¿TPÖm0H;µ%ç&$æÍÖ.µ¿$öËàð©aUæŽÊ®fŸ–†ˆÂŠw«–Õ ` ï¤2Àñ¨â>4 m‘ bÉÑ]kyFPDbRfå‹›«ØÍ» ®Ä¤¡\Ù2¥ÒuìÌQ gˆÝ‡f[ñCð4…áþgûm¨Ì·çtþ€ÕpB8#ÇI/ëGçìüvY& IÜ E³¬Áhe»î,PÛDeoîØ?xXús«°[Ðô)€ÿÇÔ›ìÀ7-H¥±âü´‰räzeræÃ³?}4¿s­—˜wÜÚA/cW8öx²Dºœó¼\.…²±ÁÕ%ˆ>10ÆTA¶Èâô}H¸O)zòÒg'šG{À¢²æ&ò8<«]yÌx©X½78ty%«ö¤ÏrÓA— 'Õár”¼9õ=Ñàîþç89QHà®ñã]$õÝûd¹ÙAfû.:¸Îìþe7¥/Ѧmüу®{ýº}/› yäcZϳžâP­ã[D©… ¹è¾"PðËøÝ‚‘šTó“òߎkr¥¸Á÷*0üÕº®ŠJD':Ö¥•Ý`6à¿^ŠÎ<’…™aUp—žouÇ™ô7çOZÕ·äFÃÏ}OW7|n•¬;t†5–ú4% 8Epj Pv€¬£xP³ ¼ÝŠÄƒY‰7&ÇDg,T„:4„¿ë…ºPäMº@¤&¬=,?òy©"åÿ¢ÁšãŽU·Q=.ÿøì~-«}RFÄb270ŸVz–§“3ç¡)Ö3Ù$³ÇFŽÞ¦ï×½,3ç% '„‚ß_ëÓln`€úêO™Nkä6t[.µ(/;9YÀšÞ#ÛJÉδ´”Éz¹O î ¦iEŸ‡±ˆs1ÙTP mê#®òíUË‘¢=ðV‰{'6ö¸©¥®ù#÷c¨óçžl8=Ÿ÷@ÿ§Ó-Ž*¿Fq*±§‚?a"5àéøy·”@nÌR6ú›ÃYФ€–_P¥Èñ^O”ésé\ׂ£à¾ g$`€¹"[­öë4ÝïjoÛ`ÕZ«ê¯¼žZÑ…ÝwÝû]# ƒj9XÔÔñË<ÔuŸ‚íØ×SÐÇ.:R•F—.ÌJi.‘*1Ø:“Ñ{_E£X§ ¦]ÙŠð!î=WÚ®X LœQ;}Ø7¦½ÿ~š¤°žè­6àò°>½ðV…‘ ,YüöÙc ‰6Pì¹+xÅ•$TØ1}Ó¯Däh]î—ç[vÓ¯»³"sºwƒÛ>ˆK'ædÈ;î µãÎ3ÇAî”{ñóƒ.tÔXϧØ×Îóc)x§ÙŒ62—»ÜS7“ÊâÛºâvÛ á}ébc¦d {W;ñ¡†}ûÂ-ž½š:˜Å!6â¸÷Æ~9¹»ÝÏÞ$¸[¥4Åó¼©üñ$‚$çÛ½šûÒÃçã=¿û mîx@·k¡+ªãûîÆ÷ 4·­EˆÕÞŸ3DËW¦sÉá †¹œ`U’ä)a×”pòRÒ/¿ËŸZøÑYþ%ïõÝ|_¦ýæ†rUJoE%¤Ÿ ôÖâų Í÷]¤ü’QæLê“ééë;½N‹[ ¯¾'ã/ÀÁàûäÒE/ö]¤l­¨ú@L Á/И<;õxÆžš“Þ™ªñ(f÷°¶~ºÁeø‘0¤•piÏÃèš%ôîvV^R&ˆ"Þåúý3¨‹ j¥qˆ×rΡ uW¨ƒËn¾ñʸ’Š”¬ìj¥- Ó‚XbµJo‚kZæHhüjîÀÆvœ/´¡æ˜!˜ÁkSYü²æÔ]‡¯yÇì’Ýä胟J²RŒÞ áªÕ¨_qv0t¤Àåj~tç—9ýâÐ •2Kn‚:±Ô ²êÀˆû€¡³ F{œå] ,±’0 T®`¢Hvư|xœy^—¥7P´}½k%SÜYˆZñvWÒÔEÎ}l5¿Z“øfl Á†?& b›~¾ëüW£ÎØþÌÚÞÕC½rºßÞZÇŒIJ?ÉÕµ®žŽ0ÚÙ&Ñ»lxŽþáRnx^ÿ»þ¾X ¬IÌ-B}’”7Q2IÁAÒ4óí$þyC^üü's·t úÿ_cÒ *Ú×?GÍï¤ëÏ/šg›’òra€…½åB„!_•xýѨðP 9>SwÅyn«Âx Ÿ.â8pØ¡BÍÒö¹¢Ã‹"ñÑ?D9Ëq"M¢a»È&Æñ>¸¾êÚB¡GöÚ×(Ⱥ’M+œãT>ÎEæÖÆr‰ÂÚrŠ:âY§Èˆ|—‰Ÿ’ât|²53ðq´ãõÁ€UÐd­nšà)~híLô­.«¤=aK÷”©ÌÇc¾ÎåøÏíß“®c¡Z};ÜgEJN·}1þ–š™'Bôd-ê(¯²=÷(k(/L>û:Uö€´3Љ(9Fn1c)Ä/+õ­—Õážl‹tg¦}òÖ‰JépWÀ R ¾‹AndŸsû±’¿1ø±@/s§Ío:Žh/vpêà§Í»Ò©î ÁíôÜ/SêØ|…2ÜñøTµŠª;‚¿¨Îeùç=†r]#nFÆÙŸ¼ÇåÐiãÚ}¿§í³´ÙUÐ(£qˆ™ò‡ß 3i4<@ í¿ä.í»ÏPö$¹‡À§Ÿh‰WpìB´¨cpˆ&ºs([`Uå+o/ùTòž°þwÒˆ+EÓTß§úAhÒóâ#…el‚,$cn¡IBJbÂídô*¥Æ£úvclšM7 ó‚èö×è"aH8T¯±Ë çßÃR7‹7¬ï·€ôouÍÜB_Ãm¥Ð¾§+4—]”ÉÈ/ðš—Ó„Â e`öà‘ nd^ƒ¿ÐéöÒ‰’~ë¿ÄÃ71}XlÀóÇö|µ`™ïàÙ1Lóõ×ýc¾²!‚2Êä-y¥5&Îxíêq&,€Ëw7Þ%7ç{«'ؼb»|k=²é&Ë'¾(^g2ÔÊ«à¯]-®„7Šé8°?î7¬vø\E&z”¤kQ^Nþ/‹q) )nR1«Å¼8~´Aˆ‰u…8Z„¸LÊ}p2îWv'úßÈä¨Ï{·4Ñ$ëô`4ßùÉßcTôiôHe‚\™}ÌíÏÃ_JÑ EŠR¶Žpëª;UÎôÐo*1Ó<ÇíÑ@>«¨ßxKèƒgŒ²W ñÆCq^ bQÆ ­#ÝV¿1Í”¨è´ŒÑNwŒ•¸¢Õm}^W¶3Ü9†ÿÝyØl$y{%ܜ쳈­€‘FÕYQûá 2rö2˜¦ ÚòßÇíš endstream endobj 229 0 obj << /Length1 2145 /Length2 12651 /Length3 0 /Length 13950 /Filter /FlateDecode >> stream xÚ͹eP\á²6ŠCÐàwwîîî283¸[pw<—àÜ=ÁÝ‚»»ÃG²÷9ûì}¿S÷þ¼5µj­î~»ûi]µj(I•ÕEÌÁ¦@I0È…‘•‰… Ô–òtJÀÎŒ¢`;s;k3 "%¥˜ÐÄÅ 7qòØY\¬Jf.o&œl,,¼ˆ”) èô&5˜z€.&êž@VÉ_BììÂhjâü&‚,­A@Ú71°ƒ§“µ¥•ËÜŒ ,ÀNÀþ =\€ ç7·ÎŒŠ2dMÌlÁîζÖ9@–I  vcZhÀ €)ÐÊÄζøkBCMBU ¥ª¤¡¬FËдº€LìÎ@€™•‰“‰™ ÐÉà|ócbnþÜÒ& €ºðí2Y1½ATsup;ý3*15u )€¸ˆ¢º¨ÉÒPSg(ª¿1ÿJþ€z{Ȁ̭Mþ¨+H¨‹¨ë(K°2ÿÉ€àöæÓúÒÿ‡ê-À¿¢ySµpÛÿu ±rqqàcfvwwg²tuva;Y29ØÑþq neýØÉðvwÚÿ¦ØdþV—·@þøSf€¼µÙ[.ƒÿ De$%ÔÔ߲Ÿ'áŒëÏäâáò7U q‰ÿ‹ôWgÙ_ÞÛ4'ûGÊ1W'§?¡)ü—Èé¿£û¯bˆ‚ßÂÑ·óö5qÿ϶5¹:{ýjÿ{!ÍÞÚÝÚÙÅùÿÌ´Ýë­²Ö ÿ×Êý9ÿÇ¢ˆ¸<€›“Àöv±¼Í°È\ loÿ†ÛñOKˆ[¿ÈìäÉü¿M¿-ìòþ_ÅÖ ó?阻:0k€¬]2âÿTzc!þ‹g t°€ŽomfÅüÇùßyøÃfýÃ~K‹¯·Ø`abç ôµ¶¾Ý½MÜÞ:ÕÉèëý?ÿN!²rÌ­Í\Þ¦ÿm± þµ.²xÿÁ~Cò_¢v"Íß­Fû¶ÒÌÁ ;Ï·îµ@dV»¼õ ÍÿßwÒ –tµ³S|3@ó¿Ôè?›Ø[Ûyþ?þã”ðOhþXù‰µ³¤µÐ\ÙÚÅÌêµúÿÎD@–v@#+Û?˜¶ÝÛp¼-ë?/?"–ÿ½õ½™-èì àâý+¾%ñ?@¿ôd³†Š¦¨”ýÿÖOK€ÌÀæÖ Ë·¶ç˜89™x"²¼5''À›õm~Ì»ÀÌ»¼©\]|ÿÔñO§ð°˜Uÿ°þR¼Üf“ÿ¦XYXÌÀÿAò˜íþ›äà0ƒAÿsp˜€NÖ`ói°r˜ÿ›|›Kfwð_úßCVþ³WþŽË¿rðÏWÈ_ZÍÅ l Ô²6{ÿ# &.NÖz,oýÍúÆûýדÁ¿9 ü×hþmQQ°‡7#'+€‘…ÀÊñÖû¬¬lì¾ÿ¦köÝ÷w¶ÞŠõ_ôŸµ=€fˆ ³`3þ`›/ ¡%~y㥰”¼LGßqµe`ÒÇ[ ñÄs6È€BùŸ2¨òÁòÒ|~)Ÿ@…Ú”ÁØv/¿›’ËÇ®ÌU„7MüüQ%D~~ÕdÒÌP˜(m'£Ý—ýš«SÄ1™ÑœÐü ñó@Œ·µã>†môýâ3™~ióò7X÷‚iÖXNvóï ÚçÇÛ ]^ï±â¢MºE覌sCq~ÊÂ9tu`n;ÞŠ•š ¯õLn @,¶uã»7¥aÄɽâuN«â”›=ì² ˆ݆žYÁ¥f…¦~ #Î'äÜ\ÁB•ÚGsò·IÖî,µ°ÜÉ ˆt|,Øp ‰@Jt£1ö­9RPqÁNÌýæowfµŽâª”5šÀ½ÆœUWù ¶f®Žo«—»Rh«Cs­ú^¯(Œïì‹<æá¤=ÛõÎN*¨R*ìÙäz°Yu§Ž3ZÔ›%/»í%]B‡ßõw¡dØìþܬÞ2«Û¥>Ì8ŠåU b§]>O›_9$dû Ð,Åa°ÊØ(aÞ‘ÈxäXÓ1acbiÖn.y÷}ÚTVÝâ z.]ïø(­rB¡ VŠí–´Š ¯Òmh²–O9åRBc)ÿM&eÂIÑ<­™KŒ4ôr¿]Kÿ¤‰€W"©jˆÌŽ•¢¹Gω÷‰˜Ew׃pŠÄ¤QÂ"§"ã÷¼ t›5<{÷øØ²çè8mÝÞÕ8ì"ÈMôk‚ˆ›E7¦?ÃÓ'­‚’*4L¤Ê¨´‘NB†‹Îx˜ÃSèr«¯æÄŠ+{q5ñÊä1l´¶Žî"YÙߣ~¯«”Ÿ­|osÕˆ_[XÙ‘›Zœ0’Ð#°‰¥pþ­D#>YzáfOq}ꃬ4×áUÆNƒÙZGáˆrÉEÏ_}'Æ„ªÊØßFñ=:^ÍÙ($b£ ¯ðÃÀNºl™‚¾9÷fÞÍ>íLlwhD•Õ &-»/fQIuHy­ —äzc,¡½6×Y©rßÙÉ!{H5ºuê¢?s"a„ÉU~{%¹Å¤®4Á·gò–æ5š¯uäóûÖôU˜ûùú ÓT¶T+ã{%…誰f-SV¨ DüoW=iªÕÔÚÉÒgÃ6cô]¡ñÜùÎI×Fk¥»ªÜÂÃdâq‹O=Yü_E"ït6í%>•eÛÿSŒ2XRPæ‰÷På° ×Þù®vù©–%ë›D.ƒ¥ÙÚ|k$Ò…i„©å&m0ŠÕYù•P…¨„™#Šúâ ö}éÒ"ÀTúûÑ}N“®ˆ¥þ‰“Wóšf°/;gbý‘xŸ.c¬~4FúÎÊ`/M {©”/|Ëšk("çû­ÀÆóÛ–¬žh38æ±AùX%A\³(ˆpYIN„3)Ô×¹¹æc›×Í‘m4·¤™üÙÛâ÷?Ê<>(öÕð—æ…A°ùi4æíßY{‹ü>VNý®Ã¢®gVšM2 ¦‚²¨p#øè VZÞjæ ‰š?6 R>Œ›IxǪ¡iøÚZµ½RZ'±€ä¢my‰9Ìè‹Uz¼4Ñôàâ´k»Æëªï‘+ ×ÏCv1„‚­$/%5— «§ü¨€ÀC?»pÑèXY³ž²1½€’\¨);'ÿÓÞ¹¶”© '(²| ð¡3µK|ÑÆ?È;³±íÓ':³yË98îú†-垌bé,âj@ ”õGx Jr›ƒ x ÖÖ€Ì=[Ó<•oá“qºqM›}•="ÇZ›d.(ºx-J%#y( çwÁÒ-CiC/Ë—†Iº&ÂÖ‚°öSÊy£¿Åiï½H0¨<J±¸ÆÄZ·ª>¸öÅHë³uX8¦øHQì"°U' ö>ð% /z{5y?…tºX ¼1•_tæ~‚¾W¤S`‡XŸó¶: _.hEHønŸWˆ$ßRíì.K’à}(!7ODâ‰"PPSŸáJèÓõ!'–<ýW‹ú)ÂÕYp‡ Â>0û+0Å8!]\Žì¾v ééÑD”¬TpÜV]ðú¦E‰â‘Ùé5ÕYl»’nVL“JèÆ¹E¥œdy!ŸÕí%õdeD¹ôöÓ™]TTâ¤I `®hÌsc’ŒÅâ¤ÈF?{ØuÓ¬Ø.f(…/“)°}v—¿É©J-Ò¬¬2P·¿‰ISæâñûrI›÷XС'4ç%õÉTÉ…"+'Š÷§Xä©ÕÊÅÅ+fy ¼¯HO“@rÿÝĺê r »42Øk­Ö–…È*Ä[˜·XÎÂ-yý­Ž¦®ØWôú,ðÃǯï«ÂЕJü.¿Ämdר^ÁضT>Þ͵הµ+¿{*ÁAvE­œióõÀäxc:'Õ@üû}îU†}è¢ÞÙ®N´0 LJù Èi‚¡$ºòÅJ÷DßiGVˆ·¦ŽŠ(Gb{B¸iþÃ>âwÚ DV—)z›Àžá_iÛG‰Má83Ç=-z‹\øû0ZP¡•Š¿(äÃ̺úÔÁÓ¿KésßmHzoÿ´ã:”%–´TÑ£Náqíµîv§hÔO+ØÒ—ˆ / Q`ƾ-ÿô ¾µA¹Iy¦·^X³#ÕO¯±‰ìÉ­"…R3àañaqœy4}˜:Ððù®pª@tó‚ [O›6m{㘗ØÞŒ,ºé }Baƒ-óço2zyÖ×£˜+þ¤uÐ\Ú{¦‘Åí9œ>¯KËVÚÓÒ\iê‰ýªT2Ô’Ò “x'º_ 7›ë9¸ˆ—ȵõ›DÔ`’ŠEÃ[™Êû‘È 2†Ã=ɪqQ=HH‹Ô·0û ´0‡¦ŽU¥\Ìv7ïnOCdŒ‡WÝÞ½sê«Ö·ȡ«e?þ„ ÷ËˆŠ¼cñÚÒÊÝà2ÕñjwRê  ƒðHm2ë©•%­ì§²þ–¿ßY™ÏîμªìÒA\½‹ÝhäZP¥@d®êÓS„§=wÀðïì‚èž§§õû½ˆcöeîXí6ö+7€ì«Èã±7™† }ùF–e”Àâcgô€ÅŽØ†­ø§[o¼–®“:6ˆ%(,¥©ÐO¡(t5ÏœôƒÐ-ŽF¿á®r7ŒÖN‚\%ïû¬uà ú`ÐÍ£/B.k(º³±'Ä¿øµ~„³e(ÓWíò›.w«Ç/9Y¬lî±ëXÏ¥uŸO¹6q&ŒQüMi¾N†®xw)èz…Ã\gĶC¯cù%’ÌúHk.ypMÌb튼«óF‹S¸·ÎæÞ‡Ž>í%üæ«Øë†UmèHººëÚ 'Ãñ¨†ÄYž q =îRfD¦ð¨vó„¨7„ÏXB@ýއ)¿ÍöÃî†ç" Eé…χâqªÌRS"ŒƒêbSJËýx—ç¦iÃÙŒ'áˆ@¼žíBp• 2Užäø‚6ªy±õ-ÂIÀV3Ò’›«Qy¸d1Ý=‰x¢es¿ûÇÈñâ÷bµ¨8)N÷OkÄ?æ³ ÊH°–»vuyx[ë…†1ü×÷$$Á÷òrXl¥Ò l«Õ.±PÜSÎOð%‹Ðÿ (u†ÿ6äq…%—î×éW&Ú]a RŒ5aê3¯äŽPg/²vÌѽº¤­íÀ÷'Z‹Tål*Ÿ2RÇ-…Þ[Ïñ`Pë'4Y3Ç‚J#¸úOù<‡Î,«»f†ö±u˜ýË®Ùkäo-»¸/¤UoMšfN‰G˜juäBº.`”³T!ÕdԮњ1¨‚:ŒÄ–k3zkF›ýUÖÂ[W7iíʈ@Y éJ;5|7„ôtýÁ_I®÷ë9VûýŠÝ®^гpT|Ðc×2Q^øù‘ÐMÚeöíkSºÛýÓŒÖ/'*ðƒçb/x³CéÛÖZ‰Þ´gvyô•ìi*FD8ü×áÄsÛã{ìs­nëc•š}iz-; Æ7©—{¹ãàÓÈð÷žÄ¡˜Å² 1T± ŠJ1åw¿užå”l²• &voœ–<_ï2-l+q>¿lµuÕRµ¼-®¸‚¼H:ïcŸ}‚Ú $+€%ÎüW$C+ÊTä2ÍéwÔÑæïí*~U:€±ßÇN;þ®è“ýMñŠ€3\4£f0Õ®šˆu¡;Ó+ï–rÛAo…Í^~Ò}æÆÔêY*¥ 5¡hõ´»Þ«:I’ ×&vi…€,ærw̱¼C¸äf,·Â¾{—èÚñ{Ö v¦Ü]ÍQäxÌÅù}(œ*ñOˆqÄÖ4ÇkÆ÷q©‹á!uÙ‡pÞÏörDsîƒ1÷ØÆm ‘YMðŽx9¢‡ª‡Ô W¨ÅâL„€SZYÝ2i>½ì°j_Þ*FœƶB3åh*Õžó Uß]ÎÖ(±¥gáS>Q-bŒ¸ñƒ×&C×¶è(ì†YmôfÑèy'ÊWšç¥ÆÔÕœêBuü|=4˜®sSùˆÉ†ïO@Mö3¥ ïl™@ ú×,f¡ôÕ1!S½0ÎØ€f\ï½a ÒK¾Ðf,)É|jO=V¯vt¬B jTcY?IѤG¦cÒ] už–ª‘Ìu¨Ÿ¡UÑ(‚J¶Ñqªù"“(Þ±{&øöpO³sƒV䤄p=Fɹ&xÍ!ü0ŸÒ³ *ŠÇ[³§÷d°¿IµžžyÔÉ“¾~DW!•g*6OïTÞ…xQÓ¬5ËV‰F<öhË50`ÒÆi‡Û_` ;•<ùíw™¬¸X烣Z¯š8LÊxsïÙ[Ã&܇ãI´ÖôŠëæiW%ƒºxhpW`…‘y6]x”B¶Ï2hi³0j£ª.X;¯Sšð}M"±‰ÿ!¬ÑÒÕ }ØÛæké¤têˆßÝ[V©‚øX %œ'>„þŠ£c,fõ['Y¾äÃ7f_—í£ÏÃðúð >7CŸ ®'y›\iœŒ×ÖP1­oËväRð0†É0…÷“$Óy¡¿ˆ‘%Mq|~ûdׂOwÉÅ{‡4èyÏ­ðªÈæ›{‡³±Õm·Åõ3Œe…XÁðáúÁFŠˆbÌ€=—xÍ.3ÇïT–‰ôÛyµ±+VdÙœ có;ILˆ¤·Šäæi¿ÎžVNäQ™–©J?U‘k ®Ö„OýçHéQUŒ‘æe ©Âú¾<{Š™Ç½˜"’àô Þü!ëïIæ1 ÷°#“cßÌp1D³Œ‰soQŽá¹rñ.”= bîœ}rëþÆX¦ðFÿ•@)*Gï™6d[NÉy ÎŽ>ÓàFh±%e­D%Å{RìT3ß½vµu°ÒÜàg QÕqqbh8¸O’»õ˜ E3 Œ;YL÷ƒôÅ‚Œ?ÔŒFÔŠ~Dñ˜Ú¢0û¦ÉM£¬òJÁ–Tˆ#Ôjåv±döè½³¿®ê&’Á(XLˆÌ/€^Äx Ñ|i•&çW÷BôC,S‰ŠWß+A6{¹ª§&/þ¿I‘Î|›oÓê5×¾¯e„¥Lƒ{‘lo,†ÎÓʇ˜$á§<'gøç1Q8²CŽºÍFÛ9_Ñéss»I’3±"ÂʼxedùMt9PRïmD¨tWضh¾þÂ*:äT1šA{B=û/ÿõý)¾},¤#½Wß à‰ý»†°¢æ¢+h¥{ ¡¢©Y€†¨Šî· CÔ¯Å|R‡3ƶѶ³¥+zZÒ°½\¯…“·lç¹bEŸ=¨ž…SÞ©ázÈÖ\Ôµ††œ—Ãìo6A¥çyµù¬,l–!>ª‘Æ˜Ìøn?zØ¿a_×Pgs0zbñÁnl>–ó·búÏéù”ݲHÁˆÛóa`û®k[bcï=@S„0=í)ÊÀˆ[örrfopG!‘q£·» á!$7˜°^©ÃØ2ÍÍÏ!ó÷Wš5ñ_«^ñàÐ%šXrž– 1ØÎ!'‘åì)CðˆÕÏ/m‚ù¿` àtùLÞñy;¬Ôܹ!õ e‰xò´1#0ã¸~sÅøZLp}Ç)ž¤¬†=?±sæv r#Á ž=§3æË]>J2õf=´dd]üøgPC÷ã=µ—rÎWgȱrgéñ/Yv<iÝ·¨ëF©ùÈù{F.8_2'Í¥Ój­KXψ§I~åpeá›*Žø[> ·XäK!.ùædk”R—cïӚ©‹Ý ((Pû~sí@²–7Áh’ ¬BúñÅ#Xª]%’ûJ]êðxÅ;¢ô’#˜pVññrã&Ù/‘˜XM§$Â…ç&ºÈð™¡Â_ž.æóÛë­66¶D¡unVë‹ÇìsuÌlEî–í¹ ßêX,C??äœ2Žßz¯qyÝå,ßßqMˆãŠi~`øÎÄFåƒ0‘˜7{˧'y]×Lu´“­Í•1[éi¬ &¯வV02¥-~ìM—%ùÓ:ý Ÿ \÷B=#‚¶’ ÇË ä,î7õ¤SŒÓ"+9w»9ÒžýÏ*khÄμäÓùŸ=]®ø[àÀ´ Š–qLB6iFa2]¢L‡Æ«›ø„´ÖôYüJVqÍmv{¦¥ {éÊÉÊA¦^è§oÈAVÒ|æØIyÙ’Š’üÞœeüQ–¼Ò\k”aC,ª´é§²!ˆqôÙÝ»Nnaï%ŸỎ¾JüzUÁÊ•Á†i‹Ò%íÏ\V¿ì«Œ˜•R_8Ci¬;7UíB^Ô<ÝAg§ãļÅJ%/S¦ß_6~¦þ¤×_ÊYš+!}Ì/ÚÖGîEƒ´§BKTª] =+ŽjrËÀ–f5ç0gØ­û9!޼·.ìVÀc¡/"ž¾ÎÐB°vPŠ˜å[5l£lÒÚž©}´ë s­Ku) Ùˆë È)%Wýåõ4Kú°œtæž”·íœøHY°]½uëL…àƒL¬Òo¶TDOgåÙmT´Š³ßæÕæòqù®žVՉׯOï1¸X1©ìÓLè»l(k³ $„ýöñç;Á刵ÏGS³7×G$:'d~J6œt{õ.avëcë:äPö|B0®žÏ4-¯Ñ}LMáK¦êcspÁïæ:!1’¤8½ÎX¾!¶°")Xb"îÂò1yŸ‹‹~+ÇÖÔÑ!!]†‘Ì•áÖ§ÿµé–¼«þ¸ümCPªõbÈ&S{›WyIg‹ÞXx#2Ê~¥^s’‘¿Þ“-Vva¦GJ5ë§q\LÊjóÄ7ejÏžÕ¤_E!+ÙÍ|ñÕ}b7äÑã PcF§û£×/Êk‰Äè½lÃokÀº®DÍwt2Ìš¶ ¢ºtÀN_¥Ö–¸&¹5ƒWú8áû(† Gù‘übF*×þ\΢éÁ*lö[v]Û¾Ó5Å!pí·Ù}šš xÔœµV¢27w®«5¥[$°uµèX¯4^Ó:Ò5dFAmÒª`Í€›BïoŒ.V"g»˜Ð¼WÎh§íëžš€Gï F&i]¾º»…dž{v›ÈÜ(QÀ*!Ô¡TTœx}ÇŸ4ÅcŒ—ÌúáëÊ7Œ¸ÖÌ Q¹Zé’ŨÂ}–Ç™T¯éÿÌ;,Ü®ØéÒèçÛœâ÷K”ƒñN†'…:©SÈ$%&ÅWwŠp.yD÷1gfS×-¯ÙÛ˜'Ì)7'z™î•CÅâ‡B€ìh«‘žtoªTéÑ™¹_Œrƒu¡˜Å‹zjÝË5yü“Ùzín mÉ0£1 ™¿ç•“¸ë@”[¯QSÝ;pÂRêÅàsˆfo˜Ñ–fQ:)·Ä“÷€G­›(Q‚!UÊ&¢÷|LÑgÚ&‡4¹,Ÿù·/ÚšV¥…i¯Ô U3èPÌGÒÔçSzÃʱžÓ¶-Î9ø#\9Üêgˆöé?ص…é I㼺µñàäLÖß?ÿˆ)¸ $â.&ìó„˜vÃÓÍÂë Ñ—éh†ø†øë•#­¥³´?мæ]D :MS±ÏF|"Ð1µª!òºAŠDlžñ䛓¤fC8¦t¾ep{ÆêDiÔ:èˆ"[Ú;i6õ*BÃ5ä nùƉÏ*´V5õ¥£•äï¡ð«ÇøHÞ-XnѪë[²ŠØ¢fÐä@;Œ eŸØÚ røõ\qÑö´™È&I±jY~h³ÛÌ2–H/š iEo€8ñÍÛvÎhB½3Ïk¿yðýÚÜDDM!†ÄOÏL n“¨üüÍ©T_PƒÕI§Õ’±Wó„Ùîh8ªð‘Ùû«‚ò—‡ËYV·æsí¨QiÝ ‚øW24;Z–"•¤½ NÙžIÓÓóôdüX°Å‘†Iš§ †•ªÆšy–fA?aõª™i…PÔ¨Ó:;ÄæÙïÄ–|…ìÓ/:Ñ HÌ‚T.?W’2Ê~•úJ{ÜýànMý,‡Äì’²ÙÿMmP„G‘80’™ é Íã¸ìz»Æô‹—>üiÐ6$vB˜º»ëçJvÄà‚×õ«]¾ª¬!7tú¬dÄŒd%¾¥Qøkyµ¾!jc;s%`î×s´j‘B”EéR EŒ ZVá(Î%ч>9æØN<0®£#5Xh–໸êɇ¬n Éóp^*„×™5ÿaêW´¯’ŽIèmE%x™BÏ=Yy³ê©¬f|ŽÅìÆ,JÓ¸z­Ê—ðŽï ˆæ×w›cÕ)Ç‹ÓnHÊ Z‘wr`ó‹8ýNÔeÈ-w´86Ûû’Ä~b«àå¯(Ý Sb;¶F‚s7¨›Ø¾¥üB=-Þü"ÞÍjð«Óµ3¿„r9-¸«eÝM Ú•UÀŒœÃP,ï³õe?þQÐKdyŽk##XNgÛj@ÒÐ~$‰ïÉG‰;^lðäHçHRxÁÑ×µS"¢ºãÚ%e3a<¡÷ ‘ ¡ôžRd ^èç']ú 1?& üŒÌ2•>òщÐ!Ò°®Vû)/ZÒ])’'I½á³fµÇ˜Ù¾F'X02¦guT_ž½ 5–5šÈZqõúO¸µ]•fŸ…ñ³bC­}PGã+ÁþÙfs"FÏÑ<àÅ{‘»˜ÜKQ¯JùÆüpÀ¥JPn)þŽTé©ÆÎ ªë ]!a‡‘©Ž¡&¯ë!Ä! ŒëÀ Í:Ú‹ÝIù-¤\a+-¹óùfÓ¾Hn™ï@€ ë°ýn?mM&R‡¶IŒ–ëAV“-+ûæ¶AÐFx^VuXölžúë™´5ª÷Uûg-ö@ýUYGKñ©‰,5c…d†xòm‹kCÍþÍžU ·ãA8jc`±žv3€½~ÕN…`ÜWð¸µïò2§¹½áR_‰ö‚Âä4ž°îBH äÚÒìDLlž\a²öìK‚¼›bÔuô§L%®:/å>ô{‡NþÃs%ñÌÊ®2Mhy ]P?=MþÖÄã ¹ˆ[ [=l˜ôf•ÒXP‘Tƒ½9ÎEÄ °9½´†àÂ3ƳÙ*òQ½ }—âÀÎ(l„»ö8Íøò0ËØ1bFÏÕ³8¥v|y/Ÿø.@¢Ï©¸¢ï9N5úUÏ£ ‘>ÙæVù¶[ )í5ªï#Δtx>I4+Båô1ÅB6Áôîpq=z!ËV¤J¯¼ºæ˜êQª D_ .þi®ˆãÔ6Bƒ¯Uó9RŠN)«!‘™&^Ë˾ðh†÷ŒjÓNI¸ÏTÏÐü“ŠS@Y¥’]ÁÑ5Ük·»>å’ñwÍšÐÿF+ Æ3¬}Mo@ÅëeŠÎþýgSQwYÔ/‘“ñê©Ä>iáÚ±ü¿‹9òªn${#»ðqüc ÇŸXTßSE&߆mîRmðÓ 5/¸ÑÔûl{£T‚ÖmlO9á)àEÂ¥n9cOŠ„g„q·Œ­(çY ,ì\—¦òPÅÒ †iÁ4ã;w"ö&J4ÔFøÀÖ Fsƒõ¼~ºã­9ž4wFaÁÝŒ«)4]@¢Géà3/ÆZ\NËÖƒø®UÈ×ô®¶¦U¦ô«1P£íëdšÝQ«}ó艰SV™;št”8L½Vü­N¨n ÃVc‘ƒéÆÍÝŽj?Q&®ž„K”—/–ɪ֩º_øs”¥^Öl¬w®!¼Bs¶%{¥Ù':ùªZ=ªe®É­Ïg.µe¿­6­ _Z[çŽÃ!ÌŸV¤hLòÍgfÙŽgi d|FŠ]4©»#dÙTÞÉ4d¥RÿžðX|ò*­?»o@™þK“½%)ÛX M ‡¦ÉHK‹ëÌ»_™’)þ³Ø]‚”>•jj.f3Ïò#ôp¾þ „®M6—g¦ot`7™^™Á×ÚOÎÖla¯¼R¸§ÓÁЛÖÙÊ-êÔ"Üe;‡n¨ª‘‘>Õ»±ÑmFÉÀ/”y×Oçë!Gût§B‹v!ˆr—û¡±§ý`ñ˜Ê")Uglòz}F¢‰AfÙ®tçF'°^‘ø<Êõ}Dz¶X8#î>~Y* Œn(«Ó)ä4^âŸ|:wšÊ:¬rçqò–g-ѪìS‡v;SŽ‹^DpMâà …YlæÍ%‚› –Y® Ññ…ÀökòæÜÅ2…f˜fJºnÑuá9xVw×OŽuJÔå–Ìå…Šð'‹ ïEÛQªX Êa·¢XTÓ”Ô˜£ôô|³)ï{»ÝÂk^¯u¡¯Å…/õ󑹦Ðrùö†îUMد›!ö-Nê¦îÛF¨¶Ó„ß©ãÖEÎ¥¥;{íH³³Gš¿+¨¢vh¹Ày,³”zA6bezêr•“qßF ì8¤§7*ëÆzŒòHçÔêIvÄצÌ{ü2zÛ´}£V.4gãÐW«K¿=Éì )[]“:‹fNYyö[Ïœ&íGh¥l¸ñ ÞI›Ó~Ó•Íù;÷_ÿÍåÜ{ vBÕï(ýb>ÉÄ>Ã5é\ÂSQnZ9*÷?tàƒ½¿Ï0õNäô=¡”"]²þ‘‹É»ú¹š8ß©¢§ (¼/#Ì3Ø‹eŸ-ŒÈp ci®K“ö°÷,yE4ù˜AؾÚ5"}Ôþº–73…žÒ“ÛœG¤þÜV&ýtøvƒñàÙ4>¥žõI¡òÏ÷^gûËsèÐJægÆU›Ðd9þkÖ_ÃíäD®$Dþ¢‘YœÜ0*C÷[„éô|'éÊ;oŽñó1›ò3¸ /Cr½ìC™ê§ƒQ£FôåèêŸÉW'é_â²¢¡ø£v° ÛîËè`…ÄèXe~4ãDç‡ý$Ú±×ù9„Z™Ñrm8Œ³3HŽe6˜:*ƒ57O¤©%ÉM£»ošÍŒj%ÊñˆBKÎHbÜ3 ·+{hÂþ©ð÷~Õ¾ª†šÕ™ød“[—)Ð…»ƒ©Zq[:‡Scá9^(®,wKTÙÝåÜ&š¿+å’;•»MëbREÃÆôÄ Ê­Ô"› k›”À¸eùž§Üs܉xû”~/³³EõÄ~I«J0âæ(¬ð~ƒÆ1¾¦ G‘YÃ5ij<›”@ªëS>¾iâÙF&¤‘U{ÁIþÏ™/ƒeîc™ƒ%H&?;/`'}f\ª"ù“˜kàÑXЬ¡Òcæ’Èí †kv½×P[‡Æbñ.Þ(sˆ¢¾6“vQòð8ëþVÜ•ÝA5’VD°"jº|0ú´R¦ÚÈ÷F?#¤ëýX–;Éj@Ç:ÕáËgq4<%·c_f+TOl¨.µ¡E2ßã„é3w3Ô„O/6÷¶F\ÅÇSØ÷ k‹eÀ•Ù`´Ä&Œïä]¥Ï š±s²[|n†ÐG[{Ä÷2 A±’ `L{`ÿ¥Ø:Dg¬ºkF—x¤0.’,Äþ‰Ê q:õ4Š/ƒækº!\2ËòÜñäOôeˆe‰ 0ýÔñÊŠ×Fnôy.š·s ïì±ÔíØˆÅ0eÐTJlöÚôoÒì^¼-ÃàaŒz×'6ü(ƯÜ':Z/ ކ?FH¡Úбq$‹¦]gÁ$œW¶^E}XÞÿèá̉±×l$»>#t‹ÒL|tŒ•‡£P\ÎÄP@%}ÉwFõù—úÕÏøR4% $“çgË÷í7'ÔÊKò ¬Ve©Ï&†ÇŠãWÐm±ÈüˆbvY„ë÷î.1$ˆ)„·rn2º%yÄMeÙ´°µ=%8$VO,‘#X³ëH½…8U=»*p°Ô@™NØõ>crPóÄÙiºÇùÝùwDýȃžÓËO5Œ,‡ë´µI<…ml£+Š‘*Ý´SïÞï÷ü¾7^ã>²BoS¦4C0AnË·áø·ž –à9´Ö‹9ÃÊéäcãAºT^ït°ä-ZßµÂ&£æäM« 0 <8»¯,é »â÷~Ñ|&|ôú,t©¥ýb°À™Å±g¶ßŒ4Ë;’—A;waó~Ç£qL9®Ñî‹Þ¯Ð5èBTG1bÈóaº¤¿8Óq]j5üª~YÓ¬D´ò¼VÄY–óu¬ò—° 2#Ê“ßìNåB–Ø«/P”I«*¬êkî<¹›Y6C¢_ 8ãÍ‚±?ÅÈ~{¬äâH¥vÄQyO(“Þ{TÏ‹$]‚¡¥à뮩_8óf­Þ“¡«U|bH@þ®CvSY-ý´ñôû‰·–íSrLÀÙÅ»`é–›vl†+AüøxãçèüU'o¡”)óAž:2I¼X ƒêj%ïk##€'raasè$†棧Q¯ÕTfãå–õý„ÈS.nʶ|'Æ*RC¨Xš1Îgjs$ÙfÉ’~¾îͰ‰ÚªO"+ú¿ÅYk¹ŒmýèìA±FµW7E¼ž]/\xÌ;¯Q0H‘Ä:-,UQAÍ"…e{þëgj½×ŠÙ&LQ~ ’emfÁY¬ÀŠ OXDCð¿X ŒP#1‹3ÏI±›˜`_Ói}+Ðâ]‘ÑÊS´})K½¸)SLÇÌÚÊ8Cè— âú¨ìãÁ>«ý„ß.Œã”s õÒ‰æïßs$°U*›×«‘–*Q’ŽžëºƒŽ¿E èBË7Cx&Ëê,ó×Ì=~²2ª¿' ƒöW)_õjˆpâµ,dQ±H2ÉíW7|2) ´ì»ëN\}iÈ ;·îHIÖaWÈâ–Í$´Ë~înkð:ëeÁµÃÈÛ™z—,ùÐ  +2 B½­¢aTœ òPÛõsu®ç ØItÕW–Ú£6èðéíp Å?´æ0錗‰,‚ÛŽí¢E㵌°DÅ'L»œšaõÎD¢:&®e7dyÀ Û`ÌìÕs·Ô¾$½ìðÚZ©Îµ>´'ä³î†–ˆàtó{¾4Lw·:+T'z 8Û*ïÕ_C¡1¶.+˜¶’BL&úÍl#@7$ÿé u÷ endstream endobj 231 0 obj << /Length1 2212 /Length2 17020 /Length3 0 /Length 18350 /Filter /FlateDecode >> stream xÚÌùuPÜa² ãî.ww ®Á5¸ÜÝÝ5Hp—àîîînÁà—d÷œÝ³ßV}÷Ï[ÔÔLw¿Ýýt?Ýï¯f 'VP¦2¶1ŠÛX;Ò330ñT€_%Üì’@{z% ©“¥=€…‰‰ Žœ\Ähàhnc-jàä°29šä?ü?Ž01qÑ$€Ö@û«1ÀÐ t4Pq³2¨ þ 6Žô†f µ©¹5úÃEÄÆÖÍÞÜÔÌñO Nú?&6öþ@]ÖiþfHYظ8X˜ ¬Ò ² 9—¥9€ÊÆ`43°4ؘü ¡ª,¦¤ P’WUP¦f¨™­ ¬€@€‘™½‘#ÐÞàüÈc`lüÜ’Ö3àÇËÀڌᢲ“­­ý?«QVQ• ˆ É©ˆ€jt Ue:€œÊ‡ò¯å¨)kcsƒ?î²b*B* bÌŒº`8ä4ÿƒô?Ê¡ø(ð¯j>\Mìm¬þ&P™9:Úò02º¸¸0˜:982ØØ›2ØZRÿI bfþQƒ½àãÝh üÛb'kãb? ùàÇs£^ÿþ5Ê ÉI‰‹)«Ðt‹þOÃéÿ’Ïàèêø·%1!QY±ÿbýÏÜèð—­?‘Œ?(6·t`øHõ…Õßx>R:þoÍ´8þkù$ ð#Ð/ŽÑä³ã?:0þ©ƒ^\^N…^FJDLNYì/Hûpt2ýãûÿÊñÿ4ÎÌÀá/d€•¹õÇÌX}às4ptrüÕ}¼€Æ$ÿh9 âdoÿ§4Ùÿ1ÙÿouÿC†°ÍG9Ú–^.ÿ9¶ÖNîÿÆöÿ%ÒècÜÍþøÏN[~¨>˜5·þÿËÜŸó" ‰Êð8Ù™,/¦³6±±²úÀí÷g$DÍ?r´±wcü¯«oamãbíñßm&æÖÆ 0v²eTµ6·sJ‰þÓãC÷/)ÐÀÚ}첑㟴7ášùú£!^¶6¶K —¹ ðã ÎÃÁÀùcFí€^ÿnø¿3'ÀØÜÈñcï?®¸¿Ñ¥¬MlÜÿP ùÓ?gêï}Fýq™ÛX[º}Ì­ £œãÇ´Pýý6úÔâN––r¨þAÿyÖÀÊÜÒíÿçôœRþ©žê¿‡0w7w+˜;™ýƒ«è¥ >vMÈÚÔøÁó_•êŸÛÇòc)>.}ó? =3 çØ>æÝÈÂèà`ÿ‡ð£…ÿúƒÎ?˜Œ²RJ ²J´ÿuÿ³6²16·6ý˜u€½½ÓÇ|±°³<˜?–ÆèúwŒ Ö6Ž.['G¯?ôÂýn£ØÕ_‰“ À(þ¿ €Qé_€Qí%nN£ÁÿJÌLÌF࿉\FË?’XýKdþ8lóoâGÛÙŒöÿ&~¤uü7ñ#¯Ó¿D–À®ÅÿÛ@…?·ÓßucúWGÿù ú++;ÚÛXÕÍ?çÿvDÖÀÑÞÜU‹écW˜?ôÿóIçÿ$ ÿךÿ›·°°«=; 7€ž…‹ ÀÌÊÎú§.¯ÿãkôôïž~Pÿ?òŸË ºà–lŒx¿%7—x‹åM•B’s3œ–a}þ*±ücª G4{›(ï×ä›F‘o##É£ãýÝϺð+y ¦åÛFsbùä±¢àŽ·¬7>’˜Ðh–ƒªšì’oi õ‘tV®FÛLZK\ !@uôX„»­ó1Šeâõ*‰D»´e-Ò¥`޹ÃÞÍu ¯iªÔñý#&Ò Gh™fV?7kTʶ»}oÊî^¤leéæÑ›á"i·7$5úð Áÿd-‚Hvúvž!«ðx¸÷>D«ßy €Î·Yc›»:·~Æ©á¥=·ióÍÓâàw$•mÃÂ1Èdߦ2¾µ›ÌX›gÉOõíÕçV]Œ‘ƒL8¿¶w²ó%ÏW0ì¿çs|ÞCœ±;+½kV™Hzæ‘#HZ¡ä\dî¨DÙ´|é‘54‰­kÆ¥"3:ó+<=ÖÿNPH‹;ÏÕñ0pµÊ’ªµ8W|^¿ß2¤êÂl< JzÞv“œ Ýåù¶Â–T²t«Ôp Ècë=³£Qn‘¬LC¥¼#›­ØÝ’§]ªÎŠAÑ ªrÜqCÍA!‚ûmÄ*‡O/MlnqMG•–N·ÎÒ‘íAÕ¶òqⓇiª)FWª…½½P#I¡%ì[¡mVé ñ7«)C½ Ƈ‹;q^“ÐSRøÔ¢ üdcÄìø¼÷ ñ¨ª<Æg n·kF‚W9‰Þ [Œ»=##®üÏ‚ýXuEv{ÿïT¦sS„žnñXÀÛD¯: )_gØDKF°ïÜ"f.ÌÓÇ%:Àø%ʳ÷7QzÓq;V¢ä:ºµhéoj2Ê?ÆÐ(»Ã;²·{²ÃbxÓ1Ó8ñ»ïTÆs`š´âë\ä‰8ö*N¡Gèö|˜€ §n Ï0iÚgðØaut¡§Ge8ßO5ü¨Á‚ÙØLlVľ×j¹,’]Óy˜6åLœçÑø_©v¤³‰w =d)ìÛ/N´  INeÉD7æÿ@[ÏÕÉQy €_Üqa<½?èñE‚àWбr{¿yW'ÏÁ$KÊŒºýqã–V7báð6´ÜKH`öÛ'_{*Êëä€õâgá-).RLo% OK9õ³Ä ÖÓ Ì¡«Öa¹ëE!N¸±g—ÉžÒ#iì5My™;·¬çÉ7Æü;vº=×$6n‡çæÄxŸ\K]PΘ5»S¨ÆÆTðcê,ÖÚ¡rÚ;#éÚ²-˜ßÞägÔ7l°,F(Œ°=:^q`š2V\«Ø¿öTW¦õ`È67LØ$@ÆPG ô qˆ<¿²½In¿ÛéCi»?o=X ô°‡Feò“ ®o ˜•»Wøÿî½ÕpÊ?”Žge c‰w`l·e2ø[âW?Ã=zããÍjjš_“„ÍeÛ•Cú¶aŒØV”øÜ4BÜã÷7WŽgÁÎQ•ºù£ƒ‹z&‚“o÷#Î3Þr¿ àºkþÑ‚cÁ¯½ñ÷Ÿ0G7 ŸmÝ{ô<3û. P3:^ë\@Íôœ~d à¡ t+ ÉõÍ`¼ì-ò|Iq²ÁÃ.côÅqÒ¦Àh–¬Lð§ºKZt–,–Ì>ͼi¾>(ÿCôö?PEøF8Ë›ó\âöîñªú'q$Ö¾¢|L/±ç[QD< d»Ô¸¡«O<¶PþÕ’àÔ½hŽœ»i©šèñ#©‡­ z¦Í*”\‹×îÔ•µÚ(èé¡¶îþ›€¦^wVj›¿áä”–*VÓjv†Èô} %³8YSa~Ǧx‹Ïìw‹h~n“‹Žˆütû U™I¶k²jDŒÑ[ÔxœyE‚¡HÓjYeJä$ÁΗjâ6p%Êè—ëä&Ã"miPbÓïW¹¦"Ž•?ü`ÆØ„Mê;.îlàõF¥hwߘáÅýú£pØt÷e»ñÐq³ÞC°i¾ K*‡aE. Á‡ãƒ—@ºÞ=uuJ?$àÞUÕ_S`ȪE50øEÂáºq„î”2î£ûÅÿJRÊåÿºÆŠÉ'½üÚ˜ÓòΈ¶“2i¾ o M`ŠòêWПO¶‚Q‚Œ×çö`9ÿ9rxÂ~#Ú¯ú®y»±×’…µ ð´ÊÙAI½ÊÁÔHB~«Ësµ£fïÚ–Ó¨'’FŒŽÆþ´yÑ…r6"s[ù?q¸2Þ¶ŸW7_µƒûáû~)ØÉ5†EóÖ´,–IÉ9?ç¡1Á!h²u^ÏÎ,…C§½sëwMû“ÔÌÄV¥¬(\YõS ™~ Ÿò Ôâþi@HäQoR–¿ U»¨ìtÕÅÊi 6ªù’Iêpii¸½ŸJžßµêòtbÒÔ„}òuƒ/Iê$ZÐCì»ëàT1ù i­«í¨‰!•£l#Ë×HÍÂ.âô&”º£ƒýü‡Á$3i_ß¹YÜTïÑÍ_OY {§¦¢‡Ï•Ç[!ˆ†¤ïÎ÷øÙHl—(¨µQwqßüöÀøÖØá·$G­­ü‰+Œ=íÞ0F¦ÍõIÀ[MÓN%Ÿÿ«¥ ;‰+â³o¹õF}…×s£Àt6xVð¡d,øƒ”âª?+Ç«þ(âA‚Y=#ˆLý/4g´Á =–â¼üƒÞ¶ˆ ˯E$aP›[$==¿-ɨólÛæ{Š6c„6ÁN³9QÛÉhø¿ÈL·Ô!‰/¨~gta}_/§%|™+â›HšVàžÆd#åAîªP/ÒðÑÿ¢Í”ÌßZêßûe–x®f4ÐZ?Öu^—Z|€OTÄÀŒ(°yW~o.¿U/Ü JL‹½¤ôªÝQx6¡VäÓFŸ‚öÝÙ$ZU ½G'‹ze€×­)A$µYÞ¡@ˆÈ•¡Cƒ-V¤¼«ß+ÉÜÎÜSÓ¤ŸÓ…» |` ú/ëÀû-p]­;‹U&¼•g Äñ{6g;¹±böï©è['ý \4(}†”ÅÒTA¢ú% _F-t3Èï{¤Ìêdñå s+e6V#«$ù[¶88Çd˜6)V½ ÎV!ç¡ÌLÕÓi6TšÑ/Ï$Ì?ëå99ÒàÓSp˜&z¹ãp}1ð ›u¢“õ7¬-l;A–3æ¨[hƒÖÖH’¶µf¶› _Í'ó¤ò"Há¡ÏMò)ä|“J/øq¢WaS€Ñäž°«ÊŒ²¼ÉÜGcØ kágqy(oër¸o¬Jæû¾3o}y úbÝŒðÕÓ€“JñÜgÿDÉq3ÝægÑõʯ£UÊ̹‚ð¥ž0hL×0_¥n“W¿Ÿ˜°òŽÔšúH‡ùÔ.¶WŽê†”Ûc=¤Žñr&´”¥ óž°W6ÖW²¢0bÁIa‘I´m@nC-7òaóhÄ.„A’ívJOëºjJe~…k æ)[êeEIs“.ü¹}´°ÿÝÌà]Ç«„OïÌ””{ÌýFy㻜t,—‘¡ÚqËCËó òýƒF…L4™k®¿z‡¨A'¢:çÛ­Ûzœ{×C ‘±âÝÜõð¢žÉÐçPM,×rQZ#ûÏûÛC5‡Ý¦¾²ùħ£ñ*'_"Nêáwê}¿W8-õg·§A%¹=åÐÌsƒ‹/œIwWÈÊ‚6©´âpv¿HBešÒ‚éöÃ…áªk$»B¯?Åä~ò?_;FëRĬ‰4øß¦ó ±j®×ÒJŽÛbyެ3Á8BM,”ˆÄ¬S÷K'¾Ã:Yu|)ßG‘ÍvÇ&òsD„6`‘Äm§nP_ ¤-Q ç©È“@mÖPt}îÁã}‘#wšóÛ:ÚQa«¤ÛG} ¶æƒÇBY vŠàÞ‚ÇazoeX3®2öË£d-øB-ϱÓN¢VÚI®—åB${¯wÍšêXëÒXÔsüùr’~‚2`®º™JVRg~ü¥U NðâË^¸g]vŒ]ج@Ÿœ¼þåK¯ž•mQ³@*ãÓO¦‚óü2ôþÊI×ÓHÿv‘î‘®ßß{Òxíü7ò5£èÀ²´dëw“¡kjðë¢énæi+)Ð*R¿Zó9U´%œC P;}¯ï¼¯:p™hO•ê\ÖËOwUEÈâ!nÎÝ´mI¥gg.ñŸ&slÇõoIÎcËC1õsDW‰K‹ì2×ÞK(›“-‡’ÅM;ÛÆùŒ»¢Y’åöï&KùjVÉÓ(—~ 8ŸÎ„ÒÆ½Üï'¶ƒIFv¢ت.#DŽ u–½ü>"½º0Än¬®*í~–Ÿ͞€Ýä§ÉÆ{ÉØì‚ÿ¿CåØý“8^ñ®twaƯ\÷ñØ6–tõ>o:ßÄs8g†cnÆHwBkP¸ÝtÕ6é¢úwI ÿwjÓ‡)<à¤u3þ¢ÁDâ/‰Áé7hÛËÑ^æ%/Åóëü²±ãW±=¶·I™Où_!P‚SË~^PÉàÞñA9OZ’“ [-®G¡J¯Y?ÑS£¼é {‰©Ô íÀÞ¦À)Ì&诹ñ§S ÿ0ãLÿ$Àž?‘:¤š`}©º› ˜È!ɳ²ë1Ìý$ Åñ»bk†©/4 yB‚ÐÐäj2š ±^DQ#TΑÿ´c¬ÓµŽSüÊ/¯«&œ.9MŒüPh8Øfvˆ\ž¶Nûc²÷=}ÈÄË5d¸½|á$F–ž \æ to8¦|¥Æ%éKX†^ÐÊvéph’·õÅqXý¤Êo¢ ¼:€¤$v~ö™Þb”âÔ^8®ÉÜÇYJ¸9Ù¾©ÐæñìÊ‚5‘úc¥n=Í ~ƒ·"gŽØûgò_Õ¼à£Ù½Þ=ŠíbTöt—?xø©Ù½øxŒÁ›‹Lu2— J!\ ‘Ü· ‰–ED-w~)gE1ôöÓº 0kñA²§hkMÖ¼Á ’EØM\_žHŒÍ‚Äx¥Ì «-ÊU8Ý¢ˆ(nuäÉ3 iìt¤Wgº}]ªßJ­hŒè¸—·Þ*FÆR/Í¿o±ž³3³‘®’"jâMu÷®FoS§/¿…`Cö"”)‹S¯z}ÆÅ*Ôíé})/G;Æx™Á„k˜¥÷zõ5ìÞº­%VøIzYé ¤èAÚr…@UMIXð€1ãnx@÷àùÌLøò´$iÁÂk\Ø•÷3ÌöœÂò9 'ïÑ  í ̺(Ä¢®’oPŠÖ…únn)±C¼ ¢žœibWŠñ–èá¾OøÂõ”çý\“! ¦=r†’Çþ–žç‹®š±S.­ˆ ædo¯Øµ½Y-le¬ƒBee-©%ìÎ\óhBØ œœëVf—±Â©a']ƒÄ[ø-8NƒíéAùR|ã™`ýN °*Ìü«J×맨á€æ¡¢m –hÍùW¼æÀœ4 :~âp?¾¾q?¸¦{é|ã_Pi »¢!ÅÒD[þV>©,ß„0µ_ìTn®á`Õa¥n bªŽ(?•.oç[àêÖä§ì#ø•ÊÿÕ'„.©YÜÚSö}q¸§•ÓóèC'&à-´rX=G–®âËï|$ƒ4ÜœQÖ´åóà{{c9†` ­šñ›+Ñ&z»¦p±O£A0æL¦Âóý`É®ç,iPdѸT–Ì_N+4ïØ‚ :Ò8Ψ¤Ì®,éý&—ÚÀpů•Â/æ5L‡0þ4¨yy“ÜŽüŸqŠrj7W3¦îO™…C–ðS‘Å3™ÏyŽû þ®/;eýDÉ0BEî‹t¼Ó*•±Jã½*þÀ z±GÏ»¨” \Ýñ°”Õê¢å}¤m^ŒÔÔe!Ï^´Ã%ŒJþߺ’ <©àŠY!rY¬P≮‹÷Bþ …õÃÏÓ;Ö¼SFˆŽžšq8±ÔuªöCšÃꯧ_ÓÅÑÙ5Žh'ìäÈtNjL¦> 8eñ„,0š—¬1ÅyÑ­eõ:öðÝL;€¢‰sޤKo8§ºŠ¡èº)L´Í2y‹€/ÏPØõîªX(\ Þ0¥¸ ãIñ*™Ê×]5C˃ͧÒ(›Ç¹Ð4‡s±¦Š8_…[Eq®aQ”®°¶æÍÄA±C!Ä‘‹Ø¢f2¨ÒXÝq¿>ã)$%m5 !3ר–qÙ¿ƒr7¯à3¡¼ÿJOêšüµµ’Z¾”u¬)63=ꔪðÉW¸ÎàÙ’G½#áNþü:ýjó&“ç¹”)×1%cû´ïÎ=¸ ø²ýîh6kûŽ!ãXä{ÿ—Àf—âñ&ÚõŠ©¤¸Â—Ù' ´&ƾ CIÙ%ÜlÑëL~üzÿ†“éoªZÆôf–U¿×ùòqÛèYùÚõt¥æ 5ñóÊ*)®‚ÂpVWû‚I žL©2Ju‹–÷ݨ'…„Ç•cŽž)@iA_]>Û«‹ìm˜5u–!ÒÝ{™V½éôt‚kÃÀXSY6(<»®åãâ¶¼•á-²¢r½ˆ²yRƒkº¾£CòD%=â‹‘M€ŽÜNÜ"Ó}£âe- øˆ:…Gi†õyl€i!Ê:& n„Ù‘§kÎkVÐòRwÙÚ ?ü-'ä[ß#Lt4ÅÍo!ÆF÷–æ!_‡sS1” æÜŸÖd–2q5¸Ó>âá`_NIH>Ë¥ñ–ØöÅ"¡-®ü© ­vÚùRæm†[a‚äXÀùå‰ózg o+ðƒˆkk™_©ƒ¨Ñû;ÝxFíäÓÜ<(¬Èœ*P*Ú„Æ^Ê®u2NÏm2³&p2μ V-V·•SÁÍ–Ì&[dS6ʃÀ[qÜÁö"˜NγFð#<Äžë‹W¥2Ïúã‘9S”X–† ~¿x’¯kN𠯙˜´’*bºÒHGŸ1€À?JÕN½W´*…©Eq&ò½YxmeÌ’>¿SZôãŸlGüM¡;;öh–R‘7ŬdÞ±°ä?u-Ϫñø—Iá¤{t6>ˆçÀ/Ruföн—)$Éý~EÑŒ’Abñ£¡g—¬~£ ѯNy0ºï°ŽO£"?NÛ‹ŠVD>¥^¢‰°oVŒ“2Ϲš-X.^N|@´Ó—q·à26ÙC‡”Õ/(y™á‘C(ÕqÈŽ½ãòŽ\xedU|k°À¤]/ã5 ^›ºhºªöïu">Jù:†™N*5˜J/˜j8PŽ^6_Òqpñ |?Å…·–›fé2(¯ÂS± Œ—]f !>ÌÜî*]ƒ– g–dnCŸª2ÞšR‰u»Bh4Vó7à>î§xü¨eh¾q8ž ©ZX|Ô1$úXùªLYë‹Ô¡î`’|vón´\ý’!d.D{ž 7agÑž•Â!Œ ^9;+v|,!ë§,ÍADp®½ n $À’O_^lS_næ z¼¸ä­ðŠË÷ä\]Ó¨ºs«åXßN7£tÊPå/HÆ<ÆŸÃÀ}©Y~c½Ó"78Ùøm "»è³•:Ø™¶?<Œpt ÎJV%Kx= ô’M&is»_6^ `ác‰KF2ö÷÷ÉÖªn¤‰éŒÆWd9º1üªBØâÜûbÝ!m¯(º”ˆ—ä7y?—m–q盲F£š4:5Ô@¼¶Ù„ˆt4eóB[ÑåÏÉ­§ÏùœµaIœŽ³&.ˆ ™f9­Þµ/•!ß³w%9‡¯àòe¹e2€'ãëuàe5>3ƒW¾DÕWYª»Ãl\O¬«¬2pá6 øPÍÄ× ×v-ßÇÅôGyÙ‚C÷IÆËvpÈã õå{vÔ¥o0¿LPµK5‚ËbwøüÎÈÔÐJWtÏ.挵i¶3¹æµYáE-y;Ñ‘þ±¶*¨8‘a;=R>‰žèü-|¨Õ_USŸ]Ú!ËjµQrªÉ†øQÊŽ8Ô§BÂ1ÝvpÕóXÄêD"±l‰t$ó犹ΠÆÖKwK÷ ÒÊóI%§!ÇR@( ƒÊF6P”ëÚHý~êyD{!xõnh¦-;ÚýõždnøGMؤK¦MÞVˆÄ¼­ž(Þgú‹k‹˜«°qpA£á©Â’ÎR©Où®"2˜ŸáR<`Ë.!°½$ë)›ù.ÖÊíâkmCžTƒ”ô¾Žã ‚ó è ïØUrku+Cå >5Pv$T0¯Î]`ÆÅdæ‰z)ǃ)^Y¯üg™èŸÇøõÑL^3¨"|þÎÔm®iDV7d¨uH¢¿|é Ð|I‹8/%ô_HË®SZ@¶Œº„ub8eú‰F1õ‘ïóA´Qç„YýÐkÎôaÐ-~ÿ…×Xƒ¬2ËÖýy00™¯lF­ä‚åôìaH!¼Ëm8àûÝ+#g¥-ÅÛMÚM‡?nÏ].ÉGÊÅ‹ÿ$N7!ÛZI®N·ªb­ –.¼mæ?YãwLVZ"Þµ^qäÛ[l+ÔÜN—¹z\ Qp¸ õšjš~¶ª,:.bJ’AŸðp¡Õò?v6‘ÐiPIoƒUª]CCo{–6Ò>ÇB¥îx˜Ò"ˆxAiï¦ ©ƒ{˜_æ8©}Ǻēcš'Ÿ¥CnŒ½L¥Ïûð>KÙlôtå<"Éß1Xdª¨j?ír¤îörË—³¹µ¼7‹B¼»ŒŸ Z2ÍA¦ ?®û¡ €¼û£6{ë%ë q¦çaÌ¢ðI%è}&Ç’¸¾¸9œœ#53á Õà=Óù¼2êÑ´gFñµÌ† ®½Y ÛæPůQbñÅõ6Z ¦€'ÅNÿðë½¥üX|¹µœf§³òܯ¸^=CÑö€íSA`ºBâY³×eªJ†JM1±·dMUKÍOïÊ b¬€“›+& ÇO‰ªu¾‰SÌÇÊlËÆ¦¹å(Æø36¥ ÄxÜáx7)>öàë ØT£*+XmÙš:Lx»a]?{ÂÆ÷UOu¾ZIò¦A¡„Œ›#Ú‰*-^üˆ •Ã,ËkŠdĨ+GxÔl®3¼/ø">ÜW<Ž÷t…}=˜Ñ<É)zþÖ“ ·å’n¶•Xþ Ëð}v‰n-Ò"Úœ¯È?øÀˆ0cÞ×nq¨}Êo„K[ïÈ–Ý4#à™î²û6ù”tbp#ŠFòÈ:A'›6ÆDù¬·‹›˜öåKòÄc½âk„Ñ«=Ö1Fú`1Ó¼¨Ù¸y)©ë>_æ;[˜ìï®Ãà³Z¢›,Eº‹ b¦7†Â|óe¦7'öˆÙ“šê´¼ð;Ý™*W™zŒž˜ŸüD@úÞ}Ÿeóõ(õõ~h‚¯•`/'G£ÐùBðwõk·–¾$ºh(u~IòvœïŽ˜1[»«¥¬xšX Çw¾Ãöh©´5· ÈW¬þU¶#à¹Õ5àí¥Ó‡8Ü´?$g¨Á/b%Ñ«² œÏÆä¹U_9ûìõ7çÚwt ºF$ðŒúo4ÁÈÏbu²\­=l„ezàRžkŸØ”J+ð.y¥èì·%N„ÑÆï…^(ýÉ}»"ˆŠxœùy“Œ¢üøL”ª#žxLãa1r¿ý­Ísj‡k–¨Dó~¼ëaî#!ûé8M)¿#Û{ÒIË D¡”°1 >8˜ -àŽ§xê‚nøÌîc|xx>ѤȖ8ä˜Ãw1í7§Êÿù5æ9pk0eôkªÙ[¹#C2TÖÚÁ•–X›l¨<ó9çBàÄÏhÉ·f½ļìûrX °8ñ“ºÙHòF¡ãÅø×Ù¸:IXV¤ dZÿƒt2h5»ÖÜÀÑ™PD[ëþç NêmvȘÒ1FæÞ¶Su ¨¯³¸±¬õ£ßk°Õ´žñ8Õûc°›˜(3DÛk+÷šîÈÇMMþüÄÒïlñ!ÃÝ÷Ú­síÁ&ó´¹*3» ú©î“áÎÞ…o°Ÿ¹ù¢'jÏ©W\Åñ›jt½šžüƾkC É}Zé»d)Ú‡Iûü+Q5W¨/4k¨ëŽm¤¥Õû"„~|p{êNŽÏîÆV^”Óá\<†Çù…(g¤EÉz_ϘûñɆòÞÈH’ák‘Oøì)«È'Âþ±ãY'n‚ûSr¸¨Ro6l!Ñûðû­µ¦1ãòµ~€ã§ñ`ëi­IÆÉiå=ë’ÈÐôÀn‹ïG™+ÇÄéjÒ+®wøe)öA{MÅ„BÆ”×ùFÔªI²ˆ¾a¶Ã47Ðw¥3Žºy“a ¢v{ÊàL¤L&/-ç–bìp¹èåjìË\ÊŠßcPDÐZc]»ÃpÈ™(e_Y{ã×r~(gk¸æ+pJlš_Dî‹ÀÓ ç1B‘L¡\…Íõ aÏlX Á’³<\0D‚ÏE´æm:R­Í¹eZŠwÕ™$·¯q«t®›ÑocËâÚßxÁŽ’Œö¦ŒÈ36ÑYëh½³WÃW?ùTM9íÍw» ç&½ºÀ‰‡%1Ù<8ˆ*Óƒ£I‡ðPz!öÇ,¶j¿ß ¹Çªu’µVEk|QUÞØR[»J"Hû!`ÃüU¨š‹=·“d:Ì=‘ïà®N1BOoÄ#µ–Þ›ms¢-Í~_öËs-ù¯nl‡C—lå‹l=oW/DÉ÷½.žŸ9ÞY±îr ýr^`'cDLïbÄ?ÓÓ¿NöòG²£…‹ùni½3 F[·ŸÕ®ôÂóu_a»qˆ¡e>„•ºFz®Häjr:‚¢ã“½ õ Ä¿4H ÁânXXe®,¬2’¿/1F¬ÿ­ðNù–O0ÝÐÌëv—‡vIoá= °SÿÓ õ>\ìÆ'¯œ1èc›ž›”?†nT†S΃îßËS̲ã(ö·cMbæ’Ï¡HZ©›äª»yï4p®ÁªR ¿%QIQuê^Ò¸YÑ'ócz ’S8“Ò!šåéc¸å i1N9Fäñê]ðÆÆA¾×ïÏÆ&rWã;±ž#M¦ o¨bÍsÅ~3;3Ômm¢kC÷Zdh¥ûQ$pyÔ¿&“Z±ûÛÕÒGî¡§ WøPæU¶nó®-e»ÎNˆLv }l»nýÍD¾yÂ’²%Ρ¦–¬¯ÄÄG-¾ö¢g¤Ö° {±—3€ž×©JÝÝùu1×£¯Ö‘©24ïA‘e„œHSŽg9Sø™c΢,_y6BÂÒ픩s"\ƒçNœ¢dɸÀ‡ÑÊ(uFÏ‘q·©ÐîôÉ"ºÈò¡6Àè‹Ê; ‡Sµs‰òéETÎNèõ°_d»Z?tÓNÜÊhô&æ®BpnÂ(¾¹q´.g·lÖëÍœÎFPš0§R?§‰ÜëòÞoˆkG”hHWq¾ê>`Œ´¼gP"œMN€fÞ¥e']âªw‚4N¯1+'«ßÊïuˆí"4m1– \ ½ |º©©]lE™ˆè$ðÊ<õõ–†Ý]/¿ìê2¥÷¦Àtº>ĵ¹Ê¥«ëÒâ¢Cõ¥.oRÌ[2o#<=š"ꡟރŠù¾Ô•v»A»FO.I÷§N¦sáT{c<8ÔÞá¾K„°ç¢A<§S7PR w+5Ü0Ñ|ÝÄ61U@úêJ¬væÂɦa’ŠênTyÈÙø[h´½ÿÛˆ79¡ñäü”BF/4’Ê£{.ÁÀ$‚â}4Ù·§à„õñäj!›[š S>ž˜|ƒŠï4óî1]£¥&P‡ñ5»xØ<± à är¼ÃŽu<ÝOqY¤¹W“îX-8›¬.eÏ»[™FDbå¦oœŠ—¹ˆå)÷àDI+?U›±ò~1 ¸^­OѳÔQ€r‹ë!ÚÂê˜ê+ÆF«?sÞ#9Ï•ƒsf8ù¤ï Sozq'„nßâ0‰¬ÎvË<†YX›kX f^ˆ;CNë«Õ²_”61+_²•M|÷!ÌÈ"eèœ 1½­ÇØòw†Éâ¥<¶Az›êlˆùÔ ŸŠ";·U¶=~ÉC†žÐ†÷.fßôåYB¡@+R€Qø·–%£úå]W,ÌL}Ûn-çc7ÜÏj$\ݦ;T¾XEí“æ˜ˆrwm××7æþ9‚l°ÌÕ¯¨ÉXXT“N¦éá3Äþüɳ÷¶Mðª‡`º“VDËŸu˜ÏL¾øÜý¤‘ªB„¤†òå¤7±!;u÷5 ž}+j|ëMêôP…+¾³ü—¦5ó'¾y >­•ð‹„„¾yh‡­C g|à©0SPX`©–˜¶ð8`ÞCšê¶¹ß:'Ò®±§ã}–ñàh䫎a)0ÿÏVÝÙçmŒðê–^Lq¦œóE×20†¼¡üÚ>34ÆøX]Óü”ÑÎó(À-4¦ÊÁ¢pOħv$4Q~j›f:p¼²lJŸ­€Múížâ"ñú9P1•yvUôÊÛ]xq‘ƒ(ff»(Q3+„”ëh”ÒÙÅ[ØAKuS«lÖã ¤ÉeÇdÁfý ˆõšûµê – añ’ŒÛÈûu²Æ¤.[Bâó¤֯[¬ºídسvþÆ EKÕáÛ”Æn¥ø3]Éï} ‰NºUARF³@ÒoåcÅtmÔo; ½Š-aúFß6¡âb4™¼Ö>kè*©Ë·XU@<Àe­Iy~Å*üf¢õD²žš¶Œ4'T¯ê“—ȧ¡¿;†ñ%*«½nµ™—’vrè5–k Øë0=ÒƒÇÅL\öjÃæl.6ßgóGÈ=’¶÷R«lˆdåƒÅ:j9þ‰8«+€umRÊJ«ñK“ŸÙ™Ÿ[®D/8÷mðWПžÕ Õ W%Üñà–®CSß1âóé¶HXçµeàí‹ÜÊÂÙç±ßžv]!SÒog"ôÐp(—à»$okÛ5´XÄò휇ÂçÊ-þœX¬™Îvµõ »ÊÖmn°çÀTßþµJ9Ñ–;“%¿ífé\eÊm+cªœœ Ûé ¬wzu¯õ`lðn–íû*’•þ-2£Uÿ¡’wÆ—ï1Ã}è{¯÷;Wàíô,©kÏÝåˆ “ý“¾0Ľ1©”JîÒe<ã¶ë?Г{:DÁÑ^ÄÛJÁTQTœ*Æ.åúïCw­Ÿ:]ßE9d+ŒìrÄ¢DIçGËYÆF®K®ú&ùÀh»ó…u‹Þ6ˆ6<–ãë•Õ 5)rB`Ér+ü^«bá+jJ)ýø{˜XðäΗž–õ=½“RÔ!Qn±­9$×óŸ¨ü¸ñë‹?Œ% À¢TòGæ$Ÿ ÔÄ^AwbL ýtâc!–ÿÁÿÅ^ô³ìX\V51ÄX%m›¿;]ñ õç³ц8Jy s==€Â@aaKð5 ¼ ñÐâÓLyµ_ƒ»¢”ªHép–TæƒU°S”Ô´°gRÅéŸR¾ª¢ëÈ( jt|Œ c³%öÀlõÞ"¹`BŒ Ýìj òØÓ …Å_N­ÅFÊÀIb‰xÂT¦í}ÄÕËf„]±22cUàRáÜP<ñI–Œ¨ÛúJâj%¹„:¿;̈öáiõÎ"TКãw2`Îý&;J£yíÆʸÐ6d ¼:y¼§qË,oÅE±=8ë6“”úÀ´îúÈ“sÿÙ¤«¼ZJ«@¬cúMQ;ŸÜç.hv Œ®†~æ.klòëxLsɸÍÃ1éNsçRYßÝg:ãÁt9—{¤Þk81òúÙ^³ü|=á°äí"æükc—€¡÷é]ú×µ'ƒˆ6[Ý$I]+ö¦_µÛ ÕÌ, áþ¹IÜž ð=L‘Iµ§ýÍ‚ðø<°Ô.ýgAK tôBÁ¯}¾3g*²®ûo° &çâ°xÛæ0à“ssWžÒ¿§¥ƒN¹õ†þ¨ÚH4ýzFT­ËŸéDŸèh¯°˜Å.´ùÛ“0ŸèæáQ÷™Š¤BÖçd:æF–J·÷2{þXÝjøèg@øÛéù|mHy †gK}DÃiÊHec*oÑX˜V™½cÔü§Û¾´-Œ€V° «AOè’¸·+¹lð*jWuÙŠ…›Òfˆ9c­[šBêÖpÀM\Dy¶Áx#˜—¨›^PØk(+ºú&#V,2eæg Bï͘¡éˆ¹…B&Ø… •›´²­ç`Q/\êù¯õ̵ó¾îå(ˆúHÆÎU…Œg˜ÿB ´ xò8´î㸠ÝèÝçÀtÉ]Œé œ<’äÑüÖwß¶)x¯SCylÍÊ7Ö™  †ù8£³ ±è¸ƒcc¼iG ´Û{RM)÷^¬j®˜ºõEàIÂ]ëD‚)×mâ©ì«—æçPõ‘ÖUÆDƒS´ä/_B³ËŸEã²YÅ[½r[¡Ir£¨É4¥_yvh+¢^5Ö‰ åHž_a:ØcŽA0ǨZØ P â¼ç„ï¤Nlñˆy:z„KE0š/R¶¹˜ÌÂ0¯§ ¦ l²/ …+/½^Fðà *·š¸ô_Ý©(Öû™)Ø,`_¬}Õ{gˆw³ËéuòghŵZ|ïI™>é4 $·ÆãRrAòà6䕈p|÷gy<¤TТ,Gk.¥r‘®]”Oãá8ßß6DËv8ÅüB\h4!.²o4È’ 䆫\Íᜭ…Ûž£ªqcu…À¡š¾…Ù0†á)‡‹áC:¶¶úzR+Ô=Ô?ÙqÀ¾˜´Ì©ºƒ¯›dVu¨â¿ç;NÛ².£‹v¡ dÜPDMeP4V>Õó ç<­¤~)»Ín€÷—nÇÊÿ¢£ai3;N!¾(y€î02å^ɬ*ÅÛ‹ýð#ºë×ÑúQ¡ç‡ýS†9}Ï^üzý ååì<©u‰›×ò0Xï| *LRÈJâ¢ýÑydÇKŸüVQØwÐyÊçY2E‰ùÐ%q(%°´«$¶´ðÆÚö6%.ë•ßEgà%57Óúê"?ü¢ÜSþÿ$ÛùŠbGZ9E&iCd‡<â®RO/l8ñxm³ÉÞ+ÖÊ×DQýöñ!ü¿Ð € Ì’Øy (0ÎBUÊü#Q¿'ð=Îõ‹~­h7J oÛ°²ž˜°GwIMž =±ÁL!fÕÝÔêàu9]{ãË þÔÙf²ùâ`N±Ê £äÈ£L« ijÀ< ³ŽyskñL¿µ¥ Ø Z ©Mø«a{«£¥í <¬ZÄ1È“`}ÿ¶K~;Áu㻑7Ãܺ÷„ל/ …˜fi;i?ç"­pÙž/Ìæú!™C ñपžîÔnˆq½Êº«ç× B`‰ðÃ^ÇÔÓ³¶×d›‰G%“† ÁyxŽÏØJřϜ8é±~øqß85ÆV‚{;I¥ô÷5œˆ´P4½ÏfvJ v¯3 ¥9"ÂDM@ªÉ¾(@uXMœÔïÜâ?FZüªŽ¯É‡åùÞ;‹–Y×€žmš%œÈ…f®ý¾&ÔáO•±•žê” a N²L¼Òý4™„“ur4(Ç@dï.ùò#‘évÀ'SuÿHæ¬;.3¯¹‚ž”¶]™–ÆÙ*»ÌîkÄ3=5dQò®\z]m²ÝÞAIŒÆ¶ÔCdÁÐvæ8›tqüfl±”ÏM')×CN\t_=K ®Uáä¦ÂV×…è£×=] £µºâC‚Ë:¶H5¢æâsUúœá÷†×-ëëaëG8¼ è*©4”®ã Ï©ÍXi¥Pù›a¿±a‹U¿IdÊ¢ºøSF¸$h¤¡†ƒA?Ï­q ¬›/ â¾  úAýè. ¤¾IbNûCþan ¶±+Q|ðîRS›ûâáøJ¬ú\GºŒóf(@ã$ •òÎúPÑçívû¢C§Xä-egBÈì0Wy–³ˆìñ"®b)„`šª¬È« gçûcÇÇ^œÌák×êÍҥ㨞Þ[®¾ýªwɰ@«ós{(ÌA%µ„•NNåMCÚ7ˆè«*‹Ç ú¸0”Ïk±Yã³èÞHd 2ÓÚb¾g”®qTžŽÔ¦[7NáJÿ‹‡@öT&A.Yeñ¶n‹0%<kÄ¿_$f-IkØG“8ä/qU­W—Ô&©=iv©÷?m„ñ§:¥°ºf¿ÙV´%Á'jÑx·…P—iyñ®Öžb½4e:˜e›ôE—<݄ŶÈhä¤Çê›Í3®­…‹¶¤"ùŽ\¤ž§ÓÂ*6Izšè·@3:š&ž» Ýâ¼C¾ÌJßÎ/¹&Â{'ð;*¼måvNiiªBcÓü È™ 8BÂCv†µÔ,<õôä&˜<‹ûÑuK°-Ísí÷yŠC—ü±Zòaž š7«.0á|Ü­Ùç‘ÆN¤Mãðƒ±FÁ• >&öéZÞ*£¨bWÅôl  Ð6µ¼ˆAq·¥Ñ®Ñœ\Á¿¶XN´BÚi½Ý¨“Â9br>%‰øù‡®–vqµ”aX“|<RSx ëBq;ÆÊÅjj?<äßLƒ6nÄ ¼ª² î— Ó47u77÷ûŸ{‰§ –€|“ð×fÚªÏeØÇpN*¨Þº³oÎ+QÅz©9$ö,uËoû¼R"Rw«¿(£ÒஞS4fXÆó€©ª4`Î ²ÒÃõÍ3ŒÝ&ûõÀ endstream endobj 233 0 obj << /Length1 2811 /Length2 26808 /Length3 0 /Length 28371 /Filter /FlateDecode >> stream xÚ̸ePœÛ¶.Œ»„Á¡qîÜÝ݃4îîîîwîîîNp×àø:k½³Î¾»ê»?oQou?cÎñ Ÿómȉ”ém b¶6NtLôŒŸ*@ qw  ÐÁèH'dke `¦gddE 'v8™ÛÚˆ8?8œÌòFN e3##9@ht- ݲ@'w; €Êà/ `ëèDghàZÚ˜šÛ©A*¶vîæ¦fN¿9Øé~Ll~»øíèæ´qYuüM*D20²´uu´4ؤèeér¶® ¡9€ÊÖ`43°2ØšüE¡ª,ª¤ W’WUP¦¦¨™l @FfFN@G€+dÇÀØøo¿% l*f@Ðc`cFrQÙÙÎÎÖá¢VVQ§ˆÊ©ˆ€j´qUeZ€œ Hø×Êo§@_’6Ææ¿ÕeEUU4D™~gÀpÙ4ÿíé„C ð'ª‰ƒ­õ_TfNNvŸ\]]éMèmLéí¬¨P13Å`ë` }:­€¥ØÙÆT'P ü.0@ÆÜ”Kà_A-Ê ÊIЉ*«Ð²E÷;átWžÞÉÍé¯X”DEdEÿÛòoÍ­€ŽÕë7—1¨ÈæVŽô c ¬Ay2êôï¨A…qúí°Õß¾@ÑÁäµ#Ãÿludø ˜¼œ Œ¤°¨œ²è_^Ú:ü!pr6ý­û¥ø¿Rgfàø—Ë2 2ksPרüs2prvü%=@c’¿“;;8üMö_KÿŽî_å²…£cåémàúŸk`ãìèñzÿïRÞÜÑÉñoFàÿdÚ $ÕÖÜæÿ¿v¿~S ŠÈ€f•À zAS,jc,lkm rÜáwWˆ˜ƒ*ädëàÎð_FßÒÆÖÕÆó¿­˜˜ÛÿÎ2ÀØÙŽAÕÆÜÞ()ò?ûA"„?2S €´²‘Ão“ Âo1Óo1(Þžv¶v+G ·¹ ôàéhàjQg ·ç?þ7B`â›9Æt¢ üÅ.icb àú[ òä_KÿÓ€TfÔ £ÌØÖÆÊÔ´& r¶N V¡úý0ú¯Åœ­¬ä@Tÿgyþs§µ¹•ûÿ¹÷?¶©Oõ_ÌÅÌÝ€Æ æNFf×éo¹¤“hÈmL­€ ÿ%Rý}ðX¦tÞ›ÿ¾.tLŒÿ¹jt#K £#€íï% (}ÿá3¨”¿=0È I‰IHÒü—&ük£¨‘­±¹)¨ÃÙÎbfcx2fÅèöWëèml@*;g'ïß…EøÝìlÁߢ¿;€Aèâ0ÿAœ‘?ˆ À úoÄÁ`ûƒ˜ â3€Aâb0HþA ëÒȺ̲.û¬ËýA ëòÿFœ ë ÈžÒ²§ü±Tþ ‹æ¿ÈžÁ²gøvý±ÖŒl­@µý—äw‰ŒÿAþ‚\2ù™Al&æèX~C—ìg±™XýÙð[ÝÖÙá„ 8Ìþ YAY4s·3þÓ!Ìüœå? («@CÖ Èü*6ª ¨iÿ-`QÛ8[þ>QLÿa’ ´í§@œ¶ÿÐbbEa÷ á1HÿØü€.ÿ ˆ ÔN6€l9™9ÿðƒ&‰ÁÉÕö ¿ÿTÄø×K£‘­Ã?¼b©¹ý‚xÝÿÄJ“ÐáoÒÿ=Ÿ ¿o½¿NrÆ?û?¯8ae'[K º¹1èEñ[d œÌÝ´AÇ0Húû×7Ýÿe€üÏ òm!![7O:6Nv +ÓïFaûwNïÿ¥kô÷Íü×:Yþ…߉ Ð h„°¼`kÄd‘ÚRâ#š7U MÎEZþOC*jùËT¶È·m ¾“_E¾­ŒÄ']Ÿd›B ò L«×õ椊ÉcEY<QÁÑl5zÕ€ Ù%¿Òê#©ì\Í"Ö™Œ–øB€êè±0W[çc4óÄÚU ‰NiËZ´kÁS#†ƒÕ{·¥w¸íxKSíàNo±Q=‚Ëg?ç†|•‚±ëîDßÏj9ä;P§2bDïÈàõE2‘Ïf‡ëc rpQÃzi=£âØ11–Gíá@àÀ H¬h™9Ù;+šˆäLœàšÎ~›8š·ºi¶÷¿"—²ìdZ»¿­~Óà#1væ… ÐògLeâC±z!ÁKâ ªÔ,/Œ}Çö–‹Ft1Óˆ#Éé«ãè"1ðâ²Þ8:]þÒöͨ U gTþÆ%%·QëfüÌúNQ`ö’²€JïB´’ÂÞ¡ª&呬ó¯p¸5À6ÎÄ=¨µds>t,r; Ù,ô‘­‰1i…>eûþ&¿*ŠUõGø›Ž#Uœ°ËÈÇ(ăVóÊB̘œÆûÜFkõ,¸DÙÇfý-™­r“D¢ý?Žñ6$^t×â&Y8uÔ4=z2^®ƒçÖ—õ'QøXýY·…mú¶Ø?~N`ͨRt8ˆÿªp7bxòÁc©-Ós³ †„"„¡Q‚ÎùÚ‘q5ž™s¥GzYe‘:D”ê.x `¿‘ÆýÖýÞt°—¿S .줭X#qöÂ^œx‡hñX‹f}¬õ·F Þ³—¤ e î}ÁñFÓ©þÀDgB8Ao8 Å«Ûå3™x·Ã2ìÅ#ÄéÎ{ÁÏ`4 \`OùgÒæµOvJg¯Çdu—‡ì> Õ¬áQ8`Õ(2)Ôu W\O‘ òÃÅÀ08Ê';¼ ¤º|U/cÓš÷.Y.ž°¸4|ÈrÝV“R¯DszMh³(Èç÷E¶ËªÌø¦2Ã¥`†KÖ¾*ÇQºÓåœGJ¨Å ã§×¤Ù7 ¡Õ&snR:îÎ}N~CÅ“ÜÇínó ^šUëx ƒèG¸¿7(…T£EFÕùm1ÃKP&$Í+¬žŠ10¿ÞÑ^Q¹óåŒDo/1 %!š77ª;'œŠˆ*}*G |?ç'À$Unòar󆥜ñ,«ÎŸTô‹º#|Á®¹ˆÒ™Çÿ묊Üq$EƒÕÏ¡'ÕwUáÃ.±ÏŠ÷„€6Çñó¬f„|Ži9]"|ý˜Õ6ë·Äæ×)ºè;Vrýï^ñ*hUß¼+· aOèü¶7­ø"ZMs³,nåMgÞ[ßg¡4ðfÃçzdÄ ßÌke±/¦m˜áÑ×Qm8Oõ;7sõì4ã¼³(W¦é¨™~XÛäm¨±wÞ«W§%/Ü—Q""¶Îžt`.û®Êî´b6îŒë]ÁDþ!ÏQ£6CœŠ­{}óE”;î5?gb‘%@ö!¤ƒ–øÍ“¥L])ɃVZ¥Öòó&wœŒþeµS?=ɰW²8»ü0îPlÚùöÐøp‘«×{µœe#¿$¶šFIæHòqsø®KÂècEÜ‚Nk‡ÓKèbž˜-a} \ÄvÖšÂêØÊÏHýôq/ãDúÖT‰¯d÷ê<˜’CT·ê|?eIk̇4Ú5HhZÁO+:Æ^K’ÂîKêw/4c$ë#}9kTGQ«† ç¼ÞÉá-lg|O€IEF9@ó½ÁÆ*?¡ÅÜÇ*P6ŠŠYùt3—£FZïb¦µdíÀ«Ü¿E|L©[”Æö¬r.X“;ý¬”µENUÛç Ûšây‘þ¸à.H°ô…y4"áÓöš0˜;q¦²€&ÖÜ/¾Âí"އ_Øù”5|Æ< UΨÇÇÔr 2@›ã!#—}º÷Ÿ%Ëg)ŠÒb6Üíˆ ¦¨^tö?„¦ùáŽÄpe=Œ%ÃÀ—V5|ˆ¸pàšœÄ„ÌË :Á¾ùûM"·æ§é Ò’yÀ+‹àÝ…P í°lOÅ#?ð©¿[êØÓÆ`XÇ©J‹ÇåTö-²o, ˆc OöjAENÄ–ŠÁ ¶ƒ¡&+5ºœ–é±>{“"O§¿7Dú5s¸ˆ‘€3´0jÑ+KÊhº[ ïë`u J‚ö´Z¤.‹æÁúäîב‡D 1¨Þ™¯¿(áĦÉV[Ù‹×Ø(LJÿ“á;ö;\›p>tqÌeSÏÄä!'ÍLÎÕ^²%9ã+ï³…´ºG˜+f÷¸ð—ž‰óÌ|&vô‡n;+=AÄ®ßÈ­PÎðÆ¾‰›’Èîà.êc%¡÷CHôò§A0Ô®ìÌ‹‹ e|Nã°ù) i·¯Psã‹…‹Bùj žI«I…vIEÿÅor;¿þ Âøò4 ûÅ¿ 8GAø©—Àµï^ÞRaxÜrˆZgœŠq÷ªÜsø›b9G²ÉÎaö³î‘2àLÈ—Ö Ì:M=§ú!kv‰9e<ÖÌ>m¤oô ¾ej¼{Ùòt±òÍG0”ìÙèaÅÔ{òŒM>ÆI‡}³häì]ݺR!ü ¼#çìöÇ—3¢q»ºÂ`½œ±6̲o™ˆq¶ ‰yãa, 6ơ٠v‘àKÔ£Ö9äï±=ctª¯¢ƒÄó©&­/Ýø`ô·ÄŽr‰‹Õ‰lè¢-£ªù·h%Ê‚è!¦¾~}ö¯dЮ|¿¤í<³0À“+TLˆEz:ò(‘§Ø~ŠhÃàíN9LÂàRÁ_t[›Ö–qãÁlzE3¶oÆÜ”Ç‘¢¥#¢KÜ=âïlÖ:±P\Õ –àcâ•ÏH¿{ÏØò•PµÜʤ•¡]&a†¸VÞˆ®l© ÍuM,6nescv&`’^‚®J©=3¼_! 1]]¾§«3|âøT-O;4§]š °Z&\<ZtXp>óIdÝXŠiœt½Åè ÕO^N0˜ø)×ué#ã2Ô¬Ûˆ4t8ddô :3 _Ø*UTž°Õ˜þ_}oJ ^¬ŽÙߵ<^•ŠE,Gè[ÒÖ¦õR¿&ô|/:~ÊU5$sõÓZøÉ¸L„ŸâS')qsËÌSl4áÛ=<¼@0Rk¼ÿ0ì|øb‚x–}VÒòþÕ%ˆÇ¹‹Reã ŠX8*m¨†ÉÚÎâ,7”Šè3õ¦78CõA”,Ëdà;ÅzËj?¬ó®“@øy츠TÉTàC!éýÞ½ÂÏ•LËòü¼ÃõV X–‡~º{²6ÒrÕgµüÛ¶ú%A“:þQHçÃðÁ®Ý¦š„cÞ÷­Š§ÙûWEí‡Í”öž.D¢¯©Þ$Юܿxtî{>çnï¤q±½Q¶”*ÞîžÙFIL|œlGôŒT*œ#¼<÷2¹Kí?"¨-Yúó¯Üd–ˆp)ËèF¬vd¼R¾ÓßÂÔmÑc„1꼬~Í–Ú ±ÇöícÉ™ªþÙº.C¼³ö.رíhXÓ¬,”ž¿'U*—h–Û$“•±dÙW–´ÚÛö‹"<ˆ˜"ÄY|¨Ò a0ÂV€yh>Ò0ÕÔTeF¾­ÔY…¬mä+$þ‚,Û;®~"AVªçXÈ­$G~iÅÅqŸ·ôAoCÆi´ÁНˆ ™•ó¬Y–¼I›á ¦c·.Äjüsá¶@åBàöñ›iÇœñ qõ öôŽ×G<¡Í°e]õq'_ˆ¯Gv·¦9³ßª<ÇÈ;'¾½Û$Í}FónM´â/•©1Dv¢#6x ¬LÞ:3 _U²zžóÀL+v9ÃnÐ[š$7)12©¯¹LÏϨ¢ÇQ0—VÇíU…'9àyë¯p2tÈeòál‹Þ SaÈ­ö{i•ä´iæ©·ÀÉí–”5’D4L¿•i–S¨F÷þZ_™È¨¥¿«œèp]B†ê]²-UAÍ,Ëá±>,”î!ÊU0Æ¡ŒFäŒ÷²¢‡d2…Tˆ&õ£ŒmnÚ"{^+Í€2(¾Jž‡$ nËaRœö÷KNô±Æ#GçÂv4×P{{9@Bà-˰VøÎ>¾¦­¾‡ø_†f/ò¶]/‚™,ï~šÆý û±¤“ABCNfGƒ_'ÝmŽð{®°c6`äÓ•$þäÁÜÇ5å;ÏZ*‘e7çºÝ!«{Ã!KwtÅ/ÏÍÍøuôewt® uË$ÌŠÄ(HÒçO±ó1grèÕ¨m’*©àÓSWðOK‹¬·µ‘&¡É²bŸ`ó>+lª˜ ¢1~>‰S5aº½Ð×f¦eš˜»ÅÊOîÙ {æ{}ʆ¹UÉÆgè‘MŽ9wÿÐtGè×#_v§+iß…G2¹)xÓV0%wc¨ODŽ­²Ýý£O} Ú^ ¡§î]÷ؾ*ϵµ=j\‡HÃÖ<~!ê9ÒG¼Ó…+úJ©ÌC-jî©ïº˜@¨÷Þ— WÖEÞh“nÝZ—Ï~ÊîÞÉÌÃç[ã±bý8Ae·ˆÏ¥èÓ÷îW>8õqj•ÆiÌ,?»¥jZš+åº0»"DŸ¾¾Óç\«¸6{ýu/4ð~Y|Ãóƒ¬êDσËlòˆ,ØÒ­]^"ªyõûÐ1Y¦ÖÞþhÑÉ$Ó¦ê:ºº‹2×{+ÅtùX‡Æó!¦“™œ¯A> X‚ùWKS÷"9⦥j"ÇOÓA±]£¥&0‡ 5»¸XŸ â†éBÂHHO„Ï4ò§~Ád ¨Ÿ€öyB•´– ÌëA¬„ÄõòÎñç|éãiv‹£pâÝÄ\³$…N§2‡¤ª5ô×.MÞlËð”HÜ`…‚_΄vÊدj©Z\óÂãZæ¦ýâĨ¢3Yv¡Û½šQƒôÝDKrÙ¥—å~¬ŠNh¸q‹ EÍZZ3i«¨Ê<¡ÞüâNÏ‚##Í  –vNm›v¦×¯Í«M¿?2 ¾Ï§ÐeçØ§ â*6›’è(ý¡L´¨9•5.àNI3ùu+Ð1ò‚=ÆÓ:û¨>¤l¼0úYV4ÃÇÊÄLQäXfc ¼ç{‹-úbJ\îé¼ íÆÊ¢Áà6K§úzÁ/”ÓÏN—,r¤ÑiÒsä>š Q=0Òo=v”¤VPý¹„ Ê$ÌK¨!‡¸û90Ñ))\|Kñª>­Û<Ö´û¸óÆóÃöÞŸ 5oXך¨eoÊ'ïjlÍý àt±´xžäy¡jX˜×IY“1›rü9yÑ×(Õ2ª%ùDІòi¾… rô­»ƒu*""7„°Ðe‘³¹åÀ•²÷]qªÕÃ÷¯þk»¤g¦K°>}BYÙ¶;_­úVªvVž üɦÌ«`”j”­ ”Ç[5fÆ»`Øñcà Ôå½â¥;²ÂivàŸta’Oî•C9ái†TPj!×ÍIï¦ZÍš€×»­^×ã`+1’Làt¢™<ƒ_¶fª +:u µž¨;Á¢6/H€ì¥Îáûh‘,4žÜBatÜ…µUÉï°[äÃ¥ŸNŸ ,ožoBçuz|44Õè‰qíÚgÞ·Þ±tK[˜Ÿ²¦Î,IãÜÅtÚ“?C$@™TÊõÞPM}…U"ØAõ+œ|.GÊÙz!‚^m“Þ¦qzeµþ2ËXõÙ“Ô…€¨CmC%¬‹ÑÊf/¼ç€Š¥¹%£tV¬r¥ »¬ò‹d*üý>¬½šj]·}ÜøLPÜóÞ(Ƴ^»‡ŸºÃÉW÷`¸¼(dâV'Ÿî²Buwïã¸Í'û"Z†¡°XÜØvzL8zcŸ·!»ÕÁ…‚2úk§D´—ƒž«ÒîÒ[Á'Gò;v¿i¯BuBèzÙMu USßm_§Ç0'Ô8áª7}s° . Æ£­ê£…zÓpb¼Ó.ÙÀ 逶lW– jψv²ÂˇÖBÕúFç¢6çéqçHâ9¢Ø²¡<ßü `hôh9aúèçxn*úî‚YÏÜÆÌ´Ü€VÊ3/»B- Gª6 M_Z EFäÍ”¹¾YK4Èo#˜á,5ŠÕúZìá')%íôFv ÆCþ|&´ÞP÷7”äÞÏrÅ@슔¤e"ž($à³Iúñ:|ƒ-X\í¡x±ãP¼ËlDôIžoð‚WàۤǔôõHØrWÞ‘Î÷¼EÑ ˜}T>‹?„Ü{LÿÛãõûí4¼ÐF^5„›ÍŽhΡý’$\ËùN¢ÃY¿Á Ì IšS·a‡B(³@Âú®ž>ñ”Ïútí–Ãz£?]ý°–S(yЏóÚy ø$ÇŸÅÌÅI×EŒ²œJƒz™Ïå75ý”qMš‚õ™½Âka »üÌ ”>rkÏêNqùþÌ9.†þìcH ˜œ ·¿¥£\¿É$ß`µ¶0cžïpw'é„èÖY¿ ZóÄ=,?ìr¥ª=½Ž.˜ÍÞ„7ÕÍû¬$ùĺHÞ)]”Õ®‹"\äµ-É-*13Û@jßÒ´_ÒEhÛ¥Ó–ÜdpôÎ"ˆò8›84?& ÷,;ÙfÔ¾:³=ì•×å/gÌ>›õ‹,¹ƒ 7½­µE&_6¹÷p[_"öŽŽyR.Ä@åžÛpˆ,æÉòU_…“ ¢B }©ðqrÒ\½jqQrÁɉ&vªs„7r¿heha4’àÏ )­h™Òm^J£o‘´ ´¡Úz‰Øéâã5'¦—܀ΧŸ ëXëQÎŽ Ëì¹Þ½°ƒ~*ªJ«ÚpcËHhgBZªngîŸ3a{ºè?åoYJ¹ùRy2\[™Í½™\E糘ÅV‰óNH†™Ö}#{!«¶h—ç@õ5èçê  ûnG"|‡ XxÆg‹P©²ˆŠ€‚mLXg¡÷󱆘µè^O¶×~õ©ª$º;ÝË»É%®Hs» ª1§(‹g—”^ í2Åú ‡àZÞ«— @>{fŸ ^'³Qš ‘51ŸI®ìB<ü’ : wAЇXý¡˜DÑ&ÞçÚ/hA’*K ì¶ÐAÍ-VÀ拯c‰¯ÿ‹WsÓ€±Ò˜‡½¾¹ÞüìÎ# jº_31¯JJâ B×é8Ë<«³¸} ÓŽtö~ÝWÔ¤èøOÁËW(VÒ8mCIÉþ+ ‘› ®ü¥!þ Œd;: é/ôçÂêS!{ÜÜAžüYÇXx0ý">ïûFlÖ™N›§Þ±>d¾ëšm8TŒ !SÊS7›T—s˜ÎÙ.ùG– ‰Jƒ3mÉ“±¤r7pþÚËïÎsÎRAJ`™aƒxŸaÛ·ãV TÀ¾b-&²ªûql¦îZMž”R»¦zÎ’OÕÄ^7râ8äæa¨ÐAáúªø¦¦îø>¶¢rRGïÍ&.4zÇ%éw7¨CÅÜ×.å \$Ëé;¾ÌF~eé#3ÃlWÿ¡Ó­£ðžšÉ± ” —~í›Æ…íq´u4‡9¸PGÞ¬*ž˜WæG|èê®< H´89 žó0ëy«ÙŽËvUì²—C«‘­ jJlsZÈÝø('ëtsêÇs1Çdšû¨TÉ,[¥31&ÓKv“ìÑcd§nm€YׅȳT¯ 9…!V#· ÌñµÀ5xzâ6#Šr*ÌzìùŒ“£³¸çWíºö ޾žÙU>È:^¼¶çÜYå8l)®Ç$Ë{sä¶L¬×¹S"'ƒÏò<Ù/~¤ë ~ ª‡„ÔpÅ^'ÍdþÔî8þ,Á[dÀr¬3bžl »‰|ü”ÞbK(R1yMAâ[áùð±0/åæ# 2ž;Îv—ÿͺ÷ÇåQ$:qŽÕ¡Ñ•PRº›î4E3[¤a8I÷p„š¬ãÍ•"r™^l–¶ÓŸ›Þ<œ¡i¿B£›Ë˜í[b¡{dY N Yi­Øã;Eß ’•1[/5ÄF’ñZ+,Õ)ççèEúsHꓯv¬Ý”ºQÇè1"pIęK)1é§RÝ®ØEC#äRpûº{Î=þBù¹‡GoÉv¸PœšBß1ñƒxýæ#¨£ ·ã€™ú ¢uú‚j»Ó§ýI07¢Tn£ý”L\z„ _eoV‘åO&|ËÝ•“mŸfÀ8Y]§TE¿K©oú:Ñ7Ãb‘9_êãVZ¬¤*ލ¤ÀFÒ’r"°&<øˆ}‰–Büê¥I1ÝØÇƤ-ºƒÅœ#Ðø~¢ð*Ùþ%ûÁ0}ñüqav£ÏAݶ´xE¿¯>|5¡·]_ ›ŠÔ²Íèj21ïá_ÿH臗ðƒÒˆ§˜Ëà×·££ñ‘/Lõã!I²>äd/8«»ŒO›?ÿâ]C§!?ØðØ«#¾ÀõkZÀh(s@BÞGÒE ,‡|ᇛ@Û=¼÷Ê!©ër:54gÿvê{Å7zã0¹¹ý¹•_?ä“ÄzyWõ붺[Þâ.·L€éd"I—©G^ät¤l¬7ÎÄ[f3äׯ ?ÄÎcòÄwÒ௡ §QÓ å^v™ÛY Þ}Ïa”.F¥¬}"ÕIÒ´…á*û>ˆn‚^É“F« ‡ m®‹Ímôt s°œ¢§ä4€‡t19õVø®z,/¾éYæV‚[Z(]&LññKÕ»xÜÛípøÏ›vX‘ê7ëÁº{¦9¼ZÜ™ZœÞÏý‚¿•ÏUòʆ^’d•Œª¡–-K©èÆíœ³ê²ÏéÒðü…&²'±h HúeU—Yz Ðf,™Ku€’ùÙª Ü_QÊÚÖË¢^K\°…ö6å—dkÈÜ©P€÷Ô+ŽZìKXÆW¿ŽÃÏL!Éh?€j¥G2>ürÎ\0µpÑàŠjÓ^‰=_2E?0{PP\¤lÍiYba¿'S*Å0ÿÞ»z\sÐø 3û4§Ø<ˆ€m§Â­þÑù&Œ]…»ë>žR÷Ø;IÀõžï²û´¤‰gÏÕ@}ê½½w‚$w8@K`/B‚ä™´Ç̳oÈ\NYàDRTÑÒõܬ”颟ܨ/ìµa£ …aÏ+Âßé¿™|Îá¹IjÃ*yäˆ{Ýqë/?DOÃdÆ8¤1)€J`­Ê•J€IoÅN-ó\ïÆFËÀ!pú4o¸Êd&üMùviñxIZòTÈâ+ËÆšaH˜AÃ1Ä ô ©¢ûű­BíC‰PS~S— éO´Ci+Ç´°ƒÞº©Áâ"ÉjÀkÄwq5s/Küðµe¯ê¸mSØñÍ­š šæ¾{ NÞÝH¬9\gÛÜ(ŒõÄ…Q²“Y " ÈVçèÌ—ÿG¸##Ô/åG¼N­«\—f«ÏÞ}©šŽ²±„­—>쟞¿mŒa?Ì“‰¥çæ ÝËÇôȧŒš[¬6¤F[ eêz£éÀ•)Zë´´0áj{e”£ÕpU¯¨ĨÙ×ÊrX…§ˆß¥g|× ‹o±ý6Y‚·ã/민z¢üC΢øÛì4µä21{É÷Šä­²T $®¢ÉXspÑpFÿyÚºÂñj™'Ùî›"fS–öôG^Íè€è×_íõ¼*pðŸ¹^$]÷Èç;úf<¡q·Lœ îÇTIg|k=á6yk0ë•u¤ëD__[ Õ•F•“ì´Ž»÷ÀxõIïÇœýéFÉœ:}›“oè·$³ç “ ­R„=Rì qa¥Å÷ÅÂ á‘ÆÇ<òvcx&G”ÙbÖÈ B!*©ÞÑÌ4”ð˜5fÅQ¼£ŽÛ®= (“M|/XÁHC$Úý$#£f³:X:öYÕhmrvù{{âzcÔy”鉘Ëá‘ZiGèí›×!1"ÏI%`uFaª|QQÓÞºücÑÜñIБ‹°¸èC²o21ŠæÔyI¯ž=_|¯Ñ˜ÃMî‘D«†\ÈM·ßqÁä×;ßZ×衲WX5×LÌe¼x~"¡úÈj€Ãž÷8ÍÂ! ýàƒ:†-A¬Šô3’­äóéï¶š§’SO?nþ:Qjå‹¿"ã*k7,¾Æ”·V¢ ékÒ_ƒ e8‰î-£{/(¶]À\ã:TÄ[Ì|‹Á€MG¡ }&$Nãtx·U/¸“Úý5¯ò[:ÍyìDëÂÙ¹í4.úµÙXÞE¾ÐÐ ‚)8:sd#lŒ™Ô"Qþ´‚p¯ÒÂXëÔÇÆ?©‹ïºÜ?Ñ9RìÝËCÒ]ØRR•êíåä u,ަΚâë‹õÈ. í+¾âyN- ²<&YBäÖœñUÄëØ²e¹JÝÿÛœd„]uÆÉçŸÂ/CöUpã+æ\ðÁKœT¯AºÈKöúM4r›¡Í+‹g+³¯ÊÛ—Ñ™ø¸?œ´!Š =e_).Ï`w,Á D!&·(6ˆ‹–Ý ä—&‹ö…ïdÁ%™}QŸõ&¿`«|óÖå[u46˜é<èœGÿÎ ŸØ4ÿ(¶"È[à…†0Æ"lRßqõ`…¬7*}O¨Û3ÜbÈëD*§ú¢¬ñx%TTBÜ+ûÓHð%ŸjX¸Þ®(/JSÖέL¾»Ï_i”i¿¸¹*®iNŸ™ë«ÖñÛ3ACUÜŠ;E|‘¨­šE ¦»&º|† Ê›°ÌøZÊùÑ­ÌZβiÔ Íf*x¨$‡nB)‹G%•M*ÚüõízÐúI;2Ìâ>í«ºÍx¤‚ UìµBDgçuÕB±:—Z_E¥¯=2óòë-•߉mÿ»¥ u™Þ´½b¼)…Ï4AK,Mß[ÐèE_ŠÓ1=~SeQ"çK,lAû’ .¼»%á$8[‚}§ìëÁ~„ïÅI?£]Þ‘*l©|>dé~‚¶þ¡ÜK!büÒäovæ/Éš+Þ ÉuM'JÍ{œÒfל¹“®©ÇkR‰ ppÅ@”Ê%Q[)¿lžÜqàÑxõë®’EUœ”s0h`Lž“r‡b[|»¶\ø”èzr1°æ pž&U'©Gr‹’³XÌhOx¸ª·+¼?0wþV›ðÕò”=ž Ñ󈸢‰yøH†?‘’L_ÜG­Ì}Ä;'šüÚŒ` _lKv–'o5»«æ‹æL/Õ˜uRJ”ìŠí¶XÆÕ+œY…þYÙ²å¬j“[õ/SÑS|jô¤Hé)˜—Êï¥2{vψlù*Ûñ£”ù’¸\‹d^{hýÑéhø± Ø/^SÁémŠcSW§€*à ÷õöÏá½cì4´AQt¶³9|¸ÂÅ`¤‚‚ùz÷OZ 8ô!<%ÄÒ ÞnlŸT¿ž‚Ö^HÛCœýð‰ö I”Þª ¾_þ(2Ž=4V¼5Ò£ñ…û_@/&c+v“×r.ºY$ ×”ÁDÚ¹…ò÷F b©Ñ$Qf"JŠ<ýô…âx ª¨û¬Ç³”;mU•*ÊØAl ²jxÁÛàpÚ2Ü6ÃÇ0âVÿìñ•¿´¹8/ ϦÌò[·Sð;“ -+DƒzWðS¬¯æsbu§1’%Ó£Qš%7.üä&Eè…ÝDêuÚ¥Á«=7ª&$ÖYß"%Ø䱤»_j/î(ìŒU4K©«<ÞËó¹°ŽØw<5Ga7¹·s{"Ù™‡[¤½¯Bí0wæ]#Ä¡,>¡g.÷ XôµÎÑ»|ñëé¬*jŸ”b-°`1´}gncv´û6¼/âRf¼yÍ–QòIB¢^† ’ÑIu B Rv$ÃÔ ùu®…?O| ?Jêµ*ŸÙ¤›ã&š—lº'p—qÍâsΫ== (RªÉZÌŠk ×i¡ns¢dfè#åƒ(èïû0|ÛÕê7¤£k -Ï=÷ø8Q³A"Ki y±ºÜ4n@êåµzŽ©¤‹ xd ï ãwc2ñù|Š·ÃÔ¿q™å§¶&Œv{ÞUv%8]6{éTYù^^…e;ôÒ›TS‘z1Щ¨“/²©õ€9?0z\£9Ÿ \xb ‘KøÊó16nuP¿n¶ðMÅJÇà cßõØ™â^ì]ÖÂÝàžºˆA2Ë~w×TÐlT_M¹WÆ/œ“ïsÌ¡öêL¹E¼ÜoßLÊ¿OˆsAõ5“74tsa1 y¨7¼oHøØ—ÑvÌ?M2'¤ûR+ZLÁÏ{]²íb÷á¨a=èÙ›´•1.pÑ\Ún¹wu;2ÛÎÚƒ\\º}ø¢-P¦”WƒœwÍ—¡ï?1 û>ÖW‰I²Fä³_–‡¸Q"ÄjÆ£ÁÏÌ ¬ ÀnB×Gô˜œ–¡/¾Ç•Jmg:¸Ÿñf^—d{É•QG‘,–QÝP^ŽÉÒS6¸ébP~jR?Dlp킸mpQXžcM¶r -L²$ù ÀSwu½Ðö͈kÐnŽÛøÚ®›úHA€•¥ìèWF}9ig~pfÝîð9‹ÛØw¨Y>¤R é Žø~µøÕ8¶¢iã öQv‚—é€e»¤“£ë ÛHÜ}ê˜c–Rìíϼ¾`æ‡<Å7³÷ÚÛV"â+õqÊ•??·éÜ‘Êë^í÷eC&}¸poO㓬fÙBãÙòZ®“]¹¥¾æY1Ë’uám¸ËTÛýÌ0 q6·'y߬îBOÎ×:®ÿË Œìúøþ,: £È˜ïcÈVUŸGzk®\„<|à]ÍÂv0FnY|èÆkúšÛ <`¶ï”xÕìBØ!H|oajFõ•RäîP1ý×Z6?ËÓBŽ'Dp´=õÛ‘÷Oâ 2:§i~ï fæªÁñ#ºÙêcô>¾Ïbçv”$f/3ì®J›‡œW½ ¿×ÐØM<©³uH%t˜½J¡E%ÝY¥BÑé (©«,@ò¼;Ì–Õí.Sw³ÀŒ_éùu,H%[BðN-êbEbQü6|r¼ËòÇ$ôiJ|æU8Qsòc]½¦¾¿ŽG…à"-9tÔÜ =k×Ý1ÁPÃMŸB›ä‹Wêý¡Ö(AÈÜ#Ǿ-m;Ÿ]_=Ìo9ø/UÕ›öD9î¥Å;°Ãq%Y2ümf±Y¹ýØïóƒ„#5œÉÖ}¥‘ïÍÕÈ” 𛩢:à:ä‘e?wAÕmŒ–B½T’`bôF4ÜðûÜ_m÷íêB —[àW/¡à·ïƒÇ†A¼ŠÐ’æ<³\LE/g œm Îež’Ô?ö»¸œ¯^@°M6=)`D Ë?èM‡90sšÇ µÞ!dO_ÞCL`Í—]zCtøFÁývþåWœ¯‘[äéØTxi©xŠ­p;³õ…ïç0(Ùh&ªÍR#¹ôs¿­ìä“OÎ dçÏÆ¶*ƒø"|ý+³›y#Áü΂·6O0 ëÛד’õ Û)ÀZL§&ÿT´ia _ä86ŸŽ«›À^xMÙ£>6ŒÂB8ÒŠþ×ÑG%×2gÕ¼C,ûT×Ü’FZxü+TJä+Üú˜{°ÉQ,x4¹sâò°“ öBIŸV¤Hü²gN‡è†^ôNâî­stwñ¦é©öØÂŽ;qׇ_s*Ø-Þç˽ååD^øö¼ˆ{O>ƒžü«·÷v^bÎ|Í$—/D¿J;]…±G)ÔЫ,|ÀKÁ² GªºôÔ,é¡‚¤6.vQ™—uK˜u¾µ©´Yuï%|ˆ§qmz}嘡mÞ°Ë (ö“÷Kë¢kvÞIÀ8ð\à!Í•=¤âtƒV8„ôºV,x†c“GIsÎ0”Þ¨þú꣜wÔ©3úu#Ü®eAÞ‘Ám·íîØñãW|GÞ&àYzáü*Ï]‘ÞK â=uýØÁ¦#Ç’èAOó< á`17<Ýê/>Ó~°H±g¿uU–‡~³Úé¶sþïDÜ.ñúqyÌTÛC"&]ù‹ðíG=(–SX÷ÍA*óòè@V/¶.9«ÇH$Í&È8—Drñ^œó©ÖÓXäx?»Xoù”áÎY;ÞÝ00eÒ1‘{Ò£Éxô:²„¹5™7¤±eÇ\Ÿ£?Ö=uç¶$ jQ¼RûðAàx#ÞÜ¥]PçÊàk9¡w¤ø_áÁ?Àá+cÍq>ìèÂYú,©º=äרRŠÚcÌ£ ;¯}Óå—öS¤òã" ?•Ôú©­3ØDÈ"dÔý½¥m:kŒÉÀB MÕèK#-^ì]CWØ«|v={ŸqEYSæ¡ÐYL9=?µrvãÃ0åm…Ö>‹µ9û¼:?ðL`×úöÇB­é;£gšÔÜ£}–vÜòýŸ\žºÎTY³°ƒŒ¹XžÅ‚²u¬`'xºè¹¿ÖT¼2‹zÔÔ+„æ]3çi]ŠJ{öÈ9!šEü’׸õÀ”õb&úX¬pO¾Ó¢kÕ-’|ÿÙœI·†¶ÈþpÁÇYÑè„'qU£MüuÕÞ#-K»æjÍ'_ò`È`†Üo5Ì”ZY–ÂRÎ?H1Á,#Wô8¼†›º¬ •sÛsféâUöBÁ%Ýb­„5…\¼üBÍg˜ú®$(Íé`^3„QxíFK´=t£9ud¹ð›ñqƒ]ñàh÷šëš­-êp¨tuNáF‘W’6õ•$’{TÒDn;cúþuª60±¡eÔâ ~TÃG¥D\”vŒr±舎k™ò1#òC0B w4íÚ×´'.,±ÖƒÕÂ!»ä·¥³6«HnƒI6ûº˜•püºAm‹ÝOf€ÎIGT×ÔÙ:qÆÜ;úñ£½ñåô„_sBÛ+¥H›WeqsA&äsÍé!7f¹¬ÃcÔeô%¼²ÒZ4Me“dz™h×^?û—MÝÉvgl±û §ðs-aÇ#àõÍgoaµ s•`q:Áwî"sëø@´žW,æ¥Áã> cP(Gö‘ Ë•ø…õ†â«¥*Ÿ6¯~¼©¡ŒÞ^¶ÚÝaø¸Ôúµ\FK¢¾é™`h¬*l­@ƒÚònºñ×Å®2áÖýÄ8)‡\"/»Ê6c»öÃt~ÿD¥÷Dçkv)ºàΩ„ÝÏþ¬ªÐ©Mo2%ç“ào.ˆW¸8Ù7?®íýÁ {¹¿Ï2šŽ \{Ç!'œËë‘·ý"Óó¡¿m¬vªcÚÀè¹êÞ u•3£…Í©ZÀ¬@0à]Aó^$º:Ë““6#ù~œad«|OШߋ7ó]Àa6åeCœ>Ùj`1þô´Êÿ šÇ ¹™÷±¢agí¤@j <’]Ò0Q†š¤ùÑZÛ®eŠ:\ˆU×ìNŒ³¬iZÛ·ÑmñHŽ>²»ë{z}n*§­A1’bެ¼éëúæ\ЛÂôLoZ®$—o$íjã‘»N‡9>.³ß€~”%ý`(Æ(xõÒˆjz[E’t½z/‘:;KLvš1%Q„TÁíT¯ô\Ýžî ª‚ Ökb‘& e­ ==ÞöY˜LÕ\¯™ Ÿ%¦ôI%õCÙlPS‚ÍUj•´×J™ØO…É[*”kš~ÌPþ7FhGfÁÉ¥Ÿ9&£#æ ät£ÞÑDŠæûS¼œžO±ºÈæ2Ô ]úÂ%ïGrbwÕÚ]=ÀG ß}¯gÛb=CúY|n?¯õfç¶T8­;¼ñÃä?ïJלó±]x3Þ ^’×.™S›,î*Ue>T‚Ã2‰kƒ·ÄC1˜ ÜõX `»ÍørtÑ·ÃàŠañ/ö"' SVã?Y€¯¡ü¨² Ûb¼“7ö•Æ¡4eNòYïsì2±5A¶IäÜRÍØ{zãÄ[úheßc*ÄŸˆØ„ùhãzÍWn µÏm%èÐöfUªξ޾VÅNKlÖÓûéù¯€Û×@^âP3ýþu«(¤E½5)ôÛ^Í”6{JÒkùd@ a·ÔÜ<É{MåX¤< îo5´zʸFòGäP†©ô?mN2ƹ߹”ñ„ÔGû<6¶ˆ%=@Z÷`3¬+âØ:0Çèäáœw"^·ôÖ ¸yTÁÚ)OÀSm—E¥Þ,mn!tÁ›:ˆWÔ„P>K&_ÿ¿ä,ÓÄ [1LÂ'ãÎaíRw³d,ùìævNÓѸr„H‰Ô†sœ™ÿn…Ç.Ú“i™1Þ®Ñ5ž&ÚÏuAÛ!?â½,ñòÿé=±œ \"iC\àw<þ‘üJÞó{¹¸ƒ3OVÑ5ënûn±þ¡ãïoB—N ûî]¬|Q¬;5Lƶ’‰iqò…Y+(Õƒ`Pé.—jB`á ¸{»~Êo×µ)30vω{1Êïè(Hz~’×ýˑ۷!¬s fZ*÷âšqH“@†ÏFêÄú¦Ÿ´Gé0Ç“ µ!6½.@ñ=xÑC/¿Jw†{(DFôJÝ‚˜ùM´3A™VКʻ2±Ò n§“ §ø{€UÂ$~ªò‹½Éjã»–š_’ãGpX#–$®6õ­ÙR¼f%Ö4¶¶à­›äüŒ¥xñ†¿gD‚ÏÀpJaæËû¡Õ÷wNËò¡=‚r1U?’€ÜAÁ)Žtô:fƒ®’pˆ±V¯¹ @‘9U€‰׺X…x\61cf+«qJ6-Êì¯(\?î ׂ۠ìÞbÝÈà=8âßkÑ(Ó€T¶Ò/> ¹#sÇ?›IÅóÈóËÄ —É {«¤à¾r’6 ÷2™¨ßö™;ʸɔ|6ˆ(Ä%Ë Å‚Æ+©û™v4[¡âùÒ2¯VÛq­YAKõà¾'÷_êׯ”n¬ÖÏ´kÐá*cÖ ÙÂ5ZøêÞ•7‹äD*`-$Š n€íÅ ¾<¤UO®¤ä+«àÈߤZÞwúl·âž¹´Ÿì¾%ýCîÐË3|ºF‘YÅ £"B ™Öž0òBf-ÞµHU«Z‚&b¾‰É/ÅHÏ–]õ.Ü£Æ_»¦¶-TNR_XëÕ(}8s'í5½¶&MLM*¿ªQjF¬#O‚P¾­°k+mhŸ¹¨½ge ¾ý‹7̨M †dÏR »“|9v~~ru„,[‡Ï œàË{>ÄZp\Äבc š!êÆW~¦ëA‰îBÆö¸}`ÒOCÛeò{¾U¹”Û€Ž4Á/ée‹íqjÄœß'°òL,ÀÚvó mìò rµŽ¨S{ß!öžm†ï4Ýhn½G¥»›ävqëþEÅ÷\h&ƒ–Ѩs7»ÃW?hõ·wŽ™sÁý¬…‰ÿÑýÙ "KØý®Ó—½ÊëOÎ;ª}™zµ¶:Y\/§ì¦€`´u¢AWøO8,b 3Ø‘Ê?Õ”ï/)zVô(›ICÚ•W­ä Hª-sÐá¢1zzN¬eXöìñÞå[±ï#7*ªB¨$|Óâ´ìà´‘ÆÅa›\.·Í<»#‰mnE!¢k_¬wÎ5ÏW6ÕÍ} !ºk…$ödèÙð†ãi¿Š³ 䎦b?ÿ-·À§î«Ghlä>#îoÃh”îóT„:•°Ñë¥àL5‹Üþ0•i={š¯h@LÐ/†Î¸R¾uµÝ‘B§Åú]/>‚£Šþ¸Ò;<£ý‚BηQÆžÃõrò,?Dbö^šó‘1iZÌmjÄ̾ׯGDŒo4ƨíF0¥Š,p§…‡â†"Ì»<Á…>7‘À”væ¡%3ý¶~Õ¤¡i?(s—¯3Ô±äË7×ãH39òê&¿D ¸A°4Ë#‚Š®“ê&› í4¸§énÍÏ(ºéO䜯ÅÑDxF!nªέEzM“æ#4ÈBž?íáë ¤çxúÍ9ü<ýe0Ž}àc?ÑYÈUÄÌí¢öqËM5QŽ*þŸ0€ø¾}+ë#™X¶ÐˆkhEUžÁ‡O ËMµ*ã;ŒOØìLü·´¼/Ÿ+8ü…‚ªÍß—,‚¬§Š0:oÖ s†„l”ç  æáÝd~ ¬ÿÜ7ŸÂ­3$®l—ÓŠ~ÛPK(6AmÅs3P[‹ÑÇV6÷÷tT’f—`ÍD×»rYÿ=tP3é†<$ 6»3}N8Ó>Fã÷Ÿ+É-ÆÚ²ë3Ù±úf_±seŒãÕÌte¯“0šËc•ƒ»~™ì®É=^>ô rq ðŽŸ¾;§Ä4#Ò^N&¯ž[y¶‰\£Q®Lî%MÖìhÞæ*|P58ùëhGr!r=HëpG1‚Š’x…N¨ýáÄÇtƒ­FÇþ%mF¶ŸD«¾{¸&  ˆí†EkíЙ ùÏCŽ:ß.õ¨bJ–’p³ 9¿ZYÚºŽ}r36Nn‰0~(ävÉýd-ÿsF൜SÅÅÍ9¾fapé¡6 !ÂZÀoE’‚äΩ£ ØXPß~Úùµl6þ¢çz2ñÒqÔ…õäÜH§PþdQ ±ª_íiJ:ÜÁu)>=‚þlؽû‘Mƒ#é:Là¸Íì BÙn(Cp7™p9#lœÞðPˆ-ª ÒºønãÀ«J·©9¥a3%ÜñYµ¤gˆÝ‡f[ñCð4…áþgûm«^¬f4¸åâ¼ï‚‚¬°oSÕé«sʵɎa§ô"Ù;E4øï·µcŒùPwŸ‚målYNÖòví›ëÞCÅž/8~š¿7¤gíørE­ÜÑéM/î {¦ãíéØ}¶‡Vx2Ë@=JÈ1͆.àåskÝ6¢.ab?ìÀCGZրݢĔª²~ …>½#_Ûµ‚ûæÕLJ¥FŸ÷£üPTÓ OÅIö°²[Šà{î6Ÿ¦×Ú‘u6zÏ‘¡»A—#€ÇšMc¦müˆòý'³¯t¦šzS3uü(qãž+·@œU$ó@ð?ü‰5~6qòÑñכĊw‹¸¤{ÔŽg*LÙ1ªV ªŒ!SµP9Ì(é½iu›d&VÙU­å®èHæ,"B>ÏOZ<¸Ç¦/«Ö-Ô"´«™ñ€14ö¼Âë½7éaŸv-dŠÉSîÒù ne.Ýq dŒÇ£ù`ë¿þH8þãšï™R 3ß²S¢j&äe[åЉ˜Ü¼Ìp¨C–½­Œû5Ð:ÀwY¥ñþ}φÙí pBðÅN$·‚!#av £¦ºõðYê;+¥ì™ûÙ§J3g†Šÿ;~Î/.T*‡D~ÿž0b¹P¿˜ÑÙëÁ,W’à«Á²×ûvJÈg­Ç‹<ôžiÑÌL$¶3Åô'úÁë ™75ñÂ1u¹ß^êI•"W^…þú¥2ñ”Å$E€DÓÈ ´ e¿‘›¯¸eŒ#FI§*6…à¦òU10 Ìò³éz>ž˜°GwIMž =±Å‡Þw„éû<9íÖMYý”æ˜Ð¦P¤Ñ <–UæIƒö–QÕ lä|÷Eä/ð\²/²1 Þ¥Î*ï1îœyäñPÛ*+>ç,³;ûþÒ—y›:€. *ÄOÖ¼Q-çv©ÝöGDøêFð{¸¤à'ü“~;P‹F¨dØÁ ‰êÄY cïRË·\Rfv) žt •_zpÂòW…ÛkÜ·›ä-xv0êã×”TóHèí,ú“ãÜ —PcËÂ’˜ X¶í›‹Õ8F&ŸvÏ’ {ì.6\‘d/nœ‹vÊs¿4ÝýAÚõ"ì†ù$Û§+Ù’¬SR&µ¤ÅySþ÷‘ƒ±Ú’ϵ|2õi”¼×N¿øT5rf*gÒõ¦øoû¥Æ&z* ¸Ì{Ia „zÒl×tWMV†cL®øòV€Ÿû1 üòg­"q ”„~ÆP2ŽØló¡,Nº-%ê’ïÙL‡£ÏsB(?°Ñuˆ¿gÂËrCU‰X½lGÍ)¾Åª3¨våú»¢Ä¦<Æ,y%õÔ-w5«• µ˜ŠçŒ²iªñ}Êöžé“©4 G©ß¥Ïö ûA­}§ï!áutûR%=X™UYmv¹‹±é@{Ñ8ƒŠU¯E½é@Üwƒ}6¶µž”2bòæï²#²\ð¢'õ|1§ÞëèÐjU[d-hl°ðÝ<¤¼-7t'e>´õrRùUŽcom&ù'Ëè-@»\*žö• ,:TYõ-õ#~â _†~/G n4ŒÁt ‘yz½ a—»ž³—½ã%§†|(îzvÂØ-p‘8xM5!i¥À%_0Ø,:5Akç@¥A g¯å/ÄiÌ Œ@±âoò uï dûT‚ç …Õz¶­)ÑGg{{T£°O&X½}=XSèm‹s¿>¿fyx>V>_Ô*ú) `#`e˜ý‹S›Ü ¾ J–y{å43®ZØ;Z ¿!6ØE?žJÑW BŽ>Žö\z¼g `ƒ­þ-Væ b[R›ÄÞÙHòÚ;I4çÕÏöÙ^—Ý(r0z^e7‡wUú3Ùh: æÛg^ÑîôŠ=£YSߟè>£Jíjgfk‹:¹:WGí¥x‰âE¤%ˆ4(PòäÆ1®r®†ÇÎøŒ·Çƒ²FhASZ:\)GbX ù]håø]êÔ‰~c<Øy:šM\k¡dwÍerk¬µ V­¡²lÌ0BaÚÐûnn}ÐV ¯ˆÏã9…–³Eö1ãÄ‹=´ÜWN"ÆSNˆ»R¼zùòQ1¾T)$eÒ X}©F5Q. è÷ð÷n —–Ô2>á}äui…¢š‡xÈF%0výQß鵇.² ^<ÀfwƬu f,–‰5Áì±Úݬ’#-ÎA¼Ù6‘”.“\ƒŽ,Ó£—¾+þ”Â&cO=Èöâˆ$´ªåóÖt­«è˜q´0£™ IN†®â”"=ðüÞýÀ}´OÿÈgIÙ‡—±úùf娟 ò €\› ŒëDtB¬H‘Zºm6êèL}ca"Ï´º>Ѫ•Â$—j^ˆˆ¿â„fÚñÎ)¦D9Ç•váá<¶jä0óý›ÀŠØ«d#ù&÷ÕfVë£ßV¬Á*ƒg\Y॒vù¢ÉH(î|Ç׬jo¦ŸGñˆõÃ]¿Â X¿Ü¡5¢àkÊ110‘Åž[ù甥§\ÿ÷¬ª#É@U_l‹!AêU­¸Û ­ Ä9y}’ᆸÉlík*Íû"I]8¼ÚºVC°5n»õ+c+µ8ž&n°5Ì9È(àBüš,Á]¬/—gñ›$/c½£¹X/§K7(îLCZqªÀ6Ô ZOnù›ÑYÙ¾Õ_G]?g°•lt:þm¤¡‡<ËM^’Ö=Œô»AÏ5­ÍXQâܪ¡Rjt{ûÝ’¡G e#Lcö´zˆªï2ó „{nâü§‚Zô†\ºñ« FE®!²Í¾AAù-µuÁ»>4ãÄ¡8±õRˆHµ~0ÜÀ"²nêíY±ˆÜð(8«WäëxÁ©\þõÖ2S‚†oΖŽfÂÑT¤.BŸ¨—R2-ß´‘'ã¾!â«32û—{ssÏϺÂ1ˆ?–—µ¾îr}xëP°¨¸Pÿ5 ͤs8¯Š„{¬±Ÿü­²i7ÐP÷ÇØä3E"¡÷;q´}ô9UŒµÎÎÕÿ¯”ÈSà‹Óq ¢¦¶¾½ŠdßmèÆŠ§wÚ6V U¸®µ‡y÷í{ŠGÑÑÇË- uÝ+RÊ+D‚BÖ6’ÀÈþ§,}/:­A[–RËqÁ#zi‚d´ã«˜ûº›dà¢Í`Ùwgh,y_¥¼ÑO+Å·E£››ùCcî–bÇGf«áU=/¯&ï@\MäÝŸƒ7 -¤üa“ –³”^ P™I½×\§ Ò/òh)YnYT•(ò‘ª«vM ¤ª°òƯä> I”ßÈkŠóYV=¾!p, -/eNÒµôvà*ýÑí& Ï!¤\•÷æB1ꎶfzÆ·ûsCêUÍ3¹ú®|¸ƒªx›c¨ªÖ‡µ™t†³Îxä¦Õ©úM Y&™âS/cY7õÿ¦Û|elýä.Q4»ù]ç”Y“Òꆹ[Uš^-d €aÖRQq35Á\›ƒ?AÚ@ÑvS¸0IXáôÚ0bºà‰‚’§*_À‹ºŽè²Å×4ïÀ¹LJX` QûM‰úyph«ˆ1œÖD(å`õ)µ "¬6)ø&H ºXdätÁØéÄç’Õö£’`'Äwa~&ix|®Oå]«ý³‹ÕEs6_È‚{»fÅÈ̶±4õÙíÿÓ¼¡Å›“v5ƒŽMEàT†Pr3º35†dnê×yg‘ÆÐwà߀®»ùÚѸ)– ÀANÚm\YÝ\Ö¾Ûíš±Zd?~¨îØÎÉ`,Œe¾LǺX½Ž™ÁÝÜž÷‡ìµøyZˆ­o¼.p•håVËMˆ›—‡ .šjdEEJ AÞºç¿zñ}qEä’“–æÞúÙÕ5µŠš¤Ÿæ ïlñР oµçîéša¦ÂûzU6À…L˜wéähûTQ$«ÝsÈ÷1—H,-ÌŒ˜œÉ",‘5ݨÁ±ž÷/ÍeÆÜØe}­rªXý]9±‘"ÂŽæ­…úesª——Y4ÍwŒ(ctv8o¨jÏhØm# o^·i€îÝk™*vG+aÇ„¾‰hPbjBšïÍ74‚µ1°K!ÉóÖˆ.>€àv,XìÄâCÏzI|HË¡èxÌ´G;ã^tx>)\+þ!£Ä"˜3ˆ–ô•­ds"U¸þåìdýJcêÝØ"Ä€l™cìA›Îƒ6”+'à³,$šEfOr[„e½Æ&6‚1X§®S Ò æu¯ /ÖQÁu§èKVJf¬ú’1WûE^%ää<À+Càøc®•_òÄ%຋XlFbólð’”p{q'6¯wÊÑUÝãpM ݶT(…Lšóˆz?qäšpÞ¥Œ_ñ{ö¸Gá`ºá­Ê·%eÓ‚ ]ÀŠqei ›®pIpúñ¼¤œqkyYO¡F12éaÑër¦|]´*5½³GPj½ùŸ†€þ˜~Ï_m Z8gf˜é‹¾ ùÈ8ÕƒIªÕ %Nm)ŒR—TlhnÁ–V{Æò»­&±Šï“Fâ›ýLb.æäp"øÃqÖÓ'6F1èèßQ”è xjUQgÕÝ™ýY˜T¶’Ÿ™‚ŠåfUt€Ö6£ D6 7¾îÜÂÔßÏôS¼©57_:|mlÖŽÿNMLÀ ¡z!4²~vÁÐrÍ´ªš§€ÛA¨WÀP8ñ~†ˆ &LjzöyÁþÖQpÝüy Š·;6‡»öV ¹h–F7W 5×¾3eêÊÍÓnB›½‡æá¸Áú+ßÄ-Q gC]µOO™òZW½;U`‡× BQŒCÜá”öÆ-†$áü¥Kµwô´Ò2¨ºj eÿ=F&‡®;ƒŒ;E'êI)䯿þcŽDrªçºÊÙ W«‘+mœ!μ%”dL¶ùËÓÖz†ƒS`x*úÅcâ_XŸŠ™{E 8ÒñRÚ9òé|”ý¡È æ„åg&õ/JI "€ˆ“ºß€3&™)]H–žÊ5¾`œ2Ü<œ&nk bFÆÈý2…woŠ8¼$µ&ìÜ Ú\̇<,ö£ÃŠ>%\À»ô1Ðho•´» ¢`8÷þo‰vv«ª¶ÎÉë¹Á=š4¤<]B* ‡Ì9¤Ù¸Uª ƲX*^Ô¸R™µh+СSÅ•)̰¸´b¸×Ã7ƒ=Õ;u°_5zvýÜ=UæÖä‚ë‡5 &‘`©]ä *›©ïkkC*ó :¨Š>·ø´ARDoîOÞÄ@ˆ wÞ bXbÀ9U|”ŽnnJ>Þ©wœ}¬°Ž‡Ù„:Bo×3Ý!À?Õ'll×ó±m#%}ìð—Fxê^Ó·c0ÔL5%)Õº£žcû0X:ô+÷·|GéAÆbEÛAKÐ9[HÈŠ2An#§9¢p:9›¬Ë 8ÿd Œ³g3ï­'•ÖgÓä•yK.₯ÄüˆHwУXzö—t@Z­jYœ(=fŠçÏþY[•\íèˆhãÛU®Î룲ž(àA„|å¯ý‹&=°`«-Û³ÔŸLâb”¿’Li¶Ê,þμç |õá4–QôÇ^æÅñÛŒs²‰ZdžHŠÅTBŸrøvøoÀÂvÌQÙ¶üõ”;õ¾ïñù¿™0¶µý•é$Ñ6¯H/.HªVCZKüWLÛ¦»/±ûÑÕ$Ñ5åPàé@NvÉVQíeƒ†–þAi‹ʆd Hò»MÏðá¿F'ÞåŽå?æªkn3£ª$ZÆ¥­>ûàCÎðœöšÄ% à…¼³ÖeWŽÛÁÏ 1qÊw‹|äPNÍiŸB¶ÞéÑ0»r28ã†v¯Íé­VƒÜo…æ¯híi–2ư_ªoãÒ\(ôES è{‹üO¹N°ý…¡•^ùƒ`o]Xûkûr&/\„‡&´# O‡„QÎþ¯¤“ Ânß–9ä%ep—[%ÆÁðlý²ý1óÊ‹š¡ ¹¯6‘DæIZ&¡‡ $¢¬/HÛæÅ‰]k8(8x’Žiд·Ùò‰_b¾<®Ê·óûKB„ÎÛ,3°ÏcÒg²ÔffÌúåŒà. %«ÜŸ‚¶¾ èˆbéDi¬õ­m6aÚ ™ÏÇþP5—D‰¤¢'ö'E—!àçÕ¾ÁÀã\MH/‘’˜×èì=G¡· ‹ä 6†„¡8—¢,vN k˜D˜ Ÿ ´y€‡ò±e£PÁù¶†/Ɉ\ꉦžæx™¿¦·Çz|Zjøb8ñ‘/Î#Ù¹)çèÌ ÅfñgH¶; mSµ‡IBÃ1Ì­´ý+ÿ)Æh¸‰VµÂ¤X*蜘ñ¦ç$EWAŠ(ºi jàhÄ‹Äè‹G4¤%{ï‰iòÆN ç h´Ÿ«VdR¥ %fEYl £H¸éŽÙί^¿¡5däo=wëeõÏm´. Àì·»ÀDذÆb ±œäG,$ˆTÙðñÃ)¬ ÿ\snÕ÷p<©ƒVÂ<êpÿ9™øÇèéƒÒ9¢î¥Ä½Jjž£iŽ?qhBHœÔ&¯œÙÃSrহ j„Œî(=Þ1q ¤KÙXz¾£Û™Qî”Ü_Z±¦’U,!W›£jÆìÜ_Kù6ìn0S£ñ­ú¹º’Lóì µ?d¬l–w¹÷×&$߀©]¡7.äVÌi-÷·§á’cÖúušln¸W’Å’ 3 /ÌpïÎìvAAkÆüÌzµAè[5Ë šw_[U²÷µY,ÔÁz¤@hæ™yºW AF?ïXb¥O]²Y5½¹þ¹×ý g}Äó˜è"(ι,à¸/žþ¡yæ¬.¬+¿zxhÛù_°§ ª È“vÑÆáˉÿ ózcÛ`½](ÖÞŸ¯øÆÈÕ´-8uuDš—¬z_~Ùç÷T3û‡“*,Ì ID¡¬WÈ›ßû‰J§7›ÏåO±Ž;SzËÅk¯ké—¶÷¾ðÅ-jZœ’ ±d{q¸áèXÙ·ž¥ã65…(óÕ¸ÁÊÓŽÕ2aÄøìÑ5®.GÂ÷wÆÇÐñõ[#$Ðý¸Ø˜¥ÝµÓ’³ ྤSÁâ4Џ{˜}m•j †ÒãBTð½@ ,X“Ë0 –ezŽq™w:Ru ï®DŽ ÅdÝzOÓ@¬<ïðOÉO ™l@ÄÈA8o»ÌPÈL§¨F/€x}öœJu…؃öì;ïA¦²pÃx§¸Ë¯‹G²3-b;Ñ$SW²Æ´¢£ùMø3*ÔáNê¸w\æ5>BèG˜2&‘÷©ú­š^¸}=¹ÌëÑGµj¬\š‹º3ñ¡­½RvÏX<•™}KÃ#[ÞI;dq›JˆYî–“nÇТ2BÒ•+)}¾<,@.àÂC{0ˆXV»¢>þ¢~Y 6Éœ… Òfº¢Iy¸†+ I (¹6ް1™ ’÷N1î8ŸÊaY²§x€ñí~M«åûžÐ¶fE¢›sxÖŸ~3Ã;>þnƒÌÓ1g¯3=ε¯×˜ ‰Ú»œþË-'º=¸bkTVrfê/Ö÷êæ¿Ëlùã’Œë—[Žk£k¿+ú§¼ä®²{윟¶ÖD>ÿÿÈ¿‡zNÍ\…Ü?iIªÞë¦lEd)èfKŽ”£0 –þ„‰!¬ÝK2e˜ýé¾jÌ]ó1ßêÕÈ!$¾®eŠWdëRßÕD±Úü]>‚³W6’w±ÑÓeÊ?´m^*÷ùÚäß5W}ˆÙ½X_ˆ=ïä+˜ƒ?‚´ÔöBá} *iŸÈHž{CÏ¿.$)øê¨ šfd¥æ1Ç­öŠ$è~Žÿœ,óÊý>žÑ“‚föÙxlü+a|þMÏßpÉñ@1±IC®Í5Á!=›uÒ#s€ #Ý×èŽCe~æÒò ¶âs®Qp'Õ7ˆ˜Ó9˪f¼u]ÉÐè 2¡õëÆ"èc…Ä:9Ë•ߣd¼f‰Ö¢{mü \²3¯)ÈMlUk¬õÂ|Ú–³ÐÊú™AŒˆOp‘ÛéÓà„à/H„DKåÖ’ýP%‰XT.ç¬BZ܉æ2£l‘ÚN…¯õk–0PCœÀÖòmŸ¢ i“(‘›(0•¨<óR5.Y®²Çîv9…ºQ¿<í(–½Œ±Ì$˜§™*«Š¾î€„éImò~Ì ý„ Ì‡Æ ‚¥kµÕÔìQ6€ÆÁO.Ö(wìᯗKöá%®ñ„@¬Žiw$£¡pÊ£̨Œ,ÕÖ9²s–? ƒA:¿©QSâ¦Ò<ñT¿;šÌKÓñjË¥%gôͲbP‚ƒGÒÃ¨ä·æÓ*VOëtà7W]ºë·´å·hêK*˜M¦Žþ„Ÿ‚œ›!sâiÓÝ•ñÜÃ[`¾H‚ýŠ7Ñi¡{ÐêV‹‹t±3VÈæ©L|W?ï,NS¸î<Ò_%Wý‰O¥ru'V…Šð–ÄË?[¸0¸ºƒ¿oK:®#âÛ·§J‡úîfSy‰AyÎŒÌo KnútóKY/æ†é+…q¹ŒÞkï]gºÕ€E+’Á0ÀKGă$ \Ö> éVv=z!À§èv<¼FÃÆÑ£ÚϲÕz YlCq$çàŸ_Óœo,´æuYÐ’ˆÃƒÌIŸžŽ’¤†ÁѦûºšD˳ôáXrÅz:zVÔ„Ôyg~iÚŠÌrÊG¸þ(â‰ù Ä­â/tÁ«!’QöªK™c³Ý 4á—{*²2s „{l²–u$’ ¤Þ?0/Ûôz{wÌaËT¸p·ÉÀàrr6jöâ´ñÉ òª™ŒâÀw Xë-X‹S¢53SÌïw›b=v%fx£< 1ìÒdO xO´Z|?JýU[,À\4+ñ+÷¿9)NTpÏåNcdçV}wHÄ–Þõ™t]¬ÏjJ|Òx“k©¹Ï«”‰½®ýi‡z žn?­T< ´Ÿ(jxµŠïm ÔµÆ&~1‰²ÌRcÆŒ.KTïSŽ˜! ³ÒÎê ±,¹Æð]²-Á›Nƒ‘ã1¨ŠŒ‚öYT£âÝgŠÐÎG£ö×Þðq@â…6Ô÷n“ž¡­”1}íx-IPÇ®¦7w*zÛ-H#óÅ.,“°Ìz;•±*ä]9s,’ƒÏFûýÓ´ïMŽwE·‹lbÙù›­-rÓ|ЪIP™UbØ¥áˆêzH.´ ïV5¨{ Y‹{·ì–Ÿ:q¿!f¡Dëfæ§0]"£Ö¹ˆJºœ~Í7bÝ6ž±ì¹uÚB±…äR®3%q!#²r·‰EnC Òg›YÁÞzM&wv¥©ø\ÿg&µÃ Ö4@ÎŽÁð™¦ùÇ4–¿"wÐýâ¡þ°§ß ¦öb³z[D±„r’×ÔÇê*®îÒËäCŒØÁ÷ø= ‡çUå‡Þ$CøïÒûè‰ÄoIX¤Õô!Ó’ôjØ¿”æ¢&Ô0!况úêÁ€H¤\Økd¦a)ó£ä씋€T§„ÞG{m»x—Ä[däÆÅNaË/„·z«êaGºx:i«1|»J×_€J•[J¼úyȾ·» ¨ôV/2¶4q~“Ws áß’ÜÛÉÝ„óQ®½Ò®¯Pár3ó؃—s†é vAÀ§‡ÆK]Í7ÉŸümC“®†û—;±þ¨þUŠì/bt¢p{Öeƒ™ˆî6®ÂAF?’¹q¢j6ì÷ qñ¹ºÈrQF¸3ä[1ý¨dQôç¨@ÞÉvÙ°Vš¡)­Œ¡ø¶Q¤‚¾¦£SîrÑŠ}“çm| ÜÐ&¸¦rO`ÐgA}gö8Žó-’ò9.ûV<8Añósø¹Ñ ZCuò.nŸ²É‰äol¦yHf£²”] V§N)mµ÷l;B®ŸxŠ"BéIn—<¨¡+»ñDIX°¸»¨%C`!Q$Ÿÿéžœ2¥²}¬Cp//õòsVY÷§ñ±l¬¤ì#1S/>©Â¨ÚP}é~G¸7™å=RÑçֶ̈ÙmkOÔ¿n¸×pÌÃòýÍÂaõ&‹‡GÆÒÿÒUH²â«^\ÆÆ ¹Ò¬ÐMÏ endstream endobj 235 0 obj << /Length1 3287 /Length2 30501 /Length3 0 /Length 32273 /Filter /FlateDecode >> stream xÚÌ·uTì7JJw÷ÐÝ‚tw H 3tw—H7HKKH7Ò tHHHƒÜñ}Ï9úž{îºßŸßbÍb~{?{ïߎ'†žZC›]ÒÒé5PÎÉÂÎÍÁ%ÐÈ{¹u€®@0»ÐÚÍÞÜÀÃÁÅŇJO/í 4‡€œeÌ!@€ Ä nÚCWpq £ÒäŽ@W¨ÒðÚ   „˜ëx9¹Læ '0„ýµ9ª:ZƒÌPi'g/Wµ ä—ö_ŽVN®¿˜~Q=!@G04*ø—S)€’¹…“Ø0w´(q¨rÔœ< B€ÉÉðhcnop²úË…®¶¬–6@^K]WC›™ BÍ¡¹6æ®æ +à„Æ1·´ü›·‚¹#@Çý˜;Úp@)j»9;;¹þ++im]y6€Œ¤šŽ,¨Ç×ÕÖa¨é@…i~‘‚~(:Z‚Ì™«ÊêHê¼ÔåæüU 7Àô‹é¥ÃMð;¨©•«“Ã_L6ˆ³'§‡‡‡µÂáäjÍálÏü+€Ž šƒ“«úßhü«ÄnŽ–ÐÆ@ ‰üåàW* h-%þ¥T•TS”“ÕÖa‡V‹ýWÁÙÿn>ÄòW.Z²’2ª²ÿKý‹ Èþ«_¿|YB› ²s@ƒý-p€vÊòŸ¬¡ü"lÿ7„:úßéqZAYƒ9ÿµÌù+v9u5vEiY5mÙ¿X:¹þvq³þeûdøÒÙ˜ƒÿ¢¬¢¡¡p09B§ÎÜÑÊbqhþ’A?@Kš¿‹H»¹ºþJMõß*×ÿd÷ïvH9AÓ1¶÷ñ3÷øïÁ5wt{ÿÑï¶Ò:ð 0ü·Gà¿*mA{ rüÿïÝ/ƒ_.%eT {•Ÿ ÀýpAw±¬£¥´“ƒ”8õ×TÈ€ ‚8¹zqþïÝoçèäáèóÿ¡´9Zþª5ÀÒÍ™S×äâT”ù— T„ú[f „¸@膶°áüø¯íðKÌýK ­‰Ÿ³“3ÀÊÜ ôY¡ÿP}ÀæîÐAuuúùü©ø'BåX‚, ÐÍ=WPÿò®èhåþ[ eòoÕ¿Æé¯3z Y:9Ú{AG× •SÍ ¦ÿÛ¤ÿb-çfo¯uÀô?;ôß‹Í@ö^ÿïåÿµLø+¦ÿí–y-5@ ›¿»õ·\bÝp’ŽÖö@h§ÿéþ:„ì¡;zöƒ~]vn®ÿÖA‡ÞÂÎøÿV¡Eü/ÚІþ" à40P“ÑÔdýßÓø×ZYG 'K£5tàæ®®æ^¨\ÐãáçøpC·Ž%Ðó¯pr8:A &g7ˆß¯£þš~§ä/ÑßHÀ)õ 8¥#!§Ìo$ à”ýäpÊýFÜNù߈À©ðñ8#>§Òoå¢üA¹¨üFP.ª¿”‹Úoå¢þ$å¢ñA£kýFÐèÚ¿4ºÎo®ûA£ëýFÐèú¿4ÞËÿ ah<ÃߺÒü7‚ò|ýAëò:òv@ˆ=Ð ò[Îûùßñß n>h¤×Ðþ±*²øâ‡°p²‡NÚ¿%||¿$¿IüANË? ”ð·h¢ÀDå…ÒNŒ½¹Ã6Ð2Zý†xA÷ßN¹y¡!­ì/øeîäæú‡C¨‰õÊÚæwÐVØx9ÛÿX•þ€PÚ¶@hÙíþ€Ð²Øÿ¡tÿH†Jî·g~¨©#t_þ¡‡Èé7¨±Ó?ÔÐdœ«¡ÎœÍ¡ã?ZÊÇý/é?Êeí t9ýÑnh%\þh9”Ž‹›ôÞ{mÿ—Ü|B¿5ÿ='ÿRý—œZÖ?ŠÎ ­!øwâÐÄÀ@Ð?ç‡ÿ× û¥ç‡:ƒ<'e¶7ÛüáÿwX~hòWàC-ÄÃ騷ß3 ù×láäúg¥¡»ÿ¡„=þB¨SÏ? 4ª×Ú%ïßœ¡ž¼®3øça«ñë9ó×åÌõûôý×Ûõ/¬ qu²êƒ,¡¿þX¢jÝ­žF\Л•*‡þýûÛ« ÿý(øÃZJÊÉÓ‡ŸGÀÎ#ÄýkÃüšq~¿ØZüýäúëV‡^ÿÆ¿; Ðhº4ïd!j›Ö^î/[4UH/ÌqôžPÜ@) a)sªŒX&‹(ñ.¨%0‹á“Š‚È+ÿ” ÇúPûŸkßVMþ°Ô|±mî¯êO†)+9š§Ç¡œ¥ºXÑIÃ| ”Wø²”ïsVkR+%@wô›´p{×mÏÄÎy*qEëJ¢Gñ,w3¾«=®ç"6iÙâT,äé?!Ö¼Wr‰eƬ0œpTé™sOÞ×ÜÖ}ñÑ­|Cœ„z•Ëͧ[7δYŒ+­”—ï[ñ]08u‹ò65|Uâ%ñ>›íßsã×1†—úŸOŒ¢fæ¯nuŒj¿Œ½xr~ÑÖ“§[°ZuaX²*/&TÖuÚ ŽÛê"óý²Ç÷}ô˜Ô†×‚ê}=¦‡MÎ6j×k#»÷xÒƒõ5“y¤Ÿ¬Ïrcª|²° ™›…,w»Å£¥½_M-­Ü¡Ä™»Ó„dÌàuï.wÉ ~iI—p Qô°h$¡¶N £5;¼ó»e¿{yx©|>u™;“ˆ¶?^š]`ë¶™jJÜÈ»!ï¦4£¾¾6Ú L¨ö_‰å!Ø!ŠX0Pækè²*É)"÷o_u:ß³Ú}†‰uÌ.†¡ ƒµv­Z•êœfgÖ/.\£i©ÑhSvJ9ü  •~u;×#4WÆØ,zv”8íC#š“oS4!8%û&áûÐ!»Ãš_ÉOi¿N–Œ\ME#Žx{ç–"H9¬0Nkç1˜öNËŸÇSTBÜÚ…[¦:ÑS‰L5¸¥0’o`û»kÒfi{;œU*-Ë¢*jÒ›\Åïí¯K¢ÄÔq¾)——¬UÛy¿½  a¼c"æ¦T½³ RÅÞ¤Ó®f*ø§„"…ê¾Ö³Ÿ5®ÿh×99ÐQ×L«ðør–½÷ãÇ£»€%>Ö!4‹áí4Ûyݤmµ®Æе qþª<-“Í|OÜWdÀO”çNßѸ™²jƒ6>{bȈ-ï ~ÞҺĺF~t:Pºóä+Á y¾Ëéä¡©–%AIŽEüä­a_’øÈ]fú¿¾ !ËcNÉD>*ô1úB(Å2ü¾ ¦à·=æ[“1é§¾xÀ.U¶~x[ñ¨¶Æ:8ÌŽçÑ7`G¡Ÿì¶rx£ˆ¤¢ÊšGÅ—7ü†m…t~ š—?Ì ­–XÞ: ä~“°×ZŠQçù„F1îq‘ÃÙ`ËÒøƒ¬†bïЃ{´2r€¿ƒ†ß—|~ÁÔJDÌ#.ß™tãWö·â§Æ -q;b5ÜäË-Ù­·u÷F¡ë¹õì@æBïå-îÙ¥yµ30†ÃáJWqôíö¨lo¼3"g¸˜Ò0>·È€‹1úàŠ¼šJÌ™‰ y ‡ÚÞ+d>$‹àU®Mž}†l‚(ƒóÞ¨¨ ˜iÉ£ÜÚzÑÒŸ½jc^!w‘W¡V£?‡r½ð x³åmûÝ*—\´ ÒcƒžÚ€V]F¨ë¶½õ>[«ì›ïn?‘:,¡ë…ò¶Äo,‰­·³Š&IoÛ ÍÑ„žÓÅÕjv}vÁßÔTœXŠ=@’®¹0¬JÿLqêæI>ˆy·Ÿ;¹4ÅÙ±¬ ž‹ë¸ÌoB÷—Sj é5ß õ˜…Ìá¸51ÔäË-eX`lUx1Aë• n–?'žvª2“‚hÞkÒ/{¯’lv›)¦Š \÷¥ ›K…¡F*<7ŸA6nƒƒa“²ùB6.0Y ‡†3=6LlOà2÷LRècoT(Xô=šõ§H­øeãm!ØP¦o²è…Xx£“r-ù¢ÊóÔh1RÙôOÈÆFÕ`<ÂדOk‚¢bŸçÉ­Å"`ŽKíXkfcž¦@’Nš1½Ú¹¬8µ\ÊeXŒ È¥×ÜUTc¦;¯CHr ‚;¼­StŸ]WJ~`癊jíS¿›|¯Î±°Ž1v¿l}ùÓ[’) ‘Î×ÐH‘óÊÏ­ÉöL¼O¾¨×àŠ ‘ sJ‡W §òî< ¾òÉç„HY?ý3¯@°*9–=Îæ#£4Þ£ÐhÖËhîV•@Œ~‰ÆÿdZ6x9Ë-oÁ6‡¡À¦›Ø…Û¥GYú·Ì…G$Øa²y[máBqó.¸¾yŽDêâœo¾§‹¡?¥K¹’˜}ÈÌÆ†Ûé“ÈlúÞ)ûób*´šLÔW×ü¥¬B•oØ¥Ú‰„wÓøÍÈ9s„QQ!Fï1òü.ùqù {,pÅo¦à§ •Ò ‰žþus)#Z£œ–ÇI VM~™žHT;ÎZÅ(gMP·£Yì’ífãÜ©>%øMŒ)‡gíRÇÒ`ÐOб^o!S“OBü¸Ú{Y„m\‰š~_+®à,Œo«Vù_Ýl2¡æ–´û”§@:½$ 4 ùWµ¶aŸc%cšíËäŠe‡Ù/Hj\OõÌRhÍûŒ×íÒvò°34‘§66韆n¯’•ŸÇ?ð©}Á·«Žì4\L—Õ…uí~Õ&n[i„ðb¹-2a/ÀÔËÉ;¢š¨KcÌÅã³mC¾;ë«Ø:¹ ?.åd–ÍXŽPÖç>±ã@ë$®ÉÀ•ýMª }ù…˜{GÑ×MÌ–ž;Öõà&…ÃÕ>Sp.»‡æ+†ÂGÊob9¯¤@[¸ PžR|ÐÖ/1%Ñì.røµLÊx€‡ç+˘˜ |Tïg •)â°^ÎBV]øs‹Í¬6¹®›C¾ö–MÊŽßYö±ùÉBü)ýœ^äò²¼kQû6oL#SF ›ÕÔ±d7|’~Ãׅа1^üHÛ¢¨ø°xž–@x4qM÷ô~/éÅ!ï,¶Cªˆñx2ãÍ â‘îÂ÷“ð÷“Ï~"W7{؂隇 õÐ¦È t„¥§ó_ÙCà5ù[+ä 1¾1o· !ÚtqÈTœS$>Þ² Ÿk¸Mø¹ Ø1Uf÷­°U¦ýpCU•ÂÇàS­ý°´0i.ûÚݶ´Úæ&déÆ(hnñY™Ÿ±òƒÖ5z4ˆú¼þ^ÈZÃ×>Z¼ók;ZixA eJvÿU©P6mè·ë™ìÈ—.U­4Ë$Ü|:4ïGߟ¿‰T¥QwJÜ´6êå=¯Ý;k¬ÿFy—ðͦ€6Ë•]¼$VœEç¡‘[»ãJ¼f³qÂe¯œÙ3ÆvDWmœ/‹]ôÌ]êFƒ«·Þ÷¹°2ÞI]Õ|ÜÎíó’ Æj³Øj†QLL Ô}”7Z)Â}G);ì³/„Ýê‘ò_uUÇNžDÉÎqËÓ(~zœxÅvQ$õ©oãÈSšÄêC_ÊÓÅrªÌÆœ¬šôù„¼³ik;u«©v’kD|Ã.:^\Ofi¸h.5ÌoѲ‡ƒë®-sf× Mt?‰N ׂyR¨6œôžÇ„g!ͬÔÛ>‹nmÐ5°òî-Á‰ŠÆÞ[LÚGß¾–ÕÕtðŽ] ôÛ@ï6µ/Xô&ÑÆˆu^‡yšéZ—’B”oú”ËB¶d™I®Ï„rN~ ÷Ú?Yñ æéÞ÷mÀŒ]ý&œþsêG4øÔ¬wöÄ­[)ˆþ»¹Ï9Y#ʇ׶ŒÛâé\uïÛ öø9oÊÛÝrfô ‡'w jzT‡FÇï§Ð-ûdV¬KäH\„<Žs$ÜêÒl°G–PÞÚ\ÎQ7’!ú) ªA>o½iGï¼!ZÙl•-ç„ Ñqõ)n ž}1´\ÛŸýX‡4s™ûêÛÊÑ–sj ½á;ªþŽõ³¾U$Èêû*±¯q<¢å=Ï&°‘ö2ýûÓ¿´"QÅðÁã&çÙ`Võ`+]yÑT±åö†3™\®­ "®oŠ7o׸ÁîÐ 1à Mâ}œ3íK•’J?ÖñFÝÖ+QP—÷„"yp¼õJzÝ !@•–ÊÓ·zJ~R©-án,ߤkÍ7ß|[ºGAÞ>òöX ¯«]QÇ2ý~|¥?A¿# f²NW¾A¸FÐ1i‡wãÄ´¬9õ^Ã8ÏE©H[/´3Õw¥¨-W&[Oˆ£´n">±Ó«^vàzi¥˜Ód«]r‡`ôHV.¶«©“x뺪ê¨v ¯(N%Æ¥^!ÙNH¯¸êó­ýr ˜š¸x[1S„Þ[Ì‹–×»µIrä•-¾ˆµ×¼’¦Ø¸ùÙÔ‡Bz?rÒ}/Á ª;‘ð!êË€§›gDøXÿkˆ±×H Ž+/ÃõÁÆÄßpz<ƒ…´ÖR¥“°”ë `ûÄ6F‡ÂŒ¤²/%)™ñbƒ(YþKù¹¥«B¿ìÏsiNlN[DO®rŸv ÛŠ¦: ?–¤uJ™´—?¾+‰9d€Æ^D ãÔO¼ž9xa›Q¨x!=Co—œ¥pêÉ ß!²!E‹ÿÍ>u„sÏV‘ 퇹üæbPp' •oìðØ3¨n»^+ᄨ¨¿Þ‰ËÝi‘ ÆL .=µCÏŽkC¿b.ô®Ytßœ;ÄYk@».£ê¥t§y…G+9ò Ž}:+K ]}Iä=ò­™ÊL$ñÆþÓû—½ï\¹©î¿VÅ)ž~e—î”+é¸CJ‰|<Ÿ¬ÃpY$ìÜ7*l{q)tiŒ3‡É NzÑ%»E†vã Ö86Ó›?¬¥V˜;¿¬‰@ÓGÖ›óé._ï]×ÏŒ¥4ì =i±ÿ¤KͨÏâ 3\²ïe˜°(µç|6îï0Áß7>znAÂÚa7Æî»:'6Q³!ͪ±åqíýaº\âÄàŽn3èÜ߯­EGŸb1ÀßfšÑ¸q*bxN¦¾%°ºúŠÇ+ÔÎtð6‘EEʨÜý[+ŽÇKæ:¶Ûo pØ­Ú{wt—šHû×ïJ#ÜÀ”ƒˆ½ŸL½æW!X…ß6zqòùKx›:øÂ½= 8? âÙ[|ûR•±¥^´Œœ@„-2Û;ëŸÂ¦÷¥W–çú£öwš:]•r™‹úK8†ÁµÔ\VÔ<6_ÓD-ÆeÊz£‘>ø÷)R4ÎÓ[_·]¤YŸ(Ë®K+ÃZ¡?IDU$F Pä/TƤe-QtIßk)šÖ;>丼Ø)núÔ­f3m:Åë=$!FÙê sI%DGx0ÆÐcßs¬<ÓðøèDôÆ3G ñQ_É’Dí%Ý„;îȶ œ{V/7,«§n•þÔïkíÚzšÌl ¾hÏWÄiöúb:.aP/ͬTà¸æ«É2‘ž›ùu=Þuî{+((é>·pi½§ýÑ`)ÅËiòuç§ Œq*6½èG"œ òk~툟\s óe¨†•8JˆƒÛH@ô²!ܶìÞh€(Êÿýô½eÏ ³0‹4ò Ú“›’ õúnýžY‡ÑÏczç€ÓsÊïû• ŸÛ ÇŠÆ-º$ù¬Ú ®‹šÛIT{=¬[þëtHÄѵÊy_!¥¬Cû-n·VÑ>O@KS$Ñ7>“é­±s[ ™?˲FÉ](5½ÚÅ ŽLŠï†‘i±°4«ŽXúçH—ïÌNƒ¸°G ÷+¯îÜWñú€'«-ô,ÔŸÕ#=+´•ê!§"âýˆƒ¦%¨éó•ãóÃ=_9Ìa©0®l«nŠßî¬×órrïF¤ø¼Å6Lß­ê’O)@þ:¸©‘ö.@ïˆa×iæ  SÊMßû1¿+m„úlM0Wò»7É+yùá§UAs´”Ænÿ.‹¦¬ÛìðÄwñ >êvM´oüÄ-ÔD¯0ªJâæ˜wè5öÔeÉç§ïâ»Gwd‡qý ž‹Ä§ûÊ’µŠìRñTÊæŠc÷-°V²[¤z ö|-Ë §Ä¿ÒRüŽñõ($"ö /53‡Žg±¢ 8yÛ€—`›ì“k·Å‘€dIã uäû‘yûÓ¸§°ÛÀ·ûTû¾KòR)Õ4Ž”zò`Õ©÷hhzfÂ5S*Ÿ-ù)*›5YÑa“_Âéÿ8_”Z ™èm7™ÓoX…ëØ=éÇàÕÌiJä› øø·0}Æ=ƒÛ; ñã¿[“&ç Z„ÏAê¸Ê³m´>Nó1\bºÈk ÝëyYVfpª.kìù´Â #M,oãÌMI©¦1&öÙ$‰ä‘²píz-@´þ¾àÜê©øŠ>C!qä–‘#µ…­' ù=[C;žj…÷•nrjé[óRÔy–obV„Îè)püU1—{ª· ûèS¨ÏIJŸªÈèÛÁ¹¾·UágX1vz£ë>WÜ|Te~¶q_ò9HäéþµÞ`)³ÛÕn%5-ñËQÃ+ÔwõØzt­È$ÉxÉ!T5}•W¬[Õ>ù¯‘ík8 ”ÑÝöwý´U[ñ›\9e©÷´Úë#Ù´;öc‡$”Ø1†Ÿê¤qå¿üG¾eȱ÷ ¾ñQj)ÓV–uÙw+'õšµÒj½-6Šá<-‚ía×~‚ ¸(߸]ÓÒ÷ -+|ž¼FOÕ÷ºú%pß ì”u¾cô]ùØ´…÷8¾rÃ7ŸÙ”‰I¨Ÿß`ͪÚ›<îO’óãzb(¨„É™ìZøúíûM &©Z´Ä\$R¿ò3XÇË-kÔ$ÒMù1Ã4ýDÚÅž´.eRÆm‚›@ivH¶|j_ñ ¯“ ItÃÎñbŒÆË®6©ò¡ß80o•粚 å:®ÀjƒL«¡ƒãñžMZòY”šCꢛNÂÝ9Øþ£|´tNR˜,ƒoßè9’©°:§ØÀ£«kýà]«IhŸÏ¶QòlsÅ>3›’¥Œ_ÊMù$E6qï´ÿP°2TÙÀJ^,>Ñ’àíO0bûUJ‹É0àãn‘¯Lí¼;B¢î¹Ã3¢"ì±PÉ—Üž{¥âî§n?ƒ«*þÙ®¢BkY—Ö‘Ä“^˯8/5’¦Ö•AŸ±&{É›áÔØ¦‡@wxËýqüƒÑ°ÒÀ~ =ü˜GeCë*Ÿ$Dš§cdÆËöý¯eß4Ýóµ¾ú,‹×[çøÝû¨}^O¼® †ä Œ‹}-…eÍã]5ÿ1¤q‡¤â¬#_aÁ7-L!rŽG{U½Š±w½-uÉ߆Èb‘ËmœÒL‡å‰pÏë’ÆeÌd¡j«ªðR¶X6óË›ƒ}|:£Ô‰Q‹’§fMŠ-ÚüBsɨㆸ˜s+ Ë—”¶Ò ëÈnnE£ÍCkwĢܛïÓí{{l“"q"R9™}~_ˆàM:ÓÎíÐ ÒÄË7¦q–¾ÐK†Þì»I-›æñö”N=7?½°6û±K"wÔwBì^Üê–W…½ÔŠ:{‰2Æ3ûŽÑ¤–oHľCAùÉó(ªo”äžb­"ÃÌŽk·ê½¥æèŒU³·v=_Mó‡ÓÆé, š™Ê’E¬>ˆJøDî|”××f´,@r€ ^£tš¶z§}Ƙ'"ã ºÛròèG‹pêÎq\‡÷ÀÊæQ]8ÿêöJ‘Ž?@ø(¨ZY€;D˜3¥ iWDÞßΣ.U·˜ïðè<þ%Ù©¬ùÌÈÆ†¡ñ@ò¦`¬çùíqƒ•{ð•什ek ÷­ È@ÄO.àCú~`läªv¹ÿ§_ÀÂÃÁƒ/óñXj-W±÷– ªUùrþqKvç@ª c¾µ–åÎÌô¯÷§Îº(ûâ¼vùå rÌ%GôÕ ²BÖÌ…**¼ôfTF«ø¿|¨>G”¡>ÐïGyÏÄÿ]¢†¤Q\æú¤AF3G›ð‡Ó'65$¥îæXÚhÃßøA±E“qAÌúã%á:â(9æ®§è}¬†¨e•ņZ|k¯ýöϸµ{®BÖ¡CæÊ`&”àhZꈪlëðlѸÎùâïÁŸ½m9’‚2iw ™""tñÇ>z ]làÖ¨Úô¼œ Å&XŸ»MÕÞG ¹lltràXí)r¼öuôHÛØÈÛÑ#í?fó9^ l F+•Ö Åé| ™ÇÑâ’Ž_›Ž2)C"¥ ¯F{zœ¡0Ð*Xní2®-òH?/HÛJ±?ÄÝó¼jy+äAõhó­¾ý ½˜¸‘» »íKREzôiéÉV<ýżHãh¬ï*bU½9 {=N¨û*!²Ùb8ÔNA´¯ñªÊôj\†« tzb#¾áM}9Ë|*&Uyë JÝ»6/gÛ%Ö“¦ÜiâðƒXûœ‘wù¾™>=ò{L ë Ú¿Ï< /™r—žŸcÒÄ«ôȪm¯Ý³1y†#°;äüœyFÃS’™öKCµûaŒûôölpLjlÎ} oHW:Ñ…î@—‰äwa«Æ2_fŸg,R×Å>îp§A1)~FùMꑘ8¹c±Vç#Ý…ôõIW£óÍb\ óvÆNû>U‚J¶Œ"f%_Èq{Ùô°ž9N ¬éUû[‰¹±›óÒ¯œ½¬wc« µs¯½;£ÒýŽÎÿHÈzqù¸sb¼ÓCRп¦å§‰ÌW¶èæd;®O0(M§ut„7ޤ&¿:ŒliäÀKñ\ü²ÊKxgO‡¬³–Â1ò¢aÉdæ¾e×¢wÌrkY€»20sGá›j—ƒ§nKè[îe5 ü5°—å!붦IžBƒëUÓ¶ª½·öǧ`ßH·%Øáï‡?a%<“õäI÷½ÙêϘM"' 1_l|¬¨Ÿq|pÂzmrþ¨"„‘àÕ«”ɧ«rTŽX°|%C"Ò³ØÄ¯Ì¶ŠÀ’/yõ£št˜(ù”þ…à·O®s #Á*>,Û+ *Yˆ¾¾ÜG“!^’ÝKÆWúœA6«{ž¼.4÷øa×¢jG šCyIŠ%…† Ûëê]xþ?Úðg_™}”"*è†ßØ9¬éΤ¹æÛÂSGíß`¢ô ÈG¾îqñ Õ§Bšc8OŒ”G¬Å T+ˆñ%øMêJí¦FìŸdU¯ÛÑU³ŸŽÖäÃÚûòw_f¨V}ŽY Ì;Az”ËIO%û\¨TËý"‡«¸Ê8gÈ÷ò)Ü¿êù•—Nî` èœHdð"33‘«E2ùzÃÿò»óZK÷ç—(*¯t$oBŸ¦o^vÕi>ãc‰¨R¼*n?ÂÍÈj­…ó"Wgš’C¿afd¯þHÚ s$áÞnüºãÐå 44btÀìE\¸hÑ+å–±ŠUõBÀüS1Ÿ­;fÛ®š@ñg’EF™öЈo‡°M´%€ŽþÔa¹íˆÞÑÕ“Ó׬O¸•0WX£¢}·Zt \‚ãßQzlÙ°zÄ"xæä$LÊš¼°ˆ£VuN`-K(Þ¨û-åz5ã)¿(ãZys+a¿É¬üZ’ÒáÚOIuVw[9§RÎ…9†·ùc)мŽ1l=‚t­^BP †¬áú”Ð=@8®æR’Ͱð"¬L¹I™qYßÖg‘É,u?|¶¨È9hA+ï­¢øp6ƒO¬NCi`{oV×’`\|T°ÛIýÇ6"'ZYƒçAX˜p2–7nEwy„¡§)7¶õõ4f'vd‡nè)Ç}š 6Sͧ²ØÝfè¹õéå…å³7{ºÛº³(üÆÁÙ˜vͦsìA'M4Î4¸hßàƒ¨X%†QóMŒt7>NI­å«* aÏ€ŠÜì£H1Všx¬ËK)æÝ=,3–ÔŸÁ…v¾Ë+ˆP«x½¢Ч5þŽ–ÞJØ»œ`"N BGPÿŽž)ýB!çY¥¼í(1K·w=2‹0mŒ­w¹’ÊmÒ¾„UÎu>™?9Б˜wÏÌËVÛ“4/ð¹§Ð™c´54@VƒBdÉj;MOvÏ¢Ì3PJ:?â¸dÜäOŒrünŸHjp|¼Åy…U‰K|3¢XCí.u: F×LLMk_TBÒzyk<O~úNk?ü»~¡d~r3¨ ¥íé6`^ȹ!^fÞ{2÷C·ë ‰SÆÏ°ß—:ëS‡îÈ¡ÈÈ“6È0KO=1aб„ÐT9´Æ¯„¦¾¹…ß?ì|RØ¡|5,8¡¨Ý~Hi¥s€Û†"ç¬èE•Mû›J¼šíæœvǵXÃ2êÄ”@¡€œZ=\L"®š›î‚ØU(E?¥¥ñÔüò nL„æå©c ëò\”룩dk¾B"mî°º{=Þ#(ž–0Œ†¦çÓÓ‡¦†Q¸¢w%ðüËÓƒ’þ©E ‘‡rgD†Ð·q5^g w˜h×¢ïFqd­‹à?çƒ9ú–†`rxoS4?ö¹å.±X—p-<ñ ÂKZŠðO-šíº"oK9”ñŒD ¸ú0q#_åà,,µ ?–¼ÿl!%±ùø°€_8ßôЖðîäàÙ˜Š»j?#ò‹ÂŽ´|ž(ÖDE0sË7Ó2¢ä|›J × Qêòg2ºc–IüŠo/õ‘JBªßzÿe.[d’È@÷êÈBš7Ê]mz¼“9OX)^>"Äê­ÆÐ:$ÄžLìF!®* ü›šzT´¤ªÊ‘Ð éï¾{çï*rð€íÔ£R(©Î<­Rk ³‘‹Ï^ ~˜˜¸û&|(æ›[Ý0 Vè÷{ó)¤eÏÌ^Tq\EâálK´ò‚f“`Ô è—4ïìÈÂâïOìömåGй;¸5€^Vp³öØ¥¶K5©hK7èÝÇjy0_þ´eg䯩®äí ™,ñ 3Ý Qæn.ûøÎm‹¼^ù²>‘e%óBu0Ñû°Õ½öLŸÖYg74å«Ö2àv‹ºwœ.9æ™85ßMõÉ=4Êä»ôjOë1è¼}Þoìb°˜Œ{#Ïpaí®sÿôn»Ð*.ãã: ïð•Í£u°-#P¹÷E6N m@·×ç!v_1ãÇ+é’ˆ[غ)Äcü­IpbÍ¡S@®J)yp~Ô8û˜*³ ÚF@xW1-‡*ßéeÓ”»YsáSíÓ ¨_nýJ+m_”¡*<)IŸ·í_¾kø$F::ð"Èg)¨¾ŠÇC`ˆu1ö"]Utïþ¤—‚e¤Ôþ`á Oè_² pÓæ~Pœ¦Óý>(V5ÛJ{¸c}s:yû0‘;Êú~eãÉɼ©’ ´‡f¾`_SÓÌSÏÉ&ÝW•‘¢–º¥%­(;Ó K¡é-éW‘^!×)m}ÏùM^¦Ã<ñfin+f+²@OrðÌ~â¹¥>®,Ç«(°ì,@’°£.`däYšÊ9†Ïßk)¢•¬ @»@€ßDÍv¨ÅõAGEÆL\ˆKÎüª¬™ªÌê¾o£Ö ö¨cpîK˜½{™/€úè+"!¸‘húœõÄÏÆà1¾¿b´Ú=S“àºk…Ì Öý¦Oâ#ÔÔµ3Iá™O“Hª.ë§kÑ:}NO·1jµuìˆ9zIëBâ¸À#ªz7XòåÝrÊ£Yú§ìµP±ô}Z @ò¾$là€’`N©Ñǵ²×«Æäœ*ŠîºŠ$¡á›Rè0~Ém•Ûã(+v…M$cÚ=§búé›56™4ËLpƒ\© ^ýogéʼ7“႘Zï1߯†ò†gÂL é¶$Úg¢¾ÔŸÊã·ìT!Æ×<£é˜¢ ¤åqœkQ<”ä^òr0É´IŸi­à±õg‚k# KŸ¢Æ÷gÝnvœ±bª`¦ÔvЍê"]ª@XX¤JŠ´4 ôU¼{0‡b¢4ØMíÝŸÑ3Ïi<k¼‘13æÔïº{Ï­rŸâ¡ßPâsÑ«A6¤zü¶aƒªÖ¬yׯÂÇÍfq ¼A¡WD+îwZØËzE3!76_/-_0@í1ú”ƒk¥g;͘ºC8{Ñhtí4GCtï­(/8¤Ú½ÿD8S.?¯Ãªb¿ *qO´+þqž{Eû•x¿îÕз¯„ÁÚÃ`šÂµÌ­ò8ï—ówÏc$e YŒWŠÜG‚‹)»…k^ÇjKQ¤ÆÒ‘+Ø~¯VSRòÄP‹åðE¦Æ4. “@ÑâbÂ6æD‹|"8ùmaƒ2=„;_Þ2˧´%~DS…æùŠ‹Mè{,Ü9`7âúbË„!ç›3ˆ‘Í> <¬+Ôüøä6η»ü<™)unfîÈã„»øö¹—Té‚ÝÎáÁRh±§O6–ä§a&”ÀïÁ?„³$¨­#sâ‚‚¥c‹eŒ‘ïFÊõY¥YRýÕgÉWÍæwð3 ît/x¼ù¢µüwšm(¶ €«š/GF™%¶„\›ßDÀ5l8ϤÊZóE;‘X{mÀÖ$æ×Q›Ãœl ç#ÚòOÕayŠÁ'm•MñØÑ p(Þ ­à¥Ñ'?Z´×2ádiåæœ=SkëÈZríî#m]ðƒ³ºÚ¤t>¦;b’ê6[¢Š FÕ[}jÔ8²Uw½ôrV+ &M0k,ñÍÅ3ævŠØÕ´@™Ÿ³.çl~è@ƃ_ßÇvR¨iª˜Â9×Q(#!à~幟¯ëŠ`ˆ*›­³g¢üç¢áÍâõîQ´t±¤E[@%)z^ÝECsßM”´n×ëC©ëÍMï» SÞùï7ᨓfkÖTò€9Y³C¨Ëˆ]yÛ;‚Â2qðu´6r‰¦)¸J´æS"ˆ‚½sðq>µ¢:j’ošl-P†ÛaéâÎðÑ÷?ô·`Ë>ì™Êìm–ØÆW&ØÔ³ßÁŒ,ÿäqëæE-­| ÞïŸþ¤yóÀúÜza³ê«Y©Uk»÷Ï+¸‡TVÍ«— ze½¯¼÷öÝâ[B軪̓)"sÈ_ðõwàpÅqRäÀÜlüéYu õ*Î ?¿UõyÄ"ê«f™UÁ I!ÏSƒ8?zc,xÞ¨¿UÛ9 ¶¤B$ <8ùOÌÕ[,àA¸Â»ø>ËèÒ“%J㳇Úã¹;2’¨æè—>M}Ž–¥»áÔ ŽÁQÞ3õ‚´'…K‡9øûîk/ú5á¤Ó"i ,þ.ÊV„.:»ÉÞˆ3v;Œ•Øæçòä3n^OŒ“:Ò!Ô—ÛÉé—cKç*-2ˆqàx¤CÑ.°ÊÍ–6äbFþ¢ ò>šHG ÄØ»b&=ž›Eòšë‡{%Y <&…3» ÿö³°Ïd„5ðÛ!‰³à>—{*á‡Ldž‡Æ•ŸØUZLž¸×¶1‹ù¤.Í)ø ß! þÎú3Ž=ozl—[Qü¥CÝ”´#5ìI”aIoXMlj£G½qÆÝW@æÏªÆæ4>œŽ„Ž£‰A‹Ôgi}9SŸD®?÷[|—Í.Å5öš‚{8ÍÞ‹Î~ ¼bFìëU Ê0zup\ïeJtºÏ‹Àÿm.ÿ ‹«§n¡›úN¥gq)u‡ =>z"/97Úä­£ÁÑ%Þ9³‹›†¹h-×–éô‰œà+ÌxÜýs”ƒ™„òF²l Vç„¢‡fëÎ`× ×I›6qZÜ3[•ôP³Ìœ‰imFqjV‘Ϟ˫>Q·.6Ì+¥²ò£‹±"GóTiæs![ófoO¾çé«LIx«ý§Îõ«WÑ«+()uD0¹¹ïWù(`+÷¥œ QF©†ò¼ªkìÔ¿h§û¼g‡IžÄáa—¥NéΖª)¹Ö­’*YÑ’Uiûà.øµ\áÏ ád?%æa/b½¯‚‹ùJ©­ï™xÙjݤ¤¢×"fI à+Mfü¨Pbjt(SÆh?zoi@SÀ8x'J‡pE€rË;\f5ùìëéúó— ?A`n²nï†[äL†U§º$ò˜È× ùöéùQžH•ä× W[=q‚×ô%8\ÀíE²6MÆGS>ÛyÅÒ}'U„›‡£ó»Ÿ©ø¸y bÁªW™%zÂúVìó\MÕ#5ÚÅo=If1FºYS‚³ $_ÐO?HD*5p½jî²hâE¦öh6Ÿy’è©w—á„™ìF…mîÆ¤né¢ÐR©R{•Ø †Ù©ýP§¡-~"x–›ô—ÜÞ8CiŠZ—´¤(0`µ©wy8ÍæDG?lðY¿õ:V³yéyzÀ@Ó5=ï%Óº¶í•²_2 }Oá¿\îÿù’SvhFáÇ¡ËD}Aµƒð{}+5Ù`‘²®#N!îMâì¾ÅÏO”׫E,yîDÏý/Rį+ò¡;Þ#Ÿ²:ÌGZŽÉœFVõfĪ©žÞFŸ$·gD¶ºa‚¶/£¿ÒµÖ´ëâ±JæLP#]Ùż»½ þäÉ@M_‰ÜÉEXg«çc `¥gs÷žÊ,?©ïk-ÎÙ"þ´e|F¿ÝŠxæI”µÅvª]X:^e‘ÿÅAƒÐþßsdqNÛ kÆÏF s牡¬ñ>swo—z§KË,o,µÄåÎh&P¦3„H\òÝMÌ;«Ñåß%rˆjÿŒ¯È˜ì7×qazKšRFX ´ü€ÛŹB‘iiÝOû.Ì|’]ëyré~›éÓ6 ©û9oQ3‰ÞKs¡3D^î)SµÂsà«-¸ ¶xröJ=éŠAV÷|£ÈUj…‹çW—愨(ßí?ÇÎ{H-0º8¾yE‰EÚ¶îlÅ%lTŠ[Á_TÅU“kÑ?2Ò²ê¦ Ö)_¼/åj¥*GÇ@iXµ5= WÒ L@« 9—1 &v¾?Å"›¢âò ¡'l;ºf?p_Ì]0 òÆ™«žOL)ëk|krÆþͽjÊ&º?¹·ß²Mî^ÆÃQ›K*›tq˜´yT—`ÏJú•ì¸a{SÈŽ7.c¥è‘÷(>± æ‡ÌÕØ°PlH{š}7PV ¿ÿË| /_£ú½KÂe‘Ë’C…znï­óÝ 'Õ‡}Þú¡«éÊCÅZÕ$×M< f…°Tæ]sD`’RcHq¦¾#»z× ì™ì6àh&“¦H*ÿ:³ðÂÕnâ%]dEò¨x8%(ÐéÃëÄío»—7[è=®€äüÁFɨ}ª6Aò2DïaùPÆû5á€ôß©QRÀzø¨=€?l…ŽgyQ™°ªO_õ¿¢&Pf$€ê5FFßœh çq]ôWá72‰?¾gì–+§šf–u\¦%‹Ú­ËÑbSŠ„¡ß5rï^ƒ5U*e~·Vy§°yÜܶ ~Ú°ñܵú©@6Õrîö{gï ^)…áiÙlÆ¡žbá+†T®© :=ôhw÷¢éqçÜao~jؾâ—,ÂrŒ‚¦ô‚*Y‰H˜ZyË?ߤ50»&TJvr_¢õh|05¹#¥ŸJ˜–t¯S”eÉï¬â=}†¶f‡JýTï.¥>‹õöLh1`“òª2Ýšgع¢Ù`¤÷|zqûpÖH|bNâ_Y!Ùq-Aò83Uùò¨\ð}{ͤ}o” §ZÈÑøra‡¯êSy9í}|TÊ­;–ž|º@`Å›ö§†§¢Lƺ70 Ãü§|¡Luu81Zó!úˆ?›é{FÀ7»QÎõ×júzRñ,•õÇ´ÉðSšÀésV2į~âpï¢íVüü ³C¿I –OõFy……öŽ]°ã6ÅæN¢­ä8àd7kó”ÏRk†œ—ÉC§ryx#—ÀOÙÖ ‘ôsVG>QâZa…qÜ^N#Ëë ¥…™.šØ‘1È.ŸÿÓ'×õ©MݧÄPÅrÞM¶¦ÇMm•q.î¶–¢œÂS?/ðqÞÌ3Už›”p6ôHmÁ-¦´•×z¥m“NTËD.þiþÜÊ,”Ïdu¾.¦Ùû–3ôÅi‡FË»Àpcÿ¡Z¼ÇEÒÝàNóÁ=è2˜ÊïþT……b¬¾-*þ˜ŒTÄŸèeŽ yMŒR€342ÔÔG;< +ø«m°oÑë­LâäŸ'+¯+Ã!kZ—pVÄ’¼#÷£“v!` @®£©èÒEr,O"]MÈJ+SI3Oi% #¾@¢·"½?J‚ÄVj¸O„ðܬ°ªæX•¯x§ðÇÓ@õ8î%þÉÏ!QOê‡öFKÁPÂaÇdrË †šq?¹…X{ÓFB“¼ïÎuyéÇÒ_È5‰îc²ßysêS]ªˆ´±8´^SI1îoÌñ §îEÊ÷|Ú;¤Sk_ Ôç㕜Ù!njlW¦ ¨¹X®´œgdè‡Íª9gœs!ÉŸ¡JÒ«QuÿŠÙ›Œsn~§ºi”ÜÑ£´îÉìÔ½!¶6 g"Ý…?£A"2íÒ èØ}åæ…Àz>ùì“[‡žŸ´O†TÎ2'ó¾]zº#2.Õ1ÍÂʼÕ冹 îdª©èØì&"Îrªùº6»è]à( ¹-ÎC¼ÏÎ µsù:æ"~£S‘ýÊÎÃŽ^}¸ý0\UŠÏdR}^­ÀÁk^RMºéMŸV:~Ÿ¾ 6ÈÛáhø*ê“WæðDDð—“;¥-C9_ñ~ŒéL”ØƒÏØ“MÇû•*1«åÈý¸ÓÎÙç.b.QmuÑVÕ©·oôm£÷œ½­zíkµÌ,ÑÓÈ–O‡èýØöé‚oæeܨí.rƒKjÂÌ:«Ì±û Eõçq˜qæq²F¢xå¡ùl½¢h18RL‚ Ç9 Ç…êæª η HÁÏÐ.0‰—KI™*â°9å$oñ}¨5FwÍ«;¾²8_¼WÀ–)-ÉÎ hJœ±ž¦‚±®ÃŸG26zꙓa›ŸÚÿØ—¼-uÊð‹$í56›ðÎ^l*PóP* 6P~n§kvS8ÛnÀã{B·²•Ý=N#Æ”T_-¸ kÓ^hF뎚ÀøO,.Iy˜‰±æï+ù̾tWr²Ðgž‚»ñ‘ XôüÞ}*óˆÌSP¡± ›jbÛmz sZsæC\ ÷IÛˆ&ÿc¤×¾f$=“ÙÒüUBD?õÈ —Kb fúcæÕXxÆšì³+ÄH2®¢ë îàWÒE‘ ¢òØ5fÅíMŸ·¾,†Í»–þûq¯˜Óµ1$[ÄÆùYF.ÙœYµ3œÆÝx>óT„¬õÁƒŽ'æ˜+FŽ:\mï÷œFµí9}¢ö+ðbûˆ!~m¦R0WZ‡MeÕª·ÕC žŽÝ \„ÌÝm>—êáúNºÊ©°¨è+Ÿ.>#Ý‘<! M//ž¬Þ(iSX†80ÉÌi×U b·ßÊ‹ô4†àè(Rø\§&¼ í%Å\‰Ha(x.t“Ûö&W&Ðñ)´ÏÑG&ÆWíÙ¬Œ '–Å)¬—×nåIß•ürLÑZ`Wa±ýZLÔ‘"ç:ô¡lÔ¶¾rp0g4Zü˜ž§Ro|¤–¯iŒ+¾Ñ…É[âM'oó“€áTu&ƒ›¹áÓZõ MüÒuÙ,QrïìË™€*3Ò ¤”yᱞ7œ³\¶$9ƒ±x ®·~Æ$ÅçÛÐ9 øG†˜Ú&Þ“ eòQKÿ“à >™.áø†Ó,jô½Ÿs3¿¦ÔÆç¬øZTë|fÊücëÑ7ß·ÿ?×;(Ä#¶ ¼'ûÓ–{袜t°Æñ/_¢è‹êÕE˜·ÝÒ Rµ*l6xûSEjlñ¨L#ÙÀc ä'ê ~»IÀ¤g„j& >÷´k¢‚ÃK¹3Ìþ­Ëœs;ÏqðvfÍ¢=ضD*#9C±~6¯ŒsÖ]¶yÅ…±’Ðö¿Ýv8¤oå b» A“•]Íñ;Ü2ZŸ.‚l±û û„~ÓZZió"‰Ø‹&¤o¦?»RƒcŠ«Üš¬þ¦6&ç>t¥P= ì(]ýBÇmPJ>&™_¿¸ÐP™ùœÆ\vÒ-¨½Áºw¢©xVûOÔåîUŠ”í¦Å‘À*"¸é¥rKN%ùM’¼!ÑÅ{™ÂBy•°,>YLéI¦ôqººðñ:Zki)³³4ˆz6O!˜$Bà¼Kˆ¯›5eùQ¦^»Þ÷B•—ð+êXwgzNâg &$p¶K€ŽôD³KÜ£¾„&ùHm"¹i‚[‘½Adªur†ƒ,okÜZjð+×§##<(E›“uŽÔ\–ðºñ9œÇe¥ jcéàÞɦ³í2aÏvR!^UÊ×^·&ô6{ˆO+z”¿’MànžÈX8e5ßâ´²&ÎÛUÇ1óFf° ³Beš\ù™<*Sícz+aM®àÔäI†7ƒ¬mܨ­ŽÄÓ”ICQ¾qWÌüÍÌwï+ªvÖh ÙÒ}/^. ‘·a!¶æ/°ÉÉ„=¦Ý$‚‘4K¥ÌŽK?²Ÿ-Ü~¡²Oö­¤Rj÷¦£Žõdnj(%·€ ¨ìºÅü´S#¥uáƒ÷Ÿì,+C_Ò$¹|acÝ[Ÿ43Ý}•ùO‘l¸- …ÄbÍÌxEÄPBg%Ó^9©so)yêÉFøò…Ÿó ¸GLæf8ß§Ô𾾸ØsÊ•ë`Iiwxpiþ?Q±Øo…ÆŒ7•¾6¯6´˜RwÁWþ³¼åšÐYDJ<À¿ryX‘glωVáˆ:­}l}ñgÑ…µ X)¯ËLpÑK6£¥l#„°þïrp°hDÐ?O’@×MžšþT6ÜØÑžPÙñâ&¯7^)Œ¸9ߤß»Î’ÇØ;„Ž‘uÄc1zÝ7lBM©|Óææˆ¡ëj'Ôb½:Vfuœ`ºv9oÀ²“w§:¿Z›ió7«f)(fâ÷2Ñ4|&óâê_>mň€“tH0åᥲܾ´V|‡ußÚ¶A=ÍÝÿ¦J¦'ù$r¯ù>>ÃS2ßâ° êTì4 ' ðÞYÞÍs²²¨ ·¹$ñ¾«Ÿ`Ú,@ï MìƒÐ?P.}¿ +¥X´ë'W’+ÍÏ]„rG?$ó|ÞîÉÏó¢o7ƒÄsQ纂œºµÓˆ×5v7 ùò㣉àFˆ•×mAd:ý À&%᜕ÙÊjhGÞ Õ\g}íEÑö‡©GG¢ÔòԜޑZæ.(/åo^ÀÅRCŸÂê¼¥—ˆèKC™ÔÆ-…´3Tÿ´‡ýë³õrߥBŒØr%Çÿ(ýÍO¸˜ R ±¢Y ¤ðšr±•• c ”iž*Ùftü¯!¼ž©tì¨'\s-¬âçzå0 1z,æ¶.R/½ó÷Ñ ‡…Noˆð©žðVê­_î@çÔÌÒͬ·ÙéÌxÅ[=çE³£eÀêfjÜM¾xœ?š ^ÌTÇå5)äm„þ{ûÈ;és¦ØXõY}ÀõÒŒjC)Uf›iãRÂñ9^{ï‘ÉzÛ†®›õ¬Ó †ª•f7’fÀÈ”@d!•òŽÄ]ÐoŽ:ÛJípºÁ´<Ä ù1#Åúð㇠Vœ¤¯‘Ž6¡ËË»'(pžòjH˜í¼y3ºQÔú”Æ0‘Ñ#6€ˆßýÁõÅßYÕ’qDúW:B@Ì“F#s´Ÿjû«,†mŽ!).ÊENl#„÷C¾k¢ê ä«š·WÝUPS;¢ÿ›kT¢ë:ƒï˜A1œ “,-!Ö/üVÔ—ÐaÓSè™–»WjáÕªoR° öœ&Ycro¸çkyzTËìýè|õ‹ÏW¨²ydÏxo§oƒç[° ôeóø³_Ÿ1ú‰ÐŸ{q­Þ Ý4^,\¯¦(SŒM*òø:Ž"dÜüî·º$¨)LE*>jn€݃ÿÚOÖs‚HÑc9¸w’ý\˜Vs«Óë]@jŸj:/çú&åÚÅÀÕ§Ëwx™ö£•ÛðRÜ?ÿô¿$«°œg3Uc´ÆÿƒtsÃrç6ÔÅt|Në…ÜÎ’@Pçó¼‘öœ8ÌbÚ£ Ç0¨.òÀDÞ‹™Ö _ìâ=r©öàœ’›„9¯ÿP§ª,÷€ÚÛÒþ µ?,¦¿ñ% c7ç-Áì2<§cØY¦½ìQhEÍÌ3d nÀ9ÙN#Mâ@ÈÒB¥k¦AF,~§.LI½­^ä¾p‚°bÕçší¸“töG˜ŒÒsÇ“´é϶©±ªÍª8*Ia­%"šY]#sBn¤0³éâÂõZ]N£–¨ Ù‘CanîGxʘÖ+!Œ‹·Ä…$sáËQÒÙ«‹ì;ÖÚ•¥2„€.çf~氋øl>ó „îpIlêýºã éLÅaø¹ÎˆD*ï üëÁûQ,çÔ%7PE!ú³£TcÜÆ(¾×²‹!~“mLv}ð𑲴yGR×î]›”RM÷h­¡0¨¬˜ìŒGøŸf ÓŠ»šèæÇ>=ý”ƒ•"#”g+Ò˜!ä‘ìäþ­ëu¯Œêå 2FO£jî8–¢T±%0ô-ßÒ´šË{¿B± Bf£pñ.½ÐšÙ¾Ä4ÑÐõ*Ö ®bQª¼o Ž0ßþÅÁ‰¬íúNºÕÖ [×0øVT4w…þ\Z­“·S$%ö¤ ÿ- º [ö›’<ß)~½)ÃÝÞ·š> å“n';-2Ü ÝŸ^¶K¡º‡Ë$‹ã½Ày¥ p#¦˜$ˆ;ôÿ4ªQçPP-é Ä'¯÷Ë'Ý)µiœËÇ¸Ž¶b f0«^WEF|fà²áXаº$^‹ó|ûKíW[õü“u35<Ãwú9Œö –jç="Ç1'‘Ë®±Žù7„™æÊ{g- ‹Ö;)}vâoèb*2#øèUop/²õ¶7­=÷_ñB¾I¸rÿ¶”¬ó•*¿dwYûÁrOd’r’):^PÝ´¢°úýOJ=`(o\eýxk¡Ú?Îøs³÷ÙÅtE®¯xhJƒ!)äœÃŒœ?º¨#e ,þÌ^ûí\g„5.×ýk<"†±S¼ß¾³DçìͨeM˜[ÇXu’Ø`X…Á=àk$5®Y`…Î]©ûa€mè'?(áœ0r¶eTB´¨à)kB-EUoÆŽ0²·–a¦Ä ¦’`ÓëZ'lµÇ¥†4Gñ”qâK^‰¹O3tÀ‚'Âi¨äÐ,\ziR€¾Pp¯×»ä¡î(ʯ•º nËÑßûÞ‰"ePX¯“®]›”áaÜtÖg=£}’‘âZòy‚ŸG¶T0¹åÞ„׃Áâ€Æ†,\ÐÔ~#õØáø.åQ©û ug3µ ¿h¦‡›a… høÀT`üŽ"0Ç“ñO=͇­Ò¨½i´ÇÙl yØÌ£¢¶ø7ÄÂùÂ\2JçªÐ×4ÚÏêÏŸí]Ç ›`í‚`©Íãà Öan ¤‘([Öf”ð@@ŒjÃê€hlãÌÉs²&ìeaT%P­‰˜ÄšF’¤øYÀ~d¦<°ãN©Ÿ‡¿]ùDÚPbðgMë5œa Qlcíƒ<ÿ7õC®Ë¤HDAqhîœ2r„Bû§fk?mwXg_g©}®ÿr¨L@ 4ûf‚MÜ!I}ü¦q®Ù7XŒ¹[Lž5Ó]½žQ®£'N÷åch$FÐ2fî¥Þ(t“díJ¨Rxõ^5´®›üÙ=O|žbó—ÚîEŽ`æŠÝªêW8ˆs‡4gð'†°Â Ö‘ÊØ°ŽP©ÝØðƲñͺÅË´¯NZ³ ¨>õøêT…HcÏ h¬ƒ;¯K"²nü}J‰:Zé|5«Wä¸4VÂFª„rÀ™/ù¾DQj.7/,:6ø©V‚ZS>Xê‰òY«¡MïÙsÍîÝôÖR¯âY¦!¢¼2mþ Ò’xø5œµê½\o»;ãk™ØWÊ"G¤HµØädf:÷¡MT•ô `6çöTáü šš?ºI꣊œ;’Ri°‹7léÝøT ®Åd¸ý ni¯¬úÞ4$X_W˜:ωµÊÒÉÝ·we`ßmOzë¯ÔÖ¶óèZG: ׯ‰ŸªÅ–·ýÝE¡œ˜åóÔUTZºSU®Ä!£ln9|X dDEª j¶úwð¥7ò6¸W¥.¸Xl¸~ ´GÓ?t)ÜÉgòe°{LÇ‹H ,*˾ + ½"# ZMŽ¥¡™6R#‚¤„¸ir­äú½\äšG{–¥ö0T&iå\G5Àaiø%±ø%¦•ÊzGqÍCø†Þ‰ì ›¹T1>QøÀœ¹^wŸÒÉì¯Pµ×PÞ„ÚhÄe ê0:Θt»=êR‹3;"}˜ý}‰öûôÅ-=E†&€¢˜jàïLÅ)ˆ~գІo/˜Þ c$¡¡ 5„[?Ê1Ýóåý:ŸÎ5ö£A·': ¾ý5*pHLÎÝÉïazB…5¬Æ>ÍÉ$ŒW¶FmÀ‚^{èO,WÏ—À«tk>j›|®‘UÆ¥³ºµWÈ!IÔ„âÌØYöNvæ½x^±ö•)jÒv[->(¦ºÎ£°Kº~0iH´‰m ß3¾b¯¤z‰–C©UZ“ LZÉSª>¥x‚9ÑýAv¹Ã×uD6‡ Ù.*Ñ–~¨–À–’éxòC³5µ´ÄmaRˆp|Ê:ƒ-—±(QžLËá­‰aå¦8`¼½GÇ㖽¡Ý¨?†»^7}M·G4úÑP6<ÿ\7¡3š©áÏ&Ž´×ú‡û5 ‘.>ôG÷®›2ΡèÑSÚ?ïÞÎ&Ü2Ž)ëþòú ÜrDÛyF¯â»/¸pÂÔŽo¸K}w#Íų¦k¤‰lS{D úx¡Ï,½È{ºC33t=]±+UÞ¦a213 ãÈRùÙ ¹¦üÒ-¿No0>­ñâi‡ä¹ËùB†‚ÇÊ?ÚZ¢ÊqÈÏ€vÑô”xD+¼QþŒÚÌ…:ë žt>"cõigs/j4È_V ¥3™MÛq­‰PÝ)®ãá=•çÌ÷ñb,:Þ;½tÙ>/ a\±Òœ!ä«jh,ÂÔ Rr©¬vZ ½ŒêJØÚ·ÃGáòý§¯ÏîTê¸õVˆ¡TÀ€1Î*8³k#,À¿•¡Áã÷.ɤé_1~7›YÄ^Ÿ€+*° µßø åä˜à2ÅÑ%@¬}¸™_õ<ª±4ÍöoÙéÎ"^ijù÷ŸrMÛ=O®%¢Økª€ñV+¡D©É› ú~Àõ4I†¯ðOð<´!ºâGªN3èΦ™œ)t|%?dõLýÓí¥‘Œ–Lå!°Ø)îåÞ°1C4PÅž —#="{,ð¥`×íhÀÑõKûÓ4¿²üµÉÐŒa›1#:NŠ®éІ~-*%Û¼šøu ãÔ!wƒ ;[D ¥)\Í«Š¬@ˆ‘ìA¿f%ŸÕÐK±>ìÙˆtD°)æë3 +SœZìÏ“¼Ï4ZÊç"« ˆ:]– Þ¥”¤LªËV-ôCðÓ²€d?Oœ5éP {¤Á< X/WÆ¥˜72¡`h”¿«%îÒ$? ®«rê‡tªÃ³ƒk¸W3Çãeî¼Pþ6ÐW‹Iùů!avá­}r ˜Í~:=(ÑÓ%Â…¤‡åaBù¸„Lž©[Áè4+ÛßÊdøÀÓùvÙ¶%Š0xÍ}Ø"¥6Ó cT—á cü¾IðBçDÖòXñ/öî‰s©/+¿…V˜:€œj%/Ï_h(’ ï¹s¦°±ß;ó¯iÒáÈ›ÏÓÐ-‹”=P°*ö#’ô1=N¸ nvËe˜ßÔ*¢,û“š‘O¸Ã$…»¯E *k×òÏ*µ”~?ßE6 Œ°|^ t·šyIQÚ™:ÌÿÛV§›=ÿ!$†/6° Ü¾xèFw«É鼆±@dñ #ûø§Ï£Ò¡°úQ²ޙÝ,6¼)PH0ð:ê^Ñ.-å3YÖýéjOÊ9nŸ{:Ìd(‹psÌRAÛfÆ£È[ù'b¹Åƒ‰xdåœf3ýç<Ñ:XÐÆÀÐκ¤ÓüdFÏ9IÎzf a½‚”)Ñ…7ëüh×¾ÅgÆ|€+ÑÌæji2ëc‡;”j÷P÷Â8°V뱈0CQ9(¨b¶/å;Œ¤ŸVL}Ñî¬v¢—¿oyF»¬î匽î|¦: ÚõÌÝQyÍo4^ƒP¸ôƒÈù®NX8By_F:”*!ßQy¡òc‘^øœ’ žÞŠLÌ/1!,ð /¦*+)+~ î#î[Ò=.+}Cö¯µÏEg>ï nL[W}¸Ê=»-í«r¯ XÑE•&²ÃÒ”ú&ÿ9e´¯eg ”î0”¼•®æñ¾#‹(øyÇJ\n߇ȇáG6[PÞç¨úµâ zf-sUFtëWãÂJ.ËxiøTY¾ì/ú—0/çP‘chÆPR ¾ ¿Í˜xýq`øf IÁëÔ»¹²û¨6æûDͽsž†ëfþ/O°Œ\Üô%E±uVó–oÿæf¹x$9¨È UæÝC=c’0Ò·Ôóaâéär¯>ò<ó•.SÎXänµ:ç‰ hU‰ó­åL/2”ò‹¨Šë”§¹å<ÒgiMøºªº”±ßx}ÖYI®.?[ ¿d[Ò§æ«x ¾R|™MIììŠÍƒÙÜ2Ú ¸OQœ²OÒ+ꘞ ¤ê5úÆ0© v9fk_=ž·¡RÇxJÆonÇRÔ#lyH=qÑa§À*‚xjIY}´@.<9 ¤Ö´¸%S•ÀÅ*eÿŸ@nÒÚå3’‹ ±N#qÛü¼qk‘oO`=ÛhÔmSØhðZYØ€Ê6šƒˆ¬wsïq"0a ƒôÉõ!“×Âhœ®¹uèIe€·çœ×Áò@C=Ë¡øÒˆ²Â™õ û˜\é"wV´Ä£\ ;SàDÇ„å"šQ’…CnXhçVoæºü6²1%^ž8µ/;J xC¸€¤ÌùL+ËTL®p =8ÇÄR!DCÃï×¢©J+ß.Rã'ä‡ WžÝÐó@ŸL`¡Qœ§çP‡‡‹^!!Kt±$µþ6¼]¾d÷gúúàîjŽæ£»ùÁRLO. ù¿1ö;Éöd¡ôT4ÊDùrEA彨.Mn,G›ÉÇaW'ˆiþ„?îð‰ÐøÂùW9žæF.“Œ„wÑe+Õž,V³ÝB;î+û =ë5ÐŽ.¯NÞ d¤^?CíªäjNé˜ËØÅبc‘1êÑ*29nZóV)Jÿ³D‘~ͪOõMïy‚å%³*Š]¹eŠ«|x„ë|´T%µ´Ä¢‡€–ƒ1ÞìAƒ‚×…Þó½ÞwLx ºõ… .S3JûðvÝ#›Ê …jG`ÚÓÒKàœQÇÑŠ±aЩ ?,ºâŒË¨ˆºuw£Óz‰h‡Ä%z¿Xø‰Ö ¶Í1&ORIT'ž']»Žýžº'\Öýæ Ä›v}Ó¿k¨lÃmÐÿsu@²E½ˆ/þˉ¡â[*‹)9 ökËЦ꺨”ÒYnh±ChI¶êsOVªÿ¬rV÷ƒbG:©ñÓœcËîb8TîfðÜÙÈKO@œ€lÚìJŒÅ]‚8\=¯;±¼”ýÙóM^ GyK`ö4;’ñ¶~ ‹™Ü×ë´àÁÍ›‘óàφHÒDs§¶¿é1;øûNT•L9ZÀÓ ¿wG(ä'ŽìU®°…Èw%gìûFxAíöõ:Ɇi#‰Ät^¨JÅgȾµp:[ [·“?`þ÷(°¢ ìvá^íÒá›ZØz¹Ó^/˜„õ ªŽ#ÝL)‘,׿6.R‹óÖ‘Ýs;pŽܳܨ—ÚÖ}Ø# kuS0äŠb ){!9–rl+Õª™u/r©˜ɨJvö¢*ðÞ¶ª§˜Dy²ÍÕô—ÈL6HDð¿¾PÓW·Û(ݵô$b5fû¦£>,¿´ÙØ‹HJ]ÑžÓ¡-ØY˜_Kf3läyÕ×þ÷¯<ÚÜâþm©"MŸR¦™[¸(»’8Z‰N^·{cüœžüñpÒ ÕÉi"œ£Ý¹óL“ÐMaÜK¦(ŠÇÌ]:u””R7ƒ‘ñ¥‘ÆÚ =Zä²µÀêÅ€b©ðAÍd¯æ¬°~­n’¢9"_ÜjÑr«¸¦³ùyH­e}ùò ˜©×¦³A«|…ŸËÉ5…Í ´zdÓ1oÅ>5ѤTQ±Rý=i&©Åû×1v”$Ð`½  F>+ÕœÝtËfq殤²FÑzTuÓ$¬0:xê>¥¡ãÞ¡¼\õR oœ¶ ÀhÉÍ=ùª ïGùém€O\é}³’t-.Ð ™?œ$ö’rj–îºþÑ–dÊÿ“ ïÏ Òá(ÀJ \CIV¼{¯wÌ—Žˆî Êpô›Qys‘h„·‘Û2.BŸ´g½ðí„É¥sSìýÙ*´L׸ñ£¢¯§Ç¦Cpu>F2ÅOÙ•",ÿz& óÜùá “¶PŒù¯£¾“afÐJ%#”›h`K§ñ¨Þm²’÷¬Ô܆·>º/TÍÅþg­Ú@™}®9ôDÏè¬//ôm²¹RG½‚aóž2[¸©ç»wk7|Õˆ"Uþ¾R¶«1λ ™ïÏÐy«§'ûÁPwá|²T©üõh¿f¤;:¸×ãö­ÒÛVê *iw®U)Ÿ]|¯Ý‚œçuÁõÒ¢Ià~[Ì1ÍSfý¢†b¸±å°Öžw"Œ9q;¿J‘º›ß¿ã·efzåâ}šÆ4ô´M¬¨–u†üQ5ñ`r~VŸÿ[ºÚW·3|y¦ZÀæ¨AZcŘÌsT¾ÙÊ4 ,Íûý5`Ì6¬+ã VØ-´ª§à¥˜§]Å=ÇãžÕß][Ÿ ¥r–C0Šì²êça6¨¾ãïoB—N ûî_ ì¤ñ§ôt>7ÿZyÖ¹+bñeÛñU7}ÀÉrw±s­Ÿ&¶”ž‚`¶ªqÞzi=7ÌU·ÅE2'ÐüˆøÇ}[]b©{Í“ç¶ÝEœ@K3‚Üì‘X:,Yõ0ÜV ¨T#F1í0(ÄðÅaŽcµ `û bîm¥ÝÑžD€J¹’hcpë‹Ó—[eJ˜x©i¥™žŠ ¸á–âe°jçDø-˜³èG¨sÈ‘vçHŠ‹t-I€ïĆ6–þïrãQçºÞOÒp#F=Ð|&ÿi¤È¢QŒþìQ£;UÖ08…cþÛ„hÊ£áÒ“·ir„ùÓ vûI§Å5½Pk+"`3¢—ê<Œœ|òØnàaú nxóKOÓeSrWá$ª% Ÿ-ýT öÒE=Š0W-Ò¡%P²Öé;zL€íÚ-I×g.[ rv)Á¤"×%ëä”`e\!â-T œ‘QZÈëY¹þ¸‹måO2Eu?ÅPÇöÝÿ!A‹wßÑü1Õ‡Ž=e6ꛞ¡Õ{À‡wÿZQçõ…Ä¡àà}]œ™ƒÌ§L—»æ/^—ÀaøÌ!ËeZ_×{FD…]Y?ÜÊ fw¡ògb%¢)›ÂæO­/QÒ!‹!Ç]£]ÇÄúú)ØÒY«^pn^³~Ä•ŠúÛøÍ«e-hÆsÂm7'M›ëÊ’À°d¾ áµoÈ{t…t×ÏL!ïL*Ú 0k¹í%[ìôKT+Ÿ˜3¡ãl0ýº®ÌúqKa!‹Msø©wxyÅ…±’Ðö¿ßÖ§FqñáUgm¨£YUºÛf}±…Â#žs ë¾{pÈÎ åt&W'•°‚iHv—ü#õ,ίRI‘E(™Þ%/å­bÀÏ6Xݽӳ#ÛÚœ(èÚ²_45/Ù;º\£ãK”D~¯Ñbì=8‡m÷~_©™:0 9?xŽ4áÍcãÒÈí×™"WŠù+ÿv›÷ùÖ ó•Æ +þOâQUôóh*¾ÿs7#/lÁœ?bAB¼µ<¤jaÕ6ÂÐ(€ZžŒ¡¸î›²Í¤U?ŽÔn]Ô& ¢yèãÔi’^~‚á+ ÕÓðÀçîRìZŠ ¹¥tš[ ž eø¶·^“öa·_@;ª‚ä+IФcÓµZ•?7o˃/»0<¶² “qtLã¯{l…j·u5ÜÒMgÞÓÅ­õ.íå~óêÉDÙqdòÑdCÞíiÁúgK£fO‹Ð ¢y©ãŒR»{ 0%¦ØúȲ+ITÜÂoo%^Þ׊R›3k$‹k­¦íQ|F‹u | 9…ÞONŠæ1ŸWªÈFfìXtf°å[V•_& DµK%a䘎 Xpô…Ò[aÒ¶Û6—$td(F(1†Ös'ÍH{—Õ ›Ê%5\SÏ¢uÙõt?¶œña¶:†˜¡$“Rj"8’âs…û¶_W€¹¦h“˜…§ðJ#øÚmÝÐÔ/í] (.O¬·½ ¦½|`þq×à톦yÕB ˜Ù bÁ´ÿÈLõ¤–«ä•ÛÇä.–jãŽ1S±xÁ¬@ŸEñ¼d×ñ+´±0F–´â³§8 AÎ jF)¥ö/÷hïØ‘ƒJ¦÷³|Uãí‰ãp¦ Ä×)«}|˜öÅ»]´Þ©Ch  ‰àL¸äÓÓ¸³ Ôö¦¼Û#G+þ]˾ãÿ¦v‰uŸ£¬Ä;í†?Ìå÷`áŸ:¯ExÁL>NO{ÏQsHwùzVƒŽ ®bÆ|ÑÜ_º-ň|ÃkCúýµø !­ø›whV7ݘQÆ ÑD‚˜›³ƒ[ÄrlKo¶‰m³|ƒÅ-ÛƒXðOÐ+M+ÖGs”D'üÉ{Êb|P®Xö=V›·…E/À¸ÇfŽÆÀT\-ëQ•ƒšcä‘þägö%ÊQ·Ò©´rê¤&[°ƒQ”2:.©} O•¿'€±AòáiÒéKÖçI ™†J¤¼_/¼†[u~Š'cŒ‡ŸW¢Éq¸èM«Bsü{¿Ü”-ùŽîˆ/BzâpSƒPa­Q¦¦–(´6±ªÏt ‘•áåü0³ð ¬.¬èÏgE<]\Ôf\8³Rṓap•è" £Ͳñƒ€Kz£fáÚ4Ñ”T•!ökua=æžÛ=tô±ºÔ¶K äÂrsr,§<àÜŠþâLÏ5—B>´¤Œ/º×]ÒŽ{v ˺£HO1×áa÷¯3à¿ E›ÈT“é z%yoF‰PxˆëÞ½ÂOÇ£l ­L¬¾²áÝGžy¦+^4ô"¡Øú¢|ì¿ÑôZ#±Ñç«uÈ{Ðßl ÁkÂß{@…"WªD„ÛfZê„Ëu²ÅíLJÌÍ`UNèÊŶ_E}¾TŒ2•L`tr—GG>ÖÃ…B<%øÓã×›jÇ9—%;Z[ŸCmãŒ6•)R’ÌîW£eh H>b"jÒÑIÈs†ë žC™§¯Øp=8Hd¯E»OïŠ)º™r±Çªk¥;£*0Ï;QTwn*eÄ hõ />4³Øï%£Æ¡Yl*cú:*@ˆ*<ž6C2½¥ÌÿÔ·¥öOðÈ3,±åP^vJ­éÍÞœe1ј:3¡L'†O‰Íœ¨Öq·”J”ôŽýe!ë¥¶×ø©ÊÔïê6ɒ EŠR¶Žp.×ÓÏÓm~$áÔ¾»î ¤¦Ë%R|nJJ¡0ÆÊÖn[´†B ;I‘bòíPOä—QÓùª^4óFEVšy½j¹µ–¡+î´Ã¤4ÛÖ6ïbôÞ'Ý,¢%F›”Wå'm¥sÝM«iÙøy˜jWw™mÜt¦ì ƒ1Q—>©½èûß—fa˯mµj šI ÊëžC>·ÐöÈ=Ãh/ÛùƸ?Ÿ8¯SœE"ë4´ãÝ-ýfs^—±…ê²|’Vd‚0ÀÖŸŽ\—PÄÉyÇãà¥jÏC´)Æö‰ Çìb–5d±§´¨jö\÷€4’€ê»êˆ¤¿„†’\Ú¶”»®3A›±ÇÕsŸ²žÝÃO¦Ó]œˆ¡‰1/ô¥k¹ÅÜÎŒÛáÆ}G¥¤e—} £ÀžMôÅÿT’#ÈÏ)ýŠCÐÏMIU˵g#a 9 g¶ƒ_b‹@`I{\}?H@–⪈h€·ÏB¿°ç#Mä/Ä0$”xÁB-–³Å\Å®ÞâÌ+þ®<¯%ئ­SÀÎõ/ÖÛK ÊãÛŒž“‰ž3Ô äü,2É,ïÂþ&bí®* ÌS¥Ÿ¸£aAä T9LØI¾%™\ Ú¢Ïü‰‚˜âŸÿÀ‰×+gã±c¤“ŒðÓü„…24܆þS[b+âçyÀü«g†Áû KO‰=äÜsþÓhqUövíµï° i÷.z”Ëš=m¾,æ°À‡L²Fi0¦@®/|LŠDÉѽ—^X,ŠÁ1Dãßð™þ¥ÃäIªçÑ?Î…¨D2nƒÍú`ÝU3ðF¼Ío™¬YÛª ´_ L„4Ä”…þ€q¯NótK€ñP©ošÑdÙ¡pì^ä<˸˜_Øçš&w_-­þ"ðPÄwȨÃu?DΑ`ê¹×©‘#«º OŬ ñln_&œü1%[<ݳ2³€¤1”i®&¬a-Êœe²5¥Þõ ï¢Y¾í¸p†8õØo…œkòÿn"#¬òÖ{y’PÊa£uN¯Á‰Zd­ÀKðe_=÷QgAR~³\ž?ȸó‡µËJ˜@(3Ü*êê(1€åÿ°!"ùù©½ÏµG™=ÓD¼j1RøV°¤r§‹´àÇjï¶•e§m‘`Lµ‹€ D覛¨HùýìÆ`ÕdqcàúÌ•¬üÏ[·m@ŸGÉlå=2Üb)vòñî*Œ|;°í냀ωG&ø'»¨Åe•˜gÕSý‚‡´O®ÐaÈ¥%o˜]$w£,xQÕ•iåè óå=}¯( ¦:J);Š}ñݰǪÊ|ÐâZÙÏÂr]"¸ÎVª(my¢ïF›1‹}C Z{“É•†×H÷û]AJÒè‘?fhVùbk:< “)=øã«6½ý–MÆBÃa¤ÓëýÜt£S²E“/4z!IBwĨb—„¶¦v©ªò´nÓ›Þ•tp>'"aÈ,ÔvãO<›©El‚¿ ¡óƒF¡zÙ”xŠ­Æ­896GWã>‘÷›¨"Q /\*%;Pæ…Z(ª -€.Lf©C®L4â¹Þ­3«íi\¼nâ·WÖPf÷ãgnø¸*]a-† ¿¼¥ºMeæBÖêbM“q{àDéÉw|ÀHÿ¦X(ŒåМvgT"Å®fa¹ÅPòò4·Œ)dJ¥µ¢‰¥J.ûÎjõltvÜÛ¿¬Tg*¯C_4«9ýužÂ›Ý „_¢j /![G’' 2o(T®ÆÇ~Fcc>ßlû†è„|Kü‹o^MÇ%zfgSaœòž¬ }„¦ ún"C‘9*’ÝåÎd¼€%z1ýŠ–Ë: í˜R/ú³C«±àY$~'n·¦ZI;§Ñÿ#ª¿$g?)£ÆgŸ(OÄ·’™qZ5Ù§ 8W˪ùp<út¯RÍjÔÐ2ÿþîàr­Q…aS=T,¢¯–C¢¶™à‡sW̳Pôù‹ñב°Ù%)¦Š%S3km¤þ '¹ž·ø^̸V¼¨eÂØ ‰É s cZÑÁcA¸Ë~}›JòOr‘ÖêI³EÈçbÏœåHO~IvÄÌnê¶ëå¤ôCxo0ŠÁ„  ]”ð£É”oDAÑýœ"ÕLôŒÙJ¸énKèá¦àQÁ˜™Ÿ³ì÷[c£NÿžŽ©¶7HR@“ }±(7,‡&Ðn9cE¯wœaß=ˆçGpÀ}óN¡ÎwÊçË@ú(ë2x×g§k׬MÑݤGÝ"ÖSࣚh©OŒ H˜ÔçewÅuäo‚™ƒ$'nçKuÝ2í’c9ZÑu D2âðŽJ½ðQFEî×Ï!/ª«^ˆøÅŒÏzÖ™ZUJ(GšÛÊðŽàõ¢hæÂw†èÙDÎCÜ6ÀÄкȪÐEÈb—é?å°œN›s?»®~æÞÚê~‹×¡Ñ”…žþÓÆ_ënKಠ|¢ ƒ¨ê†ƒ©W:t’¼˜Oð,âThQöM|ûª…þÒÄÇ­àôG´^½’R>VJ–ÝŸ<ȶÕóáNó/9xBje"k‘sñéO”Ù‘× ^ªÇ¦‘áØ,Û|ÁßMÖÅ!œ:<²ÜCÞ•+™…÷âó,U!Þ4b®»¤Ä¾‚KAÞ¨–_K>àY/÷e)c³ƒÂû3âÂe?2t‰…oå DãüxŠxAÈ¿ëÌV‹vÄz®ôRDî¸ï1íäê[ì*¨‚á\Ä!váyÛƒ‘ý‘y¹/š3ζý@?‡rCÙÎÅ»·Ô y ªœzú‡€“GlK7êF°µ ºâ¢2Û>ÇjN°%„ðôă×B«»Nä­­[–ªÍŒ”!ìCÒ Á@ûSÎ7²øº²{»¤7ÕXæz9W±D/ ™ýŠ7ïÚŠžòÒûɳ?ìñ½îÌ‘Ú4áœÏZW¯Mó¸ÂvöWöqj³ó÷‡àêgZ퇻ù–Vw*m!%óT¸B(­¢_ß5œ@á“R¸ªÅùâ»’]áñØœ-}‚Lâ_ÅznœQ8_¾îŸ Oîqà/Åy’™ /¼ÿDj/ØMpâ;ô Gk ²¸k’—㣺ª:¬êÑiB›é«Moɳ7‡"só‰& Yw^>¤JÅÓÒô0m }œ +n;Ðr¶yÝýAO¤m㌠ʒ™î ¸ëëÀÏa¯ã—Œ‡-`ൄ‘ðÐy´~™*zHÕYiϤ!D³ƒqòþ£$CQtã"Ê;í‘ m$2¾±9+v)'8ž£o‡Â!q:#vX ħvÝ6™~†­§R^µüâÐ%»gF¥Oþ¬s^P¢iÏø×G‹ÿ{AÒ¢8¶‡XÍ;$Bnršš‡feå)ωA§vÊóaä™P@ <Úi=\™,¯H¬PZ;‰öw]?ßÈ}p‚7=H'Q3ìñ—ù72Z8PQ©‹YSÊæÄkŠ0¨“š47B¡S% P£ øò6Oi߃ãB,w¯÷M²Ÿ…ñ [ù/L çJîr¦Ÿs8÷{^)PN«ëNe+cNÒìÓ!_"Þ >¾¡F6àê< ¼÷ÃÚûßüúSä„´Ž5hĵÓAæ¯ÁjÐìŠx€]Ÿ5FºÔ\¬€ˆÑÝ=È&¢-,(Òt‚wÒ4NÀæÒ×lŠ~â¹ì÷z¦n>ë7 \ákEö¯­[¿%¿%I’?œœAäÖñÑÛ¾÷vm½Ý>éŒ+L1J)¼£•±Û‘¤5|È’/•öw€½×­JŸ°•:˜2j:õ´ñ¯ì ã‚©Ê¿”ír 5«’×Ì:Xºy5»Ã}t=1- þåLÅ̵oHÀϨSr“·TüKižÉ1ù%¯µTȃ^~¦#ðŸRT/ò(¤âÓhZ×;ǃ^ Tb‡À(µT›ÁÔBƃŸØ®™cËÙz(•8¨¿·²ô_pÞÁÖ*@»DtjR‘ÄøLSQ3l~ñÃï>#ØÂF²©«Ê ftÙÒ\ô%)l/^æ9ÁÔ“ìïƒT§L \È0nY-j< Àõ; )Áb0,½øcåC×*ÁZK\<(HÌpž•×t²&“û?À•I艫.ÂK®ót¸â•všµÒ/ñ š±OGÈçôÙ¯¨ 8[/šzÃÌá)[a_7ñ9ùµ4ˆÃ…Ïgå‘à 1Š6“o¬¦#2¢§©§{–âÆŒuøì?ì»›Þ6™nqÑxnòa^u·iÛö‹‰ œà`uéÖÿ9‡WJÎëmÏji]–Zé7,U5+gú”βóèq)ø`˜¡2‚ UÊ MͼÏ@LÆQŠâMžSýò‘|2k£ŽÞ¯ß¢ÍÊO´“R„;]š0sïZÝXZÄ[fw¡°qdɰ,þ“XiÍ—‘:qMÛÖr™®[@Át\Q窱ž?H ¥\]¨q Q/j·­¦ìó‰{â`ÌÈ IÖŽ'5;¡ puŸÂ¡H{°S¾þI½–#ÐãÓ-þÃØÁ%VÞñëp… Y›Ý'c‚çÛ:ie¿M,‡P?Ì ¬8rµ–r©®ÛÉ endstream endobj 237 0 obj << /Length1 2570 /Length2 22152 /Length3 0 /Length 23627 /Filter /FlateDecode >> stream xÚÌùeTœkÒ Á݃ÁÝ%¸»»Cãîî$xpw×àÁÝ%¸»;AN'{fö~盵¾óó,VÓ}UÝUu•Üõ4 2by%Zc[C ¨­-#@¨.æîT:Xi%œ ¬ÌLt ,ðddB@'s[a' €ÝÉ gä2w010p“Ä€6@Ò`è:(»Û€¼­£­¡#H ´15·R‚L„líÜÌMÍœ~û`£ýí`bëð›à7ÐÍ hãŠêøÛ© @ÒÀÈÒÖÕÑÒ``c ¤“¡ÈÚº‚„æ [€!ÐÌÀÊ`kòÇ…Š’ˆ¢@LQNE^‰’ jt²1¥™89®@Pcã¿x‹ؔ̀ —ˆ¢’³­Ã¿²RRV£ È*‹€ª41%e€¬2HøGó›è@ÂÆØÜà·¹Œˆ²€²†¼#ýïj. ˜æ¿™þW:Ÿ@ÉþÎdjâ`ký'€ÂÌÉÉŽ‹žÞÕÕ•ÎÔÙщÎÖÁ”ÎΊòwe3sP¶–лÐ ø§ÄÎ6Æ Æ8ùãàw‹ÒæF Zÿ$þQÊÈJˆŠ()Ó‚ªEû»à´õžÎÉÍéO.Š"Â2"ÿKý› ¹ÐñO¿~û25ÙÜÊ‘ì/5¨ã F  NÿÉÔ§ß„­þâpAŽþwzô& ÖŽôÿ:êHÿ;ZQ9YeZi !Y%‘?,mþvàälúÛöÿ•áÿ)™ãÊÒòòÒksÐÔØø989;HþÈ@/ 1É_E„œ~§&óo•òûw;mAéh[yz¸þ÷àØ8;zü£ßÿ·•F 7wtrüË#ð_•¶‰@½5·ùÿ߻߿] Kƒî*+€ ôbÝbc![kkqGøßS!lê“­ƒ;ýÿ¼ü–6¶®6žÿ[gbncü»Òcg;zs{g „ð¿,@"ø¿e¦@'hºÎFfô¿Ãþ¹ ¿ÅŒ¿Å Šx{ÚÙÚL ¬Þæ&@м§£ hLœÞžÿTü_ÏÈ067r]}ÐVÿã]ÂÆÄÀù—Ääߪ !ÅŸF Zgƶ6Vî Á5§—µu Åÿ×Ò±u¶²’9 ø_ úï³ÖæVîÿ¿§ÿë˜ðwú²¶ÖVÿ¥3w5wË›;™ýÕ«¿äŰ1µhYÿªü^AV {Úüæ¿ Ãé@#oditt°±ýQAEü/Þ †þf  —TS¤þŸÃøç¨ˆ‘­±¹)hÚÙîð   cbex2‚î1ÐíÏèéll@&;g'ïß †ÿ=&l¬zߢ¿;€^èoÄ  ùbgЋþôb#&½øßˆ@/ñ7Eú±è¥ÿFzÙÿ Pù¿ȧâ߈@¯ü71ÓøâÙiþ@9ü@ ÿF ;£ÿ VÎÈÖ Ô¥K~7‹Þø”%ðDÉäÄÉì?”§™»ðŸî@2ó@5Ë@P|«@9ë¿!#ˆÊ?\1‚¨Øþ‚¨Øý‚¨8ü‚â:þ‚Šîô¢áü¢áò7drÿòøÿïˆÊÿ~üYi Ï쿞÷°’“ƒ­%PÍÜô­éGd œÌÝ´@ûˆ$ýüû“Îÿ @ö÷*ý‡µ  ­›'- hh™@ÉÈüû;ƒ÷ÿ±5úë1õg‚.׿ñïtÁ/ÍÛqY$5„”øˆäM–B‘qÒ”cóªKÆB.¥N¶áãgo‘ùòý›üÒ>åÛJ‹séø$øÛª“aY½®5«˜¸1Vàß6ð‘ñÁGÉR¥S H“Yô+í ¡<”ÌÊÕ(b™Nk‰m!¨Œ q¶u>F2¿¡]%’h—¶¬ä@¹Ì26b:X¡»-¢âµã/N¶ƒ;½=bF5èX¢šÑÏ Á‘„¶ëîÄØËl9àݲšñ?ÁÉ)k5é*2|„¿@#;»iJrÞ¨Døì*ˆÉ4×5'Äá’ÁJÈ}ñ´`tóËááöÕ@§E/Ú³ýÕ9^4F<¸>$8ŽÒ3T CÞw@¶þ'Gá“_xîÆuœ‹PínÒù#â‹:ÎÒ²Í^‡32½àß~ÌÏ ÈíšáÅ/ë*Æ8ß1±.âB¼’“ίóOÒ¡fÆ¥\i_¼ ¹ùß6©"\â?n=ïw™7Ÿ@óQràd³™ô#äùµm$á1¬ØM¶ÀôE±Ã2•ÿÒqˆôsù#TÈjX ä`(gó/û(œˆÀ”ai介cJ.Ý(~oAÑ–RÔ‹%{+Ì}ۇ˷Ö%èæˆ9o..¬AŸ£õÎxva¥t¦ žu4­:Ž_"IÐ_¼ö}à—I ªt¿6›éoÛ˜Ao ë1Ù£sÑ"É”Iëf.EÌSUÂMQàœpLDtÉqÿਆ£=ÆFÅHL¯,ª‰¸-õåã)©B1Ô“j|âfÖå÷Œûâ¿Â¥úðX½çA¬Â|;ß´c~!Í"0µÂdÖÊ\ƒÓËoÏ™£ À;%ªÚ˜ï浊òÚ¬sCž}žñîªÃ—‡`Z4M~c]ÔM¾› ¿5$˜vIË)k§½=ãÓ Òª·v•~OLè[ý_ 7’KÌò§âFº<^7>£«Š´ç¾Kö£§ˆSŠq,ñqg]ÓÌÍOåÿóš;7òÇbë=ÃB!€&ãýIÁØWüóÝE¦Où’YN†/Çu]ïôC´¦ÞC{6švÒ¡Wsýb«äkÿ’úf8sŒü¼°^Ê%‘‚‘á”ËOj4ׂàŠl<Æ#Ÿª¥°¹‘qxÝ%'‘üX0¿—&¥~>6ŸÑ¡ùÐÙ.ª0ª·–L£?P!ŒK…&ÿͦs¡Ÿ&wȉ²Ù 4~<«œ¬Œ^­ƒÁ¸ÌŸ=©;®TPwËËšIb€OhÌô…¬.u`JÜ僈¤ÑU¯Ã<esÏ¥‡©‚¶"6_Oû ­üëËy»´§3ŸMP¸F“ÿœ-9òWWIÝÞ`™:±ý}Hˆ¢ÖŽÖhÛtØ^*]'ŠgžìîVêçNŽÙ;ôw0aù‰E§ŒÖK±DSÂn¢Ä6¥1ïÇ+D¢=dâ÷H!8ñLˆs3De²È ¨1xÇ•ö¾«ž/ù¡$¿‹ð×Ö!ÌOÎáÓ<å­qâ»èOî)þïîâòòK`ïek&ÙŽ•œÀ4_Æ'æÉŠŸ—;Ûl;xmh\¨5>´>2žY<*—Y¢F93Å6—\¹“X†­ËTSa"s8¹oî˘s)õÜ)Û6c¡þ]F˜R:Æ:¶>¼HI;6vûeFŸ\ˆdÈ¢JŒG´*(”¿G–vŽ”WÌ"ÃX/Í ˆ‡ÝVgŽþ”í¹pRæ¾mÚ÷ÑŽêë[pJí‚«.§V~˽›cí¡æ…ôx¾MZ¸ –¢1…'õΜ¾Ýö¨}KÚ×#¢cÌ¡?Šœ|úmÙ‰ ½ŽY‰‚±šrJS¦Ÿý˜•WÈ$«hIn¤Ÿ;:0b¡’‘@¾EBQÄä …ÆWξwŸïvŸã¶B»þNÕãyY3àÐ|cÝøfÁBso2ç6q³L¢5掌äò[ÎVg)ž‚xÉREÔ·fkþBd>  Œ{û4¦«à:æ„U§¥~ƒ˜·ˆ¶÷YäŒß÷”!oJˆ¸Ÿ¬½5»\y)¢4‰ˆBJ"”™}‡}Nû.fmÓV®Ó1ÍØQB¾ù"÷ßx¾ºJññë‘ÃN‚$Öê›êÔ‘‚[£×cp¥dä©p'ÖËnYDä]ý>‰4˜}œüöQ£ø%*›îKw¨PDWr°xJ{SÊõéœ@iVçê9Q`À^Àyè @â¬vµÀ¼“õTÝßKiD¶”¤WܨùeGE±£ô•m&BGÀÜT‘WÛpÇö›¶úaC+éaÇšÕÖTüíò°ÝœhûaœŠ³Yrœsó… u|-œ‘ ]Ô“‰¬`‘¿¦s5¨ý4?áðÜ7ÿ|4‘Uç]ÝaB"åŽbþsÃK[:üé>¼_”FÒÍÜ^ÛëïwÀ,œçÝÅXmdžnÍ'î!½î"ï^âxìïŠyôRžZ“§è[v¹_OŠxÒ¥Yá“C¯ˆÞ¿å&]™l±£¥Ñ´Š¸øS±KBûÚØïUôÕÅhþz™N~1ä/àoÜ—ŽR+ÎV$Þ0IdU‡ö(È›’ßêÀwÓf4Ù¹†ew³ ù¬ï˜îûnù¥°àÍ£ÆÆN×¶sÒV(‚âëXhl6æƒN(¢l_šF–†º½>ipDÅ(²ûŽi!ô—§ð¨ä<”êj5/{Èõ›Qd†mŸÎ«àÆaækª™rHªCb3g­Š—è"EœÁ¬5Gtœjêê·Èã*M¬ÙnCV/­>þøQŒ&» ƒ-.3˳Ü©3ILàëºxìÉóíØgÛQçB>Ì`š{ÐÝ)”³¨‹½McwÔÆ7z®=ᇷïÐä»4ß Î ‘ž¾GwßgTZá׃ ¥Ђ¹ëR¤é%½â£§;øÎCaþh‡±_}ôQJ»›4W¦ê:œI`itvÍ¿Nˆ0K\³}oòxNH)E¡…ˆ–­ñ:Á auÌ<çwNÀDZ¾+i r”—TÃñ6dÎhã3õ‹¦Q3CEiLÕ'îÌ·š˜¯ÃŠØ°rùêxŸY•²£ðÐ}óc»¢Å\6°>¯Ñû¢ô…ZgÚ¯ŽKs?AÂ&6-6mÒ½2øâR6Ðp‡qÎmû‚߯2¢c³.P('z•“ÿ˜«eûæóÞsã…Âˬõz(˜$lZåàv¢ò¾•cçŒEF4pF{tëë†1ÙêæAc‡côÔ”IဓùƒÃ Î_€‹µY”0”mÝÉ{†cæÁ´ ¼¼ª9F«Ê ê`¸þ®2»““ÉHÅýÜL3Ç÷b8(×ó.sÛÐRM„æP^Šã¦‚ÜÊÆ1û>FB䣆Uìºêjb‰‚ç¦FE6Z®æ;ß³NS¢Ÿ?p-'£­ 3Ýåè _èOÄN QïzSñ´ññæñî†ðÌRVÔ=HCÒ¯Šü$ZœUOu:ÒÞ9&(c[*®c¡Æo¶ØÄ;Ú~¶´³[Ï’ÿUÝ£U7¸˜ç#| ŽA…wæÙŸ†ØUx'æÈñ…ÅÜéUƒUs$ŲÊk"*ƾMðñë ¿•úœú`È4!´ŸügwSÁ; …òQÞ×LJÛ„¾÷A÷2^ØÞ;ø6¨g¤õ3GÝÕ²]£µÊêEPUæL«öm¥²ì=§¿”H?¨§Lñ2w6>;š¦r”ÕÒ¡Ž¹èVÖgSÁ9PÇ}©×D£ ?{»>ìÚ Vz›ðBr3üÕ’É=?çª=²‡”Ȥ8OIÜ4]"¼ûÁ-š‘>Ðo¾`×?Œ\/þD(–æ›K|˜÷Õ‹Ê ˜Å»7?w%x{ {¨¶ÑÄÄ©Ío+¤ø£"ekŽˆ~ºLbí¤‚½­Ñ¥VtJÑØ|ší‡gûG톃w7Tªâ{ªècÕ-è¸Øû0oFäx?D ~tÊÆÔÚ@ý%fRª¯§‡¸ÙøçpVôì}ÄhÙ3áÚîàˆ^A QóÏ–€Ñõ–/ºŽ@*þcx…‚ÃíÌRzãA·6ô£¼GÛ<¯Ê>7ZŸýÑ*e;'>hÉ";b½[·pÿ¾ VÆ‘|dÀˆÀR$Ô¯[/‹o„âO¦‚N-šÍüí )9Ñ|¨S8:îð Y\Ìr/*0c²Äù»a³T¼j$}z¼,AnNâ”C/AOãÓàwM»c–P[öž©ŒÅ¯ Ÿ •tptÞ¤g|3SŒxÛ¢(.^QxÕ®B©+ ‡$:)øŒg1fHÆG†ã7ðÇry¢'Á0Á-Ú/…3‚ÛW$XZê”)»[§œ,º‡|cÒ"Øe%œ?gÍÐ>Áˆ¦L}a ,8iÓfynvé‹FÇ%Q8¡&JxŸ»7eM×¶PÁ ¿A¯õås>Ñ0éCùm@…NšY¸ð»þ]æÑ{PÍW1W蜑D%so_Û׫†M”y~9[q9@åC€Sïn¿FYuÇ _é¤'¬Ç()ƒß= „¢;q†Á2~ãÀ>0…-* Íþ$máqƒO:[4»Op€¯-›\‰–§rm½î+2ü³Ïõ£¼Á1o¶‡¤öO WË„øÓDRÓ1%S-lLž94^`n™öÏM†&LÉ>UF@hì§ó‚è^qe ¥ñE:/ôI0êŠx *j»ø¼{F99 M’ÐW”:bí|·‹xÞʣᠠö5o*‡ÀÒ¸> •ÍI cÁÙŒC)V¿µÚáPÜ®3§pìQ¹©í³x0þ@¡cßC²×ú'‡uC—b¨õ_pl®TšLl‡%…&7j7GÞd£_$ª½}¯ááÔà%n cªÉ J—¶iv-´9 ·èñÞ÷¦[ô5öØ£7’½–9q  ¬}qBBXß Öü–’(•L?¨ÚüKæìÐŒ F·g­â¶úéä%˜¾ÅB!dN³ÆàxBˆ÷/Æ]ËÙÆχhº§hÇ#2žîo|äéŠ÷ôïv8BYs.¿ùÖ¬* ®òâ6«\`ÉäÛšð_VÇCš¬2øJi–wÀ×&tåKèØ`‡]%›×kd´r>}]«àwñM[ö€L£»š~ Ã ?„1Ï»ó¹ßbAfL¶ ·½Îec+_ß!j’Ê¥Z}§ÈÀÖiD ÇÇ•ç,@¸žD7éµx8йx¾ƒÛós*‡ßU‘Q7D=xŒ cà»2îæˆÉàÈEï0ŒùâôÎ Zcǰ%M8a,Ö¯%-¿Âª:®`2}*1žê:(/`öûX']ÕØö:.-௙,„ºËPˆ”˜ƒÌ„Ëö³aoÖ‡Çwx«xc¸Ë8Ü‘¿Pº)-¢°¾çmâ›&=ñ4ì)…bjy»j©õI'¦‹JÔØ“öR¹Vº95»dæüH&â÷¨ h4¦É¸Ü„ Û”‚…dA ¸Øp¿ eï%y¾³1d–Þ– õ4¢}TuЧÃRxFÑ\_WÂåḢ™…uÅðÿÚ‡^®Á¸¸ƒ%‡¾?–š;p3æBZÿ)®š´÷J…ÎWmù˜Qíc˱SÉ]¯€F/9KÚ¹ΦÍ8£€.•‰û¾YZ‘õØÎèø±¹5JJE- ËVû´ QÜѦ,Á1!Ñ(CeàÏ…d$›!¯u‰û„¿(aº?©V+Úú‘I 3†Š:Œ”EúQSúpÂyÕ0*±GË#Ô‹dF@X¯Çu¨’lÊ%¢Ç´Ä4J¶Œèñ·­Y¶kà0;S\Lpù?£  …M`"»üµ²˜7ÞÔxeLþÖ0ò]L­xx®™ƒ«Ž™5Ùpå;B—·nŠØ±1Ò[¦oO¡‹<2®Øw…oÞÑæWûê$ÄÓmQüø:É?Ó=Á-¢Ä«B—°›é¶ZÊ{ÚŠO1ïsžC-uë¢N‘™™ú3ù'ï8]Å"X˰C1ÅÃL=g&²Sg$mbJ§¨ÉÇÌ{n]å²Þ3¼òz#.f!ÊO©½ÙÕî*)ÉyÏ?×f^ókŒá®íBbAT|%>Tu¾¤'TäÁ;hÎ#*献3æ¥ÊÙÎÞ òðdUWmÍå}Í-Ã…xp¿dÃ{èMT`­ÅX­ãú”®™ô™ás§æá²[À‚ê•¡ ÞVuOxÖp`ÅòáWôë³ÿWh„´qQ?‡ ÜXôØ8‚ }\&EyŒÂÐm)‹Ô°Õ j]JÑva¬æ;é0wÂݸ_2eJ_)ࣛöbͤr?/\¹§QŒ÷ìTÙÂZoù,–V#gíô./¨ÀÊâãel½T@^¸xê»Ïuèµ*(P¬¹pn´H¡IWSÐrê:ê÷TxÒÝ— G·W­? ÆÕc8'=š{²<ØL~A:Dj[,ãt¿m“§mŽH÷ϱ:Kä͈Ãv¯hÞœ?B;zY+Nqës›«úˆg“óñ¥ É;éu;ÇnÚ¼¼=¤Z0!dÙõ™Ð‹þ–ÙRh½~`_õö²Œ™¾Û§l~‡lWYSÇ€²"ÖæS¸á.¿ôuÅÂB*sÕBV¡ "ÝŠqµ±9sE ¥Ûv‰Ê“´- ݨÉ^D2o¢íD£ˆ»¶ MÀlLHCk’¿1tb£œÀÀÜ6¢^¥Á|÷»“·RÖr0Ò˜ˆÞºóUP Ì?KauϪ—o yÊš+Î㲌êw …#iå–¾œ{“¡$·_`ÚÖƒß4Ya½º%›ÅB$‚xâÂ\Ř}Aél+uNLBoºI32ýÝq—çÆUáÕ$½0êšP|¹ë÷s’%5QC;³!”¹±âgHªl`¥7úk<|—Ïõ&!ŒXÉ:¦n•8Ýù¥Ù ‡î¬j)DØÉ2ƒ- Ðý A¿ƒ{‰žJTuÛîi,\æÃxõ;[&"IegNj)¢¸:Ü×ï¦ÌøPçä ó¦3; îRt[_âUUøžÔMJѵHMÄ9vÖ.QÁÏ´%`:ýX‡w‡ç2¥À²µEöKZÓ^´^è/#×¾‚1zôŸ•î±q˜!ö³‘¹-`øý„Fž–òZVŸÍV&L7Jj}©… ´†Qo™û1>3į6g,ÇýÚ€y5[¸ïìÍȂթÌ,-;#j{oˆe˜f+A¯(¼G XÉ¡bmõÕø·?²ñ¹§…âMpƒß'a ÆêØ9zò‘ô3–`¬ÄÔ¡=HaNÜS‹ß’BÂëYfnæ{jõ𫯏ž#Ù‰Ì —¡&y¸¾ÿh´êS 4(Š$ ™N¸q§TËõíŠHÄoÍn€âŠç'#¸åÛ¯ï ?k]¬µ»ö>v £7qžÐt¾ù•cÜ¡±?ÉM§um¬cR¾”H¼±IÓ;ñ»_ê-Z.šL¿j¾<(mB yÃìªvç Ï·ÀH©3Aðú¥ùñG47P~™z7|ZQ” žJnèBí«Ïˆ4ëZO:ÑxǸ8ä^!€âψۥ֌ˉ,edTÚ® âêW°Úëñ{˜/u À09[MZNP¨ŽÊ:faí " Y,æS>¯ä»œ®oê1ÂGìÄÑN]p]ô|[ÈõËĶŊiuÂÛÿ<?ÅH.$S†3óœ‡#’ƒ‡žõ¤2ýA 3@6>Δ$µj-ý+‡/Ö…ñ}’d•éÞcƒ³Lã°ïøžô†l>ï…¢zí£Pµ%ÑiNꈛ`~.vêëu‚ÕÊt—~6·˜€si‹®Zm9kÙ½6Yb¤LH%î6<žìI©—>õFuþç m[ù^÷bRTÖ-ì8s™ÐuƒnfíEÇêGt§Ðâáu,¬é?9Y|+r?ãÇó7S–{ƒ¿ÓglæåŸè«¸µtžPOL‰ÑÉfâí™'a…?ÊE(ŠèɳpËÙQ>§èŸebF9SÅàãaâ Ñ’iêÓav{Ÿ vjh@döÙsîI ÞàΛĶ6€6Ý¿à‘MüK¼.ž!WýþÙƒ^nªÆæ|´¿¥€!0Ðð‹j€¥kȵñ6\äÐDD‡òLU7š» rÊ(oøƒÅW«:¢D‹»£"\Ú[™öjø‚ŒZ«m¶gÍÝkÄÒàš´†åÕ¸&d—«µ6–¾"Ÿ%µoö>Ɉ^fßÍ7¶®Áˆ§dÛÝ~ð/c$¹ÕØÏ,ËVvóÿɹ7ýˆæL”Ñ~#ôùT/Á 3“æÑñ“)U'K†qÚ+˜¾¨¯JËŒ½í]ûOLfDå\ »·ÊA->—L“¯i¾ÈEK˜·5‘æþ?L?!@²5„šÜ×TÒ™A#ˆ©­í6Ã`N/§ÛlG­ÂYPaRÂHELB³!e“\¼N¥R6©åàhÙ^'_kõýü ÞÏ;"GÚ†izNßuN]¥Á¼u·‹Ä“±*‡A"îDá’Àúi W/‚rô5# –R¡¶Lù²Œã.ó _žu0ù–J_zŸ=L˜Çb‰x¡ýH´-YO‘á4ïÚ`-²Pì/ÝÞh2 xž’!K/aGÓô±q§šõ‘÷ÖWrOjyKgævqµÑ"¥c:0¶]#ë0íFW‹¹õ(/½Èñ”Ék;/Âczp6XSH xY;¯Ì6‚1²DÄ´D&f³5G‚•Äøn†Q²®ûéR¾‘m·Ú¬Ö&ü²ºå•33‹¯NšfJD¿Ô¾¯;èäˆëÝ…êÑa|+H#*çÁì­ä¦pe*L\šçäUçìx¿lA¸&dÀ®ÑùÞ+¤´úÉÀßÞºò²3•÷êÍÓ3 ùj²7ðs³@){çÔWMo 7VAÛTE^\àçÞ¯MÒ={Ù¹§‡…ÁP×%/öm0bx"Ì«¸ï’·¾Lûâ¡…{9¸GÛ)à&1”^¦„ž:[ëlfé9Í,SkMn,9 ÛÍ\òáwJ£^>)„ ,-*h‹Ô!åñ°¦¹`~^9 Ái¸×#×m« P ¥å øî{šnJhKB+¥Huiæ¥ÚËë+t8H V„@Ýý÷»­±& fú[£%˜Ö¼„+Ÿ7¬£Âåþúº‹haÍGT:^÷_ÆŠ¹¿drŽORœ<ýjÄù crs9BŒÛj¤¶'Ù©LüÂý¾ÞðP¥î˜r å=ÆÅ0‚€:vÖrÂOáãCÙ)qˆmÂCåÃcJò‡Uû!Ÿ¦—tІƒ2Ff-µq“;'úºžÇQ™ø4v›,„!vÁØTsÁɶ|‰b;>ãÀÁóÛôŸ•¹ºíÀ[lL<Ò[¼Á¥™‚+M÷h{+Öj“ÜOÆYJúÃxŸg‘‰Ÿ"ë÷Hó'ä©Ö‚`³>êèöió©i:à.¨ GõX²¶ËH?êEPt`“¿1ÄZ'¡¼‚‡IbB&|Y˜¢oÍ€8 âC>H¬ØNÖ+s“ØS…\ñ½ç›?Æ×º|8˜‚&ùŽ$ï8N¥t/_Ð[¨?Þ~wòÈÀó‹ø˜™ZeBǺäs¼Œ¶ú4úé]²ùÜèg¿Ú@aìÍô÷w‹Âê§Êl·Íœ¯±Äö%oùly«âZÕ¥ßݽ뇛»íÒx.º™yè=GñJ×BaÇ·ˆ—L˜ßgÞøÛhÈ¡v‰íëŒoA¢¿þü>£-üUªƒL¤EB/M¨Å†ÑôŠçíîiþL¾ôâkdæ ™m$´;Fës™/2[8¥Z¢ª-²ê”=›xçÑ»k¬ÌAd¿¡¸m¥1Þe€FÅÿñ/7åŽC¤„^¢ü‚*pkW^Èwè¥ü+è#uÄò¸Ú¥¯s³.–=øÇ ÅckÉšk]ž½Ü..ûq‘o˺ý¨V’˜Y“/-ôf†‹ .Žõ“bî™}.šèàE†óù–ý»TédpC'—ĵŠA†*K$ÎÍÏ6AÃË÷Æ:Ȭ’Ñ‚ Ñ@¦Ãd@”:ñ]Ö‘½’þxÄõæ±ì±*æÝ|où¯JWhNºóåUªwÆÃDSaŽØi¡™‹Ò˜WŽ]¤Õ¯àäʰi³©ôDÅ29Wí3'ã˜)×q:å'BpƒLFSî áýœ–?â-gQ.Å,"‹zj*;“ÁO$v°…P"„!H“z{¨óÙtbÇŸ>¦¾ûÜ™Gx”eú¶—­3h™µ´¤Ç%.LâÆ(üO(uª÷uT~óé:Ü…×È¡xÁaj 2š.§»44Ió¼Ðѵ1Iu륺'Õ’Zn`dî‹Bþ`›Î…f`xu Þo–öjMó é÷È13ˆ¦[ê⃲$þ\з3å'6^:Zo“žKÍ[¥\‘ÍñX¹<·Ôš¾F1†ÿƒœRF'ŠVîøI_/4vë¸{„œ—¹DÀ¨­™tÉ‘ÅDˆä9–9Ñdë·îâ™ìµùÄ¢#í3¾¸.*Œ°º3<9 êv©rã£X‚æ’R’þh­uïÆ ×Üåc,<”ôv°­£Ý0K[‰dìÊsö„þŒ]×Þæ®cõ؉·ÒçrÁxã+¶ºù›`Ùw1©ü|¦Œ-þþñ-/NYn‹ƒž:g1Û¤ÌßT·RU[ûÎî§üoúèÛL1§‹`µÀù¼6Þ+ÑðF“2Q©¤‰yÍÀ¥ßqˆX„TDº&À…ÝBáw”/·0„˜‘õFu hØžK¹Ö“½å†´G‰yl2Ф_ü"ÆoTp5AúòBàwd:öÝÎeó¨rŠÂ_@2-Sh„¼Áæ_øÑ>§‹5ž(ò¤n1Žáæ^K´âÖò}H¸me¾PËôÚ2*Ü«CÈüY±0Wh¶¼Œ=ÅŠU5÷†˜Ê-4-ígßûÅ6×Q8-LüqºÄQǒ;,-»vš4oçc.O#‚¡&jN­•ÍPÍz,Õ\Ý‚VüÓür[é; ´ºò5e,ÖÍŒÝ÷œu1ZG0¸u^gÌ…Y“’ÏÌ‚? zF;x|Ò¼…nÔnºIŽ•}?åå}„úÕ—·êëëí‰@Ü™>²â®1ý±OÒèD¨â­ëŽAÜ}R¨Û¹7{A~ æx=ÆPª–4~µérQYUáÈÕv‚ýÒn¼ 927mmd=8㧆«! òî£ÕCqˆ½ÅÌ÷ ûXP<ØGçÜ|Ó{ª9”ôPD#i§ÞŸºÓæGxk[%€7‚G,@8ãÉóúøñÛÛï÷šÈ¯7úg¹¿CR8W ‡|ó]dkFsÁغUŸ6¯‹[9øŠy:âQ‹<¬yzt ¨œë]”5ùhÉK%lÐÿ4­>¿Ñpl¡Ö(k”§5`âÓ¢½| ßÎÊy_í>È@­&ç–´táÑpBP¼G¥U«òBÂu§fÛûÓ!räVÁŽûU¿z3G¤×wƒ²þGñ²ŠëÅ׸{£«1œd¬YÅYã"ðø Aa{³$•ÏË“„«DsÙõá¼’?üŒ|Üvº1ÚH²&¨ôiãÏ/ !¾mS™½.iÇsÃÄŽ:KÖ?•£<ýD;@ªž0òsKœnæÞÎHò'xµi*åwÁ‹pÇ Ðx¢ó?û0M<ûEØ£¾lÔþuk¸ˆ¾åa®.DiÜÏ%3›2[cÀ⌫[±¹œ)Aœ]X®ï+þKŒqÒOCÿf§ ßüi)Ià1-ÿPCD*^OVË9àdºdÁÚ<›ý}‘*¦WåošašgÔ¡bÚ‹£×ÔÅð1zÞ+~I]Kկě¡qîí¼ÒGƒHç…•ß|Õóú.²éx±<Ájð«é¹öU4à`(1½Âoʼ^$nÕÜv¹¤L§8|¸LfýŽ7ÅÞ©ºÐoÜ XâÑl)sË*ƒžÌ£èn©p™\LhÁšN#­Cÿ*=‰‹Ùõ¡u¦1¸ïLš;§C`Bn‘”ˆÉH¥¨ö+GkxMgâÏsƒ–¦0{º í<ßG¦èÁ@}¬…¸[f‰n‡²ìp„5Çõ¦^ÌÙ`…¡¬éØ €÷@^p"í5´q6£qðîý{û7+Ÿ@1ÁVÜêûR\“ÇÔä_úµ0}K%^<¡¬£ð±Ñæ wØ“…†â·¾tòTø|­$L«¿%A/jë»1§ÕÇ[Ó Äà½(˜|ý•ŽÜd´8g$åœÂF¿’vS¹¯=þ*‡W2™]9}%8±s¹¡ãs‹’ ÿBøôT„”öa½»©±2½úSoÚ›ôSSÀæ÷êÔ‰³™R­„ÜLVÑ”ÐVEh~jH¤ÏVÎr"=úØ֨ノõñ9È©ïu×¥XWÎH»!46Tø'¸ÉZž± >éÜfúrÝV½Æg©>bSwtß\ö$ÏÈq Í­]î?ÄØ7ñ¹ ߯öex–Í<‰ZÁ“À!sø~uœx§òÄîýdæw;'×œ×Æ]˜‰8‘›±×Ø$y¯å7`¦…}}Í¥ÑShªJIY˜bʇ4 ‡¿|½‹O) ¸ÂO*¹7‹`;Ó´RÛˆÙ8Dðm±8ÂÕ#í XRØv!þì,Y¾ä¹Œ7Xä…½¹u þ®—¹lÕ^ü]'SчùÖMŒ«tTšu+ TNrO,°‡ÏV#C¢ {,h…}+”UT£»¨q´-7{èRk“R¯&±uÅóŸ`ç˜nnã¹HBÀýZ¨­´•¡è¸HÝÏŒrñÚ~ ©YÌÌ‚ú&Z­ØØeÕ娩Sùa“`o Rð|øî3m­älTOWø¹Y\<óµ[¤ð™[ÏRÐÙ¿ØÛô½“6Õçç´_58Z^eÆß§BÑ}ÔLÉ ­çôýVVLxø”aÖx† f,ÅDt.ã³}WM¼Ò¸=ʉ4ëJ€ŽG´ä6'ØÿÁCmÚ¡×\¨q=ŸÇû+j\k &‰í4TLHQêË2)‰×XZ$bñžßO÷,þ[7Ú‹ý Âùz[)éÝŽû_I넆ÜÁ{KU ÍÄÙo ¯ù)+L~Ê0c9XɇyÔˆŸmÍû(/'?£9—1«ì{Ÿêuêñî!ղޒÀO÷².û vs½X_ùJÄùã{pwú‚bmnC!QY=\ESÆ4ùÖcU8´3Eì{MªðŠÝ©jq²§“ÇbŽg¶´a>#aÎ_Î(=ITs×!í?üú5c‰žÓý¨×Ë”)ðAÝ,VèG+“óV¢÷zìbÛ°VàI÷#i0Í©JŒ Âwü[Â?¸ ´½–p?­ÒïÆy: A¤Ï fD¬Að®¬"z~ˆ5 3 ÞÎ8„ßN_n]±Éx Æûq¹{$Q,*,ÆN{Ç?´Ïö)ˆ›ðºt˜o|ÓË•4}ñ£Ñ=êBQ‘—€úGÎgîUìÂôMr ²<ßaé°ä8´nŒ>s™ v›6¡X—ò6^ë[‡‘¤[ÿGÊ}_V»*}M•¢¦½_ŲºzÞöE­Ÿç´· Úþy1x­“C€—¬BÌÛSËÓÔAÊøè[æ\•$æw‹JwEq`:VÂG ïÄ”Æå§Ÿ„àMï%Î$raŠÞB¦ŠÐ¾ä£¨¹T%áãQ;x·S|PüPŠVzQ;Ýùë[!ê3ã",VÏ.ï‘bg6Ø2Ž6-sNêÜ•†À=½¢BÛ3ÅV•ÓGæ‡~jsMþÜX¹¥G/¥åXW¾3w%erÏ‹³L˜¬Š| øG×(hMÉUõ¶šªÊ©ã/ò O“Ž€0uA¨Ïàêp^Ë6ð]C(Ò"ñŠ˜é×ï8ÈEç@$lñZŸ±†(»x+ñqDoÁF`SÝî,<¯%‘ÉÎk+œßM³ÄíúÕö² WH¿äøåäÓ°Å–g²iì:)Û¡p Íݱ•ÖÿÒœ+ïeïÌ»™M·±'—«Œ„ú!èfx ½ûE›èLi¤,@y'ãºP×<Ú±À Övéq| ÞÇε§–"ôìÙ¸ Ò×Íœ’³’•6šÄ^]Çs ©¦¹Ï ~0¿cffÖ;ØÛuÖ‚Q)%Iì˙ݰfëOÌyòN"ðþ·›::—(}9êÁÅÞ‹wmA/'+ õ¥Îþ†Laîc¼£ï¨Ö]àõ ™¢‘&t¼]ïÒ¢§O•Jj§]è0äyu ñÌÛz©ÖIñný˜šJ žZƒúCÁ§dÉs/~“–?0qD[•=Ø,H’¿qùóì$*Cÿ"gÅ ä„0²Æ)×`Ï+½F b縡[à¬T¤BC\­û–ƒE32ñ ¦µ ÁŸõÿŒså(s÷àÚT.¸Ãî…iêÌ_ „NÉBø•>¥÷8º(û •³…ɳjuÊ‹U_=o1#UX·Îó@̽qº^ÿ¡x>!rü †`Lˆ;Í­Ûnõ$'à·œöWj©8°¦aV”Ѩ7AÔòXÀk¬ ¸­#ß ‚ÌH­pªÞ&vÊÄ`1¸Üž ®IÓþ{Gð´Å¾6)~¥Ûl·9ã8 ©Õ“F,ùÃÒ(¼÷韓ýllXÈNlÞ©îé´un°“ýcÀ!“%èÊuKŠ 2Kç)RÓ²lß“¶$Ù¶Ô– ¿¿r¼Nf¹B¿_tÜ:$åÀ#JÈaŠ›[f§ç¯d5) ²xÚOëÚ“ý|Ñ5©¸ß +‹loçxL‘:"—™öeo{¸æsyüFR­öQyªÏw@’f`o¡ ¸>+:®Ùºƒª„ßÕÍy¥ßP£Zpuà§:žÇ{YT @z5­Õî!Ÿßÿe^Lý«~½ñÙ~±?#%ðX2ŒQS!Opˆ‘\ù÷"R f-¡[UÓ=¡û©yÿ{«±«!¬•†IªÕ %Nm)ŒR—TlhnÁ–VyhõúÙÞQ> m£˜úœ’5§ÕPM|zÖH¶~ã#†Ìý-C(>Ü«aë dÁÓšx¹nùß`ج­+Ù ôd:ÝÊ“AHdP­p‰*u¬ê‡H˜¡„ʃ—µ¡`dvDåvVŸÏÊ]ÏÛ€Û–ûÑæ²BÌ0 ¶±5LŠ.¬ãuÛ>ŽšÛ%¼{¨u¾ùÙYΞ•¸ ~‰ºõ#,?<˜ȾšMU’x^ùTà NiRC36•äîœYå¥4òÏ3AMî.Á¹Ÿ6ú&Õæ­ÏQ¥Š\© Ÿ½[)‰á ÁO"^§CùÉ…‡vŒ(äñ|0›‰„Žä¢¢y4ƒFǼ2lO·ŠBÎPÄð7öó}—…ÉK~ŽBk¢8t6•è‚о@ø"ºÌ“9Öö -duã:…‚¨Éyæ–ÌÅyˆÓ·%áfYìÄ4NrÛ·M¯ý~e8(€iÖ(ÖÆC+=³3¡1ꉊƒ•“‰Ó¼5@®ÅÒ&u¶ÙSMº‚ðÇÍJ·Ìàáb‰j‰ÃýNÛ•R¾,Ut}zó_*öÀâV~ó*­–$z9Mu½Al½–Øp]Vs’™–K˜/ÈX›®Ùi71•cõêÁò¼x^éJæ;—ðãB¡°¥PT³»Äê@5Ör ¬a¦RòÛ ìž'€b(ؼ]K_9&ÍGøÍ?ËÐ̆o·çò¹!hRhFևѻ—ºÆ­JÒÓ'ß~µ‘—­dòç#áN-Fò± H …/ì}æLÚ]WC1kɯþ¢sO¶jFŨVŽ›øY³õó§j7Θ!ý.ÓúâQýD¯eÒÖxh`¡\´2I5ôtíËb Ýq«ô„Zù‘U2pNYV%Ýt¬ªDþñèõH`WÉšÒ6?i®Û´,Üäïfê°îª?c3nk<‹6: —'U‰˜yC*ÒJa¾<÷shžÔPi´6­Ž”zòZúœ’D>k§]B7ªE°p®ð’{2¡x£Z%ˆ>ߊx¨a.]?a}°˜¸…G¬5/ç€rS?‰Ì:i¾H0Z}ÓžrŒk¤‚ªa™±…I–»ÞPx´PØŽ T{TÇF–B¡ÐÔdTo_íRæ7…9ÆJ`©-¯ÚOy ºjйÄ„¡‰.y©Jð³Âmêü$ÿÏ?rÝlÀŠ(8aÕÎ^8®(„#¿ÕúWᜇËüâÏâÛ¨ìgH ðÄS„‹ñŒf;=•9•Èþ? Å=ñé+ѵ3ÕTcD^m÷Ų‘¯NlQ'Iðá‹ùœ‡rY]“ä +]%Åh¦ŸŸþÖû1§ÒÎR&Uà Ý).L»ð=æÂûÝ€PûÝ•+™…÷â$£ÄK>"(H¨‹I‚v¿{nE´øgJo¢pñKIDòww:±0ØJ¹aŠL§{Ç"ú`a#¤´sñÞ8Ú{×Þ²@‰=R>·‡>"´aš¤3œònA™UDU3UÉ¡ge0ôÀò-æÉ$=,ª¥«öz¾ã¦ñùÇ-k´?í·ÈÇ+BÝ™@ßNÏg)aã›P°wßÐÝûW™Ð~§c¢ =CŽÓ =¦ªqÖÌoðS´HêÒÓ/¡™œ¸Ž¦FÇd½ ˆ£ï Zþ}õö9”)E$]4–\”g›À ¸ÀÔ¶Jg™ÈDž—á< ª«nÒÚ3Â-K e8ó’f:FR|ÚÊ6ÄK”0½§ë¢¡Ä§¥pA ,½êeBªÙÜcWM™€¿/m> ŒŸya9/²,O†€އÄùqª€Ð‹w¤ ¹rçB™âU× 6¶©dܶn¬eãÛÊV0ø(€tNÚ3tÍ4$Càh‰ ³ô|ßJ¶’$R‰Gæ’¿g U÷ŽašmKèœM=ÜѰOJ¢>/t Š‚g$iÓ£hÌ^•ñüÞöL‘R\À(DUJÞ³{ì4Å•Tµû£¡ÅúdO.å<Þ›jÊÚò•WN¾Öv Á'÷k Ÿ>Ωý¼‚Dô¸ÝÜê7äŒ]£'qâÑŽÚå¢7g[ðŸ¨w‰º˜O\_D¯ªyݺ©# ;,ÖT¬¨¥óR²L›90i{•}ƒCÈ@ÍoØÍœø®é%1¿%Žô„<9íÖMYý”æ˜Ð¦P§{š0Üc+¿sÒœv(ÖV(ÿ‚Ξ|KÒ<³K'K?rÝ„iž×À ÊÃâ£Üö6k¼Ò·øÎýÀú*^w±ÞWÜÉ-mµ»·½\©„q ÌöHˆÐž°ÅO“¬Ê›CQBx=«ºkž˜AŠ c½¦RÉô%ÀH®ÁÉ)ý«7_;Gì5–¦Z“g­@ñÚß6ÆIÓ•W玛LöLÍo\ž3JÕ»]&•¬_÷£³,÷ÄDT8‹§QjçÒép:ü'²|1W1Kµ¨ÒMë{ „R‹™·Ï;—îAËZHµì%ÐgÅ9î¡S«vmôÏ2ž8Ï–<&¿‹‘ïŸ —–ßÃî|íHÓ¯N­'õ|ÀøRÖ5O©´@ƒ~‚ΑQï*JþO£!•L[†ïzãЪ1暨SFlqå°á!«²“ ¤1‚r w¥)-ÍL0è’ŒÛu¦ü“oàv©« šðAfâhQïó–JÚ„6p4óÊU¾]‘ÿºJ#+hø’ª‰÷HÝ s¯Ýø5áô(ÛçNpBvcJ.ncs)ïÙ%g¸³Cn1ÉëN¥çnPÑ!þqÁ•„w~l¥©!µ TÍ?r]€60ɱý*ž”âÝ™ÏM­i†•w«†xÔ ;Xاö]›¤žGÂr\õ<÷ê,Λ˜á8jK!àŽãFœ±eMÇ3“|ÃˆÂÆ‘Eøò ¾%jìþsÐc–|Bâ~–eUÛÈ`Ô+°>í|Ö^bÀ“ m†*±õظ[‘•YX'>h¥r¤Öß²£‰0œÔ*“ؼ‚¢v§?·ÆX ¾ÏMkë”®±ã8̆Ѕl©L—±Þ©õàÎ×O`Öv= "l8õªq]ßop4ÐêO·4vO‡k·eèäNz£›UA ™mX­  øþ… |1“÷tǪÅÂYè©ð´íW:'U¼srÑÀ§Ò0 ÅÆSçÜF¬uä6SjŸøýÇ8zOx“ýÞãÆ>¿Ý¨"Ší½Ô}PmÍc?øZ¸3[ãr%þÝJzŒE•ú‘»N2ìñE]¼>/*ÃíQ£³i1w¬²}§’]˜$ô»0êgõ©Æ¦E°<ŒsCH<¹±ä¬\û,ŸoÁã{û ý}ÌNX0J¬-šÒŠgçŠD»ôn ù6`½»HŸµÅ¿Ò$g㷷뙟ñ#ö~ñ˜pÎÁª"Ež«:Ró2Wûý òñ †s£í=‘¬ä±$ êÓRçØN'åíûÎÁ&Ír*­¦Û‡2vK’G0÷è÷|*D†]—î¹ïÔ«|A^>M6F1$ß÷¬½ãà?pc‰m;W‹&êX¿Ôm•W¹q«3Xn5x’¬JsïèäøPŠ> Ìމ”@"ßàÙÓÄÖ½Î^=:™íi†Ü¬yÛ NA ™céwòPç»õÑI‚Ùtßh*ÅNAjÃÞûˆM¤5I©0Sƒ>NÇ aDOŒ‡m#/Íý¶70¹ÀåjUᎠ;§S#:ä&ÜV4ì½ 8ÝÅ]‰†D´Jä„Fzutåù¹Õ-„0NÒw>&2«EŸ€> íÃÚÊ+«-c–wÆÆí?À±¯‘ð$˜)7¦°¥£›8RtÈ6 ¥ ‹».øBçDÖòXñ/ïeAT˜Yt6DžàùD[L€gŽx‡2§ •|â=9¶ì 6‘ý Zò VÎB™€Pâ<1e %¼>§|%+6€=ý‡•E:/ùiíO’NO‚¼6ѱ» yf¡n™'å¼€r­ÆæÑWè]œEœfRfj­¼/£©©µÒ |v¶$ žÚR±¼ò™Žl1†‚iP»ÆC\Y%  r)pµ` |¨´\Uḟv¶|fn%I8¿jDpjüÀ’t§ÿÐ’i~“¼–Š?xÈ`O°: ó”ášR¾ëDN£;¢/‡=VaÊ:ºê{ËNEŸ_æÛuüï›°÷Fe¤_ ¯%©±¼—7ÝÛ”%Þ] C§¡H¼Úß Ïõ…øT¬}Tõœ]”X‹²t`<3W+b>>Ý{LŸ]âUKzQÝÀ‹ß9Píýlê ÐdqD+)ëÎ_J¨!À9™“ŸülÅ»‡ey~Å7âiL«ð£Ó¦ë¼;îGÄ3n„´Y~ÛŠ6‘r¯Ã&jþÕ¯šî9Ü”R°*ÕƒCÖ¢×ør[—z†‚t”hòŠÚy‚/½6hFÄ«±JªdØk˜[¹†‰ûŽèé ˾sAU…#S€r*Ö6!4˜؆ríãÂb¢[-Å꬜™jgÐFIžGL›ÀGb*@¡ 7žS±¢&'&°0?3*Ü×ãéuC„ –Ü¡À9Ù u¬õ¬%C’fóïiÂΛáCƒT+ŸeÍ+× #“lb/4CSÙ^yÑM±îôÀ R/l³¿µ  Ë¢†6°ŸP„¯nÐE¿û9'_÷Ø×˜1!ÂJåÌ{Ø·}ˆÊB\ª¯È¶$P”„Ñ•&¢ 6Í[„m„¬àiwÛTTOíYkÉ+Ü®ÁÚ3îtÝ­Þ«aalÂ%ĸô9&QÕ1>½Fš¸ò°¥ú[ŠiOí±åé1[Jü’Æüýãב*‡µ¦â‹¬w8ún‹áFÔH°|ôµj÷}QÕ›5Àº(ÈÛºŽ¨ŸR‡Û”]‰‰¸N sÈ„Q«3P){Þý&ÇHÃ!C±° GvEÍ©w¿àIÚŒJ+ ¡]Άkéªixî¦Îë·åkØaMylÛOÁ/zŽ˜ sRæ,LEßë#‘»5Í/&€­„Ââ Ÿs¢"Köd˜ÔƒY¶m†lÓmžqO@¹³òž‚Sw[*z„[f-Êâ:Y@zQÕÄš½°‚úQ4;E-,Ÿgå£X âÕ¯Ew3 Àç®ÌR\ç]ÔÿbU+Ì{~-kI#Ùóžmyò‚ˆvçai‘UÊü»3õ _‡‡vH7¦e)Ë© ¸¢»"¯¾áäpuF4¿ˆD‘%™hc«~N_qÁíÇ ž`±ùëDóU‰^&½›á¶¤¿ É ˆZvIà¶?Î0‚ÿˆVdåîÉ.†³˜åœ&îQ>­»ž(æhΫ‡QZ ‡¤öãVÕȵœ:'¨„»\b.œXTÇ=kê]𗩬hIšgÔÀ$Qb7^±†ƒ0šJôþ™UˆlDOƒ6ί*µÍ¼z›>-û­õŒR$®A”ù ˜llLË¿7ToMð‘ùAž^Š`hŠQðLP¨¦€7žt#q„ñ‚ß7ð¿Ñ=þ¤t®¤‡5Ö”/þ²P)KáS¬#¥ß†˜ÁÉ X"?’÷4ms|=_›…àFO²½â‰*7òT*ÂA“o-*6H[÷+PÞ·N ’*L]Èa˜®‹IŽ´Š÷ðƒÇ6;!ºÞ^Z²bŸA-Í .ízø4¨«Oï6EÒi>ë'a£“éí¦Ž›;FQ¹Ï…½W§²rЃ|u䜑¥3$½›Õ<8eÈXáu$r²…›2éÚ‚Ïa4Hô!ËéÕ@ß#¦St™F îx- ýõúž¦°µl½Õ®p¤*à4˜X©µXó®|Kôß/°úÜ6‡òO xàEÙ«g– jøUI¡éÓ ¢^Y\ú£é2€g†Xk¥AšA£ˆ—6¥Á]µø§ó!?.0å?(Rc¼P"'¹HœIÎÖõ—Óÿ'qF¢ž–s|w;ºÎ¡·D×TÚD²ËºŠ§¯X躺é‡..–&ê;&éŠ&XÕsþ*ñåî¾,±:ƒy‰ÝýýªÝLðV5†¼L˜€ª:þ‹¾ê¨‘PÕ¯¾“Æc•nÆ8\¦Eä&°­Ò¸¡gžªJ™в·P†éˆz hŒ¨"ÂIÆÓZöÀóö°ä^Kãâ|”–ùÊèq0 ÷U3c.¬0rÞOæçjòõÁ‘ªÁ”´ú(r»õ ãÄ£Û8Hì’®Nh¤“U¤ bhL;¸Ïxdu«M¨Žc•ÈÕ‡[DSâÓm ”hÆ)Þ^8ZÛˆB/+J¶½êTAoÍí°ì¨À8´ > stream xÚ}’{Ÿ÷³ÿy¾¿µž½Öú­gÑBšÁ‘…Ã.(#@$[€AÂ`  ’ò¢E+x0CPŽ3ƒmD&B–D2‰D LF¶²ÍS–æçÉ`„NeÈ–€l½t©2™XÁp(ÂQ&Npç„ ²šÑY|î·Øv˜!+LeEÍ€¬$ å°# ‘Ýã³Ùká00iì_qF8ÂŽüþ0†SO˜…ðÃŒºc 6Ât䄲a@š‘D³hÆ ÏÈë8,˜ÇF80 @¦LˆDú!æ†0·ràˆ@ýZƒbSÖœß×!e3.®4Ãeî}û#‚ s0`óYðŒ@þ*ÀÖ>Èüvèéêèâ¹Áü맃+9L”…pB™j<#R™ QÁ ²æ…ʦ%ZpPLvpùX4AyÊSkZj ˆŒ)iš¦†&²¾C2 †|‡T@Dþ‡,™óB€ˆ~‡–€È›ÆNCc Ì7’ûßL7ÍÐ û`¯?¹žke[µQT‚nïúeîS¹ô=ìßúF'v•ŸøÕŠcÍõ½-ø@çZÀä)Õ:¥ glsõXíßt—(.Z}=kqI `¯|¥Ë󺂙T åÉM®`ð×=°a¼2/L©}Âë|¡š' \½w[ÅeiÙ^M‹û¢ÔFÞ¦AA’t±³ú¹%m6º»)©º%f÷ŸuH–¬–_ß[´j-…~Ì.¤sôQ–Õ§˜Jçë„M£»&-ßµ²ÏK\oÆgŒ.O&uEj—uë.¸E´°Ã(~ï¨mŸœà¶í ·t{¦Õ¯§ç£-ªÏÞÅD¥óœuKµD]»°¼¨íÆ‘L³}qcg;Æu. -ÔÆUwÄŽ¨Ž‰âo]ö©òOÌÓdåílR½nÂs„+çqFn¿ÓÁ–×Lø”öcý¯ vúôlS,™0XÛ;QE}ƒ7OUô~Š÷rHKl›Œ ²èÉ2̹ظ2·Î0ôÍ]o¤®¦^Á?QÝÿL4?=2X™ý).H*:‚;¦&1ª(îNLê2ã^™'Êõ±j¿Ý:c¬ÛeÒ»Î+øÌÞ?¬yÉÝÚúŽ"Þ;hæ´…žø½­1+ußǽCPà˜æo/¡ýaž9ßñ‹tM¦³ƒ·ÍnZ´Oƒ{`KÎ%œ¡úì#ŠGNDF¥ØKHŠôʃ<»qC×ôà ðsºîØŠ.K´©5:nŒ7”=z½-^|gP®ßÄ×ULSq_Ï8ì^¸ =dî[\éñ"ø~‚aÆyA3¬,Ÿ»H~îÏš™ e½ã*nþj:˜xÅô “U”–¶[Ë)w…⚪9®ubúU”ý(§IÆìÑ=Å^ò=ŠðªÅMÕÎö’C¹µ»"åô/¼÷\³iÀÔ:²úNš4º°/¤Oꌪǽí઎IL2NÅí*f‰J¯F÷åï¬þ9/~Îý-hm‰tÏÂþé²/+@˜åóŠt凎wÚv'3êS{v|–Ag¾›$.}ѾrÇãÔå/¯yžõ|ñæ<-®÷Í|ÏÁ¤ ‡’³¨üþÃÍ“»O<Ð××ʾžpƒnrëU±†0¥ÏE—4æÎfÞì-át¨)I ¢oNJÕ[R·îh©Ô›0§ÑŽ7‡½â{àh¾éç2Š—zµ‡©mz}ãB:œ@ìRZ[´±%îí„Oâà½Ææ¬Lúq©ßÓ¶¢×ŠˆÁv Æ>þ¿·›’Š›åÅY‘ãŠé~¶ŸmŽ®ÂuÓCâOô¬§Å¿„S’r÷ØtDäjÄx ®`s‚Ú— 8¹{ ¿Ý­©…ÕqÊûë#º‰}+aK&h^jhÕP9žãœæèó­¶Ö¾>„zRáÑ{U©_ÓÐ Ç~!®ÌRÜjLÌé´³*o¾Öp2Â=êj]¢6_g²ÌØBMµ½s««Å[Ü"JÝ~`ÕˆºD'©2x”ßú¯‘Ö’m=¬`ëôànÙýÔ×ܵuEU,ÑÉ"]ýÍrïk1ûßS{s;¬ìSž ¥˜YAñÇ(õ â¬Ûöeu*w6 V‡Ö½3üãîi¾ ã‘Ê\Âå-Úø§&ûpçí_Þh§ÔXSz¸=ÅîŽÁ|<„êü8‹ÇþûЕ÷¢kôi44bµZµ”†A®Ë§ú‚\뙲_à Â)*iQ¯?:׬2ZòKû½žR®]]~NŸ)=NŽFžé^¤y²\peü¶e-éÕýùý¾RáîÒ¦‰Úï+’¾œ |.Ç2éÍ…››Yܦ6s%ú endstream endobj 241 0 obj << /Length1 1647 /Length2 6610 /Length3 0 /Length 7551 /Filter /FlateDecode >> stream xÚ}”uX”k·Æé.é¤AjHAºS:u`‰aèFRJ é––”.$¤C@$D‘.9ãÞßÞx¾s]çšÞßZëyîu¯÷Å΢«Ï'[C•áÎH>A~IRÐ ‰ó °³+  `$ î¬FB%‚B@A €€ŒD‘$êAW Uf¤åî¶û]! $!@`6H€5ÔæLü}¿š³- (úwâîòOΊpC‰¸P¢Ü”$îìè €@mQçܵÁNP×_}ýŸ4Ø æèýÿCavöH—swúï¬ì³‘s¶s„þÁÜ”a^Pˆ. ic@"Ü¡‡ !P„#̪ wƒý €OP@à¿rö0g¨›ôŸ”6 ³Aõfô‹(‡÷*ºšÿÝÔ 5»î»Ù@‘ñý; ôŸÔòßc@M÷¯!•t©khðþýÿÊ)9ÛÀ!0g;€HF ÀÞA¾‚ªw/Ô eÈï G¢Ž\Ü‘þ[8‚à÷;€r¿C“((Kb Â-‰€Š·$jæ_•oIT¹%aPí–D@õ[B©kÜJ]ó–PêZ·„R×¾%”ºÎ¿$.>º%”žþ-¡ô n ¥gxK¨[Lÿ% ”ø–PzÖ·„ª´ù—@¨œ Üõ¾ÿ‰ˆˆüŽ89Ýžÿýõ! j&ÐÛéý&Ww°ã(¶·(¶0Û ßi¸;â(MûÛPÎì½]ì¡ÎT b°?eÐáD¹øSeÑéQíß^%ŒºÉÙÝÉú÷gn÷‡‚ Êü¶ÔpgèiTÓ.·iÔëu"`ð?Æ"ˆòéz+ƒ²äêGB!Öt&ˆŠþá[Õ‹Ûí\~ÔãÛ T¹ÌëVeÛÍìfÿǨN·P&öèÃF™GzÂÿ8€ºÃýök@iºÿ^ n6pÄŸvQõøQãð¼EÔÆzý(UïÛ&QG} ˆ¿%ÿ÷Ÿ_ sFx»ü»Â~oƒ¿XðoÖG"àPciÿg‰‰€y™ ð  ¾=ß¿ž,ÿïv‘—‡{ùòP[õ÷¡êÄ…„üÿW;ZSmwÔŠú‡ma¨å …zAmægà6R¡OëBÛÎjä<ù6FpVV;¢^˜öG‚³¹¾öš¸*®òO •´ÃiºseágüxöÏF½,º³‚—SUshJýkò?øòÏ»í L8½Ý˜XZÔÚï zŒ¤O̱Ì9“Œg®ÂÄz„·ª6 ¯;ܶÌ$vN€â2–Td¬Ü«Ž]ŒhS¶Uä©Y9Â<ÝÝ@Ípì#TŒõZr'yÌ"\TrÈ2¬ Î×@G±Œö*ÈQfûð×àjw ‡\çx ËóÔ¹6æ® D>ëG®«Š¦ÆÃš‰'}Àèæþet@±‘Ïê0à—ÈÑŒca†ÊÛç¹Çæ²É«>|#ÖxLÛüRHa£#Ðü•<ô‹äBìÜÓµÄêFF}š°±òð=@øSØôp)M}wó|Ë‹|î¨ã¼ÅsúÒ]ø…ÈC’s"ßð¢ãèò.ÖRý!ã¸j*Hµß$Q#§Í±t€Òù ëˆ)ûáR¿£*y¼óµ¶þ¡Ÿþ†+NÛ%³ÎÖåè;9oΣer½‡Yqó¿¼M÷ù7ÊîUO(UÞ³ûðýL…KÏ ¤6Ç›}°7P~•eá™Ôü‚,‘$ƒµ§uçG\šÏÖ>·K‘óq– ø„5›¦u/“B+F5•|­c¼äÙ4@!çS¼iùûr^ ²ï¶ïW:ùx½u>þ³ÝAôS²ê³~1¨Ñ¼–ìº|›ièÁòÞ–Ëå#°µÐö;rGÊŠ—Ã¥½Føµ;w¶À¢¥kJ:”‘yíͳæ_³‹A:®ÓsAr ¹Îe*©×´•Ìx¯§?J;|—I}56àä\U¯ÊnøŒÍ´‘¦ÀHg^tuþwæªgRøvS³¬¦s—t ç¹U®]pJäR|„ñ¸þ¬côý.L4‡BHÁKEŸÂ†Ôåî-ö/T6ß²é!Ç?¹ŽI^Õçv´æfß§à6ò—5ø,ï­23bj¼™²Ø±«FñlzΧ‰..?z?™ðJà›9ÏBzæ¬l*:ÚI‘ŠwÏ’ïu ·¡K‚ãµ%^Óòº R”¶à³?’Z×,öôwËÜoI+Ž5nåƒ,L±SFOêÜo˜Åöhô3T¦¤K×^¤xÕÇð„ëŠËe]iÞuC»øÔˆ·à#ܰ•¹j¿¨®¦‚¯XŒ±ÃÀuILü5ºYòcb&;Ÿ³hÁµ‹°{8ºi;…0 ƒãÂ3µ‡ôÌØÇŒÍćœüŸíݳَ>ˈdÇ®Ú nÖcZœ72}äÕ’„Þ;þ4åyï³ØVŧXÜzø•9M²€›À†$¸IÂAºí^v(gƒÌèÂæbÒꨭyuf[ÿ)±œÄXå¬M_j =xÍt×VYÁôÂãíå$•ä†ÍQ—Dïט—ßÔ7Ÿ![OuÃc¯MI>á‡KºsÞ8ÉšD†ÐüT%'ó(§SU¨jžsNå¾wýÞíä²å¨¡QÃ̾Gî(øÔ³K‰¿D š§·-oòΈ%W4ÕgÛjihí!‰¢'¿j2KbºG¤ŠtûHÂø:ª¶\‘;#1ã@4˜^ù _jîê,øò­„FN}\%>ë5h G¾7"¬:i˜R"7¶Zt²·¢Y l»ÿz3C÷LÁ¨â1P|–Ô|¦È,®L{@9KT[ž!ÁâøFn˜|œ!m-²@þ4Mëû}W 8çž.“¦HÅ»‚ÙH¹ÇÀb/¦%g‹JRêG¢7`µGå§ ÏÌõû'_ÇÑEºLµ,“{o>ù©c—¿>§ytZ)J@r¥ÉÕ†b“Þ¯§–õ¿.{jàÞ9™Öò³Ç°Ô1jŸIÎ]™ž~9çe2a‡¸Igà¡êUâ†â¾ÍñÓÅ«»OWØXÔ%ÝÐJûv®¿YÌ&ËßôCN£qŸ‚âÓoë§/ç³e¥X|¤'µúò>ðìIáò<¯L8y:›âkÅŽíÂô”ékÌM”í!å_+¬©ï·¨ë8º¤ëì  ýpõÆýn¦Š“>Iú)üžÊF› gOBHZ# õ1S²ÕXÌ&v0ÜQôâ‡%õ²Ý›'ú‰õ!ë̆íÍe.â‚»²}š¯Jâңmݺ©e!J¡ïÞ(ˆ¸2›[îšPÀÜ -óqù·Ó;{I&]%$T»â—F©­…_;…Í.¿jd©Å;׎ûŽ“sRªîX¬Ÿ(L€^¯SYØWûЇW‘óòÆUå×° & [T z´Þ8ׯNÁú%î¨ ]½qÞ°çPäµ÷ß{•”yy¸n¾ÝãÐe¥¦@Ì seSv=ì;˜@ªœ —Ê3J7.œ†Gæâ5LJ|%8X5ûûÅ&¦…iòqwR_î«®Œ{ׯMÙÙªŽfæO¶ÎdWjÉn³3„DÛ©Pmø>ˆ7gcÞÅÉõœàvÞ|‡Äãe.×|ëäü €&Ü…5²Àµ¡˜7½K¹B,-`žsØv®­éY1?­šxðQm‘ÑoõFþd/i”àÑ_1Qg´R$†1%Ê´y 7ÃÃäœ=4¥]µÖ&ô*ÎW…Ù62É/J(‚÷ê .1%s@#Z³mÄGh¦b˜H)‰-±ÁF·bäûnu›Þ͉!5s=NÞP:ßÈÅ3"Šç4ÙhÎGÕw¿´2ò|o‰?‘õ[`\æ–/a sÖ®áI[ï\T¥¶ä+i4hÍËäû²¯ Òá¿aX>­GçÌd‹ ˆ‹ã!nœ›-#^±”â?#@¯#H+ç$î ¢õ/³ŒU}ø%¨Š^­¹Õ'6AÑàÂÒ“Ûd*K[v'ŒÉJ Ûcb¾¤š‘#™1RY¹—ëýÿ·}?‡|IèØ]ÅbòÕI6¹ÁÓõ 3ô¡nÄÔU•æì~ã uŸ¬ÄÀ>zutÒ¾¡ö£5æ£Sf-ã°ur;…$.üIvlÈ÷—]è¾³C3Šˆf®ÍåQ·ñïWÑ¢I?Fmö?¼&-h„aÚ±JÀN_òg?>^YFsЏ|òÉõ³€éA¢^É%¬Ä§ti ¶òRn]³Gäè÷÷ .vÓÜ92åSµÌ ók”ù®_«#Â0¾Øø­=Ð.O4ån޼éZ9g}b‘L ™‰H1ÒÃõ)·Ã±ï^”° N{˜:/®/ØÕ_„+äL@‰ß}áœS¶¦.“2Ø4a–cæ¨[OéaMJ)Ì{ÑIØÁ^iª=O>)boÆa]†$Åt]3}u–ƒœâ=Jd·õ>NéHÛ¼J&Ì #¶¬‚ 0’¦A‚&‡âž‡l§©…ª]™Mamz[äšÄâ ijLºM~‘mš :C8})Jd;¿v¶ëŠ$„|Y,$c¶}ò¤Œs4½¸È]$˜šwjÈ?çH%¹0çîòbd"ôÅåÆp½ušZ~ð|.kDØçˆSê1YyçÀ+Gš%]íGžkÜE“ôÚî>ý ìj|?ßMrVnß6"R7?¯ð`KGÕ.szšËI?¾‰ZäëX®žÝOöò5ÓñîM~ÖÒ‰¥U&±êqßgÌâ7ã~õÖJ}±ýºÔßR„LëIí¡/zùEÎYÞâåü¢Fû& ¾ëq»ün…m«f³¢¯NsìlDk2ÔÓ9Ojœ¾-0`ˆæ¿£žØ]×ªì¹ØÓDÇËÊ»Èad£;“9Þh –ˆ>ؘuZr#}ÆÓgëºmÚ »ýY—\³NGQ(z:þ[Ë…Æ…RþÝU…£ÌcüéØ;,ò=Ë ÎÀìRÚ¡ñ™àòcÑŸKV_ÇZÙR(¡8Öë¯À?:JÖ ™ƒ‡´NF@ô¼L']ð84ÑîÞ˜û;õÁä«8bÄÁóê1}Ÿqªä•ÔDšF›øv¹ôµŠˆÞCÄ`UVî÷»Ì/ªm°ËvÚ~òâ¬Ô£¦F,W©C`œúÙ.Nc­I_Óœà¢ÙZ¼¥Mqm-ÊÆGX—›âß©o-AN‡kù†F`}9• Ÿ1‡L¨TŒ6ß•3ó>›K;G\@A=£¸3×øJS\Õû‚x—”µêŸ(·Ù„ª=+4æ ¶Î—«š ŠVÝX ï Á5¿*Oß±w‹sŒñw©úO½±ˆ»\ýÑ/Q3û‚Š2ÆV‘àKÊ”¬Ž ¡ ãëÙ™ÚyRÕóÅXt·ÙÑ#©¢@x™ŠÛè¦ zRi ë.•h¹ mkKÍUUòéÊ4ô›;ÇðÇ–—Ì Q'‡‰Rœ*´y£830¬æ“Ò;¥ÇŽ è[ñ³È?8këp)á+U$϶Ō-czTëê×ëë‘óGåu’Üù¼ù’8µ©-WôXbçȤ³]ø H‰Á¼ˆê]›ßðc¬yÏeº;Ê1%nýx,?"öyNþ´ü›HPYûËä·v¹Öà“üîÃ$±­õÒuj>j©í¾´ Ó‹$amkT§BÜyy” ùîÕð®Ò·ô1¾]§h=n=XcÆ>}9ªÚÅ4)'‹ÓŠ(¯Ð¢±6Öa^ã=. þì¯ÊŒ2VDZ‡¡,oÞ :Vù·†vl`Ûé®SRI\‹«cívùJ²›¿ÑÃÃ%|È)3œXïÄúwpPP9Pír*a¹Q®ÅI6/ÓwœèBùËð& on«‘4ÛhHð â©ãŒä‹)CsJÚ·Q¿¸–´›ç·j”†×°Ôøº%—^cùu%È×xØ»$W;òœÔx?o®h;TFÌw¹6(pµÝðà±´=«&¡ÈíÕ3Þ‹«H^cC3Ç¡é׉•¬ñ˜†Ö÷áÕ¥Ö,oÐib¤´Ù6}N³iå/ãea»±f¬ø«Ûb$[› ôdz,¬O<à},À—ŒuBn÷Ô; ø¹ô/,Ôb%õ#6V¹w ‡21~V8 ÑÀ_Jøu³W3-x6Huî>þºÑéŠ^_Vt÷ ²:ƒ2”ñHo¡&„T³XA2žæãƒ•6^©…5u7;ã¥Èaü‰°ð·R‡z`oª¿¿gÚ^7°þ8A2”5F“œÕå¡34ÁÂèc Žý1¤k¬2°ÁÞC?ЫäV_ÌBšrzÃ96—{?Ñ—ÄcöõÜõžY›^±æs—-s¢á®޾¨DT]™Z®¯pWü µ6Ø&X<•ÿUPîƒv*®6raûfsKkTªkíº(${S'm»åGî–0ÚF‚¼Éò¹´+<€Ìc[lFƒýœ"IVº¸¬eðG@ý/&²+Ó`%ŠÐLÍÃ#Nàs..3½Å¢N[b²ty^åküÙØXi²¥±h„€}æ³UÀyrº-—Íù€…MÍ_.ÀÎŽ²Yiþ„wq®™Ï¦Z8ö­]½cdÞ„{FË8ÈcùÍ´<©Z\.uRfÉäDËœ0,Ù+ƒrÙ'X‚eGŸÔ?=!³æÈÑ¢ãK=µ×ìôpõoiƈŒÜ)'=!™K‹PÈR¹R"ËtP·éqóù$’ jX½ô«4æV¯•Qª2þ~§r÷AaÆwú7ÏUA­ 7’H·Ãáì}úÑ¿šm5Æ ™{¸WÝäNÞ¼9w¬ê¥<‘–9¯^÷*~¶©Ó!Tª{)=~†ÛQ¼Î–ìÕ‘¬_EáÁë…ͽ=¢i˜š´înÌ Û¬™•̪ªÖ,ÒºÙú‹ã^‘_·—kÊTU9ó‡M5rZE\ßÉpÄäÓ§_®ÕMÍm‡ÿ”—êµäâê WÏõ¶{zþÜÈtÊ:‚…§,hË:ö³Ò“·´ÃjŒz hÈ7Õq…)/­.& Ä9ÈÀs€”'6”~FÔ93…w!µ¢}UíS€ý"sS?|Ìž¬É&¦ÏÀD®À‘'0Ìçà“^–Ç 5½Ó0ua9úBáØÜpºÁs’#KÛ—•`Ãr“aßÉ/1œñ%öó>Ó•÷Lºµ¼‰¥GäçµGhÊBc¥¯Ô¾déMQ™Á=×øµž2žÏøßà¦í>ÝQ¬0AÎúöX7êª`—Ä4k\ìä̰“ê‘¶K­GÔàMf‹öõ—bqVtg¾*îw±`˜‘w–º~& P«6Ï<}6–ÔÏäþ0ïxë‘&" {áºc’‰‡H\«ìQ2œúDÓK⎶M̳]Õ´úе¶ÝÖI׸”Ô§•OÚ2"Ï"üa×IÌýå!uƒgÀn|貺ÝçÙW³$¾’"q‡UüÙGÔ[]a zåpÊUÜ:«ô7–¹N:›/fÏ ¨0žRì—’0’=®V yb¯+& –Ãú„nÖÑã®õb/B[VT|S}—p-g­Yóº„ÎÒª®}±æAÕƒž°á‹ggÀ€ÿ•—™,¨ß­éðÛ3Í•³\ìœ8˜0ž_·z‹Jd/NÃêËûçg¡<ïb§ãac* 5Âü¤iBø…NjÏ|º{âÕ¤ªØ§ÏÙØ4OŒ×F´ùrŸ‹\•ð­KŠ™,à ç2ó^³T–|p)º2P¿2£­}ÄôŽö0\©8Áõ¸Ž£‰Ø×t7ò„,ú¨40~”ÐcmÅ"Þ jƒ`¹sN⿸éÝPyÓoþS•˜º¡)k*LY÷¥,Sð¡L™dÉ®ïe! ÑŸZOçäph5Í$ŠÅ©m~y¥ENù”ýÐN³í[fRØáYûå”ñ/EÕ³¶î+{´^42Še¾¯AºwgžìÝè)+e·˜y¬â ]àã¾âçìæêõx·-Ö 6zó½Ÿað»¸,’ÐßÙ÷HÚQ”®ó|Ƥ¬ÀÚB›§ÉbeYvWÚßã. 'M‘ ¢ñ܇˜¸öz‡êÓy÷5¥³*4^ú¨ÿ ¶±€ÎÃ)‚³8ék»½j´Ë3ón·^·ÃûR%ZO‹ ½M­3’³…ý®,eBêý>,­)õU9AéßéZ”˜6¸Ujîõ{”q© ðyªZô¥˜”ÀU5»a§NÁŽ|1¯vNaýûoÞ*î±E¼\ ¬v}#oب¸W¸XÞÏR°Bó «BåX× ßåÙMf/ì3'ÕOÐpÒ÷Òh[rP@ó æºã‚6fê==ÂCÿ·õ쩜Ðé  0—úÒr«ïÀ(+}óå•V!%kÖ»Éeç]Ó-žTjmw]Œ¢#£Óš÷Ùãt»r‘?µªjn@à…¾µö¡Vê¤~ݤ#‰d ³ÿc¤â endstream endobj 243 0 obj << /Length 708 /Filter /FlateDecode >> stream xÚmTMo£0½ó+¼‡Jí!m0U ó!å°mÕT«½¦àt‘Húï×o†4ÛU ÇøÍÌ󳙫ÛYZw/nÞJñä†îÔWn–ý܃««¼«N׎÷ÎÕ®>¯wâ±ïª­Åu¶É7m3Þxò¦­ÞNµ;³¾'Y÷Ú´ úˆëg÷{6jö>úÙ;A òs3¾yÒ·ëÂÅ×  ¤_®š®½êVJéE[gÝÛ‚ù$EÌÏâöM[÷“ñuÒ¢nªqú¢wuð~ yû1Œî°i÷]°Z‰ù“_Æþƒ4Þó‡¾v}Ó¾Šë¯ÒüÒöt<¾9È2X¯Eíö¾¢ßÿýîàÄüÛ=~rž?ŽNhúV¬«êj7w•ëwí« VR®Åª,×këÿÖbÎxÙOÔÔ0ñ/)=Vfá±Yú—–T{œ¦ÄðØ ­â@á r 0,jؘû@†@ÁŒtD˳¢êÏ®Ÿ´K¡µT—M¤Î"`ê¥ó xÁB ð’ã9pÄ8Ž976'>ï;-SŽ'À–û'ã¸ÎÉ…šJ3† ½Ê('ŒúZ%ЯÆðD³N½h¶FCf=tÂu4ôh­ˆ“1ûÕì¢&NI¨‚£C ýaιè‡æ%ö¥ã.sƨ¿,X§.‡GÿœEDœ(B˜üW14yñÓ¨‹ÏF_ÎÂðÝHqÅ('bï ÃÄ„ùî¾vÐmØ; &½xgìå&ò…ý5|6)ö` Æð"ásJ‘›,¸4%¬!Ź&¤AQ߄¶„üR¤3əߪ¿$S>›gcYˆšvú§ Ç²~ ï¬å³!ÌçG¹9ÝW™Ã»’qO ýø—1y>ÇDuê{?Ah<Ñ`ÀHhZ÷9ÁŽÝYôÐè;ÏZ|=”Á_4« endstream endobj 156 0 obj << /Type /ObjStm /N 100 /First 884 /Length 3187 /Filter /FlateDecode >> stream xÚíZ[sÛ¶~ׯÀÌyi§câg2±“Ú¹º©ã¤I<~eÚV+KE§NýÙ ¤îJÒ91MZ»ß~»Hre#\[™!Ü0"‡zN„‚»QD8 wN#ˆÖ o É• nVňå¶Ç$G2–8 ½sd0Rp·0|\(À…ƒñ\.@F(,ÀtÂb:H!z F”^6'\yYhQ^ÖAe-ڀѠ-ÇV£aP«ppG´ï¬ÿU÷¸YÇ`:hŒÁ £`` w z:Iþ®á!A€„Ñ‘Ø×AƒTX°™Q=x ídž>¹°86Ö@g(;*8€×)œUɰ†’ˆ#±1‘B¢HN$LÐ}ˆT d  2Z‚&œ+p<®ˆÌÁ@ÀNZFpƒÆi”µàJTŸ;¢„´=rJ;b´’(DZE˜º MtŽ  ‚`˜‘0À@LNRãÐhP)úôòÃpl±À‰UÐuèjkfð³cØ]0âtµÀt* îŒÖžÎJäÀÌg=Ž\dÞµ`g=àÊô3R‚Y°ÜÄ¡/ˆ ­¡ˆ¤ÑÈF( Ž%‰%¤*²­'Ч\qH;`YN«\ŸÁ•PŽ”1Àœ˜›HP°0žFa3+FXp@ð³ê=zÔ£‡“qE="ôô‹92 „¦ÕS[*Æ›*Òc•ŸîÑ×ådð¦¨È¡¯ŸzZæ}Ó«ârØ?˜<3 h;qÓôKèëD¹0ür†ÙÃ+öþÃG!8dv|?5j,2xWåžS ÙFyº?O`¨3ŸÚPÌFxïLíåzôÍýEåë/‡ã?{ô`R^¥Ÿ‚Ó§ô}|Æ}•€5@¦ŒK ä)T2S„ö=o=šœN€øÃà¦We&~DXé°hR`5á³IȤÄ4‘g ZY•YIÂfÌ \°Ã›A÷=ò3ÐýA5œŒéúöä^?ÜTÕÝô¿”^ö«~Uö‚bâºÊ&å5½œ èMu;¢åÕ@£3¬ügZøAö8ûq¦?’h¼–srà6Hëd”3&®µD[Y_Lf>˜ÌÎÁdì†xÙ ðj˘Üd°¨¬—¾HHokå€ÕÖëurÚ‚œ]oƒVƒ1×ËI—©|{úÎÛZv¥¯•sôµ|3úZÝ¥¯›Ñ·%·€¾Ûá°³évÞt³³éù?» :1§¼c»*ïøf~kÉ-I;ËL+·Vv‰YÞ Ã¯Hç]ž'œú:Äç½Ë·B<Ùx¸Z1<&|ÇãE´Qš•ÇTø}©Î`ù\¸õ˜Þ_„Õ;Ó™ÌøÒÈ®ÊÀf?³õ1À+#´ÌàØ³µ2ž3.®»À–ˆoÆ-ç[íÈ¿ž[pîìr &»E3ž 7A©-·qná°biÒþöU ØyPÌΠü³ùYð¹uã›(Òv¶À#þ7Ì|2ë•VÌßj™€“Ö,SÜ-ŒÌ;0/Ë;ñˆÏ 6bs[B¦¶ÇVÔ%Ô[í£3ûqàç¹…Ùa©»f€<´k8ŸY)};þŽmQ®éÊN©º-´ã8ñRp Ðõs"÷ÌË~ÎXõãüï8Ó'\Ûð÷ØÊyÝç¼w¦ñ‰Ì×_ßn¤¯¥KC Íîmra¼ð”/lw‚yþù ùŠü uÏc!|?ø9žÊÆ{äh¬{9l<ÄÇ£ 3ÞUàlä&^8G¼§¶5qÚwÛöÁ˜qü8êˆw¼à7@.ÖâLñâøÐ•1Íd& 8+rE…›)ç 7á“Q]Ëo묨Ž/TÙ‰YIAÎB '„r’IìåÔɘbÛ½ÞÁ.Ÿ¢í‰“â=ub£{(ç ìŽ:¦˜¤N…11DôAÚ†üLZ·gèUr¶3üÍ89›]+’5ð5P¥ëAà¶7'äÿV¬'놇?Ç’šâ¯-o‹65þáž¶7}B¹Y>‡€hä:øö;Kɲ«ÌªæBs¤™hÕBÈâÚI»,¡mÄTk©ŒQï2¤¦témdš”.ïV ³Ø‚±ˆW¹šå‹s"Í 8‚UMÛ¿/D¸éçõásžìUqw÷¤˜Êá]5)ëÝÞqÿ~9þ°ÿîÃËŸN‹÷G_ÊâiQN¦{“Ñ%ÈŒú×S¢já¿aÞÓ’“= ›y.5¾[Á%–îO¸qÎE;ðþÝÓbx}ª8'þ¶'¸ëÑgU4ì¯Ga°s®ŠÛwøZ±G߇N+oú%î% ûô€>¦Oè/ôÐo¥_Зô=¦¿Ò×ô„¾¡§ô-}G§ïéÚ§t@“ÛÛ>½¤õÒ+z5„¿Ï½‚s½¦7tHÿ¤#zKÇt<tB'ðÿŽÞåprIK:¥Óâs1¦Óá­huS­þšÐ{ú™~¡B?Ö˜Á!òô¬³î·¿½;8z;w ÍÐU]1ºLA×mÐõ*Ð÷¸˜Á.—Â~`€‘¦†eŠ´ívÛØýêÙÉëW'm»OŠëûQ¿\b4Œ¿'ð-£ô¯ó”MŒöêÎŒÆjb´]Â4—Z,Tj1ì¨TÛ} ¤¸&Tàó‡–Ñ’ocôñÁóçϢѧEy[¬ .kÀÏøŽÔ¿Ý†ãÕÌdcej²¯ÎLfjYpI7³Y¾,¸Ž–„×,¬F“±«$ FuLÝЛ/w70Àßß^åtx=nbl\íÀºÙy:˜”}XcRnûû÷ÇO~û­û²$›GÞàS”$­µ¨–-ƒœ‰rÍVCþ|iNû@?zð/ü;ÀjT\U±\úÔvÇ÷¢jœÓÍ|ÅÃ`Ô¿EÍ»ì:uÚKò!>ñ³úR=gÈŸè§ûIU\^Œ¼@¬Ô2¾Vkßk giu:êOo–sà3ý«æÁ&èm˜ðüäèéÑI‡ «R­‚„³'ðÛé? ÉY‚ƵB«IênªÕ‘V%„¢MˆÇø;ö48mÜߎ½±6 qUŪ×V«Ó«£ýÃWªøÃEU-FHXL±‘5Ç]›H²2kã£S|¸É—ÄK ×ÊPHç+0,ÛfmµøüòëÉó/ЬeViÐТQ ¶z"1Êä¦e..Ûµ*í¶3@ŒÿvÚM"ûÓ}äSpÜÐ,J¾óyw.l;ÛœMã±jÁrøËx0¹ޝ§áÕU©Ÿ¾žq³"gÀ7¦©lgCî"R'ÆéÒÔ²(=Á)-€@‰›ojïñ@ûjK=„L‚ǣΞ>Æ´Pz]òÌmL?¦)6!­,NœN†£Ið|îõvõV¬J¢=¸å|3HÖŒóùÀIžcc#0ö ?-üCáUG„VÈùïÒü£óÃa9­òD@¼¼ì‡ 0îïÃËêfê?fó²Q[ÿ5šo9¼â—Y²ÛZ¥ìÚ vGeɺ*+“ªŒi¼QY•Wï»úŠ®¾¸%³™¾<ÿ.ú®ÚÖvµU[B}m×ì» ›®Â¼E!…åwQxõ¦¥«ï\Ä)½T_ñ}èÛÙ4t4TsæòV€©„°öèÓYí»êÌÅTËÉÝÿÿd‹€XkÊ»¬«±P ÎNø¶tНKïq‹3{õ©B¾^‚aëמõ§.øÍo¸×¯rÁqõ½Núç»ÌÀeø£VîaìðUküè0|¼µÛák§ø‰Püò%~¥ßÇWÔ«æàËæoXWöuQ¸þN(~~_–Ç÷Î1~½¯F°™F°!ðãh_‰ÄŽCØi<„Ò>ÉCŸFõX/‹ÏD·ÏuWÕtå­®Æ-fQ8~v„ã'Í~šøÕpmD.S+djÅooL3¼\1|Ðóß:/ÒÒˆ8Lüøº3LÝSÏ÷Ô Žz%Ž2':¦¶6*ç­Ÿ«keg²yÍWL&S¥yP7NQm§È5µÀ\Õà­äŠž)ÞªÁû‘<²· endstream endobj 263 0 obj << /Producer (pdfTeX-1.40.25) /Author(\376\377\000M\000I\000T)/Title(\376\377\000K\000e\000r\000b\000e\000r\000o\000s\000\040\000C\000o\000n\000c\000e\000p\000t\000s)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20250820154558-04'00') /ModDate (D:20250820154558-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) kpathsea version 6.3.5) >> endobj 246 0 obj << /Type /ObjStm /N 26 /First 207 /Length 919 /Filter /FlateDecode >> stream xÚ…VmkÛ0þž_¡M¡uz³!JË`¬kǺ}*ýà¶&3äÄÛ¿ß,+'Ûé ¡Ò£»{ž»“,i)2¡œ0¹PJHëÀúË•)T!…tBë\H%t¡D!L?a™€vÂáà¯ÈÐABfÆb€LHÈ0 Ae($id†¢".£…Ì% Œ… §7ƒ¨Ê(w¨ÊÐÏ!…ÅÖâ’•ªòt&ŸÌç“ÙºYUB&ö}2»Aýíè[¹¯6 %ë§ÕŸFhã'‹óTyô4‰'èn¾¯~SNq0!?ùTïU¶³û’&þv{ÄWªG¦#™LÉ®bDfÖy‚õô”z‚žêƒ“0Žçä´ù†.?èqÅ6È´ œIŽˆ”± 2í¨q¬¢”gY –Hžt,Ÿnò‘=¦Xu7Fäƒ)<•|¼â­*ÃUñ"wzû›è¡\Wñ|q·}»zjÊ}3¹&.>7ÕúZNé r CD'Ù˜B$G!^ú *ª×uÓcv/}ií‚¦Š‡4„hŽXB G".’)Q}i‘5Z £T3Èq]@r\—³¡9^y Œ]>ª ¦'£3²¨:®àñ¨:9oQ/)1WNAOŽb(×d¦Ñh\5Cq>êEû± µBÑo¿Ê]Sí/ýÌtÖC°$­ô0¤eViÝVCÙ4&ÖÃ@ a’&XíÊeåÅÉ öçGȦl0ÆíâÚÊ-ËxHEˆáˆ&$¡E© 5ChÓ)†6@ûaæÂ"gg4®Š6‹æh³h®€6‹å|´,/–?ŒÜ‚6@®Géi´TÓ>Q,Xí‘ èP½5õvsé« ]ÄJtÇ1`×’z›÷1ÜGõ!Yb7yZôÝK#±AÞ‘NA *¿ù³>ˆ–Z÷A$Òƒ/H¢#1>+Ù§íqâ´ºbPÛåq|eñgÅVL›‘ƒs:=ùÐ#ŠýR¿£9=#)4´ ûg¤ÿn&÷|| Nbˆ®„kÂÇ€›gÑ¥› ÙI;æ®: 5´ ŠÏ†¿»JÌn˦\m—ô^XbKA‡‡Îã±YÕtßsz‡÷Ųúº}¯f?UgìÁûòµZæóÙÃq}xÎpð4»[,Àö‹…î2{ÜU›/Z¸øý¿– endstream endobj 264 0 obj << /Type /XRef /Index [0 265] /Size 265 /W [1 3 1] /Root 262 0 R /Info 263 0 R /ID [ ] /Length 653 /Filter /FlateDecode >> stream xÚ%”IOUA…«îEQ&yŠ øpb‡‡ ¢‚‰ ׯµ€ÄEŸucâÎàB÷Dwþ’Ž;|ßq󥪺nÝî>'mf¶ãfu–™åæVœR4ZFª&r1jUD9¨×©í&Ú*Á jŠ´ /–¨©EC÷€Ô4¥ì©i|-ØžPÓêÀþ2‚¡I[;ê©19i÷  ‘Sbƒ´ 4“jaô h!= ž’¶‚6Ò〟燀Z:ÁcÒ# ôX#= :HÏ€G¤pŒ´pÀœÉ¹F]\DΔü$8å–*KQ9YFõfµ¿t¬.·úE§ùŒ».;îQã—y·[ÃZzÁYÀó~0Î!ÐSn~¯æó`Q‹DE0ìÖTÒ*›Ì/‚Kà2˜#nÍ-j¹®2à@î|LÞ%šS¤wˆfÁM0ãVXÑ”90À5 ³-ºõ|V ãóÛ@S˜%¢û äÖ·¤¾e­¸õ¿U´ $ŠÔ’ŒÒ\fØðì{#}ÿÂÝFG”b½À»©ïF…ÛØ3­âñÀ4Qã¶ðF5¬x7plȱø4äSÜØ1dGL2!–Š6·¥×š‚ëBç¥ÚÝJE-`³À*Qp[^WMã^BÞè= ì¦µEµtn<0Côº=ÿ¨\X Ü^¼S —. ̃n/hapÙF1ðFà@²À #BŽà- w{U«)nÛ[Š&ݳ/ЦÜþ(švßêT4ãYQÂǬg›ÿïeγUŠæ=û¶£h¬zöS£%^•„‰W ¡GB„ =z$ôH< Q¢$DIˆ’Z=Ûþkžýþjÿ»ßŸ› endstream endobj startxref 184760 %%EOF krb5-1.22.1/doc/pdf/plugindev.tex0000664000175000017500000015171315051422736016414 0ustar ghudsonghudson%% Generated by Sphinx. \def\sphinxdocclass{report} \documentclass[letterpaper,10pt,english]{sphinxmanual} \ifdefined\pdfpxdimen \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen \fi \sphinxpxdimen=.75bp\relax \ifdefined\pdfimageresolution \pdfimageresolution= \numexpr \dimexpr1in\relax/\sphinxpxdimen\relax \fi %% let collapsible pdf bookmarks panel have high depth per default \PassOptionsToPackage{bookmarksdepth=5}{hyperref} \PassOptionsToPackage{booktabs}{sphinx} \PassOptionsToPackage{colorrows}{sphinx} \PassOptionsToPackage{warn}{textcomp} \usepackage[utf8]{inputenc} \ifdefined\DeclareUnicodeCharacter % support both utf8 and utf8x syntaxes \ifdefined\DeclareUnicodeCharacterAsOptional \def\sphinxDUC#1{\DeclareUnicodeCharacter{"#1}} \else \let\sphinxDUC\DeclareUnicodeCharacter \fi \sphinxDUC{00A0}{\nobreakspace} \sphinxDUC{2500}{\sphinxunichar{2500}} \sphinxDUC{2502}{\sphinxunichar{2502}} \sphinxDUC{2514}{\sphinxunichar{2514}} \sphinxDUC{251C}{\sphinxunichar{251C}} \sphinxDUC{2572}{\textbackslash} \fi \usepackage{cmap} \usepackage[T1]{fontenc} \usepackage{amsmath,amssymb,amstext} \usepackage{babel} \usepackage{tgtermes} \usepackage{tgheros} \renewcommand{\ttdefault}{txtt} \usepackage[Bjarne]{fncychap} \usepackage{sphinx} \fvset{fontsize=auto} \usepackage{geometry} % Include hyperref last. \usepackage{hyperref} % Fix anchor placement for figures with captions. \usepackage{hypcap}% it must be loaded after hyperref. % Set up styles of URL: it should be placed after hyperref. \urlstyle{same} \usepackage{sphinxmessages} \setcounter{tocdepth}{1} \title{Kerberos Plugin Module Developer Guide} \date{ } \release{1.22.1} \author{MIT} \newcommand{\sphinxlogo}{\vbox{}} \renewcommand{\releasename}{Release} \makeindex \begin{document} \ifdefined\shorthandoff \ifnum\catcode`\=\string=\active\shorthandoff{=}\fi \ifnum\catcode`\"=\active\shorthandoff{"}\fi \fi \pagestyle{empty} \sphinxmaketitle \pagestyle{plain} \sphinxtableofcontents \pagestyle{normal} \phantomsection\label{\detokenize{plugindev/index::doc}} \sphinxAtStartPar Kerberos plugin modules allow increased control over MIT krb5 library and server behavior. This guide describes how to create dynamic plugin modules and the currently available pluggable interfaces. \sphinxAtStartPar See \DUrole{xref,std,std-ref}{plugin\_config} for information on how to register dynamic plugin modules and how to enable and disable modules via \DUrole{xref,std,std-ref}{krb5.conf(5)}. \chapter{Contents} \label{\detokenize{plugindev/index:contents}} \sphinxstepscope \section{General plugin concepts} \label{\detokenize{plugindev/general:general-plugin-concepts}}\label{\detokenize{plugindev/general::doc}} \sphinxAtStartPar A krb5 dynamic plugin module is a Unix shared object or Windows DLL. Typically, the source code for a dynamic plugin module should live in its own project with a build system using \sphinxhref{https://www.gnu.org/software/automake/}{automake} and \sphinxhref{https://www.gnu.org/software/libtool/}{libtool}, or tools with similar functionality. \sphinxAtStartPar A plugin module must define a specific symbol name, which depends on the pluggable interface and module name. For most pluggable interfaces, the exported symbol is a function named \sphinxcode{\sphinxupquote{INTERFACE\_MODULE\_initvt}}, where \sphinxstyleemphasis{INTERFACE} is the name of the pluggable interface and \sphinxstyleemphasis{MODULE} is the name of the module. For these interfaces, it is possible for one shared object or DLL to implement multiple plugin modules, either for the same pluggable interface or for different ones. For example, a shared object could implement both KDC and client preauthentication mechanisms, by exporting functions named \sphinxcode{\sphinxupquote{kdcpreauth\_mymech\_initvt}} and \sphinxcode{\sphinxupquote{clpreauth\_mymech\_initvt}}. \sphinxAtStartPar A plugin module implementation should include the header file \sphinxcode{\sphinxupquote{\textless{}krb5/INTERFACE\_plugin.h\textgreater{}}}, where \sphinxstyleemphasis{INTERFACE} is the name of the pluggable interface. For instance, a ccselect plugin module implementation should use \sphinxcode{\sphinxupquote{\#include \textless{}krb5/ccselect\_plugin.h\textgreater{}}}. \sphinxAtStartPar initvt functions have the following prototype: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5\PYGZus{}error\PYGZus{}code} \PYG{n}{interface\PYGZus{}modname\PYGZus{}initvt}\PYG{p}{(}\PYG{n}{krb5\PYGZus{}context} \PYG{n}{context}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{maj\PYGZus{}ver}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{min\PYGZus{}ver}\PYG{p}{,} \PYG{n}{krb5\PYGZus{}plugin\PYGZus{}vtable} \PYG{n}{vtable}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar and should do the following: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar Check that the supplied maj\_ver argument is supported by the module. If it is not supported, the function should return KRB5\_PLUGIN\_VER\_NOTSUPP. \item {} \sphinxAtStartPar Cast the supplied vtable pointer to the structure type corresponding to the major version, as documented in the pluggable interface header file. \item {} \sphinxAtStartPar Fill in the structure fields with pointers to method functions and static data, stopping at the field indicated by the supplied minor version. Fields for unimplemented optional methods can be left alone; it is not necessary to initialize them to NULL. \end{enumerate} \sphinxAtStartPar In most cases, the context argument will not be used. The initvt function should not allocate memory; think of it as a glorified structure initializer. Each pluggable interface defines methods for allocating and freeing module state if doing so is necessary for the interface. \sphinxAtStartPar Pluggable interfaces typically include a \sphinxstylestrong{name} field in the vtable structure, which should be filled in with a pointer to a string literal containing the module name. \sphinxAtStartPar Here is an example of what an initvt function might look like for a fictional pluggable interface named fences, for a module named “wickerâ€: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5\PYGZus{}error\PYGZus{}code} \PYG{n}{fences\PYGZus{}wicker\PYGZus{}initvt}\PYG{p}{(}\PYG{n}{krb5\PYGZus{}context} \PYG{n}{context}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{maj\PYGZus{}ver}\PYG{p}{,} \PYG{n+nb}{int} \PYG{n}{min\PYGZus{}ver}\PYG{p}{,} \PYG{n}{krb5\PYGZus{}plugin\PYGZus{}vtable} \PYG{n}{vtable}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{n}{krb5\PYGZus{}ccselect\PYGZus{}vtable} \PYG{n}{vt}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{maj\PYGZus{}ver} \PYG{o}{==} \PYG{l+m+mi}{1}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{n}{krb5\PYGZus{}fences\PYGZus{}vtable} \PYG{n}{vt} \PYG{o}{=} \PYG{p}{(}\PYG{n}{krb5\PYGZus{}fences\PYGZus{}vtable}\PYG{p}{)}\PYG{n}{vtable}\PYG{p}{;} \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{name} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{wicker}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{slats} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}slats}\PYG{p}{;} \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{braces} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}braces}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{k}{else} \PYG{k}{if} \PYG{p}{(}\PYG{n}{maj\PYGZus{}ver} \PYG{o}{==} \PYG{l+m+mi}{2}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{n}{krb5\PYGZus{}fences\PYGZus{}vtable\PYGZus{}v2} \PYG{n}{vt} \PYG{o}{=} \PYG{p}{(}\PYG{n}{krb5\PYGZus{}fences\PYGZus{}vtable\PYGZus{}v2}\PYG{p}{)}\PYG{n}{vtable}\PYG{p}{;} \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{name} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{wicker}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{material} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}material}\PYG{p}{;} \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{construction} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}construction}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{min\PYGZus{}ver} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}\PYG{p}{)} \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;} \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{footing} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}footing}\PYG{p}{;} \PYG{k}{if} \PYG{p}{(}\PYG{n}{min\PYGZus{}ver} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3}\PYG{p}{)} \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;} \PYG{n}{vt}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{appearance} \PYG{o}{=} \PYG{n}{wicker\PYGZus{}appearance}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{k}{else} \PYG{p}{\PYGZob{}} \PYG{k}{return} \PYG{n}{KRB5\PYGZus{}PLUGIN\PYGZus{}VER\PYGZus{}NOTSUPP}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \subsection{Logging from KDC and kadmind plugin modules} \label{\detokenize{plugindev/general:logging-from-kdc-and-kadmind-plugin-modules}} \sphinxAtStartPar Plugin modules for the KDC or kadmind daemons can write to the configured logging outputs (see \DUrole{xref,std,std-ref}{logging}) by calling the \sphinxstylestrong{com\_err} function. The first argument (\sphinxstyleemphasis{whoami}) is ignored. If the second argument (\sphinxstyleemphasis{code}) is zero, the formatted message is logged at informational severity; otherwise, the formatted message is logged at error severity and includes the error message for the supplied code. Here are examples: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{com\PYGZus{}err}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Client message contains }\PYG{l+s+si}{\PYGZpc{}d}\PYG{l+s+s2}{ items}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{nitems}\PYG{p}{)}\PYG{p}{;} \PYG{n}{com\PYGZus{}err}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n}{retval}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{while decoding client message}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar (The behavior described above is new in release 1.17. In prior releases, the \sphinxstyleemphasis{whoami} argument is included for some logging output types, the logged message does not include the usual header for some output types, and the severity for syslog outputs is configured as part of the logging specification, defaulting to error severity.) \sphinxstepscope \section{Client preauthentication interface (clpreauth)} \label{\detokenize{plugindev/clpreauth:client-preauthentication-interface-clpreauth}}\label{\detokenize{plugindev/clpreauth::doc}} \sphinxAtStartPar During an initial ticket request, a KDC may ask a client to prove its knowledge of the password before issuing an encrypted ticket, or to use credentials other than a password. This process is called preauthentication, and is described in \index{RFC@\spxentry{RFC}!RFC 4120@\spxentry{RFC 4120}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc4120.html}{\sphinxstylestrong{RFC 4120}} and \index{RFC@\spxentry{RFC}!RFC 6113@\spxentry{RFC 6113}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc6113.html}{\sphinxstylestrong{RFC 6113}}. The clpreauth interface allows the addition of client support for preauthentication mechanisms beyond those included in the core MIT krb5 code base. For a detailed description of the clpreauth interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/clpreauth\_plugin.h\textgreater{}}} (or \sphinxcode{\sphinxupquote{\textless{}krb5/preauth\_plugin.h\textgreater{}}} before release 1.12). \sphinxAtStartPar A clpreauth module is generally responsible for: \begin{itemize} \item {} \sphinxAtStartPar Supplying a list of preauth type numbers used by the module in the \sphinxstylestrong{pa\_type\_list} field of the vtable structure. \item {} \sphinxAtStartPar Indicating what kind of preauthentication mechanism it implements, with the \sphinxstylestrong{flags} method. In the most common case, this method just returns \sphinxcode{\sphinxupquote{PA\_REAL}}, indicating that it implements a normal preauthentication type. \item {} \sphinxAtStartPar Examining the padata information included in a PREAUTH\_REQUIRED or MORE\_PREAUTH\_DATA\_REQUIRED error and producing padata values for the next AS request. This is done with the \sphinxstylestrong{process} method. \item {} \sphinxAtStartPar Examining the padata information included in a successful ticket reply, possibly verifying the KDC identity and computing a reply key. This is also done with the \sphinxstylestrong{process} method. \item {} \sphinxAtStartPar For preauthentication types which support it, recovering from errors by examining the error data from the KDC and producing a padata value for another AS request. This is done with the \sphinxstylestrong{tryagain} method. \item {} \sphinxAtStartPar Receiving option information (supplied by \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}X}} or by an application), with the \sphinxstylestrong{gic\_opts} method. \end{itemize} \sphinxAtStartPar A clpreauth module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context and per\sphinxhyphen{}request state objects by implementing the \sphinxstylestrong{init}, \sphinxstylestrong{fini}, \sphinxstylestrong{request\_init}, and \sphinxstylestrong{request\_fini} methods. Per\sphinxhyphen{}context state objects have the type krb5\_clpreauth\_moddata, and per\sphinxhyphen{}request state objects have the type krb5\_clpreauth\_modreq. These are abstract pointer types; a module should typically cast these to internal types for the state objects. \sphinxAtStartPar The \sphinxstylestrong{process} and \sphinxstylestrong{tryagain} methods have access to a callback function and handle (called a “rockâ€) which can be used to get additional information about the current request, including the expected enctype of the AS reply, the FAST armor key, and the client long\sphinxhyphen{}term key (prompting for the user password if necessary). A callback can also be used to replace the AS reply key if the preauthentication mechanism computes one. \sphinxstepscope \section{KDC preauthentication interface (kdcpreauth)} \label{\detokenize{plugindev/kdcpreauth:kdc-preauthentication-interface-kdcpreauth}}\label{\detokenize{plugindev/kdcpreauth::doc}} \sphinxAtStartPar The kdcpreauth interface allows the addition of KDC support for preauthentication mechanisms beyond those included in the core MIT krb5 code base. For a detailed description of the kdcpreauth interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/kdcpreauth\_plugin.h\textgreater{}}} (or \sphinxcode{\sphinxupquote{\textless{}krb5/preauth\_plugin.h\textgreater{}}} before release 1.12). \sphinxAtStartPar A kdcpreauth module is generally responsible for: \begin{itemize} \item {} \sphinxAtStartPar Supplying a list of preauth type numbers used by the module in the \sphinxstylestrong{pa\_type\_list} field of the vtable structure. \item {} \sphinxAtStartPar Indicating what kind of preauthentication mechanism it implements, with the \sphinxstylestrong{flags} method. If the mechanism computes a new reply key, it must specify the \sphinxcode{\sphinxupquote{PA\_REPLACES\_KEY}} flag. If the mechanism is generally only used with hardware tokens, the \sphinxcode{\sphinxupquote{PA\_HARDWARE}} flag allows the mechanism to work with principals which have the \sphinxstylestrong{requires\_hwauth} flag set. \item {} \sphinxAtStartPar Producing a padata value to be sent with a preauth\_required error, with the \sphinxstylestrong{edata} method. \item {} \sphinxAtStartPar Examining a padata value sent by a client and verifying that it proves knowledge of the appropriate client credential information. This is done with the \sphinxstylestrong{verify} method. \item {} \sphinxAtStartPar Producing a padata response value for the client, and possibly computing a reply key. This is done with the \sphinxstylestrong{return\_padata} method. \end{itemize} \sphinxAtStartPar A module can create and destroy per\sphinxhyphen{}KDC state objects by implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods. Per\sphinxhyphen{}KDC state objects have the type krb5\_kdcpreauth\_moddata, which is an abstract pointer types. A module should typically cast this to an internal type for the state object. \sphinxAtStartPar A module can create a per\sphinxhyphen{}request state object by returning one in the \sphinxstylestrong{verify} method, receiving it in the \sphinxstylestrong{return\_padata} method, and destroying it in the \sphinxstylestrong{free\_modreq} method. Note that these state objects only apply to the processing of a single AS request packet, not to an entire authentication exchange (since an authentication exchange may remain unfinished by the client or may involve multiple different KDC hosts). Per\sphinxhyphen{}request state objects have the type krb5\_kdcpreauth\_modreq, which is an abstract pointer type. \sphinxAtStartPar The \sphinxstylestrong{edata}, \sphinxstylestrong{verify}, and \sphinxstylestrong{return\_padata} methods have access to a callback function and handle (called a “rockâ€) which can be used to get additional information about the current request, including the maximum allowable clock skew, the client’s long\sphinxhyphen{}term keys, the DER\sphinxhyphen{}encoded request body, the FAST armor key, string attributes on the client’s database entry, and the client’s database entry itself. The \sphinxstylestrong{verify} method can assert one or more authentication indicators to be included in the issued ticket using the \sphinxcode{\sphinxupquote{add\_auth\_indicator}} callback (new in release 1.14). \sphinxAtStartPar A module can generate state information to be included with the next client request using the \sphinxcode{\sphinxupquote{set\_cookie}} callback (new in release 1.14). On the next request, the module can read this state information using the \sphinxcode{\sphinxupquote{get\_cookie}} callback. Cookie information is encrypted, timestamped, and transmitted to the client in a \sphinxcode{\sphinxupquote{PA\sphinxhyphen{}FX\sphinxhyphen{}COOKIE}} pa\sphinxhyphen{}data item. Older clients may not support cookies and therefore may not transmit the cookie in the next request; in this case, \sphinxcode{\sphinxupquote{get\_cookie}} will not yield the saved information. \sphinxAtStartPar If a module implements a mechanism which requires multiple round trips, its \sphinxstylestrong{verify} method can respond with the code \sphinxcode{\sphinxupquote{KRB5KDC\_ERR\_MORE\_PREAUTH\_DATA\_REQUIRED}} and a list of pa\sphinxhyphen{}data in the \sphinxstyleemphasis{e\_data} parameter to be processed by the client. \sphinxAtStartPar The \sphinxstylestrong{edata} and \sphinxstylestrong{verify} methods can be implemented asynchronously. Because of this, they do not return values directly to the caller, but must instead invoke responder functions with their results. A synchronous implementation can invoke the responder function immediately. An asynchronous implementation can use the callback to get an event context for use with the \sphinxhref{https://fedorahosted.org/libverto/}{libverto} API. \sphinxstepscope \section{Credential cache selection interface (ccselect)} \label{\detokenize{plugindev/ccselect:credential-cache-selection-interface-ccselect}}\label{\detokenize{plugindev/ccselect:ccselect-plugin}}\label{\detokenize{plugindev/ccselect::doc}} \sphinxAtStartPar The ccselect interface allows modules to control how credential caches are chosen when a GSSAPI client contacts a service. For a detailed description of the ccselect interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/ccselect\_plugin.h\textgreater{}}}. \sphinxAtStartPar The primary ccselect method is \sphinxstylestrong{choose}, which accepts a server principal as input and returns a ccache and/or principal name as output. A module can use the krb5\_cccol APIs to iterate over the cache collection in order to find an appropriate ccache to use. \sphinxAtStartPar A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects by implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods. State objects have the type krb5\_ccselect\_moddata, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. \sphinxAtStartPar A module can have one of two priorities, “authoritative†or “heuristicâ€. Results from authoritative modules, if any are available, will take priority over results from heuristic modules. A module communicates its priority as a result of the \sphinxstylestrong{init} method. \sphinxstepscope \section{Password quality interface (pwqual)} \label{\detokenize{plugindev/pwqual:password-quality-interface-pwqual}}\label{\detokenize{plugindev/pwqual:pwqual-plugin}}\label{\detokenize{plugindev/pwqual::doc}} \sphinxAtStartPar The pwqual interface allows modules to control what passwords are allowed when a user changes passwords. For a detailed description of the pwqual interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/pwqual\_plugin.h\textgreater{}}}. \sphinxAtStartPar The primary pwqual method is \sphinxstylestrong{check}, which receives a password as input and returns success (0) or a \sphinxcode{\sphinxupquote{KADM5\_PASS\_Q\_}} failure code depending on whether the password is allowed. The \sphinxstylestrong{check} method also receives the principal name and the name of the principal’s password policy as input; although there is no stable interface for the module to obtain the fields of the password policy, it can define its own configuration or data store based on the policy name. \sphinxAtStartPar A module can create and destroy per\sphinxhyphen{}process state objects by implementing the \sphinxstylestrong{open} and \sphinxstylestrong{close} methods. State objects have the type krb5\_pwqual\_moddata, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. The \sphinxstylestrong{open} method also receives the name of the realm’s dictionary file (as configured by the \sphinxstylestrong{dict\_file} variable in the \DUrole{xref,std,std-ref}{kdc\_realms} section of \DUrole{xref,std,std-ref}{kdc.conf(5)}) if it wishes to use it. \sphinxstepscope \section{KADM5 hook interface (kadm5\_hook)} \label{\detokenize{plugindev/kadm5_hook:kadm5-hook-interface-kadm5-hook}}\label{\detokenize{plugindev/kadm5_hook:kadm5-hook-plugin}}\label{\detokenize{plugindev/kadm5_hook::doc}} \sphinxAtStartPar The kadm5\_hook interface allows modules to perform actions when changes are made to the Kerberos database through \DUrole{xref,std,std-ref}{kadmin(1)}. For a detailed description of the kadm5\_hook interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/kadm5\_hook\_plugin.h\textgreater{}}}. \sphinxAtStartPar The kadm5\_hook interface has five primary methods: \sphinxstylestrong{chpass}, \sphinxstylestrong{create}, \sphinxstylestrong{modify}, \sphinxstylestrong{remove}, and \sphinxstylestrong{rename}. (The \sphinxstylestrong{rename} method was introduced in release 1.14.) Each of these methods is called twice when the corresponding administrative action takes place, once before the action is committed and once afterwards. A module can prevent the action from taking place by returning an error code during the pre\sphinxhyphen{}commit stage. \sphinxAtStartPar A module can create and destroy per\sphinxhyphen{}process state objects by implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods. State objects have the type kadm5\_hook\_modinfo, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. \sphinxAtStartPar Because the kadm5\_hook interface is tied closely to the kadmin interface (which is explicitly unstable), it may not remain as stable across versions as other public pluggable interfaces. \sphinxstepscope \section{kadmin authorization interface (kadm5\_auth)} \label{\detokenize{plugindev/kadm5_auth:kadmin-authorization-interface-kadm5-auth}}\label{\detokenize{plugindev/kadm5_auth:kadm5-auth-plugin}}\label{\detokenize{plugindev/kadm5_auth::doc}} \sphinxAtStartPar The kadm5\_auth interface (new in release 1.16) allows modules to determine whether a client principal is authorized to perform an operation in the kadmin protocol, and to apply restrictions to principal operations. For a detailed description of the kadm5\_auth interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/kadm5\_auth\_plugin.h\textgreater{}}}. \sphinxAtStartPar A module can create and destroy per\sphinxhyphen{}process state objects by implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods. State objects have the type kadm5\_auth\_modinfo, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. \sphinxAtStartPar The kadm5\_auth interface has one method for each kadmin operation, with parameters specific to the operation. Each method can return either 0 to authorize access, KRB5\_PLUGIN\_NO\_HANDLE to defer the decision to other modules, or another error (canonically EPERM) to authoritatively deny access. Access is granted if at least one module grants access and no module authoritatively denies access. \sphinxAtStartPar The \sphinxstylestrong{addprinc} and \sphinxstylestrong{modprinc} methods can also impose restrictions on the principal operation by returning a \sphinxcode{\sphinxupquote{struct kadm5\_auth\_restrictions}} object. The module should also implement the \sphinxstylestrong{free\_restrictions} method if it dynamically allocates restrictions objects for principal operations. \sphinxAtStartPar kadm5\_auth modules can optionally inspect principal or policy objects. To do this, the module must also include \sphinxcode{\sphinxupquote{\textless{}kadm5/admin.h\textgreater{}}} to gain access to the structure definitions for those objects. As the kadmin interface is explicitly not as stable as other public interfaces, modules which do this may not retain compatibility across releases. \sphinxstepscope \section{Host\sphinxhyphen{}to\sphinxhyphen{}realm interface (hostrealm)} \label{\detokenize{plugindev/hostrealm:host-to-realm-interface-hostrealm}}\label{\detokenize{plugindev/hostrealm:hostrealm-plugin}}\label{\detokenize{plugindev/hostrealm::doc}} \sphinxAtStartPar The host\sphinxhyphen{}to\sphinxhyphen{}realm interface was first introduced in release 1.12. It allows modules to control the local mapping of hostnames to realm names as well as the default realm. For a detailed description of the hostrealm interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/hostrealm\_plugin.h\textgreater{}}}. \sphinxAtStartPar Although the mapping methods in the hostrealm interface return a list of one or more realms, only the first realm in the list is currently used by callers. Callers may begin using later responses in the future. \sphinxAtStartPar Any mapping method may return KRB5\_PLUGIN\_NO\_HANDLE to defer processing to a later module. \sphinxAtStartPar A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects using the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods. If the module does not need any state, it does not need to implement these methods. \sphinxAtStartPar The optional \sphinxstylestrong{host\_realm} method allows a module to determine authoritative realm mappings for a hostname. The first authoritative mapping is used in preference to KDC referrals when getting service credentials. \sphinxAtStartPar The optional \sphinxstylestrong{fallback\_realm} method allows a module to determine fallback mappings for a hostname. The first fallback mapping is tried if there is no authoritative mapping for a realm, and KDC referrals failed to produce a successful result. \sphinxAtStartPar The optional \sphinxstylestrong{default\_realm} method allows a module to determine the local default realm. \sphinxAtStartPar If a module implements any of the above methods, it must also implement \sphinxstylestrong{free\_list} to ensure that memory is allocated and deallocated consistently. \sphinxstepscope \section{Local authorization interface (localauth)} \label{\detokenize{plugindev/localauth:local-authorization-interface-localauth}}\label{\detokenize{plugindev/localauth:localauth-plugin}}\label{\detokenize{plugindev/localauth::doc}} \sphinxAtStartPar The localauth interface was first introduced in release 1.12. It allows modules to control the relationship between Kerberos principals and local system accounts. When an application calls \sphinxcode{\sphinxupquote{krb5\_kuserok()}} or \sphinxcode{\sphinxupquote{krb5\_aname\_to\_localname()}}, localauth modules are consulted to determine the result. For a detailed description of the localauth interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/localauth\_plugin.h\textgreater{}}}. \sphinxAtStartPar A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects using the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods. If the module does not need any state, it does not need to implement these methods. \sphinxAtStartPar The optional \sphinxstylestrong{userok} method allows a module to control the behavior of \sphinxcode{\sphinxupquote{krb5\_kuserok()}}. The module receives the authenticated name and the local account name as inputs, and can return either 0 to authorize access, KRB5\_PLUGIN\_NO\_HANDLE to defer the decision to other modules, or another error (canonically EPERM) to authoritatively deny access. Access is granted if at least one module grants access and no module authoritatively denies access. \sphinxAtStartPar The optional \sphinxstylestrong{an2ln} method can work in two different ways. If the module sets an array of uppercase type names in \sphinxstylestrong{an2ln\_types}, then the module’s \sphinxstylestrong{an2ln} method will only be invoked by \sphinxcode{\sphinxupquote{krb5\_aname\_to\_localname()}} if an \sphinxstylestrong{auth\_to\_local} value in \DUrole{xref,std,std-ref}{krb5.conf(5)} refers to one of the module’s types. In this case, the \sphinxstyleemphasis{type} and \sphinxstyleemphasis{residual} arguments will give the type name and residual string of the \sphinxstylestrong{auth\_to\_local} value. \sphinxAtStartPar If the module does not set \sphinxstylestrong{an2ln\_types} but does implement \sphinxstylestrong{an2ln}, the module’s \sphinxstylestrong{an2ln} method will be invoked for all \sphinxcode{\sphinxupquote{krb5\_aname\_to\_localname()}} operations unless an earlier module determines a mapping, with \sphinxstyleemphasis{type} and \sphinxstyleemphasis{residual} set to NULL. The module can return KRB5\_LNAME\_NO\_TRANS to defer mapping to later modules. \sphinxAtStartPar If a module implements \sphinxstylestrong{an2ln}, it must also implement \sphinxstylestrong{free\_string} to ensure that memory is allocated and deallocated consistently. \sphinxstepscope \section{Server location interface (locate)} \label{\detokenize{plugindev/locate:server-location-interface-locate}}\label{\detokenize{plugindev/locate::doc}} \sphinxAtStartPar The locate interface allows modules to control how KDCs and similar services are located by clients. For a detailed description of the ccselect interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/locate\_plugin.h\textgreater{}}}. \sphinxAtStartPar A locate module exports a structure object of type krb5plugin\_service\_locate\_ftable, with the name \sphinxcode{\sphinxupquote{service\_locator}}. The structure contains a minor version and pointers to the module’s methods. \sphinxAtStartPar The primary locate method is \sphinxstylestrong{lookup}, which accepts a service type, realm name, desired socket type, and desired address family (which will be AF\_UNSPEC if no specific address family is desired). The method should invoke the callback function once for each server address it wants to return, passing a socket type (SOCK\_STREAM for TCP or SOCK\_DGRAM for UDP) and socket address. The \sphinxstylestrong{lookup} method should return 0 if it has authoritatively determined the server addresses for the realm, KRB5\_PLUGIN\_NO\_HANDLE if it wants to let other location mechanisms determine the server addresses, or another code if it experienced a failure which should abort the location process. \sphinxAtStartPar A module can create and destroy per\sphinxhyphen{}library\sphinxhyphen{}context state objects by implementing the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods. State objects have the type void *, and should be cast to an internal type for the state object. \sphinxstepscope \section{Configuration interface (profile)} \label{\detokenize{plugindev/profile:configuration-interface-profile}}\label{\detokenize{plugindev/profile:profile-plugin}}\label{\detokenize{plugindev/profile::doc}} \sphinxAtStartPar The profile interface allows a module to control how krb5 configuration information is obtained by the Kerberos library and applications. For a detailed description of the profile interface, see the header file \sphinxcode{\sphinxupquote{\textless{}profile.h\textgreater{}}}. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The profile interface does not follow the normal conventions for MIT krb5 pluggable interfaces, because it is part of a lower\sphinxhyphen{}level component of the krb5 library. \end{sphinxadmonition} \sphinxAtStartPar As with other types of plugin modules, a profile module is a Unix shared object or Windows DLL, built separately from the krb5 tree. The krb5 library will dynamically load and use a profile plugin module if it reads a \sphinxcode{\sphinxupquote{module}} directive at the beginning of krb5.conf, as described in \DUrole{xref,std,std-ref}{profile\_plugin\_config}. \sphinxAtStartPar A profile module exports a function named \sphinxcode{\sphinxupquote{profile\_module\_init}} matching the signature of the profile\_module\_init\_fn type. This function accepts a residual string, which may be used to help locate the configuration source. The function fills in a vtable and may also create a per\sphinxhyphen{}profile state object. If the module uses state objects, it should implement the \sphinxstylestrong{copy} and \sphinxstylestrong{cleanup} methods to manage them. \sphinxAtStartPar A basic read\sphinxhyphen{}only profile module need only implement the \sphinxstylestrong{get\_values} and \sphinxstylestrong{free\_values} methods. The \sphinxstylestrong{get\_values} method accepts a null\sphinxhyphen{}terminated list of C string names (e.g., an array containing “libdefaultsâ€, “clockskewâ€, and NULL for the \sphinxstylestrong{clockskew} variable in the \DUrole{xref,std,std-ref}{libdefaults} section) and returns a null\sphinxhyphen{}terminated list of values, which will be cleaned up with the \sphinxstylestrong{free\_values} method when the caller is done with them. \sphinxAtStartPar Iterable profile modules must also define the \sphinxstylestrong{iterator\_create}, \sphinxstylestrong{iterator}, \sphinxstylestrong{iterator\_free}, and \sphinxstylestrong{free\_string} methods. The core krb5 code does not require profiles to be iterable, but some applications may iterate over the krb5 profile object in order to present configuration interfaces. \sphinxAtStartPar Writable profile modules must also define the \sphinxstylestrong{writable}, \sphinxstylestrong{modified}, \sphinxstylestrong{update\_relation}, \sphinxstylestrong{rename\_section}, \sphinxstylestrong{add\_relation}, and \sphinxstylestrong{flush} methods. The core krb5 code does not require profiles to be writable, but some applications may write to the krb5 profile in order to present configuration interfaces. \sphinxAtStartPar The following is an example of a very basic read\sphinxhyphen{}only profile module which returns a hardcoded value for the \sphinxstylestrong{default\_realm} variable in \DUrole{xref,std,std-ref}{libdefaults}, and provides no other configuration information. (For conciseness, the example omits code for checking the return values of malloc and strdup.) \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{c+c1}{\PYGZsh{}include \PYGZlt{}stdlib.h\PYGZgt{}} \PYG{c+c1}{\PYGZsh{}include \PYGZlt{}string.h\PYGZgt{}} \PYG{c+c1}{\PYGZsh{}include \PYGZlt{}profile.h\PYGZgt{}} \PYG{n}{static} \PYG{n}{long} \PYG{n}{get\PYGZus{}values}\PYG{p}{(}\PYG{n}{void} \PYG{o}{*}\PYG{n}{cbdata}\PYG{p}{,} \PYG{n}{const} \PYG{n}{char} \PYG{o}{*}\PYG{n}{const} \PYG{o}{*}\PYG{n}{names}\PYG{p}{,} \PYG{n}{char} \PYG{o}{*}\PYG{o}{*}\PYG{o}{*}\PYG{n}{values}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{k}{if} \PYG{p}{(}\PYG{n}{names}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]} \PYG{o}{!=} \PYG{n}{NULL} \PYG{o}{\PYGZam{}}\PYG{o}{\PYGZam{}} \PYG{n}{strcmp}\PYG{p}{(}\PYG{n}{names}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{libdefaults}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)} \PYG{o}{==} \PYG{l+m+mi}{0} \PYG{o}{\PYGZam{}}\PYG{o}{\PYGZam{}} \PYG{n}{names}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]} \PYG{o}{!=} \PYG{n}{NULL} \PYG{o}{\PYGZam{}}\PYG{o}{\PYGZam{}} \PYG{n}{strcmp}\PYG{p}{(}\PYG{n}{names}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{default\PYGZus{}realm}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)} \PYG{o}{==} \PYG{l+m+mi}{0}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{o}{*}\PYG{n}{values} \PYG{o}{=} \PYG{n}{malloc}\PYG{p}{(}\PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{sizeof}\PYG{p}{(}\PYG{n}{char} \PYG{o}{*}\PYG{p}{)}\PYG{p}{)}\PYG{p}{;} \PYG{p}{(}\PYG{o}{*}\PYG{n}{values}\PYG{p}{)}\PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]} \PYG{o}{=} \PYG{n}{strdup}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{;} \PYG{p}{(}\PYG{o}{*}\PYG{n}{values}\PYG{p}{)}\PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{]} \PYG{o}{=} \PYG{n}{NULL}\PYG{p}{;} \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{k}{return} \PYG{n}{PROF\PYGZus{}NO\PYGZus{}RELATION}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{n}{static} \PYG{n}{void} \PYG{n}{free\PYGZus{}values}\PYG{p}{(}\PYG{n}{void} \PYG{o}{*}\PYG{n}{cbdata}\PYG{p}{,} \PYG{n}{char} \PYG{o}{*}\PYG{o}{*}\PYG{n}{values}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{n}{char} \PYG{o}{*}\PYG{o}{*}\PYG{n}{v}\PYG{p}{;} \PYG{k}{for} \PYG{p}{(}\PYG{n}{v} \PYG{o}{=} \PYG{n}{values}\PYG{p}{;} \PYG{o}{*}\PYG{n}{v}\PYG{p}{;} \PYG{n}{v}\PYG{o}{+}\PYG{o}{+}\PYG{p}{)} \PYG{n}{free}\PYG{p}{(}\PYG{o}{*}\PYG{n}{v}\PYG{p}{)}\PYG{p}{;} \PYG{n}{free}\PYG{p}{(}\PYG{n}{values}\PYG{p}{)}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \PYG{n}{long} \PYG{n}{profile\PYGZus{}module\PYGZus{}init}\PYG{p}{(}\PYG{n}{const} \PYG{n}{char} \PYG{o}{*}\PYG{n}{residual}\PYG{p}{,} \PYG{n}{struct} \PYG{n}{profile\PYGZus{}vtable} \PYG{o}{*}\PYG{n}{vtable}\PYG{p}{,} \PYG{n}{void} \PYG{o}{*}\PYG{o}{*}\PYG{n}{cb\PYGZus{}ret}\PYG{p}{)}\PYG{p}{;} \PYG{n}{long} \PYG{n}{profile\PYGZus{}module\PYGZus{}init}\PYG{p}{(}\PYG{n}{const} \PYG{n}{char} \PYG{o}{*}\PYG{n}{residual}\PYG{p}{,} \PYG{n}{struct} \PYG{n}{profile\PYGZus{}vtable} \PYG{o}{*}\PYG{n}{vtable}\PYG{p}{,} \PYG{n}{void} \PYG{o}{*}\PYG{o}{*}\PYG{n}{cb\PYGZus{}ret}\PYG{p}{)} \PYG{p}{\PYGZob{}} \PYG{o}{*}\PYG{n}{cb\PYGZus{}ret} \PYG{o}{=} \PYG{n}{NULL}\PYG{p}{;} \PYG{n}{vtable}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{get\PYGZus{}values} \PYG{o}{=} \PYG{n}{get\PYGZus{}values}\PYG{p}{;} \PYG{n}{vtable}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}}\PYG{n}{free\PYGZus{}values} \PYG{o}{=} \PYG{n}{free\PYGZus{}values}\PYG{p}{;} \PYG{k}{return} \PYG{l+m+mi}{0}\PYG{p}{;} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxstepscope \section{GSSAPI mechanism interface} \label{\detokenize{plugindev/gssapi:gssapi-mechanism-interface}}\label{\detokenize{plugindev/gssapi::doc}} \sphinxAtStartPar The GSSAPI library in MIT krb5 can load mechanism modules to augment the set of built\sphinxhyphen{}in mechanisms. \sphinxAtStartPar A mechanism module is a Unix shared object or Windows DLL, built separately from the krb5 tree. Modules are loaded according to the GSS mechanism config files described in \DUrole{xref,std,std-ref}{gssapi\_plugin\_config}. \sphinxAtStartPar For the most part, a GSSAPI mechanism module exports the same functions as would a GSSAPI implementation itself, with the same function signatures. The mechanism selection layer within the GSSAPI library (called the “mechglueâ€) will dispatch calls from the application to the module if the module’s mechanism is requested. If a module does not wish to implement a GSSAPI extension, it can simply refrain from exporting it, and the mechglue will fail gracefully if the application calls that function. \sphinxAtStartPar The mechglue does not invoke a module’s \sphinxstylestrong{gss\_add\_cred}, \sphinxstylestrong{gss\_add\_cred\_from}, \sphinxstylestrong{gss\_add\_cred\_impersonate\_name}, or \sphinxstylestrong{gss\_add\_cred\_with\_password} function. A mechanism only needs to implement the “acquire†variants of those functions. \sphinxAtStartPar A module does not need to coordinate its minor status codes with those of other mechanisms. If the mechglue detects conflicts, it will map the mechanism’s status codes onto unique values, and then map them back again when \sphinxstylestrong{gss\_display\_status} is called. \subsection{NegoEx modules} \label{\detokenize{plugindev/gssapi:negoex-modules}} \sphinxAtStartPar Some Windows GSSAPI mechanisms can only be negotiated via a Microsoft extension to SPNEGO called NegoEx. Beginning with release 1.18, mechanism modules can support NegoEx as follows: \begin{itemize} \item {} \sphinxAtStartPar Implement the gssspi\_query\_meta\_data(), gssspi\_exchange\_meta\_data(), and gssspi\_query\_mechanism\_info() SPIs declared in \sphinxcode{\sphinxupquote{\textless{}gssapi/gssapi\_ext.h\textgreater{}}}. \item {} \sphinxAtStartPar Implement gss\_inquire\_sec\_context\_by\_oid() and answer the \sphinxstylestrong{GSS\_C\_INQ\_NEGOEX\_KEY} and \sphinxstylestrong{GSS\_C\_INQ\_NEGOEX\_VERIFY\_KEY} OIDs to provide the checksum keys for outgoing and incoming checksums, respectively. The answer must be in two buffers: the first buffer contains the key contents, and the second buffer contains the key encryption type as a four\sphinxhyphen{}byte little\sphinxhyphen{}endian integer. \end{itemize} \sphinxAtStartPar By default, NegoEx mechanisms will not be directly negotiated via SPNEGO. If direct SPNEGO negotiation is required for interoperability, implement gss\_inquire\_attrs\_for\_mech() and assert the GSS\_C\_MA\_NEGOEX\_AND\_SPNEGO attribute (along with any applicable RFC 5587 attributes). \subsection{Interposer modules} \label{\detokenize{plugindev/gssapi:interposer-modules}} \sphinxAtStartPar The mechglue also supports a kind of loadable module, called an interposer module, which intercepts calls to existing mechanisms rather than implementing a new mechanism. \sphinxAtStartPar An interposer module must export the symbol \sphinxstylestrong{gss\_mech\_interposer} with the following signature: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{gss\PYGZus{}OID\PYGZus{}set} \PYG{n}{gss\PYGZus{}mech\PYGZus{}interposer}\PYG{p}{(}\PYG{n}{gss\PYGZus{}OID} \PYG{n}{mech\PYGZus{}type}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar This function is invoked with the OID of the interposer mechanism as specified in the mechanism config file, and returns a set of mechanism OIDs to be interposed. The returned OID set must have been created using the mechglue’s gss\_create\_empty\_oid\_set and gss\_add\_oid\_set\_member functions. \sphinxAtStartPar An interposer module must use the prefix \sphinxcode{\sphinxupquote{gssi\_}} for the GSSAPI functions it exports, instead of the prefix \sphinxcode{\sphinxupquote{gss\_}}. In most cases, unexported \sphinxcode{\sphinxupquote{gssi\_}} functions will result in failure from their corresponding \sphinxcode{\sphinxupquote{gss\_}} calls. \sphinxAtStartPar An interposer module can link against the GSSAPI library in order to make calls to the original mechanism. To do so, it must specify a special mechanism OID which is the concatention of the interposer’s own OID byte string and the original mechanism’s OID byte string. \sphinxAtStartPar Functions that do not accept a mechanism argument directly require no special handling, with the following exceptions: \sphinxAtStartPar Since \sphinxstylestrong{gss\_accept\_sec\_context} does not accept a mechanism argument, an interposer mechanism must, in order to invoke the original mechanism’s function, acquire a credential for the concatenated OID and pass that as the \sphinxstyleemphasis{verifier\_cred\_handle} parameter. \sphinxAtStartPar Since \sphinxstylestrong{gss\_import\_name}, \sphinxstylestrong{gss\_import\_cred}, and \sphinxstylestrong{gss\_import\_sec\_context} do not accept mechanism parameters, the SPI has been extended to include variants which do. This allows the interposer module to know which mechanism should be used to interpret the token. These functions have the following signatures: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gssi\PYGZus{}import\PYGZus{}sec\PYGZus{}context\PYGZus{}by\PYGZus{}mech}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}OID} \PYG{n}{desired\PYGZus{}mech}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{interprocess\PYGZus{}token}\PYG{p}{,} \PYG{n}{gss\PYGZus{}ctx\PYGZus{}id\PYGZus{}t} \PYG{o}{*}\PYG{n}{context\PYGZus{}handle}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gssi\PYGZus{}import\PYGZus{}name\PYGZus{}by\PYGZus{}mech}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}OID} \PYG{n}{mech\PYGZus{}type}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{input\PYGZus{}name\PYGZus{}buffer}\PYG{p}{,} \PYG{n}{gss\PYGZus{}OID} \PYG{n}{input\PYGZus{}name\PYGZus{}type}\PYG{p}{,} \PYG{n}{gss\PYGZus{}name\PYGZus{}t} \PYG{n}{output\PYGZus{}name}\PYG{p}{)}\PYG{p}{;} \PYG{n}{OM\PYGZus{}uint32} \PYG{n}{gssi\PYGZus{}import\PYGZus{}cred\PYGZus{}by\PYGZus{}mech}\PYG{p}{(}\PYG{n}{OM\PYGZus{}uint32} \PYG{o}{*}\PYG{n}{minor\PYGZus{}status}\PYG{p}{,} \PYG{n}{gss\PYGZus{}OID} \PYG{n}{mech\PYGZus{}type}\PYG{p}{,} \PYG{n}{gss\PYGZus{}buffer\PYGZus{}t} \PYG{n}{token}\PYG{p}{,} \PYG{n}{gss\PYGZus{}cred\PYGZus{}id\PYGZus{}t} \PYG{o}{*}\PYG{n}{cred\PYGZus{}handle}\PYG{p}{)}\PYG{p}{;} \end{sphinxVerbatim} \sphinxAtStartPar To re\sphinxhyphen{}enter the original mechanism when importing tokens for the above functions, the interposer module must wrap the mechanism token in the mechglue’s format, using the concatenated OID (except in \sphinxstylestrong{gss\_import\_name}). The mechglue token formats are: \begin{itemize} \item {} \sphinxAtStartPar For \sphinxstylestrong{gss\_import\_sec\_context}, a four\sphinxhyphen{}byte OID length in big\sphinxhyphen{}endian order, followed by the concatenated OID, followed by the mechanism token. \item {} \sphinxAtStartPar For \sphinxstylestrong{gss\_import\_name}, the bytes 04 01, followed by a two\sphinxhyphen{}byte OID length in big\sphinxhyphen{}endian order, followed by the mechanism OID, followed by a four\sphinxhyphen{}byte token length in big\sphinxhyphen{}endian order, followed by the mechanism token. Unlike most uses of OIDs in the API, the mechanism OID encoding must include the DER tag and length for an object identifier (06 followed by the DER length of the OID byte string), and this prefix must be included in the two\sphinxhyphen{}byte OID length. input\_name\_type must also be set to GSS\_C\_NT\_EXPORT\_NAME. \item {} \sphinxAtStartPar For \sphinxstylestrong{gss\_import\_cred}, a four\sphinxhyphen{}byte OID length in big\sphinxhyphen{}endian order, followed by the concatenated OID, followed by a four\sphinxhyphen{}byte token length in big\sphinxhyphen{}endian order, followed by the mechanism token. This sequence may be repeated multiple times. \end{itemize} \sphinxstepscope \section{Internal pluggable interfaces} \label{\detokenize{plugindev/internal:internal-pluggable-interfaces}}\label{\detokenize{plugindev/internal::doc}} \sphinxAtStartPar Following are brief discussions of pluggable interfaces which have not yet been made public. These interfaces are functional, but the interfaces are likely to change in incompatible ways from release to release. In some cases, it may be necessary to copy header files from the krb5 source tree to use an internal interface. Use these with care, and expect to need to update your modules for each new release of MIT krb5. \subsection{Kerberos database interface (KDB)} \label{\detokenize{plugindev/internal:kerberos-database-interface-kdb}} \sphinxAtStartPar A KDB module implements a database back end for KDC principal and policy information, and can also control many aspects of KDC behavior. For a full description of the interface, see the header file \sphinxcode{\sphinxupquote{\textless{}kdb.h\textgreater{}}}. \sphinxAtStartPar The KDB pluggable interface is often referred to as the DAL (Database Access Layer). \subsection{Authorization data interface (authdata)} \label{\detokenize{plugindev/internal:authorization-data-interface-authdata}} \sphinxAtStartPar The authdata interface allows a module to provide (from the KDC) or consume (in application servers) authorization data of types beyond those handled by the core MIT krb5 code base. The interface is defined in the header file \sphinxcode{\sphinxupquote{\textless{}krb5/authdata\_plugin.h\textgreater{}}}, which is not installed by the build. \sphinxstepscope \section{PKINIT certificate authorization interface (certauth)} \label{\detokenize{plugindev/certauth:pkinit-certificate-authorization-interface-certauth}}\label{\detokenize{plugindev/certauth:certauth-plugin}}\label{\detokenize{plugindev/certauth::doc}} \sphinxAtStartPar The certauth interface was first introduced in release 1.16. It allows customization of the X.509 certificate attribute requirements placed on certificates used by PKINIT enabled clients. For a detailed description of the certauth interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/certauth\_plugin.h\textgreater{}}} \sphinxAtStartPar A certauth module implements the \sphinxstylestrong{authorize} method to determine whether a client’s certificate is authorized to authenticate a client principal. \sphinxstylestrong{authorize} receives the DER\sphinxhyphen{}encoded certificate, the requested client principal, and a pointer to the client’s krb5\_db\_entry (for modules that link against libkdb5). The method must decode the certificate and inspect its attributes to determine if it should authorize PKINIT authentication. It returns the authorization status and optionally outputs a list of authentication indicator strings to be added to the ticket. \sphinxAtStartPar Beginning in release 1.19, the authorize method can request that the hardware authentication bit be set in the ticket by returning \sphinxstylestrong{KRB5\_CERTAUTH\_HWAUTH}. Beginning in release 1.20, the authorize method can return \sphinxstylestrong{KRB5\_CERTAUTH\_HWAUTH\_PASS} to request that the hardware authentication bit be set in the ticket but otherwise defer authorization to another certauth module. A module must use its own internal or library\sphinxhyphen{}provided ASN.1 certificate decoder. \sphinxAtStartPar A module can optionally create and destroy module data with the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods. Module data objects last for the lifetime of the KDC process. \sphinxAtStartPar If a module allocates and returns a list of authentication indicators from \sphinxstylestrong{authorize}, it must also implement the \sphinxstylestrong{free\_ind} method to free the list. \sphinxstepscope \section{KDC policy interface (kdcpolicy)} \label{\detokenize{plugindev/kdcpolicy:kdc-policy-interface-kdcpolicy}}\label{\detokenize{plugindev/kdcpolicy:kdcpolicy-plugin}}\label{\detokenize{plugindev/kdcpolicy::doc}} \sphinxAtStartPar The kdcpolicy interface was first introduced in release 1.16. It allows modules to veto otherwise valid AS and TGS requests or restrict the lifetime and renew time of the resulting ticket. For a detailed description of the kdcpolicy interface, see the header file \sphinxcode{\sphinxupquote{\textless{}krb5/kdcpolicy\_plugin.h\textgreater{}}}. \sphinxAtStartPar The optional \sphinxstylestrong{check\_as} and \sphinxstylestrong{check\_tgs} functions allow the module to perform access control. Additionally, a module can create and destroy module data with the \sphinxstylestrong{init} and \sphinxstylestrong{fini} methods. Module data objects last for the lifetime of the KDC process, and are provided to all other methods. The data has the type krb5\_kdcpolicy\_moddata, which should be cast to the appropriate internal type. \sphinxAtStartPar kdcpolicy modules can optionally inspect principal entries. To do this, the module must also include \sphinxcode{\sphinxupquote{\textless{}kdb.h\textgreater{}}} to gain access to the principal entry structure definition. As the KDB interface is explicitly not as stable as other public interfaces, modules which do this may not retain compatibility across releases. \renewcommand{\indexname}{Index} \printindex \end{document}krb5-1.22.1/doc/pdf/sphinxlatexstyleheadings.sty0000664000175000017500000000656514577122106021575 0ustar ghudsonghudson%% TITLES % % change this info string if making any custom modification \ProvidesFile{sphinxlatexstyleheadings.sty}[2023/02/11 headings] \RequirePackage[nobottomtitles*]{titlesec} \@ifpackagelater{titlesec}{2016/03/15}% {\@ifpackagelater{titlesec}{2016/03/21}% {}% {\newif\ifsphinx@ttlpatch@ok \IfFileExists{etoolbox.sty}{% \RequirePackage{etoolbox}% \patchcmd{\ttlh@hang}{\parindent\z@}{\parindent\z@\leavevmode}% {\sphinx@ttlpatch@oktrue}{}% \ifsphinx@ttlpatch@ok \patchcmd{\ttlh@hang}{\noindent}{}{}{\sphinx@ttlpatch@okfalse}% \fi }{}% \ifsphinx@ttlpatch@ok \typeout{^^J Package Sphinx Info: ^^J **** titlesec 2.10.1 successfully patched for bugfix ****^^J}% \else \AtEndDocument{\PackageWarningNoLine{sphinx}{^^J% ******** titlesec 2.10.1 has a bug, (section numbers disappear) ......|^^J% ******** and Sphinx could not patch it, perhaps because your local ...|^^J% ******** copy is already fixed without a changed release date. .......|^^J% ******** If not, you must update titlesec! ...........................|}}% \sphinxbuildwarning{badtitlesec}% \fi }% }{} % Augment the sectioning commands used to get our own font family in place, % and reset some internal data items (\titleformat from titlesec package) \titleformat{\section}{\Large\py@HeaderFamily}% {\py@TitleColor\thesection}{0.5em}{\py@TitleColor} \titleformat{\subsection}{\large\py@HeaderFamily}% {\py@TitleColor\thesubsection}{0.5em}{\py@TitleColor} % \normalsize added as work-around to a lualatex-ja upstream problem % https://osdn.net/projects/luatex-ja/ticket/47321 \titleformat{\subsubsection}{\normalsize\py@HeaderFamily}% {\py@TitleColor\thesubsubsection}{0.5em}{\py@TitleColor} % By default paragraphs (and subsubsections) will not be numbered because % sphinxmanual.cls and sphinxhowto.cls set secnumdepth to 2 \titleformat{\paragraph}{\normalsize\py@HeaderFamily}% {\py@TitleColor\theparagraph}{0.5em}{\py@TitleColor} \titleformat{\subparagraph}{\normalsize\py@HeaderFamily}% {\py@TitleColor\thesubparagraph}{0.5em}{\py@TitleColor} % Since Sphinx 1.5, users should use HeaderFamily key to 'sphinxsetup' rather % than defining their own \py@HeaderFamily command (which is still possible). % Memo: \py@HeaderFamily is also used by \maketitle as defined in % sphinxmanual.cls/sphinxhowto.cls \newcommand{\py@HeaderFamily}{\spx@opt@HeaderFamily} % This sets up the fancy chapter headings that make the documents look % at least a little better than the usual LaTeX output. \@ifpackagewith{fncychap}{Bjarne}{ \ChNameVar {\raggedleft\normalsize \py@HeaderFamily} \ChNumVar {\raggedleft\Large \py@HeaderFamily} \ChTitleVar{\raggedleft\Large \py@HeaderFamily} % This creates (numbered) chapter heads without the leading \vspace*{}: \def\@makechapterhead#1{% {\parindent \z@ \raggedright \normalfont \ifnum \c@secnumdepth >\m@ne \if@mainmatter \DOCH \fi \fi \interlinepenalty\@M \if@mainmatter \DOTI{#1}% \else% \DOTIS{#1}% \fi }} }{}% <-- "false" clause of \@ifpackagewith % fix fncychap's bug which uses prematurely the \textwidth value \@ifpackagewith{fncychap}{Bjornstrup} {\AtBeginDocument{\mylen\textwidth\advance\mylen-2\myhi}}% {}% <-- "false" clause of \@ifpackagewith \endinput krb5-1.22.1/doc/pdf/basic.tex0000664000175000017500000007667315051422736015513 0ustar ghudsonghudson%% Generated by Sphinx. \def\sphinxdocclass{report} \documentclass[letterpaper,10pt,english]{sphinxmanual} \ifdefined\pdfpxdimen \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen \fi \sphinxpxdimen=.75bp\relax \ifdefined\pdfimageresolution \pdfimageresolution= \numexpr \dimexpr1in\relax/\sphinxpxdimen\relax \fi %% let collapsible pdf bookmarks panel have high depth per default \PassOptionsToPackage{bookmarksdepth=5}{hyperref} \PassOptionsToPackage{booktabs}{sphinx} \PassOptionsToPackage{colorrows}{sphinx} \PassOptionsToPackage{warn}{textcomp} \usepackage[utf8]{inputenc} \ifdefined\DeclareUnicodeCharacter % support both utf8 and utf8x syntaxes \ifdefined\DeclareUnicodeCharacterAsOptional \def\sphinxDUC#1{\DeclareUnicodeCharacter{"#1}} \else \let\sphinxDUC\DeclareUnicodeCharacter \fi \sphinxDUC{00A0}{\nobreakspace} \sphinxDUC{2500}{\sphinxunichar{2500}} \sphinxDUC{2502}{\sphinxunichar{2502}} \sphinxDUC{2514}{\sphinxunichar{2514}} \sphinxDUC{251C}{\sphinxunichar{251C}} \sphinxDUC{2572}{\textbackslash} \fi \usepackage{cmap} \usepackage[T1]{fontenc} \usepackage{amsmath,amssymb,amstext} \usepackage{babel} \usepackage{tgtermes} \usepackage{tgheros} \renewcommand{\ttdefault}{txtt} \usepackage[Bjarne]{fncychap} \usepackage{sphinx} \fvset{fontsize=auto} \usepackage{geometry} % Include hyperref last. \usepackage{hyperref} % Fix anchor placement for figures with captions. \usepackage{hypcap}% it must be loaded after hyperref. % Set up styles of URL: it should be placed after hyperref. \urlstyle{same} \usepackage{sphinxmessages} \setcounter{tocdepth}{0} \title{Kerberos Concepts} \date{ } \release{1.22.1} \author{MIT} \newcommand{\sphinxlogo}{\vbox{}} \renewcommand{\releasename}{Release} \makeindex \begin{document} \ifdefined\shorthandoff \ifnum\catcode`\=\string=\active\shorthandoff{=}\fi \ifnum\catcode`\"=\active\shorthandoff{"}\fi \fi \pagestyle{empty} \sphinxmaketitle \pagestyle{plain} \sphinxtableofcontents \pagestyle{normal} \phantomsection\label{\detokenize{basic/index::doc}} \sphinxstepscope \chapter{Credential cache} \label{\detokenize{basic/ccache_def:credential-cache}}\label{\detokenize{basic/ccache_def:ccache-definition}}\label{\detokenize{basic/ccache_def::doc}} \sphinxAtStartPar A credential cache (or “ccacheâ€) holds Kerberos credentials while they remain valid and, generally, while the user’s session lasts, so that authenticating to a service multiple times (e.g., connecting to a web or mail server more than once) doesn’t require contacting the KDC every time. \sphinxAtStartPar A credential cache usually contains one initial ticket which is obtained using a password or another form of identity verification. If this ticket is a ticket\sphinxhyphen{}granting ticket, it can be used to obtain additional credentials without the password. Because the credential cache does not store the password, less long\sphinxhyphen{}term damage can be done to the user’s account if the machine is compromised. \sphinxAtStartPar A credentials cache stores a default client principal name, set when the cache is created. This is the name shown at the top of the \DUrole{xref,std,std-ref}{klist(1)} \sphinxstyleemphasis{\sphinxhyphen{}A} output. \sphinxAtStartPar Each normal cache entry includes a service principal name, a client principal name (which, in some ccache types, need not be the same as the default), lifetime information, and flags, along with the credential itself. There are also other entries, indicated by special names, that store additional information. \section{ccache types} \label{\detokenize{basic/ccache_def:ccache-types}} \sphinxAtStartPar The credential cache interface, like the {\hyperref[\detokenize{basic/keytab_def:keytab-definition}]{\sphinxcrossref{\DUrole{std,std-ref}{keytab}}}} and {\hyperref[\detokenize{basic/rcache_def:rcache-definition}]{\sphinxcrossref{\DUrole{std,std-ref}{replay cache}}}} interfaces, uses \sphinxtitleref{TYPE:value} strings to indicate the type of credential cache and any associated cache naming data to use. \sphinxAtStartPar There are several kinds of credentials cache supported in the MIT Kerberos library. Not all are supported on every platform. In most cases, it should be correct to use the default type built into the library. \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar \sphinxstylestrong{API} is only implemented on Windows. It communicates with a server process that holds the credentials in memory for the user, rather than writing them to disk. \item {} \sphinxAtStartPar \sphinxstylestrong{DIR} points to the storage location of the collection of the credential caches in \sphinxstyleemphasis{FILE:} format. It is most useful when dealing with multiple Kerberos realms and KDCs. For release 1.10 the directory must already exist. In post\sphinxhyphen{}1.10 releases the requirement is for parent directory to exist and the current process must have permissions to create the directory if it does not exist. See {\hyperref[\detokenize{basic/ccache_def:col-ccache}]{\sphinxcrossref{\DUrole{std,std-ref}{Collections of caches}}}} for details. New in release 1.10. The following residual forms are supported: \begin{itemize} \item {} \sphinxAtStartPar DIR:dirname \item {} \sphinxAtStartPar DIR::dirpath/filename \sphinxhyphen{} a single cache within the directory \end{itemize} \sphinxAtStartPar Switching to a ccache of the latter type causes it to become the primary for the directory. \item {} \sphinxAtStartPar \sphinxstylestrong{FILE} caches are the simplest and most portable. A simple flat file format is used to store one credential after another. This is the default ccache type if no type is specified in a ccache name. \item {} \sphinxAtStartPar \sphinxstylestrong{KCM} caches work by contacting a daemon process called \sphinxcode{\sphinxupquote{kcm}} to perform cache operations. If the cache name is just \sphinxcode{\sphinxupquote{KCM:}}, the default cache as determined by the KCM daemon will be used. Newly created caches must generally be named \sphinxcode{\sphinxupquote{KCM:uid:name}}, where \sphinxstyleemphasis{uid} is the effective user ID of the running process. \sphinxAtStartPar KCM client support is new in release 1.13. A KCM daemon has not yet been implemented in MIT krb5, but the client will interoperate with the KCM daemon implemented by Heimdal. macOS 10.7 and higher provides a KCM daemon as part of the operating system, and the \sphinxstylestrong{KCM} cache type is used as the default cache on that platform in a default build. \item {} \sphinxAtStartPar \sphinxstylestrong{KEYRING} is Linux\sphinxhyphen{}specific, and uses the kernel keyring support to store credential data in unswappable kernel memory where only the current user should be able to access it. The following residual forms are supported: \begin{itemize} \item {} \sphinxAtStartPar KEYRING:name \item {} \sphinxAtStartPar KEYRING:process:name \sphinxhyphen{} process keyring \item {} \sphinxAtStartPar KEYRING:thread:name \sphinxhyphen{} thread keyring \end{itemize} \sphinxAtStartPar Starting with release 1.12 the \sphinxstyleemphasis{KEYRING} type supports collections. The following new residual forms were added: \begin{itemize} \item {} \sphinxAtStartPar KEYRING:session:name \sphinxhyphen{} session keyring \item {} \sphinxAtStartPar KEYRING:user:name \sphinxhyphen{} user keyring \item {} \sphinxAtStartPar KEYRING:persistent:uidnumber \sphinxhyphen{} persistent per\sphinxhyphen{}UID collection. Unlike the user keyring, this collection survives after the user logs out, until the cache credentials expire. This type of ccache requires support from the kernel; otherwise, it will fall back to the user keyring. \end{itemize} \sphinxAtStartPar See {\hyperref[\detokenize{basic/ccache_def:col-ccache}]{\sphinxcrossref{\DUrole{std,std-ref}{Collections of caches}}}} for details. \item {} \sphinxAtStartPar \sphinxstylestrong{MEMORY} caches are for storage of credentials that don’t need to be made available outside of the current process. For example, a memory ccache is used by \DUrole{xref,std,std-ref}{kadmin(1)} to store the administrative ticket used to contact the admin server. Memory ccaches are faster than file ccaches and are automatically destroyed when the process exits. \item {} \sphinxAtStartPar \sphinxstylestrong{MSLSA} is a Windows\sphinxhyphen{}specific cache type that accesses the Windows credential store. \end{enumerate} \section{Collections of caches} \label{\detokenize{basic/ccache_def:collections-of-caches}}\label{\detokenize{basic/ccache_def:col-ccache}} \sphinxAtStartPar Some credential cache types can support collections of multiple caches. One of the caches in the collection is designated as the \sphinxstyleemphasis{primary} and will be used when the collection is resolved as a cache. When a collection\sphinxhyphen{}enabled cache type is the default cache for a process, applications can search the specified collection for a specific client principal, and GSSAPI applications will automatically select between the caches in the collection based on criteria such as the target service realm. \sphinxAtStartPar Credential cache collections are new in release 1.10, with support from the \sphinxstylestrong{DIR} and \sphinxstylestrong{API} ccache types. Starting in release 1.12, collections are also supported by the \sphinxstylestrong{KEYRING} ccache type. Collections are supported by the \sphinxstylestrong{KCM} ccache type in release 1.13. \subsection{Tool alterations to use cache collection} \label{\detokenize{basic/ccache_def:tool-alterations-to-use-cache-collection}}\begin{itemize} \item {} \sphinxAtStartPar \DUrole{xref,std,std-ref}{kdestroy(1)} \sphinxstyleemphasis{\sphinxhyphen{}A} will destroy all caches in the collection. \item {} \sphinxAtStartPar If the default cache type supports switching, \DUrole{xref,std,std-ref}{kinit(1)} \sphinxstyleemphasis{princname} will search the collection for a matching cache and store credentials there, or will store credentials in a new unique cache of the default type if no existing cache for the principal exists. Either way, kinit will switch to the selected cache. \item {} \sphinxAtStartPar \DUrole{xref,std,std-ref}{klist(1)} \sphinxstyleemphasis{\sphinxhyphen{}l} will list the caches in the collection. \item {} \sphinxAtStartPar \DUrole{xref,std,std-ref}{klist(1)} \sphinxstyleemphasis{\sphinxhyphen{}A} will show the content of all caches in the collection. \item {} \sphinxAtStartPar \DUrole{xref,std,std-ref}{kswitch(1)} \sphinxstyleemphasis{\sphinxhyphen{}p princname} will search the collection for a matching cache and switch to it. \item {} \sphinxAtStartPar \DUrole{xref,std,std-ref}{kswitch(1)} \sphinxstyleemphasis{\sphinxhyphen{}c cachename} will switch to a specified cache. \end{itemize} \section{Default ccache name} \label{\detokenize{basic/ccache_def:default-ccache-name}} \sphinxAtStartPar The default credential cache name is determined by the following, in descending order of priority: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar The \sphinxstylestrong{KRB5CCNAME} environment variable. For example, \sphinxcode{\sphinxupquote{KRB5CCNAME=DIR:/mydir/}}. \item {} \sphinxAtStartPar The \sphinxstylestrong{default\_ccache\_name} profile variable in \DUrole{xref,std,std-ref}{libdefaults}. \item {} \sphinxAtStartPar The hardcoded default, \DUrole{xref,std,std-ref}{DEFCCNAME}. \end{enumerate} \sphinxstepscope \chapter{keytab} \label{\detokenize{basic/keytab_def:keytab}}\label{\detokenize{basic/keytab_def:keytab-definition}}\label{\detokenize{basic/keytab_def::doc}} \sphinxAtStartPar A keytab (short for “key tableâ€) stores long\sphinxhyphen{}term keys for one or more principals. Keytabs are normally represented by files in a standard format, although in rare cases they can be represented in other ways. Keytabs are used most often to allow server applications to accept authentications from clients, but can also be used to obtain initial credentials for client applications. \sphinxAtStartPar Keytabs are named using the format \sphinxstyleemphasis{type}\sphinxcode{\sphinxupquote{:}}\sphinxstyleemphasis{value}. Usually \sphinxstyleemphasis{type} is \sphinxcode{\sphinxupquote{FILE}} and \sphinxstyleemphasis{value} is the absolute pathname of the file. The other possible value for \sphinxstyleemphasis{type} is \sphinxcode{\sphinxupquote{MEMORY}}, which indicates a temporary keytab stored in the memory of the current process. \sphinxAtStartPar A keytab contains one or more entries, where each entry consists of a timestamp (indicating when the entry was written to the keytab), a principal name, a key version number, an encryption type, and the encryption key itself. \sphinxAtStartPar A keytab can be displayed using the \DUrole{xref,std,std-ref}{klist(1)} command with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}k}} option. Keytabs can be created or appended to by extracting keys from the KDC database using the \DUrole{xref,std,std-ref}{kadmin(1)} \DUrole{xref,std,std-ref}{ktadd} command. Keytabs can be manipulated using the \DUrole{xref,std,std-ref}{ktutil(1)} and \DUrole{xref,std,std-ref}{k5srvutil(1)} commands. \section{Default keytab} \label{\detokenize{basic/keytab_def:default-keytab}} \sphinxAtStartPar The default keytab is used by server applications if the application does not request a specific keytab. The name of the default keytab is determined by the following, in decreasing order of preference: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar The \sphinxstylestrong{KRB5\_KTNAME} environment variable. \item {} \sphinxAtStartPar The \sphinxstylestrong{default\_keytab\_name} profile variable in \DUrole{xref,std,std-ref}{libdefaults}. \item {} \sphinxAtStartPar The hardcoded default, \DUrole{xref,std,std-ref}{DEFKTNAME}. \end{enumerate} \section{Default client keytab} \label{\detokenize{basic/keytab_def:default-client-keytab}} \sphinxAtStartPar The default client keytab is used, if it is present and readable, to automatically obtain initial credentials for GSSAPI client applications. The principal name of the first entry in the client keytab is used by default when obtaining initial credentials. The name of the default client keytab is determined by the following, in decreasing order of preference: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar The \sphinxstylestrong{KRB5\_CLIENT\_KTNAME} environment variable. \item {} \sphinxAtStartPar The \sphinxstylestrong{default\_client\_keytab\_name} profile variable in \DUrole{xref,std,std-ref}{libdefaults}. \item {} \sphinxAtStartPar The hardcoded default, \DUrole{xref,std,std-ref}{DEFCKTNAME}. \end{enumerate} \sphinxstepscope \chapter{replay cache} \label{\detokenize{basic/rcache_def:replay-cache}}\label{\detokenize{basic/rcache_def:rcache-definition}}\label{\detokenize{basic/rcache_def::doc}} \sphinxAtStartPar A replay cache (or “rcacheâ€) keeps track of all authenticators recently presented to a service. If a duplicate authentication request is detected in the replay cache, an error message is sent to the application program. \sphinxAtStartPar The replay cache interface, like the credential cache and {\hyperref[\detokenize{basic/keytab_def:keytab-definition}]{\sphinxcrossref{\DUrole{std,std-ref}{keytab}}}} interfaces, uses \sphinxtitleref{type:residual} strings to indicate the type of replay cache and any associated cache naming data to use. \section{Background information} \label{\detokenize{basic/rcache_def:background-information}} \sphinxAtStartPar Some Kerberos or GSSAPI services use a simple authentication mechanism where a message is sent containing an authenticator, which establishes the encryption key that the client will use for talking to the service. But nothing about that prevents an eavesdropper from recording the messages sent by the client, establishing a new connection, and re\sphinxhyphen{}sending or “replaying†the same messages; the replayed authenticator will establish the same encryption key for the new session, and the following messages will be decrypted and processed. The attacker may not know what the messages say, and can’t generate new messages under the same encryption key, but in some instances it may be harmful to the user (or helpful to the attacker) to cause the server to see the same messages again a second time. For example, if the legitimate client sends “delete first message in mailboxâ€, a replay from an attacker may delete another, different “first†message. (Protocol design to guard against such problems has been discussed in \index{RFC@\spxentry{RFC}!RFC 4120\#section\sphinxhyphen{}10@\spxentry{RFC 4120\#section\sphinxhyphen{}10}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc4120.html\#section-10}{\sphinxstylestrong{RFC 4120\#section\sphinxhyphen{}10}}.) \sphinxAtStartPar Even if one protocol uses further protection to verify that the client side of the connection actually knows the encryption keys (and thus is presumably a legitimate user), if another service uses the same service principal name, it may be possible to record an authenticator used with the first protocol and “replay†it against the second. \sphinxAtStartPar The replay cache mitigates these attacks somewhat, by keeping track of authenticators that have been seen until their five\sphinxhyphen{}minute window expires. Different authenticators generated by multiple connections from the same legitimate client will generally have different timestamps, and thus will not be considered the same. \sphinxAtStartPar This mechanism isn’t perfect. If a message is sent to one application server but a man\sphinxhyphen{}in\sphinxhyphen{}the\sphinxhyphen{}middle attacker can prevent it from actually arriving at that server, the attacker could then use the authenticator (once!) against a different service on the same host. This could be a problem if the message from the client included something more than authentication in the first message that could be useful to the attacker (which is uncommon; in most protocols the server has to indicate a successful authentication before the client sends additional messages), or if the simple act of presenting the authenticator triggers some interesting action in the service being attacked. \section{Replay cache types} \label{\detokenize{basic/rcache_def:replay-cache-types}} \sphinxAtStartPar Unlike the credential cache and keytab interfaces, replay cache types are in lowercase. The following types are defined: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar \sphinxstylestrong{none} disables the replay cache. The residual value is ignored. \item {} \sphinxAtStartPar \sphinxstylestrong{file2} (new in release 1.18) uses a hash\sphinxhyphen{}based format to store replay records. The file may grow to accommodate hash collisions. The residual value is the filename. \item {} \sphinxAtStartPar \sphinxstylestrong{dfl} is the default type if no environment variable or configuration specifies a different type. It stores replay data in a file2 replay cache with a filename based on the effective uid. The residual value is ignored. \end{enumerate} \sphinxAtStartPar For the dfl type, the location of the replay cache file is determined as follows: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar The directory is taken from the \sphinxstylestrong{KRB5RCACHEDIR} environment variable, or the \sphinxstylestrong{TMPDIR} environment variable, or a temporary directory determined at configuration time such as \sphinxcode{\sphinxupquote{/var/tmp}}, in descending order of preference. \item {} \sphinxAtStartPar The filename is \sphinxcode{\sphinxupquote{krb5\_EUID.rcache2}} where EUID is the effective uid of the process. \item {} \sphinxAtStartPar The file is opened without following symbolic links, and ownership of the file is verified to match the effective uid. \end{enumerate} \sphinxAtStartPar On Windows, the directory for the dfl type is the local appdata directory, unless overridden by the \sphinxstylestrong{KRB5RCACHEDIR} environment variable. The filename on Windows is \sphinxcode{\sphinxupquote{krb5.rcache2}}, and the file is opened normally. \section{Default replay cache name} \label{\detokenize{basic/rcache_def:default-replay-cache-name}} \sphinxAtStartPar The default replay cache name is determined by the following, in descending order of priority: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar The \sphinxstylestrong{KRB5RCACHENAME} environment variable (new in release 1.18). \item {} \sphinxAtStartPar The \sphinxstylestrong{KRB5RCACHETYPE} environment variable. If this variable is set, the residual value is empty. \item {} \sphinxAtStartPar The \sphinxstylestrong{default\_rcache\_name} profile variable in \DUrole{xref,std,std-ref}{libdefaults} (new in release 1.18). \item {} \sphinxAtStartPar If none of the above are set, the default replay cache name is \sphinxcode{\sphinxupquote{dfl:}}. \end{enumerate} \sphinxstepscope \chapter{stash file} \label{\detokenize{basic/stash_file_def:stash-file}}\label{\detokenize{basic/stash_file_def:stash-definition}}\label{\detokenize{basic/stash_file_def::doc}} \sphinxAtStartPar The stash file is a local copy of the master key that resides in encrypted form on the KDC’s local disk. The stash file is used to authenticate the KDC to itself automatically before starting the \DUrole{xref,std,std-ref}{kadmind(8)} and \DUrole{xref,std,std-ref}{krb5kdc(8)} daemons (e.g., as part of the machine’s boot sequence). The stash file, like the keytab file (see \DUrole{xref,std,std-ref}{keytab\_file}) is a potential point\sphinxhyphen{}of\sphinxhyphen{}entry for a break\sphinxhyphen{}in, and if compromised, would allow unrestricted access to the Kerberos database. If you choose to install a stash file, it should be readable only by root, and should exist only on the KDC’s local disk. The file should not be part of any backup of the machine, unless access to the backup data is secured as tightly as access to the master password itself. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If you choose not to install a stash file, the KDC will prompt you for the master key each time it starts up. This means that the KDC will not be able to start automatically, such as after a system reboot. \end{sphinxadmonition} \sphinxstepscope \chapter{Supported date and time formats} \label{\detokenize{basic/date_format:supported-date-and-time-formats}}\label{\detokenize{basic/date_format:datetime}}\label{\detokenize{basic/date_format::doc}} \section{Time duration} \label{\detokenize{basic/date_format:time-duration}}\label{\detokenize{basic/date_format:duration}} \sphinxAtStartPar This format is used to express a time duration in the Kerberos configuration files and user commands. The allowed formats are: \begin{quote} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TTT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar Format & \sphinxAtStartPar Example & \sphinxAtStartPar Value \\ \sphinxhline \sphinxAtStartPar h:m{[}:s{]} & \sphinxAtStartPar 36:00 & \sphinxAtStartPar 36 hours \\ \sphinxhline \sphinxAtStartPar NdNhNmNs & \sphinxAtStartPar 8h30s & \sphinxAtStartPar 8 hours 30 seconds \\ \sphinxhline \sphinxAtStartPar N (number of seconds) & \sphinxAtStartPar 3600 & \sphinxAtStartPar 1 hour \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \end{quote} \sphinxAtStartPar Here \sphinxstyleemphasis{N} denotes a number, \sphinxstyleemphasis{d} \sphinxhyphen{} days, \sphinxstyleemphasis{h} \sphinxhyphen{} hours, \sphinxstyleemphasis{m} \sphinxhyphen{} minutes, \sphinxstyleemphasis{s} \sphinxhyphen{} seconds. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The time interval should not exceed 2147483647 seconds. \end{sphinxadmonition} \sphinxAtStartPar Examples: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{Request} \PYG{n}{a} \PYG{n}{ticket} \PYG{n}{valid} \PYG{k}{for} \PYG{n}{one} \PYG{n}{hour}\PYG{p}{,} \PYG{n}{five} \PYG{n}{hours}\PYG{p}{,} \PYG{l+m+mi}{30} \PYG{n}{minutes} \PYG{o+ow}{and} \PYG{l+m+mi}{10} \PYG{n}{days} \PYG{n}{respectively}\PYG{p}{:} \PYG{n}{kinit} \PYG{o}{\PYGZhy{}}\PYG{n}{l} \PYG{l+m+mi}{3600} \PYG{n}{kinit} \PYG{o}{\PYGZhy{}}\PYG{n}{l} \PYG{l+m+mi}{5}\PYG{p}{:}\PYG{l+m+mi}{00} \PYG{n}{kinit} \PYG{o}{\PYGZhy{}}\PYG{n}{l} \PYG{l+m+mi}{30}\PYG{n}{m} \PYG{n}{kinit} \PYG{o}{\PYGZhy{}}\PYG{n}{l} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{10d 0h 0m 0s}\PYG{l+s+s2}{\PYGZdq{}} \end{sphinxVerbatim} \section{getdate time} \label{\detokenize{basic/date_format:getdate-time}}\label{\detokenize{basic/date_format:getdate}} \sphinxAtStartPar Some of the kadmin and kdb5\_util commands take a date\sphinxhyphen{}time in a human\sphinxhyphen{}readable format. Some of the acceptable date\sphinxhyphen{}time strings are: \begin{quote} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TTT} \sphinxtoprule \sphinxstyletheadfamily &\sphinxstyletheadfamily \sphinxAtStartPar Format &\sphinxstyletheadfamily \sphinxAtStartPar Example \\ \sphinxmidrule \sphinxtableatstartofbodyhook\sphinxmultirow{3}{4}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{3}} \sphinxAtStartPar Date \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% & \sphinxAtStartPar mm/dd/yy & \sphinxAtStartPar 07/27/12 \\ \sphinxcline{2-3}\sphinxfixclines{3}\sphinxtablestrut{4}& \sphinxAtStartPar month dd, yyyy & \sphinxAtStartPar Jul 27, 2012 \\ \sphinxcline{2-3}\sphinxfixclines{3}\sphinxtablestrut{4}& \sphinxAtStartPar yyyy\sphinxhyphen{}mm\sphinxhyphen{}dd & \sphinxAtStartPar 2012\sphinxhyphen{}07\sphinxhyphen{}27 \\ \sphinxhline\sphinxmultirow{2}{11}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{3}} \sphinxAtStartPar Absolute time \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% & \sphinxAtStartPar HH:mm{[}:ss{]}pp & \sphinxAtStartPar 08:30 PM \\ \sphinxcline{2-3}\sphinxfixclines{3}\sphinxtablestrut{11}& \sphinxAtStartPar hh:mm{[}:ss{]} & \sphinxAtStartPar 20:30 \\ \sphinxhline \sphinxAtStartPar Relative time & \sphinxAtStartPar N tt & \sphinxAtStartPar 30 sec \\ \sphinxhline\sphinxmultirow{2}{19}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{3}} \sphinxAtStartPar Time zone \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% & \sphinxAtStartPar Z & \sphinxAtStartPar EST \\ \sphinxcline{2-3}\sphinxfixclines{3}\sphinxtablestrut{19}& \sphinxAtStartPar z & \sphinxAtStartPar \sphinxhyphen{}0400 \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \end{quote} \sphinxAtStartPar (See {\hyperref[\detokenize{basic/date_format:abbreviation}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations used in this document}}}}.) \sphinxAtStartPar Examples: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{Create} \PYG{n}{a} \PYG{n}{principal} \PYG{n}{that} \PYG{n}{expires} \PYG{n}{on} \PYG{n}{the} \PYG{n}{date} \PYG{n}{indicated}\PYG{p}{:} \PYG{n}{addprinc} \PYG{n}{test1} \PYG{o}{\PYGZhy{}}\PYG{n}{expire} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{3/27/12 10:00:07 EST}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{addprinc} \PYG{n}{test2} \PYG{o}{\PYGZhy{}}\PYG{n}{expire} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{January 23, 2015 10:05pm}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{addprinc} \PYG{n}{test3} \PYG{o}{\PYGZhy{}}\PYG{n}{expire} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{22:00 GMT}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{Add} \PYG{n}{a} \PYG{n}{principal} \PYG{n}{that} \PYG{n}{will} \PYG{n}{expire} \PYG{o+ow}{in} \PYG{l+m+mi}{30} \PYG{n}{minutes}\PYG{p}{:} \PYG{n}{addprinc} \PYG{n}{test4} \PYG{o}{\PYGZhy{}}\PYG{n}{expire} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{30 minutes}\PYG{l+s+s2}{\PYGZdq{}} \end{sphinxVerbatim} \section{Absolute time} \label{\detokenize{basic/date_format:absolute-time}}\label{\detokenize{basic/date_format:abstime}} \sphinxAtStartPar This rarely used date\sphinxhyphen{}time format can be noted in one of the following ways: \begin{quote} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TTT} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar Format &\sphinxstyletheadfamily \sphinxAtStartPar Example &\sphinxstyletheadfamily \sphinxAtStartPar Value \\ \sphinxmidrule \sphinxtableatstartofbodyhook \sphinxAtStartPar yyyymmddhhmmss & \sphinxAtStartPar 20141231235900 &\sphinxmultirow{5}{6}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{3}} \sphinxAtStartPar One minute before 2015 \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% \\ \sphinxcline{1-2}\sphinxfixclines{3} \sphinxAtStartPar yyyy.mm.dd.hh.mm.ss & \sphinxAtStartPar 2014.12.31.23.59.00 &\sphinxtablestrut{6}\\ \sphinxcline{1-2}\sphinxfixclines{3} \sphinxAtStartPar yymmddhhmmss & \sphinxAtStartPar 141231235900 &\sphinxtablestrut{6}\\ \sphinxcline{1-2}\sphinxfixclines{3} \sphinxAtStartPar yy.mm.dd.hh.mm.ss & \sphinxAtStartPar 14.12.31.23.59.00 &\sphinxtablestrut{6}\\ \sphinxcline{1-2}\sphinxfixclines{3} \sphinxAtStartPar dd\sphinxhyphen{}month\sphinxhyphen{}yyyy:hh:mm:ss & \sphinxAtStartPar 31\sphinxhyphen{}Dec\sphinxhyphen{}2014:23:59:00 &\sphinxtablestrut{6}\\ \sphinxhline \sphinxAtStartPar hh:mm:ss & \sphinxAtStartPar 20:00:00 &\sphinxmultirow{2}{17}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{3}} \sphinxAtStartPar 8 o’clock in the evening \par \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% \\ \sphinxcline{1-2}\sphinxfixclines{3} \sphinxAtStartPar hhmmss & \sphinxAtStartPar 200000 &\sphinxtablestrut{17}\\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \end{quote} \sphinxAtStartPar (See {\hyperref[\detokenize{basic/date_format:abbreviation}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations used in this document}}}}.) \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{Set} \PYG{n}{the} \PYG{n}{default} \PYG{n}{expiration} \PYG{n}{date} \PYG{n}{to} \PYG{n}{July} \PYG{l+m+mi}{27}\PYG{p}{,} \PYG{l+m+mi}{2012} \PYG{n}{at} \PYG{l+m+mi}{20}\PYG{p}{:}\PYG{l+m+mi}{30} \PYG{n}{default\PYGZus{}principal\PYGZus{}expiration} \PYG{o}{=} \PYG{l+m+mi}{20120727203000} \end{sphinxVerbatim} \subsection{Abbreviations used in this document} \label{\detokenize{basic/date_format:abbreviations-used-in-this-document}}\label{\detokenize{basic/date_format:abbreviation}} \begin{DUlineblock}{0em} \item[] \sphinxstyleemphasis{month} : locale’s month name or its abbreviation; \item[] \sphinxstyleemphasis{dd} : day of month (01\sphinxhyphen{}31); \item[] \sphinxstyleemphasis{HH} : hours (00\sphinxhyphen{}12); \item[] \sphinxstyleemphasis{hh} : hours (00\sphinxhyphen{}23); \item[] \sphinxstyleemphasis{mm} : in time \sphinxhyphen{} minutes (00\sphinxhyphen{}59); in date \sphinxhyphen{} month (01\sphinxhyphen{}12); \item[] \sphinxstyleemphasis{N} : number; \item[] \sphinxstyleemphasis{pp} : AM or PM; \item[] \sphinxstyleemphasis{ss} : seconds (00\sphinxhyphen{}60); \item[] \sphinxstyleemphasis{tt} : time units (hours, minutes, min, seconds, sec); \item[] \sphinxstyleemphasis{yyyy} : year; \item[] \sphinxstyleemphasis{yy} : last two digits of the year; \item[] \sphinxstyleemphasis{Z} : alphabetic time zone abbreviation; \item[] \sphinxstyleemphasis{z} : numeric time zone; \end{DUlineblock} \begin{sphinxadmonition}{note}{Note:}\begin{itemize} \item {} \sphinxAtStartPar If the date specification contains spaces, you may need to enclose it in double quotes; \item {} \sphinxAtStartPar All keywords are case\sphinxhyphen{}insensitive. \end{itemize} \end{sphinxadmonition} \renewcommand{\indexname}{Index} \printindex \end{document}krb5-1.22.1/doc/pdf/sphinxpackagefootnote.sty0000664000175000017500000003562614577122106021045 0ustar ghudsonghudson\NeedsTeXFormat{LaTeX2e} \ProvidesPackage{sphinxpackagefootnote}% [2022/08/15 v5.3.0 Sphinx custom footnotehyper package (Sphinx team)] %% %% Package: sphinxpackagefootnote %% Version: based on footnotehyper.sty 2021/02/04 v1.1d %% https://www.ctan.org/pkg/footnotehyper %% License: the one applying to Sphinx %% % Provides support for footnote mark-up from Sphinx latex writer: % - "footnote" and "footnotetext" environments allowing verbatim material % - "savenotes" environment for wrapping environments, such as for tables % which have problems with LaTeX footnotes % - hyperlinks % % Sphinx uses exclusively this mark-up for footnotes: % - \begin{footnote}[N] % - \begin{footnotetext}[N] % - \sphinxfootnotemark[N] % where N is a number. % %% Some small differences from upstream footnotehyper.sty: %% - a tabulary compatibility layer (partial but enough for Sphinx), %% - usage of \spx@opt@BeforeFootnote %% - usage of \sphinxunactivateextrasandspace from sphinx.sty, %% - \sphinxlongtablepatch %% %% Starting with Sphinx v4.5.0, inherited footnotehyper macros for %% footnote/footnotetext receive some Sphinx specific extras to %% implement "intelligent" footnote marks checking page numbers. %% %% All footnotes output from Sphinx are hyperlinked. With "savenotes" %% footnotes may appear on page distinct from footnote mark, the latter %% will indicate page number of the footnote. \newif\iffootnotehyperparse\footnotehyperparsetrue \DeclareOption*{\PackageWarning{sphinxpackagefootnote}{Option `\CurrentOption' is unknown}}% \ProcessOptions\relax \newbox\FNH@notes \newtoks\FNH@toks % 1.1c \newdimen\FNH@width \let\FNH@colwidth\columnwidth \newif\ifFNH@savingnotes \AtBeginDocument {% \let\FNH@latex@footnote \footnote \let\FNH@latex@footnotetext\footnotetext \let\FNH@H@@footnotetext \@footnotetext \let\FNH@H@@mpfootnotetext \@mpfootnotetext \newenvironment{savenotes} {\FNH@savenotes\ignorespaces}{\FNH@spewnotes\ignorespacesafterend}% \let\spewnotes \FNH@spewnotes \let\footnote \FNH@footnote \let\footnotetext \FNH@footnotetext \let\endfootnote \FNH@endfntext \let\endfootnotetext\FNH@endfntext % always True branch taken with Sphinx \@ifpackageloaded{hyperref} {\ifHy@hyperfootnotes \let\FNH@H@@footnotetext\H@@footnotetext \let\FNH@H@@mpfootnotetext\H@@mpfootnotetext \else \let\FNH@hyper@fntext\FNH@nohyp@fntext \fi}% {\let\FNH@hyper@fntext\FNH@nohyp@fntext}% }% \def\FNH@hyper@fntext{\FNH@fntext\FNH@hyper@fntext@i}% \def\FNH@nohyp@fntext{\FNH@fntext\FNH@nohyp@fntext@i}% \def\FNH@fntext #1{% \ifx\ifmeasuring@\@undefined \expandafter\@secondoftwo\else\expandafter\@firstofone\fi % these two lines modified for Sphinx (tabulary compatibility): {\ifmeasuring@\expandafter\@gobbletwo\else\expandafter\@firstofone\fi}% {\ifx\equation$\expandafter\@gobbletwo\fi #1}%$ }% \long\def\FNH@hyper@fntext@i#1{% \global\setbox\FNH@notes\vbox {\unvbox\FNH@notes \FNH@startnote \@makefntext {\rule\z@\footnotesep\ignorespaces \ifHy@nesting\expandafter\ltx@firstoftwo \else\expandafter\ltx@secondoftwo \fi {\expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}{#1}}% {\Hy@raisedlink {\expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}% {\relax}}% \let\@currentHref\Hy@footnote@currentHref \let\@currentlabelname\@empty #1}% \@finalstrut\strutbox }% \FNH@endnote }% }% \long\def\FNH@nohyp@fntext@i#1{% \global\setbox\FNH@notes\vbox {\unvbox\FNH@notes \FNH@startnote \@makefntext{\rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% \FNH@endnote }% }% \def\FNH@startnote{% \hsize\FNH@colwidth \interlinepenalty\interfootnotelinepenalty \reset@font\footnotesize \floatingpenalty\@MM \@parboxrestore \protected@edef\@currentlabel{\csname p@\@mpfn\endcsname\@thefnmark}% \color@begingroup }% \def\FNH@endnote{\color@endgroup}% \def\FNH@savenotes{% \begingroup \ifFNH@savingnotes\else \FNH@savingnotestrue \let\@footnotetext \FNH@hyper@fntext \let\@mpfootnotetext \FNH@hyper@fntext \let\H@@mpfootnotetext\FNH@nohyp@fntext \FNH@width\columnwidth \let\FNH@colwidth\FNH@width \global\setbox\FNH@notes\box\voidb@x \let\FNH@thempfn\thempfn \let\FNH@mpfn\@mpfn \ifx\@minipagerestore\relax\let\@minipagerestore\@empty\fi \expandafter\def\expandafter\@minipagerestore\expandafter{% \@minipagerestore \let\thempfn\FNH@thempfn \let\@mpfn\FNH@mpfn }% \fi }% \def\FNH@spewnotes {% \if@endpe\ifx\par\@@par\FNH@toks{}\else \FNH@toks\expandafter{\expandafter \def\expandafter\par\expandafter{\par}\@endpetrue}% \expandafter\expandafter\expandafter \FNH@toks \expandafter\expandafter\expandafter {\expandafter\the\expandafter\FNH@toks \expandafter\def\expandafter\@par\expandafter{\@par}}% \expandafter\expandafter\expandafter \FNH@toks \expandafter\expandafter\expandafter {\expandafter\the\expandafter\FNH@toks \expandafter\everypar\expandafter{\the\everypar}}\fi \else\FNH@toks{}\fi \expandafter \endgroup\the\FNH@toks \ifFNH@savingnotes\else \ifvoid\FNH@notes\else \begingroup \let\@makefntext\@empty \let\@finalstrut\@gobble \let\rule\@gobbletwo \ifx\@footnotetext\@mpfootnotetext \expandafter\FNH@H@@mpfootnotetext \else \expandafter\FNH@H@@footnotetext \fi{\unvbox\FNH@notes}% \endgroup \fi \fi }% \def\FNH@footnote@envname {footnote}% \def\FNH@footnotetext@envname{footnotetext}% \def\FNH@footnote{% % this line added for Sphinx: \spx@opt@BeforeFootnote \ifx\@currenvir\FNH@footnote@envname \expandafter\FNH@footnoteenv \else \expandafter\FNH@latex@footnote \fi }% \def\FNH@footnoteenv{% % this line added for Sphinx (footnotes in parsed literal blocks): \catcode13=5 \sphinxunactivateextrasandspace \@ifnextchar[% \FNH@footnoteenv@i %] {\stepcounter\@mpfn \protected@xdef\@thefnmark{\thempfn}% \@footnotemark \def\FNH@endfntext@fntext{\@footnotetext}% \FNH@startfntext}% }% \def\FNH@footnoteenv@i[#1]{% \begingroup % This legacy code from LaTeX core restricts #1 to be digits only % This limitation could be lifted but legacy Sphinx anyhow obeys it \csname c@\@mpfn\endcsname #1\relax \unrestored@protected@xdef\@thefnmark{\thempfn}% \endgroup % -- Sphinx specific: % currently commented out due to % https://github.com/sphinx-doc/sphinx/pull/10191#issuecomment-1038807448 % Memo: memoir class detection of successive footnote marks (to separate them % by commas) is broken by \refstepcounter and also by \label, and some % mitigation such as in \sphinxfootref would be needed % \global\let\spx@saved@thefnmark\@thefnmark % % this is done to access robustly the page number where footnote mark is % \refstepcounter{sphinxfootnotemark}\label{footnotemark.\thesphinxfootnotemark}% % % if possible, compare page numbers of mark and footnote to define \@thefnmark % \ltx@ifundefined{r@\thesphinxscope.footnote.#1}% % {}% one more latex run is needed % {\sphinx@xdef@thefnmark{#1}}% check of page numbers possible % -- \@footnotemark \def\FNH@endfntext@fntext{\@footnotetext}% % -- Sphinx specific: % we need to reset \@thefnmark as it is used by \FNH@startfntext via % \FNH@startnote to set \@currentlabel which will be used by \label % currently commented out (see above) % \global\let\@thefnmark\spx@saved@thefnmark % -- \FNH@startfntext % -- again Sphinx specific % \@currentlabel as needed by \label got set by \FNH@startnote % insert this at start of footnote text then the label will allow % to robustly know on which page the footnote text ends up % currently only of use for extra footnote marks so in case footnote multiply referred \phantomsection\label{\thesphinxscope.footnote.#1}% }% \def\FNH@footnotetext{% \ifx\@currenvir\FNH@footnotetext@envname \expandafter\FNH@footnotetextenv \else \expandafter\FNH@latex@footnotetext \fi }% \def\FNH@footnotetextenv{% \@ifnextchar[% \FNH@footnotetextenv@i %] {\protected@xdef\@thefnmark{\thempfn}% \def\FNH@endfntext@fntext{\@footnotetext}% \FNH@startfntext}% }% \def\FNH@footnotetextenv@i[#1]{% \begingroup \csname c@\@mpfn\endcsname #1\relax \unrestored@protected@xdef\@thefnmark{\thempfn}% \endgroup \ifFNH@savingnotes \def\FNH@endfntext@fntext{\FNH@nohyp@fntext}% \else \def\FNH@endfntext@fntext{\FNH@H@@footnotetext}% \fi \FNH@startfntext % -- Sphinx specific addition \phantomsection\label{\thesphinxscope.footnote.#1}% }% \def\FNH@startfntext{% \setbox\z@\vbox\bgroup \FNH@startnote \FNH@prefntext \rule\z@\footnotesep\ignorespaces }% \def\FNH@endfntext {% \@finalstrut\strutbox \FNH@postfntext \FNH@endnote \egroup \begingroup \let\@makefntext\@empty\let\@finalstrut\@gobble\let\rule\@gobbletwo \FNH@endfntext@fntext {\unvbox\z@}% \endgroup }% \let\FNH@prefntext\@empty \let\FNH@postfntext\@empty \AtBeginDocument{\iffootnotehyperparse\expandafter\FNH@check\fi}% \def\FNH@safeif#1{% \iftrue\csname if#1\endcsname\csname fi\endcsname\expandafter\@firstoftwo \else\csname fi\endcsname\expandafter\@secondoftwo \fi }% \def\FNH@check{% \ifx\@makefntextFB\@undefined\expandafter\FNH@check@ \else\expandafter\FNH@frenchb@ \fi }% \def\FNH@frenchb@{% \def\FNH@prefntext{% \localleftbox{}% \let\FBeverypar@save\FBeverypar@quote \let\FBeverypar@quote\relax \FNH@safeif{FB@koma}% {\FNH@safeif{FBFrenchFootnotes}% {\ifx\footnote\thanks \let\@@makefnmark\@@makefnmarkTH \@makefntextTH{} % space as in french.ldf \else \let\@@makefnmark\@@makefnmarkFB \@makefntextFB{} % space as in french.ldf \fi }{\let\@@makefnmark\@@makefnmarkORI \@makefntextORI{}% no space as in french.ldf }% }% {\FNH@safeif{FBFrenchFootnotes}% {\@makefntextFB{}}% {\@makefntextORI{}}% }% }% \def\FNH@postfntext{% \let\FBeverypar@quote\FBeverypar@save \localleftbox{\FBeveryline@quote}% }% }% \def\FNH@check@{% \expandafter\FNH@check@a\@makefntext{1.2!3?4,}% \FNH@@@1.2!3?4,\FNH@@@\relax }% \long\def\FNH@check@a #11.2!3?4,#2\FNH@@@#3{% \ifx\relax#3\expandafter\FNH@checkagain@ \else \def\FNH@prefntext{#1}\def\FNH@postfntext{#2}% \expandafter\FNH@check@b \fi }% \def\FNH@checkagain@{% \expandafter\FNH@checkagain@a \detokenize\expandafter{\@makefntext{1.2!3?4,}}\relax\FNH@@@ }% \edef\FNH@temp{\noexpand\FNH@checkagain@a ##1\string{1.2!3?4,\string}}% \expandafter\def\FNH@temp#2#3\FNH@@@{% \ifx\relax#2% \def\FNH@prefntext{\@makefntext{}}% \else\FNH@bad@makefntext@alert \fi }% \def\FNH@check@b #1\relax{% \expandafter\expandafter\expandafter\FNH@check@c \expandafter\meaning\expandafter\FNH@prefntext \meaning\FNH@postfntext1.2!3?4,\FNH@check@c\relax }% \def\FNH@check@c #11.2!3?4,#2#3\relax{% \ifx\FNH@check@c#2\else\FNH@bad@makefntext@alert\fi }% % slight reformulation for Sphinx \def\FNH@bad@makefntext@alert{% \sphinxbuildwarning{badfootnotes}% \PackageWarningNoLine{sphinxpackagefootnote}% {Footnotes will be sub-optimal, sorry. This is due to the document class or^^J some package modifying macro \string\@makefntext.^^J You can try to report this incompatibility at^^J https://github.com/sphinx-doc/sphinx with this info:}% \typeout{\meaning\@makefntext}% \let\FNH@prefntext\@empty\let\FNH@postfntext\@empty }% % this macro from original footnote.sty is not used anymore by Sphinx % but for simplicity sake let's just keep it as is \def\makesavenoteenv{\@ifnextchar[\FNH@msne@ii\FNH@msne@i}%] \def\FNH@msne@i #1{% \expandafter\let\csname FNH$#1\expandafter\endcsname %$ \csname #1\endcsname \expandafter\let\csname endFNH$#1\expandafter\endcsname %$ \csname end#1\endcsname \FNH@msne@ii[#1]{FNH$#1}%$ }% \def\FNH@msne@ii[#1]#2{% \expandafter\edef\csname#1\endcsname{% \noexpand\savenotes \expandafter\noexpand\csname#2\endcsname }% \expandafter\edef\csname end#1\endcsname{% \expandafter\noexpand\csname end#2\endcsname \noexpand\expandafter \noexpand\spewnotes \noexpand\if@endpe\noexpand\@endpetrue\noexpand\fi }% }% % % some extras for Sphinx : % \sphinxfootnotemark: % - if in section titles will auto-remove itself from TOC \def\sphinxfootnotemark [#1]% {\ifx\thepage\relax\else\sphinxfootref{#1}\fi}% \newcounter{sphinxfootnotemark} \renewcommand\thesphinxfootnotemark{\number\value{sphinxfootnotemark}} % - compares page number of footnote mark versus the one of footnote text \def\sphinx@xdef@thefnmark#1{% \expandafter\expandafter\expandafter\sphinx@footref@get \csname r@\thesphinxscope.footnote.#1\endcsname\relax \expandafter\expandafter\expandafter\sphinx@footmark@getpage \csname r@footnotemark.\thesphinxfootnotemark\endcsname\thepage\relax \protected@xdef\@thefnmark{% \ifx\spx@footmarkpage\spx@footrefpage \spx@footreflabel \else % the macro \sphinxthefootnotemark is in sphinx.sty \sphinxthefootnotemark{\spx@footreflabel}{\spx@footrefpage}% \fi }% }% \def\sphinx@footref@get #1#2#3#4#5\relax{% \def\spx@footreflabel{#1}% \def\spx@footrefpage {#2}% \def\spx@footrefHref {#4}% }% \def\sphinx@footmark@getpage #1#2#3\relax{% \edef\spx@footmarkpage{#2}% }% \protected\def\sphinxfootref#1{% #1 always is explicit number in Sphinx \spx@opt@BeforeFootnote % each of \refstepcounter and \label interferes with memoir class detection % of successive footnote marks, so we move them to inside \@makefnmark \let\spx@saved@makefnmark\@makefnmark \ltx@ifundefined{r@\thesphinxscope.footnote.#1}% {\gdef\@thefnmark{?}% on first LaTeX run \refstepcounter{sphinxfootnotemark}\label{footnotemark.\thesphinxfootnotemark}% }% {\sphinx@xdef@thefnmark{#1}% also defines \spx@footrefHref \def\@makefnmark{% will be used by \H@@footnotemark \refstepcounter{sphinxfootnotemark}\label{footnotemark.\thesphinxfootnotemark}% \hyper@linkstart{link}{\spx@footrefHref}% \spx@saved@makefnmark \hyper@linkend }% }% \H@@footnotemark \let\@makefnmark\spx@saved@makefnmark }% \AtBeginDocument{% % let hyperref less complain \pdfstringdefDisableCommands{\def\sphinxfootnotemark [#1]{}}% % to obtain hyperlinked footnotes in longtable environment we must replace % hyperref's patch of longtable's patch of \@footnotetext by our own \let\LT@p@ftntext\FNH@hyper@fntext % this *requires* longtable to be used always wrapped in savenotes environment }% \endinput %% %% End of file `sphinxpackagefootnote.sty'. krb5-1.22.1/doc/pdf/sphinxlatextables.sty0000664000175000017500000016074614577122106020206 0ustar ghudsonghudson%% TABLES (WITH SUPPORT FOR MERGED CELLS OF GENERAL CONTENTS) % % change this info string if making any custom modification \ProvidesFile{sphinxlatextables.sty}[2022/08/15 tables]% % Provides support for this output mark-up from Sphinx latex writer % and table templates: % % - the tabulary and longtable environments from the eponymous packages % - the varwidth environment % - the >{} etc mark-up possible in tabularcolumns is from array package % which is loaded by longtable and tabulary % - \X, \Y, T column types; others (L, C, R, J) are from tabulary package % - \sphinxaftertopcaption % - \sphinxatlongtableend % - \sphinxatlongtablestart % - \sphinxattableend % - \sphinxattablestart % - \sphinxcapstartof % - \sphinxcolwidth % - \sphinxlongtablecapskipadjust % - \sphinxmultirow % - \sphinxstartmulticolumn % - \sphinxstopmulticolumn % - \sphinxtablestrut % - \sphinxthecaptionisattop % - \sphinxthelongtablecaptionisattop % - \sphinxhline % - \sphinxcline % - \sphinxvlinecrossing % - \sphinxfixclines % - \sphinxtoprule % - \sphinxmidrule % - \sphinxbottomrule % - \sphinxtableatstartofbodyhook % - \sphinxtableafterendhook % - \sphinxthistablewithglobalstyle % - \sphinxthistablewithbooktabsstyle % - \sphinxthistablewithborderlessstyle % - \sphinxthistablewithstandardstyle % - \sphinxthistablewithcolorrowsstyle % - \sphinxthistablewithnocolorrowsstyle % - \sphinxthistablewithvlinesstyle % - \sphinxthistablewithnovlinesstyle % % Executes \RequirePackage for: % % - tabulary % - longtable % - varwidth % - colortbl % - booktabs if 'booktabs' in latex_table_style % % Extends tabulary and longtable via patches and custom macros to support % merged cells possibly containing code-blocks in complex tables \RequirePackage{tabulary} % tabulary has a bug with its re-definition of \multicolumn in its first pass % which is not \long. But now Sphinx does not use LaTeX's \multicolumn but its % own macro. Hence we don't even need to patch tabulary. See % sphinxpackagemulticell.sty % X or S (Sphinx) may have meanings if some table package is loaded hence % \X was chosen to avoid possibility of conflict \newcolumntype{\X}[2]{p{\dimexpr (\linewidth-\spx@arrayrulewidth)*#1/#2-\tw@\tabcolsep-\spx@arrayrulewidth\relax}} \newcolumntype{\Y}[1]{p{\dimexpr #1\dimexpr\linewidth-\spx@arrayrulewidth\relax-\tw@\tabcolsep-\spx@arrayrulewidth\relax}} % \spx@arrayrulewidth is used internally and its meaning will be set according % to the table type; no extra user code should modify it. In particular any % \setlength{\spx@arrayrulewidth}{...} may break all of LaTeX... (really...) \def\spx@arrayrulewidth{\arrayrulewidth}% 5.3.0, to be adjusted by each table % using here T (for Tabulary) feels less of a problem than the X could be \newcolumntype{T}{J}% % For tables allowing pagebreaks \RequirePackage{longtable} % User interface to set-up whitespace before and after tables: \newcommand*\sphinxtablepre {0pt}% \newcommand*\sphinxtablepost{\medskipamount}% % Space from caption baseline to top of table or frame of literal-block \newcommand*\sphinxbelowcaptionspace{.5\sphinxbaselineskip}% % as one can not use \baselineskip from inside longtable (it is zero there) % we need \sphinxbaselineskip, which defaults to \baselineskip \def\sphinxbaselineskip{\baselineskip}% % The following is to ensure that, whether tabular(y) or longtable: % - if a caption is on top of table: % a) the space between its last baseline and the top rule of table is % exactly \sphinxbelowcaptionspace % b) the space from last baseline of previous text to first baseline of % caption is exactly \parskip+\baselineskip+ height of a strut. % c) the caption text will wrap at width \LTcapwidth (4in) % - make sure this works also if "caption" package is loaded by user % (with its width or margin option taking place of \LTcapwidth role) % TODO: obtain same for caption of literal block: a) & c) DONE, b) TO BE DONE % % To modify space below such top caption, adjust \sphinxbelowcaptionspace % To add or remove space above such top caption, adjust \sphinxtablepre: % notice that \abovecaptionskip, \belowcaptionskip, \LTpre are **ignored** % A. Table with longtable \def\sphinxatlongtablestart {\par \vskip\parskip \vskip\dimexpr\sphinxtablepre\relax % adjust vertical position \vbox{}% get correct baseline from above \LTpre\z@skip\LTpost\z@skip % set to zero longtable's own skips \edef\sphinxbaselineskip{\dimexpr\the\dimexpr\baselineskip\relax\relax}% }% % Compatibility with caption package \def\sphinxthelongtablecaptionisattop{% \spx@ifcaptionpackage{\noalign{\vskip-\belowcaptionskip}}{}% }% % Achieves exactly \sphinxbelowcaptionspace below longtable caption \def\sphinxlongtablecapskipadjust {\dimexpr-\dp\strutbox -\spx@ifcaptionpackage{\abovecaptionskip}{\sphinxbaselineskip}% +\sphinxbelowcaptionspace\relax}% \def\sphinxatlongtableend{\@nobreakfalse % latex3/latex2e#173 \prevdepth\z@\vskip\sphinxtablepost\relax}% % B. Table with tabular or tabulary \def\sphinxattablestart{\par\vskip\dimexpr\sphinxtablepre\relax}% \let\sphinxattableend\sphinxatlongtableend % This is used by tabular and tabulary templates \newcommand*\sphinxcapstartof[1]{% \vskip\parskip \vbox{}% force baselineskip for good positioning by capstart of hyperanchor % hyperref puts the anchor 6pt above this baseline; in case of caption % this baseline will be \ht\strutbox above first baseline of caption \def\@captype{#1}% \capstart % move back vertically, as tabular (or its caption) will compensate \vskip-\baselineskip\vskip-\parskip }% \def\sphinxthecaptionisattop{% locate it after \sphinxcapstartof \spx@ifcaptionpackage {\caption@setposition{t}% \vskip\baselineskip\vskip\parskip % undo those from \sphinxcapstartof \vskip-\belowcaptionskip % anticipate caption package skip % caption package uses a \vbox, not a \vtop, so "single line" case % gives different result from "multi-line" without this: \nointerlineskip }% {}% }% \def\sphinxthecaptionisatbottom{% (not finalized; for template usage) \spx@ifcaptionpackage{\caption@setposition{b}}{}% }% % The aim of \sphinxcaption is to apply to tabular(y) the maximal width % of caption as done by longtable \def\sphinxtablecapwidth{\LTcapwidth}% \newcommand\sphinxcaption{\@dblarg\spx@caption}% \long\def\spx@caption[#1]#2{% \noindent\hb@xt@\linewidth{\hss \vtop{\@tempdima\dimexpr\sphinxtablecapwidth\relax % don't exceed linewidth for the caption width \ifdim\@tempdima>\linewidth\hsize\linewidth\else\hsize\@tempdima\fi % longtable ignores \abovecaptionskip/\belowcaptionskip, so do the same here \abovecaptionskip\sphinxabovecaptionskip % \z@skip \belowcaptionskip\sphinxbelowcaptionskip % \z@skip \caption[{#1}]% {\strut\ignorespaces#2\ifhmode\unskip\@finalstrut\strutbox\fi}% }\hss}% \par\prevdepth\dp\strutbox }% \def\sphinxabovecaptionskip{\z@skip}% Do not use! Flagged for removal \def\sphinxbelowcaptionskip{\z@skip}% Do not use! Flagged for removal % This wrapper of \abovecaptionskip is used in sphinxVerbatim for top % caption, and with another value in sphinxVerbatimintable % TODO: To unify space above caption of a code-block with the one above % caption of a table/longtable, \abovecaptionskip must not be used % This auxiliary will get renamed and receive a different meaning % in future. \def\spx@abovecaptionskip{\abovecaptionskip}% % Achieve \sphinxbelowcaptionspace below a caption located above a tabular % or a tabulary \newcommand\sphinxaftertopcaption {% \spx@ifcaptionpackage {\par\prevdepth\dp\strutbox\nobreak\vskip-\abovecaptionskip}{\nobreak}% \vskip\dimexpr\sphinxbelowcaptionspace\relax \vskip-\baselineskip\vskip-\parskip }% % varwidth is crucial for our handling of general contents in merged cells \RequirePackage{varwidth} % but addition of a compatibility patch with hyperref is needed % (tested with varwidth v 0.92 Mar 2009) \AtBeginDocument {% \let\@@vwid@Hy@raisedlink\Hy@raisedlink \long\def\@vwid@Hy@raisedlink#1{\@vwid@wrap{\@@vwid@Hy@raisedlink{#1}}}% \edef\@vwid@setup{% \let\noexpand\Hy@raisedlink\noexpand\@vwid@Hy@raisedlink % HYPERREF ! \unexpanded\expandafter{\@vwid@setup}}% }% % NOTA BENE: since the multicolumn and multirow code was written Sphinx % decided to prefix non public internal macros by \spx@ and in fact all % such macros here should now be prefixed by \spx@table@, but doing the % update is delayed to later. (written at 5.3.0) %%%%%%%%%%%%%%%%%%%%% % --- MULTICOLUMN --- % standard LaTeX's \multicolumn % 1. does not allow verbatim contents, % 2. interacts very poorly with tabulary. % % It is needed to write own macros for Sphinx: to allow code-blocks in merged % cells rendered by tabular/longtable, and to allow multi-column cells with % paragraphs to be taken into account sanely by tabulary algorithm for column % widths. % % This requires quite a bit of hacking. First, in Sphinx, the multi-column % contents will *always* be wrapped in a varwidth environment. The issue % becomes to pass it the correct target width. We must trick tabulary into % believing the multicolumn is simply separate columns, else tabulary does not % incorporate the contents in its algorithm. But then we must clear the % vertical rules... % % configuration of tabulary \setlength{\tymin}{3\fontcharwd\font`0 }% minimal width of "squeezed" columns \setlength{\tymax}{10000pt}% allow enough room for paragraphs to "compete" % we need access to tabulary's final computed width. \@tempdima is too volatile % to hope it has kept tabulary's value when \sphinxcolwidth needs it. \newdimen\sphinx@TY@tablewidth \def\tabulary{% \def\TY@final{\sphinx@TY@tablewidth\@tempdima\tabular}% \let\endTY@final\endtabular \TY@tabular}% % next hack is needed only if user has set latex_use_latex_multicolumn to True: % it fixes tabulary's bug with \multicolumn defined "short" in first pass. (if % upstream tabulary adds a \long, our extra one causes no harm) \def\sphinx@tempa #1\def\multicolumn#2#3#4#5#6#7#8#9\sphinx@tempa {\def\TY@tab{#1\long\def\multicolumn####1####2####3{\multispan####1\relax}#9}}% \expandafter\sphinx@tempa\TY@tab\sphinx@tempa % % TN. 1: as \omit is never executed, Sphinx multicolumn does not need to worry % like standard multicolumn about |l| vs l|. On the other hand it assumes % columns are separated by a | ... (if not it will add extraneous % \arrayrulewidth space for each column separation in its estimate of available % width). % % Update at 5.3.0: code uses \spx@arrayrulewidth which is kept in sync with the % table column specification (aka preamble): % - no | in preamble: \spx@arrayrulewidth -> \z@ % - at least a | in the preamble: \spx@arrayrulewidth -> \arrayrulewidth % This is used for computation of merged cells widths. Mixed preambles using % at least a | but not using it for all columns (as can be obtained via the % tabularcolumns directive) may cause some merged cells contents to be slightly % shifted to the left as they assume merged columns are | separated where in % fact they perhaps are not. % % TN. 1b: as Sphinx multicolumn uses neither \omit nor \span, it can not % (easily) get rid of extra macros from >{...} or <{...} between columns. At % least, it has been made compatible with colortbl's \columncolor. % % TN. 2: tabulary's second pass is handled like tabular/longtable's single % pass, with the difference that we hacked \TY@final to set in % \sphinx@TY@tablewidth the final target width as computed by tabulary. This is % needed only to handle columns with a "horizontal" specifier: "p" type columns % (inclusive of tabulary's LJRC) holds the target column width in the % \linewidth dimension. % % TN. 3: use of \begin{sphinxmulticolumn}...\end{sphinxmulticolumn} mark-up % would need some hacking around the fact that groups can not span across table % cells (the code does inserts & tokens, see TN1b). It was decided to keep it % simple with \sphinxstartmulticolumn...\sphinxstopmulticolumn. % % MEMO about nesting: if sphinxmulticolumn is encountered in a nested tabular % inside a tabulary it will think to be at top level in the tabulary. But % Sphinx generates no nested tables, and if some LaTeX macro uses internally a % tabular this will not have a \sphinxstartmulticolumn within it! % % 5.3.0 adds a check for multirow as single-row multi-column will allow a row % colour but multi-row multi-column should not. % Attention that this assumes \sphinxstartmulticolumn is always followed % in latex mark-up either by \sphinxmultirow or \begin (from \begin{varwidth}). \def\sphinxstartmulticolumn#1#2{% \ifx\sphinxmultirow#2% \gdef\spx@table@hackCT@inmergedcell{\spx@table@hackCT@nocolor}% \else \global\let\spx@table@hackCT@inmergedcell\spx@@table@hackCT@inmergedcell \fi \sphinx@startmulticolumn{#1}#2% }% \def\sphinx@startmulticolumn{% \ifx\equation$% $ tabulary's first pass \expandafter\sphinx@TYI@start@multicolumn \else % either not tabulary or tabulary's second pass \expandafter\sphinx@start@multicolumn \fi }% \def\sphinxstopmulticolumn{% \ifx\equation$% $ tabulary's first pass \expandafter\sphinx@TYI@stop@multicolumn \else % either not tabulary or tabulary's second pass \ignorespaces \fi }% \def\sphinx@TYI@start@multicolumn#1{% % use \gdef always to avoid stack space build up \gdef\sphinx@tempa{#1}\begingroup\setbox\z@\hbox\bgroup }% \def\sphinx@TYI@stop@multicolumn{\egroup % varwidth was used with \tymax \xdef\sphinx@tempb{\the\dimexpr\wd\z@/\sphinx@tempa}% per column width \endgroup \expandafter\sphinx@TYI@multispan\expandafter{\sphinx@tempa}% }% \def\sphinx@TYI@multispan #1{% \kern\sphinx@tempb\ignorespaces % the per column occupied width \ifnum#1>\@ne % repeat, taking into account subtleties of TeX's & ... \expandafter\sphinx@TYI@multispan@next\expandafter{\the\numexpr#1-\@ne\expandafter}% \fi }% \def\sphinx@TYI@multispan@next{&\relax\sphinx@TYI@multispan}% % % Now the branch handling either the second pass of tabulary or the single pass % of tabular/longtable. This is the delicate part where we gather the % dimensions from the p columns either set-up by tabulary or by user p column % or Sphinx \X, \Y columns. The difficulty is that to get the said width, the % template must be inserted (other hacks would be horribly complicated except % if we rewrote crucial parts of LaTeX's \@array !) and we can not do % \omit\span like standard \multicolumn's easy approach. Thus we must cancel % the \vrule separators. Also, perhaps the column specifier is of the l, c, r % type, then we attempt an ad hoc rescue to give varwidth a reasonable target % width. \def\sphinx@start@multicolumn#1{% \gdef\sphinx@multiwidth{0pt}\gdef\sphinx@tempa{#1}\sphinx@multispan{#1}% }% \def\sphinx@multispan #1{% \ifnum#1=\@ne\expandafter\sphinx@multispan@end \else\expandafter\sphinx@multispan@next \fi {#1}% }% \def\sphinx@multispan@next #1{% % trick to recognize L, C, R, J or p, m, b type columns \ifdim\baselineskip>\z@ \gdef\sphinx@tempb{\linewidth}% \else % if in an l, r, c type column, try and hope for the best \xdef\sphinx@tempb{\the\dimexpr(\ifx\TY@final\@undefined\linewidth\else \sphinx@TY@tablewidth\fi-\spx@arrayrulewidth)/\sphinx@tempa -\tw@\tabcolsep-\spx@arrayrulewidth\relax}% \fi \noindent\kern\sphinx@tempb\relax \xdef\sphinx@multiwidth {\the\dimexpr\sphinx@multiwidth+\sphinx@tempb+\tw@\tabcolsep+\spx@arrayrulewidth}% \spx@table@hackCT@fixcolorpanel % silence a | column separator in our merged cell \spx@table@hackCT@inhibitvline % prevent column colours to interfere with our multi-column but allow row % colour (we can't obey a \cellcolor as it has not be seen yet at this stage) \spx@table@hackCT@inmergedcell&\relax % repeat \expandafter\sphinx@multispan\expandafter{\the\numexpr#1-\@ne}% }% \def\sphinx@multispan@end#1{% % first, trace back our steps horizontally \noindent\kern-\dimexpr\sphinx@multiwidth\relax % and now we set the final computed width for the varwidth environment \ifdim\baselineskip>\z@ \xdef\sphinx@multiwidth{\the\dimexpr\sphinx@multiwidth+\linewidth}% \else \xdef\sphinx@multiwidth{\the\dimexpr\sphinx@multiwidth+ (\ifx\TY@final\@undefined\linewidth\else \sphinx@TY@tablewidth\fi-\spx@arrayrulewidth)/\sphinx@tempa -\tw@\tabcolsep-\spx@arrayrulewidth\relax}% \fi % last cell of the multi-column \aftergroup\spx@table@hackCT@fixcolorpanel \aftergroup\spx@table@hackCT@inmergedcell }% \newcommand*\sphinxcolwidth[2]{% % this dimension will always be used for varwidth, and serves as maximum % width when cells are merged either via multirow or multicolumn or both, % as always their contents is wrapped in varwidth environment. \ifnum#1>\@ne % multi-column (and possibly also multi-row) % we wrote our own multicolumn code especially to handle that (and allow % verbatim contents) \ifx\equation$%$ \tymax % first pass of tabulary (cf MEMO above regarding nesting) \else % the \@gobble thing is for compatibility with standard \multicolumn \sphinx@multiwidth\@gobble{#1/#2}% \fi \else % single column multirow \ifx\TY@final\@undefined % not a tabulary. \ifdim\baselineskip>\z@ % in a p{..} type column, \linewidth is the target box width \linewidth \else % l, c, r columns. Do our best. \dimexpr(\linewidth-\spx@arrayrulewidth)/#2- \tw@\tabcolsep-\spx@arrayrulewidth\relax \fi \else % in tabulary \ifx\equation$%$% first pass \tymax % it is set to a big value so that paragraphs can express themselves \else % second pass. \ifdim\baselineskip>\z@ \linewidth % in a L, R, C, J column or a p, \X, \Y ... \else % we have hacked \TY@final to put in \sphinx@TY@tablewidth the table width \dimexpr(\sphinx@TY@tablewidth-\spx@arrayrulewidth)/#2- \tw@\tabcolsep-\spx@arrayrulewidth\relax \fi \fi \fi \fi }% % fallback default in case user has set latex_use_latex_multicolumn to True: % \sphinxcolwidth will use this only inside LaTeX's standard \multicolumn \def\sphinx@multiwidth #1#2{\dimexpr % #1 to gobble the \@gobble (!) (\ifx\TY@final\@undefined\linewidth\else\sphinx@TY@tablewidth\fi -\spx@arrayrulewidth)*#2-\tw@\tabcolsep-\spx@arrayrulewidth\relax}% % \spx@table@hackCT@inhibitvline % packages like colortbl add group levels, we need to "climb back up" to be % able to hack the \vline and also the colortbl inserted tokens. The hack % sets the \arrayrulewidth to \z@ to inhibit a | separator at right end % of the cell, if present (our code does not use \omit so can not avoid the % \vline insertion, but setting its width to zero makes it do nothing). % Some subtlety with colour panels must be taken care of. \def\spx@table@hackCT@inhibitvline{\ifnum\currentgrouptype=6\relax \kern\spx@arrayrulewidth % will be compensated by extra colour panel left overhang \arrayrulewidth\z@% trick to inhibit the {\vrule width \arrayrulewidth} \else\aftergroup\spx@table@hackCT@inhibitvline\fi}% % hacking around colour matters % Sphinx 1.6 comment: % It turns out \CT@row@color is not expanded contrarily to \CT@column@color % during LaTeX+colortbl preamble preparation, hence it would be possible for % \CT@setup to discard only the column color and choose to obey or not % row color and cell color. It would even be possible to propagate cell color % to row color for the duration of the Sphinx multicolumn... the (provisional?) % choice has been made to cancel the colortbl colours for the multicolumn % duration. % Sphinx 5.3.0 comment: % - colortbl has no mechanism to disable colour background in a given cell: % \cellcolor triggers one more \color, but has no possibility to revert % a previously emitted \color, only to override it via an additional \color % - prior to 5.3.0, Sphinx did not officially support colour in tables, % but it did have a mechanism to protect merged cells from being partly % covered by colour panels at various places. At 5.3.0 this mechanism % is relaxed a bit to allow row colour for a single-row merged cell. % % fixcolorpanel \def\spx@table@hackCT@fixcolorpanel{\ifnum\currentgrouptype=6\relax \edef\spx@table@leftcolorpanelextra % \edef as \arrayrulewidth will be set to \z@ next, % hence also \spx@arrayrulewidth... {\sphinxcolorpanelextraoverhang+\the\spx@arrayrulewidth}% \else\aftergroup\spx@table@hackCT@fixcolorpanel\fi}% % % inmergedcell % \spx@table@hackCT@inmergedcell will be locally set to either this % \spx@@table@hackCT@inmergedcell or to \spx@table@hackCT@nocolor % "\let\spx@original@CT@setup\CT@setup" is done after loading colortbl \def\spx@@table@hackCT@inmergedcell{\ifnum\currentgrouptype=6\relax \let\CT@setup\spx@CT@setup@inmergedcell \else\aftergroup\spx@@table@hackCT@inmergedcell\fi }% \newif\ifspx@table@inmergedcell \def\spx@CT@setup@inmergedcell #1\endgroup{% % - obey only row color and disable effect of \sphinxcolorblend % - turn on the inmergedcell boolean to signal to \CT@row@color \spx@original@CT@setup \spx@table@inmergedcelltrue % needed by \CT@row@color % deactivate effect of \sphinxcolorblend if it happened at all \ifdefined\blendcolors\blendcolors{}\fi \CT@row@color \CT@do@color \global\let\CT@cell@color\relax \endgroup }% % % nocolor \def\spx@table@hackCT@nocolor{\ifnum\currentgrouptype=6\relax % sadly \CT@column@color is possibly already expanded so we can't % simply do \let\CT@column@color\relax etc... % admittedly we could perhaps hack \CT@color but well \let\CT@setup\spx@CT@setup@nocolor \else\aftergroup\spx@table@hackCT@nocolor\fi } \def\spx@CT@setup@nocolor#1\endgroup{% \global\let\CT@cell@color\relax % the above fix was added at 5.3.0 % formerly a \cellcolor added by a raw latex directive in the merged cell % would have caused colour to apply to the *next* cell after the merged % one; we don't support \cellcolor from merged cells contents anyhow. \endgroup} % % norowcolor \def\spx@table@hackCT@norowcolor{% % a bit easier although merged cells complicate the matter as they do need % to keep the rowcolor; and we can't know yet if we are in a merged cell \ifnum\currentgrouptype=6\relax \ifx\CT@row@color\relax \else \let\spx@saved@CT@row@color\CT@row@color \def\CT@row@color{% \ifspx@table@inmergedcell\expandafter\spx@saved@CT@row@color\fi }% \fi \else\aftergroup\spx@table@hackCT@norowcolor\fi } % % \sphinxcolorblend \def\spx@table@hackCT@colorblend{% \ifnum\currentgrouptype=6\relax \expandafter\blendcolors\spx@colorblendparam % merged cells will do a \blendcolors{} to cancel the effet % we can not know here yet if in merged cell as the boolean % \ifspx@table@inmergedcell is not yet updated \else \aftergroup\spx@table@hackCT@colorblend \fi } \def\sphinxcolorblend#1{\gdef\spx@colorblendparam{{#1}}\spx@table@hackCT@colorblend} % Either xcolor.sty exists on user system and has been loaded by sphinx.sty, % or it does not exist, so we can use \@ifpackageloaded without delaying. \@ifpackageloaded{xcolor}% {}% {\def\sphinxcolorblend#1{% \PackageWarning{sphinx}{This table uses \string\sphinxcolorblend\space but xcolor is not in\MessageBreak the TeX/LaTeX installation, the command will be\MessageBreak ignored in this and the next tables}% \global\let\sphinxcolorblend\@gobble \sphinxbuildwarning{colorblend}% }% } %%%%%%%%%%%%%%%%%% % --- MULTIROW --- % standard \multirow % 1. does not allow verbatim contents, % 2. does not allow blank lines in its argument, % 3. its * specifier means to typeset "horizontally" which is very % bad for paragraph content. 2016 version has = specifier but it % must be used with p type columns only, else results are bad, % 4. it requires manual intervention if the contents is too long to fit % in the asked-for number of rows. % 5. colour panels (either from \rowcolor or \columncolor) will hide % the bottom part of multirow text, hence manual tuning is needed % to put the multirow insertion at the _bottom_. % % The Sphinx solution consists in always having contents wrapped % in a varwidth environment so that it makes sense to estimate how many % lines it will occupy, and then ensure by insertion of suitable struts % that the table rows have the needed height. The needed mark-up is done % by LaTeX writer, which has its own id for the merged cells. % % The colour issue is "solved" by clearing colour panels in all cells, % whether or not the multirow is single-column or multi-column. % % MEMO at 5.3.0: to allow a multirow cell in a single column to react to % \columncolor correctly, it seems only way is that the contents % are inserted by bottom cell (this is mentioned in multirow.sty doc, too). % Sphinx could at Python level "move" the contents to that cell. But the % mechanism used here via \sphinxtablestrut to enlarge rows to make room for % the contents if needed becomes more challenging yet, because \sphinxtablestrut % mark-up will be parsed by TeX *before* it sees the contents of the merged % cell.. So it seems the best way would be to actually store the contents into % some owned-by-Sphinx box storage which needs to be globally allocated to % that usage ; then we need multiple such boxes, say at least 5 to cover % 99% or use case. Or perhaps some trick with storing in a \vbox and recovering % via some \vsplit but this becomes complicated... perhaps in future. % % In passing we obtain baseline alignements across rows (only if % \arraystretch is 1, as LaTeX's does not obey \arraystretch in "p" % multi-line contents, only first and last line...) % % TODO: examine the situation with \arraystretch > 1. The \extrarowheight % is hopeless for multirow anyhow, it makes baseline alignment strictly % impossible. \newcommand\sphinxmultirow[2]{\begingroup % #1 = nb of spanned rows, #2 = Sphinx id of "cell", #3 = contents % but let's fetch #3 in a way allowing verbatim contents ! \def\sphinx@nbofrows{#1}\def\sphinx@cellid{#2}% \afterassignment\sphinx@multirow\let\next= }% \def\sphinx@multirow {% \setbox\z@\hbox\bgroup\aftergroup\sphinx@@multirow\strut }% \def\sphinx@@multirow {% % MEMO: we could check status of \CT@cell@color here, but unfortunately we % can't know the exact height which will be covered by the cells in total % (it may be more than our \box\z@ dimensions). We could use an \fcolorbox % wrapper on \box\z@ but this will not extend precisely to the bottom rule. % % Only solution if we want to obey a raw \cellcolor, or a \columncolor, seems % to delay unboxing the gathered contents as part of the bottom row with % a suitable vertical adjustment... % % The contents, which is a varwidth environment, has been captured in % \box0 (a \hbox). % We have with \sphinx@cellid an assigned unique id. The goal is to give % about the same height to all the involved rows. % For this Sphinx will insert a \sphinxtablestrut{cell_id} mark-up % in LaTeX file and the expansion of the latter will do the suitable thing. \dimen@\dp\z@ \dimen\tw@\ht\@arstrutbox \advance\dimen@\dimen\tw@ \advance\dimen\tw@\dp\@arstrutbox \count@=\dimen@ % type conversion dim -> int \count\tw@=\dimen\tw@ \divide\count@\count\tw@ % TeX division truncates \advance\dimen@-\count@\dimen\tw@ % 1300sp is about 0.02pt. For comparison a rule default width is 0.4pt. % (note that if \count@ holds 0, surely \dimen@>1300sp) \ifdim\dimen@>1300sp \advance\count@\@ne \fi % now \count@ holds the count L of needed "lines" % and \sphinx@nbofrows holds the number N of rows % we have L >= 1 and N >= 1 % if L is a multiple of N, ... clear what to do ! % else write L = qN + r, 1 <= r < N and we will % arrange for each row to have enough space for: % q+1 "lines" in each of the first r rows % q "lines" in each of the (N-r) bottom rows % for a total of (q+1) * r + q * (N-r) = q * N + r = L % It is possible that q == 0. \count\tw@\count@ % the TeX division truncates \divide\count\tw@\sphinx@nbofrows\relax \count4\count\tw@ % q \multiply\count\tw@\sphinx@nbofrows\relax \advance\count@-\count\tw@ % r \expandafter\xdef\csname sphinx@tablestrut_\sphinx@cellid\endcsname {\noexpand\sphinx@tablestrut{\the\count4}{\the\count@}{\sphinx@cellid}}% \dp\z@\z@ % this will use the real height if it is >\ht\@arstrutbox \sphinxtablestrut{\sphinx@cellid}\box\z@ \endgroup % group was opened in \sphinxmultirow }% \newcommand*\sphinxtablestrut[1]{% % #1 is a "cell_id", i.e. the id of a merged group of table cells \csname sphinx@tablestrut_#1\endcsname }% % LaTeX typesets the table row by row, hence each execution can do % an update for the next row. \newcommand*\sphinx@tablestrut[3]{\begingroup % #1 = q, #2 = (initially) r, #3 = cell_id, q+1 lines in first r rows % if #2 = 0, create space for max(q,1) table lines % if #2 > 0, create space for q+1 lines and decrement #2 \leavevmode \count@#1\relax \ifnum#2=\z@ \ifnum\count@=\z@\count@\@ne\fi \else % next row will be with a #2 decremented by one \expandafter\xdef\csname sphinx@tablestrut_#3\endcsname {\noexpand\sphinx@tablestrut{#1}{\the\numexpr#2-\@ne}{#3}}% \advance\count@\@ne \fi \vrule\@height\ht\@arstrutbox \@depth\dimexpr\count@\ht\@arstrutbox+\count@\dp\@arstrutbox-\ht\@arstrutbox\relax \@width\z@ \endgroup % we need this to avoid colour panels hiding bottom parts of multirow text \spx@table@hackCT@nocolor }% %%%%%%%%%%%%%%%%%% % --- STYLING --- % % % Support for colour in table % % Core LaTeX package (very old, part of texlive-latex-base on Debian distr.) % providing \columncolor, \rowcolor, \cellcolor and \arrayrulecolor. \RequirePackage{colortbl} \let\spx@original@CT@setup\CT@setup % LaTeX's \cline has **strong** deficiencies % ****************************************** % We work around them via an added \sphinxfixclines{number of columns} in the % table mark-up, and also extra mark-up \sphinxvlinecrossing{col no} for % crossings not contiguous to any cline. To fix the gap at left extremity of a % \cline, we redefine the core LaTeX \c@line because this avoids adjoining a % small square with potential PDF viewer anti-aliasing issues. We waited % after loading colortbl because it also redefines \c@line for it to obey the % colour set by \arrayrulecolor. % MEMO: booktabs package does *not* redefine \@cline so we are safe here. \def\@cline#1-#2\@nil{% \omit \@multicnt#1% \advance\@multispan\m@ne \ifnum\@multicnt=\@ne\@firstofone{&\omit}\fi \@multicnt#2% \advance\@multicnt-#1% \advance\@multispan\@ne {\CT@arc@ % start of Sphinx modification \ifnum#1>\@ne\kern-\spx@arrayrulewidth\fi% fix gap at join with vertical lines % end of Sphinx modification % Comments: % % If we had the information whether the previous column ended with a | or % not, we could decide what to do here. Alternatively the mark-up could % use either original \cline or the one modified as here depending on case. % One wonders why LaTeX does not provide itself the alternative as a % complement to \cline, to use on case by case basis. % Here we handle both at same time via using the \spx@arrayrulewidth which % will be \z@ if no | at all so will induce here nothing. % % As a result Sphinx basically supports well only tables having either all % columns |-separated, or no | at all, as it uses \spx@arrayrrulewidth in % all columns (here and in multicolumn code). % % We also considered a method not modifying \c@line but it requires too % much extra mark-up from Python LaTeX writer and/or extra LaTeX coding. % back to LaTeX+colortbl code \leaders\hrule\@height\arrayrulewidth\hfill}% \cr % the last one will need to be compensated, this is job of \sphinxclines \noalign{\vskip-\arrayrulewidth}% } \def\spx@table@fixvlinejoin{% {\CT@arc@ % this is the color command set up by \arrayrulecolor \vrule\@height\arrayrulewidth % side remark: LaTeX has only a single \arrayrulewidth for all kinds % for cell borders in table, horizontal or vertical... \@depth\z@ \@width\spx@arrayrulewidth }% } % Sphinx LaTeX writer issues one such for each vertical line separating two % contiguous multirow cells; i.e. those crossings which can are not already % taken care of by our modified at left extremity \cline. % One could imagine a more \...crossingS (plural) receiving a comma delimited % list, which would simplify the mark-up but this would complexify both the % Python and the LaTeX coding. \def\sphinxtablevlinecrossing#1{% \sphinxtabledecrementrownum \omit \@multispan{#1}% \hfill \spx@table@fixvlinejoin \cr \noalign{\vskip-\arrayrulewidth}% } % This "fixclines" is also needed if no \sphinxcline emitted and is useful % even in extreme case with no \sphinxvlinecrossing either, to give correct % height to multirow extending across all table width assuming other rows are % separated generally by an \hline, so as to keep coherent line spacing. % % It is designed to work ok even if no | separators are in the table (because % \spx@table@fixvlinejoin uses \spx@arrayrulewidth which is \z@ in that case). \def\sphinxtablefixclines#1{% #1 is the number of columns of the table \sphinxtabledecrementrownum \omit \spx@table@fixvlinejoin% unneeded if first \cline started at column 1 but does % not hurt; fills small gap at left-bordered table \@multispan{#1}% \hfill \spx@table@fixvlinejoin% fill small gap at right-bordered table \cr % this final one does NO \vskip-\arrayrulewidth... that's the whole point } %%%% end of \cline workarounds % % - passing option "table" to xcolor also loads colortbl but we needed to % load color or xcolor prior to the handling of the options % % - the \rowcolors command from [table]{xcolor} has various problems: % % * it is rigid and does not out-of-the-box allow a more complex scheme % such as colorA+colorB+colorC+colorB+colorC+colorB+colorC... suitable to % distinguish a header row. % % * its code does not export the used colour, an information which we may % need for example to colourize the rule via \arrayrulecolor in the % appropriate manner, for example to colourize the booktabs induced vertical % whitespace to avoid gaps (if one wants to). % % * incompatibility with tabulary: the output depends on parity of total % number of rows! % % * problems with longtable: the caption will receive a background colour % panel, if we do not deactivate the \rowcolors action during definition of % the headers and footers; this requires extra mark-up. Besides if we % deactivate using \hiderowcolors during header and footer formation, the % parity of the body rows is shifted, \rownum is even, not odd, at first body % row. And setting \rownum at start of first body row is too late for % influencing the colour. % % * it has a global impact and must be reset at each table. We can not % issue it only once and it provides no public interface (without @) to % cancel its effect conveniently (\hiderowcolors can only be used from % *inside* a table.) % % * its core mechanism which increments the row count is triggered % if a \cline is encountered... so this offsets the alternating colours... % ... or not if there are two \cline's in the row... % (as we will use same mechanism we have to correct this increment). % % So we need our own code. % Provide \rownum and rownum LaTeX counter (code copied from colortbl v1.0f) \ltx@ifundefined{rownum}{% \ltx@ifundefined{c@rownum}% {\newcount\rownum\let\c@rownum\rownum}% {\let\rownum\c@rownum}% }% {\let\c@rownum\rownum} \providecommand\therownum{\arabic{rownum}} % extra overhang for color panels to avoid visual artifacts in pdf viewers % (particularly if borderless) \def\sphinxcolorpanelextraoverhang{0.1pt} \def\spx@table@leftcolorpanelextra {\sphinxcolorpanelextraoverhang} \def\spx@table@rightcolorpanelextra{\sphinxcolorpanelextraoverhang} % the macro to which \CT@row@color will be set for coloured rows, serves both % in header and body, the colours must have been defined at time of use \def\spx@table@CT@row@color{\ifspx@table@inmergedcell \CT@color{sphinxTableMergeColor}% \else \CT@color{sphinxTableRowColor}% \fi \@tempdimb\dimexpr\col@sep+\spx@table@leftcolorpanelextra\relax \@tempdimc\dimexpr\col@sep+\spx@table@rightcolorpanelextra\relax }% % used by itself this will influence a single row if \CT@everycr is the % colortbl one, to influences all rows the \CT@everycr must be modified (see % below) \def\sphinxrowcolorON {\global\let\CT@row@color\spx@table@CT@row@color}% % this one turns off row colours until the next \sphinxrowcolorON \def\sphinxrowcolorOFF{\global\let\CT@row@color\relax}% % this one inhibits the row colour in one cell only (can be used as % >{\sphinxnorowcolor} for turning off row colours in a given column) \def\sphinxnorowcolor{\spx@table@hackCT@norowcolor}% % \sphinxtoprule (or rather \sphinxtabletoprulehook) will be modified by % the colorrows class to execute this one: \def\spx@table@@toprule@rowcolorON{% \noalign{% % Because of tabulary 2-pass system, the colour set-up at end of table % would contaminate the header colours at start of table, so must reset % them here. We want all header rows to obey same colours, so we don't % use original \CT@everycr which sets \CT@row@color to \relax. \global\CT@everycr{\the\everycr}% \global\sphinxcolorlet{sphinxTableRowColor}{sphinxTableRowColorHeader}% \global\sphinxcolorlet{sphinxTableMergeColor}{\sphinxTableMergeColorHeader}% \sphinxrowcolorON }% }% % \sphinxtableatstartofbodyhook will be modified by colorrows class to % execute this one; it starts the alternating colours and triggers increment % or \rownum count at each new row (the xcolor base method for \rowcolors) \def\spx@table@@startbodycolorrows{% \noalign{% \global\CT@everycr{% Nota Bene: in a longtable with \hline the \everycr is % done two extra times! but 2 is even, so this is ok \noalign{\global\advance\rownum\@ne % the xcolor \rowcolors base trick % MEMO: colortbl \CT@row@color is expanded *after* the cell contents have been % gathered and measured, so it can't be used to expose e.g. the colour to the % cell contents macro code. Of course if it is known how the colour is chosen % the procedure could be done from inside the cell. Simpler to expose the colour % in a public name sphinxTableRowColor at start of the row in this \noalign. \sphinxSwitchCaseRowColor\rownum }% \the\everycr }% \global\rownum\@ne % is done from inside table so ok with tabulary two passes \sphinxSwitchCaseRowColor\rownum % set up color for the first body row \sphinxrowcolorON % has been done from \sphinxtoprule location but let's do % it again in case \sphinxtabletoprulehook has been used % to inhibit colours in the header rows }% end of noalign contents } % set the colours according to row parity; a priori #1 is \rownum, but % the macro has been designed to be usable in user level added code \def\sphinxSwitchCaseRowColor#1{% \ifodd#1\relax \global\sphinxcolorlet{sphinxTableRowColor}{sphinxTableRowColorOdd}% \global\sphinxcolorlet{sphinxTableMergeColor}{\sphinxTableMergeColorOdd}% \else \global\sphinxcolorlet{sphinxTableRowColor}{sphinxTableRowColorEven}% \global\sphinxcolorlet{sphinxTableMergeColor}{\sphinxTableMergeColorEven}% \fi } % each \cline or \cmidrule (booktabs) consumes one \cr, offsetting the \rownum % parity; so this macro serves to compensate and must be added to each such % \cline or \cmidrule (see below) \def\spx@table@@decrementrownum{\noalign{\global\advance\rownum\m@ne}} \let\sphinxtabledecrementrownum\@empty % \sphinxtableafterendhook will be modified by colorrows class to execute % this after the table \def\spx@table@resetcolortbl{% \sphinxrowcolorOFF \spx@table@reset@CTeverycr % this last bit is done in order for the \sphinxbottomrule from the "foot" % longtable template to be able to use same code as the \sphinxbottomrule % at end of table body; see \sphinxbooktabsspecialbottomrule code \global\rownum\z@ } \def\spx@table@reset@CTeverycr{% % we should probably be more cautious and not hard-code here the colortbl % set-up; so the macro is defined without @ to fac \global\CT@everycr{\noalign{\global\let\CT@row@color\relax}\the\everycr}% } % At last the style macros \sphinxthistablewithstandardstyle etc... % They are executed before the table environments in a scope limiting % wrapper "savenotes" environment. % % 0) colour support is enacted via adding code to three hooks: % - \sphinxtabletoprulehook (implicit from \sphinxtoprule expansion) % - \sphinxtableatstartofbodyhook (explicit from table templates) % - \sphinxtableafterendhook (explicit from table templates) % additionally special adjustment must be made in \sphinxcline % \def\sphinxtoprule{\spx@toprule\sphinxtabletoprulehook} % \spx@toprule is what is defined by the standard, booktabs and borderless % styles. % The colorrows class will prepend \spx@table@toprule@rowcolorON into % \sphinxtabletoprulehook which a priori is \@empty but can contain user added % extra code, and is executed after \spx@toprule. \let\sphinxtabletoprulehook \@empty \let\sphinxtableatstartofbodyhook\@empty \let\sphinxtableafterendhook \@empty % % 1) we manage these three hooks in a way allowing a custom user extra wrapper % environment from a container class to use them as entry point for some % custom code. The container code is done first, prior to table templates. % So, the style macros will *prepend* the needed color-code to the existing % custom user code, so the custom user code can override them. The custom % user code should not redefine any of the 3 \sphinxtable...hook macros via a % \global\def, but their contents can use \gdef. In fact they probably need % to for the first two hooks which are executed from inside the table and % a priori need their code to be in a \noalign which limits scope. % % 2) the table templates and LaTeX writer code make it so that only % one of either % \sphinxthistablewithcolorrowsstyle, % or \sphinxthistablewithnocolorrowsstyle % will be inserted explicitly depending on local :class: for table. % The global 'colorrows' style in latex_table_style translates at bottom % of this file into code for inserting \sphinxthistablewithcolorrowsstyle % at end of \sphinxthistablewithglobalstyle. So it is impossible % to have first \sphinxthistablewithnocolorrowsstyle, then % \sphinxthistablewithcolorrowsstyle. Nevertheless we have written % the code so that in this case colorrows would indeed activate (except % if it was already executed before as it self-annihilates). % standard style \def\sphinxthistablewithstandardstyle{% % Those two are produced by the latex writer \def\sphinxhline {\hline}% % \sphinxtabledecrementrownum is a no-op which is redefined by colorrows % to correct the \rownum increment induced by \cline in colorrows regime \def\sphinxcline {\sphinxtabledecrementrownum\cline}% % LaTeX's \cline needs fixing \let\sphinxvlinecrossing\sphinxtablevlinecrossing \let\sphinxfixclines \sphinxtablefixclines % Those three are inserted by the table templates \def\spx@toprule {\hline}% \def\sphinxmidrule {\hline}% \def\sphinxbottomrule {\hline}% % Do not tamper with this internal \def\spx@arrayrulewidth{\arrayrulewidth}% } % booktabs style % The \@xcmidrule patch below will do beyond its main stuff % \sphinxadjustcmidrulebelowsep % Indeed the poor booktabs spacing with \cmidrule (if \sphinxbooktabscmidrule % defined below is overwritten to use it) is quite awful. Do % \let\sphinxadjustcmidrulebelowsep\empty % if you prefer booktabs defaults. \def\sphinxadjustcmidrulebelowsep{\belowrulesep=\aboverulesep} \AtBeginDocument{% patch booktabs to avoid extra vertical space from % consecutive \sphinxcline, if defined to use \cmidrule \ifdefined\@xcmidrule \let\spx@original@@xcmidrule\@xcmidrule \def\@xcmidrule{\sphinxadjustcmidrulebelowsep % if we don't do that, two \sphinxcline in the same row % will cause the second short rule to be shifted down \ifx\@tempa\sphinxcline\let\@tempa\cmidrule\fi \spx@original@@xcmidrule}% \fi } % wrappers to allow customization, e.g. via a container class % the top, mid, bottom definitions are in fact overwritten (later, below) % byt more complex ones needed to handle booktabs+colorrows context \def\sphinxbooktabstoprule {\toprule} \def\sphinxbooktabsmidrule {\midrule} \def\sphinxbooktabsbottomrule{\bottomrule} % \let\sphinxbooktabscmidrule \@gobble % i.e. draw no short rules at all! % You can redefine this to use \cmidrule with various options, such % as \cmidrule(lr), but: % Attention, if you want this to use \cmidrule (or \cline) you must, % if the table uses row colours, % also include the \sphinxtabledecrementrownum token like e.g. this % \def\sphinxbooktabscmidrule{\sphinxtabledecrementrownum\cmidrule(lr)} % and it must be first due to internals of the \cmidrule usage of \futurelet. \def\sphinxthistablewithbooktabsstyle{% \let\sphinxhline\@empty % there is no wrapper macro here so if you want to change that % you will have to redefine \sphinxthistablewithbooktabsstyle \def\sphinxcline {\sphinxbooktabscmidrule}% defaults to give \@gobble \let\sphinxvlinecrossing\@gobble % no | in a booktabs-style table ! \let\sphinxfixclines \@gobble % should not be used with booktabs + \cmidrule \def\spx@toprule {\sphinxbooktabstoprule}% \def\sphinxmidrule {\sphinxbooktabsmidrule}% \def\sphinxbottomrule{\sphinxbooktabsbottomrule}% \def\spx@arrayrulewidth{\z@}% } \AtBeginDocument{\@ifpackageloaded{booktabs}% {}% {\def\sphinxthistablewithbooktabsstyle{% \PackageWarning{sphinx}{% Add \string\usepackage{booktabs} to the preamble to allow\MessageBreak local use of booktabs table style}% \sphinxbuildwarning{booktabs}% \sphinxthistablewithstandardstyle }}% }% % borderless style \def\sphinxthistablewithborderlessstyle{% \let\sphinxhline \@empty \let\sphinxcline \@gobble \let\sphinxvlinecrossing\@gobble \let\sphinxfixclines \@gobble \let\spx@toprule \@empty \let\sphinxmidrule \@empty \let\sphinxbottomrule \@empty \def\spx@arrayrulewidth{\z@}% }% % colorrows style % \let\sphinxifthistablewithcolorrowsTF\@secondoftwo \def\sphinxthistablewithcolorrowsstyle{% \let\sphinxifthistablewithcolorrowsTF\@firstoftwo % this is defined to auto-silence itself (in the surrounding scope-limiting % environment) after one execution ("colorrows" can never follow "nocolorrows") \let\sphinxthistablewithcolorrowsstyle\@empty % \let\spx@table@toprule@rowcolorON \spx@table@@toprule@rowcolorON \let\spx@table@startbodycolorrows \spx@table@@startbodycolorrows \let\sphinxtabledecrementrownum \spx@table@@decrementrownum % Is it the best choice to "prepend" to existing code there? \spx@prepend\spx@table@toprule@rowcolorON\to\sphinxtabletoprulehook \spx@prepend\spx@table@startbodycolorrows\to\sphinxtableatstartofbodyhook % % this one is not set to \@empty by nocolorrows, because it looks harmless % to execute it always, as it simply resets to standard colortbl state after % the table; so we don't need an @@ version for this one \spx@prepend\spx@table@resetcolortbl\to\sphinxtableafterendhook } \def\spx@prepend#1\to#2{% attention about using this only with #2 "storage macro" \toks@{#1}% \toks@\expandafter\expandafter\expandafter{\expandafter\the\expandafter\toks@#2}% \edef#2{\the\toks@}% }% \def\sphinxthistablewithnocolorrowsstyle{% \let\sphinxifthistablewithcolorrowsTF\@secondoftwo % rather than trying to remove the code added by 'colorrows' style, we % simply make it no-op, without even checking if really it was activated. \let\spx@table@toprule@rowcolorON\@empty \let\spx@table@startbodycolorrows\@empty \let\sphinxtabledecrementrownum \@empty % we don't worry about \sphinxtableafterendhook as the \spx@table@resetcolortbl % done at end can not do harm; and we could also have not bothered with the % \sphinxtabledecrementrownum as its \rownum decrement, if active, is harmless % in non-colorrows context } % (not so easy) implementation of the booktabscolorgaps option. This option % defaults to true and is not officially documented, as already colorrows is % only opt-in, so it is there only as a "turn-off" switch, but if nobody % complains in next few months, it will probably be removed altogether at % 6.0.0. The reason it exists is because of longtable aspeces described % below. % % As it is used via \sphinxsetup booktabscolorgaps status is not known here % and may change locally. So it must be implemented via delayed or % conditional code. % % We do not know the order of execution of \sphinxthistablewithbooktabsstyle % versus \sphinxthistablewithcolorrows: if booktabs is global option it % will be executed first; but if colorrows is global option and not booktabs % then colorrows will be executed first via \sphinxthistablewithglobalstyle % % Modifying things from locations such as \sphinxtabletoprulehook which are % executed within the table is not convenient as it must use \global % but then we would have to undo this after the table. % % So what we do is to prepare booktabs specific macros to incorporate % a conditional to check the colorrows status. We must each time check % both if colorrows is activated and if colorgaps is. We do this via % macros without @ so they can be used easily in customization code. % When and if booktabscolorgaps option is removed, we can then replace % \sphinxifbooktabswithcolorgapsTF by \sphinxifthistablewithcolorrowsTF \def\sphinxifbooktabswithcolorgapsTF{% \if1\ifspx@opt@booktabscolorgaps \sphinxifthistablewithcolorrowsTF{1}{0}% \else0\fi \expandafter\@firstoftwo \else\expandafter\@secondoftwo \fi } % as this is done without "@" it can be relatively easily be overwritten % by user in customization code \def\sphinxbooktabstoprule{% \sphinxifbooktabswithcolorgapsTF {\sphinxbooktabsspecialtoprule}% {\toprule}% }% \def\sphinxbooktabscolorgapsoverhang{0.1pt}% avoid pixel/rounding effects % auxiliary fork \long\def\spx@table@crazyfork #1\endfirsthead\endhead\sphinxtableatstartofbodyhook#2#3\@nil{#2} % we fetch the next token to check if there is a header or not % this is a bit fragile as it relies on the table templates % and it assumes this token #1 is never braced... % let's make this \long in case #1 is \par (should not be) \long\def\sphinxbooktabsspecialtoprule\sphinxtabletoprulehook#1{% \specialrule{\heavyrulewidth}{\abovetopsep}{\z@}% % this macro contains colour init code (and defines sphinxTableRowColor) \sphinxtabletoprulehook % unfortunately colortbl provides no way to save/restore the % \arrayrulecolor status, we have to code it ourselves \noalign{\global\let\spx@@saved@CT@arc@\CT@arc@ % \@declaredcolor is not \long. Although #1 can probably never be \par with % our templates, let's be cautious and not use the creazyfork inside the \color \spx@table@crazyfork % this crazy code checks if #1 is one of \endfirsthead, \endhead or % \sphinxtableatstartofbodyhook, as criterion for table with no header #1\endhead\sphinxtableatstartofbodyhook\@secondoftwo \endfirsthead#1\sphinxtableatstartofbodyhook\@secondoftwo \endfirsthead\endhead#1\@secondoftwo \endfirsthead\endhead\sphinxtableatstartofbodyhook\@firstoftwo \@nil {\gdef\CT@arc@{\color{sphinxTableRowColor}}}% {\gdef\CT@arc@{\color{sphinxTableRowColorOdd}}}% }% end of \noalign % \specialrule uses \noalign itself \specialrule{\dimexpr\belowrulesep+\sphinxbooktabscolorgapsoverhang\relax}% {\z@}{-\sphinxbooktabscolorgapsoverhang}% \noalign{\global\let\CT@arc@\spx@@saved@CT@arc@}% #1% let's not forget to re-insert this #1 in token stream % fortunately longtable's \endfirsthead/\endhead are not delimiters but % are really tokens awaiting expansion... }% \def\sphinxbooktabsmidrule{% \sphinxifbooktabswithcolorgapsTF {\sphinxbooktabsspecialmidrule}% {\midrule}% }% \def\sphinxbooktabsspecialmidrule{% \noalign{\global\let\spx@@saved@CT@arc@\CT@arc@ \gdef\CT@arc@{\color{sphinxTableRowColor}}% this is RowColorHeader }% \specialrule{\dimexpr\aboverulesep+\sphinxbooktabscolorgapsoverhang\relax\relax}% {-\sphinxbooktabscolorgapsoverhang}{\z@}% \noalign{\global\let\CT@arc@\spx@@saved@CT@arc@}% \specialrule{\lightrulewidth}{\z@}{\z@}% \noalign{\gdef\CT@arc@{\color{sphinxTableRowColorOdd}}}% \specialrule{\dimexpr\belowrulesep+\sphinxbooktabscolorgapsoverhang\relax\relax}% {\z@}{-\sphinxbooktabscolorgapsoverhang}% \noalign{\global\let\CT@arc@\spx@@saved@CT@arc@}% }% \def\sphinxbooktabsbottomrule{% \sphinxifbooktabswithcolorgapsTF {\sphinxbooktabsspecialbottomrule}% {\bottomrule}% }% % The colour here is already updated because of the \\ before so we must % execute again the colour selection code, but this is not too complicated. % What is annoying though is that \sphinxbottomrule in the longtable context % appears both in the "foot" part and after the last body row. For the first % occurrence the \rownum could be arbitrary if it had not been reset by each % table using it via the \sphinxtableafterendhook (see above). This avoids % having to modify the longtable template. But as \rownum is thus 0 in the % "foot", the \sphinxSwitchCaseRowColor has to know how to handle negative % inputs (in fact the -1 value), the Sphinx definition has no issue with that % but any redefinition must be aware of this constraint. \def\sphinxbooktabsspecialbottomrule{% \noalign{\global\let\spx@@saved@CT@arc@\CT@arc@ \sphinxSwitchCaseRowColor{\numexpr\rownum-\@ne\relax}% \gdef\CT@arc@{\color{sphinxTableRowColor}}% }% \specialrule{\dimexpr\aboverulesep+\sphinxbooktabscolorgapsoverhang\relax}% {-\sphinxbooktabscolorgapsoverhang}{\z@}% \noalign{\global\let\CT@arc@\spx@@saved@CT@arc@}% \specialrule{\heavyrulewidth}{\z@}{\belowbottomsep}% }% % % MEMO: with longtable \sphinxtoprule, \sphinxmidrule and \sphinxbottomrule % are evaluated at time of constructing the headers and footers as boxes % (already typeset material and expanded macros; \sphinxbottomrule is also % evaluated at very end of table body, i.e. "normally"). So the used colour % to fill the booktabs gaps is decided during the headers and footers % construction by longtable. Actually they are expanded twice: in firsthead % then in head, respectively in foot and lastfoot. But in current design the % header row colours are fixed, not alternating, so there is at least no % coherence issue there. % The \spx@arrayrulewidth is used for some complex matters of merged % cells size computations. % tabularcolumns argument will override any global or local style and % trigger the appropriate adjustment of \spx@arrayrulewidth. % Notice that this will be bad if the table uses booktabs style % but anyhow table with booktabs should not use any | separator. \def\sphinxthistablewithvlinesstyle{% \def\spx@arrayrulewidth{\arrayrulewidth}% \let\sphinxvlinecrossing\sphinxtablevlinecrossing \let\sphinxfixclines \sphinxtablefixclines }% \def\sphinxthistablewithnovlinesstyle{% \def\spx@arrayrulewidth{\z@}% \let\sphinxvlinecrossing\@gobble % let's not bother to modify \sphinxfixclines, it works fine and is % useful in standard style + no vline (only hlines and clines); % besides, only one of vline or novline style macro is executed }% % default is the standard style \def\sphinxthistablewithglobalstyle{\sphinxthistablewithstandardstyle} \ifspx@opt@booktabs \RequirePackage{booktabs} \def\sphinxthistablewithglobalstyle{\sphinxthistablewithbooktabsstyle} \fi \ifspx@opt@borderless \def\sphinxthistablewithglobalstyle{\sphinxthistablewithborderlessstyle} \fi % colorrows appends to the current globalstyle (standard, booktabs, or borderless) \ifspx@opt@colorrows % let the globalstyle trigger the colorrows style on top of it \expandafter\def\expandafter\sphinxthistablewithglobalstyle\expandafter {\sphinxthistablewithglobalstyle \sphinxthistablewithcolorrowsstyle } \fi \endinput krb5-1.22.1/doc/pdf/sphinxoptionsgeometry.sty0000664000175000017500000000401514577122106021127 0ustar ghudsonghudson%% OPTIONS FOR GEOMETRY % % change this info string if making any custom modification \ProvidesFile{sphinxoptionsgeometry.sty}[2021/01/27 geometry] % geometry \ifx\kanjiskip\@undefined \PassOptionsToPackage{% hmargin={\unexpanded{\spx@opt@hmargin}},% vmargin={\unexpanded{\spx@opt@vmargin}},% marginpar=\unexpanded{\spx@opt@marginpar}} {geometry} \else % set text width for Japanese documents to be integer multiple of 1zw % and text height to be integer multiple of \baselineskip % the execution is delayed to \sphinxsetup then geometry.sty \normalsize\normalfont \newcommand*\sphinxtextwidthja[1]{% \if@twocolumn\tw@\fi \dimexpr \numexpr\dimexpr\paperwidth-\tw@\dimexpr#1\relax\relax/ \dimexpr\if@twocolumn\tw@\else\@ne\fi zw\relax zw\relax}% \newcommand*\sphinxmarginparwidthja[1]{% \dimexpr\numexpr\dimexpr#1\relax/\dimexpr1zw\relax zw\relax}% \newcommand*\sphinxtextlinesja[1]{% \numexpr\@ne+\dimexpr\paperheight-\topskip-\tw@\dimexpr#1\relax\relax/ \baselineskip\relax}% \ifx\@jsc@uplatextrue\@undefined\else % the way we found in order for the papersize special written by % geometry in the dvi file to be correct in case of jsbook class \ifnum\mag=\@m\else % do nothing special if nomag class option or 10pt \PassOptionsToPackage{truedimen}{geometry}% \fi \fi \PassOptionsToPackage{% hmarginratio={1:1},% textwidth=\unexpanded{\sphinxtextwidthja{\spx@opt@hmargin}},% vmarginratio={1:1},% lines=\unexpanded{\sphinxtextlinesja{\spx@opt@vmargin}},% marginpar=\unexpanded{\sphinxmarginparwidthja{\spx@opt@marginpar}},% footskip=2\baselineskip,% }{geometry}% \AtBeginDocument {% update a dimension used by the jsclasses \ifx\@jsc@uplatextrue\@undefined\else\fullwidth\textwidth\fi % for some reason, jreport normalizes all dimensions with \@settopoint \@ifclassloaded{jreport} {\@settopoint\textwidth\@settopoint\textheight\@settopoint\marginparwidth} {}% <-- "false" clause of \@ifclassloaded }% \fi \endinput krb5-1.22.1/doc/pdf/sphinxlatexliterals.sty0000664000175000017500000013174014577122106020543 0ustar ghudsonghudson%% LITERAL BLOCKS % % change this info string if making any custom modification \ProvidesFile{sphinxlatexliterals.sty}[2023/04/01 code-blocks and parsed literals] % Provides support for this output mark-up from Sphinx latex writer: % % - macros: % - \sphinxLiteralBlockLabel % - \sphinxSetupCaptionForVerbatim % - \sphinxSetupCodeBlockInFootnote % - \sphinxhref % - \sphinxnolinkurl % - \sphinxresetverbatimhllines % - \sphinxunactivateextrasandspace % - \sphinxupquote % - \sphinxurl % % - environments: % - sphinxVerbatim % - sphinxVerbatimintable % - sphinxalltt % % Dependency: % % - hyperref (for \phantomsection and \capstart) (loaded later) % % Executes \RequirePackage for: % % - framed % - fancyvrb % - alltt % - upquote % - needspace % - sphinxpackageboxes \RequirePackage{sphinxpackageboxes} % also in sphinxlatexadmonitions.sty: % This is a workaround to a "feature" of French lists, when literal block % follows immediately; usable generally (does only \par then), a priori... \providecommand*\sphinxvspacefixafterfrenchlists{% \ifvmode\ifdim\lastskip<\z@ \vskip\parskip\fi\else\par\fi } % For framing allowing pagebreaks \RequirePackage{framed} % For source code % MEMO: fancyvrb is used mainly to % 1- control horizontal and vertical spacing % 2- optional line numbering % 3- optional line emphasizing % 4- while still allowing expansion of Pygments latex mark-up % Other aspects such as framing, caption handling, codeline wrapping are % added on top of it. We should stop using fancyvrb and implement % 1, 2, 3, 4 by own Sphinx fully native Verbatim. This would greatly simplify % in particular wrapping long code lines in a way allowing page breaks. \RequirePackage{fancyvrb} % For parsed-literal blocks. \RequirePackage{alltt} % Display "real" single quotes in literal blocks. \RequirePackage{upquote} % Skip to next page if not enough space at bottom \RequirePackage{needspace} % Based on use of "fancyvrb.sty"'s Verbatim. % - with framing allowing page breaks ("framed.sty") % - with breaking of long lines (exploits Pygments mark-up), % - with possibly of a top caption, non-separable by pagebreak. % - and usable inside tables or footnotes ("sphinxpackagefootnote.sty"). % for emphasizing lines \define@key{FV}{hllines}{\def\sphinx@verbatim@checkifhl##1{\in@{, ##1,}{#1}}} % sphinxVerbatim must be usable by third party without requiring hllines set-up \def\sphinxresetverbatimhllines{\def\sphinx@verbatim@checkifhl##1{\in@false}} \sphinxresetverbatimhllines % Prior to Sphinx 1.5, \Verbatim and \endVerbatim were modified by Sphinx. % The aliases defined here are used in sphinxVerbatim environment and can % serve as hook-points with no need to modify \Verbatim itself. \let\OriginalVerbatim \Verbatim \let\endOriginalVerbatim\endVerbatim % for captions of literal blocks % at start of caption title \newcommand*{\fnum@literalblock}{\literalblockname\nobreakspace\theliteralblock} % this will be overwritten in document preamble by Babel translation \newcommand*{\literalblockname}{Listing } % file extension needed for \caption's good functioning, the file is created % only if a \listof{literalblock}{foo} command is encountered, which is % analogous to \listoffigures, but for the code listings (foo = chosen title.) \newcommand*{\ext@literalblock}{lol} % if forced use of minipage encapsulation is needed (e.g. table cells) \newif\ifsphinxverbatimwithminipage \sphinxverbatimwithminipagefalse % Framing macro for use with framed.sty's \FrameCommand % MEMO: the sophisticated code in \spx@fcolorbox/\spx@CustomFBox % is here for good reasons % - be responsive to indented list environments in the manner of % the "framed" (\fbox) and "shaded" (\colorbox) environments of % framed.sty; indeed code here is an evolution related to \fcolorbox % - attach non-detachable continuation hints above/below frame % - draw the frame and fill the background color in a manner avoiding % problems in some pdf viewers % - do background coloring differently from color.sty/xcolor.sty macros % (even core internal ones) to work around issues at page breaks % as the framed contents are split into chunks with possibly unpaired % "color push" or "color pop" % About the produced output: % - it obeys current indentation, % - frame with 4 padding parameters and 4 border-width parameters % - the contents use the full available text width, limited by indentation, % - #1 = will be typeset above frame, in a non detachable way, % - #2 = will be typeset below frame, in a non detachable way, % - #3 = will be typeset within the frame. % #1 and #2 are expected to be already typeset \hbox'es. % #3 are the contents, and in the context of usage of fancyvrb+framed, % it will arrive here already transformed into horizontal boxes, % interline penalties and glues. % \long\def\spx@verb@FrameCommand #1#2#3{% % The \spx@verb@boxes@fcolorbox@setup MUST have been executed beforehand. % These \hskips are for fancyvrb.sty measuring and will make the % framing "adapt" to an indented context. \hskip\@totalleftmargin \hskip-\spx@boxes@border@left\hskip-\spx@boxes@padding@left \spx@verb@fcolorbox {#1}{#2}{#3}% \hskip-\spx@boxes@padding@right\hskip-\spx@boxes@border@right \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth }% \long\def\spx@verb@fcolorbox #1#2#3{% % The \spx@verb@boxes@fcolorbox@setup MUST have been executed beforehand. % % MEMO: in the context of framed.sty this will always expand inside some % \hbox isolated from other code, so we can use \box\z@, \box\tw@,... % with no need of extra group. % % MEMO: this code was originally using \color@b@x but the latter has % problematic features regarding color in a context like here where #3 % may contain an unbalanced "color push". % \setbox\z@\hbox{#3}% \edef\spx@verb@fcolorbox@width@sp {\number\dimexpr\wd\z@+\spx@boxes@border@left +\spx@boxes@padding@left +\spx@boxes@padding@right +\spx@boxes@border@right\relax sp}% \vbox{#1% continuation hint attached above frame, uses \spx@verb@fcolorbox@width@sp % the boxes@fcolorbox constructs an \hbox with bbox containing the border % \spx@verb@boxes@fcolorbox@setup MUST have been executed beforehand. \spx@boxes@fcolorbox{\box\z@}% % This \nointerlineskip to maintain legacy spacing when a \hrule was % formerly last prior item in vertical list. TODO: remove this at 6.0.0 ? \nointerlineskip #2% continuation hint attached below frame, uses \spx@verb@fcolorbox@width@sp }% end of \vbox }% \def\spx@verb@fcolorbox@put@c#1{% hide width from framed.sty measuring \moveright.5\dimexpr\spx@verb@fcolorbox@width@sp\hb@xt@\z@{\hss#1\hss}% }% \def\spx@verb@fcolorbox@put@r#1{% right align with contents, width hidden \moveright\dimexpr\spx@verb@fcolorbox@width@sp-% \spx@boxes@padding@right-% \spx@boxes@border@right\hb@xt@\z@{\hss#1}% }% \def\spx@verb@fcolorbox@put@l#1{% left align with contents, width hidden \moveright\dimexpr\spx@boxes@border@left+% \spx@boxes@padding@left\hb@xt@\z@{#1\hss}% }% % \def\sphinxVerbatim@Continued{% \csname spx@verb@fcolorbox@put@\spx@opt@verbatimcontinuedalign\endcsname {{\normalcolor\sphinxstylecodecontinued\literalblockcontinuedname}}% }% \def\sphinxVerbatim@Continues{% \csname spx@verb@fcolorbox@put@\spx@opt@verbatimcontinuesalign\endcsname {{\normalcolor\sphinxstylecodecontinues\literalblockcontinuesname}}% }% \def\sphinxVerbatim@Title{% \spx@verb@fcolorbox@put@c{\unhcopy\sphinxVerbatim@TitleBox}% }% \let\sphinxVerbatim@Before\@empty \let\sphinxVerbatim@After\@empty % Defaults are redefined in document preamble according to language \newcommand*\literalblockcontinuedname{continued from previous page}% \newcommand*\literalblockcontinuesname{continues on next page}% % \def\sphinxVerbatim@FrameCommand{% \spx@verb@FrameCommand\sphinxVerbatim@Before\sphinxVerbatim@After }% \def\sphinxVerbatim@FirstFrameCommand{% \ifspx@pre@border@open \spx@boxes@fcolorbox@setup@openbottom \fi \spx@verb@FrameCommand\sphinxVerbatim@Before\sphinxVerbatim@Continues }% \def\sphinxVerbatim@MidFrameCommand{% \ifspx@pre@border@open \spx@boxes@fcolorbox@setup@openboth \fi \spx@verb@FrameCommand\sphinxVerbatim@Continued\sphinxVerbatim@Continues }% \def\sphinxVerbatim@LastFrameCommand{% \ifspx@pre@border@open \spx@boxes@fcolorbox@setup@opentop \fi \spx@verb@FrameCommand\sphinxVerbatim@Continued\sphinxVerbatim@After }% % \def\spx@verb@boxes@fcolorbox@setup{% % Prepares usage of \spx@boxes@fcolorbox % Extras to remap legacy color names VerbatimBorderColor and VerbatimColor % to a common naming scheme with admonitions (and topic directive), as % expected by \spx@boxes@fcolorbox@setup from sphinxpackageboxes.sty. \sphinxcolorlet{sphinxpreBorderColor}{VerbatimBorderColor}% \sphinxcolorlet{sphinxpreBgColor}{VerbatimColor}% % This VerbatimShadowColor is not a legacy name nor user documented but is % an outcome of sphinx.sty batch definitions for CSS option support. \sphinxcolorlet{sphinxpreShadowColor}{VerbatimShadowColor}% \spx@boxes@fcolorbox@setup{pre}% \ifspx@opt@verbatimwithframe \else \spx@boxes@border@top\z@ \spx@boxes@border@right\z@ \spx@boxes@border@bottom\z@ \spx@boxes@border@left\z@ \spx@boxes@border\z@ % MEMO: rounded corners still make sense in presence of a background % color, so we do not force the fcolorbox@rectangle here \fi }% % For linebreaks inside Verbatim environment from package fancyvrb. \newbox\sphinxcontinuationbox \newbox\sphinxvisiblespacebox \newcommand*\sphinxafterbreak {\copy\sphinxcontinuationbox} % Take advantage of the already applied Pygments mark-up to insert % potential linebreaks for TeX processing. % {, <, #, %, $, ' and ": go to next line. % _, }, ^, &, >, -, ~, and \: stay at end of broken line. % Use of \textquotesingle for straight quote. % FIXME: convert this to package options ? \newcommand*\sphinxbreaksbeforelist {% \do\PYGZob\{\do\PYGZlt\<\do\PYGZsh\#\do\PYGZpc\%% {, <, #, %, \do\PYGZdl\$\do\PYGZdq\"% $, " \def\PYGZsq {\discretionary{}{\sphinxafterbreak\textquotesingle}{\textquotesingle}}% ' } \newcommand*\sphinxbreaksafterlist {% \do\PYGZus\_\do\PYGZcb\}\do\PYGZca\^\do\PYGZam\&% _, }, ^, &, \do\PYGZgt\>\do\PYGZhy\-\do\PYGZti\~% >, -, ~ \do\PYGZbs\\% \ } \newcommand*\sphinxbreaksatspecials {% \def\do##1##2% {\def##1{\discretionary{}{\sphinxafterbreak\char`##2}{\char`##2}}}% \sphinxbreaksbeforelist \def\do##1##2% {\def##1{\discretionary{\char`##2}{\sphinxafterbreak}{\char`##2}}}% \sphinxbreaksafterlist } \def\sphinx@verbatim@nolig@list {\do \`}% % Some characters . , ; ? ! / are neither pygmentized nor "tex-escaped". % This macro makes them "active" and they will insert potential linebreaks. % Not compatible with math mode (cf \sphinxunactivateextras, which uses % these lists to make sure activated characters get de-activated). \newcommand*\sphinxbreaksbeforeactivelist {}% none \newcommand*\sphinxbreaksafteractivelist {\do\.\do\,\do\;\do\?\do\!\do\/} \newcommand*\sphinxbreaksviaactive {% \def\do##1{\lccode`\~`##1% \lowercase{\def~}{\discretionary{}{\sphinxafterbreak\char`##1}{\char`##1}}% \catcode`##1\active}% \sphinxbreaksbeforeactivelist \def\do##1{\lccode`\~`##1% \lowercase{\def~}{\discretionary{\char`##1}{\sphinxafterbreak}{\char`##1}}% \catcode`##1\active}% \sphinxbreaksafteractivelist \lccode`\~`\~ } % If the linebreak is at a space, the latter will be displayed as visible % space at end of first line, and a continuation symbol starts next line. \def\spx@verbatim@space {% \nobreak\hskip\z@skip \discretionary{\copy\sphinxvisiblespacebox}{\sphinxafterbreak} {\kern\fontdimen2\font}% }% % if the available space on page is less than \literalblockneedspace, insert pagebreak \newcommand{\sphinxliteralblockneedspace}{5\baselineskip} \newcommand{\sphinxliteralblockwithoutcaptionneedspace}{1.5\baselineskip} % The title (caption) is specified from outside as macro \sphinxVerbatimTitle. % \sphinxVerbatimTitle is reset to empty after each use of Verbatim. \newcommand*\sphinxVerbatimTitle {} % This box to typeset the caption before framed.sty multiple passes for framing. \newbox\sphinxVerbatim@TitleBox % This box to measure contents if nested as inner \MakeFramed requires then % minipage encapsulation but too long contents then break outer \MakeFramed \newbox\sphinxVerbatim@ContentsBox % Holder macro for labels of literal blocks. Set-up by LaTeX writer. \newcommand*\sphinxLiteralBlockLabel {} \newcommand*\sphinxSetupCaptionForVerbatim [1] {% \sphinxvspacefixafterfrenchlists \needspace{\sphinxliteralblockneedspace}% % insert a \label via \sphinxLiteralBlockLabel % reset to normal the color for the literal block caption \def\sphinxVerbatimTitle {\py@NormalColor\sphinxcaption{\sphinxLiteralBlockLabel #1}}% } \newcommand*\sphinxSetupCodeBlockInFootnote {% \fvset{fontsize=\footnotesize}\let\caption\sphinxfigcaption \sphinxverbatimwithminipagetrue % reduces vertical spaces % we counteract (this is in a group) the \@normalsize from \caption \let\normalsize\footnotesize\let\@parboxrestore\relax \def\spx@abovecaptionskip{\sphinxverbatimsmallskipamount}% } \newcommand*{\sphinxverbatimsmallskipamount}{\smallskipamount} % serves to implement line highlighting \newcommand\sphinxFancyVerbFormatLine[1]{% \expandafter\sphinx@verbatim@checkifhl\expandafter{\the\FV@CodeLineNo}% \ifin@ \sphinxVerbatimHighlightLine{#1}% \else \sphinxVerbatimFormatLine{#1}% \fi }% \let\spx@original@set@color\set@color \newcommand\sphinxVerbatimHighlightLine[1]{% % This is morally a \colorbox (with a \fboxsep which would be 0pt) % but some issues of potential colour disappearance at pagebreaks % require workaround such as the one done here. \leavevmode % MEMO: usage of original \colorbox would insert a \set@color here % and this then places a "color pop" at the end of the \box\z@. % But this could pair erroneously with an unmatched "color push" % as #1 is maybe only a part (already hboxed) of a codeline % if (default) verbatimwrapslines=true % (cf \spx@verb@@PreProcessLine; refs: #8686) % MEMO: formerly we did something with \fboxsep in relation to the LaTeX % bug graphics/4524 for \colorbox, but as we don't use \colorbox... \setbox\z@\hb@xt@\linewidth{\strut#1\hss}% % MEMO: \colorbox would lead to \color{sphinxVerbatimHighlightColor} % plus \color@block, which results in doubled (a color.sty feature) % color command send to device driver and more importantly has % a "color pop" which will be after \box\z@. We avoid that for reasons % mentioned above. {% \def\set@color{\let\set@color\spx@original@set@color}% % will only set \current@color and delay the \set@color to \color@block % as this all happens inside fancyvrb nested \hbox'es. \color{sphinxVerbatimHighlightColor}% % will use \current@color and pop it **before** \box\z@ \color@block{\wd\z@}{\ht\z@}{\dp\z@}\box\z@ }% % we added a group only for \FV@RightListNumber not be influenced by the % \current@color, if \fvset has been used to set numbers to the right. }% % MEMO: fancyvrb has options obeytabs and tabsize. Anyhow tab characters % do not make it to the tex file, they have been converted to spaces earlier. % But, if this was not the case, the support would be implemented here via % \newcommand\sphinxVerbatimFormatLine[1]{\FV@ObeyTabs{\strut #1}}% \newcommand\sphinxVerbatimFormatLine[1]{\strut#1}% % MEMO: if verbatimwrapslines is set to true (default) the #1 above is % simply \box\spx@tempboxb, from the next two macros. % The next two macros are a deep hack of fancyvrb.sty core line processing in % order to wrap too long lines, either at spaces and natural break-points, % (soft wrap) or optionally at any character (hard wrap). This requires deep % hack to work around the \hbox'es wrappers of fancyvrb.sty as they would % prevent page breaks. Formerly Sphinx obtained wrapping by inserting the % material into a vertical box (which was later again boxed -- twice -- by % fancyvrb thinking it was a single line...) but this was incompatible with % allowing page breaks (refs: #8686). % We use core TeX techniques to pre-process a paragraph then recover its % constituents lines (as boxes, not as tokens) and hand them over to original % fancyvrb line process. It is mandatory to update \FV@ProcessLine and % \@tempboxa globally to get fancyvrb internals into working to our % satisfaction. % This will get disrupted if anything adding vertical penalties or glues % is activated via some \vadjust from inside the Pygmentized code lines. \def\spx@verb@@ProcessLines{% \unskip \unpenalty \setbox\spx@tempboxb\lastbox \ifvoid\spx@tempboxb\else {\spx@verb@@ProcessLines}% \FV@ProcessLine{\box\spx@tempboxb}% \global\let\FV@ProcessLine\FV@ProcessLine \global\setbox\@tempboxa=\box\@tempboxa \aftergroup\spx@verb@@InhibitLineNumber \fi }% \def\spx@verb@@InhibitLineNumber{% \let\FV@LeftListNumber\relax \let\FV@RightListNumber\relax }% % This will replace fancyvrb's \FV@@PreProcessLine % Instead of boxing \FV@Line (which contains the Pygmentized line tokens), we % first typeset it in a vertical box of the suitable width (taking into % account nested lists) to activate the TeX built-in paragraph builder, then % we recover individual lines as horizontal boxes and feed them to fancyvrb % native line processing (which may add line numbers). The interline % penalties and vertical glue to maintain baseline distance will be added % again by this process so in recursive \spx@verb@@ProcessLines which starts % from bottom and makes its way up to first part of the wrapped line we do not % need to worry about them. An additional initial measuring step is needed if % user issued verbatimforcewraps=true, which elaborates on the same technique. % If hard wraps get activated, they get implemented via hacked \PYG macros. \def\spx@verb@@PreProcessLine{% \FV@StepLineNo \FV@Gobble \def\spx@verb@FV@Line{\FV@Line}% \ifspx@opt@verbatimforcewraps \spx@verb@DecideIfWillDoForceWrap \fi % MEMO: \everypar{} was issued earlier (and due to \@setminipage % would have been only \@minipagefalse\everypar{} otherwise). \setbox\spx@tempboxa=\vtop{\hsize\linewidth \raggedright\hyphenpenalty\z@\exhyphenpenalty\z@ \doublehyphendemerits\z@\finalhyphendemerits\z@ % MEMO: fancyvrb has options obeytabs and tabsize. Anyhow tab characters % do not make it to the tex file, they have been converted to spaces earlier. % But, if this was not the case, the support would be implemented here via % \FV@ObeyTabs{\strut\spx@verb@FV@Line\strut}% % And one would need a similar change in the measuring phase done by % \spx@verb@DecideIfWillDoForceWrap \strut\spx@verb@FV@Line\strut % MEMO: since LaTeX 2021-06-01, there might be some hooks executed at % start and end of paragraphs (in future: PDF tagging), but we need an % explicit \par here for that. Else the kernel hooks at start of paragraph % are executed but not the ones at its end. \par }% \setbox\spx@tempboxa=\vtop{\unvbox\spx@tempboxa \setbox\spx@tempboxb\lastbox {\spx@verb@@ProcessLines}% \FV@ProcessLine{\box\spx@tempboxb}% \global\let\FV@ProcessLine\FV@ProcessLine \global\setbox\@tempboxa=\box\@tempboxa }% \unvbox\spx@tempboxa }% % % The normal line wrapping allows breaks at spaces and ascii non % letters, non digits. The \raggedright above means there will be % an overfilled line only if some non-breakable "word" was % encountered, which is longer than a line (it is moved always to % be on its own on a new line). % % The "forced" line wrapping will parse the tokens to add potential % breakpoints at each character. As some strings are highlighted, % we have to apply the highlighting character per character, which % requires to manipulate the output of the Pygments LaTeXFormatter. % % Doing this at latex level is complicated. The contents should % be as expected: i.e. some active characters from % \sphinxbreaksviaactive, some Pygments character escapes such as % \PYGZdl{}, and the highlighting \PYG macro with always 2 % arguments. No other macros should be there, except perhaps % zero-parameter macros. In particular: % - the texcomments Pygments option must be set to False % % With pdflatex, Unicode input gives multi-bytes characters % where the first byte is active. We support the "utf8" macros % only. "utf8x" is not supported. % % The highlighting macro \PYG will be applied character per % character. Highlighting via a colored background gives thus a % chain of small colored boxes which may cause some artefact in % some pdf viewers. Can't do anything here if we do want the line % break to be possible. % % First a measurement step is done of what would the standard line % wrapping give (i.e line breaks only at spaces and non-letter, % non-digit ascii characters), cf TeX by Topic for the basic % dissecting technique: TeX unfortunately when building a vertical % box does not store in an accessible way what was the maximal % line-width during paragraph building. % % MEMO: in future use perhaps rather \RawNoindent/\RawParEnd, but % ltpara (LaTeX 2021-06-01) is not yet in final form (June 2022). % % Avoid LaTeX 2021 alteration of \@@par which potentially could break our % measurement step (typically if the para/after hook is configured to use % \vspace). Of course, breakage could happen only from user or package % adding things to basic Sphinx latex. And perhaps spring LaTeX 2021 will % provide a non-hooked \@@par, but this should work anyway and can't be % beaten for speed. \ltx@ifundefined{tex_par:D} % We could use \@ifl@t@r\fmtversion{2020/02/02}{use \tex_par:D}{use \@@par}. {\let\spx@par\@@par}% \@@par is then expected to be TeX's original \par {\expandafter\let\expandafter\spx@par\csname tex_par:D\endcsname} % More hesitation for avoiding the at-start-of-par hooks for our % measurement : 1. with old LaTeX, we can not avoid hooks from everyhook % or similar packages, 2. and perhaps the hooks add stuff which we should % actually measure. Ideally, hooks are for inserting things in margin % which do not change spacing. Most everything else in fact should not be % executed in our scratch box for measurement, such as counter stepping. \ltx@ifundefined{tex_everypar:D} {\let\spx@everypar\everypar} {\expandafter\let\expandafter\spx@everypar\csname tex_everypar:D\endcsname} % % If the max width exceeds the linewidth by more than verbatimmaxoverfull % character widths, or if the min width plus verbatimmaxunderfull character % widths is inferior to linewidth, then we apply the "force wrapping" with % potential line break at each character, else we don't. \long\def\spx@verb@DecideIfWillDoForceWrap{% \global\let\spx@verb@maxwidth\z@ \global\let\spx@verb@minwidth\linewidth \setbox\spx@tempboxa \vtop{\raggedright\hyphenpenalty\z@\exhyphenpenalty\z@ \doublehyphendemerits\z@\finalhyphendemerits\z@ \spx@everypar{}\noindent\strut\FV@Line\strut\spx@par \spx@verb@getwidths}% \ifdim\spx@verb@maxwidth> \dimexpr\linewidth+\spx@opt@verbatimmaxoverfull\fontcharwd\font`X \relax % The \expandafter is due to \spx@verb@wrapPYG requiring to "see" the TeX tokens % from the pygmentize output. \def\spx@verb@FV@Line{\expandafter\spx@verb@wrapPYG\FV@Line\spx@verb@wrapPYG}% \else \ifdim\spx@verb@minwidth< \dimexpr\linewidth-\spx@opt@verbatimmaxunderfull\fontcharwd\font`X \relax \def\spx@verb@FV@Line{\expandafter\spx@verb@wrapPYG\FV@Line\spx@verb@wrapPYG}% \fi \fi }% % auxiliary paragraph dissector to get max and min widths % but minwidth must not take into account the last line \def\spx@verb@getwidths {% \unskip\unpenalty \setbox\spx@tempboxb\lastbox \ifvoid\spx@tempboxb \else \setbox\spx@tempboxb\hbox{\unhbox\spx@tempboxb}% \ifdim\spx@verb@maxwidth<\wd\spx@tempboxb \xdef\spx@verb@maxwidth{\number\wd\spx@tempboxb sp}% \fi \expandafter\spx@verb@getwidths@loop \fi }% \def\spx@verb@getwidths@loop {% \unskip\unpenalty \setbox\spx@tempboxb\lastbox \ifvoid\spx@tempboxb \else \setbox\spx@tempboxb\hbox{\unhbox\spx@tempboxb}% \ifdim\spx@verb@maxwidth<\wd\spx@tempboxb \xdef\spx@verb@maxwidth{\number\wd\spx@tempboxb sp}% \fi \ifdim\spx@verb@minwidth>\wd\spx@tempboxb \xdef\spx@verb@minwidth{\number\wd\spx@tempboxb sp}% \fi \expandafter\spx@verb@getwidths@loop \fi }% % auxiliary macros to implement "cut long line even in middle of word" \catcode`Z=3 % safe delimiter \def\spx@verb@wrapPYG{% \futurelet\spx@nexttoken\spx@verb@wrapPYG@i }% \def\spx@verb@wrapPYG@i{% \ifx\spx@nexttoken\spx@verb@wrapPYG\let\next=\@gobble\else \ifx\spx@nexttoken\PYG\let\next=\spx@verb@wrapPYG@PYG@onebyone\else \discretionary{}{\sphinxafterbreak}{}% \let\next\spx@verb@wrapPYG@ii \fi\fi \next }% % Let's recognize active characters. We don't support utf8x only utf8. % And here #1 should not have picked up (non empty) braced contents \long\def\spx@verb@wrapPYG@ii#1{% \ifcat\noexpand~\noexpand#1\relax% active character \expandafter\spx@verb@wrapPYG@active \else % non-active character, control sequence such as \PYGZdl, or empty \expandafter\spx@verb@wrapPYG@one \fi {#1}% }% \long\def\spx@verb@wrapPYG@active#1{% % Let's hope expansion of active character does not really require arguments, % as we certainly don't want to go into expanding upfront token stream anyway. \expandafter\spx@verb@wrapPYG@iii#1{}{}{}{}{}{}{}{}{}Z#1% }% \long\def\spx@verb@wrapPYG@iii#1#2Z{% \ifx\UTFviii@four@octets#1\let\next=\spx@verb@wrapPYG@four\else \ifx\UTFviii@three@octets#1\let\next=\spx@verb@wrapPYG@three\else \ifx\UTFviii@two@octets#1\let\next=\spx@verb@wrapPYG@two\else \let\next=\spx@verb@wrapPYG@one \fi\fi\fi \next }% \long\def\spx@verb@wrapPYG@one #1{#1\futurelet\spx@nexttoken\spx@verb@wrapPYG@i}% \long\def\spx@verb@wrapPYG@two #1#2{#1#2\futurelet\spx@nexttoken\spx@verb@wrapPYG@i}% \long\def\spx@verb@wrapPYG@three #1#2#3{#1#2#3\futurelet\spx@nexttoken\spx@verb@wrapPYG@i}% \long\def\spx@verb@wrapPYG@four #1#2#3#4{#1#2#3#4\futurelet\spx@nexttoken\spx@verb@wrapPYG@i}% % Replace \PYG by itself applied one character at a time! This way breakpoints % can be inserted. \def\spx@verb@wrapPYG@PYG@onebyone#1#2#3{% #1 = \PYG, #2 = highlight spec, #3 = tokens \def\spx@verb@wrapPYG@PYG@spec{{#2}}% \futurelet\spx@nexttoken\spx@verb@wrapPYG@PYG@i#3Z% }% \def\spx@verb@wrapPYG@PYG@i{% \ifx\spx@nexttokenZ\let\next=\spx@verb@wrapPYG@PYG@done\else \discretionary{}{\sphinxafterbreak}{}% \let\next\spx@verb@wrapPYG@PYG@ii \fi \next }% \def\spx@verb@wrapPYG@PYG@doneZ{\futurelet\spx@nexttoken\spx@verb@wrapPYG@i}% \long\def\spx@verb@wrapPYG@PYG@ii#1{% \ifcat\noexpand~\noexpand#1\relax% active character \expandafter\spx@verb@wrapPYG@PYG@active \else % non-active character, control sequence such as \PYGZdl, or empty \expandafter\spx@verb@wrapPYG@PYG@one \fi {#1}% }% \long\def\spx@verb@wrapPYG@PYG@active#1{% % Let's hope expansion of active character does not really require arguments, % as we certainly don't want to go into expanding upfront token stream anyway. \expandafter\spx@verb@wrapPYG@PYG@iii#1{}{}{}{}{}{}{}{}{}Z#1% }% \long\def\spx@verb@wrapPYG@PYG@iii#1#2Z{% \ifx\UTFviii@four@octets#1\let\next=\spx@verb@wrapPYG@PYG@four\else \ifx\UTFviii@three@octets#1\let\next=\spx@verb@wrapPYG@PYG@three\else \ifx\UTFviii@two@octets#1\let\next=\spx@verb@wrapPYG@PYG@two\else \let\next=\spx@verb@wrapPYG@PYG@one \fi\fi\fi \next }% \long\def\spx@verb@wrapPYG@PYG@one#1{% \expandafter\PYG\spx@verb@wrapPYG@PYG@spec{#1}% \futurelet\spx@nexttoken\spx@verb@wrapPYG@PYG@i }% \long\def\spx@verb@wrapPYG@PYG@two#1#2{% \expandafter\PYG\spx@verb@wrapPYG@PYG@spec{#1#2}% \futurelet\spx@nexttoken\spx@verb@wrapPYG@PYG@i }% \long\def\spx@verb@wrapPYG@PYG@three#1#2#3{% \expandafter\PYG\spx@verb@wrapPYG@PYG@spec{#1#2#3}% \futurelet\spx@nexttoken\spx@verb@wrapPYG@PYG@i }% \long\def\spx@verb@wrapPYG@PYG@four#1#2#3#4{% \expandafter\PYG\spx@verb@wrapPYG@PYG@spec{#1#2#3#4}% \futurelet\spx@nexttoken\spx@verb@wrapPYG@PYG@i }% \catcode`Z 11 % % \g@addto@macro\FV@SetupFont{% \sbox\sphinxcontinuationbox {\spx@opt@verbatimcontinued}% \sbox\sphinxvisiblespacebox {\spx@opt@verbatimvisiblespace}% }% \newenvironment{sphinxVerbatim}{% % first, let's check if there is a caption \ifx\sphinxVerbatimTitle\empty \sphinxvspacefixafterfrenchlists \parskip\z@skip \vskip\sphinxverbatimsmallskipamount % there was no caption. Check if nevertheless a label was set. \ifx\sphinxLiteralBlockLabel\empty\else % we require some space to be sure hyperlink target from \phantomsection % will not be separated from upcoming verbatim by a page break \needspace{\sphinxliteralblockwithoutcaptionneedspace}% \phantomsection\sphinxLiteralBlockLabel \fi \else \parskip\z@skip \if t\spx@opt@literalblockcappos \vskip\spx@abovecaptionskip \def\sphinxVerbatim@Before {\sphinxVerbatim@Title\nointerlineskip \kern\dimexpr-\dp\strutbox+\sphinxbelowcaptionspace % if no frame (code-blocks inside table cells), remove % the top padding (better visually) \ifspx@opt@verbatimwithframe\else % but we must now check if there is a background color % MEMO: "fcolorbox@setup" will have been done by time of use \ifspx@boxes@withbackgroundcolor\else-\spx@boxes@padding@top\fi \fi % caption package adds \abovecaptionskip vspace, remove it \spx@ifcaptionpackage{-\abovecaptionskip}{}\relax}% \else \vskip\sphinxverbatimsmallskipamount \def\sphinxVerbatim@After {\nointerlineskip\kern\dimexpr\dp\strutbox \ifspx@opt@verbatimwithframe\else % but we must now check if there is a background color % MEMO: "fcolorbox@setup" will have been done by time of use \ifspx@boxes@withbackgroundcolor\else-\spx@boxes@padding@bottom\fi \fi \spx@ifcaptionpackage{-\abovecaptionskip}{}\relax \sphinxVerbatim@Title}% \fi \def\@captype{literalblock}% \capstart % \sphinxVerbatimTitle must reset color \setbox\sphinxVerbatim@TitleBox \hbox{\begin{minipage}{\linewidth}% % caption package may detect wrongly if top or bottom, so we help it \spx@ifcaptionpackage {\caption@setposition{\spx@opt@literalblockcappos}}{}% \sphinxVerbatimTitle \end{minipage}}% \fi \global\let\sphinxLiteralBlockLabel\empty \global\let\sphinxVerbatimTitle\empty % the "FrameCommand"'s are also responsible to attach the "Title". \let\FrameCommand \sphinxVerbatim@FrameCommand % those will also check status of the pre_box-decoration-break option \let\FirstFrameCommand\sphinxVerbatim@FirstFrameCommand \let\MidFrameCommand \sphinxVerbatim@MidFrameCommand \let\LastFrameCommand \sphinxVerbatim@LastFrameCommand % \ifspx@opt@verbatimhintsturnover\else \let\sphinxVerbatim@Continued\@empty \let\sphinxVerbatim@Continues\@empty \fi % initialization for \spx@boxes@fcolorbox from sphinxpackageboxes.sty % it will take into account status of verbatimwithframe Boolean \spx@verb@boxes@fcolorbox@setup \ifspx@opt@verbatimwrapslines % deep hack into fancyvrb's internal processing of input lines \let\FV@@PreProcessLine\spx@verb@@PreProcessLine % space character will allow line breaks \let\FV@Space\spx@verbatim@space % allow breaks at special characters using \PYG... macros. \sphinxbreaksatspecials % breaks at punctuation characters . , ; ? ! and / (needs catcode activation) \fvset{codes*=\sphinxbreaksviaactive}% \fi \let\FancyVerbFormatLine\sphinxFancyVerbFormatLine \VerbatimEnvironment % workaround to fancyvrb's check of current list depth \def\@toodeep {\advance\@listdepth\@ne}% % The list environment is needed to control perfectly the vertical space. % Note: \OuterFrameSep used by framed.sty is later set to \topsep hence 0pt. % - if caption: distance from last text baseline to caption baseline is % A+(B-F)+\ht\strutbox, A = \abovecaptionskip (default 10pt), B = % \baselineskip, F is the framed.sty \FrameHeightAdjust macro, default 6pt. % Formula valid for F < 10pt. % - distance of baseline of caption to top of frame is like for tables: % \sphinxbelowcaptionspace (=0.5\baselineskip) % - if no caption: distance of last text baseline to code frame is S+(B-F), % with S = \sphinxverbatimtopskip (=\smallskip) % - and distance from bottom of frame to next text baseline is % \baselineskip+\parskip. % The \trivlist is used to avoid possible "too deeply nested" error. \itemsep \z@skip \topsep \z@skip \partopsep \z@skip % trivlist will set \parsep to \parskip (which itself is set to zero above) % \leftmargin will be set to zero by trivlist \rightmargin\z@ \parindent \z@% becomes \itemindent. Default zero, but perhaps overwritten. \trivlist\item\relax \ifspx@inframed\setbox\sphinxVerbatim@ContentsBox\vbox\bgroup \@setminipage\hsize\linewidth % use bulk of minipage paragraph shape restores (this is needed % in indented contexts, at least for some) \textwidth\hsize \columnwidth\hsize \@totalleftmargin\z@ \leftskip\z@skip \rightskip\z@skip \@rightskip\z@skip \else \ifsphinxverbatimwithminipage\noindent\begin{minipage}{\linewidth}\fi \MakeFramed {% adapted over from framed.sty's snugshade environment \advance\hsize-\width\@totalleftmargin\z@\linewidth\hsize\@setminipage }% \fi % For grid placement from \strut's in \FancyVerbFormatLine \lineskip\z@skip % active comma should not be overwritten by \@noligs \ifspx@opt@verbatimwrapslines \let\verbatim@nolig@list \sphinx@verbatim@nolig@list \fi % optimization: as codelines will be handled inside boxes, \everypar is % never reset, and it issues \@minipagefalse repeatedly (from \@setminipage). % As fancyvrb Verbatim will do \@minipagefalse itself, let's simplify things. \everypar{}% \color@begingroup % protect against color leaks (upstream framed.sty bug) \ifspx@pre@withtextcolor\color{VerbatimTextColor}\fi % mostly shadowed by % Pygments highlighting anyhow \spx@pre@TeXextras % will fetch its optional arguments if any \OriginalVerbatim }% {% \endOriginalVerbatim \color@endgroup % matches the \color@begingroup \ifspx@inframed \egroup % finish \sphinxVerbatim@ContentsBox vbox \nobreak % update page totals %%%% % MEMO (2022/07/09, while preparing 5.1.0 LaTeX CSS-style sphinxsetup options) % This test will systematically cause to abandon framing if the code-block % is near bottom of a warning-type notice which TeX has not yet decided whether % it fits on current page and which is near bottom of page. Indeed the % \pagetotal will already be very near \pagegoal. This is probably a not % intended behaviour, and perhaps the whole thing should be removed? Indeed % the result is surprising then because the notice will be split, code-block % will be on page 2 and will have no background-color, no border. \ifdim\dimexpr \ht\sphinxVerbatim@ContentsBox+ \dp\sphinxVerbatim@ContentsBox+ \ht\sphinxVerbatim@TitleBox+ \dp\sphinxVerbatim@TitleBox+ % 6.2.0 uses here the dimen registers from sphinxpackageboxes.sty, % they got setup by \spx@verb@boxes@fcolorbox@setup \spx@boxes@padding@top+ \spx@boxes@padding@bottom+ \ifspx@opt@verbatimwithframe \spx@boxes@border@top+ \spx@boxes@border@bottom+\fi % try to account for external frame parameters % MEMO: this is because the sphinxheavybox (for warning admonitions) % environment sets \FrameSep and \FrameRule % TODO: fix this bad implicit dependency \FrameSep+\FrameRule+ % Usage here of 2 baseline distances is empirical. % In border case where code-block fits barely in remaining space, % it gets framed and looks good but the outer frame may continue % on top of next page and give (if no contents after code-block) % an empty framed line, as testing showed. 2\baselineskip+ % now add all to accumulated page totals and compare to \pagegoal \pagetotal+\pagedepth>\pagegoal % long contents: do not \MakeFramed. Do make a caption (either before or % after) if title exists. Continuation hints across pagebreaks dropped. % FIXME? a bottom caption may end up isolated at top of next page % (no problem with a top caption, which is default) \spx@opt@verbatimwithframefalse \def\sphinxVerbatim@Title{\noindent\box\sphinxVerbatim@TitleBox\par}% \sphinxVerbatim@Before \noindent\unvbox\sphinxVerbatim@ContentsBox\par \sphinxVerbatim@After \else % short enough contents: use \MakeFramed. As it is nested, this requires % minipage encapsulation. \noindent\begin{minipage}{\linewidth}% \MakeFramed {% Use it now with the fetched contents \advance\hsize-\width\@totalleftmargin\z@\linewidth\hsize\@setminipage }% \unvbox\sphinxVerbatim@ContentsBox % the \@minipagefalse is superfluous, actually. \par\unskip\@minipagefalse\endMakeFramed \end{minipage}% \fi \else % non-nested \MakeFramed \par\unskip\@minipagefalse\endMakeFramed % from framed.sty snugshade \ifsphinxverbatimwithminipage\end{minipage}\fi \fi \endtrivlist } \newenvironment {sphinxVerbatimNoFrame} {\spx@opt@verbatimwithframefalse \VerbatimEnvironment \begin{sphinxVerbatim}} {\end{sphinxVerbatim}} \newenvironment {sphinxVerbatimintable} {% don't use a frame if in a table cell \spx@opt@verbatimwithframefalse \sphinxverbatimwithminipagetrue % the literal block caption uses \sphinxcaption which is wrapper of \caption, % but \caption must be modified because longtable redefines it to work only % for the own table caption, and tabulary has multiple passes \let\caption\sphinxfigcaption % reduce above caption skip \def\spx@abovecaptionskip{\sphinxverbatimsmallskipamount}% \VerbatimEnvironment \begin{sphinxVerbatim}} {\end{sphinxVerbatim}} %% PARSED LITERALS % allow long lines to wrap like they do in code-blocks % this should be kept in sync with definitions in sphinx.util.texescape \newcommand*\sphinxbreaksattexescapedchars{% \def\do##1##2% put potential break point before character {\def##1{\discretionary{}{\sphinxafterbreak\char`##2}{\char`##2}}}% \do\{\{\do\textless\<\do\#\#\do\%\%\do\$\$% {, <, #, %, $ \def\do##1##2% put potential break point after character {\def##1{\discretionary{\char`##2}{\sphinxafterbreak}{\char`##2}}}% \do\_\_\do\}\}\do\textasciicircum\^\do\&\&% _, }, ^, &, \do\textgreater\>\do\textasciitilde\~% >, ~ \do\textbackslash\\% \ } \newcommand*\sphinxbreaksviaactiveinparsedliteral{% \sphinxbreaksviaactive % by default handles . , ; ? ! / \lccode`\~`\~ % % update \dospecials as it is used by \url % but deactivation will already have been done hence this is unneeded: % \expandafter\def\expandafter\dospecials\expandafter{\dospecials % \sphinxbreaksbeforeactivelist\sphinxbreaksafteractivelist\do\-}% } \newcommand*\sphinxbreaksatspaceinparsedliteral{% \lccode`~32 \lowercase{\let~}\spx@verbatim@space\lccode`\~`\~ } \newcommand*{\sphinxunactivateextras}{\let\do\@makeother \sphinxbreaksbeforeactivelist\sphinxbreaksafteractivelist}% % the \catcode13=5\relax (deactivate end of input lines) is left to callers \newcommand*{\sphinxunactivateextrasandspace}{\catcode32=10\relax \sphinxunactivateextras}% % alltt uses a monospace font and linebreaks at dashes (which are escaped % to \sphinxhyphen{} which expands to -\kern\z@) are inhibited with pdflatex. % Not with xelatex (cf \defaultfontfeatures in latex writer), so: \newcommand*{\sphinxhypheninparsedliteral}{\sphinxhyphennobreak} % now for the modified alltt environment \newenvironment{sphinxalltt} {% at start of next line to workaround Emacs/AUCTeX issue with this file \begin{alltt}% \ifspx@opt@parsedliteralwraps \sbox\sphinxcontinuationbox {\spx@opt@verbatimcontinued}% \sbox\sphinxvisiblespacebox {\spx@opt@verbatimvisiblespace}% \let\sphinxhyphen\sphinxhypheninparsedliteral \sphinxbreaksattexescapedchars \sphinxbreaksviaactiveinparsedliteral \sphinxbreaksatspaceinparsedliteral % alltt takes care of the ' as derivative ("prime") in math mode \everymath\expandafter{\the\everymath\sphinxunactivateextrasandspace \catcode`\<=12\catcode`\>=12\catcode`\^=7\catcode`\_=8 }% % not sure if displayed math (align,...) can end up in parsed-literal, anyway \everydisplay\expandafter{\the\everydisplay \catcode13=5 \sphinxunactivateextrasandspace \catcode`\<=12\catcode`\>=12\catcode`\^=7\catcode`\_=8 }% \fi } {\end{alltt}} %% INLINE MARK-UP % % Protect \href's first argument in contexts such as sphinxalltt (or % \sphinxcode). Sphinx uses \#, \%, \& ... always inside \sphinxhref. \protected\def\sphinxhref#1#2{{% \sphinxunactivateextrasandspace % never do \scantokens with active space! % for the \endlinechar business, https://github.com/latex3/latex2e/issues/286 \endlinechar\m@ne\everyeof{{\endlinechar13 #2}}% keep catcode regime for #2 \scantokens{\href{#1}}% normalise it for #1 during \href expansion }} % Same for \url. And also \nolinkurl for coherence. \protected\def\sphinxurl#1{{% \sphinxunactivateextrasandspace\everyeof{}% (<- precaution for \scantokens) \endlinechar\m@ne\scantokens{\url{#1}}% }} \protected\def\sphinxnolinkurl#1{{% \sphinxunactivateextrasandspace\everyeof{}% \endlinechar\m@ne\scantokens{\nolinkurl{#1}}% }} % \sphinxupquote % to obtain straight quotes we execute \@noligs as patched by upquote, and % \scantokens is needed in cases where it would be too late for the macro to % first set catcodes and then fetch its argument. We also make the contents % breakable at non-escaped . , ; ? ! / using \sphinxbreaksviaactive, % and also at \ character (which is escaped to \textbackslash{}). \protected\def\sphinxtextbackslashbreakbefore {\discretionary{}{\sphinxafterbreak\sphinx@textbackslash}{\sphinx@textbackslash}} \protected\def\sphinxtextbackslashbreakafter {\discretionary{\sphinx@textbackslash}{\sphinxafterbreak}{\sphinx@textbackslash}} \let\sphinxtextbackslash\sphinxtextbackslashbreakafter % - is escaped to \sphinxhyphen{} and this default ensures no linebreak % behaviour (also with a non monospace font, or with xelatex) \newcommand*{\sphinxhyphenininlineliteral}{\sphinxhyphennobreak} % the macro must be protected if it ends up used in moving arguments, % in 'alltt' \@noligs is done already, and the \scantokens must be avoided. \protected\def\sphinxupquote#1{{\def\@tempa{alltt}% \ifx\@tempa\@currenvir\else \let\sphinxhyphen\sphinxhyphenininlineliteral \ifspx@opt@inlineliteralwraps % break at . , ; ? ! / \sphinxbreaksviaactive % break also at \ \setbox8=\hbox{\textbackslash}% \def\sphinx@textbackslash{\copy8}% \let\textbackslash\sphinxtextbackslash % by default, no continuation symbol on next line but may be added \let\sphinxafterbreak\sphinxafterbreakofinlineliteral % do not overwrite the comma set-up \let\verbatim@nolig@list\sphinx@literal@nolig@list \fi % fix a space-gobbling issue due to LaTeX's original \do@noligs % TODO: using \@noligs as patched by upquote.sty is now unneeded because % either ` and ' are escaped (non-unicode engines) or they don't build % ligatures (unicode engines). Thus remove this and unify handling of `, <, >, % ' and - with the characters . , ; ? ! / as handled via % \sphinxbreaksviaactive. % Hence \sphinx@do@noligs will be removed, or rather replaced with code % inserting discretionaries, as they allow a continuation symbol on start of % next line to achieve common design with code-blocks. % TODO: do the above TODO! % Extend \sphinxunactivateextras for \sphinxhref as the latter may % actually be in the scope of \sphinxupquote and does a \scantokens % of its own. \expandafter\def\expandafter\sphinxunactivateextras\expandafter {\sphinxunactivateextras\verbatim@nolig@list}% \let\do@noligs\sphinx@do@noligs \@noligs\endlinechar\m@ne\everyeof{}% (<- in case inside \sphinxhref) \expandafter\scantokens \fi {{#1}}}}% extra brace pair to fix end-space gobbling issue... \def\sphinx@do@noligs #1{\catcode`#1\active\begingroup\lccode`\~`#1\relax \lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1 }}} \def\sphinx@literal@nolig@list {\do\`\do\<\do\>\do\'\do\-}% \let\sphinxafterbreakofinlineliteral\empty \endinput krb5-1.22.1/doc/pdf/LICRlatin2utf8.xdy0000664000175000017500000002371414577122106017074 0ustar ghudsonghudson;; style file for xindy ;; filename: LICRlatin2utf8.xdy ;; description: style file for xindy which maps back LaTeX Internal ;; Character Representation of letters (as arising in .idx index ;; file) to UTF-8 encoding for correct sorting by xindy. ;; usage: for use with the pdflatex engine, ;; *not* for use with xelatex or lualatex. ;; ;; This is based upon xindy's distributed file tex/inputenc/utf8.xdy. ;; The modifications include: ;; ;; - Updates for compatibility with current LaTeX macro encoding. ;; ;; - Systematic usage of the \IeC {...} mark-up, because mark-up in ;; tex/inputenc/utf8.xdy was using it on seemingly random basis, and ;; Sphinx coercing of xindy usability for both Latin and Cyrillic scripts ;; with pdflatex requires its systematic presence here. ;; ;; - Support for some extra letters: Ÿ, ÅŠ, Å‹, Å’, Å“, IJ, ij, È· and ẞ. ;; ;; Indeed Sphinx needs to support for pdflatex engine all Unicode letters ;; available in TeX T1 font encoding. The above letters are found in ;; that encoding but not in the Latin1, 2, 3 charsets which are those ;; covered by original tex/inputenc/utf8.xdy. ;; ;; - There is a problem that È· is not supported out-of-the box by LaTeX ;; with inputenc, one must add explicitly ;; \DeclareUnicodeCharacter{0237}{\j} ;; to preamble of LaTeX document. However this character is not supported ;; by the TeX "times" font used by default by Sphinx for pdflatex engine. ;; ;; **Update**: since LaTeX 2018/12/01, the \j as well as \SS, \k{} and ;; \.{} need no extra user declaration anymore. ;; ;; - ẞ needs \DeclareUnicodeCharacter{1E9E}{\SS} (but ß needs no extra set-up). ;; ;; - U+02DB (Ë›) and U+02D9 (Ë™) are also not supported by inputenc ;; out of the box and require ;; \DeclareUnicodeCharacter{02DB}{\k{}} ;; \DeclareUnicodeCharacter{02D9}{\.{}} ;; to be added to preamble. ;; ;; - U+0127 ħ and U+0126 Ħ are absent from TeX T1+TS1 font encodings. ;; ;; - Characters ÅŠ and Å‹ are not supported by TeX font "times" used by ;; default by Sphinx for pdflatex engine but they are supported by ;; some TeX fonts, in particular by the default LaTeX font for T1 ;; encoding. ;; ;; - " and ~ must be escaped as ~" and resp. ~~ in xindy merge rules. ;; ;; Contributed by the Sphinx team, July 2018. ;; ;; See sphinx.xdy for superior figures, as they are escaped by LaTeX writer. (merge-rule "\IeC {\textonesuperior }" "¹" :string) (merge-rule "\IeC {\texttwosuperior }" "²" :string) (merge-rule "\IeC {\textthreesuperior }" "³" :string) (merge-rule "\IeC {\'a}" "á" :string) (merge-rule "\IeC {\'A}" "Ã" :string) (merge-rule "\IeC {\`a}" "à" :string) (merge-rule "\IeC {\`A}" "À" :string) (merge-rule "\IeC {\^a}" "â" :string) (merge-rule "\IeC {\^A}" "Â" :string) (merge-rule "\IeC {\~"a}" "ä" :string) (merge-rule "\IeC {\~"A}" "Ä" :string) (merge-rule "\IeC {\~~a}" "ã" :string) (merge-rule "\IeC {\~~A}" "Ã" :string) (merge-rule "\IeC {\c c}" "ç" :string) (merge-rule "\IeC {\c C}" "Ç" :string) (merge-rule "\IeC {\'c}" "ć" :string) (merge-rule "\IeC {\'C}" "Ć" :string) (merge-rule "\IeC {\^c}" "ĉ" :string) (merge-rule "\IeC {\^C}" "Ĉ" :string) (merge-rule "\IeC {\.c}" "Ä‹" :string) (merge-rule "\IeC {\.C}" "ÄŠ" :string) (merge-rule "\IeC {\c s}" "ÅŸ" :string) (merge-rule "\IeC {\c S}" "Åž" :string) (merge-rule "\IeC {\c t}" "Å£" :string) (merge-rule "\IeC {\c T}" "Å¢" :string) (merge-rule "\IeC {\-}" "­" :string); soft hyphen (merge-rule "\IeC {\textdiv }" "÷" :string) (merge-rule "\IeC {\'e}" "é" :string) (merge-rule "\IeC {\'E}" "É" :string) (merge-rule "\IeC {\`e}" "è" :string) (merge-rule "\IeC {\`E}" "È" :string) (merge-rule "\IeC {\^e}" "ê" :string) (merge-rule "\IeC {\^E}" "Ê" :string) (merge-rule "\IeC {\~"e}" "ë" :string) (merge-rule "\IeC {\~"E}" "Ë" :string) (merge-rule "\IeC {\^g}" "Ä" :string) (merge-rule "\IeC {\^G}" "Äœ" :string) (merge-rule "\IeC {\.g}" "Ä¡" :string) (merge-rule "\IeC {\.G}" "Ä " :string) (merge-rule "\IeC {\^h}" "Ä¥" :string) (merge-rule "\IeC {\^H}" "Ĥ" :string) (merge-rule "\IeC {\H o}" "Å‘" :string) (merge-rule "\IeC {\H O}" "Å" :string) (merge-rule "\IeC {\textacutedbl }" "Ë" :string) (merge-rule "\IeC {\H u}" "ű" :string) (merge-rule "\IeC {\H U}" "Ű" :string) (merge-rule "\IeC {\ae }" "æ" :string) (merge-rule "\IeC {\AE }" "Æ" :string) (merge-rule "\IeC {\textcopyright }" "©" :string) (merge-rule "\IeC {\c \ }" "¸" :string) (merge-rule "\IeC {\dh }" "ð" :string) (merge-rule "\IeC {\DH }" "Ã" :string) (merge-rule "\IeC {\dj }" "Ä‘" :string) (merge-rule "\IeC {\DJ }" "Ä" :string) (merge-rule "\IeC {\guillemotleft }" "«" :string) (merge-rule "\IeC {\guillemotright }" "»" :string) (merge-rule "\IeC {\'\i }" "í" :string) (merge-rule "\IeC {\`\i }" "ì" :string) (merge-rule "\IeC {\^\i }" "î" :string) (merge-rule "\IeC {\~"\i }" "ï" :string) (merge-rule "\IeC {\i }" "ı" :string) (merge-rule "\IeC {\^\j }" "ĵ" :string) (merge-rule "\IeC {\k {}}" "Ë›" :string) (merge-rule "\IeC {\l }" "Å‚" :string) (merge-rule "\IeC {\L }" "Å" :string) (merge-rule "\IeC {\nobreakspace }" " " :string) (merge-rule "\IeC {\o }" "ø" :string) (merge-rule "\IeC {\O }" "Ø" :string) (merge-rule "\IeC {\textsterling }" "£" :string) (merge-rule "\IeC {\textparagraph }" "¶" :string) (merge-rule "\IeC {\ss }" "ß" :string) (merge-rule "\IeC {\textsection }" "§" :string) (merge-rule "\IeC {\textbrokenbar }" "¦" :string) (merge-rule "\IeC {\textcent }" "¢" :string) (merge-rule "\IeC {\textcurrency }" "¤" :string) (merge-rule "\IeC {\textdegree }" "°" :string) (merge-rule "\IeC {\textexclamdown }" "¡" :string) (merge-rule "\IeC {\texthbar }" "ħ" :string) (merge-rule "\IeC {\textHbar }" "Ħ" :string) (merge-rule "\IeC {\textonehalf }" "½" :string) (merge-rule "\IeC {\textonequarter }" "¼" :string) (merge-rule "\IeC {\textordfeminine }" "ª" :string) (merge-rule "\IeC {\textordmasculine }" "º" :string) (merge-rule "\IeC {\textperiodcentered }" "·" :string) (merge-rule "\IeC {\textquestiondown }" "¿" :string) (merge-rule "\IeC {\textregistered }" "®" :string) (merge-rule "\IeC {\textthreequarters }" "¾" :string) (merge-rule "\IeC {\textyen }" "Â¥" :string) (merge-rule "\IeC {\th }" "þ" :string) (merge-rule "\IeC {\TH }" "Þ" :string) (merge-rule "\IeC {\'I}" "Ã" :string) (merge-rule "\IeC {\`I}" "ÃŒ" :string) (merge-rule "\IeC {\^I}" "ÃŽ" :string) (merge-rule "\IeC {\~"I}" "Ã" :string) (merge-rule "\IeC {\.I}" "İ" :string) (merge-rule "\IeC {\^J}" "Ä´" :string) (merge-rule "\IeC {\k a}" "Ä…" :string) (merge-rule "\IeC {\k A}" "Ä„" :string) (merge-rule "\IeC {\k e}" "Ä™" :string) (merge-rule "\IeC {\k E}" "Ę" :string) (merge-rule "\IeC {\'l}" "ĺ" :string) (merge-rule "\IeC {\'L}" "Ĺ" :string) (merge-rule "\IeC {\textlnot }" "¬" :string) (merge-rule "\IeC {\textmu }" "µ" :string) (merge-rule "\IeC {\'n}" "Å„" :string) (merge-rule "\IeC {\'N}" "Ń" :string) (merge-rule "\IeC {\~~n}" "ñ" :string) (merge-rule "\IeC {\~~N}" "Ñ" :string) (merge-rule "\IeC {\'o}" "ó" :string) (merge-rule "\IeC {\'O}" "Ó" :string) (merge-rule "\IeC {\`o}" "ò" :string) (merge-rule "\IeC {\`O}" "Ã’" :string) (merge-rule "\IeC {\^o}" "ô" :string) (merge-rule "\IeC {\^O}" "Ô" :string) (merge-rule "\IeC {\~"o}" "ö" :string) (merge-rule "\IeC {\~"O}" "Ö" :string) (merge-rule "\IeC {\~~o}" "õ" :string) (merge-rule "\IeC {\~~O}" "Õ" :string) (merge-rule "\IeC {\textpm }" "±" :string) (merge-rule "\IeC {\r a}" "Ã¥" :string) (merge-rule "\IeC {\r A}" "Ã…" :string) (merge-rule "\IeC {\'r}" "Å•" :string) (merge-rule "\IeC {\'R}" "Å”" :string) (merge-rule "\IeC {\r u}" "ů" :string) (merge-rule "\IeC {\r U}" "Å®" :string) (merge-rule "\IeC {\'s}" "Å›" :string) (merge-rule "\IeC {\'S}" "Åš" :string) (merge-rule "\IeC {\^s}" "Å" :string) (merge-rule "\IeC {\^S}" "Åœ" :string) (merge-rule "\IeC {\textasciidieresis }" "¨" :string) (merge-rule "\IeC {\textasciimacron }" "¯" :string) (merge-rule "\IeC {\.{}}" "Ë™" :string) (merge-rule "\IeC {\textasciiacute }" "´" :string) (merge-rule "\IeC {\texttimes }" "×" :string) (merge-rule "\IeC {\u a}" "ă" :string) (merge-rule "\IeC {\u A}" "Ä‚" :string) (merge-rule "\IeC {\u g}" "ÄŸ" :string) (merge-rule "\IeC {\u G}" "Äž" :string) (merge-rule "\IeC {\textasciibreve }" "˘" :string) (merge-rule "\IeC {\'u}" "ú" :string) (merge-rule "\IeC {\'U}" "Ú" :string) (merge-rule "\IeC {\`u}" "ù" :string) (merge-rule "\IeC {\`U}" "Ù" :string) (merge-rule "\IeC {\^u}" "û" :string) (merge-rule "\IeC {\^U}" "Û" :string) (merge-rule "\IeC {\~"u}" "ü" :string) (merge-rule "\IeC {\~"U}" "Ü" :string) (merge-rule "\IeC {\u u}" "Å­" :string) (merge-rule "\IeC {\u U}" "Ŭ" :string) (merge-rule "\IeC {\v c}" "Ä" :string) (merge-rule "\IeC {\v C}" "ÄŒ" :string) (merge-rule "\IeC {\v d}" "Ä" :string) (merge-rule "\IeC {\v D}" "ÄŽ" :string) (merge-rule "\IeC {\v e}" "Ä›" :string) (merge-rule "\IeC {\v E}" "Äš" :string) (merge-rule "\IeC {\v l}" "ľ" :string) (merge-rule "\IeC {\v L}" "Ľ" :string) (merge-rule "\IeC {\v n}" "ň" :string) (merge-rule "\IeC {\v N}" "Ň" :string) (merge-rule "\IeC {\v r}" "Å™" :string) (merge-rule "\IeC {\v R}" "Ř" :string) (merge-rule "\IeC {\v s}" "Å¡" :string) (merge-rule "\IeC {\v S}" "Å " :string) (merge-rule "\IeC {\textasciicaron }" "ˇ" :string) (merge-rule "\IeC {\v t}" "Å¥" :string) (merge-rule "\IeC {\v T}" "Ť" :string) (merge-rule "\IeC {\v z}" "ž" :string) (merge-rule "\IeC {\v Z}" "Ž" :string) (merge-rule "\IeC {\'y}" "ý" :string) (merge-rule "\IeC {\'Y}" "Ã" :string) (merge-rule "\IeC {\~"y}" "ÿ" :string) (merge-rule "\IeC {\'z}" "ź" :string) (merge-rule "\IeC {\'Z}" "Ź" :string) (merge-rule "\IeC {\.z}" "ż" :string) (merge-rule "\IeC {\.Z}" "Å»" :string) ;; letters not in Latin1, 2, 3 but available in TeX T1 font encoding (merge-rule "\IeC {\~"Y}" "Ÿ" :string) (merge-rule "\IeC {\NG }" "ÅŠ" :string) (merge-rule "\IeC {\ng }" "Å‹" :string) (merge-rule "\IeC {\OE }" "Å’" :string) (merge-rule "\IeC {\oe }" "Å“" :string) (merge-rule "\IeC {\IJ }" "IJ" :string) (merge-rule "\IeC {\ij }" "ij" :string) (merge-rule "\IeC {\j }" "È·" :string) (merge-rule "\IeC {\SS }" "ẞ" :string) krb5-1.22.1/doc/pdf/sphinxlatexlists.sty0000664000175000017500000001202314577122106020052 0ustar ghudsonghudson%% ALPHANUMERIC LIST ITEMS % % change this info string if making any custom modification \ProvidesFile{sphinxlatexlists.sty}[2021/12/20 lists] % Provides support for this output mark-up from Sphinx latex writer: % - \sphinxsetlistlabels % - \sphinxlineitem % and for the maxlistdepth key of sphinxsetup % Dependencies: the \spx@opt@maxlistdepth from sphinx.sty % We need some helpers macros \newtoks\spx@lineitemlabel \long\def\sphinx@gobto@sphinxlineitem#1\sphinxlineitem{} % TeX/LaTeX has no (easy to use) built-in "peek-ahead" mechanism, but % we would like to know if next token is another \sphinxlineitem (this % can happen in glossary entries with multiple terms for same definition) % so we simply grab next token (assuming it is not {tokens} originally) \newcommand\sphinxlineitem[2]{% % safe test of whether #2 is \sphinxlineitem \sphinx@gobto@sphinxlineitem#2\@gobbletwo\sphinxlineitem\unless \iftrue % case with sphinxlineitem immediately followed by another \sphinxlineitem: % accumulate successive terms until actual definition or sub-list is found \spx@lineitemlabel\expandafter{\the\spx@lineitemlabel\strut#1\\}% \else % now issue the \item command with possibly multi-line contents % these weird incantations with \kern are related to how LaTeX % handles \item generally \item[\kern\labelwidth\kern-\itemindent\kern-\leftmargin {\parbox[t]{\dimexpr\linewidth+\leftmargin\relax}{% \raggedright \the\spx@lineitemlabel% accumulated terms before this one, CR separated \strut#1}}% due to LaTeX internals no \par token allowed here, % but the \parbox will insert one tacitly at end \kern-\labelsep]% \spx@lineitemlabel{}% % this causes the label to be typeset (filling up the line), clearing up % things in case a nested list follows. \leavevmode \fi #2% }% \newcommand\sphinxsetlistlabels[5] {% #1 = style, #2 = enum, #3 = enumnext, #4 = prefix, #5 = suffix % #2 and #3 are counters used by enumerate environment e.g. enumi, enumii. % #1 is a macro such as \arabic or \alph % prefix and suffix are strings (by default empty and a dot). \@namedef{the#2}{#1{#2}}% \@namedef{label#2}{#4\@nameuse{the#2}#5}% \@namedef{p@#3}{\@nameuse{p@#2}#4\@nameuse{the#2}#5}% }% %% MAXLISTDEPTH % % remove LaTeX's cap on nesting depth if 'maxlistdepth' key used. % This is a hack, which works with the standard classes: it assumes \@toodeep % is always used in "true" branches: "\if ... \@toodeep \else .. \fi." % will force use the "false" branch (if there is one) \def\spx@toodeep@hack{\fi\iffalse} % do nothing if 'maxlistdepth' key not used or if package enumitem loaded. \ifnum\spx@opt@maxlistdepth=\z@\expandafter\@gobbletwo\fi \AtBeginDocument{% \@ifpackageloaded{enumitem}{\remove@to@nnil}{}% \let\spx@toodeepORI\@toodeep \def\@toodeep{% \ifnum\@listdepth<\spx@opt@maxlistdepth\relax \expandafter\spx@toodeep@hack \else \expandafter\spx@toodeepORI \fi}% % define all missing \@list... macros \count@\@ne \loop \ltx@ifundefined{@list\romannumeral\the\count@} {\iffalse}{\iftrue\advance\count@\@ne}% \repeat \loop \ifnum\count@>\spx@opt@maxlistdepth\relax\else \expandafter\let \csname @list\romannumeral\the\count@\expandafter\endcsname \csname @list\romannumeral\the\numexpr\count@-\@ne\endcsname % workaround 2.6--3.2d babel-french issue (fixed in 3.2e; no change needed) \ltx@ifundefined{leftmargin\romannumeral\the\count@} {\expandafter\let \csname leftmargin\romannumeral\the\count@\expandafter\endcsname \csname leftmargin\romannumeral\the\numexpr\count@-\@ne\endcsname}{}% \advance\count@\@ne \repeat % define all missing enum... counters and \labelenum... macros and \p@enum.. \count@\@ne \loop \ltx@ifundefined{c@enum\romannumeral\the\count@} {\iffalse}{\iftrue\advance\count@\@ne}% \repeat \loop \ifnum\count@>\spx@opt@maxlistdepth\relax\else \newcounter{enum\romannumeral\the\count@}% \expandafter\def \csname labelenum\romannumeral\the\count@\expandafter\endcsname \expandafter {\csname theenum\romannumeral\the\numexpr\count@\endcsname.}% \expandafter\def \csname p@enum\romannumeral\the\count@\expandafter\endcsname \expandafter {\csname p@enum\romannumeral\the\numexpr\count@-\@ne\expandafter \endcsname\csname theenum\romannumeral\the\numexpr\count@-\@ne\endcsname.}% \advance\count@\@ne \repeat % define all missing labelitem... macros \count@\@ne \loop \ltx@ifundefined{labelitem\romannumeral\the\count@} {\iffalse}{\iftrue\advance\count@\@ne}% \repeat \loop \ifnum\count@>\spx@opt@maxlistdepth\relax\else \expandafter\let \csname labelitem\romannumeral\the\count@\expandafter\endcsname \csname labelitem\romannumeral\the\numexpr\count@-\@ne\endcsname \advance\count@\@ne \repeat \PackageInfo{sphinx}{maximal list depth extended to \spx@opt@maxlistdepth}% \@gobble\@nnil } \endinput krb5-1.22.1/doc/pdf/python.ist0000664000175000017500000000061014577122106015724 0ustar ghudsonghudsonline_max 100 headings_flag 1 heading_prefix " \\bigletter " preamble "\\begin{sphinxtheindex} \\let\\bigletter\\sphinxstyleindexlettergroup \\let\\spxpagem \\sphinxstyleindexpagemain \\let\\spxentry \\sphinxstyleindexentry \\let\\spxextra \\sphinxstyleindexextra " postamble "\n\n\\end{sphinxtheindex}\n" symhead_positive "{\\sphinxsymbolsname}" numhead_positive "{\\sphinxnumbersname}" krb5-1.22.1/doc/pdf/sphinxpackageboxes.sty0000664000175000017500000010740714577122106020325 0ustar ghudsonghudson%% COLOURED BOXES % % change this info string if making any custom modification \ProvidesPackage{sphinxpackageboxes}[2023/03/19 v6.2.0 advanced colored boxes] % Optionally executes \RequirePackage for: % % - pict2e. Ideally we would like to use the v0.4a 2020/08/16 release of this % package as it allows dimensional arguments to its \moveto, \lineto, etc... % Or we could use extra package "picture". We opt for custom wrappers % \spx@moveto, \spx@lineto, ..., working with old versions. % % - ellipse. This package extends pict2e with elliptical arcs. Its author % Daan Leijen also has contributed package longfbox which is part of % TeXLive. Had I known about it, I would perhaps have based Sphinx CSS on % top of longfbox at least partly. But this would not have spared me all % the work in sphinx.sty, which was a long walk until 6.2.0 version. % Besides I don't need the breakable boxes from longfbox, as Sphinx has % its own rather advanced layer on top of framed. I would need to check if % some thorny color issues solved by Sphinx (and not by tcolorbox) at page % breaks are solved by longfbox as well. (I have not tested) % At 6.2.0 refactoring, we do not wait for at begin document to try to load % pict2e. Actually since 6.0.0 the default is for code-blocks to use % rounded boxes, and the only reason since then to wait "at begin document" % was to check if user had reverted that default and in fact pict2e was not % needed. But with \sphinxbox, we can not know for sure even in that case % that pict2e is not needed. And even back then it would have been possible % to user to try to employ \sphinxsetup via raw directive in document body % and require some rounded corners (which was thus impossible to satisfy). % Time to be much simpler and attempt unconditionally to load pict2e % immediately. This will also have advantage that we can use % \@ifpackageloaded{pict2e} and not have to query and save its setting later % at begin document. \IfFileExists{pict2e.sty} {\RequirePackage{pict2e}} {\PackageWarningNoLine{sphinx}{% The package pict2e is required for rounded boxes.\MessageBreak It does not seem to be available on your system.\MessageBreak Options for setting radii will be ignored% }% % Formerly a \sphinxbuildwarning was issued but if we did that now it % would mean that the produced PDF will always have a red banner near its % end about pict2e not being available if indeed it is not available, even % if user has reverted the default and dropped rounded corners. Formerly % the serious warning was done after having checked at begin document that % indeed a rounded corner option had been used. As we drop the check now, % let's be more discrete and simply duplicate the earlier warning to make % it visible near end of compilation log and console output. \AtEndDocument{\PackageWarningNoLine{sphinx}{% The package pict2e is required for rounded boxes.\MessageBreak As it does not seem to be available on your system,\MessageBreak options setting radii have all been ignored}}% }% \IfFileExists{ellipse.sty} {\RequirePackage{ellipse}} {\PackageWarningNoLine{sphinx}{% The package ellipse is required for elliptical corners.\MessageBreak It does not seem to be available on your system.\MessageBreak All non-straight corners will use circle arcs.% }% \AtEndDocument{\PackageWarningNoLine{sphinx}{% The package ellipse is required for elliptical corners.\MessageBreak As it does not seem to be available on your system,\MessageBreak all non-straight corners have used circle arcs.}}% }% % The pict2e release v0.4b of 2020/09/30 does not allocate scratch dimen % register \@tempdimd which ellipse package uses. Thus ellipse package is % broken since (written on March 20, 2023). Simply allocate the register % ourself to fix that, pending some upstream fix. \@ifpackageloaded{ellipse}{\ifdefined\@tempdimd\else\newdimen\@tempdimd\fi}{} % Provides box registers \spx@tempboxa, \spx@tempboxb usable in other places \newbox\spx@tempboxa \newbox\spx@tempboxb %%%%%%%%%%%%%%%% % Internal registers, conditionals, colors to be configured by each caller % via a preliminary "setup" call % \newif\ifspx@boxes@withshadow \newif\ifspx@boxes@insetshadow \newif\ifspx@boxes@withbackgroundcolor \newif\ifspx@boxes@withshadowcolor \newif\ifspx@boxes@withbordercolor \newif\ifspx@boxes@shadowinbbox % \newdimen\spx@boxes@border \newdimen\spx@boxes@border@top \newdimen\spx@boxes@border@right \newdimen\spx@boxes@border@bottom \newdimen\spx@boxes@border@left % \newdimen\spx@boxes@padding@top \newdimen\spx@boxes@padding@right \newdimen\spx@boxes@padding@bottom \newdimen\spx@boxes@padding@left % \newdimen\spx@boxes@shadow@xoffset \newdimen\spx@boxes@shadow@yoffset % \newdimen\spx@boxes@radius@topleft@x \newdimen\spx@boxes@radius@topright@x \newdimen\spx@boxes@radius@bottomright@x \newdimen\spx@boxes@radius@bottomleft@x \newdimen\spx@boxes@radius@topleft@y \newdimen\spx@boxes@radius@topright@y \newdimen\spx@boxes@radius@bottomright@y \newdimen\spx@boxes@radius@bottomleft@y % % These colors will be set to colors defined appropriately by caller of % \spx@boxes@fcolorbox@setup macro % spx@boxes@bordercolor % spx@boxes@backgroundcolor % spx@boxes@shadowcolor % spx@boxes@textcolor %%%%%%%%%%%%%%%% % "setup" macro % % It must be called prior to \spx@boxes@fcolorbox for parameters of the latter % to be initialized. % % It also prepares \spx@boxes@fcolorbox to expand to one of % \spx@boxes@fcolorbox@rectangle or \spx@boxes@fcolorbox@rounded depending on % the configuration and availability of the pict2e package. % % The #1 is one of: pre, topic, warning, danger, etc.... % % We delay until here the parsing of radii options to extract x and y % components. \def\spx@boxes@setradii#1 #2 #3\@nnil#4#5{% #4\dimexpr#1\relax #5\dimexpr#2\relax \ifdim#5=-\maxdimen#5#4\fi % if one of them is zero or negative set both to zero \ifdim#4>\z@\else#4\z@#5\z@\fi \ifdim#5>\z@\else#4\z@#5\z@\fi }% % if ellipse.sty is not available ignore the second component of all radii % specifications, use circle arcs with radius the x component \@ifpackageloaded{ellipse} {} {\def\spx@boxes@setradii#1 #2 #3\@nnil#4#5{#4\dimexpr#1\relax #5#4}} % Using \dimexpr for maximal user input flexibility. \def\spx@boxes@fcolorbox@setup#1{% \spx@boxes@border@top \dimexpr\@nameuse{spx@#1@border@top}\relax \spx@boxes@border@right \dimexpr\@nameuse{spx@#1@border@right}\relax \spx@boxes@border@bottom\dimexpr\@nameuse{spx@#1@border@bottom}\relax \spx@boxes@border@left \dimexpr\@nameuse{spx@#1@border@left}\relax \spx@boxes@border \dimexpr\@nameuse{spx@#1@border}\relax % \spx@boxes@padding@top \dimexpr\@nameuse{spx@#1@padding@top}\relax \spx@boxes@padding@right \dimexpr\@nameuse{spx@#1@padding@right}\relax \spx@boxes@padding@bottom\dimexpr\@nameuse{spx@#1@padding@bottom}\relax \spx@boxes@padding@left \dimexpr\@nameuse{spx@#1@padding@left}\relax % \edef\spx@temp{\csname spx@#1@radius@topleft\endcsname\space}% \expandafter \spx@boxes@setradii \spx@temp {-\maxdimen} \@nnil \spx@boxes@radius@topleft@x\spx@boxes@radius@topleft@y \edef\spx@temp{\csname spx@#1@radius@topright\endcsname\space}% \expandafter \spx@boxes@setradii \spx@temp {-\maxdimen} \@nnil \spx@boxes@radius@topright@x\spx@boxes@radius@topright@y \edef\spx@temp{\csname spx@#1@radius@bottomright\endcsname\space}% \expandafter \spx@boxes@setradii \spx@temp {-\maxdimen} \@nnil \spx@boxes@radius@bottomright@x\spx@boxes@radius@bottomright@y \edef\spx@temp{\csname spx@#1@radius@bottomleft\endcsname\space}% \expandafter \spx@boxes@setradii \spx@temp {-\maxdimen} \@nnil \spx@boxes@radius@bottomleft@x\spx@boxes@radius@bottomleft@y % \@nameuse{ifspx@#1@withshadow}% \spx@boxes@withshadowtrue \spx@boxes@shadow@xoffset \dimexpr\@nameuse{spx@#1@shadow@xoffset}\relax \spx@boxes@shadow@yoffset \dimexpr\@nameuse{spx@#1@shadow@yoffset}\relax \else \spx@boxes@withshadowfalse \fi % not nesting in previous to avoid TeX conditional subtleties \@nameuse{ifspx@#1@insetshadow}% \spx@boxes@insetshadowtrue \else \spx@boxes@insetshadowfalse \fi % \@nameuse{ifspx@#1@withbordercolor}% \spx@boxes@withbordercolortrue \sphinxcolorlet{spx@boxes@bordercolor}{sphinx#1BorderColor}% \else \spx@boxes@withbordercolorfalse \fi % \@nameuse{ifspx@#1@withbackgroundcolor}% \spx@boxes@withbackgroundcolortrue \sphinxcolorlet{spx@boxes@backgroundcolor}{sphinx#1BgColor}% \else \spx@boxes@withbackgroundcolorfalse \fi % \@nameuse{ifspx@#1@withshadowcolor}% \spx@boxes@withshadowcolortrue \sphinxcolorlet{spx@boxes@shadowcolor}{sphinx#1ShadowColor}% \else \spx@boxes@withshadowcolorfalse \fi % Display elements pre, topic, warning et al. by default do not include % shadow in box (legacy; and only topic actually uses a shadow per default) % This may be refactored still more in future, but this 6.2.0 extra helped % reduce workload from code-blocks (pre), contents (topic) and admonitions. % As this conditional is a priori false and should only be changed locally % (by \sphinxbox), this line is actually superfluous. \spx@boxes@shadowinbboxfalse \spx@boxes@fcolorbox@setup@fcolorbox } \@ifpackageloaded{pict2e} {% pict2e is available and loaded \def\spx@boxes@fcolorbox@setup@fcolorbox{% \if1% use rounded boxes only if needed (rx>0 iff ry>0) \ifdim\spx@boxes@radius@topleft@x >\z@0\fi \ifdim\spx@boxes@radius@topright@x >\z@0\fi \ifdim\spx@boxes@radius@bottomright@x>\z@0\fi \ifdim\spx@boxes@radius@bottomleft@x >\z@0\fi 1\def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rectangle}% \else \def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rounded}% \fi }% end of definition of setup@fcolorbox in case of presence of pict2e }% {% pict2e could not be loaded, we must always use fcolorbox@rectangle \def\spx@boxes@fcolorbox@setup@fcolorbox{% \def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rectangle}% }% end of definition of setup@fcolorbox in case of absence of pict2e }% end of "no pict2e" branch %%%%%%%%%%%%%%%% % Support of box-decoration-break=slice % % 6.2.0 has renamed and moved this here from sphinxlatexliterals.sty, % to facilitate supporting box-decoration-break=slice for all directives, % not only code-block. % % It also modified when these post actions are executed, in order % for openboth to be able to trigger usage of fcolorbox@rectangle. % So now openbottom and opentop also take advantage of this possible % optimization. \def\spx@boxes@fcolorbox@setup@openbottom{% \spx@boxes@border@bottom \z@ \spx@boxes@radius@bottomright@x\z@ \spx@boxes@radius@bottomright@y\z@ \spx@boxes@radius@bottomleft@x \z@ \spx@boxes@radius@bottomleft@y \z@ \spx@boxes@fcolorbox@setup@fcolorbox }% \def\spx@boxes@fcolorbox@setup@opentop{% \spx@boxes@border@top \z@ \spx@boxes@radius@topright@x\z@ \spx@boxes@radius@topright@y\z@ \spx@boxes@radius@topleft@x \z@ \spx@boxes@radius@topleft@y \z@ \spx@boxes@fcolorbox@setup@fcolorbox }% \def\spx@boxes@fcolorbox@setup@openboth{% \spx@boxes@border@top \z@ \spx@boxes@border@bottom \z@ \spx@boxes@radius@bottomright@x\z@ \spx@boxes@radius@bottomright@y\z@ \spx@boxes@radius@bottomleft@x \z@ \spx@boxes@radius@bottomleft@y \z@ \spx@boxes@radius@topright@x\z@ \spx@boxes@radius@topright@y\z@ \spx@boxes@radius@topleft@x \z@ \spx@boxes@radius@topleft@y \z@ \def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rectangle}% }% %%%%%%%%%%%%%%%% % \sphinxbox (added at 6.2.0) % % For an inline box, possibly rounded. \newcommand\sphinxbox[1][]{% #1 stands for the options, they are... optional! % \leavevmode makes sure TeX switches to paragraph mode, which is necessary % if this is first in a paragraph or a list element. The \sphinxAtStartPar % mechanism also ensures this automatically, if not redefined, but not with % lualatex as then it is by default doing nothing. \leavevmode \begingroup \ifcsname spx@boxes@sphinxbox@isnested\endcsname % nested boxes reset all box options to be as the \sphinxboxsetup % defaults, before applying their specific options \spx@boxes@sphinxbox@reset \else % top layer box, toggle the nested flag \csname spx@boxes@sphinxbox@isnested\endcsname \fi % we do not use \sphinxboxsetup as it is a user command extending the % "reset" storage \setkeys{sphinxbox}{#1}% \spx@boxes@fcolorbox@setup{box}% \spx@boxes@shadowinbboxtrue% inline sphinx boxes include shadow in bbox \ifspx@box@withtextcolor\color{sphinxboxTextColor}\fi % % MEMO: the fcolorbox@{rectangle,rounded} draw the contents (which here % will be encapsulated as \box\z@) last, i.e. after shadow, background, % and border and their color commands. The \reset@color from naked % top-level \color commands in argument (which can not arise from Sphinx % mark-up anyhow) would end up being placed via color.sty \aftergroup core % mechanism in token stream after \spx@boxes@sphinxbox@a (which is the % first \aftergroup) hence after the box contents with its unbalanced % color pushes is shipped to PDF. So the missing color pop specials are % inserted then in correct order at correct place (after the \endgroup at % end of \spx@boxes@sphinxbox@a but this is not relevant) and do not end % up causing havoc in push/pop pairs (and all this happens on same page). % % There is thus no reason here to go to the trouble to add an extra % \color@begingroup/\color@endgroup or like pair to encapsulate the caught % contents in order for the \box\z@ to contain as many color pop's as it % has color pushes. But as this is subtle, this comment was added for % future maintenance. Actually even if the contents were not drawn last, % their (purely theoretical, as Sphinx mark-up can not create it) missing % color pop's would not have caused trouble I guess as long as the color % insertions for shadow, background, border are correctly balanced. \setbox0\hbox\bgroup\aftergroup\spx@boxes@sphinxbox@a \afterassignment\spx@box@TeXextras \let\next=% } \def\spx@boxes@sphinxbox@a{\spx@boxes@fcolorbox{% \ifspx@opt@box@addstrut\strut\fi\box\z@}\endgroup} \newcommand\newsphinxbox[2][]{% \newcommand#2[1][]{\sphinxbox[#1,##1]}% } % Let's catch \renewsphinxbox[...]{\sphinxbox} which would cause \sphinxbox % to fall into infinite looping on use. \newcommand\renewsphinxbox[2][]{% \in@{#2}{\sphinxbox}% \ifin@ \PackageWarning{sphinx}{Attempt to \string\renewsphinxbox\space the \string\sphinxbox\space command\MessageBreak itself. This is not allowed and will be ignored.\MessageBreak Reported}% \else \renewcommand#2[1][]{\sphinxbox[#1,##1]}% \fi } %%%%%%%%%%%%%%%% % MACROS % % \spx@boxes@fcolorbox expands either to \spx@boxes@fcolorbox@rectangle % or \spx@boxes@fcolorbox@rounded depending on preliminary set-up. % % This is decided by the "setup" which must have been executed by the caller. % Let's give it some (thus unneeded) default fall-back for clarity. \def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rectangle} % % A macro \spx@boxes@fcolorbox@setuphook used to be executed at start of the % \hbox constructs (rectangle or rounded). This was used until 6.2.0 for the % support of pre_box-decoration-break option, hence was really an internal % non-public macro. As it is not needed anymore, with some hesitation it got % entirely removed at 6.2.0 on the occasion of a refactoring of interactions of % this file with sphinxlatexliterals.sty. Besides its name should have been % rather something such as \spx@boxes@fcolorbox@atstartofhbox. % % After "setup", \spx@boxes@fcolorbox expands to one of: % % - \spx@boxes@fcolorbox@rectangle (4 padding parameters, 4 border widths, 2 shadow widths, % and three colours: background, border and shadow; same as in CSS styling) % % It branches to one of: % - \spx@boxes@fcolorbox@externalshadow % - \spx@boxes@fcolorbox@insetshadow (same concept of "inset" as in CSS styling) % % - \spx@boxes@fcolorbox@rounded: rounded corners using the picture environment % and pict2e package for its low-weight interface to PDF graphics operations % MEMO: we have also successfully tested usage of tcolorbox.sty (its \tcbox) but % decided to use pict2e.sty for the following reasons: % 1- PDF build was observed to be an order of magnitude faster, % 2- the boxes we can do with pict2e appear to be fancy enough, % almost matching what one can see in HTML renderings, % 2- orders of magnitude smaller dependency (tcolorbox uses the pgf TeX % framework), although on Ubuntu it seems texlive-pictures is % needed which also contains the whole of pgf/TikZ... so this point % is a bit moot... % For code-blocks, attachments of caption and continuation hints are done % exactly as prior to extension of Sphinx via this package, whether the box % has straight or rounded corners. The vertical space occupied is the same, % if nothing else is changed (perhaps in future the title itself could be also % rendered in a rounded box?) %%%%%%%% %//// \spx@boxes@fcolorbox@rectangle % % This box will have the same baseline as its argument (which is typeset in % horizontal mode). It takes into account four border widths parameters, four % padding parameters, two shadow widths (each possibly negative), and three % colors: background, border and shadow. Its boundary box takes into account % border and padding. Width of shadow is taken into account if the boolean % \ifspx@boxes@shadowinbbox is \iftrue. The "setup" sets it to \iffalse. % Prior to 6.2.0, shadow size was included in bbox but the callers manually % removed it by extra steps. The \sphinxbox command sets it to \iftrue after % the "setup". % % It is up to the caller to take extra steps if the border and padding must go % into margin as well (see sphinxlatexliterals.sty for how this is done in % \spx@verb@FrameCommand). % % In usage as a "FrameCommand" with framed.sty, the argument will already be a % collection of TeX boxes (and interline glues). % % This was designed so that the parameters configured by "setup" are % interpreted as they would be as CSS properties in an HTML context. \long\def\spx@boxes@fcolorbox@rectangle#1{% \hbox\bgroup \setbox\spx@tempboxa \hbox{\kern\dimexpr\spx@boxes@border@left+\spx@boxes@padding@left\relax {#1}% \kern\dimexpr\spx@boxes@padding@right+\spx@boxes@border@right\relax}% \ht\spx@tempboxa \dimexpr\ht\spx@tempboxa+\spx@boxes@border@top+\spx@boxes@padding@top\relax \dp\spx@tempboxa \dimexpr\dp\spx@tempboxa+\spx@boxes@padding@bottom+\spx@boxes@border@bottom\relax \ifspx@boxes@insetshadow \expandafter\spx@boxes@fcolorbox@insetshadow \else \expandafter\spx@boxes@fcolorbox@externalshadow \fi } % external shadow \def\spx@boxes@fcolorbox@externalshadow{% % reserve space to external shadow if on left \ifspx@boxes@withshadow \ifspx@boxes@shadowinbbox \ifdim\spx@boxes@shadow@xoffset<\z@\kern-\spx@boxes@shadow@xoffset\fi \fi \fi % BACKGROUND % draw background and move back to reference point \ifspx@boxes@withbackgroundcolor {\color{spx@boxes@backgroundcolor}% \vrule\@height\ht\spx@tempboxa \@depth\dp\spx@tempboxa \@width\wd\spx@tempboxa \kern-\wd\spx@tempboxa }% \fi % BOX SHADOW % draw shadow and move back to reference point \ifspx@boxes@withshadow \vbox{% \moveright\spx@boxes@shadow@xoffset \hbox{\lower\spx@boxes@shadow@yoffset \vbox{\ifspx@boxes@withshadowcolor \color{spx@boxes@shadowcolor}% \else % 6.2.0: guard against a manually inserted \color command in % contents which could leak at a page break to the shadow \normalcolor \fi \ifdim\spx@boxes@shadow@yoffset<\z@ \hrule\@height-\spx@boxes@shadow@yoffset \kern\spx@boxes@shadow@yoffset \fi \setbox\spx@tempboxb\hb@xt@\wd\spx@tempboxa{% \ifdim\spx@boxes@shadow@xoffset<\z@\vrule\@width-\spx@boxes@shadow@xoffset\fi \hss \ifdim\spx@boxes@shadow@xoffset>\z@\vrule\@width\spx@boxes@shadow@xoffset\fi }% \ht\spx@tempboxb\ht\spx@tempboxa \dp\spx@tempboxb\dp\spx@tempboxa \box\spx@tempboxb \ifdim\spx@boxes@shadow@yoffset>\z@ \kern-\spx@boxes@shadow@yoffset \hrule\@height\spx@boxes@shadow@yoffset \fi \kern-\dp\spx@tempboxa }% end of \vbox, attention it will have zero depth if yoffset>0 \kern-\wd\spx@tempboxa \ifdim\spx@boxes@shadow@xoffset>\z@ \kern-\spx@boxes@shadow@xoffset \fi }% end of \hbox, attention its depth is only yoffset if yoffset>0 }% end of \vbox \fi % end of shadow drawing, and we are back to horizontal reference point % BOX BORDER \vbox{\ifspx@boxes@withbordercolor \color{spx@boxes@bordercolor}% \else % 6.2.0: guard against a \color command in contents whose effect % could leak to border at a pagebreak \normalcolor \fi \hrule\@height\spx@boxes@border@top \kern-\spx@boxes@border@top \setbox\spx@tempboxb\hb@xt@\wd\spx@tempboxa {\vrule\@width\spx@boxes@border@left \hss\vrule\@width\spx@boxes@border@right }% \ht\spx@tempboxb\ht\spx@tempboxa \dp\spx@tempboxb\dp\spx@tempboxa \box\spx@tempboxb \kern-\spx@boxes@border@bottom \hrule\@height\spx@boxes@border@bottom \kern-\dp\spx@tempboxa }% attention this box has zero depth due to \hrule at bottom % step back to horizontal reference point \kern-\wd\spx@tempboxa % end of border drawing % CONTENTS % adjust the total depth to include the bottom shadow \ifspx@boxes@withshadow \ifdim\spx@boxes@shadow@yoffset>\z@ \dp\spx@tempboxa\dimexpr\dp\spx@tempboxa+\spx@boxes@shadow@yoffset\relax \fi \fi \box\spx@tempboxa % include lateral shadow in total width \ifspx@boxes@withshadow \ifspx@boxes@shadowinbbox \ifdim\spx@boxes@shadow@xoffset>\z@\kern\spx@boxes@shadow@xoffset\fi \fi \fi \egroup } % inset shadow % % The parameters signs are interpreted as in CSS styling. \def\spx@boxes@fcolorbox@insetshadow{% % BACKGROUND % draw background and move back to reference point \ifspx@boxes@withbackgroundcolor {\color{spx@boxes@backgroundcolor}% \vrule\@height\ht\spx@tempboxa \@depth\dp\spx@tempboxa \@width\wd\spx@tempboxa \kern-\wd\spx@tempboxa }% \fi % BOX SHADOW % draw shadow and move back to reference point \ifspx@boxes@withshadow \hbox{\vbox{\ifspx@boxes@withshadowcolor \color{spx@boxes@shadowcolor}% \else % 6.2.0: guard against a manually inserted \color command in % contents which could leak at a page break to the shadow \normalcolor \fi % NOTA BENE % We deliberately draw shadow partially under an area later covered by frame % with the idea to avoid anti-aliasing problems but in fact this may be a bad % idea with border is thin. % This may need some extra testing with PDF viewers... reports welcome! \ifdim\spx@boxes@shadow@yoffset>\z@ \hrule\@height\dimexpr\spx@boxes@border@top+\spx@boxes@shadow@yoffset\relax \kern-\spx@boxes@shadow@yoffset \kern-\spx@boxes@border@top \fi \setbox\spx@tempboxb\hb@xt@\wd\spx@tempboxa{% \ifdim\spx@boxes@shadow@xoffset>\z@ \vrule\@width\dimexpr\spx@boxes@border@left+\spx@boxes@shadow@xoffset\relax\fi \hss \ifdim\spx@boxes@shadow@xoffset<\z@ \vrule\@width\dimexpr-\spx@boxes@shadow@xoffset+\spx@boxes@border@right\relax\fi }% \ht\spx@tempboxb\ht\spx@tempboxa \dp\spx@tempboxb\dp\spx@tempboxa \box\spx@tempboxb \ifdim\spx@boxes@shadow@yoffset<\z@ \kern\spx@boxes@shadow@yoffset \kern-\spx@boxes@border@bottom \hrule\@height\dimexpr-\spx@boxes@shadow@yoffset+\spx@boxes@border@bottom\relax \fi \kern-\dp\spx@tempboxa }% end of \vbox, attention it will have zero depth if yoffset<0 \kern-\wd\spx@tempboxa }% end of \hbox, attention its depth is only |yoffset| if yoffset<0 \fi % end of inset shadow drawing, and we are back to horizontal reference point % BOX BORDER \vbox{\ifspx@boxes@withbordercolor \color{spx@boxes@bordercolor}% \else % 6.2.0: guard against a \color command in contents whose effect % could leak to border at a pagebreak \normalcolor \fi \hrule\@height\spx@boxes@border@top \kern-\spx@boxes@border@top \setbox\spx@tempboxb\hb@xt@\wd\spx@tempboxa {\vrule\@width\spx@boxes@border@left \hss\vrule\@width\spx@boxes@border@right }% \ht\spx@tempboxb\ht\spx@tempboxa \dp\spx@tempboxb\dp\spx@tempboxa \box\spx@tempboxb \kern-\spx@boxes@border@bottom \hrule\@height\spx@boxes@border@bottom \kern-\dp\spx@tempboxa }% attention this box has zero depth due to \hrule at bottom % step back to horizontal reference point \kern-\wd\spx@tempboxa % end of border drawing % CONTENTS \box\spx@tempboxa \egroup } % let's abort input if pict2e package could not be loaded. % To be extra safe we also alias @rounded to @rectangle but % a priori the architecture is done so that @rounded will never % be called in that case by other Sphinx LaTeX components. \@ifpackageloaded{pict2e} {} {\def\spx@boxes@fcolorbox@rounded{\spx@boxes@fcolorbox@rectangle}% \endinput } % we proceed now in the context of pict2e being available and loaded % (TeX being a macro-expansion based language it would have % swallowed all the coming definitions even if pict2e % had in fact not been loaded... but we aborted the input above) %%%%%%%% %//// \spx@boxes@fcolorbox@rounded % % Prior to 6.2.0, a constant border-width was applied as the border was % obtained as a \strokepath. This allowed 4 distinct radii but not to vary the % border widths. Now the border is drawn by two \fillpath operation, the first % one filling up to external border, the second one actually filling for the % background paradoxically on top of it, up to internal border path. % % This 6.2.0 abandonment of \strokepath allowed great simplification in % supporting opentop, openbottom and openboth situations, and it can % allow automatic support of openleft and openright analogs. % % And 6.2.0 also implements elliptical arcs thanks to ellipse package, % which extends pict2e. % Currently, inset shadow is not supported. % % Prior to 6.2.0 an inset shadow triggered the rectangle variant, so we never % ended here, but now it is simply ignored. This change does not appear to me % to be breaking, as it changes output only for conf.py's specifying both % rounded corners and an inset shadow and the documentation said it was % incompatible. % wrappers for pict2e usage if old % Better not to copy over 2020 pict2e definitions in case % something internal changes % However our wrappers will work ONLY with dimensional inputs % No need to pre-expand the arguments % Braces in case the expression uses parentheses \def\spx@moveto(#1,#2){\moveto({\strip@pt\dimexpr#1\relax},{\strip@pt\dimexpr#2\relax})} \def\spx@lineto(#1,#2){\lineto({\strip@pt\dimexpr#1\relax},{\strip@pt\dimexpr#2\relax})} % attention here the [N] becomes mandatory % \circlearc[]{}{}{}{}{} \def\spx@circlearc[#1]#2#3#4%#5#6 {\circlearc[#1]{\strip@pt\dimexpr#2\relax}% {\strip@pt\dimexpr#3\relax}% {\strip@pt\dimexpr#4\relax}% } % attention here too the [N] becomes mandatory % the core path macro of ellipse.sty. Thanks to Daan Leijen, author of this % package. % \elliparc []{}{}{}{}{}{} % maybe this wrapper is unneeded but I don't have real time to check \def\spx@elliparc[#1]#2#3#4#5%#6#7 {\elliparc[#1]{\strip@pt\dimexpr#2\relax}% {\strip@pt\dimexpr#3\relax}% {\strip@pt\dimexpr#4\relax}% {\strip@pt\dimexpr#5\relax}% } % Macro whose execution prepares a path to be either stroked or filled % Only fill operation is used at 6.2.0. The radii are given by the set box % parameters, but the width and height are in \spx@width and \spx@height. A % \put command will be used for appropriate shifts. % 6.2.0 adds elliptical corners! % But I feel perhaps I need to think about how x-radius and y-radius should % interact with border-width. So consider output WIP for time being. \def\spx@boxes@border@defpath{% \spx@moveto(\spx@boxes@radius@bottomleft@x,\z@)% our \spx@moveto is a bit rigid % and we must use \z@ not 0 here \spx@lineto(\spx@width-\spx@boxes@radius@bottomright@x,\z@)% % x and y radii are either both positive or both zero % probably not needed to actually guard against the latter case, % let's do it nevertheless \ifdim\spx@boxes@radius@bottomright@x>\z@ \ifdim\spx@boxes@radius@bottomright@x=\spx@boxes@radius@bottomright@y \spx@circlearc[2]{\spx@width-\spx@boxes@radius@bottomright@x}% {\spx@boxes@radius@bottomright@y}% {\spx@boxes@radius@bottomright@x}{-90}{0}% \else \spx@elliparc[2]{\spx@width-\spx@boxes@radius@bottomright@x}% {\spx@boxes@radius@bottomright@y}% {\spx@boxes@radius@bottomright@x} {\spx@boxes@radius@bottomright@y}{-90}{0}% \fi \fi \spx@lineto(\spx@width,% \spx@height-\spx@boxes@radius@topright@y)% \ifdim\spx@boxes@radius@topright@x>\z@ \ifdim\spx@boxes@radius@topright@x=\spx@boxes@radius@topright@y \spx@circlearc[2]{\spx@width-\spx@boxes@radius@topright@x} {\spx@height-\spx@boxes@radius@topright@y}% {\spx@boxes@radius@topright@x}{0}{90}% \else \spx@elliparc[2]{\spx@width-\spx@boxes@radius@topright@x} {\spx@height-\spx@boxes@radius@topright@y}% {\spx@boxes@radius@topright@x}% {\spx@boxes@radius@topright@y}{0}{90}% \fi \fi \spx@lineto(\spx@boxes@radius@topleft@x,\spx@height)% \ifdim\spx@boxes@radius@topleft@x>\z@ \ifdim\spx@boxes@radius@topleft@x=\spx@boxes@radius@topleft@y \spx@circlearc[2]{\spx@boxes@radius@topleft@x}% {\spx@height-\spx@boxes@radius@topleft@y}% {\spx@boxes@radius@topleft@x}{90}{180}% \else \spx@elliparc[2]{\spx@boxes@radius@topleft@x}% {\spx@height-\spx@boxes@radius@topleft@y}% {\spx@boxes@radius@topleft@x}% {\spx@boxes@radius@topleft@y}{90}{180}% \fi \fi \spx@lineto(\z@,\spx@boxes@radius@bottomleft@y)% \ifdim\spx@boxes@radius@bottomleft@x>\z@ \ifdim\spx@boxes@radius@bottomleft@x=\spx@boxes@radius@bottomleft@y \spx@circlearc[2]{\spx@boxes@radius@bottomleft@x}% {\spx@boxes@radius@bottomleft@y}% {\spx@boxes@radius@bottomleft@x}{180}{270}% \else \spx@elliparc[2]{\spx@boxes@radius@bottomleft@x}% {\spx@boxes@radius@bottomleft@y}% {\spx@boxes@radius@bottomleft@x}% {\spx@boxes@radius@bottomleft@y}{180}{270}% \fi \fi }% end of definition of \spx@boxes@border@defpath % The customization of the various parameters must have been done via an % appropriate call to \spx@boxes@fcolorbox@setup, which will have set up % \spx@boxes@fcolorbox to expand to \spx@boxes@fcolorbox@rounded, and will % have set its various parameters. % \long\def\spx@boxes@fcolorbox@rounded #1{% \hbox{% \ifspx@boxes@withshadow \ifspx@boxes@insetshadow \spx@boxes@withshadowfalse % ignore inset shadow \fi \fi % reserve space to external shadow if on left \ifspx@boxes@withshadow \ifspx@boxes@shadowinbbox \ifdim\spx@boxes@shadow@xoffset<\z@\kern-\spx@boxes@shadow@xoffset\fi \fi \fi \vbox{% % adjust vertical bbox \ifspx@boxes@withshadow \ifdim\spx@boxes@shadow@yoffset<\z@ \kern-\spx@boxes@shadow@yoffset \fi \fi \setlength{\unitlength}{1pt}% \setbox\spx@tempboxa \hbox{\kern\dimexpr\spx@boxes@border@left+\spx@boxes@padding@left\relax {#1}% \kern\dimexpr\spx@boxes@padding@right+\spx@boxes@border@right\relax}% \ht\spx@tempboxa \dimexpr\ht\spx@tempboxa+\spx@boxes@border@top+\spx@boxes@padding@top\relax \dp\spx@tempboxa \dimexpr\dp\spx@tempboxa+\spx@boxes@padding@bottom+\spx@boxes@border@bottom\relax \edef\spx@width{\number\wd\spx@tempboxa sp}% \edef\spx@height{\number\dimexpr\ht\spx@tempboxa+\dp\spx@tempboxa sp}% \hbox{% \begin{picture}% % \strip@pt\dimexpr to work around "old" LaTeX picture limitation % (we could use the "picture" package, this would add another dependency) (\strip@pt\dimexpr\spx@width\relax,\strip@pt\dimexpr\spx@height\relax)% \spx@boxes@border@defpath \ifspx@boxes@withshadow \ifspx@boxes@withshadowcolor \color{spx@boxes@shadowcolor}% \else % 6.2.0: here and elsewhere guard against a manually inserted % \color command in contents which could leak to the shadow % to the shadow \normalcolor \fi \put(\strip@pt\spx@boxes@shadow@xoffset,% \strip@pt\dimexpr-\spx@boxes@shadow@yoffset\relax) {\fillpath}% \fi \spx@boxes@border@defpath% must be redone after each \fillpath! (even if % was in a \put) \ifspx@boxes@withbordercolor \color{spx@boxes@bordercolor}% \else \normalcolor \fi \fillpath \ifspx@boxes@withbackgroundcolor \color{spx@boxes@backgroundcolor}% \else \color{white}% \fi \edef\spx@width{\number\dimexpr\spx@width-\spx@boxes@border@left -\spx@boxes@border@right sp}% \edef\spx@height{\number\dimexpr\spx@height-\spx@boxes@border@top -\spx@boxes@border@bottom sp}% % redefine a path (in relative coordinates) matching the area delimited % by the internal borders \spx@boxes@border@defpath % use \put to shift, and fill it with background color \put(\strip@pt\spx@boxes@border@left,\strip@pt\spx@boxes@border@bottom) {\fillpath}% \end{picture}}% end of picture \hbox in \vbox % back-up vertically for outputting the contents \kern-\dimexpr\ht\spx@tempboxa+\dp\spx@tempboxa\relax % adjust vertical bbox \ifspx@boxes@withshadow \ifdim\spx@boxes@shadow@yoffset>\z@ \dp\spx@tempboxa\dimexpr\dp\spx@tempboxa+\spx@boxes@shadow@yoffset\relax \fi \fi % inhibit TeX's "line skip" adjustment when piling up hboxes in a vbox \nointerlineskip \box\spx@tempboxa }% end of \vbox % include lateral shadow in total width \ifspx@boxes@withshadow \ifspx@boxes@shadowinbbox \ifdim\spx@boxes@shadow@xoffset>\z@\kern\spx@boxes@shadow@xoffset\fi \fi \fi }% end of \hbox }% \endinput krb5-1.22.1/doc/pdf/admin.tex0000664000175000017500000226210015051422731015475 0ustar ghudsonghudson%% Generated by Sphinx. \def\sphinxdocclass{report} \documentclass[letterpaper,10pt,english]{sphinxmanual} \ifdefined\pdfpxdimen \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen \fi \sphinxpxdimen=.75bp\relax \ifdefined\pdfimageresolution \pdfimageresolution= \numexpr \dimexpr1in\relax/\sphinxpxdimen\relax \fi %% let collapsible pdf bookmarks panel have high depth per default \PassOptionsToPackage{bookmarksdepth=5}{hyperref} \PassOptionsToPackage{booktabs}{sphinx} \PassOptionsToPackage{colorrows}{sphinx} \PassOptionsToPackage{warn}{textcomp} \usepackage[utf8]{inputenc} \ifdefined\DeclareUnicodeCharacter % support both utf8 and utf8x syntaxes \ifdefined\DeclareUnicodeCharacterAsOptional \def\sphinxDUC#1{\DeclareUnicodeCharacter{"#1}} \else \let\sphinxDUC\DeclareUnicodeCharacter \fi \sphinxDUC{00A0}{\nobreakspace} \sphinxDUC{2500}{\sphinxunichar{2500}} \sphinxDUC{2502}{\sphinxunichar{2502}} \sphinxDUC{2514}{\sphinxunichar{2514}} \sphinxDUC{251C}{\sphinxunichar{251C}} \sphinxDUC{2572}{\textbackslash} \fi \usepackage{cmap} \usepackage[T1]{fontenc} \usepackage{amsmath,amssymb,amstext} \usepackage{babel} \usepackage{tgtermes} \usepackage{tgheros} \renewcommand{\ttdefault}{txtt} \usepackage[Bjarne]{fncychap} \usepackage{sphinx} \fvset{fontsize=auto} \usepackage{geometry} % Include hyperref last. \usepackage{hyperref} % Fix anchor placement for figures with captions. \usepackage{hypcap}% it must be loaded after hyperref. % Set up styles of URL: it should be placed after hyperref. \urlstyle{same} \usepackage{sphinxmessages} \setcounter{tocdepth}{0} \title{Kerberos Administration Guide} \date{ } \release{1.22.1} \author{MIT} \newcommand{\sphinxlogo}{\vbox{}} \renewcommand{\releasename}{Release} \makeindex \begin{document} \ifdefined\shorthandoff \ifnum\catcode`\=\string=\active\shorthandoff{=}\fi \ifnum\catcode`\"=\active\shorthandoff{"}\fi \fi \pagestyle{empty} \sphinxmaketitle \pagestyle{plain} \sphinxtableofcontents \pagestyle{normal} \phantomsection\label{\detokenize{admin/index::doc}} \sphinxstepscope \chapter{Installation guide} \label{\detokenize{admin/install:installation-guide}}\label{\detokenize{admin/install::doc}} \section{Contents} \label{\detokenize{admin/install:contents}} \sphinxstepscope \subsection{Installing KDCs} \label{\detokenize{admin/install_kdc:installing-kdcs}}\label{\detokenize{admin/install_kdc::doc}} \sphinxAtStartPar When setting up Kerberos in a production environment, it is best to have multiple replica KDCs alongside with a primary KDC to ensure the continued availability of the Kerberized services. Each KDC contains a copy of the Kerberos database. The primary KDC contains the writable copy of the realm database, which it replicates to the replica KDCs at regular intervals. All database changes (such as password changes) are made on the primary KDC. Replica KDCs provide Kerberos ticket\sphinxhyphen{}granting services, but not database administration, when the primary KDC is unavailable. MIT recommends that you install all of your KDCs to be able to function as either the primary or one of the replicas. This will enable you to easily switch your primary KDC with one of the replicas if necessary (see {\hyperref[\detokenize{admin/install_kdc:switch-primary-replica}]{\sphinxcrossref{\DUrole{std,std-ref}{Switching primary and replica KDCs}}}}). This installation procedure is based on that recommendation. \begin{sphinxadmonition}{warning}{Warning:}\begin{itemize} \item {} \sphinxAtStartPar The Kerberos system relies on the availability of correct time information. Ensure that the primary and all replica KDCs have properly synchronized clocks. \item {} \sphinxAtStartPar It is best to install and run KDCs on secured and dedicated hardware with limited access. If your KDC is also a file server, FTP server, Web server, or even just a client machine, someone who obtained root access through a security hole in any of those areas could potentially gain access to the Kerberos database. \end{itemize} \end{sphinxadmonition} \subsubsection{Install and configure the primary KDC} \label{\detokenize{admin/install_kdc:install-and-configure-the-primary-kdc}} \sphinxAtStartPar Install Kerberos either from the OS\sphinxhyphen{}provided packages or from the source (See \DUrole{xref,std,std-ref}{do\_build}). \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar For the purpose of this document we will use the following names: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{\PYGZhy{}} \PYG{n}{primary} \PYG{n}{KDC} \PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{\PYGZhy{}} \PYG{n}{replica} \PYG{n}{KDC} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{\PYGZhy{}} \PYG{n}{realm} \PYG{n}{name} \PYG{o}{.}\PYG{n}{k5}\PYG{o}{.}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{\PYGZhy{}} \PYG{n}{stash} \PYG{n}{file} \PYG{n}{admin}\PYG{o}{/}\PYG{n}{admin} \PYG{o}{\PYGZhy{}} \PYG{n}{admin} \PYG{n}{principal} \end{sphinxVerbatim} \sphinxAtStartPar See {\hyperref[\detokenize{mitK5defaults:mitk5defaults}]{\sphinxcrossref{\DUrole{std,std-ref}{MIT Kerberos defaults}}}} for the default names and locations of the relevant to this topic files. Adjust the names and paths to your system environment. \end{sphinxadmonition} \subsubsection{Edit KDC configuration files} \label{\detokenize{admin/install_kdc:edit-kdc-configuration-files}} \sphinxAtStartPar Modify the configuration files, {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} and {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}, to reflect the correct information (such as domain\sphinxhyphen{}realm mappings and Kerberos servers names) for your realm. (See {\hyperref[\detokenize{mitK5defaults:mitk5defaults}]{\sphinxcrossref{\DUrole{std,std-ref}{MIT Kerberos defaults}}}} for the recommended default locations for these files). \sphinxAtStartPar Most of the tags in the configuration have default values that will work well for most sites. There are some tags in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} file whose values must be specified, and this section will explain those. \sphinxAtStartPar If the locations for these configuration files differs from the default ones, set \sphinxstylestrong{KRB5\_CONFIG} and \sphinxstylestrong{KRB5\_KDC\_PROFILE} environment variables to point to the krb5.conf and kdc.conf respectively. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{export} \PYG{n}{KRB5\PYGZus{}CONFIG}\PYG{o}{=}\PYG{o}{/}\PYG{n}{yourdir}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{conf} \PYG{n}{export} \PYG{n}{KRB5\PYGZus{}KDC\PYGZus{}PROFILE}\PYG{o}{=}\PYG{o}{/}\PYG{n}{yourdir}\PYG{o}{/}\PYG{n}{kdc}\PYG{o}{.}\PYG{n}{conf} \end{sphinxVerbatim} \paragraph{krb5.conf} \label{\detokenize{admin/install_kdc:krb5-conf}} \sphinxAtStartPar If you are not using DNS TXT records (see {\hyperref[\detokenize{admin/realm_config:mapping-hostnames}]{\sphinxcrossref{\DUrole{std,std-ref}{Mapping hostnames onto Kerberos realms}}}}), you must specify the \sphinxstylestrong{default\_realm} in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}} section. If you are not using DNS URI or SRV records (see {\hyperref[\detokenize{admin/realm_config:kdc-hostnames}]{\sphinxcrossref{\DUrole{std,std-ref}{Hostnames for KDCs}}}} and {\hyperref[\detokenize{admin/realm_config:kdc-discovery}]{\sphinxcrossref{\DUrole{std,std-ref}{KDC Discovery}}}}), you must include the \sphinxstylestrong{kdc} tag for each \sphinxstyleemphasis{realm} in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} section. To communicate with the kadmin server in each realm, the \sphinxstylestrong{admin\_server} tag must be set in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} section. \sphinxAtStartPar An example krb5.conf file: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{libdefaults}\PYG{p}{]} \PYG{n}{default\PYGZus{}realm} \PYG{o}{=} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{admin\PYGZus{}server} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \paragraph{kdc.conf} \label{\detokenize{admin/install_kdc:kdc-conf}} \sphinxAtStartPar The kdc.conf file can be used to control the listening ports of the KDC and kadmind, as well as realm\sphinxhyphen{}specific defaults, the database type and location, and logging. \sphinxAtStartPar An example kdc.conf file: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{kdcdefaults}\PYG{p}{]} \PYG{n}{kdc\PYGZus{}listen} \PYG{o}{=} \PYG{l+m+mi}{88} \PYG{n}{kdc\PYGZus{}tcp\PYGZus{}listen} \PYG{o}{=} \PYG{l+m+mi}{88} \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{kadmind\PYGZus{}port} \PYG{o}{=} \PYG{l+m+mi}{749} \PYG{n}{max\PYGZus{}life} \PYG{o}{=} \PYG{l+m+mi}{12}\PYG{n}{h} \PYG{l+m+mi}{0}\PYG{n}{m} \PYG{l+m+mi}{0}\PYG{n}{s} \PYG{n}{max\PYGZus{}renewable\PYGZus{}life} \PYG{o}{=} \PYG{l+m+mi}{7}\PYG{n}{d} \PYG{l+m+mi}{0}\PYG{n}{h} \PYG{l+m+mi}{0}\PYG{n}{m} \PYG{l+m+mi}{0}\PYG{n}{s} \PYG{n}{master\PYGZus{}key\PYGZus{}type} \PYG{o}{=} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts} \PYG{n}{supported\PYGZus{}enctypes} \PYG{o}{=} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{p}{:}\PYG{n}{normal} \PYG{c+c1}{\PYGZsh{} If the default location does not suit your setup,} \PYG{c+c1}{\PYGZsh{} explicitly configure the following values:} \PYG{c+c1}{\PYGZsh{} database\PYGZus{}name = /var/krb5kdc/principal} \PYG{c+c1}{\PYGZsh{} key\PYGZus{}stash\PYGZus{}file = /var/krb5kdc/.k5.ATHENA.MIT.EDU} \PYG{c+c1}{\PYGZsh{} acl\PYGZus{}file = /var/krb5kdc/kadm5.acl} \PYG{p}{\PYGZcb{}} \PYG{p}{[}\PYG{n}{logging}\PYG{p}{]} \PYG{c+c1}{\PYGZsh{} By default, the KDC and kadmind will log output using} \PYG{c+c1}{\PYGZsh{} syslog. You can instead send log output to files like this:} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{log}\PYG{o}{/}\PYG{n}{krb5kdc}\PYG{o}{.}\PYG{n}{log} \PYG{n}{admin\PYGZus{}server} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{log}\PYG{o}{/}\PYG{n}{kadmin}\PYG{o}{.}\PYG{n}{log} \PYG{n}{default} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{log}\PYG{o}{/}\PYG{n}{krb5lib}\PYG{o}{.}\PYG{n}{log} \end{sphinxVerbatim} \sphinxAtStartPar Replace \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} and \sphinxcode{\sphinxupquote{kerberos.mit.edu}} with the name of your Kerberos realm and server respectively. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar You have to have write permission on the target directories (these directories must exist) used by \sphinxstylestrong{database\_name}, \sphinxstylestrong{key\_stash\_file}, and \sphinxstylestrong{acl\_file}. \end{sphinxadmonition} \subsubsection{Create the KDC database} \label{\detokenize{admin/install_kdc:create-the-kdc-database}}\label{\detokenize{admin/install_kdc:create-db}} \sphinxAtStartPar You will use the {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} command on the primary KDC to create the Kerberos database and the optional \DUrole{xref,std,std-ref}{stash\_definition}. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If you choose not to install a stash file, the KDC will prompt you for the master key each time it starts up. This means that the KDC will not be able to start automatically, such as after a system reboot. \end{sphinxadmonition} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} will prompt you for the master password for the Kerberos database. This password can be any string. A good password is one you can remember, but that no one else can guess. Examples of bad passwords are words that can be found in a dictionary, any common or popular name, especially a famous person (or cartoon character), your username in any form (e.g., forward, backward, repeated twice, etc.), and any of the sample passwords that appear in this manual. One example of a password which might be good if it did not appear in this manual is “MITiys4K5!â€, which represents the sentence “MIT is your source for Kerberos 5!†(It’s the first letter of each word, substituting the numeral “4†for the word “forâ€, and includes the punctuation mark at the end.) \sphinxAtStartPar The following is an example of how to create a Kerberos database and stash file on the primary KDC, using the {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} command. Replace \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} with the name of your Kerberos realm: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kdb5\PYGZus{}util} \PYG{n}{create} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{\PYGZhy{}}\PYG{n}{s} \PYG{n}{Initializing} \PYG{n}{database} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{/usr/local/var/krb5kdc/principal}\PYG{l+s+s1}{\PYGZsq{}} \PYG{k}{for} \PYG{n}{realm} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{ATHENA.MIT.EDU}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{,} \PYG{n}{master} \PYG{n}{key} \PYG{n}{name} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{K/M@ATHENA.MIT.EDU}\PYG{l+s+s1}{\PYGZsq{}} \PYG{n}{You} \PYG{n}{will} \PYG{n}{be} \PYG{n}{prompted} \PYG{k}{for} \PYG{n}{the} \PYG{n}{database} \PYG{n}{Master} \PYG{n}{Password}\PYG{o}{.} \PYG{n}{It} \PYG{o+ow}{is} \PYG{n}{important} \PYG{n}{that} \PYG{n}{you} \PYG{n}{NOT} \PYG{n}{FORGET} \PYG{n}{this} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Enter} \PYG{n}{KDC} \PYG{n}{database} \PYG{n}{master} \PYG{n}{key}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{Type} \PYG{n}{the} \PYG{n}{master} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Re}\PYG{o}{\PYGZhy{}}\PYG{n}{enter} \PYG{n}{KDC} \PYG{n}{database} \PYG{n}{master} \PYG{n}{key} \PYG{n}{to} \PYG{n}{verify}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{Type} \PYG{n}{it} \PYG{n}{again}\PYG{o}{.} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar This will create five files in {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}} (or at the locations specified in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}): \begin{itemize} \item {} \sphinxAtStartPar two Kerberos database files, \sphinxcode{\sphinxupquote{principal}}, and \sphinxcode{\sphinxupquote{principal.ok}} \item {} \sphinxAtStartPar the Kerberos administrative database file, \sphinxcode{\sphinxupquote{principal.kadm5}} \item {} \sphinxAtStartPar the administrative database lock file, \sphinxcode{\sphinxupquote{principal.kadm5.lock}} \item {} \sphinxAtStartPar the stash file, in this example \sphinxcode{\sphinxupquote{.k5.ATHENA.MIT.EDU}}. If you do not want a stash file, run the above command without the \sphinxstylestrong{\sphinxhyphen{}s} option. \end{itemize} \sphinxAtStartPar For more information on administrating Kerberos database see {\hyperref[\detokenize{admin/database:db-operations}]{\sphinxcrossref{\DUrole{std,std-ref}{Operations on the Kerberos database}}}}. \subsubsection{Add administrators to the ACL file} \label{\detokenize{admin/install_kdc:add-administrators-to-the-acl-file}}\label{\detokenize{admin/install_kdc:admin-acl}} \sphinxAtStartPar Next, you need create an Access Control List (ACL) file and put the Kerberos principal of at least one of the administrators into it. This file is used by the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon to control which principals may view and make privileged modifications to the Kerberos database files. The ACL filename is determined by the \sphinxstylestrong{acl\_file} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}; the default is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kadm5.acl}}. \sphinxAtStartPar For more information on Kerberos ACL file see {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}}. \subsubsection{Add administrators to the Kerberos database} \label{\detokenize{admin/install_kdc:add-administrators-to-the-kerberos-database}}\label{\detokenize{admin/install_kdc:addadmin-kdb}} \sphinxAtStartPar Next you need to add administrative principals (i.e., principals who are allowed to administer Kerberos database) to the Kerberos database. You \sphinxstyleemphasis{must} add at least one principal now to allow communication between the Kerberos administration daemon kadmind and the kadmin program over the network for further administration. To do this, use the kadmin.local utility on the primary KDC. kadmin.local is designed to be run on the primary KDC host without using Kerberos authentication to an admin server; instead, it must have read and write access to the Kerberos database on the local filesystem. \sphinxAtStartPar The administrative principals you create should be the ones you added to the ACL file (see {\hyperref[\detokenize{admin/install_kdc:admin-acl}]{\sphinxcrossref{\DUrole{std,std-ref}{Add administrators to the ACL file}}}}). \sphinxAtStartPar In the following example, the administrative principal \sphinxcode{\sphinxupquote{admin/admin}} is created: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kadmin}\PYG{o}{.}\PYG{n}{local} \PYG{n}{kadmin}\PYG{o}{.}\PYG{n}{local}\PYG{p}{:} \PYG{n}{addprinc} \PYG{n}{admin}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{No} \PYG{n}{policy} \PYG{n}{specified} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{admin/admin@ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{assigning} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{default}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.} \PYG{n}{Enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{admin}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{Enter} \PYG{n}{a} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Re}\PYG{o}{\PYGZhy{}}\PYG{n}{enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{admin}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{Type} \PYG{n}{it} \PYG{n}{again}\PYG{o}{.} \PYG{n}{Principal} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{admin/admin@ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{created}\PYG{o}{.} \PYG{n}{kadmin}\PYG{o}{.}\PYG{n}{local}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{Start the Kerberos daemons on the primary KDC} \label{\detokenize{admin/install_kdc:start-the-kerberos-daemons-on-the-primary-kdc}}\label{\detokenize{admin/install_kdc:start-kdc-daemons}} \sphinxAtStartPar At this point, you are ready to start the Kerberos KDC ({\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}}) and administrative daemons on the primary KDC. To do so, type: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{krb5kdc} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kadmind} \end{sphinxVerbatim} \sphinxAtStartPar Each server daemon will fork and run in the background. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar Assuming you want these daemons to start up automatically at boot time, you can add them to the KDC’s \sphinxcode{\sphinxupquote{/etc/rc}} or \sphinxcode{\sphinxupquote{/etc/inittab}} file. You need to have a \DUrole{xref,std,std-ref}{stash\_definition} in order to do this. \end{sphinxadmonition} \sphinxAtStartPar You can verify that they started properly by checking for their startup messages in the logging locations you defined in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} (see {\hyperref[\detokenize{admin/conf_files/kdc_conf:logging}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}logging{]}}}}}). For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{tail} \PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{log}\PYG{o}{/}\PYG{n}{krb5kdc}\PYG{o}{.}\PYG{n}{log} \PYG{n}{Dec} \PYG{l+m+mi}{02} \PYG{l+m+mi}{12}\PYG{p}{:}\PYG{l+m+mi}{35}\PYG{p}{:}\PYG{l+m+mi}{47} \PYG{n}{beeblebrox} \PYG{n}{krb5kdc}\PYG{p}{[}\PYG{l+m+mi}{3187}\PYG{p}{]}\PYG{p}{(}\PYG{n}{info}\PYG{p}{)}\PYG{p}{:} \PYG{n}{commencing} \PYG{n}{operation} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{tail} \PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{log}\PYG{o}{/}\PYG{n}{kadmin}\PYG{o}{.}\PYG{n}{log} \PYG{n}{Dec} \PYG{l+m+mi}{02} \PYG{l+m+mi}{12}\PYG{p}{:}\PYG{l+m+mi}{35}\PYG{p}{:}\PYG{l+m+mi}{52} \PYG{n}{beeblebrox} \PYG{n}{kadmind}\PYG{p}{[}\PYG{l+m+mi}{3189}\PYG{p}{]}\PYG{p}{(}\PYG{n}{info}\PYG{p}{)}\PYG{p}{:} \PYG{n}{starting} \end{sphinxVerbatim} \sphinxAtStartPar Any errors the daemons encounter while starting will also be listed in the logging output. \sphinxAtStartPar As an additional verification, check if \DUrole{xref,std,std-ref}{kinit(1)} succeeds against the principals that you have created on the previous step ({\hyperref[\detokenize{admin/install_kdc:addadmin-kdb}]{\sphinxcrossref{\DUrole{std,std-ref}{Add administrators to the Kerberos database}}}}). Run: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kinit} \PYG{n}{admin}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \end{sphinxVerbatim} \subsubsection{Install the replica KDCs} \label{\detokenize{admin/install_kdc:install-the-replica-kdcs}} \sphinxAtStartPar You are now ready to start configuring the replica KDCs. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar Assuming you are setting the KDCs up so that you can easily switch the primary KDC with one of the replicas, you should perform each of these steps on the primary KDC as well as the replica KDCs, unless these instructions specify otherwise. \end{sphinxadmonition} \paragraph{Create host keytabs for replica KDCs} \label{\detokenize{admin/install_kdc:create-host-keytabs-for-replica-kdcs}}\label{\detokenize{admin/install_kdc:replica-host-key}} \sphinxAtStartPar Each KDC needs a \sphinxcode{\sphinxupquote{host}} key in the Kerberos database. These keys are used for mutual authentication when propagating the database dump file from the primary KDC to the secondary KDC servers. \sphinxAtStartPar On the primary KDC, connect to administrative interface and create the host principal for each of the KDCs’ \sphinxcode{\sphinxupquote{host}} services. For example, if the primary KDC were called \sphinxcode{\sphinxupquote{kerberos.mit.edu}}, and you had a replica KDC named \sphinxcode{\sphinxupquote{kerberos\sphinxhyphen{}1.mit.edu}}, you would type the following: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kadmin} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{addprinc} \PYG{o}{\PYGZhy{}}\PYG{n}{randkey} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{No} \PYG{n}{policy} \PYG{n}{specified} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{host/kerberos.mit.edu@ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{assigning} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{default}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{Principal} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{host/kerberos.mit.edu@ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{created}\PYG{o}{.} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{addprinc} \PYG{o}{\PYGZhy{}}\PYG{n}{randkey} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{No} \PYG{n}{policy} \PYG{n}{specified} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{host/kerberos\PYGZhy{}1.mit.edu@ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{assigning} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{default}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{Principal} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{host/kerberos\PYGZhy{}1.mit.edu@ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{created}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar It is not strictly necessary to have the primary KDC server in the Kerberos database, but it can be handy if you want to be able to swap the primary KDC with one of the replicas. \sphinxAtStartPar Next, extract \sphinxcode{\sphinxupquote{host}} random keys for all participating KDCs and store them in each host’s default keytab file. Ideally, you should extract each keytab locally on its own KDC. If this is not feasible, you should use an encrypted session to send them across the network. To extract a keytab directly on a replica KDC called \sphinxcode{\sphinxupquote{kerberos\sphinxhyphen{}1.mit.edu}}, you would execute the following command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{ktadd} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha384}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{192} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{arcfour}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar If you are instead extracting a keytab for the replica KDC called \sphinxcode{\sphinxupquote{kerberos\sphinxhyphen{}1.mit.edu}} on the primary KDC, you should use a dedicated temporary keytab file for that machine’s keytab: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{ktadd} \PYG{o}{\PYGZhy{}}\PYG{n}{k} \PYG{o}{/}\PYG{n}{tmp}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{keytab} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar The file \sphinxcode{\sphinxupquote{/tmp/kerberos\sphinxhyphen{}1.keytab}} can then be installed as \sphinxcode{\sphinxupquote{/etc/krb5.keytab}} on the host \sphinxcode{\sphinxupquote{kerberos\sphinxhyphen{}1.mit.edu}}. \paragraph{Configure replica KDCs} \label{\detokenize{admin/install_kdc:configure-replica-kdcs}} \sphinxAtStartPar Database propagation copies the contents of the primary’s database, but does not propagate configuration files, stash files, or the kadm5 ACL file. The following files must be copied by hand to each replica (see {\hyperref[\detokenize{mitK5defaults:mitk5defaults}]{\sphinxcrossref{\DUrole{std,std-ref}{MIT Kerberos defaults}}}} for the default locations for these files): \begin{itemize} \item {} \sphinxAtStartPar krb5.conf \item {} \sphinxAtStartPar kdc.conf \item {} \sphinxAtStartPar kadm5.acl \item {} \sphinxAtStartPar master key stash file \end{itemize} \sphinxAtStartPar Move the copied files into their appropriate directories, exactly as on the primary KDC. kadm5.acl is only needed to allow a replica to swap with the primary KDC. \sphinxAtStartPar The database is propagated from the primary KDC to the replica KDCs via the {\hyperref[\detokenize{admin/admin_commands/kpropd:kpropd-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kpropd}}}} daemon. You must explicitly specify the principals which are allowed to provide Kerberos dump updates on the replica machine with a new database. Create a file named kpropd.acl in the KDC state directory containing the \sphinxcode{\sphinxupquote{host}} principals for each of the KDCs: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{host}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \end{sphinxVerbatim} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If you expect that the primary and replica KDCs will be switched at some point of time, list the host principals from all participating KDC servers in kpropd.acl files on all of the KDCs. Otherwise, you only need to list the primary KDC’s host principal in the kpropd.acl files of the replica KDCs. \end{sphinxadmonition} \sphinxAtStartPar Then, add the following line to \sphinxcode{\sphinxupquote{/etc/inetd.conf}} on each KDC (adjust the path to kpropd): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5\PYGZus{}prop} \PYG{n}{stream} \PYG{n}{tcp} \PYG{n}{nowait} \PYG{n}{root} \PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{sbin}\PYG{o}{/}\PYG{n}{kpropd} \PYG{n}{kpropd} \end{sphinxVerbatim} \sphinxAtStartPar You also need to add the following line to \sphinxcode{\sphinxupquote{/etc/services}} on each KDC, if it is not already present (assuming that the default port is used): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5\PYGZus{}prop} \PYG{l+m+mi}{754}\PYG{o}{/}\PYG{n}{tcp} \PYG{c+c1}{\PYGZsh{} Kerberos replica propagation} \end{sphinxVerbatim} \sphinxAtStartPar Restart inetd daemon. \sphinxAtStartPar Alternatively, start {\hyperref[\detokenize{admin/admin_commands/kpropd:kpropd-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kpropd}}}} as a stand\sphinxhyphen{}alone daemon. This is required when incremental propagation is enabled. \sphinxAtStartPar Now that the replica KDC is able to accept database propagation, you’ll need to propagate the database from the primary server. \sphinxAtStartPar NOTE: Do not start the replica KDC yet; you still do not have a copy of the primary’s database. \paragraph{Propagate the database to each replica KDC} \label{\detokenize{admin/install_kdc:propagate-the-database-to-each-replica-kdc}}\label{\detokenize{admin/install_kdc:kprop-to-replicas}} \sphinxAtStartPar First, create a dump file of the database on the primary KDC, as follows: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kdb5\PYGZus{}util} \PYG{n}{dump} \PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{krb5kdc}\PYG{o}{/}\PYG{n}{replica\PYGZus{}datatrans} \end{sphinxVerbatim} \sphinxAtStartPar Then, manually propagate the database to each replica KDC, as in the following example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kprop} \PYG{o}{\PYGZhy{}}\PYG{n}{f} \PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{krb5kdc}\PYG{o}{/}\PYG{n}{replica\PYGZus{}datatrans} \PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{Database} \PYG{n}{propagation} \PYG{n}{to} \PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{p}{:} \PYG{n}{SUCCEEDED} \end{sphinxVerbatim} \sphinxAtStartPar You will need a script to dump and propagate the database. The following is an example of a Bourne shell script that will do this. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar Remember that you need to replace \sphinxcode{\sphinxupquote{/usr/local/var/krb5kdc}} with the name of the KDC state directory. \end{sphinxadmonition} \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZsh{}!/bin/sh kdclist = \PYGZdq{}kerberos\PYGZhy{}1.mit.edu kerberos\PYGZhy{}2.mit.edu\PYGZdq{} kdb5\PYGZus{}util dump /usr/local/var/krb5kdc/replica\PYGZus{}datatrans for kdc in \PYGZdl{}kdclist do kprop \PYGZhy{}f /usr/local/var/krb5kdc/replica\PYGZus{}datatrans \PYGZdl{}kdc done \end{sphinxVerbatim} \sphinxAtStartPar You will need to set up a cron job to run this script at the intervals you decided on earlier (see {\hyperref[\detokenize{admin/realm_config:db-prop}]{\sphinxcrossref{\DUrole{std,std-ref}{Database propagation}}}}). \sphinxAtStartPar Now that the replica KDC has a copy of the Kerberos database, you can start the krb5kdc daemon: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{krb5kdc} \end{sphinxVerbatim} \sphinxAtStartPar As with the primary KDC, you will probably want to add this command to the KDCs’ \sphinxcode{\sphinxupquote{/etc/rc}} or \sphinxcode{\sphinxupquote{/etc/inittab}} files, so they will start the krb5kdc daemon automatically at boot time. \subparagraph{Propagation failed?} \label{\detokenize{admin/install_kdc:propagation-failed}} \sphinxAtStartPar You may encounter the following error messages. For a more detailed discussion on possible causes and solutions click on the error link to be redirected to {\hyperref[\detokenize{admin/troubleshoot:troubleshoot}]{\sphinxcrossref{\DUrole{std,std-ref}{Troubleshooting}}}} section. \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/troubleshoot:kprop-no-route}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop: No route to host while connecting to server}}}} \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/troubleshoot:kprop-con-refused}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop: Connection refused while connecting to server}}}} \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/troubleshoot:kprop-sendauth-exchange}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop: Server rejected authentication (during sendauth exchange) while authenticating to server}}}} \end{enumerate} \subsubsection{Add Kerberos principals to the database} \label{\detokenize{admin/install_kdc:add-kerberos-principals-to-the-database}} \sphinxAtStartPar Once your KDCs are set up and running, you are ready to use {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} to load principals for your users, hosts, and other services into the Kerberos database. This procedure is described fully in {\hyperref[\detokenize{admin/database:principals}]{\sphinxcrossref{\DUrole{std,std-ref}{Principals}}}}. \sphinxAtStartPar You may occasionally want to use one of your replica KDCs as the primary. This might happen if you are upgrading the primary KDC, or if your primary KDC has a disk crash. See the following section for the instructions. \subsubsection{Switching primary and replica KDCs} \label{\detokenize{admin/install_kdc:switching-primary-and-replica-kdcs}}\label{\detokenize{admin/install_kdc:switch-primary-replica}} \sphinxAtStartPar You may occasionally want to use one of your replica KDCs as the primary. This might happen if you are upgrading the primary KDC, or if your primary KDC has a disk crash. \sphinxAtStartPar Assuming you have configured all of your KDCs to be able to function as either the primary KDC or a replica KDC (as this document recommends), all you need to do to make the changeover is: \sphinxAtStartPar If the primary KDC is still running, do the following on the \sphinxstyleemphasis{old} primary KDC: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar Kill the kadmind process. \item {} \sphinxAtStartPar Disable the cron job that propagates the database. \item {} \sphinxAtStartPar Run your database propagation script manually, to ensure that the replicas all have the latest copy of the database (see {\hyperref[\detokenize{admin/install_kdc:kprop-to-replicas}]{\sphinxcrossref{\DUrole{std,std-ref}{Propagate the database to each replica KDC}}}}). \end{enumerate} \sphinxAtStartPar On the \sphinxstyleemphasis{new} primary KDC: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar Start the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon (see {\hyperref[\detokenize{admin/install_kdc:start-kdc-daemons}]{\sphinxcrossref{\DUrole{std,std-ref}{Start the Kerberos daemons on the primary KDC}}}}). \item {} \sphinxAtStartPar Set up the cron job to propagate the database (see {\hyperref[\detokenize{admin/install_kdc:kprop-to-replicas}]{\sphinxcrossref{\DUrole{std,std-ref}{Propagate the database to each replica KDC}}}}). \item {} \sphinxAtStartPar Switch the CNAMEs of the old and new primary KDCs. If you can’t do this, you’ll need to change the {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} file on every client machine in your Kerberos realm. \end{enumerate} \subsubsection{Incremental database propagation} \label{\detokenize{admin/install_kdc:incremental-database-propagation}} \sphinxAtStartPar If you expect your Kerberos database to become large, you may wish to set up incremental propagation to replica KDCs. See {\hyperref[\detokenize{admin/database:incr-db-prop}]{\sphinxcrossref{\DUrole{std,std-ref}{Incremental database propagation}}}} for details. \sphinxstepscope \subsection{Installing and configuring UNIX client machines} \label{\detokenize{admin/install_clients:installing-and-configuring-unix-client-machines}}\label{\detokenize{admin/install_clients::doc}} \sphinxAtStartPar The Kerberized client programs include \DUrole{xref,std,std-ref}{kinit(1)}, \DUrole{xref,std,std-ref}{klist(1)}, \DUrole{xref,std,std-ref}{kdestroy(1)}, and \DUrole{xref,std,std-ref}{kpasswd(1)}. All of these programs are in the directory {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{BINDIR}}}}. \sphinxAtStartPar You can often integrate Kerberos with the login system on client machines, typically through the use of PAM. The details vary by operating system, and should be covered in your operating system’s documentation. If you do this, you will need to make sure your users know to use their Kerberos passwords when they log in. \sphinxAtStartPar You will also need to educate your users to use the ticket management programs kinit, klist, and kdestroy. If you do not have Kerberos password changing integrated into the native password program (again, typically through PAM), you will need to educate users to use kpasswd in place of its non\sphinxhyphen{}Kerberos counterparts passwd. \subsubsection{Client machine configuration files} \label{\detokenize{admin/install_clients:client-machine-configuration-files}} \sphinxAtStartPar Each machine running Kerberos should have a {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} file. At a minimum, it should define a \sphinxstylestrong{default\_realm} setting in {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}}. If you are not using DNS SRV records ({\hyperref[\detokenize{admin/realm_config:kdc-hostnames}]{\sphinxcrossref{\DUrole{std,std-ref}{Hostnames for KDCs}}}}) or URI records ({\hyperref[\detokenize{admin/realm_config:kdc-discovery}]{\sphinxcrossref{\DUrole{std,std-ref}{KDC Discovery}}}}), it must also contain a {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} section containing information for your realm’s KDCs. \sphinxAtStartPar Consider setting \sphinxstylestrong{rdns} to false in order to reduce your dependence on precisely correct DNS information for service hostnames. Turning this flag off means that service hostnames will be canonicalized through forward name resolution (which adds your domain name to unqualified hostnames, and resolves CNAME records in DNS), but not through reverse address lookup. The default value of this flag is true for historical reasons only. \sphinxAtStartPar If you anticipate users frequently logging into remote hosts (e.g., using ssh) using forwardable credentials, consider setting \sphinxstylestrong{forwardable} to true so that users obtain forwardable tickets by default. Otherwise users will need to use \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}f}} to get forwardable tickets. \sphinxAtStartPar Consider adjusting the \sphinxstylestrong{ticket\_lifetime} setting to match the likely length of sessions for your users. For instance, if most of your users will be logging in for an eight\sphinxhyphen{}hour workday, you could set the default to ten hours so that tickets obtained in the morning expire shortly after the end of the workday. Users can still manually request longer tickets when necessary, up to the maximum allowed by each user’s principal record on the KDC. \sphinxAtStartPar If a client host may access services in different realms, it may be useful to define a {\hyperref[\detokenize{admin/conf_files/krb5_conf:domain-realm}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}domain\_realm{]}}}}} mapping so that clients know which hosts belong to which realms. However, if your clients and KDC are running release 1.7 or later, it is also reasonable to leave this section out on client machines and just define it in the KDC’s krb5.conf. \sphinxstepscope \subsection{UNIX Application Servers} \label{\detokenize{admin/install_appl_srv:unix-application-servers}}\label{\detokenize{admin/install_appl_srv::doc}} \sphinxAtStartPar An application server is a host that provides one or more services over the network. Application servers can be “secure†or “insecure.†A “secure†host is set up to require authentication from every client connecting to it. An “insecure†host will still provide Kerberos authentication, but will also allow unauthenticated clients to connect. \sphinxAtStartPar If you have Kerberos V5 installed on all of your client machines, MIT recommends that you make your hosts secure, to take advantage of the security that Kerberos authentication affords. However, if you have some clients that do not have Kerberos V5 installed, you can run an insecure server, and still take advantage of Kerberos V5’s single sign\sphinxhyphen{}on capability. \subsubsection{The keytab file} \label{\detokenize{admin/install_appl_srv:the-keytab-file}}\label{\detokenize{admin/install_appl_srv:keytab-file}} \sphinxAtStartPar All Kerberos server machines need a keytab file to authenticate to the KDC. By default on UNIX\sphinxhyphen{}like systems this file is named {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFKTNAME}}}}. The keytab file is an local copy of the host’s key. The keytab file is a potential point of entry for a break\sphinxhyphen{}in, and if compromised, would allow unrestricted access to its host. The keytab file should be readable only by root, and should exist only on the machine’s local disk. The file should not be part of any backup of the machine, unless access to the backup data is secured as tightly as access to the machine’s root password. \sphinxAtStartPar In order to generate a keytab for a host, the host must have a principal in the Kerberos database. The procedure for adding hosts to the database is described fully in {\hyperref[\detokenize{admin/database:principals}]{\sphinxcrossref{\DUrole{std,std-ref}{Principals}}}}. (See {\hyperref[\detokenize{admin/install_kdc:replica-host-key}]{\sphinxcrossref{\DUrole{std,std-ref}{Create host keytabs for replica KDCs}}}} for a brief description.) The keytab is generated by running {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} and issuing the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:ktadd}]{\sphinxcrossref{\DUrole{std,std-ref}{ktadd}}}} command. \sphinxAtStartPar For example, to generate a keytab file to allow the host \sphinxcode{\sphinxupquote{trillium.mit.edu}} to authenticate for the services host, ftp, and pop, the administrator \sphinxcode{\sphinxupquote{joeadmin}} would issue the command (on \sphinxcode{\sphinxupquote{trillium.mit.edu}}): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{trillium}\PYG{o}{\PYGZpc{}} \PYG{n}{kadmin} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{root}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{root}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{ktadd} \PYG{n}{host}\PYG{o}{/}\PYG{n}{trillium}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{ftp}\PYG{o}{/}\PYG{n}{trillium}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{pop}\PYG{o}{/}\PYG{n}{trillium}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{trillium}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha384}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{192} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{ftp}\PYG{o}{/}\PYG{n}{trillium}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha384}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{192} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{pop}\PYG{o}{/}\PYG{n}{trillium}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha384}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{192} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{quit} \PYG{n}{trillium}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \sphinxAtStartPar If you generate the keytab file on another host, you need to get a copy of the keytab file onto the destination host (\sphinxcode{\sphinxupquote{trillium}}, in the above example) without sending it unencrypted over the network. \subsubsection{Some advice about secure hosts} \label{\detokenize{admin/install_appl_srv:some-advice-about-secure-hosts}} \sphinxAtStartPar Kerberos V5 can protect your host from certain types of break\sphinxhyphen{}ins, but it is possible to install Kerberos V5 and still leave your host vulnerable to attack. Obviously an installation guide is not the place to try to include an exhaustive list of countermeasures for every possible attack, but it is worth noting some of the larger holes and how to close them. \sphinxAtStartPar We recommend that backups of secure machines exclude the keytab file ({\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFKTNAME}}}}). If this is not possible, the backups should at least be done locally, rather than over a network, and the backup tapes should be physically secured. \sphinxAtStartPar The keytab file and any programs run by root, including the Kerberos V5 binaries, should be kept on local disk. The keytab file should be readable only by root. \section{Additional references} \label{\detokenize{admin/install:additional-references}}\begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar Debian: \sphinxhref{http://techpubs.spinlocksolutions.com/dklar/kerberos.html}{Setting up MIT Kerberos 5} \item {} \sphinxAtStartPar Solaris: \sphinxhref{https://docs.oracle.com/cd/E19253-01/816-4557/6maosrjv2/index.html}{Configuring the Kerberos Service} \end{enumerate} \sphinxstepscope \chapter{Configuration Files} \label{\detokenize{admin/conf_files/index:configuration-files}}\label{\detokenize{admin/conf_files/index::doc}} \sphinxAtStartPar Kerberos uses configuration files to allow administrators to specify settings on a per\sphinxhyphen{}machine basis. {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} applies to all applications using the Kerboros library, on clients and servers. For KDC\sphinxhyphen{}specific applications, additional settings can be specified in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}; the two files are merged into a configuration profile used by applications accessing the KDC database directly. {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}} is also only used on the KDC, it controls permissions for modifying the KDC database. \section{Contents} \label{\detokenize{admin/conf_files/index:contents}} \sphinxstepscope \subsection{krb5.conf} \label{\detokenize{admin/conf_files/krb5_conf:krb5-conf}}\label{\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}}\label{\detokenize{admin/conf_files/krb5_conf::doc}} \sphinxAtStartPar The krb5.conf file contains Kerberos configuration information, including the locations of KDCs and admin servers for the Kerberos realms of interest, defaults for the current realm and for Kerberos applications, and mappings of hostnames onto Kerberos realms. Normally, you should install your krb5.conf file in the directory \sphinxcode{\sphinxupquote{/etc}}. You can override the default location by setting the environment variable \sphinxstylestrong{KRB5\_CONFIG}. Multiple colon\sphinxhyphen{}separated filenames may be specified in \sphinxstylestrong{KRB5\_CONFIG}; all files which are present will be read. Starting in release 1.14, directory names can also be specified in \sphinxstylestrong{KRB5\_CONFIG}; all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores will be read. \subsubsection{Structure} \label{\detokenize{admin/conf_files/krb5_conf:structure}} \sphinxAtStartPar The krb5.conf file is set up in the style of a Windows INI file. Lines beginning with ‘\#’ or ‘;’ (possibly after initial whitespace) are ignored as comments. Sections are headed by the section name, in square brackets. Each section may contain zero or more relations, of the form: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{foo} \PYG{o}{=} \PYG{n}{bar} \end{sphinxVerbatim} \sphinxAtStartPar or: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{fubar} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{foo} \PYG{o}{=} \PYG{n}{bar} \PYG{n}{baz} \PYG{o}{=} \PYG{n}{quux} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar The krb5.conf file can include other files using either of the following directives at the beginning of a line: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{include} \PYG{n}{FILENAME} \PYG{n}{includedir} \PYG{n}{DIRNAME} \end{sphinxVerbatim} \sphinxAtStartPar \sphinxstyleemphasis{FILENAME} or \sphinxstyleemphasis{DIRNAME} should be an absolute path. The named file or directory must exist and be readable. Including a directory includes all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores. Starting in release 1.15, files with names ending in “.conf†are also included, unless the name begins with “.â€. Included profile files are syntactically independent of their parents, so each included file must begin with a section header. Starting in release 1.17, files are read in alphanumeric order; in previous releases, they may be read in any order. \sphinxAtStartPar Placing a ‘*’ after the closing bracket of a section name indicates that the section is \sphinxstyleemphasis{final}, meaning that if the same section appears again later, it will be ignored. A subsection can be marked as final by placing a ‘*’ after either the tag name or the closing brace. A relation can be marked as final by placing a ‘*’ after the tag name. Prior to release 1.22, only sections and subsections can be marked as final, and the flag only causes values to be ignored if they appear in later files specified in \sphinxstylestrong{KRB5\_CONFIG}, not if they appear later within the same file or an included file. \sphinxAtStartPar The krb5.conf file can specify that configuration should be obtained from a loadable module, rather than the file itself, using the following directive at the beginning of a line before any section headers: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{module} \PYG{n}{MODULEPATH}\PYG{p}{:}\PYG{n}{RESIDUAL} \end{sphinxVerbatim} \sphinxAtStartPar \sphinxstyleemphasis{MODULEPATH} may be relative to the library path of the krb5 installation, or it may be an absolute path. \sphinxstyleemphasis{RESIDUAL} is provided to the module at initialization time. If krb5.conf uses a module directive, {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} should also use one if it exists. \subsubsection{Sections} \label{\detokenize{admin/conf_files/krb5_conf:sections}} \sphinxAtStartPar The krb5.conf file may contain the following sections: \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}} & \sphinxAtStartPar Settings used by the Kerberos V5 library \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} & \sphinxAtStartPar Realm\sphinxhyphen{}specific contact information and settings \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:domain-realm}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}domain\_realm{]}}}}} & \sphinxAtStartPar Maps server hostnames to Kerberos realms \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:capaths}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}capaths{]}}}}} & \sphinxAtStartPar Authentication paths for non\sphinxhyphen{}hierarchical cross\sphinxhyphen{}realm \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:appdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}appdefaults{]}}}}} & \sphinxAtStartPar Settings used by some Kerberos V5 applications \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:plugins}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}plugins{]}}}}} & \sphinxAtStartPar Controls plugin module registration \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxAtStartPar Additionally, krb5.conf may include any of the relations described in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}, but it is not a recommended practice. \paragraph{{[}libdefaults{]}} \label{\detokenize{admin/conf_files/krb5_conf:libdefaults}}\label{\detokenize{admin/conf_files/krb5_conf:id1}} \sphinxAtStartPar The libdefaults section may contain any of the following relations: \begin{description} \sphinxlineitem{\sphinxstylestrong{allow\_des3}} \sphinxAtStartPar Permit the KDC to issue tickets with des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 session keys. In future releases, this flag will allow des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 to be used at all. The default value for this tag is false. (Added in release 1.21.) \sphinxlineitem{\sphinxstylestrong{allow\_rc4}} \sphinxAtStartPar Permit the KDC to issue tickets with arcfour\sphinxhyphen{}hmac session keys. In future releases, this flag will allow arcfour\sphinxhyphen{}hmac to be used at all. The default value for this tag is false. (Added in release 1.21.) \sphinxlineitem{\sphinxstylestrong{allow\_weak\_crypto}} \sphinxAtStartPar If this flag is set to false, then weak encryption types (as noted in {\hyperref[\detokenize{admin/conf_files/kdc_conf:encryption-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Encryption types}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}) will be filtered out of the lists \sphinxstylestrong{default\_tgs\_enctypes}, \sphinxstylestrong{default\_tkt\_enctypes}, and \sphinxstylestrong{permitted\_enctypes}. The default value for this tag is false. \sphinxlineitem{\sphinxstylestrong{canonicalize}} \sphinxAtStartPar If this flag is set to true, initial ticket requests to the KDC will request canonicalization of the client principal name, and answers with different client principals than the requested principal will be accepted. The default value is false. \sphinxlineitem{\sphinxstylestrong{ccache\_type}} \sphinxAtStartPar This parameter determines the format of credential cache types created by \DUrole{xref,std,std-ref}{kinit(1)} or other programs. The default value is 4, which represents the most current format. Smaller values can be used for compatibility with very old implementations of Kerberos which interact with credential caches on the same host. \sphinxlineitem{\sphinxstylestrong{clockskew}} \sphinxAtStartPar Sets the maximum allowable amount of clockskew in seconds that the library will tolerate before assuming that a Kerberos message is invalid. The default value is 300 seconds, or five minutes. \sphinxAtStartPar The clockskew setting is also used when evaluating ticket start and expiration times. For example, tickets that have reached their expiration time can still be used (and renewed if they are renewable tickets) if they have been expired for a shorter duration than the \sphinxstylestrong{clockskew} setting. \sphinxlineitem{\sphinxstylestrong{default\_ccache\_name}} \sphinxAtStartPar This relation specifies the name of the default credential cache. The default is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFCCNAME}}}}. This relation is subject to parameter expansion (see below). New in release 1.11. \sphinxlineitem{\sphinxstylestrong{default\_client\_keytab\_name}} \sphinxAtStartPar This relation specifies the name of the default keytab for obtaining client credentials. The default is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFCKTNAME}}}}. This relation is subject to parameter expansion (see below). New in release 1.11. \sphinxlineitem{\sphinxstylestrong{default\_keytab\_name}} \sphinxAtStartPar This relation specifies the default keytab name to be used by application servers such as sshd. The default is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFKTNAME}}}}. This relation is subject to parameter expansion (see below). \sphinxlineitem{\sphinxstylestrong{default\_rcache\_name}} \sphinxAtStartPar This relation specifies the name of the default replay cache. The default is \sphinxcode{\sphinxupquote{dfl:}}. This relation is subject to parameter expansion (see below). New in release 1.18. \sphinxlineitem{\sphinxstylestrong{default\_realm}} \sphinxAtStartPar Identifies the default Kerberos realm for the client. Set its value to your Kerberos realm. If this value is not set, then a realm must be specified with every Kerberos principal when invoking programs such as \DUrole{xref,std,std-ref}{kinit(1)}. \sphinxlineitem{\sphinxstylestrong{default\_tgs\_enctypes}} \sphinxAtStartPar Identifies the supported list of session key encryption types that the client should request when making a TGS\sphinxhyphen{}REQ, in order of preference from highest to lowest. The list may be delimited with commas or whitespace. See {\hyperref[\detokenize{admin/conf_files/kdc_conf:encryption-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Encryption types}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} for a list of the accepted values for this tag. Starting in release 1.18, the default value is the value of \sphinxstylestrong{permitted\_enctypes}. For previous releases or if \sphinxstylestrong{permitted\_enctypes} is not set, the default value is \sphinxcode{\sphinxupquote{aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha384\sphinxhyphen{}192 aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha256\sphinxhyphen{}128 des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 arcfour\sphinxhyphen{}hmac\sphinxhyphen{}md5 camellia256\sphinxhyphen{}cts\sphinxhyphen{}cmac camellia128\sphinxhyphen{}cts\sphinxhyphen{}cmac}}. \sphinxAtStartPar Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. \sphinxlineitem{\sphinxstylestrong{default\_tkt\_enctypes}} \sphinxAtStartPar Identifies the supported list of session key encryption types that the client should request when making an AS\sphinxhyphen{}REQ, in order of preference from highest to lowest. The format is the same as for default\_tgs\_enctypes. Starting in release 1.18, the default value is the value of \sphinxstylestrong{permitted\_enctypes}. For previous releases or if \sphinxstylestrong{permitted\_enctypes} is not set, the default value is \sphinxcode{\sphinxupquote{aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha384\sphinxhyphen{}192 aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha256\sphinxhyphen{}128 des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 arcfour\sphinxhyphen{}hmac\sphinxhyphen{}md5 camellia256\sphinxhyphen{}cts\sphinxhyphen{}cmac camellia128\sphinxhyphen{}cts\sphinxhyphen{}cmac}}. \sphinxAtStartPar Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. \sphinxlineitem{\sphinxstylestrong{dns\_canonicalize\_hostname}} \sphinxAtStartPar Indicate whether name lookups will be used to canonicalize hostnames for use in service principal names. Setting this flag to false can improve security by reducing reliance on DNS, but means that short hostnames will not be canonicalized to fully\sphinxhyphen{}qualified hostnames. If this option is set to \sphinxcode{\sphinxupquote{fallback}} (new in release 1.18), DNS canonicalization will only be performed the server hostname is not found with the original name when requesting credentials. The default value is true. \sphinxlineitem{\sphinxstylestrong{dns\_lookup\_kdc}} \sphinxAtStartPar Indicate whether DNS SRV records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. (Note that the admin\_server entry must be in the krb5.conf realm information in order to contact kadmind, because the DNS implementation for kadmin is incomplete.) \sphinxAtStartPar Enabling this option does open up a type of denial\sphinxhyphen{}of\sphinxhyphen{}service attack, if someone spoofs the DNS records and redirects you to another server. However, it’s no worse than a denial of service, because that fake KDC will be unable to decode anything you send it (besides the initial ticket request, which has no encrypted data), and anything the fake KDC sends will not be trusted without verification using some secret that it won’t know. \sphinxlineitem{\sphinxstylestrong{dns\_lookup\_realm}} \sphinxAtStartPar Indicate whether DNS TXT records should be used to map hostnames to realm names for hostnames not listed in the {[}domain\_realm{]} section, and to determine the default realm if \sphinxstylestrong{default\_realm} is not set. The default value is false. \sphinxlineitem{\sphinxstylestrong{dns\_uri\_lookup}} \sphinxAtStartPar Indicate whether DNS URI records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. SRV records are used as a fallback if no URI records were found. The default value is true. New in release 1.15. \sphinxlineitem{\sphinxstylestrong{enforce\_ok\_as\_delegate}} \sphinxAtStartPar If this flag to true, GSSAPI credential delegation will be disabled when the \sphinxcode{\sphinxupquote{ok\sphinxhyphen{}as\sphinxhyphen{}delegate}} flag is not set in the service ticket. If this flag is false, the \sphinxcode{\sphinxupquote{ok\sphinxhyphen{}as\sphinxhyphen{}delegate}} ticket flag is only enforced when an application specifically requests enforcement. The default value is false. \sphinxlineitem{\sphinxstylestrong{err\_fmt}} \sphinxAtStartPar This relation allows for custom error message formatting. If a value is set, error messages will be formatted by substituting a normal error message for \%M and an error code for \%C in the value. \sphinxlineitem{\sphinxstylestrong{extra\_addresses}} \sphinxAtStartPar This allows a computer to use multiple local addresses, in order to allow Kerberos to work in a network that uses NATs while still using address\sphinxhyphen{}restricted tickets. The addresses should be in a comma\sphinxhyphen{}separated list. This option has no effect if \sphinxstylestrong{noaddresses} is true. \sphinxlineitem{\sphinxstylestrong{forwardable}} \sphinxAtStartPar If this flag is true, initial tickets will be forwardable by default, if allowed by the KDC. The default value is false. \sphinxlineitem{\sphinxstylestrong{ignore\_acceptor\_hostname}} \sphinxAtStartPar When accepting GSSAPI or krb5 security contexts for host\sphinxhyphen{}based service principals, ignore any hostname passed by the calling application, and allow clients to authenticate to any service principal in the keytab matching the service name and realm name (if given). This option can improve the administrative flexibility of server applications on multihomed hosts, but could compromise the security of virtual hosting environments. The default value is false. New in release 1.10. \sphinxlineitem{\sphinxstylestrong{k5login\_authoritative}} \sphinxAtStartPar If this flag is true, principals must be listed in a local user’s k5login file to be granted login access, if a \DUrole{xref,std,std-ref}{.k5login(5)} file exists. If this flag is false, a principal may still be granted login access through other mechanisms even if a k5login file exists but does not list the principal. The default value is true. \sphinxlineitem{\sphinxstylestrong{k5login\_directory}} \sphinxAtStartPar If set, the library will look for a local user’s k5login file within the named directory, with a filename corresponding to the local username. If not set, the library will look for k5login files in the user’s home directory, with the filename .k5login. For security reasons, .k5login files must be owned by the local user or by root. \sphinxlineitem{\sphinxstylestrong{kcm\_mach\_service}} \sphinxAtStartPar On macOS only, determines the name of the bootstrap service used to contact the KCM daemon for the KCM credential cache type. If the value is \sphinxcode{\sphinxupquote{\sphinxhyphen{}}}, Mach RPC will not be used to contact the KCM daemon. The default value is \sphinxcode{\sphinxupquote{org.h5l.kcm}}. \sphinxlineitem{\sphinxstylestrong{kcm\_socket}} \sphinxAtStartPar Determines the path to the Unix domain socket used to access the KCM daemon for the KCM credential cache type. If the value is \sphinxcode{\sphinxupquote{\sphinxhyphen{}}}, Unix domain sockets will not be used to contact the KCM daemon. The default value is \sphinxcode{\sphinxupquote{/var/run/.heim\_org.h5l.kcm\sphinxhyphen{}socket}}. \sphinxlineitem{\sphinxstylestrong{kdc\_default\_options}} \sphinxAtStartPar Default KDC options (Xored for multiple values) when requesting initial tickets. By default it is set to 0x00000010 (KDC\_OPT\_RENEWABLE\_OK). \sphinxlineitem{\sphinxstylestrong{kdc\_timesync}} \sphinxAtStartPar Accepted values for this relation are 1 or 0. If it is nonzero, client machines will compute the difference between their time and the time returned by the KDC in the timestamps in the tickets and use this value to correct for an inaccurate system clock when requesting service tickets or authenticating to services. This corrective factor is only used by the Kerberos library; it is not used to change the system clock. The default value is 1. \sphinxlineitem{\sphinxstylestrong{noaddresses}} \sphinxAtStartPar If this flag is true, requests for initial tickets will not be made with address restrictions set, allowing the tickets to be used across NATs. The default value is true. \sphinxlineitem{\sphinxstylestrong{permitted\_enctypes}} \sphinxAtStartPar Identifies the encryption types that servers will permit for session keys and for ticket and authenticator encryption, ordered by preference from highest to lowest. Starting in release 1.18, this tag also acts as the default value for \sphinxstylestrong{default\_tgs\_enctypes} and \sphinxstylestrong{default\_tkt\_enctypes}. The default value for this tag is \sphinxcode{\sphinxupquote{aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha384\sphinxhyphen{}192 aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha256\sphinxhyphen{}128 des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 arcfour\sphinxhyphen{}hmac\sphinxhyphen{}md5 camellia256\sphinxhyphen{}cts\sphinxhyphen{}cmac camellia128\sphinxhyphen{}cts\sphinxhyphen{}cmac}}. \sphinxlineitem{\sphinxstylestrong{plugin\_base\_dir}} \sphinxAtStartPar If set, determines the base directory where krb5 plugins are located. The default value is the \sphinxcode{\sphinxupquote{krb5/plugins}} subdirectory of the krb5 library directory. This relation is subject to parameter expansion (see below) in release 1.17 and later. \sphinxlineitem{\sphinxstylestrong{preferred\_preauth\_types}} \sphinxAtStartPar This allows you to set the preferred preauthentication types which the client will attempt before others which may be advertised by a KDC. The default value for this setting is “17, 16, 15, 14â€, which forces libkrb5 to attempt to use PKINIT if it is supported. \sphinxlineitem{\sphinxstylestrong{proxiable}} \sphinxAtStartPar If this flag is true, initial tickets will be proxiable by default, if allowed by the KDC. The default value is false. \sphinxlineitem{\sphinxstylestrong{qualify\_shortname}} \sphinxAtStartPar If this string is set, it determines the domain suffix for single\sphinxhyphen{}component hostnames when DNS canonicalization is not used (either because \sphinxstylestrong{dns\_canonicalize\_hostname} is false or because forward canonicalization failed). The default value is the first search domain of the system’s DNS configuration. To disable qualification of shortnames, set this relation to the empty string with \sphinxcode{\sphinxupquote{qualify\_shortname = ""}}. (New in release 1.18.) \sphinxlineitem{\sphinxstylestrong{rdns}} \sphinxAtStartPar If this flag is true, reverse name lookup will be used in addition to forward name lookup to canonicalizing hostnames for use in service principal names. If \sphinxstylestrong{dns\_canonicalize\_hostname} is set to false, this flag has no effect. The default value is true. \sphinxlineitem{\sphinxstylestrong{realm\_try\_domains}} \sphinxAtStartPar Indicate whether a host’s domain components should be used to determine the Kerberos realm of the host. The value of this variable is an integer: \sphinxhyphen{}1 means not to search, 0 means to try the host’s domain itself, 1 means to also try the domain’s immediate parent, and so forth. The library’s usual mechanism for locating Kerberos realms is used to determine whether a domain is a valid realm, which may involve consulting DNS if \sphinxstylestrong{dns\_lookup\_kdc} is set. The default is not to search domain components. \sphinxlineitem{\sphinxstylestrong{renew\_lifetime}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Sets the default renewable lifetime for initial ticket requests. The default value is 0. \sphinxlineitem{\sphinxstylestrong{request\_timeout}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Sets the maximum total time for KDC and password change requests. This timeout does not affect the intervals between requests, so setting a low timeout may result in fewer requests being attempted and/or some servers not being contacted. A value of 0 indicates no specific maximum, in which case requests will time out if no server responds after several tries. The default value is 0. (New in release 1.22.) \sphinxlineitem{\sphinxstylestrong{spake\_preauth\_groups}} \sphinxAtStartPar A whitespace or comma\sphinxhyphen{}separated list of words which specifies the groups allowed for SPAKE preauthentication. The possible values are: \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar edwards25519 & \sphinxAtStartPar Edwards25519 curve (\index{RFC@\spxentry{RFC}!RFC 7748@\spxentry{RFC 7748}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc7748.html}{\sphinxstylestrong{RFC 7748}}) \\ \sphinxhline \sphinxAtStartPar P\sphinxhyphen{}256 & \sphinxAtStartPar NIST P\sphinxhyphen{}256 curve (\index{RFC@\spxentry{RFC}!RFC 5480@\spxentry{RFC 5480}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc5480.html}{\sphinxstylestrong{RFC 5480}}) \\ \sphinxhline \sphinxAtStartPar P\sphinxhyphen{}384 & \sphinxAtStartPar NIST P\sphinxhyphen{}384 curve (\index{RFC@\spxentry{RFC}!RFC 5480@\spxentry{RFC 5480}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc5480.html}{\sphinxstylestrong{RFC 5480}}) \\ \sphinxhline \sphinxAtStartPar P\sphinxhyphen{}521 & \sphinxAtStartPar NIST P\sphinxhyphen{}521 curve (\index{RFC@\spxentry{RFC}!RFC 5480@\spxentry{RFC 5480}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc5480.html}{\sphinxstylestrong{RFC 5480}}) \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxAtStartPar The default value for the client is \sphinxcode{\sphinxupquote{edwards25519}}. The default value for the KDC is empty. New in release 1.17. \sphinxlineitem{\sphinxstylestrong{ticket\_lifetime}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Sets the default lifetime for initial ticket requests. The default value is 1 day. \sphinxlineitem{\sphinxstylestrong{udp\_preference\_limit}} \sphinxAtStartPar When sending a message to the KDC, the library will try using TCP before UDP if the size of the message is above \sphinxstylestrong{udp\_preference\_limit}. If the message is smaller than \sphinxstylestrong{udp\_preference\_limit}, then UDP will be tried before TCP. Regardless of the size, both protocols will be tried if the first attempt fails. \sphinxlineitem{\sphinxstylestrong{verify\_ap\_req\_nofail}} \sphinxAtStartPar If this flag is true, then an attempt to verify initial credentials will fail if the client machine does not have a keytab. The default value is false. \sphinxlineitem{\sphinxstylestrong{client\_aware\_channel\_bindings}} \sphinxAtStartPar If this flag is true, then all application protocol authentication requests will be flagged to indicate that the application supports channel bindings when operating over a secure channel. The default value is false. \end{description} \paragraph{{[}realms{]}} \label{\detokenize{admin/conf_files/krb5_conf:realms}}\label{\detokenize{admin/conf_files/krb5_conf:id2}} \sphinxAtStartPar Each tag in the {[}realms{]} section of the file is the name of a Kerberos realm. The value of the tag is a subsection with relations that define the properties of that particular realm. For each realm, the following tags may be specified in the realm’s subsection: \begin{description} \sphinxlineitem{\sphinxstylestrong{admin\_server}} \sphinxAtStartPar Identifies the host where the administration server is running. Typically, this is the primary Kerberos server. This tag must be given a value in order to communicate with the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} server for the realm. \sphinxlineitem{\sphinxstylestrong{auth\_to\_local}} \sphinxAtStartPar This tag allows you to set a general rule for mapping principal names to local user names. It will be used if there is not an explicit mapping for the principal name that is being translated. The possible values are: \begin{description} \sphinxlineitem{\sphinxstylestrong{RULE:}\sphinxstyleemphasis{exp}} \sphinxAtStartPar The local name will be formulated from \sphinxstyleemphasis{exp}. \sphinxAtStartPar The format for \sphinxstyleemphasis{exp} is \sphinxstylestrong{{[}}\sphinxstyleemphasis{n}\sphinxstylestrong{:}\sphinxstyleemphasis{string}\sphinxstylestrong{{]}(}\sphinxstyleemphasis{regexp}\sphinxstylestrong{)s/}\sphinxstyleemphasis{pattern}\sphinxstylestrong{/}\sphinxstyleemphasis{replacement}\sphinxstylestrong{/g}. The integer \sphinxstyleemphasis{n} indicates how many components the target principal should have. If this matches, then a string will be formed from \sphinxstyleemphasis{string}, substituting the realm of the principal for \sphinxcode{\sphinxupquote{\$0}} and the \sphinxstyleemphasis{n}’th component of the principal for \sphinxcode{\sphinxupquote{\$n}} (e.g., if the principal was \sphinxcode{\sphinxupquote{johndoe/admin}} then \sphinxcode{\sphinxupquote{{[}2:\$2\$1foo{]}}} would result in the string \sphinxcode{\sphinxupquote{adminjohndoefoo}}). If this string matches \sphinxstyleemphasis{regexp}, then the \sphinxcode{\sphinxupquote{s//{[}g{]}}} substitution command will be run over the string. The optional \sphinxstylestrong{g} will cause the substitution to be global over the \sphinxstyleemphasis{string}, instead of replacing only the first match in the \sphinxstyleemphasis{string}. \sphinxlineitem{\sphinxstylestrong{DEFAULT}} \sphinxAtStartPar The principal name will be used as the local user name. If the principal has more than one component or is not in the default realm, this rule is not applicable and the conversion will fail. \end{description} \sphinxAtStartPar For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] [realms] ATHENA.MIT.EDU = \PYGZob{} auth\PYGZus{}to\PYGZus{}local = RULE:[2:\PYGZdl{}1](johndoe)s/\PYGZca{}.*\PYGZdl{}/guest/ auth\PYGZus{}to\PYGZus{}local = RULE:[2:\PYGZdl{}1;\PYGZdl{}2](\PYGZca{}.*;admin\PYGZdl{})s/;admin\PYGZdl{}// auth\PYGZus{}to\PYGZus{}local = RULE:[2:\PYGZdl{}2](\PYGZca{}.*;root)s/\PYGZca{}.*\PYGZdl{}/root/ auth\PYGZus{}to\PYGZus{}local = DEFAULT \PYGZcb{} \end{sphinxVerbatim} \sphinxAtStartPar would result in any principal without \sphinxcode{\sphinxupquote{root}} or \sphinxcode{\sphinxupquote{admin}} as the second component to be translated with the default rule. A principal with a second component of \sphinxcode{\sphinxupquote{admin}} will become its first component. \sphinxcode{\sphinxupquote{root}} will be used as the local name for any principal with a second component of \sphinxcode{\sphinxupquote{root}}. The exception to these two rules are any principals \sphinxcode{\sphinxupquote{johndoe/*}}, which will always get the local name \sphinxcode{\sphinxupquote{guest}}. \sphinxlineitem{\sphinxstylestrong{auth\_to\_local\_names}} \sphinxAtStartPar This subsection allows you to set explicit mappings from principal names to local user names. The tag is the mapping name, and the value is the corresponding local user name. \sphinxlineitem{\sphinxstylestrong{default\_domain}} \sphinxAtStartPar This tag specifies the domain used to expand hostnames when translating Kerberos 4 service principals to Kerberos 5 principals (for example, when converting \sphinxcode{\sphinxupquote{rcmd.hostname}} to \sphinxcode{\sphinxupquote{host/hostname.domain}}). \sphinxlineitem{\sphinxstylestrong{disable\_encrypted\_timestamp}} \sphinxAtStartPar If this flag is true, the client will not perform encrypted timestamp preauthentication if requested by the KDC. Setting this flag can help to prevent dictionary attacks by active attackers, if the realm’s KDCs support SPAKE preauthentication or if initial authentication always uses another mechanism or always uses FAST. This flag persists across client referrals during initial authentication. This flag does not prevent the KDC from offering encrypted timestamp. New in release 1.17. \sphinxlineitem{\sphinxstylestrong{http\_anchors}} \sphinxAtStartPar When KDCs and kpasswd servers are accessed through HTTPS proxies, this tag can be used to specify the location of the CA certificate which should be trusted to issue the certificate for a proxy server. If left unspecified, the system\sphinxhyphen{}wide default set of CA certificates is used. \sphinxAtStartPar The syntax for values is similar to that of values for the \sphinxstylestrong{pkinit\_anchors} tag: \sphinxAtStartPar \sphinxstylestrong{FILE:} \sphinxstyleemphasis{filename} \sphinxAtStartPar \sphinxstyleemphasis{filename} is assumed to be the name of an OpenSSL\sphinxhyphen{}style ca\sphinxhyphen{}bundle file. \sphinxAtStartPar \sphinxstylestrong{DIR:} \sphinxstyleemphasis{dirname} \sphinxAtStartPar \sphinxstyleemphasis{dirname} is assumed to be an directory which contains CA certificates. All files in the directory will be examined; if they contain certificates (in PEM format), they will be used. \sphinxAtStartPar \sphinxstylestrong{ENV:} \sphinxstyleemphasis{envvar} \sphinxAtStartPar \sphinxstyleemphasis{envvar} specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, \sphinxcode{\sphinxupquote{ENV:X509\_PROXY\_CA}}, where environment variable \sphinxcode{\sphinxupquote{X509\_PROXY\_CA}} has been set to \sphinxcode{\sphinxupquote{FILE:/tmp/my\_proxy.pem}}. \sphinxlineitem{\sphinxstylestrong{kdc}} \sphinxAtStartPar The name or address of a host running a KDC for the realm, or a UNIX domain socket path of a locally running KDC. An optional port number, separated from the hostname by a colon, may be included. If the name or address contains colons (for example, if it is an IPv6 address), enclose it in square brackets to distinguish the colon from a port separator. For your computer to be able to communicate with the KDC for each realm, this tag must be given a value in each realm subsection in the configuration file, or there must be DNS SRV records specifying the KDCs. \sphinxlineitem{\sphinxstylestrong{kpasswd\_server}} \sphinxAtStartPar The location of the password change server for the realm, using the same syntax as \sphinxstylestrong{kdc}. If there is no such entry, DNS will be queried (unless forbidden by \sphinxstylestrong{dns\_lookup\_kdc}). Finally, port 464 on the \sphinxstylestrong{admin\_server} host will be tried. \sphinxlineitem{\sphinxstylestrong{master\_kdc}} \sphinxAtStartPar The name for \sphinxstylestrong{primary\_kdc} prior to release 1.19. Its value is used as a fallback if \sphinxstylestrong{primary\_kdc} is not specified. \sphinxlineitem{\sphinxstylestrong{primary\_kdc}} \sphinxAtStartPar Identifies the primary KDC(s). Currently, this tag is used in only one case: If an attempt to get credentials fails because of an invalid password, the client software will attempt to contact the primary KDC, in case the user’s password has just been changed, and the updated database has not been propagated to the replica servers yet. New in release 1.19. \sphinxlineitem{\sphinxstylestrong{sitename}} \sphinxAtStartPar Specifies the name of the host’s site for the purpose of DNS\sphinxhyphen{}based KDC discovery for this realm. New in release 1.22. \sphinxlineitem{\sphinxstylestrong{v4\_instance\_convert}} \sphinxAtStartPar This subsection allows the administrator to configure exceptions to the \sphinxstylestrong{default\_domain} mapping rule. It contains V4 instances (the tag name) which should be translated to some specific hostname (the tag value) as the second component in a Kerberos V5 principal name. \sphinxlineitem{\sphinxstylestrong{v4\_realm}} \sphinxAtStartPar This relation is used by the krb524 library routines when converting a V5 principal name to a V4 principal name. It is used when the V4 realm name and the V5 realm name are not the same, but still share the same principal names and passwords. The tag value is the Kerberos V4 realm name. \end{description} \paragraph{{[}domain\_realm{]}} \label{\detokenize{admin/conf_files/krb5_conf:domain-realm}}\label{\detokenize{admin/conf_files/krb5_conf:id3}} \sphinxAtStartPar The {[}domain\_realm{]} section provides a translation from hostnames to Kerberos realms. Each tag is a domain name, providing the mapping for that domain and all subdomains. If the tag begins with a period (\sphinxcode{\sphinxupquote{.}}) then it applies only to subdomains. The Kerberos realm may be identified either in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{realms}}} section or using DNS SRV records. Tag names should be in lower case. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{domain\PYGZus{}realm}\PYG{p}{]} \PYG{n}{crash}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{=} \PYG{n}{TEST}\PYG{o}{.}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{.}\PYG{n}{dev}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{=} \PYG{n}{TEST}\PYG{o}{.}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{=} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \end{sphinxVerbatim} \sphinxAtStartPar maps the host with the name \sphinxcode{\sphinxupquote{crash.mit.edu}} into the \sphinxcode{\sphinxupquote{TEST.ATHENA.MIT.EDU}} realm. The second entry maps all hosts under the domain \sphinxcode{\sphinxupquote{dev.mit.edu}} into the \sphinxcode{\sphinxupquote{TEST.ATHENA.MIT.EDU}} realm, but not the host with the name \sphinxcode{\sphinxupquote{dev.mit.edu}}. That host is matched by the third entry, which maps the host \sphinxcode{\sphinxupquote{mit.edu}} and all hosts under the domain \sphinxcode{\sphinxupquote{mit.edu}} that do not match a preceding rule into the realm \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}}. \sphinxAtStartPar If no translation entry applies to a hostname used for a service principal for a service ticket request, the library will try to get a referral to the appropriate realm from the client realm’s KDC. If that does not succeed, the host’s realm is considered to be the hostname’s domain portion converted to uppercase, unless the \sphinxstylestrong{realm\_try\_domains} setting in {[}libdefaults{]} causes a different parent domain to be used. \paragraph{{[}capaths{]}} \label{\detokenize{admin/conf_files/krb5_conf:capaths}}\label{\detokenize{admin/conf_files/krb5_conf:id4}} \sphinxAtStartPar In order to perform direct (non\sphinxhyphen{}hierarchical) cross\sphinxhyphen{}realm authentication, configuration is needed to determine the authentication paths between realms. \sphinxAtStartPar A client will use this section to find the authentication path between its realm and the realm of the server. The server will use this section to verify the authentication path used by the client, by checking the transited field of the received ticket. \sphinxAtStartPar There is a tag for each participating client realm, and each tag has subtags for each of the server realms. The value of the subtags is an intermediate realm which may participate in the cross\sphinxhyphen{}realm authentication. The subtags may be repeated if there is more then one intermediate realm. A value of “.†means that the two realms share keys directly, and no intermediate realms should be allowed to participate. \sphinxAtStartPar Only those entries which will be needed on the client or the server need to be present. A client needs a tag for its local realm with subtags for all the realms of servers it will need to authenticate to. A server needs a tag for each realm of the clients it will serve, with a subtag of the server realm. \sphinxAtStartPar For example, \sphinxcode{\sphinxupquote{ANL.GOV}}, \sphinxcode{\sphinxupquote{PNL.GOV}}, and \sphinxcode{\sphinxupquote{NERSC.GOV}} all wish to use the \sphinxcode{\sphinxupquote{ES.NET}} realm as an intermediate realm. ANL has a sub realm of \sphinxcode{\sphinxupquote{TEST.ANL.GOV}} which will authenticate with \sphinxcode{\sphinxupquote{NERSC.GOV}} but not \sphinxcode{\sphinxupquote{PNL.GOV}}. The {[}capaths{]} section for \sphinxcode{\sphinxupquote{ANL.GOV}} systems would look like this: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{capaths}\PYG{p}{]} \PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{TEST}\PYG{o}{.}\PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{o}{.} \PYG{n}{PNL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{n}{NERSC}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{o}{=} \PYG{o}{.} \PYG{p}{\PYGZcb{}} \PYG{n}{TEST}\PYG{o}{.}\PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{o}{.} \PYG{p}{\PYGZcb{}} \PYG{n}{PNL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{p}{\PYGZcb{}} \PYG{n}{NERSC}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{p}{\PYGZcb{}} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{o}{.} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar The {[}capaths{]} section of the configuration file used on \sphinxcode{\sphinxupquote{NERSC.GOV}} systems would look like this: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{capaths}\PYG{p}{]} \PYG{n}{NERSC}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{n}{TEST}\PYG{o}{.}\PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{n}{TEST}\PYG{o}{.}\PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{n}{PNL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{o}{=} \PYG{o}{.} \PYG{p}{\PYGZcb{}} \PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{NERSC}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{p}{\PYGZcb{}} \PYG{n}{PNL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{NERSC}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{p}{\PYGZcb{}} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{NERSC}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{o}{.} \PYG{p}{\PYGZcb{}} \PYG{n}{TEST}\PYG{o}{.}\PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{NERSC}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ANL}\PYG{o}{.}\PYG{n}{GOV} \PYG{n}{NERSC}\PYG{o}{.}\PYG{n}{GOV} \PYG{o}{=} \PYG{n}{ES}\PYG{o}{.}\PYG{n}{NET} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar When a subtag is used more than once within a tag, clients will use the order of values to determine the path. The order of values is not important to servers. \paragraph{{[}appdefaults{]}} \label{\detokenize{admin/conf_files/krb5_conf:appdefaults}}\label{\detokenize{admin/conf_files/krb5_conf:id5}} \sphinxAtStartPar Each tag in the {[}appdefaults{]} section names a Kerberos V5 application or an option that is used by some Kerberos V5 application{[}s{]}. The value of the tag defines the default behaviors for that application. \sphinxAtStartPar For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{appdefaults}\PYG{p}{]} \PYG{n}{telnet} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{option1} \PYG{o}{=} \PYG{n}{false} \PYG{p}{\PYGZcb{}} \PYG{p}{\PYGZcb{}} \PYG{n}{telnet} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{option1} \PYG{o}{=} \PYG{n}{true} \PYG{n}{option2} \PYG{o}{=} \PYG{n}{true} \PYG{p}{\PYGZcb{}} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{option2} \PYG{o}{=} \PYG{n}{false} \PYG{p}{\PYGZcb{}} \PYG{n}{option2} \PYG{o}{=} \PYG{n}{true} \end{sphinxVerbatim} \sphinxAtStartPar The above four ways of specifying the value of an option are shown in order of decreasing precedence. In this example, if telnet is running in the realm EXAMPLE.COM, it should, by default, have option1 and option2 set to true. However, a telnet program in the realm \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} should have \sphinxcode{\sphinxupquote{option1}} set to false and \sphinxcode{\sphinxupquote{option2}} set to true. Any other programs in ATHENA.MIT.EDU should have \sphinxcode{\sphinxupquote{option2}} set to false by default. Any programs running in other realms should have \sphinxcode{\sphinxupquote{option2}} set to true. \sphinxAtStartPar The list of specifiable options for each application may be found in that application’s man pages. The application defaults specified here are overridden by those specified in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{realms}}} section. \paragraph{{[}plugins{]}} \label{\detokenize{admin/conf_files/krb5_conf:plugins}}\label{\detokenize{admin/conf_files/krb5_conf:id6}}\begin{itemize} \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:pwqual}]{\sphinxcrossref{pwqual}}} interface \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:kadm5-hook}]{\sphinxcrossref{kadm5\_hook}}} interface \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:clpreauth}]{\sphinxcrossref{clpreauth}}} and {\hyperref[\detokenize{admin/conf_files/krb5_conf:kdcpreauth}]{\sphinxcrossref{kdcpreauth}}} interfaces \end{itemize} \sphinxAtStartPar Tags in the {[}plugins{]} section can be used to register dynamic plugin modules and to turn modules on and off. Not every krb5 pluggable interface uses the {[}plugins{]} section; the ones that do are documented here. \sphinxAtStartPar New in release 1.9. \sphinxAtStartPar Each pluggable interface corresponds to a subsection of {[}plugins{]}. All subsections support the same tags: \begin{description} \sphinxlineitem{\sphinxstylestrong{disable}} \sphinxAtStartPar This tag may have multiple values. If there are values for this tag, then the named modules will be disabled for the pluggable interface. \sphinxlineitem{\sphinxstylestrong{enable\_only}} \sphinxAtStartPar This tag may have multiple values. If there are values for this tag, then only the named modules will be enabled for the pluggable interface. \sphinxlineitem{\sphinxstylestrong{module}} \sphinxAtStartPar This tag may have multiple values. Each value is a string of the form \sphinxcode{\sphinxupquote{modulename:pathname}}, which causes the shared object located at \sphinxstyleemphasis{pathname} to be registered as a dynamic module named \sphinxstyleemphasis{modulename} for the pluggable interface. If \sphinxstyleemphasis{pathname} is not an absolute path, it will be treated as relative to the \sphinxstylestrong{plugin\_base\_dir} value from {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}}. \end{description} \sphinxAtStartPar For pluggable interfaces where module order matters, modules registered with a \sphinxstylestrong{module} tag normally come first, in the order they are registered, followed by built\sphinxhyphen{}in modules in the order they are documented below. If \sphinxstylestrong{enable\_only} tags are used, then the order of those tags overrides the normal module order. \sphinxAtStartPar The following subsections are currently supported within the {[}plugins{]} section: \subparagraph{ccselect interface} \label{\detokenize{admin/conf_files/krb5_conf:ccselect-interface}}\label{\detokenize{admin/conf_files/krb5_conf:ccselect}} \sphinxAtStartPar The ccselect subsection controls modules for credential cache selection within a cache collection. In addition to any registered dynamic modules, the following built\sphinxhyphen{}in modules exist (and may be disabled with the disable tag): \begin{description} \sphinxlineitem{\sphinxstylestrong{k5identity}} \sphinxAtStartPar Uses a .k5identity file in the user’s home directory to select a client principal \sphinxlineitem{\sphinxstylestrong{realm}} \sphinxAtStartPar Uses the service realm to guess an appropriate cache from the collection \sphinxlineitem{\sphinxstylestrong{hostname}} \sphinxAtStartPar If the service principal is host\sphinxhyphen{}based, uses the service hostname to guess an appropriate cache from the collection \end{description} \subparagraph{pwqual interface} \label{\detokenize{admin/conf_files/krb5_conf:pwqual-interface}}\label{\detokenize{admin/conf_files/krb5_conf:pwqual}} \sphinxAtStartPar The pwqual subsection controls modules for the password quality interface, which is used to reject weak passwords when passwords are changed. The following built\sphinxhyphen{}in modules exist for this interface: \begin{description} \sphinxlineitem{\sphinxstylestrong{dict}} \sphinxAtStartPar Checks against the realm dictionary file \sphinxlineitem{\sphinxstylestrong{empty}} \sphinxAtStartPar Rejects empty passwords \sphinxlineitem{\sphinxstylestrong{hesiod}} \sphinxAtStartPar Checks against user information stored in Hesiod (only if Kerberos was built with Hesiod support) \sphinxlineitem{\sphinxstylestrong{princ}} \sphinxAtStartPar Checks against components of the principal name \end{description} \subparagraph{kadm5\_hook interface} \label{\detokenize{admin/conf_files/krb5_conf:kadm5-hook-interface}}\label{\detokenize{admin/conf_files/krb5_conf:kadm5-hook}} \sphinxAtStartPar The kadm5\_hook interface provides plugins with information on principal creation, modification, password changes and deletion. This interface can be used to write a plugin to synchronize MIT Kerberos with another database such as Active Directory. No plugins are built in for this interface. \subparagraph{kadm5\_auth interface} \label{\detokenize{admin/conf_files/krb5_conf:kadm5-auth-interface}}\label{\detokenize{admin/conf_files/krb5_conf:kadm5-auth}} \sphinxAtStartPar The kadm5\_auth section (introduced in release 1.16) controls modules for the kadmin authorization interface, which determines whether a client principal is allowed to perform a kadmin operation. The following built\sphinxhyphen{}in modules exist for this interface: \begin{description} \sphinxlineitem{\sphinxstylestrong{acl}} \sphinxAtStartPar This module reads the {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}} file, and authorizes operations which are allowed according to the rules in the file. \sphinxlineitem{\sphinxstylestrong{self}} \sphinxAtStartPar This module authorizes self\sphinxhyphen{}service operations including password changes, creation of new random keys, fetching the client’s principal record or string attributes, and fetching the policy record associated with the client principal. \end{description} \subparagraph{clpreauth and kdcpreauth interfaces} \label{\detokenize{admin/conf_files/krb5_conf:clpreauth-and-kdcpreauth-interfaces}}\label{\detokenize{admin/conf_files/krb5_conf:kdcpreauth}}\label{\detokenize{admin/conf_files/krb5_conf:clpreauth}} \sphinxAtStartPar The clpreauth and kdcpreauth interfaces allow plugin modules to provide client and KDC preauthentication mechanisms. The following built\sphinxhyphen{}in modules exist for these interfaces: \begin{description} \sphinxlineitem{\sphinxstylestrong{pkinit}} \sphinxAtStartPar This module implements the PKINIT preauthentication mechanism. \sphinxlineitem{\sphinxstylestrong{encrypted\_challenge}} \sphinxAtStartPar This module implements the encrypted challenge FAST factor. \sphinxlineitem{\sphinxstylestrong{encrypted\_timestamp}} \sphinxAtStartPar This module implements the encrypted timestamp mechanism. \end{description} \subparagraph{hostrealm interface} \label{\detokenize{admin/conf_files/krb5_conf:hostrealm-interface}}\label{\detokenize{admin/conf_files/krb5_conf:hostrealm}} \sphinxAtStartPar The hostrealm section (introduced in release 1.12) controls modules for the host\sphinxhyphen{}to\sphinxhyphen{}realm interface, which affects the local mapping of hostnames to realm names and the choice of default realm. The following built\sphinxhyphen{}in modules exist for this interface: \begin{description} \sphinxlineitem{\sphinxstylestrong{profile}} \sphinxAtStartPar This module consults the {[}domain\_realm{]} section of the profile for authoritative host\sphinxhyphen{}to\sphinxhyphen{}realm mappings, and the \sphinxstylestrong{default\_realm} variable for the default realm. \sphinxlineitem{\sphinxstylestrong{dns}} \sphinxAtStartPar This module looks for DNS records for fallback host\sphinxhyphen{}to\sphinxhyphen{}realm mappings and the default realm. It only operates if the \sphinxstylestrong{dns\_lookup\_realm} variable is set to true. \sphinxlineitem{\sphinxstylestrong{domain}} \sphinxAtStartPar This module applies heuristics for fallback host\sphinxhyphen{}to\sphinxhyphen{}realm mappings. It implements the \sphinxstylestrong{realm\_try\_domains} variable, and uses the uppercased parent domain of the hostname if that does not produce a result. \end{description} \subparagraph{localauth interface} \label{\detokenize{admin/conf_files/krb5_conf:localauth-interface}}\label{\detokenize{admin/conf_files/krb5_conf:localauth}} \sphinxAtStartPar The localauth section (introduced in release 1.12) controls modules for the local authorization interface, which affects the relationship between Kerberos principals and local system accounts. The following built\sphinxhyphen{}in modules exist for this interface: \begin{description} \sphinxlineitem{\sphinxstylestrong{default}} \sphinxAtStartPar This module implements the \sphinxstylestrong{DEFAULT} type for \sphinxstylestrong{auth\_to\_local} values. \sphinxlineitem{\sphinxstylestrong{rule}} \sphinxAtStartPar This module implements the \sphinxstylestrong{RULE} type for \sphinxstylestrong{auth\_to\_local} values. \sphinxlineitem{\sphinxstylestrong{names}} \sphinxAtStartPar This module looks for an \sphinxstylestrong{auth\_to\_local\_names} mapping for the principal name. \sphinxlineitem{\sphinxstylestrong{auth\_to\_local}} \sphinxAtStartPar This module processes \sphinxstylestrong{auth\_to\_local} values in the default realm’s section, and applies the default method if no \sphinxstylestrong{auth\_to\_local} values exist. \sphinxlineitem{\sphinxstylestrong{k5login}} \sphinxAtStartPar This module authorizes a principal to a local account according to the account’s \DUrole{xref,std,std-ref}{.k5login(5)} file. \sphinxlineitem{\sphinxstylestrong{an2ln}} \sphinxAtStartPar This module authorizes a principal to a local account if the principal name maps to the local account name. \end{description} \subparagraph{certauth interface} \label{\detokenize{admin/conf_files/krb5_conf:certauth-interface}}\label{\detokenize{admin/conf_files/krb5_conf:certauth}} \sphinxAtStartPar The certauth section (introduced in release 1.16) controls modules for the certificate authorization interface, which determines whether a certificate is allowed to preauthenticate a user via PKINIT. The following built\sphinxhyphen{}in modules exist for this interface: \begin{description} \sphinxlineitem{\sphinxstylestrong{pkinit\_san}} \sphinxAtStartPar This module authorizes the certificate if it contains a PKINIT Subject Alternative Name for the requested client principal, or a Microsoft UPN SAN matching the principal if \sphinxstylestrong{pkinit\_allow\_upn} is set to true for the realm. \sphinxlineitem{\sphinxstylestrong{pkinit\_eku}} \sphinxAtStartPar This module rejects the certificate if it does not contain an Extended Key Usage attribute consistent with the \sphinxstylestrong{pkinit\_eku\_checking} value for the realm. \sphinxlineitem{\sphinxstylestrong{dbmatch}} \sphinxAtStartPar This module authorizes or rejects the certificate according to whether it matches the \sphinxstylestrong{pkinit\_cert\_match} string attribute on the client principal, if that attribute is present. \end{description} \subsubsection{PKINIT options} \label{\detokenize{admin/conf_files/krb5_conf:pkinit-options}} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The following are PKINIT\sphinxhyphen{}specific options. These values may be specified in {[}libdefaults{]} as global defaults, or within a realm\sphinxhyphen{}specific subsection of {[}libdefaults{]}, or may be specified as realm\sphinxhyphen{}specific values in the {[}realms{]} section. A realm\sphinxhyphen{}specific value overrides, not adds to, a generic {[}libdefaults{]} specification. The search order is: \end{sphinxadmonition} \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar realm\sphinxhyphen{}specific subsection of {[}libdefaults{]}: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{libdefaults}\PYG{p}{]} \PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{pkinit\PYGZus{}anchors} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com}\PYG{o}{.}\PYG{n}{crt} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \item {} \sphinxAtStartPar realm\sphinxhyphen{}specific value in the {[}realms{]} section: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{OTHERREALM}\PYG{o}{.}\PYG{n}{ORG} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{pkinit\PYGZus{}anchors} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{otherrealm}\PYG{o}{.}\PYG{n}{org}\PYG{o}{.}\PYG{n}{crt} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \item {} \sphinxAtStartPar generic value in the {[}libdefaults{]} section: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{libdefaults}\PYG{p}{]} \PYG{n}{pkinit\PYGZus{}anchors} \PYG{o}{=} \PYG{n}{DIR}\PYG{p}{:}\PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{generic\PYGZus{}trusted\PYGZus{}cas}\PYG{o}{/} \end{sphinxVerbatim} \end{enumerate} \paragraph{Specifying PKINIT identity information} \label{\detokenize{admin/conf_files/krb5_conf:specifying-pkinit-identity-information}}\label{\detokenize{admin/conf_files/krb5_conf:pkinit-identity}} \sphinxAtStartPar The syntax for specifying Public Key identity, trust, and revocation information for PKINIT is as follows: \begin{description} \sphinxlineitem{\sphinxstylestrong{FILE:}\sphinxstyleemphasis{filename}{[}\sphinxstylestrong{,}\sphinxstyleemphasis{keyfilename}{]}} \sphinxAtStartPar This option has context\sphinxhyphen{}specific behavior. \sphinxAtStartPar In \sphinxstylestrong{pkinit\_identity} or \sphinxstylestrong{pkinit\_identities}, \sphinxstyleemphasis{filename} specifies the name of a PEM\sphinxhyphen{}format file containing the user’s certificate. If \sphinxstyleemphasis{keyfilename} is not specified, the user’s private key is expected to be in \sphinxstyleemphasis{filename} as well. Otherwise, \sphinxstyleemphasis{keyfilename} is the name of the file containing the private key. \sphinxAtStartPar In \sphinxstylestrong{pkinit\_anchors} or \sphinxstylestrong{pkinit\_pool}, \sphinxstyleemphasis{filename} is assumed to be the name of an OpenSSL\sphinxhyphen{}style ca\sphinxhyphen{}bundle file. \sphinxlineitem{\sphinxstylestrong{DIR:}\sphinxstyleemphasis{dirname}} \sphinxAtStartPar This option has context\sphinxhyphen{}specific behavior. \sphinxAtStartPar In \sphinxstylestrong{pkinit\_identity} or \sphinxstylestrong{pkinit\_identities}, \sphinxstyleemphasis{dirname} specifies a directory with files named \sphinxcode{\sphinxupquote{*.crt}} and \sphinxcode{\sphinxupquote{*.key}} where the first part of the file name is the same for matching pairs of certificate and private key files. When a file with a name ending with \sphinxcode{\sphinxupquote{.crt}} is found, a matching file ending with \sphinxcode{\sphinxupquote{.key}} is assumed to contain the private key. If no such file is found, then the certificate in the \sphinxcode{\sphinxupquote{.crt}} is not used. \sphinxAtStartPar In \sphinxstylestrong{pkinit\_anchors} or \sphinxstylestrong{pkinit\_pool}, \sphinxstyleemphasis{dirname} is assumed to be an OpenSSL\sphinxhyphen{}style hashed CA directory where each CA cert is stored in a file named \sphinxcode{\sphinxupquote{hash\sphinxhyphen{}of\sphinxhyphen{}ca\sphinxhyphen{}cert.\#}}. This infrastructure is encouraged, but all files in the directory will be examined and if they contain certificates (in PEM format), they will be used. \sphinxAtStartPar In \sphinxstylestrong{pkinit\_revoke}, \sphinxstyleemphasis{dirname} is assumed to be an OpenSSL\sphinxhyphen{}style hashed CA directory where each revocation list is stored in a file named \sphinxcode{\sphinxupquote{hash\sphinxhyphen{}of\sphinxhyphen{}ca\sphinxhyphen{}cert.r\#}}. This infrastructure is encouraged, but all files in the directory will be examined and if they contain a revocation list (in PEM format), they will be used. \sphinxlineitem{\sphinxstylestrong{PKCS12:}\sphinxstyleemphasis{filename}} \sphinxAtStartPar \sphinxstyleemphasis{filename} is the name of a PKCS \#12 format file, containing the user’s certificate and private key. \sphinxlineitem{\sphinxstylestrong{PKCS11:}{[}\sphinxstylestrong{module\_name=}{]}\sphinxstyleemphasis{modname}{[}\sphinxstylestrong{:slotid=}\sphinxstyleemphasis{slot\sphinxhyphen{}id}{]}{[}\sphinxstylestrong{:token=}\sphinxstyleemphasis{token\sphinxhyphen{}label}{]}{[}\sphinxstylestrong{:certid=}\sphinxstyleemphasis{cert\sphinxhyphen{}id}{]}{[}\sphinxstylestrong{:certlabel=}\sphinxstyleemphasis{cert\sphinxhyphen{}label}{]}} \sphinxAtStartPar All keyword/values are optional. \sphinxstyleemphasis{modname} specifies the location of a library implementing PKCS \#11. If a value is encountered with no keyword, it is assumed to be the \sphinxstyleemphasis{modname}. If no module\sphinxhyphen{}name is specified, the default is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{PKCS11\_MODNAME}}}}. \sphinxcode{\sphinxupquote{slotid=}} and/or \sphinxcode{\sphinxupquote{token=}} may be specified to force the use of a particular smard card reader or token if there is more than one available. \sphinxcode{\sphinxupquote{certid=}} and/or \sphinxcode{\sphinxupquote{certlabel=}} may be specified to force the selection of a particular certificate on the device. Specifier values must not contain colon characters, as colons are always treated as separators. See the \sphinxstylestrong{pkinit\_cert\_match} configuration option for more ways to select a particular certificate to use for PKINIT. \sphinxlineitem{\sphinxstylestrong{ENV:}\sphinxstyleemphasis{envvar}} \sphinxAtStartPar \sphinxstyleemphasis{envvar} specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, \sphinxcode{\sphinxupquote{ENV:X509\_PROXY}}, where environment variable \sphinxcode{\sphinxupquote{X509\_PROXY}} has been set to \sphinxcode{\sphinxupquote{FILE:/tmp/my\_proxy.pem}}. \end{description} \paragraph{PKINIT krb5.conf options} \label{\detokenize{admin/conf_files/krb5_conf:pkinit-krb5-conf-options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{pkinit\_anchors}} \sphinxAtStartPar Specifies the location of trusted anchor (root) certificates which the client trusts to sign KDC certificates. This option may be specified multiple times. These values from the config file are not used if the user specifies X509\_anchors on the command line. \sphinxlineitem{\sphinxstylestrong{pkinit\_cert\_match}} \sphinxAtStartPar Specifies matching rules that the client certificate must match before it is used to attempt PKINIT authentication. If a user has multiple certificates available (on a smart card, or via other media), there must be exactly one certificate chosen before attempting PKINIT authentication. This option may be specified multiple times. All the available certificates are checked against each rule in order until there is a match of exactly one certificate. \sphinxAtStartPar The Subject and Issuer comparison strings are the \index{RFC@\spxentry{RFC}!RFC 2253@\spxentry{RFC 2253}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc2253.html}{\sphinxstylestrong{RFC 2253}} string representations from the certificate Subject DN and Issuer DN values. \sphinxAtStartPar The syntax of the matching rules is: \begin{quote} \sphinxAtStartPar {[}\sphinxstyleemphasis{relation\sphinxhyphen{}operator}{]}\sphinxstyleemphasis{component\sphinxhyphen{}rule} … \end{quote} \sphinxAtStartPar where: \begin{description} \sphinxlineitem{\sphinxstyleemphasis{relation\sphinxhyphen{}operator}} \sphinxAtStartPar can be either \sphinxcode{\sphinxupquote{\&\&}}, meaning all component rules must match, or \sphinxcode{\sphinxupquote{||}}, meaning only one component rule must match. The default is \sphinxcode{\sphinxupquote{\&\&}}. \sphinxlineitem{\sphinxstyleemphasis{component\sphinxhyphen{}rule}} \sphinxAtStartPar can be one of the following. Note that there is no punctuation or whitespace between component rules. \begin{quote} \begin{DUlineblock}{0em} \item[] \sphinxstylestrong{\textless{}SUBJECT\textgreater{}}\sphinxstyleemphasis{regular\sphinxhyphen{}expression} \item[] \sphinxstylestrong{\textless{}ISSUER\textgreater{}}\sphinxstyleemphasis{regular\sphinxhyphen{}expression} \item[] \sphinxstylestrong{\textless{}SAN\textgreater{}}\sphinxstyleemphasis{regular\sphinxhyphen{}expression} \item[] \sphinxstylestrong{\textless{}EKU\textgreater{}}\sphinxstyleemphasis{extended\sphinxhyphen{}key\sphinxhyphen{}usage\sphinxhyphen{}list} \item[] \sphinxstylestrong{\textless{}KU\textgreater{}}\sphinxstyleemphasis{key\sphinxhyphen{}usage\sphinxhyphen{}list} \end{DUlineblock} \end{quote} \sphinxAtStartPar \sphinxstyleemphasis{extended\sphinxhyphen{}key\sphinxhyphen{}usage\sphinxhyphen{}list} is a comma\sphinxhyphen{}separated list of required Extended Key Usage values. All values in the list must be present in the certificate. Extended Key Usage values can be: \begin{itemize} \item {} \sphinxAtStartPar pkinit \item {} \sphinxAtStartPar msScLogin \item {} \sphinxAtStartPar clientAuth \item {} \sphinxAtStartPar emailProtection \end{itemize} \sphinxAtStartPar \sphinxstyleemphasis{key\sphinxhyphen{}usage\sphinxhyphen{}list} is a comma\sphinxhyphen{}separated list of required Key Usage values. All values in the list must be present in the certificate. Key Usage values can be: \begin{itemize} \item {} \sphinxAtStartPar digitalSignature \item {} \sphinxAtStartPar keyEncipherment \end{itemize} \end{description} \sphinxAtStartPar Examples: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{pkinit\PYGZus{}cert\PYGZus{}match} \PYG{o}{=} \PYG{o}{|}\PYG{o}{|}\PYG{o}{\PYGZlt{}}\PYG{n}{SUBJECT}\PYG{o}{\PYGZgt{}}\PYG{o}{.}\PYG{o}{*}\PYG{n}{DoE}\PYG{o}{.}\PYG{o}{*}\PYG{o}{\PYGZlt{}}\PYG{n}{SAN}\PYG{o}{\PYGZgt{}}\PYG{o}{.}\PYG{o}{*}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{pkinit\PYGZus{}cert\PYGZus{}match} \PYG{o}{=} \PYG{o}{\PYGZam{}}\PYG{o}{\PYGZam{}}\PYG{o}{\PYGZlt{}}\PYG{n}{EKU}\PYG{o}{\PYGZgt{}}\PYG{n}{msScLogin}\PYG{p}{,}\PYG{n}{clientAuth}\PYG{o}{\PYGZlt{}}\PYG{n}{ISSUER}\PYG{o}{\PYGZgt{}}\PYG{o}{.}\PYG{o}{*}\PYG{n}{DoE}\PYG{o}{.}\PYG{o}{*} \PYG{n}{pkinit\PYGZus{}cert\PYGZus{}match} \PYG{o}{=} \PYG{o}{\PYGZlt{}}\PYG{n}{EKU}\PYG{o}{\PYGZgt{}}\PYG{n}{msScLogin}\PYG{p}{,}\PYG{n}{clientAuth}\PYG{o}{\PYGZlt{}}\PYG{n}{KU}\PYG{o}{\PYGZgt{}}\PYG{n}{digitalSignature} \end{sphinxVerbatim} \sphinxlineitem{\sphinxstylestrong{pkinit\_eku\_checking}} \sphinxAtStartPar This option specifies what Extended Key Usage value the KDC certificate presented to the client must contain. (Note that if the KDC certificate has the pkinit SubjectAlternativeName encoded as the Kerberos TGS name, EKU checking is not necessary since the issuing CA has certified this as a KDC certificate.) The values recognized in the krb5.conf file are: \begin{description} \sphinxlineitem{\sphinxstylestrong{kpKDC}} \sphinxAtStartPar This is the default value and specifies that the KDC must have the id\sphinxhyphen{}pkinit\sphinxhyphen{}KPKdc EKU as defined in \index{RFC@\spxentry{RFC}!RFC 4556@\spxentry{RFC 4556}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc4556.html}{\sphinxstylestrong{RFC 4556}}. \sphinxlineitem{\sphinxstylestrong{kpServerAuth}} \sphinxAtStartPar If \sphinxstylestrong{kpServerAuth} is specified, a KDC certificate with the id\sphinxhyphen{}kp\sphinxhyphen{}serverAuth EKU will be accepted. This key usage value is used in most commercially issued server certificates. \sphinxlineitem{\sphinxstylestrong{none}} \sphinxAtStartPar If \sphinxstylestrong{none} is specified, then the KDC certificate will not be checked to verify it has an acceptable EKU. The use of this option is not recommended. \end{description} \sphinxlineitem{\sphinxstylestrong{pkinit\_dh\_min\_bits}} \sphinxAtStartPar Specifies the group of the Diffie\sphinxhyphen{}Hellman key the client will attempt to use. The acceptable values are 1024, 2048, P\sphinxhyphen{}256, 4096, P\sphinxhyphen{}384, and P\sphinxhyphen{}521. The default is 2048. (P\sphinxhyphen{}256, P\sphinxhyphen{}384, and P\sphinxhyphen{}521 are new in release 1.22.) \sphinxlineitem{\sphinxstylestrong{pkinit\_identities}} \sphinxAtStartPar Specifies the location(s) to be used to find the user’s X.509 identity information. If this option is specified multiple times, each value is attempted in order until certificates are found. Note that these values are not used if the user specifies \sphinxstylestrong{X509\_user\_identity} on the command line. \sphinxlineitem{\sphinxstylestrong{pkinit\_kdc\_hostname}} \sphinxAtStartPar The presence of this option indicates that the client is willing to accept a KDC certificate with a dNSName SAN (Subject Alternative Name) rather than requiring the id\sphinxhyphen{}pkinit\sphinxhyphen{}san as defined in \index{RFC@\spxentry{RFC}!RFC 4556@\spxentry{RFC 4556}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc4556.html}{\sphinxstylestrong{RFC 4556}}. This option may be specified multiple times. Its value should contain the acceptable hostname for the KDC (as contained in its certificate). \sphinxlineitem{\sphinxstylestrong{pkinit\_pool}} \sphinxAtStartPar Specifies the location of intermediate certificates which may be used by the client to complete the trust chain between a KDC certificate and a trusted anchor. This option may be specified multiple times. \sphinxlineitem{\sphinxstylestrong{pkinit\_require\_crl\_checking}} \sphinxAtStartPar The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and \sphinxstylestrong{pkinit\_require\_crl\_checking} is false, then verification succeeds. \sphinxAtStartPar However, if \sphinxstylestrong{pkinit\_require\_crl\_checking} is true and there is no CRL information available for the issuing CA, then verification fails. \sphinxAtStartPar \sphinxstylestrong{pkinit\_require\_crl\_checking} should be set to true if the policy is such that up\sphinxhyphen{}to\sphinxhyphen{}date CRLs must be present for every CA. \sphinxlineitem{\sphinxstylestrong{pkinit\_revoke}} \sphinxAtStartPar Specifies the location of Certificate Revocation List (CRL) information to be used by the client when verifying the validity of the KDC certificate presented. This option may be specified multiple times. \end{description} \subsubsection{Parameter expansion} \label{\detokenize{admin/conf_files/krb5_conf:parameter-expansion}}\label{\detokenize{admin/conf_files/krb5_conf:id7}} \sphinxAtStartPar Starting with release 1.11, several variables, such as \sphinxstylestrong{default\_keytab\_name}, allow parameters to be expanded. Valid parameters are: \begin{quote} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar \%\{TEMP\} & \sphinxAtStartPar Temporary directory \\ \sphinxhline \sphinxAtStartPar \%\{uid\} & \sphinxAtStartPar Unix real UID or Windows SID \\ \sphinxhline \sphinxAtStartPar \%\{euid\} & \sphinxAtStartPar Unix effective user ID or Windows SID \\ \sphinxhline \sphinxAtStartPar \%\{USERID\} & \sphinxAtStartPar Same as \%\{uid\} \\ \sphinxhline \sphinxAtStartPar \%\{null\} & \sphinxAtStartPar Empty string \\ \sphinxhline \sphinxAtStartPar \%\{LIBDIR\} & \sphinxAtStartPar Installation library directory \\ \sphinxhline \sphinxAtStartPar \%\{BINDIR\} & \sphinxAtStartPar Installation binary directory \\ \sphinxhline \sphinxAtStartPar \%\{SBINDIR\} & \sphinxAtStartPar Installation admin binary directory \\ \sphinxhline \sphinxAtStartPar \%\{username\} & \sphinxAtStartPar (Unix) Username of effective user ID \\ \sphinxhline \sphinxAtStartPar \%\{APPDATA\} & \sphinxAtStartPar (Windows) Roaming application data for current user \\ \sphinxhline \sphinxAtStartPar \%\{COMMON\_APPDATA\} & \sphinxAtStartPar (Windows) Application data for all users \\ \sphinxhline \sphinxAtStartPar \%\{LOCAL\_APPDATA\} & \sphinxAtStartPar (Windows) Local application data for current user \\ \sphinxhline \sphinxAtStartPar \%\{SYSTEM\} & \sphinxAtStartPar (Windows) Windows system folder \\ \sphinxhline \sphinxAtStartPar \%\{WINDOWS\} & \sphinxAtStartPar (Windows) Windows folder \\ \sphinxhline \sphinxAtStartPar \%\{USERCONFIG\} & \sphinxAtStartPar (Windows) Per\sphinxhyphen{}user MIT krb5 config file directory \\ \sphinxhline \sphinxAtStartPar \%\{COMMONCONFIG\} & \sphinxAtStartPar (Windows) Common MIT krb5 config file directory \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \end{quote} \subsubsection{Sample krb5.conf file} \label{\detokenize{admin/conf_files/krb5_conf:sample-krb5-conf-file}} \sphinxAtStartPar Here is an example of a generic krb5.conf file: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{libdefaults}\PYG{p}{]} \PYG{n}{default\PYGZus{}realm} \PYG{o}{=} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{dns\PYGZus{}lookup\PYGZus{}kdc} \PYG{o}{=} \PYG{n}{true} \PYG{n}{dns\PYGZus{}lookup\PYGZus{}realm} \PYG{o}{=} \PYG{n}{false} \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{2.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{admin\PYGZus{}server} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{primary\PYGZus{}kdc} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{p}{\PYGZcb{}} \PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{n}{admin\PYGZus{}server} \PYG{o}{=} \PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{p}{\PYGZcb{}} \PYG{p}{[}\PYG{n}{domain\PYGZus{}realm}\PYG{p}{]} \PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{=} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{p}{[}\PYG{n}{capaths}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{=} \PYG{o}{.} \PYG{p}{\PYGZcb{}} \PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{o}{.} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \subsubsection{FILES} \label{\detokenize{admin/conf_files/krb5_conf:files}} \sphinxAtStartPar \sphinxcode{\sphinxupquote{/etc/krb5.conf}} \subsubsection{SEE ALSO} \label{\detokenize{admin/conf_files/krb5_conf:see-also}} \sphinxAtStartPar syslog(3) \sphinxstepscope \subsection{kdc.conf} \label{\detokenize{admin/conf_files/kdc_conf:kdc-conf}}\label{\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}}\label{\detokenize{admin/conf_files/kdc_conf::doc}} \sphinxAtStartPar The kdc.conf file supplements {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} for programs which are typically only used on a KDC, such as the {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} and {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemons and the {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} program. Relations documented here may also be specified in krb5.conf; for the KDC programs mentioned, krb5.conf and kdc.conf will be merged into a single configuration profile. \sphinxAtStartPar Normally, the kdc.conf file is found in the KDC state directory, {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}. You can override the default location by setting the environment variable \sphinxstylestrong{KRB5\_KDC\_PROFILE}. \sphinxAtStartPar Please note that you need to restart the KDC daemon for any configuration changes to take effect. \subsubsection{Structure} \label{\detokenize{admin/conf_files/kdc_conf:structure}} \sphinxAtStartPar The kdc.conf file is set up in the same format as the {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} file. \subsubsection{Sections} \label{\detokenize{admin/conf_files/kdc_conf:sections}} \sphinxAtStartPar The kdc.conf file may contain the following sections: \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdcdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}kdcdefaults{]}}}}} & \sphinxAtStartPar Default values for KDC behavior \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} & \sphinxAtStartPar Realm\sphinxhyphen{}specific database configuration and settings \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbdefaults{]}}}}} & \sphinxAtStartPar Default database settings \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbmodules}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbmodules{]}}}}} & \sphinxAtStartPar Per\sphinxhyphen{}database settings \\ \sphinxhline \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/kdc_conf:logging}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}logging{]}}}}} & \sphinxAtStartPar Controls how Kerberos daemons perform logging \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \paragraph{{[}kdcdefaults{]}} \label{\detokenize{admin/conf_files/kdc_conf:kdcdefaults}}\label{\detokenize{admin/conf_files/kdc_conf:id1}} \sphinxAtStartPar Some relations in the {[}kdcdefaults{]} section specify default values for realm variables, to be used if the {[}realms{]} subsection does not contain a relation for the tag. See the {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} section for the definitions of these relations. \begin{itemize} \item {} \sphinxAtStartPar \sphinxstylestrong{host\_based\_services} \item {} \sphinxAtStartPar \sphinxstylestrong{kdc\_listen} \item {} \sphinxAtStartPar \sphinxstylestrong{kdc\_ports} \item {} \sphinxAtStartPar \sphinxstylestrong{kdc\_tcp\_listen} \item {} \sphinxAtStartPar \sphinxstylestrong{kdc\_tcp\_ports} \item {} \sphinxAtStartPar \sphinxstylestrong{no\_host\_referral} \item {} \sphinxAtStartPar \sphinxstylestrong{restrict\_anonymous\_to\_tgt} \end{itemize} \sphinxAtStartPar The following {[}kdcdefaults{]} variables have no per\sphinxhyphen{}realm equivalent: \begin{description} \sphinxlineitem{\sphinxstylestrong{kdc\_max\_dgram\_reply\_size}} \sphinxAtStartPar Specifies the maximum packet size that can be sent over UDP. The default value is 4096 bytes. \sphinxlineitem{\sphinxstylestrong{kdc\_tcp\_listen\_backlog}} \sphinxAtStartPar (Integer.) Set the size of the listen queue length for the KDC daemon. The value may be limited by OS settings. The default value is 5. \sphinxlineitem{\sphinxstylestrong{spake\_preauth\_kdc\_challenge}} \sphinxAtStartPar (String.) Specifies the group for a SPAKE optimistic challenge. See the \sphinxstylestrong{spake\_preauth\_groups} variable in {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}} for possible values. The default is not to issue an optimistic challenge. (New in release 1.17.) \end{description} \paragraph{{[}realms{]}} \label{\detokenize{admin/conf_files/kdc_conf:realms}}\label{\detokenize{admin/conf_files/kdc_conf:kdc-realms}} \sphinxAtStartPar Each tag in the {[}realms{]} section is the name of a Kerberos realm. The value of the tag is a subsection where the relations define KDC parameters for that particular realm. The following example shows how to define one parameter for the ATHENA.MIT.EDU realm: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{max\PYGZus{}renewable\PYGZus{}life} \PYG{o}{=} \PYG{l+m+mi}{7}\PYG{n}{d} \PYG{l+m+mi}{0}\PYG{n}{h} \PYG{l+m+mi}{0}\PYG{n}{m} \PYG{l+m+mi}{0}\PYG{n}{s} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar The following tags may be specified in a {[}realms{]} subsection: \begin{description} \sphinxlineitem{\sphinxstylestrong{acl\_file}} \sphinxAtStartPar (String.) Location of the access control list file that {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} uses to determine which principals are allowed which permissions on the Kerberos database. To operate without an ACL file, set this relation to the empty string with \sphinxcode{\sphinxupquote{acl\_file = ""}}. The default value is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kadm5.acl}}. For more information on Kerberos ACL file see {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}}. \sphinxlineitem{\sphinxstylestrong{database\_module}} \sphinxAtStartPar (String.) This relation indicates the name of the configuration section under {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbmodules}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbmodules{]}}}}} for database\sphinxhyphen{}specific parameters used by the loadable database library. The default value is the realm name. If this configuration section does not exist, default values will be used for all database parameters. \sphinxlineitem{\sphinxstylestrong{database\_name}} \sphinxAtStartPar (String, deprecated.) This relation specifies the location of the Kerberos database for this realm, if the DB2 module is being used and the {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbmodules}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbmodules{]}}}}} configuration section does not specify a database name. The default value is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/principal}}. \sphinxlineitem{\sphinxstylestrong{default\_principal\_expiration}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{abstime} string.) Specifies the default expiration date of principals created in this realm. The default value is 0, which means no expiration date. \sphinxlineitem{\sphinxstylestrong{default\_principal\_flags}} \sphinxAtStartPar (Flag string.) Specifies the default attributes of principals created in this realm. The format for this string is a comma\sphinxhyphen{}separated list of flags, with ‘+’ before each flag that should be enabled and ‘\sphinxhyphen{}’ before each flag that should be disabled. The \sphinxstylestrong{postdateable}, \sphinxstylestrong{forwardable}, \sphinxstylestrong{tgt\sphinxhyphen{}based}, \sphinxstylestrong{renewable}, \sphinxstylestrong{proxiable}, \sphinxstylestrong{dup\sphinxhyphen{}skey}, \sphinxstylestrong{allow\sphinxhyphen{}tickets}, and \sphinxstylestrong{service} flags default to enabled. \sphinxAtStartPar There are a number of possible flags: \begin{description} \sphinxlineitem{\sphinxstylestrong{allow\sphinxhyphen{}tickets}} \sphinxAtStartPar Enabling this flag means that the KDC will issue tickets for this principal. Disabling this flag essentially deactivates the principal within this realm. \sphinxlineitem{\sphinxstylestrong{dup\sphinxhyphen{}skey}} \sphinxAtStartPar Enabling this flag allows the KDC to issue user\sphinxhyphen{}to\sphinxhyphen{}user service tickets for this principal. \sphinxlineitem{\sphinxstylestrong{forwardable}} \sphinxAtStartPar Enabling this flag allows the principal to obtain forwardable tickets. \sphinxlineitem{\sphinxstylestrong{hwauth}} \sphinxAtStartPar If this flag is enabled, then the principal is required to preauthenticate using a hardware device before receiving any tickets. \sphinxlineitem{\sphinxstylestrong{no\sphinxhyphen{}auth\sphinxhyphen{}data\sphinxhyphen{}required}} \sphinxAtStartPar Enabling this flag prevents PAC or AD\sphinxhyphen{}SIGNEDPATH data from being added to service tickets for the principal. \sphinxlineitem{\sphinxstylestrong{ok\sphinxhyphen{}as\sphinxhyphen{}delegate}} \sphinxAtStartPar If this flag is enabled, it hints the client that credentials can and should be delegated when authenticating to the service. \sphinxlineitem{\sphinxstylestrong{ok\sphinxhyphen{}to\sphinxhyphen{}auth\sphinxhyphen{}as\sphinxhyphen{}delegate}} \sphinxAtStartPar Enabling this flag allows the principal to use S4USelf tickets. \sphinxlineitem{\sphinxstylestrong{postdateable}} \sphinxAtStartPar Enabling this flag allows the principal to obtain postdateable tickets. \sphinxlineitem{\sphinxstylestrong{preauth}} \sphinxAtStartPar If this flag is enabled on a client principal, then that principal is required to preauthenticate to the KDC before receiving any tickets. On a service principal, enabling this flag means that service tickets for this principal will only be issued to clients with a TGT that has the preauthenticated bit set. \sphinxlineitem{\sphinxstylestrong{proxiable}} \sphinxAtStartPar Enabling this flag allows the principal to obtain proxy tickets. \sphinxlineitem{\sphinxstylestrong{pwchange}} \sphinxAtStartPar Enabling this flag forces a password change for this principal. \sphinxlineitem{\sphinxstylestrong{pwservice}} \sphinxAtStartPar If this flag is enabled, it marks this principal as a password change service. This should only be used in special cases, for example, if a user’s password has expired, then the user has to get tickets for that principal without going through the normal password authentication in order to be able to change the password. \sphinxlineitem{\sphinxstylestrong{renewable}} \sphinxAtStartPar Enabling this flag allows the principal to obtain renewable tickets. \sphinxlineitem{\sphinxstylestrong{service}} \sphinxAtStartPar Enabling this flag allows the the KDC to issue service tickets for this principal. In release 1.17 and later, user\sphinxhyphen{}to\sphinxhyphen{}user service tickets are still allowed if the \sphinxstylestrong{dup\sphinxhyphen{}skey} flag is set. \sphinxlineitem{\sphinxstylestrong{tgt\sphinxhyphen{}based}} \sphinxAtStartPar Enabling this flag allows a principal to obtain tickets based on a ticket\sphinxhyphen{}granting\sphinxhyphen{}ticket, rather than repeating the authentication process that was used to obtain the TGT. \end{description} \sphinxlineitem{\sphinxstylestrong{dict\_file}} \sphinxAtStartPar (String.) Location of the dictionary file containing strings that are not allowed as passwords. The file should contain one string per line, with no additional whitespace. If none is specified or if there is no policy assigned to the principal, no dictionary checks of passwords will be performed. \sphinxlineitem{\sphinxstylestrong{disable\_pac}} \sphinxAtStartPar (Boolean value.) If true, the KDC will not issue PACs for this realm, and S4U2Self and S4U2Proxy operations will be disabled. The default is false, which will permit the KDC to issue PACs. New in release 1.20. \sphinxlineitem{\sphinxstylestrong{encrypted\_challenge\_indicator}} \sphinxAtStartPar (String.) Specifies the authentication indicator value that the KDC asserts into tickets obtained using FAST encrypted challenge pre\sphinxhyphen{}authentication. New in 1.16. \sphinxlineitem{\sphinxstylestrong{host\_based\_services}} \sphinxAtStartPar (Whitespace\sphinxhyphen{} or comma\sphinxhyphen{}separated list.) Lists services which will get host\sphinxhyphen{}based referral processing even if the server principal is not marked as host\sphinxhyphen{}based by the client. \sphinxlineitem{\sphinxstylestrong{iprop\_enable}} \sphinxAtStartPar (Boolean value.) Specifies whether incremental database propagation is enabled. The default value is false. \sphinxlineitem{\sphinxstylestrong{iprop\_ulogsize}} \sphinxAtStartPar (Integer.) Specifies the maximum number of log entries to be retained for incremental propagation. The default value is 1000. Prior to release 1.11, the maximum value was 2500. New in release 1.19. \sphinxlineitem{\sphinxstylestrong{iprop\_master\_ulogsize}} \sphinxAtStartPar The name for \sphinxstylestrong{iprop\_ulogsize} prior to release 1.19. Its value is used as a fallback if \sphinxstylestrong{iprop\_ulogsize} is not specified. \sphinxlineitem{\sphinxstylestrong{iprop\_replica\_poll}} \sphinxAtStartPar (Delta time string.) Specifies how often the replica KDC polls for new updates from the primary. The default value is \sphinxcode{\sphinxupquote{2m}} (that is, two minutes). New in release 1.17. \sphinxlineitem{\sphinxstylestrong{iprop\_slave\_poll}} \sphinxAtStartPar (Delta time string.) The name for \sphinxstylestrong{iprop\_replica\_poll} prior to release 1.17. Its value is used as a fallback if \sphinxstylestrong{iprop\_replica\_poll} is not specified. \sphinxlineitem{\sphinxstylestrong{iprop\_listen}} \sphinxAtStartPar (Whitespace\sphinxhyphen{} or comma\sphinxhyphen{}separated list.) Specifies the iprop RPC listening addresses and/or ports for the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon. Each entry may be an interface address, a port number, or an address and port number separated by a colon. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default (when \sphinxstylestrong{iprop\_enable} is true) is to bind to the wildcard address at the port specified in \sphinxstylestrong{iprop\_port}. New in release 1.15. \sphinxlineitem{\sphinxstylestrong{iprop\_port}} \sphinxAtStartPar (Port number.) Specifies the port number to be used for incremental propagation. When \sphinxstylestrong{iprop\_enable} is true, this relation is required in the replica KDC configuration file, and this relation or \sphinxstylestrong{iprop\_listen} is required in the primary configuration file, as there is no default port number. Port numbers specified in \sphinxstylestrong{iprop\_listen} entries will override this port number for the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon. \sphinxlineitem{\sphinxstylestrong{iprop\_resync\_timeout}} \sphinxAtStartPar (Delta time string.) Specifies the amount of time to wait for a full propagation to complete. This is optional in configuration files, and is used by replica KDCs only. The default value is 5 minutes (\sphinxcode{\sphinxupquote{5m}}). New in release 1.11. \sphinxlineitem{\sphinxstylestrong{iprop\_logfile}} \sphinxAtStartPar (File name.) Specifies where the update log file for the realm database is to be stored. The default is to use the \sphinxstylestrong{database\_name} entry from the realms section of the krb5 config file, with \sphinxcode{\sphinxupquote{.ulog}} appended. (NOTE: If \sphinxstylestrong{database\_name} isn’t specified in the realms section, perhaps because the LDAP database back end is being used, or the file name is specified in the {[}dbmodules{]} section, then the hard\sphinxhyphen{}coded default for \sphinxstylestrong{database\_name} is used. Determination of the \sphinxstylestrong{iprop\_logfile} default value will not use values from the {[}dbmodules{]} section.) \sphinxlineitem{\sphinxstylestrong{kadmind\_listen}} \sphinxAtStartPar (Whitespace\sphinxhyphen{} or comma\sphinxhyphen{}separated list.) Specifies the kadmin RPC listening addresses and/or ports for the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. To disable listening for kadmin RPC connections, set this relation to the empty string with \sphinxcode{\sphinxupquote{kadmind\_listen = ""}}. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in \sphinxstylestrong{kadmind\_port}, or the standard kadmin port (749). New in release 1.15. \sphinxlineitem{\sphinxstylestrong{kadmind\_port}} \sphinxAtStartPar (Port number.) Specifies the port on which the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon is to listen for this realm. Port numbers specified in \sphinxstylestrong{kadmind\_listen} entries will override this port number. The assigned port for kadmind is 749, which is used by default. \sphinxlineitem{\sphinxstylestrong{key\_stash\_file}} \sphinxAtStartPar (String.) Specifies the location where the master key has been stored (via kdb5\_util stash). The default is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/.k5.REALM}}, where \sphinxstyleemphasis{REALM} is the Kerberos realm. \sphinxlineitem{\sphinxstylestrong{kdc\_listen}} \sphinxAtStartPar (Whitespace\sphinxhyphen{} or comma\sphinxhyphen{}separated list.) Specifies the listening addresses and/or ports for the {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If no port is specified, the standard port (88) is used. To disable listening on UDP, set this relation to the empty string with \sphinxcode{\sphinxupquote{kdc\_listen = ""}}. If the KDC daemon fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address on the standard port. New in release 1.15. \sphinxlineitem{\sphinxstylestrong{kdc\_ports}} \sphinxAtStartPar (Whitespace\sphinxhyphen{} or comma\sphinxhyphen{}separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as \sphinxstylestrong{kdc\_listen} if that relation is not defined. \sphinxlineitem{\sphinxstylestrong{kdc\_tcp\_listen}} \sphinxAtStartPar (Whitespace\sphinxhyphen{} or comma\sphinxhyphen{}separated list.) Specifies the TCP listening addresses and/or ports for the {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} daemon. The syntax is identical to that of \sphinxstylestrong{kdc\_listen}. To disable listening on TCP, set this relation to the empty string with \sphinxcode{\sphinxupquote{kdc\_tcp\_listen = ""}}. The default is to bind to the same addresses and ports as for UDP. New in release 1.15. \sphinxlineitem{\sphinxstylestrong{kdc\_tcp\_ports}} \sphinxAtStartPar (Whitespace\sphinxhyphen{} or comma\sphinxhyphen{}separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as \sphinxstylestrong{kdc\_tcp\_listen} if that relation is not defined. \sphinxlineitem{\sphinxstylestrong{kpasswd\_listen}} \sphinxAtStartPar (Comma\sphinxhyphen{}separated list.) Specifies the kpasswd listening addresses and/or ports for the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. To disable listening for kpasswd requests, set this relation to the empty string with \sphinxcode{\sphinxupquote{kpasswd\_listen = ""}}. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in \sphinxstylestrong{kpasswd\_port}, or the standard kpasswd port (464). New in release 1.15. \sphinxlineitem{\sphinxstylestrong{kpasswd\_port}} \sphinxAtStartPar (Port number.) Specifies the port on which the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon is to listen for password change requests for this realm. Port numbers specified in \sphinxstylestrong{kpasswd\_listen} entries will override this port number. The assigned port for password change requests is 464, which is used by default. \sphinxlineitem{\sphinxstylestrong{master\_key\_name}} \sphinxAtStartPar (String.) Specifies the name of the principal associated with the master key. The default is \sphinxcode{\sphinxupquote{K/M}}. \sphinxlineitem{\sphinxstylestrong{master\_key\_type}} \sphinxAtStartPar (Key type string.) Specifies the master key’s key type. The default value for this is \sphinxcode{\sphinxupquote{aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96}}. For a list of all possible values, see {\hyperref[\detokenize{admin/conf_files/kdc_conf:encryption-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Encryption types}}}}. \sphinxlineitem{\sphinxstylestrong{max\_life}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Specifies the maximum time period for which a ticket may be valid in this realm. The default value is 24 hours. \sphinxlineitem{\sphinxstylestrong{max\_renewable\_life}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} string.) Specifies the maximum time period during which a valid ticket may be renewed in this realm. The default value is 0. \sphinxlineitem{\sphinxstylestrong{no\_host\_referral}} \sphinxAtStartPar (Whitespace\sphinxhyphen{} or comma\sphinxhyphen{}separated list.) Lists services to block from getting host\sphinxhyphen{}based referral processing, even if the client marks the server principal as host\sphinxhyphen{}based or the service is also listed in \sphinxstylestrong{host\_based\_services}. \sphinxcode{\sphinxupquote{no\_host\_referral = *}} will disable referral processing altogether. \sphinxlineitem{\sphinxstylestrong{reject\_bad\_transit}} \sphinxAtStartPar (Boolean value.) If set to true, the KDC will check the list of transited realms for cross\sphinxhyphen{}realm tickets against the transit path computed from the realm names and the capaths section of its {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} file; if the path in the ticket to be issued contains any realms not in the computed path, the ticket will not be issued, and an error will be returned to the client instead. If this value is set to false, such tickets will be issued anyways, and it will be left up to the application server to validate the realm transit path. \sphinxAtStartPar If the disable\sphinxhyphen{}transited\sphinxhyphen{}check flag is set in the incoming request, this check is not performed at all. Having the \sphinxstylestrong{reject\_bad\_transit} option will cause such ticket requests to be rejected always. \sphinxAtStartPar This transit path checking and config file option currently apply only to TGS requests. \sphinxAtStartPar The default value is true. \sphinxlineitem{\sphinxstylestrong{restrict\_anonymous\_to\_tgt}} \sphinxAtStartPar (Boolean value.) If set to true, the KDC will reject ticket requests from anonymous principals to service principals other than the realm’s ticket\sphinxhyphen{}granting service. This option allows anonymous PKINIT to be enabled for use as FAST armor tickets without allowing anonymous authentication to services. The default value is false. New in release 1.9. \sphinxlineitem{\sphinxstylestrong{spake\_preauth\_indicator}} \sphinxAtStartPar (String.) Specifies an authentication indicator value that the KDC asserts into tickets obtained using SPAKE pre\sphinxhyphen{}authentication. The default is not to add any indicators. This option may be specified multiple times. New in release 1.17. \sphinxlineitem{\sphinxstylestrong{supported\_enctypes}} \sphinxAtStartPar (List of \sphinxstyleemphasis{key}:\sphinxstyleemphasis{salt} strings.) Specifies the default key/salt combinations of principals for this realm. Any principals created through {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} will have keys of these types. The default value for this tag is \sphinxcode{\sphinxupquote{aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96:normal aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96:normal}}. For lists of possible values, see {\hyperref[\detokenize{admin/conf_files/kdc_conf:keysalt-lists}]{\sphinxcrossref{\DUrole{std,std-ref}{Keysalt lists}}}}. \end{description} \paragraph{{[}dbdefaults{]}} \label{\detokenize{admin/conf_files/kdc_conf:dbdefaults}}\label{\detokenize{admin/conf_files/kdc_conf:id2}} \sphinxAtStartPar The {[}dbdefaults{]} section specifies default values for some database parameters, to be used if the {[}dbmodules{]} subsection does not contain a relation for the tag. See the {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbmodules}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbmodules{]}}}}} section for the definitions of these relations. \begin{itemize} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kerberos\_container\_dn} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kdc\_dn} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kdc\_sasl\_authcid} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kdc\_sasl\_authzid} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kdc\_sasl\_mech} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kdc\_sasl\_realm} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kadmind\_dn} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kadmind\_sasl\_authcid} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kadmind\_sasl\_authzid} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kadmind\_sasl\_mech} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_kadmind\_sasl\_realm} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_service\_password\_file} \item {} \sphinxAtStartPar \sphinxstylestrong{ldap\_conns\_per\_server} \end{itemize} \paragraph{{[}dbmodules{]}} \label{\detokenize{admin/conf_files/kdc_conf:dbmodules}}\label{\detokenize{admin/conf_files/kdc_conf:id3}} \sphinxAtStartPar The {[}dbmodules{]} section contains parameters used by the KDC database library and database modules. Each tag in the {[}dbmodules{]} section is the name of a Kerberos realm or a section name specified by a realm’s \sphinxstylestrong{database\_module} parameter. The following example shows how to define one database parameter for the ATHENA.MIT.EDU realm: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{dbmodules}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{disable\PYGZus{}last\PYGZus{}success} \PYG{o}{=} \PYG{n}{true} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar The following tags may be specified in a {[}dbmodules{]} subsection: \begin{description} \sphinxlineitem{\sphinxstylestrong{database\_name}} \sphinxAtStartPar This DB2\sphinxhyphen{}specific tag indicates the location of the database in the filesystem. The default is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/principal}}. \sphinxlineitem{\sphinxstylestrong{db\_library}} \sphinxAtStartPar This tag indicates the name of the loadable database module. The value should be \sphinxcode{\sphinxupquote{db2}} for the DB2 module, \sphinxcode{\sphinxupquote{klmdb}} for the LMDB module, or \sphinxcode{\sphinxupquote{kldap}} for the LDAP module. \sphinxlineitem{\sphinxstylestrong{disable\_last\_success}} \sphinxAtStartPar If set to \sphinxcode{\sphinxupquote{true}}, suppresses KDC updates to the “Last successful authentication†field of principal entries requiring preauthentication. Setting this flag may improve performance. (Principal entries which do not require preauthentication never update the “Last successful authentication†field.). First introduced in release 1.9. \sphinxlineitem{\sphinxstylestrong{disable\_lockout}} \sphinxAtStartPar If set to \sphinxcode{\sphinxupquote{true}}, suppresses KDC updates to the “Last failed authentication†and “Failed password attempts†fields of principal entries requiring preauthentication. Setting this flag may improve performance, but also disables account lockout. First introduced in release 1.9. \sphinxlineitem{\sphinxstylestrong{ldap\_conns\_per\_server}} \sphinxAtStartPar This LDAP\sphinxhyphen{}specific tag indicates the number of connections to be maintained per LDAP server. \sphinxlineitem{\sphinxstylestrong{ldap\_kdc\_dn} and \sphinxstylestrong{ldap\_kadmind\_dn}} \sphinxAtStartPar These LDAP\sphinxhyphen{}specific tags indicate the default DN for binding to the LDAP server. The {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} daemon uses \sphinxstylestrong{ldap\_kdc\_dn}, while the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon and other administrative programs use \sphinxstylestrong{ldap\_kadmind\_dn}. The kadmind DN must have the rights to read and write the Kerberos data in the LDAP database. The KDC DN must have the same rights, unless \sphinxstylestrong{disable\_lockout} and \sphinxstylestrong{disable\_last\_success} are true, in which case it only needs to have rights to read the Kerberos data. These tags are ignored if a SASL mechanism is set with \sphinxstylestrong{ldap\_kdc\_sasl\_mech} or \sphinxstylestrong{ldap\_kadmind\_sasl\_mech}. \sphinxlineitem{\sphinxstylestrong{ldap\_kdc\_sasl\_mech} and \sphinxstylestrong{ldap\_kadmind\_sasl\_mech}} \sphinxAtStartPar These LDAP\sphinxhyphen{}specific tags specify the SASL mechanism (such as \sphinxcode{\sphinxupquote{EXTERNAL}}) to use when binding to the LDAP server. New in release 1.13. \sphinxlineitem{\sphinxstylestrong{ldap\_kdc\_sasl\_authcid} and \sphinxstylestrong{ldap\_kadmind\_sasl\_authcid}} \sphinxAtStartPar These LDAP\sphinxhyphen{}specific tags specify the SASL authentication identity to use when binding to the LDAP server. Not all SASL mechanisms require an authentication identity. If the SASL mechanism requires a secret (such as the password for \sphinxcode{\sphinxupquote{DIGEST\sphinxhyphen{}MD5}}), these tags also determine the name within the \sphinxstylestrong{ldap\_service\_password\_file} where the secret is stashed. New in release 1.13. \sphinxlineitem{\sphinxstylestrong{ldap\_kdc\_sasl\_authzid} and \sphinxstylestrong{ldap\_kadmind\_sasl\_authzid}} \sphinxAtStartPar These LDAP\sphinxhyphen{}specific tags specify the SASL authorization identity to use when binding to the LDAP server. In most circumstances they do not need to be specified. New in release 1.13. \sphinxlineitem{\sphinxstylestrong{ldap\_kdc\_sasl\_realm} and \sphinxstylestrong{ldap\_kadmind\_sasl\_realm}} \sphinxAtStartPar These LDAP\sphinxhyphen{}specific tags specify the SASL realm to use when binding to the LDAP server. In most circumstances they do not need to be set. New in release 1.13. \sphinxlineitem{\sphinxstylestrong{ldap\_kerberos\_container\_dn}} \sphinxAtStartPar This LDAP\sphinxhyphen{}specific tag indicates the DN of the container object where the realm objects will be located. \sphinxlineitem{\sphinxstylestrong{ldap\_servers}} \sphinxAtStartPar This LDAP\sphinxhyphen{}specific tag indicates the list of LDAP servers that the Kerberos servers can connect to. The list of LDAP servers is whitespace\sphinxhyphen{}separated. The LDAP server is specified by a LDAP URI. It is recommended to use \sphinxcode{\sphinxupquote{ldapi:}} or \sphinxcode{\sphinxupquote{ldaps:}} URLs to connect to the LDAP server. \sphinxlineitem{\sphinxstylestrong{ldap\_service\_password\_file}} \sphinxAtStartPar This LDAP\sphinxhyphen{}specific tag indicates the file containing the stashed passwords (created by \sphinxcode{\sphinxupquote{kdb5\_ldap\_util stashsrvpw}}) for the \sphinxstylestrong{ldap\_kdc\_dn} and \sphinxstylestrong{ldap\_kadmind\_dn} objects, or for the \sphinxstylestrong{ldap\_kdc\_sasl\_authcid} or \sphinxstylestrong{ldap\_kadmind\_sasl\_authcid} names for SASL authentication. This file must be kept secure. \sphinxlineitem{\sphinxstylestrong{mapsize}} \sphinxAtStartPar This LMDB\sphinxhyphen{}specific tag indicates the maximum size of the two database environments in megabytes. The default value is 128. Increase this value to address “Environment mapsize limit reached†errors. New in release 1.17. \sphinxlineitem{\sphinxstylestrong{max\_readers}} \sphinxAtStartPar This LMDB\sphinxhyphen{}specific tag indicates the maximum number of concurrent reading processes for the databases. The default value is 128. New in release 1.17. \sphinxlineitem{\sphinxstylestrong{nosync}} \sphinxAtStartPar This LMDB\sphinxhyphen{}specific tag can be set to improve the throughput of kadmind and other administrative agents, at the expense of durability (recent database changes may not survive a power outage or other sudden reboot). It does not affect the throughput of the KDC. The default value is false. New in release 1.17. \sphinxlineitem{\sphinxstylestrong{unlockiter}} \sphinxAtStartPar If set to \sphinxcode{\sphinxupquote{true}}, this DB2\sphinxhyphen{}specific tag causes iteration operations to release the database lock while processing each principal. Setting this flag to \sphinxcode{\sphinxupquote{true}} can prevent extended blocking of KDC or kadmin operations when dumps of large databases are in progress. First introduced in release 1.13. \end{description} \sphinxAtStartPar The following tag may be specified directly in the {[}dbmodules{]} section to control where database modules are loaded from: \begin{description} \sphinxlineitem{\sphinxstylestrong{db\_module\_dir}} \sphinxAtStartPar This tag controls where the plugin system looks for database modules. The value should be an absolute path. \end{description} \paragraph{{[}logging{]}} \label{\detokenize{admin/conf_files/kdc_conf:logging}}\label{\detokenize{admin/conf_files/kdc_conf:id4}} \sphinxAtStartPar The {[}logging{]} section indicates how {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} and {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} perform logging. It may contain the following relations: \begin{description} \sphinxlineitem{\sphinxstylestrong{admin\_server}} \sphinxAtStartPar Specifies how {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} performs logging. \sphinxlineitem{\sphinxstylestrong{kdc}} \sphinxAtStartPar Specifies how {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} performs logging. \sphinxlineitem{\sphinxstylestrong{default}} \sphinxAtStartPar Specifies how either daemon performs logging in the absence of relations specific to the daemon. \sphinxlineitem{\sphinxstylestrong{debug}} \sphinxAtStartPar (Boolean value.) Specifies whether debugging messages are included in log outputs other than SYSLOG. Debugging messages are always included in the system log output because syslog performs its own priority filtering. The default value is false. New in release 1.15. \end{description} \sphinxAtStartPar Logging specifications may have the following forms: \begin{description} \sphinxlineitem{\sphinxstylestrong{FILE=}\sphinxstyleemphasis{filename} or \sphinxstylestrong{FILE:}\sphinxstyleemphasis{filename}} \sphinxAtStartPar This value causes the daemon’s logging messages to go to the \sphinxstyleemphasis{filename}. If the \sphinxcode{\sphinxupquote{=}} form is used, the file is overwritten. If the \sphinxcode{\sphinxupquote{:}} form is used, the file is appended to. \sphinxlineitem{\sphinxstylestrong{STDERR}} \sphinxAtStartPar This value causes the daemon’s logging messages to go to its standard error stream. \sphinxlineitem{\sphinxstylestrong{CONSOLE}} \sphinxAtStartPar This value causes the daemon’s logging messages to go to the console, if the system supports it. \sphinxlineitem{\sphinxstylestrong{DEVICE=}\sphinxstyleemphasis{\textless{}devicename\textgreater{}}} \sphinxAtStartPar This causes the daemon’s logging messages to go to the specified device. \sphinxlineitem{\sphinxstylestrong{SYSLOG}{[}\sphinxstylestrong{:}\sphinxstyleemphasis{severity}{[}\sphinxstylestrong{:}\sphinxstyleemphasis{facility}{]}{]}} \sphinxAtStartPar This causes the daemon’s logging messages to go to the system log. \sphinxAtStartPar For backward compatibility, a severity argument may be specified, and must be specified in order to specify a facility. This argument will be ignored. \sphinxAtStartPar The facility argument specifies the facility under which the messages are logged. This may be any of the following facilities supported by the syslog(3) call minus the LOG\_ prefix: \sphinxstylestrong{KERN}, \sphinxstylestrong{USER}, \sphinxstylestrong{MAIL}, \sphinxstylestrong{DAEMON}, \sphinxstylestrong{AUTH}, \sphinxstylestrong{LPR}, \sphinxstylestrong{NEWS}, \sphinxstylestrong{UUCP}, \sphinxstylestrong{CRON}, and \sphinxstylestrong{LOCAL0} through \sphinxstylestrong{LOCAL7}. If no facility is specified, the default is \sphinxstylestrong{AUTH}. \end{description} \sphinxAtStartPar In the following example, the logging messages from the KDC will go to the console and to the system log under the facility LOG\_DAEMON, and the logging messages from the administrative server will be appended to the file \sphinxcode{\sphinxupquote{/var/adm/kadmin.log}} and sent to the device \sphinxcode{\sphinxupquote{/dev/tty04}}. \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{logging}\PYG{p}{]} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{CONSOLE} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{SYSLOG}\PYG{p}{:}\PYG{n}{INFO}\PYG{p}{:}\PYG{n}{DAEMON} \PYG{n}{admin\PYGZus{}server} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{adm}\PYG{o}{/}\PYG{n}{kadmin}\PYG{o}{.}\PYG{n}{log} \PYG{n}{admin\PYGZus{}server} \PYG{o}{=} \PYG{n}{DEVICE}\PYG{o}{=}\PYG{o}{/}\PYG{n}{dev}\PYG{o}{/}\PYG{n}{tty04} \end{sphinxVerbatim} \sphinxAtStartPar If no logging specification is given, the default is to use syslog. To disable logging entirely, specify \sphinxcode{\sphinxupquote{default = DEVICE=/dev/null}}. \paragraph{{[}otp{]}} \label{\detokenize{admin/conf_files/kdc_conf:otp}}\label{\detokenize{admin/conf_files/kdc_conf:id5}} \sphinxAtStartPar Each subsection of {[}otp{]} is the name of an OTP token type. The tags within the subsection define the configuration required to forward a One Time Password request to a RADIUS server. \sphinxAtStartPar For each token type, the following tags may be specified: \begin{description} \sphinxlineitem{\sphinxstylestrong{server}} \sphinxAtStartPar This is the server to send the RADIUS request to. It can be a hostname with optional port, an ip address with optional port, or a Unix domain socket address. The default is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/\textless{}name\textgreater{}.socket}}. \sphinxlineitem{\sphinxstylestrong{secret}} \sphinxAtStartPar This tag indicates a filename (which may be relative to {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}) containing the secret used to encrypt the RADIUS packets. The secret should appear in the first line of the file by itself; leading and trailing whitespace on the line will be removed. If the value of \sphinxstylestrong{server} is a Unix domain socket address, this tag is optional, and an empty secret will be used if it is not specified. Otherwise, this tag is required. \sphinxlineitem{\sphinxstylestrong{timeout}} \sphinxAtStartPar An integer which specifies the time in seconds during which the KDC should attempt to contact the RADIUS server. This tag is the total time across all retries and should be less than the time which an OTP value remains valid for. The default is 5 seconds. \sphinxlineitem{\sphinxstylestrong{retries}} \sphinxAtStartPar This tag specifies the number of retries to make to the RADIUS server. The default is 3 retries (4 tries). \sphinxlineitem{\sphinxstylestrong{strip\_realm}} \sphinxAtStartPar If this tag is \sphinxcode{\sphinxupquote{true}}, the principal without the realm will be passed to the RADIUS server. Otherwise, the realm will be included. The default value is \sphinxcode{\sphinxupquote{true}}. \sphinxlineitem{\sphinxstylestrong{indicator}} \sphinxAtStartPar This tag specifies an authentication indicator to be included in the ticket if this token type is used to authenticate. This option may be specified multiple times. (New in release 1.14.) \end{description} \sphinxAtStartPar In the following example, requests are sent to a remote server via UDP: \begin{sphinxVerbatim}[commandchars=\\\{\}] [otp] MyRemoteTokenType = \PYGZob{} server = radius.mydomain.com:1812 secret = SEmfiajf42\PYGZdl{} timeout = 15 retries = 5 strip\PYGZus{}realm = true \PYGZcb{} \end{sphinxVerbatim} \sphinxAtStartPar An implicit default token type named \sphinxcode{\sphinxupquote{DEFAULT}} is defined for when the per\sphinxhyphen{}principal configuration does not specify a token type. Its configuration is shown below. You may override this token type to something applicable for your situation: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{otp}\PYG{p}{]} \PYG{n}{DEFAULT} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{strip\PYGZus{}realm} \PYG{o}{=} \PYG{n}{false} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \subsubsection{PKINIT options} \label{\detokenize{admin/conf_files/kdc_conf:pkinit-options}} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The following are pkinit\sphinxhyphen{}specific options. These values may be specified in {[}kdcdefaults{]} as global defaults, or within a realm\sphinxhyphen{}specific subsection of {[}realms{]}. Also note that a realm\sphinxhyphen{}specific value over\sphinxhyphen{}rides, does not add to, a generic {[}kdcdefaults{]} specification. The search order is: \end{sphinxadmonition} \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar realm\sphinxhyphen{}specific subsection of {[}realms{]}: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{pkinit\PYGZus{}anchors} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com}\PYG{o}{.}\PYG{n}{crt} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \item {} \sphinxAtStartPar generic value in the {[}kdcdefaults{]} section: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{kdcdefaults}\PYG{p}{]} \PYG{n}{pkinit\PYGZus{}anchors} \PYG{o}{=} \PYG{n}{DIR}\PYG{p}{:}\PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{generic\PYGZus{}trusted\PYGZus{}cas}\PYG{o}{/} \end{sphinxVerbatim} \end{enumerate} \sphinxAtStartPar For information about the syntax of some of these options, see {\hyperref[\detokenize{admin/conf_files/krb5_conf:pkinit-identity}]{\sphinxcrossref{\DUrole{std,std-ref}{Specifying PKINIT identity information}}}} in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. \begin{description} \sphinxlineitem{\sphinxstylestrong{pkinit\_anchors}} \sphinxAtStartPar Specifies the location of trusted anchor (root) certificates which the KDC trusts to sign client certificates. This option is required if pkinit is to be supported by the KDC. This option may be specified multiple times. \sphinxlineitem{\sphinxstylestrong{pkinit\_dh\_min\_bits}} \sphinxAtStartPar Specifies the minimum strength of Diffie\sphinxhyphen{}Hellman group the KDC is willing to accept for key exchange. Valid values in order of increasing strength are 1024, 2048, P\sphinxhyphen{}256, 4096, P\sphinxhyphen{}384, and P\sphinxhyphen{}521. The default is 2048. (P\sphinxhyphen{}256, P\sphinxhyphen{}384, and P\sphinxhyphen{}521 are new in release 1.22.) \sphinxlineitem{\sphinxstylestrong{pkinit\_allow\_upn}} \sphinxAtStartPar Specifies that the KDC is willing to accept client certificates with the Microsoft UserPrincipalName (UPN) Subject Alternative Name (SAN). This means the KDC accepts the binding of the UPN in the certificate to the Kerberos principal name. The default value is false. \sphinxAtStartPar Without this option, the KDC will only accept certificates with the id\sphinxhyphen{}pkinit\sphinxhyphen{}san as defined in \index{RFC@\spxentry{RFC}!RFC 4556@\spxentry{RFC 4556}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc4556.html}{\sphinxstylestrong{RFC 4556}}. There is currently no option to disable SAN checking in the KDC. \sphinxlineitem{\sphinxstylestrong{pkinit\_eku\_checking}} \sphinxAtStartPar This option specifies what Extended Key Usage (EKU) values the KDC is willing to accept in client certificates. The values recognized in the kdc.conf file are: \begin{description} \sphinxlineitem{\sphinxstylestrong{kpClientAuth}} \sphinxAtStartPar This is the default value and specifies that client certificates must have the id\sphinxhyphen{}pkinit\sphinxhyphen{}KPClientAuth EKU as defined in \index{RFC@\spxentry{RFC}!RFC 4556@\spxentry{RFC 4556}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc4556.html}{\sphinxstylestrong{RFC 4556}}. \sphinxlineitem{\sphinxstylestrong{scLogin}} \sphinxAtStartPar If scLogin is specified, client certificates with the Microsoft Smart Card Login EKU (id\sphinxhyphen{}ms\sphinxhyphen{}kp\sphinxhyphen{}sc\sphinxhyphen{}logon) will be accepted. \sphinxlineitem{\sphinxstylestrong{none}} \sphinxAtStartPar If none is specified, then client certificates will not be checked to verify they have an acceptable EKU. The use of this option is not recommended. \end{description} \sphinxlineitem{\sphinxstylestrong{pkinit\_identity}} \sphinxAtStartPar Specifies the location of the KDC’s X.509 identity information. This option is required if pkinit is to be supported by the KDC. \sphinxlineitem{\sphinxstylestrong{pkinit\_indicator}} \sphinxAtStartPar Specifies an authentication indicator to include in the ticket if pkinit is used to authenticate. This option may be specified multiple times. (New in release 1.14.) \sphinxlineitem{\sphinxstylestrong{pkinit\_pool}} \sphinxAtStartPar Specifies the location of intermediate certificates which may be used by the KDC to complete the trust chain between a client’s certificate and a trusted anchor. This option may be specified multiple times. \sphinxlineitem{\sphinxstylestrong{pkinit\_revoke}} \sphinxAtStartPar Specifies the location of Certificate Revocation List (CRL) information to be used by the KDC when verifying the validity of client certificates. This option may be specified multiple times. \sphinxlineitem{\sphinxstylestrong{pkinit\_require\_crl\_checking}} \sphinxAtStartPar The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and \sphinxstylestrong{pkinit\_require\_crl\_checking} is false, then verification succeeds. \sphinxAtStartPar However, if \sphinxstylestrong{pkinit\_require\_crl\_checking} is true and there is no CRL information available for the issuing CA, then verification fails. \sphinxAtStartPar \sphinxstylestrong{pkinit\_require\_crl\_checking} should be set to true if the policy is such that up\sphinxhyphen{}to\sphinxhyphen{}date CRLs must be present for every CA. \sphinxlineitem{\sphinxstylestrong{pkinit\_require\_freshness}} \sphinxAtStartPar Specifies whether to require clients to include a freshness token in PKINIT requests. The default value is false. (New in release 1.17.) \end{description} \subsubsection{Encryption types} \label{\detokenize{admin/conf_files/kdc_conf:encryption-types}}\label{\detokenize{admin/conf_files/kdc_conf:id6}} \sphinxAtStartPar Any tag in the configuration files which requires a list of encryption types can be set to some combination of the following strings. Encryption types marked as “weak†and “deprecated†are available for compatibility but not recommended for use. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar des3\sphinxhyphen{}cbc\sphinxhyphen{}raw & \sphinxAtStartPar Triple DES cbc mode raw (weak) \\ \sphinxhline \sphinxAtStartPar des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 des3\sphinxhyphen{}hmac\sphinxhyphen{}sha1 des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1\sphinxhyphen{}kd & \sphinxAtStartPar Triple DES cbc mode with HMAC/sha1 (deprecated) \\ \sphinxhline \sphinxAtStartPar aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes256\sphinxhyphen{}cts aes256\sphinxhyphen{}sha1 & \sphinxAtStartPar AES\sphinxhyphen{}256 CTS mode with 96\sphinxhyphen{}bit SHA\sphinxhyphen{}1 HMAC \\ \sphinxhline \sphinxAtStartPar aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes128\sphinxhyphen{}cts aes128\sphinxhyphen{}sha1 & \sphinxAtStartPar AES\sphinxhyphen{}128 CTS mode with 96\sphinxhyphen{}bit SHA\sphinxhyphen{}1 HMAC \\ \sphinxhline \sphinxAtStartPar aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha384\sphinxhyphen{}192 aes256\sphinxhyphen{}sha2 & \sphinxAtStartPar AES\sphinxhyphen{}256 CTS mode with 192\sphinxhyphen{}bit SHA\sphinxhyphen{}384 HMAC \\ \sphinxhline \sphinxAtStartPar aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha256\sphinxhyphen{}128 aes128\sphinxhyphen{}sha2 & \sphinxAtStartPar AES\sphinxhyphen{}128 CTS mode with 128\sphinxhyphen{}bit SHA\sphinxhyphen{}256 HMAC \\ \sphinxhline \sphinxAtStartPar arcfour\sphinxhyphen{}hmac rc4\sphinxhyphen{}hmac arcfour\sphinxhyphen{}hmac\sphinxhyphen{}md5 & \sphinxAtStartPar RC4 with HMAC/MD5 (deprecated) \\ \sphinxhline \sphinxAtStartPar arcfour\sphinxhyphen{}hmac\sphinxhyphen{}exp rc4\sphinxhyphen{}hmac\sphinxhyphen{}exp arcfour\sphinxhyphen{}hmac\sphinxhyphen{}md5\sphinxhyphen{}exp & \sphinxAtStartPar Exportable RC4 with HMAC/MD5 (weak) \\ \sphinxhline \sphinxAtStartPar camellia256\sphinxhyphen{}cts\sphinxhyphen{}cmac camellia256\sphinxhyphen{}cts & \sphinxAtStartPar Camellia\sphinxhyphen{}256 CTS mode with CMAC \\ \sphinxhline \sphinxAtStartPar camellia128\sphinxhyphen{}cts\sphinxhyphen{}cmac camellia128\sphinxhyphen{}cts & \sphinxAtStartPar Camellia\sphinxhyphen{}128 CTS mode with CMAC \\ \sphinxhline \sphinxAtStartPar des3 & \sphinxAtStartPar The triple DES family: des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 \\ \sphinxhline \sphinxAtStartPar aes & \sphinxAtStartPar The AES family: aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96, aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96, aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha384\sphinxhyphen{}192, and aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha256\sphinxhyphen{}128 \\ \sphinxhline \sphinxAtStartPar rc4 & \sphinxAtStartPar The RC4 family: arcfour\sphinxhyphen{}hmac \\ \sphinxhline \sphinxAtStartPar camellia & \sphinxAtStartPar The Camellia family: camellia256\sphinxhyphen{}cts\sphinxhyphen{}cmac and camellia128\sphinxhyphen{}cts\sphinxhyphen{}cmac \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxAtStartPar The string \sphinxstylestrong{DEFAULT} can be used to refer to the default set of types for the variable in question. Types or families can be removed from the current list by prefixing them with a minus sign (“\sphinxhyphen{}“). Types or families can be prefixed with a plus sign (“+â€) for symmetry; it has the same meaning as just listing the type or family. For example, “\sphinxcode{\sphinxupquote{DEFAULT \sphinxhyphen{}rc4}}†would be the default set of encryption types with RC4 types removed, and “\sphinxcode{\sphinxupquote{des3 DEFAULT}}†would be the default set of encryption types with triple DES types moved to the front. \sphinxAtStartPar While \sphinxstylestrong{aes128\sphinxhyphen{}cts} and \sphinxstylestrong{aes256\sphinxhyphen{}cts} are supported for all Kerberos operations, they are not supported by very old versions of our GSSAPI implementation (krb5\sphinxhyphen{}1.3.1 and earlier). Services running versions of krb5 without AES support must not be given keys of these encryption types in the KDC database. \sphinxAtStartPar The \sphinxstylestrong{aes128\sphinxhyphen{}sha2} and \sphinxstylestrong{aes256\sphinxhyphen{}sha2} encryption types are new in release 1.15. Services running versions of krb5 without support for these newer encryption types must not be given keys of these encryption types in the KDC database. \subsubsection{Keysalt lists} \label{\detokenize{admin/conf_files/kdc_conf:keysalt-lists}}\label{\detokenize{admin/conf_files/kdc_conf:id7}} \sphinxAtStartPar Kerberos keys for users are usually derived from passwords. Kerberos commands and configuration parameters that affect generation of keys take lists of enctype\sphinxhyphen{}salttype (“keysaltâ€) pairs, known as \sphinxstyleemphasis{keysalt lists}. Each keysalt pair is an enctype name followed by a salttype name, in the format \sphinxstyleemphasis{enc}:\sphinxstyleemphasis{salt}. Individual keysalt list members are separated by comma (“,â€) characters or space characters. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin} \PYG{o}{\PYGZhy{}}\PYG{n}{e} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{p}{:}\PYG{n}{normal}\PYG{p}{,}\PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{p}{:}\PYG{n}{normal} \end{sphinxVerbatim} \sphinxAtStartPar would start up kadmin so that by default it would generate password\sphinxhyphen{}derived keys for the \sphinxstylestrong{aes256\sphinxhyphen{}cts} and \sphinxstylestrong{aes128\sphinxhyphen{}cts} encryption types, using a \sphinxstylestrong{normal} salt. \sphinxAtStartPar To ensure that people who happen to pick the same password do not have the same key, Kerberos 5 incorporates more information into the key using something called a salt. The supported salt types are as follows: \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar normal & \sphinxAtStartPar default for Kerberos Version 5 \\ \sphinxhline \sphinxAtStartPar norealm & \sphinxAtStartPar same as the default, without using realm information \\ \sphinxhline \sphinxAtStartPar onlyrealm & \sphinxAtStartPar uses only realm information as the salt \\ \sphinxhline \sphinxAtStartPar special & \sphinxAtStartPar generate a random salt \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \subsubsection{Sample kdc.conf File} \label{\detokenize{admin/conf_files/kdc_conf:sample-kdc-conf-file}} \sphinxAtStartPar Here’s an example of a kdc.conf file: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{kdcdefaults}\PYG{p}{]} \PYG{n}{kdc\PYGZus{}listen} \PYG{o}{=} \PYG{l+m+mi}{88} \PYG{n}{kdc\PYGZus{}tcp\PYGZus{}listen} \PYG{o}{=} \PYG{l+m+mi}{88} \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{kadmind\PYGZus{}port} \PYG{o}{=} \PYG{l+m+mi}{749} \PYG{n}{max\PYGZus{}life} \PYG{o}{=} \PYG{l+m+mi}{12}\PYG{n}{h} \PYG{l+m+mi}{0}\PYG{n}{m} \PYG{l+m+mi}{0}\PYG{n}{s} \PYG{n}{max\PYGZus{}renewable\PYGZus{}life} \PYG{o}{=} \PYG{l+m+mi}{7}\PYG{n}{d} \PYG{l+m+mi}{0}\PYG{n}{h} \PYG{l+m+mi}{0}\PYG{n}{m} \PYG{l+m+mi}{0}\PYG{n}{s} \PYG{n}{master\PYGZus{}key\PYGZus{}type} \PYG{o}{=} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{supported\PYGZus{}enctypes} \PYG{o}{=} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{database\PYGZus{}module} \PYG{o}{=} \PYG{n}{openldap\PYGZus{}ldapconf} \PYG{p}{\PYGZcb{}} \PYG{p}{[}\PYG{n}{logging}\PYG{p}{]} \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{krb5kdc}\PYG{o}{/}\PYG{n}{kdc}\PYG{o}{.}\PYG{n}{log} \PYG{n}{admin\PYGZus{}server} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{krb5kdc}\PYG{o}{/}\PYG{n}{kadmin}\PYG{o}{.}\PYG{n}{log} \PYG{p}{[}\PYG{n}{dbdefaults}\PYG{p}{]} \PYG{n}{ldap\PYGZus{}kerberos\PYGZus{}container\PYGZus{}dn} \PYG{o}{=} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{krbcontainer}\PYG{p}{,}\PYG{n}{dc}\PYG{o}{=}\PYG{n}{mit}\PYG{p}{,}\PYG{n}{dc}\PYG{o}{=}\PYG{n}{edu} \PYG{p}{[}\PYG{n}{dbmodules}\PYG{p}{]} \PYG{n}{openldap\PYGZus{}ldapconf} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{db\PYGZus{}library} \PYG{o}{=} \PYG{n}{kldap} \PYG{n}{disable\PYGZus{}last\PYGZus{}success} \PYG{o}{=} \PYG{n}{true} \PYG{n}{ldap\PYGZus{}kdc\PYGZus{}dn} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=krbadmin,dc=mit,dc=edu}\PYG{l+s+s2}{\PYGZdq{}} \PYG{c+c1}{\PYGZsh{} this object needs to have read rights on} \PYG{c+c1}{\PYGZsh{} the realm container and principal subtrees} \PYG{n}{ldap\PYGZus{}kadmind\PYGZus{}dn} \PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=krbadmin,dc=mit,dc=edu}\PYG{l+s+s2}{\PYGZdq{}} \PYG{c+c1}{\PYGZsh{} this object needs to have read and write rights on} \PYG{c+c1}{\PYGZsh{} the realm container and principal subtrees} \PYG{n}{ldap\PYGZus{}service\PYGZus{}password\PYGZus{}file} \PYG{o}{=} \PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{/}\PYG{n}{service}\PYG{o}{.}\PYG{n}{keyfile} \PYG{n}{ldap\PYGZus{}servers} \PYG{o}{=} \PYG{n}{ldaps}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{ldap\PYGZus{}conns\PYGZus{}per\PYGZus{}server} \PYG{o}{=} \PYG{l+m+mi}{5} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \subsubsection{FILES} \label{\detokenize{admin/conf_files/kdc_conf:files}} \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kdc.conf}} \subsubsection{SEE ALSO} \label{\detokenize{admin/conf_files/kdc_conf:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}, {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}}, {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}} \sphinxstepscope \subsection{kadm5.acl} \label{\detokenize{admin/conf_files/kadm5_acl:kadm5-acl}}\label{\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}}\label{\detokenize{admin/conf_files/kadm5_acl::doc}} \subsubsection{DESCRIPTION} \label{\detokenize{admin/conf_files/kadm5_acl:description}} \sphinxAtStartPar The Kerberos {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} daemon uses an Access Control List (ACL) file to manage access rights to the Kerberos database. For operations that affect principals, the ACL file also controls which principals can operate on which other principals. \sphinxAtStartPar The default location of the Kerberos ACL file is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kadm5.acl}} unless this is overridden by the \sphinxstyleemphasis{acl\_file} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \subsubsection{SYNTAX} \label{\detokenize{admin/conf_files/kadm5_acl:syntax}} \sphinxAtStartPar Empty lines and lines starting with the sharp sign (\sphinxcode{\sphinxupquote{\#}}) are ignored. Lines containing ACL entries have the format: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{principal} \PYG{n}{permissions} \PYG{p}{[}\PYG{n}{target\PYGZus{}principal} \PYG{p}{[}\PYG{n}{restrictions}\PYG{p}{]} \PYG{p}{]} \end{sphinxVerbatim} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar Line order in the ACL file is important. The first matching entry will control access for an actor principal on a target principal. \end{sphinxadmonition} \begin{description} \sphinxlineitem{\sphinxstyleemphasis{principal}} \sphinxAtStartPar (Partially or fully qualified Kerberos principal name.) Specifies the principal whose permissions are to be set. \sphinxAtStartPar Each component of the name may be wildcarded using the \sphinxcode{\sphinxupquote{*}} character. \sphinxlineitem{\sphinxstyleemphasis{permissions}} \sphinxAtStartPar Specifies what operations may or may not be performed by a \sphinxstyleemphasis{principal} matching a particular entry. This is a string of one or more of the following list of characters or their upper\sphinxhyphen{}case counterparts. If the character is \sphinxstyleemphasis{upper\sphinxhyphen{}case}, then the operation is disallowed. If the character is \sphinxstyleemphasis{lower\sphinxhyphen{}case}, then the operation is permitted. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar a & \sphinxAtStartPar {[}Dis{]}allows the addition of principals or policies \\ \sphinxhline \sphinxAtStartPar c & \sphinxAtStartPar {[}Dis{]}allows the changing of passwords for principals \\ \sphinxhline \sphinxAtStartPar d & \sphinxAtStartPar {[}Dis{]}allows the deletion of principals or policies \\ \sphinxhline \sphinxAtStartPar e & \sphinxAtStartPar {[}Dis{]}allows the extraction of principal keys \\ \sphinxhline \sphinxAtStartPar i & \sphinxAtStartPar {[}Dis{]}allows inquiries about principals or policies \\ \sphinxhline \sphinxAtStartPar l & \sphinxAtStartPar {[}Dis{]}allows the listing of all principals or policies \\ \sphinxhline \sphinxAtStartPar m & \sphinxAtStartPar {[}Dis{]}allows the modification of principals or policies \\ \sphinxhline \sphinxAtStartPar p & \sphinxAtStartPar {[}Dis{]}allows the propagation of the principal database (used in {\hyperref[\detokenize{admin/database:incr-db-prop}]{\sphinxcrossref{\DUrole{std,std-ref}{Incremental database propagation}}}}) \\ \sphinxhline \sphinxAtStartPar s & \sphinxAtStartPar {[}Dis{]}allows the explicit setting of the key for a principal \\ \sphinxhline \sphinxAtStartPar x & \sphinxAtStartPar Short for admcilsp. All privileges (except \sphinxcode{\sphinxupquote{e}}) \\ \sphinxhline \sphinxAtStartPar * & \sphinxAtStartPar Same as x. \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \end{description} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The \sphinxcode{\sphinxupquote{extract}} privilege is not included in the wildcard privilege; it must be explicitly assigned. This privilege allows the user to extract keys from the database, and must be handled with great care to avoid disclosure of important keys like those of the kadmin/* or krbtgt/* principals. The \sphinxstylestrong{lockdown\_keys} principal attribute can be used to prevent key extraction from specific principals regardless of the granted privilege. \end{sphinxadmonition} \begin{description} \sphinxlineitem{\sphinxstyleemphasis{target\_principal}} \sphinxAtStartPar (Optional. Partially or fully qualified Kerberos principal name.) Specifies the principal on which \sphinxstyleemphasis{permissions} may be applied. Each component of the name may be wildcarded using the \sphinxcode{\sphinxupquote{*}} character. \sphinxAtStartPar \sphinxstyleemphasis{target\_principal} can also include back\sphinxhyphen{}references to \sphinxstyleemphasis{principal}, in which \sphinxcode{\sphinxupquote{*number}} matches the corresponding wildcard in \sphinxstyleemphasis{principal}. \sphinxlineitem{\sphinxstyleemphasis{restrictions}} \sphinxAtStartPar (Optional) A string of flags. Allowed restrictions are: \begin{quote} \begin{description} \sphinxlineitem{\{+|\sphinxhyphen{}\}\sphinxstyleemphasis{flagname}} \sphinxAtStartPar flag is forced to the indicated value. The permissible flags are the same as those for the \sphinxstylestrong{default\_principal\_flags} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \sphinxlineitem{\sphinxstyleemphasis{\sphinxhyphen{}clearpolicy}} \sphinxAtStartPar policy is forced to be empty. \sphinxlineitem{\sphinxstyleemphasis{\sphinxhyphen{}policy pol}} \sphinxAtStartPar policy is forced to be \sphinxstyleemphasis{pol}. \sphinxlineitem{\sphinxhyphen{}\{\sphinxstyleemphasis{expire, pwexpire, maxlife, maxrenewlife}\} \sphinxstyleemphasis{time}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{getdate} string) associated value will be forced to MIN(\sphinxstyleemphasis{time}, requested value). \end{description} \end{quote} \sphinxAtStartPar The above flags act as restrictions on any add or modify operation which is allowed due to that ACL line. \end{description} \begin{sphinxadmonition}{warning}{Warning:} \sphinxAtStartPar If the kadmind ACL file is modified, the kadmind daemon needs to be restarted for changes to take effect. \end{sphinxadmonition} \subsubsection{EXAMPLE} \label{\detokenize{admin/conf_files/kadm5_acl:example}} \sphinxAtStartPar Here is an example of a kadm5.acl file: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{o}{*}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{*} \PYG{c+c1}{\PYGZsh{} line 1} \PYG{n}{joeadmin}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{ADMCIL} \PYG{c+c1}{\PYGZsh{} line 2} \PYG{n}{joeadmin}\PYG{o}{/}\PYG{o}{*}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{i} \PYG{o}{*}\PYG{o}{/}\PYG{n}{root}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{c+c1}{\PYGZsh{} line 3} \PYG{o}{*}\PYG{o}{/}\PYG{n}{root}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{ci} \PYG{o}{*}\PYG{l+m+mi}{1}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{c+c1}{\PYGZsh{} line 4} \PYG{o}{*}\PYG{o}{/}\PYG{n}{root}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{l} \PYG{o}{*} \PYG{c+c1}{\PYGZsh{} line 5} \PYG{n}{sms}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{x} \PYG{o}{*} \PYG{o}{\PYGZhy{}}\PYG{n}{maxlife} \PYG{l+m+mi}{9}\PYG{n}{h} \PYG{o}{\PYGZhy{}}\PYG{n}{postdateable} \PYG{c+c1}{\PYGZsh{} line 6} \end{sphinxVerbatim} \sphinxAtStartPar (line 1) Any principal in the \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} realm with an \sphinxcode{\sphinxupquote{admin}} instance has all administrative privileges except extracting keys. \sphinxAtStartPar (lines 1\sphinxhyphen{}3) The user \sphinxcode{\sphinxupquote{joeadmin}} has all permissions except extracting keys with his \sphinxcode{\sphinxupquote{admin}} instance, \sphinxcode{\sphinxupquote{joeadmin/admin@ATHENA.MIT.EDU}} (matches line 1). He has no permissions at all with his null instance, \sphinxcode{\sphinxupquote{joeadmin@ATHENA.MIT.EDU}} (matches line 2). His \sphinxcode{\sphinxupquote{root}} and other non\sphinxhyphen{}\sphinxcode{\sphinxupquote{admin}}, non\sphinxhyphen{}null instances (e.g., \sphinxcode{\sphinxupquote{extra}} or \sphinxcode{\sphinxupquote{dbadmin}}) have inquire permissions with any principal that has the instance \sphinxcode{\sphinxupquote{root}} (matches line 3). \sphinxAtStartPar (line 4) Any \sphinxcode{\sphinxupquote{root}} principal in \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} can inquire or change the password of their null instance, but not any other null instance. (Here, \sphinxcode{\sphinxupquote{*1}} denotes a back\sphinxhyphen{}reference to the component matching the first wildcard in the actor principal.) \sphinxAtStartPar (line 5) Any \sphinxcode{\sphinxupquote{root}} principal in \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} can generate the list of principals in the database, and the list of policies in the database. This line is separate from line 4, because list permission can only be granted globally, not to specific target principals. \sphinxAtStartPar (line 6) Finally, the Service Management System principal \sphinxcode{\sphinxupquote{sms@ATHENA.MIT.EDU}} has all permissions except extracting keys, but any principal that it creates or modifies will not be able to get postdateable tickets or tickets with a life of longer than 9 hours. \subsubsection{MODULE BEHAVIOR} \label{\detokenize{admin/conf_files/kadm5_acl:module-behavior}} \sphinxAtStartPar The ACL file can coexist with other authorization modules in release 1.16 and later, as configured in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:kadm5-auth}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5\_auth interface}}}} section of {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. The ACL file will positively authorize operations according to the rules above, but will never authoritatively deny an operation, so other modules can authorize operations in addition to those authorized by the ACL file. \sphinxAtStartPar To operate without an ACL file, set the \sphinxstyleemphasis{acl\_file} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} to the empty string with \sphinxcode{\sphinxupquote{acl\_file = ""}}. \subsubsection{SEE ALSO} \label{\detokenize{admin/conf_files/kadm5_acl:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}, {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} \sphinxstepscope \chapter{Realm configuration decisions} \label{\detokenize{admin/realm_config:realm-configuration-decisions}}\label{\detokenize{admin/realm_config::doc}} \sphinxAtStartPar Before installing Kerberos V5, it is necessary to consider the following issues: \begin{itemize} \item {} \sphinxAtStartPar The name of your Kerberos realm (or the name of each realm, if you need more than one). \item {} \sphinxAtStartPar How you will assign your hostnames to Kerberos realms. \item {} \sphinxAtStartPar Which ports your KDC and and kadmind services will use, if they will not be using the default ports. \item {} \sphinxAtStartPar How many replica KDCs you need and where they should be located. \item {} \sphinxAtStartPar The hostnames of your primary and replica KDCs. \item {} \sphinxAtStartPar How frequently you will propagate the database from the primary KDC to the replica KDCs. \end{itemize} \section{Realm name} \label{\detokenize{admin/realm_config:realm-name}} \sphinxAtStartPar Although your Kerberos realm can be any ASCII string, convention is to make it the same as your domain name, in upper\sphinxhyphen{}case letters. \sphinxAtStartPar For example, hosts in the domain \sphinxcode{\sphinxupquote{example.com}} would be in the Kerberos realm: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \end{sphinxVerbatim} \sphinxAtStartPar If you need multiple Kerberos realms, MIT recommends that you use descriptive names which end with your domain name, such as: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{BOSTON}\PYG{o}{.}\PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{HOUSTON}\PYG{o}{.}\PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \end{sphinxVerbatim} \section{Mapping hostnames onto Kerberos realms} \label{\detokenize{admin/realm_config:mapping-hostnames-onto-kerberos-realms}}\label{\detokenize{admin/realm_config:mapping-hostnames}} \sphinxAtStartPar Mapping hostnames onto Kerberos realms is done in one of three ways. \sphinxAtStartPar The first mechanism works through a set of rules in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:domain-realm}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}domain\_realm{]}}}}} section of {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. You can specify mappings for an entire domain or on a per\sphinxhyphen{}hostname basis. Typically you would do this by specifying the mappings for a given domain or subdomain and listing the exceptions. \sphinxAtStartPar The second mechanism is to use KDC host\sphinxhyphen{}based service referrals. With this method, the KDC’s krb5.conf has a full {[}domain\_realm{]} mapping for hosts, but the clients do not, or have mappings for only a subset of the hosts they might contact. When a client needs to contact a server host for which it has no mapping, it will ask the client realm’s KDC for the service ticket, and will receive a referral to the appropriate service realm. \sphinxAtStartPar To use referrals, clients must be running MIT krb5 1.6 or later, and the KDC must be running MIT krb5 1.7 or later. The \sphinxstylestrong{host\_based\_services} and \sphinxstylestrong{no\_host\_referral} variables in the {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} section of {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} can be used to fine\sphinxhyphen{}tune referral behavior on the KDC. \sphinxAtStartPar It is also possible for clients to use DNS TXT records, if \sphinxstylestrong{dns\_lookup\_realm} is enabled in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. Such lookups are disabled by default because DNS is an insecure protocol and security holes could result if DNS records are spoofed. If enabled, the client will try to look up a TXT record formed by prepending the prefix \sphinxcode{\sphinxupquote{\_kerberos}} to the hostname in question. If that record is not found, the client will attempt a lookup by prepending \sphinxcode{\sphinxupquote{\_kerberos}} to the host’s domain name, then its parent domain, up to the top\sphinxhyphen{}level domain. For the hostname \sphinxcode{\sphinxupquote{boston.engineering.example.com}}, the names looked up would be: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{\PYGZus{}kerberos}\PYG{o}{.}\PYG{n}{boston}\PYG{o}{.}\PYG{n}{engineering}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{n}{\PYGZus{}kerberos}\PYG{o}{.}\PYG{n}{engineering}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{n}{\PYGZus{}kerberos}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{n}{\PYGZus{}kerberos}\PYG{o}{.}\PYG{n}{com} \end{sphinxVerbatim} \sphinxAtStartPar The value of the first TXT record found is taken as the realm name. \sphinxAtStartPar Even if you do not choose to use this mechanism within your site, you may wish to set it up anyway, for use when interacting with other sites. \section{Ports for the KDC and admin services} \label{\detokenize{admin/realm_config:ports-for-the-kdc-and-admin-services}} \sphinxAtStartPar The default ports used by Kerberos are port 88 for the KDC and port 749 for the admin server. You can, however, choose to run on other ports, as long as they are specified in each host’s {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} files or in DNS SRV records, and the {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} file on each KDC. For a more thorough treatment of port numbers used by the Kerberos V5 programs, refer to the {\hyperref[\detokenize{admin/appl_servers:conf-firewall}]{\sphinxcrossref{\DUrole{std,std-ref}{Configuring your firewall to work with Kerberos V5}}}}. \section{Replica KDCs} \label{\detokenize{admin/realm_config:replica-kdcs}} \sphinxAtStartPar Replica KDCs provide an additional source of Kerberos ticket\sphinxhyphen{}granting services in the event of inaccessibility of the primary KDC. The number of replica KDCs you need and the decision of where to place them, both physically and logically, depends on the specifics of your network. \sphinxAtStartPar Kerberos authentication requires that each client be able to contact a KDC. Therefore, you need to anticipate any likely reason a KDC might be unavailable and have a replica KDC to take up the slack. \sphinxAtStartPar Some considerations include: \begin{itemize} \item {} \sphinxAtStartPar Have at least one replica KDC as a backup, for when the primary KDC is down, is being upgraded, or is otherwise unavailable. \item {} \sphinxAtStartPar If your network is split such that a network outage is likely to cause a network partition (some segment or segments of the network to become cut off or isolated from other segments), have a replica KDC accessible to each segment. \item {} \sphinxAtStartPar If possible, have at least one replica KDC in a different building from the primary, in case of power outages, fires, or other localized disasters. \end{itemize} \section{Hostnames for KDCs} \label{\detokenize{admin/realm_config:hostnames-for-kdcs}}\label{\detokenize{admin/realm_config:kdc-hostnames}} \sphinxAtStartPar MIT recommends that your KDCs have a predefined set of CNAME records (DNS hostname aliases), such as \sphinxcode{\sphinxupquote{kerberos}} for the primary KDC and \sphinxcode{\sphinxupquote{kerberos\sphinxhyphen{}1}}, \sphinxcode{\sphinxupquote{kerberos\sphinxhyphen{}2}}, … for the replica KDCs. This way, if you need to swap a machine, you only need to change a DNS entry, rather than having to change hostnames. \sphinxAtStartPar As of MIT krb5 1.4, clients can locate a realm’s KDCs through DNS using SRV records (\index{RFC@\spxentry{RFC}!RFC 2782@\spxentry{RFC 2782}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc2782.html}{\sphinxstylestrong{RFC 2782}}), assuming the Kerberos realm name is also a DNS domain name. These records indicate the hostname and port number to contact for that service, optionally with weighting and prioritization. The domain name used in the SRV record name is the realm name. Several different Kerberos\sphinxhyphen{}related service names are used: \begin{description} \sphinxlineitem{\_kerberos.\_udp} \sphinxAtStartPar This is for contacting any KDC by UDP. This entry will be used the most often. Normally you should list port 88 on each of your KDCs. \sphinxlineitem{\_kerberos.\_tcp} \sphinxAtStartPar This is for contacting any KDC by TCP. Normally you should use port 88. This entry should be omitted if the KDC does not listen on TCP ports, as was the default prior to release 1.13. \sphinxlineitem{\_kerberos\sphinxhyphen{}master.\_udp} \sphinxAtStartPar This entry should refer to those KDCs, if any, that will immediately see password changes to the Kerberos database. If a user is logging in and the password appears to be incorrect, the client will retry with the primary KDC before failing with an “incorrect password†error given. \sphinxAtStartPar If you have only one KDC, or for whatever reason there is no accessible KDC that would get database changes faster than the others, you do not need to define this entry. \sphinxlineitem{\_kerberos\sphinxhyphen{}adm.\_tcp} \sphinxAtStartPar This should list port 749 on your primary KDC. Support for it is not complete at this time, but it will eventually be used by the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} program and related utilities. For now, you will also need the \sphinxstylestrong{admin\_server} variable in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. \sphinxlineitem{\_kerberos\sphinxhyphen{}master.\_tcp} \sphinxAtStartPar The corresponding TCP port for \_kerberos\sphinxhyphen{}master.\_udp, assuming the primary KDC listens on a TCP port. \sphinxlineitem{\_kpasswd.\_udp} \sphinxAtStartPar This entry should list port 464 on your primary KDC. It is used when a user changes her password. If this entry is not defined but a \_kerberos\sphinxhyphen{}adm.\_tcp entry is defined, the client will use the \_kerberos\sphinxhyphen{}adm.\_tcp entry with the port number changed to 464. \sphinxlineitem{\_kpasswd.\_tcp} \sphinxAtStartPar The corresponding TCP port for \_kpasswd.\_udp. \end{description} \sphinxAtStartPar The DNS SRV specification requires that the hostnames listed be the canonical names, not aliases. So, for example, you might include the following records in your (BIND\sphinxhyphen{}style) zone file: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{}ORIGIN foobar.com. \PYGZus{}kerberos TXT \PYGZdq{}FOOBAR.COM\PYGZdq{} kerberos CNAME daisy kerberos\PYGZhy{}1 CNAME use\PYGZhy{}the\PYGZhy{}force\PYGZhy{}luke kerberos\PYGZhy{}2 CNAME bunny\PYGZhy{}rabbit \PYGZus{}kerberos.\PYGZus{}udp SRV 0 0 88 daisy SRV 0 0 88 use\PYGZhy{}the\PYGZhy{}force\PYGZhy{}luke SRV 0 0 88 bunny\PYGZhy{}rabbit \PYGZus{}kerberos\PYGZhy{}master.\PYGZus{}udp SRV 0 0 88 daisy \PYGZus{}kerberos\PYGZhy{}adm.\PYGZus{}tcp SRV 0 0 749 daisy \PYGZus{}kpasswd.\PYGZus{}udp SRV 0 0 464 daisy \end{sphinxVerbatim} \sphinxAtStartPar Clients can also be configured with the explicit location of services using the \sphinxstylestrong{kdc}, \sphinxstylestrong{master\_kdc}, \sphinxstylestrong{admin\_server}, and \sphinxstylestrong{kpasswd\_server} variables in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} section of {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. Even if some clients will be configured with explicit server locations, providing SRV records will still benefit unconfigured clients, and be useful for other sites. \sphinxAtStartPar Clients can be configured with the \sphinxstylestrong{sitename} realm variable (new in release 1.22). If a site name is set, the client first attempts SRV record lookups with “.*sitename*.\_sites†inserted after the service and protocol name and before the Kerberos realm. Site\sphinxhyphen{}specific records may indicate servers more proximal to the client, allowing for faster access. \section{KDC Discovery} \label{\detokenize{admin/realm_config:kdc-discovery}}\label{\detokenize{admin/realm_config:id1}} \sphinxAtStartPar As of MIT krb5 1.15, clients can also locate KDCs in DNS through URI records (\index{RFC@\spxentry{RFC}!RFC 7553@\spxentry{RFC 7553}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc7553.html}{\sphinxstylestrong{RFC 7553}}). Limitations with the SRV record format may result in extra DNS queries in situations where a client must failover to other transport types, or find a primary server. The URI record can convey more information about a realm’s KDCs with a single query. \sphinxAtStartPar The client performs a query for the following URI records: \begin{itemize} \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{\_kerberos.REALM}} for finding KDCs. \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{\_kerberos\sphinxhyphen{}adm.REALM}} for finding kadmin services. \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{\_kpasswd.REALM}} for finding password services. \end{itemize} \sphinxAtStartPar The URI record includes a priority, weight, and a URI string that consists of case\sphinxhyphen{}insensitive colon separated fields, in the form \sphinxcode{\sphinxupquote{scheme:{[}flags{]}:transport:residual}}. \begin{itemize} \item {} \sphinxAtStartPar \sphinxstyleemphasis{scheme} defines the registered URI type. It should always be \sphinxcode{\sphinxupquote{krb5srv}}. \item {} \sphinxAtStartPar \sphinxstyleemphasis{flags} contains zero or more flag characters. Currently the only valid flag is \sphinxcode{\sphinxupquote{m}}, which indicates that the record is for a primary server. \item {} \sphinxAtStartPar \sphinxstyleemphasis{transport} defines the transport type of the residual URL or address. Accepted values are \sphinxcode{\sphinxupquote{tcp}}, \sphinxcode{\sphinxupquote{udp}}, or \sphinxcode{\sphinxupquote{kkdcp}} for the MS\sphinxhyphen{}KKDCP type. \item {} \sphinxAtStartPar \sphinxstyleemphasis{residual} contains the hostname, IP address, or URL to be contacted using the specified transport, with an optional port extension. The MS\sphinxhyphen{}KKDCP transport type uses a HTTPS URL, and can include a port and/or path extension. \end{itemize} \sphinxAtStartPar An example of URI records in a zone file: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{\PYGZus{}kerberos}\PYG{o}{.}\PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{URI} \PYG{l+m+mi}{10} \PYG{l+m+mi}{1} \PYG{n}{krb5srv}\PYG{p}{:}\PYG{n}{m}\PYG{p}{:}\PYG{n}{tcp}\PYG{p}{:}\PYG{n}{kdc1}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{n}{URI} \PYG{l+m+mi}{20} \PYG{l+m+mi}{1} \PYG{n}{krb5srv}\PYG{p}{:}\PYG{n}{m}\PYG{p}{:}\PYG{n}{udp}\PYG{p}{:}\PYG{n}{kdc2}\PYG{o}{.}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com}\PYG{p}{:}\PYG{l+m+mi}{89} \PYG{n}{URI} \PYG{l+m+mi}{40} \PYG{l+m+mi}{1} \PYG{n}{krb5srv}\PYG{p}{:}\PYG{p}{:}\PYG{n}{udp}\PYG{p}{:}\PYG{l+m+mf}{10.10}\PYG{l+m+mf}{.0}\PYG{l+m+mf}{.23} \PYG{n}{URI} \PYG{l+m+mi}{30} \PYG{l+m+mi}{1} \PYG{n}{krb5srv}\PYG{p}{:}\PYG{p}{:}\PYG{n}{kkdcp}\PYG{p}{:}\PYG{n}{https}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{proxy}\PYG{p}{:}\PYG{l+m+mi}{89}\PYG{o}{/}\PYG{n}{auth} \end{sphinxVerbatim} \sphinxAtStartPar URI lookups are enabled by default, and can be disabled by setting \sphinxstylestrong{dns\_uri\_lookup} in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}} section of {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} to False. When enabled, URI lookups take precedence over SRV lookups, falling back to SRV lookups if no URI records are found. \sphinxAtStartPar The \sphinxstylestrong{sitename} variable in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} section of {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} applies to URI lookups as well as SRV lookups. \section{Database propagation} \label{\detokenize{admin/realm_config:database-propagation}}\label{\detokenize{admin/realm_config:db-prop}} \sphinxAtStartPar The Kerberos database resides on the primary KDC, and must be propagated regularly (usually by a cron job) to the replica KDCs. In deciding how frequently the propagation should happen, you will need to balance the amount of time the propagation takes against the maximum reasonable amount of time a user should have to wait for a password change to take effect. \sphinxAtStartPar If the propagation time is longer than this maximum reasonable time (e.g., you have a particularly large database, you have a lot of replicas, or you experience frequent network delays), you may wish to cut down on your propagation delay by performing the propagation in parallel. To do this, have the primary KDC propagate the database to one set of replicas, and then have each of these replicas propagate the database to additional replicas. \sphinxAtStartPar See also {\hyperref[\detokenize{admin/database:incr-db-prop}]{\sphinxcrossref{\DUrole{std,std-ref}{Incremental database propagation}}}} \sphinxstepscope \chapter{Database administration} \label{\detokenize{admin/database:database-administration}}\label{\detokenize{admin/database::doc}} \sphinxAtStartPar A Kerberos database contains all of a realm’s Kerberos principals, their passwords, and other administrative information about each principal. For the most part, you will use the {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} program to manipulate the Kerberos database as a whole, and the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} program to make changes to the entries in the database. (One notable exception is that users will use the \DUrole{xref,std,std-ref}{kpasswd(1)} program to change their own passwords.) The kadmin program has its own command\sphinxhyphen{}line interface, to which you type the database administrating commands. \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} provides a means to create, delete, load, or dump a Kerberos database. It also contains commands to roll over the database master key, and to stash a copy of the key so that the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} and {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} daemons can use the database without manual input. \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} provides for the maintenance of Kerberos principals, password policies, and service key tables (keytabs). Normally it operates as a network client using Kerberos authentication to communicate with {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}}, but there is also a variant, named kadmin.local, which directly accesses the Kerberos database on the local filesystem (or through LDAP). kadmin.local is necessary to set up enough of the database to be able to use the remote version. \sphinxAtStartPar kadmin can authenticate to the admin server using the service principal \sphinxcode{\sphinxupquote{kadmin/admin}} or \sphinxcode{\sphinxupquote{kadmin/HOST}} (where \sphinxstyleemphasis{HOST} is the hostname of the admin server). If the credentials cache contains a ticket for either service principal and the \sphinxstylestrong{\sphinxhyphen{}c} ccache option is specified, that ticket is used to authenticate to KADM5. Otherwise, the \sphinxstylestrong{\sphinxhyphen{}p} and \sphinxstylestrong{\sphinxhyphen{}k} options are used to specify the client Kerberos principal name used to authenticate. Once kadmin has determined the principal name, it requests a \sphinxcode{\sphinxupquote{kadmin/admin}} Kerberos service ticket from the KDC, and uses that service ticket to authenticate to KADM5. \sphinxAtStartPar See {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} for the available kadmin and kadmin.local commands and options. \section{Principals} \label{\detokenize{admin/database:principals}}\label{\detokenize{admin/database:id1}} \sphinxAtStartPar Each entry in the Kerberos database contains a Kerberos principal and the attributes and policies associated with that principal. \sphinxAtStartPar To add a principal to the database, use the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} \sphinxstylestrong{add\_principal} command. User principals should usually be created with the \sphinxcode{\sphinxupquote{+requires\_preauth \sphinxhyphen{}allow\_svr}} options to help mitigate dictionary attacks (see {\hyperref[\detokenize{admin/dictionary:dictionary}]{\sphinxcrossref{\DUrole{std,std-ref}{Addressing dictionary attack risks}}}}): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{addprinc} \PYG{o}{+}\PYG{n}{requires\PYGZus{}preauth} \PYG{o}{\PYGZhy{}}\PYG{n}{allow\PYGZus{}svr} \PYG{n}{alice} \PYG{n}{Enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{alice@KRBTEST.COM}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{n}{Re}\PYG{o}{\PYGZhy{}}\PYG{n}{enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{alice@KRBTEST.COM}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \end{sphinxVerbatim} \sphinxAtStartPar User principals which will authenticate with {\hyperref[\detokenize{admin/pkinit:pkinit}]{\sphinxcrossref{\DUrole{std,std-ref}{PKINIT configuration}}}} should instead by created with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}nokey}} option: \begin{quote} \sphinxAtStartPar kadmin: addprinc \sphinxhyphen{}nokey alice \end{quote} \sphinxAtStartPar Service principals can be created with the \sphinxcode{\sphinxupquote{\sphinxhyphen{}nokey}} option; long\sphinxhyphen{}term keys will be added when a keytab is generated: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{addprinc} \PYG{o}{\PYGZhy{}}\PYG{n}{nokey} \PYG{n}{host}\PYG{o}{/}\PYG{n}{foo}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{ktadd} \PYG{o}{\PYGZhy{}}\PYG{n}{k} \PYG{n}{foo}\PYG{o}{.}\PYG{n}{keytab} \PYG{n}{host}\PYG{o}{/}\PYG{n}{foo}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{foo}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{n}{foo}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{foo}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{n}{foo}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar To modify attributes of an existing principal, use the kadmin \sphinxstylestrong{modify\_principal} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{modprinc} \PYG{o}{\PYGZhy{}}\PYG{n}{expire} \PYG{n}{tomorrow} \PYG{n}{alice} \PYG{n}{Principal} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{alice@KRBTEST.COM}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{modified}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar To delete a principal, use the kadmin \sphinxstylestrong{delete\_principal} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] kadmin: delprinc alice Are you sure you want to delete the principal \PYGZdq{}alice@KRBTEST.COM\PYGZdq{}? (yes/no): yes Principal \PYGZdq{}alice@KRBTEST.COM\PYGZdq{} deleted. Make sure that you have removed this principal from all ACLs before reusing. \end{sphinxVerbatim} \sphinxAtStartPar To change a principal’s password, use the kadmin \sphinxstylestrong{change\_password} command. Password changes made through kadmin are subject to the same password policies as would apply to password changes made through \DUrole{xref,std,std-ref}{kpasswd(1)}. \sphinxAtStartPar To view the attributes of a principal, use the kadmin\textasciigrave{} \sphinxstylestrong{get\_principal} command. \sphinxAtStartPar To generate a listing of principals, use the kadmin \sphinxstylestrong{list\_principals} command. \sphinxAtStartPar To give a principal additional names, use the kadmin \sphinxstylestrong{add\_alias} command to create aliases to the principal (new in release 1.22). Aliases can be removed with the \sphinxstylestrong{delete\_principal} command. \section{Policies} \label{\detokenize{admin/database:policies}}\label{\detokenize{admin/database:id2}} \sphinxAtStartPar A policy is a set of rules governing passwords. Policies can dictate minimum and maximum password lifetimes, minimum number of characters and character classes a password must contain, and the number of old passwords kept in the database. \sphinxAtStartPar To add a new policy, use the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} \sphinxstylestrong{add\_policy} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{addpol} \PYG{o}{\PYGZhy{}}\PYG{n}{maxlife} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{1 year}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{\PYGZhy{}}\PYG{n}{history} \PYG{l+m+mi}{3} \PYG{n}{stduser} \end{sphinxVerbatim} \sphinxAtStartPar To modify attributes of a principal, use the kadmin \sphinxstylestrong{modify\_policy} command. To delete a policy, use the kadmin \sphinxstylestrong{delete\_policy} command. \sphinxAtStartPar To associate a policy with a principal, use the kadmin \sphinxstylestrong{modify\_principal} command with the \sphinxstylestrong{\sphinxhyphen{}policy} option: \begin{quote} \sphinxAtStartPar kadmin: modprinc \sphinxhyphen{}policy stduser alice Principal “\sphinxhref{mailto:alice@KRBTEST.COM}{alice@KRBTEST.COM}†modified. \end{quote} \sphinxAtStartPar A principal entry may be associated with a nonexistent policy, either because the policy did not exist at the time of associated or was deleted afterwards. kadmin will warn when associated a principal with a nonexistent policy, and will annotate the policy name with “{[}does not exist{]}†in the \sphinxstylestrong{get\_principal} output. \subsection{Updating the history key} \label{\detokenize{admin/database:updating-the-history-key}}\label{\detokenize{admin/database:updating-history-key}} \sphinxAtStartPar If a policy specifies a number of old keys kept of two or more, the stored old keys are encrypted in a history key, which is found in the key data of the \sphinxcode{\sphinxupquote{kadmin/history}} principal. \sphinxAtStartPar Currently there is no support for proper rollover of the history key, but you can change the history key (for example, to use a better encryption type) at the cost of invalidating currently stored old keys. To change the history key, run: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{change\PYGZus{}password} \PYG{o}{\PYGZhy{}}\PYG{n}{randkey} \PYG{n}{kadmin}\PYG{o}{/}\PYG{n}{history} \end{sphinxVerbatim} \sphinxAtStartPar This command will fail if you specify the \sphinxstylestrong{\sphinxhyphen{}keepold} flag. Only one new history key will be created, even if you specify multiple key/salt combinations. \sphinxAtStartPar In the future, we plan to migrate towards encrypting old keys in the master key instead of the history key, and implementing proper rollover support for stored old keys. \section{Privileges} \label{\detokenize{admin/database:privileges}}\label{\detokenize{admin/database:id3}} \sphinxAtStartPar Administrative privileges for the Kerberos database are stored in the file {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}}. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar A common use of an admin instance is so you can grant separate permissions (such as administrator access to the Kerberos database) to a separate Kerberos principal. For example, the user \sphinxcode{\sphinxupquote{joeadmin}} might have a principal for his administrative use, called \sphinxcode{\sphinxupquote{joeadmin/admin}}. This way, \sphinxcode{\sphinxupquote{joeadmin}} would obtain \sphinxcode{\sphinxupquote{joeadmin/admin}} tickets only when he actually needs to use those permissions. \end{sphinxadmonition} \section{Operations on the Kerberos database} \label{\detokenize{admin/database:operations-on-the-kerberos-database}}\label{\detokenize{admin/database:db-operations}} \sphinxAtStartPar The {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} command is the primary tool for administrating the Kerberos database when using the DB2 or LMDB modules (see {\hyperref[\detokenize{admin/dbtypes:dbtypes}]{\sphinxcrossref{\DUrole{std,std-ref}{Database types}}}}). Creating a database is described in {\hyperref[\detokenize{admin/install_kdc:create-db}]{\sphinxcrossref{\DUrole{std,std-ref}{Create the KDC database}}}}. \sphinxAtStartPar To create a stash file using the master password (because the database was not created with one using the \sphinxcode{\sphinxupquote{create \sphinxhyphen{}s}} flag, or after restoring from a backup which did not contain the stash file), use the kdb5\_util \sphinxstylestrong{stash} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}util stash kdb5\PYGZus{}util: Cannot find/read stored master key while reading master key kdb5\PYGZus{}util: Warning: proceeding without master key Enter KDC database master key: \PYGZlt{}= Type the KDC database master password. \end{sphinxVerbatim} \sphinxAtStartPar To destroy a database, use the kdb5\_util destroy command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}util destroy Deleting KDC database stored in \PYGZsq{}/var/krb5kdc/principal\PYGZsq{}, are you sure? (type \PYGZsq{}yes\PYGZsq{} to confirm)? yes OK, deleting database \PYGZsq{}/var/krb5kdc/principal\PYGZsq{}... ** Database \PYGZsq{}/var/krb5kdc/principal\PYGZsq{} destroyed. \end{sphinxVerbatim} \subsection{Dumping and loading a Kerberos database} \label{\detokenize{admin/database:dumping-and-loading-a-kerberos-database}}\label{\detokenize{admin/database:restore-from-dump}} \sphinxAtStartPar To dump a Kerberos database into a text file for backup or transfer purposes, use the {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} \sphinxstylestrong{dump} command on one of the KDCs: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}util dump dumpfile \PYGZdl{} kbd5\PYGZus{}util dump \PYGZhy{}verbose dumpfile kadmin/admin@ATHENA.MIT.EDU krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU kadmin/history@ATHENA.MIT.EDU K/M@ATHENA.MIT.EDU kadmin/changepw@ATHENA.MIT.EDU \end{sphinxVerbatim} \sphinxAtStartPar You may specify which principals to dump, using full principal names including realm: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}util dump \PYGZhy{}verbose someprincs K/M@ATHENA.MIT.EDU kadmin/admin@ATHENA.MIT.EDU kadmin/admin@ATHENA.MIT.EDU K/M@ATHENA.MIT.EDU \end{sphinxVerbatim} \sphinxAtStartPar To restore a Kerberos database dump from a file, use the {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} \sphinxstylestrong{load} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}util load dumpfile \end{sphinxVerbatim} \sphinxAtStartPar To update an existing database with a partial dump file containing only some principals, use the \sphinxcode{\sphinxupquote{\sphinxhyphen{}update}} flag: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}util load \PYGZhy{}update someprincs \end{sphinxVerbatim} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar If the database file exists, and the \sphinxstyleemphasis{\sphinxhyphen{}update} flag was not given, \sphinxstyleemphasis{kdb5\_util} will overwrite the existing database. \end{sphinxadmonition} \subsection{Updating the master key} \label{\detokenize{admin/database:updating-the-master-key}}\label{\detokenize{admin/database:updating-master-key}} \sphinxAtStartPar Starting with release 1.7, {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} allows the master key to be changed using a rollover process, with minimal loss of availability. To roll over the master key, follow these steps: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar On the primary KDC, run \sphinxcode{\sphinxupquote{kdb5\_util list\_mkeys}} to view the current master key version number (KVNO). If you have never rolled over the master key before, this will likely be version 1: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}util list\PYGZus{}mkeys Master keys for Principal: K/M@KRBTEST.COM KVNO: 1, Enctype: aes256\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha384\PYGZhy{}192, Active on: Thu Jan 01 00:00:00 UTC 1970 * \end{sphinxVerbatim} \item {} \sphinxAtStartPar On the primary KDC, run \sphinxcode{\sphinxupquote{kdb5\_util use\_mkey 1}} to ensure that a master key activation list is present in the database. This step is unnecessary in release 1.11.4 or later, or if the database was initially created with release 1.7 or later. \item {} \sphinxAtStartPar On the primary KDC, run \sphinxcode{\sphinxupquote{kdb5\_util add\_mkey \sphinxhyphen{}s}} to create a new master key and write it to the stash file. Enter a secure password when prompted. If this is the first time you are changing the master key, the new key will have version 2. The new master key will not be used until you make it active. \item {} \sphinxAtStartPar Propagate the database to all replica KDCs, either manually or by waiting until the next scheduled propagation. If you do not have any replica KDCs, you can skip this and the next step. \item {} \sphinxAtStartPar On each replica KDC, run \sphinxcode{\sphinxupquote{kdb5\_util list\_mkeys}} to verify that the new master key is present, and then \sphinxcode{\sphinxupquote{kdb5\_util stash}} to write the new master key to the replica KDC’s stash file. \item {} \sphinxAtStartPar On the primary KDC, run \sphinxcode{\sphinxupquote{kdb5\_util use\_mkey 2}} to begin using the new master key. Replace \sphinxcode{\sphinxupquote{2}} with the version of the new master key, as appropriate. You can optionally specify a date for the new master key to become active; by default, it will become active immediately. Prior to release 1.12, {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} must be restarted for this change to take full effect. \item {} \sphinxAtStartPar On the primary KDC, run \sphinxcode{\sphinxupquote{kdb5\_util update\_princ\_encryption}}. This command will iterate over the database and re\sphinxhyphen{}encrypt all keys in the new master key. If the database is large and uses DB2, the primary KDC will become unavailable while this command runs, but clients should fail over to replica KDCs (if any are present) during this time period. In release 1.13 and later, you can instead run \sphinxcode{\sphinxupquote{kdb5\_util \sphinxhyphen{}x unlockiter update\_princ\_encryption}} to use unlocked iteration; this variant will take longer, but will keep the database available to the KDC and kadmind while it runs. \item {} \sphinxAtStartPar Wait until the above changes have propagated to all replica KDCs and until all running KDC and kadmind processes have serviced requests using updated principal entries. \item {} \sphinxAtStartPar On the primary KDC, run \sphinxcode{\sphinxupquote{kdb5\_util purge\_mkeys}} to clean up the old master key. \end{enumerate} \section{Operations on the LDAP database} \label{\detokenize{admin/database:operations-on-the-ldap-database}}\label{\detokenize{admin/database:ops-on-ldap}} \sphinxAtStartPar The {\hyperref[\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_ldap\_util}}}} command is the primary tool for administrating the Kerberos database when using the LDAP module. Creating an LDAP Kerberos database is describe in {\hyperref[\detokenize{admin/conf_ldap:conf-ldap}]{\sphinxcrossref{\DUrole{std,std-ref}{Configuring Kerberos with OpenLDAP back\sphinxhyphen{}end}}}}. \sphinxAtStartPar To view a list of realms in the LDAP database, use the kdb5\_ldap\_util \sphinxstylestrong{list} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}ldap\PYGZus{}util list KRBTEST.COM \end{sphinxVerbatim} \sphinxAtStartPar To modify the attributes of a realm, use the kdb5\_ldap\_util \sphinxstylestrong{modify} command. For example, to change the default realm’s maximum ticket life: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}ldap\PYGZus{}util modify \PYGZhy{}maxtktlife \PYGZdq{}10 hours\PYGZdq{} \end{sphinxVerbatim} \sphinxAtStartPar To display the attributes of a realm, use the kdb5\_ldap\_util \sphinxstylestrong{view} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}ldap\PYGZus{}util view Realm Name: KRBTEST.COM Maximum Ticket Life: 0 days 00:10:00 \end{sphinxVerbatim} \sphinxAtStartPar To remove a realm from the LDAP database, destroying its contents, use the kdb5\_ldap\_util \sphinxstylestrong{destroy} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}ldap\PYGZus{}util destroy Deleting KDC database of \PYGZsq{}KRBTEST.COM\PYGZsq{}, are you sure? (type \PYGZsq{}yes\PYGZsq{} to confirm)? yes OK, deleting database of \PYGZsq{}KRBTEST.COM\PYGZsq{}... ** Database of \PYGZsq{}KRBTEST.COM\PYGZsq{} destroyed. \end{sphinxVerbatim} \subsection{Ticket Policy operations} \label{\detokenize{admin/database:ticket-policy-operations}} \sphinxAtStartPar Unlike the DB2 and LMDB modules, the LDAP module supports ticket policy objects, which can be associated with principals to restrict maximum ticket lifetimes and set mandatory principal flags. Ticket policy objects are distinct from the password policies described earlier on this page, and are chiefly managed through kdb5\_ldap\_util rather than kadmin. To create a new ticket policy, use the kdb5\_ldap\_util \sphinxstylestrong{create\_policy} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}ldap\PYGZus{}util create\PYGZus{}policy \PYGZhy{}maxrenewlife \PYGZdq{}2 days\PYGZdq{} users \end{sphinxVerbatim} \sphinxAtStartPar To associate a ticket policy with a principal, use the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} \sphinxstylestrong{modify\_principal} (or \sphinxstylestrong{add\_principal}) command with the \sphinxstylestrong{\sphinxhyphen{}x tktpolicy=}\sphinxstyleemphasis{policy} option: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kadmin.local modprinc \PYGZhy{}x tktpolicy=users alice \end{sphinxVerbatim} \sphinxAtStartPar To remove a ticket policy reference from a principal, use the same command with an empty \sphinxstyleemphasis{policy}: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kadmin.local modprinc \PYGZhy{}x tktpolicy= alice \end{sphinxVerbatim} \sphinxAtStartPar To list the existing ticket policy objects, use the kdb5\_ldap\_util \sphinxstylestrong{list\_policy} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}ldap\PYGZus{}util list\PYGZus{}policy users \end{sphinxVerbatim} \sphinxAtStartPar To modify the attributes of a ticket policy object, use the kdb5\_ldap\_util \sphinxstylestrong{modify\_policy} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}ldap\PYGZus{}util modify\PYGZus{}policy \PYGZhy{}allow\PYGZus{}svr +requires\PYGZus{}preauth users \end{sphinxVerbatim} \sphinxAtStartPar To view the attributes of a ticket policy object, use the kdb5\_ldap\_util \sphinxstylestrong{view\_policy} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}ldap\PYGZus{}util view\PYGZus{}policy users Ticket policy: users Maximum renewable life: 2 days 00:00:00 Ticket flags: REQUIRES\PYGZus{}PRE\PYGZus{}AUTH DISALLOW\PYGZus{}SVR \end{sphinxVerbatim} \sphinxAtStartPar To destroy an ticket policy object, use the kdb5\_ldap\_util \sphinxstylestrong{destroy\_policy} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}ldap\PYGZus{}util destroy\PYGZus{}policy users This will delete the policy object \PYGZsq{}users\PYGZsq{}, are you sure? (type \PYGZsq{}yes\PYGZsq{} to confirm)? yes ** policy object \PYGZsq{}users\PYGZsq{} deleted. \end{sphinxVerbatim} \section{Cross\sphinxhyphen{}realm authentication} \label{\detokenize{admin/database:cross-realm-authentication}}\label{\detokenize{admin/database:xrealm-authn}} \sphinxAtStartPar In order for a KDC in one realm to authenticate Kerberos users in a different realm, it must share a key with the KDC in the other realm. In both databases, there must be krbtgt service principals for both realms. For example, if you need to do cross\sphinxhyphen{}realm authentication between the realms \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} and \sphinxcode{\sphinxupquote{EXAMPLE.COM}}, you would need to add the principals \sphinxcode{\sphinxupquote{krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU}} and \sphinxcode{\sphinxupquote{krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM}} to both databases. These principals must all have the same passwords, key version numbers, and encryption types; this may require explicitly setting the key version number with the \sphinxstylestrong{\sphinxhyphen{}kvno} option. \sphinxAtStartPar In the ATHENA.MIT.EDU and EXAMPLE.COM cross\sphinxhyphen{}realm case, the administrators would run the following commands on the KDCs in both realms: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}}\PYG{p}{:} \PYG{n}{kadmin}\PYG{o}{.}\PYG{n}{local} \PYG{o}{\PYGZhy{}}\PYG{n}{e} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{aes256\PYGZhy{}cts:normal}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{addprinc} \PYG{o}{\PYGZhy{}}\PYG{n}{requires\PYGZus{}preauth} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{Enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{:} \PYG{n}{Re}\PYG{o}{\PYGZhy{}}\PYG{n}{enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{:} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{addprinc} \PYG{o}{\PYGZhy{}}\PYG{n}{requires\PYGZus{}preauth} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{Enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{n}{Enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{EXAMPLE}\PYG{o}{.}\PYG{n}{COM}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar Even if most principals in a realm are generally created with the \sphinxstylestrong{requires\_preauth} flag enabled, this flag is not desirable on cross\sphinxhyphen{}realm authentication keys because doing so makes it impossible to disable preauthentication on a service\sphinxhyphen{}by\sphinxhyphen{}service basis. Disabling it as in the example above is recommended. \end{sphinxadmonition} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar It is very important that these principals have good passwords. MIT recommends that TGT principal passwords be at least 26 characters of random ASCII text. \end{sphinxadmonition} \section{Changing the krbtgt key} \label{\detokenize{admin/database:changing-the-krbtgt-key}}\label{\detokenize{admin/database:changing-krbtgt-key}} \sphinxAtStartPar A Kerberos Ticket Granting Ticket (TGT) is a service ticket for the principal \sphinxcode{\sphinxupquote{krbtgt/REALM}}. The key for this principal is created when the Kerberos database is initialized and need not be changed. However, it will only have the encryption types supported by the KDC at the time of the initial database creation. To allow use of newer encryption types for the TGT, this key has to be changed. \sphinxAtStartPar Changing this key using the normal {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} \sphinxstylestrong{change\_password} command would invalidate any previously issued TGTs. Therefore, when changing this key, normally one should use the \sphinxstylestrong{\sphinxhyphen{}keepold} flag to change\_password to retain the previous key in the database as well as the new key. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{change\PYGZus{}password} \PYG{o}{\PYGZhy{}}\PYG{n}{randkey} \PYG{o}{\PYGZhy{}}\PYG{n}{keepold} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \end{sphinxVerbatim} \begin{sphinxadmonition}{warning}{Warning:} \sphinxAtStartPar After issuing this command, the old key is still valid and is still vulnerable to (for instance) brute force attacks. To completely retire an old key or encryption type, run the kadmin \sphinxstylestrong{purgekeys} command to delete keys with older kvnos, ideally first making sure that all tickets issued with the old keys have expired. \end{sphinxadmonition} \sphinxAtStartPar Only the first krbtgt key of the newest key version is used to encrypt ticket\sphinxhyphen{}granting tickets. However, the set of encryption types present in the krbtgt keys is used by default to determine the session key types supported by the krbtgt service (see {\hyperref[\detokenize{admin/enctypes:session-key-selection}]{\sphinxcrossref{\DUrole{std,std-ref}{Session key selection}}}}). Because non\sphinxhyphen{}MIT Kerberos clients sometimes send a limited set of encryption types when making AS requests, it can be important for the krbtgt service to support multiple encryption types. This can be accomplished by giving the krbtgt principal multiple keys, which is usually as simple as not specifying any \sphinxstylestrong{\sphinxhyphen{}e} option when changing the krbtgt key, or by setting the \sphinxstylestrong{session\_enctypes} string attribute on the krbtgt principal (see {\hyperref[\detokenize{admin/admin_commands/kadmin_local:set-string}]{\sphinxcrossref{\DUrole{std,std-ref}{set\_string}}}}). \sphinxAtStartPar Due to a bug in releases 1.8 through 1.13, renewed and forwarded tickets may not work if the original ticket was obtained prior to a krbtgt key change and the modified ticket is obtained afterwards. Upgrading the KDC to release 1.14 or later will correct this bug. \section{Incremental database propagation} \label{\detokenize{admin/database:incremental-database-propagation}}\label{\detokenize{admin/database:incr-db-prop}} \subsection{Overview} \label{\detokenize{admin/database:overview}} \sphinxAtStartPar At some very large sites, dumping and transmitting the database can take more time than is desirable for changes to propagate from the primary KDC to the replica KDCs. The incremental propagation support added in the 1.7 release is intended to address this. \sphinxAtStartPar With incremental propagation enabled, all programs on the primary KDC that change the database also write information about the changes to an “update log†file, maintained as a circular buffer of a certain size. A process on each replica KDC connects to a service on the primary KDC (currently implemented in the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} server) and periodically requests the changes that have been made since the last check. By default, this check is done every two minutes. \sphinxAtStartPar Incremental propagation uses the following entries in the per\sphinxhyphen{}realm data in the KDC config file (See {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}): \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TTT} \sphinxtoprule \sphinxtableatstartofbodyhook \sphinxAtStartPar iprop\_enable & \sphinxAtStartPar \sphinxstyleemphasis{boolean} & \sphinxAtStartPar If \sphinxstyleemphasis{true}, then incremental propagation is enabled, and (as noted below) normal kprop propagation is disabled. The default is \sphinxstyleemphasis{false}. \\ \sphinxhline \sphinxAtStartPar iprop\_master\_ulogsize & \sphinxAtStartPar \sphinxstyleemphasis{integer} & \sphinxAtStartPar Indicates the number of entries that should be retained in the update log. The default is 1000; the maximum number is 2500. \\ \sphinxhline \sphinxAtStartPar iprop\_replica\_poll & \sphinxAtStartPar \sphinxstyleemphasis{time interval} & \sphinxAtStartPar Indicates how often the replica should poll the primary KDC for changes to the database. The default is two minutes. \\ \sphinxhline \sphinxAtStartPar iprop\_port & \sphinxAtStartPar \sphinxstyleemphasis{integer} & \sphinxAtStartPar Specifies the port number to be used for incremental propagation. This is required in both primary and replica configuration files. \\ \sphinxhline \sphinxAtStartPar iprop\_resync\_timeout & \sphinxAtStartPar \sphinxstyleemphasis{integer} & \sphinxAtStartPar Specifies the number of seconds to wait for a full propagation to complete. This is optional on replica configurations. Defaults to 300 seconds (5 minutes). \\ \sphinxhline \sphinxAtStartPar iprop\_logfile & \sphinxAtStartPar \sphinxstyleemphasis{file name} & \sphinxAtStartPar Specifies where the update log file for the realm database is to be stored. The default is to use the \sphinxstyleemphasis{database\_name} entry from the realms section of the config file {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}, with \sphinxstyleemphasis{.ulog} appended. (NOTE: If database\_name isn’t specified in the realms section, perhaps because the LDAP database back end is being used, or the file name is specified in the \sphinxstyleemphasis{dbmodules} section, then the hard\sphinxhyphen{}coded default for \sphinxstyleemphasis{database\_name} is used. Determination of the \sphinxstyleemphasis{iprop\_logfile} default value will not use values from the \sphinxstyleemphasis{dbmodules} section.) \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxAtStartPar Both primary and replica sides must have a principal named \sphinxcode{\sphinxupquote{kiprop/hostname}} (where \sphinxstyleemphasis{hostname} is the lowercase, fully\sphinxhyphen{}qualified, canonical name for the host) registered in the Kerberos database, and have keys for that principal stored in the default keytab file ({\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFKTNAME}}}}). The \sphinxcode{\sphinxupquote{kiprop/hostname}} principal may have been created automatically for the primary KDC, but it must always be created for replica KDCs. \sphinxAtStartPar On the primary KDC side, the \sphinxcode{\sphinxupquote{kiprop/hostname}} principal must be listed in the kadmind ACL file {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}}, and given the \sphinxstylestrong{p} privilege (see {\hyperref[\detokenize{admin/database:privileges}]{\sphinxcrossref{\DUrole{std,std-ref}{Privileges}}}}). \sphinxAtStartPar On the replica KDC side, {\hyperref[\detokenize{admin/admin_commands/kpropd:kpropd-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kpropd}}}} should be run. When incremental propagation is enabled, it will connect to the kadmind on the primary KDC and start requesting updates. \sphinxAtStartPar The normal kprop mechanism is disabled by the incremental propagation support. However, if the replica has been unable to fetch changes from the primary KDC for too long (network problems, perhaps), the log on the primary may wrap around and overwrite some of the updates that the replica has not yet retrieved. In this case, the replica will instruct the primary KDC to dump the current database out to a file and invoke a one\sphinxhyphen{}time kprop propagation, with special options to also convey the point in the update log at which the replica should resume fetching incremental updates. Thus, all the keytab and ACL setup previously described for kprop propagation is still needed. \sphinxAtStartPar If an environment has a large number of replicas, it may be desirable to arrange them in a hierarchy instead of having the primary serve updates to every replica. To do this, run \sphinxcode{\sphinxupquote{kadmind \sphinxhyphen{}proponly}} on each intermediate replica, and \sphinxcode{\sphinxupquote{kpropd \sphinxhyphen{}A upstreamhostname}} on downstream replicas to direct each one to the appropriate upstream replica. \sphinxAtStartPar There are several known restrictions in the current implementation: \begin{itemize} \item {} \sphinxAtStartPar The incremental update protocol does not transport changes to policy objects. Any policy changes on the primary will result in full resyncs to all replicas. \item {} \sphinxAtStartPar The replica’s KDB module must support locking; it cannot be using the LDAP KDB module. \item {} \sphinxAtStartPar The primary and replica must be able to initiate TCP connections in both directions, without an intervening NAT. \end{itemize} \subsection{Sun/MIT incremental propagation differences} \label{\detokenize{admin/database:sun-mit-incremental-propagation-differences}} \sphinxAtStartPar Sun donated the original code for supporting incremental database propagation to MIT. Some changes have been made in the MIT source tree that will be visible to administrators. (These notes are based on Sun’s patches. Changes to Sun’s implementation since then may not be reflected here.) \sphinxAtStartPar The Sun config file support looks for \sphinxcode{\sphinxupquote{sunw\_dbprop\_enable}}, \sphinxcode{\sphinxupquote{sunw\_dbprop\_master\_ulogsize}}, and \sphinxcode{\sphinxupquote{sunw\_dbprop\_slave\_poll}}. \sphinxAtStartPar The incremental propagation service is implemented as an ONC RPC service. In the Sun implementation, the service is registered with rpcbind (also known as portmapper) and the client looks up the port number to contact. In the MIT implementation, where interaction with some modern versions of rpcbind doesn’t always work well, the port number must be specified in the config file on both the primary and replica sides. \sphinxAtStartPar The Sun implementation hard\sphinxhyphen{}codes pathnames in \sphinxcode{\sphinxupquote{/var/krb5}} for the update log and the per\sphinxhyphen{}replica kprop dump files. In the MIT implementation, the pathname for the update log is specified in the config file, and the per\sphinxhyphen{}replica dump files are stored in {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/replica\_datatrans\_hostname}}. \sphinxstepscope \chapter{Database types} \label{\detokenize{admin/dbtypes:database-types}}\label{\detokenize{admin/dbtypes:dbtypes}}\label{\detokenize{admin/dbtypes::doc}} \sphinxAtStartPar A Kerberos database can be implemented with one of three built\sphinxhyphen{}in database providers, called KDB modules. Software which incorporates the MIT krb5 KDC may also provide its own KDB module. The following subsections describe the three built\sphinxhyphen{}in KDB modules and the configuration specific to them. \sphinxAtStartPar The database type can be configured with the \sphinxstylestrong{db\_library} variable in the {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbmodules}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbmodules{]}}}}} subsection for the realm. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{dbmodules}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{db\PYGZus{}library} \PYG{o}{=} \PYG{n}{db2} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar If the \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} realm subsection contains a \sphinxstylestrong{database\_module} setting, then the subsection within \sphinxcode{\sphinxupquote{{[}dbmodules{]}}} should use that name instead of \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}}. \sphinxAtStartPar To transition from one database type to another, stop the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} service, use \sphinxcode{\sphinxupquote{kdb5\_util dump}} to create a dump file, change the \sphinxstylestrong{db\_library} value and set any appropriate configuration for the new database type, and use \sphinxcode{\sphinxupquote{kdb5\_util load}} to create and populate the new database. If the new database type is LDAP, create the new database using \sphinxcode{\sphinxupquote{kdb5\_ldap\_util}} and populate it from the dump file using \sphinxcode{\sphinxupquote{kdb5\_util load \sphinxhyphen{}update}}. Then restart the {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} and {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} services. \section{Berkeley database module (db2)} \label{\detokenize{admin/dbtypes:berkeley-database-module-db2}} \sphinxAtStartPar The default KDB module is \sphinxcode{\sphinxupquote{db2}}, which uses a version of the Berkeley DB library. It creates four files based on the database pathname. If the pathname ends with \sphinxcode{\sphinxupquote{principal}} then the four files are: \begin{itemize} \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{principal}}, containing principal entry data \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{principal.ok}}, a lock file for the principal database \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{principal.kadm5}}, containing policy object data \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{principal.kadm5.lock}}, a lock file for the policy database \end{itemize} \sphinxAtStartPar For large databases, the {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} \sphinxstylestrong{dump} command (perhaps invoked by {\hyperref[\detokenize{admin/admin_commands/kprop:kprop-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop}}}} or by {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} for incremental propagation) may cause {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} to stop for a noticeable period of time while it iterates over the database. This delay can be avoided by disabling account lockout features so that the KDC does not perform database writes (see {\hyperref[\detokenize{admin/lockout:disable-lockout}]{\sphinxcrossref{\DUrole{std,std-ref}{KDC performance and account lockout}}}}). Alternatively, a slower form of iteration can be enabled by setting the \sphinxstylestrong{unlockiter} variable to \sphinxcode{\sphinxupquote{true}}. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{dbmodules}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{db\PYGZus{}library} \PYG{o}{=} \PYG{n}{db2} \PYG{n}{unlockiter} \PYG{o}{=} \PYG{n}{true} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar In rare cases, a power failure or other unclean system shutdown may cause inconsistencies in the internal pointers within a database file, such that \sphinxcode{\sphinxupquote{kdb5\_util dump}} cannot retrieve all principal entries in the database. In this situation, it may be possible to retrieve all of the principal data by running \sphinxcode{\sphinxupquote{kdb5\_util dump \sphinxhyphen{}recurse}} to iterate over the database using the tree pointers instead of the iteration pointers. Running \sphinxcode{\sphinxupquote{kdb5\_util dump \sphinxhyphen{}rev}} to iterate over the database backwards may also retrieve some of the data which is not retrieved by a normal dump operation. \section{Lightning Memory\sphinxhyphen{}Mapped Database module (klmdb)} \label{\detokenize{admin/dbtypes:lightning-memory-mapped-database-module-klmdb}} \sphinxAtStartPar The klmdb module was added in release 1.17. It uses the LMDB library, and may offer better performance and reliability than the db2 module. It creates four files based on the database pathname. If the pathname ends with \sphinxcode{\sphinxupquote{principal}}, then the four files are: \begin{itemize} \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{principal.mdb}}, containing policy object data and most principal entry data \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{principal.mdb\sphinxhyphen{}lock}}, a lock file for the primary database \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{principal.lockout.mdb}}, containing the account lockout attributes (last successful authentication time, last failed authentication time, and number of failed attempts) for each principal entry \item {} \sphinxAtStartPar \sphinxcode{\sphinxupquote{principal.lockout.mdb\sphinxhyphen{}lock}}, a lock file for the lockout database \end{itemize} \sphinxAtStartPar Separating out the lockout attributes ensures that the KDC will never block on an administrative operation such as a database dump or load. It also allows the KDC to operate without write access to the primary database. If both account lockout features are disabled (see {\hyperref[\detokenize{admin/lockout:disable-lockout}]{\sphinxcrossref{\DUrole{std,std-ref}{KDC performance and account lockout}}}}), the lockout database files will be created but will not subsequently be opened, and the account lockout attributes will always have zero values. \sphinxAtStartPar Because LMDB creates a memory map to the database files, it requires a configured memory map size which also determines the maximum size of the database. This size is applied equally to the two databases, so twice the configured size will be consumed in the process address space; this is primarily a limitation on 32\sphinxhyphen{}bit platforms. The default value of 128 megabytes should be sufficient for several hundred thousand principal entries. If the limit is reached, kadmin operations will fail and the error message “Environment mapsize limit reached†will appear in the kadmind log file. In this case, the \sphinxstylestrong{mapsize} variable can be used to increase the map size. The following example sets the map size to 512 megabytes: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{dbmodules}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{db\PYGZus{}library} \PYG{o}{=} \PYG{n}{klmdb} \PYG{n}{mapsize} \PYG{o}{=} \PYG{l+m+mi}{512} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar LMDB has a configurable maximum number of readers. The default value of 128 should be sufficient for most deployments. If you are going to use a large number of KDC worker processes, it may be necessary to set the \sphinxstylestrong{max\_readers} variable to a larger number. \sphinxAtStartPar By default, LMDB synchronizes database files to disk after each write transaction to ensure durability in the case of an unclean system shutdown. The klmdb module always turns synchronization off for the lockout database to ensure reasonable KDC performance, but leaves it on for the primary database. If high throughput for administrative operations (including password changes) is required, the \sphinxstylestrong{nosync} variable can be set to “true†to disable synchronization for the primary database. \sphinxAtStartPar The klmdb module does not support explicit locking with the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} \sphinxstylestrong{lock} command. \section{LDAP module (kldap)} \label{\detokenize{admin/dbtypes:ldap-module-kldap}} \sphinxAtStartPar The kldap module stores principal and policy data using an LDAP server. To use it you must configure an LDAP server to use the Kerberos schema. See {\hyperref[\detokenize{admin/conf_ldap:conf-ldap}]{\sphinxcrossref{\DUrole{std,std-ref}{Configuring Kerberos with OpenLDAP back\sphinxhyphen{}end}}}} for details. \sphinxAtStartPar Because {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} is single\sphinxhyphen{}threaded, latency in LDAP database accesses may limit KDC operation throughput. If the LDAP server is located on the same server host as the KDC and accessed through an \sphinxcode{\sphinxupquote{ldapi://}} URL, latency should be minimal. If this is not possible, consider starting multiple KDC worker processes with the {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} \sphinxstylestrong{\sphinxhyphen{}w} option to enable concurrent processing of KDC requests. \sphinxAtStartPar The kldap module does not support explicit locking with the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} \sphinxstylestrong{lock} command. \sphinxstepscope \chapter{Account lockout} \label{\detokenize{admin/lockout:account-lockout}}\label{\detokenize{admin/lockout:lockout}}\label{\detokenize{admin/lockout::doc}} \sphinxAtStartPar As of release 1.8, the KDC can be configured to lock out principals after a number of failed authentication attempts within a period of time. Account lockout can make it more difficult to attack a principal’s password by brute force, but also makes it easy for an attacker to deny access to a principal. \section{Configuring account lockout} \label{\detokenize{admin/lockout:configuring-account-lockout}} \sphinxAtStartPar Account lockout only works for principals with the \sphinxstylestrong{+requires\_preauth} flag set. Without this flag, the KDC cannot know whether or not a client successfully decrypted the ticket it issued. It is also important to set the \sphinxstylestrong{\sphinxhyphen{}allow\_svr} flag on a principal to protect its password from an off\sphinxhyphen{}line dictionary attack through a TGS request. You can set these flags on a principal with {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} as follows: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{modprinc} \PYG{o}{+}\PYG{n}{requires\PYGZus{}preauth} \PYG{o}{\PYGZhy{}}\PYG{n}{allow\PYGZus{}svr} \PYG{n}{PRINCNAME} \end{sphinxVerbatim} \sphinxAtStartPar Account lockout parameters are configured via {\hyperref[\detokenize{admin/database:policies}]{\sphinxcrossref{\DUrole{std,std-ref}{policy objects}}}}. There may be an existing policy associated with user principals (such as the “default†policy), or you may need to create a new one and associate it with each user principal. \sphinxAtStartPar The policy parameters related to account lockout are: \begin{itemize} \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kadmin_local:policy-maxfailure}]{\sphinxcrossref{\DUrole{std,std-ref}{maxfailure}}}}: the number of failed attempts before the principal is locked out \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kadmin_local:policy-failurecountinterval}]{\sphinxcrossref{\DUrole{std,std-ref}{failurecountinterval}}}}: the allowable interval between failed attempts \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kadmin_local:policy-lockoutduration}]{\sphinxcrossref{\DUrole{std,std-ref}{lockoutduration}}}}: the amount of time a principal is locked out for \end{itemize} \sphinxAtStartPar Here is an example of setting these parameters on a new policy and associating it with a principal: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{addpol} \PYG{o}{\PYGZhy{}}\PYG{n}{maxfailure} \PYG{l+m+mi}{10} \PYG{o}{\PYGZhy{}}\PYG{n}{failurecountinterval} \PYG{l+m+mi}{180} \PYG{o}{\PYGZhy{}}\PYG{n}{lockoutduration} \PYG{l+m+mi}{60} \PYG{n}{lockout\PYGZus{}policy} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{modprinc} \PYG{o}{\PYGZhy{}}\PYG{n}{policy} \PYG{n}{lockout\PYGZus{}policy} \PYG{n}{PRINCNAME} \end{sphinxVerbatim} \section{Testing account lockout} \label{\detokenize{admin/lockout:testing-account-lockout}} \sphinxAtStartPar To test that account lockout is working, try authenticating as the principal (hopefully not one that might be in use) multiple times with the wrong password. For instance, if \sphinxstylestrong{maxfailure} is set to 2, you might see: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kinit user Password for user@KRBTEST.COM: kinit: Password incorrect while getting initial credentials \PYGZdl{} kinit user Password for user@KRBTEST.COM: kinit: Password incorrect while getting initial credentials \PYGZdl{} kinit user kinit: Client\PYGZsq{}s credentials have been revoked while getting initial credentials \end{sphinxVerbatim} \section{Account lockout principal state} \label{\detokenize{admin/lockout:account-lockout-principal-state}} \sphinxAtStartPar A principal entry keeps three pieces of state related to account lockout: \begin{itemize} \item {} \sphinxAtStartPar The time of last successful authentication \item {} \sphinxAtStartPar The time of last failed authentication \item {} \sphinxAtStartPar A counter of failed attempts \end{itemize} \sphinxAtStartPar The time of last successful authentication is not actually needed for the account lockout system to function, but may be of administrative interest. These fields can be observed with the \sphinxstylestrong{getprinc} kadmin command. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{getprinc} \PYG{n}{user} \PYG{n}{Principal}\PYG{p}{:} \PYG{n}{user}\PYG{n+nd}{@KRBTEST}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.} \PYG{n}{Last} \PYG{n}{successful} \PYG{n}{authentication}\PYG{p}{:} \PYG{p}{[}\PYG{n}{never}\PYG{p}{]} \PYG{n}{Last} \PYG{n}{failed} \PYG{n}{authentication}\PYG{p}{:} \PYG{n}{Mon} \PYG{n}{Dec} \PYG{l+m+mi}{03} \PYG{l+m+mi}{12}\PYG{p}{:}\PYG{l+m+mi}{30}\PYG{p}{:}\PYG{l+m+mi}{33} \PYG{n}{EST} \PYG{l+m+mi}{2012} \PYG{n}{Failed} \PYG{n}{password} \PYG{n}{attempts}\PYG{p}{:} \PYG{l+m+mi}{2} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar A principal which has been locked out can be administratively unlocked with the \sphinxstylestrong{\sphinxhyphen{}unlock} option to the \sphinxstylestrong{modprinc} kadmin command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{modprinc} \PYG{o}{\PYGZhy{}}\PYG{n}{unlock} \PYG{n}{PRINCNAME} \end{sphinxVerbatim} \sphinxAtStartPar This command will reset the number of failed attempts to 0. \section{KDC replication and account lockout} \label{\detokenize{admin/lockout:kdc-replication-and-account-lockout}} \sphinxAtStartPar The account lockout state of a principal is not replicated by either traditional {\hyperref[\detokenize{admin/admin_commands/kprop:kprop-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop}}}} or incremental propagation. Because of this, the number of attempts an attacker can make within a time period is multiplied by the number of KDCs. For instance, if the \sphinxstylestrong{maxfailure} parameter on a policy is 10 and there are four KDCs in the environment (a primary and three replicas), an attacker could make as many as 40 attempts before the principal is locked out on all four KDCs. \sphinxAtStartPar An administrative unlock is propagated from the primary to the replica KDCs during the next propagation. Propagation of an administrative unlock will cause the counter of failed attempts on each replica to reset to 1 on the next failure. \sphinxAtStartPar If a KDC environment uses a replication strategy other than kprop or incremental propagation, such as the LDAP KDB module with multi\sphinxhyphen{}master LDAP replication, then account lockout state may be replicated between KDCs and the concerns of this section may not apply. \section{KDC performance and account lockout} \label{\detokenize{admin/lockout:kdc-performance-and-account-lockout}}\label{\detokenize{admin/lockout:disable-lockout}} \sphinxAtStartPar In order to fully track account lockout state, the KDC must write to the the database on each successful and failed authentication. Writing to the database is generally more expensive than reading from it, so these writes may have a significant impact on KDC performance. As of release 1.9, it is possible to turn off account lockout state tracking in order to improve performance, by setting the \sphinxstylestrong{disable\_last\_success} and \sphinxstylestrong{disable\_lockout} variables in the database module subsection of {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{dbmodules}\PYG{p}{]} \PYG{n}{DB} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{disable\PYGZus{}last\PYGZus{}success} \PYG{o}{=} \PYG{n}{true} \PYG{n}{disable\PYGZus{}lockout} \PYG{o}{=} \PYG{n}{true} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar Of the two variables, setting \sphinxstylestrong{disable\_last\_success} will usually have the largest positive impact on performance, and will still allow account lockout policies to operate. However, it will make it impossible to observe the last successful authentication time with kadmin. \section{KDC setup and account lockout} \label{\detokenize{admin/lockout:kdc-setup-and-account-lockout}} \sphinxAtStartPar To update the account lockout state on principals, the KDC must be able to write to the principal database. For the DB2 module, no special setup is required. For the LDAP module, the KDC DN must be granted write access to the principal objects. If the KDC DN has only read access, account lockout will not function. \sphinxstepscope \chapter{Configuring Kerberos with OpenLDAP back\sphinxhyphen{}end} \label{\detokenize{admin/conf_ldap:configuring-kerberos-with-openldap-back-end}}\label{\detokenize{admin/conf_ldap:conf-ldap}}\label{\detokenize{admin/conf_ldap::doc}}\begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar Make sure the LDAP server is using local authentication (\sphinxcode{\sphinxupquote{ldapi://}}) or TLS (\sphinxcode{\sphinxupquote{ldaps}}). See \sphinxurl{https://www.openldap.org/doc/admin/tls.html} for instructions on configuring TLS support in OpenLDAP. \item {} \sphinxAtStartPar Add the Kerberos schema file to the LDAP Server using the OpenLDAP LDIF file from the krb5 source directory (\sphinxcode{\sphinxupquote{src/plugins/kdb/ldap/libkdb\_ldap/kerberos.openldap.ldif}}). The following example uses local authentication: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{ldapadd} \PYG{o}{\PYGZhy{}}\PYG{n}{Y} \PYG{n}{EXTERNAL} \PYG{o}{\PYGZhy{}}\PYG{n}{H} \PYG{n}{ldapi}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{o}{/} \PYG{o}{\PYGZhy{}}\PYG{n}{f} \PYG{o}{/}\PYG{n}{path}\PYG{o}{/}\PYG{n}{to}\PYG{o}{/}\PYG{n}{kerberos}\PYG{o}{.}\PYG{n}{openldap}\PYG{o}{.}\PYG{n}{ldif} \end{sphinxVerbatim} \item {} \sphinxAtStartPar Choose DNs for the {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} and {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} servers to bind to the LDAP server, and create them if necessary. Specify these DNs with the \sphinxstylestrong{ldap\_kdc\_dn} and \sphinxstylestrong{ldap\_kadmind\_dn} directives in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. The kadmind DN will also be used for administrative commands such as {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}}. \sphinxAtStartPar Alternatively, you may configure krb5kdc and kadmind to use SASL authentication to access the LDAP server; see the {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbmodules}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbmodules{]}}}}} relations \sphinxstylestrong{ldap\_kdc\_sasl\_mech} and similar. \item {} \sphinxAtStartPar Specify a location for the LDAP service password file by setting \sphinxstylestrong{ldap\_service\_password\_file}. Use \sphinxcode{\sphinxupquote{kdb5\_ldap\_util stashsrvpw}} to stash passwords for the KDC and kadmind DNs chosen above. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{n}{stashsrvpw} \PYG{o}{\PYGZhy{}}\PYG{n}{f} \PYG{o}{/}\PYG{n}{path}\PYG{o}{/}\PYG{n}{to}\PYG{o}{/}\PYG{n}{service}\PYG{o}{.}\PYG{n}{keyfile} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{krbadmin}\PYG{p}{,}\PYG{n}{dc}\PYG{o}{=}\PYG{n}{example}\PYG{p}{,}\PYG{n}{dc}\PYG{o}{=}\PYG{n}{com} \end{sphinxVerbatim} \sphinxAtStartPar Skip this step if you are using SASL authentication and the mechanism does not require a password. \item {} \sphinxAtStartPar Choose a DN for the global Kerberos container entry (but do not create the entry at this time). Specify this DN with the \sphinxstylestrong{ldap\_kerberos\_container\_dn} directive in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. Realm container entries will be created underneath this DN. Principal entries may exist either underneath the realm container (the default) or in separate trees referenced from the realm container. \item {} \sphinxAtStartPar Configure the LDAP server ACLs to enable the KDC and kadmin server DNs to read and write the Kerberos data. If \sphinxstylestrong{disable\_last\_success} and \sphinxstylestrong{disable\_lockout} are both set to true in the {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbmodules}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbmodules{]}}}}} subsection for the realm, then the KDC DN only requires read access to the Kerberos data. \sphinxAtStartPar Sample access control information: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{access} \PYG{n}{to} \PYG{n}{dn}\PYG{o}{.}\PYG{n}{base}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{by} \PYG{o}{*} \PYG{n}{read} \PYG{n}{access} \PYG{n}{to} \PYG{n}{dn}\PYG{o}{.}\PYG{n}{base}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=Subschema}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{by} \PYG{o}{*} \PYG{n}{read} \PYG{c+c1}{\PYGZsh{} Provide access to the realm container.} \PYG{n}{access} \PYG{n}{to} \PYG{n}{dn}\PYG{o}{.}\PYG{n}{subtree}\PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=EXAMPLE.COM,cn=krbcontainer,dc=example,dc=com}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{by} \PYG{n}{dn}\PYG{o}{.}\PYG{n}{exact}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=kdc\PYGZhy{}service,dc=example,dc=com}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{write} \PYG{n}{by} \PYG{n}{dn}\PYG{o}{.}\PYG{n}{exact}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=adm\PYGZhy{}service,dc=example,dc=com}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{write} \PYG{n}{by} \PYG{o}{*} \PYG{n}{none} \PYG{c+c1}{\PYGZsh{} Provide access to principals, if not underneath the realm container.} \PYG{n}{access} \PYG{n}{to} \PYG{n}{dn}\PYG{o}{.}\PYG{n}{subtree}\PYG{o}{=} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ou=users,dc=example,dc=com}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{by} \PYG{n}{dn}\PYG{o}{.}\PYG{n}{exact}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=kdc\PYGZhy{}service,dc=example,dc=com}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{write} \PYG{n}{by} \PYG{n}{dn}\PYG{o}{.}\PYG{n}{exact}\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=adm\PYGZhy{}service,dc=example,dc=com}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{write} \PYG{n}{by} \PYG{o}{*} \PYG{n}{none} \PYG{n}{access} \PYG{n}{to} \PYG{o}{*} \PYG{n}{by} \PYG{o}{*} \PYG{n}{read} \end{sphinxVerbatim} \sphinxAtStartPar If the locations of the container and principals or the DNs of the service objects for a realm are changed then this information should be updated. \item {} \sphinxAtStartPar In {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}, make sure the following relations are set in the {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbmodules}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbmodules{]}}}}} subsection for the realm: \begin{sphinxVerbatim}[commandchars=\\\{\}] db\PYGZus{}library (set to ``kldap``) ldap\PYGZus{}kerberos\PYGZus{}container\PYGZus{}dn ldap\PYGZus{}kdc\PYGZus{}dn ldap\PYGZus{}kadmind\PYGZus{}dn ldap\PYGZus{}service\PYGZus{}password\PYGZus{}file ldap\PYGZus{}servers \end{sphinxVerbatim} \item {} \sphinxAtStartPar Create the realm using {\hyperref[\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_ldap\_util}}}}: \begin{quote} \sphinxAtStartPar kdb5\_ldap\_util create \sphinxhyphen{}subtrees ou=users,dc=example,dc=com \sphinxhyphen{}s \end{quote} \sphinxAtStartPar Use the \sphinxstylestrong{\sphinxhyphen{}subtrees} option if the principals are to exist in a separate subtree from the realm container. Before executing the command, make sure that the subtree mentioned above \sphinxcode{\sphinxupquote{(ou=users,dc=example,dc=com)}} exists. If the principals will exist underneath the realm container, omit the \sphinxstylestrong{\sphinxhyphen{}subtrees} option and do not worry about creating the principal subtree. \sphinxAtStartPar For more information, refer to the section {\hyperref[\detokenize{admin/database:ops-on-ldap}]{\sphinxcrossref{\DUrole{std,std-ref}{Operations on the LDAP database}}}}. \sphinxAtStartPar The realm object is created under the \sphinxstylestrong{ldap\_kerberos\_container\_dn} specified in the configuration file. This operation will also create the Kerberos container, if not present already. This container can be used to store information related to multiple realms. \item {} \sphinxAtStartPar Add an \sphinxcode{\sphinxupquote{eq}} index for \sphinxcode{\sphinxupquote{krbPrincipalName}} to speed up principal lookup operations. See \sphinxurl{https://www.openldap.org/doc/admin/tuning.html\#Indexes} for details. \end{enumerate} \sphinxAtStartPar With the LDAP back end it is possible to provide aliases for principal entries. Beginning in release 1.22, aliases can be added with the kadmin \sphinxstylestrong{add\_alias} command, but it is also possible (in release 1.7 or later) to provide aliases through direct manipulation of the LDAP entries. \sphinxAtStartPar An entry with aliases contains multiple values of the \sphinxstyleemphasis{krbPrincipalName} attribute. Since LDAP attribute values are not ordered, it is necessary to specify which principal name is canonical, by using the \sphinxstyleemphasis{krbCanonicalName} attribute. Therefore, to create aliases for an entry, first set the \sphinxstyleemphasis{krbCanonicalName} attribute of the entry to the canonical principal name (which should be identical to the pre\sphinxhyphen{}existing \sphinxstyleemphasis{krbPrincipalName} value), and then add additional \sphinxstyleemphasis{krbPrincipalName} attributes for the aliases. \sphinxAtStartPar Principal aliases are only returned by the KDC when the client requests canonicalization. Canonicalization is normally requested for service principals; for client principals, an explicit flag is often required (e.g., \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}C}}) and canonicalization is only performed for initial ticket requests. \sphinxstepscope \chapter{Application servers} \label{\detokenize{admin/appl_servers:application-servers}}\label{\detokenize{admin/appl_servers::doc}} \sphinxAtStartPar If you need to install the Kerberos V5 programs on an application server, please refer to the Kerberos V5 Installation Guide. Once you have installed the software, you need to add that host to the Kerberos database (see {\hyperref[\detokenize{admin/database:principals}]{\sphinxcrossref{\DUrole{std,std-ref}{Principals}}}}), and generate a keytab for that host, that contains the host’s key. You also need to make sure the host’s clock is within your maximum clock skew of the KDCs. \section{Keytabs} \label{\detokenize{admin/appl_servers:keytabs}} \sphinxAtStartPar A keytab is a host’s copy of its own keylist, which is analogous to a user’s password. An application server that needs to authenticate itself to the KDC has to have a keytab that contains its own principal and key. Just as it is important for users to protect their passwords, it is equally important for hosts to protect their keytabs. You should always store keytab files on local disk, and make them readable only by root, and you should never send a keytab file over a network in the clear. Ideally, you should run the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} command to extract a keytab on the host on which the keytab is to reside. \subsection{Adding principals to keytabs} \label{\detokenize{admin/appl_servers:adding-principals-to-keytabs}}\label{\detokenize{admin/appl_servers:add-princ-kt}} \sphinxAtStartPar To generate a keytab, or to add a principal to an existing keytab, use the \sphinxstylestrong{ktadd} command from kadmin. Here is a sample session, using configuration files that enable only AES encryption: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{ktadd} \PYG{n}{host}\PYG{o}{/}\PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab} \end{sphinxVerbatim} \subsection{Removing principals from keytabs} \label{\detokenize{admin/appl_servers:removing-principals-from-keytabs}} \sphinxAtStartPar To remove a principal from an existing keytab, use the kadmin \sphinxstylestrong{ktremove} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{ktremove} \PYG{n}{host}\PYG{o}{/}\PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2} \PYG{n}{removed} \PYG{k+kn}{from} \PYG{n+nn}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2} \PYG{n}{removed} \PYG{k+kn}{from} \PYG{n+nn}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \end{sphinxVerbatim} \subsection{Using a keytab to acquire client credentials} \label{\detokenize{admin/appl_servers:using-a-keytab-to-acquire-client-credentials}} \sphinxAtStartPar While keytabs are ordinarily used to accept credentials from clients, they can also be used to acquire initial credentials, allowing one service to authenticate to another. \sphinxAtStartPar To manually obtain credentials using a keytab, use the \DUrole{xref,std,std-ref}{kinit(1)} \sphinxstylestrong{\sphinxhyphen{}k} option, together with the \sphinxstylestrong{\sphinxhyphen{}t} option if the keytab is not in the default location. \sphinxAtStartPar Beginning with release 1.11, GSSAPI applications can be configured to automatically obtain initial credentials from a keytab as needed. The recommended configuration is as follows: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar Create a keytab containing a single entry for the desired client identity. \item {} \sphinxAtStartPar Place the keytab in a location readable by the service, and set the \sphinxstylestrong{KRB5\_CLIENT\_KTNAME} environment variable to its filename. Alternatively, use the \sphinxstylestrong{default\_client\_keytab\_name} profile variable in {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}}, or use the default location of {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFCKTNAME}}}}. \item {} \sphinxAtStartPar Set \sphinxstylestrong{KRB5CCNAME} to a filename writable by the service, which will not be used for any other purpose. Do not manually obtain credentials at this location. (Another credential cache type besides \sphinxstylestrong{FILE} can be used if desired, as long the cache will not conflict with another use. A \sphinxstylestrong{MEMORY} cache can be used if the service runs as a long\sphinxhyphen{}lived process. See \DUrole{xref,std,std-ref}{ccache\_definition} for details.) \item {} \sphinxAtStartPar Start the service. When it authenticates using GSSAPI, it will automatically obtain credentials from the client keytab into the specified credential cache, and refresh them before they expire. \end{enumerate} \section{Clock Skew} \label{\detokenize{admin/appl_servers:clock-skew}} \sphinxAtStartPar A Kerberos application server host must keep its clock synchronized or it will reject authentication requests from clients. Modern operating systems typically provide a facility to maintain the correct time; make sure it is enabled. This is especially important on virtual machines, where clocks tend to drift more rapidly than normal machine clocks. \sphinxAtStartPar The default allowable clock skew is controlled by the \sphinxstylestrong{clockskew} variable in {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}}. \section{Getting DNS information correct} \label{\detokenize{admin/appl_servers:getting-dns-information-correct}} \sphinxAtStartPar Several aspects of Kerberos rely on name service. When a hostname is used to name a service, clients may canonicalize the hostname using forward and possibly reverse name resolution. The result of this canonicalization must match the principal entry in the host’s keytab, or authentication will fail. To work with all client canonicalization configurations, each host’s canonical name must be the fully\sphinxhyphen{}qualified host name (including the domain), and each host’s IP address must reverse\sphinxhyphen{}resolve to the canonical name. \sphinxAtStartPar Configuration of hostnames varies by operating system. On the application server itself, canonicalization will typically use the \sphinxcode{\sphinxupquote{/etc/hosts}} file rather than the DNS. Ensure that the line for the server’s hostname is in the following form: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{IP} \PYG{n}{address} \PYG{n}{fully}\PYG{o}{\PYGZhy{}}\PYG{n}{qualified} \PYG{n}{hostname} \PYG{n}{aliases} \end{sphinxVerbatim} \sphinxAtStartPar Here is a sample \sphinxcode{\sphinxupquote{/etc/hosts}} file: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{c+c1}{\PYGZsh{} this is a comment} \PYG{l+m+mf}{127.0}\PYG{l+m+mf}{.0}\PYG{l+m+mf}{.1} \PYG{n}{localhost} \PYG{n}{localhost}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{l+m+mf}{10.0}\PYG{l+m+mf}{.0}\PYG{l+m+mf}{.6} \PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{daffodil} \PYG{n}{trillium} \PYG{n}{wake}\PYG{o}{\PYGZhy{}}\PYG{n}{robin} \end{sphinxVerbatim} \sphinxAtStartPar The output of \sphinxcode{\sphinxupquote{klist \sphinxhyphen{}k}} for this example host should look like: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{viola}\PYG{c+c1}{\PYGZsh{} klist \PYGZhy{}k} \PYG{n}{Keytab} \PYG{n}{name}\PYG{p}{:} \PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab} \PYG{n}{KVNO} \PYG{n}{Principal} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{2} \PYG{n}{host}\PYG{o}{/}\PYG{n}{daffodil}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \end{sphinxVerbatim} \sphinxAtStartPar If you were to ssh to this host with a fresh credentials cache (ticket file), and then \DUrole{xref,std,std-ref}{klist(1)}, the output should list a service principal of \sphinxcode{\sphinxupquote{host/daffodil.mit.edu@ATHENA.MIT.EDU}}. \section{Configuring your firewall to work with Kerberos V5} \label{\detokenize{admin/appl_servers:configuring-your-firewall-to-work-with-kerberos-v5}}\label{\detokenize{admin/appl_servers:conf-firewall}} \sphinxAtStartPar If you need off\sphinxhyphen{}site users to be able to get Kerberos tickets in your realm, they must be able to get to your KDC. This requires either that you have a replica KDC outside your firewall, or that you configure your firewall to allow UDP requests into at least one of your KDCs, on whichever port the KDC is running. (The default is port 88; other ports may be specified in the KDC’s {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} file.) Similarly, if you need off\sphinxhyphen{}site users to be able to change their passwords in your realm, they must be able to get to your Kerberos admin server on the kpasswd port (which defaults to 464). If you need off\sphinxhyphen{}site users to be able to administer your Kerberos realm, they must be able to get to your Kerberos admin server on the administrative port (which defaults to 749). \sphinxAtStartPar If your on\sphinxhyphen{}site users inside your firewall will need to get to KDCs in other realms, you will also need to configure your firewall to allow outgoing TCP and UDP requests to port 88, and to port 464 to allow password changes. If your on\sphinxhyphen{}site users inside your firewall will need to get to Kerberos admin servers in other realms, you will also need to allow outgoing TCP and UDP requests to port 749. \sphinxAtStartPar If any of your KDCs are outside your firewall, you will need to allow kprop requests to get through to the remote KDC. {\hyperref[\detokenize{admin/admin_commands/kprop:kprop-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop}}}} uses the \sphinxcode{\sphinxupquote{krb5\_prop}} service on port 754 (tcp). \sphinxAtStartPar The book \sphinxstyleemphasis{UNIX System Security}, by David Curry, is a good starting point for learning to configure firewalls. \sphinxstepscope \chapter{Host configuration} \label{\detokenize{admin/host_config:host-configuration}}\label{\detokenize{admin/host_config::doc}} \sphinxAtStartPar All hosts running Kerberos software, whether they are clients, application servers, or KDCs, can be configured using {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. Here we describe some of the behavior changes you might want to make. \section{Default realm} \label{\detokenize{admin/host_config:default-realm}} \sphinxAtStartPar In the {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}} section, the \sphinxstylestrong{default\_realm} realm relation sets the default Kerberos realm. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{libdefaults}\PYG{p}{]} \PYG{n}{default\PYGZus{}realm} \PYG{o}{=} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \end{sphinxVerbatim} \sphinxAtStartPar The default realm affects Kerberos behavior in the following ways: \begin{itemize} \item {} \sphinxAtStartPar When a principal name is parsed from text, the default realm is used if no \sphinxcode{\sphinxupquote{@REALM}} component is specified. \item {} \sphinxAtStartPar The default realm affects login authorization as described below. \item {} \sphinxAtStartPar For programs which operate on a Kerberos database, the default realm is used to determine which database to operate on, unless the \sphinxstylestrong{\sphinxhyphen{}r} parameter is given to specify a realm. \item {} \sphinxAtStartPar A server program may use the default realm when looking up its key in a {\hyperref[\detokenize{admin/install_appl_srv:keytab-file}]{\sphinxcrossref{\DUrole{std,std-ref}{keytab file}}}}, if its realm is not determined by {\hyperref[\detokenize{admin/conf_files/krb5_conf:domain-realm}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}domain\_realm{]}}}}} configuration or by the server program itself. \item {} \sphinxAtStartPar If \DUrole{xref,std,std-ref}{kinit(1)} is passed the \sphinxstylestrong{\sphinxhyphen{}n} flag, it requests anonymous tickets from the default realm. \end{itemize} \sphinxAtStartPar In some situations, these uses of the default realm might conflict. For example, it might be desirable for principal name parsing to use one realm by default, but for login authorization to use a second realm. In this situation, the first realm can be configured as the default realm, and \sphinxstylestrong{auth\_to\_local} relations can be used as described below to use the second realm for login authorization. \section{Login authorization} \label{\detokenize{admin/host_config:login-authorization}}\label{\detokenize{admin/host_config:id1}} \sphinxAtStartPar If a host runs a Kerberos\sphinxhyphen{}enabled login service such as OpenSSH with GSSAPIAuthentication enabled, login authorization rules determine whether a Kerberos principal is allowed to access a local account. \sphinxAtStartPar By default, a Kerberos principal is allowed access to an account if its realm matches the default realm and its name matches the account name. (For historical reasons, access is also granted by default if the name has two components and the second component matches the default realm; for instance, \sphinxcode{\sphinxupquote{alice/ATHENA.MIT.EDU@ATHENA.MIT.EDU}} is granted access to the \sphinxcode{\sphinxupquote{alice}} account if \sphinxcode{\sphinxupquote{ATHENA.MIT.EDU}} is the default realm.) \sphinxAtStartPar The simplest way to control local access is using \DUrole{xref,std,std-ref}{.k5login(5)} files. To use these, place a \sphinxcode{\sphinxupquote{.k5login}} file in the home directory of each account listing the principal names which should have login access to that account. If it is not desirable to use \sphinxcode{\sphinxupquote{.k5login}} files located in account home directories, the \sphinxstylestrong{k5login\_directory} relation in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}} section can specify a directory containing one file per account uname. \sphinxAtStartPar By default, if a \sphinxcode{\sphinxupquote{.k5login}} file is present, it controls authorization both positively and negatively\textendash{}any principal name contained in the file is granted access and any other principal name is denied access, even if it would have had access if the \sphinxcode{\sphinxupquote{.k5login}} file didn’t exist. The \sphinxstylestrong{k5login\_authoritative} relation in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}} section can be set to false to make \sphinxcode{\sphinxupquote{.k5login}} files provide positive authorization only. \sphinxAtStartPar The \sphinxstylestrong{auth\_to\_local} relation in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} section for the default realm can specify pattern\sphinxhyphen{}matching rules to control login authorization. For example, the following configuration allows access to principals from a different realm than the default realm: \begin{sphinxVerbatim}[commandchars=\\\{\}] [realms] DEFAULT.REALM = \PYGZob{} \PYGZsh{} Allow access to principals from OTHER.REALM. \PYGZsh{} \PYGZsh{} [1:\PYGZdl{}1@\PYGZdl{}0] matches single\PYGZhy{}component principal names and creates \PYGZsh{} a selection string containing the principal name and realm. \PYGZsh{} \PYGZsh{} (.*@OTHER\PYGZbs{}.REALM) matches against the selection string, so that \PYGZsh{} only principals in OTHER.REALM are matched. \PYGZsh{} \PYGZsh{} s/@OTHER\PYGZbs{}.REALM\PYGZdl{}// removes the realm name, leaving behind the \PYGZsh{} principal name as the account name. auth\PYGZus{}to\PYGZus{}local = RULE:[1:\PYGZdl{}1@\PYGZdl{}0](.*@OTHER\PYGZbs{}.REALM)s/@OTHER\PYGZbs{}.REALM\PYGZdl{}// \PYGZsh{} Also allow principals from the default realm. Omit this line \PYGZsh{} to only allow access to principals in OTHER.REALM. auth\PYGZus{}to\PYGZus{}local = DEFAULT \PYGZcb{} \end{sphinxVerbatim} \sphinxAtStartPar The \sphinxstylestrong{auth\_to\_local\_names} subsection of the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} section for the default realm can specify explicit mappings from principal names to local accounts. The key used in this subsection is the principal name without realm, so it is only safe to use in a Kerberos environment with a single realm or a tightly controlled set of realms. An example use of \sphinxstylestrong{auth\_to\_local\_names} might be: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{auth\PYGZus{}to\PYGZus{}local\PYGZus{}names} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{c+c1}{\PYGZsh{} Careful, these match principals in any realm!} \PYG{n}{host}\PYG{o}{/}\PYG{n}{example}\PYG{o}{.}\PYG{n}{com} \PYG{o}{=} \PYG{n}{hostaccount} \PYG{n}{fred} \PYG{o}{=} \PYG{n}{localfred} \PYG{p}{\PYGZcb{}} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar Local authorization behavior can also be modified using plugin modules; see \DUrole{xref,std,std-ref}{hostrealm\_plugin} for details. \section{Plugin module configuration} \label{\detokenize{admin/host_config:plugin-module-configuration}}\label{\detokenize{admin/host_config:plugin-config}} \sphinxAtStartPar Many aspects of Kerberos behavior, such as client preauthentication and KDC service location, can be modified through the use of plugin modules. For most of these behaviors, you can use the {\hyperref[\detokenize{admin/conf_files/krb5_conf:plugins}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}plugins{]}}}}} section of krb5.conf to register third\sphinxhyphen{}party modules, and to switch off registered or built\sphinxhyphen{}in modules. \sphinxAtStartPar A plugin module takes the form of a Unix shared object (\sphinxcode{\sphinxupquote{modname.so}}) or Windows DLL (\sphinxcode{\sphinxupquote{modname.dll}}). If you have installed a third\sphinxhyphen{}party plugin module and want to register it, you do so using the \sphinxstylestrong{module} relation in the appropriate subsection of the {[}plugins{]} section. The value for \sphinxstylestrong{module} must give the module name and the path to the module, separated by a colon. The module name will often be the same as the shared object’s name, but in unusual cases (such as a shared object which implements multiple modules for the same interface) it might not be. For example, to register a client preauthentication module named \sphinxcode{\sphinxupquote{mypreauth}} installed at \sphinxcode{\sphinxupquote{/path/to/mypreauth.so}}, you could write: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{plugins}\PYG{p}{]} \PYG{n}{clpreauth} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{module} \PYG{o}{=} \PYG{n}{mypreauth}\PYG{p}{:}\PYG{o}{/}\PYG{n}{path}\PYG{o}{/}\PYG{n}{to}\PYG{o}{/}\PYG{n}{mypreauth}\PYG{o}{.}\PYG{n}{so} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar Many of the pluggable behaviors in MIT krb5 contain built\sphinxhyphen{}in modules which can be switched off. You can disable a built\sphinxhyphen{}in module (or one you have registered) using the \sphinxstylestrong{disable} directive in the appropriate subsection of the {[}plugins{]} section. For example, to disable the use of .k5identity files to select credential caches, you could write: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{plugins}\PYG{p}{]} \PYG{n}{ccselect} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{disable} \PYG{o}{=} \PYG{n}{k5identity} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar If you want to disable multiple modules, specify the \sphinxstylestrong{disable} directive multiple times, giving one module to disable each time. \sphinxAtStartPar Alternatively, you can explicitly specify which modules you want to be enabled for that behavior using the \sphinxstylestrong{enable\_only} directive. For example, to make {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} check password quality using only a module you have registered, and no other mechanism, you could write: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{plugins}\PYG{p}{]} \PYG{n}{pwqual} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{module} \PYG{o}{=} \PYG{n}{mymodule}\PYG{p}{:}\PYG{o}{/}\PYG{n}{path}\PYG{o}{/}\PYG{n}{to}\PYG{o}{/}\PYG{n}{mymodule}\PYG{o}{.}\PYG{n}{so} \PYG{n}{enable\PYGZus{}only} \PYG{o}{=} \PYG{n}{mymodule} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar Again, if you want to specify multiple modules, specify the \sphinxstylestrong{enable\_only} directive multiple times, giving one module to enable each time. \sphinxAtStartPar Some Kerberos interfaces use different mechanisms to register plugin modules. \subsection{KDC location modules} \label{\detokenize{admin/host_config:kdc-location-modules}} \sphinxAtStartPar For historical reasons, modules to control how KDC servers are located are registered simply by placing the shared object or DLL into the “libkrb5†subdirectory of the krb5 plugin directory, which defaults to {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LIBDIR}}}}\sphinxcode{\sphinxupquote{/krb5/plugins}}. For example, Samba’s winbind krb5 locator plugin would be registered by placing its shared object in {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LIBDIR}}}}\sphinxcode{\sphinxupquote{/krb5/plugins/libkrb5/winbind\_krb5\_locator.so}}. \subsection{GSSAPI mechanism modules} \label{\detokenize{admin/host_config:gssapi-mechanism-modules}}\label{\detokenize{admin/host_config:gssapi-plugin-config}} \sphinxAtStartPar GSSAPI mechanism modules are registered using the file {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{SYSCONFDIR}}}}\sphinxcode{\sphinxupquote{/gss/mech}} or configuration files in the {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{SYSCONFDIR}}}}\sphinxcode{\sphinxupquote{/gss/mech.d}} directory with a \sphinxcode{\sphinxupquote{.conf}} suffix. Each line in these files has the form: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{name} \PYG{n}{oid} \PYG{n}{pathname} \PYG{p}{[}\PYG{n}{options}\PYG{p}{]} \PYG{o}{\PYGZlt{}}\PYG{n+nb}{type}\PYG{o}{\PYGZgt{}} \end{sphinxVerbatim} \sphinxAtStartPar Only the name, oid, and pathname are required. \sphinxstyleemphasis{name} is the mechanism name, which may be used for debugging or logging purposes. \sphinxstyleemphasis{oid} is the object identifier of the GSSAPI mechanism to be registered. \sphinxstyleemphasis{pathname} is a path to the module shared object or DLL. \sphinxstyleemphasis{options} (if present) are options provided to the plugin module, surrounded in square brackets. \sphinxstyleemphasis{type} (if present) can be used to indicate a special type of module. Currently the only special module type is “interposerâ€, for a module designed to intercept calls to other mechanisms. \sphinxAtStartPar If the environment variable \sphinxstylestrong{GSS\_MECH\_CONFIG} is set, its value is used as the sole mechanism configuration filename. \subsection{Configuration profile modules} \label{\detokenize{admin/host_config:configuration-profile-modules}}\label{\detokenize{admin/host_config:profile-plugin-config}} \sphinxAtStartPar A configuration profile module replaces the information source for {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} itself. To use a profile module, begin krb5.conf with the line: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{module} \PYG{n}{PATHNAME}\PYG{p}{:}\PYG{n}{STRING} \end{sphinxVerbatim} \sphinxAtStartPar where \sphinxstyleemphasis{PATHNAME} is a path to the module shared object or DLL, and \sphinxstyleemphasis{STRING} is a string to provide to the module. The module will then take over, and the rest of krb5.conf will be ignored. \sphinxstepscope \chapter{Backups of secure hosts} \label{\detokenize{admin/backup_host:backups-of-secure-hosts}}\label{\detokenize{admin/backup_host::doc}} \sphinxAtStartPar When you back up a secure host, you should exclude the host’s keytab file from the backup. If someone obtained a copy of the keytab from a backup, that person could make any host masquerade as the host whose keytab was compromised. In many configurations, knowledge of the host’s keytab also allows root access to the host. This could be particularly dangerous if the compromised keytab was from one of your KDCs. If the machine has a disk crash and the keytab file is lost, it is easy to generate another keytab file. (See {\hyperref[\detokenize{admin/appl_servers:add-princ-kt}]{\sphinxcrossref{\DUrole{std,std-ref}{Adding principals to keytabs}}}}.) If you are unable to exclude particular files from backups, you should ensure that the backups are kept as secure as the host’s root password. \section{Backing up the Kerberos database} \label{\detokenize{admin/backup_host:backing-up-the-kerberos-database}} \sphinxAtStartPar As with any file, it is possible that your Kerberos database could become corrupted. If this happens on one of the replica KDCs, you might never notice, since the next automatic propagation of the database would install a fresh copy. However, if it happens to the primary KDC, the corrupted database would be propagated to all of the replicas during the next propagation. For this reason, MIT recommends that you back up your Kerberos database regularly. Because the primary KDC is continuously dumping the database to a file in order to propagate it to the replica KDCs, it is a simple matter to have a cron job periodically copy the dump file to a secure machine elsewhere on your network. (Of course, it is important to make the host where these backups are stored as secure as your KDCs, and to encrypt its transmission across your network.) Then if your database becomes corrupted, you can load the most recent dump onto the primary KDC. (See {\hyperref[\detokenize{admin/database:restore-from-dump}]{\sphinxcrossref{\DUrole{std,std-ref}{Dumping and loading a Kerberos database}}}}.) \sphinxstepscope \chapter{PKINIT configuration} \label{\detokenize{admin/pkinit:pkinit-configuration}}\label{\detokenize{admin/pkinit:pkinit}}\label{\detokenize{admin/pkinit::doc}} \sphinxAtStartPar PKINIT is a preauthentication mechanism for Kerberos 5 which uses X.509 certificates to authenticate the KDC to clients and vice versa. PKINIT can also be used to enable anonymity support, allowing clients to communicate securely with the KDC or with application servers without authenticating as a particular client principal. \section{Creating certificates} \label{\detokenize{admin/pkinit:creating-certificates}} \sphinxAtStartPar PKINIT requires an X.509 certificate for the KDC and one for each client principal which will authenticate using PKINIT. For anonymous PKINIT, a KDC certificate is required, but client certificates are not. A commercially issued server certificate can be used for the KDC certificate, but generally cannot be used for client certificates. \sphinxAtStartPar The instruction in this section describe how to establish a certificate authority and create standard PKINIT certificates. Skip this section if you are using a commercially issued server certificate as the KDC certificate for anonymous PKINIT, or if you are configuring a client to use an Active Directory KDC. \subsection{Generating a certificate authority certificate} \label{\detokenize{admin/pkinit:generating-a-certificate-authority-certificate}} \sphinxAtStartPar You can establish a new certificate authority (CA) for use with a PKINIT deployment with the commands: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{openssl} \PYG{n}{genrsa} \PYG{o}{\PYGZhy{}}\PYG{n}{out} \PYG{n}{cakey}\PYG{o}{.}\PYG{n}{pem} \PYG{l+m+mi}{2048} \PYG{n}{openssl} \PYG{n}{req} \PYG{o}{\PYGZhy{}}\PYG{n}{key} \PYG{n}{cakey}\PYG{o}{.}\PYG{n}{pem} \PYG{o}{\PYGZhy{}}\PYG{n}{new} \PYG{o}{\PYGZhy{}}\PYG{n}{x509} \PYG{o}{\PYGZhy{}}\PYG{n}{out} \PYG{n}{cacert}\PYG{o}{.}\PYG{n}{pem} \PYG{o}{\PYGZhy{}}\PYG{n}{days} \PYG{l+m+mi}{3650} \end{sphinxVerbatim} \sphinxAtStartPar The second command will ask for the values of several certificate fields. These fields can be set to any values. You can adjust the expiration time of the CA certificate by changing the number after \sphinxcode{\sphinxupquote{\sphinxhyphen{}days}}. Since the CA certificate must be deployed to client machines each time it changes, it should normally have an expiration time far in the future; however, expiration times after 2037 may cause interoperability issues in rare circumstances. \sphinxAtStartPar The result of these commands will be two files, cakey.pem and cacert.pem. cakey.pem will contain a 2048\sphinxhyphen{}bit RSA private key, which must be carefully protected. cacert.pem will contain the CA certificate, which must be placed in the filesystems of the KDC and each client host. cakey.pem will be required to create KDC and client certificates. \subsection{Generating a KDC certificate} \label{\detokenize{admin/pkinit:generating-a-kdc-certificate}} \sphinxAtStartPar A KDC certificate for use with PKINIT is required to have some unusual fields, which makes generating them with OpenSSL somewhat complicated. First, you will need a file containing the following: \begin{sphinxVerbatim}[commandchars=\\\{\}] [kdc\PYGZus{}cert] basicConstraints=CA:FALSE keyUsage=nonRepudiation,digitalSignature,keyEncipherment,keyAgreement extendedKeyUsage=1.3.6.1.5.2.3.5 subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer issuerAltName=issuer:copy subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc\PYGZus{}princ\PYGZus{}name [kdc\PYGZus{}princ\PYGZus{}name] realm=EXP:0,GeneralString:\PYGZdl{}\PYGZob{}ENV::REALM\PYGZcb{} principal\PYGZus{}name=EXP:1,SEQUENCE:kdc\PYGZus{}principal\PYGZus{}seq [kdc\PYGZus{}principal\PYGZus{}seq] name\PYGZus{}type=EXP:0,INTEGER:2 name\PYGZus{}string=EXP:1,SEQUENCE:kdc\PYGZus{}principals [kdc\PYGZus{}principals] princ1=GeneralString:krbtgt princ2=GeneralString:\PYGZdl{}\PYGZob{}ENV::REALM\PYGZcb{} \end{sphinxVerbatim} \sphinxAtStartPar If the above contents are placed in extensions.kdc, you can generate and sign a KDC certificate with the following commands: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{openssl} \PYG{n}{genrsa} \PYG{o}{\PYGZhy{}}\PYG{n}{out} \PYG{n}{kdckey}\PYG{o}{.}\PYG{n}{pem} \PYG{l+m+mi}{2048} \PYG{n}{openssl} \PYG{n}{req} \PYG{o}{\PYGZhy{}}\PYG{n}{new} \PYG{o}{\PYGZhy{}}\PYG{n}{out} \PYG{n}{kdc}\PYG{o}{.}\PYG{n}{req} \PYG{o}{\PYGZhy{}}\PYG{n}{key} \PYG{n}{kdckey}\PYG{o}{.}\PYG{n}{pem} \PYG{n}{env} \PYG{n}{REALM}\PYG{o}{=}\PYG{n}{YOUR\PYGZus{}REALMNAME} \PYG{n}{openssl} \PYG{n}{x509} \PYG{o}{\PYGZhy{}}\PYG{n}{req} \PYG{o}{\PYGZhy{}}\PYG{o+ow}{in} \PYG{n}{kdc}\PYG{o}{.}\PYG{n}{req} \PYGZbs{} \PYG{o}{\PYGZhy{}}\PYG{n}{CAkey} \PYG{n}{cakey}\PYG{o}{.}\PYG{n}{pem} \PYG{o}{\PYGZhy{}}\PYG{n}{CA} \PYG{n}{cacert}\PYG{o}{.}\PYG{n}{pem} \PYG{o}{\PYGZhy{}}\PYG{n}{out} \PYG{n}{kdc}\PYG{o}{.}\PYG{n}{pem} \PYG{o}{\PYGZhy{}}\PYG{n}{days} \PYG{l+m+mi}{365} \PYGZbs{} \PYG{o}{\PYGZhy{}}\PYG{n}{extfile} \PYG{n}{extensions}\PYG{o}{.}\PYG{n}{kdc} \PYG{o}{\PYGZhy{}}\PYG{n}{extensions} \PYG{n}{kdc\PYGZus{}cert} \PYG{o}{\PYGZhy{}}\PYG{n}{CAcreateserial} \PYG{n}{rm} \PYG{n}{kdc}\PYG{o}{.}\PYG{n}{req} \end{sphinxVerbatim} \sphinxAtStartPar The second command will ask for the values of certificate fields, which can be set to any values. In the third command, substitute your KDC’s realm name for YOUR\_REALMNAME. You can adjust the certificate’s expiration date by changing the number after \sphinxcode{\sphinxupquote{\sphinxhyphen{}days}}. Remember to create a new KDC certificate before the old one expires. \sphinxAtStartPar The result of this operation will be in two files, kdckey.pem and kdc.pem. Both files must be placed in the KDC’s filesystem. kdckey.pem, which contains the KDC’s private key, must be carefully protected. \sphinxAtStartPar If you examine the KDC certificate with \sphinxcode{\sphinxupquote{openssl x509 \sphinxhyphen{}in kdc.pem \sphinxhyphen{}text \sphinxhyphen{}noout}}, OpenSSL will not know how to display the KDC principal name in the Subject Alternative Name extension, so it will appear as \sphinxcode{\sphinxupquote{othername:\textless{}unsupported\textgreater{}}}. This is normal and does not mean anything is wrong with the KDC certificate. \subsection{Generating client certificates} \label{\detokenize{admin/pkinit:generating-client-certificates}} \sphinxAtStartPar PKINIT client certificates also must have some unusual certificate fields. To generate a client certificate with OpenSSL for a single\sphinxhyphen{}component principal name, you will need an extensions file (different from the KDC extensions file above) containing: \begin{sphinxVerbatim}[commandchars=\\\{\}] [client\PYGZus{}cert] basicConstraints=CA:FALSE keyUsage=digitalSignature,keyEncipherment,keyAgreement extendedKeyUsage=1.3.6.1.5.2.3.4 subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer issuerAltName=issuer:copy subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:princ\PYGZus{}name [princ\PYGZus{}name] realm=EXP:0,GeneralString:\PYGZdl{}\PYGZob{}ENV::REALM\PYGZcb{} principal\PYGZus{}name=EXP:1,SEQUENCE:principal\PYGZus{}seq [principal\PYGZus{}seq] name\PYGZus{}type=EXP:0,INTEGER:1 name\PYGZus{}string=EXP:1,SEQUENCE:principals [principals] princ1=GeneralString:\PYGZdl{}\PYGZob{}ENV::CLIENT\PYGZcb{} \end{sphinxVerbatim} \sphinxAtStartPar If the above contents are placed in extensions.client, you can generate and sign a client certificate with the following commands: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{openssl} \PYG{n}{genrsa} \PYG{o}{\PYGZhy{}}\PYG{n}{out} \PYG{n}{clientkey}\PYG{o}{.}\PYG{n}{pem} \PYG{l+m+mi}{2048} \PYG{n}{openssl} \PYG{n}{req} \PYG{o}{\PYGZhy{}}\PYG{n}{new} \PYG{o}{\PYGZhy{}}\PYG{n}{key} \PYG{n}{clientkey}\PYG{o}{.}\PYG{n}{pem} \PYG{o}{\PYGZhy{}}\PYG{n}{out} \PYG{n}{client}\PYG{o}{.}\PYG{n}{req} \PYG{n}{env} \PYG{n}{REALM}\PYG{o}{=}\PYG{n}{YOUR\PYGZus{}REALMNAME} \PYG{n}{CLIENT}\PYG{o}{=}\PYG{n}{YOUR\PYGZus{}PRINCNAME} \PYG{n}{openssl} \PYG{n}{x509} \PYGZbs{} \PYG{o}{\PYGZhy{}}\PYG{n}{CAkey} \PYG{n}{cakey}\PYG{o}{.}\PYG{n}{pem} \PYG{o}{\PYGZhy{}}\PYG{n}{CA} \PYG{n}{cacert}\PYG{o}{.}\PYG{n}{pem} \PYG{o}{\PYGZhy{}}\PYG{n}{req} \PYG{o}{\PYGZhy{}}\PYG{o+ow}{in} \PYG{n}{client}\PYG{o}{.}\PYG{n}{req} \PYGZbs{} \PYG{o}{\PYGZhy{}}\PYG{n}{extensions} \PYG{n}{client\PYGZus{}cert} \PYG{o}{\PYGZhy{}}\PYG{n}{extfile} \PYG{n}{extensions}\PYG{o}{.}\PYG{n}{client} \PYGZbs{} \PYG{o}{\PYGZhy{}}\PYG{n}{days} \PYG{l+m+mi}{365} \PYG{o}{\PYGZhy{}}\PYG{n}{out} \PYG{n}{client}\PYG{o}{.}\PYG{n}{pem} \PYG{n}{rm} \PYG{n}{client}\PYG{o}{.}\PYG{n}{req} \end{sphinxVerbatim} \sphinxAtStartPar Normally, the first two commands should be run on the client host, and the resulting client.req file transferred to the certificate authority host for the third command. As in the previous steps, the second command will ask for the values of certificate fields, which can be set to any values. In the third command, substitute your realm’s name for YOUR\_REALMNAME and the client’s principal name (without realm) for YOUR\_PRINCNAME. You can adjust the certificate’s expiration date by changing the number after \sphinxcode{\sphinxupquote{\sphinxhyphen{}days}}. \sphinxAtStartPar The result of this operation will be two files, clientkey.pem and client.pem. Both files must be present on the client’s host; clientkey.pem, which contains the client’s private key, must be protected from access by others. \sphinxAtStartPar As in the KDC certificate, OpenSSL will display the client principal name as \sphinxcode{\sphinxupquote{othername:\textless{}unsupported\textgreater{}}} in the Subject Alternative Name extension of a PKINIT client certificate. \sphinxAtStartPar If the client principal name contains more than one component (e.g. \sphinxcode{\sphinxupquote{host/example.com@REALM}}), the \sphinxcode{\sphinxupquote{{[}principals{]}}} section of \sphinxcode{\sphinxupquote{extensions.client}} must be altered to contain multiple entries. (Simply setting \sphinxcode{\sphinxupquote{CLIENT}} to \sphinxcode{\sphinxupquote{host/example.com}} would generate a certificate for \sphinxcode{\sphinxupquote{host\textbackslash{}/example.com@REALM}} which would not match the multi\sphinxhyphen{}component principal name.) For a two\sphinxhyphen{}component principal, the section should read: \begin{sphinxVerbatim}[commandchars=\\\{\}] [principals] princ1=GeneralString:\PYGZdl{}\PYGZob{}ENV::CLIENT1\PYGZcb{} princ2=GeneralString:\PYGZdl{}\PYGZob{}ENV::CLIENT2\PYGZcb{} \end{sphinxVerbatim} \sphinxAtStartPar The environment variables \sphinxcode{\sphinxupquote{CLIENT1}} and \sphinxcode{\sphinxupquote{CLIENT2}} must then be set to the first and second components when running \sphinxcode{\sphinxupquote{openssl x509}}. \section{Configuring the KDC} \label{\detokenize{admin/pkinit:configuring-the-kdc}} \sphinxAtStartPar The KDC must have filesystem access to the KDC certificate (kdc.pem) and the KDC private key (kdckey.pem). Configure the following relation in the KDC’s {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} file, either in the {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdcdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}kdcdefaults{]}}}}} section or in a {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} subsection (with appropriate pathnames): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{pkinit\PYGZus{}identity} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{lib}\PYG{o}{/}\PYG{n}{krb5kdc}\PYG{o}{/}\PYG{n}{kdc}\PYG{o}{.}\PYG{n}{pem}\PYG{p}{,}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{lib}\PYG{o}{/}\PYG{n}{krb5kdc}\PYG{o}{/}\PYG{n}{kdckey}\PYG{o}{.}\PYG{n}{pem} \end{sphinxVerbatim} \sphinxAtStartPar If any clients will authenticate using regular (as opposed to anonymous) PKINIT, the KDC must also have filesystem access to the CA certificate (cacert.pem), and the following configuration (with the appropriate pathname): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{pkinit\PYGZus{}anchors} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{var}\PYG{o}{/}\PYG{n}{lib}\PYG{o}{/}\PYG{n}{krb5kdc}\PYG{o}{/}\PYG{n}{cacert}\PYG{o}{.}\PYG{n}{pem} \end{sphinxVerbatim} \sphinxAtStartPar Because of the larger size of requests and responses using PKINIT, you may also need to allow TCP access to the KDC: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdc\PYGZus{}tcp\PYGZus{}listen} \PYG{o}{=} \PYG{l+m+mi}{88} \end{sphinxVerbatim} \sphinxAtStartPar Restart the {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} daemon to pick up the configuration changes. \sphinxAtStartPar The principal entry for each PKINIT\sphinxhyphen{}using client must be configured to require preauthentication. Ensure this with the command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin} \PYG{o}{\PYGZhy{}}\PYG{n}{q} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{modprinc +requires\PYGZus{}preauth YOUR\PYGZus{}PRINCNAME}\PYG{l+s+s1}{\PYGZsq{}} \end{sphinxVerbatim} \sphinxAtStartPar Starting with release 1.12, it is possible to remove the long\sphinxhyphen{}term keys of a principal entry, which can save some space in the database and help to clarify some PKINIT\sphinxhyphen{}related error conditions by not asking for a password: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin} \PYG{o}{\PYGZhy{}}\PYG{n}{q} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{purgekeys \PYGZhy{}all YOUR\PYGZus{}PRINCNAME}\PYG{l+s+s1}{\PYGZsq{}} \end{sphinxVerbatim} \sphinxAtStartPar These principal options can also be specified at principal creation time as follows: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin} \PYG{o}{\PYGZhy{}}\PYG{n}{q} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{add\PYGZus{}principal +requires\PYGZus{}preauth \PYGZhy{}nokey YOUR\PYGZus{}PRINCNAME}\PYG{l+s+s1}{\PYGZsq{}} \end{sphinxVerbatim} \sphinxAtStartPar By default, the KDC requires PKINIT client certificates to have the standard Extended Key Usage and Subject Alternative Name attributes for PKINIT. Starting in release 1.16, it is possible to authorize client certificates based on the subject or other criteria instead of the standard PKINIT Subject Alternative Name, by setting the \sphinxstylestrong{pkinit\_cert\_match} string attribute on each client principal entry. For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin} \PYG{n}{set\PYGZus{}string} \PYG{n}{user}\PYG{n+nd}{@REALM} \PYG{n}{pkinit\PYGZus{}cert\PYGZus{}match} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZlt{}SUBJECT\PYGZgt{}CN=user@REALM\PYGZdl{}}\PYG{l+s+s2}{\PYGZdq{}} \end{sphinxVerbatim} \sphinxAtStartPar The \sphinxstylestrong{pkinit\_cert\_match} string attribute follows the syntax used by the {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} \sphinxstylestrong{pkinit\_cert\_match} relation. To allow the use of non\sphinxhyphen{}PKINIT client certificates, it will also be necessary to disable key usage checking using the \sphinxstylestrong{pkinit\_eku\_checking} relation; for example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{kdcdefaults}\PYG{p}{]} \PYG{n}{pkinit\PYGZus{}eku\PYGZus{}checking} \PYG{o}{=} \PYG{n}{none} \end{sphinxVerbatim} \section{Configuring the clients} \label{\detokenize{admin/pkinit:configuring-the-clients}} \sphinxAtStartPar Client hosts must be configured to trust the issuing authority for the KDC certificate. For a newly established certificate authority, the client host must have filesystem access to the CA certificate (cacert.pem) and the following relation in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} in the appropriate {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} subsection (with appropriate pathnames): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{pkinit\PYGZus{}anchors} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{/}\PYG{n}{cacert}\PYG{o}{.}\PYG{n}{pem} \end{sphinxVerbatim} \sphinxAtStartPar If the KDC certificate is a commercially issued server certificate, the issuing certificate is most likely included in a system directory. You can specify it by filename as above, or specify the whole directory like so: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{pkinit\PYGZus{}anchors} \PYG{o}{=} \PYG{n}{DIR}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{ssl}\PYG{o}{/}\PYG{n}{certs} \end{sphinxVerbatim} \sphinxAtStartPar A commercially issued server certificate will usually not have the standard PKINIT principal name or Extended Key Usage extensions, so the following additional configuration is required: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{pkinit\PYGZus{}eku\PYGZus{}checking} \PYG{o}{=} \PYG{n}{kpServerAuth} \PYG{n}{pkinit\PYGZus{}kdc\PYGZus{}hostname} \PYG{o}{=} \PYG{n}{hostname}\PYG{o}{.}\PYG{n}{of}\PYG{o}{.}\PYG{n}{kdc}\PYG{o}{.}\PYG{n}{certificate} \end{sphinxVerbatim} \sphinxAtStartPar Multiple \sphinxstylestrong{pkinit\_kdc\_hostname} relations can be configured to recognize multiple KDC certificates. If the KDC is an Active Directory domain controller, setting \sphinxstylestrong{pkinit\_kdc\_hostname} is necessary, but it should not be necessary to set \sphinxstylestrong{pkinit\_eku\_checking}. \sphinxAtStartPar To perform regular (as opposed to anonymous) PKINIT authentication, a client host must have filesystem access to a client certificate (client.pem), and the corresponding private key (clientkey.pem). Configure the following relations in the client host’s {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} file in the appropriate {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} subsection (with appropriate pathnames): \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{pkinit\PYGZus{}identities} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{/}\PYG{n}{client}\PYG{o}{.}\PYG{n}{pem}\PYG{p}{,}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{/}\PYG{n}{clientkey}\PYG{o}{.}\PYG{n}{pem} \end{sphinxVerbatim} \sphinxAtStartPar If the KDC and client are properly configured, it should now be possible to run \sphinxcode{\sphinxupquote{kinit username}} without entering a password. \section{Anonymous PKINIT} \label{\detokenize{admin/pkinit:anonymous-pkinit}}\label{\detokenize{admin/pkinit:id1}} \sphinxAtStartPar Anonymity support in Kerberos allows a client to obtain a ticket without authenticating as any particular principal. Such a ticket can be used as a FAST armor ticket, or to securely communicate with an application server anonymously. \sphinxAtStartPar To configure anonymity support, you must generate or otherwise procure a KDC certificate and configure the KDC host, but you do not need to generate any client certificates. On the KDC, you must set the \sphinxstylestrong{pkinit\_identity} variable to provide the KDC certificate, but do not need to set the \sphinxstylestrong{pkinit\_anchors} variable or store the issuing certificate if you won’t have any client certificates to verify. On client hosts, you must set the \sphinxstylestrong{pkinit\_anchors} variable (and possibly \sphinxstylestrong{pkinit\_kdc\_hostname} and \sphinxstylestrong{pkinit\_eku\_checking}) in order to trust the issuing authority for the KDC certificate, but do not need to set the \sphinxstylestrong{pkinit\_identities} variable. \sphinxAtStartPar Anonymity support is not enabled by default. To enable it, you must create the principal \sphinxcode{\sphinxupquote{WELLKNOWN/ANONYMOUS}} using the command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin} \PYG{o}{\PYGZhy{}}\PYG{n}{q} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{addprinc \PYGZhy{}randkey WELLKNOWN/ANONYMOUS}\PYG{l+s+s1}{\PYGZsq{}} \end{sphinxVerbatim} \sphinxAtStartPar Some Kerberos deployments include application servers which lack proper access control, and grant some level of access to any user who can authenticate. In such an environment, enabling anonymity support on the KDC would present a security issue. If you need to enable anonymity support for TGTs (for use as FAST armor tickets) without enabling anonymous authentication to application servers, you can set the variable \sphinxstylestrong{restrict\_anonymous\_to\_tgt} to \sphinxcode{\sphinxupquote{true}} in the appropriate {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} subsection of the KDC’s {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} file. \sphinxAtStartPar To obtain anonymous credentials on a client, run \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}n}}, or \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}n @REALMNAME}} to specify a realm. The resulting tickets will have the client name \sphinxcode{\sphinxupquote{WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS}}. \section{Freshness tokens} \label{\detokenize{admin/pkinit:freshness-tokens}} \sphinxAtStartPar Freshness tokens can ensure that the client has recently had access to its certificate private key. If freshness tokens are not required by the KDC, a client program with temporary possession of the private key can compose requests for future timestamps and use them later. \sphinxAtStartPar In release 1.17 and later, freshness tokens are supported by the client and are sent by the KDC when the client indicates support for them. Because not all clients support freshness tokens yet, they are not required by default. To check if freshness tokens are supported by a realm’s clients, look in the KDC logs for the lines: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{PKINIT}\PYG{p}{:} \PYG{n}{freshness} \PYG{n}{token} \PYG{n}{received} \PYG{k+kn}{from} \PYG{o}{\PYGZlt{}}\PYG{n}{client} \PYG{n}{principal}\PYG{o}{\PYGZgt{}} \PYG{n}{PKINIT}\PYG{p}{:} \PYG{n}{no} \PYG{n}{freshness} \PYG{n}{token} \PYG{n}{received} \PYG{k+kn}{from} \PYG{o}{\PYGZlt{}}\PYG{n}{client} \PYG{n}{principal}\PYG{o}{\PYGZgt{}} \end{sphinxVerbatim} \sphinxAtStartPar To require freshness tokens for all clients in a realm (except for clients authenticating anonymously), set the \sphinxstylestrong{pkinit\_require\_freshness} variable to \sphinxcode{\sphinxupquote{true}} in the appropriate {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} subsection of the KDC’s {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} file. To test that this option is in effect, run \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}X disable\_freshness}} and verify that authentication is unsuccessful. \sphinxstepscope \chapter{OTP Preauthentication} \label{\detokenize{admin/otp:otp-preauthentication}}\label{\detokenize{admin/otp:otp-preauth}}\label{\detokenize{admin/otp::doc}} \sphinxAtStartPar OTP is a preauthentication mechanism for Kerberos 5 which uses One Time Passwords (OTP) to authenticate the client to the KDC. The OTP is passed to the KDC over an encrypted FAST channel in clear\sphinxhyphen{}text. The KDC uses the password along with per\sphinxhyphen{}user configuration to proxy the request to a third\sphinxhyphen{}party RADIUS system. This enables out\sphinxhyphen{}of\sphinxhyphen{}the\sphinxhyphen{}box compatibility with a large number of already widely deployed proprietary systems. \sphinxAtStartPar Additionally, our implementation of the OTP system allows for the passing of RADIUS requests over a UNIX domain stream socket. This permits the use of a local companion daemon which can handle the details of authentication. \section{Defining token types} \label{\detokenize{admin/otp:defining-token-types}} \sphinxAtStartPar Token types are defined in either {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} or {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} according to the following format: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{otp}\PYG{p}{]} \PYG{o}{\PYGZlt{}}\PYG{n}{name}\PYG{o}{\PYGZgt{}} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{server} \PYG{o}{=} \PYG{o}{\PYGZlt{}}\PYG{n}{host}\PYG{p}{:}\PYG{n}{port} \PYG{o+ow}{or} \PYG{n}{filename}\PYG{o}{\PYGZgt{}} \PYG{p}{(}\PYG{n}{default}\PYG{p}{:} \PYG{n}{see} \PYG{n}{below}\PYG{p}{)} \PYG{n}{secret} \PYG{o}{=} \PYG{o}{\PYGZlt{}}\PYG{n}{filename}\PYG{o}{\PYGZgt{}} \PYG{n}{timeout} \PYG{o}{=} \PYG{o}{\PYGZlt{}}\PYG{n}{integer}\PYG{o}{\PYGZgt{}} \PYG{p}{(}\PYG{n}{default}\PYG{p}{:} \PYG{l+m+mi}{5} \PYG{p}{[}\PYG{n}{seconds}\PYG{p}{]}\PYG{p}{)} \PYG{n}{retries} \PYG{o}{=} \PYG{o}{\PYGZlt{}}\PYG{n}{integer}\PYG{o}{\PYGZgt{}} \PYG{p}{(}\PYG{n}{default}\PYG{p}{:} \PYG{l+m+mi}{3}\PYG{p}{)} \PYG{n}{strip\PYGZus{}realm} \PYG{o}{=} \PYG{o}{\PYGZlt{}}\PYG{n}{boolean}\PYG{o}{\PYGZgt{}} \PYG{p}{(}\PYG{n}{default}\PYG{p}{:} \PYG{n}{true}\PYG{p}{)} \PYG{n}{indicator} \PYG{o}{=} \PYG{o}{\PYGZlt{}}\PYG{n}{string}\PYG{o}{\PYGZgt{}} \PYG{p}{(}\PYG{n}{default}\PYG{p}{:} \PYG{n}{none}\PYG{p}{)} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar If the server field begins with ‘/’, it will be interpreted as a UNIX socket. Otherwise, it is assumed to be in the format host:port. When a UNIX domain socket is specified, the secret field is optional and an empty secret is used by default. If the server field is not specified, it defaults to {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{RUNSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/\textless{}name\textgreater{}.socket}}. \sphinxAtStartPar When forwarding the request over RADIUS, by default the principal is used in the User\sphinxhyphen{}Name attribute of the RADIUS packet. The strip\_realm parameter controls whether the principal is forwarded with or without the realm portion. \sphinxAtStartPar If an indicator field is present, tickets issued using this token type will be annotated with the specified authentication indicator (see {\hyperref[\detokenize{admin/auth_indicator:auth-indicator}]{\sphinxcrossref{\DUrole{std,std-ref}{Authentication indicators}}}}). This key may be specified multiple times to add multiple indicators. \section{The default token type} \label{\detokenize{admin/otp:the-default-token-type}} \sphinxAtStartPar A default token type is used internally when no token type is specified for a given user. It is defined as follows: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{otp}\PYG{p}{]} \PYG{n}{DEFAULT} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{strip\PYGZus{}realm} \PYG{o}{=} \PYG{n}{false} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar The administrator may override the internal \sphinxcode{\sphinxupquote{DEFAULT}} token type simply by defining a configuration with the same name. \section{Token instance configuration} \label{\detokenize{admin/otp:token-instance-configuration}} \sphinxAtStartPar To enable OTP for a client principal, the administrator must define the \sphinxstylestrong{otp} string attribute for that principal. (See {\hyperref[\detokenize{admin/admin_commands/kadmin_local:set-string}]{\sphinxcrossref{\DUrole{std,std-ref}{set\_string}}}}.) The \sphinxstylestrong{otp} user string is a JSON string of the format: \begin{sphinxVerbatim}[commandchars=\\\{\}] [\PYGZob{} \PYG{+w}{ }\PYGZdq{}type\PYGZdq{}:\PYG{+w}{ }\PYG{n+nt}{\PYGZlt{}string}\PYG{n+nt}{\PYGZgt{}}, \PYG{+w}{ }\PYGZdq{}username\PYGZdq{}:\PYG{+w}{ }\PYG{n+nt}{\PYGZlt{}string}\PYG{n+nt}{\PYGZgt{}}, \PYG{+w}{ }\PYGZdq{}indicators\PYGZdq{}:\PYG{+w}{ }[\PYG{n+nt}{\PYGZlt{}string}\PYG{n+nt}{\PYGZgt{}},\PYG{+w}{ }...] \PYG{+w}{ }\PYGZcb{},\PYG{+w}{ }...] \end{sphinxVerbatim} \sphinxAtStartPar This is an array of token objects. Both fields of token objects are optional. The \sphinxstylestrong{type} field names the token type of this token; if not specified, it defaults to \sphinxcode{\sphinxupquote{DEFAULT}}. The \sphinxstylestrong{username} field specifies the value to be sent in the User\sphinxhyphen{}Name RADIUS attribute. If not specified, the principal name is sent, with or without realm as defined in the token type. The \sphinxstylestrong{indicators} field specifies a list of authentication indicators to annotate tickets with, overriding any indicators specified in the token type. \sphinxAtStartPar For ease of configuration, an empty array (\sphinxcode{\sphinxupquote{{[}{]}}}) is treated as equivalent to one DEFAULT token (\sphinxcode{\sphinxupquote{{[}\{\}{]}}}). \section{Other considerations} \label{\detokenize{admin/otp:other-considerations}}\begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar FAST is required for OTP to work. \end{enumerate} \sphinxstepscope \chapter{SPAKE Preauthentication} \label{\detokenize{admin/spake:spake-preauthentication}}\label{\detokenize{admin/spake:spake}}\label{\detokenize{admin/spake::doc}} \sphinxAtStartPar SPAKE preauthentication (added in release 1.17) uses public key cryptography techniques to protect against {\hyperref[\detokenize{admin/dictionary:dictionary}]{\sphinxcrossref{\DUrole{std,std-ref}{password dictionary attacks}}}}. Unlike {\hyperref[\detokenize{admin/pkinit:pkinit}]{\sphinxcrossref{\DUrole{std,std-ref}{PKINIT}}}}, it does not require any additional infrastructure such as certificates; it simply needs to be turned on. Using SPAKE preauthentication may modestly increase the CPU and network load on the KDC. \sphinxAtStartPar SPAKE preauthentication can use one of four elliptic curve groups for its password\sphinxhyphen{}authenticated key exchange. The recommended group is \sphinxcode{\sphinxupquote{edwards25519}}; three NIST curves (\sphinxcode{\sphinxupquote{P\sphinxhyphen{}256}}, \sphinxcode{\sphinxupquote{P\sphinxhyphen{}384}}, and \sphinxcode{\sphinxupquote{P\sphinxhyphen{}521}}) are also supported. \sphinxAtStartPar By default, SPAKE with the \sphinxcode{\sphinxupquote{edwards25519}} group is enabled on clients, but the KDC does not offer SPAKE by default. To turn it on, set the \sphinxstylestrong{spake\_preauth\_groups} variable in {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}} to a list of allowed groups. This variable affects both the client and the KDC. Simply setting it to \sphinxcode{\sphinxupquote{edwards25519}} is recommended: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{libdefaults}\PYG{p}{]} \PYG{n}{spake\PYGZus{}preauth\PYGZus{}groups} \PYG{o}{=} \PYG{n}{edwards25519} \end{sphinxVerbatim} \sphinxAtStartPar Set the \sphinxstylestrong{+requires\_preauth} and \sphinxstylestrong{\sphinxhyphen{}allow\_svr} flags on client principal entries, as you would for any preauthentication mechanism: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{modprinc} \PYG{o}{+}\PYG{n}{requires\PYGZus{}preauth} \PYG{o}{\PYGZhy{}}\PYG{n}{allow\PYGZus{}svr} \PYG{n}{PRINCNAME} \end{sphinxVerbatim} \sphinxAtStartPar Clients which do not implement SPAKE preauthentication will fall back to encrypted timestamp. \sphinxAtStartPar An active attacker can force a fallback to encrypted timestamp by modifying the initial KDC response, defeating the protection against dictionary attacks. To prevent this fallback on clients which do implement SPAKE preauthentication, set the \sphinxstylestrong{disable\_encrypted\_timestamp} variable to \sphinxcode{\sphinxupquote{true}} in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} subsection for realms whose KDCs offer SPAKE preauthentication. \sphinxAtStartPar By default, SPAKE preauthentication requires an extra network round trip to the KDC during initial authentication. If most of the clients in a realm support SPAKE, this extra round trip can be eliminated using an optimistic challenge, by setting the \sphinxstylestrong{spake\_preauth\_kdc\_challenge} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdcdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}kdcdefaults{]}}}}} to a single group name: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{kdcdefaults}\PYG{p}{]} \PYG{n}{spake\PYGZus{}preauth\PYGZus{}kdc\PYGZus{}challenge} \PYG{o}{=} \PYG{n}{edwards25519} \end{sphinxVerbatim} \sphinxAtStartPar Using optimistic challenge will cause the KDC to do extra work for initial authentication requests that do not result in SPAKE preauthentication, but will save work when SPAKE preauthentication is used. \sphinxstepscope \chapter{Addressing dictionary attack risks} \label{\detokenize{admin/dictionary:addressing-dictionary-attack-risks}}\label{\detokenize{admin/dictionary:dictionary}}\label{\detokenize{admin/dictionary::doc}} \sphinxAtStartPar Kerberos initial authentication is normally secured using the client principal’s long\sphinxhyphen{}term key, which for users is generally derived from a password. Using a pasword\sphinxhyphen{}derived long\sphinxhyphen{}term key carries the risk of a dictionary attack, where an attacker tries a sequence of possible passwords, possibly requiring much less effort than would be required to try all possible values of the key. Even if {\hyperref[\detokenize{admin/database:policies}]{\sphinxcrossref{\DUrole{std,std-ref}{password policy objects}}}} are used to force users not to pick trivial passwords, dictionary attacks can sometimes be successful against a significant fraction of the users in a realm. Dictionary attacks are not a concern for principals using random keys. \sphinxAtStartPar A dictionary attack may be online or offline. An online dictionary attack is performed by trying each password in a separate request to the KDC, and is therefore visible to the KDC and also limited in speed by the KDC’s processing power and the network capacity between the client and the KDC. Online dictionary attacks can be mitigated using {\hyperref[\detokenize{admin/lockout:lockout}]{\sphinxcrossref{\DUrole{std,std-ref}{account lockout}}}}. This measure is not totally satisfactory, as it makes it easy for an attacker to deny access to a client principal. \sphinxAtStartPar An offline dictionary attack is performed by obtaining a ciphertext generated using the password\sphinxhyphen{}derived key, and trying each password against the ciphertext. This category of attack is invisible to the KDC and can be performed much faster than an online attack. The attack will generally take much longer with more recent encryption types (particularly the ones based on AES), because those encryption types use a much more expensive string\sphinxhyphen{}to\sphinxhyphen{}key function. However, the best defense is to deny the attacker access to a useful ciphertext. The required defensive measures depend on the attacker’s level of network access. \sphinxAtStartPar An off\sphinxhyphen{}path attacker has no access to packets sent between legitimate users and the KDC. An off\sphinxhyphen{}path attacker could gain access to an attackable ciphertext either by making an AS request for a client principal which does not have the \sphinxstylestrong{+requires\_preauth} flag, or by making a TGS request (after authenticating as a different user) for a server principal which does not have the \sphinxstylestrong{\sphinxhyphen{}allow\_svr} flag. To address off\sphinxhyphen{}path attackers, a KDC administrator should set those flags on principals with password\sphinxhyphen{}derived keys: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{add\PYGZus{}principal} \PYG{o}{+}\PYG{n}{requires\PYGZus{}preauth} \PYG{o}{\PYGZhy{}}\PYG{n}{allow\PYGZus{}svr} \PYG{n}{princname} \end{sphinxVerbatim} \sphinxAtStartPar An attacker with passive network access (one who can monitor packets sent between legitimate users and the KDC, but cannot change them or insert their own packets) can gain access to an attackable ciphertext by observing an authentication by a user using the most common form of preauthentication, encrypted timestamp. Any of the following methods can prevent dictionary attacks by attackers with passive network access: \begin{itemize} \item {} \sphinxAtStartPar Enabling {\hyperref[\detokenize{admin/spake:spake}]{\sphinxcrossref{\DUrole{std,std-ref}{SPAKE preauthentication}}}} (added in release 1.17) on the KDC, and ensuring that all clients are able to support it. \item {} \sphinxAtStartPar Using an {\hyperref[\detokenize{admin/https:https}]{\sphinxcrossref{\DUrole{std,std-ref}{HTTPS proxy}}}} for communication with the KDC, if the attacker cannot monitor communication between the proxy server and the KDC. \item {} \sphinxAtStartPar Using FAST, protecting the initial authentication with either a random key (such as a host key) or with {\hyperref[\detokenize{admin/pkinit:anonymous-pkinit}]{\sphinxcrossref{\DUrole{std,std-ref}{anonymous PKINIT}}}}. \end{itemize} \sphinxAtStartPar An attacker with active network access (one who can inject or modify packets sent between legitimate users and the KDC) can try to fool the client software into sending an attackable ciphertext using an encryption type and salt string of the attacker’s choosing. Any of the following methods can prevent dictionary attacks by active attackers: \begin{itemize} \item {} \sphinxAtStartPar Enabling SPAKE preauthentication and setting the \sphinxstylestrong{disable\_encrypted\_timestamp} variable to \sphinxcode{\sphinxupquote{true}} in the {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} subsection of the client configuration. \item {} \sphinxAtStartPar Using an HTTPS proxy as described above, configured in the client’s krb5.conf realm configuration. If {\hyperref[\detokenize{admin/realm_config:kdc-discovery}]{\sphinxcrossref{\DUrole{std,std-ref}{KDC discovery}}}} is used to locate a proxy server, an active attacker may be able to use DNS spoofing to cause the client to use a different HTTPS server or to not use HTTPS. \item {} \sphinxAtStartPar Using FAST as described above. \end{itemize} \sphinxAtStartPar If {\hyperref[\detokenize{admin/pkinit:pkinit}]{\sphinxcrossref{\DUrole{std,std-ref}{PKINIT}}}} or {\hyperref[\detokenize{admin/otp:otp-preauth}]{\sphinxcrossref{\DUrole{std,std-ref}{OTP}}}} are used for initial authentication, the principal’s long\sphinxhyphen{}term keys are not used and dictionary attacks are usually not a concern. \sphinxstepscope \chapter{Principal names and DNS} \label{\detokenize{admin/princ_dns:principal-names-and-dns}}\label{\detokenize{admin/princ_dns::doc}} \sphinxAtStartPar Kerberos clients can do DNS lookups to canonicalize service principal names. This can cause difficulties when setting up Kerberos application servers, especially when the client’s name for the service is different from what the service thinks its name is. \section{Service principal names} \label{\detokenize{admin/princ_dns:service-principal-names}} \sphinxAtStartPar A frequently used kind of principal name is the host\sphinxhyphen{}based service principal name. This kind of principal name has two components: a service name and a hostname. For example, \sphinxcode{\sphinxupquote{imap/imap.example.com}} is the principal name of the “imap†service on the host “imap.example.comâ€. Other possible service names for the first component include “host†(remote login services such as ssh), “HTTPâ€, and “nfs†(Network File System). \sphinxAtStartPar Service administrators often publish well\sphinxhyphen{}known hostname aliases that they would prefer users to use instead of the canonical name of the service host. This gives service administrators more flexibility in deploying services. For example, a shell login server might be named “long\sphinxhyphen{}vanity\sphinxhyphen{}hostname.example.comâ€, but users will naturally prefer to type something like “login.example.comâ€. Hostname aliases also allow for administrators to set up load balancing for some sorts of services based on rotating \sphinxcode{\sphinxupquote{CNAME}} records in DNS. \section{Service principal canonicalization} \label{\detokenize{admin/princ_dns:service-principal-canonicalization}} \sphinxAtStartPar In the MIT krb5 client library, canonicalization of host\sphinxhyphen{}based service principals is controlled by the \sphinxstylestrong{dns\_canonicalize\_hostname}, \sphinxstylestrong{rnds}, and \sphinxstylestrong{qualify\_shortname} variables in {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}}. \sphinxAtStartPar If \sphinxstylestrong{dns\_canonicalize\_hostname} is set to \sphinxcode{\sphinxupquote{true}} (the default value), the client performs forward resolution by looking up the IPv4 and/or IPv6 addresses of the hostname using \sphinxcode{\sphinxupquote{getaddrinfo()}}. This process will typically add a domain suffix to the hostname if needed, and follow CNAME records in the DNS. If \sphinxstylestrong{rdns} is also set to \sphinxcode{\sphinxupquote{true}} (the default), the client will then perform a reverse lookup of the first returned Internet address using \sphinxcode{\sphinxupquote{getnameinfo()}}, finding the name associated with the PTR record. \sphinxAtStartPar If \sphinxstylestrong{dns\_canonicalize\_hostname} is set to \sphinxcode{\sphinxupquote{false}}, the hostname is not canonicalized using DNS. If the hostname has only one component (i.e. it contains no “.†characters), the host’s primary DNS search domain will be appended, if there is one. The \sphinxstylestrong{qualify\_shortname} variable can be used to override or disable this suffix. \sphinxAtStartPar If \sphinxstylestrong{dns\_canonicalize\_hostname} is set to \sphinxcode{\sphinxupquote{fallback}} (added in release 1.18), the hostname is initially treated according to the rules for \sphinxcode{\sphinxupquote{dns\_canonicalize\_hostname=false}}. If a ticket request fails because the service principal is unknown, the hostname will be canonicalized according to the rules for \sphinxcode{\sphinxupquote{dns\_canonicalize\_hostname=true}} and the request will be retried. \sphinxAtStartPar In all cases, the hostname is converted to lowercase, and any trailing dot is removed. \section{Reverse DNS mismatches} \label{\detokenize{admin/princ_dns:reverse-dns-mismatches}} \sphinxAtStartPar Sometimes, an enterprise will have control over its forward DNS but not its reverse DNS. The reverse DNS is sometimes under the control of the Internet service provider of the enterprise, and the enterprise may not have much influence in setting up reverse DNS records for its address space. If there are difficulties with getting forward and reverse DNS to match, it is best to set \sphinxcode{\sphinxupquote{rdns = false}} on client machines. \section{Overriding application behavior} \label{\detokenize{admin/princ_dns:overriding-application-behavior}} \sphinxAtStartPar Applications can choose to use a default hostname component in their service principal name when accepting authentication, which avoids some sorts of hostname mismatches. Because not all relevant applications do this yet, using the {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} setting: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{libdefaults}\PYG{p}{]} \PYG{n}{ignore\PYGZus{}acceptor\PYGZus{}hostname} \PYG{o}{=} \PYG{n}{true} \end{sphinxVerbatim} \sphinxAtStartPar will allow the Kerberos library to override the application’s choice of service principal hostname and will allow a server program to accept incoming authentications using any key in its keytab that matches the service name and realm name (if given). This setting defaults to “false†and is available in releases krb5\sphinxhyphen{}1.10 and later. \section{Provisioning keytabs} \label{\detokenize{admin/princ_dns:provisioning-keytabs}} \sphinxAtStartPar One service principal entry that should be in the keytab is a principal whose hostname component is the canonical hostname that \sphinxcode{\sphinxupquote{getaddrinfo()}} reports for all known aliases for the host. If the reverse DNS information does not match this canonical hostname, an additional service principal entry should be in the keytab for this different hostname. \section{Specific application advice} \label{\detokenize{admin/princ_dns:specific-application-advice}} \subsection{Secure shell (ssh)} \label{\detokenize{admin/princ_dns:secure-shell-ssh}} \sphinxAtStartPar Setting \sphinxcode{\sphinxupquote{GSSAPIStrictAcceptorCheck = no}} in the configuration file of modern versions of the openssh daemon will allow the daemon to try any key in its keytab when accepting a connection, rather than looking for the keytab entry that matches the host’s own idea of its name (typically the name that \sphinxcode{\sphinxupquote{gethostname()}} returns). This requires krb5\sphinxhyphen{}1.10 or later. \subsection{OpenLDAP (ldapsearch, etc.)} \label{\detokenize{admin/princ_dns:openldap-ldapsearch-etc}} \sphinxAtStartPar OpenLDAP’s SASL implementation performs reverse DNS lookup in order to canonicalize service principal names, even if \sphinxstylestrong{rdns} is set to \sphinxcode{\sphinxupquote{false}} in the Kerberos configuration. To disable this behavior, add \sphinxcode{\sphinxupquote{SASL\_NOCANON on}} to \sphinxcode{\sphinxupquote{ldap.conf}}, or set the \sphinxcode{\sphinxupquote{LDAPSASL\_NOCANON}} environment variable. \sphinxstepscope \chapter{Encryption types} \label{\detokenize{admin/enctypes:encryption-types}}\label{\detokenize{admin/enctypes:enctypes}}\label{\detokenize{admin/enctypes::doc}} \sphinxAtStartPar Kerberos can use a variety of cipher algorithms to protect data. A Kerberos \sphinxstylestrong{encryption type} (also known as an \sphinxstylestrong{enctype}) is a specific combination of a cipher algorithm with an integrity algorithm to provide both confidentiality and integrity to data. \section{Enctypes in requests} \label{\detokenize{admin/enctypes:enctypes-in-requests}} \sphinxAtStartPar Clients make two types of requests (KDC\sphinxhyphen{}REQ) to the KDC: AS\sphinxhyphen{}REQs and TGS\sphinxhyphen{}REQs. The client uses the AS\sphinxhyphen{}REQ to obtain initial tickets (typically a Ticket\sphinxhyphen{}Granting Ticket (TGT)), and uses the TGS\sphinxhyphen{}REQ to obtain service tickets. \sphinxAtStartPar The KDC uses three different keys when issuing a ticket to a client: \begin{itemize} \item {} \sphinxAtStartPar The long\sphinxhyphen{}term key of the service: the KDC uses this to encrypt the actual service ticket. The KDC only uses the first long\sphinxhyphen{}term key in the most recent kvno for this purpose. \item {} \sphinxAtStartPar The session key: the KDC randomly chooses this key and places one copy inside the ticket and the other copy inside the encrypted part of the reply. \item {} \sphinxAtStartPar The reply\sphinxhyphen{}encrypting key: the KDC uses this to encrypt the reply it sends to the client. For AS replies, this is a long\sphinxhyphen{}term key of the client principal. For TGS replies, this is either the session key of the authenticating ticket, or a subsession key. \end{itemize} \sphinxAtStartPar Each of these keys is of a specific enctype. \sphinxAtStartPar Each request type allows the client to submit a list of enctypes that it is willing to accept. For the AS\sphinxhyphen{}REQ, this list affects both the session key selection and the reply\sphinxhyphen{}encrypting key selection. For the TGS\sphinxhyphen{}REQ, this list only affects the session key selection. \section{Session key selection} \label{\detokenize{admin/enctypes:session-key-selection}}\label{\detokenize{admin/enctypes:id1}} \sphinxAtStartPar The KDC chooses the session key enctype by taking the intersection of its \sphinxstylestrong{permitted\_enctypes} list, the list of long\sphinxhyphen{}term keys for the most recent kvno of the service, and the client’s requested list of enctypes. Starting in krb5\sphinxhyphen{}1.21, all services are assumed to support aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96; also, des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 and arcfour\sphinxhyphen{}hmac session keys will not be issued by default. \sphinxAtStartPar Starting in krb5\sphinxhyphen{}1.11, it is possible to set a string attribute on a service principal to control what session key enctypes the KDC may issue for service tickets for that principal, overriding the service’s long\sphinxhyphen{}term keys and the assumption of aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 support. See {\hyperref[\detokenize{admin/admin_commands/kadmin_local:set-string}]{\sphinxcrossref{\DUrole{std,std-ref}{set\_string}}}} in {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} for details. \section{Choosing enctypes for a service} \label{\detokenize{admin/enctypes:choosing-enctypes-for-a-service}} \sphinxAtStartPar Generally, a service should have a key of the strongest enctype that both it and the KDC support. If the KDC is running a release earlier than krb5\sphinxhyphen{}1.11, it is also useful to generate an additional key for each enctype that the service can support. The KDC will only use the first key in the list of long\sphinxhyphen{}term keys for encrypting the service ticket, but the additional long\sphinxhyphen{}term keys indicate the other enctypes that the service supports. \sphinxAtStartPar As noted above, starting with release krb5\sphinxhyphen{}1.11, there are additional configuration settings that control session key enctype selection independently of the set of long\sphinxhyphen{}term keys that the KDC has stored for a service principal. \section{Configuration variables} \label{\detokenize{admin/enctypes:configuration-variables}} \sphinxAtStartPar The following \sphinxcode{\sphinxupquote{{[}libdefaults{]}}} settings in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} will affect how enctypes are chosen. \begin{description} \sphinxlineitem{\sphinxstylestrong{allow\_weak\_crypto}} \sphinxAtStartPar defaults to \sphinxstyleemphasis{false} starting with krb5\sphinxhyphen{}1.8. When \sphinxstyleemphasis{false}, removes weak enctypes from \sphinxstylestrong{permitted\_enctypes}, \sphinxstylestrong{default\_tkt\_enctypes}, and \sphinxstylestrong{default\_tgs\_enctypes}. Do not set this to \sphinxstyleemphasis{true} unless the use of weak enctypes is an acceptable risk for your environment and the weak enctypes are required for backward compatibility. \sphinxlineitem{\sphinxstylestrong{allow\_des3}} \sphinxAtStartPar was added in release 1.21 and defaults to \sphinxstyleemphasis{false}. Unless this flag is set to \sphinxstyleemphasis{true}, the KDC will not issue tickets with des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 session keys. In a future release, this flag will control whether des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 is permitted in similar fashion to weak enctypes. \sphinxlineitem{\sphinxstylestrong{allow\_rc4}} \sphinxAtStartPar was added in release 1.21 and defaults to \sphinxstyleemphasis{false}. Unless this flag is set to \sphinxstyleemphasis{true}, the KDC will not issue tickets with arcfour\sphinxhyphen{}hmac session keys. In a future release, this flag will control whether arcfour\sphinxhyphen{}hmac is permitted in similar fashion to weak enctypes. \sphinxlineitem{\sphinxstylestrong{permitted\_enctypes}} \sphinxAtStartPar controls the set of enctypes that a service will permit for session keys and for ticket and authenticator encryption. The KDC and other programs that access the Kerberos database will ignore keys of non\sphinxhyphen{}permitted enctypes. Starting in release 1.18, this setting also acts as the default for \sphinxstylestrong{default\_tkt\_enctypes} and \sphinxstylestrong{default\_tgs\_enctypes}. \sphinxlineitem{\sphinxstylestrong{default\_tkt\_enctypes}} \sphinxAtStartPar controls the default set of enctypes that the Kerberos client library requests when making an AS\sphinxhyphen{}REQ. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. \sphinxlineitem{\sphinxstylestrong{default\_tgs\_enctypes}} \sphinxAtStartPar controls the default set of enctypes that the Kerberos client library requests when making a TGS\sphinxhyphen{}REQ. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. \end{description} \sphinxAtStartPar The following per\sphinxhyphen{}realm setting in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} affects the generation of long\sphinxhyphen{}term keys. \begin{description} \sphinxlineitem{\sphinxstylestrong{supported\_enctypes}} \sphinxAtStartPar controls the default set of enctype\sphinxhyphen{}salttype pairs that {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} will use for generating long\sphinxhyphen{}term keys, either randomly or from passwords \end{description} \section{Enctype compatibility} \label{\detokenize{admin/enctypes:enctype-compatibility}} \sphinxAtStartPar See {\hyperref[\detokenize{admin/conf_files/kdc_conf:encryption-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Encryption types}}}} for additional information about enctypes. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TTTT} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar enctype &\sphinxstyletheadfamily \sphinxAtStartPar weak? &\sphinxstyletheadfamily \sphinxAtStartPar krb5 &\sphinxstyletheadfamily \sphinxAtStartPar Windows \\ \sphinxmidrule \sphinxtableatstartofbodyhook \sphinxAtStartPar des\sphinxhyphen{}cbc\sphinxhyphen{}crc & \sphinxAtStartPar weak & \sphinxAtStartPar \textless{}1.18 & \sphinxAtStartPar \textgreater{}=2000 \\ \sphinxhline \sphinxAtStartPar des\sphinxhyphen{}cbc\sphinxhyphen{}md4 & \sphinxAtStartPar weak & \sphinxAtStartPar \textless{}1.18 & \sphinxAtStartPar ? \\ \sphinxhline \sphinxAtStartPar des\sphinxhyphen{}cbc\sphinxhyphen{}md5 & \sphinxAtStartPar weak & \sphinxAtStartPar \textless{}1.18 & \sphinxAtStartPar \textgreater{}=2000 \\ \sphinxhline \sphinxAtStartPar des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 & \sphinxAtStartPar deprecated & \sphinxAtStartPar \textgreater{}=1.1 & \sphinxAtStartPar none \\ \sphinxhline \sphinxAtStartPar arcfour\sphinxhyphen{}hmac & \sphinxAtStartPar deprecated & \sphinxAtStartPar \textgreater{}=1.3 & \sphinxAtStartPar \textgreater{}=2000 \\ \sphinxhline \sphinxAtStartPar arcfour\sphinxhyphen{}hmac\sphinxhyphen{}exp & \sphinxAtStartPar weak & \sphinxAtStartPar \textgreater{}=1.3 & \sphinxAtStartPar \textgreater{}=2000 \\ \sphinxhline \sphinxAtStartPar aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 && \sphinxAtStartPar \textgreater{}=1.3 & \sphinxAtStartPar \textgreater{}=Vista \\ \sphinxhline \sphinxAtStartPar aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 && \sphinxAtStartPar \textgreater{}=1.3 & \sphinxAtStartPar \textgreater{}=Vista \\ \sphinxhline \sphinxAtStartPar aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha256\sphinxhyphen{}128 && \sphinxAtStartPar \textgreater{}=1.15 & \sphinxAtStartPar none \\ \sphinxhline \sphinxAtStartPar aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha384\sphinxhyphen{}192 && \sphinxAtStartPar \textgreater{}=1.15 & \sphinxAtStartPar none \\ \sphinxhline \sphinxAtStartPar camellia128\sphinxhyphen{}cts\sphinxhyphen{}cmac && \sphinxAtStartPar \textgreater{}=1.9 & \sphinxAtStartPar none \\ \sphinxhline \sphinxAtStartPar camellia256\sphinxhyphen{}cts\sphinxhyphen{}cmac && \sphinxAtStartPar \textgreater{}=1.9 & \sphinxAtStartPar none \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxAtStartPar krb5 releases 1.18 and later do not support single\sphinxhyphen{}DES. krb5 releases 1.8 and later disable the single\sphinxhyphen{}DES enctypes by default. Microsoft Windows releases Windows 7 and later disable single\sphinxhyphen{}DES enctypes by default. \sphinxAtStartPar krb5 releases 1.17 and later flag deprecated encryption types (including \sphinxcode{\sphinxupquote{des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1}} and \sphinxcode{\sphinxupquote{arcfour\sphinxhyphen{}hmac}}) in KDC logs and kadmin output. krb5 release 1.19 issues a warning during initial authentication if \sphinxcode{\sphinxupquote{des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1}} is used. Future releases will disable \sphinxcode{\sphinxupquote{des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1}} by default and eventually remove support for it. \section{Migrating away from older encryption types} \label{\detokenize{admin/enctypes:migrating-away-from-older-encryption-types}} \sphinxAtStartPar Administrator intervention may be required to migrate a realm away from legacy encryption types, especially if the realm was created using krb5 release 1.2 or earlier. This migration should be performed before upgrading to krb5 versions which disable or remove support for legacy encryption types. \sphinxAtStartPar If there is a \sphinxstylestrong{supported\_enctypes} setting in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} on the KDC, make sure that it does not include weak or deprecated encryption types. This will ensure that newly created keys do not use those encryption types by default. \sphinxAtStartPar Check the \sphinxcode{\sphinxupquote{krbtgt/REALM}} principal using the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} \sphinxstylestrong{getprinc} command. If it lists a weak or deprecated encryption type as the first key, it must be migrated using the procedure in {\hyperref[\detokenize{admin/database:changing-krbtgt-key}]{\sphinxcrossref{\DUrole{std,std-ref}{Changing the krbtgt key}}}}. \sphinxAtStartPar Check the \sphinxcode{\sphinxupquote{kadmin/history}} principal, which should have only one key entry. If it uses a weak or deprecated encryption type, it should be upgraded following the notes in {\hyperref[\detokenize{admin/database:updating-history-key}]{\sphinxcrossref{\DUrole{std,std-ref}{Updating the history key}}}}. \sphinxAtStartPar Check the other kadmin principals: kadmin/changepw, kadmin/admin, and any kadmin/hostname principals that may exist. These principals can be upgraded with \sphinxstylestrong{change\_password \sphinxhyphen{}randkey} in kadmin. \sphinxAtStartPar Check the \sphinxcode{\sphinxupquote{K/M}} entry. If it uses a weak or deprecated encryption type, it should be upgraded following the procedure in {\hyperref[\detokenize{admin/database:updating-master-key}]{\sphinxcrossref{\DUrole{std,std-ref}{Updating the master key}}}}. \sphinxAtStartPar User and service principals using legacy encryption types can be enumerated with the {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} \sphinxstylestrong{tabdump keyinfo} command. \sphinxAtStartPar Service principals can be migrated with a keytab rotation on the service host, which can be accomplished using the {\hyperref[\detokenize{admin/admin_commands/k5srvutil:k5srvutil-1}]{\sphinxcrossref{\DUrole{std,std-ref}{k5srvutil}}}} \sphinxstylestrong{change} and \sphinxstylestrong{delold} commands. Allow enough time for existing tickets to expire between the change and delold operations. \sphinxAtStartPar User principals with password\sphinxhyphen{}based keys can be migrated with a password change. The realm administrator can set a password expiration date using the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} \sphinxstylestrong{modify\_principal \sphinxhyphen{}pwexpire} command to force a password change. \sphinxAtStartPar If a legacy encryption type has not yet been disabled by default in the version of krb5 running on the KDC, it can be disabled administratively with the \sphinxstylestrong{permitted\_enctypes} variable. For example, setting \sphinxstylestrong{permitted\_enctypes} to \sphinxcode{\sphinxupquote{DEFAULT \sphinxhyphen{}des3 \sphinxhyphen{}rc4}} will cause any database keys of the triple\sphinxhyphen{}DES and RC4 encryption types to be ignored. \sphinxstepscope \chapter{HTTPS proxy configuration} \label{\detokenize{admin/https:https-proxy-configuration}}\label{\detokenize{admin/https:https}}\label{\detokenize{admin/https::doc}} \sphinxAtStartPar In addition to being able to use UDP or TCP to communicate directly with a KDC as is outlined in RFC4120, and with kpasswd services in a similar fashion, the client libraries can attempt to use an HTTPS proxy server to communicate with a KDC or kpasswd service, using the protocol outlined in {[}MS\sphinxhyphen{}KKDCP{]}. \sphinxAtStartPar Communicating with a KDC through an HTTPS proxy allows clients to contact servers when network firewalls might otherwise prevent them from doing so. The use of TLS also encrypts all traffic between the clients and the KDC, preventing observers from conducting password dictionary attacks or from observing the client and server principals being authenticated, at additional computational cost to both clients and servers. \sphinxAtStartPar An HTTPS proxy server is provided as a feature in some versions of Microsoft Windows Server, and a WSGI implementation named \sphinxtitleref{kdcproxy} is available in the python package index. \section{Configuring the clients} \label{\detokenize{admin/https:configuring-the-clients}} \sphinxAtStartPar To use an HTTPS proxy, a client host must trust the CA which issued that proxy’s SSL certificate. If that CA’s certificate is not in the system\sphinxhyphen{}wide default set of trusted certificates, configure the following relation in the client host’s {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} file in the appropriate {\hyperref[\detokenize{admin/conf_files/krb5_conf:realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} subsection: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{http\PYGZus{}anchors} \PYG{o}{=} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{/}\PYG{n}{cacert}\PYG{o}{.}\PYG{n}{pem} \end{sphinxVerbatim} \sphinxAtStartPar Adjust the pathname to match the path of the file which contains a copy of the CA’s certificate. The \sphinxtitleref{http\_anchors} option is documented more fully in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. \sphinxAtStartPar Configure the client to access the KDC and kpasswd service by specifying their locations in its {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} file in the form of HTTPS URLs for the proxy server: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdc} \PYG{o}{=} \PYG{n}{https}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{server}\PYG{o}{.}\PYG{n}{fqdn}\PYG{o}{/}\PYG{n}{KdcProxy} \PYG{n}{kpasswd\PYGZus{}server} \PYG{o}{=} \PYG{n}{https}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{server}\PYG{o}{.}\PYG{n}{fqdn}\PYG{o}{/}\PYG{n}{KdcProxy} \end{sphinxVerbatim} \sphinxAtStartPar If the proxy and client are properly configured, client commands such as \sphinxcode{\sphinxupquote{kinit}}, \sphinxcode{\sphinxupquote{kvno}}, and \sphinxcode{\sphinxupquote{kpasswd}} should all function normally. \sphinxstepscope \chapter{Authentication indicators} \label{\detokenize{admin/auth_indicator:authentication-indicators}}\label{\detokenize{admin/auth_indicator:auth-indicator}}\label{\detokenize{admin/auth_indicator::doc}} \sphinxAtStartPar As of release 1.14, the KDC can be configured to annotate tickets if the client authenticated using a stronger preauthentication mechanism such as {\hyperref[\detokenize{admin/pkinit:pkinit}]{\sphinxcrossref{\DUrole{std,std-ref}{PKINIT}}}} or {\hyperref[\detokenize{admin/otp:otp-preauth}]{\sphinxcrossref{\DUrole{std,std-ref}{OTP}}}}. These annotations are called “authentication indicators.†Service principals can be configured to require particular authentication indicators in order to authenticate to that service. An authentication indicator value can be any string chosen by the KDC administrator; there are no pre\sphinxhyphen{}set values. \sphinxAtStartPar To use authentication indicators with PKINIT or OTP, first configure the KDC to include an indicator when that preauthentication mechanism is used. For PKINIT, use the \sphinxstylestrong{pkinit\_indicator} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. For OTP, use the \sphinxstylestrong{indicator} variable in the token type definition, or specify the indicators in the \sphinxstylestrong{otp} user string as described in {\hyperref[\detokenize{admin/otp:otp-preauth}]{\sphinxcrossref{\DUrole{std,std-ref}{OTP Preauthentication}}}}. \sphinxAtStartPar To require an indicator to be present in order to authenticate to a service principal, set the \sphinxstylestrong{require\_auth} string attribute on the principal to the indicator value to be required. If you wish to allow one of several indicators to be accepted, you can specify multiple indicator values separated by spaces. \sphinxAtStartPar For example, a realm could be configured to set the authentication indicator value “strong†when PKINIT is used to authenticate, using a setting in the {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-realms}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}realms{]}}}}} subsection: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{pkinit\PYGZus{}indicator} \PYG{o}{=} \PYG{n}{strong} \end{sphinxVerbatim} \sphinxAtStartPar A service principal could be configured to require the “strong†authentication indicator value: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kadmin setstr host/high.value.server require\PYGZus{}auth strong Password for user/admin@KRBTEST.COM: \end{sphinxVerbatim} \sphinxAtStartPar A user who authenticates with PKINIT would be able to obtain a ticket for the service principal: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kinit \PYGZhy{}X X509\PYGZus{}user\PYGZus{}identity=FILE:/my/cert.pem,/my/key.pem user \PYGZdl{} kvno host/high.value.server host/high.value.server@KRBTEST.COM: kvno = 1 \end{sphinxVerbatim} \sphinxAtStartPar but a user who authenticates with a password would not: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kinit user Password for user@KRBTEST.COM: \PYGZdl{} kvno host/high.value.server kvno: KDC policy rejects request while getting credentials for host/high.value.server@KRBTEST.COM \end{sphinxVerbatim} \sphinxAtStartPar GSSAPI server applications can inspect authentication indicators through the \DUrole{xref,std,std-ref}{auth\sphinxhyphen{}indicators} name attribute. \sphinxstepscope \chapter{Administration programs} \label{\detokenize{admin/admin_commands/index:administration-programs}}\label{\detokenize{admin/admin_commands/index::doc}} \sphinxstepscope \section{kadmin} \label{\detokenize{admin/admin_commands/kadmin_local:kadmin}}\label{\detokenize{admin/admin_commands/kadmin_local:kadmin-1}}\label{\detokenize{admin/admin_commands/kadmin_local::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/kadmin_local:synopsis}}\phantomsection\label{\detokenize{admin/admin_commands/kadmin_local:kadmin-synopsis}} \sphinxAtStartPar \sphinxstylestrong{kadmin} {[}\sphinxstylestrong{\sphinxhyphen{}O}|\sphinxstylestrong{\sphinxhyphen{}N}{]} {[}\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}{]} {[}\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{principal}{]} {[}\sphinxstylestrong{\sphinxhyphen{}q} \sphinxstyleemphasis{query}{]} {[}{[}\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{cache\_name}{]}|{[}\sphinxstylestrong{\sphinxhyphen{}k} {[}\sphinxstylestrong{\sphinxhyphen{}t} \sphinxstyleemphasis{keytab}{]}{]}|\sphinxstylestrong{\sphinxhyphen{}n}{]} {[}\sphinxstylestrong{\sphinxhyphen{}w} \sphinxstyleemphasis{password}{]} {[}\sphinxstylestrong{\sphinxhyphen{}s} \sphinxstyleemphasis{admin\_server}{[}:\sphinxstyleemphasis{port}{]}{]} {[}command args…{]} \sphinxAtStartPar \sphinxstylestrong{kadmin.local} {[}\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}{]} {[}\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{principal}{]} {[}\sphinxstylestrong{\sphinxhyphen{}q} \sphinxstyleemphasis{query}{]} {[}\sphinxstylestrong{\sphinxhyphen{}d} \sphinxstyleemphasis{dbname}{]} {[}\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{enc}:\sphinxstyleemphasis{salt} …{]} {[}\sphinxstylestrong{\sphinxhyphen{}m}{]} {[}\sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_args}{]} {[}command args…{]} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/kadmin_local:description}} \sphinxAtStartPar kadmin and kadmin.local are command\sphinxhyphen{}line interfaces to the Kerberos V5 administration system. They provide nearly identical functionalities; the difference is that kadmin.local directly accesses the KDC database, while kadmin performs operations using {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}}. Except as explicitly noted otherwise, this man page will use “kadmin†to refer to both versions. kadmin provides for the maintenance of Kerberos principals, password policies, and service key tables (keytabs). \sphinxAtStartPar The remote kadmin client uses Kerberos to authenticate to kadmind using the service principal \sphinxcode{\sphinxupquote{kadmin/admin}} or \sphinxcode{\sphinxupquote{kadmin/ADMINHOST}} (where \sphinxstyleemphasis{ADMINHOST} is the fully\sphinxhyphen{}qualified hostname of the admin server). If the credentials cache contains a ticket for one of these principals, and the \sphinxstylestrong{\sphinxhyphen{}c} credentials\_cache option is specified, that ticket is used to authenticate to kadmind. Otherwise, the \sphinxstylestrong{\sphinxhyphen{}p} and \sphinxstylestrong{\sphinxhyphen{}k} options are used to specify the client Kerberos principal name used to authenticate. Once kadmin has determined the principal name, it requests a service ticket from the KDC, and uses that service ticket to authenticate to kadmind. \sphinxAtStartPar Since kadmin.local directly accesses the KDC database, it usually must be run directly on the primary KDC with sufficient permissions to read the KDC database. If the KDC database uses the LDAP database module, kadmin.local can be run on any host which can access the LDAP server. \subsection{OPTIONS} \label{\detokenize{admin/admin_commands/kadmin_local:options}}\phantomsection\label{\detokenize{admin/admin_commands/kadmin_local:kadmin-options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}} \sphinxAtStartPar Use \sphinxstyleemphasis{realm} as the default database realm. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{principal}} \sphinxAtStartPar Use \sphinxstyleemphasis{principal} to authenticate. Otherwise, kadmin will append \sphinxcode{\sphinxupquote{/admin}} to the primary principal name of the default ccache, the value of the \sphinxstylestrong{USER} environment variable, or the username as obtained with getpwuid, in order of preference. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k}} \sphinxAtStartPar Use a keytab to decrypt the KDC response instead of prompting for a password. In this case, the default principal will be \sphinxcode{\sphinxupquote{host/hostname}}. If there is no keytab specified with the \sphinxstylestrong{\sphinxhyphen{}t} option, then the default keytab will be used. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}t} \sphinxstyleemphasis{keytab}} \sphinxAtStartPar Use \sphinxstyleemphasis{keytab} to decrypt the KDC response. This can only be used with the \sphinxstylestrong{\sphinxhyphen{}k} option. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}n}} \sphinxAtStartPar Requests anonymous processing. Two types of anonymous principals are supported. For fully anonymous Kerberos, configure PKINIT on the KDC and configure \sphinxstylestrong{pkinit\_anchors} in the client’s {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. Then use the \sphinxstylestrong{\sphinxhyphen{}n} option with a principal of the form \sphinxcode{\sphinxupquote{@REALM}} (an empty principal name followed by the at\sphinxhyphen{}sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. A second form of anonymous tickets is supported; these realm\sphinxhyphen{}exposed tickets hide the identity of the client but not the client’s realm. For this mode, use \sphinxcode{\sphinxupquote{kinit \sphinxhyphen{}n}} with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}c} \sphinxstyleemphasis{credentials\_cache}} \sphinxAtStartPar Use \sphinxstyleemphasis{credentials\_cache} as the credentials cache. The cache should contain a service ticket for the \sphinxcode{\sphinxupquote{kadmin/admin}} or \sphinxcode{\sphinxupquote{kadmin/ADMINHOST}} (where \sphinxstyleemphasis{ADMINHOST} is the fully\sphinxhyphen{}qualified hostname of the admin server) service; it can be acquired with the \DUrole{xref,std,std-ref}{kinit(1)} program. If this option is not specified, kadmin requests a new service ticket from the KDC, and stores it in its own temporary ccache. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}w} \sphinxstyleemphasis{password}} \sphinxAtStartPar Use \sphinxstyleemphasis{password} instead of prompting for one. Use this option with care, as it may expose the password to other users on the system via the process list. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}q} \sphinxstyleemphasis{query}} \sphinxAtStartPar Perform the specified query and then exit. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}d} \sphinxstyleemphasis{dbname}} \sphinxAtStartPar Specifies the name of the KDC database. This option does not apply to the LDAP database module. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}s} \sphinxstyleemphasis{admin\_server}{[}:\sphinxstyleemphasis{port}{]}} \sphinxAtStartPar Specifies the admin server which kadmin should contact. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}m}} \sphinxAtStartPar If using kadmin.local, prompt for the database master password instead of reading it from a stash file. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}e} “\sphinxstyleemphasis{enc}:\sphinxstyleemphasis{salt} …â€} \sphinxAtStartPar Sets the keysalt list to be used for any new keys created. See {\hyperref[\detokenize{admin/conf_files/kdc_conf:keysalt-lists}]{\sphinxcrossref{\DUrole{std,std-ref}{Keysalt lists}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} for a list of possible values. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}O}} \sphinxAtStartPar Force use of old AUTH\_GSSAPI authentication flavor. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}N}} \sphinxAtStartPar Prevent fallback to AUTH\_GSSAPI authentication flavor. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_args}} \sphinxAtStartPar Specifies the database specific arguments. See the next section for supported options. \end{description} \sphinxAtStartPar Starting with release 1.14, if any command\sphinxhyphen{}line arguments remain after the options, they will be treated as a single query to be executed. This mode of operation is intended for scripts and behaves differently from the interactive mode in several respects: \begin{itemize} \item {} \sphinxAtStartPar Query arguments are split by the shell, not by kadmin. \item {} \sphinxAtStartPar Informational and warning messages are suppressed. Error messages and query output (e.g. for \sphinxstylestrong{get\_principal}) will still be displayed. \item {} \sphinxAtStartPar Confirmation prompts are disabled (as if \sphinxstylestrong{\sphinxhyphen{}force} was given). Password prompts will still be issued as required. \item {} \sphinxAtStartPar The exit status will be non\sphinxhyphen{}zero if the query fails. \end{itemize} \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}q} option does not carry these behavior differences; the query will be processed as if it was entered interactively. The \sphinxstylestrong{\sphinxhyphen{}q} option cannot be used in combination with a query in the remaining arguments. \subsection{DATABASE OPTIONS} \label{\detokenize{admin/admin_commands/kadmin_local:database-options}}\label{\detokenize{admin/admin_commands/kadmin_local:dboptions}} \sphinxAtStartPar Database options can be used to override database\sphinxhyphen{}specific defaults. Supported options for the DB2 module are: \begin{quote} \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x dbname=}*filename*} \sphinxAtStartPar Specifies the base filename of the DB2 database. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x lockiter}} \sphinxAtStartPar Make iteration operations hold the lock for the duration of the entire operation, rather than temporarily releasing the lock while handling each principal. This is the default behavior, but this option exists to allow command line override of a {[}dbmodules{]} setting. First introduced in release 1.13. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x unlockiter}} \sphinxAtStartPar Make iteration operations unlock the database for each principal, instead of holding the lock for the duration of the entire operation. First introduced in release 1.13. \end{description} \end{quote} \sphinxAtStartPar Supported options for the LDAP module are: \begin{quote} \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x host=}\sphinxstyleemphasis{ldapuri}} \sphinxAtStartPar Specifies the LDAP server to connect to by a LDAP URI. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x binddn=}\sphinxstyleemphasis{bind\_dn}} \sphinxAtStartPar Specifies the DN used to bind to the LDAP server. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x bindpwd=}\sphinxstyleemphasis{password}} \sphinxAtStartPar Specifies the password or SASL secret used to bind to the LDAP server. Using this option may expose the password to other users on the system via the process list; to avoid this, instead stash the password using the \sphinxstylestrong{stashsrvpw} command of {\hyperref[\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_ldap\_util}}}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x sasl\_mech=}\sphinxstyleemphasis{mechanism}} \sphinxAtStartPar Specifies the SASL mechanism used to bind to the LDAP server. The bind DN is ignored if a SASL mechanism is used. New in release 1.13. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x sasl\_authcid=}\sphinxstyleemphasis{name}} \sphinxAtStartPar Specifies the authentication name used when binding to the LDAP server with a SASL mechanism, if the mechanism requires one. New in release 1.13. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x sasl\_authzid=}\sphinxstyleemphasis{name}} \sphinxAtStartPar Specifies the authorization name used when binding to the LDAP server with a SASL mechanism. New in release 1.13. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x sasl\_realm=}\sphinxstyleemphasis{realm}} \sphinxAtStartPar Specifies the realm used when binding to the LDAP server with a SASL mechanism, if the mechanism uses one. New in release 1.13. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x debug=}\sphinxstyleemphasis{level}} \sphinxAtStartPar sets the OpenLDAP client library debug level. \sphinxstyleemphasis{level} is an integer to be interpreted by the library. Debugging messages are printed to standard error. New in release 1.12. \end{description} \end{quote} \subsection{COMMANDS} \label{\detokenize{admin/admin_commands/kadmin_local:commands}} \sphinxAtStartPar When using the remote client, available commands may be restricted according to the privileges specified in the {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}} file on the admin server. \subsubsection{add\_principal} \label{\detokenize{admin/admin_commands/kadmin_local:add-principal}}\label{\detokenize{admin/admin_commands/kadmin_local:id1}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{add\_principal} {[}\sphinxstyleemphasis{options}{]} \sphinxstyleemphasis{newprinc} \end{quote} \sphinxAtStartPar Creates the principal \sphinxstyleemphasis{newprinc}, prompting twice for a password. If no password policy is specified with the \sphinxstylestrong{\sphinxhyphen{}policy} option, and the policy named \sphinxcode{\sphinxupquote{default}} is assigned to the principal if it exists. However, creating a policy named \sphinxcode{\sphinxupquote{default}} will not automatically assign this policy to previously existing principals. This policy assignment can be suppressed with the \sphinxstylestrong{\sphinxhyphen{}clearpolicy} option. \sphinxAtStartPar This command requires the \sphinxstylestrong{add} privilege. \sphinxAtStartPar Aliases: \sphinxstylestrong{addprinc}, \sphinxstylestrong{ank} \sphinxAtStartPar Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}expire} \sphinxstyleemphasis{expdate}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{getdate} string) The expiration date of the principal. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}pwexpire} \sphinxstyleemphasis{pwexpdate}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{getdate} string) The password expiration date. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxlife} \sphinxstyleemphasis{maxlife}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} or \DUrole{xref,std,std-ref}{getdate} string) The maximum ticket life for the principal. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxrenewlife} \sphinxstyleemphasis{maxrenewlife}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} or \DUrole{xref,std,std-ref}{getdate} string) The maximum renewable life of tickets for the principal. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}kvno} \sphinxstyleemphasis{kvno}} \sphinxAtStartPar The initial key version number. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}policy} \sphinxstyleemphasis{policy}} \sphinxAtStartPar The password policy used by this principal. If not specified, the policy \sphinxcode{\sphinxupquote{default}} is used if it exists (unless \sphinxstylestrong{\sphinxhyphen{}clearpolicy} is specified). \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}clearpolicy}} \sphinxAtStartPar Prevents any policy from being assigned when \sphinxstylestrong{\sphinxhyphen{}policy} is not specified. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{allow\_postdated}} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}allow\_postdated} prohibits this principal from obtaining postdated tickets. \sphinxstylestrong{+allow\_postdated} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{allow\_forwardable}} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}allow\_forwardable} prohibits this principal from obtaining forwardable tickets. \sphinxstylestrong{+allow\_forwardable} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{allow\_renewable}} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}allow\_renewable} prohibits this principal from obtaining renewable tickets. \sphinxstylestrong{+allow\_renewable} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{allow\_proxiable}} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}allow\_proxiable} prohibits this principal from obtaining proxiable tickets. \sphinxstylestrong{+allow\_proxiable} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{allow\_dup\_skey}} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}allow\_dup\_skey} disables user\sphinxhyphen{}to\sphinxhyphen{}user authentication for this principal by prohibiting others from obtaining a service ticket encrypted in this principal’s TGT session key. \sphinxstylestrong{+allow\_dup\_skey} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{requires\_preauth}} \sphinxAtStartPar \sphinxstylestrong{+requires\_preauth} requires this principal to preauthenticate before being allowed to kinit. \sphinxstylestrong{\sphinxhyphen{}requires\_preauth} clears this flag. When \sphinxstylestrong{+requires\_preauth} is set on a service principal, the KDC will only issue service tickets for that service principal if the client’s initial authentication was performed using preauthentication. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{requires\_hwauth}} \sphinxAtStartPar \sphinxstylestrong{+requires\_hwauth} requires this principal to preauthenticate using a hardware device before being allowed to kinit. \sphinxstylestrong{\sphinxhyphen{}requires\_hwauth} clears this flag. When \sphinxstylestrong{+requires\_hwauth} is set on a service principal, the KDC will only issue service tickets for that service principal if the client’s initial authentication was performed using a hardware device to preauthenticate. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{ok\_as\_delegate}} \sphinxAtStartPar \sphinxstylestrong{+ok\_as\_delegate} sets the \sphinxstylestrong{okay as delegate} flag on tickets issued with this principal as the service. Clients may use this flag as a hint that credentials should be delegated when authenticating to the service. \sphinxstylestrong{\sphinxhyphen{}ok\_as\_delegate} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{allow\_svr}} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}allow\_svr} prohibits the issuance of service tickets for this principal. In release 1.17 and later, user\sphinxhyphen{}to\sphinxhyphen{}user service tickets are still allowed unless the \sphinxstylestrong{\sphinxhyphen{}allow\_dup\_skey} flag is also set. \sphinxstylestrong{+allow\_svr} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{allow\_tgs\_req}} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}allow\_tgs\_req} specifies that a Ticket\sphinxhyphen{}Granting Service (TGS) request for a service ticket for this principal is not permitted. \sphinxstylestrong{+allow\_tgs\_req} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{allow\_tix}} \sphinxAtStartPar \sphinxstylestrong{\sphinxhyphen{}allow\_tix} forbids the issuance of any tickets for this principal. \sphinxstylestrong{+allow\_tix} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{needchange}} \sphinxAtStartPar \sphinxstylestrong{+needchange} forces a password change on the next initial authentication to this principal. \sphinxstylestrong{\sphinxhyphen{}needchange} clears this flag. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{password\_changing\_service}} \sphinxAtStartPar \sphinxstylestrong{+password\_changing\_service} marks this principal as a password change service principal. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{ok\_to\_auth\_as\_delegate}} \sphinxAtStartPar \sphinxstylestrong{+ok\_to\_auth\_as\_delegate} allows this principal to acquire forwardable tickets to itself from arbitrary users, for use with constrained delegation. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{no\_auth\_data\_required}} \sphinxAtStartPar \sphinxstylestrong{+no\_auth\_data\_required} prevents PAC or AD\sphinxhyphen{}SIGNEDPATH data from being added to service tickets for the principal. \sphinxlineitem{\{\sphinxhyphen{}|+\}\sphinxstylestrong{lockdown\_keys}} \sphinxAtStartPar \sphinxstylestrong{+lockdown\_keys} prevents keys for this principal from leaving the KDC via kadmind. The chpass and extract operations are denied for a principal with this attribute. The chrand operation is allowed, but will not return the new keys. The delete and rename operations are also denied if this attribute is set, in order to prevent a malicious administrator from replacing principals like krbtgt/* or kadmin/* with new principals without the attribute. This attribute can be set via the network protocol, but can only be removed using kadmin.local. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}randkey}} \sphinxAtStartPar Sets the key of the principal to a random value. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}nokey}} \sphinxAtStartPar Causes the principal to be created with no key. New in release 1.12. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}pw} \sphinxstyleemphasis{password}} \sphinxAtStartPar Sets the password of the principal to the specified string and does not prompt for a password. Note: using this option in a shell script may expose the password to other users on the system via the process list. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{enc}:\sphinxstyleemphasis{salt},…} \sphinxAtStartPar Uses the specified keysalt list for setting the keys of the principal. See {\hyperref[\detokenize{admin/conf_files/kdc_conf:keysalt-lists}]{\sphinxcrossref{\DUrole{std,std-ref}{Keysalt lists}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} for a list of possible values. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_princ\_args}} \sphinxAtStartPar Indicates database\sphinxhyphen{}specific options. The options for the LDAP database module are: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x dn=}\sphinxstyleemphasis{dn}} \sphinxAtStartPar Specifies the LDAP object that will contain the Kerberos principal being created. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x linkdn=}\sphinxstyleemphasis{dn}} \sphinxAtStartPar Specifies the LDAP object to which the newly created Kerberos principal object will point. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x containerdn=}\sphinxstyleemphasis{container\_dn}} \sphinxAtStartPar Specifies the container object under which the Kerberos principal is to be created. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x tktpolicy=}\sphinxstyleemphasis{policy}} \sphinxAtStartPar Associates a ticket policy to the Kerberos principal. \end{description} \begin{sphinxadmonition}{note}{Note:}\begin{itemize} \item {} \sphinxAtStartPar The \sphinxstylestrong{containerdn} and \sphinxstylestrong{linkdn} options cannot be specified with the \sphinxstylestrong{dn} option. \item {} \sphinxAtStartPar If the \sphinxstyleemphasis{dn} or \sphinxstyleemphasis{containerdn} options are not specified while adding the principal, the principals are created under the principal container configured in the realm or the realm container. \item {} \sphinxAtStartPar \sphinxstyleemphasis{dn} and \sphinxstyleemphasis{containerdn} should be within the subtrees or principal container configured in the realm. \end{itemize} \end{sphinxadmonition} \end{description} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{addprinc} \PYG{n}{jennifer} \PYG{n}{No} \PYG{n}{policy} \PYG{n}{specified} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{jennifer@ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{;} \PYG{n}{defaulting} \PYG{n}{to} \PYG{n}{no} \PYG{n}{policy}\PYG{o}{.} \PYG{n}{Enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{n}{Re}\PYG{o}{\PYGZhy{}}\PYG{n}{enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{jennifer}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{p}{:} \PYG{n}{Principal} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{jennifer@ATHENA.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{created}\PYG{o}{.} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{modify\_principal} \label{\detokenize{admin/admin_commands/kadmin_local:modify-principal}}\label{\detokenize{admin/admin_commands/kadmin_local:id2}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{modify\_principal} {[}\sphinxstyleemphasis{options}{]} \sphinxstyleemphasis{principal} \end{quote} \sphinxAtStartPar Modifies the specified principal, changing the fields as specified. The options to \sphinxstylestrong{add\_principal} also apply to this command, except for the \sphinxstylestrong{\sphinxhyphen{}randkey}, \sphinxstylestrong{\sphinxhyphen{}pw}, and \sphinxstylestrong{\sphinxhyphen{}e} options. In addition, the option \sphinxstylestrong{\sphinxhyphen{}clearpolicy} will clear the current policy of a principal. \sphinxAtStartPar This command requires the \sphinxstyleemphasis{modify} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{modprinc} \sphinxAtStartPar Options (in addition to the \sphinxstylestrong{addprinc} options): \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}unlock}} \sphinxAtStartPar Unlocks a locked principal (one which has received too many failed authentication attempts without enough time between them according to its password policy) so that it can successfully authenticate. \end{description} \subsubsection{rename\_principal} \label{\detokenize{admin/admin_commands/kadmin_local:rename-principal}}\label{\detokenize{admin/admin_commands/kadmin_local:id3}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{rename\_principal} {[}\sphinxstylestrong{\sphinxhyphen{}force}{]} \sphinxstyleemphasis{old\_principal} \sphinxstyleemphasis{new\_principal} \end{quote} \sphinxAtStartPar Renames the specified \sphinxstyleemphasis{old\_principal} to \sphinxstyleemphasis{new\_principal}. This command prompts for confirmation, unless the \sphinxstylestrong{\sphinxhyphen{}force} option is given. \sphinxAtStartPar This command requires the \sphinxstylestrong{add} and \sphinxstylestrong{delete} privileges. \sphinxAtStartPar Alias: \sphinxstylestrong{renprinc} \subsubsection{add\_alias} \label{\detokenize{admin/admin_commands/kadmin_local:add-alias}}\label{\detokenize{admin/admin_commands/kadmin_local:id4}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{add\_alias} \sphinxstyleemphasis{alias\_princ} \sphinxstyleemphasis{target\_princ} \end{quote} \sphinxAtStartPar Create an alias \sphinxstyleemphasis{alias\_princ} pointing to \sphinxstyleemphasis{target\_princ}. Aliases may be chained (that is, \sphinxstyleemphasis{target\_princ} may itself be an alias) up to a depth of 10. \sphinxAtStartPar This command requires the \sphinxstylestrong{add} privilege for \sphinxstyleemphasis{alias\_princ} and the \sphinxstylestrong{modify} privilege for \sphinxstyleemphasis{target\_princ}. \sphinxAtStartPar (New in release 1.22.) \sphinxAtStartPar Aliases: \sphinxstylestrong{alias} \subsubsection{delete\_principal} \label{\detokenize{admin/admin_commands/kadmin_local:delete-principal}}\label{\detokenize{admin/admin_commands/kadmin_local:id5}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{delete\_principal} {[}\sphinxstylestrong{\sphinxhyphen{}force}{]} \sphinxstyleemphasis{principal} \end{quote} \sphinxAtStartPar Deletes the specified \sphinxstyleemphasis{principal} or alias from the database. This command prompts for deletion, unless the \sphinxstylestrong{\sphinxhyphen{}force} option is given. \sphinxAtStartPar This command requires the \sphinxstylestrong{delete} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{delprinc} \subsubsection{change\_password} \label{\detokenize{admin/admin_commands/kadmin_local:change-password}}\label{\detokenize{admin/admin_commands/kadmin_local:id6}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{change\_password} {[}\sphinxstyleemphasis{options}{]} \sphinxstyleemphasis{principal} \end{quote} \sphinxAtStartPar Changes the password of \sphinxstyleemphasis{principal}. Prompts for a new password if neither \sphinxstylestrong{\sphinxhyphen{}randkey} or \sphinxstylestrong{\sphinxhyphen{}pw} is specified. \sphinxAtStartPar This command requires the \sphinxstylestrong{changepw} privilege, or that the principal running the program is the same as the principal being changed. \sphinxAtStartPar Alias: \sphinxstylestrong{cpw} \sphinxAtStartPar The following options are available: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}randkey}} \sphinxAtStartPar Sets the key of the principal to a random value. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}pw} \sphinxstyleemphasis{password}} \sphinxAtStartPar Set the password to the specified string. Using this option in a script may expose the password to other users on the system via the process list. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{enc}:\sphinxstyleemphasis{salt},…} \sphinxAtStartPar Uses the specified keysalt list for setting the keys of the principal. See {\hyperref[\detokenize{admin/conf_files/kdc_conf:keysalt-lists}]{\sphinxcrossref{\DUrole{std,std-ref}{Keysalt lists}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} for a list of possible values. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}keepold}} \sphinxAtStartPar Keeps the existing keys in the database. This flag is usually not necessary except perhaps for \sphinxcode{\sphinxupquote{krbtgt}} principals. \end{description} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{cpw} \PYG{n}{systest} \PYG{n}{Enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{systest}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{:} \PYG{n}{Re}\PYG{o}{\PYGZhy{}}\PYG{n}{enter} \PYG{n}{password} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{systest}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{:} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{systest}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{changed}\PYG{o}{.} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{purgekeys} \label{\detokenize{admin/admin_commands/kadmin_local:purgekeys}}\label{\detokenize{admin/admin_commands/kadmin_local:id7}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{purgekeys} {[}\sphinxstylestrong{\sphinxhyphen{}all}|\sphinxstylestrong{\sphinxhyphen{}keepkvno} \sphinxstyleemphasis{oldest\_kvno\_to\_keep}{]} \sphinxstyleemphasis{principal} \end{quote} \sphinxAtStartPar Purges previously retained old keys (e.g., from \sphinxstylestrong{change\_password \sphinxhyphen{}keepold}) from \sphinxstyleemphasis{principal}. If \sphinxstylestrong{\sphinxhyphen{}keepkvno} is specified, then only purges keys with kvnos lower than \sphinxstyleemphasis{oldest\_kvno\_to\_keep}. If \sphinxstylestrong{\sphinxhyphen{}all} is specified, then all keys are purged. The \sphinxstylestrong{\sphinxhyphen{}all} option is new in release 1.12. \sphinxAtStartPar This command requires the \sphinxstylestrong{modify} privilege. \subsubsection{get\_principal} \label{\detokenize{admin/admin_commands/kadmin_local:get-principal}}\label{\detokenize{admin/admin_commands/kadmin_local:id8}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{get\_principal} {[}\sphinxstylestrong{\sphinxhyphen{}terse}{]} \sphinxstyleemphasis{principal} \end{quote} \sphinxAtStartPar Gets the attributes of principal. With the \sphinxstylestrong{\sphinxhyphen{}terse} option, outputs fields as quoted tab\sphinxhyphen{}separated strings. \sphinxAtStartPar This command requires the \sphinxstylestrong{inquire} privilege, or that the principal running the the program to be the same as the one being listed. \sphinxAtStartPar Alias: \sphinxstylestrong{getprinc} \sphinxAtStartPar Examples: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{getprinc} \PYG{n}{tlyu}\PYG{o}{/}\PYG{n}{admin} \PYG{n}{Principal}\PYG{p}{:} \PYG{n}{tlyu}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{Expiration} \PYG{n}{date}\PYG{p}{:} \PYG{p}{[}\PYG{n}{never}\PYG{p}{]} \PYG{n}{Last} \PYG{n}{password} \PYG{n}{change}\PYG{p}{:} \PYG{n}{Mon} \PYG{n}{Aug} \PYG{l+m+mi}{12} \PYG{l+m+mi}{14}\PYG{p}{:}\PYG{l+m+mi}{16}\PYG{p}{:}\PYG{l+m+mi}{47} \PYG{n}{EDT} \PYG{l+m+mi}{1996} \PYG{n}{Password} \PYG{n}{expiration} \PYG{n}{date}\PYG{p}{:} \PYG{p}{[}\PYG{n}{never}\PYG{p}{]} \PYG{n}{Maximum} \PYG{n}{ticket} \PYG{n}{life}\PYG{p}{:} \PYG{l+m+mi}{0} \PYG{n}{days} \PYG{l+m+mi}{10}\PYG{p}{:}\PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00} \PYG{n}{Maximum} \PYG{n}{renewable} \PYG{n}{life}\PYG{p}{:} \PYG{l+m+mi}{7} \PYG{n}{days} \PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00} \PYG{n}{Last} \PYG{n}{modified}\PYG{p}{:} \PYG{n}{Mon} \PYG{n}{Aug} \PYG{l+m+mi}{12} \PYG{l+m+mi}{14}\PYG{p}{:}\PYG{l+m+mi}{16}\PYG{p}{:}\PYG{l+m+mi}{47} \PYG{n}{EDT} \PYG{l+m+mi}{1996} \PYG{p}{(}\PYG{n}{bjaspan}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{)} \PYG{n}{Last} \PYG{n}{successful} \PYG{n}{authentication}\PYG{p}{:} \PYG{p}{[}\PYG{n}{never}\PYG{p}{]} \PYG{n}{Last} \PYG{n}{failed} \PYG{n}{authentication}\PYG{p}{:} \PYG{p}{[}\PYG{n}{never}\PYG{p}{]} \PYG{n}{Failed} \PYG{n}{password} \PYG{n}{attempts}\PYG{p}{:} \PYG{l+m+mi}{0} \PYG{n}{Number} \PYG{n}{of} \PYG{n}{keys}\PYG{p}{:} \PYG{l+m+mi}{1} \PYG{n}{Key}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha384}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{192} \PYG{n}{MKey}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{1} \PYG{n}{Attributes}\PYG{p}{:} \PYG{n}{Policy}\PYG{p}{:} \PYG{p}{[}\PYG{n}{none}\PYG{p}{]} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{getprinc} \PYG{o}{\PYGZhy{}}\PYG{n}{terse} \PYG{n}{systest} \PYG{n}{systest}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM} \PYG{l+m+mi}{3} \PYG{l+m+mi}{86400} \PYG{l+m+mi}{604800} \PYG{l+m+mi}{1} \PYG{l+m+mi}{785926535} \PYG{l+m+mi}{753241234} \PYG{l+m+mi}{785900000} \PYG{n}{tlyu}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM} \PYG{l+m+mi}{786100034} \PYG{l+m+mi}{0} \PYG{l+m+mi}{0} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{list\_principals} \label{\detokenize{admin/admin_commands/kadmin_local:list-principals}}\label{\detokenize{admin/admin_commands/kadmin_local:id9}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{list\_principals} {[}\sphinxstyleemphasis{expression}{]} \end{quote} \sphinxAtStartPar Retrieves all or some principal names. \sphinxstyleemphasis{expression} is a shell\sphinxhyphen{}style glob expression that can contain the wild\sphinxhyphen{}card characters \sphinxcode{\sphinxupquote{?}}, \sphinxcode{\sphinxupquote{*}}, and \sphinxcode{\sphinxupquote{{[}{]}}}. All principal names matching the expression are printed. If no expression is provided, all principal names are printed. If the expression does not contain an \sphinxcode{\sphinxupquote{@}} character, an \sphinxcode{\sphinxupquote{@}} character followed by the local realm is appended to the expression. \sphinxAtStartPar This command requires the \sphinxstylestrong{list} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{listprincs}, \sphinxstylestrong{get\_principals}, \sphinxstylestrong{getprincs} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{listprincs} \PYG{n}{test}\PYG{o}{*} \PYG{n}{test3}\PYG{n+nd}{@SECURE}\PYG{o}{\PYGZhy{}}\PYG{n}{TEST}\PYG{o}{.}\PYG{n}{OV}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{test2}\PYG{n+nd}{@SECURE}\PYG{o}{\PYGZhy{}}\PYG{n}{TEST}\PYG{o}{.}\PYG{n}{OV}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{test1}\PYG{n+nd}{@SECURE}\PYG{o}{\PYGZhy{}}\PYG{n}{TEST}\PYG{o}{.}\PYG{n}{OV}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{testuser}\PYG{n+nd}{@SECURE}\PYG{o}{\PYGZhy{}}\PYG{n}{TEST}\PYG{o}{.}\PYG{n}{OV}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{get\_strings} \label{\detokenize{admin/admin_commands/kadmin_local:get-strings}}\label{\detokenize{admin/admin_commands/kadmin_local:id10}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{get\_strings} \sphinxstyleemphasis{principal} \end{quote} \sphinxAtStartPar Displays string attributes on \sphinxstyleemphasis{principal}. \sphinxAtStartPar This command requires the \sphinxstylestrong{inquire} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{getstrs} \subsubsection{set\_string} \label{\detokenize{admin/admin_commands/kadmin_local:set-string}}\label{\detokenize{admin/admin_commands/kadmin_local:id11}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{set\_string} \sphinxstyleemphasis{principal} \sphinxstyleemphasis{name} \sphinxstyleemphasis{value} \end{quote} \sphinxAtStartPar Sets a string attribute on \sphinxstyleemphasis{principal}. String attributes are used to supply per\sphinxhyphen{}principal configuration to the KDC and some KDC plugin modules. The following string attribute names are recognized by the KDC: \begin{description} \sphinxlineitem{\sphinxstylestrong{require\_auth}} \sphinxAtStartPar Specifies an authentication indicator which is required to authenticate to the principal as a service. Multiple indicators can be specified, separated by spaces; in this case any of the specified indicators will be accepted. (New in release 1.14.) \sphinxlineitem{\sphinxstylestrong{session\_enctypes}} \sphinxAtStartPar Specifies the encryption types supported for session keys when the principal is authenticated to as a server. See {\hyperref[\detokenize{admin/conf_files/kdc_conf:encryption-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Encryption types}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} for a list of the accepted values. \sphinxlineitem{\sphinxstylestrong{otp}} \sphinxAtStartPar Enables One Time Passwords (OTP) preauthentication for a client \sphinxstyleemphasis{principal}. The \sphinxstyleemphasis{value} is a JSON string representing an array of objects, each having optional \sphinxcode{\sphinxupquote{type}} and \sphinxcode{\sphinxupquote{username}} fields. \sphinxlineitem{\sphinxstylestrong{pkinit\_cert\_match}} \sphinxAtStartPar Specifies a matching expression that defines the certificate attributes required for the client certificate used by the principal during PKINIT authentication. The matching expression is in the same format as those used by the \sphinxstylestrong{pkinit\_cert\_match} option in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. (New in release 1.16.) \sphinxlineitem{\sphinxstylestrong{pac\_privsvr\_enctype}} \sphinxAtStartPar Forces the encryption type of the PAC KDC checksum buffers to the specified encryption type for tickets issued to this server, by deriving a key from the local krbtgt key if it is of a different encryption type. It may be necessary to set this value to “aes256\sphinxhyphen{}sha1†on the cross\sphinxhyphen{}realm krbtgt entry for an Active Directory realm when using aes\sphinxhyphen{}sha2 keys on the local krbtgt entry. \end{description} \sphinxAtStartPar This command requires the \sphinxstylestrong{modify} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{setstr} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{set\PYGZus{}string} \PYG{n}{host}\PYG{o}{/}\PYG{n}{foo}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{session\PYGZus{}enctypes} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts} \PYG{n}{set\PYGZus{}string} \PYG{n}{user}\PYG{n+nd}{@FOO}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{otp} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[}\PYG{l+s+s2}{\PYGZob{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{type}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{:}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{hotp}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{,}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{username}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{:}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{al}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZcb{}]}\PYG{l+s+s2}{\PYGZdq{}} \end{sphinxVerbatim} \subsubsection{del\_string} \label{\detokenize{admin/admin_commands/kadmin_local:del-string}}\label{\detokenize{admin/admin_commands/kadmin_local:id12}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{del\_string} \sphinxstyleemphasis{principal} \sphinxstyleemphasis{key} \end{quote} \sphinxAtStartPar Deletes a string attribute from \sphinxstyleemphasis{principal}. \sphinxAtStartPar This command requires the \sphinxstylestrong{delete} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{delstr} \subsubsection{add\_policy} \label{\detokenize{admin/admin_commands/kadmin_local:add-policy}}\label{\detokenize{admin/admin_commands/kadmin_local:id13}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{add\_policy} {[}\sphinxstyleemphasis{options}{]} \sphinxstyleemphasis{policy} \end{quote} \sphinxAtStartPar Adds a password policy named \sphinxstyleemphasis{policy} to the database. \sphinxAtStartPar This command requires the \sphinxstylestrong{add} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{addpol} \sphinxAtStartPar The following options are available: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxlife} \sphinxstyleemphasis{time}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} or \DUrole{xref,std,std-ref}{getdate} string) Sets the maximum lifetime of a password. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}minlife} \sphinxstyleemphasis{time}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} or \DUrole{xref,std,std-ref}{getdate} string) Sets the minimum lifetime of a password. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}minlength} \sphinxstyleemphasis{length}} \sphinxAtStartPar Sets the minimum length of a password. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}minclasses} \sphinxstyleemphasis{number}} \sphinxAtStartPar Sets the minimum number of character classes required in a password. The five character classes are lower case, upper case, numbers, punctuation, and whitespace/unprintable characters. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}history} \sphinxstyleemphasis{number}} \sphinxAtStartPar Sets the number of past keys kept for a principal. This option is not supported with the LDAP KDC database module. \end{description} \phantomsection\label{\detokenize{admin/admin_commands/kadmin_local:policy-maxfailure}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxfailure} \sphinxstyleemphasis{maxnumber}} \sphinxAtStartPar Sets the number of authentication failures before the principal is locked. Authentication failures are only tracked for principals which require preauthentication. The counter of failed attempts resets to 0 after a successful attempt to authenticate. A \sphinxstyleemphasis{maxnumber} value of 0 (the default) disables lockout. \end{description} \phantomsection\label{\detokenize{admin/admin_commands/kadmin_local:policy-failurecountinterval}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}failurecountinterval} \sphinxstyleemphasis{failuretime}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} or \DUrole{xref,std,std-ref}{getdate} string) Sets the allowable time between authentication failures. If an authentication failure happens after \sphinxstyleemphasis{failuretime} has elapsed since the previous failure, the number of authentication failures is reset to 1. A \sphinxstyleemphasis{failuretime} value of 0 (the default) means forever. \end{description} \phantomsection\label{\detokenize{admin/admin_commands/kadmin_local:policy-lockoutduration}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}lockoutduration} \sphinxstyleemphasis{lockouttime}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{duration} or \DUrole{xref,std,std-ref}{getdate} string) Sets the duration for which the principal is locked from authenticating if too many authentication failures occur without the specified failure count interval elapsing. A duration of 0 (the default) means the principal remains locked out until it is administratively unlocked with \sphinxcode{\sphinxupquote{modprinc \sphinxhyphen{}unlock}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}allowedkeysalts}} \sphinxAtStartPar Specifies the key/salt tuples supported for long\sphinxhyphen{}term keys when setting or changing a principal’s password/keys. See {\hyperref[\detokenize{admin/conf_files/kdc_conf:keysalt-lists}]{\sphinxcrossref{\DUrole{std,std-ref}{Keysalt lists}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} for a list of the accepted values, but note that key/salt tuples must be separated with commas (‘,’) only. To clear the allowed key/salt policy use a value of ‘\sphinxhyphen{}‘. \end{description} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{add\PYGZus{}policy} \PYG{o}{\PYGZhy{}}\PYG{n}{maxlife} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{2 days}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{\PYGZhy{}}\PYG{n}{minlength} \PYG{l+m+mi}{5} \PYG{n}{guests} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{modify\_policy} \label{\detokenize{admin/admin_commands/kadmin_local:modify-policy}}\label{\detokenize{admin/admin_commands/kadmin_local:id14}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{modify\_policy} {[}\sphinxstyleemphasis{options}{]} \sphinxstyleemphasis{policy} \end{quote} \sphinxAtStartPar Modifies the password policy named \sphinxstyleemphasis{policy}. Options are as described for \sphinxstylestrong{add\_policy}. \sphinxAtStartPar This command requires the \sphinxstylestrong{modify} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{modpol} \subsubsection{delete\_policy} \label{\detokenize{admin/admin_commands/kadmin_local:delete-policy}}\label{\detokenize{admin/admin_commands/kadmin_local:id15}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{delete\_policy} {[}\sphinxstylestrong{\sphinxhyphen{}force}{]} \sphinxstyleemphasis{policy} \end{quote} \sphinxAtStartPar Deletes the password policy named \sphinxstyleemphasis{policy}. Prompts for confirmation before deletion. The command will fail if the policy is in use by any principals. \sphinxAtStartPar This command requires the \sphinxstylestrong{delete} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{delpol} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] kadmin: del\PYGZus{}policy guests Are you sure you want to delete the policy \PYGZdq{}guests\PYGZdq{}? (yes/no): yes kadmin: \end{sphinxVerbatim} \subsubsection{get\_policy} \label{\detokenize{admin/admin_commands/kadmin_local:get-policy}}\label{\detokenize{admin/admin_commands/kadmin_local:id16}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{get\_policy} {[} \sphinxstylestrong{\sphinxhyphen{}terse} {]} \sphinxstyleemphasis{policy} \end{quote} \sphinxAtStartPar Displays the values of the password policy named \sphinxstyleemphasis{policy}. With the \sphinxstylestrong{\sphinxhyphen{}terse} flag, outputs the fields as quoted strings separated by tabs. \sphinxAtStartPar This command requires the \sphinxstylestrong{inquire} privilege. \sphinxAtStartPar Alias: \sphinxstylestrong{getpol} \sphinxAtStartPar Examples: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{get\PYGZus{}policy} \PYG{n}{admin} \PYG{n}{Policy}\PYG{p}{:} \PYG{n}{admin} \PYG{n}{Maximum} \PYG{n}{password} \PYG{n}{life}\PYG{p}{:} \PYG{l+m+mi}{180} \PYG{n}{days} \PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00} \PYG{n}{Minimum} \PYG{n}{password} \PYG{n}{life}\PYG{p}{:} \PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00} \PYG{n}{Minimum} \PYG{n}{password} \PYG{n}{length}\PYG{p}{:} \PYG{l+m+mi}{6} \PYG{n}{Minimum} \PYG{n}{number} \PYG{n}{of} \PYG{n}{password} \PYG{n}{character} \PYG{n}{classes}\PYG{p}{:} \PYG{l+m+mi}{2} \PYG{n}{Number} \PYG{n}{of} \PYG{n}{old} \PYG{n}{keys} \PYG{n}{kept}\PYG{p}{:} \PYG{l+m+mi}{5} \PYG{n}{Reference} \PYG{n}{count}\PYG{p}{:} \PYG{l+m+mi}{17} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{get\PYGZus{}policy} \PYG{o}{\PYGZhy{}}\PYG{n}{terse} \PYG{n}{admin} \PYG{n}{admin} \PYG{l+m+mi}{15552000} \PYG{l+m+mi}{0} \PYG{l+m+mi}{6} \PYG{l+m+mi}{2} \PYG{l+m+mi}{5} \PYG{l+m+mi}{17} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \sphinxAtStartPar The “Reference count†is the number of principals using that policy. With the LDAP KDC database module, the reference count field is not meaningful. \subsubsection{list\_policies} \label{\detokenize{admin/admin_commands/kadmin_local:list-policies}}\label{\detokenize{admin/admin_commands/kadmin_local:id17}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{list\_policies} {[}\sphinxstyleemphasis{expression}{]} \end{quote} \sphinxAtStartPar Retrieves all or some policy names. \sphinxstyleemphasis{expression} is a shell\sphinxhyphen{}style glob expression that can contain the wild\sphinxhyphen{}card characters \sphinxcode{\sphinxupquote{?}}, \sphinxcode{\sphinxupquote{*}}, and \sphinxcode{\sphinxupquote{{[}{]}}}. All policy names matching the expression are printed. If no expression is provided, all existing policy names are printed. \sphinxAtStartPar This command requires the \sphinxstylestrong{list} privilege. \sphinxAtStartPar Aliases: \sphinxstylestrong{listpols}, \sphinxstylestrong{get\_policies}, \sphinxstylestrong{getpols}. \sphinxAtStartPar Examples: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{listpols} \PYG{n}{test}\PYG{o}{\PYGZhy{}}\PYG{n}{pol} \PYG{n+nb}{dict}\PYG{o}{\PYGZhy{}}\PYG{n}{only} \PYG{n}{once}\PYG{o}{\PYGZhy{}}\PYG{n}{a}\PYG{o}{\PYGZhy{}}\PYG{n+nb}{min} \PYG{n}{test}\PYG{o}{\PYGZhy{}}\PYG{n}{pol}\PYG{o}{\PYGZhy{}}\PYG{n}{nopw} \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{listpols} \PYG{n}{t}\PYG{o}{*} \PYG{n}{test}\PYG{o}{\PYGZhy{}}\PYG{n}{pol} \PYG{n}{test}\PYG{o}{\PYGZhy{}}\PYG{n}{pol}\PYG{o}{\PYGZhy{}}\PYG{n}{nopw} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{ktadd} \label{\detokenize{admin/admin_commands/kadmin_local:ktadd}}\label{\detokenize{admin/admin_commands/kadmin_local:id18}}\begin{quote} \begin{DUlineblock}{0em} \item[] \sphinxstylestrong{ktadd} {[}options{]} \sphinxstyleemphasis{principal} \item[] \sphinxstylestrong{ktadd} {[}options{]} \sphinxstylestrong{\sphinxhyphen{}glob} \sphinxstyleemphasis{princ\sphinxhyphen{}exp} \end{DUlineblock} \end{quote} \sphinxAtStartPar Adds a \sphinxstyleemphasis{principal}, or all principals matching \sphinxstyleemphasis{princ\sphinxhyphen{}exp}, to a keytab file. Each principal’s keys are randomized in the process. The rules for \sphinxstyleemphasis{princ\sphinxhyphen{}exp} are described in the \sphinxstylestrong{list\_principals} command. \sphinxAtStartPar This command requires the \sphinxstylestrong{inquire} and \sphinxstylestrong{changepw} privileges. With the \sphinxstylestrong{\sphinxhyphen{}glob} form, it also requires the \sphinxstylestrong{list} privilege. \sphinxAtStartPar The options are: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k{[}eytab{]}} \sphinxstyleemphasis{keytab}} \sphinxAtStartPar Use \sphinxstyleemphasis{keytab} as the keytab file. Otherwise, the default keytab is used. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{enc}:\sphinxstyleemphasis{salt},…} \sphinxAtStartPar Uses the specified keysalt list for setting the new keys of the principal. See {\hyperref[\detokenize{admin/conf_files/kdc_conf:keysalt-lists}]{\sphinxcrossref{\DUrole{std,std-ref}{Keysalt lists}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} for a list of possible values. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}q}} \sphinxAtStartPar Display less verbose information. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}norandkey}} \sphinxAtStartPar Do not randomize the keys. The keys and their version numbers stay unchanged. This option cannot be specified in combination with the \sphinxstylestrong{\sphinxhyphen{}e} option. \end{description} \sphinxAtStartPar An entry for each of the principal’s unique encryption types is added, ignoring multiple keys with the same encryption type but different salt types. \sphinxAtStartPar Alias: \sphinxstylestrong{xst} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{ktadd} \PYG{o}{\PYGZhy{}}\PYG{n}{k} \PYG{o}{/}\PYG{n}{tmp}\PYG{o}{/}\PYG{n}{foo}\PYG{o}{\PYGZhy{}}\PYG{n}{new}\PYG{o}{\PYGZhy{}}\PYG{n}{keytab} \PYG{n}{host}\PYG{o}{/}\PYG{n}{foo}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{foo}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{tmp}\PYG{o}{/}\PYG{n}{foo}\PYG{o}{\PYGZhy{}}\PYG{n}{new}\PYG{o}{\PYGZhy{}}\PYG{n}{keytab} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{ktremove} \label{\detokenize{admin/admin_commands/kadmin_local:ktremove}}\label{\detokenize{admin/admin_commands/kadmin_local:id19}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{ktremove} {[}options{]} \sphinxstyleemphasis{principal} {[}\sphinxstyleemphasis{kvno} | \sphinxstyleemphasis{all} | \sphinxstyleemphasis{old}{]} \end{quote} \sphinxAtStartPar Removes entries for the specified \sphinxstyleemphasis{principal} from a keytab. Requires no permissions, since this does not require database access. \sphinxAtStartPar If the string “all†is specified, all entries for that principal are removed; if the string “old†is specified, all entries for that principal except those with the highest kvno are removed. Otherwise, the value specified is parsed as an integer, and all entries whose kvno match that integer are removed. \sphinxAtStartPar The options are: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k{[}eytab{]}} \sphinxstyleemphasis{keytab}} \sphinxAtStartPar Use \sphinxstyleemphasis{keytab} as the keytab file. Otherwise, the default keytab is used. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}q}} \sphinxAtStartPar Display less verbose information. \end{description} \sphinxAtStartPar Alias: \sphinxstylestrong{ktrem} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kadmin}\PYG{p}{:} \PYG{n}{ktremove} \PYG{n}{kadmin}\PYG{o}{/}\PYG{n}{admin} \PYG{n+nb}{all} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{kadmin}\PYG{o}{/}\PYG{n}{admin} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3} \PYG{n}{removed} \PYG{k+kn}{from} \PYG{n+nn}{keytab} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab} \PYG{n}{kadmin}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{lock} \label{\detokenize{admin/admin_commands/kadmin_local:lock}} \sphinxAtStartPar Lock database exclusively. Use with extreme caution! This command only works with the DB2 KDC database module. \subsubsection{unlock} \label{\detokenize{admin/admin_commands/kadmin_local:unlock}} \sphinxAtStartPar Release the exclusive database lock. \subsubsection{list\_requests} \label{\detokenize{admin/admin_commands/kadmin_local:list-requests}} \sphinxAtStartPar Lists available for kadmin requests. \sphinxAtStartPar Aliases: \sphinxstylestrong{lr}, \sphinxstylestrong{?} \subsubsection{quit} \label{\detokenize{admin/admin_commands/kadmin_local:quit}} \sphinxAtStartPar Exit program. If the database was locked, the lock is released. \sphinxAtStartPar Aliases: \sphinxstylestrong{exit}, \sphinxstylestrong{q} \subsection{HISTORY} \label{\detokenize{admin/admin_commands/kadmin_local:history}} \sphinxAtStartPar The kadmin program was originally written by Tom Yu at MIT, as an interface to the OpenVision Kerberos administration program. \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/kadmin_local:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/kadmin_local:see-also}} \sphinxAtStartPar \DUrole{xref,std,std-ref}{kpasswd(1)}, {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}}, \DUrole{xref,std,std-ref}{kerberos(7)} \sphinxstepscope \section{kadmind} \label{\detokenize{admin/admin_commands/kadmind:kadmind}}\label{\detokenize{admin/admin_commands/kadmind:kadmind-8}}\label{\detokenize{admin/admin_commands/kadmind::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/kadmind:synopsis}} \sphinxAtStartPar \sphinxstylestrong{kadmind} {[}\sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_args}{]} {[}\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}{]} {[}\sphinxstylestrong{\sphinxhyphen{}m}{]} {[}\sphinxstylestrong{\sphinxhyphen{}nofork}{]} {[}\sphinxstylestrong{\sphinxhyphen{}proponly}{]} {[}\sphinxstylestrong{\sphinxhyphen{}port} \sphinxstyleemphasis{port\sphinxhyphen{}number}{]} {[}\sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{pid\_file}{]} {[}\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{kdb5\_util\_path}{]} {[}\sphinxstylestrong{\sphinxhyphen{}K} \sphinxstyleemphasis{kprop\_path}{]} {[}\sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{kprop\_port}{]} {[}\sphinxstylestrong{\sphinxhyphen{}F} \sphinxstyleemphasis{dump\_file}{]} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/kadmind:description}} \sphinxAtStartPar kadmind starts the Kerberos administration server. kadmind typically runs on the primary Kerberos server, which stores the KDC database. If the KDC database uses the LDAP module, the administration server and the KDC server need not run on the same machine. kadmind accepts remote requests from programs such as {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} and \DUrole{xref,std,std-ref}{kpasswd(1)} to administer the information in these database. \sphinxAtStartPar kadmind requires a number of configuration files to be set up in order for it to work: \begin{description} \sphinxlineitem{{\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}} \sphinxAtStartPar The KDC configuration file contains configuration information for the KDC and admin servers. kadmind uses settings in this file to locate the Kerberos database, and is also affected by the \sphinxstylestrong{acl\_file}, \sphinxstylestrong{dict\_file}, \sphinxstylestrong{kadmind\_port}, and iprop\sphinxhyphen{}related settings. \sphinxlineitem{{\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}}} \sphinxAtStartPar kadmind’s ACL (access control list) tells it which principals are allowed to perform administration actions. The pathname to the ACL file can be specified with the \sphinxstylestrong{acl\_file} {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} variable; by default, it is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kadm5.acl}}. \end{description} \sphinxAtStartPar After the server begins running, it puts itself in the background and disassociates itself from its controlling terminal. \sphinxAtStartPar kadmind can be configured for incremental database propagation. Incremental propagation allows replica KDC servers to receive principal and policy updates incrementally instead of receiving full dumps of the database. This facility can be enabled in the {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} file with the \sphinxstylestrong{iprop\_enable} option. Incremental propagation requires the principal \sphinxcode{\sphinxupquote{kiprop/PRIMARY\textbackslash{}@REALM}} (where PRIMARY is the primary KDC’s canonical host name, and REALM the realm name). In release 1.13, this principal is automatically created and registered into the datebase. \subsection{OPTIONS} \label{\detokenize{admin/admin_commands/kadmind:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}} \sphinxAtStartPar specifies the realm that kadmind will serve; if it is not specified, the default realm of the host is used. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}m}} \sphinxAtStartPar causes the master database password to be fetched from the keyboard (before the server puts itself in the background, if not invoked with the \sphinxstylestrong{\sphinxhyphen{}nofork} option) rather than from a file on disk. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}nofork}} \sphinxAtStartPar causes the server to remain in the foreground and remain associated to the terminal. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}proponly}} \sphinxAtStartPar causes the server to only listen and respond to Kerberos replica incremental propagation polling requests. This option can be used to set up a hierarchical propagation topology where a replica KDC provides incremental updates to other Kerberos replicas. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}port} \sphinxstyleemphasis{port\sphinxhyphen{}number}} \sphinxAtStartPar specifies the port on which the administration server listens for connections. The default port is determined by the \sphinxstylestrong{kadmind\_port} configuration variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{pid\_file}} \sphinxAtStartPar specifies the file to which the PID of kadmind process should be written after it starts up. This file can be used to identify whether kadmind is still running and to allow init scripts to stop the correct process. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{kdb5\_util\_path}} \sphinxAtStartPar specifies the path to the kdb5\_util command to use when dumping the KDB in response to full resync requests when iprop is enabled. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}K} \sphinxstyleemphasis{kprop\_path}} \sphinxAtStartPar specifies the path to the kprop command to use to send full dumps to replicas in response to full resync requests. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{kprop\_port}} \sphinxAtStartPar specifies the port by which the kprop process that is spawned by kadmind connects to the replica kpropd, in order to transfer the dump file during an iprop full resync request. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}F} \sphinxstyleemphasis{dump\_file}} \sphinxAtStartPar specifies the file path to be used for dumping the KDB in response to full resync requests when iprop is enabled. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_args}} \sphinxAtStartPar specifies database\sphinxhyphen{}specific arguments. See {\hyperref[\detokenize{admin/admin_commands/kadmin_local:dboptions}]{\sphinxcrossref{\DUrole{std,std-ref}{Database Options}}}} in {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} for supported arguments. \end{description} \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/kadmind:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \sphinxAtStartPar As of release 1.22, kadmind supports systemd socket activation via the LISTEN\_PID and LISTEN\_FDS environment variables. Sockets provided by the caller must correspond to configured listener addresses (via the \sphinxstylestrong{kadmind\_listen} or \sphinxstylestrong{kpasswd\_listen} variables or equivalents) or they will be ignored. Any configured listener addresses that do not correspond to caller\sphinxhyphen{}provided sockets will be ignored if socket activation is used. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/kadmind:see-also}} \sphinxAtStartPar \DUrole{xref,std,std-ref}{kpasswd(1)}, {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}, {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}}, {\hyperref[\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_ldap\_util}}}}, {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}}, \DUrole{xref,std,std-ref}{kerberos(7)} \sphinxstepscope \section{kdb5\_util} \label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util}}\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}}\label{\detokenize{admin/admin_commands/kdb5_util::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/kdb5_util:synopsis}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-synopsis}} \sphinxAtStartPar \sphinxstylestrong{kdb5\_util} {[}\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}{]} {[}\sphinxstylestrong{\sphinxhyphen{}d} \sphinxstyleemphasis{dbname}{]} {[}\sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{mkeytype}{]} {[}\sphinxstylestrong{\sphinxhyphen{}kv} \sphinxstyleemphasis{mkeyVNO}{]} {[}\sphinxstylestrong{\sphinxhyphen{}M} \sphinxstyleemphasis{mkeyname}{]} {[}\sphinxstylestrong{\sphinxhyphen{}m}{]} {[}\sphinxstylestrong{\sphinxhyphen{}sf} \sphinxstyleemphasis{stashfilename}{]} {[}\sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{password}{]} {[}\sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_args}{]} \sphinxstyleemphasis{command} {[}\sphinxstyleemphasis{command\_options}{]} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/kdb5_util:description}}\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-synopsis-end}} \sphinxAtStartPar kdb5\_util allows an administrator to perform maintenance procedures on the KDC database. Databases can be created, destroyed, and dumped to or loaded from ASCII files. kdb5\_util can create a Kerberos master key stash file or perform live rollover of the master key. \sphinxAtStartPar When kdb5\_util is run, it attempts to acquire the master key and open the database. However, execution continues regardless of whether or not kdb5\_util successfully opens the database, because the database may not exist yet or the stash file may be corrupt. \sphinxAtStartPar Note that some KDC database modules may not support all kdb5\_util commands. \subsection{COMMAND\sphinxhyphen{}LINE OPTIONS} \label{\detokenize{admin/admin_commands/kdb5_util:command-line-options}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}} \sphinxAtStartPar specifies the Kerberos realm of the database. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}d} \sphinxstyleemphasis{dbname}} \sphinxAtStartPar specifies the name under which the principal database is stored; by default the database is that listed in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. The password policy database and lock files are also derived from this value. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{mkeytype}} \sphinxAtStartPar specifies the key type of the master key in the database. The default is given by the \sphinxstylestrong{master\_key\_type} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}kv} \sphinxstyleemphasis{mkeyVNO}} \sphinxAtStartPar Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}M} \sphinxstyleemphasis{mkeyname}} \sphinxAtStartPar principal name for the master key in the database. If not specified, the name is determined by the \sphinxstylestrong{master\_key\_name} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}m}} \sphinxAtStartPar specifies that the master database password should be read from the keyboard rather than fetched from a file on disk. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}sf} \sphinxstyleemphasis{stash\_file}} \sphinxAtStartPar specifies the stash filename of the master database password. If not specified, the filename is determined by the \sphinxstylestrong{key\_stash\_file} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{password}} \sphinxAtStartPar specifies the master database password. Using this option may expose the password to other users on the system via the process list. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_args}} \sphinxAtStartPar specifies database\sphinxhyphen{}specific options. See {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} for supported options. \end{description} \subsection{COMMANDS} \label{\detokenize{admin/admin_commands/kdb5_util:commands}}\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-options-end}} \subsubsection{create} \label{\detokenize{admin/admin_commands/kdb5_util:create}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-create}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{create} {[}\sphinxstylestrong{\sphinxhyphen{}s}{]} \end{quote} \sphinxAtStartPar Creates a new database. If the \sphinxstylestrong{\sphinxhyphen{}s} option is specified, the stash file is also created. This command fails if the database already exists. If the command is successful, the database is opened just as if it had already existed when the program was first run. \subsubsection{destroy} \label{\detokenize{admin/admin_commands/kdb5_util:destroy}}\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-create-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-destroy}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{destroy} {[}\sphinxstylestrong{\sphinxhyphen{}f}{]} \end{quote} \sphinxAtStartPar Destroys the database, first overwriting the disk sectors and then unlinking the files, after prompting the user for confirmation. With the \sphinxstylestrong{\sphinxhyphen{}f} argument, does not prompt the user. \subsubsection{stash} \label{\detokenize{admin/admin_commands/kdb5_util:stash}}\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-destroy-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-stash}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{stash} {[}\sphinxstylestrong{\sphinxhyphen{}f} \sphinxstyleemphasis{keyfile}{]} \end{quote} \sphinxAtStartPar Stores the master principal’s keys in a stash file. The \sphinxstylestrong{\sphinxhyphen{}f} argument can be used to override the \sphinxstyleemphasis{keyfile} specified in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \subsubsection{dump} \label{\detokenize{admin/admin_commands/kdb5_util:dump}}\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-stash-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-dump}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{dump} {[}\sphinxstylestrong{\sphinxhyphen{}b7}|\sphinxstylestrong{\sphinxhyphen{}r13}|\sphinxstylestrong{\sphinxhyphen{}r18}{]} {[}\sphinxstylestrong{\sphinxhyphen{}verbose}{]} {[}\sphinxstylestrong{\sphinxhyphen{}mkey\_convert}{]} {[}\sphinxstylestrong{\sphinxhyphen{}new\_mkey\_file} \sphinxstyleemphasis{mkey\_file}{]} {[}\sphinxstylestrong{\sphinxhyphen{}rev}{]} {[}\sphinxstylestrong{\sphinxhyphen{}recurse}{]} {[}\sphinxstyleemphasis{filename} {[}\sphinxstyleemphasis{principals}…{]}{]} \end{quote} \sphinxAtStartPar Dumps the current Kerberos and KADM5 database into an ASCII file. By default, the database is dumped in current format, “kdb5\_util load\_dump version 7â€. If filename is not specified, or is the string “\sphinxhyphen{}â€, the dump is sent to standard output. Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}b7}} \sphinxAtStartPar causes the dump to be in the Kerberos 5 Beta 7 format (“kdb5\_util load\_dump version 4â€). This was the dump format produced on releases prior to 1.2.2. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r13}} \sphinxAtStartPar causes the dump to be in the Kerberos 5 1.3 format (“kdb5\_util load\_dump version 5â€). This was the dump format produced on releases prior to 1.8. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r18}} \sphinxAtStartPar causes the dump to be in the Kerberos 5 1.8 format (“kdb5\_util load\_dump version 6â€). This was the dump format produced on releases prior to 1.11. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}verbose}} \sphinxAtStartPar causes the name of each principal and policy to be printed as it is dumped. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}mkey\_convert}} \sphinxAtStartPar prompts for a new master key. This new master key will be used to re\sphinxhyphen{}encrypt principal key data in the dumpfile. The principal keys themselves will not be changed. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}new\_mkey\_file} \sphinxstyleemphasis{mkey\_file}} \sphinxAtStartPar the filename of a stash file. The master key in this stash file will be used to re\sphinxhyphen{}encrypt the key data in the dumpfile. The key data in the database will not be changed. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}rev}} \sphinxAtStartPar dumps in reverse order. This may recover principals that do not dump normally, in cases where database corruption has occurred. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}recurse}} \sphinxAtStartPar causes the dump to walk the database recursively (btree only). This may recover principals that do not dump normally, in cases where database corruption has occurred. In cases of such corruption, this option will probably retrieve more principals than the \sphinxstylestrong{\sphinxhyphen{}rev} option will. \sphinxAtStartPar \DUrole{versionmodified,changed}{Changed in version 1.15: }Release 1.15 restored the functionality of the \sphinxstylestrong{\sphinxhyphen{}recurse} option. \sphinxAtStartPar \DUrole{versionmodified,changed}{Changed in version 1.5: }The \sphinxstylestrong{\sphinxhyphen{}recurse} option ceased working until release 1.15, doing a normal dump instead of a recursive traversal. \end{description} \subsubsection{load} \label{\detokenize{admin/admin_commands/kdb5_util:load}}\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-dump-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-load}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{load} {[}\sphinxstylestrong{\sphinxhyphen{}b7}|\sphinxstylestrong{\sphinxhyphen{}r13}|\sphinxstylestrong{\sphinxhyphen{}r18}{]} {[}\sphinxstylestrong{\sphinxhyphen{}hash}{]} {[}\sphinxstylestrong{\sphinxhyphen{}verbose}{]} {[}\sphinxstylestrong{\sphinxhyphen{}update}{]} \sphinxstyleemphasis{filename} \end{quote} \sphinxAtStartPar Loads a database dump from the named file into the named database. If no option is given to determine the format of the dump file, the format is detected automatically and handled as appropriate. Unless the \sphinxstylestrong{\sphinxhyphen{}update} option is given, \sphinxstylestrong{load} creates a new database containing only the data in the dump file, overwriting the contents of any previously existing database. Note that when using the LDAP KDC database module, the \sphinxstylestrong{\sphinxhyphen{}update} flag is required. \sphinxAtStartPar Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}b7}} \sphinxAtStartPar requires the database to be in the Kerberos 5 Beta 7 format (“kdb5\_util load\_dump version 4â€). This was the dump format produced on releases prior to 1.2.2. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r13}} \sphinxAtStartPar requires the database to be in Kerberos 5 1.3 format (“kdb5\_util load\_dump version 5â€). This was the dump format produced on releases prior to 1.8. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r18}} \sphinxAtStartPar requires the database to be in Kerberos 5 1.8 format (“kdb5\_util load\_dump version 6â€). This was the dump format produced on releases prior to 1.11. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}hash}} \sphinxAtStartPar stores the database in hash format, if using the DB2 database type. If this option is not specified, the database will be stored in btree format. This option is not recommended, as databases stored in hash format are known to corrupt data and lose principals. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}verbose}} \sphinxAtStartPar causes the name of each principal and policy to be printed as it is dumped. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}update}} \sphinxAtStartPar records from the dump file are added to or updated in the existing database. Otherwise, a new database is created containing only what is in the dump file and the old one destroyed upon successful completion. \end{description} \subsubsection{ark} \label{\detokenize{admin/admin_commands/kdb5_util:ark}}\label{\detokenize{admin/admin_commands/kdb5_util:kdb5-util-load-end}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{ark} {[}\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{enc}:\sphinxstyleemphasis{salt},…{]} \sphinxstyleemphasis{principal} \end{quote} \sphinxAtStartPar Adds new random keys to \sphinxstyleemphasis{principal} at the next available key version number. Keys for the current highest key version number will be preserved. The \sphinxstylestrong{\sphinxhyphen{}e} option specifies the list of encryption and salt types to be used for the new keys. \subsubsection{add\_mkey} \label{\detokenize{admin/admin_commands/kdb5_util:add-mkey}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{add\_mkey} {[}\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{etype}{]} {[}\sphinxstylestrong{\sphinxhyphen{}s}{]} \end{quote} \sphinxAtStartPar Adds a new master key to the master key principal, but does not mark it as active. Existing master keys will remain. The \sphinxstylestrong{\sphinxhyphen{}e} option specifies the encryption type of the new master key; see {\hyperref[\detokenize{admin/conf_files/kdc_conf:encryption-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Encryption types}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} for a list of possible values. The \sphinxstylestrong{\sphinxhyphen{}s} option stashes the new master key in the stash file, which will be created if it doesn’t already exist. \sphinxAtStartPar After a new master key is added, it should be propagated to replica servers via a manual or periodic invocation of {\hyperref[\detokenize{admin/admin_commands/kprop:kprop-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop}}}}. Then, the stash files on the replica servers should be updated with the kdb5\_util \sphinxstylestrong{stash} command. Once those steps are complete, the key is ready to be marked active with the kdb5\_util \sphinxstylestrong{use\_mkey} command. \subsubsection{use\_mkey} \label{\detokenize{admin/admin_commands/kdb5_util:use-mkey}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{use\_mkey} \sphinxstyleemphasis{mkeyVNO} {[}\sphinxstyleemphasis{time}{]} \end{quote} \sphinxAtStartPar Sets the activation time of the master key specified by \sphinxstyleemphasis{mkeyVNO}. Once a master key becomes active, it will be used to encrypt newly created principal keys. If no \sphinxstyleemphasis{time} argument is given, the current time is used, causing the specified master key version to become active immediately. The format for \sphinxstyleemphasis{time} is \DUrole{xref,std,std-ref}{getdate} string. \sphinxAtStartPar After a new master key becomes active, the kdb5\_util \sphinxstylestrong{update\_princ\_encryption} command can be used to update all principal keys to be encrypted in the new master key. \subsubsection{list\_mkeys} \label{\detokenize{admin/admin_commands/kdb5_util:list-mkeys}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{list\_mkeys} \end{quote} \sphinxAtStartPar List all master keys, from most recent to earliest, in the master key principal. The output will show the kvno, enctype, and salt type for each mkey, similar to the output of {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} \sphinxstylestrong{getprinc}. A \sphinxcode{\sphinxupquote{*}} following an mkey denotes the currently active master key. \subsubsection{purge\_mkeys} \label{\detokenize{admin/admin_commands/kdb5_util:purge-mkeys}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{purge\_mkeys} {[}\sphinxstylestrong{\sphinxhyphen{}f}{]} {[}\sphinxstylestrong{\sphinxhyphen{}n}{]} {[}\sphinxstylestrong{\sphinxhyphen{}v}{]} \end{quote} \sphinxAtStartPar Delete master keys from the master key principal that are not used to protect any principals. This command can be used to remove old master keys all principal keys are protected by a newer master key. \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}f}} \sphinxAtStartPar does not prompt for confirmation. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}n}} \sphinxAtStartPar performs a dry run, showing master keys that would be purged, but not actually purging any keys. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}v}} \sphinxAtStartPar gives more verbose output. \end{description} \subsubsection{update\_princ\_encryption} \label{\detokenize{admin/admin_commands/kdb5_util:update-princ-encryption}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{update\_princ\_encryption} {[}\sphinxstylestrong{\sphinxhyphen{}f}{]} {[}\sphinxstylestrong{\sphinxhyphen{}n}{]} {[}\sphinxstylestrong{\sphinxhyphen{}v}{]} {[}\sphinxstyleemphasis{princ\sphinxhyphen{}pattern}{]} \end{quote} \sphinxAtStartPar Update all principal records (or only those matching the \sphinxstyleemphasis{princ\sphinxhyphen{}pattern} glob pattern) to re\sphinxhyphen{}encrypt the key data using the active database master key, if they are encrypted using a different version, and give a count at the end of the number of principals updated. If the \sphinxstylestrong{\sphinxhyphen{}f} option is not given, ask for confirmation before starting to make changes. The \sphinxstylestrong{\sphinxhyphen{}v} option causes each principal processed to be listed, with an indication as to whether it needed updating or not. The \sphinxstylestrong{\sphinxhyphen{}n} option performs a dry run, only showing the actions which would have been taken. \subsubsection{tabdump} \label{\detokenize{admin/admin_commands/kdb5_util:tabdump}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{tabdump} {[}\sphinxstylestrong{\sphinxhyphen{}H}{]} {[}\sphinxstylestrong{\sphinxhyphen{}c}{]} {[}\sphinxstylestrong{\sphinxhyphen{}e}{]} {[}\sphinxstylestrong{\sphinxhyphen{}n}{]} {[}\sphinxstylestrong{\sphinxhyphen{}o} \sphinxstyleemphasis{outfile}{]} \sphinxstyleemphasis{dumptype} \end{quote} \sphinxAtStartPar Dump selected fields of the database in a tabular format suitable for reporting (e.g., using traditional Unix text processing tools) or importing into relational databases. The data format is tab\sphinxhyphen{}separated (default), or optionally comma\sphinxhyphen{}separated (CSV), with a fixed number of columns. The output begins with a header line containing field names, unless suppression is requested using the \sphinxstylestrong{\sphinxhyphen{}H} option. \sphinxAtStartPar The \sphinxstyleemphasis{dumptype} parameter specifies the name of an output table (see below). \sphinxAtStartPar Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}H}} \sphinxAtStartPar suppress writing the field names in a header line \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}c}} \sphinxAtStartPar use comma separated values (CSV) format, with minimal quoting, instead of the default tab\sphinxhyphen{}separated (unquoted, unescaped) format \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}e}} \sphinxAtStartPar write empty hexadecimal string fields as empty fields instead of as “\sphinxhyphen{}1â€. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}n}} \sphinxAtStartPar produce numeric output for fields that normally have symbolic output, such as enctypes and flag names. Also requests output of time stamps as decimal POSIX time\_t values. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}o} \sphinxstyleemphasis{outfile}} \sphinxAtStartPar write the dump to the specified output file instead of to standard output \end{description} \sphinxAtStartPar Dump types: \begin{description} \sphinxlineitem{\sphinxstylestrong{alias}} \sphinxAtStartPar principal alias information \begin{description} \sphinxlineitem{\sphinxstylestrong{aliasname}} \sphinxAtStartPar the name of the alias \sphinxlineitem{\sphinxstylestrong{targetname}} \sphinxAtStartPar the target of the alias \end{description} \sphinxlineitem{\sphinxstylestrong{keydata}} \sphinxAtStartPar principal encryption key information, including actual key data (which is still encrypted in the master key) \begin{description} \sphinxlineitem{\sphinxstylestrong{name}} \sphinxAtStartPar principal name \sphinxlineitem{\sphinxstylestrong{keyindex}} \sphinxAtStartPar index of this key in the principal’s key list \sphinxlineitem{\sphinxstylestrong{kvno}} \sphinxAtStartPar key version number \sphinxlineitem{\sphinxstylestrong{enctype}} \sphinxAtStartPar encryption type \sphinxlineitem{\sphinxstylestrong{key}} \sphinxAtStartPar key data as a hexadecimal string \sphinxlineitem{\sphinxstylestrong{salttype}} \sphinxAtStartPar salt type \sphinxlineitem{\sphinxstylestrong{salt}} \sphinxAtStartPar salt data as a hexadecimal string \end{description} \sphinxlineitem{\sphinxstylestrong{keyinfo}} \sphinxAtStartPar principal encryption key information (as in \sphinxstylestrong{keydata} above), excluding actual key data \sphinxlineitem{\sphinxstylestrong{princ\_flags}} \sphinxAtStartPar principal boolean attributes. Flag names print as hexadecimal numbers if the \sphinxstylestrong{\sphinxhyphen{}n} option is specified, and all flag positions are printed regardless of whether or not they are set. If \sphinxstylestrong{\sphinxhyphen{}n} is not specified, print all known flag names for each principal, but only print hexadecimal flag names if the corresponding flag is set. \begin{description} \sphinxlineitem{\sphinxstylestrong{name}} \sphinxAtStartPar principal name \sphinxlineitem{\sphinxstylestrong{flag}} \sphinxAtStartPar flag name \sphinxlineitem{\sphinxstylestrong{value}} \sphinxAtStartPar boolean value (0 for clear, or 1 for set) \end{description} \sphinxlineitem{\sphinxstylestrong{princ\_lockout}} \sphinxAtStartPar state information used for tracking repeated password failures \begin{description} \sphinxlineitem{\sphinxstylestrong{name}} \sphinxAtStartPar principal name \sphinxlineitem{\sphinxstylestrong{last\_success}} \sphinxAtStartPar time stamp of most recent successful authentication \sphinxlineitem{\sphinxstylestrong{last\_failed}} \sphinxAtStartPar time stamp of most recent failed authentication \sphinxlineitem{\sphinxstylestrong{fail\_count}} \sphinxAtStartPar count of failed attempts \end{description} \sphinxlineitem{\sphinxstylestrong{princ\_meta}} \sphinxAtStartPar principal metadata \begin{description} \sphinxlineitem{\sphinxstylestrong{name}} \sphinxAtStartPar principal name \sphinxlineitem{\sphinxstylestrong{modby}} \sphinxAtStartPar name of last principal to modify this principal \sphinxlineitem{\sphinxstylestrong{modtime}} \sphinxAtStartPar timestamp of last modification \sphinxlineitem{\sphinxstylestrong{lastpwd}} \sphinxAtStartPar timestamp of last password change \sphinxlineitem{\sphinxstylestrong{policy}} \sphinxAtStartPar policy object name \sphinxlineitem{\sphinxstylestrong{mkvno}} \sphinxAtStartPar key version number of the master key that encrypts this principal’s key data \sphinxlineitem{\sphinxstylestrong{hist\_kvno}} \sphinxAtStartPar key version number of the history key that encrypts the key history data for this principal \end{description} \sphinxlineitem{\sphinxstylestrong{princ\_stringattrs}} \sphinxAtStartPar string attributes (key/value pairs) \begin{description} \sphinxlineitem{\sphinxstylestrong{name}} \sphinxAtStartPar principal name \sphinxlineitem{\sphinxstylestrong{key}} \sphinxAtStartPar attribute name \sphinxlineitem{\sphinxstylestrong{value}} \sphinxAtStartPar attribute value \end{description} \sphinxlineitem{\sphinxstylestrong{princ\_tktpolicy}} \sphinxAtStartPar per\sphinxhyphen{}principal ticket policy data, including maximum ticket lifetimes \begin{description} \sphinxlineitem{\sphinxstylestrong{name}} \sphinxAtStartPar principal name \sphinxlineitem{\sphinxstylestrong{expiration}} \sphinxAtStartPar principal expiration date \sphinxlineitem{\sphinxstylestrong{pw\_expiration}} \sphinxAtStartPar password expiration date \sphinxlineitem{\sphinxstylestrong{max\_life}} \sphinxAtStartPar maximum ticket lifetime \sphinxlineitem{\sphinxstylestrong{max\_renew\_life}} \sphinxAtStartPar maximum renewable ticket lifetime \end{description} \end{description} \sphinxAtStartPar Examples: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYGZdl{} kdb5\PYGZus{}util tabdump \PYGZhy{}o keyinfo.txt keyinfo \PYGZdl{} cat keyinfo.txt name keyindex kvno enctype salttype salt K/M@EXAMPLE.COM 0 1 aes256\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha384\PYGZhy{}192 normal \PYGZhy{}1 foo@EXAMPLE.COM 0 1 aes128\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha1\PYGZhy{}96 normal \PYGZhy{}1 bar@EXAMPLE.COM 0 1 aes128\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha1\PYGZhy{}96 normal \PYGZhy{}1 \PYGZdl{} sqlite3 sqlite\PYGZgt{} .mode tabs sqlite\PYGZgt{} .import keyinfo.txt keyinfo sqlite\PYGZgt{} select * from keyinfo where enctype like \PYGZsq{}aes256\PYGZhy{}\PYGZpc{}\PYGZsq{}; K/M@EXAMPLE.COM 1 1 aes256\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha384\PYGZhy{}192 normal \PYGZhy{}1 sqlite\PYGZgt{} .quit \PYGZdl{} awk \PYGZhy{}F\PYGZsq{}\PYGZbs{}t\PYGZsq{} \PYGZsq{}\PYGZdl{}4 \PYGZti{} /aes256\PYGZhy{}/ \PYGZob{} print \PYGZcb{}\PYGZsq{} keyinfo.txt K/M@EXAMPLE.COM 1 1 aes256\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha384\PYGZhy{}192 normal \PYGZhy{}1 \end{sphinxVerbatim} \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/kdb5_util:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/kdb5_util:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}, \DUrole{xref,std,std-ref}{kerberos(7)} \sphinxstepscope \section{kdb5\_ldap\_util} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-8}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:synopsis}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-synopsis}} \sphinxAtStartPar \sphinxstylestrong{kdb5\_ldap\_util} {[}\sphinxstylestrong{\sphinxhyphen{}D} \sphinxstyleemphasis{user\_dn} {[}\sphinxstylestrong{\sphinxhyphen{}w} \sphinxstyleemphasis{passwd}{]}{]} {[}\sphinxstylestrong{\sphinxhyphen{}H} \sphinxstyleemphasis{ldapuri}{]} \sphinxstylestrong{command} {[}\sphinxstyleemphasis{command\_options}{]} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:description}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-synopsis-end}} \sphinxAtStartPar kdb5\_ldap\_util allows an administrator to manage realms, Kerberos services and ticket policies. \subsection{COMMAND\sphinxhyphen{}LINE OPTIONS} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:command-line-options}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}} \sphinxAtStartPar Specifies the realm to be operated on. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}D} \sphinxstyleemphasis{user\_dn}} \sphinxAtStartPar Specifies the Distinguished Name (DN) of the user who has sufficient rights to perform the operation on the LDAP server. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}w} \sphinxstyleemphasis{passwd}} \sphinxAtStartPar Specifies the password of \sphinxstyleemphasis{user\_dn}. This option is not recommended. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}H} \sphinxstyleemphasis{ldapuri}} \sphinxAtStartPar Specifies the URI of the LDAP server. \end{description} \sphinxAtStartPar By default, kdb5\_ldap\_util operates on the default realm (as specified in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}) and connects and authenticates to the LDAP server in the same manner as :ref:kadmind(8)\textasciigrave{} would given the parameters in {\hyperref[\detokenize{admin/conf_files/kdc_conf:dbdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}dbdefaults{]}}}}} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \subsection{COMMANDS} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:commands}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-options-end}} \subsubsection{create} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:create}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-create}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{create} {[}\sphinxstylestrong{\sphinxhyphen{}subtrees} \sphinxstyleemphasis{subtree\_dn\_list}{]} {[}\sphinxstylestrong{\sphinxhyphen{}sscope} \sphinxstyleemphasis{search\_scope}{]} {[}\sphinxstylestrong{\sphinxhyphen{}containerref} \sphinxstyleemphasis{container\_reference\_dn}{]} {[}\sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{mkeytype}{]} {[}\sphinxstylestrong{\sphinxhyphen{}kv} \sphinxstyleemphasis{mkeyVNO}{]} {[}\sphinxstylestrong{\sphinxhyphen{}M} \sphinxstyleemphasis{mkeyname}{]} {[}\sphinxstylestrong{\sphinxhyphen{}m|\sphinxhyphen{}P} \sphinxstyleemphasis{password}|\sphinxstylestrong{\sphinxhyphen{}sf} \sphinxstyleemphasis{stashfilename}{]} {[}\sphinxstylestrong{\sphinxhyphen{}s}{]} {[}\sphinxstylestrong{\sphinxhyphen{}maxtktlife} \sphinxstyleemphasis{max\_ticket\_life}{]} {[}\sphinxstylestrong{\sphinxhyphen{}maxrenewlife} \sphinxstyleemphasis{max\_renewable\_ticket\_life}{]} {[}\sphinxstyleemphasis{ticket\_flags}{]} \end{quote} \sphinxAtStartPar Creates realm in directory. Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}subtrees} \sphinxstyleemphasis{subtree\_dn\_list}} \sphinxAtStartPar Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (\sphinxcode{\sphinxupquote{:}}). \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}sscope} \sphinxstyleemphasis{search\_scope}} \sphinxAtStartPar Specifies the scope for searching the principals under the subtree. The possible values are 1 or one (one level), 2 or sub (subtrees). \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}containerref} \sphinxstyleemphasis{container\_reference\_dn}} \sphinxAtStartPar Specifies the DN of the container object in which the principals of a realm will be created. If the container reference is not configured for a realm, the principals will be created in the realm container. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{mkeytype}} \sphinxAtStartPar Specifies the key type of the master key in the database. The default is given by the \sphinxstylestrong{master\_key\_type} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}kv} \sphinxstyleemphasis{mkeyVNO}} \sphinxAtStartPar Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}M} \sphinxstyleemphasis{mkeyname}} \sphinxAtStartPar Specifies the principal name for the master key in the database. If not specified, the name is determined by the \sphinxstylestrong{master\_key\_name} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}m}} \sphinxAtStartPar Specifies that the master database password should be read from the TTY rather than fetched from a file on the disk. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{password}} \sphinxAtStartPar Specifies the master database password. This option is not recommended. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}sf} \sphinxstyleemphasis{stashfilename}} \sphinxAtStartPar Specifies the stash file of the master database password. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}s}} \sphinxAtStartPar Specifies that the stash file is to be created. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxtktlife} \sphinxstyleemphasis{max\_ticket\_life}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{getdate} string) Specifies maximum ticket life for principals in this realm. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxrenewlife} \sphinxstyleemphasis{max\_renewable\_ticket\_life}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{getdate} string) Specifies maximum renewable life of tickets for principals in this realm. \sphinxlineitem{\sphinxstyleemphasis{ticket\_flags}} \sphinxAtStartPar Specifies global ticket flags for the realm. Allowable flags are documented in the description of the \sphinxstylestrong{add\_principal} command in {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}. \end{description} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{o}{\PYGZhy{}}\PYG{n}{D} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{admin}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{o}{\PYGZhy{}}\PYG{n}{H} \PYG{n}{ldaps}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{ldap}\PYG{o}{\PYGZhy{}}\PYG{n}{server1}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{create} \PYG{o}{\PYGZhy{}}\PYG{n}{subtrees} \PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{o}{\PYGZhy{}}\PYG{n}{sscope} \PYG{n}{SUB} \PYG{n}{Password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=admin,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{n}{Initializing} \PYG{n}{database} \PYG{k}{for} \PYG{n}{realm} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{ATHENA.MIT.EDU}\PYG{l+s+s1}{\PYGZsq{}} \PYG{n}{You} \PYG{n}{will} \PYG{n}{be} \PYG{n}{prompted} \PYG{k}{for} \PYG{n}{the} \PYG{n}{database} \PYG{n}{Master} \PYG{n}{Password}\PYG{o}{.} \PYG{n}{It} \PYG{o+ow}{is} \PYG{n}{important} \PYG{n}{that} \PYG{n}{you} \PYG{n}{NOT} \PYG{n}{FORGET} \PYG{n}{this} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Enter} \PYG{n}{KDC} \PYG{n}{database} \PYG{n}{master} \PYG{n}{key}\PYG{p}{:} \PYG{n}{Re}\PYG{o}{\PYGZhy{}}\PYG{n}{enter} \PYG{n}{KDC} \PYG{n}{database} \PYG{n}{master} \PYG{n}{key} \PYG{n}{to} \PYG{n}{verify}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{modify} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:modify}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-create-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-modify}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{modify} {[}\sphinxstylestrong{\sphinxhyphen{}subtrees} \sphinxstyleemphasis{subtree\_dn\_list}{]} {[}\sphinxstylestrong{\sphinxhyphen{}sscope} \sphinxstyleemphasis{search\_scope}{]} {[}\sphinxstylestrong{\sphinxhyphen{}containerref} \sphinxstyleemphasis{container\_reference\_dn}{]} {[}\sphinxstylestrong{\sphinxhyphen{}maxtktlife} \sphinxstyleemphasis{max\_ticket\_life}{]} {[}\sphinxstylestrong{\sphinxhyphen{}maxrenewlife} \sphinxstyleemphasis{max\_renewable\_ticket\_life}{]} {[}\sphinxstyleemphasis{ticket\_flags}{]} \end{quote} \sphinxAtStartPar Modifies the attributes of a realm. Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}subtrees} \sphinxstyleemphasis{subtree\_dn\_list}} \sphinxAtStartPar Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (\sphinxcode{\sphinxupquote{:}}). This list replaces the existing list. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}sscope} \sphinxstyleemphasis{search\_scope}} \sphinxAtStartPar Specifies the scope for searching the principals under the subtrees. The possible values are 1 or one (one level), 2 or sub (subtrees). \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}containerref} \sphinxstyleemphasis{container\_reference\_dn} Specifies the DN of the} \sphinxAtStartPar container object in which the principals of a realm will be created. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxtktlife} \sphinxstyleemphasis{max\_ticket\_life}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{getdate} string) Specifies maximum ticket life for principals in this realm. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxrenewlife} \sphinxstyleemphasis{max\_renewable\_ticket\_life}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{getdate} string) Specifies maximum renewable life of tickets for principals in this realm. \sphinxlineitem{\sphinxstyleemphasis{ticket\_flags}} \sphinxAtStartPar Specifies global ticket flags for the realm. Allowable flags are documented in the description of the \sphinxstylestrong{add\_principal} command in {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}. \end{description} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{\PYGZhy{}}\PYG{n}{D} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{admin}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{o}{\PYGZhy{}}\PYG{n}{H} \PYG{n}{ldaps}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{ldap}\PYG{o}{\PYGZhy{}}\PYG{n}{server1}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n}{modify} \PYG{o}{+}\PYG{n}{requires\PYGZus{}preauth} \PYG{n}{Password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=admin,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \subsubsection{view} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:view}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-modify-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-view}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{view} \end{quote} \sphinxAtStartPar Displays the attributes of a realm. \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{o}{\PYGZhy{}}\PYG{n}{D} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{admin}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{o}{\PYGZhy{}}\PYG{n}{H} \PYG{n}{ldaps}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{ldap}\PYG{o}{\PYGZhy{}}\PYG{n}{server1}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{view} \PYG{n}{Password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=admin,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{n}{Realm} \PYG{n}{Name}\PYG{p}{:} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{Subtree}\PYG{p}{:} \PYG{n}{ou}\PYG{o}{=}\PYG{n}{users}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{n}{Subtree}\PYG{p}{:} \PYG{n}{ou}\PYG{o}{=}\PYG{n}{servers}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{n}{SearchScope}\PYG{p}{:} \PYG{n}{ONE} \PYG{n}{Maximum} \PYG{n}{ticket} \PYG{n}{life}\PYG{p}{:} \PYG{l+m+mi}{0} \PYG{n}{days} \PYG{l+m+mi}{01}\PYG{p}{:}\PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00} \PYG{n}{Maximum} \PYG{n}{renewable} \PYG{n}{life}\PYG{p}{:} \PYG{l+m+mi}{0} \PYG{n}{days} \PYG{l+m+mi}{10}\PYG{p}{:}\PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00} \PYG{n}{Ticket} \PYG{n}{flags}\PYG{p}{:} \PYG{n}{DISALLOW\PYGZus{}FORWARDABLE} \PYG{n}{REQUIRES\PYGZus{}PWCHANGE} \end{sphinxVerbatim} \subsubsection{destroy} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:destroy}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-view-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-destroy}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{destroy} {[}\sphinxstylestrong{\sphinxhyphen{}f}{]} \end{quote} \sphinxAtStartPar Destroys an existing realm. Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}f}} \sphinxAtStartPar If specified, will not prompt the user for confirmation. \end{description} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] shell\PYGZpc{} kdb5\PYGZus{}ldap\PYGZus{}util \PYGZhy{}r ATHENA.MIT.EDU \PYGZhy{}D cn=admin,o=org \PYGZhy{}H ldaps://ldap\PYGZhy{}server1.mit.edu destroy Password for \PYGZdq{}cn=admin,o=org\PYGZdq{}: Deleting KDC database of \PYGZsq{}ATHENA.MIT.EDU\PYGZsq{}, are you sure? (type \PYGZsq{}yes\PYGZsq{} to confirm)? yes OK, deleting database of \PYGZsq{}ATHENA.MIT.EDU\PYGZsq{}... shell\PYGZpc{} \end{sphinxVerbatim} \subsubsection{list} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:list}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-destroy-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-list}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{list} \end{quote} \sphinxAtStartPar Lists the names of realms under the container. \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{o}{\PYGZhy{}}\PYG{n}{D} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{admin}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{o}{\PYGZhy{}}\PYG{n}{H} \PYG{n}{ldaps}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{ldap}\PYG{o}{\PYGZhy{}}\PYG{n}{server1}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{n+nb}{list} \PYG{n}{Password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=admin,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{OPENLDAP}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{MEDIA}\PYG{o}{\PYGZhy{}}\PYG{n}{LAB}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \end{sphinxVerbatim} \subsubsection{stashsrvpw} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:stashsrvpw}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-list-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-stashsrvpw}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{stashsrvpw} {[}\sphinxstylestrong{\sphinxhyphen{}f} \sphinxstyleemphasis{filename}{]} \sphinxstyleemphasis{name} \end{quote} \sphinxAtStartPar Allows an administrator to store the password for service object in a file so that KDC and Administration server can use it to authenticate to the LDAP server. Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}f} \sphinxstyleemphasis{filename}} \sphinxAtStartPar Specifies the complete path of the service password file. By default, \sphinxcode{\sphinxupquote{/usr/local/var/service\_passwd}} is used. \sphinxlineitem{\sphinxstyleemphasis{name}} \sphinxAtStartPar Specifies the name of the object whose password is to be stored. If {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}} or {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} are configured for simple binding, this should be the distinguished name it will use as given by the \sphinxstylestrong{ldap\_kdc\_dn} or \sphinxstylestrong{ldap\_kadmind\_dn} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. If the KDC or kadmind is configured for SASL binding, this should be the authentication name it will use as given by the \sphinxstylestrong{ldap\_kdc\_sasl\_authcid} or \sphinxstylestrong{ldap\_kadmind\_sasl\_authcid} variable. \end{description} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{n}{stashsrvpw} \PYG{o}{\PYGZhy{}}\PYG{n}{f} \PYG{o}{/}\PYG{n}{home}\PYG{o}{/}\PYG{n}{andrew}\PYG{o}{/}\PYG{n}{conf\PYGZus{}keyfile} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{service}\PYG{o}{\PYGZhy{}}\PYG{n}{kdc}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{n}{Password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=service\PYGZhy{}kdc,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{n}{Re}\PYG{o}{\PYGZhy{}}\PYG{n}{enter} \PYG{n}{password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=service\PYGZhy{}kdc,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{create\_policy} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:create-policy}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-stashsrvpw-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-create-policy}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{create\_policy} {[}\sphinxstylestrong{\sphinxhyphen{}maxtktlife} \sphinxstyleemphasis{max\_ticket\_life}{]} {[}\sphinxstylestrong{\sphinxhyphen{}maxrenewlife} \sphinxstyleemphasis{max\_renewable\_ticket\_life}{]} {[}\sphinxstyleemphasis{ticket\_flags}{]} \sphinxstyleemphasis{policy\_name} \end{quote} \sphinxAtStartPar Creates a ticket policy in the directory. Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxtktlife} \sphinxstyleemphasis{max\_ticket\_life}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{getdate} string) Specifies maximum ticket life for principals. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}maxrenewlife} \sphinxstyleemphasis{max\_renewable\_ticket\_life}} \sphinxAtStartPar (\DUrole{xref,std,std-ref}{getdate} string) Specifies maximum renewable life of tickets for principals. \sphinxlineitem{\sphinxstyleemphasis{ticket\_flags}} \sphinxAtStartPar Specifies the ticket flags. If this option is not specified, by default, no restriction will be set by the policy. Allowable flags are documented in the description of the \sphinxstylestrong{add\_principal} command in {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}. \sphinxlineitem{\sphinxstyleemphasis{policy\_name}} \sphinxAtStartPar Specifies the name of the ticket policy. \end{description} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{o}{\PYGZhy{}}\PYG{n}{D} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{admin}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{o}{\PYGZhy{}}\PYG{n}{H} \PYG{n}{ldaps}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{ldap}\PYG{o}{\PYGZhy{}}\PYG{n}{server1}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{create\PYGZus{}policy} \PYG{o}{\PYGZhy{}}\PYG{n}{maxtktlife} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{1 day}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{\PYGZhy{}}\PYG{n}{maxrenewlife} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{1 week}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{\PYGZhy{}}\PYG{n}{allow\PYGZus{}postdated} \PYG{o}{+}\PYG{n}{needchange} \PYG{o}{\PYGZhy{}}\PYG{n}{allow\PYGZus{}forwardable} \PYG{n}{tktpolicy} \PYG{n}{Password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=admin,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{modify\_policy} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:modify-policy}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-create-policy-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-modify-policy}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{modify\_policy} {[}\sphinxstylestrong{\sphinxhyphen{}maxtktlife} \sphinxstyleemphasis{max\_ticket\_life}{]} {[}\sphinxstylestrong{\sphinxhyphen{}maxrenewlife} \sphinxstyleemphasis{max\_renewable\_ticket\_life}{]} {[}\sphinxstyleemphasis{ticket\_flags}{]} \sphinxstyleemphasis{policy\_name} \end{quote} \sphinxAtStartPar Modifies the attributes of a ticket policy. Options are same as for \sphinxstylestrong{create\_policy}. \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{o}{\PYGZhy{}}\PYG{n}{D} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{admin}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{o}{\PYGZhy{}}\PYG{n}{H} \PYG{n}{ldaps}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{ldap}\PYG{o}{\PYGZhy{}}\PYG{n}{server1}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{modify\PYGZus{}policy} \PYG{o}{\PYGZhy{}}\PYG{n}{maxtktlife} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{60 minutes}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{\PYGZhy{}}\PYG{n}{maxrenewlife} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{10 hours}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{+}\PYG{n}{allow\PYGZus{}postdated} \PYG{o}{\PYGZhy{}}\PYG{n}{requires\PYGZus{}preauth} \PYG{n}{tktpolicy} \PYG{n}{Password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=admin,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \end{sphinxVerbatim} \subsubsection{view\_policy} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:view-policy}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-modify-policy-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-view-policy}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{view\_policy} \sphinxstyleemphasis{policy\_name} \end{quote} \sphinxAtStartPar Displays the attributes of the named ticket policy. \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{o}{\PYGZhy{}}\PYG{n}{D} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{admin}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{o}{\PYGZhy{}}\PYG{n}{H} \PYG{n}{ldaps}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{ldap}\PYG{o}{\PYGZhy{}}\PYG{n}{server1}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{view\PYGZus{}policy} \PYG{n}{tktpolicy} \PYG{n}{Password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=admin,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{n}{Ticket} \PYG{n}{policy}\PYG{p}{:} \PYG{n}{tktpolicy} \PYG{n}{Maximum} \PYG{n}{ticket} \PYG{n}{life}\PYG{p}{:} \PYG{l+m+mi}{0} \PYG{n}{days} \PYG{l+m+mi}{01}\PYG{p}{:}\PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00} \PYG{n}{Maximum} \PYG{n}{renewable} \PYG{n}{life}\PYG{p}{:} \PYG{l+m+mi}{0} \PYG{n}{days} \PYG{l+m+mi}{10}\PYG{p}{:}\PYG{l+m+mi}{00}\PYG{p}{:}\PYG{l+m+mi}{00} \PYG{n}{Ticket} \PYG{n}{flags}\PYG{p}{:} \PYG{n}{DISALLOW\PYGZus{}FORWARDABLE} \PYG{n}{REQUIRES\PYGZus{}PWCHANGE} \end{sphinxVerbatim} \subsubsection{destroy\_policy} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:destroy-policy}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-view-policy-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-destroy-policy}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{destroy\_policy} {[}\sphinxstylestrong{\sphinxhyphen{}force}{]} \sphinxstyleemphasis{policy\_name} \end{quote} \sphinxAtStartPar Destroys an existing ticket policy. Options: \begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}force}} \sphinxAtStartPar Forces the deletion of the policy object. If not specified, the user will be prompted for confirmation before deleting the policy. \sphinxlineitem{\sphinxstyleemphasis{policy\_name}} \sphinxAtStartPar Specifies the name of the ticket policy. \end{description} \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] kdb5\PYGZus{}ldap\PYGZus{}util \PYGZhy{}D cn=admin,o=org \PYGZhy{}H ldaps://ldap\PYGZhy{}server1.mit.edu \PYGZhy{}r ATHENA.MIT.EDU destroy\PYGZus{}policy tktpolicy Password for \PYGZdq{}cn=admin,o=org\PYGZdq{}: This will delete the policy object \PYGZsq{}tktpolicy\PYGZsq{}, are you sure? (type \PYGZsq{}yes\PYGZsq{} to confirm)? yes ** policy object \PYGZsq{}tktpolicy\PYGZsq{} deleted. \end{sphinxVerbatim} \subsubsection{list\_policy} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:list-policy}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-destroy-policy-end}}\phantomsection\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-list-policy}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{list\_policy} \end{quote} \sphinxAtStartPar Lists ticket policies. \sphinxAtStartPar Example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kdb5\PYGZus{}ldap\PYGZus{}util} \PYG{o}{\PYGZhy{}}\PYG{n}{D} \PYG{n}{cn}\PYG{o}{=}\PYG{n}{admin}\PYG{p}{,}\PYG{n}{o}\PYG{o}{=}\PYG{n}{org} \PYG{o}{\PYGZhy{}}\PYG{n}{H} \PYG{n}{ldaps}\PYG{p}{:}\PYG{o}{/}\PYG{o}{/}\PYG{n}{ldap}\PYG{o}{\PYGZhy{}}\PYG{n}{server1}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{n}{list\PYGZus{}policy} \PYG{n}{Password} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{cn=admin,o=org}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{n}{tktpolicy} \PYG{n}{tmppolicy} \PYG{n}{userpolicy} \end{sphinxVerbatim} \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:environment}}\label{\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-list-policy-end}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/kdb5_ldap_util:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}, \DUrole{xref,std,std-ref}{kerberos(7)} \sphinxstepscope \section{krb5kdc} \label{\detokenize{admin/admin_commands/krb5kdc:krb5kdc}}\label{\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}}\label{\detokenize{admin/admin_commands/krb5kdc::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/krb5kdc:synopsis}} \sphinxAtStartPar \sphinxstylestrong{krb5kdc} {[}\sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_args}{]} {[}\sphinxstylestrong{\sphinxhyphen{}d} \sphinxstyleemphasis{dbname}{]} {[}\sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{keytype}{]} {[}\sphinxstylestrong{\sphinxhyphen{}M} \sphinxstyleemphasis{mkeyname}{]} {[}\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{portnum}{]} {[}\sphinxstylestrong{\sphinxhyphen{}m}{]} {[}\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}{]} {[}\sphinxstylestrong{\sphinxhyphen{}n}{]} {[}\sphinxstylestrong{\sphinxhyphen{}w} \sphinxstyleemphasis{numworkers}{]} {[}\sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{pid\_file}{]} {[}\sphinxstylestrong{\sphinxhyphen{}T} \sphinxstyleemphasis{time\_offset}{]} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/krb5kdc:description}} \sphinxAtStartPar krb5kdc is the Kerberos version 5 Authentication Service and Key Distribution Center (AS/KDC). \subsection{OPTIONS} \label{\detokenize{admin/admin_commands/krb5kdc:options}} \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm} option specifies the realm for which the server should provide service. This option may be specified multiple times to serve multiple realms. If no \sphinxstylestrong{\sphinxhyphen{}r} option is given, the default realm (as specified in {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}) will be served. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}d} \sphinxstyleemphasis{dbname} option specifies the name under which the principal database can be found. This option does not apply to the LDAP database. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{keytype} option specifies the key type of the master key to be entered manually as a password when \sphinxstylestrong{\sphinxhyphen{}m} is given; the default is \sphinxcode{\sphinxupquote{aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96}}. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}M} \sphinxstyleemphasis{mkeyname} option specifies the principal name for the master key in the database (usually \sphinxcode{\sphinxupquote{K/M}} in the KDC’s realm). \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}m} option specifies that the master database password should be fetched from the keyboard rather than from a stash file. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}n} option specifies that the KDC does not put itself in the background and does not disassociate itself from the terminal. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{pid\_file} option tells the KDC to write its PID into \sphinxstyleemphasis{pid\_file} after it starts up. This can be used to identify whether the KDC is still running and to allow init scripts to stop the correct process. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{portnum} option specifies the default UDP and TCP port numbers which the KDC should listen on for Kerberos version 5 requests, as a comma\sphinxhyphen{}separated list. This value overrides the port numbers specified in the {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdcdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}kdcdefaults{]}}}}} section of {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}, but may be overridden by realm\sphinxhyphen{}specific values. If no value is given from any source, the default port is 88. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}w} \sphinxstyleemphasis{numworkers} option tells the KDC to fork \sphinxstyleemphasis{numworkers} processes to listen to the KDC ports and process requests in parallel. The top level KDC process (whose pid is recorded in the pid file if the \sphinxstylestrong{\sphinxhyphen{}P} option is also given) acts as a supervisor. The supervisor will relay SIGHUP signals to the worker subprocesses, and will terminate the worker subprocess if the it is itself terminated or if any other worker process exits. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_args} option specifies database\sphinxhyphen{}specific arguments. See {\hyperref[\detokenize{admin/admin_commands/kadmin_local:dboptions}]{\sphinxcrossref{\DUrole{std,std-ref}{Database Options}}}} in {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} for supported arguments. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}T} \sphinxstyleemphasis{offset} option specifies a time offset, in seconds, which the KDC will operate under. It is intended only for testing purposes. \subsection{EXAMPLE} \label{\detokenize{admin/admin_commands/krb5kdc:example}} \sphinxAtStartPar The KDC may service requests for multiple realms (maximum 32 realms). The realms are listed on the command line. Per\sphinxhyphen{}realm options that can be specified on the command line pertain for each realm that follows it and are superseded by subsequent definitions of the same option. \sphinxAtStartPar For example: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{krb5kdc} \PYG{o}{\PYGZhy{}}\PYG{n}{p} \PYG{l+m+mi}{2001} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{REALM1} \PYG{o}{\PYGZhy{}}\PYG{n}{p} \PYG{l+m+mi}{2002} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{REALM2} \PYG{o}{\PYGZhy{}}\PYG{n}{r} \PYG{n}{REALM3} \end{sphinxVerbatim} \sphinxAtStartPar specifies that the KDC listen on port 2001 for REALM1 and on port 2002 for REALM2 and REALM3. Additionally, per\sphinxhyphen{}realm parameters may be specified in the {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} file. The location of this file may be specified by the \sphinxstylestrong{KRB5\_KDC\_PROFILE} environment variable. Per\sphinxhyphen{}realm parameters specified in this file take precedence over options specified on the command line. See the {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} description for further details. \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/krb5kdc:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \sphinxAtStartPar As of release 1.22, krb5kdc supports systemd socket activation via the LISTEN\_PID and LISTEN\_FDS environment variables. Sockets provided by the caller must correspond to configured listener addresses (via the \sphinxstylestrong{kdc\_listen} variable or equivalent) or they will be ignored. Any configured listener addresses that do not correspond to caller\sphinxhyphen{}provided sockets will be ignored if socket activation is used. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/krb5kdc:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}}, {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}, {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}, {\hyperref[\detokenize{admin/admin_commands/kdb5_ldap_util:kdb5-ldap-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_ldap\_util}}}}, \DUrole{xref,std,std-ref}{kerberos(7)} \sphinxstepscope \section{kprop} \label{\detokenize{admin/admin_commands/kprop:kprop}}\label{\detokenize{admin/admin_commands/kprop:kprop-8}}\label{\detokenize{admin/admin_commands/kprop::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/kprop:synopsis}} \sphinxAtStartPar \sphinxstylestrong{kprop} {[}\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}{]} {[}\sphinxstylestrong{\sphinxhyphen{}f} \sphinxstyleemphasis{file}{]} {[}\sphinxstylestrong{\sphinxhyphen{}d}{]} {[}\sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{port}{]} {[}\sphinxstylestrong{\sphinxhyphen{}s} \sphinxstyleemphasis{keytab}{]} \sphinxstyleemphasis{replica\_host} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/kprop:description}} \sphinxAtStartPar kprop is used to securely propagate a Kerberos V5 database dump file from the primary Kerberos server to a replica Kerberos server, which is specified by \sphinxstyleemphasis{replica\_host}. The dump file must be created by {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}}. \subsection{OPTIONS} \label{\detokenize{admin/admin_commands/kprop:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}} \sphinxAtStartPar Specifies the realm of the primary server. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}f} \sphinxstyleemphasis{file}} \sphinxAtStartPar Specifies the filename where the dumped principal database file is to be found; by default the dumped database file is normally {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/replica\_datatrans}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{port}} \sphinxAtStartPar Specifies the port to use to contact the {\hyperref[\detokenize{admin/admin_commands/kpropd:kpropd-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kpropd}}}} server on the remote host. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}d}} \sphinxAtStartPar Prints debugging information. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}s} \sphinxstyleemphasis{keytab}} \sphinxAtStartPar Specifies the location of the keytab file. \end{description} \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/kprop:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/kprop:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kpropd:kpropd-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kpropd}}}}, {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}}, {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}}, \DUrole{xref,std,std-ref}{kerberos(7)} \sphinxstepscope \section{kpropd} \label{\detokenize{admin/admin_commands/kpropd:kpropd}}\label{\detokenize{admin/admin_commands/kpropd:kpropd-8}}\label{\detokenize{admin/admin_commands/kpropd::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/kpropd:synopsis}} \sphinxAtStartPar \sphinxstylestrong{kpropd} {[}\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}{]} {[}\sphinxstylestrong{\sphinxhyphen{}A} \sphinxstyleemphasis{admin\_server}{]} {[}\sphinxstylestrong{\sphinxhyphen{}a} \sphinxstyleemphasis{acl\_file}{]} {[}\sphinxstylestrong{\sphinxhyphen{}f} \sphinxstyleemphasis{replica\_dumpfile}{]} {[}\sphinxstylestrong{\sphinxhyphen{}F} \sphinxstyleemphasis{principal\_database}{]} {[}\sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{kdb5\_util\_prog}{]} {[}\sphinxstylestrong{\sphinxhyphen{}P} \sphinxstyleemphasis{port}{]} {[}\sphinxstylestrong{\textendash{}pid\sphinxhyphen{}file}=\sphinxstyleemphasis{pid\_file}{]} {[}\sphinxstylestrong{\sphinxhyphen{}D}{]} {[}\sphinxstylestrong{\sphinxhyphen{}d}{]} {[}\sphinxstylestrong{\sphinxhyphen{}s} \sphinxstyleemphasis{keytab\_file}{]} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/kpropd:description}} \sphinxAtStartPar The \sphinxstyleemphasis{kpropd} command runs on the replica KDC server. It listens for update requests made by the {\hyperref[\detokenize{admin/admin_commands/kprop:kprop-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop}}}} program. If incremental propagation is enabled, it periodically requests incremental updates from the primary KDC. \sphinxAtStartPar When the replica receives a kprop request from the primary, kpropd accepts the dumped KDC database and places it in a file, and then runs {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} to load the dumped database into the active database which is used by {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}}. This allows the primary Kerberos server to use {\hyperref[\detokenize{admin/admin_commands/kprop:kprop-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop}}}} to propagate its database to the replica servers. Upon a successful download of the KDC database file, the replica Kerberos server will have an up\sphinxhyphen{}to\sphinxhyphen{}date KDC database. \sphinxAtStartPar Where incremental propagation is not used, kpropd is commonly invoked out of inetd(8) as a nowait service. This is done by adding a line to the \sphinxcode{\sphinxupquote{/etc/inetd.conf}} file which looks like this: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kprop} \PYG{n}{stream} \PYG{n}{tcp} \PYG{n}{nowait} \PYG{n}{root} \PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{sbin}\PYG{o}{/}\PYG{n}{kpropd} \PYG{n}{kpropd} \end{sphinxVerbatim} \sphinxAtStartPar kpropd can also run as a standalone daemon, backgrounding itself and waiting for connections on port 754 (or the port specified with the \sphinxstylestrong{\sphinxhyphen{}P} option if given). Standalone mode is required for incremental propagation. Starting in release 1.11, kpropd automatically detects whether it was run from inetd and runs in standalone mode if it is not. Prior to release 1.11, the \sphinxstylestrong{\sphinxhyphen{}S} option is required to run kpropd in standalone mode; this option is now accepted for backward compatibility but does nothing. \sphinxAtStartPar Incremental propagation may be enabled with the \sphinxstylestrong{iprop\_enable} variable in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}}. If incremental propagation is enabled, the replica periodically polls the primary KDC for updates, at an interval determined by the \sphinxstylestrong{iprop\_replica\_poll} variable. If the replica receives updates, kpropd updates its log file with any updates from the primary. {\hyperref[\detokenize{admin/admin_commands/kproplog:kproplog-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kproplog}}}} can be used to view a summary of the update entry log on the replica KDC. If incremental propagation is enabled, the principal \sphinxcode{\sphinxupquote{kiprop/replicahostname@REALM}} (where \sphinxstyleemphasis{replicahostname} is the name of the replica KDC host, and \sphinxstyleemphasis{REALM} is the name of the Kerberos realm) must be present in the replica’s keytab file. \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kproplog:kproplog-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kproplog}}}} can be used to force full replication when iprop is enabled. \subsection{OPTIONS} \label{\detokenize{admin/admin_commands/kpropd:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}r} \sphinxstyleemphasis{realm}} \sphinxAtStartPar Specifies the realm of the primary server. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}A} \sphinxstyleemphasis{admin\_server}} \sphinxAtStartPar Specifies the server to be contacted for incremental updates; by default, the primary admin server is contacted. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}f} \sphinxstyleemphasis{file}} \sphinxAtStartPar Specifies the filename where the dumped principal database file is to be stored; by default the dumped database file is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/from\_master}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}F} \sphinxstyleemphasis{kerberos\_db}} \sphinxAtStartPar Path to the Kerberos database file, if not the default. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}p}} \sphinxAtStartPar Allows the user to specify the pathname to the {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}} program; by default the pathname used is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{SBINDIR}}}}\sphinxcode{\sphinxupquote{/kdb5\_util}}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}D}} \sphinxAtStartPar In this mode, kpropd will not detach itself from the current job and run in the background. Instead, it will run in the foreground. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}d}} \sphinxAtStartPar Turn on debug mode. kpropd will print out debugging messages during the database propogation and will run in the foreground (implies \sphinxstylestrong{\sphinxhyphen{}D}). \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}P}} \sphinxAtStartPar Allow for an alternate port number for kpropd to listen on. This is only useful in combination with the \sphinxstylestrong{\sphinxhyphen{}S} option. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}a} \sphinxstyleemphasis{acl\_file}} \sphinxAtStartPar Allows the user to specify the path to the kpropd.acl file; by default the path used is {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kpropd.acl}}. \sphinxlineitem{\sphinxstylestrong{\textendash{}pid\sphinxhyphen{}file}=\sphinxstyleemphasis{pid\_file}} \sphinxAtStartPar In standalone mode, write the process ID of the daemon into \sphinxstyleemphasis{pid\_file}. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}s} \sphinxstyleemphasis{keytab\_file}} \sphinxAtStartPar Path to a keytab to use for acquiring acceptor credentials. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}x} \sphinxstyleemphasis{db\_args}} \sphinxAtStartPar Database\sphinxhyphen{}specific arguments. See {\hyperref[\detokenize{admin/admin_commands/kadmin_local:dboptions}]{\sphinxcrossref{\DUrole{std,std-ref}{Database Options}}}} in {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} for supported arguments. \end{description} \subsection{FILES} \label{\detokenize{admin/admin_commands/kpropd:files}}\begin{description} \sphinxlineitem{kpropd.acl} \sphinxAtStartPar Access file for kpropd; the default location is \sphinxcode{\sphinxupquote{/usr/local/var/krb5kdc/kpropd.acl}}. Each entry is a line containing the principal of a host from which the local machine will allow Kerberos database propagation via {\hyperref[\detokenize{admin/admin_commands/kprop:kprop-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop}}}}. \end{description} \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/kpropd:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/kpropd:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kprop:kprop-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop}}}}, {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}}, {\hyperref[\detokenize{admin/admin_commands/krb5kdc:krb5kdc-8}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5kdc}}}}, \DUrole{xref,std,std-ref}{kerberos(7)}, inetd(8) \sphinxstepscope \section{kproplog} \label{\detokenize{admin/admin_commands/kproplog:kproplog}}\label{\detokenize{admin/admin_commands/kproplog:kproplog-8}}\label{\detokenize{admin/admin_commands/kproplog::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/kproplog:synopsis}} \sphinxAtStartPar \sphinxstylestrong{kproplog} {[}\sphinxstylestrong{\sphinxhyphen{}h}{]} {[}\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{num}{]} {[}\sphinxhyphen{}v{]} \sphinxstylestrong{kproplog} {[}\sphinxhyphen{}R{]} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/kproplog:description}} \sphinxAtStartPar The kproplog command displays the contents of the KDC database update log to standard output. It can be used to keep track of incremental updates to the principal database. The update log file contains the update log maintained by the {\hyperref[\detokenize{admin/admin_commands/kadmind:kadmind-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmind}}}} process on the primary KDC server and the {\hyperref[\detokenize{admin/admin_commands/kpropd:kpropd-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kpropd}}}} process on the replica KDC servers. When updates occur, they are logged to this file. Subsequently any KDC replica configured for incremental updates will request the current data from the primary KDC and update their log file with any updates returned. \sphinxAtStartPar The kproplog command requires read access to the update log file. It will display update entries only for the KDC it runs on. \sphinxAtStartPar If no options are specified, kproplog displays a summary of the update log. If invoked on the primary, kproplog also displays all of the update entries. If invoked on a replica KDC server, kproplog displays only a summary of the updates, which includes the serial number of the last update received and the associated time stamp of the last update. \subsection{OPTIONS} \label{\detokenize{admin/admin_commands/kproplog:options}}\begin{description} \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}R}} \sphinxAtStartPar Reset the update log. This forces full resynchronization. If used on a replica then that replica will request a full resync. If used on the primary then all replicas will request full resyncs. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}h}} \sphinxAtStartPar Display a summary of the update log. This information includes the database version number, state of the database, the number of updates in the log, the time stamp of the first and last update, and the version number of the first and last update entry. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{num}} \sphinxAtStartPar Display the last \sphinxstyleemphasis{num} update entries in the log. This is useful when debugging synchronization between KDC servers. \sphinxlineitem{\sphinxstylestrong{\sphinxhyphen{}v}} \sphinxAtStartPar Display individual attributes per update. An example of the output generated for one entry: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{Update} \PYG{n}{Entry} \PYG{n}{Update} \PYG{n}{serial} \PYG{c+c1}{\PYGZsh{} : 4} \PYG{n}{Update} \PYG{n}{operation} \PYG{p}{:} \PYG{n}{Add} \PYG{n}{Update} \PYG{n}{principal} \PYG{p}{:} \PYG{n}{test}\PYG{n+nd}{@EXAMPLE}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{Update} \PYG{n}{size} \PYG{p}{:} \PYG{l+m+mi}{424} \PYG{n}{Update} \PYG{n}{committed} \PYG{p}{:} \PYG{k+kc}{True} \PYG{n}{Update} \PYG{n}{time} \PYG{n}{stamp} \PYG{p}{:} \PYG{n}{Fri} \PYG{n}{Feb} \PYG{l+m+mi}{20} \PYG{l+m+mi}{23}\PYG{p}{:}\PYG{l+m+mi}{37}\PYG{p}{:}\PYG{l+m+mi}{42} \PYG{l+m+mi}{2004} \PYG{n}{Attributes} \PYG{n}{changed} \PYG{p}{:} \PYG{l+m+mi}{6} \PYG{n}{Principal} \PYG{n}{Key} \PYG{n}{data} \PYG{n}{Password} \PYG{n}{last} \PYG{n}{changed} \PYG{n}{Modifying} \PYG{n}{principal} \PYG{n}{Modification} \PYG{n}{time} \PYG{n}{TL} \PYG{n}{data} \end{sphinxVerbatim} \end{description} \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/kproplog:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/kproplog:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kpropd:kpropd-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kpropd}}}}, \DUrole{xref,std,std-ref}{kerberos(7)} \sphinxstepscope \section{ktutil} \label{\detokenize{admin/admin_commands/ktutil:ktutil}}\label{\detokenize{admin/admin_commands/ktutil:ktutil-1}}\label{\detokenize{admin/admin_commands/ktutil::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/ktutil:synopsis}} \sphinxAtStartPar \sphinxstylestrong{ktutil} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/ktutil:description}} \sphinxAtStartPar The ktutil command invokes a command interface from which an administrator can read, write, or edit entries in a keytab. (Kerberos V4 srvtab files are no longer supported.) \subsection{COMMANDS} \label{\detokenize{admin/admin_commands/ktutil:commands}} \subsubsection{list} \label{\detokenize{admin/admin_commands/ktutil:list}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{list} {[}\sphinxstylestrong{\sphinxhyphen{}t}{]} {[}\sphinxstylestrong{\sphinxhyphen{}k}{]} {[}\sphinxstylestrong{\sphinxhyphen{}e}{]} \end{quote} \sphinxAtStartPar Displays the current keylist. If \sphinxstylestrong{\sphinxhyphen{}t}, \sphinxstylestrong{\sphinxhyphen{}k}, and/or \sphinxstylestrong{\sphinxhyphen{}e} are specified, also display the timestamp, key contents, or enctype (respectively). \sphinxAtStartPar Alias: \sphinxstylestrong{l} \subsubsection{read\_kt} \label{\detokenize{admin/admin_commands/ktutil:read-kt}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{read\_kt} \sphinxstyleemphasis{keytab} \end{quote} \sphinxAtStartPar Read the Kerberos V5 keytab file \sphinxstyleemphasis{keytab} into the current keylist. \sphinxAtStartPar Alias: \sphinxstylestrong{rkt} \subsubsection{write\_kt} \label{\detokenize{admin/admin_commands/ktutil:write-kt}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{write\_kt} \sphinxstyleemphasis{keytab} \end{quote} \sphinxAtStartPar Write the current keylist into the Kerberos V5 keytab file \sphinxstyleemphasis{keytab}. \sphinxAtStartPar Alias: \sphinxstylestrong{wkt} \subsubsection{clear\_list} \label{\detokenize{admin/admin_commands/ktutil:clear-list}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{clear\_list} \end{quote} \sphinxAtStartPar Clear the current keylist. \sphinxAtStartPar Alias: \sphinxstylestrong{clear} \subsubsection{delete\_entry} \label{\detokenize{admin/admin_commands/ktutil:delete-entry}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{delete\_entry} \sphinxstyleemphasis{slot} \end{quote} \sphinxAtStartPar Delete the entry in slot number \sphinxstyleemphasis{slot} from the current keylist. \sphinxAtStartPar Alias: \sphinxstylestrong{delent} \subsubsection{add\_entry} \label{\detokenize{admin/admin_commands/ktutil:add-entry}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{add\_entry} \{\sphinxstylestrong{\sphinxhyphen{}key}|\sphinxstylestrong{\sphinxhyphen{}password}\} \sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{principal} \sphinxstylestrong{\sphinxhyphen{}k} \sphinxstyleemphasis{kvno} {[}\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{enctype}{]} {[}\sphinxstylestrong{\sphinxhyphen{}f}|\sphinxstylestrong{\sphinxhyphen{}s} \sphinxstyleemphasis{salt}{]} \end{quote} \sphinxAtStartPar Add \sphinxstyleemphasis{principal} to keylist using key or password. If the \sphinxstylestrong{\sphinxhyphen{}f} flag is specified, salt information will be fetched from the KDC; in this case the \sphinxstylestrong{\sphinxhyphen{}e} flag may be omitted, or it may be supplied to force a particular enctype. If the \sphinxstylestrong{\sphinxhyphen{}f} flag is not specified, the \sphinxstylestrong{\sphinxhyphen{}e} flag must be specified, and the default salt will be used unless overridden with the \sphinxstylestrong{\sphinxhyphen{}s} option. \sphinxAtStartPar Alias: \sphinxstylestrong{addent} \subsubsection{list\_requests} \label{\detokenize{admin/admin_commands/ktutil:list-requests}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{list\_requests} \end{quote} \sphinxAtStartPar Displays a listing of available commands. \sphinxAtStartPar Aliases: \sphinxstylestrong{lr}, \sphinxstylestrong{?} \subsubsection{quit} \label{\detokenize{admin/admin_commands/ktutil:quit}}\begin{quote} \sphinxAtStartPar \sphinxstylestrong{quit} \end{quote} \sphinxAtStartPar Quits ktutil. \sphinxAtStartPar Aliases: \sphinxstylestrong{exit}, \sphinxstylestrong{q} \subsection{EXAMPLE} \label{\detokenize{admin/admin_commands/ktutil:example}}\begin{quote} \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{ktutil}\PYG{p}{:} \PYG{n}{add\PYGZus{}entry} \PYG{o}{\PYGZhy{}}\PYG{n}{password} \PYG{o}{\PYGZhy{}}\PYG{n}{p} \PYG{n}{alice}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{\PYGZhy{}}\PYG{n}{k} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}}\PYG{n}{e} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{alice}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{:} \PYG{n}{ktutil}\PYG{p}{:} \PYG{n}{add\PYGZus{}entry} \PYG{o}{\PYGZhy{}}\PYG{n}{password} \PYG{o}{\PYGZhy{}}\PYG{n}{p} \PYG{n}{alice}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{\PYGZhy{}}\PYG{n}{k} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}}\PYG{n}{e} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{Password} \PYG{k}{for} \PYG{n}{alice}\PYG{n+nd}{@BLEEP}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{:} \PYG{n}{ktutil}\PYG{p}{:} \PYG{n}{write\PYGZus{}kt} \PYG{n}{alice}\PYG{o}{.}\PYG{n}{keytab} \PYG{n}{ktutil}\PYG{p}{:} \end{sphinxVerbatim} \end{quote} \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/ktutil:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/ktutil:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}, {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}}, \DUrole{xref,std,std-ref}{kerberos(7)} \sphinxstepscope \section{k5srvutil} \label{\detokenize{admin/admin_commands/k5srvutil:k5srvutil}}\label{\detokenize{admin/admin_commands/k5srvutil:k5srvutil-1}}\label{\detokenize{admin/admin_commands/k5srvutil::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/k5srvutil:synopsis}} \sphinxAtStartPar \sphinxstylestrong{k5srvutil} \sphinxstyleemphasis{operation} {[}\sphinxstylestrong{\sphinxhyphen{}i}{]} {[}\sphinxstylestrong{\sphinxhyphen{}f} \sphinxstyleemphasis{filename}{]} {[}\sphinxstylestrong{\sphinxhyphen{}e} \sphinxstyleemphasis{keysalts}{]} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/k5srvutil:description}} \sphinxAtStartPar k5srvutil allows an administrator to list keys currently in a keytab, to obtain new keys for a principal currently in a keytab, or to delete non\sphinxhyphen{}current keys from a keytab. \sphinxAtStartPar \sphinxstyleemphasis{operation} must be one of the following: \begin{description} \sphinxlineitem{\sphinxstylestrong{list}} \sphinxAtStartPar Lists the keys in a keytab, showing version number and principal name. \sphinxlineitem{\sphinxstylestrong{change}} \sphinxAtStartPar Uses the kadmin protocol to update the keys in the Kerberos database to new randomly\sphinxhyphen{}generated keys, and updates the keys in the keytab to match. If a key’s version number doesn’t match the version number stored in the Kerberos server’s database, then the operation will fail. If the \sphinxstylestrong{\sphinxhyphen{}i} flag is given, k5srvutil will prompt for confirmation before changing each key. If the \sphinxstylestrong{\sphinxhyphen{}k} option is given, the old and new keys will be displayed. Ordinarily, keys will be generated with the default encryption types and key salts. This can be overridden with the \sphinxstylestrong{\sphinxhyphen{}e} option. Old keys are retained in the keytab so that existing tickets continue to work, but \sphinxstylestrong{delold} should be used after such tickets expire, to prevent attacks against the old keys. \sphinxlineitem{\sphinxstylestrong{delold}} \sphinxAtStartPar Deletes keys that are not the most recent version from the keytab. This operation should be used some time after a change operation to remove old keys, after existing tickets issued for the service have expired. If the \sphinxstylestrong{\sphinxhyphen{}i} flag is given, then k5srvutil will prompt for confirmation for each principal. \sphinxlineitem{\sphinxstylestrong{delete}} \sphinxAtStartPar Deletes particular keys in the keytab, interactively prompting for each key. \end{description} \sphinxAtStartPar In all cases, the default keytab is used unless this is overridden by the \sphinxstylestrong{\sphinxhyphen{}f} option. \sphinxAtStartPar k5srvutil uses the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} program to edit the keytab in place. \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/k5srvutil:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/k5srvutil:see-also}} \sphinxAtStartPar {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}, {\hyperref[\detokenize{admin/admin_commands/ktutil:ktutil-1}]{\sphinxcrossref{\DUrole{std,std-ref}{ktutil}}}}, \DUrole{xref,std,std-ref}{kerberos(7)} \sphinxstepscope \section{sserver} \label{\detokenize{admin/admin_commands/sserver:sserver}}\label{\detokenize{admin/admin_commands/sserver:sserver-8}}\label{\detokenize{admin/admin_commands/sserver::doc}} \subsection{SYNOPSIS} \label{\detokenize{admin/admin_commands/sserver:synopsis}} \sphinxAtStartPar \sphinxstylestrong{sserver} {[} \sphinxstylestrong{\sphinxhyphen{}p} \sphinxstyleemphasis{port} {]} {[} \sphinxstylestrong{\sphinxhyphen{}S} \sphinxstyleemphasis{keytab} {]} {[} \sphinxstyleemphasis{server\_port} {]} \subsection{DESCRIPTION} \label{\detokenize{admin/admin_commands/sserver:description}} \sphinxAtStartPar sserver and \DUrole{xref,std,std-ref}{sclient(1)} are a simple demonstration client/server application. When sclient connects to sserver, it performs a Kerberos authentication, and then sserver returns to sclient the Kerberos principal which was used for the Kerberos authentication. It makes a good test that Kerberos has been successfully installed on a machine. \sphinxAtStartPar The service name used by sserver and sclient is sample. Hence, sserver will require that there be a keytab entry for the service \sphinxcode{\sphinxupquote{sample/hostname.domain.name@REALM.NAME}}. This keytab is generated using the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} program. The keytab file is usually installed as {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFKTNAME}}}}. \sphinxAtStartPar The \sphinxstylestrong{\sphinxhyphen{}S} option allows for a different keytab than the default. \sphinxAtStartPar sserver is normally invoked out of inetd(8), using a line in \sphinxcode{\sphinxupquote{/etc/inetd.conf}} that looks like this: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{sample} \PYG{n}{stream} \PYG{n}{tcp} \PYG{n}{nowait} \PYG{n}{root} \PYG{o}{/}\PYG{n}{usr}\PYG{o}{/}\PYG{n}{local}\PYG{o}{/}\PYG{n}{sbin}\PYG{o}{/}\PYG{n}{sserver} \PYG{n}{sserver} \end{sphinxVerbatim} \sphinxAtStartPar Since \sphinxcode{\sphinxupquote{sample}} is normally not a port defined in \sphinxcode{\sphinxupquote{/etc/services}}, you will usually have to add a line to \sphinxcode{\sphinxupquote{/etc/services}} which looks like this: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{sample} \PYG{l+m+mi}{13135}\PYG{o}{/}\PYG{n}{tcp} \end{sphinxVerbatim} \sphinxAtStartPar When using sclient, you will first have to have an entry in the Kerberos database, by using {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}, and then you have to get Kerberos tickets, by using \DUrole{xref,std,std-ref}{kinit(1)}. Also, if you are running the sclient program on a different host than the sserver it will be connecting to, be sure that both hosts have an entry in /etc/services for the sample tcp port, and that the same port number is in both files. \sphinxAtStartPar When you run sclient you should see something like this: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{sendauth} \PYG{n}{succeeded}\PYG{p}{,} \PYG{n}{reply} \PYG{o+ow}{is}\PYG{p}{:} \PYG{n}{reply} \PYG{n+nb}{len} \PYG{l+m+mi}{32}\PYG{p}{,} \PYG{n}{contents}\PYG{p}{:} \PYG{n}{You} \PYG{n}{are} \PYG{n}{nlgilman}\PYG{n+nd}{@JIMI}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \end{sphinxVerbatim} \subsection{COMMON ERROR MESSAGES} \label{\detokenize{admin/admin_commands/sserver:common-error-messages}}\begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{)}% \item {} \sphinxAtStartPar kinit returns the error: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{kinit}\PYG{p}{:} \PYG{n}{Client} \PYG{o+ow}{not} \PYG{n}{found} \PYG{o+ow}{in} \PYG{n}{Kerberos} \PYG{n}{database} \PYG{k}{while} \PYG{n}{getting} \PYG{n}{initial} \PYG{n}{credentials} \end{sphinxVerbatim} \sphinxAtStartPar This means that you didn’t create an entry for your username in the Kerberos database. \item {} \sphinxAtStartPar sclient returns the error: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{unknown} \PYG{n}{service} \PYG{n}{sample}\PYG{o}{/}\PYG{n}{tcp}\PYG{p}{;} \PYG{n}{check} \PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{services} \end{sphinxVerbatim} \sphinxAtStartPar This means that you don’t have an entry in /etc/services for the sample tcp port. \item {} \sphinxAtStartPar sclient returns the error: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{connect}\PYG{p}{:} \PYG{n}{Connection} \PYG{n}{refused} \end{sphinxVerbatim} \sphinxAtStartPar This probably means you didn’t edit /etc/inetd.conf correctly, or you didn’t restart inetd after editing inetd.conf. \item {} \sphinxAtStartPar sclient returns the error: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{sclient}\PYG{p}{:} \PYG{n}{Server} \PYG{o+ow}{not} \PYG{n}{found} \PYG{o+ow}{in} \PYG{n}{Kerberos} \PYG{n}{database} \PYG{k}{while} \PYG{n}{using} \PYG{n}{sendauth} \end{sphinxVerbatim} \sphinxAtStartPar This means that the \sphinxcode{\sphinxupquote{sample/hostname@LOCAL.REALM}} service was not defined in the Kerberos database; it should be created using {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}, and a keytab file needs to be generated to make the key for that service principal available for sclient. \item {} \sphinxAtStartPar sclient returns the error: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{sendauth} \PYG{n}{rejected}\PYG{p}{,} \PYG{n}{error} \PYG{n}{reply} \PYG{o+ow}{is}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{No such file or directory}\PYG{l+s+s2}{\PYGZdq{}} \end{sphinxVerbatim} \sphinxAtStartPar This probably means sserver couldn’t find the keytab file. It was probably not installed in the proper directory. \end{enumerate} \subsection{ENVIRONMENT} \label{\detokenize{admin/admin_commands/sserver:environment}} \sphinxAtStartPar See \DUrole{xref,std,std-ref}{kerberos(7)} for a description of Kerberos environment variables. \subsection{SEE ALSO} \label{\detokenize{admin/admin_commands/sserver:see-also}} \sphinxAtStartPar \DUrole{xref,std,std-ref}{sclient(1)}, \DUrole{xref,std,std-ref}{kerberos(7)}, services(5), inetd(8) \sphinxstepscope \chapter{MIT Kerberos defaults} \label{\detokenize{mitK5defaults:mit-kerberos-defaults}}\label{\detokenize{mitK5defaults:mitk5defaults}}\label{\detokenize{mitK5defaults::doc}} \section{General defaults} \label{\detokenize{mitK5defaults:general-defaults}} \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TTT} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar Description &\sphinxstyletheadfamily \sphinxAtStartPar Default &\sphinxstyletheadfamily \sphinxAtStartPar Environment \\ \sphinxmidrule \sphinxtableatstartofbodyhook \sphinxAtStartPar \DUrole{xref,std,std-ref}{keytab\_definition} file & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFKTNAME}}}} & \sphinxAtStartPar \sphinxstylestrong{KRB5\_KTNAME} \\ \sphinxhline \sphinxAtStartPar Client \DUrole{xref,std,std-ref}{keytab\_definition} file & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{DEFCKTNAME}}}} & \sphinxAtStartPar \sphinxstylestrong{KRB5\_CLIENT\_KTNAME} \\ \sphinxhline \sphinxAtStartPar Kerberos config file {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/etc/krb5.conf}}\sphinxcode{\sphinxupquote{:}}{\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{SYSCONFDIR}}}}\sphinxcode{\sphinxupquote{/krb5.conf}} & \sphinxAtStartPar \sphinxstylestrong{KRB5\_CONFIG} \\ \sphinxhline \sphinxAtStartPar KDC config file {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kdc.conf}} & \sphinxAtStartPar \sphinxstylestrong{KRB5\_KDC\_PROFILE} \\ \sphinxhline \sphinxAtStartPar GSS mechanism config file & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{SYSCONFDIR}}}}\sphinxcode{\sphinxupquote{/gss/mech}} & \sphinxAtStartPar \sphinxstylestrong{GSS\_MECH\_CONFIG} \\ \sphinxhline \sphinxAtStartPar KDC database path (DB2) & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/principal}} &\\ \sphinxhline \sphinxAtStartPar Master key \DUrole{xref,std,std-ref}{stash\_definition} & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/.k5.}}\sphinxstyleemphasis{realm} &\\ \sphinxhline \sphinxAtStartPar Admin server ACL file {\hyperref[\detokenize{admin/conf_files/kadm5_acl:kadm5-acl-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kadm5.acl}}}} & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kadm5.acl}} &\\ \sphinxhline \sphinxAtStartPar OTP socket directory & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{RUNSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}} &\\ \sphinxhline \sphinxAtStartPar Plugin base directory & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LIBDIR}}}}\sphinxcode{\sphinxupquote{/krb5/plugins}} &\\ \sphinxhline \sphinxAtStartPar \DUrole{xref,std,std-ref}{rcache\_definition} directory & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/var/tmp}} & \sphinxAtStartPar \sphinxstylestrong{KRB5RCACHEDIR} \\ \sphinxhline \sphinxAtStartPar Master key default enctype & \sphinxAtStartPar \sphinxcode{\sphinxupquote{aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96}} &\\ \sphinxhline \sphinxAtStartPar Default {\hyperref[\detokenize{admin/conf_files/kdc_conf:keysalt-lists}]{\sphinxcrossref{\DUrole{std,std-ref}{keysalt list}}}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96:normal aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96:normal}} &\\ \sphinxhline \sphinxAtStartPar Permitted enctypes & \sphinxAtStartPar \sphinxcode{\sphinxupquote{aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha1\sphinxhyphen{}96 aes256\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha384\sphinxhyphen{}192 aes128\sphinxhyphen{}cts\sphinxhyphen{}hmac\sphinxhyphen{}sha256\sphinxhyphen{}128 des3\sphinxhyphen{}cbc\sphinxhyphen{}sha1 arcfour\sphinxhyphen{}hmac\sphinxhyphen{}md5 camellia256\sphinxhyphen{}cts\sphinxhyphen{}cmac camellia128\sphinxhyphen{}cts\sphinxhyphen{}cmac}} &\\ \sphinxhline \sphinxAtStartPar KDC default port & \sphinxAtStartPar 88 &\\ \sphinxhline \sphinxAtStartPar Admin server port & \sphinxAtStartPar 749 &\\ \sphinxhline \sphinxAtStartPar Password change port & \sphinxAtStartPar 464 &\\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \section{Replica KDC propagation defaults} \label{\detokenize{mitK5defaults:replica-kdc-propagation-defaults}} \sphinxAtStartPar This table shows defaults used by the {\hyperref[\detokenize{admin/admin_commands/kprop:kprop-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop}}}} and {\hyperref[\detokenize{admin/admin_commands/kpropd:kpropd-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kpropd}}}} programs. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TTT} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar Description &\sphinxstyletheadfamily \sphinxAtStartPar Default &\sphinxstyletheadfamily \sphinxAtStartPar Environment \\ \sphinxmidrule \sphinxtableatstartofbodyhook \sphinxAtStartPar kprop database dump file & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/replica\_datatrans}} &\\ \sphinxhline \sphinxAtStartPar kpropd temporary dump file & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/from\_master}} &\\ \sphinxhline \sphinxAtStartPar kdb5\_util location & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{SBINDIR}}}}\sphinxcode{\sphinxupquote{/kdb5\_util}} &\\ \sphinxhline \sphinxAtStartPar kprop location & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{SBINDIR}}}}\sphinxcode{\sphinxupquote{/kprop}} &\\ \sphinxhline \sphinxAtStartPar kpropd ACL file & \sphinxAtStartPar {\hyperref[\detokenize{mitK5defaults:paths}]{\sphinxcrossref{\DUrole{std,std-ref}{LOCALSTATEDIR}}}}\sphinxcode{\sphinxupquote{/krb5kdc}}\sphinxcode{\sphinxupquote{/kpropd.acl}} &\\ \sphinxhline \sphinxAtStartPar kprop port & \sphinxAtStartPar 754 & \sphinxAtStartPar KPROP\_PORT \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \section{Default paths for Unix\sphinxhyphen{}like systems} \label{\detokenize{mitK5defaults:default-paths-for-unix-like-systems}}\label{\detokenize{mitK5defaults:paths}} \sphinxAtStartPar On Unix\sphinxhyphen{}like systems, some paths used by MIT krb5 depend on parameters chosen at build time. For a custom build, these paths default to subdirectories of \sphinxcode{\sphinxupquote{/usr/local}}. When MIT krb5 is integrated into an operating system, the paths are generally chosen to match the operating system’s filesystem layout. \begin{savenotes}\sphinxattablestart \sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{TTTT} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar Description &\sphinxstyletheadfamily \sphinxAtStartPar Symbolic name &\sphinxstyletheadfamily \sphinxAtStartPar Custom build path &\sphinxstyletheadfamily \sphinxAtStartPar Typical OS path \\ \sphinxmidrule \sphinxtableatstartofbodyhook \sphinxAtStartPar User programs & \sphinxAtStartPar BINDIR & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/usr/local/bin}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/usr/bin}} \\ \sphinxhline \sphinxAtStartPar Libraries and plugins & \sphinxAtStartPar LIBDIR & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/usr/local/lib}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/usr/lib}} \\ \sphinxhline \sphinxAtStartPar Parent of KDC state dir & \sphinxAtStartPar LOCALSTATEDIR & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/usr/local/var}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/var}} \\ \sphinxhline \sphinxAtStartPar Parent of KDC runtime dir & \sphinxAtStartPar RUNSTATEDIR & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/usr/local/var/run}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/run}} \\ \sphinxhline \sphinxAtStartPar Administrative programs & \sphinxAtStartPar SBINDIR & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/usr/local/sbin}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/usr/sbin}} \\ \sphinxhline \sphinxAtStartPar Alternate krb5.conf dir & \sphinxAtStartPar SYSCONFDIR & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/usr/local/etc}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{/etc}} \\ \sphinxhline \sphinxAtStartPar Default ccache name & \sphinxAtStartPar DEFCCNAME & \sphinxAtStartPar \sphinxcode{\sphinxupquote{FILE:/tmp/krb5cc\_\%\{uid\}}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{FILE:/tmp/krb5cc\_\%\{uid\}}} \\ \sphinxhline \sphinxAtStartPar Default keytab name & \sphinxAtStartPar DEFKTNAME & \sphinxAtStartPar \sphinxcode{\sphinxupquote{FILE:/etc/krb5.keytab}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{FILE:/etc/krb5.keytab}} \\ \sphinxhline \sphinxAtStartPar Default PKCS11 module & \sphinxAtStartPar PKCS11\_MODNAME & \sphinxAtStartPar \sphinxcode{\sphinxupquote{opensc\sphinxhyphen{}pkcs11.so}} & \sphinxAtStartPar \sphinxcode{\sphinxupquote{opensc\sphinxhyphen{}pkcs11.so}} \\ \sphinxbottomrule \end{tabulary} \sphinxtableafterendhook\par \sphinxattableend\end{savenotes} \sphinxAtStartPar The default client keytab name (DEFCKTNAME) typically defaults to \sphinxcode{\sphinxupquote{FILE:/usr/local/var/krb5/user/\%\{euid\}/client.keytab}} for a custom build. A native build will typically use a path which will vary according to the operating system’s layout of \sphinxcode{\sphinxupquote{/var}}. \sphinxstepscope \chapter{Environment variables} \label{\detokenize{admin/env_variables:environment-variables}}\label{\detokenize{admin/env_variables::doc}} \sphinxAtStartPar This content has moved to \DUrole{xref,std,std-ref}{kerberos(7)}. \sphinxstepscope \chapter{Troubleshooting} \label{\detokenize{admin/troubleshoot:troubleshooting}}\label{\detokenize{admin/troubleshoot:troubleshoot}}\label{\detokenize{admin/troubleshoot::doc}} \section{Trace logging} \label{\detokenize{admin/troubleshoot:trace-logging}}\label{\detokenize{admin/troubleshoot:id1}} \sphinxAtStartPar Most programs using MIT krb5 1.9 or later can be made to provide information about internal krb5 library operations using trace logging. To enable this, set the \sphinxstylestrong{KRB5\_TRACE} environment variable to a filename before running the program. On many operating systems, the filename \sphinxcode{\sphinxupquote{/dev/stdout}} can be used to send trace logging output to standard output. \sphinxAtStartPar Some programs do not honor \sphinxstylestrong{KRB5\_TRACE}, either because they use secure library contexts (this generally applies to setuid programs and parts of the login system) or because they take direct control of the trace logging system using the API. \sphinxAtStartPar Here is a short example showing trace logging output for an invocation of the \DUrole{xref,std,std-ref}{kvno(1)} command: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{shell}\PYG{o}{\PYGZpc{}} \PYG{n}{env} \PYG{n}{KRB5\PYGZus{}TRACE}\PYG{o}{=}\PYG{o}{/}\PYG{n}{dev}\PYG{o}{/}\PYG{n}{stdout} \PYG{n}{kvno} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{KRBTEST}\PYG{o}{.}\PYG{n}{COM} \PYG{p}{[}\PYG{l+m+mi}{9138}\PYG{p}{]} \PYG{l+m+mf}{1332348778.823276}\PYG{p}{:} \PYG{n}{Getting} \PYG{n}{credentials} \PYG{n}{user}\PYG{n+nd}{@KRBTEST}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{KRBTEST}\PYG{o}{.}\PYG{n}{COM}\PYG{n+nd}{@KRBTEST}\PYG{o}{.}\PYG{n}{COM} \PYG{n}{using} \PYG{n}{ccache} \PYG{n}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{me}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{/}\PYG{n}{build}\PYG{o}{/}\PYG{n}{testdir}\PYG{o}{/}\PYG{n}{ccache} \PYG{p}{[}\PYG{l+m+mi}{9138}\PYG{p}{]} \PYG{l+m+mf}{1332348778.823381}\PYG{p}{:} \PYG{n}{Retrieving} \PYG{n}{user}\PYG{n+nd}{@KRBTEST}\PYG{o}{.}\PYG{n}{COM} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZgt{}} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{KRBTEST}\PYG{o}{.}\PYG{n}{COM}\PYG{n+nd}{@KRBTEST}\PYG{o}{.}\PYG{n}{COM} \PYG{k+kn}{from} \PYG{n+nn}{FILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{me}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{/}\PYG{n}{build}\PYG{o}{/}\PYG{n}{testdir}\PYG{o}{/}\PYG{n}{ccache} \PYG{k}{with} \PYG{n}{result}\PYG{p}{:} \PYG{l+m+mi}{0}\PYG{o}{/}\PYG{n}{Unknown} \PYG{n}{code} \PYG{l+m+mi}{0} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{KRBTEST}\PYG{o}{.}\PYG{n}{COM}\PYG{n+nd}{@KRBTEST}\PYG{o}{.}\PYG{n}{COM}\PYG{p}{:} \PYG{n}{kvno} \PYG{o}{=} \PYG{l+m+mi}{1} \end{sphinxVerbatim} \section{List of errors} \label{\detokenize{admin/troubleshoot:list-of-errors}} \subsection{Frequently seen errors} \label{\detokenize{admin/troubleshoot:frequently-seen-errors}}\begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/troubleshoot:init-creds-etype-nosupp}]{\sphinxcrossref{\DUrole{std,std-ref}{KDC has no support for encryption type while getting initial credentials}}}} \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/troubleshoot:cert-chain-etype-nosupp}]{\sphinxcrossref{\DUrole{std,std-ref}{credential verification failed: KDC has no support for encryption type}}}} \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/troubleshoot:err-cert-chain-cert-expired}]{\sphinxcrossref{\DUrole{std,std-ref}{Cannot create cert chain: certificate has expired}}}} \end{enumerate} \subsection{Errors seen by admins} \label{\detokenize{admin/troubleshoot:errors-seen-by-admins}}\phantomsection\label{\detokenize{admin/troubleshoot:prop-failed-start}}\begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/troubleshoot:kprop-no-route}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop: No route to host while connecting to server}}}} \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/troubleshoot:kprop-con-refused}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop: Connection refused while connecting to server}}}} \item {} \sphinxAtStartPar {\hyperref[\detokenize{admin/troubleshoot:kprop-sendauth-exchange}]{\sphinxcrossref{\DUrole{std,std-ref}{kprop: Server rejected authentication (during sendauth exchange) while authenticating to server}}}} \end{enumerate} \phantomsection\label{\detokenize{admin/troubleshoot:prop-failed-end}} \bigskip\hrule\bigskip \subsubsection{KDC has no support for encryption type while getting initial credentials} \label{\detokenize{admin/troubleshoot:kdc-has-no-support-for-encryption-type-while-getting-initial-credentials}}\label{\detokenize{admin/troubleshoot:init-creds-etype-nosupp}} \subsubsection{credential verification failed: KDC has no support for encryption type} \label{\detokenize{admin/troubleshoot:credential-verification-failed-kdc-has-no-support-for-encryption-type}}\label{\detokenize{admin/troubleshoot:cert-chain-etype-nosupp}} \sphinxAtStartPar This most commonly happens when trying to use a principal with only DES keys, in a release (MIT krb5 1.7 or later) which disables DES by default. DES encryption is considered weak due to its inadequate key size. If you cannot migrate away from its use, you can re\sphinxhyphen{}enable DES by adding \sphinxcode{\sphinxupquote{allow\_weak\_crypto = true}} to the {\hyperref[\detokenize{admin/conf_files/krb5_conf:libdefaults}]{\sphinxcrossref{\DUrole{std,std-ref}{{[}libdefaults{]}}}}} section of {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}}. \subsubsection{Cannot create cert chain: certificate has expired} \label{\detokenize{admin/troubleshoot:cannot-create-cert-chain-certificate-has-expired}}\label{\detokenize{admin/troubleshoot:err-cert-chain-cert-expired}} \sphinxAtStartPar This error message indicates that PKINIT authentication failed because the client certificate, KDC certificate, or one of the certificates in the signing chain above them has expired. \sphinxAtStartPar If the KDC certificate has expired, this message appears in the KDC log file, and the client will receive a “Preauthentication failed†error. (Prior to release 1.11, the KDC log file message erroneously appears as “Out of memoryâ€. Prior to release 1.12, the client will receive a “Generic errorâ€.) \sphinxAtStartPar If the client or a signing certificate has expired, this message may appear in {\hyperref[\detokenize{admin/troubleshoot:trace-logging}]{\sphinxcrossref{trace\_logging}}} output from \DUrole{xref,std,std-ref}{kinit(1)} or, starting in release 1.12, as an error message from kinit or another program which gets initial tickets. The error message is more likely to appear properly on the client if the principal entry has no long\sphinxhyphen{}term keys. \subsubsection{kprop: No route to host while connecting to server} \label{\detokenize{admin/troubleshoot:kprop-no-route-to-host-while-connecting-to-server}}\label{\detokenize{admin/troubleshoot:kprop-no-route}} \sphinxAtStartPar Make sure that the hostname of the replica KDC (as given to kprop) is correct, and that any firewalls between the primary and the replica allow a connection on port 754. \subsubsection{kprop: Connection refused while connecting to server} \label{\detokenize{admin/troubleshoot:kprop-connection-refused-while-connecting-to-server}}\label{\detokenize{admin/troubleshoot:kprop-con-refused}} \sphinxAtStartPar If the replica KDC is intended to run kpropd out of inetd, make sure that inetd is configured to accept krb5\_prop connections. inetd may need to be restarted or sent a SIGHUP to recognize the new configuration. If the replica is intended to run kpropd in standalone mode, make sure that it is running. \subsubsection{kprop: Server rejected authentication (during sendauth exchange) while authenticating to server} \label{\detokenize{admin/troubleshoot:kprop-server-rejected-authentication-during-sendauth-exchange-while-authenticating-to-server}}\label{\detokenize{admin/troubleshoot:kprop-sendauth-exchange}} \sphinxAtStartPar Make sure that: \begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar The time is synchronized between the primary and replica KDCs. \item {} \sphinxAtStartPar The master stash file was copied from the primary to the expected location on the replica. \item {} \sphinxAtStartPar The replica has a keytab file in the default location containing a \sphinxcode{\sphinxupquote{host}} principal for the replica’s hostname. \end{enumerate} \sphinxstepscope \chapter{Advanced topics} \label{\detokenize{admin/advanced/index:advanced-topics}}\label{\detokenize{admin/advanced/index::doc}} \sphinxstepscope \section{Retiring DES} \label{\detokenize{admin/advanced/retiring-des:retiring-des}}\label{\detokenize{admin/advanced/retiring-des:id1}}\label{\detokenize{admin/advanced/retiring-des::doc}} \sphinxAtStartPar Version 5 of the Kerberos protocol was originally implemented using the Data Encryption Standard (DES) as a block cipher for encryption. While it was considered secure at the time, advancements in computational ability have rendered DES vulnerable to brute force attacks on its 56\sphinxhyphen{}bit keyspace. As such, it is now considered insecure and should not be used (\index{RFC@\spxentry{RFC}!RFC 6649@\spxentry{RFC 6649}}\sphinxhref{https://datatracker.ietf.org/doc/html/rfc6649.html}{\sphinxstylestrong{RFC 6649}}). \subsection{History} \label{\detokenize{admin/advanced/retiring-des:history}} \sphinxAtStartPar DES was used in the original Kerberos implementation, and was the only cryptosystem in krb5 1.0. Partial support for triple\sphinxhyphen{}DES (3DES) was added in version 1.1, with full support following in version 1.2. The Advanced Encryption Standard (AES), which supersedes DES, gained partial support in version 1.3.0 of krb5 and full support in version 1.3.2. However, deployments of krb5 using Kerberos databases created with older versions of krb5 will not necessarily start using strong crypto for ordinary operation without administrator intervention. \sphinxAtStartPar MIT krb5 began flagging deprecated encryption types with release 1.17, and removed DES (single\sphinxhyphen{}DES) support in release 1.18. As a consequence, a release prior to 1.18 is required to perform these migrations. \subsection{Types of keys} \label{\detokenize{admin/advanced/retiring-des:types-of-keys}}\begin{itemize} \item {} \sphinxAtStartPar The database master key: This key is not exposed to user requests, but is used to encrypt other key material stored in the kerberos database. The database master key is currently stored as \sphinxcode{\sphinxupquote{K/M}} by default. \item {} \sphinxAtStartPar Password\sphinxhyphen{}derived keys: User principals frequently have keys derived from a password. When a new password is set, the KDC uses various string2key functions to generate keys in the database for that principal. \item {} \sphinxAtStartPar Keytab keys: Application server principals generally use random keys which are not derived from a password. When the database entry is created, the KDC generates random keys of various enctypes to enter in the database, which are conveyed to the application server and stored in a keytab. \item {} \sphinxAtStartPar Session keys: These are short\sphinxhyphen{}term keys generated by the KDC while processing client requests, with an enctype selected by the KDC. \end{itemize} \sphinxAtStartPar For details on the various enctypes and how enctypes are selected by the KDC for session keys and client/server long\sphinxhyphen{}term keys, see {\hyperref[\detokenize{admin/enctypes:enctypes}]{\sphinxcrossref{\DUrole{std,std-ref}{Encryption types}}}}. When using the {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} interface to generate new long\sphinxhyphen{}term keys, the \sphinxstylestrong{\sphinxhyphen{}e} argument can be used to force a particular set of enctypes, overriding the KDC default values. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar When the KDC is selecting a session key, it has no knowledge about the kerberos installation on the server which will receive the service ticket, only what keys are in the database for the service principal. In order to allow uninterrupted operation to clients while migrating away from DES, care must be taken to ensure that kerberos installations on application server machines are configured to support newer encryption types before keys of those new encryption types are created in the Kerberos database for those server principals. \end{sphinxadmonition} \subsection{Upgrade procedure} \label{\detokenize{admin/advanced/retiring-des:upgrade-procedure}} \sphinxAtStartPar This procedure assumes that the KDC software has already been upgraded to a modern version of krb5 that supports non\sphinxhyphen{}DES keys, so that the only remaining task is to update the actual keys used to service requests. The realm used for demonstrating this procedure, ZONE.MIT.EDU, is an example of the worst\sphinxhyphen{}case scenario, where all keys in the realm are DES. The realm was initially created with a very old version of krb5, and \sphinxstylestrong{supported\_enctypes} in {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} was set to a value appropriate when the KDC was installed, but was not updated as the KDC was upgraded: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{p}{[}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{]} \PYG{n}{master\PYGZus{}key\PYGZus{}type} \PYG{o}{=} \PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc} \PYG{n}{supported\PYGZus{}enctypes} \PYG{o}{=} \PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{des}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{des}\PYG{p}{:}\PYG{n}{v4} \PYG{n}{des}\PYG{p}{:}\PYG{n}{norealm} \PYG{n}{des}\PYG{p}{:}\PYG{n}{onlyrealm} \PYG{n}{des}\PYG{p}{:}\PYG{n}{afs3} \PYG{p}{\PYGZcb{}} \end{sphinxVerbatim} \sphinxAtStartPar This resulted in the keys for all principals in the realm being forced to DES\sphinxhyphen{}only, unless specifically requested using {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}}. \sphinxAtStartPar Before starting the upgrade, all KDCs were running krb5 1.11, and the database entries for some “high\sphinxhyphen{}value†principals were: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin.local \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZsq{}getprinc krbtgt/ZONE.MIT.EDU\PYGZsq{}} \PYG{p}{[}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{]} \PYG{n}{Number} \PYG{n}{of} \PYG{n}{keys}\PYG{p}{:} \PYG{l+m+mi}{1} \PYG{n}{Key}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc}\PYG{p}{:}\PYG{n}{v4} \PYG{p}{[}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{]} \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin.local \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZsq{}getprinc kadmin/admin\PYGZsq{}} \PYG{p}{[}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{]} \PYG{n}{Number} \PYG{n}{of} \PYG{n}{keys}\PYG{p}{:} \PYG{l+m+mi}{1} \PYG{n}{Key}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{15}\PYG{p}{,} \PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc} \PYG{p}{[}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{]} \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin.local \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZsq{}getprinc kadmin/changepw\PYGZsq{}} \PYG{p}{[}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{]} \PYG{n}{Number} \PYG{n}{of} \PYG{n}{keys}\PYG{p}{:} \PYG{l+m+mi}{1} \PYG{n}{Key}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{14}\PYG{p}{,} \PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc} \PYG{p}{[}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{]} \end{sphinxVerbatim} \sphinxAtStartPar The \sphinxcode{\sphinxupquote{krbtgt/REALM}} key appears to have never been changed since creation (its kvno is 1), and all three database entries have only a des\sphinxhyphen{}cbc\sphinxhyphen{}crc key. \subsubsection{The krbtgt key and KDC keys} \label{\detokenize{admin/advanced/retiring-des:the-krbtgt-key-and-kdc-keys}} \sphinxAtStartPar Perhaps the biggest single\sphinxhyphen{}step improvement in the security of the cell is gained by strengthening the key of the ticket\sphinxhyphen{}granting service principal, \sphinxcode{\sphinxupquote{krbtgt/REALM}}—if this principal’s key is compromised, so is the entire realm. Since the server that will handle service tickets for this principal is the KDC itself, it is easy to guarantee that it will be configured to support any encryption types which might be selected. However, the default KDC behavior when creating new keys is to remove the old keys, which would invalidate all existing tickets issued against that principal, rendering the TGTs cached by clients useless. Instead, a new key can be created with the old key retained, so that existing tickets will still function until their scheduled expiry (see {\hyperref[\detokenize{admin/database:changing-krbtgt-key}]{\sphinxcrossref{\DUrole{std,std-ref}{Changing the krbtgt key}}}}). \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} enctypes=aes256\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha1\PYGZhy{}96:normal,\PYGZbs{}} \PYG{o}{\PYGZgt{}} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96}\PYG{p}{:}\PYG{n}{normal}\PYG{p}{,}\PYG{n}{des3}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{p}{:}\PYG{n}{normal}\PYG{p}{,}\PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc}\PYG{p}{:}\PYG{n}{normal} \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin.local \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZdq{}cpw \PYGZhy{}e \PYGZdl{}\PYGZob{}enctypes\PYGZcb{} \PYGZhy{}randkey \PYGZbs{}} \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZhy{}}\PYG{n}{keepold} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{root}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Key} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{randomized}\PYG{o}{.} \end{sphinxVerbatim} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The new \sphinxcode{\sphinxupquote{krbtgt@REALM}} key should be propagated to replica KDCs immediately so that TGTs issued by the primary KDC can be used to issue service tickets on replica KDCs. Replica KDCs will refuse requests using the new TGT kvno until the new krbtgt entry has been propagated to them. \end{sphinxadmonition} \sphinxAtStartPar It is necessary to explicitly specify the enctypes for the new database entry, since \sphinxstylestrong{supported\_enctypes} has not been changed. Leaving \sphinxstylestrong{supported\_enctypes} unchanged makes a potential rollback operation easier, since all new keys of new enctypes are the result of explicit administrator action and can be easily enumerated. Upgrading the krbtgt key should have minimal user\sphinxhyphen{}visible disruption other than that described in the note above, since only clients which list the new enctypes as supported will use them, per the procedure in {\hyperref[\detokenize{admin/enctypes:session-key-selection}]{\sphinxcrossref{\DUrole{std,std-ref}{Session key selection}}}}. Once the krbtgt key is updated, the session and ticket keys for user TGTs will be strong keys, but subsequent requests for service tickets will still get DES keys until the service principals have new keys generated. Application service remains uninterrupted due to the key\sphinxhyphen{}selection procedure on the KDC. \sphinxAtStartPar After the change, the database entry is now: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin.local \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZsq{}getprinc krbtgt/ZONE.MIT.EDU\PYGZsq{}} \PYG{p}{[}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{]} \PYG{n}{Number} \PYG{n}{of} \PYG{n}{keys}\PYG{p}{:} \PYG{l+m+mi}{5} \PYG{n}{Key}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{Key}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{Key}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{des3}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1} \PYG{n}{Key}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc} \PYG{n}{Key}\PYG{p}{:} \PYG{n}{vno} \PYG{l+m+mi}{1}\PYG{p}{,} \PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc}\PYG{p}{:}\PYG{n}{v4} \PYG{p}{[}\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}\PYG{p}{]} \end{sphinxVerbatim} \sphinxAtStartPar Since the expected disruptions from rekeying the krbtgt principal are minor, after a short testing period, it is appropriate to rekey the other high\sphinxhyphen{}value principals, \sphinxcode{\sphinxupquote{kadmin/admin@REALM}} and \sphinxcode{\sphinxupquote{kadmin/changepw@REALM}}. These are the service principals used for changing user passwords and updating application keytabs. The kadmin and password\sphinxhyphen{}changing services are regular kerberized services, so the session\sphinxhyphen{}key\sphinxhyphen{}selection algorithm described in {\hyperref[\detokenize{admin/enctypes:session-key-selection}]{\sphinxcrossref{\DUrole{std,std-ref}{Session key selection}}}} applies. It is particularly important to have strong session keys for these services, since user passwords and new long\sphinxhyphen{}term keys are conveyed over the encrypted channel. \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} enctypes=aes256\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha1\PYGZhy{}96:normal,\PYGZbs{}} \PYG{o}{\PYGZgt{}} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96}\PYG{p}{:}\PYG{n}{normal}\PYG{p}{,}\PYG{n}{des3}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{p}{:}\PYG{n}{normal} \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin.local \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZdq{}cpw \PYGZhy{}e \PYGZdl{}\PYGZob{}enctypes\PYGZcb{} \PYGZhy{}randkey \PYGZbs{}} \PYG{o}{\PYGZgt{}} \PYG{n}{kadmin}\PYG{o}{/}\PYG{n}{admin}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{root}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Key} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{kadmin/admin@ZONE.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{randomized}\PYG{o}{.} \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin.local \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZdq{}cpw \PYGZhy{}e \PYGZdl{}\PYGZob{}enctypes\PYGZcb{} \PYGZhy{}randkey \PYGZbs{}} \PYG{o}{\PYGZgt{}} \PYG{n}{kadmin}\PYG{o}{/}\PYG{n}{changepw}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{root}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Key} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{kadmin/changepw@ZONE.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{randomized}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar It is not necessary to retain a single\sphinxhyphen{}DES key for these services, since password changes are not part of normal daily workflow, and disruption from a client failure is likely to be minimal. Furthermore, if a kerberos client experiences failure changing a user password or keytab key, this indicates that that client will become inoperative once services are rekeyed to non\sphinxhyphen{}DES enctypes. Such problems can be detected early at this stage, giving more time for corrective action. \subsubsection{Adding strong keys to application servers} \label{\detokenize{admin/advanced/retiring-des:adding-strong-keys-to-application-servers}} \sphinxAtStartPar Before switching the default enctypes for new keys over to strong enctypes, it may be desired to test upgrading a handful of services with the new configuration before flipping the switch for the defaults. This still requires using the \sphinxstylestrong{\sphinxhyphen{}e} argument in {\hyperref[\detokenize{admin/admin_commands/kadmin_local:kadmin-1}]{\sphinxcrossref{\DUrole{std,std-ref}{kadmin}}}} to get non\sphinxhyphen{}default enctypes: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} enctypes=aes256\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha1\PYGZhy{}96:normal,\PYGZbs{}} \PYG{o}{\PYGZgt{}} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96}\PYG{p}{:}\PYG{n}{normal}\PYG{p}{,}\PYG{n}{des3}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{p}{:}\PYG{n}{normal}\PYG{p}{,}\PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc}\PYG{p}{:}\PYG{n}{normal} \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}p zephyr/zephyr@ZONE.MIT.EDU \PYGZhy{}k \PYGZhy{}t \PYGZbs{}} \PYG{o}{\PYGZgt{}} \PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab} \PYG{o}{\PYGZhy{}}\PYG{n}{q} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ktadd \PYGZhy{}e \PYGZdl{}}\PYG{l+s+si}{\PYGZob{}enctypes\PYGZcb{}}\PYG{l+s+s2}{ }\PYG{l+s+se}{\PYGZbs{}} \PYG{l+s+s2}{\PYGZgt{} \PYGZhy{}k /etc/zephyr/krb5.keytab zephyr/zephyr@ZONE.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{zephyr}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{keytab} \PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{zephyr}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{zephyr}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{zephyr}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{des3}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{zephyr}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{4}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar Be sure to remove the old keys from the application keytab, per best practice. \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} k5srvutil \PYGZhy{}f /etc/zephyr/krb5.keytab delold} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{zephyr}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{keytab} \PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{zephyr}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3} \PYG{n}{removed} \PYG{k+kn}{from} \PYG{n+nn}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{zephyr}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \end{sphinxVerbatim} \subsubsection{Adding strong keys by default} \label{\detokenize{admin/advanced/retiring-des:adding-strong-keys-by-default}} \sphinxAtStartPar Once the high\sphinxhyphen{}visibility services have been rekeyed, it is probably appropriate to change {\hyperref[\detokenize{admin/conf_files/kdc_conf:kdc-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{kdc.conf}}}} to generate keys with the new encryption types by default. This enables server administrators to generate new enctypes with the \sphinxstylestrong{change} subcommand of {\hyperref[\detokenize{admin/admin_commands/k5srvutil:k5srvutil-1}]{\sphinxcrossref{\DUrole{std,std-ref}{k5srvutil}}}}, and causes user password changes to add new encryption types for their entries. It will probably be necessary to implement administrative controls to cause all user principal keys to be updated in a reasonable period of time, whether by forcing password changes or a password synchronization service that has access to the current password and can add the new keys. \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{supported\PYGZus{}enctypes} \PYG{o}{=} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{des3}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{des3}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{des}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{crc}\PYG{p}{:}\PYG{n}{normal} \end{sphinxVerbatim} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar The krb5kdc process must be restarted for these changes to take effect. \end{sphinxadmonition} \sphinxAtStartPar At this point, all service administrators can update their services and the servers behind them to take advantage of strong cryptography. If necessary, the server’s krb5 installation should be configured and/or upgraded to a version supporting non\sphinxhyphen{}DES keys. See {\hyperref[\detokenize{admin/enctypes:enctypes}]{\sphinxcrossref{\DUrole{std,std-ref}{Encryption types}}}} for krb5 version and configuration settings. Only when the service is configured to accept non\sphinxhyphen{}DES keys should the key version number be incremented and new keys generated (\sphinxcode{\sphinxupquote{k5srvutil change \&\& k5srvutil delold}}). \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{n}{root}\PYG{n+nd}{@dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{p}{:}\PYG{o}{\PYGZti{}}\PYG{c+c1}{\PYGZsh{} k5srvutil change} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{keytab} \PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{AES}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{256} \PYG{n}{CTS} \PYG{n}{mode} \PYG{k}{with} \PYG{l+m+mi}{96}\PYG{o}{\PYGZhy{}}\PYG{n}{bit} \PYG{n}{SHA}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1} \PYG{n}{HMAC} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{AES}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{128} \PYG{n}{CTS} \PYG{n}{mode} \PYG{k}{with} \PYG{l+m+mi}{96}\PYG{o}{\PYGZhy{}}\PYG{n}{bit} \PYG{n}{SHA}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1} \PYG{n}{HMAC} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{Triple} \PYG{n}{DES} \PYG{n}{cbc} \PYG{n}{mode} \PYG{k}{with} \PYG{n}{HMAC}\PYG{o}{/}\PYG{n}{sha1} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n}{encryption} \PYG{n+nb}{type} \PYG{n}{DES} \PYG{n}{cbc} \PYG{n}{mode} \PYG{k}{with} \PYG{n}{CRC}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{32} \PYG{n}{added} \PYG{n}{to} \PYG{n}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{root}\PYG{n+nd}{@dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{p}{:}\PYG{o}{\PYGZti{}}\PYG{c+c1}{\PYGZsh{} klist \PYGZhy{}e \PYGZhy{}k \PYGZhy{}t /etc/krb5.keytab} \PYG{n}{Keytab} \PYG{n}{name}\PYG{p}{:} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab} \PYG{n}{KVNO} \PYG{n}{Timestamp} \PYG{n}{Principal} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{2} \PYG{l+m+mi}{10}\PYG{o}{/}\PYG{l+m+mi}{10}\PYG{o}{/}\PYG{l+m+mi}{12} \PYG{l+m+mi}{17}\PYG{p}{:}\PYG{l+m+mi}{03}\PYG{p}{:}\PYG{l+m+mi}{59} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{p}{(}\PYG{n}{DES} \PYG{n}{cbc} \PYG{n}{mode} \PYG{k}{with} \PYG{n}{CRC}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{32}\PYG{p}{)} \PYG{l+m+mi}{3} \PYG{l+m+mi}{12}\PYG{o}{/}\PYG{l+m+mi}{12}\PYG{o}{/}\PYG{l+m+mi}{12} \PYG{l+m+mi}{15}\PYG{p}{:}\PYG{l+m+mi}{31}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{p}{(}\PYG{n}{AES}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{256} \PYG{n}{CTS} \PYG{n}{mode} \PYG{k}{with} \PYG{l+m+mi}{96}\PYG{o}{\PYGZhy{}}\PYG{n}{bit} \PYG{n}{SHA}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1} \PYG{n}{HMAC}\PYG{p}{)} \PYG{l+m+mi}{3} \PYG{l+m+mi}{12}\PYG{o}{/}\PYG{l+m+mi}{12}\PYG{o}{/}\PYG{l+m+mi}{12} \PYG{l+m+mi}{15}\PYG{p}{:}\PYG{l+m+mi}{31}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{p}{(}\PYG{n}{AES}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{128} \PYG{n}{CTS} \PYG{n}{mode} \PYG{k}{with} \PYG{l+m+mi}{96}\PYG{o}{\PYGZhy{}}\PYG{n}{bit} \PYG{n}{SHA}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1} \PYG{n}{HMAC}\PYG{p}{)} \PYG{l+m+mi}{3} \PYG{l+m+mi}{12}\PYG{o}{/}\PYG{l+m+mi}{12}\PYG{o}{/}\PYG{l+m+mi}{12} \PYG{l+m+mi}{15}\PYG{p}{:}\PYG{l+m+mi}{31}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{p}{(}\PYG{n}{Triple} \PYG{n}{DES} \PYG{n}{cbc} \PYG{n}{mode} \PYG{k}{with} \PYG{n}{HMAC}\PYG{o}{/}\PYG{n}{sha1}\PYG{p}{)} \PYG{l+m+mi}{3} \PYG{l+m+mi}{12}\PYG{o}{/}\PYG{l+m+mi}{12}\PYG{o}{/}\PYG{l+m+mi}{12} \PYG{l+m+mi}{15}\PYG{p}{:}\PYG{l+m+mi}{31}\PYG{p}{:}\PYG{l+m+mi}{19} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{p}{(}\PYG{n}{DES} \PYG{n}{cbc} \PYG{n}{mode} \PYG{k}{with} \PYG{n}{CRC}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{32}\PYG{p}{)} \PYG{n}{root}\PYG{n+nd}{@dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{p}{:}\PYG{o}{\PYGZti{}}\PYG{c+c1}{\PYGZsh{} k5srvutil delold} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{keytab} \PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \PYG{n}{Entry} \PYG{k}{for} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{dr}\PYG{o}{\PYGZhy{}}\PYG{n}{willy}\PYG{o}{.}\PYG{n}{xvm}\PYG{o}{.}\PYG{n}{mit}\PYG{o}{.}\PYG{n}{edu}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{kvno} \PYG{l+m+mi}{2} \PYG{n}{removed} \PYG{k+kn}{from} \PYG{n+nn}{keytab} \PYG{n}{WRFILE}\PYG{p}{:}\PYG{o}{/}\PYG{n}{etc}\PYG{o}{/}\PYG{n}{krb5}\PYG{o}{.}\PYG{n}{keytab}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar When a single service principal is shared by multiple backend servers in a load\sphinxhyphen{}balanced environment, it may be necessary to schedule downtime or adjust the population in the load\sphinxhyphen{}balanced pool in order to propagate the updated keytab to all hosts in the pool with minimal service interruption. \subsubsection{Removing DES keys from usage} \label{\detokenize{admin/advanced/retiring-des:removing-des-keys-from-usage}} \sphinxAtStartPar This situation remains something of a testing or transitory state, as new DES keys are still being generated, and will be used if requested by a client. To make more progress removing DES from the realm, the KDC should be configured to not generate such keys by default. \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar An attacker posing as a client can implement a brute force attack against a DES key for any principal, if that key is in the current (highest\sphinxhyphen{}kvno) key list. This attack is only possible if \sphinxstylestrong{allow\_weak\_crypto = true} is enabled on the KDC. Setting the \sphinxstylestrong{+requires\_preauth} flag on a principal forces this attack to be an online attack, much slower than the offline attack otherwise available to the attacker. However, setting this flag on a service principal is not always advisable; see the entry in {\hyperref[\detokenize{admin/admin_commands/kadmin_local:add-principal}]{\sphinxcrossref{\DUrole{std,std-ref}{add\_principal}}}} for details. \end{sphinxadmonition} \sphinxAtStartPar The following KDC configuration will not generate DES keys by default: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{realms}\PYG{p}{]} \PYG{n}{ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{o}{=} \PYG{p}{\PYGZob{}} \PYG{n}{supported\PYGZus{}enctypes} \PYG{o}{=} \PYG{n}{aes256}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{aes128}\PYG{o}{\PYGZhy{}}\PYG{n}{cts}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{96}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{des3}\PYG{o}{\PYGZhy{}}\PYG{n}{cbc}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{p}{:}\PYG{n}{normal} \PYG{n}{des3}\PYG{o}{\PYGZhy{}}\PYG{n}{hmac}\PYG{o}{\PYGZhy{}}\PYG{n}{sha1}\PYG{p}{:}\PYG{n}{normal} \end{sphinxVerbatim} \begin{sphinxadmonition}{note}{Note:} \sphinxAtStartPar As before, the KDC process must be restarted for this change to take effect. It is best practice to update kdc.conf on all KDCs, not just the primary, to avoid unpleasant surprises should the primary fail and a replica need to be promoted. \end{sphinxadmonition} \sphinxAtStartPar It is now appropriate to remove the legacy single\sphinxhyphen{}DES key from the \sphinxcode{\sphinxupquote{krbtgt/REALM}} entry: \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin.local \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZdq{}cpw \PYGZhy{}randkey \PYGZhy{}keepold \PYGZbs{}} \PYG{o}{\PYGZgt{}} \PYG{n}{krbtgt}\PYG{o}{/}\PYG{n}{ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{host}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ATHENA}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Key} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{randomized}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar After the maximum ticket lifetime has passed, the old database entry should be removed. \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{p}{[}\PYG{n}{root}\PYG{n+nd}{@casio} \PYG{n}{krb5kdc}\PYG{p}{]}\PYG{c+c1}{\PYGZsh{} kadmin.local \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZsq{}purgekeys krbtgt/ZONE.MIT.EDU\PYGZsq{}} \PYG{n}{Authenticating} \PYG{k}{as} \PYG{n}{principal} \PYG{n}{root}\PYG{o}{/}\PYG{n}{admin}\PYG{n+nd}{@ZONE}\PYG{o}{.}\PYG{n}{MIT}\PYG{o}{.}\PYG{n}{EDU} \PYG{k}{with} \PYG{n}{password}\PYG{o}{.} \PYG{n}{Old} \PYG{n}{keys} \PYG{k}{for} \PYG{n}{principal} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{purged}\PYG{o}{.} \end{sphinxVerbatim} \sphinxAtStartPar After the KDC is restarted with the new \sphinxstylestrong{supported\_enctypes}, all user password changes and application keytab updates will not generate DES keys by default. \begin{sphinxVerbatim}[commandchars=\\\{\}] contents\PYGZhy{}vnder\PYGZhy{}pressvre:\PYGZti{}\PYGZgt{} kpasswd zonetest@ZONE.MIT.EDU Password for zonetest@ZONE.MIT.EDU: [enter old password] Enter new password: [enter new password] Enter it again: [enter new password] Password changed. contents\PYGZhy{}vnder\PYGZhy{}pressvre:\PYGZti{}\PYGZgt{} kadmin \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}q \PYGZsq{}getprinc zonetest\PYGZsq{} [...] Number of keys: 3 Key: vno 9, aes256\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha1\PYGZhy{}96 Key: vno 9, aes128\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha1\PYGZhy{}96 Key: vno 9, des3\PYGZhy{}cbc\PYGZhy{}sha1 [...] [kaduk@glossolalia \PYGZti{}]\PYGZdl{} kadmin \PYGZhy{}p kaduk@ZONE.MIT.EDU \PYGZhy{}r ZONE.MIT.EDU \PYGZhy{}k \PYGZbs{} \PYGZgt{} \PYGZhy{}t kaduk\PYGZhy{}zone.keytab \PYGZhy{}q \PYGZsq{}ktadd \PYGZhy{}k kaduk\PYGZhy{}zone.keytab kaduk@ZONE.MIT.EDU\PYGZsq{} Authenticating as principal kaduk@ZONE.MIT.EDU with keytab kaduk\PYGZhy{}zone.keytab. Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type aes256\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha1\PYGZhy{}96 added to keytab WRFILE:kaduk\PYGZhy{}zone.keytab. Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type aes128\PYGZhy{}cts\PYGZhy{}hmac\PYGZhy{}sha1\PYGZhy{}96 added to keytab WRFILE:kaduk\PYGZhy{}zone.keytab. Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type des3\PYGZhy{}cbc\PYGZhy{}sha1 added to keytab WRFILE:kaduk\PYGZhy{}zone.keytab. \end{sphinxVerbatim} \sphinxAtStartPar Once all principals have been re\sphinxhyphen{}keyed, DES support can be disabled on the KDC (\sphinxstylestrong{allow\_weak\_crypto = false}), and client machines can remove \sphinxstylestrong{allow\_weak\_crypto = true} from their {\hyperref[\detokenize{admin/conf_files/krb5_conf:krb5-conf-5}]{\sphinxcrossref{\DUrole{std,std-ref}{krb5.conf}}}} configuration files, completing the migration. \sphinxstylestrong{allow\_weak\_crypto} takes precedence over all places where DES enctypes could be explicitly configured. DES keys will not be used, even if they are present, when \sphinxstylestrong{allow\_weak\_crypto = false}. \subsubsection{Support for legacy services} \label{\detokenize{admin/advanced/retiring-des:support-for-legacy-services}} \sphinxAtStartPar If there remain legacy services which do not support non\sphinxhyphen{}DES enctypes (such as older versions of AFS), \sphinxstylestrong{allow\_weak\_crypto} must remain enabled on the KDC. Client machines need not have this setting, though—applications which require DES can use API calls to allow weak crypto on a per\sphinxhyphen{}request basis, overriding the system krb5.conf. However, having \sphinxstylestrong{allow\_weak\_crypto} set on the KDC means that any principals which have a DES key in the database could still use those keys. To minimize the use of DES in the realm and restrict it to just legacy services which require DES, it is necessary to remove all other DES keys. The realm has been configured such that at password and keytab change, no DES keys will be generated by default. The task then reduces to requiring user password changes and having server administrators update their service keytabs. Administrative outreach will be necessary, and if the desire to eliminate DES is sufficiently strong, the KDC administrators may choose to randkey any principals which have not been rekeyed after some timeout period, forcing the user to contact the helpdesk for access. \subsection{The Database Master Key} \label{\detokenize{admin/advanced/retiring-des:the-database-master-key}} \sphinxAtStartPar This procedure does not alter \sphinxcode{\sphinxupquote{K/M@REALM}}, the key used to encrypt key material in the Kerberos database. (This is the key stored in the stash file on the KDC if stash files are used.) However, the security risk of a single\sphinxhyphen{}DES key for \sphinxcode{\sphinxupquote{K/M}} is minimal, given that access to material encrypted in \sphinxcode{\sphinxupquote{K/M}} (the Kerberos database) is generally tightly controlled. If an attacker can gain access to the encrypted database, they likely have access to the stash file as well, rendering the weak cryptography broken by non\sphinxhyphen{}cryptographic means. As such, upgrading \sphinxcode{\sphinxupquote{K/M}} to a stronger encryption type is unlikely to be a high\sphinxhyphen{}priority task. \sphinxAtStartPar Is is possible to upgrade the master key used for the database, if desired. Using {\hyperref[\detokenize{admin/admin_commands/kdb5_util:kdb5-util-8}]{\sphinxcrossref{\DUrole{std,std-ref}{kdb5\_util}}}}’s \sphinxstylestrong{add\_mkey}, \sphinxstylestrong{use\_mkey}, and \sphinxstylestrong{update\_princ\_encryption} commands, a new master key can be added and activated for use on new key material, and the existing entries converted to the new master key. \sphinxstepscope \chapter{Various links} \label{\detokenize{admin/various_envs:various-links}}\label{\detokenize{admin/various_envs::doc}} \section{Whitepapers} \label{\detokenize{admin/various_envs:whitepapers}}\begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar \sphinxurl{https://kerberos.org/software/whitepapers.html} \end{enumerate} \section{Tutorials} \label{\detokenize{admin/various_envs:tutorials}}\begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar Fulvio Ricciardi \textless{}\sphinxurl{https://www.kerberos.org/software/tutorial.html}\textgreater{}\_ \end{enumerate} \section{Troubleshooting} \label{\detokenize{admin/various_envs:troubleshooting}}\begin{enumerate} \sphinxsetlistlabels{\arabic}{enumi}{enumii}{}{.}% \item {} \sphinxAtStartPar \sphinxurl{https://wiki.ncsa.illinois.edu/display/ITS/Windows+Kerberos+Troubleshooting} \item {} \sphinxAtStartPar \sphinxurl{https://www.shrubbery.net/solaris9ab/SUNWaadm/SYSADV6/p27.html} \item {} \sphinxAtStartPar \sphinxurl{https://docs.oracle.com/cd/E19253-01/816-4557/trouble-1/index.html} \item {} \sphinxAtStartPar \sphinxurl{https://docs.microsoft.com/en-us/previous-versions/tn-archive/bb463167(v=technet.10})\#EBAA \item {} \sphinxAtStartPar \sphinxurl{https://bugs.launchpad.net/ubuntu/+source/libpam-heimdal/+bug/86528} \end{enumerate} \renewcommand{\indexname}{Index} \printindex \end{document}krb5-1.22.1/doc/pdf/latexmkjarc0000664000175000017500000000125415051422730016111 0ustar ghudsonghudson$latex = 'pdflatex ' . $ENV{'LATEXOPTS'} . ' -kanji=utf8 %O %S'; $dvipdf = 'dvipdfmx %O -o %D %S'; $makeindex = 'internal mendex %S %B %D'; sub mendex { my ($source, $basename, $destination) = @_; my $dictfile = $basename . ".dic"; unlink($destination); system("mendex", "-U", "-f", "-d", $dictfile, "-s", "python.ist", $source); if ($? > 0) { print("mendex exited with error code $? (ignored)\n"); } if (!-e $destination) { # create an empty .ind file if nothing open(FH, ">" . $destination); close(FH); } return 0; } add_cus_dep( "glo", "gls", 0, "makeglo" ); sub makeglo { return system( "mendex -J -f -s gglo.ist -o '$_[0].gls' '$_[0].glo'" ); }krb5-1.22.1/doc/pdf/sphinxlatexstyletext.sty0000664000175000017500000002061514577122106020767 0ustar ghudsonghudson%% TEXT STYLING % % change this info string if making any custom modification \ProvidesFile{sphinxlatexstyletext.sty}[2023/07/23 text styling] % Basically everything here consists of macros which are part of the latex % markup produced by the Sphinx latex writer % But those arise rather from the default definitions of the respective % latex environments done in sphinxlatexadmonitions.sty \def\sphinxstylenotetitle #1{\sphinxstrong{#1} } \let\sphinxstylehinttitle \sphinxstylenotetitle % #1 holds the localized notice name \let\sphinxstyleimportanttitle\sphinxstylenotetitle % followed by a colon \let\sphinxstyletiptitle \sphinxstylenotetitle \let\sphinxstylewarningtitle \sphinxstylenotetitle \let\sphinxstylecautiontitle \sphinxstylenotetitle \let\sphinxstyleattentiontitle\sphinxstylenotetitle \let\sphinxstyledangertitle \sphinxstylenotetitle \let\sphinxstyleerrortitle \sphinxstylenotetitle \def\sphinxstyleseealsotitle#1{\sphinxstrong{#1}\par\nopagebreak} % % A utility to remove a final colon. Removing last token is not easy in % LaTeX, and there are additional complications: % - some languages will make the : "active" in document body, % - the generic admonition ends up using "note", so for \sphinxnotetitle to % use it safely, the utility has to allow an input not having any final colon. % - a bit far-fetched but maybe there is more than one colon inside the input % (possible from a generic admonition title). % Hence the scary code. \def\sphinxremovefinalcolon#1{% #1 is the "active" : TeX token \protected\def\sphinxremovefinalcolon ##1{% % complications due to : possibly "active" \begingroup\ifnum\catcode`:=\active \def\x####1#1\relax{####1}% \else\def\x####1:\relax{####1}\fi \expandafter\endgroup\x##1\relax % trick to let \x work also if input ##1 has no ending colon \@gobblefour#1\relax:\relax\relax\relax }% }% end of wrapper to inject active : \begingroup\catcode`:\active\expandafter\endgroup\sphinxremovefinalcolon: % See doc/latex.rst for an example. % Some custom font markup commands. \protected\def\sphinxstrong#1{\textbf{#1}} \protected\def\sphinxcode#1{\texttt{#1}} \protected\def\sphinxbfcode#1{\textbf{\sphinxcode{#1}}} \protected\def\sphinxemail#1{\textsf{#1}} \protected\def\sphinxtablecontinued#1{\textsf{#1}} \protected\def\sphinxtitleref#1{\emph{#1}} \protected\def\sphinxmenuselection#1{\emph{#1}} \protected\def\sphinxguilabel#1{\emph{#1}} \protected\def\sphinxkeyboard#1{\sphinxcode{#1}} \protected\def\sphinxaccelerator#1{\underline{#1}} \protected\def\sphinxcrossref#1{\emph{#1}} \protected\def\sphinxtermref#1{\emph{#1}} \protected\def\sphinxsamedocref#1{\emph{#1}} \protected\def\sphinxparam#1{\emph{#1}} \protected\def\sphinxtypeparam#1{\emph{#1}} % \optional is used for ``[, arg]``, i.e. desc_optional nodes. \long\protected\def\sphinxoptional#1{% {\sphinxoptionalhook\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}} \let\sphinxoptionalhook\empty % additional customizable styling \def\sphinxstyleindexentry #1{\texttt{#1}} \def\sphinxstyleindexextra #1{ (\emph{#1})} \def\sphinxstyleindexpageref #1{, \pageref{#1}} \def\sphinxstyleindexpagemain#1{\textbf{#1}} \def\spxentry{\@backslashchar spxentry}% let to \sphinxstyleindexentry in index \def\spxextra{\@backslashchar spxextra}% let to \sphinxstyleindexextra in index \def\sphinxstyleindexlettergroup #1% {{\Large\sffamily#1}\nopagebreak\vspace{1mm}} \def\sphinxstyleindexlettergroupDefault #1% {{\Large\sffamily\sphinxnonalphabeticalgroupname}\nopagebreak\vspace{1mm}} \protected\def\sphinxstyletopictitle #1{\textbf{#1}\par\medskip} \let\sphinxstylesidebartitle\sphinxstyletopictitle \protected\def\sphinxstyleothertitle #1{\textbf{#1}} \protected\def\sphinxstylesidebarsubtitle #1{~\\\textbf{#1} \smallskip} % \text.. commands do not allow multiple paragraphs % attention, this one is not self-delimiting \protected\def\sphinxstyletheadfamily {\sffamily} \protected\def\sphinxstyleemphasis #1{\emph{#1}} \protected\def\sphinxstyleliteralemphasis#1{\emph{\sphinxcode{#1}}} \protected\def\sphinxstylestrong #1{\textbf{#1}} \protected\def\sphinxstyleliteralstrong#1{\sphinxbfcode{#1}} \protected\def\sphinxstyleabbreviation #1{\textsc{#1}} \protected\def\sphinxstyleliteralintitle#1{\sphinxcode{#1}} \newcommand*\sphinxstylecodecontinued[1]{{\footnotesize(#1)}}% \newcommand*\sphinxstylecodecontinues[1]{{\footnotesize(#1)}}% % figure legend comes after caption and may contain arbitrary body elements \newenvironment{sphinxlegend}{\par\small}{\par} % reduce hyperref "Token not allowed in a PDF string" warnings on PDF builds \AtBeginDocument{\pdfstringdefDisableCommands{% % all "protected" macros possibly ending up in section titles should be here % TODO: examine if \sphinxhref, \sphinxurl, \sphinnolinkurl should be handled \let\sphinxstyleemphasis \@firstofone \let\sphinxstyleliteralemphasis \@firstofone \let\sphinxstylestrong \@firstofone \let\sphinxstyleliteralstrong \@firstofone \let\sphinxstyleabbreviation \@firstofone \let\sphinxstyleliteralintitle \@firstofone \let\sphinxupquote \@firstofone \let\sphinxstrong \@firstofone \let\sphinxcode \@firstofone \let\sphinxbfcode \@firstofone \let\sphinxemail \@firstofone \let\sphinxcrossref \@firstofone \let\sphinxtermref \@firstofone \let\sphinxsamedocref\@firstofone \let\sphinxhyphen\sphinxhyphenforbookmarks \def\PYG#1#2{#2}% (can not yet appear in section titles, but perhaps in future) }} % Special characters % \def\sphinxparamcomma{, }% by default separate parameters with comma + space % If the signature is rendered with one line per param, this wil be used % instead (this \texttt makes the comma slightly more distinctive). \def\sphinxparamcommaoneperline{\texttt{,}} % % The \kern\z@ is to prevent en-dash and em-dash TeX ligatures. % A linebreak can occur after the dash in regular text (this is % normal behaviour of "-" in TeX, it is not related to \kern\z@). % % Parsed-literals and inline literals also use the \sphinxhyphen % but linebreaks there are prevented due to monospace font family. % (xelatex needs a special addition, cf. sphinxlatexliterals.sty) % % Inside code-blocks, dashes are escaped via another macro, from % Pygments latex output (search for \PYGZhy in sphinxlatexliterals.sty), % and are configured to allow linebreaks despite the monospace font. % (the #1 swallows the {} from \sphinxhyphen{} mark-up) \protected\def\sphinxhyphen#1{-\kern\z@} \protected\def\sphinxhyphennobreak#1{\mbox{-}} % The {} from texescape mark-up is kept, else -- gives en-dash in PDF bookmark \def\sphinxhyphenforbookmarks{-} % For curly braces inside \index macro \def\sphinxleftcurlybrace{\{} \def\sphinxrightcurlybrace{\}} % Declare Unicode characters used by linux tree command to pdflatex utf8/utf8x \def\spx@bd#1#2{% \leavevmode \begingroup \ifx\spx@bd@height \@undefined\def\spx@bd@height{\baselineskip}\fi \ifx\spx@bd@width \@undefined\setbox0\hbox{0}\def\spx@bd@width{\wd0 }\fi \ifx\spx@bd@thickness\@undefined\def\spx@bd@thickness{.6\p@}\fi \ifx\spx@bd@lower \@undefined\def\spx@bd@lower{\dp\strutbox}\fi \lower\spx@bd@lower#1{#2}% \endgroup }% \@namedef{sphinx@u2500}% BOX DRAWINGS LIGHT HORIZONTAL {\spx@bd{\vbox to\spx@bd@height} {\vss\hrule\@height\spx@bd@thickness \@width\spx@bd@width\vss}}% \@namedef{sphinx@u2502}% BOX DRAWINGS LIGHT VERTICAL {\spx@bd{\hb@xt@\spx@bd@width} {\hss\vrule\@height\spx@bd@height \@width \spx@bd@thickness\hss}}% \@namedef{sphinx@u2514}% BOX DRAWINGS LIGHT UP AND RIGHT {\spx@bd{\hb@xt@\spx@bd@width} {\hss\raise.5\spx@bd@height \hb@xt@\z@{\hss\vrule\@height.5\spx@bd@height \@width \spx@bd@thickness\hss}% \vbox to\spx@bd@height{\vss\hrule\@height\spx@bd@thickness \@width.5\spx@bd@width\vss}}}% \@namedef{sphinx@u251C}% BOX DRAWINGS LIGHT VERTICAL AND RIGHT {\spx@bd{\hb@xt@\spx@bd@width} {\hss \hb@xt@\z@{\hss\vrule\@height\spx@bd@height \@width \spx@bd@thickness\hss}% \vbox to\spx@bd@height{\vss\hrule\@height\spx@bd@thickness \@width.5\spx@bd@width\vss}}}% \protected\def\sphinxunichar#1{\@nameuse{sphinx@u#1}}% % Tell TeX about pathological hyphenation cases: \hyphenation{Base-HTTP-Re-quest-Hand-ler} \endinput krb5-1.22.1/doc/pdf/sphinx.sty0000664000175000017500000012702014577122106015741 0ustar ghudsonghudson% % sphinx.sty % % Adapted from the old python.sty, mostly written by Fred Drake, % by Georg Brandl. % \NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesPackage{sphinx}[2023/03/19 v6.2.0 LaTeX package (Sphinx markup)] % provides \ltx@ifundefined % (many packages load ltxcmds: graphicx does for pdftex and lualatex but % not xelatex, and anyhow kvoptions does, but it may be needed in future to % use \sphinxdeprecationwarning earlier, and it needs \ltx@ifundefined) \RequirePackage{ltxcmds} %% for deprecation warnings \newcommand\sphinxdeprecationwarning[4]{% #1 the deprecated macro or name, % #2 = when deprecated, #3 = when removed, #4 = additional info {% limit scope of \spx@tempa, \AtEndDocument works even if nested. \edef\spx@tempa{\detokenize{#1}}% \ltx@ifundefined{sphinx_depr_\spx@tempa}{% \global\expandafter\let\csname sphinx_depr_\spx@tempa\endcsname\spx@tempa \expandafter\AtEndDocument\expandafter{\expandafter\let\expandafter \sphinxdeprecatedmacro\csname sphinx_depr_\spx@tempa\endcsname \PackageWarningNoLine{sphinx}{^^J**** SPHINX DEPRECATION WARNING:^^J \sphinxdeprecatedmacro^^J \@spaces- is deprecated at Sphinx #2^^J \@spaces- and removed at Sphinx #3.^^J #4^^J****}}% }{% warning already emitted (at end of latex log), don't repeat }% }% end of scope limiting group for \spx@tempa } %% important build warnings use an undefined reference to induce latexmk %% into complaining (once per warning) at very end of console output \newcommand\sphinxbuildwarning[1]{% \ifcsname sphinx_emitted_#1\endcsname \else \global\expandafter\let\csname sphinx_emitted_#1\endcsname\@empty \AtEndDocument{\hbox{% should the printing of text be made conditional on % some boolean? \bfseries\color{red}% \@nameuse{sphinx_buildwarning_#1}% % place an undefined reference deliberately \let\nfss@text\@gobble % no ?? \ref{!!\@nameuse{sphinx_buildwarning_#1}}% }}% \fi } \@namedef{sphinx_buildwarning_coloursyntax}{% The colours whose definition used xcolor syntax were set to white as xcolor was not found; check the latex log warnings for details} \@namedef{sphinx_buildwarning_colorblend}{% Command \string\sphinxcolorblend\space seen but ignored in tables as xcolor was not found; check the latex log warnings for details} \@namedef{sphinx_buildwarning_badtitlesec}{% Your system has titlesec version 2.10.1 which causes disappearance of section numbers; check the latex log warning for details} \@namedef{sphinx_buildwarning_booktabs}{% Some tables with booktabs class (check latex log) but booktabs package not loaded; add its loading to the latex preamble}% \@namedef{sphinx_buildwarning_badfootnotes}{% Footnote rendering may have had problems, due to extra package or document class; check latex log for instructions}% %% OPTION HANDLING % % We generally first handle options then load packages, but we need % \definecolor from xcolor/color to handle the options. % MEMO: xcolor \fcolorbox coloured boxes render better in some PDF viewers % than with color package \fcolorbox. Since 1.6.3, Sphinx uses only its own % custom variant of \fcolorbox when handling code-blocks. But \fcolorbox % appears also in Pygmentize output mark-up. Also, since 5.3.0, 'sphinxsetup' % color options get a richer input syntax if Sphinx knows xcolor is loaded, % and the \sphinxcolorblend (for tables) is made available only if xcolor is % loaded. \IfFileExists{xcolor.sty}{ % Should Sphinx load xcolor with its dvipsnames and svgnames options? \RequirePackage{xcolor} }{ \RequirePackage{color} } % the \colorlet of xcolor (if at all loaded) is overkill for most internal use \newcommand{\sphinxcolorlet}[2] {\expandafter\let\csname\@backslashchar color@#1\expandafter\endcsname \csname\@backslashchar color@#2\endcsname } % (5.3.0) Allow colour options to use both the \definecolor and the \colorlet % syntaxes, for example VerbatimColor={gray}{0.9} or VerbatimColor=red!10 % In the latter case we need the real \colorlet from xcolor package. \def\spx@defineorletcolor#1{% \def\spx@definedcolor{{#1}}% \futurelet\spx@token\spx@defineorlet} \def\spx@defineorlet{% \ifx\spx@token\bgroup \expandafter\spx@definecolor\else\expandafter\spx@colorlet\fi} \def\spx@colorlet#1\relax{\expandafter\colorlet\spx@definedcolor{#1}} \def\spx@definecolor{\expandafter\definecolor\spx@definedcolor} % \@ifpackageloaded{xcolor}% {}% {% xcolor not loaded because it was not found in the LaTeX installation \def\spx@colorlet#1\relax{% \sphinxbuildwarning{coloursyntax}% \PackageWarning{sphinx}{% Sorry, the #1 syntax requires package xcolor,\MessageBreak which was not found on your TeX/LaTeX installation.\MessageBreak \@spaces\expandafter\@firstofone\spx@definedcolor\MessageBreak will be set to white}% \expandafter\definecolor\spx@definedcolor{rgb}{1,1,1}% }% end of redefinition of \spx@colorlet }% end of xcolor not found branch % Handle options via "kvoptions" (later loaded by hyperref anyhow) \RequirePackage{kvoptions} \SetupKeyvalOptions{prefix=spx@opt@} % use \spx@opt@ prefix % Optional usage of booktabs package for tables \DeclareBoolOption[false]{booktabs} \DeclareBoolOption[false]{borderless} \DeclareBoolOption[true]{booktabscolorgaps} \DeclareVoidOption{booktabsnogaps}{% \ifx\@nodocument\relax % in body \expandafter\@firstofone \else % in preamble, wait for at begin document \expandafter\AtBeginDocument \fi {\ifdefined\abovetopsep % silently do nothing if booktabs not loaded \abovetopsep\z@\belowrulesep\z@\aboverulesep\z@\belowbottomsep\z@ \fi }% } % Coloured table rows \DeclareBoolOption[false]{colorrows} % Sphinx legacy text layout: 1in margins on all four sides \ifx\@jsc@uplatextrue\@undefined \DeclareStringOption[1in]{hmargin} \DeclareStringOption[1in]{vmargin} \DeclareStringOption[.5in]{marginpar} \else % Japanese standard document classes handle \mag in a special way \DeclareStringOption[\inv@mag in]{hmargin} \DeclareStringOption[\inv@mag in]{vmargin} \DeclareStringOption[.5\dimexpr\inv@mag in\relax]{marginpar} \fi \DeclareStringOption[0]{maxlistdepth}% \newcommand*\spx@opt@maxlistdepth{0} \DeclareStringOption[-1]{numfigreset} \DeclareBoolOption[false]{nonumfigreset} \DeclareBoolOption[false]{mathnumfig} \define@key{sphinx}{bookmarksdepth}{\AtBeginDocument{\hypersetup{bookmarksdepth=#1}}} \AtBeginDocument{\define@key{sphinx}{bookmarksdepth}{\hypersetup{bookmarksdepth=#1}}} % \DeclareBoolOption[false]{usespart}% not used % INFO: the keys for padding and border widths were extended at 5.1.0, % and legacy names for user interface were kept, but their definitions % are delayed further down. The legacy internally used dimen registers % \sphinxverbatimborder and \sphinxverbatimsep got removed at 6.2.0. \DeclareBoolOption[true]{verbatimwithframe} \DeclareBoolOption[true]{verbatimwrapslines} \DeclareBoolOption[false]{verbatimforcewraps} \DeclareStringOption[3]{verbatimmaxoverfull} \DeclareStringOption[100]{verbatimmaxunderfull} \DeclareBoolOption[true]{verbatimhintsturnover} \DeclareBoolOption[true]{inlineliteralwraps} \DeclareStringOption[t]{literalblockcappos} \DeclareStringOption[r]{verbatimcontinuedalign} \DeclareStringOption[r]{verbatimcontinuesalign} % parsed literal \DeclareBoolOption[true]{parsedliteralwraps} % \textvisiblespace for compatibility with fontspec+XeTeX/LuaTeX \DeclareStringOption[\textcolor{red}{\textvisiblespace}]{verbatimvisiblespace} \DeclareStringOption % must use braces to hide the brackets [{\makebox[2\fontcharwd\font`\x][r]{\textcolor{red}{\tiny$\m@th\hookrightarrow$}}}]% {verbatimcontinued} % topic boxes % % 5.1.0 added new keys for configuration. The legacy keys shadowsep, % shadowsize, shadowrule were kept for backward compatibility. Unfortunately % this had bugs due to typos, which got fixed later at 6.1.2. % % All configuration is now to be found in the "CSS" section below. % % \sphinxshadowsep, \sphinxshadowsize, \sphinxshadowrule \dimen registers % became at 5.1.0 either no-op or, for the latter, were used under an aliased % name. They got removed at 6.2.0. % % notices/admonitions % % 5.1.0 added much customizability to warning, caution, attention, danger and % error types of notices via an enhanced sphinxheavybox environment. % % 6.2.0 added the possibility to use the same kind of rendering also for % note, hint, important, and tip. % % Legacy user interface for options was kept working. All of it is handled in % the "CSS" section below. % % These 6.2.0 added booleans serve internally. There is no reason for user to % know about them, except if it is desired to toggle mid-way in the document % whether note, hint, important, and tip should use the "lightbox" or the % "heavybox" rendering. \DeclareBoolOption[false]{heavynote} \DeclareBoolOption[false]{heavyhint} \DeclareBoolOption[false]{heavyimportant} \DeclareBoolOption[false]{heavytip} % footnotes \DeclareStringOption[\mbox{ }]{AtStartFootnote} % we need a public macro name for direct use in latex file \newcommand*{\sphinxAtStartFootnote}{\spx@opt@AtStartFootnote} % no such need for this one, as it is used inside other macros \DeclareStringOption[\leavevmode\unskip]{BeforeFootnote} % some font styling. \DeclareStringOption[\sffamily\bfseries]{HeaderFamily} % colours % same problems as for dimensions: we want the key handler to use \definecolor. % first, some colours with no prefix, for backward compatibility \newcommand*{\sphinxDeclareColorOption}[2]{% % set the initial default; only \definecolor syntax for defaults! \definecolor{#1}#2% % set the key handler to accept both \definecolor and \colorlet syntax \define@key{sphinx}{#1}{\spx@defineorletcolor{#1}##1\relax}% }% \sphinxDeclareColorOption{TitleColor}{{rgb}{0.126,0.263,0.361}} \sphinxDeclareColorOption{InnerLinkColor}{{rgb}{0.208,0.374,0.486}} \sphinxDeclareColorOption{OuterLinkColor}{{rgb}{0.216,0.439,0.388}} \sphinxDeclareColorOption{VerbatimColor}{{gray}{0.95}} \sphinxDeclareColorOption{VerbatimBorderColor}{{RGB}{32,32,32}} % all other colours will be named with a "sphinx" prefix \newcommand*{\sphinxDeclareSphinxColorOption}[2]{% % set the initial default; only \definecolor syntax for defaults! \definecolor{sphinx#1}#2% % set the key handler to accept both \definecolor and \colorlet syntax \define@key{sphinx}{#1}{\spx@defineorletcolor{sphinx#1}##1\relax}% }% % table row colors \sphinxDeclareSphinxColorOption{TableRowColorHeader}{{gray}{0.86}} \sphinxDeclareSphinxColorOption{TableRowColorOdd}{{gray}{0.92}} \sphinxDeclareSphinxColorOption{TableRowColorEven}{{gray}{0.98}} % if not set, the "Merge" colour will keep in sync with the "Row" colour \def\sphinxTableMergeColorHeader{sphinxTableRowColorHeader} \define@key{sphinx}{TableMergeColorHeader}{% \spx@defineorletcolor{sphinxTableMergeColorHeader}#1\relax \def\sphinxTableMergeColorHeader{sphinxTableMergeColorHeader}% }% \def\sphinxTableMergeColorOdd{sphinxTableRowColorOdd} \define@key{sphinx}{TableMergeColorOdd}{% \spx@defineorletcolor{sphinxTableMergeColorOdd}#1\relax \def\sphinxTableMergeColorOdd{sphinxTableMergeColorOdd}% }% \def\sphinxTableMergeColorEven{sphinxTableRowColorEven} \define@key{sphinx}{TableMergeColorEven}{% \spx@defineorletcolor{sphinxTableMergeColorEven}#1\relax \def\sphinxTableMergeColorEven{sphinxTableMergeColorEven}% }% % Default color chosen to be as in minted.sty LaTeX package! \sphinxDeclareSphinxColorOption{VerbatimHighlightColor}{{rgb}{0.878,1,1}} % admonition boxes, "light" style % border color defaults to black % at 6.2.0 also background color is possible, but it then triggers % usage of the "sphinxheavybox" from sphinxlatexadmonitions.sty. \sphinxDeclareSphinxColorOption{noteBorderColor}{{rgb}{0,0,0}} \sphinxDeclareSphinxColorOption{hintBorderColor}{{rgb}{0,0,0}} \sphinxDeclareSphinxColorOption{importantBorderColor}{{rgb}{0,0,0}} \sphinxDeclareSphinxColorOption{tipBorderColor}{{rgb}{0,0,0}} \sphinxDeclareSphinxColorOption{noteBgColor}{{rgb}{1,1,1}} \sphinxDeclareSphinxColorOption{hintBgColor}{{rgb}{1,1,1}} \sphinxDeclareSphinxColorOption{importantBgColor}{{rgb}{1,1,1}} \sphinxDeclareSphinxColorOption{tipBgColor}{{rgb}{1,1,1}} % admonition boxes, "heavy" style % border color defaults to black and background color to white % As long as the color are not explicitly set via user options, % the sphinxpackageboxes.sty code will actually not use them anyhow. \sphinxDeclareSphinxColorOption{warningBorderColor}{{rgb}{0,0,0}} \sphinxDeclareSphinxColorOption{cautionBorderColor}{{rgb}{0,0,0}} \sphinxDeclareSphinxColorOption{attentionBorderColor}{{rgb}{0,0,0}} \sphinxDeclareSphinxColorOption{dangerBorderColor}{{rgb}{0,0,0}} \sphinxDeclareSphinxColorOption{errorBorderColor}{{rgb}{0,0,0}} % BgColor should have been from the start BackgroundColor for better % match with CSS property names, but this is legacy interface % which is too late to change because the internal color names % and not only the option names have been documented at user level. \sphinxDeclareSphinxColorOption{warningBgColor}{{rgb}{1,1,1}} \sphinxDeclareSphinxColorOption{cautionBgColor}{{rgb}{1,1,1}} \sphinxDeclareSphinxColorOption{attentionBgColor}{{rgb}{1,1,1}} \sphinxDeclareSphinxColorOption{dangerBgColor}{{rgb}{1,1,1}} \sphinxDeclareSphinxColorOption{errorBgColor}{{rgb}{1,1,1}} %%%%%%%% % % Additions of CSS-like keys at 5.1.0 (and possibility of rounded boxes) % ----------------------------------- % % These CSS-named alikes allow to configure 4 border widths, 4 padding seps, 4 % corner radii, optional shadow, border color, background color, shadow color. % % In future, an alternative user interface will perhaps be provided to parse % genuine CSS, but this will be easier to do in Python than in LaTeX. % % Refactoring (and extension) at 6.2.0 % ------------------------------------ % % 6.2.0 batch defines in one go all auxiliaries for code-blocks, topics, and % admonitions. The needed steps to maintain the legacy option names working % and to set some specific defaults are handled in a second step. % % This allowed to: % % - associate these CSS-named options also to note, hint, important, and tip % which thus can access the full customizability of sphinxheavybox if they use % it. % % - provide a \sphinxbox command for boxing inline text elements with the same % full customizability. % % The \dimen's \sphinxverbatimborder, \sphinxverbatimsep, \sphinxshadowsep, % \sphinxshadowsize, and \sphinxshadowrule, which had been deprecated have % finally been removed entirely. No more \dimen register is used here only % storage in macros. % \def\spxstring@none{none} \def\spxstring@clone{clone} % % Border keys % \def\spx@tempa#1{% #1 = macro prefix \expandafter\spx@tempb \csname #1border\expandafter\endcsname \csname #1border@top\expandafter\endcsname \csname #1border@right\expandafter\endcsname \csname #1border@bottom\expandafter\endcsname \csname #1border@left\expandafter\endcsname \csname if#1border@open\expandafter\endcsname \csname #1border@opentrue\expandafter\endcsname \csname #1border@openfalse\endcsname }% \def\spx@tempb #1#2#3#4#5#6#7#8#9{% #9 = option prefix \define@key{sphinx}{#9border-top-width}{\def#2{##1}}% \define@key{sphinx}{#9border-right-width}{\def#3{##1}}% \define@key{sphinx}{#9border-bottom-width}{\def#4{##1}}% \define@key{sphinx}{#9border-left-width}{\def#5{##1}}% \define@key{sphinx}{#9border-width}{% \def#1{##1}% MEMO: not immediately expanded, should this be changed? \def#2{#1}\let#3#2\let#4#2\let#5#2% }% \newif#6% \define@key{sphinx}{#9box-decoration-break}% {\begingroup\edef\spx@tempa{##1}\expandafter\endgroup \ifx\spx@tempa\spxstring@clone#8\else#7\fi}% \spx@tempc{#9}% option prefix } \def\spx@tempc #1#2{% #1 = option prefix, #2 = legacy option name % keep legacy option names as aliases to new-named options \expandafter\let\csname KV@sphinx@#2\expandafter\endcsname \csname KV@sphinx@#1border-width\endcsname % init border-width (fetches next argument) \csname KV@sphinx@#1border-width\endcsname } % MEMO: prior to 6.2.0 the \fboxrule value (0.4pt, a priori) was frozen here via % a \dimen assignment done immediately. Now it remains \fboxrule until being used. % macro prefix option prefix legacy option init value \spx@tempa{spx@pre@} {pre_} {verbatimborder} \fboxrule \spx@tempa{spx@topic@} {div.topic_} {shadowrule} \fboxrule \spx@tempa{spx@note@} {div.note_} {noteborder} {0.5pt} \spx@tempa{spx@hint@} {div.hint_} {hintborder} {0.5pt} \spx@tempa{spx@important@}{div.important_}{importantborder}{0.5pt} \spx@tempa{spx@tip@} {div.tip_} {tipborder} {0.5pt} \spx@tempa{spx@warning@} {div.warning_} {warningborder} {1pt} \spx@tempa{spx@caution@} {div.caution_} {cautionborder} {1pt} \spx@tempa{spx@attention@}{div.attention_}{attentionborder}{1pt} \spx@tempa{spx@danger@} {div.danger_} {dangerborder} {1pt} \spx@tempa{spx@error@} {div.error_} {errorborder} {1pt} % this one new at 6.2.0: (we do not create a "legacy name" for it) \spx@tempa{spx@box@} {box_} {box_border-width}\fboxrule % Set default box-decoration-break style for codeblocks to slice \spx@pre@border@opentrue % new default at 6.0.0: slice, not clone % 6.2.0 has added support for box-decoration-break=slice to all % other directives, formerly the option setting was ignored for them. % Padding keys % \def\spx@tempa#1{% \expandafter\spx@tempb \csname #1padding\expandafter\endcsname \csname #1padding@top\expandafter\endcsname \csname #1padding@right\expandafter\endcsname \csname #1padding@bottom\expandafter\endcsname \csname #1padding@left\endcsname }% \def\spx@tempb #1#2#3#4#5#6{% #6 = option prefix \define@key{sphinx}{#6padding-top}{\def#2{##1}}% \define@key{sphinx}{#6padding-right}{\def#3{##1}}% \define@key{sphinx}{#6padding-bottom}{\def#4{##1}}% \define@key{sphinx}{#6padding-left}{\def#5{##1}}% \define@key{sphinx}{#6padding}{% \def#1{##1}% \def#2{#1}\let#3#2\let#4#2\let#5#2% }% % initialization (will fetch "init" argument next): \csname KV@sphinx@#6padding\endcsname } % MEMO: prior to 6.2.0 the \fboxsep value (3pt, a priori) was frozen here via % a \dimen assignment done immediately. Now it remains \fboxsep until being used. % #1 macro prefix #6 option prefix init value \spx@tempa{spx@pre@} {pre_} \fboxsep \spx@tempa{spx@topic@} {div.topic_} {5pt} % MEMO: prior to 6.2.0, "note" type admonitions used sphinxlightbox automatically % and had no interface to set the padding parameters needed by sphinxheavybox. % At 6.2.0 they acquired such interface and the default is set as for legacy % default of "warning" type. I hesitated using \fboxsep, but if I did I would % then need to explain how to change "note etc..." into behaving exactly % as "warning etc...", which goes via the \dimexpr here which is too scary to % put sanely into documentation. \spx@tempa{spx@note@} {div.note_} {\dimexpr.6\baselineskip-\spx@note@border\relax} \spx@tempa{spx@hint@} {div.hint_} {\dimexpr.6\baselineskip-\spx@hint@border\relax} \spx@tempa{spx@important@}{div.important_} {\dimexpr.6\baselineskip-\spx@important@border\relax} \spx@tempa{spx@tip@} {div.tip_} {\dimexpr.6\baselineskip-\spx@tip@border\relax} % MEMO: prior to 5.1.0 padding was not separately customizable from border % width for warning type admonitions. The below keeps the legacy behavior of a % constant borderwidth+padding. The dim expression is not evaluated yet, only % at time of use (so that it dynamically adapts to the border width setting). % MEMO: I could use everywhere \spx@notice@border, as sphinxadmonition environment % configures it to hold the \spx@@border value. \spx@tempa{spx@warning@} {div.warning_} {\dimexpr.6\baselineskip-\spx@warning@border\relax} \spx@tempa{spx@caution@} {div.caution_} {\dimexpr.6\baselineskip-\spx@caution@border\relax} \spx@tempa{spx@attention@}{div.attention_} {\dimexpr.6\baselineskip-\spx@attention@border\relax} \spx@tempa{spx@danger@} {div.danger_} {\dimexpr.6\baselineskip-\spx@danger@border\relax} \spx@tempa{spx@error@} {div.error_} {\dimexpr.6\baselineskip-\spx@error@border\relax} \spx@tempa{spx@box@} {box_} \fboxsep % define legacy verbatimsep key as alias of pre_padding key \expandafter\let\expandafter\KV@sphinx@verbatimsep\csname KV@sphinx@pre_padding\endcsname % define legacy shadowsep key as alias of div.topic_padding key \expandafter\let\expandafter\KV@sphinx@shadowsep\csname KV@sphinx@div.topic_padding\endcsname % Corner radii keys % % Prior to 6.2.0, the "rounded box" branch obeyed the 4 radii but ignored % the separate border widths and used only the border-width setting. % Now, all 4 + 4 parameters are obeyed. \def\spx@tempa#1{% #1 = macro prefix \expandafter\spx@tempb \csname #1radius@topleft\expandafter\endcsname \csname #1radius@topright\expandafter\endcsname \csname #1radius@bottomright\expandafter\endcsname \csname #1radius@bottomleft\endcsname }% \def\spx@tempb #1#2#3#4#5{% #5 = option prefix \define@key{sphinx}{#5border-top-left-radius}{\def#1{##1}}% \define@key{sphinx}{#5border-top-right-radius}{\def#2{##1}}% \define@key{sphinx}{#5border-bottom-right-radius}{\def#3{##1}}% \define@key{sphinx}{#5border-bottom-left-radius}{\def#4{##1}}% \define@key{sphinx}{#5border-radius}{\def#1{##1}\let#2#1\let#3#1\let#4#1}% \csname KV@sphinx@#5border-radius\endcsname % fetches next argument } % The init value for corner radius in code-blocks was \z@ (i.e. 0pt) prior % to 6.0.0., then 3pt, then \fboxsep at 6.2.0 as padding is \fboxsep, % and \fboxsep=3pt per default (also with platex). % macro prefix option prefix init value \spx@tempa{spx@pre@} {pre_} \fboxsep \spx@tempa{spx@topic@} {div.topic_} \z@ \spx@tempa{spx@note@} {div.note_} \z@ \spx@tempa{spx@hint@} {div.hint_} \z@ \spx@tempa{spx@important@}{div.important_} \z@ \spx@tempa{spx@tip@} {div.tip_} \z@ \spx@tempa{spx@warning@} {div.warning_} \z@ \spx@tempa{spx@caution@} {div.caution_} \z@ \spx@tempa{spx@attention@}{div.attention_} \z@ \spx@tempa{spx@danger@} {div.danger_} \z@ \spx@tempa{spx@error@} {div.error_} \z@ \spx@tempa{spx@box@} {box_} \fboxsep % Shadow keys % % Prior to 6.2.0, an "inset" shadow caused the rendering to ignore % rounded corners. Starting with 6.2.0, an "inset" shadow is simply % ignored (not implemented) if any of the corner radii is positive, % rather than forcing a rectangle+inset shadow output. \def\spx@tempa#1{% \expandafter\spx@tempb \csname if#1withshadow\expandafter\endcsname \csname if#1insetshadow\endcsname }% \def\spx@tempb#1#2{\newif#1\newif#2}% % macro prefix \spx@tempa{spx@pre@} \spx@tempa{spx@topic@} \spx@tempa{spx@note@} \spx@tempa{spx@hint@} \spx@tempa{spx@important@} \spx@tempa{spx@tip@} \spx@tempa{spx@warning@} \spx@tempa{spx@caution@} \spx@tempa{spx@attention@} \spx@tempa{spx@danger@} \spx@tempa{spx@error@} \spx@tempa{spx@box@} % \def\spx@tempa#1{% #1 = macro prefix \expandafter\spx@tempb \csname #1withshadowtrue\expandafter\endcsname \csname #1withshadowfalse\expandafter\endcsname \csname #1insetshadowtrue\expandafter\endcsname \csname #1insetshadowfalse\expandafter\endcsname \csname #1shadow@setter\expandafter\endcsname \csname #1shadow@xoffset\expandafter\endcsname \csname #1shadow@yoffset\endcsname }% \def\spx@tempb#1#2#3#4#5#6#7#8{% #8 = option prefix \define@key{sphinx}{#8box-shadow}{#5##1 {} {} \@nnil}% \def#5##1 ##2 ##3 ##4\@nnil{% \begingroup\edef\spx@tempa{##1}\expandafter\endgroup \ifx\spx@tempa\spxstring@none #2% % MEMO: at 5.1.0 and up to 6.2.0, an \edef with \number\dimexpr was % used here. Since 6.2.0, expansion is delayed to time of use as for % the other dimensions handled above. This is synched with an added % encapsulation in \dimexpr...\relax by the "setup" from % sphinxpackageboxes.sty. An induced regression had to be fixed in % the sphinxShadowBox environment as it was using in an \ifdim the % \spx@topic@shadow@yoffset macro, now holding by default 4pt+\z@ % rather than an already digested 262144sp. The +\z@ is in case ##2 % is empty. \else #1% \def#6{##1}\def#7{##2+\z@}% \if\relax\detokenize{##3}\relax#4\else#3\fi \fi }% #5none {} {} \@nnil % no shadow by default (except for topic, see below) } \spx@tempa{spx@pre@} {pre_} \spx@tempa{spx@topic@} {div.topic_} % This corresponds to the legacy parameters of ShadowBox \spx@topic@shadow@setter 4pt 4pt {} \@nnil \spx@tempa{spx@note@} {div.note_} \spx@tempa{spx@hint@} {div.hint_} \spx@tempa{spx@important@}{div.important_} \spx@tempa{spx@tip@} {div.tip_} \spx@tempa{spx@warning@} {div.warning_} \spx@tempa{spx@caution@} {div.caution_} \spx@tempa{spx@attention@}{div.attention_} \spx@tempa{spx@danger@} {div.danger_} \spx@tempa{spx@error@} {div.error_} \spx@tempa{spx@box@} {box_} % Support for legacy shadowsize (topic/contents) % This definition was broken due to a typo at 5.1.0 and got fixed at 6.1.2 % MEMO: at 6.2.0 this no longer does \number\dimexpr in an \edef. Reason is to % keep in sync with div.topic_box-shadow handling of xoffset and yoffset. % Attention in particular to \ifdim context, we add a \dimexpr to the one here. \define@key{sphinx}{shadowsize}{% \def\spx@topic@shadow@xoffset{#1}% \let\spx@topic@shadow@yoffset\spx@topic@shadow@xoffset \ifdim\dimexpr\spx@topic@shadow@xoffset=\z@ \spx@topic@withshadowfalse \else \spx@topic@withshadowtrue \spx@topic@insetshadowfalse \fi }% % Color keys % (four of them: border, background, shadow and the text color) % % Some problems due to legacy naming scheme which had diverging conventions % for code-blocks (VerbatimBorderColor, VerbatimColor) and admonitions % (sphinxwarningBorderColor, sphinxwarningBgColor, etc...) regarding the % internal names of the used colors. Unfortunately VerbatimColor and for % example sphinxwarningBgColor are also documented at user level, they are not % only internally used. % % For topic directive, "legacy" (by this I mean Sphinx around 2016-2017 after % my first additions to LaTeX) had no interface for colors, so I could change % some internals with no breakage during 5.x up to 6.2.0. So topic % (shadowbox) could be unified with admonitions (sphinxheavybox), and the % "set-up" macros could all be moved into a single one in the % sphinxpackageboxes.sty file, with only one argument holding the directive % type. % % It was then needed only for sphinxlatexliterals.sty to let its % \spx@verb@boxes@fcolorbox@setup incorporate some extra adjustment. % % We associate a boolean to each color, so that the box code can % decide to insert a \color command or consider it is not needed. \def\spx@tempa#1{% \expandafter\spx@tempb \csname if#1withshadowcolor\expandafter\endcsname \csname if#1withbordercolor\expandafter\endcsname \csname if#1withbackgroundcolor\expandafter\endcsname \csname if#1withtextcolor\endcsname }% \def\spx@tempb#1#2#3#4{\newif#1\newif#2\newif#3\newif#4}% % macro prefix \spx@tempa{spx@pre@} \spx@tempa{spx@topic@} \spx@tempa{spx@note@} \spx@tempa{spx@hint@} \spx@tempa{spx@important@} \spx@tempa{spx@tip@} \spx@tempa{spx@warning@} \spx@tempa{spx@caution@} \spx@tempa{spx@attention@} \spx@tempa{spx@danger@} \spx@tempa{spx@error@} \spx@tempa{spx@box@} % \def\spx@tempa#1{% #1 = macro prefix \expandafter\spx@tempb \csname #1withbordercolortrue\expandafter\endcsname \csname #1withbackgroundcolortrue\expandafter\endcsname \csname #1withshadowcolortrue\expandafter\endcsname \csname #1withtextcolortrue\endcsname } \def\spx@tempb#1#2#3#4#5#6{% #5 = option prefix, #6 = color name prefix \define@key{sphinx}{#5border-TeXcolor}% {#1\spx@defineorletcolor{#6BorderColor}##1\relax}% \define@key{sphinx}{#5background-TeXcolor}% {#2\spx@defineorletcolor{#6BgColor}##1\relax}% \define@key{sphinx}{#5box-shadow-TeXcolor}% {#3\spx@defineorletcolor{#6ShadowColor}##1\relax}% \define@key{sphinx}{#5TeXcolor}% {#4\spx@defineorletcolor{#6TextColor}##1\relax}% } % macro prefix option prefix color name prefix \spx@tempa{spx@pre@} {pre_} {Verbatim} % (memo: internal VerbatimShadowColor was formerly sphinxVerbatimShadowColor) % internal legacy color name is VerbatimColor not VerbatimBgColor, so redefine: \define@key{sphinx}{pre_background-TeXcolor}% {\spx@pre@withbackgroundcolortrue\spx@defineorletcolor{VerbatimColor}#1\relax}% \spx@pre@withbordercolortrue % 6.0.0 VerbatimBorderColor {RGB}{32,32,32} \spx@pre@withbackgroundcolortrue % 6.0.0 VerbatimColor {gray}{0.95} % Keep legacy option names working \expandafter\let\expandafter\KV@sphinx@VerbatimBorderColor \csname KV@sphinx@pre_border-TeXcolor\endcsname \expandafter\let\expandafter\KV@sphinx@VerbatimColor \csname KV@sphinx@pre_background-TeXcolor\endcsname % (6.2.0 modified some internal namings for the colors of topic boxes) % macro prefix option prefix color name prefix \spx@tempa{spx@topic@} {div.topic_} {sphinxtopic}% (no legacy interface) \spx@tempa{spx@note@} {div.note_} {sphinxnote} \spx@tempa{spx@hint@} {div.hint_} {sphinxhint} \spx@tempa{spx@important@}{div.important_} {sphinximportant} \spx@tempa{spx@tip@} {div.tip_} {sphinxtip} \spx@tempa{spx@warning@} {div.warning_} {sphinxwarning} \spx@tempa{spx@caution@} {div.caution_} {sphinxcaution} \spx@tempa{spx@attention@}{div.attention_} {sphinxattention} \spx@tempa{spx@danger@} {div.danger_} {sphinxdanger} \spx@tempa{spx@error@} {div.error_} {sphinxerror} \spx@tempa{spx@box@} {box_} {sphinxbox} % Keep legacy sphinxsetup color options interface for "strong" admonitions \def\spx@tempa#1#2{% #1 = option prefix, #2 = legacy option prefix \expandafter\let\csname KV@sphinx@#2BorderColor\expandafter\endcsname \csname KV@sphinx@#1border-TeXcolor\endcsname \expandafter\let\csname KV@sphinx@#2BgColor\expandafter\endcsname \csname KV@sphinx@#1background-TeXcolor\endcsname } \spx@tempa{div.warning_} {warning} \spx@tempa{div.caution_} {caution} \spx@tempa{div.attention_} {attention} \spx@tempa{div.danger_} {danger} \spx@tempa{div.error_} {error} % Keep legacy sphinxsetup BorderColor for =note, hint, ... % which will not trigger sphinxheavybox % Add "legacy" hintTextColor etc... that will not trigger sphinxheavybox \def\spx@tempa#1#2{% #1 = CSS like option prefix, #2 = legacy option prefix \expandafter\let\csname KV@sphinx@#2BorderColor\expandafter\endcsname \csname KV@sphinx@#1border-TeXcolor\endcsname \expandafter\let\csname KV@sphinx@#2TextColor\expandafter\endcsname \csname KV@sphinx@#1TeXcolor\endcsname } \spx@tempa{div.note_} {note} \spx@tempa{div.hint_} {hint} \spx@tempa{div.important_} {important} \spx@tempa{div.tip_} {tip} % The TeXextras key % \def\spx@tempa#1{% #1 = macro prefix \expandafter\spx@tempb\csname #1TeXextras\endcsname } \def\spx@tempb#1#2{% #2 = option prefix \define@key{sphinx}{#2TeXextras}{\def#1{##1}}% } % macro prefix option prefix \spx@tempa{spx@pre@} {pre_} \spx@tempa{spx@topic@} {div.topic_} \spx@tempa{spx@note@} {div.note_} \spx@tempa{spx@hint@} {div.hint_} \spx@tempa{spx@important@}{div.important_} \spx@tempa{spx@tip@} {div.tip_} \spx@tempa{spx@warning@} {div.warning_} \spx@tempa{spx@caution@} {div.caution_} \spx@tempa{spx@attention@}{div.attention_} \spx@tempa{spx@danger@} {div.danger_} \spx@tempa{spx@error@} {div.error_} \spx@tempa{spx@box@} {box_} % Add "legacy" hintTeXextras etc... that will not trigger sphinxheavybox \def\spx@tempa#1#2{% #1 = CSS like option prefix, #2 = legacy option prefix \expandafter\let\csname KV@sphinx@#2TeXextras\expandafter\endcsname \csname KV@sphinx@#1TeXextras\endcsname } \spx@tempa{div.note_} {note} \spx@tempa{div.hint_} {hint} \spx@tempa{div.important_} {important} \spx@tempa{div.tip_} {tip} % For note type admonitions, redefine all CSS-like named options to trigger % the "heavybox" path. % % MEMO: the noteBorderColor and noteborder legacy options have already been % re-created and they do not trigger the "heavybox" as their meaning will not % be modified in the loop below contrarily to their CSS counterparts % div.note_border-TeXcolor and div.note_border-width, and to the noteBgColor % etc... which are handled below. % % This goes via rather hardcore TeX here. \def\spx@tempa#1{\if\relax#1\expandafter\@gobble \else \toks@{##1}% \expandafter\def\csname KV@sphinx@div.note_#1\expandafter\endcsname \the\toks0\expandafter{% \csname spx@opt@heavynotetrue\expandafter\expandafter\expandafter\endcsname \csname KV@sphinx@div.note_#1\endcsname{##1}}% \expandafter\def\csname KV@sphinx@div.hint_#1\expandafter\endcsname \the\toks0\expandafter{% \csname spx@opt@heavyhinttrue\expandafter\expandafter\expandafter\endcsname \csname KV@sphinx@div.hint_#1\endcsname{##1}}% \expandafter\def\csname KV@sphinx@div.important_#1\expandafter\endcsname \the\toks0\expandafter{% \csname spx@opt@heavyimportanttrue\expandafter\expandafter\expandafter\endcsname \csname KV@sphinx@div.important_#1\endcsname{##1}}% \expandafter\def\csname KV@sphinx@div.tip_#1\expandafter\endcsname \the\toks0\expandafter{% \csname spx@opt@heavytiptrue\expandafter\expandafter\expandafter\endcsname \csname KV@sphinx@div.tip_#1\endcsname{##1}}% \fi \spx@tempa } \spx@tempa{border-width}% {border-top-width}{border-right-width}{border-bottom-width}{border-left-width}% {box-decoration-break}% {padding}% {padding-top}{padding-right}{padding-bottom}{padding-left}% {border-radius}% {border-top-left-radius}{border-top-right-radius}% {border-bottom-right-radius}{border-bottom-left-radius}% {box-shadow}% {border-TeXcolor}{background-TeXcolor}{box-shadow-TeXcolor}{TeXcolor}% {TeXextras}% \relax % Now we add at 6.2.0 BgColor et al. options which will trigger the % "heavybox" as they are \let to the div._background-TeXColor option % which has already been enhanced to set the boolean for rendering via % "heavybox". This is in contrast with legacy BorderColor, % and with the new TeXcolor and TeXextras. \def\spx@tempa#1#2{% #1 = CSS like option prefix, #2 = legacy style option prefix \expandafter\let\csname KV@sphinx@#2BgColor\expandafter\endcsname \csname KV@sphinx@#1background-TeXcolor\endcsname } \spx@tempa{div.note_} {note} \spx@tempa{div.hint_} {hint} \spx@tempa{div.important_} {important} \spx@tempa{div.tip_} {tip} \newif\ifspx@opt@box@addstrut \expandafter\def\csname KV@sphinx@box_addstrut\endcsname#1{% \csname spx@opt@box@addstrut#1\endcsname } \expandafter\def\csname KV@sphinx@box_addstrut@default\endcsname{% \spx@opt@box@addstruttrue } \DeclareDefaultOption{\@unknownoptionerror} \ProcessKeyvalOptions* % don't allow use of maxlistdepth via \sphinxsetup. \DisableKeyvalOption{sphinx}{maxlistdepth} \DisableKeyvalOption{sphinx}{numfigreset} \DisableKeyvalOption{sphinx}{nonumfigreset} \DisableKeyvalOption{sphinx}{mathnumfig} \DisableKeyvalOption{sphinx}{booktabs} \DisableKeyvalOption{sphinx}{borderless} \DisableKeyvalOption{sphinx}{rowcolors} % FIXME: this is unrelated to an option, move this elsewhere % To allow hyphenation of first word in narrow contexts; no option, % customization to be done via 'preamble' key \newcommand*\sphinxAtStartPar{\leavevmode\nobreak\hskip\z@skip} % No need for the \hspace{0pt} trick (\hskip\z@skip) with luatex \ifdefined\directlua\let\sphinxAtStartPar\@empty\fi % user interface: options can be changed midway in a document! \newcommand\sphinxsetup{\setkeys{sphinx}} %% MISCELLANEOUS CONTEXT % % flag to be set in a framed environment % (defined here as currently needed by three sphinxlatex....sty files and % even if not needed if such files are replaced, the definition does no harm) \newif\ifspx@inframed % % \spx@ifcaptionpackage (defined at begin document) % is needed currently in macros from: % sphinxlatexliterals.sty (sphinxVerbatim) % sphinxlatextables.sty (for some macros used in the table templates) % % \sphinxcaption is mark-up injected by the tabular and tabulary templates % it is defined in sphinxlatextables.sty % % store the original \caption macro for usage with figures inside longtable % and tabulary cells. Make sure we get the final \caption in presence of % caption package, whether the latter was loaded before or after sphinx. \AtBeginDocument{% \let\spx@originalcaption\caption \@ifpackageloaded{caption} {\let\spx@ifcaptionpackage\@firstoftwo \caption@AtBeginDocument*{\let\spx@originalcaption\caption}% % in presence of caption package, drop our own \sphinxcaption whose aim was to % ensure same width of caption to all kinds of tables (tabular(y), longtable), % because caption package has its own width (or margin) option \def\sphinxcaption{\caption}% }% {\let\spx@ifcaptionpackage\@secondoftwo}% } %% PASS OPTIONS % % pass options to hyperref; it must not have been loaded already \input{sphinxoptionshyperref.sty} % pass options to geometry; it must not have been loaded already \input{sphinxoptionsgeometry.sty} %% COLOR (general) % % FIXME: these two should be deprecated % % FIXME: \normalcolor should be used and \py@NormalColor never defined \def\py@NormalColor{\color{black}} % FIXME: \color{TitleColor} should be used directly and \py@TitleColor % should never get defined. \def\py@TitleColor{\color{TitleColor}} %% PACKAGES % % as will be indicated below, secondary style files load some more packages % % For \text macro (sphinx.util.texescape) % also for usage of \firstchoice@true(false) in sphinxlatexgraphics.sty \RequirePackage{amstext} % It was passed "warn" option from latex template in case it is already loaded % via some other package before \usepackage{sphinx} in preamble \RequirePackage{textcomp} % For the H specifier. Do not \restylefloat{figure}, it breaks Sphinx code % for allowing figures in tables. \RequirePackage{float} % For floating figures in the text. Better to load after float. \RequirePackage{wrapfig} % Provides \captionof, used once by latex writer (\captionof{figure}) \RequirePackage{capt-of} % Support hlist directive \RequirePackage{multicol} %% GRAPHICS % % It will always be needed, so let's load it here \RequirePackage{graphicx} \input{sphinxlatexgraphics.sty} %% FRAMED ENVIRONMENTS % % \sphinxbox added at 6.2.0, its definition is in sphinxpackageboxes. % % Alias all \sphinxsetup "box_" keys to become \sphinxboxsetup no-prefix keys \@tfor\x:={border-width}% {border-top-width}{border-right-width}{border-bottom-width}{border-left-width}% {box-decoration-break}% This one is actually useless, as \sphinxbox % creates an unbreakable horizontal box, not a breakable vertical % box. And as is well-known it is very complicated (not to say % impossible) to create in LaTeX breakable horizontal boxes. No % package offers them. See the complications for the support of % verbatimforcewraps in sphinxlatexliterals.sty or see the source % code of the soul or soulutf8 packages. {padding}% {padding-top}{padding-right}{padding-bottom}{padding-left}% {border-radius}% {border-top-left-radius}{border-top-right-radius}% {border-bottom-right-radius}{border-bottom-left-radius}% {box-shadow}% {border-TeXcolor}{background-TeXcolor}{box-shadow-TeXcolor}{TeXcolor}% {TeXextras}{addstrut}{addstrut@default}% \do{\expandafter\let\csname KV@sphinxbox@\x\expandafter\endcsname \csname KV@sphinx@box_\x\endcsname} % Let \sphinxboxsetup also prepare a "reset", which will be used by nested % boxes; currently and by laziness this is implemented simply by accumulating % all passed options inside some storage, in the order they were given, rather % than saving the box would-be parameters. Advantage is that this will not % have to be modified if additional keys are added in future (e.g. for % elliptic corners). Storing obeys TeX groups. (these details would be % relevant only for some genuine independent LaTeX package and manual user % authored mark-up, not Sphinx auto mark-up). \newcommand\sphinxboxsetup[1]{% \setkeys{sphinxbox}{#1}% \expandafter\def\expandafter\spx@boxes@sphinxbox@defaults\expandafter {\spx@boxes@sphinxbox@defaults,#1}% } \def\spx@boxes@sphinxbox@reset{% \begingroup\def\x{\endgroup\setkeys{sphinxbox}}% \expandafter\x\expandafter{\spx@boxes@sphinxbox@defaults}% } % Some of these defaults got already set. But we now list them all explicitly % for a complete initial configuration of reset storage. % \let\spx@boxes@sphinxbox@defaults\@gobble \sphinxboxsetup{% border-width=\fboxrule,% <-not really needed to avoid EOL space padding=\fboxsep,% but done here out of habit border-radius=\fboxsep,% box-shadow=none,% % As xcolor is perhaps not loaded we can not use background-TeXcolor=VerbatimColor % which would not be compatible with \definecolor syntax. border-TeXcolor={RGB}{32,32,32},% the default VerbatimBorderColor background-TeXcolor={gray}{0.95},% the default VerbatimColor box-shadow-TeXcolor={rgb}{0,0,0},% TeXextras={},% addstrut=false% (a final comma here would not hurt) }% \RequirePackage{sphinxpackageboxes} \input{sphinxlatexadmonitions.sty} \input{sphinxlatexliterals.sty} \input{sphinxlatexshadowbox.sty} %% CONTAINERS % \input{sphinxlatexcontainers.sty} %% PYGMENTS % stylesheet for highlighting with pygments \RequirePackage{sphinxhighlight} %% TABLES % \input{sphinxlatextables.sty} %% NUMBERING OF FIGURES, TABLES, AND LITERAL BLOCKS % \input{sphinxlatexnumfig.sty} %% LISTS % \input{sphinxlatexlists.sty} %% FOOTNOTES % % Support scopes for footnote numbering % This is currently stepped at each input file \newcounter{sphinxscope} \newcommand{\sphinxstepscope}{\stepcounter{sphinxscope}} % We ensure \thesphinxscope expands to digits tokens, independently of language \renewcommand{\thesphinxscope}{\number\value{sphinxscope}} \newcommand\sphinxthefootnotemark[2]{% % this is used to make reference to an explicitly numbered footnote not on same page % #1=label of footnote text, #2=page number where footnote text was printed \ifdefined\pagename \pagename\space#2, % <- space \else p. #2, % <- space \fi #1% no space } % support large numbered footnotes in minipage; but this is now obsolete % from systematic use of savenotes environment around minipages \def\thempfootnote{\arabic{mpfootnote}} % This package is needed to support hyperlinked footnotes in tables and % framed contents, and to allow code-blocks in footnotes. \RequirePackage{sphinxpackagefootnote} %% INDEX, BIBLIOGRAPHY, APPENDIX, TABLE OF CONTENTS % \input{sphinxlatexindbibtoc.sty} %% STYLING % \input{sphinxlatexstylepage.sty} \input{sphinxlatexstyleheadings.sty} \input{sphinxlatexstyletext.sty} %% MODULE RELEASE DATA AND OBJECT DESCRIPTIONS % \input{sphinxlatexobjects.sty} % FIXME: this line should be dropped, as "9" is default anyhow. \ifdefined\pdfcompresslevel\pdfcompresslevel = 9 \fi \endinput krb5-1.22.1/doc/pdf/sphinxhighlight.sty0000664000175000017500000001660115051422730017625 0ustar ghudsonghudson\NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesPackage{sphinxhighlight}[2022/06/30 stylesheet for highlighting with pygments] % Its contents depend on pygments_style configuration variable. \makeatletter \def\PYG@reset{\let\PYG@it=\relax \let\PYG@bf=\relax% \let\PYG@ul=\relax \let\PYG@tc=\relax% \let\PYG@bc=\relax \let\PYG@ff=\relax} \def\PYG@tok#1{\csname PYG@tok@#1\endcsname} \def\PYG@toks#1+{\ifx\relax#1\empty\else% \PYG@tok{#1}\expandafter\PYG@toks\fi} \def\PYG@do#1{\PYG@bc{\PYG@tc{\PYG@ul{% \PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}} \def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}} \@namedef{PYG@tok@w}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}} \@namedef{PYG@tok@c}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} \@namedef{PYG@tok@cp}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@cs}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}\def\PYG@bc##1{{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}}} \@namedef{PYG@tok@k}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@kp}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@kt}{\def\PYG@tc##1{\textcolor[rgb]{0.56,0.13,0.00}{##1}}} \@namedef{PYG@tok@o}{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} \@namedef{PYG@tok@ow}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@nb}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@nf}{\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.49}{##1}}} \@namedef{PYG@tok@nc}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}} \@namedef{PYG@tok@nn}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}} \@namedef{PYG@tok@ne}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@nv}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} \@namedef{PYG@tok@no}{\def\PYG@tc##1{\textcolor[rgb]{0.38,0.68,0.84}{##1}}} \@namedef{PYG@tok@nl}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.13,0.44}{##1}}} \@namedef{PYG@tok@ni}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.84,0.33,0.22}{##1}}} \@namedef{PYG@tok@na}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@nt}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.45}{##1}}} \@namedef{PYG@tok@nd}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}} \@namedef{PYG@tok@s}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@sd}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@si}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.44,0.63,0.82}{##1}}} \@namedef{PYG@tok@se}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@sr}{\def\PYG@tc##1{\textcolor[rgb]{0.14,0.33,0.53}{##1}}} \@namedef{PYG@tok@ss}{\def\PYG@tc##1{\textcolor[rgb]{0.32,0.47,0.09}{##1}}} \@namedef{PYG@tok@sx}{\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}} \@namedef{PYG@tok@m}{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \@namedef{PYG@tok@gh}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}} \@namedef{PYG@tok@gu}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}} \@namedef{PYG@tok@gd}{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}} \@namedef{PYG@tok@gi}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}} \@namedef{PYG@tok@gr}{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}} \@namedef{PYG@tok@ge}{\let\PYG@it=\textit} \@namedef{PYG@tok@gs}{\let\PYG@bf=\textbf} \@namedef{PYG@tok@ges}{\let\PYG@bf=\textbf\let\PYG@it=\textit} \@namedef{PYG@tok@gp}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}} \@namedef{PYG@tok@go}{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}} \@namedef{PYG@tok@gt}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}} \@namedef{PYG@tok@err}{\def\PYG@bc##1{{\setlength{\fboxsep}{\string -\fboxrule}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}} \@namedef{PYG@tok@kc}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@kd}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@kn}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@kr}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@bp}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} \@namedef{PYG@tok@fm}{\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.49}{##1}}} \@namedef{PYG@tok@vc}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} \@namedef{PYG@tok@vg}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} \@namedef{PYG@tok@vi}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} \@namedef{PYG@tok@vm}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} \@namedef{PYG@tok@sa}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@sb}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@sc}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@dl}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@s2}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@sh}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@s1}{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} \@namedef{PYG@tok@mb}{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \@namedef{PYG@tok@mf}{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \@namedef{PYG@tok@mh}{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \@namedef{PYG@tok@mi}{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \@namedef{PYG@tok@il}{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \@namedef{PYG@tok@mo}{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} \@namedef{PYG@tok@ch}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} \@namedef{PYG@tok@cm}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} \@namedef{PYG@tok@cpf}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} \@namedef{PYG@tok@c1}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} \def\PYGZbs{\char`\\} \def\PYGZus{\char`\_} \def\PYGZob{\char`\{} \def\PYGZcb{\char`\}} \def\PYGZca{\char`\^} \def\PYGZam{\char`\&} \def\PYGZlt{\char`\<} \def\PYGZgt{\char`\>} \def\PYGZsh{\char`\#} \def\PYGZpc{\char`\%} \def\PYGZdl{\char`\$} \def\PYGZhy{\char`\-} \def\PYGZsq{\char`\'} \def\PYGZdq{\char`\"} \def\PYGZti{\char`\~} % for compatibility with earlier versions \def\PYGZat{@} \def\PYGZlb{[} \def\PYGZrb{]} \makeatother % Sphinx redefinitions % Originally to obtain a straight single quote via package textcomp, then % to fix problems for the 5.0.0 inline code highlighting (captions!). % The \text is from amstext, a dependency of sphinx.sty. It is here only % to avoid build errors if for some reason expansion is in math mode. \def\PYGZbs{\text\textbackslash} \def\PYGZus{\_} \def\PYGZob{\{} \def\PYGZcb{\}} \def\PYGZca{\text\textasciicircum} \def\PYGZam{\&} \def\PYGZlt{\text\textless} \def\PYGZgt{\text\textgreater} \def\PYGZsh{\#} \def\PYGZpc{\%} \def\PYGZdl{\$} \def\PYGZhy{\sphinxhyphen}% defined in sphinxlatexstyletext.sty \def\PYGZsq{\text\textquotesingle} \def\PYGZdq{"} \def\PYGZti{\text\textasciitilde} \makeatletter % use \protected to allow syntax highlighting in captions \protected\def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+{\PYG@do{#2}}} \makeatother krb5-1.22.1/doc/pdf/sphinxmanual.cls0000664000175000017500000001022114577122106017073 0ustar ghudsonghudson% % sphinxmanual.cls for Sphinx (https://www.sphinx-doc.org/) % \NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesClass{sphinxmanual}[2019/12/01 v2.3.0 Document class (Sphinx manual)] % chapters starting at odd pages (overridden by 'openany' document option) \PassOptionsToClass{openright}{\sphinxdocclass} % 'oneside' option overriding the 'twoside' default \newif\if@oneside \DeclareOption{oneside}{\@onesidetrue} % Pass remaining document options to the parent class. \DeclareOption*{\PassOptionsToClass{\CurrentOption}{\sphinxdocclass}} \ProcessOptions\relax % Defaults two-side document \if@oneside % nothing to do (oneside is the default) \else \PassOptionsToClass{twoside}{\sphinxdocclass} \fi \LoadClass{\sphinxdocclass} % Set some sane defaults for section numbering depth and TOC depth. You can % reset these counters in your preamble. % \setcounter{secnumdepth}{2} \setcounter{tocdepth}{1} % Adapt \and command to the flushright context of \sphinxmaketitle, to % avoid ragged line endings if author names do not fit all on one single line \DeclareRobustCommand{\and}{% \end{tabular}\kern-\tabcolsep \allowbreak \hskip\dimexpr1em+\tabcolsep\@plus.17fil\begin{tabular}[t]{c}% }% % If it is desired that each author name be on its own line, use in preamble: %\DeclareRobustCommand{\and}{% % \end{tabular}\kern-\tabcolsep\\\begin{tabular}[t]{c}% %}% % Change the title page to look a bit better, and fit in with the fncychap % ``Bjarne'' style a bit better. % \newcommand{\sphinxmaketitle}{% \let\sphinxrestorepageanchorsetting\relax \ifHy@pageanchor\def\sphinxrestorepageanchorsetting{\Hy@pageanchortrue}\fi \hypersetup{pageanchor=false}% avoid duplicate destination warnings \begin{titlepage}% \let\footnotesize\small \let\footnoterule\relax \noindent\rule{\textwidth}{1pt}\par \begingroup % for PDF information dictionary \def\endgraf{ }\def\and{\& }% \pdfstringdefDisableCommands{\def\\{, }}% overwrite hyperref setup \hypersetup{pdfauthor={\@author}, pdftitle={\@title}}% \endgroup \begin{flushright}% \sphinxlogo \py@HeaderFamily {\Huge \@title \par} {\itshape\LARGE \py@release\releaseinfo \par} \vfill {\LARGE \begin{tabular}[t]{c} \@author \end{tabular}\kern-\tabcolsep \par} \vfill\vfill {\large \@date \par \vfill \py@authoraddress \par }% \end{flushright}%\par \@thanks \end{titlepage}% \setcounter{footnote}{0}% \let\thanks\relax\let\maketitle\relax %\gdef\@thanks{}\gdef\@author{}\gdef\@title{} \clearpage \ifdefined\sphinxbackoftitlepage\sphinxbackoftitlepage\fi \if@openright\cleardoublepage\else\clearpage\fi \sphinxrestorepageanchorsetting } \newcommand{\sphinxtableofcontents}{% \pagenumbering{roman}% \begingroup \parskip \z@skip \sphinxtableofcontentshook \tableofcontents \endgroup % before resetting page counter, let's do the right thing. \if@openright\cleardoublepage\else\clearpage\fi \pagenumbering{arabic}% } % This is needed to get the width of the section # area wide enough in the % library reference. Doing it here keeps it the same for all the manuals. % \newcommand{\sphinxtableofcontentshook}{% \renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}}% \renewcommand*\l@subsection{\@dottedtocline{2}{4.1em}{3.5em}}% } % Fix the bibliography environment to add an entry to the Table of % Contents. % For a report document class this environment is a chapter. % \newenvironment{sphinxthebibliography}[1]{% \if@openright\cleardoublepage\else\clearpage\fi % \phantomsection % not needed here since TeXLive 2010's hyperref \begin{thebibliography}{#1}% \addcontentsline{toc}{chapter}{\bibname}}{\end{thebibliography}} % Same for the indices. % The memoir class already does this, so we don't duplicate it in that case. % \@ifclassloaded{memoir} {\newenvironment{sphinxtheindex}{\begin{theindex}}{\end{theindex}}} {\newenvironment{sphinxtheindex}{% \if@openright\cleardoublepage\else\clearpage\fi \phantomsection % needed as no chapter, section, ... created \begin{theindex}% \addcontentsline{toc}{chapter}{\indexname}}{\end{theindex}}} krb5-1.22.1/doc/pdf/sphinxlatexnumfig.sty0000664000175000017500000001066414577122106020212 0ustar ghudsonghudson%% NUMBERING OF FIGURES, TABLES, AND LITERAL BLOCKS % % change this info string if making any custom modification \ProvidesFile{sphinxlatexnumfig.sty}[2021/01/27 numbering] % Requires: remreset (old LaTeX only) % relates to numfig and numfig_secnum_depth configuration variables % LaTeX 2018-04-01 and later provides \@removefromreset \ltx@ifundefined{@removefromreset} {\RequirePackage{remreset}} {}% avoid warning % Everything is delayed to \begin{document} to allow hyperref patches into % \newcounter to solve duplicate label problems for internal hyperlinks to % code listings (literalblock counter). User or extension re-definitions of % \theliteralblock, et al., thus have also to be delayed. (changed at 3.5.0) \AtBeginDocument{% \ltx@ifundefined{c@chapter} {\newcounter{literalblock}}% {\newcounter{literalblock}[chapter]% \def\theliteralblock{\ifnum\c@chapter>\z@\arabic{chapter}.\fi \arabic{literalblock}}% }% \ifspx@opt@nonumfigreset \ltx@ifundefined{c@chapter}{}{% \@removefromreset{figure}{chapter}% \@removefromreset{table}{chapter}% \@removefromreset{literalblock}{chapter}% \ifspx@opt@mathnumfig \@removefromreset{equation}{chapter}% \fi }% \def\thefigure{\arabic{figure}}% \def\thetable {\arabic{table}}% \def\theliteralblock{\arabic{literalblock}}% \ifspx@opt@mathnumfig \def\theequation{\arabic{equation}}% \fi \else \let\spx@preAthefigure\@empty \let\spx@preBthefigure\@empty % \ifspx@opt@usespart % <-- LaTeX writer could pass such a 'usespart' boolean % % as sphinx.sty package option % If document uses \part, (triggered in Sphinx by latex_toplevel_sectioning) % LaTeX core per default does not reset chapter or section % counters at each part. % But if we modify this, we need to redefine \thechapter, \thesection to % include the part number and this will cause problems in table of contents % because of too wide numbering. Simplest is to do nothing. % \fi \ifnum\spx@opt@numfigreset>0 \ltx@ifundefined{c@chapter} {} {\g@addto@macro\spx@preAthefigure{\ifnum\c@chapter>\z@\arabic{chapter}.}% \g@addto@macro\spx@preBthefigure{\fi}}% \fi \ifnum\spx@opt@numfigreset>1 \@addtoreset{figure}{section}% \@addtoreset{table}{section}% \@addtoreset{literalblock}{section}% \ifspx@opt@mathnumfig \@addtoreset{equation}{section}% \fi% \g@addto@macro\spx@preAthefigure{\ifnum\c@section>\z@\arabic{section}.}% \g@addto@macro\spx@preBthefigure{\fi}% \fi \ifnum\spx@opt@numfigreset>2 \@addtoreset{figure}{subsection}% \@addtoreset{table}{subsection}% \@addtoreset{literalblock}{subsection}% \ifspx@opt@mathnumfig \@addtoreset{equation}{subsection}% \fi% \g@addto@macro\spx@preAthefigure{\ifnum\c@subsection>\z@\arabic{subsection}.}% \g@addto@macro\spx@preBthefigure{\fi}% \fi \ifnum\spx@opt@numfigreset>3 \@addtoreset{figure}{subsubsection}% \@addtoreset{table}{subsubsection}% \@addtoreset{literalblock}{subsubsection}% \ifspx@opt@mathnumfig \@addtoreset{equation}{subsubsection}% \fi% \g@addto@macro\spx@preAthefigure{\ifnum\c@subsubsection>\z@\arabic{subsubsection}.}% \g@addto@macro\spx@preBthefigure{\fi}% \fi \ifnum\spx@opt@numfigreset>4 \@addtoreset{figure}{paragraph}% \@addtoreset{table}{paragraph}% \@addtoreset{literalblock}{paragraph}% \ifspx@opt@mathnumfig \@addtoreset{equation}{paragraph}% \fi% \g@addto@macro\spx@preAthefigure{\ifnum\c@subparagraph>\z@\arabic{subparagraph}.}% \g@addto@macro\spx@preBthefigure{\fi}% \fi \ifnum\spx@opt@numfigreset>5 \@addtoreset{figure}{subparagraph}% \@addtoreset{table}{subparagraph}% \@addtoreset{literalblock}{subparagraph}% \ifspx@opt@mathnumfig \@addtoreset{equation}{subparagraph}% \fi% \g@addto@macro\spx@preAthefigure{\ifnum\c@subsubparagraph>\z@\arabic{subsubparagraph}.}% \g@addto@macro\spx@preBthefigure{\fi}% \fi \expandafter\g@addto@macro \expandafter\spx@preAthefigure\expandafter{\spx@preBthefigure}% \let\thefigure\spx@preAthefigure \let\thetable\spx@preAthefigure \let\theliteralblock\spx@preAthefigure \g@addto@macro\thefigure{\arabic{figure}}% \g@addto@macro\thetable{\arabic{table}}% \g@addto@macro\theliteralblock{\arabic{literalblock}}% \ifspx@opt@mathnumfig \let\theequation\spx@preAthefigure \g@addto@macro\theequation{\arabic{equation}}% \fi \fi }% end of big \AtBeginDocument \endinput krb5-1.22.1/doc/mitK5license.rst0000664000175000017500000000023515051422640016174 0ustar ghudsonghudson.. _mitK5license: MIT Kerberos License information ================================ .. toctree:: :hidden: copyright.rst .. include:: notice.rst krb5-1.22.1/doc/build_this.rst0000664000175000017500000000554415051422640015776 0ustar ghudsonghudsonHow to build this documentation from the source =============================================== Pre-requisites for a simple build, or to update man pages: * Sphinx 1.0.4 or higher (See https://www.sphinx-doc.org) with the autodoc extension installed. Additional prerequisites to include the API reference based on Doxygen markup: * Python 2.5 with the Cheetah, lxml, and xml modules * Doxygen Simple build without API reference ---------------------------------- To test simple changes to the RST sources, you can build the documentation without the Doxygen reference by running, from the doc directory:: sphinx-build . test_html You will see a number of warnings about missing files. This is expected. If there is not already a ``doc/version.py`` file, you will need to create one by first running ``make version.py`` in the ``src/doc`` directory of a configured build tree. Updating man pages ------------------ Man pages are generated from the RST sources and checked into the ``src/man`` directory of the repository. This allows man pages to be installed without requiring Sphinx when using a source checkout. To regenerate these files, run ``make man`` from the man subdirectory of a configured build tree. You can also do this from an unconfigured source tree with:: cd src/man make -f Makefile.in top_srcdir=.. srcdir=. man make clean As with the simple build, it is normal to see warnings about missing files when rebuilding the man pages. Building for a release tarball or web site ------------------------------------------ To generate documentation in HTML format, run ``make html`` in the ``doc`` subdirectory of a configured build tree (the build directory corresponding to ``src/doc``, not the top-level ``doc`` directory). The output will be placed in the top-level ``doc/html`` directory. This build will include the API reference generated from Doxygen markup in the source tree. Documentation generated this way will use symbolic names for paths (like ``BINDIR`` for the directory containing user programs), with the symbolic names being links to a table showing typical values for those paths. You can also do this from an unconfigured source tree with:: cd src/doc make -f Makefile.in SPHINX_ARGS= htmlsrc Building for an OS package or site documentation ------------------------------------------------ To generate documentation specific to a build of MIT krb5 as you have configured it, run ``make substhtml`` in the ``doc`` subdirectory of a configured build tree (the build directory corresponding to ``src/doc``, not the top-level ``doc`` directory). The output will be placed in the ``html_subst`` subdirectory of that build directory. This build will include the API reference. Documentation generated this way will use concrete paths (like ``/usr/local/bin`` for the directory containing user programs, for a default custom build). krb5-1.22.1/doc/copyright.rst0000664000175000017500000000032415051422640015647 0ustar ghudsonghudsonCopyright ========= Copyright |copy| 1985-2025 by the Massachusetts Institute of Technology and its contributors. All rights reserved. See :ref:`mitK5license` for additional copyright and license information. krb5-1.22.1/doc/thread-safe.txt0000664000175000017500000002076015051422640016037 0ustar ghudsonghudson[May be out of date. Last significant update: Jan 2005.] In general, it's assumed that the library initialization function (if initialization isn't delayed) and the library finalization function are run in some thread-safe fashion, with no other parts of the library in question in use. (If dlopen or dlsym in one thread starts running the initializer, and then dlopen/dlsym in another thread returns and lets you start accessing functions or data in the library before the initializer is finished, that really seems like a dlopen/dlsym bug.) It's also assumed that if library A depends on library B, then library B's initializer runs first, and its finalizer last, whether loading dynamically at run time or at process startup/exit. (It appears that AIX 4.3.3 may violate this, at least when we use gcc's constructor/destructor attributes in shared libraries.) Support for freeing the heap storage allocated by a library has NOT, in general, been written. There are hooks, but often they ignore some of the library's local storage, mutexes, etc. If shared library finalization code doesn't get run at all at dlclose time, or if we can't use it because the execution order is wrong, then you'll get memory leaks. Deal with it. Several debugging variables that are not part of our official API are not protected by mutexes. In general, the only way to set them is by changing the sources and recompiling, which obviously has no run-time thread safety issues, or by stopping the process under a debugger, which we blithely assert is "safe enough". Debug code that we don't normally enable may be less thread safe than might be desired. For example, multiple printf calls may be made, with the assumption that the output will not be intermixed with output from some other thread. Offhand, I'm not aware of any cases where debugging code is "really" unsafe, as in likely to crash the program or produce insecure results. Various libraries may call assert() and abort(). This should only be for "can't happen" cases, and indicate programming errors. In some cases, the compiler may be able to infer that the "can't happen" cases really can't happen, and drop the calls, but in many cases, this is not possible. There are cases (e.g., in the com_err library) where errors arising when dealing with other errors are handled by calling abort, for lack of anything better. We should probably clean those up someday. Various libraries call getenv(). This is perfectly safe, as long as nothing is calling setenv or putenv or what have you, while multiple threads are executing. Of course, that severely curtails the ability to control our libraries through that "interface". Various libraries call the ctype functions/macros (isupper, etc). It is assumed that the program does not call setlocale, or does so only while the program is still single-threaded or while calls into the Kerberos libraries are not in progress. The Windows thread safety support is unfinished. I'm assuming that structure fields that are never written to (e.g., after a structure has been initialized and *then* made possibly visible to multiple threads) are safe to read from one thread while another field is being updated by another thread. If that's not the case, some more work is needed (and I'd like details on why it's not safe). ---------------- libcom_err Issues: The callback hook support (set_com_err_hook, reset_com_err_hook, and calls to com_err and com_err_va) uses a mutex to protect the handle on the hook function. As a side effect of this, if a callback function is registered which pops up a window and waits for the users' acknowledgement, then other errors cannot be reported by other threads until after the acknowledgement. This could be fixed with multiple-reader-one-writer type locks, but that's a bit more complicated. The string returned by error_message may be per-thread storage. It can be passed off between threads, but it shouldn't be in use by any thread by the time the originating thread calls error_message again. Error tables must no longer be in use (including pointers returned by error_message) when the library containing them is unloaded. Temporary: A flag variable has been created in error_message.c which is used to try to catch cases where remove_error_table is called after the library finalization function. This generally indicates out-of-order execution of the library finalization functions. The handling of this flag is not thread-safe, but if the finalization function is called, other threads should in theory be finished with this library anyways. Statics: error_message.c, com_err.c, covered above. ---------------- libprofile (and its use in libkrb5) Does no checks to see if it's opened multiple instances of the same file under different names. Does not guard against trying to open a file while another thread or process is in the process of replacing it, or two threads trying to update a file at the same time. The former should be pretty safe on UNIX with atomic rename, but on Windows there's a race condition; there's a window (so to speak) where the filename does not correspond to an actual file. Statics: prof_file.c, a list of opened config files and their parse trees, and a mutex to protect it. ---------------- libk5crypto Uses ctype macros; what happens if the locale is changed in a multi-threaded program? Debug var in pbkdf2.c. Statics: pbkdf2.c: debug variable. Statics: crypto_libinit.c: library initializer aux data. ---------------- libkrb5 (TBD) Uses: ctype macros Uses: getaddrinfo, getnameinfo. According to current specifications, getaddrinfo should be thread-safe; some implementations are not, and we're not attempting to figure out which ones. NetBSD 1.6, for example, had an unsafe implementation. Uses: res_ninit, res_nsearch. If these aren't available, the non-'n' versions will be used, and they are sometimes not thread-safe. Uses: mkstemp, mktemp -- Are these, or our uses of them, likely to be thread-safe? Uses: sigaction The use of sigaction is in the code prompting for a password; we try to catch the keyboard interrupt character being used and turn it into an error return from that function. THIS IS NOT THREAD-SAFE. Uses: tcgetattr, tcsetattr. This is also in the password-prompting code. These are fine as long as no other threads are accessing the same terminal at the same time. Uses: fopen. This is thread-safe, actually, but a multi-threaded server is likely to be using lots of file descriptors. On 32-bit Solaris platforms, fopen will not work if the next available file descriptor number is 256 or higher. This can cause the keytab code to fail. Statics: prompter.c: interrupt flag Statics: ccdefops.c: default operations table pointer Statics: ktdefname.c: variable to override default keytab name, NO LOCKING. DON'T TOUCH THESE VARIABLES, at least in threaded programs. Statics: conv_creds.c: debug variable Statics: sendto_kdc.c: debug variable, in export list for KDC Statics: parse.c: default realm cache, changed to not cache Statics: krb5_libinit.c: lib init aux data Statics: osconfig.c: various internal variables, probably should be const Statics: init_ctx.c: "brand" string; not written. Statics: cc_memory.c: list of caches, with mutex. Statics: c_ustime.c: last timestamp, to implement "microseconds must always increment" Statics: ktbase.c, ccbase.c, rc_base.c: type registries and mutexes. ---------------- libgssapi_krb5 (TBD) Uses: ctype macros Statics: acquire_cred.c: name of keytab to use, and mutex. Statics: gssapi_krb5.c: Statics: init_sec_context.c: Statics: set_ccache.c: Statics: gssapi_generic.c: OID definitions, non-const by specification. We probably could make them const anyways. The keytab name saved away by krb5_gss_register_acceptor_identity is global and protected by a mutex; the ccache name stored by gss_krb5_ccache_name is per-thread. This inconsistency is due to the anticipated usage patterns. The old ccache name returned by gss_krb5_ccache_name if the last parameter is not a null pointer is also stored per-thread, and will be discarded at the next call to that routine from the same thread, or at thread termination. Needs work: check various objects for thread safety ---------------- libgssrpc New version is in place. Ignore it for now? ---------------- libkadm5* libkdb5 Skip these for now. We may want the KDC libraries to be thread-safe eventually, so the KDC can take better advantage of hyperthreaded or multiprocessor systems. ---------------- libapputils libss Used by single-threaded programs only (but see above re KDC). Don't bother for now. krb5-1.22.1/doc/notice.rst0000664000175000017500000017201715051422640015131 0ustar ghudsonghudsonCopyright |copy| 1985-2025 by the Massachusetts Institute of Technology. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Downloading of this software may constitute an export of cryptographic software from the United States of America that is subject to the United States Export Administration Regulations (EAR), 15 CFR 730-774. Additional laws or regulations may apply. It is the responsibility of the person or entity contemplating export to comply with all applicable export laws and regulations, including obtaining any required license from the U.S. government. The U.S. government prohibits export of encryption source code to certain countries and individuals, including, but not limited to, the countries of Cuba, Iran, North Korea, Sudan, Syria, and residents and nationals of those countries. Documentation components of this software distribution are licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. (https://creativecommons.org/licenses/by-sa/3.0/) Individual source code files are copyright MIT, Cygnus Support, Novell, OpenVision Technologies, Oracle, Red Hat, Sun Microsystems, FundsXpress, and others. Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, and Zephyr are trademarks of the Massachusetts Institute of Technology (MIT). No commercial use of these trademarks may be made without prior written permission of MIT. "Commercial use" means use of a name in a product or other for-profit manner. It does NOT prevent a commercial firm from referring to the MIT trademarks in order to convey information (although in doing so, recognition of their trademark status should be given). ------------------- The following copyright and permission notice applies to the OpenVision Kerberos Administration system located in ``kadmin/create``, ``kadmin/dbutil``, ``kadmin/passwd``, ``kadmin/server``, ``lib/kadm5``, and portions of ``lib/rpc``: Copyright, OpenVision Technologies, Inc., 1993-1996, All Rights Reserved WARNING: Retrieving the OpenVision Kerberos Administration system source code, as described below, indicates your acceptance of the following terms. If you do not agree to the following terms, do not retrieve the OpenVision Kerberos administration system. You may freely use and distribute the Source Code and Object Code compiled from it, with or without modification, but this Source Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY OTHER REASON. OpenVision retains all copyrights in the donated Source Code. OpenVision also retains copyright to derivative works of the Source Code, whether created by OpenVision or by a third party. The OpenVision copyright notice must be preserved if derivative works are made based on the donated Source Code. OpenVision Technologies, Inc. has donated this Kerberos Administration system to MIT for inclusion in the standard Kerberos 5 distribution. This donation underscores our commitment to continuing Kerberos technology development and our gratitude for the valuable work which has been performed by MIT and the Kerberos community. ------------------- Portions contributed by Matt Crawford ``crawdad@fnal.gov`` were work performed at Fermi National Accelerator Laboratory, which is operated by Universities Research Association, Inc., under contract DE-AC02-76CHO3000 with the U.S. Department of Energy. ------------------- Portions of ``src/lib/crypto`` have the following copyright: Copyright |copy| 1998 by the FundsXpress, INC. All rights reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of FundsXpress. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. FundsXpress makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ------------------- The implementation of the AES encryption algorithm in ``src/lib/crypto/builtin/aes`` has the following copyright: | Copyright |copy| 1998-2013, Brian Gladman, Worcester, UK. All | rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. ------------------- Portions contributed by Red Hat, including the pre-authentication plug-in framework and the NSS crypto implementation, contain the following copyright: | Copyright |copy| 2006 Red Hat, Inc. | Portions copyright |copy| 2006 Massachusetts Institute of Technology | All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Red Hat, Inc., nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- The bundled verto source code is subject to the following license: Copyright 2011 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------- The MS-KKDCP client implementation has the following copyright: Copyright 2013,2014 Red Hat, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- The implementations of GSSAPI mechglue in GSSAPI-SPNEGO in ``src/lib/gssapi``, including the following files: .. parsed-literal:: lib/gssapi/generic/gssapi_err_generic.et lib/gssapi/mechglue/g_accept_sec_context.c lib/gssapi/mechglue/g_acquire_cred.c lib/gssapi/mechglue/g_canon_name.c lib/gssapi/mechglue/g_compare_name.c lib/gssapi/mechglue/g_context_time.c lib/gssapi/mechglue/g_delete_sec_context.c lib/gssapi/mechglue/g_dsp_name.c lib/gssapi/mechglue/g_dsp_status.c lib/gssapi/mechglue/g_dup_name.c lib/gssapi/mechglue/g_exp_sec_context.c lib/gssapi/mechglue/g_export_name.c lib/gssapi/mechglue/g_glue.c lib/gssapi/mechglue/g_imp_name.c lib/gssapi/mechglue/g_imp_sec_context.c lib/gssapi/mechglue/g_init_sec_context.c lib/gssapi/mechglue/g_initialize.c lib/gssapi/mechglue/g_inquire_context.c lib/gssapi/mechglue/g_inquire_cred.c lib/gssapi/mechglue/g_inquire_names.c lib/gssapi/mechglue/g_process_context.c lib/gssapi/mechglue/g_rel_buffer.c lib/gssapi/mechglue/g_rel_cred.c lib/gssapi/mechglue/g_rel_name.c lib/gssapi/mechglue/g_rel_oid_set.c lib/gssapi/mechglue/g_seal.c lib/gssapi/mechglue/g_sign.c lib/gssapi/mechglue/g_store_cred.c lib/gssapi/mechglue/g_unseal.c lib/gssapi/mechglue/g_userok.c lib/gssapi/mechglue/g_utils.c lib/gssapi/mechglue/g_verify.c lib/gssapi/mechglue/gssd_pname_to_uid.c lib/gssapi/mechglue/mglueP.h lib/gssapi/mechglue/oid_ops.c lib/gssapi/spnego/gssapiP_spnego.h lib/gssapi/spnego/spnego_mech.c and the initial implementation of incremental propagation, including the following new or changed files: .. parsed-literal:: include/iprop_hdr.h kadmin/server/ipropd_svc.c lib/kdb/iprop.x lib/kdb/kdb_convert.c lib/kdb/kdb_log.c lib/kdb/kdb_log.h lib/krb5/error_tables/kdb5_err.et kprop/kpropd_rpc.c kprop/kproplog.c are subject to the following license: Copyright |copy| 2004 Sun Microsystems, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------- Kerberos V5 includes documentation and software developed at the University of California at Berkeley, which includes this copyright notice: | Copyright |copy| 1983 Regents of the University of California. | All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- Portions contributed by Novell, Inc., including the LDAP database backend, are subject to the following license: | Copyright |copy| 2004-2005, Novell, Inc. | All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The copyright holder's name is not used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- Portions funded by Sandia National Laboratory and developed by the University of Michigan's Center for Information Technology Integration, including the PKINIT implementation, are subject to the following license: | COPYRIGHT |copy| 2006-2007 | THE REGENTS OF THE UNIVERSITY OF MICHIGAN | ALL RIGHTS RESERVED Permission is granted to use, copy, create derivative works and redistribute this software and such derivative works for any purpose, so long as the name of The University of Michigan is not used in any advertising or publicity pertaining to the use of distribution of this software without specific, written prior authorization. If the above copyright notice or any other identification of the University of Michigan is included in any copy of any portion of this software, then the disclaimer below must also be included. THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ------------------- The pkcs11.h file included in the PKINIT code has the following license: | Copyright 2006 g10 Code GmbH | Copyright 2006 Andreas Jellinghaus This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ------------------- Portions contributed by Apple Inc. are subject to the following license: Copyright 2004-2008 Apple Inc. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Apple Inc. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Apple Inc. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ------------------- The implementations of UTF-8 string handling in src/util/support and src/lib/krb5/unicode are subject to the following copyright and permission notice: | The OpenLDAP Public License | Version 2.8, 17 August 2003 Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met: 1. Redistributions in source form must retain copyright statements and notices, 2. Redistributions in binary form must reproduce applicable copyright statements and notices, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution, and 3. Redistributions must contain a verbatim copy of this document. The OpenLDAP Foundation may revise this license from time to time. Each revision is distinguished by a version number. You may use this Software under terms of this license revision or under the terms of any subsequent revision of the license. THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S) OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The names of the authors and copyright holders must not be used in advertising or otherwise to promote the sale, use or other dealing in this Software without specific, written prior permission. Title to copyright in this Software shall at all times remain with copyright holders. OpenLDAP is a registered trademark of the OpenLDAP Foundation. Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, California, USA. All Rights Reserved. Permission to copy and distribute verbatim copies of this document is granted. ------------------- Marked test programs in src/lib/krb5/krb have the following copyright: | Copyright |copy| 2006 Kungliga Tekniska Högskola | (Royal Institute of Technology, Stockholm, Sweden). | All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of KTH nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- The KCM Mach RPC definition file used on macOS has the following copyright: | Copyright |copy| 2009 Kungliga Tekniska Högskola | (Royal Institute of Technology, Stockholm, Sweden). | All rights reserved. Portions Copyright |copy| 2009 Apple Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- Portions of the RPC implementation in src/lib/rpc and src/include/gssrpc have the following copyright and permission notice: Copyright |copy| 2010, Oracle America, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the "Oracle America, Inc." nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- Copyright |copy| 2006,2007,2009 NTT (Nippon Telegraph and Telephone Corporation). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer as the first lines of this file unmodified. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY NTT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- Copyright 2000 by Carnegie Mellon University All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Carnegie Mellon University not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ------------------- Copyright |copy| 2002 Naval Research Laboratory (NRL/CCS) Permission to use, copy, modify and distribute this software and its documentation is hereby granted, provided that both the copyright notice and this permission notice appear in all copies of the software, derivative works or modified versions, and any portions thereof. NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ------------------- Copyright |copy| 2022 United States Government as represented by the Secretary of the Navy. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- Copyright |copy| 1991, 1992, 1994 by Cygnus Support. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Cygnus Support makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ------------------- Copyright |copy| 2006 Secure Endpoints Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------- Copyright |copy| 1994 by the University of Southern California EXPORT OF THIS SOFTWARE from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute this software and its documentation in source and binary forms is hereby granted, provided that any documentation or other materials related to such distribution or use acknowledge that the software was developed by the University of Southern California. DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The University of Southern California MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not limitation, the University of Southern California MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. The University of Southern California shall not be held liable for any liability nor for any direct, indirect, or consequential damages with respect to any claim by the user or distributor of the ksu software. ------------------- | Copyright |copy| 1995 | The President and Fellows of Harvard University This code is derived from software contributed to Harvard by Jeremy Rassen. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the University of California, Berkeley and its contributors. 4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- | Copyright |copy| 2008 by the Massachusetts Institute of Technology. | Copyright 1995 by Richard P. Basch. All Rights Reserved. | Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Richard P. Basch, Lehman Brothers and M.I.T. make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ------------------- The following notice applies to ``src/lib/krb5/krb/strptime.c`` and ``src/include/k5-queue.h``. | Copyright |copy| 1997, 1998 The NetBSD Foundation, Inc. | All rights reserved. This code was contributed to The NetBSD Foundation by Klaus Klein. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the NetBSD Foundation, Inc. and its contributors. 4. Neither the name of The NetBSD Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- The following notice applies to Unicode library files in ``src/lib/krb5/unicode``: | Copyright 1997, 1998, 1999 Computing Research Labs, | New Mexico State University Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------- The following notice applies to ``src/util/support/strlcpy.c``: Copyright |copy| 1998 Todd C. Miller ``Todd.Miller@courtesan.com`` Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ------------------- The following notice applies to ``src/util/profile/argv_parse.c`` and ``src/util/profile/argv_parse.h``: Copyright 1999 by Theodore Ts'o. Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't it sick that the U.S. culture of lawsuit-happy lawyers requires this kind of disclaimer?) ------------------- The following notice applies to portiions of ``src/lib/rpc`` and ``src/include/gssrpc``: Copyright |copy| 2000 The Regents of the University of Michigan. All rights reserved. Copyright |copy| 2000 Dug Song ``dugsong@UMICH.EDU``. All rights reserved, all wrongs reversed. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- Implementations of the MD4 algorithm are subject to the following notice: Copyright |copy| 1990, RSA Data Security, Inc. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD4 Message Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD4 Message Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. ------------------- Implementations of the MD5 algorithm are subject to the following notice: Copyright |copy| 1990, RSA Data Security, Inc. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message- Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. ------------------- The following notice applies to ``src/lib/crypto/crypto_tests/t_mddriver.c``: Copyright |copy| 1990-2, RSA Data Security, Inc. Created 1990. All rights reserved. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. ------------------- Portions of ``src/lib/krb5`` are subject to the following notice: | Copyright |copy| 1994 CyberSAFE Corporation. | Copyright 1990,1991,2007,2008 by the Massachusetts Institute of Technology. | All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. Neither M.I.T., the Open Computing Security Group, nor CyberSAFE Corporation make any representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ------------------- Portions contributed by PADL Software are subject to the following license: Copyright (c) 2011, PADL Software Pty Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of PADL Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- The bundled libev source code is subject to the following license: All files in libev are Copyright (C)2007,2008,2009 Marc Alexander Lehmann. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Alternatively, the contents of this package may be used under the terms of the GNU General Public License ("GPL") version 2 or any later version, in which case the provisions of the GPL are applicable instead of the above. If you wish to allow the use of your version of this package only under the terms of the GPL and not to allow others to use your version of this file under the BSD license, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL in this and the other files of this package. If you do not delete the provisions above, a recipient may use your version of this file under either the BSD or the GPL. ------------------- Files copied from the Intel AESNI Sample Library are subject to the following license: Copyright |copy| 2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- The following notice applies to ``src/ccapi/common/win/OldCC/autolock.hxx``: Copyright (C) 1998 by Danilo Almeida. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------- The following notice applies to portions of ``src/plugins/preauth/spake/edwards25519.c`` and ``src/plugins/preauth/spake/edwards25519_tables.h``: The MIT License (MIT) Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------- The following notice applies to portions of ``src/plugins/preauth/spake/edwards25519.c``: Copyright (c) 2015-2016, Google Inc. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ------------------- The following notice applies to files in ``src/tests/fuzzing``: Copyright (C) 2024 by Arjun. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. krb5-1.22.1/doc/resources.rst0000664000175000017500000000361015051422640015652 0ustar ghudsonghudsonResources ========= Mailing lists ------------- * kerberos@mit.edu is a community resource for discussion and questions about MIT krb5 and other Kerberos implementations. To subscribe to the list, please follow the instructions at https://mailman.mit.edu/mailman/listinfo/kerberos. * krbdev@mit.edu is the primary list for developers of MIT Kerberos. To subscribe to the list, please follow the instructions at https://mailman.mit.edu/mailman/listinfo/krbdev. * krb5-bugs@mit.edu is notified when a ticket is created or updated. This list helps track bugs and feature requests. In addition, this list is used to track documentation criticism and recommendations for improvements. * krbcore@mit.edu is a private list for the MIT krb5 core team. Send mail to this list if you need to contact the core team. * krbcore-security@mit.edu is the point of contact for security problems with MIT Kerberos. Please use PGP-encrypted mail to report possible vulnerabilities to this list. IRC channels ------------ The IRC channel `#kerberos` on libera.chat is a community resource for general Kerberos discussion and support. The main IRC channel for MIT Kerberos development is `#krbdev` on Libera Chat. For more information about Libera Chat, see https://libera.chat/. Archives -------- * The archive https://mailman.mit.edu/pipermail/kerberos/ contains past postings from the `kerberos@mit.edu` list. * The https://mailman.mit.edu/pipermail/krbdev/ contains past postings from the `krbdev@mit.edu` list. Wiki ---- The wiki at https://k5wiki.kerberos.org/ contains useful information for developers working on the MIT Kerberos source code. Some of the information on the wiki may be useful for advanced users or system administrators. Web pages --------- * https://web.mit.edu/kerberos/ is the MIT Kerberos software web page. * https://kerberos.org/ is the MIT Kerberos Consortium web page. krb5-1.22.1/doc/_templates/0000775000175000017500000000000015051422640015243 5ustar ghudsonghudsonkrb5-1.22.1/doc/_templates/layout.html0000664000175000017500000000516715051422640017457 0ustar ghudsonghudson{% extends "!layout.html" %} {% set rellinks = [('search', 'Enter search criteria', 'S', 'Search')] + rellinks + [('index', 'Full Table of Contents', 'C', 'Contents')] %} {# Add a "feedback" button to the rellinks #} {%- macro feedback_rellinks() %} {%- for rellink in rellinks|reverse %} {{ rellink[3] }}{{ reldelim2 }} {%- endfor %} feedback {%- endmacro %} {% block footer %}

{% endblock %} {% block header %}
{% if logo %} {% endif %} {% block headertitle %}

{{ shorttitle|e }}

{% endblock %}
{{ feedback_rellinks() }}
{% endblock %} {%- block sidebartoc %}

{{ _('On this page') }}

{{ toc }}

{{ _('Table of contents') }}

{{ toctree(collapse=true, maxdepth=3, titles_only=true, includehidden=false) }}

Full Table of Contents

{%- endblock %} {%- block sidebarsearch %}

{{ _('Search') }}

{%- endblock %} krb5-1.22.1/doc/kadm5-errmsg.txt0000664000175000017500000000474715051422640016161 0ustar ghudsonghudsonProposed approach for passing more detailed error messages across the kadm5 API: We've already got too many init functions and too many options. Multiplying the number of init functions isn't feasible. Create an (opaque to application) init-options type, create/destroy functions for it, set-creds/set-keytab/set-password functions, and a kadm5-init-with-options function. (Optional: Reimplement the current init functions as wrappers around these.) Add a set-context function which saves away in the init-options object a krb5_context to be used in the new server handle instead of creating a new one. (Destroying a server handle with such a "borrowed" krb5 context should probably not destroy the context.) Calls within the library should store any error messages in the context contained in the server handle. Error messages produced during initialization should also be stored in this context. The caller of these functions can use krb5_get_error_message to extract the text of the error message from the supplied context. Unless we determine it's safe, we should probably assert (for now) that each server handle must have a different context. (That's aside from the thread safety issues.) These contexts should have been created with kadm5_init_krb5_context, which will decide whether to look at the KDC config file depending on whether you're using the client-side or server-side version of the library. (Same as for kadmin vs kadmin.local.) Notes: * The existing API must continue to work, without changes. There is external code we need to continue to support. * We considered a variant where the application could retrieve the error message from the server handle using a new kadm5_get_error_message function. However, the initialization code is one likely place where the errors would occur (can't authenticate, etc), and in that case, there is no server handle from which to extract the context. A function to retrieve the library-created krb5_context from the server handle would have the same problem. Using a separate approach to deal with errors at initialization time, in combination with the above, might work. But we still wind up either creating the init-with-options interface or adding error-message-return variants of multiple existing init functions. To do: * Write up specifics (including function names -- the names used here aren't meant to be definitive) and discuss on krbdev. * Implement library part. * Change kadmin and kdc to use it. krb5-1.22.1/doc/plugindev/0000775000175000017500000000000015051422640015103 5ustar ghudsonghudsonkrb5-1.22.1/doc/plugindev/kdcpolicy.rst0000664000175000017500000000212615051422640017617 0ustar ghudsonghudson.. _kdcpolicy_plugin: KDC policy interface (kdcpolicy) ================================ The kdcpolicy interface was first introduced in release 1.16. It allows modules to veto otherwise valid AS and TGS requests or restrict the lifetime and renew time of the resulting ticket. For a detailed description of the kdcpolicy interface, see the header file ````. The optional **check_as** and **check_tgs** functions allow the module to perform access control. Additionally, a module can create and destroy module data with the **init** and **fini** methods. Module data objects last for the lifetime of the KDC process, and are provided to all other methods. The data has the type krb5_kdcpolicy_moddata, which should be cast to the appropriate internal type. kdcpolicy modules can optionally inspect principal entries. To do this, the module must also include ```` to gain access to the principal entry structure definition. As the KDB interface is explicitly not as stable as other public interfaces, modules which do this may not retain compatibility across releases. krb5-1.22.1/doc/plugindev/hostrealm.rst0000664000175000017500000000305515051422640017636 0ustar ghudsonghudson.. _hostrealm_plugin: Host-to-realm interface (hostrealm) =================================== The host-to-realm interface was first introduced in release 1.12. It allows modules to control the local mapping of hostnames to realm names as well as the default realm. For a detailed description of the hostrealm interface, see the header file ````. Although the mapping methods in the hostrealm interface return a list of one or more realms, only the first realm in the list is currently used by callers. Callers may begin using later responses in the future. Any mapping method may return KRB5_PLUGIN_NO_HANDLE to defer processing to a later module. A module can create and destroy per-library-context state objects using the **init** and **fini** methods. If the module does not need any state, it does not need to implement these methods. The optional **host_realm** method allows a module to determine authoritative realm mappings for a hostname. The first authoritative mapping is used in preference to KDC referrals when getting service credentials. The optional **fallback_realm** method allows a module to determine fallback mappings for a hostname. The first fallback mapping is tried if there is no authoritative mapping for a realm, and KDC referrals failed to produce a successful result. The optional **default_realm** method allows a module to determine the local default realm. If a module implements any of the above methods, it must also implement **free_list** to ensure that memory is allocated and deallocated consistently. krb5-1.22.1/doc/plugindev/gssapi.rst0000664000175000017500000001371415051422640017131 0ustar ghudsonghudsonGSSAPI mechanism interface ========================== The GSSAPI library in MIT krb5 can load mechanism modules to augment the set of built-in mechanisms. .. note: The GSSAPI loadable mechanism interface does not follow the normal conventions for MIT krb5 pluggable interfaces. A mechanism module is a Unix shared object or Windows DLL, built separately from the krb5 tree. Modules are loaded according to the GSS mechanism config files described in :ref:`gssapi_plugin_config`. For the most part, a GSSAPI mechanism module exports the same functions as would a GSSAPI implementation itself, with the same function signatures. The mechanism selection layer within the GSSAPI library (called the "mechglue") will dispatch calls from the application to the module if the module's mechanism is requested. If a module does not wish to implement a GSSAPI extension, it can simply refrain from exporting it, and the mechglue will fail gracefully if the application calls that function. The mechglue does not invoke a module's **gss_add_cred**, **gss_add_cred_from**, **gss_add_cred_impersonate_name**, or **gss_add_cred_with_password** function. A mechanism only needs to implement the "acquire" variants of those functions. A module does not need to coordinate its minor status codes with those of other mechanisms. If the mechglue detects conflicts, it will map the mechanism's status codes onto unique values, and then map them back again when **gss_display_status** is called. NegoEx modules -------------- Some Windows GSSAPI mechanisms can only be negotiated via a Microsoft extension to SPNEGO called NegoEx. Beginning with release 1.18, mechanism modules can support NegoEx as follows: * Implement the gssspi_query_meta_data(), gssspi_exchange_meta_data(), and gssspi_query_mechanism_info() SPIs declared in ````. * Implement gss_inquire_sec_context_by_oid() and answer the **GSS_C_INQ_NEGOEX_KEY** and **GSS_C_INQ_NEGOEX_VERIFY_KEY** OIDs to provide the checksum keys for outgoing and incoming checksums, respectively. The answer must be in two buffers: the first buffer contains the key contents, and the second buffer contains the key encryption type as a four-byte little-endian integer. By default, NegoEx mechanisms will not be directly negotiated via SPNEGO. If direct SPNEGO negotiation is required for interoperability, implement gss_inquire_attrs_for_mech() and assert the GSS_C_MA_NEGOEX_AND_SPNEGO attribute (along with any applicable RFC 5587 attributes). Interposer modules ------------------ The mechglue also supports a kind of loadable module, called an interposer module, which intercepts calls to existing mechanisms rather than implementing a new mechanism. An interposer module must export the symbol **gss_mech_interposer** with the following signature:: gss_OID_set gss_mech_interposer(gss_OID mech_type); This function is invoked with the OID of the interposer mechanism as specified in the mechanism config file, and returns a set of mechanism OIDs to be interposed. The returned OID set must have been created using the mechglue's gss_create_empty_oid_set and gss_add_oid_set_member functions. An interposer module must use the prefix ``gssi_`` for the GSSAPI functions it exports, instead of the prefix ``gss_``. In most cases, unexported ``gssi_`` functions will result in failure from their corresponding ``gss_`` calls. An interposer module can link against the GSSAPI library in order to make calls to the original mechanism. To do so, it must specify a special mechanism OID which is the concatention of the interposer's own OID byte string and the original mechanism's OID byte string. Functions that do not accept a mechanism argument directly require no special handling, with the following exceptions: Since **gss_accept_sec_context** does not accept a mechanism argument, an interposer mechanism must, in order to invoke the original mechanism's function, acquire a credential for the concatenated OID and pass that as the *verifier_cred_handle* parameter. Since **gss_import_name**, **gss_import_cred**, and **gss_import_sec_context** do not accept mechanism parameters, the SPI has been extended to include variants which do. This allows the interposer module to know which mechanism should be used to interpret the token. These functions have the following signatures:: OM_uint32 gssi_import_sec_context_by_mech(OM_uint32 *minor_status, gss_OID desired_mech, gss_buffer_t interprocess_token, gss_ctx_id_t *context_handle); OM_uint32 gssi_import_name_by_mech(OM_uint32 *minor_status, gss_OID mech_type, gss_buffer_t input_name_buffer, gss_OID input_name_type, gss_name_t output_name); OM_uint32 gssi_import_cred_by_mech(OM_uint32 *minor_status, gss_OID mech_type, gss_buffer_t token, gss_cred_id_t *cred_handle); To re-enter the original mechanism when importing tokens for the above functions, the interposer module must wrap the mechanism token in the mechglue's format, using the concatenated OID (except in **gss_import_name**). The mechglue token formats are: * For **gss_import_sec_context**, a four-byte OID length in big-endian order, followed by the concatenated OID, followed by the mechanism token. * For **gss_import_name**, the bytes 04 01, followed by a two-byte OID length in big-endian order, followed by the mechanism OID, followed by a four-byte token length in big-endian order, followed by the mechanism token. Unlike most uses of OIDs in the API, the mechanism OID encoding must include the DER tag and length for an object identifier (06 followed by the DER length of the OID byte string), and this prefix must be included in the two-byte OID length. input_name_type must also be set to GSS_C_NT_EXPORT_NAME. * For **gss_import_cred**, a four-byte OID length in big-endian order, followed by the concatenated OID, followed by a four-byte token length in big-endian order, followed by the mechanism token. This sequence may be repeated multiple times. krb5-1.22.1/doc/plugindev/kadm5_auth.rst0000664000175000017500000000332715051422640017664 0ustar ghudsonghudson.. _kadm5_auth_plugin: kadmin authorization interface (kadm5_auth) =========================================== The kadm5_auth interface (new in release 1.16) allows modules to determine whether a client principal is authorized to perform an operation in the kadmin protocol, and to apply restrictions to principal operations. For a detailed description of the kadm5_auth interface, see the header file ````. A module can create and destroy per-process state objects by implementing the **init** and **fini** methods. State objects have the type kadm5_auth_modinfo, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. The kadm5_auth interface has one method for each kadmin operation, with parameters specific to the operation. Each method can return either 0 to authorize access, KRB5_PLUGIN_NO_HANDLE to defer the decision to other modules, or another error (canonically EPERM) to authoritatively deny access. Access is granted if at least one module grants access and no module authoritatively denies access. The **addprinc** and **modprinc** methods can also impose restrictions on the principal operation by returning a ``struct kadm5_auth_restrictions`` object. The module should also implement the **free_restrictions** method if it dynamically allocates restrictions objects for principal operations. kadm5_auth modules can optionally inspect principal or policy objects. To do this, the module must also include ```` to gain access to the structure definitions for those objects. As the kadmin interface is explicitly not as stable as other public interfaces, modules which do this may not retain compatibility across releases. krb5-1.22.1/doc/plugindev/internal.rst0000664000175000017500000000231615051422640017453 0ustar ghudsonghudsonInternal pluggable interfaces ============================= Following are brief discussions of pluggable interfaces which have not yet been made public. These interfaces are functional, but the interfaces are likely to change in incompatible ways from release to release. In some cases, it may be necessary to copy header files from the krb5 source tree to use an internal interface. Use these with care, and expect to need to update your modules for each new release of MIT krb5. Kerberos database interface (KDB) --------------------------------- A KDB module implements a database back end for KDC principal and policy information, and can also control many aspects of KDC behavior. For a full description of the interface, see the header file ````. The KDB pluggable interface is often referred to as the DAL (Database Access Layer). Authorization data interface (authdata) --------------------------------------- The authdata interface allows a module to provide (from the KDC) or consume (in application servers) authorization data of types beyond those handled by the core MIT krb5 code base. The interface is defined in the header file ````, which is not installed by the build. krb5-1.22.1/doc/plugindev/general.rst0000664000175000017500000001172215051422640017255 0ustar ghudsonghudsonGeneral plugin concepts ======================= A krb5 dynamic plugin module is a Unix shared object or Windows DLL. Typically, the source code for a dynamic plugin module should live in its own project with a build system using automake_ and libtool_, or tools with similar functionality. A plugin module must define a specific symbol name, which depends on the pluggable interface and module name. For most pluggable interfaces, the exported symbol is a function named ``INTERFACE_MODULE_initvt``, where *INTERFACE* is the name of the pluggable interface and *MODULE* is the name of the module. For these interfaces, it is possible for one shared object or DLL to implement multiple plugin modules, either for the same pluggable interface or for different ones. For example, a shared object could implement both KDC and client preauthentication mechanisms, by exporting functions named ``kdcpreauth_mymech_initvt`` and ``clpreauth_mymech_initvt``. .. note: The profile, locate, and GSSAPI mechglue pluggable interfaces follow different conventions. See the documentation for those interfaces for details. The remainder of this section applies to pluggable interfaces which use the standard conventions. A plugin module implementation should include the header file ````, where *INTERFACE* is the name of the pluggable interface. For instance, a ccselect plugin module implementation should use ``#include ``. .. note: clpreauth and kdcpreauth module implementations should include . initvt functions have the following prototype:: krb5_error_code interface_modname_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); and should do the following: 1. Check that the supplied maj_ver argument is supported by the module. If it is not supported, the function should return KRB5_PLUGIN_VER_NOTSUPP. 2. Cast the supplied vtable pointer to the structure type corresponding to the major version, as documented in the pluggable interface header file. 3. Fill in the structure fields with pointers to method functions and static data, stopping at the field indicated by the supplied minor version. Fields for unimplemented optional methods can be left alone; it is not necessary to initialize them to NULL. In most cases, the context argument will not be used. The initvt function should not allocate memory; think of it as a glorified structure initializer. Each pluggable interface defines methods for allocating and freeing module state if doing so is necessary for the interface. Pluggable interfaces typically include a **name** field in the vtable structure, which should be filled in with a pointer to a string literal containing the module name. Here is an example of what an initvt function might look like for a fictional pluggable interface named fences, for a module named "wicker":: krb5_error_code fences_wicker_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_ccselect_vtable vt; if (maj_ver == 1) { krb5_fences_vtable vt = (krb5_fences_vtable)vtable; vt->name = "wicker"; vt->slats = wicker_slats; vt->braces = wicker_braces; } else if (maj_ver == 2) { krb5_fences_vtable_v2 vt = (krb5_fences_vtable_v2)vtable; vt->name = "wicker"; vt->material = wicker_material; vt->construction = wicker_construction; if (min_ver < 2) return 0; vt->footing = wicker_footing; if (min_ver < 3) return 0; vt->appearance = wicker_appearance; } else { return KRB5_PLUGIN_VER_NOTSUPP; } return 0; } Logging from KDC and kadmind plugin modules ------------------------------------------- Plugin modules for the KDC or kadmind daemons can write to the configured logging outputs (see :ref:`logging`) by calling the **com_err** function. The first argument (*whoami*) is ignored. If the second argument (*code*) is zero, the formatted message is logged at informational severity; otherwise, the formatted message is logged at error severity and includes the error message for the supplied code. Here are examples:: com_err("", 0, "Client message contains %d items", nitems); com_err("", retval, "while decoding client message"); (The behavior described above is new in release 1.17. In prior releases, the *whoami* argument is included for some logging output types, the logged message does not include the usual header for some output types, and the severity for syslog outputs is configured as part of the logging specification, defaulting to error severity.) .. _automake: https://www.gnu.org/software/automake/ .. _libtool: https://www.gnu.org/software/libtool/ krb5-1.22.1/doc/plugindev/clpreauth.rst0000664000175000017500000000513515051422640017630 0ustar ghudsonghudsonClient preauthentication interface (clpreauth) ============================================== During an initial ticket request, a KDC may ask a client to prove its knowledge of the password before issuing an encrypted ticket, or to use credentials other than a password. This process is called preauthentication, and is described in :rfc:`4120` and :rfc:`6113`. The clpreauth interface allows the addition of client support for preauthentication mechanisms beyond those included in the core MIT krb5 code base. For a detailed description of the clpreauth interface, see the header file ```` (or ```` before release 1.12). A clpreauth module is generally responsible for: * Supplying a list of preauth type numbers used by the module in the **pa_type_list** field of the vtable structure. * Indicating what kind of preauthentication mechanism it implements, with the **flags** method. In the most common case, this method just returns ``PA_REAL``, indicating that it implements a normal preauthentication type. * Examining the padata information included in a PREAUTH_REQUIRED or MORE_PREAUTH_DATA_REQUIRED error and producing padata values for the next AS request. This is done with the **process** method. * Examining the padata information included in a successful ticket reply, possibly verifying the KDC identity and computing a reply key. This is also done with the **process** method. * For preauthentication types which support it, recovering from errors by examining the error data from the KDC and producing a padata value for another AS request. This is done with the **tryagain** method. * Receiving option information (supplied by ``kinit -X`` or by an application), with the **gic_opts** method. A clpreauth module can create and destroy per-library-context and per-request state objects by implementing the **init**, **fini**, **request_init**, and **request_fini** methods. Per-context state objects have the type krb5_clpreauth_moddata, and per-request state objects have the type krb5_clpreauth_modreq. These are abstract pointer types; a module should typically cast these to internal types for the state objects. The **process** and **tryagain** methods have access to a callback function and handle (called a "rock") which can be used to get additional information about the current request, including the expected enctype of the AS reply, the FAST armor key, and the client long-term key (prompting for the user password if necessary). A callback can also be used to replace the AS reply key if the preauthentication mechanism computes one. krb5-1.22.1/doc/plugindev/locate.rst0000664000175000017500000000303215051422640017102 0ustar ghudsonghudsonServer location interface (locate) ================================== The locate interface allows modules to control how KDCs and similar services are located by clients. For a detailed description of the ccselect interface, see the header file ````. .. note: The locate interface does not follow the normal conventions for MIT krb5 pluggable interfaces, because it was made public before those conventions were established. A locate module exports a structure object of type krb5plugin_service_locate_ftable, with the name ``service_locator``. The structure contains a minor version and pointers to the module's methods. The primary locate method is **lookup**, which accepts a service type, realm name, desired socket type, and desired address family (which will be AF_UNSPEC if no specific address family is desired). The method should invoke the callback function once for each server address it wants to return, passing a socket type (SOCK_STREAM for TCP or SOCK_DGRAM for UDP) and socket address. The **lookup** method should return 0 if it has authoritatively determined the server addresses for the realm, KRB5_PLUGIN_NO_HANDLE if it wants to let other location mechanisms determine the server addresses, or another code if it experienced a failure which should abort the location process. A module can create and destroy per-library-context state objects by implementing the **init** and **fini** methods. State objects have the type void \*, and should be cast to an internal type for the state object. krb5-1.22.1/doc/plugindev/certauth.rst0000664000175000017500000000336015051422640017456 0ustar ghudsonghudson.. _certauth_plugin: PKINIT certificate authorization interface (certauth) ===================================================== The certauth interface was first introduced in release 1.16. It allows customization of the X.509 certificate attribute requirements placed on certificates used by PKINIT enabled clients. For a detailed description of the certauth interface, see the header file ```` A certauth module implements the **authorize** method to determine whether a client's certificate is authorized to authenticate a client principal. **authorize** receives the DER-encoded certificate, the requested client principal, and a pointer to the client's krb5_db_entry (for modules that link against libkdb5). The method must decode the certificate and inspect its attributes to determine if it should authorize PKINIT authentication. It returns the authorization status and optionally outputs a list of authentication indicator strings to be added to the ticket. Beginning in release 1.19, the authorize method can request that the hardware authentication bit be set in the ticket by returning **KRB5_CERTAUTH_HWAUTH**. Beginning in release 1.20, the authorize method can return **KRB5_CERTAUTH_HWAUTH_PASS** to request that the hardware authentication bit be set in the ticket but otherwise defer authorization to another certauth module. A module must use its own internal or library-provided ASN.1 certificate decoder. A module can optionally create and destroy module data with the **init** and **fini** methods. Module data objects last for the lifetime of the KDC process. If a module allocates and returns a list of authentication indicators from **authorize**, it must also implement the **free_ind** method to free the list. krb5-1.22.1/doc/plugindev/ccselect.rst0000664000175000017500000000236515051422640017430 0ustar ghudsonghudson.. _ccselect_plugin: Credential cache selection interface (ccselect) =============================================== The ccselect interface allows modules to control how credential caches are chosen when a GSSAPI client contacts a service. For a detailed description of the ccselect interface, see the header file ````. The primary ccselect method is **choose**, which accepts a server principal as input and returns a ccache and/or principal name as output. A module can use the krb5_cccol APIs to iterate over the cache collection in order to find an appropriate ccache to use. .. TODO: add reference to the admin guide for ccaches and cache collections when we have appropriate sections. A module can create and destroy per-library-context state objects by implementing the **init** and **fini** methods. State objects have the type krb5_ccselect_moddata, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. A module can have one of two priorities, "authoritative" or "heuristic". Results from authoritative modules, if any are available, will take priority over results from heuristic modules. A module communicates its priority as a result of the **init** method. krb5-1.22.1/doc/plugindev/localauth.rst0000664000175000017500000000406215051422640017613 0ustar ghudsonghudson.. _localauth_plugin: Local authorization interface (localauth) ========================================= The localauth interface was first introduced in release 1.12. It allows modules to control the relationship between Kerberos principals and local system accounts. When an application calls :c:func:`krb5_kuserok` or :c:func:`krb5_aname_to_localname`, localauth modules are consulted to determine the result. For a detailed description of the localauth interface, see the header file ````. A module can create and destroy per-library-context state objects using the **init** and **fini** methods. If the module does not need any state, it does not need to implement these methods. The optional **userok** method allows a module to control the behavior of :c:func:`krb5_kuserok`. The module receives the authenticated name and the local account name as inputs, and can return either 0 to authorize access, KRB5_PLUGIN_NO_HANDLE to defer the decision to other modules, or another error (canonically EPERM) to authoritatively deny access. Access is granted if at least one module grants access and no module authoritatively denies access. The optional **an2ln** method can work in two different ways. If the module sets an array of uppercase type names in **an2ln_types**, then the module's **an2ln** method will only be invoked by :c:func:`krb5_aname_to_localname` if an **auth_to_local** value in :ref:`krb5.conf(5)` refers to one of the module's types. In this case, the *type* and *residual* arguments will give the type name and residual string of the **auth_to_local** value. If the module does not set **an2ln_types** but does implement **an2ln**, the module's **an2ln** method will be invoked for all :c:func:`krb5_aname_to_localname` operations unless an earlier module determines a mapping, with *type* and *residual* set to NULL. The module can return KRB5_LNAME_NO_TRANS to defer mapping to later modules. If a module implements **an2ln**, it must also implement **free_string** to ensure that memory is allocated and deallocated consistently. krb5-1.22.1/doc/plugindev/profile.rst0000664000175000017500000000717615051422640017310 0ustar ghudsonghudson.. _profile_plugin: Configuration interface (profile) ================================= The profile interface allows a module to control how krb5 configuration information is obtained by the Kerberos library and applications. For a detailed description of the profile interface, see the header file ````. .. note:: The profile interface does not follow the normal conventions for MIT krb5 pluggable interfaces, because it is part of a lower-level component of the krb5 library. As with other types of plugin modules, a profile module is a Unix shared object or Windows DLL, built separately from the krb5 tree. The krb5 library will dynamically load and use a profile plugin module if it reads a ``module`` directive at the beginning of krb5.conf, as described in :ref:`profile_plugin_config`. A profile module exports a function named ``profile_module_init`` matching the signature of the profile_module_init_fn type. This function accepts a residual string, which may be used to help locate the configuration source. The function fills in a vtable and may also create a per-profile state object. If the module uses state objects, it should implement the **copy** and **cleanup** methods to manage them. A basic read-only profile module need only implement the **get_values** and **free_values** methods. The **get_values** method accepts a null-terminated list of C string names (e.g., an array containing "libdefaults", "clockskew", and NULL for the **clockskew** variable in the :ref:`libdefaults` section) and returns a null-terminated list of values, which will be cleaned up with the **free_values** method when the caller is done with them. Iterable profile modules must also define the **iterator_create**, **iterator**, **iterator_free**, and **free_string** methods. The core krb5 code does not require profiles to be iterable, but some applications may iterate over the krb5 profile object in order to present configuration interfaces. Writable profile modules must also define the **writable**, **modified**, **update_relation**, **rename_section**, **add_relation**, and **flush** methods. The core krb5 code does not require profiles to be writable, but some applications may write to the krb5 profile in order to present configuration interfaces. The following is an example of a very basic read-only profile module which returns a hardcoded value for the **default_realm** variable in :ref:`libdefaults`, and provides no other configuration information. (For conciseness, the example omits code for checking the return values of malloc and strdup.) :: #include #include #include static long get_values(void *cbdata, const char *const *names, char ***values) { if (names[0] != NULL && strcmp(names[0], "libdefaults") == 0 && names[1] != NULL && strcmp(names[1], "default_realm") == 0) { *values = malloc(2 * sizeof(char *)); (*values)[0] = strdup("ATHENA.MIT.EDU"); (*values)[1] = NULL; return 0; } return PROF_NO_RELATION; } static void free_values(void *cbdata, char **values) { char **v; for (v = values; *v; v++) free(*v); free(values); } long profile_module_init(const char *residual, struct profile_vtable *vtable, void **cb_ret); long profile_module_init(const char *residual, struct profile_vtable *vtable, void **cb_ret) { *cb_ret = NULL; vtable->get_values = get_values; vtable->free_values = free_values; return 0; } krb5-1.22.1/doc/plugindev/pwqual.rst0000664000175000017500000000233315051422640017147 0ustar ghudsonghudson.. _pwqual_plugin: Password quality interface (pwqual) =================================== The pwqual interface allows modules to control what passwords are allowed when a user changes passwords. For a detailed description of the pwqual interface, see the header file ````. The primary pwqual method is **check**, which receives a password as input and returns success (0) or a ``KADM5_PASS_Q_`` failure code depending on whether the password is allowed. The **check** method also receives the principal name and the name of the principal's password policy as input; although there is no stable interface for the module to obtain the fields of the password policy, it can define its own configuration or data store based on the policy name. A module can create and destroy per-process state objects by implementing the **open** and **close** methods. State objects have the type krb5_pwqual_moddata, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. The **open** method also receives the name of the realm's dictionary file (as configured by the **dict_file** variable in the :ref:`kdc_realms` section of :ref:`kdc.conf(5)`) if it wishes to use it. krb5-1.22.1/doc/plugindev/kadm5_hook.rst0000664000175000017500000000231415051422640017656 0ustar ghudsonghudson.. _kadm5_hook_plugin: KADM5 hook interface (kadm5_hook) ================================= The kadm5_hook interface allows modules to perform actions when changes are made to the Kerberos database through :ref:`kadmin(1)`. For a detailed description of the kadm5_hook interface, see the header file ````. The kadm5_hook interface has five primary methods: **chpass**, **create**, **modify**, **remove**, and **rename**. (The **rename** method was introduced in release 1.14.) Each of these methods is called twice when the corresponding administrative action takes place, once before the action is committed and once afterwards. A module can prevent the action from taking place by returning an error code during the pre-commit stage. A module can create and destroy per-process state objects by implementing the **init** and **fini** methods. State objects have the type kadm5_hook_modinfo, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. Because the kadm5_hook interface is tied closely to the kadmin interface (which is explicitly unstable), it may not remain as stable across versions as other public pluggable interfaces. krb5-1.22.1/doc/plugindev/index.rst0000664000175000017500000000152515051422640016747 0ustar ghudsonghudsonFor plugin module developers ============================ Kerberos plugin modules allow increased control over MIT krb5 library and server behavior. This guide describes how to create dynamic plugin modules and the currently available pluggable interfaces. See :ref:`plugin_config` for information on how to register dynamic plugin modules and how to enable and disable modules via :ref:`krb5.conf(5)`. .. TODO: update the above reference when we have a free-form section in the admin guide about plugin configuration Contents -------- .. toctree:: :maxdepth: 2 general.rst clpreauth.rst kdcpreauth.rst ccselect.rst pwqual.rst kadm5_hook.rst kadm5_auth.rst hostrealm.rst localauth.rst locate.rst profile.rst gssapi.rst internal.rst certauth.rst kdcpolicy.rst .. TODO: GSSAPI mechanism plugins krb5-1.22.1/doc/plugindev/kdcpreauth.rst0000664000175000017500000000760615051422640020000 0ustar ghudsonghudsonKDC preauthentication interface (kdcpreauth) ============================================ The kdcpreauth interface allows the addition of KDC support for preauthentication mechanisms beyond those included in the core MIT krb5 code base. For a detailed description of the kdcpreauth interface, see the header file ```` (or ```` before release 1.12). A kdcpreauth module is generally responsible for: * Supplying a list of preauth type numbers used by the module in the **pa_type_list** field of the vtable structure. * Indicating what kind of preauthentication mechanism it implements, with the **flags** method. If the mechanism computes a new reply key, it must specify the ``PA_REPLACES_KEY`` flag. If the mechanism is generally only used with hardware tokens, the ``PA_HARDWARE`` flag allows the mechanism to work with principals which have the **requires_hwauth** flag set. * Producing a padata value to be sent with a preauth_required error, with the **edata** method. * Examining a padata value sent by a client and verifying that it proves knowledge of the appropriate client credential information. This is done with the **verify** method. * Producing a padata response value for the client, and possibly computing a reply key. This is done with the **return_padata** method. A module can create and destroy per-KDC state objects by implementing the **init** and **fini** methods. Per-KDC state objects have the type krb5_kdcpreauth_moddata, which is an abstract pointer types. A module should typically cast this to an internal type for the state object. A module can create a per-request state object by returning one in the **verify** method, receiving it in the **return_padata** method, and destroying it in the **free_modreq** method. Note that these state objects only apply to the processing of a single AS request packet, not to an entire authentication exchange (since an authentication exchange may remain unfinished by the client or may involve multiple different KDC hosts). Per-request state objects have the type krb5_kdcpreauth_modreq, which is an abstract pointer type. The **edata**, **verify**, and **return_padata** methods have access to a callback function and handle (called a "rock") which can be used to get additional information about the current request, including the maximum allowable clock skew, the client's long-term keys, the DER-encoded request body, the FAST armor key, string attributes on the client's database entry, and the client's database entry itself. The **verify** method can assert one or more authentication indicators to be included in the issued ticket using the ``add_auth_indicator`` callback (new in release 1.14). A module can generate state information to be included with the next client request using the ``set_cookie`` callback (new in release 1.14). On the next request, the module can read this state information using the ``get_cookie`` callback. Cookie information is encrypted, timestamped, and transmitted to the client in a ``PA-FX-COOKIE`` pa-data item. Older clients may not support cookies and therefore may not transmit the cookie in the next request; in this case, ``get_cookie`` will not yield the saved information. If a module implements a mechanism which requires multiple round trips, its **verify** method can respond with the code ``KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED`` and a list of pa-data in the *e_data* parameter to be processed by the client. The **edata** and **verify** methods can be implemented asynchronously. Because of this, they do not return values directly to the caller, but must instead invoke responder functions with their results. A synchronous implementation can invoke the responder function immediately. An asynchronous implementation can use the callback to get an event context for use with the libverto_ API. .. _libverto: https://fedorahosted.org/libverto/ krb5-1.22.1/doc/coding-style0000664000175000017500000000013515051422640015431 0ustar ghudsonghudsonPlease see https://k5wiki.kerberos.org/wiki/Coding_style for the current coding style. krb5-1.22.1/doc/kadm5/0000775000175000017500000000000015051422640014107 5ustar ghudsonghudsonkrb5-1.22.1/doc/kadm5/api-funcspec.tex0000664000175000017500000023606615051422640017223 0ustar ghudsonghudson% This document is included for historical purposes only, and does not % apply to krb5 today. \documentstyle[12pt,fullpage]{article} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Make _ actually generate an _, and allow line-breaking after it. \let\underscore=\_ \catcode`_=13 \def_{\underscore\penalty75\relax} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \setlength{\parskip}{.7\baselineskip} \setlength{\parindent}{0pt} \def\v#1{\verb+#1+} \title{Kerberos Administration System \\ KADM5 API Functional Specifications} \author{Barry Jaspan} \begin{document} \sloppy \maketitle {\setlength{\parskip}{0pt}\tableofcontents} \section{Introduction} This document describes the Admin API that can be used to maintain principals and policies. It describes the data structures used for each function and the interpretation of each data type field, the semantics of each API function, and the possible return codes. The Admin API is intended to be used by remote clients using an RPC interface. It is implemented by the admin server running on the Kerberos master server. It is also possible for a program running on the Kerberos master server to use the Admin API directly, without going through the admin server. \section{Versions of the API} The versions of this API and a brief description of the changes for each are: \begin{description} \item[KADM5_API_VERSION_1] The initial version of this API, written by OpenVision Technologies and donated to MIT for including in the public release. Originally called OVSEC_KADM_API_VERSION_1. Most everything has been renamed in one way or another, including functions, header files, and data structures. Where possible, the old OVSEC_KADM names have been left behind for compatibility with version 1, and KADM5_API_VERSION_1 is compatible with OVSEC_KADM_API_VERSION_1 at compile-, link-, and run-time. The OVSEC_KADM name compatibility will not be extended to new functionality in future versions because no existing OVSEC_KADM clients will use that functionality; new clients should be written to the KADM5 API. \item[KADM5_API_VERSION_2] This version contains the initial changes necessary to make the OpenVision administration system work with the mid-1996 MIT version of Kerberos 5. Changes include \begin{enumerate} \item The kadm5_init functions now take a structure of parameters instead of just a realm name, allowing the calling program to specify non-default values for various configuration options. See section \ref{sec:configparams} for details. \item The KADM5 API has been extended to support new features of the Kerberos database, including multiple encryption and salt types per principal. See section \ref{sec:keys} for details. \item kadm5_get_principal now allows a principal's keys to be retrieved {\it by local clients only}. This is necessary in order for the kadm5 API to provide the primary Kerberos database interface. \item The KADM5 authorization system has been completely changed. \item The functions kadm5_flush, kadm5_get_principals, and kadm5_get_policies have been added. \item The KADM5 API now obeys a caller-allocates rather than callee-allocates system. kadm5_get_principal and kadm5_get_policy are affected. \end{enumerate} \end{description} \section{Policies and Password Quality} The Admin API Password Quality mechanism provides the following controls. Note that two strings are defined to be ``significantly different'' if they differ by at least one character. The compare is not case sensitive. \begin{itemize} \item A minimum length can be required; a password with fewer than the specified number of characters will not be accepted. \item A minimum number of character classes can be required; a password that does not contain at least one character from at least the specified number of character classes will not be accepted. The character classes are defined by islower(), isupper(), isdigit(), ispunct(), and other. \item Passwords can be required to be different from previous passwords; a password that generates the same encryption key as any of the principal's specified previous number of passwords will not be accepted. This comparison is performed on the encryption keys generated from the passwords, not on the passwords themselves. \item A single ``forbidden password'' dictionary can be specified for all users; a password that is not significantly different from every word in the dictionary will not be accepted. \end{itemize} \section{Data Structures} This section describes the data structures used by the Admin API. They are defined in $<$kadm5/admin.h$>$. \subsection{Principals, kadm5_principal_ent_t} \label{sec:principal-structure} A Kerberos principal entry is represented by a kadm5_principal_ent_t. It contains a subset of the information stored in the master Kerberos database as well as the additional information maintained by the admin system. In the current version, the only additional information is the principal's policy and the aux_attributes flags. The principal may or may not have a policy enforced on it. If the POLICY bit (see section \ref{sec:masks}) is set in aux_attributes, the policy field names the principal's policy. If the POLICY bit is not set in aux_attributes, no policy is enforced on the principal and the value of the policy field is undefined. \begin{figure}[htbp] \begin{verbatim} typedef struct _kadm5_principal_ent_t { krb5_principal principal; krb5_timestamp princ_expire_time; krb5_timestamp last_pwd_change; krb5_timestamp pw_expiration; krb5_deltat max_life; krb5_principal mod_name; krb5_timestamp mod_date; krb5_flags attributes; krb5_kvno kvno; krb5_kvno mkvno; char * policy; u_int32 aux_attributes; krb5_deltat max_renewable_life; krb5_timestamp last_success; krb5_timestamp last_failed; krb5_kvno fail_auth_count; krb5_int16 n_key_data; krb5_int16 n_tl_data; krb5_tl_data *tl_data; krb5_key_data *key_data; } kadm5_principal_ent_rec, *kadm5_principal_ent_t; \end{verbatim} \caption{Definition of kadm5_principal_ent_t.} \label{fig:princ-t} \end{figure} The fields of an kadm5_principal_ent_t are interpreted as follows. \begin{description} \item[principal] The name of the principal; must conform to Kerberos naming specifications. \item[princ_expire_time] The expire time of the principal as a Kerberos timestamp. No Kerberos tickets will be issued for a principal after its expire time. \item[last_pwd_change] The time this principal's password was last changed, as a Kerberos timestamp. \item[pw_expiration] The expire time of the user's current password, as a Kerberos timestamp. No application service tickets will be issued for the principal once the password expire time has passed. Note that the user can only obtain tickets for services that have the PW_CHANGE_SERVICE bit set in the attributes field. \item[max_life] The maximum lifetime of any Kerberos ticket issued to this principal. \item[attributes] A bitfield of attributes for use by the KDC. The symbols and constant values are defined below; their interpretation appears in the libkdb functional specification. \begin{tabular}{clr} {\bf Name} & {\bf Value} \\ KRB5_KDB_DISALLOW_POSTDATED & 0x00000001 \\ KRB5_KDB_DISALLOW_FORWARDABLE & 0x00000002 \\ KRB5_KDB_DISALLOW_TGT_BASED & 0x00000004 \\ KRB5_KDB_DISALLOW_RENEWABLE & 0x00000008 \\ KRB5_KDB_DISALLOW_PROXIABLE & 0x00000010 \\ KRB5_KDB_DISALLOW_DUP_SKEY & 0x00000020 \\ KRB5_KDB_DISALLOW_ALL_TIX & 0x00000040 \\ KRB5_KDB_REQUIRES_PRE_AUTH & 0x00000080 \\ KRB5_KDB_REQUIRES_HW_AUTH & 0x00000100 \\ KRB5_KDB_REQUIRES_PWCHANGE & 0x00000200 \\ KRB5_KDB_DISALLOW_SVR & 0x00001000 \\ KRB5_KDB_PWCHANGE_SERVICE & 0x00002000 \\ KRB5_KDB_SUPPORT_DESMD5 & 0x00004000 \\ KRB5_KDB_NEW_PRINC & 0x00008000 \end{tabular} \item[mod_name] The name of the Kerberos principal that most recently modified this principal. \item[mod_date] The time this principal was last modified, as a Kerberos timestamp. \item[kvno] The version of the principal's current key. \item[mkvno] The version of the Kerberos Master Key in effect when this principal's key was last changed. In KADM5_API_VERSION_2, this field is always zero. \item[policy] If the POLICY bit is set in aux_attributes, the name of the policy controlling this principal. \item[aux_attributes] A bitfield of flags for use by the administration system. Currently, the only valid flag is POLICY, and it indicates whether or not the principal has a policy enforced on it. \item[max_renewable_life] The maximum renewable lifetime of any Kerberos ticket issued to or for this principal. This field only exists in KADM5_API_VERSION_2. \item[last_success] The KDC time of the last successful AS_REQ. This is only updated if KRBCONF_KDC_MODIFIES_KDB is defined during compilation of the KDC. This field only exists in KADM5_API_VERSION_2. \item[last_failed] The KDC time of the last failed AS_REQ. This is only updated if KRBCONF_KDC_MODIFIES_KDB is defined during compilation of the KDC. This field only exists in KADM5_API_VERSION_2. \item[fail_auth_count] The number of consecutive failed AS_REQs. When this number reaches KRB5_MAX_FAIL_COUNT, the KRB5_KDC_DISALLOW_ALL_TIX is set on the principal. This is only updated if KRBCONF_KDC_MODIFIES_KDB is defined during compilation. This field only exists in KADM5_API_VERSION_2. \item[n_tl_data] The number of elements in the \v{tl_data} linked list. This field only exists in KADM5_API_VERSION_2. \item[n_key_data] The number of elements in the \v{key_data} array. This field only exists in KADM5_API_VERSION_2. \item[tl_data] A linked list of tagged data. This list is a mechanism by which programs can store extended information in a principal entry, without having to modify the database API. Each element is of type krb5_tl_data: \begin{verbatim} typedef struct _krb5_tl_data { struct _krb5_tl_data* tl_data_next; krb5_int16 tl_data_type; krb5_int16 tl_data_length; krb5_octet * tl_data_contents; } krb5_tl_data; \end{verbatim} % The KADM5 API only allows elements whose tl_data_type is greater than or equal to 256. Values less than 256 are reserved for internal use by the KADM5 or kdb system. They are filtered out of the list returned by kadm5_get_principal, and generate an error if given to kadm5_modify_principal. The libkdb library defines the tagged data types KRB5_TL_LAST_PWD_CHANGE, KRB5_TL_MOD_PRINC, and KRB5_TL_KADM_DATA, all with values less than 256, which store the last password modification time, time and modifier of last principal modification, and administration system data. All of these entries are expected by the administration system and parsed out into fields of the kadm5_principal_ent_rec structure; as described above, they are not included in the tl_data list. Tagged data elements with types greater than 256 are handled without interpretation by KADM5. Note that an application that calls kadm5_modify_principal with the KADM5_TL_DATA mask bit set is responsible for providing the {\it complete} tl_data list, which it necessarily must obtain from kadm5_get_principal. It is {\it never} possible for an application to construct a complete tl_data list from scratch. \item[key_data] An array of the principal's keys. The keys contained in this array are encrypted in the Kerberos master key. See section \ref{sec:keys} for a discussion of the krb5_key_data structure. \end{description} \subsection{Policies, kadm5_policy_ent_t} \label{sec:policy-fields} If the POLICY bit is set in aux_attributes, the \v{policy} name field in the kadm5_principal_ent_t structure refers to a password policy entry defined in a \v{kadm5_policy_ent_t}. \begin{verbatim} typedef struct _kadm5_policy_ent_t { char *policy; u_int32 pw_min_life; u_int32 pw_max_life; u_int32 pw_min_length; u_int32 pw_min_classes; u_int32 pw_history_num; u_int32 policy_refcnt; } kadm5_policy_ent_rec, *kadm5_policy_ent_t; \end{verbatim} The fields of an kadm5_policy_ent_t are interpreted as follows. Note that a policy's values only apply to a principal using that policy. \begin{description} \item[policy] The name of this policy, as a NULL-terminated string. The ASCII characters between 32 (space) and 126 (tilde), inclusive, are legal. \item[pw_min_life] The minimum password lifetime, in seconds. A principal cannot change its password before pw_min_life seconds have passed since last_pwd_change. \item[pw_max_life] The default duration, in seconds, used to compute pw_expiration when a principal's password is changed. \item[pw_min_length] The minimum password length, in characters. A principal cannot set its password to anything with fewer than this number of characters. This value must be greater than zero. \item[pw_min_classes] The minimum number of character classes in the password. This value can only be 1, 2, 3, 4, or 5. A principal cannot set its password to anything with fewer than this number of character classes in it. \item[pw_history_num] The number of past passwords that are stored for the principal; the minimum value is 1 and the maximum value is 10. A principal cannot set its password to any of its previous pw_history_num passwords. The first ``previous'' password is the current password; thus, a principal with a policy can never reset its password to its current value. \item[policy_refcnt] The number of principals currently using this policy. A policy cannot be deleted unless this number is zero. \end{description} \subsection{Configuration parameters} \label{sec:configparams} The KADM5 API acquires configuration information from the Kerberos configuration file (\$KRB5_CONFIG or DEFAULT_PROFILE_PATH) and from the KDC configuration file (\$KRB5_KDC_CONFIG or DEFAULT_KDC_PROFILE). In KADM5_API_VERSION_2, some of the configuration parameters used by the KADM5 API can be controlled by the caller by providing a kadm5_config_params structure to kadm5_init: % \begin{verbatim} typedef struct _kadm5_config_params { u_int32 mask; /* Client and server fields */ char *realm; char *profile; int kadmind_port; /* client fields */ char *admin_server; /* server fields */ char *dbname; char *admin_dbname; char *admin_lockfile; char *acl_file; char *dict_file; char *admin_keytab; /* server library (database) fields */ int mkey_from_kbd; char *stash_file; char *mkey_name; krb5_enctype enctype; krb5_deltat max_life; krb5_deltat max_rlife; krb5_timestamp expiration; krb5_flags flags; krb5_key_salt_tuple *keysalts; krb5_int32 num_keysalts; } kadm5_config_params; \end{verbatim} % The following list describes each of the fields of the structure, along with the profile relation it overrides, its mask value, its default value, and whether it is valid on the client, server, or both, or neither. \begin{description} \item[mask] No variable. No mask value. A bitfield specifying which fields of the structure contain valid information. A caller sets this mask before calling kadm5_init_*, indicating which parameters are specified. The mask values are defined in $<$kadm5/admin.h$>$ and are all prefixed with KADM5_CONFIG_; the prefix is not included in the descriptions below. \item[realm] No variable. REALM. Client and server. The realm to which these parameters apply, and the realm for which additional parameters are to be acquired, if any. If this field is not specified in the mask, the default local realm is used. \item[profile] Variable: profile (server only). PROFILE. Client and server. The Kerberos profile to use. On the client, the default is the value of the KRB5_CONFIG environment variable, or DEFAULT_PROFILE_PATH if that is not set. On the server, the value of the ``profile'' variable of the KDC configuration file will be used as the first default if it exists; otherwise, the default is the value of the KRB5_KDC_PROFILE environment variable or DEFAULT_KDC_PROFILE. \item[kadmind_port] Variable: kadmind_port. KADMIND_PORT. Client and server. The port number the kadmind server listens on. The client uses this field to determine where to connect, and the server to determine where to listen. The default is 749, which has been assigned by IANA. \item[admin_server] Variable: admin_server. ADMIN_SERVER. Client. The host name of the admin server to which to connect. There is no default. If the value of this field contains a colon (:), the text following the colon is treated as an integer and assigned to the kadmind_port field, overriding any value of the kadmind_port variable. \item[dbname] Variable: dbname. DBNAME. Server. The Kerberos database name to use; the Kerberos database stores principal information. The default is DEFAULT_KDB_FILE. \item[admin_dbname] Variable: admin_database_name. ADBNAME. Neither. If the dbname field is set, this field is set to the value of dbname followed by ``.kadm5''. \item[admin_lockfile] Variable: admin_database_lockfile. ADB_LOCKFILE. Neither. If the admin_dbname field is set, this field is set to the value of admin_dbname followed by ``.lock''. \item[acl_file] Variable: acl_file. ACL_FILE. Server. The admin server's ACL file. The default is DEFAULT_KADM5_ACL_FILE. \item[dict_file] Variable: admin_dict_file. DICT_FILE. Server. The admin server's dictionary file of passwords to disallow. No default. \item[admin_keytab] Variable: admin_keytab. ADMIN_KEYTAB. Server. The keytab file containing the kadmin/admin and kadmin/changepw entries for the server to use. The default is the value of the KRB5_KTNAME environment variable, if defined, else DEFAULT_KADM5_KEYTAB. \item[mkey_from_keyboard] No variable. MKEY_FROM_KEYBOARD. Server. If non-zero, prompt for the master password via the tty instead of using the stash file. If this mask bit is not set, or is set and the value is zero, the stash file is used. \item[stash_file] Variable: key_stash_file. STASH_FILE. Server. The file name containing the master key stash file. No default; libkdb will work with a NULL value. \item[mkey_name] Variable: master_key_name. MKEY_NAME. Server. The name of the master principal for the realm. No default; lbkdb will work with a NULL value. \item[enctype] Variable: master_key_type. ENCTYPE. Server. The encryption type of the master principal. The default is DEFAULT_KDC_ENCTYPE. \item[max_life] Variable: max_life. MAX_LIFE. Maximum lifetime for all tickets issued to the principal. The default is 28800, which is 8 hours. \item[max_rlife, expiration, flags] Variables: max_renewable_life, default_principal_expiration, default_principal_flags. MAX_LIFE, MAX_RLIFE, EXPIRATION, FLAGS. Server. Default values for new principals. All default to 0. \item[keysalts, num_keysalts] Variable: supported_enctypes. ENCTYPES. Server. The list of supported encryption type/salt type tuples; both fields must be assigned if ENCTYPES is set. The default is a list containing one enctype, DES-CBC-CRC with normal salt. \end{description} \subsection{Principal keys} \label{sec:keys} In KADM5_API_VERSION_1, all principals had a single key. The encryption method was always DES, and the salt type was determined outside the API (by command-line options to the administration server). In KADM5_API_VERSION_2, principals can have multiple keys, each with its own encryption type and salt. Each time a principal's key is changed with kadm5_create_principal, kadm5_chpass_principal or kadm5_randkey_principal, existing key entries are removed and a key entry for each encryption and salt type tuple specified in the configuration parameters is added. There is no provision for specifying encryption and salt type information on a per-principal basis; in a future version, this will probably be part of the admin policy. There is also presently no provision for keeping multiple key versions for a single principal active in the database. A single key is represented by a krb5_key_data: % \begin{verbatim} typedef struct _krb5_key_data { krb5_int16 key_data_ver; /* Version */ krb5_int16 key_data_kvno; /* Key Version */ krb5_int16 key_data_type[2]; /* Array of types */ krb5_int16 key_data_length[2]; /* Array of lengths */ krb5_octet * key_data_contents[2]; /* Array of pointers */ } krb5_key_data; \end{verbatim} % \begin{description} \item[key_data_ver] The version number of the structure. Versions 1 and 2 are currently defined. If key_data_ver is 1 then the key is either a random key (not requiring a salt) or the salt is the normal v5 salt which is the same as the realm and therefore doesn't need to be saved in the database. \item[key_data_kvno] The key version number of this key. \item[key_data_type] The first element is the enctype of this key. In a version 2 structure, the second element is the salttype of this key. The legal encryption types are defined in $<$krb5.h$>$. The legal salt types are defined in $<$k5-int.h$>$. \item[key_data_length] The first element is length this key. In a version 2 structure, the second element is length of the salt for this key. \item[key_data_contents] The first element is the content of this key. In a version 2 structure, the second element is the contents of the salt for this key. \end{description} \subsection{Field masks} \label{sec:masks} The API functions for creating, retrieving, and modifying principals and policies allow for a relevant subset of the fields of the kadm5_principal_ent_t and kadm5_policy_ent_t to be specified or changed. The chosen fields are determined by a bitmask that is passed to the relevant function. Each API function has different rules for which mask values can be specified, and can specify whether a given mask value is mandatory, optional, or forbidden. Mandatory fields must be present and forbidden fields must not be present or an error is generated. When creating a principal or policy, optional fields have a default value if they are not specified. When modifying a principal or policy, optional fields are unchanged if they are not specified. When retrieving a principal, optional fields are simply not provided if they are not specified; not specifying undeeded fields for retrieval may improve efficiency. The values for forbidden fields are defined in the function semantics. The masks for principals are in table \ref{tab:princ-bits} and the masks for policies are in table \ref{tab:policy-bits}. They are defined in $<$kadm5/admin.h$>$. The KADM5_ prefix has been removed from the Name fields. In the Create and Modify fields, M means mandatory, F means forbidden, and O means optional. Create fields that are optional specify the default value. The notation ``K/M value'' means that the field inherits its value from the corresponding field in the Kerberos master principal, for KADM5_API_VERSION_1, and from the configuration parameters for KADM5_API_VERSION_2. All masks for principals are optional for retrevial, {\it except} that the KEY_DATA mask is illegal when specified by a remote client; for details, see the function semantics for kadm5_get_principal. Note that the POLICY and POLICY_CLR bits are special. When POLICY is set, the policy is assigned to the principal. When POLICY_CLR is specified, the policy is unassigned to the principal and as a result no policy controls the principal. For convenience, the mask KADM5_PRINCIPAL_NORMAL_MASK contains all of the principal masks {\it except} KADM5_KEY_DATA and KADM5_TL_DATA, and the mask KADM5_POLICY_NORMAL_MASK contains all of the policy masks. \begin{table}[htbp] \begin{tabular}{@{}lclll} {\bf Name} & {\bf Value} & {\bf Fields Affected} & {\bf Create} & {\bf Modify} \\ PRINCIPAL & 0x000001 & principal & M & F \\ PRINC_EXPIRE_TIME & 0x000002 & princ_expire_time & O, K/M value & O \\ PW_EXPIRATION & 0x000004 & pw_expiration & O, now+pw_max_life & O \\ LAST_PWD_CHANGE & 0x000008 & last_pwd_change & F & F \\ ATTRIBUTES & 0x000010 & attributes & O, 0 & O \\ MAX_LIFE & 0x000020 & max_life & O, K/M value & O \\ MOD_TIME & 0x000040 & mod_date & F & F \\ MOD_NAME & 0x000080 & mod_name & F & F \\ KVNO & 0x000100 & kvno & O, 1 & O \\ MKVNO & 0x000200 & mkvno & F & F \\ AUX_ATTRIBUTES & 0x000400 & aux_attributes & F & F \\ POLICY & 0x000800 & policy & O, none & O \\ POLICY_CLR & 0x001000 & policy & F & O \\ MAX_RLIFE & 0x002000 & max_renewable_life & O, K/M value & O \\ LAST_SUCCESS & 0x004000 & last_success & F & F \\ LAST_FAILED & 0x008000 & last_failed & F & F \\ FAIL_AUTH_COUNT & 0x010000 & fail_auth_count & F & O \\ KEY_DATA & 0x020000 & n_key_data, key_data & F & F \\ TL_DATA & 0x040000 & n_tl_data, tl_data & O, 0, NULL & O \end{tabular} \caption{Mask bits for creating, retrieving, and modifying principals.} \label{tab:princ-bits} \end{table} \begin{table}[htbp] \begin{tabular}{@{}lclll} Name & Value & Field Affected & Create & Modify \\ POLICY & same & policy & M & F \\ PW_MAX_LIFE & 0x004000 & pw_max_life & O, 0 (infinite) & O \\ PW_MIN_LIFE & 0x008000 & pw_min_life & O, 0 & O \\ PW_MIN_LENGTH & 0x010000 & pw_min_length & O, 1 & O \\ PW_MIN_CLASSES & 0x020000 & pw_min_classes & O, 1 & O \\ PW_HISTORY_NUM & 0x040000 & pw_history_num & O, 0 & O \\ REF_COUNT & 0x080000 & pw_refcnt & F & F \end{tabular} \caption{Mask bits for creating/modifying policies.} \label{tab:policy-bits} \end{table} \section{Constants, Header Files, Libraries} $<$kadm5/admin.h$>$ includes a number of required header files, including RPC, Kerberos 5, com_err, and admin com_err defines. It contains prototypes for all kadm5 routines mentioned below, as well as all Admin API data structures, type definitions and defines mentioned in this document. Before \v{\#include}ing $<$kadm5/admin.h$>$, the programmer can specify the API version number that the program will use by \v{\#define}ing USE_KADM5_API_VERSION; for example, define that symbol to be 1 to use KADM5_API_VERSION_1. This will ensure that the correct functional prototypes and data structures are defined. If no version symbol is defined, the most recent version supported by the header files will be used. Some of the defines and their values contained in $<$kadm5/admin.h$>$ include the following, whose KADM5_ prefixes have been removed. Symbols that do not exist in KADM5_API_VERSION_2 do not have a KADM5_ prefix, but instead retain only with OVSEC_KADM_ prefix for compatibility. \begin{description} \item[admin service principal] ADMIN_SERVICE (``kadmin/admin'') \item[admin history key] HIST_PRINCIPAL (``kadmin/history'') \item[change password principal] CHANGEPW_SERVICE (``kadmin/changepw'') \item[server acl file path] ACLFILE (``/krb5/ovsec_adm.acl''). In KADM5_API_VERSION 2, this is controlled by configuration parameters. \item[dictionary] WORDFILE (``/krb5/kadmind.dict''). In KADM5_API_VERSION 2, this is controlled by configuration parameters. \end{description} KADM5 errors are described in $<$kadm5/kadm_err.h$>$, which is included by $<$kadm5/admin.h$>$. The locations of the admin policy and principal databases, as well as defines and type definitions for the databases, are defined in $<$kadm5/adb.h$>$. Some of the defines in that file are: \begin{description} \item[admin policy database] POLICY_DB (``/krb5/kadm5_policy.db''). In KADM5_API_VERSION 2, this is controlled by configuration parameters. \item[admin principal database] PRINCIPAL_DB (``/krb5/ovsec_principal.db''). In KADM5_API_VERSION 2, this is controlled by configuration parameters. \end{description} Client applications will link against libkadm5clnt.a and server programs against libkadm5srv.a. Client applications must also link against: libgssapi_krb5.a, libkrb5.a, libcrypto.a, libgssrpc.a, libcom_err.a, and libdyn.a. Server applications must also link against: libkdb5.a, libkrb5.a, libcrypto.a, libgssrpc.a, libcom_err.a, and libdyn.a. \section{Error Codes} The error codes that can be returned by admin functions are listed below. Error codes indicated with a ``*'' can be returned by every admin function and always have the same meaning; these codes are omitted from the list presented with each function. The admin system guarantees that a function that returns an error code has no other side effect. The Admin system will use \v{com_err} for error codes. Note that this means \v{com_err} codes may be returned from functions that the admin routines call (e.g. the kerberos library). Callers should not expect that only KADM5 errors will be returned. The Admin system error code table name will be ``ovk'', and the offsets will be the same as the order presented here. As mentioned above, the error table include file will be $<$kadm5/kadm_err.h$>$. Note that these error codes are also used as protocol error code constants and therefore must not change between product releases. Additional codes should be added at the end of the list, not in the middle. The integer value of KADM5_FAILURE is 43787520; the remaining values are assigned in sequentially increasing order. \begin{description} \item[* KADM5_FAILURE] Operation failed for unspecified reason \item[* KADM5_AUTH_GET] Operation requires ``get'' privilege \item[* KADM5_AUTH_ADD] Operation requires ``add'' privilege \item[* KADM5_AUTH_MODIFY] Operation requires ``modify'' privilege \item[* KADM5_AUTH_DELETE] Operation requires ``delete'' privilege \item[* KADM5_AUTH_INSUFFICIENT] Insufficient authorization for operation \item[* KADM5_BAD_DB] Database inconsistency detected \item[KADM5_DUP] Principal or policy already exists \item[KADM5_RPC_ERROR] Communication failure with server \item[KADM5_NO_SRV] No administration server found for realm \item[KADM5_BAD_HIST_KEY] Password history principal key version mismatch \item[KADM5_NOT_INIT] Connection to server not initialized \item[KADM5_UNK_PRINC] Principal does not exist \item[KADM5_UNK_POLICY] Policy does not exist \item[KADM5_BAD_MASK] Invalid field mask for operation \item[KADM5_BAD_CLASS] Invalid number of character classes \item[KADM5_BAD_LENGTH] Invalid password length \item[KADM5_BAD_POLICY] Illegal policy name \item[KADM5_BAD_PRINCIPAL] Illegal principal name. \item[KADM5_BAD_AUX_ATTR] Invalid auxiliary attributes \item[KADM5_BAD_HISTORY] Invalid password history count \item[KADM5_BAD_MIN_PASS_LIFE] Password minimum life is greater then password maximum life \item[KADM5_PASS_Q_TOOSHORT] Password is too short \item[KADM5_PASS_Q_CLASS] Password does not contain enough character classes \item[KADM5_PASS_Q_DICT] Password is in the password dictionary \item[KADM5_PASS_REUSE] Cannot reuse password \item[KADM5_PASS_TOOSOON] Current password's minimum life has not expired \item[KADM5_POLICY_REF] Policy is in use \item[KADM5_INIT] Connection to server already initialized \item[KADM5_BAD_PASSWORD] Incorrect password \item[KADM5_PROTECT_PRINCIPAL] Cannot change protected principal \item[* KADM5_BAD_SERVER_HANDLE] Programmer error! Bad Admin server handle \item[* KADM5_BAD_STRUCT_VERSION] Programmer error! Bad API structure version \item[* KADM5_OLD_STRUCT_VERSION] API structure version specified by application is no longer supported (to fix, recompile application against current Admin API header files and libraries) \item[* KADM5_NEW_STRUCT_VERSION] API structure version specified by application is unknown to libraries (to fix, obtain current Admin API header files and libraries and recompile application) \item[* KADM5_BAD_API_VERSION] Programmer error! Bad API version \item[* KADM5_OLD_LIB_API_VERSION] API version specified by application is no longer supported by libraries (to fix, update application to adhere to current API version and recompile) \item[* KADM5_OLD_SERVER_API_VERSION] API version specified by application is no longer supported by server (to fix, update application to adhere to current API version and recompile) \item[* KADM5_NEW_LIB_API_VERSION] API version specified by application is unknown to libraries (to fix, obtain current Admin API header files and libraries and recompile application) \item[* KADM5_NEW_SERVER_API_VERSION] API version specified by application is unknown to server (to fix, obtain and install newest Admin Server) \item[KADM5_SECURE_PRINC_MISSING] Database error! Required principal missing \item[KADM5_NO_RENAME_SALT] The salt type of the specified principal does not support renaming \item[KADM5_BAD_CLIENT_PARAMS] Illegal configuration parameter for remote KADM5 client \item[KADM5_BAD_SERVER_PARAMS] Illegal configuration parameter for local KADM5 client. \item[KADM5_AUTH_LIST] Operation requires ``list'' privilege \item[KADM5_AUTH_CHANGEPW] Operation requires ``change-password'' privilege \item[KADM5_BAD_TL_TYPE] Programmer error! Illegal tagged data list element type \item[KADM5_MISSING_CONF_PARAMS] Required parameters in kdc.conf missing \item[KADM5_BAD_SERVER_NAME] Bad krb5 admin server hostname \item[KADM5_AUTH_SETKEY] Operation requires ``set-key'' privilege \item[KADM5_SETKEY_DUP_ENCTYPES] Multiple values for single or folded enctype \end{description} \section{Authentication and Authorization} \label{sec:auth} Two Kerberos principals exist for use in communicating with the Admin system: kadmin/admin and kadmin/changepw. Both principals have the KRB5_KDB_DISALLOW_TGT_BASED bit set in their attributes so that service tickets for them can only be acquired via a password-based (AS_REQ) request. Additionally, kadmin/changepw has the KRB5_KDB_PWCHANGE_SERVICE bit set so that a principal with an expired password can still obtain a service ticket for it. The Admin system accepts requests that are authenticated to either service principal, but the sets of operations that can be performed by a request authenticated to each service are different. In particular, only the functions chpass_principal, randkey_principal, get_principal, and get_policy can be performed by a request authenticated to the kadmin/changepw service, and they can only be performed when the target principal of the operation is the same as the authenticated client principal; the function semantics descriptions below give the precise details. This means that administrative operations can only be performed when authenticated to the kadmin/admin service. The reason for this distinction is that tickets for kadmin/changepw can be acquired with an expired password, and the KADM system does not want to allow an administrator with an expired password to perform administrative operations on arbitrary principals. Each Admin API operation authenticated to the kadmin/admin service requires a specific authorization to run. This version uses a simple named privilege system with the following names and meanings: \begin{description} \item[Get] Able to examine the attributes (NOT key data) of principals and policies. \item[Add] Able to add principals and policies. \item[Modify] Able to modify attributes of existing principals and policies; this does not include changing passwords. \item[Delete] Able to remove principals and policies. \item[List] Able to retrieve a list of principals and policies. \item[Changepw] Able to change the password of principals. \item[Setkey] Able to set principal keys directly. \end{description} Privileges are specified via an external configuration file on the Kerberos master server. Table \ref{tab:func-overview} summarizes the authorization requirements of each function. Additionally, each API function description identifies the privilege required to perform it. The Authorization checks only happen if you are using the RPC mechanism. If you are using the server-side API functions locally on the admin server, the only authorization check is if you can access the approporiate local files. \section{Functions} \subsection{Overview} The functions provided by the Admin API, and the authorization they require, are listed in the table \ref{tab:func-overview}. The ``kadm5_'' prefix has been removed from each function name. The function semantics in the following sections omit details that are the same for every function. \begin{itemize} \item The effects of every function are atomic. \item Every function performs an authorization check and returns the appropriate KADM5_AUTH_* error code if the caller does not have the required privilege. No other information or error code is ever returned to an unauthorized user. \item Every function checks its arguments for NULL pointers or other obviously invalid values, and returns EINVAL if any are detected. \item Any function that performs a policy check uses the policy named in the principal's policy field. If the POLICY bit is not set in the principal's aux_attributes field, however, the principal has no policy, so the policy check is not performed. \item Unless otherwise specified, all functions return KADM5_OK. \end{itemize} \begin{table}[htbp] \caption{Summary of functions and required authorization.} \label{tab:func-overview} \begin{tabular}{@{}llp{3.24in}} \\ {\bf Function Name} & {\bf Authorization} & {\bf Operation} \\ init & none & Open a connection with the kadm5 library. OBSOLETE but still provided---use init_with_password instead. \\ init_with_password & none & Open a connection with the kadm5 library using a password to obtain initial credentials. \\ init_with_skey & none & Open a connection with the kadm5 library using the keytab entry to obtain initial credentials. \\ destroy & none & Close the connection with the kadm5 library. \\ flush & none & Flush all database changes to disk; no-op when called remotely. \\ create_principal & add & Create a new principal. \\ delete_principal & delete & Delete a principal. \\ modify_principal & modify & Modify the attributes of an existing principal (not password). \\ rename_principal & add and delete & Rename a principal. \\ get_principal & get\footnotemark & Retrieve a principal. \\ get_principals & list & Retrieve some or all principal names. \\ chpass_principal & changepw\footnotemark[\thefootnote] & Change a principal's password. \\ chpass_principal_util & changepw\footnotemark[\thefootnote] & Utility wrapper around chpass_principal. \\ randkey_principal & changepw\footnotemark[\thefootnote] & Randomize a principal's key. \\ setkey_principal & setkey & Explicitly set a principal's keys. \\ decrypt_key & none & Decrypt a principal key. \\ create_policy & add & Create a new policy. \\ delete_policy & delete & Delete a policy. \\ modify_policy & modify & Modify the attributes of a policy. \\ get_policy & get & Retrieve a policy. \\ get_policies & list & Retrieve some or all policy names. \\ free_principal_ent & none & Free the memory associated with an kadm5_principal_ent_t. \\ free_policy_ent & none & Free the memory associated with an kadm5_policy_ent_t. \\ get_privs & none & Return the caller's admin server privileges. \end{tabular} \end{table} \footnotetext[\thefootnote]{These functions also allow a principal to perform the operation on itself; see the function's semantics for details.} \subsection{kadm5_init_*} In KADM5_API_VERSION 1: \begin{verbatim} kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass, char *service_name, char *realm, unsigned long struct_version, unsigned long api_version, void **server_handle) kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, char *service_name, char *realm, unsigned long struct_version, unsigned long api_version, void **server_handle) kadm5_ret_t kadm5_init(char *client_name, char *pass, char *service_name, char *realm, unsigned long struct_version, unsigned long api_version, void **server_handle) \end{verbatim} In KADM5_API_VERSION 2: \begin{verbatim} kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass, char *service_name, kadm5_config_params *realm_params, unsigned long struct_version, unsigned long api_version, void **server_handle) kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, char *service_name, kadm5_config_params *realm_params, unsigned long struct_version, unsigned long api_version, void **server_handle) kadm5_ret_t kadm5_init(char *client_name, char *pass, char *service_name, kadm5_config_params *realm_params, unsigned long struct_version, unsigned long api_version, void **server_handle) kadm5_ret_t kadm5_init_with_creds(char *client_name, krb5_ccache ccache, char *service_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, void **server_handle) \end{verbatim} AUTHORIZATION REQUIRED: none NOTE: kadm5_init is an obsolete function provided for backwards compatibility. It is identical to kadm5_init_with_password. These three functions open a connection to the kadm5 library and initialize any necessary state information. They behave differently when called from local and remote clients. In KADM5_API_VERSION_2, these functions take a kadm5_config_params structure instead of a realm name as an argument. The semantics are similar: if a NULL pointer is passed for the realm_params argument, the default realm and default parameters for that realm, as specified in the krb5 configuration file (e.g. /etc/krb5.conf) are used. If a realm_params structure is provided, the fields that are set override the default values. If a parameter is specified to the local or remote libraries that does not apply to that side, an error code (KADM5_BAD_CLIENT_PARAMS or KADM5_BAD_SERVER_PARAMS) is returned. See section \ref{sec:configparams} for a discussion of configuration parameters. For remote clients, the semantics are: \begin{enumerate} \item Initializes all the com_err error tables used by the Admin system. \item Acquires configuration parameters. In KADM5_API_VERSION_1, all the defaults specified in the configuration file are used, according to the realm. In KADM5_API_VERSION_2, the values in params_in are merged with the default values. If an illegal mask value is specified, KADM5_BAD_CLIENT_PARAMS is returned. \item Acquires a Kerberos ticket for the specified service. \begin{enumerate} \item The ticket's client is client_name, which can be any valid Kerberos principal. If client_name does not include a realm, the default realm of the local host is used \item The ticket's service is service_name@realm. service_name must be one of the constants KADM5_ADMIN_SERVICE or KADM5_CHANGEPW_SERVICE. \item If realm is NULL, client_name's realm is used. \item For init_with_password, an initial ticket is acquired and decoded with the password pass, which must be client_name's password. If pass is NULL or an empty string, the user is prompted (via the tty) for a password. \item For init_with_skey, an initial ticket is acquired and decoded with client_name's key obtained from the specified keytab. If keytab is NULL or an empty string the default keytab is used. \item For init_with_creds, ccache must be an open credential cache that already has a ticket for the specified client and server. Alternatively, if a site chooses to disable the DISALLOW_TGT_BASED flag on the admin and changepw principals, the ccache can contain a ticket-granting ticket for client_name. \end{enumerate} \item Creates a GSS-API authenticated connection to the Admin server, using the just-acquired Kerberos ticket. \item Verifies that the struct_version and api_version specified by the caller are valid and known to the library. \item Sends the specified api_version to the server. \item Upon successful completion, fills in server_handle with a handle for this connection, to be used in all subsequent API calls. \end{enumerate} The caller should always specify KADM5_STRUCT_VERSION for the struct_version argument, a valid and supported API version constant for the api_version argument (currently, KADM5_API_VERSION_1 or KADM5_API_VERSION_2), and a valid pointer in which the server handle will be stored. If any kadm5_init_* is invoked locally its semantics are: \begin{enumerate} \item Initializes all the com_err error tables used by the Admin system. \item Acquires configuration parameters. In KADM5_API_VERSION_1, all the defaults specified in the configuration file are used, according to the realm. In KADM5_API_VERSION_2, the values in params_in are merged with the default values. If an illegal mask value is specified, KADM5_BAD_SERVER_PARAMS is returned. \item Initializes direct access to the KDC database. In KADM5_API_VERISON_1, if pass (or keytab) is NULL or an empty string, reads the master password from the stash file; otherwise, the non-NULL password is ignored and the user is prompted for it via the tty. In KADM5_API_VERSION_2, if the MKEY_FROM_KEYBOARD parameter mask is set and the value is non-zero, reads the master password from the user via the tty; otherwise, the master key is read from the stash file. Calling init_with_skey or init_with_creds with the MKEY_FROM_KEYBOARD mask set with a non-zero field is illegal, and calling them without the mask set is exactly like calling init_with_password. \item Initializes the dictionary (if present) for dictionary checks. \item Parses client_name as a Kerberos principal. client_name should usually be specified as the name of the program. \item Verifies that the struct_version and api_version specified by the caller are valid. \item Fills in server_handle with a handle containing all state information (version numbers and client name) for this ``connection.'' \end{enumerate} The service_name argument is not used. RETURN CODES: \begin{description} \item[KADM5_NO_SRV] No Admin server can be found for the specified realm. \item[KADM5_RPC_ERROR] The RPC connection to the server cannot be initiated. \item[KADM5_BAD_PASSWORD] Incorrect password. \item[KADM5_SECURE_PRINC_MISSING] The principal KADM5_ADMIN_SERVICE or KADM5_CHANGEPW_SERVICE does not exist. This is a special-case replacement return code for ``Server not found in database'' for these required principals. \item[KADM5_BAD_CLIENT_PARAMS] A field in the parameters mask was specified to the remote client library that is not legal for remote clients. \item[KADM5_BAD_SERVER_PARAMS] A field in the parameters mask was specified to the local client library that is not legal for local clients. \end{description} \subsection{kadm5_flush} \begin{verbatim} kadm5_ret_t kadm5_flush(void *server_handle) \end{verbatim} AUTHORIZATION REQUIRED: none Flush all changes to the Kerberos databases, leaving the connection to the Admin API open. This function behaves differently when called by local and remote clients. For local clients, the function closes and reopens the Kerberos database with krb5_db_fini() and krb5_db_init(). Although it is unlikely, either of these functions could return errors; in that case, this function calls kadm5_destroy and returns the error code. Therefore, if kadm5_flush does not return KADM5_OK, the connection to the Admin server has been terminated and, in principle, the databases might be corrupt. For remote clients, the function is a no-op. \subsection{kadm5_destroy} \begin{verbatim} kadm5_ret_t kadm5_destroy(void *server_handle) \end{verbatim} AUTHORIZATION REQUIRED: none Close the connection to the Admin server and releases all related resources. This function behaves differently when called by local and remote clients. For remote clients, the semantics are: \begin{enumerate} \item Destroy the temporary credential cache created by kadm5_init. \item Tear down the GSS-API context negotiated with the server. \item Close the RPC connection. \item Free storage space associated with server_handle, after erasing its magic number so it won't be mistaken for a valid handle by the library later. \end{enumerate} For local clients, this function just frees the storage space associated with server_handle after erasing its magic number. RETURN CODES: \subsection{kadm5_create_principal} \begin{verbatim} kadm5_ret_t kadm5_create_principal(void *server_handle, kadm5_principal_ent_t princ, u_int32 mask, char *pw); \end{verbatim} AUTHORIZATION REQUIRED: add \begin{enumerate} \item Return KADM5_BAD_MASK if the mask is invalid. \item If the named principal exists, return KADM5_DUP. \item If the POLICY bit is set and the named policy does not exist, return KADM5_UNK_POLICY. \item If KADM5_POLICY bit is set in aux_attributes check to see if the password does not meets quality standards, return the appropriate KADM5_PASS_Q_* error code if it fails. \item Store the principal, set the key; see section \ref{sec:keys}. \item If the POLICY bit is set, increment the named policy's reference count by one. \item Set the pw_expiration field. \begin{enumerate} \item If the POLICY bit is set in mask, then if pw_max_life is non-zero, set pw_expiration to now + pw_maxlife, otherwise set pw_max_life to never. \item If the PW_EXPIRATION bit is set in mask, set pw_expiration to the requested value, overriding the value set above. \end{enumerate} NOTE: This is a change from the original semantics, in which policy expiration was enforced even on administrators. The old semantics are not preserved, even for version 1 callers, because this is a server-specific policy decision; besides, the new semantics are less restrictive, so all previous callers should continue to function properly. \item Set mod_date to now and set mod_name to caller. \item Set last_pwd_change to now. \end{enumerate} RETURN CODES: \begin{description} \item[KADM5_BAD_MASK] The field mask is invalid for a create operation. \item[KADM5_DUP] Principal already exists. \item[KADM5_UNK_POLICY] Policy named in entry does not exist. \item[KADM5_PASS_Q_*] Specified password does not meet policy standards. \end{description} \subsection{kadm5_delete_principal} \begin{verbatim} kadm5_ret_t kadm5_delete_principal(void *server_handle, krb5_principal princ); \end{verbatim} AUTHORIZATION REQUIRED: delete \begin{enumerate} \item Return KADM5_UNK_PRINC if the principal does not exist. \item If the POLICY bit is set in aux_attributes, decrement the named policy's reference count by one. \item Delete principal. \end{enumerate} RETURN CODES: \begin{description} \item[KADM5_UNK_PRINC] Principal does not exist. \end{description} \subsection{kadm5_modify_principal} \begin{verbatim} kadm5_ret_t kadm5_modify_principal(void *server_handle, kadm5_principal_ent_t princ, u_int32 mask); \end{verbatim} Modify the attributes of the principal named in kadm5_principal_ent_t. This does not allow the principal to be renamed or for its password to be changed. AUTHORIZATION REQUIRED: modify Although a principal's pw_expiration is usually computed based on its policy and the time at which it changes its password, this function also allows it to be specified explicitly. This allows an administrator, for example, to create a principal and assign it to a policy with a pw_max_life of one month, but to declare that the new principal must change its password away from its initial value sometime within the first week. \begin{enumerate} \item Return KADM5_UNK_PRINC if the principal does not exist. \item Return KADM5_BAD_MASK if the mask is invalid. \item If POLICY bit is set but the new policy does not exist, return KADM5_UNK_POLICY. \item If either the POLICY or POLICY_CLR bits are set, update the corresponding bits in aux_attributes. \item Update policy reference counts. \begin{enumerate} \item If the POLICY bit is set, then increment policy count on new policy. \item If the POLICY or POLICY_CLR bit is set, and the POLICY bit in aux_attributes is set, decrement policy count on old policy. \end{enumerate} \item Set pw_expiration appropriately. pw_expiration can change if: the POLICY bit is set in mask, so the principal is changing to a policy (either from another policy or no policy); the POLICY_CLR bit is set in mask, so the principal is changing to no policy; or PW_EXPIRATION is set. \begin{enumerate} \item If the POLICY bit is set in mask, set pw_expiration to last_pwd_change + pw_max_life if pw_max_life is non-zero, otherwise set pw_expiration to never. \item If the POLICY_CLR biti s set in mask, set pw_expiration to never. \item If PW_EXPIRATION is set, set pw_expiration to the requested value, overriding the value from the previous two cases. NOTE: This is a change from the original semantics, in which policy expiration was enforced even on administrators. The old semantics are not preserved, even for version 1 callers, because this is a server-specific policy decision; besides, the new semantics are less restrictive, so all previous callers should continue to function properly. \end{enumerate} % Here is the previous, and confusing, text of pw_expiration semantics: %\begin{enumerate} %\item If the POLICY bit is not set in aux_attributes, then %\begin{enumerate} %\item if the PW_EXPIRATION bit is set, set pw_expiration to the given %value, else %\item set pw_expiration to never. %\end{enumerate} %\item Otherwise, if the PW_EXPIRATION bit is set, set pw_expiration to %the sooner of the given value and last_pwd_change + pw_max_life. %\item Otherwise, set pw_expiration to last_pwd_change + pw_max_life. %\end{enumerate} \item Update the remaining fields specified in the mask. \item Update mod_name field to caller and mod_date to now. \end{enumerate} RETURN CODES: \begin{description} \item[KADM5_UNK_PRINC] Entry does not exist. \item[KADM5_BAD_MASK] The mask is not valid for a modify operation. \item[KADM5_UNK_POLICY] The POLICY bit is set but the new policy does not exist. \item[KADM5_BAD_TL_TYPE] The KADM5_TL_DATA bit is set in mask, and the given tl_data list contains an element whose type is less than 256. \end{description} \subsection{kadm5_rename_principal} \begin{verbatim} kadm5_ret_t kadm5_rename_principal(void *server_handle, krb5_principal source, krb5_principal target); \end{verbatim} AUTHORIZATION REQUIRED: add and delete \begin{enumerate} \item Check to see if source principal exists, if not return KADM5_UNK_PRINC error. \item Check to see if target exists, if so return KADM5_DUP error. \item Create the new principal named target, then delete the old principal named source. All of target's fields will be the same as source's fields, except that mod_name and mod_date will be updated to reflect the current caller and time. \end{enumerate} Note that since the principal name may have been used as the salt for the principal's key, renaming the principal may render the principal's current password useless; with the new salt, the key generated by string-to-key on the password will suddenly be different. Therefore, an application that renames a principal must also require the user to specify a new password for the principal (and administrators should notify the affected party). Note also that, by the same argument, renaming a principal will invalidate that principal's password history information; since the salt will be different, a user will be able to select a previous password without error. RETURN CODES: \begin{description} \item[KADM5_UNK_PRINC] Source principal does not exist. \item[KADM5_DUP] Target principal already exist. \end{description} \subsection{kadm5_chpass_principal} \begin{verbatim} kadm5_ret_t kadm5_chpass_principal(void *server_handle, krb5_principal princ, char *pw); \end{verbatim} AUTHORIZATION REQUIRED: changepw, or the calling principal being the same as the princ argument. If the request is authenticated to the kadmin/changepw service, the changepw privilege is disregarded. Change a principal's password. See section \ref{sec:keys} for a description of how the keys are determined. This function enforces password policy and dictionary checks. If the new password specified is in the password dictionary, and the policy bit is set KADM5_PASS_DICT is returned. If the principal's POLICY bit is set in aux_attributes, compliance with each of the named policy fields is verified and an appropriate error code is returned if verification fails. Note that the policy checks are only be performed if the POLICY bit is set in the principal's aux_attributes field. \begin{enumerate} \item Make sure principal exists, if not return KADM5_UNK_PRINC error. \item If caller does not have modify privilege, (now - last_pwd_change) $<$ pw_min_life, and the KRB5_KDB_REQUIRES_PWCHANGE bit is not set in the principal's attributes, return KADM5_PASS_TOOSOON. \item If the principal your are trying to change is kadmin/history return KADM5_PROTECT_PRINCIPAL. \item If the password does not meet the quality standards, return the appropriate KADM5_PASS_Q_* error code. \item Convert password to key; see section \ref{sec:keys}. \item If the new key is in the principal's password history, return KADM5_PASS_REUSE. \item Store old key in history. \item Update principal to have new key. \item Increment principal's key version number by one. \item If the POLICY bit is set, set pw_expiration to now + max_pw_life. If the POLICY bit is not set, set pw_expiration to never. \item If the KRB5_KDB_REQUIRES_PWCHANGE bit is set in the principal's attributes, clear it. \item Update last_pwd_change and mod_date to now, update mod_name to caller. \end{enumerate} RETURN CODES: \begin{description} \item[KADM5_UNK_PRINC] Principal does not exist. \item[KADM5_PASS_Q_*] Requested password does not meet quality standards. \item[KADM5_PASS_REUSE] Requested password is in user's password history. \item[KADM5_PASS_TOOSOON] Current password has not reached minimum life \item[KADM5_PROTECT_PRINCIPAL] Cannot change the password of a special principal \end{description} \subsection{kadm5_chpass_principal_util} \begin{verbatim} kadm5_ret_t kadm5_chpass_principal_util(void *server_handle, krb5_principal princ, char *new_pw, char **pw_ret, char *msg_ret); \end{verbatim} AUTHORIZATION REQUIRED: changepw, or the calling principal being the same as the princ argument. If the request is authenticated to the kadmin/changepw service, the changepw privilege is disregarded. This function is a wrapper around kadm5_chpass_principal. It can read a new password from a user, change a principal's password, and return detailed error messages. msg_ret should point to a char buffer in the caller's space of sufficient length for the error messages described below. 1024 bytes is recommended. It will also return the new password to the caller if pw_ret is non-NULL. \begin{enumerate} \item If new_pw is NULL, this routine will prompt the user for the new password (using the strings specified by KADM5_PW_FIRST_PROMPT and KADM5_PW_SECOND_PROMPT) and read (without echoing) the password input. Since it is likely that this will simply call krb5_read_password only terminal-based applications will make use of the password reading functionality. If the passwords don't match the string ``New passwords do not match - password not changed.'' will be copied into msg_ret, and the error code KRB5_LIBOS_BADPWDMATCH will be returned. For other errors that occur while reading the new password, copy the string ``$ occurred while trying to read new password.'' followed by a blank line and the string specified by CHPASS_UTIL_PASSWORD_NOT_CHANGED into msg_ret and return the error code returned by krb5_read_password. \item If pw_ret is non-NULL, and the password was prompted, set *pw_ret to point to a static buffer containing the password. If pw_ret is non-NULL and the password was supplied, set *pw_ret to the supplied password. \item Call kadm5_chpass_principal with princ, and new_pw. \item If successful copy the string specified by CHPASS_UTIL_PASSWORD_CHANGED into msg_ret and return zero. \item For a policy related failure copy the appropriate message (from below) followed by a newline and ``Password not changed.'' into msg_ret filling in the parameters from the principal's policy information. If the policy information cannot be obtained copy the generic message if one is specified below. Return the error code from kadm5_chpass_principal. Detailed messages: \begin{description} \item[PASS_Q_TOO_SHORT] New password is too short. Please choose a password which is more than $<$pw-min-len$>$ characters. \item[PASS_Q_TOO_SHORT - generic] New password is too short. Please choose a longer password. \item[PASS_REUSE] New password was used previously. Please choose a different password. \item[PASS_Q_CLASS] New password does not have enough character classes. Classes include lower class letters, upper case letters, digits, punctuation and all other characters. Please choose a password with at least $<$min-classes$>$ character classes. \item[PASS_Q_CLASS - generic] New password does not have enough character classes. Classes include lower class letters, upper case letters, digits, punctuation and all other characters. \item[PASS_Q_DICT] New password was found in a dictionary of possible passwords and therefore may be easily guessed. Please choose another password. See the kpasswd man page for help in choosing a good password. \item[PASS_TOOSOON] Password cannot be changed because it was changed too recently. Please wait until $<$last-pw-change+pw-min-life$>$ before you change it. If you need to change your password before then, contact your system security administrator. \item[PASS_TOOSOON - generic] Password cannot be changed because it was changed too recently. If you need to change your now please contact your system security administrator. \end{description} \item For other errors copy the string ``$<$com_err message$>$ occurred while trying to change password.'' following by a blank line and ``Password not changed.'' into msg_ret. Return the error code returned by kadm5_chpass_principal. \end{enumerate} RETURN CODES: \begin{description} \item[KRB5_LIBOS_BADPWDMATCH] Typed new passwords did not match. \item[KADM5_UNK_PRINC] Principal does not exist. \item[KADM5_PASS_Q_*] Requested password does not meet quality standards. \item[KADM5_PASS_REUSE] Requested password is in user's password history. \item[KADM5_PASS_TOOSOON] Current password has not reached minimum life. \end{description} \subsection{kadm5_randkey_principal} In KADM5_API_VERSION_1: \begin{verbatim} kadm5_ret_t kadm5_randkey_principal(void *server_handle, krb5_principal princ, krb5_keyblock **new_key) \end{verbatim} In KADM5_API_VERSION_2: \begin{verbatim} kadm5_ret_t kadm5_randkey_principal(void *server_handle, krb5_principal princ, krb5_keyblock **new_keys, int *n_keys) \end{verbatim} AUTHORIZATION REQUIRED: changepw, or the calling principal being the same as the princ argument. If the request is authenticated to the kadmin/changepw service, the changepw privilege is disregarded. Generate and assign a new random key to the named principal, and return the generated key in allocated storage. In KADM5_API_VERSION_2, multiple keys may be generated and returned as an array, and n_new_keys is filled in with the number of keys generated. See section \ref{sec:keys} for a description of how the keys are chosen. In KADM5_API_VERSION_1, the caller must free the returned krb5_keyblock * with krb5_free_keyblock. In KADM5_API_VERSION_2, the caller must free each returned keyblock with krb5_free_keyblock. If the principal's POLICY bit is set in aux_attributes and the caller does not have modify privilege , compliance with the password minimum life specified by the policy is verified and an appropriate error code is returned if verification fails. \begin{enumerate} \item If the principal does not exist, return KADM5_UNK_PRINC. \item If caller does not have modify privilege, (now - last_pwd_change) $<$ pw_min_life, and the KRB5_KDB_REQUIRES_PWCHANGE bit is not set in the principal's attributes, return KADM5_PASS_TOOSOON. \item If the principal you are trying to change is kadmin/history return KADM5_PROTECT_PRINCIPAL. \item Store old key in history. \item Update principal to have new key. \item Increment principal's key version number by one. \item If the POLICY bit in aux_attributes is set, set pw_expiration to now + max_pw_life. \item If the KRB5_KDC_REQUIRES_PWCHANGE bit is set in the principal's attributes, clear it. \item Update last_pwd_change and mod_date to now, update mod_name to caller. \end{enumerate} RETURN CODES: \begin{description} \item[KADM5_UNK_PRINC] Principal does not exist. \item[KADM5_PASS_TOOSOON] The minimum lifetime for the current key has not expired. \item[KADM5_PROTECT_PRINCIPAL] Cannot change the password of a special principal \end{description} This function can also be used as part of a sequence to create a new principal with a random key. The steps to perform the operation securely are \begin{enumerate} \item Create the principal with kadm5_create_principal with a random password string and with the KRB5_KDB_DISALLOW_ALL_TIX bit set in the attributes field. \item Randomize the principal's key with kadm5_randkey_principal. \item Call kadm5_modify_principal to reset the KRB5_KDB_DISALLOW_ALL_TIX bit in the attributes field. \end{enumerate} The three steps are necessary to ensure secure creation. Since an attacker might be able to guess the initial password assigned by the client program, the principal must be disabled until the key can be truly randomized. \subsection{kadm5_setkey_principal} \begin{verbatim} kadm5_ret_t kadm5_setkey_principal(void *server_handle, krb5_principal princ, krb5_keyblock *new_keys, int n_keys) \end{verbatim} AUTHORIZATION REQUIRED: setkey. This function does not allow the use of regular changepw authorization because it bypasses the password policy mechanism. This function only exists in KADM5_API_VERSION_2. Explicitly sets the specified principal's keys to the n_keys keys in the new_keys array. The keys in new_keys should not be encrypted in the Kerberos master key; this function will perform that operation itself (the keys will be protected during transmission from the calling client to the kadmind server by the AUTH_GSSAPI RPC layer). This function completely bypasses the principal's password policy, if set. \begin{enumerate} \item If the principal does not exist, return KADM5_UNK_PRINC. \item If the principal you are trying to change is kadmin/history return KADM5_PROTECT_PRINCIPAL. \item If new_keys contains more than one key of any ENCTYPE_DES_CBC_* type that is folded, return KADM5_SETKEY_DUP_ENCTYPES. \item Store old key in history. \item Update principal to have new key. \item Increment principal's key version number by one. \item If the POLICY bit in aux_attributes is set, set pw_expiration to now + max_pw_life. \item If the KRB5_KDC_REQUIRES_PWCHANGE bit is set in the principal's attributes, clear it. \item Update last_pwd_change and mod_date to now, update mod_name to caller. \end{enumerate} RETURN CODES: \begin{description} \item[KADM5_UNK_PRINC] Principal does not exist. \item[KADM5_PROTECT_PRINCIPAL] Cannot change the password of a special principal \end{description} This function can also be used as part of a sequence to create a new principal with an explicitly key. The steps to perform the operation securely are \begin{enumerate} \item Create the principal with kadm5_create_principal with a random password string and with the KRB5_KDB_DISALLOW_ALL_TIX bit set in the attributes field. \item Set the principal's key with kadm5_setkey_principal. \item Call kadm5_modify_principal to reset the KRB5_KDB_DISALLOW_ALL_TIX bit in the attributes field. \end{enumerate} The three steps are necessary to ensure secure creation. Since an attacker might be able to guess the initial password assigned by the client program, the principal must be disabled until the key can be truly randomized. \subsection{kadm5_get_principal} In KADM5_API_VERSION_1: \begin{verbatim} kadm5_ret_t kadm5_get_principal(void *server_handle, krb5_principal princ, kadm5_principal_ent_t *ent); \end{verbatim} In KADM5_API_VERSION_2: \begin{verbatim} kadm5_ret_t kadm5_get_principal(void *server_handle, krb5_principal princ, kadm5_principal_ent_t ent, u_int32 mask); \end{verbatim} AUTHORIZATION REQUIRED: get, or the calling principal being the same as the princ argument. If the request is authenticated to the kadmin/changepw service, the get privilege is disregarded. In KADM5_API_VERSION_1, return all of the principal's attributes in allocated memory; if an error is returned entry is set to NULL. In KADM5_API_VERSION_2, fill in the fields of the principal structure specified in the mask; memory for the structure is not allocated. Typically, a caller will specify the mask KADM5_PRINCIPAL_NORMAL_MASK, which includes all the fields {\it except} key_data and tl_data to improve time and memory efficiency. A caller that wants key_data and tl_data can bitwise-OR those masks onto NORMAL_MASK. Note that even if KADM5_TL_DATA is specified, this function will not return internal tl_data elements whose type is less than 256. The caller must free the returned entry with kadm5_free_principal_ent. The function behaves differently for local and remote clients. For remote clients, the KEY_DATA mask is illegal and results in a KADM5_BAD_MASK error. RETURN CODES: \begin{description} \item[KADM5_UNK_PRINC] Principal does not exist. \item[KADM5_BAD_MASK] The mask is not valid for a get operation. \end{description} \subsection{kadm5_decyrpt_key} \begin{verbatim} kadm5_ret_t kadm5_decrypt_key(void *server_handle, kadm5_principal_ent_t entry, krb5_int32 ktype, krb5_int32 stype, krb5_int32 kvno, krb5_keyblock *keyblock, krb5_keysalt *keysalt, int *kvnop) \end{verbatim} AUTHORIZATION REQUIRED: none, local function Searches a principal's key_data array to find a key with the specified enctype, salt type, and kvno, and decrypts the key into keyblock and keysalt if found. entry must have been returned by kadm5_get_principal with at least the KADM5_KEY_DATA mask set. Returns ENOENT if the key cannot be found, EINVAL if the key_data array is empty (as it always is in an RPC client). If ktype or stype is -1, it is ignored for the search. If kvno is -1, ktype and stype are ignored and the key with the max kvno is returned. If kvno is 0, only the key with the max kvno is returned and only if it matches the ktype and stype; otherwise, ENOENT is returned. \subsection{kadm5_get_principals} \begin{verbatim} kadm5_ret_t kadm5_get_principals(void *server_handle, char *exp, char ***princs, int *count) \end{verbatim} Retrieves the list of principal names. AUTHORIZATION REQUIRED: list If \v{exp} is NULL, all principal names are retrieved; otherwise, principal names that match the expression exp are retrieved. \v{princs} is filled in with a pointer to a NULL-terminated array of strings, and \v{count} is filled in with the number of principal names in the array. \v{princs} must be freed with a call to \v{kadm5_free_name_list}. All characters in the expression match themselves except ``?'' which matches any single character, ``*'' which matches any number of consecutive characters, and ``[chars]'' which matches any single character of ``chars''. Any character which follows a ``$\backslash$'' matches itself exactly, and a ``$\backslash$'' cannot be the last character in the string. \subsection{kadm5_create_policy} \begin{verbatim} kadm5_ret_t kadm5_create_policy(void *server_handle, kadm5_policy_ent_t policy, u_int32 mask); \end{verbatim} Create a new policy. AUTHORIZATION REQUIRED: add \begin{enumerate} \item Check to see if mask is valid, if not return KADM5_BAD_MASK error. \item Return KADM5_BAD_POLICY if the policy name contains illegal characters. \item Check to see if the policy already exists, if so return KADM5_DUP error. \item If the PW_MIN_CLASSES bit is set and pw_min_classes is not 1, 2, 3, 4, or 5, return KADM5_BAD_CLASS. \item Create a new policy setting the appropriate fields determined by the mask. \end{enumerate} RETURN CODES: \begin{description} \item[KADM5_DUP] Policy already exists \item[KADM5_BAD_MASK] The mask is not valid for a create operation. \item[KADM5_BAD_CLASS] The specified number of character classes is invalid. \item[KADM5_BAD_POLICY] The policy name contains illegal characters. \end{description} \subsection{kadm5_delete_policy} \begin{verbatim} kadm5_ret_t kadm5_delete_policy(void *server_handle, char *policy); \end{verbatim} Deletes a policy. AUTHORIZATION REQUIRED: delete \begin{enumerate} \item Return KADM5_BAD_POLICY if the policy name contains illegal characters. \item Return KADM5_UNK_POLICY if the named policy does not exist. \item Return KADM5_POLICY_REF if the named policy's refcnt is not 0. \item Delete policy. \end{enumerate} RETURN CODES: \begin{description} \item[KADM5_BAD_POLICY] The policy name contains illegal characters. \item[KADM5_UNK_POLICY] Policy does not exist. \item[KADM5_POLICY_REF] Policy is being referenced. \end{description} \subsection{kadm5_modify_policy} \begin{verbatim} kadm5_ret_t kadm5_modify_policy(void *server_handle, kadm5_policy_ent_t policy, u_int32 mask); \end{verbatim} Modify an existing policy. Note that modifying a policy has no affect on a principal using the policy until the next time the principal's password is changed. AUTHORIZATION REQUIRED: modify \begin{enumerate} \item Return KADM5_BAD_POLICY if the policy name contains illegal characters. \item Check to see if mask is legal, if not return KADM5_BAD_MASK error. \item Check to see if policy exists, if not return KADM5_UNK_POLICY error. \item If the PW_MIN_CLASSES bit is set and pw_min_classes is not 1, 2, 3, 4, or 5, return KADM5_BAD_CLASS. \item Update the fields specified in the mask. \end{enumerate} RETURN CODES: \begin{description} \item[KADM5_BAD_POLICY] The policy name contains illegal characters. \item[KADM5_UNK_POLICY] Policy not found. \item[KADM5_BAD_MASK] The mask is not valid for a modify operation. \item[KADM5_BAD_CLASS] The specified number of character classes is invalid. \end{description} \subsection{kadm5_get_policy} In KADM5_API_VERSION_1: \begin{verbatim} kadm5_ret_t kadm5_get_policy(void *server_handle, char *policy, kadm5_policy_ent_t *ent); \end{verbatim} In KADM5_API_VERSION_2: \begin{verbatim} kadm5_ret_t kadm5_get_policy(void *server_handle, char *policy, kadm5_policy_ent_t ent); \end{verbatim} AUTHORIZATION REQUIRED: get, or the calling principal's policy being the same as the policy argument. If the request is authenticated to the kadmin/changepw service, the get privilege is disregarded. In KADM5_API_VERSION_1, return the policy's attributes in allocated memory; if an error is returned entry is set to NULL. In KADM5_API_VERSION_2, fill in fields of the policy structure allocated by the caller. The caller must free the returned entry with kadm5_free_policy_ent RETURN CODES: \begin{description} \item[KADM5_BAD_POLICY] The policy name contains illegal characters. \item[KADM5_UNK_POLICY] Policy not found. \end{description} \subsection{kadm5_get_policies} \begin{verbatim} kadm5_ret_t kadm5_get_policies(void *server_handle, char *exp, char ***pols, int *count) \end{verbatim} Retrieves the list of principal names. AUTHORIZATION REQUIRED: list If \v{exp} is NULL, all principal names are retrieved; otherwise, principal names that match the expression exp are retrieved. \v{pols} is filled in with a pointer to a NULL-terminated array of strings, and \v{count} is filled in with the number of principal names in the array. \v{pols} must be freed with a call to \v{kadm5_free_name_list}. All characters in the expression match themselves except ``?'' which matches any single character, ``*'' which matches any number of consecutive characters, and ``[chars]'' which matches any single character of ``chars''. Any character which follows a ``$\backslash$'' matches itself exactly, and a ``$\backslash$'' cannot be the last character in the string. \subsection{kadm5_free_principal_ent, _policy_ent} \begin{verbatim} void kadm5_free_principal_ent(void *server_handle, kadm5_principal_ent_t princ); \end{verbatim} In KADM5_API_VERSION_1, free the structure and contents allocated by a call to kadm5_get_principal. In KADM5_API_VERSION_2, free the contents allocated by a call to kadm5_get_principal. AUTHORIZATION REQUIRED: none (local operation) \begin{verbatim} void kadm5_free_policy_ent(kadm5_policy_ent_t policy); \end{verbatim} Free memory that was allocated by a call to kadm5_get_policy. If the argument is NULL, the function returns successfully. AUTHORIZATION REQUIRED: none (local operation) \subsection{kadm5_free_name_list} \begin{verbatim} void kadm5_free_name_list(void *server_handle, char **names, int *count); \end{verbatim} Free the memory that was allocated by kadm5_get_principals or kadm5_get_policies. names and count must be a matched pair of values returned from one of those two functions. \subsection{kadm5_free_key_data} \begin{verbatim} void kadm5_free_key_data(void *server_handle, krb5_int16 *n_key_data, krb5_key_data *key_data) \end{verbatim} Free the memory that was allocated by kadm5_randkey_principal. n_key_data and key_data must be a matched pair of values returned from that function. \subsection{kadm5_get_privs} \begin{verbatim} kadm5_ret_t kadm5_get_privs(void *server_handle, u_int32 *privs); \end{verbatim} Return the caller's admin server privileges in the integer pointed to by the argument. The Admin API does not define any way for a principal's privileges to be set. Note that this function will probably be removed or drastically changed in future versions of this system. The returned value is a bitmask indicating the caller's privileges: \begin{tabular}{llr} {\bf Privilege} & {\bf Symbol} & {\bf Value} \\ Get & KADM5_PRIV_GET & 0x01 \\ Add & KADM5_PRIV_ADD & 0x02 \\ Modify & KADM5_PRIV_MODIFY & 0x04 \\ Delete & KADM5_PRIV_DELETE & 0x08 \\ List & KADM5_PRIV_LIST & 0x10 \\ Changepw & KADM5_PRIV_CPW & 0x20 \end{tabular} There is no guarantee that a caller will have a privilege indicated by this function for any length of time or for any particular target; applications using this function must still be prepared to handle all possible KADM5_AUTH_* error codes. In the initial MIT Kerberos version of the admin server, permissions depend both on the caller and the target; this function returns a bitmask representing all privileges the caller can possibly have for any possible target. \end{document} krb5-1.22.1/doc/kadm5/fullpage.sty0000664000175000017500000000021115051422640016441 0ustar ghudsonghudson\marginparwidth 0pt \oddsidemargin 0pt \evensidemargin 0pt \marginparsep 0pt \topmargin 0pt \textwidth 6.5in \textheight 8.5 in krb5-1.22.1/doc/kadm5/api-server-design.tex0000664000175000017500000013305115051422640020160 0ustar ghudsonghudson% This document is included for historical purposes only, and does not % apply to krb5 today. \documentstyle[12pt,fullpage]{article} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Make _ actually generate an _, and allow line-breaking after it. \let\underscore=\_ \catcode`_=13 \def_{\underscore\penalty75\relax} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \setlength{\parskip}{.7\baselineskip} \setlength{\parindent}{0pt} \def\v#1{\verb+#1+} \def\k#1{K$_#1$} \title{KADM5 Library and Server \\ Implementation Design} \author{Barry Jaspan} \begin{document} \sloppy \maketitle {\setlength{\parskip}{0pt}\tableofcontents} \section{Overview} The KADM5 administration system is designed around the KADM5 API. The ``server-side'' library libkadm5srv.a implements the KADM5 API by operating directly on the underlying KDC and admin databases. The ``client-side'' library libkadm5clnt.a implements the KADM5 API via an RPC mechanism. The administration server kadmind accepts RPC requests from the client-side library and translates them into calls to the server-side library, performing authentication, authorization, and logging along the way. The two libraries, libkadm5clnt.a and libkadm5srv.a, export the identical kadm5 interface; for example, both contain definitions for kadm5_get_principal, and all other kadm5 functions. In most cases, the client library function just marshalls arguments and results into and out of an RPC call, whereas the server library function performs the actual operation on the database file. kadm5_init_*, however, are substantially different even though they export the same interface: on the client, they establish the RPC connection and GSS-API context, whereas on the server side the open the database files, read in the password dictionary, and the like. Also, the kadm5_free functions operate on local process memory in both libraries. The admin server is implemented as a nearly-stateless transaction server, where each admin API function represents a single transaction. No per-client or per-connection information is stored; only local database handles are maintained between requests. The RPC mechanism provides access to remote callers' authentication credentials for authorization purposes. The admin API is exported via an RPC interface that hides all details about network encoding, authentication, and encryption of data on the wire. The RPC mechanism does, however, allow the server to access the underlying authentication credentials for authorization purposes. The admin system maintains two databases: % \begin{itemize} \item The master Kerberos (KDC) database is used to store all the information that the Kerberos server understands, thus allowing the greatest functionality with no modifications to a standard KDC. \item The KDC database also stores kadm5-specific per-principal information in each principal's krb5_tl_data list. In a prior version, this data was stored in a separate admin principal database; thus, when this document refers to ``the admin principal database,'' it now refers to the appropriate krb5_tl_data entries in the KDC database. \item The policy database stores kadm5 policy information. \end{itemize} The per-principal information stored in the admin principal database consists of the principal's policy name and an array of the principal's previous keys. The old keys are stored encrypted in the key of the special principal ``kadmin/history'' that is created by the server library when it is first needed. Since a change in kadmin/history's key renders every principal's key history array useless, it can only be changed using the ovsec_adm_edit utility; that program will reencrypt every principal's key history in the new key.\footnote{ovsec_adm_edit has not yet been implemented, and there are currently no plans to implement it; thus, the history cannot currently be changed.} The server library refuses all requests to change kadmin/history's key. \section{API Handles} Each call to kadm5_init_* on the client or server creates a new API handle. The handles encapsulate the API and structure versions specified by kadm5_init_*'s caller and all other internal data needed by the library. A process can have multiple open API handles simultaneously by calling kadm5_init_* multiple times, and call can specify a different version, client or service principal, and so forth. Each kadm5 function verifies the handle it is given with the CHECK_HANDLE or _KADM5_CHECK_HANDLE macros. The CHECK_HANDLE macro differs for the client and server library because the handle types used by those libraries differ, so it is defined in both $<$client_internal.h$>$ and $<$server_internal.h$>$ in the library source directory. In each header file, CHECK_HANDLE first calls GENERIC_CHECK_HANDLE, defined in $<$admin_internal.h$>$, which verifies the magic number, API version, and structure version that is contained in both client and server handles. CHECK_HANDLE then calls either CLIENT_CHECK_HANDLE or SERVER_CHECK_HANDLE respectively to verify the client- or server-library specific handle fields. The CHECK_HANDLE macro is useful because it inlines the handle check instead of requiring a separate function call. However, using CHECK_HANDLE means that a source file cannot be compiled once and included into both the client and server library, because CHECK_HANDLE is always either specific to either the client or server library, not both. There are a number of functions that can be implemented with the same code in both the client and server libraries, however, including all of the kadm5_free functions and kadm5_chpass_principal_util. The _KADM5_CHECK_HANDLE macro solves this problem; instead of inlining the handle check, it calls the function _kadm5_check_handle which is defined separately in both the client and server library, in client_init.c and server_init.c. Since these two files are only compiled once and put in a single library, they simply verify the handle they are passed with CHECK_HANDLE and return the result. \section{API Versioning} The KADM5 system was designed by OpenVision to support multiple versions of the KADM5 API. MIT has not adopted this level of support, and considers the KADM5 C API to be unstable from release to release. This section describes the original design intent; bear in mind that only the most recent API is supported by current MIT krb5 releases, and that the API version does not necessarily change with API changes unless there is a need to do so for wire compatibility. Historically, three versions of the KADM5 API have existed: KADM5_API_VERSION_1 through KADM5_API_VERSION_3. The first version was equivalent to the initial OpenVision API, OVSEC_KADM_API_VERSION_1; the second was created during the initial integration of the OpenVision system into the MIT release; and the third was created for MIT krb5 1.8 to add lockout fields to policy entries. MIT dropped wire compatibility support for version 1 in MIT krb5 1.8 (as version 1 was never used in shipped MIT code), but retains wire compatibility support for version 2. Implementing a versioned API in C via with both local and RPC access presents a number of design issues, some of them quite subtle. The contexts in which versioning considerations must be made include: \begin{enumerate} \item Typedefs, function declarations, and defined constants depend on the API version a client is written to and must be correct at compile time. \item Each function in the server library must behave according to the API version specified by the caller at runtime to kadm5_init_*. \item The XDR functions used by the RPC layer to transmit function arguments and results must encode data structures correctly depending on the API version specified by the client at runtime. \item Each function in the client library must behave according to the API version specified by the caller at runtime to kadm5_init_*. \item The RPC server (kadmind) must accept calls from a client using any supported API version, and must then invoke the function in the server library corresponding to the RPC with the API version indicated by the client caller. \item When a first API function is invoked that needs to call a second function in the API on its own behalf, and that second API function's behavior depends on the API version specified, the first API function must either be prepared to call the second API function at whatever version its caller specifies or have a means of always calling the second API function at a pre-determined version. \end{enumerate} The following functions describe how each context is handled. \subsection{Designing for future compatibility} Any code whose behavior depends on the API version should be written so as to be compatible with future, currently unknown API versions on the grounds that any particular piece of API behavior will most likely not change between versions. For example, in the current system, the code is not written as ``if this is VERSION_1, do X, else if this is VERSION_2, do Y''; instead, it is written as ``if this is VERSION_1, do X; else, do Y.'' The former will require additional work when VERSION_3 is defined, even if ``do Y'' is still the correct action, whereas the latter will work without modification in that case. \subsection{Header file declarations} Typedefs, defined constants and macros, and function declarations may change between versions. A client is always written to a single, specific API version, and thus expects the header files to define everything according to that API. Failure of a header file to define values correctly will result in either compiler warnings (e.g. if the pointer type of a function argument changes) or fatal errors (e.g. if the number of arguments to a function changes, or the fields of a structure change). For example, in VERSION_1, kadm5_get_policy took a pointer to a pointer to a structure, and in VERSION_2 it takes a pointer to a structure; that would generate a warning if not correct. In VERSION_1, kadm5_randkey_principal accepted three arguments but in VERSION_2 accepts four; that would generate a fatal error. The header file defines everything correctly based on the value of the USE_KADM5_API_VERSION constant. The constant can be assigned to an integer corresponding to any supported API version, and defaults to the newest version. The header files then simply use an \#ifdef to include the right definitions: % \begin{verbatim} #if USE_KADM5_API_VERSION == 1 kadm5_ret_t kadm5_get_principal(void *server_handle, krb5_principal principal, kadm5_principal_ent_t *ent); #else kadm5_ret_t kadm5_get_principal(void *server_handle, krb5_principal principal, kadm5_principal_ent_t ent, long mask); #endif \end{verbatim} \subsection{Server library functions} Server library functions must know how many and what type of arguments to expect, and must operate on those arguments correctly, based on the API version with which they are invoked. The API version is contained in the handle that is always passed as their first argument, generated by kadm5_init_* (to which the client specified the API version to use at run-time). In general, it is probably unsafe for a compiled function in a library to re-interpret the number and type of defined arguments at run-time since the calling conventions may not allow it; for example, a function whose first argument was a short in one version and a pointer in the next might fail if it simply typed-casted the argument. In that case, the function would have to written to take variable arguments (i.e. use $<$stdarg.h$>$) and extract them from the stack based on the API version. Alternatively, a separate function for each API version could be defined, and $<$kadm5/admin.h$>$ could be written to \v{\#define} the exported function name based on the value of USE_KADM5_API_VERSION. In the current system, it turns out, that isn't necessary, and future implementors should take try to ensure that no version has semantics that will cause such problems in the future. All the functions in KADM5 that have different arguments or results between VERSION_1 and VERSION_2 do so simply by type-casting their arguments to the appropriate version and then have separate code paths to handle each one correctly. kadm5_get_principal, in svr_principal.c, is a good example. In VERSION_1, it took the address of a pointer to a kadm5_principal_ent_t to fill in with a pointer to allocated memory; in VERSION_2, it takes a pointer to a structure to fill in, and a mask of which fields in that structure should be filled in. Also, the contents of the kadm5_principal_ent_t changed slightly between the two versions. kadm5_get_principal handles versioning as follows (following along in the source code will be helpful): \begin{enumerate} \item If VERSION_1, it saves away its entry argument (address of a pointer to a structure) and resets its value to contain the address of a locally stack-allocated entry structure; this allows most of the function to written once, in terms of VERSION_2 semantics. If VERSION_1, it also resets its mask argument to be KADM5_PRINCIPAL_NORMAL_MASK, because that is the equivalent to VERSION_1 behavior, which was to return all the fields of the structure. \item The bulk of the function is implemented as expected for VERSION_2. \item The new fields in the VERSION_2 entry structure are assigned inside a block that is only execute if the caller specified VERSION_2. This saves a little time for a VERSION_1 caller. \item After the entry structure is filled, the function checks again if it was called as VERSION_1. If so, it allocates a new kadm5_principal_ent_t_v1 structure (which is conveniently defined in the header file) with malloc, copies the appropriate values from the entry structure into the VERSION_1 entry structure, and then writes the address of the newly allocated memory into address specified by the original entry argument which it had previously saved away. \end{enumerate} There is another complication involved in a function re-interpreting the number of arguments it receives at compile time---it cannot assign any value to an argument for which the client did not pass a value. For example, a VERSION_1 client only passes three arguments to kadm5_get_principal. If the implementation of kadm5_get_principal notices that the caller is VERSION_1 and therefore assigns its fourth argument, mask, to a value that mimics the VERSION_1 behavior, it may inadvertently overwrite data on its caller's stack. This problem can be avoided simply by using a true local variable in such cases, instead of treating an unpassed argument as a local variable. \subsection{XDR functions} The XDR functions used to encode function arguments and results must know how to encode the data for any API version. This is important both so that all the data gets correctly transmitted and so that protocol compatibility between clients or servers using the new library but an old API version is maintained; specific, new kadmind servers should support old kadm5 clients. The signature of all XDR functions is strictly defined: they take the address of an XDR function and the address of the data object to be encoded or decoded. It is thus impossible to provide the API version of the data object as an additional argument to an XDR function. There are two other means to convey the information, storing the API version to use as a field in the data object itself and creating separate XDR functions to handle each different version of the data object, and both of them are used in KADM5. In the client library, each kadm5 function collects its arguments into a single structure to be passed by the RPC; similarly, it expects all of the results to come back as a single structure from the RPC that it will then decode back into its constituent pieces (these are the standard ONC RPC semantics). In order to pass versioning information to the XDR functions, each function argument and result datatype has a filed to store the API version. For example, consider kadm5_get_principal's structures: % \begin{verbatim} struct gprinc_arg { krb5_ui_4 api_version; krb5_principal princ; long mask; }; typedef struct gprinc_arg gprinc_arg; bool_t xdr_gprinc_arg(); struct gprinc_ret { krb5_ui_4 api_version; kadm5_ret_t code; kadm5_principal_ent_rec rec; }; typedef struct gprinc_ret gprinc_ret; bool_t xdr_gprinc_ret(); \end{verbatim} % kadm5_get_principal (in client_principal.c) assigns the api_version field of the gprinc_arg to the version specified by its caller, assigns the princ field based on its arguments, and assigns the mask field from its argument if the caller specified VERSION_2. It then calls the RPC function clnt_call, specifying the XDR functions xdr_gprinc_arg and xdr_gprinc_ret to handle the arguments and results. xdr_gprinc_arg is invoked with a pointer to the gprinc_arg structure just described. It first encodes the api_version field; this allows the server to know what to expect. It then encodes the krb5_principal structure and, if api_version is VERSION_2, the mask. If api_version is not VERSION_2, it does not encode {\it anything} in place of the mask, because an old VERSION_1 server will not expect any other data to arrive on the wire there. The server performs the kadm5_get_principal call and returns its results in an XDR encoded gprinc_ret structure. clnt_call, which has been blocking until the results arrived, invokes xdr_gprinc_ret with a pointer to the encoded data for it to decode. xdr_gprinc_ret first decodes the api_version field, and then the code field since that is present in all versions to date. The kadm5_principal_ent_rec presents a problem, however. The structure does not itself contain an api_version field, but the structure is different between the two versions. Thus, a single XDR function cannot decode both versions of the structure because it will have no way to decide which version to expect. The solution is to have two functions, kadm5_principal_ent_rec_v1 and kadm5_principal_ent_rec, which always decode according to VERSION_1 or VERSION_2, respectively. gprinc_ret knows which one to invoke because it has the api_version field returned by the server (which is always the same as that specified by the client in the gpring_arg). In hindsight, it probably would have been better to encode the API version of all structures directly in a version field in the structure itself; then multiple XDR functions for a single data type wouldn't be necessary, and the data objects would stand complete on their own. This can be added in a future API version if desired. \subsection{Client library functions} Just as with server library functions, client library functions must be able to interpret their arguments and provide result according to the API version specified by the caller. Again, kadm5_get_principal (in client_principal.c) is a good example. The gprinc_ret structure that it gets back from clnt_call contains a kadm5_principal_ent_rec or a kadm5_principal_ent_rec_v1 (the logic is simplified somewhat because the VERSION_2 structure only has new fields added on the end). If kadm5_get_principal was invoked with VERSION_2, that structure should be copied into the pointer provided as the entry argument; if it was invoked with VERSION_1, however, the structure should be copied into allocated memory whose address is then written into the pointer provided by the entry argument. Client library functions make this determination based on the API version specified in the provided handle, just like server library functions do. \subsection{Admin server stubs} When an RPC call arrives at the server, the RPC layer authenticates the call using the GSS-API, decodes the arguments into their single-structure form (ie: a gprinc_arg) and dispatches the call to a stub function in the server (in server_stubs.c). The stub function first checks the caller's authorization to invoke the function and, if authorized, calls the kadm5 function corresponding to the RPC function with the arguments specified in the single-structure argument. Once again, kadm5_get_principal is a good example for the issues involved. The contents of the gprinc_arg given to the stub (get_principal_1) depends on the API version the caller on the client side specified; that version is available to the server in the api_version field of the gprinc_arg. When the server calls kadm5_get_principal in the server library, it must give that function an API handle that contains the API version requested by the client; otherwise the function semantics might not be correct. One possibility would be for the server to call kadm5_init for each client request, specifying the client's API version number and thus generating an API handle with the correct version, but that would be prohibitively inefficient. Instead, the server dips down in the server library's internal abstraction barrier, using the function new_server_handle to cons up a server handle based on the server's own global_server_handle but using the API version specified by the client. The server then passes the newly generated handle to kadm5_get_principal, ensuring the right behavior, and creates the gprinc_ret structure in a manner similar to that described above. Although new_server_handle solves the problem of providing the server with an API handle containing the right API version number, it does not solve another problem: that a single source file, server_stubs.c, needs to be able to invoke functions with arguments appropriate for multiple API versions. If the client specifies VERSION_1, for example, the server must invoke kadm5_get_principal with three arguments, but if the client specifies VERSION_2 the server must invoke kadm5_get_principal with four arguments. The compiler will not allow this inconsistency. The server defines wrapper functions in a separate source file that match the old version, and the separate source file is compiled with USE_KADM5_API_VERSION set to the old version; see kadm5_get_principal_v1 in server_glue_v1.c. The server then calls the correct variant of kadm5_get_principal_* based on the API version and puts the return values into the gprinc_ret in a manner similar to that described above. Neither of these solutions are necessarily correct. new_server_handle violates the server library's abstraction barrier and is at best a kludge; the server library should probably export a function to provide this behavior without violating the abstraction; alternatively, the librar should be modified so that having the server call kadm5_init for each client RPC request would not be too inefficient. The glue functions in server_glue_v1.c really are not necessary, because the server stubs could always just pass dummy arguments for the extra arguments; after all, the glue functions pass {\it nothing} for the extra arguments, so they just end up as stack garbage anyway. Another alternative to the new_server_handle problem is to have the server always invoke server library functions at a single API version, and then have the stubs take care of converting the function arguments and results back into the form expected by the caller. In general, however, this might require the stubs to duplicate substantial logic already present in the server library and further violate the server library's abstraction barrier. \subsection{KADM5 self-reference} Some kadm5 functions call other kadm5 functions ``on their own behalf'' to perform functionality that is necessary but that does not directly affect what the client sees. For example, kadm5_chpass_principal has to enforce password policies; thus, it needs to call kadm5_get_principal and, if the principal has a policy, kadm5_get_policy and kadm5_modify_principal in the process of changing a principal's password. This leads to a complication: what API handle should kadm5_chpass_principal pass to the other kadm5 functions it calls? The ``obvious,'' but wrong, answer is that it should pass the handle it was given by its caller. The caller may provide an API handle specifying any valid API version. Although the semantics of kadm5_chpass_principal did not change between VERSION_1 and VERSION_2, the declarations of both kadm5_get_principal and kadm5_get_policy did. Thus, to use the caller's API handle, kadm5_chpass_principal will have to have a separate code path for each API version, even though it itself did not change between versions, and duplicate a lot of logic found elsewhere in the library. Instead, each API handle contains a ``local-use handle,'' or lhandle, that kadm5 functions should use to call other kadm5 functions. For example, the client-side library's handle structure is: % \begin{verbatim} typedef struct _kadm5_server_handle_t { krb5_ui_4 magic_number; krb5_ui_4 struct_version; krb5_ui_4 api_version; char * cache_name; int destroy_cache; CLIENT * clnt; krb5_context context; kadm5_config_params params; struct _kadm5_server_handle_t *lhandle; } kadm5_server_handle_rec, *kadm5_server_handle_t; \end{verbatim} % The lhandle field is allocated automatically when the handle is created. All of the fields of the API handle that are accessed outside kadm5_init are also duplicated in the lhandle; however, the api_version field of the lhandle is always set to a {\it constant} value, regardless of the API version specified by the caller to kadm5_init. In the current implementation, the lhandle's api_version is always VERSION_2. By passing the caller's handle's lhandle to recursively called kadm5 functions, a kadm5 function is assured of invoking the second kadm5 function with a known API version. Additionally, the lhandle's lhandle field points back to the lhandle, in case kadm5 functions call themselves more than one level deep; handle$->$lhandle always points to the same lhandle, no matter how many times the indirection is performed. This scheme might break down if a kadm5 function has to call another kadm5 function to perform operations that they client will see and for its own benefit, since the semantics of the recursively-called kadm5 function may depend on the API version specified and the client may be depending on a particular version's behavior. Future implementors should avoid creating a situation in which this is possible. \section{Server Main} The admin server starts by trapping all fatal signals and directing them to a cleanup-and-exit function. It then creates and exports the RPC interface and enters its main loop. The main loop dispatches all incoming requests to the RPC mechanism. In a previous version, after 15 seconds of inactivity, the server closed all open databases; each database was be automatically reopened by the API function implementations as necessary. That behavior existed to protect against loss of written data before the process exited. The current database libraries write all changes out to disk immediately, however, so this behavior is no longer required or performed. \section{Remote Procedure Calls} The RPC for the Admin system will be based on ONC RPC. ONC RPC is used because it is a well-known, portable RPC mechanism. The underlying external data representation (xdr) mechanisms for wire encapsulation are well-known and extensible. Authentication to the admin server and encryption of all RPC functional arguments and results are be handled via the AUTH_GSSAPI authentication flavor of ONC RPC. \section{Database Record Types} \label{sec:db-types} \subsection{Admin Principal, osa_princ_ent_t} The admin principal database stores records of the type osa_princ_ent_t (declared in $<$kadm5/adb.h$>$), which is the subset of the kadm5_principal_ent_t structure that is not stored in the Kerberos database plus the necessary bookkeeping information. The records are keyed by the ASCII representation of the principal's name, including the trailing NULL. \begin{verbatim} typedef struct _osa_pw_hist_t { int n_key_data; krb5_key_data *key_data; } osa_pw_hist_ent, *osa_pw_hist_t; typedef struct _osa_princ_ent_t { char * policy; u_int32 aux_attributes; unsigned int old_key_len; unsigned int old_key_next; krb5_kvno admin_history_kvno; osa_pw_hist_ent *old_keys; u_int32 num_old_keys; u_int32 next_old_key; krb5_kvno admin_history_kvno; osa_pw_hist_ent *old_keys; } osa_princ_ent_rec, *osa_princ_ent_t; \end{verbatim} The fields that are different from kadm5_principal_ent_t are: \begin{description} \item[num_old_keys] The number of previous keys in the old_keys array. This value must be 0 $\le$ num_old_keys $<$ pw_history_num. \item[old_key_next] The index into old_keys where the next key should be inserted. This value must be 0 $\le$ old_key_next $\le$ num_old_keys. \item[admin_history_kvno] The key version number of the kadmin/history principal's key used to encrypt the values in old_keys. If the server library finds that kadmin/history's kvno is different from the value in this field, it returns KADM5_BAD_HIST_KEY. \item[old_keys] The array of the principal's previous passwords, each encrypted in the kadmin/history key. There are num_old_keys elements. Each ``password'' in the array is itself an array of n_key_data krb5_key_data structures, one for each keysalt type the password was encoded in. \end{description} \subsection{Policy, osa_policy_ent_t} The policy database stores records of the type osa_policy_ent_t (declared in $<$kadm5/adb.h$>$) , which is all of kadm5_policy_ent_t plus necessary bookkeeping information. The records are keyed by the policy name. \begin{verbatim} typedef struct _osa_policy_ent_t { char *policy; u_int32 pw_min_life; u_int32 pw_max_life; u_int32 pw_min_length; u_int32 pw_min_classes; u_int32 pw_history_num; u_int32 refcnt; } osa_policy_ent_rec, *osa_policy_ent_t; \end{verbatim} \subsection{Kerberos, krb5_db_entry} The Kerberos database stores records of type krb5_db_entry, which is defined in the $<$k5-int.h$>$ header file. The semantics of each field are defined in the libkdb functional specification. \section{Database Access Methods} \subsection{Principal and Policy Databases} This section describes the database abstraction used for the admin policy database; the admin principal database used to be treated in the same manner but is now handled more directly as krb5_tl_data; thus, nothing in this section applies to it any more. Since both databases export equivalent functionality, the API is only described once. The character T is used to represent both ``princ'' and ``policy''. The location of the principal database is defined by the configuration parameters given to any of the kadm5_init functions in the server library. Note that this is {\it only} a database abstraction. All functional intelligence, such as maintaining policy reference counts or sanity checking, must be implemented above this layer. Prototypes for the osa functions are supplied in $<$kadm5/adb.h$>$. The routines are defined in libkadm5srv.a. They require linking with the Berkely DB library. \subsubsection{Error codes} The database routines use com_err for error codes. The error code table name is ``adb'' and the offsets are the same as the order presented here. The error table header file is $<$kadm5/adb_err.h$>$. Callers of the OSA routines should first call init_adb_err_tbl() to initialize the database table. \begin{description} \item[OSA_ADB_OK] Operation successful. \item[OSA_ADB_FAILURE] General failure. \item[OSA_ADB_DUP] Operation would create a duplicate database entry. \item[OSA_ADB_NOENT] Named entry not in database. \item[OSA_ADB_BAD_PRINC] The krb5_principal structure is invalid. \item[OSA_ADB_BAD_POLICY] The specified policy name is invalid. \item[OSA_ADB_XDR_FAILURE] The principal or policy structure cannot be encoded for storage. \item[OSA_ADB_BADLOCKMODE] Bad lock mode specified. \item[OSA_ADB_CANTLOCK_DB] Cannot lock database, presumably because it is already locked. \item[OSA_ADB_NOTLOCKED] Internal error, database not locked when unlock is called. \item[OSA_ADB_NOLOCKFILE] KADM5 administration database lock file missing. \end{description} Database functions can also return system errors. Unless otherwise specified, database functions return OSA_ADB_OK. \subsubsection{Locking} All of the osa_adb functions except open and close lock and unlock the database to prevent concurrency collisions. The overall locking algorithm is as follows: \begin{enumerate} \item osa_adb_open_T calls osa_adb_init_db to allocate the osa_adb_T_t structure and open the locking file for further use. \item Each osa_adb functions locks the locking file and opens the appropriate database with osa_adb_open_and_lock, performs its action, and then closes the database and unlocks the locking file with osa_adb_close_and_unlock. \item osa_adb_close_T calls osa_adb_fini_db to close the locking file and deallocate the db structure. \end{enumerate} Functions which modify the database acquire an exclusive lock, others acquire a shared lock. osa_adb_iter_T acquires an exclusive lock for safety but as stated below consequences of modifying the database in the iteration function are undefined. \subsubsection{Function descriptions} \begin{verbatim} osa_adb_ret_t osa_adb_create_T_db(kadm5_config_params *params) \end{verbatim} % Create the database and lockfile specified in params. The database must not already exist, or EEXIST is returned. The lock file is only created after the database file has been created successfully. \begin{verbatim} osa_adb_ret_t osa_adb_rename_T_db(kadm5_config_params *fromparams, kadm5_config_params *toparams) \end{verbatim} % Rename the database named by fromparams to that named by toparams. The fromparams database must already exist; the toparams database may exist or not. When the function returns, the database named by fromparams no longer exists, and toparams has been overwritten with fromparams. This function acquires a permanent lock on both databases for the duration of its operation, so a failure is likely to leave the databases unusable. \begin{verbatim} osa_adb_ret_t osa_adb_destroy_policy_db(kadm5_config_params *params) \end{verbatim} % Destroy the database named by params. The database file and lock file are deleted. \begin{verbatim} osa_adb_ret_t osa_adb_open_T(osa_adb_T_t *db, char *filename); \end{verbatim} % Open the database named filename. Returns OSA_ADB_NOLOCKFILE if the database does not exist or if the lock file is missing. The database is not actually opened in the operating-system file sense until a lock is acquire. \begin{verbatim} osa_adb_ret_t osa_adb_close_T(osa_adb_T_t db); \end{verbatim} % Release all shared or exclusive locks (on BOTH databases, since they use the same lock file) and close the database. It is an error to exit while a permanent lock is held; OSA_ADB_NOLOCKFILE is returned in this case. \begin{verbatim} osa_adb_ret_t osa_adb_get_lock(osa_adb_T_t db, int mode) \end{verbatim} Acquire a lock on the administration databases; note that both databases are locked simultaneously by a single call. The mode argument can be OSA_ADB_SHARED, OSA_ADB_EXCLUSIVE, or OSA_ADB_PERMANENT. The first two and the third are really disjoint locking semantics and should not be interleaved. Shared and exclusive locks have the usual semantics, and a program can upgrade a shared lock to an exclusive lock by calling the function again. A reference count of open locks is maintained by this function and osa_adb_release_lock so the functions can be called multiple times; the actual lock is not released until the final osa_adb_release_lock. Note, however, that once a lock is upgraded from shared to exclusive, or from exclusive to permanent, it is not downgraded again until released completely. In other words, get_lock(SHARED), get_lock(EXCLUSIVE), release_lock() leaves the process with an exclusive lock with a reference count of one. An attempt to get a shared or exclusive lock that conflicts with another process results in the OSA_ADB_CANLOCK_DB error code. This function and osa_adb_release_lock are called automatically as needed by all other osa_adb functions to acquire shared and exclusive locks and so are not normally needed. They can be used explicitly by a program that wants to perform multiple osa_adb functions within the context of a single lock. Acquiring an OSA_ADB_PERMANENT lock is different. A permanent lock consists of first acquiring an exclusive lock and then {\it deleting the lock file}. Any subsequent attempt to acquire a lock by a different process will fail with OSA_ADB_NOLOCKFILE instead of OSA_ADB_CANTLOCK_DB (attempts in the same process will ``succeed'' because only the reference count gets incremented). The lock file is recreated by osa_adb_release_lock when the last pending lock is released. The purpose of a permanent lock is to absolutely ensure that the database remain locked during non-atomic operations. If the locking process dies while holding a permanent lock, all subsequent osa_adb operations will fail, even through a system reboot. This is useful, for example, for ovsec_adm_import which creates both new database files in a temporary location and renames them into place. If both renames do not fully complete the database will probably be inconsistent and everything should stop working until an administrator can clean it up. \begin{verbatim} osa_adb_ret_t osa_adb_release_lock(osa_adb_T_t db) \end{verbatim} Releases a shared, exclusive, or permanent lock acquired with osa_adb_get_lock, or just decrements the reference count if multiple locks are held. When a permanent lock is released, the lock file is re-created. All of a process' shared or exclusive database locks are released when the process terminates. A permanent lock is {\it not} released when the process exits (although the exclusive lock it begins with obviously is). \begin{verbatim} osa_adb_ret_t osa_adb_create_T(osa_adb_T_t db, osa_T_ent_t entry); \end{verbatim} % Adds the entry to the database. All fields are defined. Returns OSA_ADB_DUP if it already exists. \begin{verbatim} osa_adb_ret_t osa_adb_destroy_T(osa_adb_T_t db, osa_T_t name); \end{verbatim} Removes the named entry from the database. Returns OSA_ADB_NOENT if it does not exist. \begin{verbatim} osa_adb_ret_t osa_adb_get_T(osa_adb_T_t db, osa_T_t name, osa_princ_ent_t *entry); \end{verbatim} Looks up the named entry in the db, and returns it in *entry in allocated storage that must be freed with osa_adb_free_T. Returns OSA_ADB_NOENT if name does not exist, OSA_ADB_MEM if memory cannot be allocated. \begin{verbatim} osa_adb_ret_t osadb_adb_put_T(osa_adb_T_t db, osa_T_ent_t entry); \end{verbatim} Modifies the existing entry named in entry. All fields must be filled in. Returns OSA_DB_NOENT if the named entry does not exist. Note that this cannot be used to rename an entry; rename is implemented by deleting the old name and creating the new one (NOT ATOMIC!). \begin{verbatim} void osa_adb_free_T(osa_T_ent_t); \end{verbatim} Frees the memory associated with an osa_T_ent_t allocated by osa_adb_get_T. \begin{verbatim} typedef osa_adb_ret_t (*osa_adb_iter_T_func)(void *data, osa_T_ent_t entry); osa_adb_ret_t osa_adb_iter_T(osa_adb_T_t db, osa_adb_iter_T_func func, void *data); \end{verbatim} Iterates over every entry in the database. For each entry ent in the database db, the function (*func)(data, ent) is called. If func returns an error code, osa_adb_iter_T returns an error code. If all invocations of func return OSA_ADB_OK, osa_adb_iter_T returns OSA_ADB_OK. The function func is permitted to access the database, but the consequences of modifying the database during the iteration are undefined. \subsection{Kerberos Database} Kerberos uses the libkdb interface to store krb5_db_entry records. It can be accessed and modified in parallel with the Kerberos server, using functions that are defined inside the KDC and the libkdb.a. The libkdb interface is defined in the libkdb functional specifications. \subsubsection{Initialization and Key Access} Keys stored in the Kerberos database are encrypted in the Kerberos master key. The admin server will therefore have to acquire the key before it can perform any key-changing operations, and will have to decrypt and encrypt the keys retrieved from and placed into the database via krb5_db_get_principal and _put_principal. This section describes the internal admin server API that will be used to perform these functions. \begin{verbatim} krb5_principal master_princ; krb5_encrypt_block master_encblock; krb5_keyblock master_keyblock; void kdc_init_master() \end{verbatim} kdc_init_master opens the database and acquires the master key. It also sets the global variables master_princ, master_encblock, and master_keyblock: \begin{itemize} \item master_princ is set to the name of the Kerberos master principal (\v{K/M@REALM}). \item master_encblock is something I have no idea about. \item master_keyblock is the Kerberos master key \end{itemize} \begin{verbatim} krb5_error_code kdb_get_entry_and_key(krb5_principal principal, krb5_db_entry *entry, krb5_keyblock *key) \end{verbatim} kdb_get_entry_and_key retrieves the named principal's entry from the database in entry, and decrypts its key into key. The caller must free entry with krb5_dbm_db_free_principal and free key-$>$contents with free.\footnote{The caller should also \v{memset(key-$>$contents, 0, key-$>$length)}. There should be a function krb5_free_keyblock_contents for this, but there is not.} \begin{verbatim} krb5_error_code kdb_put_entry_pw(krb5_db_entry *entry, char *pw) \end{verbatim} kdb_put_entry_pw stores entry in the database. All the entry values must already be set; this function does not change any of them except the key. pw, the NULL-terminated password string, is converted to a key using string-to-key with the salt type specified in entry-$>$salt_type.\footnote{The salt_type should be set based on the command line arguments to the kadmin server (see the ``Command Line'' section of the functional specification).} \section{Admin Principal and Policy Database Implementation} The admin principal and policy databases will each be stored in a single hash table, implemented by the Berkeley 4.4BSD db library. Each record will consist of an entire osa_T_ent_t. The key into the hash table is the entry name (for principals, the ASCII representation of the name). The value is the T entry structure. Since the key and data must be self-contained, with no pointers, the Sun xdr mechanisms will be used to marshal and unmarshal data in the database. The server in the first release will be single-threaded in that a request will run to completion (or error) before the next will run, but multiple connections will be allowed simultaneously. \section{ACLs, acl_check} The ACL mechanism described in the ``Authorization ACLs'' section of the functional specifications will be implemented by the acl_check function. \begin{verbatim} enum access_t { ACCESS_DENIED = 0, ACCESS_OK = 1, }; enum access_t acl_check(krb5_principal princ, char *priv); \end{verbatim} The priv argument must be one of ``get'', ``add'', ``delete'', or ``modify''. acl_check returns 1 if the principal princ has the named privilege, 0 if it does not. \section{Function Details} This section discusses specific design issues for Admin API functions that are not addressed by the functional specifications. \subsection{kadm5_create_principal} If the named principal exists in either the Kerberos or admin principal database, but not both, return KADM5_BAD_DB. The principal's initial key is not stored in the key history array at creation time. \subsection{kadm5_delete_principal} If the named principal exists in either the Kerberos or admin principal database, but not both, return KADM5_BAD_DB. \subsection{kadm5_modify_principal} If the named principal exists in either the Kerberos or admin principal database, but not both, return KADM5_BAD_DB. If pw_history_num changes and the new value $n$ is smaller than the current value of num_old_keys, old_keys should end up with the $n$ most recent keys; these are found by counting backwards $n$ elements in old_keys from old_key_next. old_key_nexts should then be reset to 0, the oldest of the saved keys, and num_old_keys set to $n$, the new actual number of old keys in the array. \subsection{kadm5_chpass_principal, randkey_principal} The algorithm for determining whether a password is in the principal's key history is complicated by the use of the kadmin/history \k{h} encrypting key. \begin{enumerate} \item For kadm5_chpass_principal, convert the password to a key using string-to-key and the salt method specified by the command line arguments. \item If the POLICY bit is set and pw_history_num is not zero, check if the new key is in the history. \begin{enumerate} \item Retrieve the principal's current key and decrypt it with \k{M}. If it is the same as the new key, return KADM5_PASS_REUSE. \item Retrieve the kadmin/history key \k{h} and decrypt it with \k{M}. \item Encrypt the principal's new key in \k{h}. \item If the principal's new key encrypted in \k{h} is in old_keys, return KADM5_PASS_REUSE. \item Encrypt the principal's current key in \k{h} and store it in old_keys. \item Erase the memory containing \k{h}. \end{enumerate} \item Encrypt the principal's new key in \k{M} and store it in the database. \item Erase the memory containing \k{M}. \end{enumerate} To store the an encrypted key in old_keys, insert it as the old_key_next element of old_keys, and increment old_key_next by one modulo pw_history_num. \subsection{kadm5_get_principal} If the named principal exists in either the Kerberos or admin principal database, but not both, return KADM5_BAD_DB. \end{document} krb5-1.22.1/doc/kadm5/adb-unit-test.tex0000664000175000017500000000621015051422640017310 0ustar ghudsonghudson% This document is included for historical purposes only, and does not % apply to krb5 today. \documentstyle[times,fullpage]{article} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Make _ actually generate an _, and allow line-breaking after it. \let\underscore=\_ \catcode`_=13 \def_{\underscore\penalty75\relax} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\test}[1]{\begin{description} \setlength{\itemsep}{0pt} #1 \end{description} } \newcommand{\numtest}[2]{\begin{description} \setlength{\itemsep}{0pt} \Number{#1} #2 \end{description} } \newcommand{\Number}[1]{\item[Number:] #1} \newcommand{\Reason}[1]{\item[Reason:] #1} %\newcommand{\Call}[1]{\item[Call:] #1} \newcommand{\Expected}[1]{\item[Expected:] #1} \newcommand{\Conditions}[1]{\item[Conditions:] #1} \newcommand{\Priority}[1]{\item[Priority:] #1} \newcommand{\Status}[1]{\item[Status:] #1} %\newcommand{\Number}[1]{} %\newcommand{\Reason}[1]{} \newcommand{\Call}[1]{} %\newcommand{\Expected}[1]{} %\newcommand{\Conditions}[1]{} %\newcommand{\Priority}[1]{} \title{OpenV*Secure Admin Database API\\ Unit Test Description} \author{Jonathan I. Kamens} \begin{document} \maketitle %\tableofcontents \section{Introduction} The following is a description of a black-box unit test of the OpenV*Secure Admin Database API (osa_adb). Each API function is listed, followed by the tests that should be performed on it. The tests described here are based on the ``OV*Secure Admin Server Implementation Design'' revision 1.14. \section{osa_adb_get_lock and osa_adb_release_lock} \numtest{1}{ \Reason{A shared lock can be acquired.} \Status{Implemented} } \numtest{2}{ \Reason{An exclusive lock can be acquired and released.} \Status{Implemented} } \numtest{3}{ \Reason{A permanent lock can be acquired and released.} \Status{Implemented} } \numtest{4}{ \Reason{Attempting to release a lock when none is held fails with NOTLOCKED.} \Status{Implemented} } \numtest{5}{ \Reason{Two processes can both acquire a shared lock.} \Status{Implemented} } \numtest{6}{ \Reason{An attempt to acquire a shared lock while another process holds an exclusive lock fails with CANTLOCK_DB.} \Status{Implemented} } \numtest{7}{ \Reason{An attempt to acquire an exclusive lock while another process holds a shared lock fails with CANTLOCK_DB.} \Status{Implemented} } \numtest{8}{ \Reason{An attempt to open the database while a process holds a permanent lock fails with NO_LOCKFILE.} \Status{Implemented} } \numtest{9}{ \Reason{An attempt to acquire an exclusive lock while a process holds a permanent lock fails with NO_LOCKFILE.} \Status{Implemented} } \numtest{10}{ \Reason{Acquiring a permanent lock deletes the lockfile.} \Status{Implemented} } \numtest{11}{ \Reason{Releasing a permanent lock re-creates the lockfile.} \Status{Implemented} } \numtest{12}{ \Reason{A process can perform a get operation while another process holds a shared lock.} \Status{Implemented} } \numtest{13}{ \Reason{A process that is running and has opened the adb principal database can retrieve a principal created after the open occurred.} \Status{Implemented, but not working} } \end{document} krb5-1.22.1/doc/about.rst0000664000175000017500000000345115051422640014755 0ustar ghudsonghudsonContributing to the MIT Kerberos Documentation ============================================== We are looking for documentation writers and editors who could contribute towards improving the MIT KC documentation content. If you are an experienced Kerberos developer and/or administrator, please consider sharing your knowledge and experience with the Kerberos Community. You can suggest your own topic or write about any of the topics listed `here `__. If you have any questions, comments, or suggestions on the existing documents, please send your feedback via email to krb5-bugs@mit.edu. The HTML version of this documentation has a "FEEDBACK" link to the krb5-bugs@mit.edu email address with a pre-constructed subject line. Background ---------- Starting with release 1.11, the Kerberos documentation set is unified in a central form. Man pages, HTML documentation, and PDF documents are compiled from reStructuredText sources, and the application developer documentation incorporates Doxygen markup from the source tree. This project was undertaken along the outline described `here `__. Previous versions of Kerberos 5 attempted to maintain separate documentation in the texinfo format, with separate groff manual pages. Having the API documentation disjoint from the source code implementing that API resulted in the documentation becoming stale, and over time the documentation ceased to match reality. With a fresh start and a source format that is easier to use and maintain, reStructuredText-based documents should provide an improved experience for the user. Consolidating all the documentation formats into a single source document makes the documentation set easier to maintain. krb5-1.22.1/doc/threads.txt0000664000175000017500000000764715051422640015317 0ustar ghudsonghudsonThread safety in the MIT Kerberos libraries The return value from krb5_cc_default_name is a handle on internal storage from the krb5_context. It is valid only until krb5_cc_set_default_name or krb5_free_context is called. If krb5_cc_set_default_name may be called, the calling code must ensure that the storage returned by krb5_cc_default_name is no longer in use by that time. Any use of krb5_context must be confined to one thread at a time by the application code. Uses of credentials caches, replay caches, and keytabs may happen in multiple threads simultaneously as long as none of them destroys the object while other threads may still be using it. (Any internal data modification in those objects will be protected by mutexes or other means, within the krb5 library.) The simple, exposed data structures in krb5.h like krb5_principal are not protected; they should not be used in one thread while another thread might be modifying them. (TO DO: Build a list of which calls keep references to supplied data or return references to otherwise-referenced data, as opposed to everything making copies.) [ This part is a little outdated already. ] // Between these two, we should be able to do pure compile-time // and pure run-time initialization. // POSIX: partial initializer is PTHREAD_MUTEX_INITIALIZER, // finish does nothing // Windows: partial initializer is zero/empty, // finish does the actual work and runs at load time // debug: partial initializer sets one magic value, // finish verifies, sets a new magic value k5_mutex_t foo_mutex = K5_MUTEX_PARTIAL_INITIALIZER; int k5_mutex_finish_init(k5_mutex_t *); // for dynamic allocation int k5_mutex_init(k5_mutex_t *); // Must work for both kinds of allocation, even if it means adding // a flag. int k5_mutex_destroy(k5_mutex_t *); // // Per library, one function to finish the static mutex // initialization. // // A second function called at various possible "first" entry // points which either calls pthread_once on the first function // (POSIX), or checks some flag set by the first function (Windows, // debug support), and possibly returns an error. // // A third function for library termination calls mutex_destroy on // each mutex for the library. // // int k5_mutex_lock(k5_mutex_t *); int k5_mutex_unlock(k5_mutex_t *); // Optional (always defined, but need not do anything): void k5_mutex_assert_locked(k5_mutex_t *); void k5_mutex_assert_unlocked(k5_mutex_t *); k5_key_t key; int k5_key_create(k5_key_t *, void (*destructor)(void *)); void *k5_getspecific(k5_key_t); int k5_setspecific(k5_key_t, const void *); ... stuff to signal library termination ... This is **NOT** an exported interface, and is subject to change. On many platforms with weak reference support, we can declare certain symbols to be weak, and test the addresses before calling them. The references generally will be non-null if the application pulls in the pthread support. Sometimes stubs are present in the C library for some of these routines, and sometimes they're not functional; if so, we need to figure out which ones, and check for the presence of some *other* routines. AIX 4.3.3 doesn't support weak references. However, it looks like calling dlsym(NULL) causes the pthread library to get loaded, so we're going to just go ahead and link against it anyways. On Tru64 we also link against the thread library always. For now, the basic model is: If weak references are supported, use them. Else, assume support is present; if that means explicitly pulling in the thread library, so be it. The locking described above may not be sufficient, at least for good performance. At some point we may want to switch to read/write locks, so multiple threads can grovel over a data structure at once as long as they don't change it. See also notes in src/include/k5-thread.h. krb5-1.22.1/doc/appdev/0000775000175000017500000000000015051422640014365 5ustar ghudsonghudsonkrb5-1.22.1/doc/appdev/h5l_mit_apidiff.rst0000664000175000017500000000354615051422640020152 0ustar ghudsonghudsonDifferences between Heimdal and MIT Kerberos API ================================================ .. tabularcolumns:: |l|l| .. table:: ======================================== ================================================= :c:func:`krb5_auth_con_getaddrs()` H5l: If either of the pointers to local_addr and remote_addr is not NULL, it is freed first and then reallocated before being populated with the content of corresponding address from authentication context. :c:func:`krb5_auth_con_setaddrs()` H5l: If either address is NULL, the previous address remains in place :c:func:`krb5_auth_con_setports()` H5l: Not implemented as of version 1.3.3 :c:func:`krb5_auth_con_setrecvsubkey()` H5l: If either port is NULL, the previous port remains in place :c:func:`krb5_auth_con_setsendsubkey()` H5l: Not implemented as of version 1.3.3 :c:func:`krb5_cc_set_config()` MIT: Before version 1.10 it was assumed that the last argument *data* is ALWAYS non-zero. :c:func:`krb5_cccol_last_change_time()` MIT: not implemented :c:func:`krb5_set_default_realm()` H5l: Caches the computed default realm context field. If the second argument is NULL, it tries to retrieve it from libdefaults or DNS. MIT: Computes the default realm each time if it wasn't explicitly set in the context ======================================== ================================================= krb5-1.22.1/doc/appdev/gssapi.rst0000664000175000017500000010365615051422640016420 0ustar ghudsonghudsonDeveloping with GSSAPI ====================== The GSSAPI (Generic Security Services API) allows applications to communicate securely using Kerberos 5 or other security mechanisms. We recommend using the GSSAPI (or a higher-level framework which encompasses GSSAPI, such as SASL) for secure network communication over using the libkrb5 API directly. GSSAPIv2 is specified in :rfc:`2743` and :rfc:`2744`. Also see :rfc:`7546` for a description of how to use the GSSAPI in a client or server program. This documentation will describe how various ways of using the GSSAPI will behave with the krb5 mechanism as implemented in MIT krb5, as well as krb5-specific extensions to the GSSAPI. Name types ---------- A GSSAPI application can name a local or remote entity by calling gss_import_name_, specifying a name type and a value. The following name types are supported by the krb5 mechanism: * **GSS_C_NT_HOSTBASED_SERVICE**: The value should be a string of the form ``service`` or ``service@hostname``. This is the most common way to name target services when initiating a security context, and is the most likely name type to work across multiple mechanisms. * **GSS_KRB5_NT_PRINCIPAL_NAME**: The value should be a principal name string. This name type only works with the krb5 mechanism, and is defined in the ```` header. * **GSS_C_NT_USER_NAME** or **GSS_C_NULL_OID**: The value is treated as an unparsed principal name string, as above. These name types may work with mechanisms other than krb5, but will have different interpretations in those mechanisms. **GSS_C_NT_USER_NAME** is intended to be used with a local username, which will parse into a single-component principal in the default realm. * **GSS_C_NT_ANONYMOUS**: The value is ignored. The anonymous principal is used, allowing a client to authenticate to a server without asserting a particular identity (which may or may not be allowed by a particular server or Kerberos realm). * **GSS_C_NT_MACHINE_UID_NAME**: The value is uid_t object. On Unix-like systems, the username of the uid is looked up in the system user database and the resulting username is parsed as a principal name. * **GSS_C_NT_STRING_UID_NAME**: As above, but the value is a decimal string representation of the uid. * **GSS_C_NT_EXPORT_NAME**: The value must be the result of a gss_export_name_ call. * **GSS_KRB5_NT_ENTERPRISE_NAME**: The value should be a krb5 enterprise name string (see :rfc:`6806` section 5), in the form ``user@suffix``. This name type is used to convey alias names, and is defined in the ```` header. (New in release 1.17.) * **GSS_KRB5_NT_X509_CERT**: The value should be an X.509 certificate encoded according to :rfc:`5280`. This name form can be used for the desired_name parameter of gss_acquire_cred_impersonate_name(), to identify the S4U2Self user by certificate. (New in release 1.19.) Initiator credentials --------------------- A GSSAPI client application uses gss_init_sec_context_ to establish a security context. The *initiator_cred_handle* parameter determines what tickets are used to establish the connection. An application can either pass **GSS_C_NO_CREDENTIAL** to use the default client credential, or it can use gss_acquire_cred_ beforehand to acquire an initiator credential. The call to gss_acquire_cred_ may include a *desired_name* parameter, or it may pass **GSS_C_NO_NAME** if it does not have a specific name preference. If the desired name for a krb5 initiator credential is a host-based name, it is converted to a principal name of the form ``service/hostname`` in the local realm, where *hostname* is the local hostname if not specified. The hostname will be canonicalized using forward name resolution, and possibly also using reverse name resolution depending on the value of the **rdns** variable in :ref:`libdefaults`. If a desired name is specified in the call to gss_acquire_cred_, the krb5 mechanism will attempt to find existing tickets for that client principal name in the default credential cache or collection. If the default cache type does not support a collection, and the default cache contains credentials for a different principal than the desired name, a **GSS_S_CRED_UNAVAIL** error will be returned with a minor code indicating a mismatch. If no existing tickets are available for the desired name, but the name has an entry in the default client :ref:`keytab_definition`, the krb5 mechanism will acquire initial tickets for the name using the default client keytab. If no desired name is specified, credential acquisition will be deferred until the credential is used in a call to gss_init_sec_context_ or gss_inquire_cred_. If the call is to gss_init_sec_context_, the target name will be used to choose a client principal name using the credential cache selection facility. (This facility might, for instance, try to choose existing tickets for a client principal in the same realm as the target service). If there are no existing tickets for the chosen principal, but it is present in the default client keytab, the krb5 mechanism will acquire initial tickets using the keytab. If the target name cannot be used to select a client principal (because the credentials are used in a call to gss_inquire_cred_), or if the credential cache selection facility cannot choose a principal for it, the default credential cache will be selected if it exists and contains tickets. If the default credential cache does not exist, but the default client keytab does, the krb5 mechanism will try to acquire initial tickets for the first principal in the default client keytab. If the krb5 mechanism acquires initial tickets using the default client keytab, the resulting tickets will be stored in the default cache or collection, and will be refreshed by future calls to gss_acquire_cred_ as they approach their expire time. Acceptor names -------------- A GSSAPI server application uses gss_accept_sec_context_ to establish a security context based on tokens provided by the client. The *acceptor_cred_handle* parameter determines what :ref:`keytab_definition` entries may be authenticated to by the client, if the krb5 mechanism is used. The simplest choice is to pass **GSS_C_NO_CREDENTIAL** as the acceptor credential. In this case, clients may authenticate to any service principal in the default keytab (typically |keytab|, or the value of the **KRB5_KTNAME** environment variable). This is the recommended approach if the server application has no specific requirements to the contrary. A server may acquire an acceptor credential with gss_acquire_cred_ and a *cred_usage* of **GSS_C_ACCEPT** or **GSS_C_BOTH**. If the *desired_name* parameter is **GSS_C_NO_NAME**, then clients will be allowed to authenticate to any service principal in the default keytab, just as if no acceptor credential was supplied. If a server wishes to specify a *desired_name* to gss_acquire_cred_, the most common choice is a host-based name. If the host-based *desired_name* contains just a *service*, then clients will be allowed to authenticate to any host-based service principal (that is, a principal of the form ``service/hostname@REALM``) for the named service, regardless of hostname or realm, as long as it is present in the default keytab. If the input name contains both a *service* and a *hostname*, clients will be allowed to authenticate to any host-based principal for the named service and hostname, regardless of realm. .. note:: If a *hostname* is specified, it will be canonicalized using forward name resolution, and possibly also using reverse name resolution depending on the value of the **rdns** variable in :ref:`libdefaults`. .. note:: If the **ignore_acceptor_hostname** variable in :ref:`libdefaults` is enabled, then *hostname* will be ignored even if one is specified in the input name. .. note:: In MIT krb5 versions prior to 1.10, and in Heimdal's implementation of the krb5 mechanism, an input name with just a *service* is treated like an input name of ``service@localhostname``, where *localhostname* is the string returned by gethostname(). If the *desired_name* is a krb5 principal name or a local system name type which is mapped to a krb5 principal name, clients will only be allowed to authenticate to that principal in the default keytab. Name Attributes --------------- In release 1.8 or later, the gss_inquire_name_ and gss_get_name_attribute_ functions, specified in :rfc:`6680`, can be used to retrieve name attributes from the *src_name* returned by gss_accept_sec_context_. The following attributes are defined when the krb5 mechanism is used: .. _gssapi_authind_attr: * "auth-indicators" attribute: This attribute will be included in the gss_inquire_name_ output if the ticket contains :ref:`authentication indicators `. One indicator is returned per invocation of gss_get_name_attribute_, so multiple invocations may be necessary to retrieve all of the indicators from the ticket. (New in release 1.15.) Credential store extensions --------------------------- Beginning with release 1.11, the following GSSAPI extensions declared in ```` can be used to specify how credentials are acquired or stored:: struct gss_key_value_element_struct { const char *key; const char *value; }; typedef struct gss_key_value_element_struct gss_key_value_element_desc; struct gss_key_value_set_struct { OM_uint32 count; gss_key_value_element_desc *elements; }; typedef const struct gss_key_value_set_struct gss_key_value_set_desc; typedef const gss_key_value_set_desc *gss_const_key_value_set_t; OM_uint32 gss_acquire_cred_from(OM_uint32 *minor_status, const gss_name_t desired_name, OM_uint32 time_req, const gss_OID_set desired_mechs, gss_cred_usage_t cred_usage, gss_const_key_value_set_t cred_store, gss_cred_id_t *output_cred_handle, gss_OID_set *actual_mechs, OM_uint32 *time_rec); OM_uint32 gss_store_cred_into(OM_uint32 *minor_status, gss_cred_id_t input_cred_handle, gss_cred_usage_t cred_usage, const gss_OID desired_mech, OM_uint32 overwrite_cred, OM_uint32 default_cred, gss_const_key_value_set_t cred_store, gss_OID_set *elements_stored, gss_cred_usage_t *cred_usage_stored); The additional *cred_store* parameter allows the caller to specify information about how the credentials should be obtained and stored. The following options are supported by the krb5 mechanism: * **ccache**: For acquiring initiator credentials, the name of the :ref:`credential cache ` to which the handle will refer. For storing credentials, the name of the cache or collection where the credentials will be stored (see below). * **client_keytab**: For acquiring initiator credentials, the name of the :ref:`keytab ` which will be used, if necessary, to refresh the credentials in the cache. * **keytab**: For acquiring acceptor credentials, the name of the :ref:`keytab ` to which the handle will refer. In release 1.19 and later, this option also determines the keytab to be used for verification when initiator credentials are acquired using a password and verified. * **password**: For acquiring initiator credentials, this option instructs the mechanism to acquire fresh credentials into a unique memory credential cache. This option may not be used with the **ccache** or **client_keytab** options, and a *desired_name* must be specified. (New in release 1.19.) * **rcache**: For acquiring acceptor credentials, the name of the :ref:`replay cache ` to be used when processing the initiator tokens. (New in release 1.13.) * **verify**: For acquiring initiator credentials, this option instructs the mechanism to verify the credentials by obtaining a ticket to a service with a known key. The service key is obtained from the keytab specified with the **keytab** option or the default keytab. The value may be the name of a principal in the keytab, or the empty string. If the empty string is given, any ``host`` service principal in the keytab may be used. (New in release 1.19.) In release 1.20 or later, if a collection name is specified for **cache** in a call to gss_store_cred_into(), an existing cache for the client principal within the collection will be selected, or a new cache will be created within the collection. If *overwrite_cred* is false and the selected credential cache already exists, a **GSS_S_DUPLICATE_ELEMENT** error will be returned. If *default_cred* is true, the primary cache of the collection will be switched to the selected cache. Importing and exporting credentials ----------------------------------- The following GSSAPI extensions can be used to import and export credentials (declared in ````):: OM_uint32 gss_export_cred(OM_uint32 *minor_status, gss_cred_id_t cred_handle, gss_buffer_t token); OM_uint32 gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token, gss_cred_id_t *cred_handle); The first function serializes a GSSAPI credential handle into a buffer; the second unseralizes a buffer into a GSSAPI credential handle. Serializing a credential does not destroy it. If any of the mechanisms used in *cred_handle* do not support serialization, gss_export_cred will return **GSS_S_UNAVAILABLE**. As with other GSSAPI serialization functions, these extensions are only intended to work with a matching implementation on the other side; they do not serialize credentials in a standardized format. A serialized credential may contain secret information such as ticket session keys. The serialization format does not protect this information from eavesdropping or tampering. The calling application must take care to protect the serialized credential when communicating it over an insecure channel or to an untrusted party. A krb5 GSSAPI credential may contain references to a credential cache, a client keytab, an acceptor keytab, and a replay cache. These resources are normally serialized as references to their external locations (such as the filename of the credential cache). Because of this, a serialized krb5 credential can only be imported by a process with similar privileges to the exporter. A serialized credential should not be trusted if it originates from a source with lower privileges than the importer, as it may contain references to external credential cache, keytab, or replay cache resources not accessible to the originator. An exception to the above rule applies when a krb5 GSSAPI credential refers to a memory credential cache, as is normally the case for delegated credentials received by gss_accept_sec_context_. In this case, the contents of the credential cache are serialized, so that the resulting token may be imported even if the original memory credential cache no longer exists. Constrained delegation (S4U) ---------------------------- The Microsoft S4U2Self and S4U2Proxy Kerberos protocol extensions allow an intermediate service to acquire credentials from a client to a target service without requiring the client to delegate a ticket-granting ticket, if the KDC is configured to allow it. To perform a constrained delegation operation, the intermediate service must submit to the KDC an "evidence ticket" from the client to the intermediate service. An evidence ticket can be acquired when the client authenticates to the intermediate service with Kerberos, or with an S4U2Self request if the KDC allows it. The MIT krb5 GSSAPI library represents an evidence ticket using a "proxy credential", which is a special kind of gss_cred_id_t object whose underlying credential cache contains the evidence ticket and a krbtgt ticket for the intermediate service. To acquire a proxy credential during client authentication, the service should first create an acceptor credential using the **GSS_C_BOTH** usage. The application should then pass this credential as the *acceptor_cred_handle* to gss_accept_sec_context_, and also pass a *delegated_cred_handle* output parameter to receive a proxy credential containing the evidence ticket. The output value of *delegated_cred_handle* may be a delegated ticket-granting ticket if the client sent one, or a proxy credential if not. If the library can determine that the client's ticket is not a valid evidence ticket, it will place **GSS_C_NO_CREDENTIAL** in *delegated_cred_handle*. To acquire a proxy credential using an S4U2Self request, the service can use the following GSSAPI extension:: OM_uint32 gss_acquire_cred_impersonate_name(OM_uint32 *minor_status, gss_cred_id_t icred, gss_name_t desired_name, OM_uint32 time_req, gss_OID_set desired_mechs, gss_cred_usage_t cred_usage, gss_cred_id_t *output_cred, gss_OID_set *actual_mechs, OM_uint32 *time_rec); The parameters to this function are similar to those of gss_acquire_cred_, except that *icred* is used to make an S4U2Self request to the KDC for a ticket from *desired_name* to the intermediate service. Both *icred* and *desired_name* are required for this function; passing **GSS_C_NO_CREDENTIAL** or **GSS_C_NO_NAME** will cause the call to fail. *icred* must contain a krbtgt ticket for the intermediate service. The result of this operation is a proxy credential. (Prior to release 1.18, the result of this operation may be a regular credential for *desired_name*, if the KDC issues a non-forwardable ticket.) Once the intermediate service has a proxy credential, it can simply pass it to gss_init_sec_context_ as the *initiator_cred_handle* parameter, and the desired service as the *target_name* parameter. The GSSAPI library will present the krbtgt ticket and evidence ticket in the proxy credential to the KDC in an S4U2Proxy request; if the intermediate service has the appropriate permissions, the KDC will issue a ticket from the client to the target service. The GSSAPI library will then use this ticket to authenticate to the target service. If an application needs to find out whether a credential it holds is a proxy credential and the name of the intermediate service, it can query the credential with the **GSS_KRB5_GET_CRED_IMPERSONATOR** OID (new in release 1.16, declared in ````) using the gss_inquire_cred_by_oid extension (declared in ````):: OM_uint32 gss_inquire_cred_by_oid(OM_uint32 *minor_status, const gss_cred_id_t cred_handle, gss_OID desired_object, gss_buffer_set_t *data_set); If the call succeeds and *cred_handle* is a proxy credential, *data_set* will be set to a single-element buffer set containing the unparsed principal name of the intermediate service. If *cred_handle* is not a proxy credential, *data_set* will be set to an empty buffer set. If the library does not support the query, gss_inquire_cred_by_oid will return **GSS_S_UNAVAILABLE**. Channel binding behavior and GSS_C_CHANNEL_BOUND_FLAG ----------------------------------------------------- GSSAPI channel bindings can be used to limit the scope of a context establishment token to a particular protected channel or endpoint, such as a TLS channel or server certificate. Channel bindings can be supplied via the *input_chan_bindings* parameter to either gss_init_sec_context() or gss_accept_sec_context(). If both the initiator and acceptor of a GSSAPI exchange supply matching channel bindings, **GSS_C_CHANNEL_BOUND_FLAG** will be included in the gss_accept_sec_context() *ret_flags* result. If either the initiator or acceptor (or both) do not supply channel bindings, the exchange will succeed, but **GSS_C_CHANNEL_BOUND_FLAG** will not be included in the return flags. If the acceptor and initiator both inlude channel bindings but they do not match, the exchange will fail. If **GSS_C_CHANNEL_BOUND_FLAG** is included in the *req_flags* parameter of gss_init_sec_context(), the initiator will add the Microsoft KERB_AP_OPTIONS_CBT extension to the Kerberos authenticator. This extension requests that the acceptor strictly enforce channel bindings, causing the exchange to fail if the acceptor supplies channel bindings and the initiator does not. The KERB_AP_OPTIONS_CBT extension will also be included if the **client_aware_channel_bindings** variable is set to ``true`` in :ref:`libdefaults`. Prior to release 1.19, **GSS_C_CHANNEL_BOUND_FLAG** is not implemented, and the exchange will fail if the acceptor supply channel bindings and the initiator does not (but not vice versa). Between releases 1.19 and 1.21, **GSS_C_CHANNEL_BOUND_FLAG** is not recognized as an initiator flag, so **client_aware_channel_bindings** is the only way to cause KERB_AP_OPTIONS_CBT to be included. AEAD message wrapping --------------------- The following GSSAPI extensions (declared in ````) can be used to wrap and unwrap messages with additional "associated data" which is integrity-checked but is not included in the output buffer:: OM_uint32 gss_wrap_aead(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, gss_buffer_t input_assoc_buffer, gss_buffer_t input_payload_buffer, int *conf_state, gss_buffer_t output_message_buffer); OM_uint32 gss_unwrap_aead(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_buffer_t input_message_buffer, gss_buffer_t input_assoc_buffer, gss_buffer_t output_payload_buffer, int *conf_state, gss_qop_t *qop_state); Wrap tokens created with gss_wrap_aead will successfully unwrap only if the same *input_assoc_buffer* contents are presented to gss_unwrap_aead. IOV message wrapping -------------------- The following extensions (declared in ````) can be used for in-place encryption, fine-grained control over wrap token layout, and for constructing wrap tokens compatible with Microsoft DCE RPC:: typedef struct gss_iov_buffer_desc_struct { OM_uint32 type; gss_buffer_desc buffer; } gss_iov_buffer_desc, *gss_iov_buffer_t; OM_uint32 gss_wrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, int *conf_state, gss_iov_buffer_desc *iov, int iov_count); OM_uint32 gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int *conf_state, gss_qop_t *qop_state, gss_iov_buffer_desc *iov, int iov_count); OM_uint32 gss_wrap_iov_length(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, int *conf_state, gss_iov_buffer_desc *iov, int iov_count); OM_uint32 gss_release_iov_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count); The caller of gss_wrap_iov provides an array of gss_iov_buffer_desc structures, each containing a type and a gss_buffer_desc structure. Valid types include: * **GSS_C_BUFFER_TYPE_DATA**: A data buffer to be included in the token, and to be encrypted or decrypted in-place if the token is confidentiality-protected. * **GSS_C_BUFFER_TYPE_HEADER**: The GSSAPI wrap token header and underlying cryptographic header. * **GSS_C_BUFFER_TYPE_TRAILER**: The cryptographic trailer, if one is required. * **GSS_C_BUFFER_TYPE_PADDING**: Padding to be combined with the data during encryption and decryption. (The implementation may choose to place padding in the trailer buffer, in which case it will set the padding buffer length to 0.) * **GSS_C_BUFFER_TYPE_STREAM**: For unwrapping only, a buffer containing a complete wrap token in standard format to be unwrapped. * **GSS_C_BUFFER_TYPE_SIGN_ONLY**: A buffer to be included in the token's integrity protection checksum, but not to be encrypted or included in the token itself. For gss_wrap_iov, the IOV list should contain one HEADER buffer, followed by zero or more SIGN_ONLY buffers, followed by one or more DATA buffers, followed by a TRAILER buffer. The memory pointed to by the buffers is not required to be contiguous or in any particular order. If *conf_req_flag* is true, DATA buffers will be encrypted in-place, while SIGN_ONLY buffers will not be modified. The type of an output buffer may be combined with **GSS_C_BUFFER_FLAG_ALLOCATE** to request that gss_wrap_iov allocate the buffer contents. If gss_wrap_iov allocates a buffer, it sets the **GSS_C_BUFFER_FLAG_ALLOCATED** flag on the buffer type. gss_release_iov_buffer can be used to release all allocated buffers within an iov list and unset their allocated flags. Here is an example of how gss_wrap_iov can be used with allocation requested (*ctx* is assumed to be a previously established gss_ctx_id_t):: OM_uint32 major, minor; gss_iov_buffer_desc iov[4]; char str[] = "message"; iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = str; iov[1].buffer.length = strlen(str); iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL, iov, 4); if (GSS_ERROR(major)) handle_error(major, minor); /* Transmit or otherwise use resulting buffers. */ (void)gss_release_iov_buffer(&minor, iov, 4); If the caller does not choose to request buffer allocation by gss_wrap_iov, it should first call gss_wrap_iov_length to query the lengths of the HEADER, PADDING, and TRAILER buffers. DATA buffers must be provided in the iov list so that padding length can be computed correctly, but the output buffers need not be initialized. Here is an example of using gss_wrap_iov_length and gss_wrap_iov:: OM_uint32 major, minor; gss_iov_buffer_desc iov[4]; char str[1024] = "message", *ptr; iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = str; iov[1].buffer.length = strlen(str); iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING; iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER; major = gss_wrap_iov_length(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL, iov, 4); if (GSS_ERROR(major)) handle_error(major, minor); if (strlen(str) + iov[0].buffer.length + iov[2].buffer.length + iov[3].buffer.length > sizeof(str)) handle_out_of_space_error(); ptr = str + strlen(str); iov[0].buffer.value = ptr; ptr += iov[0].buffer.length; iov[2].buffer.value = ptr; ptr += iov[2].buffer.length; iov[3].buffer.value = ptr; major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL, iov, 4); if (GSS_ERROR(major)) handle_error(major, minor); If the context was established using the **GSS_C_DCE_STYLE** flag (described in :rfc:`4757`), wrap tokens compatible with Microsoft DCE RPC can be constructed. In this case, the IOV list must include a SIGN_ONLY buffer, a DATA buffer, a second SIGN_ONLY buffer, and a HEADER buffer in that order (the order of the buffer contents remains arbitrary). The application must pad the DATA buffer to a multiple of 16 bytes as no padding or trailer buffer is used. gss_unwrap_iov may be called with an IOV list just like one which would be provided to gss_wrap_iov. DATA buffers will be decrypted in-place if they were encrypted, and SIGN_ONLY buffers will not be modified. Alternatively, gss_unwrap_iov may be called with a single STREAM buffer, zero or more SIGN_ONLY buffers, and a single DATA buffer. The STREAM buffer is interpreted as a complete wrap token. The STREAM buffer will be modified in-place to decrypt its contents. The DATA buffer will be initialized to point to the decrypted data within the STREAM buffer, unless it has the **GSS_C_BUFFER_FLAG_ALLOCATE** flag set, in which case it will be initialized with a copy of the decrypted data. Here is an example (*token* and *token_len* are assumed to be a pre-existing pointer and length for a modifiable region of data):: OM_uint32 major, minor; gss_iov_buffer_desc iov[2]; iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; iov[0].buffer.value = token; iov[0].buffer.length = token_len; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2); if (GSS_ERROR(major)) handle_error(major, minor); /* Decrypted data is in iov[1].buffer, pointing to a subregion of * token. */ .. _gssapi_mic_token: IOV MIC tokens -------------- The following extensions (declared in ````) can be used in release 1.12 or later to construct and verify MIC tokens using an IOV list:: OM_uint32 gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_qop_t qop_req, gss_iov_buffer_desc *iov, int iov_count); OM_uint32 gss_get_mic_iov_length(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_qop_t qop_req, gss_iov_buffer_desc *iov, iov_count); OM_uint32 gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_qop_t *qop_state, gss_iov_buffer_desc *iov, int iov_count); The caller of gss_get_mic_iov provides an array of gss_iov_buffer_desc structures, each containing a type and a gss_buffer_desc structure. Valid types include: * **GSS_C_BUFFER_TYPE_DATA** and **GSS_C_BUFFER_TYPE_SIGN_ONLY**: The corresponding buffer for each of these types will be signed for the MIC token, in the order provided. * **GSS_C_BUFFER_TYPE_MIC_TOKEN**: The GSSAPI MIC token. The type of the MIC_TOKEN buffer may be combined with **GSS_C_BUFFER_FLAG_ALLOCATE** to request that gss_get_mic_iov allocate the buffer contents. If gss_get_mic_iov allocates the buffer, it sets the **GSS_C_BUFFER_FLAG_ALLOCATED** flag on the buffer type. gss_release_iov_buffer can be used to release all allocated buffers within an iov list and unset their allocated flags. Here is an example of how gss_get_mic_iov can be used with allocation requested (*ctx* is assumed to be a previously established gss_ctx_id_t):: OM_uint32 major, minor; gss_iov_buffer_desc iov[3]; iov[0].type = GSS_IOV_BUFFER_TYPE_DATA; iov[0].buffer.value = "sign1"; iov[0].buffer.length = 5; iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[1].buffer.value = "sign2"; iov[1].buffer.length = 5; iov[2].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 3); if (GSS_ERROR(major)) handle_error(major, minor); /* Transmit or otherwise use iov[2].buffer. */ (void)gss_release_iov_buffer(&minor, iov, 3); If the caller does not choose to request buffer allocation by gss_get_mic_iov, it should first call gss_get_mic_iov_length to query the length of the MIC_TOKEN buffer. Here is an example of using gss_get_mic_iov_length and gss_get_mic_iov:: OM_uint32 major, minor; gss_iov_buffer_desc iov[2]; char data[1024]; iov[0].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = "message"; iov[1].buffer.length = 7; major = gss_get_mic_iov_length(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 2); if (GSS_ERROR(major)) handle_error(major, minor); if (iov[0].buffer.length > sizeof(data)) handle_out_of_space_error(); iov[0].buffer.value = data; major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 2); if (GSS_ERROR(major)) handle_error(major, minor); .. _gss_accept_sec_context: https://tools.ietf.org/html/rfc2744.html#section-5.1 .. _gss_acquire_cred: https://tools.ietf.org/html/rfc2744.html#section-5.2 .. _gss_export_name: https://tools.ietf.org/html/rfc2744.html#section-5.13 .. _gss_get_name_attribute: https://tools.ietf.org/html/6680.html#section-7.5 .. _gss_import_name: https://tools.ietf.org/html/rfc2744.html#section-5.16 .. _gss_init_sec_context: https://tools.ietf.org/html/rfc2744.html#section-5.19 .. _gss_inquire_name: https://tools.ietf.org/html/rfc6680.txt#section-7.4 .. _gss_inquire_cred: https://tools.ietf.org/html/rfc2744.html#section-5.21 krb5-1.22.1/doc/appdev/y2038.rst0000664000175000017500000000246515051422640015713 0ustar ghudsonghudsonYear 2038 considerations for uses of krb5_timestamp =================================================== POSIX time values, which measure the number of seconds since January 1 1970, will exceed the maximum value representable in a signed 32-bit integer in January 2038. This documentation describes considerations for consumers of the MIT krb5 libraries. Applications or libraries which use libkrb5 and consume the timestamps included in credentials or other structures make use of the :c:type:`krb5_timestamp` type. For historical reasons, krb5_timestamp is a signed 32-bit integer, even on platforms where a larger type is natively used to represent time values. To behave properly for time values after January 2038, calling code should cast krb5_timestamp values to uint32_t, and then to time_t:: (time_t)(uint32_t)timestamp Used in this way, krb5_timestamp values can represent time values up until February 2106, provided that the platform uses a 64-bit or larger time_t type. This usage will also remain safe if a later version of MIT krb5 changes krb5_timestamp to an unsigned 32-bit integer. The GSSAPI only uses representations of time intervals, not absolute times. Callers of the GSSAPI should require no changes to behave correctly after January 2038, provided that they use MIT krb5 release 1.16 or later. krb5-1.22.1/doc/appdev/init_creds.rst0000664000175000017500000003116615051422640017251 0ustar ghudsonghudsonInitial credentials =================== Software that performs tasks such as logging users into a computer when they type their Kerberos password needs to get initial credentials (usually ticket granting tickets) from Kerberos. Such software shares some behavior with the :ref:`kinit(1)` program. Whenever a program grants access to a resource (such as a local login session on a desktop computer) based on a user successfully getting initial Kerberos credentials, it must verify those credentials against a secure shared secret (e.g., a host keytab) to ensure that the user credentials actually originate from a legitimate KDC. Failure to perform this verification is a critical vulnerability, because a malicious user can execute the "Zanarotti attack": the user constructs a fake response that appears to come from the legitimate KDC, but whose contents come from an attacker-controlled KDC. Some applications read a Kerberos password over the network (ideally over a secure channel), which they then verify against the KDC. While this technique may be the only practical way to integrate Kerberos into some existing legacy systems, its use is contrary to the original design goals of Kerberos. The function :c:func:`krb5_get_init_creds_password` will get initial credentials for a client using a password. An application that needs to verify the credentials can call :c:func:`krb5_verify_init_creds`. Here is an example of code to obtain and verify TGT credentials, given strings *princname* and *password* for the client principal name and password:: krb5_error_code ret; krb5_creds creds; krb5_principal client_princ = NULL; memset(&creds, 0, sizeof(creds)); ret = krb5_parse_name(context, princname, &client_princ); if (ret) goto cleanup; ret = krb5_get_init_creds_password(context, &creds, client_princ, password, NULL, NULL, 0, NULL, NULL); if (ret) goto cleanup; ret = krb5_verify_init_creds(context, &creds, NULL, NULL, NULL, NULL); cleanup: krb5_free_principal(context, client_princ); krb5_free_cred_contents(context, &creds); return ret; Options for get_init_creds -------------------------- The function :c:func:`krb5_get_init_creds_password` takes an options parameter (which can be a null pointer). Use the function :c:func:`krb5_get_init_creds_opt_alloc` to allocate an options structure, and :c:func:`krb5_get_init_creds_opt_free` to free it. For example:: krb5_error_code ret; krb5_get_init_creds_opt *opt = NULL; krb5_creds creds; memset(&creds, 0, sizeof(creds)); ret = krb5_get_init_creds_opt_alloc(context, &opt); if (ret) goto cleanup; krb5_get_init_creds_opt_set_tkt_life(opt, 24 * 60 * 60); ret = krb5_get_init_creds_password(context, &creds, client_princ, password, NULL, NULL, 0, NULL, opt); if (ret) goto cleanup; cleanup: krb5_get_init_creds_opt_free(context, opt); krb5_free_cred_contents(context, &creds); return ret; Getting anonymous credentials ----------------------------- As of release 1.8, it is possible to obtain fully anonymous or partially anonymous (realm-exposed) credentials, if the KDC supports it. The MIT KDC supports issuing fully anonymous credentials as of release 1.8 if configured appropriately (see :ref:`anonymous_pkinit`), but does not support issuing realm-exposed anonymous credentials at this time. To obtain fully anonymous credentials, call :c:func:`krb5_get_init_creds_opt_set_anonymous` on the options structure to set the anonymous flag, and specify a client principal with the KDC's realm and a single empty data component (the principal obtained by parsing ``@``\ *realmname*). Authentication will take place using anonymous PKINIT; if successful, the client principal of the resulting tickets will be ``WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS``. Here is an example:: krb5_get_init_creds_opt_set_anonymous(opt, 1); ret = krb5_build_principal(context, &client_princ, strlen(myrealm), myrealm, "", (char *)NULL); if (ret) goto cleanup; ret = krb5_get_init_creds_password(context, &creds, client_princ, password, NULL, NULL, 0, NULL, opt); if (ret) goto cleanup; To obtain realm-exposed anonymous credentials, set the anonymous flag on the options structure as above, but specify a normal client principal in order to prove membership in the realm. Authentication will take place as it normally does; if successful, the client principal of the resulting tickets will be ``WELLKNOWN/ANONYMOUS@``\ *realmname*. User interaction ---------------- Authenticating a user usually requires the entry of secret information, such as a password. A password can be supplied directly to :c:func:`krb5_get_init_creds_password` via the *password* parameter, or the application can supply prompter and/or responder callbacks instead. If callbacks are used, the user can also be queried for other secret information such as a PIN, informed of impending password expiration, or prompted to change a password which has expired. Prompter callback ~~~~~~~~~~~~~~~~~ A prompter callback can be specified via the *prompter* and *data* parameters to :c:func:`krb5_get_init_creds_password`. The prompter will be invoked each time the krb5 library has a question to ask or information to present. When the prompter callback is invoked, the *banner* argument (if not null) is intended to be displayed to the user, and the questions to be answered are specified in the *prompts* array. Each prompt contains a text question in the *prompt* field, a *hidden* bit to indicate whether the answer should be hidden from display, and a storage area for the answer in the *reply* field. The callback should fill in each question's ``reply->data`` with the answer, up to a maximum number of ``reply->length`` bytes, and then reset ``reply->length`` to the length of the answer. A prompter callback can call :c:func:`krb5_get_prompt_types` to get an array of type constants corresponding to the prompts, to get programmatic information about the semantic meaning of the questions. :c:func:`krb5_get_prompt_types` may return a null pointer if no prompt type information is available. Text-based applications can use a built-in text prompter implementation by supplying :c:func:`krb5_prompter_posix` as the *prompter* parameter and a null pointer as the *data* parameter. For example:: ret = krb5_get_init_creds_password(context, &creds, client_princ, NULL, krb5_prompter_posix, NULL, 0, NULL, NULL); Responder callback ~~~~~~~~~~~~~~~~~~ A responder callback can be specified through the init_creds options using the :c:func:`krb5_get_init_creds_opt_set_responder` function. Responder callbacks can present a more sophisticated user interface for authentication secrets. The responder callback is usually invoked only once per authentication, with a list of questions produced by all of the allowed preauthentication mechanisms. When the responder callback is invoked, the *rctx* argument can be accessed to obtain the list of questions and to answer them. The :c:func:`krb5_responder_list_questions` function retrieves an array of question types. For each question type, the :c:func:`krb5_responder_get_challenge` function retrieves additional information about the question, if applicable, and the :c:func:`krb5_responder_set_answer` function sets the answer. Responder question types, challenges, and answers are UTF-8 strings. The question type is a well-known string; the meaning of the challenge and answer depend on the question type. If an application does not understand a question type, it cannot interpret the challenge or provide an answer. Failing to answer a question typically results in the prompter callback being used as a fallback. Password question ################# The :c:macro:`KRB5_RESPONDER_QUESTION_PASSWORD` (or ``"password"``) question type requests the user's password. This question does not have a challenge, and the response is simply the password string. One-time password question ########################## The :c:macro:`KRB5_RESPONDER_QUESTION_OTP` (or ``"otp"``) question type requests a choice among one-time password tokens and the PIN and value for the chosen token. The challenge and answer are JSON-encoded strings, but an application can use convenience functions to avoid doing any JSON processing itself. The :c:func:`krb5_responder_otp_get_challenge` function decodes the challenge into a krb5_responder_otp_challenge structure. The :c:func:`krb5_responder_otp_set_answer` function selects one of the token information elements from the challenge and supplies the value and pin for that token. PKINIT password or PIN question ############################### The :c:macro:`KRB5_RESPONDER_QUESTION_PKINIT` (or ``"pkinit"``) question type requests PINs for hardware devices and/or passwords for encrypted credentials which are stored on disk, potentially also supplying information about the state of the hardware devices. The challenge and answer are JSON-encoded strings, but an application can use convenience functions to avoid doing any JSON processing itself. The :c:func:`krb5_responder_pkinit_get_challenge` function decodes the challenges into a krb5_responder_pkinit_challenge structure. The :c:func:`krb5_responder_pkinit_set_answer` function can be used to supply the PIN or password for a particular client credential, and can be called multiple times. Example ####### Here is an example of using a responder callback:: static krb5_error_code my_responder(krb5_context context, void *data, krb5_responder_context rctx) { krb5_error_code ret; krb5_responder_otp_challenge *chl; if (krb5_responder_get_challenge(context, rctx, KRB5_RESPONDER_QUESTION_PASSWORD)) { ret = krb5_responder_set_answer(context, rctx, KRB5_RESPONDER_QUESTION_PASSWORD, "open sesame"); if (ret) return ret; } ret = krb5_responder_otp_get_challenge(context, rctx, &chl); if (ret == 0 && chl != NULL) { ret = krb5_responder_otp_set_answer(context, rctx, 0, "1234", NULL); krb5_responder_otp_challenge_free(context, rctx, chl); if (ret) return ret; } return 0; } static krb5_error_code get_creds(krb5_context context, krb5_principal client_princ) { krb5_error_code ret; krb5_get_init_creds_opt *opt = NULL; krb5_creds creds; memset(&creds, 0, sizeof(creds)); ret = krb5_get_init_creds_opt_alloc(context, &opt); if (ret) goto cleanup; ret = krb5_get_init_creds_opt_set_responder(context, opt, my_responder, NULL); if (ret) goto cleanup; ret = krb5_get_init_creds_password(context, &creds, client_princ, NULL, NULL, NULL, 0, NULL, opt); cleanup: krb5_get_init_creds_opt_free(context, opt); krb5_free_cred_contents(context, &creds); return ret; } Verifying initial credentials ----------------------------- Use the function :c:func:`krb5_verify_init_creds` to verify initial credentials. It takes an options structure (which can be a null pointer). Use :c:func:`krb5_verify_init_creds_opt_init` to initialize the caller-allocated options structure, and :c:func:`krb5_verify_init_creds_opt_set_ap_req_nofail` to set the "nofail" option. For example:: krb5_verify_init_creds_opt vopt; krb5_verify_init_creds_opt_init(&vopt); krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, 1); ret = krb5_verify_init_creds(context, &creds, NULL, NULL, NULL, &vopt); The confusingly named "nofail" option, when set, means that the verification must actually succeed in order for :c:func:`krb5_verify_init_creds` to indicate success. The default state of this option (cleared) means that if there is no key material available to verify the user credentials, the verification will succeed anyway. (The default can be changed by a configuration file setting.) This accommodates a use case where a large number of unkeyed shared desktop workstations need to allow users to log in using Kerberos. The security risks from this practice are mitigated by the absence of valuable state on the shared workstations---any valuable resources that the users would access reside on networked servers. krb5-1.22.1/doc/appdev/princ_handle.rst0000664000175000017500000000175615051422640017556 0ustar ghudsonghudsonPrincipal manipulation and parsing ================================== Kerberos principal structure .. :c:type:`krb5_principal_data` :c:type:`krb5_principal` .. Create and free principal .. :c:func:`krb5_build_principal()` :c:func:`krb5_build_principal_alloc_va()` :c:func:`krb5_build_principal_ext()` :c:func:`krb5_copy_principal()` :c:func:`krb5_free_principal()` :c:func:`krb5_cc_get_principal()` .. Comparing .. :c:func:`krb5_principal_compare()` :c:func:`krb5_principal_compare_flags()` :c:func:`krb5_principal_compare_any_realm()` :c:func:`krb5_sname_match()` :c:func:`krb5_sname_to_principal()` .. Parsing: .. :c:func:`krb5_parse_name()` :c:func:`krb5_parse_name_flags()` :c:func:`krb5_unparse_name()` :c:func:`krb5_unparse_name_flags()` .. Utilities: .. :c:func:`krb5_is_config_principal()` :c:func:`krb5_kuserok()` :c:func:`krb5_set_password()` :c:func:`krb5_set_password_using_ccache()` :c:func:`krb5_set_principal_realm()` :c:func:`krb5_realm_compare()` .. krb5-1.22.1/doc/appdev/refs/0000775000175000017500000000000015051422640015324 5ustar ghudsonghudsonkrb5-1.22.1/doc/appdev/refs/api/0000775000175000017500000000000015051422640016075 5ustar ghudsonghudsonkrb5-1.22.1/doc/appdev/refs/api/index.rst0000664000175000017500000002673215051422640017750 0ustar ghudsonghudsonkrb5 API ======== Frequently used public interfaces ---------------------------------- .. toctree:: :maxdepth: 1 krb5_build_principal.rst krb5_build_principal_alloc_va.rst krb5_build_principal_ext.rst krb5_cc_close.rst krb5_cc_default.rst krb5_cc_default_name.rst krb5_cc_destroy.rst krb5_cc_dup.rst krb5_cc_get_name.rst krb5_cc_get_principal.rst krb5_cc_get_type.rst krb5_cc_initialize.rst krb5_cc_new_unique.rst krb5_cc_resolve.rst krb5_change_password.rst krb5_chpw_message.rst krb5_expand_hostname.rst krb5_free_config_files.rst krb5_free_context.rst krb5_free_error_message.rst krb5_free_principal.rst krb5_fwd_tgt_creds.rst krb5_get_default_realm.rst krb5_get_error_message.rst krb5_get_host_realm.rst krb5_get_credentials.rst krb5_get_default_config_files.rst krb5_get_fallback_host_realm.rst krb5_get_init_creds_keytab.rst krb5_get_init_creds_opt_alloc.rst krb5_get_init_creds_opt_free.rst krb5_get_init_creds_opt_get_fast_flags.rst krb5_get_init_creds_opt_set_address_list.rst krb5_get_init_creds_opt_set_anonymous.rst krb5_get_init_creds_opt_set_canonicalize.rst krb5_get_init_creds_opt_set_change_password_prompt.rst krb5_get_init_creds_opt_set_etype_list.rst krb5_get_init_creds_opt_set_expire_callback.rst krb5_get_init_creds_opt_set_fast_ccache.rst krb5_get_init_creds_opt_set_fast_ccache_name.rst krb5_get_init_creds_opt_set_fast_flags.rst krb5_get_init_creds_opt_set_forwardable.rst krb5_get_init_creds_opt_set_in_ccache.rst krb5_get_init_creds_opt_set_out_ccache.rst krb5_get_init_creds_opt_set_pa.rst krb5_get_init_creds_opt_set_pac_request.rst krb5_get_init_creds_opt_set_preauth_list.rst krb5_get_init_creds_opt_set_proxiable.rst krb5_get_init_creds_opt_set_renew_life.rst krb5_get_init_creds_opt_set_responder.rst krb5_get_init_creds_opt_set_salt.rst krb5_get_init_creds_opt_set_tkt_life.rst krb5_get_init_creds_password.rst krb5_get_profile.rst krb5_get_prompt_types.rst krb5_get_renewed_creds.rst krb5_get_validated_creds.rst krb5_init_context.rst krb5_init_secure_context.rst krb5_is_config_principal.rst krb5_is_thread_safe.rst krb5_kt_close.rst krb5_kt_client_default.rst krb5_kt_default.rst krb5_kt_default_name.rst krb5_kt_dup.rst krb5_kt_get_name.rst krb5_kt_get_type.rst krb5_kt_resolve.rst krb5_kuserok.rst krb5_parse_name.rst krb5_parse_name_flags.rst krb5_principal_compare.rst krb5_principal_compare_any_realm.rst krb5_principal_compare_flags.rst krb5_prompter_posix.rst krb5_realm_compare.rst krb5_responder_get_challenge.rst krb5_responder_list_questions.rst krb5_responder_set_answer.rst krb5_responder_otp_get_challenge.rst krb5_responder_otp_set_answer.rst krb5_responder_otp_challenge_free.rst krb5_responder_pkinit_get_challenge.rst krb5_responder_pkinit_set_answer.rst krb5_responder_pkinit_challenge_free.rst krb5_set_default_realm.rst krb5_set_password.rst krb5_set_password_using_ccache.rst krb5_set_principal_realm.rst krb5_set_trace_callback.rst krb5_set_trace_filename.rst krb5_sname_match.rst krb5_sname_to_principal.rst krb5_unparse_name.rst krb5_unparse_name_ext.rst krb5_unparse_name_flags.rst krb5_unparse_name_flags_ext.rst krb5_us_timeofday.rst krb5_verify_authdata_kdc_issued.rst Rarely used public interfaces -------------------------------- .. toctree:: :maxdepth: 1 krb5_425_conv_principal.rst krb5_524_conv_principal.rst krb5_address_compare.rst krb5_address_order.rst krb5_address_search.rst krb5_allow_weak_crypto.rst krb5_aname_to_localname.rst krb5_anonymous_principal.rst krb5_anonymous_realm.rst krb5_appdefault_boolean.rst krb5_appdefault_string.rst krb5_auth_con_free.rst krb5_auth_con_genaddrs.rst krb5_auth_con_get_checksum_func.rst krb5_auth_con_getaddrs.rst krb5_auth_con_getauthenticator.rst krb5_auth_con_getflags.rst krb5_auth_con_getkey.rst krb5_auth_con_getkey_k.rst krb5_auth_con_getlocalseqnumber.rst krb5_auth_con_getrcache.rst krb5_auth_con_getrecvsubkey.rst krb5_auth_con_getrecvsubkey_k.rst krb5_auth_con_getremoteseqnumber.rst krb5_auth_con_getsendsubkey.rst krb5_auth_con_getsendsubkey_k.rst krb5_auth_con_init.rst krb5_auth_con_set_checksum_func.rst krb5_auth_con_set_req_cksumtype.rst krb5_auth_con_setaddrs.rst krb5_auth_con_setflags.rst krb5_auth_con_setports.rst krb5_auth_con_setrcache.rst krb5_auth_con_setrecvsubkey.rst krb5_auth_con_setrecvsubkey_k.rst krb5_auth_con_setsendsubkey.rst krb5_auth_con_setsendsubkey_k.rst krb5_auth_con_setuseruserkey.rst krb5_cc_cache_match.rst krb5_cc_copy_creds.rst krb5_cc_end_seq_get.rst krb5_cc_get_config.rst krb5_cc_get_flags.rst krb5_cc_get_full_name.rst krb5_cc_move.rst krb5_cc_next_cred.rst krb5_cc_remove_cred.rst krb5_cc_retrieve_cred.rst krb5_cc_select.rst krb5_cc_set_config.rst krb5_cc_set_default_name.rst krb5_cc_set_flags.rst krb5_cc_start_seq_get.rst krb5_cc_store_cred.rst krb5_cc_support_switch.rst krb5_cc_switch.rst krb5_cccol_cursor_free.rst krb5_cccol_cursor_new.rst krb5_cccol_cursor_next.rst krb5_cccol_have_content.rst krb5_clear_error_message.rst krb5_check_clockskew.rst krb5_copy_addresses.rst krb5_copy_authdata.rst krb5_copy_authenticator.rst krb5_copy_checksum.rst krb5_copy_context.rst krb5_copy_creds.rst krb5_copy_data.rst krb5_copy_error_message.rst krb5_copy_keyblock.rst krb5_copy_keyblock_contents.rst krb5_copy_principal.rst krb5_copy_ticket.rst krb5_find_authdata.rst krb5_free_addresses.rst krb5_free_ap_rep_enc_part.rst krb5_free_authdata.rst krb5_free_authenticator.rst krb5_free_cred_contents.rst krb5_free_creds.rst krb5_free_data.rst krb5_free_data_contents.rst krb5_free_default_realm.rst krb5_free_enctypes.rst krb5_free_error.rst krb5_free_host_realm.rst krb5_free_keyblock.rst krb5_free_keyblock_contents.rst krb5_free_keytab_entry_contents.rst krb5_free_string.rst krb5_free_ticket.rst krb5_free_unparsed_name.rst krb5_get_etype_info.rst krb5_get_permitted_enctypes.rst krb5_get_server_rcache.rst krb5_get_time_offsets.rst krb5_init_context_profile.rst krb5_init_creds_free.rst krb5_init_creds_get.rst krb5_init_creds_get_creds.rst krb5_init_creds_get_error.rst krb5_init_creds_get_times.rst krb5_init_creds_init.rst krb5_init_creds_set_keytab.rst krb5_init_creds_set_password.rst krb5_init_creds_set_service.rst krb5_init_creds_step.rst krb5_init_keyblock.rst krb5_is_referral_realm.rst krb5_kdc_sign_ticket.rst krb5_kdc_verify_ticket.rst krb5_kt_add_entry.rst krb5_kt_end_seq_get.rst krb5_kt_get_entry.rst krb5_kt_have_content.rst krb5_kt_next_entry.rst krb5_kt_read_service_key.rst krb5_kt_remove_entry.rst krb5_kt_start_seq_get.rst krb5_make_authdata_kdc_issued.rst krb5_marshal_credentials.rst krb5_merge_authdata.rst krb5_mk_1cred.rst krb5_mk_error.rst krb5_mk_ncred.rst krb5_mk_priv.rst krb5_mk_rep.rst krb5_mk_rep_dce.rst krb5_mk_req.rst krb5_mk_req_extended.rst krb5_mk_safe.rst krb5_os_localaddr.rst krb5_pac_add_buffer.rst krb5_pac_free.rst krb5_pac_get_buffer.rst krb5_pac_get_types.rst krb5_pac_init.rst krb5_pac_parse.rst krb5_pac_sign.rst krb5_pac_sign_ext.rst krb5_pac_verify.rst krb5_pac_verify_ext.rst krb5_pac_get_client_info.rst krb5_prepend_error_message.rst krb5_principal2salt.rst krb5_rd_cred.rst krb5_rd_error.rst krb5_rd_priv.rst krb5_rd_rep.rst krb5_rd_rep_dce.rst krb5_rd_req.rst krb5_rd_safe.rst krb5_read_password.rst krb5_salttype_to_string.rst krb5_server_decrypt_ticket_keytab.rst krb5_set_default_tgs_enctypes.rst krb5_set_error_message.rst krb5_set_kdc_recv_hook.rst krb5_set_kdc_send_hook.rst krb5_set_real_time.rst krb5_string_to_cksumtype.rst krb5_string_to_deltat.rst krb5_string_to_enctype.rst krb5_string_to_salttype.rst krb5_string_to_timestamp.rst krb5_timeofday.rst krb5_timestamp_to_sfstring.rst krb5_timestamp_to_string.rst krb5_tkt_creds_free.rst krb5_tkt_creds_get.rst krb5_tkt_creds_get_creds.rst krb5_tkt_creds_get_times.rst krb5_tkt_creds_init.rst krb5_tkt_creds_step.rst krb5_unmarshal_credentials.rst krb5_verify_init_creds.rst krb5_verify_init_creds_opt_init.rst krb5_verify_init_creds_opt_set_ap_req_nofail.rst krb5_vprepend_error_message.rst krb5_vset_error_message.rst krb5_vwrap_error_message.rst krb5_wrap_error_message.rst Public interfaces that should not be called directly ------------------------------------------------------- .. toctree:: :maxdepth: 1 krb5_c_block_size.rst krb5_c_checksum_length.rst krb5_c_crypto_length.rst krb5_c_crypto_length_iov.rst krb5_c_decrypt.rst krb5_c_decrypt_iov.rst krb5_c_derive_prfplus.rst krb5_c_encrypt.rst krb5_c_encrypt_iov.rst krb5_c_encrypt_length.rst krb5_c_enctype_compare.rst krb5_c_free_state.rst krb5_c_fx_cf2_simple.rst krb5_c_init_state.rst krb5_c_is_coll_proof_cksum.rst krb5_c_is_keyed_cksum.rst krb5_c_keyed_checksum_types.rst krb5_c_keylengths.rst krb5_c_make_checksum.rst krb5_c_make_checksum_iov.rst krb5_c_make_random_key.rst krb5_c_padding_length.rst krb5_c_prf.rst krb5_c_prfplus.rst krb5_c_prf_length.rst krb5_c_random_add_entropy.rst krb5_c_random_make_octets.rst krb5_c_random_os_entropy.rst krb5_c_random_to_key.rst krb5_c_string_to_key.rst krb5_c_string_to_key_with_params.rst krb5_c_valid_cksumtype.rst krb5_c_valid_enctype.rst krb5_c_verify_checksum.rst krb5_c_verify_checksum_iov.rst krb5_cksumtype_to_string.rst krb5_decode_authdata_container.rst krb5_decode_ticket.rst krb5_deltat_to_string.rst krb5_encode_authdata_container.rst krb5_enctype_to_name.rst krb5_enctype_to_string.rst krb5_free_checksum.rst krb5_free_checksum_contents.rst krb5_free_cksumtypes.rst krb5_free_tgt_creds.rst krb5_k_create_key.rst krb5_k_decrypt.rst krb5_k_decrypt_iov.rst krb5_k_encrypt.rst krb5_k_encrypt_iov.rst krb5_k_free_key.rst krb5_k_key_enctype.rst krb5_k_key_keyblock.rst krb5_k_make_checksum.rst krb5_k_make_checksum_iov.rst krb5_k_prf.rst krb5_k_reference_key.rst krb5_k_verify_checksum.rst krb5_k_verify_checksum_iov.rst Legacy convenience interfaces ------------------------------ .. toctree:: :maxdepth: 1 krb5_recvauth.rst krb5_recvauth_version.rst krb5_sendauth.rst Deprecated public interfaces ------------------------------ .. toctree:: :maxdepth: 1 krb5_524_convert_creds.rst krb5_auth_con_getlocalsubkey.rst krb5_auth_con_getremotesubkey.rst krb5_auth_con_initivector.rst krb5_build_principal_va.rst krb5_c_random_seed.rst krb5_calculate_checksum.rst krb5_checksum_size.rst krb5_encrypt.rst krb5_decrypt.rst krb5_eblock_enctype.rst krb5_encrypt_size.rst krb5_finish_key.rst krb5_finish_random_key.rst krb5_cc_gen_new.rst krb5_get_credentials_renew.rst krb5_get_credentials_validate.rst krb5_get_in_tkt_with_password.rst krb5_get_in_tkt_with_skey.rst krb5_get_in_tkt_with_keytab.rst krb5_get_init_creds_opt_init.rst krb5_init_random_key.rst krb5_kt_free_entry.rst krb5_random_key.rst krb5_process_key.rst krb5_string_to_key.rst krb5_use_enctype.rst krb5_verify_checksum.rst krb5-1.22.1/doc/appdev/refs/macros/0000775000175000017500000000000015051422640016610 5ustar ghudsonghudsonkrb5-1.22.1/doc/appdev/refs/macros/index.rst0000664000175000017500000002774615051422640020471 0ustar ghudsonghudsonkrb5 simple macros ========================= Public ------- .. toctree:: :maxdepth: 1 ADDRTYPE_ADDRPORT.rst ADDRTYPE_CHAOS.rst ADDRTYPE_DIRECTIONAL.rst ADDRTYPE_DDP.rst ADDRTYPE_INET.rst ADDRTYPE_INET6.rst ADDRTYPE_IPPORT.rst ADDRTYPE_ISO.rst ADDRTYPE_IS_LOCAL.rst ADDRTYPE_NETBIOS.rst ADDRTYPE_XNS.rst ADDRTYPE_UNIXSOCK.rst AD_TYPE_EXTERNAL.rst AD_TYPE_FIELD_TYPE_MASK.rst AD_TYPE_REGISTERED.rst AD_TYPE_RESERVED.rst AP_OPTS_ETYPE_NEGOTIATION.rst AP_OPTS_CBT_FLAG.rst AP_OPTS_MUTUAL_REQUIRED.rst AP_OPTS_RESERVED.rst AP_OPTS_USE_SESSION_KEY.rst AP_OPTS_USE_SUBKEY.rst AP_OPTS_WIRE_MASK.rst CKSUMTYPE_CMAC_CAMELLIA128.rst CKSUMTYPE_CMAC_CAMELLIA256.rst CKSUMTYPE_CRC32.rst CKSUMTYPE_DESCBC.rst CKSUMTYPE_HMAC_MD5_ARCFOUR.rst CKSUMTYPE_HMAC_SHA1_96_AES128.rst CKSUMTYPE_HMAC_SHA1_96_AES256.rst CKSUMTYPE_HMAC_SHA256_128_AES128.rst CKSUMTYPE_HMAC_SHA384_192_AES256.rst CKSUMTYPE_HMAC_SHA1_DES3.rst CKSUMTYPE_MD5_HMAC_ARCFOUR.rst CKSUMTYPE_NIST_SHA.rst CKSUMTYPE_RSA_MD4.rst CKSUMTYPE_RSA_MD4_DES.rst CKSUMTYPE_RSA_MD5.rst CKSUMTYPE_RSA_MD5_DES.rst CKSUMTYPE_SHA1.rst ENCTYPE_AES128_CTS_HMAC_SHA1_96.rst ENCTYPE_AES128_CTS_HMAC_SHA256_128.rst ENCTYPE_AES256_CTS_HMAC_SHA1_96.rst ENCTYPE_AES256_CTS_HMAC_SHA384_192.rst ENCTYPE_ARCFOUR_HMAC.rst ENCTYPE_ARCFOUR_HMAC_EXP.rst ENCTYPE_CAMELLIA128_CTS_CMAC.rst ENCTYPE_CAMELLIA256_CTS_CMAC.rst ENCTYPE_DES3_CBC_ENV.rst ENCTYPE_DES3_CBC_RAW.rst ENCTYPE_DES3_CBC_SHA.rst ENCTYPE_DES3_CBC_SHA1.rst ENCTYPE_DES_CBC_CRC.rst ENCTYPE_DES_CBC_MD4.rst ENCTYPE_DES_CBC_MD5.rst ENCTYPE_DES_CBC_RAW.rst ENCTYPE_DES_HMAC_SHA1.rst ENCTYPE_DSA_SHA1_CMS.rst ENCTYPE_MD5_RSA_CMS.rst ENCTYPE_NULL.rst ENCTYPE_RC2_CBC_ENV.rst ENCTYPE_RSA_ENV.rst ENCTYPE_RSA_ES_OAEP_ENV.rst ENCTYPE_SHA1_RSA_CMS.rst ENCTYPE_UNKNOWN.rst KDC_OPT_ALLOW_POSTDATE.rst KDC_OPT_CANONICALIZE.rst KDC_OPT_CNAME_IN_ADDL_TKT.rst KDC_OPT_DISABLE_TRANSITED_CHECK.rst KDC_OPT_ENC_TKT_IN_SKEY.rst KDC_OPT_FORWARDABLE.rst KDC_OPT_FORWARDED.rst KDC_OPT_POSTDATED.rst KDC_OPT_PROXIABLE.rst KDC_OPT_PROXY.rst KDC_OPT_RENEW.rst KDC_OPT_RENEWABLE.rst KDC_OPT_RENEWABLE_OK.rst KDC_OPT_REQUEST_ANONYMOUS.rst KDC_OPT_VALIDATE.rst KDC_TKT_COMMON_MASK.rst KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE.rst KRB5_ANONYMOUS_PRINCSTR.rst KRB5_ANONYMOUS_REALMSTR.rst KRB5_AP_REP.rst KRB5_AP_REQ.rst KRB5_AS_REP.rst KRB5_AS_REQ.rst KRB5_AUTHDATA_AND_OR.rst KRB5_AUTHDATA_AP_OPTIONS.rst KRB5_AUTHDATA_AUTH_INDICATOR.rst KRB5_AUTHDATA_CAMMAC.rst KRB5_AUTHDATA_ETYPE_NEGOTIATION.rst KRB5_AUTHDATA_FX_ARMOR.rst KRB5_AUTHDATA_IF_RELEVANT.rst KRB5_AUTHDATA_INITIAL_VERIFIED_CAS.rst KRB5_AUTHDATA_KDC_ISSUED.rst KRB5_AUTHDATA_MANDATORY_FOR_KDC.rst KRB5_AUTHDATA_OSF_DCE.rst KRB5_AUTHDATA_SESAME.rst KRB5_AUTHDATA_SIGNTICKET.rst KRB5_AUTHDATA_WIN2K_PAC.rst KRB5_AUTH_CONTEXT_DO_SEQUENCE.rst KRB5_AUTH_CONTEXT_DO_TIME.rst KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR.rst KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR.rst KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR.rst KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR.rst KRB5_AUTH_CONTEXT_PERMIT_ALL.rst KRB5_AUTH_CONTEXT_RET_SEQUENCE.rst KRB5_AUTH_CONTEXT_RET_TIME.rst KRB5_AUTH_CONTEXT_USE_SUBKEY.rst KRB5_CRED.rst KRB5_CRYPTO_TYPE_CHECKSUM.rst KRB5_CRYPTO_TYPE_DATA.rst KRB5_CRYPTO_TYPE_EMPTY.rst KRB5_CRYPTO_TYPE_HEADER.rst KRB5_CRYPTO_TYPE_PADDING.rst KRB5_CRYPTO_TYPE_SIGN_ONLY.rst KRB5_CRYPTO_TYPE_STREAM.rst KRB5_CRYPTO_TYPE_TRAILER.rst KRB5_CYBERSAFE_SECUREID.rst KRB5_DOMAIN_X500_COMPRESS.rst KRB5_ENCPADATA_REQ_ENC_PA_REP.rst KRB5_ERROR.rst KRB5_FAST_REQUIRED.rst KRB5_GC_CACHED.rst KRB5_GC_CANONICALIZE.rst KRB5_GC_CONSTRAINED_DELEGATION.rst KRB5_GC_FORWARDABLE.rst KRB5_GC_NO_STORE.rst KRB5_GC_NO_TRANSIT_CHECK.rst KRB5_GC_USER_USER.rst KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST.rst KRB5_GET_INIT_CREDS_OPT_ANONYMOUS.rst KRB5_GET_INIT_CREDS_OPT_CANONICALIZE.rst KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT.rst KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST.rst KRB5_GET_INIT_CREDS_OPT_FORWARDABLE.rst KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST.rst KRB5_GET_INIT_CREDS_OPT_PROXIABLE.rst KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE.rst KRB5_GET_INIT_CREDS_OPT_SALT.rst KRB5_GET_INIT_CREDS_OPT_TKT_LIFE.rst KRB5_INIT_CONTEXT_SECURE.rst KRB5_INIT_CONTEXT_KDC.rst KRB5_INIT_CREDS_STEP_FLAG_CONTINUE.rst KRB5_INT16_MAX.rst KRB5_INT16_MIN.rst KRB5_INT32_MAX.rst KRB5_INT32_MIN.rst KRB5_KEYUSAGE_AD_ITE.rst KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM.rst KRB5_KEYUSAGE_AD_MTE.rst KRB5_KEYUSAGE_AD_SIGNEDPATH.rst KRB5_KEYUSAGE_APP_DATA_CKSUM.rst KRB5_KEYUSAGE_APP_DATA_ENCRYPT.rst KRB5_KEYUSAGE_AP_REP_ENCPART.rst KRB5_KEYUSAGE_AP_REQ_AUTH.rst KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM.rst KRB5_KEYUSAGE_AS_REP_ENCPART.rst KRB5_KEYUSAGE_AS_REQ.rst KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS.rst KRB5_KEYUSAGE_CAMMAC.rst KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT.rst KRB5_KEYUSAGE_ENC_CHALLENGE_KDC.rst KRB5_KEYUSAGE_FAST_ENC.rst KRB5_KEYUSAGE_FAST_FINISHED.rst KRB5_KEYUSAGE_FAST_REP.rst KRB5_KEYUSAGE_FAST_REQ_CHKSUM.rst KRB5_KEYUSAGE_GSS_TOK_MIC.rst KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG.rst KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV.rst KRB5_KEYUSAGE_FINISHED.rst KRB5_KEYUSAGE_IAKERB_FINISHED.rst KRB5_KEYUSAGE_KDC_REP_TICKET.rst KRB5_KEYUSAGE_KRB_CRED_ENCPART.rst KRB5_KEYUSAGE_KRB_ERROR_CKSUM.rst KRB5_KEYUSAGE_KRB_PRIV_ENCPART.rst KRB5_KEYUSAGE_KRB_SAFE_CKSUM.rst KRB5_KEYUSAGE_PA_AS_FRESHNESS.rst KRB5_KEYUSAGE_PA_FX_COOKIE.rst KRB5_KEYUSAGE_PA_OTP_REQUEST.rst KRB5_KEYUSAGE_PA_PKINIT_KX.rst KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY.rst KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST.rst KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM.rst KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID.rst KRB5_KEYUSAGE_PA_SAM_RESPONSE.rst KRB5_KEYUSAGE_SPAKE.rst KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY.rst KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY.rst KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY.rst KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY.rst KRB5_KEYUSAGE_TGS_REQ_AUTH.rst KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM.rst KRB5_KPASSWD_ACCESSDENIED.rst KRB5_KPASSWD_AUTHERROR.rst KRB5_KPASSWD_BAD_VERSION.rst KRB5_KPASSWD_HARDERROR.rst KRB5_KPASSWD_INITIAL_FLAG_NEEDED.rst KRB5_KPASSWD_MALFORMED.rst KRB5_KPASSWD_SOFTERROR.rst KRB5_KPASSWD_SUCCESS.rst KRB5_LRQ_ALL_ACCT_EXPTIME.rst KRB5_LRQ_ALL_LAST_INITIAL.rst KRB5_LRQ_ALL_LAST_RENEWAL.rst KRB5_LRQ_ALL_LAST_REQ.rst KRB5_LRQ_ALL_LAST_TGT.rst KRB5_LRQ_ALL_LAST_TGT_ISSUED.rst KRB5_LRQ_ALL_PW_EXPTIME.rst KRB5_LRQ_NONE.rst KRB5_LRQ_ONE_ACCT_EXPTIME.rst KRB5_LRQ_ONE_LAST_INITIAL.rst KRB5_LRQ_ONE_LAST_RENEWAL.rst KRB5_LRQ_ONE_LAST_REQ.rst KRB5_LRQ_ONE_LAST_TGT.rst KRB5_LRQ_ONE_LAST_TGT_ISSUED.rst KRB5_LRQ_ONE_PW_EXPTIME.rst KRB5_NT_ENTERPRISE_PRINCIPAL.rst KRB5_NT_ENT_PRINCIPAL_AND_ID.rst KRB5_NT_MS_PRINCIPAL.rst KRB5_NT_MS_PRINCIPAL_AND_ID.rst KRB5_NT_PRINCIPAL.rst KRB5_NT_SMTP_NAME.rst KRB5_NT_SRV_HST.rst KRB5_NT_SRV_INST.rst KRB5_NT_SRV_XHST.rst KRB5_NT_UID.rst KRB5_NT_UNKNOWN.rst KRB5_NT_WELLKNOWN.rst KRB5_NT_X500_PRINCIPAL.rst KRB5_PAC_ATTRIBUTES_INFO.rst KRB5_PAC_CLIENT_INFO.rst KRB5_PAC_CLIENT_CLAIMS.rst KRB5_PAC_CREDENTIALS_INFO.rst KRB5_PAC_DELEGATION_INFO.rst KRB5_PAC_DEVICE_CLAIMS.rst KRB5_PAC_DEVICE_INFO.rst KRB5_PAC_LOGON_INFO.rst KRB5_PAC_PRIVSVR_CHECKSUM.rst KRB5_PAC_REQUESTOR.rst KRB5_PAC_SERVER_CHECKSUM.rst KRB5_PAC_TICKET_CHECKSUM.rst KRB5_PAC_UPN_DNS_INFO.rst KRB5_PAC_FULL_CHECKSUM.rst KRB5_PADATA_AFS3_SALT.rst KRB5_PADATA_AP_REQ.rst KRB5_PADATA_AS_CHECKSUM.rst KRB5_PADATA_AS_FRESHNESS.rst KRB5_PADATA_ENCRYPTED_CHALLENGE.rst KRB5_PADATA_ENC_SANDIA_SECURID.rst KRB5_PADATA_ENC_TIMESTAMP.rst KRB5_PADATA_ENC_UNIX_TIME.rst KRB5_PADATA_ETYPE_INFO.rst KRB5_PADATA_ETYPE_INFO2.rst KRB5_PADATA_FOR_USER.rst KRB5_PADATA_FX_COOKIE.rst KRB5_PADATA_FX_ERROR.rst KRB5_PADATA_FX_FAST.rst KRB5_PADATA_GET_FROM_TYPED_DATA.rst KRB5_PADATA_NONE.rst KRB5_PADATA_OSF_DCE.rst KRB5_PADATA_OTP_CHALLENGE.rst KRB5_PADATA_OTP_PIN_CHANGE.rst KRB5_PADATA_OTP_REQUEST.rst KRB5_PADATA_PAC_OPTIONS.rst KRB5_PADATA_PAC_REQUEST.rst KRB5_PADATA_PKINIT_KX.rst KRB5_PADATA_PK_AS_REP.rst KRB5_PADATA_PK_AS_REP_OLD.rst KRB5_PADATA_PK_AS_REQ.rst KRB5_PADATA_PK_AS_REQ_OLD.rst KRB5_PADATA_PW_SALT.rst KRB5_PADATA_REFERRAL.rst KRB5_PADATA_S4U_X509_USER.rst KRB5_PADATA_SAM_CHALLENGE.rst KRB5_PADATA_SAM_CHALLENGE_2.rst KRB5_PADATA_SAM_REDIRECT.rst KRB5_PADATA_SAM_RESPONSE.rst KRB5_PADATA_SAM_RESPONSE_2.rst KRB5_PADATA_SESAME.rst KRB5_PADATA_SPAKE.rst KRB5_PADATA_REDHAT_IDP_OAUTH2.rst KRB5_PADATA_REDHAT_PASSKEY.rst KRB5_PADATA_SVR_REFERRAL_INFO.rst KRB5_PADATA_TGS_REQ.rst KRB5_PADATA_USE_SPECIFIED_KVNO.rst KRB5_PRINCIPAL_COMPARE_CASEFOLD.rst KRB5_PRINCIPAL_COMPARE_ENTERPRISE.rst KRB5_PRINCIPAL_COMPARE_IGNORE_REALM.rst KRB5_PRINCIPAL_COMPARE_UTF8.rst KRB5_PRINCIPAL_PARSE_ENTERPRISE.rst KRB5_PRINCIPAL_PARSE_IGNORE_REALM.rst KRB5_PRINCIPAL_PARSE_NO_DEF_REALM.rst KRB5_PRINCIPAL_PARSE_NO_REALM.rst KRB5_PRINCIPAL_PARSE_REQUIRE_REALM.rst KRB5_PRINCIPAL_UNPARSE_DISPLAY.rst KRB5_PRINCIPAL_UNPARSE_NO_REALM.rst KRB5_PRINCIPAL_UNPARSE_SHORT.rst KRB5_PRIV.rst KRB5_PROMPT_TYPE_NEW_PASSWORD.rst KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN.rst KRB5_PROMPT_TYPE_PASSWORD.rst KRB5_PROMPT_TYPE_PREAUTH.rst KRB5_PVNO.rst KRB5_REALM_BRANCH_CHAR.rst KRB5_RECVAUTH_BADAUTHVERS.rst KRB5_RECVAUTH_SKIP_VERSION.rst KRB5_REFERRAL_REALM.rst KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW.rst KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY.rst KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED.rst KRB5_RESPONDER_QUESTION_PKINIT.rst KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN.rst KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN.rst KRB5_RESPONDER_OTP_FLAGS_NEXTOTP.rst KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN.rst KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC.rst KRB5_RESPONDER_OTP_FORMAT_DECIMAL.rst KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL.rst KRB5_RESPONDER_QUESTION_OTP.rst KRB5_RESPONDER_QUESTION_PASSWORD.rst KRB5_SAFE.rst KRB5_SAM_MUST_PK_ENCRYPT_SAD.rst KRB5_SAM_SEND_ENCRYPTED_SAD.rst KRB5_SAM_USE_SAD_AS_KEY.rst KRB5_TC_MATCH_2ND_TKT.rst KRB5_TC_MATCH_AUTHDATA.rst KRB5_TC_MATCH_FLAGS.rst KRB5_TC_MATCH_FLAGS_EXACT.rst KRB5_TC_MATCH_IS_SKEY.rst KRB5_TC_MATCH_KTYPE.rst KRB5_TC_MATCH_SRV_NAMEONLY.rst KRB5_TC_MATCH_TIMES.rst KRB5_TC_MATCH_TIMES_EXACT.rst KRB5_TC_NOTICKET.rst KRB5_TC_OPENCLOSE.rst KRB5_TC_SUPPORTED_KTYPES.rst KRB5_TGS_NAME.rst KRB5_TGS_NAME_SIZE.rst KRB5_TGS_REP.rst KRB5_TGS_REQ.rst KRB5_TKT_CREDS_STEP_FLAG_CONTINUE.rst KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL.rst KRB5_WELLKNOWN_NAMESTR.rst LR_TYPE_INTERPRETATION_MASK.rst LR_TYPE_THIS_SERVER_ONLY.rst MAX_KEYTAB_NAME_LEN.rst MSEC_DIRBIT.rst MSEC_VAL_MASK.rst SALT_TYPE_AFS_LENGTH.rst SALT_TYPE_NO_LENGTH.rst THREEPARAMOPEN.rst TKT_FLG_ANONYMOUS.rst TKT_FLG_ENC_PA_REP.rst TKT_FLG_FORWARDABLE.rst TKT_FLG_FORWARDED.rst TKT_FLG_HW_AUTH.rst TKT_FLG_INITIAL.rst TKT_FLG_INVALID.rst TKT_FLG_MAY_POSTDATE.rst TKT_FLG_OK_AS_DELEGATE.rst TKT_FLG_POSTDATED.rst TKT_FLG_PRE_AUTH.rst TKT_FLG_PROXIABLE.rst TKT_FLG_PROXY.rst TKT_FLG_RENEWABLE.rst TKT_FLG_TRANSIT_POLICY_CHECKED.rst VALID_INT_BITS.rst VALID_UINT_BITS.rst krb5_const.rst krb5_princ_component.rst krb5_princ_name.rst krb5_princ_realm.rst krb5_princ_set_realm.rst krb5_princ_set_realm_data.rst krb5_princ_set_realm_length.rst krb5_princ_size.rst krb5_princ_type.rst krb5_roundup.rst krb5_x.rst krb5_xc.rst Deprecated macros ------------------------------ .. toctree:: :maxdepth: 1 krb524_convert_creds_kdc.rst krb524_init_ets.rst krb5-1.22.1/doc/appdev/refs/types/0000775000175000017500000000000015051422640016470 5ustar ghudsonghudsonkrb5-1.22.1/doc/appdev/refs/types/krb5_int32.rst0000664000175000017500000000021215051422640021077 0ustar ghudsonghudson.. highlight:: c .. _krb5-int32-struct: krb5_int32 ========== .. .. c:type:: krb5_int32 .. krb5_int32 is a signed 32-bit integer type krb5-1.22.1/doc/appdev/refs/types/krb5_ui_4.rst0000664000175000017500000000021115051422640020777 0ustar ghudsonghudson.. highlight:: c .. _krb5-ui4-struct: krb5_ui_4 ========== .. .. c:type:: krb5_ui_4 .. krb5_ui_4 is an unsigned 32-bit integer type. krb5-1.22.1/doc/appdev/refs/types/index.rst0000664000175000017500000000436615051422640020342 0ustar ghudsonghudsonkrb5 types and structures ========================= Public ------- .. toctree:: :maxdepth: 1 krb5_address.rst krb5_addrtype.rst krb5_ap_req.rst krb5_ap_rep.rst krb5_ap_rep_enc_part.rst krb5_authdata.rst krb5_authdatatype.rst krb5_authenticator.rst krb5_boolean.rst krb5_checksum.rst krb5_const_pointer.rst krb5_const_principal.rst krb5_cred.rst krb5_cred_enc_part.rst krb5_cred_info.rst krb5_creds.rst krb5_crypto_iov.rst krb5_cryptotype.rst krb5_data.rst krb5_deltat.rst krb5_enc_data.rst krb5_enc_kdc_rep_part.rst krb5_enc_tkt_part.rst krb5_encrypt_block.rst krb5_enctype.rst krb5_error.rst krb5_error_code.rst krb5_expire_callback_func.rst krb5_flags.rst krb5_get_init_creds_opt.rst krb5_gic_opt_pa_data.rst krb5_int16.rst krb5_int32.rst krb5_kdc_rep.rst krb5_kdc_req.rst krb5_keyblock.rst krb5_keytab_entry.rst krb5_keyusage.rst krb5_kt_cursor.rst krb5_kvno.rst krb5_last_req_entry.rst krb5_magic.rst krb5_mk_req_checksum_func.rst krb5_msgtype.rst krb5_octet.rst krb5_pa_pac_req.rst krb5_pa_server_referral_data.rst krb5_pa_svr_referral_data.rst krb5_pa_data.rst krb5_pointer.rst krb5_post_recv_fn.rst krb5_pre_send_fn.rst krb5_preauthtype.rst krb5_principal.rst krb5_principal_data.rst krb5_prompt.rst krb5_prompt_type.rst krb5_prompter_fct.rst krb5_pwd_data.rst krb5_responder_context.rst krb5_responder_fn.rst krb5_responder_otp_challenge.rst krb5_responder_otp_tokeninfo.rst krb5_responder_pkinit_challenge.rst krb5_responder_pkinit_identity.rst krb5_response.rst krb5_replay_data.rst krb5_ticket.rst krb5_ticket_times.rst krb5_timestamp.rst krb5_tkt_authent.rst krb5_trace_callback.rst krb5_trace_info.rst krb5_transited.rst krb5_typed_data.rst krb5_ui_2.rst krb5_ui_4.rst krb5_verify_init_creds_opt.rst passwd_phrase_element.rst Internal --------- .. toctree:: :maxdepth: 1 krb5_auth_context.rst krb5_cksumtype krb5_context.rst krb5_cc_cursor.rst krb5_ccache.rst krb5_cccol_cursor.rst krb5_init_creds_context.rst krb5_key.rst krb5_keytab.rst krb5_pac.rst krb5_rcache.rst krb5_tkt_creds_context.rst krb5-1.22.1/doc/appdev/refs/index.rst0000664000175000017500000000024515051422640017166 0ustar ghudsonghudsonComplete reference - API and datatypes ====================================== .. toctree:: :maxdepth: 1 api/index.rst types/index.rst macros/index.rst krb5-1.22.1/doc/appdev/index.rst0000664000175000017500000000033615051422640016230 0ustar ghudsonghudsonFor application developers ========================== .. toctree:: :maxdepth: 1 gssapi.rst y2038.rst h5l_mit_apidiff.rst init_creds.rst princ_handle.rst .. toctree:: :maxdepth: 1 refs/index.rst krb5-1.22.1/doc/_static/0000775000175000017500000000000015051422640014534 5ustar ghudsonghudsonkrb5-1.22.1/doc/_static/kerb.css_t0000664000175000017500000000463115051422640016520 0ustar ghudsonghudson/* * kerb.css * ~~~~~~~~~~~ * * Sphinx stylesheet -- modification to agogo theme. * */ div.body { padding-right: .5em; text-align: left; overflow-x: hidden; } /* Page layout */ div.header, div.content, div.footer { margin-left: auto; margin-right: auto; padding-left: 1em; padding-right: 1em; max-width: 60em; } div.header-wrapper { background: white; border-bottom: 3px solid #2e3436; border-top: 13px solid #5d1509; } /* Header */ div.header { padding-top: 10px; padding-bottom: 0px; } div.header h1 { font-family: "Georgia", "Times New Roman", serif, black; font-weight: normal; } div.header h1 a { color: {{ theme_bgcolor }}; font-size: 120%; padding-top: 10px; } div.header div.right a { color: #fcaf3e; letter-spacing: .1em; text-transform: lowercase; float: right; } div.header div.rel { font-family: "Georgia", "Times New Roman", serif, black; font-weight: normal; margin-bottom: 1.6em; } /* Content */ div.document { width: 80%; float: left; margin: 0; background-color: white; padding-top: 20px; padding-bottom: 20px; } div.document div.section h1 { margin-bottom: 20px; padding: 1px; line-height: 130%; } div.document div.section dl { margin-top: 15px; margin-bottom: 5px; padding: 1px; text-align: left; } /* Sidebar */ div.sidebar { float: right; font-size: .9em; width: 20%; margin: 0; padding: 0; background-color: #F9F9F9; } div.sidebar ul { list-style-type: none; margin-left: .5em; } div.sidebar li.toctree-l1 a { margin-left: .5em; } div.sidebar li.toctree-l2 a { margin-left: .5em; } div.sidebar li.toctree-l3 a { margin-left: .5em; } div.sidebar li.toctree-l2.current a { border-right: 2px solid #fcaf3e !important; } div.sidebar li.toctree-l3.current a { font-weight: bold; } div.sidebar li.toctree-l4 a { display: none; } div.sidebar input[type=text] { width: auto; } /* Other body styles */ dt:target, .highlighted { background-color: #c1c1c1; } /* Code displays */ pre { overflow: auto; overflow-y: hidden; } td.linenos pre { padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } /* ordered lists */ ol.arabic { list-style: decimal; } ol.loweralpha { list-style: lower-alpha; } ol.upperalpha { list-style: upper-alpha; } ol.lowerroman { list-style-type: lower-roman; } ol.upperroman { list-style-type: upper-roman; } krb5-1.22.1/doc/build/0000775000175000017500000000000015051422640014205 5ustar ghudsonghudsonkrb5-1.22.1/doc/build/directory_org.rst0000664000175000017500000000616615051422640017623 0ustar ghudsonghudsonOrganization of the source directory ==================================== Below is a brief overview of the organization of the complete source directory. More detailed descriptions follow. =============== ============================================== appl Kerberos application client and server programs ccapi Credential cache services clients Kerberos V5 user programs (See :ref:`user_commands`) config Configure scripts config-files Sample Kerberos configuration files include include files needed to build the Kerberos system kadmin Administrative interface to the Kerberos database: :ref:`kadmin(1)`, :ref:`kdb5_util(8)`, :ref:`ktutil(1)`. kdc Kerberos V5 Authentication Service and Key Distribution Center lib_ Libraries for use with/by Kerberos V5 plugins Kerberos plugins directory po Localization infrastructure prototype Templates files containing the MIT copyright message and a placeholder for the title and description of the file. kprop Utilities for propagating the database to replica KDCs :ref:`kprop(8)` and :ref:`kpropd(8)` tests Test suite util_ Various utilities for building/configuring the code, sending bug reports, etc. windows Source code for building Kerberos V5 on Windows (see windows/README) =============== ============================================== .. _lib: lib --- The lib directory contain several subdirectories as well as some definition and glue files. - The apputils directory contains the code for the generic network servicing. - The crypto subdirectory contains the Kerberos V5 encryption library. - The gssapi library contains the Generic Security Services API, which is a library of commands to be used in secure client-server communication. - The kadm5 directory contains the libraries for the KADM5 administration utilities. - The Kerberos 5 database libraries are contained in kdb. - The krb5 directory contains Kerberos 5 API. - The rpc directory contains the API for the Kerberos Remote Procedure Call protocol. .. _util: util ---- The util directory contains several utility programs and libraries. - the programs used to configure and build the code, such as autoconf, lndir, kbuild, reconf, and makedepend, are in this directory. - the profile directory contains most of the functions which parse the Kerberos configuration files (krb5.conf and kdc.conf). - the Kerberos error table library and utilities (et); - the Sub-system library and utilities (ss); - database utilities (db2); - pseudo-terminal utilities (pty); - bug-reporting program send-pr; - a generic support library support used by several of our other libraries; - the build infrastructure for building lightweight Kerberos client (collected-client-lib) - the tool for validating Kerberos configuration files (confvalidator); - the toolkit for kernel integrators for building krb5 code subsets (gss-kernel-lib); - source code for building Kerberos V5 on MacOS (mac) - Windows getopt operations (windows) krb5-1.22.1/doc/build/doing_build.rst0000664000175000017500000001214715051422640017223 0ustar ghudsonghudsonDoing the build =============== .. _do_build: Building within a single tree ----------------------------- If you only need to build Kerberos for one platform, using a single directory tree which contains both the source files and the object files is the simplest. However, if you need to maintain Kerberos for a large number of platforms, you will probably want to use separate build trees for each platform. We recommend that you look at OS Incompatibilities, for notes that we have on particular operating systems. If you don't want separate build trees for each architecture, then use the following abbreviated procedure:: cd /u1/krb5-VERSION/src ./configure make That's it! Building with separate build directories ---------------------------------------- If you wish to keep separate build directories for each platform, you can do so using the following procedure. (Note, this requires that your make program support VPATH. GNU's make will provide this functionality, for example.) If your make program does not support this, see the next section. For example, if you wish to store the binaries in ``tmpbuild`` build directory you might use the following procedure:: mkdir /u1/tmpbuild cd /u1/tmpbuild /u1/krb5-VERSION/src/configure make Building using lndir -------------------- If you wish to keep separate build directories for each platform, and you do not have access to a make program which supports VPATH, all is not lost. You can use the lndir program to create symbolic link trees in your build directory. For example, if you wish to create a build directory for solaris binaries you might use the following procedure:: mkdir /u1/krb5-VERSION/solaris cd /u1/krb5-VERSION/solaris /u1/krb5-VERSION/src/util/lndir `pwd`/../src ./configure make You must give an absolute pathname to lndir because it has a bug that makes it fail for relative pathnames. Note that this version differs from the latest version as distributed and installed by the XConsortium with X11R6. Either version should be acceptable. Installing the binaries ----------------------- Once you have built Kerberos, you should install the binaries. You can do this by running:: make install If you want to install the binaries into a destination directory that is not their final destination, which may be convenient if you want to build a binary distribution to be deployed on multiple hosts, you may use:: make install DESTDIR=/path/to/destdir This will install the binaries under *DESTDIR/PREFIX*, e.g., the user programs will install into *DESTDIR/PREFIX/bin*, the libraries into *DESTDIR/PREFIX/lib*, etc. *DESTDIR* must be an absolute path. Some implementations of make allow multiple commands to be run in parallel, for faster builds. We test our Makefiles in parallel builds with GNU make only; they may not be compatible with other parallel build implementations. Testing the build ----------------- The Kerberos V5 distribution comes with built-in regression tests. To run them, simply type the following command while in the top-level build directory (i.e., the directory where you sent typed make to start building Kerberos; see :ref:`do_build`):: make check On some operating systems, you have to run ``make install`` before running ``make check``, or the test suite will pick up installed versions of Kerberos libraries rather than the newly built ones. You can install into a prefix that isn't in the system library search path, though. Alternatively, you can configure with **-**\ **-disable-rpath**, which renders the build tree less suitable for installation, but allows testing without interference from previously installed libraries. There are additional regression tests available, which are not run by ``make check``. These tests require manual setup and teardown of support infrastructure which is not easily automated, or require excessive resources for ordinary use. The procedure for running the manual tests is documented at https://k5wiki.kerberos.org/wiki/Manual_Testing. Cleaning up the build --------------------- * Use ``make clean`` to remove all files generated by running make command. * Use ``make distclean`` to remove all files generated by running ./configure script. After running ``make distclean`` your source tree (ideally) should look like the raw (just un-tarred) source tree. Using autoconf -------------- (If you are not a developer, you can ignore this section.) In the Kerberos V5 source directory, there is a configure script which automatically determines the compilation environment and creates the proper Makefiles for a particular platform. This configure script is generated using autoconf, which you should already have installed if you will be making changes to ``src/configure.in``. Normal users will not need to worry about running autoconf; the distribution comes with the configure script already prebuilt. The autoconf package comes with a script called ``autoreconf`` that will automatically run ``autoconf`` and ``autoheader`` as needed. You should run ``autoreconf`` from the top source directory, e.g.:: cd /u1/krb5-VERSION/src autoreconf --verbose krb5-1.22.1/doc/build/options2configure.rst0000664000175000017500000003444715051422640020432 0ustar ghudsonghudson.. _options2configure: Options to *configure* ====================== There are a number of options to configure which you can use to control how the Kerberos distribution is built. Most commonly used options -------------------------- **-**\ **-help** Provides help to configure. This will list the set of commonly used options for building Kerberos. **-**\ **-prefix=**\ *PREFIX* By default, Kerberos will install the package's files rooted at ``/usr/local``. If you desire to place the binaries into the directory *PREFIX*, use this option. **-**\ **-exec-prefix=**\ *EXECPREFIX* This option allows one to separate the architecture independent programs from the host-dependent files (configuration files, manual pages). Use this option to install architecture-dependent programs in *EXECPREFIX*. The default location is the value of specified by **-**\ **-prefix** option. **-**\ **-localstatedir=**\ *LOCALSTATEDIR* This option sets the directory for locally modifiable single-machine data. In Kerberos, this mostly is useful for setting a location for the KDC data files, as they will be installed in ``LOCALSTATEDIR/krb5kdc``, which is by default ``PREFIX/var/krb5kdc``. **-**\ **-with-netlib**\ [=\ *libs*] Allows for suppression of or replacement of network libraries. By default, Kerberos V5 configuration will look for ``-lnsl`` and ``-lsocket``. If your operating system has a broken resolver library or fails to pass the tests in ``src/tests/resolv``, you will need to use this option. **-**\ **-enable-dns-for-realm** Enable the use of DNS to look up a host's Kerberos realm, if the information is not provided in :ref:`krb5.conf(5)`. See :ref:`mapping_hostnames` for information about using DNS to determine the default realm. DNS lookups for realm names are disabled by default. **-**\ **-with-system-et** Use an installed version of the error-table (et) support software, the compile_et program, the com_err.h header file and the com_err library. If these are not in the default locations, you may wish to specify ``CPPFLAGS=-I/some/dir`` and ``LDFLAGS=-L/some/other/dir`` options at configuration time as well. If this option is not given, a version supplied with the Kerberos sources will be built and installed along with the rest of the Kerberos tree, for Kerberos applications to link against. **-**\ **-with-system-ss** Use an installed version of the subsystem command-line interface software, the mk_cmds program, the ``ss/ss.h`` header file and the ss library. If these are not in the default locations, you may wish to specify ``CPPFLAGS=-I/some/dir`` and ``LDFLAGS=-L/some/other/dir`` options at configuration time as well. See also the **SS_LIB** option. If this option is not given, the ss library supplied with the Kerberos sources will be compiled and linked into those programs that need it; it will not be installed separately. **-**\ **-with-system-db** Use an installed version of the Berkeley DB package, which must provide an API compatible with version 1.85. This option is unsupported and untested. In particular, we do not know if the database-rename code used in the dumpfile load operation will behave properly. If this option is not given, a version supplied with the Kerberos sources will be built and installed. (We are not updating this version at this time because of licensing issues with newer versions that we haven't investigated sufficiently yet.) Environment variables --------------------- **CC=**\ *COMPILER* Use *COMPILER* as the C compiler. **CFLAGS=**\ *FLAGS* Use *FLAGS* as the default set of C compiler flags. **CPP=**\ *CPP* C preprocessor to use. (e.g., ``CPP='gcc -E'``) **CPPFLAGS=**\ *CPPOPTS* Use *CPPOPTS* as the default set of C preprocessor flags. The most common use of this option is to select certain #define's for use with the operating system's include files. **DB_HEADER=**\ *headername* If db.h is not the correct header file to include to compile against the Berkeley DB 1.85 API, specify the correct header file name with this option. For example, ``DB_HEADER=db3/db_185.h``. **DB_LIB=**\ *libs*... If ``-ldb`` is not the correct library specification for the Berkeley DB library version to be used, override it with this option. For example, ``DB_LIB=-ldb-3.3``. **DEFCCNAME=**\ *ccachename* Override the built-in default credential cache name. For example, ``DEFCCNAME=DIR:/var/run/user/%{USERID}/ccache`` See :ref:`parameter_expansion` for information about supported parameter expansions. **DEFCKTNAME=**\ *keytabname* Override the built-in default client keytab name. The format is the same as for *DEFCCNAME*. **DEFKTNAME=**\ *keytabname* Override the built-in default keytab name. The format is the same as for *DEFCCNAME*. **LD=**\ *LINKER* Use *LINKER* as the default loader if it should be different from C compiler as specified above. **LDFLAGS=**\ *LDOPTS* This option informs the linker where to get additional libraries (e.g., ``-L``). **LIBS=**\ *LDNAME* This option allows one to specify libraries to be passed to the linker (e.g., ``-l``) **PKCS11_MODNAME=**\ *library* Override the built-in default PKCS11 library name. **SS_LIB=**\ *libs*... If ``-lss`` is not the correct way to link in your installed ss library, for example if additional support libraries are needed, specify the correct link options here. Some variants of this library are around which allow for Emacs-like line editing, but different versions require different support libraries to be explicitly specified. This option is ignored if **-**\ **-with-system-ss** is not specified. **YACC** The 'Yet Another C Compiler' implementation to use. Defaults to the first program found out of: '`bison -y`', '`byacc`', '`yacc`'. **YFLAGS** The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of ``-d`` given by some make applications. Fine tuning of the installation directories ------------------------------------------- **-**\ **-bindir=**\ *DIR* User executables. Defaults to ``EXECPREFIX/bin``, where *EXECPREFIX* is the path specified by **-**\ **-exec-prefix** configuration option. **-**\ **-sbindir=**\ *DIR* System admin executables. Defaults to ``EXECPREFIX/sbin``, where *EXECPREFIX* is the path specified by **-**\ **-exec-prefix** configuration option. **-**\ **-sysconfdir=**\ *DIR* Read-only single-machine data such as krb5.conf. Defaults to ``PREFIX/etc``, where *PREFIX* is the path specified by **-**\ **-prefix** configuration option. **-**\ **-libdir=**\ *DIR* Object code libraries. Defaults to ``EXECPREFIX/lib``, where *EXECPREFIX* is the path specified by **-**\ **-exec-prefix** configuration option. **-**\ **-includedir=**\ *DIR* C header files. Defaults to ``PREFIX/include``, where *PREFIX* is the path specified by **-**\ **-prefix** configuration option. **-**\ **-datarootdir=**\ *DATAROOTDIR* Read-only architecture-independent data root. Defaults to ``PREFIX/share``, where *PREFIX* is the path specified by **-**\ **-prefix** configuration option. **-**\ **-datadir=**\ *DIR* Read-only architecture-independent data. Defaults to path specified by **-**\ **-datarootdir** configuration option. **-**\ **-localedir=**\ *DIR* Locale-dependent data. Defaults to ``DATAROOTDIR/locale``, where *DATAROOTDIR* is the path specified by **-**\ **-datarootdir** configuration option. **-**\ **-mandir=**\ *DIR* Man documentation. Defaults to ``DATAROOTDIR/man``, where *DATAROOTDIR* is the path specified by **-**\ **-datarootdir** configuration option. Program names ------------- **-**\ **-program-prefix=**\ *PREFIX* Prepend *PREFIX* to the names of the programs when installing them. For example, specifying ``--program-prefix=mit-`` at the configure time will cause the program named ``abc`` to be installed as ``mit-abc``. **-**\ **-program-suffix=**\ *SUFFIX* Append *SUFFIX* to the names of the programs when installing them. For example, specifying ``--program-suffix=-mit`` at the configure time will cause the program named ``abc`` to be installed as ``abc-mit``. **-**\ **-program-transform-name=**\ *PROGRAM* Run ``sed -e PROGRAM`` on installed program names. (*PROGRAM* is a sed script). System types ------------ **-**\ **-build=**\ *BUILD* Configure for building on *BUILD* (e.g., ``--build=x86_64-linux-gnu``). **-**\ **-host=**\ *HOST* Cross-compile to build programs to run on *HOST* (e.g., ``--host=x86_64-linux-gnu``). By default, Kerberos V5 configuration will look for "build" option. Optional features ----------------- **-**\ **-disable-option-checking** Ignore unrecognized --enable/--with options. **-**\ **-disable-**\ *FEATURE* Do not include *FEATURE* (same as --enable-FEATURE=no). **-**\ **-enable-**\ *FEATURE*\ [=\ *ARG*] Include *FEATURE* [ARG=yes]. **-**\ **-enable-maintainer-mode** Enable rebuilding of source files, Makefiles, etc. **-**\ **-disable-delayed-initialization** Initialize library code when loaded. Defaults to delay until first use. **-**\ **-disable-thread-support** Don't enable thread support. Defaults to enabled. **-**\ **-disable-rpath** Suppress run path flags in link lines. **-**\ **-enable-athena** Build with MIT Project Athena configuration. **-**\ **-disable-kdc-lookaside-cache** Disable the cache which detects client retransmits. **-**\ **-disable-pkinit** Disable PKINIT plugin support. **-**\ **-disable-aesni** Disable support for using AES instructions on x86 platforms. **-**\ **-enable-asan**\ [=\ *ARG*] Enable building with asan memory error checking. If *ARG* is given, it controls the -fsanitize compilation flag value (the default is "address"). **-**\ **-enable-ossfuzz** Enable building fuzzing targets with OSS-Fuzz build support. Optional packages ----------------- **-**\ **-with-**\ *PACKAGE*\ [=ARG\] Use *PACKAGE* (e.g., ``--with-imap``). The default value of *ARG* is ``yes``. **-**\ **-without-**\ *PACKAGE* Do not use *PACKAGE* (same as ``--with-PACKAGE=no``) (e.g., ``--without-libedit``). **-**\ **-with-size-optimizations** Enable a few optimizations to reduce code size possibly at some run-time cost. **-**\ **-with-system-et** Use the com_err library and compile_et utility that are already installed on the system, instead of building and installing local versions. **-**\ **-with-system-ss** Use the ss library and mk_cmds utility that are already installed on the system, instead of building and using private versions. **-**\ **-with-system-db** Use the berkeley db utility already installed on the system, instead of using a private version. This option is not recommended; enabling it may result in incompatibility with key databases originating on other systems. **-**\ **-with-netlib=**\ *LIBS* Use the resolver library specified in *LIBS*. Use this variable if the C library resolver is insufficient or broken. **-**\ **-with-hesiod=**\ *path* Compile with Hesiod support. The *path* points to the Hesiod directory. By default Hesiod is unsupported. **-**\ **-with-ldap** Compile OpenLDAP database backend module. **-**\ **-with-lmdb** Compile LMDB database backend module. **-**\ **-with-vague-errors** Do not send helpful errors to client. For example, if the KDC should return only vague error codes to clients. **-**\ **-with-crypto-impl=**\ *IMPL* Use specified crypto implementation (e.g., **-**\ **-with-crypto-impl=**\ *openssl*). The default is the native MIT Kerberos implementation ``builtin``. The other currently implemented crypto backend is ``openssl``. (See :ref:`mitK5features`) **-**\ **-without-libedit** Do not compile and link against libedit. Some utilities will no longer offer command history or completion in interactive mode if libedit is disabled. **-**\ **-with-readline** Compile and link against GNU readline, as an alternative to libedit. **-**\ **-with-system-verto** Use an installed version of libverto. If the libverto header and library are not in default locations, you may wish to specify ``CPPFLAGS=-I/some/dir`` and ``LDFLAGS=-L/some/other/dir`` options at configuration time as well. If this option is not given, the build system will try to detect an installed version of libverto and use it if it is found. Otherwise, a version supplied with the Kerberos sources will be built and installed. The built-in version does not contain the full set of back-end modules and is not a suitable general replacement for the upstream version, but will work for the purposes of Kerberos. Specifying **-**\ **-without-system-verto** will cause the built-in version of libverto to be used unconditionally. **-**\ **-with-krb5-config=**\ *PATH* Use the krb5-config program at *PATH* to obtain the build-time default credential cache, keytab, and client keytab names. The default is to use ``krb5-config`` from the program path. Specify ``--without-krb5-config`` to disable the use of krb5-config and use the usual built-in defaults. **-**\ **-without-keyutils** Build without libkeyutils support. This disables the KEYRING credential cache type. Examples -------- For example, in order to configure Kerberos on a Solaris machine using the suncc compiler with the optimizer turned on, run the configure script with the following options:: % ./configure CC=suncc CFLAGS=-O For a slightly more complicated example, consider a system where several packages to be used by Kerberos are installed in ``/usr/foobar``, including Berkeley DB 3.3, and an ss library that needs to link against the curses library. The configuration of Kerberos might be done thus:: ./configure CPPFLAGS=-I/usr/foobar/include LDFLAGS=-L/usr/foobar/lib \ --with-system-et --with-system-ss --with-system-db \ SS_LIB='-lss -lcurses' DB_HEADER=db3/db_185.h DB_LIB=-ldb-3.3 krb5-1.22.1/doc/build/index.rst0000664000175000017500000000413215051422640016046 0ustar ghudsonghudson.. _build_V5: Building Kerberos V5 ==================== This section details how to build and install MIT Kerberos software from the source. Prerequisites ------------- In order to build Kerberos V5, you will need approximately 60-70 megabytes of disk space. The exact amount will vary depending on the platform and whether the distribution is compiled with debugging symbol tables or not. Your C compiler must conform to ANSI C (ISO/IEC 9899:1990, "c89"). Some operating systems do not have an ANSI C compiler, or their default compiler requires extra command-line options to enable ANSI C conformance. If you wish to keep a separate build tree, which contains the compiled \*.o file and executables, separate from your source tree, you will need a make program which supports **VPATH**, or you will need to use a tool such as lndir to produce a symbolic link tree for your build tree. Obtaining the software ---------------------- The source code can be obtained from MIT Kerberos Distribution page, at https://kerberos.org/dist/index.html. The MIT Kerberos distribution comes in an archive file, generally named krb5-VERSION-signed.tar, where *VERSION* is a placeholder for the major and minor versions of MIT Kerberos. (For example, MIT Kerberos 1.9 has major version "1" and minor version "9".) The krb5-VERSION-signed.tar contains a compressed tar file consisting of the sources for all of Kerberos (generally named krb5-VERSION.tar.gz) and a PGP signature file for this source tree (generally named krb5-VERSION.tar.gz.asc). MIT highly recommends that you verify the integrity of the source code using this signature, e.g., by running:: tar xf krb5-VERSION-signed.tar gpg --verify krb5-VERSION.tar.gz.asc Unpack krb5-VERSION.tar.gz in some directory. In this section we will assume that you have chosen the top directory of the distribution the directory ``/u1/krb5-VERSION``. Review the README file for the license, copyright and other sprecific to the distribution information. Contents -------- .. toctree:: :maxdepth: 1 directory_org.rst doing_build.rst options2configure.rst osconf.rst krb5-1.22.1/doc/build/osconf.rst0000664000175000017500000000156115051422640016231 0ustar ghudsonghudsonosconf.hin ========== There is one configuration file which you may wish to edit to control various compile-time parameters in the Kerberos distribution:: include/osconf.hin The list that follows is by no means complete, just some of the more interesting variables. **DEFAULT_PROFILE_PATH** The pathname to the file which contains the profiles for the known realms, their KDCs, etc. The default value is |krb5conf|. **DEFAULT_KEYTAB_NAME** The type and pathname to the default server keytab file. The default is |keytab|. **DEFAULT_KDC_ENCTYPE** The default encryption type for the KDC database master key. The default value is |defmkey|. **RCTMPDIR** The directory which stores replay caches. The default is ``/var/tmp``. **DEFAULT_KDB_FILE** The location of the default database. The default value is |kdcdir|\ ``/principal``. krb5-1.22.1/doc/formats/0000775000175000017500000000000015051422640014561 5ustar ghudsonghudsonkrb5-1.22.1/doc/formats/rcache_file_format.rst0000664000175000017500000000455615051422640021121 0ustar ghudsonghudsonReplay cache file format ======================== This section documents the second version of the replay cache file format, used by the "file2" replay cache type (new in release 1.18). The first version of the file replay cache format is not documented. All accesses to the replay cache file take place under an exclusive POSIX or Windows file lock, obtained when the file is opened and released when it is closed. Replay cache files are automatically created when first accessed. For each store operation, a tag is derived from the checksum part of the :RFC:`3961` ciphertext of the authenticator. The checksum is coerced to a fixed length of 12 bytes, either through truncation or right-padding with zero bytes. A four-byte timestamp is appended to the tag to produce a total record length of 16 bytes. Bytes 0 through 15 of the file contain a hash seed for the SipHash-2-4 algorithm (siphash_); this field is populated with random bytes when the file is first created. All remaining bytes are divided into a series of expanding hash tables: * Bytes 16-16383: hash table 1 (1023 slots) * Bytes 16384-49151: hash table 2 (2048 slots) * Bytes 49152-114687: hash table 3 (4096 slots) * ... Only some hash tables will be present in the file at any specific time, and the final table may be only partially filled. Replay cache files may be sparse if the filesystem supports it. For each table present in the file, the tag is hashed with SipHash-2-4 using the seed recorded in the file. The first byte of the seed is incremented by one (modulo 256) for each table after the first. The resulting hash value is taken modulo one less than the table size (1022 for the first hash table, 2047 for the second) to produce the index. The record may be found at the slot given by the index or at the next slot. All candidate locations for the record must be searched until a slot is found with a timestamp of zero (indicating a slot which has never been written to) or an offset is reached at or beyond the end of the file. Any candidate location with a timestamp value of zero, with a timestamp value less than the current time minus clockskew, or at or beyond the end of the file is available for writing. When all candidate locations have been searched without finding a match, the new entry is written to the earliest candidate available for writing. .. _siphash: https://131002.net/siphash/siphash.pdf krb5-1.22.1/doc/formats/keytab_file_format.rst0000664000175000017500000000337515051422640021151 0ustar ghudsonghudson.. _keytab_file_format: Keytab file format ================== There are two versions of the file format used by the FILE keytab type. The first byte of the file always has the value 5, and the value of the second byte contains the version number (1 or 2). Version 1 of the file format uses native byte order for integer representations. Version 2 always uses big-endian byte order. After the two-byte version indicator, the file contains a sequence of signed 32-bit record lengths followed by key records or holes. A positive record length indicates a valid key entry whose size is equal to or less than the record length. A negative length indicates a zero-filled hole whose size is the inverse of the length. A length of 0 indicates the end of the file. Key entry format ---------------- A key entry may be smaller in size than the record length which precedes it, because it may have replaced a hole which is larger than the key entry. Key entries use the following informal grammar:: entry ::= principal timestamp (32 bits) key version (8 bits) enctype (16 bits) key length (16 bits) key contents key version (32 bits) [in release 1.14 and later] principal ::= count of components (16 bits) [includes realm in version 1] realm (data) component1 (data) component2 (data) ... name type (32 bits) [omitted in version 1] data ::= length (16 bits) value (length bytes) The 32-bit key version overrides the 8-bit key version. To determine if it is present, the implementation must check that at least 4 bytes remain in the record after the other fields are read, and that the value of the 32-bit integer contained in those bytes is non-zero. krb5-1.22.1/doc/formats/database_formats.rst0000664000175000017500000003652415051422640020624 0ustar ghudsonghudsonKerberos Database (KDB) Formats =============================== Dump format ----------- Files created with the :ref:`kdb5_util(8)` **dump** command begin with a versioned header "kdb5_util load_dump version 7". This version has been in use since MIT krb5 release 1.11; some previous versions are supported but are not described here. Each subsequent line of the dump file contains one or more tab-separated fields describing either a principal entry or a policy entry. The fields of a principal entry line are: * the word "princ" * the string "38" (this was originally a length field) * the length of the principal name in string form * the decimal number of tag-length data elements * the decimal number of key-data elements * the string "0" (this was originally an extension length field) * the principal name in string form * the principal attributes as a decimal number; when converted to binary, the bits from least significant to most significant are: - disallow_postdated - disallow_forwardable - disallow_tgt_based - disallow_renewable - disallow_proxiable - disallow_dup_skey - disallow_all_tix - requires_preauth - requires_hwauth - requires_pwchange - disallow_svr - pwchange_service - support_desmd5 - new_princ - ok_as_delegate - ok_to_auth_as_delegate - no_auth_data_required - lockdown_keys * the maximum ticket lifetime, as a decimal number of seconds * the maximum renewable ticket lifetime, as a decimal number of seconds * the principal expiration time, as a decimal POSIX timestamp * the password expiration time, as a decimal POSIX timestamp * the last successful authentication time, as a decimal POSIX timestamp * the last failed authentication time, as a decimal POSIX timestamp * the decimal number of failed authentications since the last successful authentication time * for each tag-length data value: - the tag value in decimal - the length in decimal - the data as a lowercase hexadecimal byte string, or "-1" if the length is 0 * for each key-data element: - the string "2" if this element has non-normal salt type, "1" otherwise - the key version number of this element - the encryption type - the length of the encrypted key value - the encrypted key as a lowercase hexadecimal byte string - if this element has non-normal salt type: - the salt type - the length of the salt data - the salt data as a lowercase hexadecimal byte string, or the string "-1" if the salt data length is 0 * the string "-1;" (this was originally an extension field) The fields of a policy entry line are: * the string "policy" * the policy name * the minimum password lifetime as a decimal number of seconds * the maximum password lifetime as a decimal number of seconds * the minimum password length, in decimal * the minimum number of character classes, in decimal * the number of historical keys to be stored, in decimal * the policy reference count (no longer used) * the maximum number of failed authentications before lockout * the time interval after which the failed authentication count is reset, as a decimal number of seconds * the lockout duration, as a decimal number of seconds * the required principal attributes, in decimal (currently unenforced) * the maximum ticket lifetime as a decimal number of seconds (currently unenforced) * the maximum renewable lifetime as a decimal number of seconds (currently unenforced) * the allowed key/salt types, or "-" if unrestricted * the number of tag-length values * for each tag-length data value: - the tag value in decimal - the length in decimal - the data as a lowercase hexadecimal byte string, or "-1" if the length is 0 Tag-length data formats ----------------------- The currently defined tag-length data types are: * (1) last password change: a four-byte little-endian POSIX timestamp giving the last password change time * (2) last modification data: a four-byte little-endian POSIX timestamp followed by a zero-terminated principal name in string form, giving the time of the last principal change and the principal who performed it * (3) kadmin data: the XDR encoding of a per-principal kadmin data record (see below) * (8) master key version: a two-byte little-endian integer containing the master key version used to encrypt this principal's key data * (9) active kvno: see below * (10) master key auxiliary data: see below * (11) string attributes: one or more iterations of a zero-terminated string key followed by a zero-terminated string value * (12) alias target principal: a zero-terminated principal name in string form * (255) LDAP object information: see below * (768) referral padata: a DER-encoded PA-SVR-REFERRAL-DATA to be sent to a TGS-REQ client within encrypted padata (see Appendix A of :rfc:`1606`) * (1792) last admin unlock: a four-byte little-endian POSIX timestamp giving the time of the last administrative account unlock * (32767) database arguments: a zero-terminated key=value string (may appear multiple times); used by the kadmin protocol to communicate -x arguments to kadmind Per-principal kadmin data ~~~~~~~~~~~~~~~~~~~~~~~~~ Per-principal kadmin data records use a modified XDR encoding of the kadmin_data type defined as follows: .. code-block:: c struct key_data { int numfields; unsigned int kvno; int enctype; int salttype; unsigned int keylen; unsigned int saltlen; opaque key<>; opaque salt<>; }; struct hist_entry { key_data keys<>; }; struct kadmin_data { int version_number; nullstring policy; int aux_attributes; unsigned int old_key_next; unsigned int admin_history_kvno; hist_entry old_keysets<>; }; The type "nullstring" uses a custom string encoder where the length field is zero or the string length plus one; a length of zero indicates that no policy object is specified for the principal. The field "version_number" contains 0x12345C01. The aux_attributes field contains the bit 0x800 if a policy object is associated with the principal. Within a key_data record, numfields is 2 if the key data has non-normal salt type, 1 otherwise. Active kvno and master key auxiliary data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These types only appear in the entry of the master key principal (K/M). They use little-endian binary integer encoding. The active kvno table determines which master key version is active for a given timestamp. It uses the following binary format: .. code-block:: bnf active-key-version-table ::= version (16 bits) [with the value 1] version entry 1 (key-version-entry) version entry 2 (key-version-entry) ... key-version-entry ::= key version (16 bits) timestamp (32 bits) [when this key version becomes active] The master key auxiliary data record contains copies of the current master key encrypted in each older master key. It uses the following binary format: .. code-block:: bnf master-key-aux ::= version (16 bits) [with the value 1] key entry 1 (key-entry) key entry 2 (key-entry) ... key-entry ::= old master key version (16 bits) latest master key version (16 bits) latest master key encryption type (16 bits) encrypted key length (16 bits) encrypted key contents LDAP object information ~~~~~~~~~~~~~~~~~~~~~~~ This type appears in principal entries retrieved with the LDAP KDB module. The value uses the following binary format, using big-endian integer encoding: .. code-block:: bnf ldap-principal-data ::= record 1 (ldap-tl-data) record 2 (ldap-tl-data) ... ldap-tl-data ::= type (8 bits) length (16 bits) data The currently defined ldap-tl-data types are (all integers are big-endian): * (1) principal type: 16 bits containing the value 1, indicating that the LDAP object containing the principal entry is a standalone principal object * (2) principal count: 16 bits containing the number of krbPrincipalName values in the LDAP object * (3) user DN: the string representation of the distinguished name of the LDAP object * (5) attribute mask: 16 bits indicating which Kerberos-specific LDAP attributes are present in the LDAP object (see below) * (7) link DN: the string representation of the distinguished name of an LDAP object this object is linked to; may appear multiple times When converted to binary, the attribute mask bits, from least significant to most significant, correspond to the following LDAP attributes: * krbMaxTicketLife * krbMaxRenewableAge * krbTicketFlags * krbPrincipalExpiration * krbTicketPolicyReference * krbPrincipalAuthInd * krbPwdPolicyReference * krbPasswordExpiration * krbPrincipalKey * krbLastPwdChange * krbExtraData * krbLastSuccessfulAuth * krbLastFailedAuth * krbLoginFailedCount * krbLastAdminUnlock * krbPwdHistory Alias principal entries ----------------------- To allow aliases to be represented in dump files and within the incremental update protocol, the krb5 database library supports the concept of an alias principal entry. An alias principal entry contains an alias target principal in its tag-length data, has its attributes set to disallow_all_tix, and has zero or empty values for all other fields. The database glue library recognizes alias entries and iteratively looks up the alias target up to a depth of 10 chained aliases. (Added in release 1.22.) DB2 principal and policy formats -------------------------------- The DB2 KDB module uses the string form of a principal name, with zero terminator, as a lookup key for principal entries. Principal entry values use the following binary format with little-endian integer encoding: .. code-block:: bnf db2-principal-entry ::= len (16 bits) [always has the value 38] attributes (32 bits) max ticket lifetime (32 bits) max renewable lifetime (32 bits) principal expiration timestamp (32 bits) password expiration timestamp (32 bits) last successful authentication timestamp (32 bits) last failed authentication timestamp (32 bits) failed authentication counter (32 bits) number of tag-length elements (16 bits) number of key-data elements (16 bits) length of string-form principal with zero terminator (16 bits) string-form principal with zero terminator tag-length entry 1 (tag-length-data) tag-length entry 2 (tag-length-data) ... key-data entry 1 (key-data) key-data entry 2 (key-data) ... tag-length-data ::= type tag (16 bits) data length (16 bits) data key-data ::= salt indicator (16 bits) [1 for default salt, 2 otherwise] key version (16 bits) encryption type (16 bits) encrypted key length (16 bits) encrypted key salt type (16 bits) [omitted if salt indicator is 1] salt data length (16 bits) [omitted if salt indicator is 1] salt data [omitted if salt indicator is 1] DB2 policy entries reside in a separate database file. The lookup key is the policy name with zero terminator. Policy entry values use a modified XDR encoding of the policy type defined as follows: .. code-block:: c struct tl_data { int type; opaque data<>; tl_data *next; }; struct policy { int version_number; unsigned int min_life; unsigned int max_pw_life; unsigned int min_length; unsigned int min_classes; unsigned int history_num; unsigned int refcount; unsigned int max_fail; unsigned int failcount_interval; unsigned int lockout_duration; unsigned int attributes; unsigned int max_ticket_life; unsigned int max_renewable_life; nullstring allowed_keysalts; int n_tl_data; tl_data *tag_length_data; }; The type "nullstring" uses the same custom encoder as in the per-principal kadmin data. The field "version_number" contains 0x12345D01, 0x12345D02, or 0x12345D03 for versions 1, 2, and 3 respectively. Versions 1 and 2 omit the fields "attributes" through "tag_length_data". Version 1 also omits the fields "max_fail" through "lockout_duration". Encoding uses the lowest version that can represent the policy entry. The field "refcount" is no longer used and its value is ignored. LMDB principal and policy formats --------------------------------- In the LMDB KDB module, principal entries are stored in the "principal" database within the main LMDB environment (typically named "principal.mdb"), with the exception of lockout-related fields which are stored in the "lockout" table of the lockout LMDB environment (typically named "principal.lockout.mdb"). For both databases the key is the principal name in string form, with no zero terminator. Values in the "principal" database use the following binary format with little-endian integer encoding: .. code-block:: bnf lmdb-principal-entry ::= attributes (32 bits) max ticket lifetime (32 bits) max renewable lifetime (32 bits) principal expiration timestamp (32 bits) password expiration timestamp (32 bits) number of tag-length elements (16 bits) number of key-data elements (16 bits) tag-length entry 1 (tag-length-data) tag-length entry 2 (tag-length-data) ... key-data entry 1 (key-data) key-data entry 2 (key-data) ... tag-length-data ::= type tag (16 bits) data length (16 bits) data value key-data ::= salt indicator (16 bits) [1 for default salt, 2 otherwise] key version (16 bits) encryption type (16 bits) encrypted key length (16 bits) encrypted key salt type (16 bits) [omitted if salt indicator is 1] salt data length (16 bits) [omitted if salt indicator is 1] salt data [omitted if salt indicator is 1] Values in the "lockout" database have the following binary format with little-endian integer encoding: .. code-block:: bnf lmdb-lockout-entry ::= last successful authentication timestamp (32 bits) last failed authentication timestamp (32 bits) failed authentication counter (32 bits) In the "policy" database, the lookup key is the policy name with no zero terminator. Values in this database use the following binary format with little-endian integer encoding: .. code-block:: bnf lmdb-policy-entry ::= minimum password lifetime (32 bits) maximum password lifetime (32 bits) minimum password length (32 bits) minimum character classes (32 bits) number of historical keys (32 bits) maximum failed authentications before lockout (32 bits) time interval to reset failed authentication counter (32 bits) lockout duration (32 bits) required principal attributes (32 bits) [currently unenforced] maximum ticket lifetime (32 bits) [currently unenforced] maximum renewable lifetime (32 bits) [currently unenforced] allowed key/salt type specification length [32 bits] allowed key/salt type specification number of tag-length values (16 bits) tag-length entry 1 (tag-length-data) tag-length entry 2 (tag-length-data) ... tag-length-data ::= type tag (16 bits) data length (16 bits) data value krb5-1.22.1/doc/formats/cookie.rst0000664000175000017500000000767615051422640016604 0ustar ghudsonghudson.. highlight:: abnf KDC cookie format ================= :rfc:`6113` section 5.2 specifies a pa-data type PA-FX-COOKIE, which clients are required to reflect back to the KDC during pre-authentication. The MIT krb5 KDC uses the following formats for cookies. Trivial cookie (version 0) -------------------------- If there is no pre-authentication mechanism state information to save, a trivial cookie containing the value "MIT" is used. A trivial cookie is needed to indicate that the conversation can continue. Secure cookie (version 1) ------------------------- In release 1.14 and later, a secure cookie can be sent if there is any mechanism state to save for the next request. A secure cookie contains the concatenation of the following: * the four bytes "MIT1" * a four-byte big-endian kvno value * an :rfc:`3961` ciphertext The ciphertext is encrypted in the cookie key with key usage number 513. The cookie key is derived from a key in the local krbtgt principal entry for the realm (e.g. ``krbtgt/KRBTEST.COM@KRBTEST.COM`` if the request is to the ``KRBTEST.COM`` realm). The first krbtgt key for the indicated kvno value is combined with the client principal as follows:: cookie-key <- random-to-key(PRF+(tgt-key, "COOKIE" | client-princ)) where **random-to-key** is the :rfc:`3961` random-to-key operation for the krbtgt key's encryption type, **PRF+** is defined in :rfc:`6113`, and ``|`` denotes concatenation. *client-princ* is the request client principal name with realm, marshalled according to :rfc:`1964` section 2.1.1. The plain text of the encrypted part of a cookie is the DER encoding of the following ASN.1 type: .. code-block:: bnf SecureCookie ::= SEQUENCE { time INTEGER, data SEQUENCE OF PA-DATA, ... } The time field represents the cookie creation time; for brevity, it is encoded as an integer giving the POSIX timestamp rather than as an ASN.1 GeneralizedTime value. The data field contains one element for each pre-authentication type which requires saved state. For mechanisms which have separate request and reply types, the request type is used; this allows the KDC to determine whether a cookie is relevant to a request by comparing the request pa-data types to the cookie data types. SPAKE cookie format (version 1) ------------------------------- Inside the SecureCookie wrapper, a data value of type 151 contains state for SPAKE pre-authentication. This data has the following binary format with big-endian integer encoding: .. code-block:: bnf cookie ::= version (16 bits) [with the value 1] stage number (16 bits) group number (32 bits) SPAKE value length (32 bits) SPAKE value transcript hash length (32 bits) transcript hash second factor record 1 (factor-record) second factor record 2 (factor-record) ... factor-record ::= second factor type (32 bits) second factor data length (32 bits) second factor data The stage value is 0 if the cookie was sent with a challenge message. Otherwise it is 1 for the first encdata message sent by the KDC during an exchange, 2 for the second, etc.. The group value indicates the group number used in the SPAKE challenge. For a stage-0 cookie, the SPAKE value is the KDC private key, represented in the scalar marshalling form of the group. For other cookies, the SPAKE value is the SPAKE result K, represented in the group element marshalling form. For a stage-0 cookie, the transcript hash is the intermediate hash after updating with the client support message (if one was sent) and challenge. For other cookies it is the final hash. For a stage-0 cookie, there may be any number of second-factor records, including none; a second-factor type need not create a state field if it does not need one, and no record is created for SF-NONE. For other cookies, there must be exactly one second-factor record corresponding to the factor type chosen by the client. krb5-1.22.1/doc/formats/index.rst0000664000175000017500000000031015051422640016414 0ustar ghudsonghudsonProtocols and file formats ========================== .. toctree:: :maxdepth: 1 ccache_file_format keytab_file_format rcache_file_format cookie freshness_token database_formats krb5-1.22.1/doc/formats/freshness_token.rst0000664000175000017500000000155615051422640020522 0ustar ghudsonghudsonPKINIT freshness tokens ======================= :rfc:`8070` specifies a pa-data type PA_AS_FRESHNESS, which clients should reflect within signed PKINIT data to prove recent access to the client certificate private key. The contents of a freshness token are left to the KDC implementation. The MIT krb5 KDC uses the following format for freshness tokens (starting in release 1.17): * a four-byte big-endian POSIX timestamp * a four-byte big-endian key version number * an :rfc:`3961` checksum, with no ASN.1 wrapper The checksum is computed using the first key in the local krbtgt principal entry for the realm (e.g. ``krbtgt/KRBTEST.COM@KRBTEST.COM`` if the request is to the ``KRBTEST.COM`` realm) of the indicated key version. The checksum type must be the mandatory checksum type for the encryption type of the krbtgt key. The key usage value for the checksum is 514. krb5-1.22.1/doc/formats/ccache_file_format.rst0000664000175000017500000001430415051422640021072 0ustar ghudsonghudson.. _ccache_file_format: Credential cache file format ============================ There are four versions of the file format used by the FILE credential cache type. The first byte of the file always has the value 5, and the value of the second byte contains the version number (1 through 4). Versions 1 and 2 of the file format use native byte order for integer representations. Versions 3 and 4 always use big-endian byte order. After the two-byte version indicator, the file has three parts: the header (in version 4 only), the default principal name, and a sequence of credentials. Header format ------------- The header appears only in format version 4. It begins with a 16-bit integer giving the length of the entire header, followed by a sequence of fields. Each field consists of a 16-bit tag, a 16-bit length, and a value of the given length. A file format implementation should ignore fields with unknown tags. At this time there is only one defined header field. Its tag value is 1, its length is always 8, and its contents are two 32-bit integers giving the seconds and microseconds of the time offset of the KDC relative to the client. Adding this offset to the current time on the client should give the current time on the KDC, if that offset has not changed since the initial authentication. .. _cache_principal_format: Principal format ---------------- The default principal is marshalled using the following informal grammar:: principal ::= name type (32 bits) [omitted in version 1] count of components (32 bits) [includes realm in version 1] realm (data) component1 (data) component2 (data) ... data ::= length (32 bits) value (length bytes) There is no external framing on the default principal, so it must be parsed according to the above grammar in order to find the sequence of credentials which follows. .. _ccache_credential_format: Credential format ----------------- The credential format uses the following informal grammar (referencing the ``principal`` and ``data`` types from the previous section):: credential ::= client (principal) server (principal) keyblock (keyblock) authtime (32 bits) starttime (32 bits) endtime (32 bits) renew_till (32 bits) is_skey (1 byte, 0 or 1) ticket_flags (32 bits) addresses (addresses) authdata (authdata) ticket (data) second_ticket (data) keyblock ::= enctype (16 bits) [repeated twice in version 3] data addresses ::= count (32 bits) address1 address2 ... address ::= addrtype (16 bits) data authdata ::= count (32 bits) authdata1 authdata2 ... authdata ::= ad_type (16 bits) data There is no external framing on a marshalled credential, so it must be parsed according to the above grammar in order to find the next credential. There is also no count of credentials or marker at the end of the sequence of credentials; the sequence ends when the file ends. Credential cache configuration entries -------------------------------------- Configuration entries are encoded as credential entries. The client principal of the entry is the default principal of the cache. The server principal has the realm ``X-CACHECONF:`` and two or three components, the first of which is ``krb5_ccache_conf_data``. The server principal's second component is the configuration key. The third component, if it exists, is a principal to which the configuration key is associated. The configuration value is stored in the ticket field of the entry. All other entry fields are zeroed. Programs using credential caches must be aware of configuration entries for several reasons: * A program which displays the contents of a cache should not generally display configuration entries. * The ticket field of a configuration entry is not (usually) a valid encoding of a Kerberos ticket. An implementation must not treat the cache file as malformed if it cannot decode the ticket field. * Configuration entries have an endtime field of 0 and might therefore always be considered expired, but they should not be treated as unimportant as a result. For instance, a program which copies credentials from one cache to another should not omit configuration entries because of the endtime. The following configuration keys are currently used in MIT krb5: fast_avail The presence of this key with a non-empty value indicates that the KDC asserted support for FAST (see :rfc:`6113`) during the initial authentication, using the negotiation method described in :rfc:`6806` section 11. This key is not associated with any principal. pa_config_data The value of this key contains a JSON object representation of parameters remembered by the preauthentication mechanism used during the initial authentication. These parameters may be used when refreshing credentials. This key is associated with the server principal of the initial authentication (usually the local krbtgt principal of the client realm). pa_type The value of this key is the ASCII decimal representation of the preauth type number used during the initial authentication. This key is associated with the server principal of the initial authentication. proxy_impersonator The presence of this key indicates that the cache is a synthetic delegated credential for use with S4U2Proxy. The value is the name of the intermediate service whose TGT can be used to make S4U2Proxy requests for target services. This key is not associated with any principal. refresh_time The presence of this key indicates that the cache was acquired by the GSS mechanism using a client keytab. The value is the ASCII decimal representation of a timestamp at which the GSS mechanism should attempt to refresh the credential cache from the client keytab. start_realm This key indicates the realm of the ticket-granting ticket to be used for TGS requests, when making a referrals request or beginning a cross-realm request. If it is not present, the client realm is used. krb5-1.22.1/doc/contributing.txt0000664000175000017500000000472615051422640016367 0ustar ghudsonghudson Contributing to MIT Kerberos DESIGN ====== If you are planning to contribute a substantial amount of work, please ensure that you have a discussion about the design on the krbdev@mit.edu list. Some changes may require coordination with standards groups. For example, interface changes and extensions for the GSS-API should be discussed in the IETF KITTEN Working Group. STYLE ===== Please follow the guidelines in doc/coding-style for new code. For existing code, please preserve its existing indentation and brace conventions. These existing conventions usually resemble the guidelines in doc/coding-style. Exceptions to the style in doc/coding-style are usually large past contributions or imports from other parties. These include (not an exhaustive list): src/appl/bsd src/appl/gssftp src/appl/telnet src/kadmin src/lib/kadm5 src/lib/gssapi/mechglue src/lib/rpc PATCHES ======= We prefer patches in either unified or context diff format (diff -u or diff -c). As is usual practice, please specify the original file before the modified file on the diff command line. It's also useful to perform the diff from the top level of the tree, e.g., diff -ur src.orig src It's even more useful if you use our anonymous Subversion repository at svn://anonsvn.mit.edu/krb5 and use "svn diff" (or "svk diff" if you prefer to use SVK) to generate your patches. It is much easier for us to integrate patches which are generated against current code on the trunk. Please ensure that your source tree is up-to-date before generating your patch. COPYRIGHT ========= If you are submitting substantial quantities of new code, or are substantially modifying existing code, please be clear about the copyright status of your contributions. Note that if your contribution was created in the course of your employment, your employer may own copyright in your contribution. We prefer that MIT receives the ownership of the contributions, but will generally accept contributed code with copyright owned by other parties provided that the license conditions are substantially identical to the existing license on the MIT krb5 code. Appropriate copyright notices and license terms should be added to new or changed files, unless the contributed code is being assigned to the already-listed copyright holder in the file, or the contribution is being released to the public domain. Please make sure that the year in the copyright statement is kept up-to-date. krb5-1.22.1/doc/admin/0000775000175000017500000000000015051422640014176 5ustar ghudsonghudsonkrb5-1.22.1/doc/admin/dbtypes.rst0000664000175000017500000001474215051422640016412 0ustar ghudsonghudson.. _dbtypes: Database types ============== A Kerberos database can be implemented with one of three built-in database providers, called KDB modules. Software which incorporates the MIT krb5 KDC may also provide its own KDB module. The following subsections describe the three built-in KDB modules and the configuration specific to them. The database type can be configured with the **db_library** variable in the :ref:`dbmodules` subsection for the realm. For example:: [dbmodules] ATHENA.MIT.EDU = { db_library = db2 } If the ``ATHENA.MIT.EDU`` realm subsection contains a **database_module** setting, then the subsection within ``[dbmodules]`` should use that name instead of ``ATHENA.MIT.EDU``. To transition from one database type to another, stop the :ref:`kadmind(8)` service, use ``kdb5_util dump`` to create a dump file, change the **db_library** value and set any appropriate configuration for the new database type, and use ``kdb5_util load`` to create and populate the new database. If the new database type is LDAP, create the new database using ``kdb5_ldap_util`` and populate it from the dump file using ``kdb5_util load -update``. Then restart the :ref:`krb5kdc(8)` and :ref:`kadmind(8)` services. Berkeley database module (db2) ------------------------------ The default KDB module is ``db2``, which uses a version of the Berkeley DB library. It creates four files based on the database pathname. If the pathname ends with ``principal`` then the four files are: * ``principal``, containing principal entry data * ``principal.ok``, a lock file for the principal database * ``principal.kadm5``, containing policy object data * ``principal.kadm5.lock``, a lock file for the policy database For large databases, the :ref:`kdb5_util(8)` **dump** command (perhaps invoked by :ref:`kprop(8)` or by :ref:`kadmind(8)` for incremental propagation) may cause :ref:`krb5kdc(8)` to stop for a noticeable period of time while it iterates over the database. This delay can be avoided by disabling account lockout features so that the KDC does not perform database writes (see :ref:`disable_lockout`). Alternatively, a slower form of iteration can be enabled by setting the **unlockiter** variable to ``true``. For example:: [dbmodules] ATHENA.MIT.EDU = { db_library = db2 unlockiter = true } In rare cases, a power failure or other unclean system shutdown may cause inconsistencies in the internal pointers within a database file, such that ``kdb5_util dump`` cannot retrieve all principal entries in the database. In this situation, it may be possible to retrieve all of the principal data by running ``kdb5_util dump -recurse`` to iterate over the database using the tree pointers instead of the iteration pointers. Running ``kdb5_util dump -rev`` to iterate over the database backwards may also retrieve some of the data which is not retrieved by a normal dump operation. Lightning Memory-Mapped Database module (klmdb) ----------------------------------------------- The klmdb module was added in release 1.17. It uses the LMDB library, and may offer better performance and reliability than the db2 module. It creates four files based on the database pathname. If the pathname ends with ``principal``, then the four files are: * ``principal.mdb``, containing policy object data and most principal entry data * ``principal.mdb-lock``, a lock file for the primary database * ``principal.lockout.mdb``, containing the account lockout attributes (last successful authentication time, last failed authentication time, and number of failed attempts) for each principal entry * ``principal.lockout.mdb-lock``, a lock file for the lockout database Separating out the lockout attributes ensures that the KDC will never block on an administrative operation such as a database dump or load. It also allows the KDC to operate without write access to the primary database. If both account lockout features are disabled (see :ref:`disable_lockout`), the lockout database files will be created but will not subsequently be opened, and the account lockout attributes will always have zero values. Because LMDB creates a memory map to the database files, it requires a configured memory map size which also determines the maximum size of the database. This size is applied equally to the two databases, so twice the configured size will be consumed in the process address space; this is primarily a limitation on 32-bit platforms. The default value of 128 megabytes should be sufficient for several hundred thousand principal entries. If the limit is reached, kadmin operations will fail and the error message "Environment mapsize limit reached" will appear in the kadmind log file. In this case, the **mapsize** variable can be used to increase the map size. The following example sets the map size to 512 megabytes:: [dbmodules] ATHENA.MIT.EDU = { db_library = klmdb mapsize = 512 } LMDB has a configurable maximum number of readers. The default value of 128 should be sufficient for most deployments. If you are going to use a large number of KDC worker processes, it may be necessary to set the **max_readers** variable to a larger number. By default, LMDB synchronizes database files to disk after each write transaction to ensure durability in the case of an unclean system shutdown. The klmdb module always turns synchronization off for the lockout database to ensure reasonable KDC performance, but leaves it on for the primary database. If high throughput for administrative operations (including password changes) is required, the **nosync** variable can be set to "true" to disable synchronization for the primary database. The klmdb module does not support explicit locking with the :ref:`kadmin(1)` **lock** command. LDAP module (kldap) ------------------- The kldap module stores principal and policy data using an LDAP server. To use it you must configure an LDAP server to use the Kerberos schema. See :ref:`conf_ldap` for details. Because :ref:`krb5kdc(8)` is single-threaded, latency in LDAP database accesses may limit KDC operation throughput. If the LDAP server is located on the same server host as the KDC and accessed through an ``ldapi://`` URL, latency should be minimal. If this is not possible, consider starting multiple KDC worker processes with the :ref:`krb5kdc(8)` **-w** option to enable concurrent processing of KDC requests. The kldap module does not support explicit locking with the :ref:`kadmin(1)` **lock** command. krb5-1.22.1/doc/admin/backup_host.rst0000664000175000017500000000340115051422640017230 0ustar ghudsonghudsonBackups of secure hosts ======================= When you back up a secure host, you should exclude the host's keytab file from the backup. If someone obtained a copy of the keytab from a backup, that person could make any host masquerade as the host whose keytab was compromised. In many configurations, knowledge of the host's keytab also allows root access to the host. This could be particularly dangerous if the compromised keytab was from one of your KDCs. If the machine has a disk crash and the keytab file is lost, it is easy to generate another keytab file. (See :ref:`add_princ_kt`.) If you are unable to exclude particular files from backups, you should ensure that the backups are kept as secure as the host's root password. Backing up the Kerberos database -------------------------------- As with any file, it is possible that your Kerberos database could become corrupted. If this happens on one of the replica KDCs, you might never notice, since the next automatic propagation of the database would install a fresh copy. However, if it happens to the primary KDC, the corrupted database would be propagated to all of the replicas during the next propagation. For this reason, MIT recommends that you back up your Kerberos database regularly. Because the primary KDC is continuously dumping the database to a file in order to propagate it to the replica KDCs, it is a simple matter to have a cron job periodically copy the dump file to a secure machine elsewhere on your network. (Of course, it is important to make the host where these backups are stored as secure as your KDCs, and to encrypt its transmission across your network.) Then if your database becomes corrupted, you can load the most recent dump onto the primary KDC. (See :ref:`restore_from_dump`.) krb5-1.22.1/doc/admin/conf_ldap.rst0000664000175000017500000001306015051422640016655 0ustar ghudsonghudson.. _conf_ldap: Configuring Kerberos with OpenLDAP back-end =========================================== 1. Make sure the LDAP server is using local authentication (``ldapi://``) or TLS (``ldaps``). See https://www.openldap.org/doc/admin/tls.html for instructions on configuring TLS support in OpenLDAP. 2. Add the Kerberos schema file to the LDAP Server using the OpenLDAP LDIF file from the krb5 source directory (``src/plugins/kdb/ldap/libkdb_ldap/kerberos.openldap.ldif``). The following example uses local authentication:: ldapadd -Y EXTERNAL -H ldapi:/// -f /path/to/kerberos.openldap.ldif 3. Choose DNs for the :ref:`krb5kdc(8)` and :ref:`kadmind(8)` servers to bind to the LDAP server, and create them if necessary. Specify these DNs with the **ldap_kdc_dn** and **ldap_kadmind_dn** directives in :ref:`kdc.conf(5)`. The kadmind DN will also be used for administrative commands such as :ref:`kdb5_util(8)`. Alternatively, you may configure krb5kdc and kadmind to use SASL authentication to access the LDAP server; see the :ref:`dbmodules` relations **ldap_kdc_sasl_mech** and similar. 4. Specify a location for the LDAP service password file by setting **ldap_service_password_file**. Use ``kdb5_ldap_util stashsrvpw`` to stash passwords for the KDC and kadmind DNs chosen above. For example:: kdb5_ldap_util stashsrvpw -f /path/to/service.keyfile cn=krbadmin,dc=example,dc=com Skip this step if you are using SASL authentication and the mechanism does not require a password. 5. Choose a DN for the global Kerberos container entry (but do not create the entry at this time). Specify this DN with the **ldap_kerberos_container_dn** directive in :ref:`kdc.conf(5)`. Realm container entries will be created underneath this DN. Principal entries may exist either underneath the realm container (the default) or in separate trees referenced from the realm container. 6. Configure the LDAP server ACLs to enable the KDC and kadmin server DNs to read and write the Kerberos data. If **disable_last_success** and **disable_lockout** are both set to true in the :ref:`dbmodules` subsection for the realm, then the KDC DN only requires read access to the Kerberos data. Sample access control information:: access to dn.base="" by * read access to dn.base="cn=Subschema" by * read # Provide access to the realm container. access to dn.subtree= "cn=EXAMPLE.COM,cn=krbcontainer,dc=example,dc=com" by dn.exact="cn=kdc-service,dc=example,dc=com" write by dn.exact="cn=adm-service,dc=example,dc=com" write by * none # Provide access to principals, if not underneath the realm container. access to dn.subtree= "ou=users,dc=example,dc=com" by dn.exact="cn=kdc-service,dc=example,dc=com" write by dn.exact="cn=adm-service,dc=example,dc=com" write by * none access to * by * read If the locations of the container and principals or the DNs of the service objects for a realm are changed then this information should be updated. 7. In :ref:`kdc.conf(5)`, make sure the following relations are set in the :ref:`dbmodules` subsection for the realm:: db_library (set to ``kldap``) ldap_kerberos_container_dn ldap_kdc_dn ldap_kadmind_dn ldap_service_password_file ldap_servers 8. Create the realm using :ref:`kdb5_ldap_util(8)`: kdb5_ldap_util create -subtrees ou=users,dc=example,dc=com -s Use the **-subtrees** option if the principals are to exist in a separate subtree from the realm container. Before executing the command, make sure that the subtree mentioned above ``(ou=users,dc=example,dc=com)`` exists. If the principals will exist underneath the realm container, omit the **-subtrees** option and do not worry about creating the principal subtree. For more information, refer to the section :ref:`ops_on_ldap`. The realm object is created under the **ldap_kerberos_container_dn** specified in the configuration file. This operation will also create the Kerberos container, if not present already. This container can be used to store information related to multiple realms. 9. Add an ``eq`` index for ``krbPrincipalName`` to speed up principal lookup operations. See https://www.openldap.org/doc/admin/tuning.html#Indexes for details. With the LDAP back end it is possible to provide aliases for principal entries. Beginning in release 1.22, aliases can be added with the kadmin **add_alias** command, but it is also possible (in release 1.7 or later) to provide aliases through direct manipulation of the LDAP entries. An entry with aliases contains multiple values of the *krbPrincipalName* attribute. Since LDAP attribute values are not ordered, it is necessary to specify which principal name is canonical, by using the *krbCanonicalName* attribute. Therefore, to create aliases for an entry, first set the *krbCanonicalName* attribute of the entry to the canonical principal name (which should be identical to the pre-existing *krbPrincipalName* value), and then add additional *krbPrincipalName* attributes for the aliases. Principal aliases are only returned by the KDC when the client requests canonicalization. Canonicalization is normally requested for service principals; for client principals, an explicit flag is often required (e.g., ``kinit -C``) and canonicalization is only performed for initial ticket requests. krb5-1.22.1/doc/admin/host_config.rst0000664000175000017500000002222215051422640017232 0ustar ghudsonghudsonHost configuration ================== All hosts running Kerberos software, whether they are clients, application servers, or KDCs, can be configured using :ref:`krb5.conf(5)`. Here we describe some of the behavior changes you might want to make. Default realm ------------- In the :ref:`libdefaults` section, the **default_realm** realm relation sets the default Kerberos realm. For example:: [libdefaults] default_realm = ATHENA.MIT.EDU The default realm affects Kerberos behavior in the following ways: * When a principal name is parsed from text, the default realm is used if no ``@REALM`` component is specified. * The default realm affects login authorization as described below. * For programs which operate on a Kerberos database, the default realm is used to determine which database to operate on, unless the **-r** parameter is given to specify a realm. * A server program may use the default realm when looking up its key in a :ref:`keytab file `, if its realm is not determined by :ref:`domain_realm` configuration or by the server program itself. * If :ref:`kinit(1)` is passed the **-n** flag, it requests anonymous tickets from the default realm. In some situations, these uses of the default realm might conflict. For example, it might be desirable for principal name parsing to use one realm by default, but for login authorization to use a second realm. In this situation, the first realm can be configured as the default realm, and **auth_to_local** relations can be used as described below to use the second realm for login authorization. .. _login_authorization: Login authorization ------------------- If a host runs a Kerberos-enabled login service such as OpenSSH with GSSAPIAuthentication enabled, login authorization rules determine whether a Kerberos principal is allowed to access a local account. By default, a Kerberos principal is allowed access to an account if its realm matches the default realm and its name matches the account name. (For historical reasons, access is also granted by default if the name has two components and the second component matches the default realm; for instance, ``alice/ATHENA.MIT.EDU@ATHENA.MIT.EDU`` is granted access to the ``alice`` account if ``ATHENA.MIT.EDU`` is the default realm.) The simplest way to control local access is using :ref:`.k5login(5)` files. To use these, place a ``.k5login`` file in the home directory of each account listing the principal names which should have login access to that account. If it is not desirable to use ``.k5login`` files located in account home directories, the **k5login_directory** relation in the :ref:`libdefaults` section can specify a directory containing one file per account uname. By default, if a ``.k5login`` file is present, it controls authorization both positively and negatively--any principal name contained in the file is granted access and any other principal name is denied access, even if it would have had access if the ``.k5login`` file didn't exist. The **k5login_authoritative** relation in the :ref:`libdefaults` section can be set to false to make ``.k5login`` files provide positive authorization only. The **auth_to_local** relation in the :ref:`realms` section for the default realm can specify pattern-matching rules to control login authorization. For example, the following configuration allows access to principals from a different realm than the default realm:: [realms] DEFAULT.REALM = { # Allow access to principals from OTHER.REALM. # # [1:$1@$0] matches single-component principal names and creates # a selection string containing the principal name and realm. # # (.*@OTHER\.REALM) matches against the selection string, so that # only principals in OTHER.REALM are matched. # # s/@OTHER\.REALM$// removes the realm name, leaving behind the # principal name as the account name. auth_to_local = RULE:[1:$1@$0](.*@OTHER\.REALM)s/@OTHER\.REALM$// # Also allow principals from the default realm. Omit this line # to only allow access to principals in OTHER.REALM. auth_to_local = DEFAULT } The **auth_to_local_names** subsection of the :ref:`realms` section for the default realm can specify explicit mappings from principal names to local accounts. The key used in this subsection is the principal name without realm, so it is only safe to use in a Kerberos environment with a single realm or a tightly controlled set of realms. An example use of **auth_to_local_names** might be:: [realms] ATHENA.MIT.EDU = { auth_to_local_names = { # Careful, these match principals in any realm! host/example.com = hostaccount fred = localfred } } Local authorization behavior can also be modified using plugin modules; see :ref:`hostrealm_plugin` for details. .. _plugin_config: Plugin module configuration --------------------------- Many aspects of Kerberos behavior, such as client preauthentication and KDC service location, can be modified through the use of plugin modules. For most of these behaviors, you can use the :ref:`plugins` section of krb5.conf to register third-party modules, and to switch off registered or built-in modules. A plugin module takes the form of a Unix shared object (``modname.so``) or Windows DLL (``modname.dll``). If you have installed a third-party plugin module and want to register it, you do so using the **module** relation in the appropriate subsection of the [plugins] section. The value for **module** must give the module name and the path to the module, separated by a colon. The module name will often be the same as the shared object's name, but in unusual cases (such as a shared object which implements multiple modules for the same interface) it might not be. For example, to register a client preauthentication module named ``mypreauth`` installed at ``/path/to/mypreauth.so``, you could write:: [plugins] clpreauth = { module = mypreauth:/path/to/mypreauth.so } Many of the pluggable behaviors in MIT krb5 contain built-in modules which can be switched off. You can disable a built-in module (or one you have registered) using the **disable** directive in the appropriate subsection of the [plugins] section. For example, to disable the use of .k5identity files to select credential caches, you could write:: [plugins] ccselect = { disable = k5identity } If you want to disable multiple modules, specify the **disable** directive multiple times, giving one module to disable each time. Alternatively, you can explicitly specify which modules you want to be enabled for that behavior using the **enable_only** directive. For example, to make :ref:`kadmind(8)` check password quality using only a module you have registered, and no other mechanism, you could write:: [plugins] pwqual = { module = mymodule:/path/to/mymodule.so enable_only = mymodule } Again, if you want to specify multiple modules, specify the **enable_only** directive multiple times, giving one module to enable each time. Some Kerberos interfaces use different mechanisms to register plugin modules. KDC location modules ~~~~~~~~~~~~~~~~~~~~ For historical reasons, modules to control how KDC servers are located are registered simply by placing the shared object or DLL into the "libkrb5" subdirectory of the krb5 plugin directory, which defaults to |libdir|\ ``/krb5/plugins``. For example, Samba's winbind krb5 locator plugin would be registered by placing its shared object in |libdir|\ ``/krb5/plugins/libkrb5/winbind_krb5_locator.so``. .. _gssapi_plugin_config: GSSAPI mechanism modules ~~~~~~~~~~~~~~~~~~~~~~~~ GSSAPI mechanism modules are registered using the file |sysconfdir|\ ``/gss/mech`` or configuration files in the |sysconfdir|\ ``/gss/mech.d`` directory with a ``.conf`` suffix. Each line in these files has the form:: name oid pathname [options] Only the name, oid, and pathname are required. *name* is the mechanism name, which may be used for debugging or logging purposes. *oid* is the object identifier of the GSSAPI mechanism to be registered. *pathname* is a path to the module shared object or DLL. *options* (if present) are options provided to the plugin module, surrounded in square brackets. *type* (if present) can be used to indicate a special type of module. Currently the only special module type is "interposer", for a module designed to intercept calls to other mechanisms. If the environment variable **GSS_MECH_CONFIG** is set, its value is used as the sole mechanism configuration filename. .. _profile_plugin_config: Configuration profile modules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A configuration profile module replaces the information source for :ref:`krb5.conf(5)` itself. To use a profile module, begin krb5.conf with the line:: module PATHNAME:STRING where *PATHNAME* is a path to the module shared object or DLL, and *STRING* is a string to provide to the module. The module will then take over, and the rest of krb5.conf will be ignored. krb5-1.22.1/doc/admin/advanced/0000775000175000017500000000000015051422640015743 5ustar ghudsonghudsonkrb5-1.22.1/doc/admin/advanced/index.rst0000664000175000017500000000012415051422640017601 0ustar ghudsonghudsonAdvanced topics =============== .. toctree:: :maxdepth: 1 retiring-des.rst krb5-1.22.1/doc/admin/advanced/retiring-des.rst0000664000175000017500000005045315051422640021100 0ustar ghudsonghudson.. _retiring-des: Retiring DES ======================= Version 5 of the Kerberos protocol was originally implemented using the Data Encryption Standard (DES) as a block cipher for encryption. While it was considered secure at the time, advancements in computational ability have rendered DES vulnerable to brute force attacks on its 56-bit keyspace. As such, it is now considered insecure and should not be used (:rfc:`6649`). History ------- DES was used in the original Kerberos implementation, and was the only cryptosystem in krb5 1.0. Partial support for triple-DES (3DES) was added in version 1.1, with full support following in version 1.2. The Advanced Encryption Standard (AES), which supersedes DES, gained partial support in version 1.3.0 of krb5 and full support in version 1.3.2. However, deployments of krb5 using Kerberos databases created with older versions of krb5 will not necessarily start using strong crypto for ordinary operation without administrator intervention. MIT krb5 began flagging deprecated encryption types with release 1.17, and removed DES (single-DES) support in release 1.18. As a consequence, a release prior to 1.18 is required to perform these migrations. Types of keys ------------- * The database master key: This key is not exposed to user requests, but is used to encrypt other key material stored in the kerberos database. The database master key is currently stored as ``K/M`` by default. * Password-derived keys: User principals frequently have keys derived from a password. When a new password is set, the KDC uses various string2key functions to generate keys in the database for that principal. * Keytab keys: Application server principals generally use random keys which are not derived from a password. When the database entry is created, the KDC generates random keys of various enctypes to enter in the database, which are conveyed to the application server and stored in a keytab. * Session keys: These are short-term keys generated by the KDC while processing client requests, with an enctype selected by the KDC. For details on the various enctypes and how enctypes are selected by the KDC for session keys and client/server long-term keys, see :ref:`enctypes`. When using the :ref:`kadmin(1)` interface to generate new long-term keys, the **-e** argument can be used to force a particular set of enctypes, overriding the KDC default values. .. note:: When the KDC is selecting a session key, it has no knowledge about the kerberos installation on the server which will receive the service ticket, only what keys are in the database for the service principal. In order to allow uninterrupted operation to clients while migrating away from DES, care must be taken to ensure that kerberos installations on application server machines are configured to support newer encryption types before keys of those new encryption types are created in the Kerberos database for those server principals. Upgrade procedure ----------------- This procedure assumes that the KDC software has already been upgraded to a modern version of krb5 that supports non-DES keys, so that the only remaining task is to update the actual keys used to service requests. The realm used for demonstrating this procedure, ZONE.MIT.EDU, is an example of the worst-case scenario, where all keys in the realm are DES. The realm was initially created with a very old version of krb5, and **supported_enctypes** in :ref:`kdc.conf(5)` was set to a value appropriate when the KDC was installed, but was not updated as the KDC was upgraded: :: [realms] ZONE.MIT.EDU = { [...] master_key_type = des-cbc-crc supported_enctypes = des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3 } This resulted in the keys for all principals in the realm being forced to DES-only, unless specifically requested using :ref:`kadmin(1)`. Before starting the upgrade, all KDCs were running krb5 1.11, and the database entries for some "high-value" principals were: :: [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc krbtgt/ZONE.MIT.EDU' [...] Number of keys: 1 Key: vno 1, des-cbc-crc:v4 [...] [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc kadmin/admin' [...] Number of keys: 1 Key: vno 15, des-cbc-crc [...] [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc kadmin/changepw' [...] Number of keys: 1 Key: vno 14, des-cbc-crc [...] The ``krbtgt/REALM`` key appears to have never been changed since creation (its kvno is 1), and all three database entries have only a des-cbc-crc key. The krbtgt key and KDC keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Perhaps the biggest single-step improvement in the security of the cell is gained by strengthening the key of the ticket-granting service principal, ``krbtgt/REALM``---if this principal's key is compromised, so is the entire realm. Since the server that will handle service tickets for this principal is the KDC itself, it is easy to guarantee that it will be configured to support any encryption types which might be selected. However, the default KDC behavior when creating new keys is to remove the old keys, which would invalidate all existing tickets issued against that principal, rendering the TGTs cached by clients useless. Instead, a new key can be created with the old key retained, so that existing tickets will still function until their scheduled expiry (see :ref:`changing_krbtgt_key`). :: [root@casio krb5kdc]# enctypes=aes256-cts-hmac-sha1-96:normal,\ > aes128-cts-hmac-sha1-96:normal,des3-hmac-sha1:normal,des-cbc-crc:normal [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -e ${enctypes} -randkey \ > -keepold krbtgt/ZONE.MIT.EDU" Authenticating as principal root/admin@ZONE.MIT.EDU with password. Key for "krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU" randomized. .. note:: The new ``krbtgt@REALM`` key should be propagated to replica KDCs immediately so that TGTs issued by the primary KDC can be used to issue service tickets on replica KDCs. Replica KDCs will refuse requests using the new TGT kvno until the new krbtgt entry has been propagated to them. It is necessary to explicitly specify the enctypes for the new database entry, since **supported_enctypes** has not been changed. Leaving **supported_enctypes** unchanged makes a potential rollback operation easier, since all new keys of new enctypes are the result of explicit administrator action and can be easily enumerated. Upgrading the krbtgt key should have minimal user-visible disruption other than that described in the note above, since only clients which list the new enctypes as supported will use them, per the procedure in :ref:`session_key_selection`. Once the krbtgt key is updated, the session and ticket keys for user TGTs will be strong keys, but subsequent requests for service tickets will still get DES keys until the service principals have new keys generated. Application service remains uninterrupted due to the key-selection procedure on the KDC. After the change, the database entry is now: :: [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc krbtgt/ZONE.MIT.EDU' [...] Number of keys: 5 Key: vno 2, aes256-cts-hmac-sha1-96 Key: vno 2, aes128-cts-hmac-sha1-96 Key: vno 2, des3-cbc-sha1 Key: vno 2, des-cbc-crc Key: vno 1, des-cbc-crc:v4 [...] Since the expected disruptions from rekeying the krbtgt principal are minor, after a short testing period, it is appropriate to rekey the other high-value principals, ``kadmin/admin@REALM`` and ``kadmin/changepw@REALM``. These are the service principals used for changing user passwords and updating application keytabs. The kadmin and password-changing services are regular kerberized services, so the session-key-selection algorithm described in :ref:`session_key_selection` applies. It is particularly important to have strong session keys for these services, since user passwords and new long-term keys are conveyed over the encrypted channel. :: [root@casio krb5kdc]# enctypes=aes256-cts-hmac-sha1-96:normal,\ > aes128-cts-hmac-sha1-96:normal,des3-hmac-sha1:normal [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -e ${enctypes} -randkey \ > kadmin/admin" Authenticating as principal root/admin@ZONE.MIT.EDU with password. Key for "kadmin/admin@ZONE.MIT.EDU" randomized. [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -e ${enctypes} -randkey \ > kadmin/changepw" Authenticating as principal root/admin@ZONE.MIT.EDU with password. Key for "kadmin/changepw@ZONE.MIT.EDU" randomized. It is not necessary to retain a single-DES key for these services, since password changes are not part of normal daily workflow, and disruption from a client failure is likely to be minimal. Furthermore, if a kerberos client experiences failure changing a user password or keytab key, this indicates that that client will become inoperative once services are rekeyed to non-DES enctypes. Such problems can be detected early at this stage, giving more time for corrective action. Adding strong keys to application servers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Before switching the default enctypes for new keys over to strong enctypes, it may be desired to test upgrading a handful of services with the new configuration before flipping the switch for the defaults. This still requires using the **-e** argument in :ref:`kadmin(1)` to get non-default enctypes: :: [root@casio krb5kdc]# enctypes=aes256-cts-hmac-sha1-96:normal,\ > aes128-cts-hmac-sha1-96:normal,des3-cbc-sha1:normal,des-cbc-crc:normal [root@casio krb5kdc]# kadmin -r ZONE.MIT.EDU -p zephyr/zephyr@ZONE.MIT.EDU -k -t \ > /etc/zephyr/krb5.keytab -q "ktadd -e ${enctypes} \ > -k /etc/zephyr/krb5.keytab zephyr/zephyr@ZONE.MIT.EDU" Authenticating as principal zephyr/zephyr@ZONE.MIT.EDU with keytab /etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type des-cbc-crc added to keytab WRFILE:/etc/zephyr/krb5.keytab. Be sure to remove the old keys from the application keytab, per best practice. :: [root@casio krb5kdc]# k5srvutil -f /etc/zephyr/krb5.keytab delold Authenticating as principal zephyr/zephyr@ZONE.MIT.EDU with keytab /etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 3 removed from keytab WRFILE:/etc/zephyr/krb5.keytab. Adding strong keys by default ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Once the high-visibility services have been rekeyed, it is probably appropriate to change :ref:`kdc.conf(5)` to generate keys with the new encryption types by default. This enables server administrators to generate new enctypes with the **change** subcommand of :ref:`k5srvutil(1)`, and causes user password changes to add new encryption types for their entries. It will probably be necessary to implement administrative controls to cause all user principal keys to be updated in a reasonable period of time, whether by forcing password changes or a password synchronization service that has access to the current password and can add the new keys. :: [realms] ZONE.MIT.EDU = { supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des3-hmac-sha1:normal des-cbc-crc:normal .. note:: The krb5kdc process must be restarted for these changes to take effect. At this point, all service administrators can update their services and the servers behind them to take advantage of strong cryptography. If necessary, the server's krb5 installation should be configured and/or upgraded to a version supporting non-DES keys. See :ref:`enctypes` for krb5 version and configuration settings. Only when the service is configured to accept non-DES keys should the key version number be incremented and new keys generated (``k5srvutil change && k5srvutil delold``). :: root@dr-willy:~# k5srvutil change Authenticating as principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with keytab /etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type AES-256 CTS mode with 96-bit SHA-1 HMAC added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type AES-128 CTS mode with 96-bit SHA-1 HMAC added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/etc/krb5.keytab. root@dr-willy:~# klist -e -k -t /etc/krb5.keytab Keytab name: WRFILE:/etc/krb5.keytab KVNO Timestamp Principal ---- ----------------- -------------------------------------------------------- 2 10/10/12 17:03:59 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (DES cbc mode with CRC-32) 3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (AES-256 CTS mode with 96-bit SHA-1 HMAC) 3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (AES-128 CTS mode with 96-bit SHA-1 HMAC) 3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (Triple DES cbc mode with HMAC/sha1) 3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (DES cbc mode with CRC-32) root@dr-willy:~# k5srvutil delold Authenticating as principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with keytab /etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 2 removed from keytab WRFILE:/etc/krb5.keytab. When a single service principal is shared by multiple backend servers in a load-balanced environment, it may be necessary to schedule downtime or adjust the population in the load-balanced pool in order to propagate the updated keytab to all hosts in the pool with minimal service interruption. Removing DES keys from usage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This situation remains something of a testing or transitory state, as new DES keys are still being generated, and will be used if requested by a client. To make more progress removing DES from the realm, the KDC should be configured to not generate such keys by default. .. note:: An attacker posing as a client can implement a brute force attack against a DES key for any principal, if that key is in the current (highest-kvno) key list. This attack is only possible if **allow_weak_crypto = true** is enabled on the KDC. Setting the **+requires_preauth** flag on a principal forces this attack to be an online attack, much slower than the offline attack otherwise available to the attacker. However, setting this flag on a service principal is not always advisable; see the entry in :ref:`add_principal` for details. The following KDC configuration will not generate DES keys by default: :: [realms] ZONE.MIT.EDU = { supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des3-hmac-sha1:normal .. note:: As before, the KDC process must be restarted for this change to take effect. It is best practice to update kdc.conf on all KDCs, not just the primary, to avoid unpleasant surprises should the primary fail and a replica need to be promoted. It is now appropriate to remove the legacy single-DES key from the ``krbtgt/REALM`` entry: :: [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -randkey -keepold \ > krbtgt/ZONE.MIT.EDU" Authenticating as principal host/admin@ATHENA.MIT.EDU with password. Key for "krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU" randomized. After the maximum ticket lifetime has passed, the old database entry should be removed. :: [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'purgekeys krbtgt/ZONE.MIT.EDU' Authenticating as principal root/admin@ZONE.MIT.EDU with password. Old keys for principal "krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU" purged. After the KDC is restarted with the new **supported_enctypes**, all user password changes and application keytab updates will not generate DES keys by default. :: contents-vnder-pressvre:~> kpasswd zonetest@ZONE.MIT.EDU Password for zonetest@ZONE.MIT.EDU: [enter old password] Enter new password: [enter new password] Enter it again: [enter new password] Password changed. contents-vnder-pressvre:~> kadmin -r ZONE.MIT.EDU -q 'getprinc zonetest' [...] Number of keys: 3 Key: vno 9, aes256-cts-hmac-sha1-96 Key: vno 9, aes128-cts-hmac-sha1-96 Key: vno 9, des3-cbc-sha1 [...] [kaduk@glossolalia ~]$ kadmin -p kaduk@ZONE.MIT.EDU -r ZONE.MIT.EDU -k \ > -t kaduk-zone.keytab -q 'ktadd -k kaduk-zone.keytab kaduk@ZONE.MIT.EDU' Authenticating as principal kaduk@ZONE.MIT.EDU with keytab kaduk-zone.keytab. Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:kaduk-zone.keytab. Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:kaduk-zone.keytab. Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type des3-cbc-sha1 added to keytab WRFILE:kaduk-zone.keytab. Once all principals have been re-keyed, DES support can be disabled on the KDC (**allow_weak_crypto = false**), and client machines can remove **allow_weak_crypto = true** from their :ref:`krb5.conf(5)` configuration files, completing the migration. **allow_weak_crypto** takes precedence over all places where DES enctypes could be explicitly configured. DES keys will not be used, even if they are present, when **allow_weak_crypto = false**. Support for legacy services ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If there remain legacy services which do not support non-DES enctypes (such as older versions of AFS), **allow_weak_crypto** must remain enabled on the KDC. Client machines need not have this setting, though---applications which require DES can use API calls to allow weak crypto on a per-request basis, overriding the system krb5.conf. However, having **allow_weak_crypto** set on the KDC means that any principals which have a DES key in the database could still use those keys. To minimize the use of DES in the realm and restrict it to just legacy services which require DES, it is necessary to remove all other DES keys. The realm has been configured such that at password and keytab change, no DES keys will be generated by default. The task then reduces to requiring user password changes and having server administrators update their service keytabs. Administrative outreach will be necessary, and if the desire to eliminate DES is sufficiently strong, the KDC administrators may choose to randkey any principals which have not been rekeyed after some timeout period, forcing the user to contact the helpdesk for access. The Database Master Key ----------------------- This procedure does not alter ``K/M@REALM``, the key used to encrypt key material in the Kerberos database. (This is the key stored in the stash file on the KDC if stash files are used.) However, the security risk of a single-DES key for ``K/M`` is minimal, given that access to material encrypted in ``K/M`` (the Kerberos database) is generally tightly controlled. If an attacker can gain access to the encrypted database, they likely have access to the stash file as well, rendering the weak cryptography broken by non-cryptographic means. As such, upgrading ``K/M`` to a stronger encryption type is unlikely to be a high-priority task. Is is possible to upgrade the master key used for the database, if desired. Using :ref:`kdb5_util(8)`'s **add_mkey**, **use_mkey**, and **update_princ_encryption** commands, a new master key can be added and activated for use on new key material, and the existing entries converted to the new master key. krb5-1.22.1/doc/admin/enctypes.rst0000664000175000017500000002247615051422640016575 0ustar ghudsonghudson.. _enctypes: Encryption types ================ Kerberos can use a variety of cipher algorithms to protect data. A Kerberos **encryption type** (also known as an **enctype**) is a specific combination of a cipher algorithm with an integrity algorithm to provide both confidentiality and integrity to data. Enctypes in requests -------------------- Clients make two types of requests (KDC-REQ) to the KDC: AS-REQs and TGS-REQs. The client uses the AS-REQ to obtain initial tickets (typically a Ticket-Granting Ticket (TGT)), and uses the TGS-REQ to obtain service tickets. The KDC uses three different keys when issuing a ticket to a client: * The long-term key of the service: the KDC uses this to encrypt the actual service ticket. The KDC only uses the first long-term key in the most recent kvno for this purpose. * The session key: the KDC randomly chooses this key and places one copy inside the ticket and the other copy inside the encrypted part of the reply. * The reply-encrypting key: the KDC uses this to encrypt the reply it sends to the client. For AS replies, this is a long-term key of the client principal. For TGS replies, this is either the session key of the authenticating ticket, or a subsession key. Each of these keys is of a specific enctype. Each request type allows the client to submit a list of enctypes that it is willing to accept. For the AS-REQ, this list affects both the session key selection and the reply-encrypting key selection. For the TGS-REQ, this list only affects the session key selection. .. _session_key_selection: Session key selection --------------------- The KDC chooses the session key enctype by taking the intersection of its **permitted_enctypes** list, the list of long-term keys for the most recent kvno of the service, and the client's requested list of enctypes. Starting in krb5-1.21, all services are assumed to support aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session keys will not be issued by default. Starting in krb5-1.11, it is possible to set a string attribute on a service principal to control what session key enctypes the KDC may issue for service tickets for that principal, overriding the service's long-term keys and the assumption of aes256-cts-hmac-sha1-96 support. See :ref:`set_string` in :ref:`kadmin(1)` for details. Choosing enctypes for a service ------------------------------- Generally, a service should have a key of the strongest enctype that both it and the KDC support. If the KDC is running a release earlier than krb5-1.11, it is also useful to generate an additional key for each enctype that the service can support. The KDC will only use the first key in the list of long-term keys for encrypting the service ticket, but the additional long-term keys indicate the other enctypes that the service supports. As noted above, starting with release krb5-1.11, there are additional configuration settings that control session key enctype selection independently of the set of long-term keys that the KDC has stored for a service principal. Configuration variables ----------------------- The following ``[libdefaults]`` settings in :ref:`krb5.conf(5)` will affect how enctypes are chosen. **allow_weak_crypto** defaults to *false* starting with krb5-1.8. When *false*, removes weak enctypes from **permitted_enctypes**, **default_tkt_enctypes**, and **default_tgs_enctypes**. Do not set this to *true* unless the use of weak enctypes is an acceptable risk for your environment and the weak enctypes are required for backward compatibility. **allow_des3** was added in release 1.21 and defaults to *false*. Unless this flag is set to *true*, the KDC will not issue tickets with des3-cbc-sha1 session keys. In a future release, this flag will control whether des3-cbc-sha1 is permitted in similar fashion to weak enctypes. **allow_rc4** was added in release 1.21 and defaults to *false*. Unless this flag is set to *true*, the KDC will not issue tickets with arcfour-hmac session keys. In a future release, this flag will control whether arcfour-hmac is permitted in similar fashion to weak enctypes. **permitted_enctypes** controls the set of enctypes that a service will permit for session keys and for ticket and authenticator encryption. The KDC and other programs that access the Kerberos database will ignore keys of non-permitted enctypes. Starting in release 1.18, this setting also acts as the default for **default_tkt_enctypes** and **default_tgs_enctypes**. **default_tkt_enctypes** controls the default set of enctypes that the Kerberos client library requests when making an AS-REQ. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. **default_tgs_enctypes** controls the default set of enctypes that the Kerberos client library requests when making a TGS-REQ. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. The following per-realm setting in :ref:`kdc.conf(5)` affects the generation of long-term keys. **supported_enctypes** controls the default set of enctype-salttype pairs that :ref:`kadmind(8)` will use for generating long-term keys, either randomly or from passwords Enctype compatibility --------------------- See :ref:`Encryption_types` for additional information about enctypes. ========================== ========== ======== ======= enctype weak? krb5 Windows ========================== ========== ======== ======= des-cbc-crc weak <1.18 >=2000 des-cbc-md4 weak <1.18 ? des-cbc-md5 weak <1.18 >=2000 des3-cbc-sha1 deprecated >=1.1 none arcfour-hmac deprecated >=1.3 >=2000 arcfour-hmac-exp weak >=1.3 >=2000 aes128-cts-hmac-sha1-96 >=1.3 >=Vista aes256-cts-hmac-sha1-96 >=1.3 >=Vista aes128-cts-hmac-sha256-128 >=1.15 none aes256-cts-hmac-sha384-192 >=1.15 none camellia128-cts-cmac >=1.9 none camellia256-cts-cmac >=1.9 none ========================== ========== ======== ======= krb5 releases 1.18 and later do not support single-DES. krb5 releases 1.8 and later disable the single-DES enctypes by default. Microsoft Windows releases Windows 7 and later disable single-DES enctypes by default. krb5 releases 1.17 and later flag deprecated encryption types (including ``des3-cbc-sha1`` and ``arcfour-hmac``) in KDC logs and kadmin output. krb5 release 1.19 issues a warning during initial authentication if ``des3-cbc-sha1`` is used. Future releases will disable ``des3-cbc-sha1`` by default and eventually remove support for it. Migrating away from older encryption types ------------------------------------------ Administrator intervention may be required to migrate a realm away from legacy encryption types, especially if the realm was created using krb5 release 1.2 or earlier. This migration should be performed before upgrading to krb5 versions which disable or remove support for legacy encryption types. If there is a **supported_enctypes** setting in :ref:`kdc.conf(5)` on the KDC, make sure that it does not include weak or deprecated encryption types. This will ensure that newly created keys do not use those encryption types by default. Check the ``krbtgt/REALM`` principal using the :ref:`kadmin(1)` **getprinc** command. If it lists a weak or deprecated encryption type as the first key, it must be migrated using the procedure in :ref:`changing_krbtgt_key`. Check the ``kadmin/history`` principal, which should have only one key entry. If it uses a weak or deprecated encryption type, it should be upgraded following the notes in :ref:`updating_history_key`. Check the other kadmin principals: kadmin/changepw, kadmin/admin, and any kadmin/hostname principals that may exist. These principals can be upgraded with **change_password -randkey** in kadmin. Check the ``K/M`` entry. If it uses a weak or deprecated encryption type, it should be upgraded following the procedure in :ref:`updating_master_key`. User and service principals using legacy encryption types can be enumerated with the :ref:`kdb5_util(8)` **tabdump keyinfo** command. Service principals can be migrated with a keytab rotation on the service host, which can be accomplished using the :ref:`k5srvutil(1)` **change** and **delold** commands. Allow enough time for existing tickets to expire between the change and delold operations. User principals with password-based keys can be migrated with a password change. The realm administrator can set a password expiration date using the :ref:`kadmin(1)` **modify_principal -pwexpire** command to force a password change. If a legacy encryption type has not yet been disabled by default in the version of krb5 running on the KDC, it can be disabled administratively with the **permitted_enctypes** variable. For example, setting **permitted_enctypes** to ``DEFAULT -des3 -rc4`` will cause any database keys of the triple-DES and RC4 encryption types to be ignored. krb5-1.22.1/doc/admin/install.rst0000664000175000017500000000065015051422640016377 0ustar ghudsonghudsonInstallation guide ================== Contents -------- .. toctree:: :maxdepth: 2 install_kdc.rst install_clients.rst install_appl_srv.rst Additional references --------------------- #. Debian: `Setting up MIT Kerberos 5 `_ #. Solaris: `Configuring the Kerberos Service `_ krb5-1.22.1/doc/admin/https.rst0000664000175000017500000000364615051422640016103 0ustar ghudsonghudson.. _https: HTTPS proxy configuration ========================= In addition to being able to use UDP or TCP to communicate directly with a KDC as is outlined in RFC4120, and with kpasswd services in a similar fashion, the client libraries can attempt to use an HTTPS proxy server to communicate with a KDC or kpasswd service, using the protocol outlined in [MS-KKDCP]. Communicating with a KDC through an HTTPS proxy allows clients to contact servers when network firewalls might otherwise prevent them from doing so. The use of TLS also encrypts all traffic between the clients and the KDC, preventing observers from conducting password dictionary attacks or from observing the client and server principals being authenticated, at additional computational cost to both clients and servers. An HTTPS proxy server is provided as a feature in some versions of Microsoft Windows Server, and a WSGI implementation named `kdcproxy` is available in the python package index. Configuring the clients ----------------------- To use an HTTPS proxy, a client host must trust the CA which issued that proxy's SSL certificate. If that CA's certificate is not in the system-wide default set of trusted certificates, configure the following relation in the client host's :ref:`krb5.conf(5)` file in the appropriate :ref:`realms` subsection:: http_anchors = FILE:/etc/krb5/cacert.pem Adjust the pathname to match the path of the file which contains a copy of the CA's certificate. The `http_anchors` option is documented more fully in :ref:`krb5.conf(5)`. Configure the client to access the KDC and kpasswd service by specifying their locations in its :ref:`krb5.conf(5)` file in the form of HTTPS URLs for the proxy server:: kdc = https://server.fqdn/KdcProxy kpasswd_server = https://server.fqdn/KdcProxy If the proxy and client are properly configured, client commands such as ``kinit``, ``kvno``, and ``kpasswd`` should all function normally. krb5-1.22.1/doc/admin/various_envs.rst0000664000175000017500000000115115051422640017451 0ustar ghudsonghudsonVarious links ============= Whitepapers ----------- #. https://kerberos.org/software/whitepapers.html Tutorials --------- #. Fulvio Ricciardi _ Troubleshooting --------------- #. https://wiki.ncsa.illinois.edu/display/ITS/Windows+Kerberos+Troubleshooting #. https://www.shrubbery.net/solaris9ab/SUNWaadm/SYSADV6/p27.html #. https://docs.oracle.com/cd/E19253-01/816-4557/trouble-1/index.html #. https://docs.microsoft.com/en-us/previous-versions/tn-archive/bb463167(v=technet.10)#EBAA #. https://bugs.launchpad.net/ubuntu/+source/libpam-heimdal/+bug/86528 krb5-1.22.1/doc/admin/auth_indicator.rst0000664000175000017500000000443515051422640017733 0ustar ghudsonghudson.. _auth_indicator: Authentication indicators ========================= As of release 1.14, the KDC can be configured to annotate tickets if the client authenticated using a stronger preauthentication mechanism such as :ref:`PKINIT ` or :ref:`OTP `. These annotations are called "authentication indicators." Service principals can be configured to require particular authentication indicators in order to authenticate to that service. An authentication indicator value can be any string chosen by the KDC administrator; there are no pre-set values. To use authentication indicators with PKINIT or OTP, first configure the KDC to include an indicator when that preauthentication mechanism is used. For PKINIT, use the **pkinit_indicator** variable in :ref:`kdc.conf(5)`. For OTP, use the **indicator** variable in the token type definition, or specify the indicators in the **otp** user string as described in :ref:`otp_preauth`. To require an indicator to be present in order to authenticate to a service principal, set the **require_auth** string attribute on the principal to the indicator value to be required. If you wish to allow one of several indicators to be accepted, you can specify multiple indicator values separated by spaces. For example, a realm could be configured to set the authentication indicator value "strong" when PKINIT is used to authenticate, using a setting in the :ref:`kdc_realms` subsection:: pkinit_indicator = strong A service principal could be configured to require the "strong" authentication indicator value:: $ kadmin setstr host/high.value.server require_auth strong Password for user/admin@KRBTEST.COM: A user who authenticates with PKINIT would be able to obtain a ticket for the service principal:: $ kinit -X X509_user_identity=FILE:/my/cert.pem,/my/key.pem user $ kvno host/high.value.server host/high.value.server@KRBTEST.COM: kvno = 1 but a user who authenticates with a password would not:: $ kinit user Password for user@KRBTEST.COM: $ kvno host/high.value.server kvno: KDC policy rejects request while getting credentials for host/high.value.server@KRBTEST.COM GSSAPI server applications can inspect authentication indicators through the :ref:`auth-indicators ` name attribute. krb5-1.22.1/doc/admin/dictionary.rst0000664000175000017500000001044615051422640017102 0ustar ghudsonghudson.. _dictionary: Addressing dictionary attack risks ================================== Kerberos initial authentication is normally secured using the client principal's long-term key, which for users is generally derived from a password. Using a pasword-derived long-term key carries the risk of a dictionary attack, where an attacker tries a sequence of possible passwords, possibly requiring much less effort than would be required to try all possible values of the key. Even if :ref:`password policy objects ` are used to force users not to pick trivial passwords, dictionary attacks can sometimes be successful against a significant fraction of the users in a realm. Dictionary attacks are not a concern for principals using random keys. A dictionary attack may be online or offline. An online dictionary attack is performed by trying each password in a separate request to the KDC, and is therefore visible to the KDC and also limited in speed by the KDC's processing power and the network capacity between the client and the KDC. Online dictionary attacks can be mitigated using :ref:`account lockout `. This measure is not totally satisfactory, as it makes it easy for an attacker to deny access to a client principal. An offline dictionary attack is performed by obtaining a ciphertext generated using the password-derived key, and trying each password against the ciphertext. This category of attack is invisible to the KDC and can be performed much faster than an online attack. The attack will generally take much longer with more recent encryption types (particularly the ones based on AES), because those encryption types use a much more expensive string-to-key function. However, the best defense is to deny the attacker access to a useful ciphertext. The required defensive measures depend on the attacker's level of network access. An off-path attacker has no access to packets sent between legitimate users and the KDC. An off-path attacker could gain access to an attackable ciphertext either by making an AS request for a client principal which does not have the **+requires_preauth** flag, or by making a TGS request (after authenticating as a different user) for a server principal which does not have the **-allow_svr** flag. To address off-path attackers, a KDC administrator should set those flags on principals with password-derived keys:: kadmin: add_principal +requires_preauth -allow_svr princname An attacker with passive network access (one who can monitor packets sent between legitimate users and the KDC, but cannot change them or insert their own packets) can gain access to an attackable ciphertext by observing an authentication by a user using the most common form of preauthentication, encrypted timestamp. Any of the following methods can prevent dictionary attacks by attackers with passive network access: * Enabling :ref:`SPAKE preauthentication ` (added in release 1.17) on the KDC, and ensuring that all clients are able to support it. * Using an :ref:`HTTPS proxy ` for communication with the KDC, if the attacker cannot monitor communication between the proxy server and the KDC. * Using FAST, protecting the initial authentication with either a random key (such as a host key) or with :ref:`anonymous PKINIT `. An attacker with active network access (one who can inject or modify packets sent between legitimate users and the KDC) can try to fool the client software into sending an attackable ciphertext using an encryption type and salt string of the attacker's choosing. Any of the following methods can prevent dictionary attacks by active attackers: * Enabling SPAKE preauthentication and setting the **disable_encrypted_timestamp** variable to ``true`` in the :ref:`realms` subsection of the client configuration. * Using an HTTPS proxy as described above, configured in the client's krb5.conf realm configuration. If :ref:`KDC discovery ` is used to locate a proxy server, an active attacker may be able to use DNS spoofing to cause the client to use a different HTTPS server or to not use HTTPS. * Using FAST as described above. If :ref:`PKINIT ` or :ref:`OTP ` are used for initial authentication, the principal's long-term keys are not used and dictionary attacks are usually not a concern. krb5-1.22.1/doc/admin/realm_config.rst0000664000175000017500000002666315051422640017372 0ustar ghudsonghudsonRealm configuration decisions ============================= Before installing Kerberos V5, it is necessary to consider the following issues: * The name of your Kerberos realm (or the name of each realm, if you need more than one). * How you will assign your hostnames to Kerberos realms. * Which ports your KDC and and kadmind services will use, if they will not be using the default ports. * How many replica KDCs you need and where they should be located. * The hostnames of your primary and replica KDCs. * How frequently you will propagate the database from the primary KDC to the replica KDCs. Realm name ---------- Although your Kerberos realm can be any ASCII string, convention is to make it the same as your domain name, in upper-case letters. For example, hosts in the domain ``example.com`` would be in the Kerberos realm:: EXAMPLE.COM If you need multiple Kerberos realms, MIT recommends that you use descriptive names which end with your domain name, such as:: BOSTON.EXAMPLE.COM HOUSTON.EXAMPLE.COM .. _mapping_hostnames: Mapping hostnames onto Kerberos realms -------------------------------------- Mapping hostnames onto Kerberos realms is done in one of three ways. The first mechanism works through a set of rules in the :ref:`domain_realm` section of :ref:`krb5.conf(5)`. You can specify mappings for an entire domain or on a per-hostname basis. Typically you would do this by specifying the mappings for a given domain or subdomain and listing the exceptions. The second mechanism is to use KDC host-based service referrals. With this method, the KDC's krb5.conf has a full [domain_realm] mapping for hosts, but the clients do not, or have mappings for only a subset of the hosts they might contact. When a client needs to contact a server host for which it has no mapping, it will ask the client realm's KDC for the service ticket, and will receive a referral to the appropriate service realm. To use referrals, clients must be running MIT krb5 1.6 or later, and the KDC must be running MIT krb5 1.7 or later. The **host_based_services** and **no_host_referral** variables in the :ref:`kdc_realms` section of :ref:`kdc.conf(5)` can be used to fine-tune referral behavior on the KDC. It is also possible for clients to use DNS TXT records, if **dns_lookup_realm** is enabled in :ref:`krb5.conf(5)`. Such lookups are disabled by default because DNS is an insecure protocol and security holes could result if DNS records are spoofed. If enabled, the client will try to look up a TXT record formed by prepending the prefix ``_kerberos`` to the hostname in question. If that record is not found, the client will attempt a lookup by prepending ``_kerberos`` to the host's domain name, then its parent domain, up to the top-level domain. For the hostname ``boston.engineering.example.com``, the names looked up would be:: _kerberos.boston.engineering.example.com _kerberos.engineering.example.com _kerberos.example.com _kerberos.com The value of the first TXT record found is taken as the realm name. Even if you do not choose to use this mechanism within your site, you may wish to set it up anyway, for use when interacting with other sites. Ports for the KDC and admin services ------------------------------------ The default ports used by Kerberos are port 88 for the KDC and port 749 for the admin server. You can, however, choose to run on other ports, as long as they are specified in each host's :ref:`krb5.conf(5)` files or in DNS SRV records, and the :ref:`kdc.conf(5)` file on each KDC. For a more thorough treatment of port numbers used by the Kerberos V5 programs, refer to the :ref:`conf_firewall`. Replica KDCs ------------ Replica KDCs provide an additional source of Kerberos ticket-granting services in the event of inaccessibility of the primary KDC. The number of replica KDCs you need and the decision of where to place them, both physically and logically, depends on the specifics of your network. Kerberos authentication requires that each client be able to contact a KDC. Therefore, you need to anticipate any likely reason a KDC might be unavailable and have a replica KDC to take up the slack. Some considerations include: * Have at least one replica KDC as a backup, for when the primary KDC is down, is being upgraded, or is otherwise unavailable. * If your network is split such that a network outage is likely to cause a network partition (some segment or segments of the network to become cut off or isolated from other segments), have a replica KDC accessible to each segment. * If possible, have at least one replica KDC in a different building from the primary, in case of power outages, fires, or other localized disasters. .. _kdc_hostnames: Hostnames for KDCs ------------------ MIT recommends that your KDCs have a predefined set of CNAME records (DNS hostname aliases), such as ``kerberos`` for the primary KDC and ``kerberos-1``, ``kerberos-2``, ... for the replica KDCs. This way, if you need to swap a machine, you only need to change a DNS entry, rather than having to change hostnames. As of MIT krb5 1.4, clients can locate a realm's KDCs through DNS using SRV records (:rfc:`2782`), assuming the Kerberos realm name is also a DNS domain name. These records indicate the hostname and port number to contact for that service, optionally with weighting and prioritization. The domain name used in the SRV record name is the realm name. Several different Kerberos-related service names are used: _kerberos._udp This is for contacting any KDC by UDP. This entry will be used the most often. Normally you should list port 88 on each of your KDCs. _kerberos._tcp This is for contacting any KDC by TCP. Normally you should use port 88. This entry should be omitted if the KDC does not listen on TCP ports, as was the default prior to release 1.13. _kerberos-master._udp This entry should refer to those KDCs, if any, that will immediately see password changes to the Kerberos database. If a user is logging in and the password appears to be incorrect, the client will retry with the primary KDC before failing with an "incorrect password" error given. If you have only one KDC, or for whatever reason there is no accessible KDC that would get database changes faster than the others, you do not need to define this entry. _kerberos-adm._tcp This should list port 749 on your primary KDC. Support for it is not complete at this time, but it will eventually be used by the :ref:`kadmin(1)` program and related utilities. For now, you will also need the **admin_server** variable in :ref:`krb5.conf(5)`. _kerberos-master._tcp The corresponding TCP port for _kerberos-master._udp, assuming the primary KDC listens on a TCP port. _kpasswd._udp This entry should list port 464 on your primary KDC. It is used when a user changes her password. If this entry is not defined but a _kerberos-adm._tcp entry is defined, the client will use the _kerberos-adm._tcp entry with the port number changed to 464. _kpasswd._tcp The corresponding TCP port for _kpasswd._udp. The DNS SRV specification requires that the hostnames listed be the canonical names, not aliases. So, for example, you might include the following records in your (BIND-style) zone file:: $ORIGIN foobar.com. _kerberos TXT "FOOBAR.COM" kerberos CNAME daisy kerberos-1 CNAME use-the-force-luke kerberos-2 CNAME bunny-rabbit _kerberos._udp SRV 0 0 88 daisy SRV 0 0 88 use-the-force-luke SRV 0 0 88 bunny-rabbit _kerberos-master._udp SRV 0 0 88 daisy _kerberos-adm._tcp SRV 0 0 749 daisy _kpasswd._udp SRV 0 0 464 daisy Clients can also be configured with the explicit location of services using the **kdc**, **master_kdc**, **admin_server**, and **kpasswd_server** variables in the :ref:`realms` section of :ref:`krb5.conf(5)`. Even if some clients will be configured with explicit server locations, providing SRV records will still benefit unconfigured clients, and be useful for other sites. Clients can be configured with the **sitename** realm variable (new in release 1.22). If a site name is set, the client first attempts SRV record lookups with ".*sitename*._sites" inserted after the service and protocol name and before the Kerberos realm. Site-specific records may indicate servers more proximal to the client, allowing for faster access. .. _kdc_discovery: KDC Discovery ------------- As of MIT krb5 1.15, clients can also locate KDCs in DNS through URI records (:rfc:`7553`). Limitations with the SRV record format may result in extra DNS queries in situations where a client must failover to other transport types, or find a primary server. The URI record can convey more information about a realm's KDCs with a single query. The client performs a query for the following URI records: * ``_kerberos.REALM`` for finding KDCs. * ``_kerberos-adm.REALM`` for finding kadmin services. * ``_kpasswd.REALM`` for finding password services. The URI record includes a priority, weight, and a URI string that consists of case-insensitive colon separated fields, in the form ``scheme:[flags]:transport:residual``. * *scheme* defines the registered URI type. It should always be ``krb5srv``. * *flags* contains zero or more flag characters. Currently the only valid flag is ``m``, which indicates that the record is for a primary server. * *transport* defines the transport type of the residual URL or address. Accepted values are ``tcp``, ``udp``, or ``kkdcp`` for the MS-KKDCP type. * *residual* contains the hostname, IP address, or URL to be contacted using the specified transport, with an optional port extension. The MS-KKDCP transport type uses a HTTPS URL, and can include a port and/or path extension. An example of URI records in a zone file:: _kerberos.EXAMPLE.COM URI 10 1 krb5srv:m:tcp:kdc1.example.com URI 20 1 krb5srv:m:udp:kdc2.example.com:89 URI 40 1 krb5srv::udp:10.10.0.23 URI 30 1 krb5srv::kkdcp:https://proxy:89/auth URI lookups are enabled by default, and can be disabled by setting **dns_uri_lookup** in the :ref:`libdefaults` section of :ref:`krb5.conf(5)` to False. When enabled, URI lookups take precedence over SRV lookups, falling back to SRV lookups if no URI records are found. The **sitename** variable in the :ref:`realms` section of :ref:`krb5.conf(5)` applies to URI lookups as well as SRV lookups. .. _db_prop: Database propagation -------------------- The Kerberos database resides on the primary KDC, and must be propagated regularly (usually by a cron job) to the replica KDCs. In deciding how frequently the propagation should happen, you will need to balance the amount of time the propagation takes against the maximum reasonable amount of time a user should have to wait for a password change to take effect. If the propagation time is longer than this maximum reasonable time (e.g., you have a particularly large database, you have a lot of replicas, or you experience frequent network delays), you may wish to cut down on your propagation delay by performing the propagation in parallel. To do this, have the primary KDC propagate the database to one set of replicas, and then have each of these replicas propagate the database to additional replicas. See also :ref:`incr_db_prop` krb5-1.22.1/doc/admin/princ_dns.rst0000664000175000017500000001232415051422640016711 0ustar ghudsonghudsonPrincipal names and DNS ======================= Kerberos clients can do DNS lookups to canonicalize service principal names. This can cause difficulties when setting up Kerberos application servers, especially when the client's name for the service is different from what the service thinks its name is. Service principal names ----------------------- A frequently used kind of principal name is the host-based service principal name. This kind of principal name has two components: a service name and a hostname. For example, ``imap/imap.example.com`` is the principal name of the "imap" service on the host "imap.example.com". Other possible service names for the first component include "host" (remote login services such as ssh), "HTTP", and "nfs" (Network File System). Service administrators often publish well-known hostname aliases that they would prefer users to use instead of the canonical name of the service host. This gives service administrators more flexibility in deploying services. For example, a shell login server might be named "long-vanity-hostname.example.com", but users will naturally prefer to type something like "login.example.com". Hostname aliases also allow for administrators to set up load balancing for some sorts of services based on rotating ``CNAME`` records in DNS. Service principal canonicalization ---------------------------------- In the MIT krb5 client library, canonicalization of host-based service principals is controlled by the **dns_canonicalize_hostname**, **rnds**, and **qualify_shortname** variables in :ref:`libdefaults`. If **dns_canonicalize_hostname** is set to ``true`` (the default value), the client performs forward resolution by looking up the IPv4 and/or IPv6 addresses of the hostname using ``getaddrinfo()``. This process will typically add a domain suffix to the hostname if needed, and follow CNAME records in the DNS. If **rdns** is also set to ``true`` (the default), the client will then perform a reverse lookup of the first returned Internet address using ``getnameinfo()``, finding the name associated with the PTR record. If **dns_canonicalize_hostname** is set to ``false``, the hostname is not canonicalized using DNS. If the hostname has only one component (i.e. it contains no "." characters), the host's primary DNS search domain will be appended, if there is one. The **qualify_shortname** variable can be used to override or disable this suffix. If **dns_canonicalize_hostname** is set to ``fallback`` (added in release 1.18), the hostname is initially treated according to the rules for ``dns_canonicalize_hostname=false``. If a ticket request fails because the service principal is unknown, the hostname will be canonicalized according to the rules for ``dns_canonicalize_hostname=true`` and the request will be retried. In all cases, the hostname is converted to lowercase, and any trailing dot is removed. Reverse DNS mismatches ---------------------- Sometimes, an enterprise will have control over its forward DNS but not its reverse DNS. The reverse DNS is sometimes under the control of the Internet service provider of the enterprise, and the enterprise may not have much influence in setting up reverse DNS records for its address space. If there are difficulties with getting forward and reverse DNS to match, it is best to set ``rdns = false`` on client machines. Overriding application behavior ------------------------------- Applications can choose to use a default hostname component in their service principal name when accepting authentication, which avoids some sorts of hostname mismatches. Because not all relevant applications do this yet, using the :ref:`krb5.conf(5)` setting:: [libdefaults] ignore_acceptor_hostname = true will allow the Kerberos library to override the application's choice of service principal hostname and will allow a server program to accept incoming authentications using any key in its keytab that matches the service name and realm name (if given). This setting defaults to "false" and is available in releases krb5-1.10 and later. Provisioning keytabs -------------------- One service principal entry that should be in the keytab is a principal whose hostname component is the canonical hostname that ``getaddrinfo()`` reports for all known aliases for the host. If the reverse DNS information does not match this canonical hostname, an additional service principal entry should be in the keytab for this different hostname. Specific application advice --------------------------- Secure shell (ssh) ~~~~~~~~~~~~~~~~~~ Setting ``GSSAPIStrictAcceptorCheck = no`` in the configuration file of modern versions of the openssh daemon will allow the daemon to try any key in its keytab when accepting a connection, rather than looking for the keytab entry that matches the host's own idea of its name (typically the name that ``gethostname()`` returns). This requires krb5-1.10 or later. OpenLDAP (ldapsearch, etc.) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ OpenLDAP's SASL implementation performs reverse DNS lookup in order to canonicalize service principal names, even if **rdns** is set to ``false`` in the Kerberos configuration. To disable this behavior, add ``SASL_NOCANON on`` to ``ldap.conf``, or set the ``LDAPSASL_NOCANON`` environment variable. krb5-1.22.1/doc/admin/lockout.rst0000664000175000017500000001324215051422640016412 0ustar ghudsonghudson.. _lockout: Account lockout =============== As of release 1.8, the KDC can be configured to lock out principals after a number of failed authentication attempts within a period of time. Account lockout can make it more difficult to attack a principal's password by brute force, but also makes it easy for an attacker to deny access to a principal. Configuring account lockout --------------------------- Account lockout only works for principals with the **+requires_preauth** flag set. Without this flag, the KDC cannot know whether or not a client successfully decrypted the ticket it issued. It is also important to set the **-allow_svr** flag on a principal to protect its password from an off-line dictionary attack through a TGS request. You can set these flags on a principal with :ref:`kadmin(1)` as follows:: kadmin: modprinc +requires_preauth -allow_svr PRINCNAME Account lockout parameters are configured via :ref:`policy objects `. There may be an existing policy associated with user principals (such as the "default" policy), or you may need to create a new one and associate it with each user principal. The policy parameters related to account lockout are: * :ref:`maxfailure `: the number of failed attempts before the principal is locked out * :ref:`failurecountinterval `: the allowable interval between failed attempts * :ref:`lockoutduration `: the amount of time a principal is locked out for Here is an example of setting these parameters on a new policy and associating it with a principal:: kadmin: addpol -maxfailure 10 -failurecountinterval 180 -lockoutduration 60 lockout_policy kadmin: modprinc -policy lockout_policy PRINCNAME Testing account lockout ----------------------- To test that account lockout is working, try authenticating as the principal (hopefully not one that might be in use) multiple times with the wrong password. For instance, if **maxfailure** is set to 2, you might see:: $ kinit user Password for user@KRBTEST.COM: kinit: Password incorrect while getting initial credentials $ kinit user Password for user@KRBTEST.COM: kinit: Password incorrect while getting initial credentials $ kinit user kinit: Client's credentials have been revoked while getting initial credentials Account lockout principal state ------------------------------- A principal entry keeps three pieces of state related to account lockout: * The time of last successful authentication * The time of last failed authentication * A counter of failed attempts The time of last successful authentication is not actually needed for the account lockout system to function, but may be of administrative interest. These fields can be observed with the **getprinc** kadmin command. For example:: kadmin: getprinc user Principal: user@KRBTEST.COM ... Last successful authentication: [never] Last failed authentication: Mon Dec 03 12:30:33 EST 2012 Failed password attempts: 2 ... A principal which has been locked out can be administratively unlocked with the **-unlock** option to the **modprinc** kadmin command:: kadmin: modprinc -unlock PRINCNAME This command will reset the number of failed attempts to 0. KDC replication and account lockout ----------------------------------- The account lockout state of a principal is not replicated by either traditional :ref:`kprop(8)` or incremental propagation. Because of this, the number of attempts an attacker can make within a time period is multiplied by the number of KDCs. For instance, if the **maxfailure** parameter on a policy is 10 and there are four KDCs in the environment (a primary and three replicas), an attacker could make as many as 40 attempts before the principal is locked out on all four KDCs. An administrative unlock is propagated from the primary to the replica KDCs during the next propagation. Propagation of an administrative unlock will cause the counter of failed attempts on each replica to reset to 1 on the next failure. If a KDC environment uses a replication strategy other than kprop or incremental propagation, such as the LDAP KDB module with multi-master LDAP replication, then account lockout state may be replicated between KDCs and the concerns of this section may not apply. .. _disable_lockout: KDC performance and account lockout ----------------------------------- In order to fully track account lockout state, the KDC must write to the the database on each successful and failed authentication. Writing to the database is generally more expensive than reading from it, so these writes may have a significant impact on KDC performance. As of release 1.9, it is possible to turn off account lockout state tracking in order to improve performance, by setting the **disable_last_success** and **disable_lockout** variables in the database module subsection of :ref:`kdc.conf(5)`. For example:: [dbmodules] DB = { disable_last_success = true disable_lockout = true } Of the two variables, setting **disable_last_success** will usually have the largest positive impact on performance, and will still allow account lockout policies to operate. However, it will make it impossible to observe the last successful authentication time with kadmin. KDC setup and account lockout ----------------------------- To update the account lockout state on principals, the KDC must be able to write to the principal database. For the DB2 module, no special setup is required. For the LDAP module, the KDC DN must be granted write access to the principal objects. If the KDC DN has only read access, account lockout will not function. krb5-1.22.1/doc/admin/install_kdc.rst0000664000175000017500000004655515051422640017236 0ustar ghudsonghudsonInstalling KDCs =============== When setting up Kerberos in a production environment, it is best to have multiple replica KDCs alongside with a primary KDC to ensure the continued availability of the Kerberized services. Each KDC contains a copy of the Kerberos database. The primary KDC contains the writable copy of the realm database, which it replicates to the replica KDCs at regular intervals. All database changes (such as password changes) are made on the primary KDC. Replica KDCs provide Kerberos ticket-granting services, but not database administration, when the primary KDC is unavailable. MIT recommends that you install all of your KDCs to be able to function as either the primary or one of the replicas. This will enable you to easily switch your primary KDC with one of the replicas if necessary (see :ref:`switch_primary_replica`). This installation procedure is based on that recommendation. .. warning:: - The Kerberos system relies on the availability of correct time information. Ensure that the primary and all replica KDCs have properly synchronized clocks. - It is best to install and run KDCs on secured and dedicated hardware with limited access. If your KDC is also a file server, FTP server, Web server, or even just a client machine, someone who obtained root access through a security hole in any of those areas could potentially gain access to the Kerberos database. Install and configure the primary KDC ------------------------------------- Install Kerberos either from the OS-provided packages or from the source (See :ref:`do_build`). .. note:: For the purpose of this document we will use the following names:: kerberos.mit.edu - primary KDC kerberos-1.mit.edu - replica KDC ATHENA.MIT.EDU - realm name .k5.ATHENA.MIT.EDU - stash file admin/admin - admin principal See :ref:`mitK5defaults` for the default names and locations of the relevant to this topic files. Adjust the names and paths to your system environment. Edit KDC configuration files ---------------------------- Modify the configuration files, :ref:`krb5.conf(5)` and :ref:`kdc.conf(5)`, to reflect the correct information (such as domain-realm mappings and Kerberos servers names) for your realm. (See :ref:`mitK5defaults` for the recommended default locations for these files). Most of the tags in the configuration have default values that will work well for most sites. There are some tags in the :ref:`krb5.conf(5)` file whose values must be specified, and this section will explain those. If the locations for these configuration files differs from the default ones, set **KRB5_CONFIG** and **KRB5_KDC_PROFILE** environment variables to point to the krb5.conf and kdc.conf respectively. For example:: export KRB5_CONFIG=/yourdir/krb5.conf export KRB5_KDC_PROFILE=/yourdir/kdc.conf krb5.conf ~~~~~~~~~ If you are not using DNS TXT records (see :ref:`mapping_hostnames`), you must specify the **default_realm** in the :ref:`libdefaults` section. If you are not using DNS URI or SRV records (see :ref:`kdc_hostnames` and :ref:`kdc_discovery`), you must include the **kdc** tag for each *realm* in the :ref:`realms` section. To communicate with the kadmin server in each realm, the **admin_server** tag must be set in the :ref:`realms` section. An example krb5.conf file:: [libdefaults] default_realm = ATHENA.MIT.EDU [realms] ATHENA.MIT.EDU = { kdc = kerberos.mit.edu kdc = kerberos-1.mit.edu admin_server = kerberos.mit.edu } kdc.conf ~~~~~~~~ The kdc.conf file can be used to control the listening ports of the KDC and kadmind, as well as realm-specific defaults, the database type and location, and logging. An example kdc.conf file:: [kdcdefaults] kdc_listen = 88 kdc_tcp_listen = 88 [realms] ATHENA.MIT.EDU = { kadmind_port = 749 max_life = 12h 0m 0s max_renewable_life = 7d 0h 0m 0s master_key_type = aes256-cts supported_enctypes = aes256-cts:normal aes128-cts:normal # If the default location does not suit your setup, # explicitly configure the following values: # database_name = /var/krb5kdc/principal # key_stash_file = /var/krb5kdc/.k5.ATHENA.MIT.EDU # acl_file = /var/krb5kdc/kadm5.acl } [logging] # By default, the KDC and kadmind will log output using # syslog. You can instead send log output to files like this: kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmin.log default = FILE:/var/log/krb5lib.log Replace ``ATHENA.MIT.EDU`` and ``kerberos.mit.edu`` with the name of your Kerberos realm and server respectively. .. note:: You have to have write permission on the target directories (these directories must exist) used by **database_name**, **key_stash_file**, and **acl_file**. .. _create_db: Create the KDC database ----------------------- You will use the :ref:`kdb5_util(8)` command on the primary KDC to create the Kerberos database and the optional :ref:`stash_definition`. .. note:: If you choose not to install a stash file, the KDC will prompt you for the master key each time it starts up. This means that the KDC will not be able to start automatically, such as after a system reboot. :ref:`kdb5_util(8)` will prompt you for the master password for the Kerberos database. This password can be any string. A good password is one you can remember, but that no one else can guess. Examples of bad passwords are words that can be found in a dictionary, any common or popular name, especially a famous person (or cartoon character), your username in any form (e.g., forward, backward, repeated twice, etc.), and any of the sample passwords that appear in this manual. One example of a password which might be good if it did not appear in this manual is "MITiys4K5!", which represents the sentence "MIT is your source for Kerberos 5!" (It's the first letter of each word, substituting the numeral "4" for the word "for", and includes the punctuation mark at the end.) The following is an example of how to create a Kerberos database and stash file on the primary KDC, using the :ref:`kdb5_util(8)` command. Replace ``ATHENA.MIT.EDU`` with the name of your Kerberos realm:: shell% kdb5_util create -r ATHENA.MIT.EDU -s Initializing database '/usr/local/var/krb5kdc/principal' for realm 'ATHENA.MIT.EDU', master key name 'K/M@ATHENA.MIT.EDU' You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter KDC database master key: <= Type the master password. Re-enter KDC database master key to verify: <= Type it again. shell% This will create five files in |kdcdir| (or at the locations specified in :ref:`kdc.conf(5)`): * two Kerberos database files, ``principal``, and ``principal.ok`` * the Kerberos administrative database file, ``principal.kadm5`` * the administrative database lock file, ``principal.kadm5.lock`` * the stash file, in this example ``.k5.ATHENA.MIT.EDU``. If you do not want a stash file, run the above command without the **-s** option. For more information on administrating Kerberos database see :ref:`db_operations`. .. _admin_acl: Add administrators to the ACL file ---------------------------------- Next, you need create an Access Control List (ACL) file and put the Kerberos principal of at least one of the administrators into it. This file is used by the :ref:`kadmind(8)` daemon to control which principals may view and make privileged modifications to the Kerberos database files. The ACL filename is determined by the **acl_file** variable in :ref:`kdc.conf(5)`; the default is |kdcdir|\ ``/kadm5.acl``. For more information on Kerberos ACL file see :ref:`kadm5.acl(5)`. .. _addadmin_kdb: Add administrators to the Kerberos database ------------------------------------------- Next you need to add administrative principals (i.e., principals who are allowed to administer Kerberos database) to the Kerberos database. You *must* add at least one principal now to allow communication between the Kerberos administration daemon kadmind and the kadmin program over the network for further administration. To do this, use the kadmin.local utility on the primary KDC. kadmin.local is designed to be run on the primary KDC host without using Kerberos authentication to an admin server; instead, it must have read and write access to the Kerberos database on the local filesystem. The administrative principals you create should be the ones you added to the ACL file (see :ref:`admin_acl`). In the following example, the administrative principal ``admin/admin`` is created:: shell% kadmin.local kadmin.local: addprinc admin/admin@ATHENA.MIT.EDU No policy specified for "admin/admin@ATHENA.MIT.EDU"; assigning "default". Enter password for principal admin/admin@ATHENA.MIT.EDU: <= Enter a password. Re-enter password for principal admin/admin@ATHENA.MIT.EDU: <= Type it again. Principal "admin/admin@ATHENA.MIT.EDU" created. kadmin.local: .. _start_kdc_daemons: Start the Kerberos daemons on the primary KDC --------------------------------------------- At this point, you are ready to start the Kerberos KDC (:ref:`krb5kdc(8)`) and administrative daemons on the primary KDC. To do so, type:: shell% krb5kdc shell% kadmind Each server daemon will fork and run in the background. .. note:: Assuming you want these daemons to start up automatically at boot time, you can add them to the KDC's ``/etc/rc`` or ``/etc/inittab`` file. You need to have a :ref:`stash_definition` in order to do this. You can verify that they started properly by checking for their startup messages in the logging locations you defined in :ref:`krb5.conf(5)` (see :ref:`logging`). For example:: shell% tail /var/log/krb5kdc.log Dec 02 12:35:47 beeblebrox krb5kdc[3187](info): commencing operation shell% tail /var/log/kadmin.log Dec 02 12:35:52 beeblebrox kadmind[3189](info): starting Any errors the daemons encounter while starting will also be listed in the logging output. As an additional verification, check if :ref:`kinit(1)` succeeds against the principals that you have created on the previous step (:ref:`addadmin_kdb`). Run:: shell% kinit admin/admin@ATHENA.MIT.EDU Install the replica KDCs ------------------------ You are now ready to start configuring the replica KDCs. .. note:: Assuming you are setting the KDCs up so that you can easily switch the primary KDC with one of the replicas, you should perform each of these steps on the primary KDC as well as the replica KDCs, unless these instructions specify otherwise. .. _replica_host_key: Create host keytabs for replica KDCs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each KDC needs a ``host`` key in the Kerberos database. These keys are used for mutual authentication when propagating the database dump file from the primary KDC to the secondary KDC servers. On the primary KDC, connect to administrative interface and create the host principal for each of the KDCs' ``host`` services. For example, if the primary KDC were called ``kerberos.mit.edu``, and you had a replica KDC named ``kerberos-1.mit.edu``, you would type the following:: shell% kadmin kadmin: addprinc -randkey host/kerberos.mit.edu No policy specified for "host/kerberos.mit.edu@ATHENA.MIT.EDU"; assigning "default" Principal "host/kerberos.mit.edu@ATHENA.MIT.EDU" created. kadmin: addprinc -randkey host/kerberos-1.mit.edu No policy specified for "host/kerberos-1.mit.edu@ATHENA.MIT.EDU"; assigning "default" Principal "host/kerberos-1.mit.edu@ATHENA.MIT.EDU" created. It is not strictly necessary to have the primary KDC server in the Kerberos database, but it can be handy if you want to be able to swap the primary KDC with one of the replicas. Next, extract ``host`` random keys for all participating KDCs and store them in each host's default keytab file. Ideally, you should extract each keytab locally on its own KDC. If this is not feasible, you should use an encrypted session to send them across the network. To extract a keytab directly on a replica KDC called ``kerberos-1.mit.edu``, you would execute the following command:: kadmin: ktadd host/kerberos-1.mit.edu Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type arcfour-hmac added to keytab FILE:/etc/krb5.keytab. If you are instead extracting a keytab for the replica KDC called ``kerberos-1.mit.edu`` on the primary KDC, you should use a dedicated temporary keytab file for that machine's keytab:: kadmin: ktadd -k /tmp/kerberos-1.keytab host/kerberos-1.mit.edu Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. The file ``/tmp/kerberos-1.keytab`` can then be installed as ``/etc/krb5.keytab`` on the host ``kerberos-1.mit.edu``. Configure replica KDCs ~~~~~~~~~~~~~~~~~~~~~~ Database propagation copies the contents of the primary's database, but does not propagate configuration files, stash files, or the kadm5 ACL file. The following files must be copied by hand to each replica (see :ref:`mitK5defaults` for the default locations for these files): * krb5.conf * kdc.conf * kadm5.acl * master key stash file Move the copied files into their appropriate directories, exactly as on the primary KDC. kadm5.acl is only needed to allow a replica to swap with the primary KDC. The database is propagated from the primary KDC to the replica KDCs via the :ref:`kpropd(8)` daemon. You must explicitly specify the principals which are allowed to provide Kerberos dump updates on the replica machine with a new database. Create a file named kpropd.acl in the KDC state directory containing the ``host`` principals for each of the KDCs:: host/kerberos.mit.edu@ATHENA.MIT.EDU host/kerberos-1.mit.edu@ATHENA.MIT.EDU .. note:: If you expect that the primary and replica KDCs will be switched at some point of time, list the host principals from all participating KDC servers in kpropd.acl files on all of the KDCs. Otherwise, you only need to list the primary KDC's host principal in the kpropd.acl files of the replica KDCs. Then, add the following line to ``/etc/inetd.conf`` on each KDC (adjust the path to kpropd):: krb5_prop stream tcp nowait root /usr/local/sbin/kpropd kpropd You also need to add the following line to ``/etc/services`` on each KDC, if it is not already present (assuming that the default port is used):: krb5_prop 754/tcp # Kerberos replica propagation Restart inetd daemon. Alternatively, start :ref:`kpropd(8)` as a stand-alone daemon. This is required when incremental propagation is enabled. Now that the replica KDC is able to accept database propagation, you’ll need to propagate the database from the primary server. NOTE: Do not start the replica KDC yet; you still do not have a copy of the primary's database. .. _kprop_to_replicas: Propagate the database to each replica KDC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ First, create a dump file of the database on the primary KDC, as follows:: shell% kdb5_util dump /usr/local/var/krb5kdc/replica_datatrans Then, manually propagate the database to each replica KDC, as in the following example:: shell% kprop -f /usr/local/var/krb5kdc/replica_datatrans kerberos-1.mit.edu Database propagation to kerberos-1.mit.edu: SUCCEEDED You will need a script to dump and propagate the database. The following is an example of a Bourne shell script that will do this. .. note:: Remember that you need to replace ``/usr/local/var/krb5kdc`` with the name of the KDC state directory. :: #!/bin/sh kdclist = "kerberos-1.mit.edu kerberos-2.mit.edu" kdb5_util dump /usr/local/var/krb5kdc/replica_datatrans for kdc in $kdclist do kprop -f /usr/local/var/krb5kdc/replica_datatrans $kdc done You will need to set up a cron job to run this script at the intervals you decided on earlier (see :ref:`db_prop`). Now that the replica KDC has a copy of the Kerberos database, you can start the krb5kdc daemon:: shell% krb5kdc As with the primary KDC, you will probably want to add this command to the KDCs' ``/etc/rc`` or ``/etc/inittab`` files, so they will start the krb5kdc daemon automatically at boot time. Propagation failed? ################### You may encounter the following error messages. For a more detailed discussion on possible causes and solutions click on the error link to be redirected to :ref:`troubleshoot` section. .. include:: ./troubleshoot.rst :start-after: _prop_failed_start: :end-before: _prop_failed_end: Add Kerberos principals to the database --------------------------------------- Once your KDCs are set up and running, you are ready to use :ref:`kadmin(1)` to load principals for your users, hosts, and other services into the Kerberos database. This procedure is described fully in :ref:`principals`. You may occasionally want to use one of your replica KDCs as the primary. This might happen if you are upgrading the primary KDC, or if your primary KDC has a disk crash. See the following section for the instructions. .. _switch_primary_replica: Switching primary and replica KDCs ---------------------------------- You may occasionally want to use one of your replica KDCs as the primary. This might happen if you are upgrading the primary KDC, or if your primary KDC has a disk crash. Assuming you have configured all of your KDCs to be able to function as either the primary KDC or a replica KDC (as this document recommends), all you need to do to make the changeover is: If the primary KDC is still running, do the following on the *old* primary KDC: #. Kill the kadmind process. #. Disable the cron job that propagates the database. #. Run your database propagation script manually, to ensure that the replicas all have the latest copy of the database (see :ref:`kprop_to_replicas`). On the *new* primary KDC: #. Start the :ref:`kadmind(8)` daemon (see :ref:`start_kdc_daemons`). #. Set up the cron job to propagate the database (see :ref:`kprop_to_replicas`). #. Switch the CNAMEs of the old and new primary KDCs. If you can't do this, you'll need to change the :ref:`krb5.conf(5)` file on every client machine in your Kerberos realm. Incremental database propagation -------------------------------- If you expect your Kerberos database to become large, you may wish to set up incremental propagation to replica KDCs. See :ref:`incr_db_prop` for details. krb5-1.22.1/doc/admin/conf_files/0000775000175000017500000000000015051422640016305 5ustar ghudsonghudsonkrb5-1.22.1/doc/admin/conf_files/krb5_conf.rst0000664000175000017500000014250015051422640020711 0ustar ghudsonghudson.. _krb5.conf(5): krb5.conf ========= The krb5.conf file contains Kerberos configuration information, including the locations of KDCs and admin servers for the Kerberos realms of interest, defaults for the current realm and for Kerberos applications, and mappings of hostnames onto Kerberos realms. Normally, you should install your krb5.conf file in the directory ``/etc``. You can override the default location by setting the environment variable **KRB5_CONFIG**. Multiple colon-separated filenames may be specified in **KRB5_CONFIG**; all files which are present will be read. Starting in release 1.14, directory names can also be specified in **KRB5_CONFIG**; all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores will be read. Structure --------- The krb5.conf file is set up in the style of a Windows INI file. Lines beginning with '#' or ';' (possibly after initial whitespace) are ignored as comments. Sections are headed by the section name, in square brackets. Each section may contain zero or more relations, of the form:: foo = bar or:: fubar = { foo = bar baz = quux } The krb5.conf file can include other files using either of the following directives at the beginning of a line:: include FILENAME includedir DIRNAME *FILENAME* or *DIRNAME* should be an absolute path. The named file or directory must exist and be readable. Including a directory includes all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores. Starting in release 1.15, files with names ending in ".conf" are also included, unless the name begins with ".". Included profile files are syntactically independent of their parents, so each included file must begin with a section header. Starting in release 1.17, files are read in alphanumeric order; in previous releases, they may be read in any order. Placing a '\*' after the closing bracket of a section name indicates that the section is *final*, meaning that if the same section appears again later, it will be ignored. A subsection can be marked as final by placing a '\*' after either the tag name or the closing brace. A relation can be marked as final by placing a '\*' after the tag name. Prior to release 1.22, only sections and subsections can be marked as final, and the flag only causes values to be ignored if they appear in later files specified in **KRB5_CONFIG**, not if they appear later within the same file or an included file. The krb5.conf file can specify that configuration should be obtained from a loadable module, rather than the file itself, using the following directive at the beginning of a line before any section headers:: module MODULEPATH:RESIDUAL *MODULEPATH* may be relative to the library path of the krb5 installation, or it may be an absolute path. *RESIDUAL* is provided to the module at initialization time. If krb5.conf uses a module directive, :ref:`kdc.conf(5)` should also use one if it exists. Sections -------- The krb5.conf file may contain the following sections: =================== ======================================================= :ref:`libdefaults` Settings used by the Kerberos V5 library :ref:`realms` Realm-specific contact information and settings :ref:`domain_realm` Maps server hostnames to Kerberos realms :ref:`capaths` Authentication paths for non-hierarchical cross-realm :ref:`appdefaults` Settings used by some Kerberos V5 applications :ref:`plugins` Controls plugin module registration =================== ======================================================= Additionally, krb5.conf may include any of the relations described in :ref:`kdc.conf(5)`, but it is not a recommended practice. .. _libdefaults: [libdefaults] ~~~~~~~~~~~~~ The libdefaults section may contain any of the following relations: **allow_des3** Permit the KDC to issue tickets with des3-cbc-sha1 session keys. In future releases, this flag will allow des3-cbc-sha1 to be used at all. The default value for this tag is false. (Added in release 1.21.) **allow_rc4** Permit the KDC to issue tickets with arcfour-hmac session keys. In future releases, this flag will allow arcfour-hmac to be used at all. The default value for this tag is false. (Added in release 1.21.) **allow_weak_crypto** If this flag is set to false, then weak encryption types (as noted in :ref:`Encryption_types` in :ref:`kdc.conf(5)`) will be filtered out of the lists **default_tgs_enctypes**, **default_tkt_enctypes**, and **permitted_enctypes**. The default value for this tag is false. **canonicalize** If this flag is set to true, initial ticket requests to the KDC will request canonicalization of the client principal name, and answers with different client principals than the requested principal will be accepted. The default value is false. **ccache_type** This parameter determines the format of credential cache types created by :ref:`kinit(1)` or other programs. The default value is 4, which represents the most current format. Smaller values can be used for compatibility with very old implementations of Kerberos which interact with credential caches on the same host. **clockskew** Sets the maximum allowable amount of clockskew in seconds that the library will tolerate before assuming that a Kerberos message is invalid. The default value is 300 seconds, or five minutes. The clockskew setting is also used when evaluating ticket start and expiration times. For example, tickets that have reached their expiration time can still be used (and renewed if they are renewable tickets) if they have been expired for a shorter duration than the **clockskew** setting. **default_ccache_name** This relation specifies the name of the default credential cache. The default is |ccache|. This relation is subject to parameter expansion (see below). New in release 1.11. **default_client_keytab_name** This relation specifies the name of the default keytab for obtaining client credentials. The default is |ckeytab|. This relation is subject to parameter expansion (see below). New in release 1.11. **default_keytab_name** This relation specifies the default keytab name to be used by application servers such as sshd. The default is |keytab|. This relation is subject to parameter expansion (see below). **default_rcache_name** This relation specifies the name of the default replay cache. The default is ``dfl:``. This relation is subject to parameter expansion (see below). New in release 1.18. **default_realm** Identifies the default Kerberos realm for the client. Set its value to your Kerberos realm. If this value is not set, then a realm must be specified with every Kerberos principal when invoking programs such as :ref:`kinit(1)`. **default_tgs_enctypes** Identifies the supported list of session key encryption types that the client should request when making a TGS-REQ, in order of preference from highest to lowest. The list may be delimited with commas or whitespace. See :ref:`Encryption_types` in :ref:`kdc.conf(5)` for a list of the accepted values for this tag. Starting in release 1.18, the default value is the value of **permitted_enctypes**. For previous releases or if **permitted_enctypes** is not set, the default value is |defetypes|. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. **default_tkt_enctypes** Identifies the supported list of session key encryption types that the client should request when making an AS-REQ, in order of preference from highest to lowest. The format is the same as for default_tgs_enctypes. Starting in release 1.18, the default value is the value of **permitted_enctypes**. For previous releases or if **permitted_enctypes** is not set, the default value is |defetypes|. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. **dns_canonicalize_hostname** Indicate whether name lookups will be used to canonicalize hostnames for use in service principal names. Setting this flag to false can improve security by reducing reliance on DNS, but means that short hostnames will not be canonicalized to fully-qualified hostnames. If this option is set to ``fallback`` (new in release 1.18), DNS canonicalization will only be performed the server hostname is not found with the original name when requesting credentials. The default value is true. **dns_lookup_kdc** Indicate whether DNS SRV records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. (Note that the admin_server entry must be in the krb5.conf realm information in order to contact kadmind, because the DNS implementation for kadmin is incomplete.) Enabling this option does open up a type of denial-of-service attack, if someone spoofs the DNS records and redirects you to another server. However, it's no worse than a denial of service, because that fake KDC will be unable to decode anything you send it (besides the initial ticket request, which has no encrypted data), and anything the fake KDC sends will not be trusted without verification using some secret that it won't know. **dns_lookup_realm** Indicate whether DNS TXT records should be used to map hostnames to realm names for hostnames not listed in the [domain_realm] section, and to determine the default realm if **default_realm** is not set. The default value is false. **dns_uri_lookup** Indicate whether DNS URI records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. SRV records are used as a fallback if no URI records were found. The default value is true. New in release 1.15. **enforce_ok_as_delegate** If this flag to true, GSSAPI credential delegation will be disabled when the ``ok-as-delegate`` flag is not set in the service ticket. If this flag is false, the ``ok-as-delegate`` ticket flag is only enforced when an application specifically requests enforcement. The default value is false. **err_fmt** This relation allows for custom error message formatting. If a value is set, error messages will be formatted by substituting a normal error message for %M and an error code for %C in the value. **extra_addresses** This allows a computer to use multiple local addresses, in order to allow Kerberos to work in a network that uses NATs while still using address-restricted tickets. The addresses should be in a comma-separated list. This option has no effect if **noaddresses** is true. **forwardable** If this flag is true, initial tickets will be forwardable by default, if allowed by the KDC. The default value is false. **ignore_acceptor_hostname** When accepting GSSAPI or krb5 security contexts for host-based service principals, ignore any hostname passed by the calling application, and allow clients to authenticate to any service principal in the keytab matching the service name and realm name (if given). This option can improve the administrative flexibility of server applications on multihomed hosts, but could compromise the security of virtual hosting environments. The default value is false. New in release 1.10. **k5login_authoritative** If this flag is true, principals must be listed in a local user's k5login file to be granted login access, if a :ref:`.k5login(5)` file exists. If this flag is false, a principal may still be granted login access through other mechanisms even if a k5login file exists but does not list the principal. The default value is true. **k5login_directory** If set, the library will look for a local user's k5login file within the named directory, with a filename corresponding to the local username. If not set, the library will look for k5login files in the user's home directory, with the filename .k5login. For security reasons, .k5login files must be owned by the local user or by root. **kcm_mach_service** On macOS only, determines the name of the bootstrap service used to contact the KCM daemon for the KCM credential cache type. If the value is ``-``, Mach RPC will not be used to contact the KCM daemon. The default value is ``org.h5l.kcm``. **kcm_socket** Determines the path to the Unix domain socket used to access the KCM daemon for the KCM credential cache type. If the value is ``-``, Unix domain sockets will not be used to contact the KCM daemon. The default value is ``/var/run/.heim_org.h5l.kcm-socket``. **kdc_default_options** Default KDC options (Xored for multiple values) when requesting initial tickets. By default it is set to 0x00000010 (KDC_OPT_RENEWABLE_OK). **kdc_timesync** Accepted values for this relation are 1 or 0. If it is nonzero, client machines will compute the difference between their time and the time returned by the KDC in the timestamps in the tickets and use this value to correct for an inaccurate system clock when requesting service tickets or authenticating to services. This corrective factor is only used by the Kerberos library; it is not used to change the system clock. The default value is 1. **noaddresses** If this flag is true, requests for initial tickets will not be made with address restrictions set, allowing the tickets to be used across NATs. The default value is true. **permitted_enctypes** Identifies the encryption types that servers will permit for session keys and for ticket and authenticator encryption, ordered by preference from highest to lowest. Starting in release 1.18, this tag also acts as the default value for **default_tgs_enctypes** and **default_tkt_enctypes**. The default value for this tag is |defetypes|. **plugin_base_dir** If set, determines the base directory where krb5 plugins are located. The default value is the ``krb5/plugins`` subdirectory of the krb5 library directory. This relation is subject to parameter expansion (see below) in release 1.17 and later. **preferred_preauth_types** This allows you to set the preferred preauthentication types which the client will attempt before others which may be advertised by a KDC. The default value for this setting is "17, 16, 15, 14", which forces libkrb5 to attempt to use PKINIT if it is supported. **proxiable** If this flag is true, initial tickets will be proxiable by default, if allowed by the KDC. The default value is false. **qualify_shortname** If this string is set, it determines the domain suffix for single-component hostnames when DNS canonicalization is not used (either because **dns_canonicalize_hostname** is false or because forward canonicalization failed). The default value is the first search domain of the system's DNS configuration. To disable qualification of shortnames, set this relation to the empty string with ``qualify_shortname = ""``. (New in release 1.18.) **rdns** If this flag is true, reverse name lookup will be used in addition to forward name lookup to canonicalizing hostnames for use in service principal names. If **dns_canonicalize_hostname** is set to false, this flag has no effect. The default value is true. **realm_try_domains** Indicate whether a host's domain components should be used to determine the Kerberos realm of the host. The value of this variable is an integer: -1 means not to search, 0 means to try the host's domain itself, 1 means to also try the domain's immediate parent, and so forth. The library's usual mechanism for locating Kerberos realms is used to determine whether a domain is a valid realm, which may involve consulting DNS if **dns_lookup_kdc** is set. The default is not to search domain components. **renew_lifetime** (:ref:`duration` string.) Sets the default renewable lifetime for initial ticket requests. The default value is 0. **request_timeout** (:ref:`duration` string.) Sets the maximum total time for KDC and password change requests. This timeout does not affect the intervals between requests, so setting a low timeout may result in fewer requests being attempted and/or some servers not being contacted. A value of 0 indicates no specific maximum, in which case requests will time out if no server responds after several tries. The default value is 0. (New in release 1.22.) **spake_preauth_groups** A whitespace or comma-separated list of words which specifies the groups allowed for SPAKE preauthentication. The possible values are: ============ ================================ edwards25519 Edwards25519 curve (:rfc:`7748`) P-256 NIST P-256 curve (:rfc:`5480`) P-384 NIST P-384 curve (:rfc:`5480`) P-521 NIST P-521 curve (:rfc:`5480`) ============ ================================ The default value for the client is ``edwards25519``. The default value for the KDC is empty. New in release 1.17. **ticket_lifetime** (:ref:`duration` string.) Sets the default lifetime for initial ticket requests. The default value is 1 day. **udp_preference_limit** When sending a message to the KDC, the library will try using TCP before UDP if the size of the message is above **udp_preference_limit**. If the message is smaller than **udp_preference_limit**, then UDP will be tried before TCP. Regardless of the size, both protocols will be tried if the first attempt fails. **verify_ap_req_nofail** If this flag is true, then an attempt to verify initial credentials will fail if the client machine does not have a keytab. The default value is false. **client_aware_channel_bindings** If this flag is true, then all application protocol authentication requests will be flagged to indicate that the application supports channel bindings when operating over a secure channel. The default value is false. .. _realms: [realms] ~~~~~~~~ Each tag in the [realms] section of the file is the name of a Kerberos realm. The value of the tag is a subsection with relations that define the properties of that particular realm. For each realm, the following tags may be specified in the realm's subsection: **admin_server** Identifies the host where the administration server is running. Typically, this is the primary Kerberos server. This tag must be given a value in order to communicate with the :ref:`kadmind(8)` server for the realm. **auth_to_local** This tag allows you to set a general rule for mapping principal names to local user names. It will be used if there is not an explicit mapping for the principal name that is being translated. The possible values are: **RULE:**\ *exp* The local name will be formulated from *exp*. The format for *exp* is **[**\ *n*\ **:**\ *string*\ **](**\ *regexp*\ **)s/**\ *pattern*\ **/**\ *replacement*\ **/g**. The integer *n* indicates how many components the target principal should have. If this matches, then a string will be formed from *string*, substituting the realm of the principal for ``$0`` and the *n*'th component of the principal for ``$n`` (e.g., if the principal was ``johndoe/admin`` then ``[2:$2$1foo]`` would result in the string ``adminjohndoefoo``). If this string matches *regexp*, then the ``s//[g]`` substitution command will be run over the string. The optional **g** will cause the substitution to be global over the *string*, instead of replacing only the first match in the *string*. **DEFAULT** The principal name will be used as the local user name. If the principal has more than one component or is not in the default realm, this rule is not applicable and the conversion will fail. For example:: [realms] ATHENA.MIT.EDU = { auth_to_local = RULE:[2:$1](johndoe)s/^.*$/guest/ auth_to_local = RULE:[2:$1;$2](^.*;admin$)s/;admin$// auth_to_local = RULE:[2:$2](^.*;root)s/^.*$/root/ auth_to_local = DEFAULT } would result in any principal without ``root`` or ``admin`` as the second component to be translated with the default rule. A principal with a second component of ``admin`` will become its first component. ``root`` will be used as the local name for any principal with a second component of ``root``. The exception to these two rules are any principals ``johndoe/*``, which will always get the local name ``guest``. **auth_to_local_names** This subsection allows you to set explicit mappings from principal names to local user names. The tag is the mapping name, and the value is the corresponding local user name. **default_domain** This tag specifies the domain used to expand hostnames when translating Kerberos 4 service principals to Kerberos 5 principals (for example, when converting ``rcmd.hostname`` to ``host/hostname.domain``). **disable_encrypted_timestamp** If this flag is true, the client will not perform encrypted timestamp preauthentication if requested by the KDC. Setting this flag can help to prevent dictionary attacks by active attackers, if the realm's KDCs support SPAKE preauthentication or if initial authentication always uses another mechanism or always uses FAST. This flag persists across client referrals during initial authentication. This flag does not prevent the KDC from offering encrypted timestamp. New in release 1.17. **http_anchors** When KDCs and kpasswd servers are accessed through HTTPS proxies, this tag can be used to specify the location of the CA certificate which should be trusted to issue the certificate for a proxy server. If left unspecified, the system-wide default set of CA certificates is used. The syntax for values is similar to that of values for the **pkinit_anchors** tag: **FILE:** *filename* *filename* is assumed to be the name of an OpenSSL-style ca-bundle file. **DIR:** *dirname* *dirname* is assumed to be an directory which contains CA certificates. All files in the directory will be examined; if they contain certificates (in PEM format), they will be used. **ENV:** *envvar* *envvar* specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, ``ENV:X509_PROXY_CA``, where environment variable ``X509_PROXY_CA`` has been set to ``FILE:/tmp/my_proxy.pem``. **kdc** The name or address of a host running a KDC for the realm, or a UNIX domain socket path of a locally running KDC. An optional port number, separated from the hostname by a colon, may be included. If the name or address contains colons (for example, if it is an IPv6 address), enclose it in square brackets to distinguish the colon from a port separator. For your computer to be able to communicate with the KDC for each realm, this tag must be given a value in each realm subsection in the configuration file, or there must be DNS SRV records specifying the KDCs. **kpasswd_server** The location of the password change server for the realm, using the same syntax as **kdc**. If there is no such entry, DNS will be queried (unless forbidden by **dns_lookup_kdc**). Finally, port 464 on the **admin_server** host will be tried. **master_kdc** The name for **primary_kdc** prior to release 1.19. Its value is used as a fallback if **primary_kdc** is not specified. **primary_kdc** Identifies the primary KDC(s). Currently, this tag is used in only one case: If an attempt to get credentials fails because of an invalid password, the client software will attempt to contact the primary KDC, in case the user's password has just been changed, and the updated database has not been propagated to the replica servers yet. New in release 1.19. **sitename** Specifies the name of the host's site for the purpose of DNS-based KDC discovery for this realm. New in release 1.22. **v4_instance_convert** This subsection allows the administrator to configure exceptions to the **default_domain** mapping rule. It contains V4 instances (the tag name) which should be translated to some specific hostname (the tag value) as the second component in a Kerberos V5 principal name. **v4_realm** This relation is used by the krb524 library routines when converting a V5 principal name to a V4 principal name. It is used when the V4 realm name and the V5 realm name are not the same, but still share the same principal names and passwords. The tag value is the Kerberos V4 realm name. .. _domain_realm: [domain_realm] ~~~~~~~~~~~~~~ The [domain_realm] section provides a translation from hostnames to Kerberos realms. Each tag is a domain name, providing the mapping for that domain and all subdomains. If the tag begins with a period (``.``) then it applies only to subdomains. The Kerberos realm may be identified either in the realms_ section or using DNS SRV records. Tag names should be in lower case. For example:: [domain_realm] crash.mit.edu = TEST.ATHENA.MIT.EDU .dev.mit.edu = TEST.ATHENA.MIT.EDU mit.edu = ATHENA.MIT.EDU maps the host with the name ``crash.mit.edu`` into the ``TEST.ATHENA.MIT.EDU`` realm. The second entry maps all hosts under the domain ``dev.mit.edu`` into the ``TEST.ATHENA.MIT.EDU`` realm, but not the host with the name ``dev.mit.edu``. That host is matched by the third entry, which maps the host ``mit.edu`` and all hosts under the domain ``mit.edu`` that do not match a preceding rule into the realm ``ATHENA.MIT.EDU``. If no translation entry applies to a hostname used for a service principal for a service ticket request, the library will try to get a referral to the appropriate realm from the client realm's KDC. If that does not succeed, the host's realm is considered to be the hostname's domain portion converted to uppercase, unless the **realm_try_domains** setting in [libdefaults] causes a different parent domain to be used. .. _capaths: [capaths] ~~~~~~~~~ In order to perform direct (non-hierarchical) cross-realm authentication, configuration is needed to determine the authentication paths between realms. A client will use this section to find the authentication path between its realm and the realm of the server. The server will use this section to verify the authentication path used by the client, by checking the transited field of the received ticket. There is a tag for each participating client realm, and each tag has subtags for each of the server realms. The value of the subtags is an intermediate realm which may participate in the cross-realm authentication. The subtags may be repeated if there is more then one intermediate realm. A value of "." means that the two realms share keys directly, and no intermediate realms should be allowed to participate. Only those entries which will be needed on the client or the server need to be present. A client needs a tag for its local realm with subtags for all the realms of servers it will need to authenticate to. A server needs a tag for each realm of the clients it will serve, with a subtag of the server realm. For example, ``ANL.GOV``, ``PNL.GOV``, and ``NERSC.GOV`` all wish to use the ``ES.NET`` realm as an intermediate realm. ANL has a sub realm of ``TEST.ANL.GOV`` which will authenticate with ``NERSC.GOV`` but not ``PNL.GOV``. The [capaths] section for ``ANL.GOV`` systems would look like this:: [capaths] ANL.GOV = { TEST.ANL.GOV = . PNL.GOV = ES.NET NERSC.GOV = ES.NET ES.NET = . } TEST.ANL.GOV = { ANL.GOV = . } PNL.GOV = { ANL.GOV = ES.NET } NERSC.GOV = { ANL.GOV = ES.NET } ES.NET = { ANL.GOV = . } The [capaths] section of the configuration file used on ``NERSC.GOV`` systems would look like this:: [capaths] NERSC.GOV = { ANL.GOV = ES.NET TEST.ANL.GOV = ES.NET TEST.ANL.GOV = ANL.GOV PNL.GOV = ES.NET ES.NET = . } ANL.GOV = { NERSC.GOV = ES.NET } PNL.GOV = { NERSC.GOV = ES.NET } ES.NET = { NERSC.GOV = . } TEST.ANL.GOV = { NERSC.GOV = ANL.GOV NERSC.GOV = ES.NET } When a subtag is used more than once within a tag, clients will use the order of values to determine the path. The order of values is not important to servers. .. _appdefaults: [appdefaults] ~~~~~~~~~~~~~ Each tag in the [appdefaults] section names a Kerberos V5 application or an option that is used by some Kerberos V5 application[s]. The value of the tag defines the default behaviors for that application. For example:: [appdefaults] telnet = { ATHENA.MIT.EDU = { option1 = false } } telnet = { option1 = true option2 = true } ATHENA.MIT.EDU = { option2 = false } option2 = true The above four ways of specifying the value of an option are shown in order of decreasing precedence. In this example, if telnet is running in the realm EXAMPLE.COM, it should, by default, have option1 and option2 set to true. However, a telnet program in the realm ``ATHENA.MIT.EDU`` should have ``option1`` set to false and ``option2`` set to true. Any other programs in ATHENA.MIT.EDU should have ``option2`` set to false by default. Any programs running in other realms should have ``option2`` set to true. The list of specifiable options for each application may be found in that application's man pages. The application defaults specified here are overridden by those specified in the realms_ section. .. _plugins: [plugins] ~~~~~~~~~ * pwqual_ interface * kadm5_hook_ interface * clpreauth_ and kdcpreauth_ interfaces Tags in the [plugins] section can be used to register dynamic plugin modules and to turn modules on and off. Not every krb5 pluggable interface uses the [plugins] section; the ones that do are documented here. New in release 1.9. Each pluggable interface corresponds to a subsection of [plugins]. All subsections support the same tags: **disable** This tag may have multiple values. If there are values for this tag, then the named modules will be disabled for the pluggable interface. **enable_only** This tag may have multiple values. If there are values for this tag, then only the named modules will be enabled for the pluggable interface. **module** This tag may have multiple values. Each value is a string of the form ``modulename:pathname``, which causes the shared object located at *pathname* to be registered as a dynamic module named *modulename* for the pluggable interface. If *pathname* is not an absolute path, it will be treated as relative to the **plugin_base_dir** value from :ref:`libdefaults`. For pluggable interfaces where module order matters, modules registered with a **module** tag normally come first, in the order they are registered, followed by built-in modules in the order they are documented below. If **enable_only** tags are used, then the order of those tags overrides the normal module order. The following subsections are currently supported within the [plugins] section: .. _ccselect: ccselect interface ################## The ccselect subsection controls modules for credential cache selection within a cache collection. In addition to any registered dynamic modules, the following built-in modules exist (and may be disabled with the disable tag): **k5identity** Uses a .k5identity file in the user's home directory to select a client principal **realm** Uses the service realm to guess an appropriate cache from the collection **hostname** If the service principal is host-based, uses the service hostname to guess an appropriate cache from the collection .. _pwqual: pwqual interface ################ The pwqual subsection controls modules for the password quality interface, which is used to reject weak passwords when passwords are changed. The following built-in modules exist for this interface: **dict** Checks against the realm dictionary file **empty** Rejects empty passwords **hesiod** Checks against user information stored in Hesiod (only if Kerberos was built with Hesiod support) **princ** Checks against components of the principal name .. _kadm5_hook: kadm5_hook interface #################### The kadm5_hook interface provides plugins with information on principal creation, modification, password changes and deletion. This interface can be used to write a plugin to synchronize MIT Kerberos with another database such as Active Directory. No plugins are built in for this interface. .. _kadm5_auth: kadm5_auth interface #################### The kadm5_auth section (introduced in release 1.16) controls modules for the kadmin authorization interface, which determines whether a client principal is allowed to perform a kadmin operation. The following built-in modules exist for this interface: **acl** This module reads the :ref:`kadm5.acl(5)` file, and authorizes operations which are allowed according to the rules in the file. **self** This module authorizes self-service operations including password changes, creation of new random keys, fetching the client's principal record or string attributes, and fetching the policy record associated with the client principal. .. _clpreauth: .. _kdcpreauth: clpreauth and kdcpreauth interfaces ################################### The clpreauth and kdcpreauth interfaces allow plugin modules to provide client and KDC preauthentication mechanisms. The following built-in modules exist for these interfaces: **pkinit** This module implements the PKINIT preauthentication mechanism. **encrypted_challenge** This module implements the encrypted challenge FAST factor. **encrypted_timestamp** This module implements the encrypted timestamp mechanism. .. _hostrealm: hostrealm interface ################### The hostrealm section (introduced in release 1.12) controls modules for the host-to-realm interface, which affects the local mapping of hostnames to realm names and the choice of default realm. The following built-in modules exist for this interface: **profile** This module consults the [domain_realm] section of the profile for authoritative host-to-realm mappings, and the **default_realm** variable for the default realm. **dns** This module looks for DNS records for fallback host-to-realm mappings and the default realm. It only operates if the **dns_lookup_realm** variable is set to true. **domain** This module applies heuristics for fallback host-to-realm mappings. It implements the **realm_try_domains** variable, and uses the uppercased parent domain of the hostname if that does not produce a result. .. _localauth: localauth interface ################### The localauth section (introduced in release 1.12) controls modules for the local authorization interface, which affects the relationship between Kerberos principals and local system accounts. The following built-in modules exist for this interface: **default** This module implements the **DEFAULT** type for **auth_to_local** values. **rule** This module implements the **RULE** type for **auth_to_local** values. **names** This module looks for an **auth_to_local_names** mapping for the principal name. **auth_to_local** This module processes **auth_to_local** values in the default realm's section, and applies the default method if no **auth_to_local** values exist. **k5login** This module authorizes a principal to a local account according to the account's :ref:`.k5login(5)` file. **an2ln** This module authorizes a principal to a local account if the principal name maps to the local account name. .. _certauth: certauth interface ################## The certauth section (introduced in release 1.16) controls modules for the certificate authorization interface, which determines whether a certificate is allowed to preauthenticate a user via PKINIT. The following built-in modules exist for this interface: **pkinit_san** This module authorizes the certificate if it contains a PKINIT Subject Alternative Name for the requested client principal, or a Microsoft UPN SAN matching the principal if **pkinit_allow_upn** is set to true for the realm. **pkinit_eku** This module rejects the certificate if it does not contain an Extended Key Usage attribute consistent with the **pkinit_eku_checking** value for the realm. **dbmatch** This module authorizes or rejects the certificate according to whether it matches the **pkinit_cert_match** string attribute on the client principal, if that attribute is present. PKINIT options -------------- .. note:: The following are PKINIT-specific options. These values may be specified in [libdefaults] as global defaults, or within a realm-specific subsection of [libdefaults], or may be specified as realm-specific values in the [realms] section. A realm-specific value overrides, not adds to, a generic [libdefaults] specification. The search order is: 1. realm-specific subsection of [libdefaults]:: [libdefaults] EXAMPLE.COM = { pkinit_anchors = FILE:/usr/local/example.com.crt } 2. realm-specific value in the [realms] section:: [realms] OTHERREALM.ORG = { pkinit_anchors = FILE:/usr/local/otherrealm.org.crt } 3. generic value in the [libdefaults] section:: [libdefaults] pkinit_anchors = DIR:/usr/local/generic_trusted_cas/ .. _pkinit_identity: Specifying PKINIT identity information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The syntax for specifying Public Key identity, trust, and revocation information for PKINIT is as follows: **FILE:**\ *filename*\ [**,**\ *keyfilename*] This option has context-specific behavior. In **pkinit_identity** or **pkinit_identities**, *filename* specifies the name of a PEM-format file containing the user's certificate. If *keyfilename* is not specified, the user's private key is expected to be in *filename* as well. Otherwise, *keyfilename* is the name of the file containing the private key. In **pkinit_anchors** or **pkinit_pool**, *filename* is assumed to be the name of an OpenSSL-style ca-bundle file. **DIR:**\ *dirname* This option has context-specific behavior. In **pkinit_identity** or **pkinit_identities**, *dirname* specifies a directory with files named ``*.crt`` and ``*.key`` where the first part of the file name is the same for matching pairs of certificate and private key files. When a file with a name ending with ``.crt`` is found, a matching file ending with ``.key`` is assumed to contain the private key. If no such file is found, then the certificate in the ``.crt`` is not used. In **pkinit_anchors** or **pkinit_pool**, *dirname* is assumed to be an OpenSSL-style hashed CA directory where each CA cert is stored in a file named ``hash-of-ca-cert.#``. This infrastructure is encouraged, but all files in the directory will be examined and if they contain certificates (in PEM format), they will be used. In **pkinit_revoke**, *dirname* is assumed to be an OpenSSL-style hashed CA directory where each revocation list is stored in a file named ``hash-of-ca-cert.r#``. This infrastructure is encouraged, but all files in the directory will be examined and if they contain a revocation list (in PEM format), they will be used. **PKCS12:**\ *filename* *filename* is the name of a PKCS #12 format file, containing the user's certificate and private key. **PKCS11:**\ [**module_name=**]\ *modname*\ [**:slotid=**\ *slot-id*][**:token=**\ *token-label*][**:certid=**\ *cert-id*][**:certlabel=**\ *cert-label*] All keyword/values are optional. *modname* specifies the location of a library implementing PKCS #11. If a value is encountered with no keyword, it is assumed to be the *modname*. If no module-name is specified, the default is |pkcs11_modname|. ``slotid=`` and/or ``token=`` may be specified to force the use of a particular smard card reader or token if there is more than one available. ``certid=`` and/or ``certlabel=`` may be specified to force the selection of a particular certificate on the device. Specifier values must not contain colon characters, as colons are always treated as separators. See the **pkinit_cert_match** configuration option for more ways to select a particular certificate to use for PKINIT. **ENV:**\ *envvar* *envvar* specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, ``ENV:X509_PROXY``, where environment variable ``X509_PROXY`` has been set to ``FILE:/tmp/my_proxy.pem``. PKINIT krb5.conf options ~~~~~~~~~~~~~~~~~~~~~~~~ **pkinit_anchors** Specifies the location of trusted anchor (root) certificates which the client trusts to sign KDC certificates. This option may be specified multiple times. These values from the config file are not used if the user specifies X509_anchors on the command line. **pkinit_cert_match** Specifies matching rules that the client certificate must match before it is used to attempt PKINIT authentication. If a user has multiple certificates available (on a smart card, or via other media), there must be exactly one certificate chosen before attempting PKINIT authentication. This option may be specified multiple times. All the available certificates are checked against each rule in order until there is a match of exactly one certificate. The Subject and Issuer comparison strings are the :rfc:`2253` string representations from the certificate Subject DN and Issuer DN values. The syntax of the matching rules is: [*relation-operator*\ ]\ *component-rule* ... where: *relation-operator* can be either ``&&``, meaning all component rules must match, or ``||``, meaning only one component rule must match. The default is ``&&``. *component-rule* can be one of the following. Note that there is no punctuation or whitespace between component rules. | ****\ *regular-expression* | ****\ *regular-expression* | ****\ *regular-expression* | ****\ *extended-key-usage-list* | ****\ *key-usage-list* *extended-key-usage-list* is a comma-separated list of required Extended Key Usage values. All values in the list must be present in the certificate. Extended Key Usage values can be: * pkinit * msScLogin * clientAuth * emailProtection *key-usage-list* is a comma-separated list of required Key Usage values. All values in the list must be present in the certificate. Key Usage values can be: * digitalSignature * keyEncipherment Examples:: pkinit_cert_match = ||.*DoE.*.*@EXAMPLE.COM pkinit_cert_match = &&msScLogin,clientAuth.*DoE.* pkinit_cert_match = msScLogin,clientAuthdigitalSignature **pkinit_eku_checking** This option specifies what Extended Key Usage value the KDC certificate presented to the client must contain. (Note that if the KDC certificate has the pkinit SubjectAlternativeName encoded as the Kerberos TGS name, EKU checking is not necessary since the issuing CA has certified this as a KDC certificate.) The values recognized in the krb5.conf file are: **kpKDC** This is the default value and specifies that the KDC must have the id-pkinit-KPKdc EKU as defined in :rfc:`4556`. **kpServerAuth** If **kpServerAuth** is specified, a KDC certificate with the id-kp-serverAuth EKU will be accepted. This key usage value is used in most commercially issued server certificates. **none** If **none** is specified, then the KDC certificate will not be checked to verify it has an acceptable EKU. The use of this option is not recommended. **pkinit_dh_min_bits** Specifies the group of the Diffie-Hellman key the client will attempt to use. The acceptable values are 1024, 2048, P-256, 4096, P-384, and P-521. The default is 2048. (P-256, P-384, and P-521 are new in release 1.22.) **pkinit_identities** Specifies the location(s) to be used to find the user's X.509 identity information. If this option is specified multiple times, each value is attempted in order until certificates are found. Note that these values are not used if the user specifies **X509_user_identity** on the command line. **pkinit_kdc_hostname** The presence of this option indicates that the client is willing to accept a KDC certificate with a dNSName SAN (Subject Alternative Name) rather than requiring the id-pkinit-san as defined in :rfc:`4556`. This option may be specified multiple times. Its value should contain the acceptable hostname for the KDC (as contained in its certificate). **pkinit_pool** Specifies the location of intermediate certificates which may be used by the client to complete the trust chain between a KDC certificate and a trusted anchor. This option may be specified multiple times. **pkinit_require_crl_checking** The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and **pkinit_require_crl_checking** is false, then verification succeeds. However, if **pkinit_require_crl_checking** is true and there is no CRL information available for the issuing CA, then verification fails. **pkinit_require_crl_checking** should be set to true if the policy is such that up-to-date CRLs must be present for every CA. **pkinit_revoke** Specifies the location of Certificate Revocation List (CRL) information to be used by the client when verifying the validity of the KDC certificate presented. This option may be specified multiple times. .. _parameter_expansion: Parameter expansion ------------------- Starting with release 1.11, several variables, such as **default_keytab_name**, allow parameters to be expanded. Valid parameters are: ================= =================================================== %{TEMP} Temporary directory %{uid} Unix real UID or Windows SID %{euid} Unix effective user ID or Windows SID %{USERID} Same as %{uid} %{null} Empty string %{LIBDIR} Installation library directory %{BINDIR} Installation binary directory %{SBINDIR} Installation admin binary directory %{username} (Unix) Username of effective user ID %{APPDATA} (Windows) Roaming application data for current user %{COMMON_APPDATA} (Windows) Application data for all users %{LOCAL_APPDATA} (Windows) Local application data for current user %{SYSTEM} (Windows) Windows system folder %{WINDOWS} (Windows) Windows folder %{USERCONFIG} (Windows) Per-user MIT krb5 config file directory %{COMMONCONFIG} (Windows) Common MIT krb5 config file directory ================= =================================================== Sample krb5.conf file --------------------- Here is an example of a generic krb5.conf file:: [libdefaults] default_realm = ATHENA.MIT.EDU dns_lookup_kdc = true dns_lookup_realm = false [realms] ATHENA.MIT.EDU = { kdc = kerberos.mit.edu kdc = kerberos-1.mit.edu kdc = kerberos-2.mit.edu admin_server = kerberos.mit.edu primary_kdc = kerberos.mit.edu } EXAMPLE.COM = { kdc = kerberos.example.com kdc = kerberos-1.example.com admin_server = kerberos.example.com } [domain_realm] mit.edu = ATHENA.MIT.EDU [capaths] ATHENA.MIT.EDU = { EXAMPLE.COM = . } EXAMPLE.COM = { ATHENA.MIT.EDU = . } FILES ----- |krb5conf| SEE ALSO -------- syslog(3) krb5-1.22.1/doc/admin/conf_files/kadm5_acl.rst0000664000175000017500000001437715051422640020673 0ustar ghudsonghudson.. _kadm5.acl(5): kadm5.acl ========= DESCRIPTION ----------- The Kerberos :ref:`kadmind(8)` daemon uses an Access Control List (ACL) file to manage access rights to the Kerberos database. For operations that affect principals, the ACL file also controls which principals can operate on which other principals. The default location of the Kerberos ACL file is |kdcdir|\ ``/kadm5.acl`` unless this is overridden by the *acl_file* variable in :ref:`kdc.conf(5)`. SYNTAX ------ Empty lines and lines starting with the sharp sign (``#``) are ignored. Lines containing ACL entries have the format:: principal permissions [target_principal [restrictions] ] .. note:: Line order in the ACL file is important. The first matching entry will control access for an actor principal on a target principal. *principal* (Partially or fully qualified Kerberos principal name.) Specifies the principal whose permissions are to be set. Each component of the name may be wildcarded using the ``*`` character. *permissions* Specifies what operations may or may not be performed by a *principal* matching a particular entry. This is a string of one or more of the following list of characters or their upper-case counterparts. If the character is *upper-case*, then the operation is disallowed. If the character is *lower-case*, then the operation is permitted. == ====================================================== a [Dis]allows the addition of principals or policies c [Dis]allows the changing of passwords for principals d [Dis]allows the deletion of principals or policies e [Dis]allows the extraction of principal keys i [Dis]allows inquiries about principals or policies l [Dis]allows the listing of all principals or policies m [Dis]allows the modification of principals or policies p [Dis]allows the propagation of the principal database (used in :ref:`incr_db_prop`) s [Dis]allows the explicit setting of the key for a principal x Short for admcilsp. All privileges (except ``e``) \* Same as x. == ====================================================== .. note:: The ``extract`` privilege is not included in the wildcard privilege; it must be explicitly assigned. This privilege allows the user to extract keys from the database, and must be handled with great care to avoid disclosure of important keys like those of the kadmin/* or krbtgt/* principals. The **lockdown_keys** principal attribute can be used to prevent key extraction from specific principals regardless of the granted privilege. *target_principal* (Optional. Partially or fully qualified Kerberos principal name.) Specifies the principal on which *permissions* may be applied. Each component of the name may be wildcarded using the ``*`` character. *target_principal* can also include back-references to *principal*, in which ``*number`` matches the corresponding wildcard in *principal*. *restrictions* (Optional) A string of flags. Allowed restrictions are: {+\|-}\ *flagname* flag is forced to the indicated value. The permissible flags are the same as those for the **default_principal_flags** variable in :ref:`kdc.conf(5)`. *-clearpolicy* policy is forced to be empty. *-policy pol* policy is forced to be *pol*. -{*expire, pwexpire, maxlife, maxrenewlife*} *time* (:ref:`getdate` string) associated value will be forced to MIN(*time*, requested value). The above flags act as restrictions on any add or modify operation which is allowed due to that ACL line. .. warning:: If the kadmind ACL file is modified, the kadmind daemon needs to be restarted for changes to take effect. EXAMPLE ------- Here is an example of a kadm5.acl file:: */admin@ATHENA.MIT.EDU * # line 1 joeadmin@ATHENA.MIT.EDU ADMCIL # line 2 joeadmin/*@ATHENA.MIT.EDU i */root@ATHENA.MIT.EDU # line 3 */root@ATHENA.MIT.EDU ci *1@ATHENA.MIT.EDU # line 4 */root@ATHENA.MIT.EDU l * # line 5 sms@ATHENA.MIT.EDU x * -maxlife 9h -postdateable # line 6 (line 1) Any principal in the ``ATHENA.MIT.EDU`` realm with an ``admin`` instance has all administrative privileges except extracting keys. (lines 1-3) The user ``joeadmin`` has all permissions except extracting keys with his ``admin`` instance, ``joeadmin/admin@ATHENA.MIT.EDU`` (matches line 1). He has no permissions at all with his null instance, ``joeadmin@ATHENA.MIT.EDU`` (matches line 2). His ``root`` and other non-``admin``, non-null instances (e.g., ``extra`` or ``dbadmin``) have inquire permissions with any principal that has the instance ``root`` (matches line 3). (line 4) Any ``root`` principal in ``ATHENA.MIT.EDU`` can inquire or change the password of their null instance, but not any other null instance. (Here, ``*1`` denotes a back-reference to the component matching the first wildcard in the actor principal.) (line 5) Any ``root`` principal in ``ATHENA.MIT.EDU`` can generate the list of principals in the database, and the list of policies in the database. This line is separate from line 4, because list permission can only be granted globally, not to specific target principals. (line 6) Finally, the Service Management System principal ``sms@ATHENA.MIT.EDU`` has all permissions except extracting keys, but any principal that it creates or modifies will not be able to get postdateable tickets or tickets with a life of longer than 9 hours. MODULE BEHAVIOR --------------- The ACL file can coexist with other authorization modules in release 1.16 and later, as configured in the :ref:`kadm5_auth` section of :ref:`krb5.conf(5)`. The ACL file will positively authorize operations according to the rules above, but will never authoritatively deny an operation, so other modules can authorize operations in addition to those authorized by the ACL file. To operate without an ACL file, set the *acl_file* variable in :ref:`kdc.conf(5)` to the empty string with ``acl_file = ""``. SEE ALSO -------- :ref:`kdc.conf(5)`, :ref:`kadmind(8)` krb5-1.22.1/doc/admin/conf_files/kdc_conf.rst0000664000175000017500000011611615051422640020613 0ustar ghudsonghudson.. _kdc.conf(5): kdc.conf ======== The kdc.conf file supplements :ref:`krb5.conf(5)` for programs which are typically only used on a KDC, such as the :ref:`krb5kdc(8)` and :ref:`kadmind(8)` daemons and the :ref:`kdb5_util(8)` program. Relations documented here may also be specified in krb5.conf; for the KDC programs mentioned, krb5.conf and kdc.conf will be merged into a single configuration profile. Normally, the kdc.conf file is found in the KDC state directory, |kdcdir|. You can override the default location by setting the environment variable **KRB5_KDC_PROFILE**. Please note that you need to restart the KDC daemon for any configuration changes to take effect. Structure --------- The kdc.conf file is set up in the same format as the :ref:`krb5.conf(5)` file. Sections -------- The kdc.conf file may contain the following sections: ==================== ================================================= :ref:`kdcdefaults` Default values for KDC behavior :ref:`kdc_realms` Realm-specific database configuration and settings :ref:`dbdefaults` Default database settings :ref:`dbmodules` Per-database settings :ref:`logging` Controls how Kerberos daemons perform logging ==================== ================================================= .. _kdcdefaults: [kdcdefaults] ~~~~~~~~~~~~~ Some relations in the [kdcdefaults] section specify default values for realm variables, to be used if the [realms] subsection does not contain a relation for the tag. See the :ref:`kdc_realms` section for the definitions of these relations. * **host_based_services** * **kdc_listen** * **kdc_ports** * **kdc_tcp_listen** * **kdc_tcp_ports** * **no_host_referral** * **restrict_anonymous_to_tgt** The following [kdcdefaults] variables have no per-realm equivalent: **kdc_max_dgram_reply_size** Specifies the maximum packet size that can be sent over UDP. The default value is 4096 bytes. **kdc_tcp_listen_backlog** (Integer.) Set the size of the listen queue length for the KDC daemon. The value may be limited by OS settings. The default value is 5. **spake_preauth_kdc_challenge** (String.) Specifies the group for a SPAKE optimistic challenge. See the **spake_preauth_groups** variable in :ref:`libdefaults` for possible values. The default is not to issue an optimistic challenge. (New in release 1.17.) .. _kdc_realms: [realms] ~~~~~~~~ Each tag in the [realms] section is the name of a Kerberos realm. The value of the tag is a subsection where the relations define KDC parameters for that particular realm. The following example shows how to define one parameter for the ATHENA.MIT.EDU realm:: [realms] ATHENA.MIT.EDU = { max_renewable_life = 7d 0h 0m 0s } The following tags may be specified in a [realms] subsection: **acl_file** (String.) Location of the access control list file that :ref:`kadmind(8)` uses to determine which principals are allowed which permissions on the Kerberos database. To operate without an ACL file, set this relation to the empty string with ``acl_file = ""``. The default value is |kdcdir|\ ``/kadm5.acl``. For more information on Kerberos ACL file see :ref:`kadm5.acl(5)`. **database_module** (String.) This relation indicates the name of the configuration section under :ref:`dbmodules` for database-specific parameters used by the loadable database library. The default value is the realm name. If this configuration section does not exist, default values will be used for all database parameters. **database_name** (String, deprecated.) This relation specifies the location of the Kerberos database for this realm, if the DB2 module is being used and the :ref:`dbmodules` configuration section does not specify a database name. The default value is |kdcdir|\ ``/principal``. **default_principal_expiration** (:ref:`abstime` string.) Specifies the default expiration date of principals created in this realm. The default value is 0, which means no expiration date. **default_principal_flags** (Flag string.) Specifies the default attributes of principals created in this realm. The format for this string is a comma-separated list of flags, with '+' before each flag that should be enabled and '-' before each flag that should be disabled. The **postdateable**, **forwardable**, **tgt-based**, **renewable**, **proxiable**, **dup-skey**, **allow-tickets**, and **service** flags default to enabled. There are a number of possible flags: **allow-tickets** Enabling this flag means that the KDC will issue tickets for this principal. Disabling this flag essentially deactivates the principal within this realm. **dup-skey** Enabling this flag allows the KDC to issue user-to-user service tickets for this principal. **forwardable** Enabling this flag allows the principal to obtain forwardable tickets. **hwauth** If this flag is enabled, then the principal is required to preauthenticate using a hardware device before receiving any tickets. **no-auth-data-required** Enabling this flag prevents PAC or AD-SIGNEDPATH data from being added to service tickets for the principal. **ok-as-delegate** If this flag is enabled, it hints the client that credentials can and should be delegated when authenticating to the service. **ok-to-auth-as-delegate** Enabling this flag allows the principal to use S4USelf tickets. **postdateable** Enabling this flag allows the principal to obtain postdateable tickets. **preauth** If this flag is enabled on a client principal, then that principal is required to preauthenticate to the KDC before receiving any tickets. On a service principal, enabling this flag means that service tickets for this principal will only be issued to clients with a TGT that has the preauthenticated bit set. **proxiable** Enabling this flag allows the principal to obtain proxy tickets. **pwchange** Enabling this flag forces a password change for this principal. **pwservice** If this flag is enabled, it marks this principal as a password change service. This should only be used in special cases, for example, if a user's password has expired, then the user has to get tickets for that principal without going through the normal password authentication in order to be able to change the password. **renewable** Enabling this flag allows the principal to obtain renewable tickets. **service** Enabling this flag allows the the KDC to issue service tickets for this principal. In release 1.17 and later, user-to-user service tickets are still allowed if the **dup-skey** flag is set. **tgt-based** Enabling this flag allows a principal to obtain tickets based on a ticket-granting-ticket, rather than repeating the authentication process that was used to obtain the TGT. **dict_file** (String.) Location of the dictionary file containing strings that are not allowed as passwords. The file should contain one string per line, with no additional whitespace. If none is specified or if there is no policy assigned to the principal, no dictionary checks of passwords will be performed. **disable_pac** (Boolean value.) If true, the KDC will not issue PACs for this realm, and S4U2Self and S4U2Proxy operations will be disabled. The default is false, which will permit the KDC to issue PACs. New in release 1.20. **encrypted_challenge_indicator** (String.) Specifies the authentication indicator value that the KDC asserts into tickets obtained using FAST encrypted challenge pre-authentication. New in 1.16. **host_based_services** (Whitespace- or comma-separated list.) Lists services which will get host-based referral processing even if the server principal is not marked as host-based by the client. **iprop_enable** (Boolean value.) Specifies whether incremental database propagation is enabled. The default value is false. **iprop_ulogsize** (Integer.) Specifies the maximum number of log entries to be retained for incremental propagation. The default value is 1000. Prior to release 1.11, the maximum value was 2500. New in release 1.19. **iprop_master_ulogsize** The name for **iprop_ulogsize** prior to release 1.19. Its value is used as a fallback if **iprop_ulogsize** is not specified. **iprop_replica_poll** (Delta time string.) Specifies how often the replica KDC polls for new updates from the primary. The default value is ``2m`` (that is, two minutes). New in release 1.17. **iprop_slave_poll** (Delta time string.) The name for **iprop_replica_poll** prior to release 1.17. Its value is used as a fallback if **iprop_replica_poll** is not specified. **iprop_listen** (Whitespace- or comma-separated list.) Specifies the iprop RPC listening addresses and/or ports for the :ref:`kadmind(8)` daemon. Each entry may be an interface address, a port number, or an address and port number separated by a colon. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default (when **iprop_enable** is true) is to bind to the wildcard address at the port specified in **iprop_port**. New in release 1.15. **iprop_port** (Port number.) Specifies the port number to be used for incremental propagation. When **iprop_enable** is true, this relation is required in the replica KDC configuration file, and this relation or **iprop_listen** is required in the primary configuration file, as there is no default port number. Port numbers specified in **iprop_listen** entries will override this port number for the :ref:`kadmind(8)` daemon. **iprop_resync_timeout** (Delta time string.) Specifies the amount of time to wait for a full propagation to complete. This is optional in configuration files, and is used by replica KDCs only. The default value is 5 minutes (``5m``). New in release 1.11. **iprop_logfile** (File name.) Specifies where the update log file for the realm database is to be stored. The default is to use the **database_name** entry from the realms section of the krb5 config file, with ``.ulog`` appended. (NOTE: If **database_name** isn't specified in the realms section, perhaps because the LDAP database back end is being used, or the file name is specified in the [dbmodules] section, then the hard-coded default for **database_name** is used. Determination of the **iprop_logfile** default value will not use values from the [dbmodules] section.) **kadmind_listen** (Whitespace- or comma-separated list.) Specifies the kadmin RPC listening addresses and/or ports for the :ref:`kadmind(8)` daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. To disable listening for kadmin RPC connections, set this relation to the empty string with ``kadmind_listen = ""``. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in **kadmind_port**, or the standard kadmin port (749). New in release 1.15. **kadmind_port** (Port number.) Specifies the port on which the :ref:`kadmind(8)` daemon is to listen for this realm. Port numbers specified in **kadmind_listen** entries will override this port number. The assigned port for kadmind is 749, which is used by default. **key_stash_file** (String.) Specifies the location where the master key has been stored (via kdb5_util stash). The default is |kdcdir|\ ``/.k5.REALM``, where *REALM* is the Kerberos realm. **kdc_listen** (Whitespace- or comma-separated list.) Specifies the listening addresses and/or ports for the :ref:`krb5kdc(8)` daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If no port is specified, the standard port (88) is used. To disable listening on UDP, set this relation to the empty string with ``kdc_listen = ""``. If the KDC daemon fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address on the standard port. New in release 1.15. **kdc_ports** (Whitespace- or comma-separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the :ref:`krb5kdc(8)` daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as **kdc_listen** if that relation is not defined. **kdc_tcp_listen** (Whitespace- or comma-separated list.) Specifies the TCP listening addresses and/or ports for the :ref:`krb5kdc(8)` daemon. The syntax is identical to that of **kdc_listen**. To disable listening on TCP, set this relation to the empty string with ``kdc_tcp_listen = ""``. The default is to bind to the same addresses and ports as for UDP. New in release 1.15. **kdc_tcp_ports** (Whitespace- or comma-separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the :ref:`krb5kdc(8)` daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as **kdc_tcp_listen** if that relation is not defined. **kpasswd_listen** (Comma-separated list.) Specifies the kpasswd listening addresses and/or ports for the :ref:`kadmind(8)` daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. To disable listening for kpasswd requests, set this relation to the empty string with ``kpasswd_listen = ""``. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in **kpasswd_port**, or the standard kpasswd port (464). New in release 1.15. **kpasswd_port** (Port number.) Specifies the port on which the :ref:`kadmind(8)` daemon is to listen for password change requests for this realm. Port numbers specified in **kpasswd_listen** entries will override this port number. The assigned port for password change requests is 464, which is used by default. **master_key_name** (String.) Specifies the name of the principal associated with the master key. The default is ``K/M``. **master_key_type** (Key type string.) Specifies the master key's key type. The default value for this is |defmkey|. For a list of all possible values, see :ref:`Encryption_types`. **max_life** (:ref:`duration` string.) Specifies the maximum time period for which a ticket may be valid in this realm. The default value is 24 hours. **max_renewable_life** (:ref:`duration` string.) Specifies the maximum time period during which a valid ticket may be renewed in this realm. The default value is 0. **no_host_referral** (Whitespace- or comma-separated list.) Lists services to block from getting host-based referral processing, even if the client marks the server principal as host-based or the service is also listed in **host_based_services**. ``no_host_referral = *`` will disable referral processing altogether. **reject_bad_transit** (Boolean value.) If set to true, the KDC will check the list of transited realms for cross-realm tickets against the transit path computed from the realm names and the capaths section of its :ref:`krb5.conf(5)` file; if the path in the ticket to be issued contains any realms not in the computed path, the ticket will not be issued, and an error will be returned to the client instead. If this value is set to false, such tickets will be issued anyways, and it will be left up to the application server to validate the realm transit path. If the disable-transited-check flag is set in the incoming request, this check is not performed at all. Having the **reject_bad_transit** option will cause such ticket requests to be rejected always. This transit path checking and config file option currently apply only to TGS requests. The default value is true. **restrict_anonymous_to_tgt** (Boolean value.) If set to true, the KDC will reject ticket requests from anonymous principals to service principals other than the realm's ticket-granting service. This option allows anonymous PKINIT to be enabled for use as FAST armor tickets without allowing anonymous authentication to services. The default value is false. New in release 1.9. **spake_preauth_indicator** (String.) Specifies an authentication indicator value that the KDC asserts into tickets obtained using SPAKE pre-authentication. The default is not to add any indicators. This option may be specified multiple times. New in release 1.17. **supported_enctypes** (List of *key*:*salt* strings.) Specifies the default key/salt combinations of principals for this realm. Any principals created through :ref:`kadmin(1)` will have keys of these types. The default value for this tag is |defkeysalts|. For lists of possible values, see :ref:`Keysalt_lists`. .. _dbdefaults: [dbdefaults] ~~~~~~~~~~~~ The [dbdefaults] section specifies default values for some database parameters, to be used if the [dbmodules] subsection does not contain a relation for the tag. See the :ref:`dbmodules` section for the definitions of these relations. * **ldap_kerberos_container_dn** * **ldap_kdc_dn** * **ldap_kdc_sasl_authcid** * **ldap_kdc_sasl_authzid** * **ldap_kdc_sasl_mech** * **ldap_kdc_sasl_realm** * **ldap_kadmind_dn** * **ldap_kadmind_sasl_authcid** * **ldap_kadmind_sasl_authzid** * **ldap_kadmind_sasl_mech** * **ldap_kadmind_sasl_realm** * **ldap_service_password_file** * **ldap_conns_per_server** .. _dbmodules: [dbmodules] ~~~~~~~~~~~ The [dbmodules] section contains parameters used by the KDC database library and database modules. Each tag in the [dbmodules] section is the name of a Kerberos realm or a section name specified by a realm's **database_module** parameter. The following example shows how to define one database parameter for the ATHENA.MIT.EDU realm:: [dbmodules] ATHENA.MIT.EDU = { disable_last_success = true } The following tags may be specified in a [dbmodules] subsection: **database_name** This DB2-specific tag indicates the location of the database in the filesystem. The default is |kdcdir|\ ``/principal``. **db_library** This tag indicates the name of the loadable database module. The value should be ``db2`` for the DB2 module, ``klmdb`` for the LMDB module, or ``kldap`` for the LDAP module. **disable_last_success** If set to ``true``, suppresses KDC updates to the "Last successful authentication" field of principal entries requiring preauthentication. Setting this flag may improve performance. (Principal entries which do not require preauthentication never update the "Last successful authentication" field.). First introduced in release 1.9. **disable_lockout** If set to ``true``, suppresses KDC updates to the "Last failed authentication" and "Failed password attempts" fields of principal entries requiring preauthentication. Setting this flag may improve performance, but also disables account lockout. First introduced in release 1.9. **ldap_conns_per_server** This LDAP-specific tag indicates the number of connections to be maintained per LDAP server. **ldap_kdc_dn** and **ldap_kadmind_dn** These LDAP-specific tags indicate the default DN for binding to the LDAP server. The :ref:`krb5kdc(8)` daemon uses **ldap_kdc_dn**, while the :ref:`kadmind(8)` daemon and other administrative programs use **ldap_kadmind_dn**. The kadmind DN must have the rights to read and write the Kerberos data in the LDAP database. The KDC DN must have the same rights, unless **disable_lockout** and **disable_last_success** are true, in which case it only needs to have rights to read the Kerberos data. These tags are ignored if a SASL mechanism is set with **ldap_kdc_sasl_mech** or **ldap_kadmind_sasl_mech**. **ldap_kdc_sasl_mech** and **ldap_kadmind_sasl_mech** These LDAP-specific tags specify the SASL mechanism (such as ``EXTERNAL``) to use when binding to the LDAP server. New in release 1.13. **ldap_kdc_sasl_authcid** and **ldap_kadmind_sasl_authcid** These LDAP-specific tags specify the SASL authentication identity to use when binding to the LDAP server. Not all SASL mechanisms require an authentication identity. If the SASL mechanism requires a secret (such as the password for ``DIGEST-MD5``), these tags also determine the name within the **ldap_service_password_file** where the secret is stashed. New in release 1.13. **ldap_kdc_sasl_authzid** and **ldap_kadmind_sasl_authzid** These LDAP-specific tags specify the SASL authorization identity to use when binding to the LDAP server. In most circumstances they do not need to be specified. New in release 1.13. **ldap_kdc_sasl_realm** and **ldap_kadmind_sasl_realm** These LDAP-specific tags specify the SASL realm to use when binding to the LDAP server. In most circumstances they do not need to be set. New in release 1.13. **ldap_kerberos_container_dn** This LDAP-specific tag indicates the DN of the container object where the realm objects will be located. **ldap_servers** This LDAP-specific tag indicates the list of LDAP servers that the Kerberos servers can connect to. The list of LDAP servers is whitespace-separated. The LDAP server is specified by a LDAP URI. It is recommended to use ``ldapi:`` or ``ldaps:`` URLs to connect to the LDAP server. **ldap_service_password_file** This LDAP-specific tag indicates the file containing the stashed passwords (created by ``kdb5_ldap_util stashsrvpw``) for the **ldap_kdc_dn** and **ldap_kadmind_dn** objects, or for the **ldap_kdc_sasl_authcid** or **ldap_kadmind_sasl_authcid** names for SASL authentication. This file must be kept secure. **mapsize** This LMDB-specific tag indicates the maximum size of the two database environments in megabytes. The default value is 128. Increase this value to address "Environment mapsize limit reached" errors. New in release 1.17. **max_readers** This LMDB-specific tag indicates the maximum number of concurrent reading processes for the databases. The default value is 128. New in release 1.17. **nosync** This LMDB-specific tag can be set to improve the throughput of kadmind and other administrative agents, at the expense of durability (recent database changes may not survive a power outage or other sudden reboot). It does not affect the throughput of the KDC. The default value is false. New in release 1.17. **unlockiter** If set to ``true``, this DB2-specific tag causes iteration operations to release the database lock while processing each principal. Setting this flag to ``true`` can prevent extended blocking of KDC or kadmin operations when dumps of large databases are in progress. First introduced in release 1.13. The following tag may be specified directly in the [dbmodules] section to control where database modules are loaded from: **db_module_dir** This tag controls where the plugin system looks for database modules. The value should be an absolute path. .. _logging: [logging] ~~~~~~~~~ The [logging] section indicates how :ref:`krb5kdc(8)` and :ref:`kadmind(8)` perform logging. It may contain the following relations: **admin_server** Specifies how :ref:`kadmind(8)` performs logging. **kdc** Specifies how :ref:`krb5kdc(8)` performs logging. **default** Specifies how either daemon performs logging in the absence of relations specific to the daemon. **debug** (Boolean value.) Specifies whether debugging messages are included in log outputs other than SYSLOG. Debugging messages are always included in the system log output because syslog performs its own priority filtering. The default value is false. New in release 1.15. Logging specifications may have the following forms: **FILE=**\ *filename* or **FILE:**\ *filename* This value causes the daemon's logging messages to go to the *filename*. If the ``=`` form is used, the file is overwritten. If the ``:`` form is used, the file is appended to. **STDERR** This value causes the daemon's logging messages to go to its standard error stream. **CONSOLE** This value causes the daemon's logging messages to go to the console, if the system supports it. **DEVICE=**\ ** This causes the daemon's logging messages to go to the specified device. **SYSLOG**\ [\ **:**\ *severity*\ [\ **:**\ *facility*\ ]] This causes the daemon's logging messages to go to the system log. For backward compatibility, a severity argument may be specified, and must be specified in order to specify a facility. This argument will be ignored. The facility argument specifies the facility under which the messages are logged. This may be any of the following facilities supported by the syslog(3) call minus the LOG\_ prefix: **KERN**, **USER**, **MAIL**, **DAEMON**, **AUTH**, **LPR**, **NEWS**, **UUCP**, **CRON**, and **LOCAL0** through **LOCAL7**. If no facility is specified, the default is **AUTH**. In the following example, the logging messages from the KDC will go to the console and to the system log under the facility LOG_DAEMON, and the logging messages from the administrative server will be appended to the file ``/var/adm/kadmin.log`` and sent to the device ``/dev/tty04``. :: [logging] kdc = CONSOLE kdc = SYSLOG:INFO:DAEMON admin_server = FILE:/var/adm/kadmin.log admin_server = DEVICE=/dev/tty04 If no logging specification is given, the default is to use syslog. To disable logging entirely, specify ``default = DEVICE=/dev/null``. .. _otp: [otp] ~~~~~ Each subsection of [otp] is the name of an OTP token type. The tags within the subsection define the configuration required to forward a One Time Password request to a RADIUS server. For each token type, the following tags may be specified: **server** This is the server to send the RADIUS request to. It can be a hostname with optional port, an ip address with optional port, or a Unix domain socket address. The default is |kdcdir|\ ``/.socket``. **secret** This tag indicates a filename (which may be relative to |kdcdir|) containing the secret used to encrypt the RADIUS packets. The secret should appear in the first line of the file by itself; leading and trailing whitespace on the line will be removed. If the value of **server** is a Unix domain socket address, this tag is optional, and an empty secret will be used if it is not specified. Otherwise, this tag is required. **timeout** An integer which specifies the time in seconds during which the KDC should attempt to contact the RADIUS server. This tag is the total time across all retries and should be less than the time which an OTP value remains valid for. The default is 5 seconds. **retries** This tag specifies the number of retries to make to the RADIUS server. The default is 3 retries (4 tries). **strip_realm** If this tag is ``true``, the principal without the realm will be passed to the RADIUS server. Otherwise, the realm will be included. The default value is ``true``. **indicator** This tag specifies an authentication indicator to be included in the ticket if this token type is used to authenticate. This option may be specified multiple times. (New in release 1.14.) In the following example, requests are sent to a remote server via UDP:: [otp] MyRemoteTokenType = { server = radius.mydomain.com:1812 secret = SEmfiajf42$ timeout = 15 retries = 5 strip_realm = true } An implicit default token type named ``DEFAULT`` is defined for when the per-principal configuration does not specify a token type. Its configuration is shown below. You may override this token type to something applicable for your situation:: [otp] DEFAULT = { strip_realm = false } PKINIT options -------------- .. note:: The following are pkinit-specific options. These values may be specified in [kdcdefaults] as global defaults, or within a realm-specific subsection of [realms]. Also note that a realm-specific value over-rides, does not add to, a generic [kdcdefaults] specification. The search order is: 1. realm-specific subsection of [realms]:: [realms] EXAMPLE.COM = { pkinit_anchors = FILE:/usr/local/example.com.crt } 2. generic value in the [kdcdefaults] section:: [kdcdefaults] pkinit_anchors = DIR:/usr/local/generic_trusted_cas/ For information about the syntax of some of these options, see :ref:`Specifying PKINIT identity information ` in :ref:`krb5.conf(5)`. **pkinit_anchors** Specifies the location of trusted anchor (root) certificates which the KDC trusts to sign client certificates. This option is required if pkinit is to be supported by the KDC. This option may be specified multiple times. **pkinit_dh_min_bits** Specifies the minimum strength of Diffie-Hellman group the KDC is willing to accept for key exchange. Valid values in order of increasing strength are 1024, 2048, P-256, 4096, P-384, and P-521. The default is 2048. (P-256, P-384, and P-521 are new in release 1.22.) **pkinit_allow_upn** Specifies that the KDC is willing to accept client certificates with the Microsoft UserPrincipalName (UPN) Subject Alternative Name (SAN). This means the KDC accepts the binding of the UPN in the certificate to the Kerberos principal name. The default value is false. Without this option, the KDC will only accept certificates with the id-pkinit-san as defined in :rfc:`4556`. There is currently no option to disable SAN checking in the KDC. **pkinit_eku_checking** This option specifies what Extended Key Usage (EKU) values the KDC is willing to accept in client certificates. The values recognized in the kdc.conf file are: **kpClientAuth** This is the default value and specifies that client certificates must have the id-pkinit-KPClientAuth EKU as defined in :rfc:`4556`. **scLogin** If scLogin is specified, client certificates with the Microsoft Smart Card Login EKU (id-ms-kp-sc-logon) will be accepted. **none** If none is specified, then client certificates will not be checked to verify they have an acceptable EKU. The use of this option is not recommended. **pkinit_identity** Specifies the location of the KDC's X.509 identity information. This option is required if pkinit is to be supported by the KDC. **pkinit_indicator** Specifies an authentication indicator to include in the ticket if pkinit is used to authenticate. This option may be specified multiple times. (New in release 1.14.) **pkinit_pool** Specifies the location of intermediate certificates which may be used by the KDC to complete the trust chain between a client's certificate and a trusted anchor. This option may be specified multiple times. **pkinit_revoke** Specifies the location of Certificate Revocation List (CRL) information to be used by the KDC when verifying the validity of client certificates. This option may be specified multiple times. **pkinit_require_crl_checking** The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and **pkinit_require_crl_checking** is false, then verification succeeds. However, if **pkinit_require_crl_checking** is true and there is no CRL information available for the issuing CA, then verification fails. **pkinit_require_crl_checking** should be set to true if the policy is such that up-to-date CRLs must be present for every CA. **pkinit_require_freshness** Specifies whether to require clients to include a freshness token in PKINIT requests. The default value is false. (New in release 1.17.) .. _Encryption_types: Encryption types ---------------- Any tag in the configuration files which requires a list of encryption types can be set to some combination of the following strings. Encryption types marked as "weak" and "deprecated" are available for compatibility but not recommended for use. ==================================================== ========================================================= des3-cbc-raw Triple DES cbc mode raw (weak) des3-cbc-sha1 des3-hmac-sha1 des3-cbc-sha1-kd Triple DES cbc mode with HMAC/sha1 (deprecated) aes256-cts-hmac-sha1-96 aes256-cts aes256-sha1 AES-256 CTS mode with 96-bit SHA-1 HMAC aes128-cts-hmac-sha1-96 aes128-cts aes128-sha1 AES-128 CTS mode with 96-bit SHA-1 HMAC aes256-cts-hmac-sha384-192 aes256-sha2 AES-256 CTS mode with 192-bit SHA-384 HMAC aes128-cts-hmac-sha256-128 aes128-sha2 AES-128 CTS mode with 128-bit SHA-256 HMAC arcfour-hmac rc4-hmac arcfour-hmac-md5 RC4 with HMAC/MD5 (deprecated) arcfour-hmac-exp rc4-hmac-exp arcfour-hmac-md5-exp Exportable RC4 with HMAC/MD5 (weak) camellia256-cts-cmac camellia256-cts Camellia-256 CTS mode with CMAC camellia128-cts-cmac camellia128-cts Camellia-128 CTS mode with CMAC des3 The triple DES family: des3-cbc-sha1 aes The AES family: aes256-cts-hmac-sha1-96, aes128-cts-hmac-sha1-96, aes256-cts-hmac-sha384-192, and aes128-cts-hmac-sha256-128 rc4 The RC4 family: arcfour-hmac camellia The Camellia family: camellia256-cts-cmac and camellia128-cts-cmac ==================================================== ========================================================= The string **DEFAULT** can be used to refer to the default set of types for the variable in question. Types or families can be removed from the current list by prefixing them with a minus sign ("-"). Types or families can be prefixed with a plus sign ("+") for symmetry; it has the same meaning as just listing the type or family. For example, "``DEFAULT -rc4``" would be the default set of encryption types with RC4 types removed, and "``des3 DEFAULT``" would be the default set of encryption types with triple DES types moved to the front. While **aes128-cts** and **aes256-cts** are supported for all Kerberos operations, they are not supported by very old versions of our GSSAPI implementation (krb5-1.3.1 and earlier). Services running versions of krb5 without AES support must not be given keys of these encryption types in the KDC database. The **aes128-sha2** and **aes256-sha2** encryption types are new in release 1.15. Services running versions of krb5 without support for these newer encryption types must not be given keys of these encryption types in the KDC database. .. _Keysalt_lists: Keysalt lists ------------- Kerberos keys for users are usually derived from passwords. Kerberos commands and configuration parameters that affect generation of keys take lists of enctype-salttype ("keysalt") pairs, known as *keysalt lists*. Each keysalt pair is an enctype name followed by a salttype name, in the format *enc*:*salt*. Individual keysalt list members are separated by comma (",") characters or space characters. For example:: kadmin -e aes256-cts:normal,aes128-cts:normal would start up kadmin so that by default it would generate password-derived keys for the **aes256-cts** and **aes128-cts** encryption types, using a **normal** salt. To ensure that people who happen to pick the same password do not have the same key, Kerberos 5 incorporates more information into the key using something called a salt. The supported salt types are as follows: ================= ============================================ normal default for Kerberos Version 5 norealm same as the default, without using realm information onlyrealm uses only realm information as the salt special generate a random salt ================= ============================================ Sample kdc.conf File -------------------- Here's an example of a kdc.conf file:: [kdcdefaults] kdc_listen = 88 kdc_tcp_listen = 88 [realms] ATHENA.MIT.EDU = { kadmind_port = 749 max_life = 12h 0m 0s max_renewable_life = 7d 0h 0m 0s master_key_type = aes256-cts-hmac-sha1-96 supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal database_module = openldap_ldapconf } [logging] kdc = FILE:/usr/local/var/krb5kdc/kdc.log admin_server = FILE:/usr/local/var/krb5kdc/kadmin.log [dbdefaults] ldap_kerberos_container_dn = cn=krbcontainer,dc=mit,dc=edu [dbmodules] openldap_ldapconf = { db_library = kldap disable_last_success = true ldap_kdc_dn = "cn=krbadmin,dc=mit,dc=edu" # this object needs to have read rights on # the realm container and principal subtrees ldap_kadmind_dn = "cn=krbadmin,dc=mit,dc=edu" # this object needs to have read and write rights on # the realm container and principal subtrees ldap_service_password_file = /etc/kerberos/service.keyfile ldap_servers = ldaps://kerberos.mit.edu ldap_conns_per_server = 5 } FILES ------ |kdcdir|\ ``/kdc.conf`` SEE ALSO --------- :ref:`krb5.conf(5)`, :ref:`krb5kdc(8)`, :ref:`kadm5.acl(5)` krb5-1.22.1/doc/admin/conf_files/index.rst0000664000175000017500000000120115051422640020140 0ustar ghudsonghudsonConfiguration Files =================== Kerberos uses configuration files to allow administrators to specify settings on a per-machine basis. :ref:`krb5.conf(5)` applies to all applications using the Kerboros library, on clients and servers. For KDC-specific applications, additional settings can be specified in :ref:`kdc.conf(5)`; the two files are merged into a configuration profile used by applications accessing the KDC database directly. :ref:`kadm5.acl(5)` is also only used on the KDC, it controls permissions for modifying the KDC database. Contents -------- .. toctree:: :maxdepth: 1 krb5_conf kdc_conf kadm5_acl krb5-1.22.1/doc/admin/install_clients.rst0000664000175000017500000000544215051422640020124 0ustar ghudsonghudsonInstalling and configuring UNIX client machines =============================================== The Kerberized client programs include :ref:`kinit(1)`, :ref:`klist(1)`, :ref:`kdestroy(1)`, and :ref:`kpasswd(1)`. All of these programs are in the directory |bindir|. You can often integrate Kerberos with the login system on client machines, typically through the use of PAM. The details vary by operating system, and should be covered in your operating system's documentation. If you do this, you will need to make sure your users know to use their Kerberos passwords when they log in. You will also need to educate your users to use the ticket management programs kinit, klist, and kdestroy. If you do not have Kerberos password changing integrated into the native password program (again, typically through PAM), you will need to educate users to use kpasswd in place of its non-Kerberos counterparts passwd. Client machine configuration files ---------------------------------- Each machine running Kerberos should have a :ref:`krb5.conf(5)` file. At a minimum, it should define a **default_realm** setting in :ref:`libdefaults`. If you are not using DNS SRV records (:ref:`kdc_hostnames`) or URI records (:ref:`kdc_discovery`), it must also contain a :ref:`realms` section containing information for your realm's KDCs. Consider setting **rdns** to false in order to reduce your dependence on precisely correct DNS information for service hostnames. Turning this flag off means that service hostnames will be canonicalized through forward name resolution (which adds your domain name to unqualified hostnames, and resolves CNAME records in DNS), but not through reverse address lookup. The default value of this flag is true for historical reasons only. If you anticipate users frequently logging into remote hosts (e.g., using ssh) using forwardable credentials, consider setting **forwardable** to true so that users obtain forwardable tickets by default. Otherwise users will need to use ``kinit -f`` to get forwardable tickets. Consider adjusting the **ticket_lifetime** setting to match the likely length of sessions for your users. For instance, if most of your users will be logging in for an eight-hour workday, you could set the default to ten hours so that tickets obtained in the morning expire shortly after the end of the workday. Users can still manually request longer tickets when necessary, up to the maximum allowed by each user's principal record on the KDC. If a client host may access services in different realms, it may be useful to define a :ref:`domain_realm` mapping so that clients know which hosts belong to which realms. However, if your clients and KDC are running release 1.7 or later, it is also reasonable to leave this section out on client machines and just define it in the KDC's krb5.conf. krb5-1.22.1/doc/admin/pkinit.rst0000664000175000017500000003434315051422640016235 0ustar ghudsonghudson.. _pkinit: PKINIT configuration ==================== PKINIT is a preauthentication mechanism for Kerberos 5 which uses X.509 certificates to authenticate the KDC to clients and vice versa. PKINIT can also be used to enable anonymity support, allowing clients to communicate securely with the KDC or with application servers without authenticating as a particular client principal. Creating certificates --------------------- PKINIT requires an X.509 certificate for the KDC and one for each client principal which will authenticate using PKINIT. For anonymous PKINIT, a KDC certificate is required, but client certificates are not. A commercially issued server certificate can be used for the KDC certificate, but generally cannot be used for client certificates. The instruction in this section describe how to establish a certificate authority and create standard PKINIT certificates. Skip this section if you are using a commercially issued server certificate as the KDC certificate for anonymous PKINIT, or if you are configuring a client to use an Active Directory KDC. Generating a certificate authority certificate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can establish a new certificate authority (CA) for use with a PKINIT deployment with the commands:: openssl genrsa -out cakey.pem 2048 openssl req -key cakey.pem -new -x509 -out cacert.pem -days 3650 The second command will ask for the values of several certificate fields. These fields can be set to any values. You can adjust the expiration time of the CA certificate by changing the number after ``-days``. Since the CA certificate must be deployed to client machines each time it changes, it should normally have an expiration time far in the future; however, expiration times after 2037 may cause interoperability issues in rare circumstances. The result of these commands will be two files, cakey.pem and cacert.pem. cakey.pem will contain a 2048-bit RSA private key, which must be carefully protected. cacert.pem will contain the CA certificate, which must be placed in the filesystems of the KDC and each client host. cakey.pem will be required to create KDC and client certificates. Generating a KDC certificate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A KDC certificate for use with PKINIT is required to have some unusual fields, which makes generating them with OpenSSL somewhat complicated. First, you will need a file containing the following:: [kdc_cert] basicConstraints=CA:FALSE keyUsage=nonRepudiation,digitalSignature,keyEncipherment,keyAgreement extendedKeyUsage=1.3.6.1.5.2.3.5 subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer issuerAltName=issuer:copy subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name [kdc_princ_name] realm=EXP:0,GeneralString:${ENV::REALM} principal_name=EXP:1,SEQUENCE:kdc_principal_seq [kdc_principal_seq] name_type=EXP:0,INTEGER:2 name_string=EXP:1,SEQUENCE:kdc_principals [kdc_principals] princ1=GeneralString:krbtgt princ2=GeneralString:${ENV::REALM} If the above contents are placed in extensions.kdc, you can generate and sign a KDC certificate with the following commands:: openssl genrsa -out kdckey.pem 2048 openssl req -new -out kdc.req -key kdckey.pem env REALM=YOUR_REALMNAME openssl x509 -req -in kdc.req \ -CAkey cakey.pem -CA cacert.pem -out kdc.pem -days 365 \ -extfile extensions.kdc -extensions kdc_cert -CAcreateserial rm kdc.req The second command will ask for the values of certificate fields, which can be set to any values. In the third command, substitute your KDC's realm name for YOUR_REALMNAME. You can adjust the certificate's expiration date by changing the number after ``-days``. Remember to create a new KDC certificate before the old one expires. The result of this operation will be in two files, kdckey.pem and kdc.pem. Both files must be placed in the KDC's filesystem. kdckey.pem, which contains the KDC's private key, must be carefully protected. If you examine the KDC certificate with ``openssl x509 -in kdc.pem -text -noout``, OpenSSL will not know how to display the KDC principal name in the Subject Alternative Name extension, so it will appear as ``othername:``. This is normal and does not mean anything is wrong with the KDC certificate. Generating client certificates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PKINIT client certificates also must have some unusual certificate fields. To generate a client certificate with OpenSSL for a single-component principal name, you will need an extensions file (different from the KDC extensions file above) containing:: [client_cert] basicConstraints=CA:FALSE keyUsage=digitalSignature,keyEncipherment,keyAgreement extendedKeyUsage=1.3.6.1.5.2.3.4 subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer issuerAltName=issuer:copy subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:princ_name [princ_name] realm=EXP:0,GeneralString:${ENV::REALM} principal_name=EXP:1,SEQUENCE:principal_seq [principal_seq] name_type=EXP:0,INTEGER:1 name_string=EXP:1,SEQUENCE:principals [principals] princ1=GeneralString:${ENV::CLIENT} If the above contents are placed in extensions.client, you can generate and sign a client certificate with the following commands:: openssl genrsa -out clientkey.pem 2048 openssl req -new -key clientkey.pem -out client.req env REALM=YOUR_REALMNAME CLIENT=YOUR_PRINCNAME openssl x509 \ -CAkey cakey.pem -CA cacert.pem -req -in client.req \ -extensions client_cert -extfile extensions.client \ -days 365 -out client.pem rm client.req Normally, the first two commands should be run on the client host, and the resulting client.req file transferred to the certificate authority host for the third command. As in the previous steps, the second command will ask for the values of certificate fields, which can be set to any values. In the third command, substitute your realm's name for YOUR_REALMNAME and the client's principal name (without realm) for YOUR_PRINCNAME. You can adjust the certificate's expiration date by changing the number after ``-days``. The result of this operation will be two files, clientkey.pem and client.pem. Both files must be present on the client's host; clientkey.pem, which contains the client's private key, must be protected from access by others. As in the KDC certificate, OpenSSL will display the client principal name as ``othername:`` in the Subject Alternative Name extension of a PKINIT client certificate. If the client principal name contains more than one component (e.g. ``host/example.com@REALM``), the ``[principals]`` section of ``extensions.client`` must be altered to contain multiple entries. (Simply setting ``CLIENT`` to ``host/example.com`` would generate a certificate for ``host\/example.com@REALM`` which would not match the multi-component principal name.) For a two-component principal, the section should read:: [principals] princ1=GeneralString:${ENV::CLIENT1} princ2=GeneralString:${ENV::CLIENT2} The environment variables ``CLIENT1`` and ``CLIENT2`` must then be set to the first and second components when running ``openssl x509``. Configuring the KDC ------------------- The KDC must have filesystem access to the KDC certificate (kdc.pem) and the KDC private key (kdckey.pem). Configure the following relation in the KDC's :ref:`kdc.conf(5)` file, either in the :ref:`kdcdefaults` section or in a :ref:`kdc_realms` subsection (with appropriate pathnames):: pkinit_identity = FILE:/var/lib/krb5kdc/kdc.pem,/var/lib/krb5kdc/kdckey.pem If any clients will authenticate using regular (as opposed to anonymous) PKINIT, the KDC must also have filesystem access to the CA certificate (cacert.pem), and the following configuration (with the appropriate pathname):: pkinit_anchors = FILE:/var/lib/krb5kdc/cacert.pem Because of the larger size of requests and responses using PKINIT, you may also need to allow TCP access to the KDC:: kdc_tcp_listen = 88 Restart the :ref:`krb5kdc(8)` daemon to pick up the configuration changes. The principal entry for each PKINIT-using client must be configured to require preauthentication. Ensure this with the command:: kadmin -q 'modprinc +requires_preauth YOUR_PRINCNAME' Starting with release 1.12, it is possible to remove the long-term keys of a principal entry, which can save some space in the database and help to clarify some PKINIT-related error conditions by not asking for a password:: kadmin -q 'purgekeys -all YOUR_PRINCNAME' These principal options can also be specified at principal creation time as follows:: kadmin -q 'add_principal +requires_preauth -nokey YOUR_PRINCNAME' By default, the KDC requires PKINIT client certificates to have the standard Extended Key Usage and Subject Alternative Name attributes for PKINIT. Starting in release 1.16, it is possible to authorize client certificates based on the subject or other criteria instead of the standard PKINIT Subject Alternative Name, by setting the **pkinit_cert_match** string attribute on each client principal entry. For example:: kadmin set_string user@REALM pkinit_cert_match "CN=user@REALM$" The **pkinit_cert_match** string attribute follows the syntax used by the :ref:`krb5.conf(5)` **pkinit_cert_match** relation. To allow the use of non-PKINIT client certificates, it will also be necessary to disable key usage checking using the **pkinit_eku_checking** relation; for example:: [kdcdefaults] pkinit_eku_checking = none Configuring the clients ----------------------- Client hosts must be configured to trust the issuing authority for the KDC certificate. For a newly established certificate authority, the client host must have filesystem access to the CA certificate (cacert.pem) and the following relation in :ref:`krb5.conf(5)` in the appropriate :ref:`realms` subsection (with appropriate pathnames):: pkinit_anchors = FILE:/etc/krb5/cacert.pem If the KDC certificate is a commercially issued server certificate, the issuing certificate is most likely included in a system directory. You can specify it by filename as above, or specify the whole directory like so:: pkinit_anchors = DIR:/etc/ssl/certs A commercially issued server certificate will usually not have the standard PKINIT principal name or Extended Key Usage extensions, so the following additional configuration is required:: pkinit_eku_checking = kpServerAuth pkinit_kdc_hostname = hostname.of.kdc.certificate Multiple **pkinit_kdc_hostname** relations can be configured to recognize multiple KDC certificates. If the KDC is an Active Directory domain controller, setting **pkinit_kdc_hostname** is necessary, but it should not be necessary to set **pkinit_eku_checking**. To perform regular (as opposed to anonymous) PKINIT authentication, a client host must have filesystem access to a client certificate (client.pem), and the corresponding private key (clientkey.pem). Configure the following relations in the client host's :ref:`krb5.conf(5)` file in the appropriate :ref:`realms` subsection (with appropriate pathnames):: pkinit_identities = FILE:/etc/krb5/client.pem,/etc/krb5/clientkey.pem If the KDC and client are properly configured, it should now be possible to run ``kinit username`` without entering a password. .. _anonymous_pkinit: Anonymous PKINIT ---------------- Anonymity support in Kerberos allows a client to obtain a ticket without authenticating as any particular principal. Such a ticket can be used as a FAST armor ticket, or to securely communicate with an application server anonymously. To configure anonymity support, you must generate or otherwise procure a KDC certificate and configure the KDC host, but you do not need to generate any client certificates. On the KDC, you must set the **pkinit_identity** variable to provide the KDC certificate, but do not need to set the **pkinit_anchors** variable or store the issuing certificate if you won't have any client certificates to verify. On client hosts, you must set the **pkinit_anchors** variable (and possibly **pkinit_kdc_hostname** and **pkinit_eku_checking**) in order to trust the issuing authority for the KDC certificate, but do not need to set the **pkinit_identities** variable. Anonymity support is not enabled by default. To enable it, you must create the principal ``WELLKNOWN/ANONYMOUS`` using the command:: kadmin -q 'addprinc -randkey WELLKNOWN/ANONYMOUS' Some Kerberos deployments include application servers which lack proper access control, and grant some level of access to any user who can authenticate. In such an environment, enabling anonymity support on the KDC would present a security issue. If you need to enable anonymity support for TGTs (for use as FAST armor tickets) without enabling anonymous authentication to application servers, you can set the variable **restrict_anonymous_to_tgt** to ``true`` in the appropriate :ref:`kdc_realms` subsection of the KDC's :ref:`kdc.conf(5)` file. To obtain anonymous credentials on a client, run ``kinit -n``, or ``kinit -n @REALMNAME`` to specify a realm. The resulting tickets will have the client name ``WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS``. Freshness tokens ---------------- Freshness tokens can ensure that the client has recently had access to its certificate private key. If freshness tokens are not required by the KDC, a client program with temporary possession of the private key can compose requests for future timestamps and use them later. In release 1.17 and later, freshness tokens are supported by the client and are sent by the KDC when the client indicates support for them. Because not all clients support freshness tokens yet, they are not required by default. To check if freshness tokens are supported by a realm's clients, look in the KDC logs for the lines:: PKINIT: freshness token received from PKINIT: no freshness token received from To require freshness tokens for all clients in a realm (except for clients authenticating anonymously), set the **pkinit_require_freshness** variable to ``true`` in the appropriate :ref:`kdc_realms` subsection of the KDC's :ref:`kdc.conf(5)` file. To test that this option is in effect, run ``kinit -X disable_freshness`` and verify that authentication is unsuccessful. krb5-1.22.1/doc/admin/admin_commands/0000775000175000017500000000000015051422640017147 5ustar ghudsonghudsonkrb5-1.22.1/doc/admin/admin_commands/k5srvutil.rst0000664000175000017500000000401215051422640021646 0ustar ghudsonghudson.. _k5srvutil(1): k5srvutil ========= SYNOPSIS -------- **k5srvutil** *operation* [**-i**] [**-f** *filename*] [**-e** *keysalts*] DESCRIPTION ----------- k5srvutil allows an administrator to list keys currently in a keytab, to obtain new keys for a principal currently in a keytab, or to delete non-current keys from a keytab. *operation* must be one of the following: **list** Lists the keys in a keytab, showing version number and principal name. **change** Uses the kadmin protocol to update the keys in the Kerberos database to new randomly-generated keys, and updates the keys in the keytab to match. If a key's version number doesn't match the version number stored in the Kerberos server's database, then the operation will fail. If the **-i** flag is given, k5srvutil will prompt for confirmation before changing each key. If the **-k** option is given, the old and new keys will be displayed. Ordinarily, keys will be generated with the default encryption types and key salts. This can be overridden with the **-e** option. Old keys are retained in the keytab so that existing tickets continue to work, but **delold** should be used after such tickets expire, to prevent attacks against the old keys. **delold** Deletes keys that are not the most recent version from the keytab. This operation should be used some time after a change operation to remove old keys, after existing tickets issued for the service have expired. If the **-i** flag is given, then k5srvutil will prompt for confirmation for each principal. **delete** Deletes particular keys in the keytab, interactively prompting for each key. In all cases, the default keytab is used unless this is overridden by the **-f** option. k5srvutil uses the :ref:`kadmin(1)` program to edit the keytab in place. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`ktutil(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/admin/admin_commands/kdb5_util.rst0000664000175000017500000003550215051422640021570 0ustar ghudsonghudson.. _kdb5_util(8): kdb5_util ========= SYNOPSIS -------- .. _kdb5_util_synopsis: **kdb5_util** [**-r** *realm*] [**-d** *dbname*] [**-k** *mkeytype*] [**-kv** *mkeyVNO*] [**-M** *mkeyname*] [**-m**] [**-sf** *stashfilename*] [**-P** *password*] [**-x** *db_args*] *command* [*command_options*] .. _kdb5_util_synopsis_end: DESCRIPTION ----------- kdb5_util allows an administrator to perform maintenance procedures on the KDC database. Databases can be created, destroyed, and dumped to or loaded from ASCII files. kdb5_util can create a Kerberos master key stash file or perform live rollover of the master key. When kdb5_util is run, it attempts to acquire the master key and open the database. However, execution continues regardless of whether or not kdb5_util successfully opens the database, because the database may not exist yet or the stash file may be corrupt. Note that some KDC database modules may not support all kdb5_util commands. COMMAND-LINE OPTIONS -------------------- .. _kdb5_util_options: **-r** *realm* specifies the Kerberos realm of the database. **-d** *dbname* specifies the name under which the principal database is stored; by default the database is that listed in :ref:`kdc.conf(5)`. The password policy database and lock files are also derived from this value. **-k** *mkeytype* specifies the key type of the master key in the database. The default is given by the **master_key_type** variable in :ref:`kdc.conf(5)`. **-kv** *mkeyVNO* Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed. **-M** *mkeyname* principal name for the master key in the database. If not specified, the name is determined by the **master_key_name** variable in :ref:`kdc.conf(5)`. **-m** specifies that the master database password should be read from the keyboard rather than fetched from a file on disk. **-sf** *stash_file* specifies the stash filename of the master database password. If not specified, the filename is determined by the **key_stash_file** variable in :ref:`kdc.conf(5)`. **-P** *password* specifies the master database password. Using this option may expose the password to other users on the system via the process list. **-x** *db_args* specifies database-specific options. See :ref:`kadmin(1)` for supported options. .. _kdb5_util_options_end: COMMANDS -------- create ~~~~~~ .. _kdb5_util_create: **create** [**-s**] Creates a new database. If the **-s** option is specified, the stash file is also created. This command fails if the database already exists. If the command is successful, the database is opened just as if it had already existed when the program was first run. .. _kdb5_util_create_end: destroy ~~~~~~~ .. _kdb5_util_destroy: **destroy** [**-f**] Destroys the database, first overwriting the disk sectors and then unlinking the files, after prompting the user for confirmation. With the **-f** argument, does not prompt the user. .. _kdb5_util_destroy_end: stash ~~~~~ .. _kdb5_util_stash: **stash** [**-f** *keyfile*] Stores the master principal's keys in a stash file. The **-f** argument can be used to override the *keyfile* specified in :ref:`kdc.conf(5)`. .. _kdb5_util_stash_end: dump ~~~~ .. _kdb5_util_dump: **dump** [**-b7**\|\ **-r13**\|\ **-r18**] [**-verbose**] [**-mkey_convert**] [**-new_mkey_file** *mkey_file*] [**-rev**] [**-recurse**] [*filename* [*principals*...]] Dumps the current Kerberos and KADM5 database into an ASCII file. By default, the database is dumped in current format, "kdb5_util load_dump version 7". If filename is not specified, or is the string "-", the dump is sent to standard output. Options: **-b7** causes the dump to be in the Kerberos 5 Beta 7 format ("kdb5_util load_dump version 4"). This was the dump format produced on releases prior to 1.2.2. **-r13** causes the dump to be in the Kerberos 5 1.3 format ("kdb5_util load_dump version 5"). This was the dump format produced on releases prior to 1.8. **-r18** causes the dump to be in the Kerberos 5 1.8 format ("kdb5_util load_dump version 6"). This was the dump format produced on releases prior to 1.11. **-verbose** causes the name of each principal and policy to be printed as it is dumped. **-mkey_convert** prompts for a new master key. This new master key will be used to re-encrypt principal key data in the dumpfile. The principal keys themselves will not be changed. **-new_mkey_file** *mkey_file* the filename of a stash file. The master key in this stash file will be used to re-encrypt the key data in the dumpfile. The key data in the database will not be changed. **-rev** dumps in reverse order. This may recover principals that do not dump normally, in cases where database corruption has occurred. **-recurse** causes the dump to walk the database recursively (btree only). This may recover principals that do not dump normally, in cases where database corruption has occurred. In cases of such corruption, this option will probably retrieve more principals than the **-rev** option will. .. versionchanged:: 1.15 Release 1.15 restored the functionality of the **-recurse** option. .. versionchanged:: 1.5 The **-recurse** option ceased working until release 1.15, doing a normal dump instead of a recursive traversal. .. _kdb5_util_dump_end: load ~~~~ .. _kdb5_util_load: **load** [**-b7**\|\ **-r13**\|\ **-r18**] [**-hash**] [**-verbose**] [**-update**] *filename* Loads a database dump from the named file into the named database. If no option is given to determine the format of the dump file, the format is detected automatically and handled as appropriate. Unless the **-update** option is given, **load** creates a new database containing only the data in the dump file, overwriting the contents of any previously existing database. Note that when using the LDAP KDC database module, the **-update** flag is required. Options: **-b7** requires the database to be in the Kerberos 5 Beta 7 format ("kdb5_util load_dump version 4"). This was the dump format produced on releases prior to 1.2.2. **-r13** requires the database to be in Kerberos 5 1.3 format ("kdb5_util load_dump version 5"). This was the dump format produced on releases prior to 1.8. **-r18** requires the database to be in Kerberos 5 1.8 format ("kdb5_util load_dump version 6"). This was the dump format produced on releases prior to 1.11. **-hash** stores the database in hash format, if using the DB2 database type. If this option is not specified, the database will be stored in btree format. This option is not recommended, as databases stored in hash format are known to corrupt data and lose principals. **-verbose** causes the name of each principal and policy to be printed as it is dumped. **-update** records from the dump file are added to or updated in the existing database. Otherwise, a new database is created containing only what is in the dump file and the old one destroyed upon successful completion. .. _kdb5_util_load_end: ark ~~~ **ark** [**-e** *enc*:*salt*,...] *principal* Adds new random keys to *principal* at the next available key version number. Keys for the current highest key version number will be preserved. The **-e** option specifies the list of encryption and salt types to be used for the new keys. add_mkey ~~~~~~~~ **add_mkey** [**-e** *etype*] [**-s**] Adds a new master key to the master key principal, but does not mark it as active. Existing master keys will remain. The **-e** option specifies the encryption type of the new master key; see :ref:`Encryption_types` in :ref:`kdc.conf(5)` for a list of possible values. The **-s** option stashes the new master key in the stash file, which will be created if it doesn't already exist. After a new master key is added, it should be propagated to replica servers via a manual or periodic invocation of :ref:`kprop(8)`. Then, the stash files on the replica servers should be updated with the kdb5_util **stash** command. Once those steps are complete, the key is ready to be marked active with the kdb5_util **use_mkey** command. use_mkey ~~~~~~~~ **use_mkey** *mkeyVNO* [*time*] Sets the activation time of the master key specified by *mkeyVNO*. Once a master key becomes active, it will be used to encrypt newly created principal keys. If no *time* argument is given, the current time is used, causing the specified master key version to become active immediately. The format for *time* is :ref:`getdate` string. After a new master key becomes active, the kdb5_util **update_princ_encryption** command can be used to update all principal keys to be encrypted in the new master key. list_mkeys ~~~~~~~~~~ **list_mkeys** List all master keys, from most recent to earliest, in the master key principal. The output will show the kvno, enctype, and salt type for each mkey, similar to the output of :ref:`kadmin(1)` **getprinc**. A ``*`` following an mkey denotes the currently active master key. purge_mkeys ~~~~~~~~~~~ **purge_mkeys** [**-f**] [**-n**] [**-v**] Delete master keys from the master key principal that are not used to protect any principals. This command can be used to remove old master keys all principal keys are protected by a newer master key. **-f** does not prompt for confirmation. **-n** performs a dry run, showing master keys that would be purged, but not actually purging any keys. **-v** gives more verbose output. update_princ_encryption ~~~~~~~~~~~~~~~~~~~~~~~ **update_princ_encryption** [**-f**] [**-n**] [**-v**] [*princ-pattern*] Update all principal records (or only those matching the *princ-pattern* glob pattern) to re-encrypt the key data using the active database master key, if they are encrypted using a different version, and give a count at the end of the number of principals updated. If the **-f** option is not given, ask for confirmation before starting to make changes. The **-v** option causes each principal processed to be listed, with an indication as to whether it needed updating or not. The **-n** option performs a dry run, only showing the actions which would have been taken. tabdump ~~~~~~~ **tabdump** [**-H**] [**-c**] [**-e**] [**-n**] [**-o** *outfile*] *dumptype* Dump selected fields of the database in a tabular format suitable for reporting (e.g., using traditional Unix text processing tools) or importing into relational databases. The data format is tab-separated (default), or optionally comma-separated (CSV), with a fixed number of columns. The output begins with a header line containing field names, unless suppression is requested using the **-H** option. The *dumptype* parameter specifies the name of an output table (see below). Options: **-H** suppress writing the field names in a header line **-c** use comma separated values (CSV) format, with minimal quoting, instead of the default tab-separated (unquoted, unescaped) format **-e** write empty hexadecimal string fields as empty fields instead of as "-1". **-n** produce numeric output for fields that normally have symbolic output, such as enctypes and flag names. Also requests output of time stamps as decimal POSIX time_t values. **-o** *outfile* write the dump to the specified output file instead of to standard output Dump types: **alias** principal alias information **aliasname** the name of the alias **targetname** the target of the alias **keydata** principal encryption key information, including actual key data (which is still encrypted in the master key) **name** principal name **keyindex** index of this key in the principal's key list **kvno** key version number **enctype** encryption type **key** key data as a hexadecimal string **salttype** salt type **salt** salt data as a hexadecimal string **keyinfo** principal encryption key information (as in **keydata** above), excluding actual key data **princ_flags** principal boolean attributes. Flag names print as hexadecimal numbers if the **-n** option is specified, and all flag positions are printed regardless of whether or not they are set. If **-n** is not specified, print all known flag names for each principal, but only print hexadecimal flag names if the corresponding flag is set. **name** principal name **flag** flag name **value** boolean value (0 for clear, or 1 for set) **princ_lockout** state information used for tracking repeated password failures **name** principal name **last_success** time stamp of most recent successful authentication **last_failed** time stamp of most recent failed authentication **fail_count** count of failed attempts **princ_meta** principal metadata **name** principal name **modby** name of last principal to modify this principal **modtime** timestamp of last modification **lastpwd** timestamp of last password change **policy** policy object name **mkvno** key version number of the master key that encrypts this principal's key data **hist_kvno** key version number of the history key that encrypts the key history data for this principal **princ_stringattrs** string attributes (key/value pairs) **name** principal name **key** attribute name **value** attribute value **princ_tktpolicy** per-principal ticket policy data, including maximum ticket lifetimes **name** principal name **expiration** principal expiration date **pw_expiration** password expiration date **max_life** maximum ticket lifetime **max_renew_life** maximum renewable ticket lifetime Examples:: $ kdb5_util tabdump -o keyinfo.txt keyinfo $ cat keyinfo.txt name keyindex kvno enctype salttype salt K/M@EXAMPLE.COM 0 1 aes256-cts-hmac-sha384-192 normal -1 foo@EXAMPLE.COM 0 1 aes128-cts-hmac-sha1-96 normal -1 bar@EXAMPLE.COM 0 1 aes128-cts-hmac-sha1-96 normal -1 $ sqlite3 sqlite> .mode tabs sqlite> .import keyinfo.txt keyinfo sqlite> select * from keyinfo where enctype like 'aes256-%'; K/M@EXAMPLE.COM 1 1 aes256-cts-hmac-sha384-192 normal -1 sqlite> .quit $ awk -F'\t' '$4 ~ /aes256-/ { print }' keyinfo.txt K/M@EXAMPLE.COM 1 1 aes256-cts-hmac-sha384-192 normal -1 ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/admin/admin_commands/sserver.rst0000664000175000017500000000623515051422640021400 0ustar ghudsonghudson.. _sserver(8): sserver ======= SYNOPSIS -------- **sserver** [ **-p** *port* ] [ **-S** *keytab* ] [ *server_port* ] DESCRIPTION ----------- sserver and :ref:`sclient(1)` are a simple demonstration client/server application. When sclient connects to sserver, it performs a Kerberos authentication, and then sserver returns to sclient the Kerberos principal which was used for the Kerberos authentication. It makes a good test that Kerberos has been successfully installed on a machine. The service name used by sserver and sclient is sample. Hence, sserver will require that there be a keytab entry for the service ``sample/hostname.domain.name@REALM.NAME``. This keytab is generated using the :ref:`kadmin(1)` program. The keytab file is usually installed as |keytab|. The **-S** option allows for a different keytab than the default. sserver is normally invoked out of inetd(8), using a line in ``/etc/inetd.conf`` that looks like this:: sample stream tcp nowait root /usr/local/sbin/sserver sserver Since ``sample`` is normally not a port defined in ``/etc/services``, you will usually have to add a line to ``/etc/services`` which looks like this:: sample 13135/tcp When using sclient, you will first have to have an entry in the Kerberos database, by using :ref:`kadmin(1)`, and then you have to get Kerberos tickets, by using :ref:`kinit(1)`. Also, if you are running the sclient program on a different host than the sserver it will be connecting to, be sure that both hosts have an entry in /etc/services for the sample tcp port, and that the same port number is in both files. When you run sclient you should see something like this:: sendauth succeeded, reply is: reply len 32, contents: You are nlgilman@JIMI.MIT.EDU COMMON ERROR MESSAGES --------------------- 1) kinit returns the error:: kinit: Client not found in Kerberos database while getting initial credentials This means that you didn't create an entry for your username in the Kerberos database. 2) sclient returns the error:: unknown service sample/tcp; check /etc/services This means that you don't have an entry in /etc/services for the sample tcp port. 3) sclient returns the error:: connect: Connection refused This probably means you didn't edit /etc/inetd.conf correctly, or you didn't restart inetd after editing inetd.conf. 4) sclient returns the error:: sclient: Server not found in Kerberos database while using sendauth This means that the ``sample/hostname@LOCAL.REALM`` service was not defined in the Kerberos database; it should be created using :ref:`kadmin(1)`, and a keytab file needs to be generated to make the key for that service principal available for sclient. 5) sclient returns the error:: sendauth rejected, error reply is: "No such file or directory" This probably means sserver couldn't find the keytab file. It was probably not installed in the proper directory. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`sclient(1)`, :ref:`kerberos(7)`, services(5), inetd(8) krb5-1.22.1/doc/admin/admin_commands/krb5kdc.rst0000664000175000017500000001005515051422640021227 0ustar ghudsonghudson.. _krb5kdc(8): krb5kdc ======= SYNOPSIS -------- **krb5kdc** [**-x** *db_args*] [**-d** *dbname*] [**-k** *keytype*] [**-M** *mkeyname*] [**-p** *portnum*] [**-m**] [**-r** *realm*] [**-n**] [**-w** *numworkers*] [**-P** *pid_file*] [**-T** *time_offset*] DESCRIPTION ----------- krb5kdc is the Kerberos version 5 Authentication Service and Key Distribution Center (AS/KDC). OPTIONS ------- The **-r** *realm* option specifies the realm for which the server should provide service. This option may be specified multiple times to serve multiple realms. If no **-r** option is given, the default realm (as specified in :ref:`krb5.conf(5)`) will be served. The **-d** *dbname* option specifies the name under which the principal database can be found. This option does not apply to the LDAP database. The **-k** *keytype* option specifies the key type of the master key to be entered manually as a password when **-m** is given; the default is |defmkey|. The **-M** *mkeyname* option specifies the principal name for the master key in the database (usually ``K/M`` in the KDC's realm). The **-m** option specifies that the master database password should be fetched from the keyboard rather than from a stash file. The **-n** option specifies that the KDC does not put itself in the background and does not disassociate itself from the terminal. The **-P** *pid_file* option tells the KDC to write its PID into *pid_file* after it starts up. This can be used to identify whether the KDC is still running and to allow init scripts to stop the correct process. The **-p** *portnum* option specifies the default UDP and TCP port numbers which the KDC should listen on for Kerberos version 5 requests, as a comma-separated list. This value overrides the port numbers specified in the :ref:`kdcdefaults` section of :ref:`kdc.conf(5)`, but may be overridden by realm-specific values. If no value is given from any source, the default port is 88. The **-w** *numworkers* option tells the KDC to fork *numworkers* processes to listen to the KDC ports and process requests in parallel. The top level KDC process (whose pid is recorded in the pid file if the **-P** option is also given) acts as a supervisor. The supervisor will relay SIGHUP signals to the worker subprocesses, and will terminate the worker subprocess if the it is itself terminated or if any other worker process exits. The **-x** *db_args* option specifies database-specific arguments. See :ref:`Database Options ` in :ref:`kadmin(1)` for supported arguments. The **-T** *offset* option specifies a time offset, in seconds, which the KDC will operate under. It is intended only for testing purposes. EXAMPLE ------- The KDC may service requests for multiple realms (maximum 32 realms). The realms are listed on the command line. Per-realm options that can be specified on the command line pertain for each realm that follows it and are superseded by subsequent definitions of the same option. For example:: krb5kdc -p 2001 -r REALM1 -p 2002 -r REALM2 -r REALM3 specifies that the KDC listen on port 2001 for REALM1 and on port 2002 for REALM2 and REALM3. Additionally, per-realm parameters may be specified in the :ref:`kdc.conf(5)` file. The location of this file may be specified by the **KRB5_KDC_PROFILE** environment variable. Per-realm parameters specified in this file take precedence over options specified on the command line. See the :ref:`kdc.conf(5)` description for further details. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. As of release 1.22, krb5kdc supports systemd socket activation via the LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by the caller must correspond to configured listener addresses (via the **kdc_listen** variable or equivalent) or they will be ignored. Any configured listener addresses that do not correspond to caller-provided sockets will be ignored if socket activation is used. SEE ALSO -------- :ref:`kdb5_util(8)`, :ref:`kdc.conf(5)`, :ref:`krb5.conf(5)`, :ref:`kdb5_ldap_util(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/admin/admin_commands/kadmin_local.rst0000664000175000017500000007466515051422640022340 0ustar ghudsonghudson.. _kadmin(1): kadmin ====== SYNOPSIS -------- .. _kadmin_synopsis: **kadmin** [**-O**\|\ **-N**] [**-r** *realm*] [**-p** *principal*] [**-q** *query*] [[**-c** *cache_name*]\|[**-k** [**-t** *keytab*]]\|\ **-n**] [**-w** *password*] [**-s** *admin_server*\ [:*port*]] [command args...] **kadmin.local** [**-r** *realm*] [**-p** *principal*] [**-q** *query*] [**-d** *dbname*] [**-e** *enc*:*salt* ...] [**-m**] [**-x** *db_args*] [command args...] DESCRIPTION ----------- kadmin and kadmin.local are command-line interfaces to the Kerberos V5 administration system. They provide nearly identical functionalities; the difference is that kadmin.local directly accesses the KDC database, while kadmin performs operations using :ref:`kadmind(8)`. Except as explicitly noted otherwise, this man page will use "kadmin" to refer to both versions. kadmin provides for the maintenance of Kerberos principals, password policies, and service key tables (keytabs). The remote kadmin client uses Kerberos to authenticate to kadmind using the service principal ``kadmin/admin`` or ``kadmin/ADMINHOST`` (where *ADMINHOST* is the fully-qualified hostname of the admin server). If the credentials cache contains a ticket for one of these principals, and the **-c** credentials_cache option is specified, that ticket is used to authenticate to kadmind. Otherwise, the **-p** and **-k** options are used to specify the client Kerberos principal name used to authenticate. Once kadmin has determined the principal name, it requests a service ticket from the KDC, and uses that service ticket to authenticate to kadmind. Since kadmin.local directly accesses the KDC database, it usually must be run directly on the primary KDC with sufficient permissions to read the KDC database. If the KDC database uses the LDAP database module, kadmin.local can be run on any host which can access the LDAP server. OPTIONS ------- .. _kadmin_options: **-r** *realm* Use *realm* as the default database realm. **-p** *principal* Use *principal* to authenticate. Otherwise, kadmin will append ``/admin`` to the primary principal name of the default ccache, the value of the **USER** environment variable, or the username as obtained with getpwuid, in order of preference. **-k** Use a keytab to decrypt the KDC response instead of prompting for a password. In this case, the default principal will be ``host/hostname``. If there is no keytab specified with the **-t** option, then the default keytab will be used. **-t** *keytab* Use *keytab* to decrypt the KDC response. This can only be used with the **-k** option. **-n** Requests anonymous processing. Two types of anonymous principals are supported. For fully anonymous Kerberos, configure PKINIT on the KDC and configure **pkinit_anchors** in the client's :ref:`krb5.conf(5)`. Then use the **-n** option with a principal of the form ``@REALM`` (an empty principal name followed by the at-sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. A second form of anonymous tickets is supported; these realm-exposed tickets hide the identity of the client but not the client's realm. For this mode, use ``kinit -n`` with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation. **-c** *credentials_cache* Use *credentials_cache* as the credentials cache. The cache should contain a service ticket for the ``kadmin/admin`` or ``kadmin/ADMINHOST`` (where *ADMINHOST* is the fully-qualified hostname of the admin server) service; it can be acquired with the :ref:`kinit(1)` program. If this option is not specified, kadmin requests a new service ticket from the KDC, and stores it in its own temporary ccache. **-w** *password* Use *password* instead of prompting for one. Use this option with care, as it may expose the password to other users on the system via the process list. **-q** *query* Perform the specified query and then exit. **-d** *dbname* Specifies the name of the KDC database. This option does not apply to the LDAP database module. **-s** *admin_server*\ [:*port*] Specifies the admin server which kadmin should contact. **-m** If using kadmin.local, prompt for the database master password instead of reading it from a stash file. **-e** "*enc*:*salt* ..." Sets the keysalt list to be used for any new keys created. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of possible values. **-O** Force use of old AUTH_GSSAPI authentication flavor. **-N** Prevent fallback to AUTH_GSSAPI authentication flavor. **-x** *db_args* Specifies the database specific arguments. See the next section for supported options. Starting with release 1.14, if any command-line arguments remain after the options, they will be treated as a single query to be executed. This mode of operation is intended for scripts and behaves differently from the interactive mode in several respects: * Query arguments are split by the shell, not by kadmin. * Informational and warning messages are suppressed. Error messages and query output (e.g. for **get_principal**) will still be displayed. * Confirmation prompts are disabled (as if **-force** was given). Password prompts will still be issued as required. * The exit status will be non-zero if the query fails. The **-q** option does not carry these behavior differences; the query will be processed as if it was entered interactively. The **-q** option cannot be used in combination with a query in the remaining arguments. .. _dboptions: DATABASE OPTIONS ---------------- Database options can be used to override database-specific defaults. Supported options for the DB2 module are: **-x dbname=**\ \*filename* Specifies the base filename of the DB2 database. **-x lockiter** Make iteration operations hold the lock for the duration of the entire operation, rather than temporarily releasing the lock while handling each principal. This is the default behavior, but this option exists to allow command line override of a [dbmodules] setting. First introduced in release 1.13. **-x unlockiter** Make iteration operations unlock the database for each principal, instead of holding the lock for the duration of the entire operation. First introduced in release 1.13. Supported options for the LDAP module are: **-x host=**\ *ldapuri* Specifies the LDAP server to connect to by a LDAP URI. **-x binddn=**\ *bind_dn* Specifies the DN used to bind to the LDAP server. **-x bindpwd=**\ *password* Specifies the password or SASL secret used to bind to the LDAP server. Using this option may expose the password to other users on the system via the process list; to avoid this, instead stash the password using the **stashsrvpw** command of :ref:`kdb5_ldap_util(8)`. **-x sasl_mech=**\ *mechanism* Specifies the SASL mechanism used to bind to the LDAP server. The bind DN is ignored if a SASL mechanism is used. New in release 1.13. **-x sasl_authcid=**\ *name* Specifies the authentication name used when binding to the LDAP server with a SASL mechanism, if the mechanism requires one. New in release 1.13. **-x sasl_authzid=**\ *name* Specifies the authorization name used when binding to the LDAP server with a SASL mechanism. New in release 1.13. **-x sasl_realm=**\ *realm* Specifies the realm used when binding to the LDAP server with a SASL mechanism, if the mechanism uses one. New in release 1.13. **-x debug=**\ *level* sets the OpenLDAP client library debug level. *level* is an integer to be interpreted by the library. Debugging messages are printed to standard error. New in release 1.12. COMMANDS -------- When using the remote client, available commands may be restricted according to the privileges specified in the :ref:`kadm5.acl(5)` file on the admin server. .. _add_principal: add_principal ~~~~~~~~~~~~~ **add_principal** [*options*] *newprinc* Creates the principal *newprinc*, prompting twice for a password. If no password policy is specified with the **-policy** option, and the policy named ``default`` is assigned to the principal if it exists. However, creating a policy named ``default`` will not automatically assign this policy to previously existing principals. This policy assignment can be suppressed with the **-clearpolicy** option. This command requires the **add** privilege. Aliases: **addprinc**, **ank** Options: **-expire** *expdate* (:ref:`getdate` string) The expiration date of the principal. **-pwexpire** *pwexpdate* (:ref:`getdate` string) The password expiration date. **-maxlife** *maxlife* (:ref:`duration` or :ref:`getdate` string) The maximum ticket life for the principal. **-maxrenewlife** *maxrenewlife* (:ref:`duration` or :ref:`getdate` string) The maximum renewable life of tickets for the principal. **-kvno** *kvno* The initial key version number. **-policy** *policy* The password policy used by this principal. If not specified, the policy ``default`` is used if it exists (unless **-clearpolicy** is specified). **-clearpolicy** Prevents any policy from being assigned when **-policy** is not specified. {-\|+}\ **allow_postdated** **-allow_postdated** prohibits this principal from obtaining postdated tickets. **+allow_postdated** clears this flag. {-\|+}\ **allow_forwardable** **-allow_forwardable** prohibits this principal from obtaining forwardable tickets. **+allow_forwardable** clears this flag. {-\|+}\ **allow_renewable** **-allow_renewable** prohibits this principal from obtaining renewable tickets. **+allow_renewable** clears this flag. {-\|+}\ **allow_proxiable** **-allow_proxiable** prohibits this principal from obtaining proxiable tickets. **+allow_proxiable** clears this flag. {-\|+}\ **allow_dup_skey** **-allow_dup_skey** disables user-to-user authentication for this principal by prohibiting others from obtaining a service ticket encrypted in this principal's TGT session key. **+allow_dup_skey** clears this flag. {-\|+}\ **requires_preauth** **+requires_preauth** requires this principal to preauthenticate before being allowed to kinit. **-requires_preauth** clears this flag. When **+requires_preauth** is set on a service principal, the KDC will only issue service tickets for that service principal if the client's initial authentication was performed using preauthentication. {-\|+}\ **requires_hwauth** **+requires_hwauth** requires this principal to preauthenticate using a hardware device before being allowed to kinit. **-requires_hwauth** clears this flag. When **+requires_hwauth** is set on a service principal, the KDC will only issue service tickets for that service principal if the client's initial authentication was performed using a hardware device to preauthenticate. {-\|+}\ **ok_as_delegate** **+ok_as_delegate** sets the **okay as delegate** flag on tickets issued with this principal as the service. Clients may use this flag as a hint that credentials should be delegated when authenticating to the service. **-ok_as_delegate** clears this flag. {-\|+}\ **allow_svr** **-allow_svr** prohibits the issuance of service tickets for this principal. In release 1.17 and later, user-to-user service tickets are still allowed unless the **-allow_dup_skey** flag is also set. **+allow_svr** clears this flag. {-\|+}\ **allow_tgs_req** **-allow_tgs_req** specifies that a Ticket-Granting Service (TGS) request for a service ticket for this principal is not permitted. **+allow_tgs_req** clears this flag. {-\|+}\ **allow_tix** **-allow_tix** forbids the issuance of any tickets for this principal. **+allow_tix** clears this flag. {-\|+}\ **needchange** **+needchange** forces a password change on the next initial authentication to this principal. **-needchange** clears this flag. {-\|+}\ **password_changing_service** **+password_changing_service** marks this principal as a password change service principal. {-\|+}\ **ok_to_auth_as_delegate** **+ok_to_auth_as_delegate** allows this principal to acquire forwardable tickets to itself from arbitrary users, for use with constrained delegation. {-\|+}\ **no_auth_data_required** **+no_auth_data_required** prevents PAC or AD-SIGNEDPATH data from being added to service tickets for the principal. {-\|+}\ **lockdown_keys** **+lockdown_keys** prevents keys for this principal from leaving the KDC via kadmind. The chpass and extract operations are denied for a principal with this attribute. The chrand operation is allowed, but will not return the new keys. The delete and rename operations are also denied if this attribute is set, in order to prevent a malicious administrator from replacing principals like krbtgt/* or kadmin/* with new principals without the attribute. This attribute can be set via the network protocol, but can only be removed using kadmin.local. **-randkey** Sets the key of the principal to a random value. **-nokey** Causes the principal to be created with no key. New in release 1.12. **-pw** *password* Sets the password of the principal to the specified string and does not prompt for a password. Note: using this option in a shell script may expose the password to other users on the system via the process list. **-e** *enc*:*salt*,... Uses the specified keysalt list for setting the keys of the principal. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of possible values. **-x** *db_princ_args* Indicates database-specific options. The options for the LDAP database module are: **-x dn=**\ *dn* Specifies the LDAP object that will contain the Kerberos principal being created. **-x linkdn=**\ *dn* Specifies the LDAP object to which the newly created Kerberos principal object will point. **-x containerdn=**\ *container_dn* Specifies the container object under which the Kerberos principal is to be created. **-x tktpolicy=**\ *policy* Associates a ticket policy to the Kerberos principal. .. note:: - The **containerdn** and **linkdn** options cannot be specified with the **dn** option. - If the *dn* or *containerdn* options are not specified while adding the principal, the principals are created under the principal container configured in the realm or the realm container. - *dn* and *containerdn* should be within the subtrees or principal container configured in the realm. Example:: kadmin: addprinc jennifer No policy specified for "jennifer@ATHENA.MIT.EDU"; defaulting to no policy. Enter password for principal jennifer@ATHENA.MIT.EDU: Re-enter password for principal jennifer@ATHENA.MIT.EDU: Principal "jennifer@ATHENA.MIT.EDU" created. kadmin: .. _modify_principal: modify_principal ~~~~~~~~~~~~~~~~ **modify_principal** [*options*] *principal* Modifies the specified principal, changing the fields as specified. The options to **add_principal** also apply to this command, except for the **-randkey**, **-pw**, and **-e** options. In addition, the option **-clearpolicy** will clear the current policy of a principal. This command requires the *modify* privilege. Alias: **modprinc** Options (in addition to the **addprinc** options): **-unlock** Unlocks a locked principal (one which has received too many failed authentication attempts without enough time between them according to its password policy) so that it can successfully authenticate. .. _rename_principal: rename_principal ~~~~~~~~~~~~~~~~ **rename_principal** [**-force**] *old_principal* *new_principal* Renames the specified *old_principal* to *new_principal*. This command prompts for confirmation, unless the **-force** option is given. This command requires the **add** and **delete** privileges. Alias: **renprinc** .. _add_alias: add_alias ~~~~~~~~~ **add_alias** *alias_princ* *target_princ* Create an alias *alias_princ* pointing to *target_princ*. Aliases may be chained (that is, *target_princ* may itself be an alias) up to a depth of 10. This command requires the **add** privilege for *alias_princ* and the **modify** privilege for *target_princ*. (New in release 1.22.) Aliases: **alias** .. _delete_principal: delete_principal ~~~~~~~~~~~~~~~~ **delete_principal** [**-force**] *principal* Deletes the specified *principal* or alias from the database. This command prompts for deletion, unless the **-force** option is given. This command requires the **delete** privilege. Alias: **delprinc** .. _change_password: change_password ~~~~~~~~~~~~~~~ **change_password** [*options*] *principal* Changes the password of *principal*. Prompts for a new password if neither **-randkey** or **-pw** is specified. This command requires the **changepw** privilege, or that the principal running the program is the same as the principal being changed. Alias: **cpw** The following options are available: **-randkey** Sets the key of the principal to a random value. **-pw** *password* Set the password to the specified string. Using this option in a script may expose the password to other users on the system via the process list. **-e** *enc*:*salt*,... Uses the specified keysalt list for setting the keys of the principal. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of possible values. **-keepold** Keeps the existing keys in the database. This flag is usually not necessary except perhaps for ``krbtgt`` principals. Example:: kadmin: cpw systest Enter password for principal systest@BLEEP.COM: Re-enter password for principal systest@BLEEP.COM: Password for systest@BLEEP.COM changed. kadmin: .. _purgekeys: purgekeys ~~~~~~~~~ **purgekeys** [**-all**\|\ **-keepkvno** *oldest_kvno_to_keep*] *principal* Purges previously retained old keys (e.g., from **change_password -keepold**) from *principal*. If **-keepkvno** is specified, then only purges keys with kvnos lower than *oldest_kvno_to_keep*. If **-all** is specified, then all keys are purged. The **-all** option is new in release 1.12. This command requires the **modify** privilege. .. _get_principal: get_principal ~~~~~~~~~~~~~ **get_principal** [**-terse**] *principal* Gets the attributes of principal. With the **-terse** option, outputs fields as quoted tab-separated strings. This command requires the **inquire** privilege, or that the principal running the the program to be the same as the one being listed. Alias: **getprinc** Examples:: kadmin: getprinc tlyu/admin Principal: tlyu/admin@BLEEP.COM Expiration date: [never] Last password change: Mon Aug 12 14:16:47 EDT 1996 Password expiration date: [never] Maximum ticket life: 0 days 10:00:00 Maximum renewable life: 7 days 00:00:00 Last modified: Mon Aug 12 14:16:47 EDT 1996 (bjaspan/admin@BLEEP.COM) Last successful authentication: [never] Last failed authentication: [never] Failed password attempts: 0 Number of keys: 1 Key: vno 1, aes256-cts-hmac-sha384-192 MKey: vno 1 Attributes: Policy: [none] kadmin: getprinc -terse systest systest@BLEEP.COM 3 86400 604800 1 785926535 753241234 785900000 tlyu/admin@BLEEP.COM 786100034 0 0 kadmin: .. _list_principals: list_principals ~~~~~~~~~~~~~~~ **list_principals** [*expression*] Retrieves all or some principal names. *expression* is a shell-style glob expression that can contain the wild-card characters ``?``, ``*``, and ``[]``. All principal names matching the expression are printed. If no expression is provided, all principal names are printed. If the expression does not contain an ``@`` character, an ``@`` character followed by the local realm is appended to the expression. This command requires the **list** privilege. Alias: **listprincs**, **get_principals**, **getprincs** Example:: kadmin: listprincs test* test3@SECURE-TEST.OV.COM test2@SECURE-TEST.OV.COM test1@SECURE-TEST.OV.COM testuser@SECURE-TEST.OV.COM kadmin: .. _get_strings: get_strings ~~~~~~~~~~~ **get_strings** *principal* Displays string attributes on *principal*. This command requires the **inquire** privilege. Alias: **getstrs** .. _set_string: set_string ~~~~~~~~~~ **set_string** *principal* *name* *value* Sets a string attribute on *principal*. String attributes are used to supply per-principal configuration to the KDC and some KDC plugin modules. The following string attribute names are recognized by the KDC: **require_auth** Specifies an authentication indicator which is required to authenticate to the principal as a service. Multiple indicators can be specified, separated by spaces; in this case any of the specified indicators will be accepted. (New in release 1.14.) **session_enctypes** Specifies the encryption types supported for session keys when the principal is authenticated to as a server. See :ref:`Encryption_types` in :ref:`kdc.conf(5)` for a list of the accepted values. **otp** Enables One Time Passwords (OTP) preauthentication for a client *principal*. The *value* is a JSON string representing an array of objects, each having optional ``type`` and ``username`` fields. **pkinit_cert_match** Specifies a matching expression that defines the certificate attributes required for the client certificate used by the principal during PKINIT authentication. The matching expression is in the same format as those used by the **pkinit_cert_match** option in :ref:`krb5.conf(5)`. (New in release 1.16.) **pac_privsvr_enctype** Forces the encryption type of the PAC KDC checksum buffers to the specified encryption type for tickets issued to this server, by deriving a key from the local krbtgt key if it is of a different encryption type. It may be necessary to set this value to "aes256-sha1" on the cross-realm krbtgt entry for an Active Directory realm when using aes-sha2 keys on the local krbtgt entry. This command requires the **modify** privilege. Alias: **setstr** Example:: set_string host/foo.mit.edu session_enctypes aes128-cts set_string user@FOO.COM otp "[{""type"":""hotp"",""username"":""al""}]" .. _del_string: del_string ~~~~~~~~~~ **del_string** *principal* *key* Deletes a string attribute from *principal*. This command requires the **delete** privilege. Alias: **delstr** .. _add_policy: add_policy ~~~~~~~~~~ **add_policy** [*options*] *policy* Adds a password policy named *policy* to the database. This command requires the **add** privilege. Alias: **addpol** The following options are available: **-maxlife** *time* (:ref:`duration` or :ref:`getdate` string) Sets the maximum lifetime of a password. **-minlife** *time* (:ref:`duration` or :ref:`getdate` string) Sets the minimum lifetime of a password. **-minlength** *length* Sets the minimum length of a password. **-minclasses** *number* Sets the minimum number of character classes required in a password. The five character classes are lower case, upper case, numbers, punctuation, and whitespace/unprintable characters. **-history** *number* Sets the number of past keys kept for a principal. This option is not supported with the LDAP KDC database module. .. _policy_maxfailure: **-maxfailure** *maxnumber* Sets the number of authentication failures before the principal is locked. Authentication failures are only tracked for principals which require preauthentication. The counter of failed attempts resets to 0 after a successful attempt to authenticate. A *maxnumber* value of 0 (the default) disables lockout. .. _policy_failurecountinterval: **-failurecountinterval** *failuretime* (:ref:`duration` or :ref:`getdate` string) Sets the allowable time between authentication failures. If an authentication failure happens after *failuretime* has elapsed since the previous failure, the number of authentication failures is reset to 1. A *failuretime* value of 0 (the default) means forever. .. _policy_lockoutduration: **-lockoutduration** *lockouttime* (:ref:`duration` or :ref:`getdate` string) Sets the duration for which the principal is locked from authenticating if too many authentication failures occur without the specified failure count interval elapsing. A duration of 0 (the default) means the principal remains locked out until it is administratively unlocked with ``modprinc -unlock``. **-allowedkeysalts** Specifies the key/salt tuples supported for long-term keys when setting or changing a principal's password/keys. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of the accepted values, but note that key/salt tuples must be separated with commas (',') only. To clear the allowed key/salt policy use a value of '-'. Example:: kadmin: add_policy -maxlife "2 days" -minlength 5 guests kadmin: .. _modify_policy: modify_policy ~~~~~~~~~~~~~ **modify_policy** [*options*] *policy* Modifies the password policy named *policy*. Options are as described for **add_policy**. This command requires the **modify** privilege. Alias: **modpol** .. _delete_policy: delete_policy ~~~~~~~~~~~~~ **delete_policy** [**-force**] *policy* Deletes the password policy named *policy*. Prompts for confirmation before deletion. The command will fail if the policy is in use by any principals. This command requires the **delete** privilege. Alias: **delpol** Example:: kadmin: del_policy guests Are you sure you want to delete the policy "guests"? (yes/no): yes kadmin: .. _get_policy: get_policy ~~~~~~~~~~ **get_policy** [ **-terse** ] *policy* Displays the values of the password policy named *policy*. With the **-terse** flag, outputs the fields as quoted strings separated by tabs. This command requires the **inquire** privilege. Alias: **getpol** Examples:: kadmin: get_policy admin Policy: admin Maximum password life: 180 days 00:00:00 Minimum password life: 00:00:00 Minimum password length: 6 Minimum number of password character classes: 2 Number of old keys kept: 5 Reference count: 17 kadmin: get_policy -terse admin admin 15552000 0 6 2 5 17 kadmin: The "Reference count" is the number of principals using that policy. With the LDAP KDC database module, the reference count field is not meaningful. .. _list_policies: list_policies ~~~~~~~~~~~~~ **list_policies** [*expression*] Retrieves all or some policy names. *expression* is a shell-style glob expression that can contain the wild-card characters ``?``, ``*``, and ``[]``. All policy names matching the expression are printed. If no expression is provided, all existing policy names are printed. This command requires the **list** privilege. Aliases: **listpols**, **get_policies**, **getpols**. Examples:: kadmin: listpols test-pol dict-only once-a-min test-pol-nopw kadmin: listpols t* test-pol test-pol-nopw kadmin: .. _ktadd: ktadd ~~~~~ | **ktadd** [options] *principal* | **ktadd** [options] **-glob** *princ-exp* Adds a *principal*, or all principals matching *princ-exp*, to a keytab file. Each principal's keys are randomized in the process. The rules for *princ-exp* are described in the **list_principals** command. This command requires the **inquire** and **changepw** privileges. With the **-glob** form, it also requires the **list** privilege. The options are: **-k[eytab]** *keytab* Use *keytab* as the keytab file. Otherwise, the default keytab is used. **-e** *enc*:*salt*,... Uses the specified keysalt list for setting the new keys of the principal. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of possible values. **-q** Display less verbose information. **-norandkey** Do not randomize the keys. The keys and their version numbers stay unchanged. This option cannot be specified in combination with the **-e** option. An entry for each of the principal's unique encryption types is added, ignoring multiple keys with the same encryption type but different salt types. Alias: **xst** Example:: kadmin: ktadd -k /tmp/foo-new-keytab host/foo.mit.edu Entry for principal host/foo.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/tmp/foo-new-keytab kadmin: .. _ktremove: ktremove ~~~~~~~~ **ktremove** [options] *principal* [*kvno* | *all* | *old*] Removes entries for the specified *principal* from a keytab. Requires no permissions, since this does not require database access. If the string "all" is specified, all entries for that principal are removed; if the string "old" is specified, all entries for that principal except those with the highest kvno are removed. Otherwise, the value specified is parsed as an integer, and all entries whose kvno match that integer are removed. The options are: **-k[eytab]** *keytab* Use *keytab* as the keytab file. Otherwise, the default keytab is used. **-q** Display less verbose information. Alias: **ktrem** Example:: kadmin: ktremove kadmin/admin all Entry for principal kadmin/admin with kvno 3 removed from keytab FILE:/etc/krb5.keytab kadmin: lock ~~~~ Lock database exclusively. Use with extreme caution! This command only works with the DB2 KDC database module. unlock ~~~~~~ Release the exclusive database lock. list_requests ~~~~~~~~~~~~~ Lists available for kadmin requests. Aliases: **lr**, **?** quit ~~~~ Exit program. If the database was locked, the lock is released. Aliases: **exit**, **q** HISTORY ------- The kadmin program was originally written by Tom Yu at MIT, as an interface to the OpenVision Kerberos administration program. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kpasswd(1)`, :ref:`kadmind(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/admin/admin_commands/kadmind.rst0000664000175000017500000001127415051422640021315 0ustar ghudsonghudson.. _kadmind(8): kadmind ======= SYNOPSIS -------- **kadmind** [**-x** *db_args*] [**-r** *realm*] [**-m**] [**-nofork**] [**-proponly**] [**-port** *port-number*] [**-P** *pid_file*] [**-p** *kdb5_util_path*] [**-K** *kprop_path*] [**-k** *kprop_port*] [**-F** *dump_file*] DESCRIPTION ----------- kadmind starts the Kerberos administration server. kadmind typically runs on the primary Kerberos server, which stores the KDC database. If the KDC database uses the LDAP module, the administration server and the KDC server need not run on the same machine. kadmind accepts remote requests from programs such as :ref:`kadmin(1)` and :ref:`kpasswd(1)` to administer the information in these database. kadmind requires a number of configuration files to be set up in order for it to work: :ref:`kdc.conf(5)` The KDC configuration file contains configuration information for the KDC and admin servers. kadmind uses settings in this file to locate the Kerberos database, and is also affected by the **acl_file**, **dict_file**, **kadmind_port**, and iprop-related settings. :ref:`kadm5.acl(5)` kadmind's ACL (access control list) tells it which principals are allowed to perform administration actions. The pathname to the ACL file can be specified with the **acl_file** :ref:`kdc.conf(5)` variable; by default, it is |kdcdir|\ ``/kadm5.acl``. After the server begins running, it puts itself in the background and disassociates itself from its controlling terminal. kadmind can be configured for incremental database propagation. Incremental propagation allows replica KDC servers to receive principal and policy updates incrementally instead of receiving full dumps of the database. This facility can be enabled in the :ref:`kdc.conf(5)` file with the **iprop_enable** option. Incremental propagation requires the principal ``kiprop/PRIMARY\@REALM`` (where PRIMARY is the primary KDC's canonical host name, and REALM the realm name). In release 1.13, this principal is automatically created and registered into the datebase. OPTIONS ------- **-r** *realm* specifies the realm that kadmind will serve; if it is not specified, the default realm of the host is used. **-m** causes the master database password to be fetched from the keyboard (before the server puts itself in the background, if not invoked with the **-nofork** option) rather than from a file on disk. **-nofork** causes the server to remain in the foreground and remain associated to the terminal. **-proponly** causes the server to only listen and respond to Kerberos replica incremental propagation polling requests. This option can be used to set up a hierarchical propagation topology where a replica KDC provides incremental updates to other Kerberos replicas. **-port** *port-number* specifies the port on which the administration server listens for connections. The default port is determined by the **kadmind_port** configuration variable in :ref:`kdc.conf(5)`. **-P** *pid_file* specifies the file to which the PID of kadmind process should be written after it starts up. This file can be used to identify whether kadmind is still running and to allow init scripts to stop the correct process. **-p** *kdb5_util_path* specifies the path to the kdb5_util command to use when dumping the KDB in response to full resync requests when iprop is enabled. **-K** *kprop_path* specifies the path to the kprop command to use to send full dumps to replicas in response to full resync requests. **-k** *kprop_port* specifies the port by which the kprop process that is spawned by kadmind connects to the replica kpropd, in order to transfer the dump file during an iprop full resync request. **-F** *dump_file* specifies the file path to be used for dumping the KDB in response to full resync requests when iprop is enabled. **-x** *db_args* specifies database-specific arguments. See :ref:`Database Options ` in :ref:`kadmin(1)` for supported arguments. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. As of release 1.22, kadmind supports systemd socket activation via the LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by the caller must correspond to configured listener addresses (via the **kadmind_listen** or **kpasswd_listen** variables or equivalents) or they will be ignored. Any configured listener addresses that do not correspond to caller-provided sockets will be ignored if socket activation is used. SEE ALSO -------- :ref:`kpasswd(1)`, :ref:`kadmin(1)`, :ref:`kdb5_util(8)`, :ref:`kdb5_ldap_util(8)`, :ref:`kadm5.acl(5)`, :ref:`kerberos(7)` krb5-1.22.1/doc/admin/admin_commands/kpropd.rst0000664000175000017500000001104215051422640021176 0ustar ghudsonghudson.. _kpropd(8): kpropd ====== SYNOPSIS -------- **kpropd** [**-r** *realm*] [**-A** *admin_server*] [**-a** *acl_file*] [**-f** *replica_dumpfile*] [**-F** *principal_database*] [**-p** *kdb5_util_prog*] [**-P** *port*] [**--pid-file**\ =\ *pid_file*] [**-D**] [**-d**] [**-s** *keytab_file*] DESCRIPTION ----------- The *kpropd* command runs on the replica KDC server. It listens for update requests made by the :ref:`kprop(8)` program. If incremental propagation is enabled, it periodically requests incremental updates from the primary KDC. When the replica receives a kprop request from the primary, kpropd accepts the dumped KDC database and places it in a file, and then runs :ref:`kdb5_util(8)` to load the dumped database into the active database which is used by :ref:`krb5kdc(8)`. This allows the primary Kerberos server to use :ref:`kprop(8)` to propagate its database to the replica servers. Upon a successful download of the KDC database file, the replica Kerberos server will have an up-to-date KDC database. Where incremental propagation is not used, kpropd is commonly invoked out of inetd(8) as a nowait service. This is done by adding a line to the ``/etc/inetd.conf`` file which looks like this:: kprop stream tcp nowait root /usr/local/sbin/kpropd kpropd kpropd can also run as a standalone daemon, backgrounding itself and waiting for connections on port 754 (or the port specified with the **-P** option if given). Standalone mode is required for incremental propagation. Starting in release 1.11, kpropd automatically detects whether it was run from inetd and runs in standalone mode if it is not. Prior to release 1.11, the **-S** option is required to run kpropd in standalone mode; this option is now accepted for backward compatibility but does nothing. Incremental propagation may be enabled with the **iprop_enable** variable in :ref:`kdc.conf(5)`. If incremental propagation is enabled, the replica periodically polls the primary KDC for updates, at an interval determined by the **iprop_replica_poll** variable. If the replica receives updates, kpropd updates its log file with any updates from the primary. :ref:`kproplog(8)` can be used to view a summary of the update entry log on the replica KDC. If incremental propagation is enabled, the principal ``kiprop/replicahostname@REALM`` (where *replicahostname* is the name of the replica KDC host, and *REALM* is the name of the Kerberos realm) must be present in the replica's keytab file. :ref:`kproplog(8)` can be used to force full replication when iprop is enabled. OPTIONS -------- **-r** *realm* Specifies the realm of the primary server. **-A** *admin_server* Specifies the server to be contacted for incremental updates; by default, the primary admin server is contacted. **-f** *file* Specifies the filename where the dumped principal database file is to be stored; by default the dumped database file is |kdcdir|\ ``/from_master``. **-F** *kerberos_db* Path to the Kerberos database file, if not the default. **-p** Allows the user to specify the pathname to the :ref:`kdb5_util(8)` program; by default the pathname used is |sbindir|\ ``/kdb5_util``. **-D** In this mode, kpropd will not detach itself from the current job and run in the background. Instead, it will run in the foreground. **-d** Turn on debug mode. kpropd will print out debugging messages during the database propogation and will run in the foreground (implies **-D**). **-P** Allow for an alternate port number for kpropd to listen on. This is only useful in combination with the **-S** option. **-a** *acl_file* Allows the user to specify the path to the kpropd.acl file; by default the path used is |kdcdir|\ ``/kpropd.acl``. **--pid-file**\ =\ *pid_file* In standalone mode, write the process ID of the daemon into *pid_file*. **-s** *keytab_file* Path to a keytab to use for acquiring acceptor credentials. **-x** *db_args* Database-specific arguments. See :ref:`Database Options ` in :ref:`kadmin(1)` for supported arguments. FILES ----- kpropd.acl Access file for kpropd; the default location is ``/usr/local/var/krb5kdc/kpropd.acl``. Each entry is a line containing the principal of a host from which the local machine will allow Kerberos database propagation via :ref:`kprop(8)`. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kprop(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)`, :ref:`kerberos(7)`, inetd(8) krb5-1.22.1/doc/admin/admin_commands/kdb5_ldap_util.rst0000664000175000017500000002656115051422640022575 0ustar ghudsonghudson.. _kdb5_ldap_util(8): kdb5_ldap_util =============== SYNOPSIS -------- .. _kdb5_ldap_util_synopsis: **kdb5_ldap_util** [**-D** *user_dn* [**-w** *passwd*]] [**-H** *ldapuri*] **command** [*command_options*] .. _kdb5_ldap_util_synopsis_end: DESCRIPTION ----------- kdb5_ldap_util allows an administrator to manage realms, Kerberos services and ticket policies. COMMAND-LINE OPTIONS -------------------- .. _kdb5_ldap_util_options: **-r** *realm* Specifies the realm to be operated on. **-D** *user_dn* Specifies the Distinguished Name (DN) of the user who has sufficient rights to perform the operation on the LDAP server. **-w** *passwd* Specifies the password of *user_dn*. This option is not recommended. **-H** *ldapuri* Specifies the URI of the LDAP server. By default, kdb5_ldap_util operates on the default realm (as specified in :ref:`krb5.conf(5)`) and connects and authenticates to the LDAP server in the same manner as :ref:kadmind(8)` would given the parameters in :ref:`dbdefaults` in :ref:`kdc.conf(5)`. .. _kdb5_ldap_util_options_end: COMMANDS -------- create ~~~~~~ .. _kdb5_ldap_util_create: **create** [**-subtrees** *subtree_dn_list*] [**-sscope** *search_scope*] [**-containerref** *container_reference_dn*] [**-k** *mkeytype*] [**-kv** *mkeyVNO*] [**-M** *mkeyname*] [**-m|-P** *password*\|\ **-sf** *stashfilename*] [**-s**] [**-maxtktlife** *max_ticket_life*] [**-maxrenewlife** *max_renewable_ticket_life*] [*ticket_flags*] Creates realm in directory. Options: **-subtrees** *subtree_dn_list* Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (``:``). **-sscope** *search_scope* Specifies the scope for searching the principals under the subtree. The possible values are 1 or one (one level), 2 or sub (subtrees). **-containerref** *container_reference_dn* Specifies the DN of the container object in which the principals of a realm will be created. If the container reference is not configured for a realm, the principals will be created in the realm container. **-k** *mkeytype* Specifies the key type of the master key in the database. The default is given by the **master_key_type** variable in :ref:`kdc.conf(5)`. **-kv** *mkeyVNO* Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed. **-M** *mkeyname* Specifies the principal name for the master key in the database. If not specified, the name is determined by the **master_key_name** variable in :ref:`kdc.conf(5)`. **-m** Specifies that the master database password should be read from the TTY rather than fetched from a file on the disk. **-P** *password* Specifies the master database password. This option is not recommended. **-sf** *stashfilename* Specifies the stash file of the master database password. **-s** Specifies that the stash file is to be created. **-maxtktlife** *max_ticket_life* (:ref:`getdate` string) Specifies maximum ticket life for principals in this realm. **-maxrenewlife** *max_renewable_ticket_life* (:ref:`getdate` string) Specifies maximum renewable life of tickets for principals in this realm. *ticket_flags* Specifies global ticket flags for the realm. Allowable flags are documented in the description of the **add_principal** command in :ref:`kadmin(1)`. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU create -subtrees o=org -sscope SUB Password for "cn=admin,o=org": Initializing database for realm 'ATHENA.MIT.EDU' You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter KDC database master key: Re-enter KDC database master key to verify: .. _kdb5_ldap_util_create_end: modify ~~~~~~ .. _kdb5_ldap_util_modify: **modify** [**-subtrees** *subtree_dn_list*] [**-sscope** *search_scope*] [**-containerref** *container_reference_dn*] [**-maxtktlife** *max_ticket_life*] [**-maxrenewlife** *max_renewable_ticket_life*] [*ticket_flags*] Modifies the attributes of a realm. Options: **-subtrees** *subtree_dn_list* Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (``:``). This list replaces the existing list. **-sscope** *search_scope* Specifies the scope for searching the principals under the subtrees. The possible values are 1 or one (one level), 2 or sub (subtrees). **-containerref** *container_reference_dn* Specifies the DN of the container object in which the principals of a realm will be created. **-maxtktlife** *max_ticket_life* (:ref:`getdate` string) Specifies maximum ticket life for principals in this realm. **-maxrenewlife** *max_renewable_ticket_life* (:ref:`getdate` string) Specifies maximum renewable life of tickets for principals in this realm. *ticket_flags* Specifies global ticket flags for the realm. Allowable flags are documented in the description of the **add_principal** command in :ref:`kadmin(1)`. Example:: shell% kdb5_ldap_util -r ATHENA.MIT.EDU -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu modify +requires_preauth Password for "cn=admin,o=org": shell% .. _kdb5_ldap_util_modify_end: view ~~~~ .. _kdb5_ldap_util_view: **view** Displays the attributes of a realm. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU view Password for "cn=admin,o=org": Realm Name: ATHENA.MIT.EDU Subtree: ou=users,o=org Subtree: ou=servers,o=org SearchScope: ONE Maximum ticket life: 0 days 01:00:00 Maximum renewable life: 0 days 10:00:00 Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PWCHANGE .. _kdb5_ldap_util_view_end: destroy ~~~~~~~ .. _kdb5_ldap_util_destroy: **destroy** [**-f**] Destroys an existing realm. Options: **-f** If specified, will not prompt the user for confirmation. Example:: shell% kdb5_ldap_util -r ATHENA.MIT.EDU -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu destroy Password for "cn=admin,o=org": Deleting KDC database of 'ATHENA.MIT.EDU', are you sure? (type 'yes' to confirm)? yes OK, deleting database of 'ATHENA.MIT.EDU'... shell% .. _kdb5_ldap_util_destroy_end: list ~~~~ .. _kdb5_ldap_util_list: **list** Lists the names of realms under the container. Example:: shell% kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu list Password for "cn=admin,o=org": ATHENA.MIT.EDU OPENLDAP.MIT.EDU MEDIA-LAB.MIT.EDU shell% .. _kdb5_ldap_util_list_end: stashsrvpw ~~~~~~~~~~ .. _kdb5_ldap_util_stashsrvpw: **stashsrvpw** [**-f** *filename*] *name* Allows an administrator to store the password for service object in a file so that KDC and Administration server can use it to authenticate to the LDAP server. Options: **-f** *filename* Specifies the complete path of the service password file. By default, ``/usr/local/var/service_passwd`` is used. *name* Specifies the name of the object whose password is to be stored. If :ref:`krb5kdc(8)` or :ref:`kadmind(8)` are configured for simple binding, this should be the distinguished name it will use as given by the **ldap_kdc_dn** or **ldap_kadmind_dn** variable in :ref:`kdc.conf(5)`. If the KDC or kadmind is configured for SASL binding, this should be the authentication name it will use as given by the **ldap_kdc_sasl_authcid** or **ldap_kadmind_sasl_authcid** variable. Example:: kdb5_ldap_util stashsrvpw -f /home/andrew/conf_keyfile cn=service-kdc,o=org Password for "cn=service-kdc,o=org": Re-enter password for "cn=service-kdc,o=org": .. _kdb5_ldap_util_stashsrvpw_end: create_policy ~~~~~~~~~~~~~ .. _kdb5_ldap_util_create_policy: **create_policy** [**-maxtktlife** *max_ticket_life*] [**-maxrenewlife** *max_renewable_ticket_life*] [*ticket_flags*] *policy_name* Creates a ticket policy in the directory. Options: **-maxtktlife** *max_ticket_life* (:ref:`getdate` string) Specifies maximum ticket life for principals. **-maxrenewlife** *max_renewable_ticket_life* (:ref:`getdate` string) Specifies maximum renewable life of tickets for principals. *ticket_flags* Specifies the ticket flags. If this option is not specified, by default, no restriction will be set by the policy. Allowable flags are documented in the description of the **add_principal** command in :ref:`kadmin(1)`. *policy_name* Specifies the name of the ticket policy. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU create_policy -maxtktlife "1 day" -maxrenewlife "1 week" -allow_postdated +needchange -allow_forwardable tktpolicy Password for "cn=admin,o=org": .. _kdb5_ldap_util_create_policy_end: modify_policy ~~~~~~~~~~~~~ .. _kdb5_ldap_util_modify_policy: **modify_policy** [**-maxtktlife** *max_ticket_life*] [**-maxrenewlife** *max_renewable_ticket_life*] [*ticket_flags*] *policy_name* Modifies the attributes of a ticket policy. Options are same as for **create_policy**. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU modify_policy -maxtktlife "60 minutes" -maxrenewlife "10 hours" +allow_postdated -requires_preauth tktpolicy Password for "cn=admin,o=org": .. _kdb5_ldap_util_modify_policy_end: view_policy ~~~~~~~~~~~ .. _kdb5_ldap_util_view_policy: **view_policy** *policy_name* Displays the attributes of the named ticket policy. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU view_policy tktpolicy Password for "cn=admin,o=org": Ticket policy: tktpolicy Maximum ticket life: 0 days 01:00:00 Maximum renewable life: 0 days 10:00:00 Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PWCHANGE .. _kdb5_ldap_util_view_policy_end: destroy_policy ~~~~~~~~~~~~~~ .. _kdb5_ldap_util_destroy_policy: **destroy_policy** [**-force**] *policy_name* Destroys an existing ticket policy. Options: **-force** Forces the deletion of the policy object. If not specified, the user will be prompted for confirmation before deleting the policy. *policy_name* Specifies the name of the ticket policy. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU destroy_policy tktpolicy Password for "cn=admin,o=org": This will delete the policy object 'tktpolicy', are you sure? (type 'yes' to confirm)? yes ** policy object 'tktpolicy' deleted. .. _kdb5_ldap_util_destroy_policy_end: list_policy ~~~~~~~~~~~ .. _kdb5_ldap_util_list_policy: **list_policy** Lists ticket policies. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU list_policy Password for "cn=admin,o=org": tktpolicy tmppolicy userpolicy .. _kdb5_ldap_util_list_policy_end: ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/admin/admin_commands/ktutil.rst0000664000175000017500000000426415051422640021223 0ustar ghudsonghudson.. _ktutil(1): ktutil ====== SYNOPSIS -------- **ktutil** DESCRIPTION ----------- The ktutil command invokes a command interface from which an administrator can read, write, or edit entries in a keytab. (Kerberos V4 srvtab files are no longer supported.) COMMANDS -------- list ~~~~ **list** [**-t**] [**-k**] [**-e**] Displays the current keylist. If **-t**, **-k**, and/or **-e** are specified, also display the timestamp, key contents, or enctype (respectively). Alias: **l** read_kt ~~~~~~~ **read_kt** *keytab* Read the Kerberos V5 keytab file *keytab* into the current keylist. Alias: **rkt** write_kt ~~~~~~~~ **write_kt** *keytab* Write the current keylist into the Kerberos V5 keytab file *keytab*. Alias: **wkt** clear_list ~~~~~~~~~~ **clear_list** Clear the current keylist. Alias: **clear** delete_entry ~~~~~~~~~~~~ **delete_entry** *slot* Delete the entry in slot number *slot* from the current keylist. Alias: **delent** add_entry ~~~~~~~~~ **add_entry** {**-key**\|\ **-password**} **-p** *principal* **-k** *kvno* [**-e** *enctype*] [**-f**\|\ **-s** *salt*] Add *principal* to keylist using key or password. If the **-f** flag is specified, salt information will be fetched from the KDC; in this case the **-e** flag may be omitted, or it may be supplied to force a particular enctype. If the **-f** flag is not specified, the **-e** flag must be specified, and the default salt will be used unless overridden with the **-s** option. Alias: **addent** list_requests ~~~~~~~~~~~~~ **list_requests** Displays a listing of available commands. Aliases: **lr**, **?** quit ~~~~ **quit** Quits ktutil. Aliases: **exit**, **q** EXAMPLE ------- :: ktutil: add_entry -password -p alice@BLEEP.COM -k 1 -e aes128-cts-hmac-sha1-96 Password for alice@BLEEP.COM: ktutil: add_entry -password -p alice@BLEEP.COM -k 1 -e aes256-cts-hmac-sha1-96 Password for alice@BLEEP.COM: ktutil: write_kt alice.keytab ktutil: ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`kdb5_util(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/admin/admin_commands/kproplog.rst0000664000175000017500000000504315051422640021540 0ustar ghudsonghudson.. _kproplog(8): kproplog ======== SYNOPSIS -------- **kproplog** [**-h**] [**-e** *num*] [-v] **kproplog** [-R] DESCRIPTION ----------- The kproplog command displays the contents of the KDC database update log to standard output. It can be used to keep track of incremental updates to the principal database. The update log file contains the update log maintained by the :ref:`kadmind(8)` process on the primary KDC server and the :ref:`kpropd(8)` process on the replica KDC servers. When updates occur, they are logged to this file. Subsequently any KDC replica configured for incremental updates will request the current data from the primary KDC and update their log file with any updates returned. The kproplog command requires read access to the update log file. It will display update entries only for the KDC it runs on. If no options are specified, kproplog displays a summary of the update log. If invoked on the primary, kproplog also displays all of the update entries. If invoked on a replica KDC server, kproplog displays only a summary of the updates, which includes the serial number of the last update received and the associated time stamp of the last update. OPTIONS ------- **-R** Reset the update log. This forces full resynchronization. If used on a replica then that replica will request a full resync. If used on the primary then all replicas will request full resyncs. **-h** Display a summary of the update log. This information includes the database version number, state of the database, the number of updates in the log, the time stamp of the first and last update, and the version number of the first and last update entry. **-e** *num* Display the last *num* update entries in the log. This is useful when debugging synchronization between KDC servers. **-v** Display individual attributes per update. An example of the output generated for one entry:: Update Entry Update serial # : 4 Update operation : Add Update principal : test@EXAMPLE.COM Update size : 424 Update committed : True Update time stamp : Fri Feb 20 23:37:42 2004 Attributes changed : 6 Principal Key data Password last changed Modifying principal Modification time TL data ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kpropd(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/admin/admin_commands/kprop.rst0000664000175000017500000000207515051422640021040 0ustar ghudsonghudson.. _kprop(8): kprop ===== SYNOPSIS -------- **kprop** [**-r** *realm*] [**-f** *file*] [**-d**] [**-P** *port*] [**-s** *keytab*] *replica_host* DESCRIPTION ----------- kprop is used to securely propagate a Kerberos V5 database dump file from the primary Kerberos server to a replica Kerberos server, which is specified by *replica_host*. The dump file must be created by :ref:`kdb5_util(8)`. OPTIONS ------- **-r** *realm* Specifies the realm of the primary server. **-f** *file* Specifies the filename where the dumped principal database file is to be found; by default the dumped database file is normally |kdcdir|\ ``/replica_datatrans``. **-P** *port* Specifies the port to use to contact the :ref:`kpropd(8)` server on the remote host. **-d** Prints debugging information. **-s** *keytab* Specifies the location of the keytab file. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kpropd(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/admin/admin_commands/index.rst0000664000175000017500000000040315051422640021005 0ustar ghudsonghudsonAdministration programs ======================== .. toctree:: :maxdepth: 1 kadmin_local.rst kadmind.rst kdb5_util.rst kdb5_ldap_util.rst krb5kdc.rst kprop.rst kpropd.rst kproplog.rst ktutil.rst k5srvutil.rst sserver.rst krb5-1.22.1/doc/admin/otp.rst0000664000175000017500000000663415051422640015543 0ustar ghudsonghudson.. _otp_preauth: OTP Preauthentication ===================== OTP is a preauthentication mechanism for Kerberos 5 which uses One Time Passwords (OTP) to authenticate the client to the KDC. The OTP is passed to the KDC over an encrypted FAST channel in clear-text. The KDC uses the password along with per-user configuration to proxy the request to a third-party RADIUS system. This enables out-of-the-box compatibility with a large number of already widely deployed proprietary systems. Additionally, our implementation of the OTP system allows for the passing of RADIUS requests over a UNIX domain stream socket. This permits the use of a local companion daemon which can handle the details of authentication. Defining token types -------------------- Token types are defined in either :ref:`krb5.conf(5)` or :ref:`kdc.conf(5)` according to the following format:: [otp] = { server = (default: see below) secret = timeout = (default: 5 [seconds]) retries = (default: 3) strip_realm = (default: true) indicator = (default: none) } If the server field begins with '/', it will be interpreted as a UNIX socket. Otherwise, it is assumed to be in the format host:port. When a UNIX domain socket is specified, the secret field is optional and an empty secret is used by default. If the server field is not specified, it defaults to |kdcrundir|\ ``/.socket``. When forwarding the request over RADIUS, by default the principal is used in the User-Name attribute of the RADIUS packet. The strip_realm parameter controls whether the principal is forwarded with or without the realm portion. If an indicator field is present, tickets issued using this token type will be annotated with the specified authentication indicator (see :ref:`auth_indicator`). This key may be specified multiple times to add multiple indicators. The default token type ---------------------- A default token type is used internally when no token type is specified for a given user. It is defined as follows:: [otp] DEFAULT = { strip_realm = false } The administrator may override the internal ``DEFAULT`` token type simply by defining a configuration with the same name. Token instance configuration ---------------------------- To enable OTP for a client principal, the administrator must define the **otp** string attribute for that principal. (See :ref:`set_string`.) The **otp** user string is a JSON string of the format: .. code-block:: xml [{ "type": , "username": , "indicators": [, ...] }, ...] This is an array of token objects. Both fields of token objects are optional. The **type** field names the token type of this token; if not specified, it defaults to ``DEFAULT``. The **username** field specifies the value to be sent in the User-Name RADIUS attribute. If not specified, the principal name is sent, with or without realm as defined in the token type. The **indicators** field specifies a list of authentication indicators to annotate tickets with, overriding any indicators specified in the token type. For ease of configuration, an empty array (``[]``) is treated as equivalent to one DEFAULT token (``[{}]``). Other considerations -------------------- #. FAST is required for OTP to work. krb5-1.22.1/doc/admin/spake.rst0000664000175000017500000000447415051422640016044 0ustar ghudsonghudson.. _spake: SPAKE Preauthentication ======================= SPAKE preauthentication (added in release 1.17) uses public key cryptography techniques to protect against :ref:`password dictionary attacks `. Unlike :ref:`PKINIT `, it does not require any additional infrastructure such as certificates; it simply needs to be turned on. Using SPAKE preauthentication may modestly increase the CPU and network load on the KDC. SPAKE preauthentication can use one of four elliptic curve groups for its password-authenticated key exchange. The recommended group is ``edwards25519``; three NIST curves (``P-256``, ``P-384``, and ``P-521``) are also supported. By default, SPAKE with the ``edwards25519`` group is enabled on clients, but the KDC does not offer SPAKE by default. To turn it on, set the **spake_preauth_groups** variable in :ref:`libdefaults` to a list of allowed groups. This variable affects both the client and the KDC. Simply setting it to ``edwards25519`` is recommended:: [libdefaults] spake_preauth_groups = edwards25519 Set the **+requires_preauth** and **-allow_svr** flags on client principal entries, as you would for any preauthentication mechanism:: kadmin: modprinc +requires_preauth -allow_svr PRINCNAME Clients which do not implement SPAKE preauthentication will fall back to encrypted timestamp. An active attacker can force a fallback to encrypted timestamp by modifying the initial KDC response, defeating the protection against dictionary attacks. To prevent this fallback on clients which do implement SPAKE preauthentication, set the **disable_encrypted_timestamp** variable to ``true`` in the :ref:`realms` subsection for realms whose KDCs offer SPAKE preauthentication. By default, SPAKE preauthentication requires an extra network round trip to the KDC during initial authentication. If most of the clients in a realm support SPAKE, this extra round trip can be eliminated using an optimistic challenge, by setting the **spake_preauth_kdc_challenge** variable in :ref:`kdcdefaults` to a single group name:: [kdcdefaults] spake_preauth_kdc_challenge = edwards25519 Using optimistic challenge will cause the KDC to do extra work for initial authentication requests that do not result in SPAKE preauthentication, but will save work when SPAKE preauthentication is used. krb5-1.22.1/doc/admin/database.rst0000664000175000017500000006121515051422640016501 0ustar ghudsonghudsonDatabase administration ======================= A Kerberos database contains all of a realm's Kerberos principals, their passwords, and other administrative information about each principal. For the most part, you will use the :ref:`kdb5_util(8)` program to manipulate the Kerberos database as a whole, and the :ref:`kadmin(1)` program to make changes to the entries in the database. (One notable exception is that users will use the :ref:`kpasswd(1)` program to change their own passwords.) The kadmin program has its own command-line interface, to which you type the database administrating commands. :ref:`kdb5_util(8)` provides a means to create, delete, load, or dump a Kerberos database. It also contains commands to roll over the database master key, and to stash a copy of the key so that the :ref:`kadmind(8)` and :ref:`krb5kdc(8)` daemons can use the database without manual input. :ref:`kadmin(1)` provides for the maintenance of Kerberos principals, password policies, and service key tables (keytabs). Normally it operates as a network client using Kerberos authentication to communicate with :ref:`kadmind(8)`, but there is also a variant, named kadmin.local, which directly accesses the Kerberos database on the local filesystem (or through LDAP). kadmin.local is necessary to set up enough of the database to be able to use the remote version. kadmin can authenticate to the admin server using the service principal ``kadmin/admin`` or ``kadmin/HOST`` (where *HOST* is the hostname of the admin server). If the credentials cache contains a ticket for either service principal and the **-c** ccache option is specified, that ticket is used to authenticate to KADM5. Otherwise, the **-p** and **-k** options are used to specify the client Kerberos principal name used to authenticate. Once kadmin has determined the principal name, it requests a ``kadmin/admin`` Kerberos service ticket from the KDC, and uses that service ticket to authenticate to KADM5. See :ref:`kadmin(1)` for the available kadmin and kadmin.local commands and options. .. _principals: Principals ---------- Each entry in the Kerberos database contains a Kerberos principal and the attributes and policies associated with that principal. To add a principal to the database, use the :ref:`kadmin(1)` **add_principal** command. User principals should usually be created with the ``+requires_preauth -allow_svr`` options to help mitigate dictionary attacks (see :ref:`dictionary`):: kadmin: addprinc +requires_preauth -allow_svr alice Enter password for principal "alice@KRBTEST.COM": Re-enter password for principal "alice@KRBTEST.COM": User principals which will authenticate with :ref:`pkinit` should instead by created with the ``-nokey`` option: kadmin: addprinc -nokey alice Service principals can be created with the ``-nokey`` option; long-term keys will be added when a keytab is generated:: kadmin: addprinc -nokey host/foo.mit.edu kadmin: ktadd -k foo.keytab host/foo.mit.edu Entry for principal host/foo.mit.edu with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:foo.keytab. Entry for principal host/foo.mit.edu with kvno 1, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:foo.keytab. To modify attributes of an existing principal, use the kadmin **modify_principal** command:: kadmin: modprinc -expire tomorrow alice Principal "alice@KRBTEST.COM" modified. To delete a principal, use the kadmin **delete_principal** command:: kadmin: delprinc alice Are you sure you want to delete the principal "alice@KRBTEST.COM"? (yes/no): yes Principal "alice@KRBTEST.COM" deleted. Make sure that you have removed this principal from all ACLs before reusing. To change a principal's password, use the kadmin **change_password** command. Password changes made through kadmin are subject to the same password policies as would apply to password changes made through :ref:`kpasswd(1)`. To view the attributes of a principal, use the kadmin` **get_principal** command. To generate a listing of principals, use the kadmin **list_principals** command. To give a principal additional names, use the kadmin **add_alias** command to create aliases to the principal (new in release 1.22). Aliases can be removed with the **delete_principal** command. .. _policies: Policies -------- A policy is a set of rules governing passwords. Policies can dictate minimum and maximum password lifetimes, minimum number of characters and character classes a password must contain, and the number of old passwords kept in the database. To add a new policy, use the :ref:`kadmin(1)` **add_policy** command:: kadmin: addpol -maxlife "1 year" -history 3 stduser To modify attributes of a principal, use the kadmin **modify_policy** command. To delete a policy, use the kadmin **delete_policy** command. To associate a policy with a principal, use the kadmin **modify_principal** command with the **-policy** option: kadmin: modprinc -policy stduser alice Principal "alice@KRBTEST.COM" modified. A principal entry may be associated with a nonexistent policy, either because the policy did not exist at the time of associated or was deleted afterwards. kadmin will warn when associated a principal with a nonexistent policy, and will annotate the policy name with "[does not exist]" in the **get_principal** output. .. _updating_history_key: Updating the history key ~~~~~~~~~~~~~~~~~~~~~~~~ If a policy specifies a number of old keys kept of two or more, the stored old keys are encrypted in a history key, which is found in the key data of the ``kadmin/history`` principal. Currently there is no support for proper rollover of the history key, but you can change the history key (for example, to use a better encryption type) at the cost of invalidating currently stored old keys. To change the history key, run:: kadmin: change_password -randkey kadmin/history This command will fail if you specify the **-keepold** flag. Only one new history key will be created, even if you specify multiple key/salt combinations. In the future, we plan to migrate towards encrypting old keys in the master key instead of the history key, and implementing proper rollover support for stored old keys. .. _privileges: Privileges ---------- Administrative privileges for the Kerberos database are stored in the file :ref:`kadm5.acl(5)`. .. note:: A common use of an admin instance is so you can grant separate permissions (such as administrator access to the Kerberos database) to a separate Kerberos principal. For example, the user ``joeadmin`` might have a principal for his administrative use, called ``joeadmin/admin``. This way, ``joeadmin`` would obtain ``joeadmin/admin`` tickets only when he actually needs to use those permissions. .. _db_operations: Operations on the Kerberos database ----------------------------------- The :ref:`kdb5_util(8)` command is the primary tool for administrating the Kerberos database when using the DB2 or LMDB modules (see :ref:`dbtypes`). Creating a database is described in :ref:`create_db`. To create a stash file using the master password (because the database was not created with one using the ``create -s`` flag, or after restoring from a backup which did not contain the stash file), use the kdb5_util **stash** command:: $ kdb5_util stash kdb5_util: Cannot find/read stored master key while reading master key kdb5_util: Warning: proceeding without master key Enter KDC database master key: <= Type the KDC database master password. To destroy a database, use the kdb5_util destroy command:: $ kdb5_util destroy Deleting KDC database stored in '/var/krb5kdc/principal', are you sure? (type 'yes' to confirm)? yes OK, deleting database '/var/krb5kdc/principal'... ** Database '/var/krb5kdc/principal' destroyed. .. _restore_from_dump: Dumping and loading a Kerberos database ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To dump a Kerberos database into a text file for backup or transfer purposes, use the :ref:`kdb5_util(8)` **dump** command on one of the KDCs:: $ kdb5_util dump dumpfile $ kbd5_util dump -verbose dumpfile kadmin/admin@ATHENA.MIT.EDU krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU kadmin/history@ATHENA.MIT.EDU K/M@ATHENA.MIT.EDU kadmin/changepw@ATHENA.MIT.EDU You may specify which principals to dump, using full principal names including realm:: $ kdb5_util dump -verbose someprincs K/M@ATHENA.MIT.EDU kadmin/admin@ATHENA.MIT.EDU kadmin/admin@ATHENA.MIT.EDU K/M@ATHENA.MIT.EDU To restore a Kerberos database dump from a file, use the :ref:`kdb5_util(8)` **load** command:: $ kdb5_util load dumpfile To update an existing database with a partial dump file containing only some principals, use the ``-update`` flag:: $ kdb5_util load -update someprincs .. note:: If the database file exists, and the *-update* flag was not given, *kdb5_util* will overwrite the existing database. .. _updating_master_key: Updating the master key ~~~~~~~~~~~~~~~~~~~~~~~ Starting with release 1.7, :ref:`kdb5_util(8)` allows the master key to be changed using a rollover process, with minimal loss of availability. To roll over the master key, follow these steps: #. On the primary KDC, run ``kdb5_util list_mkeys`` to view the current master key version number (KVNO). If you have never rolled over the master key before, this will likely be version 1:: $ kdb5_util list_mkeys Master keys for Principal: K/M@KRBTEST.COM KVNO: 1, Enctype: aes256-cts-hmac-sha384-192, Active on: Thu Jan 01 00:00:00 UTC 1970 * #. On the primary KDC, run ``kdb5_util use_mkey 1`` to ensure that a master key activation list is present in the database. This step is unnecessary in release 1.11.4 or later, or if the database was initially created with release 1.7 or later. #. On the primary KDC, run ``kdb5_util add_mkey -s`` to create a new master key and write it to the stash file. Enter a secure password when prompted. If this is the first time you are changing the master key, the new key will have version 2. The new master key will not be used until you make it active. #. Propagate the database to all replica KDCs, either manually or by waiting until the next scheduled propagation. If you do not have any replica KDCs, you can skip this and the next step. #. On each replica KDC, run ``kdb5_util list_mkeys`` to verify that the new master key is present, and then ``kdb5_util stash`` to write the new master key to the replica KDC's stash file. #. On the primary KDC, run ``kdb5_util use_mkey 2`` to begin using the new master key. Replace ``2`` with the version of the new master key, as appropriate. You can optionally specify a date for the new master key to become active; by default, it will become active immediately. Prior to release 1.12, :ref:`kadmind(8)` must be restarted for this change to take full effect. #. On the primary KDC, run ``kdb5_util update_princ_encryption``. This command will iterate over the database and re-encrypt all keys in the new master key. If the database is large and uses DB2, the primary KDC will become unavailable while this command runs, but clients should fail over to replica KDCs (if any are present) during this time period. In release 1.13 and later, you can instead run ``kdb5_util -x unlockiter update_princ_encryption`` to use unlocked iteration; this variant will take longer, but will keep the database available to the KDC and kadmind while it runs. #. Wait until the above changes have propagated to all replica KDCs and until all running KDC and kadmind processes have serviced requests using updated principal entries. #. On the primary KDC, run ``kdb5_util purge_mkeys`` to clean up the old master key. .. _ops_on_ldap: Operations on the LDAP database ------------------------------- The :ref:`kdb5_ldap_util(8)` command is the primary tool for administrating the Kerberos database when using the LDAP module. Creating an LDAP Kerberos database is describe in :ref:`conf_ldap`. To view a list of realms in the LDAP database, use the kdb5_ldap_util **list** command:: $ kdb5_ldap_util list KRBTEST.COM To modify the attributes of a realm, use the kdb5_ldap_util **modify** command. For example, to change the default realm's maximum ticket life:: $ kdb5_ldap_util modify -maxtktlife "10 hours" To display the attributes of a realm, use the kdb5_ldap_util **view** command:: $ kdb5_ldap_util view Realm Name: KRBTEST.COM Maximum Ticket Life: 0 days 00:10:00 To remove a realm from the LDAP database, destroying its contents, use the kdb5_ldap_util **destroy** command:: $ kdb5_ldap_util destroy Deleting KDC database of 'KRBTEST.COM', are you sure? (type 'yes' to confirm)? yes OK, deleting database of 'KRBTEST.COM'... ** Database of 'KRBTEST.COM' destroyed. Ticket Policy operations ~~~~~~~~~~~~~~~~~~~~~~~~ Unlike the DB2 and LMDB modules, the LDAP module supports ticket policy objects, which can be associated with principals to restrict maximum ticket lifetimes and set mandatory principal flags. Ticket policy objects are distinct from the password policies described earlier on this page, and are chiefly managed through kdb5_ldap_util rather than kadmin. To create a new ticket policy, use the kdb5_ldap_util **create_policy** command:: $ kdb5_ldap_util create_policy -maxrenewlife "2 days" users To associate a ticket policy with a principal, use the :ref:`kadmin(1)` **modify_principal** (or **add_principal**) command with the **-x tktpolicy=**\ *policy* option:: $ kadmin.local modprinc -x tktpolicy=users alice To remove a ticket policy reference from a principal, use the same command with an empty *policy*:: $ kadmin.local modprinc -x tktpolicy= alice To list the existing ticket policy objects, use the kdb5_ldap_util **list_policy** command:: $ kdb5_ldap_util list_policy users To modify the attributes of a ticket policy object, use the kdb5_ldap_util **modify_policy** command:: $ kdb5_ldap_util modify_policy -allow_svr +requires_preauth users To view the attributes of a ticket policy object, use the kdb5_ldap_util **view_policy** command:: $ kdb5_ldap_util view_policy users Ticket policy: users Maximum renewable life: 2 days 00:00:00 Ticket flags: REQUIRES_PRE_AUTH DISALLOW_SVR To destroy an ticket policy object, use the kdb5_ldap_util **destroy_policy** command:: $ kdb5_ldap_util destroy_policy users This will delete the policy object 'users', are you sure? (type 'yes' to confirm)? yes ** policy object 'users' deleted. .. _xrealm_authn: Cross-realm authentication -------------------------- In order for a KDC in one realm to authenticate Kerberos users in a different realm, it must share a key with the KDC in the other realm. In both databases, there must be krbtgt service principals for both realms. For example, if you need to do cross-realm authentication between the realms ``ATHENA.MIT.EDU`` and ``EXAMPLE.COM``, you would need to add the principals ``krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU`` and ``krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM`` to both databases. These principals must all have the same passwords, key version numbers, and encryption types; this may require explicitly setting the key version number with the **-kvno** option. In the ATHENA.MIT.EDU and EXAMPLE.COM cross-realm case, the administrators would run the following commands on the KDCs in both realms:: shell%: kadmin.local -e "aes256-cts:normal" kadmin: addprinc -requires_preauth krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM Enter password for principal krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM: Re-enter password for principal krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM: kadmin: addprinc -requires_preauth krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU Enter password for principal krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU: Enter password for principal krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU: kadmin: .. note:: Even if most principals in a realm are generally created with the **requires_preauth** flag enabled, this flag is not desirable on cross-realm authentication keys because doing so makes it impossible to disable preauthentication on a service-by-service basis. Disabling it as in the example above is recommended. .. note:: It is very important that these principals have good passwords. MIT recommends that TGT principal passwords be at least 26 characters of random ASCII text. .. _changing_krbtgt_key: Changing the krbtgt key ----------------------- A Kerberos Ticket Granting Ticket (TGT) is a service ticket for the principal ``krbtgt/REALM``. The key for this principal is created when the Kerberos database is initialized and need not be changed. However, it will only have the encryption types supported by the KDC at the time of the initial database creation. To allow use of newer encryption types for the TGT, this key has to be changed. Changing this key using the normal :ref:`kadmin(1)` **change_password** command would invalidate any previously issued TGTs. Therefore, when changing this key, normally one should use the **-keepold** flag to change_password to retain the previous key in the database as well as the new key. For example:: kadmin: change_password -randkey -keepold krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU .. warning:: After issuing this command, the old key is still valid and is still vulnerable to (for instance) brute force attacks. To completely retire an old key or encryption type, run the kadmin **purgekeys** command to delete keys with older kvnos, ideally first making sure that all tickets issued with the old keys have expired. Only the first krbtgt key of the newest key version is used to encrypt ticket-granting tickets. However, the set of encryption types present in the krbtgt keys is used by default to determine the session key types supported by the krbtgt service (see :ref:`session_key_selection`). Because non-MIT Kerberos clients sometimes send a limited set of encryption types when making AS requests, it can be important for the krbtgt service to support multiple encryption types. This can be accomplished by giving the krbtgt principal multiple keys, which is usually as simple as not specifying any **-e** option when changing the krbtgt key, or by setting the **session_enctypes** string attribute on the krbtgt principal (see :ref:`set_string`). Due to a bug in releases 1.8 through 1.13, renewed and forwarded tickets may not work if the original ticket was obtained prior to a krbtgt key change and the modified ticket is obtained afterwards. Upgrading the KDC to release 1.14 or later will correct this bug. .. _incr_db_prop: Incremental database propagation -------------------------------- Overview ~~~~~~~~ At some very large sites, dumping and transmitting the database can take more time than is desirable for changes to propagate from the primary KDC to the replica KDCs. The incremental propagation support added in the 1.7 release is intended to address this. With incremental propagation enabled, all programs on the primary KDC that change the database also write information about the changes to an "update log" file, maintained as a circular buffer of a certain size. A process on each replica KDC connects to a service on the primary KDC (currently implemented in the :ref:`kadmind(8)` server) and periodically requests the changes that have been made since the last check. By default, this check is done every two minutes. Incremental propagation uses the following entries in the per-realm data in the KDC config file (See :ref:`kdc.conf(5)`): ====================== =============== =========================================== iprop_enable *boolean* If *true*, then incremental propagation is enabled, and (as noted below) normal kprop propagation is disabled. The default is *false*. iprop_master_ulogsize *integer* Indicates the number of entries that should be retained in the update log. The default is 1000; the maximum number is 2500. iprop_replica_poll *time interval* Indicates how often the replica should poll the primary KDC for changes to the database. The default is two minutes. iprop_port *integer* Specifies the port number to be used for incremental propagation. This is required in both primary and replica configuration files. iprop_resync_timeout *integer* Specifies the number of seconds to wait for a full propagation to complete. This is optional on replica configurations. Defaults to 300 seconds (5 minutes). iprop_logfile *file name* Specifies where the update log file for the realm database is to be stored. The default is to use the *database_name* entry from the realms section of the config file :ref:`kdc.conf(5)`, with *.ulog* appended. (NOTE: If database_name isn't specified in the realms section, perhaps because the LDAP database back end is being used, or the file name is specified in the *dbmodules* section, then the hard-coded default for *database_name* is used. Determination of the *iprop_logfile* default value will not use values from the *dbmodules* section.) ====================== =============== =========================================== Both primary and replica sides must have a principal named ``kiprop/hostname`` (where *hostname* is the lowercase, fully-qualified, canonical name for the host) registered in the Kerberos database, and have keys for that principal stored in the default keytab file (|keytab|). The ``kiprop/hostname`` principal may have been created automatically for the primary KDC, but it must always be created for replica KDCs. On the primary KDC side, the ``kiprop/hostname`` principal must be listed in the kadmind ACL file :ref:`kadm5.acl(5)`, and given the **p** privilege (see :ref:`privileges`). On the replica KDC side, :ref:`kpropd(8)` should be run. When incremental propagation is enabled, it will connect to the kadmind on the primary KDC and start requesting updates. The normal kprop mechanism is disabled by the incremental propagation support. However, if the replica has been unable to fetch changes from the primary KDC for too long (network problems, perhaps), the log on the primary may wrap around and overwrite some of the updates that the replica has not yet retrieved. In this case, the replica will instruct the primary KDC to dump the current database out to a file and invoke a one-time kprop propagation, with special options to also convey the point in the update log at which the replica should resume fetching incremental updates. Thus, all the keytab and ACL setup previously described for kprop propagation is still needed. If an environment has a large number of replicas, it may be desirable to arrange them in a hierarchy instead of having the primary serve updates to every replica. To do this, run ``kadmind -proponly`` on each intermediate replica, and ``kpropd -A upstreamhostname`` on downstream replicas to direct each one to the appropriate upstream replica. There are several known restrictions in the current implementation: - The incremental update protocol does not transport changes to policy objects. Any policy changes on the primary will result in full resyncs to all replicas. - The replica's KDB module must support locking; it cannot be using the LDAP KDB module. - The primary and replica must be able to initiate TCP connections in both directions, without an intervening NAT. Sun/MIT incremental propagation differences ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sun donated the original code for supporting incremental database propagation to MIT. Some changes have been made in the MIT source tree that will be visible to administrators. (These notes are based on Sun's patches. Changes to Sun's implementation since then may not be reflected here.) The Sun config file support looks for ``sunw_dbprop_enable``, ``sunw_dbprop_master_ulogsize``, and ``sunw_dbprop_slave_poll``. The incremental propagation service is implemented as an ONC RPC service. In the Sun implementation, the service is registered with rpcbind (also known as portmapper) and the client looks up the port number to contact. In the MIT implementation, where interaction with some modern versions of rpcbind doesn't always work well, the port number must be specified in the config file on both the primary and replica sides. The Sun implementation hard-codes pathnames in ``/var/krb5`` for the update log and the per-replica kprop dump files. In the MIT implementation, the pathname for the update log is specified in the config file, and the per-replica dump files are stored in |kdcdir|\ ``/replica_datatrans_hostname``. krb5-1.22.1/doc/admin/appl_servers.rst0000664000175000017500000001622515051422640017443 0ustar ghudsonghudsonApplication servers =================== If you need to install the Kerberos V5 programs on an application server, please refer to the Kerberos V5 Installation Guide. Once you have installed the software, you need to add that host to the Kerberos database (see :ref:`principals`), and generate a keytab for that host, that contains the host's key. You also need to make sure the host's clock is within your maximum clock skew of the KDCs. Keytabs ------- A keytab is a host's copy of its own keylist, which is analogous to a user's password. An application server that needs to authenticate itself to the KDC has to have a keytab that contains its own principal and key. Just as it is important for users to protect their passwords, it is equally important for hosts to protect their keytabs. You should always store keytab files on local disk, and make them readable only by root, and you should never send a keytab file over a network in the clear. Ideally, you should run the :ref:`kadmin(1)` command to extract a keytab on the host on which the keytab is to reside. .. _add_princ_kt: Adding principals to keytabs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To generate a keytab, or to add a principal to an existing keytab, use the **ktadd** command from kadmin. Here is a sample session, using configuration files that enable only AES encryption:: kadmin: ktadd host/daffodil.mit.edu@ATHENA.MIT.EDU Entry for principal host/daffodil.mit.edu with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab Entry for principal host/daffodil.mit.edu with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab Removing principals from keytabs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To remove a principal from an existing keytab, use the kadmin **ktremove** command:: kadmin: ktremove host/daffodil.mit.edu@ATHENA.MIT.EDU Entry for principal host/daffodil.mit.edu with kvno 2 removed from keytab FILE:/etc/krb5.keytab. Entry for principal host/daffodil.mit.edu with kvno 2 removed from keytab FILE:/etc/krb5.keytab. Using a keytab to acquire client credentials ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ While keytabs are ordinarily used to accept credentials from clients, they can also be used to acquire initial credentials, allowing one service to authenticate to another. To manually obtain credentials using a keytab, use the :ref:`kinit(1)` **-k** option, together with the **-t** option if the keytab is not in the default location. Beginning with release 1.11, GSSAPI applications can be configured to automatically obtain initial credentials from a keytab as needed. The recommended configuration is as follows: #. Create a keytab containing a single entry for the desired client identity. #. Place the keytab in a location readable by the service, and set the **KRB5_CLIENT_KTNAME** environment variable to its filename. Alternatively, use the **default_client_keytab_name** profile variable in :ref:`libdefaults`, or use the default location of |ckeytab|. #. Set **KRB5CCNAME** to a filename writable by the service, which will not be used for any other purpose. Do not manually obtain credentials at this location. (Another credential cache type besides **FILE** can be used if desired, as long the cache will not conflict with another use. A **MEMORY** cache can be used if the service runs as a long-lived process. See :ref:`ccache_definition` for details.) #. Start the service. When it authenticates using GSSAPI, it will automatically obtain credentials from the client keytab into the specified credential cache, and refresh them before they expire. Clock Skew ---------- A Kerberos application server host must keep its clock synchronized or it will reject authentication requests from clients. Modern operating systems typically provide a facility to maintain the correct time; make sure it is enabled. This is especially important on virtual machines, where clocks tend to drift more rapidly than normal machine clocks. The default allowable clock skew is controlled by the **clockskew** variable in :ref:`libdefaults`. Getting DNS information correct ------------------------------- Several aspects of Kerberos rely on name service. When a hostname is used to name a service, clients may canonicalize the hostname using forward and possibly reverse name resolution. The result of this canonicalization must match the principal entry in the host's keytab, or authentication will fail. To work with all client canonicalization configurations, each host's canonical name must be the fully-qualified host name (including the domain), and each host's IP address must reverse-resolve to the canonical name. Configuration of hostnames varies by operating system. On the application server itself, canonicalization will typically use the ``/etc/hosts`` file rather than the DNS. Ensure that the line for the server's hostname is in the following form:: IP address fully-qualified hostname aliases Here is a sample ``/etc/hosts`` file:: # this is a comment 127.0.0.1 localhost localhost.mit.edu 10.0.0.6 daffodil.mit.edu daffodil trillium wake-robin The output of ``klist -k`` for this example host should look like:: viola# klist -k Keytab name: /etc/krb5.keytab KVNO Principal ---- ------------------------------------------------------------ 2 host/daffodil.mit.edu@ATHENA.MIT.EDU If you were to ssh to this host with a fresh credentials cache (ticket file), and then :ref:`klist(1)`, the output should list a service principal of ``host/daffodil.mit.edu@ATHENA.MIT.EDU``. .. _conf_firewall: Configuring your firewall to work with Kerberos V5 -------------------------------------------------- If you need off-site users to be able to get Kerberos tickets in your realm, they must be able to get to your KDC. This requires either that you have a replica KDC outside your firewall, or that you configure your firewall to allow UDP requests into at least one of your KDCs, on whichever port the KDC is running. (The default is port 88; other ports may be specified in the KDC's :ref:`kdc.conf(5)` file.) Similarly, if you need off-site users to be able to change their passwords in your realm, they must be able to get to your Kerberos admin server on the kpasswd port (which defaults to 464). If you need off-site users to be able to administer your Kerberos realm, they must be able to get to your Kerberos admin server on the administrative port (which defaults to 749). If your on-site users inside your firewall will need to get to KDCs in other realms, you will also need to configure your firewall to allow outgoing TCP and UDP requests to port 88, and to port 464 to allow password changes. If your on-site users inside your firewall will need to get to Kerberos admin servers in other realms, you will also need to allow outgoing TCP and UDP requests to port 749. If any of your KDCs are outside your firewall, you will need to allow kprop requests to get through to the remote KDC. :ref:`kprop(8)` uses the ``krb5_prop`` service on port 754 (tcp). The book *UNIX System Security*, by David Curry, is a good starting point for learning to configure firewalls. krb5-1.22.1/doc/admin/troubleshoot.rst0000664000175000017500000001074715051422640017472 0ustar ghudsonghudson.. _troubleshoot: Troubleshooting =============== .. _trace_logging: Trace logging ------------- Most programs using MIT krb5 1.9 or later can be made to provide information about internal krb5 library operations using trace logging. To enable this, set the **KRB5_TRACE** environment variable to a filename before running the program. On many operating systems, the filename ``/dev/stdout`` can be used to send trace logging output to standard output. Some programs do not honor **KRB5_TRACE**, either because they use secure library contexts (this generally applies to setuid programs and parts of the login system) or because they take direct control of the trace logging system using the API. Here is a short example showing trace logging output for an invocation of the :ref:`kvno(1)` command:: shell% env KRB5_TRACE=/dev/stdout kvno krbtgt/KRBTEST.COM [9138] 1332348778.823276: Getting credentials user@KRBTEST.COM -> krbtgt/KRBTEST.COM@KRBTEST.COM using ccache FILE:/me/krb5/build/testdir/ccache [9138] 1332348778.823381: Retrieving user@KRBTEST.COM -> krbtgt/KRBTEST.COM@KRBTEST.COM from FILE:/me/krb5/build/testdir/ccache with result: 0/Unknown code 0 krbtgt/KRBTEST.COM@KRBTEST.COM: kvno = 1 List of errors -------------- Frequently seen errors ~~~~~~~~~~~~~~~~~~~~~~ #. :ref:`init_creds_ETYPE_NOSUPP` #. :ref:`cert_chain_ETYPE_NOSUPP` #. :ref:`err_cert_chain_cert_expired` Errors seen by admins ~~~~~~~~~~~~~~~~~~~~~ .. _prop_failed_start: #. :ref:`kprop_no_route` #. :ref:`kprop_con_refused` #. :ref:`kprop_sendauth_exchange` .. _prop_failed_end: ----- .. _init_creds_etype_nosupp: KDC has no support for encryption type while getting initial credentials ........................................................................ .. _cert_chain_etype_nosupp: credential verification failed: KDC has no support for encryption type ...................................................................... This most commonly happens when trying to use a principal with only DES keys, in a release (MIT krb5 1.7 or later) which disables DES by default. DES encryption is considered weak due to its inadequate key size. If you cannot migrate away from its use, you can re-enable DES by adding ``allow_weak_crypto = true`` to the :ref:`libdefaults` section of :ref:`krb5.conf(5)`. .. _err_cert_chain_cert_expired: Cannot create cert chain: certificate has expired ................................................. This error message indicates that PKINIT authentication failed because the client certificate, KDC certificate, or one of the certificates in the signing chain above them has expired. If the KDC certificate has expired, this message appears in the KDC log file, and the client will receive a "Preauthentication failed" error. (Prior to release 1.11, the KDC log file message erroneously appears as "Out of memory". Prior to release 1.12, the client will receive a "Generic error".) If the client or a signing certificate has expired, this message may appear in trace_logging_ output from :ref:`kinit(1)` or, starting in release 1.12, as an error message from kinit or another program which gets initial tickets. The error message is more likely to appear properly on the client if the principal entry has no long-term keys. .. _kprop_no_route: kprop: No route to host while connecting to server .................................................. Make sure that the hostname of the replica KDC (as given to kprop) is correct, and that any firewalls between the primary and the replica allow a connection on port 754. .. _kprop_con_refused: kprop: Connection refused while connecting to server .................................................... If the replica KDC is intended to run kpropd out of inetd, make sure that inetd is configured to accept krb5_prop connections. inetd may need to be restarted or sent a SIGHUP to recognize the new configuration. If the replica is intended to run kpropd in standalone mode, make sure that it is running. .. _kprop_sendauth_exchange: kprop: Server rejected authentication (during sendauth exchange) while authenticating to server ............................................................................................... Make sure that: #. The time is synchronized between the primary and replica KDCs. #. The master stash file was copied from the primary to the expected location on the replica. #. The replica has a keytab file in the default location containing a ``host`` principal for the replica's hostname. krb5-1.22.1/doc/admin/index.rst0000664000175000017500000000103315051422640016034 0ustar ghudsonghudsonFor administrators ================== .. toctree:: :maxdepth: 1 install.rst conf_files/index.rst realm_config.rst database.rst dbtypes.rst lockout.rst conf_ldap.rst appl_servers.rst host_config.rst backup_host.rst pkinit.rst otp.rst spake.rst dictionary.rst princ_dns.rst enctypes.rst https.rst auth_indicator.rst .. toctree:: :maxdepth: 1 admin_commands/index.rst ../mitK5defaults.rst env_variables.rst troubleshoot.rst advanced/index.rst various_envs.rst krb5-1.22.1/doc/admin/install_appl_srv.rst0000664000175000017500000000716115051422640020311 0ustar ghudsonghudsonUNIX Application Servers ======================== An application server is a host that provides one or more services over the network. Application servers can be "secure" or "insecure." A "secure" host is set up to require authentication from every client connecting to it. An "insecure" host will still provide Kerberos authentication, but will also allow unauthenticated clients to connect. If you have Kerberos V5 installed on all of your client machines, MIT recommends that you make your hosts secure, to take advantage of the security that Kerberos authentication affords. However, if you have some clients that do not have Kerberos V5 installed, you can run an insecure server, and still take advantage of Kerberos V5's single sign-on capability. .. _keytab_file: The keytab file --------------- All Kerberos server machines need a keytab file to authenticate to the KDC. By default on UNIX-like systems this file is named |keytab|. The keytab file is an local copy of the host's key. The keytab file is a potential point of entry for a break-in, and if compromised, would allow unrestricted access to its host. The keytab file should be readable only by root, and should exist only on the machine's local disk. The file should not be part of any backup of the machine, unless access to the backup data is secured as tightly as access to the machine's root password. In order to generate a keytab for a host, the host must have a principal in the Kerberos database. The procedure for adding hosts to the database is described fully in :ref:`principals`. (See :ref:`replica_host_key` for a brief description.) The keytab is generated by running :ref:`kadmin(1)` and issuing the :ref:`ktadd` command. For example, to generate a keytab file to allow the host ``trillium.mit.edu`` to authenticate for the services host, ftp, and pop, the administrator ``joeadmin`` would issue the command (on ``trillium.mit.edu``):: trillium% kadmin Authenticating as principal root/admin@ATHENA.MIT.EDU with password. Password for root/admin@ATHENA.MIT.EDU: kadmin: ktadd host/trillium.mit.edu ftp/trillium.mit.edu pop/trillium.mit.edu Entry for principal host/trillium.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab. kadmin: Entry for principal ftp/trillium.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab. kadmin: Entry for principal pop/trillium.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab. kadmin: quit trillium% If you generate the keytab file on another host, you need to get a copy of the keytab file onto the destination host (``trillium``, in the above example) without sending it unencrypted over the network. Some advice about secure hosts ------------------------------ Kerberos V5 can protect your host from certain types of break-ins, but it is possible to install Kerberos V5 and still leave your host vulnerable to attack. Obviously an installation guide is not the place to try to include an exhaustive list of countermeasures for every possible attack, but it is worth noting some of the larger holes and how to close them. We recommend that backups of secure machines exclude the keytab file (|keytab|). If this is not possible, the backups should at least be done locally, rather than over a network, and the backup tapes should be physically secured. The keytab file and any programs run by root, including the Kerberos V5 binaries, should be kept on local disk. The keytab file should be readable only by root. krb5-1.22.1/doc/admin/env_variables.rst0000664000175000017500000000013315051422640017545 0ustar ghudsonghudsonEnvironment variables ===================== This content has moved to :ref:`kerberos(7)`. krb5-1.22.1/doc/mitK5defaults.rst0000664000175000017500000001046315051422640016365 0ustar ghudsonghudson.. _mitK5defaults: MIT Kerberos defaults ===================== General defaults ---------------- ========================================== ============================= ==================== Description Default Environment ========================================== ============================= ==================== :ref:`keytab_definition` file |keytab| **KRB5_KTNAME** Client :ref:`keytab_definition` file |ckeytab| **KRB5_CLIENT_KTNAME** Kerberos config file :ref:`krb5.conf(5)` |krb5conf|\ ``:``\ **KRB5_CONFIG** |sysconfdir|\ ``/krb5.conf`` KDC config file :ref:`kdc.conf(5)` |kdcdir|\ ``/kdc.conf`` **KRB5_KDC_PROFILE** GSS mechanism config file |sysconfdir|\ ``/gss/mech`` **GSS_MECH_CONFIG** KDC database path (DB2) |kdcdir|\ ``/principal`` Master key :ref:`stash_definition` |kdcdir|\ ``/.k5.``\ *realm* Admin server ACL file :ref:`kadm5.acl(5)` |kdcdir|\ ``/kadm5.acl`` OTP socket directory |kdcrundir| Plugin base directory |libdir|\ ``/krb5/plugins`` :ref:`rcache_definition` directory ``/var/tmp`` **KRB5RCACHEDIR** Master key default enctype |defmkey| Default :ref:`keysalt list` |defkeysalts| Permitted enctypes |defetypes| KDC default port 88 Admin server port 749 Password change port 464 ========================================== ============================= ==================== Replica KDC propagation defaults -------------------------------- This table shows defaults used by the :ref:`kprop(8)` and :ref:`kpropd(8)` programs. ========================== ================================ =========== Description Default Environment ========================== ================================ =========== kprop database dump file |kdcdir|\ ``/replica_datatrans`` kpropd temporary dump file |kdcdir|\ ``/from_master`` kdb5_util location |sbindir|\ ``/kdb5_util`` kprop location |sbindir|\ ``/kprop`` kpropd ACL file |kdcdir|\ ``/kpropd.acl`` kprop port 754 KPROP_PORT ========================== ================================ =========== .. _paths: Default paths for Unix-like systems ----------------------------------- On Unix-like systems, some paths used by MIT krb5 depend on parameters chosen at build time. For a custom build, these paths default to subdirectories of ``/usr/local``. When MIT krb5 is integrated into an operating system, the paths are generally chosen to match the operating system's filesystem layout. ========================== ============== =========================== =========================== Description Symbolic name Custom build path Typical OS path ========================== ============== =========================== =========================== User programs BINDIR ``/usr/local/bin`` ``/usr/bin`` Libraries and plugins LIBDIR ``/usr/local/lib`` ``/usr/lib`` Parent of KDC state dir LOCALSTATEDIR ``/usr/local/var`` ``/var`` Parent of KDC runtime dir RUNSTATEDIR ``/usr/local/var/run`` ``/run`` Administrative programs SBINDIR ``/usr/local/sbin`` ``/usr/sbin`` Alternate krb5.conf dir SYSCONFDIR ``/usr/local/etc`` ``/etc`` Default ccache name DEFCCNAME ``FILE:/tmp/krb5cc_%{uid}`` ``FILE:/tmp/krb5cc_%{uid}`` Default keytab name DEFKTNAME ``FILE:/etc/krb5.keytab`` ``FILE:/etc/krb5.keytab`` Default PKCS11 module PKCS11_MODNAME ``opensc-pkcs11.so`` ``opensc-pkcs11.so`` ========================== ============== =========================== =========================== The default client keytab name (DEFCKTNAME) typically defaults to ``FILE:/usr/local/var/krb5/user/%{euid}/client.keytab`` for a custom build. A native build will typically use a path which will vary according to the operating system's layout of ``/var``. krb5-1.22.1/doc/index.rst0000664000175000017500000000047215051422640014752 0ustar ghudsonghudsonMIT Kerberos Documentation (|release|) ====================================== .. toctree:: :maxdepth: 1 user/index.rst admin/index.rst appdev/index.rst plugindev/index.rst build/index.rst basic/index.rst formats/index.rst mitK5features.rst build_this.rst about.rst resources krb5-1.22.1/doc/tools/0000775000175000017500000000000015051422641014247 5ustar ghudsonghudsonkrb5-1.22.1/doc/tools/README0000664000175000017500000000524615051422640015135 0ustar ghudsonghudsonHow to deploy the Doxygen output in Sphinx project. ==================================================== The text below is meant to give the instructions on how to incorporate MIT Kerberos API reference documentation into Sphinx document hierarchy. The Sphinx API documentation can be constructed with (Part B) or without (Part A) the bridge to the original Doxygen HTML output. Pre-requisites: - python 2.5+ with Cheetah, lxml and xml extension modules installed; - For part B only: - Sphinx "doxylink" extension; - Doxygen HTML output Part A: Transforming Doxygen XML output into reStructuredText (rst) without the bridge to Doxygen HTML output. 1. Delete lines containing text "Doxygen reference" from the template files func_document.tmpl and type_document.tmpl; 2. In the Doxygen configuration file set GENERATE_XML to YES. Generate Doxygen XML output; 3. Suppose the Doxygen XML output is located in doxy_xml_dir and the desired output directory is rst_dir. Run: python doxy.py -i doxy_xml_dir -o rst_dir -t func This will result in the storing of the API function documentation files in rst format in the rst_dir. The file names are constructed based on the function name. For example, the file for krb5_build_principal() will be krb5_build_principal.rst Run: python doxy.py -i doxy_xml_dir -o rst_dir -t typedef It is similar to the API function conversion, but for data types. The result will be stored under rst_dir/types directory Alternatively, running python doxy.py -i doxy_xml_dir -o rst_dir or python doxy.py -i doxy_xml_dir -o rst_dir -t all converts Doxygen XML output into reStructuredText format files both for API functions and data types; 4. In appdev/index.rst add the following section to point to the API references: .. toctree:: :maxdepth: 1 refs/index.rst 5. Copy the content of rst_dir into appdev/refs/api/ directory and rst_dir/types into appdev/refs/types directory; 6. Rebuild Sphinx source: sphinx-build source_dir build_dir Part B: Bridge to Doxygen HTML output. 1. Transform Doxygen XML output into reStructuredText. In src/Doxygen configuration file request generation of the tag file and XML output: GENERATE_TAGFILE = krb5doxy.tag GENERATE_XML = YES 2. Modify Sphinx conf.py file to point to the "doxylink" extension and Doxygen tag file: extensions = ['sphinx.ext.autodoc', 'sphinxcontrib.doxylink'] doxylink = { ' krb5doxy' : ('/tmp/krb5doxy.tag, ' doxy_html_dir ') } where doxy_html_dir is the location of the Doxygen HTML output 3. Continue with steps 3 - 6 of Part A. krb5-1.22.1/doc/tools/doxybuilder_types.py0000664000175000017500000003513615051422640020406 0ustar ghudsonghudson''' Copyright 2011 by the Massachusetts Institute of Technology. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ''' import sys import os import re import textwrap from lxml import etree from docmodel import * exclude_types = [ 'TRUE', 'FALSE', 'KRB5_ATTR_DEPRECATED', 'KRB5_CALLCONV', 'KRB5_CALLCONV_C', 'KRB5_CALLCONV_WRONG', 'KRB5_GENERAL__', 'KRB5_KEYUSAGE_PA_REFERRAL', 'KRB5_OLD_CRYPTO', 'KRB5INT_BEGIN_DECLS', 'KRB5INT_END_DECLS', 'krb5_cc_ops', 'krb5_octet_data' ] class DoxyTypes(object): def __init__(self, xmlpath): self.xmlpath = xmlpath def run_compound(self, filename, include=None): path = '%s/%s' % (self.xmlpath,filename) tree = etree.parse(path) root = tree.getroot() brief_node = root.xpath('./compounddef/briefdescription')[0] brief_description = self._get_brief_description(brief_node) details_node = root.xpath('./compounddef/detaileddescription')[0] detailed_description = self._get_detailed_description(details_node) fields = list() for node in root.iterfind(".//memberdef[@kind]"): data = {} kind = node.attrib['kind'] if include is None or kind in include: if kind == 'variable': data = self._process_variable_node(node) else: pass fields.append(data) result = {'brief_description': brief_description, 'detailed_description': detailed_description, 'attributes': fields} return result def run(self, filename, include=None): """ Parses xml file generated by doxygen. @param filename: doxygen xml file name @param include: members sections to include, in None -- include all """ path = '%s/%s' % (self.xmlpath,filename) tree = etree.parse(path) root = tree.getroot() result = list() for node in root.iterfind(".//memberdef[@kind]"): data = {} kind = node.attrib['kind'] if include is None or kind in include: if kind == 'typedef': data = self._process_typedef_node(node) elif kind == 'variable': data = self._process_variable_node(node) elif kind == 'define': data = self._process_define_node(node) if 'name' in data and data['name'] in exclude_types: continue result.append(data) return result def _process_typedef_node(self, node): t_name = node.xpath('./name/text()')[0] t_Id = node.attrib['id'] t_definition = node.xpath('./definition/text()')[0] t_type = self._process_type_node(node.xpath("./type")[0]) brief_node = node.xpath('./briefdescription')[0] t_brief = self._get_brief_description(brief_node) details_node = node.xpath('./detaileddescription')[0] t_detailed = self._get_detailed_description(details_node) # remove macros t_definition = re.sub('KRB5_CALLCONV_C', '', t_definition) t_definition = re.sub('KRB5_CALLCONV', '', t_definition) t_definition = re.sub(r'\*', '\\*', t_definition) # handle fp if t_type[1].find('(') >= 0: t_type = (t_type[0],None) typedef_descr = {'category': 'composite', 'definition': t_definition, 'name': t_name, 'Id': t_Id, 'initializer': '', 'type': t_type[1], 'short_description': t_brief, 'long_description': t_detailed, 'attributes': list() } if t_type[0] is not None : filename = '%s.xml' % t_type[0] path = '%s/%s' % (self.xmlpath,filename) if not os.path.exists(path): # nothing can be done return typedef_descr compound_info = self.run_compound(filename) if compound_info is not None: brief_description = compound_info.get('brief_description') if brief_description is not None and len(brief_description): # override brief description typedef_descr['short_description'] = brief_description detailed_description = compound_info.get('detailed_description') if detailed_description is not None and len(detailed_description): # check if this is not a duplicate if detailed_description.find(t_detailed) < 0: typedef_descr['long_description'] = '%s\n%s' % \ (detailed_description, typedef_descr['long_description']) typedef_descr['attributes'] = compound_info['attributes'] return typedef_descr def _process_variable_node(self, node): v_name = node.xpath('./name/text()')[0] v_Id = node.attrib['id'] v_definition = node.xpath('./definition/text()')[0] v_type = self._process_type_node(node.xpath("./type")[0]) brief_node = node.xpath('./briefdescription')[0] v_brief = self._get_brief_description(brief_node) details_node = node.xpath('./detaileddescription')[0] detailed_description = self._get_detailed_description(details_node) # remove macros v_definition = re.sub('KRB5_CALLCONV_C', '', v_definition) v_definition = re.sub('KRB5_CALLCONV', '', v_definition) v_definition = re.sub(r'\*', '\\*', v_definition) variable_descr = {'category': 'variable', 'definition': v_definition, 'name': v_name, 'Id': v_Id, 'initializer': '', 'type': v_type[1], 'short_description': v_brief, 'long_description': detailed_description, 'attributes': list() } return variable_descr def _process_define_node(self, node): d_name = node.xpath('./name/text()')[0] d_initializer = '' d_type = '' d_signature = '' # Process param/defname node if len(node.xpath('./param/defname')) > 0: prm_str = '' prm_list = list() for p in node.xpath("./param"): x = self._process_paragraph_content(p) if x is not None and len(x): prm_list.append(x) if prm_list is not None: prm_str = prm_str.join(prm_list) d_signature = " %s (%s) " % (d_name , prm_str) d_signature = re.sub(r', \)', ')', d_signature).strip() if len(node.xpath('./initializer')) > 0: len_ref = len(node.xpath('./initializer/ref')) if len(node.xpath('./initializer/ref')) > 0: d_type = self._process_type_node(node.xpath("./initializer/ref")[0]) if len(d_type) > 0: len_text = len(node.xpath('./initializer/text()')) if len_text == 0 and d_type[1]: d_initializer = d_type[1] if len_text > 0 and len(node.xpath('./initializer/text()')[0]) > 0: d_initializer = node.xpath('./initializer/text()')[0] + d_type[1] if len_text > 1: if node.xpath('./initializer/text()')[1] is not None: d_initializer = d_initializer + node.xpath('./initializer/text()')[1] else: d_initializer = node.xpath('./initializer/text()')[0] d_Id = node.attrib['id'] brief_node = node.xpath('./briefdescription')[0] d_brief = self._get_brief_description(brief_node) details_node = node.xpath('./detaileddescription')[0] detailed_description = self._get_detailed_description(details_node) # Condense multiline macros, stripping leading whitespace. d_initializer = re.sub(" *\\\\\n *", " ", d_initializer) define_descr = {'category': 'composite', 'definition': '', 'name': d_name, 'name_signature': d_signature, 'Id': d_Id, 'initializer': d_initializer, 'type': '', 'short_description': d_brief, 'long_description': detailed_description, 'attributes': list() } return define_descr def _get_brief_description(self, node): result = list() for p in node.xpath("./para"): x = self._process_paragraph_content(p) if x is not None and len(x): result.append(x) result = '\n'.join(result) return result def _get_detailed_description(self, node): """ Description node is comprised of ... sections. There are few types of these sections: a) Content section b) Return value section -- skip c) Parameter list section -- skip @param node: detailed description node """ result = list() for p in node.xpath("./para"): if len(p.xpath("./simplesect[@kind='return']")): continue elif len(p.xpath("./parameterlist[@kind='param']")): continue else: x = self._process_paragraph_content(p) result.append(x) result = '\n'.join(result) return result def _process_paragraph_content(self, node): def add_text(l, s): # Add a space if it wouldn't be at the start or end of a line. if l and not l[-1].endswith('\n') and not s.startswith('\n'): l.append(' ') l.append(s) result = list() content = node.xpath(".//text()") for e in content: if e.is_tail or node is e.getparent(): add_text(result, e.strip()) elif e.getparent().tag == 'ref': if e.strip().find('(') > 0: add_text(result, ':c:func:`%s`' % e.strip()) elif e.isupper(): add_text(result, ':c:data:`%s`' % e.strip()) else: add_text(result, ':c:type:`%s`' % e.strip()) elif e.getparent().tag == 'emphasis': add_text(result, '*%s*' % e.strip()) elif e.getparent().tag == 'computeroutput': add_text(result, '*%s*' % e.strip()) elif e.getparent().tag == 'defname': add_text(result, '%s, ' % e.strip()) elif e.getparent().tag == 'verbatim': add_text(result, '\n::\n\n') add_text(result, textwrap.indent(e, ' ', lambda x: True)) add_text(result, '\n') result = ''.join(result) return result def _process_type_node(self, node): """ Type node has form type_string for build in types and 'type_name' postfix (ex. *, **m, etc.) for user defined types. """ p_id = node.xpath("./ref/@refid") if len(p_id) == 1: p_id = p_id[0] elif len(p_id) == 0: p_id = None p_type = ' '.join(node.xpath(".//text()")) # remove macros p_type = re.sub('KRB5_CALLCONV_C', ' ', p_type) p_type = re.sub('KRB5_CALLCONV', ' ', p_type) return (p_id,p_type) def save(self, obj, templates, target_dir): template_path = templates[obj.category] outpath = '%s/%s.rst' % (target_dir,obj.name) obj.save(outpath, template_path) class DoxyBuilderTypes(DoxyTypes): def __init__(self, xmlpath, rstpath): self.templates = { 'composite': 'type_document.tmpl'} self.target_dir = rstpath super(DoxyBuilderTypes,self).__init__(xmlpath) def run_all(self): self.process_typedef_nodes() self.process_define_nodes() def test_run(self): filename = 'krb5_8hin.xml' self.run(filename) def process_variable_nodes(self): filename = 'struct__krb5__octet__data.xml' result = self.run(filename, include=['variable']) def process_typedef_nodes(self): # run parser for typedefs filename = 'krb5_8hin.xml' result = self.run(filename, include=['typedef']) target_dir = '%s/types' % (self.target_dir) if not os.path.exists(target_dir): os.makedirs(target_dir, 0o755) for t in result: obj = DocModel(**t) self.save(obj, self.templates, target_dir) def process_define_nodes(self): # run parser for define's filename = 'krb5_8hin.xml' result = self.run(filename, include=['define']) target_dir = '%s/macros' % (self.target_dir) if not os.path.exists(target_dir): os.makedirs(target_dir, 0o755) for t in result: obj = DocModel(**t) tmpl = {'composite': 'define_document.tmpl'} self.save(obj, tmpl, target_dir) if __name__ == '__main__': builder = DoxyBuilderTypes( xml_inpath, rst_outpath) builder.run_all() krb5-1.22.1/doc/tools/doxy.py0000664000175000017500000000477715051422640015622 0ustar ghudsonghudson''' Copyright 2011 by the Massachusetts Institute of Technology. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ''' import sys import os import re from optparse import OptionParser from doxybuilder_types import * from doxybuilder_funcs import * def processOptions(): usage = "\n\t\t%prog -t type -i in_dir -o out_dir" description = "Description:\n\tProcess doxygen output for c-types and/or functions" parser = OptionParser(usage=usage, description=description) parser.add_option("-t", "--type", type="string", dest="action_type", help="process typedef and/or function. Possible choices: typedef, func, all. Default: all.", default="all") parser.add_option("-i", "--in", type="string", dest="in_dir", help="input directory") parser.add_option("-o", "--out", type="string", dest= "out_dir", help="output directory. Note: The subdirectory ./types will be created for typedef") (options, args) = parser.parse_args() action = options.action_type in_dir = options.in_dir out_dir = options.out_dir if in_dir is None or out_dir is None: parser.error("Input and output directories are required") if action == "all" or action == "typedef": builder = DoxyBuilderTypes(in_dir, out_dir) builder.run_all() if action == "all" or action == "func" or action == "function": builder = DoxyBuilderFuncs(in_dir, out_dir) builder.run_all() if __name__ == '__main__': parser = processOptions() krb5-1.22.1/doc/tools/__pycache__/0000775000175000017500000000000015051422641016457 5ustar ghudsonghudsonkrb5-1.22.1/doc/tools/__pycache__/doxybuilder_types.cpython-312.pyc0000664000175000017500000004266315051422641024753 0ustar ghudsonghudsonË  %¦h^:ãó°—dZddlZddlZddlZddlZddlmZddl­gd¢ZGd„de «Z Gd„d e «Z e d k(re e e«Zej!«yy) aŸ Copyright 2011 by the Massachusetts Institute of Technology. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. éN)Úetree)Ú*) ÚTRUEÚFALSEÚKRB5_ATTR_DEPRECATEDÚ KRB5_CALLCONVÚKRB5_CALLCONV_CÚKRB5_CALLCONV_WRONGÚKRB5_GENERAL__ÚKRB5_KEYUSAGE_PA_REFERRALÚKRB5_OLD_CRYPTOÚKRB5INT_BEGIN_DECLSÚKRB5INT_END_DECLSÚ krb5_cc_opsÚkrb5_octet_datacóR—eZdZd„Zd d„Zd d„Zd„Zd„Zd„Zd„Z d „Z d „Z d „Z d „Z y)Ú DoxyTypescó—||_y©N)Úxmlpath)Úselfrs ú//tmp/krb5-1.22.1/doc/tools/doxybuilder_types.pyÚ__init__zDoxyTypes.__init__*s €Øˆ óNcóÔ—|j›d|›}tj|«}|j«}|j d«d}|j |«}|j d«d}|j |«} t«} |jd«D]C} i} | jd} || |vsŒ| dk(r|j| «} n | j| «ŒE|| | dœ}|S) Nú/z./compounddef/briefdescriptionrz!./compounddef/detaileddescriptionú.//memberdef[@kind]ÚkindÚvariable)Úbrief_descriptionÚdetailed_descriptionÚ attributes) rrÚparseÚgetrootÚxpathÚ_get_brief_descriptionÚ_get_detailed_descriptionÚlistÚiterfindÚattribÚ_process_variable_nodeÚappend)rÚfilenameÚincludeÚpathÚtreeÚrootÚ brief_noder Ú details_noder!ÚfieldsÚnodeÚdatarÚresults rÚ run_compoundzDoxyTypes.run_compound-sñ€ØŸ,›,¡xÐ0ˆÜ{‰{˜4Ó ˆØ|‰|‹~ˆà—Z‘ZÐ @ÓAÀ!ÑDˆ Ø ×7Ñ7¸ ÓCÐØ—z‘zÐ"EÓFÀqÑIˆ Ø#×=Ñ=¸lÓKÐ䓈ؗM‘MÐ"7Ó8ò $ˆD؈DØ—;‘;˜vÑ&ˆD؈ $¨'¢/ؘ:Ò%Ø×6Ñ6°tÓ<‘DàØ— ‘ ˜dÕ#ð $ð(9Ø*>Ø &ñ(ˆðˆ rcó¬—|j›d|›}tj|«}|j«}t «}|j d«D]}i}|j d} || |vsŒ| dk(r|j|«}n-| dk(r|j|«}n| dk(r|j|«}d|vr |dtvrŒo|j|«Œ|S)z³ Parses xml file generated by doxygen. @param filename: doxygen xml file name @param include: members sections to include, in None -- include all rrrÚtypedefrÚdefineÚname) rrr#r$r(r)r*Ú_process_typedef_noder+Ú_process_define_nodeÚ exclude_typesr,) rr-r.r/r0r1r7r5r6rs rÚrunz DoxyTypes.runJsÙ€ðŸ,›,¡xÐ0ˆÜ{‰{˜4Ó ˆØ|‰|‹~ˆÜ“ˆØ—M‘MÐ"7Ó8ò $ˆD؈DØ—;‘;˜vÑ&ˆD؈ $¨'¢/ؘ9Ò$Ø×5Ñ5°dÓ;‘DؘZÒ'Ø×6Ñ6°tÓ<‘DؘXÒ%Ø×4Ñ4°TÓ:DؘT‘> d¨6¡l´mÑ&CØØ— ‘ ˜dÕ#ð $ðˆ rc óº—|jd«d}|jd}|jd«d}|j|jd«d«}|jd«d}|j|«}|jd«d}|j |«} t j dd |«}t j d d |«}t j d d |«}|d jd «dk\r|ddf}d|||d |d || t«dœ } |d·d|dz} |j›d| ›} tjj| «s| S|j| «} | j| jd«}|t|«r|| d<| jd«}|,t|«r!|j| «dkr |›d| d›| d<| d| d<| S)Nú ./name/text()rÚidú./definition/text()ú./typeú./briefdescriptionú./detaileddescriptionr Úrú\*éú(Ú composite© ÚcategoryÚ definitionr<ÚIdÚ initializerÚtypeÚshort_descriptionÚlong_descriptionr"z%s.xmlrr rSr!ú rTr")r%r*Ú_process_type_noder&r'ÚreÚsubÚfindr(rÚosr/Úexistsr8ÚgetÚlen)rr5Út_nameÚt_IdÚ t_definitionÚt_typer2Út_briefr3Ú t_detailedÚ typedef_descrr-r/Ú compound_infor r!s rr=zDoxyTypes._process_typedef_nodees€Ø—‘˜OÓ,¨QÑ/ˆà{‰{˜4Ñ ˆØ—z‘zÐ"7Ó8¸Ñ;ˆ Ø×(Ñ(¨¯©°HÓ)=¸aÑ)@ÓAˆØ—Z‘ZÐ 4Ó5°aÑ8ˆ Ø×-Ñ-¨jÓ9ˆØ—z‘zÐ"9Ó:¸1Ñ=ˆ Ø×3Ñ3°LÓAˆ ä—v‘vÐ/°°\ÓBˆ Ü—v‘v˜o¨r°<Ó@ˆ Ü—v‘v˜e U¨LÓ9ˆ à !‰9>‰>˜#Ó  !Ò #ؘq™  $Ð'ˆfà%0Ø'3Ø!'Ø#Ø(*Ø!'¨¡Ø.5Ø-7Ü'+£vñ ˆ ð !‰9Ð Ø &¨¡)Ñ+ˆHØ"Ÿl›l©8Ð4ˆDÜ—7‘7—>‘> $Ô'à$Ð$à ×-Ñ-¨hÓ7ˆMØÐ(Ø%2×%6Ñ%6Ð7JÓ%KÐ!Ø$Ð0´SÐ9JÔ5Kà9JMÐ"5Ñ6Ø'4×'8Ñ'8Ð9OÓ'PÐ$Ø'Ð3¼Ðð=@˜ Ð&8Ñ9ð/<¸LÑ.I ˜lÑ+ØÐrc ó—|jd«d}|jd}|jd«d}|j|jd«d«}|jd«d}|j|«}|jd«d}|j |«} t j dd |«}t j d d |«}t j d d |«}d |||d |d || t«dœ } | S)NrBrrCrDrErFrGr rHrrIrrJrM)r%r*rVr&r'rWrXr() rr5Úv_nameÚv_IdÚ v_definitionÚv_typer2Úv_briefr3r!Úvariable_descrs rr+z DoxyTypes._process_variable_node˜s€Ø—‘˜OÓ,¨QÑ/ˆØ{‰{˜4Ñ ˆØ—z‘zÐ"7Ó8¸Ñ;ˆ Ø×(Ñ(¨¯©°HÓ)=¸aÑ)@ÓAˆØ—Z‘ZÐ 4Ó5°aÑ8ˆ Ø×-Ñ-¨jÓ9ˆØ—z‘zÐ"9Ó:¸1Ñ=ˆ Ø#×=Ñ=¸lÓKÐä—v‘vÐ/°°\ÓBˆ Ü—v‘v˜o¨r°<Ó@ˆ Ü—v‘v˜e U¨LÓ9ˆ à&0Ø(4Ø"(Ø $Ø)+Ø"(¨¡)Ø/6Ø.BÜ(,«ñ ˆðÐrc ó —|jd«d}d}d}d}t|jd««dkDr”d}t«}|jd«D]3}|j|«} | €Œt| «sŒ#|j | «Œ5||j |«}d|›d|›d}t jd d |«j«}t|jd ««dkDrt|jd ««} t|jd ««dkDr#|j|jd «d«}t|«dkDr™t|jd ««} | dk(r |dr|d}| dkDr:t|jd «d«dkDr|jd «d|dz}| dkDr@|jd «d,||jd «dz}n|jd «d}|jd} |jd«d} |j| «}|jd«d}|j|«}t jdd|«}dd||| |d||t«dœ }|S)NrBrrHz./param/defnamez./paramú z (z) z, \)ú)z ./initializerz./initializer/refz./initializer/text()rJrCrFrGz *\\ *rL) rNrOr<Úname_signaturerPrQrRrSrTr") r%r]r(Ú_process_paragraph_contentr,ÚjoinrWrXÚstriprVr*r&r')rr5Úd_nameÚ d_initializerÚd_typeÚ d_signatureÚprm_strÚprm_listÚpÚxÚlen_refÚlen_textÚd_Idr2Úd_briefr3r!Ú define_descrs rr>zDoxyTypes._process_define_node³s}€Ø—‘˜OÓ,¨QÑ/ˆØˆ ؈؈ ô ˆtz‰zÐ+Ó,Ó -°Ò 1؈GÜ“vˆHØ—Z‘Z  Ó*ò &Ø×3Ñ3°AÓ6Ø‘=¤S¨¥VØ—?‘? 1Õ%ð &ðÐ#Ø!Ÿ,™, xÓ0øÚ)/²'Ð:ˆKÜŸ&™& ¨#¨{Ó;×AÑAÓCˆKä ˆtz‰z˜/Ó*Ó +¨aÓ /ܘ$Ÿ*™*Ð%8Ó9Ó:ˆGÜ4—:‘:Ð1Ó2Ó3°aÒ7Ø×0Ñ0°·±Ð... sections. There are few types of these sections: a) Content section b) Return value section -- skip c) Parameter list section -- skip @param node: detailed description node r‚z./simplesect[@kind='return']z./parameterlist[@kind='param']rU)r(r%r]rqr,rrrƒs rr'z#DoxyTypes._get_detailed_description÷s~€ô“ˆØ—‘˜HÓ%ò !ˆAÜ1—7‘7Ð9Ó:Ô;ØÜQ—W‘WÐ=Ó>Ô?Øà×3Ñ3°AÓ6Ø— ‘ ˜aÕ ð !𗑘6Ó"ˆàˆ rc ó—d„}t«}|jd«}|D]Ô}|js||j«ur|||j ««Œ:|j«j dk(rƒ|j «j d«dkDr||d|j «z«Œ”|j«r||d|j «z«Œ¿||d|j «z«ŒÚ|j«j d k(r||d |j «z«Œ|j«j d k(r||d |j «z«ŒL|j«j d k(r||d |j «z«Œ…|j«j dk(sŒ¤||d«||tj|dd„««||d«Œ×dj|«}|S)Ncó–—|r6|djd«s"|jd«s|jd«|j|«y)NéÿÿÿÿrUrn)ÚendswithÚ startswithr,)ÚlÚss rÚadd_textz6DoxyTypes._process_paragraph_content..add_texts5€á˜˜2™Ÿ™¨Ô-°a·l±lÀ4Ô6HØ—‘˜” Ø H‰HQKrú .//text()ÚrefrKrz :c:func:`%s`z :c:data:`%s`z :c:type:`%s`Úemphasisz*%s*ÚcomputeroutputÚdefnamez%s, Úverbatimz :: z có—y)NT©)r{s rúz6DoxyTypes._process_paragraph_content..)srrUrH) r(r%Úis_tailÚ getparentrsÚtagrYÚisupperÚtextwrapÚindentrr)rr5rŒr7ÚcontentÚes rrqz$DoxyTypes._process_paragraph_content s“€ò ô “ˆØ—*‘*˜[Ó)ˆØó 'ˆAØyŠy˜D A§K¡K£MÑ1Ù˜ §¡£Õ+Ø—‘“×"Ñ" eÒ+Ø—7‘7“9—>‘> #Ó&¨Ò*Ù˜V ^°a·g±g³iÑ%?Õ@Ø—Y‘Y”[Ù˜V ^°a·g±g³iÑ%?Õ@á˜V ^°a·g±g³iÑ%?Õ@Ø—‘“×"Ñ" jÒ0Ù˜ ¨!¯'©'«)Ñ!3Ö4Ø—‘“×"Ñ"Ð&6Ò6Ù˜ ¨!¯'©'«)Ñ!3Ö4Ø—‘“×"Ñ" iÒ/Ù˜ ¨!¯'©'«)Ñ!3Ö4Ø—‘“×"Ñ" jÔ0Ù˜ Ô,Ù˜¤§¡°°F¹NÓ!KÔLÙ˜ Ö&ð' 'ð*—‘˜“ˆàˆ rcó—|jd«}t|«dk(r|d}nt|«dk(rd}dj|jd««}tjdd|«}tjdd|«}||fS) aR Type node has form type_string for build in types and 'type_name' postfix (ex. *, **m, etc.) for user defined types. z ./ref/@refidrJrNrnrr r)r%r]rrrWrX)rr5Úp_idÚp_types rrVzDoxyTypes._process_type_node0s~€ðz‰z˜.Ó)ˆÜ ˆt‹9˜Š>ؘ‘7‰DÜ ‹Y˜!Š^؈DØ—‘˜$Ÿ*™* [Ó1Ó2ˆô—‘Ð)¨3°Ó7ˆÜ—‘˜¨¨fÓ5ˆàVˆ}Ðrcój—||j}|›d|j›d}|j||«y)Nrz.rst)rNr<Úsave)rÚobjÚ templatesÚ target_dirÚ template_pathÚoutpaths rr¢zDoxyTypes.saveJs,€Ø! #§,¡,Ñ/ˆ Ú!+¨C¯H«HÐ5ˆØ ‰˜-Õ(rr)Ú__name__Ú __module__Ú __qualname__rr8r@r=r+r>r&r'rqrVr¢r”rrrr)s<„òóó:ò61òfò66òròò,!òFó4)rrcó<‡—eZdZˆfd„Zd„Zd„Zd„Zd„Zd„ZˆxZ S)ÚDoxyBuilderTypescóL•—ddi|_||_tt||«y)NrLztype_document.tmpl)r¤r¥Úsuperr¬r)rrÚrstpathÚ __class__s €rrzDoxyBuilderTypes.__init__Rs'ø€Ø&Ð(<Ð=ˆŒØ!ˆŒä Ô˜tÑ-¨gÕ6rcóD—|j«|j«yr)Úprocess_typedef_nodesÚprocess_define_nodes)rs rÚrun_allzDoxyBuilderTypes.run_allXs€Ø ×"Ñ"Ô$Ø ×!Ñ!Õ#rcó*—d}|j|«y)Nú krb5_8hin.xml©r@)rr-s rÚtest_runzDoxyBuilderTypes.test_run\s€Ø"ˆØ ‰Õrcó0—d}|j|dg¬«}y)Nzstruct__krb5__octet__data.xmlr©r.r·)rr-r7s rÚprocess_variable_nodesz'DoxyBuilderTypes.process_variable_nodes`s€Ø2ˆØ—‘˜(¨Z¨LÓ9‰rcó—d}|j|dg¬«}d|jz}tjj |«stj |d«|D]*}t di|¤Ž}|j||j|«Œ,y)Nr¶r:rºz%s/typeséír”) r@r¥rZr/r[ÚmakedirsÚDocModelr¢r¤)rr-r7r¥Útr£s rr²z&DoxyBuilderTypes.process_typedef_nodesdsu€à"ˆØ—‘˜(¨Y¨KÓ8ˆØ 4§?¡?Ñ3ˆ Üw‰w~‰~˜jÔ)Ü K‰K˜  EÔ *Øò 7ˆAÜ‘-˜Q‘-ˆCØ I‰Ic˜4Ÿ>™>¨:Õ 6ñ 7rcó —d}|j|dg¬«}d|jz}tjj |«stj |d«|D]$}t di|¤Ž}ddi}|j|||«Œ&y) Nr¶r;rºz %s/macrosr½rLzdefine_document.tmplr”)r@r¥rZr/r[r¾r¿r¢)rr-r7r¥rÀr£Útmpls rr³z%DoxyBuilderTypes.process_define_nodesos|€à"ˆØ—‘˜(¨X¨JÓ7ˆØ  D§O¡OÑ4ˆ Üw‰w~‰~˜jÔ)Ü K‰K˜  EÔ *Øò -ˆAÜ‘-˜Q‘-ˆCØÐ!7Ð8ˆDØ I‰Ic˜4 Õ ,ñ -r) r¨r©rªrr´r¸r»r²r³Ú __classcell__)r°s@rr¬r¬Qs!ø„ô7ò $òò:ò 7ö -rr¬Ú__main__)Ú__doc__ÚsysrZrWršÚlxmlrÚdocmodelr?Úobjectrr¬r¨Ú xml_inpathÚ rst_outpathÚbuilderr´r”rrúrÍsfðñó0 Û Û Ûåäò5€ ôd)ôd)ôP (-yô(-ðT ˆzÒá  ¨KÓ8€GØ ‡OOÕðrkrb5-1.22.1/doc/tools/__pycache__/docmodel.cpython-312.pyc0000664000175000017500000003547315051422641022764 0ustar ghudsonghudsonË  %¦h9#ãóØ—dZddlZddlmZGd„de«ZGd„d«ZGd„d e«ZGd „d e«ZGd „d e«Z Gd„de «Z e dk(re «Z e j«yy)aŸ Copyright 2011 by the Massachusetts Institute of Technology. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. éN)ÚTemplatecó—eZdZd„Zd„Zy)Ú Attributec ó8—|jd«|_|jd«|_|jd«|_|jd«|_|jd«|_|jd«|_|jd«|_y)NÚ definitionÚnameÚtypeÚtypeIdÚshort_descriptionÚlong_descriptionÚversion)Úgetrrr r r r r ©ÚselfÚargkws ú&/tmp/krb5-1.22.1/doc/tools/docmodel.pyÚ__init__zAttribute.__init__sv€ØŸ)™) LÓ1ˆŒØ—I‘I˜fÓ%ˆŒ Ø—I‘I˜fÓ%ˆŒ Ø—i‘i Ó)ˆŒ Ø!&§¡Ð+>Ó!?ˆÔØ %§ ¡ Ð*<Ó =ˆÔØ—y‘y Ó+ˆ ócó®—t«}|jj«D]\}}|j|›d|›«Œddj |«zS)Nú=z Attribute: %sú,)ÚlistÚ__dict__Ú iteritemsÚappendÚjoin)rÚresultÚattrÚvalues rÚ__repr__zAttribute.__repr__&sN€Ü“ˆØ ŸM™M×3Ñ3Ó5ò 2‰LˆT%Ø M‰M¢T©%Ð0Õ 1ð 2à §¡¨&Ó!1Ñ1Ð1rN©Ú__name__Ú __module__Ú __qualname__rr ©rrrrs „ò,ó2rrcó*—eZdZd„Zd„Zd„Zd„Zd„Zy)Ú CompositeTypec ón—d|_|jd«|_|jd«|_|jd«|_|jd«|_|jd«|_|jdd«|_|jd «|_|jd «|_ |jd «|_ |jd «|_ |jd «|_ |jd«|_ |j|jd««|_y)NÚ compositerrÚname_signatureÚIdÚ initializerÚactiveFr Ú return_typer r Úfriendsr Ú attributes)Úcategoryrrrr*r+r,r-r r.r r r/r Ú_setAttributesr0rs rrzCompositeType.__init__.sí€Ø#ˆŒ ØŸ)™) LÓ1ˆŒØ—I‘I˜fÓ%ˆŒ Ø#Ÿi™iÐ(8Ó9ˆÔØ—)‘)˜D“/ˆŒØ Ÿ9™9 ]Ó3ˆÔØ—i‘i ¨%Ó0ˆŒ Ø—y‘y Ó+ˆŒ Ø Ÿ9™9 ]Ó3ˆÔØ!&§¡Ð+>Ó!?ˆÔØ %§ ¡ Ð*<Ó =ˆÔØ—y‘y Ó+ˆŒ Ø—I‘I˜fÓ%ˆŒ Ø×-Ñ-¨e¯i©i¸ Ó.EÓFˆrcó—t«}|jj«D]H\}}|dk(r(|&|Dcgc]}d|z‘Œ }}ddj|«z}|j |›d|›«ŒJdj|«}|Scc}w)Nr0z%sz %sz z: ú )rrrrr)rrrrÚar0s rr zCompositeType.__repr__>sŒ€Ü“ˆØ ŸM™M×3Ñ3Ó5ò 3‰LˆT%Ø|Ò#ØÐ$Ø49Ö!:¨q $¨£(Ð!:JÐ!:Ø$ v§{¡{°:Ó'>Ñ>Eà M‰M¢d©5Ð1Õ 2ð  3𗑘6Ó"ˆàˆ ùò ";s¶ Bcód—d}|+t«}|D]}|jtdi|¤Ž«Œ|S©Nr%)rrr)rr0rr5s rr2zCompositeType._setAttributesKó<€ØˆØ Ð !Ü“VˆFØò .Ø— ‘ œi™n¨!™nÕ-ð .ðˆ rcó>—tjdd|«}d|z}|S)NÚ_ú-z _%s-struct©ÚreÚsub©rrrs rÚstruct_referencezCompositeType.struct_referenceTs#€Ü—‘˜˜c 4Ó(ˆØ Ñ&ˆàˆ rcó>—tjdd|«}d|z}|S)Nr:r;z_%s-datar<r?s rÚmacro_referencezCompositeType.macro_referenceZs#€Ü—‘˜˜c 4Ó(ˆØ˜fÑ$ˆàˆ rN)r"r#r$rr r2r@rBr%rrr'r'-s„òGò òòó rr'có—eZdZd„Zd„Zy)Ú Parameterc ó8—|jd«|_|jd«|_|jd«|_|jd«|_|jd«|_|jd«|_|jd«|_y)NÚseqnorÚ directionr r Ú descriptionr )rrFrrGr r rHr rs rrzParameter.__init__ass€Ø—Y‘Y˜wÓ'ˆŒ Ø—I‘I˜fÓ%ˆŒ ØŸ™ ;Ó/ˆŒØ—I‘I˜fÓ%ˆŒ Ø—i‘i Ó)ˆŒ Ø Ÿ9™9 ]Ó3ˆÔØ—y‘y Ó+ˆ rcó”—|j|j|j|j|j|j f}d|zS)NzCParameter: name=%s,direction=%s,seqno=%s,type=%s,typeId=%s,descr=%s)rrGrFr r rH)rÚcontents rr zParameter.__repr__js:€Ø—9‘9˜TŸ^™^¨D¯J©J°t·y±yÀÇÁÈT×M]ÑM]Ð^ˆØTÐW^Ñ^Ð^rNr!r%rrrDrD`s „ò,ó_rrDcó0—eZdZd„Zd„Zd„Zd„Zd„Zd„Zy)ÚFunctionc óò—d|_|jd«|_|jd«|_|jdd«|_|jd«|_|j |jd««|_|jd«|_|jd «|_ |jd «|_ |jd «|_ |jd «|_ |jd «|_ |jd«|_|jd«|_|jd«|_|jd«|_|jd«|_y)NÚfunctionrr+r-Fr Ú parametersr.Úreturn_descriptionÚretval_descriptionÚwarn_descriptionÚsa_descriptionÚnotes_descriptionÚ version_numr r Údeprecated_descriptionr/)r1rrr+r-r Ú_setParametersrOr.rPrQrRrSrTrUr r rVr/rs rrzFunction.__init__os'€Ø"ˆŒ Ø—I‘I˜fÓ%ˆŒ Ø—)‘)˜D“/ˆŒØ—i‘i ¨%Ó0ˆŒ Ø—y‘y Ó+ˆŒ Ø×-Ñ-¨e¯i©i¸ Ó.EÓFˆŒØ Ÿ9™9 ]Ó3ˆÔØ"'§)¡)Ð,@Ó"AˆÔØ"'§)¡)Ð,@Ó"AˆÔØ %§ ¡ Ð*<Ó =ˆÔØ#Ÿi™iÐ(8Ó9ˆÔØ!&§¡Ð+>Ó!?ˆÔØ Ÿ9™9 ]Ó3ˆÔØ!&§¡Ð+>Ó!?ˆÔØ %§ ¡ Ð*<Ó =ˆÔØ&+§i¡iÐ0HÓ&IˆÔ#Ø—y‘y Ó+ˆ rcód—d}|+t«}|D]}|jtdi|¤Ž«Œ|Sr7)rrrD)rrOrÚps rrWzFunction._setParameters‚r8rcó|—t|j«|j|jg}dj |«S©Nr)Ústrr+rr1r©rrs rÚ getObjectRowzFunction.getObjectRow‹s3€Üd—g‘g“,Ø—)‘)Ø—-‘-ð!ˆðx‰x˜ÓÐrcó–—|j|j|j|j|jg}dj |«Sr[)r+r-r r r rr]s rÚgetObjectDescriptionRowz Function.getObjectDescriptionRow’sA€Ø—'‘'Ø—+‘+Ø—,‘,Ø×(Ñ(Ø×'Ñ'ð )ˆð x‰x˜ÓÐrcó8—t«}|jD]q}|j|j|j|j |j |j|jg}|jdj|««Œsdj|«S)Nrr4) rrOr+rrFr r rHr rr)rrrYÚp_rows rÚgetParameterRowszFunction.getParameterRows›s{€Ü“ˆØ—‘ò +ˆAØ—W‘WØ—V‘VØ—W‘WØ—V‘VØ—X‘XØ—]‘]Ø—Y‘Yð  ˆEð M‰M˜#Ÿ(™( 5›/Õ *ð +ðy‰y˜Ó Ð rcóЗt«}|jd|jz«|jd|jz«|jd|jz«|j Dcgc]}d|z‘Œ }}|jddj |«z«|jd|jz«|jd|jz«|jd |jz«|jd |jz«|jd |jz«|jd |jz«|jd |jz«|jd|jz«|jd|jz«|jd|j z«dj |«}|Scc}w)Nz Category: %szFunction name: %szFunction Id: %sz %szParameters: %sr4zFunction return type: %sz$Function return type description: %szFunction retval description: %szFunction short description: %szFunction long description: %szWarning description: %szSee also description: %szNOTE description: %szVersion introduced: %szDeprecated description: %s)rrr1rr+rOrr.rPrQr r rRrSrTrUrV)rÚlinesrYrOrs rr zFunction.__repr__©sˆ€Ü“ˆØ ‰ ^ d§m¡mÑ3Ô4Ø ‰ Ð(¨4¯9©9Ñ4Ô5Ø ‰ Ð&¨¯©Ñ0Ô1Ø*.¯/©/Ö: Qf˜q“jÐ:ˆ Ð:Ø ‰ Ð&¨¯©°:Ó)>Ñ>Ô?Ø ‰ Ð/°$×2BÑ2BÑBÔCØ ‰ Ð<¸t×?VÑ?VÑVÔWØ ‰ Ð7¸$×:QÑ:QÑQÔRØ ‰ Ð6¸×9OÑ9OÑOÔPØ ‰ Ð5¸×8MÑ8MÑMÔNØ ‰ Ð/°$×2GÑ2GÑGÔHØ ‰ Ð0°4×3FÑ3FÑFÔGØ ‰ Ð,¨t×/EÑ/EÑEÔFØ ‰ Ð.°×1AÑ1AÑAÔBØ ‰ Ð2°T×5PÑ5PÑPÔQØ—‘˜5Ó!ˆàˆ ùò;sÁ3 G#N) r"r#r$rrWr^r`rcr r%rrrLrLns „ò,ò&ò ò ò !órrLcó$—eZdZd„Zd„Zd„Zd„Zy)ÚDocModelc ó°—t|«rK|d|_|ddk(rd|_tdi|¤Ž|_y|ddk(rd|_t di|¤Ž|_yyy)Nrr1rNr)r%)Úlenrr1rLrNr'r)rs rrzDocModel.__init__Àsd€Ü ˆuŒ:ؘf™ ˆDŒIØZÑ  JÒ.Ø *” Ü (Ñ 1¨5Ñ 1• ØzÑ" kÒ1Ø +” Ü!.Ñ!7°Ñ!7•ð2ð rcóD—t||j«}t|«S©N)Úgetattrr1r\)rÚobjs rr zDocModel.__repr__Ês€Üd˜4Ÿ=™=Ó)ˆÜ3‹xˆrcóŠ—t«}|jjD][}|jdur!|j |j›dd›«Œ2|j |j›d|j ›«Œ]dj |«}|jj›d|jj ›d|›d}|S)Nz... ú z, ú(ú))rrNrOr rrrr.)rÚ param_listrYrs rÚ signaturezDocModel.signatureÎs›€Ü“Vˆ Ø—‘×)Ñ)ò >ˆAØv‰v˜ÑØ×!Ñ!¨Q¯V«V±CÐ"8Õ9à×!Ñ!¨Q¯V«V°Q·V²VÐ"<Õ=ð  >ð —Y‘Y˜zÓ*ˆ Ø $§ ¡ × 9Ó 9Ø $§ ¡ × 2Ó 2²Jð@ˆðˆ rcóÜ—t|d«}t|j«|«}t|d«}|jt |««|j «|j «y)NÚrÚw)ÚopenrÚreadÚwriter\Úclose)rÚpathÚ template_pathÚfÚtÚouts rÚsavez DocModel.saveÛsM€Ü  Ó $ˆÜ Q—V‘V“X˜dÓ #ˆÜ4˜‹oˆØ ‰ ”#a“&ÔØ ‰ Œ Ø ‰ rN)r"r#r$rr rsr€r%rrrgrg¿s„ò8òò órrgcó0‡—eZdZˆfd„Zd„Zd„Zd„ZˆxZS)Ú DocModelTestcón•—d}tjt|d««}tt|di|¤Žy)Nz../docutil/example.ymlrur%)ÚyamlÚloadrwÚsuperr‚r)rÚdoc_pathrÚ __class__s €rrzDocModelTest.__init__ås/ø€Ø+ˆÜ— ‘ œ$˜x¨Ó,Ó-ˆÜ Œl˜4Ñ)Ñ2¨EÓ2rcó$—|j«yrk)Ú test_save©rs rÚ run_testszDocModelTest.run_testsês €Ø ‰Õrcó0—td«t|«y)NÚtesting)Úprintr‹s rÚ test_printzDocModelTest.test_printís€Ü ˆiÔÜ ˆd rcó0—d}d}|j||«y)Nz../docutil/function2edit.htmlz;/var/tsitkova/Sources/v10/trunk/documentation/test_doc.html)r€)rr|r{s rrŠzDocModelTest.test_saveòs€Ø7ˆ àLˆà ‰ $˜ Õ&r)r"r#r$rrŒrrŠÚ __classcell__)rˆs@rr‚r‚äsø„ô3ò òö 'rr‚Ú__main__)Ú__doc__r=ÚCheetah.TemplaterÚobjectrr'rDrLrgr‚r"ÚtesterrŒr%rrúr˜sðñó. å%ô2ô2÷"1ñ1ôf _ô _ôNˆvôNôb"ˆvô"ôJ'8ô'ð* ˆzÒÙ ‹^€FØ ×ÑÕðrkrb5-1.22.1/doc/tools/__pycache__/doxybuilder_funcs.cpython-312.pyc0000664000175000017500000006533415051422641024725 0ustar ghudsonghudsonË  %¦hÔTãóø—dZddlZddlZddlmZddlmZddlmZddl ­dgZ Gd„d e «Z Gd „d e«Z Gd „d e «ZGd„de«ZGd„de«Zedk(reee«Zej+«yy)aŸ Copyright 2011 by the Massachusetts Institute of Technology. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. éN)Ú defaultdict)Ú make_parser)ÚContentHandler)Ú*Úkrb5_free_octet_datacó,—eZdZdZd„Zgfd„Zd„Zd„Zy)ÚDocNodez/ Represents the structure of xml node. cóv—||_t«|_t«|_t t«|_y)a @param node: name - the name of a node. @param attributes: a dictionary populated with attributes of a node @param children: a dictionary with lists of children nodes. Nodes in lists are ordered as they appear in a document. @param content: a content of xml node represented as a list of tuples [(type,value)] with type = ['char'|'element']. If type is 'char' then the value is a character string otherwise it is a reference to a child node. N)ÚnameÚlistÚcontentÚdictÚ attributesrÚchildren)Úselfr s ú//tmp/krb5-1.22.1/doc/tools/doxybuilder_funcs.pyÚ__init__zDocNode.__init__&s)€ðˆŒ Ü“vˆŒ Ü›&ˆŒÜ#¤DÓ)ˆ ócóö—t«}|j|j|d«}|j|d«||d<|jD]L\}}|dk(r|dk7sŒ|j|«Œ#|j |d|«}|€Œ9|jd|z«ŒN|j «|d<||dj|««}|.|dk(rtjdd|«}|S|j«}|S)NÚdefaultÚcharÚéz %s z[ ]+ú ) r Úgetr Úappendr ÚwalkÚpopÚjoinÚreÚsubÚstrip) rÚ decoratorsÚsub_wsÚstackÚresultÚ decoratorÚobj_typeÚobjÚpartials rrz DocNode.walk6sö€Ü“ˆØ—N‘N 4§9¡9¨j¸Ñ.CÓDˆ Ø ‰ Z  Ñ*Ô+Ø )ˆ 9Ñà"Ÿl™lò 4‰NˆXcؘ6Ò!ؘ"“9Ø—M‘M #Õ&àŸ(™( :¨a°Ó7ØÑ&Ø—M‘M &¨7Ñ"2Õ3ð 4ð!&§ ¡ £ ˆ 9ÑÙ˜4 §¡¨£Ó1ˆØ РؘŠ{ÜŸ™ ¨¨vÓ6ðˆ ð Ÿ™›àˆ rcóT—dd„i}|j|d«}t|«dk(rd}|S)Nrcó—|S©N©)ÚnodeÚvalues rúz$DocNode.getContent..Os€°E€rrr)rÚlen)rr#r&s rÚ getContentzDocNode.getContentNs3€ØÑ!9Ð:ˆ Ø—‘˜: qÓ)ˆÜ ˆv‹;˜!Ò ØˆFàˆ rcó8—d|jzg}|jj«D]\}}|jd|›d|›«Œ|jj«D]$\}}|jd|t |«fz«Œ&dj |«S)Nz Content: %szAttr: z = z Child: %s,%iú )r rÚ iteritemsrrr2r)rr&Úkeyr0s rÚ__repr__zDocNode.__repr__Vs€Ø $§,¡,Ñ.Ð/ˆàŸ?™?×4Ñ4Ó6ò 9‰KˆSØ MŠMªS±Ð7Õ 8ð 9àŸ=™=×2Ñ2Ó4ò =‰KˆSØ M‰M˜.¨C´°E³ Ð+;Ñ;Õ <ð =ðy‰y˜Ó Ð rN)Ú__name__Ú __module__Ú __qualname__Ú__doc__rrr3r8r.rrr r "s „ñò*ð .0óò0ó!rr có0—eZdZd„Zd„Zd„Zd„Zd„Zd„Zy)ÚDoxyContenHandlercóV—||_tt«|_d|_d|_yr-)ÚbuilderrÚintÚcountersÚ_nodesÚ_current)rr@s rrzDoxyContenHandler.__init__as#€ØˆŒ Ü#¤CÓ(ˆŒ ؈Œ ؈ rcó—yr-r.©rs rÚ startDocumentzDoxyContenHandler.startDocumentgs€Ø rcó —ddl}y)Nr)Úsys)rrIs rÚ endDocumentzDoxyContenHandler.endDocumentjs€Ürcóö—||jjk(rg|_|dk(r5|jd«}|€ t d«‚|j |xxdz cc<|j€yt |«}|j«D]\}}||j|<Œ|jM|jj|j|«|jj|j«||_ y)NÚ memberdefÚkindzKind is not definedr) r@ÚtoplevelrCrÚ ValueErrorrBr ÚitemsrrDrr)rr ÚattrsrMr/r7r0s rÚ startElementzDoxyContenHandler.startElementms×€Ø 4—<‘<×(Ñ(Ò (؈DŒKà ;Ò Ø—9‘9˜VÓ$ˆD؈|Ü Ð!6Ó7Ð7Ø M‰M˜$Ó  1Ñ $Ó à ;‰;Ð Ø ät‹}ˆØ Ÿ;™;›=ò )‰KˆSØ#(ˆDO‰O˜CÒ ð )à =‰=Ð $Ø M‰M× "Ñ " 4Ñ (× /Ñ /°Ô 5Ø K‰K× Ñ ˜tŸ}™}Ô -؈ rcóˆ—|j6|jjjd|j«f«yy)Nr)rDr rr")rr s rÚ characterszDoxyContenHandler.characters‚s4€à =‰=Ð $Ø M‰M× !Ñ !× (Ñ (¨&°·±³Ð)AÕ Bð %rcó¤—||jjk(rXt|j«dk(sJ‚d|_|jjj |j «d|_y|jS|j }|jj«|_|j jj d|f«yy)NrÚelement) r@rNr2rCÚdocumentrrDrr )rr r/s rÚ endElementzDoxyContenHandler.endElement‡sœ€Ø 4—<‘<×(Ñ(Ò (Üt—{‘{Ó# qÒ(Ð )Ð(؈DŒKØ L‰L× !Ñ !× (Ñ (¨¯©Ô 7Ø ˆDMà{‰{Ð&Ø—}‘}Ø $§ ¡ §¡Ó 1” Ø— ‘ ×%Ñ%×,Ñ,¨i¸Ð-=Õ>ð'rN) r9r:r;rrGrJrRrTrXr.rrr>r>`s!„òò  òòò*Có ?rr>có—eZdZdZdd„Zy)ÚXML2ASTz† Translates XML document into Abstract Syntax Tree like representation The content of document is stored in self.document cóö—t«|_||_t«|_t |«}|jj |«d}|›d|›}|jjt|d««y)Nz krb5_8hin.xmlú/Úr) r rWrNrÚparserr>ÚsetContentHandlerÚparseÚopen)rÚxmlpathrNÚhandlerÚfilenameÚfilepaths rrzXML2AST.__init__™s_€Ü›ˆŒ Ø ˆŒ Ü!“mˆŒ Ü# DÓ)ˆØ ‰ ×%Ñ% gÔ.Ø"ˆÚ%¡hÐ/ˆØ ‰ ×Ñœ$˜x¨Ó,Õ-rN)Údoxygen)r9r:r;r<rr.rrrZrZ”s „ñô.rrZc󸇗eZdZˆfd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zdd„Zdd„ZˆxZS)Ú DoxyFuncscóN•—tt| |d¬«t«|_y)NrL)rN)Úsuperrhrr Úobjects)rÚpathÚ __class__s €rrzDoxyFuncs.__init__¥s ø€Ü Œi˜Ñ'¨°kÐ'ÔBÜ“vˆ rcóH—|jD]}|j|«Œyr-)rWÚprocess)rr/s rÚrunz DoxyFuncs.run©s!€Ø—M‘Mò ˆDØ L‰L˜Õ ñ rcóº—|jd}|dk(r|j|«}nyd|vr |dtvry|jj t di|¤Ž«y)NrMÚfunctionr r.)rÚ_process_function_nodeÚ exclude_funcsrkrÚDocModel)rr/Ú node_typeÚdatas rrozDoxyFuncs.process­sZ€Ø—O‘O FÑ+ˆ Ø ˜ Ò "Ø×.Ñ.¨tÓ4‰Dà à T‰>˜d 6™l¬mÑ;Ø Ø ‰ ×ÑœHÑ, tÑ,Õ-rcóŒ—|jD]5}||j}|›d|j›d}|j||«Œ7y)Nr\z.rst)rkÚcategoryr Úsave)rÚ templatesÚ target_dirr)Ú template_pathÚoutpaths rrzzDoxyFuncs.save¸s?€Ø—<‘<ò -ˆCØ% c§l¡lÑ3ˆMÚ%/°·³Ð9ˆGØ H‰HW˜mÕ ,ñ -rcóÊ—|jddj«}|jd}|j|jdd«}|jddj«}|jdd}|j |«}|j |«}|j |«} |j|«} |j|«} |j|«} |j|«} |j|«}|j|«}|jddj«}|jddj«}d |||d || | | | || ||t«d œ}|d }t|jd «D]©\}}|jdd}|j|«}|d jd«dkDrd}nd}|jj!d«}||dj«}|j!|d«\}}||||d |d|dœ}|j#|«Œ«t%di|¤Ž}t'||j(¬«|S)Nr rÚidÚtypeÚbriefdescriptionÚdetaileddescriptionÚ definitionÚ argsstringrrr)ryr ÚIdÚ return_typeÚreturn_descriptionÚretval_descriptionÚsa_descriptionÚwarn_descriptionÚnotes_descriptionÚshort_descriptionÚ version_numÚlong_descriptionÚdeprecated_descriptionÚ parametersr‘Úparamz...éÿÿÿÿrÚdeclname)NN)Úseqnor Ú directionrÚtypeIdÚ description)Úfiler.)rr3rÚ_process_type_nodeÚ_process_description_nodeÚ!_process_return_value_descriptionÚ_process_retval_descriptionÚ_process_warning_descriptionÚ_process_seealso_descriptionÚ_process_notes_descriptionÚ_process_version_descriptionÚ_process_deprecated_descriptionÚprocess_parameter_descriptionr Ú enumerateÚfindrrÚFunctionÚprintÚtmp)rr/Úf_nameÚf_IdÚ f_ret_typeÚf_briefÚ f_detailedÚdetailed_descriptionÚreturn_value_descriptionr‰Úwarning_descriptionÚseealso_descriptionrŒÚ f_versionrÚparam_description_mapÚ f_definitionÚ f_argsstringÚfunction_descrr‘ÚiÚpÚ type_nodeÚp_typeÚp_nameÚ p_name_nodeÚ p_directionÚp_descrÚ param_descrr&s rrsz DoxyFuncs._process_function_node¿s†€Ø—‘˜vÑ& qÑ)×4Ñ4Ó6ˆØ‰˜tÑ$ˆØ×,Ñ,¨T¯]©]¸6Ñ-BÀ1Ñ-EÓFˆ Ø—-‘-Ð 2Ñ3°AÑ6×AÑAÓCˆØ—]‘]Ð#8Ñ9¸!Ñ<ˆ Ø#×=Ñ=¸jÓIÐØ#'×#IÑ#IÈ*Ó#UÐ Ø!×=Ñ=¸jÓIÐØ"×?Ñ?À ÓKÐØ"×?Ñ?À ÓKÐØ ×;Ñ;¸JÓGÐØ×5Ñ5°jÓAˆ Ø!%×!EÑ!EÀjÓ!QÐØ $× BÑ BÀ:Ó NÐØ—}‘} \Ñ2°1Ñ5×@Ñ@ÓBˆ Ø—}‘} \Ñ2°1Ñ5×@Ñ@ÓBˆ à&0Ø"(Ø $Ø)3°A©Ø0HØ0BØ,?Ø.AØ/@Ø/6Ø)2Ø.BØ4JÜ(,«ñ 0ˆð$ LÑ1ˆ ܘtŸ}™}¨WÑ5Ó6ò +‰EˆQˆqØŸ ™  6Ñ*¨1Ñ-ˆIØ×,Ñ,¨YÓ7ˆFØa‰y~‰~˜eÓ$ rÒ)Ø‘àØŸ*™*Ÿ.™.¨Ó4ˆKØÐ&Ø$ Q™×2Ñ2Ó4Ø$9×$=Ñ$=¸fÀ[Ó$QÑ !ˆ[˜à$%Ø#)Ø(3Ø#)¨!¡9Ø%+¨A¡YØ*1ñ 3ˆKð × Ñ ˜kÕ *ð% +ô&Ñ+˜NÑ+ˆÜ ˆf˜4Ÿ8™8Õ$àÐrcóf—|jjd«}||djd}nd}|j«}t j dd|«}t j dd|«}t j dd|«}t j d d|«}|j «}||fS) aR Type node has form type_string for build in types and 'type_name' postfix (ex. *, **m, etc.) for user defined types. ÚrefNrÚrefidÚKRB5_ATTR_DEPRECATEDrÚKRB5_CALLCONV_CÚKRB5_CALLCONV_WRONGÚ KRB5_CALLCONV)rrrr3r r!r")rr¹Ú type_ref_nodeÚ p_type_idrºs rršzDoxyFuncs._process_type_nodeùs©€ð"×*Ñ*×.Ñ.¨uÓ5ˆ Ø Ð $Ø% aÑ(×3Ñ3°GÑ<‰IàˆIØ×%Ñ%Ó'ˆä—‘Ð.°°FÓ;ˆÜ—‘Ð)¨2¨vÓ6ˆÜ—‘Ð-¨r°6Ó:ˆÜ—‘˜¨¨VÓ4ˆØ—‘“ˆà˜6Ð"Ð"rc ó—|jjd«}t«}|Pd|ji}|D]=}|j t |j |d«««|j d«Œ?dj|«}|S)zL Description node is comprised of ... sections Úpararrr5)rrr Úparagraph_content_decoratorrÚstrrr)rr/rÊr&r#Úes rr›z#DoxyFuncs._process_description_nodes€ð}‰}× Ñ  Ó(ˆÜ“ˆØ Ð Ø# T×%EÑ%EÐFˆJØò $Ø— ‘ œc !§&¡&¨°QÓ"7Ó8Ô9Ø— ‘ ˜dÕ#ð $𗑘6Ó"ˆàˆ rcó€—|jdk(r/|jddk(rt«}|j«}|Syy)NÚ simplesectrMÚreturn)r rÚsetr3)rr/r0Úconts rÚ"return_value_description_decoratorz,DoxyFuncs.return_value_description_decorator$sA€Ø 9‰9˜ Ò $؉˜vÑ&¨(Ò2Ü“uØ—‘Ó(Ø ð3ð rcóŠ—|jdk(r|dzS|jdk(r|jddk(ryy|jdk(r$|jd«dk\rd |zd zSd |zd zS|jd k(rd |zd zS|jdk(rd|zS|jdk(rd|zdzS|jdk(rd|zdzSy)NrÊr5rÏrMrÐrÁz()rz :c:func:`ú`z:data:`ÚemphasisrÚ itemizedlistÚlistitemz - Úcomputeroutputz**)r rr¥©rr/r0s rrËz%DoxyFuncs.paragraph_content_decorator-sè€Ø 9‰9˜Ò ؘ4‘<Ð Ø Y‰Y˜,Ò &؉˜vÑ&¨(Ò2Øð3à Y‰Y˜%Ò Øz‰z˜$Ó 1Ò$à'¨%Ñ/°#Ñ5Ð5ð&¨Ñ-°Ñ3Ð3Ø Y‰Y˜*Ò $ؘ‘; Ñ$Ð $Ø Y‰Y˜.Ò (ؘ%‘<Ð Ø Y‰Y˜*Ò $ؘuÑ$ tÑ+Ð +Ø Y‰YÐ*Ò *ؘ%‘< $Ñ&Ð &àrcó—|jdk(r&|jjd«}||›d|›}|S|jdk(ry|S)NÚ parameternamer–ú:Úparameterdescription)r rr)rr/r0r–s rÚparameter_name_decoratorz"DoxyFuncs.parameter_name_decoratorEsL€Ø 9‰9˜Ò 'ØŸ™×+Ñ+¨KÓ8ˆIØÐ$Ú#(©Ð3؈Là Y‰YÐ0Ò 0ØàˆLrcóH—|jdk(r|S|jdk(ry|S)NrÞrÜ)r rÚs rÚparameter_description_decoratorz)DoxyFuncs.parameter_description_decoratorQs(€Ø 9‰9Ð.Ò .؈LØ Y‰Y˜/Ò )ØàˆLrcóà—|jjd«}t«}|Æ|D]Á}|jjd«}|€Œ!|djjd«}|€ŒB|D]{}d|ji}d} |j |d«j d«} t | «dk(r| d } |j|jd œ}|j |d«} | | f|| d<Œ}ŒÃ|S) zT Parameter descriptions reside inside detailed description section. rÊNÚ parameterlistrÚ parameteritemrrÝér©rrÊ) rrrrßrÚsplitr2rárË) rr/rÊr&rÍÚ param_listÚ param_itemsÚitr#r–r r˜s rr£z'DoxyFuncs.process_parameter_descriptionYs€ð}‰}× Ñ  Ó(ˆÜ“ˆØ Ð Øò >àŸZ™ZŸ^™^¨OÓ< ØÐ%ØØ(¨™m×4Ñ4×8Ñ8¸ÓI ØÐ&ØØ%ò >BØ"+¨T×-JÑ-JÐ!KJØ $IØŸ7™7 :¨aÓ0×6Ñ6°sÓ;Dܘ4“y A’~Ø$(¨¡G˜ à-1×-QÑ-QØ*.×*JÑ*Jñ"LJà"$§'¡'¨*°aÓ"8KØ'0°Ð&=F˜4 ™7’Oñ >ð >ð&ˆ rcó.—d}t«}|jjd«}|k|D]f}|jjd«}|€Œ!|D]A}|j|jdœ}|j |d«}|€Œ1|j |«ŒCŒh|S©NrÊrÏrær)r rrrÓrßrr) rr/r&ÚretrÊr¸Úsimplesect_listrêr#s rrœz+DoxyFuncs._process_return_value_descriptionvs¤€ØˆÜ‹fˆà}‰}× Ñ  Ó(ˆØ Ð Øò +Ø"#§*¡*§.¡.°Ó">Ø"Ð*ØØ)ò+BØ-1×-TÑ-TØ*.×*GÑ*Gñ"IJàŸW™W Z°Ó3FØÑ)ØŸ ™  6Õ*ñ +ð +ðˆ rcój—|jjd«}d}t«}||D]}|jjd«}|€Œ"|D]Ü}|jd}|dk(sŒ|jjd«} | €Œ6| D]¢} | jjd«} | 6| djjd«} | | dj «} nd } d |j i}| j |d «jd «}|d} d | ›d ›}|j|«Œ¤ŒÞŒ|S)zQ retval descriptions reside inside detailed description section. rÊNrãrMÚretvalrärÞrrrrrÝrz ) rrr rr3rßrrçr)rr/rÊr&rírÍrèr¸rMrérêr¿ÚvalÚ val_descrr#r s rrz%DoxyFuncs._process_retval_description‰sG€ð}‰}× Ñ  Ó(ˆàˆÜ‹fˆØ Ñ àó 0ØŸZ™ZŸ^™^¨OÓ< ØÐ%ØØ#ò0AØŸ<™<¨Ñ/DؘxÓ'à&'§j¡j§n¡n°_Ó&E˜ Ø&Ð.Ø$ð#.ò0˜BØ*,¯+©+¯/©/Ð:PÓ*Q˜KØ*Ð6Ø&1°!¡n×&=Ñ&=×&AÑ&AÀ&Ó&I à#& ?Ø03°A±×0AÑ0AÓ0C¡Ið02 Ià*3°T×5RÑ5RÐ)S˜Jà#%§7¡7¨:°qÓ#9×#?Ñ#?ÀÓ#D˜Dà"& q¡'™CÚ25±yÐ%A˜FØŸJ™J¨Õ/ñ#0ò0ð  0ð>ˆ rcóL—|jdk(r|jddk(r|Syy)NrÏrMÚwarning©r rrÚs rÚreturn_warning_decoratorz"DoxyFuncs.return_warning_decorator´ó.€Ø 9‰9˜ Ò $؉˜vÑ&¨)Ò3Ø ð4ðrcó—d}|jjd«}|_|D]Z}|jjd«}|€Œ!|D]5}|j|jdœ}|j |d«}|€Œ1|ccSŒ\|Srì)rrrörËr©rr/r&rÊr¸rîrêr#s rržz&DoxyFuncs._process_warning_description»s–€ØˆØ}‰}× Ñ  Ó(ˆØ Ð Øò &Ø"#§*¡*§.¡.°Ó">Ø"Ð*ØØ)ò&BØ-1×-JÑ-JØ*.×*JÑ*Jñ"LJàŸW™W Z°Ó3FàÑ)Ø%œ ñ &ð &ðˆ rcóL—|jdk(r|jddk(r|Syy)NrÏrMÚseerõrÚs rÚreturn_seealso_decoratorz"DoxyFuncs.return_seealso_decoratorÌs.€Ø 9‰9˜ Ò $؉˜vÑ&¨%Ò/Ø ð0ðrcóò—d}|jjd«}|W|D]R}|jjd«}|€Œ!|D]-}|j|jdœ}|j |d«}Œ/ŒT|Srì)rrrürËrrùs rrŸz&DoxyFuncs._process_seealso_descriptionÓs‹€ØˆØ}‰}× Ñ  Ó(ˆØ Ð Øò 4Ø"#§*¡*§.¡.°Ó">Ø"Ð*ØØ)ò4BØ-1×-JÑ-JØ*.×*JÑ*Jñ"LJàŸW™W Z°Ó3‘Fñ4ð  4ðˆ rcóL—|jdk(r|jddk(r|Syy)NrÏrMÚversionrõrÚs rÚreturn_version_decoratorz"DoxyFuncs.return_version_decoratorár÷rcó—d}|jjd«}|_|D]Z}|jjd«}|€Œ!|D]5}|j|jdœ}|j |d«}|€Œ1|ccSŒ\|Srì)rrrrËrrùs rr¡z&DoxyFuncs._process_version_descriptionès–€ØˆØ}‰}× Ñ  Ó(ˆØ Ð Øò &Ø"#§*¡*§.¡.°Ó">Ø"Ð*ØØ)ò&BØ-1×-JÑ-JØ*.×*JÑ*Jñ"LJàŸW™W Z°Ó3FØÑ)Ø%œ ñ &ð &ðˆ rcól—|jdk(r%|jddk(r|jdd«Syy)NrÏrMÚnotez z )r rÚreplacerÚs rÚreturn_notes_decoratorz DoxyFuncs.return_notes_decoratorøs:€Ø 9‰9˜ Ò $؉˜vÑ&¨&Ò0à—}‘} V¨ZÓ8Ð8ð1ðrcó—d}|jjd«}|_|D]Z}|jjd«}|€Œ!|D]5}|j|jdœ}|j |d«}|€Œ1|ccSŒ\|Srì)rrrrËrrùs rr z$DoxyFuncs._process_notes_descriptions–€ØˆØ}‰}× Ñ  Ó(ˆØ Ð Øò &Ø"#§*¡*§.¡.°Ó">Ø"Ð*ØØ)ò&BØ-1×-HÑ-HØ*.×*JÑ*Jñ"LJàŸW™W Z°Ó3FØÑ)Ø%œ ñ &ð &ðˆ rcó—|jdk(rv|jdjd«dkDrT|jj d«}|d3|jj d«}d|dj «z}|Syyy) NÚxrefsectr€Ú deprecated_r“Ú xreftitlerÚxrefdescriptionz DEPRECATED %s)r rr¥rrr3)rr/r0r Ú xrefdescrÚdeprecated_descrs rÚreturn_deprecated_decoratorz%DoxyFuncs.return_deprecated_decoratorsŠ€Ø 9‰9˜ Ò "؉˜tÑ$×)Ñ)¨-Ó8¸2Ò=Ø ŸM™M×-Ñ-¨kÓ: ؘQ‘<Ð+Ø $§ ¡ × 1Ñ 1Ð2CÓ DIØ'6¸À1¹×9PÑ9PÓ9RÑ'RÐ$Ø+Ð+ð,ð>ðrcó—d}|jjd«}|_|D]Z}|jjd«}|€Œ!|D]5}|j|jdœ}|j |d«}|€Œ1|ccSŒ\|S)NrÊrrær)rrrrËr)rr/r&rÊr¸Ú xrefsect_listrêr#s rr¢z)DoxyFuncs._process_deprecated_descriptions–€ØˆØ}‰}× Ñ  Ó(ˆØ Ð Øò &Ø !§ ¡ §¡¨zÓ : Ø Ð(ØØ'ò&BØ-1×-MÑ-MØ*.×*JÑ*Jñ"LJàŸW™W Z°Ó3FØÑ)Ø%œ ñ &ð &ðˆ rcóÞ—tdt|«|«t|«gz}t«}t|dd|dd«D]\}}|j |||«Œdj |«}|S)Nrr“rr5)Úranger2r Úziprr)rr0ÚlinelenÚbreaksr&ÚstartÚends rÚbreak_into_lineszDoxyFuncs.break_into_lines+sr€Üqœ˜U› GÓ,´°E³ ¨|Ñ;ˆÜ“ˆÜ˜v c r˜{¨6°!°"¨:Ó6ò ,‰KˆU3Ø M‰M˜%  cÐ*Õ +ð ,à—‘˜6Ó"ˆàˆ rcó¼—|€tj}n t|d«}|D]%}|jddj |«z«Œ'||j «yy)NÚwz%s ú,)rIÚstdoutraÚwriterÚclose)rÚtablerlÚfÚls rÚ_savezDoxyFuncs._save4sW€Ø ˆ<Ü— ‘ ‰AäT˜3“ˆAØò *ˆAØ G‰GF˜SŸX™X a›[Ñ(Õ )ð *à Ð Ø G‰GIð r)éRr-)r9r:r;rrprorzrsršr›rÓrËrßrár£rœrröržrürŸrr¡rr rr¢rr"Ú __classcell__©rms@rrhrh¤s‡ø„ôòò .ò-ò8òt#ò8 òòò0 òòò:ò&)òVòò"ò òòò òò òó ÷rrhcó*‡—eZdZˆfd„Zd„Zd„ZˆxZS)ÚDoxyBuilderFuncscó~•—tt| |«||_|j›dd›}t |d«|_y)Nr\zout.txtr)rjr'rr|rar¨)rrbÚrstpathÚoutfilerms €rrzDoxyBuilderFuncs.__init__As6ø€Ü Ô˜tÑ-¨gÔ6Ø!ˆŒØ!Ÿ_›_©iÐ8ˆÜ˜ Ó%ˆrcód—|j«ddi}|j||j«y)Nrrzfunc_document.tmpl)rprzr|)rr{s rÚrun_allzDoxyBuilderFuncs.run_allGs(€Ø ‰Œ ØÐ!5Ð6ˆ Ø ‰ )˜TŸ_™_Õ-rcó$—|j«yr-)rprFs rÚtest_runzDoxyBuilderFuncs.test_runLs €Ø ‰ r)r9r:r;rr,r.r$r%s@rr'r'@sø„ô&ò .ö rr'Ú__main__)r<rIr Ú collectionsrÚxml.saxrÚxml.sax.handlerrÚdocmodelrtÚobjectr r>rZrhr'r9rbr)r@r,r.rrúr5sŒðñó. Û å#ÝÝ*Üà'Ð(€ ô<!ˆfô<!ô|1?˜ô1?ôh .ˆfô .ô XôXôx yô ð ˆzÒÙ˜w¨Ó0€GØ ‡OOÕðrkrb5-1.22.1/doc/tools/define_document.tmpl0000664000175000017500000000154015051422640020274 0ustar ghudsonghudson.. highlight:: c .. $composite.macro_reference($composite.name): #set $title = $composite.name $title #echo ''.join(['=']*len($title)) # .. .. data:: $composite.name .. #if $composite.short_description is not None and len($composite.short_description) $composite.short_description #end if $composite.long_description #if $composite.name_signature is not None and len($composite.name_signature) #echo ''.join(['=']*(len($composite.name_signature)+4)) + '== ======================' # ``$composite.name_signature`` ``$composite.initializer`` #echo ''.join(['=']*(len($composite.name_signature)+4)) + '== ======================' # #else #echo ''.join(['=']*(len($composite.name)+4)) + '=== ======================' # ``$composite.name`` ``$composite.initializer`` #echo ''.join(['=']*(len($composite.name)+4)) + '=== ======================' # #end if krb5-1.22.1/doc/tools/doxybuilder_funcs.py0000664000175000017500000005232415051422640020356 0ustar ghudsonghudson''' Copyright 2011 by the Massachusetts Institute of Technology. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ''' import sys import re from collections import defaultdict from xml.sax import make_parser from xml.sax.handler import ContentHandler from docmodel import * exclude_funcs = ['krb5_free_octet_data'] class DocNode(object): """ Represents the structure of xml node. """ def __init__(self, name): """ @param node: name - the name of a node. @param attributes: a dictionary populated with attributes of a node @param children: a dictionary with lists of children nodes. Nodes in lists are ordered as they appear in a document. @param content: a content of xml node represented as a list of tuples [(type,value)] with type = ['char'|'element']. If type is 'char' then the value is a character string otherwise it is a reference to a child node. """ self.name = name self.content = list() self.attributes = dict() self.children = defaultdict(list) def walk(self, decorators, sub_ws, stack=[]): result = list() decorator = decorators.get(self.name, decorators['default']) stack.append(decorators['default']) decorators['default'] = decorator for (obj_type,obj) in self.content: if obj_type == 'char': if obj != '': result.append(obj) else: partial = obj.walk(decorators,1, stack) if partial is not None: result.append(' %s ' % partial) decorators['default'] = stack.pop() result = decorator(self, ''.join(result)) if result is not None: if sub_ws == 1: result = re.sub(r'[ ]+', r' ', result) else: result = result.strip() return result def getContent(self): decorators = {'default': lambda node,value: value} result = self.walk(decorators, 1) if len(result) == 0: result = None return result def __repr__(self): result = ['Content: %s' % self.content] for (key,value) in self.attributes.iteritems(): result.append('Attr: %s = %s' % (key,value)) for (key,value) in self.children.iteritems(): result.append('Child: %s,%i' % (key,len(value))) return '\n'.join(result) class DoxyContenHandler(ContentHandler): def __init__(self, builder): self.builder = builder self.counters = defaultdict(int) self._nodes = None self._current = None def startDocument(self): pass def endDocument(self): import sys def startElement(self, name, attrs): if name == self.builder.toplevel: self._nodes = [] if name == 'memberdef': kind = attrs.get('kind') if kind is None: raise ValueError('Kind is not defined') self.counters[kind] += 1 if self._nodes is None: return node = DocNode(name) for (key,value) in attrs.items(): node.attributes[key] = value if self._current is not None: self._current.children[name].append(node) self._nodes.append(self._current) self._current = node def characters(self, content): if self._current is not None: self._current.content.append(('char',content.strip())) def endElement(self, name): if name == self.builder.toplevel: assert(len(self._nodes) == 0) self._nodes = None self.builder.document.append(self._current) self._current = None else: if self._nodes is not None: node = self._current self._current = self._nodes.pop() self._current.content.append(('element',node)) class XML2AST(object): """ Translates XML document into Abstract Syntax Tree like representation The content of document is stored in self.document """ def __init__(self, xmlpath, toplevel='doxygen'): self.document = list() self.toplevel = toplevel self.parser = make_parser() handler = DoxyContenHandler(self) self.parser.setContentHandler(handler) filename = 'krb5_8hin.xml' filepath = '%s/%s' % (xmlpath,filename) self.parser.parse(open(filepath,'r')) class DoxyFuncs(XML2AST): def __init__(self, path): super(DoxyFuncs, self).__init__(path,toplevel='memberdef') self.objects = list() def run(self): for node in self.document: self.process(node) def process(self, node): node_type = node.attributes['kind'] if node_type == 'function': data = self._process_function_node(node) else: return if 'name' in data and data['name'] in exclude_funcs: return self.objects.append(DocModel(**data)) def save(self, templates, target_dir): for obj in self.objects: template_path = templates[obj.category] outpath = '%s/%s.rst' % (target_dir,obj.name) obj.save(outpath, template_path) def _process_function_node(self, node): f_name = node.children['name'][0].getContent() f_Id = node.attributes['id'] f_ret_type = self._process_type_node(node.children['type'][0]) f_brief = node.children['briefdescription'][0].getContent() f_detailed = node.children['detaileddescription'][0] detailed_description = self._process_description_node(f_detailed) return_value_description = self._process_return_value_description(f_detailed) retval_description = self._process_retval_description(f_detailed) warning_description = self._process_warning_description(f_detailed) seealso_description = self._process_seealso_description(f_detailed) notes_description = self._process_notes_description(f_detailed) f_version = self._process_version_description(f_detailed) deprecated_description = self._process_deprecated_description(f_detailed) param_description_map = self.process_parameter_description(f_detailed) f_definition = node.children['definition'][0].getContent() f_argsstring = node.children['argsstring'][0].getContent() function_descr = {'category': 'function', 'name': f_name, 'Id': f_Id, 'return_type': f_ret_type[1], 'return_description': return_value_description, 'retval_description': retval_description, 'sa_description': seealso_description, 'warn_description': warning_description, 'notes_description': notes_description, 'short_description': f_brief, 'version_num': f_version, 'long_description': detailed_description, 'deprecated_description': deprecated_description, 'parameters': list()} parameters = function_descr['parameters'] for (i,p) in enumerate(node.children['param']): type_node = p.children['type'][0] p_type = self._process_type_node(type_node) if p_type[1].find('...') > -1 : p_name = '' else: p_name = None p_name_node = p.children.get('declname') if p_name_node is not None: p_name = p_name_node[0].getContent() (p_direction,p_descr) = param_description_map.get(p_name,(None,None)) param_descr = {'seqno': i, 'name': p_name, 'direction': p_direction, 'type': p_type[1], 'typeId': p_type[0], 'description': p_descr} parameters.append(param_descr) result = Function(**function_descr) print(result, file=self.tmp) return function_descr def _process_type_node(self, type_node): """ Type node has form type_string for build in types and 'type_name' postfix (ex. *, **m, etc.) for user defined types. """ type_ref_node = type_node.children.get('ref') if type_ref_node is not None: p_type_id = type_ref_node[0].attributes['refid'] else: p_type_id = None p_type = type_node.getContent() # remove some macros p_type = re.sub('KRB5_ATTR_DEPRECATED', '', p_type) p_type = re.sub('KRB5_CALLCONV_C', '', p_type) p_type = re.sub('KRB5_CALLCONV_WRONG', '', p_type) p_type = re.sub('KRB5_CALLCONV', '', p_type) p_type = p_type.strip() return (p_type_id, p_type) def _process_description_node(self, node): """ Description node is comprised of ... sections """ para = node.children.get('para') result = list() if para is not None: decorators = {'default': self.paragraph_content_decorator} for e in para: result.append(str(e.walk(decorators, 1))) result.append('\n') result = '\n'.join(result) return result def return_value_description_decorator(self, node, value): if node.name == 'simplesect': if node.attributes['kind'] == 'return': cont = set() cont = node.getContent() return value else: return None def paragraph_content_decorator(self, node, value): if node.name == 'para': return value + '\n' elif node.name == 'simplesect': if node.attributes['kind'] == 'return': return None elif node.name == 'ref': if value.find('()') >= 0: # functions return ':c:func:' + '`' + value + '`' else: # macro's return ':data:' + '`' + value + '`' elif node.name == 'emphasis': return '*' + value + '*' elif node.name == 'itemizedlist': return '\n' + value elif node.name == 'listitem': return '\n\t - ' + value + '\n' elif node.name == 'computeroutput': return '**' + value + '**' else: return None def parameter_name_decorator(self, node, value): if node.name == 'parametername': direction = node.attributes.get('direction') if direction is not None: value = '%s:%s' % (value,direction) return value elif node.name == 'parameterdescription': return None else: return value def parameter_description_decorator(self, node, value): if node.name == 'parameterdescription': return value elif node.name == 'parametername': return None else: return value def process_parameter_description(self, node): """ Parameter descriptions reside inside detailed description section. """ para = node.children.get('para') result = dict() if para is not None: for e in para: param_list = e.children.get('parameterlist') if param_list is None: continue param_items = param_list[0].children.get('parameteritem') if param_items is None: continue for it in param_items: decorators = {'default': self.parameter_name_decorator} direction = None name = it.walk(decorators,0).split(':') if len(name) == 2: direction = name[1] decorators = {'default': self.parameter_description_decorator, 'para': self.paragraph_content_decorator} description = it.walk(decorators, 0) result[name[0]] = (direction,description) return result def _process_return_value_description(self, node): result = None ret = list() para = node.children.get('para') if para is not None: for p in para: simplesect_list = p.children.get('simplesect') if simplesect_list is None: continue for it in simplesect_list: decorators = {'default': self.return_value_description_decorator, 'para': self.parameter_name_decorator} result = it.walk(decorators, 1) if result is not None: ret.append(result) return ret def _process_retval_description(self, node): """ retval descriptions reside inside detailed description section. """ para = node.children.get('para') result = None ret = list() if para is not None: for e in para: param_list = e.children.get('parameterlist') if param_list is None: continue for p in param_list: kind = p.attributes['kind'] if kind == 'retval': param_items = p.children.get('parameteritem') if param_items is None: continue for it in param_items: param_descr = it.children.get('parameterdescription') if param_descr is not None: val = param_descr[0].children.get('para') if val is not None: val_descr = val[0].getContent() else: val_descr ='' decorators = {'default': self.parameter_name_decorator} name = it.walk(decorators, 1).split(':') val = name[0] result = " %s %s" % (val, val_descr) ret.append (result) return ret def return_warning_decorator(self, node, value): if node.name == 'simplesect': if node.attributes['kind'] == 'warning': return value else: return None def _process_warning_description(self, node): result = None para = node.children.get('para') if para is not None: for p in para: simplesect_list = p.children.get('simplesect') if simplesect_list is None: continue for it in simplesect_list: decorators = {'default': self.return_warning_decorator, 'para': self.paragraph_content_decorator} result = it.walk(decorators, 1) # Assuming that only one Warning per function if result is not None: return result return result def return_seealso_decorator(self, node, value): if node.name == 'simplesect': if node.attributes['kind'] == 'see': return value else: return None def _process_seealso_description(self, node): result = None para = node.children.get('para') if para is not None: for p in para: simplesect_list = p.children.get('simplesect') if simplesect_list is None: continue for it in simplesect_list: decorators = {'default': self.return_seealso_decorator, 'para': self.paragraph_content_decorator} result = it.walk(decorators, 1) return result def return_version_decorator(self, node, value): if node.name == 'simplesect': if node.attributes['kind'] == 'version': return value else: return None def _process_version_description(self, node): result = None para = node.children.get('para') if para is not None: for p in para: simplesect_list = p.children.get('simplesect') if simplesect_list is None: continue for it in simplesect_list: decorators = {'default': self.return_version_decorator, 'para': self.paragraph_content_decorator} result = it.walk(decorators, 1) if result is not None: return result return result def return_notes_decorator(self, node, value): if node.name == 'simplesect': if node.attributes['kind'] == 'note': # We indent notes with an extra tab. Do it for all paragraphs. return value.replace("\n ", "\n\n\t "); else: return None def _process_notes_description(self, node): result = None para = node.children.get('para') if para is not None: for p in para: simplesect_list = p.children.get('simplesect') if simplesect_list is None: continue for it in simplesect_list: decorators = {'default': self.return_notes_decorator, 'para': self.paragraph_content_decorator} result = it.walk(decorators, 1) if result is not None: return result return result def return_deprecated_decorator(self, node, value): if node.name == 'xrefsect': if node.attributes['id'].find('deprecated_') > -1: xreftitle = node.children.get('xreftitle') if xreftitle[0] is not None: xrefdescr = node.children.get('xrefdescription') deprecated_descr = "DEPRECATED %s" % xrefdescr[0].getContent() return deprecated_descr else: return None def _process_deprecated_description(self, node): result = None para = node.children.get('para') if para is not None: for p in para: xrefsect_list = p.children.get('xrefsect') if xrefsect_list is None: continue for it in xrefsect_list: decorators = {'default': self.return_deprecated_decorator, 'para': self.paragraph_content_decorator} result = it.walk(decorators, 1) if result is not None: return result return result def break_into_lines(self, value, linelen=82): breaks = range(0,len(value),linelen) + [len(value)] result = list() for (start,end) in zip(breaks[:-1],breaks[1:]): result.append(value[start:end]) result = '\n'.join(result) return result def _save(self, table, path = None): if path is None: f = sys.stdout else: f = open(path, 'w') for l in table: f.write('%s\n' % ','.join(l)) if path is not None: f.close() class DoxyBuilderFuncs(DoxyFuncs): def __init__(self, xmlpath, rstpath): super(DoxyBuilderFuncs,self).__init__(xmlpath) self.target_dir = rstpath outfile = '%s/%s' % (self.target_dir, 'out.txt') self.tmp = open(outfile, 'w') def run_all(self): self.run() templates = {'function': 'func_document.tmpl'} self.save(templates, self.target_dir) def test_run(self): self.run() if __name__ == '__main__': builder = DoxyBuilderFuncs(xmlpath, rstpath) builder.run_all() krb5-1.22.1/doc/tools/type_document.tmpl0000664000175000017500000000143015051422640020021 0ustar ghudsonghudson.. highlight:: c .. $composite.struct_reference($composite.name): #set $title = $composite.name $title #echo ''.join(['=']*len($title)) # .. .. c:type:: $composite.name .. #if $composite.short_description is not None and len($composite.short_description) $composite.short_description #end if $composite.long_description Declaration ------------ $composite.definition #if $composite.Id is not None #if len($composite.attributes) Members --------- #end if #for $attr in $composite.attributes: #if $attr.name is not None .. c:member:: $attr.type $composite.name.$attr.name $attr.short_description #if $attr.long_description is not None $attr.long_description #end if #end if #end for #end if krb5-1.22.1/doc/tools/docmodel.py0000664000175000017500000002147115051422640016413 0ustar ghudsonghudson''' Copyright 2011 by the Massachusetts Institute of Technology. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. M.I.T. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ''' import re from Cheetah.Template import Template class Attribute(object): def __init__(self, **argkw): self.definition = argkw.get('definition') self.name = argkw.get('name') self.type = argkw.get('type') self.typeId = argkw.get('typeId') self.short_description = argkw.get('short_description') self.long_description = argkw.get('long_description') self.version = argkw.get('version') def __repr__(self): result = list() for (attr,value) in self.__dict__.iteritems(): result.append('%s=%s' % (attr,value)) return 'Attribute: %s' % ','.join(result) class CompositeType(): def __init__(self, **argkw): self.category = 'composite' self.definition = argkw.get('definition') self.name = argkw.get('name') self.name_signature = argkw.get('name_signature') self.Id = argkw.get('Id') self.initializer = argkw.get('initializer') self.active = argkw.get('active', False) self.version = argkw.get('version') self.return_type = argkw.get('return_type') self.short_description = argkw.get('short_description') self.long_description = argkw.get('long_description') self.friends = argkw.get('friends') self.type = argkw.get('type') self.attributes = self._setAttributes(argkw.get('attributes')) def __repr__(self): result = list() for (attr,value) in self.__dict__.iteritems(): if attr == 'attributes': if value is not None: attributes = ['%s' % a for a in value] value = '\n %s' % '\n '.join(attributes) result.append('%s: %s' % (attr,value)) result = '\n'.join(result) return result def _setAttributes(self, attributes): result = None if attributes is not None: result = list() for a in attributes: result.append(Attribute(**a)) return result def struct_reference(self, name): result = re.sub(r'_', '-', name) result = '_%s-struct' % result return result def macro_reference(self, name): result = re.sub(r'_', '-', name) result = '_%s-data' % result return result class Parameter(object): def __init__(self, **argkw): self.seqno = argkw.get('seqno') self.name = argkw.get('name') self.direction = argkw.get('direction') self.type = argkw.get('type') self.typeId = argkw.get('typeId') self.description = argkw.get('description') self.version = argkw.get('version') def __repr__(self): content = (self.name,self.direction,self.seqno,self.type,self.typeId,self.description) return 'Parameter: name=%s,direction=%s,seqno=%s,type=%s,typeId=%s,descr=%s' % content class Function(object): def __init__(self, **argkw): self.category = 'function' self.name = argkw.get('name') self.Id = argkw.get('Id') self.active = argkw.get('active', False) self.version = argkw.get('version') self.parameters = self._setParameters(argkw.get('parameters')) self.return_type = argkw.get('return_type') self.return_description = argkw.get('return_description') self.retval_description = argkw.get('retval_description') self.warn_description = argkw.get('warn_description') self.sa_description = argkw.get('sa_description') self.notes_description = argkw.get('notes_description') self.version_num = argkw.get('version_num') self.short_description = argkw.get('short_description') self.long_description = argkw.get('long_description') self.deprecated_description = argkw.get('deprecated_description') self.friends = argkw.get('friends') def _setParameters(self, parameters): result = None if parameters is not None: result = list() for p in parameters: result.append(Parameter(**p)) return result def getObjectRow(self): result = [str(self.Id), self.name, self.category] return ','.join(result) def getObjectDescriptionRow(self): result = [self.Id, self.active, self.version, self.short_description, self.long_description] return ','.join(result) def getParameterRows(self): result = list() for p in self.parameters: p_row = [self.Id, p.name, p.seqno, p.type, p.typeId, p.description, p.version] result.append(','.join(p_row)) return '\n'.join(result) def __repr__(self): lines = list() lines.append('Category: %s' % self.category) lines.append('Function name: %s' % self.name) lines.append('Function Id: %s' % self.Id) parameters = [' %s' % p for p in self.parameters] lines.append('Parameters:\n%s' % '\n'.join(parameters)) lines.append('Function return type: %s' % self.return_type) lines.append('Function return type description:\n%s' % self.return_description) lines.append('Function retval description:\n%s' % self.retval_description) lines.append('Function short description:\n%s' % self.short_description) lines.append('Function long description:\n%s' % self.long_description) lines.append('Warning description:\n%s' % self.warn_description) lines.append('See also description:\n%s' % self.sa_description) lines.append('NOTE description:\n%s' % self.notes_description) lines.append('Version introduced:\n%s' % self.version_num) lines.append('Deprecated description:\n%s' % self.deprecated_description) result = '\n'.join(lines) return result class DocModel(object): def __init__(self, **argkw): if len(argkw): self.name = argkw['name'] if argkw['category'] == 'function': self.category = 'function' self.function = Function(**argkw) elif argkw['category'] == 'composite': self.category = 'composite' self.composite = CompositeType(**argkw) def __repr__(self): obj = getattr(self,self.category) return str(obj) def signature(self): param_list = list() for p in self.function.parameters: if p.type is "... " : param_list.append('%s %s' % (p.type,' ')) else: param_list.append('%s %s' % (p.type, p.name)) param_list = ', '.join(param_list) result = '%s %s(%s)' % (self.function.return_type, self.function.name, param_list) return result def save(self, path, template_path): f = open(template_path, 'r') t = Template(f.read(),self) out = open(path, 'w') out.write(str(t)) out.close() f.close() class DocModelTest(DocModel): def __init__(self): doc_path = '../docutil/example.yml' argkw = yaml.load(open(doc_path,'r')) super(DocModelTest,self).__init__(**argkw) def run_tests(self): self.test_save() def test_print(self): print('testing') print(self) def test_save(self): template_path = '../docutil/function2edit.html' path = '/var/tsitkova/Sources/v10/trunk/documentation/test_doc.html' self.save(path, template_path) if __name__ == '__main__': tester = DocModelTest() tester.run_tests() krb5-1.22.1/doc/tools/func_document.tmpl0000664000175000017500000000311215051422640017772 0ustar ghudsonghudson#if $function.short_description is not None #set $title = $function.name + ' - ' + $function.short_description #else #set $title = $function.name #end if $title #echo ''.join(['=']*len($title)) # .. .. c:function:: $signature .. :param: #for $param in $function.parameters: #if $param.name == '' #continue #end if #if $param.direction is not None #set name_description = '**[%s]** **%s**' % ($param.direction, $param.name) #else #set name_description = '**%s**' % $param.name #end if #if $param.description is not None #set $description= ' - ' + $param.description #else #set $description='' #end if $name_description$description #end for .. #if len($function.retval_description) > 0 :retval: #for $retval in $function.retval_description: - $retval #end for #end if #if len($function.return_description) > 0 :return: #for $retval in $function.return_description: - $retval #end for #end if .. #if $function.deprecated_description is not None $function.deprecated_description #end if #if $function.long_description is not None $function.long_description #end if .. #if $function.sa_description is not None .. seealso:: $function.sa_description #end if #if $function.warn_description is not None or $function.notes_description is not None #if $function.warn_description is not None .. warning:: $function.warn_description #end if #if $function.notes_description is not None .. note:: $function.notes_description #end if #end if #if $function.version_num is not None .. note:: $function.version_num #end if krb5-1.22.1/doc/basic/0000775000175000017500000000000015051422640014167 5ustar ghudsonghudsonkrb5-1.22.1/doc/basic/keytab_def.rst0000664000175000017500000000422415051422640017020 0ustar ghudsonghudson.. _keytab_definition: keytab ====== A keytab (short for "key table") stores long-term keys for one or more principals. Keytabs are normally represented by files in a standard format, although in rare cases they can be represented in other ways. Keytabs are used most often to allow server applications to accept authentications from clients, but can also be used to obtain initial credentials for client applications. Keytabs are named using the format *type*\ ``:``\ *value*. Usually *type* is ``FILE`` and *value* is the absolute pathname of the file. The other possible value for *type* is ``MEMORY``, which indicates a temporary keytab stored in the memory of the current process. A keytab contains one or more entries, where each entry consists of a timestamp (indicating when the entry was written to the keytab), a principal name, a key version number, an encryption type, and the encryption key itself. A keytab can be displayed using the :ref:`klist(1)` command with the ``-k`` option. Keytabs can be created or appended to by extracting keys from the KDC database using the :ref:`kadmin(1)` :ref:`ktadd` command. Keytabs can be manipulated using the :ref:`ktutil(1)` and :ref:`k5srvutil(1)` commands. Default keytab -------------- The default keytab is used by server applications if the application does not request a specific keytab. The name of the default keytab is determined by the following, in decreasing order of preference: #. The **KRB5_KTNAME** environment variable. #. The **default_keytab_name** profile variable in :ref:`libdefaults`. #. The hardcoded default, |keytab|. Default client keytab --------------------- The default client keytab is used, if it is present and readable, to automatically obtain initial credentials for GSSAPI client applications. The principal name of the first entry in the client keytab is used by default when obtaining initial credentials. The name of the default client keytab is determined by the following, in decreasing order of preference: #. The **KRB5_CLIENT_KTNAME** environment variable. #. The **default_client_keytab_name** profile variable in :ref:`libdefaults`. #. The hardcoded default, |ckeytab|. krb5-1.22.1/doc/basic/ccache_def.rst0000664000175000017500000001516615051422640016756 0ustar ghudsonghudson.. _ccache_definition: Credential cache ================ A credential cache (or "ccache") holds Kerberos credentials while they remain valid and, generally, while the user's session lasts, so that authenticating to a service multiple times (e.g., connecting to a web or mail server more than once) doesn't require contacting the KDC every time. A credential cache usually contains one initial ticket which is obtained using a password or another form of identity verification. If this ticket is a ticket-granting ticket, it can be used to obtain additional credentials without the password. Because the credential cache does not store the password, less long-term damage can be done to the user's account if the machine is compromised. A credentials cache stores a default client principal name, set when the cache is created. This is the name shown at the top of the :ref:`klist(1)` *-A* output. Each normal cache entry includes a service principal name, a client principal name (which, in some ccache types, need not be the same as the default), lifetime information, and flags, along with the credential itself. There are also other entries, indicated by special names, that store additional information. ccache types ------------ The credential cache interface, like the :ref:`keytab_definition` and :ref:`rcache_definition` interfaces, uses `TYPE:value` strings to indicate the type of credential cache and any associated cache naming data to use. There are several kinds of credentials cache supported in the MIT Kerberos library. Not all are supported on every platform. In most cases, it should be correct to use the default type built into the library. #. **API** is only implemented on Windows. It communicates with a server process that holds the credentials in memory for the user, rather than writing them to disk. #. **DIR** points to the storage location of the collection of the credential caches in *FILE:* format. It is most useful when dealing with multiple Kerberos realms and KDCs. For release 1.10 the directory must already exist. In post-1.10 releases the requirement is for parent directory to exist and the current process must have permissions to create the directory if it does not exist. See :ref:`col_ccache` for details. New in release 1.10. The following residual forms are supported: * DIR:dirname * DIR::dirpath/filename - a single cache within the directory Switching to a ccache of the latter type causes it to become the primary for the directory. #. **FILE** caches are the simplest and most portable. A simple flat file format is used to store one credential after another. This is the default ccache type if no type is specified in a ccache name. #. **KCM** caches work by contacting a daemon process called ``kcm`` to perform cache operations. If the cache name is just ``KCM:``, the default cache as determined by the KCM daemon will be used. Newly created caches must generally be named ``KCM:uid:name``, where *uid* is the effective user ID of the running process. KCM client support is new in release 1.13. A KCM daemon has not yet been implemented in MIT krb5, but the client will interoperate with the KCM daemon implemented by Heimdal. macOS 10.7 and higher provides a KCM daemon as part of the operating system, and the **KCM** cache type is used as the default cache on that platform in a default build. #. **KEYRING** is Linux-specific, and uses the kernel keyring support to store credential data in unswappable kernel memory where only the current user should be able to access it. The following residual forms are supported: * KEYRING:name * KEYRING:process:name - process keyring * KEYRING:thread:name - thread keyring Starting with release 1.12 the *KEYRING* type supports collections. The following new residual forms were added: * KEYRING:session:name - session keyring * KEYRING:user:name - user keyring * KEYRING:persistent:uidnumber - persistent per-UID collection. Unlike the user keyring, this collection survives after the user logs out, until the cache credentials expire. This type of ccache requires support from the kernel; otherwise, it will fall back to the user keyring. See :ref:`col_ccache` for details. #. **MEMORY** caches are for storage of credentials that don't need to be made available outside of the current process. For example, a memory ccache is used by :ref:`kadmin(1)` to store the administrative ticket used to contact the admin server. Memory ccaches are faster than file ccaches and are automatically destroyed when the process exits. #. **MSLSA** is a Windows-specific cache type that accesses the Windows credential store. .. _col_ccache: Collections of caches --------------------- Some credential cache types can support collections of multiple caches. One of the caches in the collection is designated as the *primary* and will be used when the collection is resolved as a cache. When a collection-enabled cache type is the default cache for a process, applications can search the specified collection for a specific client principal, and GSSAPI applications will automatically select between the caches in the collection based on criteria such as the target service realm. Credential cache collections are new in release 1.10, with support from the **DIR** and **API** ccache types. Starting in release 1.12, collections are also supported by the **KEYRING** ccache type. Collections are supported by the **KCM** ccache type in release 1.13. Tool alterations to use cache collection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * :ref:`kdestroy(1)` *-A* will destroy all caches in the collection. * If the default cache type supports switching, :ref:`kinit(1)` *princname* will search the collection for a matching cache and store credentials there, or will store credentials in a new unique cache of the default type if no existing cache for the principal exists. Either way, kinit will switch to the selected cache. * :ref:`klist(1)` *-l* will list the caches in the collection. * :ref:`klist(1)` *-A* will show the content of all caches in the collection. * :ref:`kswitch(1)` *-p princname* will search the collection for a matching cache and switch to it. * :ref:`kswitch(1)` *-c cachename* will switch to a specified cache. Default ccache name ------------------- The default credential cache name is determined by the following, in descending order of priority: #. The **KRB5CCNAME** environment variable. For example, ``KRB5CCNAME=DIR:/mydir/``. #. The **default_ccache_name** profile variable in :ref:`libdefaults`. #. The hardcoded default, |ccache|. krb5-1.22.1/doc/basic/stash_file_def.rst0000664000175000017500000000202615051422640017660 0ustar ghudsonghudson.. _stash_definition: stash file ============ The stash file is a local copy of the master key that resides in encrypted form on the KDC's local disk. The stash file is used to authenticate the KDC to itself automatically before starting the :ref:`kadmind(8)` and :ref:`krb5kdc(8)` daemons (e.g., as part of the machine's boot sequence). The stash file, like the keytab file (see :ref:`keytab_file`) is a potential point-of-entry for a break-in, and if compromised, would allow unrestricted access to the Kerberos database. If you choose to install a stash file, it should be readable only by root, and should exist only on the KDC's local disk. The file should not be part of any backup of the machine, unless access to the backup data is secured as tightly as access to the master password itself. .. note:: If you choose not to install a stash file, the KDC will prompt you for the master key each time it starts up. This means that the KDC will not be able to start automatically, such as after a system reboot. krb5-1.22.1/doc/basic/rcache_def.rst0000664000175000017500000001134115051422640016764 0ustar ghudsonghudson.. _rcache_definition: replay cache ============ A replay cache (or "rcache") keeps track of all authenticators recently presented to a service. If a duplicate authentication request is detected in the replay cache, an error message is sent to the application program. The replay cache interface, like the credential cache and :ref:`keytab_definition` interfaces, uses `type:residual` strings to indicate the type of replay cache and any associated cache naming data to use. Background information ---------------------- Some Kerberos or GSSAPI services use a simple authentication mechanism where a message is sent containing an authenticator, which establishes the encryption key that the client will use for talking to the service. But nothing about that prevents an eavesdropper from recording the messages sent by the client, establishing a new connection, and re-sending or "replaying" the same messages; the replayed authenticator will establish the same encryption key for the new session, and the following messages will be decrypted and processed. The attacker may not know what the messages say, and can't generate new messages under the same encryption key, but in some instances it may be harmful to the user (or helpful to the attacker) to cause the server to see the same messages again a second time. For example, if the legitimate client sends "delete first message in mailbox", a replay from an attacker may delete another, different "first" message. (Protocol design to guard against such problems has been discussed in :rfc:`4120#section-10`.) Even if one protocol uses further protection to verify that the client side of the connection actually knows the encryption keys (and thus is presumably a legitimate user), if another service uses the same service principal name, it may be possible to record an authenticator used with the first protocol and "replay" it against the second. The replay cache mitigates these attacks somewhat, by keeping track of authenticators that have been seen until their five-minute window expires. Different authenticators generated by multiple connections from the same legitimate client will generally have different timestamps, and thus will not be considered the same. This mechanism isn't perfect. If a message is sent to one application server but a man-in-the-middle attacker can prevent it from actually arriving at that server, the attacker could then use the authenticator (once!) against a different service on the same host. This could be a problem if the message from the client included something more than authentication in the first message that could be useful to the attacker (which is uncommon; in most protocols the server has to indicate a successful authentication before the client sends additional messages), or if the simple act of presenting the authenticator triggers some interesting action in the service being attacked. Replay cache types ------------------ Unlike the credential cache and keytab interfaces, replay cache types are in lowercase. The following types are defined: #. **none** disables the replay cache. The residual value is ignored. #. **file2** (new in release 1.18) uses a hash-based format to store replay records. The file may grow to accommodate hash collisions. The residual value is the filename. #. **dfl** is the default type if no environment variable or configuration specifies a different type. It stores replay data in a file2 replay cache with a filename based on the effective uid. The residual value is ignored. For the dfl type, the location of the replay cache file is determined as follows: #. The directory is taken from the **KRB5RCACHEDIR** environment variable, or the **TMPDIR** environment variable, or a temporary directory determined at configuration time such as ``/var/tmp``, in descending order of preference. #. The filename is ``krb5_EUID.rcache2`` where EUID is the effective uid of the process. #. The file is opened without following symbolic links, and ownership of the file is verified to match the effective uid. On Windows, the directory for the dfl type is the local appdata directory, unless overridden by the **KRB5RCACHEDIR** environment variable. The filename on Windows is ``krb5.rcache2``, and the file is opened normally. Default replay cache name ------------------------- The default replay cache name is determined by the following, in descending order of priority: #. The **KRB5RCACHENAME** environment variable (new in release 1.18). #. The **KRB5RCACHETYPE** environment variable. If this variable is set, the residual value is empty. #. The **default_rcache_name** profile variable in :ref:`libdefaults` (new in release 1.18). #. If none of the above are set, the default replay cache name is ``dfl:``. krb5-1.22.1/doc/basic/date_format.rst0000664000175000017500000001105015051422640017203 0ustar ghudsonghudson.. _datetime: Supported date and time formats =============================== .. _duration: Time duration ------------- This format is used to express a time duration in the Kerberos configuration files and user commands. The allowed formats are: ====================== ============== ============ Format Example Value ---------------------- -------------- ------------ h:m[:s] 36:00 36 hours NdNhNmNs 8h30s 8 hours 30 seconds N (number of seconds) 3600 1 hour ====================== ============== ============ Here *N* denotes a number, *d* - days, *h* - hours, *m* - minutes, *s* - seconds. .. note:: The time interval should not exceed 2147483647 seconds. Examples:: Request a ticket valid for one hour, five hours, 30 minutes and 10 days respectively: kinit -l 3600 kinit -l 5:00 kinit -l 30m kinit -l "10d 0h 0m 0s" .. _getdate: getdate time ------------ Some of the kadmin and kdb5_util commands take a date-time in a human-readable format. Some of the acceptable date-time strings are: +-----------+------------------+-----------------+ | | Format | Example | +===========+==================+=================+ | Date | mm/dd/yy | 07/27/12 | | +------------------+-----------------+ | | month dd, yyyy | Jul 27, 2012 | | +------------------+-----------------+ | | yyyy-mm-dd | 2012-07-27 | +-----------+------------------+-----------------+ | Absolute | HH:mm[:ss]pp | 08:30 PM | | time +------------------+-----------------+ | | hh:mm[:ss] | 20:30 | +-----------+------------------+-----------------+ | Relative | N tt | 30 sec | | time | | | +-----------+------------------+-----------------+ | Time zone | Z | EST | | +------------------+-----------------+ | | z | -0400 | +-----------+------------------+-----------------+ (See :ref:`abbreviation`.) Examples:: Create a principal that expires on the date indicated: addprinc test1 -expire "3/27/12 10:00:07 EST" addprinc test2 -expire "January 23, 2015 10:05pm" addprinc test3 -expire "22:00 GMT" Add a principal that will expire in 30 minutes: addprinc test4 -expire "30 minutes" .. _abstime: Absolute time ------------- This rarely used date-time format can be noted in one of the following ways: +------------------------+----------------------+--------------+ | Format | Example | Value | +========================+======================+==============+ | yyyymmddhhmmss | 20141231235900 | One minute | +------------------------+----------------------+ before 2015 | | yyyy.mm.dd.hh.mm.ss | 2014.12.31.23.59.00 | | +------------------------+----------------------+ | | yymmddhhmmss | 141231235900 | | +------------------------+----------------------+ | | yy.mm.dd.hh.mm.ss | 14.12.31.23.59.00 | | +------------------------+----------------------+ | | dd-month-yyyy:hh:mm:ss | 31-Dec-2014:23:59:00 | | +------------------------+----------------------+--------------+ | hh:mm:ss | 20:00:00 | 8 o'clock in | +------------------------+----------------------+ the evening | | hhmmss | 200000 | | +------------------------+----------------------+--------------+ (See :ref:`abbreviation`.) Example:: Set the default expiration date to July 27, 2012 at 20:30 default_principal_expiration = 20120727203000 .. _abbreviation: Abbreviations used in this document ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | *month* : locale’s month name or its abbreviation; | *dd* : day of month (01-31); | *HH* : hours (00-12); | *hh* : hours (00-23); | *mm* : in time - minutes (00-59); in date - month (01-12); | *N* : number; | *pp* : AM or PM; | *ss* : seconds (00-60); | *tt* : time units (hours, minutes, min, seconds, sec); | *yyyy* : year; | *yy* : last two digits of the year; | *Z* : alphabetic time zone abbreviation; | *z* : numeric time zone; .. note:: - If the date specification contains spaces, you may need to enclose it in double quotes; - All keywords are case-insensitive. krb5-1.22.1/doc/basic/index.rst0000664000175000017500000000025215051422640016027 0ustar ghudsonghudson.. _basic_concepts: Kerberos V5 concepts ==================== .. toctree:: :maxdepth: 1 ccache_def keytab_def rcache_def stash_file_def date_format krb5-1.22.1/doc/html/0000775000175000017500000000000015051422775014063 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/user/0000775000175000017500000000000015051422714015032 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/user/index.html0000664000175000017500000002053515051422713017033 0ustar ghudsonghudson For users — MIT Kerberos Documentation krb5-1.22.1/doc/html/user/tkt_mgmt.html0000664000175000017500000011102015051422714017541 0ustar ghudsonghudson Ticket management — MIT Kerberos Documentation

Ticket management¶

On many systems, Kerberos is built into the login program, and you get tickets automatically when you log in. Other programs, such as ssh, can forward copies of your tickets to a remote host. Most of these programs also automatically destroy your tickets when they exit. However, MIT recommends that you explicitly destroy your Kerberos tickets when you are through with them, just to be sure. One way to help ensure that this happens is to add the kdestroy command to your .logout file. Additionally, if you are going to be away from your machine and are concerned about an intruder using your permissions, it is safest to either destroy all copies of your tickets, or use a screensaver that locks the screen.

Kerberos ticket properties¶

There are various properties that Kerberos tickets can have:

If a ticket is forwardable, then the KDC can issue a new ticket (with a different network address, if necessary) based on the forwardable ticket. This allows for authentication forwarding without requiring a password to be typed in again. For example, if a user with a forwardable TGT logs into a remote system, the KDC could issue a new TGT for that user with the network address of the remote system, allowing authentication on that host to work as though the user were logged in locally.

When the KDC creates a new ticket based on a forwardable ticket, it sets the forwarded flag on that new ticket. Any tickets that are created based on a ticket with the forwarded flag set will also have their forwarded flags set.

A proxiable ticket is similar to a forwardable ticket in that it allows a service to take on the identity of the client. Unlike a forwardable ticket, however, a proxiable ticket is only issued for specific services. In other words, a ticket-granting ticket cannot be issued based on a ticket that is proxiable but not forwardable.

A proxy ticket is one that was issued based on a proxiable ticket.

A postdated ticket is issued with the invalid flag set. After the starting time listed on the ticket, it can be presented to the KDC to obtain valid tickets.

Ticket-granting tickets with the postdateable flag set can be used to obtain postdated service tickets.

Renewable tickets can be used to obtain new session keys without the user entering their password again. A renewable ticket has two expiration times. The first is the time at which this particular ticket expires. The second is the latest possible expiration time for any ticket issued based on this renewable ticket.

A ticket with the initial flag set was issued based on the authentication protocol, and not on a ticket-granting ticket. Application servers that wish to ensure that the user’s key has been recently presented for verification could specify that this flag must be set to accept the ticket.

An invalid ticket must be rejected by application servers. Postdated tickets are usually issued with this flag set, and must be validated by the KDC before they can be used.

A preauthenticated ticket is one that was only issued after the client requesting the ticket had authenticated itself to the KDC.

The hardware authentication flag is set on a ticket which required the use of hardware for authentication. The hardware is expected to be possessed only by the client which requested the tickets.

If a ticket has the transit policy checked flag set, then the KDC that issued this ticket implements the transited-realm check policy and checked the transited-realms list on the ticket. The transited-realms list contains a list of all intermediate realms between the realm of the KDC that issued the first ticket and that of the one that issued the current ticket. If this flag is not set, then the application server must check the transited realms itself or else reject the ticket.

The okay as delegate flag indicates that the server specified in the ticket is suitable as a delegate as determined by the policy of that realm. Some client applications may use this flag to decide whether to forward tickets to a remote host, although many applications do not honor it.

An anonymous ticket is one in which the named principal is a generic principal for that realm; it does not actually specify the individual that will be using the ticket. This ticket is meant only to securely distribute a session key.

Obtaining tickets with kinit¶

If your site has integrated Kerberos V5 with the login system, you will get Kerberos tickets automatically when you log in. Otherwise, you may need to explicitly obtain your Kerberos tickets, using the kinit program. Similarly, if your Kerberos tickets expire, use the kinit program to obtain new ones.

To use the kinit program, simply type kinit and then type your password at the prompt. For example, Jennifer (whose username is jennifer) works for Bleep, Inc. (a fictitious company with the domain name mit.edu and the Kerberos realm ATHENA.MIT.EDU). She would type:

shell% kinit
Password for jennifer@ATHENA.MIT.EDU: <-- [Type jennifer's password here.]
shell%

If you type your password incorrectly, kinit will give you the following error message:

shell% kinit
Password for jennifer@ATHENA.MIT.EDU: <-- [Type the wrong password here.]
kinit: Password incorrect
shell%

and you won’t get Kerberos tickets.

By default, kinit assumes you want tickets for your own username in your default realm. Suppose Jennifer’s friend David is visiting, and he wants to borrow a window to check his mail. David needs to get tickets for himself in his own realm, EXAMPLE.COM. He would type:

shell% kinit david@EXAMPLE.COM
Password for david@EXAMPLE.COM: <-- [Type david's password here.]
shell%

David would then have tickets which he could use to log onto his own machine. Note that he typed his password locally on Jennifer’s machine, but it never went over the network. Kerberos on the local host performed the authentication to the KDC in the other realm.

If you want to be able to forward your tickets to another host, you need to request forwardable tickets. You do this by specifying the -f option:

shell% kinit -f
Password for jennifer@ATHENA.MIT.EDU: <-- [Type your password here.]
shell%

Note that kinit does not tell you that it obtained forwardable tickets; you can verify this using the klist command (see Viewing tickets with klist).

Normally, your tickets are good for your system’s default ticket lifetime, which is ten hours on many systems. You can specify a different ticket lifetime with the -l option. Add the letter s to the value for seconds, m for minutes, h for hours, or d for days. For example, to obtain forwardable tickets for david@EXAMPLE.COM that would be good for three hours, you would type:

shell% kinit -f -l 3h david@EXAMPLE.COM
Password for david@EXAMPLE.COM: <-- [Type david's password here.]
shell%

Note

You cannot mix units; specifying a lifetime of 3h30m would result in an error. Note also that most systems specify a maximum ticket lifetime. If you request a longer ticket lifetime, it will be automatically truncated to the maximum lifetime.

Viewing tickets with klist¶

The klist command shows your tickets. When you first obtain tickets, you will have only the ticket-granting ticket. The listing would look like this:

shell% klist
Ticket cache: /tmp/krb5cc_ttypa
Default principal: jennifer@ATHENA.MIT.EDU

Valid starting     Expires            Service principal
06/07/04 19:49:21  06/08/04 05:49:19  krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU
shell%

The ticket cache is the location of your ticket file. In the above example, this file is named /tmp/krb5cc_ttypa. The default principal is your Kerberos principal.

The “valid starting†and “expires†fields describe the period of time during which the ticket is valid. The “service principal†describes each ticket. The ticket-granting ticket has a first component krbtgt, and a second component which is the realm name.

Now, if jennifer connected to the machine daffodil.mit.edu, and then typed “klist†again, she would have gotten the following result:

shell% klist
Ticket cache: /tmp/krb5cc_ttypa
Default principal: jennifer@ATHENA.MIT.EDU

Valid starting     Expires            Service principal
06/07/04 19:49:21  06/08/04 05:49:19  krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU
06/07/04 20:22:30  06/08/04 05:49:19  host/daffodil.mit.edu@ATHENA.MIT.EDU
shell%

Here’s what happened: when jennifer used ssh to connect to the host daffodil.mit.edu, the ssh program presented her ticket-granting ticket to the KDC and requested a host ticket for the host daffodil.mit.edu. The KDC sent the host ticket, which ssh then presented to the host daffodil.mit.edu, and she was allowed to log in without typing her password.

Suppose your Kerberos tickets allow you to log into a host in another domain, such as trillium.example.com, which is also in another Kerberos realm, EXAMPLE.COM. If you ssh to this host, you will receive a ticket-granting ticket for the realm EXAMPLE.COM, plus the new host ticket for trillium.example.com. klist will now show:

shell% klist
Ticket cache: /tmp/krb5cc_ttypa
Default principal: jennifer@ATHENA.MIT.EDU

Valid starting     Expires            Service principal
06/07/04 19:49:21  06/08/04 05:49:19  krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU
06/07/04 20:22:30  06/08/04 05:49:19  host/daffodil.mit.edu@ATHENA.MIT.EDU
06/07/04 20:24:18  06/08/04 05:49:19  krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU
06/07/04 20:24:18  06/08/04 05:49:19  host/trillium.example.com@EXAMPLE.COM
shell%

Depending on your host’s and realm’s configuration, you may also see a ticket with the service principal host/trillium.example.com@. If so, this means that your host did not know what realm trillium.example.com is in, so it asked the ATHENA.MIT.EDU KDC for a referral. The next time you connect to trillium.example.com, the odd-looking entry will be used to avoid needing to ask for a referral again.

You can use the -f option to view the flags that apply to your tickets. The flags are:

F

Forwardable

f

forwarded

P

Proxiable

p

proxy

D

postDateable

d

postdated

R

Renewable

I

Initial

i

invalid

H

Hardware authenticated

A

preAuthenticated

T

Transit policy checked

O

Okay as delegate

a

anonymous

Here is a sample listing. In this example, the user jennifer obtained her initial tickets (I), which are forwardable (F) and postdated (d) but not yet validated (i):

shell% klist -f
Ticket cache: /tmp/krb5cc_320
Default principal: jennifer@ATHENA.MIT.EDU

Valid starting      Expires             Service principal
31/07/05 19:06:25  31/07/05 19:16:25  krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU
        Flags: FdiI
shell%

In the following example, the user david’s tickets were forwarded (f) to this host from another host. The tickets are reforwardable (F):

shell% klist -f
Ticket cache: /tmp/krb5cc_p11795
Default principal: david@EXAMPLE.COM

Valid starting     Expires            Service principal
07/31/05 11:52:29  07/31/05 21:11:23  krbtgt/EXAMPLE.COM@EXAMPLE.COM
        Flags: Ff
07/31/05 12:03:48  07/31/05 21:11:23  host/trillium.example.com@EXAMPLE.COM
        Flags: Ff
shell%

Destroying tickets with kdestroy¶

Your Kerberos tickets are proof that you are indeed yourself, and tickets could be stolen if someone gains access to a computer where they are stored. If this happens, the person who has them can masquerade as you until they expire. For this reason, you should destroy your Kerberos tickets when you are away from your computer.

Destroying your tickets is easy. Simply type kdestroy:

shell% kdestroy
shell%

If kdestroy fails to destroy your tickets, it will beep and give an error message. For example, if kdestroy can’t find any tickets to destroy, it will give the following message:

shell% kdestroy
kdestroy: No credentials cache file found while destroying cache
shell%
krb5-1.22.1/doc/html/user/user_config/0000775000175000017500000000000015051422714017335 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/user/user_config/index.html0000664000175000017500000001506715051422714021343 0ustar ghudsonghudson User config files — MIT Kerberos Documentation krb5-1.22.1/doc/html/user/user_config/k5login.html0000664000175000017500000002351515051422714021601 0ustar ghudsonghudson .k5login — MIT Kerberos Documentation

.k5login¶

DESCRIPTION¶

The .k5login file, which resides in a user’s home directory, contains a list of the Kerberos principals. Anyone with valid tickets for a principal in the file is allowed host access with the UID of the user in whose home directory the file resides. One common use is to place a .k5login file in root’s home directory, thereby granting system administrators remote root access to the host via Kerberos.

EXAMPLES¶

Suppose the user alice had a .k5login file in her home directory containing just the following line:

bob@FOOBAR.ORG

This would allow bob to use Kerberos network applications, such as ssh(1), to access alice’s account, using bob’s Kerberos tickets. In a default configuration (with k5login_authoritative set to true in krb5.conf), this .k5login file would not let alice use those network applications to access her account, since she is not listed! With no .k5login file, or with k5login_authoritative set to false, a default rule would permit the principal alice in the machine’s default realm to access the alice account.

Let us further suppose that alice is a system administrator. Alice and the other system administrators would have their principals in root’s .k5login file on each host:

alice@BLEEP.COM

joeadmin/root@BLEEP.COM

This would allow either system administrator to log in to these hosts using their Kerberos tickets instead of having to type the root password. Note that because bob retains the Kerberos tickets for his own principal, bob@FOOBAR.ORG, he would not have any of the privileges that require alice’s tickets, such as root access to any of the site’s hosts, or the ability to change alice’s password.

SEE ALSO¶

kerberos(1)

krb5-1.22.1/doc/html/user/user_config/k5identity.html0000664000175000017500000002472615051422714022327 0ustar ghudsonghudson .k5identity — MIT Kerberos Documentation

.k5identity¶

DESCRIPTION¶

The .k5identity file, which resides in a user’s home directory, contains a list of rules for selecting a client principals based on the server being accessed. These rules are used to choose a credential cache within the cache collection when possible.

Blank lines and lines beginning with # are ignored. Each line has the form:

principal field=value …

If the server principal meets all of the field constraints, then principal is chosen as the client principal. The following fields are recognized:

realm

If the realm of the server principal is known, it is matched against value, which may be a pattern using shell wildcards. For host-based server principals, the realm will generally only be known if there is a [domain_realm] section in krb5.conf with a mapping for the hostname.

service

If the server principal is a host-based principal, its service component is matched against value, which may be a pattern using shell wildcards.

host

If the server principal is a host-based principal, its hostname component is converted to lower case and matched against value, which may be a pattern using shell wildcards.

If the server principal matches the constraints of multiple lines in the .k5identity file, the principal from the first matching line is used. If no line matches, credentials will be selected some other way, such as the realm heuristic or the current primary cache.

EXAMPLE¶

The following example .k5identity file selects the client principal alice@KRBTEST.COM if the server principal is within that realm, the principal alice/root@EXAMPLE.COM if the server host is within a servers subdomain, and the principal alice/mail@EXAMPLE.COM when accessing the IMAP service on mail.example.com:

alice@KRBTEST.COM       realm=KRBTEST.COM
alice/root@EXAMPLE.COM  host=*.servers.example.com
alice/mail@EXAMPLE.COM  host=mail.example.com service=imap

SEE ALSO¶

kerberos(1), krb5.conf

krb5-1.22.1/doc/html/user/user_config/kerberos.html0000664000175000017500000004742415051422714022052 0ustar ghudsonghudson kerberos — MIT Kerberos Documentation

kerberos¶

DESCRIPTION¶

The Kerberos system authenticates individual users in a network environment. After authenticating yourself to Kerberos, you can use Kerberos-enabled programs without having to present passwords or certificates to those programs.

If you receive the following response from kinit:

kinit: Client not found in Kerberos database while getting initial credentials

you haven’t been registered as a Kerberos user. See your system administrator.

A Kerberos name usually contains three parts. The first is the primary, which is usually a user’s or service’s name. The second is the instance, which in the case of a user is usually null. Some users may have privileged instances, however, such as root or admin. In the case of a service, the instance is the fully qualified name of the machine on which it runs; i.e. there can be an ssh service running on the machine ABC (ssh/ABC@REALM), which is different from the ssh service running on the machine XYZ (ssh/XYZ@REALM). The third part of a Kerberos name is the realm. The realm corresponds to the Kerberos service providing authentication for the principal. Realms are conventionally all-uppercase, and often match the end of hostnames in the realm (for instance, host01.example.com might be in realm EXAMPLE.COM).

When writing a Kerberos name, the principal name is separated from the instance (if not null) by a slash, and the realm (if not the local realm) follows, preceded by an “@†sign. The following are examples of valid Kerberos names:

david
jennifer/admin
joeuser@BLEEP.COM
cbrown/root@FUBAR.ORG

When you authenticate yourself with Kerberos you get an initial Kerberos ticket. (A Kerberos ticket is an encrypted protocol message that provides authentication.) Kerberos uses this ticket for network utilities such as ssh. The ticket transactions are done transparently, so you don’t have to worry about their management.

Note, however, that tickets expire. Administrators may configure more privileged tickets, such as those with service or instance of root or admin, to expire in a few minutes, while tickets that carry more ordinary privileges may be good for several hours or a day. If your login session extends beyond the time limit, you will have to re-authenticate yourself to Kerberos to get new tickets using the kinit command.

Some tickets are renewable beyond their initial lifetime. This means that kinit -R can extend their lifetime without requiring you to re-authenticate.

If you wish to delete your local tickets, use the kdestroy command.

Kerberos tickets can be forwarded. In order to forward tickets, you must request forwardable tickets when you kinit. Once you have forwardable tickets, most Kerberos programs have a command line option to forward them to the remote host. This can be useful for, e.g., running kinit on your local machine and then sshing into another to do work. Note that this should not be done on untrusted machines since they will then have your tickets.

ENVIRONMENT VARIABLES¶

Several environment variables affect the operation of Kerberos-enabled programs. These include:

KRB5CCNAME

Default name for the credentials cache file, in the form TYPE:residual. The type of the default cache may determine the availability of a cache collection. FILE is not a collection type; KEYRING, DIR, and KCM are.

If not set, the value of default_ccache_name from configuration files (see KRB5_CONFIG) will be used. If that is also not set, the default type is FILE, and the residual is the path /tmp/krb5cc_*uid*, where uid is the decimal user ID of the user.

KRB5_KTNAME

Specifies the location of the default keytab file, in the form TYPE:residual. If no type is present, the FILE type is assumed and residual is the pathname of the keytab file. If unset, DEFKTNAME will be used.

KRB5_CONFIG

Specifies the location of the Kerberos configuration file. The default is SYSCONFDIR/krb5.conf. Multiple filenames can be specified, separated by a colon; all files which are present will be read.

KRB5_KDC_PROFILE

Specifies the location of the KDC configuration file, which contains additional configuration directives for the Key Distribution Center daemon and associated programs. The default is LOCALSTATEDIR/krb5kdc/kdc.conf.

KRB5RCACHENAME

(New in release 1.18) Specifies the location of the default replay cache, in the form type:residual. The file2 type with a pathname residual specifies a replay cache file in the version-2 format in the specified location. The none type (residual is ignored) disables the replay cache. The dfl type (residual is ignored) indicates the default, which uses a file2 replay cache in a temporary directory. The default is dfl:.

KRB5RCACHETYPE

Specifies the type of the default replay cache, if KRB5RCACHENAME is unspecified. No residual can be specified, so none and dfl are the only useful types.

KRB5RCACHEDIR

Specifies the directory used by the dfl replay cache type. The default is the value of the TMPDIR environment variable, or /var/tmp if TMPDIR is not set.

KRB5_TRACE

Specifies a filename to write trace log output to. Trace logs can help illuminate decisions made internally by the Kerberos libraries. For example, env KRB5_TRACE=/dev/stderr kinit would send tracing information for kinit to /dev/stderr. The default is not to write trace log output anywhere.

KRB5_CLIENT_KTNAME

Default client keytab file name. If unset, DEFCKTNAME will be used).

KPROP_PORT

kprop port to use. Defaults to 754.

GSS_MECH_CONFIG

Specifies a filename containing GSSAPI mechanism module configuration. The default is to read SYSCONFDIR/gss/mech and files with a .conf suffix within the directory SYSCONFDIR/gss/mech.d.

Most environment variables are disabled for certain programs, such as login system programs and setuid programs, which are designed to be secure when run within an untrusted process environment.

SEE ALSO¶

kdestroy, kinit, klist, kswitch, kpasswd, ksu, krb5.conf, kdc.conf, kadmin, kadmind, kdb5_util, krb5kdc

BUGS¶

AUTHORS¶

Steve Miller, MIT Project Athena/Digital Equipment Corporation
Clifford Neuman, MIT Project Athena
Greg Hudson, MIT Kerberos Consortium
Robbie Harwood, Red Hat, Inc.

HISTORY¶

The MIT Kerberos 5 implementation was developed at MIT, with contributions from many outside parties. It is currently maintained by the MIT Kerberos Consortium.

RESTRICTIONS¶

Copyright 1985, 1986, 1989-1996, 2002, 2011, 2018 Masachusetts Institute of Technology

krb5-1.22.1/doc/html/user/pwd_mgmt.html0000664000175000017500000003406515051422713017545 0ustar ghudsonghudson Password management — MIT Kerberos Documentation

Password management¶

Your password is the only way Kerberos has of verifying your identity. If someone finds out your password, that person can masquerade as you—send email that comes from you, read, edit, or delete your files, or log into other hosts as you—and no one will be able to tell the difference. For this reason, it is important that you choose a good password, and keep it secret. If you need to give access to your account to someone else, you can do so through Kerberos (see Granting access to your account). You should never tell your password to anyone, including your system administrator, for any reason. You should change your password frequently, particularly any time you think someone may have found out what it is.

Changing your password¶

To change your Kerberos password, use the kpasswd command. It will ask you for your old password (to prevent someone else from walking up to your computer when you’re not there and changing your password), and then prompt you for the new one twice. (The reason you have to type it twice is to make sure you have typed it correctly.) For example, user david would do the following:

shell% kpasswd
Password for david:    <- Type your old password.
Enter new password:    <- Type your new password.
Enter it again:  <- Type the new password again.
Password changed.
shell%

If david typed the incorrect old password, he would get the following message:

shell% kpasswd
Password for david:  <- Type the incorrect old password.
kpasswd: Password incorrect while getting initial ticket
shell%

If you make a mistake and don’t type the new password the same way twice, kpasswd will ask you to try again:

shell% kpasswd
Password for david:  <- Type the old password.
Enter new password:  <- Type the new password.
Enter it again: <- Type a different new password.
kpasswd: Password mismatch while reading password
shell%

Once you change your password, it takes some time for the change to propagate through the system. Depending on how your system is set up, this might be anywhere from a few minutes to an hour or more. If you need to get new Kerberos tickets shortly after changing your password, try the new password. If the new password doesn’t work, try again using the old one.

Granting access to your account¶

If you need to give someone access to log into your account, you can do so through Kerberos, without telling the person your password. Simply create a file called .k5login in your home directory. This file should contain the Kerberos principal of each person to whom you wish to give access. Each principal must be on a separate line. Here is a sample .k5login file:

jennifer@ATHENA.MIT.EDU
david@EXAMPLE.COM

This file would allow the users jennifer and david to use your user ID, provided that they had Kerberos tickets in their respective realms. If you will be logging into other hosts across a network, you will want to include your own Kerberos principal in your .k5login file on each of these hosts.

Using a .k5login file is much safer than giving out your password, because:

  • You can take access away any time simply by removing the principal from your .k5login file.

  • Although the user has full access to your account on one particular host (or set of hosts if your .k5login file is shared, e.g., over NFS), that user does not inherit your network privileges.

  • Kerberos keeps a log of who obtains tickets, so a system administrator could find out, if necessary, who was capable of using your user ID at a particular time.

One common application is to have a .k5login file in root’s home directory, giving root access to that machine to the Kerberos principals listed. This allows system administrators to allow users to become root locally, or to log in remotely as root, without their having to give out the root password, and without anyone having to type the root password over the network.

Password quality verification¶

TODO

krb5-1.22.1/doc/html/user/user_commands/0000775000175000017500000000000015051422714017671 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/user/user_commands/kdestroy.html0000664000175000017500000002421015051422714022422 0ustar ghudsonghudson kdestroy — MIT Kerberos Documentation

kdestroy¶

SYNOPSIS¶

kdestroy [-A] [-q] [-c cache_name] [-p princ_name]

DESCRIPTION¶

The kdestroy utility destroys the user’s active Kerberos authorization tickets by overwriting and deleting the credentials cache that contains them. If the credentials cache is not specified, the default credentials cache is destroyed.

OPTIONS¶

-A

Destroys all caches in the collection, if a cache collection is available. May be used with the -c option to specify the collection to be destroyed.

-q

Run quietly. Normally kdestroy beeps if it fails to destroy the user’s tickets. The -q flag suppresses this behavior.

-c cache_name

Use cache_name as the credentials (ticket) cache name and location; if this option is not used, the default cache name and location are used.

The default credentials cache may vary between systems. If the KRB5CCNAME environment variable is set, its value is used to name the default ticket cache.

-p princ_name

If a cache collection is available, destroy the cache for princ_name instead of the primary cache. May be used with the -c option to specify the collection to be searched.

NOTE¶

Most installations recommend that you place the kdestroy command in your .logout file, so that your tickets are destroyed automatically when you log out.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

FILES¶

DEFCCNAME

Default location of Kerberos 5 credentials cache

SEE ALSO¶

kinit, klist, kerberos

krb5-1.22.1/doc/html/user/user_commands/krb5-config.html0000664000175000017500000002772415051422714022701 0ustar ghudsonghudson krb5-config — MIT Kerberos Documentation

krb5-config¶

SYNOPSIS¶

krb5-config [--help | --all | --version | --vendor | --prefix | --exec-prefix | --defccname | --defktname | --defcktname | --cflags | --libs [libraries]]

DESCRIPTION¶

krb5-config tells the application programmer what flags to use to compile and link programs against the installed Kerberos libraries.

OPTIONS¶

--help

prints a usage message. This is the default behavior when no options are specified.

--all

prints the version, vendor, prefix, and exec-prefix.

--version

prints the version number of the Kerberos installation.

--vendor

prints the name of the vendor of the Kerberos installation.

--prefix

prints the prefix for which the Kerberos installation was built.

--exec-prefix

prints the prefix for executables for which the Kerberos installation was built.

--defccname

prints the built-in default credentials cache location.

--defktname

prints the built-in default keytab location.

--defcktname

prints the built-in default client (initiator) keytab location.

--cflags

prints the compilation flags used to build the Kerberos installation.

--libs [library]

prints the compiler options needed to link against library. Allowed values for library are:

krb5

Kerberos 5 applications (default)

gssapi

GSSAPI applications with Kerberos 5 bindings

kadm-client

Kadmin client

kadm-server

Kadmin server

kdb

Applications that access the Kerberos database

EXAMPLES¶

krb5-config is particularly useful for compiling against a Kerberos installation that was installed in a non-standard location. For example, a Kerberos installation that is installed in /opt/krb5/ but uses libraries in /usr/local/lib/ for text localization would produce the following output:

shell% krb5-config --libs krb5
-L/opt/krb5/lib -Wl,-rpath -Wl,/opt/krb5/lib -L/usr/local/lib -lkrb5 -lk5crypto -lcom_err

SEE ALSO¶

kerberos, cc(1)

krb5-1.22.1/doc/html/user/user_commands/index.html0000664000175000017500000001662215051422714021675 0ustar ghudsonghudson User commands — MIT Kerberos Documentation krb5-1.22.1/doc/html/user/user_commands/sclient.html0000664000175000017500000002036615051422714022227 0ustar ghudsonghudson sclient — MIT Kerberos Documentation

sclient¶

SYNOPSIS¶

sclient remotehost

DESCRIPTION¶

sclient is a sample application, primarily useful for testing purposes. It contacts a sample server sserver and authenticates to it using Kerberos version 5 tickets, then displays the server’s response.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kinit, sserver, kerberos

krb5-1.22.1/doc/html/user/user_commands/kinit.html0000664000175000017500000004352715051422714021710 0ustar ghudsonghudson kinit — MIT Kerberos Documentation

kinit¶

SYNOPSIS¶

kinit [-V] [-l lifetime] [-s start_time] [-r renewable_life] [-p | -P] [-f | -F] [-a] [-A] [-C] [-E] [-v] [-R] [-k [-i | -t keytab_file]] [-c cache_name] [-n] [-S service_name] [-I input_ccache] [-T armor_ccache] [-X attribute[=value]] [–request-pac | –no-request-pac] [principal]

DESCRIPTION¶

kinit obtains and caches an initial ticket-granting ticket for principal. If principal is absent, kinit chooses an appropriate principal name based on existing credential cache contents or the local username of the user invoking kinit. Some options modify the choice of principal name.

OPTIONS¶

-V

display verbose output.

-l lifetime

(Time duration string.) Requests a ticket with the lifetime lifetime.

For example, kinit -l 5:30 or kinit -l 5h30m.

If the -l option is not specified, the default ticket lifetime (configured by each site) is used. Specifying a ticket lifetime longer than the maximum ticket lifetime (configured by each site) will not override the configured maximum ticket lifetime.

-s start_time

(Time duration string.) Requests a postdated ticket. Postdated tickets are issued with the invalid flag set, and need to be resubmitted to the KDC for validation before use.

start_time specifies the duration of the delay before the ticket can become valid.

-r renewable_life

(Time duration string.) Requests renewable tickets, with a total lifetime of renewable_life.

-f

requests forwardable tickets.

-F

requests non-forwardable tickets.

-p

requests proxiable tickets.

-P

requests non-proxiable tickets.

-a

requests tickets restricted to the host’s local address[es].

-A

requests tickets not restricted by address.

-C

requests canonicalization of the principal name, and allows the KDC to reply with a different client principal from the one requested.

-E

treats the principal name as an enterprise name.

-v

requests that the ticket-granting ticket in the cache (with the invalid flag set) be passed to the KDC for validation. If the ticket is within its requested time range, the cache is replaced with the validated ticket.

-R

requests renewal of the ticket-granting ticket. Note that an expired ticket cannot be renewed, even if the ticket is still within its renewable life.

Note that renewable tickets that have expired as reported by klist may sometimes be renewed using this option, because the KDC applies a grace period to account for client-KDC clock skew. See krb5.conf clockskew setting.

-k [-i | -t keytab_file]

requests a ticket, obtained from a key in the local host’s keytab. The location of the keytab may be specified with the -t keytab_file option, or with the -i option to specify the use of the default client keytab; otherwise the default keytab will be used. By default, a host ticket for the local host is requested, but any principal may be specified. On a KDC, the special keytab location KDB: can be used to indicate that kinit should open the KDC database and look up the key directly. This permits an administrator to obtain tickets as any principal that supports authentication based on the key.

-n

Requests anonymous processing. Two types of anonymous principals are supported.

For fully anonymous Kerberos, configure pkinit on the KDC and configure pkinit_anchors in the client’s krb5.conf. Then use the -n option with a principal of the form @REALM (an empty principal name followed by the at-sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned.

A second form of anonymous tickets is supported; these realm-exposed tickets hide the identity of the client but not the client’s realm. For this mode, use kinit -n with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal.

As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation.

-I input_ccache

Specifies the name of a credentials cache that already contains a ticket. When obtaining that ticket, if information about how that ticket was obtained was also stored to the cache, that information will be used to affect how new credentials are obtained, including preselecting the same methods of authenticating to the KDC.

-T armor_ccache

Specifies the name of a credentials cache that already contains a ticket. If supported by the KDC, this cache will be used to armor the request, preventing offline dictionary attacks and allowing the use of additional preauthentication mechanisms. Armoring also makes sure that the response from the KDC is not modified in transit.

-c cache_name

use cache_name as the Kerberos 5 credentials (ticket) cache location. If this option is not used, the default cache location is used.

The default cache location may vary between systems. If the KRB5CCNAME environment variable is set, its value is used to locate the default cache. If a principal name is specified and the type of the default cache supports a collection (such as the DIR type), an existing cache containing credentials for the principal is selected or a new one is created and becomes the new primary cache. Otherwise, any existing contents of the default cache are destroyed by kinit.

-S service_name

specify an alternate service name to use when getting initial tickets.

-X attribute[=value]

specify a pre-authentication attribute and value to be interpreted by pre-authentication modules. The acceptable attribute and value values vary from module to module. This option may be specified multiple times to specify multiple attributes. If no value is specified, it is assumed to be “yesâ€.

The following attributes are recognized by the PKINIT pre-authentication mechanism:

X509_user_identity=value

specify where to find user’s X509 identity information

X509_anchors=value

specify where to find trusted X509 anchor information

disable_freshness[=yes]

disable sending freshness tokens (for testing purposes only)

–request-pac | –no-request-pac

mutually exclusive. If –request-pac is set, ask the KDC to include a PAC in authdata; if –no-request-pac is set, ask the KDC not to include a PAC; if neither are set, the KDC will follow its default, which is typically is to include a PAC if doing so is supported.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

FILES¶

DEFCCNAME

default location of Kerberos 5 credentials cache

DEFKTNAME

default location for the local host’s keytab.

SEE ALSO¶

klist, kdestroy, kerberos

krb5-1.22.1/doc/html/user/user_commands/ksu.html0000664000175000017500000007627115051422714021376 0ustar ghudsonghudson ksu — MIT Kerberos Documentation

ksu¶

SYNOPSIS¶

ksu [ target_user ] [ -n target_principal_name ] [ -c source_cache_name ] [ -k ] [ -r time ] [ -p | -P] [ -f | -F] [ -l lifetime ] [ -z | Z ] [ -q ] [ -e command [ args … ] ] [ -a [ args … ] ]

REQUIREMENTS¶

Must have Kerberos version 5 installed to compile ksu. Must have a Kerberos version 5 server running to use ksu.

DESCRIPTION¶

ksu is a Kerberized version of the su program that has two missions: one is to securely change the real and effective user ID to that of the target user, and the other is to create a new security context.

Note

For the sake of clarity, all references to and attributes of the user invoking the program will start with “source†(e.g., “source userâ€, “source cacheâ€, etc.).

Likewise, all references to and attributes of the target account will start with “targetâ€.

AUTHENTICATION¶

To fulfill the first mission, ksu operates in two phases: authentication and authorization. Resolving the target principal name is the first step in authentication. The user can either specify his principal name with the -n option (e.g., -n jqpublic@USC.EDU) or a default principal name will be assigned using a heuristic described in the OPTIONS section (see -n option). The target user name must be the first argument to ksu; if not specified root is the default. If . is specified then the target user will be the source user (e.g., ksu .). If the source user is root or the target user is the source user, no authentication or authorization takes place. Otherwise, ksu looks for an appropriate Kerberos ticket in the source cache.

The ticket can either be for the end-server or a ticket granting ticket (TGT) for the target principal’s realm. If the ticket for the end-server is already in the cache, it’s decrypted and verified. If it’s not in the cache but the TGT is, the TGT is used to obtain the ticket for the end-server. The end-server ticket is then verified. If neither ticket is in the cache, but ksu is compiled with the GET_TGT_VIA_PASSWD define, the user will be prompted for a Kerberos password which will then be used to get a TGT. If the user is logged in remotely and does not have a secure channel, the password may be exposed. If neither ticket is in the cache and GET_TGT_VIA_PASSWD is not defined, authentication fails.

AUTHORIZATION¶

This section describes authorization of the source user when ksu is invoked without the -e option. For a description of the -e option, see the OPTIONS section.

Upon successful authentication, ksu checks whether the target principal is authorized to access the target account. In the target user’s home directory, ksu attempts to access two authorization files: .k5login and .k5users. In the .k5login file each line contains the name of a principal that is authorized to access the account.

For example:

jqpublic@USC.EDU
jqpublic/secure@USC.EDU
jqpublic/admin@USC.EDU

The format of .k5users is the same, except the principal name may be followed by a list of commands that the principal is authorized to execute (see the -e option in the OPTIONS section for details).

Thus if the target principal name is found in the .k5login file the source user is authorized to access the target account. Otherwise ksu looks in the .k5users file. If the target principal name is found without any trailing commands or followed only by * then the source user is authorized. If either .k5login or .k5users exist but an appropriate entry for the target principal does not exist then access is denied. If neither file exists then the principal will be granted access to the account according to the aname->lname mapping rules. Otherwise, authorization fails.

EXECUTION OF THE TARGET SHELL¶

Upon successful authentication and authorization, ksu proceeds in a similar fashion to su. The environment is unmodified with the exception of USER, HOME and SHELL variables. If the target user is not root, USER gets set to the target user name. Otherwise USER remains unchanged. Both HOME and SHELL are set to the target login’s default values. In addition, the environment variable KRB5CCNAME gets set to the name of the target cache. The real and effective user ID are changed to that of the target user. The target user’s shell is then invoked (the shell name is specified in the password file). Upon termination of the shell, ksu deletes the target cache (unless ksu is invoked with the -k option). This is implemented by first doing a fork and then an exec, instead of just exec, as done by su.

CREATING A NEW SECURITY CONTEXT¶

ksu can be used to create a new security context for the target program (either the target shell, or command specified via the -e option). The target program inherits a set of credentials from the source user. By default, this set includes all of the credentials in the source cache plus any additional credentials obtained during authentication. The source user is able to limit the credentials in this set by using -z or -Z option. -z restricts the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. The -Z option provides the target user with a fresh target cache (no creds in the cache). Note that for security reasons, when the source user is root and target user is non-root, -z option is the default mode of operation.

While no authentication takes place if the source user is root or is the same as the target user, additional tickets can still be obtained for the target cache. If -n is specified and no credentials can be copied to the target cache, the source user is prompted for a Kerberos password (unless -Z specified or GET_TGT_VIA_PASSWD is undefined). If successful, a TGT is obtained from the Kerberos server and stored in the target cache. Otherwise, if a password is not provided (user hit return) ksu continues in a normal mode of operation (the target cache will not contain the desired TGT). If the wrong password is typed in, ksu fails.

Note

During authentication, only the tickets that could be obtained without providing a password are cached in the source cache.

OPTIONS¶

-n target_principal_name

Specify a Kerberos target principal name. Used in authentication and authorization phases of ksu.

If ksu is invoked without -n, a default principal name is assigned via the following heuristic:

  • Case 1: source user is non-root.

    If the target user is the source user the default principal name is set to the default principal of the source cache. If the cache does not exist then the default principal name is set to target_user@local_realm. If the source and target users are different and neither ~target_user/.k5users nor ~target_user/.k5login exist then the default principal name is target_user_login_name@local_realm. Otherwise, starting with the first principal listed below, ksu checks if the principal is authorized to access the target account and whether there is a legitimate ticket for that principal in the source cache. If both conditions are met that principal becomes the default target principal, otherwise go to the next principal.

    1. default principal of the source cache

    2. target_user@local_realm

    3. source_user@local_realm

    If a-c fails try any principal for which there is a ticket in the source cache and that is authorized to access the target account. If that fails select the first principal that is authorized to access the target account from the above list. If none are authorized and ksu is configured with PRINC_LOOK_AHEAD turned on, select the default principal as follows:

    For each candidate in the above list, select an authorized principal that has the same realm name and first part of the principal name equal to the prefix of the candidate. For example if candidate a) is jqpublic@ISI.EDU and jqpublic/secure@ISI.EDU is authorized to access the target account then the default principal is set to jqpublic/secure@ISI.EDU.

  • Case 2: source user is root.

    If the target user is non-root then the default principal name is target_user@local_realm. Else, if the source cache exists the default principal name is set to the default principal of the source cache. If the source cache does not exist, default principal name is set to root\@local_realm.

-c source_cache_name

Specify source cache name (e.g., -c FILE:/tmp/my_cache). If -c option is not used then the name is obtained from KRB5CCNAME environment variable. If KRB5CCNAME is not defined the source cache name is set to krb5cc_<source uid>. The target cache name is automatically set to krb5cc_<target uid>.(gen_sym()), where gen_sym generates a new number such that the resulting cache does not already exist. For example:

krb5cc_1984.2
-k

Do not delete the target cache upon termination of the target shell or a command (-e command). Without -k, ksu deletes the target cache.

-z

Restrict the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. Use the -n option if you want the tickets for other then the default principal. Note that the -z option is mutually exclusive with the -Z option.

-Z

Don’t copy any tickets from the source cache to the target cache. Just create a fresh target cache, where the default principal name of the cache is initialized to the target principal name. Note that the -Z option is mutually exclusive with the -z option.

-q

Suppress the printing of status messages.

Ticket granting ticket options:

-l lifetime -r time -p -P -f -F

The ticket granting ticket options only apply to the case where there are no appropriate tickets in the cache to authenticate the source user. In this case if ksu is configured to prompt users for a Kerberos password (GET_TGT_VIA_PASSWD is defined), the ticket granting ticket options that are specified will be used when getting a ticket granting ticket from the Kerberos server.

-l lifetime

(Time duration string.) Specifies the lifetime to be requested for the ticket; if this option is not specified, the default ticket lifetime (12 hours) is used instead.

-r time

(Time duration string.) Specifies that the renewable option should be requested for the ticket, and specifies the desired total lifetime of the ticket.

-p

specifies that the proxiable option should be requested for the ticket.

-P

specifies that the proxiable option should not be requested for the ticket, even if the default configuration is to ask for proxiable tickets.

-f

option specifies that the forwardable option should be requested for the ticket.

-F

option specifies that the forwardable option should not be requested for the ticket, even if the default configuration is to ask for forwardable tickets.

-e command [args …]

ksu proceeds exactly the same as if it was invoked without the -e option, except instead of executing the target shell, ksu executes the specified command. Example of usage:

ksu bob -e ls -lag

The authorization algorithm for -e is as follows:

If the source user is root or source user == target user, no authorization takes place and the command is executed. If source user id != 0, and ~target_user/.k5users file does not exist, authorization fails. Otherwise, ~target_user/.k5users file must have an appropriate entry for target principal to get authorized.

The .k5users file format:

A single principal entry on each line that may be followed by a list of commands that the principal is authorized to execute. A principal name followed by a * means that the user is authorized to execute any command. Thus, in the following example:

jqpublic@USC.EDU ls mail /local/kerberos/klist
jqpublic/secure@USC.EDU *
jqpublic/admin@USC.EDU

jqpublic@USC.EDU is only authorized to execute ls, mail and klist commands. jqpublic/secure@USC.EDU is authorized to execute any command. jqpublic/admin@USC.EDU is not authorized to execute any command. Note, that jqpublic/admin@USC.EDU is authorized to execute the target shell (regular ksu, without the -e option) but jqpublic@USC.EDU is not.

The commands listed after the principal name must be either a full path names or just the program name. In the second case, CMD_PATH specifying the location of authorized programs must be defined at the compilation time of ksu. Which command gets executed?

If the source user is root or the target user is the source user or the user is authorized to execute any command (* entry) then command can be either a full or a relative path leading to the target program. Otherwise, the user must specify either a full path or just the program name.

-a args

Specify arguments to be passed to the target shell. Note that all flags and parameters following -a will be passed to the shell, thus all options intended for ksu must precede -a.

The -a option can be used to simulate the -e option if used as follows:

-a -c [command [arguments]].

-c is interpreted by the c-shell to execute the command.

INSTALLATION INSTRUCTIONS¶

ksu can be compiled with the following four flags:

GET_TGT_VIA_PASSWD

In case no appropriate tickets are found in the source cache, the user will be prompted for a Kerberos password. The password is then used to get a ticket granting ticket from the Kerberos server. The danger of configuring ksu with this macro is if the source user is logged in remotely and does not have a secure channel, the password may get exposed.

PRINC_LOOK_AHEAD

During the resolution of the default principal name, PRINC_LOOK_AHEAD enables ksu to find principal names in the .k5users file as described in the OPTIONS section (see -n option).

CMD_PATH

Specifies a list of directories containing programs that users are authorized to execute (via .k5users file).

HAVE_GETUSERSHELL

If the source user is non-root, ksu insists that the target user’s shell to be invoked is a “legal shellâ€. getusershell(3) is called to obtain the names of “legal shellsâ€. Note that the target user’s shell is obtained from the passwd file.

Sample configuration:

KSU_OPTS = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /usr/ucb /local/bin"

ksu should be owned by root and have the set user id bit turned on.

ksu attempts to get a ticket for the end server just as Kerberized telnet and rlogin. Thus, there must be an entry for the server in the Kerberos database (e.g., host/nii.isi.edu@ISI.EDU). The keytab file must be in an appropriate location.

SIDE EFFECTS¶

ksu deletes all expired tickets from the source cache.

AUTHOR OF KSU¶

GENNADY (ARI) MEDVINSKY

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kerberos, kinit

krb5-1.22.1/doc/html/user/user_commands/kpasswd.html0000664000175000017500000002162315051422714022237 0ustar ghudsonghudson kpasswd — MIT Kerberos Documentation

kpasswd¶

SYNOPSIS¶

kpasswd [principal]

DESCRIPTION¶

The kpasswd command is used to change a Kerberos principal’s password. kpasswd first prompts for the current Kerberos password, then prompts the user twice for the new password, and the password is changed.

If the principal is governed by a policy that specifies the length and/or number of character classes required in the new password, the new password must conform to the policy. (The five character classes are lower case, upper case, numbers, punctuation, and all other characters.)

OPTIONS¶

principal

Change the password for the Kerberos principal principal. Otherwise, kpasswd uses the principal name from an existing ccache if there is one; if not, the principal is derived from the identity of the user invoking the kpasswd command.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kadmin, kadmind, kerberos

krb5-1.22.1/doc/html/user/user_commands/kvno.html0000664000175000017500000003010115051422714021527 0ustar ghudsonghudson kvno — MIT Kerberos Documentation

kvno¶

SYNOPSIS¶

kvno [-c ccache] [-e etype] [-k keytab] [-q] [-u | -S sname] [-P] [–cached-only] [–no-store] [–out-cache cache] [[{-F cert_file | {-I | -U} for_user} [-P]] | –u2u ccache] service1 service2 …

DESCRIPTION¶

kvno acquires a service ticket for the specified Kerberos principals and prints out the key version numbers of each.

OPTIONS¶

-c ccache

Specifies the name of a credentials cache to use (if not the default)

-e etype

Specifies the enctype which will be requested for the session key of all the services named on the command line. This is useful in certain backward compatibility situations.

-k keytab

Decrypt the acquired tickets using keytab to confirm their validity.

-q

Suppress printing output when successful. If a service ticket cannot be obtained, an error message will still be printed and kvno will exit with nonzero status.

-u

Use the unknown name type in requested service principal names. This option Cannot be used with -S.

-P

Specifies that the service1 service2 … arguments are to be treated as services for which credentials should be acquired using constrained delegation. This option is only valid when used in conjunction with protocol transition.

-S sname

Specifies that the service1 service2 … arguments are interpreted as hostnames, and the service principals are to be constructed from those hostnames and the service name sname. The service hostnames will be canonicalized according to the usual rules for constructing service principals.

-I for_user

Specifies that protocol transition (S4U2Self) is to be used to acquire a ticket on behalf of for_user. If constrained delegation is not requested, the service name must match the credentials cache client principal.

-U for_user

Same as -I, but treats for_user as an enterprise name.

-F cert_file

Specifies that protocol transition is to be used, identifying the client principal with the X.509 certificate in cert_file. The certificate file must be in PEM format.

–cached-only

Only retrieve credentials already present in the cache, not from the KDC. (Added in release 1.19.)

–no-store

Do not store retrieved credentials in the cache. If –out-cache is also specified, credentials will still be stored into the output credential cache. (Added in release 1.19.)

–out-cache ccache

Initialize ccache and store all retrieved credentials into it. Do not store acquired credentials in the input cache. (Added in release 1.19.)

–u2u ccache

Requests a user-to-user ticket. ccache must contain a local krbtgt ticket for the server principal. The reported version number will typically be 0, as the resulting ticket is not encrypted in the server’s long-term key.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

FILES¶

DEFCCNAME

Default location of the credentials cache

SEE ALSO¶

kinit, kdestroy, kerberos

krb5-1.22.1/doc/html/user/user_commands/kswitch.html0000664000175000017500000002201615051422714022234 0ustar ghudsonghudson kswitch — MIT Kerberos Documentation

kswitch¶

SYNOPSIS¶

kswitch {-c cachename|-p principal}

DESCRIPTION¶

kswitch makes the specified credential cache the primary cache for the collection, if a cache collection is available.

OPTIONS¶

-c cachename

Directly specifies the credential cache to be made primary.

-p principal

Causes the cache collection to be searched for a cache containing credentials for principal. If one is found, that collection is made primary.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

FILES¶

DEFCCNAME

Default location of Kerberos 5 credentials cache

SEE ALSO¶

kinit, kdestroy, klist, kerberos

krb5-1.22.1/doc/html/user/user_commands/klist.html0000664000175000017500000003071715051422714021715 0ustar ghudsonghudson klist — MIT Kerberos Documentation

klist¶

SYNOPSIS¶

klist [-e] [[-c] [-l] [-A] [-f] [-s] [-a [-n]]] [-C] [-k [-i] [-t] [-K]] [-V] [-d] [cache_name|keytab_name]

DESCRIPTION¶

klist lists the Kerberos principal and Kerberos tickets held in a credentials cache, or the keys held in a keytab file.

OPTIONS¶

-e

Displays the encryption types of the session key and the ticket for each credential in the credential cache, or each key in the keytab file.

-l

If a cache collection is available, displays a table summarizing the caches present in the collection.

-A

If a cache collection is available, displays the contents of all of the caches in the collection.

-c

List tickets held in a credentials cache. This is the default if neither -c nor -k is specified.

-f

Shows the flags present in the credentials, using the following abbreviations:

F    Forwardable
f    forwarded
P    Proxiable
p    proxy
D    postDateable
d    postdated
R    Renewable
I    Initial
i    invalid
H    Hardware authenticated
A    preAuthenticated
T    Transit policy checked
O    Okay as delegate
a    anonymous
-s

Causes klist to run silently (produce no output). klist will exit with status 1 if the credentials cache cannot be read or is expired, and with status 0 otherwise.

-a

Display list of addresses in credentials.

-n

Show numeric addresses instead of reverse-resolving addresses.

-C

List configuration data that has been stored in the credentials cache when klist encounters it. By default, configuration data is not listed.

-k

List keys held in a keytab file.

-i

In combination with -k, defaults to using the default client keytab instead of the default acceptor keytab, if no name is given.

-t

Display the time entry timestamps for each keytab entry in the keytab file.

-K

Display the value of the encryption key in each keytab entry in the keytab file.

-d

Display the authdata types (if any) for each entry.

-V

Display the Kerberos version number and exit.

If cache_name or keytab_name is not specified, klist will display the credentials in the default credentials cache or keytab file as appropriate. If the KRB5CCNAME environment variable is set, its value is used to locate the default ticket cache.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

FILES¶

DEFCCNAME

Default location of Kerberos 5 credentials cache

DEFKTNAME

Default location for the local host’s keytab file.

SEE ALSO¶

kinit, kdestroy, kerberos

krb5-1.22.1/doc/html/genindex-K.html0000664000175000017500000042043715051422714016745 0ustar ghudsonghudson Index — MIT Kerberos Documentation

Index – K

krb5-1.22.1/doc/html/build_this.html0000664000175000017500000002736315051422713017102 0ustar ghudsonghudson How to build this documentation from the source — MIT Kerberos Documentation

How to build this documentation from the source¶

Pre-requisites for a simple build, or to update man pages:

Additional prerequisites to include the API reference based on Doxygen markup:

  • Python 2.5 with the Cheetah, lxml, and xml modules

  • Doxygen

Simple build without API reference¶

To test simple changes to the RST sources, you can build the documentation without the Doxygen reference by running, from the doc directory:

sphinx-build . test_html

You will see a number of warnings about missing files. This is expected. If there is not already a doc/version.py file, you will need to create one by first running make version.py in the src/doc directory of a configured build tree.

Updating man pages¶

Man pages are generated from the RST sources and checked into the src/man directory of the repository. This allows man pages to be installed without requiring Sphinx when using a source checkout. To regenerate these files, run make man from the man subdirectory of a configured build tree. You can also do this from an unconfigured source tree with:

cd src/man
make -f Makefile.in top_srcdir=.. srcdir=. man
make clean

As with the simple build, it is normal to see warnings about missing files when rebuilding the man pages.

Building for a release tarball or web site¶

To generate documentation in HTML format, run make html in the doc subdirectory of a configured build tree (the build directory corresponding to src/doc, not the top-level doc directory). The output will be placed in the top-level doc/html directory. This build will include the API reference generated from Doxygen markup in the source tree.

Documentation generated this way will use symbolic names for paths (like BINDIR for the directory containing user programs), with the symbolic names being links to a table showing typical values for those paths.

You can also do this from an unconfigured source tree with:

cd src/doc
make -f Makefile.in SPHINX_ARGS= htmlsrc

Building for an OS package or site documentation¶

To generate documentation specific to a build of MIT krb5 as you have configured it, run make substhtml in the doc subdirectory of a configured build tree (the build directory corresponding to src/doc, not the top-level doc directory). The output will be placed in the html_subst subdirectory of that build directory. This build will include the API reference.

Documentation generated this way will use concrete paths (like /usr/local/bin for the directory containing user programs, for a default custom build).

krb5-1.22.1/doc/html/genindex-E.html0000664000175000017500000002002515051422714016724 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/mitK5features.html0000664000175000017500000012645615051422713017507 0ustar ghudsonghudson MIT Kerberos features — MIT Kerberos Documentation

MIT Kerberos features¶

https://web.mit.edu/kerberos

Quick facts¶

License - MIT Kerberos License information

Releases:
Supported platforms / OS distributions:
  • Windows (KfW 4.0): Windows 7, Vista, XP

  • Solaris: SPARC, x86_64/x86

  • GNU/Linux: Debian x86_64/x86, Ubuntu x86_64/x86, RedHat x86_64/x86

  • BSD: NetBSD x86_64/x86

Crypto backends:

Database backends: LDAP, DB2, LMDB

krb4 support: Kerberos 5 release < 1.8

DES support: Kerberos 5 release < 1.18 (See Retiring DES)

Interoperability¶

Microsoft

Starting from release 1.7:

  • Follow client principal referrals in the client library when obtaining initial tickets.

  • KDC can issue realm referrals for service principals based on domain names.

  • Extensions supporting DCE RPC, including three-leg GSS context setup and unencapsulated GSS tokens inside SPNEGO.

  • Microsoft GSS_WrapEX, implemented using the gss_iov API, which is similar to the equivalent SSPI functionality. This is needed to support some instances of DCE RPC.

  • NTLM recognition support in GSS-API, to facilitate dropping in an NTLM implementation for improved compatibility with older releases of Microsoft Windows.

  • KDC support for principal aliases, if the back end supports them. Currently, only the LDAP back end supports aliases.

  • Support Microsoft set/change password (RFC 3244) protocol in kadmind.

  • Implement client and KDC support for GSS_C_DELEG_POLICY_FLAG, which allows a GSS application to request credential delegation only if permitted by KDC policy.

Starting from release 1.8:

  • Microsoft Services for User (S4U) compatibility

Heimdal

  • Support for KCM credential cache starting from release 1.13

Feature list¶

For more information on the specific project see https://k5wiki.kerberos.org/wiki/Projects

Release 1.7
Release 1.8
Release 1.9
  • Advance warning on password expiry

  • Camellia encryption (CTS-CMAC mode) RFC 6803

  • KDC support for SecurID preauthentication

  • kadmin over IPv6

  • Trace logging Trace logging

  • GSSAPI/KRB5 multi-realm support

  • Plugin to test password quality Password quality interface (pwqual)

  • Plugin to synchronize password changes KADM5 hook interface (kadm5_hook)

  • Parallel KDC

  • GSS-API extensions for SASL GS2 bridge RFC 5801 RFC 5587

  • Purging old keys

  • Naming extensions for delegation chain

  • Password expiration API

  • Windows client support (build-only)

  • IPv6 support in iprop

Release 1.10
Release 1.11
  • Client support for FAST OTP RFC 6560

  • GSS-API extensions for credential locations

  • Responder mechanism

Release 1.12

Release 1.13

  • Add support for accessing KDCs via an HTTPS proxy server using the MS-KKDCP protocol.

  • Add support for hierarchical incremental propagation, where replicas can act as intermediates between an upstream primary and other downstream replicas.

  • Add support for configuring GSS mechanisms using /etc/gss/mech.d/*.conf files in addition to /etc/gss/mech.

  • Add support to the LDAP KDB module for binding to the LDAP server using SASL.

  • The KDC listens for TCP connections by default.

  • Fix a minor key disclosure vulnerability where using the “keepold†option to the kadmin randkey operation could return the old keys. [CVE-2014-5351]

  • Add client support for the Kerberos Cache Manager protocol. If the host is running a Heimdal kcm daemon, caches served by the daemon can be accessed with the KCM: cache type.

  • When built on macOS 10.7 and higher, use “KCM:†as the default cachetype, unless overridden by command-line options or krb5-config values.

  • Add support for doing unlocked database dumps for the DB2 KDC back end, which would allow the KDC and kadmind to continue accessing the database during lengthy database dumps.

Release 1.14

  • Administrator experience

    • Add a new kdb5_util tabdump command to provide reporting-friendly tabular dump formats (tab-separated or CSV) for the KDC database. Unlike the normal dump format, each output table has a fixed number of fields. Some tables include human-readable forms of data that are opaque in ordinary dump files. This format is also suitable for importing into relational databases for complex queries.

    • Add support to kadmin and kadmin.local for specifying a single command line following any global options, where the command arguments are split by the shell–for example, “kadmin getprinc principalnameâ€. Commands issued this way do not prompt for confirmation or display warning messages, and exit with non-zero status if the operation fails.

    • Accept the same principal flag names in kadmin as we do for the default_principal_flags kdc.conf variable, and vice versa. Also accept flag specifiers in the form that kadmin prints, as well as hexadecimal numbers.

    • Remove the triple-DES and RC4 encryption types from the default value of supported_enctypes, which determines the default key and salt types for new password-derived keys. By default, keys will only created only for AES128 and AES256. This mitigates some types of password guessing attacks.

    • Add support for directory names in the KRB5_CONFIG and KRB5_KDC_PROFILE environment variables.

    • Add support for authentication indicators, which are ticket annotations to indicate the strength of the initial authentication. Add support for the “require_auth†string attribute, which can be set on server principal entries to require an indicator when authenticating to the server.

    • Add support for key version numbers larger than 255 in keytab files, and for version numbers up to 65535 in KDC databases.

    • Transmit only one ETYPE-INFO and/or ETYPE-INFO2 entry from the KDC during pre-authentication, corresponding to the client’s most preferred encryption type.

    • Add support for server name identification (SNI) when proxying KDC requests over HTTPS.

    • Add support for the err_fmt profile parameter, which can be used to generate custom-formatted error messages.

  • Developer experience:

    • Change gss_acquire_cred_with_password() to acquire credentials into a private memory credential cache. Applications can use gss_store_cred() to make the resulting credentials visible to other processes.

    • Change gss_acquire_cred() and SPNEGO not to acquire credentials for IAKERB or for non-standard variants of the krb5 mechanism OID unless explicitly requested. (SPNEGO will still accept the Microsoft variant of the krb5 mechanism OID during negotiation.)

    • Change gss_accept_sec_context() not to accept tokens for IAKERB or for non-standard variants of the krb5 mechanism OID unless an acceptor credential is acquired for those mechanisms.

    • Change gss_acquire_cred() to immediately resolve credentials if the time_rec parameter is not NULL, so that a correct expiration time can be returned. Normally credential resolution is delayed until the target name is known.

    • Add krb5_prepend_error_message() and krb5_wrap_error_message() APIs, which can be used by plugin modules or applications to add prefixes to existing detailed error messages.

    • Add krb5_c_prfplus() and krb5_c_derive_prfplus() APIs, which implement the RFC 6113 PRF+ operation and key derivation using PRF+.

    • Add support for pre-authentication mechanisms which use multiple round trips, using the the KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error code. Add get_cookie() and set_cookie() callbacks to the kdcpreauth interface; these callbacks can be used to save marshalled state information in an encrypted cookie for the next request.

    • Add a client_key() callback to the kdcpreauth interface to retrieve the chosen client key, corresponding to the ETYPE-INFO2 entry sent by the KDC.

    • Add an add_auth_indicator() callback to the kdcpreauth interface, allowing pre-authentication modules to assert authentication indicators.

    • Add support for the GSS_KRB5_CRED_NO_CI_FLAGS_X cred option to suppress sending the confidentiality and integrity flags in GSS initiator tokens unless they are requested by the caller. These flags control the negotiated SASL security layer for the Microsoft GSS-SPNEGO SASL mechanism.

    • Make the FILE credential cache implementation less prone to corruption issues in multi-threaded programs, especially on platforms with support for open file description locks.

  • Performance:

    • On replica KDCs, poll the primary KDC immediately after processing a full resync, and do not require two full resyncs after the primary KDC’s log file is reset.

Release 1.15

  • Administrator experience:

    • Add support to kadmin for remote extraction of current keys without changing them (requires a special kadmin permission that is excluded from the wildcard permission), with the exception of highly protected keys.

    • Add a lockdown_keys principal attribute to prevent retrieval of the principal’s keys (old or new) via the kadmin protocol. In newly created databases, this attribute is set on the krbtgt and kadmin principals.

    • Restore recursive dump capability for DB2 back end, so sites can more easily recover from database corruption resulting from power failure events.

    • Add DNS auto-discovery of KDC and kpasswd servers from URI records, in addition to SRV records. URI records can convey TCP and UDP servers and primary KDC status in a single DNS lookup, and can also point to HTTPS proxy servers.

    • Add support for password history to the LDAP back end.

    • Add support for principal renaming to the LDAP back end.

    • Use the getrandom system call on supported Linux kernels to avoid blocking problems when getting entropy from the operating system.

  • Code quality:

    • Clean up numerous compilation warnings.

    • Remove various infrequently built modules, including some preauth modules that were not built by default.

  • Developer experience:

    • Add support for building with OpenSSL 1.1.

    • Use SHA-256 instead of MD5 for (non-cryptographic) hashing of authenticators in the replay cache. This helps sites that must build with FIPS 140 conformant libraries that lack MD5.

  • Protocol evolution:

    • Add support for the AES-SHA2 enctypes, which allows sites to conform to Suite B crypto requirements.

Release 1.16

  • Administrator experience:

    • The KDC can match PKINIT client certificates against the “pkinit_cert_match†string attribute on the client principal entry, using the same syntax as the existing “pkinit_cert_match†profile option.

    • The ktutil addent command supports the “-k 0†option to ignore the key version, and the “-s†option to use a non-default salt string.

    • kpropd supports a –pid-file option to write a pid file at startup, when it is run in standalone mode.

    • The “encrypted_challenge_indicator†realm option can be used to attach an authentication indicator to tickets obtained using FAST encrypted challenge pre-authentication.

    • Localization support can be disabled at build time with the –disable-nls configure option.

  • Developer experience:

    • The kdcpolicy pluggable interface allows modules control whether tickets are issued by the KDC.

    • The kadm5_auth pluggable interface allows modules to control whether kadmind grants access to a kadmin request.

    • The certauth pluggable interface allows modules to control which PKINIT client certificates can authenticate to which client principals.

    • KDB modules can use the client and KDC interface IP addresses to determine whether to allow an AS request.

    • GSS applications can query the bit strength of a krb5 GSS context using the GSS_C_SEC_CONTEXT_SASL_SSF OID with gss_inquire_sec_context_by_oid().

    • GSS applications can query the impersonator name of a krb5 GSS credential using the GSS_KRB5_GET_CRED_IMPERSONATOR OID with gss_inquire_cred_by_oid().

    • kdcpreauth modules can query the KDC for the canonicalized requested client principal name, or match a principal name against the requested client principal name with canonicalization.

  • Protocol evolution:

    • The client library will continue to try pre-authentication mechanisms after most failure conditions.

    • The KDC will issue trivially renewable tickets (where the renewable lifetime is equal to or less than the ticket lifetime) if requested by the client, to be friendlier to scripts.

    • The client library will use a random nonce for TGS requests instead of the current system time.

    • For the RC4 string-to-key or PAC operations, UTF-16 is supported (previously only UCS-2 was supported).

    • When matching PKINIT client certificates, UPN SANs will be matched correctly as UPNs, with canonicalization.

  • User experience:

    • Dates after the year 2038 are accepted (provided that the platform time facilities support them), through the year 2106.

    • Automatic credential cache selection based on the client realm will take into account the fallback realm and the service hostname.

    • Referral and alternate cross-realm TGTs will not be cached, avoiding some scenarios where they can be added to the credential cache multiple times.

    • A German translation has been added.

  • Code quality:

    • The build is warning-clean under clang with the configured warning options.

    • The automated test suite runs cleanly under AddressSanitizer.

Release 1.17

  • Administrator experience:

    • A new Kerberos database module using the Lightning Memory-Mapped Database library (LMDB) has been added. The LMDB KDB module should be more performant and more robust than the DB2 module, and may become the default module for new databases in a future release.

    • “kdb5_util dump†will no longer dump policy entries when specific principal names are requested.

  • Developer experience:

    • The new krb5_get_etype_info() API can be used to retrieve enctype, salt, and string-to-key parameters from the KDC for a client principal.

    • The new GSS_KRB5_NT_ENTERPRISE_NAME name type allows enterprise principal names to be used with GSS-API functions.

    • KDC and kadmind modules which call com_err() will now write to the log file in a format more consistent with other log messages.

    • Programs which use large numbers of memory credential caches should perform better.

  • Protocol evolution:

    • The SPAKE pre-authentication mechanism is now supported. This mechanism protects against password dictionary attacks without requiring any additional infrastructure such as certificates. SPAKE is enabled by default on clients, but must be manually enabled on the KDC for this release.

    • PKINIT freshness tokens are now supported. Freshness tokens can protect against scenarios where an attacker uses temporary access to a smart card to generate authentication requests for the future.

    • Password change operations now prefer TCP over UDP, to avoid spurious error messages about replays when a response packet is dropped.

    • The KDC now supports cross-realm S4U2Self requests when used with a third-party KDB module such as Samba’s. The client code for cross-realm S4U2Self requests is also now more robust.

  • User experience:

    • The new ktutil addent -f flag can be used to fetch salt information from the KDC for password-based keys.

    • The new kdestroy -p option can be used to destroy a credential cache within a collection by client principal name.

    • The Kerberos man page has been restored, and documents the environment variables that affect programs using the Kerberos library.

  • Code quality:

    • Python test scripts now use Python 3.

    • Python test scripts now display markers in verbose output, making it easier to find where a failure occurred within the scripts.

    • The Windows build system has been simplified and updated to work with more recent versions of Visual Studio. A large volume of unused Windows-specific code has been removed. Visual Studio 2013 or later is now required.

Release 1.18

  • Administrator experience:

    • Remove support for single-DES encryption types.

    • Change the replay cache format to be more efficient and robust. Replay cache filenames using the new format end with .rcache2 by default.

    • setuid programs will automatically ignore environment variables that normally affect krb5 API functions, even if the caller does not use krb5_init_secure_context().

    • Add an enforce_ok_as_delegate krb5.conf relation to disable credential forwarding during GSSAPI authentication unless the KDC sets the ok-as-delegate bit in the service ticket.

  • Developer experience:

    • Implement krb5_cc_remove_cred() for all credential cache types.

    • Add the krb5_pac_get_client_info() API to get the client account name from a PAC.

  • Protocol evolution:

    • Add KDC support for S4U2Self requests where the user is identified by X.509 certificate. (Requires support for certificate lookup from a third-party KDB module.)

    • Remove support for an old (“draft 9â€) variant of PKINIT.

    • Add support for Microsoft NegoEx. (Requires one or more third-party GSS modules implementing NegoEx mechanisms.)

  • User experience:

    • Add support for dns_canonicalize_hostname=fallback, causing host-based principal names to be tried first without DNS canonicalization, and again with DNS canonicalization if the un-canonicalized server is not found.

    • Expand single-component hostnames in hhost-based principal names when DNS canonicalization is not used, adding the system’s first DNS search path as a suffix. Add a qualify_shortname krb5.conf relation to override this suffix or disable expansion.

  • Code quality:

    • The libkrb5 serialization code (used to export and import krb5 GSS security contexts) has been simplified and made type-safe.

    • The libkrb5 code for creating KRB-PRIV, KRB-SAFE, and KRB-CRED messages has been revised to conform to current coding practices.

    • The test suite has been modified to work with macOS System Integrity Protection enabled.

    • The test suite incorporates soft-pkcs11 so that PKINIT PKCS11 support can always be tested.

Release 1.19

  • Administrator experience:

    • When a client keytab is present, the GSSAPI krb5 mech will refresh credentials even if the current credentials were acquired manually.

    • It is now harder to accidentally delete the K/M entry from a KDB.

  • Developer experience:

    • gss_acquire_cred_from() now supports the “password†and “verify†options, allowing credentials to be acquired via password and verified using a keytab key.

    • When an application accepts a GSS security context, the new GSS_C_CHANNEL_BOUND_FLAG will be set if the initiator and acceptor both provided matching channel bindings.

    • Added the GSS_KRB5_NT_X509_CERT name type, allowing S4U2Self requests to identify the desired client principal by certificate.

    • PKINIT certauth modules can now cause the hw-authent flag to be set in issued tickets.

    • The krb5_init_creds_step() API will now issue the same password expiration warnings as krb5_get_init_creds_password().

  • Protocol evolution:

    • Added client and KDC support for Microsoft’s Resource-Based Constrained Delegation, which allows cross-realm S4U2Proxy requests. A third-party database module is required for KDC support.

    • kadmin/admin is now the preferred server principal name for kadmin connections, and the host-based form is no longer created by default. The client will still try the host-based form as a fallback.

    • Added client and server support for Microsoft’s KERB_AP_OPTIONS_CBT extension, which causes channel bindings to be required for the initiator if the acceptor provided them. The client will send this option if the client_aware_gss_bindings profile option is set.

User experience:

  • The default setting of dns_canonicalize_realm is now “fallbackâ€. Hostnames provided from applications will be tried in principal names as given (possibly with shortname qualification), falling back to the canonicalized name.

  • kinit will now issue a warning if the des3-cbc-sha1 encryption type is used in the reply. This encryption type will be deprecated and removed in future releases.

  • Added kvno flags –out-cache, –no-store, and –cached-only (inspired by Heimdal’s kgetcred).

Release 1.20

  • Administrator experience:

    • Added a “disable_pac†realm relation to suppress adding PAC authdata to tickets, for realms which do not need to support S4U requests.

    • Most credential cache types will use atomic replacement when a cache is reinitialized using kinit or refreshed from the client keytab.

    • kprop can now propagate databases with a dump size larger than 4GB, if both the client and server are upgraded.

    • kprop can now work over NATs that change the destination IP address, if the client is upgraded.

  • Developer experience:

    • Updated the KDB interface. The sign_authdata() method is replaced with the issue_pac() method, allowing KDB modules to add logon info and other buffers to the PAC issued by the KDC.

    • Host-based initiator names are better supported in the GSS krb5 mechanism.

  • Protocol evolution:

    • Replaced AD-SIGNEDPATH authdata with minimal PACs.

    • To avoid spurious replay errors, password change requests will not be attempted over UDP until the attempt over TCP fails.

    • PKINIT will sign its CMS messages with SHA-256 instead of SHA-1.

  • Code quality:

    • Updated all code using OpenSSL to be compatible with OpenSSL 3.

    • Reorganized the libk5crypto build system to allow the OpenSSL back-end to pull in material from the builtin back-end depending on the OpenSSL version.

    • Simplified the PRNG logic to always use the platform PRNG.

    • Converted the remaining Tcl tests to Python.

Release 1.21

  • User experience:

    • Added a credential cache type providing compatibility with the macOS 11 native credential cache.

  • Developer experience:

    • libkadm5 will use the provided krb5_context object to read configuration values, instead of creating its own.

    • Added an interface to retrieve the ticket session key from a GSS context.

  • Protocol evolution:

    • The KDC will no longer issue tickets with RC4 or triple-DES session keys unless explicitly configured with the new allow_rc4 or allow_des3 variables respectively.

    • The KDC will assume that all services can handle aes256-sha1 session keys unless the service principal has a session_enctypes string attribute.

    • Support for PAC full KDC checksums has been added to mitigate an S4U2Proxy privilege escalation attack.

    • The PKINIT client will advertise a more modern set of supported CMS algorithms.

  • Code quality:

    • Removed unused code in libkrb5, libkrb5support, and the PKINIT module.

    • Modernized the KDC code for processing TGS requests, the code for encrypting and decrypting key data, the PAC handling code, and the GSS library packet parsing and composition code.

    • Improved the test framework’s detection of memory errors in daemon processes when used with asan.

Release 1.22

  • User experience:

    • The libdefaults configuration variable “request_timeout†can be set to limit the total timeout for KDC requests. When making a KDC request, the client will now wait indefinitely (or until the request timeout has elapsed) on a KDC which accepts a TCP connection, without contacting any additional KDCs. Clients will make fewer DNS queries in some configurations.

    • The realm configuration variable “sitename†can be set to cause the client to query site-specific DNS records when making KDC requests.

  • Administrator experience:

    • Principal aliases are supported in the DB2 and LMDB KDB modules and in the kadmin protocol. (The LDAP KDB module has supported aliases since release 1.7.)

    • UNIX domain sockets are supported for the Kerberos and kpasswd protocols.

    • systemd socket activation is supported for krb5kdc and kadmind.

  • Developer experience:

    • KDB modules can be be implemented in terms of other modules using the new krb5_db_load_module() function.

    • The profile library supports the modification of empty profiles and the copying of modified profiles, making it possible to construct an in-memory profile and pass it to krb5_init_context_profile().

    • GSS-API applications can pass the GSS_C_CHANNEL_BOUND flag to gss_init_sec_context() to request strict enforcement of channel bindings by the acceptor.

  • Protocol evolution:

    • The PKINIT preauth module supports elliptic curve client certificates, ECDH key exchange, and the Microsoft paChecksum2 field.

    • The IAKERB implementation has been changed to comply with the most recent draft standard and to support realm discovery.

    • Message-Authenticator is supported in the RADIUS implementation used by the OTP kdcpreauth module.

  • Code quality:

    • Removed old-style function declarations, to accomodate compilers which have removed support for them.

    • Added OSS-Fuzz to the project’s continuous integration infrastructure.

    • Rewrote the GSS per-message token parsing code for improved safety.

Pre-authentication mechanisms

krb5-1.22.1/doc/html/index.html0000664000175000017500000001431215051422713016051 0ustar ghudsonghudson MIT Kerberos Documentation (1.22.1) — MIT Kerberos Documentation krb5-1.22.1/doc/html/genindex.html0000664000175000017500000001217315051422714016547 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/genindex-V.html0000664000175000017500000001141415051422714016747 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/objects.inv0000664000175000017500000014027015051422714016227 0ustar ghudsonghudson# Sphinx inventory version 2 # Project: MIT Kerberos # Version: 1.22.1 # The remainder of this file is compressed using zlib. xÚÔ½ÝrÜ8¶&zßO¡ˆ9ÝqÚî)w¹cï}§’d—¶¤RÊ®ªsâƒÊ¤$Ž2É4É”­¾š×˜×›'9ø#‰Ÿ`-™ò\t—œ\ëû> ˆßÇæömöó›·Ù²®ž²mSVËr›¯–ÿu·«–]YWG?åÛíªxúGSܵÿÈ·å?a§×Ýfýß–¯ÿ¯£Wñ™°vÅ÷Nÿʛ|C'ñ<P—UÛåÕ²x î*ß¼¯øë%ˆ›"_oöNüöÍÏôÀuœÀLˆë'ñ ÷SóÀ} ^JÐÎÉK Ú9‰IA;™¸hºlÙ«–³ƒ7dG‹Äˆu(<¢½¼O?Û©:ïÛCðæ«US´œ¥{Þ8ÿ©ý‡nç”Sÿ;ÿ¯@XþצØÜM:”(èªkg€ZÕ}÷0Ð&¿/—ÓqXl¶yS ªˆåCð6X<à Ôß›ò«ÿƺY±"Æ—°÷–|šT:0 ÑËôæ L‰%Bäj‹¼Y>ŠC:xËC=æÿ¤*7‘!•~®uÙv‡âK,jëã/ þO·0Öëú[ö­ÈÙÛèyÛÕ˜òµ}â¨äœðQxD{y‹*¿]û¦åÚ¬«³u½Ì×VïÖËå8¹Ùèšä”¾³ŸÂ'ÛOL-À©×/•æuÕ–ÿ.²²:y]=oê]Kúༀrm.ꊟ^¯r‡Úþþ‰“ @bäó´„Ø ÒžnËþ½7®ÂÌ+.ªeÆ:7¦ÏB÷|C(™&“ªÁ>†÷š•À¦@Ë#àîÚb¹\ZvâqÛâkVíæÀw·Åó\À_qAðÕãýšý§ÞòŠ×bù¡vÝûÔ,—yW7“ÑHeëEaj‹n ³¾Ëwë.»­ëu‘W˜&ÐqBಒؒ^’^Ÿp?5µc0#uÿï§|½{‘´Ëè fÒˆâ¼Ä/ßmÇú÷´Ú#}B•GY¤×“Â#ÚË›^q¦ñN­5ÓØ“«Ì4ÚÔú2•õ@ÙÌÞž|T9»k Ô·§nïVãiÿ/R¬Bø€Rð@\÷EÅGEZJvõ>þ,,&e›ÍãQî%)Þ»u~ßœµ¬îV‡#í²åC±|lw›Œ3ÒÂÇrÅ‘m:1 <̱ÔÅuý€’Vy—ÿHz¬89¼ž„†®‹6tÝ, ]¬…·Nmè¦ñмŒ4u1uSlê®88·õ}NŠ$Ý7Q†åäÈ‚x#)C‰‚2âeU½|.Ù¯~ µð „´˜G¹—ü¥xSûR©¬r\‘R|Ì#XxüùÔ¢Ó8@ÅÚÃ3²ÿݲ·Âãá(³Gzye±c3”ÙÈãQî%)^3ü÷Í)úmñu˜( ”£é,PËtjÉÂ̱ÔÅuý€’ Ây)Qý¤=H„'"B¤Ý<áapS‘óã(™Ò¸Ï ¥YæìÒ)XöÊdj±›L>õ~þ¤vröÌÅò)©FŽáBÍò¤Q—'”†°‚e÷ý¥%L©»3ê ÷ÖtWdó¾ÛÄ"tfŒ´ÄtL.ø¹„$öëf‡jR»y–w$LÛÉM:ÌM!BÚ©jRwo~]iï‡Ñ,óôù ÖpªbŠ~(1ÓÞ3¨i‹j•£c04³´w‡ËJCXAâ[cN S |Fäî‚îŠ,ðäîÄNKLÇ䂟KHbwaº²*;J‘s{9‹§“švP «|*–Ä™(Í-œq½Ñäü³Øü©©xí”e-~™C;ï2‡7gÞFçÌÛÙ–9ìQRÒ2‡=êIZæ0«ž¦øš µ)޲†s8dMÓÉ! 2ÇR×åÄË‹úò‰¼¦.‡igYÓ×g´¾õíÔå0Sy',‡™J=e9L:7yµC]íÐβڡ Îÿ·¾ùÿvêj‡©¼i«ÒY·uÓQ Pø PZL-@ƒÇ£ÜKþR¼² àœZ5æ¦OʵñI¹vžI¹6Õg¢ÚÉ“r3KHe›Wm”­ÅNʵÓ'åZÌT™‚jg˜”Û‹”Q¶¹„¤ ¨·¸õvê€zEnƒ£Èíäõ™%L©ê3ê WuÜ€z;}@½Å ·‘áãv†õ½I¬ê³ÙµEÃÿG¯ëšg°ìu»©=6€3˜¢ˆœGÉ”`¢•‘C.4c°´Õ@k…z^ç« {0c‹r4c 8c }òF w¬™f "é;uâPáMJæ º)ÿóPÎTt`RŒ%èGºç†]—ìsƒbÏý¡`bÏü!`R"‹I;뇌>ç':;~ßI3·»r½"IfyÄ©o)<(ÖÃH:z>ÒÉsð±ÖüptâPÄeö”ÓccpÉh˜oSæp…ÓÓ1-jg3% g–2%Öç–’^ æQbÆ–ê‚B6#P£ñаO ¹‰Ü“bl*÷„ š@Ôº"ÚÕI-j¤zø+Æôös õ¤ÐB<)n'OZ4ï2Ÿø?0¬º¹¦ÆCñ§…LíJ„¨ˆQ™NT0t²"ѰLjø¬—†å‰mA^\ä%ñÈö3S‹i&^';÷D+Ž'žîñœž}<(ÖÃH÷ÉŒ´öb2ÝaS—•õ=.¸W,6„Í´øÐi¼âì”5­3SO Ó©ìk –øU!¢¢HÙ±Ó?a}‡¢ÉÚ.ï¹gáZÊ\jXñËj»Û:aŒŒ]ïº}JßµùýÞŠÝ–iöþH”í×”hª‘®&LŒÌ.Z 1ˆ:g7‰ŒÞöM K‹gìén»ÞµÈÐÖ]Àè6 â "€ûHÉ/Ç9HÉmòtÊÇÃÒÕ{O+8ô«^Ù!Ø?Ik\-\K™KB p">1¬ˆè¤W=›úª'›F:úU¯Ùû#q«À”„‰‘™ÂE{!N ¢¿ê'Ñ_õÈÒâ™ÊD©1]Ñ:VÀ‚}¤äWý¤¢M& TÏÃJÒKåäùI¸qÖñ#ŰH ˆÂ#ÚË[ütxÊ7§lËM¹Î›½óò›*œ÷™Ÿe4"D{HØ‘:?©$Ä÷=æ{¶¼{“±òÞ®‘e {@Å`<§—Šõ0>þtH²7$#}ZLç¤Æ÷dFâ öd>RGk2±4•=6íxÅ¢_OŒH`DÒ•âŸSÙiý³R§íTfú8÷¬ôSêOw“W«z“áöY;>¾:¤Y¤E°Káíå%w'fâ}| çé~Ø·ùjUV÷”™ Ó(AË€\€0,ØGÊ+`Fí;ÍAL›9Hi‹^Ó›;\t4wPH°_éq0Bi" LbWHŸE€R'ï㤠;˜Ã%“^Q`W DD¯#‰D¤YE* z•—yWòº.x!³(q5ýqoÈ õ¯^„¬¥ËŠªkê-®ïâºE ‘K×OäO@H­7:7;ÿ©­wͲ8¬Ñç©—]ѵ”âÕÜüÅ«¥/@äO@H@RñNb¯Û”Š3zù3V³IÍW—Æ+>ÀÞ²ÿT÷/E¾[.‹¶=${[+Jar{1Ч©¨C"A®¤:@$êjôg®ááÏ&õ<5£LxP¬‡‘ܛ̘øY;™Wý+)>(¬¬½àŸM„1<€1Ÿ“c„ÅzÉ12™‘“ÙÚ|}Èì”ÿ:aö­ìØç<#iéñ¨{ÇbÓ°§m4qUÓby_ªÒã}_ŠœpùDM¨¨{“4¥2Oõ”¯ËéªÇ¨Ð¶±ºx<’-V·rƈ”‡7ýóÇ”TXà Ô‘¯hÊ»gÚºå¥Â² Σ{<’ý¬Ô¦|&^Z_m&RR[<'qªn&VɇfEO³~ñ ’:Õ $#¬bb¥™Cä 4‡€)•i~úüDL«Ýs(˜VÓ‰ òõr·Î;Úz2ÇÉ­ë® µŠyI|ÂÔ¤öeFâ²zVêúŒäõ®£õ{fä¶FCÊ{°,_fâR¤l“wKÔL²áàÖTó±ü›²Q„‡¤zû#ÎÃFl„RèÖu[ Ë…›‚%"nÕ²áL94=Pàõ–½gšbÕ"3`°sa|š ×D‚\eµ\„ˆ7•ûdÚ5-â…Á*‚Uq—ïÖ®4•qçõ’Ó¦­ ` G •"«òMAÊáÈùì¶`°Ÿä`º–ÐqD"Ò^éQÈ¢Zeü2ûÙ8hP^ê©1@C2=däœF×7Ê{c»/ª¬*¾áJEC%Ò?¢–†iËÈ%@ èø=Qwå=6;z{8G†§)šmh@$ÈE™BDu˜BCfšÂÝ‚³6ìÍ⺹/ºÔ•ÞägÁºò@š¤N "]žD³[¯ ½2ÃÅ[ƒARqØð°\/eZÑL#åñ?ˆ_ÿÉÌ´ •Ur1ù${Ô&– …rs—íâËí,‚ïšräz)“rl"ijËŸD‹­}%§ðÊÈøÖ¤AI…‚dá™”ùy­ˆnå‹ö”š3.0 f"çO:WJ¬Ù6õ²,¸%T âwz®èp† yÕîµm–ó¢òS…vUùu‡ÌÍÑÊSí)=g]h@$ÈõPV‡!"}M¤Ó¦öˆ¾wb`[âÊ.ðþ!µ%s`]y MBX¥Y#þû¢¡Žxš‚WwBakPqë©@C2=däbŸFG,üIdÔOɲ¶^c_—Ê.}ùˆ^ò¤- H(m"…õ¡6#~×”±Îi.p¾ëôÜàa¹^Ê„ò˜NJ®ƒ“)é5q2åæ Él‹u±DNjH[(Õ“”å&¨%Ëe Ç _|Ÿì5mÑ<Í>àiƒÿmpð¿2øßz‡•[hX¹MüO'"u×Óihƒÿé<)ŸÕ lô%¶—/Ö&. ðÑxÅ؉ïÿ‰Ô„ù”64ŸÒ&ϧ´¾ù‡˜h'̧$Q_½4š.o:ÚÔ¾á…a@.–륤Í ¤ÔÏÕDκ¡ô G{¸¤†§ôb²‰0SBé$s»T¦Ýv[órúV¢Wçš>`©˜ ùRxD{y‰Cm©¤”¬óg™Ê*jÃZa)ÂW¢cë6¹öe½Æ¯ýƒHâê T™X>qTz.z(<¢ý¼Äöy:-vY–éΤT0,ØKšž}‰œß;zî}ïbÙ÷¾*ÙÃàÑì§Tlx§”ö!ç,<¾ðt'Oé&Iù‘ø„÷Ôyu_dÛ¼m¿Õ ª¿ez¸‰±žSSÃb}Œ¤þÐt>V»·ßÈ×-ÿÎ\Ö«âeX3⡳‘€·X>ò-@ËÇö÷f3=€ê`>'Wëa\Qî J¤“›##3ïÆÚaO«~ÃÛ›Û¢™„([»v°a7ät¨M~_.ç@ÊZä¢$Ý>Œ–¢64 æ"}€Q™¶ß²MÑZ»ßýè£9CÚCr¹À®@ˆHý—4U‘L&ç,Èm,…N;#ÒVøêŸð£‰­^™®ùõíîîŽ0ãgñj“SŽž—œ~†Éþu‘7YÑ4¬¿M¨¯®—[¦€Í²ûŽN“ŸÂ+¼g®«¶Ë¶uÉš Ä …ní¦B>Õ¦PhþEÔÖs5!}añïK"0úíIÄmŠ|½Ù.¶;‡U¯hñwà ßQ¯V¬3Ýânó3"xä·" …éÊŠÿ}(6ö>Ý®{°&ÇÃÊÞS2ýÓ¤‚± ‘ WYõ„ŽÒ1JäaŸå2ïŒÁ¥(Çàä/šÑ„ÿ뮩7ä”8,>åaî®~ æÔ¨L¢¦œ¥ÛÃŧ†H.7øhC£‡ŠXLÉD åBår(Âè¡÷YÿÒ«@]q ÿžQÛö ™À)3éGÌxcqOb1N–i'T%0ð#eöFAyÝú_µÉ¯Yø]伇ԫ•´pŽ Ï²y_øä/;Ç ÎvÓ„†’Q›À·«ÜÏÝ6ËÃQƒ‰z{8‡§)ñkC"A.òk3•ˆøÒL¤É´qfR‘ Žá²ͦ’CJHXFrùͨ!±h“ö±pá¦o(Á!¡0]Y‰¿EǯNÛ?ëõ?è.¥´†ËE=K)Ö°+bK¬(HÙ%‹ŒDK2ùEÅ/øl:̰XäÍ$ôh¢AæL;#Ó2$ž§ƒu‹”4,fUWËbf̦›·Ý®,ð¬¬îêÙ‘Y¯Ë7Û™qwm1S ¨D#‚”[ú1^/yÙ K&Ö¹;X¿a,RŒ` »Êæk[þšœMÄíd¬X-ìûZŸÚÀèðâŒÃðS`H!é)Û¬•û˦ h_ŒS`(±ìÃ`íP]­ÆîÚ4,B}ðÌ¢D½( ‡j3)‚ŸYOÝq«J½i=7ŒÃçO ·ˆd0uPTªÂþàxŸø™)~ôÔ¸[a„B¬ãì[:ñÁ›—U™äòúâY^3Á“(g$UQAP¼¼"Â÷çÞõPÖÍ+ýioØû¢qø¼_Q“|› A¢¦Øî‡·p¸Œá–P–ˆß鱦Ãb,䩞 ¸¬¶]³ܧb¹X>¶½Öúßé°ë.BH3 žøÏ¤•™¶K“¸&Ó‡ë p–bÎÃ9Åþ8eí$\{i:8ee=&6+08$¦£µ5t¶j‰ë7ö†nöô–åö¡hTÞÄ:pq¸±ü¦c=>Uõ,@ØþiéqÅ5ÚâFFm‡("~Š-Ñ txì—™_÷[|ßî{·û××½€SŽˆÜÞg„ FÇŽ§Ó‘ÑÃ#)ÐØÁC:6v…Ü=vøÆ£7"‰o׺)ÿóWLF¨á8xR›„„ÄŽDâ!)í‘R}qˆ´ ÅaR‚‰ØäU[vb6u*jò˜Ž×ÏBÓ‰rFRDÓ9ˆ"J‡xßz(c:ó‰AZ(K(S-,8CŒ…LüÀ“-(¸„A ,mЂL´ÀÃf}±Eßô£µ/ºÔS5ÁÞžÍ3®}FCãfõ(ˆ„7(¹±\7b©¼$»»ÕÛÐñÐ.-¦ò fž¼ã#òw>ƒ<]Óòˆ!Ç<è V?!adlBw°jߌ-ëîwEÛ†=rêø„‚#iìÔËàÑ¢M ’i´é¡Bâå õãM·rKHüŠÿ> ðO“©Èeb!ŒýIQy:ý: `à‡PB 3”L;CÉ`Ç›ýý™SˆP¦.Ê÷m^­²‡ºí°/@Ó#†øz™WuÅÿEÙ§ç!%ûx‰_#Óùû¥+ùa°ùz}›/3Î/zÀÉ)²»’Ñöºöa´×ù*£4ù 4 æÚò±ìŒ:î1‰“f“¸ä¡kíA¸ÔºýçeÙ>dæýle Å\ÿˆ^ ¨-Ì¥  GPVùë -OF_Öhi9äRxD{y“²m:-aÄ$•S½‡›bø~Ž/é Ó!‚G.k Ó=áïÂH¤ÚŠé%ms.¿L7O®YFIyù@ÎÍIä„÷¿nïÉËÔ÷# ˆ¹ÈùEç¡>ã:ùó*ù?‰O¸Ÿ:%ÿ’h §¿öpþ¥ž”B"A.j^%òP6²ÃŽáÑ~ÚM{Z1aEj»F8ÿ´ç)áåƒb=Œâÿ×e»wNÂQx†=œg©GáЀH‹Z3yÈÝŒøu³)™x÷{gónežMB—ßʵ‚)¹í:{s0MÌu?i,aqIýªÉD9«Ït€ó<ù¬> ÓQ[2z¹™f çQqHBË­tq 5_ Ý}GûHà|§d …éØ_íž¹°'3hÖžLJ:t€uÄ,Ôà!0ìªmÞ´Å »¾×u‚óÇ4IÉ&Ä'ÜOMÍ»$Úo+Z-ÔíÝü3žòY¢Œš> $\.CÓ¯!=Õsï®n¾åÍ*¿]á«wÝíîî T eß$¦aë>¨î ùŸzÍטêjy8Ö~N»Ê؃jõÒ|ƲÊH·ÖÎ@Yo9ËAwÝ¡S™5î‚rÐ/™ÊjR|šL4„%LŠØy4LŒáyDL‹ê™4LŒó©*X­´.ýÅ2÷®ÑÈ §¿ÍNOTË´Z0¯˜©Õa^5ëÅÌb¦Vd9ýœqM‰Ï¬& !y…IŒ2œ$@vvÁñ &2i†ÁKáíå¥MŠN ¥Îr9>`&Zs\„)½øÅ~RüÄÚN±sRÊ»ÁθñqBè¹àP˜®ßJØ\6•²ÞŒ 6ß+aûæqËñÛCfh›¯»½óÝõ[àHS»O°@v µ!@LLD i×uˆÿo·VB.ôHYO+â@:bòI»L§r%”™ŽuËù ZßÊîAÍ#"KÈuK 0ëtC'ÊOJFDDsï¦÷E”п÷¢‚^ö"ƒú´öj¿Q‘ð‰ºÛFn%Ê~ˆLiø¦h>Þ³]?¿˜–mÞ¶ßêf•ÐRö®Ñ¶r0œÔZÚtáäĤLk©fÖ2­½šYÌ”Vk^)ÓÚ®yµLlÁæTÚ—T3K«:¯¦9ÚÖYµ¸Ã ·h»*Œ&µ©­}0(?D?­ZÛ9ƒ€)íåtzÂRØ=OªñÓù'6ÊÓÌÓôM×1Gs— ¢Ts=Ô¯mËÏÓÐÙV©Ÿ¹¶@:‚2h«±ö#!¥Ñ›[½Ý›YŠM¾ª\/*å‘=(—YR{4³”¶Ë›.SǾ€ 9¥>¿Èu‰5ÜDã“©ÍG±³ÓHäˆÿ(2ô]‘iLØ›Ñõ›ûá`/Xñ~Ýkè$û.’mS/÷šebýKËÝþ(ø,ÛÞÀy›¾OõY¾^×Kz_epEsL|O;„áÅÄçš÷!„o HËxî‰Éwa7=Ûuº`b"J¦åù *ä|f;^_÷&¦,éåK@&­sZiHãÎ-ËD)ÿgZ„ñbâJØM+%*˜¿Š–l›}Ñ„4Û(˜ô;>ÐiŸÔñ A'Ÿ wZÙí[iUWÏ›z×N(Ð]šƒÄž”A¶\’±2g(Á}G×Ë|»Ù‚-AÃÇ##%› -è Hž^ ûTúW÷Å0É’±¯§ÍvBƒ ã¡‹öž!ƒ²2()Næþc¸&1(F l h €”ŒsU Ó 5£Ý£õbЧ׬}i4ï˜{&:-·åíÔ|‚uPò€¨xò7á‹È¦®|þ4ÏP‹ö-Y|_:K ˆ*5l=Ò]RV2`4`ÓMP:KÝ9ˆÔé±w™Ø]H Ñ—tö Q)3ˆÊ™ùJf Õ½ªž0–Û’ÇrÛ¹Çr[Òèc‹}´`§Ž‘FåL1·àÙ\G—¹BÅM8^êQt™ü`öïVª¹<25ê4tØé>3& p‚RO†ýŸ"yž‰›½*—·&G£‚À‡bï0GZä¸ÄbBÙóÃÈ4'Þˆ-=Íczñ¹ôÈ£5‚™ôCIm·uµ*š)e¨ ðEØ;ÌÓqàŒ9ÃÞžÎQö*вF¦ÚýÜøÂvzaé”Ñ„!YðÂ’´ý‰EÒ#`‹e°Ÿ^465*¡Hu@Ƽ°Dòa0Žg¬ˆÆcF¦ì¢ œÌà¦%&dÒ+kV%vÔΩcÂûqN³lïSÐ,›|ç”v Ì~¤ˆÅšÉý9¥LÞ*f[4›²ëŠå’UØlF³„ÆËOJHXýé*šš‡Íai g«z–’—&¬#`quÏ̪aF >ÍÅ—?£AZ&9°`T|ïòkÖ‘×D9>`RL ú´!ÈàÑì§%÷|æ¡¥—Ü<¼Ô^Í,¬é‡DzySÖPæÁ 0`M‹„")<¢½¼Û² åá,¬ÍrK›…Mdå=…¬¾»cßGØ–FwËÍ0H(6ˆì#ݔ˦n ÆM«}Ó™EÚßB{IX^`éÙ6ô…‡Å«=DN~]ÌINÝ9Ù©¯Ž¹Ó_ ©"ä§%û²ÈÔxä %ÓÞ dë¹ZÓ=R…Û¯À˜Š+¿­œpóe´nÄ¢†0ì ˆ_$[0©ß(!"BH˪ç§'~=Í @|íÙ®“®‹§X… ò4Ë#†˜#<(ÖLj¿hhÛ}ÑÑ2ì¾–À}ÑMÈ®û¢óé¿/:]R^¥P¡»E[$×Òº!"‚(=„=Чæ4rq½`…[¬`¥Ñ´‚5ˆü  HÎÙÈíü==ÿÔI¨±Â-V°ÒhZÁDþ$ì ävþ„y,–å*Nñœö]èAµú“C'™1)VRÙ(Óž3Чg`¤ÎÑÍ@IŸ‹›FÊ×8 Ï"ýBõN³J¯ .U a IÕc>~ÚYìóJ ¬TñxÆ :uH„.˜˜˜’äŸSuÕÁüRÜA9$·rŒ}o6­ä-²PB"2’‹}6 ÄaÐYetÅ–XÒÌ#XÄüù„²ÕàA±>Æ´bLdK¨›ÄWV$#\ð;é"òT>ö¶»]ר£Ä {8Ї§)anC"A.µLç \´}P“¨¨ÁFäiòjUo2Ü5a–\øÚó”âwáA±ÆÂŽâ}gß”„u ©lm±ÜñãÓhb¦–MJ„À4^ñ{÷Ó¿S(Ì PÞýó Æ÷Ÿo\_1sWÞgÛ¦¬–å6_còÓõ “óÓOã`‡R¸G~†U4M¾F_‡îø@yjY4„´Àà¹#c÷À~YemŽÚ¥b:@)Ð_ÔUAH€ ©T\¼;‘wòõ¡›;º‡Ä0†€]û_FyKg"¼Ç‰$«bÙ<£Ž¥lÜJöP4¬‡Èxð‚-\K™KB-_"~YmwûC'\zIÆfa²Oé»6¿ß[±feýD‰BnïDñtR4êø€R˜012S¸h Ï¢”€Má©v›ì`‰J e,ûšD7ªÊåþIZ[¸–2—„ºD|b£JD'Å(›Ú¨ቑHCG7ªš½?'4ª> &LŒÌ.Zû3(%`Sxèê²´PÆ2ñuuèo…Þæá9°lP[˜KA*f4<ÿîp,ýÀš=úSr–ЀH‹”7 <„QiÓÁ“G©ãÒ08$¦#çÓ$*bkAæÛäE¶|(–ínƒ*Ã(ó¹Ñ‚ƒRC|”©ƒ98©8™‘Ø{›ÌGŠùÉlÄ÷ÖT>t§ÌñŠE¿ì/MŒHà}ìÊñOŠÎ©ì´ækVêô ÊLïåÍJ?¥þи·Íªæ0; ®ð_ÉÑ©Ai" Lbëˆ@$…ú “¬Ó…ï@јÏÉ…ƒb=Œ¤ O`{*šòî™Öñ±|€\³-ˆG²Ÿ•ZZ3ñÒZ¼™HI2'±}‰Uìõ=4+ºoøÅ+Hjÿ(@HFXÅÄJ3‡†IhS*Óüô~ÓDL«Ýs(˜VÓ‰ Vü|ømt=Œ²së´ú}ØBÛ¼bïêl›7sB½™k“ß—Ë9pÚûL5vS¡¶¹ª+SºrùXLÏð¯È úêó¯VMѶb_NKk×=ÔMùïœ× Œ”S~Pb”ûîšz3 ÿï¸ùk2)0ý8´ºÀ¡Ö?T5+8©®–s("Ö^?P£¶ÄMÅ‘g-eÄÆ „ÇÉš¨+×ë`vðfa†ŒoËûj̪h÷Øôˆ!ªfF.“D÷`P±–ØžÎÈK¤{<$#áž9Øšò©}jÈ8ÔºÃûhnCçÈŸ3–ËÍ3C‘Ô°"MH"‡úˆXwùu‰‘ã•„eA/˜Â#Ú˫—҉˜@]·6ÿ˜)œmüAJni€¦ œv„ {×´â³HCÐ[B‰'…` öÒƒÎSänY÷†¤jIEϪ|SrCx²D>OÎëa´r:ööï}sî¶ÈÒÙmÁBÙmSÊb·uôí¶,þh ,"­ BÕ*k‹¯ÈãUM(/õÇô<À!¡º¾é;¹ù&³‰…ë„ÙhŒö”^..4 ä¢vˈLâTM| æPéä»!"â±)SˆhÅHC®‰<ä³Ò©äçÙÞHð]‹ÞÚº‰] Ö°$3•„ØWI¥XÕþX°[ŒFk_é&m/raqKRé"Iò'u8L…ìoèPæÏéÁƒb=ŒäÌJ ¬ø „·Ühe˜ö”ž].4 æ¢öÎÒ©¨/»t&ré©ä¡/ò|DìZq× Šdž >¯ø;½#4';eåìÌÛ¦^æÍý HéIÍÉOë^MbÞÔO¤ï)Ý®BÚó”êãƒb=ŒÔVn*iˆ-‰¬­×O¶l„1\,òQJ‰ ¶0—â±#f ŸØFãË£ÙIÃ>† ”í¦=óAX°—”ÚŘ“ÜHàܱ­Fí×–nñ¨ß©¥bÂb,ä5ÿïpé¯'¶|çD&H˜‘“ë¼åÕé+rFÝ4 ½^7ØÅ³4\ìì: {÷_µÎHaø>ÃúP±Ô¥lÛ]¹ÀçŠæxÍúì_a06c¬áTE+e5Ħf¿bÄšC á[c&!Mû¯ÅÙ㬖ùºEUÇ ¨® ¹Ø½4^ñv‘„ ²™éË*#]J7…¾hî‹ ¨ò^.ÃÁ-Kó1µApH(LWVêÏŸÎøæPŒ,,Õßûc|Ì~ⱂ eêBÿ€ƒgÔ8°PMU6Ã~ÁI‘½*R#CoÈm{qdo EFÒ‘6 )È_Kþ×~Àùúù=€WøJWù*]5¥ÒUPTVT‰•ŽN¬thz¥#€§T:<ßÀ€ n Å…ø=1,tLC‘¿?dz©a‘SŠ ‹Í‡ H_R(èu—•4„"ÿœu‘Rcbï –ÑíînfÔl…ºn4öd¨x”ž©:²­Îå9EJfc¾b3ü+œÙ__ç[1D¼ýÔÄÔõXè©ÅˆÀ^.óåC1;ê~Ä>ÔmG™9Àâ–UFlQ° 1‹@%ÞZˆ„dá¨ñqKÀÉS92EµÂö#uâ¤zç°€š}ÄÉUríáÉ#?³PÒkã$Æ”ŠJ%D^ä,¡È¿'žsóR¯È‚ß2½ÃŒENé0c±:ÌQèö^͆EšXiçDB½ìÄÔvØ[X¹¾m¶®—ùšo„FÝ<ˆõÚ æ„ꪃXˆÑI"Úæ}«ÎXeçdGÿ;aów ½];„(á°ÿ"'rHüÈÌ]£i…½,–ëݪÈäi*YLuJÁp¡6 ?,þëá_⬽lWuå—’h‹ÕprÉþ ·Y íþ¹¾îжc©VYôÛöMÝ5»b¿¬O)ú”‚L:lɲDÈ]B~bg9ë¥Ý˜7—éÁ£¾W`pH(LGéPLå"œ25•вÌ9‰‹ï“C–=7K]Ë÷…Ÿ™±ÃäæÞÈS£[GvBL‰‘N'J‰z:KB H I­ IT©5ƒN–^Kè\ôó–É\ò`Yd½”Æ`­TR꤉j+s9j#•‚XCÈð)u#„rîr íˆåÂ;ctÄgò{ÃE‡”Â|ÉñšF—»‰TéqœL˜Óit©ñÆ–ÖÚÙ§ö¸ªÑ¨QÃ#rtÛ ¶0—‚².œÃ"E‘‰²»u~ß’r^ºò_$—‚I ö‘ÚÉ9eZ(Laœêºd…?öWÙ¹AQ‹]Ú˧ì®B€ŒÆ.RSd-?Ï4ÚB8âe‹Y¤ÙB8[N!öìd›¢µn ôä‡Cg5j…´O aÝ÷å¿Ûtã»± Q–@!öOMa ð«’`è•I,ôJv™SêM›£7"xäW …é¶Í¡˜šâ‰Ê–õ†½p J±ô>þ’,R ǦðˆöòŠ_~zÚ7‡¦ÍòêÙù0@“ŽÞñòÔl§–¬KMBÕÄrߣ¨7?„(ô쉈´ï0]01%´ý阙ó yó"Bpk4 ó@ĉÇÔÞ ”Þ¯CÁ’{x(Tr_…Jíõù@ë%ëË#OµÕ¬CHôÆÅuÄ,EÞ>I(ÓD$†Í¶CÔ4neµø¹\­Ä²‹x „`-Ó`Ø÷áúy*J†il=8E“Ý-±ù+ýHÛº-¿ãj‡æÁ{}›WahĆtÂlô9‰Ž4 >‘‹4¢8•k·Q?µ‡¢Ü;Ý·òµ¯ ÝÀîëb#oˆ6Q,ô«8ŠÔò 6Õ’é¿›&®É«U½A¾+Gãµ^º ¶0—‚öšLaЮ£Ýa¡¾?O"øÒÌ-ÅU†ÌE¶Õ¹< H(?AUWø—h_±ú.ÌÔ³ÇLL]…ž&ì=ÁÒÃJ» ‹J[K‡EíÊåc1k¶"/R–P¤&^daŠ,øý!SC ‹›òÇb'v¢ðü"ªmÞ¶ßêõ¡¦Û»‘a<¥  ˆ¹†!ÚCQ½9WSt»¦âã-¡ãW g’s|ë aÁ†aÅ›ö”o.4 ä¢M…N§z³7ªåoÇQE!MRP˜Ûš¯Èn9 Z¯‰jªrR^9$†½‚ß­ö„KY @ƒ&ö”HØÄþ ›Øk¢`!Ãí]¼ug0˜á6 ¬ÚÇü"¤ô1‘/¥¦L£L«AÓ8ÓjÖ4δ73ñeC$Ý®ógÜ  f TõñY+F bÓlX4¾Ó¯íòÍvFLö½±œ ×n늟;6-±ì³<˜ˆ}ºqI§ó¯ù’)\ŸôÄ2Pv=D¨‚ ‰¨g*’êÎÞ¤4/•#ë²í²>#ZRÑ›®²· “’ “…Ò¼œ’ºÛ[‹ ¿@–›vã ûñÆlSW?•:ÏmÏ\ØÓCî$®×ˇ5=\ü¤ñÄ¡D¥Äð¾E5?†ªôךã‰ëõ–(˜ÝMFQjyìMQó#Hj™I^µßPÇú\#¡¡&'Ù% '&&d[V?†æ‡É’®ü1tô·u¿”ý Né• ~‘ê0Úåëû¬\‘; t"ý°o®~teïÙ²¶kÊêÑH¸NÜ×Î-FÁõsøt™ 7*ÌÉÜÿ´nö¡Ž\›×›ºeÖ?HÛW`㚺\úú?"CÂê(íu"¶¸³gOØûÌÒfH4~ —zÓ5²«—Î>Ë÷©ï[bïŽÝzOÁB[{†Ä¬ŠeóÌ5+Í2gaŸÃï´˜cr-‹Çˆöøj¢-œYWÇ îräèS 4l r×`–†r" '(&¦ ]á6›êYÐŽ˜Ýég@{ñ=Šý¤øïÚÙ8 g=Oà|\-å‘ãuýˆ,2Ã,2Ó"¡j€Ñ^^Zg&R(3÷É,Îy'Þàã-¼Ñ"±ð h/oJáM&…2s_Ì„M¬º9XdãÖ‡œÏãõÿÎî(ŸA¼/Ò ’ÒC$‘ˆö‘‘JSß¶ßöO#¿i2ê m2™;ƶ_ÎÑe»–ÑdÎx†Èð Ö0Ó’:øaŒ¤).gžÚ¿méÄ^ô$Wò½¨™Øì[Ó„:¼Oi/§j8‚™ò±nyÁíŒe“Rm`¯ø;ù2¹™ùÉ£¸ù™uaˆj°Ëq|šP‚4 äڔ˦n FIë'%kr~Ðk¾^ßæKìGŽée²¼Í¨_0‰Ox€š sQßUd½+×òšC×)P†ƒIrFÚ$>á~j m{âwÔmòn‰šf­Ý ÔžQsÎ…uÄ,âÿ)/ì4ÑÆï£«3è­Æ×<a˜$•Dâî§~¨ÛŽÉ3r7ýú%ÈÛ—J5imF2¯è*óGËÇv·±8½t®—¾€Íð×0?“W@ñË`òU±îòŽ”©Ò%£Ê@þ'!/MX°45 “8Õl)÷”O ûz õß„ ´8<ª½Ä©y˜H‹»ÆÀ°ä^Âe 4 ä"õ¿§Ñ®O˜DE½Ga™uÕç~ˆ€Õ„qŽÞ)mƒIÿGBmµi|Òä‰6™Y? ŸŸƒW CG›ÔD9,^íòá¯í +x«¥™“wêg~ÝÁ6o0Ûuq@o&#aW”‡Q†…n“`d®#óX‘ÄYäzt>œŠ´8ÃDÙô‹%,–¬IÑ5™|b¹Òø»Œ¿ÔäÞ‰H4Úº%¨=Ë·ÚV˜è[ *ÿ[.óuÀÝ]Aâ ݺ©€ò 2ì鞎Gy¾†éÁ#¿€ApH¨‡¿ÊuÕ}Ñ‘2ê¾å;šœM4 æJÉ#:³ŸE"ÿ ç–²™’g&W|ˆ²onîÄœÂÜ2ÑJÓÓËl&•¦AãbOÍÑÉÌv¾îŸ›Ÿt@*Hî(Cñ˜¶ŒƆtzØRƒ%‘.­®'’¥„bqgòº¶C]Œh:bNI!/­M(ýdbT }ª&]œ(4lÞûÁveö&šíÜòüãù³ëYmò¦}È×¢àƒùÓCýpèÔW^*ˆ°ê%è{QA™jŸ,`Ërå§n«ö\š.°+"¢¬ Kg!/µO¦ÊÌ\ÃàgÐà—c0¡DtX°4µtÒ'•T:-¿ëòpŒv'Å$œÂq"M¦DŠAâî§&}ÌIœ¨y§…ë4ò”¦fpDÒäfÇ! %$,cb`Í#bZÍ£a†€›GHr‹™¤¡%­¿ÐÍÝ@oÓWa@À®@ˆ(eóX:Û~‰ ŠbÍ(‰ñ¹ p¯.`¡-NM%q2g.–§¢)ïžÅ$¬¸ýQ¶í®Àœsáwv &`š¯ø¿Ò` ã̱Ô!t©ß~$MĘ>„$ñŸæGRd.«?¨œåC!¶œà+Oïá«1Ãs“.”êãK µIŒ”6n>ü\À,dÙ0,y(ζ ·¨Sé–Hy rÕ…ãã«mšm’×ËàÑì§Mªv3ðR¦}gc¥Ý]>-q.x6^ÚѵsÑò•ˆÑQÐ+^M„•:û»ªïò³Ö~ ö¶– ØE#~gÏëGö´\fSCÒᎥ/¨L\á`•jZv8Hȼqý|zòÉ+Š”%Dýsô¼ Ø6Å–yH=vt 6Ëüø[˜)”аÊ^{Ó€_j³/ „³k§KH9yø)~ô0`Bаð¡¼OÞSyŸ¦y<+/!’f¤¥DO2í·†µ]ä°q½Ü¸lHãçð*P“bgfjBøÌËL‰ y™ëõ*;P–'E0"€'Q$A”ôP"hNZBøÌIKnq´å*Û>49¼_›È.5ÐAرÆ-YþºhñωÐǧ§×7^eü«Ë뛣íó‰qn“óé¶8æË@:ùõør„¶ÆééYBþç×g'7ç—DZ8£€w~q†ÍnêAøâ_Æ¡„¤1„²¸ÄB,.Aÿìãå :c{s‰%ó—st¬(kçóÅù‹Ë“H Þ@ú㫆Yêþ™øñ웳kDÌ™Ö.λó³êÏOÇ‹88ËÉE½>{¾`”g§8ÀÑÂZœ]Á#Ik ç*»¼ºYd'¿Üdï>¿àXÖ.Ι ‘÷—7çǼã7ùÓç›ÏÇY~û|Ï:ØÉEEæŸeíâ|^œe‹³Å‚IÏ>œý‰ƒ³œ<¨Ÿ¡ {ëw–˜(¶ÍG¤“‹ÏŸäëâÓñIvrüéìãÇóãŸÞüGÒïÅ~óö_IØÌľ>ùç4 7†PNÏ'¿œ`a¤5„ó+Wüéômv|}òîòó5Ñöób/~=þ)ûÏeÇg B!®BQ®a–‡ÿ¤ƒs¯.£ÍXâ³Çôñüó?~Î~úÏ7‰™dzC<<„51Žl?û‚½y¸ ,foa]/ŽçÏX(e@â%LDã.~Ä·4´·$º¶·>m<˜±PÜvÄ8»8‘_ "F³Ö®ëu/ qF±¨J’L¤üA.þ,9E3ŠEUÇd"åpÉJ( ‘èšGuq¯è˜ÜËÅÕ^ß"a'h½§¿Ï8:¾îéâó·ëÀ²Ô]|Ááê¼ëã߉xÌ#€mu!0ÞOtÀŸ@Dñ”uÐx½ƒ-úfBho©hoýh”¢ –ìØÞàñ‘½8DãuòiÔ<\<þâ/#4œæà¢]|þøÃ-]ÿë“7´Šª9hL&I{PÙåñÙmtrQE‰2^÷pñ>_|¸¸üý¥ŒG”§'ü0;þøñò÷ìêrqsz|sƒ}\Ì“ã‹Ë‹ó“ãçÿQ÷ð.X£Ÿ_ðÐÙ͇$¨íæ"Ÿž/Žùx–Ý\_,ÎoÎN³“_Ïbc[g—…§çRÑÏ|“‹úîòú÷ãëS.‡¨9xÑbƒ$޹‹ÔÇi0®/ÿ8ǧo0‡‘þÄ£¹}}vqö;A˜zð©ÌHÙå"ó€ð~û|Æ>éx%üóÓåçÔrs‘¿°oWzk‡W‚“ËOŸ./#[€ƒ†výË[Öxݾù5;¾¹á3"?ž]¼ƒ¦W—‹˜Ð8€ÍÖç ‹«ó‹“ÅÍ5†Áqò¢^ŸüDEílÔ+öä ƒ$ !ïß°Þ¿ÙÞ ,÷â^`¹7+MvÇ,‡N³KTVš^<1Ìz~›çðyyqyø_œ²æ Q¯áéÃgßXÑï1ÈÇGœ/ˆ8ûXÞýÁ>l?Ñò£÷ñaž¿cñòñìËñÅ Vsó"_œ³ô|̾œ]Ÿ¿;ç}‡cR”@þ>.Þ(ž/Ÿ£¯d—÷ Gòî·§À;Î>–ËÅ»ìô䌂­\|ˆ‹³ëR¥‡ïüýÅÍùɇ3RŒ^>ÜßÏ/Þ|È®hUqpPÙkñâæìÖu½dIboï t¾B®†›óO)èÜ-„üžõe®Y/AÎt‹ÅT‚ÀøŽ}ÈÎA;à ¸¯Ï>]ÞœMãÕ0(œÓl…دή?‹L*Ýè¿>»I~Ý7Æ‘þ½_;_ò´ðO®Q¯†“kç]prýçÕÍe¦Ö‰9 ’ë@æ •»Ï>]ÝüI„>Ì_ÏŽOÏ®‰ Ò)€zÅêËùÅ{"¬ò àò×Ovyñ‘š ƒ_û†}bPã@:Po®Ï?’3XyÙ¸þrv½8~Ç×fœ|¾>;GÅ¿ãd¡ž^~:>¿Èþxûßÿ;ÿ½b…˜Näf!³‡)¿³ï16tuŒübò¹Ú ×ר¾³°³|ß/n‹v\{ ë=_àÁÚ Î` a Ç }ñPº`]íSÖ·ýñúºø=×ÁE»`5Ö¿FBõÖ ŽáD Žz¼\\ö6ºÿ‡Ìm¤³ñ1$ÞN 9>Íz¬ eϘyÁ‡7‹¹Ç™¨QF@ðýú>»úý4»ºfï¾DB"Î(?÷ÓKnôsë[ ÎÆšuÑKO›Ž€áÞÇÜãLbt™©z—H5úǹÇs{ÆñùàqzJzo‹GZ©^8nœÄv !ÊÞTz¸"=‹›³+±Xxœ_|Æ3xü®›Ÿþ•}:þ…«laŒó <Æù…‹ñÏ7xÒÆÀê¶û.û¼8~ϿϳóLn[<Ar,/Ã~¢¼<ŸÈº?uó¯³Ó«ã›_‰°££ýê*“ƒ×ä1<£ø¬ËÍ¿G’”¯Ÿƒ÷äeÿšÈ {ñ£dpé†@N)ËÙ˲HΟ*°O–G ‰éÿyôõq gw,gçAO>žŸ]ròÇqáÞ¤~g‹ø{å°—Ï»ë³Å¯¸OŸk€áÝì;âòÃù~ð `_Þ\õ«™ˆèšgÿêƒø.úð}ð `/~þÌGŽÿS±jƒÑ øRr ÄqÒ»Ô(†Ð|7×Ç'ÎO'1*Œ'ašÏÕǰ¸b­6W8øÐnÞÝc±Á7!ƒ@3bg@#a¾ßħdjâto Ob’4ç( ñCN÷Ã`Óë¦ëmó\/¿ŸfÇ'','OÏ.Îq½Ą͇̀±³_ŽóV$_ή¸9"À˃û+_tMÔ:øx0û¥db¬îâìì””Á€·‡çÓñÇw—ןHèƒsqùƒó³ˆ ¢ô°ð>^ÿÆ×¢ð¼áÛì B 7òGþ¥ €€¬»…åªq2²r #ÿFGý-„xóþ†ŠÈ\"ˆøU“OþÕï ñ0:¨—X,n °_S"Õvó 'DªíB¦EªíFþŽú[©ºK‘©€§Ÿ©¦“…zÁ‡ÈXÛË>ZgrsÃùªØ<ž þøX¬ÏGõÜ=ž.þ§U·îÆ#É]t¢Ô€ÎÅ'ö¥{[6­›H×_²_QŸŒ£1Œr~AáÖ0Î$9€z>cËí3TN¨½œ–±‹òûÙÇœÁÜEKшÁcúX˜Wü’››ëó_>ßœ-XY¼»D ^®œ2`ÿ9>ÿ´@¢>~L‚NÍ»fã þ#%ÞvÇe`Ë Äýr~rFËUÃÇIÒ9xxb=9aÙ±ã`~¼|OËÊÑ@ãó‹/×T‘¶€¬FÍP_>†=€%<#‹´¼\9€Oŵ¼ÜÏWÙé©&é.¢Ü÷nñOìò"ÛŃˆÝiØ{°´l´¼¨”a{À ÆUËÄ–x5Їœ½,,÷/NÏåb&Ô+Øëëçà=ÙÅÍñ§+üàæGæ§cb7Š@ndu°)²rX>1Ì7) o`T¾õ¹Øòðà&‰l/"v|ÉòðâñÙqw€ÑøÄw×—ŸÄV‡Sì>¿3Ì‚\ЬaüNNÓÁƒÆ¾0ZÃÍ|u~ÁÍÈУŸ?iæ:Á¨ü ‡ßjî:ùQÉZ5'*a2Ôvñ!âϰ]"ˆÙåÇÓTîFþŽú[1Mëo­¿ûCÊFcŸ2¿³¤S–;|ú„ðq\ƒ |P7‘úù°ß±Võ-lyÀxÆ8Ôpó ëÏdÝ œ½IÄÎÞøÑYIˆ£áiнW=±xÅq©™1úy°±'ö,äÌ¿nîAúr=D5±{é¸Â j6«`4±ßùêìDñáËA°ëks ƒ¯|Ëæñ5_&»8{‡lƒ½ÎQ–q<‰gt2¿¿¸¼>“§%qéQ¶Ï7ïþ#‰…;zÑ™Å"9ÏlçKr~¹î¦‹Ëìôì]2“îgšÀ‚aPÛ€“i /×ç i}z¾¸úxü'‰Çòr$å™íeYüz‰Z-êñtñ¿àÀ¾8ž¬ÞdꔦßE/ê÷Ëk\+»"²ã÷Ǩ Wa€[bZéP[9©ÀÒËÆE¾ØÜw˜ˆ´ì—ëã‹“_y Óu|Ì“/b1×/ìEÊþË×3¡`]7òâÃùauèç`«¾ ¶æšïÞž]‹/w¾2jÁ^W¬û{rÃPðAßÍ凳©ŒÁyqöÇ ûW"›òFð,ÎXKÆÏJÏL"Ìxyýé˜*tõëñÅçOgר%Q ç)ë~~B}r†Ü1L¿žýq<‘Mƒð2ªqY"¨ä p1hvùùâ&ûxù;I 1IÏ»ó V»o®ÿœMÏ€˜¤çãåÉÔ œW‰¿ã³ÃÔê¬;ÆÑ /Ø€7‚GäD"‹ðµ8ø¦7s/nøœšéb¿¢À@OqvqªM£áá]G]|ŸòáCÜ0›ëd¡Þœd¬ aý‰7Œ>~¾7äâCìÏE¤@ö>>LQ¡(€Â!ˆ–±Öó䆌)Ý|Èç‹ 9j»ø?ðn(O8øÐøj*¾F y èçÓ¯PáD£—‘ææ"_\¢wFjÖ.Îå«°/ÈrÌ]¤Ågq%ïâņÌ>ÛËÆå=;Ü`foêAȸS { 7Q¤,AÿßÐþöȤ8›<ýx•»Å$þÓ9kJžœpqùîøÓÕC X¼ÃªBQ¸£ÉŸóãu¦ˆQ¸³¹h-~|ÀÑE¿ù•7|r=S¼5òy¸ŸŽÿ௹›ã_d$~Œ}‚Úâì„ß™ûK¬ £ZÞ_XÏ3žg†éˆÀçôdŠß-¸´÷±‘ È»¸$ #Úͯ×gâcîoÚÂ@¦­†ñw“ßcOrsÌ]$쮽‹…>§ pð¢Å¾%sé×ß -cµ+Ä2†PÄíXaì¢|:þyäáâ]ŠIvµØ‰hú¸˜ÈûUséúŒP€½5„ƒ:iÎ1‡‘þÄ£üé" oYqÌ]¤þøÊ«Ëç'Ê…”ØL‡}G~üÕ”±¦:ÒØ˜¶6Æg Ègå±¹}ûæçlYWOEÓe˦XµÙãj†óy9¸eUvYѵ(¸ÞØDá,mv–ï¶)«%{²ÙÖUQaP,¯Ê7Šƒ(M‘¯7ha â´EGÄ<Âx™#ƒ ·òº¨î»‡l飗ÿÆ— 7Qºç-…[(M½«V»-BYZþßžßmŸ%ÆI«¯ß–+Ýe÷ü×·;j»Õ­óÛb}ôê§£][4ÿàÿÇ+Ô]yÿÑVŒÿ~õöHCâ¨ëú¾¬0°Çÿ`âϿ䷷MñTæ]YW&Ômޖ˰¤Ù]Ýlò¡‚k.-g\•ÕQ÷P¶G«z¹Û0 ¶ÞuýÄÑÄá褮º¦¼ÝueuÔÕ̳8úÄ:ÜŠæ¶`™xtªPƒj»’µXqm½ÞuÅ÷ùK¾zÅçUñ½+š*_¿%g A—¶Ÿªcèÿ`4cÈþ}€¿+‹µús“·4–wçgÕŸúÇ€çñÀÙ÷eËRU¬ht×gïÏÙ'­v¸ûD#a¡ôD§ŸjüÁ¯²|]æ­¹Ú”Õ?Äÿó×Â&¯V¬Fɯëe¾–€Ìû•ô~%¶õº\>'C)w…%›ÇDÛnיȦÕܹÇ+æq¼Zñ€ÿ.·ùºå±ýXßÛ´¸<ùàôF†ïUü®pöÛ_ÀÖ®¬VÅw£·àµ’]ˆã±éâýÖèÖ÷M¾iaøÇ·móĺë(Å`)i†þ%ÚHÇ¡íýHþ‚^!QW:àʃ¸b=Óõ*ßf¸œ0̾ñ[€Ï`pYoã˜ÜJáñ?X+ØJC[àXoÈ 5Hö/(ûàƒQLi§ å?<ˆ®X:­L:´²'ÅSvPýc@|Ê«e±ò×ýy_óåo¬»²-—­Ô]É:I÷¯VEÔÍ$îµúåèôlh¤´þ€e÷ŽÙ/åR}IÉ=Ò®{ÈX"øÓÊ2ã¹Bc¿ñ¯=8<í1oóåãn›=Ômçj%Ú/â‡ö¨¾cÒ–»¦8âÏz,þ­˜Ý•ëÂÛÛ×ûÆÜ©Vøì"òVém–/×AÔÁjlÊÞ¾fÿðVKñq†SF}Û²|Íÿ€©á¬Zo5V3·‹þÈÌ0hCGû[Ù=]n‹êãéñÕ/ºWÅЊ÷½pº"‘O{»Üx5ö(·ü5D±z`aˆßz×Rvr›gÀ{xÖWÎûblyê4·¼ëXšŽš²}ìA‹jéÔ?‘€gÕ²yÞŠèÒ5ÕSö”7e~»†1´Ç=ÐSÙÔU8)4^Ôp‰‹¥=”H¿ò ·Ô¿‡éº- Fü¬\on®¼¯òýDðÔ=­Â½c­‡ùÙöãkr¤û¹ü‡¬®÷»rU˜î™lÔš'/Î`!yOÑh÷F»×;-×%ËøÖª •<ŠØdÈ)þoÁ'Xó}ÂØ\àKÓþÖ9>œžô¬söh[éT”/—õŽ P?*ߺª?ûQúðÅ}WM‘ºòÜ>òáx×Yþ.ýÕ²:(jäŪ²wx¤@†á>RÞŠÜ=úärÔ×Wô§ý“„ŠŽVŲlù° Âl·ù#Ðt‰Ÿ%ŠÜ3çËš®©w¼¦>Ô5AúS‰v£ýÂÊV¡ð _ïÚŒµ @&éO%ÊùË ¾ÅÞ_ñQ>Ä­ýC,Ç'ø‹å/yUWÏN®Å€Å EÁì_)ûãþ É·¯êm×¾ZÞv¯îÖù=ò«M\„¾ÈN~‘kX‡/7ë÷¾PŸµ÷,›EyÑx¼7{ æÍ®Û±¯ÿ¦øº+ñcŸ öÓç›Ïb#y¢çñÀIUhÎ(¨õû¿k‹W-m²l|,ži,bµçÙ‚o´Ð—{z›œ»Û4:ãd÷É@ò•e@\!ýÎ7™Cáöƒ¿ï»|·îÀ!do×ý¿šïÿ÷%ã¾mómi´ úÕ=*žŠ5ûê`ï Ñe{¿X_÷o×Ù¦ìØ ²\•ww–e¡@Ù_EÃz=¬=¾-ºoEQýZ”›k¥yûlLŒhtn_Aû]ë,hïæ•Ô/^Ͻq©¦”A¤þaÿÊ,Ye_ñŸxC¯ùžy`z×€¤?¶ßDì#±ÜîT—„'x›7­hºµa9æM°i0vÐõÌlD4üüFDÄ“5 ïõ¸ŒDÞ«#ÞÕç3öGùX|_~gø»@ôv|ô–Ý/ Èv]4ÙžGö[¿ìŸÑ²‡Õ hÕƒ zDójÖâÔU­=ôèÎå·ŒXŸ7ETµe¯i¶‘„bùg÷­e)»"¦¨nVÖ¸KÔP#Q˜–ë¢Û5¼î‰ŸxóV߉~J»eݹ»²X¡¥µEÞ,ÐÚ¤9 Ná0u ùWÎ:c컋 ¤ÝñöÍ铸^×ß²oEþ˜‰oÊ:®ÒöÐ…:hLë1ÿQäœÞì²g5 φ}m‰gìû¿šþ÷ÿü_¬È]QEÇ{®¾DðŽ{ÖÕrY,މ¦ÂqÑ“áâõik|1Èj$‡»OäЫE·T€!ÓEd:Ù•ëÜáy´5‘ä:¼®qψdÔ¤Q|(Öéx ݑ춮×E^ÅE9.º.OJkJöþgå×ÿú”¯wÅÑ]Soú»Trb“W·a¬+.Ÿ}æðƃ ^zÀâš©]ý8“t>êÊžgwM¨Gºµ.Ù@arßñÿææÃ®øÎ?îšÝ’EHÓs_T¼-kñšzH׀ƴ½/ª‚}‹2}ìéQ/LkRy–æüAÅò‘µ©|Z±èâ‚ÙÛø¡X>¶»Mv·«–å–+œ_¤¥¥ß?8bÍÒšžªTTF"I çyÈónÈó1|e6‰ÕBm²Êqœ¤nhjuOŸj]W/*šñ41|X‚–ÍÂÃ#X¢éBå/*’'ÕÂŽ}“„2{LŽdç¦úæçk„À¼<Ê[ž‚âù–4âäfTÁÙ£_2C£ŠFȈ¶øZí6·-„MWp ßNš®/¾îøW÷‘²š”1’áL…°ˆËh–ùò¡ ).r…gg]Sl×ùó‘|˜˜cM±|JȰÑÍ'yÄue/‹òIôM¤Á,µm$$V:Ý1š  î+9›º+Òª¥åëM”Éঋ?Ÿ«f*¶”HÃ)AVζ¨V :F7 ×m¥ùÚ¡£cä"»îMø¾ §$¦Ý™Z‹ZC* ÿ2fŸs¼÷\ñ%ïb8”ï„P’´ÕqåëiSzrš“OjÉç»¶pŠŸ}ÈóŸÙ—òƒ¨ê,Q1­mz¿Åôñ[¨¿(ø(„ÛÃ/+jÈ}-_3$vžä®>ù&¾’?ˆ?*ádíÄo“6ðmÒjß& õ %ûD<¬U#<~&e5±ßúø­ÖÇ—á :øü+J¨›ÒÉgè|­2M«ððh•hJ«“­üiÿý—”±ÔŽ^êèµzG¯£—¦1¡‡×Æzx­ÝÃõZ½!W³œ®Ã¿ïÚÔÎ]ïܵn玄ò”ÞFëm´vo£×¬¿žgÉø´ŽFïh´nG—„h¾áŽÿšéšŸG²Žl(¿ÂÑŠoùp9aLÞ²×ÚHãX¼=c°‹«Ýzýª+šMYåbTQ ã¶8b®e™=åTÁƒ£_ùˆíMÂßUøïŸÂÛñôkòæ^ìUóSÈÉ7--¼XýÉàˆ±Bûy_‰µkä2HÈý`¾?å0ï2 …ÜacÔ5.cœ–Q]ñìH¸ø$ ÝPµw:®Ãò0ÄØh£"Ñó’?ÖwCG±ŸØ4:Ž~­bÚ T·7uHÚt–¦1?Ú°–'¿/T÷KM¾.û•m…¹^§:+ë'ªrîãW/ùTL¹^óöQþ*3ö¡ÈWEó÷£®ÉË5‹¹æDîݽÉóË/¬V7ù³WýªlÍÊÒPÚ{3}§êO±<ªofx›þW¾L‡5•í‘läEÐþ-&™‘š5$¬Ï¹œ$²œ5kHX_Ά¸¹Ê¹ç@·K¦¨wl™Näk¸onØÛLˆW¾M¼QB¯èqmœ‰„ ÑØÐ¢aŒÐúàï»<ñ5Íëg±æd)ºa·Ï=€Xë',ÿê/Ó»ïÙòî {­n¶k”XÝÞÔk i*6 _ÿòêݯNÞ½aýÙÍ-ï2ª }ž¯,ôäÂõm±ÝŠä…º1zÊŠGcC®†Á´žkGUñ 3ŠÆ0øú¯õšµVu}'G‰0‚\/S€Ê$Þ-ûöz(:®+·‡ Ú#î#Ö鿎!Ñ,¿‹E¯æ`KÕ±*…¹W›ë;Wîv"¼›¡Ä5zCj!š04UóÓPÄWüî­Ðý!†Õ÷QPIPƶðc”;vÝÌ}êÃñö¹ 4M›ü±r!̰7´™HZ…׊ø†1 ‘oDÇÇ/ÒîBjB‹u!¾øØ¯C_Ñ£>(¾aÍX½É0ƒއ+\C3úˆ Û5†Îº4Õƒ“#ú´ªÎ1þUn:J-,½Z©Ù>©}o¼^vüˆ2¯®æ#¦¹30/=œÌÙ¶ÅnU¿Ry® Œ-ƒ±-HËŽ~QS½ëx—u¬¾¦,>?"_ߊø†ßñ†zÜZW{È@ ¿T×èe{©¸åä°JÕÔ[Lmp î㻨A2ÞðìšÄ®cF2,–9uKÏ›Ñ7>P·E±Â“rkˆŽÿ!b︖а‡ÈR¬f”UIÖè.ÕjT¼HÃÞi"«­ÕêÖ¿¶;±â}›·í·ºYýM®»µÑhÆ{¬©å¢P¥ê¾~ÙC -˜ Õ;b¼<=éH?HÁ—À'Öá^&o#16K—¢)ïžYÛ›wZ7É铿GÂwÜ´¥“„*Ñâ•= ½G²„ë»!¬7(ûÖx”® åa&ÁB‘Þ´0‘ýAÀ+¤´ï~Ṙ›½WB§Ð—ˆ|½äá(]nÇE—ï<ôð.31ÙË^XbïŽi®ó™8¢ï\ñÙˆq¯•šUV³‚Z5“;úc›78ún ”Fnh©¾¼¹ÂÔE?;{_"7±Ö–ŽE´Ûg@‹_„Úê€Q LMúÞ_t¾Ûz­Zõ?;™Øé3¢e¨½H–=¨+ëw!i“$â'õ ëÓ’ÈÞJõ3N0µ…I1À,ÿ$•×n‹¢Þm-ZæÇ)wr+Yq´ÄiQ­Xë+_Y‡áÕÌM~GVæ²Õ–5Š…:Iˆ¯Ôy°mê¥:ùÅ ÞÑ,ýÜ%ß¡’ñ4„Zej*U?ðÁó]¢Ö6Ë€¢>Ôrëô m[%@80nÁ”n슋l…pÊ%¶Hª‡Ý­×èêm8,{'2ÔsjîQÔÁÂ@Mrúÿ–}‡Wu'{Q âð .lW¦±ä¢+è[Äña‚J\Çt´uµõR# S2M[Y‹4Z›’4{Ð/eS?¡Dp;“^x2âOõ’5dÙ®*YËŠ!­Mz E[¶,§+ìvÀ…¦:i $Ü ¨Šïr;>N²2¶÷N5ä«[øKäyÜò‰ÏO¾òò©@«ÓÌM}:ŽP(JX?d€Üð7ªû…’%LmIÒ_ëÉåÔþ[£ršAšƒ­GDzvîŽý)YÖ²ï¬%ª_#-MÊ[,¤Ù¥–Æ÷ß(òKÄ—IKêd´žNFkt2]Ýžn†œ“ d\Gî«Û>®T»Ï¾°^IÄ`l)=¡î µzOˆë©·j¤\üX³­Ë›ŽÒ6,eSwÕr½@­u¥×ÏüÌ€Õ«6¬ÁÓ”R œÇºVÖ¶æeˆG½SEÉU%Y˪n¬Áô°Ä™hâûL®2-ôye§†‹®Žôe‘&œýGnp¼ZHå î? $N)7ü°Lµ·²nŽÊNNÔË ¼ê˜I¶Ü5mÝàÎ1p< µ6š¶œÄV=j;’‰¸Ï<ÓÁ'c™µ¨ìäp??oEvF|ƾª¿UNBZœîïUø÷ί\®×í{ðâßN—••† Ð‡œ¿xùð «Twq¤x¼ÉÊ;°ûeóÉËŠ¯ÒyÖvÉ­"¹ýW÷EÖÏÄS`Úëò-$¡ÿ¤MF Ó¦ß˶3ãÍåáž^•,ø@âò±}Ä„²io¨4‘ôÎÅå5ìu±Ùòa{ÞQ± Î ¦b3wT½wY /)îχ±q‹«uk[xÿ»hû-ë ÇyFcƒFÃÆ[X—w+†EȬEq‹åMx’Vо¬è§~ø„òÜÀG× 3cæT’˜ S ‰ë"o²¢iX{ÎK×G— ŠÑpö³\½ýUöŸ;â6C.Ëw|pk‰Ò÷ FuæºDg¯Ô„Š~þWPÊ®{ΜŒ+QÖŽE×Á~«›òßêHE±ìÔ¿óc€ÁŸØâº@²Œ3ZÔ°yH'‹ ñ‰©ôt“nm«2Ww‚4tŒ–a'FŠŠI[‰Â°… ÷†R&yÀhzG>Q ~|ðBk­| ~«oÿÿ(ÇÅ–â67\om6ü u¾ç‘½µ<-¨«Bß·žW5ïØ‡ÒÐÏ´âä›-劖‘á}Œ†[ßwji*7ŸœWÏÌáG1ÖŠÑI–6Ìm]Öé¡"Ÿ¢Ã%Ü‘µQ²¦K[›Z!X>à†«ÙªXÖ«bhã3ÕmEœ|âõÔôùÑ™ÚÏÕ·&߯’°Td†Ö®¤1ÓNÅü¥v¼¸xýÓ+y‘"ß |½jP»bܽOêìºË;BÌv0ˆ,,£'Öü¸á'yE¤M‹÷Ç Yû°kxLsM›ùÀÃU¥Æ¦×SWPbów82ÇN DóêF…†»]Jý„Å}·èÆ.Aà«¥ßÐâ5@jÙ›\’}ÎR]zræ“}“ò{-_G"«ˆã‹*‰Gf¸†|ßæÕJ\:„Ë@Ó^×f!‰slªºb½Z5…×?úûѶnÛòvÝï÷“ÌEóT.}-ÿ]ɰÑ_†µ¦ÑDV;¹5G­ kýjÊöµ¬t45u¨ƒø„ÍއË6>óò iøïAÓ\§3qúÑH1Å ¯näõÃèïC ¹ÍšbËë_ÅÚ!šNŽL Ó> Ö¡ ÷O$&:JukG™¥}þñ¬ã}ìœUŸûJ\¨¦e¢yœU o2à¿p]H°ñ…kŸ©‹ÿÂxè/\ÃÚV¥áê‚Ð_¸ þûvó©3¾†Ò¶¾d÷ã[X½ƒ½#tD2R«¿æ†º $1+*ïù@ŠÒ<Y:ÚXÂb·Ÿ»eö^›üÔ=ÿú·°`Ôà†n Èì7´d2o1}¦“ ßßH >ÝÅQdàÅ‚52àôºZ§®âùñí.Ôæí­>ƒæ&–‘á©A—‘)Sl¶þwÑÔã[Wœý”¯jîŒ}×Å‘oà¹Ú/3èyD7¶ë†=uUXz÷¸ 2ðn¨µ-y@Ú8äáHŒˆá´pSGˆð×TÈÜ&¯:Öýÿ?ò£±ø 7’e¤AC×Ô¬šÚû÷j{—YÔ†sX·¸Ü‘¤£½­XCÒkצØÔͳçý1ú„U¢‡3 k[¡>œ©7J:¢a¢nÂn>uèFŠ,»ËoÅ–Çgºt×à’À>Ã:qR€p IÇÓšæ¶Dcœ6ü¿Uç Æ 4[[Ò8î Rý`TÕÁéw<‡u÷¥×0˜ÛºF°ƒ:®}b/Ø‚#Çm5[GÐ0f«2*8@+\v¿HõÌPC1®‹-ÁÄsŠŒ}Úò[«n8¬EßV”"Ó­uuʰRà®n¾å ŸRºy#ú0rx›ßvýË«“ë³Óþ=â‘'ö{hKÝb-{M¢Ô‹¬ôM°Á"µØ[³ ôòë’Ïqžú-T ½c@FoâW}y¡”@Ž–:ÿeXãj,ÎåöâvÝ×qù¸ž‡ãá¬_C5.ž7ºÈM´.œãair:pýJ·¿õý”ïßì9_yøa½ ÕKqÿlVVw5Nê`nëqôŒS÷¿µùºGûæQmwsÒNOêîÔ1å”þ¥ÇÏÒ XøeÙ½¤fß¶/ÉaÅœ|"o”–…ÇÙSVY÷ØÉ3dÇ ¥Ïu³tº8 è5‡>Ç€ŽÞ§¤Å ÏCN­w^Zö—¼ÒŠÂòrømT8¥{‡¬q¢è¿FÉ­·<½—ªxpô‹±Õ­ŽËqû”›„a‡AìS`A-Ùöø…õË·ý¢ñReûÓbwhDÂò-6½u~w¼¸Ñ·¶Î‘8Ô5!¿pBø?Ñ2øæ•þTÑÏHdc„å9Œý5 겺†ïx/ÕaSe5Kf Îá†ÌÔ$öˆô \ý– æhWµêE6>å15g—úœub2uŒxJ F(±†Áìé5WÞóS)7Ûä†Ñy«°sCš½êÍ^)³¹óDö0§Ôå!žv­¯Ç|Ç€i2gMå÷mÉ÷‰õ÷ó¤&Õ„A¤×âíÍwv°'ê2&íÖ ¹,^MKÜe,qˆxBu>•HñÌ› ßÑïÚCòpHHRB]¥¢¦†–ô”ï'éÉ]œ–ÐÅi.ÎP¬ò—9S%‡ÃDCš¬‘.zéÏçnrÙ×Ï´š9ÄÓ9rMq‡S.mm¹ A¨4g{‹ñ «àZMºÙv!W5Wàˆ¥Š^yÈßä‡þD¦¨6Ñ󕟨Ù{ÇÃRg¢)yêG½õ³o}„jG8ŒVÕò<§¬Áwž Kµ‰f8nÞ£*÷ݪˆ'JÉ[™W¬Q(XcÊhÞ¢dõÝ]‹9œÞv°Xæ«¢áê 1ÊO¸Ž†B?aO ËÇÒi#ª€~vS½ZJÙü!—_ëÆš.C?T°[Ç@7:“G—Þ õ -üx.[R.^ ¨9+ËÞÑ;"ik¬ W&Cæ€.Ó¥ç:^~Ý•ÖiWC£3U(²¢@N^ÑcUÝ“i€ÎÜ›! ¸•É“? Ãjå~™Á:gïyùëÐöÏ–qÌ5ÂÉŸ‰i,ѽCù`í¨ÙJËV,ôÆ¢oÄJ>òbLGm\%ï-#€^°b •÷ÀEó¥Îfà¿©ãg’î…{üüIÐ{áòZ{ólªéÚÕ&Xªô~ï¬Wykä~ÿã¸ÊxŽTtÅ–$ŸÙ{ts$ûÀ5Þ”ôcc“Ô¢èÖ¶R}¾~\1ëâ²Nú³µì=¤‡°×ײ·5ÅöùÊ›‹å®)hÝ+ÓǦµ‘™ºZ?«1½E×ök<ñKì];€èÞs8>W²Ø‰á5Ó%_¥{ÇÞ‡ù¹´Ïñ0[hÃ1tr%Ÿ¼ÊCœ…ûáú—·ÙõÙ»³ëëãìãŸü»±›¨Í#2¦¹©NDZsÒX„ØGÄ·¼=âwwRôf·îJ ÒŸøéýÈ[ ~Y ¦ÖèÆš`ÃÚl¸oJ]”-NUàŸ€üÁxÆFäìžGôù+À ,ôÛ§ëmÎg¿ÿ-& uëΣçþéÇîŸÆhÅžQòœRòH¿Ô™ ™}ðµÎ3\ëŒÑÚowBíM •ƒ¿*ayk’ÿf-KÛ±ßjUäæ ±Š±ã§c²ÿàgãò=©^™ü’2ìQ=†µ!VG±Ö÷¿[Ò¢K@%&ºÃ`š;Úô.ƒvÖ:?«?t0Q{¥´ë_½×¿>Ò¯ÅD"ýØÇà°3^«é÷ÉÇ\_úh]_ú˜t})=k‡ªˆ¬é†½¡×D=[L÷*£ÞD÷¸‰î1á&:Lî¥ÜE÷¹‹îqÞ»èÉX-3¾%»{Ѳץ[Hü»‘ýS®2ÐÎo’«äk´'evy¨Z wôd–PMŸX¬Ôn¸ŽQ£4c] ŽÁ‡(W+µ)Aþ4\°ÚFÁ@äu{è‹äS’…æ»VN^ñ‡R‡¹â¯7´µXWü­ƒ×¦=’r̆Hú ']Ïñ轚ãѽ–þ)jÌ•À}qu4³øí«ëÔà\¬ (W×™æ&¿uuÝ5kó>¸Žà}]‚²ªŽÖ¦Šñw/‘òÆò Æ&͈1î+ÖnKBµèKÔ4[W…n9:Èзi¶.·ÖGf4Çîy<H×'Xö¦ïÅ Cø‰)ëV|× —%„/Id°â~,t¬ŒÖ¦8 sÍ"ãäþÅu]S£ƒhÝ$¥†š‡ñ”'S\ß…Î@ÝÞ–§!7%Ô:ìý_£©­d¸ÿKV9Ù¾ª±;„ÚíF¶ƒ)ƹÝhÁå5ܪ.“7šg bÇJ¼F|+K;]•ò4.*ïœ1Xuf§<ýd]‹Õ“âîr¾é`Íç“|ï ñÅ8¤Ë;eÛîW.ù5õ^l9¸#n^‰ŽçÑñé«§'çò9ú\éMÞ´ùštÊàchvÅW3\¾¨Ã<~S4÷„0Ms]’‰Ã¯aâ¿ußjße|‰°<•—u­·;l³ŸPlõ†º¬Þ—1øN&Q5™-òu"Egž?Óúuáææ{CS×xb˜ÒU‰ÛäEÀq‰ÙÙõõåuäô†Saó¦ró¦Bæ x.O _XÅÂHâv¦"ái ºº>ÿψ1)ÍLÊFNZšÅ ue9_e×gW(þl…˜ M¯EÎéÉÙÑõÕIH×Wœ¦¯¶ž¯ÆôÊÀÿ&/¾fÃm8òÁÞQ1"…å¨é>ø¾¶®Àô+EMž);SY?]f„êâøÝY${ê6o<¾÷;ʬkô†¶`W ¢²wðŸ…OtæqÒ=°—pà̾‡…{ÜîîîËóMsMš…3  ¨‹Ÿo| ~¥rÔ¸ÞÐ`ݪ‡âãß7„Äæ·†cv©ÕÆýåLYD’øAÂøâtD¡0_õGü7ÍbV«·pÚ°T9‹Ïµ—N;ýÆ"d‰¢põ†–${ÉV¿>䊽 ÊuÁZ›ãŽ•ì-Ÿ_9)šŽO pÿ2e‹KǼ¡´ KKœôwœÈ?åM5o#妲¡cU"z¶!ÜÐÒÁ #g˜µ*º1ÀÀö³È±d‡4µ”¿5ý:FˆNØhgjég\UÂqýpè„1 ¸¦ÑÔP5øW¹¨ÓÇÏ9a"ÇÁ…Ÿ¶²'<Ý92 7Û ÚqkwŠf±„E‚{D³žë¤ÞzéòAÔáuÉߕ߹`y­Ñ—ßÓÛ†Ô½AíH3Í ‘Ž‘ÃVÖŠ6Gþv§uy]r5<Ï–õFÜ4‹Ý{@º45.®°eߤƒA‹Õ“åÕ3r1XÀ7¤Qcðª=bía­Îå†Üµ®Ÿ¸,ÈŠûõkÕÔ.o{ã WºzÉOKÂŒuj¶†¾áW/{¥MÆZ[VÕ,š¹I¤ãˆË’ÅŽ/>¤%7»‡7øV’‚‹HcëG›î†re§#¯†[ÉE7‘‘>sáÈ3^›r¤¤74 #%ýUj‚3<"Î%B E(;“¶Џ’q„‹`¾˜±ifrª±ˆ+Õ©[õ C51š:2ú¡œÄH„€ýŠ“ôÕ–ó5*å·x® >õgl3®ŒíCù¥/¦XЛ kß@j¢¶“÷ù ´:oVò\¿ õý‚5¬MAŠÞÜ‹µFì¡8õšmŠåFˆ‘††å+ǾŸô=ýr¨¼Uï¹ëêe½Žhà=r±«¥w4 XXmòåØ{‰SpùdŠW²:Å@~Ð?äëuQÝcŠô3#Ûó˜ãyY‰B¿/ŸŠêHìõP'˜G.„·^Ô|6 ëaZBªLG0Y6K×G¾É „Ëcvû{Wé ©»í˜‡¸­3˜ €C¿{@79×µ˜þFY{ïÉø“>—aìˆ= r£Äâêòâôì:ûíóÙâæüò"»¼¹’_y'êc•y~eû 1öçsô¦BÃæ_wò¯XúPŒªß>Ê X©Aúƒi™H¡¦ ¨Ñ¹Ñ“9vWÎ/Îoˆ‘§ø’‚Ïñ ¥ˆ‚*9Cƒ(™áÓúbB¥{Ž&-)M‘Ä€©—º®’_:|”‚xß«ë¢ÉðÌq)>*‚¼êuè$D)C]Gï+–iŠÁý¤Î‘:|£ß5$×áb7‡œ ­mÒ°bYNô‰›u†ÑØBœ–|%D¸¢…®„¸d©hÊp%„ÓõFÂRÃïî[ü©?>Gv[m’î•ß¼_€ÇÙö«K†¨á1ß–|ïE¸÷¢…î½N£UóÄÀ]ˆAS±ç}µ}øì¡F,†r<,¡&Ú°o‰ÞÖm÷Š=+øéâqäî¥W\šºÁP7¢™êšâ„V†þÊõìÛÇlÖ×FœÕLÿX™¢Sý:A&ܱg{z==òMtlZ„5:!ÃÐ+¾%³|lñ¢qbžhÀøm”¸§äÙ{ Jv„Ñ6X[ªF”^Ïx|’R”ÖuM¾$¤íºXB-<ãІáWãý+<ި״è~î¯;"í]@¡ž!Ti$~æW%kÄVŒT1 '÷±G5޶º8 !´›_XðsÔä_Æ_PëáO p]©žy(ÙÝn½¶§Çú‰\µ¬:°X_v 9þp‡s\¯ë£ ¡ÉRÑ#5n†ŽJ\ë.ïú¤(Nay•‰ç² _šQqØ­ÉŽ(OÛ¢ ê«ìÎRTfÂǰuy§}F“þ£„ÀÖ»€”ž·¬†Ïœh&ˆ›º|³%ˆ|@u#¢WÞËãÏë»U/ŸÁR“2z;£¦»¦»ry‹ßá­Õo-Ö_qùêìÚŽï2 èé¥r‡ü€½,ý.ª‘™ckŸ±—I’'°òíòôò-Ÿòõ~äšd) ËÇŠ÷É{$Ègšë¢áãøÄWV>Rø›p„Àì#1¬A!ý’çjùÐÔU½kùí·|Ì<¦6Q)ò>Àǧšv_²nܹu€W7êÔº$½¨¥Ž¦9¨Ò{R«)<^€ìeß‹ÿûþ¯öèF&å}“W¢Û¸PGœÅ¤£Î3ÍAéÑÓÇħ‚Ôø.¯%òHÛU)[v@/M(Œ*F·Ú„;ê¦`Üj?ÝØä[ñç[Ö§7˜ÖmĨ5“¶ƒGo¿n²×RÜ_x]­Žø˜~÷€ÑŠ[&åºøô:kQy]œèrÐsyp jOÈqut<-¡Ç¥ë‚Û@¿«}f­Ã¦ï[1“¿óæ -–"*6íßùö¯¥:sh[/½!ÒèÏ ÍÖÐ9ü S¨uÁ)ûý®š€¾XQþ­É·r¡—\’œ¶ë‘z„ŒÿëIn<ŒK8z¸”Ú¸B:R6¿ç»Ë»aïùk¤Hü¥˜~×ìß:íR?ì]xõ—E`/Y…©Ä ÝVì٪껼\'¦ËÁ‰&ÒeV#†ý’/Áe+ú¼ïèKjÚúï§Øð§yV€Ýó§<ûÿkû¶æ¶q¬Ûwÿ Uõê-SÑDËÍpcy4Ïòù,͆Q·™ƒ§Ùæ¢DÓÙt4ˆÆ£ÿãK,†È´¢ÅI:E•|4…ùëqžÝd¾ÌjœB¯š]†£4ú2Žó,‰¦é(‹‡ùà:n”k‰–õXœ\ªP¡ቴ}Ý%«PŒ.öËYò%CíÉ,DȬ‚Áƒ±ujDó7²™'G˜{|¹¸¿ÌÅ“\Éìë(à:r…‹%·q=ð<êÎR‘ÄÓøÁûÊø8©?àZqOÛµâNùì&”…X‘ÅMŠ7É¡v|œÌîRof%N¥WÌ. ÷¨Rx¹0w™‘¥Úˆ šÌ&“ÙÔg^ÎÑÐ)##lÞ³è.»Î£,ƒuJãq<½Šé–.iknÛ¨¢vG»Bv{Г6šÒ,ñR¥E‰J4£;>L;˜EÙ™ÑÎNvIôaÄž" Np#ßz#ߪȷväÔ[sªjNÝšSoÍ©ª9ukFå=˜º7Ã|æw‹å‘K¶xâ™ôѬu­‘-ÌHέà±M‡¨é™…æ^ 5 ‘<ÚÅ ¢Iû¸ž)ÄDN,í¤¡klZ¢MR¼ÖÛÈ!—_ó(™ÞdÒÀlíÔ£KôÀŒãûhš± q&‚ÙCÃt„.Õ8¿“ÑåšÿQØb0ª2øµËƒ×ì(MïÚÄ–0“”ÆÚ.`‚*x¦¡ý‘A:´h“Í©]Õ,½Ìa+ß-4Ƥ€šÚyÓ8EÝ× Zbb%ÒÑÕ4 nâ°§¤ 3’sk»€‡Ñôü&ŸV˜<ÊDÏNvÔºœfñWÔKŸ¡«…ZÒSÿ{nŠU”˜\¼õd£I'-çÐf? W¨g“ †>Y6?3ÖcÀ°i3¸vÒyy7þ±ÈS1÷”Ä“YŸ(Yi•+øv“ú—XEòx‘çq2á¡Ð`©M¨M[ãá'&‰³îµŒl$úøKêTѰ@—ÿªÆ{Ѱ+Ô&Žû¿öÏ ‘<ƒÄÑÂ$ól–Ó§b¼ÈC“8u³—x-†òCŒ…L^¼ñdž=†ã 3¶yQ_ÇÑ0NB¹I”…œ½Øç¨šM¯Béi˜…ŸZ½@,ŸMÇÁWŸZDp»ŸŒ,‰£à¢O¢l°Ñ‹=K¢Ñ8¼Ð0 ?µÚ<~‰8Uǃ»$ùÕ.Z”H¯­ìÃÙ$Mó¯ÿú ŸÎ“8õêršâ&³Uz¡¢ -ñ$¾ÅÓOóÈwHÍ+h±¹Øõà“r|ÈÁQd‚ßVØË(Í|?(Ò)ÝJw_g Zß‹Š; 4<ÍMá?lQéZ¦ƒ™ßlšÂc5‡ù0ÇWÞ#XÖ`EˆÑÇ%)`&TÉÛfB©Ûõ³YâKÇÜe.–ÚBD'¤ýf¼-a±du @²ÿãÉÌýeJžlçŠ3<4†k)Yº¨îÊÇ£ÔkÄ£BTäö é;OØß"Ï9oh ® Ün…~ˆ!îú*Ÿ? óy‚Ú‹]UŠ-2E×dHý„²Ø¸6~!òB+A'‚[ W%©‡¡†îïp E·FÑ3L¤çZ¶ø6y®µ"– ¼„å貫¸À­®ñ ‘—Fã®÷BÝ’À#D ,I8áJ±p·(æeFüéø†çœ‰#HPM~¼¤LMÂlìÄÚ"_¨4‹çxÛ;šÞH±h¢,~yÙ§?óIôÕO u–hiZÅh@1šê£©‹âóy@.ˆ³LAÒÚ(¼sAœu G.nâÇ»4º‚qî|”y%D S,^¤°a žͽÇþá1Š——°IøÕ˜X¯ÆÄójÀ˜Q<œGÙu(wi‘Ð8x(™Ïs²¨"üžH¡F-’G€˜xŠG—ºÉ¡ÁNAÔÇG £ñ•$Tj–#zxйţùáJHœU1ièTf”è=Þ%'í~›ÒÖÛ”Þ&ï%mJˆ•üÖ—†ýðÚö´}lÒø´Kò_ô¥„˜è[}q?×,DŒGñ4¬<˜L‚L~¡ò<›ªöèva®æ+Á£­(.H 2i`6OêKÔ¼L=‡qÍ‘VÌÁS‰ç¼dåw «ž·è¾W©J¬CsñÐÓé~¸n…÷]¸JÓ<›Ý ¦lXiâL³¿†‡½ŠPË:¾ê$¥ w)j¼…Í“Ñ}w]Ý* œÚU¢›8ùÒ­Ð(±&EŠK»Xn /lÿ5|–P“ÙÃC ’ýæNm5Ø(Hññ“„§ñ:4à”X› ÁÅO”´Î—H ¶)}ü$áÉånW¨ µÉi<ÚÅ &j|]&qz=õœº¶Åšä(.^z.¿æƒÙìf‡Šá%Üî%c–ÍÙ_¡B„P‹ÁÃK 9;¿ù*…Z„p»—Œô;X“ð7™ DU•ßz—‹4ƒg'‘n¡ÄS¨ÿmM£‰ØÎ®Ì6™ºg‘Y nFÃÓdR/¡Ô×[jȧˆ¶X‡°ÖÏy@:G‹ 8ÂÄ íŒÙ•4š€·‘õ\çÙ†aReqí Ó{9j „—J÷òT%îzv¾Žb¸]œè&¬ë…¢Ûd…^®ÐD1ЩÅkQôîP¡êám’Ú*Òy”¦Ã< ÐýÆÓ‘g'Æ'J1˜Û5 ¹Þkó´ ;³µRA%é>NRÏef†0½`mp »U„æȹ­•š},ˆ§5§q< +†pƒƒW«°I4¾œ%“09<È ‚ÛZ©ÓÙe|;xšÛÚ©ïð3DLBL´Äb%'·ðÍ <§lèûý‡)N 7™[5Œa¤Ž–“ bœAƒhöÓ@¶ñ×@ãl¨ÙWÃmþ[;÷­ov•ó¢/2yó|{l u¨hû™ùϺ<M”ABct²OgSoNðU˜ ɉìs5NáUÍ­º<æjœAƒ÷cÎs5ΦÁç1œo;ðßÚ¹oýxs1ÆÆÛö˜‹Ž¹!Ô¡Âç1ÿðÇ\Ž2Hðx̧0/ˆšód”Æd«žÑܯZB1#ÞÝÅoàΉÑ<\b&iðCdrÑâKv ‘v ÙÍ»%ã^¹N'Ù<Ÿzn.!úË\<ÙÉ•Üç×~ã›·ÂCÛXFÓ p×y µèkX~¾3ôµ%GwÞ%ñN-ywî’æ·…©â­08¶0¥.ñxÂÃýe&žìâŸ!†>@rÌ*Û¬Ôs8m$Ë’Ñ—»,NQÙ¹œùÂzƒÕ)€¬¾AÿE£IêK/)ä’͇:$ßBˆ™¶=¿IÔaùæ!fÚÖüâ­>BvNЂbÉæ¤Ï®os¡6'#L×§÷Ip~Õ8…]5;5ÐYB¿0)@aåéN:|’axŽ•0…Z±:%-Á”0E€bu ¸›Oóá4¬JcjÑäà%^¦Ÿ½¿¬Rc$^ÙÔÊë½e§``toàɼÒÀÛ«FˆSŸ›Ë\ƒV±ÂŒüíkW¨/]ö7§s×: Ѻƒ“‡*TV¦ÃQD>÷òkõZƒšIÐO³h2TÃãÌB¸ÙGœçì½!“)ά›[5ÐcÅ}ë#%ÈÀÎmþÔç¸Ï]äçmì°3¤ïvJˆÎË,­¤!«ÊÔmëZ²ÆÑ{¢K 1²º'¹?X—Æ FJ0´1—µ—Él‚÷ìzo€eÖ•œÚTùŽù î:¯säŸúìa*Gètmû—2·lÞéE#ÅØE³†ùh á"š@³ŠÆî##`™ŸeжºBk0`7n=JgŒ>ìáy¢Ìì¾yY–ªÆ˜[£rÇ€]ãÕoÛNòªc>»pCœƒ̾n;ðßÚ¹o½y;æýÖ÷[¯¼?„ö£h„÷Á«•ÄÃë(ËGCto`¹SH{I‹ÕUh.žz`ù‰çÊ?c U µ·Ë¸D ¿±`%ÄDM,m¤Ò:ëf)N§—Ì­ĵÉ!Ä8ƒÑ¤!?ïª"?oÑ‘Ÿû(Ag”ă,P 3k`V?þ ¾ a6-˼ ¾Á·¢ t‹ð¸Þ{ÙKZ÷>öÌËwi»èo s.kgN÷ ¯!B{ËZ¬AƒêÒ¦‡.þ PA#tnjhcÄ›*Ïã9jâæ~r ô`]‡îc—ħÜa[Ò(çÓøÒ·I`EYT5K5ºéjâÊ·m£«é,‰ÉaNÝÔ‰N}¢c€Â»ìò¯nÊ Ò©<” ß´û]T£ŠT'oUÝïŸïPxïHÐt–ãËîÚÄx‡6Ñ-DÛ)º<4…é¡[w%8”I~òî¦$n8Jçãè1Lšl”¥øHêvÕh§¨€ûÈBÒë™ß§Ý–P§ìásïÉ|/ÓÜ;0Qe™åôü¯Ü){˜%ž¯Xs¬Ämv Ö“GW‘ß¶rnmÄÑKa׫Õr¥‚®ݺ4X ³) V»ß–¡Òtµ÷ð“˜I¢éàz†^ýn-H`ÓlêÁ=þÂî j¥¢ÿáS/?v=N ›Û5¤7£yÈlÆ@“ ÑîA;(Þu¯!‹#t=‡q‚‡Â᫲5áÆcÔ'‡‘y? NI“Ó³“ÈlvŸ,ƒx žAR§ñ× ýê*’†·È£^AÂÒ½ùà ¨î´ˆÑ"QtõÕ9K&5¿Ž¦w“8ñÛѩĮT÷ “:DÝë‰ß€©+¾M u ÓvNÕ'`´i\=tÒI!RTðCFöÙÀ󃳻i–ga²½ ¹ðŠ<1S—£)ªž³äñã2Å!ƒ3Å#OÌÔx6¸ñû()/8;$Ì#/xú– WÐb¤QŸè¢$¤]ëwkjmåšbðï* ·ˆÂ>VI°ß•;ø DðÓ9É'wió“tÙJúÑC%f£‡SLO‡ÂÀ-z¤"Ewp*Á£ÅѦm=§ õ(El´²gƒ½?P¿á În¼Šœ#0«¦v^väm1 213[;5®Î‚xq„‰<sô®dá¼$ÎÊNÌíF¨uèYÈÔ75µóÞ@‡;ˆG˜8±¡¾Yƒoý|Ï4šøE{» ¼‚6ˆG˜ˆ±Á“±C1â¬ìíÅl:óßÉSp—Yª‹h6G5ìx–ú–*î/SñdWz7ŸÏ¨Ëqáó½Ÿj˜Ì¬Zí ×é9Í|E*šÔŠŸ§žGbI&œî¤ó\iF] ׺²€Éd}¹mú޶9åüW¼(ã¦Ãé-÷¨}ù¨FvçŸÎ.£‘WWÔFPêámÌ?”ÅE&ͼBµ AŒf3Q“œ®«Ç³”qF¾_œDiÛ1‚ŽH"ÂáàR’]ÃK”|ùåñ®²…ÉT«IÀ$ú Ã,úBÚqëðž!‚Ð FÆ4äÃQò¥µs#xR†&ÁŠ|:Ö7RòÐY’ V6’+]¦½«Ö¹Sa3YܤÓY('P)¹ÁĘ]'1;œÀk±…Lv&ÁWÙÜgõ2/ÿS 2aË©‚Š[ëxæod3ç0§ëŸ-)o™‡&ºXüö[R¼eÇÞJ zèGCoì­²àDË$zÌç³4CýRß!†È|¢ÅE:ÃËÀé'ú¾´rL,Û\ÔLžïuåþ2!Ovr%qHqdî Muù©ù«TŽ3.E§ÇžGãÑ…OvüòÏ ÷—yx²‹‹ª<ŸGƒGòõ±wÉ0Ë*Ì>&IøA…æYŽZmïÙ™PÊivŠ» Ž;É‹eµ]–?[°±A|Ý»èÕ«Ín]öˆÕ ^çä‹jûVîùb_.ëüu¹há±…5Ô&«CÀj»:äå¡öãeÞK´±€žúàA@lòÛ »Û¯¶ ä³ÙUÛrëE „TŠ¥…t[lJ>ðÖ¨ ±…e_ë? v×xpj Q]BÉxˆFÈ-¾¤ù²8˜qœ›½5¬Ëíó᥋ éÐAÚ”¬þP¢À[gD‰-,‡÷] xk,heÙWÇíò¸ó¡ ®>M±‚ÿô*áü§já…µÁäZ.CË«ApÞ 8µWl—(l\Žû²6 cÎb¹DÖÚM z ziŠ ÚU ® ¸VÄ*û;lì("ã7n^¢r¸+öo¡1q‹“ò»/Ów•à»÷xxÜ¡üé•Á]ä’]L®*Öàª0h5©!Ä·0 îg¡B>èÕ¼Z‡jïIÅý.žn#ûVUë²ØzÐPO€¦Ø ¨qÜ×^yà¾b«ˆ¥Ù ŠÅKé…Ž4$ØqÕ:D{ã.q4ÉV¦—rñZ7>,ÔUd IVt0z–Wî+â³4+´[ó]µBϥוýÕö/Ko!ƒ—ójW¬ýéX„NÈ,JÏjK¯±Z*+è³øà"7ýt!†¼1$…£õmVÛ§Ê—|UHsÔžàµ\ÛAßw‡*_Uo^ÈÌY‚g‰nß§Ž;k®çÎó-§¼á\o·e¹F/%Lì(¢â.”#OµÌUÀfI.tÔíÇíÏR¯†(l¢ÉÅzx=„02w…%;˜ ,äßÖÕâÕªñ—¹št™g©¥ž2«¼–û½×›û‰°ðÛ ŠªÙe鋌Uxœhåø¹[íË|Q¬×ߊÅkþtÜ.|Ø a"¯ÁlSð´.ž}êAì'pàß6ÐgÔgÇ£Ydä¬Úù”c=H ÓVîǪ̃ÜûV J„È*[l”‚0ÿ7º$ëF;÷áÓŸ^tÈOb@¿ ŸÏý@?ŸË ŸÏm ´ê󀥞0MqC÷†þ®A[»—¯å»lù.B–ï8ßÊ–¹ÊÀÎ*ÙÅ7?lä(#£7.ª…ûwotâ®qdÓ±.žK?ì*3à$+úÁ¿×Å}EüCKëõmëÓb7ý´!®‹Æ?¿{_|9@`‘ 6¾M*=ì' ãßVÐWLÌú“¾¯9S˜Hi0[ÔÏžê)òtµ8”>>ö`ño¨ÿÛKkµ¼­yWøÖ—³L@u¹+÷Èé 5ƒŠu@vL‘2»ÉÃ%å­›Ž7·ˆ7o /Â…„o-ÊþÃ!ú@HËÈ®ÂUÄâ-Úzá7îI“leBíÓºÜ.=‰oi…§:h`”ÒóѼe–j§ñ42 µqïâ+˜¨ÜEv_m¼íÄQ‡7nî}?¸·Æ»ï¸ âi០⮑d+Ó¥÷-¡®"M²¡ï} ÷êôÞ9šÒëâÝW¸à-24©všzWm—å> [¤ÅH”Š­Ø«zÝtö ¦ñ©;ÔA]îrëÕ|µDù%?)‡êµÜz Z"­R¸G»”Ý+éÊvº0j°Qêä­iµ„É«Ã{I,Ö¥ˆù¸Õþ—¤Ö/@mÍîaµxõj–G™$¸qÑ›²öF'îI¶3!ã¡Øì¼h¨¯ÄAÓ¬¨;Gç0}(o‘¤IuÑ„i1 ¥×ÐÐa_,šQ@V)@¤” n>Ï:§qÖx\5 òØÖ«ƒ×Ü÷•Hš•ýéýJoœE žhã8®rŸÑ5ppá§ñ?Ä?dÄ?lˆ¨µzzÅ5Æ œF»AÄ®¨kÔ:ڽ싺ÌËu¹i}L!„Úhb¬ïçÿúlÚæ§“øÇ²Ø÷°Ì좚}_Vè¯ÞSµïkTVOZ­KJVÛ¥°Îb]|+טa¹Ym—=0Ó/Öo¢¢fâëqC}ö­¨W‹ßÉBƒ|Y>‰Pm$t¹ uSH븡’Zæ(y~N3ÒOrŽ»]µ‡Lxýd¹G|˜,m=—L¿}+÷ßÊ}U÷î/àš.Ê¦ã„Æ<56Z¦È¸%1îc¯\ Ò|•.ºmõKþ´Z[ d;Ái=H# 9Ë‹|¿Õìÿ‚úÜÙ|5Ž«õò÷å u¥ÑÏ«ý³$J7M³ýs±]ý—”T.Ð…¨ŽûEÙãÞ ¼ZmŸsü·º1à!$`8œH1ô{Ý$“¸/¡B6i0zøá9:G™~Z=÷¥¤¹Ð\’äÞ¡êq ­!Å€„ÓI8û{µ%AùáeUk!8•\W?€‹\+ìŒP ý„z‹Â¥¦¨oJAP®Í/8¡ÜŒ‰Ú¦Ï.<¦’>yìqÇåSxbÁÉ}ŽÑ§s>fA×®8¼Ô¦Š .nV£ËøË?zÿ¦qÿ9£¼šé&—èmP˜`¡úbŠù3 ¯¸ †‡N©¾¤Õ‹º´NY€tƒxÒ§c“½’‡ÐKÏãð Þj;q¨|·>>¯” BÒàÕÆÜ˜^ò«Oƒ4±ÄL^@”©÷+‹úíl?’x)VÛ¼„Wq¾­jôš0eç°¯ŽßPf^ªŠ‘£à>îãà> n @·Ø+ð©@cù¿½›á ÷RÔ=˜p!ï$ü2¦KÀ<¼Sƒ¯-‹®-Mj»¶Ô­É~§Ó ºI$“<¡w(2W{Va‹W˜Æ¢+üR ®mŽ›1Õ~ilLÀ¿ð᎓Q†Èïuµ #¿Œ>ÇèT¨ãQîÏ>ש CS=K¥ƒ‚ú$¨Aš†ë?’oæ3¾À¯¿ØèuWlÊõzU|:ÿ«Ï[Ø ™¾zŸøˆ¿ÿLàìàhÇ£ųÛd÷°‘Ÿ_üy9Šo!G"ù~ñù<˜1Љu™’ìeY/¾-BÁ‡q:ø2ÐÑIºÿ×m³¼èûÅz«…]ÃU™ /ò(\ÎîRõPÉë—âSÿï?ûEYw(4=½Ž>åÿ™Gqj,7'‡Š¥G%0 ƒ“QºãŸ» @wø³‹ìZÈ4\þÓîBÉQxëý r>ÿõGÿÓßç'Þ„’#”Ö;"û ràÁÀ’:>Pì1‰õéP=òíª>Àµ%ŽÒ r¥“1‹@²¯ ”Ë?B9’4BÒÿÐ)¨ÁÄPÖY ÌZ™À¨±]tcº°±\˜ºæç•Ÿ %?¤F£ç\LJԳŚNu·•x ¼.ì'oËÔgø[…f:«­‘^­ûÔ{P­iã²àD€Ãröåb½66‡v»5]'P3ÌíSŸ‡ hŸZ-ïèéíq êä¡öÑkïÇ å@êŒçzYì¬×Œö‰8ÆžíÊíxÍ{0¨Ú/·Kİ{߯ž_¤žHGqØÏ3ÔB†Ñ™å7“žÕ¶> Üðoš!Þ}ä=Àá¶4¢Yóî tðXŽá©ã@è®·-¿åÕŽ”µ¶+—ßú‚û¬ùZò •]»Fï7˜¢5Þ òÁ(àðØyH£{ð«xÆ •¼â¸>´ö~— ¹óÛDþ¡lªåq]v¡€A‡;:5ñÿуM$¿DiÜcç†.¿‘%Mן˜x(»28õlY¢ç瀋m)(¼OÃû€U¢ò³«Ö«Å{W8„Ч ¢´ð¢+(A¸+\Õ{sOˆ[ÙE‹ÈסM!´8`Æe¿ª_Ñ…\Õêòñku4vò©‰ª"þ}æÏ(zðcµ]­X,ªãöУ>gËJÄS›Ôa¼_–UŸ8ó!'¨ŽPß½GЯ5*û=^ÕzôÍ÷ìÞoÙ'‘ÿqP?’çÚ³’É Fa1gMç>·–jëƒÖ÷Ip,Ôgô+ÖÎ]j¹ýïõª§²In¾æƒ,•÷,c-n.-¬9~ªÚÐöPD=EQ âä ¸ÈäæÒÂ:§Ê¡MEÔ³E»XQ˜ ÒÔÇȱ`3S•?wÝéòøëÜE vN+ŽåÀµ_çT«Á×r`ȱÉG“Ànw ìvº$ˆ>\´óaf±dF ù|ðe#:*¡`Òx¼{c*˜Ð3˜ <]y.ì<ϾøÑ'‰l<È$ñƒ'¡L¼Â1qq£Èög«Ü¾“}Æâã齋Ûtª.Wð³ã~6]CBå=Ü Á &›‘êSw®O.2áv¡Î:&Zlê@2ÔÇï¡Á$Õ¸§‚ç Æ‚™ Ó‘`â<ÛãzF0½UdHãûÅy·2 ÎmEZ05<èò„s ü›ðI²Œ]÷«¢ÜuäHóYÏ­\™sâ’ÕéžãÒc¹é¢S·¯ÛêÇ6ŒånŠwV h2Ã66±™Çj éý>&ñŸä£Ô¥ß¤ è ƒøO0(¶ÛêÐ#ãx"­‡½þWšTƒ©AqfŸ¯ÇYZfuÝS¸<¸ª^W¥[èâÔ¥£žJ<ܠ̵ IõQÔð~ü¯7Ã/¿õ.ép ‹~BýÕ—-ê³’e¼&Å…àÓ‰Knëa[ƒ«-‘ c_ªEµ&û6 ׯ¡ |Zî‘îÅ.þÒtgö^7o¹ù‰°\H‚†•Ð,ç¼\³T<‚?ÏàæF@Px3ü±NûÀpÂÀ ’ñšº3‹ÇhxPЯ“ϼaøðìy_ly±X° »xü±.÷¿Ã'›ç ÅÎ}ê|?`8ƒþ>Tdd—–œ=×u±[áåºèæäÅá°7Ö–Äà¿û4¦cú i³Z‘ è“€Ñì¾7 ØCDÉ:niº /ði•8¬II`Ÿ^¥i4õ6%ÌÕ¯êM/žAx‡ñœôšÀf9OkYÁýÿÉVD\£tUú ~ïWîùÛÙËá°3–Kl`*¯³lžÂÀîÏw¾&Œ ¡r¾ÏãÅòP4x÷Ù€ñýÀËEÑc²4 kŸðäOPÙTÌÒz±_?ýóüüŸŸ~;–†¯ž`¼Vª–WÏø­Žéýxª =ø¹Á ¢àõÆßtõÙëE½;Vë_?ýæS10w"ÿDþüï3¨=.þY,Ö¿^üÖVÁÕ ~¢ç}Ý¿èq”3ê~"ä¤ðä´ý!\«oæÈËíò#y`.Þy«§w ¡;Ì›“·Í\ŒžS+d˜©*–%z—V”cÖ·°|\.) ÎßzUl„y?§í†ÊœŸWá–B–-7LË‘ú&üË õ ZQ¿ vÀð#ï#æ´ÝDíƒs)ܾxz?JfÓI<ÍT~ò°~ -Åê›9>.{çìmUþ°Ð}ä-¤Œ¶›(1~x>… Ùµ<‡M’vf½qb$û¸¬R@œÉÁl2‰¦ÃT%mÙáðúv®Ëcƒ‰³)½5þ€V ³Ð4ó|`.)"Î#¬äNFxÊ Eùc1Rß„ÿq¹4œ#úr4²}dƒ mõÀöÁYê¹yA$¶û.±µß4ô;´ñM¸r˾c£Þ¬ßü.ÍY¾ÒˆíÚ~u@7 ‘â¸Ù„ ñ}ðdÁƒ48«b)`ÃÏSpq|_|(êhšGÃáŽ÷ÕHUÎÌÖ°òí6úx—Æ0þá(…cÚØQiñœ’¦ª°¸q-åvót¯å{˜8:ŽlC™ä‡É ÜŠ™s>UûÅ~‰¯AŸz¤¦À%ª©ð ëÛ……žI§sÄCÎÀžŒ@ùpD¡9‘3쫟«ð+%ŸT(2ð³ E†÷pôGrs÷å¶ü†ŠTQq¢Œ~5ä³Utéj4 ÕkG’|vcåA6êûµ…úPå½oªcÊw{§™rˆ®Dª8pæ7T¿†WèøCCUÎÒ1<Ô%ðâ©¶ýMQ\B|@:zé‹ÇoSÅ<ÿ„‰ 2i;èß]ô`å¨>^To¥ù«ýc€iB`.qÈ~a8˜™…wKíׄ\ó¿`F×gdnVç–†ý›üÿ€êú-ŠqhO¯e®ŒùqI´/ÇfÊàë ÒŸgʘÛogÂçrÿ>»{¥}m"/¦€ÄFñe9¡½˜O½WÞ£SÙ¿þ îûïÌ“bÑ_ýÿé±?Ö{]¬x$6ð¶“È>‰¼!¿ðX9F¥û9¶Q6ú…ü·¡Û ËŒ\ߨ‘o ÷oÊ`?„fMÒ™eu“¶³ˆe}“ˆÍv1,yÂûzÝqp¤Èx%º×ðÿÙ+\M/p¤xø!‰²å–q¥(äà¿Ò¾ÚyŽ~€+ÃA¨üO0 ÁŽÍˆÝs"Aa}†Sþ>êÜÒQ˜…,¥XPì…QõÈ÷§”}[ÁÉŒæÑõ¶ê“Ê;­zä7‡µ6HÆ+ÊŸdzÜçÁTGŠ)PÞÿ/¢E™/ämÊ~]’ï]Y|ÅÿF‹þч o/‹Ìµ×·­D-^CD£ætùÌ•¯ÛADe±xéQ?¨ å2 €-Ò%+b´œ®«ç$ä-`¡_ ýyõ}Ÿž>Ù'g\Ú›–#,Ñ[B:Ä’c’%Êa |fo²C`×d£›â€—í’ÝXûlŸRÏfRòåuœ38Ö<2Ô(ºFÝèxz£¶^:ŸMÓ¦mÖîJuñÆ'^ïˆ2¢…µ,Qã4¤Y"ókf•“´K:r&q4žØ9™™rî ø‡ðÌÂ\ÆÆItŸá © Òb8,”å¸P‘+˜Â€,~½·úŸ•ðB~×~§€uèÝJõ»• w«Ípªg82 2Ý`¶¿¬Ð«uå¶‹ çžÌÁlšÅ_³|8ËSè­MÊlq2«€Â'(ÈF7;8˜ŸQ—y½I¼æ W ]U\¡~r‚º’ùx6ˆÆ0r–ØœÛÕ=Á7@(ñòn¨“G¸ÄîËM…þû¡I<™¡ÿ¯fÙ(‚kj ¹)Zž~ö‹ý¦Û5¿üšGÉÄvµ™U!\=¡êb]¾ÁD8G—¨.Ç÷Ñ43Ó *3ùÌ¢O¶5…¹±¢S)‡ïñFèu{'£ËÌ{E–ònòTDÁXꪮÞ=ŒaÒôN˜ï±ØZè ãöÃYXDv˜F‡'é毀Ë,BsS´TõSüÃгô2^\¢Qa«ËºØt"Kã4šX¸ˆM¥Z=oɉèFWÓl4¸‰-½±«´a/D~Œ‚ø2ÄÇ(Ȱ?VÛóWÔ%íTTFÓó›|n«&¹Yæ -âŒYFMš‘0ôrð@„[Ë·ªZ—Å6Ÿ†HÈ4`.}rfêb!žªÉpy*CÆûgÁòó¯L¼—7Ä vP‹·-4 n ”‚žBOcdhšHa›ÍpY ÌR)2ž¨ñŸoÜéhe“ãôÍ/Ž\{Ö4lN«–›Á8E£ç]”Ž@”ÐùQˆ" ß#?œG:ÕOaâ§û1®Ðþ‚©« õà‹Í€êp(/jHºŒùA yÄO²,pÎO0?1HBÇG5È ^U‡bÕXÍÐÞw‡ª¿ªÞ !*GQ .K–ÀɶX¬& )ól–“ý®`ñTz7Qʇî 3ã×s7VxûZÁ¨³•›Ýá½#]<™gV>lÕ _ÊbYî;2^ÇÑ0N¬”ĬsîŠ%ìÐØ‘t ‡£é•••ÚuZh1ö«íºëõ…6a>›Žíט{Èá«ÿ®Å7Í’8²^bÖ9{8V¢ëÍÍ’h4vÜ]jiƒßé<ÊPoõ÷oå¾.žv‰š'å*èµðø%NÒè]¦xp—Ä#å%¡™ ghc_kè7üe¹Fã 0!Ãá$ H¶"ýyñ¯Á¢­žLõ¿"ÃÙ$Mó¯(ÖgÍ“8•»Ø& ïÐÐ+/Iíê°Ä–¬{Ú¿¢‰,µÚéoiÕØÐÁ‚·.TpP¡‘†8ªåàJÁizÎÅӪʠ—Ä·xQî<ÒfËlN\RyD´Å×.-pu¼K[%ßæhUÔõÖ¹ì¸Û×.í广û±ìïö›Ý‰7rp}•φù7‚ùQ9+úQ[ܽD¡-Ô÷Ò{™Šp‘lÓñê°ÉY’º¢D’U62|Ñ• PØ9‰]¤Å÷¶ÃмPbL£ôºY#­¨¯ -uL¿ÚÃs‹JšÅóür]á\ަw¦ü[<™¨Ã§?û›âg€ìÓŸù$úªÑT xµ MMÀ£©t»P€r‡P Gû|žÿÏç¦ü“T 84ÿ¡çŸ¤ŠÀaùomRW À£#F"M1¿‡c~7`ÒµÓ°þ-¯|—±ÊwŽ<ÜÃbTDa‡~¤UnûPðÑŽSá¹A¢7ÀrÀc]<ÃzÜþêRÝÄwitëióQ&×9ŠM§B·•.: ²¡Ñ„,.Êõ™+‡Ÿ.gÓ9çGÎ'¦œÃ K¹„“Ó;2ÂJ<œGÙµ•¸qQùù§x\·‹ü¡SM2‹ÉÇ$á;]ÞÚùÞã/4èêUÇ­WÝZNSÑʯ1“aîS.Á<'+<]ù}lØø)"н†i¯ÔKRŸ\(SB™º eèG42ì­ƒòÖLµ+ÈKݦ1ð>$©‹¾ñR„¯7æÀ†õÆŠM¡‚œ6_.Ö«rÛé>C>š¯ýãQ<µÜm“§STX'Ç£vwìnŠ<¯À&%àD`ffV!|õ^‡Í ȸ—¨o‘ªÓfØ\ŸŒ«NòiV3áwt˻ָlªÝI{•«8©*N¹âî‹m¾ÎÏu Oà(:p^¥ižÍnP¿ÃR¼ ó=zËŠ»çS<$è]Šú@ñ•[Gãç’³Û¯ÞNV3OF÷bÀMѲ*`3Œ“ Ã(º‰“/-eBqRT°N_ðqŽ‹ûájX$nñQ% «ÀÖv}÷£_xtÃýöW½ Bètz×Úð”·«A¦8Tà¢yâå€"×~9D/ƒ¼–褫W µ\ŒÆG‘€ÚG¨¥Äê¢5|Pè2‰Ó멺|Çæ¤«xúÙ''vu”pù5Ìf7£ØÊÏ=tòê°ã{iu£Ÿes¶[–U€à£KØ‘ b^v@ŽËo¾Z鹇N^ÿq„%\“)cؼ㽣Œô;X¬õ7™1F5’²D±Å·]Ú)7I%tß.£·A`±Ý]Ÿd Œ&bcÚþD›}Û¤öÅâuµüqY nFCOyÔÛ,°Ã&*“q뛓¢¢Þ¡VBîtŽ^ûfFlRy‚†qŒ:˜ˆØÃ³Ü«¯Q%öù2W]I]wøÔ-U¿cnsnSúmµOÿƺÅ×(í;*<õšÝâÁÀöË%ú9äœx‘KëõÜlZN;ä,-ƒ‡ºŸKΉBÚ%PrºK9épYnWaý‡y”¦Ã< ÐÝÆÓ‘Úw08(Ìð‘aàâPŽŠò¡/Õ¬2á7TôÞÊ}¶Ü~A…é>NRu¡ŸÁ.Ó¾Àöºóy [éZóÉ­2!û:ÏoËrÙéβ/¾ñ,ï4އ–lð“ålŠ5ì*ØIÄ$_Î’‰…š[eºz:t½àéì2³_pnUø!êBw‡3±QªC‡O_¦/Oy*E~Û}Cþ2J Pk64²8]¨sQž?8 rcn8·Õ6”i:›êøØ è %Âr?–ªƒÌ|Âc ÀÎÇRu00w{,9°í±TŒÌß»³Þºo lá%4=–¢ÑÂÖé±qm¥ÁG–Ðù±dÇc)› 禀µ™ïM ½.q E{¥óTôkîÐÏ›6¯ø½ËâõÏ›L”º~ýJ†È$`nabSÜb6 í™ÂfF6ZÍa;Ä)j¿ÊeÂâ#J(÷HC] JB%Ä ÂOã†Å Aóá6õ‰a’¶^ƒ‹™¿3±‹‘Suä±’è õæ°ëoÃöQB@é$›çSu%ÑÐ0ìßú/A#º“Üç×ÊÐm“,a¯¶]ÀGS3:¤Kð?;iÿjÿUT -¸wzA½ æqûº­~l1§7ÓÙÃTÃ%ÉûG¹^w@ˆÇc#>7pü…yÇ¿·–zÙJ«Å¡ Z¦Ž¤Ú§´Ÿ˜>!>€)£"xé/‚@QÚêß&™ƒ“ýâa_þr¿§<‰@ä ˜!“O£áíDomìoêì²¾_};Êšì£ã_àæÑöKOF_î²8EUÆåL*r{CKm-ÖÅjS’’åWè¿h4I5JɪvÈ#4æO° Tûr û¦ëN×Ö PÔ·°\TÕ¡a¾dî@Ü|læUì"íÛjQv»™Ãø~4ˆm7S²j„òˆ-ù㶆 oÛÜa+$ÄÛ-÷AÒ¬ áºzîvûƳ+ÛkL ¬ ЧcÞ`¹GzŸØ³§:4Ìtr;hdéÔ´2*+YZ¯wÌ]'÷±#sŠ]  ©¸J=½hpè*ªŽòÉê(»|ÅÞÐw¨e³íTmÝͧùpj©²D#c#%?ÕŸC?ÿ¤»¯D—égý»OÕ(³…žæÀÐôC$‹LRw»m/µÝ5Õ¬rvYÛÔ š—5ì-,1®QßsUï,ƒZòÖ2§¨o9ŠÈ×”JãÞê¥ Á™úPlvÝ4ÀøKšE“¹ž;hÌÇíêgè~ñðÝtôUß.Þä 2ÃwøLT¶ö¥ ?|B;¥ËX,*T7Y ç ®5„½ Õ†bµžŸÂxî¦<—8agéÀ½F("ì­m7¢Ødª«žq jTÙBgJ<}žT±©Txé|&X o!“ÄÛ?í« Þ•oº£$†oè/“Ùo¾7Ô÷–´»IZ§X(ª6Ë"¤KðáÛS$Ófã²Iæ9ìN©i`U¨³Ž‘4æÝjÛ'g¿u£ž¦€îàn<4òð嘮iý¥n–8¡)~l…ö–éÔ Ý¬qvΧзqóù~~ƒ¼1d¥-lÕzyc>¬à`dþÞõÖÅxka;)Ÿ·mù¼5ä3|q75­ëV2ÛŽ=‡ùƒµß@MϾ\¾‡þj‰ ,WëÐâHâáu”å£!*°.ÍØîМL*`±QزI–©+& ¹0:H{‰ZÊh´b“¨ä…ðÁ|Òjv©ä 3KËÈ;Üey5¸ñ+.þÓØ[¹5fT¾VûrqèFŒÊÎ(‰™—Ù ´tYüyWb²ÜÝ~¹;ùIÔmÄ2mèq- P?¬E²È$‹ý’¶Ô_4È â”E·~ ²ÀÚýÓœ$lÉt07] mb¤&‰Ÿ—¶+ä˜%¼V2˜Ÿ†6äछû©1¿º~p…éÈ é°Š]…— -ÞúOÛ0`¼sñ–?môÆ@)ö%>ü9”a_â§5‚&ãÃ9t•‰¦â³t†¿‚Ïú« ª&¼7 P(2ç‘ d©ü× Hd €d! Ž£ è8]„¯ËCG i¥á6;Uw>Ãd©ÁÁÌ oiß5ŒÐÀÉN\$~ïTE@dâAÉ"6?{#Ûð ±d¯e€_à¶ëò)°kÂW!ÁæøQƒ¤ñ¥ÖA±ºÙ´ ¹NQÓ¬ÔjÑÓ8Ú­ž·°MsÀ“d¡]MgIL÷nQ%ºÚtO¤ç.»ü«E¸¨üÁë!X¤åáæ&•å²>¹@ l¤ÅAu3k9¹(‚ ;šAç|:YÑt–ãKE¢£UѨñRâPA÷ð?Y ݹßC䩊êò¸˜Ÿù¸%^®êݺxï”Õ»)ÉÂp”ÎÇÑ£%›Š—MÈI÷Ÿq´”Õͦ¥~©‚vÙÐÒ뙲džŇKx ã»WÁïRµ Û™D(¥’$@z2ðàᩇY2Ì£«HÙÔÔíÚ¢ëtE^Zt'*hew0ÓÓ;“ Ðí¼Ä®Ó2S#“§‹ø¨ƒü´èPŠË}Žâ Ä@)»ýZ¿éÌÿX†7k~, šH`÷ÁÇîõãN÷Âq§¤bý¶/¶‹™ ŽÅeþ%‰¦ƒku”Çb5+#\¼áù­XÂÿðvçà^ÿ%Âÿð!¶B«;(Ìõëj×áûpŽœÞŒæÆ/ÄŒœ¤…¾ÉøÈ˜þö’MŒ‡¿³ƒJ ÓKŸÎða8Î6ì°:6î®YUư¦Na *…<Þ‰ AäÂB,ù˜4ò@•ÝnVNaLz'xî¾ÖOQïk<ŽL€+EÈéÛ.íP½–%.›ÝÄþò°·]à øuš´iü5C¿ZEQ?»œºDíÇâP~À½LcÔHŒ²ØëfŠÎFuÕ~SúÅz÷Rl›r´ë£Â8K&Q–Gãùu4½›Ä‰²d«·Cà²\¬6A““F¶a<M”™J—£CÑKù³ø U×ñ×È[™àlR‡ÈÐã’嚉C8j/î£j ëN¬D Jk=ªºYÄGTUxʯ4ªŽÛC]ýèt÷èrò᪈쭆WÍî¦Y>ž=Xn¦WlHVžV[Ta'ŽÎÊåhŠÚYòØ!+<6$+p4BÐçß~ZƳÁòMxH %+ü Ðáý¤2Î@ÜEœy©Jðb.hÇv}×á[ð½ý5'ºXù;tq Æž®ÃÏ.‡Ü¡ÓÄàrÑ*{‰Bê•^mªâjV¡¡ªjyÜLÜГ¤H¼W«ÿÕMW¥  iÓßë¬IcçÔÅ2|’OîÒ VÑUè(m¨ð} x ºY/® §Ca¼I€îÒðãõˆ´¨ûak·/ ˆ†°æN]¸¥› çaÑG­Ôi?Gù†CÆü³AލW~޲“ÝÈ%\5*lÐ\iÍ¡k¬-°Ö¬ !yKt`ÃÕ¹™ ›Œ<¨M·8tfËQÓl98‰ƒÂ¼B½ƒ°"ÃAG¨¯Õ¨°½úOËp70âgfÂ&…v€Õ ÕvÝ)k°‡ì®0›Ž-ù=rüPVü™›Œ< †tÁ3o«àí×38^×°åºÎ᫪D×UXFfsT/Žg©VB¸3ÔÇÝ®ÚC%Ëbà}JïæóYÕ/.uÚÍRí”FÂåÁ"1mß–¨ Öa‡ß2”ÌØ—fÿ ùÀœÁW^WƒïÔŒ¿[@ñ°SózõMŽüv\­—¿“O€ªý{^íŸÍÈ{Y>Çõ¡{HþÑû·ûTò]µ^-VeÝéBŸ#ô)"[Šu fƒPÁ­ªÐì6øC‹'ôBoÀòÝúø¼Úʘ$ žMîGU±Ÿ}6†„¤TûÕñ6O KïWîÿ0¾VǃI<51½ÑOuôh2Š|FTÏmÙ^.”›LÂþñèÚÊ X/𥠬žYfQ\_ŽCšœß³õ¾Ow~ÀËtËÙíjSÔ¯~•Þ8Ééöxímœ‘ ­&QzÃrãpáü‡™!{ ùb0äìÆ_ÈBâ†Í~¶A`èúæpÝð›ÙtQÉ7âU¥aý&lBRzM j§W½›rÿ­D {£>ƒ³ËéÙи»öÇŸD_a2‹¾®ê¸™´7˜Î6«ÃÍ…Tµ,«@KŒÐ›Œ²F'3„§²8÷¥ŽÀ f"¨>)·u©ÐtCü˜F@sæ|¡t¢× sM©g.‰-K¯r–d)S*Š˜­W)[2ˆ˜1صj F\ó¾wªe BŸ"ô9"«wOå Õ§?•jö½Ï ôfVËãºì ålS—¨‰¶Úóš¤ñ Ž’/ÍDðÞŠu@Å„ÃTI‰gÕ·C²ºÛ†·>ôÍ7ÏZ³Wè™÷føOxèÉ(GÝCí —ž;«v¨õ®è²Ø™®?(ÿV°b‚œQe×Çγ]¹Ç%jÞá¥ì‡Ñ¼ÇÎèöç¤:B%ÒÔÜМX¾gÄÐCU·U‡]è{ …üâØ—}¦xd¦ÙƒmF¨ß,›÷æäo˜[]‡–élJXZþÜA‡Úüv³78@¿˜³´O;£GŠì^ö|“².7þ£E$6'±9eWÄh<ƒãã}ê«!ùÝ#þ¨rèÝÁÖWëÕ+º½ïõ¡D¯2¹jº,İÈÔ(¿½ôËÚWžxï¥ø‹Ýw(ù”Œ›Äš´®è{Ó«±B"ú4bNZgRŸ(ùá»Å¢.aQœø†Ñ­¤jð D{x5n•ö‹ùMdAÝB^Îuj%,ì ÄÕ”ðÒÞ¶d‘×Z|¨t2f¦yÂû¯övê3%±°‘æ¹Ü¢šfm&¡FBqE=is݉E¹CïSÁ½®‹ÝÊ…m)M£ù¨·)aÇ¡U½óM Ü\2ãq3¼†­ôc1ÓÜOÌtóÓp…WØ%zwRéCåºBUs-!²­í2+1_px.¾­ËF«ˆ oâ‹Ü~÷;Á%on{küÓX^ªêÕÅvÂr '=ì¯aCª„½\š™)òpУî"2sR]Fc ]E ÒÈ]TEîLôeˆCi‡?ÐfqŠ»A¸ëkÂ=”"èn_AåmF¥FZcˆ5©J½$Ôß¶Nl´Î£ ‘zD^ ,öc¨á4î?g®ñ ¹A…Þ‚Ô—½ç0 Ú:¸S޵½ul¼¾ÏœJa¶Š©¡£KvN¢Bi ô·Hz¡TÔ)ÌŠø7ús{Ü Ï™{ôH»cÜßPax.}©÷-Á-ãAâÓð ýÁÆ‚<‰#¨y#Q±fŽÌÈcòÞÁ9ÚáÂ[.órk^=ì«#zŸÔ¨">p¢]Ÿõ!¨/ÁÔ‡b"aê¸._Ë÷ºóH­P©Ô4Jh1à„¶{ÝTR¿¿Ùöª²šÎmK¯wþŽÞ[¹óK>ùÊQcŸ™¥>ç¨ ¯¿7ND$ýØL"Ÿ‘ëG ®CIØP8 ;86@@¤±Јްx Ž6áÂI*ÅzÝ̻Р<Š£bÐ>‡#üî‘Q2Ò¢ŽðF¯U]÷ yPŠ'’»‘°Ÿà}¨öe{–æËãÆ£7NCÈ6§8dˆþÞº¨:-–øoa€‰õÍ¡’ßøàÒ6ÿV ¶óòwёݣ„¦õ†qz†÷ßâÅS´% ì²G;£ËƯšOIM6j[udšÎ¬DÜtV““"|¦V¨+A£?'ýë¬.‹ýBr i¬Ý„ís8íÎfF”ɼéíîM¹]àn>%%axUi–’Ô.à,õ ¶•A] Ëè~ëÓT“<Þ?ÃŒ™`°_^Ø6Ì0ŒR“s¿EêLEÐ!÷¿zô¯3\Ýóš/‹rS™ÛmÚ#£è¼,‰JñkƱ„ç…˜èøªG6Åþžn`­_ZjLâƒßÁ¼ÖÄi})%ôÀéŒLOæ”&g•‰WvÈ' í³Ð'ÃcÚ¡fj©Ã˾Ä_Ÿm`mŸß•]'1þrlë÷ØÍ–SÏ`MÐÓú¹_l«íû¦:zÎIÃÒžËñUMgÓÇÉìŽ/áÓ œv`ßþËàì¬>ÄÅpº…“ êýG±_B‡8Œår– Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/.buildinfo0000664000175000017500000000034615051422714016033 0ustar ghudsonghudson# Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: 62c817db4dbe5853c22bc095f98b965a tags: 645f666f9bcd5a90fca523b33c5a78b7 krb5-1.22.1/doc/html/_sources/0000775000175000017500000000000015051422713015675 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/user/0000775000175000017500000000000015051422714016654 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/user/index.rst.txt0000664000175000017500000000020715051422642021332 0ustar ghudsonghudsonFor users ========= .. toctree:: :maxdepth: 2 pwd_mgmt.rst tkt_mgmt.rst user_config/index.rst user_commands/index.rst krb5-1.22.1/doc/html/_sources/user/user_config/0000775000175000017500000000000015051422714021157 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/user/user_config/k5identity.rst.txt0000664000175000017500000000414315051422642024622 0ustar ghudsonghudson.. _.k5identity(5): .k5identity =========== DESCRIPTION ----------- The .k5identity file, which resides in a user's home directory, contains a list of rules for selecting a client principals based on the server being accessed. These rules are used to choose a credential cache within the cache collection when possible. Blank lines and lines beginning with ``#`` are ignored. Each line has the form: *principal* *field*\=\ *value* ... If the server principal meets all of the field constraints, then principal is chosen as the client principal. The following fields are recognized: **realm** If the realm of the server principal is known, it is matched against *value*, which may be a pattern using shell wildcards. For host-based server principals, the realm will generally only be known if there is a :ref:`domain_realm` section in :ref:`krb5.conf(5)` with a mapping for the hostname. **service** If the server principal is a host-based principal, its service component is matched against *value*, which may be a pattern using shell wildcards. **host** If the server principal is a host-based principal, its hostname component is converted to lower case and matched against *value*, which may be a pattern using shell wildcards. If the server principal matches the constraints of multiple lines in the .k5identity file, the principal from the first matching line is used. If no line matches, credentials will be selected some other way, such as the realm heuristic or the current primary cache. EXAMPLE ------- The following example .k5identity file selects the client principal ``alice@KRBTEST.COM`` if the server principal is within that realm, the principal ``alice/root@EXAMPLE.COM`` if the server host is within a servers subdomain, and the principal ``alice/mail@EXAMPLE.COM`` when accessing the IMAP service on ``mail.example.com``:: alice@KRBTEST.COM realm=KRBTEST.COM alice/root@EXAMPLE.COM host=*.servers.example.com alice/mail@EXAMPLE.COM host=mail.example.com service=imap SEE ALSO -------- kerberos(1), :ref:`krb5.conf(5)` krb5-1.22.1/doc/html/_sources/user/user_config/index.rst.txt0000664000175000017500000000045515051422642023642 0ustar ghudsonghudsonUser config files ================= The following files in your home directory can be used to control the behavior of Kerberos as it applies to your account (unless they have been disabled by your host's configuration): .. toctree:: :maxdepth: 1 kerberos.rst k5login.rst k5identity.rst krb5-1.22.1/doc/html/_sources/user/user_config/kerberos.rst.txt0000664000175000017500000001600515051422642024345 0ustar ghudsonghudson.. _kerberos(7): kerberos ======== DESCRIPTION ----------- The Kerberos system authenticates individual users in a network environment. After authenticating yourself to Kerberos, you can use Kerberos-enabled programs without having to present passwords or certificates to those programs. If you receive the following response from :ref:`kinit(1)`: kinit: Client not found in Kerberos database while getting initial credentials you haven't been registered as a Kerberos user. See your system administrator. A Kerberos name usually contains three parts. The first is the **primary**, which is usually a user's or service's name. The second is the **instance**, which in the case of a user is usually null. Some users may have privileged instances, however, such as ``root`` or ``admin``. In the case of a service, the instance is the fully qualified name of the machine on which it runs; i.e. there can be an ssh service running on the machine ABC (ssh/ABC@REALM), which is different from the ssh service running on the machine XYZ (ssh/XYZ@REALM). The third part of a Kerberos name is the **realm**. The realm corresponds to the Kerberos service providing authentication for the principal. Realms are conventionally all-uppercase, and often match the end of hostnames in the realm (for instance, host01.example.com might be in realm EXAMPLE.COM). When writing a Kerberos name, the principal name is separated from the instance (if not null) by a slash, and the realm (if not the local realm) follows, preceded by an "@" sign. The following are examples of valid Kerberos names:: david jennifer/admin joeuser@BLEEP.COM cbrown/root@FUBAR.ORG When you authenticate yourself with Kerberos you get an initial Kerberos **ticket**. (A Kerberos ticket is an encrypted protocol message that provides authentication.) Kerberos uses this ticket for network utilities such as ssh. The ticket transactions are done transparently, so you don't have to worry about their management. Note, however, that tickets expire. Administrators may configure more privileged tickets, such as those with service or instance of ``root`` or ``admin``, to expire in a few minutes, while tickets that carry more ordinary privileges may be good for several hours or a day. If your login session extends beyond the time limit, you will have to re-authenticate yourself to Kerberos to get new tickets using the :ref:`kinit(1)` command. Some tickets are **renewable** beyond their initial lifetime. This means that ``kinit -R`` can extend their lifetime without requiring you to re-authenticate. If you wish to delete your local tickets, use the :ref:`kdestroy(1)` command. Kerberos tickets can be forwarded. In order to forward tickets, you must request **forwardable** tickets when you kinit. Once you have forwardable tickets, most Kerberos programs have a command line option to forward them to the remote host. This can be useful for, e.g., running kinit on your local machine and then sshing into another to do work. Note that this should not be done on untrusted machines since they will then have your tickets. ENVIRONMENT VARIABLES --------------------- Several environment variables affect the operation of Kerberos-enabled programs. These include: **KRB5CCNAME** Default name for the credentials cache file, in the form *TYPE*:*residual*. The type of the default cache may determine the availability of a cache collection. ``FILE`` is not a collection type; ``KEYRING``, ``DIR``, and ``KCM`` are. If not set, the value of **default_ccache_name** from configuration files (see **KRB5_CONFIG**) will be used. If that is also not set, the default *type* is ``FILE``, and the *residual* is the path /tmp/krb5cc_*uid*, where *uid* is the decimal user ID of the user. **KRB5_KTNAME** Specifies the location of the default keytab file, in the form *TYPE*:*residual*. If no *type* is present, the **FILE** type is assumed and *residual* is the pathname of the keytab file. If unset, |keytab| will be used. **KRB5_CONFIG** Specifies the location of the Kerberos configuration file. The default is |sysconfdir|\ ``/krb5.conf``. Multiple filenames can be specified, separated by a colon; all files which are present will be read. **KRB5_KDC_PROFILE** Specifies the location of the KDC configuration file, which contains additional configuration directives for the Key Distribution Center daemon and associated programs. The default is |kdcdir|\ ``/kdc.conf``. **KRB5RCACHENAME** (New in release 1.18) Specifies the location of the default replay cache, in the form *type*:*residual*. The ``file2`` type with a pathname residual specifies a replay cache file in the version-2 format in the specified location. The ``none`` type (residual is ignored) disables the replay cache. The ``dfl`` type (residual is ignored) indicates the default, which uses a file2 replay cache in a temporary directory. The default is ``dfl:``. **KRB5RCACHETYPE** Specifies the type of the default replay cache, if **KRB5RCACHENAME** is unspecified. No residual can be specified, so ``none`` and ``dfl`` are the only useful types. **KRB5RCACHEDIR** Specifies the directory used by the ``dfl`` replay cache type. The default is the value of the **TMPDIR** environment variable, or ``/var/tmp`` if **TMPDIR** is not set. **KRB5_TRACE** Specifies a filename to write trace log output to. Trace logs can help illuminate decisions made internally by the Kerberos libraries. For example, ``env KRB5_TRACE=/dev/stderr kinit`` would send tracing information for :ref:`kinit(1)` to ``/dev/stderr``. The default is not to write trace log output anywhere. **KRB5_CLIENT_KTNAME** Default client keytab file name. If unset, |ckeytab| will be used). **KPROP_PORT** :ref:`kprop(8)` port to use. Defaults to 754. **GSS_MECH_CONFIG** Specifies a filename containing GSSAPI mechanism module configuration. The default is to read |sysconfdir|\ ``/gss/mech`` and files with a ``.conf`` suffix within the directory |sysconfdir|\ ``/gss/mech.d``. Most environment variables are disabled for certain programs, such as login system programs and setuid programs, which are designed to be secure when run within an untrusted process environment. SEE ALSO -------- :ref:`kdestroy(1)`, :ref:`kinit(1)`, :ref:`klist(1)`, :ref:`kswitch(1)`, :ref:`kpasswd(1)`, :ref:`ksu(1)`, :ref:`krb5.conf(5)`, :ref:`kdc.conf(5)`, :ref:`kadmin(1)`, :ref:`kadmind(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)` BUGS ---- AUTHORS ------- | Steve Miller, MIT Project Athena/Digital Equipment Corporation | Clifford Neuman, MIT Project Athena | Greg Hudson, MIT Kerberos Consortium | Robbie Harwood, Red Hat, Inc. HISTORY ------- The MIT Kerberos 5 implementation was developed at MIT, with contributions from many outside parties. It is currently maintained by the MIT Kerberos Consortium. RESTRICTIONS ------------ Copyright 1985, 1986, 1989-1996, 2002, 2011, 2018 Masachusetts Institute of Technology krb5-1.22.1/doc/html/_sources/user/user_config/k5login.rst.txt0000664000175000017500000000345415051422642024105 0ustar ghudsonghudson.. _.k5login(5): .k5login ======== DESCRIPTION ----------- The .k5login file, which resides in a user's home directory, contains a list of the Kerberos principals. Anyone with valid tickets for a principal in the file is allowed host access with the UID of the user in whose home directory the file resides. One common use is to place a .k5login file in root's home directory, thereby granting system administrators remote root access to the host via Kerberos. EXAMPLES -------- Suppose the user ``alice`` had a .k5login file in her home directory containing just the following line:: bob@FOOBAR.ORG This would allow ``bob`` to use Kerberos network applications, such as ssh(1), to access ``alice``'s account, using ``bob``'s Kerberos tickets. In a default configuration (with **k5login_authoritative** set to true in :ref:`krb5.conf(5)`), this .k5login file would not let ``alice`` use those network applications to access her account, since she is not listed! With no .k5login file, or with **k5login_authoritative** set to false, a default rule would permit the principal ``alice`` in the machine's default realm to access the ``alice`` account. Let us further suppose that ``alice`` is a system administrator. Alice and the other system administrators would have their principals in root's .k5login file on each host:: alice@BLEEP.COM joeadmin/root@BLEEP.COM This would allow either system administrator to log in to these hosts using their Kerberos tickets instead of having to type the root password. Note that because ``bob`` retains the Kerberos tickets for his own principal, ``bob@FOOBAR.ORG``, he would not have any of the privileges that require ``alice``'s tickets, such as root access to any of the site's hosts, or the ability to change ``alice``'s password. SEE ALSO -------- kerberos(1) krb5-1.22.1/doc/html/_sources/user/tkt_mgmt.rst.txt0000664000175000017500000003047715051422642022065 0ustar ghudsonghudsonTicket management ================= On many systems, Kerberos is built into the login program, and you get tickets automatically when you log in. Other programs, such as ssh, can forward copies of your tickets to a remote host. Most of these programs also automatically destroy your tickets when they exit. However, MIT recommends that you explicitly destroy your Kerberos tickets when you are through with them, just to be sure. One way to help ensure that this happens is to add the :ref:`kdestroy(1)` command to your .logout file. Additionally, if you are going to be away from your machine and are concerned about an intruder using your permissions, it is safest to either destroy all copies of your tickets, or use a screensaver that locks the screen. Kerberos ticket properties -------------------------- There are various properties that Kerberos tickets can have: If a ticket is **forwardable**, then the KDC can issue a new ticket (with a different network address, if necessary) based on the forwardable ticket. This allows for authentication forwarding without requiring a password to be typed in again. For example, if a user with a forwardable TGT logs into a remote system, the KDC could issue a new TGT for that user with the network address of the remote system, allowing authentication on that host to work as though the user were logged in locally. When the KDC creates a new ticket based on a forwardable ticket, it sets the **forwarded** flag on that new ticket. Any tickets that are created based on a ticket with the forwarded flag set will also have their forwarded flags set. A **proxiable** ticket is similar to a forwardable ticket in that it allows a service to take on the identity of the client. Unlike a forwardable ticket, however, a proxiable ticket is only issued for specific services. In other words, a ticket-granting ticket cannot be issued based on a ticket that is proxiable but not forwardable. A **proxy** ticket is one that was issued based on a proxiable ticket. A **postdated** ticket is issued with the invalid flag set. After the starting time listed on the ticket, it can be presented to the KDC to obtain valid tickets. Ticket-granting tickets with the **postdateable** flag set can be used to obtain postdated service tickets. **Renewable** tickets can be used to obtain new session keys without the user entering their password again. A renewable ticket has two expiration times. The first is the time at which this particular ticket expires. The second is the latest possible expiration time for any ticket issued based on this renewable ticket. A ticket with the **initial flag** set was issued based on the authentication protocol, and not on a ticket-granting ticket. Application servers that wish to ensure that the user's key has been recently presented for verification could specify that this flag must be set to accept the ticket. An **invalid** ticket must be rejected by application servers. Postdated tickets are usually issued with this flag set, and must be validated by the KDC before they can be used. A **preauthenticated** ticket is one that was only issued after the client requesting the ticket had authenticated itself to the KDC. The **hardware authentication** flag is set on a ticket which required the use of hardware for authentication. The hardware is expected to be possessed only by the client which requested the tickets. If a ticket has the **transit policy** checked flag set, then the KDC that issued this ticket implements the transited-realm check policy and checked the transited-realms list on the ticket. The transited-realms list contains a list of all intermediate realms between the realm of the KDC that issued the first ticket and that of the one that issued the current ticket. If this flag is not set, then the application server must check the transited realms itself or else reject the ticket. The **okay as delegate** flag indicates that the server specified in the ticket is suitable as a delegate as determined by the policy of that realm. Some client applications may use this flag to decide whether to forward tickets to a remote host, although many applications do not honor it. An **anonymous** ticket is one in which the named principal is a generic principal for that realm; it does not actually specify the individual that will be using the ticket. This ticket is meant only to securely distribute a session key. .. _obtain_tkt: Obtaining tickets with kinit ---------------------------- If your site has integrated Kerberos V5 with the login system, you will get Kerberos tickets automatically when you log in. Otherwise, you may need to explicitly obtain your Kerberos tickets, using the :ref:`kinit(1)` program. Similarly, if your Kerberos tickets expire, use the kinit program to obtain new ones. To use the kinit program, simply type ``kinit`` and then type your password at the prompt. For example, Jennifer (whose username is ``jennifer``) works for Bleep, Inc. (a fictitious company with the domain name mit.edu and the Kerberos realm ATHENA.MIT.EDU). She would type:: shell% kinit Password for jennifer@ATHENA.MIT.EDU: <-- [Type jennifer's password here.] shell% If you type your password incorrectly, kinit will give you the following error message:: shell% kinit Password for jennifer@ATHENA.MIT.EDU: <-- [Type the wrong password here.] kinit: Password incorrect shell% and you won't get Kerberos tickets. By default, kinit assumes you want tickets for your own username in your default realm. Suppose Jennifer's friend David is visiting, and he wants to borrow a window to check his mail. David needs to get tickets for himself in his own realm, EXAMPLE.COM. He would type:: shell% kinit david@EXAMPLE.COM Password for david@EXAMPLE.COM: <-- [Type david's password here.] shell% David would then have tickets which he could use to log onto his own machine. Note that he typed his password locally on Jennifer's machine, but it never went over the network. Kerberos on the local host performed the authentication to the KDC in the other realm. If you want to be able to forward your tickets to another host, you need to request forwardable tickets. You do this by specifying the **-f** option:: shell% kinit -f Password for jennifer@ATHENA.MIT.EDU: <-- [Type your password here.] shell% Note that kinit does not tell you that it obtained forwardable tickets; you can verify this using the :ref:`klist(1)` command (see :ref:`view_tkt`). Normally, your tickets are good for your system's default ticket lifetime, which is ten hours on many systems. You can specify a different ticket lifetime with the **-l** option. Add the letter **s** to the value for seconds, **m** for minutes, **h** for hours, or **d** for days. For example, to obtain forwardable tickets for ``david@EXAMPLE.COM`` that would be good for three hours, you would type:: shell% kinit -f -l 3h david@EXAMPLE.COM Password for david@EXAMPLE.COM: <-- [Type david's password here.] shell% .. note:: You cannot mix units; specifying a lifetime of 3h30m would result in an error. Note also that most systems specify a maximum ticket lifetime. If you request a longer ticket lifetime, it will be automatically truncated to the maximum lifetime. .. _view_tkt: Viewing tickets with klist -------------------------- The :ref:`klist(1)` command shows your tickets. When you first obtain tickets, you will have only the ticket-granting ticket. The listing would look like this:: shell% klist Ticket cache: /tmp/krb5cc_ttypa Default principal: jennifer@ATHENA.MIT.EDU Valid starting Expires Service principal 06/07/04 19:49:21 06/08/04 05:49:19 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU shell% The ticket cache is the location of your ticket file. In the above example, this file is named ``/tmp/krb5cc_ttypa``. The default principal is your Kerberos principal. The "valid starting" and "expires" fields describe the period of time during which the ticket is valid. The "service principal" describes each ticket. The ticket-granting ticket has a first component ``krbtgt``, and a second component which is the realm name. Now, if ``jennifer`` connected to the machine ``daffodil.mit.edu``, and then typed "klist" again, she would have gotten the following result:: shell% klist Ticket cache: /tmp/krb5cc_ttypa Default principal: jennifer@ATHENA.MIT.EDU Valid starting Expires Service principal 06/07/04 19:49:21 06/08/04 05:49:19 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU 06/07/04 20:22:30 06/08/04 05:49:19 host/daffodil.mit.edu@ATHENA.MIT.EDU shell% Here's what happened: when ``jennifer`` used ssh to connect to the host ``daffodil.mit.edu``, the ssh program presented her ticket-granting ticket to the KDC and requested a host ticket for the host ``daffodil.mit.edu``. The KDC sent the host ticket, which ssh then presented to the host ``daffodil.mit.edu``, and she was allowed to log in without typing her password. Suppose your Kerberos tickets allow you to log into a host in another domain, such as ``trillium.example.com``, which is also in another Kerberos realm, ``EXAMPLE.COM``. If you ssh to this host, you will receive a ticket-granting ticket for the realm ``EXAMPLE.COM``, plus the new host ticket for ``trillium.example.com``. klist will now show:: shell% klist Ticket cache: /tmp/krb5cc_ttypa Default principal: jennifer@ATHENA.MIT.EDU Valid starting Expires Service principal 06/07/04 19:49:21 06/08/04 05:49:19 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU 06/07/04 20:22:30 06/08/04 05:49:19 host/daffodil.mit.edu@ATHENA.MIT.EDU 06/07/04 20:24:18 06/08/04 05:49:19 krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU 06/07/04 20:24:18 06/08/04 05:49:19 host/trillium.example.com@EXAMPLE.COM shell% Depending on your host's and realm's configuration, you may also see a ticket with the service principal ``host/trillium.example.com@``. If so, this means that your host did not know what realm trillium.example.com is in, so it asked the ``ATHENA.MIT.EDU`` KDC for a referral. The next time you connect to ``trillium.example.com``, the odd-looking entry will be used to avoid needing to ask for a referral again. You can use the **-f** option to view the flags that apply to your tickets. The flags are: ===== ========================= F Forwardable f forwarded P Proxiable p proxy D postDateable d postdated R Renewable I Initial i invalid H Hardware authenticated A preAuthenticated T Transit policy checked O Okay as delegate a anonymous ===== ========================= Here is a sample listing. In this example, the user *jennifer* obtained her initial tickets (**I**), which are forwardable (**F**) and postdated (**d**) but not yet validated (**i**):: shell% klist -f Ticket cache: /tmp/krb5cc_320 Default principal: jennifer@ATHENA.MIT.EDU Valid starting Expires Service principal 31/07/05 19:06:25 31/07/05 19:16:25 krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU Flags: FdiI shell% In the following example, the user *david*'s tickets were forwarded (**f**) to this host from another host. The tickets are reforwardable (**F**):: shell% klist -f Ticket cache: /tmp/krb5cc_p11795 Default principal: david@EXAMPLE.COM Valid starting Expires Service principal 07/31/05 11:52:29 07/31/05 21:11:23 krbtgt/EXAMPLE.COM@EXAMPLE.COM Flags: Ff 07/31/05 12:03:48 07/31/05 21:11:23 host/trillium.example.com@EXAMPLE.COM Flags: Ff shell% Destroying tickets with kdestroy -------------------------------- Your Kerberos tickets are proof that you are indeed yourself, and tickets could be stolen if someone gains access to a computer where they are stored. If this happens, the person who has them can masquerade as you until they expire. For this reason, you should destroy your Kerberos tickets when you are away from your computer. Destroying your tickets is easy. Simply type kdestroy:: shell% kdestroy shell% If :ref:`kdestroy(1)` fails to destroy your tickets, it will beep and give an error message. For example, if kdestroy can't find any tickets to destroy, it will give the following message:: shell% kdestroy kdestroy: No credentials cache file found while destroying cache shell% krb5-1.22.1/doc/html/_sources/user/pwd_mgmt.rst.txt0000664000175000017500000001012115051422642022035 0ustar ghudsonghudsonPassword management =================== Your password is the only way Kerberos has of verifying your identity. If someone finds out your password, that person can masquerade as you---send email that comes from you, read, edit, or delete your files, or log into other hosts as you---and no one will be able to tell the difference. For this reason, it is important that you choose a good password, and keep it secret. If you need to give access to your account to someone else, you can do so through Kerberos (see :ref:`grant_access`). You should never tell your password to anyone, including your system administrator, for any reason. You should change your password frequently, particularly any time you think someone may have found out what it is. Changing your password ---------------------- To change your Kerberos password, use the :ref:`kpasswd(1)` command. It will ask you for your old password (to prevent someone else from walking up to your computer when you're not there and changing your password), and then prompt you for the new one twice. (The reason you have to type it twice is to make sure you have typed it correctly.) For example, user ``david`` would do the following:: shell% kpasswd Password for david: <- Type your old password. Enter new password: <- Type your new password. Enter it again: <- Type the new password again. Password changed. shell% If ``david`` typed the incorrect old password, he would get the following message:: shell% kpasswd Password for david: <- Type the incorrect old password. kpasswd: Password incorrect while getting initial ticket shell% If you make a mistake and don't type the new password the same way twice, kpasswd will ask you to try again:: shell% kpasswd Password for david: <- Type the old password. Enter new password: <- Type the new password. Enter it again: <- Type a different new password. kpasswd: Password mismatch while reading password shell% Once you change your password, it takes some time for the change to propagate through the system. Depending on how your system is set up, this might be anywhere from a few minutes to an hour or more. If you need to get new Kerberos tickets shortly after changing your password, try the new password. If the new password doesn't work, try again using the old one. .. _grant_access: Granting access to your account ------------------------------- If you need to give someone access to log into your account, you can do so through Kerberos, without telling the person your password. Simply create a file called :ref:`.k5login(5)` in your home directory. This file should contain the Kerberos principal of each person to whom you wish to give access. Each principal must be on a separate line. Here is a sample .k5login file:: jennifer@ATHENA.MIT.EDU david@EXAMPLE.COM This file would allow the users ``jennifer`` and ``david`` to use your user ID, provided that they had Kerberos tickets in their respective realms. If you will be logging into other hosts across a network, you will want to include your own Kerberos principal in your .k5login file on each of these hosts. Using a .k5login file is much safer than giving out your password, because: * You can take access away any time simply by removing the principal from your .k5login file. * Although the user has full access to your account on one particular host (or set of hosts if your .k5login file is shared, e.g., over NFS), that user does not inherit your network privileges. * Kerberos keeps a log of who obtains tickets, so a system administrator could find out, if necessary, who was capable of using your user ID at a particular time. One common application is to have a .k5login file in root's home directory, giving root access to that machine to the Kerberos principals listed. This allows system administrators to allow users to become root locally, or to log in remotely as root, without their having to give out the root password, and without anyone having to type the root password over the network. Password quality verification ----------------------------- TODO krb5-1.22.1/doc/html/_sources/user/user_commands/0000775000175000017500000000000015051422714021513 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/user/user_commands/ksu.rst.txt0000664000175000017500000003740315051422642023674 0ustar ghudsonghudson.. _ksu(1): ksu === SYNOPSIS -------- **ksu** [ *target_user* ] [ **-n** *target_principal_name* ] [ **-c** *source_cache_name* ] [ **-k** ] [ **-r** time ] [ **-p** | **-P**] [ **-f** | **-F**] [ **-l** *lifetime* ] [ **-z | Z** ] [ **-q** ] [ **-e** *command* [ args ... ] ] [ **-a** [ args ... ] ] REQUIREMENTS ------------ Must have Kerberos version 5 installed to compile ksu. Must have a Kerberos version 5 server running to use ksu. DESCRIPTION ----------- ksu is a Kerberized version of the su program that has two missions: one is to securely change the real and effective user ID to that of the target user, and the other is to create a new security context. .. note:: For the sake of clarity, all references to and attributes of the user invoking the program will start with "source" (e.g., "source user", "source cache", etc.). Likewise, all references to and attributes of the target account will start with "target". AUTHENTICATION -------------- To fulfill the first mission, ksu operates in two phases: authentication and authorization. Resolving the target principal name is the first step in authentication. The user can either specify his principal name with the **-n** option (e.g., ``-n jqpublic@USC.EDU``) or a default principal name will be assigned using a heuristic described in the OPTIONS section (see **-n** option). The target user name must be the first argument to ksu; if not specified root is the default. If ``.`` is specified then the target user will be the source user (e.g., ``ksu .``). If the source user is root or the target user is the source user, no authentication or authorization takes place. Otherwise, ksu looks for an appropriate Kerberos ticket in the source cache. The ticket can either be for the end-server or a ticket granting ticket (TGT) for the target principal's realm. If the ticket for the end-server is already in the cache, it's decrypted and verified. If it's not in the cache but the TGT is, the TGT is used to obtain the ticket for the end-server. The end-server ticket is then verified. If neither ticket is in the cache, but ksu is compiled with the **GET_TGT_VIA_PASSWD** define, the user will be prompted for a Kerberos password which will then be used to get a TGT. If the user is logged in remotely and does not have a secure channel, the password may be exposed. If neither ticket is in the cache and **GET_TGT_VIA_PASSWD** is not defined, authentication fails. AUTHORIZATION ------------- This section describes authorization of the source user when ksu is invoked without the **-e** option. For a description of the **-e** option, see the OPTIONS section. Upon successful authentication, ksu checks whether the target principal is authorized to access the target account. In the target user's home directory, ksu attempts to access two authorization files: :ref:`.k5login(5)` and .k5users. In the .k5login file each line contains the name of a principal that is authorized to access the account. For example:: jqpublic@USC.EDU jqpublic/secure@USC.EDU jqpublic/admin@USC.EDU The format of .k5users is the same, except the principal name may be followed by a list of commands that the principal is authorized to execute (see the **-e** option in the OPTIONS section for details). Thus if the target principal name is found in the .k5login file the source user is authorized to access the target account. Otherwise ksu looks in the .k5users file. If the target principal name is found without any trailing commands or followed only by ``*`` then the source user is authorized. If either .k5login or .k5users exist but an appropriate entry for the target principal does not exist then access is denied. If neither file exists then the principal will be granted access to the account according to the aname->lname mapping rules. Otherwise, authorization fails. EXECUTION OF THE TARGET SHELL ----------------------------- Upon successful authentication and authorization, ksu proceeds in a similar fashion to su. The environment is unmodified with the exception of USER, HOME and SHELL variables. If the target user is not root, USER gets set to the target user name. Otherwise USER remains unchanged. Both HOME and SHELL are set to the target login's default values. In addition, the environment variable **KRB5CCNAME** gets set to the name of the target cache. The real and effective user ID are changed to that of the target user. The target user's shell is then invoked (the shell name is specified in the password file). Upon termination of the shell, ksu deletes the target cache (unless ksu is invoked with the **-k** option). This is implemented by first doing a fork and then an exec, instead of just exec, as done by su. CREATING A NEW SECURITY CONTEXT ------------------------------- ksu can be used to create a new security context for the target program (either the target shell, or command specified via the **-e** option). The target program inherits a set of credentials from the source user. By default, this set includes all of the credentials in the source cache plus any additional credentials obtained during authentication. The source user is able to limit the credentials in this set by using **-z** or **-Z** option. **-z** restricts the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. The **-Z** option provides the target user with a fresh target cache (no creds in the cache). Note that for security reasons, when the source user is root and target user is non-root, **-z** option is the default mode of operation. While no authentication takes place if the source user is root or is the same as the target user, additional tickets can still be obtained for the target cache. If **-n** is specified and no credentials can be copied to the target cache, the source user is prompted for a Kerberos password (unless **-Z** specified or **GET_TGT_VIA_PASSWD** is undefined). If successful, a TGT is obtained from the Kerberos server and stored in the target cache. Otherwise, if a password is not provided (user hit return) ksu continues in a normal mode of operation (the target cache will not contain the desired TGT). If the wrong password is typed in, ksu fails. .. note:: During authentication, only the tickets that could be obtained without providing a password are cached in the source cache. OPTIONS ------- **-n** *target_principal_name* Specify a Kerberos target principal name. Used in authentication and authorization phases of ksu. If ksu is invoked without **-n**, a default principal name is assigned via the following heuristic: * Case 1: source user is non-root. If the target user is the source user the default principal name is set to the default principal of the source cache. If the cache does not exist then the default principal name is set to ``target_user@local_realm``. If the source and target users are different and neither ``~target_user/.k5users`` nor ``~target_user/.k5login`` exist then the default principal name is ``target_user_login_name@local_realm``. Otherwise, starting with the first principal listed below, ksu checks if the principal is authorized to access the target account and whether there is a legitimate ticket for that principal in the source cache. If both conditions are met that principal becomes the default target principal, otherwise go to the next principal. a) default principal of the source cache b) target_user\@local_realm c) source_user\@local_realm If a-c fails try any principal for which there is a ticket in the source cache and that is authorized to access the target account. If that fails select the first principal that is authorized to access the target account from the above list. If none are authorized and ksu is configured with **PRINC_LOOK_AHEAD** turned on, select the default principal as follows: For each candidate in the above list, select an authorized principal that has the same realm name and first part of the principal name equal to the prefix of the candidate. For example if candidate a) is ``jqpublic@ISI.EDU`` and ``jqpublic/secure@ISI.EDU`` is authorized to access the target account then the default principal is set to ``jqpublic/secure@ISI.EDU``. * Case 2: source user is root. If the target user is non-root then the default principal name is ``target_user@local_realm``. Else, if the source cache exists the default principal name is set to the default principal of the source cache. If the source cache does not exist, default principal name is set to ``root\@local_realm``. **-c** *source_cache_name* Specify source cache name (e.g., ``-c FILE:/tmp/my_cache``). If **-c** option is not used then the name is obtained from **KRB5CCNAME** environment variable. If **KRB5CCNAME** is not defined the source cache name is set to ``krb5cc_``. The target cache name is automatically set to ``krb5cc_.(gen_sym())``, where gen_sym generates a new number such that the resulting cache does not already exist. For example:: krb5cc_1984.2 **-k** Do not delete the target cache upon termination of the target shell or a command (**-e** command). Without **-k**, ksu deletes the target cache. **-z** Restrict the copy of tickets from the source cache to the target cache to only the tickets where client == the target principal name. Use the **-n** option if you want the tickets for other then the default principal. Note that the **-z** option is mutually exclusive with the **-Z** option. **-Z** Don't copy any tickets from the source cache to the target cache. Just create a fresh target cache, where the default principal name of the cache is initialized to the target principal name. Note that the **-Z** option is mutually exclusive with the **-z** option. **-q** Suppress the printing of status messages. Ticket granting ticket options: **-l** *lifetime* **-r** *time* **-p** **-P** **-f** **-F** The ticket granting ticket options only apply to the case where there are no appropriate tickets in the cache to authenticate the source user. In this case if ksu is configured to prompt users for a Kerberos password (**GET_TGT_VIA_PASSWD** is defined), the ticket granting ticket options that are specified will be used when getting a ticket granting ticket from the Kerberos server. **-l** *lifetime* (:ref:`duration` string.) Specifies the lifetime to be requested for the ticket; if this option is not specified, the default ticket lifetime (12 hours) is used instead. **-r** *time* (:ref:`duration` string.) Specifies that the **renewable** option should be requested for the ticket, and specifies the desired total lifetime of the ticket. **-p** specifies that the **proxiable** option should be requested for the ticket. **-P** specifies that the **proxiable** option should not be requested for the ticket, even if the default configuration is to ask for proxiable tickets. **-f** option specifies that the **forwardable** option should be requested for the ticket. **-F** option specifies that the **forwardable** option should not be requested for the ticket, even if the default configuration is to ask for forwardable tickets. **-e** *command* [*args* ...] ksu proceeds exactly the same as if it was invoked without the **-e** option, except instead of executing the target shell, ksu executes the specified command. Example of usage:: ksu bob -e ls -lag The authorization algorithm for **-e** is as follows: If the source user is root or source user == target user, no authorization takes place and the command is executed. If source user id != 0, and ``~target_user/.k5users`` file does not exist, authorization fails. Otherwise, ``~target_user/.k5users`` file must have an appropriate entry for target principal to get authorized. The .k5users file format: A single principal entry on each line that may be followed by a list of commands that the principal is authorized to execute. A principal name followed by a ``*`` means that the user is authorized to execute any command. Thus, in the following example:: jqpublic@USC.EDU ls mail /local/kerberos/klist jqpublic/secure@USC.EDU * jqpublic/admin@USC.EDU ``jqpublic@USC.EDU`` is only authorized to execute ``ls``, ``mail`` and ``klist`` commands. ``jqpublic/secure@USC.EDU`` is authorized to execute any command. ``jqpublic/admin@USC.EDU`` is not authorized to execute any command. Note, that ``jqpublic/admin@USC.EDU`` is authorized to execute the target shell (regular ksu, without the **-e** option) but ``jqpublic@USC.EDU`` is not. The commands listed after the principal name must be either a full path names or just the program name. In the second case, **CMD_PATH** specifying the location of authorized programs must be defined at the compilation time of ksu. Which command gets executed? If the source user is root or the target user is the source user or the user is authorized to execute any command (``*`` entry) then command can be either a full or a relative path leading to the target program. Otherwise, the user must specify either a full path or just the program name. **-a** *args* Specify arguments to be passed to the target shell. Note that all flags and parameters following -a will be passed to the shell, thus all options intended for ksu must precede **-a**. The **-a** option can be used to simulate the **-e** option if used as follows:: -a -c [command [arguments]]. **-c** is interpreted by the c-shell to execute the command. INSTALLATION INSTRUCTIONS ------------------------- ksu can be compiled with the following four flags: **GET_TGT_VIA_PASSWD** In case no appropriate tickets are found in the source cache, the user will be prompted for a Kerberos password. The password is then used to get a ticket granting ticket from the Kerberos server. The danger of configuring ksu with this macro is if the source user is logged in remotely and does not have a secure channel, the password may get exposed. **PRINC_LOOK_AHEAD** During the resolution of the default principal name, **PRINC_LOOK_AHEAD** enables ksu to find principal names in the .k5users file as described in the OPTIONS section (see **-n** option). **CMD_PATH** Specifies a list of directories containing programs that users are authorized to execute (via .k5users file). **HAVE_GETUSERSHELL** If the source user is non-root, ksu insists that the target user's shell to be invoked is a "legal shell". *getusershell(3)* is called to obtain the names of "legal shells". Note that the target user's shell is obtained from the passwd file. Sample configuration:: KSU_OPTS = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /usr/ucb /local/bin" ksu should be owned by root and have the set user id bit turned on. ksu attempts to get a ticket for the end server just as Kerberized telnet and rlogin. Thus, there must be an entry for the server in the Kerberos database (e.g., ``host/nii.isi.edu@ISI.EDU``). The keytab file must be in an appropriate location. SIDE EFFECTS ------------ ksu deletes all expired tickets from the source cache. AUTHOR OF KSU ------------- GENNADY (ARI) MEDVINSKY ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kerberos(7)`, :ref:`kinit(1)` krb5-1.22.1/doc/html/_sources/user/user_commands/sclient.rst.txt0000664000175000017500000000076115051422642024530 0ustar ghudsonghudson.. _sclient(1): sclient ======= SYNOPSIS -------- **sclient** *remotehost* DESCRIPTION ----------- sclient is a sample application, primarily useful for testing purposes. It contacts a sample server :ref:`sserver(8)` and authenticates to it using Kerberos version 5 tickets, then displays the server's response. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kinit(1)`, :ref:`sserver(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/user/user_commands/index.rst.txt0000664000175000017500000000032015051422642024165 0ustar ghudsonghudson.. _user_commands: User commands ============= .. toctree:: :maxdepth: 1 kdestroy.rst kinit.rst klist.rst kpasswd.rst krb5-config.rst ksu.rst kswitch.rst kvno.rst sclient.rst krb5-1.22.1/doc/html/_sources/user/user_commands/klist.rst.txt0000664000175000017500000000555715051422642024225 0ustar ghudsonghudson.. _klist(1): klist ===== SYNOPSIS -------- **klist** [**-e**] [[**-c**] [**-l**] [**-A**] [**-f**] [**-s**] [**-a** [**-n**]]] [**-C**] [**-k** [**-i**] [**-t**] [**-K**]] [**-V**] [**-d**] [*cache_name*\|\ *keytab_name*] DESCRIPTION ----------- klist lists the Kerberos principal and Kerberos tickets held in a credentials cache, or the keys held in a keytab file. OPTIONS ------- **-e** Displays the encryption types of the session key and the ticket for each credential in the credential cache, or each key in the keytab file. **-l** If a cache collection is available, displays a table summarizing the caches present in the collection. **-A** If a cache collection is available, displays the contents of all of the caches in the collection. **-c** List tickets held in a credentials cache. This is the default if neither **-c** nor **-k** is specified. **-f** Shows the flags present in the credentials, using the following abbreviations:: F Forwardable f forwarded P Proxiable p proxy D postDateable d postdated R Renewable I Initial i invalid H Hardware authenticated A preAuthenticated T Transit policy checked O Okay as delegate a anonymous **-s** Causes klist to run silently (produce no output). klist will exit with status 1 if the credentials cache cannot be read or is expired, and with status 0 otherwise. **-a** Display list of addresses in credentials. **-n** Show numeric addresses instead of reverse-resolving addresses. **-C** List configuration data that has been stored in the credentials cache when klist encounters it. By default, configuration data is not listed. **-k** List keys held in a keytab file. **-i** In combination with **-k**, defaults to using the default client keytab instead of the default acceptor keytab, if no name is given. **-t** Display the time entry timestamps for each keytab entry in the keytab file. **-K** Display the value of the encryption key in each keytab entry in the keytab file. **-d** Display the authdata types (if any) for each entry. **-V** Display the Kerberos version number and exit. If *cache_name* or *keytab_name* is not specified, klist will display the credentials in the default credentials cache or keytab file as appropriate. If the **KRB5CCNAME** environment variable is set, its value is used to locate the default ticket cache. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| Default location of Kerberos 5 credentials cache |keytab| Default location for the local host's keytab file. SEE ALSO -------- :ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/user/user_commands/kdestroy.rst.txt0000664000175000017500000000325615051422642024735 0ustar ghudsonghudson.. _kdestroy(1): kdestroy ======== SYNOPSIS -------- **kdestroy** [**-A**] [**-q**] [**-c** *cache_name*] [**-p** *princ_name*] DESCRIPTION ----------- The kdestroy utility destroys the user's active Kerberos authorization tickets by overwriting and deleting the credentials cache that contains them. If the credentials cache is not specified, the default credentials cache is destroyed. OPTIONS ------- **-A** Destroys all caches in the collection, if a cache collection is available. May be used with the **-c** option to specify the collection to be destroyed. **-q** Run quietly. Normally kdestroy beeps if it fails to destroy the user's tickets. The **-q** flag suppresses this behavior. **-c** *cache_name* Use *cache_name* as the credentials (ticket) cache name and location; if this option is not used, the default cache name and location are used. The default credentials cache may vary between systems. If the **KRB5CCNAME** environment variable is set, its value is used to name the default ticket cache. **-p** *princ_name* If a cache collection is available, destroy the cache for *princ_name* instead of the primary cache. May be used with the **-c** option to specify the collection to be searched. NOTE ---- Most installations recommend that you place the kdestroy command in your .logout file, so that your tickets are destroyed automatically when you log out. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| Default location of Kerberos 5 credentials cache SEE ALSO -------- :ref:`kinit(1)`, :ref:`klist(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/user/user_commands/kinit.rst.txt0000664000175000017500000001636115051422642024210 0ustar ghudsonghudson.. _kinit(1): kinit ===== SYNOPSIS -------- **kinit** [**-V**] [**-l** *lifetime*] [**-s** *start_time*] [**-r** *renewable_life*] [**-p** | -**P**] [**-f** | -**F**] [**-a**] [**-A**] [**-C**] [**-E**] [**-v**] [**-R**] [**-k** [**-i** | -**t** *keytab_file*]] [**-c** *cache_name*] [**-n**] [**-S** *service_name*] [**-I** *input_ccache*] [**-T** *armor_ccache*] [**-X** *attribute*\ [=\ *value*]] [**--request-pac** | **--no-request-pac**] [*principal*] DESCRIPTION ----------- kinit obtains and caches an initial ticket-granting ticket for *principal*. If *principal* is absent, kinit chooses an appropriate principal name based on existing credential cache contents or the local username of the user invoking kinit. Some options modify the choice of principal name. OPTIONS ------- **-V** display verbose output. **-l** *lifetime* (:ref:`duration` string.) Requests a ticket with the lifetime *lifetime*. For example, ``kinit -l 5:30`` or ``kinit -l 5h30m``. If the **-l** option is not specified, the default ticket lifetime (configured by each site) is used. Specifying a ticket lifetime longer than the maximum ticket lifetime (configured by each site) will not override the configured maximum ticket lifetime. **-s** *start_time* (:ref:`duration` string.) Requests a postdated ticket. Postdated tickets are issued with the **invalid** flag set, and need to be resubmitted to the KDC for validation before use. *start_time* specifies the duration of the delay before the ticket can become valid. **-r** *renewable_life* (:ref:`duration` string.) Requests renewable tickets, with a total lifetime of *renewable_life*. **-f** requests forwardable tickets. **-F** requests non-forwardable tickets. **-p** requests proxiable tickets. **-P** requests non-proxiable tickets. **-a** requests tickets restricted to the host's local address[es]. **-A** requests tickets not restricted by address. **-C** requests canonicalization of the principal name, and allows the KDC to reply with a different client principal from the one requested. **-E** treats the principal name as an enterprise name. **-v** requests that the ticket-granting ticket in the cache (with the **invalid** flag set) be passed to the KDC for validation. If the ticket is within its requested time range, the cache is replaced with the validated ticket. **-R** requests renewal of the ticket-granting ticket. Note that an expired ticket cannot be renewed, even if the ticket is still within its renewable life. Note that renewable tickets that have expired as reported by :ref:`klist(1)` may sometimes be renewed using this option, because the KDC applies a grace period to account for client-KDC clock skew. See :ref:`krb5.conf(5)` **clockskew** setting. **-k** [**-i** | **-t** *keytab_file*] requests a ticket, obtained from a key in the local host's keytab. The location of the keytab may be specified with the **-t** *keytab_file* option, or with the **-i** option to specify the use of the default client keytab; otherwise the default keytab will be used. By default, a host ticket for the local host is requested, but any principal may be specified. On a KDC, the special keytab location ``KDB:`` can be used to indicate that kinit should open the KDC database and look up the key directly. This permits an administrator to obtain tickets as any principal that supports authentication based on the key. **-n** Requests anonymous processing. Two types of anonymous principals are supported. For fully anonymous Kerberos, configure pkinit on the KDC and configure **pkinit_anchors** in the client's :ref:`krb5.conf(5)`. Then use the **-n** option with a principal of the form ``@REALM`` (an empty principal name followed by the at-sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. A second form of anonymous tickets is supported; these realm-exposed tickets hide the identity of the client but not the client's realm. For this mode, use ``kinit -n`` with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation. **-I** *input_ccache* Specifies the name of a credentials cache that already contains a ticket. When obtaining that ticket, if information about how that ticket was obtained was also stored to the cache, that information will be used to affect how new credentials are obtained, including preselecting the same methods of authenticating to the KDC. **-T** *armor_ccache* Specifies the name of a credentials cache that already contains a ticket. If supported by the KDC, this cache will be used to armor the request, preventing offline dictionary attacks and allowing the use of additional preauthentication mechanisms. Armoring also makes sure that the response from the KDC is not modified in transit. **-c** *cache_name* use *cache_name* as the Kerberos 5 credentials (ticket) cache location. If this option is not used, the default cache location is used. The default cache location may vary between systems. If the **KRB5CCNAME** environment variable is set, its value is used to locate the default cache. If a principal name is specified and the type of the default cache supports a collection (such as the DIR type), an existing cache containing credentials for the principal is selected or a new one is created and becomes the new primary cache. Otherwise, any existing contents of the default cache are destroyed by kinit. **-S** *service_name* specify an alternate service name to use when getting initial tickets. **-X** *attribute*\ [=\ *value*] specify a pre-authentication *attribute* and *value* to be interpreted by pre-authentication modules. The acceptable attribute and value values vary from module to module. This option may be specified multiple times to specify multiple attributes. If no value is specified, it is assumed to be "yes". The following attributes are recognized by the PKINIT pre-authentication mechanism: **X509_user_identity**\ =\ *value* specify where to find user's X509 identity information **X509_anchors**\ =\ *value* specify where to find trusted X509 anchor information **disable_freshness**\ [**=yes**] disable sending freshness tokens (for testing purposes only) **--request-pac** | **--no-request-pac** mutually exclusive. If **--request-pac** is set, ask the KDC to include a PAC in authdata; if **--no-request-pac** is set, ask the KDC not to include a PAC; if neither are set, the KDC will follow its default, which is typically is to include a PAC if doing so is supported. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| default location of Kerberos 5 credentials cache |keytab| default location for the local host's keytab. SEE ALSO -------- :ref:`klist(1)`, :ref:`kdestroy(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/user/user_commands/kvno.rst.txt0000664000175000017500000000640215051422642024042 0ustar ghudsonghudson.. _kvno(1): kvno ==== SYNOPSIS -------- **kvno** [**-c** *ccache*] [**-e** *etype*] [**-k** *keytab*] [**-q**] [**-u** | **-S** *sname*] [**-P**] [**--cached-only**] [**--no-store**] [**--out-cache** *cache*] [[{**-F** *cert_file* | {**-I** | **-U**} *for_user*} [**-P**]] | **--u2u** *ccache*] *service1 service2* ... DESCRIPTION ----------- kvno acquires a service ticket for the specified Kerberos principals and prints out the key version numbers of each. OPTIONS ------- **-c** *ccache* Specifies the name of a credentials cache to use (if not the default) **-e** *etype* Specifies the enctype which will be requested for the session key of all the services named on the command line. This is useful in certain backward compatibility situations. **-k** *keytab* Decrypt the acquired tickets using *keytab* to confirm their validity. **-q** Suppress printing output when successful. If a service ticket cannot be obtained, an error message will still be printed and kvno will exit with nonzero status. **-u** Use the unknown name type in requested service principal names. This option Cannot be used with *-S*. **-P** Specifies that the *service1 service2* ... arguments are to be treated as services for which credentials should be acquired using constrained delegation. This option is only valid when used in conjunction with protocol transition. **-S** *sname* Specifies that the *service1 service2* ... arguments are interpreted as hostnames, and the service principals are to be constructed from those hostnames and the service name *sname*. The service hostnames will be canonicalized according to the usual rules for constructing service principals. **-I** *for_user* Specifies that protocol transition (S4U2Self) is to be used to acquire a ticket on behalf of *for_user*. If constrained delegation is not requested, the service name must match the credentials cache client principal. **-U** *for_user* Same as -I, but treats *for_user* as an enterprise name. **-F** *cert_file* Specifies that protocol transition is to be used, identifying the client principal with the X.509 certificate in *cert_file*. The certificate file must be in PEM format. **--cached-only** Only retrieve credentials already present in the cache, not from the KDC. (Added in release 1.19.) **--no-store** Do not store retrieved credentials in the cache. If **--out-cache** is also specified, credentials will still be stored into the output credential cache. (Added in release 1.19.) **--out-cache** *ccache* Initialize *ccache* and store all retrieved credentials into it. Do not store acquired credentials in the input cache. (Added in release 1.19.) **--u2u** *ccache* Requests a user-to-user ticket. *ccache* must contain a local krbtgt ticket for the server principal. The reported version number will typically be 0, as the resulting ticket is not encrypted in the server's long-term key. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| Default location of the credentials cache SEE ALSO -------- :ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/user/user_commands/krb5-config.rst.txt0000664000175000017500000000456315051422642025201 0ustar ghudsonghudson.. _krb5-config(1): krb5-config =========== SYNOPSIS -------- **krb5-config** [**-**\ **-help** | **-**\ **-all** | **-**\ **-version** | **-**\ **-vendor** | **-**\ **-prefix** | **-**\ **-exec-prefix** | **-**\ **-defccname** | **-**\ **-defktname** | **-**\ **-defcktname** | **-**\ **-cflags** | **-**\ **-libs** [*libraries*]] DESCRIPTION ----------- krb5-config tells the application programmer what flags to use to compile and link programs against the installed Kerberos libraries. OPTIONS ------- **-**\ **-help** prints a usage message. This is the default behavior when no options are specified. **-**\ **-all** prints the version, vendor, prefix, and exec-prefix. **-**\ **-version** prints the version number of the Kerberos installation. **-**\ **-vendor** prints the name of the vendor of the Kerberos installation. **-**\ **-prefix** prints the prefix for which the Kerberos installation was built. **-**\ **-exec-prefix** prints the prefix for executables for which the Kerberos installation was built. **-**\ **-defccname** prints the built-in default credentials cache location. **-**\ **-defktname** prints the built-in default keytab location. **-**\ **-defcktname** prints the built-in default client (initiator) keytab location. **-**\ **-cflags** prints the compilation flags used to build the Kerberos installation. **-**\ **-libs** [*library*] prints the compiler options needed to link against *library*. Allowed values for *library* are: ============ =============================================== krb5 Kerberos 5 applications (default) gssapi GSSAPI applications with Kerberos 5 bindings kadm-client Kadmin client kadm-server Kadmin server kdb Applications that access the Kerberos database ============ =============================================== EXAMPLES -------- krb5-config is particularly useful for compiling against a Kerberos installation that was installed in a non-standard location. For example, a Kerberos installation that is installed in ``/opt/krb5/`` but uses libraries in ``/usr/local/lib/`` for text localization would produce the following output:: shell% krb5-config --libs krb5 -L/opt/krb5/lib -Wl,-rpath -Wl,/opt/krb5/lib -L/usr/local/lib -lkrb5 -lk5crypto -lcom_err SEE ALSO -------- :ref:`kerberos(7)`, cc(1) krb5-1.22.1/doc/html/_sources/user/user_commands/kswitch.rst.txt0000664000175000017500000000145015051422642024537 0ustar ghudsonghudson.. _kswitch(1): kswitch ======= SYNOPSIS -------- **kswitch** {**-c** *cachename*\|\ **-p** *principal*} DESCRIPTION ----------- kswitch makes the specified credential cache the primary cache for the collection, if a cache collection is available. OPTIONS ------- **-c** *cachename* Directly specifies the credential cache to be made primary. **-p** *principal* Causes the cache collection to be searched for a cache containing credentials for *principal*. If one is found, that collection is made primary. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. FILES ----- |ccache| Default location of Kerberos 5 credentials cache SEE ALSO -------- :ref:`kinit(1)`, :ref:`kdestroy(1)`, :ref:`klist(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/user/user_commands/kpasswd.rst.txt0000664000175000017500000000204315051422642024536 0ustar ghudsonghudson.. _kpasswd(1): kpasswd ======= SYNOPSIS -------- **kpasswd** [*principal*] DESCRIPTION ----------- The kpasswd command is used to change a Kerberos principal's password. kpasswd first prompts for the current Kerberos password, then prompts the user twice for the new password, and the password is changed. If the principal is governed by a policy that specifies the length and/or number of character classes required in the new password, the new password must conform to the policy. (The five character classes are lower case, upper case, numbers, punctuation, and all other characters.) OPTIONS ------- *principal* Change the password for the Kerberos principal principal. Otherwise, kpasswd uses the principal name from an existing ccache if there is one; if not, the principal is derived from the identity of the user invoking the kpasswd command. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`kadmind(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/mitK5defaults.rst.txt0000664000175000017500000001046315051422642021773 0ustar ghudsonghudson.. _mitK5defaults: MIT Kerberos defaults ===================== General defaults ---------------- ========================================== ============================= ==================== Description Default Environment ========================================== ============================= ==================== :ref:`keytab_definition` file |keytab| **KRB5_KTNAME** Client :ref:`keytab_definition` file |ckeytab| **KRB5_CLIENT_KTNAME** Kerberos config file :ref:`krb5.conf(5)` |krb5conf|\ ``:``\ **KRB5_CONFIG** |sysconfdir|\ ``/krb5.conf`` KDC config file :ref:`kdc.conf(5)` |kdcdir|\ ``/kdc.conf`` **KRB5_KDC_PROFILE** GSS mechanism config file |sysconfdir|\ ``/gss/mech`` **GSS_MECH_CONFIG** KDC database path (DB2) |kdcdir|\ ``/principal`` Master key :ref:`stash_definition` |kdcdir|\ ``/.k5.``\ *realm* Admin server ACL file :ref:`kadm5.acl(5)` |kdcdir|\ ``/kadm5.acl`` OTP socket directory |kdcrundir| Plugin base directory |libdir|\ ``/krb5/plugins`` :ref:`rcache_definition` directory ``/var/tmp`` **KRB5RCACHEDIR** Master key default enctype |defmkey| Default :ref:`keysalt list` |defkeysalts| Permitted enctypes |defetypes| KDC default port 88 Admin server port 749 Password change port 464 ========================================== ============================= ==================== Replica KDC propagation defaults -------------------------------- This table shows defaults used by the :ref:`kprop(8)` and :ref:`kpropd(8)` programs. ========================== ================================ =========== Description Default Environment ========================== ================================ =========== kprop database dump file |kdcdir|\ ``/replica_datatrans`` kpropd temporary dump file |kdcdir|\ ``/from_master`` kdb5_util location |sbindir|\ ``/kdb5_util`` kprop location |sbindir|\ ``/kprop`` kpropd ACL file |kdcdir|\ ``/kpropd.acl`` kprop port 754 KPROP_PORT ========================== ================================ =========== .. _paths: Default paths for Unix-like systems ----------------------------------- On Unix-like systems, some paths used by MIT krb5 depend on parameters chosen at build time. For a custom build, these paths default to subdirectories of ``/usr/local``. When MIT krb5 is integrated into an operating system, the paths are generally chosen to match the operating system's filesystem layout. ========================== ============== =========================== =========================== Description Symbolic name Custom build path Typical OS path ========================== ============== =========================== =========================== User programs BINDIR ``/usr/local/bin`` ``/usr/bin`` Libraries and plugins LIBDIR ``/usr/local/lib`` ``/usr/lib`` Parent of KDC state dir LOCALSTATEDIR ``/usr/local/var`` ``/var`` Parent of KDC runtime dir RUNSTATEDIR ``/usr/local/var/run`` ``/run`` Administrative programs SBINDIR ``/usr/local/sbin`` ``/usr/sbin`` Alternate krb5.conf dir SYSCONFDIR ``/usr/local/etc`` ``/etc`` Default ccache name DEFCCNAME ``FILE:/tmp/krb5cc_%{uid}`` ``FILE:/tmp/krb5cc_%{uid}`` Default keytab name DEFKTNAME ``FILE:/etc/krb5.keytab`` ``FILE:/etc/krb5.keytab`` Default PKCS11 module PKCS11_MODNAME ``opensc-pkcs11.so`` ``opensc-pkcs11.so`` ========================== ============== =========================== =========================== The default client keytab name (DEFCKTNAME) typically defaults to ``FILE:/usr/local/var/krb5/user/%{euid}/client.keytab`` for a custom build. A native build will typically use a path which will vary according to the operating system's layout of ``/var``. krb5-1.22.1/doc/html/_sources/index.rst.txt0000664000175000017500000000047215051422642020360 0ustar ghudsonghudsonMIT Kerberos Documentation (|release|) ====================================== .. toctree:: :maxdepth: 1 user/index.rst admin/index.rst appdev/index.rst plugindev/index.rst build/index.rst basic/index.rst formats/index.rst mitK5features.rst build_this.rst about.rst resources krb5-1.22.1/doc/html/_sources/build_this.rst.txt0000664000175000017500000000554415051422642021404 0ustar ghudsonghudsonHow to build this documentation from the source =============================================== Pre-requisites for a simple build, or to update man pages: * Sphinx 1.0.4 or higher (See https://www.sphinx-doc.org) with the autodoc extension installed. Additional prerequisites to include the API reference based on Doxygen markup: * Python 2.5 with the Cheetah, lxml, and xml modules * Doxygen Simple build without API reference ---------------------------------- To test simple changes to the RST sources, you can build the documentation without the Doxygen reference by running, from the doc directory:: sphinx-build . test_html You will see a number of warnings about missing files. This is expected. If there is not already a ``doc/version.py`` file, you will need to create one by first running ``make version.py`` in the ``src/doc`` directory of a configured build tree. Updating man pages ------------------ Man pages are generated from the RST sources and checked into the ``src/man`` directory of the repository. This allows man pages to be installed without requiring Sphinx when using a source checkout. To regenerate these files, run ``make man`` from the man subdirectory of a configured build tree. You can also do this from an unconfigured source tree with:: cd src/man make -f Makefile.in top_srcdir=.. srcdir=. man make clean As with the simple build, it is normal to see warnings about missing files when rebuilding the man pages. Building for a release tarball or web site ------------------------------------------ To generate documentation in HTML format, run ``make html`` in the ``doc`` subdirectory of a configured build tree (the build directory corresponding to ``src/doc``, not the top-level ``doc`` directory). The output will be placed in the top-level ``doc/html`` directory. This build will include the API reference generated from Doxygen markup in the source tree. Documentation generated this way will use symbolic names for paths (like ``BINDIR`` for the directory containing user programs), with the symbolic names being links to a table showing typical values for those paths. You can also do this from an unconfigured source tree with:: cd src/doc make -f Makefile.in SPHINX_ARGS= htmlsrc Building for an OS package or site documentation ------------------------------------------------ To generate documentation specific to a build of MIT krb5 as you have configured it, run ``make substhtml`` in the ``doc`` subdirectory of a configured build tree (the build directory corresponding to ``src/doc``, not the top-level ``doc`` directory). The output will be placed in the ``html_subst`` subdirectory of that build directory. This build will include the API reference. Documentation generated this way will use concrete paths (like ``/usr/local/bin`` for the directory containing user programs, for a default custom build). krb5-1.22.1/doc/html/_sources/about.rst.txt0000664000175000017500000000345115051422642020363 0ustar ghudsonghudsonContributing to the MIT Kerberos Documentation ============================================== We are looking for documentation writers and editors who could contribute towards improving the MIT KC documentation content. If you are an experienced Kerberos developer and/or administrator, please consider sharing your knowledge and experience with the Kerberos Community. You can suggest your own topic or write about any of the topics listed `here `__. If you have any questions, comments, or suggestions on the existing documents, please send your feedback via email to krb5-bugs@mit.edu. The HTML version of this documentation has a "FEEDBACK" link to the krb5-bugs@mit.edu email address with a pre-constructed subject line. Background ---------- Starting with release 1.11, the Kerberos documentation set is unified in a central form. Man pages, HTML documentation, and PDF documents are compiled from reStructuredText sources, and the application developer documentation incorporates Doxygen markup from the source tree. This project was undertaken along the outline described `here `__. Previous versions of Kerberos 5 attempted to maintain separate documentation in the texinfo format, with separate groff manual pages. Having the API documentation disjoint from the source code implementing that API resulted in the documentation becoming stale, and over time the documentation ceased to match reality. With a fresh start and a source format that is easier to use and maintain, reStructuredText-based documents should provide an improved experience for the user. Consolidating all the documentation formats into a single source document makes the documentation set easier to maintain. krb5-1.22.1/doc/html/_sources/plugindev/0000775000175000017500000000000015051422713017672 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/plugindev/pwqual.rst.txt0000664000175000017500000000233315051422642022555 0ustar ghudsonghudson.. _pwqual_plugin: Password quality interface (pwqual) =================================== The pwqual interface allows modules to control what passwords are allowed when a user changes passwords. For a detailed description of the pwqual interface, see the header file ````. The primary pwqual method is **check**, which receives a password as input and returns success (0) or a ``KADM5_PASS_Q_`` failure code depending on whether the password is allowed. The **check** method also receives the principal name and the name of the principal's password policy as input; although there is no stable interface for the module to obtain the fields of the password policy, it can define its own configuration or data store based on the policy name. A module can create and destroy per-process state objects by implementing the **open** and **close** methods. State objects have the type krb5_pwqual_moddata, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. The **open** method also receives the name of the realm's dictionary file (as configured by the **dict_file** variable in the :ref:`kdc_realms` section of :ref:`kdc.conf(5)`) if it wishes to use it. krb5-1.22.1/doc/html/_sources/plugindev/index.rst.txt0000664000175000017500000000152515051422642022355 0ustar ghudsonghudsonFor plugin module developers ============================ Kerberos plugin modules allow increased control over MIT krb5 library and server behavior. This guide describes how to create dynamic plugin modules and the currently available pluggable interfaces. See :ref:`plugin_config` for information on how to register dynamic plugin modules and how to enable and disable modules via :ref:`krb5.conf(5)`. .. TODO: update the above reference when we have a free-form section in the admin guide about plugin configuration Contents -------- .. toctree:: :maxdepth: 2 general.rst clpreauth.rst kdcpreauth.rst ccselect.rst pwqual.rst kadm5_hook.rst kadm5_auth.rst hostrealm.rst localauth.rst locate.rst profile.rst gssapi.rst internal.rst certauth.rst kdcpolicy.rst .. TODO: GSSAPI mechanism plugins krb5-1.22.1/doc/html/_sources/plugindev/kdcpreauth.rst.txt0000664000175000017500000000760615051422642023406 0ustar ghudsonghudsonKDC preauthentication interface (kdcpreauth) ============================================ The kdcpreauth interface allows the addition of KDC support for preauthentication mechanisms beyond those included in the core MIT krb5 code base. For a detailed description of the kdcpreauth interface, see the header file ```` (or ```` before release 1.12). A kdcpreauth module is generally responsible for: * Supplying a list of preauth type numbers used by the module in the **pa_type_list** field of the vtable structure. * Indicating what kind of preauthentication mechanism it implements, with the **flags** method. If the mechanism computes a new reply key, it must specify the ``PA_REPLACES_KEY`` flag. If the mechanism is generally only used with hardware tokens, the ``PA_HARDWARE`` flag allows the mechanism to work with principals which have the **requires_hwauth** flag set. * Producing a padata value to be sent with a preauth_required error, with the **edata** method. * Examining a padata value sent by a client and verifying that it proves knowledge of the appropriate client credential information. This is done with the **verify** method. * Producing a padata response value for the client, and possibly computing a reply key. This is done with the **return_padata** method. A module can create and destroy per-KDC state objects by implementing the **init** and **fini** methods. Per-KDC state objects have the type krb5_kdcpreauth_moddata, which is an abstract pointer types. A module should typically cast this to an internal type for the state object. A module can create a per-request state object by returning one in the **verify** method, receiving it in the **return_padata** method, and destroying it in the **free_modreq** method. Note that these state objects only apply to the processing of a single AS request packet, not to an entire authentication exchange (since an authentication exchange may remain unfinished by the client or may involve multiple different KDC hosts). Per-request state objects have the type krb5_kdcpreauth_modreq, which is an abstract pointer type. The **edata**, **verify**, and **return_padata** methods have access to a callback function and handle (called a "rock") which can be used to get additional information about the current request, including the maximum allowable clock skew, the client's long-term keys, the DER-encoded request body, the FAST armor key, string attributes on the client's database entry, and the client's database entry itself. The **verify** method can assert one or more authentication indicators to be included in the issued ticket using the ``add_auth_indicator`` callback (new in release 1.14). A module can generate state information to be included with the next client request using the ``set_cookie`` callback (new in release 1.14). On the next request, the module can read this state information using the ``get_cookie`` callback. Cookie information is encrypted, timestamped, and transmitted to the client in a ``PA-FX-COOKIE`` pa-data item. Older clients may not support cookies and therefore may not transmit the cookie in the next request; in this case, ``get_cookie`` will not yield the saved information. If a module implements a mechanism which requires multiple round trips, its **verify** method can respond with the code ``KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED`` and a list of pa-data in the *e_data* parameter to be processed by the client. The **edata** and **verify** methods can be implemented asynchronously. Because of this, they do not return values directly to the caller, but must instead invoke responder functions with their results. A synchronous implementation can invoke the responder function immediately. An asynchronous implementation can use the callback to get an event context for use with the libverto_ API. .. _libverto: https://fedorahosted.org/libverto/ krb5-1.22.1/doc/html/_sources/plugindev/profile.rst.txt0000664000175000017500000000717615051422642022716 0ustar ghudsonghudson.. _profile_plugin: Configuration interface (profile) ================================= The profile interface allows a module to control how krb5 configuration information is obtained by the Kerberos library and applications. For a detailed description of the profile interface, see the header file ````. .. note:: The profile interface does not follow the normal conventions for MIT krb5 pluggable interfaces, because it is part of a lower-level component of the krb5 library. As with other types of plugin modules, a profile module is a Unix shared object or Windows DLL, built separately from the krb5 tree. The krb5 library will dynamically load and use a profile plugin module if it reads a ``module`` directive at the beginning of krb5.conf, as described in :ref:`profile_plugin_config`. A profile module exports a function named ``profile_module_init`` matching the signature of the profile_module_init_fn type. This function accepts a residual string, which may be used to help locate the configuration source. The function fills in a vtable and may also create a per-profile state object. If the module uses state objects, it should implement the **copy** and **cleanup** methods to manage them. A basic read-only profile module need only implement the **get_values** and **free_values** methods. The **get_values** method accepts a null-terminated list of C string names (e.g., an array containing "libdefaults", "clockskew", and NULL for the **clockskew** variable in the :ref:`libdefaults` section) and returns a null-terminated list of values, which will be cleaned up with the **free_values** method when the caller is done with them. Iterable profile modules must also define the **iterator_create**, **iterator**, **iterator_free**, and **free_string** methods. The core krb5 code does not require profiles to be iterable, but some applications may iterate over the krb5 profile object in order to present configuration interfaces. Writable profile modules must also define the **writable**, **modified**, **update_relation**, **rename_section**, **add_relation**, and **flush** methods. The core krb5 code does not require profiles to be writable, but some applications may write to the krb5 profile in order to present configuration interfaces. The following is an example of a very basic read-only profile module which returns a hardcoded value for the **default_realm** variable in :ref:`libdefaults`, and provides no other configuration information. (For conciseness, the example omits code for checking the return values of malloc and strdup.) :: #include #include #include static long get_values(void *cbdata, const char *const *names, char ***values) { if (names[0] != NULL && strcmp(names[0], "libdefaults") == 0 && names[1] != NULL && strcmp(names[1], "default_realm") == 0) { *values = malloc(2 * sizeof(char *)); (*values)[0] = strdup("ATHENA.MIT.EDU"); (*values)[1] = NULL; return 0; } return PROF_NO_RELATION; } static void free_values(void *cbdata, char **values) { char **v; for (v = values; *v; v++) free(*v); free(values); } long profile_module_init(const char *residual, struct profile_vtable *vtable, void **cb_ret); long profile_module_init(const char *residual, struct profile_vtable *vtable, void **cb_ret) { *cb_ret = NULL; vtable->get_values = get_values; vtable->free_values = free_values; return 0; } krb5-1.22.1/doc/html/_sources/plugindev/certauth.rst.txt0000664000175000017500000000336015051422642023064 0ustar ghudsonghudson.. _certauth_plugin: PKINIT certificate authorization interface (certauth) ===================================================== The certauth interface was first introduced in release 1.16. It allows customization of the X.509 certificate attribute requirements placed on certificates used by PKINIT enabled clients. For a detailed description of the certauth interface, see the header file ```` A certauth module implements the **authorize** method to determine whether a client's certificate is authorized to authenticate a client principal. **authorize** receives the DER-encoded certificate, the requested client principal, and a pointer to the client's krb5_db_entry (for modules that link against libkdb5). The method must decode the certificate and inspect its attributes to determine if it should authorize PKINIT authentication. It returns the authorization status and optionally outputs a list of authentication indicator strings to be added to the ticket. Beginning in release 1.19, the authorize method can request that the hardware authentication bit be set in the ticket by returning **KRB5_CERTAUTH_HWAUTH**. Beginning in release 1.20, the authorize method can return **KRB5_CERTAUTH_HWAUTH_PASS** to request that the hardware authentication bit be set in the ticket but otherwise defer authorization to another certauth module. A module must use its own internal or library-provided ASN.1 certificate decoder. A module can optionally create and destroy module data with the **init** and **fini** methods. Module data objects last for the lifetime of the KDC process. If a module allocates and returns a list of authentication indicators from **authorize**, it must also implement the **free_ind** method to free the list. krb5-1.22.1/doc/html/_sources/plugindev/ccselect.rst.txt0000664000175000017500000000236515051422642023036 0ustar ghudsonghudson.. _ccselect_plugin: Credential cache selection interface (ccselect) =============================================== The ccselect interface allows modules to control how credential caches are chosen when a GSSAPI client contacts a service. For a detailed description of the ccselect interface, see the header file ````. The primary ccselect method is **choose**, which accepts a server principal as input and returns a ccache and/or principal name as output. A module can use the krb5_cccol APIs to iterate over the cache collection in order to find an appropriate ccache to use. .. TODO: add reference to the admin guide for ccaches and cache collections when we have appropriate sections. A module can create and destroy per-library-context state objects by implementing the **init** and **fini** methods. State objects have the type krb5_ccselect_moddata, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. A module can have one of two priorities, "authoritative" or "heuristic". Results from authoritative modules, if any are available, will take priority over results from heuristic modules. A module communicates its priority as a result of the **init** method. krb5-1.22.1/doc/html/_sources/plugindev/kadm5_auth.rst.txt0000664000175000017500000000332715051422642023272 0ustar ghudsonghudson.. _kadm5_auth_plugin: kadmin authorization interface (kadm5_auth) =========================================== The kadm5_auth interface (new in release 1.16) allows modules to determine whether a client principal is authorized to perform an operation in the kadmin protocol, and to apply restrictions to principal operations. For a detailed description of the kadm5_auth interface, see the header file ````. A module can create and destroy per-process state objects by implementing the **init** and **fini** methods. State objects have the type kadm5_auth_modinfo, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. The kadm5_auth interface has one method for each kadmin operation, with parameters specific to the operation. Each method can return either 0 to authorize access, KRB5_PLUGIN_NO_HANDLE to defer the decision to other modules, or another error (canonically EPERM) to authoritatively deny access. Access is granted if at least one module grants access and no module authoritatively denies access. The **addprinc** and **modprinc** methods can also impose restrictions on the principal operation by returning a ``struct kadm5_auth_restrictions`` object. The module should also implement the **free_restrictions** method if it dynamically allocates restrictions objects for principal operations. kadm5_auth modules can optionally inspect principal or policy objects. To do this, the module must also include ```` to gain access to the structure definitions for those objects. As the kadmin interface is explicitly not as stable as other public interfaces, modules which do this may not retain compatibility across releases. krb5-1.22.1/doc/html/_sources/plugindev/internal.rst.txt0000664000175000017500000000231615051422642023061 0ustar ghudsonghudsonInternal pluggable interfaces ============================= Following are brief discussions of pluggable interfaces which have not yet been made public. These interfaces are functional, but the interfaces are likely to change in incompatible ways from release to release. In some cases, it may be necessary to copy header files from the krb5 source tree to use an internal interface. Use these with care, and expect to need to update your modules for each new release of MIT krb5. Kerberos database interface (KDB) --------------------------------- A KDB module implements a database back end for KDC principal and policy information, and can also control many aspects of KDC behavior. For a full description of the interface, see the header file ````. The KDB pluggable interface is often referred to as the DAL (Database Access Layer). Authorization data interface (authdata) --------------------------------------- The authdata interface allows a module to provide (from the KDC) or consume (in application servers) authorization data of types beyond those handled by the core MIT krb5 code base. The interface is defined in the header file ````, which is not installed by the build. krb5-1.22.1/doc/html/_sources/plugindev/localauth.rst.txt0000664000175000017500000000406215051422642023221 0ustar ghudsonghudson.. _localauth_plugin: Local authorization interface (localauth) ========================================= The localauth interface was first introduced in release 1.12. It allows modules to control the relationship between Kerberos principals and local system accounts. When an application calls :c:func:`krb5_kuserok` or :c:func:`krb5_aname_to_localname`, localauth modules are consulted to determine the result. For a detailed description of the localauth interface, see the header file ````. A module can create and destroy per-library-context state objects using the **init** and **fini** methods. If the module does not need any state, it does not need to implement these methods. The optional **userok** method allows a module to control the behavior of :c:func:`krb5_kuserok`. The module receives the authenticated name and the local account name as inputs, and can return either 0 to authorize access, KRB5_PLUGIN_NO_HANDLE to defer the decision to other modules, or another error (canonically EPERM) to authoritatively deny access. Access is granted if at least one module grants access and no module authoritatively denies access. The optional **an2ln** method can work in two different ways. If the module sets an array of uppercase type names in **an2ln_types**, then the module's **an2ln** method will only be invoked by :c:func:`krb5_aname_to_localname` if an **auth_to_local** value in :ref:`krb5.conf(5)` refers to one of the module's types. In this case, the *type* and *residual* arguments will give the type name and residual string of the **auth_to_local** value. If the module does not set **an2ln_types** but does implement **an2ln**, the module's **an2ln** method will be invoked for all :c:func:`krb5_aname_to_localname` operations unless an earlier module determines a mapping, with *type* and *residual* set to NULL. The module can return KRB5_LNAME_NO_TRANS to defer mapping to later modules. If a module implements **an2ln**, it must also implement **free_string** to ensure that memory is allocated and deallocated consistently. krb5-1.22.1/doc/html/_sources/plugindev/kadm5_hook.rst.txt0000664000175000017500000000231415051422642023264 0ustar ghudsonghudson.. _kadm5_hook_plugin: KADM5 hook interface (kadm5_hook) ================================= The kadm5_hook interface allows modules to perform actions when changes are made to the Kerberos database through :ref:`kadmin(1)`. For a detailed description of the kadm5_hook interface, see the header file ````. The kadm5_hook interface has five primary methods: **chpass**, **create**, **modify**, **remove**, and **rename**. (The **rename** method was introduced in release 1.14.) Each of these methods is called twice when the corresponding administrative action takes place, once before the action is committed and once afterwards. A module can prevent the action from taking place by returning an error code during the pre-commit stage. A module can create and destroy per-process state objects by implementing the **init** and **fini** methods. State objects have the type kadm5_hook_modinfo, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. Because the kadm5_hook interface is tied closely to the kadmin interface (which is explicitly unstable), it may not remain as stable across versions as other public pluggable interfaces. krb5-1.22.1/doc/html/_sources/plugindev/locate.rst.txt0000664000175000017500000000303215051422642022510 0ustar ghudsonghudsonServer location interface (locate) ================================== The locate interface allows modules to control how KDCs and similar services are located by clients. For a detailed description of the ccselect interface, see the header file ````. .. note: The locate interface does not follow the normal conventions for MIT krb5 pluggable interfaces, because it was made public before those conventions were established. A locate module exports a structure object of type krb5plugin_service_locate_ftable, with the name ``service_locator``. The structure contains a minor version and pointers to the module's methods. The primary locate method is **lookup**, which accepts a service type, realm name, desired socket type, and desired address family (which will be AF_UNSPEC if no specific address family is desired). The method should invoke the callback function once for each server address it wants to return, passing a socket type (SOCK_STREAM for TCP or SOCK_DGRAM for UDP) and socket address. The **lookup** method should return 0 if it has authoritatively determined the server addresses for the realm, KRB5_PLUGIN_NO_HANDLE if it wants to let other location mechanisms determine the server addresses, or another code if it experienced a failure which should abort the location process. A module can create and destroy per-library-context state objects by implementing the **init** and **fini** methods. State objects have the type void \*, and should be cast to an internal type for the state object. krb5-1.22.1/doc/html/_sources/plugindev/clpreauth.rst.txt0000664000175000017500000000513515051422642023236 0ustar ghudsonghudsonClient preauthentication interface (clpreauth) ============================================== During an initial ticket request, a KDC may ask a client to prove its knowledge of the password before issuing an encrypted ticket, or to use credentials other than a password. This process is called preauthentication, and is described in :rfc:`4120` and :rfc:`6113`. The clpreauth interface allows the addition of client support for preauthentication mechanisms beyond those included in the core MIT krb5 code base. For a detailed description of the clpreauth interface, see the header file ```` (or ```` before release 1.12). A clpreauth module is generally responsible for: * Supplying a list of preauth type numbers used by the module in the **pa_type_list** field of the vtable structure. * Indicating what kind of preauthentication mechanism it implements, with the **flags** method. In the most common case, this method just returns ``PA_REAL``, indicating that it implements a normal preauthentication type. * Examining the padata information included in a PREAUTH_REQUIRED or MORE_PREAUTH_DATA_REQUIRED error and producing padata values for the next AS request. This is done with the **process** method. * Examining the padata information included in a successful ticket reply, possibly verifying the KDC identity and computing a reply key. This is also done with the **process** method. * For preauthentication types which support it, recovering from errors by examining the error data from the KDC and producing a padata value for another AS request. This is done with the **tryagain** method. * Receiving option information (supplied by ``kinit -X`` or by an application), with the **gic_opts** method. A clpreauth module can create and destroy per-library-context and per-request state objects by implementing the **init**, **fini**, **request_init**, and **request_fini** methods. Per-context state objects have the type krb5_clpreauth_moddata, and per-request state objects have the type krb5_clpreauth_modreq. These are abstract pointer types; a module should typically cast these to internal types for the state objects. The **process** and **tryagain** methods have access to a callback function and handle (called a "rock") which can be used to get additional information about the current request, including the expected enctype of the AS reply, the FAST armor key, and the client long-term key (prompting for the user password if necessary). A callback can also be used to replace the AS reply key if the preauthentication mechanism computes one. krb5-1.22.1/doc/html/_sources/plugindev/gssapi.rst.txt0000664000175000017500000001371415051422642022537 0ustar ghudsonghudsonGSSAPI mechanism interface ========================== The GSSAPI library in MIT krb5 can load mechanism modules to augment the set of built-in mechanisms. .. note: The GSSAPI loadable mechanism interface does not follow the normal conventions for MIT krb5 pluggable interfaces. A mechanism module is a Unix shared object or Windows DLL, built separately from the krb5 tree. Modules are loaded according to the GSS mechanism config files described in :ref:`gssapi_plugin_config`. For the most part, a GSSAPI mechanism module exports the same functions as would a GSSAPI implementation itself, with the same function signatures. The mechanism selection layer within the GSSAPI library (called the "mechglue") will dispatch calls from the application to the module if the module's mechanism is requested. If a module does not wish to implement a GSSAPI extension, it can simply refrain from exporting it, and the mechglue will fail gracefully if the application calls that function. The mechglue does not invoke a module's **gss_add_cred**, **gss_add_cred_from**, **gss_add_cred_impersonate_name**, or **gss_add_cred_with_password** function. A mechanism only needs to implement the "acquire" variants of those functions. A module does not need to coordinate its minor status codes with those of other mechanisms. If the mechglue detects conflicts, it will map the mechanism's status codes onto unique values, and then map them back again when **gss_display_status** is called. NegoEx modules -------------- Some Windows GSSAPI mechanisms can only be negotiated via a Microsoft extension to SPNEGO called NegoEx. Beginning with release 1.18, mechanism modules can support NegoEx as follows: * Implement the gssspi_query_meta_data(), gssspi_exchange_meta_data(), and gssspi_query_mechanism_info() SPIs declared in ````. * Implement gss_inquire_sec_context_by_oid() and answer the **GSS_C_INQ_NEGOEX_KEY** and **GSS_C_INQ_NEGOEX_VERIFY_KEY** OIDs to provide the checksum keys for outgoing and incoming checksums, respectively. The answer must be in two buffers: the first buffer contains the key contents, and the second buffer contains the key encryption type as a four-byte little-endian integer. By default, NegoEx mechanisms will not be directly negotiated via SPNEGO. If direct SPNEGO negotiation is required for interoperability, implement gss_inquire_attrs_for_mech() and assert the GSS_C_MA_NEGOEX_AND_SPNEGO attribute (along with any applicable RFC 5587 attributes). Interposer modules ------------------ The mechglue also supports a kind of loadable module, called an interposer module, which intercepts calls to existing mechanisms rather than implementing a new mechanism. An interposer module must export the symbol **gss_mech_interposer** with the following signature:: gss_OID_set gss_mech_interposer(gss_OID mech_type); This function is invoked with the OID of the interposer mechanism as specified in the mechanism config file, and returns a set of mechanism OIDs to be interposed. The returned OID set must have been created using the mechglue's gss_create_empty_oid_set and gss_add_oid_set_member functions. An interposer module must use the prefix ``gssi_`` for the GSSAPI functions it exports, instead of the prefix ``gss_``. In most cases, unexported ``gssi_`` functions will result in failure from their corresponding ``gss_`` calls. An interposer module can link against the GSSAPI library in order to make calls to the original mechanism. To do so, it must specify a special mechanism OID which is the concatention of the interposer's own OID byte string and the original mechanism's OID byte string. Functions that do not accept a mechanism argument directly require no special handling, with the following exceptions: Since **gss_accept_sec_context** does not accept a mechanism argument, an interposer mechanism must, in order to invoke the original mechanism's function, acquire a credential for the concatenated OID and pass that as the *verifier_cred_handle* parameter. Since **gss_import_name**, **gss_import_cred**, and **gss_import_sec_context** do not accept mechanism parameters, the SPI has been extended to include variants which do. This allows the interposer module to know which mechanism should be used to interpret the token. These functions have the following signatures:: OM_uint32 gssi_import_sec_context_by_mech(OM_uint32 *minor_status, gss_OID desired_mech, gss_buffer_t interprocess_token, gss_ctx_id_t *context_handle); OM_uint32 gssi_import_name_by_mech(OM_uint32 *minor_status, gss_OID mech_type, gss_buffer_t input_name_buffer, gss_OID input_name_type, gss_name_t output_name); OM_uint32 gssi_import_cred_by_mech(OM_uint32 *minor_status, gss_OID mech_type, gss_buffer_t token, gss_cred_id_t *cred_handle); To re-enter the original mechanism when importing tokens for the above functions, the interposer module must wrap the mechanism token in the mechglue's format, using the concatenated OID (except in **gss_import_name**). The mechglue token formats are: * For **gss_import_sec_context**, a four-byte OID length in big-endian order, followed by the concatenated OID, followed by the mechanism token. * For **gss_import_name**, the bytes 04 01, followed by a two-byte OID length in big-endian order, followed by the mechanism OID, followed by a four-byte token length in big-endian order, followed by the mechanism token. Unlike most uses of OIDs in the API, the mechanism OID encoding must include the DER tag and length for an object identifier (06 followed by the DER length of the OID byte string), and this prefix must be included in the two-byte OID length. input_name_type must also be set to GSS_C_NT_EXPORT_NAME. * For **gss_import_cred**, a four-byte OID length in big-endian order, followed by the concatenated OID, followed by a four-byte token length in big-endian order, followed by the mechanism token. This sequence may be repeated multiple times. krb5-1.22.1/doc/html/_sources/plugindev/kdcpolicy.rst.txt0000664000175000017500000000212615051422642023225 0ustar ghudsonghudson.. _kdcpolicy_plugin: KDC policy interface (kdcpolicy) ================================ The kdcpolicy interface was first introduced in release 1.16. It allows modules to veto otherwise valid AS and TGS requests or restrict the lifetime and renew time of the resulting ticket. For a detailed description of the kdcpolicy interface, see the header file ````. The optional **check_as** and **check_tgs** functions allow the module to perform access control. Additionally, a module can create and destroy module data with the **init** and **fini** methods. Module data objects last for the lifetime of the KDC process, and are provided to all other methods. The data has the type krb5_kdcpolicy_moddata, which should be cast to the appropriate internal type. kdcpolicy modules can optionally inspect principal entries. To do this, the module must also include ```` to gain access to the principal entry structure definition. As the KDB interface is explicitly not as stable as other public interfaces, modules which do this may not retain compatibility across releases. krb5-1.22.1/doc/html/_sources/plugindev/hostrealm.rst.txt0000664000175000017500000000305515051422642023244 0ustar ghudsonghudson.. _hostrealm_plugin: Host-to-realm interface (hostrealm) =================================== The host-to-realm interface was first introduced in release 1.12. It allows modules to control the local mapping of hostnames to realm names as well as the default realm. For a detailed description of the hostrealm interface, see the header file ````. Although the mapping methods in the hostrealm interface return a list of one or more realms, only the first realm in the list is currently used by callers. Callers may begin using later responses in the future. Any mapping method may return KRB5_PLUGIN_NO_HANDLE to defer processing to a later module. A module can create and destroy per-library-context state objects using the **init** and **fini** methods. If the module does not need any state, it does not need to implement these methods. The optional **host_realm** method allows a module to determine authoritative realm mappings for a hostname. The first authoritative mapping is used in preference to KDC referrals when getting service credentials. The optional **fallback_realm** method allows a module to determine fallback mappings for a hostname. The first fallback mapping is tried if there is no authoritative mapping for a realm, and KDC referrals failed to produce a successful result. The optional **default_realm** method allows a module to determine the local default realm. If a module implements any of the above methods, it must also implement **free_list** to ensure that memory is allocated and deallocated consistently. krb5-1.22.1/doc/html/_sources/plugindev/general.rst.txt0000664000175000017500000001172215051422642022663 0ustar ghudsonghudsonGeneral plugin concepts ======================= A krb5 dynamic plugin module is a Unix shared object or Windows DLL. Typically, the source code for a dynamic plugin module should live in its own project with a build system using automake_ and libtool_, or tools with similar functionality. A plugin module must define a specific symbol name, which depends on the pluggable interface and module name. For most pluggable interfaces, the exported symbol is a function named ``INTERFACE_MODULE_initvt``, where *INTERFACE* is the name of the pluggable interface and *MODULE* is the name of the module. For these interfaces, it is possible for one shared object or DLL to implement multiple plugin modules, either for the same pluggable interface or for different ones. For example, a shared object could implement both KDC and client preauthentication mechanisms, by exporting functions named ``kdcpreauth_mymech_initvt`` and ``clpreauth_mymech_initvt``. .. note: The profile, locate, and GSSAPI mechglue pluggable interfaces follow different conventions. See the documentation for those interfaces for details. The remainder of this section applies to pluggable interfaces which use the standard conventions. A plugin module implementation should include the header file ````, where *INTERFACE* is the name of the pluggable interface. For instance, a ccselect plugin module implementation should use ``#include ``. .. note: clpreauth and kdcpreauth module implementations should include . initvt functions have the following prototype:: krb5_error_code interface_modname_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); and should do the following: 1. Check that the supplied maj_ver argument is supported by the module. If it is not supported, the function should return KRB5_PLUGIN_VER_NOTSUPP. 2. Cast the supplied vtable pointer to the structure type corresponding to the major version, as documented in the pluggable interface header file. 3. Fill in the structure fields with pointers to method functions and static data, stopping at the field indicated by the supplied minor version. Fields for unimplemented optional methods can be left alone; it is not necessary to initialize them to NULL. In most cases, the context argument will not be used. The initvt function should not allocate memory; think of it as a glorified structure initializer. Each pluggable interface defines methods for allocating and freeing module state if doing so is necessary for the interface. Pluggable interfaces typically include a **name** field in the vtable structure, which should be filled in with a pointer to a string literal containing the module name. Here is an example of what an initvt function might look like for a fictional pluggable interface named fences, for a module named "wicker":: krb5_error_code fences_wicker_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_ccselect_vtable vt; if (maj_ver == 1) { krb5_fences_vtable vt = (krb5_fences_vtable)vtable; vt->name = "wicker"; vt->slats = wicker_slats; vt->braces = wicker_braces; } else if (maj_ver == 2) { krb5_fences_vtable_v2 vt = (krb5_fences_vtable_v2)vtable; vt->name = "wicker"; vt->material = wicker_material; vt->construction = wicker_construction; if (min_ver < 2) return 0; vt->footing = wicker_footing; if (min_ver < 3) return 0; vt->appearance = wicker_appearance; } else { return KRB5_PLUGIN_VER_NOTSUPP; } return 0; } Logging from KDC and kadmind plugin modules ------------------------------------------- Plugin modules for the KDC or kadmind daemons can write to the configured logging outputs (see :ref:`logging`) by calling the **com_err** function. The first argument (*whoami*) is ignored. If the second argument (*code*) is zero, the formatted message is logged at informational severity; otherwise, the formatted message is logged at error severity and includes the error message for the supplied code. Here are examples:: com_err("", 0, "Client message contains %d items", nitems); com_err("", retval, "while decoding client message"); (The behavior described above is new in release 1.17. In prior releases, the *whoami* argument is included for some logging output types, the logged message does not include the usual header for some output types, and the severity for syslog outputs is configured as part of the logging specification, defaulting to error severity.) .. _automake: https://www.gnu.org/software/automake/ .. _libtool: https://www.gnu.org/software/libtool/ krb5-1.22.1/doc/html/_sources/mitK5license.rst.txt0000664000175000017500000000023515051422642021602 0ustar ghudsonghudson.. _mitK5license: MIT Kerberos License information ================================ .. toctree:: :hidden: copyright.rst .. include:: notice.rst krb5-1.22.1/doc/html/_sources/copyright.rst.txt0000664000175000017500000000032415051422642021255 0ustar ghudsonghudsonCopyright ========= Copyright |copy| 1985-2025 by the Massachusetts Institute of Technology and its contributors. All rights reserved. See :ref:`mitK5license` for additional copyright and license information. krb5-1.22.1/doc/html/_sources/appdev/0000775000175000017500000000000015051422713017154 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/appdev/index.rst.txt0000664000175000017500000000033615051422642021636 0ustar ghudsonghudsonFor application developers ========================== .. toctree:: :maxdepth: 1 gssapi.rst y2038.rst h5l_mit_apidiff.rst init_creds.rst princ_handle.rst .. toctree:: :maxdepth: 1 refs/index.rst krb5-1.22.1/doc/html/_sources/appdev/init_creds.rst.txt0000664000175000017500000003116615051422642022657 0ustar ghudsonghudsonInitial credentials =================== Software that performs tasks such as logging users into a computer when they type their Kerberos password needs to get initial credentials (usually ticket granting tickets) from Kerberos. Such software shares some behavior with the :ref:`kinit(1)` program. Whenever a program grants access to a resource (such as a local login session on a desktop computer) based on a user successfully getting initial Kerberos credentials, it must verify those credentials against a secure shared secret (e.g., a host keytab) to ensure that the user credentials actually originate from a legitimate KDC. Failure to perform this verification is a critical vulnerability, because a malicious user can execute the "Zanarotti attack": the user constructs a fake response that appears to come from the legitimate KDC, but whose contents come from an attacker-controlled KDC. Some applications read a Kerberos password over the network (ideally over a secure channel), which they then verify against the KDC. While this technique may be the only practical way to integrate Kerberos into some existing legacy systems, its use is contrary to the original design goals of Kerberos. The function :c:func:`krb5_get_init_creds_password` will get initial credentials for a client using a password. An application that needs to verify the credentials can call :c:func:`krb5_verify_init_creds`. Here is an example of code to obtain and verify TGT credentials, given strings *princname* and *password* for the client principal name and password:: krb5_error_code ret; krb5_creds creds; krb5_principal client_princ = NULL; memset(&creds, 0, sizeof(creds)); ret = krb5_parse_name(context, princname, &client_princ); if (ret) goto cleanup; ret = krb5_get_init_creds_password(context, &creds, client_princ, password, NULL, NULL, 0, NULL, NULL); if (ret) goto cleanup; ret = krb5_verify_init_creds(context, &creds, NULL, NULL, NULL, NULL); cleanup: krb5_free_principal(context, client_princ); krb5_free_cred_contents(context, &creds); return ret; Options for get_init_creds -------------------------- The function :c:func:`krb5_get_init_creds_password` takes an options parameter (which can be a null pointer). Use the function :c:func:`krb5_get_init_creds_opt_alloc` to allocate an options structure, and :c:func:`krb5_get_init_creds_opt_free` to free it. For example:: krb5_error_code ret; krb5_get_init_creds_opt *opt = NULL; krb5_creds creds; memset(&creds, 0, sizeof(creds)); ret = krb5_get_init_creds_opt_alloc(context, &opt); if (ret) goto cleanup; krb5_get_init_creds_opt_set_tkt_life(opt, 24 * 60 * 60); ret = krb5_get_init_creds_password(context, &creds, client_princ, password, NULL, NULL, 0, NULL, opt); if (ret) goto cleanup; cleanup: krb5_get_init_creds_opt_free(context, opt); krb5_free_cred_contents(context, &creds); return ret; Getting anonymous credentials ----------------------------- As of release 1.8, it is possible to obtain fully anonymous or partially anonymous (realm-exposed) credentials, if the KDC supports it. The MIT KDC supports issuing fully anonymous credentials as of release 1.8 if configured appropriately (see :ref:`anonymous_pkinit`), but does not support issuing realm-exposed anonymous credentials at this time. To obtain fully anonymous credentials, call :c:func:`krb5_get_init_creds_opt_set_anonymous` on the options structure to set the anonymous flag, and specify a client principal with the KDC's realm and a single empty data component (the principal obtained by parsing ``@``\ *realmname*). Authentication will take place using anonymous PKINIT; if successful, the client principal of the resulting tickets will be ``WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS``. Here is an example:: krb5_get_init_creds_opt_set_anonymous(opt, 1); ret = krb5_build_principal(context, &client_princ, strlen(myrealm), myrealm, "", (char *)NULL); if (ret) goto cleanup; ret = krb5_get_init_creds_password(context, &creds, client_princ, password, NULL, NULL, 0, NULL, opt); if (ret) goto cleanup; To obtain realm-exposed anonymous credentials, set the anonymous flag on the options structure as above, but specify a normal client principal in order to prove membership in the realm. Authentication will take place as it normally does; if successful, the client principal of the resulting tickets will be ``WELLKNOWN/ANONYMOUS@``\ *realmname*. User interaction ---------------- Authenticating a user usually requires the entry of secret information, such as a password. A password can be supplied directly to :c:func:`krb5_get_init_creds_password` via the *password* parameter, or the application can supply prompter and/or responder callbacks instead. If callbacks are used, the user can also be queried for other secret information such as a PIN, informed of impending password expiration, or prompted to change a password which has expired. Prompter callback ~~~~~~~~~~~~~~~~~ A prompter callback can be specified via the *prompter* and *data* parameters to :c:func:`krb5_get_init_creds_password`. The prompter will be invoked each time the krb5 library has a question to ask or information to present. When the prompter callback is invoked, the *banner* argument (if not null) is intended to be displayed to the user, and the questions to be answered are specified in the *prompts* array. Each prompt contains a text question in the *prompt* field, a *hidden* bit to indicate whether the answer should be hidden from display, and a storage area for the answer in the *reply* field. The callback should fill in each question's ``reply->data`` with the answer, up to a maximum number of ``reply->length`` bytes, and then reset ``reply->length`` to the length of the answer. A prompter callback can call :c:func:`krb5_get_prompt_types` to get an array of type constants corresponding to the prompts, to get programmatic information about the semantic meaning of the questions. :c:func:`krb5_get_prompt_types` may return a null pointer if no prompt type information is available. Text-based applications can use a built-in text prompter implementation by supplying :c:func:`krb5_prompter_posix` as the *prompter* parameter and a null pointer as the *data* parameter. For example:: ret = krb5_get_init_creds_password(context, &creds, client_princ, NULL, krb5_prompter_posix, NULL, 0, NULL, NULL); Responder callback ~~~~~~~~~~~~~~~~~~ A responder callback can be specified through the init_creds options using the :c:func:`krb5_get_init_creds_opt_set_responder` function. Responder callbacks can present a more sophisticated user interface for authentication secrets. The responder callback is usually invoked only once per authentication, with a list of questions produced by all of the allowed preauthentication mechanisms. When the responder callback is invoked, the *rctx* argument can be accessed to obtain the list of questions and to answer them. The :c:func:`krb5_responder_list_questions` function retrieves an array of question types. For each question type, the :c:func:`krb5_responder_get_challenge` function retrieves additional information about the question, if applicable, and the :c:func:`krb5_responder_set_answer` function sets the answer. Responder question types, challenges, and answers are UTF-8 strings. The question type is a well-known string; the meaning of the challenge and answer depend on the question type. If an application does not understand a question type, it cannot interpret the challenge or provide an answer. Failing to answer a question typically results in the prompter callback being used as a fallback. Password question ################# The :c:macro:`KRB5_RESPONDER_QUESTION_PASSWORD` (or ``"password"``) question type requests the user's password. This question does not have a challenge, and the response is simply the password string. One-time password question ########################## The :c:macro:`KRB5_RESPONDER_QUESTION_OTP` (or ``"otp"``) question type requests a choice among one-time password tokens and the PIN and value for the chosen token. The challenge and answer are JSON-encoded strings, but an application can use convenience functions to avoid doing any JSON processing itself. The :c:func:`krb5_responder_otp_get_challenge` function decodes the challenge into a krb5_responder_otp_challenge structure. The :c:func:`krb5_responder_otp_set_answer` function selects one of the token information elements from the challenge and supplies the value and pin for that token. PKINIT password or PIN question ############################### The :c:macro:`KRB5_RESPONDER_QUESTION_PKINIT` (or ``"pkinit"``) question type requests PINs for hardware devices and/or passwords for encrypted credentials which are stored on disk, potentially also supplying information about the state of the hardware devices. The challenge and answer are JSON-encoded strings, but an application can use convenience functions to avoid doing any JSON processing itself. The :c:func:`krb5_responder_pkinit_get_challenge` function decodes the challenges into a krb5_responder_pkinit_challenge structure. The :c:func:`krb5_responder_pkinit_set_answer` function can be used to supply the PIN or password for a particular client credential, and can be called multiple times. Example ####### Here is an example of using a responder callback:: static krb5_error_code my_responder(krb5_context context, void *data, krb5_responder_context rctx) { krb5_error_code ret; krb5_responder_otp_challenge *chl; if (krb5_responder_get_challenge(context, rctx, KRB5_RESPONDER_QUESTION_PASSWORD)) { ret = krb5_responder_set_answer(context, rctx, KRB5_RESPONDER_QUESTION_PASSWORD, "open sesame"); if (ret) return ret; } ret = krb5_responder_otp_get_challenge(context, rctx, &chl); if (ret == 0 && chl != NULL) { ret = krb5_responder_otp_set_answer(context, rctx, 0, "1234", NULL); krb5_responder_otp_challenge_free(context, rctx, chl); if (ret) return ret; } return 0; } static krb5_error_code get_creds(krb5_context context, krb5_principal client_princ) { krb5_error_code ret; krb5_get_init_creds_opt *opt = NULL; krb5_creds creds; memset(&creds, 0, sizeof(creds)); ret = krb5_get_init_creds_opt_alloc(context, &opt); if (ret) goto cleanup; ret = krb5_get_init_creds_opt_set_responder(context, opt, my_responder, NULL); if (ret) goto cleanup; ret = krb5_get_init_creds_password(context, &creds, client_princ, NULL, NULL, NULL, 0, NULL, opt); cleanup: krb5_get_init_creds_opt_free(context, opt); krb5_free_cred_contents(context, &creds); return ret; } Verifying initial credentials ----------------------------- Use the function :c:func:`krb5_verify_init_creds` to verify initial credentials. It takes an options structure (which can be a null pointer). Use :c:func:`krb5_verify_init_creds_opt_init` to initialize the caller-allocated options structure, and :c:func:`krb5_verify_init_creds_opt_set_ap_req_nofail` to set the "nofail" option. For example:: krb5_verify_init_creds_opt vopt; krb5_verify_init_creds_opt_init(&vopt); krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, 1); ret = krb5_verify_init_creds(context, &creds, NULL, NULL, NULL, &vopt); The confusingly named "nofail" option, when set, means that the verification must actually succeed in order for :c:func:`krb5_verify_init_creds` to indicate success. The default state of this option (cleared) means that if there is no key material available to verify the user credentials, the verification will succeed anyway. (The default can be changed by a configuration file setting.) This accommodates a use case where a large number of unkeyed shared desktop workstations need to allow users to log in using Kerberos. The security risks from this practice are mitigated by the absence of valuable state on the shared workstations---any valuable resources that the users would access reside on networked servers. krb5-1.22.1/doc/html/_sources/appdev/h5l_mit_apidiff.rst.txt0000664000175000017500000000354615051422642023560 0ustar ghudsonghudsonDifferences between Heimdal and MIT Kerberos API ================================================ .. tabularcolumns:: |l|l| .. table:: ======================================== ================================================= :c:func:`krb5_auth_con_getaddrs()` H5l: If either of the pointers to local_addr and remote_addr is not NULL, it is freed first and then reallocated before being populated with the content of corresponding address from authentication context. :c:func:`krb5_auth_con_setaddrs()` H5l: If either address is NULL, the previous address remains in place :c:func:`krb5_auth_con_setports()` H5l: Not implemented as of version 1.3.3 :c:func:`krb5_auth_con_setrecvsubkey()` H5l: If either port is NULL, the previous port remains in place :c:func:`krb5_auth_con_setsendsubkey()` H5l: Not implemented as of version 1.3.3 :c:func:`krb5_cc_set_config()` MIT: Before version 1.10 it was assumed that the last argument *data* is ALWAYS non-zero. :c:func:`krb5_cccol_last_change_time()` MIT: not implemented :c:func:`krb5_set_default_realm()` H5l: Caches the computed default realm context field. If the second argument is NULL, it tries to retrieve it from libdefaults or DNS. MIT: Computes the default realm each time if it wasn't explicitly set in the context ======================================== ================================================= krb5-1.22.1/doc/html/_sources/appdev/y2038.rst.txt0000664000175000017500000000246515051422642021321 0ustar ghudsonghudsonYear 2038 considerations for uses of krb5_timestamp =================================================== POSIX time values, which measure the number of seconds since January 1 1970, will exceed the maximum value representable in a signed 32-bit integer in January 2038. This documentation describes considerations for consumers of the MIT krb5 libraries. Applications or libraries which use libkrb5 and consume the timestamps included in credentials or other structures make use of the :c:type:`krb5_timestamp` type. For historical reasons, krb5_timestamp is a signed 32-bit integer, even on platforms where a larger type is natively used to represent time values. To behave properly for time values after January 2038, calling code should cast krb5_timestamp values to uint32_t, and then to time_t:: (time_t)(uint32_t)timestamp Used in this way, krb5_timestamp values can represent time values up until February 2106, provided that the platform uses a 64-bit or larger time_t type. This usage will also remain safe if a later version of MIT krb5 changes krb5_timestamp to an unsigned 32-bit integer. The GSSAPI only uses representations of time intervals, not absolute times. Callers of the GSSAPI should require no changes to behave correctly after January 2038, provided that they use MIT krb5 release 1.16 or later. krb5-1.22.1/doc/html/_sources/appdev/princ_handle.rst.txt0000664000175000017500000000175615051422642023164 0ustar ghudsonghudsonPrincipal manipulation and parsing ================================== Kerberos principal structure .. :c:type:`krb5_principal_data` :c:type:`krb5_principal` .. Create and free principal .. :c:func:`krb5_build_principal()` :c:func:`krb5_build_principal_alloc_va()` :c:func:`krb5_build_principal_ext()` :c:func:`krb5_copy_principal()` :c:func:`krb5_free_principal()` :c:func:`krb5_cc_get_principal()` .. Comparing .. :c:func:`krb5_principal_compare()` :c:func:`krb5_principal_compare_flags()` :c:func:`krb5_principal_compare_any_realm()` :c:func:`krb5_sname_match()` :c:func:`krb5_sname_to_principal()` .. Parsing: .. :c:func:`krb5_parse_name()` :c:func:`krb5_parse_name_flags()` :c:func:`krb5_unparse_name()` :c:func:`krb5_unparse_name_flags()` .. Utilities: .. :c:func:`krb5_is_config_principal()` :c:func:`krb5_kuserok()` :c:func:`krb5_set_password()` :c:func:`krb5_set_password_using_ccache()` :c:func:`krb5_set_principal_realm()` :c:func:`krb5_realm_compare()` .. krb5-1.22.1/doc/html/_sources/appdev/refs/0000775000175000017500000000000015051422712020112 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/appdev/refs/index.rst.txt0000664000175000017500000000024515051422642022574 0ustar ghudsonghudsonComplete reference - API and datatypes ====================================== .. toctree:: :maxdepth: 1 api/index.rst types/index.rst macros/index.rst krb5-1.22.1/doc/html/_sources/appdev/refs/api/0000775000175000017500000000000015051422674020672 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_anonymous_realm.rst.txt0000664000175000017500000000055715051422642026377 0ustar ghudsonghudsonkrb5_anonymous_realm - Return an anonymous realm data. ======================================================== .. .. c:function:: const krb5_data * krb5_anonymous_realm(void None) .. :param: **None** .. .. This function returns constant storage that must not be freed. .. .. seealso:: KRB5_ANONYMOUS_REALMSTR krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_credentials.rst.txt0000664000175000017500000000340715051422642026320 0ustar ghudsonghudsonkrb5_get_credentials - Get an additional ticket. ================================================== .. .. c:function:: krb5_error_code krb5_get_credentials(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds * in_creds, krb5_creds ** out_creds) .. :param: **[in]** **context** - Library context **[in]** **options** - Options **[in]** **ccache** - Credential cache handle **[in]** **in_creds** - Input credentials **[out]** **out_creds** - Output updated credentials .. :retval: - 0 Success :return: - Kerberos error codes .. Use *ccache* or a TGS exchange to get a service ticket matching *in_creds* . Valid values for *options* are: - KRB5_GC_CACHED Search only credential cache for the ticket - KRB5_GC_USER_USER Return a user to user authentication ticket *in_creds* must be non-null. *in_creds->client* and *in_creds->server* must be filled in to specify the client and the server respectively. If any authorization data needs to be requested for the service ticket (such as restrictions on how the ticket can be used), specify it in *in_creds->authdata* ; otherwise set *in_creds->authdata* to NULL. The session key type is specified in *in_creds->keyblock.enctype* , if it is nonzero. If *in_creds->times.endtime* is specified, it is used as the requested expiration date if a TGS request is made. If *in_creds->times.endtime* is set to 0, the latest possible expiration date will be requested. The KDC or cache may return a ticket with an earlier expiration date. Any returned ticket and intermediate ticket-granting tickets are stored in *ccache* . Use krb5_free_creds() to free *out_creds* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_unparse_name_flags_ext.rst.txt0000664000175000017500000000141615051422642027673 0ustar ghudsonghudsonkrb5_unparse_name_flags_ext - Convert krb5_principal structure to string format with flags. ============================================================================================= .. .. c:function:: krb5_error_code krb5_unparse_name_flags_ext(krb5_context context, krb5_const_principal principal, int flags, char ** name, unsigned int * size) .. :param: **[in]** **context** - Library context **[in]** **principal** - Principal **[in]** **flags** - Flags **[out]** **name** - Single string format of principal name **[out]** **size** - Size of unparsed name buffer .. :retval: - 0 Success :return: - Kerberos error codes. On failure name is set to NULL .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_permitted_enctypes.rst.txt0000664000175000017500000000144515051422642027732 0ustar ghudsonghudsonkrb5_get_permitted_enctypes - Return a list of encryption types permitted for session keys. ============================================================================================= .. .. c:function:: krb5_error_code krb5_get_permitted_enctypes(krb5_context context, krb5_enctype ** ktypes) .. :param: **[in]** **context** - Library context **[out]** **ktypes** - Zero-terminated list of encryption types .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function returns the list of encryption types permitted for session keys within *context* , as determined by configuration or by a previous call to krb5_set_default_tgs_enctypes(). Use krb5_free_enctypes() to free *ktypes* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_remove_entry.rst.txt0000664000175000017500000000111215051422642026367 0ustar ghudsonghudsonkrb5_kt_remove_entry - Remove an entry from a key table. ========================================================== .. .. c:function:: krb5_error_code krb5_kt_remove_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry * entry) .. :param: **[in]** **context** - Library context **[in]** **id** - Key table handle **[in]** **entry** - Entry to remove from key table .. :retval: - 0 Success - KRB5_KT_NOWRITE Key table is not writable :return: - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_default_tgs_enctypes.rst.txt0000664000175000017500000000145115051422642030247 0ustar ghudsonghudsonkrb5_set_default_tgs_enctypes - Set default TGS encryption types in a krb5_context structure. =============================================================================================== .. .. c:function:: krb5_error_code krb5_set_default_tgs_enctypes(krb5_context context, const krb5_enctype * etypes) .. :param: **[in]** **context** - Library context **[in]** **etypes** - Encryption type(s) to set .. :retval: - 0 Success - KRB5_PROG_ETYPE_NOSUPP Program lacks support for encryption type :return: - Kerberos error codes .. This function sets the default enctype list for TGS requests made using *context* to *etypes* . .. .. note:: This overrides the default list (from config file or built-in). krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_fx_cf2_simple.rst.txt0000664000175000017500000000215315051422642026203 0ustar ghudsonghudsonkrb5_c_fx_cf2_simple - Compute the KRB-FX-CF2 combination of two keys and pepper strings. =========================================================================================== .. .. c:function:: krb5_error_code krb5_c_fx_cf2_simple(krb5_context context, const krb5_keyblock * k1, const char * pepper1, const krb5_keyblock * k2, const char * pepper2, krb5_keyblock ** out) .. :param: **[in]** **context** - Library context **[in]** **k1** - KDC contribution key **[in]** **pepper1** - String"PKINIT" **[in]** **k2** - Reply key **[in]** **pepper2** - String"KeyExchange" **[out]** **out** - Output key .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function computes the KRB-FX-CF2 function over its inputs and places the results in a newly allocated keyblock. This function is simple in that it assumes that *pepper1* and *pepper2* are C strings with no internal nulls and that the enctype of the result will be the same as that of *k1* . *k1* and *k2* may be of different enctypes. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_setflags.rst.txt0000664000175000017500000000142315051422642026650 0ustar ghudsonghudsonkrb5_auth_con_setflags - Set a flags field in a krb5_auth_context structure. ============================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_setflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 flags) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **flags** - Flags bit mask .. :retval: - 0 (always) .. Valid values for *flags* are: - KRB5_AUTH_CONTEXT_DO_TIME Use timestamps - KRB5_AUTH_CONTEXT_RET_TIME Save timestamps - KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers - KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_set_req_cksumtype.rst.txt0000664000175000017500000000127615051422642030614 0ustar ghudsonghudsonkrb5_auth_con_set_req_cksumtype - Set checksum type in an an auth context. ============================================================================ .. .. c:function:: krb5_error_code krb5_auth_con_set_req_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **cksumtype** - Checksum type .. :retval: - 0 Success. Otherwise - Kerberos error codes .. This function sets the checksum type in *auth_context* to be used by krb5_mk_req() for the authenticator checksum. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_gen_new.rst.txt0000664000175000017500000000033215051422642025245 0ustar ghudsonghudsonkrb5_cc_gen_new =============== .. .. c:function:: krb5_error_code krb5_cc_gen_new(krb5_context context, krb5_ccache * cache) .. :param: **context** **cache** .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_set_checksum_func.rst.txt0000664000175000017500000000142415051422642030531 0ustar ghudsonghudsonkrb5_auth_con_set_checksum_func - Set a checksum callback in an auth context. =============================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_set_checksum_func(krb5_context context, krb5_auth_context auth_context, krb5_mk_req_checksum_func func, void * data) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **func** - Checksum callback **[in]** **data** - Callback argument .. :retval: - 0 (always) .. Set a callback to obtain checksum data in krb5_mk_req(). The callback will be invoked after the subkey and local sequence number are stored in *auth_context* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_trace_callback.rst.txt0000664000175000017500000000225415051422642026750 0ustar ghudsonghudsonkrb5_set_trace_callback - Specify a callback function for trace events. ========================================================================= .. .. c:function:: krb5_error_code krb5_set_trace_callback(krb5_context context, krb5_trace_callback fn, void * cb_data) .. :param: **[in]** **context** - Library context **[in]** **fn** - Callback function **[in]** **cb_data** - Callback data .. :return: - Returns KRB5_TRACE_NOSUPP if tracing is not supported in the library (unless fn is NULL). .. Specify a callback for trace events occurring in krb5 operations performed within *context* . *fn* will be invoked with *context* as the first argument, *cb_data* as the last argument, and a pointer to a krb5_trace_info as the second argument. If the trace callback is reset via this function or *context* is destroyed, *fn* will be invoked with a NULL second argument so it can clean up *cb_data* . Supply a NULL value for *fn* to disable trace callbacks within *context* . .. .. note:: This function overrides the information passed through the *KRB5_TRACE* environment variable. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_encrypt.rst.txt0000664000175000017500000000262415051422642025152 0ustar ghudsonghudsonkrb5_c_encrypt - Encrypt data using a key (operates on keyblock). =================================================================== .. .. c:function:: krb5_error_code krb5_c_encrypt(krb5_context context, const krb5_keyblock * key, krb5_keyusage usage, const krb5_data * cipher_state, const krb5_data * input, krb5_enc_data * output) .. :param: **[in]** **context** - Library context **[in]** **key** - Encryption key **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[inout]** **cipher_state** - Cipher state; specify NULL if not needed **[in]** **input** - Data to be encrypted **[out]** **output** - Encrypted data .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function encrypts the data block *input* and stores the output into *output* . The actual encryption key will be derived from *key* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. .. .. note:: The caller must initialize *output* and allocate at least enough space for the result (using krb5_c_encrypt_length() to determine the amount of space needed). *output->length* will be set to the actual length of the ciphertext. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_checksum.rst.txt0000664000175000017500000000065115051422642025765 0ustar ghudsonghudsonkrb5_free_checksum - Free a krb5_checksum structure. ====================================================== .. .. c:function:: void krb5_free_checksum(krb5_context context, krb5_checksum * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Checksum structure to be freed .. .. This function frees the contents of *val* and the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_keytab.rst.txt0000664000175000017500000000236715051422642027511 0ustar ghudsonghudsonkrb5_get_init_creds_keytab - Get initial credentials using a key table. ========================================================================= .. .. c:function:: krb5_error_code krb5_get_init_creds_keytab(krb5_context context, krb5_creds * creds, krb5_principal client, krb5_keytab arg_keytab, krb5_deltat start_time, const char * in_tkt_service, krb5_get_init_creds_opt * k5_gic_options) .. :param: **[in]** **context** - Library context **[out]** **creds** - New credentials **[in]** **client** - Client principal **[in]** **arg_keytab** - Key table handle **[in]** **start_time** - Time when ticket becomes valid (0 for now) **[in]** **in_tkt_service** - Service name of initial credentials (or NULL) **[in]** **k5_gic_options** - Initial credential options .. :retval: - 0 Success :return: - Kerberos error codes .. This function requests KDC for an initial credentials for *client* using a client key stored in *arg_keytab* . If *in_tkt_service* is specified, it is parsed as a principal name (with the realm ignored) and used as the service principal for the request; otherwise the ticket-granting service is used. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_build_principal_ext.rst.txt0000664000175000017500000000230515051422642027200 0ustar ghudsonghudsonkrb5_build_principal_ext - Build a principal name using length-counted strings. ================================================================================= .. .. c:function:: krb5_error_code krb5_build_principal_ext(krb5_context context, krb5_principal * princ, unsigned int rlen, const char * realm, ... ) .. :param: **[in]** **context** - Library context **[out]** **princ** - Principal name **[in]** **rlen** - Realm name length **[in]** **realm** - Realm name .. :retval: - 0 Success :return: - Kerberos error codes .. This function creates a principal from a length-counted string and a variable-length list of length-counted components. The list of components ends with the first 0 length argument (so it is not possible to specify an empty component with this function). Call krb5_free_principal() to free allocated memory for principal when it is no longer needed. Beginning with release 1.20, the name type of the principal will be inferred as **KRB5_NT_SRV_INST** or **KRB5_NT_WELLKNOWN** based on the principal name. The type will be **KRB5_NT_PRINCIPAL** if a type cannot be inferred. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_parse_name_flags.rst.txt0000664000175000017500000000271615051422642026454 0ustar ghudsonghudsonkrb5_parse_name_flags - Convert a string principal name to a krb5_principal with flags. ========================================================================================= .. .. c:function:: krb5_error_code krb5_parse_name_flags(krb5_context context, const char * name, int flags, krb5_principal * principal_out) .. :param: **[in]** **context** - Library context **[in]** **name** - String representation of a principal name **[in]** **flags** - Flag **[out]** **principal_out** - New principal .. :retval: - 0 Success :return: - Kerberos error codes .. Similar to krb5_parse_name(), this function converts a single-string representation of a principal name to a krb5_principal structure. The following flags are valid: - KRB5_PRINCIPAL_PARSE_NO_REALM - no realm must be present in *name* - KRB5_PRINCIPAL_PARSE_REQUIRE_REALM - realm must be present in *name* - KRB5_PRINCIPAL_PARSE_ENTERPRISE - create single-component enterprise principal - KRB5_PRINCIPAL_PARSE_IGNORE_REALM - ignore realm if present in *name* If **KRB5_PRINCIPAL_PARSE_NO_REALM** or **KRB5_PRINCIPAL_PARSE_IGNORE_REALM** is specified in *flags* , the realm of the new principal will be empty. Otherwise, the default realm for *context* will be used if *name* does not specify a realm. Use krb5_free_principal() to free *principal_out* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_find_authdata.rst.txt0000664000175000017500000000215115051422642025752 0ustar ghudsonghudsonkrb5_find_authdata - Find authorization data elements. ======================================================== .. .. c:function:: krb5_error_code krb5_find_authdata(krb5_context context, krb5_authdata *const * ticket_authdata, krb5_authdata *const * ap_req_authdata, krb5_authdatatype ad_type, krb5_authdata *** results) .. :param: **[in]** **context** - Library context **[in]** **ticket_authdata** - Authorization data list from ticket **[in]** **ap_req_authdata** - Authorization data list from AP request **[in]** **ad_type** - Authorization data type to find **[out]** **results** - List of matching entries .. .. This function searches *ticket_authdata* and *ap_req_authdata* for elements of type *ad_type* . Either input list may be NULL, in which case it will not be searched; otherwise, the input lists must be terminated by NULL entries. This function will search inside AD-IF-RELEVANT containers if found in either list. Use krb5_free_authdata() to free *results* when it is no longer needed. .. .. note:: New in 1.10 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_password_using_ccache.rst.txt0000664000175000017500000000306415051422642030373 0ustar ghudsonghudsonkrb5_set_password_using_ccache - Set a password for a principal using cached credentials. =========================================================================================== .. .. c:function:: krb5_error_code krb5_set_password_using_ccache(krb5_context context, krb5_ccache ccache, const char * newpw, krb5_principal change_password_for, int * result_code, krb5_data * result_code_string, krb5_data * result_string) .. :param: **[in]** **context** - Library context **[in]** **ccache** - Credential cache **[in]** **newpw** - New password **[in]** **change_password_for** - Change the password for this principal **[out]** **result_code** - Numeric error code from server **[out]** **result_code_string** - String equivalent to *result_code* **[out]** **result_string** - Data returned from the remote system .. :retval: - 0 Success :return: - Kerberos error codes .. This function uses the cached credentials from *ccache* to set the password *newpw* for the principal *change_password_for* . It implements RFC 3244 set password operation (interoperable with MS Windows implementations) using the credential cache. The error code and strings are returned in *result_code* , *result_code_string* and *result_string* . .. .. note:: If *change_password_for* is set to NULL, the change is performed on the default principal in *ccache* . If *change_password_for* is nonnull, the change is performed on the specified principal. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_remove_cred.rst.txt0000664000175000017500000000153215051422642026120 0ustar ghudsonghudsonkrb5_cc_remove_cred - Remove credentials from a credential cache. =================================================================== .. .. c:function:: krb5_error_code krb5_cc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds * creds) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[in]** **flags** - Bitwise-ORed search flags **[in]** **creds** - Credentials to be matched .. :retval: - KRB5_CC_NOSUPP Not implemented for this cache type :return: - No matches found; Data cannot be deleted; Kerberos error codes .. This function accepts the same flag values as krb5_cc_retrieve_cred(). .. .. warning:: This function is not implemented for some cache types. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_mk_rep_dce.rst.txt0000664000175000017500000000117415051422642025253 0ustar ghudsonghudsonkrb5_mk_rep_dce - Format and encrypt a KRB_AP_REP message for DCE RPC. ======================================================================== .. .. c:function:: krb5_error_code krb5_mk_rep_dce(krb5_context context, krb5_auth_context auth_context, krb5_data * outbuf) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **outbuf** - **AP-REP** message .. :retval: - 0 Success; otherwise - Kerberos error codes .. Use krb5_free_data_contents() to free *outbuf* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_credentials_validate.rst.txt0000664000175000017500000000071115051422642030164 0ustar ghudsonghudsonkrb5_get_credentials_validate ============================= .. .. c:function:: krb5_error_code krb5_get_credentials_validate(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds * in_creds, krb5_creds ** out_creds) .. :param: **context** **options** **ccache** **in_creds** **out_creds** .. .. DEPRECATED Replaced by krb5_get_validated_creds. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_allow_weak_crypto.rst.txt0000664000175000017500000000113415051422642026704 0ustar ghudsonghudsonkrb5_allow_weak_crypto - Allow the application to override the profile's allow_weak_crypto setting. ===================================================================================================== .. .. c:function:: krb5_error_code krb5_allow_weak_crypto(krb5_context context, krb5_boolean enable) .. :param: **[in]** **context** - Library context **[in]** **enable** - Boolean flag .. :retval: - 0 (always) .. This function allows an application to override the allow_weak_crypto setting. It is primarily for use by aklog. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_add_buffer.rst.txt0000664000175000017500000000215615051422642026070 0ustar ghudsonghudsonkrb5_pac_add_buffer - Add a buffer to a PAC handle. ===================================================== .. .. c:function:: krb5_error_code krb5_pac_add_buffer(krb5_context context, krb5_pac pac, krb5_ui_4 type, const krb5_data * data) .. :param: **[in]** **context** - Library context **[in]** **pac** - PAC handle **[in]** **type** - Buffer type **[in]** **data** - contents .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function adds a buffer of type *type* and contents *data* to *pac* if there isn't already a buffer of this type present. The valid values of *type* is one of the following: - KRB5_PAC_LOGON_INFO - Logon information - KRB5_PAC_CREDENTIALS_INFO - Credentials information - KRB5_PAC_SERVER_CHECKSUM - Server checksum - KRB5_PAC_PRIVSVR_CHECKSUM - KDC checksum - KRB5_PAC_CLIENT_INFO - Client name and ticket information - KRB5_PAC_DELEGATION_INFO - Constrained delegation information - KRB5_PAC_UPN_DNS_INFO - User principal name and DNS information .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_cred_contents.rst.txt0000664000175000017500000000073715051422642027022 0ustar ghudsonghudsonkrb5_free_cred_contents - Free the contents of a krb5_creds structure. ======================================================================== .. .. c:function:: void krb5_free_cred_contents(krb5_context context, krb5_creds * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Credential structure to free contents of .. .. This function frees the contents of *val* , but not the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_kdc_send_hook.rst.txt0000664000175000017500000000131415051422642026624 0ustar ghudsonghudsonkrb5_set_kdc_send_hook - Set a KDC pre-send hook function. ============================================================ .. .. c:function:: void krb5_set_kdc_send_hook(krb5_context context, krb5_pre_send_fn send_hook, void * data) .. :param: **[in]** **context** - Library context **[in]** **send_hook** - Hook function (or NULL to disable the hook) **[in]** **data** - Callback data to be passed to *send_hook* .. .. *send_hook* will be called before messages are sent to KDCs by library functions such as krb5_get_credentials(). The hook function may inspect, override, or synthesize its own reply to the message. .. .. note:: New in 1.15 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getlocalsubkey.rst.txt0000664000175000017500000000060215051422642030053 0ustar ghudsonghudsonkrb5_auth_con_getlocalsubkey ============================ .. .. c:function:: krb5_error_code krb5_auth_con_getlocalsubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock ** keyblock) .. :param: **context** **auth_context** **keyblock** .. .. DEPRECATED Replaced by krb5_auth_con_getsendsubkey(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_step.rst.txt0000664000175000017500000000323215051422642026336 0ustar ghudsonghudsonkrb5_init_creds_step - Get the next KDC request for acquiring initial credentials. ==================================================================================== .. .. c:function:: krb5_error_code krb5_init_creds_step(krb5_context context, krb5_init_creds_context ctx, krb5_data * in, krb5_data * out, krb5_data * realm, unsigned int * flags) .. :param: **[in]** **context** - Library context **[in]** **ctx** - Initial credentials context **[in]** **in** - KDC response (empty on the first call) **[out]** **out** - Next KDC request **[out]** **realm** - Realm for next KDC request **[out]** **flags** - Output flags .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function constructs the next KDC request in an initial credential exchange, allowing the caller to control the transport of KDC requests and replies. On the first call, *in* should be set to an empty buffer; on subsequent calls, it should be set to the KDC's reply to the previous request. If more requests are needed, *flags* will be set to KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in *out* . If no more requests are needed, *flags* will not contain KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and *out* will be empty. If this function returns **KRB5KRB_ERR_RESPONSE_TOO_BIG** , the caller should transmit the next request using TCP rather than UDP. If this function returns any other error, the initial credential exchange has failed. *context* must be the same as the one passed to krb5_init_creds_init() for this initial credentials context. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/index.rst.txt0000664000175000017500000002673215051422642023356 0ustar ghudsonghudsonkrb5 API ======== Frequently used public interfaces ---------------------------------- .. toctree:: :maxdepth: 1 krb5_build_principal.rst krb5_build_principal_alloc_va.rst krb5_build_principal_ext.rst krb5_cc_close.rst krb5_cc_default.rst krb5_cc_default_name.rst krb5_cc_destroy.rst krb5_cc_dup.rst krb5_cc_get_name.rst krb5_cc_get_principal.rst krb5_cc_get_type.rst krb5_cc_initialize.rst krb5_cc_new_unique.rst krb5_cc_resolve.rst krb5_change_password.rst krb5_chpw_message.rst krb5_expand_hostname.rst krb5_free_config_files.rst krb5_free_context.rst krb5_free_error_message.rst krb5_free_principal.rst krb5_fwd_tgt_creds.rst krb5_get_default_realm.rst krb5_get_error_message.rst krb5_get_host_realm.rst krb5_get_credentials.rst krb5_get_default_config_files.rst krb5_get_fallback_host_realm.rst krb5_get_init_creds_keytab.rst krb5_get_init_creds_opt_alloc.rst krb5_get_init_creds_opt_free.rst krb5_get_init_creds_opt_get_fast_flags.rst krb5_get_init_creds_opt_set_address_list.rst krb5_get_init_creds_opt_set_anonymous.rst krb5_get_init_creds_opt_set_canonicalize.rst krb5_get_init_creds_opt_set_change_password_prompt.rst krb5_get_init_creds_opt_set_etype_list.rst krb5_get_init_creds_opt_set_expire_callback.rst krb5_get_init_creds_opt_set_fast_ccache.rst krb5_get_init_creds_opt_set_fast_ccache_name.rst krb5_get_init_creds_opt_set_fast_flags.rst krb5_get_init_creds_opt_set_forwardable.rst krb5_get_init_creds_opt_set_in_ccache.rst krb5_get_init_creds_opt_set_out_ccache.rst krb5_get_init_creds_opt_set_pa.rst krb5_get_init_creds_opt_set_pac_request.rst krb5_get_init_creds_opt_set_preauth_list.rst krb5_get_init_creds_opt_set_proxiable.rst krb5_get_init_creds_opt_set_renew_life.rst krb5_get_init_creds_opt_set_responder.rst krb5_get_init_creds_opt_set_salt.rst krb5_get_init_creds_opt_set_tkt_life.rst krb5_get_init_creds_password.rst krb5_get_profile.rst krb5_get_prompt_types.rst krb5_get_renewed_creds.rst krb5_get_validated_creds.rst krb5_init_context.rst krb5_init_secure_context.rst krb5_is_config_principal.rst krb5_is_thread_safe.rst krb5_kt_close.rst krb5_kt_client_default.rst krb5_kt_default.rst krb5_kt_default_name.rst krb5_kt_dup.rst krb5_kt_get_name.rst krb5_kt_get_type.rst krb5_kt_resolve.rst krb5_kuserok.rst krb5_parse_name.rst krb5_parse_name_flags.rst krb5_principal_compare.rst krb5_principal_compare_any_realm.rst krb5_principal_compare_flags.rst krb5_prompter_posix.rst krb5_realm_compare.rst krb5_responder_get_challenge.rst krb5_responder_list_questions.rst krb5_responder_set_answer.rst krb5_responder_otp_get_challenge.rst krb5_responder_otp_set_answer.rst krb5_responder_otp_challenge_free.rst krb5_responder_pkinit_get_challenge.rst krb5_responder_pkinit_set_answer.rst krb5_responder_pkinit_challenge_free.rst krb5_set_default_realm.rst krb5_set_password.rst krb5_set_password_using_ccache.rst krb5_set_principal_realm.rst krb5_set_trace_callback.rst krb5_set_trace_filename.rst krb5_sname_match.rst krb5_sname_to_principal.rst krb5_unparse_name.rst krb5_unparse_name_ext.rst krb5_unparse_name_flags.rst krb5_unparse_name_flags_ext.rst krb5_us_timeofday.rst krb5_verify_authdata_kdc_issued.rst Rarely used public interfaces -------------------------------- .. toctree:: :maxdepth: 1 krb5_425_conv_principal.rst krb5_524_conv_principal.rst krb5_address_compare.rst krb5_address_order.rst krb5_address_search.rst krb5_allow_weak_crypto.rst krb5_aname_to_localname.rst krb5_anonymous_principal.rst krb5_anonymous_realm.rst krb5_appdefault_boolean.rst krb5_appdefault_string.rst krb5_auth_con_free.rst krb5_auth_con_genaddrs.rst krb5_auth_con_get_checksum_func.rst krb5_auth_con_getaddrs.rst krb5_auth_con_getauthenticator.rst krb5_auth_con_getflags.rst krb5_auth_con_getkey.rst krb5_auth_con_getkey_k.rst krb5_auth_con_getlocalseqnumber.rst krb5_auth_con_getrcache.rst krb5_auth_con_getrecvsubkey.rst krb5_auth_con_getrecvsubkey_k.rst krb5_auth_con_getremoteseqnumber.rst krb5_auth_con_getsendsubkey.rst krb5_auth_con_getsendsubkey_k.rst krb5_auth_con_init.rst krb5_auth_con_set_checksum_func.rst krb5_auth_con_set_req_cksumtype.rst krb5_auth_con_setaddrs.rst krb5_auth_con_setflags.rst krb5_auth_con_setports.rst krb5_auth_con_setrcache.rst krb5_auth_con_setrecvsubkey.rst krb5_auth_con_setrecvsubkey_k.rst krb5_auth_con_setsendsubkey.rst krb5_auth_con_setsendsubkey_k.rst krb5_auth_con_setuseruserkey.rst krb5_cc_cache_match.rst krb5_cc_copy_creds.rst krb5_cc_end_seq_get.rst krb5_cc_get_config.rst krb5_cc_get_flags.rst krb5_cc_get_full_name.rst krb5_cc_move.rst krb5_cc_next_cred.rst krb5_cc_remove_cred.rst krb5_cc_retrieve_cred.rst krb5_cc_select.rst krb5_cc_set_config.rst krb5_cc_set_default_name.rst krb5_cc_set_flags.rst krb5_cc_start_seq_get.rst krb5_cc_store_cred.rst krb5_cc_support_switch.rst krb5_cc_switch.rst krb5_cccol_cursor_free.rst krb5_cccol_cursor_new.rst krb5_cccol_cursor_next.rst krb5_cccol_have_content.rst krb5_clear_error_message.rst krb5_check_clockskew.rst krb5_copy_addresses.rst krb5_copy_authdata.rst krb5_copy_authenticator.rst krb5_copy_checksum.rst krb5_copy_context.rst krb5_copy_creds.rst krb5_copy_data.rst krb5_copy_error_message.rst krb5_copy_keyblock.rst krb5_copy_keyblock_contents.rst krb5_copy_principal.rst krb5_copy_ticket.rst krb5_find_authdata.rst krb5_free_addresses.rst krb5_free_ap_rep_enc_part.rst krb5_free_authdata.rst krb5_free_authenticator.rst krb5_free_cred_contents.rst krb5_free_creds.rst krb5_free_data.rst krb5_free_data_contents.rst krb5_free_default_realm.rst krb5_free_enctypes.rst krb5_free_error.rst krb5_free_host_realm.rst krb5_free_keyblock.rst krb5_free_keyblock_contents.rst krb5_free_keytab_entry_contents.rst krb5_free_string.rst krb5_free_ticket.rst krb5_free_unparsed_name.rst krb5_get_etype_info.rst krb5_get_permitted_enctypes.rst krb5_get_server_rcache.rst krb5_get_time_offsets.rst krb5_init_context_profile.rst krb5_init_creds_free.rst krb5_init_creds_get.rst krb5_init_creds_get_creds.rst krb5_init_creds_get_error.rst krb5_init_creds_get_times.rst krb5_init_creds_init.rst krb5_init_creds_set_keytab.rst krb5_init_creds_set_password.rst krb5_init_creds_set_service.rst krb5_init_creds_step.rst krb5_init_keyblock.rst krb5_is_referral_realm.rst krb5_kdc_sign_ticket.rst krb5_kdc_verify_ticket.rst krb5_kt_add_entry.rst krb5_kt_end_seq_get.rst krb5_kt_get_entry.rst krb5_kt_have_content.rst krb5_kt_next_entry.rst krb5_kt_read_service_key.rst krb5_kt_remove_entry.rst krb5_kt_start_seq_get.rst krb5_make_authdata_kdc_issued.rst krb5_marshal_credentials.rst krb5_merge_authdata.rst krb5_mk_1cred.rst krb5_mk_error.rst krb5_mk_ncred.rst krb5_mk_priv.rst krb5_mk_rep.rst krb5_mk_rep_dce.rst krb5_mk_req.rst krb5_mk_req_extended.rst krb5_mk_safe.rst krb5_os_localaddr.rst krb5_pac_add_buffer.rst krb5_pac_free.rst krb5_pac_get_buffer.rst krb5_pac_get_types.rst krb5_pac_init.rst krb5_pac_parse.rst krb5_pac_sign.rst krb5_pac_sign_ext.rst krb5_pac_verify.rst krb5_pac_verify_ext.rst krb5_pac_get_client_info.rst krb5_prepend_error_message.rst krb5_principal2salt.rst krb5_rd_cred.rst krb5_rd_error.rst krb5_rd_priv.rst krb5_rd_rep.rst krb5_rd_rep_dce.rst krb5_rd_req.rst krb5_rd_safe.rst krb5_read_password.rst krb5_salttype_to_string.rst krb5_server_decrypt_ticket_keytab.rst krb5_set_default_tgs_enctypes.rst krb5_set_error_message.rst krb5_set_kdc_recv_hook.rst krb5_set_kdc_send_hook.rst krb5_set_real_time.rst krb5_string_to_cksumtype.rst krb5_string_to_deltat.rst krb5_string_to_enctype.rst krb5_string_to_salttype.rst krb5_string_to_timestamp.rst krb5_timeofday.rst krb5_timestamp_to_sfstring.rst krb5_timestamp_to_string.rst krb5_tkt_creds_free.rst krb5_tkt_creds_get.rst krb5_tkt_creds_get_creds.rst krb5_tkt_creds_get_times.rst krb5_tkt_creds_init.rst krb5_tkt_creds_step.rst krb5_unmarshal_credentials.rst krb5_verify_init_creds.rst krb5_verify_init_creds_opt_init.rst krb5_verify_init_creds_opt_set_ap_req_nofail.rst krb5_vprepend_error_message.rst krb5_vset_error_message.rst krb5_vwrap_error_message.rst krb5_wrap_error_message.rst Public interfaces that should not be called directly ------------------------------------------------------- .. toctree:: :maxdepth: 1 krb5_c_block_size.rst krb5_c_checksum_length.rst krb5_c_crypto_length.rst krb5_c_crypto_length_iov.rst krb5_c_decrypt.rst krb5_c_decrypt_iov.rst krb5_c_derive_prfplus.rst krb5_c_encrypt.rst krb5_c_encrypt_iov.rst krb5_c_encrypt_length.rst krb5_c_enctype_compare.rst krb5_c_free_state.rst krb5_c_fx_cf2_simple.rst krb5_c_init_state.rst krb5_c_is_coll_proof_cksum.rst krb5_c_is_keyed_cksum.rst krb5_c_keyed_checksum_types.rst krb5_c_keylengths.rst krb5_c_make_checksum.rst krb5_c_make_checksum_iov.rst krb5_c_make_random_key.rst krb5_c_padding_length.rst krb5_c_prf.rst krb5_c_prfplus.rst krb5_c_prf_length.rst krb5_c_random_add_entropy.rst krb5_c_random_make_octets.rst krb5_c_random_os_entropy.rst krb5_c_random_to_key.rst krb5_c_string_to_key.rst krb5_c_string_to_key_with_params.rst krb5_c_valid_cksumtype.rst krb5_c_valid_enctype.rst krb5_c_verify_checksum.rst krb5_c_verify_checksum_iov.rst krb5_cksumtype_to_string.rst krb5_decode_authdata_container.rst krb5_decode_ticket.rst krb5_deltat_to_string.rst krb5_encode_authdata_container.rst krb5_enctype_to_name.rst krb5_enctype_to_string.rst krb5_free_checksum.rst krb5_free_checksum_contents.rst krb5_free_cksumtypes.rst krb5_free_tgt_creds.rst krb5_k_create_key.rst krb5_k_decrypt.rst krb5_k_decrypt_iov.rst krb5_k_encrypt.rst krb5_k_encrypt_iov.rst krb5_k_free_key.rst krb5_k_key_enctype.rst krb5_k_key_keyblock.rst krb5_k_make_checksum.rst krb5_k_make_checksum_iov.rst krb5_k_prf.rst krb5_k_reference_key.rst krb5_k_verify_checksum.rst krb5_k_verify_checksum_iov.rst Legacy convenience interfaces ------------------------------ .. toctree:: :maxdepth: 1 krb5_recvauth.rst krb5_recvauth_version.rst krb5_sendauth.rst Deprecated public interfaces ------------------------------ .. toctree:: :maxdepth: 1 krb5_524_convert_creds.rst krb5_auth_con_getlocalsubkey.rst krb5_auth_con_getremotesubkey.rst krb5_auth_con_initivector.rst krb5_build_principal_va.rst krb5_c_random_seed.rst krb5_calculate_checksum.rst krb5_checksum_size.rst krb5_encrypt.rst krb5_decrypt.rst krb5_eblock_enctype.rst krb5_encrypt_size.rst krb5_finish_key.rst krb5_finish_random_key.rst krb5_cc_gen_new.rst krb5_get_credentials_renew.rst krb5_get_credentials_validate.rst krb5_get_in_tkt_with_password.rst krb5_get_in_tkt_with_skey.rst krb5_get_in_tkt_with_keytab.rst krb5_get_init_creds_opt_init.rst krb5_init_random_key.rst krb5_kt_free_entry.rst krb5_random_key.rst krb5_process_key.rst krb5_string_to_key.rst krb5_use_enctype.rst krb5_verify_checksum.rst krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_vprepend_error_message.rst.txt0000664000175000017500000000127115051422642027721 0ustar ghudsonghudsonkrb5_vprepend_error_message - Add a prefix to the message for an error code using a va_list. ============================================================================================== .. .. c:function:: void krb5_vprepend_error_message(krb5_context ctx, krb5_error_code code, const char * fmt, va_list args) .. :param: **[in]** **ctx** - Library context **[in]** **code** - Error code **[in]** **fmt** - Format string for error message prefix **[in]** **args** - List of vprintf(3) style arguments .. .. This function is similar to krb5_prepend_error_message(), but uses a va_list instead of variadic arguments. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_out_ccache.rst.txt0000664000175000017500000000154115051422642032055 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_out_ccache - Set an output credential cache in initial credential options. ======================================================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_set_out_ccache(krb5_context context, krb5_get_init_creds_opt * opt, krb5_ccache ccache) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options **[in]** **ccache** - Credential cache handle .. .. If an output credential cache is set, then the krb5_get_init_creds family of APIs will write credentials to it. Setting an output ccache is desirable both because it simplifies calling code and because it permits the krb5_get_init_creds APIs to write out configuration information about the realm to the ccache. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_get_type.rst.txt0000664000175000017500000000071115051422642025475 0ustar ghudsonghudsonkrb5_kt_get_type - Return the type of a key table. ==================================================== .. .. c:function:: const char * krb5_kt_get_type(krb5_context context, krb5_keytab keytab) .. :param: **[in]** **context** - Library context **[in]** **keytab** - Key table handle .. :return: - The type of a key table as an alias that must not be modified or freed by the caller. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_recvauth_version.rst.txt0000664000175000017500000000220215051422642026542 0ustar ghudsonghudsonkrb5_recvauth_version - Server function for sendauth protocol with version parameter. ======================================================================================= .. .. c:function:: krb5_error_code krb5_recvauth_version(krb5_context context, krb5_auth_context * auth_context, krb5_pointer fd, krb5_principal server, krb5_int32 flags, krb5_keytab keytab, krb5_ticket ** ticket, krb5_data * version) .. :param: **[in]** **context** - Library context **[inout]** **auth_context** - Pre-existing or newly created auth context **[in]** **fd** - File descriptor **[in]** **server** - Server principal (NULL for any in *keytab* ) **[in]** **flags** - Additional specifications **[in]** **keytab** - Decryption key **[out]** **ticket** - Ticket (NULL if not needed) **[out]** **version** - sendauth protocol version (NULL if not needed) .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function is similar to krb5_recvauth() with the additional output information place into *version* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_setrcache.rst.txt0000664000175000017500000000133715051422642027005 0ustar ghudsonghudsonkrb5_auth_con_setrcache - Set the replay cache in an auth context. ==================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_setrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache rcache) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **rcache** - Replay cache haddle .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function sets the replay cache in *auth_context* to *rcache* . *rcache* will be closed when *auth_context* is freed, so the caller should relinquish that responsibility. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_make_authdata_kdc_issued.rst.txt0000664000175000017500000000167215051422642030153 0ustar ghudsonghudsonkrb5_make_authdata_kdc_issued - Encode and sign AD-KDCIssued authorization data. ================================================================================== .. .. c:function:: krb5_error_code krb5_make_authdata_kdc_issued(krb5_context context, const krb5_keyblock * key, krb5_const_principal issuer, krb5_authdata *const * authdata, krb5_authdata *** ad_kdcissued) .. :param: **[in]** **context** - Library context **[in]** **key** - Session key **[in]** **issuer** - The name of the issuing principal **[in]** **authdata** - List of authorization data to be signed **[out]** **ad_kdcissued** - List containing AD-KDCIssued authdata .. .. This function wraps a list of authorization data entries *authdata* in an AD-KDCIssued container (see RFC 4120 section 5.2.6.2) signed with *key* . The result is returned in *ad_kdcissued* as a single-element list. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_retrieve_cred.rst.txt0000664000175000017500000000335215051422642026452 0ustar ghudsonghudsonkrb5_cc_retrieve_cred - Retrieve a specified credentials from a credential cache. =================================================================================== .. .. c:function:: krb5_error_code krb5_cc_retrieve_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds * mcreds, krb5_creds * creds) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[in]** **flags** - Flags bit mask **[in]** **mcreds** - Credentials to match **[out]** **creds** - Credentials matching the requested value .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function searches a credential cache for credentials matching *mcreds* and returns it if found. Valid values for *flags* are: - KRB5_TC_MATCH_TIMES The requested lifetime must be at least as great as in *mcreds* . - KRB5_TC_MATCH_IS_SKEY The *is_skey* field much match exactly. - KRB5_TC_MATCH_FLAGS Flags set in *mcreds* must be set. - KRB5_TC_MATCH_TIMES_EXACT The requested lifetime must match exactly. - KRB5_TC_MATCH_FLAGS_EXACT Flags must match exactly. - KRB5_TC_MATCH_AUTHDATA The authorization data must match. - KRB5_TC_MATCH_SRV_NAMEONLY Only the name portion of the principal name must match, not the realm. - KRB5_TC_MATCH_2ND_TKT The second tickets must match. - KRB5_TC_MATCH_KTYPE The encryption key types must match. - KRB5_TC_SUPPORTED_KTYPES Check all matching entries that have any supported encryption type and return the one with the encryption type listed earliest. Use krb5_free_cred_contents() to free *creds* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_authenticator.rst.txt0000664000175000017500000000071415051422642027035 0ustar ghudsonghudsonkrb5_free_authenticator - Free a krb5_authenticator structure. ================================================================ .. .. c:function:: void krb5_free_authenticator(krb5_context context, krb5_authenticator * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Authenticator structure to be freed .. .. This function frees the contents of *val* and the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_password.rst.txt0000664000175000017500000000311715051422642025677 0ustar ghudsonghudsonkrb5_set_password - Set a password for a principal using specified credentials. ================================================================================= .. .. c:function:: krb5_error_code krb5_set_password(krb5_context context, krb5_creds * creds, const char * newpw, krb5_principal change_password_for, int * result_code, krb5_data * result_code_string, krb5_data * result_string) .. :param: **[in]** **context** - Library context **[in]** **creds** - Credentials for kadmin/changepw service **[in]** **newpw** - New password **[in]** **change_password_for** - Change the password for this principal **[out]** **result_code** - Numeric error code from server **[out]** **result_code_string** - String equivalent to *result_code* **[out]** **result_string** - Data returned from the remote system .. :retval: - 0 Success and result_code is set to KRB5_KPASSWD_SUCCESS. :return: - Kerberos error codes. .. This function uses the credentials *creds* to set the password *newpw* for the principal *change_password_for* . It implements the set password operation of RFC 3244, for interoperability with Microsoft Windows implementations. The error code and strings are returned in *result_code* , *result_code_string* and *result_string* . .. .. note:: If *change_password_for* is NULL, the change is performed on the current principal. If *change_password_for* is non-null, the change is performed on the principal name passed in *change_password_for* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_validated_creds.rst.txt0000664000175000017500000000260115051422642027133 0ustar ghudsonghudsonkrb5_get_validated_creds - Get validated credentials from the KDC. ==================================================================== .. .. c:function:: krb5_error_code krb5_get_validated_creds(krb5_context context, krb5_creds * creds, krb5_principal client, krb5_ccache ccache, const char * in_tkt_service) .. :param: **[in]** **context** - Library context **[out]** **creds** - Validated credentials **[in]** **client** - Client principal name **[in]** **ccache** - Credential cache **[in]** **in_tkt_service** - Server principal string (or NULL) .. :retval: - 0 Success - KRB5_NO_2ND_TKT Request missing second ticket - KRB5_NO_TKT_SUPPLIED Request did not supply a ticket - KRB5_PRINC_NOMATCH Requested principal and ticket do not match - KRB5_KDCREP_MODIFIED KDC reply did not match expectations - KRB5_KDCREP_SKEW Clock skew too great in KDC reply :return: - Kerberos error codes .. This function gets a validated credential using a postdated credential from *ccache* . If *in_tkt_service* is specified, it is parsed (with the realm part ignored) and used as the server principal of the credential; otherwise, the ticket-granting service is used. If successful, the validated credential is placed in *creds* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getrcache.rst.txt0000664000175000017500000000120415051422642026762 0ustar ghudsonghudsonkrb5_auth_con_getrcache - Retrieve the replay cache from an auth context. =========================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_getrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache * rcache) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **rcache** - Replay cache handle .. :retval: - 0 (always) .. This function fetches the replay cache from *auth_context* . The caller should not close *rcache* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_keyblock.rst.txt0000664000175000017500000000157515051422642026016 0ustar ghudsonghudsonkrb5_init_keyblock - Initialize an empty krb5_keyblock . ========================================================== .. .. c:function:: krb5_error_code krb5_init_keyblock(krb5_context context, krb5_enctype enctype, size_t length, krb5_keyblock ** out) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[in]** **length** - Length of keyblock (or 0) **[out]** **out** - New keyblock structure .. :retval: - 0 Success; otherwise - Kerberos error codes .. Initialize a new keyblock and allocate storage for the contents of the key. It is legal to pass in a length of 0, in which case contents are left unallocated. Use krb5_free_keyblock() to free *out* when it is no longer needed. .. .. note:: If *length* is set to 0, contents are left unallocated. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_524_convert_creds.rst.txt0000664000175000017500000000100115051422642026402 0ustar ghudsonghudsonkrb5_524_convert_creds - Convert a Kerberos V5 credentials to a Kerberos V4 credentials. ========================================================================================== .. .. c:function:: int krb5_524_convert_creds(krb5_context context, krb5_creds * v5creds, struct credentials * v4creds) .. :param: **context** **v5creds** **v4creds** .. :retval: - KRB524_KRB4_DISABLED (always) .. .. .. note:: Not implemented krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_get_principal.rst.txt0000664000175000017500000000134415051422642026447 0ustar ghudsonghudsonkrb5_cc_get_principal - Get the default principal of a credential cache. ========================================================================== .. .. c:function:: krb5_error_code krb5_cc_get_principal(krb5_context context, krb5_ccache cache, krb5_principal * principal) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[out]** **principal** - Primary principal .. :retval: - 0 Success :return: - Kerberos error codes .. Returns the default client principal of a credential cache as set by krb5_cc_initialize(). Use krb5_free_principal() to free *principal* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cccol_cursor_free.rst.txt0000664000175000017500000000102415051422642026636 0ustar ghudsonghudsonkrb5_cccol_cursor_free - Free a credential cache collection cursor. ===================================================================== .. .. c:function:: krb5_error_code krb5_cccol_cursor_free(krb5_context context, krb5_cccol_cursor * cursor) .. :param: **[in]** **context** - Library context **[in]** **cursor** - Cursor .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. .. seealso:: krb5_cccol_cursor_new(), krb5_cccol_cursor_next() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_in_tkt_with_password.rst.txt0000664000175000017500000000124415051422642030265 0ustar ghudsonghudsonkrb5_get_in_tkt_with_password ============================= .. .. c:function:: krb5_error_code krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options, krb5_address *const * addrs, krb5_enctype * ktypes, krb5_preauthtype * pre_auth_types, const char * password, krb5_ccache ccache, krb5_creds * creds, krb5_kdc_rep ** ret_as_reply) .. :param: **context** **options** **addrs** **ktypes** **pre_auth_types** **password** **ccache** **creds** **ret_as_reply** .. .. DEPRECATED Replaced by krb5_get_init_creds_password(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_end_seq_get.rst.txt0000664000175000017500000000126715051422642026110 0ustar ghudsonghudsonkrb5_cc_end_seq_get - Finish a series of sequential processing credential cache entries. ========================================================================================== .. .. c:function:: krb5_error_code krb5_cc_end_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor * cursor) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[in]** **cursor** - Cursor .. :retval: - 0 (always) .. This function finishes processing credential cache entries and invalidates *cursor* . .. .. seealso:: krb5_cc_start_seq_get(), krb5_cc_next_cred() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_address_list.rst.txt0000664000175000017500000000075715051422642032450 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_address_list - Set address restrictions in initial credential options. ==================================================================================================== .. .. c:function:: void krb5_get_init_creds_opt_set_address_list(krb5_get_init_creds_opt * opt, krb5_address ** addresses) .. :param: **[in]** **opt** - Options structure **[in]** **addresses** - Null-terminated array of addresses .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_verify_checksum.rst.txt0000664000175000017500000000252315051422642026652 0ustar ghudsonghudsonkrb5_c_verify_checksum - Verify a checksum (operates on keyblock). ==================================================================== .. .. c:function:: krb5_error_code krb5_c_verify_checksum(krb5_context context, const krb5_keyblock * key, krb5_keyusage usage, const krb5_data * data, const krb5_checksum * cksum, krb5_boolean * valid) .. :param: **[in]** **context** - Library context **[in]** **key** - Encryption key for a keyed checksum **[in]** **usage** - *key* usage **[in]** **data** - Data to be used to compute a new checksum using *key* to compare *cksum* against **[in]** **cksum** - Checksum to be verified **[out]** **valid** - Non-zero for success, zero for failure .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function verifies that *cksum* is a valid checksum for *data* . If the checksum type of *cksum* is a keyed checksum, *key* is used to verify the checksum. If the checksum type in *cksum* is 0 and *key* is not NULL, the mandatory checksum type for *key* will be used. The actual checksum key will be derived from *key* and *usage* if key derivation is specified for the checksum type. .. .. note:: This function is similar to krb5_k_verify_checksum(), but operates on keyblock *key* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_verify_authdata_kdc_issued.rst.txt0000664000175000017500000000175715051422642030546 0ustar ghudsonghudsonkrb5_verify_authdata_kdc_issued - Unwrap and verify AD-KDCIssued authorization data. ====================================================================================== .. .. c:function:: krb5_error_code krb5_verify_authdata_kdc_issued(krb5_context context, const krb5_keyblock * key, const krb5_authdata * ad_kdcissued, krb5_principal * issuer, krb5_authdata *** authdata) .. :param: **[in]** **context** - Library context **[in]** **key** - Session key **[in]** **ad_kdcissued** - AD-KDCIssued authorization data to be unwrapped **[out]** **issuer** - Name of issuing principal (or NULL) **[out]** **authdata** - Unwrapped list of authorization data .. .. This function unwraps an AD-KDCIssued authdatum (see RFC 4120 section 5.2.6.2) and verifies its signature against *key* . The issuer field of the authdatum element is returned in *issuer* , and the unwrapped list of authdata is returned in *authdata* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_get_entry.rst.txt0000664000175000017500000000232515051422642025660 0ustar ghudsonghudsonkrb5_kt_get_entry - Get an entry from a key table. ==================================================== .. .. c:function:: krb5_error_code krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, krb5_const_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keytab_entry * entry) .. :param: **[in]** **context** - Library context **[in]** **keytab** - Key table handle **[in]** **principal** - Principal name **[in]** **vno** - Key version number (0 for highest available) **[in]** **enctype** - Encryption type (0 zero for any enctype) **[out]** **entry** - Returned entry from key table .. :retval: - 0 Success - Kerberos error codes on failure .. Retrieve an entry from a key table which matches the *keytab* , *principal* , *vno* , and *enctype* . If *vno* is zero, retrieve the highest-numbered kvno matching the other fields. If *enctype* is 0, match any enctype. Use krb5_free_keytab_entry_contents() to free *entry* when it is no longer needed. .. .. note:: If *vno* is zero, the function retrieves the highest-numbered-kvno entry that matches the specified principal. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_preauth_list.rst.txt0000664000175000017500000000143515051422642032465 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_preauth_list - Set preauthentication types in initial credential options. ======================================================================================================= .. .. c:function:: void krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt * opt, krb5_preauthtype * preauth_list, int preauth_list_length) .. :param: **[in]** **opt** - Options structure **[in]** **preauth_list** - Array of preauthentication types **[in]** **preauth_list_length** - Length of *preauth_list* .. .. This function can be used to perform optimistic preauthentication when getting initial credentials, in combination with krb5_get_init_creds_opt_set_salt() and krb5_get_init_creds_opt_set_pa(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_prompter_posix.rst.txt0000664000175000017500000000224715051422642026257 0ustar ghudsonghudsonkrb5_prompter_posix - Prompt user for password. ================================================= .. .. c:function:: krb5_error_code krb5_prompter_posix(krb5_context context, void * data, const char * name, const char * banner, int num_prompts, krb5_prompt prompts) .. :param: **[in]** **context** - Library context **data** - Unused (callback argument) **[in]** **name** - Name to output during prompt **[in]** **banner** - Banner to output during prompt **[in]** **num_prompts** - Number of prompts in *prompts* **[in]** **prompts** - Array of prompts and replies .. :retval: - 0 Success :return: - Kerberos error codes .. This function is intended to be used as a prompter callback for krb5_get_init_creds_password() or krb5_init_creds_init(). Writes *name* and *banner* to stdout, each followed by a newline, then writes each prompt field in the *prompts* array, followed by":", and sets the reply field of the entry to a line of input read from stdin. If the hidden flag is set for a prompt, then terminal echoing is turned off when input is read. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_destroy.rst.txt0000664000175000017500000000077515051422642025327 0ustar ghudsonghudsonkrb5_cc_destroy - Destroy a credential cache. =============================================== .. .. c:function:: krb5_error_code krb5_cc_destroy(krb5_context context, krb5_ccache cache) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle .. :retval: - 0 Success :return: - Permission errors .. This function destroys any existing contents of *cache* and closes the handle to it. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_creds.rst.txt0000664000175000017500000000121715051422642025313 0ustar ghudsonghudsonkrb5_copy_creds - Copy a krb5_creds structure. ================================================ .. .. c:function:: krb5_error_code krb5_copy_creds(krb5_context context, const krb5_creds * incred, krb5_creds ** outcred) .. :param: **[in]** **context** - Library context **[in]** **incred** - Credentials structure to be copied **[out]** **outcred** - Copy of *incred* .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new credential with the contents of *incred* . Use krb5_free_creds() to free *outcred* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_server_rcache.rst.txt0000664000175000017500000000152515051422642026635 0ustar ghudsonghudsonkrb5_get_server_rcache - Generate a replay cache object for server use and open it. ===================================================================================== .. .. c:function:: krb5_error_code krb5_get_server_rcache(krb5_context context, const krb5_data * piece, krb5_rcache * rcptr) .. :param: **[in]** **context** - Library context **[in]** **piece** - Unused (replay cache identifier) **[out]** **rcptr** - Handle to an open rcache .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a handle to the default replay cache. Use krb5_rc_close() to close *rcptr* when it is no longer needed. .. .. note:: Prior to release 1.18, this function creates a handle to a different replay cache for each unique value of *piece* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_make_checksum_iov.rst.txt0000664000175000017500000000227415051422642027143 0ustar ghudsonghudsonkrb5_c_make_checksum_iov - Fill in a checksum element in IOV array (operates on keyblock) =========================================================================================== .. .. c:function:: krb5_error_code krb5_c_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock * key, krb5_keyusage usage, krb5_crypto_iov * data, size_t num_data) .. :param: **[in]** **context** - Library context **[in]** **cksumtype** - Checksum type (0 for mandatory type) **[in]** **key** - Encryption key for a keyed checksum **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[inout]** **data** - IOV array **[in]** **num_data** - Size of *data* .. :retval: - 0 Success; otherwise - Kerberos error codes .. Create a checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element over KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in *data* . Only the KRB5_CRYPTO_TYPE_CHECKSUM region is modified. .. .. seealso:: krb5_c_verify_checksum_iov() .. note:: This function is similar to krb5_k_make_checksum_iov(), but operates on keyblock *key* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_responder_otp_set_answer.rst.txt0000664000175000017500000000127215051422642030277 0ustar ghudsonghudsonkrb5_responder_otp_set_answer - Answer the KRB5_RESPONDER_QUESTION_OTP question. ================================================================================== .. .. c:function:: krb5_error_code krb5_responder_otp_set_answer(krb5_context ctx, krb5_responder_context rctx, size_t ti, const char * value, const char * pin) .. :param: **[in]** **ctx** - Library context **[in]** **rctx** - Responder context **[in]** **ti** - The index of the tokeninfo selected **[in]** **value** - The value to set, or NULL for none **[in]** **pin** - The pin to set, or NULL for none .. .. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_sname_match.rst.txt0000664000175000017500000000202315051422642025434 0ustar ghudsonghudsonkrb5_sname_match - Test whether a principal matches a matching principal. =========================================================================== .. .. c:function:: krb5_boolean krb5_sname_match(krb5_context context, krb5_const_principal matching, krb5_const_principal princ) .. :param: **[in]** **context** - Library context **[in]** **matching** - Matching principal **[in]** **princ** - Principal to test .. :return: - TRUE if princ matches matching , FALSE otherwise. .. If *matching* is NULL, return TRUE. If *matching* is not a matching principal, return the value of krb5_principal_compare(context, matching,princ). .. .. note:: A matching principal is a host-based principal with an empty realm and/or second data component (hostname). Profile configuration may cause the hostname to be ignored even if it is present. A principal matches a matching principal if the former has the same non-empty (and non-ignored) components of the latter. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_init.rst.txt0000664000175000017500000000171615051422642026010 0ustar ghudsonghudsonkrb5_auth_con_init - Create and initialize an authentication context. ======================================================================= .. .. c:function:: krb5_error_code krb5_auth_con_init(krb5_context context, krb5_auth_context * auth_context) .. :param: **[in]** **context** - Library context **[out]** **auth_context** - Authentication context .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates an authentication context to hold configuration and state relevant to krb5 functions for authenticating principals and protecting messages once authentication has occurred. By default, flags for the context are set to enable the use of the replay cache (KRB5_AUTH_CONTEXT_DO_TIME), but not sequence numbers. Use krb5_auth_con_setflags() to change the flags. The allocated *auth_context* must be freed with krb5_auth_con_free() when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_verify_init_creds_opt_set_ap_req_nofail.rst.txt0000664000175000017500000000175215051422642033310 0ustar ghudsonghudsonkrb5_verify_init_creds_opt_set_ap_req_nofail - Set whether credential verification is required. ================================================================================================= .. .. c:function:: void krb5_verify_init_creds_opt_set_ap_req_nofail(krb5_verify_init_creds_opt * k5_vic_options, int ap_req_nofail) .. :param: **[in]** **k5_vic_options** - Verification options structure **[in]** **ap_req_nofail** - Whether to require successful verification .. .. This function determines how krb5_verify_init_creds() behaves if no keytab information is available. If *ap_req_nofail* is **FALSE** , verification will be skipped in this case and krb5_verify_init_creds() will return successfully. If *ap_req_nofail* is **TRUE** , krb5_verify_init_creds() will not return successfully unless verification can be performed. If this function is not used, the behavior of krb5_verify_init_creds() is determined through configuration. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_context.rst.txt0000664000175000017500000000056015051422642025646 0ustar ghudsonghudsonkrb5_free_context - Free a krb5 library context. ================================================== .. .. c:function:: void krb5_free_context(krb5_context context) .. :param: **[in]** **context** - Library context .. .. This function frees a *context* that was created by krb5_init_context() or krb5_init_secure_context(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_tkt_creds_free.rst.txt0000664000175000017500000000056715051422642026153 0ustar ghudsonghudsonkrb5_tkt_creds_free - Free a TGS request context. =================================================== .. .. c:function:: void krb5_tkt_creds_free(krb5_context context, krb5_tkt_creds_context ctx) .. :param: **[in]** **context** - Library context **[in]** **ctx** - TGS request context .. .. .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_string_to_cksumtype.rst.txt0000664000175000017500000000072215051422642027275 0ustar ghudsonghudsonkrb5_string_to_cksumtype - Convert a string to a checksum type. ================================================================= .. .. c:function:: krb5_error_code krb5_string_to_cksumtype(char * string, krb5_cksumtype * cksumtypep) .. :param: **[in]** **string** - String to be converted **[out]** **cksumtypep** - Checksum type to be filled in .. :retval: - 0 Success; otherwise - EINVAL .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_tkt_life.rst.txt0000664000175000017500000000071015051422642031556 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_tkt_life - Set the ticket lifetime in initial credential options. =============================================================================================== .. .. c:function:: void krb5_get_init_creds_opt_set_tkt_life(krb5_get_init_creds_opt * opt, krb5_deltat tkt_life) .. :param: **[in]** **opt** - Options structure **[in]** **tkt_life** - Ticket lifetime .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_padding_length.rst.txt0000664000175000017500000000131515051422642026431 0ustar ghudsonghudsonkrb5_c_padding_length - Return a number of padding octets. ============================================================ .. .. c:function:: krb5_error_code krb5_c_padding_length(krb5_context context, krb5_enctype enctype, size_t data_length, unsigned int * size) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[in]** **data_length** - Length of the plaintext to pad **[out]** **size** - Number of padding octets .. :retval: - 0 Success; otherwise - KRB5_BAD_ENCTYPE .. This function returns the number of the padding octets required to pad *data_length* octets of plaintext. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_default_name.rst.txt0000664000175000017500000000121015051422642026274 0ustar ghudsonghudsonkrb5_kt_default_name - Get the default key table name. ======================================================== .. .. c:function:: krb5_error_code krb5_kt_default_name(krb5_context context, char * name, int name_size) .. :param: **[in]** **context** - Library context **[out]** **name** - Default key table name **[in]** **name_size** - Space available in *name* .. :retval: - 0 Success - KRB5_CONFIG_NOTENUFSPACE Buffer is too short :return: - Kerberos error codes .. Fill *name* with the name of the default key table for *context* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_425_conv_principal.rst.txt0000664000175000017500000000153515051422642026564 0ustar ghudsonghudsonkrb5_425_conv_principal - Convert a Kerberos V4 principal to a Kerberos V5 principal. ======================================================================================= .. .. c:function:: krb5_error_code krb5_425_conv_principal(krb5_context context, const char * name, const char * instance, const char * realm, krb5_principal * princ) .. :param: **[in]** **context** - Library context **[in]** **name** - V4 name **[in]** **instance** - V4 instance **[in]** **realm** - Realm **[out]** **princ** - V5 principal .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function builds a *princ* from V4 specification based on given input *name.instance@realm* . Use krb5_free_principal() to free *princ* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_rd_rep_dce.rst.txt0000664000175000017500000000141315051422642025245 0ustar ghudsonghudsonkrb5_rd_rep_dce - Parse and decrypt a KRB_AP_REP message for DCE RPC. ======================================================================= .. .. c:function:: krb5_error_code krb5_rd_rep_dce(krb5_context context, krb5_auth_context auth_context, const krb5_data * inbuf, krb5_ui_4 * nonce) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **inbuf** - AP-REP message **[out]** **nonce** - Sequence number from the decrypted reply .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function parses, decrypts and verifies a message from *inbuf* and fills in *nonce* with a decrypted reply sequence number. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_principal2salt.rst.txt0000664000175000017500000000111115051422642026101 0ustar ghudsonghudsonkrb5_principal2salt - Convert a principal name into the default salt for that principal. ========================================================================================== .. .. c:function:: krb5_error_code krb5_principal2salt(krb5_context context, krb5_const_principal pr, krb5_data * ret) .. :param: **[in]** **context** - Library context **[in]** **pr** - Principal name **[out]** **ret** - Default salt for *pr* to be filled in .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_random_add_entropy.rst.txt0000664000175000017500000000054015051422642027331 0ustar ghudsonghudsonkrb5_c_random_add_entropy ========================= .. .. c:function:: krb5_error_code krb5_c_random_add_entropy(krb5_context context, unsigned int randsource, const krb5_data * data) .. :param: **context** **randsource** **data** .. .. DEPRECATED This call is no longer necessary. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getauthenticator.rst.txt0000664000175000017500000000127315051422642030415 0ustar ghudsonghudsonkrb5_auth_con_getauthenticator - Retrieve the authenticator from an auth context. =================================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_getauthenticator(krb5_context context, krb5_auth_context auth_context, krb5_authenticator ** authenticator) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **authenticator** - Authenticator .. :retval: - 0 Success. Otherwise - Kerberos error codes .. Use krb5_free_authenticator() to free *authenticator* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_checksum_length.rst.txt0000664000175000017500000000105015051422642026621 0ustar ghudsonghudsonkrb5_c_checksum_length - Return the length of checksums for a checksum type. ============================================================================== .. .. c:function:: krb5_error_code krb5_c_checksum_length(krb5_context context, krb5_cksumtype cksumtype, size_t * length) .. :param: **[in]** **context** - Library context **[in]** **cksumtype** - Checksum type **[out]** **length** - Checksum length .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_dup.rst.txt0000664000175000017500000000104015051422642024441 0ustar ghudsonghudsonkrb5_kt_dup - Duplicate keytab handle. ======================================== .. .. c:function:: krb5_error_code krb5_kt_dup(krb5_context context, krb5_keytab in, krb5_keytab * out) .. :param: **[in]** **context** - Library context **[in]** **in** - Key table handle to be duplicated **[out]** **out** - Key table handle .. .. Create a new handle referring to the same key table as *in* . The new handle and *in* can be closed independently. .. .. note:: New in 1.12 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_rd_safe.rst.txt0000664000175000017500000000347115051422642024570 0ustar ghudsonghudsonkrb5_rd_safe - Process KRB-SAFE message. ========================================== .. .. c:function:: krb5_error_code krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, const krb5_data * inbuf, krb5_data * userdata_out, krb5_replay_data * rdata_out) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **inbuf** - **KRB-SAFE** message to be parsed **[out]** **userdata_out** - Data parsed from **KRB-SAFE** message **[out]** **rdata_out** - Replay data. Specify NULL if not needed .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function parses a **KRB-SAFE** message, verifies its integrity, and stores its data into *userdata_out* . If *auth_context* has a remote address set, the address will be used to verify the sender address in the KRB-SAFE message. If *auth_context* has a local address set, it will be used to verify the receiver address in the KRB-SAFE message if the message contains one. If the KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in *auth_context* , the sequence number of the KRB-SAFE message is checked against the remote sequence number field of *auth_context* . Otherwise, the sequence number is not used. If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in-memory replay cache to detect reflections or replays. Use krb5_free_data_contents() to free *userdata_out* when it is no longer needed. .. .. note:: The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cccol_have_content.rst.txt0000664000175000017500000000106515051422642027002 0ustar ghudsonghudsonkrb5_cccol_have_content - Check if the credential cache collection contains any initialized caches. ===================================================================================================== .. .. c:function:: krb5_error_code krb5_cccol_have_content(krb5_context context) .. :param: **[in]** **context** - Library context .. :retval: - 0 At least one initialized cache is present in the collection - KRB5_CC_NOTFOUND The collection contains no caches .. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_sign_ext.rst.txt0000664000175000017500000000111615051422642025622 0ustar ghudsonghudsonkrb5_pac_sign_ext ================= .. .. c:function:: krb5_error_code krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock * server_key, const krb5_keyblock * privsvr_key, krb5_boolean with_realm, krb5_data * data) .. :param: **context** **pac** **authtime** **principal** **server_key** **privsvr_key** **with_realm** **data** .. .. DEPRECATED Use krb5_kdc_sign_ticket() instead. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_free_state.rst.txt0000664000175000017500000000105515051422642025604 0ustar ghudsonghudsonkrb5_c_free_state - Free a cipher state previously allocated by krb5_c_init_state(). ====================================================================================== .. .. c:function:: krb5_error_code krb5_c_free_state(krb5_context context, const krb5_keyblock * key, krb5_data * state) .. :param: **[in]** **context** - Library context **[in]** **key** - Key **[in]** **state** - Cipher state to be freed .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_clear_error_message.rst.txt0000664000175000017500000000072215051422642027164 0ustar ghudsonghudsonkrb5_clear_error_message - Clear the extended error message in a context. =========================================================================== .. .. c:function:: void krb5_clear_error_message(krb5_context ctx) .. :param: **[in]** **ctx** - Library context .. .. This function unsets the extended error message in a context, to ensure that it is not mistakenly applied to another occurrence of the same error code. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_principal_compare.rst.txt0000664000175000017500000000100415051422642026642 0ustar ghudsonghudsonkrb5_principal_compare - Compare two principals. ================================================== .. .. c:function:: krb5_boolean krb5_principal_compare(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2) .. :param: **[in]** **context** - Library context **[in]** **princ1** - First principal **[in]** **princ2** - Second principal .. :retval: - TRUE if the principals are the same; FALSE otherwise .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_timestamp_to_sfstring.rst.txt0000664000175000017500000000147015051422642027606 0ustar ghudsonghudsonkrb5_timestamp_to_sfstring - Convert a timestamp to a string, with optional output padding. ============================================================================================= .. .. c:function:: krb5_error_code krb5_timestamp_to_sfstring(krb5_timestamp timestamp, char * buffer, size_t buflen, char * pad) .. :param: **[in]** **timestamp** - Timestamp to convert **[out]** **buffer** - Buffer to hold the converted timestamp **[in]** **buflen** - Length of buffer **[in]** **pad** - Optional value to pad *buffer* if converted timestamp does not fill it .. :retval: - 0 Success; otherwise - Kerberos error codes .. If *pad* is not NULL, *buffer* is padded out to *buflen* - 1 characters with the value of * *pad* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_authenticator.rst.txt0000664000175000017500000000137615051422642027073 0ustar ghudsonghudsonkrb5_copy_authenticator - Copy a krb5_authenticator structure. ================================================================ .. .. c:function:: krb5_error_code krb5_copy_authenticator(krb5_context context, const krb5_authenticator * authfrom, krb5_authenticator ** authto) .. :param: **[in]** **context** - Library context **[in]** **authfrom** - krb5_authenticator structure to be copied **[out]** **authto** - Copy of krb5_authenticator structure .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new krb5_authenticator structure with the content of *authfrom* . Use krb5_free_authenticator() to free *authto* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_get_type.rst.txt0000664000175000017500000000074715051422642025455 0ustar ghudsonghudsonkrb5_cc_get_type - Retrieve the type of a credential cache. ============================================================= .. .. c:function:: const char * krb5_cc_get_type(krb5_context context, krb5_ccache cache) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle .. :return: - The type of a credential cache as an alias that must not be modified or freed by the caller. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache.rst.txt0000664000175000017500000000127015051422642032202 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_fast_ccache - Set FAST armor cache in initial credential options. =============================================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_set_fast_ccache(krb5_context context, krb5_get_init_creds_opt * opt, krb5_ccache ccache) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options **[in]** **ccache** - Credential cache handle .. .. This function is similar to krb5_get_init_creds_opt_set_fast_ccache_name(), but uses a credential cache handle instead of a name. .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_make_checksum.rst.txt0000664000175000017500000000266715051422642026274 0ustar ghudsonghudsonkrb5_c_make_checksum - Compute a checksum (operates on keyblock). =================================================================== .. .. c:function:: krb5_error_code krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock * key, krb5_keyusage usage, const krb5_data * input, krb5_checksum * cksum) .. :param: **[in]** **context** - Library context **[in]** **cksumtype** - Checksum type (0 for mandatory type) **[in]** **key** - Encryption key for a keyed checksum **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[in]** **input** - Input data **[out]** **cksum** - Generated checksum .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function computes a checksum of type *cksumtype* over *input* , using *key* if the checksum type is a keyed checksum. If *cksumtype* is 0 and *key* is non-null, the checksum type will be the mandatory-to-implement checksum type for the key's encryption type. The actual checksum key will be derived from *key* and *usage* if key derivation is specified for the checksum type. The newly created *cksum* must be released by calling krb5_free_checksum_contents() when it is no longer needed. .. .. seealso:: krb5_c_verify_checksum() .. note:: This function is similar to krb5_k_make_checksum(), but operates on keyblock *key* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_tkt_creds_init.rst.txt0000664000175000017500000000240215051422642026163 0ustar ghudsonghudsonkrb5_tkt_creds_init - Create a context to get credentials from a KDC's Ticket Granting Service. ================================================================================================= .. .. c:function:: krb5_error_code krb5_tkt_creds_init(krb5_context context, krb5_ccache ccache, krb5_creds * creds, krb5_flags options, krb5_tkt_creds_context * ctx) .. :param: **[in]** **context** - Library context **[in]** **ccache** - Credential cache handle **[in]** **creds** - Input credentials **[in]** **options** - Options (see KRB5_GC macros) **[out]** **ctx** - New TGS request context .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function prepares to obtain credentials matching *creds* , either by retrieving them from *ccache* or by making requests to ticket-granting services beginning with a ticket-granting ticket for the client principal's realm. The resulting TGS acquisition context can be used asynchronously with krb5_tkt_creds_step() or synchronously with krb5_tkt_creds_get(). See also krb5_get_credentials() for synchronous use. Use krb5_tkt_creds_free() to free *ctx* when it is no longer needed. .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_set_password.rst.txt0000664000175000017500000000126115051422642030100 0ustar ghudsonghudsonkrb5_init_creds_set_password - Set a password for acquiring initial credentials. ================================================================================== .. .. c:function:: krb5_error_code krb5_init_creds_set_password(krb5_context context, krb5_init_creds_context ctx, const char * password) .. :param: **[in]** **context** - Library context **[in]** **ctx** - Initial credentials context **[in]** **password** - Password .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function supplies a password to be used to construct the client key for an initial credentials request. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getrecvsubkey.rst.txt0000664000175000017500000000137115051422642027724 0ustar ghudsonghudsonkrb5_auth_con_getrecvsubkey - Retrieve the receiving subkey from an auth context as a keyblock. ================================================================================================= .. .. c:function:: krb5_error_code krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock ** keyblock) .. :param: **[in]** **ctx** - Library context **[in]** **ac** - Authentication context **[out]** **keyblock** - Receiving subkey .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a keyblock containing the receiving subkey from *auth_context* . Use krb5_free_keyblock() to free *keyblock* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_setrecvsubkey.rst.txt0000664000175000017500000000122715051422642027740 0ustar ghudsonghudsonkrb5_auth_con_setrecvsubkey - Set the receiving subkey in an auth context with a keyblock. ============================================================================================ .. .. c:function:: krb5_error_code krb5_auth_con_setrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock * keyblock) .. :param: **[in]** **ctx** - Library context **[in]** **ac** - Authentication context **[in]** **keyblock** - Receiving subkey .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function sets the receiving subkey in *ac* to a copy of *keyblock* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_free.rst.txt0000664000175000017500000000055215051422642024726 0ustar ghudsonghudsonkrb5_pac_free - Free a PAC handle. ==================================== .. .. c:function:: void krb5_pac_free(krb5_context context, krb5_pac pac) .. :param: **[in]** **context** - Library context **[in]** **pac** - PAC to be freed .. .. This function frees the contents of *pac* and the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getkey_k.rst.txt0000664000175000017500000000122015051422642026635 0ustar ghudsonghudsonkrb5_auth_con_getkey_k - Retrieve the session key from an auth context. ========================================================================= .. .. c:function:: krb5_error_code krb5_auth_con_getkey_k(krb5_context context, krb5_auth_context auth_context, krb5_key * key) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **key** - Session key .. :retval: - 0 (always) .. This function sets *key* to the session key from *auth_context* . Use krb5_k_free_key() to release *key* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_renew_life.rst.txt0000664000175000017500000000076315051422642032104 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_renew_life - Set the ticket renewal lifetime in initial credential options. ========================================================================================================= .. .. c:function:: void krb5_get_init_creds_opt_set_renew_life(krb5_get_init_creds_opt * opt, krb5_deltat renew_life) .. :param: **[in]** **opt** - Pointer to *options* field **[in]** **renew_life** - Ticket renewal lifetime .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_key_keyblock.rst.txt0000664000175000017500000000061715051422642026151 0ustar ghudsonghudsonkrb5_k_key_keyblock - Retrieve a copy of the keyblock from a krb5_key structure. ================================================================================== .. .. c:function:: krb5_error_code krb5_k_key_keyblock(krb5_context context, krb5_key key, krb5_keyblock ** key_data) .. :param: **context** **key** **key_data** .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_rd_cred.rst.txt0000664000175000017500000000220615051422642024562 0ustar ghudsonghudsonkrb5_rd_cred - Read and validate a KRB-CRED message. ====================================================== .. .. c:function:: krb5_error_code krb5_rd_cred(krb5_context context, krb5_auth_context auth_context, krb5_data * creddata, krb5_creds *** creds_out, krb5_replay_data * rdata_out) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **creddata** - **KRB-CRED** message **[out]** **creds_out** - Null-terminated array of forwarded credentials **[out]** **rdata_out** - Replay data (NULL if not needed) .. :retval: - 0 Success; otherwise - Kerberos error codes .. *creddata* will be decrypted using the receiving subkey if it is present in *auth_context* , or the session key if the receiving subkey is not present or fails to decrypt the message. Use krb5_free_tgt_creds() to free *creds_out* when it is no longer needed. .. .. note:: The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* .` krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_credentials_renew.rst.txt0000664000175000017500000000067615051422642027525 0ustar ghudsonghudsonkrb5_get_credentials_renew ========================== .. .. c:function:: krb5_error_code krb5_get_credentials_renew(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds * in_creds, krb5_creds ** out_creds) .. :param: **context** **options** **ccache** **in_creds** **out_creds** .. .. DEPRECATED Replaced by krb5_get_renewed_creds. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getremotesubkey.rst.txt0000664000175000017500000000060515051422642030257 0ustar ghudsonghudsonkrb5_auth_con_getremotesubkey ============================= .. .. c:function:: krb5_error_code krb5_auth_con_getremotesubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock ** keyblock) .. :param: **context** **auth_context** **keyblock** .. .. DEPRECATED Replaced by krb5_auth_con_getrecvsubkey(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_decrypt.rst.txt0000664000175000017500000000270415051422642025147 0ustar ghudsonghudsonkrb5_k_decrypt - Decrypt data using a key (operates on opaque key). ===================================================================== .. .. c:function:: krb5_error_code krb5_k_decrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data * cipher_state, const krb5_enc_data * input, krb5_data * output) .. :param: **[in]** **context** - Library context **[in]** **key** - Encryption key **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[inout]** **cipher_state** - Cipher state; specify NULL if not needed **[in]** **input** - Encrypted data **[out]** **output** - Decrypted data .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function decrypts the data block *input* and stores the output into *output* . The actual decryption key will be derived from *key* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. .. .. note:: The caller must initialize *output* and allocate at least enough space for the result. The usual practice is to allocate an output buffer as long as the ciphertext, and let krb5_c_decrypt() trim *output->length* . For some enctypes, the resulting *output->length* may include padding bytes. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_forwardable.rst.txt0000664000175000017500000000077515051422642032260 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_forwardable - Set or unset the forwardable flag in initial credential options. ============================================================================================================ .. .. c:function:: void krb5_get_init_creds_opt_set_forwardable(krb5_get_init_creds_opt * opt, int forwardable) .. :param: **[in]** **opt** - Options structure **[in]** **forwardable** - Whether credentials should be forwardable .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_random_make_octets.rst.txt0000664000175000017500000000111615051422642027317 0ustar ghudsonghudsonkrb5_c_random_make_octets - Generate pseudo-random bytes. =========================================================== .. .. c:function:: krb5_error_code krb5_c_random_make_octets(krb5_context context, krb5_data * data) .. :param: **[in]** **context** - Library context **[out]** **data** - Random data .. :retval: - 0 Success; otherwise - Kerberos error codes .. Fills in *data* with bytes from the PRNG used by krb5 crypto operations. The caller must preinitialize *data* and allocate the desired amount of space. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_prompt_types.rst.txt0000664000175000017500000000110615051422642026562 0ustar ghudsonghudsonkrb5_get_prompt_types - Get prompt types array from a context. ================================================================ .. .. c:function:: krb5_prompt_type * krb5_get_prompt_types(krb5_context context) .. :param: **[in]** **context** - Library context .. :return: - Pointer to an array of prompt types corresponding to the prompter's prompts arguments. Each type has one of the following values: KRB5_PROMPT_TYPE_PASSWORD KRB5_PROMPT_TYPE_NEW_PASSWORD KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN KRB5_PROMPT_TYPE_PREAUTH .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_parse.rst.txt0000664000175000017500000000113715051422642025117 0ustar ghudsonghudsonkrb5_pac_parse - Unparse an encoded PAC into a new handle. ============================================================ .. .. c:function:: krb5_error_code krb5_pac_parse(krb5_context context, const void * ptr, size_t len, krb5_pac * pac) .. :param: **[in]** **context** - Library context **[in]** **ptr** - PAC buffer **[in]** **len** - Length of *ptr* **[out]** **pac** - PAC handle .. :retval: - 0 Success; otherwise - Kerberos error codes .. Use krb5_pac_free() to free *pac* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_client_default.rst.txt0000664000175000017500000000106615051422642026643 0ustar ghudsonghudsonkrb5_kt_client_default - Resolve the default client key table. ================================================================ .. .. c:function:: krb5_error_code krb5_kt_client_default(krb5_context context, krb5_keytab * keytab_out) .. :param: **[in]** **context** - Library context **[out]** **keytab_out** - Key table handle .. :retval: - 0 Success :return: - Kerberos error codes .. Fill *keytab_out* with a handle to the default client key table. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_fast_flags.rst.txt0000664000175000017500000000122715051422642032072 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_fast_flags - Set FAST flags in initial credential options. ======================================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_set_fast_flags(krb5_context context, krb5_get_init_creds_opt * opt, krb5_flags flags) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options **[in]** **flags** - FAST flags .. :retval: - 0 - Success; Kerberos errors otherwise. .. The following flag values are valid: - KRB5_FAST_REQUIRED - Require FAST to be used .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_address_search.rst.txt0000664000175000017500000000131115051422642026126 0ustar ghudsonghudsonkrb5_address_search - Search a list of addresses for a specified address. =========================================================================== .. .. c:function:: krb5_boolean krb5_address_search(krb5_context context, const krb5_address * addr, krb5_address *const * addrlist) .. :param: **[in]** **context** - Library context **[in]** **addr** - Address to search for **[in]** **addrlist** - Address list to be searched (or NULL) .. :return: - TRUE if addr is listed in addrlist , or addrlist is NULL; FALSE otherwise .. .. .. note:: If *addrlist* contains only a NetBIOS addresses, it will be treated as a null list. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_get_name.rst.txt0000664000175000017500000000131415051422642025403 0ustar ghudsonghudsonkrb5_cc_get_name - Retrieve the name, but not type of a credential cache. =========================================================================== .. .. c:function:: const char * krb5_cc_get_name(krb5_context context, krb5_ccache cache) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle .. :return: - On success - the name of the credential cache. .. .. .. warning:: Returns the name of the credential cache. The result is an alias into *cache* and should not be freed or modified by the caller. This name does not include the cache type, so should not be used as input to krb5_cc_resolve(). krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_random_seed.rst.txt0000664000175000017500000000042115051422642025737 0ustar ghudsonghudsonkrb5_c_random_seed ================== .. .. c:function:: krb5_error_code krb5_c_random_seed(krb5_context context, krb5_data * data) .. :param: **context** **data** .. .. DEPRECATED This call is no longer necessary. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_encrypt.rst.txt0000664000175000017500000000261315051422642025160 0ustar ghudsonghudsonkrb5_k_encrypt - Encrypt data using a key (operates on opaque key). ===================================================================== .. .. c:function:: krb5_error_code krb5_k_encrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data * cipher_state, const krb5_data * input, krb5_enc_data * output) .. :param: **[in]** **context** - Library context **[in]** **key** - Encryption key **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[inout]** **cipher_state** - Cipher state; specify NULL if not needed **[in]** **input** - Data to be encrypted **[out]** **output** - Encrypted data .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function encrypts the data block *input* and stores the output into *output* . The actual encryption key will be derived from *key* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. .. .. note:: The caller must initialize *output* and allocate at least enough space for the result (using krb5_c_encrypt_length() to determine the amount of space needed). *output->length* will be set to the actual length of the ciphertext. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_responder_pkinit_get_challenge.rst.txt0000664000175000017500000000161215051422642031400 0ustar ghudsonghudsonkrb5_responder_pkinit_get_challenge - Decode the KRB5_RESPONDER_QUESTION_PKINIT to a C struct. ================================================================================================ .. .. c:function:: krb5_error_code krb5_responder_pkinit_get_challenge(krb5_context ctx, krb5_responder_context rctx, krb5_responder_pkinit_challenge ** chl_out) .. :param: **[in]** **ctx** - Library context **[in]** **rctx** - Responder context **[out]** **chl_out** - Challenge structure .. .. A convenience function which parses the KRB5_RESPONDER_QUESTION_PKINIT question challenge data, making it available in native C. The main feature of this function is the ability to read the challenge without parsing the JSON. The returned value must be passed to krb5_responder_pkinit_challenge_free() to be freed. .. .. note:: New in 1.12 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_close.rst.txt0000664000175000017500000000102315051422642024726 0ustar ghudsonghudsonkrb5_cc_close - Close a credential cache handle. ================================================== .. .. c:function:: krb5_error_code krb5_cc_close(krb5_context context, krb5_ccache cache) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle .. :retval: - 0 Success :return: - Kerberos error codes .. This function closes a credential cache handle *cache* without affecting the contents of the cache. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_switch.rst.txt0000664000175000017500000000122115051422642025122 0ustar ghudsonghudsonkrb5_cc_switch - Make a credential cache the primary cache for its collection. ================================================================================ .. .. c:function:: krb5_error_code krb5_cc_switch(krb5_context context, krb5_ccache cache) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle .. :retval: - 0 Success, or the type of cache doesn't support switching :return: - Kerberos error codes .. If the type of *cache* supports it, set *cache* to be the primary credential cache for the collection it belongs to. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_rd_priv.rst.txt0000664000175000017500000000351315051422642024627 0ustar ghudsonghudsonkrb5_rd_priv - Process a KRB-PRIV message. ============================================ .. .. c:function:: krb5_error_code krb5_rd_priv(krb5_context context, krb5_auth_context auth_context, const krb5_data * inbuf, krb5_data * userdata_out, krb5_replay_data * rdata_out) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication structure **[in]** **inbuf** - **KRB-PRIV** message to be parsed **[out]** **userdata_out** - Data parsed from **KRB-PRIV** message **[out]** **rdata_out** - Replay data. Specify NULL if not needed .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function parses a **KRB-PRIV** message, verifies its integrity, and stores its unencrypted data into *userdata_out* . If *auth_context* has a remote address set, the address will be used to verify the sender address in the KRB-PRIV message. If *auth_context* has a local address set, it will be used to verify the receiver address in the KRB-PRIV message if the message contains one. If the KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in *auth_context* , the sequence number of the KRB-PRIV message is checked against the remote sequence number field of *auth_context* . Otherwise, the sequence number is not used. If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in-memory replay cache to detect reflections or replays. Use krb5_free_data_contents() to free *userdata_out* when it is no longer needed. .. .. note:: The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_random_os_entropy.rst.txt0000664000175000017500000000050615051422642027224 0ustar ghudsonghudsonkrb5_c_random_os_entropy ======================== .. .. c:function:: krb5_error_code krb5_c_random_os_entropy(krb5_context context, int strong, int * success) .. :param: **context** **strong** **success** .. .. DEPRECATED This call is no longer necessary. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_derive_prfplus.rst.txt0000664000175000017500000000152615051422642026517 0ustar ghudsonghudsonkrb5_c_derive_prfplus - Derive a key using some input data (via RFC 6113 PRF+). ================================================================================= .. .. c:function:: krb5_error_code krb5_c_derive_prfplus(krb5_context context, const krb5_keyblock * k, const krb5_data * input, krb5_enctype enctype, krb5_keyblock ** out) .. :param: **[in]** **context** - Library context **[in]** **k** - KDC contribution key **[in]** **input** - Input string **[in]** **enctype** - Output key enctype (or **ENCTYPE_NULL** ) **[out]** **out** - Derived keyblock .. .. This function uses PRF+ as defined in RFC 6113 to derive a key from another key and an input string. If *enctype* is **ENCTYPE_NULL** , the output key will have the same enctype as the input key. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kdc_sign_ticket.rst.txt0000664000175000017500000000271615051422642026312 0ustar ghudsonghudsonkrb5_kdc_sign_ticket - Sign a PAC, possibly including a ticket signature. =========================================================================== .. .. c:function:: krb5_error_code krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part * enc_tkt, const krb5_pac pac, krb5_const_principal server_princ, krb5_const_principal client_princ, const krb5_keyblock * server, const krb5_keyblock * privsvr, krb5_boolean with_realm) .. :param: **[in]** **context** - Library context **[in]** **enc_tkt** - The ticket for the signature **[in]** **pac** - PAC handle **[in]** **server_princ** - Canonical ticket server name **[in]** **client_princ** - PAC_CLIENT_INFO principal (or NULL) **[in]** **server** - Key for server checksum **[in]** **privsvr** - Key for KDC and ticket checksum **[in]** **with_realm** - If true, include the realm of *principal* .. :retval: - 0 on success, otherwise - Kerberos error codes .. Sign *pac* using the keys *server* and *privsvr* . Include a ticket signature over *enc_tkt* if *server_princ* is not a TGS or kadmin/changepw principal name. Add the signed PAC's encoding to the authorization data of *enc_tkt* in the first slot, wrapped in an AD-IF-RELEVANT container. If *client_princ* is non-null, add a PAC_CLIENT_INFO buffer, including the realm if *with_realm* is true. .. .. note:: New in 1.20 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_free_key.rst.txt0000664000175000017500000000052615051422642025266 0ustar ghudsonghudsonkrb5_k_free_key - Decrement the reference count on a key and free it if it hits zero. ======================================================================================= .. .. c:function:: void krb5_k_free_key(krb5_context context, krb5_key key) .. :param: **context** **key** .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_next_entry.rst.txt0000664000175000017500000000146315051422642026061 0ustar ghudsonghudsonkrb5_kt_next_entry - Retrieve the next entry from the key table. ================================================================== .. .. c:function:: krb5_error_code krb5_kt_next_entry(krb5_context context, krb5_keytab keytab, krb5_keytab_entry * entry, krb5_kt_cursor * cursor) .. :param: **[in]** **context** - Library context **[in]** **keytab** - Key table handle **[out]** **entry** - Returned key table entry **[in]** **cursor** - Key table cursor .. :retval: - 0 Success - KRB5_KT_END - if the last entry was reached :return: - Kerberos error codes .. Return the next sequential entry in *keytab* and advance *cursor* . Callers must release the returned entry with krb5_kt_free_entry(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_eblock_enctype.rst.txt0000664000175000017500000000044315051422642026147 0ustar ghudsonghudsonkrb5_eblock_enctype =================== .. .. c:function:: krb5_enctype krb5_eblock_enctype(krb5_context context, const krb5_encrypt_block * eblock) .. :param: **context** **eblock** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_principal_compare_any_realm.rst.txt0000664000175000017500000000127115051422642030677 0ustar ghudsonghudsonkrb5_principal_compare_any_realm - Compare two principals ignoring realm components. ====================================================================================== .. .. c:function:: krb5_boolean krb5_principal_compare_any_realm(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2) .. :param: **[in]** **context** - Library context **[in]** **princ1** - First principal **[in]** **princ2** - Second principal .. :retval: - TRUE if the principals are the same; FALSE otherwise .. Similar to krb5_principal_compare(), but do not compare the realm components of the principals. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_alloc.rst.txt0000664000175000017500000000134415051422642030200 0ustar ghudsonghudsonkrb5_get_init_creds_opt_alloc - Allocate a new initial credential options structure. ====================================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_alloc(krb5_context context, krb5_get_init_creds_opt ** opt) .. :param: **[in]** **context** - Library context **[out]** **opt** - New options structure .. :retval: - 0 - Success; Kerberos errors otherwise. .. This function is the preferred way to create an options structure for getting initial credentials, and is required to make use of certain options. Use krb5_get_init_creds_opt_free() to free *opt* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_read_password.rst.txt0000664000175000017500000000271015051422642026015 0ustar ghudsonghudsonkrb5_read_password - Read a password from keyboard input. =========================================================== .. .. c:function:: krb5_error_code krb5_read_password(krb5_context context, const char * prompt, const char * prompt2, char * return_pwd, unsigned int * size_return) .. :param: **[in]** **context** - Library context **[in]** **prompt** - First user prompt when reading password **[in]** **prompt2** - Second user prompt (NULL to prompt only once) **[out]** **return_pwd** - Returned password **[inout]** **size_return** - On input, maximum size of password; on output, size of password read .. :retval: - 0 Success :return: - Error in reading or verifying the password - Kerberos error codes .. This function reads a password from keyboard input and stores it in *return_pwd* . *size_return* should be set by the caller to the amount of storage space available in *return_pwd* ; on successful return, it will be set to the length of the password read. *prompt* is printed to the terminal, followed by":", and then a password is read from the keyboard. If *prompt2* is NULL, the password is read only once. Otherwise, *prompt2* is printed to the terminal and a second password is read. If the two passwords entered are not identical, KRB5_LIBOS_BADPWDMATCH is returned. Echoing is turned off when the password is read. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_random_key.rst.txt0000664000175000017500000000056415051422642025315 0ustar ghudsonghudsonkrb5_random_key =============== .. .. c:function:: krb5_error_code krb5_random_key(krb5_context context, const krb5_encrypt_block * eblock, krb5_pointer ptr, krb5_keyblock ** keyblock) .. :param: **context** **eblock** **ptr** **keyblock** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_address_compare.rst.txt0000664000175000017500000000104115051422642026307 0ustar ghudsonghudsonkrb5_address_compare - Compare two Kerberos addresses. ======================================================== .. .. c:function:: krb5_boolean krb5_address_compare(krb5_context context, const krb5_address * addr1, const krb5_address * addr2) .. :param: **[in]** **context** - Library context **[in]** **addr1** - First address to be compared **[in]** **addr2** - Second address to be compared .. :return: - TRUE if the addresses are the same, FALSE otherwise .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_vwrap_error_message.rst.txt0000664000175000017500000000140515051422642027234 0ustar ghudsonghudsonkrb5_vwrap_error_message - Add a prefix to a different error code's message using a va_list. ============================================================================================== .. .. c:function:: void krb5_vwrap_error_message(krb5_context ctx, krb5_error_code old_code, krb5_error_code code, const char * fmt, va_list args) .. :param: **[in]** **ctx** - Library context **[in]** **old_code** - Previous error code **[in]** **code** - Error code **[in]** **fmt** - Format string for error message prefix **[in]** **args** - List of vprintf(3) style arguments .. .. This function is similar to krb5_wrap_error_message(), but uses a va_list instead of variadic arguments. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_mk_req_extended.rst.txt0000664000175000017500000000365415051422642026326 0ustar ghudsonghudsonkrb5_mk_req_extended - Create a KRB_AP_REQ message using supplied credentials. ================================================================================ .. .. c:function:: krb5_error_code krb5_mk_req_extended(krb5_context context, krb5_auth_context * auth_context, krb5_flags ap_req_options, krb5_data * in_data, krb5_creds * in_creds, krb5_data * outbuf) .. :param: **[in]** **context** - Library context **[inout]** **auth_context** - Pre-existing or newly created auth context **[in]** **ap_req_options** - Options (see AP_OPTS macros) **[in]** **in_data** - Application data to be checksummed in the authenticator, or NULL **[in]** **in_creds** - Credentials for the service with valid ticket and key **[out]** **outbuf** - **AP-REQ** message .. :retval: - 0 Success; otherwise - Kerberos error codes .. Valid *ap_req_options* are: - AP_OPTS_USE_SESSION_KEY - Use the session key when creating the request used for user to user authentication. - AP_OPTS_MUTUAL_REQUIRED - Request a mutual authentication packet from the receiver. - AP_OPTS_USE_SUBKEY - Generate a subsession key from the current session key obtained from the credentials. This function creates a KRB_AP_REQ message using supplied credentials *in_creds* . *auth_context* may point to an existing auth context or to NULL, in which case a new one will be created. If *in_data* is non-null, a checksum of it will be included in the authenticator contained in the KRB_AP_REQ message. Use krb5_free_data_contents() to free *outbuf* when it is no longer needed. On successful return, the authenticator is stored in *auth_context* with the *client* and *checksum* fields nulled out. (This is to prevent pointer-sharing problems; the caller should not need these fields anyway, since the caller supplied them.) .. .. seealso:: krb5_mk_req() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_make_random_key.rst.txt0000664000175000017500000000127015051422642026607 0ustar ghudsonghudsonkrb5_c_make_random_key - Generate an enctype-specific random encryption key. ============================================================================== .. .. c:function:: krb5_error_code krb5_c_make_random_key(krb5_context context, krb5_enctype enctype, krb5_keyblock * k5_random_key) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type of the generated key **[out]** **k5_random_key** - An allocated and initialized keyblock .. :retval: - 0 Success; otherwise - Kerberos error codes .. Use krb5_free_keyblock_contents() to free *k5_random_key* when no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_change_password.rst.txt0000664000175000017500000000237615051422642026337 0ustar ghudsonghudsonkrb5_change_password - Change a password for an existing Kerberos account. ============================================================================ .. .. c:function:: krb5_error_code krb5_change_password(krb5_context context, krb5_creds * creds, const char * newpw, int * result_code, krb5_data * result_code_string, krb5_data * result_string) .. :param: **[in]** **context** - Library context **[in]** **creds** - Credentials for kadmin/changepw service **[in]** **newpw** - New password **[out]** **result_code** - Numeric error code from server **[out]** **result_code_string** - String equivalent to *result_code* **[out]** **result_string** - Change password response from the KDC .. :retval: - 0 Success; otherwise - Kerberos error codes .. Change the password for the existing principal identified by *creds* . The possible values of the output *result_code* are: - KRB5_KPASSWD_SUCCESS (0) - success - KRB5_KPASSWD_MALFORMED (1) - Malformed request error - KRB5_KPASSWD_HARDERROR (2) - Server error - KRB5_KPASSWD_AUTHERROR (3) - Authentication error - KRB5_KPASSWD_SOFTERROR (4) - Password change rejected .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_calculate_checksum.rst.txt0000664000175000017500000000100515051422642026773 0ustar ghudsonghudsonkrb5_calculate_checksum ======================= .. .. c:function:: krb5_error_code krb5_calculate_checksum(krb5_context context, krb5_cksumtype ctype, krb5_const_pointer in, size_t in_length, krb5_const_pointer seed, size_t seed_length, krb5_checksum * outcksum) .. :param: **context** **ctype** **in** **in_length** **seed** **seed_length** **outcksum** .. .. DEPRECATED See krb5_c_make_checksum() .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_chpw_message.rst.txt0000664000175000017500000000201715051422642025625 0ustar ghudsonghudsonkrb5_chpw_message - Get a result message for changing or setting a password. ============================================================================== .. .. c:function:: krb5_error_code krb5_chpw_message(krb5_context context, const krb5_data * server_string, char ** message_out) .. :param: **[in]** **context** - Library context **[in]** **server_string** - Data returned from the remote system **[out]** **message_out** - A message displayable to the user .. :retval: - 0 Success :return: - Kerberos error codes .. This function processes the *server_string* returned in the *result_string* parameter of krb5_change_password(), krb5_set_password(), and related functions, and returns a displayable string. If *server_string* contains Active Directory structured policy information, it will be converted into human-readable text. Use krb5_free_string() to free *message_out* when it is no longer needed. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_free_entry.rst.txt0000664000175000017500000000044615051422642026024 0ustar ghudsonghudsonkrb5_kt_free_entry ================== .. .. c:function:: krb5_error_code krb5_kt_free_entry(krb5_context context, krb5_keytab_entry * entry) .. :param: **context** **entry** .. .. DEPRECATED Use krb5_free_keytab_entry_contents instead. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getsendsubkey_k.rst.txt0000664000175000017500000000125215051422642030226 0ustar ghudsonghudsonkrb5_auth_con_getsendsubkey_k - Retrieve the send subkey from an auth context. ================================================================================ .. .. c:function:: krb5_error_code krb5_auth_con_getsendsubkey_k(krb5_context ctx, krb5_auth_context ac, krb5_key * key) .. :param: **[in]** **ctx** - Library context **[in]** **ac** - Authentication context **[out]** **key** - Send subkey .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function sets *key* to the send subkey from *auth_context* . Use krb5_k_free_key() to release *key* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_canonicalize.rst.txt0000664000175000017500000000100315051422642032410 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_canonicalize - Set or unset the canonicalize flag in initial credential options. ============================================================================================================== .. .. c:function:: void krb5_get_init_creds_opt_set_canonicalize(krb5_get_init_creds_opt * opt, int canonicalize) .. :param: **[in]** **opt** - Options structure **[in]** **canonicalize** - Whether to canonicalize client principal .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_sign.rst.txt0000664000175000017500000000101615051422642024741 0ustar ghudsonghudsonkrb5_pac_sign ============= .. .. c:function:: krb5_error_code krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock * server_key, const krb5_keyblock * privsvr_key, krb5_data * data) .. :param: **context** **pac** **authtime** **principal** **server_key** **privsvr_key** **data** .. .. DEPRECATED Use krb5_kdc_sign_ticket() instead. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getkey.rst.txt0000664000175000017500000000135315051422642026332 0ustar ghudsonghudsonkrb5_auth_con_getkey - Retrieve the session key from an auth context as a keyblock. ===================================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock ** keyblock) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **keyblock** - Session key .. :retval: - 0 Success. Otherwise - Kerberos error codes .. This function creates a keyblock containing the session key from *auth_context* . Use krb5_free_keyblock() to free *keyblock* when it is no longer needed .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_unparsed_name.rst.txt0000664000175000017500000000057715051422642027013 0ustar ghudsonghudsonkrb5_free_unparsed_name - Free a string representation of a principal. ======================================================================== .. .. c:function:: void krb5_free_unparsed_name(krb5_context context, char * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Name string to be freed .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_get_client_info.rst.txt0000664000175000017500000000166515051422642027143 0ustar ghudsonghudsonkrb5_pac_get_client_info - Read client information from a PAC. ================================================================ .. .. c:function:: krb5_error_code krb5_pac_get_client_info(krb5_context context, const krb5_pac pac, krb5_timestamp * authtime_out, char ** princname_out) .. :param: **[in]** **context** - Library context **[in]** **pac** - PAC handle **[out]** **authtime_out** - Authentication timestamp (NULL if not needed) **[out]** **princname_out** - Client account name .. :retval: - 0 on success, ENOENT if no PAC_CLIENT_INFO buffer is present in pac , ERANGE if the buffer contains invalid lengths. .. Read the PAC_CLIENT_INFO buffer in *pac* . Place the client account name as a string in *princname_out* . If *authtime_out* is not NULL, place the initial authentication timestamp in *authtime_out* . .. .. note:: New in 1.18 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_principal.rst.txt0000664000175000017500000000122215051422642026170 0ustar ghudsonghudsonkrb5_copy_principal - Copy a principal. ========================================= .. .. c:function:: krb5_error_code krb5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_principal * outprinc) .. :param: **[in]** **context** - Library context **[in]** **inprinc** - Principal to be copied **[out]** **outprinc** - Copy of *inprinc* .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new principal structure with the contents of *inprinc* . Use krb5_free_principal() to free *outprinc* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_recvauth.rst.txt0000664000175000017500000000236315051422642025005 0ustar ghudsonghudsonkrb5_recvauth - Server function for sendauth protocol. ======================================================== .. .. c:function:: krb5_error_code krb5_recvauth(krb5_context context, krb5_auth_context * auth_context, krb5_pointer fd, char * appl_version, krb5_principal server, krb5_int32 flags, krb5_keytab keytab, krb5_ticket ** ticket) .. :param: **[in]** **context** - Library context **[inout]** **auth_context** - Pre-existing or newly created auth context **[in]** **fd** - File descriptor **[in]** **appl_version** - Application protocol version to be matched against the client's application version **[in]** **server** - Server principal (NULL for any in *keytab* ) **[in]** **flags** - Additional specifications **[in]** **keytab** - Key table containing service keys **[out]** **ticket** - Ticket (NULL if not needed) .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function performs the server side of a sendauth/recvauth exchange by sending and receiving messages over *fd* . Use krb5_free_ticket() to free *ticket* when it is no longer needed. .. .. seealso:: krb5_sendauth() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_prf_length.rst.txt0000664000175000017500000000107615051422642025616 0ustar ghudsonghudsonkrb5_c_prf_length - Get the output length of pseudo-random functions for an encryption type. ============================================================================================== .. .. c:function:: krb5_error_code krb5_c_prf_length(krb5_context context, krb5_enctype enctype, size_t * len) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[out]** **len** - Length of PRF output .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_authdata.rst.txt0000664000175000017500000000147615051422642026015 0ustar ghudsonghudsonkrb5_copy_authdata - Copy an authorization data list. ======================================================= .. .. c:function:: krb5_error_code krb5_copy_authdata(krb5_context context, krb5_authdata *const * in_authdat, krb5_authdata *** out) .. :param: **[in]** **context** - Library context **[in]** **in_authdat** - List of *krb5_authdata* structures **[out]** **out** - New array of *krb5_authdata* structures .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new authorization data list containing a copy of *in_authdat* , which must be null-terminated. Use krb5_free_authdata() to free *out* when it is no longer needed. .. .. note:: The last array entry in *in_authdat* must be a NULL pointer. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_renewed_creds.rst.txt0000664000175000017500000000210015051422642026621 0ustar ghudsonghudsonkrb5_get_renewed_creds - Get renewed credential from KDC using an existing credential. ======================================================================================== .. .. c:function:: krb5_error_code krb5_get_renewed_creds(krb5_context context, krb5_creds * creds, krb5_principal client, krb5_ccache ccache, const char * in_tkt_service) .. :param: **[in]** **context** - Library context **[out]** **creds** - Renewed credentials **[in]** **client** - Client principal name **[in]** **ccache** - Credential cache **[in]** **in_tkt_service** - Server principal string (or NULL) .. :retval: - 0 Success :return: - Kerberos error codes .. This function gets a renewed credential using an existing one from *ccache* . If *in_tkt_service* is specified, it is parsed (with the realm part ignored) and used as the server principal of the credential; otherwise, the ticket-granting service is used. If successful, the renewed credential is placed in *creds* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_deltat_to_string.rst.txt0000664000175000017500000000105215051422642026523 0ustar ghudsonghudsonkrb5_deltat_to_string - Convert a relative time value to a string. ==================================================================== .. .. c:function:: krb5_error_code krb5_deltat_to_string(krb5_deltat deltat, char * buffer, size_t buflen) .. :param: **[in]** **deltat** - Relative time value to convert **[out]** **buffer** - Buffer to hold time string **[in]** **buflen** - Storage available in *buffer* .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_is_config_principal.rst.txt0000664000175000017500000000107015051422642027157 0ustar ghudsonghudsonkrb5_is_config_principal - Test whether a principal is a configuration principal. =================================================================================== .. .. c:function:: krb5_boolean krb5_is_config_principal(krb5_context context, krb5_const_principal principal) .. :param: **[in]** **context** - Library context **[in]** **principal** - Principal to check .. :return: - TRUE if the principal is a configuration principal (generated part of krb5_cc_set_config()); FALSE otherwise. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_encrypt_length.rst.txt0000664000175000017500000000135015051422642026506 0ustar ghudsonghudsonkrb5_c_encrypt_length - Compute encrypted data length. ======================================================== .. .. c:function:: krb5_error_code krb5_c_encrypt_length(krb5_context context, krb5_enctype enctype, size_t inputlen, size_t * length) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[in]** **inputlen** - Length of the data to be encrypted **[out]** **length** - Length of the encrypted data .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function computes the length of the ciphertext produced by encrypting *inputlen* bytes including padding, confounder, and checksum. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_real_time.rst.txt0000664000175000017500000000133715051422642026000 0ustar ghudsonghudsonkrb5_set_real_time - Set time offset field in a krb5_context structure. ========================================================================= .. .. c:function:: krb5_error_code krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds) .. :param: **[in]** **context** - Library context **[in]** **seconds** - Real time, seconds portion **[in]** **microseconds** - Real time, microseconds portion .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function sets the time offset in *context* to the difference between the system time and the real time as determined by *seconds* and *microseconds* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_get.rst.txt0000664000175000017500000000144215051422642026143 0ustar ghudsonghudsonkrb5_init_creds_get - Acquire credentials using an initial credentials context. ================================================================================= .. .. c:function:: krb5_error_code krb5_init_creds_get(krb5_context context, krb5_init_creds_context ctx) .. :param: **[in]** **context** - Library context **[in]** **ctx** - Initial credentials context .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function synchronously obtains credentials using a context created by krb5_init_creds_init(). On successful return, the credentials can be retrieved with krb5_init_creds_get_creds(). *context* must be the same as the one passed to krb5_init_creds_init() for this initial credentials context. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_vset_error_message.rst.txt0000664000175000017500000000107715051422642027063 0ustar ghudsonghudsonkrb5_vset_error_message - Set an extended error message for an error code using a va_list. ============================================================================================ .. .. c:function:: void krb5_vset_error_message(krb5_context ctx, krb5_error_code code, const char * fmt, va_list args) .. :param: **[in]** **ctx** - Library context **[in]** **code** - Error code **[in]** **fmt** - Error string for the error code **[in]** **args** - List of vprintf(3) style arguments .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_host_realm.rst.txt0000664000175000017500000000161615051422642026160 0ustar ghudsonghudsonkrb5_get_host_realm - Get the Kerberos realm names for a host. ================================================================ .. .. c:function:: krb5_error_code krb5_get_host_realm(krb5_context context, const char * host, char *** realmsp) .. :param: **[in]** **context** - Library context **[in]** **host** - Host name (or NULL) **[out]** **realmsp** - Null-terminated list of realm names .. :retval: - 0 Success - ENOMEM Insufficient memory :return: - Kerberos error codes .. Fill in *realmsp* with a pointer to a null-terminated list of realm names. If there are no known realms for the host, a list containing the referral (empty) realm is returned. If *host* is NULL, the local host's realms are determined. Use krb5_free_host_realm() to release *realmsp* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getlocalseqnumber.rst.txt0000664000175000017500000000145515051422642030561 0ustar ghudsonghudsonkrb5_auth_con_getlocalseqnumber - Retrieve the local sequence number from an auth context. ============================================================================================ .. .. c:function:: krb5_error_code krb5_auth_con_getlocalseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 * seqnumber) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **seqnumber** - Local sequence number .. :retval: - 0 Success; otherwise - Kerberos error codes .. Retrieve the local sequence number from *auth_context* and return it in *seqnumber* . The KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in *auth_context* for this function to be useful. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_set_default_name.rst.txt0000664000175000017500000000157715051422642027136 0ustar ghudsonghudsonkrb5_cc_set_default_name - Set the default credential cache name. =================================================================== .. .. c:function:: krb5_error_code krb5_cc_set_default_name(krb5_context context, const char * name) .. :param: **[in]** **context** - Library context **[in]** **name** - Default credential cache name or NULL .. :retval: - 0 Success - KV5M_CONTEXT Bad magic number for _krb5_context structure :return: - Kerberos error codes .. Set the default credential cache name to *name* for future operations using *context* . If *name* is NULL, clear any previous application-set default name and forget any cached value of the default name for *context* . Calls to this function invalidate the result of any previous calls to krb5_cc_default_name() using *context* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_setuseruserkey.rst.txt0000664000175000017500000000106715051422642030146 0ustar ghudsonghudsonkrb5_auth_con_setuseruserkey - Set the session key in an auth context. ======================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock * keyblock) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **keyblock** - User key .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_enctypes.rst.txt0000664000175000017500000000060515051422642026014 0ustar ghudsonghudsonkrb5_free_enctypes - Free an array of encryption types. ========================================================= .. .. c:function:: void krb5_free_enctypes(krb5_context context, krb5_enctype * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Array of enctypes to be freed .. .. .. .. note:: New in 1.12 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_have_content.rst.txt0000664000175000017500000000104215051422642026330 0ustar ghudsonghudsonkrb5_kt_have_content - Check if a keytab exists and contains entries. ======================================================================= .. .. c:function:: krb5_error_code krb5_kt_have_content(krb5_context context, krb5_keytab keytab) .. :param: **[in]** **context** - Library context **[in]** **keytab** - Key table handle .. :retval: - 0 Keytab exists and contains entries - KRB5_KT_NOTFOUND Keytab does not contain entries .. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_is_thread_safe.rst.txt0000664000175000017500000000061515051422642026122 0ustar ghudsonghudsonkrb5_is_thread_safe - Test whether the Kerberos library was built with multithread support. ============================================================================================= .. .. c:function:: krb5_boolean krb5_is_thread_safe(void None) .. :param: **None** .. :retval: - TRUE if the library is threadsafe; FALSE otherwise .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_time_offsets.rst.txt0000664000175000017500000000120015051422642026477 0ustar ghudsonghudsonkrb5_get_time_offsets - Return the time offsets from the os context. ====================================================================== .. .. c:function:: krb5_error_code krb5_get_time_offsets(krb5_context context, krb5_timestamp * seconds, krb5_int32 * microseconds) .. :param: **[in]** **context** - Library context **[out]** **seconds** - Time offset, seconds portion **[out]** **microseconds** - Time offset, microseconds portion .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function returns the time offsets in *context* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_init_state.rst.txt0000664000175000017500000000110515051422642025622 0ustar ghudsonghudsonkrb5_c_init_state - Initialize a new cipher state. ==================================================== .. .. c:function:: krb5_error_code krb5_c_init_state(krb5_context context, const krb5_keyblock * key, krb5_keyusage usage, krb5_data * new_state) .. :param: **[in]** **context** - Library context **[in]** **key** - Key **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[out]** **new_state** - New cipher state .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_close.rst.txt0000664000175000017500000000055215051422642024765 0ustar ghudsonghudsonkrb5_kt_close - Close a key table handle. =========================================== .. .. c:function:: krb5_error_code krb5_kt_close(krb5_context context, krb5_keytab keytab) .. :param: **[in]** **context** - Library context **[in]** **keytab** - Key table handle .. :retval: - 0 None .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_default_name.rst.txt0000664000175000017500000000244715051422642026260 0ustar ghudsonghudsonkrb5_cc_default_name - Return the name of the default credential cache. ========================================================================= .. .. c:function:: const char * krb5_cc_default_name(krb5_context context) .. :param: **[in]** **context** - Library context .. :return: - Name of default credential cache for the current user. .. Return a pointer to the default credential cache name for *context* , as determined by a prior call to krb5_cc_set_default_name(), by the KRB5CCNAME environment variable, by the default_ccache_name profile variable, or by the operating system or build-time default value. The returned value must not be modified or freed by the caller. The returned value becomes invalid when *context* is destroyed krb5_free_context() or if a subsequent call to krb5_cc_set_default_name() is made on *context* . The default credential cache name is cached in *context* between calls to this function, so if the value of KRB5CCNAME changes in the process environment after the first call to this function on, that change will not be reflected in later calls with the same context. The caller can invoke krb5_cc_set_default_name() with a NULL value of *name* to clear the cached value and force the default name to be recomputed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_finish_random_key.rst.txt0000664000175000017500000000052715051422642026654 0ustar ghudsonghudsonkrb5_finish_random_key ====================== .. .. c:function:: krb5_error_code krb5_finish_random_key(krb5_context context, const krb5_encrypt_block * eblock, krb5_pointer * ptr) .. :param: **context** **eblock** **ptr** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_error.rst.txt0000664000175000017500000000074115051422642025314 0ustar ghudsonghudsonkrb5_free_error - Free an error allocated by krb5_read_error() or krb5_sendauth(). ==================================================================================== .. .. c:function:: void krb5_free_error(krb5_context context, krb5_error * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Error data structure to be freed .. .. This function frees the contents of *val* and the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_mk_req.rst.txt0000664000175000017500000000245215051422642024441 0ustar ghudsonghudsonkrb5_mk_req - Create a KRB_AP_REQ message. ============================================ .. .. c:function:: krb5_error_code krb5_mk_req(krb5_context context, krb5_auth_context * auth_context, krb5_flags ap_req_options, const char * service, const char * hostname, krb5_data * in_data, krb5_ccache ccache, krb5_data * outbuf) .. :param: **[in]** **context** - Library context **[inout]** **auth_context** - Pre-existing or newly created auth context **[in]** **ap_req_options** - Options (see AP_OPTS macros) **[in]** **service** - Service name, or NULL to use **"host"** **[in]** **hostname** - Host name, or NULL to use local hostname **[in]** **in_data** - Application data to be checksummed in the authenticator, or NULL **[in]** **ccache** - Credential cache used to obtain credentials for the desired service. **[out]** **outbuf** - **AP-REQ** message .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function is similar to krb5_mk_req_extended() except that it uses a given *hostname* , *service* , and *ccache* to construct a service principal name and obtain credentials. Use krb5_free_data_contents() to free *outbuf* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_keylengths.rst.txt0000664000175000017500000000116015051422642025635 0ustar ghudsonghudsonkrb5_c_keylengths - Return length of the specified key in bytes. ================================================================== .. .. c:function:: krb5_error_code krb5_c_keylengths(krb5_context context, krb5_enctype enctype, size_t * keybytes, size_t * keylength) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[out]** **keybytes** - Number of bytes required to make a key **[out]** **keylength** - Length of final key .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_free.rst.txt0000664000175000017500000000075015051422642026306 0ustar ghudsonghudsonkrb5_init_creds_free - Free an initial credentials context. ============================================================= .. .. c:function:: void krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx) .. :param: **[in]** **context** - Library context **[in]** **ctx** - Initial credentials context .. .. *context* must be the same as the one passed to krb5_init_creds_init() for this initial credentials context. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_valid_cksumtype.rst.txt0000664000175000017500000000065515051422642026673 0ustar ghudsonghudsonkrb5_c_valid_cksumtype - Verify that specified checksum type is a valid Kerberos checksum type. ================================================================================================= .. .. c:function:: krb5_boolean krb5_c_valid_cksumtype(krb5_cksumtype ctype) .. :param: **[in]** **ctype** - Checksum type .. :return: - TRUE if ctype is valid, FALSE if not .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache_name.rst.txt0000664000175000017500000000176115051422642033207 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_fast_ccache_name - Set location of FAST armor ccache in initial credential options. ================================================================================================================= .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_set_fast_ccache_name(krb5_context context, krb5_get_init_creds_opt * opt, const char * fast_ccache_name) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options **[in]** **fast_ccache_name** - Credential cache name .. .. Sets the location of a credential cache containing an armor ticket to protect an initial credential exchange using the FAST protocol extension. In version 1.7, setting an armor ccache requires that FAST be used for the exchange. In version 1.8 or later, setting the armor ccache causes FAST to be used if the KDC supports it; krb5_get_init_creds_opt_set_fast_flags() must be used to require that FAST be used. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_etype_list.rst.txt0000664000175000017500000000111015051422642032131 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_etype_list - Set allowable encryption types in initial credential options. ======================================================================================================== .. .. c:function:: void krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt * opt, krb5_enctype * etype_list, int etype_list_length) .. :param: **[in]** **opt** - Options structure **[in]** **etype_list** - Array of encryption types **[in]** **etype_list_length** - Length of *etype_list* .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_responder_otp_challenge_free.rst.txt0000664000175000017500000000107115051422642031045 0ustar ghudsonghudsonkrb5_responder_otp_challenge_free - Free the value returned by krb5_responder_otp_get_challenge(). ==================================================================================================== .. .. c:function:: void krb5_responder_otp_challenge_free(krb5_context ctx, krb5_responder_context rctx, krb5_responder_otp_challenge * chl) .. :param: **[in]** **ctx** - Library context **[in]** **rctx** - Responder context **[in]** **chl** - The challenge to free .. .. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_enctype_compare.rst.txt0000664000175000017500000000126615051422642026644 0ustar ghudsonghudsonkrb5_c_enctype_compare - Compare two encryption types. ======================================================== .. .. c:function:: krb5_error_code krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2, krb5_boolean * similar) .. :param: **[in]** **context** - Library context **[in]** **e1** - First encryption type **[in]** **e2** - Second encryption type **[out]** **similar** - **TRUE** if types are similar, **FALSE** if not .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function determines whether two encryption types use the same kind of keys. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_sendauth.rst.txt0000664000175000017500000000523615051422642025001 0ustar ghudsonghudsonkrb5_sendauth - Client function for sendauth protocol. ======================================================== .. .. c:function:: krb5_error_code krb5_sendauth(krb5_context context, krb5_auth_context * auth_context, krb5_pointer fd, char * appl_version, krb5_principal client, krb5_principal server, krb5_flags ap_req_options, krb5_data * in_data, krb5_creds * in_creds, krb5_ccache ccache, krb5_error ** error, krb5_ap_rep_enc_part ** rep_result, krb5_creds ** out_creds) .. :param: **[in]** **context** - Library context **[inout]** **auth_context** - Pre-existing or newly created auth context **[in]** **fd** - File descriptor that describes network socket **[in]** **appl_version** - Application protocol version to be matched with the receiver's application version **[in]** **client** - Client principal **[in]** **server** - Server principal **[in]** **ap_req_options** - Options (see AP_OPTS macros) **[in]** **in_data** - Data to be sent to the server **[in]** **in_creds** - Input credentials, or NULL to use *ccache* **[in]** **ccache** - Credential cache **[out]** **error** - If non-null, contains KRB_ERROR message returned from server **[out]** **rep_result** - If non-null and *ap_req_options* is AP_OPTS_MUTUAL_REQUIRED, contains the result of mutual authentication exchange **[out]** **out_creds** - If non-null, the retrieved credentials .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function performs the client side of a sendauth/recvauth exchange by sending and receiving messages over *fd* . Credentials may be specified in three ways: - If *in_creds* is NULL, credentials are obtained with krb5_get_credentials() using the principals *client* and *server* . *server* must be non-null; *client* may NULL to use the default principal of *ccache* . - If *in_creds* is non-null, but does not contain a ticket, credentials for the exchange are obtained with krb5_get_credentials() using *in_creds* . In this case, the values of *client* and *server* are unused. - If *in_creds* is a complete credentials structure, it used directly. In this case, the values of *client* , *server* , and *ccache* are unused. If the server is using a different application protocol than that specified in *appl_version* , an error will be returned. Use krb5_free_creds() to free *out_creds* , krb5_free_ap_rep_enc_part() to free *rep_result* , and krb5_free_error() to free *error* when they are no longer needed. .. .. seealso:: krb5_recvauth() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_crypto_length.rst.txt0000664000175000017500000000127215051422642026345 0ustar ghudsonghudsonkrb5_c_crypto_length - Return a length of a message field specific to the encryption type. ============================================================================================ .. .. c:function:: krb5_error_code krb5_c_crypto_length(krb5_context context, krb5_enctype enctype, krb5_cryptotype type, unsigned int * size) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[in]** **type** - Type field (See KRB5_CRYPTO_TYPE macros) **[out]** **size** - Length of the *type* specific to *enctype* .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_verify_checksum.rst.txt0000664000175000017500000000077615051422642026360 0ustar ghudsonghudsonkrb5_verify_checksum ==================== .. .. c:function:: krb5_error_code krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype, const krb5_checksum * cksum, krb5_const_pointer in, size_t in_length, krb5_const_pointer seed, size_t seed_length) .. :param: **context** **ctype** **cksum** **in** **in_length** **seed** **seed_length** .. .. DEPRECATED See krb5_c_verify_checksum() .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_checksum_size.rst.txt0000664000175000017500000000041015051422642026007 0ustar ghudsonghudsonkrb5_checksum_size ================== .. .. c:function:: size_t krb5_checksum_size(krb5_context context, krb5_cksumtype ctype) .. :param: **context** **ctype** .. .. DEPRECATED See krb5_c_checksum_length() .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_init.rst.txt0000664000175000017500000000102115051422642024740 0ustar ghudsonghudsonkrb5_pac_init - Create an empty Privilege Attribute Certificate (PAC) handle. =============================================================================== .. .. c:function:: krb5_error_code krb5_pac_init(krb5_context context, krb5_pac * pac) .. :param: **[in]** **context** - Library context **[out]** **pac** - New PAC handle .. :retval: - 0 Success; otherwise - Kerberos error codes .. Use krb5_pac_free() to free *pac* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_524_conv_principal.rst.txt0000664000175000017500000000175515051422642026570 0ustar ghudsonghudsonkrb5_524_conv_principal - Convert a Kerberos V5 principal to a Kerberos V4 principal. ======================================================================================= .. .. c:function:: krb5_error_code krb5_524_conv_principal(krb5_context context, krb5_const_principal princ, char * name, char * inst, char * realm) .. :param: **[in]** **context** - Library context **[in]** **princ** - V5 Principal **[out]** **name** - V4 principal's name to be filled in **[out]** **inst** - V4 principal's instance name to be filled in **[out]** **realm** - Principal's realm name to be filled in .. :retval: - 0 Success - KRB5_INVALID_PRINCIPAL Invalid principal name - KRB5_CONFIG_CANTOPEN Can't open or find Kerberos configuration file :return: - Kerberos error codes .. This function separates a V5 principal *princ* into *name* , *instance* , and *realm* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_string_to_key.rst.txt0000664000175000017500000000157615051422642026353 0ustar ghudsonghudsonkrb5_c_string_to_key - Convert a string (such a password) to a key. ===================================================================== .. .. c:function:: krb5_error_code krb5_c_string_to_key(krb5_context context, krb5_enctype enctype, const krb5_data * string, const krb5_data * salt, krb5_keyblock * key) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[in]** **string** - String to be converted **[in]** **salt** - Salt value **[out]** **key** - Generated key .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function converts *string* to a *key* of encryption type *enctype* , using the specified *salt* . The newly created *key* must be released by calling krb5_free_keyblock_contents() when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_default_realm.rst.txt0000664000175000017500000000065115051422642026767 0ustar ghudsonghudsonkrb5_free_default_realm - Free a default realm string returned by krb5_get_default_realm(). ============================================================================================= .. .. c:function:: void krb5_free_default_realm(krb5_context context, char * lrealm) .. :param: **[in]** **context** - Library context **[in]** **lrealm** - Realm to be freed .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_prfplus.rst.txt0000664000175000017500000000203715051422642025157 0ustar ghudsonghudsonkrb5_c_prfplus - Generate pseudo-random bytes using RFC 6113 PRF+. ==================================================================== .. .. c:function:: krb5_error_code krb5_c_prfplus(krb5_context context, const krb5_keyblock * k, const krb5_data * input, krb5_data * output) .. :param: **[in]** **context** - Library context **[in]** **k** - KDC contribution key **[in]** **input** - Input data **[out]** **output** - Pseudo-random output buffer .. :return: - 0 on success, E2BIG if output->length is too large for PRF+ to generate, ENOMEM on allocation failure, or an error code from krb5_c_prf() .. This function fills *output* with PRF+(k, input) as defined in RFC 6113 section 5.1. The caller must preinitialize *output* and allocate the desired amount of space. The length of the pseudo-random output will match the length of *output* . .. .. note:: RFC 4402 defines a different PRF+ operation. This function does not implement that operation. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_marshal_credentials.rst.txt0000664000175000017500000000132715051422642027167 0ustar ghudsonghudsonkrb5_marshal_credentials - Serialize a krb5_creds object. =========================================================== .. .. c:function:: krb5_error_code krb5_marshal_credentials(krb5_context context, krb5_creds * in_creds, krb5_data ** data_out) .. :param: **[in]** **context** - Library context **[in]** **in_creds** - The credentials object to serialize **[out]** **data_out** - The serialized credentials .. :retval: - 0 Success; otherwise - Kerberos error codes .. Serialize *creds* in the format used by the FILE ccache format (vesion 4) and KCM ccache protocol. Use krb5_free_data() to free *data_out* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_decrypt.rst.txt0000664000175000017500000000066115051422642024635 0ustar ghudsonghudsonkrb5_decrypt ============ .. .. c:function:: krb5_error_code krb5_decrypt(krb5_context context, krb5_const_pointer inptr, krb5_pointer outptr, size_t size, krb5_encrypt_block * eblock, krb5_pointer ivec) .. :param: **context** **inptr** **outptr** **size** **eblock** **ivec** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cccol_cursor_next.rst.txt0000664000175000017500000000144715051422642026704 0ustar ghudsonghudsonkrb5_cccol_cursor_next - Get the next credential cache in the collection. =========================================================================== .. .. c:function:: krb5_error_code krb5_cccol_cursor_next(krb5_context context, krb5_cccol_cursor cursor, krb5_ccache * ccache) .. :param: **[in]** **context** - Library context **[in]** **cursor** - Cursor **[out]** **ccache** - Credential cache handle .. :retval: - 0 Success; otherwise - Kerberos error codes .. Use krb5_cc_close() to close *ccache* when it is no longer needed. .. .. seealso:: krb5_cccol_cursor_new(), krb5_cccol_cursor_free() .. note:: When all caches are iterated over and the end of the list is reached, *ccache* is set to NULL. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cksumtype_to_string.rst.txt0000664000175000017500000000105315051422642027273 0ustar ghudsonghudsonkrb5_cksumtype_to_string - Convert a checksum type to a string. ================================================================= .. .. c:function:: krb5_error_code krb5_cksumtype_to_string(krb5_cksumtype cksumtype, char * buffer, size_t buflen) .. :param: **[in]** **cksumtype** - Checksum type **[out]** **buffer** - Buffer to hold converted checksum type **[in]** **buflen** - Storage available in *buffer* .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_decode_authdata_container.rst.txt0000664000175000017500000000134315051422642030321 0ustar ghudsonghudsonkrb5_decode_authdata_container - Unwrap authorization data. ============================================================= .. .. c:function:: krb5_error_code krb5_decode_authdata_container(krb5_context context, krb5_authdatatype type, const krb5_authdata * container, krb5_authdata *** authdata) .. :param: **[in]** **context** - Library context **[in]** **type** - Container type (see KRB5_AUTHDATA macros) **[in]** **container** - Authorization data to be decoded **[out]** **authdata** - List of decoded authorization data .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. .. seealso:: krb5_encode_authdata_container() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_appdefault_boolean.rst.txt0000664000175000017500000000163215051422642027006 0ustar ghudsonghudsonkrb5_appdefault_boolean - Retrieve a boolean value from the appdefaults section of krb5.conf. =============================================================================================== .. .. c:function:: void krb5_appdefault_boolean(krb5_context context, const char * appname, const krb5_data * realm, const char * option, int default_value, int * ret_value) .. :param: **[in]** **context** - Library context **[in]** **appname** - Application name **[in]** **realm** - Realm name **[in]** **option** - Option to be checked **[in]** **default_value** - Default value to return if no match is found **[out]** **ret_value** - Boolean value of *option* .. .. This function gets the application defaults for *option* based on the given *appname* and/or *realm* . .. .. seealso:: krb5_appdefault_string() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_tkt_creds_get_creds.rst.txt0000664000175000017500000000151515051422642027163 0ustar ghudsonghudsonkrb5_tkt_creds_get_creds - Retrieve acquired credentials from a TGS request context. ====================================================================================== .. .. c:function:: krb5_error_code krb5_tkt_creds_get_creds(krb5_context context, krb5_tkt_creds_context ctx, krb5_creds * creds) .. :param: **[in]** **context** - Library context **[in]** **ctx** - TGS request context **[out]** **creds** - Acquired credentials .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function copies the acquired initial credentials from *ctx* into *creds* , after the successful completion of krb5_tkt_creds_get() or krb5_tkt_creds_step(). Use krb5_free_cred_contents() to free *creds* when it is no longer needed. .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_is_keyed_cksum.rst.txt0000664000175000017500000000057615051422642026470 0ustar ghudsonghudsonkrb5_c_is_keyed_cksum - Test whether a checksum type is keyed. ================================================================ .. .. c:function:: krb5_boolean krb5_c_is_keyed_cksum(krb5_cksumtype ctype) .. :param: **[in]** **ctype** - Checksum type .. :return: - TRUE if ctype is a keyed checksum type, FALSE otherwise. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_timestamp_to_string.rst.txt0000664000175000017500000000117215051422642027254 0ustar ghudsonghudsonkrb5_timestamp_to_string - Convert a timestamp to a string. ============================================================= .. .. c:function:: krb5_error_code krb5_timestamp_to_string(krb5_timestamp timestamp, char * buffer, size_t buflen) .. :param: **[in]** **timestamp** - Timestamp to convert **[out]** **buffer** - Buffer to hold converted timestamp **[in]** **buflen** - Storage available in *buffer* .. :retval: - 0 Success; otherwise - Kerberos error codes .. The string is returned in the locale's appropriate date and time representation. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_salt.rst.txt0000664000175000017500000000135015051422642030721 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_salt - Set salt for optimistic preauthentication in initial credential options. ============================================================================================================= .. .. c:function:: void krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt * opt, krb5_data * salt) .. :param: **[in]** **opt** - Options structure **[in]** **salt** - Salt data .. .. When getting initial credentials with a password, a salt string it used to convert the password to a key. Normally this salt is obtained from the first KDC reply, but when performing optimistic preauthentication, the client may need to supply the salt string with this function. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_make_checksum.rst.txt0000664000175000017500000000265415051422642026300 0ustar ghudsonghudsonkrb5_k_make_checksum - Compute a checksum (operates on opaque key). ===================================================================== .. .. c:function:: krb5_error_code krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, const krb5_data * input, krb5_checksum * cksum) .. :param: **[in]** **context** - Library context **[in]** **cksumtype** - Checksum type (0 for mandatory type) **[in]** **key** - Encryption key for a keyed checksum **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[in]** **input** - Input data **[out]** **cksum** - Generated checksum .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function computes a checksum of type *cksumtype* over *input* , using *key* if the checksum type is a keyed checksum. If *cksumtype* is 0 and *key* is non-null, the checksum type will be the mandatory-to-implement checksum type for the key's encryption type. The actual checksum key will be derived from *key* and *usage* if key derivation is specified for the checksum type. The newly created *cksum* must be released by calling krb5_free_checksum_contents() when it is no longer needed. .. .. seealso:: krb5_c_verify_checksum() .. note:: This function is similar to krb5_c_make_checksum(), but operates on opaque *key* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_prf.rst.txt0000664000175000017500000000151015051422642024246 0ustar ghudsonghudsonkrb5_c_prf - Generate enctype-specific pseudo-random bytes. ============================================================= .. .. c:function:: krb5_error_code krb5_c_prf(krb5_context context, const krb5_keyblock * keyblock, krb5_data * input, krb5_data * output) .. :param: **[in]** **context** - Library context **[in]** **keyblock** - Key **[in]** **input** - Input data **[out]** **output** - Output data .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function selects a pseudo-random function based on *keyblock* and computes its value over *input* , placing the result into *output* . The caller must preinitialize *output* and allocate space for the result, using krb5_c_prf_length() to determine the required length. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_unparse_name.rst.txt0000664000175000017500000000141315051422642025634 0ustar ghudsonghudsonkrb5_unparse_name - Convert a krb5_principal structure to a string representation. ==================================================================================== .. .. c:function:: krb5_error_code krb5_unparse_name(krb5_context context, krb5_const_principal principal, char ** name) .. :param: **[in]** **context** - Library context **[in]** **principal** - Principal **[out]** **name** - String representation of principal name .. :retval: - 0 Success :return: - Kerberos error codes .. The resulting string representation uses the format and quoting conventions described for krb5_parse_name(). Use krb5_free_unparsed_name() to free *name* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_random_to_key.rst.txt0000664000175000017500000000170215051422642026314 0ustar ghudsonghudsonkrb5_c_random_to_key - Generate an enctype-specific key from random data. =========================================================================== .. .. c:function:: krb5_error_code krb5_c_random_to_key(krb5_context context, krb5_enctype enctype, krb5_data * random_data, krb5_keyblock * k5_random_key) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[in]** **random_data** - Random input data **[out]** **k5_random_key** - Resulting key .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function takes random input data *random_data* and produces a valid key *k5_random_key* for a given *enctype* . .. .. seealso:: krb5_c_keylengths() .. note:: It is assumed that *k5_random_key* has already been initialized and *k5_random_key->contents* has been allocated with the correct length. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_timeofday.rst.txt0000664000175000017500000000115015051422642025136 0ustar ghudsonghudsonkrb5_timeofday - Retrieve the current time with context specific time offset adjustment. ========================================================================================== .. .. c:function:: krb5_error_code krb5_timeofday(krb5_context context, krb5_timestamp * timeret) .. :param: **[in]** **context** - Library context **[out]** **timeret** - Timestamp to fill in .. :retval: - 0 Success :return: - Kerberos error codes .. This function retrieves the system time of day with the context specific time offset adjustment. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_keyblock_contents.rst.txt0000664000175000017500000000122015051422642027725 0ustar ghudsonghudsonkrb5_copy_keyblock_contents - Copy the contents of a keyblock. ================================================================ .. .. c:function:: krb5_error_code krb5_copy_keyblock_contents(krb5_context context, const krb5_keyblock * from, krb5_keyblock * to) .. :param: **[in]** **context** - Library context **[in]** **from** - Key to be copied **[out]** **to** - Output key .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function copies the contents of *from* to *to* . Use krb5_free_keyblock_contents() to free *to* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_us_timeofday.rst.txt0000664000175000017500000000133315051422642025650 0ustar ghudsonghudsonkrb5_us_timeofday - Retrieve the system time of day, in sec and ms, since the epoch. ====================================================================================== .. .. c:function:: krb5_error_code krb5_us_timeofday(krb5_context context, krb5_timestamp * seconds, krb5_int32 * microseconds) .. :param: **[in]** **context** - Library context **[out]** **seconds** - System timeofday, seconds portion **[out]** **microseconds** - System timeofday, microseconds portion .. :retval: - 0 Success :return: - Kerberos error codes .. This function retrieves the system time of day with the context specific time offset adjustment. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_read_service_key.rst.txt0000664000175000017500000000231315051422642027160 0ustar ghudsonghudsonkrb5_kt_read_service_key - Retrieve a service key from a key table. ===================================================================== .. .. c:function:: krb5_error_code krb5_kt_read_service_key(krb5_context context, krb5_pointer keyprocarg, krb5_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keyblock ** key) .. :param: **[in]** **context** - Library context **[in]** **keyprocarg** - Name of a key table (NULL to use default name) **[in]** **principal** - Service principal **[in]** **vno** - Key version number (0 for highest available) **[in]** **enctype** - Encryption type (0 for any type) **[out]** **key** - Service key from key table .. :retval: - 0 Success :return: - Kerberos error code if not found or keyprocarg is invalid. .. Open and search the specified key table for the entry identified by *principal* , *enctype* , and *vno* . If no key is found, return an error code. The default key table is used, unless *keyprocarg* is non-null. *keyprocarg* designates a specific key table. Use krb5_free_keyblock() to free *key* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_prepend_error_message.rst.txt0000664000175000017500000000115515051422642027534 0ustar ghudsonghudsonkrb5_prepend_error_message - Add a prefix to the message for an error code. ============================================================================= .. .. c:function:: void krb5_prepend_error_message(krb5_context ctx, krb5_error_code code, const char * fmt, ... ) .. :param: **[in]** **ctx** - Library context **[in]** **code** - Error code **[in]** **fmt** - Format string for error message prefix .. .. Format a message and prepend it to the current message for *code* . The prefix will be separated from the old message with a colon and space. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_mk_safe.rst.txt0000664000175000017500000000423015051422642024564 0ustar ghudsonghudsonkrb5_mk_safe - Format a KRB-SAFE message. =========================================== .. .. c:function:: krb5_error_code krb5_mk_safe(krb5_context context, krb5_auth_context auth_context, const krb5_data * userdata, krb5_data * der_out, krb5_replay_data * rdata_out) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **userdata** - User data in the message **[out]** **der_out** - Formatted **KRB-SAFE** buffer **[out]** **rdata_out** - Replay data. Specify NULL if not needed .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates an integrity protected **KRB-SAFE** message using data supplied by the application. Fields in *auth_context* specify the checksum type, the keyblock that can be used to seed the checksum, full addresses (host and port) for the sender and receiver, and KRB5_AUTH_CONTEXT flags. The local address in *auth_context* must be set, and is used to form the sender address used in the KRB-SAFE message. The remote address is optional; if specified, it will be used to form the receiver address used in the message. If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , a timestamp is included in the KRB-SAFE message, and an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If KRB5_AUTH_CONTEXT_RET_TIME is set in *auth_context* , a timestamp is included in the KRB-SAFE message and is stored in *rdata_out* . If either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the *auth_context* local sequence number is included in the KRB-SAFE message and then incremented. If KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in *rdata_out* . Use krb5_free_data_contents() to free *der_out* when it is no longer needed. .. .. note:: The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_string_to_salttype.rst.txt0000664000175000017500000000071615051422642027121 0ustar ghudsonghudsonkrb5_string_to_salttype - Convert a string to a salt type. ============================================================ .. .. c:function:: krb5_error_code krb5_string_to_salttype(char * string, krb5_int32 * salttypep) .. :param: **[in]** **string** - String to convert to an encryption type **[out]** **salttypep** - Salt type to be filled in .. :retval: - 0 Success; otherwise - EINVAL .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kdc_verify_ticket.rst.txt0000664000175000017500000000316215051422642026652 0ustar ghudsonghudsonkrb5_kdc_verify_ticket - Verify a PAC, possibly including ticket signature. ============================================================================= .. .. c:function:: krb5_error_code krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part * enc_tkt, krb5_const_principal server_princ, const krb5_keyblock * server, const krb5_keyblock * privsvr, krb5_pac * pac_out) .. :param: **[in]** **context** - Library context **[in]** **enc_tkt** - Ticket enc-part, possibly containing a PAC **[in]** **server_princ** - Canonicalized name of ticket server **[in]** **server** - Key to validate server checksum (or NULL) **[in]** **privsvr** - Key to validate KDC checksum (or NULL) **[out]** **pac_out** - Verified PAC (NULL if no PAC included) .. :retval: - 0 Success; otherwise - Kerberos error codes .. If a PAC is present in *enc_tkt* , verify its signatures. If *privsvr* is not NULL and *server_princ* is not a krbtgt or kadmin/changepw service, require a ticket signature over *enc_tkt* in addition to the KDC signature. Place the verified PAC in *pac_out* . If an invalid PAC signature is found, return an error matching the Windows KDC protocol code for that condition as closely as possible. If no PAC is present in *enc_tkt* , set *pac_out* to NULL and return successfully. .. .. note:: This function does not validate the PAC_CLIENT_INFO buffer. If a specific value is expected, the caller can make a separate call to krb5_pac_verify_ext() with a principal but no keys. .. note:: New in 1.20 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_ticket.rst.txt0000664000175000017500000000120515051422642025473 0ustar ghudsonghudsonkrb5_copy_ticket - Copy a krb5_ticket structure. ================================================== .. .. c:function:: krb5_error_code krb5_copy_ticket(krb5_context context, const krb5_ticket * from, krb5_ticket ** pto) .. :param: **[in]** **context** - Library context **[in]** **from** - Ticket to be copied **[out]** **pto** - Copy of ticket .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new krb5_ticket structure containing the contents of *from* . Use krb5_free_ticket() to free *pto* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_addresses.rst.txt0000664000175000017500000000125515051422642026172 0ustar ghudsonghudsonkrb5_copy_addresses - Copy an array of addresses. =================================================== .. .. c:function:: krb5_error_code krb5_copy_addresses(krb5_context context, krb5_address *const * inaddr, krb5_address *** outaddr) .. :param: **[in]** **context** - Library context **[in]** **inaddr** - Array of addresses to be copied **[out]** **outaddr** - Copy of array of addresses .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new address array containing a copy of *inaddr* . Use krb5_free_addresses() to free *outaddr* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_set_keytab.rst.txt0000664000175000017500000000126115051422642027515 0ustar ghudsonghudsonkrb5_init_creds_set_keytab - Specify a keytab to use for acquiring initial credentials. ========================================================================================= .. .. c:function:: krb5_error_code krb5_init_creds_set_keytab(krb5_context context, krb5_init_creds_context ctx, krb5_keytab keytab) .. :param: **[in]** **context** - Library context **[in]** **ctx** - Initial credentials context **[in]** **keytab** - Key table handle .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function supplies a keytab containing the client key for an initial credentials request. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_get_flags.rst.txt0000664000175000017500000000114715051422642025563 0ustar ghudsonghudsonkrb5_cc_get_flags - Retrieve flags from a credential cache structure. ======================================================================= .. .. c:function:: krb5_error_code krb5_cc_get_flags(krb5_context context, krb5_ccache cache, krb5_flags * flags) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[out]** **flags** - Flag bit mask .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. .. warning:: For memory credential cache always returns a flag mask of 0. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_encode_authdata_container.rst.txt0000664000175000017500000000151115051422642030330 0ustar ghudsonghudsonkrb5_encode_authdata_container - Wrap authorization data in a container. ========================================================================== .. .. c:function:: krb5_error_code krb5_encode_authdata_container(krb5_context context, krb5_authdatatype type, krb5_authdata *const * authdata, krb5_authdata *** container) .. :param: **[in]** **context** - Library context **[in]** **type** - Container type (see KRB5_AUTHDATA macros) **[in]** **authdata** - List of authorization data to be encoded **[out]** **container** - List of encoded authorization data .. :retval: - 0 Success; otherwise - Kerberos error codes .. The result is returned in *container* as a single-element list. .. .. seealso:: krb5_decode_authdata_container() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_checksum.rst.txt0000664000175000017500000000125515051422642026017 0ustar ghudsonghudsonkrb5_copy_checksum - Copy a krb5_checksum structure. ====================================================== .. .. c:function:: krb5_error_code krb5_copy_checksum(krb5_context context, const krb5_checksum * ckfrom, krb5_checksum ** ckto) .. :param: **[in]** **context** - Library context **[in]** **ckfrom** - Checksum to be copied **[out]** **ckto** - Copy of krb5_checksum structure .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new krb5_checksum structure with the contents of *ckfrom* . Use krb5_free_checksum() to free *ckto* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_unparse_name_flags.rst.txt0000664000175000017500000000211615051422642027011 0ustar ghudsonghudsonkrb5_unparse_name_flags - Convert krb5_principal structure to a string with flags. ==================================================================================== .. .. c:function:: krb5_error_code krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal, int flags, char ** name) .. :param: **[in]** **context** - Library context **[in]** **principal** - Principal **[in]** **flags** - Flags **[out]** **name** - String representation of principal name .. :retval: - 0 Success :return: - Kerberos error codes. On failure name is set to NULL .. Similar to krb5_unparse_name(), this function converts a krb5_principal structure to a string representation. The following flags are valid: - KRB5_PRINCIPAL_UNPARSE_SHORT - omit realm if it is the local realm - KRB5_PRINCIPAL_UNPARSE_NO_REALM - omit realm - KRB5_PRINCIPAL_UNPARSE_DISPLAY - do not quote special characters Use krb5_free_unparsed_name() to free *name* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_pa.rst.txt0000664000175000017500000000146315051422642030363 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_pa - Supply options for preauthentication in initial credential options. ====================================================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_set_pa(krb5_context context, krb5_get_init_creds_opt * opt, const char * attr, const char * value) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options structure **[in]** **attr** - Preauthentication option name **[in]** **value** - Preauthentication option value .. .. This function allows the caller to supply options for preauthentication. The values of *attr* and *value* are supplied to each preauthentication module available within *context* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_responder_get_challenge.rst.txt0000664000175000017500000000166015051422642030025 0ustar ghudsonghudsonkrb5_responder_get_challenge - Retrieve the challenge data for a given question in the responder context. =========================================================================================================== .. .. c:function:: const char * krb5_responder_get_challenge(krb5_context ctx, krb5_responder_context rctx, const char * question) .. :param: **[in]** **ctx** - Library context **[in]** **rctx** - Responder context **[in]** **question** - Question name .. .. Return a pointer to a C string containing the challenge for *question* within *rctx* , or NULL if the question is not present in *rctx* . The structure of the question depends on the question name, but will always be printable UTF-8 text. The returned pointer is an alias, valid only as long as the lifetime of *rctx* , and should not be modified or freed by the caller. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_context.rst.txt0000664000175000017500000000103615051422642025676 0ustar ghudsonghudsonkrb5_copy_context - Copy a krb5_context structure. ==================================================== .. .. c:function:: krb5_error_code krb5_copy_context(krb5_context ctx, krb5_context * nctx_out) .. :param: **[in]** **ctx** - Library context **[out]** **nctx_out** - New context structure .. :retval: - 0 Success :return: - Kerberos error codes .. The newly created context must be released by calling krb5_free_context() when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_principal.rst.txt0000664000175000017500000000056315051422642026146 0ustar ghudsonghudsonkrb5_free_principal - Free the storage assigned to a principal. ================================================================= .. .. c:function:: void krb5_free_principal(krb5_context context, krb5_principal val) .. :param: **[in]** **context** - Library context **[in]** **val** - Principal to be freed .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_responder_set_answer.rst.txt0000664000175000017500000000145615051422642027421 0ustar ghudsonghudsonkrb5_responder_set_answer - Answer a named question in the responder context. =============================================================================== .. .. c:function:: krb5_error_code krb5_responder_set_answer(krb5_context ctx, krb5_responder_context rctx, const char * question, const char * answer) .. :param: **[in]** **ctx** - Library context **[in]** **rctx** - Responder context **[in]** **question** - Question name **[in]** **answer** - The string to set (MUST be printable UTF-8) .. :retval: - EINVAL question is not present within rctx .. This function supplies an answer to *question* within *rctx* . The appropriate form of the answer depends on the question name. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_string_to_timestamp.rst.txt0000664000175000017500000000070115051422642027251 0ustar ghudsonghudsonkrb5_string_to_timestamp - Convert a string to a timestamp. ============================================================= .. .. c:function:: krb5_error_code krb5_string_to_timestamp(char * string, krb5_timestamp * timestampp) .. :param: **[in]** **string** - String to be converted **[out]** **timestampp** - Pointer to timestamp .. :retval: - 0 Success; otherwise - EINVAL .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_ap_rep_enc_part.rst.txt0000664000175000017500000000072015051422642027301 0ustar ghudsonghudsonkrb5_free_ap_rep_enc_part - Free a krb5_ap_rep_enc_part structure. ==================================================================== .. .. c:function:: void krb5_free_ap_rep_enc_part(krb5_context context, krb5_ap_rep_enc_part * val) .. :param: **[in]** **context** - Library context **[in]** **val** - AP-REP enc part to be freed .. .. This function frees the contents of *val* and the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_unparse_name_ext.rst.txt0000664000175000017500000000232015051422642026512 0ustar ghudsonghudsonkrb5_unparse_name_ext - Convert krb5_principal structure to string and length. ================================================================================ .. .. c:function:: krb5_error_code krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, char ** name, unsigned int * size) .. :param: **[in]** **context** - Library context **[in]** **principal** - Principal **[inout]** **name** - String representation of principal name **[inout]** **size** - Size of unparsed name .. :retval: - 0 Success :return: - Kerberos error codes. On failure name is set to NULL .. This function is similar to krb5_unparse_name(), but allows the use of an existing buffer for the result. If size is not NULL, then *name* must point to either NULL or an existing buffer of at least the size pointed to by *size* . The buffer will be allocated or resized if necessary, with the new pointer stored into *name* . Whether or not the buffer is resized, the necessary space for the result, including null terminator, will be stored into *size* . If size is NULL, this function behaves exactly as krb5_unparse_name(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_etype_info.rst.txt0000664000175000017500000000323415051422642026162 0ustar ghudsonghudsonkrb5_get_etype_info - Retrieve enctype, salt and s2kparams from KDC. ====================================================================== .. .. c:function:: krb5_error_code krb5_get_etype_info(krb5_context context, krb5_principal principal, krb5_get_init_creds_opt * opt, krb5_enctype * enctype_out, krb5_data * salt_out, krb5_data * s2kparams_out) .. :param: **[in]** **context** - Library context **[in]** **principal** - Principal whose information is requested **[in]** **opt** - Initial credential options **[out]** **enctype_out** - The enctype chosen by KDC **[out]** **salt_out** - Salt returned from KDC **[out]** **s2kparams_out** - String-to-key parameters returned from KDC .. :retval: - 0 Success :return: - A Kerberos error code .. Send an initial ticket request for *principal* and extract the encryption type, salt type, and string-to-key parameters from the KDC response. If the KDC provides no etype-info, set *enctype_out* to **ENCTYPE_NULL** and set *salt_out* and *s2kparams_out* to empty. If the KDC etype-info provides no salt, compute the default salt and place it in *salt_out* . If the KDC etype-info provides no string-to-key parameters, set *s2kparams_out* to empty. *opt* may be used to specify options which affect the initial request, such as request encryption types or a FAST armor cache (see krb5_get_init_creds_opt_set_etype_list() and krb5_get_init_creds_opt_set_fast_ccache_name()). Use krb5_free_data_contents() to free *salt_out* and *s2kparams_out* when they are no longer needed. .. .. note:: New in 1.17 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_is_coll_proof_cksum.rst.txt0000664000175000017500000000071315051422642027516 0ustar ghudsonghudsonkrb5_c_is_coll_proof_cksum - Test whether a checksum type is collision-proof. =============================================================================== .. .. c:function:: krb5_boolean krb5_c_is_coll_proof_cksum(krb5_cksumtype ctype) .. :param: **[in]** **ctype** - Checksum type .. :return: - TRUE if ctype is collision-proof, FALSE if it is not collision-proof or not a valid checksum type. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_anonymous_principal.rst.txt0000664000175000017500000000057215051422642027255 0ustar ghudsonghudsonkrb5_anonymous_principal - Build an anonymous principal. ========================================================== .. .. c:function:: krb5_const_principal krb5_anonymous_principal(void None) .. :param: **None** .. .. This function returns constant storage that must not be freed. .. .. seealso:: KRB5_ANONYMOUS_PRINCSTR krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_copy_creds.rst.txt0000664000175000017500000000100315051422642025751 0ustar ghudsonghudsonkrb5_cc_copy_creds - Copy a credential cache. =============================================== .. .. c:function:: krb5_error_code krb5_cc_copy_creds(krb5_context context, krb5_ccache incc, krb5_ccache outcc) .. :param: **[in]** **context** - Library context **[in]** **incc** - Credential cache to be copied **[out]** **outcc** - Copy of credential cache to be filled in .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_anonymous.rst.txt0000664000175000017500000000132615051422642032011 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_anonymous - Set or unset the anonymous flag in initial credential options. ======================================================================================================== .. .. c:function:: void krb5_get_init_creds_opt_set_anonymous(krb5_get_init_creds_opt * opt, int anonymous) .. :param: **[in]** **opt** - Options structure **[in]** **anonymous** - Whether to make an anonymous request .. .. This function may be used to request anonymous credentials from the KDC by setting *anonymous* to non-zero. Note that anonymous credentials are only a request; clients must verify that credentials are anonymous if that is a requirement. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_mk_priv.rst.txt0000664000175000017500000000375615051422642024642 0ustar ghudsonghudsonkrb5_mk_priv - Format a KRB-PRIV message. =========================================== .. .. c:function:: krb5_error_code krb5_mk_priv(krb5_context context, krb5_auth_context auth_context, const krb5_data * userdata, krb5_data * der_out, krb5_replay_data * rdata_out) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **userdata** - User data for **KRB-PRIV** message **[out]** **der_out** - Formatted **KRB-PRIV** message **[out]** **rdata_out** - Replay data (NULL if not needed) .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function is similar to krb5_mk_safe(), but the message is encrypted and integrity-protected, not just integrity-protected. The local address in *auth_context* must be set, and is used to form the sender address used in the KRB-PRIV message. The remote address is optional; if specified, it will be used to form the receiver address used in the message. If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , a timestamp is included in the KRB-PRIV message, and an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If KRB5_AUTH_CONTEXT_RET_TIME is set in *auth_context* , a timestamp is included in the KRB-PRIV message and is stored in *rdata_out* . If either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the *auth_context* local sequence number is included in the KRB-PRIV message and then incremented. If KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in *rdata_out* . Use krb5_free_data_contents() to free *der_out* when it is no longer needed. .. .. note:: The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_resolve.rst.txt0000664000175000017500000000141215051422642025302 0ustar ghudsonghudsonkrb5_cc_resolve - Resolve a credential cache name. ==================================================== .. .. c:function:: krb5_error_code krb5_cc_resolve(krb5_context context, const char * name, krb5_ccache * cache) .. :param: **[in]** **context** - Library context **[in]** **name** - Credential cache name to be resolved **[out]** **cache** - Credential cache handle .. :retval: - 0 Success :return: - Kerberos error codes .. Fills in *cache* with a *cache* handle that corresponds to the name in *name* . *name* should be of the form **type:residual** , and *type* must be a type known to the library. If the *name* does not contain a colon, interpret it as a file name. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_default_realm.rst.txt0000664000175000017500000000113115051422642026617 0ustar ghudsonghudsonkrb5_get_default_realm - Retrieve the default realm. ====================================================== .. .. c:function:: krb5_error_code krb5_get_default_realm(krb5_context context, char ** lrealm) .. :param: **[in]** **context** - Library context **[out]** **lrealm** - Default realm name .. :retval: - 0 Success :return: - Kerberos error codes .. Retrieves the default realm to be used if no user-specified realm is available. Use krb5_free_default_realm() to free *lrealm* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_support_switch.rst.txt0000664000175000017500000000111515051422642026720 0ustar ghudsonghudsonkrb5_cc_support_switch - Determine whether a credential cache type supports switching. ======================================================================================== .. .. c:function:: krb5_boolean krb5_cc_support_switch(krb5_context context, const char * type) .. :param: **[in]** **context** - Library context **[in]** **type** - Credential cache type .. :retval: - TRUE if type supports switching - FALSE if it does not or is not a valid credential cache type. .. .. .. note:: New in 1.10 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_select.rst.txt0000664000175000017500000000316115051422642025105 0ustar ghudsonghudsonkrb5_cc_select - Select a credential cache to use with a server principal. ============================================================================ .. .. c:function:: krb5_error_code krb5_cc_select(krb5_context context, krb5_principal server, krb5_ccache * cache_out, krb5_principal * princ_out) .. :param: **[in]** **context** - Library context **[in]** **server** - Server principal **[out]** **cache_out** - Credential cache handle **[out]** **princ_out** - Client principal .. :return: - If an appropriate cache is found, 0 is returned, cache_out is set to the selected cache, and princ_out is set to the default principal of that cache. .. Select a cache within the collection containing credentials most appropriate for use with *server* , according to configured rules and heuristics. Use krb5_cc_close() to release *cache_out* when it is no longer needed. Use krb5_free_principal() to release *princ_out* when it is no longer needed. Note that *princ_out* is set in some error conditions. If the appropriate client principal can be authoritatively determined but the cache collection contains no credentials for that principal, then KRB5_CC_NOTFOUND is returned, *cache_out* is set to NULL, and *princ_out* is set to the appropriate client principal. If no configured mechanism can determine the appropriate cache or principal, KRB5_CC_NOTFOUND is returned and *cache_out* and *princ_out* are set to NULL. Any other error code indicates a fatal error in the processing of a cache selection mechanism. .. .. note:: New in 1.10 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_tkt_creds_get.rst.txt0000664000175000017500000000130515051422642026000 0ustar ghudsonghudsonkrb5_tkt_creds_get - Synchronously obtain credentials using a TGS request context. ==================================================================================== .. .. c:function:: krb5_error_code krb5_tkt_creds_get(krb5_context context, krb5_tkt_creds_context ctx) .. :param: **[in]** **context** - Library context **[in]** **ctx** - TGS request context .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function synchronously obtains credentials using a context created by krb5_tkt_creds_init(). On successful return, the credentials can be retrieved with krb5_tkt_creds_get_creds(). .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_error_message.rst.txt0000664000175000017500000000074715051422642027057 0ustar ghudsonghudsonkrb5_copy_error_message - Copy the most recent extended error message from one context to another. ==================================================================================================== .. .. c:function:: void krb5_copy_error_message(krb5_context dest_ctx, krb5_context src_ctx) .. :param: **[in]** **dest_ctx** - Library context to copy message to **[in]** **src_ctx** - Library context with current message .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_get_checksum_func.rst.txt0000664000175000017500000000117615051422642030521 0ustar ghudsonghudsonkrb5_auth_con_get_checksum_func - Get the checksum callback from an auth context. =================================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_get_checksum_func(krb5_context context, krb5_auth_context auth_context, krb5_mk_req_checksum_func * func, void ** data) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **func** - Checksum callback **[out]** **data** - Callback argument .. :retval: - 0 (always) .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_encrypt.rst.txt0000664000175000017500000000066115051422642024647 0ustar ghudsonghudsonkrb5_encrypt ============ .. .. c:function:: krb5_error_code krb5_encrypt(krb5_context context, krb5_const_pointer inptr, krb5_pointer outptr, size_t size, krb5_encrypt_block * eblock, krb5_pointer ivec) .. :param: **context** **inptr** **outptr** **size** **eblock** **ivec** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_setports.rst.txt0000664000175000017500000000156615051422642026733 0ustar ghudsonghudsonkrb5_auth_con_setports - Set local and remote port fields in an auth context. =============================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb5_address * local_port, krb5_address * remote_port) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **local_port** - Local port **[in]** **remote_port** - Remote port .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function releases the storage assigned to the contents of the local and remote ports of *auth_context* and then sets them to *local_port* and *remote_port* respectively. .. .. seealso:: krb5_auth_con_genaddrs() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_get_config.rst.txt0000664000175000017500000000150015051422642025725 0ustar ghudsonghudsonkrb5_cc_get_config - Get a configuration value from a credential cache. ========================================================================= .. .. c:function:: krb5_error_code krb5_cc_get_config(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char * key, krb5_data * data) .. :param: **[in]** **context** - Library context **[in]** **id** - Credential cache handle **[in]** **principal** - Configuration for this principal; if NULL, global for the whole cache **[in]** **key** - Name of config variable **[out]** **data** - Data to be fetched .. :retval: - 0 Success :return: - Kerberos error codes .. Use krb5_free_data_contents() to free *data* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_get_buffer.rst.txt0000664000175000017500000000117615051422642026120 0ustar ghudsonghudsonkrb5_pac_get_buffer - Retrieve a buffer value from a PAC. =========================================================== .. .. c:function:: krb5_error_code krb5_pac_get_buffer(krb5_context context, krb5_pac pac, krb5_ui_4 type, krb5_data * data) .. :param: **[in]** **context** - Library context **[in]** **pac** - PAC handle **[in]** **type** - Type of buffer to retrieve **[out]** **data** - Buffer value .. :retval: - 0 Success; otherwise - Kerberos error codes .. Use krb5_free_data_contents() to free *data* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_get_name.rst.txt0000664000175000017500000000131315051422642025433 0ustar ghudsonghudsonkrb5_kt_get_name - Get a key table name. ========================================== .. .. c:function:: krb5_error_code krb5_kt_get_name(krb5_context context, krb5_keytab keytab, char * name, unsigned int namelen) .. :param: **[in]** **context** - Library context **[in]** **keytab** - Key table handle **[out]** **name** - Key table name **[in]** **namelen** - Maximum length to fill in name .. :retval: - 0 Success - KRB5_KT_NAME_TOOLONG Key table name does not fit in namelen bytes :return: - Kerberos error codes .. Fill *name* with the name of *keytab* including the type and delimiter. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_cache_match.rst.txt0000664000175000017500000000134615051422642026050 0ustar ghudsonghudsonkrb5_cc_cache_match - Find a credential cache with a specified client principal. ================================================================================== .. .. c:function:: krb5_error_code krb5_cc_cache_match(krb5_context context, krb5_principal client, krb5_ccache * cache_out) .. :param: **[in]** **context** - Library context **[in]** **client** - Client principal **[out]** **cache_out** - Credential cache handle .. :retval: - 0 Success - KRB5_CC_NOTFOUND .. Find a cache within the collection whose default principal is *client* . Use *krb5_cc_close* to close *ccache* when it is no longer needed. .. .. note:: New in 1.10 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_start_seq_get.rst.txt0000664000175000017500000000127115051422642026523 0ustar ghudsonghudsonkrb5_kt_start_seq_get - Start a sequential retrieval of key table entries. ============================================================================ .. .. c:function:: krb5_error_code krb5_kt_start_seq_get(krb5_context context, krb5_keytab keytab, krb5_kt_cursor * cursor) .. :param: **[in]** **context** - Library context **[in]** **keytab** - Key table handle **[out]** **cursor** - Cursor .. :retval: - 0 Success :return: - Kerberos error codes .. Prepare to read sequentially every key in the specified key table. Use krb5_kt_end_seq_get() to release the cursor when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_encrypt_iov.rst.txt0000664000175000017500000000315715051422642026031 0ustar ghudsonghudsonkrb5_c_encrypt_iov - Encrypt data in place supporting AEAD (operates on keyblock). ==================================================================================== .. .. c:function:: krb5_error_code krb5_c_encrypt_iov(krb5_context context, const krb5_keyblock * keyblock, krb5_keyusage usage, const krb5_data * cipher_state, krb5_crypto_iov * data, size_t num_data) .. :param: **[in]** **context** - Library context **[in]** **keyblock** - Encryption key **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[in]** **cipher_state** - Cipher state; specify NULL if not needed **[inout]** **data** - IOV array. Modified in-place. **[in]** **num_data** - Size of *data* .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function encrypts the data block *data* and stores the output in-place. The actual encryption key will be derived from *keyblock* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5_crypto_iov structures before calling into this API. .. .. seealso:: krb5_c_decrypt_iov() .. note:: On return from a krb5_c_encrypt_iov() call, the *data->length* in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_build_principal_alloc_va.rst.txt0000664000175000017500000000172415051422642030164 0ustar ghudsonghudsonkrb5_build_principal_alloc_va - Build a principal name, using a precomputed variable argument list. ===================================================================================================== .. .. c:function:: krb5_error_code krb5_build_principal_alloc_va(krb5_context context, krb5_principal * princ, unsigned int rlen, const char * realm, va_list ap) .. :param: **[in]** **context** - Library context **[out]** **princ** - Principal structure **[in]** **rlen** - Realm name length **[in]** **realm** - Realm name **[in]** **ap** - List of char * components, ending with NULL .. :retval: - 0 Success :return: - Kerberos error codes .. Similar to krb5_build_principal(), this function builds a principal name, but its name components are specified as a va_list. Use krb5_free_principal() to deallocate *princ* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_mk_error.rst.txt0000664000175000017500000000123515051422642025001 0ustar ghudsonghudsonkrb5_mk_error - Format and encode a KRB_ERROR message. ======================================================== .. .. c:function:: krb5_error_code krb5_mk_error(krb5_context context, const krb5_error * dec_err, krb5_data * enc_err) .. :param: **[in]** **context** - Library context **[in]** **dec_err** - Error structure to be encoded **[out]** **enc_err** - Encoded error structure .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a **KRB_ERROR** message in *enc_err* . Use krb5_free_data_contents() to free *enc_err* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_genaddrs.rst.txt0000664000175000017500000000216415051422642026632 0ustar ghudsonghudsonkrb5_auth_con_genaddrs - Generate auth context addresses from a connected socket. =================================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_genaddrs(krb5_context context, krb5_auth_context auth_context, int infd, int flags) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **infd** - Connected socket descriptor **[in]** **flags** - Flags .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function sets the local and/or remote addresses in *auth_context* based on the local and remote endpoints of the socket *infd* . The following flags determine the operations performed: - KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR Generate local address. - KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR Generate remote address. - KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR Generate local address and port. - KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR Generate remote address and port. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_new_unique.rst.txt0000664000175000017500000000121615051422642026004 0ustar ghudsonghudsonkrb5_cc_new_unique - Create a new credential cache of the specified type with a unique name. ============================================================================================== .. .. c:function:: krb5_error_code krb5_cc_new_unique(krb5_context context, const char * type, const char * hint, krb5_ccache * id) .. :param: **[in]** **context** - Library context **[in]** **type** - Credential cache type name **[in]** **hint** - Unused **[out]** **id** - Credential cache handle .. :retval: - 0 Success :return: - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_in_tkt_with_keytab.rst.txt0000664000175000017500000000123715051422642027704 0ustar ghudsonghudsonkrb5_get_in_tkt_with_keytab =========================== .. .. c:function:: krb5_error_code krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options, krb5_address *const * addrs, krb5_enctype * ktypes, krb5_preauthtype * pre_auth_types, krb5_keytab arg_keytab, krb5_ccache ccache, krb5_creds * creds, krb5_kdc_rep ** ret_as_reply) .. :param: **context** **options** **addrs** **ktypes** **pre_auth_types** **arg_keytab** **ccache** **creds** **ret_as_reply** .. .. DEPRECATED Replaced by krb5_get_init_creds_keytab(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_checksum_contents.rst.txt0000664000175000017500000000112715051422642027701 0ustar ghudsonghudsonkrb5_free_checksum_contents - Free the contents of a krb5_checksum structure. =============================================================================== .. .. c:function:: void krb5_free_checksum_contents(krb5_context context, krb5_checksum * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Checksum structure to free contents of .. .. This function frees the contents of *val* , but not the structure itself. It sets the checksum's data pointer to null and (beginning in release 1.19) sets its length to zero. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_set_service.rst.txt0000664000175000017500000000145115051422642027677 0ustar ghudsonghudsonkrb5_init_creds_set_service - Specify a service principal for acquiring initial credentials. ============================================================================================== .. .. c:function:: krb5_error_code krb5_init_creds_set_service(krb5_context context, krb5_init_creds_context ctx, const char * service) .. :param: **[in]** **context** - Library context **[in]** **ctx** - Initial credentials context **[in]** **service** - Service principal string .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function supplies a service principal string to acquire initial credentials for instead of the default krbtgt service. *service* is parsed as a principal name; any realm part is ignored. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_secure_context.rst.txt0000664000175000017500000000124715051422642027241 0ustar ghudsonghudsonkrb5_init_secure_context - Create a krb5 library context using only configuration files. ========================================================================================== .. .. c:function:: krb5_error_code krb5_init_secure_context(krb5_context * context) .. :param: **[out]** **context** - Library context .. :retval: - 0 Success :return: - Kerberos error codes .. Create a context structure, using only system configuration files. All information passed through the environment variables is ignored. The *context* must be released by calling krb5_free_context() when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_default.rst.txt0000664000175000017500000000076315051422642025310 0ustar ghudsonghudsonkrb5_kt_default - Resolve the default key table. ================================================== .. .. c:function:: krb5_error_code krb5_kt_default(krb5_context context, krb5_keytab * id) .. :param: **[in]** **context** - Library context **[out]** **id** - Key table handle .. :retval: - 0 Success :return: - Kerberos error codes .. Set *id* to a handle to the default key table. The key table is not opened. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_principal_realm.rst.txt0000664000175000017500000000115415051422642027175 0ustar ghudsonghudsonkrb5_set_principal_realm - Set the realm field of a principal. ================================================================ .. .. c:function:: krb5_error_code krb5_set_principal_realm(krb5_context context, krb5_principal principal, const char * realm) .. :param: **[in]** **context** - Library context **[in]** **principal** - Principal name **[in]** **realm** - Realm name .. :retval: - 0 Success :return: - Kerberos error codes .. Set the realm name part of *principal* to *realm* , overwriting the previous realm. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_rd_rep.rst.txt0000664000175000017500000000153415051422642024436 0ustar ghudsonghudsonkrb5_rd_rep - Parse and decrypt a KRB_AP_REP message. ======================================================= .. .. c:function:: krb5_error_code krb5_rd_rep(krb5_context context, krb5_auth_context auth_context, const krb5_data * inbuf, krb5_ap_rep_enc_part ** repl) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **inbuf** - AP-REP message **[out]** **repl** - Decrypted reply message .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function parses, decrypts and verifies a message from *inbuf* and fills in *repl* with a pointer to allocated memory containing the fields from the encrypted response. Use krb5_free_ap_rep_enc_part() to free *repl* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_wrap_error_message.rst.txt0000664000175000017500000000137515051422642027054 0ustar ghudsonghudsonkrb5_wrap_error_message - Add a prefix to a different error code's message. ============================================================================= .. .. c:function:: void krb5_wrap_error_message(krb5_context ctx, krb5_error_code old_code, krb5_error_code code, const char * fmt, ... ) .. :param: **[in]** **ctx** - Library context **[in]** **old_code** - Previous error code **[in]** **code** - Error code **[in]** **fmt** - Format string for error message prefix .. .. Format a message and prepend it to the message for *old_code* . The prefix will be separated from the old message with a colon and space. Set the resulting message as the extended error message for *code* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_set_config.rst.txt0000664000175000017500000000164415051422642025752 0ustar ghudsonghudsonkrb5_cc_set_config - Store a configuration value in a credential cache. ========================================================================= .. .. c:function:: krb5_error_code krb5_cc_set_config(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char * key, krb5_data * data) .. :param: **[in]** **context** - Library context **[in]** **id** - Credential cache handle **[in]** **principal** - Configuration for a specific principal; if NULL, global for the whole cache **[in]** **key** - Name of config variable **[in]** **data** - Data to store, or NULL to remove .. :retval: - 0 Success :return: - Kerberos error codes .. .. .. warning:: Before version 1.10 *data* was assumed to be always non-null. .. note:: Existing configuration under the same key is over-written. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_get_fast_flags.rst.txt0000664000175000017500000000112415051422642032052 0ustar ghudsonghudsonkrb5_get_init_creds_opt_get_fast_flags - Retrieve FAST flags from initial credential options. =============================================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_get_fast_flags(krb5_context context, krb5_get_init_creds_opt * opt, krb5_flags * out_flags) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options **[out]** **out_flags** - FAST flags .. :retval: - 0 - Success; Kerberos errors otherwise. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_responder_list_questions.rst.txt0000664000175000017500000000146315051422642030332 0ustar ghudsonghudsonkrb5_responder_list_questions - List the question names contained in the responder context. ============================================================================================= .. .. c:function:: const char *const * krb5_responder_list_questions(krb5_context ctx, krb5_responder_context rctx) .. :param: **[in]** **ctx** - Library context **[in]** **rctx** - Responder context .. .. Return a pointer to a null-terminated list of question names which are present in *rctx* . The pointer is an alias, valid only as long as the lifetime of *rctx* , and should not be modified or freed by the caller. A question's challenge can be retrieved using krb5_responder_get_challenge() and answered using krb5_responder_set_answer(). .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_create_key.rst.txt0000664000175000017500000000122615051422642025606 0ustar ghudsonghudsonkrb5_k_create_key - Create a krb5_key from the enctype and key data in a keyblock. ==================================================================================== .. .. c:function:: krb5_error_code krb5_k_create_key(krb5_context context, const krb5_keyblock * key_data, krb5_key * out) .. :param: **[in]** **context** - Library context **[in]** **key_data** - Keyblock **[out]** **out** - Opaque key .. :retval: - 0 Success; otherwise - KRB5_BAD_ENCTYPE .. The reference count on a key *out* is set to 1. Use krb5_k_free_key() to free *out* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_setaddrs.rst.txt0000664000175000017500000000160415051422642026652 0ustar ghudsonghudsonkrb5_auth_con_setaddrs - Set the local and remote addresses in an auth context. ================================================================================= .. .. c:function:: krb5_error_code krb5_auth_con_setaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address * local_addr, krb5_address * remote_addr) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **local_addr** - Local address **[in]** **remote_addr** - Remote address .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function releases the storage assigned to the contents of the local and remote addresses of *auth_context* and then sets them to *local_addr* and *remote_addr* respectively. .. .. seealso:: krb5_auth_con_genaddrs() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_crypto_length_iov.rst.txt0000664000175000017500000000157715051422642027232 0ustar ghudsonghudsonkrb5_c_crypto_length_iov - Fill in lengths for header, trailer and padding in a IOV array. ============================================================================================ .. .. c:function:: krb5_error_code krb5_c_crypto_length_iov(krb5_context context, krb5_enctype enctype, krb5_crypto_iov * data, size_t num_data) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[inout]** **data** - IOV array **[in]** **num_data** - Size of *data* .. :retval: - 0 Success; otherwise - Kerberos error codes .. Padding is set to the actual padding required based on the provided *data* buffers. Typically this API is used after setting up the data buffers and KRB5_CRYPTO_TYPE_SIGN_ONLY buffers, but before actually allocating header, trailer and padding. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_random_key.rst.txt0000664000175000017500000000061215051422642026332 0ustar ghudsonghudsonkrb5_init_random_key ==================== .. .. c:function:: krb5_error_code krb5_init_random_key(krb5_context context, const krb5_encrypt_block * eblock, const krb5_keyblock * keyblock, krb5_pointer * ptr) .. :param: **context** **eblock** **keyblock** **ptr** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_start_seq_get.rst.txt0000664000175000017500000000160315051422642026471 0ustar ghudsonghudsonkrb5_cc_start_seq_get - Prepare to sequentially read every credential in a credential cache. ============================================================================================== .. .. c:function:: krb5_error_code krb5_cc_start_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor * cursor) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[out]** **cursor** - Cursor .. :retval: - 0 Success; otherwise - Kerberos error codes .. krb5_cc_end_seq_get() must be called to complete the retrieve operation. .. .. note:: If the cache represented by *cache* is modified between the time of the call to this function and the time of the final krb5_cc_end_seq_get(), these changes may not be reflected in the results of krb5_cc_next_cred() calls. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_string_to_key.rst.txt0000664000175000017500000000065215051422642026043 0ustar ghudsonghudsonkrb5_string_to_key ================== .. .. c:function:: krb5_error_code krb5_string_to_key(krb5_context context, const krb5_encrypt_block * eblock, krb5_keyblock * keyblock, const krb5_data * data, const krb5_data * salt) .. :param: **context** **eblock** **keyblock** **data** **salt** .. .. DEPRECATED See krb5_c_string_to_key() .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_init.rst.txt0000664000175000017500000000041515051422642030047 0ustar ghudsonghudsonkrb5_get_init_creds_opt_init ============================ .. .. c:function:: void krb5_get_init_creds_opt_init(krb5_get_init_creds_opt * opt) .. :param: **opt** .. .. DEPRECATED Use krb5_get_init_creds_opt_alloc() instead. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_build_principal_va.rst.txt0000664000175000017500000000064115051422642027007 0ustar ghudsonghudsonkrb5_build_principal_va ======================= .. .. c:function:: krb5_error_code krb5_build_principal_va(krb5_context context, krb5_principal princ, unsigned int rlen, const char * realm, va_list ap) .. :param: **context** **princ** **rlen** **realm** **ap** .. .. DEPRECATED Replaced by krb5_build_principal_alloc_va(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_store_cred.rst.txt0000664000175000017500000000141615051422642025760 0ustar ghudsonghudsonkrb5_cc_store_cred - Store credentials in a credential cache. =============================================================== .. .. c:function:: krb5_error_code krb5_cc_store_cred(krb5_context context, krb5_ccache cache, krb5_creds * creds) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[in]** **creds** - Credentials to be stored in cache .. :retval: - 0 Success :return: - Permission errors; storage failure errors; Kerberos error codes .. This function stores *creds* into *cache* . If *creds->server* and the server in the decoded ticket *creds->ticket* differ, the credentials will be stored under both server principal names. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_keytab_entry_contents.rst.txt0000664000175000017500000000106215051422642030575 0ustar ghudsonghudsonkrb5_free_keytab_entry_contents - Free the contents of a key table entry. =========================================================================== .. .. c:function:: krb5_error_code krb5_free_keytab_entry_contents(krb5_context context, krb5_keytab_entry * entry) .. :param: **[in]** **context** - Library context **[in]** **entry** - Key table entry whose contents are to be freed .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. .. note:: The pointer is not freed. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_verify_checksum_iov.rst.txt0000664000175000017500000000242015051422642027523 0ustar ghudsonghudsonkrb5_c_verify_checksum_iov - Validate a checksum element in IOV array (operates on keyblock). =============================================================================================== .. .. c:function:: krb5_error_code krb5_c_verify_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock * key, krb5_keyusage usage, const krb5_crypto_iov * data, size_t num_data, krb5_boolean * valid) .. :param: **[in]** **context** - Library context **[in]** **cksumtype** - Checksum type (0 for mandatory type) **[in]** **key** - Encryption key for a keyed checksum **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[in]** **data** - IOV array **[in]** **num_data** - Size of *data* **[out]** **valid** - Non-zero for success, zero for failure .. :retval: - 0 Success; otherwise - Kerberos error codes .. Confirm that the checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element is a valid checksum of the KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY regions in the iov. .. .. seealso:: krb5_c_make_checksum_iov() .. note:: This function is similar to krb5_k_verify_checksum_iov(), but operates on keyblock *key* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_expire_callback.rst.txt0000664000175000017500000000400515051422642033066 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_expire_callback - Set an expiration callback in initial credential options. ========================================================================================================= .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_set_expire_callback(krb5_context context, krb5_get_init_creds_opt * opt, krb5_expire_callback_func cb, void * data) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options structure **[in]** **cb** - Callback function **[in]** **data** - Callback argument .. .. Set a callback to receive password and account expiration times. *cb* will be invoked if and only if credentials are successfully acquired. The callback will receive the *context* from the calling function and the *data* argument supplied with this API. The remaining arguments should be interpreted as follows: If *is_last_req* is true, then the KDC reply contained last-req entries which unambiguously indicated the password expiration, account expiration, or both. (If either value was not present, the corresponding argument will be 0.) Furthermore, a non-zero *password_expiration* should be taken as a suggestion from the KDC that a warning be displayed. If *is_last_req* is false, then *account_expiration* will be 0 and *password_expiration* will contain the expiration time of either the password or account, or 0 if no expiration time was indicated in the KDC reply. The callback should independently decide whether to display a password expiration warning. Note that *cb* may be invoked even if credentials are being acquired for the kadmin/changepw service in order to change the password. It is the caller's responsibility to avoid displaying a password expiry warning in this case. .. .. warning:: Setting an expire callback with this API will cause krb5_get_init_creds_password() not to send password expiry warnings to the prompter, as it ordinarily may. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_finish_key.rst.txt0000664000175000017500000000042415051422642025310 0ustar ghudsonghudsonkrb5_finish_key =============== .. .. c:function:: krb5_error_code krb5_finish_key(krb5_context context, krb5_encrypt_block * eblock) .. :param: **context** **eblock** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_add_entry.rst.txt0000664000175000017500000000113315051422642025625 0ustar ghudsonghudsonkrb5_kt_add_entry - Add a new entry to a key table. ===================================================== .. .. c:function:: krb5_error_code krb5_kt_add_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry * entry) .. :param: **[in]** **context** - Library context **[in]** **id** - Key table handle **[in]** **entry** - Entry to be added .. :retval: - 0 Success - ENOMEM Insufficient memory - KRB5_KT_NOWRITE Key table is not writeable :return: - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getflags.rst.txt0000664000175000017500000000142415051422642026635 0ustar ghudsonghudsonkrb5_auth_con_getflags - Retrieve flags from a krb5_auth_context structure. ============================================================================= .. .. c:function:: krb5_error_code krb5_auth_con_getflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 * flags) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **flags** - Flags bit mask .. :retval: - 0 (always) .. Valid values for *flags* are: - KRB5_AUTH_CONTEXT_DO_TIME Use timestamps - KRB5_AUTH_CONTEXT_RET_TIME Save timestamps - KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers - KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_initialize.rst.txt0000664000175000017500000000122515051422642025766 0ustar ghudsonghudsonkrb5_cc_initialize - Initialize a credential cache. ===================================================== .. .. c:function:: krb5_error_code krb5_cc_initialize(krb5_context context, krb5_ccache cache, krb5_principal principal) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[in]** **principal** - Default principal name .. :retval: - 0 Success :return: - System errors; Permission errors; Kerberos error codes .. Destroy any existing contents of *cache* and initialize it for the default principal *principal* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_verify.rst.txt0000664000175000017500000000267315051422642025317 0ustar ghudsonghudsonkrb5_pac_verify - Verify a PAC. ================================= .. .. c:function:: krb5_error_code krb5_pac_verify(krb5_context context, const krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock * server, const krb5_keyblock * privsvr) .. :param: **[in]** **context** - Library context **[in]** **pac** - PAC handle **[in]** **authtime** - Expected timestamp **[in]** **principal** - Expected principal name (or NULL) **[in]** **server** - Key to validate server checksum (or NULL) **[in]** **privsvr** - Key to validate KDC checksum (or NULL) .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function validates *pac* against the supplied *server* , *privsvr* , *principal* and *authtime* . If *principal* is NULL, the principal and authtime are not verified. If *server* or *privsvr* is NULL, the corresponding checksum is not verified. If successful, *pac* is marked as verified. .. .. note:: A checksum mismatch can occur if the PAC was copied from a cross-realm TGT by an ignorant KDC; also macOS Server Open Directory (as of 10.6) generates PACs with no server checksum at all. One should consider not failing the whole authentication because of this reason, but, instead, treating the ticket as if it did not contain a PAC or marking the PAC information as non-verified. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_error_message.rst.txt0000664000175000017500000000063615051422642027023 0ustar ghudsonghudsonkrb5_free_error_message - Free an error message generated by krb5_get_error_message(). ======================================================================================== .. .. c:function:: void krb5_free_error_message(krb5_context ctx, const char * msg) .. :param: **[in]** **ctx** - Library context **[in]** **msg** - Pointer to error message .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_key_enctype.rst.txt0000664000175000017500000000047315051422642026015 0ustar ghudsonghudsonkrb5_k_key_enctype - Retrieve the enctype of a krb5_key structure. ==================================================================== .. .. c:function:: krb5_enctype krb5_k_key_enctype(krb5_context context, krb5_key key) .. :param: **context** **key** .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_address_order.rst.txt0000664000175000017500000000116115051422642025777 0ustar ghudsonghudsonkrb5_address_order - Return an ordering of the specified addresses. ===================================================================== .. .. c:function:: int krb5_address_order(krb5_context context, const krb5_address * addr1, const krb5_address * addr2) .. :param: **[in]** **context** - Library context **[in]** **addr1** - First address **[in]** **addr2** - Second address .. :retval: - 0 if The two addresses are the same - < 0 First address is less than second - > 0 First address is greater than second .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_context_profile.rst.txt0000664000175000017500000000174715051422642027420 0ustar ghudsonghudsonkrb5_init_context_profile - Create a krb5 library context using a specified profile. ====================================================================================== .. .. c:function:: krb5_error_code krb5_init_context_profile(struct _profile_t * profile, krb5_flags flags, krb5_context * context) .. :param: **[in]** **profile** - Profile object (NULL to create default profile) **[in]** **flags** - Context initialization flags **[out]** **context** - Library context .. .. Create a context structure, optionally using a specified profile and initialization flags. If *profile* is NULL, the default profile will be created from config files. If *profile* is non-null, a copy of it will be made for the new context; the caller should still clean up its copy. Valid flag values are: - KRB5_INIT_CONTEXT_SECURE Ignore environment variables - KRB5_INIT_CONTEXT_KDC Use KDC configuration if creating profile .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_appdefault_string.rst.txt0000664000175000017500000000164015051422642026674 0ustar ghudsonghudsonkrb5_appdefault_string - Retrieve a string value from the appdefaults section of krb5.conf. ============================================================================================= .. .. c:function:: void krb5_appdefault_string(krb5_context context, const char * appname, const krb5_data * realm, const char * option, const char * default_value, char ** ret_value) .. :param: **[in]** **context** - Library context **[in]** **appname** - Application name **[in]** **realm** - Realm name **[in]** **option** - Option to be checked **[in]** **default_value** - Default value to return if no match is found **[out]** **ret_value** - String value of *option* .. .. This function gets the application defaults for *option* based on the given *appname* and/or *realm* . .. .. seealso:: krb5_appdefault_boolean() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_string_to_deltat.rst.txt0000664000175000017500000000072215051422642026526 0ustar ghudsonghudsonkrb5_string_to_deltat - Convert a string to a delta time value. ================================================================= .. .. c:function:: krb5_error_code krb5_string_to_deltat(char * string, krb5_deltat * deltatp) .. :param: **[in]** **string** - String to be converted **[out]** **deltatp** - Delta time to be filled in .. :retval: - 0 Success; otherwise - KRB5_DELTAT_BADFORMAT .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_pac_request.rst.txt0000664000175000017500000000161615051422642032276 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_pac_request - Ask the KDC to include or not include a PAC in the ticket. ====================================================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_set_pac_request(krb5_context context, krb5_get_init_creds_opt * opt, krb5_boolean req_pac) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options structure **[in]** **req_pac** - Whether to request a PAC or not .. .. If this option is set, the AS request will include a PAC-REQUEST pa-data item explicitly asking the KDC to either include or not include a privilege attribute certificate in the ticket authorization data. By default, no request is made; typically the KDC will default to including a PAC if it supports them. .. .. note:: New in 1.15 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_encrypt_size.rst.txt0000664000175000017500000000040115051422642025671 0ustar ghudsonghudsonkrb5_encrypt_size ================= .. .. c:function:: size_t krb5_encrypt_size(size_t length, krb5_enctype crypto) .. :param: **length** **crypto** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_cksumtypes.rst.txt0000664000175000017500000000056415051422642026375 0ustar ghudsonghudsonkrb5_free_cksumtypes - Free an array of checksum types. ========================================================= .. .. c:function:: void krb5_free_cksumtypes(krb5_context context, krb5_cksumtype * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Array of checksum types to be freed .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_setrecvsubkey_k.rst.txt0000664000175000017500000000123115051422642030245 0ustar ghudsonghudsonkrb5_auth_con_setrecvsubkey_k - Set the receiving subkey in an auth context. ============================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_setrecvsubkey_k(krb5_context ctx, krb5_auth_context ac, krb5_key key) .. :param: **[in]** **ctx** - Library context **[in]** **ac** - Authentication context **[in]** **key** - Receiving subkey .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function sets the receiving subkey in *ac* to *key* , incrementing its reference count. .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_get_error.rst.txt0000664000175000017500000000116615051422642027357 0ustar ghudsonghudsonkrb5_init_creds_get_error - Get the last error from KDC from an initial credentials context. ============================================================================================== .. .. c:function:: krb5_error_code krb5_init_creds_get_error(krb5_context context, krb5_init_creds_context ctx, krb5_error ** error) .. :param: **[in]** **context** - Library context **[in]** **ctx** - Initial credentials context **[out]** **error** - Error from KDC, or NULL if none was received .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_expand_hostname.rst.txt0000664000175000017500000000127515051422642026342 0ustar ghudsonghudsonkrb5_expand_hostname - Canonicalize a hostname, possibly using name service. ============================================================================== .. .. c:function:: krb5_error_code krb5_expand_hostname(krb5_context context, const char * host, char ** canonhost_out) .. :param: **[in]** **context** - Library context **[in]** **host** - Input hostname **[out]** **canonhost_out** - Canonicalized hostname .. .. This function canonicalizes orig_hostname, possibly using name service lookups if configuration permits. Use krb5_free_string() to free *canonhost_out* when it is no longer needed. .. .. note:: New in 1.15 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getsendsubkey.rst.txt0000664000175000017500000000134515051422642027717 0ustar ghudsonghudsonkrb5_auth_con_getsendsubkey - Retrieve the send subkey from an auth context as a keyblock. ============================================================================================ .. .. c:function:: krb5_error_code krb5_auth_con_getsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock ** keyblock) .. :param: **[in]** **ctx** - Library context **[in]** **ac** - Authentication context **[out]** **keyblock** - Send subkey .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a keyblock containing the send subkey from *auth_context* . Use krb5_free_keyblock() to free *keyblock* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_responder_otp_get_challenge.rst.txt0000664000175000017500000000156015051422642030706 0ustar ghudsonghudsonkrb5_responder_otp_get_challenge - Decode the KRB5_RESPONDER_QUESTION_OTP to a C struct. ========================================================================================== .. .. c:function:: krb5_error_code krb5_responder_otp_get_challenge(krb5_context ctx, krb5_responder_context rctx, krb5_responder_otp_challenge ** chl) .. :param: **[in]** **ctx** - Library context **[in]** **rctx** - Responder context **[out]** **chl** - Challenge structure .. .. A convenience function which parses the KRB5_RESPONDER_QUESTION_OTP question challenge data, making it available in native C. The main feature of this function is the ability to interact with OTP tokens without parsing the JSON. The returned value must be passed to krb5_responder_otp_challenge_free() to be freed. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_ticket.rst.txt0000664000175000017500000000056315051422642025450 0ustar ghudsonghudsonkrb5_free_ticket - Free a ticket. =================================== .. .. c:function:: void krb5_free_ticket(krb5_context context, krb5_ticket * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Ticket to be freed .. .. This function frees the contents of *val* and the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_tkt_creds_step.rst.txt0000664000175000017500000000276715051422642026211 0ustar ghudsonghudsonkrb5_tkt_creds_step - Get the next KDC request in a TGS exchange. =================================================================== .. .. c:function:: krb5_error_code krb5_tkt_creds_step(krb5_context context, krb5_tkt_creds_context ctx, krb5_data * in, krb5_data * out, krb5_data * realm, unsigned int * flags) .. :param: **[in]** **context** - Library context **[in]** **ctx** - TGS request context **[in]** **in** - KDC response (empty on the first call) **[out]** **out** - Next KDC request **[out]** **realm** - Realm for next KDC request **[out]** **flags** - Output flags .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function constructs the next KDC request for a TGS exchange, allowing the caller to control the transport of KDC requests and replies. On the first call, *in* should be set to an empty buffer; on subsequent calls, it should be set to the KDC's reply to the previous request. If more requests are needed, *flags* will be set to KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in *out* . If no more requests are needed, *flags* will not contain KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and *out* will be empty. If this function returns **KRB5KRB_ERR_RESPONSE_TOO_BIG** , the caller should transmit the next request using TCP rather than UDP. If this function returns any other error, the TGS exchange has failed. .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_default_realm.rst.txt0000664000175000017500000000106615051422642026642 0ustar ghudsonghudsonkrb5_set_default_realm - Override the default realm for the specified context. ================================================================================ .. .. c:function:: krb5_error_code krb5_set_default_realm(krb5_context context, const char * lrealm) .. :param: **[in]** **context** - Library context **[in]** **lrealm** - Realm name for the default realm .. :retval: - 0 Success :return: - Kerberos error codes .. If *lrealm* is NULL, clear the default realm setting. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_keyblock_contents.rst.txt0000664000175000017500000000074015051422642027702 0ustar ghudsonghudsonkrb5_free_keyblock_contents - Free the contents of a krb5_keyblock structure. =============================================================================== .. .. c:function:: void krb5_free_keyblock_contents(krb5_context context, krb5_keyblock * key) .. :param: **[in]** **context** - Library context **[in]** **key** - Keyblock to be freed .. .. This function frees the contents of *key* , but not the structure itself. .. ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootkrb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_change_password_prompt.rst.txtkrb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_change_password_prompt.rst0000664000175000017500000000133115051422642033707 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_change_password_prompt - Set or unset change-password-prompt flag in initial credential options. ============================================================================================================================== .. .. c:function:: void krb5_get_init_creds_opt_set_change_password_prompt(krb5_get_init_creds_opt * opt, int prompt) .. :param: **[in]** **opt** - Options structure **[in]** **prompt** - Whether to prompt to change password .. .. This flag is on by default. It controls whether krb5_get_init_creds_password() will react to an expired-password error by prompting for a new password and attempting to change the old one. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_merge_authdata.rst.txt0000664000175000017500000000173715051422642026142 0ustar ghudsonghudsonkrb5_merge_authdata - Merge two authorization data lists into a new list. =========================================================================== .. .. c:function:: krb5_error_code krb5_merge_authdata(krb5_context context, krb5_authdata *const * inauthdat1, krb5_authdata *const * inauthdat2, krb5_authdata *** outauthdat) .. :param: **[in]** **context** - Library context **[in]** **inauthdat1** - First list of *krb5_authdata* structures **[in]** **inauthdat2** - Second list of *krb5_authdata* structures **[out]** **outauthdat** - Merged list of *krb5_authdata* structures .. :retval: - 0 Success; otherwise - Kerberos error codes .. Merge two authdata arrays, such as the array from a ticket and authenticator. Use krb5_free_authdata() to free *outauthdat* when it is no longer needed. .. .. note:: The last array entry in *inauthdat1* and *inauthdat2* must be a NULL pointer. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_responder_pkinit_set_answer.rst.txt0000664000175000017500000000126215051422642030772 0ustar ghudsonghudsonkrb5_responder_pkinit_set_answer - Answer the KRB5_RESPONDER_QUESTION_PKINIT question for one identity. ========================================================================================================= .. .. c:function:: krb5_error_code krb5_responder_pkinit_set_answer(krb5_context ctx, krb5_responder_context rctx, const char * identity, const char * pin) .. :param: **[in]** **ctx** - Library context **[in]** **rctx** - Responder context **[in]** **identity** - The identity for which a PIN is being supplied **[in]** **pin** - The provided PIN, or NULL for none .. .. .. .. note:: New in 1.12 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_next_cred.rst.txt0000664000175000017500000000152115051422642025577 0ustar ghudsonghudsonkrb5_cc_next_cred - Retrieve the next entry from the credential cache. ======================================================================== .. .. c:function:: krb5_error_code krb5_cc_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor * cursor, krb5_creds * creds) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[in]** **cursor** - Cursor **[out]** **creds** - Next credential cache entry .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function fills in *creds* with the next entry in *cache* and advances *cursor* . Use krb5_free_cred_contents() to free *creds* when it is no longer needed. .. .. seealso:: krb5_cc_start_seq_get(), krb5_end_seq_get() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_process_key.rst.txt0000664000175000017500000000050615051422642025507 0ustar ghudsonghudsonkrb5_process_key ================ .. .. c:function:: krb5_error_code krb5_process_key(krb5_context context, krb5_encrypt_block * eblock, const krb5_keyblock * key) .. :param: **context** **eblock** **key** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_rd_req.rst.txt0000664000175000017500000000560015051422642024435 0ustar ghudsonghudsonkrb5_rd_req - Parse and decrypt a KRB_AP_REQ message. ======================================================= .. .. c:function:: krb5_error_code krb5_rd_req(krb5_context context, krb5_auth_context * auth_context, const krb5_data * inbuf, krb5_const_principal server, krb5_keytab keytab, krb5_flags * ap_req_options, krb5_ticket ** ticket) .. :param: **[in]** **context** - Library context **[inout]** **auth_context** - Pre-existing or newly created auth context **[in]** **inbuf** - AP-REQ message to be parsed **[in]** **server** - Matching principal for server, or NULL to allow any principal in keytab **[in]** **keytab** - Key table, or NULL to use the default **[out]** **ap_req_options** - If non-null, the AP-REQ flags on output **[out]** **ticket** - If non-null, ticket from the AP-REQ message .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function parses, decrypts and verifies a AP-REQ message from *inbuf* and stores the authenticator in *auth_context* . If a keyblock was specified in *auth_context* using krb5_auth_con_setuseruserkey(), that key is used to decrypt the ticket in AP-REQ message and *keytab* is ignored. In this case, *server* should be specified as a complete principal name to allow for proper transited-path checking and replay cache selection. Otherwise, the decryption key is obtained from *keytab* , or from the default keytab if it is NULL. In this case, *server* may be a complete principal name, a matching principal (see krb5_sname_match()), or NULL to match any principal name. The keys tried against the encrypted part of the ticket are determined as follows: - If *server* is a complete principal name, then its entry in *keytab* is tried. - Otherwise, if *keytab* is iterable, then all entries in *keytab* which match *server* are tried. - Otherwise, the server principal in the ticket must match *server* , and its entry in *keytab* is tried. The client specified in the decrypted authenticator must match the client specified in the decrypted ticket. If the *remote_addr* field of *auth_context* is set, the request must come from that address. If a replay cache handle is provided in the *auth_context* , the authenticator and ticket are verified against it. If no conflict is found, the new authenticator is then stored in the replay cache of *auth_context* . Various other checks are performed on the decoded data, including cross-realm policy, clockskew, and ticket validation times. On success the authenticator, subkey, and remote sequence number of the request are stored in *auth_context* . If the AP_OPTS_MUTUAL_REQUIRED bit is set, the local sequence number is XORed with the remote sequence number in the request. Use krb5_free_ticket() to free *ticket* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_verify_init_creds.rst.txt0000664000175000017500000000362415051422642026674 0ustar ghudsonghudsonkrb5_verify_init_creds - Verify initial credentials against a keytab. ======================================================================= .. .. c:function:: krb5_error_code krb5_verify_init_creds(krb5_context context, krb5_creds * creds, krb5_principal server, krb5_keytab keytab, krb5_ccache * ccache, krb5_verify_init_creds_opt * options) .. :param: **[in]** **context** - Library context **[in]** **creds** - Initial credentials to be verified **[in]** **server** - Server principal (or NULL) **[in]** **keytab** - Key table (NULL to use default keytab) **[in]** **ccache** - Credential cache for fetched creds (or NULL) **[in]** **options** - Verification options (NULL for default options) .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function attempts to verify that *creds* were obtained from a KDC with knowledge of a key in *keytab* , or the default keytab if *keytab* is NULL. If *server* is provided, the highest-kvno key entry for that principal name is used to verify the credentials; otherwise, all unique"host"service principals in the keytab are tried. If the specified keytab does not exist, or is empty, or cannot be read, or does not contain an entry for *server* , then credential verification may be skipped unless configuration demands that it succeed. The caller can control this behavior by providing a verification options structure; see krb5_verify_init_creds_opt_init() and krb5_verify_init_creds_opt_set_ap_req_nofail(). If *ccache* is NULL, any additional credentials fetched during the verification process will be destroyed. If *ccache* points to NULL, a memory ccache will be created for the additional credentials and returned in *ccache* . If *ccache* points to a valid credential cache handle, the additional credentials will be stored in that cache. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_data_contents.rst.txt0000664000175000017500000000115415051422642027010 0ustar ghudsonghudsonkrb5_free_data_contents - Free the contents of a krb5_data structure and zero the data field. =============================================================================================== .. .. c:function:: void krb5_free_data_contents(krb5_context context, krb5_data * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Data structure to free contents of .. .. This function frees the contents of *val* , but not the structure itself. It sets the structure's data pointer to null and (beginning in release 1.19) sets its length to zero. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_kdc_recv_hook.rst.txt0000664000175000017500000000143415051422642026635 0ustar ghudsonghudsonkrb5_set_kdc_recv_hook - Set a KDC post-receive hook function. ================================================================ .. .. c:function:: void krb5_set_kdc_recv_hook(krb5_context context, krb5_post_recv_fn recv_hook, void * data) .. :param: **[in]** **context** - The library context. **[in]** **recv_hook** - Hook function (or NULL to disable the hook) **[in]** **data** - Callback data to be passed to *recv_hook* .. .. *recv_hook* will be called after a reply is received from a KDC during a call to a library function such as krb5_get_credentials(). The hook function may inspect or override the reply. This hook will not be executed if the pre-send hook returns a synthetic reply. .. .. note:: New in 1.15 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_data.rst.txt0000664000175000017500000000117515051422642025127 0ustar ghudsonghudsonkrb5_copy_data - Copy a krb5_data object. =========================================== .. .. c:function:: krb5_error_code krb5_copy_data(krb5_context context, const krb5_data * indata, krb5_data ** outdata) .. :param: **[in]** **context** - Library context **[in]** **indata** - Data object to be copied **[out]** **outdata** - Copy of *indata* .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new krb5_data object with the contents of *indata* . Use krb5_free_data() to free *outdata* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_block_size.rst.txt0000664000175000017500000000076015051422642025611 0ustar ghudsonghudsonkrb5_c_block_size - Return cipher block size. =============================================== .. .. c:function:: krb5_error_code krb5_c_block_size(krb5_context context, krb5_enctype enctype, size_t * blocksize) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[out]** **blocksize** - Block size for *enctype* .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_data.rst.txt0000664000175000017500000000061515051422642025074 0ustar ghudsonghudsonkrb5_free_data - Free a krb5_data structure. ============================================== .. .. c:function:: void krb5_free_data(krb5_context context, krb5_data * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Data structure to be freed .. .. This function frees the contents of *val* and the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_enctype_to_name.rst.txt0000664000175000017500000000151115051422642026327 0ustar ghudsonghudsonkrb5_enctype_to_name - Convert an encryption type to a name or alias. ======================================================================= .. .. c:function:: krb5_error_code krb5_enctype_to_name(krb5_enctype enctype, krb5_boolean shortest, char * buffer, size_t buflen) .. :param: **[in]** **enctype** - Encryption type **[in]** **shortest** - Flag **[out]** **buffer** - Buffer to hold encryption type string **[in]** **buflen** - Storage available in *buffer* .. :retval: - 0 Success; otherwise - Kerberos error codes .. If *shortest* is FALSE, this function returns the enctype's canonical name (like"aes128-cts-hmac-sha1-96"). If *shortest* is TRUE, it return the enctype's shortest alias (like"aes128-cts"). .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_encrypt_iov.rst.txt0000664000175000017500000000312715051422642026036 0ustar ghudsonghudsonkrb5_k_encrypt_iov - Encrypt data in place supporting AEAD (operates on opaque key). ====================================================================================== .. .. c:function:: krb5_error_code krb5_k_encrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data * cipher_state, krb5_crypto_iov * data, size_t num_data) .. :param: **[in]** **context** - Library context **[in]** **key** - Encryption key **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[in]** **cipher_state** - Cipher state; specify NULL if not needed **[inout]** **data** - IOV array. Modified in-place. **[in]** **num_data** - Size of *data* .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function encrypts the data block *data* and stores the output in-place. The actual encryption key will be derived from *key* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5_crypto_iov structures before calling into this API. .. .. seealso:: krb5_k_decrypt_iov() .. note:: On return from a krb5_c_encrypt_iov() call, the *data->length* in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_context.rst.txt0000664000175000017500000000116215051422642025667 0ustar ghudsonghudsonkrb5_init_context - Create a krb5 library context. ==================================================== .. .. c:function:: krb5_error_code krb5_init_context(krb5_context * context) .. :param: **[out]** **context** - Library context .. :retval: - 0 Success :return: - Kerberos error codes .. The *context* must be released by calling krb5_free_context() when it is no longer needed. .. .. warning:: Any program or module that needs the Kerberos code to not trust the environment must use krb5_init_secure_context(), or clean out the environment. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_init.rst.txt0000664000175000017500000000244715051422642026335 0ustar ghudsonghudsonkrb5_init_creds_init - Create a context for acquiring initial credentials. ============================================================================ .. .. c:function:: krb5_error_code krb5_init_creds_init(krb5_context context, krb5_principal client, krb5_prompter_fct prompter, void * data, krb5_deltat start_time, krb5_get_init_creds_opt * options, krb5_init_creds_context * ctx) .. :param: **[in]** **context** - Library context **[in]** **client** - Client principal to get initial creds for **[in]** **prompter** - Prompter callback **[in]** **data** - Prompter callback argument **[in]** **start_time** - Time when credentials become valid (0 for now) **[in]** **options** - Options structure (NULL for default) **[out]** **ctx** - New initial credentials context .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new context for acquiring initial credentials. Use krb5_init_creds_free() to free *ctx* when it is no longer needed. Any subsequent calls to krb5_init_creds_step(), krb5_init_creds_get(), or krb5_init_creds_free() for this initial credentials context must use the same *context* argument as the one passed to this function. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kuserok.rst.txt0000664000175000017500000000121415051422642024641 0ustar ghudsonghudsonkrb5_kuserok - Determine if a principal is authorized to log in as a local user. ================================================================================== .. .. c:function:: krb5_boolean krb5_kuserok(krb5_context context, krb5_principal principal, const char * luser) .. :param: **[in]** **context** - Library context **[in]** **principal** - Principal name **[in]** **luser** - Local username .. :retval: - TRUE Principal is authorized to log in as user; FALSE otherwise. .. Determine whether *principal* is authorized to log in as a local user *luser* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_make_checksum_iov.rst.txt0000664000175000017500000000226115051422642027147 0ustar ghudsonghudsonkrb5_k_make_checksum_iov - Fill in a checksum element in IOV array (operates on opaque key) ============================================================================================= .. .. c:function:: krb5_error_code krb5_k_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, krb5_crypto_iov * data, size_t num_data) .. :param: **[in]** **context** - Library context **[in]** **cksumtype** - Checksum type (0 for mandatory type) **[in]** **key** - Encryption key for a keyed checksum **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[inout]** **data** - IOV array **[in]** **num_data** - Size of *data* .. :retval: - 0 Success; otherwise - Kerberos error codes .. Create a checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element over KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in *data* . Only the KRB5_CRYPTO_TYPE_CHECKSUM region is modified. .. .. seealso:: krb5_k_verify_checksum_iov() .. note:: This function is similar to krb5_c_make_checksum_iov(), but operates on opaque *key* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_creds.rst.txt0000664000175000017500000000063215051422642025262 0ustar ghudsonghudsonkrb5_free_creds - Free a krb5_creds structure. ================================================ .. .. c:function:: void krb5_free_creds(krb5_context context, krb5_creds * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Credential structure to be freed. .. .. This function frees the contents of *val* and the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_setsendsubkey_k.rst.txt0000664000175000017500000000120615051422642030241 0ustar ghudsonghudsonkrb5_auth_con_setsendsubkey_k - Set the send subkey in an auth context. ========================================================================= .. .. c:function:: krb5_error_code krb5_auth_con_setsendsubkey_k(krb5_context ctx, krb5_auth_context ac, krb5_key key) .. :param: **[in]** **ctx** - Library context **[in]** **ac** - Authentication context **[out]** **key** - Send subkey .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function sets the send subkey in *ac* to *key* , incrementing its reference count. .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_get_full_name.rst.txt0000664000175000017500000000111215051422642026421 0ustar ghudsonghudsonkrb5_cc_get_full_name - Retrieve the full name of a credential cache. ======================================================================= .. .. c:function:: krb5_error_code krb5_cc_get_full_name(krb5_context context, krb5_ccache cache, char ** fullname_out) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[out]** **fullname_out** - Full name of cache .. .. Use krb5_free_string() to free *fullname_out* when it is no longer needed. .. .. note:: New in 1.10 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_fallback_host_realm.rst.txt0000664000175000017500000000132615051422642027775 0ustar ghudsonghudsonkrb5_get_fallback_host_realm ============================ .. .. c:function:: krb5_error_code krb5_get_fallback_host_realm(krb5_context context, krb5_data * hdata, char *** realmsp) .. :param: **[in]** **context** - Library context **[in]** **hdata** - Host name (or NULL) **[out]** **realmsp** - Null-terminated list of realm names .. .. Fill in *realmsp* with a pointer to a null-terminated list of realm names obtained through heuristics or insecure resolution methods which have lower priority than KDC referrals. If *host* is NULL, the local host's realms are determined. Use krb5_free_host_realm() to release *realmsp* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_in_ccache.rst.txt0000664000175000017500000000173015051422642031654 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_in_ccache - Set an input credential cache in initial credential options. ====================================================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_set_in_ccache(krb5_context context, krb5_get_init_creds_opt * opt, krb5_ccache ccache) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options **[in]** **ccache** - Credential cache handle .. .. If an input credential cache is set, then the krb5_get_init_creds family of APIs will read settings from it. Setting an input ccache is desirable when the application wishes to perform authentication in the same way (using the same preauthentication mechanisms, and making the same non-security- sensitive choices) as the previous authentication attempt, which stored information in the passed-in ccache. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_server_decrypt_ticket_keytab.rst.txt0000664000175000017500000000130315051422642031117 0ustar ghudsonghudsonkrb5_server_decrypt_ticket_keytab - Decrypt a ticket using the specified key table. ===================================================================================== .. .. c:function:: krb5_error_code krb5_server_decrypt_ticket_keytab(krb5_context context, const krb5_keytab kt, krb5_ticket * ticket) .. :param: **[in]** **context** - Library context **[in]** **kt** - Key table **[in]** **ticket** - Ticket to be decrypted .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function takes a *ticket* as input and decrypts it using key data from *kt* . The result is placed into *ticket->enc_part2* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_profile.rst.txt0000664000175000017500000000132215051422642025455 0ustar ghudsonghudsonkrb5_get_profile - Retrieve configuration profile from the context. ===================================================================== .. .. c:function:: krb5_error_code krb5_get_profile(krb5_context context, struct _profile_t ** profile) .. :param: **[in]** **context** - Library context **[out]** **profile** - Pointer to data read from a configuration file .. :retval: - 0 Success :return: - Kerberos error codes .. This function creates a new *profile* object that reflects profile in the supplied *context* . The *profile* object may be freed with profile_release() function. See profile.h and profile API for more details. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_fwd_tgt_creds.rst.txt0000664000175000017500000000265515051422642026006 0ustar ghudsonghudsonkrb5_fwd_tgt_creds - Get a forwarded TGT and format a KRB-CRED message. ========================================================================= .. .. c:function:: krb5_error_code krb5_fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context, const char * rhost, krb5_principal client, krb5_principal server, krb5_ccache cc, int forwardable, krb5_data * outbuf) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **rhost** - Remote host **[in]** **client** - Client principal of TGT **[in]** **server** - Principal of server to receive TGT **[in]** **cc** - Credential cache handle (NULL to use default) **[in]** **forwardable** - Whether TGT should be forwardable **[out]** **outbuf** - KRB-CRED message .. :retval: - 0 Success - ENOMEM Insufficient memory - KRB5_PRINC_NOMATCH Requested principal and ticket do not match - KRB5_NO_TKT_SUPPLIED Request did not supply a ticket - KRB5_CC_BADNAME Credential cache name or principal name malformed :return: - Kerberos error codes .. Get a TGT for use at the remote host *rhost* and format it into a KRB-CRED message. If *rhost* is NULL and *server* is of type KRB5_NT_SRV_HST, the second component of *server* will be used. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_tgt_creds.rst.txt0000664000175000017500000000072515051422642026143 0ustar ghudsonghudsonkrb5_free_tgt_creds - Free an array of credential structures. =============================================================== .. .. c:function:: void krb5_free_tgt_creds(krb5_context context, krb5_creds ** tgts) .. :param: **[in]** **context** - Library context **[in]** **tgts** - Null-terminated array of credentials to free .. .. .. .. note:: The last entry in the array *tgts* must be a NULL pointer. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_decrypt_iov.rst.txt0000664000175000017500000000312715051422642026024 0ustar ghudsonghudsonkrb5_k_decrypt_iov - Decrypt data in place supporting AEAD (operates on opaque key). ====================================================================================== .. .. c:function:: krb5_error_code krb5_k_decrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data * cipher_state, krb5_crypto_iov * data, size_t num_data) .. :param: **[in]** **context** - Library context **[in]** **key** - Encryption key **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[in]** **cipher_state** - Cipher state; specify NULL if not needed **[inout]** **data** - IOV array. Modified in-place. **[in]** **num_data** - Size of *data* .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function decrypts the data block *data* and stores the output in-place. The actual decryption key will be derived from *key* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5_crypto_iov structures before calling into this API. .. .. seealso:: krb5_k_encrypt_iov() .. note:: On return from a krb5_c_decrypt_iov() call, the *data->length* in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_string.rst.txt0000664000175000017500000000057615051422642025477 0ustar ghudsonghudsonkrb5_free_string - Free a string allocated by a krb5 function. ================================================================ .. .. c:function:: void krb5_free_string(krb5_context context, char * val) .. :param: **[in]** **context** - Library context **[in]** **val** - String to be freed .. .. .. .. note:: New in 1.10 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_error_message.rst.txt0000664000175000017500000000162315051422642026656 0ustar ghudsonghudsonkrb5_get_error_message - Get the (possibly extended) error message for a code. ================================================================================ .. .. c:function:: const char * krb5_get_error_message(krb5_context ctx, krb5_error_code code) .. :param: **[in]** **ctx** - Library context **[in]** **code** - Error code .. .. The behavior of krb5_get_error_message() is only defined the first time it is called after a failed call to a krb5 function using the same context, and only when the error code passed in is the same as that returned by the krb5 function. This function never returns NULL, so its result may be used unconditionally as a C string. The string returned by this function must be freed using krb5_free_error_message() .. .. note:: Future versions may return the same string for the second and following calls. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_error_message.rst.txt0000664000175000017500000000072115051422642026670 0ustar ghudsonghudsonkrb5_set_error_message - Set an extended error message for an error code. =========================================================================== .. .. c:function:: void krb5_set_error_message(krb5_context ctx, krb5_error_code code, const char * fmt, ... ) .. :param: **[in]** **ctx** - Library context **[in]** **code** - Error code **[in]** **fmt** - Error string for the error code .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_reference_key.rst.txt0000664000175000017500000000045515051422642026304 0ustar ghudsonghudsonkrb5_k_reference_key - Increment the reference count on a key. ================================================================ .. .. c:function:: void krb5_k_reference_key(krb5_context context, krb5_key key) .. :param: **context** **key** .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_default.rst.txt0000664000175000017500000000132115051422642025246 0ustar ghudsonghudsonkrb5_cc_default - Resolve the default credential cache name. ============================================================== .. .. c:function:: krb5_error_code krb5_cc_default(krb5_context context, krb5_ccache * ccache) .. :param: **[in]** **context** - Library context **[out]** **ccache** - Pointer to credential cache name .. :retval: - 0 Success - KV5M_CONTEXT Bad magic number for _krb5_context structure - KRB5_FCC_INTERNAL The name of the default credential cache cannot be obtained :return: - Kerberos error codes .. Create a handle to the default credential cache as given by krb5_cc_default_name(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_check_clockskew.rst.txt0000664000175000017500000000130415051422642026300 0ustar ghudsonghudsonkrb5_check_clockskew - Check if a timestamp is within the allowed clock skew of the current time. =================================================================================================== .. .. c:function:: krb5_error_code krb5_check_clockskew(krb5_context context, krb5_timestamp date) .. :param: **[in]** **context** - Library context **[in]** **date** - Timestamp to check .. :retval: - 0 Success - KRB5KRB_AP_ERR_SKEW date is not within allowable clock skew .. This function checks if *date* is close enough to the current time according to the configured allowable clock skew. .. .. note:: New in 1.10 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_keyblock.rst.txt0000664000175000017500000000063715051422642025772 0ustar ghudsonghudsonkrb5_free_keyblock - Free a krb5_keyblock structure. ====================================================== .. .. c:function:: void krb5_free_keyblock(krb5_context context, krb5_keyblock * val) .. :param: **[in]** **context** - Library context **[in]** **val** - Keyblock to be freed .. .. This function frees the contents of *val* and the structure itself. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_verify_init_creds_opt_init.rst.txt0000664000175000017500000000062715051422642030601 0ustar ghudsonghudsonkrb5_verify_init_creds_opt_init - Initialize a credential verification options structure. =========================================================================================== .. .. c:function:: void krb5_verify_init_creds_opt_init(krb5_verify_init_creds_opt * k5_vic_options) .. :param: **[in]** **k5_vic_options** - Verification options structure .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_default_config_files.rst.txt0000664000175000017500000000116415051422642030154 0ustar ghudsonghudsonkrb5_get_default_config_files - Return a list of default configuration filenames. =================================================================================== .. .. c:function:: krb5_error_code krb5_get_default_config_files(char *** filenames) .. :param: **[out]** **filenames** - Configuration filename list .. .. Fill in *filenames* with a null-terminated list of configuration files which will be read by krb5_init_context() in the current process environment. Use krb5_free_config_files() to free *filenames* when it is no longer needed. .. .. note:: New in 1.22 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_parse_name.rst.txt0000664000175000017500000000317615051422642025301 0ustar ghudsonghudsonkrb5_parse_name - Convert a string principal name to a krb5_principal structure. ================================================================================== .. .. c:function:: krb5_error_code krb5_parse_name(krb5_context context, const char * name, krb5_principal * principal_out) .. :param: **[in]** **context** - Library context **[in]** **name** - String representation of a principal name **[out]** **principal_out** - New principal .. :retval: - 0 Success :return: - Kerberos error codes .. Convert a string representation of a principal name to a krb5_principal structure. A string representation of a Kerberos name consists of one or more principal name components, separated by slashes, optionally followed by the @ character and a realm name. If the realm name is not specified, the local realm is used. To use the slash and @ symbols as part of a component (quoted) instead of using them as a component separator or as a realm prefix), put a backslash () character in front of the symbol. Similarly, newline, tab, backspace, and NULL characters can be included in a component by using **n** , **t** , **b** or **0** , respectively. Beginning with release 1.20, the name type of the principal will be inferred as **KRB5_NT_SRV_INST** or **KRB5_NT_WELLKNOWN** based on the principal name. The type will be **KRB5_NT_PRINCIPAL** if a type cannot be inferred. Use krb5_free_principal() to free *principal_out* when it is no longer needed. .. .. note:: The realm in a Kerberos *name* cannot contain slash, colon, or NULL characters. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_copy_keyblock.rst.txt0000664000175000017500000000116115051422642026014 0ustar ghudsonghudsonkrb5_copy_keyblock - Copy a keyblock. ======================================= .. .. c:function:: krb5_error_code krb5_copy_keyblock(krb5_context context, const krb5_keyblock * from, krb5_keyblock ** to) .. :param: **[in]** **context** - Library context **[in]** **from** - Keyblock to be copied **[out]** **to** - Copy of keyblock *from* .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function creates a new keyblock with the same contents as *from* . Use krb5_free_keyblock() to free *to* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_responder_pkinit_challenge_free.rst.txt0000664000175000017500000000111315051422642031536 0ustar ghudsonghudsonkrb5_responder_pkinit_challenge_free - Free the value returned by krb5_responder_pkinit_get_challenge(). ========================================================================================================== .. .. c:function:: void krb5_responder_pkinit_challenge_free(krb5_context ctx, krb5_responder_context rctx, krb5_responder_pkinit_challenge * chl) .. :param: **[in]** **ctx** - Library context **[in]** **rctx** - Responder context **[in]** **chl** - The challenge to free .. .. .. .. note:: New in 1.12 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getrecvsubkey_k.rst.txt0000664000175000017500000000133215051422642030233 0ustar ghudsonghudsonkrb5_auth_con_getrecvsubkey_k - Retrieve the receiving subkey from an auth context as a keyblock. =================================================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_getrecvsubkey_k(krb5_context ctx, krb5_auth_context ac, krb5_key * key) .. :param: **[in]** **ctx** - Library context **[in]** **ac** - Authentication context **[out]** **key** - Receiving subkey .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function sets *key* to the receiving subkey from *auth_context* . Use krb5_k_free_key() to release *key* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_mk_ncred.rst.txt0000664000175000017500000000451615051422642024750 0ustar ghudsonghudsonkrb5_mk_ncred - Format a KRB-CRED message for an array of credentials. ======================================================================== .. .. c:function:: krb5_error_code krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds ** creds, krb5_data ** der_out, krb5_replay_data * rdata_out) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **creds** - Null-terminated array of credentials **[out]** **der_out** - Encoded credentials **[out]** **rdata_out** - Replay cache information (NULL if not needed) .. :retval: - 0 Success - ENOMEM Insufficient memory - KRB5_RC_REQUIRED Message replay detection requires rcache parameter :return: - Kerberos error codes .. This function takes an array of credentials *creds* and formats a **KRB-CRED** message *der_out* to pass to krb5_rd_cred(). The local and remote addresses in *auth_context* are optional; if either is specified, they are used to form the sender and receiver addresses in the KRB-CRED message. If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in *auth_context* , an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If KRB5_AUTH_CONTEXT_RET_TIME is set in *auth_context* , the timestamp used for the KRB-CRED message is stored in *rdata_out* . If either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the *auth_context* local sequence number is included in the KRB-CRED message and then incremented. If KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in *rdata_out* . Use krb5_free_data_contents() to free *der_out* when it is no longer needed. The message will be encrypted using the send subkey of *auth_context* if it is present, or the session key otherwise. If neither key is present, the credentials will not be encrypted, and the message should only be sent over a secure channel. No replay cache entry is used in this case. .. .. note:: The *rdata_out* argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in *auth_context* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cccol_cursor_new.rst.txt0000664000175000017500000000135015051422642026510 0ustar ghudsonghudsonkrb5_cccol_cursor_new - Prepare to iterate over the collection of known credential caches. ============================================================================================ .. .. c:function:: krb5_error_code krb5_cccol_cursor_new(krb5_context context, krb5_cccol_cursor * cursor) .. :param: **[in]** **context** - Library context **[out]** **cursor** - Cursor .. :retval: - 0 Success; otherwise - Kerberos error codes .. Get a new cache iteration *cursor* that will iterate over all known credential caches independent of type. Use krb5_cccol_cursor_free() to release *cursor* when it is no longer needed. .. .. seealso:: krb5_cccol_cursor_next() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_principal_compare_flags.rst.txt0000664000175000017500000000167715051422642030036 0ustar ghudsonghudsonkrb5_principal_compare_flags - Compare two principals with additional flags. ============================================================================== .. .. c:function:: krb5_boolean krb5_principal_compare_flags(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2, int flags) .. :param: **[in]** **context** - Library context **[in]** **princ1** - First principal **[in]** **princ2** - Second principal **[in]** **flags** - Flags .. :retval: - TRUE if the principal names are the same; FALSE otherwise .. Valid flags are: - KRB5_PRINCIPAL_COMPARE_IGNORE_REALM - ignore realm component - KRB5_PRINCIPAL_COMPARE_ENTERPRISE - UPNs as real principals - KRB5_PRINCIPAL_COMPARE_CASEFOLD case-insensitive - KRB5_PRINCIPAL_COMPARE_UTF8 - treat principals as UTF-8 .. .. seealso:: krb5_principal_compare() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_mk_rep.rst.txt0000664000175000017500000000171215051422642024436 0ustar ghudsonghudsonkrb5_mk_rep - Format and encrypt a KRB_AP_REP message. ======================================================== .. .. c:function:: krb5_error_code krb5_mk_rep(krb5_context context, krb5_auth_context auth_context, krb5_data * outbuf) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **outbuf** - **AP-REP** message .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function fills in *outbuf* with an AP-REP message using information from *auth_context* . If the flags in *auth_context* indicate that a sequence number should be used (either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE) and the local sequence number in *auth_context* is 0, a new number will be generated with krb5_generate_seq_number(). Use krb5_free_data_contents() to free *outbuf* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_resolve.rst.txt0000664000175000017500000000167315051422642025344 0ustar ghudsonghudsonkrb5_kt_resolve - Get a handle for a key table. ================================================= .. .. c:function:: krb5_error_code krb5_kt_resolve(krb5_context context, const char * name, krb5_keytab * ktid) .. :param: **[in]** **context** - Library context **[in]** **name** - Name of the key table **[out]** **ktid** - Key table handle .. :retval: - 0 Success :return: - Kerberos error codes .. Resolve the key table name *name* and set *ktid* to a handle identifying the key table. Use krb5_kt_close() to free *ktid* when it is no longer needed. *name* must be of the form **type:residual** , where *type* must be a type known to the library and *residual* portion should be specific to the particular keytab type. If no *type* is given, the default is **FILE** . If *name* is of type **FILE** , the keytab file is not opened by this call. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_in_tkt_with_skey.rst.txt0000664000175000017500000000121615051422642027375 0ustar ghudsonghudsonkrb5_get_in_tkt_with_skey ========================= .. .. c:function:: krb5_error_code krb5_get_in_tkt_with_skey(krb5_context context, krb5_flags options, krb5_address *const * addrs, krb5_enctype * ktypes, krb5_preauthtype * pre_auth_types, const krb5_keyblock * key, krb5_ccache ccache, krb5_creds * creds, krb5_kdc_rep ** ret_as_reply) .. :param: **context** **options** **addrs** **ktypes** **pre_auth_types** **key** **ccache** **creds** **ret_as_reply** .. .. DEPRECATED Replaced by krb5_get_init_creds(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_unmarshal_credentials.rst.txt0000664000175000017500000000135215051422642027530 0ustar ghudsonghudsonkrb5_unmarshal_credentials - Deserialize a krb5_creds object. =============================================================== .. .. c:function:: krb5_error_code krb5_unmarshal_credentials(krb5_context context, const krb5_data * data, krb5_creds ** creds_out) .. :param: **[in]** **context** - Library context **[in]** **data** - The serialized credentials **[out]** **creds_out** - The resulting creds object .. :retval: - 0 Success; otherwise - Kerberos error codes .. Deserialize *data* to credentials in the format used by the FILE ccache format (vesion 4) and KCM ccache protocol. Use krb5_free_creds() to free *creds_out* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_responder.rst.txt0000664000175000017500000000122015051422642031753 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_responder - Set the responder function in initial credential options. =================================================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_opt_set_responder(krb5_context context, krb5_get_init_creds_opt * opt, krb5_responder_fn responder, void * data) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options structure **[in]** **responder** - Responder function **[in]** **data** - Responder data argument .. .. .. .. note:: New in 1.11 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_decrypt.rst.txt0000664000175000017500000000271515051422642025141 0ustar ghudsonghudsonkrb5_c_decrypt - Decrypt data using a key (operates on keyblock). =================================================================== .. .. c:function:: krb5_error_code krb5_c_decrypt(krb5_context context, const krb5_keyblock * key, krb5_keyusage usage, const krb5_data * cipher_state, const krb5_enc_data * input, krb5_data * output) .. :param: **[in]** **context** - Library context **[in]** **key** - Encryption key **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[inout]** **cipher_state** - Cipher state; specify NULL if not needed **[in]** **input** - Encrypted data **[out]** **output** - Decrypted data .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function decrypts the data block *input* and stores the output into *output* . The actual decryption key will be derived from *key* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. .. .. note:: The caller must initialize *output* and allocate at least enough space for the result. The usual practice is to allocate an output buffer as long as the ciphertext, and let krb5_c_decrypt() trim *output->length* . For some enctypes, the resulting *output->length* may include padding bytes. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_string_to_enctype.rst.txt0000664000175000017500000000071715051422642026724 0ustar ghudsonghudsonkrb5_string_to_enctype - Convert a string to an encryption type. ================================================================== .. .. c:function:: krb5_error_code krb5_string_to_enctype(char * string, krb5_enctype * enctypep) .. :param: **[in]** **string** - String to convert to an encryption type **[out]** **enctypep** - Encryption type .. :retval: - 0 Success; otherwise - EINVAL .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_rd_error.rst.txt0000664000175000017500000000131515051422642024776 0ustar ghudsonghudsonkrb5_rd_error - Decode a KRB-ERROR message. ============================================= .. .. c:function:: krb5_error_code krb5_rd_error(krb5_context context, const krb5_data * enc_errbuf, krb5_error ** dec_error) .. :param: **[in]** **context** - Library context **[in]** **enc_errbuf** - Encoded error message **[out]** **dec_error** - Decoded error message .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function processes **KRB-ERROR** message *enc_errbuf* and returns an allocated structure *dec_error* containing the error message. Use krb5_free_error() to free *dec_error* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_build_principal.rst.txt0000664000175000017500000000220315051422642026315 0ustar ghudsonghudsonkrb5_build_principal - Build a principal name using null-terminated strings. ============================================================================== .. .. c:function:: krb5_error_code krb5_build_principal(krb5_context context, krb5_principal * princ, unsigned int rlen, const char * realm, ... ) .. :param: **[in]** **context** - Library context **[out]** **princ** - Principal name **[in]** **rlen** - Realm name length **[in]** **realm** - Realm name .. :retval: - 0 Success :return: - Kerberos error codes .. Call krb5_free_principal() to free *princ* when it is no longer needed. Beginning with release 1.20, the name type of the principal will be inferred as **KRB5_NT_SRV_INST** or **KRB5_NT_WELLKNOWN** based on the principal name. The type will be **KRB5_NT_PRINCIPAL** if a type cannot be inferred. .. .. note:: krb5_build_principal() and krb5_build_principal_alloc_va() perform the same task. krb5_build_principal() takes variadic arguments. krb5_build_principal_alloc_va() takes a pre-computed *varargs* pointer. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_decrypt_iov.rst.txt0000664000175000017500000000315715051422642026017 0ustar ghudsonghudsonkrb5_c_decrypt_iov - Decrypt data in place supporting AEAD (operates on keyblock). ==================================================================================== .. .. c:function:: krb5_error_code krb5_c_decrypt_iov(krb5_context context, const krb5_keyblock * keyblock, krb5_keyusage usage, const krb5_data * cipher_state, krb5_crypto_iov * data, size_t num_data) .. :param: **[in]** **context** - Library context **[in]** **keyblock** - Encryption key **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[in]** **cipher_state** - Cipher state; specify NULL if not needed **[inout]** **data** - IOV array. Modified in-place. **[in]** **num_data** - Size of *data* .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function decrypts the data block *data* and stores the output in-place. The actual decryption key will be derived from *keyblock* and *usage* if key derivation is specified for the encryption type. If non-null, *cipher_state* specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5_crypto_iov structures before calling into this API. .. .. seealso:: krb5_c_decrypt_iov() .. note:: On return from a krb5_c_decrypt_iov() call, the *data->length* in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_sname_to_principal.rst.txt0000664000175000017500000000250415051422642027027 0ustar ghudsonghudsonkrb5_sname_to_principal - Generate a full principal name from a service name. =============================================================================== .. .. c:function:: krb5_error_code krb5_sname_to_principal(krb5_context context, const char * hostname, const char * sname, krb5_int32 type, krb5_principal * ret_princ) .. :param: **[in]** **context** - Library context **[in]** **hostname** - Host name, or NULL to use local host **[in]** **sname** - Service name, or NULL to use **"host"** **[in]** **type** - Principal type **[out]** **ret_princ** - Generated principal .. :retval: - 0 Success :return: - Kerberos error codes .. This function converts a *hostname* and *sname* into *krb5_principal* structure *ret_princ* . The returned principal will be of the form *sname\/hostname@REALM* where REALM is determined by krb5_get_host_realm(). In some cases this may be the referral (empty) realm. The *type* can be one of the following: - KRB5_NT_SRV_HST canonicalizes the host name before looking up the realm and generating the principal. - KRB5_NT_UNKNOWN accepts the hostname as given, and does not canonicalize it. Use krb5_free_principal to free *ret_princ* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_is_referral_realm.rst.txt0000664000175000017500000000057015051422642026637 0ustar ghudsonghudsonkrb5_is_referral_realm - Check for a match with KRB5_REFERRAL_REALM. ====================================================================== .. .. c:function:: krb5_boolean krb5_is_referral_realm(const krb5_data * r) .. :param: **[in]** **r** - Realm to check .. :return: - TRUE if r is zero-length, FALSE otherwise .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_verify_ext.rst.txt0000664000175000017500000000224515051422642026172 0ustar ghudsonghudsonkrb5_pac_verify_ext - Verify a PAC, possibly from a specified realm. ====================================================================== .. .. c:function:: krb5_error_code krb5_pac_verify_ext(krb5_context context, const krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock * server, const krb5_keyblock * privsvr, krb5_boolean with_realm) .. :param: **[in]** **context** - Library context **[in]** **pac** - PAC handle **[in]** **authtime** - Expected timestamp **[in]** **principal** - Expected principal name (or NULL) **[in]** **server** - Key to validate server checksum (or NULL) **[in]** **privsvr** - Key to validate KDC checksum (or NULL) **[in]** **with_realm** - If true, expect the realm of *principal* .. .. This function is similar to krb5_pac_verify(), but adds a parameter *with_realm* . If *with_realm* is true, the PAC_CLIENT_INFO field is expected to include the realm of *principal* as well as the name. This flag is necessary to verify PACs in cross-realm S4U2Self referral TGTs. .. .. note:: New in 1.17 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_authdata.rst.txt0000664000175000017500000000106115051422642025752 0ustar ghudsonghudsonkrb5_free_authdata - Free the storage assigned to array of authentication data. ================================================================================= .. .. c:function:: void krb5_free_authdata(krb5_context context, krb5_authdata ** val) .. :param: **[in]** **context** - Library context **[in]** **val** - Array of authentication data to be freed .. .. This function frees the contents of *val* and the array itself. .. .. note:: The last entry in the array must be a NULL pointer. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_setsendsubkey.rst.txt0000664000175000017500000000120315051422642027724 0ustar ghudsonghudsonkrb5_auth_con_setsendsubkey - Set the send subkey in an auth context with a keyblock. ======================================================================================= .. .. c:function:: krb5_error_code krb5_auth_con_setsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock * keyblock) .. :param: **[in]** **ctx** - Library context **[in]** **ac** - Authentication context **[in]** **keyblock** - Send subkey .. :retval: - 0 Success. Otherwise - Kerberos error codes .. This function sets the send subkey in *ac* to a copy of *keyblock* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_dup.rst.txt0000664000175000017500000000101315051422642024410 0ustar ghudsonghudsonkrb5_cc_dup - Duplicate ccache handle. ======================================== .. .. c:function:: krb5_error_code krb5_cc_dup(krb5_context context, krb5_ccache in, krb5_ccache * out) .. :param: **[in]** **context** - Library context **[in]** **in** - Credential cache handle to be duplicated **[out]** **out** - Credential cache handle .. .. Create a new handle referring to the same cache as *in* . The new handle and *in* can be closed independently. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_initivector.rst.txt0000664000175000017500000000113215051422642027374 0ustar ghudsonghudsonkrb5_auth_con_initivector - Cause an auth context to use cipher state. ======================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context .. :retval: - 0 Success; otherwise - Kerberos error codes .. Prepare *auth_context* to use cipher state when krb5_mk_priv() or krb5_rd_priv() encrypt or decrypt data. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_aname_to_localname.rst.txt0000664000175000017500000000174015051422642026760 0ustar ghudsonghudsonkrb5_aname_to_localname - Convert a principal name to a local name. ===================================================================== .. .. c:function:: krb5_error_code krb5_aname_to_localname(krb5_context context, krb5_const_principal aname, int lnsize_in, char * lname) .. :param: **[in]** **context** - Library context **[in]** **aname** - Principal name **[in]** **lnsize_in** - Space available in *lname* **[out]** **lname** - Local name buffer to be filled in .. :retval: - 0 Success - System errors :return: - Kerberos error codes .. If *aname* does not correspond to any local account, KRB5_LNAME_NOTRANS is returned. If *lnsize_in* is too small for the local name, KRB5_CONFIG_NOTENUFSPACE is returned. Local names, rather than principal names, can be used by programs that translate to an environment-specific name (for example, a user account name). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_mk_1cred.rst.txt0000664000175000017500000000172415051422642024651 0ustar ghudsonghudsonkrb5_mk_1cred - Format a KRB-CRED message for a single set of credentials. ============================================================================ .. .. c:function:: krb5_error_code krb5_mk_1cred(krb5_context context, krb5_auth_context auth_context, krb5_creds * creds, krb5_data ** der_out, krb5_replay_data * rdata_out) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[in]** **creds** - Pointer to credentials **[out]** **der_out** - Encoded credentials **[out]** **rdata_out** - Replay cache data (NULL if not needed) .. :retval: - 0 Success - ENOMEM Insufficient memory - KRB5_RC_REQUIRED Message replay detection requires rcache parameter :return: - Kerberos error codes .. This is a convenience function that calls krb5_mk_ncred() with a single set of credentials. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_keyed_checksum_types.rst.txt0000664000175000017500000000144415051422642027674 0ustar ghudsonghudsonkrb5_c_keyed_checksum_types - Return a list of keyed checksum types usable with an encryption type. ===================================================================================================== .. .. c:function:: krb5_error_code krb5_c_keyed_checksum_types(krb5_context context, krb5_enctype enctype, unsigned int * count, krb5_cksumtype ** cksumtypes) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[out]** **count** - Count of allowable checksum types **[out]** **cksumtypes** - Array of allowable checksum types .. :retval: - 0 Success; otherwise - Kerberos error codes .. Use krb5_free_cksumtypes() to free *cksumtypes* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_password.rst.txt0000664000175000017500000000401215051422642030061 0ustar ghudsonghudsonkrb5_get_init_creds_password - Get initial credentials using a password. ========================================================================== .. .. c:function:: krb5_error_code krb5_get_init_creds_password(krb5_context context, krb5_creds * creds, krb5_principal client, const char * password, krb5_prompter_fct prompter, void * data, krb5_deltat start_time, const char * in_tkt_service, krb5_get_init_creds_opt * k5_gic_options) .. :param: **[in]** **context** - Library context **[out]** **creds** - New credentials **[in]** **client** - Client principal **[in]** **password** - Password (or NULL) **[in]** **prompter** - Prompter function **[in]** **data** - Prompter callback data **[in]** **start_time** - Time when ticket becomes valid (0 for now) **[in]** **in_tkt_service** - Service name of initial credentials (or NULL) **[in]** **k5_gic_options** - Initial credential options .. :retval: - 0 Success - EINVAL Invalid argument - KRB5_KDC_UNREACH Cannot contact any KDC for requested realm - KRB5_PREAUTH_FAILED Generic Pre-athentication failure - KRB5_LIBOS_PWDINTR Password read interrupted - KRB5_REALM_CANT_RESOLVE Cannot resolve network address for KDC in requested realm - KRB5KDC_ERR_KEY_EXP Password has expired - KRB5_LIBOS_BADPWDMATCH Password mismatch - KRB5_CHPW_PWDNULL New password cannot be zero length - KRB5_CHPW_FAIL Password change failed :return: - Kerberos error codes .. This function requests KDC for an initial credentials for *client* using *password* . If *password* is NULL, a password will be prompted for using *prompter* if necessary. If *in_tkt_service* is specified, it is parsed as a principal name (with the realm ignored) and used as the service principal for the request; otherwise the ticket-granting service is used. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_prf.rst.txt0000664000175000017500000000157615051422642024272 0ustar ghudsonghudsonkrb5_k_prf - Generate enctype-specific pseudo-random bytes (operates on opaque key). ====================================================================================== .. .. c:function:: krb5_error_code krb5_k_prf(krb5_context context, krb5_key key, krb5_data * input, krb5_data * output) .. :param: **[in]** **context** - Library context **[in]** **key** - Key **[in]** **input** - Input data **[out]** **output** - Output data .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function selects a pseudo-random function based on *key* and computes its value over *input* , placing the result into *output* . The caller must preinitialize *output* and allocate space for the result. .. .. note:: This function is similar to krb5_c_prf(), but operates on opaque *key* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_verify_checksum.rst.txt0000664000175000017500000000251015051422642026656 0ustar ghudsonghudsonkrb5_k_verify_checksum - Verify a checksum (operates on opaque key). ====================================================================== .. .. c:function:: krb5_error_code krb5_k_verify_checksum(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data * data, const krb5_checksum * cksum, krb5_boolean * valid) .. :param: **[in]** **context** - Library context **[in]** **key** - Encryption key for a keyed checksum **[in]** **usage** - *key* usage **[in]** **data** - Data to be used to compute a new checksum using *key* to compare *cksum* against **[in]** **cksum** - Checksum to be verified **[out]** **valid** - Non-zero for success, zero for failure .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function verifies that *cksum* is a valid checksum for *data* . If the checksum type of *cksum* is a keyed checksum, *key* is used to verify the checksum. If the checksum type in *cksum* is 0 and *key* is not NULL, the mandatory checksum type for *key* will be used. The actual checksum key will be derived from *key* and *usage* if key derivation is specified for the checksum type. .. .. note:: This function is similar to krb5_c_verify_checksum(), but operates on opaque *key* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_salttype_to_string.rst.txt0000664000175000017500000000104015051422642027110 0ustar ghudsonghudsonkrb5_salttype_to_string - Convert a salt type to a string. ============================================================ .. .. c:function:: krb5_error_code krb5_salttype_to_string(krb5_int32 salttype, char * buffer, size_t buflen) .. :param: **[in]** **salttype** - Salttype to convert **[out]** **buffer** - Buffer to receive the converted string **[in]** **buflen** - Storage available in *buffer* .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_k_verify_checksum_iov.rst.txt0000664000175000017500000000240515051422642027536 0ustar ghudsonghudsonkrb5_k_verify_checksum_iov - Validate a checksum element in IOV array (operates on opaque key). ================================================================================================= .. .. c:function:: krb5_error_code krb5_k_verify_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov * data, size_t num_data, krb5_boolean * valid) .. :param: **[in]** **context** - Library context **[in]** **cksumtype** - Checksum type (0 for mandatory type) **[in]** **key** - Encryption key for a keyed checksum **[in]** **usage** - Key usage (see KRB5_KEYUSAGE macros) **[in]** **data** - IOV array **[in]** **num_data** - Size of *data* **[out]** **valid** - Non-zero for success, zero for failure .. :retval: - 0 Success; otherwise - Kerberos error codes .. Confirm that the checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element is a valid checksum of the KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY regions in the iov. .. .. seealso:: krb5_k_make_checksum_iov() .. note:: This function is similar to krb5_c_verify_checksum_iov(), but operates on opaque *key* . krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_string_to_key_with_params.rst.txt0000664000175000017500000000211015051422642030732 0ustar ghudsonghudsonkrb5_c_string_to_key_with_params - Convert a string (such as a password) to a key with additional parameters. =============================================================================================================== .. .. c:function:: krb5_error_code krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype, const krb5_data * string, const krb5_data * salt, const krb5_data * params, krb5_keyblock * key) .. :param: **[in]** **context** - Library context **[in]** **enctype** - Encryption type **[in]** **string** - String to be converted **[in]** **salt** - Salt value **[in]** **params** - Parameters **[out]** **key** - Generated key .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function is similar to krb5_c_string_to_key(), but also takes parameters which may affect the algorithm in an enctype-dependent way. The newly created *key* must be released by calling krb5_free_keyblock_contents() when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_use_enctype.rst.txt0000664000175000017500000000050515051422642025503 0ustar ghudsonghudsonkrb5_use_enctype ================ .. .. c:function:: krb5_error_code krb5_use_enctype(krb5_context context, krb5_encrypt_block * eblock, krb5_enctype enctype) .. :param: **context** **eblock** **enctype** .. .. DEPRECATED Replaced by krb5_c_* API family. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_free.rst.txt0000664000175000017500000000070315051422642030025 0ustar ghudsonghudsonkrb5_get_init_creds_opt_free - Free initial credential options. ================================================================= .. .. c:function:: void krb5_get_init_creds_opt_free(krb5_context context, krb5_get_init_creds_opt * opt) .. :param: **[in]** **context** - Library context **[in]** **opt** - Options structure to free .. .. .. .. seealso:: krb5_get_init_creds_opt_alloc() krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_addresses.rst.txt0000664000175000017500000000101315051422642026131 0ustar ghudsonghudsonkrb5_free_addresses - Free the data stored in array of addresses. =================================================================== .. .. c:function:: void krb5_free_addresses(krb5_context context, krb5_address ** val) .. :param: **[in]** **context** - Library context **[in]** **val** - Array of addresses to be freed .. .. This function frees the contents of *val* and the array itself. .. .. note:: The last entry in the array must be a NULL pointer. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_set_flags.rst.txt0000664000175000017500000000106215051422642025573 0ustar ghudsonghudsonkrb5_cc_set_flags - Set options flags on a credential cache. ============================================================== .. .. c:function:: krb5_error_code krb5_cc_set_flags(krb5_context context, krb5_ccache cache, krb5_flags flags) .. :param: **[in]** **context** - Library context **[in]** **cache** - Credential cache handle **[in]** **flags** - Flag bit mask .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function resets *cache* flags to *flags* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_enctype_to_string.rst.txt0000664000175000017500000000104615051422642026720 0ustar ghudsonghudsonkrb5_enctype_to_string - Convert an encryption type to a string. ================================================================== .. .. c:function:: krb5_error_code krb5_enctype_to_string(krb5_enctype enctype, char * buffer, size_t buflen) .. :param: **[in]** **enctype** - Encryption type **[out]** **buffer** - Buffer to hold encryption type string **[in]** **buflen** - Storage available in *buffer* .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_os_localaddr.rst.txt0000664000175000017500000000105615051422642025610 0ustar ghudsonghudsonkrb5_os_localaddr - Return all interface addresses for this host. =================================================================== .. .. c:function:: krb5_error_code krb5_os_localaddr(krb5_context context, krb5_address *** addr) .. :param: **[in]** **context** - Library context **[out]** **addr** - Array of krb5_address pointers, ending with NULL .. :retval: - 0 Success; otherwise - Kerberos error codes .. Use krb5_free_addresses() to free *addr* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_realm_compare.rst.txt0000664000175000017500000000102515051422642025764 0ustar ghudsonghudsonkrb5_realm_compare - Compare the realms of two principals. ============================================================ .. .. c:function:: krb5_boolean krb5_realm_compare(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2) .. :param: **[in]** **context** - Library context **[in]** **princ1** - First principal **[in]** **princ2** - Second principal .. :retval: - TRUE if the realm names are the same; FALSE otherwise .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_get_init_creds_opt_set_proxiable.rst.txt0000664000175000017500000000075515051422642031753 0ustar ghudsonghudsonkrb5_get_init_creds_opt_set_proxiable - Set or unset the proxiable flag in initial credential options. ======================================================================================================== .. .. c:function:: void krb5_get_init_creds_opt_set_proxiable(krb5_get_init_creds_opt * opt, int proxiable) .. :param: **[in]** **opt** - Options structure **[in]** **proxiable** - Whether credentials should be proxiable .. .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getremoteseqnumber.rst.txt0000664000175000017500000000146415051422642030762 0ustar ghudsonghudsonkrb5_auth_con_getremoteseqnumber - Retrieve the remote sequence number from an auth context. ============================================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 * seqnumber) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **seqnumber** - Remote sequence number .. :retval: - 0 Success; otherwise - Kerberos error codes .. Retrieve the remote sequence number from *auth_context* and return it in *seqnumber* . The KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in *auth_context* for this function to be useful. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_get_creds.rst.txt0000664000175000017500000000152315051422642027323 0ustar ghudsonghudsonkrb5_init_creds_get_creds - Retrieve acquired credentials from an initial credentials context. ================================================================================================ .. .. c:function:: krb5_error_code krb5_init_creds_get_creds(krb5_context context, krb5_init_creds_context ctx, krb5_creds * creds) .. :param: **[in]** **context** - Library context **[in]** **ctx** - Initial credentials context **[out]** **creds** - Acquired credentials .. :retval: - 0 Success; otherwise - Kerberos error codes .. This function copies the acquired initial credentials from *ctx* into *creds* , after the successful completion of krb5_init_creds_get() or krb5_init_creds_step(). Use krb5_free_cred_contents() to free *creds* when it is no longer needed. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_config_files.rst.txt0000664000175000017500000000056715051422642026620 0ustar ghudsonghudsonkrb5_free_config_files - Free a list allocated by krb5_get_default_config_files() =================================================================================== .. .. c:function:: void krb5_free_config_files(char ** filenames) .. :param: **[in]** **filenames** - Configuration filename list .. .. .. .. note:: New in 1.22 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_free.rst.txt0000664000175000017500000000077715051422642025774 0ustar ghudsonghudsonkrb5_auth_con_free - Free a krb5_auth_context structure. ========================================================== .. .. c:function:: krb5_error_code krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context to be freed .. :retval: - 0 (always) .. This function frees an auth context allocated by krb5_auth_con_init(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_cc_move.rst.txt0000664000175000017500000000130215051422642024567 0ustar ghudsonghudsonkrb5_cc_move - Move a credential cache. ========================================= .. .. c:function:: krb5_error_code krb5_cc_move(krb5_context context, krb5_ccache src, krb5_ccache dst) .. :param: **[in]** **context** - Library context **[in]** **src** - The credential cache to move the content from **[in]** **dst** - The credential cache to move the content to .. :retval: - 0 Success; src is closed. :return: - Kerberos error codes; src is still allocated. .. This function reinitializes *dst* and populates it with the credentials and default principal of *src* ; then, if successful, destroys *src* . .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_init_creds_get_times.rst.txt0000664000175000017500000000136215051422642027345 0ustar ghudsonghudsonkrb5_init_creds_get_times - Retrieve ticket times from an initial credentials context. ======================================================================================== .. .. c:function:: krb5_error_code krb5_init_creds_get_times(krb5_context context, krb5_init_creds_context ctx, krb5_ticket_times * times) .. :param: **[in]** **context** - Library context **[in]** **ctx** - Initial credentials context **[out]** **times** - Ticket times for acquired credentials .. :retval: - 0 Success; otherwise - Kerberos error codes .. The initial credentials context must have completed obtaining credentials via either krb5_init_creds_get() or krb5_init_creds_step(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_auth_con_getaddrs.rst.txt0000664000175000017500000000127115051422642026636 0ustar ghudsonghudsonkrb5_auth_con_getaddrs - Retrieve address fields from an auth context. ======================================================================== .. .. c:function:: krb5_error_code krb5_auth_con_getaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address ** local_addr, krb5_address ** remote_addr) .. :param: **[in]** **context** - Library context **[in]** **auth_context** - Authentication context **[out]** **local_addr** - Local address (NULL if not needed) **[out]** **remote_addr** - Remote address (NULL if not needed) .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_pac_get_types.rst.txt0000664000175000017500000000112415051422642026004 0ustar ghudsonghudsonkrb5_pac_get_types - Return an array of buffer types in a PAC handle. ======================================================================= .. .. c:function:: krb5_error_code krb5_pac_get_types(krb5_context context, krb5_pac pac, size_t * len, krb5_ui_4 ** types) .. :param: **[in]** **context** - Library context **[in]** **pac** - PAC handle **[out]** **len** - Number of entries in *types* **[out]** **types** - Array of buffer types .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_kt_end_seq_get.rst.txt0000664000175000017500000000111015051422642026124 0ustar ghudsonghudsonkrb5_kt_end_seq_get - Release a keytab cursor. ================================================ .. .. c:function:: krb5_error_code krb5_kt_end_seq_get(krb5_context context, krb5_keytab keytab, krb5_kt_cursor * cursor) .. :param: **[in]** **context** - Library context **[in]** **keytab** - Key table handle **[out]** **cursor** - Cursor .. :retval: - 0 Success :return: - Kerberos error codes .. This function should be called to release the cursor created by krb5_kt_start_seq_get(). .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_set_trace_filename.rst.txt0000664000175000017500000000134115051422642026770 0ustar ghudsonghudsonkrb5_set_trace_filename - Specify a file name for directing trace events. =========================================================================== .. .. c:function:: krb5_error_code krb5_set_trace_filename(krb5_context context, const char * filename) .. :param: **[in]** **context** - Library context **[in]** **filename** - File name .. :retval: - KRB5_TRACE_NOSUPP Tracing is not supported in the library. .. Open *filename* for appending (creating it, if necessary) and set up a callback to write trace events to it. .. .. note:: This function overrides the information passed through the *KRB5_TRACE* environment variable. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_tkt_creds_get_times.rst.txt0000664000175000017500000000134415051422642027204 0ustar ghudsonghudsonkrb5_tkt_creds_get_times - Retrieve ticket times from a TGS request context. ============================================================================== .. .. c:function:: krb5_error_code krb5_tkt_creds_get_times(krb5_context context, krb5_tkt_creds_context ctx, krb5_ticket_times * times) .. :param: **[in]** **context** - Library context **[in]** **ctx** - TGS request context **[out]** **times** - Ticket times for acquired credentials .. :retval: - 0 Success; otherwise - Kerberos error codes .. The TGS request context must have completed obtaining credentials via either krb5_tkt_creds_get() or krb5_tkt_creds_step(). .. .. note:: New in 1.9 krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_free_host_realm.rst.txt0000664000175000017500000000077415051422642026326 0ustar ghudsonghudsonkrb5_free_host_realm - Free the memory allocated by krb5_get_host_realm(). ============================================================================ .. .. c:function:: krb5_error_code krb5_free_host_realm(krb5_context context, char *const * realmlist) .. :param: **[in]** **context** - Library context **[in]** **realmlist** - List of realm names to be released .. :retval: - 0 Success :return: - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_decode_ticket.rst.txt0000664000175000017500000000067415051422642025755 0ustar ghudsonghudsonkrb5_decode_ticket - Decode an ASN.1-formatted ticket. ======================================================== .. .. c:function:: krb5_error_code krb5_decode_ticket(const krb5_data * code, krb5_ticket ** rep) .. :param: **[in]** **code** - ASN.1-formatted ticket **[out]** **rep** - Decoded ticket information .. :retval: - 0 Success; otherwise - Kerberos error codes .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/api/krb5_c_valid_enctype.rst.txt0000664000175000017500000000066315051422642026315 0ustar ghudsonghudsonkrb5_c_valid_enctype - Verify that a specified encryption type is a valid Kerberos encryption type. ===================================================================================================== .. .. c:function:: krb5_boolean krb5_c_valid_enctype(krb5_enctype ktype) .. :param: **[in]** **ktype** - Encryption type .. :return: - TRUE if ktype is valid, FALSE if not .. .. krb5-1.22.1/doc/html/_sources/appdev/refs/macros/0000775000175000017500000000000015051422712021376 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_PROXY.rst.txt0000664000175000017500000000035115051422642025073 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-PROXY-data: KDC_OPT_PROXY ============= .. .. data:: KDC_OPT_PROXY .. ==================== ====================== ``KDC_OPT_PROXY`` ``0x08000000`` ==================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_SALT.rst.txt0000664000175000017500000000051615051422642027264 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-SALT-data: KRB5_GET_INIT_CREDS_OPT_SALT ============================ .. .. data:: KRB5_GET_INIT_CREDS_OPT_SALT .. =================================== ====================== ``KRB5_GET_INIT_CREDS_OPT_SALT`` ``0x0080`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_INIT_CONTEXT_KDC.rst.txt0000664000175000017500000000047615051422642026172 0ustar ghudsonghudson.. highlight:: c .. _KRB5-INIT-CONTEXT-KDC-data: KRB5_INIT_CONTEXT_KDC ===================== .. .. data:: KRB5_INIT_CONTEXT_KDC .. Use KDC configuration if available. ============================ ====================== ``KRB5_INIT_CONTEXT_KDC`` ``0x2`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_UNIXSOCK.rst.txt0000664000175000017500000000041415051422642025506 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-UNIXSOCK-data: ADDRTYPE_UNIXSOCK ================= .. .. data:: ADDRTYPE_UNIXSOCK .. ======================== ====================== ``ADDRTYPE_UNIXSOCK`` ``(0x8000 | 0x0001)`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KPASSWD_MALFORMED.rst.txt0000664000175000017500000000046215051422642026237 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KPASSWD-MALFORMED-data: KRB5_KPASSWD_MALFORMED ====================== .. .. data:: KRB5_KPASSWD_MALFORMED .. Malformed request. ============================= ====================== ``KRB5_KPASSWD_MALFORMED`` ``1`` ============================= ====================== ././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootkrb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY.rst.txtkrb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TR0000664000175000017500000000112115051422642031256 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-PKINIT-FLAGS-TOKEN-USER-PIN-FINAL-TRY-data: KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY ==================================================== .. .. data:: KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY .. This flag indicates that supplying an incorrect PIN will cause the token to lock itself. =========================================================== ====================== ``KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY`` ``(1 << 1)`` =========================================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_PRINCIPAL.rst.txt0000664000175000017500000000046415051422642025461 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-PRINCIPAL-data: KRB5_NT_PRINCIPAL ================= .. .. data:: KRB5_NT_PRINCIPAL .. Just the name of the principal as in DCE, or for users. ======================== ====================== ``KRB5_NT_PRINCIPAL`` ``1`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_SHORT.rst.txt0000664000175000017500000000056015051422642027231 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-UNPARSE-SHORT-data: KRB5_PRINCIPAL_UNPARSE_SHORT ============================ .. .. data:: KRB5_PRINCIPAL_UNPARSE_SHORT .. Omit realm if it is the local realm. =================================== ====================== ``KRB5_PRINCIPAL_UNPARSE_SHORT`` ``0x1`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_FORWARDABLE.rst.txt0000664000175000017500000000057715051422642030260 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-FORWARDABLE-data: KRB5_GET_INIT_CREDS_OPT_FORWARDABLE =================================== .. .. data:: KRB5_GET_INIT_CREDS_OPT_FORWARDABLE .. ========================================== ====================== ``KRB5_GET_INIT_CREDS_OPT_FORWARDABLE`` ``0x0004`` ========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_RENEW.rst.txt0000664000175000017500000000035115051422642025032 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-RENEW-data: KDC_OPT_RENEW ============= .. .. data:: KDC_OPT_RENEW .. ==================== ====================== ``KDC_OPT_RENEW`` ``0x00000002`` ==================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_SRV_HST.rst.txt0000664000175000017500000000044515051422642025327 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-SRV-HST-data: KRB5_NT_SRV_HST =============== .. .. data:: KRB5_NT_SRV_HST .. Service with host name as instance (telnet, rcommands) ====================== ====================== ``KRB5_NT_SRV_HST`` ``3`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_FORWARDABLE.rst.txt0000664000175000017500000000042315051422642025711 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-FORWARDABLE-data: TKT_FLG_FORWARDABLE =================== .. .. data:: TKT_FLG_FORWARDABLE .. ========================== ====================== ``TKT_FLG_FORWARDABLE`` ``0x40000000`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ONE_LAST_REQ.rst.txt0000664000175000017500000000043315051422642026224 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ONE-LAST-REQ-data: KRB5_LRQ_ONE_LAST_REQ ===================== .. .. data:: KRB5_LRQ_ONE_LAST_REQ .. ============================ ====================== ``KRB5_LRQ_ONE_LAST_REQ`` ``(-5)`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_MATCH_TIMES_EXACT.rst.txt0000664000175000017500000000054515051422642026646 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-MATCH-TIMES-EXACT-data: KRB5_TC_MATCH_TIMES_EXACT ========================= .. .. data:: KRB5_TC_MATCH_TIMES_EXACT .. All the time fields must match exactly. ================================ ====================== ``KRB5_TC_MATCH_TIMES_EXACT`` ``0x00000008`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_SEQUENCE.rst.txt0000664000175000017500000000060015051422642027346 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-DO-SEQUENCE-data: KRB5_AUTH_CONTEXT_DO_SEQUENCE ============================= .. .. data:: KRB5_AUTH_CONTEXT_DO_SEQUENCE .. Prevent replays with sequence numbers. ==================================== ====================== ``KRB5_AUTH_CONTEXT_DO_SEQUENCE`` ``0x00000004`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_princ_name.rst.txt0000664000175000017500000000045315051422642026010 0ustar ghudsonghudson.. highlight:: c .. _krb5-princ-name-data: krb5_princ_name =============== .. .. data:: krb5_princ_name .. ====================================== ====================== ``krb5_princ_name (context, princ)`` ``(princ)->data`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ONE_LAST_INITIAL.rst.txt0000664000175000017500000000046715051422642026675 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ONE-LAST-INITIAL-data: KRB5_LRQ_ONE_LAST_INITIAL ========================= .. .. data:: KRB5_LRQ_ONE_LAST_INITIAL .. ================================ ====================== ``KRB5_LRQ_ONE_LAST_INITIAL`` ``(-2)`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN.rst.txt0000664000175000017500000000070015051422642030402 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-OTP-FLAGS-COLLECT-PIN-data: KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN ==================================== .. .. data:: KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN .. This flag indicates that the PIN value MUST be collected. =========================================== ====================== ``KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN`` ``0x0002`` =========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_LOGON_INFO.rst.txt0000664000175000017500000000043515051422642025711 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-LOGON-INFO-data: KRB5_PAC_LOGON_INFO =================== .. .. data:: KRB5_PAC_LOGON_INFO .. Logon information. ========================== ====================== ``KRB5_PAC_LOGON_INFO`` ``1`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_princ_set_realm.rst.txt0000664000175000017500000000056115051422642027043 0ustar ghudsonghudson.. highlight:: c .. _krb5-princ-set-realm-data: krb5_princ_set_realm ==================== .. .. data:: krb5_princ_set_realm .. ================================================== ====================== ``krb5_princ_set_realm (context, princ, value)`` ``((princ)->realm = *(value))`` ================================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_SAM_MUST_PK_ENCRYPT_SAD.rst.txt0000664000175000017500000000055115051422642027311 0ustar ghudsonghudson.. highlight:: c .. _KRB5-SAM-MUST-PK-ENCRYPT-SAD-data: KRB5_SAM_MUST_PK_ENCRYPT_SAD ============================ .. .. data:: KRB5_SAM_MUST_PK_ENCRYPT_SAD .. currently must be zero =================================== ====================== ``KRB5_SAM_MUST_PK_ENCRYPT_SAD`` ``0x20000000`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/index.rst.txt0000664000175000017500000002774615051422642024077 0ustar ghudsonghudsonkrb5 simple macros ========================= Public ------- .. toctree:: :maxdepth: 1 ADDRTYPE_ADDRPORT.rst ADDRTYPE_CHAOS.rst ADDRTYPE_DIRECTIONAL.rst ADDRTYPE_DDP.rst ADDRTYPE_INET.rst ADDRTYPE_INET6.rst ADDRTYPE_IPPORT.rst ADDRTYPE_ISO.rst ADDRTYPE_IS_LOCAL.rst ADDRTYPE_NETBIOS.rst ADDRTYPE_XNS.rst ADDRTYPE_UNIXSOCK.rst AD_TYPE_EXTERNAL.rst AD_TYPE_FIELD_TYPE_MASK.rst AD_TYPE_REGISTERED.rst AD_TYPE_RESERVED.rst AP_OPTS_ETYPE_NEGOTIATION.rst AP_OPTS_CBT_FLAG.rst AP_OPTS_MUTUAL_REQUIRED.rst AP_OPTS_RESERVED.rst AP_OPTS_USE_SESSION_KEY.rst AP_OPTS_USE_SUBKEY.rst AP_OPTS_WIRE_MASK.rst CKSUMTYPE_CMAC_CAMELLIA128.rst CKSUMTYPE_CMAC_CAMELLIA256.rst CKSUMTYPE_CRC32.rst CKSUMTYPE_DESCBC.rst CKSUMTYPE_HMAC_MD5_ARCFOUR.rst CKSUMTYPE_HMAC_SHA1_96_AES128.rst CKSUMTYPE_HMAC_SHA1_96_AES256.rst CKSUMTYPE_HMAC_SHA256_128_AES128.rst CKSUMTYPE_HMAC_SHA384_192_AES256.rst CKSUMTYPE_HMAC_SHA1_DES3.rst CKSUMTYPE_MD5_HMAC_ARCFOUR.rst CKSUMTYPE_NIST_SHA.rst CKSUMTYPE_RSA_MD4.rst CKSUMTYPE_RSA_MD4_DES.rst CKSUMTYPE_RSA_MD5.rst CKSUMTYPE_RSA_MD5_DES.rst CKSUMTYPE_SHA1.rst ENCTYPE_AES128_CTS_HMAC_SHA1_96.rst ENCTYPE_AES128_CTS_HMAC_SHA256_128.rst ENCTYPE_AES256_CTS_HMAC_SHA1_96.rst ENCTYPE_AES256_CTS_HMAC_SHA384_192.rst ENCTYPE_ARCFOUR_HMAC.rst ENCTYPE_ARCFOUR_HMAC_EXP.rst ENCTYPE_CAMELLIA128_CTS_CMAC.rst ENCTYPE_CAMELLIA256_CTS_CMAC.rst ENCTYPE_DES3_CBC_ENV.rst ENCTYPE_DES3_CBC_RAW.rst ENCTYPE_DES3_CBC_SHA.rst ENCTYPE_DES3_CBC_SHA1.rst ENCTYPE_DES_CBC_CRC.rst ENCTYPE_DES_CBC_MD4.rst ENCTYPE_DES_CBC_MD5.rst ENCTYPE_DES_CBC_RAW.rst ENCTYPE_DES_HMAC_SHA1.rst ENCTYPE_DSA_SHA1_CMS.rst ENCTYPE_MD5_RSA_CMS.rst ENCTYPE_NULL.rst ENCTYPE_RC2_CBC_ENV.rst ENCTYPE_RSA_ENV.rst ENCTYPE_RSA_ES_OAEP_ENV.rst ENCTYPE_SHA1_RSA_CMS.rst ENCTYPE_UNKNOWN.rst KDC_OPT_ALLOW_POSTDATE.rst KDC_OPT_CANONICALIZE.rst KDC_OPT_CNAME_IN_ADDL_TKT.rst KDC_OPT_DISABLE_TRANSITED_CHECK.rst KDC_OPT_ENC_TKT_IN_SKEY.rst KDC_OPT_FORWARDABLE.rst KDC_OPT_FORWARDED.rst KDC_OPT_POSTDATED.rst KDC_OPT_PROXIABLE.rst KDC_OPT_PROXY.rst KDC_OPT_RENEW.rst KDC_OPT_RENEWABLE.rst KDC_OPT_RENEWABLE_OK.rst KDC_OPT_REQUEST_ANONYMOUS.rst KDC_OPT_VALIDATE.rst KDC_TKT_COMMON_MASK.rst KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE.rst KRB5_ANONYMOUS_PRINCSTR.rst KRB5_ANONYMOUS_REALMSTR.rst KRB5_AP_REP.rst KRB5_AP_REQ.rst KRB5_AS_REP.rst KRB5_AS_REQ.rst KRB5_AUTHDATA_AND_OR.rst KRB5_AUTHDATA_AP_OPTIONS.rst KRB5_AUTHDATA_AUTH_INDICATOR.rst KRB5_AUTHDATA_CAMMAC.rst KRB5_AUTHDATA_ETYPE_NEGOTIATION.rst KRB5_AUTHDATA_FX_ARMOR.rst KRB5_AUTHDATA_IF_RELEVANT.rst KRB5_AUTHDATA_INITIAL_VERIFIED_CAS.rst KRB5_AUTHDATA_KDC_ISSUED.rst KRB5_AUTHDATA_MANDATORY_FOR_KDC.rst KRB5_AUTHDATA_OSF_DCE.rst KRB5_AUTHDATA_SESAME.rst KRB5_AUTHDATA_SIGNTICKET.rst KRB5_AUTHDATA_WIN2K_PAC.rst KRB5_AUTH_CONTEXT_DO_SEQUENCE.rst KRB5_AUTH_CONTEXT_DO_TIME.rst KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR.rst KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR.rst KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR.rst KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR.rst KRB5_AUTH_CONTEXT_PERMIT_ALL.rst KRB5_AUTH_CONTEXT_RET_SEQUENCE.rst KRB5_AUTH_CONTEXT_RET_TIME.rst KRB5_AUTH_CONTEXT_USE_SUBKEY.rst KRB5_CRED.rst KRB5_CRYPTO_TYPE_CHECKSUM.rst KRB5_CRYPTO_TYPE_DATA.rst KRB5_CRYPTO_TYPE_EMPTY.rst KRB5_CRYPTO_TYPE_HEADER.rst KRB5_CRYPTO_TYPE_PADDING.rst KRB5_CRYPTO_TYPE_SIGN_ONLY.rst KRB5_CRYPTO_TYPE_STREAM.rst KRB5_CRYPTO_TYPE_TRAILER.rst KRB5_CYBERSAFE_SECUREID.rst KRB5_DOMAIN_X500_COMPRESS.rst KRB5_ENCPADATA_REQ_ENC_PA_REP.rst KRB5_ERROR.rst KRB5_FAST_REQUIRED.rst KRB5_GC_CACHED.rst KRB5_GC_CANONICALIZE.rst KRB5_GC_CONSTRAINED_DELEGATION.rst KRB5_GC_FORWARDABLE.rst KRB5_GC_NO_STORE.rst KRB5_GC_NO_TRANSIT_CHECK.rst KRB5_GC_USER_USER.rst KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST.rst KRB5_GET_INIT_CREDS_OPT_ANONYMOUS.rst KRB5_GET_INIT_CREDS_OPT_CANONICALIZE.rst KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT.rst KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST.rst KRB5_GET_INIT_CREDS_OPT_FORWARDABLE.rst KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST.rst KRB5_GET_INIT_CREDS_OPT_PROXIABLE.rst KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE.rst KRB5_GET_INIT_CREDS_OPT_SALT.rst KRB5_GET_INIT_CREDS_OPT_TKT_LIFE.rst KRB5_INIT_CONTEXT_SECURE.rst KRB5_INIT_CONTEXT_KDC.rst KRB5_INIT_CREDS_STEP_FLAG_CONTINUE.rst KRB5_INT16_MAX.rst KRB5_INT16_MIN.rst KRB5_INT32_MAX.rst KRB5_INT32_MIN.rst KRB5_KEYUSAGE_AD_ITE.rst KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM.rst KRB5_KEYUSAGE_AD_MTE.rst KRB5_KEYUSAGE_AD_SIGNEDPATH.rst KRB5_KEYUSAGE_APP_DATA_CKSUM.rst KRB5_KEYUSAGE_APP_DATA_ENCRYPT.rst KRB5_KEYUSAGE_AP_REP_ENCPART.rst KRB5_KEYUSAGE_AP_REQ_AUTH.rst KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM.rst KRB5_KEYUSAGE_AS_REP_ENCPART.rst KRB5_KEYUSAGE_AS_REQ.rst KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS.rst KRB5_KEYUSAGE_CAMMAC.rst KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT.rst KRB5_KEYUSAGE_ENC_CHALLENGE_KDC.rst KRB5_KEYUSAGE_FAST_ENC.rst KRB5_KEYUSAGE_FAST_FINISHED.rst KRB5_KEYUSAGE_FAST_REP.rst KRB5_KEYUSAGE_FAST_REQ_CHKSUM.rst KRB5_KEYUSAGE_GSS_TOK_MIC.rst KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG.rst KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV.rst KRB5_KEYUSAGE_FINISHED.rst KRB5_KEYUSAGE_IAKERB_FINISHED.rst KRB5_KEYUSAGE_KDC_REP_TICKET.rst KRB5_KEYUSAGE_KRB_CRED_ENCPART.rst KRB5_KEYUSAGE_KRB_ERROR_CKSUM.rst KRB5_KEYUSAGE_KRB_PRIV_ENCPART.rst KRB5_KEYUSAGE_KRB_SAFE_CKSUM.rst KRB5_KEYUSAGE_PA_AS_FRESHNESS.rst KRB5_KEYUSAGE_PA_FX_COOKIE.rst KRB5_KEYUSAGE_PA_OTP_REQUEST.rst KRB5_KEYUSAGE_PA_PKINIT_KX.rst KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY.rst KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST.rst KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM.rst KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID.rst KRB5_KEYUSAGE_PA_SAM_RESPONSE.rst KRB5_KEYUSAGE_SPAKE.rst KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY.rst KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY.rst KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY.rst KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY.rst KRB5_KEYUSAGE_TGS_REQ_AUTH.rst KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM.rst KRB5_KPASSWD_ACCESSDENIED.rst KRB5_KPASSWD_AUTHERROR.rst KRB5_KPASSWD_BAD_VERSION.rst KRB5_KPASSWD_HARDERROR.rst KRB5_KPASSWD_INITIAL_FLAG_NEEDED.rst KRB5_KPASSWD_MALFORMED.rst KRB5_KPASSWD_SOFTERROR.rst KRB5_KPASSWD_SUCCESS.rst KRB5_LRQ_ALL_ACCT_EXPTIME.rst KRB5_LRQ_ALL_LAST_INITIAL.rst KRB5_LRQ_ALL_LAST_RENEWAL.rst KRB5_LRQ_ALL_LAST_REQ.rst KRB5_LRQ_ALL_LAST_TGT.rst KRB5_LRQ_ALL_LAST_TGT_ISSUED.rst KRB5_LRQ_ALL_PW_EXPTIME.rst KRB5_LRQ_NONE.rst KRB5_LRQ_ONE_ACCT_EXPTIME.rst KRB5_LRQ_ONE_LAST_INITIAL.rst KRB5_LRQ_ONE_LAST_RENEWAL.rst KRB5_LRQ_ONE_LAST_REQ.rst KRB5_LRQ_ONE_LAST_TGT.rst KRB5_LRQ_ONE_LAST_TGT_ISSUED.rst KRB5_LRQ_ONE_PW_EXPTIME.rst KRB5_NT_ENTERPRISE_PRINCIPAL.rst KRB5_NT_ENT_PRINCIPAL_AND_ID.rst KRB5_NT_MS_PRINCIPAL.rst KRB5_NT_MS_PRINCIPAL_AND_ID.rst KRB5_NT_PRINCIPAL.rst KRB5_NT_SMTP_NAME.rst KRB5_NT_SRV_HST.rst KRB5_NT_SRV_INST.rst KRB5_NT_SRV_XHST.rst KRB5_NT_UID.rst KRB5_NT_UNKNOWN.rst KRB5_NT_WELLKNOWN.rst KRB5_NT_X500_PRINCIPAL.rst KRB5_PAC_ATTRIBUTES_INFO.rst KRB5_PAC_CLIENT_INFO.rst KRB5_PAC_CLIENT_CLAIMS.rst KRB5_PAC_CREDENTIALS_INFO.rst KRB5_PAC_DELEGATION_INFO.rst KRB5_PAC_DEVICE_CLAIMS.rst KRB5_PAC_DEVICE_INFO.rst KRB5_PAC_LOGON_INFO.rst KRB5_PAC_PRIVSVR_CHECKSUM.rst KRB5_PAC_REQUESTOR.rst KRB5_PAC_SERVER_CHECKSUM.rst KRB5_PAC_TICKET_CHECKSUM.rst KRB5_PAC_UPN_DNS_INFO.rst KRB5_PAC_FULL_CHECKSUM.rst KRB5_PADATA_AFS3_SALT.rst KRB5_PADATA_AP_REQ.rst KRB5_PADATA_AS_CHECKSUM.rst KRB5_PADATA_AS_FRESHNESS.rst KRB5_PADATA_ENCRYPTED_CHALLENGE.rst KRB5_PADATA_ENC_SANDIA_SECURID.rst KRB5_PADATA_ENC_TIMESTAMP.rst KRB5_PADATA_ENC_UNIX_TIME.rst KRB5_PADATA_ETYPE_INFO.rst KRB5_PADATA_ETYPE_INFO2.rst KRB5_PADATA_FOR_USER.rst KRB5_PADATA_FX_COOKIE.rst KRB5_PADATA_FX_ERROR.rst KRB5_PADATA_FX_FAST.rst KRB5_PADATA_GET_FROM_TYPED_DATA.rst KRB5_PADATA_NONE.rst KRB5_PADATA_OSF_DCE.rst KRB5_PADATA_OTP_CHALLENGE.rst KRB5_PADATA_OTP_PIN_CHANGE.rst KRB5_PADATA_OTP_REQUEST.rst KRB5_PADATA_PAC_OPTIONS.rst KRB5_PADATA_PAC_REQUEST.rst KRB5_PADATA_PKINIT_KX.rst KRB5_PADATA_PK_AS_REP.rst KRB5_PADATA_PK_AS_REP_OLD.rst KRB5_PADATA_PK_AS_REQ.rst KRB5_PADATA_PK_AS_REQ_OLD.rst KRB5_PADATA_PW_SALT.rst KRB5_PADATA_REFERRAL.rst KRB5_PADATA_S4U_X509_USER.rst KRB5_PADATA_SAM_CHALLENGE.rst KRB5_PADATA_SAM_CHALLENGE_2.rst KRB5_PADATA_SAM_REDIRECT.rst KRB5_PADATA_SAM_RESPONSE.rst KRB5_PADATA_SAM_RESPONSE_2.rst KRB5_PADATA_SESAME.rst KRB5_PADATA_SPAKE.rst KRB5_PADATA_REDHAT_IDP_OAUTH2.rst KRB5_PADATA_REDHAT_PASSKEY.rst KRB5_PADATA_SVR_REFERRAL_INFO.rst KRB5_PADATA_TGS_REQ.rst KRB5_PADATA_USE_SPECIFIED_KVNO.rst KRB5_PRINCIPAL_COMPARE_CASEFOLD.rst KRB5_PRINCIPAL_COMPARE_ENTERPRISE.rst KRB5_PRINCIPAL_COMPARE_IGNORE_REALM.rst KRB5_PRINCIPAL_COMPARE_UTF8.rst KRB5_PRINCIPAL_PARSE_ENTERPRISE.rst KRB5_PRINCIPAL_PARSE_IGNORE_REALM.rst KRB5_PRINCIPAL_PARSE_NO_DEF_REALM.rst KRB5_PRINCIPAL_PARSE_NO_REALM.rst KRB5_PRINCIPAL_PARSE_REQUIRE_REALM.rst KRB5_PRINCIPAL_UNPARSE_DISPLAY.rst KRB5_PRINCIPAL_UNPARSE_NO_REALM.rst KRB5_PRINCIPAL_UNPARSE_SHORT.rst KRB5_PRIV.rst KRB5_PROMPT_TYPE_NEW_PASSWORD.rst KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN.rst KRB5_PROMPT_TYPE_PASSWORD.rst KRB5_PROMPT_TYPE_PREAUTH.rst KRB5_PVNO.rst KRB5_REALM_BRANCH_CHAR.rst KRB5_RECVAUTH_BADAUTHVERS.rst KRB5_RECVAUTH_SKIP_VERSION.rst KRB5_REFERRAL_REALM.rst KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW.rst KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY.rst KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED.rst KRB5_RESPONDER_QUESTION_PKINIT.rst KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN.rst KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN.rst KRB5_RESPONDER_OTP_FLAGS_NEXTOTP.rst KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN.rst KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC.rst KRB5_RESPONDER_OTP_FORMAT_DECIMAL.rst KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL.rst KRB5_RESPONDER_QUESTION_OTP.rst KRB5_RESPONDER_QUESTION_PASSWORD.rst KRB5_SAFE.rst KRB5_SAM_MUST_PK_ENCRYPT_SAD.rst KRB5_SAM_SEND_ENCRYPTED_SAD.rst KRB5_SAM_USE_SAD_AS_KEY.rst KRB5_TC_MATCH_2ND_TKT.rst KRB5_TC_MATCH_AUTHDATA.rst KRB5_TC_MATCH_FLAGS.rst KRB5_TC_MATCH_FLAGS_EXACT.rst KRB5_TC_MATCH_IS_SKEY.rst KRB5_TC_MATCH_KTYPE.rst KRB5_TC_MATCH_SRV_NAMEONLY.rst KRB5_TC_MATCH_TIMES.rst KRB5_TC_MATCH_TIMES_EXACT.rst KRB5_TC_NOTICKET.rst KRB5_TC_OPENCLOSE.rst KRB5_TC_SUPPORTED_KTYPES.rst KRB5_TGS_NAME.rst KRB5_TGS_NAME_SIZE.rst KRB5_TGS_REP.rst KRB5_TGS_REQ.rst KRB5_TKT_CREDS_STEP_FLAG_CONTINUE.rst KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL.rst KRB5_WELLKNOWN_NAMESTR.rst LR_TYPE_INTERPRETATION_MASK.rst LR_TYPE_THIS_SERVER_ONLY.rst MAX_KEYTAB_NAME_LEN.rst MSEC_DIRBIT.rst MSEC_VAL_MASK.rst SALT_TYPE_AFS_LENGTH.rst SALT_TYPE_NO_LENGTH.rst THREEPARAMOPEN.rst TKT_FLG_ANONYMOUS.rst TKT_FLG_ENC_PA_REP.rst TKT_FLG_FORWARDABLE.rst TKT_FLG_FORWARDED.rst TKT_FLG_HW_AUTH.rst TKT_FLG_INITIAL.rst TKT_FLG_INVALID.rst TKT_FLG_MAY_POSTDATE.rst TKT_FLG_OK_AS_DELEGATE.rst TKT_FLG_POSTDATED.rst TKT_FLG_PRE_AUTH.rst TKT_FLG_PROXIABLE.rst TKT_FLG_PROXY.rst TKT_FLG_RENEWABLE.rst TKT_FLG_TRANSIT_POLICY_CHECKED.rst VALID_INT_BITS.rst VALID_UINT_BITS.rst krb5_const.rst krb5_princ_component.rst krb5_princ_name.rst krb5_princ_realm.rst krb5_princ_set_realm.rst krb5_princ_set_realm_data.rst krb5_princ_set_realm_length.rst krb5_princ_size.rst krb5_princ_type.rst krb5_roundup.rst krb5_x.rst krb5_xc.rst Deprecated macros ------------------------------ .. toctree:: :maxdepth: 1 krb524_convert_creds_kdc.rst krb524_init_ets.rst krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_OTP_REQUEST.rst.txt0000664000175000017500000000047615051422642026426 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-OTP-REQUEST-data: KRB5_PADATA_OTP_REQUEST ======================= .. .. data:: KRB5_PADATA_OTP_REQUEST .. RFC 6560 section 4.2. ============================== ====================== ``KRB5_PADATA_OTP_REQUEST`` ``142`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_MATCH_SRV_NAMEONLY.rst.txt0000664000175000017500000000057415051422642027017 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-MATCH-SRV-NAMEONLY-data: KRB5_TC_MATCH_SRV_NAMEONLY ========================== .. .. data:: KRB5_TC_MATCH_SRV_NAMEONLY .. Only the name portion of the principal name must match. ================================= ====================== ``KRB5_TC_MATCH_SRV_NAMEONLY`` ``0x00000040`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH.rst.txt0000664000175000017500000000047315051422642027021 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-TGS-REQ-AUTH-data: KRB5_KEYUSAGE_TGS_REQ_AUTH ========================== .. .. data:: KRB5_KEYUSAGE_TGS_REQ_AUTH .. ================================= ====================== ``KRB5_KEYUSAGE_TGS_REQ_AUTH`` ``7`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_PROXY.rst.txt0000664000175000017500000000035115051422642025102 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-PROXY-data: TKT_FLG_PROXY ============= .. .. data:: TKT_FLG_PROXY .. ==================== ====================== ``TKT_FLG_PROXY`` ``0x08000000`` ==================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CRYPTO_TYPE_TRAILER.rst.txt0000664000175000017500000000051015051422642026572 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CRYPTO-TYPE-TRAILER-data: KRB5_CRYPTO_TYPE_TRAILER ======================== .. .. data:: KRB5_CRYPTO_TYPE_TRAILER .. [out] checksum for encrypt =============================== ====================== ``KRB5_CRYPTO_TYPE_TRAILER`` ``5`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb524_convert_creds_kdc.rst.txt0000664000175000017500000000050215051422642027517 0ustar ghudsonghudson.. highlight:: c .. _krb524-convert-creds-kdc-data: krb524_convert_creds_kdc ======================== .. .. data:: krb524_convert_creds_kdc .. =============================== ====================== ``krb524_convert_creds_kdc`` ``krb5_524_convert_creds`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ.rst.txt0000664000175000017500000000042215051422642026040 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AS-REQ-data: KRB5_KEYUSAGE_AS_REQ ==================== .. .. data:: KRB5_KEYUSAGE_AS_REQ .. =========================== ====================== ``KRB5_KEYUSAGE_AS_REQ`` ``56`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_AND_OR.rst.txt0000664000175000017500000000042115051422642026005 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-AND-OR-data: KRB5_AUTHDATA_AND_OR ==================== .. .. data:: KRB5_AUTHDATA_AND_OR .. =========================== ====================== ``KRB5_AUTHDATA_AND_OR`` ``5`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_AUTH_INDICATOR.rst.txt0000664000175000017500000000051215051422642027141 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-AUTH-INDICATOR-data: KRB5_AUTHDATA_AUTH_INDICATOR ============================ .. .. data:: KRB5_AUTHDATA_AUTH_INDICATOR .. =================================== ====================== ``KRB5_AUTHDATA_AUTH_INDICATOR`` ``97`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_PRE_AUTH.rst.txt0000664000175000017500000000037615051422642025437 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-PRE-AUTH-data: TKT_FLG_PRE_AUTH ================ .. .. data:: TKT_FLG_PRE_AUTH .. ======================= ====================== ``TKT_FLG_PRE_AUTH`` ``0x00200000`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_INET6.rst.txt0000664000175000017500000000035415051422642025073 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-INET6-data: ADDRTYPE_INET6 ============== .. .. data:: ADDRTYPE_INET6 .. ===================== ====================== ``ADDRTYPE_INET6`` ``0x0018`` ===================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_SRV_INST.rst.txt0000664000175000017500000000044015051422642025441 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-SRV-INST-data: KRB5_NT_SRV_INST ================ .. .. data:: KRB5_NT_SRV_INST .. Service and other unique instance (krbtgt) ======================= ====================== ``KRB5_NT_SRV_INST`` ``2`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_HMAC_SHA256_128_AES128.rst.txt0000664000175000017500000000056415051422642027376 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-HMAC-SHA256-128-AES128-data: CKSUMTYPE_HMAC_SHA256_128_AES128 ================================ .. .. data:: CKSUMTYPE_HMAC_SHA256_128_AES128 .. RFC 8009. ======================================= ====================== ``CKSUMTYPE_HMAC_SHA256_128_AES128`` ``0x0013`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DES_CBC_CRC.rst.txt0000664000175000017500000000041715051422642025712 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DES-CBC-CRC-data: ENCTYPE_DES_CBC_CRC =================== .. .. data:: ENCTYPE_DES_CBC_CRC .. ========================== ====================== ``ENCTYPE_DES_CBC_CRC`` ``0x0001`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_RC2_CBC_ENV.rst.txt0000664000175000017500000000046115051422642025705 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-RC2-CBC-ENV-data: ENCTYPE_RC2_CBC_ENV =================== .. .. data:: ENCTYPE_RC2_CBC_ENV .. RC2 cbc mode, CMS enveloped data. ========================== ====================== ``ENCTYPE_RC2_CBC_ENV`` ``0x000c`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_IPPORT.rst.txt0000664000175000017500000000036315051422642025263 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-IPPORT-data: ADDRTYPE_IPPORT =============== .. .. data:: ADDRTYPE_IPPORT .. ====================== ====================== ``ADDRTYPE_IPPORT`` ``0x0101`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE.rst.txt0000664000175000017500000000046715051422642026512 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-SAM-RESPONSE-data: KRB5_PADATA_SAM_RESPONSE ======================== .. .. data:: KRB5_PADATA_SAM_RESPONSE .. SAM/OTP. =============================== ====================== ``KRB5_PADATA_SAM_RESPONSE`` ``13`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_DEVICE_CLAIMS.rst.txt0000664000175000017500000000047315051422642026211 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-DEVICE-CLAIMS-data: KRB5_PAC_DEVICE_CLAIMS ====================== .. .. data:: KRB5_PAC_DEVICE_CLAIMS .. Device claims information. ============================= ====================== ``KRB5_PAC_DEVICE_CLAIMS`` ``15`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC.rst.txt0000664000175000017500000000044015051422642026026 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-ARCFOUR-HMAC-data: ENCTYPE_ARCFOUR_HMAC ==================== .. .. data:: ENCTYPE_ARCFOUR_HMAC .. RFC 4757. =========================== ====================== ``ENCTYPE_ARCFOUR_HMAC`` ``0x0017`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_DDP.rst.txt0000664000175000017500000000033615051422642024655 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-DDP-data: ADDRTYPE_DDP ============ .. .. data:: ADDRTYPE_DDP .. =================== ====================== ``ADDRTYPE_DDP`` ``0x0010`` =================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_REQUEST_ANONYMOUS.rst.txt0000664000175000017500000000047515051422642026761 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-REQUEST-ANONYMOUS-data: KDC_OPT_REQUEST_ANONYMOUS ========================= .. .. data:: KDC_OPT_REQUEST_ANONYMOUS .. ================================ ====================== ``KDC_OPT_REQUEST_ANONYMOUS`` ``0x00008000`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_KRB_PRIV_ENCPART.rst.txt0000664000175000017500000000053015051422642027460 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-KRB-PRIV-ENCPART-data: KRB5_KEYUSAGE_KRB_PRIV_ENCPART ============================== .. .. data:: KRB5_KEYUSAGE_KRB_PRIV_ENCPART .. ===================================== ====================== ``KRB5_KEYUSAGE_KRB_PRIV_ENCPART`` ``13`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_REFERRAL.rst.txt0000664000175000017500000000045015051422642025746 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-REFERRAL-data: KRB5_PADATA_REFERRAL ==================== .. .. data:: KRB5_PADATA_REFERRAL .. draft referral system =========================== ====================== ``KRB5_PADATA_REFERRAL`` ``25`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_PA_OTP_REQUEST.rst.txt0000664000175000017500000000054415051422642027265 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-PA-OTP-REQUEST-data: KRB5_KEYUSAGE_PA_OTP_REQUEST ============================ .. .. data:: KRB5_KEYUSAGE_PA_OTP_REQUEST .. See RFC 6560 section 4.2. =================================== ====================== ``KRB5_KEYUSAGE_PA_OTP_REQUEST`` ``45`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_QUESTION_PASSWORD.rst.txt0000664000175000017500000000103015051422642027737 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-QUESTION-PASSWORD-data: KRB5_RESPONDER_QUESTION_PASSWORD ================================ .. .. data:: KRB5_RESPONDER_QUESTION_PASSWORD .. Long-term password responder question. This question is asked when the long-term password is needed. It has no challenge and the response is simply the password string. ======================================= ====================== ``KRB5_RESPONDER_QUESTION_PASSWORD`` ``"password"`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_PK_AS_REQ.rst.txt0000664000175000017500000000045115051422642026151 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-PK-AS-REQ-data: KRB5_PADATA_PK_AS_REQ ===================== .. .. data:: KRB5_PADATA_PK_AS_REQ .. PKINIT. RFC 4556 ============================ ====================== ``KRB5_PADATA_PK_AS_REQ`` ``16`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_IGNORE_REALM.rst.txt0000664000175000017500000000060715051422642027774 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-PARSE-IGNORE-REALM-data: KRB5_PRINCIPAL_PARSE_IGNORE_REALM ================================= .. .. data:: KRB5_PRINCIPAL_PARSE_IGNORE_REALM .. Ignore realm if present. ======================================== ====================== ``KRB5_PRINCIPAL_PARSE_IGNORE_REALM`` ``0x8`` ======================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE.rst.txt0000664000175000017500000000047615051422642026536 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-SAM-CHALLENGE-data: KRB5_PADATA_SAM_CHALLENGE ========================= .. .. data:: KRB5_PADATA_SAM_CHALLENGE .. SAM/OTP. ================================ ====================== ``KRB5_PADATA_SAM_CHALLENGE`` ``12`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_SVR_REFERRAL_INFO.rst.txt0000664000175000017500000000056115051422642027316 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-SVR-REFERRAL-INFO-data: KRB5_PADATA_SVR_REFERRAL_INFO ============================= .. .. data:: KRB5_PADATA_SVR_REFERRAL_INFO .. Windows 2000 referrals. RFC 6820 ==================================== ====================== ``KRB5_PADATA_SVR_REFERRAL_INFO`` ``20`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_ADDRPORT.rst.txt0000664000175000017500000000040115051422642025456 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-ADDRPORT-data: ADDRTYPE_ADDRPORT ================= .. .. data:: ADDRTYPE_ADDRPORT .. ======================== ====================== ``ADDRTYPE_ADDRPORT`` ``0x0100`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KPASSWD_ACCESSDENIED.rst.txt0000664000175000017500000000050415051422642026540 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KPASSWD-ACCESSDENIED-data: KRB5_KPASSWD_ACCESSDENIED ========================= .. .. data:: KRB5_KPASSWD_ACCESSDENIED .. Not authorized. ================================ ====================== ``KRB5_KPASSWD_ACCESSDENIED`` ``5`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_princ_set_realm_data.rst.txt0000664000175000017500000000062615051422642030036 0ustar ghudsonghudson.. highlight:: c .. _krb5-princ-set-realm-data-data: krb5_princ_set_realm_data ========================= .. .. data:: krb5_princ_set_realm_data .. ======================================================= ====================== ``krb5_princ_set_realm_data (context, princ, value)`` ``(princ)->realm.data = (value)`` ======================================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DES3_CBC_SHA1.rst.txt0000664000175000017500000000043515051422642026062 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DES3-CBC-SHA1-data: ENCTYPE_DES3_CBC_SHA1 ===================== .. .. data:: ENCTYPE_DES3_CBC_SHA1 .. ============================ ====================== ``ENCTYPE_DES3_CBC_SHA1`` ``0x0010`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_DISABLE_TRANSITED_CHECK.rst.txt0000664000175000017500000000054715051422642027536 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-DISABLE-TRANSITED-CHECK-data: KDC_OPT_DISABLE_TRANSITED_CHECK =============================== .. .. data:: KDC_OPT_DISABLE_TRANSITED_CHECK .. ====================================== ====================== ``KDC_OPT_DISABLE_TRANSITED_CHECK`` ``0x00000020`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_SPAKE.rst.txt0000664000175000017500000000041315051422642025671 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-SPAKE-data: KRB5_KEYUSAGE_SPAKE =================== .. .. data:: KRB5_KEYUSAGE_SPAKE .. ========================== ====================== ``KRB5_KEYUSAGE_SPAKE`` ``65`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE.rst.txt0000664000175000017500000000063215051422642030226 0ustar ghudsonghudson.. highlight:: c .. _KRB5-ALTAUTH-ATT-CHALLENGE-RESPONSE-data: KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE =================================== .. .. data:: KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE .. alternate authentication types ========================================== ====================== ``KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE`` ``64`` ========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_PROXIABLE.rst.txt0000664000175000017500000000040515051422642025506 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-PROXIABLE-data: TKT_FLG_PROXIABLE ================= .. .. data:: TKT_FLG_PROXIABLE .. ======================== ====================== ``TKT_FLG_PROXIABLE`` ``0x10000000`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRIV.rst.txt0000664000175000017500000000036215051422642024314 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRIV-data: KRB5_PRIV ========= .. .. data:: KRB5_PRIV .. Private application message. ================ ====================== ``KRB5_PRIV`` ``((krb5_msgtype)21)`` ================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/VALID_UINT_BITS.rst.txt0000664000175000017500000000036515051422642025273 0ustar ghudsonghudson.. highlight:: c .. _VALID-UINT-BITS-data: VALID_UINT_BITS =============== .. .. data:: VALID_UINT_BITS .. ====================== ====================== ``VALID_UINT_BITS`` ``UINT_MAX`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CRYPTO_TYPE_STREAM.rst.txt0000664000175000017500000000060215051422642026465 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CRYPTO-TYPE-STREAM-data: KRB5_CRYPTO_TYPE_STREAM ======================= .. .. data:: KRB5_CRYPTO_TYPE_STREAM .. [in] entire message without decomposing the structure into header, data and trailer buffers ============================== ====================== ``KRB5_CRYPTO_TYPE_STREAM`` ``7`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_REALM_BRANCH_CHAR.rst.txt0000664000175000017500000000044115051422642026204 0ustar ghudsonghudson.. highlight:: c .. _KRB5-REALM-BRANCH-CHAR-data: KRB5_REALM_BRANCH_CHAR ====================== .. .. data:: KRB5_REALM_BRANCH_CHAR .. ============================= ====================== ``KRB5_REALM_BRANCH_CHAR`` ``'.'`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_RSA_ES_OAEP_ENV.rst.txt0000664000175000017500000000052615051422642026472 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-RSA-ES-OAEP-ENV-data: ENCTYPE_RSA_ES_OAEP_ENV ======================= .. .. data:: ENCTYPE_RSA_ES_OAEP_ENV .. RSA w/OEAP encryption, CMS enveloped data. ============================== ====================== ``ENCTYPE_RSA_ES_OAEP_ENV`` ``0x000e`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PVNO.rst.txt0000664000175000017500000000033515051422642024316 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PVNO-data: KRB5_PVNO ========= .. .. data:: KRB5_PVNO .. Protocol version number. ================ ====================== ``KRB5_PVNO`` ``5`` ================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_TIME.rst.txt0000664000175000017500000000055715051422642026707 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-DO-TIME-data: KRB5_AUTH_CONTEXT_DO_TIME ========================= .. .. data:: KRB5_AUTH_CONTEXT_DO_TIME .. Prevent replays with timestamps and replay cache. ================================ ====================== ``KRB5_AUTH_CONTEXT_DO_TIME`` ``0x00000001`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_DISPLAY.rst.txt0000664000175000017500000000057215051422642027442 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-UNPARSE-DISPLAY-data: KRB5_PRINCIPAL_UNPARSE_DISPLAY ============================== .. .. data:: KRB5_PRINCIPAL_UNPARSE_DISPLAY .. Don't escape special characters. ===================================== ====================== ``KRB5_PRINCIPAL_UNPARSE_DISPLAY`` ``0x4`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AD_ITE.rst.txt0000664000175000017500000000042215051422642026013 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AD-ITE-data: KRB5_KEYUSAGE_AD_ITE ==================== .. .. data:: KRB5_KEYUSAGE_AD_ITE .. =========================== ====================== ``KRB5_KEYUSAGE_AD_ITE`` ``21`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KPASSWD_HARDERROR.rst.txt0000664000175000017500000000045515051422642026263 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KPASSWD-HARDERROR-data: KRB5_KPASSWD_HARDERROR ====================== .. .. data:: KRB5_KPASSWD_HARDERROR .. Server error. ============================= ====================== ``KRB5_KPASSWD_HARDERROR`` ``2`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_FAST_REQ_CHKSUM.rst.txt0000664000175000017500000000052115051422642027344 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-FAST-REQ-CHKSUM-data: KRB5_KEYUSAGE_FAST_REQ_CHKSUM ============================= .. .. data:: KRB5_KEYUSAGE_FAST_REQ_CHKSUM .. ==================================== ====================== ``KRB5_KEYUSAGE_FAST_REQ_CHKSUM`` ``50`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KPASSWD_SUCCESS.rst.txt0000664000175000017500000000043215051422642026036 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KPASSWD-SUCCESS-data: KRB5_KPASSWD_SUCCESS ==================== .. .. data:: KRB5_KPASSWD_SUCCESS .. Success. =========================== ====================== ``KRB5_KPASSWD_SUCCESS`` ``0`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AP_REQ.rst.txt0000664000175000017500000000040315051422642024537 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AP-REQ-data: KRB5_AP_REQ =========== .. .. data:: KRB5_AP_REQ .. Auth req to application server. ================== ====================== ``KRB5_AP_REQ`` ``((krb5_msgtype)14)`` ================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_PK_AS_REP.rst.txt0000664000175000017500000000045115051422642026150 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-PK-AS-REP-data: KRB5_PADATA_PK_AS_REP ===================== .. .. data:: KRB5_PADATA_PK_AS_REP .. PKINIT. RFC 4556 ============================ ====================== ``KRB5_PADATA_PK_AS_REP`` ``17`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE_2.rst.txt0000664000175000017500000000054315051422642026752 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-SAM-CHALLENGE-2-data: KRB5_PADATA_SAM_CHALLENGE_2 =========================== .. .. data:: KRB5_PADATA_SAM_CHALLENGE_2 .. draft challenge system, updated ================================== ====================== ``KRB5_PADATA_SAM_CHALLENGE_2`` ``30`` ================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_ETYPE_INFO2.rst.txt0000664000175000017500000000046115051422642026331 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-ETYPE-INFO2-data: KRB5_PADATA_ETYPE_INFO2 ======================= .. .. data:: KRB5_PADATA_ETYPE_INFO2 .. RFC 4120. ============================== ====================== ``KRB5_PADATA_ETYPE_INFO2`` ``19`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_AFS3_SALT.rst.txt0000664000175000017500000000045715051422642026072 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-AFS3-SALT-data: KRB5_PADATA_AFS3_SALT ===================== .. .. data:: KRB5_PADATA_AFS3_SALT .. Cygnus. RFC 4120, 3961 ============================ ====================== ``KRB5_PADATA_AFS3_SALT`` ``10`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_TICKET_CHECKSUM.rst.txt0000664000175000017500000000047715051422642026473 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-TICKET-CHECKSUM-data: KRB5_PAC_TICKET_CHECKSUM ======================== .. .. data:: KRB5_PAC_TICKET_CHECKSUM .. Ticket checksum. =============================== ====================== ``KRB5_PAC_TICKET_CHECKSUM`` ``16`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_CREDENTIALS_INFO.rst.txt0000664000175000017500000000051515051422642026567 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-CREDENTIALS-INFO-data: KRB5_PAC_CREDENTIALS_INFO ========================= .. .. data:: KRB5_PAC_CREDENTIALS_INFO .. Credentials information. ================================ ====================== ``KRB5_PAC_CREDENTIALS_INFO`` ``2`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_AP_OPTIONS.rst.txt0000664000175000017500000000045715051422642026527 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-AP-OPTIONS-data: KRB5_AUTHDATA_AP_OPTIONS ======================== .. .. data:: KRB5_AUTHDATA_AP_OPTIONS .. =============================== ====================== ``KRB5_AUTHDATA_AP_OPTIONS`` ``143`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_TKT_COMMON_MASK.rst.txt0000664000175000017500000000042315051422642025755 0ustar ghudsonghudson.. highlight:: c .. _KDC-TKT-COMMON-MASK-data: KDC_TKT_COMMON_MASK =================== .. .. data:: KDC_TKT_COMMON_MASK .. ========================== ====================== ``KDC_TKT_COMMON_MASK`` ``0x54800000`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_SAM_USE_SAD_AS_KEY.rst.txt0000664000175000017500000000045715051422642026457 0ustar ghudsonghudson.. highlight:: c .. _KRB5-SAM-USE-SAD-AS-KEY-data: KRB5_SAM_USE_SAD_AS_KEY ======================= .. .. data:: KRB5_SAM_USE_SAD_AS_KEY .. ============================== ====================== ``KRB5_SAM_USE_SAD_AS_KEY`` ``0x80000000`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DES3_CBC_RAW.rst.txt0000664000175000017500000000042615051422642026017 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DES3-CBC-RAW-data: ENCTYPE_DES3_CBC_RAW ==================== .. .. data:: ENCTYPE_DES3_CBC_RAW .. =========================== ====================== ``ENCTYPE_DES3_CBC_RAW`` ``0x0006`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_x.rst.txt0000664000175000017500000000036315051422642024144 0ustar ghudsonghudson.. highlight:: c .. _krb5-x-data: krb5_x ====== .. .. data:: krb5_x .. ======================== ====================== ``krb5_x (ptr, args)`` ``((ptr)?((*(ptr)) args):(abort(),1))`` ======================== ====================== ././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootkrb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW.rst.txtkrb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LO0000664000175000017500000000115715051422642031313 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-PKINIT-FLAGS-TOKEN-USER-PIN-COUNT-LOW-data: KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW ==================================================== .. .. data:: KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW .. This flag indicates that an incorrect PIN was supplied at least once since the last time the correct PIN was supplied. =========================================================== ====================== ``KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW`` ``(1 << 0)`` =========================================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_ATTRIBUTES_INFO.rst.txt0000664000175000017500000000047615051422642026526 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-ATTRIBUTES-INFO-data: KRB5_PAC_ATTRIBUTES_INFO ======================== .. .. data:: KRB5_PAC_ATTRIBUTES_INFO .. PAC attributes. =============================== ====================== ``KRB5_PAC_ATTRIBUTES_INFO`` ``17`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_MIC.rst.txt0000664000175000017500000000046515051422642026676 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-GSS-TOK-MIC-data: KRB5_KEYUSAGE_GSS_TOK_MIC ========================= .. .. data:: KRB5_KEYUSAGE_GSS_TOK_MIC .. ================================ ====================== ``KRB5_KEYUSAGE_GSS_TOK_MIC`` ``22`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_NETBIOS.rst.txt0000664000175000017500000000037215051422642025351 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-NETBIOS-data: ADDRTYPE_NETBIOS ================ .. .. data:: ADDRTYPE_NETBIOS .. ======================= ====================== ``ADDRTYPE_NETBIOS`` ``0x0014`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_XNS.rst.txt0000664000175000017500000000033615051422642024716 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-XNS-data: ADDRTYPE_XNS ============ .. .. data:: ADDRTYPE_XNS .. =================== ====================== ``ADDRTYPE_XNS`` ``0x0006`` =================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_OK_AS_DELEGATE.rst.txt0000664000175000017500000000045015051422642026307 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-OK-AS-DELEGATE-data: TKT_FLG_OK_AS_DELEGATE ====================== .. .. data:: TKT_FLG_OK_AS_DELEGATE .. ============================= ====================== ``TKT_FLG_OK_AS_DELEGATE`` ``0x00040000`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT.rst.txt0000664000175000017500000000061515051422642030616 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-CHG-PWD-PRMPT-data: KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT ===================================== .. .. data:: KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT .. ============================================ ====================== ``KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT`` ``0x0100`` ============================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_SIGNTICKET.rst.txt0000664000175000017500000000045715051422642026460 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-SIGNTICKET-data: KRB5_AUTHDATA_SIGNTICKET ======================== .. .. data:: KRB5_AUTHDATA_SIGNTICKET .. =============================== ====================== ``KRB5_AUTHDATA_SIGNTICKET`` ``512`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_MS_PRINCIPAL.rst.txt0000664000175000017500000000045615051422642026061 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-MS-PRINCIPAL-data: KRB5_NT_MS_PRINCIPAL ==================== .. .. data:: KRB5_NT_MS_PRINCIPAL .. Windows 2000 UPN and SID. =========================== ====================== ``KRB5_NT_MS_PRINCIPAL`` ``-128`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_RENEWABLE_OK.rst.txt0000664000175000017500000000043215051422642026047 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-RENEWABLE-OK-data: KDC_OPT_RENEWABLE_OK ==================== .. .. data:: KDC_OPT_RENEWABLE_OK .. =========================== ====================== ``KDC_OPT_RENEWABLE_OK`` ``0x00000010`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_FX_COOKIE.rst.txt0000664000175000017500000000044415051422642026115 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-FX-COOKIE-data: KRB5_PADATA_FX_COOKIE ===================== .. .. data:: KRB5_PADATA_FX_COOKIE .. RFC 6113. ============================ ====================== ``KRB5_PADATA_FX_COOKIE`` ``133`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_INVALID.rst.txt0000664000175000017500000000036715051422642025256 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-INVALID-data: TKT_FLG_INVALID =============== .. .. data:: TKT_FLG_INVALID .. ====================== ====================== ``TKT_FLG_INVALID`` ``0x01000000`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_QUESTION_PKINIT.rst.txt0000664000175000017500000000176715051422642027514 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-QUESTION-PKINIT-data: KRB5_RESPONDER_QUESTION_PKINIT ============================== .. .. data:: KRB5_RESPONDER_QUESTION_PKINIT .. PKINIT responder question. The PKINIT responder question is asked when the client needs a password that's being used to protect key information, and is formatted as a JSON object. A specific identity's flags value, if not zero, is the bitwise-OR of one or more of the KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_* flags defined below, and possibly other flags to be added later. Any resemblance to similarly-named CKF_* values in the PKCS#11 API should not be depended on. :: { identity : flags , ... } The answer to the question MUST be JSON formatted: :: { identity : password , ... } ===================================== ====================== ``KRB5_RESPONDER_QUESTION_PKINIT`` ``"pkinit"`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR.rst.txt0000664000175000017500000000075315051422642031305 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-GENERATE-LOCAL-FULL-ADDR-data: KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR ========================================== .. .. data:: KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR .. Generate the local network address and the local port. ================================================= ====================== ``KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR`` ``0x00000004`` ================================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_PKINIT_KX.rst.txt0000664000175000017500000000044415051422642026147 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-PKINIT-KX-data: KRB5_PADATA_PKINIT_KX ===================== .. .. data:: KRB5_PADATA_PKINIT_KX .. RFC 6112. ============================ ====================== ``KRB5_PADATA_PKINIT_KX`` ``147`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TGS_NAME.rst.txt0000664000175000017500000000034715051422642024774 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TGS-NAME-data: KRB5_TGS_NAME ============= .. .. data:: KRB5_TGS_NAME .. ==================== ====================== ``KRB5_TGS_NAME`` ``"krbtgt"`` ==================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PROMPT_TYPE_PREAUTH.rst.txt0000664000175000017500000000055015051422642026605 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PROMPT-TYPE-PREAUTH-data: KRB5_PROMPT_TYPE_PREAUTH ======================== .. .. data:: KRB5_PROMPT_TYPE_PREAUTH .. Prompt for preauthentication data (such as an OTP value) =============================== ====================== ``KRB5_PROMPT_TYPE_PREAUTH`` ``0x4`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_ENTERPRISE.rst.txt0000664000175000017500000000060515051422642027763 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-COMPARE-ENTERPRISE-data: KRB5_PRINCIPAL_COMPARE_ENTERPRISE ================================= .. .. data:: KRB5_PRINCIPAL_COMPARE_ENTERPRISE .. UPNs as real principals. ======================================== ====================== ``KRB5_PRINCIPAL_COMPARE_ENTERPRISE`` ``2`` ======================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_roundup.rst.txt0000664000175000017500000000040615051422642025367 0ustar ghudsonghudson.. highlight:: c .. _krb5-roundup-data: krb5_roundup ============ .. .. data:: krb5_roundup .. ========================= ====================== ``krb5_roundup (x, y)`` ``((((x) + (y) - 1)/(y))*(y))`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN.rst.txt0000664000175000017500000000072015051422642030636 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-OTP-FLAGS-COLLECT-TOKEN-data: KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN ====================================== .. .. data:: KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN .. This flag indicates that the token value MUST be collected. ============================================= ====================== ``KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN`` ``0x0001`` ============================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GC_NO_TRANSIT_CHECK.rst.txt0000664000175000017500000000050715051422642026523 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GC-NO-TRANSIT-CHECK-data: KRB5_GC_NO_TRANSIT_CHECK ======================== .. .. data:: KRB5_GC_NO_TRANSIT_CHECK .. Disable transited check. =============================== ====================== ``KRB5_GC_NO_TRANSIT_CHECK`` ``32`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_PA_AS_FRESHNESS.rst.txt0000664000175000017500000000055515051422642027340 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-PA-AS-FRESHNESS-data: KRB5_KEYUSAGE_PA_AS_FRESHNESS ============================= .. .. data:: KRB5_KEYUSAGE_PA_AS_FRESHNESS .. Used for freshness tokens. ==================================== ====================== ``KRB5_KEYUSAGE_PA_AS_FRESHNESS`` ``514`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_USE_SUBKEY.rst.txt0000664000175000017500000000052215051422642027275 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-USE-SUBKEY-data: KRB5_AUTH_CONTEXT_USE_SUBKEY ============================ .. .. data:: KRB5_AUTH_CONTEXT_USE_SUBKEY .. =================================== ====================== ``KRB5_AUTH_CONTEXT_USE_SUBKEY`` ``0x00000020`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_PK_AS_REP_OLD.rst.txt0000664000175000017500000000047515051422642026654 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-PK-AS-REP-OLD-data: KRB5_PADATA_PK_AS_REP_OLD ========================= .. .. data:: KRB5_PADATA_PK_AS_REP_OLD .. PKINIT. ================================ ====================== ``KRB5_PADATA_PK_AS_REP_OLD`` ``15`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CRED.rst.txt0000664000175000017500000000035615051422642024254 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CRED-data: KRB5_CRED ========= .. .. data:: KRB5_CRED .. Cred forwarding message. ================ ====================== ``KRB5_CRED`` ``((krb5_msgtype)22)`` ================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_MATCH_FLAGS_EXACT.rst.txt0000664000175000017500000000053715051422642026622 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-MATCH-FLAGS-EXACT-data: KRB5_TC_MATCH_FLAGS_EXACT ========================= .. .. data:: KRB5_TC_MATCH_FLAGS_EXACT .. All the flags must match exactly. ================================ ====================== ``KRB5_TC_MATCH_FLAGS_EXACT`` ``0x00000010`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY.rst.txt0000664000175000017500000000061015051422642030552 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-TGS-REP-ENCPART-SESSKEY-data: KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY ===================================== .. .. data:: KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY .. ============================================ ====================== ``KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY`` ``8`` ============================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_TRANSIT_POLICY_CHECKED.rst.txt0000664000175000017500000000054015051422642027472 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-TRANSIT-POLICY-CHECKED-data: TKT_FLG_TRANSIT_POLICY_CHECKED ============================== .. .. data:: TKT_FLG_TRANSIT_POLICY_CHECKED .. ===================================== ====================== ``TKT_FLG_TRANSIT_POLICY_CHECKED`` ``0x00080000`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_DIRECTIONAL.rst.txt0000664000175000017500000000042615051422642026003 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-DIRECTIONAL-data: ADDRTYPE_DIRECTIONAL ==================== .. .. data:: ADDRTYPE_DIRECTIONAL .. =========================== ====================== ``ADDRTYPE_DIRECTIONAL`` ``0x0003`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_CAMELLIA128_CTS_CMAC.rst.txt0000664000175000017500000000053015051422642027033 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-CAMELLIA128-CTS-CMAC-data: ENCTYPE_CAMELLIA128_CTS_CMAC ============================ .. .. data:: ENCTYPE_CAMELLIA128_CTS_CMAC .. RFC 6803. =================================== ====================== ``ENCTYPE_CAMELLIA128_CTS_CMAC`` ``0x0019`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG.rst.txt0000664000175000017500000000054615051422642027765 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-GSS-TOK-WRAP-INTEG-data: KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG ================================ .. .. data:: KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG .. ======================================= ====================== ``KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG`` ``23`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT_ISSUED.rst.txt0000664000175000017500000000051415051422642027307 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ONE-LAST-TGT-ISSUED-data: KRB5_LRQ_ONE_LAST_TGT_ISSUED ============================ .. .. data:: KRB5_LRQ_ONE_LAST_TGT_ISSUED .. =================================== ====================== ``KRB5_LRQ_ONE_LAST_TGT_ISSUED`` ``(-3)`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_SHA1_RSA_CMS.rst.txt0000664000175000017500000000046415051422642026046 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-SHA1-RSA-CMS-data: ENCTYPE_SHA1_RSA_CMS ==================== .. .. data:: ENCTYPE_SHA1_RSA_CMS .. SHA1 with RSA, CMS signature. =========================== ====================== ``ENCTYPE_SHA1_RSA_CMS`` ``0x000b`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TGS_REQ.rst.txt0000664000175000017500000000041215051422642024674 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TGS-REQ-data: KRB5_TGS_REQ ============ .. .. data:: KRB5_TGS_REQ .. Ticket granting server request. =================== ====================== ``KRB5_TGS_REQ`` ``((krb5_msgtype)12)`` =================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_IS_LOCAL.rst.txt0000664000175000017500000000045515051422642025475 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-IS-LOCAL-data: ADDRTYPE_IS_LOCAL ================= .. .. data:: ADDRTYPE_IS_LOCAL .. ================================== ====================== ``ADDRTYPE_IS_LOCAL (addrtype)`` ``(addrtype & 0x8000)`` ================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AP_OPTS_ETYPE_NEGOTIATION.rst.txt0000664000175000017500000000047515051422642026731 0ustar ghudsonghudson.. highlight:: c .. _AP-OPTS-ETYPE-NEGOTIATION-data: AP_OPTS_ETYPE_NEGOTIATION ========================= .. .. data:: AP_OPTS_ETYPE_NEGOTIATION .. ================================ ====================== ``AP_OPTS_ETYPE_NEGOTIATION`` ``0x00000002`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_INT16_MAX.rst.txt0000664000175000017500000000035315051422642025042 0ustar ghudsonghudson.. highlight:: c .. _KRB5-INT16-MAX-data: KRB5_INT16_MAX ============== .. .. data:: KRB5_INT16_MAX .. ===================== ====================== ``KRB5_INT16_MAX`` ``65535`` ===================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_WELLKNOWN_NAMESTR.rst.txt0000664000175000017500000000052515051422642026306 0ustar ghudsonghudson.. highlight:: c .. _KRB5-WELLKNOWN-NAMESTR-data: KRB5_WELLKNOWN_NAMESTR ====================== .. .. data:: KRB5_WELLKNOWN_NAMESTR .. First component of NT_WELLKNOWN principals. ============================= ====================== ``KRB5_WELLKNOWN_NAMESTR`` ``"WELLKNOWN"`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_princ_set_realm_length.rst.txt0000664000175000017500000000064615051422642030410 0ustar ghudsonghudson.. highlight:: c .. _krb5-princ-set-realm-length-data: krb5_princ_set_realm_length =========================== .. .. data:: krb5_princ_set_realm_length .. ========================================================= ====================== ``krb5_princ_set_realm_length (context, princ, value)`` ``(princ)->realm.length = (value)`` ========================================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_NIST_SHA.rst.txt0000664000175000017500000000041015051422642025657 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-NIST-SHA-data: CKSUMTYPE_NIST_SHA ================== .. .. data:: CKSUMTYPE_NIST_SHA .. ========================= ====================== ``CKSUMTYPE_NIST_SHA`` ``0x0009`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_RENEWABLE.rst.txt0000664000175000017500000000040515051422642025465 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-RENEWABLE-data: TKT_FLG_RENEWABLE ================= .. .. data:: TKT_FLG_RENEWABLE .. ======================== ====================== ``TKT_FLG_RENEWABLE`` ``0x00800000`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_PK_AS_REQ_OLD.rst.txt0000664000175000017500000000047515051422642026655 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-PK-AS-REQ-OLD-data: KRB5_PADATA_PK_AS_REQ_OLD ========================= .. .. data:: KRB5_PADATA_PK_AS_REQ_OLD .. PKINIT. ================================ ====================== ``KRB5_PADATA_PK_AS_REQ_OLD`` ``14`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/VALID_INT_BITS.rst.txt0000664000175000017500000000035515051422642025145 0ustar ghudsonghudson.. highlight:: c .. _VALID-INT-BITS-data: VALID_INT_BITS ============== .. .. data:: VALID_INT_BITS .. ===================== ====================== ``VALID_INT_BITS`` ``INT_MAX`` ===================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CRYPTO_TYPE_HEADER.rst.txt0000664000175000017500000000046315051422642026427 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CRYPTO-TYPE-HEADER-data: KRB5_CRYPTO_TYPE_HEADER ======================= .. .. data:: KRB5_CRYPTO_TYPE_HEADER .. [out] header ============================== ====================== ``KRB5_CRYPTO_TYPE_HEADER`` ``1`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_RENEWABLE.rst.txt0000664000175000017500000000040515051422642025456 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-RENEWABLE-data: KDC_OPT_RENEWABLE ================= .. .. data:: KDC_OPT_RENEWABLE .. ======================== ====================== ``KDC_OPT_RENEWABLE`` ``0x00800000`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_ENT_PRINCIPAL_AND_ID.rst.txt0000664000175000017500000000054515051422642027225 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-ENT-PRINCIPAL-AND-ID-data: KRB5_NT_ENT_PRINCIPAL_AND_ID ============================ .. .. data:: KRB5_NT_ENT_PRINCIPAL_AND_ID .. NT 4 style name and SID. =================================== ====================== ``KRB5_NT_ENT_PRINCIPAL_AND_ID`` ``-130`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_NEXTOTP.rst.txt0000664000175000017500000000101015051422642027743 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-OTP-FLAGS-NEXTOTP-data: KRB5_RESPONDER_OTP_FLAGS_NEXTOTP ================================ .. .. data:: KRB5_RESPONDER_OTP_FLAGS_NEXTOTP .. This flag indicates that the token is now in re-synchronization mode with the server. The user is expected to reply with the next code displayed on the token. ======================================= ====================== ``KRB5_RESPONDER_OTP_FLAGS_NEXTOTP`` ``0x0004`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DES3_CBC_ENV.rst.txt0000664000175000017500000000047215051422642026017 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DES3-CBC-ENV-data: ENCTYPE_DES3_CBC_ENV ==================== .. .. data:: ENCTYPE_DES3_CBC_ENV .. DES-3 cbc mode, CMS enveloped data. =========================== ====================== ``ENCTYPE_DES3_CBC_ENV`` ``0x000f`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_QUESTION_OTP.rst.txt0000664000175000017500000000217315051422642027150 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-QUESTION-OTP-data: KRB5_RESPONDER_QUESTION_OTP =========================== .. .. data:: KRB5_RESPONDER_QUESTION_OTP .. OTP responder question. The OTP responder question is asked when the KDC indicates that an OTP value is required in order to complete the authentication. The JSON format of the challenge is: :: { "service": , "tokenInfo": [ { "flags": , "vendor": , "challenge": , "length": , "format": , "tokenID": , "algID": , }, ... ] } The answer to the question MUST be JSON formatted: :: { "tokeninfo": , "value": , "pin": , } For more detail, please see RFC 6560. ================================== ====================== ``KRB5_RESPONDER_QUESTION_OTP`` ``"otp"`` ================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PROXIABLE.rst.txt0000664000175000017500000000056115051422642030046 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-PROXIABLE-data: KRB5_GET_INIT_CREDS_OPT_PROXIABLE ================================= .. .. data:: KRB5_GET_INIT_CREDS_OPT_PROXIABLE .. ======================================== ====================== ``KRB5_GET_INIT_CREDS_OPT_PROXIABLE`` ``0x0008`` ======================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AP_OPTS_MUTUAL_REQUIRED.rst.txt0000664000175000017500000000053115051422642026503 0ustar ghudsonghudson.. highlight:: c .. _AP-OPTS-MUTUAL-REQUIRED-data: AP_OPTS_MUTUAL_REQUIRED ======================= .. .. data:: AP_OPTS_MUTUAL_REQUIRED .. Perform a mutual authentication exchange. ============================== ====================== ``AP_OPTS_MUTUAL_REQUIRED`` ``0x20000000`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RECVAUTH_BADAUTHVERS.rst.txt0000664000175000017500000000047115051422642026606 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RECVAUTH-BADAUTHVERS-data: KRB5_RECVAUTH_BADAUTHVERS ========================= .. .. data:: KRB5_RECVAUTH_BADAUTHVERS .. ================================ ====================== ``KRB5_RECVAUTH_BADAUTHVERS`` ``0x0002`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_ENCRYPTED_CHALLENGE.rst.txt0000664000175000017500000000055215051422642027446 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-ENCRYPTED-CHALLENGE-data: KRB5_PADATA_ENCRYPTED_CHALLENGE =============================== .. .. data:: KRB5_PADATA_ENCRYPTED_CHALLENGE .. RFC 6113. ====================================== ====================== ``KRB5_PADATA_ENCRYPTED_CHALLENGE`` ``138`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_REALM.rst.txt0000664000175000017500000000055515051422642027327 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-PARSE-NO-REALM-data: KRB5_PRINCIPAL_PARSE_NO_REALM ============================= .. .. data:: KRB5_PRINCIPAL_PARSE_NO_REALM .. Error if realm is present. ==================================== ====================== ``KRB5_PRINCIPAL_PARSE_NO_REALM`` ``0x1`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_RSA_MD4.rst.txt0000664000175000017500000000040115051422642025500 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-RSA-MD4-data: CKSUMTYPE_RSA_MD4 ================= .. .. data:: CKSUMTYPE_RSA_MD4 .. ======================== ====================== ``CKSUMTYPE_RSA_MD4`` ``0x0002`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_UTF8.rst.txt0000664000175000017500000000053415051422642027032 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-COMPARE-UTF8-data: KRB5_PRINCIPAL_COMPARE_UTF8 =========================== .. .. data:: KRB5_PRINCIPAL_COMPARE_UTF8 .. treat principals as UTF-8 ================================== ====================== ``KRB5_PRINCIPAL_COMPARE_UTF8`` ``8`` ================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CRYPTO_TYPE_SIGN_ONLY.rst.txt0000664000175000017500000000052015051422642027072 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CRYPTO-TYPE-SIGN-ONLY-data: KRB5_CRYPTO_TYPE_SIGN_ONLY ========================== .. .. data:: KRB5_CRYPTO_TYPE_SIGN_ONLY .. [in] associated data ================================= ====================== ``KRB5_CRYPTO_TYPE_SIGN_ONLY`` ``3`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_DES3.rst.txt0000664000175000017500000000046215051422642026460 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-HMAC-SHA1-DES3-data: CKSUMTYPE_HMAC_SHA1_DES3 ======================== .. .. data:: CKSUMTYPE_HMAC_SHA1_DES3 .. =============================== ====================== ``CKSUMTYPE_HMAC_SHA1_DES3`` ``0x000c`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_PAC_REQUEST.rst.txt0000664000175000017500000000047415051422642026365 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-PAC-REQUEST-data: KRB5_PADATA_PAC_REQUEST ======================= .. .. data:: KRB5_PADATA_PAC_REQUEST .. include Windows PAC ============================== ====================== ``KRB5_PADATA_PAC_REQUEST`` ``128`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KPASSWD_SOFTERROR.rst.txt0000664000175000017500000000047115051422642026316 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KPASSWD-SOFTERROR-data: KRB5_KPASSWD_SOFTERROR ====================== .. .. data:: KRB5_KPASSWD_SOFTERROR .. Password change rejected. ============================= ====================== ``KRB5_KPASSWD_SOFTERROR`` ``4`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_X500_PRINCIPAL.rst.txt0000664000175000017500000000044715051422642026176 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-X500-PRINCIPAL-data: KRB5_NT_X500_PRINCIPAL ====================== .. .. data:: KRB5_NT_X500_PRINCIPAL .. PKINIT. ============================= ====================== ``KRB5_NT_X500_PRINCIPAL`` ``6`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AP_OPTS_WIRE_MASK.rst.txt0000664000175000017500000000040515051422642025555 0ustar ghudsonghudson.. highlight:: c .. _AP-OPTS-WIRE-MASK-data: AP_OPTS_WIRE_MASK ================= .. .. data:: AP_OPTS_WIRE_MASK .. ======================== ====================== ``AP_OPTS_WIRE_MASK`` ``0xfffffff0`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_PW_SALT.rst.txt0000664000175000017500000000042415051422642025716 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-PW-SALT-data: KRB5_PADATA_PW_SALT =================== .. .. data:: KRB5_PADATA_PW_SALT .. RFC 4120. ========================== ====================== ``KRB5_PADATA_PW_SALT`` ``3`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR.rst.txt0000664000175000017500000000066515051422642030465 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-GENERATE-LOCAL-ADDR-data: KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR ===================================== .. .. data:: KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR .. Generate the local network address. ============================================ ====================== ``KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR`` ``0x00000001`` ============================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_DECIMAL.rst.txt0000664000175000017500000000065315051422642030010 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-OTP-FORMAT-DECIMAL-data: KRB5_RESPONDER_OTP_FORMAT_DECIMAL ================================= .. .. data:: KRB5_RESPONDER_OTP_FORMAT_DECIMAL .. These format constants identify the format of the token value. ======================================== ====================== ``KRB5_RESPONDER_OTP_FORMAT_DECIMAL`` ``0`` ======================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/MSEC_DIRBIT.rst.txt0000664000175000017500000000032715051422642024536 0ustar ghudsonghudson.. highlight:: c .. _MSEC-DIRBIT-data: MSEC_DIRBIT =========== .. .. data:: MSEC_DIRBIT .. ================== ====================== ``MSEC_DIRBIT`` ``0x8000`` ================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV.rst.txt0000664000175000017500000000053715051422642027677 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-GSS-TOK-WRAP-PRIV-data: KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV =============================== .. .. data:: KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV .. ====================================== ====================== ``KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV`` ``24`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CRYPTO_TYPE_PADDING.rst.txt0000664000175000017500000000047315051422642026546 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CRYPTO-TYPE-PADDING-data: KRB5_CRYPTO_TYPE_PADDING ======================== .. .. data:: KRB5_CRYPTO_TYPE_PADDING .. [out] padding =============================== ====================== ``KRB5_CRYPTO_TYPE_PADDING`` ``4`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_SRV_XHST.rst.txt0000664000175000017500000000044015051422642025452 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-SRV-XHST-data: KRB5_NT_SRV_XHST ================ .. .. data:: KRB5_NT_SRV_XHST .. Service with host as remaining components. ======================= ====================== ``KRB5_NT_SRV_XHST`` ``4`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_POSTDATED.rst.txt0000664000175000017500000000040515051422642025510 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-POSTDATED-data: TKT_FLG_POSTDATED ================= .. .. data:: TKT_FLG_POSTDATED .. ======================== ====================== ``TKT_FLG_POSTDATED`` ``0x02000000`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_TKT_LIFE.rst.txt0000664000175000017500000000055215051422642027762 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-TKT-LIFE-data: KRB5_GET_INIT_CREDS_OPT_TKT_LIFE ================================ .. .. data:: KRB5_GET_INIT_CREDS_OPT_TKT_LIFE .. ======================================= ====================== ``KRB5_GET_INIT_CREDS_OPT_TKT_LIFE`` ``0x0001`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_CKSUM.rst.txt0000664000175000017500000000051215051422642027201 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-APP-DATA-CKSUM-data: KRB5_KEYUSAGE_APP_DATA_CKSUM ============================ .. .. data:: KRB5_KEYUSAGE_APP_DATA_CKSUM .. =================================== ====================== ``KRB5_KEYUSAGE_APP_DATA_CKSUM`` ``17`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM.rst.txt0000664000175000017500000000053715051422642027627 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AP-REQ-AUTH-CKSUM-data: KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM =============================== .. .. data:: KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM .. ====================================== ====================== ``KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM`` ``10`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_OPENCLOSE.rst.txt0000664000175000017500000000046715051422642025457 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-OPENCLOSE-data: KRB5_TC_OPENCLOSE ================= .. .. data:: KRB5_TC_OPENCLOSE .. Open and close the file for each cache operation. ======================== ====================== ``KRB5_TC_OPENCLOSE`` ``0x00000001`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_SMTP_NAME.rst.txt0000664000175000017500000000043515051422642025521 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-SMTP-NAME-data: KRB5_NT_SMTP_NAME ================= .. .. data:: KRB5_NT_SMTP_NAME .. Name in form of SMTP email name. ======================== ====================== ``KRB5_NT_SMTP_NAME`` ``7`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_CLIENT_CLAIMS.rst.txt0000664000175000017500000000047315051422642026230 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-CLIENT-CLAIMS-data: KRB5_PAC_CLIENT_CLAIMS ====================== .. .. data:: KRB5_PAC_CLIENT_CLAIMS .. Client claims information. ============================= ====================== ``KRB5_PAC_CLIENT_CLAIMS`` ``13`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb524_init_ets.rst.txt0000664000175000017500000000037215051422642025661 0ustar ghudsonghudson.. highlight:: c .. _krb524-init-ets-data: krb524_init_ets =============== .. .. data:: krb524_init_ets .. ========================= ====================== ``krb524_init_ets (x)`` ``(0)`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_REQUESTOR.rst.txt0000664000175000017500000000042715051422642025612 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-REQUESTOR-data: KRB5_PAC_REQUESTOR ================== .. .. data:: KRB5_PAC_REQUESTOR .. PAC requestor SID. ========================= ====================== ``KRB5_PAC_REQUESTOR`` ``18`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_OTP_PIN_CHANGE.rst.txt0000664000175000017500000000052315051422642026722 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-OTP-PIN-CHANGE-data: KRB5_PADATA_OTP_PIN_CHANGE ========================== .. .. data:: KRB5_PADATA_OTP_PIN_CHANGE .. RFC 6560 section 4.3. ================================= ====================== ``KRB5_PADATA_OTP_PIN_CHANGE`` ``144`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_FINISHED.rst.txt0000664000175000017500000000044015051422642026217 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-FINISHED-data: KRB5_KEYUSAGE_FINISHED ====================== .. .. data:: KRB5_KEYUSAGE_FINISHED .. ============================= ====================== ``KRB5_KEYUSAGE_FINISHED`` ``41`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_SEQUENCE.rst.txt0000664000175000017500000000060715051422642027505 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-RET-SEQUENCE-data: KRB5_AUTH_CONTEXT_RET_SEQUENCE ============================== .. .. data:: KRB5_AUTH_CONTEXT_RET_SEQUENCE .. Save sequence numbers for application. ===================================== ====================== ``KRB5_AUTH_CONTEXT_RET_SEQUENCE`` ``0x00000008`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_WIN2K_PAC.rst.txt0000664000175000017500000000045015051422642026322 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-WIN2K-PAC-data: KRB5_AUTHDATA_WIN2K_PAC ======================= .. .. data:: KRB5_AUTHDATA_WIN2K_PAC .. ============================== ====================== ``KRB5_AUTHDATA_WIN2K_PAC`` ``128`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ANONYMOUS.rst.txt0000664000175000017500000000056115051422642030111 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-ANONYMOUS-data: KRB5_GET_INIT_CREDS_OPT_ANONYMOUS ================================= .. .. data:: KRB5_GET_INIT_CREDS_OPT_ANONYMOUS .. ======================================== ====================== ``KRB5_GET_INIT_CREDS_OPT_ANONYMOUS`` ``0x0400`` ======================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_AS_CHECKSUM.rst.txt0000664000175000017500000000046515051422642026337 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-AS-CHECKSUM-data: KRB5_PADATA_AS_CHECKSUM ======================= .. .. data:: KRB5_PADATA_AS_CHECKSUM .. AS checksum. ============================== ====================== ``KRB5_PADATA_AS_CHECKSUM`` ``132`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ALL_ACCT_EXPTIME.rst.txt0000664000175000017500000000046415051422642026652 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ALL-ACCT-EXPTIME-data: KRB5_LRQ_ALL_ACCT_EXPTIME ========================= .. .. data:: KRB5_LRQ_ALL_ACCT_EXPTIME .. ================================ ====================== ``KRB5_LRQ_ALL_ACCT_EXPTIME`` ``7`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_FORWARDED.rst.txt0000664000175000017500000000040515051422642025467 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-FORWARDED-data: KDC_OPT_FORWARDED ================= .. .. data:: KDC_OPT_FORWARDED .. ======================== ====================== ``KDC_OPT_FORWARDED`` ``0x20000000`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_OSF_DCE.rst.txt0000664000175000017500000000043315051422642025647 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-OSF-DCE-data: KRB5_PADATA_OSF_DCE =================== .. .. data:: KRB5_PADATA_OSF_DCE .. OSF DCE. RFC 4120 ========================== ====================== ``KRB5_PADATA_OSF_DCE`` ``8`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CANONICALIZE.rst.txt0000664000175000017500000000060615051422642030360 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-CANONICALIZE-data: KRB5_GET_INIT_CREDS_OPT_CANONICALIZE ==================================== .. .. data:: KRB5_GET_INIT_CREDS_OPT_CANONICALIZE .. =========================================== ====================== ``KRB5_GET_INIT_CREDS_OPT_CANONICALIZE`` ``0x0200`` =========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_SPAKE.rst.txt0000664000175000017500000000037615051422642025416 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-SPAKE-data: KRB5_PADATA_SPAKE ================= .. .. data:: KRB5_PADATA_SPAKE .. ======================== ====================== ``KRB5_PADATA_SPAKE`` ``151`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_MS_PRINCIPAL_AND_ID.rst.txt0000664000175000017500000000052615051422642027115 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-MS-PRINCIPAL-AND-ID-data: KRB5_NT_MS_PRINCIPAL_AND_ID =========================== .. .. data:: KRB5_NT_MS_PRINCIPAL_AND_ID .. NT 4 style name. ================================== ====================== ``KRB5_NT_MS_PRINCIPAL_AND_ID`` ``-129`` ================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AP_OPTS_USE_SESSION_KEY.rst.txt0000664000175000017500000000050015051422642026537 0ustar ghudsonghudson.. highlight:: c .. _AP-OPTS-USE-SESSION-KEY-data: AP_OPTS_USE_SESSION_KEY ======================= .. .. data:: AP_OPTS_USE_SESSION_KEY .. Use session key. ============================== ====================== ``AP_OPTS_USE_SESSION_KEY`` ``0x40000000`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY.rst.txt0000664000175000017500000000054515051422642027752 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-TGS-REQ-AD-SESSKEY-data: KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY ================================ .. .. data:: KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY .. ======================================= ====================== ``KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY`` ``4`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_SERVER_CHECKSUM.rst.txt0000664000175000017500000000047615051422642026515 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-SERVER-CHECKSUM-data: KRB5_PAC_SERVER_CHECKSUM ======================== .. .. data:: KRB5_PAC_SERVER_CHECKSUM .. Server checksum. =============================== ====================== ``KRB5_PAC_SERVER_CHECKSUM`` ``6`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_CAMELLIA256_CTS_CMAC.rst.txt0000664000175000017500000000053015051422642027035 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-CAMELLIA256-CTS-CMAC-data: ENCTYPE_CAMELLIA256_CTS_CMAC ============================ .. .. data:: ENCTYPE_CAMELLIA256_CTS_CMAC .. RFC 6803. =================================== ====================== ``ENCTYPE_CAMELLIA256_CTS_CMAC`` ``0x001a`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_IF_RELEVANT.rst.txt0000664000175000017500000000046415051422642026610 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-IF-RELEVANT-data: KRB5_AUTHDATA_IF_RELEVANT ========================= .. .. data:: KRB5_AUTHDATA_IF_RELEVANT .. ================================ ====================== ``KRB5_AUTHDATA_IF_RELEVANT`` ``1`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DES3_CBC_SHA.rst.txt0000664000175000017500000000042615051422642026001 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DES3-CBC-SHA-data: ENCTYPE_DES3_CBC_SHA ==================== .. .. data:: ENCTYPE_DES3_CBC_SHA .. =========================== ====================== ``ENCTYPE_DES3_CBC_SHA`` ``0x0005`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_CASEFOLD.rst.txt0000664000175000017500000000055715051422642027471 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-COMPARE-CASEFOLD-data: KRB5_PRINCIPAL_COMPARE_CASEFOLD =============================== .. .. data:: KRB5_PRINCIPAL_COMPARE_CASEFOLD .. case-insensitive ====================================== ====================== ``KRB5_PRINCIPAL_COMPARE_CASEFOLD`` ``4`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_SAM_REDIRECT.rst.txt0000664000175000017500000000047715051422642026456 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-SAM-REDIRECT-data: KRB5_PADATA_SAM_REDIRECT ======================== .. .. data:: KRB5_PADATA_SAM_REDIRECT .. SAM/OTP. RFC 4120 =============================== ====================== ``KRB5_PADATA_SAM_REDIRECT`` ``21`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CRYPTO_TYPE_EMPTY.rst.txt0000664000175000017500000000045415051422642026375 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CRYPTO-TYPE-EMPTY-data: KRB5_CRYPTO_TYPE_EMPTY ====================== .. .. data:: KRB5_CRYPTO_TYPE_EMPTY .. [in] ignored ============================= ====================== ``KRB5_CRYPTO_TYPE_EMPTY`` ``0`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AD_MTE.rst.txt0000664000175000017500000000042215051422642026017 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AD-MTE-data: KRB5_KEYUSAGE_AD_MTE ==================== .. .. data:: KRB5_KEYUSAGE_AD_MTE .. =========================== ====================== ``KRB5_KEYUSAGE_AD_MTE`` ``20`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TGS_NAME_SIZE.rst.txt0000664000175000017500000000040315051422642025617 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TGS-NAME-SIZE-data: KRB5_TGS_NAME_SIZE ================== .. .. data:: KRB5_TGS_NAME_SIZE .. ========================= ====================== ``KRB5_TGS_NAME_SIZE`` ``6`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_PAC_OPTIONS.rst.txt0000664000175000017500000000047415051422642026370 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-PAC-OPTIONS-data: KRB5_PADATA_PAC_OPTIONS ======================= .. .. data:: KRB5_PADATA_PAC_OPTIONS .. MS-KILE and MS-SFU. ============================== ====================== ``KRB5_PADATA_PAC_OPTIONS`` ``167`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_AP_REQ.rst.txt0000664000175000017500000000040315051422642025551 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-AP-REQ-data: KRB5_PADATA_AP_REQ ================== .. .. data:: KRB5_PADATA_AP_REQ .. ========================= ====================== ``KRB5_PADATA_AP_REQ`` ``1`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TGS_REP.rst.txt0000664000175000017500000000040315051422642024673 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TGS-REP-data: KRB5_TGS_REP ============ .. .. data:: KRB5_TGS_REP .. Response to TGS request. =================== ====================== ``KRB5_TGS_REP`` ``((krb5_msgtype)13)`` =================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA384_192.rst.txt0000664000175000017500000000060215051422642027630 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-AES256-CTS-HMAC-SHA384-192-data: ENCTYPE_AES256_CTS_HMAC_SHA384_192 ================================== .. .. data:: ENCTYPE_AES256_CTS_HMAC_SHA384_192 .. RFC 8009. ========================================= ====================== ``ENCTYPE_AES256_CTS_HMAC_SHA384_192`` ``0x0014`` ========================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_MATCH_2ND_TKT.rst.txt0000664000175000017500000000047715051422642026152 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-MATCH-2ND-TKT-data: KRB5_TC_MATCH_2ND_TKT ===================== .. .. data:: KRB5_TC_MATCH_2ND_TKT .. The second ticket must match. ============================ ====================== ``KRB5_TC_MATCH_2ND_TKT`` ``0x00000080`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_FOR_USER.rst.txt0000664000175000017500000000047015051422642026032 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-FOR-USER-data: KRB5_PADATA_FOR_USER ==================== .. .. data:: KRB5_PADATA_FOR_USER .. username protocol transition request =========================== ====================== ``KRB5_PADATA_FOR_USER`` ``129`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_NONE.rst.txt0000664000175000017500000000034015051422642025005 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-NONE-data: KRB5_LRQ_NONE ============= .. .. data:: KRB5_LRQ_NONE .. ==================== ====================== ``KRB5_LRQ_NONE`` ``0`` ==================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AD_TYPE_REGISTERED.rst.txt0000664000175000017500000000041015051422642025605 0ustar ghudsonghudson.. highlight:: c .. _AD-TYPE-REGISTERED-data: AD_TYPE_REGISTERED ================== .. .. data:: AD_TYPE_REGISTERED .. ========================= ====================== ``AD_TYPE_REGISTERED`` ``0x2000`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AP_OPTS_RESERVED.rst.txt0000664000175000017500000000037615051422642025422 0ustar ghudsonghudson.. highlight:: c .. _AP-OPTS-RESERVED-data: AP_OPTS_RESERVED ================ .. .. data:: AP_OPTS_RESERVED .. ======================= ====================== ``AP_OPTS_RESERVED`` ``0x80000000`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_DOMAIN_X500_COMPRESS.rst.txt0000664000175000017500000000051615051422642026533 0ustar ghudsonghudson.. highlight:: c .. _KRB5-DOMAIN-X500-COMPRESS-data: KRB5_DOMAIN_X500_COMPRESS ========================= .. .. data:: KRB5_DOMAIN_X500_COMPRESS .. Transited encoding types. ================================ ====================== ``KRB5_DOMAIN_X500_COMPRESS`` ``1`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_IAKERB_FINISHED.rst.txt0000664000175000017500000000052115051422642027234 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-IAKERB-FINISHED-data: KRB5_KEYUSAGE_IAKERB_FINISHED ============================= .. .. data:: KRB5_KEYUSAGE_IAKERB_FINISHED .. ==================================== ====================== ``KRB5_KEYUSAGE_IAKERB_FINISHED`` ``42`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_FAST_FINISHED.rst.txt0000664000175000017500000000050315051422642027034 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-FAST-FINISHED-data: KRB5_KEYUSAGE_FAST_FINISHED =========================== .. .. data:: KRB5_KEYUSAGE_FAST_FINISHED .. ================================== ====================== ``KRB5_KEYUSAGE_FAST_FINISHED`` ``53`` ================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_NONE.rst.txt0000664000175000017500000000036515051422642025310 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-NONE-data: KRB5_PADATA_NONE ================ .. .. data:: KRB5_PADATA_NONE .. ======================= ====================== ``KRB5_PADATA_NONE`` ``0`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_ENTERPRISE.rst.txt0000664000175000017500000000061615051422642027551 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-PARSE-ENTERPRISE-data: KRB5_PRINCIPAL_PARSE_ENTERPRISE =============================== .. .. data:: KRB5_PRINCIPAL_PARSE_ENTERPRISE .. Create single-component enterprise principle. ====================================== ====================== ``KRB5_PRINCIPAL_PARSE_ENTERPRISE`` ``0x4`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_ALLOW_POSTDATE.rst.txt0000664000175000017500000000045015051422642026333 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-ALLOW-POSTDATE-data: KDC_OPT_ALLOW_POSTDATE ====================== .. .. data:: KDC_OPT_ALLOW_POSTDATE .. ============================= ====================== ``KDC_OPT_ALLOW_POSTDATE`` ``0x04000000`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GC_NO_STORE.rst.txt0000664000175000017500000000042715051422642025377 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GC-NO-STORE-data: KRB5_GC_NO_STORE ================ .. .. data:: KRB5_GC_NO_STORE .. Do not store in credential cache. ======================= ====================== ``KRB5_GC_NO_STORE`` ``8`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_VALIDATE.rst.txt0000664000175000017500000000037615051422642025352 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-VALIDATE-data: KDC_OPT_VALIDATE ================ .. .. data:: KDC_OPT_VALIDATE .. ======================= ====================== ``KDC_OPT_VALIDATE`` ``0x00000001`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_INIT_CREDS_STEP_FLAG_CONTINUE.rst.txt0000664000175000017500000000061415051422642030147 0ustar ghudsonghudson.. highlight:: c .. _KRB5-INIT-CREDS-STEP-FLAG-CONTINUE-data: KRB5_INIT_CREDS_STEP_FLAG_CONTINUE ================================== .. .. data:: KRB5_INIT_CREDS_STEP_FLAG_CONTINUE .. More responses needed. ========================================= ====================== ``KRB5_INIT_CREDS_STEP_FLAG_CONTINUE`` ``0x1`` ========================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC.rst.txt0000664000175000017500000000061715051422642030622 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-OTP-FORMAT-ALPHANUMERIC-data: KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC ====================================== .. .. data:: KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC .. ============================================= ====================== ``KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC`` ``2`` ============================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_MD5_HMAC_ARCFOUR.rst.txt0000664000175000017500000000052715051422642026756 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-MD5-HMAC-ARCFOUR-data: CKSUMTYPE_MD5_HMAC_ARCFOUR ========================== .. .. data:: CKSUMTYPE_MD5_HMAC_ARCFOUR .. ================================= ====================== ``CKSUMTYPE_MD5_HMAC_ARCFOUR`` ``-137 /* Microsoft netlogon */`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/MAX_KEYTAB_NAME_LEN.rst.txt0000664000175000017500000000046615051422642025740 0ustar ghudsonghudson.. highlight:: c .. _MAX-KEYTAB-NAME-LEN-data: MAX_KEYTAB_NAME_LEN =================== .. .. data:: MAX_KEYTAB_NAME_LEN .. Long enough for MAXPATHLEN + some extra. ========================== ====================== ``MAX_KEYTAB_NAME_LEN`` ``1100`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_SESAME.rst.txt0000664000175000017500000000042215051422642025761 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-SESAME-data: KRB5_AUTHDATA_SESAME ==================== .. .. data:: KRB5_AUTHDATA_SESAME .. =========================== ====================== ``KRB5_AUTHDATA_SESAME`` ``65`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_PERMIT_ALL.rst.txt0000664000175000017500000000052215051422642027247 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-PERMIT-ALL-data: KRB5_AUTH_CONTEXT_PERMIT_ALL ============================ .. .. data:: KRB5_AUTH_CONTEXT_PERMIT_ALL .. =================================== ====================== ``KRB5_AUTH_CONTEXT_PERMIT_ALL`` ``0x00000010`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY.rst.txt0000664000175000017500000000060215051422642030357 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-PA-S4U-X509-USER-REPLY-data: KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY ==================================== .. .. data:: KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY .. =========================================== ====================== ``KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY`` ``27`` =========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/SALT_TYPE_NO_LENGTH.rst.txt0000664000175000017500000000042115051422642026006 0ustar ghudsonghudson.. highlight:: c .. _SALT-TYPE-NO-LENGTH-data: SALT_TYPE_NO_LENGTH =================== .. .. data:: SALT_TYPE_NO_LENGTH .. ========================== ====================== ``SALT_TYPE_NO_LENGTH`` ``UINT_MAX`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AP_OPTS_CBT_FLAG.rst.txt0000664000175000017500000000044015051422642025374 0ustar ghudsonghudson.. highlight:: c .. _AP-OPTS-CBT-FLAG-data: AP_OPTS_CBT_FLAG ================ .. .. data:: AP_OPTS_CBT_FLAG .. ======================= ====================== ``AP_OPTS_CBT_FLAG`` ``0x00000004 /* include KERB_AP_OPTIONS_CBT */`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TKT_CREDS_STEP_FLAG_CONTINUE.rst.txt0000664000175000017500000000060515051422642030046 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TKT-CREDS-STEP-FLAG-CONTINUE-data: KRB5_TKT_CREDS_STEP_FLAG_CONTINUE ================================= .. .. data:: KRB5_TKT_CREDS_STEP_FLAG_CONTINUE .. More responses needed. ======================================== ====================== ``KRB5_TKT_CREDS_STEP_FLAG_CONTINUE`` ``0x1`` ======================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DES_CBC_RAW.rst.txt0000664000175000017500000000041715051422642025734 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DES-CBC-RAW-data: ENCTYPE_DES_CBC_RAW =================== .. .. data:: ENCTYPE_DES_CBC_RAW .. ========================== ====================== ``ENCTYPE_DES_CBC_RAW`` ``0x0004`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL.rst.txt0000664000175000017500000000061015051422642030447 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-OTP-FORMAT-HEXADECIMAL-data: KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL ===================================== .. .. data:: KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL .. ============================================ ====================== ``KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL`` ``1`` ============================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KPASSWD_BAD_VERSION.rst.txt0000664000175000017500000000050215051422642026517 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KPASSWD-BAD-VERSION-data: KRB5_KPASSWD_BAD_VERSION ======================== .. .. data:: KRB5_KPASSWD_BAD_VERSION .. Unknown RPC version. =============================== ====================== ``KRB5_KPASSWD_BAD_VERSION`` ``6`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_ENCRYPT.rst.txt0000664000175000017500000000053015051422642027443 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-APP-DATA-ENCRYPT-data: KRB5_KEYUSAGE_APP_DATA_ENCRYPT ============================== .. .. data:: KRB5_KEYUSAGE_APP_DATA_ENCRYPT .. ===================================== ====================== ``KRB5_KEYUSAGE_APP_DATA_ENCRYPT`` ``16`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_MAY_POSTDATE.rst.txt0000664000175000017500000000043215051422642026112 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-MAY-POSTDATE-data: TKT_FLG_MAY_POSTDATE ==================== .. .. data:: TKT_FLG_MAY_POSTDATE .. =========================== ====================== ``TKT_FLG_MAY_POSTDATE`` ``0x04000000`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_S4U_X509_USER.rst.txt0000664000175000017500000000053615051422642026547 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-S4U-X509-USER-data: KRB5_PADATA_S4U_X509_USER ========================= .. .. data:: KRB5_PADATA_S4U_X509_USER .. certificate protocol transition request ================================ ====================== ``KRB5_PADATA_S4U_X509_USER`` ``130`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_PRIVSVR_CHECKSUM.rst.txt0000664000175000017500000000050215051422642026650 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-PRIVSVR-CHECKSUM-data: KRB5_PAC_PRIVSVR_CHECKSUM ========================= .. .. data:: KRB5_PAC_PRIVSVR_CHECKSUM .. KDC checksum. ================================ ====================== ``KRB5_PAC_PRIVSVR_CHECKSUM`` ``7`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_WELLKNOWN.rst.txt0000664000175000017500000000043515051422642025516 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-WELLKNOWN-data: KRB5_NT_WELLKNOWN ================= .. .. data:: KRB5_NT_WELLKNOWN .. Well-known (special) principal. ======================== ====================== ``KRB5_NT_WELLKNOWN`` ``11`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA256.rst.txt0000664000175000017500000000051215051422642026601 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-CMAC-CAMELLIA256-data: CKSUMTYPE_CMAC_CAMELLIA256 ========================== .. .. data:: CKSUMTYPE_CMAC_CAMELLIA256 .. RFC 6803. ================================= ====================== ``CKSUMTYPE_CMAC_CAMELLIA256`` ``0x0012`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC_EXP.rst.txt0000664000175000017500000000047415051422642026551 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-ARCFOUR-HMAC-EXP-data: ENCTYPE_ARCFOUR_HMAC_EXP ======================== .. .. data:: ENCTYPE_ARCFOUR_HMAC_EXP .. RFC 4757. =============================== ====================== ``ENCTYPE_ARCFOUR_HMAC_EXP`` ``0x0018`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DES_CBC_MD5.rst.txt0000664000175000017500000000041715051422642025670 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DES-CBC-MD5-data: ENCTYPE_DES_CBC_MD5 =================== .. .. data:: ENCTYPE_DES_CBC_MD5 .. ========================== ====================== ``ENCTYPE_DES_CBC_MD5`` ``0x0003`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_OTP_CHALLENGE.rst.txt0000664000175000017500000000051415051422642026551 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-OTP-CHALLENGE-data: KRB5_PADATA_OTP_CHALLENGE ========================= .. .. data:: KRB5_PADATA_OTP_CHALLENGE .. RFC 6560 section 4.1. ================================ ====================== ``KRB5_PADATA_OTP_CHALLENGE`` ``141`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_KRB_SAFE_CKSUM.rst.txt0000664000175000017500000000051215051422642027204 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-KRB-SAFE-CKSUM-data: KRB5_KEYUSAGE_KRB_SAFE_CKSUM ============================ .. .. data:: KRB5_KEYUSAGE_KRB_SAFE_CKSUM .. =================================== ====================== ``KRB5_KEYUSAGE_KRB_SAFE_CKSUM`` ``15`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AD_TYPE_FIELD_TYPE_MASK.rst.txt0000664000175000017500000000045315051422642026456 0ustar ghudsonghudson.. highlight:: c .. _AD-TYPE-FIELD-TYPE-MASK-data: AD_TYPE_FIELD_TYPE_MASK ======================= .. .. data:: AD_TYPE_FIELD_TYPE_MASK .. ============================== ====================== ``AD_TYPE_FIELD_TYPE_MASK`` ``0x1fff`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_ENTERPRISE_PRINCIPAL.rst.txt0000664000175000017500000000053415051422642027217 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-ENTERPRISE-PRINCIPAL-data: KRB5_NT_ENTERPRISE_PRINCIPAL ============================ .. .. data:: KRB5_NT_ENTERPRISE_PRINCIPAL .. Windows 2000 UPN. =================================== ====================== ``KRB5_NT_ENTERPRISE_PRINCIPAL`` ``10`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CRYPTO_TYPE_DATA.rst.txt0000664000175000017500000000045415051422642026210 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CRYPTO-TYPE-DATA-data: KRB5_CRYPTO_TYPE_DATA ===================== .. .. data:: KRB5_CRYPTO_TYPE_DATA .. [in, out] plaintext ============================ ====================== ``KRB5_CRYPTO_TYPE_DATA`` ``2`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY.rst.txt0000664000175000017500000000053615051422642027626 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-TGS-REQ-AD-SUBKEY-data: KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY =============================== .. .. data:: KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY .. ====================================== ====================== ``KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY`` ``5`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_SAM_SEND_ENCRYPTED_SAD.rst.txt0000664000175000017500000000051315051422642027067 0ustar ghudsonghudson.. highlight:: c .. _KRB5-SAM-SEND-ENCRYPTED-SAD-data: KRB5_SAM_SEND_ENCRYPTED_SAD =========================== .. .. data:: KRB5_SAM_SEND_ENCRYPTED_SAD .. ================================== ====================== ``KRB5_SAM_SEND_ENCRYPTED_SAD`` ``0x40000000`` ================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AS_REQ.rst.txt0000664000175000017500000000040315051422642024542 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AS-REQ-data: KRB5_AS_REQ =========== .. .. data:: KRB5_AS_REQ .. Initial authentication request. ================== ====================== ``KRB5_AS_REQ`` ``((krb5_msgtype)10)`` ================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_ISO.rst.txt0000664000175000017500000000033615051422642024700 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-ISO-data: ADDRTYPE_ISO ============ .. .. data:: ADDRTYPE_ISO .. =================== ====================== ``ADDRTYPE_ISO`` ``0x0007`` =================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST.rst.txt0000664000175000017500000000060615051422642030441 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-ADDRESS-LIST-data: KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST ==================================== .. .. data:: KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST .. =========================================== ====================== ``KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST`` ``0x0020`` =========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT_ISSUED.rst.txt0000664000175000017500000000051115051422642027273 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ALL-LAST-TGT-ISSUED-data: KRB5_LRQ_ALL_LAST_TGT_ISSUED ============================ .. .. data:: KRB5_LRQ_ALL_LAST_TGT_ISSUED .. =================================== ====================== ``KRB5_LRQ_ALL_LAST_TGT_ISSUED`` ``3`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CYBERSAFE_SECUREID.rst.txt0000664000175000017500000000047115051422642026323 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CYBERSAFE-SECUREID-data: KRB5_CYBERSAFE_SECUREID ======================= .. .. data:: KRB5_CYBERSAFE_SECUREID .. Cybersafe. RFC 4120 ============================== ====================== ``KRB5_CYBERSAFE_SECUREID`` ``9`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_xc.rst.txt0000664000175000017500000000040115051422642024300 0ustar ghudsonghudson.. highlight:: c .. _krb5-xc-data: krb5_xc ======= .. .. data:: krb5_xc .. ========================= ====================== ``krb5_xc (ptr, args)`` ``((ptr)?((*(ptr)) args):(abort(),(char*)0))`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN.rst.txt0000664000175000017500000000137515051422642030532 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-OTP-FLAGS-SEPARATE-PIN-data: KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN ===================================== .. .. data:: KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN .. This flag indicates that the PIN MUST be returned as a separate item. This flag only takes effect if KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN is set. If this flag is not set, the responder may either concatenate PIN + token value and store it as "value" in the answer or it may return them separately. If they are returned separately, they will be concatenated internally. ============================================ ====================== ``KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN`` ``0x0008`` ============================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_CHAOS.rst.txt0000664000175000017500000000035415051422642025103 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-CHAOS-data: ADDRTYPE_CHAOS ============== .. .. data:: ADDRTYPE_CHAOS .. ===================== ====================== ``ADDRTYPE_CHAOS`` ``0x0005`` ===================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_INT32_MAX.rst.txt0000664000175000017500000000036015051422642025036 0ustar ghudsonghudson.. highlight:: c .. _KRB5-INT32-MAX-data: KRB5_INT32_MAX ============== .. .. data:: KRB5_INT32_MAX .. ===================== ====================== ``KRB5_INT32_MAX`` ``2147483647`` ===================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DSA_SHA1_CMS.rst.txt0000664000175000017500000000046415051422642026030 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DSA-SHA1-CMS-data: ENCTYPE_DSA_SHA1_CMS ==================== .. .. data:: ENCTYPE_DSA_SHA1_CMS .. DSA with SHA1, CMS signature. =========================== ====================== ``ENCTYPE_DSA_SHA1_CMS`` ``0x0009`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES256.rst.txt0000664000175000017500000000061015051422642027140 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-HMAC-SHA1-96-AES256-data: CKSUMTYPE_HMAC_SHA1_96_AES256 ============================= .. .. data:: CKSUMTYPE_HMAC_SHA1_96_AES256 .. RFC 3962. Used with ENCTYPE_AES256_CTS_HMAC_SHA1_96 ==================================== ====================== ``CKSUMTYPE_HMAC_SHA1_96_AES256`` ``0x0010`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_PROXIABLE.rst.txt0000664000175000017500000000040515051422642025477 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-PROXIABLE-data: KDC_OPT_PROXIABLE ================= .. .. data:: KDC_OPT_PROXIABLE .. ======================== ====================== ``KDC_OPT_PROXIABLE`` ``0x10000000`` ======================== ====================== ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootkrb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED.rst.txtkrb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED.r0000664000175000017500000000107715051422642031233 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RESPONDER-PKINIT-FLAGS-TOKEN-USER-PIN-LOCKED-data: KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED ================================================= .. .. data:: KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED .. This flag indicates that the user PIN is locked, and you can't log in to the token with it. ======================================================== ====================== ``KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED`` ``(1 << 2)`` ======================================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_DELEGATION_INFO.rst.txt0000664000175000017500000000051315051422642026443 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-DELEGATION-INFO-data: KRB5_PAC_DELEGATION_INFO ======================== .. .. data:: KRB5_PAC_DELEGATION_INFO .. Constrained delegation info. =============================== ====================== ``KRB5_PAC_DELEGATION_INFO`` ``11`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS.rst.txt0000664000175000017500000000052715051422642027521 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AS-REQ-PA-ENC-TS-data: KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS ============================== .. .. data:: KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS .. ===================================== ====================== ``KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS`` ``1`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GC_USER_USER.rst.txt0000664000175000017500000000042315051422642025517 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GC-USER-USER-data: KRB5_GC_USER_USER ================= .. .. data:: KRB5_GC_USER_USER .. Want user-user ticket. ======================== ====================== ``KRB5_GC_USER_USER`` ``1`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_REQUIRE_REALM.rst.txt0000664000175000017500000000062415051422642030124 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-PARSE-REQUIRE-REALM-data: KRB5_PRINCIPAL_PARSE_REQUIRE_REALM ================================== .. .. data:: KRB5_PRINCIPAL_PARSE_REQUIRE_REALM .. Error if realm is not present. ========================================= ====================== ``KRB5_PRINCIPAL_PARSE_REQUIRE_REALM`` ``0x2`` ========================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES128.rst.txt0000664000175000017500000000061015051422642027136 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-HMAC-SHA1-96-AES128-data: CKSUMTYPE_HMAC_SHA1_96_AES128 ============================= .. .. data:: CKSUMTYPE_HMAC_SHA1_96_AES128 .. RFC 3962. Used with ENCTYPE_AES128_CTS_HMAC_SHA1_96 ==================================== ====================== ``CKSUMTYPE_HMAC_SHA1_96_AES128`` ``0x000f`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR.rst.txt0000664000175000017500000000067515051422642030627 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-GENERATE-REMOTE-ADDR-data: KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR ====================================== .. .. data:: KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR .. Generate the remote network address. ============================================= ====================== ``KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR`` ``0x00000002`` ============================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM.rst.txt0000664000175000017500000000060215051422642030332 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-PA-SAM-CHALLENGE-CKSUM-data: KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM ==================================== .. .. data:: KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM .. =========================================== ====================== ``KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM`` ``25`` =========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_FULL_CHECKSUM.rst.txt0000664000175000017500000000046315051422642026245 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-FULL-CHECKSUM-data: KRB5_PAC_FULL_CHECKSUM ====================== .. .. data:: KRB5_PAC_FULL_CHECKSUM .. KDC full checksum. ============================= ====================== ``KRB5_PAC_FULL_CHECKSUM`` ``19`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_SAFE.rst.txt0000664000175000017500000000035715051422642024256 0ustar ghudsonghudson.. highlight:: c .. _KRB5-SAFE-data: KRB5_SAFE ========= .. .. data:: KRB5_SAFE .. Safe application message. ================ ====================== ``KRB5_SAFE`` ``((krb5_msgtype)20)`` ================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ALL_PW_EXPTIME.rst.txt0000664000175000017500000000044615051422642026466 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ALL-PW-EXPTIME-data: KRB5_LRQ_ALL_PW_EXPTIME ======================= .. .. data:: KRB5_LRQ_ALL_PW_EXPTIME .. ============================== ====================== ``KRB5_LRQ_ALL_PW_EXPTIME`` ``6`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_UNKNOWN.rst.txt0000664000175000017500000000036315051422642025300 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-UNKNOWN-data: ENCTYPE_UNKNOWN =============== .. .. data:: ENCTYPE_UNKNOWN .. ====================== ====================== ``ENCTYPE_UNKNOWN`` ``0x01ff`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_OSF_DCE.rst.txt0000664000175000017500000000043115051422642026106 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-OSF-DCE-data: KRB5_AUTHDATA_OSF_DCE ===================== .. .. data:: KRB5_AUTHDATA_OSF_DCE .. ============================ ====================== ``KRB5_AUTHDATA_OSF_DCE`` ``64`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_INT16_MIN.rst.txt0000664000175000017500000000037115051422642025040 0ustar ghudsonghudson.. highlight:: c .. _KRB5-INT16-MIN-data: KRB5_INT16_MIN ============== .. .. data:: KRB5_INT16_MIN .. ===================== ====================== ``KRB5_INT16_MIN`` ``(-KRB5_INT16_MAX-1)`` ===================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID.rst.txt0000664000175000017500000000062015051422642030531 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-PA-SAM-CHALLENGE-TRACKID-data: KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID ====================================== .. .. data:: KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID .. ============================================= ====================== ``KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID`` ``26`` ============================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_KDC_REP_TICKET.rst.txt0000664000175000017500000000051115051422642027177 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-KDC-REP-TICKET-data: KRB5_KEYUSAGE_KDC_REP_TICKET ============================ .. .. data:: KRB5_KEYUSAGE_KDC_REP_TICKET .. =================================== ====================== ``KRB5_KEYUSAGE_KDC_REP_TICKET`` ``2`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_CLIENT_INFO.rst.txt0000664000175000017500000000045715051422642026015 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-CLIENT-INFO-data: KRB5_PAC_CLIENT_INFO ==================== .. .. data:: KRB5_PAC_CLIENT_INFO .. Client name and ticket info. =========================== ====================== ``KRB5_PAC_CLIENT_INFO`` ``10`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_TIME.rst.txt0000664000175000017500000000054515051422642027034 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-RET-TIME-data: KRB5_AUTH_CONTEXT_RET_TIME ========================== .. .. data:: KRB5_AUTH_CONTEXT_RET_TIME .. Save timestamps for application. ================================= ====================== ``KRB5_AUTH_CONTEXT_RET_TIME`` ``0x00000002`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_FORWARDABLE.rst.txt0000664000175000017500000000042315051422642025702 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-FORWARDABLE-data: KDC_OPT_FORWARDABLE =================== .. .. data:: KDC_OPT_FORWARDABLE .. ========================== ====================== ``KDC_OPT_FORWARDABLE`` ``0x40000000`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_princ_realm.rst.txt0000664000175000017500000000046615051422642026174 0ustar ghudsonghudson.. highlight:: c .. _krb5-princ-realm-data: krb5_princ_realm ================ .. .. data:: krb5_princ_realm .. ======================================= ====================== ``krb5_princ_realm (context, princ)`` ``(&(princ)->realm)`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_ANONYMOUS_PRINCSTR.rst.txt0000664000175000017500000000051215051422642026445 0ustar ghudsonghudson.. highlight:: c .. _KRB5-ANONYMOUS-PRINCSTR-data: KRB5_ANONYMOUS_PRINCSTR ======================= .. .. data:: KRB5_ANONYMOUS_PRINCSTR .. Anonymous principal name. ============================== ====================== ``KRB5_ANONYMOUS_PRINCSTR`` ``"ANONYMOUS"`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL.rst.txt0000664000175000017500000000064215051422642031145 0ustar ghudsonghudson.. highlight:: c .. _KRB5-VERIFY-INIT-CREDS-OPT-AP-REQ-NOFAIL-data: KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL ======================================== .. .. data:: KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL .. =============================================== ====================== ``KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL`` ``0x0001`` =============================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH.rst.txt0000664000175000017500000000046515051422642026665 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AP-REQ-AUTH-data: KRB5_KEYUSAGE_AP_REQ_AUTH ========================= .. .. data:: KRB5_KEYUSAGE_AP_REQ_AUTH .. ================================ ====================== ``KRB5_KEYUSAGE_AP_REQ_AUTH`` ``11`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_const.rst.txt0000664000175000017500000000031715051422642025022 0ustar ghudsonghudson.. highlight:: c .. _krb5-const-data: krb5_const ========== .. .. data:: krb5_const .. ================= ====================== ``krb5_const`` ``const`` ================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/LR_TYPE_INTERPRETATION_MASK.rst.txt0000664000175000017500000000050715051422642027172 0ustar ghudsonghudson.. highlight:: c .. _LR-TYPE-INTERPRETATION-MASK-data: LR_TYPE_INTERPRETATION_MASK =========================== .. .. data:: LR_TYPE_INTERPRETATION_MASK .. ================================== ====================== ``LR_TYPE_INTERPRETATION_MASK`` ``0x7fff`` ================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_POSTDATED.rst.txt0000664000175000017500000000040515051422642025501 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-POSTDATED-data: KDC_OPT_POSTDATED ================= .. .. data:: KDC_OPT_POSTDATED .. ======================== ====================== ``KDC_OPT_POSTDATED`` ``0x02000000`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR.rst.txt0000664000175000017500000000076415051422642031450 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTH-CONTEXT-GENERATE-REMOTE-FULL-ADDR-data: KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR =========================================== .. .. data:: KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR .. Generate the remote network address and the remote port. ================================================== ====================== ``KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR`` ``0x00000008`` ================================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_MATCH_KTYPE.rst.txt0000664000175000017500000000046715051422642025740 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-MATCH-KTYPE-data: KRB5_TC_MATCH_KTYPE =================== .. .. data:: KRB5_TC_MATCH_KTYPE .. The encryption key type must match. ========================== ====================== ``KRB5_TC_MATCH_KTYPE`` ``0x00000100`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_ERROR.rst.txt0000664000175000017500000000035415051422642024426 0ustar ghudsonghudson.. highlight:: c .. _KRB5-ERROR-data: KRB5_ERROR ========== .. .. data:: KRB5_ERROR .. Error response. ================= ====================== ``KRB5_ERROR`` ``((krb5_msgtype)30)`` ================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_UPN_DNS_INFO.rst.txt0000664000175000017500000000047315051422642026203 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-UPN-DNS-INFO-data: KRB5_PAC_UPN_DNS_INFO ===================== .. .. data:: KRB5_PAC_UPN_DNS_INFO .. User principal name and DNS info. ============================ ====================== ``KRB5_PAC_UPN_DNS_INFO`` ``12`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GC_CACHED.rst.txt0000664000175000017500000000040015051422642025005 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GC-CACHED-data: KRB5_GC_CACHED ============== .. .. data:: KRB5_GC_CACHED .. Want cached ticket only. ===================== ====================== ``KRB5_GC_CACHED`` ``2`` ===================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KPASSWD_INITIAL_FLAG_NEEDED.rst.txt0000664000175000017500000000065415051422642027622 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KPASSWD-INITIAL-FLAG-NEEDED-data: KRB5_KPASSWD_INITIAL_FLAG_NEEDED ================================ .. .. data:: KRB5_KPASSWD_INITIAL_FLAG_NEEDED .. The presented credentials were not obtained using a password directly. ======================================= ====================== ``KRB5_KPASSWD_INITIAL_FLAG_NEEDED`` ``7`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_CNAME_IN_ADDL_TKT.rst.txt0000664000175000017500000000047515051422642026700 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-CNAME-IN-ADDL-TKT-data: KDC_OPT_CNAME_IN_ADDL_TKT ========================= .. .. data:: KDC_OPT_CNAME_IN_ADDL_TKT .. ================================ ====================== ``KDC_OPT_CNAME_IN_ADDL_TKT`` ``0x00020000`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_MATCH_AUTHDATA.rst.txt0000664000175000017500000000051315051422642026227 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-MATCH-AUTHDATA-data: KRB5_TC_MATCH_AUTHDATA ====================== .. .. data:: KRB5_TC_MATCH_AUTHDATA .. The authorization data must match. ============================= ====================== ``KRB5_TC_MATCH_AUTHDATA`` ``0x00000020`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_IGNORE_REALM.rst.txt0000664000175000017500000000062115051422642030204 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-COMPARE-IGNORE-REALM-data: KRB5_PRINCIPAL_COMPARE_IGNORE_REALM =================================== .. .. data:: KRB5_PRINCIPAL_COMPARE_IGNORE_REALM .. ignore realm component ========================================== ====================== ``KRB5_PRINCIPAL_COMPARE_IGNORE_REALM`` ``1`` ========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_REFERRAL_REALM.rst.txt0000664000175000017500000000045115051422642025655 0ustar ghudsonghudson.. highlight:: c .. _KRB5-REFERRAL-REALM-data: KRB5_REFERRAL_REALM =================== .. .. data:: KRB5_REFERRAL_REALM .. Constant for realm referrals. ========================== ====================== ``KRB5_REFERRAL_REALM`` ``""`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_ENC_TKT_IN_SKEY.rst.txt0000664000175000017500000000045715051422642026531 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-ENC-TKT-IN-SKEY-data: KDC_OPT_ENC_TKT_IN_SKEY ======================= .. .. data:: KDC_OPT_ENC_TKT_IN_SKEY .. ============================== ====================== ``KDC_OPT_ENC_TKT_IN_SKEY`` ``0x00000008`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_INIT_CONTEXT_SECURE.rst.txt0000664000175000017500000000052115051422642026546 0ustar ghudsonghudson.. highlight:: c .. _KRB5-INIT-CONTEXT-SECURE-data: KRB5_INIT_CONTEXT_SECURE ======================== .. .. data:: KRB5_INIT_CONTEXT_SECURE .. Use secure context configuration. =============================== ====================== ``KRB5_INIT_CONTEXT_SECURE`` ``0x1`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY.rst.txt0000664000175000017500000000060115051422642030426 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-TGS-REP-ENCPART-SUBKEY-data: KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY ==================================== .. .. data:: KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY .. =========================================== ====================== ``KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY`` ``9`` =========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ADDRTYPE_INET.rst.txt0000664000175000017500000000034515051422642025005 0ustar ghudsonghudson.. highlight:: c .. _ADDRTYPE-INET-data: ADDRTYPE_INET ============= .. .. data:: ADDRTYPE_INET .. ==================== ====================== ``ADDRTYPE_INET`` ``0x0002`` ==================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_ENC_UNIX_TIME.rst.txt0000664000175000017500000000053015051422642026631 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-ENC-UNIX-TIME-data: KRB5_PADATA_ENC_UNIX_TIME ========================= .. .. data:: KRB5_PADATA_ENC_UNIX_TIME .. timestamp encrypted in key. RFC 4120 ================================ ====================== ``KRB5_PADATA_ENC_UNIX_TIME`` ``5`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_INITIAL_VERIFIED_CAS.rst.txt0000664000175000017500000000056315051422642030046 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-INITIAL-VERIFIED-CAS-data: KRB5_AUTHDATA_INITIAL_VERIFIED_CAS ================================== .. .. data:: KRB5_AUTHDATA_INITIAL_VERIFIED_CAS .. ========================================= ====================== ``KRB5_AUTHDATA_INITIAL_VERIFIED_CAS`` ``9`` ========================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_NULL.rst.txt0000664000175000017500000000033615051422642024713 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-NULL-data: ENCTYPE_NULL ============ .. .. data:: ENCTYPE_NULL .. =================== ====================== ``ENCTYPE_NULL`` ``0x0000`` =================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_AS_FRESHNESS.rst.txt0000664000175000017500000000047115051422642026472 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-AS-FRESHNESS-data: KRB5_PADATA_AS_FRESHNESS ======================== .. .. data:: KRB5_PADATA_AS_FRESHNESS .. RFC 8070. =============================== ====================== ``KRB5_PADATA_AS_FRESHNESS`` ``150`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_princ_size.rst.txt0000664000175000017500000000045515051422642026044 0ustar ghudsonghudson.. highlight:: c .. _krb5-princ-size-data: krb5_princ_size =============== .. .. data:: krb5_princ_size .. ====================================== ====================== ``krb5_princ_size (context, princ)`` ``(princ)->length`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GC_CANONICALIZE.rst.txt0000664000175000017500000000045615051422642025750 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GC-CANONICALIZE-data: KRB5_GC_CANONICALIZE ==================== .. .. data:: KRB5_GC_CANONICALIZE .. Set canonicalize KDC option. =========================== ====================== ``KRB5_GC_CANONICALIZE`` ``4`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_FAST_REP.rst.txt0000664000175000017500000000044015051422642026271 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-FAST-REP-data: KRB5_KEYUSAGE_FAST_REP ====================== .. .. data:: KRB5_KEYUSAGE_FAST_REP .. ============================= ====================== ``KRB5_KEYUSAGE_FAST_REP`` ``52`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_MD5_RSA_CMS.rst.txt0000664000175000017500000000045415051422642025736 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-MD5-RSA-CMS-data: ENCTYPE_MD5_RSA_CMS =================== .. .. data:: ENCTYPE_MD5_RSA_CMS .. MD5 with RSA, CMS signature. ========================== ====================== ``ENCTYPE_MD5_RSA_CMS`` ``0x000a`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KPASSWD_AUTHERROR.rst.txt0000664000175000017500000000046515051422642026307 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KPASSWD-AUTHERROR-data: KRB5_KPASSWD_AUTHERROR ====================== .. .. data:: KRB5_KPASSWD_AUTHERROR .. Authentication error. ============================= ====================== ``KRB5_KPASSWD_AUTHERROR`` ``3`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AP_REP_ENCPART.rst.txt0000664000175000017500000000051215051422642027210 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AP-REP-ENCPART-data: KRB5_KEYUSAGE_AP_REP_ENCPART ============================ .. .. data:: KRB5_KEYUSAGE_AP_REP_ENCPART .. =================================== ====================== ``KRB5_KEYUSAGE_AP_REP_ENCPART`` ``12`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN.rst.txt0000664000175000017500000000063315051422642030351 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PROMPT-TYPE-NEW-PASSWORD-AGAIN-data: KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN =================================== .. .. data:: KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN .. Prompt for new password again. ========================================== ====================== ``KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN`` ``0x3`` ========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_DESCBC.rst.txt0000664000175000017500000000037215051422642025341 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-DESCBC-data: CKSUMTYPE_DESCBC ================ .. .. data:: CKSUMTYPE_DESCBC .. ======================= ====================== ``CKSUMTYPE_DESCBC`` ``0x0004`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ONE_PW_EXPTIME.rst.txt0000664000175000017500000000045115051422642026473 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ONE-PW-EXPTIME-data: KRB5_LRQ_ONE_PW_EXPTIME ======================= .. .. data:: KRB5_LRQ_ONE_PW_EXPTIME .. ============================== ====================== ``KRB5_LRQ_ONE_PW_EXPTIME`` ``(-6)`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_FAST_REQUIRED.rst.txt0000664000175000017500000000044515051422642025573 0ustar ghudsonghudson.. highlight:: c .. _KRB5-FAST-REQUIRED-data: KRB5_FAST_REQUIRED ================== .. .. data:: KRB5_FAST_REQUIRED .. Require KDC to support FAST. ========================= ====================== ``KRB5_FAST_REQUIRED`` ``0x0001`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_USE_SPECIFIED_KVNO.rst.txt0000664000175000017500000000054215051422642027412 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-USE-SPECIFIED-KVNO-data: KRB5_PADATA_USE_SPECIFIED_KVNO ============================== .. .. data:: KRB5_PADATA_USE_SPECIFIED_KVNO .. RFC 4120. ===================================== ====================== ``KRB5_PADATA_USE_SPECIFIED_KVNO`` ``20`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_princ_component.rst.txt0000664000175000017500000000062415051422642027072 0ustar ghudsonghudson.. highlight:: c .. _krb5-princ-component-data: krb5_princ_component ==================== .. .. data:: krb5_princ_component .. ============================================== ====================== ``krb5_princ_component (context, princ, i)`` `` (((i) < krb5_princ_size(context, princ)) ? (princ)->data + (i) : NULL)`` ============================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM.rst.txt0000664000175000017500000000054515051422642027763 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-TGS-REQ-AUTH-CKSUM-data: KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM ================================ .. .. data:: KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM .. ======================================= ====================== ``KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM`` ``6`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_ENC_PA_REP.rst.txt0000664000175000017500000000041415051422642025654 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-ENC-PA-REP-data: TKT_FLG_ENC_PA_REP ================== .. .. data:: TKT_FLG_ENC_PA_REP .. ========================= ====================== ``TKT_FLG_ENC_PA_REP`` ``0x00010000`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_KRB_CRED_ENCPART.rst.txt0000664000175000017500000000053015051422642027415 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-KRB-CRED-ENCPART-data: KRB5_KEYUSAGE_KRB_CRED_ENCPART ============================== .. .. data:: KRB5_KEYUSAGE_KRB_CRED_ENCPART .. ===================================== ====================== ``KRB5_KEYUSAGE_KRB_CRED_ENCPART`` ``14`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AP_REP.rst.txt0000664000175000017500000000040215051422642024535 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AP-REP-data: KRB5_AP_REP =========== .. .. data:: KRB5_AP_REP .. Response to mutual AP request. ================== ====================== ``KRB5_AP_REP`` ``((krb5_msgtype)15)`` ================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_RESPONSE.rst.txt0000664000175000017500000000052115051422642027344 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-PA-SAM-RESPONSE-data: KRB5_KEYUSAGE_PA_SAM_RESPONSE ============================= .. .. data:: KRB5_KEYUSAGE_PA_SAM_RESPONSE .. ==================================== ====================== ``KRB5_KEYUSAGE_PA_SAM_RESPONSE`` ``27`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA256_128.rst.txt0000664000175000017500000000060215051422642027623 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-AES128-CTS-HMAC-SHA256-128-data: ENCTYPE_AES128_CTS_HMAC_SHA256_128 ================================== .. .. data:: ENCTYPE_AES128_CTS_HMAC_SHA256_128 .. RFC 8009. ========================================= ====================== ``ENCTYPE_AES128_CTS_HMAC_SHA256_128`` ``0x0013`` ========================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/LR_TYPE_THIS_SERVER_ONLY.rst.txt0000664000175000017500000000046215051422642026706 0ustar ghudsonghudson.. highlight:: c .. _LR-TYPE-THIS-SERVER-ONLY-data: LR_TYPE_THIS_SERVER_ONLY ======================== .. .. data:: LR_TYPE_THIS_SERVER_ONLY .. =============================== ====================== ``LR_TYPE_THIS_SERVER_ONLY`` ``0x8000`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_NOTICKET.rst.txt0000664000175000017500000000037615051422642025347 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-NOTICKET-data: KRB5_TC_NOTICKET ================ .. .. data:: KRB5_TC_NOTICKET .. ======================= ====================== ``KRB5_TC_NOTICKET`` ``0x00000002`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT.rst.txt0000664000175000017500000000043015051422642026217 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ALL-LAST-TGT-data: KRB5_LRQ_ALL_LAST_TGT ===================== .. .. data:: KRB5_LRQ_ALL_LAST_TGT .. ============================ ====================== ``KRB5_LRQ_ALL_LAST_TGT`` ``1`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_CRC32.rst.txt0000664000175000017500000000036315051422642025172 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-CRC32-data: CKSUMTYPE_CRC32 =============== .. .. data:: CKSUMTYPE_CRC32 .. ====================== ====================== ``CKSUMTYPE_CRC32`` ``0x0001`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_HMAC_MD5_ARCFOUR.rst.txt0000664000175000017500000000051015051422642026746 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-HMAC-MD5-ARCFOUR-data: CKSUMTYPE_HMAC_MD5_ARCFOUR ========================== .. .. data:: CKSUMTYPE_HMAC_MD5_ARCFOUR .. RFC 4757. ================================= ====================== ``CKSUMTYPE_HMAC_MD5_ARCFOUR`` ``-138`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_RECVAUTH_SKIP_VERSION.rst.txt0000664000175000017500000000050015051422642027002 0ustar ghudsonghudson.. highlight:: c .. _KRB5-RECVAUTH-SKIP-VERSION-data: KRB5_RECVAUTH_SKIP_VERSION ========================== .. .. data:: KRB5_RECVAUTH_SKIP_VERSION .. ================================= ====================== ``KRB5_RECVAUTH_SKIP_VERSION`` ``0x0001`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/THREEPARAMOPEN.rst.txt0000664000175000017500000000041515051422642025062 0ustar ghudsonghudson.. highlight:: c .. _THREEPARAMOPEN-data: THREEPARAMOPEN ============== .. .. data:: THREEPARAMOPEN .. ============================== ====================== ``THREEPARAMOPEN (x, y, z)`` ``open(x,y,z)`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_MATCH_IS_SKEY.rst.txt0000664000175000017500000000050715051422642026205 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-MATCH-IS-SKEY-data: KRB5_TC_MATCH_IS_SKEY ===================== .. .. data:: KRB5_TC_MATCH_IS_SKEY .. The is_skey field must match exactly. ============================ ====================== ``KRB5_TC_MATCH_IS_SKEY`` ``0x00000002`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT.rst.txt0000664000175000017500000000056415051422642030042 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-ENC-CHALLENGE-CLIENT-data: KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT ================================== .. .. data:: KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT .. ========================================= ====================== ``KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT`` ``54`` ========================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/krb5_princ_type.rst.txt0000664000175000017500000000045315051422642026051 0ustar ghudsonghudson.. highlight:: c .. _krb5-princ-type-data: krb5_princ_type =============== .. .. data:: krb5_princ_type .. ====================================== ====================== ``krb5_princ_type (context, princ)`` ``(princ)->type`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_ETYPE_NEGOTIATION.rst.txt0000664000175000017500000000055215051422642027536 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-ETYPE-NEGOTIATION-data: KRB5_AUTHDATA_ETYPE_NEGOTIATION =============================== .. .. data:: KRB5_AUTHDATA_ETYPE_NEGOTIATION .. RFC 4537. ====================================== ====================== ``KRB5_AUTHDATA_ETYPE_NEGOTIATION`` ``129`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_GET_FROM_TYPED_DATA.rst.txt0000664000175000017500000000057715051422642027556 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-GET-FROM-TYPED-DATA-data: KRB5_PADATA_GET_FROM_TYPED_DATA =============================== .. .. data:: KRB5_PADATA_GET_FROM_TYPED_DATA .. Embedded in typed data. RFC 4120 ====================================== ====================== ``KRB5_PADATA_GET_FROM_TYPED_DATA`` ``22`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AP_OPTS_USE_SUBKEY.rst.txt0000664000175000017500000000054215051422642025714 0ustar ghudsonghudson.. highlight:: c .. _AP-OPTS-USE-SUBKEY-data: AP_OPTS_USE_SUBKEY ================== .. .. data:: AP_OPTS_USE_SUBKEY .. Generate a subsession key from the current session key obtained from the credentials. ========================= ====================== ``AP_OPTS_USE_SUBKEY`` ``0x00000001`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_FX_FAST.rst.txt0000664000175000017500000000042615051422642025701 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-FX-FAST-data: KRB5_PADATA_FX_FAST =================== .. .. data:: KRB5_PADATA_FX_FAST .. RFC 6113. ========================== ====================== ``KRB5_PADATA_FX_FAST`` ``136`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_CRYPTO_TYPE_CHECKSUM.rst.txt0000664000175000017500000000051315051422642026675 0ustar ghudsonghudson.. highlight:: c .. _KRB5-CRYPTO-TYPE-CHECKSUM-data: KRB5_CRYPTO_TYPE_CHECKSUM ========================= .. .. data:: KRB5_CRYPTO_TYPE_CHECKSUM .. [out] checksum for MIC ================================ ====================== ``KRB5_CRYPTO_TYPE_CHECKSUM`` ``6`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/SALT_TYPE_AFS_LENGTH.rst.txt0000664000175000017500000000043015051422642026103 0ustar ghudsonghudson.. highlight:: c .. _SALT-TYPE-AFS-LENGTH-data: SALT_TYPE_AFS_LENGTH ==================== .. .. data:: SALT_TYPE_AFS_LENGTH .. =========================== ====================== ``SALT_TYPE_AFS_LENGTH`` ``UINT_MAX`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ALL_LAST_RENEWAL.rst.txt0000664000175000017500000000046415051422642026665 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ALL-LAST-RENEWAL-data: KRB5_LRQ_ALL_LAST_RENEWAL ========================= .. .. data:: KRB5_LRQ_ALL_LAST_RENEWAL .. ================================ ====================== ``KRB5_LRQ_ALL_LAST_RENEWAL`` ``4`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_REDHAT_IDP_OAUTH2.rst.txt0000664000175000017500000000055115051422642027233 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-REDHAT-IDP-OAUTH2-data: KRB5_PADATA_REDHAT_IDP_OAUTH2 ============================= .. .. data:: KRB5_PADATA_REDHAT_IDP_OAUTH2 .. Red Hat IdP mechanism. ==================================== ====================== ``KRB5_PADATA_REDHAT_IDP_OAUTH2`` ``152`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_SESAME.rst.txt0000664000175000017500000000043315051422642025522 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-SESAME-data: KRB5_PADATA_SESAME ================== .. .. data:: KRB5_PADATA_SESAME .. Sesame project. RFC 4120 ========================= ====================== ``KRB5_PADATA_SESAME`` ``7`` ========================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DES_HMAC_SHA1.rst.txt0000664000175000017500000000043515051422642026120 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DES-HMAC-SHA1-data: ENCTYPE_DES_HMAC_SHA1 ===================== .. .. data:: ENCTYPE_DES_HMAC_SHA1 .. ============================ ====================== ``ENCTYPE_DES_HMAC_SHA1`` ``0x0008`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_ENC_TIMESTAMP.rst.txt0000664000175000017500000000047615051422642026604 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-ENC-TIMESTAMP-data: KRB5_PADATA_ENC_TIMESTAMP ========================= .. .. data:: KRB5_PADATA_ENC_TIMESTAMP .. RFC 4120. ================================ ====================== ``KRB5_PADATA_ENC_TIMESTAMP`` ``2`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AD_TYPE_EXTERNAL.rst.txt0000664000175000017500000000037215051422642025401 0ustar ghudsonghudson.. highlight:: c .. _AD-TYPE-EXTERNAL-data: AD_TYPE_EXTERNAL ================ .. .. data:: AD_TYPE_EXTERNAL .. ======================= ====================== ``AD_TYPE_EXTERNAL`` ``0x4000`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GC_FORWARDABLE.rst.txt0000664000175000017500000000045015051422642025633 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GC-FORWARDABLE-data: KRB5_GC_FORWARDABLE =================== .. .. data:: KRB5_GC_FORWARDABLE .. Acquire forwardable tickets. ========================== ====================== ``KRB5_GC_FORWARDABLE`` ``16`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_REDHAT_PASSKEY.rst.txt0000664000175000017500000000053015051422642026711 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-REDHAT-PASSKEY-data: KRB5_PADATA_REDHAT_PASSKEY ========================== .. .. data:: KRB5_PADATA_REDHAT_PASSKEY .. Red Hat Passkey mechanism. ================================= ====================== ``KRB5_PADATA_REDHAT_PASSKEY`` ``153`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_INT32_MIN.rst.txt0000664000175000017500000000037115051422642025036 0ustar ghudsonghudson.. highlight:: c .. _KRB5-INT32-MIN-data: KRB5_INT32_MIN ============== .. .. data:: KRB5_INT32_MIN .. ===================== ====================== ``KRB5_INT32_MIN`` ``(-KRB5_INT32_MAX-1)`` ===================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST.rst.txt0000664000175000017500000000062015051422642030614 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-PA-S4U-X509-USER-REQUEST-data: KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST ====================================== .. .. data:: KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST .. ============================================= ====================== ``KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST`` ``26`` ============================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_ENC_SANDIA_SECURID.rst.txt0000664000175000017500000000056115051422642027351 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-ENC-SANDIA-SECURID-data: KRB5_PADATA_ENC_SANDIA_SECURID ============================== .. .. data:: KRB5_PADATA_ENC_SANDIA_SECURID .. SecurId passcode. RFC 4120 ===================================== ====================== ``KRB5_PADATA_ENC_SANDIA_SECURID`` ``6`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_FX_ERROR.rst.txt0000664000175000017500000000043515051422642026035 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-FX-ERROR-data: KRB5_PADATA_FX_ERROR ==================== .. .. data:: KRB5_PADATA_FX_ERROR .. RFC 6113. =========================== ====================== ``KRB5_PADATA_FX_ERROR`` ``137`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_ETYPE_INFO.rst.txt0000664000175000017500000000050015051422642026241 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-ETYPE-INFO-data: KRB5_PADATA_ETYPE_INFO ====================== .. .. data:: KRB5_PADATA_ETYPE_INFO .. Etype info for preauth. RFC 4120 ============================= ====================== ``KRB5_PADATA_ETYPE_INFO`` ``11`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA1_96.rst.txt0000664000175000017500000000055515051422642027402 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-AES128-CTS-HMAC-SHA1-96-data: ENCTYPE_AES128_CTS_HMAC_SHA1_96 =============================== .. .. data:: ENCTYPE_AES128_CTS_HMAC_SHA1_96 .. RFC 3962. ====================================== ====================== ``ENCTYPE_AES128_CTS_HMAC_SHA1_96`` ``0x0011`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_TGS_REQ.rst.txt0000664000175000017500000000043315051422642025711 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-TGS-REQ-data: KRB5_PADATA_TGS_REQ =================== .. .. data:: KRB5_PADATA_TGS_REQ .. ========================== ====================== ``KRB5_PADATA_TGS_REQ`` ``KRB5_PADATA_AP_REQ`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE.rst.txt0000664000175000017500000000057015051422642030200 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-RENEW-LIFE-data: KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE ================================== .. .. data:: KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE .. ========================================= ====================== ``KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE`` ``0x0002`` ========================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_CAMMAC.rst.txt0000664000175000017500000000042215051422642025747 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-CAMMAC-data: KRB5_KEYUSAGE_CAMMAC ==================== .. .. data:: KRB5_KEYUSAGE_CAMMAC .. =========================== ====================== ``KRB5_KEYUSAGE_CAMMAC`` ``64`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_RSA_ENV.rst.txt0000664000175000017500000000042715051422642025277 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-RSA-ENV-data: ENCTYPE_RSA_ENV =============== .. .. data:: ENCTYPE_RSA_ENV .. RSA encryption, CMS enveloped data. ====================== ====================== ``ENCTYPE_RSA_ENV`` ``0x000d`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_KDC.rst.txt0000664000175000017500000000053715051422642027465 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-ENC-CHALLENGE-KDC-data: KRB5_KEYUSAGE_ENC_CHALLENGE_KDC =============================== .. .. data:: KRB5_KEYUSAGE_ENC_CHALLENGE_KDC .. ====================================== ====================== ``KRB5_KEYUSAGE_ENC_CHALLENGE_KDC`` ``55`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ALL_LAST_REQ.rst.txt0000664000175000017500000000043015051422642026210 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ALL-LAST-REQ-data: KRB5_LRQ_ALL_LAST_REQ ===================== .. .. data:: KRB5_LRQ_ALL_LAST_REQ .. ============================ ====================== ``KRB5_LRQ_ALL_LAST_REQ`` ``5`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_HMAC_SHA384_192_AES256.rst.txt0000664000175000017500000000056415051422642027403 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-HMAC-SHA384-192-AES256-data: CKSUMTYPE_HMAC_SHA384_192_AES256 ================================ .. .. data:: CKSUMTYPE_HMAC_SHA384_192_AES256 .. RFC 8009. ======================================= ====================== ``CKSUMTYPE_HMAC_SHA384_192_AES256`` ``0x0014`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PROMPT_TYPE_PASSWORD.rst.txt0000664000175000017500000000051315051422642026736 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PROMPT-TYPE-PASSWORD-data: KRB5_PROMPT_TYPE_PASSWORD ========================= .. .. data:: KRB5_PROMPT_TYPE_PASSWORD .. Prompt for password. ================================ ====================== ``KRB5_PROMPT_TYPE_PASSWORD`` ``0x1`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AS_REP_ENCPART.rst.txt0000664000175000017500000000051115051422642027212 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AS-REP-ENCPART-data: KRB5_KEYUSAGE_AS_REP_ENCPART ============================ .. .. data:: KRB5_KEYUSAGE_AS_REP_ENCPART .. =================================== ====================== ``KRB5_KEYUSAGE_AS_REP_ENCPART`` ``3`` =================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD.rst.txt0000664000175000017500000000060315051422642027447 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PROMPT-TYPE-NEW-PASSWORD-data: KRB5_PROMPT_TYPE_NEW_PASSWORD ============================= .. .. data:: KRB5_PROMPT_TYPE_NEW_PASSWORD .. Prompt for new password (during password change) ==================================== ====================== ``KRB5_PROMPT_TYPE_NEW_PASSWORD`` ``0x2`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_PA_PKINIT_KX.rst.txt0000664000175000017500000000047415051422642027015 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-PA-PKINIT-KX-data: KRB5_KEYUSAGE_PA_PKINIT_KX ========================== .. .. data:: KRB5_KEYUSAGE_PA_PKINIT_KX .. ================================= ====================== ``KRB5_KEYUSAGE_PA_PKINIT_KX`` ``44`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/MSEC_VAL_MASK.rst.txt0000664000175000017500000000034515051422642025016 0ustar ghudsonghudson.. highlight:: c .. _MSEC-VAL-MASK-data: MSEC_VAL_MASK ============= .. .. data:: MSEC_VAL_MASK .. ==================== ====================== ``MSEC_VAL_MASK`` ``0x7fff`` ==================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_ANONYMOUS_REALMSTR.rst.txt0000664000175000017500000000051315051422642026433 0ustar ghudsonghudson.. highlight:: c .. _KRB5-ANONYMOUS-REALMSTR-data: KRB5_ANONYMOUS_REALMSTR ======================= .. .. data:: KRB5_ANONYMOUS_REALMSTR .. Anonymous realm. ============================== ====================== ``KRB5_ANONYMOUS_REALMSTR`` ``"WELLKNOWN:ANONYMOUS"`` ============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_KRB_ERROR_CKSUM.rst.txt0000664000175000017500000000052115051422642027357 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-KRB-ERROR-CKSUM-data: KRB5_KEYUSAGE_KRB_ERROR_CKSUM ============================= .. .. data:: KRB5_KEYUSAGE_KRB_ERROR_CKSUM .. ==================================== ====================== ``KRB5_KEYUSAGE_KRB_ERROR_CKSUM`` ``18`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_ANONYMOUS.rst.txt0000664000175000017500000000040515051422642025551 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-ANONYMOUS-data: TKT_FLG_ANONYMOUS ================= .. .. data:: TKT_FLG_ANONYMOUS .. ======================== ====================== ``TKT_FLG_ANONYMOUS`` ``0x00008000`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_DEF_REALM.rst.txt0000664000175000017500000000061015051422642027775 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-PARSE-NO-DEF-REALM-data: KRB5_PRINCIPAL_PARSE_NO_DEF_REALM ================================= .. .. data:: KRB5_PRINCIPAL_PARSE_NO_DEF_REALM .. Don't add default realm. ======================================== ====================== ``KRB5_PRINCIPAL_PARSE_NO_DEF_REALM`` ``0x10`` ======================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_HW_AUTH.rst.txt0000664000175000017500000000036715051422642025327 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-HW-AUTH-data: TKT_FLG_HW_AUTH =============== .. .. data:: TKT_FLG_HW_AUTH .. ====================== ====================== ``TKT_FLG_HW_AUTH`` ``0x00100000`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM.rst.txt0000664000175000017500000000054615051422642027661 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AD-KDCISSUED-CKSUM-data: KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM ================================ .. .. data:: KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM .. ======================================= ====================== ``KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM`` ``19`` ======================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST.rst.txt0000664000175000017500000000060615051422642030464 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-PREAUTH-LIST-data: KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST ==================================== .. .. data:: KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST .. =========================================== ====================== ``KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST`` ``0x0040`` =========================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_KDC_ISSUED.rst.txt0000664000175000017500000000045515051422642026467 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-KDC-ISSUED-data: KRB5_AUTHDATA_KDC_ISSUED ======================== .. .. data:: KRB5_AUTHDATA_KDC_ISSUED .. =============================== ====================== ``KRB5_AUTHDATA_KDC_ISSUED`` ``4`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_AD_SIGNEDPATH.rst.txt0000664000175000017500000000050415051422642027021 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-AD-SIGNEDPATH-data: KRB5_KEYUSAGE_AD_SIGNEDPATH =========================== .. .. data:: KRB5_KEYUSAGE_AD_SIGNEDPATH .. ================================== ====================== ``KRB5_KEYUSAGE_AD_SIGNEDPATH`` ``-21`` ================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_ENCPADATA_REQ_ENC_PA_REP.rst.txt0000664000175000017500000000053415051422642027277 0ustar ghudsonghudson.. highlight:: c .. _KRB5-ENCPADATA-REQ-ENC-PA-REP-data: KRB5_ENCPADATA_REQ_ENC_PA_REP ============================= .. .. data:: KRB5_ENCPADATA_REQ_ENC_PA_REP .. RFC 6806. ==================================== ====================== ``KRB5_ENCPADATA_REQ_ENC_PA_REP`` ``149`` ==================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ONE_ACCT_EXPTIME.rst.txt0000664000175000017500000000046715051422642026666 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ONE-ACCT-EXPTIME-data: KRB5_LRQ_ONE_ACCT_EXPTIME ========================= .. .. data:: KRB5_LRQ_ONE_ACCT_EXPTIME .. ================================ ====================== ``KRB5_LRQ_ONE_ACCT_EXPTIME`` ``(-7)`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ONE_LAST_RENEWAL.rst.txt0000664000175000017500000000046715051422642026701 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ONE-LAST-RENEWAL-data: KRB5_LRQ_ONE_LAST_RENEWAL ========================= .. .. data:: KRB5_LRQ_ONE_LAST_RENEWAL .. ================================ ====================== ``KRB5_LRQ_ONE_LAST_RENEWAL`` ``(-4)`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA1_96.rst.txt0000664000175000017500000000055515051422642027404 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-AES256-CTS-HMAC-SHA1-96-data: ENCTYPE_AES256_CTS_HMAC_SHA1_96 =============================== .. .. data:: ENCTYPE_AES256_CTS_HMAC_SHA1_96 .. RFC 3962. ====================================== ====================== ``ENCTYPE_AES256_CTS_HMAC_SHA1_96`` ``0x0012`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_INITIAL.rst.txt0000664000175000017500000000036715051422642025261 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-INITIAL-data: TKT_FLG_INITIAL =============== .. .. data:: TKT_FLG_INITIAL .. ====================== ====================== ``TKT_FLG_INITIAL`` ``0x00400000`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/ENCTYPE_DES_CBC_MD4.rst.txt0000664000175000017500000000041715051422642025667 0ustar ghudsonghudson.. highlight:: c .. _ENCTYPE-DES-CBC-MD4-data: ENCTYPE_DES_CBC_MD4 =================== .. .. data:: ENCTYPE_DES_CBC_MD4 .. ========================== ====================== ``ENCTYPE_DES_CBC_MD4`` ``0x0002`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_FX_ARMOR.rst.txt0000664000175000017500000000044015051422642026261 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-FX-ARMOR-data: KRB5_AUTHDATA_FX_ARMOR ====================== .. .. data:: KRB5_AUTHDATA_FX_ARMOR .. ============================= ====================== ``KRB5_AUTHDATA_FX_ARMOR`` ``71`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_RSA_MD4_DES.rst.txt0000664000175000017500000000043515051422642026202 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-RSA-MD4-DES-data: CKSUMTYPE_RSA_MD4_DES ===================== .. .. data:: CKSUMTYPE_RSA_MD4_DES .. ============================ ====================== ``CKSUMTYPE_RSA_MD4_DES`` ``0x0003`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST.rst.txt0000664000175000017500000000057015051422642030242 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GET-INIT-CREDS-OPT-ETYPE-LIST-data: KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST ================================== .. .. data:: KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST .. ========================================= ====================== ``KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST`` ``0x0010`` ========================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA128.rst.txt0000664000175000017500000000051215051422642026577 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-CMAC-CAMELLIA128-data: CKSUMTYPE_CMAC_CAMELLIA128 ========================== .. .. data:: CKSUMTYPE_CMAC_CAMELLIA128 .. RFC 6803. ================================= ====================== ``CKSUMTYPE_CMAC_CAMELLIA128`` ``0x0011`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT.rst.txt0000664000175000017500000000043315051422642026233 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ONE-LAST-TGT-data: KRB5_LRQ_ONE_LAST_TGT ===================== .. .. data:: KRB5_LRQ_ONE_LAST_TGT .. ============================ ====================== ``KRB5_LRQ_ONE_LAST_TGT`` ``(-1)`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_PA_FX_COOKIE.rst.txt0000664000175000017500000000053615051422642026762 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-PA-FX-COOKIE-data: KRB5_KEYUSAGE_PA_FX_COOKIE ========================== .. .. data:: KRB5_KEYUSAGE_PA_FX_COOKIE .. Used for encrypted FAST cookies. ================================= ====================== ``KRB5_KEYUSAGE_PA_FX_COOKIE`` ``513`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/TKT_FLG_FORWARDED.rst.txt0000664000175000017500000000040515051422642025476 0ustar ghudsonghudson.. highlight:: c .. _TKT-FLG-FORWARDED-data: TKT_FLG_FORWARDED ================= .. .. data:: TKT_FLG_FORWARDED .. ======================== ====================== ``TKT_FLG_FORWARDED`` ``0x20000000`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_MATCH_TIMES.rst.txt0000664000175000017500000000053315051422642025717 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-MATCH-TIMES-data: KRB5_TC_MATCH_TIMES =================== .. .. data:: KRB5_TC_MATCH_TIMES .. The requested lifetime must be at least as great as the time specified. ========================== ====================== ``KRB5_TC_MATCH_TIMES`` ``0x00000001`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_GC_CONSTRAINED_DELEGATION.rst.txt0000664000175000017500000000056015051422642027351 0ustar ghudsonghudson.. highlight:: c .. _KRB5-GC-CONSTRAINED-DELEGATION-data: KRB5_GC_CONSTRAINED_DELEGATION ============================== .. .. data:: KRB5_GC_CONSTRAINED_DELEGATION .. Constrained delegation. ===================================== ====================== ``KRB5_GC_CONSTRAINED_DELEGATION`` ``64`` ===================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_RSA_MD5_DES.rst.txt0000664000175000017500000000043515051422642026203 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-RSA-MD5-DES-data: CKSUMTYPE_RSA_MD5_DES ===================== .. .. data:: CKSUMTYPE_RSA_MD5_DES .. ============================ ====================== ``CKSUMTYPE_RSA_MD5_DES`` ``0x0008`` ============================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_CAMMAC.rst.txt0000664000175000017500000000042215051422642025725 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-CAMMAC-data: KRB5_AUTHDATA_CAMMAC ==================== .. .. data:: KRB5_AUTHDATA_CAMMAC .. =========================== ====================== ``KRB5_AUTHDATA_CAMMAC`` ``96`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/AD_TYPE_RESERVED.rst.txt0000664000175000017500000000037215051422642025376 0ustar ghudsonghudson.. highlight:: c .. _AD-TYPE-RESERVED-data: AD_TYPE_RESERVED ================ .. .. data:: AD_TYPE_RESERVED .. ======================= ====================== ``AD_TYPE_RESERVED`` ``0x8000`` ======================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AUTHDATA_MANDATORY_FOR_KDC.rst.txt0000664000175000017500000000053615051422642027537 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AUTHDATA-MANDATORY-FOR-KDC-data: KRB5_AUTHDATA_MANDATORY_FOR_KDC =============================== .. .. data:: KRB5_AUTHDATA_MANDATORY_FOR_KDC .. ====================================== ====================== ``KRB5_AUTHDATA_MANDATORY_FOR_KDC`` ``8`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_RSA_MD5.rst.txt0000664000175000017500000000040115051422642025501 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-RSA-MD5-data: CKSUMTYPE_RSA_MD5 ================= .. .. data:: CKSUMTYPE_RSA_MD5 .. ======================== ====================== ``CKSUMTYPE_RSA_MD5`` ``0x0007`` ======================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_LRQ_ALL_LAST_INITIAL.rst.txt0000664000175000017500000000046415051422642026661 0ustar ghudsonghudson.. highlight:: c .. _KRB5-LRQ-ALL-LAST-INITIAL-data: KRB5_LRQ_ALL_LAST_INITIAL ========================= .. .. data:: KRB5_LRQ_ALL_LAST_INITIAL .. ================================ ====================== ``KRB5_LRQ_ALL_LAST_INITIAL`` ``2`` ================================ ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_MATCH_FLAGS.rst.txt0000664000175000017500000000051315051422642025670 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-MATCH-FLAGS-data: KRB5_TC_MATCH_FLAGS =================== .. .. data:: KRB5_TC_MATCH_FLAGS .. All the flags set in the match credentials must be set. ========================== ====================== ``KRB5_TC_MATCH_FLAGS`` ``0x00000004`` ========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PAC_DEVICE_INFO.rst.txt0000664000175000017500000000044615051422642025774 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PAC-DEVICE-INFO-data: KRB5_PAC_DEVICE_INFO ==================== .. .. data:: KRB5_PAC_DEVICE_INFO .. Device information. =========================== ====================== ``KRB5_PAC_DEVICE_INFO`` ``14`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE_2.rst.txt0000664000175000017500000000053415051422642026726 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PADATA-SAM-RESPONSE-2-data: KRB5_PADATA_SAM_RESPONSE_2 ========================== .. .. data:: KRB5_PADATA_SAM_RESPONSE_2 .. draft challenge system, updated ================================= ====================== ``KRB5_PADATA_SAM_RESPONSE_2`` ``31`` ================================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_NO_REALM.rst.txt0000664000175000017500000000056315051422642027571 0ustar ghudsonghudson.. highlight:: c .. _KRB5-PRINCIPAL-UNPARSE-NO-REALM-data: KRB5_PRINCIPAL_UNPARSE_NO_REALM =============================== .. .. data:: KRB5_PRINCIPAL_UNPARSE_NO_REALM .. Omit realm always. ====================================== ====================== ``KRB5_PRINCIPAL_UNPARSE_NO_REALM`` ``0x2`` ====================================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/CKSUMTYPE_SHA1.rst.txt0000664000175000017500000000036615051422642025115 0ustar ghudsonghudson.. highlight:: c .. _CKSUMTYPE-SHA1-data: CKSUMTYPE_SHA1 ============== .. .. data:: CKSUMTYPE_SHA1 .. RFC 3961. ===================== ====================== ``CKSUMTYPE_SHA1`` ``0x000e`` ===================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_TC_SUPPORTED_KTYPES.rst.txt0000664000175000017500000000053215051422642026605 0ustar ghudsonghudson.. highlight:: c .. _KRB5-TC-SUPPORTED-KTYPES-data: KRB5_TC_SUPPORTED_KTYPES ======================== .. .. data:: KRB5_TC_SUPPORTED_KTYPES .. The supported key types must match. =============================== ====================== ``KRB5_TC_SUPPORTED_KTYPES`` ``0x00000200`` =============================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_AS_REP.rst.txt0000664000175000017500000000037315051422642024547 0ustar ghudsonghudson.. highlight:: c .. _KRB5-AS-REP-data: KRB5_AS_REP =========== .. .. data:: KRB5_AS_REP .. Response to AS request. ================== ====================== ``KRB5_AS_REP`` ``((krb5_msgtype)11)`` ================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_KEYUSAGE_FAST_ENC.rst.txt0000664000175000017500000000044015051422642026250 0ustar ghudsonghudson.. highlight:: c .. _KRB5-KEYUSAGE-FAST-ENC-data: KRB5_KEYUSAGE_FAST_ENC ====================== .. .. data:: KRB5_KEYUSAGE_FAST_ENC .. ============================= ====================== ``KRB5_KEYUSAGE_FAST_ENC`` ``51`` ============================= ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_UID.rst.txt0000664000175000017500000000033515051422642024556 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-UID-data: KRB5_NT_UID =========== .. .. data:: KRB5_NT_UID .. Unique ID. ================== ====================== ``KRB5_NT_UID`` ``5`` ================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KRB5_NT_UNKNOWN.rst.txt0000664000175000017500000000040315051422642025270 0ustar ghudsonghudson.. highlight:: c .. _KRB5-NT-UNKNOWN-data: KRB5_NT_UNKNOWN =============== .. .. data:: KRB5_NT_UNKNOWN .. Name type not known. ====================== ====================== ``KRB5_NT_UNKNOWN`` ``0`` ====================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/macros/KDC_OPT_CANONICALIZE.rst.txt0000664000175000017500000000043215051422642026011 0ustar ghudsonghudson.. highlight:: c .. _KDC-OPT-CANONICALIZE-data: KDC_OPT_CANONICALIZE ==================== .. .. data:: KDC_OPT_CANONICALIZE .. =========================== ====================== ``KDC_OPT_CANONICALIZE`` ``0x00010000`` =========================== ====================== krb5-1.22.1/doc/html/_sources/appdev/refs/types/0000775000175000017500000000000015051422713021257 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_pre_send_fn.rst.txt0000664000175000017500000000163415051422642026041 0ustar ghudsonghudson.. highlight:: c .. _krb5-pre-send-fn-struct: krb5_pre_send_fn ================ .. .. c:type:: krb5_pre_send_fn .. Hook function for inspecting or modifying messages sent to KDCs. If the hook function sets *new_reply_out* , *message* will not be sent to the KDC, and the given reply will used instead. If the hook function sets *new_message_out* , the given message will be sent to the KDC in place of *message* . If the hook function returns successfully without setting either output, *message* will be sent to the KDC normally. The hook function should use krb5_copy_data() to construct the value for *new_message_out* or *reply_out* , to ensure that it can be freed correctly by the library. Declaration ------------ typedef krb5_error_code( \* krb5_pre_send_fn) (krb5_context context, void \*data, const krb5_data \*realm, const krb5_data \*message, krb5_data \*\*new_message_out, krb5_data \*\*new_reply_out) krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_replay_data.rst.txt0000664000175000017500000000146715051422642026050 0ustar ghudsonghudson.. highlight:: c .. _krb5-replay-data-struct: krb5_replay_data ================ .. .. c:type:: krb5_replay_data .. Replay data. Sequence number and timestamp information output by krb5_rd_priv() and krb5_rd_safe(). Declaration ------------ typedef struct krb5_replay_data krb5_replay_data Members --------- .. c:member:: krb5_timestamp krb5_replay_data.timestamp Timestamp, seconds portion. .. c:member:: krb5_int32 krb5_replay_data.usec Timestamp, microseconds portion. .. c:member:: krb5_ui_4 krb5_replay_data.seq Sequence number. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_cryptotype.rst.txt0000664000175000017500000000026515051422642026000 0ustar ghudsonghudson.. highlight:: c .. _krb5-cryptotype-struct: krb5_cryptotype =============== .. .. c:type:: krb5_cryptotype .. Declaration ------------ typedef krb5_int32 krb5_cryptotype krb5-1.22.1/doc/html/_sources/appdev/refs/types/index.rst.txt0000664000175000017500000000436615051422642023750 0ustar ghudsonghudsonkrb5 types and structures ========================= Public ------- .. toctree:: :maxdepth: 1 krb5_address.rst krb5_addrtype.rst krb5_ap_req.rst krb5_ap_rep.rst krb5_ap_rep_enc_part.rst krb5_authdata.rst krb5_authdatatype.rst krb5_authenticator.rst krb5_boolean.rst krb5_checksum.rst krb5_const_pointer.rst krb5_const_principal.rst krb5_cred.rst krb5_cred_enc_part.rst krb5_cred_info.rst krb5_creds.rst krb5_crypto_iov.rst krb5_cryptotype.rst krb5_data.rst krb5_deltat.rst krb5_enc_data.rst krb5_enc_kdc_rep_part.rst krb5_enc_tkt_part.rst krb5_encrypt_block.rst krb5_enctype.rst krb5_error.rst krb5_error_code.rst krb5_expire_callback_func.rst krb5_flags.rst krb5_get_init_creds_opt.rst krb5_gic_opt_pa_data.rst krb5_int16.rst krb5_int32.rst krb5_kdc_rep.rst krb5_kdc_req.rst krb5_keyblock.rst krb5_keytab_entry.rst krb5_keyusage.rst krb5_kt_cursor.rst krb5_kvno.rst krb5_last_req_entry.rst krb5_magic.rst krb5_mk_req_checksum_func.rst krb5_msgtype.rst krb5_octet.rst krb5_pa_pac_req.rst krb5_pa_server_referral_data.rst krb5_pa_svr_referral_data.rst krb5_pa_data.rst krb5_pointer.rst krb5_post_recv_fn.rst krb5_pre_send_fn.rst krb5_preauthtype.rst krb5_principal.rst krb5_principal_data.rst krb5_prompt.rst krb5_prompt_type.rst krb5_prompter_fct.rst krb5_pwd_data.rst krb5_responder_context.rst krb5_responder_fn.rst krb5_responder_otp_challenge.rst krb5_responder_otp_tokeninfo.rst krb5_responder_pkinit_challenge.rst krb5_responder_pkinit_identity.rst krb5_response.rst krb5_replay_data.rst krb5_ticket.rst krb5_ticket_times.rst krb5_timestamp.rst krb5_tkt_authent.rst krb5_trace_callback.rst krb5_trace_info.rst krb5_transited.rst krb5_typed_data.rst krb5_ui_2.rst krb5_ui_4.rst krb5_verify_init_creds_opt.rst passwd_phrase_element.rst Internal --------- .. toctree:: :maxdepth: 1 krb5_auth_context.rst krb5_cksumtype krb5_context.rst krb5_cc_cursor.rst krb5_ccache.rst krb5_cccol_cursor.rst krb5_init_creds_context.rst krb5_key.rst krb5_keytab.rst krb5_pac.rst krb5_rcache.rst krb5_tkt_creds_context.rst krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_last_req_entry.rst.txt0000664000175000017500000000131515051422642026606 0ustar ghudsonghudson.. highlight:: c .. _krb5-last-req-entry-struct: krb5_last_req_entry =================== .. .. c:type:: krb5_last_req_entry .. Last request entry. Declaration ------------ typedef struct _krb5_last_req_entry krb5_last_req_entry Members --------- .. c:member:: krb5_magic krb5_last_req_entry.magic .. c:member:: krb5_int32 krb5_last_req_entry.lr_type LR type. .. c:member:: krb5_timestamp krb5_last_req_entry.value Timestamp. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_gic_opt_pa_data.rst.txt0000664000175000017500000000107515051422642026653 0ustar ghudsonghudson.. highlight:: c .. _krb5-gic-opt-pa-data-struct: krb5_gic_opt_pa_data ==================== .. .. c:type:: krb5_gic_opt_pa_data .. Generic preauth option attribute/value pairs. Declaration ------------ typedef struct _krb5_gic_opt_pa_data krb5_gic_opt_pa_data Members --------- .. c:member:: char * krb5_gic_opt_pa_data.attr .. c:member:: char * krb5_gic_opt_pa_data.value krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_key.rst.txt0000664000175000017500000000065615051422642024352 0ustar ghudsonghudson.. highlight:: c .. _krb5-key-struct: krb5_key ======== .. .. c:type:: krb5_key .. Opaque identifier for a key. Use with the krb5_k APIs for better performance for repeated operations with the same key and usage. Key identifiers must not be used simultaneously within multiple threads, as they may contain mutable internal state and are not mutex-protected. Declaration ------------ typedef struct krb5_key_st\* krb5_key krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_verify_init_creds_opt.rst.txt0000664000175000017500000000112015051422642030136 0ustar ghudsonghudson.. highlight:: c .. _krb5-verify-init-creds-opt-struct: krb5_verify_init_creds_opt ========================== .. .. c:type:: krb5_verify_init_creds_opt .. Declaration ------------ typedef struct _krb5_verify_init_creds_opt krb5_verify_init_creds_opt Members --------- .. c:member:: krb5_flags krb5_verify_init_creds_opt.flags .. c:member:: int krb5_verify_init_creds_opt.ap_req_nofail boolean krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_mk_req_checksum_func.rst.txt0000664000175000017500000000056615051422642027735 0ustar ghudsonghudson.. highlight:: c .. _krb5-mk-req-checksum-func-struct: krb5_mk_req_checksum_func ========================= .. .. c:type:: krb5_mk_req_checksum_func .. Type of function used as a callback to generate checksum data for mk_req. Declaration ------------ typedef krb5_error_code( \* krb5_mk_req_checksum_func) (krb5_context, krb5_auth_context, void \*, krb5_data \*\*) krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_cred_enc_part.rst.txt0000664000175000017500000000265615051422642026354 0ustar ghudsonghudson.. highlight:: c .. _krb5-cred-enc-part-struct: krb5_cred_enc_part ================== .. .. c:type:: krb5_cred_enc_part .. Cleartext credentials information. Declaration ------------ typedef struct _krb5_cred_enc_part krb5_cred_enc_part Members --------- .. c:member:: krb5_magic krb5_cred_enc_part.magic .. c:member:: krb5_int32 krb5_cred_enc_part.nonce Nonce (optional) .. c:member:: krb5_timestamp krb5_cred_enc_part.timestamp Generation time, seconds portion. .. c:member:: krb5_int32 krb5_cred_enc_part.usec Generation time, microseconds portion. .. c:member:: krb5_address * krb5_cred_enc_part.s_address Sender address (optional) .. c:member:: krb5_address * krb5_cred_enc_part.r_address Recipient address (optional) .. c:member:: krb5_cred_info ** krb5_cred_enc_part.ticket_info krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_addrtype.rst.txt0000664000175000017500000000025315051422642025367 0ustar ghudsonghudson.. highlight:: c .. _krb5-addrtype-struct: krb5_addrtype ============= .. .. c:type:: krb5_addrtype .. Declaration ------------ typedef krb5_int32 krb5_addrtype krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_timestamp.rst.txt0000664000175000017500000000100115051422642025546 0ustar ghudsonghudson.. highlight:: c .. _krb5-timestamp-struct: krb5_timestamp ============== .. .. c:type:: krb5_timestamp .. Represents a timestamp in seconds since the POSIX epoch. This legacy type is used frequently in the ABI, but cannot represent timestamps after 2038 as a positive number. Code which uses this type should cast values of it to uint32_t so that negative values are treated as timestamps between 2038 and 2106 on platforms with 64-bit time_t. Declaration ------------ typedef krb5_int32 krb5_timestamp krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_ticket_times.rst.txt0000664000175000017500000000207115051422642026237 0ustar ghudsonghudson.. highlight:: c .. _krb5-ticket-times-struct: krb5_ticket_times ================= .. .. c:type:: krb5_ticket_times .. Ticket start time, end time, and renewal duration. Declaration ------------ typedef struct _krb5_ticket_times krb5_ticket_times Members --------- .. c:member:: krb5_timestamp krb5_ticket_times.authtime Time at which KDC issued the initial ticket that corresponds to this ticket. .. c:member:: krb5_timestamp krb5_ticket_times.starttime optional in ticket, if not present, use *authtime* .. c:member:: krb5_timestamp krb5_ticket_times.endtime Ticket expiration time. .. c:member:: krb5_timestamp krb5_ticket_times.renew_till Latest time at which renewal of ticket can be valid. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_magic.rst.txt0000664000175000017500000000024115051422642024630 0ustar ghudsonghudson.. highlight:: c .. _krb5-magic-struct: krb5_magic ========== .. .. c:type:: krb5_magic .. Declaration ------------ typedef krb5_error_code krb5_magic krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_cred.rst.txt0000664000175000017500000000147715051422642024501 0ustar ghudsonghudson.. highlight:: c .. _krb5-cred-struct: krb5_cred ========= .. .. c:type:: krb5_cred .. Credentials data structure. Declaration ------------ typedef struct _krb5_cred krb5_cred Members --------- .. c:member:: krb5_magic krb5_cred.magic .. c:member:: krb5_ticket ** krb5_cred.tickets Tickets. .. c:member:: krb5_enc_data krb5_cred.enc_part Encrypted part. .. c:member:: krb5_cred_enc_part * krb5_cred.enc_part2 Unencrypted version, if available. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_principal_data.rst.txt0000664000175000017500000000172615051422642026533 0ustar ghudsonghudson.. highlight:: c .. _krb5-principal-data-struct: krb5_principal_data =================== .. .. c:type:: krb5_principal_data .. Declaration ------------ typedef struct krb5_principal_data krb5_principal_data Members --------- .. c:member:: krb5_magic krb5_principal_data.magic .. c:member:: krb5_data krb5_principal_data.realm .. c:member:: krb5_data * krb5_principal_data.data An array of strings. .. c:member:: krb5_int32 krb5_principal_data.length .. c:member:: krb5_int32 krb5_principal_data.type krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_const_principal.rst.txt0000664000175000017500000000202515051422642026741 0ustar ghudsonghudson.. highlight:: c .. _krb5-const-principal-struct: krb5_const_principal ==================== .. .. c:type:: krb5_const_principal .. Constant version of :c:type:`krb5_principal_data` . Declaration ------------ typedef const krb5_principal_data\* krb5_const_principal Members --------- .. c:member:: krb5_magic krb5_const_principal.magic .. c:member:: krb5_data krb5_const_principal.realm .. c:member:: krb5_data * krb5_const_principal.data An array of strings. .. c:member:: krb5_int32 krb5_const_principal.length .. c:member:: krb5_int32 krb5_const_principal.type krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_pa_pac_req.rst.txt0000664000175000017500000000062715051422642025652 0ustar ghudsonghudson.. highlight:: c .. _krb5-pa-pac-req-struct: krb5_pa_pac_req =============== .. .. c:type:: krb5_pa_pac_req .. Declaration ------------ typedef struct _krb5_pa_pac_req krb5_pa_pac_req Members --------- .. c:member:: krb5_boolean krb5_pa_pac_req.include_pac TRUE if a PAC should be included in TGS-REP. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_authdata.rst.txt0000664000175000017500000000147315051422642025353 0ustar ghudsonghudson.. highlight:: c .. _krb5-authdata-struct: krb5_authdata ============= .. .. c:type:: krb5_authdata .. Structure for auth data. Declaration ------------ typedef struct _krb5_authdata krb5_authdata Members --------- .. c:member:: krb5_magic krb5_authdata.magic .. c:member:: krb5_authdatatype krb5_authdata.ad_type ADTYPE. .. c:member:: unsigned int krb5_authdata.length Length of data. .. c:member:: krb5_octet * krb5_authdata.contents Data. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_enc_tkt_part.rst.txt0000664000175000017500000000306515051422642026234 0ustar ghudsonghudson.. highlight:: c .. _krb5-enc-tkt-part-struct: krb5_enc_tkt_part ================= .. .. c:type:: krb5_enc_tkt_part .. Encrypted part of ticket. Declaration ------------ typedef struct _krb5_enc_tkt_part krb5_enc_tkt_part Members --------- .. c:member:: krb5_magic krb5_enc_tkt_part.magic .. c:member:: krb5_flags krb5_enc_tkt_part.flags flags .. c:member:: krb5_keyblock * krb5_enc_tkt_part.session session key: includes enctype .. c:member:: krb5_principal krb5_enc_tkt_part.client client name/realm .. c:member:: krb5_transited krb5_enc_tkt_part.transited list of transited realms .. c:member:: krb5_ticket_times krb5_enc_tkt_part.times auth, start, end, renew_till .. c:member:: krb5_address ** krb5_enc_tkt_part.caddrs array of ptrs to addresses .. c:member:: krb5_authdata ** krb5_enc_tkt_part.authorization_data auth data krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_creds.rst.txt0000664000175000017500000000407215051422642024656 0ustar ghudsonghudson.. highlight:: c .. _krb5-creds-struct: krb5_creds ========== .. .. c:type:: krb5_creds .. Credentials structure including ticket, session key, and lifetime info. Declaration ------------ typedef struct _krb5_creds krb5_creds Members --------- .. c:member:: krb5_magic krb5_creds.magic .. c:member:: krb5_principal krb5_creds.client client's principal identifier .. c:member:: krb5_principal krb5_creds.server server's principal identifier .. c:member:: krb5_keyblock krb5_creds.keyblock session encryption key info .. c:member:: krb5_ticket_times krb5_creds.times lifetime info .. c:member:: krb5_boolean krb5_creds.is_skey true if ticket is encrypted in another ticket's skey .. c:member:: krb5_flags krb5_creds.ticket_flags flags in ticket .. c:member:: krb5_address ** krb5_creds.addresses addrs in ticket .. c:member:: krb5_data krb5_creds.ticket ticket string itself .. c:member:: krb5_data krb5_creds.second_ticket second ticket, if related to ticket (via DUPLICATE-SKEY or ENC-TKT-IN-SKEY) .. c:member:: krb5_authdata ** krb5_creds.authdata authorization data krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_kt_cursor.rst.txt0000664000175000017500000000026215051422642025566 0ustar ghudsonghudson.. highlight:: c .. _krb5-kt-cursor-struct: krb5_kt_cursor ============== .. .. c:type:: krb5_kt_cursor .. Declaration ------------ typedef krb5_pointer krb5_kt_cursor krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_preauthtype.rst.txt0000664000175000017500000000027215051422642026126 0ustar ghudsonghudson.. highlight:: c .. _krb5-preauthtype-struct: krb5_preauthtype ================ .. .. c:type:: krb5_preauthtype .. Declaration ------------ typedef krb5_int32 krb5_preauthtype krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_deltat.rst.txt0000664000175000017500000000024115051422642025025 0ustar ghudsonghudson.. highlight:: c .. _krb5-deltat-struct: krb5_deltat =========== .. .. c:type:: krb5_deltat .. Declaration ------------ typedef krb5_int32 krb5_deltat krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_authdatatype.rst.txt0000664000175000017500000000027715051422642026256 0ustar ghudsonghudson.. highlight:: c .. _krb5-authdatatype-struct: krb5_authdatatype ================= .. .. c:type:: krb5_authdatatype .. Declaration ------------ typedef krb5_int32 krb5_authdatatype krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_kvno.rst.txt0000664000175000017500000000023115051422642024524 0ustar ghudsonghudson.. highlight:: c .. _krb5-kvno-struct: krb5_kvno ========= .. .. c:type:: krb5_kvno .. Declaration ------------ typedef unsigned int krb5_kvno krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_trace_info.rst.txt0000664000175000017500000000113415051422642025663 0ustar ghudsonghudson.. highlight:: c .. _krb5-trace-info-struct: krb5_trace_info =============== .. .. c:type:: krb5_trace_info .. A wrapper for passing information to a *krb5_trace_callback* . Currently, it only contains the formatted message as determined the the format string and arguments of the tracing macro, but it may be extended to contain more fields in the future. Declaration ------------ typedef struct _krb5_trace_info krb5_trace_info Members --------- .. c:member:: const char * krb5_trace_info.message krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_cc_cursor.rst.txt0000664000175000017500000000032015051422642025530 0ustar ghudsonghudson.. highlight:: c .. _krb5-cc-cursor-struct: krb5_cc_cursor ============== .. .. c:type:: krb5_cc_cursor .. Cursor for sequential lookup. Declaration ------------ typedef krb5_pointer krb5_cc_cursor krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_cred_info.rst.txt0000664000175000017500000000264515051422642025512 0ustar ghudsonghudson.. highlight:: c .. _krb5-cred-info-struct: krb5_cred_info ============== .. .. c:type:: krb5_cred_info .. Credentials information inserted into *EncKrbCredPart* . Declaration ------------ typedef struct _krb5_cred_info krb5_cred_info Members --------- .. c:member:: krb5_magic krb5_cred_info.magic .. c:member:: krb5_keyblock * krb5_cred_info.session Session key used to encrypt ticket. .. c:member:: krb5_principal krb5_cred_info.client Client principal and realm. .. c:member:: krb5_principal krb5_cred_info.server Server principal and realm. .. c:member:: krb5_flags krb5_cred_info.flags Ticket flags. .. c:member:: krb5_ticket_times krb5_cred_info.times Auth, start, end, renew_till. .. c:member:: krb5_address ** krb5_cred_info.caddrs Array of pointers to addrs (optional) krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_pac.rst.txt0000664000175000017500000000032615051422642024317 0ustar ghudsonghudson.. highlight:: c .. _krb5-pac-struct: krb5_pac ======== .. .. c:type:: krb5_pac .. PAC data structure to convey authorization information. Declaration ------------ typedef struct krb5_pac_data\* krb5_pac krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_int16.rst.txt0000664000175000017500000000023115051422642024510 0ustar ghudsonghudson.. highlight:: c .. _krb5-int16-struct: krb5_int16 ========== .. .. c:type:: krb5_int16 .. Declaration ------------ typedef int16_t krb5_int16 krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_enctype.rst.txt0000664000175000017500000000024615051422642025224 0ustar ghudsonghudson.. highlight:: c .. _krb5-enctype-struct: krb5_enctype ============ .. .. c:type:: krb5_enctype .. Declaration ------------ typedef krb5_int32 krb5_enctype krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_responder_context.rst.txt0000664000175000017500000000133115051422642027316 0ustar ghudsonghudson.. highlight:: c .. _krb5-responder-context-struct: krb5_responder_context ====================== .. .. c:type:: krb5_responder_context .. A container for a set of preauthentication questions and answers. A responder context is supplied by the krb5 authentication system to a krb5_responder_fn callback. It contains a list of questions and can receive answers. Questions contained in a responder context can be listed using krb5_responder_list_questions(), retrieved using krb5_responder_get_challenge(), or answered using krb5_responder_set_answer(). The form of a question's challenge and answer depend on the question name. Declaration ------------ typedef struct krb5_responder_context_st\* krb5_responder_context krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_encrypt_block.rst.txt0000664000175000017500000000124515051422642026413 0ustar ghudsonghudson.. highlight:: c .. _krb5-encrypt-block-struct: krb5_encrypt_block ================== .. .. c:type:: krb5_encrypt_block .. Declaration ------------ typedef struct _krb5_encrypt_block krb5_encrypt_block Members --------- .. c:member:: krb5_magic krb5_encrypt_block.magic .. c:member:: krb5_enctype krb5_encrypt_block.crypto_entry .. c:member:: krb5_keyblock * krb5_encrypt_block.key krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_octet.rst.txt0000664000175000017500000000023115051422642024665 0ustar ghudsonghudson.. highlight:: c .. _krb5-octet-struct: krb5_octet ========== .. .. c:type:: krb5_octet .. Declaration ------------ typedef uint8_t krb5_octet krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_responder_pkinit_challenge.rst.txt0000664000175000017500000000076015051422642031137 0ustar ghudsonghudson.. highlight:: c .. _krb5-responder-pkinit-challenge-struct: krb5_responder_pkinit_challenge =============================== .. .. c:type:: krb5_responder_pkinit_challenge .. Declaration ------------ typedef struct _krb5_responder_pkinit_challenge krb5_responder_pkinit_challenge Members --------- .. c:member:: krb5_responder_pkinit_identity ** krb5_responder_pkinit_challenge.identities krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_flags.rst.txt0000664000175000017500000000023415051422642024646 0ustar ghudsonghudson.. highlight:: c .. _krb5-flags-struct: krb5_flags ========== .. .. c:type:: krb5_flags .. Declaration ------------ typedef krb5_int32 krb5_flags krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_boolean.rst.txt0000664000175000017500000000025015051422642025167 0ustar ghudsonghudson.. highlight:: c .. _krb5-boolean-struct: krb5_boolean ============ .. .. c:type:: krb5_boolean .. Declaration ------------ typedef unsigned int krb5_boolean krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_crypto_iov.rst.txt0000664000175000017500000000175115051422642025754 0ustar ghudsonghudson.. highlight:: c .. _krb5-crypto-iov-struct: krb5_crypto_iov =============== .. .. c:type:: krb5_crypto_iov .. Structure to describe a region of text to be encrypted or decrypted. The *flags* member describes the type of the iov. The *data* member points to the memory that will be manipulated. All iov APIs take a pointer to the first element of an array of krb5_crypto_iov's along with the size of that array. Buffer contents are manipulated in-place; data is overwritten. Callers must allocate the right number of krb5_crypto_iov structures before calling into an iov API. Declaration ------------ typedef struct _krb5_crypto_iov krb5_crypto_iov Members --------- .. c:member:: krb5_cryptotype krb5_crypto_iov.flags iov type (see KRB5_CRYPTO_TYPE macros) .. c:member:: krb5_data krb5_crypto_iov.data krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_keytab.rst.txt0000664000175000017500000000025015051422642025027 0ustar ghudsonghudson.. highlight:: c .. _krb5-keytab-struct: krb5_keytab =========== .. .. c:type:: krb5_keytab .. Declaration ------------ typedef struct _krb5_kt\* krb5_keytab krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_responder_pkinit_identity.rst.txt0000664000175000017500000000115515051422642031045 0ustar ghudsonghudson.. highlight:: c .. _krb5-responder-pkinit-identity-struct: krb5_responder_pkinit_identity ============================== .. .. c:type:: krb5_responder_pkinit_identity .. Declaration ------------ typedef struct _krb5_responder_pkinit_identity krb5_responder_pkinit_identity Members --------- .. c:member:: char * krb5_responder_pkinit_identity.identity .. c:member:: krb5_int32 krb5_responder_pkinit_identity.token_flags krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_ui_2.rst.txt0000664000175000017500000000022515051422642024410 0ustar ghudsonghudson.. highlight:: c .. _krb5-ui-2-struct: krb5_ui_2 ========= .. .. c:type:: krb5_ui_2 .. Declaration ------------ typedef uint16_t krb5_ui_2 krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_principal.rst.txt0000664000175000017500000000163715051422642025543 0ustar ghudsonghudson.. highlight:: c .. _krb5-principal-struct: krb5_principal ============== .. .. c:type:: krb5_principal .. Declaration ------------ typedef krb5_principal_data\* krb5_principal Members --------- .. c:member:: krb5_magic krb5_principal.magic .. c:member:: krb5_data krb5_principal.realm .. c:member:: krb5_data * krb5_principal.data An array of strings. .. c:member:: krb5_int32 krb5_principal.length .. c:member:: krb5_int32 krb5_principal.type krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_tkt_creds_context.rst.txt0000664000175000017500000000035615051422642027305 0ustar ghudsonghudson.. highlight:: c .. _krb5-tkt-creds-context-struct: krb5_tkt_creds_context ====================== .. .. c:type:: krb5_tkt_creds_context .. Declaration ------------ typedef struct _krb5_tkt_creds_context\* krb5_tkt_creds_context krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_keyusage.rst.txt0000664000175000017500000000025315051422642025370 0ustar ghudsonghudson.. highlight:: c .. _krb5-keyusage-struct: krb5_keyusage ============= .. .. c:type:: krb5_keyusage .. Declaration ------------ typedef krb5_int32 krb5_keyusage krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_post_recv_fn.rst.txt0000664000175000017500000000142415051422642026243 0ustar ghudsonghudson.. highlight:: c .. _krb5-post-recv-fn-struct: krb5_post_recv_fn ================= .. .. c:type:: krb5_post_recv_fn .. Hook function for inspecting or overriding KDC replies. If *code* is non-zero, KDC communication failed and *reply* should be ignored. The hook function may return *code* or a different error code, or may synthesize a reply by setting *new_reply_out* and return successfully. The hook function should use krb5_copy_data() to construct the value for *new_reply_out* , to ensure that it can be freed correctly by the library. Declaration ------------ typedef krb5_error_code( \* krb5_post_recv_fn) (krb5_context context, void \*data, krb5_error_code code, const krb5_data \*realm, const krb5_data \*message, const krb5_data \*reply, krb5_data \*\*new_reply_out) krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_tkt_authent.rst.txt0000664000175000017500000000151515051422642026107 0ustar ghudsonghudson.. highlight:: c .. _krb5-tkt-authent-struct: krb5_tkt_authent ================ .. .. c:type:: krb5_tkt_authent .. Ticket authentication data. Declaration ------------ typedef struct _krb5_tkt_authent krb5_tkt_authent Members --------- .. c:member:: krb5_magic krb5_tkt_authent.magic .. c:member:: krb5_ticket * krb5_tkt_authent.ticket .. c:member:: krb5_authenticator * krb5_tkt_authent.authenticator .. c:member:: krb5_flags krb5_tkt_authent.ap_options krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_init_creds_context.rst.txt0000664000175000017500000000036415051422642027445 0ustar ghudsonghudson.. highlight:: c .. _krb5-init-creds-context-struct: krb5_init_creds_context ======================= .. .. c:type:: krb5_init_creds_context .. Declaration ------------ typedef struct _krb5_init_creds_context\* krb5_init_creds_context krb5-1.22.1/doc/html/_sources/appdev/refs/types/passwd_phrase_element.rst.txt0000664000175000017500000000127115051422642027205 0ustar ghudsonghudson.. highlight:: c .. _passwd-phrase-element-struct: passwd_phrase_element ===================== .. .. c:type:: passwd_phrase_element .. Declaration ------------ typedef struct _passwd_phrase_element passwd_phrase_element Members --------- .. c:member:: krb5_magic passwd_phrase_element.magic .. c:member:: krb5_data * passwd_phrase_element.passwd .. c:member:: krb5_data * passwd_phrase_element.phrase krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_int32.rst.txt0000664000175000017500000000023115051422642024506 0ustar ghudsonghudson.. highlight:: c .. _krb5-int32-struct: krb5_int32 ========== .. .. c:type:: krb5_int32 .. Declaration ------------ typedef int32_t krb5_int32 krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_pa_server_referral_data.rst.txt0000664000175000017500000000216415051422642030417 0ustar ghudsonghudson.. highlight:: c .. _krb5-pa-server-referral-data-struct: krb5_pa_server_referral_data ============================ .. .. c:type:: krb5_pa_server_referral_data .. Declaration ------------ typedef struct _krb5_pa_server_referral_data krb5_pa_server_referral_data Members --------- .. c:member:: krb5_data * krb5_pa_server_referral_data.referred_realm .. c:member:: krb5_principal krb5_pa_server_referral_data.true_principal_name .. c:member:: krb5_principal krb5_pa_server_referral_data.requested_principal_name .. c:member:: krb5_timestamp krb5_pa_server_referral_data.referral_valid_until .. c:member:: krb5_checksum krb5_pa_server_referral_data.rep_cksum krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_responder_otp_challenge.rst.txt0000664000175000017500000000116015051422642030436 0ustar ghudsonghudson.. highlight:: c .. _krb5-responder-otp-challenge-struct: krb5_responder_otp_challenge ============================ .. .. c:type:: krb5_responder_otp_challenge .. Declaration ------------ typedef struct _krb5_responder_otp_challenge krb5_responder_otp_challenge Members --------- .. c:member:: char * krb5_responder_otp_challenge.service .. c:member:: krb5_responder_otp_tokeninfo ** krb5_responder_otp_challenge.tokeninfo krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_ui_4.rst.txt0000664000175000017500000000022515051422642024412 0ustar ghudsonghudson.. highlight:: c .. _krb5-ui-4-struct: krb5_ui_4 ========= .. .. c:type:: krb5_ui_4 .. Declaration ------------ typedef uint32_t krb5_ui_4 krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_auth_context.rst.txt0000664000175000017500000000032015051422642026253 0ustar ghudsonghudson.. highlight:: c .. _krb5-auth-context-struct: krb5_auth_context ================= .. .. c:type:: krb5_auth_context .. Declaration ------------ typedef struct _krb5_auth_context\* krb5_auth_context krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_responder_otp_tokeninfo.rst.txt0000664000175000017500000000252515051422642030516 0ustar ghudsonghudson.. highlight:: c .. _krb5-responder-otp-tokeninfo-struct: krb5_responder_otp_tokeninfo ============================ .. .. c:type:: krb5_responder_otp_tokeninfo .. Declaration ------------ typedef struct _krb5_responder_otp_tokeninfo krb5_responder_otp_tokeninfo Members --------- .. c:member:: krb5_flags krb5_responder_otp_tokeninfo.flags .. c:member:: krb5_int32 krb5_responder_otp_tokeninfo.format .. c:member:: krb5_int32 krb5_responder_otp_tokeninfo.length .. c:member:: char * krb5_responder_otp_tokeninfo.vendor .. c:member:: char * krb5_responder_otp_tokeninfo.challenge .. c:member:: char * krb5_responder_otp_tokeninfo.token_id .. c:member:: char * krb5_responder_otp_tokeninfo.alg_id krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_cksumtype.rst.txt0000664000175000017500000000026015051422642025575 0ustar ghudsonghudson.. highlight:: c .. _krb5-cksumtype-struct: krb5_cksumtype ============== .. .. c:type:: krb5_cksumtype .. Declaration ------------ typedef krb5_int32 krb5_cksumtype krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_keyblock.rst.txt0000664000175000017500000000143515051422642025361 0ustar ghudsonghudson.. highlight:: c .. _krb5-keyblock-struct: krb5_keyblock ============= .. .. c:type:: krb5_keyblock .. Exposed contents of a key. Declaration ------------ typedef struct _krb5_keyblock krb5_keyblock Members --------- .. c:member:: krb5_magic krb5_keyblock.magic .. c:member:: krb5_enctype krb5_keyblock.enctype .. c:member:: unsigned int krb5_keyblock.length .. c:member:: krb5_octet * krb5_keyblock.contents krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_ccache.rst.txt0000664000175000017500000000025415051422642024762 0ustar ghudsonghudson.. highlight:: c .. _krb5-ccache-struct: krb5_ccache =========== .. .. c:type:: krb5_ccache .. Declaration ------------ typedef struct _krb5_ccache\* krb5_ccache krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_expire_callback_func.rst.txt0000664000175000017500000000055315051422642027701 0ustar ghudsonghudson.. highlight:: c .. _krb5-expire-callback-func-struct: krb5_expire_callback_func ========================= .. .. c:type:: krb5_expire_callback_func .. Declaration ------------ typedef void( \* krb5_expire_callback_func) (krb5_context context, void \*data, krb5_timestamp password_expiration, krb5_timestamp account_expiration, krb5_boolean is_last_req) krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_address.rst.txt0000664000175000017500000000142115051422642025176 0ustar ghudsonghudson.. highlight:: c .. _krb5-address-struct: krb5_address ============ .. .. c:type:: krb5_address .. Structure for address. Declaration ------------ typedef struct _krb5_address krb5_address Members --------- .. c:member:: krb5_magic krb5_address.magic .. c:member:: krb5_addrtype krb5_address.addrtype .. c:member:: unsigned int krb5_address.length .. c:member:: krb5_octet * krb5_address.contents krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_error_code.rst.txt0000664000175000017500000000054115051422642025676 0ustar ghudsonghudson.. highlight:: c .. _krb5-error-code-struct: krb5_error_code =============== .. .. c:type:: krb5_error_code .. Used to convey an operation status. The value 0 indicates success; any other values are com_err codes. Use krb5_get_error_message() to obtain a string describing the error. Declaration ------------ typedef krb5_int32 krb5_error_code krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_kdc_req.rst.txt0000664000175000017500000000560215051422642025166 0ustar ghudsonghudson.. highlight:: c .. _krb5-kdc-req-struct: krb5_kdc_req ============ .. .. c:type:: krb5_kdc_req .. C representation of KDC-REQ protocol message, including KDC-REQ-BODY. Declaration ------------ typedef struct _krb5_kdc_req krb5_kdc_req Members --------- .. c:member:: krb5_magic krb5_kdc_req.magic .. c:member:: krb5_msgtype krb5_kdc_req.msg_type KRB5_AS_REQ or KRB5_TGS_REQ. .. c:member:: krb5_pa_data ** krb5_kdc_req.padata Preauthentication data. .. c:member:: krb5_flags krb5_kdc_req.kdc_options Requested options. .. c:member:: krb5_principal krb5_kdc_req.client Client principal and realm. .. c:member:: krb5_principal krb5_kdc_req.server Server principal and realm. .. c:member:: krb5_timestamp krb5_kdc_req.from Requested start time. .. c:member:: krb5_timestamp krb5_kdc_req.till Requested end time. .. c:member:: krb5_timestamp krb5_kdc_req.rtime Requested renewable end time. .. c:member:: krb5_int32 krb5_kdc_req.nonce Nonce to match request and response. .. c:member:: int krb5_kdc_req.nktypes Number of enctypes. .. c:member:: krb5_enctype * krb5_kdc_req.ktype Requested enctypes. .. c:member:: krb5_address ** krb5_kdc_req.addresses Requested addresses (optional) .. c:member:: krb5_enc_data krb5_kdc_req.authorization_data Encrypted authz data (optional) .. c:member:: krb5_authdata ** krb5_kdc_req.unenc_authdata Unencrypted authz data. .. c:member:: krb5_ticket ** krb5_kdc_req.second_ticket Second ticket array (optional) krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_context.rst.txt0000664000175000017500000000026215051422642025237 0ustar ghudsonghudson.. highlight:: c .. _krb5-context-struct: krb5_context ============ .. .. c:type:: krb5_context .. Declaration ------------ typedef struct _krb5_context\* krb5_context krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_rcache.rst.txt0000664000175000017500000000025215051422642024777 0ustar ghudsonghudson.. highlight:: c .. _krb5-rcache-struct: krb5_rcache =========== .. .. c:type:: krb5_rcache .. Declaration ------------ typedef struct krb5_rc_st\* krb5_rcache krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_ap_req.rst.txt0000664000175000017500000000147715051422642025033 0ustar ghudsonghudson.. highlight:: c .. _krb5-ap-req-struct: krb5_ap_req =========== .. .. c:type:: krb5_ap_req .. Authentication header. Declaration ------------ typedef struct _krb5_ap_req krb5_ap_req Members --------- .. c:member:: krb5_magic krb5_ap_req.magic .. c:member:: krb5_flags krb5_ap_req.ap_options Requested options. .. c:member:: krb5_ticket * krb5_ap_req.ticket Ticket. .. c:member:: krb5_enc_data krb5_ap_req.authenticator Encrypted authenticator. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_prompt.rst.txt0000664000175000017500000000140415051422642025073 0ustar ghudsonghudson.. highlight:: c .. _krb5-prompt-struct: krb5_prompt =========== .. .. c:type:: krb5_prompt .. Text for prompt used in prompter callback function. Declaration ------------ typedef struct _krb5_prompt krb5_prompt Members --------- .. c:member:: char * krb5_prompt.prompt The prompt to show to the user. .. c:member:: int krb5_prompt.hidden Boolean; informative prompt or hidden (e.g. PIN) .. c:member:: krb5_data * krb5_prompt.reply Must be allocated before call to prompt routine. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_kdc_rep.rst.txt0000664000175000017500000000260215051422642025162 0ustar ghudsonghudson.. highlight:: c .. _krb5-kdc-rep-struct: krb5_kdc_rep ============ .. .. c:type:: krb5_kdc_rep .. Representation of the *KDC-REP* protocol message. Declaration ------------ typedef struct _krb5_kdc_rep krb5_kdc_rep Members --------- .. c:member:: krb5_magic krb5_kdc_rep.magic .. c:member:: krb5_msgtype krb5_kdc_rep.msg_type KRB5_AS_REP or KRB5_KDC_REP. .. c:member:: krb5_pa_data ** krb5_kdc_rep.padata Preauthentication data from KDC. .. c:member:: krb5_principal krb5_kdc_rep.client Client principal and realm. .. c:member:: krb5_ticket * krb5_kdc_rep.ticket Ticket. .. c:member:: krb5_enc_data krb5_kdc_rep.enc_part Encrypted part of reply. .. c:member:: krb5_enc_kdc_rep_part * krb5_kdc_rep.enc_part2 Unencrypted version, if available. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_checksum.rst.txt0000664000175000017500000000141215051422642025353 0ustar ghudsonghudson.. highlight:: c .. _krb5-checksum-struct: krb5_checksum ============= .. .. c:type:: krb5_checksum .. Declaration ------------ typedef struct _krb5_checksum krb5_checksum Members --------- .. c:member:: krb5_magic krb5_checksum.magic .. c:member:: krb5_cksumtype krb5_checksum.checksum_type .. c:member:: unsigned int krb5_checksum.length .. c:member:: krb5_octet * krb5_checksum.contents krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_prompt_type.rst.txt0000664000175000017500000000027215051422642026136 0ustar ghudsonghudson.. highlight:: c .. _krb5-prompt-type-struct: krb5_prompt_type ================ .. .. c:type:: krb5_prompt_type .. Declaration ------------ typedef krb5_int32 krb5_prompt_type krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_msgtype.rst.txt0000664000175000017500000000025015051422642025240 0ustar ghudsonghudson.. highlight:: c .. _krb5-msgtype-struct: krb5_msgtype ============ .. .. c:type:: krb5_msgtype .. Declaration ------------ typedef unsigned int krb5_msgtype krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_authenticator.rst.txt0000664000175000017500000000317415051422642026432 0ustar ghudsonghudson.. highlight:: c .. _krb5-authenticator-struct: krb5_authenticator ================== .. .. c:type:: krb5_authenticator .. Ticket authenticator. The C representation of an unencrypted authenticator. Declaration ------------ typedef struct _krb5_authenticator krb5_authenticator Members --------- .. c:member:: krb5_magic krb5_authenticator.magic .. c:member:: krb5_principal krb5_authenticator.client client name/realm .. c:member:: krb5_checksum * krb5_authenticator.checksum checksum, includes type, optional .. c:member:: krb5_int32 krb5_authenticator.cusec client usec portion .. c:member:: krb5_timestamp krb5_authenticator.ctime client sec portion .. c:member:: krb5_keyblock * krb5_authenticator.subkey true session key, optional .. c:member:: krb5_ui_4 krb5_authenticator.seq_number sequence #, optional .. c:member:: krb5_authdata ** krb5_authenticator.authorization_data authoriazation data krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_const_pointer.rst.txt0000664000175000017500000000030615051422642026440 0ustar ghudsonghudson.. highlight:: c .. _krb5-const-pointer-struct: krb5_const_pointer ================== .. .. c:type:: krb5_const_pointer .. Declaration ------------ typedef void const\* krb5_const_pointer krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_ap_rep_enc_part.rst.txt0000664000175000017500000000217715051422642026703 0ustar ghudsonghudson.. highlight:: c .. _krb5-ap-rep-enc-part-struct: krb5_ap_rep_enc_part ==================== .. .. c:type:: krb5_ap_rep_enc_part .. Cleartext that is encrypted and put into :c:type:`_krb5_ap_rep` . Declaration ------------ typedef struct _krb5_ap_rep_enc_part krb5_ap_rep_enc_part Members --------- .. c:member:: krb5_magic krb5_ap_rep_enc_part.magic .. c:member:: krb5_timestamp krb5_ap_rep_enc_part.ctime Client time, seconds portion. .. c:member:: krb5_int32 krb5_ap_rep_enc_part.cusec Client time, microseconds portion. .. c:member:: krb5_keyblock * krb5_ap_rep_enc_part.subkey Subkey (optional) .. c:member:: krb5_ui_4 krb5_ap_rep_enc_part.seq_number Sequence number. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_pa_svr_referral_data.rst.txt0000664000175000017500000000072715051422642027726 0ustar ghudsonghudson.. highlight:: c .. _krb5-pa-svr-referral-data-struct: krb5_pa_svr_referral_data ========================= .. .. c:type:: krb5_pa_svr_referral_data .. Declaration ------------ typedef struct _krb5_pa_svr_referral_data krb5_pa_svr_referral_data Members --------- .. c:member:: krb5_principal krb5_pa_svr_referral_data.principal Referred name, only realm is required. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_pa_data.rst.txt0000664000175000017500000000150515051422642025145 0ustar ghudsonghudson.. highlight:: c .. _krb5-pa-data-struct: krb5_pa_data ============ .. .. c:type:: krb5_pa_data .. Pre-authentication data. Declaration ------------ typedef struct _krb5_pa_data krb5_pa_data Members --------- .. c:member:: krb5_magic krb5_pa_data.magic .. c:member:: krb5_preauthtype krb5_pa_data.pa_type Preauthentication data type. .. c:member:: unsigned int krb5_pa_data.length Length of data. .. c:member:: krb5_octet * krb5_pa_data.contents Data. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_typed_data.rst.txt0000664000175000017500000000141515051422642025672 0ustar ghudsonghudson.. highlight:: c .. _krb5-typed-data-struct: krb5_typed_data =============== .. .. c:type:: krb5_typed_data .. Declaration ------------ typedef struct _krb5_typed_data krb5_typed_data Members --------- .. c:member:: krb5_magic krb5_typed_data.magic .. c:member:: krb5_int32 krb5_typed_data.type .. c:member:: unsigned int krb5_typed_data.length .. c:member:: krb5_octet * krb5_typed_data.data krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_pwd_data.rst.txt0000664000175000017500000000117615051422642025343 0ustar ghudsonghudson.. highlight:: c .. _krb5-pwd-data-struct: krb5_pwd_data ============= .. .. c:type:: krb5_pwd_data .. Declaration ------------ typedef struct _krb5_pwd_data krb5_pwd_data Members --------- .. c:member:: krb5_magic krb5_pwd_data.magic .. c:member:: int krb5_pwd_data.sequence_count .. c:member:: passwd_phrase_element ** krb5_pwd_data.element krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_enc_data.rst.txt0000664000175000017500000000137415051422642025316 0ustar ghudsonghudson.. highlight:: c .. _krb5-enc-data-struct: krb5_enc_data ============= .. .. c:type:: krb5_enc_data .. Declaration ------------ typedef struct _krb5_enc_data krb5_enc_data Members --------- .. c:member:: krb5_magic krb5_enc_data.magic .. c:member:: krb5_enctype krb5_enc_data.enctype .. c:member:: krb5_kvno krb5_enc_data.kvno .. c:member:: krb5_data krb5_enc_data.ciphertext krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_pointer.rst.txt0000664000175000017500000000024215051422642025231 0ustar ghudsonghudson.. highlight:: c .. _krb5-pointer-struct: krb5_pointer ============ .. .. c:type:: krb5_pointer .. Declaration ------------ typedef void\* krb5_pointer krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_data.rst.txt0000664000175000017500000000110515051422642024461 0ustar ghudsonghudson.. highlight:: c .. _krb5-data-struct: krb5_data ========= .. .. c:type:: krb5_data .. Declaration ------------ typedef struct _krb5_data krb5_data Members --------- .. c:member:: krb5_magic krb5_data.magic .. c:member:: unsigned int krb5_data.length .. c:member:: char * krb5_data.data krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_prompter_fct.rst.txt0000664000175000017500000000054615051422642026264 0ustar ghudsonghudson.. highlight:: c .. _krb5-prompter-fct-struct: krb5_prompter_fct ================= .. .. c:type:: krb5_prompter_fct .. Pointer to a prompter callback function. Declaration ------------ typedef krb5_error_code( \* krb5_prompter_fct) (krb5_context context, void \*data, const char \*name, const char \*banner, int num_prompts, krb5_prompt prompts[]) krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_enc_kdc_rep_part.rst.txt0000664000175000017500000000434515051422642027043 0ustar ghudsonghudson.. highlight:: c .. _krb5-enc-kdc-rep-part-struct: krb5_enc_kdc_rep_part ===================== .. .. c:type:: krb5_enc_kdc_rep_part .. C representation of *EncKDCRepPart* protocol message. This is the cleartext message that is encrypted and inserted in *KDC-REP* . Declaration ------------ typedef struct _krb5_enc_kdc_rep_part krb5_enc_kdc_rep_part Members --------- .. c:member:: krb5_magic krb5_enc_kdc_rep_part.magic .. c:member:: krb5_msgtype krb5_enc_kdc_rep_part.msg_type krb5 message type .. c:member:: krb5_keyblock * krb5_enc_kdc_rep_part.session Session key. .. c:member:: krb5_last_req_entry ** krb5_enc_kdc_rep_part.last_req Array of pointers to entries. .. c:member:: krb5_int32 krb5_enc_kdc_rep_part.nonce Nonce from request. .. c:member:: krb5_timestamp krb5_enc_kdc_rep_part.key_exp Expiration date. .. c:member:: krb5_flags krb5_enc_kdc_rep_part.flags Ticket flags. .. c:member:: krb5_ticket_times krb5_enc_kdc_rep_part.times Lifetime info. .. c:member:: krb5_principal krb5_enc_kdc_rep_part.server Server's principal identifier. .. c:member:: krb5_address ** krb5_enc_kdc_rep_part.caddrs Array of ptrs to addrs, optional. .. c:member:: krb5_pa_data ** krb5_enc_kdc_rep_part.enc_padata Encrypted preauthentication data. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_cccol_cursor.rst.txt0000664000175000017500000000036715051422642026241 0ustar ghudsonghudson.. highlight:: c .. _krb5-cccol-cursor-struct: krb5_cccol_cursor ================= .. .. c:type:: krb5_cccol_cursor .. Cursor for iterating over all ccaches. Declaration ------------ typedef struct _krb5_cccol_cursor\* krb5_cccol_cursor krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_trace_callback.rst.txt0000664000175000017500000000041515051422642026465 0ustar ghudsonghudson.. highlight:: c .. _krb5-trace-callback-struct: krb5_trace_callback =================== .. .. c:type:: krb5_trace_callback .. Declaration ------------ typedef void( \* krb5_trace_callback) (krb5_context context, const krb5_trace_info \*info, void \*cb_data) krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_error.rst.txt0000664000175000017500000000343115051422642024705 0ustar ghudsonghudson.. highlight:: c .. _krb5-error-struct: krb5_error ========== .. .. c:type:: krb5_error .. Error message structure. Declaration ------------ typedef struct _krb5_error krb5_error Members --------- .. c:member:: krb5_magic krb5_error.magic .. c:member:: krb5_timestamp krb5_error.ctime Client sec portion; optional. .. c:member:: krb5_int32 krb5_error.cusec Client usec portion; optional. .. c:member:: krb5_int32 krb5_error.susec Server usec portion. .. c:member:: krb5_timestamp krb5_error.stime Server sec portion. .. c:member:: krb5_ui_4 krb5_error.error Error code (protocol error #'s) .. c:member:: krb5_principal krb5_error.client Client principal and realm. .. c:member:: krb5_principal krb5_error.server Server principal and realm. .. c:member:: krb5_data krb5_error.text Descriptive text. .. c:member:: krb5_data krb5_error.e_data Additional error-describing data. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_transited.rst.txt0000664000175000017500000000127615051422642025556 0ustar ghudsonghudson.. highlight:: c .. _krb5-transited-struct: krb5_transited ============== .. .. c:type:: krb5_transited .. Structure for transited encoding. Declaration ------------ typedef struct _krb5_transited krb5_transited Members --------- .. c:member:: krb5_magic krb5_transited.magic .. c:member:: krb5_octet krb5_transited.tr_type Transited encoding type. .. c:member:: krb5_data krb5_transited.tr_contents Contents. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_keytab_entry.rst.txt0000664000175000017500000000204715051422642026256 0ustar ghudsonghudson.. highlight:: c .. _krb5-keytab-entry-struct: krb5_keytab_entry ================= .. .. c:type:: krb5_keytab_entry .. A key table entry. Declaration ------------ typedef struct krb5_keytab_entry_st krb5_keytab_entry Members --------- .. c:member:: krb5_magic krb5_keytab_entry.magic .. c:member:: krb5_principal krb5_keytab_entry.principal Principal of this key. .. c:member:: krb5_timestamp krb5_keytab_entry.timestamp Time entry written to keytable. .. c:member:: krb5_kvno krb5_keytab_entry.vno Key version number. .. c:member:: krb5_keyblock krb5_keytab_entry.key The secret key. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_get_init_creds_opt.rst.txt0000664000175000017500000000372015051422642027421 0ustar ghudsonghudson.. highlight:: c .. _krb5-get-init-creds-opt-struct: krb5_get_init_creds_opt ======================= .. .. c:type:: krb5_get_init_creds_opt .. Store options for *_krb5_get_init_creds* . Declaration ------------ typedef struct _krb5_get_init_creds_opt krb5_get_init_creds_opt Members --------- .. c:member:: krb5_flags krb5_get_init_creds_opt.flags .. c:member:: krb5_deltat krb5_get_init_creds_opt.tkt_life .. c:member:: krb5_deltat krb5_get_init_creds_opt.renew_life .. c:member:: int krb5_get_init_creds_opt.forwardable .. c:member:: int krb5_get_init_creds_opt.proxiable .. c:member:: krb5_enctype * krb5_get_init_creds_opt.etype_list .. c:member:: int krb5_get_init_creds_opt.etype_list_length .. c:member:: krb5_address ** krb5_get_init_creds_opt.address_list .. c:member:: krb5_preauthtype * krb5_get_init_creds_opt.preauth_list .. c:member:: int krb5_get_init_creds_opt.preauth_list_length .. c:member:: krb5_data * krb5_get_init_creds_opt.salt krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_response.rst.txt0000664000175000017500000000163615051422642025417 0ustar ghudsonghudson.. highlight:: c .. _krb5-response-struct: krb5_response ============= .. .. c:type:: krb5_response .. Declaration ------------ typedef struct _krb5_response krb5_response Members --------- .. c:member:: krb5_magic krb5_response.magic .. c:member:: krb5_octet krb5_response.message_type .. c:member:: krb5_data krb5_response.response .. c:member:: krb5_int32 krb5_response.expected_nonce .. c:member:: krb5_timestamp krb5_response.request_time krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_responder_fn.rst.txt0000664000175000017500000000057615051422642026247 0ustar ghudsonghudson.. highlight:: c .. _krb5-responder-fn-struct: krb5_responder_fn ================= .. .. c:type:: krb5_responder_fn .. Responder function for an initial credential exchange. If a required question is unanswered, the prompter may be called. Declaration ------------ typedef krb5_error_code( \* krb5_responder_fn) (krb5_context ctx, void \*data, krb5_responder_context rctx) krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_ap_rep.rst.txt0000664000175000017500000000113215051422642025016 0ustar ghudsonghudson.. highlight:: c .. _krb5-ap-rep-struct: krb5_ap_rep =========== .. .. c:type:: krb5_ap_rep .. C representaton of AP-REP message. The server's response to a client's request for mutual authentication. Declaration ------------ typedef struct _krb5_ap_rep krb5_ap_rep Members --------- .. c:member:: krb5_magic krb5_ap_rep.magic .. c:member:: krb5_enc_data krb5_ap_rep.enc_part Ciphertext of ApRepEncPart. krb5-1.22.1/doc/html/_sources/appdev/refs/types/krb5_ticket.rst.txt0000664000175000017500000000172615051422642025044 0ustar ghudsonghudson.. highlight:: c .. _krb5-ticket-struct: krb5_ticket =========== .. .. c:type:: krb5_ticket .. Ticket structure. The C representation of the ticket message, with a pointer to the C representation of the encrypted part. Declaration ------------ typedef struct _krb5_ticket krb5_ticket Members --------- .. c:member:: krb5_magic krb5_ticket.magic .. c:member:: krb5_principal krb5_ticket.server server name/realm .. c:member:: krb5_enc_data krb5_ticket.enc_part encryption type, kvno, encrypted encoding .. c:member:: krb5_enc_tkt_part * krb5_ticket.enc_part2 ptr to decrypted version, if available krb5-1.22.1/doc/html/_sources/appdev/gssapi.rst.txt0000664000175000017500000010365615051422642022026 0ustar ghudsonghudsonDeveloping with GSSAPI ====================== The GSSAPI (Generic Security Services API) allows applications to communicate securely using Kerberos 5 or other security mechanisms. We recommend using the GSSAPI (or a higher-level framework which encompasses GSSAPI, such as SASL) for secure network communication over using the libkrb5 API directly. GSSAPIv2 is specified in :rfc:`2743` and :rfc:`2744`. Also see :rfc:`7546` for a description of how to use the GSSAPI in a client or server program. This documentation will describe how various ways of using the GSSAPI will behave with the krb5 mechanism as implemented in MIT krb5, as well as krb5-specific extensions to the GSSAPI. Name types ---------- A GSSAPI application can name a local or remote entity by calling gss_import_name_, specifying a name type and a value. The following name types are supported by the krb5 mechanism: * **GSS_C_NT_HOSTBASED_SERVICE**: The value should be a string of the form ``service`` or ``service@hostname``. This is the most common way to name target services when initiating a security context, and is the most likely name type to work across multiple mechanisms. * **GSS_KRB5_NT_PRINCIPAL_NAME**: The value should be a principal name string. This name type only works with the krb5 mechanism, and is defined in the ```` header. * **GSS_C_NT_USER_NAME** or **GSS_C_NULL_OID**: The value is treated as an unparsed principal name string, as above. These name types may work with mechanisms other than krb5, but will have different interpretations in those mechanisms. **GSS_C_NT_USER_NAME** is intended to be used with a local username, which will parse into a single-component principal in the default realm. * **GSS_C_NT_ANONYMOUS**: The value is ignored. The anonymous principal is used, allowing a client to authenticate to a server without asserting a particular identity (which may or may not be allowed by a particular server or Kerberos realm). * **GSS_C_NT_MACHINE_UID_NAME**: The value is uid_t object. On Unix-like systems, the username of the uid is looked up in the system user database and the resulting username is parsed as a principal name. * **GSS_C_NT_STRING_UID_NAME**: As above, but the value is a decimal string representation of the uid. * **GSS_C_NT_EXPORT_NAME**: The value must be the result of a gss_export_name_ call. * **GSS_KRB5_NT_ENTERPRISE_NAME**: The value should be a krb5 enterprise name string (see :rfc:`6806` section 5), in the form ``user@suffix``. This name type is used to convey alias names, and is defined in the ```` header. (New in release 1.17.) * **GSS_KRB5_NT_X509_CERT**: The value should be an X.509 certificate encoded according to :rfc:`5280`. This name form can be used for the desired_name parameter of gss_acquire_cred_impersonate_name(), to identify the S4U2Self user by certificate. (New in release 1.19.) Initiator credentials --------------------- A GSSAPI client application uses gss_init_sec_context_ to establish a security context. The *initiator_cred_handle* parameter determines what tickets are used to establish the connection. An application can either pass **GSS_C_NO_CREDENTIAL** to use the default client credential, or it can use gss_acquire_cred_ beforehand to acquire an initiator credential. The call to gss_acquire_cred_ may include a *desired_name* parameter, or it may pass **GSS_C_NO_NAME** if it does not have a specific name preference. If the desired name for a krb5 initiator credential is a host-based name, it is converted to a principal name of the form ``service/hostname`` in the local realm, where *hostname* is the local hostname if not specified. The hostname will be canonicalized using forward name resolution, and possibly also using reverse name resolution depending on the value of the **rdns** variable in :ref:`libdefaults`. If a desired name is specified in the call to gss_acquire_cred_, the krb5 mechanism will attempt to find existing tickets for that client principal name in the default credential cache or collection. If the default cache type does not support a collection, and the default cache contains credentials for a different principal than the desired name, a **GSS_S_CRED_UNAVAIL** error will be returned with a minor code indicating a mismatch. If no existing tickets are available for the desired name, but the name has an entry in the default client :ref:`keytab_definition`, the krb5 mechanism will acquire initial tickets for the name using the default client keytab. If no desired name is specified, credential acquisition will be deferred until the credential is used in a call to gss_init_sec_context_ or gss_inquire_cred_. If the call is to gss_init_sec_context_, the target name will be used to choose a client principal name using the credential cache selection facility. (This facility might, for instance, try to choose existing tickets for a client principal in the same realm as the target service). If there are no existing tickets for the chosen principal, but it is present in the default client keytab, the krb5 mechanism will acquire initial tickets using the keytab. If the target name cannot be used to select a client principal (because the credentials are used in a call to gss_inquire_cred_), or if the credential cache selection facility cannot choose a principal for it, the default credential cache will be selected if it exists and contains tickets. If the default credential cache does not exist, but the default client keytab does, the krb5 mechanism will try to acquire initial tickets for the first principal in the default client keytab. If the krb5 mechanism acquires initial tickets using the default client keytab, the resulting tickets will be stored in the default cache or collection, and will be refreshed by future calls to gss_acquire_cred_ as they approach their expire time. Acceptor names -------------- A GSSAPI server application uses gss_accept_sec_context_ to establish a security context based on tokens provided by the client. The *acceptor_cred_handle* parameter determines what :ref:`keytab_definition` entries may be authenticated to by the client, if the krb5 mechanism is used. The simplest choice is to pass **GSS_C_NO_CREDENTIAL** as the acceptor credential. In this case, clients may authenticate to any service principal in the default keytab (typically |keytab|, or the value of the **KRB5_KTNAME** environment variable). This is the recommended approach if the server application has no specific requirements to the contrary. A server may acquire an acceptor credential with gss_acquire_cred_ and a *cred_usage* of **GSS_C_ACCEPT** or **GSS_C_BOTH**. If the *desired_name* parameter is **GSS_C_NO_NAME**, then clients will be allowed to authenticate to any service principal in the default keytab, just as if no acceptor credential was supplied. If a server wishes to specify a *desired_name* to gss_acquire_cred_, the most common choice is a host-based name. If the host-based *desired_name* contains just a *service*, then clients will be allowed to authenticate to any host-based service principal (that is, a principal of the form ``service/hostname@REALM``) for the named service, regardless of hostname or realm, as long as it is present in the default keytab. If the input name contains both a *service* and a *hostname*, clients will be allowed to authenticate to any host-based principal for the named service and hostname, regardless of realm. .. note:: If a *hostname* is specified, it will be canonicalized using forward name resolution, and possibly also using reverse name resolution depending on the value of the **rdns** variable in :ref:`libdefaults`. .. note:: If the **ignore_acceptor_hostname** variable in :ref:`libdefaults` is enabled, then *hostname* will be ignored even if one is specified in the input name. .. note:: In MIT krb5 versions prior to 1.10, and in Heimdal's implementation of the krb5 mechanism, an input name with just a *service* is treated like an input name of ``service@localhostname``, where *localhostname* is the string returned by gethostname(). If the *desired_name* is a krb5 principal name or a local system name type which is mapped to a krb5 principal name, clients will only be allowed to authenticate to that principal in the default keytab. Name Attributes --------------- In release 1.8 or later, the gss_inquire_name_ and gss_get_name_attribute_ functions, specified in :rfc:`6680`, can be used to retrieve name attributes from the *src_name* returned by gss_accept_sec_context_. The following attributes are defined when the krb5 mechanism is used: .. _gssapi_authind_attr: * "auth-indicators" attribute: This attribute will be included in the gss_inquire_name_ output if the ticket contains :ref:`authentication indicators `. One indicator is returned per invocation of gss_get_name_attribute_, so multiple invocations may be necessary to retrieve all of the indicators from the ticket. (New in release 1.15.) Credential store extensions --------------------------- Beginning with release 1.11, the following GSSAPI extensions declared in ```` can be used to specify how credentials are acquired or stored:: struct gss_key_value_element_struct { const char *key; const char *value; }; typedef struct gss_key_value_element_struct gss_key_value_element_desc; struct gss_key_value_set_struct { OM_uint32 count; gss_key_value_element_desc *elements; }; typedef const struct gss_key_value_set_struct gss_key_value_set_desc; typedef const gss_key_value_set_desc *gss_const_key_value_set_t; OM_uint32 gss_acquire_cred_from(OM_uint32 *minor_status, const gss_name_t desired_name, OM_uint32 time_req, const gss_OID_set desired_mechs, gss_cred_usage_t cred_usage, gss_const_key_value_set_t cred_store, gss_cred_id_t *output_cred_handle, gss_OID_set *actual_mechs, OM_uint32 *time_rec); OM_uint32 gss_store_cred_into(OM_uint32 *minor_status, gss_cred_id_t input_cred_handle, gss_cred_usage_t cred_usage, const gss_OID desired_mech, OM_uint32 overwrite_cred, OM_uint32 default_cred, gss_const_key_value_set_t cred_store, gss_OID_set *elements_stored, gss_cred_usage_t *cred_usage_stored); The additional *cred_store* parameter allows the caller to specify information about how the credentials should be obtained and stored. The following options are supported by the krb5 mechanism: * **ccache**: For acquiring initiator credentials, the name of the :ref:`credential cache ` to which the handle will refer. For storing credentials, the name of the cache or collection where the credentials will be stored (see below). * **client_keytab**: For acquiring initiator credentials, the name of the :ref:`keytab ` which will be used, if necessary, to refresh the credentials in the cache. * **keytab**: For acquiring acceptor credentials, the name of the :ref:`keytab ` to which the handle will refer. In release 1.19 and later, this option also determines the keytab to be used for verification when initiator credentials are acquired using a password and verified. * **password**: For acquiring initiator credentials, this option instructs the mechanism to acquire fresh credentials into a unique memory credential cache. This option may not be used with the **ccache** or **client_keytab** options, and a *desired_name* must be specified. (New in release 1.19.) * **rcache**: For acquiring acceptor credentials, the name of the :ref:`replay cache ` to be used when processing the initiator tokens. (New in release 1.13.) * **verify**: For acquiring initiator credentials, this option instructs the mechanism to verify the credentials by obtaining a ticket to a service with a known key. The service key is obtained from the keytab specified with the **keytab** option or the default keytab. The value may be the name of a principal in the keytab, or the empty string. If the empty string is given, any ``host`` service principal in the keytab may be used. (New in release 1.19.) In release 1.20 or later, if a collection name is specified for **cache** in a call to gss_store_cred_into(), an existing cache for the client principal within the collection will be selected, or a new cache will be created within the collection. If *overwrite_cred* is false and the selected credential cache already exists, a **GSS_S_DUPLICATE_ELEMENT** error will be returned. If *default_cred* is true, the primary cache of the collection will be switched to the selected cache. Importing and exporting credentials ----------------------------------- The following GSSAPI extensions can be used to import and export credentials (declared in ````):: OM_uint32 gss_export_cred(OM_uint32 *minor_status, gss_cred_id_t cred_handle, gss_buffer_t token); OM_uint32 gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token, gss_cred_id_t *cred_handle); The first function serializes a GSSAPI credential handle into a buffer; the second unseralizes a buffer into a GSSAPI credential handle. Serializing a credential does not destroy it. If any of the mechanisms used in *cred_handle* do not support serialization, gss_export_cred will return **GSS_S_UNAVAILABLE**. As with other GSSAPI serialization functions, these extensions are only intended to work with a matching implementation on the other side; they do not serialize credentials in a standardized format. A serialized credential may contain secret information such as ticket session keys. The serialization format does not protect this information from eavesdropping or tampering. The calling application must take care to protect the serialized credential when communicating it over an insecure channel or to an untrusted party. A krb5 GSSAPI credential may contain references to a credential cache, a client keytab, an acceptor keytab, and a replay cache. These resources are normally serialized as references to their external locations (such as the filename of the credential cache). Because of this, a serialized krb5 credential can only be imported by a process with similar privileges to the exporter. A serialized credential should not be trusted if it originates from a source with lower privileges than the importer, as it may contain references to external credential cache, keytab, or replay cache resources not accessible to the originator. An exception to the above rule applies when a krb5 GSSAPI credential refers to a memory credential cache, as is normally the case for delegated credentials received by gss_accept_sec_context_. In this case, the contents of the credential cache are serialized, so that the resulting token may be imported even if the original memory credential cache no longer exists. Constrained delegation (S4U) ---------------------------- The Microsoft S4U2Self and S4U2Proxy Kerberos protocol extensions allow an intermediate service to acquire credentials from a client to a target service without requiring the client to delegate a ticket-granting ticket, if the KDC is configured to allow it. To perform a constrained delegation operation, the intermediate service must submit to the KDC an "evidence ticket" from the client to the intermediate service. An evidence ticket can be acquired when the client authenticates to the intermediate service with Kerberos, or with an S4U2Self request if the KDC allows it. The MIT krb5 GSSAPI library represents an evidence ticket using a "proxy credential", which is a special kind of gss_cred_id_t object whose underlying credential cache contains the evidence ticket and a krbtgt ticket for the intermediate service. To acquire a proxy credential during client authentication, the service should first create an acceptor credential using the **GSS_C_BOTH** usage. The application should then pass this credential as the *acceptor_cred_handle* to gss_accept_sec_context_, and also pass a *delegated_cred_handle* output parameter to receive a proxy credential containing the evidence ticket. The output value of *delegated_cred_handle* may be a delegated ticket-granting ticket if the client sent one, or a proxy credential if not. If the library can determine that the client's ticket is not a valid evidence ticket, it will place **GSS_C_NO_CREDENTIAL** in *delegated_cred_handle*. To acquire a proxy credential using an S4U2Self request, the service can use the following GSSAPI extension:: OM_uint32 gss_acquire_cred_impersonate_name(OM_uint32 *minor_status, gss_cred_id_t icred, gss_name_t desired_name, OM_uint32 time_req, gss_OID_set desired_mechs, gss_cred_usage_t cred_usage, gss_cred_id_t *output_cred, gss_OID_set *actual_mechs, OM_uint32 *time_rec); The parameters to this function are similar to those of gss_acquire_cred_, except that *icred* is used to make an S4U2Self request to the KDC for a ticket from *desired_name* to the intermediate service. Both *icred* and *desired_name* are required for this function; passing **GSS_C_NO_CREDENTIAL** or **GSS_C_NO_NAME** will cause the call to fail. *icred* must contain a krbtgt ticket for the intermediate service. The result of this operation is a proxy credential. (Prior to release 1.18, the result of this operation may be a regular credential for *desired_name*, if the KDC issues a non-forwardable ticket.) Once the intermediate service has a proxy credential, it can simply pass it to gss_init_sec_context_ as the *initiator_cred_handle* parameter, and the desired service as the *target_name* parameter. The GSSAPI library will present the krbtgt ticket and evidence ticket in the proxy credential to the KDC in an S4U2Proxy request; if the intermediate service has the appropriate permissions, the KDC will issue a ticket from the client to the target service. The GSSAPI library will then use this ticket to authenticate to the target service. If an application needs to find out whether a credential it holds is a proxy credential and the name of the intermediate service, it can query the credential with the **GSS_KRB5_GET_CRED_IMPERSONATOR** OID (new in release 1.16, declared in ````) using the gss_inquire_cred_by_oid extension (declared in ````):: OM_uint32 gss_inquire_cred_by_oid(OM_uint32 *minor_status, const gss_cred_id_t cred_handle, gss_OID desired_object, gss_buffer_set_t *data_set); If the call succeeds and *cred_handle* is a proxy credential, *data_set* will be set to a single-element buffer set containing the unparsed principal name of the intermediate service. If *cred_handle* is not a proxy credential, *data_set* will be set to an empty buffer set. If the library does not support the query, gss_inquire_cred_by_oid will return **GSS_S_UNAVAILABLE**. Channel binding behavior and GSS_C_CHANNEL_BOUND_FLAG ----------------------------------------------------- GSSAPI channel bindings can be used to limit the scope of a context establishment token to a particular protected channel or endpoint, such as a TLS channel or server certificate. Channel bindings can be supplied via the *input_chan_bindings* parameter to either gss_init_sec_context() or gss_accept_sec_context(). If both the initiator and acceptor of a GSSAPI exchange supply matching channel bindings, **GSS_C_CHANNEL_BOUND_FLAG** will be included in the gss_accept_sec_context() *ret_flags* result. If either the initiator or acceptor (or both) do not supply channel bindings, the exchange will succeed, but **GSS_C_CHANNEL_BOUND_FLAG** will not be included in the return flags. If the acceptor and initiator both inlude channel bindings but they do not match, the exchange will fail. If **GSS_C_CHANNEL_BOUND_FLAG** is included in the *req_flags* parameter of gss_init_sec_context(), the initiator will add the Microsoft KERB_AP_OPTIONS_CBT extension to the Kerberos authenticator. This extension requests that the acceptor strictly enforce channel bindings, causing the exchange to fail if the acceptor supplies channel bindings and the initiator does not. The KERB_AP_OPTIONS_CBT extension will also be included if the **client_aware_channel_bindings** variable is set to ``true`` in :ref:`libdefaults`. Prior to release 1.19, **GSS_C_CHANNEL_BOUND_FLAG** is not implemented, and the exchange will fail if the acceptor supply channel bindings and the initiator does not (but not vice versa). Between releases 1.19 and 1.21, **GSS_C_CHANNEL_BOUND_FLAG** is not recognized as an initiator flag, so **client_aware_channel_bindings** is the only way to cause KERB_AP_OPTIONS_CBT to be included. AEAD message wrapping --------------------- The following GSSAPI extensions (declared in ````) can be used to wrap and unwrap messages with additional "associated data" which is integrity-checked but is not included in the output buffer:: OM_uint32 gss_wrap_aead(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, gss_buffer_t input_assoc_buffer, gss_buffer_t input_payload_buffer, int *conf_state, gss_buffer_t output_message_buffer); OM_uint32 gss_unwrap_aead(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_buffer_t input_message_buffer, gss_buffer_t input_assoc_buffer, gss_buffer_t output_payload_buffer, int *conf_state, gss_qop_t *qop_state); Wrap tokens created with gss_wrap_aead will successfully unwrap only if the same *input_assoc_buffer* contents are presented to gss_unwrap_aead. IOV message wrapping -------------------- The following extensions (declared in ````) can be used for in-place encryption, fine-grained control over wrap token layout, and for constructing wrap tokens compatible with Microsoft DCE RPC:: typedef struct gss_iov_buffer_desc_struct { OM_uint32 type; gss_buffer_desc buffer; } gss_iov_buffer_desc, *gss_iov_buffer_t; OM_uint32 gss_wrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, int *conf_state, gss_iov_buffer_desc *iov, int iov_count); OM_uint32 gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int *conf_state, gss_qop_t *qop_state, gss_iov_buffer_desc *iov, int iov_count); OM_uint32 gss_wrap_iov_length(OM_uint32 *minor_status, gss_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, int *conf_state, gss_iov_buffer_desc *iov, int iov_count); OM_uint32 gss_release_iov_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count); The caller of gss_wrap_iov provides an array of gss_iov_buffer_desc structures, each containing a type and a gss_buffer_desc structure. Valid types include: * **GSS_C_BUFFER_TYPE_DATA**: A data buffer to be included in the token, and to be encrypted or decrypted in-place if the token is confidentiality-protected. * **GSS_C_BUFFER_TYPE_HEADER**: The GSSAPI wrap token header and underlying cryptographic header. * **GSS_C_BUFFER_TYPE_TRAILER**: The cryptographic trailer, if one is required. * **GSS_C_BUFFER_TYPE_PADDING**: Padding to be combined with the data during encryption and decryption. (The implementation may choose to place padding in the trailer buffer, in which case it will set the padding buffer length to 0.) * **GSS_C_BUFFER_TYPE_STREAM**: For unwrapping only, a buffer containing a complete wrap token in standard format to be unwrapped. * **GSS_C_BUFFER_TYPE_SIGN_ONLY**: A buffer to be included in the token's integrity protection checksum, but not to be encrypted or included in the token itself. For gss_wrap_iov, the IOV list should contain one HEADER buffer, followed by zero or more SIGN_ONLY buffers, followed by one or more DATA buffers, followed by a TRAILER buffer. The memory pointed to by the buffers is not required to be contiguous or in any particular order. If *conf_req_flag* is true, DATA buffers will be encrypted in-place, while SIGN_ONLY buffers will not be modified. The type of an output buffer may be combined with **GSS_C_BUFFER_FLAG_ALLOCATE** to request that gss_wrap_iov allocate the buffer contents. If gss_wrap_iov allocates a buffer, it sets the **GSS_C_BUFFER_FLAG_ALLOCATED** flag on the buffer type. gss_release_iov_buffer can be used to release all allocated buffers within an iov list and unset their allocated flags. Here is an example of how gss_wrap_iov can be used with allocation requested (*ctx* is assumed to be a previously established gss_ctx_id_t):: OM_uint32 major, minor; gss_iov_buffer_desc iov[4]; char str[] = "message"; iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = str; iov[1].buffer.length = strlen(str); iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL, iov, 4); if (GSS_ERROR(major)) handle_error(major, minor); /* Transmit or otherwise use resulting buffers. */ (void)gss_release_iov_buffer(&minor, iov, 4); If the caller does not choose to request buffer allocation by gss_wrap_iov, it should first call gss_wrap_iov_length to query the lengths of the HEADER, PADDING, and TRAILER buffers. DATA buffers must be provided in the iov list so that padding length can be computed correctly, but the output buffers need not be initialized. Here is an example of using gss_wrap_iov_length and gss_wrap_iov:: OM_uint32 major, minor; gss_iov_buffer_desc iov[4]; char str[1024] = "message", *ptr; iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = str; iov[1].buffer.length = strlen(str); iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING; iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER; major = gss_wrap_iov_length(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL, iov, 4); if (GSS_ERROR(major)) handle_error(major, minor); if (strlen(str) + iov[0].buffer.length + iov[2].buffer.length + iov[3].buffer.length > sizeof(str)) handle_out_of_space_error(); ptr = str + strlen(str); iov[0].buffer.value = ptr; ptr += iov[0].buffer.length; iov[2].buffer.value = ptr; ptr += iov[2].buffer.length; iov[3].buffer.value = ptr; major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL, iov, 4); if (GSS_ERROR(major)) handle_error(major, minor); If the context was established using the **GSS_C_DCE_STYLE** flag (described in :rfc:`4757`), wrap tokens compatible with Microsoft DCE RPC can be constructed. In this case, the IOV list must include a SIGN_ONLY buffer, a DATA buffer, a second SIGN_ONLY buffer, and a HEADER buffer in that order (the order of the buffer contents remains arbitrary). The application must pad the DATA buffer to a multiple of 16 bytes as no padding or trailer buffer is used. gss_unwrap_iov may be called with an IOV list just like one which would be provided to gss_wrap_iov. DATA buffers will be decrypted in-place if they were encrypted, and SIGN_ONLY buffers will not be modified. Alternatively, gss_unwrap_iov may be called with a single STREAM buffer, zero or more SIGN_ONLY buffers, and a single DATA buffer. The STREAM buffer is interpreted as a complete wrap token. The STREAM buffer will be modified in-place to decrypt its contents. The DATA buffer will be initialized to point to the decrypted data within the STREAM buffer, unless it has the **GSS_C_BUFFER_FLAG_ALLOCATE** flag set, in which case it will be initialized with a copy of the decrypted data. Here is an example (*token* and *token_len* are assumed to be a pre-existing pointer and length for a modifiable region of data):: OM_uint32 major, minor; gss_iov_buffer_desc iov[2]; iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; iov[0].buffer.value = token; iov[0].buffer.length = token_len; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2); if (GSS_ERROR(major)) handle_error(major, minor); /* Decrypted data is in iov[1].buffer, pointing to a subregion of * token. */ .. _gssapi_mic_token: IOV MIC tokens -------------- The following extensions (declared in ````) can be used in release 1.12 or later to construct and verify MIC tokens using an IOV list:: OM_uint32 gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_qop_t qop_req, gss_iov_buffer_desc *iov, int iov_count); OM_uint32 gss_get_mic_iov_length(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_qop_t qop_req, gss_iov_buffer_desc *iov, iov_count); OM_uint32 gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_qop_t *qop_state, gss_iov_buffer_desc *iov, int iov_count); The caller of gss_get_mic_iov provides an array of gss_iov_buffer_desc structures, each containing a type and a gss_buffer_desc structure. Valid types include: * **GSS_C_BUFFER_TYPE_DATA** and **GSS_C_BUFFER_TYPE_SIGN_ONLY**: The corresponding buffer for each of these types will be signed for the MIC token, in the order provided. * **GSS_C_BUFFER_TYPE_MIC_TOKEN**: The GSSAPI MIC token. The type of the MIC_TOKEN buffer may be combined with **GSS_C_BUFFER_FLAG_ALLOCATE** to request that gss_get_mic_iov allocate the buffer contents. If gss_get_mic_iov allocates the buffer, it sets the **GSS_C_BUFFER_FLAG_ALLOCATED** flag on the buffer type. gss_release_iov_buffer can be used to release all allocated buffers within an iov list and unset their allocated flags. Here is an example of how gss_get_mic_iov can be used with allocation requested (*ctx* is assumed to be a previously established gss_ctx_id_t):: OM_uint32 major, minor; gss_iov_buffer_desc iov[3]; iov[0].type = GSS_IOV_BUFFER_TYPE_DATA; iov[0].buffer.value = "sign1"; iov[0].buffer.length = 5; iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[1].buffer.value = "sign2"; iov[1].buffer.length = 5; iov[2].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 3); if (GSS_ERROR(major)) handle_error(major, minor); /* Transmit or otherwise use iov[2].buffer. */ (void)gss_release_iov_buffer(&minor, iov, 3); If the caller does not choose to request buffer allocation by gss_get_mic_iov, it should first call gss_get_mic_iov_length to query the length of the MIC_TOKEN buffer. Here is an example of using gss_get_mic_iov_length and gss_get_mic_iov:: OM_uint32 major, minor; gss_iov_buffer_desc iov[2]; char data[1024]; iov[0].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = "message"; iov[1].buffer.length = 7; major = gss_get_mic_iov_length(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 2); if (GSS_ERROR(major)) handle_error(major, minor); if (iov[0].buffer.length > sizeof(data)) handle_out_of_space_error(); iov[0].buffer.value = data; major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 2); if (GSS_ERROR(major)) handle_error(major, minor); .. _gss_accept_sec_context: https://tools.ietf.org/html/rfc2744.html#section-5.1 .. _gss_acquire_cred: https://tools.ietf.org/html/rfc2744.html#section-5.2 .. _gss_export_name: https://tools.ietf.org/html/rfc2744.html#section-5.13 .. _gss_get_name_attribute: https://tools.ietf.org/html/6680.html#section-7.5 .. _gss_import_name: https://tools.ietf.org/html/rfc2744.html#section-5.16 .. _gss_init_sec_context: https://tools.ietf.org/html/rfc2744.html#section-5.19 .. _gss_inquire_name: https://tools.ietf.org/html/rfc6680.txt#section-7.4 .. _gss_inquire_cred: https://tools.ietf.org/html/rfc2744.html#section-5.21 krb5-1.22.1/doc/html/_sources/build/0000775000175000017500000000000015051422713016774 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/build/doing_build.rst.txt0000664000175000017500000001214715051422642022631 0ustar ghudsonghudsonDoing the build =============== .. _do_build: Building within a single tree ----------------------------- If you only need to build Kerberos for one platform, using a single directory tree which contains both the source files and the object files is the simplest. However, if you need to maintain Kerberos for a large number of platforms, you will probably want to use separate build trees for each platform. We recommend that you look at OS Incompatibilities, for notes that we have on particular operating systems. If you don't want separate build trees for each architecture, then use the following abbreviated procedure:: cd /u1/krb5-VERSION/src ./configure make That's it! Building with separate build directories ---------------------------------------- If you wish to keep separate build directories for each platform, you can do so using the following procedure. (Note, this requires that your make program support VPATH. GNU's make will provide this functionality, for example.) If your make program does not support this, see the next section. For example, if you wish to store the binaries in ``tmpbuild`` build directory you might use the following procedure:: mkdir /u1/tmpbuild cd /u1/tmpbuild /u1/krb5-VERSION/src/configure make Building using lndir -------------------- If you wish to keep separate build directories for each platform, and you do not have access to a make program which supports VPATH, all is not lost. You can use the lndir program to create symbolic link trees in your build directory. For example, if you wish to create a build directory for solaris binaries you might use the following procedure:: mkdir /u1/krb5-VERSION/solaris cd /u1/krb5-VERSION/solaris /u1/krb5-VERSION/src/util/lndir `pwd`/../src ./configure make You must give an absolute pathname to lndir because it has a bug that makes it fail for relative pathnames. Note that this version differs from the latest version as distributed and installed by the XConsortium with X11R6. Either version should be acceptable. Installing the binaries ----------------------- Once you have built Kerberos, you should install the binaries. You can do this by running:: make install If you want to install the binaries into a destination directory that is not their final destination, which may be convenient if you want to build a binary distribution to be deployed on multiple hosts, you may use:: make install DESTDIR=/path/to/destdir This will install the binaries under *DESTDIR/PREFIX*, e.g., the user programs will install into *DESTDIR/PREFIX/bin*, the libraries into *DESTDIR/PREFIX/lib*, etc. *DESTDIR* must be an absolute path. Some implementations of make allow multiple commands to be run in parallel, for faster builds. We test our Makefiles in parallel builds with GNU make only; they may not be compatible with other parallel build implementations. Testing the build ----------------- The Kerberos V5 distribution comes with built-in regression tests. To run them, simply type the following command while in the top-level build directory (i.e., the directory where you sent typed make to start building Kerberos; see :ref:`do_build`):: make check On some operating systems, you have to run ``make install`` before running ``make check``, or the test suite will pick up installed versions of Kerberos libraries rather than the newly built ones. You can install into a prefix that isn't in the system library search path, though. Alternatively, you can configure with **-**\ **-disable-rpath**, which renders the build tree less suitable for installation, but allows testing without interference from previously installed libraries. There are additional regression tests available, which are not run by ``make check``. These tests require manual setup and teardown of support infrastructure which is not easily automated, or require excessive resources for ordinary use. The procedure for running the manual tests is documented at https://k5wiki.kerberos.org/wiki/Manual_Testing. Cleaning up the build --------------------- * Use ``make clean`` to remove all files generated by running make command. * Use ``make distclean`` to remove all files generated by running ./configure script. After running ``make distclean`` your source tree (ideally) should look like the raw (just un-tarred) source tree. Using autoconf -------------- (If you are not a developer, you can ignore this section.) In the Kerberos V5 source directory, there is a configure script which automatically determines the compilation environment and creates the proper Makefiles for a particular platform. This configure script is generated using autoconf, which you should already have installed if you will be making changes to ``src/configure.in``. Normal users will not need to worry about running autoconf; the distribution comes with the configure script already prebuilt. The autoconf package comes with a script called ``autoreconf`` that will automatically run ``autoconf`` and ``autoheader`` as needed. You should run ``autoreconf`` from the top source directory, e.g.:: cd /u1/krb5-VERSION/src autoreconf --verbose krb5-1.22.1/doc/html/_sources/build/index.rst.txt0000664000175000017500000000413215051422642021454 0ustar ghudsonghudson.. _build_V5: Building Kerberos V5 ==================== This section details how to build and install MIT Kerberos software from the source. Prerequisites ------------- In order to build Kerberos V5, you will need approximately 60-70 megabytes of disk space. The exact amount will vary depending on the platform and whether the distribution is compiled with debugging symbol tables or not. Your C compiler must conform to ANSI C (ISO/IEC 9899:1990, "c89"). Some operating systems do not have an ANSI C compiler, or their default compiler requires extra command-line options to enable ANSI C conformance. If you wish to keep a separate build tree, which contains the compiled \*.o file and executables, separate from your source tree, you will need a make program which supports **VPATH**, or you will need to use a tool such as lndir to produce a symbolic link tree for your build tree. Obtaining the software ---------------------- The source code can be obtained from MIT Kerberos Distribution page, at https://kerberos.org/dist/index.html. The MIT Kerberos distribution comes in an archive file, generally named krb5-VERSION-signed.tar, where *VERSION* is a placeholder for the major and minor versions of MIT Kerberos. (For example, MIT Kerberos 1.9 has major version "1" and minor version "9".) The krb5-VERSION-signed.tar contains a compressed tar file consisting of the sources for all of Kerberos (generally named krb5-VERSION.tar.gz) and a PGP signature file for this source tree (generally named krb5-VERSION.tar.gz.asc). MIT highly recommends that you verify the integrity of the source code using this signature, e.g., by running:: tar xf krb5-VERSION-signed.tar gpg --verify krb5-VERSION.tar.gz.asc Unpack krb5-VERSION.tar.gz in some directory. In this section we will assume that you have chosen the top directory of the distribution the directory ``/u1/krb5-VERSION``. Review the README file for the license, copyright and other sprecific to the distribution information. Contents -------- .. toctree:: :maxdepth: 1 directory_org.rst doing_build.rst options2configure.rst osconf.rst krb5-1.22.1/doc/html/_sources/build/osconf.rst.txt0000664000175000017500000000156115051422642021637 0ustar ghudsonghudsonosconf.hin ========== There is one configuration file which you may wish to edit to control various compile-time parameters in the Kerberos distribution:: include/osconf.hin The list that follows is by no means complete, just some of the more interesting variables. **DEFAULT_PROFILE_PATH** The pathname to the file which contains the profiles for the known realms, their KDCs, etc. The default value is |krb5conf|. **DEFAULT_KEYTAB_NAME** The type and pathname to the default server keytab file. The default is |keytab|. **DEFAULT_KDC_ENCTYPE** The default encryption type for the KDC database master key. The default value is |defmkey|. **RCTMPDIR** The directory which stores replay caches. The default is ``/var/tmp``. **DEFAULT_KDB_FILE** The location of the default database. The default value is |kdcdir|\ ``/principal``. krb5-1.22.1/doc/html/_sources/build/options2configure.rst.txt0000664000175000017500000003444715051422642024040 0ustar ghudsonghudson.. _options2configure: Options to *configure* ====================== There are a number of options to configure which you can use to control how the Kerberos distribution is built. Most commonly used options -------------------------- **-**\ **-help** Provides help to configure. This will list the set of commonly used options for building Kerberos. **-**\ **-prefix=**\ *PREFIX* By default, Kerberos will install the package's files rooted at ``/usr/local``. If you desire to place the binaries into the directory *PREFIX*, use this option. **-**\ **-exec-prefix=**\ *EXECPREFIX* This option allows one to separate the architecture independent programs from the host-dependent files (configuration files, manual pages). Use this option to install architecture-dependent programs in *EXECPREFIX*. The default location is the value of specified by **-**\ **-prefix** option. **-**\ **-localstatedir=**\ *LOCALSTATEDIR* This option sets the directory for locally modifiable single-machine data. In Kerberos, this mostly is useful for setting a location for the KDC data files, as they will be installed in ``LOCALSTATEDIR/krb5kdc``, which is by default ``PREFIX/var/krb5kdc``. **-**\ **-with-netlib**\ [=\ *libs*] Allows for suppression of or replacement of network libraries. By default, Kerberos V5 configuration will look for ``-lnsl`` and ``-lsocket``. If your operating system has a broken resolver library or fails to pass the tests in ``src/tests/resolv``, you will need to use this option. **-**\ **-enable-dns-for-realm** Enable the use of DNS to look up a host's Kerberos realm, if the information is not provided in :ref:`krb5.conf(5)`. See :ref:`mapping_hostnames` for information about using DNS to determine the default realm. DNS lookups for realm names are disabled by default. **-**\ **-with-system-et** Use an installed version of the error-table (et) support software, the compile_et program, the com_err.h header file and the com_err library. If these are not in the default locations, you may wish to specify ``CPPFLAGS=-I/some/dir`` and ``LDFLAGS=-L/some/other/dir`` options at configuration time as well. If this option is not given, a version supplied with the Kerberos sources will be built and installed along with the rest of the Kerberos tree, for Kerberos applications to link against. **-**\ **-with-system-ss** Use an installed version of the subsystem command-line interface software, the mk_cmds program, the ``ss/ss.h`` header file and the ss library. If these are not in the default locations, you may wish to specify ``CPPFLAGS=-I/some/dir`` and ``LDFLAGS=-L/some/other/dir`` options at configuration time as well. See also the **SS_LIB** option. If this option is not given, the ss library supplied with the Kerberos sources will be compiled and linked into those programs that need it; it will not be installed separately. **-**\ **-with-system-db** Use an installed version of the Berkeley DB package, which must provide an API compatible with version 1.85. This option is unsupported and untested. In particular, we do not know if the database-rename code used in the dumpfile load operation will behave properly. If this option is not given, a version supplied with the Kerberos sources will be built and installed. (We are not updating this version at this time because of licensing issues with newer versions that we haven't investigated sufficiently yet.) Environment variables --------------------- **CC=**\ *COMPILER* Use *COMPILER* as the C compiler. **CFLAGS=**\ *FLAGS* Use *FLAGS* as the default set of C compiler flags. **CPP=**\ *CPP* C preprocessor to use. (e.g., ``CPP='gcc -E'``) **CPPFLAGS=**\ *CPPOPTS* Use *CPPOPTS* as the default set of C preprocessor flags. The most common use of this option is to select certain #define's for use with the operating system's include files. **DB_HEADER=**\ *headername* If db.h is not the correct header file to include to compile against the Berkeley DB 1.85 API, specify the correct header file name with this option. For example, ``DB_HEADER=db3/db_185.h``. **DB_LIB=**\ *libs*... If ``-ldb`` is not the correct library specification for the Berkeley DB library version to be used, override it with this option. For example, ``DB_LIB=-ldb-3.3``. **DEFCCNAME=**\ *ccachename* Override the built-in default credential cache name. For example, ``DEFCCNAME=DIR:/var/run/user/%{USERID}/ccache`` See :ref:`parameter_expansion` for information about supported parameter expansions. **DEFCKTNAME=**\ *keytabname* Override the built-in default client keytab name. The format is the same as for *DEFCCNAME*. **DEFKTNAME=**\ *keytabname* Override the built-in default keytab name. The format is the same as for *DEFCCNAME*. **LD=**\ *LINKER* Use *LINKER* as the default loader if it should be different from C compiler as specified above. **LDFLAGS=**\ *LDOPTS* This option informs the linker where to get additional libraries (e.g., ``-L``). **LIBS=**\ *LDNAME* This option allows one to specify libraries to be passed to the linker (e.g., ``-l``) **PKCS11_MODNAME=**\ *library* Override the built-in default PKCS11 library name. **SS_LIB=**\ *libs*... If ``-lss`` is not the correct way to link in your installed ss library, for example if additional support libraries are needed, specify the correct link options here. Some variants of this library are around which allow for Emacs-like line editing, but different versions require different support libraries to be explicitly specified. This option is ignored if **-**\ **-with-system-ss** is not specified. **YACC** The 'Yet Another C Compiler' implementation to use. Defaults to the first program found out of: '`bison -y`', '`byacc`', '`yacc`'. **YFLAGS** The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of ``-d`` given by some make applications. Fine tuning of the installation directories ------------------------------------------- **-**\ **-bindir=**\ *DIR* User executables. Defaults to ``EXECPREFIX/bin``, where *EXECPREFIX* is the path specified by **-**\ **-exec-prefix** configuration option. **-**\ **-sbindir=**\ *DIR* System admin executables. Defaults to ``EXECPREFIX/sbin``, where *EXECPREFIX* is the path specified by **-**\ **-exec-prefix** configuration option. **-**\ **-sysconfdir=**\ *DIR* Read-only single-machine data such as krb5.conf. Defaults to ``PREFIX/etc``, where *PREFIX* is the path specified by **-**\ **-prefix** configuration option. **-**\ **-libdir=**\ *DIR* Object code libraries. Defaults to ``EXECPREFIX/lib``, where *EXECPREFIX* is the path specified by **-**\ **-exec-prefix** configuration option. **-**\ **-includedir=**\ *DIR* C header files. Defaults to ``PREFIX/include``, where *PREFIX* is the path specified by **-**\ **-prefix** configuration option. **-**\ **-datarootdir=**\ *DATAROOTDIR* Read-only architecture-independent data root. Defaults to ``PREFIX/share``, where *PREFIX* is the path specified by **-**\ **-prefix** configuration option. **-**\ **-datadir=**\ *DIR* Read-only architecture-independent data. Defaults to path specified by **-**\ **-datarootdir** configuration option. **-**\ **-localedir=**\ *DIR* Locale-dependent data. Defaults to ``DATAROOTDIR/locale``, where *DATAROOTDIR* is the path specified by **-**\ **-datarootdir** configuration option. **-**\ **-mandir=**\ *DIR* Man documentation. Defaults to ``DATAROOTDIR/man``, where *DATAROOTDIR* is the path specified by **-**\ **-datarootdir** configuration option. Program names ------------- **-**\ **-program-prefix=**\ *PREFIX* Prepend *PREFIX* to the names of the programs when installing them. For example, specifying ``--program-prefix=mit-`` at the configure time will cause the program named ``abc`` to be installed as ``mit-abc``. **-**\ **-program-suffix=**\ *SUFFIX* Append *SUFFIX* to the names of the programs when installing them. For example, specifying ``--program-suffix=-mit`` at the configure time will cause the program named ``abc`` to be installed as ``abc-mit``. **-**\ **-program-transform-name=**\ *PROGRAM* Run ``sed -e PROGRAM`` on installed program names. (*PROGRAM* is a sed script). System types ------------ **-**\ **-build=**\ *BUILD* Configure for building on *BUILD* (e.g., ``--build=x86_64-linux-gnu``). **-**\ **-host=**\ *HOST* Cross-compile to build programs to run on *HOST* (e.g., ``--host=x86_64-linux-gnu``). By default, Kerberos V5 configuration will look for "build" option. Optional features ----------------- **-**\ **-disable-option-checking** Ignore unrecognized --enable/--with options. **-**\ **-disable-**\ *FEATURE* Do not include *FEATURE* (same as --enable-FEATURE=no). **-**\ **-enable-**\ *FEATURE*\ [=\ *ARG*] Include *FEATURE* [ARG=yes]. **-**\ **-enable-maintainer-mode** Enable rebuilding of source files, Makefiles, etc. **-**\ **-disable-delayed-initialization** Initialize library code when loaded. Defaults to delay until first use. **-**\ **-disable-thread-support** Don't enable thread support. Defaults to enabled. **-**\ **-disable-rpath** Suppress run path flags in link lines. **-**\ **-enable-athena** Build with MIT Project Athena configuration. **-**\ **-disable-kdc-lookaside-cache** Disable the cache which detects client retransmits. **-**\ **-disable-pkinit** Disable PKINIT plugin support. **-**\ **-disable-aesni** Disable support for using AES instructions on x86 platforms. **-**\ **-enable-asan**\ [=\ *ARG*] Enable building with asan memory error checking. If *ARG* is given, it controls the -fsanitize compilation flag value (the default is "address"). **-**\ **-enable-ossfuzz** Enable building fuzzing targets with OSS-Fuzz build support. Optional packages ----------------- **-**\ **-with-**\ *PACKAGE*\ [=ARG\] Use *PACKAGE* (e.g., ``--with-imap``). The default value of *ARG* is ``yes``. **-**\ **-without-**\ *PACKAGE* Do not use *PACKAGE* (same as ``--with-PACKAGE=no``) (e.g., ``--without-libedit``). **-**\ **-with-size-optimizations** Enable a few optimizations to reduce code size possibly at some run-time cost. **-**\ **-with-system-et** Use the com_err library and compile_et utility that are already installed on the system, instead of building and installing local versions. **-**\ **-with-system-ss** Use the ss library and mk_cmds utility that are already installed on the system, instead of building and using private versions. **-**\ **-with-system-db** Use the berkeley db utility already installed on the system, instead of using a private version. This option is not recommended; enabling it may result in incompatibility with key databases originating on other systems. **-**\ **-with-netlib=**\ *LIBS* Use the resolver library specified in *LIBS*. Use this variable if the C library resolver is insufficient or broken. **-**\ **-with-hesiod=**\ *path* Compile with Hesiod support. The *path* points to the Hesiod directory. By default Hesiod is unsupported. **-**\ **-with-ldap** Compile OpenLDAP database backend module. **-**\ **-with-lmdb** Compile LMDB database backend module. **-**\ **-with-vague-errors** Do not send helpful errors to client. For example, if the KDC should return only vague error codes to clients. **-**\ **-with-crypto-impl=**\ *IMPL* Use specified crypto implementation (e.g., **-**\ **-with-crypto-impl=**\ *openssl*). The default is the native MIT Kerberos implementation ``builtin``. The other currently implemented crypto backend is ``openssl``. (See :ref:`mitK5features`) **-**\ **-without-libedit** Do not compile and link against libedit. Some utilities will no longer offer command history or completion in interactive mode if libedit is disabled. **-**\ **-with-readline** Compile and link against GNU readline, as an alternative to libedit. **-**\ **-with-system-verto** Use an installed version of libverto. If the libverto header and library are not in default locations, you may wish to specify ``CPPFLAGS=-I/some/dir`` and ``LDFLAGS=-L/some/other/dir`` options at configuration time as well. If this option is not given, the build system will try to detect an installed version of libverto and use it if it is found. Otherwise, a version supplied with the Kerberos sources will be built and installed. The built-in version does not contain the full set of back-end modules and is not a suitable general replacement for the upstream version, but will work for the purposes of Kerberos. Specifying **-**\ **-without-system-verto** will cause the built-in version of libverto to be used unconditionally. **-**\ **-with-krb5-config=**\ *PATH* Use the krb5-config program at *PATH* to obtain the build-time default credential cache, keytab, and client keytab names. The default is to use ``krb5-config`` from the program path. Specify ``--without-krb5-config`` to disable the use of krb5-config and use the usual built-in defaults. **-**\ **-without-keyutils** Build without libkeyutils support. This disables the KEYRING credential cache type. Examples -------- For example, in order to configure Kerberos on a Solaris machine using the suncc compiler with the optimizer turned on, run the configure script with the following options:: % ./configure CC=suncc CFLAGS=-O For a slightly more complicated example, consider a system where several packages to be used by Kerberos are installed in ``/usr/foobar``, including Berkeley DB 3.3, and an ss library that needs to link against the curses library. The configuration of Kerberos might be done thus:: ./configure CPPFLAGS=-I/usr/foobar/include LDFLAGS=-L/usr/foobar/lib \ --with-system-et --with-system-ss --with-system-db \ SS_LIB='-lss -lcurses' DB_HEADER=db3/db_185.h DB_LIB=-ldb-3.3 krb5-1.22.1/doc/html/_sources/build/directory_org.rst.txt0000664000175000017500000000616615051422642023231 0ustar ghudsonghudsonOrganization of the source directory ==================================== Below is a brief overview of the organization of the complete source directory. More detailed descriptions follow. =============== ============================================== appl Kerberos application client and server programs ccapi Credential cache services clients Kerberos V5 user programs (See :ref:`user_commands`) config Configure scripts config-files Sample Kerberos configuration files include include files needed to build the Kerberos system kadmin Administrative interface to the Kerberos database: :ref:`kadmin(1)`, :ref:`kdb5_util(8)`, :ref:`ktutil(1)`. kdc Kerberos V5 Authentication Service and Key Distribution Center lib_ Libraries for use with/by Kerberos V5 plugins Kerberos plugins directory po Localization infrastructure prototype Templates files containing the MIT copyright message and a placeholder for the title and description of the file. kprop Utilities for propagating the database to replica KDCs :ref:`kprop(8)` and :ref:`kpropd(8)` tests Test suite util_ Various utilities for building/configuring the code, sending bug reports, etc. windows Source code for building Kerberos V5 on Windows (see windows/README) =============== ============================================== .. _lib: lib --- The lib directory contain several subdirectories as well as some definition and glue files. - The apputils directory contains the code for the generic network servicing. - The crypto subdirectory contains the Kerberos V5 encryption library. - The gssapi library contains the Generic Security Services API, which is a library of commands to be used in secure client-server communication. - The kadm5 directory contains the libraries for the KADM5 administration utilities. - The Kerberos 5 database libraries are contained in kdb. - The krb5 directory contains Kerberos 5 API. - The rpc directory contains the API for the Kerberos Remote Procedure Call protocol. .. _util: util ---- The util directory contains several utility programs and libraries. - the programs used to configure and build the code, such as autoconf, lndir, kbuild, reconf, and makedepend, are in this directory. - the profile directory contains most of the functions which parse the Kerberos configuration files (krb5.conf and kdc.conf). - the Kerberos error table library and utilities (et); - the Sub-system library and utilities (ss); - database utilities (db2); - pseudo-terminal utilities (pty); - bug-reporting program send-pr; - a generic support library support used by several of our other libraries; - the build infrastructure for building lightweight Kerberos client (collected-client-lib) - the tool for validating Kerberos configuration files (confvalidator); - the toolkit for kernel integrators for building krb5 code subsets (gss-kernel-lib); - source code for building Kerberos V5 on MacOS (mac) - Windows getopt operations (windows) krb5-1.22.1/doc/html/_sources/formats/0000775000175000017500000000000015051422713017350 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/formats/index.rst.txt0000664000175000017500000000031015051422642022022 0ustar ghudsonghudsonProtocols and file formats ========================== .. toctree:: :maxdepth: 1 ccache_file_format keytab_file_format rcache_file_format cookie freshness_token database_formats krb5-1.22.1/doc/html/_sources/formats/database_formats.rst.txt0000664000175000017500000003652415051422642024232 0ustar ghudsonghudsonKerberos Database (KDB) Formats =============================== Dump format ----------- Files created with the :ref:`kdb5_util(8)` **dump** command begin with a versioned header "kdb5_util load_dump version 7". This version has been in use since MIT krb5 release 1.11; some previous versions are supported but are not described here. Each subsequent line of the dump file contains one or more tab-separated fields describing either a principal entry or a policy entry. The fields of a principal entry line are: * the word "princ" * the string "38" (this was originally a length field) * the length of the principal name in string form * the decimal number of tag-length data elements * the decimal number of key-data elements * the string "0" (this was originally an extension length field) * the principal name in string form * the principal attributes as a decimal number; when converted to binary, the bits from least significant to most significant are: - disallow_postdated - disallow_forwardable - disallow_tgt_based - disallow_renewable - disallow_proxiable - disallow_dup_skey - disallow_all_tix - requires_preauth - requires_hwauth - requires_pwchange - disallow_svr - pwchange_service - support_desmd5 - new_princ - ok_as_delegate - ok_to_auth_as_delegate - no_auth_data_required - lockdown_keys * the maximum ticket lifetime, as a decimal number of seconds * the maximum renewable ticket lifetime, as a decimal number of seconds * the principal expiration time, as a decimal POSIX timestamp * the password expiration time, as a decimal POSIX timestamp * the last successful authentication time, as a decimal POSIX timestamp * the last failed authentication time, as a decimal POSIX timestamp * the decimal number of failed authentications since the last successful authentication time * for each tag-length data value: - the tag value in decimal - the length in decimal - the data as a lowercase hexadecimal byte string, or "-1" if the length is 0 * for each key-data element: - the string "2" if this element has non-normal salt type, "1" otherwise - the key version number of this element - the encryption type - the length of the encrypted key value - the encrypted key as a lowercase hexadecimal byte string - if this element has non-normal salt type: - the salt type - the length of the salt data - the salt data as a lowercase hexadecimal byte string, or the string "-1" if the salt data length is 0 * the string "-1;" (this was originally an extension field) The fields of a policy entry line are: * the string "policy" * the policy name * the minimum password lifetime as a decimal number of seconds * the maximum password lifetime as a decimal number of seconds * the minimum password length, in decimal * the minimum number of character classes, in decimal * the number of historical keys to be stored, in decimal * the policy reference count (no longer used) * the maximum number of failed authentications before lockout * the time interval after which the failed authentication count is reset, as a decimal number of seconds * the lockout duration, as a decimal number of seconds * the required principal attributes, in decimal (currently unenforced) * the maximum ticket lifetime as a decimal number of seconds (currently unenforced) * the maximum renewable lifetime as a decimal number of seconds (currently unenforced) * the allowed key/salt types, or "-" if unrestricted * the number of tag-length values * for each tag-length data value: - the tag value in decimal - the length in decimal - the data as a lowercase hexadecimal byte string, or "-1" if the length is 0 Tag-length data formats ----------------------- The currently defined tag-length data types are: * (1) last password change: a four-byte little-endian POSIX timestamp giving the last password change time * (2) last modification data: a four-byte little-endian POSIX timestamp followed by a zero-terminated principal name in string form, giving the time of the last principal change and the principal who performed it * (3) kadmin data: the XDR encoding of a per-principal kadmin data record (see below) * (8) master key version: a two-byte little-endian integer containing the master key version used to encrypt this principal's key data * (9) active kvno: see below * (10) master key auxiliary data: see below * (11) string attributes: one or more iterations of a zero-terminated string key followed by a zero-terminated string value * (12) alias target principal: a zero-terminated principal name in string form * (255) LDAP object information: see below * (768) referral padata: a DER-encoded PA-SVR-REFERRAL-DATA to be sent to a TGS-REQ client within encrypted padata (see Appendix A of :rfc:`1606`) * (1792) last admin unlock: a four-byte little-endian POSIX timestamp giving the time of the last administrative account unlock * (32767) database arguments: a zero-terminated key=value string (may appear multiple times); used by the kadmin protocol to communicate -x arguments to kadmind Per-principal kadmin data ~~~~~~~~~~~~~~~~~~~~~~~~~ Per-principal kadmin data records use a modified XDR encoding of the kadmin_data type defined as follows: .. code-block:: c struct key_data { int numfields; unsigned int kvno; int enctype; int salttype; unsigned int keylen; unsigned int saltlen; opaque key<>; opaque salt<>; }; struct hist_entry { key_data keys<>; }; struct kadmin_data { int version_number; nullstring policy; int aux_attributes; unsigned int old_key_next; unsigned int admin_history_kvno; hist_entry old_keysets<>; }; The type "nullstring" uses a custom string encoder where the length field is zero or the string length plus one; a length of zero indicates that no policy object is specified for the principal. The field "version_number" contains 0x12345C01. The aux_attributes field contains the bit 0x800 if a policy object is associated with the principal. Within a key_data record, numfields is 2 if the key data has non-normal salt type, 1 otherwise. Active kvno and master key auxiliary data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These types only appear in the entry of the master key principal (K/M). They use little-endian binary integer encoding. The active kvno table determines which master key version is active for a given timestamp. It uses the following binary format: .. code-block:: bnf active-key-version-table ::= version (16 bits) [with the value 1] version entry 1 (key-version-entry) version entry 2 (key-version-entry) ... key-version-entry ::= key version (16 bits) timestamp (32 bits) [when this key version becomes active] The master key auxiliary data record contains copies of the current master key encrypted in each older master key. It uses the following binary format: .. code-block:: bnf master-key-aux ::= version (16 bits) [with the value 1] key entry 1 (key-entry) key entry 2 (key-entry) ... key-entry ::= old master key version (16 bits) latest master key version (16 bits) latest master key encryption type (16 bits) encrypted key length (16 bits) encrypted key contents LDAP object information ~~~~~~~~~~~~~~~~~~~~~~~ This type appears in principal entries retrieved with the LDAP KDB module. The value uses the following binary format, using big-endian integer encoding: .. code-block:: bnf ldap-principal-data ::= record 1 (ldap-tl-data) record 2 (ldap-tl-data) ... ldap-tl-data ::= type (8 bits) length (16 bits) data The currently defined ldap-tl-data types are (all integers are big-endian): * (1) principal type: 16 bits containing the value 1, indicating that the LDAP object containing the principal entry is a standalone principal object * (2) principal count: 16 bits containing the number of krbPrincipalName values in the LDAP object * (3) user DN: the string representation of the distinguished name of the LDAP object * (5) attribute mask: 16 bits indicating which Kerberos-specific LDAP attributes are present in the LDAP object (see below) * (7) link DN: the string representation of the distinguished name of an LDAP object this object is linked to; may appear multiple times When converted to binary, the attribute mask bits, from least significant to most significant, correspond to the following LDAP attributes: * krbMaxTicketLife * krbMaxRenewableAge * krbTicketFlags * krbPrincipalExpiration * krbTicketPolicyReference * krbPrincipalAuthInd * krbPwdPolicyReference * krbPasswordExpiration * krbPrincipalKey * krbLastPwdChange * krbExtraData * krbLastSuccessfulAuth * krbLastFailedAuth * krbLoginFailedCount * krbLastAdminUnlock * krbPwdHistory Alias principal entries ----------------------- To allow aliases to be represented in dump files and within the incremental update protocol, the krb5 database library supports the concept of an alias principal entry. An alias principal entry contains an alias target principal in its tag-length data, has its attributes set to disallow_all_tix, and has zero or empty values for all other fields. The database glue library recognizes alias entries and iteratively looks up the alias target up to a depth of 10 chained aliases. (Added in release 1.22.) DB2 principal and policy formats -------------------------------- The DB2 KDB module uses the string form of a principal name, with zero terminator, as a lookup key for principal entries. Principal entry values use the following binary format with little-endian integer encoding: .. code-block:: bnf db2-principal-entry ::= len (16 bits) [always has the value 38] attributes (32 bits) max ticket lifetime (32 bits) max renewable lifetime (32 bits) principal expiration timestamp (32 bits) password expiration timestamp (32 bits) last successful authentication timestamp (32 bits) last failed authentication timestamp (32 bits) failed authentication counter (32 bits) number of tag-length elements (16 bits) number of key-data elements (16 bits) length of string-form principal with zero terminator (16 bits) string-form principal with zero terminator tag-length entry 1 (tag-length-data) tag-length entry 2 (tag-length-data) ... key-data entry 1 (key-data) key-data entry 2 (key-data) ... tag-length-data ::= type tag (16 bits) data length (16 bits) data key-data ::= salt indicator (16 bits) [1 for default salt, 2 otherwise] key version (16 bits) encryption type (16 bits) encrypted key length (16 bits) encrypted key salt type (16 bits) [omitted if salt indicator is 1] salt data length (16 bits) [omitted if salt indicator is 1] salt data [omitted if salt indicator is 1] DB2 policy entries reside in a separate database file. The lookup key is the policy name with zero terminator. Policy entry values use a modified XDR encoding of the policy type defined as follows: .. code-block:: c struct tl_data { int type; opaque data<>; tl_data *next; }; struct policy { int version_number; unsigned int min_life; unsigned int max_pw_life; unsigned int min_length; unsigned int min_classes; unsigned int history_num; unsigned int refcount; unsigned int max_fail; unsigned int failcount_interval; unsigned int lockout_duration; unsigned int attributes; unsigned int max_ticket_life; unsigned int max_renewable_life; nullstring allowed_keysalts; int n_tl_data; tl_data *tag_length_data; }; The type "nullstring" uses the same custom encoder as in the per-principal kadmin data. The field "version_number" contains 0x12345D01, 0x12345D02, or 0x12345D03 for versions 1, 2, and 3 respectively. Versions 1 and 2 omit the fields "attributes" through "tag_length_data". Version 1 also omits the fields "max_fail" through "lockout_duration". Encoding uses the lowest version that can represent the policy entry. The field "refcount" is no longer used and its value is ignored. LMDB principal and policy formats --------------------------------- In the LMDB KDB module, principal entries are stored in the "principal" database within the main LMDB environment (typically named "principal.mdb"), with the exception of lockout-related fields which are stored in the "lockout" table of the lockout LMDB environment (typically named "principal.lockout.mdb"). For both databases the key is the principal name in string form, with no zero terminator. Values in the "principal" database use the following binary format with little-endian integer encoding: .. code-block:: bnf lmdb-principal-entry ::= attributes (32 bits) max ticket lifetime (32 bits) max renewable lifetime (32 bits) principal expiration timestamp (32 bits) password expiration timestamp (32 bits) number of tag-length elements (16 bits) number of key-data elements (16 bits) tag-length entry 1 (tag-length-data) tag-length entry 2 (tag-length-data) ... key-data entry 1 (key-data) key-data entry 2 (key-data) ... tag-length-data ::= type tag (16 bits) data length (16 bits) data value key-data ::= salt indicator (16 bits) [1 for default salt, 2 otherwise] key version (16 bits) encryption type (16 bits) encrypted key length (16 bits) encrypted key salt type (16 bits) [omitted if salt indicator is 1] salt data length (16 bits) [omitted if salt indicator is 1] salt data [omitted if salt indicator is 1] Values in the "lockout" database have the following binary format with little-endian integer encoding: .. code-block:: bnf lmdb-lockout-entry ::= last successful authentication timestamp (32 bits) last failed authentication timestamp (32 bits) failed authentication counter (32 bits) In the "policy" database, the lookup key is the policy name with no zero terminator. Values in this database use the following binary format with little-endian integer encoding: .. code-block:: bnf lmdb-policy-entry ::= minimum password lifetime (32 bits) maximum password lifetime (32 bits) minimum password length (32 bits) minimum character classes (32 bits) number of historical keys (32 bits) maximum failed authentications before lockout (32 bits) time interval to reset failed authentication counter (32 bits) lockout duration (32 bits) required principal attributes (32 bits) [currently unenforced] maximum ticket lifetime (32 bits) [currently unenforced] maximum renewable lifetime (32 bits) [currently unenforced] allowed key/salt type specification length [32 bits] allowed key/salt type specification number of tag-length values (16 bits) tag-length entry 1 (tag-length-data) tag-length entry 2 (tag-length-data) ... tag-length-data ::= type tag (16 bits) data length (16 bits) data value krb5-1.22.1/doc/html/_sources/formats/ccache_file_format.rst.txt0000664000175000017500000001430415051422642024500 0ustar ghudsonghudson.. _ccache_file_format: Credential cache file format ============================ There are four versions of the file format used by the FILE credential cache type. The first byte of the file always has the value 5, and the value of the second byte contains the version number (1 through 4). Versions 1 and 2 of the file format use native byte order for integer representations. Versions 3 and 4 always use big-endian byte order. After the two-byte version indicator, the file has three parts: the header (in version 4 only), the default principal name, and a sequence of credentials. Header format ------------- The header appears only in format version 4. It begins with a 16-bit integer giving the length of the entire header, followed by a sequence of fields. Each field consists of a 16-bit tag, a 16-bit length, and a value of the given length. A file format implementation should ignore fields with unknown tags. At this time there is only one defined header field. Its tag value is 1, its length is always 8, and its contents are two 32-bit integers giving the seconds and microseconds of the time offset of the KDC relative to the client. Adding this offset to the current time on the client should give the current time on the KDC, if that offset has not changed since the initial authentication. .. _cache_principal_format: Principal format ---------------- The default principal is marshalled using the following informal grammar:: principal ::= name type (32 bits) [omitted in version 1] count of components (32 bits) [includes realm in version 1] realm (data) component1 (data) component2 (data) ... data ::= length (32 bits) value (length bytes) There is no external framing on the default principal, so it must be parsed according to the above grammar in order to find the sequence of credentials which follows. .. _ccache_credential_format: Credential format ----------------- The credential format uses the following informal grammar (referencing the ``principal`` and ``data`` types from the previous section):: credential ::= client (principal) server (principal) keyblock (keyblock) authtime (32 bits) starttime (32 bits) endtime (32 bits) renew_till (32 bits) is_skey (1 byte, 0 or 1) ticket_flags (32 bits) addresses (addresses) authdata (authdata) ticket (data) second_ticket (data) keyblock ::= enctype (16 bits) [repeated twice in version 3] data addresses ::= count (32 bits) address1 address2 ... address ::= addrtype (16 bits) data authdata ::= count (32 bits) authdata1 authdata2 ... authdata ::= ad_type (16 bits) data There is no external framing on a marshalled credential, so it must be parsed according to the above grammar in order to find the next credential. There is also no count of credentials or marker at the end of the sequence of credentials; the sequence ends when the file ends. Credential cache configuration entries -------------------------------------- Configuration entries are encoded as credential entries. The client principal of the entry is the default principal of the cache. The server principal has the realm ``X-CACHECONF:`` and two or three components, the first of which is ``krb5_ccache_conf_data``. The server principal's second component is the configuration key. The third component, if it exists, is a principal to which the configuration key is associated. The configuration value is stored in the ticket field of the entry. All other entry fields are zeroed. Programs using credential caches must be aware of configuration entries for several reasons: * A program which displays the contents of a cache should not generally display configuration entries. * The ticket field of a configuration entry is not (usually) a valid encoding of a Kerberos ticket. An implementation must not treat the cache file as malformed if it cannot decode the ticket field. * Configuration entries have an endtime field of 0 and might therefore always be considered expired, but they should not be treated as unimportant as a result. For instance, a program which copies credentials from one cache to another should not omit configuration entries because of the endtime. The following configuration keys are currently used in MIT krb5: fast_avail The presence of this key with a non-empty value indicates that the KDC asserted support for FAST (see :rfc:`6113`) during the initial authentication, using the negotiation method described in :rfc:`6806` section 11. This key is not associated with any principal. pa_config_data The value of this key contains a JSON object representation of parameters remembered by the preauthentication mechanism used during the initial authentication. These parameters may be used when refreshing credentials. This key is associated with the server principal of the initial authentication (usually the local krbtgt principal of the client realm). pa_type The value of this key is the ASCII decimal representation of the preauth type number used during the initial authentication. This key is associated with the server principal of the initial authentication. proxy_impersonator The presence of this key indicates that the cache is a synthetic delegated credential for use with S4U2Proxy. The value is the name of the intermediate service whose TGT can be used to make S4U2Proxy requests for target services. This key is not associated with any principal. refresh_time The presence of this key indicates that the cache was acquired by the GSS mechanism using a client keytab. The value is the ASCII decimal representation of a timestamp at which the GSS mechanism should attempt to refresh the credential cache from the client keytab. start_realm This key indicates the realm of the ticket-granting ticket to be used for TGS requests, when making a referrals request or beginning a cross-realm request. If it is not present, the client realm is used. krb5-1.22.1/doc/html/_sources/formats/keytab_file_format.rst.txt0000664000175000017500000000337515051422642024557 0ustar ghudsonghudson.. _keytab_file_format: Keytab file format ================== There are two versions of the file format used by the FILE keytab type. The first byte of the file always has the value 5, and the value of the second byte contains the version number (1 or 2). Version 1 of the file format uses native byte order for integer representations. Version 2 always uses big-endian byte order. After the two-byte version indicator, the file contains a sequence of signed 32-bit record lengths followed by key records or holes. A positive record length indicates a valid key entry whose size is equal to or less than the record length. A negative length indicates a zero-filled hole whose size is the inverse of the length. A length of 0 indicates the end of the file. Key entry format ---------------- A key entry may be smaller in size than the record length which precedes it, because it may have replaced a hole which is larger than the key entry. Key entries use the following informal grammar:: entry ::= principal timestamp (32 bits) key version (8 bits) enctype (16 bits) key length (16 bits) key contents key version (32 bits) [in release 1.14 and later] principal ::= count of components (16 bits) [includes realm in version 1] realm (data) component1 (data) component2 (data) ... name type (32 bits) [omitted in version 1] data ::= length (16 bits) value (length bytes) The 32-bit key version overrides the 8-bit key version. To determine if it is present, the implementation must check that at least 4 bytes remain in the record after the other fields are read, and that the value of the 32-bit integer contained in those bytes is non-zero. krb5-1.22.1/doc/html/_sources/formats/rcache_file_format.rst.txt0000664000175000017500000000455615051422642024527 0ustar ghudsonghudsonReplay cache file format ======================== This section documents the second version of the replay cache file format, used by the "file2" replay cache type (new in release 1.18). The first version of the file replay cache format is not documented. All accesses to the replay cache file take place under an exclusive POSIX or Windows file lock, obtained when the file is opened and released when it is closed. Replay cache files are automatically created when first accessed. For each store operation, a tag is derived from the checksum part of the :RFC:`3961` ciphertext of the authenticator. The checksum is coerced to a fixed length of 12 bytes, either through truncation or right-padding with zero bytes. A four-byte timestamp is appended to the tag to produce a total record length of 16 bytes. Bytes 0 through 15 of the file contain a hash seed for the SipHash-2-4 algorithm (siphash_); this field is populated with random bytes when the file is first created. All remaining bytes are divided into a series of expanding hash tables: * Bytes 16-16383: hash table 1 (1023 slots) * Bytes 16384-49151: hash table 2 (2048 slots) * Bytes 49152-114687: hash table 3 (4096 slots) * ... Only some hash tables will be present in the file at any specific time, and the final table may be only partially filled. Replay cache files may be sparse if the filesystem supports it. For each table present in the file, the tag is hashed with SipHash-2-4 using the seed recorded in the file. The first byte of the seed is incremented by one (modulo 256) for each table after the first. The resulting hash value is taken modulo one less than the table size (1022 for the first hash table, 2047 for the second) to produce the index. The record may be found at the slot given by the index or at the next slot. All candidate locations for the record must be searched until a slot is found with a timestamp of zero (indicating a slot which has never been written to) or an offset is reached at or beyond the end of the file. Any candidate location with a timestamp value of zero, with a timestamp value less than the current time minus clockskew, or at or beyond the end of the file is available for writing. When all candidate locations have been searched without finding a match, the new entry is written to the earliest candidate available for writing. .. _siphash: https://131002.net/siphash/siphash.pdf krb5-1.22.1/doc/html/_sources/formats/cookie.rst.txt0000664000175000017500000000767615051422642022212 0ustar ghudsonghudson.. highlight:: abnf KDC cookie format ================= :rfc:`6113` section 5.2 specifies a pa-data type PA-FX-COOKIE, which clients are required to reflect back to the KDC during pre-authentication. The MIT krb5 KDC uses the following formats for cookies. Trivial cookie (version 0) -------------------------- If there is no pre-authentication mechanism state information to save, a trivial cookie containing the value "MIT" is used. A trivial cookie is needed to indicate that the conversation can continue. Secure cookie (version 1) ------------------------- In release 1.14 and later, a secure cookie can be sent if there is any mechanism state to save for the next request. A secure cookie contains the concatenation of the following: * the four bytes "MIT1" * a four-byte big-endian kvno value * an :rfc:`3961` ciphertext The ciphertext is encrypted in the cookie key with key usage number 513. The cookie key is derived from a key in the local krbtgt principal entry for the realm (e.g. ``krbtgt/KRBTEST.COM@KRBTEST.COM`` if the request is to the ``KRBTEST.COM`` realm). The first krbtgt key for the indicated kvno value is combined with the client principal as follows:: cookie-key <- random-to-key(PRF+(tgt-key, "COOKIE" | client-princ)) where **random-to-key** is the :rfc:`3961` random-to-key operation for the krbtgt key's encryption type, **PRF+** is defined in :rfc:`6113`, and ``|`` denotes concatenation. *client-princ* is the request client principal name with realm, marshalled according to :rfc:`1964` section 2.1.1. The plain text of the encrypted part of a cookie is the DER encoding of the following ASN.1 type: .. code-block:: bnf SecureCookie ::= SEQUENCE { time INTEGER, data SEQUENCE OF PA-DATA, ... } The time field represents the cookie creation time; for brevity, it is encoded as an integer giving the POSIX timestamp rather than as an ASN.1 GeneralizedTime value. The data field contains one element for each pre-authentication type which requires saved state. For mechanisms which have separate request and reply types, the request type is used; this allows the KDC to determine whether a cookie is relevant to a request by comparing the request pa-data types to the cookie data types. SPAKE cookie format (version 1) ------------------------------- Inside the SecureCookie wrapper, a data value of type 151 contains state for SPAKE pre-authentication. This data has the following binary format with big-endian integer encoding: .. code-block:: bnf cookie ::= version (16 bits) [with the value 1] stage number (16 bits) group number (32 bits) SPAKE value length (32 bits) SPAKE value transcript hash length (32 bits) transcript hash second factor record 1 (factor-record) second factor record 2 (factor-record) ... factor-record ::= second factor type (32 bits) second factor data length (32 bits) second factor data The stage value is 0 if the cookie was sent with a challenge message. Otherwise it is 1 for the first encdata message sent by the KDC during an exchange, 2 for the second, etc.. The group value indicates the group number used in the SPAKE challenge. For a stage-0 cookie, the SPAKE value is the KDC private key, represented in the scalar marshalling form of the group. For other cookies, the SPAKE value is the SPAKE result K, represented in the group element marshalling form. For a stage-0 cookie, the transcript hash is the intermediate hash after updating with the client support message (if one was sent) and challenge. For other cookies it is the final hash. For a stage-0 cookie, there may be any number of second-factor records, including none; a second-factor type need not create a state field if it does not need one, and no record is created for SF-NONE. For other cookies, there must be exactly one second-factor record corresponding to the factor type chosen by the client. krb5-1.22.1/doc/html/_sources/formats/freshness_token.rst.txt0000664000175000017500000000155615051422642024130 0ustar ghudsonghudsonPKINIT freshness tokens ======================= :rfc:`8070` specifies a pa-data type PA_AS_FRESHNESS, which clients should reflect within signed PKINIT data to prove recent access to the client certificate private key. The contents of a freshness token are left to the KDC implementation. The MIT krb5 KDC uses the following format for freshness tokens (starting in release 1.17): * a four-byte big-endian POSIX timestamp * a four-byte big-endian key version number * an :rfc:`3961` checksum, with no ASN.1 wrapper The checksum is computed using the first key in the local krbtgt principal entry for the realm (e.g. ``krbtgt/KRBTEST.COM@KRBTEST.COM`` if the request is to the ``KRBTEST.COM`` realm) of the indicated key version. The checksum type must be the mandatory checksum type for the encryption type of the krbtgt key. The key usage value for the checksum is 514. krb5-1.22.1/doc/html/_sources/mitK5features.rst.txt0000664000175000017500000007064115051422642022006 0ustar ghudsonghudson.. highlight:: rst .. toctree:: :hidden: mitK5license.rst .. _mitK5features: MIT Kerberos features ===================== https://web.mit.edu/kerberos Quick facts ----------- License - :ref:`mitK5license` Releases: - Latest stable: https://web.mit.edu/kerberos/krb5-1.22/ - Supported: https://web.mit.edu/kerberos/krb5-1.21/ - Release cycle: approximately 12 months Supported platforms \/ OS distributions: - Windows (KfW 4.0): Windows 7, Vista, XP - Solaris: SPARC, x86_64/x86 - GNU/Linux: Debian x86_64/x86, Ubuntu x86_64/x86, RedHat x86_64/x86 - BSD: NetBSD x86_64/x86 Crypto backends: - builtin - MIT Kerberos native crypto library - OpenSSL (1.0\+) - https://www.openssl.org Database backends: LDAP, DB2, LMDB krb4 support: Kerberos 5 release < 1.8 DES support: Kerberos 5 release < 1.18 (See :ref:`retiring-des`) Interoperability ---------------- `Microsoft` Starting from release 1.7: * Follow client principal referrals in the client library when obtaining initial tickets. * KDC can issue realm referrals for service principals based on domain names. * Extensions supporting DCE RPC, including three-leg GSS context setup and unencapsulated GSS tokens inside SPNEGO. * Microsoft GSS_WrapEX, implemented using the gss_iov API, which is similar to the equivalent SSPI functionality. This is needed to support some instances of DCE RPC. * NTLM recognition support in GSS-API, to facilitate dropping in an NTLM implementation for improved compatibility with older releases of Microsoft Windows. * KDC support for principal aliases, if the back end supports them. Currently, only the LDAP back end supports aliases. * Support Microsoft set/change password (:rfc:`3244`) protocol in kadmind. * Implement client and KDC support for GSS_C_DELEG_POLICY_FLAG, which allows a GSS application to request credential delegation only if permitted by KDC policy. Starting from release 1.8: * Microsoft Services for User (S4U) compatibility `Heimdal` * Support for KCM credential cache starting from release 1.13 Feature list ------------ For more information on the specific project see https://k5wiki.kerberos.org/wiki/Projects Release 1.7 - Credentials delegation :rfc:`5896` - Cross-realm authentication and referrals :rfc:`6806` - Master key migration - PKINIT :rfc:`4556` :ref:`pkinit` Release 1.8 - Anonymous PKINIT :rfc:`6112` :ref:`anonymous_pkinit` - Constrained delegation - IAKERB https://tools.ietf.org/html/draft-ietf-krb-wg-iakerb-02 - Heimdal bridge plugin for KDC backend - GSS-API S4U extensions https://msdn.microsoft.com/en-us/library/cc246071 - GSS-API naming extensions :rfc:`6680` - GSS-API extensions for storing delegated credentials :rfc:`5588` Release 1.9 - Advance warning on password expiry - Camellia encryption (CTS-CMAC mode) :rfc:`6803` - KDC support for SecurID preauthentication - kadmin over IPv6 - Trace logging :ref:`trace_logging` - GSSAPI/KRB5 multi-realm support - Plugin to test password quality :ref:`pwqual_plugin` - Plugin to synchronize password changes :ref:`kadm5_hook_plugin` - Parallel KDC - GSS-API extensions for SASL GS2 bridge :rfc:`5801` :rfc:`5587` - Purging old keys - Naming extensions for delegation chain - Password expiration API - Windows client support (build-only) - IPv6 support in iprop Release 1.10 - Plugin interface for configuration :ref:`profile_plugin` - Credentials for multiple identities :ref:`ccselect_plugin` Release 1.11 - Client support for FAST OTP :rfc:`6560` - GSS-API extensions for credential locations - Responder mechanism Release 1.12 - Plugin to control krb5_aname_to_localname and krb5_kuserok behavior :ref:`localauth_plugin` - Plugin to control hostname-to-realm mappings and the default realm :ref:`hostrealm_plugin` - GSSAPI extensions for constructing MIC tokens using IOV lists :ref:`gssapi_mic_token` - Principal may refer to nonexistent policies `Policy Refcount project `_ - Support for having no long-term keys for a principal `Principals Without Keys project `_ - Collection support to the KEYRING credential cache type on Linux :ref:`ccache_definition` - FAST OTP preauthentication module for the KDC which uses RADIUS to validate OTP token values :ref:`otp_preauth` - Experimental Audit plugin for KDC processing `Audit project `_ Release 1.13 - Add support for accessing KDCs via an HTTPS proxy server using the `MS-KKDCP `_ protocol. - Add support for `hierarchical incremental propagation `_, where replicas can act as intermediates between an upstream primary and other downstream replicas. - Add support for configuring GSS mechanisms using ``/etc/gss/mech.d/*.conf`` files in addition to ``/etc/gss/mech``. - Add support to the LDAP KDB module for `binding to the LDAP server using SASL `_. - The KDC listens for TCP connections by default. - Fix a minor key disclosure vulnerability where using the "keepold" option to the kadmin randkey operation could return the old keys. `[CVE-2014-5351] `_ - Add client support for the Kerberos Cache Manager protocol. If the host is running a Heimdal kcm daemon, caches served by the daemon can be accessed with the KCM: cache type. - When built on macOS 10.7 and higher, use "KCM:" as the default cachetype, unless overridden by command-line options or krb5-config values. - Add support for doing unlocked database dumps for the DB2 KDC back end, which would allow the KDC and kadmind to continue accessing the database during lengthy database dumps. Release 1.14 * Administrator experience - Add a new kdb5_util tabdump command to provide reporting-friendly tabular dump formats (tab-separated or CSV) for the KDC database. Unlike the normal dump format, each output table has a fixed number of fields. Some tables include human-readable forms of data that are opaque in ordinary dump files. This format is also suitable for importing into relational databases for complex queries. - Add support to kadmin and kadmin.local for specifying a single command line following any global options, where the command arguments are split by the shell--for example, "kadmin getprinc principalname". Commands issued this way do not prompt for confirmation or display warning messages, and exit with non-zero status if the operation fails. - Accept the same principal flag names in kadmin as we do for the default_principal_flags kdc.conf variable, and vice versa. Also accept flag specifiers in the form that kadmin prints, as well as hexadecimal numbers. - Remove the triple-DES and RC4 encryption types from the default value of supported_enctypes, which determines the default key and salt types for new password-derived keys. By default, keys will only created only for AES128 and AES256. This mitigates some types of password guessing attacks. - Add support for directory names in the KRB5_CONFIG and KRB5_KDC_PROFILE environment variables. - Add support for authentication indicators, which are ticket annotations to indicate the strength of the initial authentication. Add support for the "require_auth" string attribute, which can be set on server principal entries to require an indicator when authenticating to the server. - Add support for key version numbers larger than 255 in keytab files, and for version numbers up to 65535 in KDC databases. - Transmit only one ETYPE-INFO and/or ETYPE-INFO2 entry from the KDC during pre-authentication, corresponding to the client's most preferred encryption type. - Add support for server name identification (SNI) when proxying KDC requests over HTTPS. - Add support for the err_fmt profile parameter, which can be used to generate custom-formatted error messages. * Developer experience: - Change gss_acquire_cred_with_password() to acquire credentials into a private memory credential cache. Applications can use gss_store_cred() to make the resulting credentials visible to other processes. - Change gss_acquire_cred() and SPNEGO not to acquire credentials for IAKERB or for non-standard variants of the krb5 mechanism OID unless explicitly requested. (SPNEGO will still accept the Microsoft variant of the krb5 mechanism OID during negotiation.) - Change gss_accept_sec_context() not to accept tokens for IAKERB or for non-standard variants of the krb5 mechanism OID unless an acceptor credential is acquired for those mechanisms. - Change gss_acquire_cred() to immediately resolve credentials if the time_rec parameter is not NULL, so that a correct expiration time can be returned. Normally credential resolution is delayed until the target name is known. - Add krb5_prepend_error_message() and krb5_wrap_error_message() APIs, which can be used by plugin modules or applications to add prefixes to existing detailed error messages. - Add krb5_c_prfplus() and krb5_c_derive_prfplus() APIs, which implement the RFC 6113 PRF+ operation and key derivation using PRF+. - Add support for pre-authentication mechanisms which use multiple round trips, using the the KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error code. Add get_cookie() and set_cookie() callbacks to the kdcpreauth interface; these callbacks can be used to save marshalled state information in an encrypted cookie for the next request. - Add a client_key() callback to the kdcpreauth interface to retrieve the chosen client key, corresponding to the ETYPE-INFO2 entry sent by the KDC. - Add an add_auth_indicator() callback to the kdcpreauth interface, allowing pre-authentication modules to assert authentication indicators. - Add support for the GSS_KRB5_CRED_NO_CI_FLAGS_X cred option to suppress sending the confidentiality and integrity flags in GSS initiator tokens unless they are requested by the caller. These flags control the negotiated SASL security layer for the Microsoft GSS-SPNEGO SASL mechanism. - Make the FILE credential cache implementation less prone to corruption issues in multi-threaded programs, especially on platforms with support for open file description locks. * Performance: - On replica KDCs, poll the primary KDC immediately after processing a full resync, and do not require two full resyncs after the primary KDC's log file is reset. Release 1.15 * Administrator experience: - Add support to kadmin for remote extraction of current keys without changing them (requires a special kadmin permission that is excluded from the wildcard permission), with the exception of highly protected keys. - Add a lockdown_keys principal attribute to prevent retrieval of the principal's keys (old or new) via the kadmin protocol. In newly created databases, this attribute is set on the krbtgt and kadmin principals. - Restore recursive dump capability for DB2 back end, so sites can more easily recover from database corruption resulting from power failure events. - Add DNS auto-discovery of KDC and kpasswd servers from URI records, in addition to SRV records. URI records can convey TCP and UDP servers and primary KDC status in a single DNS lookup, and can also point to HTTPS proxy servers. - Add support for password history to the LDAP back end. - Add support for principal renaming to the LDAP back end. - Use the getrandom system call on supported Linux kernels to avoid blocking problems when getting entropy from the operating system. * Code quality: - Clean up numerous compilation warnings. - Remove various infrequently built modules, including some preauth modules that were not built by default. * Developer experience: - Add support for building with OpenSSL 1.1. - Use SHA-256 instead of MD5 for (non-cryptographic) hashing of authenticators in the replay cache. This helps sites that must build with FIPS 140 conformant libraries that lack MD5. * Protocol evolution: - Add support for the AES-SHA2 enctypes, which allows sites to conform to Suite B crypto requirements. Release 1.16 * Administrator experience: - The KDC can match PKINIT client certificates against the "pkinit_cert_match" string attribute on the client principal entry, using the same syntax as the existing "pkinit_cert_match" profile option. - The ktutil addent command supports the "-k 0" option to ignore the key version, and the "-s" option to use a non-default salt string. - kpropd supports a --pid-file option to write a pid file at startup, when it is run in standalone mode. - The "encrypted_challenge_indicator" realm option can be used to attach an authentication indicator to tickets obtained using FAST encrypted challenge pre-authentication. - Localization support can be disabled at build time with the --disable-nls configure option. * Developer experience: - The kdcpolicy pluggable interface allows modules control whether tickets are issued by the KDC. - The kadm5_auth pluggable interface allows modules to control whether kadmind grants access to a kadmin request. - The certauth pluggable interface allows modules to control which PKINIT client certificates can authenticate to which client principals. - KDB modules can use the client and KDC interface IP addresses to determine whether to allow an AS request. - GSS applications can query the bit strength of a krb5 GSS context using the GSS_C_SEC_CONTEXT_SASL_SSF OID with gss_inquire_sec_context_by_oid(). - GSS applications can query the impersonator name of a krb5 GSS credential using the GSS_KRB5_GET_CRED_IMPERSONATOR OID with gss_inquire_cred_by_oid(). - kdcpreauth modules can query the KDC for the canonicalized requested client principal name, or match a principal name against the requested client principal name with canonicalization. * Protocol evolution: - The client library will continue to try pre-authentication mechanisms after most failure conditions. - The KDC will issue trivially renewable tickets (where the renewable lifetime is equal to or less than the ticket lifetime) if requested by the client, to be friendlier to scripts. - The client library will use a random nonce for TGS requests instead of the current system time. - For the RC4 string-to-key or PAC operations, UTF-16 is supported (previously only UCS-2 was supported). - When matching PKINIT client certificates, UPN SANs will be matched correctly as UPNs, with canonicalization. * User experience: - Dates after the year 2038 are accepted (provided that the platform time facilities support them), through the year 2106. - Automatic credential cache selection based on the client realm will take into account the fallback realm and the service hostname. - Referral and alternate cross-realm TGTs will not be cached, avoiding some scenarios where they can be added to the credential cache multiple times. - A German translation has been added. * Code quality: - The build is warning-clean under clang with the configured warning options. - The automated test suite runs cleanly under AddressSanitizer. Release 1.17 * Administrator experience: - A new Kerberos database module using the Lightning Memory-Mapped Database library (LMDB) has been added. The LMDB KDB module should be more performant and more robust than the DB2 module, and may become the default module for new databases in a future release. - "kdb5_util dump" will no longer dump policy entries when specific principal names are requested. * Developer experience: - The new krb5_get_etype_info() API can be used to retrieve enctype, salt, and string-to-key parameters from the KDC for a client principal. - The new GSS_KRB5_NT_ENTERPRISE_NAME name type allows enterprise principal names to be used with GSS-API functions. - KDC and kadmind modules which call com_err() will now write to the log file in a format more consistent with other log messages. - Programs which use large numbers of memory credential caches should perform better. * Protocol evolution: - The SPAKE pre-authentication mechanism is now supported. This mechanism protects against password dictionary attacks without requiring any additional infrastructure such as certificates. SPAKE is enabled by default on clients, but must be manually enabled on the KDC for this release. - PKINIT freshness tokens are now supported. Freshness tokens can protect against scenarios where an attacker uses temporary access to a smart card to generate authentication requests for the future. - Password change operations now prefer TCP over UDP, to avoid spurious error messages about replays when a response packet is dropped. - The KDC now supports cross-realm S4U2Self requests when used with a third-party KDB module such as Samba's. The client code for cross-realm S4U2Self requests is also now more robust. * User experience: - The new ktutil addent -f flag can be used to fetch salt information from the KDC for password-based keys. - The new kdestroy -p option can be used to destroy a credential cache within a collection by client principal name. - The Kerberos man page has been restored, and documents the environment variables that affect programs using the Kerberos library. * Code quality: - Python test scripts now use Python 3. - Python test scripts now display markers in verbose output, making it easier to find where a failure occurred within the scripts. - The Windows build system has been simplified and updated to work with more recent versions of Visual Studio. A large volume of unused Windows-specific code has been removed. Visual Studio 2013 or later is now required. Release 1.18 * Administrator experience: - Remove support for single-DES encryption types. - Change the replay cache format to be more efficient and robust. Replay cache filenames using the new format end with ``.rcache2`` by default. - setuid programs will automatically ignore environment variables that normally affect krb5 API functions, even if the caller does not use krb5_init_secure_context(). - Add an ``enforce_ok_as_delegate`` krb5.conf relation to disable credential forwarding during GSSAPI authentication unless the KDC sets the ok-as-delegate bit in the service ticket. * Developer experience: - Implement krb5_cc_remove_cred() for all credential cache types. - Add the krb5_pac_get_client_info() API to get the client account name from a PAC. * Protocol evolution: - Add KDC support for S4U2Self requests where the user is identified by X.509 certificate. (Requires support for certificate lookup from a third-party KDB module.) - Remove support for an old ("draft 9") variant of PKINIT. - Add support for Microsoft NegoEx. (Requires one or more third-party GSS modules implementing NegoEx mechanisms.) * User experience: - Add support for ``dns_canonicalize_hostname=fallback``, causing host-based principal names to be tried first without DNS canonicalization, and again with DNS canonicalization if the un-canonicalized server is not found. - Expand single-component hostnames in hhost-based principal names when DNS canonicalization is not used, adding the system's first DNS search path as a suffix. Add a ``qualify_shortname`` krb5.conf relation to override this suffix or disable expansion. * Code quality: - The libkrb5 serialization code (used to export and import krb5 GSS security contexts) has been simplified and made type-safe. - The libkrb5 code for creating KRB-PRIV, KRB-SAFE, and KRB-CRED messages has been revised to conform to current coding practices. - The test suite has been modified to work with macOS System Integrity Protection enabled. - The test suite incorporates soft-pkcs11 so that PKINIT PKCS11 support can always be tested. Release 1.19 * Administrator experience: - When a client keytab is present, the GSSAPI krb5 mech will refresh credentials even if the current credentials were acquired manually. - It is now harder to accidentally delete the K/M entry from a KDB. * Developer experience: - gss_acquire_cred_from() now supports the "password" and "verify" options, allowing credentials to be acquired via password and verified using a keytab key. - When an application accepts a GSS security context, the new GSS_C_CHANNEL_BOUND_FLAG will be set if the initiator and acceptor both provided matching channel bindings. - Added the GSS_KRB5_NT_X509_CERT name type, allowing S4U2Self requests to identify the desired client principal by certificate. - PKINIT certauth modules can now cause the hw-authent flag to be set in issued tickets. - The krb5_init_creds_step() API will now issue the same password expiration warnings as krb5_get_init_creds_password(). * Protocol evolution: - Added client and KDC support for Microsoft's Resource-Based Constrained Delegation, which allows cross-realm S4U2Proxy requests. A third-party database module is required for KDC support. - kadmin/admin is now the preferred server principal name for kadmin connections, and the host-based form is no longer created by default. The client will still try the host-based form as a fallback. - Added client and server support for Microsoft's KERB_AP_OPTIONS_CBT extension, which causes channel bindings to be required for the initiator if the acceptor provided them. The client will send this option if the client_aware_gss_bindings profile option is set. User experience: - The default setting of dns_canonicalize_realm is now "fallback". Hostnames provided from applications will be tried in principal names as given (possibly with shortname qualification), falling back to the canonicalized name. - kinit will now issue a warning if the des3-cbc-sha1 encryption type is used in the reply. This encryption type will be deprecated and removed in future releases. - Added kvno flags --out-cache, --no-store, and --cached-only (inspired by Heimdal's kgetcred). Release 1.20 * Administrator experience: - Added a "disable_pac" realm relation to suppress adding PAC authdata to tickets, for realms which do not need to support S4U requests. - Most credential cache types will use atomic replacement when a cache is reinitialized using kinit or refreshed from the client keytab. - kprop can now propagate databases with a dump size larger than 4GB, if both the client and server are upgraded. - kprop can now work over NATs that change the destination IP address, if the client is upgraded. * Developer experience: - Updated the KDB interface. The sign_authdata() method is replaced with the issue_pac() method, allowing KDB modules to add logon info and other buffers to the PAC issued by the KDC. - Host-based initiator names are better supported in the GSS krb5 mechanism. * Protocol evolution: - Replaced AD-SIGNEDPATH authdata with minimal PACs. - To avoid spurious replay errors, password change requests will not be attempted over UDP until the attempt over TCP fails. - PKINIT will sign its CMS messages with SHA-256 instead of SHA-1. * Code quality: - Updated all code using OpenSSL to be compatible with OpenSSL 3. - Reorganized the libk5crypto build system to allow the OpenSSL back-end to pull in material from the builtin back-end depending on the OpenSSL version. - Simplified the PRNG logic to always use the platform PRNG. - Converted the remaining Tcl tests to Python. Release 1.21 * User experience: - Added a credential cache type providing compatibility with the macOS 11 native credential cache. * Developer experience: - libkadm5 will use the provided krb5_context object to read configuration values, instead of creating its own. - Added an interface to retrieve the ticket session key from a GSS context. * Protocol evolution: - The KDC will no longer issue tickets with RC4 or triple-DES session keys unless explicitly configured with the new allow_rc4 or allow_des3 variables respectively. - The KDC will assume that all services can handle aes256-sha1 session keys unless the service principal has a session_enctypes string attribute. - Support for PAC full KDC checksums has been added to mitigate an S4U2Proxy privilege escalation attack. - The PKINIT client will advertise a more modern set of supported CMS algorithms. * Code quality: - Removed unused code in libkrb5, libkrb5support, and the PKINIT module. - Modernized the KDC code for processing TGS requests, the code for encrypting and decrypting key data, the PAC handling code, and the GSS library packet parsing and composition code. - Improved the test framework's detection of memory errors in daemon processes when used with asan. Release 1.22 * User experience: - The libdefaults configuration variable "request_timeout" can be set to limit the total timeout for KDC requests. When making a KDC request, the client will now wait indefinitely (or until the request timeout has elapsed) on a KDC which accepts a TCP connection, without contacting any additional KDCs. Clients will make fewer DNS queries in some configurations. - The realm configuration variable "sitename" can be set to cause the client to query site-specific DNS records when making KDC requests. * Administrator experience: - Principal aliases are supported in the DB2 and LMDB KDB modules and in the kadmin protocol. (The LDAP KDB module has supported aliases since release 1.7.) - UNIX domain sockets are supported for the Kerberos and kpasswd protocols. - systemd socket activation is supported for krb5kdc and kadmind. * Developer experience: - KDB modules can be be implemented in terms of other modules using the new krb5_db_load_module() function. - The profile library supports the modification of empty profiles and the copying of modified profiles, making it possible to construct an in-memory profile and pass it to krb5_init_context_profile(). - GSS-API applications can pass the GSS_C_CHANNEL_BOUND flag to gss_init_sec_context() to request strict enforcement of channel bindings by the acceptor. * Protocol evolution: - The PKINIT preauth module supports elliptic curve client certificates, ECDH key exchange, and the Microsoft paChecksum2 field. - The IAKERB implementation has been changed to comply with the most recent draft standard and to support realm discovery. - Message-Authenticator is supported in the RADIUS implementation used by the OTP kdcpreauth module. * Code quality: - Removed old-style function declarations, to accomodate compilers which have removed support for them. - Added OSS-Fuzz to the project's continuous integration infrastructure. - Rewrote the GSS per-message token parsing code for improved safety. `Pre-authentication mechanisms` - PW-SALT :rfc:`4120#section-5.2.7.3` - ENC-TIMESTAMP :rfc:`4120#section-5.2.7.2` - SAM-2 - FAST negotiation framework (release 1.8) :rfc:`6113` - PKINIT with FAST on client (release 1.10) :rfc:`6113` - PKINIT :rfc:`4556` - FX-COOKIE :rfc:`6113#section-5.2` - S4U-X509-USER (release 1.8) https://msdn.microsoft.com/en-us/library/cc246091 - OTP (release 1.12) :ref:`otp_preauth` - SPAKE (release 1.17) :ref:`spake` krb5-1.22.1/doc/html/_sources/admin/0000775000175000017500000000000015051422657016774 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/admin/lockout.rst.txt0000664000175000017500000001324215051422642022020 0ustar ghudsonghudson.. _lockout: Account lockout =============== As of release 1.8, the KDC can be configured to lock out principals after a number of failed authentication attempts within a period of time. Account lockout can make it more difficult to attack a principal's password by brute force, but also makes it easy for an attacker to deny access to a principal. Configuring account lockout --------------------------- Account lockout only works for principals with the **+requires_preauth** flag set. Without this flag, the KDC cannot know whether or not a client successfully decrypted the ticket it issued. It is also important to set the **-allow_svr** flag on a principal to protect its password from an off-line dictionary attack through a TGS request. You can set these flags on a principal with :ref:`kadmin(1)` as follows:: kadmin: modprinc +requires_preauth -allow_svr PRINCNAME Account lockout parameters are configured via :ref:`policy objects `. There may be an existing policy associated with user principals (such as the "default" policy), or you may need to create a new one and associate it with each user principal. The policy parameters related to account lockout are: * :ref:`maxfailure `: the number of failed attempts before the principal is locked out * :ref:`failurecountinterval `: the allowable interval between failed attempts * :ref:`lockoutduration `: the amount of time a principal is locked out for Here is an example of setting these parameters on a new policy and associating it with a principal:: kadmin: addpol -maxfailure 10 -failurecountinterval 180 -lockoutduration 60 lockout_policy kadmin: modprinc -policy lockout_policy PRINCNAME Testing account lockout ----------------------- To test that account lockout is working, try authenticating as the principal (hopefully not one that might be in use) multiple times with the wrong password. For instance, if **maxfailure** is set to 2, you might see:: $ kinit user Password for user@KRBTEST.COM: kinit: Password incorrect while getting initial credentials $ kinit user Password for user@KRBTEST.COM: kinit: Password incorrect while getting initial credentials $ kinit user kinit: Client's credentials have been revoked while getting initial credentials Account lockout principal state ------------------------------- A principal entry keeps three pieces of state related to account lockout: * The time of last successful authentication * The time of last failed authentication * A counter of failed attempts The time of last successful authentication is not actually needed for the account lockout system to function, but may be of administrative interest. These fields can be observed with the **getprinc** kadmin command. For example:: kadmin: getprinc user Principal: user@KRBTEST.COM ... Last successful authentication: [never] Last failed authentication: Mon Dec 03 12:30:33 EST 2012 Failed password attempts: 2 ... A principal which has been locked out can be administratively unlocked with the **-unlock** option to the **modprinc** kadmin command:: kadmin: modprinc -unlock PRINCNAME This command will reset the number of failed attempts to 0. KDC replication and account lockout ----------------------------------- The account lockout state of a principal is not replicated by either traditional :ref:`kprop(8)` or incremental propagation. Because of this, the number of attempts an attacker can make within a time period is multiplied by the number of KDCs. For instance, if the **maxfailure** parameter on a policy is 10 and there are four KDCs in the environment (a primary and three replicas), an attacker could make as many as 40 attempts before the principal is locked out on all four KDCs. An administrative unlock is propagated from the primary to the replica KDCs during the next propagation. Propagation of an administrative unlock will cause the counter of failed attempts on each replica to reset to 1 on the next failure. If a KDC environment uses a replication strategy other than kprop or incremental propagation, such as the LDAP KDB module with multi-master LDAP replication, then account lockout state may be replicated between KDCs and the concerns of this section may not apply. .. _disable_lockout: KDC performance and account lockout ----------------------------------- In order to fully track account lockout state, the KDC must write to the the database on each successful and failed authentication. Writing to the database is generally more expensive than reading from it, so these writes may have a significant impact on KDC performance. As of release 1.9, it is possible to turn off account lockout state tracking in order to improve performance, by setting the **disable_last_success** and **disable_lockout** variables in the database module subsection of :ref:`kdc.conf(5)`. For example:: [dbmodules] DB = { disable_last_success = true disable_lockout = true } Of the two variables, setting **disable_last_success** will usually have the largest positive impact on performance, and will still allow account lockout policies to operate. However, it will make it impossible to observe the last successful authentication time with kadmin. KDC setup and account lockout ----------------------------- To update the account lockout state on principals, the KDC must be able to write to the principal database. For the DB2 module, no special setup is required. For the LDAP module, the KDC DN must be granted write access to the principal objects. If the KDC DN has only read access, account lockout will not function. krb5-1.22.1/doc/html/_sources/admin/install_kdc.rst.txt0000664000175000017500000004655515051422642022644 0ustar ghudsonghudsonInstalling KDCs =============== When setting up Kerberos in a production environment, it is best to have multiple replica KDCs alongside with a primary KDC to ensure the continued availability of the Kerberized services. Each KDC contains a copy of the Kerberos database. The primary KDC contains the writable copy of the realm database, which it replicates to the replica KDCs at regular intervals. All database changes (such as password changes) are made on the primary KDC. Replica KDCs provide Kerberos ticket-granting services, but not database administration, when the primary KDC is unavailable. MIT recommends that you install all of your KDCs to be able to function as either the primary or one of the replicas. This will enable you to easily switch your primary KDC with one of the replicas if necessary (see :ref:`switch_primary_replica`). This installation procedure is based on that recommendation. .. warning:: - The Kerberos system relies on the availability of correct time information. Ensure that the primary and all replica KDCs have properly synchronized clocks. - It is best to install and run KDCs on secured and dedicated hardware with limited access. If your KDC is also a file server, FTP server, Web server, or even just a client machine, someone who obtained root access through a security hole in any of those areas could potentially gain access to the Kerberos database. Install and configure the primary KDC ------------------------------------- Install Kerberos either from the OS-provided packages or from the source (See :ref:`do_build`). .. note:: For the purpose of this document we will use the following names:: kerberos.mit.edu - primary KDC kerberos-1.mit.edu - replica KDC ATHENA.MIT.EDU - realm name .k5.ATHENA.MIT.EDU - stash file admin/admin - admin principal See :ref:`mitK5defaults` for the default names and locations of the relevant to this topic files. Adjust the names and paths to your system environment. Edit KDC configuration files ---------------------------- Modify the configuration files, :ref:`krb5.conf(5)` and :ref:`kdc.conf(5)`, to reflect the correct information (such as domain-realm mappings and Kerberos servers names) for your realm. (See :ref:`mitK5defaults` for the recommended default locations for these files). Most of the tags in the configuration have default values that will work well for most sites. There are some tags in the :ref:`krb5.conf(5)` file whose values must be specified, and this section will explain those. If the locations for these configuration files differs from the default ones, set **KRB5_CONFIG** and **KRB5_KDC_PROFILE** environment variables to point to the krb5.conf and kdc.conf respectively. For example:: export KRB5_CONFIG=/yourdir/krb5.conf export KRB5_KDC_PROFILE=/yourdir/kdc.conf krb5.conf ~~~~~~~~~ If you are not using DNS TXT records (see :ref:`mapping_hostnames`), you must specify the **default_realm** in the :ref:`libdefaults` section. If you are not using DNS URI or SRV records (see :ref:`kdc_hostnames` and :ref:`kdc_discovery`), you must include the **kdc** tag for each *realm* in the :ref:`realms` section. To communicate with the kadmin server in each realm, the **admin_server** tag must be set in the :ref:`realms` section. An example krb5.conf file:: [libdefaults] default_realm = ATHENA.MIT.EDU [realms] ATHENA.MIT.EDU = { kdc = kerberos.mit.edu kdc = kerberos-1.mit.edu admin_server = kerberos.mit.edu } kdc.conf ~~~~~~~~ The kdc.conf file can be used to control the listening ports of the KDC and kadmind, as well as realm-specific defaults, the database type and location, and logging. An example kdc.conf file:: [kdcdefaults] kdc_listen = 88 kdc_tcp_listen = 88 [realms] ATHENA.MIT.EDU = { kadmind_port = 749 max_life = 12h 0m 0s max_renewable_life = 7d 0h 0m 0s master_key_type = aes256-cts supported_enctypes = aes256-cts:normal aes128-cts:normal # If the default location does not suit your setup, # explicitly configure the following values: # database_name = /var/krb5kdc/principal # key_stash_file = /var/krb5kdc/.k5.ATHENA.MIT.EDU # acl_file = /var/krb5kdc/kadm5.acl } [logging] # By default, the KDC and kadmind will log output using # syslog. You can instead send log output to files like this: kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmin.log default = FILE:/var/log/krb5lib.log Replace ``ATHENA.MIT.EDU`` and ``kerberos.mit.edu`` with the name of your Kerberos realm and server respectively. .. note:: You have to have write permission on the target directories (these directories must exist) used by **database_name**, **key_stash_file**, and **acl_file**. .. _create_db: Create the KDC database ----------------------- You will use the :ref:`kdb5_util(8)` command on the primary KDC to create the Kerberos database and the optional :ref:`stash_definition`. .. note:: If you choose not to install a stash file, the KDC will prompt you for the master key each time it starts up. This means that the KDC will not be able to start automatically, such as after a system reboot. :ref:`kdb5_util(8)` will prompt you for the master password for the Kerberos database. This password can be any string. A good password is one you can remember, but that no one else can guess. Examples of bad passwords are words that can be found in a dictionary, any common or popular name, especially a famous person (or cartoon character), your username in any form (e.g., forward, backward, repeated twice, etc.), and any of the sample passwords that appear in this manual. One example of a password which might be good if it did not appear in this manual is "MITiys4K5!", which represents the sentence "MIT is your source for Kerberos 5!" (It's the first letter of each word, substituting the numeral "4" for the word "for", and includes the punctuation mark at the end.) The following is an example of how to create a Kerberos database and stash file on the primary KDC, using the :ref:`kdb5_util(8)` command. Replace ``ATHENA.MIT.EDU`` with the name of your Kerberos realm:: shell% kdb5_util create -r ATHENA.MIT.EDU -s Initializing database '/usr/local/var/krb5kdc/principal' for realm 'ATHENA.MIT.EDU', master key name 'K/M@ATHENA.MIT.EDU' You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter KDC database master key: <= Type the master password. Re-enter KDC database master key to verify: <= Type it again. shell% This will create five files in |kdcdir| (or at the locations specified in :ref:`kdc.conf(5)`): * two Kerberos database files, ``principal``, and ``principal.ok`` * the Kerberos administrative database file, ``principal.kadm5`` * the administrative database lock file, ``principal.kadm5.lock`` * the stash file, in this example ``.k5.ATHENA.MIT.EDU``. If you do not want a stash file, run the above command without the **-s** option. For more information on administrating Kerberos database see :ref:`db_operations`. .. _admin_acl: Add administrators to the ACL file ---------------------------------- Next, you need create an Access Control List (ACL) file and put the Kerberos principal of at least one of the administrators into it. This file is used by the :ref:`kadmind(8)` daemon to control which principals may view and make privileged modifications to the Kerberos database files. The ACL filename is determined by the **acl_file** variable in :ref:`kdc.conf(5)`; the default is |kdcdir|\ ``/kadm5.acl``. For more information on Kerberos ACL file see :ref:`kadm5.acl(5)`. .. _addadmin_kdb: Add administrators to the Kerberos database ------------------------------------------- Next you need to add administrative principals (i.e., principals who are allowed to administer Kerberos database) to the Kerberos database. You *must* add at least one principal now to allow communication between the Kerberos administration daemon kadmind and the kadmin program over the network for further administration. To do this, use the kadmin.local utility on the primary KDC. kadmin.local is designed to be run on the primary KDC host without using Kerberos authentication to an admin server; instead, it must have read and write access to the Kerberos database on the local filesystem. The administrative principals you create should be the ones you added to the ACL file (see :ref:`admin_acl`). In the following example, the administrative principal ``admin/admin`` is created:: shell% kadmin.local kadmin.local: addprinc admin/admin@ATHENA.MIT.EDU No policy specified for "admin/admin@ATHENA.MIT.EDU"; assigning "default". Enter password for principal admin/admin@ATHENA.MIT.EDU: <= Enter a password. Re-enter password for principal admin/admin@ATHENA.MIT.EDU: <= Type it again. Principal "admin/admin@ATHENA.MIT.EDU" created. kadmin.local: .. _start_kdc_daemons: Start the Kerberos daemons on the primary KDC --------------------------------------------- At this point, you are ready to start the Kerberos KDC (:ref:`krb5kdc(8)`) and administrative daemons on the primary KDC. To do so, type:: shell% krb5kdc shell% kadmind Each server daemon will fork and run in the background. .. note:: Assuming you want these daemons to start up automatically at boot time, you can add them to the KDC's ``/etc/rc`` or ``/etc/inittab`` file. You need to have a :ref:`stash_definition` in order to do this. You can verify that they started properly by checking for their startup messages in the logging locations you defined in :ref:`krb5.conf(5)` (see :ref:`logging`). For example:: shell% tail /var/log/krb5kdc.log Dec 02 12:35:47 beeblebrox krb5kdc[3187](info): commencing operation shell% tail /var/log/kadmin.log Dec 02 12:35:52 beeblebrox kadmind[3189](info): starting Any errors the daemons encounter while starting will also be listed in the logging output. As an additional verification, check if :ref:`kinit(1)` succeeds against the principals that you have created on the previous step (:ref:`addadmin_kdb`). Run:: shell% kinit admin/admin@ATHENA.MIT.EDU Install the replica KDCs ------------------------ You are now ready to start configuring the replica KDCs. .. note:: Assuming you are setting the KDCs up so that you can easily switch the primary KDC with one of the replicas, you should perform each of these steps on the primary KDC as well as the replica KDCs, unless these instructions specify otherwise. .. _replica_host_key: Create host keytabs for replica KDCs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each KDC needs a ``host`` key in the Kerberos database. These keys are used for mutual authentication when propagating the database dump file from the primary KDC to the secondary KDC servers. On the primary KDC, connect to administrative interface and create the host principal for each of the KDCs' ``host`` services. For example, if the primary KDC were called ``kerberos.mit.edu``, and you had a replica KDC named ``kerberos-1.mit.edu``, you would type the following:: shell% kadmin kadmin: addprinc -randkey host/kerberos.mit.edu No policy specified for "host/kerberos.mit.edu@ATHENA.MIT.EDU"; assigning "default" Principal "host/kerberos.mit.edu@ATHENA.MIT.EDU" created. kadmin: addprinc -randkey host/kerberos-1.mit.edu No policy specified for "host/kerberos-1.mit.edu@ATHENA.MIT.EDU"; assigning "default" Principal "host/kerberos-1.mit.edu@ATHENA.MIT.EDU" created. It is not strictly necessary to have the primary KDC server in the Kerberos database, but it can be handy if you want to be able to swap the primary KDC with one of the replicas. Next, extract ``host`` random keys for all participating KDCs and store them in each host's default keytab file. Ideally, you should extract each keytab locally on its own KDC. If this is not feasible, you should use an encrypted session to send them across the network. To extract a keytab directly on a replica KDC called ``kerberos-1.mit.edu``, you would execute the following command:: kadmin: ktadd host/kerberos-1.mit.edu Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type arcfour-hmac added to keytab FILE:/etc/krb5.keytab. If you are instead extracting a keytab for the replica KDC called ``kerberos-1.mit.edu`` on the primary KDC, you should use a dedicated temporary keytab file for that machine's keytab:: kadmin: ktadd -k /tmp/kerberos-1.keytab host/kerberos-1.mit.edu Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab. The file ``/tmp/kerberos-1.keytab`` can then be installed as ``/etc/krb5.keytab`` on the host ``kerberos-1.mit.edu``. Configure replica KDCs ~~~~~~~~~~~~~~~~~~~~~~ Database propagation copies the contents of the primary's database, but does not propagate configuration files, stash files, or the kadm5 ACL file. The following files must be copied by hand to each replica (see :ref:`mitK5defaults` for the default locations for these files): * krb5.conf * kdc.conf * kadm5.acl * master key stash file Move the copied files into their appropriate directories, exactly as on the primary KDC. kadm5.acl is only needed to allow a replica to swap with the primary KDC. The database is propagated from the primary KDC to the replica KDCs via the :ref:`kpropd(8)` daemon. You must explicitly specify the principals which are allowed to provide Kerberos dump updates on the replica machine with a new database. Create a file named kpropd.acl in the KDC state directory containing the ``host`` principals for each of the KDCs:: host/kerberos.mit.edu@ATHENA.MIT.EDU host/kerberos-1.mit.edu@ATHENA.MIT.EDU .. note:: If you expect that the primary and replica KDCs will be switched at some point of time, list the host principals from all participating KDC servers in kpropd.acl files on all of the KDCs. Otherwise, you only need to list the primary KDC's host principal in the kpropd.acl files of the replica KDCs. Then, add the following line to ``/etc/inetd.conf`` on each KDC (adjust the path to kpropd):: krb5_prop stream tcp nowait root /usr/local/sbin/kpropd kpropd You also need to add the following line to ``/etc/services`` on each KDC, if it is not already present (assuming that the default port is used):: krb5_prop 754/tcp # Kerberos replica propagation Restart inetd daemon. Alternatively, start :ref:`kpropd(8)` as a stand-alone daemon. This is required when incremental propagation is enabled. Now that the replica KDC is able to accept database propagation, you’ll need to propagate the database from the primary server. NOTE: Do not start the replica KDC yet; you still do not have a copy of the primary's database. .. _kprop_to_replicas: Propagate the database to each replica KDC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ First, create a dump file of the database on the primary KDC, as follows:: shell% kdb5_util dump /usr/local/var/krb5kdc/replica_datatrans Then, manually propagate the database to each replica KDC, as in the following example:: shell% kprop -f /usr/local/var/krb5kdc/replica_datatrans kerberos-1.mit.edu Database propagation to kerberos-1.mit.edu: SUCCEEDED You will need a script to dump and propagate the database. The following is an example of a Bourne shell script that will do this. .. note:: Remember that you need to replace ``/usr/local/var/krb5kdc`` with the name of the KDC state directory. :: #!/bin/sh kdclist = "kerberos-1.mit.edu kerberos-2.mit.edu" kdb5_util dump /usr/local/var/krb5kdc/replica_datatrans for kdc in $kdclist do kprop -f /usr/local/var/krb5kdc/replica_datatrans $kdc done You will need to set up a cron job to run this script at the intervals you decided on earlier (see :ref:`db_prop`). Now that the replica KDC has a copy of the Kerberos database, you can start the krb5kdc daemon:: shell% krb5kdc As with the primary KDC, you will probably want to add this command to the KDCs' ``/etc/rc`` or ``/etc/inittab`` files, so they will start the krb5kdc daemon automatically at boot time. Propagation failed? ################### You may encounter the following error messages. For a more detailed discussion on possible causes and solutions click on the error link to be redirected to :ref:`troubleshoot` section. .. include:: ./troubleshoot.rst :start-after: _prop_failed_start: :end-before: _prop_failed_end: Add Kerberos principals to the database --------------------------------------- Once your KDCs are set up and running, you are ready to use :ref:`kadmin(1)` to load principals for your users, hosts, and other services into the Kerberos database. This procedure is described fully in :ref:`principals`. You may occasionally want to use one of your replica KDCs as the primary. This might happen if you are upgrading the primary KDC, or if your primary KDC has a disk crash. See the following section for the instructions. .. _switch_primary_replica: Switching primary and replica KDCs ---------------------------------- You may occasionally want to use one of your replica KDCs as the primary. This might happen if you are upgrading the primary KDC, or if your primary KDC has a disk crash. Assuming you have configured all of your KDCs to be able to function as either the primary KDC or a replica KDC (as this document recommends), all you need to do to make the changeover is: If the primary KDC is still running, do the following on the *old* primary KDC: #. Kill the kadmind process. #. Disable the cron job that propagates the database. #. Run your database propagation script manually, to ensure that the replicas all have the latest copy of the database (see :ref:`kprop_to_replicas`). On the *new* primary KDC: #. Start the :ref:`kadmind(8)` daemon (see :ref:`start_kdc_daemons`). #. Set up the cron job to propagate the database (see :ref:`kprop_to_replicas`). #. Switch the CNAMEs of the old and new primary KDCs. If you can't do this, you'll need to change the :ref:`krb5.conf(5)` file on every client machine in your Kerberos realm. Incremental database propagation -------------------------------- If you expect your Kerberos database to become large, you may wish to set up incremental propagation to replica KDCs. See :ref:`incr_db_prop` for details. krb5-1.22.1/doc/html/_sources/admin/index.rst.txt0000664000175000017500000000103315051422642021442 0ustar ghudsonghudsonFor administrators ================== .. toctree:: :maxdepth: 1 install.rst conf_files/index.rst realm_config.rst database.rst dbtypes.rst lockout.rst conf_ldap.rst appl_servers.rst host_config.rst backup_host.rst pkinit.rst otp.rst spake.rst dictionary.rst princ_dns.rst enctypes.rst https.rst auth_indicator.rst .. toctree:: :maxdepth: 1 admin_commands/index.rst ../mitK5defaults.rst env_variables.rst troubleshoot.rst advanced/index.rst various_envs.rst krb5-1.22.1/doc/html/_sources/admin/dbtypes.rst.txt0000664000175000017500000001474215051422642022020 0ustar ghudsonghudson.. _dbtypes: Database types ============== A Kerberos database can be implemented with one of three built-in database providers, called KDB modules. Software which incorporates the MIT krb5 KDC may also provide its own KDB module. The following subsections describe the three built-in KDB modules and the configuration specific to them. The database type can be configured with the **db_library** variable in the :ref:`dbmodules` subsection for the realm. For example:: [dbmodules] ATHENA.MIT.EDU = { db_library = db2 } If the ``ATHENA.MIT.EDU`` realm subsection contains a **database_module** setting, then the subsection within ``[dbmodules]`` should use that name instead of ``ATHENA.MIT.EDU``. To transition from one database type to another, stop the :ref:`kadmind(8)` service, use ``kdb5_util dump`` to create a dump file, change the **db_library** value and set any appropriate configuration for the new database type, and use ``kdb5_util load`` to create and populate the new database. If the new database type is LDAP, create the new database using ``kdb5_ldap_util`` and populate it from the dump file using ``kdb5_util load -update``. Then restart the :ref:`krb5kdc(8)` and :ref:`kadmind(8)` services. Berkeley database module (db2) ------------------------------ The default KDB module is ``db2``, which uses a version of the Berkeley DB library. It creates four files based on the database pathname. If the pathname ends with ``principal`` then the four files are: * ``principal``, containing principal entry data * ``principal.ok``, a lock file for the principal database * ``principal.kadm5``, containing policy object data * ``principal.kadm5.lock``, a lock file for the policy database For large databases, the :ref:`kdb5_util(8)` **dump** command (perhaps invoked by :ref:`kprop(8)` or by :ref:`kadmind(8)` for incremental propagation) may cause :ref:`krb5kdc(8)` to stop for a noticeable period of time while it iterates over the database. This delay can be avoided by disabling account lockout features so that the KDC does not perform database writes (see :ref:`disable_lockout`). Alternatively, a slower form of iteration can be enabled by setting the **unlockiter** variable to ``true``. For example:: [dbmodules] ATHENA.MIT.EDU = { db_library = db2 unlockiter = true } In rare cases, a power failure or other unclean system shutdown may cause inconsistencies in the internal pointers within a database file, such that ``kdb5_util dump`` cannot retrieve all principal entries in the database. In this situation, it may be possible to retrieve all of the principal data by running ``kdb5_util dump -recurse`` to iterate over the database using the tree pointers instead of the iteration pointers. Running ``kdb5_util dump -rev`` to iterate over the database backwards may also retrieve some of the data which is not retrieved by a normal dump operation. Lightning Memory-Mapped Database module (klmdb) ----------------------------------------------- The klmdb module was added in release 1.17. It uses the LMDB library, and may offer better performance and reliability than the db2 module. It creates four files based on the database pathname. If the pathname ends with ``principal``, then the four files are: * ``principal.mdb``, containing policy object data and most principal entry data * ``principal.mdb-lock``, a lock file for the primary database * ``principal.lockout.mdb``, containing the account lockout attributes (last successful authentication time, last failed authentication time, and number of failed attempts) for each principal entry * ``principal.lockout.mdb-lock``, a lock file for the lockout database Separating out the lockout attributes ensures that the KDC will never block on an administrative operation such as a database dump or load. It also allows the KDC to operate without write access to the primary database. If both account lockout features are disabled (see :ref:`disable_lockout`), the lockout database files will be created but will not subsequently be opened, and the account lockout attributes will always have zero values. Because LMDB creates a memory map to the database files, it requires a configured memory map size which also determines the maximum size of the database. This size is applied equally to the two databases, so twice the configured size will be consumed in the process address space; this is primarily a limitation on 32-bit platforms. The default value of 128 megabytes should be sufficient for several hundred thousand principal entries. If the limit is reached, kadmin operations will fail and the error message "Environment mapsize limit reached" will appear in the kadmind log file. In this case, the **mapsize** variable can be used to increase the map size. The following example sets the map size to 512 megabytes:: [dbmodules] ATHENA.MIT.EDU = { db_library = klmdb mapsize = 512 } LMDB has a configurable maximum number of readers. The default value of 128 should be sufficient for most deployments. If you are going to use a large number of KDC worker processes, it may be necessary to set the **max_readers** variable to a larger number. By default, LMDB synchronizes database files to disk after each write transaction to ensure durability in the case of an unclean system shutdown. The klmdb module always turns synchronization off for the lockout database to ensure reasonable KDC performance, but leaves it on for the primary database. If high throughput for administrative operations (including password changes) is required, the **nosync** variable can be set to "true" to disable synchronization for the primary database. The klmdb module does not support explicit locking with the :ref:`kadmin(1)` **lock** command. LDAP module (kldap) ------------------- The kldap module stores principal and policy data using an LDAP server. To use it you must configure an LDAP server to use the Kerberos schema. See :ref:`conf_ldap` for details. Because :ref:`krb5kdc(8)` is single-threaded, latency in LDAP database accesses may limit KDC operation throughput. If the LDAP server is located on the same server host as the KDC and accessed through an ``ldapi://`` URL, latency should be minimal. If this is not possible, consider starting multiple KDC worker processes with the :ref:`krb5kdc(8)` **-w** option to enable concurrent processing of KDC requests. The kldap module does not support explicit locking with the :ref:`kadmin(1)` **lock** command. krb5-1.22.1/doc/html/_sources/admin/advanced/0000775000175000017500000000000015051422656020540 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/admin/advanced/index.rst.txt0000664000175000017500000000012415051422642023207 0ustar ghudsonghudsonAdvanced topics =============== .. toctree:: :maxdepth: 1 retiring-des.rst krb5-1.22.1/doc/html/_sources/admin/advanced/retiring-des.rst.txt0000664000175000017500000005045315051422642024506 0ustar ghudsonghudson.. _retiring-des: Retiring DES ======================= Version 5 of the Kerberos protocol was originally implemented using the Data Encryption Standard (DES) as a block cipher for encryption. While it was considered secure at the time, advancements in computational ability have rendered DES vulnerable to brute force attacks on its 56-bit keyspace. As such, it is now considered insecure and should not be used (:rfc:`6649`). History ------- DES was used in the original Kerberos implementation, and was the only cryptosystem in krb5 1.0. Partial support for triple-DES (3DES) was added in version 1.1, with full support following in version 1.2. The Advanced Encryption Standard (AES), which supersedes DES, gained partial support in version 1.3.0 of krb5 and full support in version 1.3.2. However, deployments of krb5 using Kerberos databases created with older versions of krb5 will not necessarily start using strong crypto for ordinary operation without administrator intervention. MIT krb5 began flagging deprecated encryption types with release 1.17, and removed DES (single-DES) support in release 1.18. As a consequence, a release prior to 1.18 is required to perform these migrations. Types of keys ------------- * The database master key: This key is not exposed to user requests, but is used to encrypt other key material stored in the kerberos database. The database master key is currently stored as ``K/M`` by default. * Password-derived keys: User principals frequently have keys derived from a password. When a new password is set, the KDC uses various string2key functions to generate keys in the database for that principal. * Keytab keys: Application server principals generally use random keys which are not derived from a password. When the database entry is created, the KDC generates random keys of various enctypes to enter in the database, which are conveyed to the application server and stored in a keytab. * Session keys: These are short-term keys generated by the KDC while processing client requests, with an enctype selected by the KDC. For details on the various enctypes and how enctypes are selected by the KDC for session keys and client/server long-term keys, see :ref:`enctypes`. When using the :ref:`kadmin(1)` interface to generate new long-term keys, the **-e** argument can be used to force a particular set of enctypes, overriding the KDC default values. .. note:: When the KDC is selecting a session key, it has no knowledge about the kerberos installation on the server which will receive the service ticket, only what keys are in the database for the service principal. In order to allow uninterrupted operation to clients while migrating away from DES, care must be taken to ensure that kerberos installations on application server machines are configured to support newer encryption types before keys of those new encryption types are created in the Kerberos database for those server principals. Upgrade procedure ----------------- This procedure assumes that the KDC software has already been upgraded to a modern version of krb5 that supports non-DES keys, so that the only remaining task is to update the actual keys used to service requests. The realm used for demonstrating this procedure, ZONE.MIT.EDU, is an example of the worst-case scenario, where all keys in the realm are DES. The realm was initially created with a very old version of krb5, and **supported_enctypes** in :ref:`kdc.conf(5)` was set to a value appropriate when the KDC was installed, but was not updated as the KDC was upgraded: :: [realms] ZONE.MIT.EDU = { [...] master_key_type = des-cbc-crc supported_enctypes = des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3 } This resulted in the keys for all principals in the realm being forced to DES-only, unless specifically requested using :ref:`kadmin(1)`. Before starting the upgrade, all KDCs were running krb5 1.11, and the database entries for some "high-value" principals were: :: [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc krbtgt/ZONE.MIT.EDU' [...] Number of keys: 1 Key: vno 1, des-cbc-crc:v4 [...] [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc kadmin/admin' [...] Number of keys: 1 Key: vno 15, des-cbc-crc [...] [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc kadmin/changepw' [...] Number of keys: 1 Key: vno 14, des-cbc-crc [...] The ``krbtgt/REALM`` key appears to have never been changed since creation (its kvno is 1), and all three database entries have only a des-cbc-crc key. The krbtgt key and KDC keys ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Perhaps the biggest single-step improvement in the security of the cell is gained by strengthening the key of the ticket-granting service principal, ``krbtgt/REALM``---if this principal's key is compromised, so is the entire realm. Since the server that will handle service tickets for this principal is the KDC itself, it is easy to guarantee that it will be configured to support any encryption types which might be selected. However, the default KDC behavior when creating new keys is to remove the old keys, which would invalidate all existing tickets issued against that principal, rendering the TGTs cached by clients useless. Instead, a new key can be created with the old key retained, so that existing tickets will still function until their scheduled expiry (see :ref:`changing_krbtgt_key`). :: [root@casio krb5kdc]# enctypes=aes256-cts-hmac-sha1-96:normal,\ > aes128-cts-hmac-sha1-96:normal,des3-hmac-sha1:normal,des-cbc-crc:normal [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -e ${enctypes} -randkey \ > -keepold krbtgt/ZONE.MIT.EDU" Authenticating as principal root/admin@ZONE.MIT.EDU with password. Key for "krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU" randomized. .. note:: The new ``krbtgt@REALM`` key should be propagated to replica KDCs immediately so that TGTs issued by the primary KDC can be used to issue service tickets on replica KDCs. Replica KDCs will refuse requests using the new TGT kvno until the new krbtgt entry has been propagated to them. It is necessary to explicitly specify the enctypes for the new database entry, since **supported_enctypes** has not been changed. Leaving **supported_enctypes** unchanged makes a potential rollback operation easier, since all new keys of new enctypes are the result of explicit administrator action and can be easily enumerated. Upgrading the krbtgt key should have minimal user-visible disruption other than that described in the note above, since only clients which list the new enctypes as supported will use them, per the procedure in :ref:`session_key_selection`. Once the krbtgt key is updated, the session and ticket keys for user TGTs will be strong keys, but subsequent requests for service tickets will still get DES keys until the service principals have new keys generated. Application service remains uninterrupted due to the key-selection procedure on the KDC. After the change, the database entry is now: :: [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc krbtgt/ZONE.MIT.EDU' [...] Number of keys: 5 Key: vno 2, aes256-cts-hmac-sha1-96 Key: vno 2, aes128-cts-hmac-sha1-96 Key: vno 2, des3-cbc-sha1 Key: vno 2, des-cbc-crc Key: vno 1, des-cbc-crc:v4 [...] Since the expected disruptions from rekeying the krbtgt principal are minor, after a short testing period, it is appropriate to rekey the other high-value principals, ``kadmin/admin@REALM`` and ``kadmin/changepw@REALM``. These are the service principals used for changing user passwords and updating application keytabs. The kadmin and password-changing services are regular kerberized services, so the session-key-selection algorithm described in :ref:`session_key_selection` applies. It is particularly important to have strong session keys for these services, since user passwords and new long-term keys are conveyed over the encrypted channel. :: [root@casio krb5kdc]# enctypes=aes256-cts-hmac-sha1-96:normal,\ > aes128-cts-hmac-sha1-96:normal,des3-hmac-sha1:normal [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -e ${enctypes} -randkey \ > kadmin/admin" Authenticating as principal root/admin@ZONE.MIT.EDU with password. Key for "kadmin/admin@ZONE.MIT.EDU" randomized. [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -e ${enctypes} -randkey \ > kadmin/changepw" Authenticating as principal root/admin@ZONE.MIT.EDU with password. Key for "kadmin/changepw@ZONE.MIT.EDU" randomized. It is not necessary to retain a single-DES key for these services, since password changes are not part of normal daily workflow, and disruption from a client failure is likely to be minimal. Furthermore, if a kerberos client experiences failure changing a user password or keytab key, this indicates that that client will become inoperative once services are rekeyed to non-DES enctypes. Such problems can be detected early at this stage, giving more time for corrective action. Adding strong keys to application servers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Before switching the default enctypes for new keys over to strong enctypes, it may be desired to test upgrading a handful of services with the new configuration before flipping the switch for the defaults. This still requires using the **-e** argument in :ref:`kadmin(1)` to get non-default enctypes: :: [root@casio krb5kdc]# enctypes=aes256-cts-hmac-sha1-96:normal,\ > aes128-cts-hmac-sha1-96:normal,des3-cbc-sha1:normal,des-cbc-crc:normal [root@casio krb5kdc]# kadmin -r ZONE.MIT.EDU -p zephyr/zephyr@ZONE.MIT.EDU -k -t \ > /etc/zephyr/krb5.keytab -q "ktadd -e ${enctypes} \ > -k /etc/zephyr/krb5.keytab zephyr/zephyr@ZONE.MIT.EDU" Authenticating as principal zephyr/zephyr@ZONE.MIT.EDU with keytab /etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type des-cbc-crc added to keytab WRFILE:/etc/zephyr/krb5.keytab. Be sure to remove the old keys from the application keytab, per best practice. :: [root@casio krb5kdc]# k5srvutil -f /etc/zephyr/krb5.keytab delold Authenticating as principal zephyr/zephyr@ZONE.MIT.EDU with keytab /etc/zephyr/krb5.keytab. Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 3 removed from keytab WRFILE:/etc/zephyr/krb5.keytab. Adding strong keys by default ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Once the high-visibility services have been rekeyed, it is probably appropriate to change :ref:`kdc.conf(5)` to generate keys with the new encryption types by default. This enables server administrators to generate new enctypes with the **change** subcommand of :ref:`k5srvutil(1)`, and causes user password changes to add new encryption types for their entries. It will probably be necessary to implement administrative controls to cause all user principal keys to be updated in a reasonable period of time, whether by forcing password changes or a password synchronization service that has access to the current password and can add the new keys. :: [realms] ZONE.MIT.EDU = { supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des3-hmac-sha1:normal des-cbc-crc:normal .. note:: The krb5kdc process must be restarted for these changes to take effect. At this point, all service administrators can update their services and the servers behind them to take advantage of strong cryptography. If necessary, the server's krb5 installation should be configured and/or upgraded to a version supporting non-DES keys. See :ref:`enctypes` for krb5 version and configuration settings. Only when the service is configured to accept non-DES keys should the key version number be incremented and new keys generated (``k5srvutil change && k5srvutil delold``). :: root@dr-willy:~# k5srvutil change Authenticating as principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with keytab /etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type AES-256 CTS mode with 96-bit SHA-1 HMAC added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type AES-128 CTS mode with 96-bit SHA-1 HMAC added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/etc/krb5.keytab. root@dr-willy:~# klist -e -k -t /etc/krb5.keytab Keytab name: WRFILE:/etc/krb5.keytab KVNO Timestamp Principal ---- ----------------- -------------------------------------------------------- 2 10/10/12 17:03:59 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (DES cbc mode with CRC-32) 3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (AES-256 CTS mode with 96-bit SHA-1 HMAC) 3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (AES-128 CTS mode with 96-bit SHA-1 HMAC) 3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (Triple DES cbc mode with HMAC/sha1) 3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (DES cbc mode with CRC-32) root@dr-willy:~# k5srvutil delold Authenticating as principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with keytab /etc/krb5.keytab. Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 2 removed from keytab WRFILE:/etc/krb5.keytab. When a single service principal is shared by multiple backend servers in a load-balanced environment, it may be necessary to schedule downtime or adjust the population in the load-balanced pool in order to propagate the updated keytab to all hosts in the pool with minimal service interruption. Removing DES keys from usage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This situation remains something of a testing or transitory state, as new DES keys are still being generated, and will be used if requested by a client. To make more progress removing DES from the realm, the KDC should be configured to not generate such keys by default. .. note:: An attacker posing as a client can implement a brute force attack against a DES key for any principal, if that key is in the current (highest-kvno) key list. This attack is only possible if **allow_weak_crypto = true** is enabled on the KDC. Setting the **+requires_preauth** flag on a principal forces this attack to be an online attack, much slower than the offline attack otherwise available to the attacker. However, setting this flag on a service principal is not always advisable; see the entry in :ref:`add_principal` for details. The following KDC configuration will not generate DES keys by default: :: [realms] ZONE.MIT.EDU = { supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des3-hmac-sha1:normal .. note:: As before, the KDC process must be restarted for this change to take effect. It is best practice to update kdc.conf on all KDCs, not just the primary, to avoid unpleasant surprises should the primary fail and a replica need to be promoted. It is now appropriate to remove the legacy single-DES key from the ``krbtgt/REALM`` entry: :: [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -randkey -keepold \ > krbtgt/ZONE.MIT.EDU" Authenticating as principal host/admin@ATHENA.MIT.EDU with password. Key for "krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU" randomized. After the maximum ticket lifetime has passed, the old database entry should be removed. :: [root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'purgekeys krbtgt/ZONE.MIT.EDU' Authenticating as principal root/admin@ZONE.MIT.EDU with password. Old keys for principal "krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU" purged. After the KDC is restarted with the new **supported_enctypes**, all user password changes and application keytab updates will not generate DES keys by default. :: contents-vnder-pressvre:~> kpasswd zonetest@ZONE.MIT.EDU Password for zonetest@ZONE.MIT.EDU: [enter old password] Enter new password: [enter new password] Enter it again: [enter new password] Password changed. contents-vnder-pressvre:~> kadmin -r ZONE.MIT.EDU -q 'getprinc zonetest' [...] Number of keys: 3 Key: vno 9, aes256-cts-hmac-sha1-96 Key: vno 9, aes128-cts-hmac-sha1-96 Key: vno 9, des3-cbc-sha1 [...] [kaduk@glossolalia ~]$ kadmin -p kaduk@ZONE.MIT.EDU -r ZONE.MIT.EDU -k \ > -t kaduk-zone.keytab -q 'ktadd -k kaduk-zone.keytab kaduk@ZONE.MIT.EDU' Authenticating as principal kaduk@ZONE.MIT.EDU with keytab kaduk-zone.keytab. Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:kaduk-zone.keytab. Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:kaduk-zone.keytab. Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type des3-cbc-sha1 added to keytab WRFILE:kaduk-zone.keytab. Once all principals have been re-keyed, DES support can be disabled on the KDC (**allow_weak_crypto = false**), and client machines can remove **allow_weak_crypto = true** from their :ref:`krb5.conf(5)` configuration files, completing the migration. **allow_weak_crypto** takes precedence over all places where DES enctypes could be explicitly configured. DES keys will not be used, even if they are present, when **allow_weak_crypto = false**. Support for legacy services ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If there remain legacy services which do not support non-DES enctypes (such as older versions of AFS), **allow_weak_crypto** must remain enabled on the KDC. Client machines need not have this setting, though---applications which require DES can use API calls to allow weak crypto on a per-request basis, overriding the system krb5.conf. However, having **allow_weak_crypto** set on the KDC means that any principals which have a DES key in the database could still use those keys. To minimize the use of DES in the realm and restrict it to just legacy services which require DES, it is necessary to remove all other DES keys. The realm has been configured such that at password and keytab change, no DES keys will be generated by default. The task then reduces to requiring user password changes and having server administrators update their service keytabs. Administrative outreach will be necessary, and if the desire to eliminate DES is sufficiently strong, the KDC administrators may choose to randkey any principals which have not been rekeyed after some timeout period, forcing the user to contact the helpdesk for access. The Database Master Key ----------------------- This procedure does not alter ``K/M@REALM``, the key used to encrypt key material in the Kerberos database. (This is the key stored in the stash file on the KDC if stash files are used.) However, the security risk of a single-DES key for ``K/M`` is minimal, given that access to material encrypted in ``K/M`` (the Kerberos database) is generally tightly controlled. If an attacker can gain access to the encrypted database, they likely have access to the stash file as well, rendering the weak cryptography broken by non-cryptographic means. As such, upgrading ``K/M`` to a stronger encryption type is unlikely to be a high-priority task. Is is possible to upgrade the master key used for the database, if desired. Using :ref:`kdb5_util(8)`'s **add_mkey**, **use_mkey**, and **update_princ_encryption** commands, a new master key can be added and activated for use on new key material, and the existing entries converted to the new master key. krb5-1.22.1/doc/html/_sources/admin/install_appl_srv.rst.txt0000664000175000017500000000716115051422642023717 0ustar ghudsonghudsonUNIX Application Servers ======================== An application server is a host that provides one or more services over the network. Application servers can be "secure" or "insecure." A "secure" host is set up to require authentication from every client connecting to it. An "insecure" host will still provide Kerberos authentication, but will also allow unauthenticated clients to connect. If you have Kerberos V5 installed on all of your client machines, MIT recommends that you make your hosts secure, to take advantage of the security that Kerberos authentication affords. However, if you have some clients that do not have Kerberos V5 installed, you can run an insecure server, and still take advantage of Kerberos V5's single sign-on capability. .. _keytab_file: The keytab file --------------- All Kerberos server machines need a keytab file to authenticate to the KDC. By default on UNIX-like systems this file is named |keytab|. The keytab file is an local copy of the host's key. The keytab file is a potential point of entry for a break-in, and if compromised, would allow unrestricted access to its host. The keytab file should be readable only by root, and should exist only on the machine's local disk. The file should not be part of any backup of the machine, unless access to the backup data is secured as tightly as access to the machine's root password. In order to generate a keytab for a host, the host must have a principal in the Kerberos database. The procedure for adding hosts to the database is described fully in :ref:`principals`. (See :ref:`replica_host_key` for a brief description.) The keytab is generated by running :ref:`kadmin(1)` and issuing the :ref:`ktadd` command. For example, to generate a keytab file to allow the host ``trillium.mit.edu`` to authenticate for the services host, ftp, and pop, the administrator ``joeadmin`` would issue the command (on ``trillium.mit.edu``):: trillium% kadmin Authenticating as principal root/admin@ATHENA.MIT.EDU with password. Password for root/admin@ATHENA.MIT.EDU: kadmin: ktadd host/trillium.mit.edu ftp/trillium.mit.edu pop/trillium.mit.edu Entry for principal host/trillium.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab. kadmin: Entry for principal ftp/trillium.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab. kadmin: Entry for principal pop/trillium.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab. kadmin: quit trillium% If you generate the keytab file on another host, you need to get a copy of the keytab file onto the destination host (``trillium``, in the above example) without sending it unencrypted over the network. Some advice about secure hosts ------------------------------ Kerberos V5 can protect your host from certain types of break-ins, but it is possible to install Kerberos V5 and still leave your host vulnerable to attack. Obviously an installation guide is not the place to try to include an exhaustive list of countermeasures for every possible attack, but it is worth noting some of the larger holes and how to close them. We recommend that backups of secure machines exclude the keytab file (|keytab|). If this is not possible, the backups should at least be done locally, rather than over a network, and the backup tapes should be physically secured. The keytab file and any programs run by root, including the Kerberos V5 binaries, should be kept on local disk. The keytab file should be readable only by root. krb5-1.22.1/doc/html/_sources/admin/realm_config.rst.txt0000664000175000017500000002666315051422642023000 0ustar ghudsonghudsonRealm configuration decisions ============================= Before installing Kerberos V5, it is necessary to consider the following issues: * The name of your Kerberos realm (or the name of each realm, if you need more than one). * How you will assign your hostnames to Kerberos realms. * Which ports your KDC and and kadmind services will use, if they will not be using the default ports. * How many replica KDCs you need and where they should be located. * The hostnames of your primary and replica KDCs. * How frequently you will propagate the database from the primary KDC to the replica KDCs. Realm name ---------- Although your Kerberos realm can be any ASCII string, convention is to make it the same as your domain name, in upper-case letters. For example, hosts in the domain ``example.com`` would be in the Kerberos realm:: EXAMPLE.COM If you need multiple Kerberos realms, MIT recommends that you use descriptive names which end with your domain name, such as:: BOSTON.EXAMPLE.COM HOUSTON.EXAMPLE.COM .. _mapping_hostnames: Mapping hostnames onto Kerberos realms -------------------------------------- Mapping hostnames onto Kerberos realms is done in one of three ways. The first mechanism works through a set of rules in the :ref:`domain_realm` section of :ref:`krb5.conf(5)`. You can specify mappings for an entire domain or on a per-hostname basis. Typically you would do this by specifying the mappings for a given domain or subdomain and listing the exceptions. The second mechanism is to use KDC host-based service referrals. With this method, the KDC's krb5.conf has a full [domain_realm] mapping for hosts, but the clients do not, or have mappings for only a subset of the hosts they might contact. When a client needs to contact a server host for which it has no mapping, it will ask the client realm's KDC for the service ticket, and will receive a referral to the appropriate service realm. To use referrals, clients must be running MIT krb5 1.6 or later, and the KDC must be running MIT krb5 1.7 or later. The **host_based_services** and **no_host_referral** variables in the :ref:`kdc_realms` section of :ref:`kdc.conf(5)` can be used to fine-tune referral behavior on the KDC. It is also possible for clients to use DNS TXT records, if **dns_lookup_realm** is enabled in :ref:`krb5.conf(5)`. Such lookups are disabled by default because DNS is an insecure protocol and security holes could result if DNS records are spoofed. If enabled, the client will try to look up a TXT record formed by prepending the prefix ``_kerberos`` to the hostname in question. If that record is not found, the client will attempt a lookup by prepending ``_kerberos`` to the host's domain name, then its parent domain, up to the top-level domain. For the hostname ``boston.engineering.example.com``, the names looked up would be:: _kerberos.boston.engineering.example.com _kerberos.engineering.example.com _kerberos.example.com _kerberos.com The value of the first TXT record found is taken as the realm name. Even if you do not choose to use this mechanism within your site, you may wish to set it up anyway, for use when interacting with other sites. Ports for the KDC and admin services ------------------------------------ The default ports used by Kerberos are port 88 for the KDC and port 749 for the admin server. You can, however, choose to run on other ports, as long as they are specified in each host's :ref:`krb5.conf(5)` files or in DNS SRV records, and the :ref:`kdc.conf(5)` file on each KDC. For a more thorough treatment of port numbers used by the Kerberos V5 programs, refer to the :ref:`conf_firewall`. Replica KDCs ------------ Replica KDCs provide an additional source of Kerberos ticket-granting services in the event of inaccessibility of the primary KDC. The number of replica KDCs you need and the decision of where to place them, both physically and logically, depends on the specifics of your network. Kerberos authentication requires that each client be able to contact a KDC. Therefore, you need to anticipate any likely reason a KDC might be unavailable and have a replica KDC to take up the slack. Some considerations include: * Have at least one replica KDC as a backup, for when the primary KDC is down, is being upgraded, or is otherwise unavailable. * If your network is split such that a network outage is likely to cause a network partition (some segment or segments of the network to become cut off or isolated from other segments), have a replica KDC accessible to each segment. * If possible, have at least one replica KDC in a different building from the primary, in case of power outages, fires, or other localized disasters. .. _kdc_hostnames: Hostnames for KDCs ------------------ MIT recommends that your KDCs have a predefined set of CNAME records (DNS hostname aliases), such as ``kerberos`` for the primary KDC and ``kerberos-1``, ``kerberos-2``, ... for the replica KDCs. This way, if you need to swap a machine, you only need to change a DNS entry, rather than having to change hostnames. As of MIT krb5 1.4, clients can locate a realm's KDCs through DNS using SRV records (:rfc:`2782`), assuming the Kerberos realm name is also a DNS domain name. These records indicate the hostname and port number to contact for that service, optionally with weighting and prioritization. The domain name used in the SRV record name is the realm name. Several different Kerberos-related service names are used: _kerberos._udp This is for contacting any KDC by UDP. This entry will be used the most often. Normally you should list port 88 on each of your KDCs. _kerberos._tcp This is for contacting any KDC by TCP. Normally you should use port 88. This entry should be omitted if the KDC does not listen on TCP ports, as was the default prior to release 1.13. _kerberos-master._udp This entry should refer to those KDCs, if any, that will immediately see password changes to the Kerberos database. If a user is logging in and the password appears to be incorrect, the client will retry with the primary KDC before failing with an "incorrect password" error given. If you have only one KDC, or for whatever reason there is no accessible KDC that would get database changes faster than the others, you do not need to define this entry. _kerberos-adm._tcp This should list port 749 on your primary KDC. Support for it is not complete at this time, but it will eventually be used by the :ref:`kadmin(1)` program and related utilities. For now, you will also need the **admin_server** variable in :ref:`krb5.conf(5)`. _kerberos-master._tcp The corresponding TCP port for _kerberos-master._udp, assuming the primary KDC listens on a TCP port. _kpasswd._udp This entry should list port 464 on your primary KDC. It is used when a user changes her password. If this entry is not defined but a _kerberos-adm._tcp entry is defined, the client will use the _kerberos-adm._tcp entry with the port number changed to 464. _kpasswd._tcp The corresponding TCP port for _kpasswd._udp. The DNS SRV specification requires that the hostnames listed be the canonical names, not aliases. So, for example, you might include the following records in your (BIND-style) zone file:: $ORIGIN foobar.com. _kerberos TXT "FOOBAR.COM" kerberos CNAME daisy kerberos-1 CNAME use-the-force-luke kerberos-2 CNAME bunny-rabbit _kerberos._udp SRV 0 0 88 daisy SRV 0 0 88 use-the-force-luke SRV 0 0 88 bunny-rabbit _kerberos-master._udp SRV 0 0 88 daisy _kerberos-adm._tcp SRV 0 0 749 daisy _kpasswd._udp SRV 0 0 464 daisy Clients can also be configured with the explicit location of services using the **kdc**, **master_kdc**, **admin_server**, and **kpasswd_server** variables in the :ref:`realms` section of :ref:`krb5.conf(5)`. Even if some clients will be configured with explicit server locations, providing SRV records will still benefit unconfigured clients, and be useful for other sites. Clients can be configured with the **sitename** realm variable (new in release 1.22). If a site name is set, the client first attempts SRV record lookups with ".*sitename*._sites" inserted after the service and protocol name and before the Kerberos realm. Site-specific records may indicate servers more proximal to the client, allowing for faster access. .. _kdc_discovery: KDC Discovery ------------- As of MIT krb5 1.15, clients can also locate KDCs in DNS through URI records (:rfc:`7553`). Limitations with the SRV record format may result in extra DNS queries in situations where a client must failover to other transport types, or find a primary server. The URI record can convey more information about a realm's KDCs with a single query. The client performs a query for the following URI records: * ``_kerberos.REALM`` for finding KDCs. * ``_kerberos-adm.REALM`` for finding kadmin services. * ``_kpasswd.REALM`` for finding password services. The URI record includes a priority, weight, and a URI string that consists of case-insensitive colon separated fields, in the form ``scheme:[flags]:transport:residual``. * *scheme* defines the registered URI type. It should always be ``krb5srv``. * *flags* contains zero or more flag characters. Currently the only valid flag is ``m``, which indicates that the record is for a primary server. * *transport* defines the transport type of the residual URL or address. Accepted values are ``tcp``, ``udp``, or ``kkdcp`` for the MS-KKDCP type. * *residual* contains the hostname, IP address, or URL to be contacted using the specified transport, with an optional port extension. The MS-KKDCP transport type uses a HTTPS URL, and can include a port and/or path extension. An example of URI records in a zone file:: _kerberos.EXAMPLE.COM URI 10 1 krb5srv:m:tcp:kdc1.example.com URI 20 1 krb5srv:m:udp:kdc2.example.com:89 URI 40 1 krb5srv::udp:10.10.0.23 URI 30 1 krb5srv::kkdcp:https://proxy:89/auth URI lookups are enabled by default, and can be disabled by setting **dns_uri_lookup** in the :ref:`libdefaults` section of :ref:`krb5.conf(5)` to False. When enabled, URI lookups take precedence over SRV lookups, falling back to SRV lookups if no URI records are found. The **sitename** variable in the :ref:`realms` section of :ref:`krb5.conf(5)` applies to URI lookups as well as SRV lookups. .. _db_prop: Database propagation -------------------- The Kerberos database resides on the primary KDC, and must be propagated regularly (usually by a cron job) to the replica KDCs. In deciding how frequently the propagation should happen, you will need to balance the amount of time the propagation takes against the maximum reasonable amount of time a user should have to wait for a password change to take effect. If the propagation time is longer than this maximum reasonable time (e.g., you have a particularly large database, you have a lot of replicas, or you experience frequent network delays), you may wish to cut down on your propagation delay by performing the propagation in parallel. To do this, have the primary KDC propagate the database to one set of replicas, and then have each of these replicas propagate the database to additional replicas. See also :ref:`incr_db_prop` krb5-1.22.1/doc/html/_sources/admin/various_envs.rst.txt0000664000175000017500000000115115051422642023057 0ustar ghudsonghudsonVarious links ============= Whitepapers ----------- #. https://kerberos.org/software/whitepapers.html Tutorials --------- #. Fulvio Ricciardi _ Troubleshooting --------------- #. https://wiki.ncsa.illinois.edu/display/ITS/Windows+Kerberos+Troubleshooting #. https://www.shrubbery.net/solaris9ab/SUNWaadm/SYSADV6/p27.html #. https://docs.oracle.com/cd/E19253-01/816-4557/trouble-1/index.html #. https://docs.microsoft.com/en-us/previous-versions/tn-archive/bb463167(v=technet.10)#EBAA #. https://bugs.launchpad.net/ubuntu/+source/libpam-heimdal/+bug/86528 krb5-1.22.1/doc/html/_sources/admin/enctypes.rst.txt0000664000175000017500000002247615051422642022203 0ustar ghudsonghudson.. _enctypes: Encryption types ================ Kerberos can use a variety of cipher algorithms to protect data. A Kerberos **encryption type** (also known as an **enctype**) is a specific combination of a cipher algorithm with an integrity algorithm to provide both confidentiality and integrity to data. Enctypes in requests -------------------- Clients make two types of requests (KDC-REQ) to the KDC: AS-REQs and TGS-REQs. The client uses the AS-REQ to obtain initial tickets (typically a Ticket-Granting Ticket (TGT)), and uses the TGS-REQ to obtain service tickets. The KDC uses three different keys when issuing a ticket to a client: * The long-term key of the service: the KDC uses this to encrypt the actual service ticket. The KDC only uses the first long-term key in the most recent kvno for this purpose. * The session key: the KDC randomly chooses this key and places one copy inside the ticket and the other copy inside the encrypted part of the reply. * The reply-encrypting key: the KDC uses this to encrypt the reply it sends to the client. For AS replies, this is a long-term key of the client principal. For TGS replies, this is either the session key of the authenticating ticket, or a subsession key. Each of these keys is of a specific enctype. Each request type allows the client to submit a list of enctypes that it is willing to accept. For the AS-REQ, this list affects both the session key selection and the reply-encrypting key selection. For the TGS-REQ, this list only affects the session key selection. .. _session_key_selection: Session key selection --------------------- The KDC chooses the session key enctype by taking the intersection of its **permitted_enctypes** list, the list of long-term keys for the most recent kvno of the service, and the client's requested list of enctypes. Starting in krb5-1.21, all services are assumed to support aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session keys will not be issued by default. Starting in krb5-1.11, it is possible to set a string attribute on a service principal to control what session key enctypes the KDC may issue for service tickets for that principal, overriding the service's long-term keys and the assumption of aes256-cts-hmac-sha1-96 support. See :ref:`set_string` in :ref:`kadmin(1)` for details. Choosing enctypes for a service ------------------------------- Generally, a service should have a key of the strongest enctype that both it and the KDC support. If the KDC is running a release earlier than krb5-1.11, it is also useful to generate an additional key for each enctype that the service can support. The KDC will only use the first key in the list of long-term keys for encrypting the service ticket, but the additional long-term keys indicate the other enctypes that the service supports. As noted above, starting with release krb5-1.11, there are additional configuration settings that control session key enctype selection independently of the set of long-term keys that the KDC has stored for a service principal. Configuration variables ----------------------- The following ``[libdefaults]`` settings in :ref:`krb5.conf(5)` will affect how enctypes are chosen. **allow_weak_crypto** defaults to *false* starting with krb5-1.8. When *false*, removes weak enctypes from **permitted_enctypes**, **default_tkt_enctypes**, and **default_tgs_enctypes**. Do not set this to *true* unless the use of weak enctypes is an acceptable risk for your environment and the weak enctypes are required for backward compatibility. **allow_des3** was added in release 1.21 and defaults to *false*. Unless this flag is set to *true*, the KDC will not issue tickets with des3-cbc-sha1 session keys. In a future release, this flag will control whether des3-cbc-sha1 is permitted in similar fashion to weak enctypes. **allow_rc4** was added in release 1.21 and defaults to *false*. Unless this flag is set to *true*, the KDC will not issue tickets with arcfour-hmac session keys. In a future release, this flag will control whether arcfour-hmac is permitted in similar fashion to weak enctypes. **permitted_enctypes** controls the set of enctypes that a service will permit for session keys and for ticket and authenticator encryption. The KDC and other programs that access the Kerberos database will ignore keys of non-permitted enctypes. Starting in release 1.18, this setting also acts as the default for **default_tkt_enctypes** and **default_tgs_enctypes**. **default_tkt_enctypes** controls the default set of enctypes that the Kerberos client library requests when making an AS-REQ. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. **default_tgs_enctypes** controls the default set of enctypes that the Kerberos client library requests when making a TGS-REQ. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. The following per-realm setting in :ref:`kdc.conf(5)` affects the generation of long-term keys. **supported_enctypes** controls the default set of enctype-salttype pairs that :ref:`kadmind(8)` will use for generating long-term keys, either randomly or from passwords Enctype compatibility --------------------- See :ref:`Encryption_types` for additional information about enctypes. ========================== ========== ======== ======= enctype weak? krb5 Windows ========================== ========== ======== ======= des-cbc-crc weak <1.18 >=2000 des-cbc-md4 weak <1.18 ? des-cbc-md5 weak <1.18 >=2000 des3-cbc-sha1 deprecated >=1.1 none arcfour-hmac deprecated >=1.3 >=2000 arcfour-hmac-exp weak >=1.3 >=2000 aes128-cts-hmac-sha1-96 >=1.3 >=Vista aes256-cts-hmac-sha1-96 >=1.3 >=Vista aes128-cts-hmac-sha256-128 >=1.15 none aes256-cts-hmac-sha384-192 >=1.15 none camellia128-cts-cmac >=1.9 none camellia256-cts-cmac >=1.9 none ========================== ========== ======== ======= krb5 releases 1.18 and later do not support single-DES. krb5 releases 1.8 and later disable the single-DES enctypes by default. Microsoft Windows releases Windows 7 and later disable single-DES enctypes by default. krb5 releases 1.17 and later flag deprecated encryption types (including ``des3-cbc-sha1`` and ``arcfour-hmac``) in KDC logs and kadmin output. krb5 release 1.19 issues a warning during initial authentication if ``des3-cbc-sha1`` is used. Future releases will disable ``des3-cbc-sha1`` by default and eventually remove support for it. Migrating away from older encryption types ------------------------------------------ Administrator intervention may be required to migrate a realm away from legacy encryption types, especially if the realm was created using krb5 release 1.2 or earlier. This migration should be performed before upgrading to krb5 versions which disable or remove support for legacy encryption types. If there is a **supported_enctypes** setting in :ref:`kdc.conf(5)` on the KDC, make sure that it does not include weak or deprecated encryption types. This will ensure that newly created keys do not use those encryption types by default. Check the ``krbtgt/REALM`` principal using the :ref:`kadmin(1)` **getprinc** command. If it lists a weak or deprecated encryption type as the first key, it must be migrated using the procedure in :ref:`changing_krbtgt_key`. Check the ``kadmin/history`` principal, which should have only one key entry. If it uses a weak or deprecated encryption type, it should be upgraded following the notes in :ref:`updating_history_key`. Check the other kadmin principals: kadmin/changepw, kadmin/admin, and any kadmin/hostname principals that may exist. These principals can be upgraded with **change_password -randkey** in kadmin. Check the ``K/M`` entry. If it uses a weak or deprecated encryption type, it should be upgraded following the procedure in :ref:`updating_master_key`. User and service principals using legacy encryption types can be enumerated with the :ref:`kdb5_util(8)` **tabdump keyinfo** command. Service principals can be migrated with a keytab rotation on the service host, which can be accomplished using the :ref:`k5srvutil(1)` **change** and **delold** commands. Allow enough time for existing tickets to expire between the change and delold operations. User principals with password-based keys can be migrated with a password change. The realm administrator can set a password expiration date using the :ref:`kadmin(1)` **modify_principal -pwexpire** command to force a password change. If a legacy encryption type has not yet been disabled by default in the version of krb5 running on the KDC, it can be disabled administratively with the **permitted_enctypes** variable. For example, setting **permitted_enctypes** to ``DEFAULT -des3 -rc4`` will cause any database keys of the triple-DES and RC4 encryption types to be ignored. krb5-1.22.1/doc/html/_sources/admin/spake.rst.txt0000664000175000017500000000447415051422642021452 0ustar ghudsonghudson.. _spake: SPAKE Preauthentication ======================= SPAKE preauthentication (added in release 1.17) uses public key cryptography techniques to protect against :ref:`password dictionary attacks `. Unlike :ref:`PKINIT `, it does not require any additional infrastructure such as certificates; it simply needs to be turned on. Using SPAKE preauthentication may modestly increase the CPU and network load on the KDC. SPAKE preauthentication can use one of four elliptic curve groups for its password-authenticated key exchange. The recommended group is ``edwards25519``; three NIST curves (``P-256``, ``P-384``, and ``P-521``) are also supported. By default, SPAKE with the ``edwards25519`` group is enabled on clients, but the KDC does not offer SPAKE by default. To turn it on, set the **spake_preauth_groups** variable in :ref:`libdefaults` to a list of allowed groups. This variable affects both the client and the KDC. Simply setting it to ``edwards25519`` is recommended:: [libdefaults] spake_preauth_groups = edwards25519 Set the **+requires_preauth** and **-allow_svr** flags on client principal entries, as you would for any preauthentication mechanism:: kadmin: modprinc +requires_preauth -allow_svr PRINCNAME Clients which do not implement SPAKE preauthentication will fall back to encrypted timestamp. An active attacker can force a fallback to encrypted timestamp by modifying the initial KDC response, defeating the protection against dictionary attacks. To prevent this fallback on clients which do implement SPAKE preauthentication, set the **disable_encrypted_timestamp** variable to ``true`` in the :ref:`realms` subsection for realms whose KDCs offer SPAKE preauthentication. By default, SPAKE preauthentication requires an extra network round trip to the KDC during initial authentication. If most of the clients in a realm support SPAKE, this extra round trip can be eliminated using an optimistic challenge, by setting the **spake_preauth_kdc_challenge** variable in :ref:`kdcdefaults` to a single group name:: [kdcdefaults] spake_preauth_kdc_challenge = edwards25519 Using optimistic challenge will cause the KDC to do extra work for initial authentication requests that do not result in SPAKE preauthentication, but will save work when SPAKE preauthentication is used. krb5-1.22.1/doc/html/_sources/admin/database.rst.txt0000664000175000017500000006121515051422642022107 0ustar ghudsonghudsonDatabase administration ======================= A Kerberos database contains all of a realm's Kerberos principals, their passwords, and other administrative information about each principal. For the most part, you will use the :ref:`kdb5_util(8)` program to manipulate the Kerberos database as a whole, and the :ref:`kadmin(1)` program to make changes to the entries in the database. (One notable exception is that users will use the :ref:`kpasswd(1)` program to change their own passwords.) The kadmin program has its own command-line interface, to which you type the database administrating commands. :ref:`kdb5_util(8)` provides a means to create, delete, load, or dump a Kerberos database. It also contains commands to roll over the database master key, and to stash a copy of the key so that the :ref:`kadmind(8)` and :ref:`krb5kdc(8)` daemons can use the database without manual input. :ref:`kadmin(1)` provides for the maintenance of Kerberos principals, password policies, and service key tables (keytabs). Normally it operates as a network client using Kerberos authentication to communicate with :ref:`kadmind(8)`, but there is also a variant, named kadmin.local, which directly accesses the Kerberos database on the local filesystem (or through LDAP). kadmin.local is necessary to set up enough of the database to be able to use the remote version. kadmin can authenticate to the admin server using the service principal ``kadmin/admin`` or ``kadmin/HOST`` (where *HOST* is the hostname of the admin server). If the credentials cache contains a ticket for either service principal and the **-c** ccache option is specified, that ticket is used to authenticate to KADM5. Otherwise, the **-p** and **-k** options are used to specify the client Kerberos principal name used to authenticate. Once kadmin has determined the principal name, it requests a ``kadmin/admin`` Kerberos service ticket from the KDC, and uses that service ticket to authenticate to KADM5. See :ref:`kadmin(1)` for the available kadmin and kadmin.local commands and options. .. _principals: Principals ---------- Each entry in the Kerberos database contains a Kerberos principal and the attributes and policies associated with that principal. To add a principal to the database, use the :ref:`kadmin(1)` **add_principal** command. User principals should usually be created with the ``+requires_preauth -allow_svr`` options to help mitigate dictionary attacks (see :ref:`dictionary`):: kadmin: addprinc +requires_preauth -allow_svr alice Enter password for principal "alice@KRBTEST.COM": Re-enter password for principal "alice@KRBTEST.COM": User principals which will authenticate with :ref:`pkinit` should instead by created with the ``-nokey`` option: kadmin: addprinc -nokey alice Service principals can be created with the ``-nokey`` option; long-term keys will be added when a keytab is generated:: kadmin: addprinc -nokey host/foo.mit.edu kadmin: ktadd -k foo.keytab host/foo.mit.edu Entry for principal host/foo.mit.edu with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:foo.keytab. Entry for principal host/foo.mit.edu with kvno 1, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:foo.keytab. To modify attributes of an existing principal, use the kadmin **modify_principal** command:: kadmin: modprinc -expire tomorrow alice Principal "alice@KRBTEST.COM" modified. To delete a principal, use the kadmin **delete_principal** command:: kadmin: delprinc alice Are you sure you want to delete the principal "alice@KRBTEST.COM"? (yes/no): yes Principal "alice@KRBTEST.COM" deleted. Make sure that you have removed this principal from all ACLs before reusing. To change a principal's password, use the kadmin **change_password** command. Password changes made through kadmin are subject to the same password policies as would apply to password changes made through :ref:`kpasswd(1)`. To view the attributes of a principal, use the kadmin` **get_principal** command. To generate a listing of principals, use the kadmin **list_principals** command. To give a principal additional names, use the kadmin **add_alias** command to create aliases to the principal (new in release 1.22). Aliases can be removed with the **delete_principal** command. .. _policies: Policies -------- A policy is a set of rules governing passwords. Policies can dictate minimum and maximum password lifetimes, minimum number of characters and character classes a password must contain, and the number of old passwords kept in the database. To add a new policy, use the :ref:`kadmin(1)` **add_policy** command:: kadmin: addpol -maxlife "1 year" -history 3 stduser To modify attributes of a principal, use the kadmin **modify_policy** command. To delete a policy, use the kadmin **delete_policy** command. To associate a policy with a principal, use the kadmin **modify_principal** command with the **-policy** option: kadmin: modprinc -policy stduser alice Principal "alice@KRBTEST.COM" modified. A principal entry may be associated with a nonexistent policy, either because the policy did not exist at the time of associated or was deleted afterwards. kadmin will warn when associated a principal with a nonexistent policy, and will annotate the policy name with "[does not exist]" in the **get_principal** output. .. _updating_history_key: Updating the history key ~~~~~~~~~~~~~~~~~~~~~~~~ If a policy specifies a number of old keys kept of two or more, the stored old keys are encrypted in a history key, which is found in the key data of the ``kadmin/history`` principal. Currently there is no support for proper rollover of the history key, but you can change the history key (for example, to use a better encryption type) at the cost of invalidating currently stored old keys. To change the history key, run:: kadmin: change_password -randkey kadmin/history This command will fail if you specify the **-keepold** flag. Only one new history key will be created, even if you specify multiple key/salt combinations. In the future, we plan to migrate towards encrypting old keys in the master key instead of the history key, and implementing proper rollover support for stored old keys. .. _privileges: Privileges ---------- Administrative privileges for the Kerberos database are stored in the file :ref:`kadm5.acl(5)`. .. note:: A common use of an admin instance is so you can grant separate permissions (such as administrator access to the Kerberos database) to a separate Kerberos principal. For example, the user ``joeadmin`` might have a principal for his administrative use, called ``joeadmin/admin``. This way, ``joeadmin`` would obtain ``joeadmin/admin`` tickets only when he actually needs to use those permissions. .. _db_operations: Operations on the Kerberos database ----------------------------------- The :ref:`kdb5_util(8)` command is the primary tool for administrating the Kerberos database when using the DB2 or LMDB modules (see :ref:`dbtypes`). Creating a database is described in :ref:`create_db`. To create a stash file using the master password (because the database was not created with one using the ``create -s`` flag, or after restoring from a backup which did not contain the stash file), use the kdb5_util **stash** command:: $ kdb5_util stash kdb5_util: Cannot find/read stored master key while reading master key kdb5_util: Warning: proceeding without master key Enter KDC database master key: <= Type the KDC database master password. To destroy a database, use the kdb5_util destroy command:: $ kdb5_util destroy Deleting KDC database stored in '/var/krb5kdc/principal', are you sure? (type 'yes' to confirm)? yes OK, deleting database '/var/krb5kdc/principal'... ** Database '/var/krb5kdc/principal' destroyed. .. _restore_from_dump: Dumping and loading a Kerberos database ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To dump a Kerberos database into a text file for backup or transfer purposes, use the :ref:`kdb5_util(8)` **dump** command on one of the KDCs:: $ kdb5_util dump dumpfile $ kbd5_util dump -verbose dumpfile kadmin/admin@ATHENA.MIT.EDU krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU kadmin/history@ATHENA.MIT.EDU K/M@ATHENA.MIT.EDU kadmin/changepw@ATHENA.MIT.EDU You may specify which principals to dump, using full principal names including realm:: $ kdb5_util dump -verbose someprincs K/M@ATHENA.MIT.EDU kadmin/admin@ATHENA.MIT.EDU kadmin/admin@ATHENA.MIT.EDU K/M@ATHENA.MIT.EDU To restore a Kerberos database dump from a file, use the :ref:`kdb5_util(8)` **load** command:: $ kdb5_util load dumpfile To update an existing database with a partial dump file containing only some principals, use the ``-update`` flag:: $ kdb5_util load -update someprincs .. note:: If the database file exists, and the *-update* flag was not given, *kdb5_util* will overwrite the existing database. .. _updating_master_key: Updating the master key ~~~~~~~~~~~~~~~~~~~~~~~ Starting with release 1.7, :ref:`kdb5_util(8)` allows the master key to be changed using a rollover process, with minimal loss of availability. To roll over the master key, follow these steps: #. On the primary KDC, run ``kdb5_util list_mkeys`` to view the current master key version number (KVNO). If you have never rolled over the master key before, this will likely be version 1:: $ kdb5_util list_mkeys Master keys for Principal: K/M@KRBTEST.COM KVNO: 1, Enctype: aes256-cts-hmac-sha384-192, Active on: Thu Jan 01 00:00:00 UTC 1970 * #. On the primary KDC, run ``kdb5_util use_mkey 1`` to ensure that a master key activation list is present in the database. This step is unnecessary in release 1.11.4 or later, or if the database was initially created with release 1.7 or later. #. On the primary KDC, run ``kdb5_util add_mkey -s`` to create a new master key and write it to the stash file. Enter a secure password when prompted. If this is the first time you are changing the master key, the new key will have version 2. The new master key will not be used until you make it active. #. Propagate the database to all replica KDCs, either manually or by waiting until the next scheduled propagation. If you do not have any replica KDCs, you can skip this and the next step. #. On each replica KDC, run ``kdb5_util list_mkeys`` to verify that the new master key is present, and then ``kdb5_util stash`` to write the new master key to the replica KDC's stash file. #. On the primary KDC, run ``kdb5_util use_mkey 2`` to begin using the new master key. Replace ``2`` with the version of the new master key, as appropriate. You can optionally specify a date for the new master key to become active; by default, it will become active immediately. Prior to release 1.12, :ref:`kadmind(8)` must be restarted for this change to take full effect. #. On the primary KDC, run ``kdb5_util update_princ_encryption``. This command will iterate over the database and re-encrypt all keys in the new master key. If the database is large and uses DB2, the primary KDC will become unavailable while this command runs, but clients should fail over to replica KDCs (if any are present) during this time period. In release 1.13 and later, you can instead run ``kdb5_util -x unlockiter update_princ_encryption`` to use unlocked iteration; this variant will take longer, but will keep the database available to the KDC and kadmind while it runs. #. Wait until the above changes have propagated to all replica KDCs and until all running KDC and kadmind processes have serviced requests using updated principal entries. #. On the primary KDC, run ``kdb5_util purge_mkeys`` to clean up the old master key. .. _ops_on_ldap: Operations on the LDAP database ------------------------------- The :ref:`kdb5_ldap_util(8)` command is the primary tool for administrating the Kerberos database when using the LDAP module. Creating an LDAP Kerberos database is describe in :ref:`conf_ldap`. To view a list of realms in the LDAP database, use the kdb5_ldap_util **list** command:: $ kdb5_ldap_util list KRBTEST.COM To modify the attributes of a realm, use the kdb5_ldap_util **modify** command. For example, to change the default realm's maximum ticket life:: $ kdb5_ldap_util modify -maxtktlife "10 hours" To display the attributes of a realm, use the kdb5_ldap_util **view** command:: $ kdb5_ldap_util view Realm Name: KRBTEST.COM Maximum Ticket Life: 0 days 00:10:00 To remove a realm from the LDAP database, destroying its contents, use the kdb5_ldap_util **destroy** command:: $ kdb5_ldap_util destroy Deleting KDC database of 'KRBTEST.COM', are you sure? (type 'yes' to confirm)? yes OK, deleting database of 'KRBTEST.COM'... ** Database of 'KRBTEST.COM' destroyed. Ticket Policy operations ~~~~~~~~~~~~~~~~~~~~~~~~ Unlike the DB2 and LMDB modules, the LDAP module supports ticket policy objects, which can be associated with principals to restrict maximum ticket lifetimes and set mandatory principal flags. Ticket policy objects are distinct from the password policies described earlier on this page, and are chiefly managed through kdb5_ldap_util rather than kadmin. To create a new ticket policy, use the kdb5_ldap_util **create_policy** command:: $ kdb5_ldap_util create_policy -maxrenewlife "2 days" users To associate a ticket policy with a principal, use the :ref:`kadmin(1)` **modify_principal** (or **add_principal**) command with the **-x tktpolicy=**\ *policy* option:: $ kadmin.local modprinc -x tktpolicy=users alice To remove a ticket policy reference from a principal, use the same command with an empty *policy*:: $ kadmin.local modprinc -x tktpolicy= alice To list the existing ticket policy objects, use the kdb5_ldap_util **list_policy** command:: $ kdb5_ldap_util list_policy users To modify the attributes of a ticket policy object, use the kdb5_ldap_util **modify_policy** command:: $ kdb5_ldap_util modify_policy -allow_svr +requires_preauth users To view the attributes of a ticket policy object, use the kdb5_ldap_util **view_policy** command:: $ kdb5_ldap_util view_policy users Ticket policy: users Maximum renewable life: 2 days 00:00:00 Ticket flags: REQUIRES_PRE_AUTH DISALLOW_SVR To destroy an ticket policy object, use the kdb5_ldap_util **destroy_policy** command:: $ kdb5_ldap_util destroy_policy users This will delete the policy object 'users', are you sure? (type 'yes' to confirm)? yes ** policy object 'users' deleted. .. _xrealm_authn: Cross-realm authentication -------------------------- In order for a KDC in one realm to authenticate Kerberos users in a different realm, it must share a key with the KDC in the other realm. In both databases, there must be krbtgt service principals for both realms. For example, if you need to do cross-realm authentication between the realms ``ATHENA.MIT.EDU`` and ``EXAMPLE.COM``, you would need to add the principals ``krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU`` and ``krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM`` to both databases. These principals must all have the same passwords, key version numbers, and encryption types; this may require explicitly setting the key version number with the **-kvno** option. In the ATHENA.MIT.EDU and EXAMPLE.COM cross-realm case, the administrators would run the following commands on the KDCs in both realms:: shell%: kadmin.local -e "aes256-cts:normal" kadmin: addprinc -requires_preauth krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM Enter password for principal krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM: Re-enter password for principal krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM: kadmin: addprinc -requires_preauth krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU Enter password for principal krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU: Enter password for principal krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU: kadmin: .. note:: Even if most principals in a realm are generally created with the **requires_preauth** flag enabled, this flag is not desirable on cross-realm authentication keys because doing so makes it impossible to disable preauthentication on a service-by-service basis. Disabling it as in the example above is recommended. .. note:: It is very important that these principals have good passwords. MIT recommends that TGT principal passwords be at least 26 characters of random ASCII text. .. _changing_krbtgt_key: Changing the krbtgt key ----------------------- A Kerberos Ticket Granting Ticket (TGT) is a service ticket for the principal ``krbtgt/REALM``. The key for this principal is created when the Kerberos database is initialized and need not be changed. However, it will only have the encryption types supported by the KDC at the time of the initial database creation. To allow use of newer encryption types for the TGT, this key has to be changed. Changing this key using the normal :ref:`kadmin(1)` **change_password** command would invalidate any previously issued TGTs. Therefore, when changing this key, normally one should use the **-keepold** flag to change_password to retain the previous key in the database as well as the new key. For example:: kadmin: change_password -randkey -keepold krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU .. warning:: After issuing this command, the old key is still valid and is still vulnerable to (for instance) brute force attacks. To completely retire an old key or encryption type, run the kadmin **purgekeys** command to delete keys with older kvnos, ideally first making sure that all tickets issued with the old keys have expired. Only the first krbtgt key of the newest key version is used to encrypt ticket-granting tickets. However, the set of encryption types present in the krbtgt keys is used by default to determine the session key types supported by the krbtgt service (see :ref:`session_key_selection`). Because non-MIT Kerberos clients sometimes send a limited set of encryption types when making AS requests, it can be important for the krbtgt service to support multiple encryption types. This can be accomplished by giving the krbtgt principal multiple keys, which is usually as simple as not specifying any **-e** option when changing the krbtgt key, or by setting the **session_enctypes** string attribute on the krbtgt principal (see :ref:`set_string`). Due to a bug in releases 1.8 through 1.13, renewed and forwarded tickets may not work if the original ticket was obtained prior to a krbtgt key change and the modified ticket is obtained afterwards. Upgrading the KDC to release 1.14 or later will correct this bug. .. _incr_db_prop: Incremental database propagation -------------------------------- Overview ~~~~~~~~ At some very large sites, dumping and transmitting the database can take more time than is desirable for changes to propagate from the primary KDC to the replica KDCs. The incremental propagation support added in the 1.7 release is intended to address this. With incremental propagation enabled, all programs on the primary KDC that change the database also write information about the changes to an "update log" file, maintained as a circular buffer of a certain size. A process on each replica KDC connects to a service on the primary KDC (currently implemented in the :ref:`kadmind(8)` server) and periodically requests the changes that have been made since the last check. By default, this check is done every two minutes. Incremental propagation uses the following entries in the per-realm data in the KDC config file (See :ref:`kdc.conf(5)`): ====================== =============== =========================================== iprop_enable *boolean* If *true*, then incremental propagation is enabled, and (as noted below) normal kprop propagation is disabled. The default is *false*. iprop_master_ulogsize *integer* Indicates the number of entries that should be retained in the update log. The default is 1000; the maximum number is 2500. iprop_replica_poll *time interval* Indicates how often the replica should poll the primary KDC for changes to the database. The default is two minutes. iprop_port *integer* Specifies the port number to be used for incremental propagation. This is required in both primary and replica configuration files. iprop_resync_timeout *integer* Specifies the number of seconds to wait for a full propagation to complete. This is optional on replica configurations. Defaults to 300 seconds (5 minutes). iprop_logfile *file name* Specifies where the update log file for the realm database is to be stored. The default is to use the *database_name* entry from the realms section of the config file :ref:`kdc.conf(5)`, with *.ulog* appended. (NOTE: If database_name isn't specified in the realms section, perhaps because the LDAP database back end is being used, or the file name is specified in the *dbmodules* section, then the hard-coded default for *database_name* is used. Determination of the *iprop_logfile* default value will not use values from the *dbmodules* section.) ====================== =============== =========================================== Both primary and replica sides must have a principal named ``kiprop/hostname`` (where *hostname* is the lowercase, fully-qualified, canonical name for the host) registered in the Kerberos database, and have keys for that principal stored in the default keytab file (|keytab|). The ``kiprop/hostname`` principal may have been created automatically for the primary KDC, but it must always be created for replica KDCs. On the primary KDC side, the ``kiprop/hostname`` principal must be listed in the kadmind ACL file :ref:`kadm5.acl(5)`, and given the **p** privilege (see :ref:`privileges`). On the replica KDC side, :ref:`kpropd(8)` should be run. When incremental propagation is enabled, it will connect to the kadmind on the primary KDC and start requesting updates. The normal kprop mechanism is disabled by the incremental propagation support. However, if the replica has been unable to fetch changes from the primary KDC for too long (network problems, perhaps), the log on the primary may wrap around and overwrite some of the updates that the replica has not yet retrieved. In this case, the replica will instruct the primary KDC to dump the current database out to a file and invoke a one-time kprop propagation, with special options to also convey the point in the update log at which the replica should resume fetching incremental updates. Thus, all the keytab and ACL setup previously described for kprop propagation is still needed. If an environment has a large number of replicas, it may be desirable to arrange them in a hierarchy instead of having the primary serve updates to every replica. To do this, run ``kadmind -proponly`` on each intermediate replica, and ``kpropd -A upstreamhostname`` on downstream replicas to direct each one to the appropriate upstream replica. There are several known restrictions in the current implementation: - The incremental update protocol does not transport changes to policy objects. Any policy changes on the primary will result in full resyncs to all replicas. - The replica's KDB module must support locking; it cannot be using the LDAP KDB module. - The primary and replica must be able to initiate TCP connections in both directions, without an intervening NAT. Sun/MIT incremental propagation differences ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sun donated the original code for supporting incremental database propagation to MIT. Some changes have been made in the MIT source tree that will be visible to administrators. (These notes are based on Sun's patches. Changes to Sun's implementation since then may not be reflected here.) The Sun config file support looks for ``sunw_dbprop_enable``, ``sunw_dbprop_master_ulogsize``, and ``sunw_dbprop_slave_poll``. The incremental propagation service is implemented as an ONC RPC service. In the Sun implementation, the service is registered with rpcbind (also known as portmapper) and the client looks up the port number to contact. In the MIT implementation, where interaction with some modern versions of rpcbind doesn't always work well, the port number must be specified in the config file on both the primary and replica sides. The Sun implementation hard-codes pathnames in ``/var/krb5`` for the update log and the per-replica kprop dump files. In the MIT implementation, the pathname for the update log is specified in the config file, and the per-replica dump files are stored in |kdcdir|\ ``/replica_datatrans_hostname``. krb5-1.22.1/doc/html/_sources/admin/pkinit.rst.txt0000664000175000017500000003434315051422642021643 0ustar ghudsonghudson.. _pkinit: PKINIT configuration ==================== PKINIT is a preauthentication mechanism for Kerberos 5 which uses X.509 certificates to authenticate the KDC to clients and vice versa. PKINIT can also be used to enable anonymity support, allowing clients to communicate securely with the KDC or with application servers without authenticating as a particular client principal. Creating certificates --------------------- PKINIT requires an X.509 certificate for the KDC and one for each client principal which will authenticate using PKINIT. For anonymous PKINIT, a KDC certificate is required, but client certificates are not. A commercially issued server certificate can be used for the KDC certificate, but generally cannot be used for client certificates. The instruction in this section describe how to establish a certificate authority and create standard PKINIT certificates. Skip this section if you are using a commercially issued server certificate as the KDC certificate for anonymous PKINIT, or if you are configuring a client to use an Active Directory KDC. Generating a certificate authority certificate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can establish a new certificate authority (CA) for use with a PKINIT deployment with the commands:: openssl genrsa -out cakey.pem 2048 openssl req -key cakey.pem -new -x509 -out cacert.pem -days 3650 The second command will ask for the values of several certificate fields. These fields can be set to any values. You can adjust the expiration time of the CA certificate by changing the number after ``-days``. Since the CA certificate must be deployed to client machines each time it changes, it should normally have an expiration time far in the future; however, expiration times after 2037 may cause interoperability issues in rare circumstances. The result of these commands will be two files, cakey.pem and cacert.pem. cakey.pem will contain a 2048-bit RSA private key, which must be carefully protected. cacert.pem will contain the CA certificate, which must be placed in the filesystems of the KDC and each client host. cakey.pem will be required to create KDC and client certificates. Generating a KDC certificate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A KDC certificate for use with PKINIT is required to have some unusual fields, which makes generating them with OpenSSL somewhat complicated. First, you will need a file containing the following:: [kdc_cert] basicConstraints=CA:FALSE keyUsage=nonRepudiation,digitalSignature,keyEncipherment,keyAgreement extendedKeyUsage=1.3.6.1.5.2.3.5 subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer issuerAltName=issuer:copy subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name [kdc_princ_name] realm=EXP:0,GeneralString:${ENV::REALM} principal_name=EXP:1,SEQUENCE:kdc_principal_seq [kdc_principal_seq] name_type=EXP:0,INTEGER:2 name_string=EXP:1,SEQUENCE:kdc_principals [kdc_principals] princ1=GeneralString:krbtgt princ2=GeneralString:${ENV::REALM} If the above contents are placed in extensions.kdc, you can generate and sign a KDC certificate with the following commands:: openssl genrsa -out kdckey.pem 2048 openssl req -new -out kdc.req -key kdckey.pem env REALM=YOUR_REALMNAME openssl x509 -req -in kdc.req \ -CAkey cakey.pem -CA cacert.pem -out kdc.pem -days 365 \ -extfile extensions.kdc -extensions kdc_cert -CAcreateserial rm kdc.req The second command will ask for the values of certificate fields, which can be set to any values. In the third command, substitute your KDC's realm name for YOUR_REALMNAME. You can adjust the certificate's expiration date by changing the number after ``-days``. Remember to create a new KDC certificate before the old one expires. The result of this operation will be in two files, kdckey.pem and kdc.pem. Both files must be placed in the KDC's filesystem. kdckey.pem, which contains the KDC's private key, must be carefully protected. If you examine the KDC certificate with ``openssl x509 -in kdc.pem -text -noout``, OpenSSL will not know how to display the KDC principal name in the Subject Alternative Name extension, so it will appear as ``othername:``. This is normal and does not mean anything is wrong with the KDC certificate. Generating client certificates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PKINIT client certificates also must have some unusual certificate fields. To generate a client certificate with OpenSSL for a single-component principal name, you will need an extensions file (different from the KDC extensions file above) containing:: [client_cert] basicConstraints=CA:FALSE keyUsage=digitalSignature,keyEncipherment,keyAgreement extendedKeyUsage=1.3.6.1.5.2.3.4 subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer issuerAltName=issuer:copy subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:princ_name [princ_name] realm=EXP:0,GeneralString:${ENV::REALM} principal_name=EXP:1,SEQUENCE:principal_seq [principal_seq] name_type=EXP:0,INTEGER:1 name_string=EXP:1,SEQUENCE:principals [principals] princ1=GeneralString:${ENV::CLIENT} If the above contents are placed in extensions.client, you can generate and sign a client certificate with the following commands:: openssl genrsa -out clientkey.pem 2048 openssl req -new -key clientkey.pem -out client.req env REALM=YOUR_REALMNAME CLIENT=YOUR_PRINCNAME openssl x509 \ -CAkey cakey.pem -CA cacert.pem -req -in client.req \ -extensions client_cert -extfile extensions.client \ -days 365 -out client.pem rm client.req Normally, the first two commands should be run on the client host, and the resulting client.req file transferred to the certificate authority host for the third command. As in the previous steps, the second command will ask for the values of certificate fields, which can be set to any values. In the third command, substitute your realm's name for YOUR_REALMNAME and the client's principal name (without realm) for YOUR_PRINCNAME. You can adjust the certificate's expiration date by changing the number after ``-days``. The result of this operation will be two files, clientkey.pem and client.pem. Both files must be present on the client's host; clientkey.pem, which contains the client's private key, must be protected from access by others. As in the KDC certificate, OpenSSL will display the client principal name as ``othername:`` in the Subject Alternative Name extension of a PKINIT client certificate. If the client principal name contains more than one component (e.g. ``host/example.com@REALM``), the ``[principals]`` section of ``extensions.client`` must be altered to contain multiple entries. (Simply setting ``CLIENT`` to ``host/example.com`` would generate a certificate for ``host\/example.com@REALM`` which would not match the multi-component principal name.) For a two-component principal, the section should read:: [principals] princ1=GeneralString:${ENV::CLIENT1} princ2=GeneralString:${ENV::CLIENT2} The environment variables ``CLIENT1`` and ``CLIENT2`` must then be set to the first and second components when running ``openssl x509``. Configuring the KDC ------------------- The KDC must have filesystem access to the KDC certificate (kdc.pem) and the KDC private key (kdckey.pem). Configure the following relation in the KDC's :ref:`kdc.conf(5)` file, either in the :ref:`kdcdefaults` section or in a :ref:`kdc_realms` subsection (with appropriate pathnames):: pkinit_identity = FILE:/var/lib/krb5kdc/kdc.pem,/var/lib/krb5kdc/kdckey.pem If any clients will authenticate using regular (as opposed to anonymous) PKINIT, the KDC must also have filesystem access to the CA certificate (cacert.pem), and the following configuration (with the appropriate pathname):: pkinit_anchors = FILE:/var/lib/krb5kdc/cacert.pem Because of the larger size of requests and responses using PKINIT, you may also need to allow TCP access to the KDC:: kdc_tcp_listen = 88 Restart the :ref:`krb5kdc(8)` daemon to pick up the configuration changes. The principal entry for each PKINIT-using client must be configured to require preauthentication. Ensure this with the command:: kadmin -q 'modprinc +requires_preauth YOUR_PRINCNAME' Starting with release 1.12, it is possible to remove the long-term keys of a principal entry, which can save some space in the database and help to clarify some PKINIT-related error conditions by not asking for a password:: kadmin -q 'purgekeys -all YOUR_PRINCNAME' These principal options can also be specified at principal creation time as follows:: kadmin -q 'add_principal +requires_preauth -nokey YOUR_PRINCNAME' By default, the KDC requires PKINIT client certificates to have the standard Extended Key Usage and Subject Alternative Name attributes for PKINIT. Starting in release 1.16, it is possible to authorize client certificates based on the subject or other criteria instead of the standard PKINIT Subject Alternative Name, by setting the **pkinit_cert_match** string attribute on each client principal entry. For example:: kadmin set_string user@REALM pkinit_cert_match "CN=user@REALM$" The **pkinit_cert_match** string attribute follows the syntax used by the :ref:`krb5.conf(5)` **pkinit_cert_match** relation. To allow the use of non-PKINIT client certificates, it will also be necessary to disable key usage checking using the **pkinit_eku_checking** relation; for example:: [kdcdefaults] pkinit_eku_checking = none Configuring the clients ----------------------- Client hosts must be configured to trust the issuing authority for the KDC certificate. For a newly established certificate authority, the client host must have filesystem access to the CA certificate (cacert.pem) and the following relation in :ref:`krb5.conf(5)` in the appropriate :ref:`realms` subsection (with appropriate pathnames):: pkinit_anchors = FILE:/etc/krb5/cacert.pem If the KDC certificate is a commercially issued server certificate, the issuing certificate is most likely included in a system directory. You can specify it by filename as above, or specify the whole directory like so:: pkinit_anchors = DIR:/etc/ssl/certs A commercially issued server certificate will usually not have the standard PKINIT principal name or Extended Key Usage extensions, so the following additional configuration is required:: pkinit_eku_checking = kpServerAuth pkinit_kdc_hostname = hostname.of.kdc.certificate Multiple **pkinit_kdc_hostname** relations can be configured to recognize multiple KDC certificates. If the KDC is an Active Directory domain controller, setting **pkinit_kdc_hostname** is necessary, but it should not be necessary to set **pkinit_eku_checking**. To perform regular (as opposed to anonymous) PKINIT authentication, a client host must have filesystem access to a client certificate (client.pem), and the corresponding private key (clientkey.pem). Configure the following relations in the client host's :ref:`krb5.conf(5)` file in the appropriate :ref:`realms` subsection (with appropriate pathnames):: pkinit_identities = FILE:/etc/krb5/client.pem,/etc/krb5/clientkey.pem If the KDC and client are properly configured, it should now be possible to run ``kinit username`` without entering a password. .. _anonymous_pkinit: Anonymous PKINIT ---------------- Anonymity support in Kerberos allows a client to obtain a ticket without authenticating as any particular principal. Such a ticket can be used as a FAST armor ticket, or to securely communicate with an application server anonymously. To configure anonymity support, you must generate or otherwise procure a KDC certificate and configure the KDC host, but you do not need to generate any client certificates. On the KDC, you must set the **pkinit_identity** variable to provide the KDC certificate, but do not need to set the **pkinit_anchors** variable or store the issuing certificate if you won't have any client certificates to verify. On client hosts, you must set the **pkinit_anchors** variable (and possibly **pkinit_kdc_hostname** and **pkinit_eku_checking**) in order to trust the issuing authority for the KDC certificate, but do not need to set the **pkinit_identities** variable. Anonymity support is not enabled by default. To enable it, you must create the principal ``WELLKNOWN/ANONYMOUS`` using the command:: kadmin -q 'addprinc -randkey WELLKNOWN/ANONYMOUS' Some Kerberos deployments include application servers which lack proper access control, and grant some level of access to any user who can authenticate. In such an environment, enabling anonymity support on the KDC would present a security issue. If you need to enable anonymity support for TGTs (for use as FAST armor tickets) without enabling anonymous authentication to application servers, you can set the variable **restrict_anonymous_to_tgt** to ``true`` in the appropriate :ref:`kdc_realms` subsection of the KDC's :ref:`kdc.conf(5)` file. To obtain anonymous credentials on a client, run ``kinit -n``, or ``kinit -n @REALMNAME`` to specify a realm. The resulting tickets will have the client name ``WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS``. Freshness tokens ---------------- Freshness tokens can ensure that the client has recently had access to its certificate private key. If freshness tokens are not required by the KDC, a client program with temporary possession of the private key can compose requests for future timestamps and use them later. In release 1.17 and later, freshness tokens are supported by the client and are sent by the KDC when the client indicates support for them. Because not all clients support freshness tokens yet, they are not required by default. To check if freshness tokens are supported by a realm's clients, look in the KDC logs for the lines:: PKINIT: freshness token received from PKINIT: no freshness token received from To require freshness tokens for all clients in a realm (except for clients authenticating anonymously), set the **pkinit_require_freshness** variable to ``true`` in the appropriate :ref:`kdc_realms` subsection of the KDC's :ref:`kdc.conf(5)` file. To test that this option is in effect, run ``kinit -X disable_freshness`` and verify that authentication is unsuccessful. krb5-1.22.1/doc/html/_sources/admin/auth_indicator.rst.txt0000664000175000017500000000443515051422642023341 0ustar ghudsonghudson.. _auth_indicator: Authentication indicators ========================= As of release 1.14, the KDC can be configured to annotate tickets if the client authenticated using a stronger preauthentication mechanism such as :ref:`PKINIT ` or :ref:`OTP `. These annotations are called "authentication indicators." Service principals can be configured to require particular authentication indicators in order to authenticate to that service. An authentication indicator value can be any string chosen by the KDC administrator; there are no pre-set values. To use authentication indicators with PKINIT or OTP, first configure the KDC to include an indicator when that preauthentication mechanism is used. For PKINIT, use the **pkinit_indicator** variable in :ref:`kdc.conf(5)`. For OTP, use the **indicator** variable in the token type definition, or specify the indicators in the **otp** user string as described in :ref:`otp_preauth`. To require an indicator to be present in order to authenticate to a service principal, set the **require_auth** string attribute on the principal to the indicator value to be required. If you wish to allow one of several indicators to be accepted, you can specify multiple indicator values separated by spaces. For example, a realm could be configured to set the authentication indicator value "strong" when PKINIT is used to authenticate, using a setting in the :ref:`kdc_realms` subsection:: pkinit_indicator = strong A service principal could be configured to require the "strong" authentication indicator value:: $ kadmin setstr host/high.value.server require_auth strong Password for user/admin@KRBTEST.COM: A user who authenticates with PKINIT would be able to obtain a ticket for the service principal:: $ kinit -X X509_user_identity=FILE:/my/cert.pem,/my/key.pem user $ kvno host/high.value.server host/high.value.server@KRBTEST.COM: kvno = 1 but a user who authenticates with a password would not:: $ kinit user Password for user@KRBTEST.COM: $ kvno host/high.value.server kvno: KDC policy rejects request while getting credentials for host/high.value.server@KRBTEST.COM GSSAPI server applications can inspect authentication indicators through the :ref:`auth-indicators ` name attribute. krb5-1.22.1/doc/html/_sources/admin/backup_host.rst.txt0000664000175000017500000000340115051422642022636 0ustar ghudsonghudsonBackups of secure hosts ======================= When you back up a secure host, you should exclude the host's keytab file from the backup. If someone obtained a copy of the keytab from a backup, that person could make any host masquerade as the host whose keytab was compromised. In many configurations, knowledge of the host's keytab also allows root access to the host. This could be particularly dangerous if the compromised keytab was from one of your KDCs. If the machine has a disk crash and the keytab file is lost, it is easy to generate another keytab file. (See :ref:`add_princ_kt`.) If you are unable to exclude particular files from backups, you should ensure that the backups are kept as secure as the host's root password. Backing up the Kerberos database -------------------------------- As with any file, it is possible that your Kerberos database could become corrupted. If this happens on one of the replica KDCs, you might never notice, since the next automatic propagation of the database would install a fresh copy. However, if it happens to the primary KDC, the corrupted database would be propagated to all of the replicas during the next propagation. For this reason, MIT recommends that you back up your Kerberos database regularly. Because the primary KDC is continuously dumping the database to a file in order to propagate it to the replica KDCs, it is a simple matter to have a cron job periodically copy the dump file to a secure machine elsewhere on your network. (Of course, it is important to make the host where these backups are stored as secure as your KDCs, and to encrypt its transmission across your network.) Then if your database becomes corrupted, you can load the most recent dump onto the primary KDC. (See :ref:`restore_from_dump`.) krb5-1.22.1/doc/html/_sources/admin/env_variables.rst.txt0000664000175000017500000000013315051422642023153 0ustar ghudsonghudsonEnvironment variables ===================== This content has moved to :ref:`kerberos(7)`. krb5-1.22.1/doc/html/_sources/admin/conf_files/0000775000175000017500000000000015051422656021102 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/admin/conf_files/index.rst.txt0000664000175000017500000000120115051422642023546 0ustar ghudsonghudsonConfiguration Files =================== Kerberos uses configuration files to allow administrators to specify settings on a per-machine basis. :ref:`krb5.conf(5)` applies to all applications using the Kerboros library, on clients and servers. For KDC-specific applications, additional settings can be specified in :ref:`kdc.conf(5)`; the two files are merged into a configuration profile used by applications accessing the KDC database directly. :ref:`kadm5.acl(5)` is also only used on the KDC, it controls permissions for modifying the KDC database. Contents -------- .. toctree:: :maxdepth: 1 krb5_conf kdc_conf kadm5_acl krb5-1.22.1/doc/html/_sources/admin/conf_files/kadm5_acl.rst.txt0000664000175000017500000001437715051422642024301 0ustar ghudsonghudson.. _kadm5.acl(5): kadm5.acl ========= DESCRIPTION ----------- The Kerberos :ref:`kadmind(8)` daemon uses an Access Control List (ACL) file to manage access rights to the Kerberos database. For operations that affect principals, the ACL file also controls which principals can operate on which other principals. The default location of the Kerberos ACL file is |kdcdir|\ ``/kadm5.acl`` unless this is overridden by the *acl_file* variable in :ref:`kdc.conf(5)`. SYNTAX ------ Empty lines and lines starting with the sharp sign (``#``) are ignored. Lines containing ACL entries have the format:: principal permissions [target_principal [restrictions] ] .. note:: Line order in the ACL file is important. The first matching entry will control access for an actor principal on a target principal. *principal* (Partially or fully qualified Kerberos principal name.) Specifies the principal whose permissions are to be set. Each component of the name may be wildcarded using the ``*`` character. *permissions* Specifies what operations may or may not be performed by a *principal* matching a particular entry. This is a string of one or more of the following list of characters or their upper-case counterparts. If the character is *upper-case*, then the operation is disallowed. If the character is *lower-case*, then the operation is permitted. == ====================================================== a [Dis]allows the addition of principals or policies c [Dis]allows the changing of passwords for principals d [Dis]allows the deletion of principals or policies e [Dis]allows the extraction of principal keys i [Dis]allows inquiries about principals or policies l [Dis]allows the listing of all principals or policies m [Dis]allows the modification of principals or policies p [Dis]allows the propagation of the principal database (used in :ref:`incr_db_prop`) s [Dis]allows the explicit setting of the key for a principal x Short for admcilsp. All privileges (except ``e``) \* Same as x. == ====================================================== .. note:: The ``extract`` privilege is not included in the wildcard privilege; it must be explicitly assigned. This privilege allows the user to extract keys from the database, and must be handled with great care to avoid disclosure of important keys like those of the kadmin/* or krbtgt/* principals. The **lockdown_keys** principal attribute can be used to prevent key extraction from specific principals regardless of the granted privilege. *target_principal* (Optional. Partially or fully qualified Kerberos principal name.) Specifies the principal on which *permissions* may be applied. Each component of the name may be wildcarded using the ``*`` character. *target_principal* can also include back-references to *principal*, in which ``*number`` matches the corresponding wildcard in *principal*. *restrictions* (Optional) A string of flags. Allowed restrictions are: {+\|-}\ *flagname* flag is forced to the indicated value. The permissible flags are the same as those for the **default_principal_flags** variable in :ref:`kdc.conf(5)`. *-clearpolicy* policy is forced to be empty. *-policy pol* policy is forced to be *pol*. -{*expire, pwexpire, maxlife, maxrenewlife*} *time* (:ref:`getdate` string) associated value will be forced to MIN(*time*, requested value). The above flags act as restrictions on any add or modify operation which is allowed due to that ACL line. .. warning:: If the kadmind ACL file is modified, the kadmind daemon needs to be restarted for changes to take effect. EXAMPLE ------- Here is an example of a kadm5.acl file:: */admin@ATHENA.MIT.EDU * # line 1 joeadmin@ATHENA.MIT.EDU ADMCIL # line 2 joeadmin/*@ATHENA.MIT.EDU i */root@ATHENA.MIT.EDU # line 3 */root@ATHENA.MIT.EDU ci *1@ATHENA.MIT.EDU # line 4 */root@ATHENA.MIT.EDU l * # line 5 sms@ATHENA.MIT.EDU x * -maxlife 9h -postdateable # line 6 (line 1) Any principal in the ``ATHENA.MIT.EDU`` realm with an ``admin`` instance has all administrative privileges except extracting keys. (lines 1-3) The user ``joeadmin`` has all permissions except extracting keys with his ``admin`` instance, ``joeadmin/admin@ATHENA.MIT.EDU`` (matches line 1). He has no permissions at all with his null instance, ``joeadmin@ATHENA.MIT.EDU`` (matches line 2). His ``root`` and other non-``admin``, non-null instances (e.g., ``extra`` or ``dbadmin``) have inquire permissions with any principal that has the instance ``root`` (matches line 3). (line 4) Any ``root`` principal in ``ATHENA.MIT.EDU`` can inquire or change the password of their null instance, but not any other null instance. (Here, ``*1`` denotes a back-reference to the component matching the first wildcard in the actor principal.) (line 5) Any ``root`` principal in ``ATHENA.MIT.EDU`` can generate the list of principals in the database, and the list of policies in the database. This line is separate from line 4, because list permission can only be granted globally, not to specific target principals. (line 6) Finally, the Service Management System principal ``sms@ATHENA.MIT.EDU`` has all permissions except extracting keys, but any principal that it creates or modifies will not be able to get postdateable tickets or tickets with a life of longer than 9 hours. MODULE BEHAVIOR --------------- The ACL file can coexist with other authorization modules in release 1.16 and later, as configured in the :ref:`kadm5_auth` section of :ref:`krb5.conf(5)`. The ACL file will positively authorize operations according to the rules above, but will never authoritatively deny an operation, so other modules can authorize operations in addition to those authorized by the ACL file. To operate without an ACL file, set the *acl_file* variable in :ref:`kdc.conf(5)` to the empty string with ``acl_file = ""``. SEE ALSO -------- :ref:`kdc.conf(5)`, :ref:`kadmind(8)` krb5-1.22.1/doc/html/_sources/admin/conf_files/krb5_conf.rst.txt0000664000175000017500000014250015051422642024317 0ustar ghudsonghudson.. _krb5.conf(5): krb5.conf ========= The krb5.conf file contains Kerberos configuration information, including the locations of KDCs and admin servers for the Kerberos realms of interest, defaults for the current realm and for Kerberos applications, and mappings of hostnames onto Kerberos realms. Normally, you should install your krb5.conf file in the directory ``/etc``. You can override the default location by setting the environment variable **KRB5_CONFIG**. Multiple colon-separated filenames may be specified in **KRB5_CONFIG**; all files which are present will be read. Starting in release 1.14, directory names can also be specified in **KRB5_CONFIG**; all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores will be read. Structure --------- The krb5.conf file is set up in the style of a Windows INI file. Lines beginning with '#' or ';' (possibly after initial whitespace) are ignored as comments. Sections are headed by the section name, in square brackets. Each section may contain zero or more relations, of the form:: foo = bar or:: fubar = { foo = bar baz = quux } The krb5.conf file can include other files using either of the following directives at the beginning of a line:: include FILENAME includedir DIRNAME *FILENAME* or *DIRNAME* should be an absolute path. The named file or directory must exist and be readable. Including a directory includes all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores. Starting in release 1.15, files with names ending in ".conf" are also included, unless the name begins with ".". Included profile files are syntactically independent of their parents, so each included file must begin with a section header. Starting in release 1.17, files are read in alphanumeric order; in previous releases, they may be read in any order. Placing a '\*' after the closing bracket of a section name indicates that the section is *final*, meaning that if the same section appears again later, it will be ignored. A subsection can be marked as final by placing a '\*' after either the tag name or the closing brace. A relation can be marked as final by placing a '\*' after the tag name. Prior to release 1.22, only sections and subsections can be marked as final, and the flag only causes values to be ignored if they appear in later files specified in **KRB5_CONFIG**, not if they appear later within the same file or an included file. The krb5.conf file can specify that configuration should be obtained from a loadable module, rather than the file itself, using the following directive at the beginning of a line before any section headers:: module MODULEPATH:RESIDUAL *MODULEPATH* may be relative to the library path of the krb5 installation, or it may be an absolute path. *RESIDUAL* is provided to the module at initialization time. If krb5.conf uses a module directive, :ref:`kdc.conf(5)` should also use one if it exists. Sections -------- The krb5.conf file may contain the following sections: =================== ======================================================= :ref:`libdefaults` Settings used by the Kerberos V5 library :ref:`realms` Realm-specific contact information and settings :ref:`domain_realm` Maps server hostnames to Kerberos realms :ref:`capaths` Authentication paths for non-hierarchical cross-realm :ref:`appdefaults` Settings used by some Kerberos V5 applications :ref:`plugins` Controls plugin module registration =================== ======================================================= Additionally, krb5.conf may include any of the relations described in :ref:`kdc.conf(5)`, but it is not a recommended practice. .. _libdefaults: [libdefaults] ~~~~~~~~~~~~~ The libdefaults section may contain any of the following relations: **allow_des3** Permit the KDC to issue tickets with des3-cbc-sha1 session keys. In future releases, this flag will allow des3-cbc-sha1 to be used at all. The default value for this tag is false. (Added in release 1.21.) **allow_rc4** Permit the KDC to issue tickets with arcfour-hmac session keys. In future releases, this flag will allow arcfour-hmac to be used at all. The default value for this tag is false. (Added in release 1.21.) **allow_weak_crypto** If this flag is set to false, then weak encryption types (as noted in :ref:`Encryption_types` in :ref:`kdc.conf(5)`) will be filtered out of the lists **default_tgs_enctypes**, **default_tkt_enctypes**, and **permitted_enctypes**. The default value for this tag is false. **canonicalize** If this flag is set to true, initial ticket requests to the KDC will request canonicalization of the client principal name, and answers with different client principals than the requested principal will be accepted. The default value is false. **ccache_type** This parameter determines the format of credential cache types created by :ref:`kinit(1)` or other programs. The default value is 4, which represents the most current format. Smaller values can be used for compatibility with very old implementations of Kerberos which interact with credential caches on the same host. **clockskew** Sets the maximum allowable amount of clockskew in seconds that the library will tolerate before assuming that a Kerberos message is invalid. The default value is 300 seconds, or five minutes. The clockskew setting is also used when evaluating ticket start and expiration times. For example, tickets that have reached their expiration time can still be used (and renewed if they are renewable tickets) if they have been expired for a shorter duration than the **clockskew** setting. **default_ccache_name** This relation specifies the name of the default credential cache. The default is |ccache|. This relation is subject to parameter expansion (see below). New in release 1.11. **default_client_keytab_name** This relation specifies the name of the default keytab for obtaining client credentials. The default is |ckeytab|. This relation is subject to parameter expansion (see below). New in release 1.11. **default_keytab_name** This relation specifies the default keytab name to be used by application servers such as sshd. The default is |keytab|. This relation is subject to parameter expansion (see below). **default_rcache_name** This relation specifies the name of the default replay cache. The default is ``dfl:``. This relation is subject to parameter expansion (see below). New in release 1.18. **default_realm** Identifies the default Kerberos realm for the client. Set its value to your Kerberos realm. If this value is not set, then a realm must be specified with every Kerberos principal when invoking programs such as :ref:`kinit(1)`. **default_tgs_enctypes** Identifies the supported list of session key encryption types that the client should request when making a TGS-REQ, in order of preference from highest to lowest. The list may be delimited with commas or whitespace. See :ref:`Encryption_types` in :ref:`kdc.conf(5)` for a list of the accepted values for this tag. Starting in release 1.18, the default value is the value of **permitted_enctypes**. For previous releases or if **permitted_enctypes** is not set, the default value is |defetypes|. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. **default_tkt_enctypes** Identifies the supported list of session key encryption types that the client should request when making an AS-REQ, in order of preference from highest to lowest. The format is the same as for default_tgs_enctypes. Starting in release 1.18, the default value is the value of **permitted_enctypes**. For previous releases or if **permitted_enctypes** is not set, the default value is |defetypes|. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded. **dns_canonicalize_hostname** Indicate whether name lookups will be used to canonicalize hostnames for use in service principal names. Setting this flag to false can improve security by reducing reliance on DNS, but means that short hostnames will not be canonicalized to fully-qualified hostnames. If this option is set to ``fallback`` (new in release 1.18), DNS canonicalization will only be performed the server hostname is not found with the original name when requesting credentials. The default value is true. **dns_lookup_kdc** Indicate whether DNS SRV records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. (Note that the admin_server entry must be in the krb5.conf realm information in order to contact kadmind, because the DNS implementation for kadmin is incomplete.) Enabling this option does open up a type of denial-of-service attack, if someone spoofs the DNS records and redirects you to another server. However, it's no worse than a denial of service, because that fake KDC will be unable to decode anything you send it (besides the initial ticket request, which has no encrypted data), and anything the fake KDC sends will not be trusted without verification using some secret that it won't know. **dns_lookup_realm** Indicate whether DNS TXT records should be used to map hostnames to realm names for hostnames not listed in the [domain_realm] section, and to determine the default realm if **default_realm** is not set. The default value is false. **dns_uri_lookup** Indicate whether DNS URI records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. SRV records are used as a fallback if no URI records were found. The default value is true. New in release 1.15. **enforce_ok_as_delegate** If this flag to true, GSSAPI credential delegation will be disabled when the ``ok-as-delegate`` flag is not set in the service ticket. If this flag is false, the ``ok-as-delegate`` ticket flag is only enforced when an application specifically requests enforcement. The default value is false. **err_fmt** This relation allows for custom error message formatting. If a value is set, error messages will be formatted by substituting a normal error message for %M and an error code for %C in the value. **extra_addresses** This allows a computer to use multiple local addresses, in order to allow Kerberos to work in a network that uses NATs while still using address-restricted tickets. The addresses should be in a comma-separated list. This option has no effect if **noaddresses** is true. **forwardable** If this flag is true, initial tickets will be forwardable by default, if allowed by the KDC. The default value is false. **ignore_acceptor_hostname** When accepting GSSAPI or krb5 security contexts for host-based service principals, ignore any hostname passed by the calling application, and allow clients to authenticate to any service principal in the keytab matching the service name and realm name (if given). This option can improve the administrative flexibility of server applications on multihomed hosts, but could compromise the security of virtual hosting environments. The default value is false. New in release 1.10. **k5login_authoritative** If this flag is true, principals must be listed in a local user's k5login file to be granted login access, if a :ref:`.k5login(5)` file exists. If this flag is false, a principal may still be granted login access through other mechanisms even if a k5login file exists but does not list the principal. The default value is true. **k5login_directory** If set, the library will look for a local user's k5login file within the named directory, with a filename corresponding to the local username. If not set, the library will look for k5login files in the user's home directory, with the filename .k5login. For security reasons, .k5login files must be owned by the local user or by root. **kcm_mach_service** On macOS only, determines the name of the bootstrap service used to contact the KCM daemon for the KCM credential cache type. If the value is ``-``, Mach RPC will not be used to contact the KCM daemon. The default value is ``org.h5l.kcm``. **kcm_socket** Determines the path to the Unix domain socket used to access the KCM daemon for the KCM credential cache type. If the value is ``-``, Unix domain sockets will not be used to contact the KCM daemon. The default value is ``/var/run/.heim_org.h5l.kcm-socket``. **kdc_default_options** Default KDC options (Xored for multiple values) when requesting initial tickets. By default it is set to 0x00000010 (KDC_OPT_RENEWABLE_OK). **kdc_timesync** Accepted values for this relation are 1 or 0. If it is nonzero, client machines will compute the difference between their time and the time returned by the KDC in the timestamps in the tickets and use this value to correct for an inaccurate system clock when requesting service tickets or authenticating to services. This corrective factor is only used by the Kerberos library; it is not used to change the system clock. The default value is 1. **noaddresses** If this flag is true, requests for initial tickets will not be made with address restrictions set, allowing the tickets to be used across NATs. The default value is true. **permitted_enctypes** Identifies the encryption types that servers will permit for session keys and for ticket and authenticator encryption, ordered by preference from highest to lowest. Starting in release 1.18, this tag also acts as the default value for **default_tgs_enctypes** and **default_tkt_enctypes**. The default value for this tag is |defetypes|. **plugin_base_dir** If set, determines the base directory where krb5 plugins are located. The default value is the ``krb5/plugins`` subdirectory of the krb5 library directory. This relation is subject to parameter expansion (see below) in release 1.17 and later. **preferred_preauth_types** This allows you to set the preferred preauthentication types which the client will attempt before others which may be advertised by a KDC. The default value for this setting is "17, 16, 15, 14", which forces libkrb5 to attempt to use PKINIT if it is supported. **proxiable** If this flag is true, initial tickets will be proxiable by default, if allowed by the KDC. The default value is false. **qualify_shortname** If this string is set, it determines the domain suffix for single-component hostnames when DNS canonicalization is not used (either because **dns_canonicalize_hostname** is false or because forward canonicalization failed). The default value is the first search domain of the system's DNS configuration. To disable qualification of shortnames, set this relation to the empty string with ``qualify_shortname = ""``. (New in release 1.18.) **rdns** If this flag is true, reverse name lookup will be used in addition to forward name lookup to canonicalizing hostnames for use in service principal names. If **dns_canonicalize_hostname** is set to false, this flag has no effect. The default value is true. **realm_try_domains** Indicate whether a host's domain components should be used to determine the Kerberos realm of the host. The value of this variable is an integer: -1 means not to search, 0 means to try the host's domain itself, 1 means to also try the domain's immediate parent, and so forth. The library's usual mechanism for locating Kerberos realms is used to determine whether a domain is a valid realm, which may involve consulting DNS if **dns_lookup_kdc** is set. The default is not to search domain components. **renew_lifetime** (:ref:`duration` string.) Sets the default renewable lifetime for initial ticket requests. The default value is 0. **request_timeout** (:ref:`duration` string.) Sets the maximum total time for KDC and password change requests. This timeout does not affect the intervals between requests, so setting a low timeout may result in fewer requests being attempted and/or some servers not being contacted. A value of 0 indicates no specific maximum, in which case requests will time out if no server responds after several tries. The default value is 0. (New in release 1.22.) **spake_preauth_groups** A whitespace or comma-separated list of words which specifies the groups allowed for SPAKE preauthentication. The possible values are: ============ ================================ edwards25519 Edwards25519 curve (:rfc:`7748`) P-256 NIST P-256 curve (:rfc:`5480`) P-384 NIST P-384 curve (:rfc:`5480`) P-521 NIST P-521 curve (:rfc:`5480`) ============ ================================ The default value for the client is ``edwards25519``. The default value for the KDC is empty. New in release 1.17. **ticket_lifetime** (:ref:`duration` string.) Sets the default lifetime for initial ticket requests. The default value is 1 day. **udp_preference_limit** When sending a message to the KDC, the library will try using TCP before UDP if the size of the message is above **udp_preference_limit**. If the message is smaller than **udp_preference_limit**, then UDP will be tried before TCP. Regardless of the size, both protocols will be tried if the first attempt fails. **verify_ap_req_nofail** If this flag is true, then an attempt to verify initial credentials will fail if the client machine does not have a keytab. The default value is false. **client_aware_channel_bindings** If this flag is true, then all application protocol authentication requests will be flagged to indicate that the application supports channel bindings when operating over a secure channel. The default value is false. .. _realms: [realms] ~~~~~~~~ Each tag in the [realms] section of the file is the name of a Kerberos realm. The value of the tag is a subsection with relations that define the properties of that particular realm. For each realm, the following tags may be specified in the realm's subsection: **admin_server** Identifies the host where the administration server is running. Typically, this is the primary Kerberos server. This tag must be given a value in order to communicate with the :ref:`kadmind(8)` server for the realm. **auth_to_local** This tag allows you to set a general rule for mapping principal names to local user names. It will be used if there is not an explicit mapping for the principal name that is being translated. The possible values are: **RULE:**\ *exp* The local name will be formulated from *exp*. The format for *exp* is **[**\ *n*\ **:**\ *string*\ **](**\ *regexp*\ **)s/**\ *pattern*\ **/**\ *replacement*\ **/g**. The integer *n* indicates how many components the target principal should have. If this matches, then a string will be formed from *string*, substituting the realm of the principal for ``$0`` and the *n*'th component of the principal for ``$n`` (e.g., if the principal was ``johndoe/admin`` then ``[2:$2$1foo]`` would result in the string ``adminjohndoefoo``). If this string matches *regexp*, then the ``s//[g]`` substitution command will be run over the string. The optional **g** will cause the substitution to be global over the *string*, instead of replacing only the first match in the *string*. **DEFAULT** The principal name will be used as the local user name. If the principal has more than one component or is not in the default realm, this rule is not applicable and the conversion will fail. For example:: [realms] ATHENA.MIT.EDU = { auth_to_local = RULE:[2:$1](johndoe)s/^.*$/guest/ auth_to_local = RULE:[2:$1;$2](^.*;admin$)s/;admin$// auth_to_local = RULE:[2:$2](^.*;root)s/^.*$/root/ auth_to_local = DEFAULT } would result in any principal without ``root`` or ``admin`` as the second component to be translated with the default rule. A principal with a second component of ``admin`` will become its first component. ``root`` will be used as the local name for any principal with a second component of ``root``. The exception to these two rules are any principals ``johndoe/*``, which will always get the local name ``guest``. **auth_to_local_names** This subsection allows you to set explicit mappings from principal names to local user names. The tag is the mapping name, and the value is the corresponding local user name. **default_domain** This tag specifies the domain used to expand hostnames when translating Kerberos 4 service principals to Kerberos 5 principals (for example, when converting ``rcmd.hostname`` to ``host/hostname.domain``). **disable_encrypted_timestamp** If this flag is true, the client will not perform encrypted timestamp preauthentication if requested by the KDC. Setting this flag can help to prevent dictionary attacks by active attackers, if the realm's KDCs support SPAKE preauthentication or if initial authentication always uses another mechanism or always uses FAST. This flag persists across client referrals during initial authentication. This flag does not prevent the KDC from offering encrypted timestamp. New in release 1.17. **http_anchors** When KDCs and kpasswd servers are accessed through HTTPS proxies, this tag can be used to specify the location of the CA certificate which should be trusted to issue the certificate for a proxy server. If left unspecified, the system-wide default set of CA certificates is used. The syntax for values is similar to that of values for the **pkinit_anchors** tag: **FILE:** *filename* *filename* is assumed to be the name of an OpenSSL-style ca-bundle file. **DIR:** *dirname* *dirname* is assumed to be an directory which contains CA certificates. All files in the directory will be examined; if they contain certificates (in PEM format), they will be used. **ENV:** *envvar* *envvar* specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, ``ENV:X509_PROXY_CA``, where environment variable ``X509_PROXY_CA`` has been set to ``FILE:/tmp/my_proxy.pem``. **kdc** The name or address of a host running a KDC for the realm, or a UNIX domain socket path of a locally running KDC. An optional port number, separated from the hostname by a colon, may be included. If the name or address contains colons (for example, if it is an IPv6 address), enclose it in square brackets to distinguish the colon from a port separator. For your computer to be able to communicate with the KDC for each realm, this tag must be given a value in each realm subsection in the configuration file, or there must be DNS SRV records specifying the KDCs. **kpasswd_server** The location of the password change server for the realm, using the same syntax as **kdc**. If there is no such entry, DNS will be queried (unless forbidden by **dns_lookup_kdc**). Finally, port 464 on the **admin_server** host will be tried. **master_kdc** The name for **primary_kdc** prior to release 1.19. Its value is used as a fallback if **primary_kdc** is not specified. **primary_kdc** Identifies the primary KDC(s). Currently, this tag is used in only one case: If an attempt to get credentials fails because of an invalid password, the client software will attempt to contact the primary KDC, in case the user's password has just been changed, and the updated database has not been propagated to the replica servers yet. New in release 1.19. **sitename** Specifies the name of the host's site for the purpose of DNS-based KDC discovery for this realm. New in release 1.22. **v4_instance_convert** This subsection allows the administrator to configure exceptions to the **default_domain** mapping rule. It contains V4 instances (the tag name) which should be translated to some specific hostname (the tag value) as the second component in a Kerberos V5 principal name. **v4_realm** This relation is used by the krb524 library routines when converting a V5 principal name to a V4 principal name. It is used when the V4 realm name and the V5 realm name are not the same, but still share the same principal names and passwords. The tag value is the Kerberos V4 realm name. .. _domain_realm: [domain_realm] ~~~~~~~~~~~~~~ The [domain_realm] section provides a translation from hostnames to Kerberos realms. Each tag is a domain name, providing the mapping for that domain and all subdomains. If the tag begins with a period (``.``) then it applies only to subdomains. The Kerberos realm may be identified either in the realms_ section or using DNS SRV records. Tag names should be in lower case. For example:: [domain_realm] crash.mit.edu = TEST.ATHENA.MIT.EDU .dev.mit.edu = TEST.ATHENA.MIT.EDU mit.edu = ATHENA.MIT.EDU maps the host with the name ``crash.mit.edu`` into the ``TEST.ATHENA.MIT.EDU`` realm. The second entry maps all hosts under the domain ``dev.mit.edu`` into the ``TEST.ATHENA.MIT.EDU`` realm, but not the host with the name ``dev.mit.edu``. That host is matched by the third entry, which maps the host ``mit.edu`` and all hosts under the domain ``mit.edu`` that do not match a preceding rule into the realm ``ATHENA.MIT.EDU``. If no translation entry applies to a hostname used for a service principal for a service ticket request, the library will try to get a referral to the appropriate realm from the client realm's KDC. If that does not succeed, the host's realm is considered to be the hostname's domain portion converted to uppercase, unless the **realm_try_domains** setting in [libdefaults] causes a different parent domain to be used. .. _capaths: [capaths] ~~~~~~~~~ In order to perform direct (non-hierarchical) cross-realm authentication, configuration is needed to determine the authentication paths between realms. A client will use this section to find the authentication path between its realm and the realm of the server. The server will use this section to verify the authentication path used by the client, by checking the transited field of the received ticket. There is a tag for each participating client realm, and each tag has subtags for each of the server realms. The value of the subtags is an intermediate realm which may participate in the cross-realm authentication. The subtags may be repeated if there is more then one intermediate realm. A value of "." means that the two realms share keys directly, and no intermediate realms should be allowed to participate. Only those entries which will be needed on the client or the server need to be present. A client needs a tag for its local realm with subtags for all the realms of servers it will need to authenticate to. A server needs a tag for each realm of the clients it will serve, with a subtag of the server realm. For example, ``ANL.GOV``, ``PNL.GOV``, and ``NERSC.GOV`` all wish to use the ``ES.NET`` realm as an intermediate realm. ANL has a sub realm of ``TEST.ANL.GOV`` which will authenticate with ``NERSC.GOV`` but not ``PNL.GOV``. The [capaths] section for ``ANL.GOV`` systems would look like this:: [capaths] ANL.GOV = { TEST.ANL.GOV = . PNL.GOV = ES.NET NERSC.GOV = ES.NET ES.NET = . } TEST.ANL.GOV = { ANL.GOV = . } PNL.GOV = { ANL.GOV = ES.NET } NERSC.GOV = { ANL.GOV = ES.NET } ES.NET = { ANL.GOV = . } The [capaths] section of the configuration file used on ``NERSC.GOV`` systems would look like this:: [capaths] NERSC.GOV = { ANL.GOV = ES.NET TEST.ANL.GOV = ES.NET TEST.ANL.GOV = ANL.GOV PNL.GOV = ES.NET ES.NET = . } ANL.GOV = { NERSC.GOV = ES.NET } PNL.GOV = { NERSC.GOV = ES.NET } ES.NET = { NERSC.GOV = . } TEST.ANL.GOV = { NERSC.GOV = ANL.GOV NERSC.GOV = ES.NET } When a subtag is used more than once within a tag, clients will use the order of values to determine the path. The order of values is not important to servers. .. _appdefaults: [appdefaults] ~~~~~~~~~~~~~ Each tag in the [appdefaults] section names a Kerberos V5 application or an option that is used by some Kerberos V5 application[s]. The value of the tag defines the default behaviors for that application. For example:: [appdefaults] telnet = { ATHENA.MIT.EDU = { option1 = false } } telnet = { option1 = true option2 = true } ATHENA.MIT.EDU = { option2 = false } option2 = true The above four ways of specifying the value of an option are shown in order of decreasing precedence. In this example, if telnet is running in the realm EXAMPLE.COM, it should, by default, have option1 and option2 set to true. However, a telnet program in the realm ``ATHENA.MIT.EDU`` should have ``option1`` set to false and ``option2`` set to true. Any other programs in ATHENA.MIT.EDU should have ``option2`` set to false by default. Any programs running in other realms should have ``option2`` set to true. The list of specifiable options for each application may be found in that application's man pages. The application defaults specified here are overridden by those specified in the realms_ section. .. _plugins: [plugins] ~~~~~~~~~ * pwqual_ interface * kadm5_hook_ interface * clpreauth_ and kdcpreauth_ interfaces Tags in the [plugins] section can be used to register dynamic plugin modules and to turn modules on and off. Not every krb5 pluggable interface uses the [plugins] section; the ones that do are documented here. New in release 1.9. Each pluggable interface corresponds to a subsection of [plugins]. All subsections support the same tags: **disable** This tag may have multiple values. If there are values for this tag, then the named modules will be disabled for the pluggable interface. **enable_only** This tag may have multiple values. If there are values for this tag, then only the named modules will be enabled for the pluggable interface. **module** This tag may have multiple values. Each value is a string of the form ``modulename:pathname``, which causes the shared object located at *pathname* to be registered as a dynamic module named *modulename* for the pluggable interface. If *pathname* is not an absolute path, it will be treated as relative to the **plugin_base_dir** value from :ref:`libdefaults`. For pluggable interfaces where module order matters, modules registered with a **module** tag normally come first, in the order they are registered, followed by built-in modules in the order they are documented below. If **enable_only** tags are used, then the order of those tags overrides the normal module order. The following subsections are currently supported within the [plugins] section: .. _ccselect: ccselect interface ################## The ccselect subsection controls modules for credential cache selection within a cache collection. In addition to any registered dynamic modules, the following built-in modules exist (and may be disabled with the disable tag): **k5identity** Uses a .k5identity file in the user's home directory to select a client principal **realm** Uses the service realm to guess an appropriate cache from the collection **hostname** If the service principal is host-based, uses the service hostname to guess an appropriate cache from the collection .. _pwqual: pwqual interface ################ The pwqual subsection controls modules for the password quality interface, which is used to reject weak passwords when passwords are changed. The following built-in modules exist for this interface: **dict** Checks against the realm dictionary file **empty** Rejects empty passwords **hesiod** Checks against user information stored in Hesiod (only if Kerberos was built with Hesiod support) **princ** Checks against components of the principal name .. _kadm5_hook: kadm5_hook interface #################### The kadm5_hook interface provides plugins with information on principal creation, modification, password changes and deletion. This interface can be used to write a plugin to synchronize MIT Kerberos with another database such as Active Directory. No plugins are built in for this interface. .. _kadm5_auth: kadm5_auth interface #################### The kadm5_auth section (introduced in release 1.16) controls modules for the kadmin authorization interface, which determines whether a client principal is allowed to perform a kadmin operation. The following built-in modules exist for this interface: **acl** This module reads the :ref:`kadm5.acl(5)` file, and authorizes operations which are allowed according to the rules in the file. **self** This module authorizes self-service operations including password changes, creation of new random keys, fetching the client's principal record or string attributes, and fetching the policy record associated with the client principal. .. _clpreauth: .. _kdcpreauth: clpreauth and kdcpreauth interfaces ################################### The clpreauth and kdcpreauth interfaces allow plugin modules to provide client and KDC preauthentication mechanisms. The following built-in modules exist for these interfaces: **pkinit** This module implements the PKINIT preauthentication mechanism. **encrypted_challenge** This module implements the encrypted challenge FAST factor. **encrypted_timestamp** This module implements the encrypted timestamp mechanism. .. _hostrealm: hostrealm interface ################### The hostrealm section (introduced in release 1.12) controls modules for the host-to-realm interface, which affects the local mapping of hostnames to realm names and the choice of default realm. The following built-in modules exist for this interface: **profile** This module consults the [domain_realm] section of the profile for authoritative host-to-realm mappings, and the **default_realm** variable for the default realm. **dns** This module looks for DNS records for fallback host-to-realm mappings and the default realm. It only operates if the **dns_lookup_realm** variable is set to true. **domain** This module applies heuristics for fallback host-to-realm mappings. It implements the **realm_try_domains** variable, and uses the uppercased parent domain of the hostname if that does not produce a result. .. _localauth: localauth interface ################### The localauth section (introduced in release 1.12) controls modules for the local authorization interface, which affects the relationship between Kerberos principals and local system accounts. The following built-in modules exist for this interface: **default** This module implements the **DEFAULT** type for **auth_to_local** values. **rule** This module implements the **RULE** type for **auth_to_local** values. **names** This module looks for an **auth_to_local_names** mapping for the principal name. **auth_to_local** This module processes **auth_to_local** values in the default realm's section, and applies the default method if no **auth_to_local** values exist. **k5login** This module authorizes a principal to a local account according to the account's :ref:`.k5login(5)` file. **an2ln** This module authorizes a principal to a local account if the principal name maps to the local account name. .. _certauth: certauth interface ################## The certauth section (introduced in release 1.16) controls modules for the certificate authorization interface, which determines whether a certificate is allowed to preauthenticate a user via PKINIT. The following built-in modules exist for this interface: **pkinit_san** This module authorizes the certificate if it contains a PKINIT Subject Alternative Name for the requested client principal, or a Microsoft UPN SAN matching the principal if **pkinit_allow_upn** is set to true for the realm. **pkinit_eku** This module rejects the certificate if it does not contain an Extended Key Usage attribute consistent with the **pkinit_eku_checking** value for the realm. **dbmatch** This module authorizes or rejects the certificate according to whether it matches the **pkinit_cert_match** string attribute on the client principal, if that attribute is present. PKINIT options -------------- .. note:: The following are PKINIT-specific options. These values may be specified in [libdefaults] as global defaults, or within a realm-specific subsection of [libdefaults], or may be specified as realm-specific values in the [realms] section. A realm-specific value overrides, not adds to, a generic [libdefaults] specification. The search order is: 1. realm-specific subsection of [libdefaults]:: [libdefaults] EXAMPLE.COM = { pkinit_anchors = FILE:/usr/local/example.com.crt } 2. realm-specific value in the [realms] section:: [realms] OTHERREALM.ORG = { pkinit_anchors = FILE:/usr/local/otherrealm.org.crt } 3. generic value in the [libdefaults] section:: [libdefaults] pkinit_anchors = DIR:/usr/local/generic_trusted_cas/ .. _pkinit_identity: Specifying PKINIT identity information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The syntax for specifying Public Key identity, trust, and revocation information for PKINIT is as follows: **FILE:**\ *filename*\ [**,**\ *keyfilename*] This option has context-specific behavior. In **pkinit_identity** or **pkinit_identities**, *filename* specifies the name of a PEM-format file containing the user's certificate. If *keyfilename* is not specified, the user's private key is expected to be in *filename* as well. Otherwise, *keyfilename* is the name of the file containing the private key. In **pkinit_anchors** or **pkinit_pool**, *filename* is assumed to be the name of an OpenSSL-style ca-bundle file. **DIR:**\ *dirname* This option has context-specific behavior. In **pkinit_identity** or **pkinit_identities**, *dirname* specifies a directory with files named ``*.crt`` and ``*.key`` where the first part of the file name is the same for matching pairs of certificate and private key files. When a file with a name ending with ``.crt`` is found, a matching file ending with ``.key`` is assumed to contain the private key. If no such file is found, then the certificate in the ``.crt`` is not used. In **pkinit_anchors** or **pkinit_pool**, *dirname* is assumed to be an OpenSSL-style hashed CA directory where each CA cert is stored in a file named ``hash-of-ca-cert.#``. This infrastructure is encouraged, but all files in the directory will be examined and if they contain certificates (in PEM format), they will be used. In **pkinit_revoke**, *dirname* is assumed to be an OpenSSL-style hashed CA directory where each revocation list is stored in a file named ``hash-of-ca-cert.r#``. This infrastructure is encouraged, but all files in the directory will be examined and if they contain a revocation list (in PEM format), they will be used. **PKCS12:**\ *filename* *filename* is the name of a PKCS #12 format file, containing the user's certificate and private key. **PKCS11:**\ [**module_name=**]\ *modname*\ [**:slotid=**\ *slot-id*][**:token=**\ *token-label*][**:certid=**\ *cert-id*][**:certlabel=**\ *cert-label*] All keyword/values are optional. *modname* specifies the location of a library implementing PKCS #11. If a value is encountered with no keyword, it is assumed to be the *modname*. If no module-name is specified, the default is |pkcs11_modname|. ``slotid=`` and/or ``token=`` may be specified to force the use of a particular smard card reader or token if there is more than one available. ``certid=`` and/or ``certlabel=`` may be specified to force the selection of a particular certificate on the device. Specifier values must not contain colon characters, as colons are always treated as separators. See the **pkinit_cert_match** configuration option for more ways to select a particular certificate to use for PKINIT. **ENV:**\ *envvar* *envvar* specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, ``ENV:X509_PROXY``, where environment variable ``X509_PROXY`` has been set to ``FILE:/tmp/my_proxy.pem``. PKINIT krb5.conf options ~~~~~~~~~~~~~~~~~~~~~~~~ **pkinit_anchors** Specifies the location of trusted anchor (root) certificates which the client trusts to sign KDC certificates. This option may be specified multiple times. These values from the config file are not used if the user specifies X509_anchors on the command line. **pkinit_cert_match** Specifies matching rules that the client certificate must match before it is used to attempt PKINIT authentication. If a user has multiple certificates available (on a smart card, or via other media), there must be exactly one certificate chosen before attempting PKINIT authentication. This option may be specified multiple times. All the available certificates are checked against each rule in order until there is a match of exactly one certificate. The Subject and Issuer comparison strings are the :rfc:`2253` string representations from the certificate Subject DN and Issuer DN values. The syntax of the matching rules is: [*relation-operator*\ ]\ *component-rule* ... where: *relation-operator* can be either ``&&``, meaning all component rules must match, or ``||``, meaning only one component rule must match. The default is ``&&``. *component-rule* can be one of the following. Note that there is no punctuation or whitespace between component rules. | ****\ *regular-expression* | ****\ *regular-expression* | ****\ *regular-expression* | ****\ *extended-key-usage-list* | ****\ *key-usage-list* *extended-key-usage-list* is a comma-separated list of required Extended Key Usage values. All values in the list must be present in the certificate. Extended Key Usage values can be: * pkinit * msScLogin * clientAuth * emailProtection *key-usage-list* is a comma-separated list of required Key Usage values. All values in the list must be present in the certificate. Key Usage values can be: * digitalSignature * keyEncipherment Examples:: pkinit_cert_match = ||.*DoE.*.*@EXAMPLE.COM pkinit_cert_match = &&msScLogin,clientAuth.*DoE.* pkinit_cert_match = msScLogin,clientAuthdigitalSignature **pkinit_eku_checking** This option specifies what Extended Key Usage value the KDC certificate presented to the client must contain. (Note that if the KDC certificate has the pkinit SubjectAlternativeName encoded as the Kerberos TGS name, EKU checking is not necessary since the issuing CA has certified this as a KDC certificate.) The values recognized in the krb5.conf file are: **kpKDC** This is the default value and specifies that the KDC must have the id-pkinit-KPKdc EKU as defined in :rfc:`4556`. **kpServerAuth** If **kpServerAuth** is specified, a KDC certificate with the id-kp-serverAuth EKU will be accepted. This key usage value is used in most commercially issued server certificates. **none** If **none** is specified, then the KDC certificate will not be checked to verify it has an acceptable EKU. The use of this option is not recommended. **pkinit_dh_min_bits** Specifies the group of the Diffie-Hellman key the client will attempt to use. The acceptable values are 1024, 2048, P-256, 4096, P-384, and P-521. The default is 2048. (P-256, P-384, and P-521 are new in release 1.22.) **pkinit_identities** Specifies the location(s) to be used to find the user's X.509 identity information. If this option is specified multiple times, each value is attempted in order until certificates are found. Note that these values are not used if the user specifies **X509_user_identity** on the command line. **pkinit_kdc_hostname** The presence of this option indicates that the client is willing to accept a KDC certificate with a dNSName SAN (Subject Alternative Name) rather than requiring the id-pkinit-san as defined in :rfc:`4556`. This option may be specified multiple times. Its value should contain the acceptable hostname for the KDC (as contained in its certificate). **pkinit_pool** Specifies the location of intermediate certificates which may be used by the client to complete the trust chain between a KDC certificate and a trusted anchor. This option may be specified multiple times. **pkinit_require_crl_checking** The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and **pkinit_require_crl_checking** is false, then verification succeeds. However, if **pkinit_require_crl_checking** is true and there is no CRL information available for the issuing CA, then verification fails. **pkinit_require_crl_checking** should be set to true if the policy is such that up-to-date CRLs must be present for every CA. **pkinit_revoke** Specifies the location of Certificate Revocation List (CRL) information to be used by the client when verifying the validity of the KDC certificate presented. This option may be specified multiple times. .. _parameter_expansion: Parameter expansion ------------------- Starting with release 1.11, several variables, such as **default_keytab_name**, allow parameters to be expanded. Valid parameters are: ================= =================================================== %{TEMP} Temporary directory %{uid} Unix real UID or Windows SID %{euid} Unix effective user ID or Windows SID %{USERID} Same as %{uid} %{null} Empty string %{LIBDIR} Installation library directory %{BINDIR} Installation binary directory %{SBINDIR} Installation admin binary directory %{username} (Unix) Username of effective user ID %{APPDATA} (Windows) Roaming application data for current user %{COMMON_APPDATA} (Windows) Application data for all users %{LOCAL_APPDATA} (Windows) Local application data for current user %{SYSTEM} (Windows) Windows system folder %{WINDOWS} (Windows) Windows folder %{USERCONFIG} (Windows) Per-user MIT krb5 config file directory %{COMMONCONFIG} (Windows) Common MIT krb5 config file directory ================= =================================================== Sample krb5.conf file --------------------- Here is an example of a generic krb5.conf file:: [libdefaults] default_realm = ATHENA.MIT.EDU dns_lookup_kdc = true dns_lookup_realm = false [realms] ATHENA.MIT.EDU = { kdc = kerberos.mit.edu kdc = kerberos-1.mit.edu kdc = kerberos-2.mit.edu admin_server = kerberos.mit.edu primary_kdc = kerberos.mit.edu } EXAMPLE.COM = { kdc = kerberos.example.com kdc = kerberos-1.example.com admin_server = kerberos.example.com } [domain_realm] mit.edu = ATHENA.MIT.EDU [capaths] ATHENA.MIT.EDU = { EXAMPLE.COM = . } EXAMPLE.COM = { ATHENA.MIT.EDU = . } FILES ----- |krb5conf| SEE ALSO -------- syslog(3) krb5-1.22.1/doc/html/_sources/admin/conf_files/kdc_conf.rst.txt0000664000175000017500000011611615051422642024221 0ustar ghudsonghudson.. _kdc.conf(5): kdc.conf ======== The kdc.conf file supplements :ref:`krb5.conf(5)` for programs which are typically only used on a KDC, such as the :ref:`krb5kdc(8)` and :ref:`kadmind(8)` daemons and the :ref:`kdb5_util(8)` program. Relations documented here may also be specified in krb5.conf; for the KDC programs mentioned, krb5.conf and kdc.conf will be merged into a single configuration profile. Normally, the kdc.conf file is found in the KDC state directory, |kdcdir|. You can override the default location by setting the environment variable **KRB5_KDC_PROFILE**. Please note that you need to restart the KDC daemon for any configuration changes to take effect. Structure --------- The kdc.conf file is set up in the same format as the :ref:`krb5.conf(5)` file. Sections -------- The kdc.conf file may contain the following sections: ==================== ================================================= :ref:`kdcdefaults` Default values for KDC behavior :ref:`kdc_realms` Realm-specific database configuration and settings :ref:`dbdefaults` Default database settings :ref:`dbmodules` Per-database settings :ref:`logging` Controls how Kerberos daemons perform logging ==================== ================================================= .. _kdcdefaults: [kdcdefaults] ~~~~~~~~~~~~~ Some relations in the [kdcdefaults] section specify default values for realm variables, to be used if the [realms] subsection does not contain a relation for the tag. See the :ref:`kdc_realms` section for the definitions of these relations. * **host_based_services** * **kdc_listen** * **kdc_ports** * **kdc_tcp_listen** * **kdc_tcp_ports** * **no_host_referral** * **restrict_anonymous_to_tgt** The following [kdcdefaults] variables have no per-realm equivalent: **kdc_max_dgram_reply_size** Specifies the maximum packet size that can be sent over UDP. The default value is 4096 bytes. **kdc_tcp_listen_backlog** (Integer.) Set the size of the listen queue length for the KDC daemon. The value may be limited by OS settings. The default value is 5. **spake_preauth_kdc_challenge** (String.) Specifies the group for a SPAKE optimistic challenge. See the **spake_preauth_groups** variable in :ref:`libdefaults` for possible values. The default is not to issue an optimistic challenge. (New in release 1.17.) .. _kdc_realms: [realms] ~~~~~~~~ Each tag in the [realms] section is the name of a Kerberos realm. The value of the tag is a subsection where the relations define KDC parameters for that particular realm. The following example shows how to define one parameter for the ATHENA.MIT.EDU realm:: [realms] ATHENA.MIT.EDU = { max_renewable_life = 7d 0h 0m 0s } The following tags may be specified in a [realms] subsection: **acl_file** (String.) Location of the access control list file that :ref:`kadmind(8)` uses to determine which principals are allowed which permissions on the Kerberos database. To operate without an ACL file, set this relation to the empty string with ``acl_file = ""``. The default value is |kdcdir|\ ``/kadm5.acl``. For more information on Kerberos ACL file see :ref:`kadm5.acl(5)`. **database_module** (String.) This relation indicates the name of the configuration section under :ref:`dbmodules` for database-specific parameters used by the loadable database library. The default value is the realm name. If this configuration section does not exist, default values will be used for all database parameters. **database_name** (String, deprecated.) This relation specifies the location of the Kerberos database for this realm, if the DB2 module is being used and the :ref:`dbmodules` configuration section does not specify a database name. The default value is |kdcdir|\ ``/principal``. **default_principal_expiration** (:ref:`abstime` string.) Specifies the default expiration date of principals created in this realm. The default value is 0, which means no expiration date. **default_principal_flags** (Flag string.) Specifies the default attributes of principals created in this realm. The format for this string is a comma-separated list of flags, with '+' before each flag that should be enabled and '-' before each flag that should be disabled. The **postdateable**, **forwardable**, **tgt-based**, **renewable**, **proxiable**, **dup-skey**, **allow-tickets**, and **service** flags default to enabled. There are a number of possible flags: **allow-tickets** Enabling this flag means that the KDC will issue tickets for this principal. Disabling this flag essentially deactivates the principal within this realm. **dup-skey** Enabling this flag allows the KDC to issue user-to-user service tickets for this principal. **forwardable** Enabling this flag allows the principal to obtain forwardable tickets. **hwauth** If this flag is enabled, then the principal is required to preauthenticate using a hardware device before receiving any tickets. **no-auth-data-required** Enabling this flag prevents PAC or AD-SIGNEDPATH data from being added to service tickets for the principal. **ok-as-delegate** If this flag is enabled, it hints the client that credentials can and should be delegated when authenticating to the service. **ok-to-auth-as-delegate** Enabling this flag allows the principal to use S4USelf tickets. **postdateable** Enabling this flag allows the principal to obtain postdateable tickets. **preauth** If this flag is enabled on a client principal, then that principal is required to preauthenticate to the KDC before receiving any tickets. On a service principal, enabling this flag means that service tickets for this principal will only be issued to clients with a TGT that has the preauthenticated bit set. **proxiable** Enabling this flag allows the principal to obtain proxy tickets. **pwchange** Enabling this flag forces a password change for this principal. **pwservice** If this flag is enabled, it marks this principal as a password change service. This should only be used in special cases, for example, if a user's password has expired, then the user has to get tickets for that principal without going through the normal password authentication in order to be able to change the password. **renewable** Enabling this flag allows the principal to obtain renewable tickets. **service** Enabling this flag allows the the KDC to issue service tickets for this principal. In release 1.17 and later, user-to-user service tickets are still allowed if the **dup-skey** flag is set. **tgt-based** Enabling this flag allows a principal to obtain tickets based on a ticket-granting-ticket, rather than repeating the authentication process that was used to obtain the TGT. **dict_file** (String.) Location of the dictionary file containing strings that are not allowed as passwords. The file should contain one string per line, with no additional whitespace. If none is specified or if there is no policy assigned to the principal, no dictionary checks of passwords will be performed. **disable_pac** (Boolean value.) If true, the KDC will not issue PACs for this realm, and S4U2Self and S4U2Proxy operations will be disabled. The default is false, which will permit the KDC to issue PACs. New in release 1.20. **encrypted_challenge_indicator** (String.) Specifies the authentication indicator value that the KDC asserts into tickets obtained using FAST encrypted challenge pre-authentication. New in 1.16. **host_based_services** (Whitespace- or comma-separated list.) Lists services which will get host-based referral processing even if the server principal is not marked as host-based by the client. **iprop_enable** (Boolean value.) Specifies whether incremental database propagation is enabled. The default value is false. **iprop_ulogsize** (Integer.) Specifies the maximum number of log entries to be retained for incremental propagation. The default value is 1000. Prior to release 1.11, the maximum value was 2500. New in release 1.19. **iprop_master_ulogsize** The name for **iprop_ulogsize** prior to release 1.19. Its value is used as a fallback if **iprop_ulogsize** is not specified. **iprop_replica_poll** (Delta time string.) Specifies how often the replica KDC polls for new updates from the primary. The default value is ``2m`` (that is, two minutes). New in release 1.17. **iprop_slave_poll** (Delta time string.) The name for **iprop_replica_poll** prior to release 1.17. Its value is used as a fallback if **iprop_replica_poll** is not specified. **iprop_listen** (Whitespace- or comma-separated list.) Specifies the iprop RPC listening addresses and/or ports for the :ref:`kadmind(8)` daemon. Each entry may be an interface address, a port number, or an address and port number separated by a colon. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default (when **iprop_enable** is true) is to bind to the wildcard address at the port specified in **iprop_port**. New in release 1.15. **iprop_port** (Port number.) Specifies the port number to be used for incremental propagation. When **iprop_enable** is true, this relation is required in the replica KDC configuration file, and this relation or **iprop_listen** is required in the primary configuration file, as there is no default port number. Port numbers specified in **iprop_listen** entries will override this port number for the :ref:`kadmind(8)` daemon. **iprop_resync_timeout** (Delta time string.) Specifies the amount of time to wait for a full propagation to complete. This is optional in configuration files, and is used by replica KDCs only. The default value is 5 minutes (``5m``). New in release 1.11. **iprop_logfile** (File name.) Specifies where the update log file for the realm database is to be stored. The default is to use the **database_name** entry from the realms section of the krb5 config file, with ``.ulog`` appended. (NOTE: If **database_name** isn't specified in the realms section, perhaps because the LDAP database back end is being used, or the file name is specified in the [dbmodules] section, then the hard-coded default for **database_name** is used. Determination of the **iprop_logfile** default value will not use values from the [dbmodules] section.) **kadmind_listen** (Whitespace- or comma-separated list.) Specifies the kadmin RPC listening addresses and/or ports for the :ref:`kadmind(8)` daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. To disable listening for kadmin RPC connections, set this relation to the empty string with ``kadmind_listen = ""``. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in **kadmind_port**, or the standard kadmin port (749). New in release 1.15. **kadmind_port** (Port number.) Specifies the port on which the :ref:`kadmind(8)` daemon is to listen for this realm. Port numbers specified in **kadmind_listen** entries will override this port number. The assigned port for kadmind is 749, which is used by default. **key_stash_file** (String.) Specifies the location where the master key has been stored (via kdb5_util stash). The default is |kdcdir|\ ``/.k5.REALM``, where *REALM* is the Kerberos realm. **kdc_listen** (Whitespace- or comma-separated list.) Specifies the listening addresses and/or ports for the :ref:`krb5kdc(8)` daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If no port is specified, the standard port (88) is used. To disable listening on UDP, set this relation to the empty string with ``kdc_listen = ""``. If the KDC daemon fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address on the standard port. New in release 1.15. **kdc_ports** (Whitespace- or comma-separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the :ref:`krb5kdc(8)` daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as **kdc_listen** if that relation is not defined. **kdc_tcp_listen** (Whitespace- or comma-separated list.) Specifies the TCP listening addresses and/or ports for the :ref:`krb5kdc(8)` daemon. The syntax is identical to that of **kdc_listen**. To disable listening on TCP, set this relation to the empty string with ``kdc_tcp_listen = ""``. The default is to bind to the same addresses and ports as for UDP. New in release 1.15. **kdc_tcp_ports** (Whitespace- or comma-separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the :ref:`krb5kdc(8)` daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as **kdc_tcp_listen** if that relation is not defined. **kpasswd_listen** (Comma-separated list.) Specifies the kpasswd listening addresses and/or ports for the :ref:`kadmind(8)` daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. To disable listening for kpasswd requests, set this relation to the empty string with ``kpasswd_listen = ""``. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in **kpasswd_port**, or the standard kpasswd port (464). New in release 1.15. **kpasswd_port** (Port number.) Specifies the port on which the :ref:`kadmind(8)` daemon is to listen for password change requests for this realm. Port numbers specified in **kpasswd_listen** entries will override this port number. The assigned port for password change requests is 464, which is used by default. **master_key_name** (String.) Specifies the name of the principal associated with the master key. The default is ``K/M``. **master_key_type** (Key type string.) Specifies the master key's key type. The default value for this is |defmkey|. For a list of all possible values, see :ref:`Encryption_types`. **max_life** (:ref:`duration` string.) Specifies the maximum time period for which a ticket may be valid in this realm. The default value is 24 hours. **max_renewable_life** (:ref:`duration` string.) Specifies the maximum time period during which a valid ticket may be renewed in this realm. The default value is 0. **no_host_referral** (Whitespace- or comma-separated list.) Lists services to block from getting host-based referral processing, even if the client marks the server principal as host-based or the service is also listed in **host_based_services**. ``no_host_referral = *`` will disable referral processing altogether. **reject_bad_transit** (Boolean value.) If set to true, the KDC will check the list of transited realms for cross-realm tickets against the transit path computed from the realm names and the capaths section of its :ref:`krb5.conf(5)` file; if the path in the ticket to be issued contains any realms not in the computed path, the ticket will not be issued, and an error will be returned to the client instead. If this value is set to false, such tickets will be issued anyways, and it will be left up to the application server to validate the realm transit path. If the disable-transited-check flag is set in the incoming request, this check is not performed at all. Having the **reject_bad_transit** option will cause such ticket requests to be rejected always. This transit path checking and config file option currently apply only to TGS requests. The default value is true. **restrict_anonymous_to_tgt** (Boolean value.) If set to true, the KDC will reject ticket requests from anonymous principals to service principals other than the realm's ticket-granting service. This option allows anonymous PKINIT to be enabled for use as FAST armor tickets without allowing anonymous authentication to services. The default value is false. New in release 1.9. **spake_preauth_indicator** (String.) Specifies an authentication indicator value that the KDC asserts into tickets obtained using SPAKE pre-authentication. The default is not to add any indicators. This option may be specified multiple times. New in release 1.17. **supported_enctypes** (List of *key*:*salt* strings.) Specifies the default key/salt combinations of principals for this realm. Any principals created through :ref:`kadmin(1)` will have keys of these types. The default value for this tag is |defkeysalts|. For lists of possible values, see :ref:`Keysalt_lists`. .. _dbdefaults: [dbdefaults] ~~~~~~~~~~~~ The [dbdefaults] section specifies default values for some database parameters, to be used if the [dbmodules] subsection does not contain a relation for the tag. See the :ref:`dbmodules` section for the definitions of these relations. * **ldap_kerberos_container_dn** * **ldap_kdc_dn** * **ldap_kdc_sasl_authcid** * **ldap_kdc_sasl_authzid** * **ldap_kdc_sasl_mech** * **ldap_kdc_sasl_realm** * **ldap_kadmind_dn** * **ldap_kadmind_sasl_authcid** * **ldap_kadmind_sasl_authzid** * **ldap_kadmind_sasl_mech** * **ldap_kadmind_sasl_realm** * **ldap_service_password_file** * **ldap_conns_per_server** .. _dbmodules: [dbmodules] ~~~~~~~~~~~ The [dbmodules] section contains parameters used by the KDC database library and database modules. Each tag in the [dbmodules] section is the name of a Kerberos realm or a section name specified by a realm's **database_module** parameter. The following example shows how to define one database parameter for the ATHENA.MIT.EDU realm:: [dbmodules] ATHENA.MIT.EDU = { disable_last_success = true } The following tags may be specified in a [dbmodules] subsection: **database_name** This DB2-specific tag indicates the location of the database in the filesystem. The default is |kdcdir|\ ``/principal``. **db_library** This tag indicates the name of the loadable database module. The value should be ``db2`` for the DB2 module, ``klmdb`` for the LMDB module, or ``kldap`` for the LDAP module. **disable_last_success** If set to ``true``, suppresses KDC updates to the "Last successful authentication" field of principal entries requiring preauthentication. Setting this flag may improve performance. (Principal entries which do not require preauthentication never update the "Last successful authentication" field.). First introduced in release 1.9. **disable_lockout** If set to ``true``, suppresses KDC updates to the "Last failed authentication" and "Failed password attempts" fields of principal entries requiring preauthentication. Setting this flag may improve performance, but also disables account lockout. First introduced in release 1.9. **ldap_conns_per_server** This LDAP-specific tag indicates the number of connections to be maintained per LDAP server. **ldap_kdc_dn** and **ldap_kadmind_dn** These LDAP-specific tags indicate the default DN for binding to the LDAP server. The :ref:`krb5kdc(8)` daemon uses **ldap_kdc_dn**, while the :ref:`kadmind(8)` daemon and other administrative programs use **ldap_kadmind_dn**. The kadmind DN must have the rights to read and write the Kerberos data in the LDAP database. The KDC DN must have the same rights, unless **disable_lockout** and **disable_last_success** are true, in which case it only needs to have rights to read the Kerberos data. These tags are ignored if a SASL mechanism is set with **ldap_kdc_sasl_mech** or **ldap_kadmind_sasl_mech**. **ldap_kdc_sasl_mech** and **ldap_kadmind_sasl_mech** These LDAP-specific tags specify the SASL mechanism (such as ``EXTERNAL``) to use when binding to the LDAP server. New in release 1.13. **ldap_kdc_sasl_authcid** and **ldap_kadmind_sasl_authcid** These LDAP-specific tags specify the SASL authentication identity to use when binding to the LDAP server. Not all SASL mechanisms require an authentication identity. If the SASL mechanism requires a secret (such as the password for ``DIGEST-MD5``), these tags also determine the name within the **ldap_service_password_file** where the secret is stashed. New in release 1.13. **ldap_kdc_sasl_authzid** and **ldap_kadmind_sasl_authzid** These LDAP-specific tags specify the SASL authorization identity to use when binding to the LDAP server. In most circumstances they do not need to be specified. New in release 1.13. **ldap_kdc_sasl_realm** and **ldap_kadmind_sasl_realm** These LDAP-specific tags specify the SASL realm to use when binding to the LDAP server. In most circumstances they do not need to be set. New in release 1.13. **ldap_kerberos_container_dn** This LDAP-specific tag indicates the DN of the container object where the realm objects will be located. **ldap_servers** This LDAP-specific tag indicates the list of LDAP servers that the Kerberos servers can connect to. The list of LDAP servers is whitespace-separated. The LDAP server is specified by a LDAP URI. It is recommended to use ``ldapi:`` or ``ldaps:`` URLs to connect to the LDAP server. **ldap_service_password_file** This LDAP-specific tag indicates the file containing the stashed passwords (created by ``kdb5_ldap_util stashsrvpw``) for the **ldap_kdc_dn** and **ldap_kadmind_dn** objects, or for the **ldap_kdc_sasl_authcid** or **ldap_kadmind_sasl_authcid** names for SASL authentication. This file must be kept secure. **mapsize** This LMDB-specific tag indicates the maximum size of the two database environments in megabytes. The default value is 128. Increase this value to address "Environment mapsize limit reached" errors. New in release 1.17. **max_readers** This LMDB-specific tag indicates the maximum number of concurrent reading processes for the databases. The default value is 128. New in release 1.17. **nosync** This LMDB-specific tag can be set to improve the throughput of kadmind and other administrative agents, at the expense of durability (recent database changes may not survive a power outage or other sudden reboot). It does not affect the throughput of the KDC. The default value is false. New in release 1.17. **unlockiter** If set to ``true``, this DB2-specific tag causes iteration operations to release the database lock while processing each principal. Setting this flag to ``true`` can prevent extended blocking of KDC or kadmin operations when dumps of large databases are in progress. First introduced in release 1.13. The following tag may be specified directly in the [dbmodules] section to control where database modules are loaded from: **db_module_dir** This tag controls where the plugin system looks for database modules. The value should be an absolute path. .. _logging: [logging] ~~~~~~~~~ The [logging] section indicates how :ref:`krb5kdc(8)` and :ref:`kadmind(8)` perform logging. It may contain the following relations: **admin_server** Specifies how :ref:`kadmind(8)` performs logging. **kdc** Specifies how :ref:`krb5kdc(8)` performs logging. **default** Specifies how either daemon performs logging in the absence of relations specific to the daemon. **debug** (Boolean value.) Specifies whether debugging messages are included in log outputs other than SYSLOG. Debugging messages are always included in the system log output because syslog performs its own priority filtering. The default value is false. New in release 1.15. Logging specifications may have the following forms: **FILE=**\ *filename* or **FILE:**\ *filename* This value causes the daemon's logging messages to go to the *filename*. If the ``=`` form is used, the file is overwritten. If the ``:`` form is used, the file is appended to. **STDERR** This value causes the daemon's logging messages to go to its standard error stream. **CONSOLE** This value causes the daemon's logging messages to go to the console, if the system supports it. **DEVICE=**\ ** This causes the daemon's logging messages to go to the specified device. **SYSLOG**\ [\ **:**\ *severity*\ [\ **:**\ *facility*\ ]] This causes the daemon's logging messages to go to the system log. For backward compatibility, a severity argument may be specified, and must be specified in order to specify a facility. This argument will be ignored. The facility argument specifies the facility under which the messages are logged. This may be any of the following facilities supported by the syslog(3) call minus the LOG\_ prefix: **KERN**, **USER**, **MAIL**, **DAEMON**, **AUTH**, **LPR**, **NEWS**, **UUCP**, **CRON**, and **LOCAL0** through **LOCAL7**. If no facility is specified, the default is **AUTH**. In the following example, the logging messages from the KDC will go to the console and to the system log under the facility LOG_DAEMON, and the logging messages from the administrative server will be appended to the file ``/var/adm/kadmin.log`` and sent to the device ``/dev/tty04``. :: [logging] kdc = CONSOLE kdc = SYSLOG:INFO:DAEMON admin_server = FILE:/var/adm/kadmin.log admin_server = DEVICE=/dev/tty04 If no logging specification is given, the default is to use syslog. To disable logging entirely, specify ``default = DEVICE=/dev/null``. .. _otp: [otp] ~~~~~ Each subsection of [otp] is the name of an OTP token type. The tags within the subsection define the configuration required to forward a One Time Password request to a RADIUS server. For each token type, the following tags may be specified: **server** This is the server to send the RADIUS request to. It can be a hostname with optional port, an ip address with optional port, or a Unix domain socket address. The default is |kdcdir|\ ``/.socket``. **secret** This tag indicates a filename (which may be relative to |kdcdir|) containing the secret used to encrypt the RADIUS packets. The secret should appear in the first line of the file by itself; leading and trailing whitespace on the line will be removed. If the value of **server** is a Unix domain socket address, this tag is optional, and an empty secret will be used if it is not specified. Otherwise, this tag is required. **timeout** An integer which specifies the time in seconds during which the KDC should attempt to contact the RADIUS server. This tag is the total time across all retries and should be less than the time which an OTP value remains valid for. The default is 5 seconds. **retries** This tag specifies the number of retries to make to the RADIUS server. The default is 3 retries (4 tries). **strip_realm** If this tag is ``true``, the principal without the realm will be passed to the RADIUS server. Otherwise, the realm will be included. The default value is ``true``. **indicator** This tag specifies an authentication indicator to be included in the ticket if this token type is used to authenticate. This option may be specified multiple times. (New in release 1.14.) In the following example, requests are sent to a remote server via UDP:: [otp] MyRemoteTokenType = { server = radius.mydomain.com:1812 secret = SEmfiajf42$ timeout = 15 retries = 5 strip_realm = true } An implicit default token type named ``DEFAULT`` is defined for when the per-principal configuration does not specify a token type. Its configuration is shown below. You may override this token type to something applicable for your situation:: [otp] DEFAULT = { strip_realm = false } PKINIT options -------------- .. note:: The following are pkinit-specific options. These values may be specified in [kdcdefaults] as global defaults, or within a realm-specific subsection of [realms]. Also note that a realm-specific value over-rides, does not add to, a generic [kdcdefaults] specification. The search order is: 1. realm-specific subsection of [realms]:: [realms] EXAMPLE.COM = { pkinit_anchors = FILE:/usr/local/example.com.crt } 2. generic value in the [kdcdefaults] section:: [kdcdefaults] pkinit_anchors = DIR:/usr/local/generic_trusted_cas/ For information about the syntax of some of these options, see :ref:`Specifying PKINIT identity information ` in :ref:`krb5.conf(5)`. **pkinit_anchors** Specifies the location of trusted anchor (root) certificates which the KDC trusts to sign client certificates. This option is required if pkinit is to be supported by the KDC. This option may be specified multiple times. **pkinit_dh_min_bits** Specifies the minimum strength of Diffie-Hellman group the KDC is willing to accept for key exchange. Valid values in order of increasing strength are 1024, 2048, P-256, 4096, P-384, and P-521. The default is 2048. (P-256, P-384, and P-521 are new in release 1.22.) **pkinit_allow_upn** Specifies that the KDC is willing to accept client certificates with the Microsoft UserPrincipalName (UPN) Subject Alternative Name (SAN). This means the KDC accepts the binding of the UPN in the certificate to the Kerberos principal name. The default value is false. Without this option, the KDC will only accept certificates with the id-pkinit-san as defined in :rfc:`4556`. There is currently no option to disable SAN checking in the KDC. **pkinit_eku_checking** This option specifies what Extended Key Usage (EKU) values the KDC is willing to accept in client certificates. The values recognized in the kdc.conf file are: **kpClientAuth** This is the default value and specifies that client certificates must have the id-pkinit-KPClientAuth EKU as defined in :rfc:`4556`. **scLogin** If scLogin is specified, client certificates with the Microsoft Smart Card Login EKU (id-ms-kp-sc-logon) will be accepted. **none** If none is specified, then client certificates will not be checked to verify they have an acceptable EKU. The use of this option is not recommended. **pkinit_identity** Specifies the location of the KDC's X.509 identity information. This option is required if pkinit is to be supported by the KDC. **pkinit_indicator** Specifies an authentication indicator to include in the ticket if pkinit is used to authenticate. This option may be specified multiple times. (New in release 1.14.) **pkinit_pool** Specifies the location of intermediate certificates which may be used by the KDC to complete the trust chain between a client's certificate and a trusted anchor. This option may be specified multiple times. **pkinit_revoke** Specifies the location of Certificate Revocation List (CRL) information to be used by the KDC when verifying the validity of client certificates. This option may be specified multiple times. **pkinit_require_crl_checking** The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and **pkinit_require_crl_checking** is false, then verification succeeds. However, if **pkinit_require_crl_checking** is true and there is no CRL information available for the issuing CA, then verification fails. **pkinit_require_crl_checking** should be set to true if the policy is such that up-to-date CRLs must be present for every CA. **pkinit_require_freshness** Specifies whether to require clients to include a freshness token in PKINIT requests. The default value is false. (New in release 1.17.) .. _Encryption_types: Encryption types ---------------- Any tag in the configuration files which requires a list of encryption types can be set to some combination of the following strings. Encryption types marked as "weak" and "deprecated" are available for compatibility but not recommended for use. ==================================================== ========================================================= des3-cbc-raw Triple DES cbc mode raw (weak) des3-cbc-sha1 des3-hmac-sha1 des3-cbc-sha1-kd Triple DES cbc mode with HMAC/sha1 (deprecated) aes256-cts-hmac-sha1-96 aes256-cts aes256-sha1 AES-256 CTS mode with 96-bit SHA-1 HMAC aes128-cts-hmac-sha1-96 aes128-cts aes128-sha1 AES-128 CTS mode with 96-bit SHA-1 HMAC aes256-cts-hmac-sha384-192 aes256-sha2 AES-256 CTS mode with 192-bit SHA-384 HMAC aes128-cts-hmac-sha256-128 aes128-sha2 AES-128 CTS mode with 128-bit SHA-256 HMAC arcfour-hmac rc4-hmac arcfour-hmac-md5 RC4 with HMAC/MD5 (deprecated) arcfour-hmac-exp rc4-hmac-exp arcfour-hmac-md5-exp Exportable RC4 with HMAC/MD5 (weak) camellia256-cts-cmac camellia256-cts Camellia-256 CTS mode with CMAC camellia128-cts-cmac camellia128-cts Camellia-128 CTS mode with CMAC des3 The triple DES family: des3-cbc-sha1 aes The AES family: aes256-cts-hmac-sha1-96, aes128-cts-hmac-sha1-96, aes256-cts-hmac-sha384-192, and aes128-cts-hmac-sha256-128 rc4 The RC4 family: arcfour-hmac camellia The Camellia family: camellia256-cts-cmac and camellia128-cts-cmac ==================================================== ========================================================= The string **DEFAULT** can be used to refer to the default set of types for the variable in question. Types or families can be removed from the current list by prefixing them with a minus sign ("-"). Types or families can be prefixed with a plus sign ("+") for symmetry; it has the same meaning as just listing the type or family. For example, "``DEFAULT -rc4``" would be the default set of encryption types with RC4 types removed, and "``des3 DEFAULT``" would be the default set of encryption types with triple DES types moved to the front. While **aes128-cts** and **aes256-cts** are supported for all Kerberos operations, they are not supported by very old versions of our GSSAPI implementation (krb5-1.3.1 and earlier). Services running versions of krb5 without AES support must not be given keys of these encryption types in the KDC database. The **aes128-sha2** and **aes256-sha2** encryption types are new in release 1.15. Services running versions of krb5 without support for these newer encryption types must not be given keys of these encryption types in the KDC database. .. _Keysalt_lists: Keysalt lists ------------- Kerberos keys for users are usually derived from passwords. Kerberos commands and configuration parameters that affect generation of keys take lists of enctype-salttype ("keysalt") pairs, known as *keysalt lists*. Each keysalt pair is an enctype name followed by a salttype name, in the format *enc*:*salt*. Individual keysalt list members are separated by comma (",") characters or space characters. For example:: kadmin -e aes256-cts:normal,aes128-cts:normal would start up kadmin so that by default it would generate password-derived keys for the **aes256-cts** and **aes128-cts** encryption types, using a **normal** salt. To ensure that people who happen to pick the same password do not have the same key, Kerberos 5 incorporates more information into the key using something called a salt. The supported salt types are as follows: ================= ============================================ normal default for Kerberos Version 5 norealm same as the default, without using realm information onlyrealm uses only realm information as the salt special generate a random salt ================= ============================================ Sample kdc.conf File -------------------- Here's an example of a kdc.conf file:: [kdcdefaults] kdc_listen = 88 kdc_tcp_listen = 88 [realms] ATHENA.MIT.EDU = { kadmind_port = 749 max_life = 12h 0m 0s max_renewable_life = 7d 0h 0m 0s master_key_type = aes256-cts-hmac-sha1-96 supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal database_module = openldap_ldapconf } [logging] kdc = FILE:/usr/local/var/krb5kdc/kdc.log admin_server = FILE:/usr/local/var/krb5kdc/kadmin.log [dbdefaults] ldap_kerberos_container_dn = cn=krbcontainer,dc=mit,dc=edu [dbmodules] openldap_ldapconf = { db_library = kldap disable_last_success = true ldap_kdc_dn = "cn=krbadmin,dc=mit,dc=edu" # this object needs to have read rights on # the realm container and principal subtrees ldap_kadmind_dn = "cn=krbadmin,dc=mit,dc=edu" # this object needs to have read and write rights on # the realm container and principal subtrees ldap_service_password_file = /etc/kerberos/service.keyfile ldap_servers = ldaps://kerberos.mit.edu ldap_conns_per_server = 5 } FILES ------ |kdcdir|\ ``/kdc.conf`` SEE ALSO --------- :ref:`krb5.conf(5)`, :ref:`krb5kdc(8)`, :ref:`kadm5.acl(5)` krb5-1.22.1/doc/html/_sources/admin/dictionary.rst.txt0000664000175000017500000001044615051422642022510 0ustar ghudsonghudson.. _dictionary: Addressing dictionary attack risks ================================== Kerberos initial authentication is normally secured using the client principal's long-term key, which for users is generally derived from a password. Using a pasword-derived long-term key carries the risk of a dictionary attack, where an attacker tries a sequence of possible passwords, possibly requiring much less effort than would be required to try all possible values of the key. Even if :ref:`password policy objects ` are used to force users not to pick trivial passwords, dictionary attacks can sometimes be successful against a significant fraction of the users in a realm. Dictionary attacks are not a concern for principals using random keys. A dictionary attack may be online or offline. An online dictionary attack is performed by trying each password in a separate request to the KDC, and is therefore visible to the KDC and also limited in speed by the KDC's processing power and the network capacity between the client and the KDC. Online dictionary attacks can be mitigated using :ref:`account lockout `. This measure is not totally satisfactory, as it makes it easy for an attacker to deny access to a client principal. An offline dictionary attack is performed by obtaining a ciphertext generated using the password-derived key, and trying each password against the ciphertext. This category of attack is invisible to the KDC and can be performed much faster than an online attack. The attack will generally take much longer with more recent encryption types (particularly the ones based on AES), because those encryption types use a much more expensive string-to-key function. However, the best defense is to deny the attacker access to a useful ciphertext. The required defensive measures depend on the attacker's level of network access. An off-path attacker has no access to packets sent between legitimate users and the KDC. An off-path attacker could gain access to an attackable ciphertext either by making an AS request for a client principal which does not have the **+requires_preauth** flag, or by making a TGS request (after authenticating as a different user) for a server principal which does not have the **-allow_svr** flag. To address off-path attackers, a KDC administrator should set those flags on principals with password-derived keys:: kadmin: add_principal +requires_preauth -allow_svr princname An attacker with passive network access (one who can monitor packets sent between legitimate users and the KDC, but cannot change them or insert their own packets) can gain access to an attackable ciphertext by observing an authentication by a user using the most common form of preauthentication, encrypted timestamp. Any of the following methods can prevent dictionary attacks by attackers with passive network access: * Enabling :ref:`SPAKE preauthentication ` (added in release 1.17) on the KDC, and ensuring that all clients are able to support it. * Using an :ref:`HTTPS proxy ` for communication with the KDC, if the attacker cannot monitor communication between the proxy server and the KDC. * Using FAST, protecting the initial authentication with either a random key (such as a host key) or with :ref:`anonymous PKINIT `. An attacker with active network access (one who can inject or modify packets sent between legitimate users and the KDC) can try to fool the client software into sending an attackable ciphertext using an encryption type and salt string of the attacker's choosing. Any of the following methods can prevent dictionary attacks by active attackers: * Enabling SPAKE preauthentication and setting the **disable_encrypted_timestamp** variable to ``true`` in the :ref:`realms` subsection of the client configuration. * Using an HTTPS proxy as described above, configured in the client's krb5.conf realm configuration. If :ref:`KDC discovery ` is used to locate a proxy server, an active attacker may be able to use DNS spoofing to cause the client to use a different HTTPS server or to not use HTTPS. * Using FAST as described above. If :ref:`PKINIT ` or :ref:`OTP ` are used for initial authentication, the principal's long-term keys are not used and dictionary attacks are usually not a concern. krb5-1.22.1/doc/html/_sources/admin/otp.rst.txt0000664000175000017500000000663415051422642021151 0ustar ghudsonghudson.. _otp_preauth: OTP Preauthentication ===================== OTP is a preauthentication mechanism for Kerberos 5 which uses One Time Passwords (OTP) to authenticate the client to the KDC. The OTP is passed to the KDC over an encrypted FAST channel in clear-text. The KDC uses the password along with per-user configuration to proxy the request to a third-party RADIUS system. This enables out-of-the-box compatibility with a large number of already widely deployed proprietary systems. Additionally, our implementation of the OTP system allows for the passing of RADIUS requests over a UNIX domain stream socket. This permits the use of a local companion daemon which can handle the details of authentication. Defining token types -------------------- Token types are defined in either :ref:`krb5.conf(5)` or :ref:`kdc.conf(5)` according to the following format:: [otp] = { server = (default: see below) secret = timeout = (default: 5 [seconds]) retries = (default: 3) strip_realm = (default: true) indicator = (default: none) } If the server field begins with '/', it will be interpreted as a UNIX socket. Otherwise, it is assumed to be in the format host:port. When a UNIX domain socket is specified, the secret field is optional and an empty secret is used by default. If the server field is not specified, it defaults to |kdcrundir|\ ``/.socket``. When forwarding the request over RADIUS, by default the principal is used in the User-Name attribute of the RADIUS packet. The strip_realm parameter controls whether the principal is forwarded with or without the realm portion. If an indicator field is present, tickets issued using this token type will be annotated with the specified authentication indicator (see :ref:`auth_indicator`). This key may be specified multiple times to add multiple indicators. The default token type ---------------------- A default token type is used internally when no token type is specified for a given user. It is defined as follows:: [otp] DEFAULT = { strip_realm = false } The administrator may override the internal ``DEFAULT`` token type simply by defining a configuration with the same name. Token instance configuration ---------------------------- To enable OTP for a client principal, the administrator must define the **otp** string attribute for that principal. (See :ref:`set_string`.) The **otp** user string is a JSON string of the format: .. code-block:: xml [{ "type": , "username": , "indicators": [, ...] }, ...] This is an array of token objects. Both fields of token objects are optional. The **type** field names the token type of this token; if not specified, it defaults to ``DEFAULT``. The **username** field specifies the value to be sent in the User-Name RADIUS attribute. If not specified, the principal name is sent, with or without realm as defined in the token type. The **indicators** field specifies a list of authentication indicators to annotate tickets with, overriding any indicators specified in the token type. For ease of configuration, an empty array (``[]``) is treated as equivalent to one DEFAULT token (``[{}]``). Other considerations -------------------- #. FAST is required for OTP to work. krb5-1.22.1/doc/html/_sources/admin/admin_commands/0000775000175000017500000000000015051422656021744 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/admin/admin_commands/kadmind.rst.txt0000664000175000017500000001127415051422642024723 0ustar ghudsonghudson.. _kadmind(8): kadmind ======= SYNOPSIS -------- **kadmind** [**-x** *db_args*] [**-r** *realm*] [**-m**] [**-nofork**] [**-proponly**] [**-port** *port-number*] [**-P** *pid_file*] [**-p** *kdb5_util_path*] [**-K** *kprop_path*] [**-k** *kprop_port*] [**-F** *dump_file*] DESCRIPTION ----------- kadmind starts the Kerberos administration server. kadmind typically runs on the primary Kerberos server, which stores the KDC database. If the KDC database uses the LDAP module, the administration server and the KDC server need not run on the same machine. kadmind accepts remote requests from programs such as :ref:`kadmin(1)` and :ref:`kpasswd(1)` to administer the information in these database. kadmind requires a number of configuration files to be set up in order for it to work: :ref:`kdc.conf(5)` The KDC configuration file contains configuration information for the KDC and admin servers. kadmind uses settings in this file to locate the Kerberos database, and is also affected by the **acl_file**, **dict_file**, **kadmind_port**, and iprop-related settings. :ref:`kadm5.acl(5)` kadmind's ACL (access control list) tells it which principals are allowed to perform administration actions. The pathname to the ACL file can be specified with the **acl_file** :ref:`kdc.conf(5)` variable; by default, it is |kdcdir|\ ``/kadm5.acl``. After the server begins running, it puts itself in the background and disassociates itself from its controlling terminal. kadmind can be configured for incremental database propagation. Incremental propagation allows replica KDC servers to receive principal and policy updates incrementally instead of receiving full dumps of the database. This facility can be enabled in the :ref:`kdc.conf(5)` file with the **iprop_enable** option. Incremental propagation requires the principal ``kiprop/PRIMARY\@REALM`` (where PRIMARY is the primary KDC's canonical host name, and REALM the realm name). In release 1.13, this principal is automatically created and registered into the datebase. OPTIONS ------- **-r** *realm* specifies the realm that kadmind will serve; if it is not specified, the default realm of the host is used. **-m** causes the master database password to be fetched from the keyboard (before the server puts itself in the background, if not invoked with the **-nofork** option) rather than from a file on disk. **-nofork** causes the server to remain in the foreground and remain associated to the terminal. **-proponly** causes the server to only listen and respond to Kerberos replica incremental propagation polling requests. This option can be used to set up a hierarchical propagation topology where a replica KDC provides incremental updates to other Kerberos replicas. **-port** *port-number* specifies the port on which the administration server listens for connections. The default port is determined by the **kadmind_port** configuration variable in :ref:`kdc.conf(5)`. **-P** *pid_file* specifies the file to which the PID of kadmind process should be written after it starts up. This file can be used to identify whether kadmind is still running and to allow init scripts to stop the correct process. **-p** *kdb5_util_path* specifies the path to the kdb5_util command to use when dumping the KDB in response to full resync requests when iprop is enabled. **-K** *kprop_path* specifies the path to the kprop command to use to send full dumps to replicas in response to full resync requests. **-k** *kprop_port* specifies the port by which the kprop process that is spawned by kadmind connects to the replica kpropd, in order to transfer the dump file during an iprop full resync request. **-F** *dump_file* specifies the file path to be used for dumping the KDB in response to full resync requests when iprop is enabled. **-x** *db_args* specifies database-specific arguments. See :ref:`Database Options ` in :ref:`kadmin(1)` for supported arguments. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. As of release 1.22, kadmind supports systemd socket activation via the LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by the caller must correspond to configured listener addresses (via the **kadmind_listen** or **kpasswd_listen** variables or equivalents) or they will be ignored. Any configured listener addresses that do not correspond to caller-provided sockets will be ignored if socket activation is used. SEE ALSO -------- :ref:`kpasswd(1)`, :ref:`kadmin(1)`, :ref:`kdb5_util(8)`, :ref:`kdb5_ldap_util(8)`, :ref:`kadm5.acl(5)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/admin/admin_commands/sserver.rst.txt0000664000175000017500000000623515051422642025006 0ustar ghudsonghudson.. _sserver(8): sserver ======= SYNOPSIS -------- **sserver** [ **-p** *port* ] [ **-S** *keytab* ] [ *server_port* ] DESCRIPTION ----------- sserver and :ref:`sclient(1)` are a simple demonstration client/server application. When sclient connects to sserver, it performs a Kerberos authentication, and then sserver returns to sclient the Kerberos principal which was used for the Kerberos authentication. It makes a good test that Kerberos has been successfully installed on a machine. The service name used by sserver and sclient is sample. Hence, sserver will require that there be a keytab entry for the service ``sample/hostname.domain.name@REALM.NAME``. This keytab is generated using the :ref:`kadmin(1)` program. The keytab file is usually installed as |keytab|. The **-S** option allows for a different keytab than the default. sserver is normally invoked out of inetd(8), using a line in ``/etc/inetd.conf`` that looks like this:: sample stream tcp nowait root /usr/local/sbin/sserver sserver Since ``sample`` is normally not a port defined in ``/etc/services``, you will usually have to add a line to ``/etc/services`` which looks like this:: sample 13135/tcp When using sclient, you will first have to have an entry in the Kerberos database, by using :ref:`kadmin(1)`, and then you have to get Kerberos tickets, by using :ref:`kinit(1)`. Also, if you are running the sclient program on a different host than the sserver it will be connecting to, be sure that both hosts have an entry in /etc/services for the sample tcp port, and that the same port number is in both files. When you run sclient you should see something like this:: sendauth succeeded, reply is: reply len 32, contents: You are nlgilman@JIMI.MIT.EDU COMMON ERROR MESSAGES --------------------- 1) kinit returns the error:: kinit: Client not found in Kerberos database while getting initial credentials This means that you didn't create an entry for your username in the Kerberos database. 2) sclient returns the error:: unknown service sample/tcp; check /etc/services This means that you don't have an entry in /etc/services for the sample tcp port. 3) sclient returns the error:: connect: Connection refused This probably means you didn't edit /etc/inetd.conf correctly, or you didn't restart inetd after editing inetd.conf. 4) sclient returns the error:: sclient: Server not found in Kerberos database while using sendauth This means that the ``sample/hostname@LOCAL.REALM`` service was not defined in the Kerberos database; it should be created using :ref:`kadmin(1)`, and a keytab file needs to be generated to make the key for that service principal available for sclient. 5) sclient returns the error:: sendauth rejected, error reply is: "No such file or directory" This probably means sserver couldn't find the keytab file. It was probably not installed in the proper directory. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`sclient(1)`, :ref:`kerberos(7)`, services(5), inetd(8) krb5-1.22.1/doc/html/_sources/admin/admin_commands/kproplog.rst.txt0000664000175000017500000000504315051422642025146 0ustar ghudsonghudson.. _kproplog(8): kproplog ======== SYNOPSIS -------- **kproplog** [**-h**] [**-e** *num*] [-v] **kproplog** [-R] DESCRIPTION ----------- The kproplog command displays the contents of the KDC database update log to standard output. It can be used to keep track of incremental updates to the principal database. The update log file contains the update log maintained by the :ref:`kadmind(8)` process on the primary KDC server and the :ref:`kpropd(8)` process on the replica KDC servers. When updates occur, they are logged to this file. Subsequently any KDC replica configured for incremental updates will request the current data from the primary KDC and update their log file with any updates returned. The kproplog command requires read access to the update log file. It will display update entries only for the KDC it runs on. If no options are specified, kproplog displays a summary of the update log. If invoked on the primary, kproplog also displays all of the update entries. If invoked on a replica KDC server, kproplog displays only a summary of the updates, which includes the serial number of the last update received and the associated time stamp of the last update. OPTIONS ------- **-R** Reset the update log. This forces full resynchronization. If used on a replica then that replica will request a full resync. If used on the primary then all replicas will request full resyncs. **-h** Display a summary of the update log. This information includes the database version number, state of the database, the number of updates in the log, the time stamp of the first and last update, and the version number of the first and last update entry. **-e** *num* Display the last *num* update entries in the log. This is useful when debugging synchronization between KDC servers. **-v** Display individual attributes per update. An example of the output generated for one entry:: Update Entry Update serial # : 4 Update operation : Add Update principal : test@EXAMPLE.COM Update size : 424 Update committed : True Update time stamp : Fri Feb 20 23:37:42 2004 Attributes changed : 6 Principal Key data Password last changed Modifying principal Modification time TL data ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kpropd(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/admin/admin_commands/index.rst.txt0000664000175000017500000000040315051422642024413 0ustar ghudsonghudsonAdministration programs ======================== .. toctree:: :maxdepth: 1 kadmin_local.rst kadmind.rst kdb5_util.rst kdb5_ldap_util.rst krb5kdc.rst kprop.rst kpropd.rst kproplog.rst ktutil.rst k5srvutil.rst sserver.rst krb5-1.22.1/doc/html/_sources/admin/admin_commands/kpropd.rst.txt0000664000175000017500000001104215051422642024604 0ustar ghudsonghudson.. _kpropd(8): kpropd ====== SYNOPSIS -------- **kpropd** [**-r** *realm*] [**-A** *admin_server*] [**-a** *acl_file*] [**-f** *replica_dumpfile*] [**-F** *principal_database*] [**-p** *kdb5_util_prog*] [**-P** *port*] [**--pid-file**\ =\ *pid_file*] [**-D**] [**-d**] [**-s** *keytab_file*] DESCRIPTION ----------- The *kpropd* command runs on the replica KDC server. It listens for update requests made by the :ref:`kprop(8)` program. If incremental propagation is enabled, it periodically requests incremental updates from the primary KDC. When the replica receives a kprop request from the primary, kpropd accepts the dumped KDC database and places it in a file, and then runs :ref:`kdb5_util(8)` to load the dumped database into the active database which is used by :ref:`krb5kdc(8)`. This allows the primary Kerberos server to use :ref:`kprop(8)` to propagate its database to the replica servers. Upon a successful download of the KDC database file, the replica Kerberos server will have an up-to-date KDC database. Where incremental propagation is not used, kpropd is commonly invoked out of inetd(8) as a nowait service. This is done by adding a line to the ``/etc/inetd.conf`` file which looks like this:: kprop stream tcp nowait root /usr/local/sbin/kpropd kpropd kpropd can also run as a standalone daemon, backgrounding itself and waiting for connections on port 754 (or the port specified with the **-P** option if given). Standalone mode is required for incremental propagation. Starting in release 1.11, kpropd automatically detects whether it was run from inetd and runs in standalone mode if it is not. Prior to release 1.11, the **-S** option is required to run kpropd in standalone mode; this option is now accepted for backward compatibility but does nothing. Incremental propagation may be enabled with the **iprop_enable** variable in :ref:`kdc.conf(5)`. If incremental propagation is enabled, the replica periodically polls the primary KDC for updates, at an interval determined by the **iprop_replica_poll** variable. If the replica receives updates, kpropd updates its log file with any updates from the primary. :ref:`kproplog(8)` can be used to view a summary of the update entry log on the replica KDC. If incremental propagation is enabled, the principal ``kiprop/replicahostname@REALM`` (where *replicahostname* is the name of the replica KDC host, and *REALM* is the name of the Kerberos realm) must be present in the replica's keytab file. :ref:`kproplog(8)` can be used to force full replication when iprop is enabled. OPTIONS -------- **-r** *realm* Specifies the realm of the primary server. **-A** *admin_server* Specifies the server to be contacted for incremental updates; by default, the primary admin server is contacted. **-f** *file* Specifies the filename where the dumped principal database file is to be stored; by default the dumped database file is |kdcdir|\ ``/from_master``. **-F** *kerberos_db* Path to the Kerberos database file, if not the default. **-p** Allows the user to specify the pathname to the :ref:`kdb5_util(8)` program; by default the pathname used is |sbindir|\ ``/kdb5_util``. **-D** In this mode, kpropd will not detach itself from the current job and run in the background. Instead, it will run in the foreground. **-d** Turn on debug mode. kpropd will print out debugging messages during the database propogation and will run in the foreground (implies **-D**). **-P** Allow for an alternate port number for kpropd to listen on. This is only useful in combination with the **-S** option. **-a** *acl_file* Allows the user to specify the path to the kpropd.acl file; by default the path used is |kdcdir|\ ``/kpropd.acl``. **--pid-file**\ =\ *pid_file* In standalone mode, write the process ID of the daemon into *pid_file*. **-s** *keytab_file* Path to a keytab to use for acquiring acceptor credentials. **-x** *db_args* Database-specific arguments. See :ref:`Database Options ` in :ref:`kadmin(1)` for supported arguments. FILES ----- kpropd.acl Access file for kpropd; the default location is ``/usr/local/var/krb5kdc/kpropd.acl``. Each entry is a line containing the principal of a host from which the local machine will allow Kerberos database propagation via :ref:`kprop(8)`. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kprop(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)`, :ref:`kerberos(7)`, inetd(8) krb5-1.22.1/doc/html/_sources/admin/admin_commands/kdb5_ldap_util.rst.txt0000664000175000017500000002656115051422642026203 0ustar ghudsonghudson.. _kdb5_ldap_util(8): kdb5_ldap_util =============== SYNOPSIS -------- .. _kdb5_ldap_util_synopsis: **kdb5_ldap_util** [**-D** *user_dn* [**-w** *passwd*]] [**-H** *ldapuri*] **command** [*command_options*] .. _kdb5_ldap_util_synopsis_end: DESCRIPTION ----------- kdb5_ldap_util allows an administrator to manage realms, Kerberos services and ticket policies. COMMAND-LINE OPTIONS -------------------- .. _kdb5_ldap_util_options: **-r** *realm* Specifies the realm to be operated on. **-D** *user_dn* Specifies the Distinguished Name (DN) of the user who has sufficient rights to perform the operation on the LDAP server. **-w** *passwd* Specifies the password of *user_dn*. This option is not recommended. **-H** *ldapuri* Specifies the URI of the LDAP server. By default, kdb5_ldap_util operates on the default realm (as specified in :ref:`krb5.conf(5)`) and connects and authenticates to the LDAP server in the same manner as :ref:kadmind(8)` would given the parameters in :ref:`dbdefaults` in :ref:`kdc.conf(5)`. .. _kdb5_ldap_util_options_end: COMMANDS -------- create ~~~~~~ .. _kdb5_ldap_util_create: **create** [**-subtrees** *subtree_dn_list*] [**-sscope** *search_scope*] [**-containerref** *container_reference_dn*] [**-k** *mkeytype*] [**-kv** *mkeyVNO*] [**-M** *mkeyname*] [**-m|-P** *password*\|\ **-sf** *stashfilename*] [**-s**] [**-maxtktlife** *max_ticket_life*] [**-maxrenewlife** *max_renewable_ticket_life*] [*ticket_flags*] Creates realm in directory. Options: **-subtrees** *subtree_dn_list* Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (``:``). **-sscope** *search_scope* Specifies the scope for searching the principals under the subtree. The possible values are 1 or one (one level), 2 or sub (subtrees). **-containerref** *container_reference_dn* Specifies the DN of the container object in which the principals of a realm will be created. If the container reference is not configured for a realm, the principals will be created in the realm container. **-k** *mkeytype* Specifies the key type of the master key in the database. The default is given by the **master_key_type** variable in :ref:`kdc.conf(5)`. **-kv** *mkeyVNO* Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed. **-M** *mkeyname* Specifies the principal name for the master key in the database. If not specified, the name is determined by the **master_key_name** variable in :ref:`kdc.conf(5)`. **-m** Specifies that the master database password should be read from the TTY rather than fetched from a file on the disk. **-P** *password* Specifies the master database password. This option is not recommended. **-sf** *stashfilename* Specifies the stash file of the master database password. **-s** Specifies that the stash file is to be created. **-maxtktlife** *max_ticket_life* (:ref:`getdate` string) Specifies maximum ticket life for principals in this realm. **-maxrenewlife** *max_renewable_ticket_life* (:ref:`getdate` string) Specifies maximum renewable life of tickets for principals in this realm. *ticket_flags* Specifies global ticket flags for the realm. Allowable flags are documented in the description of the **add_principal** command in :ref:`kadmin(1)`. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU create -subtrees o=org -sscope SUB Password for "cn=admin,o=org": Initializing database for realm 'ATHENA.MIT.EDU' You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter KDC database master key: Re-enter KDC database master key to verify: .. _kdb5_ldap_util_create_end: modify ~~~~~~ .. _kdb5_ldap_util_modify: **modify** [**-subtrees** *subtree_dn_list*] [**-sscope** *search_scope*] [**-containerref** *container_reference_dn*] [**-maxtktlife** *max_ticket_life*] [**-maxrenewlife** *max_renewable_ticket_life*] [*ticket_flags*] Modifies the attributes of a realm. Options: **-subtrees** *subtree_dn_list* Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (``:``). This list replaces the existing list. **-sscope** *search_scope* Specifies the scope for searching the principals under the subtrees. The possible values are 1 or one (one level), 2 or sub (subtrees). **-containerref** *container_reference_dn* Specifies the DN of the container object in which the principals of a realm will be created. **-maxtktlife** *max_ticket_life* (:ref:`getdate` string) Specifies maximum ticket life for principals in this realm. **-maxrenewlife** *max_renewable_ticket_life* (:ref:`getdate` string) Specifies maximum renewable life of tickets for principals in this realm. *ticket_flags* Specifies global ticket flags for the realm. Allowable flags are documented in the description of the **add_principal** command in :ref:`kadmin(1)`. Example:: shell% kdb5_ldap_util -r ATHENA.MIT.EDU -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu modify +requires_preauth Password for "cn=admin,o=org": shell% .. _kdb5_ldap_util_modify_end: view ~~~~ .. _kdb5_ldap_util_view: **view** Displays the attributes of a realm. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU view Password for "cn=admin,o=org": Realm Name: ATHENA.MIT.EDU Subtree: ou=users,o=org Subtree: ou=servers,o=org SearchScope: ONE Maximum ticket life: 0 days 01:00:00 Maximum renewable life: 0 days 10:00:00 Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PWCHANGE .. _kdb5_ldap_util_view_end: destroy ~~~~~~~ .. _kdb5_ldap_util_destroy: **destroy** [**-f**] Destroys an existing realm. Options: **-f** If specified, will not prompt the user for confirmation. Example:: shell% kdb5_ldap_util -r ATHENA.MIT.EDU -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu destroy Password for "cn=admin,o=org": Deleting KDC database of 'ATHENA.MIT.EDU', are you sure? (type 'yes' to confirm)? yes OK, deleting database of 'ATHENA.MIT.EDU'... shell% .. _kdb5_ldap_util_destroy_end: list ~~~~ .. _kdb5_ldap_util_list: **list** Lists the names of realms under the container. Example:: shell% kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu list Password for "cn=admin,o=org": ATHENA.MIT.EDU OPENLDAP.MIT.EDU MEDIA-LAB.MIT.EDU shell% .. _kdb5_ldap_util_list_end: stashsrvpw ~~~~~~~~~~ .. _kdb5_ldap_util_stashsrvpw: **stashsrvpw** [**-f** *filename*] *name* Allows an administrator to store the password for service object in a file so that KDC and Administration server can use it to authenticate to the LDAP server. Options: **-f** *filename* Specifies the complete path of the service password file. By default, ``/usr/local/var/service_passwd`` is used. *name* Specifies the name of the object whose password is to be stored. If :ref:`krb5kdc(8)` or :ref:`kadmind(8)` are configured for simple binding, this should be the distinguished name it will use as given by the **ldap_kdc_dn** or **ldap_kadmind_dn** variable in :ref:`kdc.conf(5)`. If the KDC or kadmind is configured for SASL binding, this should be the authentication name it will use as given by the **ldap_kdc_sasl_authcid** or **ldap_kadmind_sasl_authcid** variable. Example:: kdb5_ldap_util stashsrvpw -f /home/andrew/conf_keyfile cn=service-kdc,o=org Password for "cn=service-kdc,o=org": Re-enter password for "cn=service-kdc,o=org": .. _kdb5_ldap_util_stashsrvpw_end: create_policy ~~~~~~~~~~~~~ .. _kdb5_ldap_util_create_policy: **create_policy** [**-maxtktlife** *max_ticket_life*] [**-maxrenewlife** *max_renewable_ticket_life*] [*ticket_flags*] *policy_name* Creates a ticket policy in the directory. Options: **-maxtktlife** *max_ticket_life* (:ref:`getdate` string) Specifies maximum ticket life for principals. **-maxrenewlife** *max_renewable_ticket_life* (:ref:`getdate` string) Specifies maximum renewable life of tickets for principals. *ticket_flags* Specifies the ticket flags. If this option is not specified, by default, no restriction will be set by the policy. Allowable flags are documented in the description of the **add_principal** command in :ref:`kadmin(1)`. *policy_name* Specifies the name of the ticket policy. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU create_policy -maxtktlife "1 day" -maxrenewlife "1 week" -allow_postdated +needchange -allow_forwardable tktpolicy Password for "cn=admin,o=org": .. _kdb5_ldap_util_create_policy_end: modify_policy ~~~~~~~~~~~~~ .. _kdb5_ldap_util_modify_policy: **modify_policy** [**-maxtktlife** *max_ticket_life*] [**-maxrenewlife** *max_renewable_ticket_life*] [*ticket_flags*] *policy_name* Modifies the attributes of a ticket policy. Options are same as for **create_policy**. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU modify_policy -maxtktlife "60 minutes" -maxrenewlife "10 hours" +allow_postdated -requires_preauth tktpolicy Password for "cn=admin,o=org": .. _kdb5_ldap_util_modify_policy_end: view_policy ~~~~~~~~~~~ .. _kdb5_ldap_util_view_policy: **view_policy** *policy_name* Displays the attributes of the named ticket policy. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU view_policy tktpolicy Password for "cn=admin,o=org": Ticket policy: tktpolicy Maximum ticket life: 0 days 01:00:00 Maximum renewable life: 0 days 10:00:00 Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PWCHANGE .. _kdb5_ldap_util_view_policy_end: destroy_policy ~~~~~~~~~~~~~~ .. _kdb5_ldap_util_destroy_policy: **destroy_policy** [**-force**] *policy_name* Destroys an existing ticket policy. Options: **-force** Forces the deletion of the policy object. If not specified, the user will be prompted for confirmation before deleting the policy. *policy_name* Specifies the name of the ticket policy. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU destroy_policy tktpolicy Password for "cn=admin,o=org": This will delete the policy object 'tktpolicy', are you sure? (type 'yes' to confirm)? yes ** policy object 'tktpolicy' deleted. .. _kdb5_ldap_util_destroy_policy_end: list_policy ~~~~~~~~~~~ .. _kdb5_ldap_util_list_policy: **list_policy** Lists ticket policies. Example:: kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU list_policy Password for "cn=admin,o=org": tktpolicy tmppolicy userpolicy .. _kdb5_ldap_util_list_policy_end: ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/admin/admin_commands/k5srvutil.rst.txt0000664000175000017500000000401215051422642025254 0ustar ghudsonghudson.. _k5srvutil(1): k5srvutil ========= SYNOPSIS -------- **k5srvutil** *operation* [**-i**] [**-f** *filename*] [**-e** *keysalts*] DESCRIPTION ----------- k5srvutil allows an administrator to list keys currently in a keytab, to obtain new keys for a principal currently in a keytab, or to delete non-current keys from a keytab. *operation* must be one of the following: **list** Lists the keys in a keytab, showing version number and principal name. **change** Uses the kadmin protocol to update the keys in the Kerberos database to new randomly-generated keys, and updates the keys in the keytab to match. If a key's version number doesn't match the version number stored in the Kerberos server's database, then the operation will fail. If the **-i** flag is given, k5srvutil will prompt for confirmation before changing each key. If the **-k** option is given, the old and new keys will be displayed. Ordinarily, keys will be generated with the default encryption types and key salts. This can be overridden with the **-e** option. Old keys are retained in the keytab so that existing tickets continue to work, but **delold** should be used after such tickets expire, to prevent attacks against the old keys. **delold** Deletes keys that are not the most recent version from the keytab. This operation should be used some time after a change operation to remove old keys, after existing tickets issued for the service have expired. If the **-i** flag is given, then k5srvutil will prompt for confirmation for each principal. **delete** Deletes particular keys in the keytab, interactively prompting for each key. In all cases, the default keytab is used unless this is overridden by the **-f** option. k5srvutil uses the :ref:`kadmin(1)` program to edit the keytab in place. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`ktutil(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/admin/admin_commands/kdb5_util.rst.txt0000664000175000017500000003550215051422642025176 0ustar ghudsonghudson.. _kdb5_util(8): kdb5_util ========= SYNOPSIS -------- .. _kdb5_util_synopsis: **kdb5_util** [**-r** *realm*] [**-d** *dbname*] [**-k** *mkeytype*] [**-kv** *mkeyVNO*] [**-M** *mkeyname*] [**-m**] [**-sf** *stashfilename*] [**-P** *password*] [**-x** *db_args*] *command* [*command_options*] .. _kdb5_util_synopsis_end: DESCRIPTION ----------- kdb5_util allows an administrator to perform maintenance procedures on the KDC database. Databases can be created, destroyed, and dumped to or loaded from ASCII files. kdb5_util can create a Kerberos master key stash file or perform live rollover of the master key. When kdb5_util is run, it attempts to acquire the master key and open the database. However, execution continues regardless of whether or not kdb5_util successfully opens the database, because the database may not exist yet or the stash file may be corrupt. Note that some KDC database modules may not support all kdb5_util commands. COMMAND-LINE OPTIONS -------------------- .. _kdb5_util_options: **-r** *realm* specifies the Kerberos realm of the database. **-d** *dbname* specifies the name under which the principal database is stored; by default the database is that listed in :ref:`kdc.conf(5)`. The password policy database and lock files are also derived from this value. **-k** *mkeytype* specifies the key type of the master key in the database. The default is given by the **master_key_type** variable in :ref:`kdc.conf(5)`. **-kv** *mkeyVNO* Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed. **-M** *mkeyname* principal name for the master key in the database. If not specified, the name is determined by the **master_key_name** variable in :ref:`kdc.conf(5)`. **-m** specifies that the master database password should be read from the keyboard rather than fetched from a file on disk. **-sf** *stash_file* specifies the stash filename of the master database password. If not specified, the filename is determined by the **key_stash_file** variable in :ref:`kdc.conf(5)`. **-P** *password* specifies the master database password. Using this option may expose the password to other users on the system via the process list. **-x** *db_args* specifies database-specific options. See :ref:`kadmin(1)` for supported options. .. _kdb5_util_options_end: COMMANDS -------- create ~~~~~~ .. _kdb5_util_create: **create** [**-s**] Creates a new database. If the **-s** option is specified, the stash file is also created. This command fails if the database already exists. If the command is successful, the database is opened just as if it had already existed when the program was first run. .. _kdb5_util_create_end: destroy ~~~~~~~ .. _kdb5_util_destroy: **destroy** [**-f**] Destroys the database, first overwriting the disk sectors and then unlinking the files, after prompting the user for confirmation. With the **-f** argument, does not prompt the user. .. _kdb5_util_destroy_end: stash ~~~~~ .. _kdb5_util_stash: **stash** [**-f** *keyfile*] Stores the master principal's keys in a stash file. The **-f** argument can be used to override the *keyfile* specified in :ref:`kdc.conf(5)`. .. _kdb5_util_stash_end: dump ~~~~ .. _kdb5_util_dump: **dump** [**-b7**\|\ **-r13**\|\ **-r18**] [**-verbose**] [**-mkey_convert**] [**-new_mkey_file** *mkey_file*] [**-rev**] [**-recurse**] [*filename* [*principals*...]] Dumps the current Kerberos and KADM5 database into an ASCII file. By default, the database is dumped in current format, "kdb5_util load_dump version 7". If filename is not specified, or is the string "-", the dump is sent to standard output. Options: **-b7** causes the dump to be in the Kerberos 5 Beta 7 format ("kdb5_util load_dump version 4"). This was the dump format produced on releases prior to 1.2.2. **-r13** causes the dump to be in the Kerberos 5 1.3 format ("kdb5_util load_dump version 5"). This was the dump format produced on releases prior to 1.8. **-r18** causes the dump to be in the Kerberos 5 1.8 format ("kdb5_util load_dump version 6"). This was the dump format produced on releases prior to 1.11. **-verbose** causes the name of each principal and policy to be printed as it is dumped. **-mkey_convert** prompts for a new master key. This new master key will be used to re-encrypt principal key data in the dumpfile. The principal keys themselves will not be changed. **-new_mkey_file** *mkey_file* the filename of a stash file. The master key in this stash file will be used to re-encrypt the key data in the dumpfile. The key data in the database will not be changed. **-rev** dumps in reverse order. This may recover principals that do not dump normally, in cases where database corruption has occurred. **-recurse** causes the dump to walk the database recursively (btree only). This may recover principals that do not dump normally, in cases where database corruption has occurred. In cases of such corruption, this option will probably retrieve more principals than the **-rev** option will. .. versionchanged:: 1.15 Release 1.15 restored the functionality of the **-recurse** option. .. versionchanged:: 1.5 The **-recurse** option ceased working until release 1.15, doing a normal dump instead of a recursive traversal. .. _kdb5_util_dump_end: load ~~~~ .. _kdb5_util_load: **load** [**-b7**\|\ **-r13**\|\ **-r18**] [**-hash**] [**-verbose**] [**-update**] *filename* Loads a database dump from the named file into the named database. If no option is given to determine the format of the dump file, the format is detected automatically and handled as appropriate. Unless the **-update** option is given, **load** creates a new database containing only the data in the dump file, overwriting the contents of any previously existing database. Note that when using the LDAP KDC database module, the **-update** flag is required. Options: **-b7** requires the database to be in the Kerberos 5 Beta 7 format ("kdb5_util load_dump version 4"). This was the dump format produced on releases prior to 1.2.2. **-r13** requires the database to be in Kerberos 5 1.3 format ("kdb5_util load_dump version 5"). This was the dump format produced on releases prior to 1.8. **-r18** requires the database to be in Kerberos 5 1.8 format ("kdb5_util load_dump version 6"). This was the dump format produced on releases prior to 1.11. **-hash** stores the database in hash format, if using the DB2 database type. If this option is not specified, the database will be stored in btree format. This option is not recommended, as databases stored in hash format are known to corrupt data and lose principals. **-verbose** causes the name of each principal and policy to be printed as it is dumped. **-update** records from the dump file are added to or updated in the existing database. Otherwise, a new database is created containing only what is in the dump file and the old one destroyed upon successful completion. .. _kdb5_util_load_end: ark ~~~ **ark** [**-e** *enc*:*salt*,...] *principal* Adds new random keys to *principal* at the next available key version number. Keys for the current highest key version number will be preserved. The **-e** option specifies the list of encryption and salt types to be used for the new keys. add_mkey ~~~~~~~~ **add_mkey** [**-e** *etype*] [**-s**] Adds a new master key to the master key principal, but does not mark it as active. Existing master keys will remain. The **-e** option specifies the encryption type of the new master key; see :ref:`Encryption_types` in :ref:`kdc.conf(5)` for a list of possible values. The **-s** option stashes the new master key in the stash file, which will be created if it doesn't already exist. After a new master key is added, it should be propagated to replica servers via a manual or periodic invocation of :ref:`kprop(8)`. Then, the stash files on the replica servers should be updated with the kdb5_util **stash** command. Once those steps are complete, the key is ready to be marked active with the kdb5_util **use_mkey** command. use_mkey ~~~~~~~~ **use_mkey** *mkeyVNO* [*time*] Sets the activation time of the master key specified by *mkeyVNO*. Once a master key becomes active, it will be used to encrypt newly created principal keys. If no *time* argument is given, the current time is used, causing the specified master key version to become active immediately. The format for *time* is :ref:`getdate` string. After a new master key becomes active, the kdb5_util **update_princ_encryption** command can be used to update all principal keys to be encrypted in the new master key. list_mkeys ~~~~~~~~~~ **list_mkeys** List all master keys, from most recent to earliest, in the master key principal. The output will show the kvno, enctype, and salt type for each mkey, similar to the output of :ref:`kadmin(1)` **getprinc**. A ``*`` following an mkey denotes the currently active master key. purge_mkeys ~~~~~~~~~~~ **purge_mkeys** [**-f**] [**-n**] [**-v**] Delete master keys from the master key principal that are not used to protect any principals. This command can be used to remove old master keys all principal keys are protected by a newer master key. **-f** does not prompt for confirmation. **-n** performs a dry run, showing master keys that would be purged, but not actually purging any keys. **-v** gives more verbose output. update_princ_encryption ~~~~~~~~~~~~~~~~~~~~~~~ **update_princ_encryption** [**-f**] [**-n**] [**-v**] [*princ-pattern*] Update all principal records (or only those matching the *princ-pattern* glob pattern) to re-encrypt the key data using the active database master key, if they are encrypted using a different version, and give a count at the end of the number of principals updated. If the **-f** option is not given, ask for confirmation before starting to make changes. The **-v** option causes each principal processed to be listed, with an indication as to whether it needed updating or not. The **-n** option performs a dry run, only showing the actions which would have been taken. tabdump ~~~~~~~ **tabdump** [**-H**] [**-c**] [**-e**] [**-n**] [**-o** *outfile*] *dumptype* Dump selected fields of the database in a tabular format suitable for reporting (e.g., using traditional Unix text processing tools) or importing into relational databases. The data format is tab-separated (default), or optionally comma-separated (CSV), with a fixed number of columns. The output begins with a header line containing field names, unless suppression is requested using the **-H** option. The *dumptype* parameter specifies the name of an output table (see below). Options: **-H** suppress writing the field names in a header line **-c** use comma separated values (CSV) format, with minimal quoting, instead of the default tab-separated (unquoted, unescaped) format **-e** write empty hexadecimal string fields as empty fields instead of as "-1". **-n** produce numeric output for fields that normally have symbolic output, such as enctypes and flag names. Also requests output of time stamps as decimal POSIX time_t values. **-o** *outfile* write the dump to the specified output file instead of to standard output Dump types: **alias** principal alias information **aliasname** the name of the alias **targetname** the target of the alias **keydata** principal encryption key information, including actual key data (which is still encrypted in the master key) **name** principal name **keyindex** index of this key in the principal's key list **kvno** key version number **enctype** encryption type **key** key data as a hexadecimal string **salttype** salt type **salt** salt data as a hexadecimal string **keyinfo** principal encryption key information (as in **keydata** above), excluding actual key data **princ_flags** principal boolean attributes. Flag names print as hexadecimal numbers if the **-n** option is specified, and all flag positions are printed regardless of whether or not they are set. If **-n** is not specified, print all known flag names for each principal, but only print hexadecimal flag names if the corresponding flag is set. **name** principal name **flag** flag name **value** boolean value (0 for clear, or 1 for set) **princ_lockout** state information used for tracking repeated password failures **name** principal name **last_success** time stamp of most recent successful authentication **last_failed** time stamp of most recent failed authentication **fail_count** count of failed attempts **princ_meta** principal metadata **name** principal name **modby** name of last principal to modify this principal **modtime** timestamp of last modification **lastpwd** timestamp of last password change **policy** policy object name **mkvno** key version number of the master key that encrypts this principal's key data **hist_kvno** key version number of the history key that encrypts the key history data for this principal **princ_stringattrs** string attributes (key/value pairs) **name** principal name **key** attribute name **value** attribute value **princ_tktpolicy** per-principal ticket policy data, including maximum ticket lifetimes **name** principal name **expiration** principal expiration date **pw_expiration** password expiration date **max_life** maximum ticket lifetime **max_renew_life** maximum renewable ticket lifetime Examples:: $ kdb5_util tabdump -o keyinfo.txt keyinfo $ cat keyinfo.txt name keyindex kvno enctype salttype salt K/M@EXAMPLE.COM 0 1 aes256-cts-hmac-sha384-192 normal -1 foo@EXAMPLE.COM 0 1 aes128-cts-hmac-sha1-96 normal -1 bar@EXAMPLE.COM 0 1 aes128-cts-hmac-sha1-96 normal -1 $ sqlite3 sqlite> .mode tabs sqlite> .import keyinfo.txt keyinfo sqlite> select * from keyinfo where enctype like 'aes256-%'; K/M@EXAMPLE.COM 1 1 aes256-cts-hmac-sha384-192 normal -1 sqlite> .quit $ awk -F'\t' '$4 ~ /aes256-/ { print }' keyinfo.txt K/M@EXAMPLE.COM 1 1 aes256-cts-hmac-sha384-192 normal -1 ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/admin/admin_commands/ktutil.rst.txt0000664000175000017500000000426415051422642024631 0ustar ghudsonghudson.. _ktutil(1): ktutil ====== SYNOPSIS -------- **ktutil** DESCRIPTION ----------- The ktutil command invokes a command interface from which an administrator can read, write, or edit entries in a keytab. (Kerberos V4 srvtab files are no longer supported.) COMMANDS -------- list ~~~~ **list** [**-t**] [**-k**] [**-e**] Displays the current keylist. If **-t**, **-k**, and/or **-e** are specified, also display the timestamp, key contents, or enctype (respectively). Alias: **l** read_kt ~~~~~~~ **read_kt** *keytab* Read the Kerberos V5 keytab file *keytab* into the current keylist. Alias: **rkt** write_kt ~~~~~~~~ **write_kt** *keytab* Write the current keylist into the Kerberos V5 keytab file *keytab*. Alias: **wkt** clear_list ~~~~~~~~~~ **clear_list** Clear the current keylist. Alias: **clear** delete_entry ~~~~~~~~~~~~ **delete_entry** *slot* Delete the entry in slot number *slot* from the current keylist. Alias: **delent** add_entry ~~~~~~~~~ **add_entry** {**-key**\|\ **-password**} **-p** *principal* **-k** *kvno* [**-e** *enctype*] [**-f**\|\ **-s** *salt*] Add *principal* to keylist using key or password. If the **-f** flag is specified, salt information will be fetched from the KDC; in this case the **-e** flag may be omitted, or it may be supplied to force a particular enctype. If the **-f** flag is not specified, the **-e** flag must be specified, and the default salt will be used unless overridden with the **-s** option. Alias: **addent** list_requests ~~~~~~~~~~~~~ **list_requests** Displays a listing of available commands. Aliases: **lr**, **?** quit ~~~~ **quit** Quits ktutil. Aliases: **exit**, **q** EXAMPLE ------- :: ktutil: add_entry -password -p alice@BLEEP.COM -k 1 -e aes128-cts-hmac-sha1-96 Password for alice@BLEEP.COM: ktutil: add_entry -password -p alice@BLEEP.COM -k 1 -e aes256-cts-hmac-sha1-96 Password for alice@BLEEP.COM: ktutil: write_kt alice.keytab ktutil: ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kadmin(1)`, :ref:`kdb5_util(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/admin/admin_commands/kadmin_local.rst.txt0000664000175000017500000007466515051422642025746 0ustar ghudsonghudson.. _kadmin(1): kadmin ====== SYNOPSIS -------- .. _kadmin_synopsis: **kadmin** [**-O**\|\ **-N**] [**-r** *realm*] [**-p** *principal*] [**-q** *query*] [[**-c** *cache_name*]\|[**-k** [**-t** *keytab*]]\|\ **-n**] [**-w** *password*] [**-s** *admin_server*\ [:*port*]] [command args...] **kadmin.local** [**-r** *realm*] [**-p** *principal*] [**-q** *query*] [**-d** *dbname*] [**-e** *enc*:*salt* ...] [**-m**] [**-x** *db_args*] [command args...] DESCRIPTION ----------- kadmin and kadmin.local are command-line interfaces to the Kerberos V5 administration system. They provide nearly identical functionalities; the difference is that kadmin.local directly accesses the KDC database, while kadmin performs operations using :ref:`kadmind(8)`. Except as explicitly noted otherwise, this man page will use "kadmin" to refer to both versions. kadmin provides for the maintenance of Kerberos principals, password policies, and service key tables (keytabs). The remote kadmin client uses Kerberos to authenticate to kadmind using the service principal ``kadmin/admin`` or ``kadmin/ADMINHOST`` (where *ADMINHOST* is the fully-qualified hostname of the admin server). If the credentials cache contains a ticket for one of these principals, and the **-c** credentials_cache option is specified, that ticket is used to authenticate to kadmind. Otherwise, the **-p** and **-k** options are used to specify the client Kerberos principal name used to authenticate. Once kadmin has determined the principal name, it requests a service ticket from the KDC, and uses that service ticket to authenticate to kadmind. Since kadmin.local directly accesses the KDC database, it usually must be run directly on the primary KDC with sufficient permissions to read the KDC database. If the KDC database uses the LDAP database module, kadmin.local can be run on any host which can access the LDAP server. OPTIONS ------- .. _kadmin_options: **-r** *realm* Use *realm* as the default database realm. **-p** *principal* Use *principal* to authenticate. Otherwise, kadmin will append ``/admin`` to the primary principal name of the default ccache, the value of the **USER** environment variable, or the username as obtained with getpwuid, in order of preference. **-k** Use a keytab to decrypt the KDC response instead of prompting for a password. In this case, the default principal will be ``host/hostname``. If there is no keytab specified with the **-t** option, then the default keytab will be used. **-t** *keytab* Use *keytab* to decrypt the KDC response. This can only be used with the **-k** option. **-n** Requests anonymous processing. Two types of anonymous principals are supported. For fully anonymous Kerberos, configure PKINIT on the KDC and configure **pkinit_anchors** in the client's :ref:`krb5.conf(5)`. Then use the **-n** option with a principal of the form ``@REALM`` (an empty principal name followed by the at-sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. A second form of anonymous tickets is supported; these realm-exposed tickets hide the identity of the client but not the client's realm. For this mode, use ``kinit -n`` with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation. **-c** *credentials_cache* Use *credentials_cache* as the credentials cache. The cache should contain a service ticket for the ``kadmin/admin`` or ``kadmin/ADMINHOST`` (where *ADMINHOST* is the fully-qualified hostname of the admin server) service; it can be acquired with the :ref:`kinit(1)` program. If this option is not specified, kadmin requests a new service ticket from the KDC, and stores it in its own temporary ccache. **-w** *password* Use *password* instead of prompting for one. Use this option with care, as it may expose the password to other users on the system via the process list. **-q** *query* Perform the specified query and then exit. **-d** *dbname* Specifies the name of the KDC database. This option does not apply to the LDAP database module. **-s** *admin_server*\ [:*port*] Specifies the admin server which kadmin should contact. **-m** If using kadmin.local, prompt for the database master password instead of reading it from a stash file. **-e** "*enc*:*salt* ..." Sets the keysalt list to be used for any new keys created. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of possible values. **-O** Force use of old AUTH_GSSAPI authentication flavor. **-N** Prevent fallback to AUTH_GSSAPI authentication flavor. **-x** *db_args* Specifies the database specific arguments. See the next section for supported options. Starting with release 1.14, if any command-line arguments remain after the options, they will be treated as a single query to be executed. This mode of operation is intended for scripts and behaves differently from the interactive mode in several respects: * Query arguments are split by the shell, not by kadmin. * Informational and warning messages are suppressed. Error messages and query output (e.g. for **get_principal**) will still be displayed. * Confirmation prompts are disabled (as if **-force** was given). Password prompts will still be issued as required. * The exit status will be non-zero if the query fails. The **-q** option does not carry these behavior differences; the query will be processed as if it was entered interactively. The **-q** option cannot be used in combination with a query in the remaining arguments. .. _dboptions: DATABASE OPTIONS ---------------- Database options can be used to override database-specific defaults. Supported options for the DB2 module are: **-x dbname=**\ \*filename* Specifies the base filename of the DB2 database. **-x lockiter** Make iteration operations hold the lock for the duration of the entire operation, rather than temporarily releasing the lock while handling each principal. This is the default behavior, but this option exists to allow command line override of a [dbmodules] setting. First introduced in release 1.13. **-x unlockiter** Make iteration operations unlock the database for each principal, instead of holding the lock for the duration of the entire operation. First introduced in release 1.13. Supported options for the LDAP module are: **-x host=**\ *ldapuri* Specifies the LDAP server to connect to by a LDAP URI. **-x binddn=**\ *bind_dn* Specifies the DN used to bind to the LDAP server. **-x bindpwd=**\ *password* Specifies the password or SASL secret used to bind to the LDAP server. Using this option may expose the password to other users on the system via the process list; to avoid this, instead stash the password using the **stashsrvpw** command of :ref:`kdb5_ldap_util(8)`. **-x sasl_mech=**\ *mechanism* Specifies the SASL mechanism used to bind to the LDAP server. The bind DN is ignored if a SASL mechanism is used. New in release 1.13. **-x sasl_authcid=**\ *name* Specifies the authentication name used when binding to the LDAP server with a SASL mechanism, if the mechanism requires one. New in release 1.13. **-x sasl_authzid=**\ *name* Specifies the authorization name used when binding to the LDAP server with a SASL mechanism. New in release 1.13. **-x sasl_realm=**\ *realm* Specifies the realm used when binding to the LDAP server with a SASL mechanism, if the mechanism uses one. New in release 1.13. **-x debug=**\ *level* sets the OpenLDAP client library debug level. *level* is an integer to be interpreted by the library. Debugging messages are printed to standard error. New in release 1.12. COMMANDS -------- When using the remote client, available commands may be restricted according to the privileges specified in the :ref:`kadm5.acl(5)` file on the admin server. .. _add_principal: add_principal ~~~~~~~~~~~~~ **add_principal** [*options*] *newprinc* Creates the principal *newprinc*, prompting twice for a password. If no password policy is specified with the **-policy** option, and the policy named ``default`` is assigned to the principal if it exists. However, creating a policy named ``default`` will not automatically assign this policy to previously existing principals. This policy assignment can be suppressed with the **-clearpolicy** option. This command requires the **add** privilege. Aliases: **addprinc**, **ank** Options: **-expire** *expdate* (:ref:`getdate` string) The expiration date of the principal. **-pwexpire** *pwexpdate* (:ref:`getdate` string) The password expiration date. **-maxlife** *maxlife* (:ref:`duration` or :ref:`getdate` string) The maximum ticket life for the principal. **-maxrenewlife** *maxrenewlife* (:ref:`duration` or :ref:`getdate` string) The maximum renewable life of tickets for the principal. **-kvno** *kvno* The initial key version number. **-policy** *policy* The password policy used by this principal. If not specified, the policy ``default`` is used if it exists (unless **-clearpolicy** is specified). **-clearpolicy** Prevents any policy from being assigned when **-policy** is not specified. {-\|+}\ **allow_postdated** **-allow_postdated** prohibits this principal from obtaining postdated tickets. **+allow_postdated** clears this flag. {-\|+}\ **allow_forwardable** **-allow_forwardable** prohibits this principal from obtaining forwardable tickets. **+allow_forwardable** clears this flag. {-\|+}\ **allow_renewable** **-allow_renewable** prohibits this principal from obtaining renewable tickets. **+allow_renewable** clears this flag. {-\|+}\ **allow_proxiable** **-allow_proxiable** prohibits this principal from obtaining proxiable tickets. **+allow_proxiable** clears this flag. {-\|+}\ **allow_dup_skey** **-allow_dup_skey** disables user-to-user authentication for this principal by prohibiting others from obtaining a service ticket encrypted in this principal's TGT session key. **+allow_dup_skey** clears this flag. {-\|+}\ **requires_preauth** **+requires_preauth** requires this principal to preauthenticate before being allowed to kinit. **-requires_preauth** clears this flag. When **+requires_preauth** is set on a service principal, the KDC will only issue service tickets for that service principal if the client's initial authentication was performed using preauthentication. {-\|+}\ **requires_hwauth** **+requires_hwauth** requires this principal to preauthenticate using a hardware device before being allowed to kinit. **-requires_hwauth** clears this flag. When **+requires_hwauth** is set on a service principal, the KDC will only issue service tickets for that service principal if the client's initial authentication was performed using a hardware device to preauthenticate. {-\|+}\ **ok_as_delegate** **+ok_as_delegate** sets the **okay as delegate** flag on tickets issued with this principal as the service. Clients may use this flag as a hint that credentials should be delegated when authenticating to the service. **-ok_as_delegate** clears this flag. {-\|+}\ **allow_svr** **-allow_svr** prohibits the issuance of service tickets for this principal. In release 1.17 and later, user-to-user service tickets are still allowed unless the **-allow_dup_skey** flag is also set. **+allow_svr** clears this flag. {-\|+}\ **allow_tgs_req** **-allow_tgs_req** specifies that a Ticket-Granting Service (TGS) request for a service ticket for this principal is not permitted. **+allow_tgs_req** clears this flag. {-\|+}\ **allow_tix** **-allow_tix** forbids the issuance of any tickets for this principal. **+allow_tix** clears this flag. {-\|+}\ **needchange** **+needchange** forces a password change on the next initial authentication to this principal. **-needchange** clears this flag. {-\|+}\ **password_changing_service** **+password_changing_service** marks this principal as a password change service principal. {-\|+}\ **ok_to_auth_as_delegate** **+ok_to_auth_as_delegate** allows this principal to acquire forwardable tickets to itself from arbitrary users, for use with constrained delegation. {-\|+}\ **no_auth_data_required** **+no_auth_data_required** prevents PAC or AD-SIGNEDPATH data from being added to service tickets for the principal. {-\|+}\ **lockdown_keys** **+lockdown_keys** prevents keys for this principal from leaving the KDC via kadmind. The chpass and extract operations are denied for a principal with this attribute. The chrand operation is allowed, but will not return the new keys. The delete and rename operations are also denied if this attribute is set, in order to prevent a malicious administrator from replacing principals like krbtgt/* or kadmin/* with new principals without the attribute. This attribute can be set via the network protocol, but can only be removed using kadmin.local. **-randkey** Sets the key of the principal to a random value. **-nokey** Causes the principal to be created with no key. New in release 1.12. **-pw** *password* Sets the password of the principal to the specified string and does not prompt for a password. Note: using this option in a shell script may expose the password to other users on the system via the process list. **-e** *enc*:*salt*,... Uses the specified keysalt list for setting the keys of the principal. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of possible values. **-x** *db_princ_args* Indicates database-specific options. The options for the LDAP database module are: **-x dn=**\ *dn* Specifies the LDAP object that will contain the Kerberos principal being created. **-x linkdn=**\ *dn* Specifies the LDAP object to which the newly created Kerberos principal object will point. **-x containerdn=**\ *container_dn* Specifies the container object under which the Kerberos principal is to be created. **-x tktpolicy=**\ *policy* Associates a ticket policy to the Kerberos principal. .. note:: - The **containerdn** and **linkdn** options cannot be specified with the **dn** option. - If the *dn* or *containerdn* options are not specified while adding the principal, the principals are created under the principal container configured in the realm or the realm container. - *dn* and *containerdn* should be within the subtrees or principal container configured in the realm. Example:: kadmin: addprinc jennifer No policy specified for "jennifer@ATHENA.MIT.EDU"; defaulting to no policy. Enter password for principal jennifer@ATHENA.MIT.EDU: Re-enter password for principal jennifer@ATHENA.MIT.EDU: Principal "jennifer@ATHENA.MIT.EDU" created. kadmin: .. _modify_principal: modify_principal ~~~~~~~~~~~~~~~~ **modify_principal** [*options*] *principal* Modifies the specified principal, changing the fields as specified. The options to **add_principal** also apply to this command, except for the **-randkey**, **-pw**, and **-e** options. In addition, the option **-clearpolicy** will clear the current policy of a principal. This command requires the *modify* privilege. Alias: **modprinc** Options (in addition to the **addprinc** options): **-unlock** Unlocks a locked principal (one which has received too many failed authentication attempts without enough time between them according to its password policy) so that it can successfully authenticate. .. _rename_principal: rename_principal ~~~~~~~~~~~~~~~~ **rename_principal** [**-force**] *old_principal* *new_principal* Renames the specified *old_principal* to *new_principal*. This command prompts for confirmation, unless the **-force** option is given. This command requires the **add** and **delete** privileges. Alias: **renprinc** .. _add_alias: add_alias ~~~~~~~~~ **add_alias** *alias_princ* *target_princ* Create an alias *alias_princ* pointing to *target_princ*. Aliases may be chained (that is, *target_princ* may itself be an alias) up to a depth of 10. This command requires the **add** privilege for *alias_princ* and the **modify** privilege for *target_princ*. (New in release 1.22.) Aliases: **alias** .. _delete_principal: delete_principal ~~~~~~~~~~~~~~~~ **delete_principal** [**-force**] *principal* Deletes the specified *principal* or alias from the database. This command prompts for deletion, unless the **-force** option is given. This command requires the **delete** privilege. Alias: **delprinc** .. _change_password: change_password ~~~~~~~~~~~~~~~ **change_password** [*options*] *principal* Changes the password of *principal*. Prompts for a new password if neither **-randkey** or **-pw** is specified. This command requires the **changepw** privilege, or that the principal running the program is the same as the principal being changed. Alias: **cpw** The following options are available: **-randkey** Sets the key of the principal to a random value. **-pw** *password* Set the password to the specified string. Using this option in a script may expose the password to other users on the system via the process list. **-e** *enc*:*salt*,... Uses the specified keysalt list for setting the keys of the principal. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of possible values. **-keepold** Keeps the existing keys in the database. This flag is usually not necessary except perhaps for ``krbtgt`` principals. Example:: kadmin: cpw systest Enter password for principal systest@BLEEP.COM: Re-enter password for principal systest@BLEEP.COM: Password for systest@BLEEP.COM changed. kadmin: .. _purgekeys: purgekeys ~~~~~~~~~ **purgekeys** [**-all**\|\ **-keepkvno** *oldest_kvno_to_keep*] *principal* Purges previously retained old keys (e.g., from **change_password -keepold**) from *principal*. If **-keepkvno** is specified, then only purges keys with kvnos lower than *oldest_kvno_to_keep*. If **-all** is specified, then all keys are purged. The **-all** option is new in release 1.12. This command requires the **modify** privilege. .. _get_principal: get_principal ~~~~~~~~~~~~~ **get_principal** [**-terse**] *principal* Gets the attributes of principal. With the **-terse** option, outputs fields as quoted tab-separated strings. This command requires the **inquire** privilege, or that the principal running the the program to be the same as the one being listed. Alias: **getprinc** Examples:: kadmin: getprinc tlyu/admin Principal: tlyu/admin@BLEEP.COM Expiration date: [never] Last password change: Mon Aug 12 14:16:47 EDT 1996 Password expiration date: [never] Maximum ticket life: 0 days 10:00:00 Maximum renewable life: 7 days 00:00:00 Last modified: Mon Aug 12 14:16:47 EDT 1996 (bjaspan/admin@BLEEP.COM) Last successful authentication: [never] Last failed authentication: [never] Failed password attempts: 0 Number of keys: 1 Key: vno 1, aes256-cts-hmac-sha384-192 MKey: vno 1 Attributes: Policy: [none] kadmin: getprinc -terse systest systest@BLEEP.COM 3 86400 604800 1 785926535 753241234 785900000 tlyu/admin@BLEEP.COM 786100034 0 0 kadmin: .. _list_principals: list_principals ~~~~~~~~~~~~~~~ **list_principals** [*expression*] Retrieves all or some principal names. *expression* is a shell-style glob expression that can contain the wild-card characters ``?``, ``*``, and ``[]``. All principal names matching the expression are printed. If no expression is provided, all principal names are printed. If the expression does not contain an ``@`` character, an ``@`` character followed by the local realm is appended to the expression. This command requires the **list** privilege. Alias: **listprincs**, **get_principals**, **getprincs** Example:: kadmin: listprincs test* test3@SECURE-TEST.OV.COM test2@SECURE-TEST.OV.COM test1@SECURE-TEST.OV.COM testuser@SECURE-TEST.OV.COM kadmin: .. _get_strings: get_strings ~~~~~~~~~~~ **get_strings** *principal* Displays string attributes on *principal*. This command requires the **inquire** privilege. Alias: **getstrs** .. _set_string: set_string ~~~~~~~~~~ **set_string** *principal* *name* *value* Sets a string attribute on *principal*. String attributes are used to supply per-principal configuration to the KDC and some KDC plugin modules. The following string attribute names are recognized by the KDC: **require_auth** Specifies an authentication indicator which is required to authenticate to the principal as a service. Multiple indicators can be specified, separated by spaces; in this case any of the specified indicators will be accepted. (New in release 1.14.) **session_enctypes** Specifies the encryption types supported for session keys when the principal is authenticated to as a server. See :ref:`Encryption_types` in :ref:`kdc.conf(5)` for a list of the accepted values. **otp** Enables One Time Passwords (OTP) preauthentication for a client *principal*. The *value* is a JSON string representing an array of objects, each having optional ``type`` and ``username`` fields. **pkinit_cert_match** Specifies a matching expression that defines the certificate attributes required for the client certificate used by the principal during PKINIT authentication. The matching expression is in the same format as those used by the **pkinit_cert_match** option in :ref:`krb5.conf(5)`. (New in release 1.16.) **pac_privsvr_enctype** Forces the encryption type of the PAC KDC checksum buffers to the specified encryption type for tickets issued to this server, by deriving a key from the local krbtgt key if it is of a different encryption type. It may be necessary to set this value to "aes256-sha1" on the cross-realm krbtgt entry for an Active Directory realm when using aes-sha2 keys on the local krbtgt entry. This command requires the **modify** privilege. Alias: **setstr** Example:: set_string host/foo.mit.edu session_enctypes aes128-cts set_string user@FOO.COM otp "[{""type"":""hotp"",""username"":""al""}]" .. _del_string: del_string ~~~~~~~~~~ **del_string** *principal* *key* Deletes a string attribute from *principal*. This command requires the **delete** privilege. Alias: **delstr** .. _add_policy: add_policy ~~~~~~~~~~ **add_policy** [*options*] *policy* Adds a password policy named *policy* to the database. This command requires the **add** privilege. Alias: **addpol** The following options are available: **-maxlife** *time* (:ref:`duration` or :ref:`getdate` string) Sets the maximum lifetime of a password. **-minlife** *time* (:ref:`duration` or :ref:`getdate` string) Sets the minimum lifetime of a password. **-minlength** *length* Sets the minimum length of a password. **-minclasses** *number* Sets the minimum number of character classes required in a password. The five character classes are lower case, upper case, numbers, punctuation, and whitespace/unprintable characters. **-history** *number* Sets the number of past keys kept for a principal. This option is not supported with the LDAP KDC database module. .. _policy_maxfailure: **-maxfailure** *maxnumber* Sets the number of authentication failures before the principal is locked. Authentication failures are only tracked for principals which require preauthentication. The counter of failed attempts resets to 0 after a successful attempt to authenticate. A *maxnumber* value of 0 (the default) disables lockout. .. _policy_failurecountinterval: **-failurecountinterval** *failuretime* (:ref:`duration` or :ref:`getdate` string) Sets the allowable time between authentication failures. If an authentication failure happens after *failuretime* has elapsed since the previous failure, the number of authentication failures is reset to 1. A *failuretime* value of 0 (the default) means forever. .. _policy_lockoutduration: **-lockoutduration** *lockouttime* (:ref:`duration` or :ref:`getdate` string) Sets the duration for which the principal is locked from authenticating if too many authentication failures occur without the specified failure count interval elapsing. A duration of 0 (the default) means the principal remains locked out until it is administratively unlocked with ``modprinc -unlock``. **-allowedkeysalts** Specifies the key/salt tuples supported for long-term keys when setting or changing a principal's password/keys. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of the accepted values, but note that key/salt tuples must be separated with commas (',') only. To clear the allowed key/salt policy use a value of '-'. Example:: kadmin: add_policy -maxlife "2 days" -minlength 5 guests kadmin: .. _modify_policy: modify_policy ~~~~~~~~~~~~~ **modify_policy** [*options*] *policy* Modifies the password policy named *policy*. Options are as described for **add_policy**. This command requires the **modify** privilege. Alias: **modpol** .. _delete_policy: delete_policy ~~~~~~~~~~~~~ **delete_policy** [**-force**] *policy* Deletes the password policy named *policy*. Prompts for confirmation before deletion. The command will fail if the policy is in use by any principals. This command requires the **delete** privilege. Alias: **delpol** Example:: kadmin: del_policy guests Are you sure you want to delete the policy "guests"? (yes/no): yes kadmin: .. _get_policy: get_policy ~~~~~~~~~~ **get_policy** [ **-terse** ] *policy* Displays the values of the password policy named *policy*. With the **-terse** flag, outputs the fields as quoted strings separated by tabs. This command requires the **inquire** privilege. Alias: **getpol** Examples:: kadmin: get_policy admin Policy: admin Maximum password life: 180 days 00:00:00 Minimum password life: 00:00:00 Minimum password length: 6 Minimum number of password character classes: 2 Number of old keys kept: 5 Reference count: 17 kadmin: get_policy -terse admin admin 15552000 0 6 2 5 17 kadmin: The "Reference count" is the number of principals using that policy. With the LDAP KDC database module, the reference count field is not meaningful. .. _list_policies: list_policies ~~~~~~~~~~~~~ **list_policies** [*expression*] Retrieves all or some policy names. *expression* is a shell-style glob expression that can contain the wild-card characters ``?``, ``*``, and ``[]``. All policy names matching the expression are printed. If no expression is provided, all existing policy names are printed. This command requires the **list** privilege. Aliases: **listpols**, **get_policies**, **getpols**. Examples:: kadmin: listpols test-pol dict-only once-a-min test-pol-nopw kadmin: listpols t* test-pol test-pol-nopw kadmin: .. _ktadd: ktadd ~~~~~ | **ktadd** [options] *principal* | **ktadd** [options] **-glob** *princ-exp* Adds a *principal*, or all principals matching *princ-exp*, to a keytab file. Each principal's keys are randomized in the process. The rules for *princ-exp* are described in the **list_principals** command. This command requires the **inquire** and **changepw** privileges. With the **-glob** form, it also requires the **list** privilege. The options are: **-k[eytab]** *keytab* Use *keytab* as the keytab file. Otherwise, the default keytab is used. **-e** *enc*:*salt*,... Uses the specified keysalt list for setting the new keys of the principal. See :ref:`Keysalt_lists` in :ref:`kdc.conf(5)` for a list of possible values. **-q** Display less verbose information. **-norandkey** Do not randomize the keys. The keys and their version numbers stay unchanged. This option cannot be specified in combination with the **-e** option. An entry for each of the principal's unique encryption types is added, ignoring multiple keys with the same encryption type but different salt types. Alias: **xst** Example:: kadmin: ktadd -k /tmp/foo-new-keytab host/foo.mit.edu Entry for principal host/foo.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/tmp/foo-new-keytab kadmin: .. _ktremove: ktremove ~~~~~~~~ **ktremove** [options] *principal* [*kvno* | *all* | *old*] Removes entries for the specified *principal* from a keytab. Requires no permissions, since this does not require database access. If the string "all" is specified, all entries for that principal are removed; if the string "old" is specified, all entries for that principal except those with the highest kvno are removed. Otherwise, the value specified is parsed as an integer, and all entries whose kvno match that integer are removed. The options are: **-k[eytab]** *keytab* Use *keytab* as the keytab file. Otherwise, the default keytab is used. **-q** Display less verbose information. Alias: **ktrem** Example:: kadmin: ktremove kadmin/admin all Entry for principal kadmin/admin with kvno 3 removed from keytab FILE:/etc/krb5.keytab kadmin: lock ~~~~ Lock database exclusively. Use with extreme caution! This command only works with the DB2 KDC database module. unlock ~~~~~~ Release the exclusive database lock. list_requests ~~~~~~~~~~~~~ Lists available for kadmin requests. Aliases: **lr**, **?** quit ~~~~ Exit program. If the database was locked, the lock is released. Aliases: **exit**, **q** HISTORY ------- The kadmin program was originally written by Tom Yu at MIT, as an interface to the OpenVision Kerberos administration program. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kpasswd(1)`, :ref:`kadmind(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/admin/admin_commands/kprop.rst.txt0000664000175000017500000000207515051422642024446 0ustar ghudsonghudson.. _kprop(8): kprop ===== SYNOPSIS -------- **kprop** [**-r** *realm*] [**-f** *file*] [**-d**] [**-P** *port*] [**-s** *keytab*] *replica_host* DESCRIPTION ----------- kprop is used to securely propagate a Kerberos V5 database dump file from the primary Kerberos server to a replica Kerberos server, which is specified by *replica_host*. The dump file must be created by :ref:`kdb5_util(8)`. OPTIONS ------- **-r** *realm* Specifies the realm of the primary server. **-f** *file* Specifies the filename where the dumped principal database file is to be found; by default the dumped database file is normally |kdcdir|\ ``/replica_datatrans``. **-P** *port* Specifies the port to use to contact the :ref:`kpropd(8)` server on the remote host. **-d** Prints debugging information. **-s** *keytab* Specifies the location of the keytab file. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. SEE ALSO -------- :ref:`kpropd(8)`, :ref:`kdb5_util(8)`, :ref:`krb5kdc(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/admin/admin_commands/krb5kdc.rst.txt0000664000175000017500000001005515051422642024635 0ustar ghudsonghudson.. _krb5kdc(8): krb5kdc ======= SYNOPSIS -------- **krb5kdc** [**-x** *db_args*] [**-d** *dbname*] [**-k** *keytype*] [**-M** *mkeyname*] [**-p** *portnum*] [**-m**] [**-r** *realm*] [**-n**] [**-w** *numworkers*] [**-P** *pid_file*] [**-T** *time_offset*] DESCRIPTION ----------- krb5kdc is the Kerberos version 5 Authentication Service and Key Distribution Center (AS/KDC). OPTIONS ------- The **-r** *realm* option specifies the realm for which the server should provide service. This option may be specified multiple times to serve multiple realms. If no **-r** option is given, the default realm (as specified in :ref:`krb5.conf(5)`) will be served. The **-d** *dbname* option specifies the name under which the principal database can be found. This option does not apply to the LDAP database. The **-k** *keytype* option specifies the key type of the master key to be entered manually as a password when **-m** is given; the default is |defmkey|. The **-M** *mkeyname* option specifies the principal name for the master key in the database (usually ``K/M`` in the KDC's realm). The **-m** option specifies that the master database password should be fetched from the keyboard rather than from a stash file. The **-n** option specifies that the KDC does not put itself in the background and does not disassociate itself from the terminal. The **-P** *pid_file* option tells the KDC to write its PID into *pid_file* after it starts up. This can be used to identify whether the KDC is still running and to allow init scripts to stop the correct process. The **-p** *portnum* option specifies the default UDP and TCP port numbers which the KDC should listen on for Kerberos version 5 requests, as a comma-separated list. This value overrides the port numbers specified in the :ref:`kdcdefaults` section of :ref:`kdc.conf(5)`, but may be overridden by realm-specific values. If no value is given from any source, the default port is 88. The **-w** *numworkers* option tells the KDC to fork *numworkers* processes to listen to the KDC ports and process requests in parallel. The top level KDC process (whose pid is recorded in the pid file if the **-P** option is also given) acts as a supervisor. The supervisor will relay SIGHUP signals to the worker subprocesses, and will terminate the worker subprocess if the it is itself terminated or if any other worker process exits. The **-x** *db_args* option specifies database-specific arguments. See :ref:`Database Options ` in :ref:`kadmin(1)` for supported arguments. The **-T** *offset* option specifies a time offset, in seconds, which the KDC will operate under. It is intended only for testing purposes. EXAMPLE ------- The KDC may service requests for multiple realms (maximum 32 realms). The realms are listed on the command line. Per-realm options that can be specified on the command line pertain for each realm that follows it and are superseded by subsequent definitions of the same option. For example:: krb5kdc -p 2001 -r REALM1 -p 2002 -r REALM2 -r REALM3 specifies that the KDC listen on port 2001 for REALM1 and on port 2002 for REALM2 and REALM3. Additionally, per-realm parameters may be specified in the :ref:`kdc.conf(5)` file. The location of this file may be specified by the **KRB5_KDC_PROFILE** environment variable. Per-realm parameters specified in this file take precedence over options specified on the command line. See the :ref:`kdc.conf(5)` description for further details. ENVIRONMENT ----------- See :ref:`kerberos(7)` for a description of Kerberos environment variables. As of release 1.22, krb5kdc supports systemd socket activation via the LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by the caller must correspond to configured listener addresses (via the **kdc_listen** variable or equivalent) or they will be ignored. Any configured listener addresses that do not correspond to caller-provided sockets will be ignored if socket activation is used. SEE ALSO -------- :ref:`kdb5_util(8)`, :ref:`kdc.conf(5)`, :ref:`krb5.conf(5)`, :ref:`kdb5_ldap_util(8)`, :ref:`kerberos(7)` krb5-1.22.1/doc/html/_sources/admin/conf_ldap.rst.txt0000664000175000017500000001306015051422642022263 0ustar ghudsonghudson.. _conf_ldap: Configuring Kerberos with OpenLDAP back-end =========================================== 1. Make sure the LDAP server is using local authentication (``ldapi://``) or TLS (``ldaps``). See https://www.openldap.org/doc/admin/tls.html for instructions on configuring TLS support in OpenLDAP. 2. Add the Kerberos schema file to the LDAP Server using the OpenLDAP LDIF file from the krb5 source directory (``src/plugins/kdb/ldap/libkdb_ldap/kerberos.openldap.ldif``). The following example uses local authentication:: ldapadd -Y EXTERNAL -H ldapi:/// -f /path/to/kerberos.openldap.ldif 3. Choose DNs for the :ref:`krb5kdc(8)` and :ref:`kadmind(8)` servers to bind to the LDAP server, and create them if necessary. Specify these DNs with the **ldap_kdc_dn** and **ldap_kadmind_dn** directives in :ref:`kdc.conf(5)`. The kadmind DN will also be used for administrative commands such as :ref:`kdb5_util(8)`. Alternatively, you may configure krb5kdc and kadmind to use SASL authentication to access the LDAP server; see the :ref:`dbmodules` relations **ldap_kdc_sasl_mech** and similar. 4. Specify a location for the LDAP service password file by setting **ldap_service_password_file**. Use ``kdb5_ldap_util stashsrvpw`` to stash passwords for the KDC and kadmind DNs chosen above. For example:: kdb5_ldap_util stashsrvpw -f /path/to/service.keyfile cn=krbadmin,dc=example,dc=com Skip this step if you are using SASL authentication and the mechanism does not require a password. 5. Choose a DN for the global Kerberos container entry (but do not create the entry at this time). Specify this DN with the **ldap_kerberos_container_dn** directive in :ref:`kdc.conf(5)`. Realm container entries will be created underneath this DN. Principal entries may exist either underneath the realm container (the default) or in separate trees referenced from the realm container. 6. Configure the LDAP server ACLs to enable the KDC and kadmin server DNs to read and write the Kerberos data. If **disable_last_success** and **disable_lockout** are both set to true in the :ref:`dbmodules` subsection for the realm, then the KDC DN only requires read access to the Kerberos data. Sample access control information:: access to dn.base="" by * read access to dn.base="cn=Subschema" by * read # Provide access to the realm container. access to dn.subtree= "cn=EXAMPLE.COM,cn=krbcontainer,dc=example,dc=com" by dn.exact="cn=kdc-service,dc=example,dc=com" write by dn.exact="cn=adm-service,dc=example,dc=com" write by * none # Provide access to principals, if not underneath the realm container. access to dn.subtree= "ou=users,dc=example,dc=com" by dn.exact="cn=kdc-service,dc=example,dc=com" write by dn.exact="cn=adm-service,dc=example,dc=com" write by * none access to * by * read If the locations of the container and principals or the DNs of the service objects for a realm are changed then this information should be updated. 7. In :ref:`kdc.conf(5)`, make sure the following relations are set in the :ref:`dbmodules` subsection for the realm:: db_library (set to ``kldap``) ldap_kerberos_container_dn ldap_kdc_dn ldap_kadmind_dn ldap_service_password_file ldap_servers 8. Create the realm using :ref:`kdb5_ldap_util(8)`: kdb5_ldap_util create -subtrees ou=users,dc=example,dc=com -s Use the **-subtrees** option if the principals are to exist in a separate subtree from the realm container. Before executing the command, make sure that the subtree mentioned above ``(ou=users,dc=example,dc=com)`` exists. If the principals will exist underneath the realm container, omit the **-subtrees** option and do not worry about creating the principal subtree. For more information, refer to the section :ref:`ops_on_ldap`. The realm object is created under the **ldap_kerberos_container_dn** specified in the configuration file. This operation will also create the Kerberos container, if not present already. This container can be used to store information related to multiple realms. 9. Add an ``eq`` index for ``krbPrincipalName`` to speed up principal lookup operations. See https://www.openldap.org/doc/admin/tuning.html#Indexes for details. With the LDAP back end it is possible to provide aliases for principal entries. Beginning in release 1.22, aliases can be added with the kadmin **add_alias** command, but it is also possible (in release 1.7 or later) to provide aliases through direct manipulation of the LDAP entries. An entry with aliases contains multiple values of the *krbPrincipalName* attribute. Since LDAP attribute values are not ordered, it is necessary to specify which principal name is canonical, by using the *krbCanonicalName* attribute. Therefore, to create aliases for an entry, first set the *krbCanonicalName* attribute of the entry to the canonical principal name (which should be identical to the pre-existing *krbPrincipalName* value), and then add additional *krbPrincipalName* attributes for the aliases. Principal aliases are only returned by the KDC when the client requests canonicalization. Canonicalization is normally requested for service principals; for client principals, an explicit flag is often required (e.g., ``kinit -C``) and canonicalization is only performed for initial ticket requests. krb5-1.22.1/doc/html/_sources/admin/troubleshoot.rst.txt0000664000175000017500000001074715051422642023100 0ustar ghudsonghudson.. _troubleshoot: Troubleshooting =============== .. _trace_logging: Trace logging ------------- Most programs using MIT krb5 1.9 or later can be made to provide information about internal krb5 library operations using trace logging. To enable this, set the **KRB5_TRACE** environment variable to a filename before running the program. On many operating systems, the filename ``/dev/stdout`` can be used to send trace logging output to standard output. Some programs do not honor **KRB5_TRACE**, either because they use secure library contexts (this generally applies to setuid programs and parts of the login system) or because they take direct control of the trace logging system using the API. Here is a short example showing trace logging output for an invocation of the :ref:`kvno(1)` command:: shell% env KRB5_TRACE=/dev/stdout kvno krbtgt/KRBTEST.COM [9138] 1332348778.823276: Getting credentials user@KRBTEST.COM -> krbtgt/KRBTEST.COM@KRBTEST.COM using ccache FILE:/me/krb5/build/testdir/ccache [9138] 1332348778.823381: Retrieving user@KRBTEST.COM -> krbtgt/KRBTEST.COM@KRBTEST.COM from FILE:/me/krb5/build/testdir/ccache with result: 0/Unknown code 0 krbtgt/KRBTEST.COM@KRBTEST.COM: kvno = 1 List of errors -------------- Frequently seen errors ~~~~~~~~~~~~~~~~~~~~~~ #. :ref:`init_creds_ETYPE_NOSUPP` #. :ref:`cert_chain_ETYPE_NOSUPP` #. :ref:`err_cert_chain_cert_expired` Errors seen by admins ~~~~~~~~~~~~~~~~~~~~~ .. _prop_failed_start: #. :ref:`kprop_no_route` #. :ref:`kprop_con_refused` #. :ref:`kprop_sendauth_exchange` .. _prop_failed_end: ----- .. _init_creds_etype_nosupp: KDC has no support for encryption type while getting initial credentials ........................................................................ .. _cert_chain_etype_nosupp: credential verification failed: KDC has no support for encryption type ...................................................................... This most commonly happens when trying to use a principal with only DES keys, in a release (MIT krb5 1.7 or later) which disables DES by default. DES encryption is considered weak due to its inadequate key size. If you cannot migrate away from its use, you can re-enable DES by adding ``allow_weak_crypto = true`` to the :ref:`libdefaults` section of :ref:`krb5.conf(5)`. .. _err_cert_chain_cert_expired: Cannot create cert chain: certificate has expired ................................................. This error message indicates that PKINIT authentication failed because the client certificate, KDC certificate, or one of the certificates in the signing chain above them has expired. If the KDC certificate has expired, this message appears in the KDC log file, and the client will receive a "Preauthentication failed" error. (Prior to release 1.11, the KDC log file message erroneously appears as "Out of memory". Prior to release 1.12, the client will receive a "Generic error".) If the client or a signing certificate has expired, this message may appear in trace_logging_ output from :ref:`kinit(1)` or, starting in release 1.12, as an error message from kinit or another program which gets initial tickets. The error message is more likely to appear properly on the client if the principal entry has no long-term keys. .. _kprop_no_route: kprop: No route to host while connecting to server .................................................. Make sure that the hostname of the replica KDC (as given to kprop) is correct, and that any firewalls between the primary and the replica allow a connection on port 754. .. _kprop_con_refused: kprop: Connection refused while connecting to server .................................................... If the replica KDC is intended to run kpropd out of inetd, make sure that inetd is configured to accept krb5_prop connections. inetd may need to be restarted or sent a SIGHUP to recognize the new configuration. If the replica is intended to run kpropd in standalone mode, make sure that it is running. .. _kprop_sendauth_exchange: kprop: Server rejected authentication (during sendauth exchange) while authenticating to server ............................................................................................... Make sure that: #. The time is synchronized between the primary and replica KDCs. #. The master stash file was copied from the primary to the expected location on the replica. #. The replica has a keytab file in the default location containing a ``host`` principal for the replica's hostname. krb5-1.22.1/doc/html/_sources/admin/princ_dns.rst.txt0000664000175000017500000001232415051422642022317 0ustar ghudsonghudsonPrincipal names and DNS ======================= Kerberos clients can do DNS lookups to canonicalize service principal names. This can cause difficulties when setting up Kerberos application servers, especially when the client's name for the service is different from what the service thinks its name is. Service principal names ----------------------- A frequently used kind of principal name is the host-based service principal name. This kind of principal name has two components: a service name and a hostname. For example, ``imap/imap.example.com`` is the principal name of the "imap" service on the host "imap.example.com". Other possible service names for the first component include "host" (remote login services such as ssh), "HTTP", and "nfs" (Network File System). Service administrators often publish well-known hostname aliases that they would prefer users to use instead of the canonical name of the service host. This gives service administrators more flexibility in deploying services. For example, a shell login server might be named "long-vanity-hostname.example.com", but users will naturally prefer to type something like "login.example.com". Hostname aliases also allow for administrators to set up load balancing for some sorts of services based on rotating ``CNAME`` records in DNS. Service principal canonicalization ---------------------------------- In the MIT krb5 client library, canonicalization of host-based service principals is controlled by the **dns_canonicalize_hostname**, **rnds**, and **qualify_shortname** variables in :ref:`libdefaults`. If **dns_canonicalize_hostname** is set to ``true`` (the default value), the client performs forward resolution by looking up the IPv4 and/or IPv6 addresses of the hostname using ``getaddrinfo()``. This process will typically add a domain suffix to the hostname if needed, and follow CNAME records in the DNS. If **rdns** is also set to ``true`` (the default), the client will then perform a reverse lookup of the first returned Internet address using ``getnameinfo()``, finding the name associated with the PTR record. If **dns_canonicalize_hostname** is set to ``false``, the hostname is not canonicalized using DNS. If the hostname has only one component (i.e. it contains no "." characters), the host's primary DNS search domain will be appended, if there is one. The **qualify_shortname** variable can be used to override or disable this suffix. If **dns_canonicalize_hostname** is set to ``fallback`` (added in release 1.18), the hostname is initially treated according to the rules for ``dns_canonicalize_hostname=false``. If a ticket request fails because the service principal is unknown, the hostname will be canonicalized according to the rules for ``dns_canonicalize_hostname=true`` and the request will be retried. In all cases, the hostname is converted to lowercase, and any trailing dot is removed. Reverse DNS mismatches ---------------------- Sometimes, an enterprise will have control over its forward DNS but not its reverse DNS. The reverse DNS is sometimes under the control of the Internet service provider of the enterprise, and the enterprise may not have much influence in setting up reverse DNS records for its address space. If there are difficulties with getting forward and reverse DNS to match, it is best to set ``rdns = false`` on client machines. Overriding application behavior ------------------------------- Applications can choose to use a default hostname component in their service principal name when accepting authentication, which avoids some sorts of hostname mismatches. Because not all relevant applications do this yet, using the :ref:`krb5.conf(5)` setting:: [libdefaults] ignore_acceptor_hostname = true will allow the Kerberos library to override the application's choice of service principal hostname and will allow a server program to accept incoming authentications using any key in its keytab that matches the service name and realm name (if given). This setting defaults to "false" and is available in releases krb5-1.10 and later. Provisioning keytabs -------------------- One service principal entry that should be in the keytab is a principal whose hostname component is the canonical hostname that ``getaddrinfo()`` reports for all known aliases for the host. If the reverse DNS information does not match this canonical hostname, an additional service principal entry should be in the keytab for this different hostname. Specific application advice --------------------------- Secure shell (ssh) ~~~~~~~~~~~~~~~~~~ Setting ``GSSAPIStrictAcceptorCheck = no`` in the configuration file of modern versions of the openssh daemon will allow the daemon to try any key in its keytab when accepting a connection, rather than looking for the keytab entry that matches the host's own idea of its name (typically the name that ``gethostname()`` returns). This requires krb5-1.10 or later. OpenLDAP (ldapsearch, etc.) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ OpenLDAP's SASL implementation performs reverse DNS lookup in order to canonicalize service principal names, even if **rdns** is set to ``false`` in the Kerberos configuration. To disable this behavior, add ``SASL_NOCANON on`` to ``ldap.conf``, or set the ``LDAPSASL_NOCANON`` environment variable. krb5-1.22.1/doc/html/_sources/admin/install_clients.rst.txt0000664000175000017500000000544215051422642023532 0ustar ghudsonghudsonInstalling and configuring UNIX client machines =============================================== The Kerberized client programs include :ref:`kinit(1)`, :ref:`klist(1)`, :ref:`kdestroy(1)`, and :ref:`kpasswd(1)`. All of these programs are in the directory |bindir|. You can often integrate Kerberos with the login system on client machines, typically through the use of PAM. The details vary by operating system, and should be covered in your operating system's documentation. If you do this, you will need to make sure your users know to use their Kerberos passwords when they log in. You will also need to educate your users to use the ticket management programs kinit, klist, and kdestroy. If you do not have Kerberos password changing integrated into the native password program (again, typically through PAM), you will need to educate users to use kpasswd in place of its non-Kerberos counterparts passwd. Client machine configuration files ---------------------------------- Each machine running Kerberos should have a :ref:`krb5.conf(5)` file. At a minimum, it should define a **default_realm** setting in :ref:`libdefaults`. If you are not using DNS SRV records (:ref:`kdc_hostnames`) or URI records (:ref:`kdc_discovery`), it must also contain a :ref:`realms` section containing information for your realm's KDCs. Consider setting **rdns** to false in order to reduce your dependence on precisely correct DNS information for service hostnames. Turning this flag off means that service hostnames will be canonicalized through forward name resolution (which adds your domain name to unqualified hostnames, and resolves CNAME records in DNS), but not through reverse address lookup. The default value of this flag is true for historical reasons only. If you anticipate users frequently logging into remote hosts (e.g., using ssh) using forwardable credentials, consider setting **forwardable** to true so that users obtain forwardable tickets by default. Otherwise users will need to use ``kinit -f`` to get forwardable tickets. Consider adjusting the **ticket_lifetime** setting to match the likely length of sessions for your users. For instance, if most of your users will be logging in for an eight-hour workday, you could set the default to ten hours so that tickets obtained in the morning expire shortly after the end of the workday. Users can still manually request longer tickets when necessary, up to the maximum allowed by each user's principal record on the KDC. If a client host may access services in different realms, it may be useful to define a :ref:`domain_realm` mapping so that clients know which hosts belong to which realms. However, if your clients and KDC are running release 1.7 or later, it is also reasonable to leave this section out on client machines and just define it in the KDC's krb5.conf. krb5-1.22.1/doc/html/_sources/admin/install.rst.txt0000664000175000017500000000065015051422642022005 0ustar ghudsonghudsonInstallation guide ================== Contents -------- .. toctree:: :maxdepth: 2 install_kdc.rst install_clients.rst install_appl_srv.rst Additional references --------------------- #. Debian: `Setting up MIT Kerberos 5 `_ #. Solaris: `Configuring the Kerberos Service `_ krb5-1.22.1/doc/html/_sources/admin/appl_servers.rst.txt0000664000175000017500000001622515051422642023051 0ustar ghudsonghudsonApplication servers =================== If you need to install the Kerberos V5 programs on an application server, please refer to the Kerberos V5 Installation Guide. Once you have installed the software, you need to add that host to the Kerberos database (see :ref:`principals`), and generate a keytab for that host, that contains the host's key. You also need to make sure the host's clock is within your maximum clock skew of the KDCs. Keytabs ------- A keytab is a host's copy of its own keylist, which is analogous to a user's password. An application server that needs to authenticate itself to the KDC has to have a keytab that contains its own principal and key. Just as it is important for users to protect their passwords, it is equally important for hosts to protect their keytabs. You should always store keytab files on local disk, and make them readable only by root, and you should never send a keytab file over a network in the clear. Ideally, you should run the :ref:`kadmin(1)` command to extract a keytab on the host on which the keytab is to reside. .. _add_princ_kt: Adding principals to keytabs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To generate a keytab, or to add a principal to an existing keytab, use the **ktadd** command from kadmin. Here is a sample session, using configuration files that enable only AES encryption:: kadmin: ktadd host/daffodil.mit.edu@ATHENA.MIT.EDU Entry for principal host/daffodil.mit.edu with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab Entry for principal host/daffodil.mit.edu with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab Removing principals from keytabs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To remove a principal from an existing keytab, use the kadmin **ktremove** command:: kadmin: ktremove host/daffodil.mit.edu@ATHENA.MIT.EDU Entry for principal host/daffodil.mit.edu with kvno 2 removed from keytab FILE:/etc/krb5.keytab. Entry for principal host/daffodil.mit.edu with kvno 2 removed from keytab FILE:/etc/krb5.keytab. Using a keytab to acquire client credentials ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ While keytabs are ordinarily used to accept credentials from clients, they can also be used to acquire initial credentials, allowing one service to authenticate to another. To manually obtain credentials using a keytab, use the :ref:`kinit(1)` **-k** option, together with the **-t** option if the keytab is not in the default location. Beginning with release 1.11, GSSAPI applications can be configured to automatically obtain initial credentials from a keytab as needed. The recommended configuration is as follows: #. Create a keytab containing a single entry for the desired client identity. #. Place the keytab in a location readable by the service, and set the **KRB5_CLIENT_KTNAME** environment variable to its filename. Alternatively, use the **default_client_keytab_name** profile variable in :ref:`libdefaults`, or use the default location of |ckeytab|. #. Set **KRB5CCNAME** to a filename writable by the service, which will not be used for any other purpose. Do not manually obtain credentials at this location. (Another credential cache type besides **FILE** can be used if desired, as long the cache will not conflict with another use. A **MEMORY** cache can be used if the service runs as a long-lived process. See :ref:`ccache_definition` for details.) #. Start the service. When it authenticates using GSSAPI, it will automatically obtain credentials from the client keytab into the specified credential cache, and refresh them before they expire. Clock Skew ---------- A Kerberos application server host must keep its clock synchronized or it will reject authentication requests from clients. Modern operating systems typically provide a facility to maintain the correct time; make sure it is enabled. This is especially important on virtual machines, where clocks tend to drift more rapidly than normal machine clocks. The default allowable clock skew is controlled by the **clockskew** variable in :ref:`libdefaults`. Getting DNS information correct ------------------------------- Several aspects of Kerberos rely on name service. When a hostname is used to name a service, clients may canonicalize the hostname using forward and possibly reverse name resolution. The result of this canonicalization must match the principal entry in the host's keytab, or authentication will fail. To work with all client canonicalization configurations, each host's canonical name must be the fully-qualified host name (including the domain), and each host's IP address must reverse-resolve to the canonical name. Configuration of hostnames varies by operating system. On the application server itself, canonicalization will typically use the ``/etc/hosts`` file rather than the DNS. Ensure that the line for the server's hostname is in the following form:: IP address fully-qualified hostname aliases Here is a sample ``/etc/hosts`` file:: # this is a comment 127.0.0.1 localhost localhost.mit.edu 10.0.0.6 daffodil.mit.edu daffodil trillium wake-robin The output of ``klist -k`` for this example host should look like:: viola# klist -k Keytab name: /etc/krb5.keytab KVNO Principal ---- ------------------------------------------------------------ 2 host/daffodil.mit.edu@ATHENA.MIT.EDU If you were to ssh to this host with a fresh credentials cache (ticket file), and then :ref:`klist(1)`, the output should list a service principal of ``host/daffodil.mit.edu@ATHENA.MIT.EDU``. .. _conf_firewall: Configuring your firewall to work with Kerberos V5 -------------------------------------------------- If you need off-site users to be able to get Kerberos tickets in your realm, they must be able to get to your KDC. This requires either that you have a replica KDC outside your firewall, or that you configure your firewall to allow UDP requests into at least one of your KDCs, on whichever port the KDC is running. (The default is port 88; other ports may be specified in the KDC's :ref:`kdc.conf(5)` file.) Similarly, if you need off-site users to be able to change their passwords in your realm, they must be able to get to your Kerberos admin server on the kpasswd port (which defaults to 464). If you need off-site users to be able to administer your Kerberos realm, they must be able to get to your Kerberos admin server on the administrative port (which defaults to 749). If your on-site users inside your firewall will need to get to KDCs in other realms, you will also need to configure your firewall to allow outgoing TCP and UDP requests to port 88, and to port 464 to allow password changes. If your on-site users inside your firewall will need to get to Kerberos admin servers in other realms, you will also need to allow outgoing TCP and UDP requests to port 749. If any of your KDCs are outside your firewall, you will need to allow kprop requests to get through to the remote KDC. :ref:`kprop(8)` uses the ``krb5_prop`` service on port 754 (tcp). The book *UNIX System Security*, by David Curry, is a good starting point for learning to configure firewalls. krb5-1.22.1/doc/html/_sources/admin/host_config.rst.txt0000664000175000017500000002222215051422642022640 0ustar ghudsonghudsonHost configuration ================== All hosts running Kerberos software, whether they are clients, application servers, or KDCs, can be configured using :ref:`krb5.conf(5)`. Here we describe some of the behavior changes you might want to make. Default realm ------------- In the :ref:`libdefaults` section, the **default_realm** realm relation sets the default Kerberos realm. For example:: [libdefaults] default_realm = ATHENA.MIT.EDU The default realm affects Kerberos behavior in the following ways: * When a principal name is parsed from text, the default realm is used if no ``@REALM`` component is specified. * The default realm affects login authorization as described below. * For programs which operate on a Kerberos database, the default realm is used to determine which database to operate on, unless the **-r** parameter is given to specify a realm. * A server program may use the default realm when looking up its key in a :ref:`keytab file `, if its realm is not determined by :ref:`domain_realm` configuration or by the server program itself. * If :ref:`kinit(1)` is passed the **-n** flag, it requests anonymous tickets from the default realm. In some situations, these uses of the default realm might conflict. For example, it might be desirable for principal name parsing to use one realm by default, but for login authorization to use a second realm. In this situation, the first realm can be configured as the default realm, and **auth_to_local** relations can be used as described below to use the second realm for login authorization. .. _login_authorization: Login authorization ------------------- If a host runs a Kerberos-enabled login service such as OpenSSH with GSSAPIAuthentication enabled, login authorization rules determine whether a Kerberos principal is allowed to access a local account. By default, a Kerberos principal is allowed access to an account if its realm matches the default realm and its name matches the account name. (For historical reasons, access is also granted by default if the name has two components and the second component matches the default realm; for instance, ``alice/ATHENA.MIT.EDU@ATHENA.MIT.EDU`` is granted access to the ``alice`` account if ``ATHENA.MIT.EDU`` is the default realm.) The simplest way to control local access is using :ref:`.k5login(5)` files. To use these, place a ``.k5login`` file in the home directory of each account listing the principal names which should have login access to that account. If it is not desirable to use ``.k5login`` files located in account home directories, the **k5login_directory** relation in the :ref:`libdefaults` section can specify a directory containing one file per account uname. By default, if a ``.k5login`` file is present, it controls authorization both positively and negatively--any principal name contained in the file is granted access and any other principal name is denied access, even if it would have had access if the ``.k5login`` file didn't exist. The **k5login_authoritative** relation in the :ref:`libdefaults` section can be set to false to make ``.k5login`` files provide positive authorization only. The **auth_to_local** relation in the :ref:`realms` section for the default realm can specify pattern-matching rules to control login authorization. For example, the following configuration allows access to principals from a different realm than the default realm:: [realms] DEFAULT.REALM = { # Allow access to principals from OTHER.REALM. # # [1:$1@$0] matches single-component principal names and creates # a selection string containing the principal name and realm. # # (.*@OTHER\.REALM) matches against the selection string, so that # only principals in OTHER.REALM are matched. # # s/@OTHER\.REALM$// removes the realm name, leaving behind the # principal name as the account name. auth_to_local = RULE:[1:$1@$0](.*@OTHER\.REALM)s/@OTHER\.REALM$// # Also allow principals from the default realm. Omit this line # to only allow access to principals in OTHER.REALM. auth_to_local = DEFAULT } The **auth_to_local_names** subsection of the :ref:`realms` section for the default realm can specify explicit mappings from principal names to local accounts. The key used in this subsection is the principal name without realm, so it is only safe to use in a Kerberos environment with a single realm or a tightly controlled set of realms. An example use of **auth_to_local_names** might be:: [realms] ATHENA.MIT.EDU = { auth_to_local_names = { # Careful, these match principals in any realm! host/example.com = hostaccount fred = localfred } } Local authorization behavior can also be modified using plugin modules; see :ref:`hostrealm_plugin` for details. .. _plugin_config: Plugin module configuration --------------------------- Many aspects of Kerberos behavior, such as client preauthentication and KDC service location, can be modified through the use of plugin modules. For most of these behaviors, you can use the :ref:`plugins` section of krb5.conf to register third-party modules, and to switch off registered or built-in modules. A plugin module takes the form of a Unix shared object (``modname.so``) or Windows DLL (``modname.dll``). If you have installed a third-party plugin module and want to register it, you do so using the **module** relation in the appropriate subsection of the [plugins] section. The value for **module** must give the module name and the path to the module, separated by a colon. The module name will often be the same as the shared object's name, but in unusual cases (such as a shared object which implements multiple modules for the same interface) it might not be. For example, to register a client preauthentication module named ``mypreauth`` installed at ``/path/to/mypreauth.so``, you could write:: [plugins] clpreauth = { module = mypreauth:/path/to/mypreauth.so } Many of the pluggable behaviors in MIT krb5 contain built-in modules which can be switched off. You can disable a built-in module (or one you have registered) using the **disable** directive in the appropriate subsection of the [plugins] section. For example, to disable the use of .k5identity files to select credential caches, you could write:: [plugins] ccselect = { disable = k5identity } If you want to disable multiple modules, specify the **disable** directive multiple times, giving one module to disable each time. Alternatively, you can explicitly specify which modules you want to be enabled for that behavior using the **enable_only** directive. For example, to make :ref:`kadmind(8)` check password quality using only a module you have registered, and no other mechanism, you could write:: [plugins] pwqual = { module = mymodule:/path/to/mymodule.so enable_only = mymodule } Again, if you want to specify multiple modules, specify the **enable_only** directive multiple times, giving one module to enable each time. Some Kerberos interfaces use different mechanisms to register plugin modules. KDC location modules ~~~~~~~~~~~~~~~~~~~~ For historical reasons, modules to control how KDC servers are located are registered simply by placing the shared object or DLL into the "libkrb5" subdirectory of the krb5 plugin directory, which defaults to |libdir|\ ``/krb5/plugins``. For example, Samba's winbind krb5 locator plugin would be registered by placing its shared object in |libdir|\ ``/krb5/plugins/libkrb5/winbind_krb5_locator.so``. .. _gssapi_plugin_config: GSSAPI mechanism modules ~~~~~~~~~~~~~~~~~~~~~~~~ GSSAPI mechanism modules are registered using the file |sysconfdir|\ ``/gss/mech`` or configuration files in the |sysconfdir|\ ``/gss/mech.d`` directory with a ``.conf`` suffix. Each line in these files has the form:: name oid pathname [options] Only the name, oid, and pathname are required. *name* is the mechanism name, which may be used for debugging or logging purposes. *oid* is the object identifier of the GSSAPI mechanism to be registered. *pathname* is a path to the module shared object or DLL. *options* (if present) are options provided to the plugin module, surrounded in square brackets. *type* (if present) can be used to indicate a special type of module. Currently the only special module type is "interposer", for a module designed to intercept calls to other mechanisms. If the environment variable **GSS_MECH_CONFIG** is set, its value is used as the sole mechanism configuration filename. .. _profile_plugin_config: Configuration profile modules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A configuration profile module replaces the information source for :ref:`krb5.conf(5)` itself. To use a profile module, begin krb5.conf with the line:: module PATHNAME:STRING where *PATHNAME* is a path to the module shared object or DLL, and *STRING* is a string to provide to the module. The module will then take over, and the rest of krb5.conf will be ignored. krb5-1.22.1/doc/html/_sources/admin/https.rst.txt0000664000175000017500000000364615051422642021511 0ustar ghudsonghudson.. _https: HTTPS proxy configuration ========================= In addition to being able to use UDP or TCP to communicate directly with a KDC as is outlined in RFC4120, and with kpasswd services in a similar fashion, the client libraries can attempt to use an HTTPS proxy server to communicate with a KDC or kpasswd service, using the protocol outlined in [MS-KKDCP]. Communicating with a KDC through an HTTPS proxy allows clients to contact servers when network firewalls might otherwise prevent them from doing so. The use of TLS also encrypts all traffic between the clients and the KDC, preventing observers from conducting password dictionary attacks or from observing the client and server principals being authenticated, at additional computational cost to both clients and servers. An HTTPS proxy server is provided as a feature in some versions of Microsoft Windows Server, and a WSGI implementation named `kdcproxy` is available in the python package index. Configuring the clients ----------------------- To use an HTTPS proxy, a client host must trust the CA which issued that proxy's SSL certificate. If that CA's certificate is not in the system-wide default set of trusted certificates, configure the following relation in the client host's :ref:`krb5.conf(5)` file in the appropriate :ref:`realms` subsection:: http_anchors = FILE:/etc/krb5/cacert.pem Adjust the pathname to match the path of the file which contains a copy of the CA's certificate. The `http_anchors` option is documented more fully in :ref:`krb5.conf(5)`. Configure the client to access the KDC and kpasswd service by specifying their locations in its :ref:`krb5.conf(5)` file in the form of HTTPS URLs for the proxy server:: kdc = https://server.fqdn/KdcProxy kpasswd_server = https://server.fqdn/KdcProxy If the proxy and client are properly configured, client commands such as ``kinit``, ``kvno``, and ``kpasswd`` should all function normally. krb5-1.22.1/doc/html/_sources/resources.rst.txt0000664000175000017500000000361015051422642021260 0ustar ghudsonghudsonResources ========= Mailing lists ------------- * kerberos@mit.edu is a community resource for discussion and questions about MIT krb5 and other Kerberos implementations. To subscribe to the list, please follow the instructions at https://mailman.mit.edu/mailman/listinfo/kerberos. * krbdev@mit.edu is the primary list for developers of MIT Kerberos. To subscribe to the list, please follow the instructions at https://mailman.mit.edu/mailman/listinfo/krbdev. * krb5-bugs@mit.edu is notified when a ticket is created or updated. This list helps track bugs and feature requests. In addition, this list is used to track documentation criticism and recommendations for improvements. * krbcore@mit.edu is a private list for the MIT krb5 core team. Send mail to this list if you need to contact the core team. * krbcore-security@mit.edu is the point of contact for security problems with MIT Kerberos. Please use PGP-encrypted mail to report possible vulnerabilities to this list. IRC channels ------------ The IRC channel `#kerberos` on libera.chat is a community resource for general Kerberos discussion and support. The main IRC channel for MIT Kerberos development is `#krbdev` on Libera Chat. For more information about Libera Chat, see https://libera.chat/. Archives -------- * The archive https://mailman.mit.edu/pipermail/kerberos/ contains past postings from the `kerberos@mit.edu` list. * The https://mailman.mit.edu/pipermail/krbdev/ contains past postings from the `krbdev@mit.edu` list. Wiki ---- The wiki at https://k5wiki.kerberos.org/ contains useful information for developers working on the MIT Kerberos source code. Some of the information on the wiki may be useful for advanced users or system administrators. Web pages --------- * https://web.mit.edu/kerberos/ is the MIT Kerberos software web page. * https://kerberos.org/ is the MIT Kerberos Consortium web page. krb5-1.22.1/doc/html/_sources/basic/0000775000175000017500000000000015051422713016756 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_sources/basic/index.rst.txt0000664000175000017500000000025215051422642021435 0ustar ghudsonghudson.. _basic_concepts: Kerberos V5 concepts ==================== .. toctree:: :maxdepth: 1 ccache_def keytab_def rcache_def stash_file_def date_format krb5-1.22.1/doc/html/_sources/basic/rcache_def.rst.txt0000664000175000017500000001134115051422642022372 0ustar ghudsonghudson.. _rcache_definition: replay cache ============ A replay cache (or "rcache") keeps track of all authenticators recently presented to a service. If a duplicate authentication request is detected in the replay cache, an error message is sent to the application program. The replay cache interface, like the credential cache and :ref:`keytab_definition` interfaces, uses `type:residual` strings to indicate the type of replay cache and any associated cache naming data to use. Background information ---------------------- Some Kerberos or GSSAPI services use a simple authentication mechanism where a message is sent containing an authenticator, which establishes the encryption key that the client will use for talking to the service. But nothing about that prevents an eavesdropper from recording the messages sent by the client, establishing a new connection, and re-sending or "replaying" the same messages; the replayed authenticator will establish the same encryption key for the new session, and the following messages will be decrypted and processed. The attacker may not know what the messages say, and can't generate new messages under the same encryption key, but in some instances it may be harmful to the user (or helpful to the attacker) to cause the server to see the same messages again a second time. For example, if the legitimate client sends "delete first message in mailbox", a replay from an attacker may delete another, different "first" message. (Protocol design to guard against such problems has been discussed in :rfc:`4120#section-10`.) Even if one protocol uses further protection to verify that the client side of the connection actually knows the encryption keys (and thus is presumably a legitimate user), if another service uses the same service principal name, it may be possible to record an authenticator used with the first protocol and "replay" it against the second. The replay cache mitigates these attacks somewhat, by keeping track of authenticators that have been seen until their five-minute window expires. Different authenticators generated by multiple connections from the same legitimate client will generally have different timestamps, and thus will not be considered the same. This mechanism isn't perfect. If a message is sent to one application server but a man-in-the-middle attacker can prevent it from actually arriving at that server, the attacker could then use the authenticator (once!) against a different service on the same host. This could be a problem if the message from the client included something more than authentication in the first message that could be useful to the attacker (which is uncommon; in most protocols the server has to indicate a successful authentication before the client sends additional messages), or if the simple act of presenting the authenticator triggers some interesting action in the service being attacked. Replay cache types ------------------ Unlike the credential cache and keytab interfaces, replay cache types are in lowercase. The following types are defined: #. **none** disables the replay cache. The residual value is ignored. #. **file2** (new in release 1.18) uses a hash-based format to store replay records. The file may grow to accommodate hash collisions. The residual value is the filename. #. **dfl** is the default type if no environment variable or configuration specifies a different type. It stores replay data in a file2 replay cache with a filename based on the effective uid. The residual value is ignored. For the dfl type, the location of the replay cache file is determined as follows: #. The directory is taken from the **KRB5RCACHEDIR** environment variable, or the **TMPDIR** environment variable, or a temporary directory determined at configuration time such as ``/var/tmp``, in descending order of preference. #. The filename is ``krb5_EUID.rcache2`` where EUID is the effective uid of the process. #. The file is opened without following symbolic links, and ownership of the file is verified to match the effective uid. On Windows, the directory for the dfl type is the local appdata directory, unless overridden by the **KRB5RCACHEDIR** environment variable. The filename on Windows is ``krb5.rcache2``, and the file is opened normally. Default replay cache name ------------------------- The default replay cache name is determined by the following, in descending order of priority: #. The **KRB5RCACHENAME** environment variable (new in release 1.18). #. The **KRB5RCACHETYPE** environment variable. If this variable is set, the residual value is empty. #. The **default_rcache_name** profile variable in :ref:`libdefaults` (new in release 1.18). #. If none of the above are set, the default replay cache name is ``dfl:``. krb5-1.22.1/doc/html/_sources/basic/ccache_def.rst.txt0000664000175000017500000001516615051422642022364 0ustar ghudsonghudson.. _ccache_definition: Credential cache ================ A credential cache (or "ccache") holds Kerberos credentials while they remain valid and, generally, while the user's session lasts, so that authenticating to a service multiple times (e.g., connecting to a web or mail server more than once) doesn't require contacting the KDC every time. A credential cache usually contains one initial ticket which is obtained using a password or another form of identity verification. If this ticket is a ticket-granting ticket, it can be used to obtain additional credentials without the password. Because the credential cache does not store the password, less long-term damage can be done to the user's account if the machine is compromised. A credentials cache stores a default client principal name, set when the cache is created. This is the name shown at the top of the :ref:`klist(1)` *-A* output. Each normal cache entry includes a service principal name, a client principal name (which, in some ccache types, need not be the same as the default), lifetime information, and flags, along with the credential itself. There are also other entries, indicated by special names, that store additional information. ccache types ------------ The credential cache interface, like the :ref:`keytab_definition` and :ref:`rcache_definition` interfaces, uses `TYPE:value` strings to indicate the type of credential cache and any associated cache naming data to use. There are several kinds of credentials cache supported in the MIT Kerberos library. Not all are supported on every platform. In most cases, it should be correct to use the default type built into the library. #. **API** is only implemented on Windows. It communicates with a server process that holds the credentials in memory for the user, rather than writing them to disk. #. **DIR** points to the storage location of the collection of the credential caches in *FILE:* format. It is most useful when dealing with multiple Kerberos realms and KDCs. For release 1.10 the directory must already exist. In post-1.10 releases the requirement is for parent directory to exist and the current process must have permissions to create the directory if it does not exist. See :ref:`col_ccache` for details. New in release 1.10. The following residual forms are supported: * DIR:dirname * DIR::dirpath/filename - a single cache within the directory Switching to a ccache of the latter type causes it to become the primary for the directory. #. **FILE** caches are the simplest and most portable. A simple flat file format is used to store one credential after another. This is the default ccache type if no type is specified in a ccache name. #. **KCM** caches work by contacting a daemon process called ``kcm`` to perform cache operations. If the cache name is just ``KCM:``, the default cache as determined by the KCM daemon will be used. Newly created caches must generally be named ``KCM:uid:name``, where *uid* is the effective user ID of the running process. KCM client support is new in release 1.13. A KCM daemon has not yet been implemented in MIT krb5, but the client will interoperate with the KCM daemon implemented by Heimdal. macOS 10.7 and higher provides a KCM daemon as part of the operating system, and the **KCM** cache type is used as the default cache on that platform in a default build. #. **KEYRING** is Linux-specific, and uses the kernel keyring support to store credential data in unswappable kernel memory where only the current user should be able to access it. The following residual forms are supported: * KEYRING:name * KEYRING:process:name - process keyring * KEYRING:thread:name - thread keyring Starting with release 1.12 the *KEYRING* type supports collections. The following new residual forms were added: * KEYRING:session:name - session keyring * KEYRING:user:name - user keyring * KEYRING:persistent:uidnumber - persistent per-UID collection. Unlike the user keyring, this collection survives after the user logs out, until the cache credentials expire. This type of ccache requires support from the kernel; otherwise, it will fall back to the user keyring. See :ref:`col_ccache` for details. #. **MEMORY** caches are for storage of credentials that don't need to be made available outside of the current process. For example, a memory ccache is used by :ref:`kadmin(1)` to store the administrative ticket used to contact the admin server. Memory ccaches are faster than file ccaches and are automatically destroyed when the process exits. #. **MSLSA** is a Windows-specific cache type that accesses the Windows credential store. .. _col_ccache: Collections of caches --------------------- Some credential cache types can support collections of multiple caches. One of the caches in the collection is designated as the *primary* and will be used when the collection is resolved as a cache. When a collection-enabled cache type is the default cache for a process, applications can search the specified collection for a specific client principal, and GSSAPI applications will automatically select between the caches in the collection based on criteria such as the target service realm. Credential cache collections are new in release 1.10, with support from the **DIR** and **API** ccache types. Starting in release 1.12, collections are also supported by the **KEYRING** ccache type. Collections are supported by the **KCM** ccache type in release 1.13. Tool alterations to use cache collection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * :ref:`kdestroy(1)` *-A* will destroy all caches in the collection. * If the default cache type supports switching, :ref:`kinit(1)` *princname* will search the collection for a matching cache and store credentials there, or will store credentials in a new unique cache of the default type if no existing cache for the principal exists. Either way, kinit will switch to the selected cache. * :ref:`klist(1)` *-l* will list the caches in the collection. * :ref:`klist(1)` *-A* will show the content of all caches in the collection. * :ref:`kswitch(1)` *-p princname* will search the collection for a matching cache and switch to it. * :ref:`kswitch(1)` *-c cachename* will switch to a specified cache. Default ccache name ------------------- The default credential cache name is determined by the following, in descending order of priority: #. The **KRB5CCNAME** environment variable. For example, ``KRB5CCNAME=DIR:/mydir/``. #. The **default_ccache_name** profile variable in :ref:`libdefaults`. #. The hardcoded default, |ccache|. krb5-1.22.1/doc/html/_sources/basic/date_format.rst.txt0000664000175000017500000001105015051422642022611 0ustar ghudsonghudson.. _datetime: Supported date and time formats =============================== .. _duration: Time duration ------------- This format is used to express a time duration in the Kerberos configuration files and user commands. The allowed formats are: ====================== ============== ============ Format Example Value ---------------------- -------------- ------------ h:m[:s] 36:00 36 hours NdNhNmNs 8h30s 8 hours 30 seconds N (number of seconds) 3600 1 hour ====================== ============== ============ Here *N* denotes a number, *d* - days, *h* - hours, *m* - minutes, *s* - seconds. .. note:: The time interval should not exceed 2147483647 seconds. Examples:: Request a ticket valid for one hour, five hours, 30 minutes and 10 days respectively: kinit -l 3600 kinit -l 5:00 kinit -l 30m kinit -l "10d 0h 0m 0s" .. _getdate: getdate time ------------ Some of the kadmin and kdb5_util commands take a date-time in a human-readable format. Some of the acceptable date-time strings are: +-----------+------------------+-----------------+ | | Format | Example | +===========+==================+=================+ | Date | mm/dd/yy | 07/27/12 | | +------------------+-----------------+ | | month dd, yyyy | Jul 27, 2012 | | +------------------+-----------------+ | | yyyy-mm-dd | 2012-07-27 | +-----------+------------------+-----------------+ | Absolute | HH:mm[:ss]pp | 08:30 PM | | time +------------------+-----------------+ | | hh:mm[:ss] | 20:30 | +-----------+------------------+-----------------+ | Relative | N tt | 30 sec | | time | | | +-----------+------------------+-----------------+ | Time zone | Z | EST | | +------------------+-----------------+ | | z | -0400 | +-----------+------------------+-----------------+ (See :ref:`abbreviation`.) Examples:: Create a principal that expires on the date indicated: addprinc test1 -expire "3/27/12 10:00:07 EST" addprinc test2 -expire "January 23, 2015 10:05pm" addprinc test3 -expire "22:00 GMT" Add a principal that will expire in 30 minutes: addprinc test4 -expire "30 minutes" .. _abstime: Absolute time ------------- This rarely used date-time format can be noted in one of the following ways: +------------------------+----------------------+--------------+ | Format | Example | Value | +========================+======================+==============+ | yyyymmddhhmmss | 20141231235900 | One minute | +------------------------+----------------------+ before 2015 | | yyyy.mm.dd.hh.mm.ss | 2014.12.31.23.59.00 | | +------------------------+----------------------+ | | yymmddhhmmss | 141231235900 | | +------------------------+----------------------+ | | yy.mm.dd.hh.mm.ss | 14.12.31.23.59.00 | | +------------------------+----------------------+ | | dd-month-yyyy:hh:mm:ss | 31-Dec-2014:23:59:00 | | +------------------------+----------------------+--------------+ | hh:mm:ss | 20:00:00 | 8 o'clock in | +------------------------+----------------------+ the evening | | hhmmss | 200000 | | +------------------------+----------------------+--------------+ (See :ref:`abbreviation`.) Example:: Set the default expiration date to July 27, 2012 at 20:30 default_principal_expiration = 20120727203000 .. _abbreviation: Abbreviations used in this document ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | *month* : locale’s month name or its abbreviation; | *dd* : day of month (01-31); | *HH* : hours (00-12); | *hh* : hours (00-23); | *mm* : in time - minutes (00-59); in date - month (01-12); | *N* : number; | *pp* : AM or PM; | *ss* : seconds (00-60); | *tt* : time units (hours, minutes, min, seconds, sec); | *yyyy* : year; | *yy* : last two digits of the year; | *Z* : alphabetic time zone abbreviation; | *z* : numeric time zone; .. note:: - If the date specification contains spaces, you may need to enclose it in double quotes; - All keywords are case-insensitive. krb5-1.22.1/doc/html/_sources/basic/keytab_def.rst.txt0000664000175000017500000000422415051422642022426 0ustar ghudsonghudson.. _keytab_definition: keytab ====== A keytab (short for "key table") stores long-term keys for one or more principals. Keytabs are normally represented by files in a standard format, although in rare cases they can be represented in other ways. Keytabs are used most often to allow server applications to accept authentications from clients, but can also be used to obtain initial credentials for client applications. Keytabs are named using the format *type*\ ``:``\ *value*. Usually *type* is ``FILE`` and *value* is the absolute pathname of the file. The other possible value for *type* is ``MEMORY``, which indicates a temporary keytab stored in the memory of the current process. A keytab contains one or more entries, where each entry consists of a timestamp (indicating when the entry was written to the keytab), a principal name, a key version number, an encryption type, and the encryption key itself. A keytab can be displayed using the :ref:`klist(1)` command with the ``-k`` option. Keytabs can be created or appended to by extracting keys from the KDC database using the :ref:`kadmin(1)` :ref:`ktadd` command. Keytabs can be manipulated using the :ref:`ktutil(1)` and :ref:`k5srvutil(1)` commands. Default keytab -------------- The default keytab is used by server applications if the application does not request a specific keytab. The name of the default keytab is determined by the following, in decreasing order of preference: #. The **KRB5_KTNAME** environment variable. #. The **default_keytab_name** profile variable in :ref:`libdefaults`. #. The hardcoded default, |keytab|. Default client keytab --------------------- The default client keytab is used, if it is present and readable, to automatically obtain initial credentials for GSSAPI client applications. The principal name of the first entry in the client keytab is used by default when obtaining initial credentials. The name of the default client keytab is determined by the following, in decreasing order of preference: #. The **KRB5_CLIENT_KTNAME** environment variable. #. The **default_client_keytab_name** profile variable in :ref:`libdefaults`. #. The hardcoded default, |ckeytab|. krb5-1.22.1/doc/html/_sources/basic/stash_file_def.rst.txt0000664000175000017500000000202615051422642023266 0ustar ghudsonghudson.. _stash_definition: stash file ============ The stash file is a local copy of the master key that resides in encrypted form on the KDC's local disk. The stash file is used to authenticate the KDC to itself automatically before starting the :ref:`kadmind(8)` and :ref:`krb5kdc(8)` daemons (e.g., as part of the machine's boot sequence). The stash file, like the keytab file (see :ref:`keytab_file`) is a potential point-of-entry for a break-in, and if compromised, would allow unrestricted access to the Kerberos database. If you choose to install a stash file, it should be readable only by root, and should exist only on the KDC's local disk. The file should not be part of any backup of the machine, unless access to the backup data is secured as tightly as access to the master password itself. .. note:: If you choose not to install a stash file, the KDC will prompt you for the master key each time it starts up. This means that the KDC will not be able to start automatically, such as after a system reboot. krb5-1.22.1/doc/html/resources.html0000664000175000017500000002214315051422713016755 0ustar ghudsonghudson Resources — MIT Kerberos Documentation

Resources¶

Mailing lists¶

  • kerberos@mit.edu is a community resource for discussion and questions about MIT krb5 and other Kerberos implementations. To subscribe to the list, please follow the instructions at https://mailman.mit.edu/mailman/listinfo/kerberos.

  • krbdev@mit.edu is the primary list for developers of MIT Kerberos. To subscribe to the list, please follow the instructions at https://mailman.mit.edu/mailman/listinfo/krbdev.

  • krb5-bugs@mit.edu is notified when a ticket is created or updated. This list helps track bugs and feature requests. In addition, this list is used to track documentation criticism and recommendations for improvements.

  • krbcore@mit.edu is a private list for the MIT krb5 core team. Send mail to this list if you need to contact the core team.

  • krbcore-security@mit.edu is the point of contact for security problems with MIT Kerberos. Please use PGP-encrypted mail to report possible vulnerabilities to this list.

IRC channels¶

The IRC channel #kerberos on libera.chat is a community resource for general Kerberos discussion and support.

The main IRC channel for MIT Kerberos development is #krbdev on Libera Chat.

For more information about Libera Chat, see https://libera.chat/.

Archives¶

Wiki¶

The wiki at https://k5wiki.kerberos.org/ contains useful information for developers working on the MIT Kerberos source code. Some of the information on the wiki may be useful for advanced users or system administrators.

Web pages¶

krb5-1.22.1/doc/html/genindex-all.html0000664000175000017500000046532015051422714017323 0ustar ghudsonghudson Index — MIT Kerberos Documentation

Index

A | C | E | K | L | M | P | R | S | T | V

A

C

E

K

L

M

P

R

S

T

V

krb5-1.22.1/doc/html/mitK5defaults.html0000664000175000017500000005066315051422713017474 0ustar ghudsonghudson MIT Kerberos defaults — MIT Kerberos Documentation

MIT Kerberos defaults¶

General defaults¶

Description

Default

Environment

keytab file

DEFKTNAME

KRB5_KTNAME

Client keytab file

DEFCKTNAME

KRB5_CLIENT_KTNAME

Kerberos config file krb5.conf

/etc/krb5.conf:SYSCONFDIR/krb5.conf

KRB5_CONFIG

KDC config file kdc.conf

LOCALSTATEDIR/krb5kdc/kdc.conf

KRB5_KDC_PROFILE

GSS mechanism config file

SYSCONFDIR/gss/mech

GSS_MECH_CONFIG

KDC database path (DB2)

LOCALSTATEDIR/krb5kdc/principal

Master key stash file

LOCALSTATEDIR/krb5kdc/.k5.realm

Admin server ACL file kadm5.acl

LOCALSTATEDIR/krb5kdc/kadm5.acl

OTP socket directory

RUNSTATEDIR/krb5kdc

Plugin base directory

LIBDIR/krb5/plugins

replay cache directory

/var/tmp

KRB5RCACHEDIR

Master key default enctype

aes256-cts-hmac-sha1-96

Default keysalt list

aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal

Permitted enctypes

aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 aes128-cts-hmac-sha256-128 des3-cbc-sha1 arcfour-hmac-md5 camellia256-cts-cmac camellia128-cts-cmac

KDC default port

88

Admin server port

749

Password change port

464

Replica KDC propagation defaults¶

This table shows defaults used by the kprop and kpropd programs.

Description

Default

Environment

kprop database dump file

LOCALSTATEDIR/krb5kdc/replica_datatrans

kpropd temporary dump file

LOCALSTATEDIR/krb5kdc/from_master

kdb5_util location

SBINDIR/kdb5_util

kprop location

SBINDIR/kprop

kpropd ACL file

LOCALSTATEDIR/krb5kdc/kpropd.acl

kprop port

754

KPROP_PORT

Default paths for Unix-like systems¶

On Unix-like systems, some paths used by MIT krb5 depend on parameters chosen at build time. For a custom build, these paths default to subdirectories of /usr/local. When MIT krb5 is integrated into an operating system, the paths are generally chosen to match the operating system’s filesystem layout.

Description

Symbolic name

Custom build path

Typical OS path

User programs

BINDIR

/usr/local/bin

/usr/bin

Libraries and plugins

LIBDIR

/usr/local/lib

/usr/lib

Parent of KDC state dir

LOCALSTATEDIR

/usr/local/var

/var

Parent of KDC runtime dir

RUNSTATEDIR

/usr/local/var/run

/run

Administrative programs

SBINDIR

/usr/local/sbin

/usr/sbin

Alternate krb5.conf dir

SYSCONFDIR

/usr/local/etc

/etc

Default ccache name

DEFCCNAME

FILE:/tmp/krb5cc_%{uid}

FILE:/tmp/krb5cc_%{uid}

Default keytab name

DEFKTNAME

FILE:/etc/krb5.keytab

FILE:/etc/krb5.keytab

Default PKCS11 module

PKCS11_MODNAME

opensc-pkcs11.so

opensc-pkcs11.so

The default client keytab name (DEFCKTNAME) typically defaults to FILE:/usr/local/var/krb5/user/%{euid}/client.keytab for a custom build. A native build will typically use a path which will vary according to the operating system’s layout of /var.

krb5-1.22.1/doc/html/mitK5license.html0000664000175000017500000023601515051422713017304 0ustar ghudsonghudson MIT Kerberos License information — MIT Kerberos Documentation

MIT Kerberos License information¶

Copyright © 1985-2025 by the Massachusetts Institute of Technology.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Downloading of this software may constitute an export of cryptographic software from the United States of America that is subject to the United States Export Administration Regulations (EAR), 15 CFR 730-774. Additional laws or regulations may apply. It is the responsibility of the person or entity contemplating export to comply with all applicable export laws and regulations, including obtaining any required license from the U.S. government.

The U.S. government prohibits export of encryption source code to certain countries and individuals, including, but not limited to, the countries of Cuba, Iran, North Korea, Sudan, Syria, and residents and nationals of those countries.

Documentation components of this software distribution are licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. (https://creativecommons.org/licenses/by-sa/3.0/)

Individual source code files are copyright MIT, Cygnus Support, Novell, OpenVision Technologies, Oracle, Red Hat, Sun Microsystems, FundsXpress, and others.

Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, and Zephyr are trademarks of the Massachusetts Institute of Technology (MIT). No commercial use of these trademarks may be made without prior written permission of MIT.

“Commercial use†means use of a name in a product or other for-profit manner. It does NOT prevent a commercial firm from referring to the MIT trademarks in order to convey information (although in doing so, recognition of their trademark status should be given).


The following copyright and permission notice applies to the OpenVision Kerberos Administration system located in kadmin/create, kadmin/dbutil, kadmin/passwd, kadmin/server, lib/kadm5, and portions of lib/rpc:

Copyright, OpenVision Technologies, Inc., 1993-1996, All Rights Reserved

WARNING: Retrieving the OpenVision Kerberos Administration system source code, as described below, indicates your acceptance of the following terms. If you do not agree to the following terms, do not retrieve the OpenVision Kerberos administration system.

You may freely use and distribute the Source Code and Object Code compiled from it, with or without modification, but this Source Code is provided to you “AS IS†EXCLUSIVE OF ANY WARRANTY, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY OTHER REASON.

OpenVision retains all copyrights in the donated Source Code. OpenVision also retains copyright to derivative works of the Source Code, whether created by OpenVision or by a third party. The OpenVision copyright notice must be preserved if derivative works are made based on the donated Source Code.

OpenVision Technologies, Inc. has donated this Kerberos Administration system to MIT for inclusion in the standard Kerberos 5 distribution. This donation underscores our commitment to continuing Kerberos technology development and our gratitude for the valuable work which has been performed by MIT and the Kerberos community.


Portions contributed by Matt Crawford crawdad@fnal.gov were work performed at Fermi National Accelerator Laboratory, which is operated by Universities Research Association, Inc., under contract DE-AC02-76CHO3000 with the U.S. Department of Energy.


Portions of src/lib/crypto have the following copyright:

Copyright © 1998 by the FundsXpress, INC.

All rights reserved.

Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting.

WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of FundsXpress. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. FundsXpress makes no representations about the suitability of this software for any purpose. It is provided “as is†without express or implied warranty.

THIS SOFTWARE IS PROVIDED “AS IS†AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.


The implementation of the AES encryption algorithm in src/lib/crypto/builtin/aes has the following copyright:

Copyright © 1998-2013, Brian Gladman, Worcester, UK. All
rights reserved.

The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that:

source code distributions include the above copyright notice, this list of conditions and the following disclaimer;

binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation.

This software is provided ‘as is’ with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose.


Portions contributed by Red Hat, including the pre-authentication plug-in framework and the NSS crypto implementation, contain the following copyright:

Copyright © 2006 Red Hat, Inc.
Portions copyright © 2006 Massachusetts Institute of Technology
All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • Neither the name of Red Hat, Inc., nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


The bundled verto source code is subject to the following license:

Copyright 2011 Red Hat, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Softwareâ€), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS ISâ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


The MS-KKDCP client implementation has the following copyright:

Copyright 2013,2014 Red Hat, Inc.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


The implementations of GSSAPI mechglue in GSSAPI-SPNEGO in src/lib/gssapi, including the following files:

lib/gssapi/generic/gssapi_err_generic.et
lib/gssapi/mechglue/g_accept_sec_context.c
lib/gssapi/mechglue/g_acquire_cred.c
lib/gssapi/mechglue/g_canon_name.c
lib/gssapi/mechglue/g_compare_name.c
lib/gssapi/mechglue/g_context_time.c
lib/gssapi/mechglue/g_delete_sec_context.c
lib/gssapi/mechglue/g_dsp_name.c
lib/gssapi/mechglue/g_dsp_status.c
lib/gssapi/mechglue/g_dup_name.c
lib/gssapi/mechglue/g_exp_sec_context.c
lib/gssapi/mechglue/g_export_name.c
lib/gssapi/mechglue/g_glue.c
lib/gssapi/mechglue/g_imp_name.c
lib/gssapi/mechglue/g_imp_sec_context.c
lib/gssapi/mechglue/g_init_sec_context.c
lib/gssapi/mechglue/g_initialize.c
lib/gssapi/mechglue/g_inquire_context.c
lib/gssapi/mechglue/g_inquire_cred.c
lib/gssapi/mechglue/g_inquire_names.c
lib/gssapi/mechglue/g_process_context.c
lib/gssapi/mechglue/g_rel_buffer.c
lib/gssapi/mechglue/g_rel_cred.c
lib/gssapi/mechglue/g_rel_name.c
lib/gssapi/mechglue/g_rel_oid_set.c
lib/gssapi/mechglue/g_seal.c
lib/gssapi/mechglue/g_sign.c
lib/gssapi/mechglue/g_store_cred.c
lib/gssapi/mechglue/g_unseal.c
lib/gssapi/mechglue/g_userok.c
lib/gssapi/mechglue/g_utils.c
lib/gssapi/mechglue/g_verify.c
lib/gssapi/mechglue/gssd_pname_to_uid.c
lib/gssapi/mechglue/mglueP.h
lib/gssapi/mechglue/oid_ops.c
lib/gssapi/spnego/gssapiP_spnego.h
lib/gssapi/spnego/spnego_mech.c

and the initial implementation of incremental propagation, including the following new or changed files:

include/iprop_hdr.h
kadmin/server/ipropd_svc.c
lib/kdb/iprop.x
lib/kdb/kdb_convert.c
lib/kdb/kdb_log.c
lib/kdb/kdb_log.h
lib/krb5/error_tables/kdb5_err.et
kprop/kpropd_rpc.c
kprop/kproplog.c

are subject to the following license:

Copyright © 2004 Sun Microsystems, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Softwareâ€), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS ISâ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Kerberos V5 includes documentation and software developed at the University of California at Berkeley, which includes this copyright notice:

Copyright © 1983 Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Portions contributed by Novell, Inc., including the LDAP database backend, are subject to the following license:

Copyright © 2004-2005, Novell, Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • The copyright holder’s name is not used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Portions funded by Sandia National Laboratory and developed by the University of Michigan’s Center for Information Technology Integration, including the PKINIT implementation, are subject to the following license:

COPYRIGHT © 2006-2007
THE REGENTS OF THE UNIVERSITY OF MICHIGAN
ALL RIGHTS RESERVED

Permission is granted to use, copy, create derivative works and redistribute this software and such derivative works for any purpose, so long as the name of The University of Michigan is not used in any advertising or publicity pertaining to the use of distribution of this software without specific, written prior authorization. If the above copyright notice or any other identification of the University of Michigan is included in any copy of any portion of this software, then the disclaimer below must also be included.

THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.


The pkcs11.h file included in the PKINIT code has the following license:

Copyright 2006 g10 Code GmbH
Copyright 2006 Andreas Jellinghaus

This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved.

This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Portions contributed by Apple Inc. are subject to the following license:

Copyright 2004-2008 Apple Inc. All Rights Reserved.

Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting.

WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Apple Inc. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Apple Inc. makes no representations about the suitability of this software for any purpose. It is provided “as is†without express or implied warranty.

THIS SOFTWARE IS PROVIDED “AS IS†AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.


The implementations of UTF-8 string handling in src/util/support and src/lib/krb5/unicode are subject to the following copyright and permission notice:

The OpenLDAP Public License
Version 2.8, 17 August 2003

Redistribution and use of this software and associated documentation (“Softwareâ€), with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions in source form must retain copyright statements and notices,

  2. Redistributions in binary form must reproduce applicable copyright statements and notices, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution, and

  3. Redistributions must contain a verbatim copy of this document.

The OpenLDAP Foundation may revise this license from time to time. Each revision is distinguished by a version number. You may use this Software under terms of this license revision or under the terms of any subsequent revision of the license.

THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS CONTRIBUTORS “AS IS†AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S) OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The names of the authors and copyright holders must not be used in advertising or otherwise to promote the sale, use or other dealing in this Software without specific, written prior permission. Title to copyright in this Software shall at all times remain with copyright holders.

OpenLDAP is a registered trademark of the OpenLDAP Foundation.

Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, California, USA. All Rights Reserved. Permission to copy and distribute verbatim copies of this document is granted.


Marked test programs in src/lib/krb5/krb have the following copyright:

Copyright © 2006 Kungliga Tekniska Högskola
(Royal Institute of Technology, Stockholm, Sweden).
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. Neither the name of KTH nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


The KCM Mach RPC definition file used on macOS has the following copyright:

Copyright © 2009 Kungliga Tekniska Högskola
(Royal Institute of Technology, Stockholm, Sweden).
All rights reserved.

Portions Copyright © 2009 Apple Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. Neither the name of the Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Portions of the RPC implementation in src/lib/rpc and src/include/gssrpc have the following copyright and permission notice:

Copyright © 2010, Oracle America, Inc.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. Neither the name of the “Oracle America, Inc.†nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Copyright © 2006,2007,2009 NTT (Nippon Telegraph and Telephone Corporation). All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer as the first lines of this file unmodified.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY NTT “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Copyright 2000 by Carnegie Mellon University

All Rights Reserved

Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Carnegie Mellon University not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.

CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.


Copyright © 2002 Naval Research Laboratory (NRL/CCS)

Permission to use, copy, modify and distribute this software and its documentation is hereby granted, provided that both the copyright notice and this permission notice appear in all copies of the software, derivative works or modified versions, and any portions thereof.

NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS “AS IS†CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.


Copyright © 2022 United States Government as represented by the Secretary of the Navy. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Copyright © 1991, 1992, 1994 by Cygnus Support.

Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Cygnus Support makes no representations about the suitability of this software for any purpose. It is provided “as is†without express or implied warranty.


Copyright © 2006 Secure Endpoints Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Softwareâ€), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS ISâ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Copyright © 1994 by the University of Southern California

EXPORT OF THIS SOFTWARE from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting.

WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute this software and its documentation in source and binary forms is hereby granted, provided that any documentation or other materials related to such distribution or use acknowledge that the software was developed by the University of Southern California.

DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED “AS ISâ€. The University of Southern California MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not limitation, the University of Southern California MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. The University of Southern California shall not be held liable for any liability nor for any direct, indirect, or consequential damages with respect to any claim by the user or distributor of the ksu software.


Copyright © 1995
The President and Fellows of Harvard University

This code is derived from software contributed to Harvard by Jeremy Rassen.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. All advertising materials mentioning features or use of this software must display the following acknowledgement:

    This product includes software developed by the University of California, Berkeley and its contributors.

  4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Copyright © 2008 by the Massachusetts Institute of Technology.
Copyright 1995 by Richard P. Basch. All Rights Reserved.
Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved.

Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting.

WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Richard P. Basch, Lehman Brothers and M.I.T. make no representations about the suitability of this software for any purpose. It is provided “as is†without express or implied warranty.


The following notice applies to src/lib/krb5/krb/strptime.c and src/include/k5-queue.h.

Copyright © 1997, 1998 The NetBSD Foundation, Inc.
All rights reserved.

This code was contributed to The NetBSD Foundation by Klaus Klein.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. All advertising materials mentioning features or use of this software must display the following acknowledgement:

    This product includes software developed by the NetBSD Foundation, Inc. and its contributors.

  4. Neither the name of The NetBSD Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


The following notice applies to Unicode library files in src/lib/krb5/unicode:

Copyright 1997, 1998, 1999 Computing Research Labs,
New Mexico State University

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Softwareâ€), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS ISâ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


The following notice applies to src/util/support/strlcpy.c:

Copyright © 1998 Todd C. Miller Todd.Miller@courtesan.com

Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED “AS IS†AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.


The following notice applies to src/util/profile/argv_parse.c and src/util/profile/argv_parse.h:

Copyright 1999 by Theodore Ts’o.

Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED “AS IS†AND THEODORE TS’O (THE AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn’t it sick that the U.S. culture of lawsuit-happy lawyers requires this kind of disclaimer?)


The following notice applies to portiions of src/lib/rpc and src/include/gssrpc:

Copyright © 2000 The Regents of the University of Michigan. All rights reserved.

Copyright © 2000 Dug Song dugsong@UMICH.EDU. All rights reserved, all wrongs reversed.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Implementations of the MD4 algorithm are subject to the following notice:

Copyright © 1990, RSA Data Security, Inc. All rights reserved.

License to copy and use this software is granted provided that it is identified as the “RSA Data Security, Inc. MD4 Message Digest Algorithm†in all material mentioning or referencing this software or this function.

License is also granted to make and use derivative works provided that such works are identified as “derived from the RSA Data Security, Inc. MD4 Message Digest Algorithm†in all material mentioning or referencing the derived work.

RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided “as is†without express or implied warranty of any kind.

These notices must be retained in any copies of any part of this documentation and/or software.


Implementations of the MD5 algorithm are subject to the following notice:

Copyright © 1990, RSA Data Security, Inc. All rights reserved.

License to copy and use this software is granted provided that it is identified as the “RSA Data Security, Inc. MD5 Message- Digest Algorithm†in all material mentioning or referencing this software or this function.

License is also granted to make and use derivative works provided that such works are identified as “derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm†in all material mentioning or referencing the derived work.

RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided “as is†without express or implied warranty of any kind.

These notices must be retained in any copies of any part of this documentation and/or software.


The following notice applies to src/lib/crypto/crypto_tests/t_mddriver.c:

Copyright © 1990-2, RSA Data Security, Inc. Created 1990. All rights reserved.

RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided “as is†without express or implied warranty of any kind.

These notices must be retained in any copies of any part of this documentation and/or software.


Portions of src/lib/krb5 are subject to the following notice:

Copyright © 1994 CyberSAFE Corporation.
Copyright 1990,1991,2007,2008 by the Massachusetts Institute of Technology.
All Rights Reserved.

Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting.

WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. Neither M.I.T., the Open Computing Security Group, nor CyberSAFE Corporation make any representations about the suitability of this software for any purpose. It is provided “as is†without express or implied warranty.


Portions contributed by PADL Software are subject to the following license:

Copyright (c) 2011, PADL Software Pty Ltd. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. Neither the name of PADL Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


The bundled libev source code is subject to the following license:

All files in libev are Copyright (C)2007,2008,2009 Marc Alexander Lehmann.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Alternatively, the contents of this package may be used under the terms of the GNU General Public License (“GPLâ€) version 2 or any later version, in which case the provisions of the GPL are applicable instead of the above. If you wish to allow the use of your version of this package only under the terms of the GPL and not to allow others to use your version of this file under the BSD license, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL in this and the other files of this package. If you do not delete the provisions above, a recipient may use your version of this file under either the BSD or the GPL.


Files copied from the Intel AESNI Sample Library are subject to the following license:

Copyright © 2010, Intel Corporation All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


The following notice applies to src/ccapi/common/win/OldCC/autolock.hxx:

Copyright (C) 1998 by Danilo Almeida. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


The following notice applies to portions of src/plugins/preauth/spake/edwards25519.c and src/plugins/preauth/spake/edwards25519_tables.h:

The MIT License (MIT)

Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file).

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Softwareâ€), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS ISâ€, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


The following notice applies to portions of src/plugins/preauth/spake/edwards25519.c:

Copyright (c) 2015-2016, Google Inc.

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED “AS IS†AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.


The following notice applies to files in src/tests/fuzzing:

Copyright (C) 2024 by Arjun. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

krb5-1.22.1/doc/html/genindex-A.html0000664000175000017500000001663015051422714016727 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/searchindex.js0000664000175000017500000333345615051422714016730 0ustar ghudsonghudsonSearch.setIndex({"docnames": ["about", "admin/admin_commands/index", "admin/admin_commands/k5srvutil", "admin/admin_commands/kadmin_local", "admin/admin_commands/kadmind", "admin/admin_commands/kdb5_ldap_util", "admin/admin_commands/kdb5_util", "admin/admin_commands/kprop", "admin/admin_commands/kpropd", "admin/admin_commands/kproplog", "admin/admin_commands/krb5kdc", "admin/admin_commands/ktutil", "admin/admin_commands/sserver", "admin/advanced/index", "admin/advanced/retiring-des", "admin/appl_servers", "admin/auth_indicator", "admin/backup_host", "admin/conf_files/index", "admin/conf_files/kadm5_acl", "admin/conf_files/kdc_conf", "admin/conf_files/krb5_conf", "admin/conf_ldap", "admin/database", "admin/dbtypes", "admin/dictionary", "admin/enctypes", "admin/env_variables", "admin/host_config", "admin/https", "admin/index", "admin/install", "admin/install_appl_srv", "admin/install_clients", "admin/install_kdc", "admin/lockout", "admin/otp", "admin/pkinit", "admin/princ_dns", "admin/realm_config", "admin/spake", "admin/troubleshoot", "admin/various_envs", "appdev/gssapi", "appdev/h5l_mit_apidiff", "appdev/index", "appdev/init_creds", "appdev/princ_handle", "appdev/refs/api/index", "appdev/refs/api/krb5_425_conv_principal", "appdev/refs/api/krb5_524_conv_principal", "appdev/refs/api/krb5_524_convert_creds", "appdev/refs/api/krb5_address_compare", "appdev/refs/api/krb5_address_order", "appdev/refs/api/krb5_address_search", "appdev/refs/api/krb5_allow_weak_crypto", "appdev/refs/api/krb5_aname_to_localname", "appdev/refs/api/krb5_anonymous_principal", "appdev/refs/api/krb5_anonymous_realm", "appdev/refs/api/krb5_appdefault_boolean", "appdev/refs/api/krb5_appdefault_string", "appdev/refs/api/krb5_auth_con_free", "appdev/refs/api/krb5_auth_con_genaddrs", "appdev/refs/api/krb5_auth_con_get_checksum_func", "appdev/refs/api/krb5_auth_con_getaddrs", "appdev/refs/api/krb5_auth_con_getauthenticator", "appdev/refs/api/krb5_auth_con_getflags", "appdev/refs/api/krb5_auth_con_getkey", "appdev/refs/api/krb5_auth_con_getkey_k", "appdev/refs/api/krb5_auth_con_getlocalseqnumber", "appdev/refs/api/krb5_auth_con_getlocalsubkey", "appdev/refs/api/krb5_auth_con_getrcache", "appdev/refs/api/krb5_auth_con_getrecvsubkey", "appdev/refs/api/krb5_auth_con_getrecvsubkey_k", "appdev/refs/api/krb5_auth_con_getremoteseqnumber", "appdev/refs/api/krb5_auth_con_getremotesubkey", "appdev/refs/api/krb5_auth_con_getsendsubkey", "appdev/refs/api/krb5_auth_con_getsendsubkey_k", "appdev/refs/api/krb5_auth_con_init", "appdev/refs/api/krb5_auth_con_initivector", "appdev/refs/api/krb5_auth_con_set_checksum_func", "appdev/refs/api/krb5_auth_con_set_req_cksumtype", "appdev/refs/api/krb5_auth_con_setaddrs", "appdev/refs/api/krb5_auth_con_setflags", "appdev/refs/api/krb5_auth_con_setports", "appdev/refs/api/krb5_auth_con_setrcache", "appdev/refs/api/krb5_auth_con_setrecvsubkey", "appdev/refs/api/krb5_auth_con_setrecvsubkey_k", "appdev/refs/api/krb5_auth_con_setsendsubkey", "appdev/refs/api/krb5_auth_con_setsendsubkey_k", "appdev/refs/api/krb5_auth_con_setuseruserkey", "appdev/refs/api/krb5_build_principal", "appdev/refs/api/krb5_build_principal_alloc_va", "appdev/refs/api/krb5_build_principal_ext", "appdev/refs/api/krb5_build_principal_va", "appdev/refs/api/krb5_c_block_size", "appdev/refs/api/krb5_c_checksum_length", "appdev/refs/api/krb5_c_crypto_length", "appdev/refs/api/krb5_c_crypto_length_iov", "appdev/refs/api/krb5_c_decrypt", "appdev/refs/api/krb5_c_decrypt_iov", "appdev/refs/api/krb5_c_derive_prfplus", "appdev/refs/api/krb5_c_encrypt", "appdev/refs/api/krb5_c_encrypt_iov", "appdev/refs/api/krb5_c_encrypt_length", "appdev/refs/api/krb5_c_enctype_compare", "appdev/refs/api/krb5_c_free_state", "appdev/refs/api/krb5_c_fx_cf2_simple", "appdev/refs/api/krb5_c_init_state", "appdev/refs/api/krb5_c_is_coll_proof_cksum", "appdev/refs/api/krb5_c_is_keyed_cksum", "appdev/refs/api/krb5_c_keyed_checksum_types", "appdev/refs/api/krb5_c_keylengths", "appdev/refs/api/krb5_c_make_checksum", "appdev/refs/api/krb5_c_make_checksum_iov", "appdev/refs/api/krb5_c_make_random_key", "appdev/refs/api/krb5_c_padding_length", "appdev/refs/api/krb5_c_prf", "appdev/refs/api/krb5_c_prf_length", "appdev/refs/api/krb5_c_prfplus", "appdev/refs/api/krb5_c_random_add_entropy", "appdev/refs/api/krb5_c_random_make_octets", "appdev/refs/api/krb5_c_random_os_entropy", "appdev/refs/api/krb5_c_random_seed", "appdev/refs/api/krb5_c_random_to_key", "appdev/refs/api/krb5_c_string_to_key", "appdev/refs/api/krb5_c_string_to_key_with_params", "appdev/refs/api/krb5_c_valid_cksumtype", "appdev/refs/api/krb5_c_valid_enctype", "appdev/refs/api/krb5_c_verify_checksum", "appdev/refs/api/krb5_c_verify_checksum_iov", "appdev/refs/api/krb5_calculate_checksum", "appdev/refs/api/krb5_cc_cache_match", "appdev/refs/api/krb5_cc_close", "appdev/refs/api/krb5_cc_copy_creds", "appdev/refs/api/krb5_cc_default", "appdev/refs/api/krb5_cc_default_name", "appdev/refs/api/krb5_cc_destroy", "appdev/refs/api/krb5_cc_dup", "appdev/refs/api/krb5_cc_end_seq_get", "appdev/refs/api/krb5_cc_gen_new", "appdev/refs/api/krb5_cc_get_config", "appdev/refs/api/krb5_cc_get_flags", "appdev/refs/api/krb5_cc_get_full_name", "appdev/refs/api/krb5_cc_get_name", "appdev/refs/api/krb5_cc_get_principal", "appdev/refs/api/krb5_cc_get_type", "appdev/refs/api/krb5_cc_initialize", "appdev/refs/api/krb5_cc_move", "appdev/refs/api/krb5_cc_new_unique", "appdev/refs/api/krb5_cc_next_cred", "appdev/refs/api/krb5_cc_remove_cred", "appdev/refs/api/krb5_cc_resolve", "appdev/refs/api/krb5_cc_retrieve_cred", "appdev/refs/api/krb5_cc_select", "appdev/refs/api/krb5_cc_set_config", "appdev/refs/api/krb5_cc_set_default_name", "appdev/refs/api/krb5_cc_set_flags", "appdev/refs/api/krb5_cc_start_seq_get", "appdev/refs/api/krb5_cc_store_cred", "appdev/refs/api/krb5_cc_support_switch", "appdev/refs/api/krb5_cc_switch", "appdev/refs/api/krb5_cccol_cursor_free", "appdev/refs/api/krb5_cccol_cursor_new", "appdev/refs/api/krb5_cccol_cursor_next", "appdev/refs/api/krb5_cccol_have_content", "appdev/refs/api/krb5_change_password", "appdev/refs/api/krb5_check_clockskew", "appdev/refs/api/krb5_checksum_size", "appdev/refs/api/krb5_chpw_message", "appdev/refs/api/krb5_cksumtype_to_string", "appdev/refs/api/krb5_clear_error_message", "appdev/refs/api/krb5_copy_addresses", "appdev/refs/api/krb5_copy_authdata", "appdev/refs/api/krb5_copy_authenticator", "appdev/refs/api/krb5_copy_checksum", "appdev/refs/api/krb5_copy_context", "appdev/refs/api/krb5_copy_creds", "appdev/refs/api/krb5_copy_data", "appdev/refs/api/krb5_copy_error_message", "appdev/refs/api/krb5_copy_keyblock", "appdev/refs/api/krb5_copy_keyblock_contents", "appdev/refs/api/krb5_copy_principal", "appdev/refs/api/krb5_copy_ticket", "appdev/refs/api/krb5_decode_authdata_container", "appdev/refs/api/krb5_decode_ticket", "appdev/refs/api/krb5_decrypt", "appdev/refs/api/krb5_deltat_to_string", "appdev/refs/api/krb5_eblock_enctype", "appdev/refs/api/krb5_encode_authdata_container", "appdev/refs/api/krb5_encrypt", "appdev/refs/api/krb5_encrypt_size", "appdev/refs/api/krb5_enctype_to_name", "appdev/refs/api/krb5_enctype_to_string", "appdev/refs/api/krb5_expand_hostname", "appdev/refs/api/krb5_find_authdata", "appdev/refs/api/krb5_finish_key", "appdev/refs/api/krb5_finish_random_key", "appdev/refs/api/krb5_free_addresses", "appdev/refs/api/krb5_free_ap_rep_enc_part", "appdev/refs/api/krb5_free_authdata", "appdev/refs/api/krb5_free_authenticator", "appdev/refs/api/krb5_free_checksum", "appdev/refs/api/krb5_free_checksum_contents", "appdev/refs/api/krb5_free_cksumtypes", "appdev/refs/api/krb5_free_config_files", "appdev/refs/api/krb5_free_context", "appdev/refs/api/krb5_free_cred_contents", "appdev/refs/api/krb5_free_creds", "appdev/refs/api/krb5_free_data", "appdev/refs/api/krb5_free_data_contents", "appdev/refs/api/krb5_free_default_realm", "appdev/refs/api/krb5_free_enctypes", "appdev/refs/api/krb5_free_error", "appdev/refs/api/krb5_free_error_message", "appdev/refs/api/krb5_free_host_realm", "appdev/refs/api/krb5_free_keyblock", "appdev/refs/api/krb5_free_keyblock_contents", "appdev/refs/api/krb5_free_keytab_entry_contents", "appdev/refs/api/krb5_free_principal", "appdev/refs/api/krb5_free_string", "appdev/refs/api/krb5_free_tgt_creds", "appdev/refs/api/krb5_free_ticket", "appdev/refs/api/krb5_free_unparsed_name", "appdev/refs/api/krb5_fwd_tgt_creds", "appdev/refs/api/krb5_get_credentials", "appdev/refs/api/krb5_get_credentials_renew", "appdev/refs/api/krb5_get_credentials_validate", "appdev/refs/api/krb5_get_default_config_files", "appdev/refs/api/krb5_get_default_realm", "appdev/refs/api/krb5_get_error_message", "appdev/refs/api/krb5_get_etype_info", "appdev/refs/api/krb5_get_fallback_host_realm", "appdev/refs/api/krb5_get_host_realm", "appdev/refs/api/krb5_get_in_tkt_with_keytab", "appdev/refs/api/krb5_get_in_tkt_with_password", "appdev/refs/api/krb5_get_in_tkt_with_skey", "appdev/refs/api/krb5_get_init_creds_keytab", "appdev/refs/api/krb5_get_init_creds_opt_alloc", "appdev/refs/api/krb5_get_init_creds_opt_free", "appdev/refs/api/krb5_get_init_creds_opt_get_fast_flags", "appdev/refs/api/krb5_get_init_creds_opt_init", "appdev/refs/api/krb5_get_init_creds_opt_set_address_list", "appdev/refs/api/krb5_get_init_creds_opt_set_anonymous", "appdev/refs/api/krb5_get_init_creds_opt_set_canonicalize", "appdev/refs/api/krb5_get_init_creds_opt_set_change_password_prompt", "appdev/refs/api/krb5_get_init_creds_opt_set_etype_list", "appdev/refs/api/krb5_get_init_creds_opt_set_expire_callback", "appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache", "appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache_name", "appdev/refs/api/krb5_get_init_creds_opt_set_fast_flags", "appdev/refs/api/krb5_get_init_creds_opt_set_forwardable", "appdev/refs/api/krb5_get_init_creds_opt_set_in_ccache", "appdev/refs/api/krb5_get_init_creds_opt_set_out_ccache", "appdev/refs/api/krb5_get_init_creds_opt_set_pa", "appdev/refs/api/krb5_get_init_creds_opt_set_pac_request", "appdev/refs/api/krb5_get_init_creds_opt_set_preauth_list", "appdev/refs/api/krb5_get_init_creds_opt_set_proxiable", "appdev/refs/api/krb5_get_init_creds_opt_set_renew_life", "appdev/refs/api/krb5_get_init_creds_opt_set_responder", "appdev/refs/api/krb5_get_init_creds_opt_set_salt", "appdev/refs/api/krb5_get_init_creds_opt_set_tkt_life", "appdev/refs/api/krb5_get_init_creds_password", "appdev/refs/api/krb5_get_permitted_enctypes", "appdev/refs/api/krb5_get_profile", "appdev/refs/api/krb5_get_prompt_types", "appdev/refs/api/krb5_get_renewed_creds", "appdev/refs/api/krb5_get_server_rcache", "appdev/refs/api/krb5_get_time_offsets", "appdev/refs/api/krb5_get_validated_creds", "appdev/refs/api/krb5_init_context", "appdev/refs/api/krb5_init_context_profile", "appdev/refs/api/krb5_init_creds_free", "appdev/refs/api/krb5_init_creds_get", "appdev/refs/api/krb5_init_creds_get_creds", "appdev/refs/api/krb5_init_creds_get_error", "appdev/refs/api/krb5_init_creds_get_times", "appdev/refs/api/krb5_init_creds_init", "appdev/refs/api/krb5_init_creds_set_keytab", "appdev/refs/api/krb5_init_creds_set_password", "appdev/refs/api/krb5_init_creds_set_service", "appdev/refs/api/krb5_init_creds_step", "appdev/refs/api/krb5_init_keyblock", "appdev/refs/api/krb5_init_random_key", "appdev/refs/api/krb5_init_secure_context", "appdev/refs/api/krb5_is_config_principal", "appdev/refs/api/krb5_is_referral_realm", "appdev/refs/api/krb5_is_thread_safe", "appdev/refs/api/krb5_k_create_key", "appdev/refs/api/krb5_k_decrypt", "appdev/refs/api/krb5_k_decrypt_iov", "appdev/refs/api/krb5_k_encrypt", "appdev/refs/api/krb5_k_encrypt_iov", "appdev/refs/api/krb5_k_free_key", "appdev/refs/api/krb5_k_key_enctype", "appdev/refs/api/krb5_k_key_keyblock", "appdev/refs/api/krb5_k_make_checksum", "appdev/refs/api/krb5_k_make_checksum_iov", "appdev/refs/api/krb5_k_prf", "appdev/refs/api/krb5_k_reference_key", "appdev/refs/api/krb5_k_verify_checksum", "appdev/refs/api/krb5_k_verify_checksum_iov", "appdev/refs/api/krb5_kdc_sign_ticket", "appdev/refs/api/krb5_kdc_verify_ticket", "appdev/refs/api/krb5_kt_add_entry", "appdev/refs/api/krb5_kt_client_default", "appdev/refs/api/krb5_kt_close", "appdev/refs/api/krb5_kt_default", "appdev/refs/api/krb5_kt_default_name", "appdev/refs/api/krb5_kt_dup", "appdev/refs/api/krb5_kt_end_seq_get", "appdev/refs/api/krb5_kt_free_entry", "appdev/refs/api/krb5_kt_get_entry", "appdev/refs/api/krb5_kt_get_name", "appdev/refs/api/krb5_kt_get_type", "appdev/refs/api/krb5_kt_have_content", "appdev/refs/api/krb5_kt_next_entry", "appdev/refs/api/krb5_kt_read_service_key", "appdev/refs/api/krb5_kt_remove_entry", "appdev/refs/api/krb5_kt_resolve", "appdev/refs/api/krb5_kt_start_seq_get", "appdev/refs/api/krb5_kuserok", "appdev/refs/api/krb5_make_authdata_kdc_issued", "appdev/refs/api/krb5_marshal_credentials", "appdev/refs/api/krb5_merge_authdata", "appdev/refs/api/krb5_mk_1cred", "appdev/refs/api/krb5_mk_error", "appdev/refs/api/krb5_mk_ncred", "appdev/refs/api/krb5_mk_priv", "appdev/refs/api/krb5_mk_rep", "appdev/refs/api/krb5_mk_rep_dce", "appdev/refs/api/krb5_mk_req", "appdev/refs/api/krb5_mk_req_extended", "appdev/refs/api/krb5_mk_safe", "appdev/refs/api/krb5_os_localaddr", "appdev/refs/api/krb5_pac_add_buffer", "appdev/refs/api/krb5_pac_free", "appdev/refs/api/krb5_pac_get_buffer", "appdev/refs/api/krb5_pac_get_client_info", "appdev/refs/api/krb5_pac_get_types", "appdev/refs/api/krb5_pac_init", "appdev/refs/api/krb5_pac_parse", "appdev/refs/api/krb5_pac_sign", "appdev/refs/api/krb5_pac_sign_ext", "appdev/refs/api/krb5_pac_verify", "appdev/refs/api/krb5_pac_verify_ext", "appdev/refs/api/krb5_parse_name", "appdev/refs/api/krb5_parse_name_flags", "appdev/refs/api/krb5_prepend_error_message", "appdev/refs/api/krb5_principal2salt", "appdev/refs/api/krb5_principal_compare", "appdev/refs/api/krb5_principal_compare_any_realm", "appdev/refs/api/krb5_principal_compare_flags", "appdev/refs/api/krb5_process_key", "appdev/refs/api/krb5_prompter_posix", "appdev/refs/api/krb5_random_key", "appdev/refs/api/krb5_rd_cred", "appdev/refs/api/krb5_rd_error", "appdev/refs/api/krb5_rd_priv", "appdev/refs/api/krb5_rd_rep", "appdev/refs/api/krb5_rd_rep_dce", "appdev/refs/api/krb5_rd_req", "appdev/refs/api/krb5_rd_safe", "appdev/refs/api/krb5_read_password", "appdev/refs/api/krb5_realm_compare", "appdev/refs/api/krb5_recvauth", "appdev/refs/api/krb5_recvauth_version", "appdev/refs/api/krb5_responder_get_challenge", "appdev/refs/api/krb5_responder_list_questions", "appdev/refs/api/krb5_responder_otp_challenge_free", "appdev/refs/api/krb5_responder_otp_get_challenge", "appdev/refs/api/krb5_responder_otp_set_answer", "appdev/refs/api/krb5_responder_pkinit_challenge_free", "appdev/refs/api/krb5_responder_pkinit_get_challenge", "appdev/refs/api/krb5_responder_pkinit_set_answer", "appdev/refs/api/krb5_responder_set_answer", "appdev/refs/api/krb5_salttype_to_string", "appdev/refs/api/krb5_sendauth", "appdev/refs/api/krb5_server_decrypt_ticket_keytab", "appdev/refs/api/krb5_set_default_realm", "appdev/refs/api/krb5_set_default_tgs_enctypes", "appdev/refs/api/krb5_set_error_message", "appdev/refs/api/krb5_set_kdc_recv_hook", "appdev/refs/api/krb5_set_kdc_send_hook", "appdev/refs/api/krb5_set_password", "appdev/refs/api/krb5_set_password_using_ccache", "appdev/refs/api/krb5_set_principal_realm", "appdev/refs/api/krb5_set_real_time", "appdev/refs/api/krb5_set_trace_callback", "appdev/refs/api/krb5_set_trace_filename", "appdev/refs/api/krb5_sname_match", "appdev/refs/api/krb5_sname_to_principal", "appdev/refs/api/krb5_string_to_cksumtype", "appdev/refs/api/krb5_string_to_deltat", "appdev/refs/api/krb5_string_to_enctype", "appdev/refs/api/krb5_string_to_key", "appdev/refs/api/krb5_string_to_salttype", "appdev/refs/api/krb5_string_to_timestamp", "appdev/refs/api/krb5_timeofday", "appdev/refs/api/krb5_timestamp_to_sfstring", "appdev/refs/api/krb5_timestamp_to_string", "appdev/refs/api/krb5_tkt_creds_free", "appdev/refs/api/krb5_tkt_creds_get", "appdev/refs/api/krb5_tkt_creds_get_creds", "appdev/refs/api/krb5_tkt_creds_get_times", "appdev/refs/api/krb5_tkt_creds_init", "appdev/refs/api/krb5_tkt_creds_step", "appdev/refs/api/krb5_unmarshal_credentials", "appdev/refs/api/krb5_unparse_name", "appdev/refs/api/krb5_unparse_name_ext", "appdev/refs/api/krb5_unparse_name_flags", "appdev/refs/api/krb5_unparse_name_flags_ext", "appdev/refs/api/krb5_us_timeofday", "appdev/refs/api/krb5_use_enctype", "appdev/refs/api/krb5_verify_authdata_kdc_issued", "appdev/refs/api/krb5_verify_checksum", "appdev/refs/api/krb5_verify_init_creds", "appdev/refs/api/krb5_verify_init_creds_opt_init", "appdev/refs/api/krb5_verify_init_creds_opt_set_ap_req_nofail", "appdev/refs/api/krb5_vprepend_error_message", "appdev/refs/api/krb5_vset_error_message", "appdev/refs/api/krb5_vwrap_error_message", "appdev/refs/api/krb5_wrap_error_message", "appdev/refs/index", "appdev/refs/macros/ADDRTYPE_ADDRPORT", "appdev/refs/macros/ADDRTYPE_CHAOS", "appdev/refs/macros/ADDRTYPE_DDP", "appdev/refs/macros/ADDRTYPE_DIRECTIONAL", "appdev/refs/macros/ADDRTYPE_INET", "appdev/refs/macros/ADDRTYPE_INET6", "appdev/refs/macros/ADDRTYPE_IPPORT", "appdev/refs/macros/ADDRTYPE_ISO", "appdev/refs/macros/ADDRTYPE_IS_LOCAL", "appdev/refs/macros/ADDRTYPE_NETBIOS", "appdev/refs/macros/ADDRTYPE_UNIXSOCK", "appdev/refs/macros/ADDRTYPE_XNS", "appdev/refs/macros/AD_TYPE_EXTERNAL", "appdev/refs/macros/AD_TYPE_FIELD_TYPE_MASK", "appdev/refs/macros/AD_TYPE_REGISTERED", "appdev/refs/macros/AD_TYPE_RESERVED", "appdev/refs/macros/AP_OPTS_CBT_FLAG", "appdev/refs/macros/AP_OPTS_ETYPE_NEGOTIATION", "appdev/refs/macros/AP_OPTS_MUTUAL_REQUIRED", "appdev/refs/macros/AP_OPTS_RESERVED", "appdev/refs/macros/AP_OPTS_USE_SESSION_KEY", "appdev/refs/macros/AP_OPTS_USE_SUBKEY", "appdev/refs/macros/AP_OPTS_WIRE_MASK", "appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA128", "appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA256", "appdev/refs/macros/CKSUMTYPE_CRC32", "appdev/refs/macros/CKSUMTYPE_DESCBC", "appdev/refs/macros/CKSUMTYPE_HMAC_MD5_ARCFOUR", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES128", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES256", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_DES3", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA256_128_AES128", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA384_192_AES256", "appdev/refs/macros/CKSUMTYPE_MD5_HMAC_ARCFOUR", "appdev/refs/macros/CKSUMTYPE_NIST_SHA", "appdev/refs/macros/CKSUMTYPE_RSA_MD4", "appdev/refs/macros/CKSUMTYPE_RSA_MD4_DES", "appdev/refs/macros/CKSUMTYPE_RSA_MD5", "appdev/refs/macros/CKSUMTYPE_RSA_MD5_DES", "appdev/refs/macros/CKSUMTYPE_SHA1", "appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA1_96", "appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA256_128", "appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA1_96", "appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA384_192", "appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC", "appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC_EXP", "appdev/refs/macros/ENCTYPE_CAMELLIA128_CTS_CMAC", "appdev/refs/macros/ENCTYPE_CAMELLIA256_CTS_CMAC", "appdev/refs/macros/ENCTYPE_DES3_CBC_ENV", "appdev/refs/macros/ENCTYPE_DES3_CBC_RAW", "appdev/refs/macros/ENCTYPE_DES3_CBC_SHA", "appdev/refs/macros/ENCTYPE_DES3_CBC_SHA1", "appdev/refs/macros/ENCTYPE_DES_CBC_CRC", "appdev/refs/macros/ENCTYPE_DES_CBC_MD4", "appdev/refs/macros/ENCTYPE_DES_CBC_MD5", "appdev/refs/macros/ENCTYPE_DES_CBC_RAW", "appdev/refs/macros/ENCTYPE_DES_HMAC_SHA1", "appdev/refs/macros/ENCTYPE_DSA_SHA1_CMS", "appdev/refs/macros/ENCTYPE_MD5_RSA_CMS", "appdev/refs/macros/ENCTYPE_NULL", "appdev/refs/macros/ENCTYPE_RC2_CBC_ENV", "appdev/refs/macros/ENCTYPE_RSA_ENV", "appdev/refs/macros/ENCTYPE_RSA_ES_OAEP_ENV", "appdev/refs/macros/ENCTYPE_SHA1_RSA_CMS", "appdev/refs/macros/ENCTYPE_UNKNOWN", "appdev/refs/macros/KDC_OPT_ALLOW_POSTDATE", "appdev/refs/macros/KDC_OPT_CANONICALIZE", "appdev/refs/macros/KDC_OPT_CNAME_IN_ADDL_TKT", "appdev/refs/macros/KDC_OPT_DISABLE_TRANSITED_CHECK", "appdev/refs/macros/KDC_OPT_ENC_TKT_IN_SKEY", "appdev/refs/macros/KDC_OPT_FORWARDABLE", "appdev/refs/macros/KDC_OPT_FORWARDED", "appdev/refs/macros/KDC_OPT_POSTDATED", "appdev/refs/macros/KDC_OPT_PROXIABLE", "appdev/refs/macros/KDC_OPT_PROXY", "appdev/refs/macros/KDC_OPT_RENEW", "appdev/refs/macros/KDC_OPT_RENEWABLE", "appdev/refs/macros/KDC_OPT_RENEWABLE_OK", "appdev/refs/macros/KDC_OPT_REQUEST_ANONYMOUS", "appdev/refs/macros/KDC_OPT_VALIDATE", "appdev/refs/macros/KDC_TKT_COMMON_MASK", "appdev/refs/macros/KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE", "appdev/refs/macros/KRB5_ANONYMOUS_PRINCSTR", "appdev/refs/macros/KRB5_ANONYMOUS_REALMSTR", "appdev/refs/macros/KRB5_AP_REP", "appdev/refs/macros/KRB5_AP_REQ", "appdev/refs/macros/KRB5_AS_REP", "appdev/refs/macros/KRB5_AS_REQ", "appdev/refs/macros/KRB5_AUTHDATA_AND_OR", "appdev/refs/macros/KRB5_AUTHDATA_AP_OPTIONS", "appdev/refs/macros/KRB5_AUTHDATA_AUTH_INDICATOR", "appdev/refs/macros/KRB5_AUTHDATA_CAMMAC", "appdev/refs/macros/KRB5_AUTHDATA_ETYPE_NEGOTIATION", "appdev/refs/macros/KRB5_AUTHDATA_FX_ARMOR", "appdev/refs/macros/KRB5_AUTHDATA_IF_RELEVANT", "appdev/refs/macros/KRB5_AUTHDATA_INITIAL_VERIFIED_CAS", "appdev/refs/macros/KRB5_AUTHDATA_KDC_ISSUED", "appdev/refs/macros/KRB5_AUTHDATA_MANDATORY_FOR_KDC", "appdev/refs/macros/KRB5_AUTHDATA_OSF_DCE", "appdev/refs/macros/KRB5_AUTHDATA_SESAME", "appdev/refs/macros/KRB5_AUTHDATA_SIGNTICKET", "appdev/refs/macros/KRB5_AUTHDATA_WIN2K_PAC", "appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_SEQUENCE", "appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_TIME", "appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR", "appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR", "appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR", "appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR", "appdev/refs/macros/KRB5_AUTH_CONTEXT_PERMIT_ALL", "appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_SEQUENCE", "appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_TIME", "appdev/refs/macros/KRB5_AUTH_CONTEXT_USE_SUBKEY", "appdev/refs/macros/KRB5_CRED", "appdev/refs/macros/KRB5_CRYPTO_TYPE_CHECKSUM", "appdev/refs/macros/KRB5_CRYPTO_TYPE_DATA", "appdev/refs/macros/KRB5_CRYPTO_TYPE_EMPTY", "appdev/refs/macros/KRB5_CRYPTO_TYPE_HEADER", "appdev/refs/macros/KRB5_CRYPTO_TYPE_PADDING", "appdev/refs/macros/KRB5_CRYPTO_TYPE_SIGN_ONLY", "appdev/refs/macros/KRB5_CRYPTO_TYPE_STREAM", "appdev/refs/macros/KRB5_CRYPTO_TYPE_TRAILER", "appdev/refs/macros/KRB5_CYBERSAFE_SECUREID", "appdev/refs/macros/KRB5_DOMAIN_X500_COMPRESS", "appdev/refs/macros/KRB5_ENCPADATA_REQ_ENC_PA_REP", "appdev/refs/macros/KRB5_ERROR", "appdev/refs/macros/KRB5_FAST_REQUIRED", "appdev/refs/macros/KRB5_GC_CACHED", "appdev/refs/macros/KRB5_GC_CANONICALIZE", "appdev/refs/macros/KRB5_GC_CONSTRAINED_DELEGATION", "appdev/refs/macros/KRB5_GC_FORWARDABLE", "appdev/refs/macros/KRB5_GC_NO_STORE", "appdev/refs/macros/KRB5_GC_NO_TRANSIT_CHECK", "appdev/refs/macros/KRB5_GC_USER_USER", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ANONYMOUS", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CANONICALIZE", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_FORWARDABLE", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PROXIABLE", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_SALT", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_TKT_LIFE", "appdev/refs/macros/KRB5_INIT_CONTEXT_KDC", "appdev/refs/macros/KRB5_INIT_CONTEXT_SECURE", "appdev/refs/macros/KRB5_INIT_CREDS_STEP_FLAG_CONTINUE", "appdev/refs/macros/KRB5_INT16_MAX", "appdev/refs/macros/KRB5_INT16_MIN", "appdev/refs/macros/KRB5_INT32_MAX", "appdev/refs/macros/KRB5_INT32_MIN", "appdev/refs/macros/KRB5_KEYUSAGE_AD_ITE", "appdev/refs/macros/KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM", "appdev/refs/macros/KRB5_KEYUSAGE_AD_MTE", "appdev/refs/macros/KRB5_KEYUSAGE_AD_SIGNEDPATH", "appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_CKSUM", "appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_ENCRYPT", "appdev/refs/macros/KRB5_KEYUSAGE_AP_REP_ENCPART", "appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH", "appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM", "appdev/refs/macros/KRB5_KEYUSAGE_AS_REP_ENCPART", "appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ", "appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS", "appdev/refs/macros/KRB5_KEYUSAGE_CAMMAC", "appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT", "appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_KDC", "appdev/refs/macros/KRB5_KEYUSAGE_FAST_ENC", "appdev/refs/macros/KRB5_KEYUSAGE_FAST_FINISHED", "appdev/refs/macros/KRB5_KEYUSAGE_FAST_REP", "appdev/refs/macros/KRB5_KEYUSAGE_FAST_REQ_CHKSUM", "appdev/refs/macros/KRB5_KEYUSAGE_FINISHED", "appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_MIC", "appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG", "appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV", "appdev/refs/macros/KRB5_KEYUSAGE_IAKERB_FINISHED", "appdev/refs/macros/KRB5_KEYUSAGE_KDC_REP_TICKET", "appdev/refs/macros/KRB5_KEYUSAGE_KRB_CRED_ENCPART", "appdev/refs/macros/KRB5_KEYUSAGE_KRB_ERROR_CKSUM", "appdev/refs/macros/KRB5_KEYUSAGE_KRB_PRIV_ENCPART", "appdev/refs/macros/KRB5_KEYUSAGE_KRB_SAFE_CKSUM", "appdev/refs/macros/KRB5_KEYUSAGE_PA_AS_FRESHNESS", "appdev/refs/macros/KRB5_KEYUSAGE_PA_FX_COOKIE", "appdev/refs/macros/KRB5_KEYUSAGE_PA_OTP_REQUEST", "appdev/refs/macros/KRB5_KEYUSAGE_PA_PKINIT_KX", "appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY", "appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST", "appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM", "appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID", "appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_RESPONSE", "appdev/refs/macros/KRB5_KEYUSAGE_SPAKE", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM", "appdev/refs/macros/KRB5_KPASSWD_ACCESSDENIED", "appdev/refs/macros/KRB5_KPASSWD_AUTHERROR", "appdev/refs/macros/KRB5_KPASSWD_BAD_VERSION", "appdev/refs/macros/KRB5_KPASSWD_HARDERROR", "appdev/refs/macros/KRB5_KPASSWD_INITIAL_FLAG_NEEDED", "appdev/refs/macros/KRB5_KPASSWD_MALFORMED", "appdev/refs/macros/KRB5_KPASSWD_SOFTERROR", "appdev/refs/macros/KRB5_KPASSWD_SUCCESS", "appdev/refs/macros/KRB5_LRQ_ALL_ACCT_EXPTIME", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_INITIAL", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_RENEWAL", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_REQ", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT_ISSUED", "appdev/refs/macros/KRB5_LRQ_ALL_PW_EXPTIME", "appdev/refs/macros/KRB5_LRQ_NONE", "appdev/refs/macros/KRB5_LRQ_ONE_ACCT_EXPTIME", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_INITIAL", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_RENEWAL", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_REQ", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT_ISSUED", "appdev/refs/macros/KRB5_LRQ_ONE_PW_EXPTIME", "appdev/refs/macros/KRB5_NT_ENTERPRISE_PRINCIPAL", "appdev/refs/macros/KRB5_NT_ENT_PRINCIPAL_AND_ID", "appdev/refs/macros/KRB5_NT_MS_PRINCIPAL", "appdev/refs/macros/KRB5_NT_MS_PRINCIPAL_AND_ID", "appdev/refs/macros/KRB5_NT_PRINCIPAL", "appdev/refs/macros/KRB5_NT_SMTP_NAME", "appdev/refs/macros/KRB5_NT_SRV_HST", "appdev/refs/macros/KRB5_NT_SRV_INST", "appdev/refs/macros/KRB5_NT_SRV_XHST", "appdev/refs/macros/KRB5_NT_UID", "appdev/refs/macros/KRB5_NT_UNKNOWN", "appdev/refs/macros/KRB5_NT_WELLKNOWN", "appdev/refs/macros/KRB5_NT_X500_PRINCIPAL", "appdev/refs/macros/KRB5_PAC_ATTRIBUTES_INFO", "appdev/refs/macros/KRB5_PAC_CLIENT_CLAIMS", "appdev/refs/macros/KRB5_PAC_CLIENT_INFO", "appdev/refs/macros/KRB5_PAC_CREDENTIALS_INFO", "appdev/refs/macros/KRB5_PAC_DELEGATION_INFO", "appdev/refs/macros/KRB5_PAC_DEVICE_CLAIMS", "appdev/refs/macros/KRB5_PAC_DEVICE_INFO", "appdev/refs/macros/KRB5_PAC_FULL_CHECKSUM", "appdev/refs/macros/KRB5_PAC_LOGON_INFO", "appdev/refs/macros/KRB5_PAC_PRIVSVR_CHECKSUM", "appdev/refs/macros/KRB5_PAC_REQUESTOR", "appdev/refs/macros/KRB5_PAC_SERVER_CHECKSUM", "appdev/refs/macros/KRB5_PAC_TICKET_CHECKSUM", "appdev/refs/macros/KRB5_PAC_UPN_DNS_INFO", "appdev/refs/macros/KRB5_PADATA_AFS3_SALT", "appdev/refs/macros/KRB5_PADATA_AP_REQ", "appdev/refs/macros/KRB5_PADATA_AS_CHECKSUM", "appdev/refs/macros/KRB5_PADATA_AS_FRESHNESS", "appdev/refs/macros/KRB5_PADATA_ENCRYPTED_CHALLENGE", "appdev/refs/macros/KRB5_PADATA_ENC_SANDIA_SECURID", "appdev/refs/macros/KRB5_PADATA_ENC_TIMESTAMP", "appdev/refs/macros/KRB5_PADATA_ENC_UNIX_TIME", "appdev/refs/macros/KRB5_PADATA_ETYPE_INFO", "appdev/refs/macros/KRB5_PADATA_ETYPE_INFO2", "appdev/refs/macros/KRB5_PADATA_FOR_USER", "appdev/refs/macros/KRB5_PADATA_FX_COOKIE", "appdev/refs/macros/KRB5_PADATA_FX_ERROR", "appdev/refs/macros/KRB5_PADATA_FX_FAST", "appdev/refs/macros/KRB5_PADATA_GET_FROM_TYPED_DATA", "appdev/refs/macros/KRB5_PADATA_NONE", "appdev/refs/macros/KRB5_PADATA_OSF_DCE", "appdev/refs/macros/KRB5_PADATA_OTP_CHALLENGE", "appdev/refs/macros/KRB5_PADATA_OTP_PIN_CHANGE", "appdev/refs/macros/KRB5_PADATA_OTP_REQUEST", "appdev/refs/macros/KRB5_PADATA_PAC_OPTIONS", "appdev/refs/macros/KRB5_PADATA_PAC_REQUEST", "appdev/refs/macros/KRB5_PADATA_PKINIT_KX", "appdev/refs/macros/KRB5_PADATA_PK_AS_REP", "appdev/refs/macros/KRB5_PADATA_PK_AS_REP_OLD", "appdev/refs/macros/KRB5_PADATA_PK_AS_REQ", "appdev/refs/macros/KRB5_PADATA_PK_AS_REQ_OLD", "appdev/refs/macros/KRB5_PADATA_PW_SALT", "appdev/refs/macros/KRB5_PADATA_REDHAT_IDP_OAUTH2", "appdev/refs/macros/KRB5_PADATA_REDHAT_PASSKEY", "appdev/refs/macros/KRB5_PADATA_REFERRAL", "appdev/refs/macros/KRB5_PADATA_S4U_X509_USER", "appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE", "appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE_2", "appdev/refs/macros/KRB5_PADATA_SAM_REDIRECT", "appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE", "appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE_2", "appdev/refs/macros/KRB5_PADATA_SESAME", "appdev/refs/macros/KRB5_PADATA_SPAKE", "appdev/refs/macros/KRB5_PADATA_SVR_REFERRAL_INFO", "appdev/refs/macros/KRB5_PADATA_TGS_REQ", "appdev/refs/macros/KRB5_PADATA_USE_SPECIFIED_KVNO", "appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_CASEFOLD", "appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_ENTERPRISE", "appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_IGNORE_REALM", "appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_UTF8", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_ENTERPRISE", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_IGNORE_REALM", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_DEF_REALM", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_REALM", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_REQUIRE_REALM", "appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_DISPLAY", "appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_NO_REALM", "appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_SHORT", "appdev/refs/macros/KRB5_PRIV", "appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD", "appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN", "appdev/refs/macros/KRB5_PROMPT_TYPE_PASSWORD", "appdev/refs/macros/KRB5_PROMPT_TYPE_PREAUTH", "appdev/refs/macros/KRB5_PVNO", "appdev/refs/macros/KRB5_REALM_BRANCH_CHAR", "appdev/refs/macros/KRB5_RECVAUTH_BADAUTHVERS", "appdev/refs/macros/KRB5_RECVAUTH_SKIP_VERSION", "appdev/refs/macros/KRB5_REFERRAL_REALM", "appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN", "appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN", "appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_NEXTOTP", "appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN", "appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC", "appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_DECIMAL", "appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL", "appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW", "appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY", "appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED", "appdev/refs/macros/KRB5_RESPONDER_QUESTION_OTP", "appdev/refs/macros/KRB5_RESPONDER_QUESTION_PASSWORD", "appdev/refs/macros/KRB5_RESPONDER_QUESTION_PKINIT", "appdev/refs/macros/KRB5_SAFE", "appdev/refs/macros/KRB5_SAM_MUST_PK_ENCRYPT_SAD", "appdev/refs/macros/KRB5_SAM_SEND_ENCRYPTED_SAD", "appdev/refs/macros/KRB5_SAM_USE_SAD_AS_KEY", "appdev/refs/macros/KRB5_TC_MATCH_2ND_TKT", "appdev/refs/macros/KRB5_TC_MATCH_AUTHDATA", "appdev/refs/macros/KRB5_TC_MATCH_FLAGS", "appdev/refs/macros/KRB5_TC_MATCH_FLAGS_EXACT", "appdev/refs/macros/KRB5_TC_MATCH_IS_SKEY", "appdev/refs/macros/KRB5_TC_MATCH_KTYPE", "appdev/refs/macros/KRB5_TC_MATCH_SRV_NAMEONLY", "appdev/refs/macros/KRB5_TC_MATCH_TIMES", "appdev/refs/macros/KRB5_TC_MATCH_TIMES_EXACT", "appdev/refs/macros/KRB5_TC_NOTICKET", "appdev/refs/macros/KRB5_TC_OPENCLOSE", "appdev/refs/macros/KRB5_TC_SUPPORTED_KTYPES", "appdev/refs/macros/KRB5_TGS_NAME", "appdev/refs/macros/KRB5_TGS_NAME_SIZE", "appdev/refs/macros/KRB5_TGS_REP", "appdev/refs/macros/KRB5_TGS_REQ", "appdev/refs/macros/KRB5_TKT_CREDS_STEP_FLAG_CONTINUE", "appdev/refs/macros/KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL", "appdev/refs/macros/KRB5_WELLKNOWN_NAMESTR", "appdev/refs/macros/LR_TYPE_INTERPRETATION_MASK", "appdev/refs/macros/LR_TYPE_THIS_SERVER_ONLY", "appdev/refs/macros/MAX_KEYTAB_NAME_LEN", "appdev/refs/macros/MSEC_DIRBIT", "appdev/refs/macros/MSEC_VAL_MASK", "appdev/refs/macros/SALT_TYPE_AFS_LENGTH", "appdev/refs/macros/SALT_TYPE_NO_LENGTH", "appdev/refs/macros/THREEPARAMOPEN", "appdev/refs/macros/TKT_FLG_ANONYMOUS", "appdev/refs/macros/TKT_FLG_ENC_PA_REP", "appdev/refs/macros/TKT_FLG_FORWARDABLE", "appdev/refs/macros/TKT_FLG_FORWARDED", "appdev/refs/macros/TKT_FLG_HW_AUTH", "appdev/refs/macros/TKT_FLG_INITIAL", "appdev/refs/macros/TKT_FLG_INVALID", "appdev/refs/macros/TKT_FLG_MAY_POSTDATE", "appdev/refs/macros/TKT_FLG_OK_AS_DELEGATE", "appdev/refs/macros/TKT_FLG_POSTDATED", "appdev/refs/macros/TKT_FLG_PRE_AUTH", "appdev/refs/macros/TKT_FLG_PROXIABLE", "appdev/refs/macros/TKT_FLG_PROXY", "appdev/refs/macros/TKT_FLG_RENEWABLE", "appdev/refs/macros/TKT_FLG_TRANSIT_POLICY_CHECKED", "appdev/refs/macros/VALID_INT_BITS", "appdev/refs/macros/VALID_UINT_BITS", "appdev/refs/macros/index", "appdev/refs/macros/krb524_convert_creds_kdc", "appdev/refs/macros/krb524_init_ets", "appdev/refs/macros/krb5_const", "appdev/refs/macros/krb5_princ_component", "appdev/refs/macros/krb5_princ_name", "appdev/refs/macros/krb5_princ_realm", "appdev/refs/macros/krb5_princ_set_realm", "appdev/refs/macros/krb5_princ_set_realm_data", "appdev/refs/macros/krb5_princ_set_realm_length", "appdev/refs/macros/krb5_princ_size", "appdev/refs/macros/krb5_princ_type", "appdev/refs/macros/krb5_roundup", "appdev/refs/macros/krb5_x", "appdev/refs/macros/krb5_xc", "appdev/refs/types/index", "appdev/refs/types/krb5_address", "appdev/refs/types/krb5_addrtype", "appdev/refs/types/krb5_ap_rep", "appdev/refs/types/krb5_ap_rep_enc_part", "appdev/refs/types/krb5_ap_req", "appdev/refs/types/krb5_auth_context", "appdev/refs/types/krb5_authdata", "appdev/refs/types/krb5_authdatatype", "appdev/refs/types/krb5_authenticator", "appdev/refs/types/krb5_boolean", "appdev/refs/types/krb5_cc_cursor", "appdev/refs/types/krb5_ccache", "appdev/refs/types/krb5_cccol_cursor", "appdev/refs/types/krb5_checksum", "appdev/refs/types/krb5_cksumtype", "appdev/refs/types/krb5_const_pointer", "appdev/refs/types/krb5_const_principal", "appdev/refs/types/krb5_context", "appdev/refs/types/krb5_cred", "appdev/refs/types/krb5_cred_enc_part", "appdev/refs/types/krb5_cred_info", "appdev/refs/types/krb5_creds", "appdev/refs/types/krb5_crypto_iov", "appdev/refs/types/krb5_cryptotype", "appdev/refs/types/krb5_data", "appdev/refs/types/krb5_deltat", "appdev/refs/types/krb5_enc_data", "appdev/refs/types/krb5_enc_kdc_rep_part", "appdev/refs/types/krb5_enc_tkt_part", "appdev/refs/types/krb5_encrypt_block", "appdev/refs/types/krb5_enctype", "appdev/refs/types/krb5_error", "appdev/refs/types/krb5_error_code", "appdev/refs/types/krb5_expire_callback_func", "appdev/refs/types/krb5_flags", "appdev/refs/types/krb5_get_init_creds_opt", "appdev/refs/types/krb5_gic_opt_pa_data", "appdev/refs/types/krb5_init_creds_context", "appdev/refs/types/krb5_int16", "appdev/refs/types/krb5_int32", "appdev/refs/types/krb5_kdc_rep", "appdev/refs/types/krb5_kdc_req", "appdev/refs/types/krb5_key", "appdev/refs/types/krb5_keyblock", "appdev/refs/types/krb5_keytab", "appdev/refs/types/krb5_keytab_entry", "appdev/refs/types/krb5_keyusage", "appdev/refs/types/krb5_kt_cursor", "appdev/refs/types/krb5_kvno", "appdev/refs/types/krb5_last_req_entry", "appdev/refs/types/krb5_magic", "appdev/refs/types/krb5_mk_req_checksum_func", "appdev/refs/types/krb5_msgtype", "appdev/refs/types/krb5_octet", "appdev/refs/types/krb5_pa_data", "appdev/refs/types/krb5_pa_pac_req", "appdev/refs/types/krb5_pa_server_referral_data", "appdev/refs/types/krb5_pa_svr_referral_data", "appdev/refs/types/krb5_pac", "appdev/refs/types/krb5_pointer", "appdev/refs/types/krb5_post_recv_fn", "appdev/refs/types/krb5_pre_send_fn", "appdev/refs/types/krb5_preauthtype", "appdev/refs/types/krb5_principal", "appdev/refs/types/krb5_principal_data", "appdev/refs/types/krb5_prompt", "appdev/refs/types/krb5_prompt_type", "appdev/refs/types/krb5_prompter_fct", "appdev/refs/types/krb5_pwd_data", "appdev/refs/types/krb5_rcache", "appdev/refs/types/krb5_replay_data", "appdev/refs/types/krb5_responder_context", "appdev/refs/types/krb5_responder_fn", "appdev/refs/types/krb5_responder_otp_challenge", "appdev/refs/types/krb5_responder_otp_tokeninfo", "appdev/refs/types/krb5_responder_pkinit_challenge", "appdev/refs/types/krb5_responder_pkinit_identity", "appdev/refs/types/krb5_response", "appdev/refs/types/krb5_ticket", "appdev/refs/types/krb5_ticket_times", "appdev/refs/types/krb5_timestamp", "appdev/refs/types/krb5_tkt_authent", "appdev/refs/types/krb5_tkt_creds_context", "appdev/refs/types/krb5_trace_callback", "appdev/refs/types/krb5_trace_info", "appdev/refs/types/krb5_transited", "appdev/refs/types/krb5_typed_data", "appdev/refs/types/krb5_ui_2", "appdev/refs/types/krb5_ui_4", "appdev/refs/types/krb5_verify_init_creds_opt", "appdev/refs/types/passwd_phrase_element", "appdev/y2038", "basic/ccache_def", "basic/date_format", "basic/index", "basic/keytab_def", "basic/rcache_def", "basic/stash_file_def", "build/directory_org", "build/doing_build", "build/index", "build/options2configure", "build/osconf", "build_this", "copyright", "formats/ccache_file_format", "formats/cookie", "formats/database_formats", "formats/freshness_token", "formats/index", "formats/keytab_file_format", "formats/rcache_file_format", "index", "mitK5defaults", "mitK5features", "mitK5license", "plugindev/ccselect", "plugindev/certauth", "plugindev/clpreauth", "plugindev/general", "plugindev/gssapi", "plugindev/hostrealm", "plugindev/index", "plugindev/internal", "plugindev/kadm5_auth", "plugindev/kadm5_hook", "plugindev/kdcpolicy", "plugindev/kdcpreauth", "plugindev/localauth", "plugindev/locate", "plugindev/profile", "plugindev/pwqual", "resources", "user/index", "user/pwd_mgmt", "user/tkt_mgmt", "user/user_commands/index", "user/user_commands/kdestroy", "user/user_commands/kinit", "user/user_commands/klist", "user/user_commands/kpasswd", "user/user_commands/krb5-config", "user/user_commands/ksu", "user/user_commands/kswitch", "user/user_commands/kvno", "user/user_commands/sclient", "user/user_config/index", "user/user_config/k5identity", "user/user_config/k5login", "user/user_config/kerberos"], "filenames": ["about.rst", "admin/admin_commands/index.rst", "admin/admin_commands/k5srvutil.rst", "admin/admin_commands/kadmin_local.rst", "admin/admin_commands/kadmind.rst", "admin/admin_commands/kdb5_ldap_util.rst", "admin/admin_commands/kdb5_util.rst", "admin/admin_commands/kprop.rst", "admin/admin_commands/kpropd.rst", "admin/admin_commands/kproplog.rst", "admin/admin_commands/krb5kdc.rst", "admin/admin_commands/ktutil.rst", "admin/admin_commands/sserver.rst", "admin/advanced/index.rst", "admin/advanced/retiring-des.rst", "admin/appl_servers.rst", "admin/auth_indicator.rst", "admin/backup_host.rst", "admin/conf_files/index.rst", "admin/conf_files/kadm5_acl.rst", "admin/conf_files/kdc_conf.rst", "admin/conf_files/krb5_conf.rst", "admin/conf_ldap.rst", "admin/database.rst", "admin/dbtypes.rst", "admin/dictionary.rst", "admin/enctypes.rst", "admin/env_variables.rst", "admin/host_config.rst", "admin/https.rst", "admin/index.rst", "admin/install.rst", "admin/install_appl_srv.rst", "admin/install_clients.rst", "admin/install_kdc.rst", "admin/lockout.rst", "admin/otp.rst", "admin/pkinit.rst", "admin/princ_dns.rst", "admin/realm_config.rst", "admin/spake.rst", "admin/troubleshoot.rst", "admin/various_envs.rst", "appdev/gssapi.rst", "appdev/h5l_mit_apidiff.rst", "appdev/index.rst", "appdev/init_creds.rst", "appdev/princ_handle.rst", "appdev/refs/api/index.rst", "appdev/refs/api/krb5_425_conv_principal.rst", "appdev/refs/api/krb5_524_conv_principal.rst", "appdev/refs/api/krb5_524_convert_creds.rst", "appdev/refs/api/krb5_address_compare.rst", "appdev/refs/api/krb5_address_order.rst", "appdev/refs/api/krb5_address_search.rst", "appdev/refs/api/krb5_allow_weak_crypto.rst", "appdev/refs/api/krb5_aname_to_localname.rst", "appdev/refs/api/krb5_anonymous_principal.rst", "appdev/refs/api/krb5_anonymous_realm.rst", "appdev/refs/api/krb5_appdefault_boolean.rst", "appdev/refs/api/krb5_appdefault_string.rst", "appdev/refs/api/krb5_auth_con_free.rst", "appdev/refs/api/krb5_auth_con_genaddrs.rst", "appdev/refs/api/krb5_auth_con_get_checksum_func.rst", "appdev/refs/api/krb5_auth_con_getaddrs.rst", "appdev/refs/api/krb5_auth_con_getauthenticator.rst", "appdev/refs/api/krb5_auth_con_getflags.rst", "appdev/refs/api/krb5_auth_con_getkey.rst", "appdev/refs/api/krb5_auth_con_getkey_k.rst", "appdev/refs/api/krb5_auth_con_getlocalseqnumber.rst", "appdev/refs/api/krb5_auth_con_getlocalsubkey.rst", "appdev/refs/api/krb5_auth_con_getrcache.rst", "appdev/refs/api/krb5_auth_con_getrecvsubkey.rst", "appdev/refs/api/krb5_auth_con_getrecvsubkey_k.rst", "appdev/refs/api/krb5_auth_con_getremoteseqnumber.rst", "appdev/refs/api/krb5_auth_con_getremotesubkey.rst", "appdev/refs/api/krb5_auth_con_getsendsubkey.rst", "appdev/refs/api/krb5_auth_con_getsendsubkey_k.rst", "appdev/refs/api/krb5_auth_con_init.rst", "appdev/refs/api/krb5_auth_con_initivector.rst", "appdev/refs/api/krb5_auth_con_set_checksum_func.rst", "appdev/refs/api/krb5_auth_con_set_req_cksumtype.rst", "appdev/refs/api/krb5_auth_con_setaddrs.rst", "appdev/refs/api/krb5_auth_con_setflags.rst", "appdev/refs/api/krb5_auth_con_setports.rst", "appdev/refs/api/krb5_auth_con_setrcache.rst", "appdev/refs/api/krb5_auth_con_setrecvsubkey.rst", "appdev/refs/api/krb5_auth_con_setrecvsubkey_k.rst", "appdev/refs/api/krb5_auth_con_setsendsubkey.rst", "appdev/refs/api/krb5_auth_con_setsendsubkey_k.rst", "appdev/refs/api/krb5_auth_con_setuseruserkey.rst", "appdev/refs/api/krb5_build_principal.rst", "appdev/refs/api/krb5_build_principal_alloc_va.rst", "appdev/refs/api/krb5_build_principal_ext.rst", "appdev/refs/api/krb5_build_principal_va.rst", "appdev/refs/api/krb5_c_block_size.rst", "appdev/refs/api/krb5_c_checksum_length.rst", "appdev/refs/api/krb5_c_crypto_length.rst", "appdev/refs/api/krb5_c_crypto_length_iov.rst", "appdev/refs/api/krb5_c_decrypt.rst", "appdev/refs/api/krb5_c_decrypt_iov.rst", "appdev/refs/api/krb5_c_derive_prfplus.rst", "appdev/refs/api/krb5_c_encrypt.rst", "appdev/refs/api/krb5_c_encrypt_iov.rst", "appdev/refs/api/krb5_c_encrypt_length.rst", "appdev/refs/api/krb5_c_enctype_compare.rst", "appdev/refs/api/krb5_c_free_state.rst", "appdev/refs/api/krb5_c_fx_cf2_simple.rst", "appdev/refs/api/krb5_c_init_state.rst", "appdev/refs/api/krb5_c_is_coll_proof_cksum.rst", "appdev/refs/api/krb5_c_is_keyed_cksum.rst", "appdev/refs/api/krb5_c_keyed_checksum_types.rst", "appdev/refs/api/krb5_c_keylengths.rst", "appdev/refs/api/krb5_c_make_checksum.rst", "appdev/refs/api/krb5_c_make_checksum_iov.rst", "appdev/refs/api/krb5_c_make_random_key.rst", "appdev/refs/api/krb5_c_padding_length.rst", "appdev/refs/api/krb5_c_prf.rst", "appdev/refs/api/krb5_c_prf_length.rst", "appdev/refs/api/krb5_c_prfplus.rst", "appdev/refs/api/krb5_c_random_add_entropy.rst", "appdev/refs/api/krb5_c_random_make_octets.rst", "appdev/refs/api/krb5_c_random_os_entropy.rst", "appdev/refs/api/krb5_c_random_seed.rst", "appdev/refs/api/krb5_c_random_to_key.rst", "appdev/refs/api/krb5_c_string_to_key.rst", "appdev/refs/api/krb5_c_string_to_key_with_params.rst", "appdev/refs/api/krb5_c_valid_cksumtype.rst", "appdev/refs/api/krb5_c_valid_enctype.rst", "appdev/refs/api/krb5_c_verify_checksum.rst", "appdev/refs/api/krb5_c_verify_checksum_iov.rst", "appdev/refs/api/krb5_calculate_checksum.rst", "appdev/refs/api/krb5_cc_cache_match.rst", "appdev/refs/api/krb5_cc_close.rst", "appdev/refs/api/krb5_cc_copy_creds.rst", "appdev/refs/api/krb5_cc_default.rst", "appdev/refs/api/krb5_cc_default_name.rst", "appdev/refs/api/krb5_cc_destroy.rst", "appdev/refs/api/krb5_cc_dup.rst", "appdev/refs/api/krb5_cc_end_seq_get.rst", "appdev/refs/api/krb5_cc_gen_new.rst", "appdev/refs/api/krb5_cc_get_config.rst", "appdev/refs/api/krb5_cc_get_flags.rst", "appdev/refs/api/krb5_cc_get_full_name.rst", "appdev/refs/api/krb5_cc_get_name.rst", "appdev/refs/api/krb5_cc_get_principal.rst", "appdev/refs/api/krb5_cc_get_type.rst", "appdev/refs/api/krb5_cc_initialize.rst", "appdev/refs/api/krb5_cc_move.rst", "appdev/refs/api/krb5_cc_new_unique.rst", "appdev/refs/api/krb5_cc_next_cred.rst", "appdev/refs/api/krb5_cc_remove_cred.rst", "appdev/refs/api/krb5_cc_resolve.rst", "appdev/refs/api/krb5_cc_retrieve_cred.rst", "appdev/refs/api/krb5_cc_select.rst", "appdev/refs/api/krb5_cc_set_config.rst", "appdev/refs/api/krb5_cc_set_default_name.rst", "appdev/refs/api/krb5_cc_set_flags.rst", "appdev/refs/api/krb5_cc_start_seq_get.rst", "appdev/refs/api/krb5_cc_store_cred.rst", "appdev/refs/api/krb5_cc_support_switch.rst", "appdev/refs/api/krb5_cc_switch.rst", "appdev/refs/api/krb5_cccol_cursor_free.rst", "appdev/refs/api/krb5_cccol_cursor_new.rst", "appdev/refs/api/krb5_cccol_cursor_next.rst", "appdev/refs/api/krb5_cccol_have_content.rst", "appdev/refs/api/krb5_change_password.rst", "appdev/refs/api/krb5_check_clockskew.rst", "appdev/refs/api/krb5_checksum_size.rst", "appdev/refs/api/krb5_chpw_message.rst", "appdev/refs/api/krb5_cksumtype_to_string.rst", "appdev/refs/api/krb5_clear_error_message.rst", "appdev/refs/api/krb5_copy_addresses.rst", "appdev/refs/api/krb5_copy_authdata.rst", "appdev/refs/api/krb5_copy_authenticator.rst", "appdev/refs/api/krb5_copy_checksum.rst", "appdev/refs/api/krb5_copy_context.rst", "appdev/refs/api/krb5_copy_creds.rst", "appdev/refs/api/krb5_copy_data.rst", "appdev/refs/api/krb5_copy_error_message.rst", "appdev/refs/api/krb5_copy_keyblock.rst", "appdev/refs/api/krb5_copy_keyblock_contents.rst", "appdev/refs/api/krb5_copy_principal.rst", "appdev/refs/api/krb5_copy_ticket.rst", "appdev/refs/api/krb5_decode_authdata_container.rst", "appdev/refs/api/krb5_decode_ticket.rst", "appdev/refs/api/krb5_decrypt.rst", "appdev/refs/api/krb5_deltat_to_string.rst", "appdev/refs/api/krb5_eblock_enctype.rst", "appdev/refs/api/krb5_encode_authdata_container.rst", "appdev/refs/api/krb5_encrypt.rst", "appdev/refs/api/krb5_encrypt_size.rst", "appdev/refs/api/krb5_enctype_to_name.rst", "appdev/refs/api/krb5_enctype_to_string.rst", "appdev/refs/api/krb5_expand_hostname.rst", "appdev/refs/api/krb5_find_authdata.rst", "appdev/refs/api/krb5_finish_key.rst", "appdev/refs/api/krb5_finish_random_key.rst", "appdev/refs/api/krb5_free_addresses.rst", "appdev/refs/api/krb5_free_ap_rep_enc_part.rst", "appdev/refs/api/krb5_free_authdata.rst", "appdev/refs/api/krb5_free_authenticator.rst", "appdev/refs/api/krb5_free_checksum.rst", "appdev/refs/api/krb5_free_checksum_contents.rst", "appdev/refs/api/krb5_free_cksumtypes.rst", "appdev/refs/api/krb5_free_config_files.rst", "appdev/refs/api/krb5_free_context.rst", "appdev/refs/api/krb5_free_cred_contents.rst", "appdev/refs/api/krb5_free_creds.rst", "appdev/refs/api/krb5_free_data.rst", "appdev/refs/api/krb5_free_data_contents.rst", "appdev/refs/api/krb5_free_default_realm.rst", "appdev/refs/api/krb5_free_enctypes.rst", "appdev/refs/api/krb5_free_error.rst", "appdev/refs/api/krb5_free_error_message.rst", "appdev/refs/api/krb5_free_host_realm.rst", "appdev/refs/api/krb5_free_keyblock.rst", "appdev/refs/api/krb5_free_keyblock_contents.rst", "appdev/refs/api/krb5_free_keytab_entry_contents.rst", "appdev/refs/api/krb5_free_principal.rst", "appdev/refs/api/krb5_free_string.rst", "appdev/refs/api/krb5_free_tgt_creds.rst", "appdev/refs/api/krb5_free_ticket.rst", "appdev/refs/api/krb5_free_unparsed_name.rst", "appdev/refs/api/krb5_fwd_tgt_creds.rst", "appdev/refs/api/krb5_get_credentials.rst", "appdev/refs/api/krb5_get_credentials_renew.rst", "appdev/refs/api/krb5_get_credentials_validate.rst", "appdev/refs/api/krb5_get_default_config_files.rst", "appdev/refs/api/krb5_get_default_realm.rst", "appdev/refs/api/krb5_get_error_message.rst", "appdev/refs/api/krb5_get_etype_info.rst", "appdev/refs/api/krb5_get_fallback_host_realm.rst", "appdev/refs/api/krb5_get_host_realm.rst", "appdev/refs/api/krb5_get_in_tkt_with_keytab.rst", "appdev/refs/api/krb5_get_in_tkt_with_password.rst", "appdev/refs/api/krb5_get_in_tkt_with_skey.rst", "appdev/refs/api/krb5_get_init_creds_keytab.rst", "appdev/refs/api/krb5_get_init_creds_opt_alloc.rst", "appdev/refs/api/krb5_get_init_creds_opt_free.rst", "appdev/refs/api/krb5_get_init_creds_opt_get_fast_flags.rst", "appdev/refs/api/krb5_get_init_creds_opt_init.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_address_list.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_anonymous.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_canonicalize.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_change_password_prompt.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_etype_list.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_expire_callback.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache_name.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_fast_flags.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_forwardable.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_in_ccache.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_out_ccache.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_pa.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_pac_request.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_preauth_list.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_proxiable.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_renew_life.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_responder.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_salt.rst", "appdev/refs/api/krb5_get_init_creds_opt_set_tkt_life.rst", "appdev/refs/api/krb5_get_init_creds_password.rst", "appdev/refs/api/krb5_get_permitted_enctypes.rst", "appdev/refs/api/krb5_get_profile.rst", "appdev/refs/api/krb5_get_prompt_types.rst", "appdev/refs/api/krb5_get_renewed_creds.rst", "appdev/refs/api/krb5_get_server_rcache.rst", "appdev/refs/api/krb5_get_time_offsets.rst", "appdev/refs/api/krb5_get_validated_creds.rst", "appdev/refs/api/krb5_init_context.rst", "appdev/refs/api/krb5_init_context_profile.rst", "appdev/refs/api/krb5_init_creds_free.rst", "appdev/refs/api/krb5_init_creds_get.rst", "appdev/refs/api/krb5_init_creds_get_creds.rst", "appdev/refs/api/krb5_init_creds_get_error.rst", "appdev/refs/api/krb5_init_creds_get_times.rst", "appdev/refs/api/krb5_init_creds_init.rst", "appdev/refs/api/krb5_init_creds_set_keytab.rst", "appdev/refs/api/krb5_init_creds_set_password.rst", "appdev/refs/api/krb5_init_creds_set_service.rst", "appdev/refs/api/krb5_init_creds_step.rst", "appdev/refs/api/krb5_init_keyblock.rst", "appdev/refs/api/krb5_init_random_key.rst", "appdev/refs/api/krb5_init_secure_context.rst", "appdev/refs/api/krb5_is_config_principal.rst", "appdev/refs/api/krb5_is_referral_realm.rst", "appdev/refs/api/krb5_is_thread_safe.rst", "appdev/refs/api/krb5_k_create_key.rst", "appdev/refs/api/krb5_k_decrypt.rst", "appdev/refs/api/krb5_k_decrypt_iov.rst", "appdev/refs/api/krb5_k_encrypt.rst", "appdev/refs/api/krb5_k_encrypt_iov.rst", "appdev/refs/api/krb5_k_free_key.rst", "appdev/refs/api/krb5_k_key_enctype.rst", "appdev/refs/api/krb5_k_key_keyblock.rst", "appdev/refs/api/krb5_k_make_checksum.rst", "appdev/refs/api/krb5_k_make_checksum_iov.rst", "appdev/refs/api/krb5_k_prf.rst", "appdev/refs/api/krb5_k_reference_key.rst", "appdev/refs/api/krb5_k_verify_checksum.rst", "appdev/refs/api/krb5_k_verify_checksum_iov.rst", "appdev/refs/api/krb5_kdc_sign_ticket.rst", "appdev/refs/api/krb5_kdc_verify_ticket.rst", "appdev/refs/api/krb5_kt_add_entry.rst", "appdev/refs/api/krb5_kt_client_default.rst", "appdev/refs/api/krb5_kt_close.rst", "appdev/refs/api/krb5_kt_default.rst", "appdev/refs/api/krb5_kt_default_name.rst", "appdev/refs/api/krb5_kt_dup.rst", "appdev/refs/api/krb5_kt_end_seq_get.rst", "appdev/refs/api/krb5_kt_free_entry.rst", "appdev/refs/api/krb5_kt_get_entry.rst", "appdev/refs/api/krb5_kt_get_name.rst", "appdev/refs/api/krb5_kt_get_type.rst", "appdev/refs/api/krb5_kt_have_content.rst", "appdev/refs/api/krb5_kt_next_entry.rst", "appdev/refs/api/krb5_kt_read_service_key.rst", "appdev/refs/api/krb5_kt_remove_entry.rst", "appdev/refs/api/krb5_kt_resolve.rst", "appdev/refs/api/krb5_kt_start_seq_get.rst", "appdev/refs/api/krb5_kuserok.rst", "appdev/refs/api/krb5_make_authdata_kdc_issued.rst", "appdev/refs/api/krb5_marshal_credentials.rst", "appdev/refs/api/krb5_merge_authdata.rst", "appdev/refs/api/krb5_mk_1cred.rst", "appdev/refs/api/krb5_mk_error.rst", "appdev/refs/api/krb5_mk_ncred.rst", "appdev/refs/api/krb5_mk_priv.rst", "appdev/refs/api/krb5_mk_rep.rst", "appdev/refs/api/krb5_mk_rep_dce.rst", "appdev/refs/api/krb5_mk_req.rst", "appdev/refs/api/krb5_mk_req_extended.rst", "appdev/refs/api/krb5_mk_safe.rst", "appdev/refs/api/krb5_os_localaddr.rst", "appdev/refs/api/krb5_pac_add_buffer.rst", "appdev/refs/api/krb5_pac_free.rst", "appdev/refs/api/krb5_pac_get_buffer.rst", "appdev/refs/api/krb5_pac_get_client_info.rst", "appdev/refs/api/krb5_pac_get_types.rst", "appdev/refs/api/krb5_pac_init.rst", "appdev/refs/api/krb5_pac_parse.rst", "appdev/refs/api/krb5_pac_sign.rst", "appdev/refs/api/krb5_pac_sign_ext.rst", "appdev/refs/api/krb5_pac_verify.rst", "appdev/refs/api/krb5_pac_verify_ext.rst", "appdev/refs/api/krb5_parse_name.rst", "appdev/refs/api/krb5_parse_name_flags.rst", "appdev/refs/api/krb5_prepend_error_message.rst", "appdev/refs/api/krb5_principal2salt.rst", "appdev/refs/api/krb5_principal_compare.rst", "appdev/refs/api/krb5_principal_compare_any_realm.rst", "appdev/refs/api/krb5_principal_compare_flags.rst", "appdev/refs/api/krb5_process_key.rst", "appdev/refs/api/krb5_prompter_posix.rst", "appdev/refs/api/krb5_random_key.rst", "appdev/refs/api/krb5_rd_cred.rst", "appdev/refs/api/krb5_rd_error.rst", "appdev/refs/api/krb5_rd_priv.rst", "appdev/refs/api/krb5_rd_rep.rst", "appdev/refs/api/krb5_rd_rep_dce.rst", "appdev/refs/api/krb5_rd_req.rst", "appdev/refs/api/krb5_rd_safe.rst", "appdev/refs/api/krb5_read_password.rst", "appdev/refs/api/krb5_realm_compare.rst", "appdev/refs/api/krb5_recvauth.rst", "appdev/refs/api/krb5_recvauth_version.rst", "appdev/refs/api/krb5_responder_get_challenge.rst", "appdev/refs/api/krb5_responder_list_questions.rst", "appdev/refs/api/krb5_responder_otp_challenge_free.rst", "appdev/refs/api/krb5_responder_otp_get_challenge.rst", "appdev/refs/api/krb5_responder_otp_set_answer.rst", "appdev/refs/api/krb5_responder_pkinit_challenge_free.rst", "appdev/refs/api/krb5_responder_pkinit_get_challenge.rst", "appdev/refs/api/krb5_responder_pkinit_set_answer.rst", "appdev/refs/api/krb5_responder_set_answer.rst", "appdev/refs/api/krb5_salttype_to_string.rst", "appdev/refs/api/krb5_sendauth.rst", "appdev/refs/api/krb5_server_decrypt_ticket_keytab.rst", "appdev/refs/api/krb5_set_default_realm.rst", "appdev/refs/api/krb5_set_default_tgs_enctypes.rst", "appdev/refs/api/krb5_set_error_message.rst", "appdev/refs/api/krb5_set_kdc_recv_hook.rst", "appdev/refs/api/krb5_set_kdc_send_hook.rst", "appdev/refs/api/krb5_set_password.rst", "appdev/refs/api/krb5_set_password_using_ccache.rst", "appdev/refs/api/krb5_set_principal_realm.rst", "appdev/refs/api/krb5_set_real_time.rst", "appdev/refs/api/krb5_set_trace_callback.rst", "appdev/refs/api/krb5_set_trace_filename.rst", "appdev/refs/api/krb5_sname_match.rst", "appdev/refs/api/krb5_sname_to_principal.rst", "appdev/refs/api/krb5_string_to_cksumtype.rst", "appdev/refs/api/krb5_string_to_deltat.rst", "appdev/refs/api/krb5_string_to_enctype.rst", "appdev/refs/api/krb5_string_to_key.rst", "appdev/refs/api/krb5_string_to_salttype.rst", "appdev/refs/api/krb5_string_to_timestamp.rst", "appdev/refs/api/krb5_timeofday.rst", "appdev/refs/api/krb5_timestamp_to_sfstring.rst", "appdev/refs/api/krb5_timestamp_to_string.rst", "appdev/refs/api/krb5_tkt_creds_free.rst", "appdev/refs/api/krb5_tkt_creds_get.rst", "appdev/refs/api/krb5_tkt_creds_get_creds.rst", "appdev/refs/api/krb5_tkt_creds_get_times.rst", "appdev/refs/api/krb5_tkt_creds_init.rst", "appdev/refs/api/krb5_tkt_creds_step.rst", "appdev/refs/api/krb5_unmarshal_credentials.rst", "appdev/refs/api/krb5_unparse_name.rst", "appdev/refs/api/krb5_unparse_name_ext.rst", "appdev/refs/api/krb5_unparse_name_flags.rst", "appdev/refs/api/krb5_unparse_name_flags_ext.rst", "appdev/refs/api/krb5_us_timeofday.rst", "appdev/refs/api/krb5_use_enctype.rst", "appdev/refs/api/krb5_verify_authdata_kdc_issued.rst", "appdev/refs/api/krb5_verify_checksum.rst", "appdev/refs/api/krb5_verify_init_creds.rst", "appdev/refs/api/krb5_verify_init_creds_opt_init.rst", "appdev/refs/api/krb5_verify_init_creds_opt_set_ap_req_nofail.rst", "appdev/refs/api/krb5_vprepend_error_message.rst", "appdev/refs/api/krb5_vset_error_message.rst", "appdev/refs/api/krb5_vwrap_error_message.rst", "appdev/refs/api/krb5_wrap_error_message.rst", "appdev/refs/index.rst", "appdev/refs/macros/ADDRTYPE_ADDRPORT.rst", "appdev/refs/macros/ADDRTYPE_CHAOS.rst", "appdev/refs/macros/ADDRTYPE_DDP.rst", "appdev/refs/macros/ADDRTYPE_DIRECTIONAL.rst", "appdev/refs/macros/ADDRTYPE_INET.rst", "appdev/refs/macros/ADDRTYPE_INET6.rst", "appdev/refs/macros/ADDRTYPE_IPPORT.rst", "appdev/refs/macros/ADDRTYPE_ISO.rst", "appdev/refs/macros/ADDRTYPE_IS_LOCAL.rst", "appdev/refs/macros/ADDRTYPE_NETBIOS.rst", "appdev/refs/macros/ADDRTYPE_UNIXSOCK.rst", "appdev/refs/macros/ADDRTYPE_XNS.rst", "appdev/refs/macros/AD_TYPE_EXTERNAL.rst", "appdev/refs/macros/AD_TYPE_FIELD_TYPE_MASK.rst", "appdev/refs/macros/AD_TYPE_REGISTERED.rst", "appdev/refs/macros/AD_TYPE_RESERVED.rst", "appdev/refs/macros/AP_OPTS_CBT_FLAG.rst", "appdev/refs/macros/AP_OPTS_ETYPE_NEGOTIATION.rst", "appdev/refs/macros/AP_OPTS_MUTUAL_REQUIRED.rst", "appdev/refs/macros/AP_OPTS_RESERVED.rst", "appdev/refs/macros/AP_OPTS_USE_SESSION_KEY.rst", "appdev/refs/macros/AP_OPTS_USE_SUBKEY.rst", "appdev/refs/macros/AP_OPTS_WIRE_MASK.rst", "appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA128.rst", "appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA256.rst", "appdev/refs/macros/CKSUMTYPE_CRC32.rst", "appdev/refs/macros/CKSUMTYPE_DESCBC.rst", "appdev/refs/macros/CKSUMTYPE_HMAC_MD5_ARCFOUR.rst", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES128.rst", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES256.rst", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_DES3.rst", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA256_128_AES128.rst", "appdev/refs/macros/CKSUMTYPE_HMAC_SHA384_192_AES256.rst", "appdev/refs/macros/CKSUMTYPE_MD5_HMAC_ARCFOUR.rst", "appdev/refs/macros/CKSUMTYPE_NIST_SHA.rst", "appdev/refs/macros/CKSUMTYPE_RSA_MD4.rst", "appdev/refs/macros/CKSUMTYPE_RSA_MD4_DES.rst", "appdev/refs/macros/CKSUMTYPE_RSA_MD5.rst", "appdev/refs/macros/CKSUMTYPE_RSA_MD5_DES.rst", "appdev/refs/macros/CKSUMTYPE_SHA1.rst", "appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA1_96.rst", "appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA256_128.rst", "appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA1_96.rst", "appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA384_192.rst", "appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC.rst", "appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC_EXP.rst", "appdev/refs/macros/ENCTYPE_CAMELLIA128_CTS_CMAC.rst", "appdev/refs/macros/ENCTYPE_CAMELLIA256_CTS_CMAC.rst", "appdev/refs/macros/ENCTYPE_DES3_CBC_ENV.rst", "appdev/refs/macros/ENCTYPE_DES3_CBC_RAW.rst", "appdev/refs/macros/ENCTYPE_DES3_CBC_SHA.rst", "appdev/refs/macros/ENCTYPE_DES3_CBC_SHA1.rst", "appdev/refs/macros/ENCTYPE_DES_CBC_CRC.rst", "appdev/refs/macros/ENCTYPE_DES_CBC_MD4.rst", "appdev/refs/macros/ENCTYPE_DES_CBC_MD5.rst", "appdev/refs/macros/ENCTYPE_DES_CBC_RAW.rst", "appdev/refs/macros/ENCTYPE_DES_HMAC_SHA1.rst", "appdev/refs/macros/ENCTYPE_DSA_SHA1_CMS.rst", "appdev/refs/macros/ENCTYPE_MD5_RSA_CMS.rst", "appdev/refs/macros/ENCTYPE_NULL.rst", "appdev/refs/macros/ENCTYPE_RC2_CBC_ENV.rst", "appdev/refs/macros/ENCTYPE_RSA_ENV.rst", "appdev/refs/macros/ENCTYPE_RSA_ES_OAEP_ENV.rst", "appdev/refs/macros/ENCTYPE_SHA1_RSA_CMS.rst", "appdev/refs/macros/ENCTYPE_UNKNOWN.rst", "appdev/refs/macros/KDC_OPT_ALLOW_POSTDATE.rst", "appdev/refs/macros/KDC_OPT_CANONICALIZE.rst", "appdev/refs/macros/KDC_OPT_CNAME_IN_ADDL_TKT.rst", "appdev/refs/macros/KDC_OPT_DISABLE_TRANSITED_CHECK.rst", "appdev/refs/macros/KDC_OPT_ENC_TKT_IN_SKEY.rst", "appdev/refs/macros/KDC_OPT_FORWARDABLE.rst", "appdev/refs/macros/KDC_OPT_FORWARDED.rst", "appdev/refs/macros/KDC_OPT_POSTDATED.rst", "appdev/refs/macros/KDC_OPT_PROXIABLE.rst", "appdev/refs/macros/KDC_OPT_PROXY.rst", "appdev/refs/macros/KDC_OPT_RENEW.rst", "appdev/refs/macros/KDC_OPT_RENEWABLE.rst", "appdev/refs/macros/KDC_OPT_RENEWABLE_OK.rst", "appdev/refs/macros/KDC_OPT_REQUEST_ANONYMOUS.rst", "appdev/refs/macros/KDC_OPT_VALIDATE.rst", "appdev/refs/macros/KDC_TKT_COMMON_MASK.rst", "appdev/refs/macros/KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE.rst", "appdev/refs/macros/KRB5_ANONYMOUS_PRINCSTR.rst", "appdev/refs/macros/KRB5_ANONYMOUS_REALMSTR.rst", "appdev/refs/macros/KRB5_AP_REP.rst", "appdev/refs/macros/KRB5_AP_REQ.rst", "appdev/refs/macros/KRB5_AS_REP.rst", "appdev/refs/macros/KRB5_AS_REQ.rst", "appdev/refs/macros/KRB5_AUTHDATA_AND_OR.rst", "appdev/refs/macros/KRB5_AUTHDATA_AP_OPTIONS.rst", "appdev/refs/macros/KRB5_AUTHDATA_AUTH_INDICATOR.rst", "appdev/refs/macros/KRB5_AUTHDATA_CAMMAC.rst", "appdev/refs/macros/KRB5_AUTHDATA_ETYPE_NEGOTIATION.rst", "appdev/refs/macros/KRB5_AUTHDATA_FX_ARMOR.rst", "appdev/refs/macros/KRB5_AUTHDATA_IF_RELEVANT.rst", "appdev/refs/macros/KRB5_AUTHDATA_INITIAL_VERIFIED_CAS.rst", "appdev/refs/macros/KRB5_AUTHDATA_KDC_ISSUED.rst", "appdev/refs/macros/KRB5_AUTHDATA_MANDATORY_FOR_KDC.rst", "appdev/refs/macros/KRB5_AUTHDATA_OSF_DCE.rst", "appdev/refs/macros/KRB5_AUTHDATA_SESAME.rst", "appdev/refs/macros/KRB5_AUTHDATA_SIGNTICKET.rst", "appdev/refs/macros/KRB5_AUTHDATA_WIN2K_PAC.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_SEQUENCE.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_TIME.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_PERMIT_ALL.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_SEQUENCE.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_TIME.rst", "appdev/refs/macros/KRB5_AUTH_CONTEXT_USE_SUBKEY.rst", "appdev/refs/macros/KRB5_CRED.rst", "appdev/refs/macros/KRB5_CRYPTO_TYPE_CHECKSUM.rst", "appdev/refs/macros/KRB5_CRYPTO_TYPE_DATA.rst", "appdev/refs/macros/KRB5_CRYPTO_TYPE_EMPTY.rst", "appdev/refs/macros/KRB5_CRYPTO_TYPE_HEADER.rst", "appdev/refs/macros/KRB5_CRYPTO_TYPE_PADDING.rst", "appdev/refs/macros/KRB5_CRYPTO_TYPE_SIGN_ONLY.rst", "appdev/refs/macros/KRB5_CRYPTO_TYPE_STREAM.rst", "appdev/refs/macros/KRB5_CRYPTO_TYPE_TRAILER.rst", "appdev/refs/macros/KRB5_CYBERSAFE_SECUREID.rst", "appdev/refs/macros/KRB5_DOMAIN_X500_COMPRESS.rst", "appdev/refs/macros/KRB5_ENCPADATA_REQ_ENC_PA_REP.rst", "appdev/refs/macros/KRB5_ERROR.rst", "appdev/refs/macros/KRB5_FAST_REQUIRED.rst", "appdev/refs/macros/KRB5_GC_CACHED.rst", "appdev/refs/macros/KRB5_GC_CANONICALIZE.rst", "appdev/refs/macros/KRB5_GC_CONSTRAINED_DELEGATION.rst", "appdev/refs/macros/KRB5_GC_FORWARDABLE.rst", "appdev/refs/macros/KRB5_GC_NO_STORE.rst", "appdev/refs/macros/KRB5_GC_NO_TRANSIT_CHECK.rst", "appdev/refs/macros/KRB5_GC_USER_USER.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ANONYMOUS.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CANONICALIZE.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_FORWARDABLE.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PROXIABLE.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_SALT.rst", "appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_TKT_LIFE.rst", "appdev/refs/macros/KRB5_INIT_CONTEXT_KDC.rst", "appdev/refs/macros/KRB5_INIT_CONTEXT_SECURE.rst", "appdev/refs/macros/KRB5_INIT_CREDS_STEP_FLAG_CONTINUE.rst", "appdev/refs/macros/KRB5_INT16_MAX.rst", "appdev/refs/macros/KRB5_INT16_MIN.rst", "appdev/refs/macros/KRB5_INT32_MAX.rst", "appdev/refs/macros/KRB5_INT32_MIN.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AD_ITE.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AD_MTE.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AD_SIGNEDPATH.rst", "appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_CKSUM.rst", "appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_ENCRYPT.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AP_REP_ENCPART.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AS_REP_ENCPART.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ.rst", "appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS.rst", "appdev/refs/macros/KRB5_KEYUSAGE_CAMMAC.rst", "appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT.rst", "appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_KDC.rst", "appdev/refs/macros/KRB5_KEYUSAGE_FAST_ENC.rst", "appdev/refs/macros/KRB5_KEYUSAGE_FAST_FINISHED.rst", "appdev/refs/macros/KRB5_KEYUSAGE_FAST_REP.rst", "appdev/refs/macros/KRB5_KEYUSAGE_FAST_REQ_CHKSUM.rst", "appdev/refs/macros/KRB5_KEYUSAGE_FINISHED.rst", "appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_MIC.rst", "appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG.rst", "appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV.rst", "appdev/refs/macros/KRB5_KEYUSAGE_IAKERB_FINISHED.rst", "appdev/refs/macros/KRB5_KEYUSAGE_KDC_REP_TICKET.rst", "appdev/refs/macros/KRB5_KEYUSAGE_KRB_CRED_ENCPART.rst", "appdev/refs/macros/KRB5_KEYUSAGE_KRB_ERROR_CKSUM.rst", "appdev/refs/macros/KRB5_KEYUSAGE_KRB_PRIV_ENCPART.rst", "appdev/refs/macros/KRB5_KEYUSAGE_KRB_SAFE_CKSUM.rst", "appdev/refs/macros/KRB5_KEYUSAGE_PA_AS_FRESHNESS.rst", "appdev/refs/macros/KRB5_KEYUSAGE_PA_FX_COOKIE.rst", "appdev/refs/macros/KRB5_KEYUSAGE_PA_OTP_REQUEST.rst", "appdev/refs/macros/KRB5_KEYUSAGE_PA_PKINIT_KX.rst", "appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY.rst", "appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST.rst", "appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM.rst", "appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID.rst", "appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_RESPONSE.rst", "appdev/refs/macros/KRB5_KEYUSAGE_SPAKE.rst", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY.rst", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY.rst", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY.rst", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY.rst", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH.rst", "appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM.rst", "appdev/refs/macros/KRB5_KPASSWD_ACCESSDENIED.rst", "appdev/refs/macros/KRB5_KPASSWD_AUTHERROR.rst", "appdev/refs/macros/KRB5_KPASSWD_BAD_VERSION.rst", "appdev/refs/macros/KRB5_KPASSWD_HARDERROR.rst", "appdev/refs/macros/KRB5_KPASSWD_INITIAL_FLAG_NEEDED.rst", "appdev/refs/macros/KRB5_KPASSWD_MALFORMED.rst", "appdev/refs/macros/KRB5_KPASSWD_SOFTERROR.rst", "appdev/refs/macros/KRB5_KPASSWD_SUCCESS.rst", "appdev/refs/macros/KRB5_LRQ_ALL_ACCT_EXPTIME.rst", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_INITIAL.rst", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_RENEWAL.rst", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_REQ.rst", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT.rst", "appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT_ISSUED.rst", "appdev/refs/macros/KRB5_LRQ_ALL_PW_EXPTIME.rst", "appdev/refs/macros/KRB5_LRQ_NONE.rst", "appdev/refs/macros/KRB5_LRQ_ONE_ACCT_EXPTIME.rst", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_INITIAL.rst", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_RENEWAL.rst", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_REQ.rst", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT.rst", "appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT_ISSUED.rst", "appdev/refs/macros/KRB5_LRQ_ONE_PW_EXPTIME.rst", "appdev/refs/macros/KRB5_NT_ENTERPRISE_PRINCIPAL.rst", "appdev/refs/macros/KRB5_NT_ENT_PRINCIPAL_AND_ID.rst", "appdev/refs/macros/KRB5_NT_MS_PRINCIPAL.rst", "appdev/refs/macros/KRB5_NT_MS_PRINCIPAL_AND_ID.rst", "appdev/refs/macros/KRB5_NT_PRINCIPAL.rst", "appdev/refs/macros/KRB5_NT_SMTP_NAME.rst", "appdev/refs/macros/KRB5_NT_SRV_HST.rst", "appdev/refs/macros/KRB5_NT_SRV_INST.rst", "appdev/refs/macros/KRB5_NT_SRV_XHST.rst", "appdev/refs/macros/KRB5_NT_UID.rst", "appdev/refs/macros/KRB5_NT_UNKNOWN.rst", "appdev/refs/macros/KRB5_NT_WELLKNOWN.rst", "appdev/refs/macros/KRB5_NT_X500_PRINCIPAL.rst", "appdev/refs/macros/KRB5_PAC_ATTRIBUTES_INFO.rst", "appdev/refs/macros/KRB5_PAC_CLIENT_CLAIMS.rst", "appdev/refs/macros/KRB5_PAC_CLIENT_INFO.rst", "appdev/refs/macros/KRB5_PAC_CREDENTIALS_INFO.rst", "appdev/refs/macros/KRB5_PAC_DELEGATION_INFO.rst", "appdev/refs/macros/KRB5_PAC_DEVICE_CLAIMS.rst", "appdev/refs/macros/KRB5_PAC_DEVICE_INFO.rst", "appdev/refs/macros/KRB5_PAC_FULL_CHECKSUM.rst", "appdev/refs/macros/KRB5_PAC_LOGON_INFO.rst", "appdev/refs/macros/KRB5_PAC_PRIVSVR_CHECKSUM.rst", "appdev/refs/macros/KRB5_PAC_REQUESTOR.rst", "appdev/refs/macros/KRB5_PAC_SERVER_CHECKSUM.rst", "appdev/refs/macros/KRB5_PAC_TICKET_CHECKSUM.rst", "appdev/refs/macros/KRB5_PAC_UPN_DNS_INFO.rst", "appdev/refs/macros/KRB5_PADATA_AFS3_SALT.rst", "appdev/refs/macros/KRB5_PADATA_AP_REQ.rst", "appdev/refs/macros/KRB5_PADATA_AS_CHECKSUM.rst", "appdev/refs/macros/KRB5_PADATA_AS_FRESHNESS.rst", "appdev/refs/macros/KRB5_PADATA_ENCRYPTED_CHALLENGE.rst", "appdev/refs/macros/KRB5_PADATA_ENC_SANDIA_SECURID.rst", "appdev/refs/macros/KRB5_PADATA_ENC_TIMESTAMP.rst", "appdev/refs/macros/KRB5_PADATA_ENC_UNIX_TIME.rst", "appdev/refs/macros/KRB5_PADATA_ETYPE_INFO.rst", "appdev/refs/macros/KRB5_PADATA_ETYPE_INFO2.rst", "appdev/refs/macros/KRB5_PADATA_FOR_USER.rst", "appdev/refs/macros/KRB5_PADATA_FX_COOKIE.rst", "appdev/refs/macros/KRB5_PADATA_FX_ERROR.rst", "appdev/refs/macros/KRB5_PADATA_FX_FAST.rst", "appdev/refs/macros/KRB5_PADATA_GET_FROM_TYPED_DATA.rst", "appdev/refs/macros/KRB5_PADATA_NONE.rst", "appdev/refs/macros/KRB5_PADATA_OSF_DCE.rst", "appdev/refs/macros/KRB5_PADATA_OTP_CHALLENGE.rst", "appdev/refs/macros/KRB5_PADATA_OTP_PIN_CHANGE.rst", "appdev/refs/macros/KRB5_PADATA_OTP_REQUEST.rst", "appdev/refs/macros/KRB5_PADATA_PAC_OPTIONS.rst", "appdev/refs/macros/KRB5_PADATA_PAC_REQUEST.rst", "appdev/refs/macros/KRB5_PADATA_PKINIT_KX.rst", "appdev/refs/macros/KRB5_PADATA_PK_AS_REP.rst", "appdev/refs/macros/KRB5_PADATA_PK_AS_REP_OLD.rst", "appdev/refs/macros/KRB5_PADATA_PK_AS_REQ.rst", "appdev/refs/macros/KRB5_PADATA_PK_AS_REQ_OLD.rst", "appdev/refs/macros/KRB5_PADATA_PW_SALT.rst", "appdev/refs/macros/KRB5_PADATA_REDHAT_IDP_OAUTH2.rst", "appdev/refs/macros/KRB5_PADATA_REDHAT_PASSKEY.rst", "appdev/refs/macros/KRB5_PADATA_REFERRAL.rst", "appdev/refs/macros/KRB5_PADATA_S4U_X509_USER.rst", "appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE.rst", "appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE_2.rst", "appdev/refs/macros/KRB5_PADATA_SAM_REDIRECT.rst", "appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE.rst", "appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE_2.rst", "appdev/refs/macros/KRB5_PADATA_SESAME.rst", "appdev/refs/macros/KRB5_PADATA_SPAKE.rst", "appdev/refs/macros/KRB5_PADATA_SVR_REFERRAL_INFO.rst", "appdev/refs/macros/KRB5_PADATA_TGS_REQ.rst", "appdev/refs/macros/KRB5_PADATA_USE_SPECIFIED_KVNO.rst", "appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_CASEFOLD.rst", "appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_ENTERPRISE.rst", "appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_IGNORE_REALM.rst", "appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_UTF8.rst", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_ENTERPRISE.rst", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_IGNORE_REALM.rst", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_DEF_REALM.rst", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_REALM.rst", "appdev/refs/macros/KRB5_PRINCIPAL_PARSE_REQUIRE_REALM.rst", "appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_DISPLAY.rst", "appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_NO_REALM.rst", "appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_SHORT.rst", "appdev/refs/macros/KRB5_PRIV.rst", "appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD.rst", "appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN.rst", "appdev/refs/macros/KRB5_PROMPT_TYPE_PASSWORD.rst", "appdev/refs/macros/KRB5_PROMPT_TYPE_PREAUTH.rst", "appdev/refs/macros/KRB5_PVNO.rst", "appdev/refs/macros/KRB5_REALM_BRANCH_CHAR.rst", "appdev/refs/macros/KRB5_RECVAUTH_BADAUTHVERS.rst", "appdev/refs/macros/KRB5_RECVAUTH_SKIP_VERSION.rst", "appdev/refs/macros/KRB5_REFERRAL_REALM.rst", "appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN.rst", "appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN.rst", "appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_NEXTOTP.rst", "appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN.rst", "appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC.rst", "appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_DECIMAL.rst", "appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL.rst", "appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW.rst", "appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY.rst", "appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED.rst", "appdev/refs/macros/KRB5_RESPONDER_QUESTION_OTP.rst", "appdev/refs/macros/KRB5_RESPONDER_QUESTION_PASSWORD.rst", "appdev/refs/macros/KRB5_RESPONDER_QUESTION_PKINIT.rst", "appdev/refs/macros/KRB5_SAFE.rst", "appdev/refs/macros/KRB5_SAM_MUST_PK_ENCRYPT_SAD.rst", "appdev/refs/macros/KRB5_SAM_SEND_ENCRYPTED_SAD.rst", "appdev/refs/macros/KRB5_SAM_USE_SAD_AS_KEY.rst", "appdev/refs/macros/KRB5_TC_MATCH_2ND_TKT.rst", "appdev/refs/macros/KRB5_TC_MATCH_AUTHDATA.rst", "appdev/refs/macros/KRB5_TC_MATCH_FLAGS.rst", "appdev/refs/macros/KRB5_TC_MATCH_FLAGS_EXACT.rst", "appdev/refs/macros/KRB5_TC_MATCH_IS_SKEY.rst", "appdev/refs/macros/KRB5_TC_MATCH_KTYPE.rst", "appdev/refs/macros/KRB5_TC_MATCH_SRV_NAMEONLY.rst", "appdev/refs/macros/KRB5_TC_MATCH_TIMES.rst", "appdev/refs/macros/KRB5_TC_MATCH_TIMES_EXACT.rst", "appdev/refs/macros/KRB5_TC_NOTICKET.rst", "appdev/refs/macros/KRB5_TC_OPENCLOSE.rst", "appdev/refs/macros/KRB5_TC_SUPPORTED_KTYPES.rst", "appdev/refs/macros/KRB5_TGS_NAME.rst", "appdev/refs/macros/KRB5_TGS_NAME_SIZE.rst", "appdev/refs/macros/KRB5_TGS_REP.rst", "appdev/refs/macros/KRB5_TGS_REQ.rst", "appdev/refs/macros/KRB5_TKT_CREDS_STEP_FLAG_CONTINUE.rst", "appdev/refs/macros/KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL.rst", "appdev/refs/macros/KRB5_WELLKNOWN_NAMESTR.rst", "appdev/refs/macros/LR_TYPE_INTERPRETATION_MASK.rst", "appdev/refs/macros/LR_TYPE_THIS_SERVER_ONLY.rst", "appdev/refs/macros/MAX_KEYTAB_NAME_LEN.rst", "appdev/refs/macros/MSEC_DIRBIT.rst", "appdev/refs/macros/MSEC_VAL_MASK.rst", "appdev/refs/macros/SALT_TYPE_AFS_LENGTH.rst", "appdev/refs/macros/SALT_TYPE_NO_LENGTH.rst", "appdev/refs/macros/THREEPARAMOPEN.rst", "appdev/refs/macros/TKT_FLG_ANONYMOUS.rst", "appdev/refs/macros/TKT_FLG_ENC_PA_REP.rst", "appdev/refs/macros/TKT_FLG_FORWARDABLE.rst", "appdev/refs/macros/TKT_FLG_FORWARDED.rst", "appdev/refs/macros/TKT_FLG_HW_AUTH.rst", "appdev/refs/macros/TKT_FLG_INITIAL.rst", "appdev/refs/macros/TKT_FLG_INVALID.rst", "appdev/refs/macros/TKT_FLG_MAY_POSTDATE.rst", "appdev/refs/macros/TKT_FLG_OK_AS_DELEGATE.rst", "appdev/refs/macros/TKT_FLG_POSTDATED.rst", "appdev/refs/macros/TKT_FLG_PRE_AUTH.rst", "appdev/refs/macros/TKT_FLG_PROXIABLE.rst", "appdev/refs/macros/TKT_FLG_PROXY.rst", "appdev/refs/macros/TKT_FLG_RENEWABLE.rst", "appdev/refs/macros/TKT_FLG_TRANSIT_POLICY_CHECKED.rst", "appdev/refs/macros/VALID_INT_BITS.rst", "appdev/refs/macros/VALID_UINT_BITS.rst", "appdev/refs/macros/index.rst", "appdev/refs/macros/krb524_convert_creds_kdc.rst", "appdev/refs/macros/krb524_init_ets.rst", "appdev/refs/macros/krb5_const.rst", "appdev/refs/macros/krb5_princ_component.rst", "appdev/refs/macros/krb5_princ_name.rst", "appdev/refs/macros/krb5_princ_realm.rst", "appdev/refs/macros/krb5_princ_set_realm.rst", "appdev/refs/macros/krb5_princ_set_realm_data.rst", "appdev/refs/macros/krb5_princ_set_realm_length.rst", "appdev/refs/macros/krb5_princ_size.rst", "appdev/refs/macros/krb5_princ_type.rst", "appdev/refs/macros/krb5_roundup.rst", "appdev/refs/macros/krb5_x.rst", "appdev/refs/macros/krb5_xc.rst", "appdev/refs/types/index.rst", "appdev/refs/types/krb5_address.rst", "appdev/refs/types/krb5_addrtype.rst", "appdev/refs/types/krb5_ap_rep.rst", "appdev/refs/types/krb5_ap_rep_enc_part.rst", "appdev/refs/types/krb5_ap_req.rst", "appdev/refs/types/krb5_auth_context.rst", "appdev/refs/types/krb5_authdata.rst", "appdev/refs/types/krb5_authdatatype.rst", "appdev/refs/types/krb5_authenticator.rst", "appdev/refs/types/krb5_boolean.rst", "appdev/refs/types/krb5_cc_cursor.rst", "appdev/refs/types/krb5_ccache.rst", "appdev/refs/types/krb5_cccol_cursor.rst", "appdev/refs/types/krb5_checksum.rst", "appdev/refs/types/krb5_cksumtype.rst", "appdev/refs/types/krb5_const_pointer.rst", "appdev/refs/types/krb5_const_principal.rst", "appdev/refs/types/krb5_context.rst", "appdev/refs/types/krb5_cred.rst", "appdev/refs/types/krb5_cred_enc_part.rst", "appdev/refs/types/krb5_cred_info.rst", "appdev/refs/types/krb5_creds.rst", "appdev/refs/types/krb5_crypto_iov.rst", "appdev/refs/types/krb5_cryptotype.rst", "appdev/refs/types/krb5_data.rst", "appdev/refs/types/krb5_deltat.rst", "appdev/refs/types/krb5_enc_data.rst", "appdev/refs/types/krb5_enc_kdc_rep_part.rst", "appdev/refs/types/krb5_enc_tkt_part.rst", "appdev/refs/types/krb5_encrypt_block.rst", "appdev/refs/types/krb5_enctype.rst", "appdev/refs/types/krb5_error.rst", "appdev/refs/types/krb5_error_code.rst", "appdev/refs/types/krb5_expire_callback_func.rst", "appdev/refs/types/krb5_flags.rst", "appdev/refs/types/krb5_get_init_creds_opt.rst", "appdev/refs/types/krb5_gic_opt_pa_data.rst", "appdev/refs/types/krb5_init_creds_context.rst", "appdev/refs/types/krb5_int16.rst", "appdev/refs/types/krb5_int32.rst", "appdev/refs/types/krb5_kdc_rep.rst", "appdev/refs/types/krb5_kdc_req.rst", "appdev/refs/types/krb5_key.rst", "appdev/refs/types/krb5_keyblock.rst", "appdev/refs/types/krb5_keytab.rst", "appdev/refs/types/krb5_keytab_entry.rst", "appdev/refs/types/krb5_keyusage.rst", "appdev/refs/types/krb5_kt_cursor.rst", "appdev/refs/types/krb5_kvno.rst", "appdev/refs/types/krb5_last_req_entry.rst", "appdev/refs/types/krb5_magic.rst", "appdev/refs/types/krb5_mk_req_checksum_func.rst", "appdev/refs/types/krb5_msgtype.rst", "appdev/refs/types/krb5_octet.rst", "appdev/refs/types/krb5_pa_data.rst", "appdev/refs/types/krb5_pa_pac_req.rst", "appdev/refs/types/krb5_pa_server_referral_data.rst", "appdev/refs/types/krb5_pa_svr_referral_data.rst", "appdev/refs/types/krb5_pac.rst", "appdev/refs/types/krb5_pointer.rst", "appdev/refs/types/krb5_post_recv_fn.rst", "appdev/refs/types/krb5_pre_send_fn.rst", "appdev/refs/types/krb5_preauthtype.rst", "appdev/refs/types/krb5_principal.rst", "appdev/refs/types/krb5_principal_data.rst", "appdev/refs/types/krb5_prompt.rst", "appdev/refs/types/krb5_prompt_type.rst", "appdev/refs/types/krb5_prompter_fct.rst", "appdev/refs/types/krb5_pwd_data.rst", "appdev/refs/types/krb5_rcache.rst", "appdev/refs/types/krb5_replay_data.rst", "appdev/refs/types/krb5_responder_context.rst", "appdev/refs/types/krb5_responder_fn.rst", "appdev/refs/types/krb5_responder_otp_challenge.rst", "appdev/refs/types/krb5_responder_otp_tokeninfo.rst", "appdev/refs/types/krb5_responder_pkinit_challenge.rst", "appdev/refs/types/krb5_responder_pkinit_identity.rst", "appdev/refs/types/krb5_response.rst", "appdev/refs/types/krb5_ticket.rst", "appdev/refs/types/krb5_ticket_times.rst", "appdev/refs/types/krb5_timestamp.rst", "appdev/refs/types/krb5_tkt_authent.rst", "appdev/refs/types/krb5_tkt_creds_context.rst", "appdev/refs/types/krb5_trace_callback.rst", "appdev/refs/types/krb5_trace_info.rst", "appdev/refs/types/krb5_transited.rst", "appdev/refs/types/krb5_typed_data.rst", "appdev/refs/types/krb5_ui_2.rst", "appdev/refs/types/krb5_ui_4.rst", "appdev/refs/types/krb5_verify_init_creds_opt.rst", "appdev/refs/types/passwd_phrase_element.rst", "appdev/y2038.rst", "basic/ccache_def.rst", "basic/date_format.rst", "basic/index.rst", "basic/keytab_def.rst", "basic/rcache_def.rst", "basic/stash_file_def.rst", "build/directory_org.rst", "build/doing_build.rst", "build/index.rst", "build/options2configure.rst", "build/osconf.rst", "build_this.rst", "copyright.rst", "formats/ccache_file_format.rst", "formats/cookie.rst", "formats/database_formats.rst", "formats/freshness_token.rst", "formats/index.rst", "formats/keytab_file_format.rst", "formats/rcache_file_format.rst", "index.rst", "mitK5defaults.rst", "mitK5features.rst", "mitK5license.rst", "plugindev/ccselect.rst", "plugindev/certauth.rst", "plugindev/clpreauth.rst", "plugindev/general.rst", "plugindev/gssapi.rst", "plugindev/hostrealm.rst", "plugindev/index.rst", "plugindev/internal.rst", "plugindev/kadm5_auth.rst", "plugindev/kadm5_hook.rst", "plugindev/kdcpolicy.rst", "plugindev/kdcpreauth.rst", "plugindev/localauth.rst", "plugindev/locate.rst", "plugindev/profile.rst", "plugindev/pwqual.rst", "resources.rst", "user/index.rst", "user/pwd_mgmt.rst", "user/tkt_mgmt.rst", "user/user_commands/index.rst", "user/user_commands/kdestroy.rst", "user/user_commands/kinit.rst", "user/user_commands/klist.rst", "user/user_commands/kpasswd.rst", "user/user_commands/krb5-config.rst", "user/user_commands/ksu.rst", "user/user_commands/kswitch.rst", "user/user_commands/kvno.rst", "user/user_commands/sclient.rst", "user/user_config/index.rst", "user/user_config/k5identity.rst", "user/user_config/k5login.rst", "user/user_config/kerberos.rst"], "titles": ["Contributing to the MIT Kerberos Documentation", "Administration programs", "k5srvutil", "kadmin", "kadmind", "kdb5_ldap_util", "kdb5_util", "kprop", "kpropd", "kproplog", "krb5kdc", "ktutil", "sserver", "Advanced topics", "Retiring DES", "Application servers", "Authentication indicators", "Backups of secure hosts", "Configuration Files", "kadm5.acl", "kdc.conf", "krb5.conf", "Configuring Kerberos with OpenLDAP back-end", "Database administration", "Database types", "Addressing dictionary attack risks", "Encryption types", "Environment variables", "Host configuration", "HTTPS proxy configuration", "For administrators", "Installation guide", "UNIX Application Servers", "Installing and configuring UNIX client machines", "Installing KDCs", "Account lockout", "OTP Preauthentication", "PKINIT configuration", "Principal names and DNS", "Realm configuration decisions", "SPAKE Preauthentication", "Troubleshooting", "Various links", "Developing with GSSAPI", "Differences between Heimdal and MIT Kerberos API", "For application developers", "Initial credentials", "Principal manipulation and parsing", "krb5 API", "krb5_425_conv_principal - Convert a Kerberos V4 principal to a Kerberos V5 principal.", "krb5_524_conv_principal - Convert a Kerberos V5 principal to a Kerberos V4 principal.", "krb5_524_convert_creds - Convert a Kerberos V5 credentials to a Kerberos V4 credentials.", "krb5_address_compare - Compare two Kerberos addresses.", "krb5_address_order - Return an ordering of the specified addresses.", "krb5_address_search - Search a list of addresses for a specified address.", "krb5_allow_weak_crypto - Allow the application to override the profile\u2019s allow_weak_crypto setting.", "krb5_aname_to_localname - Convert a principal name to a local name.", "krb5_anonymous_principal - Build an anonymous principal.", "krb5_anonymous_realm - Return an anonymous realm data.", "krb5_appdefault_boolean - Retrieve a boolean value from the appdefaults section of krb5.conf.", "krb5_appdefault_string - Retrieve a string value from the appdefaults section of krb5.conf.", "krb5_auth_con_free - Free a krb5_auth_context structure.", "krb5_auth_con_genaddrs - Generate auth context addresses from a connected socket.", "krb5_auth_con_get_checksum_func - Get the checksum callback from an auth context.", "krb5_auth_con_getaddrs - Retrieve address fields from an auth context.", "krb5_auth_con_getauthenticator - Retrieve the authenticator from an auth context.", "krb5_auth_con_getflags - Retrieve flags from a krb5_auth_context structure.", "krb5_auth_con_getkey - Retrieve the session key from an auth context as a keyblock.", "krb5_auth_con_getkey_k - Retrieve the session key from an auth context.", "krb5_auth_con_getlocalseqnumber - Retrieve the local sequence number from an auth context.", "krb5_auth_con_getlocalsubkey", "krb5_auth_con_getrcache - Retrieve the replay cache from an auth context.", "krb5_auth_con_getrecvsubkey - Retrieve the receiving subkey from an auth context as a keyblock.", "krb5_auth_con_getrecvsubkey_k - Retrieve the receiving subkey from an auth context as a keyblock.", "krb5_auth_con_getremoteseqnumber - Retrieve the remote sequence number from an auth context.", "krb5_auth_con_getremotesubkey", "krb5_auth_con_getsendsubkey - Retrieve the send subkey from an auth context as a keyblock.", "krb5_auth_con_getsendsubkey_k - Retrieve the send subkey from an auth context.", "krb5_auth_con_init - Create and initialize an authentication context.", "krb5_auth_con_initivector - Cause an auth context to use cipher state.", "krb5_auth_con_set_checksum_func - Set a checksum callback in an auth context.", "krb5_auth_con_set_req_cksumtype - Set checksum type in an an auth context.", "krb5_auth_con_setaddrs - Set the local and remote addresses in an auth context.", "krb5_auth_con_setflags - Set a flags field in a krb5_auth_context structure.", "krb5_auth_con_setports - Set local and remote port fields in an auth context.", "krb5_auth_con_setrcache - Set the replay cache in an auth context.", "krb5_auth_con_setrecvsubkey - Set the receiving subkey in an auth context with a keyblock.", "krb5_auth_con_setrecvsubkey_k - Set the receiving subkey in an auth context.", "krb5_auth_con_setsendsubkey - Set the send subkey in an auth context with a keyblock.", "krb5_auth_con_setsendsubkey_k - Set the send subkey in an auth context.", "krb5_auth_con_setuseruserkey - Set the session key in an auth context.", "krb5_build_principal - Build a principal name using null-terminated strings.", "krb5_build_principal_alloc_va - Build a principal name, using a precomputed variable argument list.", "krb5_build_principal_ext - Build a principal name using length-counted strings.", "krb5_build_principal_va", "krb5_c_block_size - Return cipher block size.", "krb5_c_checksum_length - Return the length of checksums for a checksum type.", "krb5_c_crypto_length - Return a length of a message field specific to the encryption type.", "krb5_c_crypto_length_iov - Fill in lengths for header, trailer and padding in a IOV array.", "krb5_c_decrypt - Decrypt data using a key (operates on keyblock).", "krb5_c_decrypt_iov - Decrypt data in place supporting AEAD (operates on keyblock).", "krb5_c_derive_prfplus - Derive a key using some input data (via RFC 6113 PRF+).", "krb5_c_encrypt - Encrypt data using a key (operates on keyblock).", "krb5_c_encrypt_iov - Encrypt data in place supporting AEAD (operates on keyblock).", "krb5_c_encrypt_length - Compute encrypted data length.", "krb5_c_enctype_compare - Compare two encryption types.", "krb5_c_free_state - Free a cipher state previously allocated by krb5_c_init_state().", "krb5_c_fx_cf2_simple - Compute the KRB-FX-CF2 combination of two keys and pepper strings.", "krb5_c_init_state - Initialize a new cipher state.", "krb5_c_is_coll_proof_cksum - Test whether a checksum type is collision-proof.", "krb5_c_is_keyed_cksum - Test whether a checksum type is keyed.", "krb5_c_keyed_checksum_types - Return a list of keyed checksum types usable with an encryption type.", "krb5_c_keylengths - Return length of the specified key in bytes.", "krb5_c_make_checksum - Compute a checksum (operates on keyblock).", "krb5_c_make_checksum_iov - Fill in a checksum element in IOV array (operates on keyblock)", "krb5_c_make_random_key - Generate an enctype-specific random encryption key.", "krb5_c_padding_length - Return a number of padding octets.", "krb5_c_prf - Generate enctype-specific pseudo-random bytes.", "krb5_c_prf_length - Get the output length of pseudo-random functions for an encryption type.", "krb5_c_prfplus - Generate pseudo-random bytes using RFC 6113 PRF+.", "krb5_c_random_add_entropy", "krb5_c_random_make_octets - Generate pseudo-random bytes.", "krb5_c_random_os_entropy", "krb5_c_random_seed", "krb5_c_random_to_key - Generate an enctype-specific key from random data.", "krb5_c_string_to_key - Convert a string (such a password) to a key.", "krb5_c_string_to_key_with_params - Convert a string (such as a password) to a key with additional parameters.", "krb5_c_valid_cksumtype - Verify that specified checksum type is a valid Kerberos checksum type.", "krb5_c_valid_enctype - Verify that a specified encryption type is a valid Kerberos encryption type.", "krb5_c_verify_checksum - Verify a checksum (operates on keyblock).", "krb5_c_verify_checksum_iov - Validate a checksum element in IOV array (operates on keyblock).", "krb5_calculate_checksum", "krb5_cc_cache_match - Find a credential cache with a specified client principal.", "krb5_cc_close - Close a credential cache handle.", "krb5_cc_copy_creds - Copy a credential cache.", "krb5_cc_default - Resolve the default credential cache name.", "krb5_cc_default_name - Return the name of the default credential cache.", "krb5_cc_destroy - Destroy a credential cache.", "krb5_cc_dup - Duplicate ccache handle.", "krb5_cc_end_seq_get - Finish a series of sequential processing credential cache entries.", "krb5_cc_gen_new", "krb5_cc_get_config - Get a configuration value from a credential cache.", "krb5_cc_get_flags - Retrieve flags from a credential cache structure.", "krb5_cc_get_full_name - Retrieve the full name of a credential cache.", "krb5_cc_get_name - Retrieve the name, but not type of a credential cache.", "krb5_cc_get_principal - Get the default principal of a credential cache.", "krb5_cc_get_type - Retrieve the type of a credential cache.", "krb5_cc_initialize - Initialize a credential cache.", "krb5_cc_move - Move a credential cache.", "krb5_cc_new_unique - Create a new credential cache of the specified type with a unique name.", "krb5_cc_next_cred - Retrieve the next entry from the credential cache.", "krb5_cc_remove_cred - Remove credentials from a credential cache.", "krb5_cc_resolve - Resolve a credential cache name.", "krb5_cc_retrieve_cred - Retrieve a specified credentials from a credential cache.", "krb5_cc_select - Select a credential cache to use with a server principal.", "krb5_cc_set_config - Store a configuration value in a credential cache.", "krb5_cc_set_default_name - Set the default credential cache name.", "krb5_cc_set_flags - Set options flags on a credential cache.", "krb5_cc_start_seq_get - Prepare to sequentially read every credential in a credential cache.", "krb5_cc_store_cred - Store credentials in a credential cache.", "krb5_cc_support_switch - Determine whether a credential cache type supports switching.", "krb5_cc_switch - Make a credential cache the primary cache for its collection.", "krb5_cccol_cursor_free - Free a credential cache collection cursor.", "krb5_cccol_cursor_new - Prepare to iterate over the collection of known credential caches.", "krb5_cccol_cursor_next - Get the next credential cache in the collection.", "krb5_cccol_have_content - Check if the credential cache collection contains any initialized caches.", "krb5_change_password - Change a password for an existing Kerberos account.", "krb5_check_clockskew - Check if a timestamp is within the allowed clock skew of the current time.", "krb5_checksum_size", "krb5_chpw_message - Get a result message for changing or setting a password.", "krb5_cksumtype_to_string - Convert a checksum type to a string.", "krb5_clear_error_message - Clear the extended error message in a context.", "krb5_copy_addresses - Copy an array of addresses.", "krb5_copy_authdata - Copy an authorization data list.", "krb5_copy_authenticator - Copy a krb5_authenticator structure.", "krb5_copy_checksum - Copy a krb5_checksum structure.", "krb5_copy_context - Copy a krb5_context structure.", "krb5_copy_creds - Copy a krb5_creds structure.", "krb5_copy_data - Copy a krb5_data object.", "krb5_copy_error_message - Copy the most recent extended error message from one context to another.", "krb5_copy_keyblock - Copy a keyblock.", "krb5_copy_keyblock_contents - Copy the contents of a keyblock.", "krb5_copy_principal - Copy a principal.", "krb5_copy_ticket - Copy a krb5_ticket structure.", "krb5_decode_authdata_container - Unwrap authorization data.", "krb5_decode_ticket - Decode an ASN.1-formatted ticket.", "krb5_decrypt", "krb5_deltat_to_string - Convert a relative time value to a string.", "krb5_eblock_enctype", "krb5_encode_authdata_container - Wrap authorization data in a container.", "krb5_encrypt", "krb5_encrypt_size", "krb5_enctype_to_name - Convert an encryption type to a name or alias.", "krb5_enctype_to_string - Convert an encryption type to a string.", "krb5_expand_hostname - Canonicalize a hostname, possibly using name service.", "krb5_find_authdata - Find authorization data elements.", "krb5_finish_key", "krb5_finish_random_key", "krb5_free_addresses - Free the data stored in array of addresses.", "krb5_free_ap_rep_enc_part - Free a krb5_ap_rep_enc_part structure.", "krb5_free_authdata - Free the storage assigned to array of authentication data.", "krb5_free_authenticator - Free a krb5_authenticator structure.", "krb5_free_checksum - Free a krb5_checksum structure.", "krb5_free_checksum_contents - Free the contents of a krb5_checksum structure.", "krb5_free_cksumtypes - Free an array of checksum types.", "krb5_free_config_files - Free a list allocated by krb5_get_default_config_files()", "krb5_free_context - Free a krb5 library context.", "krb5_free_cred_contents - Free the contents of a krb5_creds structure.", "krb5_free_creds - Free a krb5_creds structure.", "krb5_free_data - Free a krb5_data structure.", "krb5_free_data_contents - Free the contents of a krb5_data structure and zero the data field.", "krb5_free_default_realm - Free a default realm string returned by krb5_get_default_realm().", "krb5_free_enctypes - Free an array of encryption types.", "krb5_free_error - Free an error allocated by krb5_read_error() or krb5_sendauth().", "krb5_free_error_message - Free an error message generated by krb5_get_error_message().", "krb5_free_host_realm - Free the memory allocated by krb5_get_host_realm().", "krb5_free_keyblock - Free a krb5_keyblock structure.", "krb5_free_keyblock_contents - Free the contents of a krb5_keyblock structure.", "krb5_free_keytab_entry_contents - Free the contents of a key table entry.", "krb5_free_principal - Free the storage assigned to a principal.", "krb5_free_string - Free a string allocated by a krb5 function.", "krb5_free_tgt_creds - Free an array of credential structures.", "krb5_free_ticket - Free a ticket.", "krb5_free_unparsed_name - Free a string representation of a principal.", "krb5_fwd_tgt_creds - Get a forwarded TGT and format a KRB-CRED message.", "krb5_get_credentials - Get an additional ticket.", "krb5_get_credentials_renew", "krb5_get_credentials_validate", "krb5_get_default_config_files - Return a list of default configuration filenames.", "krb5_get_default_realm - Retrieve the default realm.", "krb5_get_error_message - Get the (possibly extended) error message for a code.", "krb5_get_etype_info - Retrieve enctype, salt and s2kparams from KDC.", "krb5_get_fallback_host_realm", "krb5_get_host_realm - Get the Kerberos realm names for a host.", "krb5_get_in_tkt_with_keytab", "krb5_get_in_tkt_with_password", "krb5_get_in_tkt_with_skey", "krb5_get_init_creds_keytab - Get initial credentials using a key table.", "krb5_get_init_creds_opt_alloc - Allocate a new initial credential options structure.", "krb5_get_init_creds_opt_free - Free initial credential options.", "krb5_get_init_creds_opt_get_fast_flags - Retrieve FAST flags from initial credential options.", "krb5_get_init_creds_opt_init", "krb5_get_init_creds_opt_set_address_list - Set address restrictions in initial credential options.", "krb5_get_init_creds_opt_set_anonymous - Set or unset the anonymous flag in initial credential options.", "krb5_get_init_creds_opt_set_canonicalize - Set or unset the canonicalize flag in initial credential options.", "krb5_get_init_creds_opt_set_change_password_prompt - Set or unset change-password-prompt flag in initial credential options.", "krb5_get_init_creds_opt_set_etype_list - Set allowable encryption types in initial credential options.", "krb5_get_init_creds_opt_set_expire_callback - Set an expiration callback in initial credential options.", "krb5_get_init_creds_opt_set_fast_ccache - Set FAST armor cache in initial credential options.", "krb5_get_init_creds_opt_set_fast_ccache_name - Set location of FAST armor ccache in initial credential options.", "krb5_get_init_creds_opt_set_fast_flags - Set FAST flags in initial credential options.", "krb5_get_init_creds_opt_set_forwardable - Set or unset the forwardable flag in initial credential options.", "krb5_get_init_creds_opt_set_in_ccache - Set an input credential cache in initial credential options.", "krb5_get_init_creds_opt_set_out_ccache - Set an output credential cache in initial credential options.", "krb5_get_init_creds_opt_set_pa - Supply options for preauthentication in initial credential options.", "krb5_get_init_creds_opt_set_pac_request - Ask the KDC to include or not include a PAC in the ticket.", "krb5_get_init_creds_opt_set_preauth_list - Set preauthentication types in initial credential options.", "krb5_get_init_creds_opt_set_proxiable - Set or unset the proxiable flag in initial credential options.", "krb5_get_init_creds_opt_set_renew_life - Set the ticket renewal lifetime in initial credential options.", "krb5_get_init_creds_opt_set_responder - Set the responder function in initial credential options.", "krb5_get_init_creds_opt_set_salt - Set salt for optimistic preauthentication in initial credential options.", "krb5_get_init_creds_opt_set_tkt_life - Set the ticket lifetime in initial credential options.", "krb5_get_init_creds_password - Get initial credentials using a password.", "krb5_get_permitted_enctypes - Return a list of encryption types permitted for session keys.", "krb5_get_profile - Retrieve configuration profile from the context.", "krb5_get_prompt_types - Get prompt types array from a context.", "krb5_get_renewed_creds - Get renewed credential from KDC using an existing credential.", "krb5_get_server_rcache - Generate a replay cache object for server use and open it.", "krb5_get_time_offsets - Return the time offsets from the os context.", "krb5_get_validated_creds - Get validated credentials from the KDC.", "krb5_init_context - Create a krb5 library context.", "krb5_init_context_profile - Create a krb5 library context using a specified profile.", "krb5_init_creds_free - Free an initial credentials context.", "krb5_init_creds_get - Acquire credentials using an initial credentials context.", "krb5_init_creds_get_creds - Retrieve acquired credentials from an initial credentials context.", "krb5_init_creds_get_error - Get the last error from KDC from an initial credentials context.", "krb5_init_creds_get_times - Retrieve ticket times from an initial credentials context.", "krb5_init_creds_init - Create a context for acquiring initial credentials.", "krb5_init_creds_set_keytab - Specify a keytab to use for acquiring initial credentials.", "krb5_init_creds_set_password - Set a password for acquiring initial credentials.", "krb5_init_creds_set_service - Specify a service principal for acquiring initial credentials.", "krb5_init_creds_step - Get the next KDC request for acquiring initial credentials.", "krb5_init_keyblock - Initialize an empty krb5_keyblock .", "krb5_init_random_key", "krb5_init_secure_context - Create a krb5 library context using only configuration files.", "krb5_is_config_principal - Test whether a principal is a configuration principal.", "krb5_is_referral_realm - Check for a match with KRB5_REFERRAL_REALM.", "krb5_is_thread_safe - Test whether the Kerberos library was built with multithread support.", "krb5_k_create_key - Create a krb5_key from the enctype and key data in a keyblock.", "krb5_k_decrypt - Decrypt data using a key (operates on opaque key).", "krb5_k_decrypt_iov - Decrypt data in place supporting AEAD (operates on opaque key).", "krb5_k_encrypt - Encrypt data using a key (operates on opaque key).", "krb5_k_encrypt_iov - Encrypt data in place supporting AEAD (operates on opaque key).", "krb5_k_free_key - Decrement the reference count on a key and free it if it hits zero.", "krb5_k_key_enctype - Retrieve the enctype of a krb5_key structure.", "krb5_k_key_keyblock - Retrieve a copy of the keyblock from a krb5_key structure.", "krb5_k_make_checksum - Compute a checksum (operates on opaque key).", "krb5_k_make_checksum_iov - Fill in a checksum element in IOV array (operates on opaque key)", "krb5_k_prf - Generate enctype-specific pseudo-random bytes (operates on opaque key).", "krb5_k_reference_key - Increment the reference count on a key.", "krb5_k_verify_checksum - Verify a checksum (operates on opaque key).", "krb5_k_verify_checksum_iov - Validate a checksum element in IOV array (operates on opaque key).", "krb5_kdc_sign_ticket - Sign a PAC, possibly including a ticket signature.", "krb5_kdc_verify_ticket - Verify a PAC, possibly including ticket signature.", "krb5_kt_add_entry - Add a new entry to a key table.", "krb5_kt_client_default - Resolve the default client key table.", "krb5_kt_close - Close a key table handle.", "krb5_kt_default - Resolve the default key table.", "krb5_kt_default_name - Get the default key table name.", "krb5_kt_dup - Duplicate keytab handle.", "krb5_kt_end_seq_get - Release a keytab cursor.", "krb5_kt_free_entry", "krb5_kt_get_entry - Get an entry from a key table.", "krb5_kt_get_name - Get a key table name.", "krb5_kt_get_type - Return the type of a key table.", "krb5_kt_have_content - Check if a keytab exists and contains entries.", "krb5_kt_next_entry - Retrieve the next entry from the key table.", "krb5_kt_read_service_key - Retrieve a service key from a key table.", "krb5_kt_remove_entry - Remove an entry from a key table.", "krb5_kt_resolve - Get a handle for a key table.", "krb5_kt_start_seq_get - Start a sequential retrieval of key table entries.", "krb5_kuserok - Determine if a principal is authorized to log in as a local user.", "krb5_make_authdata_kdc_issued - Encode and sign AD-KDCIssued authorization data.", "krb5_marshal_credentials - Serialize a krb5_creds object.", "krb5_merge_authdata - Merge two authorization data lists into a new list.", "krb5_mk_1cred - Format a KRB-CRED message for a single set of credentials.", "krb5_mk_error - Format and encode a KRB_ERROR message.", "krb5_mk_ncred - Format a KRB-CRED message for an array of credentials.", "krb5_mk_priv - Format a KRB-PRIV message.", "krb5_mk_rep - Format and encrypt a KRB_AP_REP message.", "krb5_mk_rep_dce - Format and encrypt a KRB_AP_REP message for DCE RPC.", "krb5_mk_req - Create a KRB_AP_REQ message.", "krb5_mk_req_extended - Create a KRB_AP_REQ message using supplied credentials.", "krb5_mk_safe - Format a KRB-SAFE message.", "krb5_os_localaddr - Return all interface addresses for this host.", "krb5_pac_add_buffer - Add a buffer to a PAC handle.", "krb5_pac_free - Free a PAC handle.", "krb5_pac_get_buffer - Retrieve a buffer value from a PAC.", "krb5_pac_get_client_info - Read client information from a PAC.", "krb5_pac_get_types - Return an array of buffer types in a PAC handle.", "krb5_pac_init - Create an empty Privilege Attribute Certificate (PAC) handle.", "krb5_pac_parse - Unparse an encoded PAC into a new handle.", "krb5_pac_sign", "krb5_pac_sign_ext", "krb5_pac_verify - Verify a PAC.", "krb5_pac_verify_ext - Verify a PAC, possibly from a specified realm.", "krb5_parse_name - Convert a string principal name to a krb5_principal structure.", "krb5_parse_name_flags - Convert a string principal name to a krb5_principal with flags.", "krb5_prepend_error_message - Add a prefix to the message for an error code.", "krb5_principal2salt - Convert a principal name into the default salt for that principal.", "krb5_principal_compare - Compare two principals.", "krb5_principal_compare_any_realm - Compare two principals ignoring realm components.", "krb5_principal_compare_flags - Compare two principals with additional flags.", "krb5_process_key", "krb5_prompter_posix - Prompt user for password.", "krb5_random_key", "krb5_rd_cred - Read and validate a KRB-CRED message.", "krb5_rd_error - Decode a KRB-ERROR message.", "krb5_rd_priv - Process a KRB-PRIV message.", "krb5_rd_rep - Parse and decrypt a KRB_AP_REP message.", "krb5_rd_rep_dce - Parse and decrypt a KRB_AP_REP message for DCE RPC.", "krb5_rd_req - Parse and decrypt a KRB_AP_REQ message.", "krb5_rd_safe - Process KRB-SAFE message.", "krb5_read_password - Read a password from keyboard input.", "krb5_realm_compare - Compare the realms of two principals.", "krb5_recvauth - Server function for sendauth protocol.", "krb5_recvauth_version - Server function for sendauth protocol with version parameter.", "krb5_responder_get_challenge - Retrieve the challenge data for a given question in the responder context.", "krb5_responder_list_questions - List the question names contained in the responder context.", "krb5_responder_otp_challenge_free - Free the value returned by krb5_responder_otp_get_challenge().", "krb5_responder_otp_get_challenge - Decode the KRB5_RESPONDER_QUESTION_OTP to a C struct.", "krb5_responder_otp_set_answer - Answer the KRB5_RESPONDER_QUESTION_OTP question.", "krb5_responder_pkinit_challenge_free - Free the value returned by krb5_responder_pkinit_get_challenge().", "krb5_responder_pkinit_get_challenge - Decode the KRB5_RESPONDER_QUESTION_PKINIT to a C struct.", "krb5_responder_pkinit_set_answer - Answer the KRB5_RESPONDER_QUESTION_PKINIT question for one identity.", "krb5_responder_set_answer - Answer a named question in the responder context.", "krb5_salttype_to_string - Convert a salt type to a string.", "krb5_sendauth - Client function for sendauth protocol.", "krb5_server_decrypt_ticket_keytab - Decrypt a ticket using the specified key table.", "krb5_set_default_realm - Override the default realm for the specified context.", "krb5_set_default_tgs_enctypes - Set default TGS encryption types in a krb5_context structure.", "krb5_set_error_message - Set an extended error message for an error code.", "krb5_set_kdc_recv_hook - Set a KDC post-receive hook function.", "krb5_set_kdc_send_hook - Set a KDC pre-send hook function.", "krb5_set_password - Set a password for a principal using specified credentials.", "krb5_set_password_using_ccache - Set a password for a principal using cached credentials.", "krb5_set_principal_realm - Set the realm field of a principal.", "krb5_set_real_time - Set time offset field in a krb5_context structure.", "krb5_set_trace_callback - Specify a callback function for trace events.", "krb5_set_trace_filename - Specify a file name for directing trace events.", "krb5_sname_match - Test whether a principal matches a matching principal.", "krb5_sname_to_principal - Generate a full principal name from a service name.", "krb5_string_to_cksumtype - Convert a string to a checksum type.", "krb5_string_to_deltat - Convert a string to a delta time value.", "krb5_string_to_enctype - Convert a string to an encryption type.", "krb5_string_to_key", "krb5_string_to_salttype - Convert a string to a salt type.", "krb5_string_to_timestamp - Convert a string to a timestamp.", "krb5_timeofday - Retrieve the current time with context specific time offset adjustment.", "krb5_timestamp_to_sfstring - Convert a timestamp to a string, with optional output padding.", "krb5_timestamp_to_string - Convert a timestamp to a string.", "krb5_tkt_creds_free - Free a TGS request context.", "krb5_tkt_creds_get - Synchronously obtain credentials using a TGS request context.", "krb5_tkt_creds_get_creds - Retrieve acquired credentials from a TGS request context.", "krb5_tkt_creds_get_times - Retrieve ticket times from a TGS request context.", "krb5_tkt_creds_init - Create a context to get credentials from a KDC\u2019s Ticket Granting Service.", "krb5_tkt_creds_step - Get the next KDC request in a TGS exchange.", "krb5_unmarshal_credentials - Deserialize a krb5_creds object.", "krb5_unparse_name - Convert a krb5_principal structure to a string representation.", "krb5_unparse_name_ext - Convert krb5_principal structure to string and length.", "krb5_unparse_name_flags - Convert krb5_principal structure to a string with flags.", "krb5_unparse_name_flags_ext - Convert krb5_principal structure to string format with flags.", "krb5_us_timeofday - Retrieve the system time of day, in sec and ms, since the epoch.", "krb5_use_enctype", "krb5_verify_authdata_kdc_issued - Unwrap and verify AD-KDCIssued authorization data.", "krb5_verify_checksum", "krb5_verify_init_creds - Verify initial credentials against a keytab.", "krb5_verify_init_creds_opt_init - Initialize a credential verification options structure.", "krb5_verify_init_creds_opt_set_ap_req_nofail - Set whether credential verification is required.", "krb5_vprepend_error_message - Add a prefix to the message for an error code using a va_list.", "krb5_vset_error_message - Set an extended error message for an error code using a va_list.", "krb5_vwrap_error_message - Add a prefix to a different error code\u2019s message using a va_list.", "krb5_wrap_error_message - Add a prefix to a different error code\u2019s message.", "Complete reference - API and datatypes", "ADDRTYPE_ADDRPORT", "ADDRTYPE_CHAOS", "ADDRTYPE_DDP", "ADDRTYPE_DIRECTIONAL", "ADDRTYPE_INET", "ADDRTYPE_INET6", "ADDRTYPE_IPPORT", "ADDRTYPE_ISO", "ADDRTYPE_IS_LOCAL", "ADDRTYPE_NETBIOS", "ADDRTYPE_UNIXSOCK", "ADDRTYPE_XNS", "AD_TYPE_EXTERNAL", "AD_TYPE_FIELD_TYPE_MASK", "AD_TYPE_REGISTERED", "AD_TYPE_RESERVED", "AP_OPTS_CBT_FLAG", "AP_OPTS_ETYPE_NEGOTIATION", "AP_OPTS_MUTUAL_REQUIRED", "AP_OPTS_RESERVED", "AP_OPTS_USE_SESSION_KEY", "AP_OPTS_USE_SUBKEY", "AP_OPTS_WIRE_MASK", "CKSUMTYPE_CMAC_CAMELLIA128", "CKSUMTYPE_CMAC_CAMELLIA256", "CKSUMTYPE_CRC32", "CKSUMTYPE_DESCBC", "CKSUMTYPE_HMAC_MD5_ARCFOUR", "CKSUMTYPE_HMAC_SHA1_96_AES128", "CKSUMTYPE_HMAC_SHA1_96_AES256", "CKSUMTYPE_HMAC_SHA1_DES3", "CKSUMTYPE_HMAC_SHA256_128_AES128", "CKSUMTYPE_HMAC_SHA384_192_AES256", "CKSUMTYPE_MD5_HMAC_ARCFOUR", "CKSUMTYPE_NIST_SHA", "CKSUMTYPE_RSA_MD4", "CKSUMTYPE_RSA_MD4_DES", "CKSUMTYPE_RSA_MD5", "CKSUMTYPE_RSA_MD5_DES", "CKSUMTYPE_SHA1", "ENCTYPE_AES128_CTS_HMAC_SHA1_96", "ENCTYPE_AES128_CTS_HMAC_SHA256_128", "ENCTYPE_AES256_CTS_HMAC_SHA1_96", "ENCTYPE_AES256_CTS_HMAC_SHA384_192", "ENCTYPE_ARCFOUR_HMAC", "ENCTYPE_ARCFOUR_HMAC_EXP", "ENCTYPE_CAMELLIA128_CTS_CMAC", "ENCTYPE_CAMELLIA256_CTS_CMAC", "ENCTYPE_DES3_CBC_ENV", "ENCTYPE_DES3_CBC_RAW", "ENCTYPE_DES3_CBC_SHA", "ENCTYPE_DES3_CBC_SHA1", "ENCTYPE_DES_CBC_CRC", "ENCTYPE_DES_CBC_MD4", "ENCTYPE_DES_CBC_MD5", "ENCTYPE_DES_CBC_RAW", "ENCTYPE_DES_HMAC_SHA1", "ENCTYPE_DSA_SHA1_CMS", "ENCTYPE_MD5_RSA_CMS", "ENCTYPE_NULL", "ENCTYPE_RC2_CBC_ENV", "ENCTYPE_RSA_ENV", "ENCTYPE_RSA_ES_OAEP_ENV", "ENCTYPE_SHA1_RSA_CMS", "ENCTYPE_UNKNOWN", "KDC_OPT_ALLOW_POSTDATE", "KDC_OPT_CANONICALIZE", "KDC_OPT_CNAME_IN_ADDL_TKT", "KDC_OPT_DISABLE_TRANSITED_CHECK", "KDC_OPT_ENC_TKT_IN_SKEY", "KDC_OPT_FORWARDABLE", "KDC_OPT_FORWARDED", "KDC_OPT_POSTDATED", "KDC_OPT_PROXIABLE", "KDC_OPT_PROXY", "KDC_OPT_RENEW", "KDC_OPT_RENEWABLE", "KDC_OPT_RENEWABLE_OK", "KDC_OPT_REQUEST_ANONYMOUS", "KDC_OPT_VALIDATE", "KDC_TKT_COMMON_MASK", "KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE", "KRB5_ANONYMOUS_PRINCSTR", "KRB5_ANONYMOUS_REALMSTR", "KRB5_AP_REP", "KRB5_AP_REQ", "KRB5_AS_REP", "KRB5_AS_REQ", "KRB5_AUTHDATA_AND_OR", "KRB5_AUTHDATA_AP_OPTIONS", "KRB5_AUTHDATA_AUTH_INDICATOR", "KRB5_AUTHDATA_CAMMAC", "KRB5_AUTHDATA_ETYPE_NEGOTIATION", "KRB5_AUTHDATA_FX_ARMOR", "KRB5_AUTHDATA_IF_RELEVANT", "KRB5_AUTHDATA_INITIAL_VERIFIED_CAS", "KRB5_AUTHDATA_KDC_ISSUED", "KRB5_AUTHDATA_MANDATORY_FOR_KDC", "KRB5_AUTHDATA_OSF_DCE", "KRB5_AUTHDATA_SESAME", "KRB5_AUTHDATA_SIGNTICKET", "KRB5_AUTHDATA_WIN2K_PAC", "KRB5_AUTH_CONTEXT_DO_SEQUENCE", "KRB5_AUTH_CONTEXT_DO_TIME", "KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR", "KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR", "KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR", "KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR", "KRB5_AUTH_CONTEXT_PERMIT_ALL", "KRB5_AUTH_CONTEXT_RET_SEQUENCE", "KRB5_AUTH_CONTEXT_RET_TIME", "KRB5_AUTH_CONTEXT_USE_SUBKEY", "KRB5_CRED", "KRB5_CRYPTO_TYPE_CHECKSUM", "KRB5_CRYPTO_TYPE_DATA", "KRB5_CRYPTO_TYPE_EMPTY", "KRB5_CRYPTO_TYPE_HEADER", "KRB5_CRYPTO_TYPE_PADDING", "KRB5_CRYPTO_TYPE_SIGN_ONLY", "KRB5_CRYPTO_TYPE_STREAM", "KRB5_CRYPTO_TYPE_TRAILER", "KRB5_CYBERSAFE_SECUREID", "KRB5_DOMAIN_X500_COMPRESS", "KRB5_ENCPADATA_REQ_ENC_PA_REP", "KRB5_ERROR", "KRB5_FAST_REQUIRED", "KRB5_GC_CACHED", "KRB5_GC_CANONICALIZE", "KRB5_GC_CONSTRAINED_DELEGATION", "KRB5_GC_FORWARDABLE", "KRB5_GC_NO_STORE", "KRB5_GC_NO_TRANSIT_CHECK", "KRB5_GC_USER_USER", "KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST", "KRB5_GET_INIT_CREDS_OPT_ANONYMOUS", "KRB5_GET_INIT_CREDS_OPT_CANONICALIZE", "KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT", "KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST", "KRB5_GET_INIT_CREDS_OPT_FORWARDABLE", "KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST", "KRB5_GET_INIT_CREDS_OPT_PROXIABLE", "KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE", "KRB5_GET_INIT_CREDS_OPT_SALT", "KRB5_GET_INIT_CREDS_OPT_TKT_LIFE", "KRB5_INIT_CONTEXT_KDC", "KRB5_INIT_CONTEXT_SECURE", "KRB5_INIT_CREDS_STEP_FLAG_CONTINUE", "KRB5_INT16_MAX", "KRB5_INT16_MIN", "KRB5_INT32_MAX", "KRB5_INT32_MIN", "KRB5_KEYUSAGE_AD_ITE", "KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM", "KRB5_KEYUSAGE_AD_MTE", "KRB5_KEYUSAGE_AD_SIGNEDPATH", "KRB5_KEYUSAGE_APP_DATA_CKSUM", "KRB5_KEYUSAGE_APP_DATA_ENCRYPT", "KRB5_KEYUSAGE_AP_REP_ENCPART", "KRB5_KEYUSAGE_AP_REQ_AUTH", "KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM", "KRB5_KEYUSAGE_AS_REP_ENCPART", "KRB5_KEYUSAGE_AS_REQ", "KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS", "KRB5_KEYUSAGE_CAMMAC", "KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT", "KRB5_KEYUSAGE_ENC_CHALLENGE_KDC", "KRB5_KEYUSAGE_FAST_ENC", "KRB5_KEYUSAGE_FAST_FINISHED", "KRB5_KEYUSAGE_FAST_REP", "KRB5_KEYUSAGE_FAST_REQ_CHKSUM", "KRB5_KEYUSAGE_FINISHED", "KRB5_KEYUSAGE_GSS_TOK_MIC", "KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG", "KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV", "KRB5_KEYUSAGE_IAKERB_FINISHED", "KRB5_KEYUSAGE_KDC_REP_TICKET", "KRB5_KEYUSAGE_KRB_CRED_ENCPART", "KRB5_KEYUSAGE_KRB_ERROR_CKSUM", "KRB5_KEYUSAGE_KRB_PRIV_ENCPART", "KRB5_KEYUSAGE_KRB_SAFE_CKSUM", "KRB5_KEYUSAGE_PA_AS_FRESHNESS", "KRB5_KEYUSAGE_PA_FX_COOKIE", "KRB5_KEYUSAGE_PA_OTP_REQUEST", "KRB5_KEYUSAGE_PA_PKINIT_KX", "KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY", "KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST", "KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM", "KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID", "KRB5_KEYUSAGE_PA_SAM_RESPONSE", "KRB5_KEYUSAGE_SPAKE", "KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY", "KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY", "KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY", "KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY", "KRB5_KEYUSAGE_TGS_REQ_AUTH", "KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM", "KRB5_KPASSWD_ACCESSDENIED", "KRB5_KPASSWD_AUTHERROR", "KRB5_KPASSWD_BAD_VERSION", "KRB5_KPASSWD_HARDERROR", "KRB5_KPASSWD_INITIAL_FLAG_NEEDED", "KRB5_KPASSWD_MALFORMED", "KRB5_KPASSWD_SOFTERROR", "KRB5_KPASSWD_SUCCESS", "KRB5_LRQ_ALL_ACCT_EXPTIME", "KRB5_LRQ_ALL_LAST_INITIAL", "KRB5_LRQ_ALL_LAST_RENEWAL", "KRB5_LRQ_ALL_LAST_REQ", "KRB5_LRQ_ALL_LAST_TGT", "KRB5_LRQ_ALL_LAST_TGT_ISSUED", "KRB5_LRQ_ALL_PW_EXPTIME", "KRB5_LRQ_NONE", "KRB5_LRQ_ONE_ACCT_EXPTIME", "KRB5_LRQ_ONE_LAST_INITIAL", "KRB5_LRQ_ONE_LAST_RENEWAL", "KRB5_LRQ_ONE_LAST_REQ", "KRB5_LRQ_ONE_LAST_TGT", "KRB5_LRQ_ONE_LAST_TGT_ISSUED", "KRB5_LRQ_ONE_PW_EXPTIME", "KRB5_NT_ENTERPRISE_PRINCIPAL", "KRB5_NT_ENT_PRINCIPAL_AND_ID", "KRB5_NT_MS_PRINCIPAL", "KRB5_NT_MS_PRINCIPAL_AND_ID", "KRB5_NT_PRINCIPAL", "KRB5_NT_SMTP_NAME", "KRB5_NT_SRV_HST", "KRB5_NT_SRV_INST", "KRB5_NT_SRV_XHST", "KRB5_NT_UID", "KRB5_NT_UNKNOWN", "KRB5_NT_WELLKNOWN", "KRB5_NT_X500_PRINCIPAL", "KRB5_PAC_ATTRIBUTES_INFO", "KRB5_PAC_CLIENT_CLAIMS", "KRB5_PAC_CLIENT_INFO", "KRB5_PAC_CREDENTIALS_INFO", "KRB5_PAC_DELEGATION_INFO", "KRB5_PAC_DEVICE_CLAIMS", "KRB5_PAC_DEVICE_INFO", "KRB5_PAC_FULL_CHECKSUM", "KRB5_PAC_LOGON_INFO", "KRB5_PAC_PRIVSVR_CHECKSUM", "KRB5_PAC_REQUESTOR", "KRB5_PAC_SERVER_CHECKSUM", "KRB5_PAC_TICKET_CHECKSUM", "KRB5_PAC_UPN_DNS_INFO", "KRB5_PADATA_AFS3_SALT", "KRB5_PADATA_AP_REQ", "KRB5_PADATA_AS_CHECKSUM", "KRB5_PADATA_AS_FRESHNESS", "KRB5_PADATA_ENCRYPTED_CHALLENGE", "KRB5_PADATA_ENC_SANDIA_SECURID", "KRB5_PADATA_ENC_TIMESTAMP", "KRB5_PADATA_ENC_UNIX_TIME", "KRB5_PADATA_ETYPE_INFO", "KRB5_PADATA_ETYPE_INFO2", "KRB5_PADATA_FOR_USER", "KRB5_PADATA_FX_COOKIE", "KRB5_PADATA_FX_ERROR", "KRB5_PADATA_FX_FAST", "KRB5_PADATA_GET_FROM_TYPED_DATA", "KRB5_PADATA_NONE", "KRB5_PADATA_OSF_DCE", "KRB5_PADATA_OTP_CHALLENGE", "KRB5_PADATA_OTP_PIN_CHANGE", "KRB5_PADATA_OTP_REQUEST", "KRB5_PADATA_PAC_OPTIONS", "KRB5_PADATA_PAC_REQUEST", "KRB5_PADATA_PKINIT_KX", "KRB5_PADATA_PK_AS_REP", "KRB5_PADATA_PK_AS_REP_OLD", "KRB5_PADATA_PK_AS_REQ", "KRB5_PADATA_PK_AS_REQ_OLD", "KRB5_PADATA_PW_SALT", "KRB5_PADATA_REDHAT_IDP_OAUTH2", "KRB5_PADATA_REDHAT_PASSKEY", "KRB5_PADATA_REFERRAL", "KRB5_PADATA_S4U_X509_USER", "KRB5_PADATA_SAM_CHALLENGE", "KRB5_PADATA_SAM_CHALLENGE_2", "KRB5_PADATA_SAM_REDIRECT", "KRB5_PADATA_SAM_RESPONSE", "KRB5_PADATA_SAM_RESPONSE_2", "KRB5_PADATA_SESAME", "KRB5_PADATA_SPAKE", "KRB5_PADATA_SVR_REFERRAL_INFO", "KRB5_PADATA_TGS_REQ", "KRB5_PADATA_USE_SPECIFIED_KVNO", "KRB5_PRINCIPAL_COMPARE_CASEFOLD", "KRB5_PRINCIPAL_COMPARE_ENTERPRISE", "KRB5_PRINCIPAL_COMPARE_IGNORE_REALM", "KRB5_PRINCIPAL_COMPARE_UTF8", "KRB5_PRINCIPAL_PARSE_ENTERPRISE", "KRB5_PRINCIPAL_PARSE_IGNORE_REALM", "KRB5_PRINCIPAL_PARSE_NO_DEF_REALM", "KRB5_PRINCIPAL_PARSE_NO_REALM", "KRB5_PRINCIPAL_PARSE_REQUIRE_REALM", "KRB5_PRINCIPAL_UNPARSE_DISPLAY", "KRB5_PRINCIPAL_UNPARSE_NO_REALM", "KRB5_PRINCIPAL_UNPARSE_SHORT", "KRB5_PRIV", "KRB5_PROMPT_TYPE_NEW_PASSWORD", "KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN", "KRB5_PROMPT_TYPE_PASSWORD", "KRB5_PROMPT_TYPE_PREAUTH", "KRB5_PVNO", "KRB5_REALM_BRANCH_CHAR", "KRB5_RECVAUTH_BADAUTHVERS", "KRB5_RECVAUTH_SKIP_VERSION", "KRB5_REFERRAL_REALM", "KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN", "KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN", "KRB5_RESPONDER_OTP_FLAGS_NEXTOTP", "KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN", "KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC", "KRB5_RESPONDER_OTP_FORMAT_DECIMAL", "KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL", "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW", "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY", "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED", "KRB5_RESPONDER_QUESTION_OTP", "KRB5_RESPONDER_QUESTION_PASSWORD", "KRB5_RESPONDER_QUESTION_PKINIT", "KRB5_SAFE", "KRB5_SAM_MUST_PK_ENCRYPT_SAD", "KRB5_SAM_SEND_ENCRYPTED_SAD", "KRB5_SAM_USE_SAD_AS_KEY", "KRB5_TC_MATCH_2ND_TKT", "KRB5_TC_MATCH_AUTHDATA", "KRB5_TC_MATCH_FLAGS", "KRB5_TC_MATCH_FLAGS_EXACT", "KRB5_TC_MATCH_IS_SKEY", "KRB5_TC_MATCH_KTYPE", "KRB5_TC_MATCH_SRV_NAMEONLY", "KRB5_TC_MATCH_TIMES", "KRB5_TC_MATCH_TIMES_EXACT", "KRB5_TC_NOTICKET", "KRB5_TC_OPENCLOSE", "KRB5_TC_SUPPORTED_KTYPES", "KRB5_TGS_NAME", "KRB5_TGS_NAME_SIZE", "KRB5_TGS_REP", "KRB5_TGS_REQ", "KRB5_TKT_CREDS_STEP_FLAG_CONTINUE", "KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL", "KRB5_WELLKNOWN_NAMESTR", "LR_TYPE_INTERPRETATION_MASK", "LR_TYPE_THIS_SERVER_ONLY", "MAX_KEYTAB_NAME_LEN", "MSEC_DIRBIT", "MSEC_VAL_MASK", "SALT_TYPE_AFS_LENGTH", "SALT_TYPE_NO_LENGTH", "THREEPARAMOPEN", "TKT_FLG_ANONYMOUS", "TKT_FLG_ENC_PA_REP", "TKT_FLG_FORWARDABLE", "TKT_FLG_FORWARDED", "TKT_FLG_HW_AUTH", "TKT_FLG_INITIAL", "TKT_FLG_INVALID", "TKT_FLG_MAY_POSTDATE", "TKT_FLG_OK_AS_DELEGATE", "TKT_FLG_POSTDATED", "TKT_FLG_PRE_AUTH", "TKT_FLG_PROXIABLE", "TKT_FLG_PROXY", "TKT_FLG_RENEWABLE", "TKT_FLG_TRANSIT_POLICY_CHECKED", "VALID_INT_BITS", "VALID_UINT_BITS", "krb5 simple macros", "krb524_convert_creds_kdc", "krb524_init_ets", "krb5_const", "krb5_princ_component", "krb5_princ_name", "krb5_princ_realm", "krb5_princ_set_realm", "krb5_princ_set_realm_data", "krb5_princ_set_realm_length", "krb5_princ_size", "krb5_princ_type", "krb5_roundup", "krb5_x", "krb5_xc", "krb5 types and structures", "krb5_address", "krb5_addrtype", "krb5_ap_rep", "krb5_ap_rep_enc_part", "krb5_ap_req", "krb5_auth_context", "krb5_authdata", "krb5_authdatatype", "krb5_authenticator", "krb5_boolean", "krb5_cc_cursor", "krb5_ccache", "krb5_cccol_cursor", "krb5_checksum", "krb5_cksumtype", "krb5_const_pointer", "krb5_const_principal", "krb5_context", "krb5_cred", "krb5_cred_enc_part", "krb5_cred_info", "krb5_creds", "krb5_crypto_iov", "krb5_cryptotype", "krb5_data", "krb5_deltat", "krb5_enc_data", "krb5_enc_kdc_rep_part", "krb5_enc_tkt_part", "krb5_encrypt_block", "krb5_enctype", "krb5_error", "krb5_error_code", "krb5_expire_callback_func", "krb5_flags", "krb5_get_init_creds_opt", "krb5_gic_opt_pa_data", "krb5_init_creds_context", "krb5_int16", "krb5_int32", "krb5_kdc_rep", "krb5_kdc_req", "krb5_key", "krb5_keyblock", "krb5_keytab", "krb5_keytab_entry", "krb5_keyusage", "krb5_kt_cursor", "krb5_kvno", "krb5_last_req_entry", "krb5_magic", "krb5_mk_req_checksum_func", "krb5_msgtype", "krb5_octet", "krb5_pa_data", "krb5_pa_pac_req", "krb5_pa_server_referral_data", "krb5_pa_svr_referral_data", "krb5_pac", "krb5_pointer", "krb5_post_recv_fn", "krb5_pre_send_fn", "krb5_preauthtype", "krb5_principal", "krb5_principal_data", "krb5_prompt", "krb5_prompt_type", "krb5_prompter_fct", "krb5_pwd_data", "krb5_rcache", "krb5_replay_data", "krb5_responder_context", "krb5_responder_fn", "krb5_responder_otp_challenge", "krb5_responder_otp_tokeninfo", "krb5_responder_pkinit_challenge", "krb5_responder_pkinit_identity", "krb5_response", "krb5_ticket", "krb5_ticket_times", "krb5_timestamp", "krb5_tkt_authent", "krb5_tkt_creds_context", "krb5_trace_callback", "krb5_trace_info", "krb5_transited", "krb5_typed_data", "krb5_ui_2", "krb5_ui_4", "krb5_verify_init_creds_opt", "passwd_phrase_element", "Year 2038 considerations for uses of krb5_timestamp", "Credential cache", "Supported date and time formats", "Kerberos V5 concepts", "keytab", "replay cache", "stash file", "Organization of the source directory", "Doing the build", "Building Kerberos V5", "Options to configure", "osconf.hin", "How to build this documentation from the source", "Copyright", "Credential cache file format", "KDC cookie format", "Kerberos Database (KDB) Formats", "PKINIT freshness tokens", "Protocols and file formats", "Keytab file format", "Replay cache file format", "MIT Kerberos Documentation (1.22.1)", "MIT Kerberos defaults", "MIT Kerberos features", "MIT Kerberos License information", "Credential cache selection interface (ccselect)", "PKINIT certificate authorization interface (certauth)", "Client preauthentication interface (clpreauth)", "General plugin concepts", "GSSAPI mechanism interface", "Host-to-realm interface (hostrealm)", "For plugin module developers", "Internal pluggable interfaces", "kadmin authorization interface (kadm5_auth)", "KADM5 hook interface (kadm5_hook)", "KDC policy interface (kdcpolicy)", "KDC preauthentication interface (kdcpreauth)", "Local authorization interface (localauth)", "Server location interface (locate)", "Configuration interface (profile)", "Password quality interface (pwqual)", "Resources", "For users", "Password management", "Ticket management", "User commands", "kdestroy", "kinit", "klist", "kpasswd", "krb5-config", "ksu", "kswitch", "kvno", "sclient", "User config files", ".k5identity", ".k5login", "kerberos"], "terms": {"we": [0, 23, 28, 32, 34, 43, 910, 911, 912, 925], "ar": [0, 2, 3, 4, 5, 6, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 33, 34, 35, 36, 37, 38, 39, 40, 43, 46, 52, 53, 66, 78, 80, 83, 92, 100, 103, 105, 107, 153, 154, 164, 166, 218, 225, 231, 232, 233, 243, 247, 250, 254, 271, 281, 282, 290, 292, 327, 332, 344, 347, 350, 351, 352, 361, 363, 364, 368, 377, 383, 384, 385, 406, 410, 416, 737, 833, 843, 853, 891, 903, 904, 906, 907, 909, 910, 912, 914, 916, 917, 918, 919, 921, 922, 924, 925, 926, 927, 929, 930, 931, 934, 936, 937, 939, 940, 942, 946, 948, 949, 951, 952, 953, 955, 958, 960], "look": [0, 8, 12, 15, 20, 21, 23, 28, 37, 38, 39, 43, 391, 910, 912, 918, 930, 946, 949, 953], "writer": 0, "editor": 0, "who": [0, 5, 16, 20, 25, 34, 37, 918, 945, 946], "could": [0, 14, 16, 17, 21, 25, 28, 33, 34, 35, 39, 907, 925, 930, 945, 946, 953], "toward": [0, 23], "improv": [0, 14, 20, 21, 35, 925, 943], "kc": 0, "content": [0, 6, 9, 11, 12, 14, 23, 27, 34, 37, 43, 44, 46, 48, 82, 84, 124, 133, 137, 147, 148, 174, 175, 177, 178, 180, 182, 183, 198, 199, 200, 201, 202, 208, 209, 213, 216, 222, 282, 335, 336, 811, 817, 824, 833, 854, 865, 896, 903, 916, 918, 919, 921, 926, 931, 949, 950], "If": [0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 46, 54, 56, 99, 100, 101, 102, 103, 113, 129, 152, 154, 156, 158, 159, 161, 169, 192, 224, 225, 231, 232, 233, 237, 247, 252, 253, 255, 262, 266, 269, 271, 281, 282, 289, 290, 291, 292, 296, 300, 302, 303, 312, 317, 319, 327, 328, 329, 332, 333, 338, 344, 345, 346, 347, 354, 358, 361, 362, 363, 377, 379, 384, 385, 388, 390, 399, 406, 409, 416, 418, 737, 871, 872, 883, 903, 904, 907, 908, 910, 911, 912, 914, 916, 917, 925, 926, 928, 930, 931, 932, 938, 939, 941, 945, 946, 948, 949, 950, 951, 953, 954, 955, 958, 960], "you": [0, 3, 5, 12, 15, 16, 17, 20, 21, 22, 23, 24, 28, 32, 33, 34, 35, 37, 39, 40, 41, 743, 904, 908, 910, 911, 912, 913, 914, 926, 943, 945, 946, 948, 953, 960], "an": [0, 2, 3, 4, 5, 6, 8, 9, 11, 12, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 46, 48, 55, 56, 61, 93, 99, 101, 119, 126, 144, 146, 154, 231, 237, 238, 243, 245, 249, 262, 265, 267, 278, 279, 281, 289, 302, 303, 314, 317, 322, 328, 329, 332, 333, 344, 357, 358, 362, 367, 368, 375, 377, 390, 396, 406, 409, 414, 416, 728, 741, 742, 744, 819, 827, 833, 843, 874, 875, 883, 902, 906, 907, 910, 911, 912, 916, 917, 918, 919, 922, 924, 925, 926, 927, 929, 930, 931, 934, 935, 936, 938, 939, 940, 941, 942, 945, 946, 949, 951, 953, 955, 960], "experienc": [0, 940], "develop": [0, 910, 923, 925, 926, 943, 960], "administr": [0, 2, 3, 4, 5, 6, 11, 14, 15, 16, 18, 19, 20, 21, 22, 24, 25, 26, 31, 32, 35, 36, 38, 903, 909, 918, 923, 924, 925, 926, 936, 943, 945, 949, 959, 960], "pleas": [0, 15, 20, 744, 943], "consid": [0, 14, 21, 24, 33, 39, 41, 344, 907, 912, 916], "share": [0, 14, 21, 23, 28, 46, 332, 912, 930, 931, 941, 945], "your": [0, 12, 17, 20, 21, 26, 32, 33, 34, 37, 39, 910, 911, 912, 926, 934, 944, 946, 948, 957, 960], "knowledg": [0, 14, 17, 416, 929, 938], "experi": [0, 14, 39, 925], "commun": [0, 21, 23, 25, 29, 34, 37, 43, 871, 903, 909, 918, 926, 927, 943], "can": [0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 46, 50, 56, 136, 138, 154, 225, 256, 273, 303, 309, 333, 344, 346, 368, 388, 391, 402, 405, 416, 418, 743, 871, 872, 882, 890, 902, 903, 904, 906, 907, 910, 911, 912, 914, 916, 917, 918, 925, 927, 928, 929, 930, 931, 932, 934, 935, 936, 937, 938, 939, 940, 942, 945, 946, 949, 953, 957, 960], "suggest": [0, 247], "own": [0, 3, 15, 20, 21, 23, 24, 25, 34, 38, 383, 925, 928, 930, 931, 942, 945, 946, 953, 959], "topic": [0, 30, 34], "write": [0, 6, 8, 10, 11, 20, 21, 22, 23, 24, 28, 34, 35, 253, 354, 389, 903, 922, 925, 930, 941, 960], "about": [0, 14, 19, 20, 22, 23, 26, 31, 39, 41, 43, 46, 253, 907, 910, 912, 914, 925, 926, 929, 938, 943, 946, 949, 960], "ani": [0, 3, 4, 6, 8, 9, 10, 14, 15, 16, 17, 19, 20, 21, 23, 24, 25, 26, 28, 32, 34, 36, 37, 38, 39, 40, 41, 43, 46, 48, 56, 137, 147, 153, 154, 156, 225, 262, 270, 277, 280, 281, 312, 317, 361, 365, 366, 406, 416, 746, 843, 903, 907, 908, 916, 917, 922, 925, 926, 927, 931, 932, 939, 945, 946, 949, 950, 953, 959], "list": [0, 2, 3, 4, 6, 10, 14, 15, 19, 21, 23, 26, 28, 32, 34, 36, 39, 40, 43, 46, 48, 93, 153, 164, 184, 189, 195, 215, 232, 233, 322, 380, 414, 419, 420, 421, 839, 882, 903, 912, 913, 924, 926, 928, 929, 932, 938, 941, 945, 946, 950, 953, 958, 959], "here": [0, 15, 19, 20, 21, 23, 28, 35, 41, 43, 46, 904, 912, 918, 930, 945, 946], "have": [0, 2, 3, 6, 8, 12, 14, 15, 17, 19, 20, 21, 23, 24, 25, 26, 28, 32, 33, 34, 35, 37, 38, 39, 43, 46, 101, 153, 232, 276, 404, 903, 907, 910, 911, 914, 916, 917, 918, 921, 922, 925, 926, 927, 929, 930, 931, 934, 935, 936, 938, 940, 942, 945, 946, 949, 953, 957, 959, 960], "question": [0, 20, 39, 48, 370, 373, 744, 745, 746, 882, 883, 943], "comment": [0, 15, 21], "exist": [0, 2, 3, 5, 6, 14, 15, 20, 21, 22, 23, 26, 28, 32, 34, 35, 43, 46, 48, 137, 147, 155, 331, 332, 361, 365, 366, 377, 409, 416, 903, 908, 916, 925, 931, 949, 951, 953], "send": [0, 4, 15, 20, 21, 23, 25, 26, 32, 34, 41, 48, 231, 247, 327, 365, 377, 382, 907, 909, 912, 925, 943, 945, 949, 960], "feedback": 0, "via": [0, 3, 4, 6, 8, 10, 20, 21, 34, 35, 43, 46, 48, 276, 388, 404, 832, 925, 931, 933, 953, 959], "email": [0, 648, 945], "krb5": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 953, 954, 955, 956, 957, 958, 959, 960], "bug": [0, 23, 42, 909, 910, 943], "edu": [0, 3, 5, 12, 14, 15, 19, 20, 21, 23, 24, 28, 32, 34, 42, 925, 926, 941, 943, 945, 946, 953], "The": [0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 31, 33, 34, 35, 37, 38, 39, 40, 41, 43, 46, 53, 62, 69, 71, 74, 78, 80, 91, 93, 99, 100, 102, 103, 113, 117, 119, 121, 125, 126, 129, 135, 136, 138, 144, 146, 148, 153, 165, 166, 173, 176, 189, 198, 200, 218, 221, 225, 230, 231, 247, 250, 254, 264, 270, 276, 284, 288, 289, 290, 291, 292, 296, 298, 300, 302, 307, 309, 314, 317, 322, 323, 324, 327, 328, 333, 335, 346, 347, 348, 356, 358, 361, 362, 367, 368, 369, 370, 371, 372, 373, 374, 375, 378, 382, 383, 384, 385, 391, 400, 404, 405, 407, 408, 409, 410, 414, 416, 422, 624, 736, 744, 746, 751, 752, 755, 756, 758, 762, 813, 819, 833, 843, 856, 871, 872, 876, 882, 889, 902, 903, 904, 906, 907, 908, 909, 910, 911, 912, 913, 914, 916, 917, 918, 919, 921, 922, 924, 925, 926, 927, 928, 929, 930, 931, 932, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 945, 946, 948, 949, 951, 953, 955, 957, 958, 959, 960], "html": [0, 22, 42, 911, 914, 925], "version": [0, 2, 3, 5, 6, 9, 10, 14, 20, 23, 24, 26, 29, 38, 42, 43, 44, 48, 155, 230, 249, 312, 317, 365, 377, 622, 729, 827, 829, 851, 856, 889, 902, 906, 910, 911, 912, 914, 916, 918, 919, 921, 922, 925, 926, 930, 936, 940, 950, 952, 953, 955, 956, 960], "thi": [0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 14, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 46, 48, 49, 50, 55, 57, 58, 59, 60, 61, 62, 67, 68, 69, 71, 72, 73, 74, 76, 77, 78, 81, 82, 84, 85, 86, 87, 88, 89, 92, 93, 98, 99, 100, 101, 102, 103, 104, 105, 107, 113, 114, 116, 117, 119, 120, 122, 123, 124, 125, 126, 129, 130, 133, 136, 137, 139, 141, 144, 148, 150, 151, 153, 156, 157, 158, 159, 167, 169, 171, 172, 173, 174, 175, 177, 178, 180, 181, 182, 183, 192, 194, 195, 198, 199, 200, 201, 202, 203, 206, 207, 208, 209, 210, 213, 216, 217, 222, 230, 237, 238, 243, 245, 247, 248, 254, 255, 256, 260, 262, 263, 264, 266, 267, 268, 269, 272, 273, 274, 277, 278, 279, 280, 281, 289, 290, 291, 292, 296, 297, 298, 300, 301, 303, 310, 319, 322, 325, 326, 327, 328, 329, 331, 332, 333, 335, 336, 344, 345, 347, 354, 357, 358, 359, 360, 361, 362, 363, 365, 366, 370, 373, 375, 377, 378, 380, 382, 384, 385, 387, 388, 389, 391, 398, 402, 403, 405, 406, 409, 410, 412, 414, 416, 418, 419, 421, 734, 735, 736, 737, 741, 742, 743, 745, 838, 856, 890, 891, 902, 903, 907, 908, 909, 910, 911, 912, 916, 917, 918, 922, 923, 924, 925, 926, 927, 929, 931, 933, 935, 936, 937, 938, 939, 941, 942, 943, 945, 946, 948, 949, 950, 952, 953, 955, 959, 960], "ha": [0, 3, 5, 6, 12, 14, 15, 17, 19, 20, 21, 23, 24, 25, 26, 27, 28, 34, 35, 37, 38, 39, 43, 46, 78, 124, 262, 265, 281, 358, 362, 390, 406, 745, 903, 907, 910, 911, 912, 916, 917, 918, 921, 922, 925, 926, 931, 935, 936, 937, 940, 945, 946, 950, 953, 958], "link": [0, 30, 34, 907, 910, 911, 912, 914, 918, 928, 931, 952], "address": [0, 4, 10, 15, 20, 21, 23, 24, 30, 33, 38, 39, 44, 48, 262, 327, 328, 333, 358, 361, 362, 528, 529, 530, 531, 811, 830, 832, 839, 852, 912, 916, 925, 940, 946, 949, 950], "pre": [0, 16, 20, 22, 43, 48, 91, 262, 331, 332, 361, 365, 366, 377, 382, 865, 914, 917, 925, 926, 936, 949], "construct": [0, 43, 46, 279, 281, 331, 406, 871, 872, 925, 930, 955], "subject": [0, 20, 21, 23, 37, 926], "line": [0, 3, 8, 10, 12, 15, 19, 20, 21, 23, 28, 34, 35, 37, 354, 911, 912, 918, 925, 926, 945, 953, 955, 958, 959, 960], "start": [0, 3, 4, 6, 8, 10, 14, 15, 19, 20, 21, 23, 24, 26, 31, 37, 41, 48, 831, 839, 852, 890, 903, 908, 910, 919, 925, 946, 953], "releas": [0, 3, 4, 6, 8, 10, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 33, 35, 37, 38, 39, 40, 41, 43, 46, 48, 68, 73, 77, 82, 84, 91, 93, 113, 125, 126, 154, 163, 176, 203, 210, 215, 232, 233, 267, 270, 284, 296, 316, 320, 346, 902, 903, 907, 917, 918, 919, 921, 922, 925, 928, 929, 930, 931, 932, 934, 935, 936, 937, 938, 939, 949, 955, 960], "1": [0, 3, 4, 5, 6, 8, 10, 11, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 28, 33, 34, 35, 37, 38, 39, 40, 41, 42, 43, 44, 46, 48, 87, 89, 91, 93, 119, 132, 143, 154, 155, 160, 165, 166, 167, 169, 192, 194, 195, 203, 205, 210, 212, 220, 228, 231, 247, 248, 249, 252, 255, 259, 267, 288, 302, 303, 305, 309, 315, 338, 345, 346, 367, 368, 369, 370, 371, 372, 373, 374, 375, 382, 383, 388, 389, 399, 401, 402, 403, 404, 405, 406, 518, 540, 546, 556, 572, 574, 586, 625, 632, 640, 647, 664, 671, 687, 714, 740, 741, 742, 743, 807, 808, 902, 903, 904, 907, 911, 912, 914, 916, 918, 919, 921, 922, 925, 928, 929, 930, 931, 932, 935, 936, 937, 938, 939, 941, 949, 950, 952, 953, 955, 958, 959, 960], "11": [0, 6, 8, 14, 15, 20, 21, 23, 26, 41, 43, 165, 169, 252, 259, 305, 315, 367, 368, 369, 370, 371, 375, 510, 582, 654, 660, 678, 746, 916, 918, 925, 946], "set": [0, 3, 4, 5, 6, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 43, 44, 46, 48, 62, 68, 69, 73, 74, 77, 78, 98, 102, 145, 153, 154, 161, 164, 203, 210, 225, 231, 255, 281, 282, 288, 291, 303, 307, 319, 327, 328, 333, 354, 356, 358, 361, 362, 363, 371, 375, 379, 389, 406, 409, 410, 411, 422, 551, 737, 753, 871, 872, 882, 903, 904, 907, 912, 918, 925, 928, 931, 938, 939, 945, 946, 948, 949, 950, 953, 959, 960], "i": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 46, 48, 49, 53, 54, 55, 56, 59, 60, 65, 67, 68, 72, 73, 76, 77, 78, 85, 91, 92, 93, 98, 99, 100, 101, 102, 103, 107, 111, 113, 114, 119, 120, 122, 123, 124, 125, 126, 129, 130, 132, 136, 141, 143, 144, 145, 148, 150, 151, 153, 154, 155, 156, 158, 160, 163, 164, 165, 169, 171, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 189, 192, 194, 195, 218, 224, 225, 228, 229, 230, 231, 232, 233, 237, 238, 243, 245, 247, 248, 252, 253, 255, 260, 262, 263, 266, 267, 269, 270, 271, 274, 277, 280, 282, 284, 286, 287, 288, 289, 290, 291, 292, 296, 297, 298, 300, 301, 302, 303, 304, 307, 308, 312, 317, 318, 319, 320, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 337, 338, 340, 341, 344, 345, 346, 347, 354, 356, 357, 358, 359, 361, 362, 363, 365, 366, 367, 368, 370, 373, 374, 375, 377, 378, 379, 382, 384, 385, 388, 389, 390, 391, 399, 400, 403, 405, 407, 408, 409, 410, 411, 414, 416, 419, 421, 719, 720, 723, 736, 737, 743, 744, 745, 746, 799, 814, 832, 833, 838, 868, 871, 882, 883, 891, 902, 903, 904, 906, 907, 908, 909, 910, 911, 912, 913, 914, 916, 917, 918, 919, 921, 922, 924, 925, 926, 927, 928, 929, 930, 931, 932, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 945, 946, 948, 949, 950, 951, 952, 953, 954, 955, 956, 958, 959, 960], "unifi": 0, "central": 0, "form": [0, 3, 15, 20, 21, 24, 25, 28, 29, 34, 39, 43, 152, 319, 327, 328, 333, 375, 391, 648, 882, 903, 908, 917, 918, 925, 926, 949, 958, 960], "man": [0, 3, 21, 907, 912, 925], "page": [0, 3, 21, 23, 911, 912, 925], "pdf": 0, "compil": [0, 910, 911, 912, 913, 925, 926, 952, 953], "from": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, 19, 20, 21, 22, 23, 24, 25, 28, 29, 32, 34, 35, 37, 38, 39, 41, 43, 44, 46, 48, 49, 93, 99, 100, 101, 102, 103, 113, 119, 121, 129, 148, 166, 169, 180, 181, 183, 195, 243, 247, 252, 260, 271, 289, 290, 291, 292, 296, 300, 324, 329, 332, 344, 348, 354, 358, 359, 360, 361, 362, 377, 378, 380, 382, 384, 385, 416, 422, 445, 838, 851, 852, 903, 906, 907, 910, 911, 912, 916, 917, 918, 922, 923, 925, 926, 927, 928, 929, 931, 933, 934, 936, 941, 943, 945, 946, 949, 951, 953, 955, 958, 960], "restructuredtext": 0, "sourc": [0, 10, 22, 23, 28, 34, 39, 42, 43, 910, 911, 912, 923, 926, 930, 934, 941, 943, 953], "applic": [0, 12, 16, 18, 20, 21, 28, 30, 31, 37, 43, 46, 48, 59, 60, 156, 252, 331, 332, 333, 365, 377, 509, 533, 534, 724, 747, 902, 903, 906, 907, 909, 912, 923, 925, 926, 929, 931, 934, 939, 941, 945, 946, 952, 956, 959], "incorpor": [0, 20, 24, 925], "doxygen": [0, 914], "markup": [0, 914], "tree": [0, 22, 23, 24, 34, 911, 912, 914, 931, 934, 941], "project": [0, 707, 912, 925, 926, 930, 960], "wa": [0, 3, 6, 8, 12, 14, 17, 20, 21, 23, 24, 26, 39, 41, 43, 44, 48, 155, 206, 247, 275, 316, 344, 361, 741, 906, 916, 917, 918, 925, 926, 928, 932, 936, 937, 939, 945, 946, 949, 952, 953, 960], "undertaken": 0, "along": [0, 36, 833, 903, 912, 931], "outlin": [0, 29], "describ": [0, 3, 14, 16, 21, 23, 24, 25, 28, 32, 34, 37, 43, 377, 408, 833, 842, 843, 902, 916, 918, 926, 929, 930, 931, 933, 941, 946, 953], "previou": [0, 3, 21, 23, 34, 37, 42, 44, 156, 252, 263, 281, 386, 406, 421, 422, 916, 918], "5": [0, 3, 6, 10, 12, 14, 19, 20, 21, 23, 31, 34, 36, 37, 43, 119, 322, 414, 512, 544, 617, 620, 631, 639, 652, 677, 729, 904, 909, 914, 916, 917, 918, 921, 925, 926, 948, 949, 950, 952, 953, 954, 956, 960], "attempt": [0, 3, 6, 20, 21, 24, 29, 35, 39, 43, 245, 252, 416, 916, 925, 953], "maintain": [0, 9, 15, 20, 23, 910, 912, 960], "separ": [0, 3, 5, 6, 10, 16, 19, 20, 21, 22, 23, 24, 25, 28, 39, 50, 303, 346, 348, 422, 737, 911, 912, 917, 918, 925, 931, 941, 945, 960], "texinfo": 0, "format": [0, 3, 6, 19, 20, 21, 36, 39, 43, 48, 323, 348, 407, 408, 419, 421, 422, 739, 744, 746, 885, 895, 903, 905, 906, 907, 912, 914, 919, 923, 925, 930, 931, 953, 955, 960], "groff": 0, "manual": [0, 6, 10, 15, 23, 33, 34, 910, 912, 925], "api": [0, 14, 41, 43, 45, 98, 100, 103, 186, 188, 190, 191, 196, 197, 247, 252, 253, 264, 283, 290, 292, 353, 355, 413, 746, 833, 853, 903, 909, 912, 925, 927, 931, 938], "disjoint": 0, "code": [0, 20, 21, 23, 41, 43, 46, 48, 49, 50, 56, 62, 64, 65, 67, 69, 72, 73, 74, 76, 77, 78, 79, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 117, 118, 119, 121, 124, 125, 126, 129, 130, 133, 134, 135, 141, 142, 145, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 161, 162, 163, 164, 166, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187, 189, 192, 193, 215, 218, 224, 225, 229, 231, 233, 237, 253, 262, 263, 264, 266, 267, 268, 269, 270, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 284, 289, 290, 291, 292, 296, 297, 298, 300, 301, 302, 303, 304, 305, 307, 308, 310, 312, 313, 316, 317, 318, 319, 320, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 337, 339, 340, 341, 344, 346, 347, 349, 354, 356, 357, 358, 359, 360, 361, 362, 363, 365, 366, 376, 377, 378, 379, 380, 384, 385, 386, 387, 391, 398, 399, 400, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 416, 736, 842, 843, 871, 891, 902, 909, 911, 912, 925, 926, 929, 930, 931, 934, 936, 938, 940, 941, 942, 943], "implement": [0, 14, 20, 21, 23, 24, 28, 29, 36, 38, 40, 43, 44, 46, 51, 113, 119, 151, 296, 384, 385, 903, 910, 912, 916, 919, 921, 925, 926, 927, 928, 929, 930, 931, 932, 934, 935, 936, 938, 939, 940, 941, 942, 943, 946, 953, 960], "result": [0, 14, 15, 21, 23, 37, 39, 40, 41, 43, 46, 48, 99, 102, 107, 117, 124, 144, 156, 158, 189, 195, 230, 289, 291, 298, 322, 377, 378, 405, 407, 408, 409, 422, 912, 916, 917, 922, 925, 926, 927, 931, 932, 937, 938, 939, 946, 953, 955], "becom": [0, 6, 14, 17, 21, 23, 34, 39, 136, 237, 262, 277, 903, 918, 925, 945, 949, 953], "stale": [0, 21, 26], "over": [0, 10, 14, 15, 20, 21, 23, 24, 28, 32, 34, 36, 38, 39, 43, 46, 48, 107, 113, 114, 117, 155, 164, 296, 297, 298, 302, 303, 327, 365, 377, 823, 925, 927, 933, 941, 945, 946], "time": [0, 2, 3, 5, 6, 9, 10, 14, 15, 19, 20, 21, 22, 23, 24, 26, 28, 34, 35, 36, 37, 39, 41, 43, 44, 48, 136, 158, 225, 230, 237, 247, 262, 277, 358, 361, 362, 400, 741, 758, 759, 814, 830, 831, 832, 838, 839, 852, 856, 890, 902, 903, 905, 907, 908, 912, 913, 916, 917, 918, 922, 924, 925, 926, 931, 937, 945, 946, 949, 950, 953, 960], "ceas": [0, 6], "match": [0, 2, 3, 6, 15, 19, 20, 21, 28, 29, 33, 37, 38, 43, 48, 59, 60, 119, 151, 153, 195, 224, 225, 269, 303, 312, 361, 365, 377, 405, 751, 752, 753, 754, 755, 756, 757, 759, 762, 852, 903, 907, 922, 924, 925, 941, 955, 958, 960], "realiti": 0, "With": [0, 3, 6, 22, 23, 39, 959], "fresh": [0, 15, 17, 20, 43, 604, 920, 925, 949, 953], "easier": [0, 14, 925], "us": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 45, 46, 49, 55, 56, 65, 66, 67, 68, 69, 72, 73, 74, 76, 77, 78, 81, 83, 98, 100, 103, 105, 111, 113, 115, 117, 121, 125, 129, 132, 141, 143, 144, 145, 150, 153, 156, 163, 164, 169, 172, 173, 174, 175, 177, 178, 180, 181, 182, 183, 195, 224, 225, 228, 229, 230, 231, 232, 233, 238, 241, 243, 248, 249, 250, 252, 256, 260, 263, 269, 270, 274, 277, 279, 281, 282, 288, 290, 292, 296, 300, 302, 311, 312, 317, 319, 320, 323, 324, 326, 327, 328, 329, 330, 331, 333, 334, 337, 340, 341, 342, 343, 346, 347, 354, 356, 357, 358, 359, 361, 362, 365, 368, 377, 380, 391, 403, 405, 406, 407, 408, 409, 410, 416, 418, 444, 452, 453, 568, 569, 604, 605, 624, 746, 831, 843, 853, 862, 871, 872, 876, 882, 890, 891, 906, 907, 908, 909, 911, 914, 916, 917, 918, 919, 921, 922, 924, 925, 926, 927, 928, 929, 930, 931, 932, 934, 938, 939, 941, 942, 943, 945, 946, 948, 949, 950, 951, 952, 953, 955, 956, 957, 958, 959, 960], "base": [0, 3, 20, 21, 22, 23, 24, 25, 26, 34, 37, 38, 39, 43, 46, 49, 59, 60, 62, 91, 93, 98, 117, 298, 346, 390, 903, 907, 914, 924, 925, 926, 929, 934, 938, 942, 946, 949, 958], "should": [0, 2, 3, 4, 5, 6, 10, 12, 14, 15, 17, 20, 21, 22, 23, 24, 25, 26, 28, 29, 32, 33, 34, 37, 38, 39, 43, 46, 71, 85, 144, 152, 224, 247, 251, 257, 271, 281, 310, 319, 327, 329, 332, 344, 361, 363, 367, 368, 406, 746, 866, 871, 872, 891, 902, 903, 904, 908, 910, 912, 916, 919, 925, 926, 927, 928, 929, 930, 931, 935, 936, 937, 938, 940, 941, 942, 945, 946, 949, 953, 955, 960], "provid": [0, 3, 4, 10, 15, 21, 22, 23, 24, 26, 28, 29, 32, 34, 37, 38, 39, 41, 43, 46, 98, 231, 361, 374, 416, 902, 903, 910, 912, 925, 926, 928, 931, 934, 937, 941, 945, 953, 960], "user": [0, 3, 5, 6, 8, 14, 15, 16, 19, 20, 21, 22, 23, 25, 26, 33, 34, 35, 36, 37, 38, 39, 41, 43, 48, 56, 90, 136, 169, 225, 229, 328, 332, 333, 335, 363, 556, 647, 669, 736, 743, 876, 903, 904, 907, 909, 910, 912, 914, 918, 923, 924, 925, 926, 929, 942, 943, 945, 946, 948, 949, 951, 953, 955, 958, 959, 960], "consolid": 0, "all": [0, 2, 3, 6, 9, 14, 15, 17, 18, 19, 20, 21, 23, 24, 25, 26, 28, 29, 32, 33, 34, 35, 37, 38, 43, 46, 48, 153, 163, 164, 284, 344, 361, 416, 753, 754, 759, 823, 833, 903, 904, 907, 910, 911, 915, 916, 918, 922, 925, 926, 937, 939, 946, 948, 950, 951, 952, 953, 955, 958, 960], "singl": [0, 3, 14, 15, 20, 21, 24, 26, 28, 32, 34, 37, 39, 40, 43, 46, 48, 189, 322, 347, 411, 716, 903, 912, 925, 938, 953], "make": [0, 3, 6, 12, 14, 15, 17, 20, 21, 22, 23, 25, 26, 28, 32, 33, 34, 35, 37, 39, 41, 43, 48, 112, 238, 243, 252, 303, 370, 373, 405, 902, 910, 911, 912, 914, 916, 925, 926, 931, 945, 949, 954], "bindir": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "sbindir": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "libdir": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "localstatedir": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "krb5kdc": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "runstatedir": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "sysconfdir": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "defccnam": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "defktnam": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "defcktnam": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "pkcs11_modnam": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "etc": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "conf": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "aes256": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "ct": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "hmac": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "sha1": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "96": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "normal": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "aes128": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "sha384": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "192": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "sha256": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "128": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "des3": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "cbc": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "arcfour": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "md5": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "camellia256": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "cmac": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "camellia128": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960], "kadmin": [1, 2, 4, 5, 6, 8, 10, 11, 12, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 32, 34, 35, 37, 39, 40, 166, 247, 302, 303, 384, 903, 904, 906, 909, 925, 926, 933, 936, 951, 952, 960], "kadmind": [1, 3, 5, 9, 19, 20, 21, 22, 23, 24, 26, 28, 34, 39, 908, 918, 925, 933, 951, 960], "kdb5_util": [1, 4, 7, 8, 10, 11, 14, 20, 22, 23, 24, 26, 34, 904, 909, 918, 924, 925, 960], "kdb5_ldap_util": [1, 3, 4, 10, 20, 22, 23, 24], "kprop": [1, 4, 6, 8, 15, 23, 24, 34, 35, 909, 924, 925, 926, 960], "kpropd": [1, 4, 7, 9, 23, 34, 41, 909, 924, 925], "kproplog": [1, 8, 926], "ktutil": [1, 2, 906, 909, 925], "k5srvutil": [1, 14, 26, 906], "sserver": [1, 956], "oper": [2, 3, 5, 9, 10, 14, 15, 19, 20, 21, 22, 24, 26, 28, 33, 34, 35, 37, 41, 43, 48, 62, 119, 121, 136, 156, 158, 384, 385, 388, 761, 843, 853, 903, 909, 910, 911, 912, 917, 922, 924, 925, 926, 935, 939, 949, 953, 960], "f": [2, 4, 5, 6, 7, 8, 11, 14, 22, 33, 34, 914, 925, 946, 949, 950, 953, 955], "filenam": [2, 3, 5, 6, 7, 8, 15, 20, 21, 28, 34, 36, 37, 41, 43, 48, 205, 389, 903, 907, 925, 960], "e": [2, 3, 6, 9, 11, 14, 19, 20, 21, 22, 23, 33, 34, 37, 38, 39, 46, 876, 903, 908, 910, 911, 912, 917, 919, 941, 945, 949, 950, 953, 955, 960], "keysalt": [2, 3, 924], "allow": [2, 3, 4, 5, 6, 8, 10, 12, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 26, 28, 29, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 46, 48, 111, 254, 281, 361, 406, 409, 904, 906, 908, 910, 912, 914, 917, 918, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 945, 946, 949, 952, 959], "kei": [2, 3, 5, 6, 9, 10, 11, 12, 15, 16, 19, 20, 21, 25, 28, 32, 34, 36, 37, 38, 40, 41, 43, 46, 48, 73, 77, 87, 89, 100, 103, 105, 106, 108, 113, 114, 117, 119, 129, 130, 141, 153, 155, 181, 217, 225, 231, 236, 260, 278, 279, 282, 294, 295, 302, 303, 309, 310, 315, 322, 327, 332, 344, 345, 353, 356, 361, 365, 366, 414, 416, 444, 445, 677, 746, 756, 762, 819, 831, 832, 838, 839, 840, 853, 854, 856, 906, 907, 908, 909, 912, 913, 916, 917, 919, 924, 925, 929, 931, 938, 946, 949, 950, 955, 960], "current": [2, 3, 6, 8, 9, 11, 14, 20, 21, 23, 28, 39, 48, 136, 179, 228, 332, 348, 358, 362, 384, 445, 748, 895, 903, 906, 912, 916, 918, 922, 925, 929, 932, 933, 938, 946, 951, 958, 960], "keytab": [2, 3, 7, 8, 11, 12, 14, 17, 21, 23, 26, 28, 31, 41, 43, 46, 48, 306, 312, 313, 314, 316, 319, 320, 361, 365, 366, 418, 903, 905, 907, 908, 912, 913, 916, 920, 924, 925, 949, 950, 952, 953, 955, 960], "obtain": [2, 3, 15, 16, 17, 20, 21, 23, 25, 26, 33, 34, 37, 43, 46, 48, 80, 135, 232, 260, 273, 276, 331, 332, 361, 377, 404, 405, 416, 445, 624, 843, 903, 906, 912, 922, 925, 926, 941, 942, 944, 945, 949, 953, 955], "new": [2, 3, 6, 14, 20, 21, 23, 24, 26, 34, 35, 37, 39, 41, 43, 48, 87, 89, 129, 132, 138, 143, 154, 160, 163, 165, 166, 167, 169, 172, 173, 174, 175, 176, 177, 178, 180, 182, 183, 192, 194, 195, 205, 212, 220, 228, 231, 237, 245, 247, 248, 252, 255, 259, 262, 264, 271, 277, 282, 300, 302, 303, 305, 309, 315, 329, 332, 338, 340, 345, 346, 347, 361, 367, 368, 369, 370, 371, 372, 373, 374, 375, 382, 383, 384, 385, 388, 389, 401, 402, 403, 404, 405, 406, 409, 725, 726, 903, 907, 922, 925, 926, 930, 931, 934, 935, 938, 945, 946, 949, 951, 960], "princip": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 19, 20, 21, 22, 24, 25, 26, 28, 29, 30, 31, 32, 33, 36, 37, 40, 41, 43, 45, 46, 48, 78, 141, 147, 148, 153, 155, 159, 166, 224, 231, 237, 244, 262, 266, 269, 277, 302, 303, 312, 317, 322, 331, 335, 342, 343, 344, 345, 361, 365, 366, 377, 405, 408, 409, 410, 411, 414, 416, 506, 647, 654, 669, 713, 715, 757, 769, 831, 832, 838, 842, 851, 852, 856, 868, 903, 904, 906, 907, 913, 917, 919, 921, 924, 925, 927, 928, 934, 935, 937, 938, 939, 942, 945, 946, 949, 950, 951, 953, 954, 955, 958, 959, 960], "delet": [2, 3, 5, 6, 11, 19, 21, 23, 151, 907, 925, 926, 945, 948, 953, 960], "non": [2, 3, 14, 19, 21, 23, 26, 33, 37, 43, 44, 99, 100, 102, 103, 113, 129, 130, 155, 225, 243, 247, 252, 271, 289, 290, 291, 292, 296, 300, 301, 302, 317, 332, 344, 361, 377, 384, 390, 871, 916, 918, 921, 925, 949, 952, 953], "must": [2, 3, 4, 7, 8, 10, 11, 14, 15, 19, 20, 21, 23, 24, 26, 28, 29, 32, 33, 34, 35, 36, 37, 39, 43, 46, 57, 58, 69, 74, 78, 99, 100, 102, 103, 113, 117, 119, 121, 125, 126, 136, 146, 152, 153, 158, 173, 176, 195, 198, 200, 221, 225, 230, 243, 249, 270, 272, 273, 276, 277, 281, 284, 289, 290, 291, 292, 296, 298, 314, 316, 319, 324, 328, 333, 347, 361, 370, 373, 375, 377, 404, 409, 734, 735, 737, 744, 746, 748, 751, 752, 753, 754, 755, 756, 757, 758, 759, 762, 833, 853, 876, 903, 910, 911, 912, 916, 917, 919, 921, 922, 925, 926, 928, 930, 931, 932, 935, 937, 938, 939, 941, 945, 946, 951, 953, 955, 960], "one": [2, 3, 5, 6, 9, 15, 16, 17, 19, 20, 21, 23, 24, 25, 26, 28, 32, 34, 35, 36, 37, 38, 39, 40, 41, 43, 46, 48, 153, 165, 245, 265, 266, 272, 273, 277, 281, 332, 335, 346, 358, 362, 391, 746, 903, 904, 906, 907, 910, 912, 913, 914, 916, 917, 918, 922, 925, 927, 929, 930, 932, 935, 938, 939, 945, 946, 949, 951, 953, 954], "follow": [2, 3, 6, 10, 14, 15, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 34, 35, 36, 37, 38, 39, 43, 62, 230, 247, 250, 265, 335, 346, 347, 354, 361, 363, 391, 410, 903, 904, 906, 907, 909, 910, 912, 913, 916, 917, 918, 919, 921, 925, 926, 930, 931, 934, 941, 943, 945, 946, 949, 950, 952, 953, 957, 958, 959, 960], "show": [2, 6, 20, 41, 876, 903, 914, 924, 946, 950], "number": [2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 14, 19, 20, 21, 23, 24, 35, 36, 37, 39, 46, 48, 66, 78, 80, 83, 100, 103, 112, 135, 156, 290, 292, 312, 317, 327, 328, 329, 333, 339, 354, 358, 360, 361, 362, 526, 533, 729, 744, 746, 814, 833, 852, 856, 881, 891, 902, 904, 906, 910, 912, 914, 916, 917, 918, 919, 921, 925, 926, 929, 938, 950, 951, 952, 953, 955], "name": [2, 3, 4, 5, 6, 8, 10, 12, 14, 15, 16, 19, 20, 21, 22, 23, 24, 28, 29, 30, 32, 33, 34, 36, 37, 40, 46, 48, 49, 50, 59, 60, 141, 147, 153, 155, 159, 215, 223, 224, 229, 232, 237, 248, 249, 254, 262, 266, 269, 280, 302, 303, 312, 317, 319, 321, 322, 331, 335, 338, 344, 345, 352, 354, 361, 364, 367, 379, 384, 386, 408, 409, 410, 411, 414, 416, 506, 644, 646, 647, 648, 649, 653, 658, 669, 746, 757, 819, 839, 868, 878, 882, 889, 904, 906, 911, 914, 916, 917, 918, 921, 924, 925, 926, 927, 930, 932, 939, 940, 941, 942, 946, 948, 949, 950, 951, 952, 953, 955, 960], "chang": [2, 3, 6, 9, 14, 15, 19, 20, 21, 22, 24, 25, 26, 28, 33, 34, 37, 39, 46, 48, 78, 136, 158, 247, 262, 384, 385, 626, 725, 902, 910, 914, 916, 918, 924, 925, 926, 934, 936, 942, 944, 951, 953, 959], "protocol": [2, 3, 14, 21, 23, 29, 39, 43, 48, 249, 303, 323, 407, 680, 701, 729, 838, 842, 851, 852, 907, 909, 918, 923, 925, 935, 946, 955, 960], "updat": [2, 4, 6, 8, 9, 14, 20, 21, 22, 24, 26, 34, 35, 99, 100, 102, 103, 225, 289, 290, 291, 292, 703, 706, 912, 917, 918, 925, 934, 943], "kerbero": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 18, 19, 20, 21, 24, 25, 26, 27, 28, 30, 31, 32, 33, 36, 37, 38, 42, 43, 45, 46, 47, 48, 56, 62, 64, 65, 67, 69, 72, 73, 74, 76, 77, 78, 79, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 117, 118, 121, 124, 125, 126, 129, 130, 133, 134, 135, 141, 142, 145, 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158, 159, 161, 162, 163, 164, 169, 170, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187, 189, 192, 193, 215, 218, 224, 225, 229, 231, 237, 238, 240, 250, 262, 263, 264, 266, 267, 268, 269, 270, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 284, 289, 290, 291, 292, 296, 297, 298, 300, 301, 302, 303, 304, 305, 307, 308, 310, 312, 313, 316, 317, 318, 319, 320, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 337, 339, 340, 341, 344, 346, 347, 349, 354, 356, 357, 358, 359, 360, 361, 362, 363, 365, 366, 376, 377, 378, 379, 380, 384, 385, 386, 387, 391, 398, 399, 400, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 416, 903, 904, 907, 908, 909, 910, 912, 913, 915, 916, 920, 933, 936, 939, 941, 943, 944, 945, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959], "databas": [2, 4, 5, 6, 7, 8, 9, 10, 12, 15, 18, 19, 20, 21, 22, 26, 28, 30, 31, 32, 35, 37, 43, 906, 908, 909, 912, 913, 920, 924, 925, 926, 933, 936, 938, 949, 952, 953, 960], "randomli": [2, 26], "gener": [2, 9, 12, 14, 15, 17, 19, 20, 21, 23, 25, 26, 32, 35, 41, 43, 48, 113, 125, 126, 262, 285, 296, 329, 332, 344, 445, 528, 529, 530, 531, 830, 847, 862, 903, 907, 909, 910, 911, 912, 914, 916, 925, 926, 929, 933, 938, 943, 946, 953, 958], "": [2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 14, 15, 17, 19, 20, 21, 22, 23, 25, 26, 28, 29, 32, 33, 34, 35, 37, 38, 39, 41, 43, 46, 48, 50, 113, 192, 203, 210, 232, 233, 247, 265, 281, 296, 302, 365, 368, 377, 380, 400, 406, 746, 813, 832, 833, 838, 842, 882, 903, 904, 908, 910, 912, 916, 917, 918, 924, 925, 926, 928, 931, 938, 939, 940, 942, 945, 946, 948, 949, 950, 951, 953, 955, 956, 957, 958, 959, 960], "doesn": [2, 6, 23, 161, 903, 945], "t": [2, 3, 6, 10, 11, 12, 14, 15, 20, 21, 23, 28, 34, 37, 44, 50, 161, 335, 346, 718, 721, 743, 903, 907, 910, 912, 926, 945, 946, 949, 950, 953, 960], "store": [2, 3, 4, 5, 6, 8, 14, 15, 17, 20, 21, 22, 23, 24, 26, 34, 37, 46, 48, 80, 99, 100, 102, 103, 225, 237, 252, 289, 290, 291, 292, 327, 328, 332, 333, 358, 361, 362, 363, 409, 416, 554, 737, 846, 903, 906, 907, 910, 913, 916, 918, 922, 925, 942, 946, 949, 950, 953, 955], "server": [2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16, 18, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 34, 36, 37, 38, 39, 43, 46, 48, 159, 166, 224, 225, 266, 269, 302, 303, 335, 344, 345, 361, 377, 384, 385, 416, 509, 623, 667, 736, 766, 813, 831, 832, 838, 842, 852, 889, 903, 906, 907, 909, 913, 916, 924, 925, 926, 927, 933, 934, 946, 952, 953, 955, 956, 958], "fail": [2, 3, 6, 14, 15, 20, 21, 23, 24, 35, 38, 39, 43, 46, 230, 262, 281, 344, 356, 406, 871, 910, 912, 918, 925, 931, 932, 946, 948, 953], "flag": [2, 3, 5, 6, 11, 14, 19, 20, 21, 22, 23, 25, 26, 28, 33, 35, 39, 40, 43, 46, 48, 55, 62, 69, 74, 78, 151, 153, 192, 271, 281, 327, 328, 329, 333, 345, 354, 356, 358, 361, 362, 365, 366, 406, 734, 735, 736, 737, 741, 742, 743, 744, 746, 753, 754, 831, 832, 833, 838, 839, 846, 885, 900, 903, 912, 925, 929, 938, 946, 948, 949, 950, 952, 953], "given": [2, 3, 5, 6, 8, 10, 14, 20, 21, 23, 28, 36, 38, 39, 41, 43, 46, 48, 49, 59, 60, 124, 135, 319, 331, 391, 872, 912, 916, 918, 922, 925, 926, 950], "prompt": [2, 3, 5, 6, 23, 34, 46, 48, 262, 363, 725, 726, 727, 728, 876, 878, 908, 925, 929, 945, 946, 951, 953], "confirm": [2, 3, 5, 6, 23, 130, 301, 925, 955], "befor": [2, 3, 4, 5, 6, 14, 15, 20, 21, 22, 23, 26, 35, 37, 39, 41, 44, 98, 100, 103, 155, 290, 292, 383, 391, 833, 876, 904, 907, 908, 910, 918, 926, 929, 936, 938, 946, 949], "each": [2, 3, 6, 8, 10, 15, 19, 20, 21, 23, 24, 25, 26, 28, 33, 35, 37, 39, 43, 44, 46, 254, 265, 267, 354, 761, 903, 906, 908, 910, 916, 917, 918, 922, 925, 926, 930, 934, 935, 936, 940, 945, 946, 949, 950, 953, 955, 958, 959], "k": [2, 3, 4, 5, 6, 10, 11, 14, 15, 20, 23, 26, 34, 101, 119, 906, 917, 918, 925, 949, 950, 953, 955], "option": [2, 11, 12, 15, 19, 22, 23, 24, 28, 29, 34, 35, 36, 37, 39, 43, 48, 59, 60, 225, 226, 227, 231, 234, 235, 236, 237, 255, 262, 271, 277, 327, 328, 331, 332, 333, 346, 377, 405, 416, 418, 551, 744, 814, 815, 819, 830, 831, 838, 842, 846, 847, 852, 890, 906, 911, 925, 928, 929, 930, 932, 935, 937, 939, 946, 960], "old": [2, 3, 6, 14, 20, 21, 23, 34, 37, 245, 348, 422, 918, 925, 945], "displai": [2, 3, 5, 9, 11, 23, 37, 42, 46, 247, 736, 906, 916, 925, 926, 949, 950, 956], "ordinarili": [2, 15, 247], "default": [2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 19, 20, 21, 22, 23, 24, 26, 29, 30, 32, 33, 34, 35, 37, 38, 39, 40, 41, 43, 44, 46, 48, 59, 60, 78, 132, 147, 148, 154, 224, 231, 245, 255, 267, 271, 277, 280, 317, 319, 347, 361, 377, 385, 416, 718, 904, 911, 912, 913, 914, 916, 918, 925, 930, 931, 932, 946, 948, 949, 950, 952, 953, 954, 955, 959, 960], "encrypt": [2, 3, 6, 14, 15, 17, 21, 23, 25, 29, 30, 32, 34, 36, 40, 43, 46, 48, 79, 95, 98, 99, 100, 112, 113, 114, 116, 124, 125, 126, 129, 130, 153, 231, 282, 289, 290, 296, 297, 300, 301, 312, 317, 327, 328, 359, 361, 396, 485, 486, 544, 605, 677, 756, 814, 815, 829, 831, 832, 833, 838, 839, 851, 852, 889, 906, 907, 908, 909, 913, 917, 918, 919, 925, 926, 929, 931, 938, 943, 950, 955, 960], "type": [2, 3, 5, 6, 10, 15, 16, 21, 23, 25, 28, 30, 32, 34, 38, 39, 46, 48, 91, 93, 95, 98, 99, 100, 102, 103, 104, 112, 113, 114, 115, 116, 124, 125, 126, 129, 130, 151, 152, 153, 161, 163, 184, 189, 195, 224, 225, 231, 282, 289, 290, 291, 292, 296, 297, 300, 301, 312, 313, 317, 319, 333, 335, 337, 346, 391, 423, 505, 546, 653, 684, 756, 762, 806, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 906, 910, 913, 916, 917, 918, 919, 921, 922, 925, 927, 929, 930, 931, 934, 935, 936, 937, 938, 939, 940, 941, 942, 945, 946, 949, 950, 953, 955, 959, 960], "salt": [2, 3, 6, 11, 20, 23, 25, 48, 125, 126, 395, 846, 918, 925], "overridden": [2, 10, 11, 19, 21, 907, 925], "retain": [2, 3, 14, 20, 23, 926, 935, 937, 959], "so": [2, 3, 5, 14, 19, 20, 21, 23, 24, 28, 29, 33, 34, 35, 37, 39, 43, 85, 93, 136, 144, 230, 388, 891, 903, 910, 916, 924, 925, 926, 930, 931, 945, 946, 948, 949, 960], "ticket": [2, 3, 5, 6, 12, 14, 15, 16, 19, 20, 21, 22, 26, 28, 33, 34, 35, 36, 37, 38, 39, 41, 43, 46, 48, 153, 159, 183, 195, 224, 231, 237, 249, 262, 266, 269, 324, 332, 335, 344, 361, 365, 366, 377, 550, 553, 556, 658, 668, 751, 766, 815, 819, 829, 831, 832, 838, 839, 851, 852, 889, 890, 892, 903, 904, 916, 918, 925, 928, 929, 937, 938, 943, 944, 945, 948, 949, 950, 953, 955, 956, 959, 960], "continu": [2, 6, 17, 34, 917, 925, 926, 953], "work": [2, 3, 4, 6, 21, 23, 34, 35, 36, 39, 40, 43, 903, 912, 925, 926, 938, 939, 943, 945, 946, 960], "delold": [2, 14, 26], "after": [2, 3, 4, 6, 10, 12, 14, 21, 23, 24, 25, 33, 34, 35, 37, 39, 80, 98, 136, 230, 274, 382, 403, 891, 902, 903, 908, 910, 916, 917, 918, 921, 922, 925, 945, 946, 953, 960], "expir": [2, 3, 6, 15, 19, 20, 21, 23, 26, 33, 37, 43, 46, 48, 225, 245, 262, 838, 890, 903, 904, 907, 916, 918, 925, 946, 949, 950, 953, 960], "prevent": [2, 3, 19, 20, 21, 25, 26, 29, 40, 332, 526, 527, 907, 925, 926, 936, 945, 949], "attack": [2, 14, 21, 23, 29, 30, 32, 35, 40, 46, 327, 328, 333, 907, 925, 949], "against": [2, 14, 20, 21, 25, 28, 34, 39, 40, 46, 48, 129, 300, 344, 358, 361, 362, 365, 414, 907, 912, 925, 928, 931, 952, 958], "most": [2, 6, 17, 20, 21, 23, 24, 25, 26, 28, 33, 34, 37, 39, 40, 41, 43, 48, 154, 903, 906, 907, 909, 918, 925, 929, 930, 931, 946, 948, 960], "recent": [2, 6, 17, 20, 25, 26, 37, 48, 907, 919, 925, 946], "some": [2, 3, 6, 14, 20, 21, 23, 24, 28, 29, 31, 34, 37, 38, 39, 41, 46, 48, 99, 151, 154, 289, 391, 772, 903, 904, 907, 909, 910, 911, 912, 913, 918, 922, 924, 925, 930, 931, 934, 941, 943, 945, 946, 949, 958, 960], "remov": [2, 3, 6, 20, 23, 26, 28, 37, 38, 48, 155, 910, 925, 936, 945], "issu": [2, 3, 14, 20, 21, 23, 26, 29, 32, 35, 36, 37, 39, 43, 46, 322, 414, 890, 912, 925, 929, 938, 946, 949], "servic": [2, 3, 5, 8, 10, 12, 15, 16, 19, 20, 21, 22, 23, 24, 28, 29, 31, 32, 33, 34, 43, 48, 166, 225, 237, 247, 262, 266, 269, 303, 331, 332, 365, 384, 416, 649, 650, 651, 744, 884, 903, 907, 909, 916, 925, 926, 927, 932, 940, 946, 949, 955, 958, 960], "particular": [2, 11, 14, 16, 17, 19, 20, 21, 37, 43, 46, 319, 910, 912, 926, 945, 946], "interact": [2, 3, 21, 23, 39, 370, 912], "In": [2, 3, 4, 6, 8, 14, 17, 20, 21, 22, 23, 24, 26, 28, 29, 32, 34, 35, 37, 38, 39, 43, 249, 361, 377, 391, 903, 910, 911, 912, 917, 918, 925, 929, 930, 931, 934, 939, 943, 946, 950, 953, 959, 960], "case": [2, 3, 6, 11, 14, 19, 20, 21, 23, 24, 28, 38, 39, 43, 46, 195, 247, 282, 327, 332, 352, 361, 377, 391, 418, 712, 903, 904, 906, 926, 929, 930, 931, 934, 938, 939, 951, 953, 958, 960], "unless": [2, 3, 6, 11, 14, 19, 20, 21, 26, 28, 32, 34, 43, 317, 388, 416, 418, 907, 908, 925, 939, 953, 957], "program": [2, 3, 4, 6, 8, 12, 15, 20, 21, 23, 26, 28, 30, 32, 33, 34, 37, 38, 39, 41, 43, 46, 56, 270, 380, 907, 909, 910, 911, 914, 916, 924, 925, 926, 946, 952, 953, 960], "edit": [2, 11, 12, 31, 912, 913, 945], "place": [2, 8, 14, 15, 21, 26, 28, 32, 33, 37, 39, 43, 44, 46, 48, 107, 117, 231, 266, 269, 281, 298, 303, 338, 366, 378, 406, 833, 872, 912, 914, 922, 928, 936, 948, 953, 959], "variabl": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 19, 20, 21, 24, 25, 28, 30, 34, 35, 37, 38, 39, 40, 41, 43, 48, 93, 136, 141, 155, 271, 284, 388, 389, 903, 906, 907, 913, 925, 941, 942, 948, 949, 950, 951, 953, 954, 955, 956], "o": [3, 5, 6, 20, 34, 48, 904, 910, 911, 912, 924, 925, 926, 946, 950], "n": [3, 6, 10, 21, 28, 37, 346, 904, 949, 950, 953], "r": [3, 4, 5, 6, 7, 8, 9, 10, 14, 21, 28, 34, 286, 946, 949, 950, 953, 960], "realm": [3, 4, 5, 6, 7, 8, 10, 12, 14, 15, 16, 19, 22, 24, 25, 26, 29, 30, 33, 34, 36, 37, 38, 40, 43, 44, 46, 48, 49, 50, 59, 60, 91, 92, 93, 94, 153, 215, 232, 237, 253, 262, 266, 269, 280, 281, 286, 302, 344, 346, 347, 352, 361, 390, 391, 405, 406, 410, 507, 714, 717, 718, 719, 720, 722, 723, 733, 801, 802, 803, 804, 819, 827, 831, 839, 842, 851, 852, 868, 871, 872, 874, 875, 889, 903, 912, 913, 916, 917, 919, 921, 924, 925, 933, 940, 942, 945, 946, 949, 953, 958, 959, 960], "p": [3, 4, 5, 6, 7, 8, 10, 11, 12, 14, 19, 20, 21, 23, 40, 903, 925, 926, 946, 948, 949, 950, 953, 954, 955], "q": [3, 11, 14, 37, 948, 953, 955], "queri": [3, 21, 39, 43, 46, 925], "c": [3, 6, 19, 21, 22, 23, 48, 107, 230, 367, 813, 819, 838, 852, 889, 903, 911, 912, 926, 941, 948, 949, 950, 953, 954, 955], "cache_nam": [3, 948, 949, 950], "w": [3, 5, 10, 24, 486], "password": [3, 4, 5, 6, 9, 10, 11, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 32, 33, 34, 35, 36, 37, 39, 40, 43, 48, 235, 247, 260, 624, 626, 725, 726, 727, 745, 746, 903, 908, 918, 924, 925, 929, 933, 944, 946, 951, 953, 959, 960], "admin_serv": [3, 8, 20, 21, 34, 39], "port": [3, 4, 7, 8, 10, 12, 15, 20, 21, 23, 34, 36, 41, 44, 48, 62, 333, 529, 531, 924, 960], "arg": [3, 419, 420, 421, 808, 809, 912, 953], "local": [3, 5, 8, 12, 14, 15, 20, 21, 22, 23, 28, 32, 34, 36, 39, 43, 46, 48, 62, 64, 80, 232, 233, 327, 328, 329, 331, 333, 346, 358, 361, 362, 391, 400, 410, 528, 529, 723, 904, 907, 908, 909, 912, 914, 916, 917, 919, 924, 925, 932, 933, 945, 946, 949, 950, 952, 953, 955, 960], "d": [3, 5, 6, 7, 8, 10, 19, 28, 904, 912, 925, 930, 946, 950, 960], "dbname": [3, 6, 10], "enc": [3, 6, 20, 199, 303, 832, 925], "m": [3, 4, 5, 6, 10, 14, 19, 20, 21, 23, 26, 29, 34, 39, 48, 385, 690, 904, 918, 925, 926, 946], "x": [3, 4, 6, 8, 10, 16, 19, 20, 21, 23, 37, 43, 777, 797, 807, 916, 918, 925, 926, 928, 929, 949, 955], "db_arg": [3, 4, 6, 8, 10], "interfac": [3, 11, 14, 19, 20, 23, 28, 34, 46, 903, 907, 909, 912, 925, 930, 933], "v5": [3, 7, 11, 21, 32, 39, 48, 909, 910, 912, 923, 926, 946], "system": [3, 6, 14, 15, 19, 20, 21, 24, 29, 32, 33, 34, 35, 36, 37, 38, 41, 43, 46, 48, 56, 136, 147, 169, 284, 384, 385, 387, 398, 700, 703, 706, 882, 903, 908, 909, 910, 911, 925, 926, 930, 939, 943, 945, 946, 948, 949, 959, 960], "thei": [3, 4, 6, 9, 10, 14, 15, 20, 21, 28, 33, 34, 37, 38, 39, 41, 43, 46, 231, 327, 377, 737, 853, 902, 903, 906, 910, 912, 916, 918, 925, 938, 945, 946, 957, 960], "nearli": 3, "ident": [3, 15, 20, 22, 43, 48, 363, 746, 886, 887, 903, 925, 929, 945, 946, 949, 951], "function": [3, 6, 14, 25, 29, 34, 35, 43, 46, 48, 49, 50, 55, 57, 58, 59, 60, 61, 62, 67, 68, 69, 71, 72, 73, 74, 76, 77, 78, 81, 82, 84, 85, 86, 87, 88, 89, 92, 93, 99, 100, 101, 102, 103, 104, 105, 107, 113, 114, 116, 117, 119, 124, 125, 126, 129, 130, 133, 136, 137, 139, 148, 150, 151, 153, 156, 157, 158, 159, 167, 169, 171, 172, 173, 174, 175, 177, 178, 180, 181, 182, 183, 192, 194, 195, 198, 199, 200, 201, 202, 203, 206, 207, 208, 209, 210, 213, 216, 217, 222, 230, 237, 238, 243, 247, 248, 254, 256, 260, 262, 263, 264, 266, 267, 268, 269, 273, 274, 277, 278, 279, 280, 281, 289, 290, 291, 292, 296, 297, 298, 300, 301, 303, 310, 312, 322, 325, 326, 327, 328, 329, 331, 332, 333, 335, 336, 344, 345, 347, 354, 357, 358, 359, 360, 361, 362, 363, 370, 373, 375, 378, 380, 384, 385, 387, 389, 391, 398, 402, 403, 405, 406, 409, 410, 412, 414, 416, 418, 419, 421, 862, 871, 872, 876, 878, 883, 909, 910, 925, 926, 929, 930, 931, 934, 937, 938, 940, 941], "differ": [3, 6, 12, 21, 25, 26, 28, 33, 34, 37, 38, 39, 43, 45, 48, 107, 119, 159, 267, 377, 387, 871, 907, 910, 912, 930, 938, 939, 945, 946, 949, 953, 960], "directli": [3, 18, 20, 21, 23, 29, 34, 43, 46, 377, 624, 931, 938, 949, 954], "access": [3, 4, 8, 9, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 32, 33, 34, 35, 37, 39, 43, 46, 903, 908, 910, 919, 922, 925, 929, 934, 935, 937, 938, 939, 944, 946, 952, 953, 958, 959], "kdc": [3, 4, 5, 6, 8, 9, 10, 11, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 29, 31, 32, 33, 36, 40, 43, 46, 48, 101, 107, 119, 166, 225, 232, 237, 243, 247, 249, 260, 262, 271, 302, 303, 335, 344, 345, 416, 549, 551, 568, 663, 665, 744, 838, 851, 852, 871, 872, 890, 903, 906, 908, 909, 912, 913, 916, 919, 920, 925, 928, 929, 932, 933, 934, 940, 942, 946, 949, 955, 960], "while": [3, 12, 14, 15, 16, 20, 21, 23, 24, 34, 35, 43, 46, 903, 910, 930, 945, 946, 953, 960], "perform": [3, 4, 5, 6, 12, 14, 19, 20, 21, 22, 24, 25, 26, 34, 37, 38, 39, 43, 46, 62, 91, 252, 256, 260, 361, 365, 377, 384, 385, 388, 418, 442, 853, 903, 918, 925, 926, 935, 936, 937, 946], "except": [3, 19, 21, 23, 37, 39, 43, 331, 918, 925, 926, 931, 953], "explicitli": [3, 14, 19, 23, 28, 34, 44, 255, 912, 925, 935, 936, 937, 946], "note": [3, 5, 6, 14, 20, 21, 23, 26, 32, 34, 154, 243, 247, 904, 910, 938, 946, 949, 953, 959, 960], "otherwis": [3, 6, 14, 20, 21, 23, 29, 33, 34, 36, 37, 39, 43, 49, 52, 54, 62, 64, 65, 67, 69, 72, 73, 74, 76, 77, 78, 79, 81, 82, 84, 85, 86, 87, 88, 89, 90, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 121, 124, 125, 126, 129, 130, 134, 142, 150, 153, 157, 158, 162, 163, 164, 166, 170, 172, 173, 174, 175, 177, 178, 180, 181, 182, 183, 184, 185, 187, 189, 192, 193, 195, 218, 225, 237, 238, 240, 250, 262, 263, 266, 267, 268, 269, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 285, 286, 287, 288, 289, 290, 291, 292, 296, 297, 298, 300, 301, 302, 303, 321, 323, 324, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 337, 339, 340, 341, 344, 347, 349, 350, 351, 352, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 376, 377, 378, 387, 390, 392, 393, 394, 396, 397, 399, 400, 402, 403, 404, 405, 406, 407, 416, 903, 912, 917, 918, 926, 928, 930, 937, 946, 949, 950, 951, 953], "refer": [3, 5, 15, 19, 20, 22, 23, 39, 43, 45, 48, 87, 89, 138, 288, 309, 868, 918, 925, 926, 934, 939, 953], "both": [3, 12, 21, 22, 23, 24, 26, 28, 29, 36, 37, 39, 40, 43, 159, 247, 253, 910, 918, 925, 926, 930, 953], "mainten": [3, 6, 23], "polici": [3, 4, 5, 6, 16, 19, 20, 21, 24, 25, 34, 35, 169, 361, 925, 933, 934, 935, 942, 946, 950, 951], "tabl": [3, 6, 23, 48, 278, 309, 310, 315, 361, 365, 416, 856, 906, 909, 911, 912, 914, 918, 922, 924, 925, 950], "remot": [3, 4, 7, 15, 20, 23, 33, 38, 43, 48, 62, 64, 169, 224, 327, 328, 333, 358, 361, 362, 384, 385, 530, 531, 909, 925, 945, 946, 953, 959, 960], "client": [3, 12, 14, 16, 18, 20, 21, 22, 23, 25, 26, 28, 31, 32, 34, 35, 36, 38, 39, 40, 41, 43, 46, 48, 145, 154, 224, 225, 237, 243, 244, 260, 262, 266, 269, 277, 278, 279, 332, 335, 361, 365, 405, 657, 658, 746, 813, 814, 819, 831, 832, 839, 842, 851, 852, 903, 907, 909, 912, 916, 917, 918, 919, 924, 925, 926, 927, 928, 930, 933, 935, 938, 940, 946, 949, 950, 952, 953, 955, 958, 960], "authent": [3, 5, 6, 10, 12, 14, 15, 20, 21, 22, 24, 25, 26, 29, 30, 32, 34, 35, 36, 37, 38, 39, 40, 43, 44, 46, 48, 61, 62, 63, 64, 66, 67, 68, 69, 71, 72, 73, 74, 76, 77, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 166, 201, 224, 225, 252, 324, 325, 327, 328, 329, 330, 331, 332, 333, 338, 344, 356, 358, 359, 360, 361, 362, 377, 442, 505, 511, 621, 744, 813, 815, 819, 865, 882, 892, 903, 906, 907, 908, 909, 916, 917, 918, 922, 925, 926, 928, 938, 939, 946, 949, 950, 956, 960], "admin": [3, 4, 5, 8, 14, 15, 16, 19, 21, 22, 23, 26, 32, 34, 903, 912, 918, 924, 925, 935, 953, 960], "adminhost": 3, "where": [3, 4, 6, 7, 8, 14, 15, 17, 20, 21, 23, 25, 28, 39, 43, 46, 319, 391, 902, 903, 906, 907, 910, 911, 912, 917, 918, 925, 930, 946, 949, 953, 960], "fulli": [3, 15, 19, 21, 23, 29, 32, 34, 35, 46, 949, 960], "qualifi": [3, 15, 19, 21, 23, 960], "hostnam": [3, 12, 15, 20, 21, 23, 26, 33, 34, 37, 38, 41, 43, 48, 331, 390, 391, 912, 925, 932, 955, 958, 960], "credenti": [3, 8, 12, 16, 20, 21, 23, 28, 33, 35, 37, 45, 48, 138, 166, 177, 207, 208, 224, 225, 231, 323, 331, 335, 356, 377, 404, 407, 445, 554, 624, 659, 753, 829, 830, 831, 832, 883, 902, 905, 906, 907, 909, 912, 920, 925, 929, 931, 932, 933, 938, 946, 948, 949, 950, 952, 953, 954, 955, 958, 960], "cach": [3, 14, 15, 21, 23, 28, 43, 44, 48, 78, 138, 140, 224, 225, 231, 249, 266, 269, 325, 327, 328, 331, 333, 358, 361, 362, 377, 405, 416, 527, 550, 554, 761, 905, 909, 912, 913, 920, 924, 925, 933, 946, 948, 949, 950, 952, 953, 954, 955, 958, 960], "contain": [3, 4, 5, 6, 8, 9, 15, 19, 20, 21, 22, 23, 24, 28, 29, 33, 34, 37, 38, 39, 41, 43, 46, 48, 54, 67, 72, 76, 152, 154, 169, 172, 173, 183, 184, 195, 233, 247, 249, 278, 281, 302, 303, 322, 332, 338, 344, 346, 357, 358, 359, 362, 365, 367, 377, 406, 416, 853, 882, 895, 903, 904, 906, 907, 909, 910, 911, 912, 913, 914, 916, 917, 918, 921, 922, 926, 930, 931, 940, 941, 943, 945, 946, 948, 949, 953, 954, 955, 958, 959, 960], "credentials_cach": 3, "specifi": [3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 16, 18, 19, 20, 22, 23, 28, 29, 34, 36, 37, 39, 43, 46, 48, 92, 93, 99, 100, 102, 103, 113, 125, 129, 225, 229, 231, 237, 262, 266, 269, 289, 290, 291, 292, 296, 300, 312, 317, 320, 327, 328, 333, 346, 347, 358, 361, 362, 377, 385, 416, 758, 903, 907, 912, 917, 918, 919, 925, 931, 938, 946, 948, 949, 950, 951, 952, 953, 954, 955, 960], "onc": [3, 6, 14, 15, 21, 23, 34, 43, 46, 78, 363, 741, 903, 907, 910, 936, 940, 945, 960], "determin": [3, 4, 5, 6, 8, 20, 21, 23, 24, 28, 34, 43, 48, 62, 102, 105, 117, 136, 154, 232, 233, 263, 291, 361, 387, 391, 418, 895, 903, 906, 907, 910, 912, 917, 918, 921, 925, 928, 932, 935, 939, 940, 946, 960], "request": [3, 4, 6, 8, 9, 10, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 33, 35, 36, 37, 38, 40, 43, 46, 48, 153, 166, 195, 224, 225, 231, 237, 243, 255, 262, 269, 278, 279, 332, 361, 380, 405, 508, 510, 511, 625, 680, 701, 758, 765, 766, 813, 815, 838, 852, 860, 904, 906, 907, 916, 917, 919, 925, 928, 929, 931, 937, 938, 943, 946, 949, 953, 955, 960], "sinc": [3, 12, 14, 17, 21, 22, 23, 37, 48, 332, 741, 891, 902, 916, 918, 925, 931, 938, 959, 960], "usual": [3, 10, 12, 20, 21, 23, 25, 35, 37, 39, 46, 99, 289, 903, 906, 912, 916, 930, 946, 955, 960], "run": [3, 4, 6, 8, 9, 10, 12, 14, 15, 20, 21, 23, 24, 26, 28, 32, 33, 34, 37, 39, 41, 903, 910, 911, 912, 914, 924, 925, 948, 950, 953, 960], "primari": [3, 4, 7, 8, 9, 14, 17, 20, 21, 23, 24, 31, 35, 38, 39, 41, 43, 48, 145, 903, 925, 927, 936, 940, 942, 943, 948, 949, 954, 958, 960], "suffici": [3, 5, 14, 24, 912], "permiss": [3, 18, 19, 20, 23, 34, 43, 137, 147, 159, 903, 925, 926, 946], "read": [3, 5, 6, 9, 11, 20, 21, 22, 23, 34, 35, 37, 46, 48, 228, 252, 262, 264, 320, 354, 373, 416, 912, 921, 925, 938, 941, 945, 950, 960], "ldap": [3, 4, 5, 6, 10, 20, 22, 35, 38, 912, 925, 926], "modul": [3, 4, 6, 20, 21, 23, 35, 254, 270, 912, 914, 918, 923, 924, 925, 927, 928, 929, 932, 934, 935, 936, 937, 938, 939, 940, 941, 942, 949, 960], "host": [3, 4, 7, 8, 12, 14, 15, 16, 20, 21, 23, 24, 25, 26, 29, 30, 31, 33, 36, 37, 38, 39, 43, 46, 48, 194, 224, 232, 331, 333, 390, 391, 416, 649, 651, 907, 910, 912, 925, 933, 938, 945, 946, 949, 950, 953, 957, 958, 959, 960], "which": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 46, 126, 173, 195, 228, 231, 232, 247, 252, 282, 312, 332, 361, 368, 370, 373, 374, 890, 891, 902, 903, 906, 907, 909, 910, 911, 912, 913, 916, 917, 918, 919, 921, 922, 924, 925, 926, 927, 929, 930, 931, 934, 935, 936, 937, 938, 940, 941, 942, 946, 949, 952, 953, 955, 958, 959, 960], "append": [3, 20, 23, 38, 389, 906, 912, 922], "ccach": [3, 23, 41, 43, 48, 132, 135, 164, 225, 226, 227, 234, 235, 236, 248, 252, 253, 266, 269, 323, 331, 377, 385, 405, 407, 416, 823, 912, 924, 927, 951, 955], "valu": [3, 5, 6, 10, 14, 16, 19, 20, 21, 22, 23, 24, 25, 26, 28, 33, 34, 36, 37, 38, 39, 43, 46, 48, 66, 83, 117, 125, 126, 136, 151, 153, 156, 166, 225, 247, 250, 254, 265, 267, 271, 298, 303, 335, 370, 371, 373, 377, 388, 390, 399, 728, 734, 735, 737, 739, 744, 746, 802, 803, 804, 843, 847, 860, 871, 872, 891, 902, 903, 904, 906, 907, 912, 913, 914, 916, 917, 918, 919, 921, 922, 925, 929, 931, 938, 939, 941, 946, 948, 949, 950, 952, 953, 958, 960], "usernam": [3, 12, 21, 34, 36, 37, 43, 321, 680, 946, 949], "getpwuid": 3, "order": [3, 4, 6, 14, 16, 17, 19, 20, 21, 22, 23, 32, 33, 34, 35, 37, 38, 43, 46, 48, 247, 744, 903, 906, 907, 911, 912, 916, 921, 926, 927, 931, 941, 960], "prefer": [3, 21, 38, 43, 238, 906, 907, 925, 932], "decrypt": [3, 35, 43, 48, 79, 356, 366, 833, 889, 907, 925, 953, 955], "respons": [3, 4, 37, 40, 46, 85, 166, 231, 247, 281, 359, 406, 508, 510, 548, 570, 745, 765, 767, 813, 852, 888, 925, 926, 929, 932, 938, 949, 956, 960], "instead": [3, 4, 6, 8, 14, 20, 21, 23, 24, 34, 37, 38, 46, 241, 248, 280, 311, 342, 343, 344, 346, 419, 421, 872, 912, 925, 926, 931, 938, 948, 950, 953, 959], "onli": [3, 4, 6, 8, 9, 10, 14, 15, 18, 19, 20, 21, 22, 23, 26, 28, 32, 33, 34, 35, 38, 39, 41, 43, 46, 48, 54, 114, 153, 225, 230, 243, 247, 297, 327, 363, 367, 368, 550, 737, 757, 868, 895, 902, 903, 908, 910, 912, 916, 918, 922, 925, 926, 931, 932, 938, 939, 941, 945, 946, 949, 953, 955, 958, 960], "anonym": [3, 20, 25, 28, 43, 48, 506, 507, 925, 946, 949, 950], "process": [3, 4, 6, 8, 9, 10, 14, 15, 20, 21, 23, 24, 25, 34, 38, 43, 46, 48, 136, 154, 169, 228, 357, 416, 903, 906, 907, 925, 928, 929, 932, 935, 936, 937, 938, 940, 942, 949, 960], "two": [3, 18, 20, 21, 23, 24, 26, 28, 34, 35, 37, 38, 48, 53, 363, 904, 916, 918, 921, 925, 927, 931, 939, 946, 949, 953], "support": [3, 4, 6, 8, 10, 11, 20, 21, 22, 23, 24, 25, 26, 37, 39, 40, 43, 46, 48, 153, 161, 249, 255, 380, 388, 389, 549, 762, 903, 905, 909, 910, 911, 912, 916, 917, 918, 922, 925, 926, 929, 930, 931, 938, 943, 949], "For": [3, 10, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, 32, 33, 34, 35, 36, 37, 38, 39, 43, 46, 99, 100, 103, 142, 289, 290, 292, 744, 902, 903, 907, 910, 911, 912, 916, 917, 918, 922, 923, 924, 925, 927, 928, 929, 930, 931, 932, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 945, 946, 949, 952, 953, 958, 960], "configur": [3, 4, 5, 9, 10, 14, 16, 17, 19, 20, 21, 23, 24, 25, 30, 31, 38, 41, 43, 46, 48, 50, 78, 154, 167, 194, 205, 253, 263, 271, 390, 416, 418, 568, 569, 904, 907, 909, 910, 911, 913, 914, 925, 930, 933, 942, 946, 949, 950, 953, 957, 959, 960], "pkinit": [3, 16, 23, 25, 30, 40, 41, 107, 655, 693, 694, 695, 696, 746, 912, 920, 925, 926, 933, 949], "pkinit_anchor": [3, 20, 21, 37, 949], "Then": [3, 6, 17, 24, 34, 949], "empti": [3, 6, 19, 20, 21, 23, 36, 43, 46, 48, 93, 231, 233, 281, 347, 390, 391, 406, 416, 907, 912, 916, 918, 925, 949], "sign": [3, 19, 20, 21, 32, 37, 41, 43, 48, 902, 911, 919, 921, 925, 949, 960], "permit": [3, 19, 20, 21, 26, 36, 48, 194, 253, 358, 362, 924, 925, 926, 949, 959], "return": [3, 9, 12, 20, 21, 22, 38, 43, 46, 48, 50, 52, 54, 56, 57, 59, 60, 69, 74, 91, 92, 93, 100, 103, 109, 110, 119, 127, 128, 133, 135, 137, 141, 142, 144, 145, 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 159, 161, 169, 176, 189, 192, 215, 224, 225, 229, 230, 231, 233, 237, 262, 264, 265, 266, 269, 270, 273, 281, 284, 285, 286, 290, 292, 303, 304, 305, 307, 308, 310, 312, 313, 316, 317, 318, 319, 320, 322, 325, 327, 332, 346, 347, 354, 357, 363, 367, 368, 370, 373, 377, 379, 380, 382, 384, 385, 386, 388, 390, 391, 398, 400, 402, 406, 408, 409, 410, 411, 412, 414, 416, 418, 737, 871, 872, 912, 925, 927, 928, 929, 930, 931, 932, 935, 936, 938, 939, 940, 941, 942, 949, 953], "A": [3, 6, 8, 15, 16, 19, 21, 23, 24, 25, 26, 28, 32, 34, 35, 36, 37, 38, 43, 46, 169, 231, 344, 346, 368, 370, 373, 390, 746, 856, 882, 895, 903, 906, 907, 916, 917, 918, 921, 922, 924, 925, 926, 927, 928, 929, 930, 931, 932, 934, 935, 936, 938, 939, 940, 941, 942, 946, 948, 949, 950, 960], "second": [3, 10, 20, 21, 23, 28, 36, 37, 39, 43, 44, 52, 53, 105, 153, 224, 230, 268, 269, 324, 350, 351, 352, 363, 364, 387, 388, 390, 412, 751, 814, 830, 832, 852, 881, 891, 902, 904, 907, 916, 917, 918, 921, 922, 930, 931, 946, 949, 953, 960], "expos": [3, 6, 14, 46, 854, 949, 953], "hide": [3, 949], "mode": [3, 6, 8, 14, 20, 41, 472, 484, 736, 912, 925, 949, 953], "kinit": [3, 12, 15, 16, 21, 22, 28, 29, 33, 34, 35, 37, 41, 46, 903, 904, 925, 929, 944, 947, 948, 950, 953, 954, 955, 956, 960], "replac": [3, 5, 21, 23, 28, 34, 70, 75, 94, 186, 188, 190, 191, 196, 197, 226, 227, 234, 235, 236, 283, 353, 355, 413, 912, 921, 925, 926, 929, 949], "As": [3, 4, 10, 14, 16, 17, 26, 34, 35, 37, 39, 43, 46, 914, 935, 937, 941, 949], "8": [3, 5, 6, 8, 12, 23, 26, 35, 43, 46, 249, 352, 367, 375, 521, 554, 614, 686, 715, 904, 916, 918, 921, 925, 926, 949], "mit": [3, 5, 12, 14, 15, 17, 19, 20, 21, 24, 28, 30, 31, 32, 34, 38, 39, 41, 43, 45, 46, 902, 903, 909, 911, 912, 914, 915, 916, 917, 918, 919, 929, 931, 933, 934, 938, 941, 943, 945, 946, 949, 960], "acquir": [3, 6, 8, 43, 48, 247, 276, 404, 553, 916, 925, 931, 955], "its": [3, 4, 8, 10, 14, 15, 17, 20, 21, 23, 24, 26, 28, 29, 32, 33, 34, 35, 37, 38, 39, 40, 41, 43, 46, 48, 87, 89, 92, 107, 117, 203, 210, 230, 271, 298, 303, 358, 361, 362, 383, 414, 904, 915, 916, 918, 925, 926, 927, 928, 929, 930, 931, 938, 942, 948, 949, 950, 958], "temporari": [3, 21, 34, 37, 906, 907, 924, 925, 960], "care": [3, 14, 19, 28, 43, 934], "mai": [3, 6, 8, 10, 11, 14, 15, 19, 20, 21, 22, 23, 24, 25, 26, 28, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 46, 99, 107, 126, 158, 195, 225, 230, 231, 243, 247, 260, 264, 289, 332, 361, 377, 382, 383, 390, 391, 416, 737, 853, 871, 883, 895, 904, 907, 910, 912, 913, 916, 917, 918, 921, 922, 925, 926, 929, 931, 932, 934, 935, 936, 937, 938, 941, 943, 945, 946, 948, 949, 953, 958, 960], "other": [3, 4, 6, 10, 14, 15, 19, 20, 21, 23, 24, 26, 28, 34, 35, 37, 38, 39, 43, 46, 154, 281, 312, 361, 406, 650, 746, 843, 902, 903, 906, 909, 910, 911, 912, 916, 917, 918, 921, 925, 926, 929, 931, 935, 936, 937, 939, 940, 941, 943, 945, 946, 951, 953, 958, 959], "exit": [3, 10, 11, 903, 925, 946, 950, 955], "doe": [3, 6, 8, 10, 14, 20, 21, 22, 23, 24, 25, 26, 34, 37, 38, 39, 40, 43, 46, 56, 119, 144, 152, 160, 303, 313, 315, 347, 377, 391, 399, 416, 903, 906, 910, 912, 917, 925, 926, 930, 931, 932, 939, 941, 945, 946, 953], "appli": [3, 10, 14, 18, 19, 20, 21, 23, 24, 35, 39, 41, 43, 171, 926, 935, 938, 946, 949, 953, 957], "contact": [3, 7, 8, 14, 20, 21, 23, 29, 39, 262, 903, 925, 927, 943, 956], "master": [3, 4, 5, 6, 10, 20, 26, 34, 35, 39, 41, 908, 913, 924, 925], "stash": [3, 5, 10, 14, 20, 22, 23, 34, 41, 905, 924], "file": [3, 4, 5, 6, 7, 9, 10, 11, 12, 14, 15, 16, 17, 19, 22, 23, 24, 28, 29, 30, 31, 37, 38, 39, 41, 46, 48, 50, 152, 228, 264, 271, 319, 323, 365, 366, 377, 380, 407, 761, 903, 904, 905, 906, 907, 909, 910, 911, 912, 913, 914, 918, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 934, 935, 936, 937, 938, 939, 940, 941, 942, 944, 945, 946, 953, 958, 959, 960], "creat": [3, 4, 7, 12, 14, 15, 19, 20, 21, 22, 23, 24, 26, 28, 31, 32, 35, 43, 47, 48, 67, 72, 76, 93, 113, 114, 125, 126, 135, 138, 172, 173, 174, 175, 176, 177, 178, 180, 182, 183, 206, 238, 264, 267, 273, 296, 297, 309, 310, 326, 333, 347, 361, 365, 366, 377, 389, 402, 416, 716, 903, 904, 906, 910, 914, 917, 918, 922, 925, 926, 927, 928, 929, 931, 932, 933, 935, 936, 937, 938, 939, 940, 941, 942, 943, 945, 946, 949], "possibl": [3, 5, 6, 14, 17, 20, 21, 22, 24, 25, 26, 32, 34, 35, 37, 38, 39, 46, 93, 166, 225, 303, 906, 907, 925, 926, 930, 943, 946, 958], "forc": [3, 5, 8, 9, 11, 14, 19, 20, 21, 23, 25, 26, 35, 39, 40, 136], "auth_gssapi": 3, "flavor": 3, "fallback": [3, 20, 21, 38, 40, 46, 925, 932], "specif": [3, 4, 6, 8, 10, 14, 18, 19, 20, 21, 24, 26, 34, 39, 43, 48, 49, 56, 155, 303, 317, 319, 365, 366, 412, 746, 903, 904, 906, 912, 914, 918, 922, 925, 926, 930, 935, 940, 946], "argument": [3, 4, 6, 8, 10, 14, 20, 44, 46, 48, 63, 80, 91, 93, 247, 259, 262, 265, 277, 327, 328, 333, 354, 356, 358, 362, 388, 419, 420, 421, 895, 912, 918, 925, 930, 931, 939, 953, 955], "next": [3, 6, 17, 23, 34, 35, 48, 99, 100, 102, 103, 289, 290, 291, 292, 736, 910, 916, 917, 918, 922, 925, 929, 938, 946, 953], "section": [3, 10, 19, 22, 23, 28, 33, 34, 35, 37, 39, 41, 43, 48, 119, 322, 414, 606, 687, 688, 689, 907, 910, 911, 916, 917, 922, 925, 941, 942, 953, 958], "14": [3, 14, 16, 20, 21, 23, 509, 600, 662, 696, 904, 917, 921, 925, 936, 938], "remain": [3, 4, 6, 14, 20, 43, 44, 247, 651, 902, 903, 921, 922, 925, 926, 936, 938, 953], "treat": [3, 21, 36, 38, 43, 54, 344, 352, 715, 891, 916, 949, 955], "execut": [3, 6, 22, 34, 46, 382, 911, 912, 952], "intend": [3, 10, 23, 41, 43, 46, 354, 953], "script": [3, 4, 10, 34, 909, 910, 912, 925], "behav": [3, 43, 409, 418, 902, 912], "sever": [3, 15, 16, 20, 21, 23, 24, 37, 39, 903, 909, 912, 916, 930, 960], "respect": [3, 11, 34, 82, 84, 225, 346, 904, 918, 925, 926, 931, 945], "split": [3, 39, 925], "shell": [3, 5, 23, 34, 41, 925, 945, 946, 952, 958], "inform": [3, 4, 6, 7, 9, 11, 20, 22, 23, 26, 28, 33, 34, 38, 39, 41, 43, 46, 48, 169, 185, 231, 252, 253, 284, 327, 329, 335, 344, 366, 388, 389, 418, 657, 659, 661, 662, 664, 746, 830, 831, 869, 876, 881, 895, 903, 911, 912, 915, 916, 917, 921, 925, 929, 930, 933, 934, 938, 941, 943, 949, 960], "warn": [3, 23, 26, 247, 914, 925, 926], "messag": [3, 8, 20, 21, 24, 34, 41, 48, 78, 365, 377, 383, 536, 543, 724, 747, 813, 838, 842, 851, 852, 871, 872, 889, 895, 907, 909, 917, 925, 926, 930, 945, 946, 952, 953, 955, 960], "suppress": [3, 6, 20, 912, 925, 948, 953, 955], "error": [3, 20, 21, 24, 34, 37, 39, 43, 48, 49, 50, 56, 62, 64, 65, 67, 69, 72, 73, 74, 76, 77, 78, 79, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 117, 118, 119, 121, 124, 125, 126, 129, 130, 133, 134, 135, 137, 141, 142, 145, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 161, 162, 163, 164, 166, 169, 170, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187, 189, 192, 193, 215, 218, 224, 225, 229, 231, 233, 237, 238, 240, 245, 250, 262, 263, 264, 266, 267, 268, 269, 270, 273, 274, 276, 277, 278, 279, 280, 281, 282, 284, 289, 290, 291, 292, 296, 297, 298, 300, 301, 302, 303, 304, 305, 307, 308, 310, 312, 313, 316, 317, 318, 319, 320, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 337, 339, 340, 341, 344, 346, 347, 349, 354, 356, 358, 359, 360, 361, 362, 363, 365, 366, 376, 377, 378, 379, 380, 384, 385, 386, 387, 391, 398, 399, 400, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 416, 548, 621, 623, 719, 720, 842, 843, 871, 907, 909, 912, 925, 929, 930, 935, 936, 938, 939, 946, 955], "output": [3, 6, 9, 15, 20, 23, 26, 34, 41, 43, 48, 99, 100, 101, 102, 103, 107, 117, 119, 166, 181, 225, 281, 289, 290, 291, 292, 298, 354, 361, 363, 366, 406, 872, 881, 903, 914, 925, 927, 928, 930, 949, 950, 952, 955, 960], "g": [3, 6, 19, 21, 22, 33, 34, 37, 39, 46, 876, 903, 908, 910, 911, 912, 917, 919, 941, 945, 953, 960], "still": [3, 4, 6, 10, 14, 20, 21, 23, 32, 33, 34, 35, 39, 148, 271, 925, 949, 953, 955], "disabl": [3, 14, 20, 21, 23, 24, 26, 28, 34, 37, 38, 39, 41, 382, 383, 388, 555, 907, 910, 912, 925, 933, 949, 957, 960], "requir": [3, 4, 6, 8, 9, 12, 14, 15, 16, 20, 21, 22, 23, 24, 25, 26, 28, 32, 34, 35, 36, 37, 38, 39, 40, 43, 46, 48, 98, 112, 116, 117, 238, 243, 249, 250, 303, 325, 327, 328, 333, 356, 358, 362, 549, 744, 868, 883, 902, 903, 910, 911, 912, 914, 917, 918, 925, 926, 928, 931, 938, 941, 946, 951, 959, 960], "statu": [3, 843, 925, 926, 928, 931, 950, 953, 955], "zero": [3, 21, 24, 39, 43, 44, 48, 129, 130, 203, 243, 247, 262, 263, 286, 300, 301, 312, 746, 748, 871, 916, 918, 921, 922, 925, 930], "carri": [3, 25, 960], "behavior": [3, 14, 20, 21, 28, 39, 46, 230, 416, 418, 925, 930, 933, 934, 939, 948, 952, 957], "enter": [3, 5, 10, 14, 23, 34, 37, 327, 328, 333, 363, 931, 945, 946], "cannot": [3, 23, 24, 25, 35, 37, 43, 46, 91, 93, 135, 151, 262, 346, 416, 891, 916, 946, 949, 950, 955], "combin": [3, 8, 20, 23, 26, 43, 48, 256, 917, 950], "overrid": [3, 6, 10, 14, 20, 21, 26, 36, 48, 380, 382, 383, 388, 389, 871, 912, 921, 925, 949], "db2": [3, 6, 20, 23, 35, 909, 924, 925], "lockit": 3, "iter": [3, 20, 23, 24, 48, 164, 361, 823, 918, 927, 941], "hold": [3, 43, 78, 170, 187, 192, 193, 399, 400, 903], "durat": [3, 20, 21, 890, 918, 949, 953], "entir": [3, 14, 20, 39, 543, 916, 938], "rather": [3, 4, 5, 6, 10, 15, 20, 21, 23, 32, 38, 39, 56, 281, 406, 903, 910, 917, 931], "than": [3, 4, 5, 6, 10, 12, 14, 15, 19, 20, 21, 23, 24, 25, 26, 28, 32, 35, 37, 38, 39, 43, 53, 56, 232, 281, 377, 406, 903, 907, 910, 917, 921, 922, 925, 929, 931, 945, 949], "temporarili": 3, "handl": [3, 6, 14, 19, 36, 43, 48, 71, 132, 135, 137, 139, 141, 142, 143, 144, 145, 146, 147, 149, 150, 151, 152, 153, 154, 155, 157, 158, 159, 161, 164, 224, 225, 237, 248, 252, 253, 267, 278, 302, 304, 305, 307, 310, 312, 313, 314, 315, 316, 318, 320, 337, 338, 344, 345, 361, 405, 416, 925, 926, 929, 931, 934, 938], "dbmodul": [3, 22, 23, 24, 35], "first": [3, 6, 9, 12, 16, 19, 20, 21, 22, 23, 26, 28, 34, 37, 38, 39, 43, 44, 52, 53, 93, 105, 136, 230, 260, 281, 302, 324, 350, 351, 352, 363, 364, 388, 406, 769, 833, 906, 907, 912, 914, 916, 917, 919, 921, 922, 925, 926, 928, 930, 931, 932, 937, 939, 946, 951, 953, 958, 960], "introduc": [3, 20, 21, 928, 932, 936, 937, 939], "13": [3, 4, 20, 23, 39, 43, 602, 657, 705, 765, 903, 925], "unlockit": [3, 20, 23, 24], "ldapuri": [3, 5], "connect": [3, 4, 5, 8, 12, 20, 23, 32, 34, 38, 43, 48, 903, 907, 925, 926, 946], "uri": [3, 5, 20, 21, 33, 34, 39, 925], "binddn": 3, "bind_dn": 3, "dn": [3, 5, 20, 21, 22, 25, 30, 33, 34, 35, 39, 44, 335, 669, 912, 918, 925], "bind": [3, 5, 20, 21, 22, 39, 925, 952], "bindpwd": 3, "sasl": [3, 5, 20, 22, 38, 43, 925], "secret": [3, 20, 21, 36, 43, 46, 856, 945], "avoid": [3, 14, 19, 24, 38, 46, 247, 912, 925, 946], "stashsrvpw": [3, 20, 22], "sasl_mech": 3, "mechan": [3, 16, 20, 21, 22, 23, 36, 37, 39, 40, 43, 46, 154, 252, 698, 699, 907, 916, 917, 924, 925, 929, 930, 933, 938, 940, 949, 960], "ignor": [3, 4, 10, 19, 20, 21, 26, 28, 43, 48, 237, 262, 266, 269, 271, 280, 284, 344, 347, 352, 361, 390, 539, 714, 717, 871, 907, 910, 912, 916, 918, 925, 930, 958, 960], "sasl_authcid": 3, "when": [3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 17, 20, 21, 22, 23, 26, 28, 29, 33, 34, 36, 37, 38, 39, 40, 41, 43, 46, 49, 65, 67, 68, 72, 73, 76, 77, 78, 79, 85, 91, 92, 93, 111, 113, 115, 125, 126, 132, 136, 141, 143, 145, 150, 153, 154, 163, 164, 169, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 194, 195, 225, 228, 229, 230, 231, 232, 233, 237, 238, 252, 256, 260, 262, 263, 267, 270, 274, 277, 282, 284, 288, 296, 312, 317, 319, 320, 323, 324, 326, 327, 328, 329, 330, 331, 332, 333, 334, 337, 340, 341, 346, 347, 354, 356, 357, 358, 359, 361, 362, 363, 365, 377, 391, 403, 405, 407, 408, 410, 744, 745, 746, 903, 906, 912, 914, 916, 918, 922, 924, 925, 927, 931, 932, 936, 939, 941, 942, 943, 945, 946, 948, 949, 950, 952, 953, 955, 958, 960], "sasl_authzid": 3, "author": [3, 19, 20, 21, 48, 153, 225, 255, 302, 620, 752, 832, 869, 925, 926, 933, 948], "sasl_realm": 3, "debug": [3, 7, 8, 9, 20, 28, 911], "level": [3, 5, 10, 25, 37, 39, 43, 910, 914, 941], "openldap": [3, 5, 23, 24, 30, 912, 926], "librari": [3, 18, 20, 21, 24, 26, 29, 38, 41, 43, 46, 48, 49, 50, 52, 53, 54, 55, 56, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 116, 117, 118, 119, 121, 124, 125, 126, 129, 130, 132, 133, 134, 135, 136, 137, 138, 139, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 169, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 189, 194, 195, 198, 199, 200, 201, 202, 203, 204, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 229, 230, 231, 232, 233, 237, 238, 239, 240, 247, 248, 249, 250, 252, 253, 254, 255, 259, 262, 263, 264, 265, 266, 267, 268, 269, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 285, 288, 289, 290, 291, 292, 296, 297, 298, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 344, 345, 346, 347, 348, 349, 350, 351, 352, 354, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 398, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 414, 416, 419, 420, 421, 422, 871, 872, 902, 903, 909, 910, 912, 918, 924, 925, 926, 927, 928, 929, 931, 932, 933, 939, 940, 941, 952, 960], "integ": [3, 20, 21, 23, 36, 37, 902, 916, 917, 918, 921, 931], "interpret": [3, 36, 43, 46, 152, 247, 931, 949, 953, 955], "print": [3, 6, 7, 8, 363, 925, 952, 953, 955], "standard": [3, 6, 9, 14, 20, 37, 41, 43, 906, 925, 926, 952], "12": [3, 14, 21, 23, 34, 35, 37, 41, 43, 212, 309, 372, 373, 374, 581, 669, 702, 766, 903, 904, 918, 922, 925, 929, 932, 938, 939, 946, 953], "avail": [3, 6, 11, 12, 14, 20, 21, 23, 29, 34, 38, 43, 46, 56, 170, 187, 192, 193, 229, 254, 308, 312, 317, 363, 370, 373, 376, 400, 418, 568, 829, 851, 889, 903, 910, 922, 927, 933, 948, 950, 954, 960], "restrict": [3, 5, 14, 19, 21, 23, 48, 225, 926, 935, 937, 949, 953], "accord": [3, 19, 21, 36, 38, 43, 154, 167, 916, 917, 924, 931, 953, 955], "privileg": [3, 19, 34, 43, 48, 255, 925, 945, 959, 960], "kadm5": [3, 4, 6, 18, 20, 21, 23, 24, 34, 909, 924, 925, 926, 933, 935], "acl": [3, 4, 8, 18, 20, 21, 22, 23, 31, 924], "newprinc": 3, "twice": [3, 24, 34, 916, 936, 945, 951], "assign": [3, 19, 20, 34, 39, 48, 82, 84, 953], "howev": [3, 6, 14, 17, 20, 21, 23, 25, 32, 33, 35, 37, 39, 910, 926, 946, 960], "automat": [3, 4, 6, 8, 15, 17, 23, 34, 903, 906, 908, 910, 922, 925, 946, 948, 953], "previous": [3, 6, 23, 43, 48, 910, 925], "clearpolici": [3, 19], "add": [3, 6, 9, 11, 12, 14, 15, 19, 20, 21, 22, 23, 31, 33, 36, 38, 43, 48, 302, 345, 718, 904, 925, 946], "alias": [3, 11, 15, 22, 23, 38, 39, 918, 925], "addprinc": [3, 23, 34, 37, 904, 935], "ank": 3, "expdat": 3, "getdat": [3, 5, 6, 19], "string": [3, 5, 6, 16, 19, 20, 21, 23, 25, 26, 28, 34, 36, 37, 39, 43, 46, 48, 101, 166, 169, 192, 230, 231, 260, 266, 269, 280, 338, 348, 367, 375, 381, 384, 385, 419, 420, 421, 422, 744, 745, 746, 827, 832, 843, 874, 875, 895, 903, 904, 907, 912, 918, 925, 926, 928, 930, 931, 938, 939, 941, 949, 953], "date": [3, 6, 8, 20, 21, 23, 26, 37, 167, 225, 400, 838, 905, 925], "pwexpir": [3, 19, 26], "pwexpdat": 3, "maxlif": [3, 19, 23], "maximum": [3, 5, 6, 10, 14, 15, 20, 21, 23, 24, 33, 39, 46, 313, 363, 902, 918, 938, 946, 949], "life": [3, 5, 19, 23, 949], "maxrenewlif": [3, 5, 19, 23], "renew": [3, 5, 6, 20, 21, 23, 48, 852, 890, 918, 925, 937, 946, 949, 950, 953, 960], "kvno": [3, 6, 11, 14, 15, 16, 23, 26, 29, 32, 34, 41, 312, 416, 837, 889, 917, 925, 944, 947], "initi": [3, 5, 12, 14, 15, 21, 22, 23, 25, 26, 34, 35, 38, 40, 45, 48, 99, 102, 115, 124, 231, 271, 289, 291, 338, 403, 511, 883, 890, 903, 906, 912, 916, 925, 926, 929, 930, 945, 946, 949, 950, 952, 953, 955, 960], "being": [3, 14, 20, 21, 23, 29, 39, 44, 46, 247, 374, 746, 907, 914, 958], "allow_postd": [3, 5], "prohibit": [3, 926], "postdat": [3, 19, 20, 269, 946, 949, 950], "clear": [3, 6, 11, 15, 36, 46, 48, 136, 156, 379], "allow_forward": [3, 5], "forward": [3, 15, 20, 21, 23, 33, 34, 36, 38, 43, 48, 356, 536, 553, 846, 925, 946, 949, 950, 953, 960], "allow_renew": 3, "allow_proxi": 3, "proxiabl": [3, 20, 21, 48, 846, 946, 949, 950, 953], "allow_dup_skei": 3, "tgt": [3, 14, 20, 23, 26, 37, 46, 48, 221, 344, 345, 916, 917, 925, 946, 953], "session": [3, 14, 15, 21, 23, 33, 34, 43, 46, 48, 225, 322, 327, 332, 356, 414, 444, 445, 819, 831, 832, 838, 839, 903, 907, 925, 946, 950, 955, 960], "requires_preauth": [3, 5, 14, 23, 25, 35, 37, 40, 918], "preauthent": [3, 16, 20, 21, 23, 25, 28, 30, 37, 41, 46, 48, 252, 728, 838, 851, 852, 865, 882, 916, 925, 930, 933, 946, 949, 950], "requires_hwauth": [3, 918, 938], "hardwar": [3, 20, 34, 46, 928, 938, 946, 950], "devic": [3, 20, 21, 46, 661, 662], "ok_as_deleg": [3, 918], "okai": [3, 946, 950], "deleg": [3, 20, 21, 335, 552, 660, 916, 925, 946, 950, 955], "hint": [3, 20, 149], "allow_svr": [3, 23, 25, 35, 40], "issuanc": 3, "17": [3, 14, 20, 21, 24, 25, 26, 37, 40, 43, 231, 345, 579, 656, 693, 919, 925, 926, 930], "later": [3, 19, 20, 21, 22, 23, 26, 33, 37, 38, 39, 41, 43, 136, 249, 746, 902, 917, 921, 925, 926, 932, 939], "allow_tgs_req": 3, "grant": [3, 14, 19, 20, 21, 23, 26, 28, 34, 35, 37, 39, 43, 46, 48, 225, 237, 262, 266, 269, 766, 903, 916, 925, 926, 935, 939, 944, 946, 949, 953, 959], "tg": [3, 20, 21, 25, 26, 35, 48, 225, 302, 405, 765, 866, 916, 918, 925, 937], "allow_tix": 3, "forbid": 3, "needchang": [3, 5], "password_changing_servic": 3, "mark": [3, 6, 20, 21, 34, 344, 926], "ok_to_auth_as_deleg": [3, 918], "itself": [3, 4, 8, 10, 14, 15, 20, 21, 28, 43, 46, 198, 199, 200, 201, 202, 203, 207, 208, 209, 210, 213, 216, 217, 222, 336, 742, 832, 903, 906, 908, 931, 938, 946], "arbitrari": [3, 43], "constrain": [3, 335, 552, 660, 925, 955], "no_auth_data_requir": [3, 918], "pac": [3, 20, 48, 342, 343, 656, 666, 691, 866, 869, 925, 949], "ad": [3, 6, 8, 17, 20, 21, 22, 23, 24, 25, 26, 32, 34, 38, 40, 41, 48, 195, 302, 304, 746, 903, 916, 918, 925, 928, 955], "signedpath": [3, 20, 925], "data": [3, 6, 9, 14, 20, 21, 22, 23, 24, 26, 32, 43, 44, 46, 48, 63, 79, 80, 98, 113, 114, 117, 119, 120, 121, 123, 129, 130, 141, 151, 153, 155, 169, 178, 203, 209, 213, 225, 247, 255, 259, 260, 262, 264, 277, 296, 297, 298, 300, 301, 302, 325, 328, 331, 332, 333, 335, 337, 342, 343, 354, 356, 358, 361, 362, 370, 373, 377, 378, 382, 383, 384, 385, 388, 390, 395, 407, 472, 484, 485, 486, 542, 543, 684, 728, 752, 799, 800, 803, 817, 819, 827, 829, 832, 833, 835, 838, 839, 842, 844, 851, 852, 862, 865, 869, 871, 872, 874, 875, 878, 881, 883, 892, 897, 903, 907, 908, 912, 916, 917, 919, 921, 925, 926, 928, 929, 930, 933, 937, 938, 942, 950], "lockdown_kei": [3, 19, 918, 925], "leav": [3, 14, 24, 28, 32, 33], "chpass": [3, 936], "extract": [3, 15, 19, 34, 231, 906, 925], "deni": [3, 19, 25, 28, 35, 935, 939, 953], "attribut": [3, 5, 6, 9, 16, 19, 20, 21, 22, 23, 24, 26, 36, 37, 48, 255, 656, 847, 918, 925, 926, 928, 931, 938, 949, 953], "chrand": 3, "renam": [3, 912, 925, 936], "malici": [3, 46], "like": [3, 6, 8, 12, 14, 15, 19, 21, 23, 32, 33, 34, 37, 38, 39, 41, 43, 192, 903, 907, 908, 910, 912, 914, 930, 934, 946], "krbtgt": [3, 19, 26, 37, 41, 43, 280, 303, 650, 763, 916, 917, 919, 925, 946, 955], "without": [3, 14, 19, 20, 21, 23, 24, 28, 32, 34, 35, 36, 37, 43, 133, 370, 373, 543, 872, 903, 907, 910, 912, 922, 925, 926, 945, 946, 953, 960], "network": [3, 15, 17, 21, 23, 25, 29, 32, 34, 38, 39, 40, 43, 46, 262, 377, 528, 529, 530, 531, 909, 912, 945, 946, 959, 960], "randkei": [3, 14, 23, 26, 34, 37, 925], "random": [3, 6, 14, 20, 21, 23, 25, 34, 48, 917, 922, 925], "nokei": [3, 23, 37], "caus": [3, 4, 6, 14, 20, 21, 24, 25, 26, 34, 35, 37, 38, 39, 40, 43, 48, 247, 249, 390, 742, 903, 907, 912, 925, 926, 950, 954], "pw": [3, 925], "db_princ_arg": 3, "indic": [3, 6, 14, 19, 20, 21, 23, 26, 28, 30, 36, 37, 39, 41, 43, 46, 154, 247, 329, 734, 735, 736, 737, 741, 742, 743, 744, 843, 903, 904, 906, 907, 916, 917, 918, 919, 921, 922, 925, 926, 928, 929, 930, 938, 946, 949, 960], "object": [3, 5, 6, 20, 21, 22, 23, 24, 25, 28, 35, 36, 43, 48, 264, 271, 746, 910, 912, 916, 925, 926, 927, 928, 929, 930, 931, 932, 935, 936, 937, 938, 939, 940, 941, 942], "linkdn": 3, "newli": [3, 6, 26, 37, 107, 113, 125, 126, 176, 296, 331, 332, 361, 365, 366, 377, 903, 910, 925], "point": [3, 14, 15, 23, 32, 34, 43, 332, 409, 416, 833, 903, 908, 912, 925, 943], "containerdn": 3, "container_dn": 3, "under": [3, 5, 6, 10, 20, 21, 22, 38, 155, 159, 907, 910, 922, 925, 926], "tktpolici": [3, 5, 23], "associ": [3, 4, 9, 19, 20, 21, 23, 35, 38, 43, 542, 903, 907, 916, 918, 926, 960], "within": [3, 15, 20, 21, 24, 34, 35, 39, 43, 48, 132, 154, 254, 263, 358, 362, 367, 375, 388, 853, 903, 918, 919, 925, 926, 931, 949, 958, 960], "subtre": [3, 5, 20, 22], "exampl": [3, 5, 6, 9, 14, 15, 16, 20, 21, 22, 23, 24, 26, 28, 32, 34, 35, 37, 38, 39, 41, 43, 56, 100, 103, 290, 292, 903, 904, 907, 910, 911, 925, 926, 930, 941, 945, 946, 949, 953, 960], "jennif": [3, 945, 946, 960], "No": [3, 12, 21, 34, 151, 327, 926, 946, 960], "athena": [3, 5, 14, 15, 19, 20, 21, 23, 24, 28, 32, 34, 912, 926, 941, 945, 946, 960], "re": [3, 5, 6, 14, 23, 34, 41, 736, 907, 931, 945, 960], "modifi": [3, 6, 9, 18, 19, 23, 25, 28, 34, 40, 43, 100, 103, 114, 136, 144, 146, 158, 290, 292, 297, 314, 367, 368, 872, 912, 918, 925, 926, 936, 941, 949], "field": [3, 6, 20, 21, 35, 36, 37, 39, 44, 46, 48, 153, 258, 312, 332, 333, 345, 354, 358, 359, 361, 362, 414, 755, 759, 895, 916, 917, 918, 921, 922, 925, 929, 930, 938, 942, 946, 958], "addit": [3, 18, 19, 20, 21, 22, 23, 26, 29, 34, 37, 38, 39, 40, 43, 46, 48, 303, 365, 366, 416, 842, 903, 907, 910, 912, 914, 915, 925, 926, 929, 938, 943, 949, 953, 960], "alia": [3, 6, 11, 43, 48, 144, 146, 314, 367, 368], "modprinc": [3, 23, 35, 37, 40, 935], "receiv": [3, 4, 8, 9, 14, 20, 21, 37, 39, 41, 43, 48, 224, 247, 275, 327, 328, 332, 333, 356, 358, 362, 365, 376, 377, 882, 928, 929, 938, 939, 942, 946, 960], "too": [3, 23, 56, 100, 103, 119, 269, 290, 292, 308], "mani": [3, 17, 21, 28, 35, 39, 41, 934, 946, 960], "enough": [3, 23, 26, 99, 102, 167, 289, 291, 772], "between": [3, 9, 20, 21, 23, 25, 26, 29, 34, 35, 41, 43, 45, 136, 158, 387, 891, 903, 925, 939, 946, 948, 949], "them": [3, 14, 15, 20, 22, 23, 24, 25, 29, 32, 34, 37, 39, 41, 46, 82, 84, 255, 332, 346, 405, 737, 903, 910, 912, 925, 926, 930, 931, 941, 946, 948, 960], "successfulli": [3, 6, 12, 35, 43, 46, 247, 303, 418, 871, 872], "old_princip": 3, "new_princip": 3, "renprinc": 3, "alias_princ": 3, "target_princ": 3, "chain": [3, 20, 21, 918, 925], "up": [3, 4, 8, 10, 20, 21, 22, 23, 28, 31, 32, 33, 34, 37, 38, 39, 43, 46, 98, 271, 388, 389, 391, 902, 908, 912, 918, 925, 941, 945, 949], "depth": [3, 918], "10": [3, 5, 14, 15, 21, 23, 35, 38, 39, 42, 43, 44, 132, 143, 154, 155, 160, 167, 195, 220, 344, 511, 583, 643, 658, 670, 903, 904, 907, 918, 925], "22": [3, 4, 10, 20, 21, 22, 23, 39, 205, 228, 536, 595, 684, 904, 918, 925, 946], "delprinc": [3, 23], "neither": [3, 327, 926, 949, 950, 953], "changepw": [3, 14, 23, 26, 166, 247, 302, 303, 384], "same": [3, 4, 5, 10, 12, 19, 20, 21, 23, 24, 28, 36, 39, 43, 52, 53, 91, 101, 105, 107, 136, 138, 151, 155, 171, 180, 230, 252, 272, 273, 277, 281, 309, 350, 351, 352, 364, 390, 853, 903, 907, 912, 918, 925, 930, 931, 945, 949, 953, 955], "cpw": [3, 14], "keepold": [3, 14, 23, 925], "keep": [3, 9, 15, 23, 35, 907, 910, 911, 945], "necessari": [3, 14, 21, 22, 23, 24, 33, 34, 37, 39, 43, 120, 122, 123, 262, 345, 389, 409, 929, 930, 934, 945, 946], "perhap": [3, 14, 20, 23, 24], "systest": 3, "bleep": [3, 11, 946, 959, 960], "com": [3, 6, 9, 11, 16, 20, 21, 22, 23, 28, 35, 37, 38, 39, 41, 42, 917, 919, 925, 926, 945, 946, 958, 959, 960], "keepkvno": 3, "oldest_kvno_to_keep": 3, "purg": [3, 6, 14, 925], "lower": [3, 19, 21, 43, 232, 941, 951, 958], "ters": 3, "get": [3, 12, 14, 16, 19, 20, 21, 32, 33, 35, 38, 39, 48, 59, 60, 163, 238, 256, 260, 277, 912, 925, 929, 932, 938, 945, 946, 949, 953, 960], "quot": [3, 6, 346, 408, 410, 904], "tab": [3, 6, 346, 918, 925], "inquir": [3, 19], "getprinc": [3, 6, 14, 26, 35, 925], "tlyu": 3, "never": [3, 14, 15, 17, 19, 20, 23, 24, 35, 100, 103, 230, 290, 292, 922, 945, 946], "last": [3, 6, 9, 20, 23, 24, 35, 44, 48, 173, 198, 200, 221, 247, 316, 324, 388, 741, 860, 903, 904, 918, 928, 937], "mon": [3, 35], "aug": 3, "16": [3, 19, 20, 21, 37, 43, 553, 580, 668, 695, 902, 916, 917, 918, 921, 922, 925, 928, 935, 937, 946], "47": [3, 34], "edt": 3, "1996": [3, 926, 960], "0": [3, 5, 6, 14, 15, 20, 21, 23, 28, 34, 35, 37, 39, 41, 43, 46, 49, 50, 53, 55, 56, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 116, 117, 118, 119, 121, 124, 125, 126, 129, 130, 132, 133, 134, 135, 137, 139, 141, 142, 145, 147, 148, 149, 150, 152, 153, 154, 155, 156, 157, 158, 159, 161, 162, 163, 164, 165, 166, 167, 169, 170, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187, 189, 192, 193, 215, 218, 224, 225, 229, 231, 233, 237, 238, 240, 247, 250, 262, 263, 264, 266, 267, 268, 269, 270, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 284, 288, 289, 290, 291, 292, 296, 297, 298, 300, 301, 302, 303, 304, 305, 306, 307, 308, 310, 312, 313, 315, 316, 317, 318, 319, 320, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 337, 338, 339, 340, 341, 344, 346, 347, 349, 354, 356, 357, 358, 359, 360, 361, 362, 363, 365, 366, 376, 377, 378, 379, 380, 384, 385, 386, 387, 391, 392, 393, 394, 396, 397, 398, 399, 400, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 416, 539, 627, 635, 653, 685, 739, 741, 797, 809, 843, 904, 914, 916, 918, 921, 922, 925, 926, 930, 935, 939, 940, 941, 942, 950, 953, 955], "dai": [3, 5, 21, 23, 37, 48, 398, 904, 946, 960], "00": [3, 5, 23, 904], "7": [3, 6, 22, 23, 26, 33, 39, 41, 43, 249, 543, 618, 624, 628, 636, 648, 665, 707, 903, 918, 925], "bjaspan": 3, "success": [3, 6, 8, 20, 24, 25, 35, 46, 49, 50, 56, 62, 64, 65, 67, 69, 72, 73, 74, 76, 77, 78, 79, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 116, 117, 118, 119, 121, 122, 124, 125, 126, 129, 130, 132, 133, 134, 135, 137, 141, 142, 144, 145, 147, 148, 149, 150, 152, 153, 155, 156, 157, 158, 159, 161, 162, 163, 164, 166, 167, 169, 170, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187, 189, 192, 193, 215, 218, 224, 225, 229, 231, 233, 237, 238, 240, 250, 262, 263, 264, 266, 267, 268, 269, 270, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 284, 288, 289, 290, 291, 292, 296, 297, 298, 300, 301, 302, 303, 304, 305, 307, 308, 310, 312, 313, 316, 317, 318, 319, 320, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 337, 338, 339, 340, 341, 344, 346, 347, 349, 354, 356, 357, 358, 359, 360, 361, 362, 363, 365, 366, 376, 377, 378, 379, 380, 384, 385, 386, 387, 391, 392, 393, 394, 396, 397, 398, 399, 400, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 416, 418, 627, 843, 907, 918, 929, 932, 942, 953, 955], "vno": [3, 14, 312, 317, 856], "mkei": [3, 6], "none": [3, 20, 21, 22, 26, 36, 37, 57, 58, 275, 287, 306, 371, 374, 907, 917, 953, 960], "3": [3, 6, 14, 19, 20, 21, 23, 26, 32, 36, 37, 43, 44, 166, 419, 420, 421, 472, 542, 584, 621, 633, 641, 649, 688, 697, 904, 912, 916, 918, 922, 925, 926, 930, 953], "86400": 3, "604800": 3, "785926535": 3, "753241234": 3, "785900000": 3, "786100034": 3, "express": [3, 21, 904, 926], "retriev": [3, 6, 23, 24, 41, 43, 44, 46, 48, 158, 273, 312, 368, 377, 402, 405, 882, 918, 925, 926, 955], "style": [3, 21, 39, 419, 420, 421, 644, 646, 925], "glob": [3, 6], "wild": 3, "card": [3, 20, 21, 925], "charact": [3, 19, 20, 21, 23, 34, 38, 39, 346, 399, 410, 721, 918, 951], "listprinc": 3, "test": [3, 9, 10, 12, 14, 21, 37, 48, 909, 912, 914, 925, 926, 949, 956], "test3": [3, 904], "secur": [3, 7, 14, 15, 20, 21, 23, 25, 30, 31, 34, 37, 39, 41, 43, 46, 252, 327, 569, 908, 909, 925, 926, 943, 946, 960], "ov": 3, "test2": [3, 904], "test1": [3, 904], "testus": 3, "getstr": 3, "suppli": [3, 11, 43, 46, 48, 224, 247, 260, 264, 269, 278, 279, 280, 333, 344, 374, 375, 388, 741, 742, 882, 912, 929, 930, 938], "per": [3, 6, 9, 10, 14, 18, 20, 21, 23, 26, 28, 36, 39, 43, 46, 903, 925, 927, 929, 932, 935, 936, 938, 939, 940, 941, 942], "plugin": [3, 20, 22, 909, 912, 923, 924, 925, 926, 941], "recogn": [3, 20, 21, 37, 41, 43, 918, 949, 958], "require_auth": [3, 16, 925], "multipl": [3, 10, 14, 16, 20, 21, 22, 23, 24, 28, 34, 35, 36, 37, 39, 43, 46, 853, 903, 907, 910, 918, 925, 930, 931, 938, 949, 958, 960], "space": [3, 16, 20, 24, 37, 38, 56, 99, 102, 117, 119, 121, 289, 291, 298, 308, 348, 363, 409, 422, 904, 911], "accept": [3, 4, 8, 14, 15, 16, 20, 21, 26, 34, 38, 39, 41, 151, 391, 904, 906, 910, 925, 926, 927, 931, 940, 941, 946, 949], "session_enctyp": [3, 23, 925], "otp": [3, 16, 25, 30, 46, 370, 702, 704, 705, 728, 744, 924, 925], "enabl": [3, 4, 8, 14, 15, 20, 21, 22, 23, 24, 25, 28, 34, 36, 37, 39, 40, 41, 43, 55, 78, 903, 911, 912, 925, 928, 933, 953, 960], "One": [3, 20, 23, 34, 36, 38, 43, 344, 903, 904, 945, 946, 959], "json": [3, 36, 46, 370, 373, 744, 746, 916], "repres": [3, 21, 34, 43, 158, 891, 902, 906, 917, 918, 926], "arrai": [3, 36, 43, 46, 48, 100, 103, 111, 173, 242, 246, 256, 290, 292, 324, 334, 354, 356, 827, 831, 833, 838, 839, 852, 874, 875, 939, 941], "pkinit_cert_match": [3, 21, 37, 925], "defin": [3, 12, 20, 21, 33, 34, 39, 43, 101, 119, 230, 746, 907, 912, 916, 917, 918, 930, 934, 941, 942, 953], "certif": [3, 20, 21, 29, 40, 43, 48, 255, 701, 919, 925, 933, 955, 960], "dure": [3, 4, 8, 17, 20, 21, 23, 26, 34, 35, 40, 43, 354, 382, 416, 725, 916, 917, 925, 929, 936, 946, 953], "those": [3, 6, 14, 19, 21, 23, 25, 26, 34, 39, 43, 46, 912, 914, 921, 925, 926, 929, 931, 934, 935, 938, 955, 959, 960], "pac_privsvr_enctyp": 3, "checksum": [3, 43, 48, 104, 175, 202, 203, 302, 303, 331, 332, 333, 335, 344, 345, 537, 544, 663, 665, 667, 668, 672, 819, 862, 919, 922, 925, 931], "buffer": [3, 23, 43, 48, 56, 98, 99, 119, 170, 187, 192, 193, 281, 289, 302, 303, 308, 333, 338, 341, 376, 399, 400, 406, 409, 411, 543, 833, 925, 931], "deriv": [3, 6, 14, 20, 25, 48, 99, 100, 102, 103, 113, 129, 289, 290, 291, 292, 296, 300, 917, 922, 925, 926, 951], "It": [3, 5, 8, 9, 10, 12, 14, 20, 21, 23, 24, 34, 35, 36, 39, 46, 55, 124, 203, 210, 245, 247, 282, 384, 385, 745, 882, 903, 907, 916, 918, 925, 926, 928, 932, 937, 939, 945, 956, 960], "cross": [3, 20, 21, 344, 345, 361, 912, 916, 925], "entri": [3, 8, 9, 11, 12, 14, 15, 19, 20, 21, 22, 23, 24, 26, 32, 34, 35, 37, 38, 39, 40, 41, 43, 46, 48, 153, 173, 195, 198, 200, 221, 247, 311, 317, 322, 324, 327, 328, 333, 339, 354, 361, 416, 838, 856, 860, 903, 906, 908, 917, 919, 922, 925, 937, 938, 946, 950, 953], "activ": [3, 4, 6, 8, 10, 14, 21, 23, 25, 37, 40, 169, 925, 948], "directori": [3, 5, 12, 20, 21, 22, 28, 33, 34, 37, 169, 344, 903, 907, 911, 913, 914, 924, 925, 945, 953, 957, 958, 959, 960], "ae": [3, 14, 15, 20, 25, 912, 925, 926], "sha2": [3, 20, 925], "setstr": [3, 16], "foo": [3, 6, 21, 23], "hotp": 3, "al": 3, "delstr": 3, "addpol": [3, 23, 35], "lifetim": [3, 6, 14, 21, 23, 48, 153, 367, 368, 758, 832, 838, 903, 918, 925, 928, 937, 946, 949, 953, 960], "minlif": 3, "minimum": [3, 20, 23, 33, 918], "minlength": 3, "length": [3, 20, 33, 43, 46, 48, 91, 92, 99, 100, 102, 103, 116, 117, 119, 124, 191, 203, 210, 246, 256, 262, 282, 286, 289, 290, 291, 292, 313, 338, 341, 363, 399, 744, 804, 805, 811, 817, 824, 827, 835, 854, 865, 874, 875, 885, 897, 916, 917, 921, 922, 931, 951], "minclass": 3, "class": [3, 23, 918, 951], "five": [3, 21, 34, 904, 907, 936, 951], "upper": [3, 19, 39, 951], "punctuat": [3, 21, 34, 951], "whitespac": [3, 20, 21], "unprint": 3, "past": [3, 943], "kept": [3, 17, 20, 23, 32], "maxfailur": [3, 35], "maxnumb": 3, "failur": [3, 6, 14, 24, 35, 46, 119, 129, 130, 159, 262, 300, 301, 312, 409, 410, 411, 925, 926, 931, 940, 942], "track": [3, 6, 9, 35, 907, 943], "counter": [3, 35, 918], "reset": [3, 9, 35, 46, 157, 388, 918, 925], "lockout": [3, 20, 24, 25, 30, 918], "failurecountinterv": [3, 35], "failuretim": 3, "happen": [3, 17, 20, 34, 39, 41, 946], "elaps": [3, 925], "mean": [3, 12, 14, 20, 21, 23, 33, 34, 37, 46, 908, 913, 926, 946, 953, 960], "forev": 3, "lockoutdur": [3, 35], "lockouttim": 3, "occur": [3, 6, 9, 78, 344, 388, 925], "count": [3, 6, 43, 48, 87, 89, 111, 288, 916, 918, 921], "interv": [3, 8, 21, 23, 34, 35, 902, 904, 918], "out": [3, 8, 12, 21, 23, 24, 33, 35, 36, 37, 41, 43, 49, 50, 56, 59, 60, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 76, 77, 78, 89, 91, 92, 93, 95, 96, 97, 99, 101, 102, 104, 105, 107, 108, 111, 112, 113, 115, 116, 117, 118, 119, 121, 124, 125, 126, 129, 130, 132, 134, 135, 138, 141, 142, 143, 145, 149, 150, 152, 153, 154, 158, 163, 164, 166, 169, 170, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187, 189, 192, 193, 194, 195, 224, 225, 228, 229, 231, 232, 233, 237, 238, 240, 253, 262, 263, 264, 266, 267, 268, 269, 270, 271, 274, 275, 276, 277, 281, 282, 284, 288, 289, 291, 296, 298, 300, 301, 303, 305, 307, 308, 309, 310, 312, 313, 316, 317, 319, 320, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 337, 338, 339, 340, 341, 346, 347, 349, 356, 357, 358, 359, 360, 361, 362, 363, 365, 366, 370, 373, 376, 377, 384, 385, 391, 392, 393, 394, 396, 397, 398, 399, 400, 403, 404, 405, 406, 407, 408, 410, 411, 412, 414, 537, 538, 540, 541, 544, 903, 912, 925, 926, 945, 948, 955], "until": [3, 6, 14, 21, 23, 43, 902, 903, 907, 912, 922, 925, 946], "allowedkeysalt": 3, "tupl": 3, "long": [3, 14, 15, 23, 25, 26, 37, 38, 39, 41, 43, 99, 289, 367, 368, 745, 772, 903, 906, 925, 926, 929, 938, 941, 955], "term": [3, 14, 23, 25, 26, 37, 41, 745, 903, 906, 925, 926, 929, 938, 955], "comma": [3, 6, 10, 20, 21], "To": [3, 14, 15, 16, 19, 20, 21, 23, 24, 25, 28, 29, 34, 35, 36, 37, 38, 39, 40, 41, 43, 46, 346, 902, 910, 914, 918, 921, 925, 931, 935, 937, 943, 945, 946, 953], "2": [3, 5, 6, 14, 15, 19, 21, 23, 26, 34, 35, 37, 39, 43, 166, 322, 414, 538, 550, 599, 606, 623, 629, 637, 650, 659, 676, 689, 713, 738, 743, 914, 916, 917, 918, 921, 922, 925, 926, 930, 941, 953, 960], "guest": [3, 21], "modpol": 3, "delpol": 3, "del_polici": 3, "sure": [3, 5, 12, 14, 15, 22, 23, 26, 33, 41, 945, 946, 949], "want": [3, 23, 28, 34, 550, 556, 910, 940, 945, 946, 953], "ye": [3, 5, 23, 912, 949], "getpol": 3, "180": [3, 35], "6": [3, 6, 9, 15, 19, 37, 39, 322, 344, 414, 537, 619, 622, 634, 642, 655, 667, 675, 764], "15552000": 3, "meaning": 3, "listpol": 3, "pol": [3, 19], "dict": [3, 21], "min": [3, 19, 904], "nopw": 3, "princ": [3, 6, 21, 49, 50, 91, 92, 93, 94, 390, 799, 800, 801, 802, 803, 804, 805, 806, 917, 918], "exp": [3, 20, 21, 26, 37], "rule": [3, 19, 21, 23, 28, 38, 39, 43, 154, 953, 955, 958, 959], "eytab": 3, "less": [3, 20, 25, 53, 903, 910, 921, 922, 925], "verbos": [3, 6, 23, 910, 925, 949], "norandkei": 3, "do": [3, 4, 6, 10, 14, 15, 20, 21, 22, 23, 26, 28, 29, 32, 33, 34, 37, 38, 39, 40, 41, 43, 46, 224, 269, 351, 410, 554, 911, 912, 914, 925, 926, 930, 931, 935, 937, 938, 945, 946, 949, 953, 955, 960], "stai": 3, "unchang": [3, 14, 953], "uniqu": [3, 43, 48, 267, 416, 650, 652, 903, 931], "xst": 3, "tmp": [3, 21, 34, 907, 913, 924, 946, 953, 960], "highest": [3, 6, 14, 21, 312, 317, 416], "pars": [3, 28, 43, 45, 46, 48, 237, 262, 266, 269, 280, 358, 362, 370, 373, 909, 916, 925], "whose": [3, 5, 10, 17, 19, 21, 34, 38, 40, 43, 46, 132, 218, 231, 916, 921, 946, 959], "ktrem": 3, "exclus": [3, 922, 926, 949, 953], "extrem": 3, "caution": 3, "lr": [3, 11, 860], "origin": [3, 14, 21, 23, 39, 43, 46, 912, 918, 926, 931], "written": [3, 4, 155, 856, 906, 922, 926], "tom": 3, "yu": 3, "openvis": [3, 926], "kpasswd": [3, 4, 14, 15, 20, 21, 23, 29, 33, 925, 944, 945, 947, 960], "nofork": 4, "proponli": [4, 23], "pid_fil": [4, 8, 10], "kdb5_util_path": 4, "kprop_path": 4, "kprop_port": [4, 924, 960], "dump_fil": 4, "typic": [4, 15, 20, 21, 26, 33, 38, 39, 43, 46, 98, 255, 914, 918, 924, 927, 929, 930, 935, 936, 938, 942, 949, 955], "need": [4, 6, 12, 14, 15, 19, 20, 21, 23, 32, 33, 34, 35, 37, 38, 39, 40, 41, 43, 46, 49, 64, 65, 67, 68, 72, 73, 76, 77, 78, 91, 92, 93, 99, 100, 102, 103, 111, 113, 115, 125, 126, 132, 141, 143, 145, 150, 153, 154, 163, 164, 169, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 194, 195, 225, 228, 229, 231, 232, 233, 238, 260, 263, 267, 270, 274, 277, 281, 282, 284, 288, 289, 290, 291, 292, 296, 312, 317, 319, 320, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 337, 338, 340, 341, 346, 347, 356, 357, 358, 359, 361, 362, 365, 366, 377, 391, 403, 405, 406, 407, 408, 410, 570, 745, 746, 767, 903, 904, 909, 910, 911, 912, 914, 917, 925, 931, 932, 934, 939, 941, 943, 945, 946, 949, 952], "machin": [4, 8, 12, 14, 15, 17, 18, 21, 31, 32, 34, 37, 38, 39, 903, 908, 912, 945, 946, 959, 960], "administ": [4, 15, 34], "locat": [4, 7, 8, 10, 15, 19, 20, 21, 22, 24, 25, 29, 34, 39, 41, 43, 48, 903, 907, 912, 913, 922, 924, 925, 926, 933, 941, 946, 948, 949, 950, 952, 953, 954, 955, 960], "affect": [4, 19, 20, 21, 26, 28, 40, 126, 133, 231, 925, 949, 960], "acl_fil": [4, 8, 19, 20, 34], "dict_fil": [4, 20, 942], "kadmind_port": [4, 20, 34], "iprop": [4, 8, 20, 925, 926], "relat": [4, 6, 20, 21, 22, 28, 29, 35, 37, 39, 169, 832, 918, 925, 926], "control": [4, 14, 15, 18, 19, 20, 21, 22, 26, 28, 34, 36, 37, 38, 41, 43, 46, 245, 281, 406, 416, 912, 913, 925, 927, 932, 933, 934, 937, 939, 940, 941, 942, 957], "tell": [4, 10, 945, 946, 952], "action": [4, 6, 14, 907, 926, 936], "pathnam": [4, 8, 20, 21, 23, 24, 28, 29, 37, 906, 910, 913, 960], "begin": [4, 6, 15, 21, 22, 23, 28, 36, 43, 91, 93, 99, 100, 102, 103, 203, 210, 289, 290, 291, 292, 346, 405, 916, 918, 928, 931, 932, 941, 958], "put": [4, 10, 34, 346, 814], "background": [4, 8, 10, 34], "disassoci": [4, 10], "termin": [4, 10, 48, 173, 195, 221, 228, 232, 233, 242, 263, 327, 354, 356, 363, 368, 409, 909, 918, 941, 953], "increment": [4, 8, 9, 14, 19, 20, 24, 31, 35, 39, 48, 87, 89, 327, 328, 333, 918, 922, 925, 926], "propag": [4, 6, 7, 8, 14, 17, 19, 20, 21, 24, 31, 35, 909, 925, 926, 945], "replica": [4, 6, 7, 8, 9, 14, 15, 17, 20, 21, 23, 31, 32, 35, 41, 909, 925], "full": [4, 8, 9, 14, 20, 23, 39, 48, 333, 663, 912, 925, 934, 945, 953], "dump": [4, 7, 8, 17, 20, 24, 34, 924, 925], "facil": [4, 15, 20, 43, 925], "iprop_en": [4, 8, 20, 23], "kiprop": [4, 8, 23], "canon": [4, 15, 22, 23, 38, 39, 192, 302, 935, 939], "regist": [4, 21, 23, 28, 39, 926, 933, 960], "datebas": 4, "serv": [4, 10, 21, 23, 925], "fetch": [4, 5, 6, 10, 11, 21, 23, 71, 141, 416, 925], "keyboard": [4, 6, 10, 48], "invok": [4, 8, 9, 11, 12, 21, 23, 24, 46, 80, 136, 247, 388, 931, 938, 939, 940, 949, 951, 953], "disk": [4, 5, 6, 15, 17, 24, 32, 34, 46, 903, 908, 911], "foreground": [4, 8], "listen": [4, 8, 10, 20, 34, 39, 925], "respond": [4, 21, 48, 369, 370, 371, 372, 373, 374, 737, 744, 745, 746, 882, 883, 925, 938], "poll": [4, 8, 20, 23, 925], "hierarch": [4, 21, 925], "topologi": 4, "pid": [4, 8, 10, 925], "identifi": [4, 10, 21, 28, 43, 166, 267, 317, 319, 739, 832, 838, 853, 925, 926, 931, 955], "whether": [4, 6, 8, 10, 14, 20, 21, 26, 28, 35, 36, 43, 46, 48, 105, 224, 243, 244, 245, 247, 251, 255, 257, 321, 409, 911, 917, 925, 926, 928, 935, 942, 946, 953], "init": [4, 10, 927, 928, 929, 932, 935, 936, 937, 938, 939, 940], "stop": [4, 10, 24, 930], "correct": [4, 10, 14, 21, 23, 33, 34, 41, 124, 741, 903, 912, 925, 926], "path": [4, 5, 8, 20, 21, 22, 25, 28, 29, 34, 39, 361, 910, 912, 914, 925, 953, 960], "command": [4, 8, 9, 10, 14, 15, 20, 21, 22, 23, 24, 26, 29, 32, 34, 35, 37, 41, 904, 906, 909, 910, 911, 912, 918, 925, 944, 945, 946, 948, 951, 953, 955, 960], "kdb": [4, 22, 23, 24, 35, 909, 920, 925, 926, 933, 937, 949, 952], "resync": [4, 9, 23, 925], "spawn": 4, "transfer": [4, 23, 37], "systemd": [4, 10, 925], "socket": [4, 10, 20, 21, 36, 48, 377, 924, 925, 940], "listen_pid": [4, 10], "listen_fd": [4, 10], "caller": [4, 10, 43, 46, 71, 85, 99, 100, 102, 103, 117, 119, 121, 136, 144, 146, 247, 254, 271, 281, 289, 290, 291, 292, 298, 303, 314, 316, 332, 363, 367, 368, 406, 416, 833, 902, 925, 932, 938, 941], "correspond": [4, 6, 10, 19, 21, 37, 39, 43, 44, 46, 56, 152, 247, 265, 344, 890, 914, 917, 918, 925, 930, 931, 936, 960], "kadmind_listen": [4, 20], "kpasswd_listen": [4, 20], "equival": [4, 10, 20, 36, 166, 384, 385, 925], "user_dn": 5, "passwd": [5, 33, 901, 926, 953], "h": [5, 6, 9, 22, 43, 264, 904, 912, 926, 927, 928, 929, 930, 931, 932, 934, 935, 936, 937, 938, 939, 940, 941, 942, 946, 950], "command_opt": [5, 6], "manag": [5, 19, 23, 33, 925, 941, 944, 960], "distinguish": [5, 21, 918, 926], "right": [5, 19, 20, 100, 103, 290, 292, 833, 915, 922, 926], "recommend": [5, 6, 15, 17, 20, 21, 23, 32, 34, 39, 40, 43, 910, 911, 912, 943, 946, 948], "By": [5, 6, 21, 23, 24, 28, 32, 34, 37, 40, 78, 255, 912, 925, 926, 931, 946, 949, 950, 953], "manner": [5, 926], "ref": 5, "would": [5, 6, 14, 16, 17, 20, 21, 23, 25, 28, 32, 34, 37, 38, 39, 40, 43, 46, 908, 925, 931, 945, 946, 952, 959, 960], "paramet": [5, 6, 10, 20, 28, 35, 36, 43, 46, 48, 169, 231, 325, 327, 345, 912, 913, 916, 924, 925, 931, 935, 938, 953], "dbdefault": 5, "subtree_dn_list": 5, "sscope": 5, "search_scop": 5, "containerref": 5, "container_reference_dn": 5, "mkeytyp": [5, 6], "kv": [5, 6], "mkeyvno": [5, 6], "mkeynam": [5, 6, 10], "sf": [5, 6, 917], "stashfilenam": [5, 6], "maxtktlif": [5, 23], "max_ticket_lif": [5, 918], "max_renewable_ticket_lif": 5, "ticket_flag": [5, 832, 916], "colon": [5, 20, 21, 28, 39, 152, 346, 348, 422, 960], "scope": [5, 43], "search": [5, 20, 21, 38, 48, 151, 153, 195, 225, 317, 903, 910, 922, 925, 948, 954], "sub": [5, 21, 909], "master_key_typ": [5, 6, 14, 20, 34], "master_key_nam": [5, 6, 20], "tty": 5, "global": [5, 19, 20, 21, 22, 141, 155, 925], "document": [5, 20, 21, 29, 33, 34, 43, 902, 910, 912, 922, 925, 926, 930, 943], "add_princip": [5, 14, 23, 25, 37], "cn": [5, 20, 22, 37], "org": [5, 21, 22, 42, 910, 911, 914, 925, 926, 943, 959, 960], "server1": 5, "import": [5, 6, 14, 15, 17, 19, 21, 23, 34, 35, 925, 931, 945], "NOT": [5, 34, 926], "forget": [5, 34, 156], "verifi": [5, 20, 21, 23, 34, 37, 43, 48, 243, 358, 359, 360, 361, 362, 363, 907, 911, 925, 929, 938, 945, 946, 953], "ou": [5, 22], "searchscop": 5, "ONE": 5, "01": [5, 23, 42, 904, 931], "disallow_forward": [5, 918], "requires_pwchang": [5, 918], "ok": [5, 20, 21, 23, 24, 34, 925], "media": [5, 21], "lab": [5, 926], "complet": [5, 6, 14, 20, 21, 23, 39, 43, 45, 158, 274, 276, 361, 377, 403, 404, 744, 909, 912, 913], "usr": [5, 8, 12, 20, 21, 34, 912, 914, 924, 952, 953], "var": [5, 8, 20, 21, 23, 34, 37, 907, 912, 913, 924, 960], "service_passwd": 5, "simpl": [5, 12, 17, 23, 107, 423, 903, 907], "ldap_kdc_dn": [5, 20, 22], "ldap_kadmind_dn": [5, 20, 22], "ldap_kdc_sasl_authcid": [5, 20], "ldap_kadmind_sasl_authcid": [5, 20], "home": [5, 21, 28, 945, 953, 957, 958, 959], "andrew": 5, "conf_keyfil": 5, "policy_nam": 5, "week": 5, "60": [5, 35, 46, 904, 911], "minut": [5, 20, 21, 23, 904, 907, 945, 946, 960], "hour": [5, 19, 20, 23, 33, 904, 945, 946, 953, 960], "tmppolici": 5, "userpolici": 5, "procedur": [6, 26, 32, 34, 909, 910], "ascii": [6, 23, 39, 916], "live": [6, 15, 930], "rollov": [6, 23], "open": [6, 21, 24, 46, 48, 50, 307, 317, 319, 344, 389, 761, 777, 907, 922, 925, 926, 942, 949], "regardless": [6, 19, 21, 43], "becaus": [6, 17, 19, 20, 21, 23, 24, 25, 35, 37, 38, 39, 41, 43, 46, 253, 344, 903, 910, 912, 916, 921, 936, 938, 941, 945, 949, 959], "yet": [6, 21, 23, 26, 34, 37, 38, 903, 912, 934, 946], "corrupt": [6, 17, 925], "lock": [6, 20, 23, 24, 34, 35, 742, 743, 922, 925, 946], "stash_fil": 6, "key_stash_fil": [6, 20, 34], "alreadi": [6, 14, 22, 34, 36, 43, 124, 335, 903, 910, 912, 914, 949, 953, 955], "just": [6, 14, 15, 20, 21, 33, 34, 43, 328, 647, 903, 910, 913, 929, 946, 953, 959], "had": [6, 28, 34, 37, 945, 946, 959], "overwrit": [6, 23, 386, 948], "sector": 6, "unlink": 6, "keyfil": [6, 20, 22], "b7": 6, "r13": 6, "r18": 6, "mkey_convert": 6, "new_mkey_fil": 6, "mkey_fil": 6, "rev": [6, 24], "recurs": [6, 24, 925], "load_dump": [6, 918], "sent": [6, 20, 25, 36, 37, 41, 43, 327, 377, 383, 872, 907, 910, 917, 918, 925, 938, 946], "beta": 6, "4": [6, 9, 14, 19, 20, 21, 23, 34, 37, 39, 43, 166, 323, 407, 520, 541, 551, 606, 616, 626, 630, 638, 644, 646, 651, 687, 688, 689, 712, 914, 916, 921, 922, 925], "produc": [6, 21, 46, 104, 124, 911, 922, 929, 932, 938, 950, 952], "prior": [6, 8, 14, 20, 21, 23, 39, 41, 43, 136, 267, 926, 930], "dumpfil": [6, 23, 912], "themselv": 6, "revers": [6, 15, 21, 33, 43, 926, 950], "recov": [6, 925, 929], "walk": [6, 945], "btree": 6, "probabl": [6, 12, 14, 34, 910], "more": [6, 14, 15, 19, 20, 21, 22, 23, 25, 29, 32, 34, 35, 37, 38, 39, 41, 43, 46, 264, 281, 346, 406, 570, 744, 746, 767, 895, 903, 906, 907, 909, 912, 913, 918, 925, 932, 938, 943, 945, 960], "15": [6, 14, 20, 21, 26, 39, 43, 194, 255, 382, 383, 508, 603, 661, 694, 922, 925, 926], "restor": [6, 23, 925], "travers": 6, "hash": [6, 21, 37, 907, 917, 922, 925], "detect": [6, 8, 14, 325, 327, 328, 333, 358, 362, 907, 912, 925, 931], "appropri": [6, 14, 21, 23, 24, 28, 29, 34, 37, 39, 43, 46, 154, 375, 400, 927, 937, 938, 949, 950, 953], "known": [6, 20, 23, 26, 38, 43, 46, 48, 152, 233, 319, 653, 654, 913, 925, 958], "lose": 6, "record": [6, 10, 21, 33, 34, 38, 39, 907, 917, 918, 921, 922, 925], "what": [6, 14, 19, 20, 21, 26, 38, 43, 907, 929, 930, 938, 942, 945, 946, 952], "upon": [6, 8, 953], "preserv": [6, 926], "etyp": [6, 231, 380, 678, 925, 955], "period": [6, 8, 14, 17, 20, 21, 23, 24, 35, 946, 949], "invoc": [6, 41, 43], "step": [6, 14, 22, 23, 34, 37, 953], "readi": [6, 34], "immedi": [6, 14, 21, 23, 39, 925, 938], "earliest": [6, 153, 922], "enctyp": [6, 11, 14, 20, 21, 23, 48, 95, 97, 98, 99, 101, 104, 107, 111, 112, 116, 118, 125, 126, 192, 193, 212, 225, 282, 289, 312, 317, 380, 413, 837, 839, 852, 854, 916, 918, 921, 924, 925, 929, 955], "similar": [6, 21, 22, 26, 29, 43, 92, 105, 113, 114, 126, 129, 130, 248, 296, 297, 298, 300, 301, 328, 331, 345, 347, 351, 366, 409, 410, 419, 421, 925, 930, 940, 946, 953], "denot": [6, 19, 904, 917], "v": [6, 9, 42, 941, 949, 950], "protect": [6, 15, 25, 26, 32, 35, 37, 40, 43, 78, 249, 328, 333, 746, 853, 907, 925], "newer": [6, 14, 20, 23, 912], "dry": 6, "actual": [6, 14, 23, 26, 35, 46, 98, 99, 100, 102, 103, 113, 129, 289, 290, 291, 292, 296, 300, 907, 946], "give": [6, 14, 23, 28, 38, 910, 916, 917, 918, 926, 939, 945, 946], "pattern": [6, 21, 28, 958], "end": [6, 20, 21, 23, 24, 30, 33, 34, 39, 92, 93, 164, 334, 831, 839, 852, 890, 912, 916, 921, 922, 925, 934, 953, 960], "ask": [6, 37, 39, 46, 48, 744, 745, 746, 929, 945, 946, 949, 953], "been": [6, 12, 14, 20, 21, 23, 26, 35, 124, 903, 907, 918, 922, 925, 926, 931, 934, 946, 950, 957, 960], "taken": [6, 14, 39, 247, 907, 922], "outfil": 6, "dumptyp": 6, "select": [6, 14, 21, 23, 28, 43, 46, 48, 117, 298, 361, 371, 903, 912, 925, 931, 933, 949, 953, 958], "tabular": [6, 925], "suitabl": [6, 910, 912, 925, 926, 946], "report": [6, 38, 909, 925, 943, 949, 955], "tradit": [6, 35], "unix": [6, 15, 20, 21, 28, 31, 36, 43, 925, 930, 931, 941], "text": [6, 23, 28, 36, 37, 46, 169, 367, 833, 842, 876, 917, 952], "tool": [6, 23, 909, 911, 925, 930], "csv": [6, 925], "fix": [6, 922, 925], "column": 6, "header": [6, 21, 43, 48, 540, 543, 815, 912, 918, 927, 928, 929, 930, 932, 934, 935, 936, 937, 938, 939, 940, 941, 942], "below": [6, 20, 21, 23, 28, 36, 43, 746, 909, 918, 926, 953], "minim": [6, 14, 23, 24, 925], "unquot": 6, "unescap": 6, "hexadecim": [6, 918, 925], "numer": [6, 34, 166, 384, 385, 904, 925, 950], "symbol": [6, 346, 907, 910, 911, 914, 924, 930, 931], "stamp": [6, 9], "decim": [6, 43, 916, 918, 960], "posix": [6, 891, 902, 917, 918, 919, 922], "time_t": [6, 891, 902], "aliasnam": 6, "targetnam": 6, "target": [6, 19, 21, 34, 43, 903, 912, 916, 918, 925], "keydata": 6, "includ": [6, 9, 15, 16, 19, 20, 21, 23, 24, 26, 32, 33, 34, 37, 38, 39, 43, 48, 99, 104, 144, 289, 313, 327, 328, 332, 333, 345, 346, 361, 409, 440, 691, 819, 832, 839, 852, 866, 902, 903, 907, 909, 912, 913, 914, 916, 917, 921, 925, 926, 929, 930, 931, 935, 937, 938, 941, 945, 949, 953, 960], "keyindex": 6, "index": [6, 22, 29, 42, 371, 911, 922], "salttyp": [6, 20, 26, 376, 918], "keyinfo": [6, 26], "abov": [6, 14, 19, 21, 22, 23, 25, 26, 32, 34, 37, 41, 43, 46, 907, 912, 916, 926, 930, 931, 932, 946, 953], "exclud": [6, 17, 32, 925], "princ_flag": 6, "boolean": [6, 20, 23, 36, 48, 55, 876, 900], "posit": [6, 19, 28, 35, 891, 921], "princ_lockout": 6, "state": [6, 9, 14, 20, 34, 46, 48, 78, 99, 100, 102, 103, 289, 290, 291, 292, 853, 917, 924, 925, 926, 927, 929, 930, 932, 935, 936, 938, 939, 940, 941, 942], "repeat": [6, 20, 21, 34, 853, 916, 931], "last_success": 6, "last_fail": 6, "fail_count": 6, "princ_meta": 6, "metadata": 6, "modbi": 6, "modtim": 6, "timestamp": [6, 11, 14, 21, 25, 37, 40, 48, 66, 83, 327, 328, 333, 338, 344, 345, 358, 362, 398, 527, 534, 677, 830, 856, 860, 881, 891, 902, 906, 907, 916, 917, 918, 919, 921, 922, 925, 938, 950], "modif": [6, 9, 19, 21, 34, 918, 925, 926], "lastpwd": 6, "mkvno": 6, "hist_kvno": 6, "histori": [6, 26, 912, 925], "princ_stringattr": 6, "pair": [6, 20, 21, 26, 847], "princ_tktpolici": 6, "pw_expir": 6, "max_lif": [6, 20, 34], "max_renew_lif": 6, "txt": [6, 21, 34, 39], "cat": 6, "bar": [6, 21], "sqlite3": 6, "sqlite": 6, "quit": [6, 32], "awk": 6, "replica_host": 7, "found": [7, 10, 12, 20, 21, 23, 34, 39, 59, 60, 151, 153, 154, 195, 303, 317, 361, 912, 922, 925, 945, 946, 953, 954, 960], "replica_datatran": [7, 34, 924], "replica_dumpfil": 8, "principal_databas": 8, "kdb5_util_prog": 8, "keytab_fil": [8, 949], "made": [8, 21, 23, 34, 41, 136, 225, 255, 271, 380, 903, 925, 926, 934, 936, 954, 960], "load": [8, 14, 17, 20, 24, 34, 38, 40, 912, 931, 941], "download": [8, 926], "commonli": [8, 41], "inetd": [8, 12, 34, 41], "nowait": [8, 12, 34], "done": [8, 23, 32, 34, 39, 903, 912, 929, 938, 941, 953, 960], "stream": [8, 12, 20, 34, 36, 43], "tcp": [8, 10, 12, 15, 20, 21, 23, 29, 34, 37, 39, 281, 406, 925, 940], "root": [8, 12, 14, 15, 17, 19, 20, 21, 32, 34, 908, 912, 945, 953, 958, 959, 960], "sbin": [8, 12, 34, 912, 924], "standalon": [8, 41, 918, 925], "daemon": [8, 19, 20, 21, 23, 31, 36, 37, 38, 903, 908, 925, 930, 960], "wait": [8, 20, 23, 39, 925], "754": [8, 15, 34, 41, 924, 960], "now": [8, 14, 34, 37, 39, 237, 262, 277, 736, 925, 946], "backward": [8, 20, 21, 24, 26, 34, 955], "compat": [8, 20, 21, 36, 43, 910, 912, 925, 935, 937, 955], "noth": [8, 907], "iprop_replica_pol": [8, 20, 23], "log": [8, 9, 23, 24, 26, 28, 33, 34, 37, 39, 46, 48, 743, 903, 925, 933, 945, 946, 948, 953, 959, 960], "view": [8, 23, 34, 944], "summari": [8, 9], "replicahostnam": 8, "present": [8, 14, 16, 20, 21, 22, 23, 28, 34, 36, 37, 43, 46, 165, 247, 303, 327, 335, 338, 347, 356, 367, 368, 375, 390, 624, 717, 719, 720, 890, 906, 907, 916, 918, 921, 922, 925, 941, 946, 950, 955, 960], "replic": [8, 34], "from_mast": [8, 924], "kerberos_db": 8, "detach": 8, "job": [8, 17, 34, 39], "turn": [8, 21, 24, 33, 35, 40, 354, 363, 912, 953], "propog": 8, "impli": [8, 926], "altern": [8, 15, 20, 21, 22, 24, 28, 34, 37, 43, 505, 910, 912, 924, 925, 926, 949], "id": [8, 20, 21, 141, 149, 155, 304, 307, 318, 652, 903, 945, 953, 960], "acceptor": [8, 925, 950], "num": 9, "subsequ": [9, 10, 14, 24, 136, 277, 281, 406, 918, 926], "serial": [9, 43, 48, 407, 925], "resynchron": 9, "synchron": [9, 14, 15, 21, 24, 34, 41, 48, 273, 405, 736, 925, 938], "individu": [9, 20, 926, 946, 960], "size": [9, 20, 21, 23, 24, 37, 41, 48, 97, 98, 100, 103, 114, 116, 130, 186, 190, 290, 292, 297, 301, 363, 409, 411, 833, 912, 921, 922, 925], "424": 9, "commit": [9, 926, 936], "true": [9, 14, 20, 21, 22, 23, 24, 25, 26, 33, 35, 36, 37, 38, 40, 41, 43, 52, 54, 105, 109, 110, 127, 128, 160, 192, 247, 285, 286, 287, 302, 321, 345, 350, 351, 352, 364, 390, 418, 819, 832, 866, 959], "fri": 9, "feb": 9, "20": [9, 20, 39, 43, 91, 93, 302, 303, 346, 577, 709, 711, 747, 904, 925, 928, 946], "23": [9, 39, 596, 904, 946], "37": 9, "42": [9, 598], "2004": [9, 926], "tl": [9, 22, 29, 43, 918], "keytyp": 10, "portnum": 10, "numwork": 10, "time_offset": 10, "distribut": [10, 909, 910, 911, 912, 913, 925, 926, 946, 960], "center": [10, 909, 926, 960], "AS": [10, 21, 23, 25, 26, 255, 510, 672, 925, 926, 929, 937, 938], "udp": [10, 15, 20, 21, 29, 39, 281, 406, 925, 940], "kdcdefault": [10, 34, 37, 40], "88": [10, 15, 20, 34, 37, 39, 924], "fork": [10, 34, 953], "parallel": [10, 39, 910, 925], "top": [10, 39, 903, 910, 911, 914], "act": [10, 19, 21, 26, 907, 925], "supervisor": 10, "relai": 10, "sighup": [10, 41], "signal": 10, "worker": [10, 24], "subprocess": 10, "offset": [10, 48, 412, 916, 922], "purpos": [10, 15, 21, 23, 26, 28, 34, 912, 926, 949, 956], "32": [10, 12, 14, 24, 555, 902, 916, 917, 918, 921], "pertain": [10, 926], "supersed": [10, 14], "definit": [10, 16, 20, 909, 926, 935, 937], "2001": 10, "realm1": 10, "2002": [10, 926, 960], "realm2": 10, "realm3": 10, "addition": [10, 21, 36, 937, 946], "krb5_kdc_profil": [10, 20, 34, 924, 925, 960], "take": [10, 14, 19, 20, 21, 23, 25, 26, 28, 32, 39, 41, 43, 46, 91, 124, 126, 327, 378, 737, 833, 904, 922, 925, 927, 936, 945, 946, 953], "preced": [10, 14, 21, 39, 921, 953, 960], "further": [10, 34, 907, 959], "detail": [10, 14, 15, 22, 24, 26, 28, 33, 34, 36, 264, 744, 903, 909, 911, 925, 927, 928, 929, 932, 935, 936, 937, 938, 939, 940, 941, 942, 953], "kdc_listen": [10, 20, 34], "v4": [11, 14, 21, 48], "srvtab": 11, "longer": [11, 19, 23, 25, 33, 39, 43, 49, 65, 67, 68, 72, 73, 76, 77, 78, 91, 92, 93, 111, 113, 115, 120, 122, 123, 125, 126, 132, 141, 143, 145, 150, 153, 154, 163, 164, 169, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 194, 195, 225, 228, 229, 231, 232, 233, 238, 263, 267, 270, 274, 277, 282, 284, 288, 296, 312, 317, 319, 320, 323, 324, 326, 327, 328, 329, 330, 331, 332, 333, 334, 337, 340, 341, 346, 347, 356, 357, 358, 359, 361, 362, 365, 377, 391, 403, 405, 407, 408, 410, 912, 918, 925, 946, 949], "keylist": [11, 15], "l": [11, 19, 903, 904, 912, 946, 949, 950, 952, 953], "rkt": 11, "wkt": 11, "slot": [11, 21, 302, 922], "delent": 11, "omit": [11, 22, 28, 39, 410, 722, 723, 916, 918, 921, 941], "addent": [11, 925], "alic": [11, 23, 28, 958, 959], "server_port": 12, "sclient": [12, 944, 947], "demonstr": [12, 14], "good": [12, 15, 23, 34, 926, 945, 946, 960], "instal": [12, 14, 15, 17, 21, 28, 30, 32, 39, 908, 911, 914, 934, 948, 952], "sampl": [12, 15, 22, 34, 909, 926, 945, 946, 953, 956], "henc": 12, "domain": [12, 15, 20, 21, 33, 34, 36, 37, 38, 39, 925, 946], "13135": 12, "someth": [12, 14, 20, 38, 907], "sendauth": [12, 34, 48], "succeed": [12, 34], "repli": [12, 26, 46, 107, 247, 260, 269, 281, 354, 359, 360, 382, 383, 406, 736, 851, 871, 872, 876, 917, 925, 929, 938, 949], "len": [12, 118, 339, 341, 918], "nlgilman": 12, "jimi": 12, "didn": [12, 28], "unknown": [12, 38, 41, 622, 916, 955], "check": [12, 20, 21, 23, 26, 28, 34, 37, 43, 48, 59, 60, 153, 285, 358, 361, 362, 555, 910, 912, 914, 921, 930, 941, 942, 946, 950, 953], "don": [12, 718, 721, 903, 910, 912, 945, 953, 960], "refus": [12, 14, 34], "correctli": [12, 43, 871, 872, 902, 925, 945], "restart": [12, 14, 19, 20, 23, 24, 34, 37, 41], "reject": [12, 15, 16, 20, 21, 34, 166, 626, 946], "couldn": 12, "find": [12, 21, 23, 38, 39, 43, 48, 50, 916, 922, 925, 927, 945, 946, 949, 953], "proper": [12, 23, 37, 361, 910], "retir": [13, 23, 925], "de": [13, 20, 26, 41, 472, 925, 926], "block": [14, 20, 24, 48, 99, 100, 102, 103, 289, 290, 291, 292, 925], "cipher": [14, 26, 48, 99, 100, 102, 103, 289, 290, 291, 292], "advanc": [14, 30, 150, 316, 925, 943], "comput": [14, 20, 21, 29, 43, 44, 46, 48, 91, 117, 129, 231, 298, 300, 919, 926, 929, 938, 945, 946], "abil": [14, 370, 373, 959], "render": [14, 910], "vulner": [14, 23, 32, 46, 925, 943], "brute": [14, 23, 35], "56": [14, 585], "bit": [14, 20, 24, 37, 46, 66, 83, 142, 153, 157, 361, 891, 902, 916, 917, 918, 921, 925, 928, 953], "keyspac": 14, "insecur": [14, 32, 39, 43, 232], "rfc": [14, 20, 21, 39, 43, 48, 322, 384, 385, 414, 447, 448, 451, 452, 453, 455, 456, 463, 464, 465, 466, 467, 468, 469, 470, 471, 516, 545, 547, 606, 670, 673, 674, 675, 676, 677, 678, 679, 681, 682, 683, 684, 686, 687, 688, 689, 692, 693, 695, 697, 704, 707, 709, 711, 744, 907, 916, 917, 918, 919, 922, 925, 929, 931], "6649": 14, "cryptosystem": 14, "partial": [14, 19, 23, 46, 922], "tripl": [14, 20, 26, 925], "3de": 14, "gain": [14, 25, 34, 935, 937, 946], "deploy": [14, 24, 37], "older": [14, 23, 918, 925, 938], "necessarili": 14, "crypto": [14, 121, 191, 909, 912, 925, 926], "ordinari": [14, 910, 925, 960], "intervent": [14, 26], "began": 14, "deprec": [14, 20, 26, 70, 75, 94, 120, 122, 123, 131, 168, 186, 188, 190, 191, 196, 197, 226, 227, 234, 235, 236, 241, 283, 311, 342, 343, 353, 355, 395, 413, 415, 925], "18": [14, 21, 26, 38, 43, 267, 338, 601, 666, 907, 922, 925, 931, 946, 960], "consequ": 14, "migrat": [14, 23, 41, 925], "materi": [14, 46, 925, 926, 930], "frequent": [14, 33, 38, 39, 891, 945], "variou": [14, 30, 43, 361, 909, 913, 925, 946], "string2kei": 14, "convei": [14, 23, 39, 43, 843, 869, 925, 926], "These": [14, 16, 20, 21, 23, 26, 34, 35, 37, 39, 43, 739, 910, 916, 918, 925, 926, 929, 931, 934, 958, 960], "short": [14, 19, 21, 41, 308, 906], "how": [14, 20, 21, 23, 26, 28, 32, 34, 37, 39, 43, 225, 418, 911, 912, 923, 927, 933, 940, 941, 945, 949], "see": [14, 15, 17, 22, 23, 24, 26, 28, 32, 34, 35, 36, 39, 43, 46, 97, 99, 100, 102, 103, 108, 113, 114, 130, 131, 168, 184, 189, 231, 264, 289, 290, 291, 292, 296, 297, 301, 322, 331, 332, 361, 377, 395, 405, 414, 415, 416, 606, 744, 833, 903, 904, 907, 908, 909, 910, 912, 914, 915, 916, 918, 925, 926, 927, 928, 929, 930, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 945, 946], "uninterrupt": 14, "awai": [14, 41, 945, 946], "ensur": [14, 15, 17, 20, 23, 24, 25, 26, 34, 37, 46, 171, 871, 872, 932, 939, 946], "assum": [14, 21, 26, 34, 36, 39, 43, 44, 107, 124, 155, 911, 925, 946, 949, 960], "softwar": [14, 15, 21, 24, 25, 28, 42, 46, 912, 926, 943], "modern": [14, 15, 23, 38, 925], "task": [14, 46, 91], "zone": [14, 39, 904], "worst": 14, "scenario": [14, 925], "veri": [14, 20, 21, 23, 941], "supported_enctyp": [14, 20, 26, 34, 925], "crc": [14, 26], "norealm": [14, 20], "onlyrealm": [14, 20], "afs3": 14, "were": [14, 15, 21, 34, 43, 416, 624, 903, 925, 926, 946], "high": [14, 16, 24], "casio": 14, "appear": [14, 20, 21, 24, 34, 37, 39, 41, 46, 916, 918, 926, 930], "creation": [14, 21, 23, 37, 917], "three": [14, 24, 26, 35, 39, 40, 377, 916, 925, 946, 960], "biggest": 14, "cell": 14, "strengthen": 14, "compromis": [14, 17, 21, 32, 903, 908], "easi": [14, 17, 25, 35, 946], "guarante": 14, "might": [14, 17, 23, 28, 29, 34, 35, 38, 39, 43, 910, 912, 916, 926, 930, 945, 960], "invalid": [14, 21, 23, 50, 136, 139, 156, 262, 303, 317, 338, 946, 949, 950], "useless": 14, "schedul": [14, 23], "expiri": [14, 247, 925], "potenti": [14, 32, 34, 46, 908], "rollback": 14, "explicit": [14, 19, 21, 22, 24, 28, 39, 926], "easili": [14, 34, 910, 925], "enumer": [14, 26], "visibl": [14, 23, 25, 925], "disrupt": 14, "due": [14, 19, 23, 41], "expect": [14, 21, 34, 41, 269, 303, 344, 345, 736, 914, 929, 934, 946], "rekei": 14, "minor": [14, 43, 911, 925, 930, 931, 940], "regular": [14, 21, 34, 37, 43, 953], "kerber": [14, 33, 34, 953], "algorithm": [14, 26, 126, 922, 925, 926, 953], "particularli": [14, 17, 25, 39, 945, 952], "channel": [14, 21, 36, 46, 327, 925, 953], "part": [14, 21, 23, 26, 32, 41, 199, 266, 269, 280, 285, 303, 346, 361, 386, 829, 839, 851, 889, 903, 908, 916, 917, 922, 926, 930, 931, 941, 953, 960], "daili": 14, "workflow": 14, "furthermor": [14, 247, 926], "inop": 14, "Such": [14, 37, 39, 46], "problem": [14, 23, 332, 907, 925, 943], "earli": 14, "stage": [14, 917, 936], "switch": [14, 28, 31, 43, 48, 161, 903], "desir": [14, 15, 23, 28, 43, 119, 121, 252, 253, 331, 912, 925, 940, 953], "hand": [14, 34], "flip": 14, "zephyr": [14, 926], "ktadd": [14, 15, 23, 32, 34, 906], "wrfile": [14, 23], "Be": 14, "best": [14, 25, 34, 38], "practic": [14, 21, 46, 99, 289, 925], "subcommand": 14, "reason": [14, 17, 21, 24, 28, 33, 39, 344, 902, 916, 926, 945, 946, 953], "effect": [14, 19, 20, 21, 23, 37, 39, 737, 903, 907], "At": [14, 23, 33, 34, 165, 916], "behind": [14, 28], "advantag": [14, 21, 26, 32], "cryptographi": [14, 40], "dr": 14, "willi": 14, "xvm": 14, "256": [14, 20, 21, 40, 922, 925], "sha": [14, 20, 925], "klist": [14, 15, 33, 903, 906, 944, 947, 948, 949, 953, 954, 960], "03": [14, 35, 946], "59": [14, 904], "31": [14, 706, 904, 946], "19": [14, 20, 21, 26, 43, 203, 210, 576, 663, 679, 925, 928, 946, 955], "backend": [14, 912, 925, 926], "balanc": [14, 38, 39], "environ": [14, 15, 20, 21, 23, 24, 26, 28, 30, 34, 35, 37, 38, 41, 43, 56, 136, 228, 270, 271, 284, 388, 389, 903, 906, 907, 910, 918, 924, 925], "downtim": 14, "adjust": [14, 29, 33, 34, 37, 48, 100, 103, 290, 292, 412], "popul": [14, 24, 44, 148, 922], "pool": 14, "interrupt": [14, 262, 926], "situat": [14, 20, 24, 28, 39, 955], "transitori": 14, "progress": [14, 20], "pose": 14, "allow_weak_crypto": [14, 21, 26, 41, 48], "onlin": [14, 25], "much": [14, 25, 38, 153, 945], "slower": [14, 24], "offlin": [14, 25, 949], "alwai": [14, 15, 20, 21, 23, 24, 39, 44, 51, 55, 61, 63, 66, 68, 71, 80, 83, 139, 142, 155, 367, 722, 916, 918, 921, 925], "advis": [14, 926], "unpleas": 14, "surpris": 14, "promot": [14, 926], "pass": [14, 20, 21, 28, 36, 43, 99, 100, 102, 103, 230, 252, 272, 273, 277, 281, 282, 284, 289, 290, 291, 292, 327, 370, 373, 382, 383, 384, 388, 389, 895, 912, 925, 931, 940, 949, 953], "purgekei": [14, 23, 37], "vnder": 14, "pressvr": 14, "zonetest": 14, "again": [14, 21, 28, 33, 34, 726, 907, 925, 931, 945, 946], "9": [14, 19, 20, 21, 26, 35, 41, 87, 89, 192, 247, 248, 388, 389, 401, 402, 403, 404, 405, 406, 519, 545, 615, 911, 925], "kaduk": 14, "glossolalia": 14, "fals": [14, 20, 21, 23, 26, 28, 33, 36, 37, 38, 39, 43, 52, 54, 105, 109, 110, 127, 128, 160, 192, 247, 285, 286, 287, 321, 350, 351, 352, 364, 390, 418, 959], "even": [14, 20, 21, 23, 25, 28, 34, 38, 39, 43, 247, 390, 902, 904, 907, 925, 926, 949, 953], "af": 14, "though": [14, 910, 946], "call": [14, 16, 20, 21, 23, 24, 28, 34, 43, 46, 91, 93, 100, 103, 113, 120, 122, 123, 125, 126, 136, 156, 158, 176, 230, 247, 253, 263, 270, 277, 281, 284, 290, 292, 296, 303, 310, 319, 325, 382, 383, 406, 833, 876, 883, 902, 903, 909, 910, 925, 929, 930, 931, 936, 938, 939, 945, 953], "weak": [14, 20, 21, 26, 41], "basi": [14, 18, 23, 39], "reduc": [14, 21, 33, 100, 103, 290, 292, 912], "outreach": 14, "elimin": [14, 40], "choos": [14, 22, 25, 34, 38, 39, 43, 908, 927, 945, 949, 958], "timeout": [14, 20, 21, 36, 925], "helpdesk": 14, "alter": [14, 37], "risk": [14, 23, 26, 30, 46], "tightli": [14, 28, 32, 908], "well": [14, 21, 23, 34, 38, 39, 43, 46, 345, 654, 909, 912, 925, 932], "broken": [14, 912], "cryptograph": [14, 43, 925, 926], "stronger": [14, 16, 21, 26], "unlik": [14, 23, 40, 903, 907, 925, 931, 946], "prioriti": [14, 20, 39, 232, 903, 907, 927], "add_mkei": [14, 23], "use_mkei": [14, 23], "update_princ_encrypt": [14, 23], "convert": [14, 21, 38, 43, 48, 169, 260, 391, 918, 925, 958], "guid": [15, 30, 32, 933], "also": [15, 17, 18, 22, 23, 24, 25, 26, 28, 29, 32, 33, 34, 35, 37, 38, 39, 40, 43, 46, 126, 344, 405, 902, 903, 906, 912, 914, 916, 918, 925, 926, 928, 929, 931, 932, 934, 935, 937, 939, 941, 942, 946], "copi": [15, 17, 23, 26, 29, 32, 34, 37, 41, 43, 48, 86, 88, 271, 274, 344, 403, 908, 916, 918, 925, 926, 934, 941, 946, 953], "analog": 15, "equal": [15, 24, 921, 925, 953], "readabl": [15, 21, 32, 169, 904, 906, 908, 925], "ideal": [15, 23, 34, 46, 910], "resid": [15, 39, 46, 908, 918, 926, 958, 959], "daffodil": [15, 946], "ktremov": 15, "anoth": [15, 17, 21, 24, 32, 41, 48, 101, 171, 832, 903, 907, 912, 916, 928, 929, 935, 939, 940, 946, 960], "togeth": 15, "gssapi": [15, 16, 20, 21, 45, 902, 903, 906, 907, 909, 925, 926, 927, 933, 952, 960], "krb5_client_ktnam": [15, 906, 924, 960], "default_client_keytab_nam": [15, 21, 906], "profil": [15, 18, 20, 21, 48, 136, 390, 903, 906, 907, 909, 913, 925, 926, 933], "libdefault": [15, 20, 26, 28, 33, 34, 38, 39, 40, 41, 43, 44, 903, 906, 907, 925, 941], "krb5ccname": [15, 136, 903, 948, 949, 950, 953, 960], "writabl": [15, 34, 318, 941], "besid": [15, 21], "conflict": [15, 28, 361, 931], "memori": [15, 41, 43, 48, 93, 142, 224, 233, 304, 325, 327, 328, 333, 358, 359, 362, 416, 833, 903, 906, 912, 925, 930, 932, 939], "refresh": [15, 43, 916, 925], "especi": [15, 26, 34, 38, 925], "virtual": [15, 21], "tend": 15, "drift": 15, "rapidli": 15, "clockskew": [15, 21, 361, 922, 941, 949], "aspect": [15, 28, 934], "reli": [15, 34], "canonic": [15, 21, 22, 33, 43, 48, 303, 391, 551, 925, 949, 955], "possibli": [15, 21, 25, 37, 43, 48, 746, 912, 925, 929, 938], "resolut": [15, 33, 38, 43, 232, 925, 953], "ip": [15, 20, 39, 925], "resolv": [15, 33, 48, 262, 319, 903, 912, 925, 950, 953], "vari": [15, 33, 911, 924, 948, 949], "On": [15, 20, 21, 23, 34, 37, 41, 43, 100, 103, 144, 273, 281, 290, 292, 332, 361, 363, 402, 406, 409, 410, 411, 907, 910, 924, 925, 938, 946, 949], "127": 15, "localhost": 15, "trillium": [15, 32, 946], "wake": 15, "robin": 15, "viola": 15, "ssh": [15, 33, 946, 959, 960], "off": [15, 21, 24, 25, 28, 33, 35, 39, 354, 363], "site": [15, 21, 23, 34, 39, 925, 946, 949, 959], "abl": [15, 16, 19, 20, 21, 23, 25, 29, 34, 35, 39, 903, 908, 945, 946, 953], "either": [15, 20, 21, 22, 23, 25, 26, 34, 35, 36, 37, 41, 43, 44, 195, 247, 255, 276, 327, 328, 329, 333, 404, 405, 409, 737, 872, 903, 910, 918, 922, 926, 930, 935, 939, 946, 953, 959], "outsid": [15, 903, 960], "least": [15, 23, 32, 34, 39, 99, 102, 153, 165, 289, 291, 409, 741, 758, 918, 921, 935, 939], "whichev": 15, "similarli": [15, 346, 746, 946], "464": [15, 20, 21, 39, 924], "749": [15, 20, 34, 39, 924], "insid": [15, 26, 195, 917, 925], "outgo": [15, 931], "through": [15, 16, 20, 21, 22, 23, 24, 28, 29, 33, 34, 35, 39, 46, 232, 284, 388, 389, 418, 916, 918, 922, 925, 936, 945, 946], "krb5_prop": [15, 34, 41], "book": 15, "david": [15, 945, 946, 960], "curri": 15, "learn": 15, "annot": [16, 23, 36, 925], "chosen": [16, 21, 22, 26, 43, 46, 231, 911, 917, 924, 925, 927, 958], "pkinit_ind": [16, 20], "token": [16, 20, 21, 46, 370, 604, 735, 736, 737, 739, 742, 743, 920, 925, 931, 938, 949], "wish": [16, 21, 34, 39, 43, 252, 910, 911, 912, 913, 926, 931, 942, 945, 946, 960], "strong": [16, 122], "subsect": [16, 20, 21, 22, 24, 25, 28, 29, 35, 37, 40], "krbtest": [16, 23, 35, 41, 917, 919, 958], "x509_user_ident": [16, 21, 949], "my": 16, "cert": [16, 21, 37], "pem": [16, 21, 29, 37, 955], "inspect": [16, 382, 383, 871, 872, 928, 935, 937], "auth": [16, 20, 39, 43, 48, 61, 331, 332, 361, 365, 366, 377, 509, 817, 831, 839], "someon": [17, 21, 34, 945, 946], "person": [17, 34, 926, 945, 946], "masquerad": [17, 945, 946], "danger": [17, 953], "crash": [17, 21, 34], "lost": [17, 910, 926], "unabl": [17, 21, 23], "notic": [17, 24, 926], "regularli": [17, 39], "matter": [17, 21], "cron": [17, 20, 34, 39], "elsewher": 17, "Of": [17, 35], "cours": 17, "transmiss": 17, "across": [17, 20, 21, 34, 43, 935, 936, 937, 945], "onto": [17, 21, 32, 34, 912, 931, 946], "kerboro": 18, "merg": [18, 20, 48, 926], "sharp": 19, "target_princip": 19, "actor": 19, "compon": [19, 21, 28, 37, 38, 43, 46, 48, 92, 93, 224, 346, 347, 352, 390, 651, 714, 716, 769, 916, 921, 925, 926, 941, 946, 958], "wildcard": [19, 20, 925, 958], "counterpart": [19, 33], "disallow": 19, "di": 19, "inquiri": 19, "admcilsp": 19, "great": [19, 153, 269, 758], "disclosur": [19, 925], "back": [19, 20, 23, 24, 30, 39, 40, 903, 912, 917, 925, 931, 934], "flagnam": 19, "default_principal_flag": [19, 20, 925], "joeadmin": [19, 23, 32, 959], "admcil": 19, "ci": 19, "sm": 19, "9h": 19, "instanc": [19, 21, 23, 28, 33, 35, 43, 49, 50, 649, 650, 907, 916, 925, 930, 960], "hi": [19, 23, 946, 953, 959], "he": [19, 23, 945, 946, 959], "null": [19, 20, 21, 43, 44, 46, 48, 54, 64, 92, 99, 100, 102, 103, 107, 113, 129, 136, 141, 154, 155, 156, 164, 173, 195, 198, 200, 203, 210, 221, 224, 225, 228, 230, 232, 233, 237, 242, 262, 266, 269, 271, 275, 277, 289, 290, 291, 292, 296, 300, 302, 303, 317, 324, 325, 327, 328, 331, 332, 333, 334, 338, 344, 345, 346, 356, 358, 361, 362, 363, 365, 366, 367, 368, 371, 374, 377, 379, 382, 383, 384, 385, 388, 390, 391, 399, 409, 410, 411, 414, 416, 799, 925, 930, 939, 941, 960], "extra": [19, 39, 40, 772, 911], "dbadmin": 19, "final": [19, 21, 112, 158, 910, 917, 922], "coexist": 19, "kadm5_auth": [19, 925, 933], "authorit": [19, 21, 154, 927, 932, 935, 939, 940], "supplement": 20, "mention": [20, 22, 926], "tag": [20, 21, 34, 916, 922, 931], "host_based_servic": [20, 39], "kdc_port": 20, "kdc_tcp_listen": [20, 34, 37], "kdc_tcp_port": 20, "no_host_referr": [20, 39], "restrict_anonymous_to_tgt": [20, 37], "kdc_max_dgram_reply_s": 20, "packet": [20, 25, 36, 332, 925, 938], "4096": [20, 21, 922], "byte": [20, 43, 46, 48, 99, 104, 289, 313, 916, 917, 918, 919, 921, 922, 931], "kdc_tcp_listen_backlog": 20, "queue": [20, 926], "limit": [20, 23, 24, 25, 34, 39, 43, 925, 926, 953, 960], "spake_preauth_kdc_challeng": [20, 40], "group": [20, 21, 40, 917, 926], "spake": [20, 21, 25, 30, 925, 926], "optimist": [20, 40, 48, 256], "challeng": [20, 21, 40, 46, 48, 368, 369, 370, 372, 373, 703, 706, 744, 745, 882, 885, 917, 925], "spake_preauth_group": [20, 21, 40], "max_renewable_lif": [20, 34, 918], "7d": [20, 34], "0h": [20, 34, 904], "0m": [20, 34, 904], "database_modul": [20, 24], "loadabl": [20, 21, 931], "database_nam": [20, 23, 34], "default_principal_expir": [20, 904], "absolut": [20, 21, 902, 906, 910], "dup": 20, "skei": [20, 832], "There": [20, 21, 23, 34, 35, 903, 910, 912, 913, 916, 921, 946], "essenti": 20, "deactiv": 20, "hwauth": 20, "s4uself": 20, "preauth": [20, 678, 847, 916, 925, 926, 929, 938], "proxi": [20, 21, 25, 30, 36, 39, 43, 925, 946, 950], "pwchang": 20, "pwservic": 20, "special": [20, 23, 28, 35, 43, 410, 654, 721, 903, 925, 926, 931, 949], "go": [20, 24, 946, 953], "dictionari": [20, 21, 23, 29, 30, 34, 35, 40, 925, 942, 949], "disable_pac": [20, 925], "s4u2self": [20, 43, 345, 925, 955], "s4u2proxi": [20, 43, 916, 925], "encrypted_challenge_ind": [20, 925], "assert": [20, 43, 916, 925, 931, 938], "fast": [20, 21, 25, 36, 37, 48, 231, 549, 605, 916, 925, 929, 938], "referr": [20, 21, 39, 232, 233, 345, 391, 700, 709, 733, 916, 918, 925, 932, 946], "iprop_ulogs": 20, "1000": [20, 23], "2500": [20, 23], "iprop_master_ulogs": [20, 23], "Its": [20, 21, 916], "delta": [20, 48], "often": [20, 22, 23, 28, 33, 38, 39, 906, 934, 960], "2m": 20, "iprop_slave_pol": 20, "iprop_listen": 20, "rpc": [20, 21, 23, 43, 48, 622, 909, 925, 926], "enclos": [20, 21, 904], "squar": [20, 21, 28], "bracket": [20, 21, 28], "iprop_port": [20, 23], "iprop_resync_timeout": [20, 23], "amount": [20, 21, 35, 39, 102, 119, 121, 291, 363, 911], "5m": 20, "iprop_logfil": [20, 23], "config": [20, 21, 23, 141, 155, 271, 380, 909, 912, 924, 925, 931, 944, 947], "ulog": [20, 23], "isn": [20, 23, 335, 907, 910, 926], "hard": [20, 23], "k5": [20, 34, 924, 926], "syntax": [20, 21, 37, 925], "kpasswd_port": 20, "valid": [20, 21, 23, 39, 43, 48, 66, 83, 109, 124, 129, 153, 160, 225, 237, 250, 262, 271, 277, 300, 303, 332, 335, 344, 345, 347, 352, 361, 367, 368, 410, 416, 890, 903, 904, 909, 916, 921, 925, 937, 946, 949, 955, 959, 960], "24": [20, 46, 597, 946], "altogeth": 20, "reject_bad_transit": 20, "transit": [20, 21, 24, 361, 546, 555, 680, 701, 839, 896, 946, 949, 950, 955], "capath": 20, "anywai": [20, 39, 46, 332], "left": [20, 21, 282, 919, 930], "incom": [20, 38, 931], "armor": [20, 37, 48, 231, 929, 938, 949], "spake_preauth_ind": 20, "ldap_kerberos_container_dn": [20, 22], "ldap_kdc_sasl_authzid": 20, "ldap_kdc_sasl_mech": [20, 22], "ldap_kdc_sasl_realm": 20, "ldap_kadmind_sasl_authzid": 20, "ldap_kadmind_sasl_mech": 20, "ldap_kadmind_sasl_realm": 20, "ldap_service_password_fil": [20, 22], "ldap_conns_per_serv": 20, "disable_last_success": [20, 22, 35], "filesystem": [20, 23, 34, 37, 922, 924], "db_librari": [20, 22, 24], "klmdb": 20, "lmdb": [20, 23, 24, 912, 925], "kldap": [20, 22], "disable_lockout": [20, 22, 35], "account": [20, 21, 24, 25, 28, 30, 48, 56, 247, 338, 903, 918, 925, 939, 944, 949, 953, 957, 959], "extern": [20, 22, 43, 916], "Not": [20, 21, 44, 51, 151, 620, 903], "digest": [20, 926], "circumst": [20, 37], "ldap_serv": [20, 22], "ldapi": [20, 22, 24], "url": [20, 24, 29, 39], "mapsiz": [20, 24], "megabyt": [20, 24, 911], "increas": [20, 24, 40, 100, 103, 290, 292, 933], "reach": [20, 21, 24, 164, 316, 922], "max_read": [20, 24], "concurr": [20, 24], "nosync": [20, 24], "throughput": [20, 24], "agent": 20, "expens": [20, 25, 35], "durabl": [20, 24], "surviv": [20, 903], "power": [20, 24, 25, 39, 925], "outag": [20, 39], "sudden": 20, "reboot": [20, 34, 908], "extend": [20, 21, 37, 48, 422, 895, 931, 960], "larg": [20, 23, 24, 34, 36, 39, 46, 100, 103, 119, 290, 292, 910, 925], "db_module_dir": 20, "absenc": [20, 46], "syslog": [20, 21, 34, 930], "filter": [20, 21], "overwritten": [20, 833], "stderr": [20, 960], "consol": 20, "devicenam": 20, "minu": [20, 922], "log_": 20, "prefix": [20, 39, 48, 346, 910, 912, 925, 931, 952, 953], "kern": 20, "mail": [20, 903, 946, 953, 958], "lpr": 20, "uucp": 20, "local0": 20, "local7": 20, "log_daemon": 20, "adm": [20, 22, 39], "dev": [20, 21, 41, 960], "tty04": 20, "info": [20, 34, 231, 658, 660, 669, 678, 832, 838, 894, 925], "radiu": [20, 36, 925], "rel": [20, 21, 48, 904, 910, 916, 953], "lead": [20, 953], "trail": [20, 38, 953], "total": [20, 21, 25, 922, 925, 949, 953], "retri": [20, 36, 38, 39], "tri": [20, 21, 25, 44, 361, 416, 925, 932], "strip_realm": [20, 36], "myremotetokentyp": 20, "mydomain": 20, "1812": 20, "semfiajf42": 20, "implicit": 20, "shown": [20, 21, 903], "ride": 20, "crt": [20, 21], "dir": [20, 21, 37, 903, 912, 924, 949, 960], "generic_trusted_ca": [20, 21], "trust": [20, 21, 29, 37, 43, 270, 949], "anchor": [20, 21, 949], "pkinit_dh_min_bit": [20, 21], "strength": [20, 925], "diffi": [20, 21], "hellman": [20, 21], "willing": [20, 21, 26], "exchang": [20, 34, 40, 43, 48, 225, 249, 281, 365, 377, 442, 883, 917, 925, 938], "1024": [20, 21, 43], "2048": [20, 21, 37, 922], "384": [20, 21, 40], "521": [20, 21, 40], "pkinit_allow_upn": [20, 21], "microsoft": [20, 21, 26, 29, 42, 43, 384, 457, 925, 931], "userprincipalnam": 20, "upn": [20, 21, 352, 643, 645, 713, 925], "san": [20, 21, 925], "4556": [20, 21, 693, 695, 925], "pkinit_eku_check": [20, 21, 37], "usag": [20, 21, 37, 43, 99, 100, 102, 103, 108, 113, 114, 129, 130, 289, 290, 291, 292, 296, 297, 300, 301, 853, 902, 917, 919, 952, 953], "eku": [20, 21], "kpclientauth": 20, "sclogin": 20, "smart": [20, 21, 925], "login": [20, 21, 33, 38, 41, 46, 946, 953, 960], "kp": [20, 21], "sc": 20, "logon": [20, 335, 664, 925], "pkinit_ident": [20, 21, 37], "509": [20, 21, 37, 43, 925, 928, 955], "pkinit_pool": [20, 21], "intermedi": [20, 21, 23, 43, 225, 916, 917, 925, 946], "pkinit_revok": [20, 21], "revoc": [20, 21], "crl": [20, 21], "pkinit_require_crl_check": [20, 21], "verif": [20, 21, 34, 43, 46, 48, 416, 903, 944, 946], "revok": [20, 21, 35], "ca": [20, 21, 29, 37], "succe": [20, 21, 34, 43, 46, 416], "everi": [20, 21, 23, 32, 34, 48, 320, 903], "pkinit_require_fresh": [20, 37], "raw": [20, 910], "kd": 20, "rc4": [20, 26, 925], "export": [20, 34, 925, 926, 930, 931, 940, 941], "camellia": [20, 925], "famili": [20, 186, 188, 190, 191, 196, 197, 252, 253, 283, 353, 355, 413, 940], "plu": [20, 918, 946, 953], "symmetri": 20, "move": [20, 27, 34, 48], "front": [20, 346], "our": [20, 36, 909, 910, 926], "earlier": [20, 23, 26, 34, 225, 939], "member": 20, "peopl": 20, "pick": [20, 25, 37, 910], "12h": [20, 34], "openldap_ldapconf": 20, "krbcontain": [20, 22], "dc": [20, 22], "krbadmin": [20, 22], "interest": [21, 35, 907, 913], "map": [21, 28, 33, 34, 43, 912, 925, 931, 932, 939, 953, 958], "krb5_config": [21, 34, 924, 925, 960], "consist": [21, 39, 346, 906, 911, 916, 925, 932, 939], "sole": [21, 28], "alphanumer": 21, "dash": 21, "underscor": [21, 926], "window": [21, 26, 28, 29, 42, 303, 384, 385, 643, 645, 691, 709, 903, 907, 909, 922, 925, 930, 931, 941, 946], "ini": 21, "head": 21, "fubar": [21, 960], "baz": 21, "quux": 21, "direct": [21, 22, 23, 28, 41, 48, 926, 931, 941, 960], "includedir": [21, 912], "dirnam": [21, 903], "syntact": 21, "independ": [21, 26, 138, 163, 247, 309, 912], "parent": [21, 39, 903, 924], "close": [21, 32, 48, 71, 85, 132, 137, 138, 148, 164, 167, 267, 303, 309, 761, 922, 936, 942], "brace": [21, 930], "modulepath": 21, "residu": [21, 39, 152, 319, 903, 907, 939, 941, 960], "registr": 21, "allow_des3": [21, 26, 925], "futur": [21, 23, 26, 37, 43, 156, 230, 895, 925, 932], "21": [21, 26, 43, 575, 578, 704, 724, 925, 946], "allow_rc4": [21, 26, 925], "default_tgs_enctyp": [21, 26], "default_tkt_enctyp": [21, 26], "permitted_enctyp": [21, 26], "answer": [21, 46, 48, 368, 737, 744, 746, 882, 931], "ccache_typ": 21, "smaller": [21, 921], "toler": 21, "300": [21, 23], "evalu": 21, "shorter": 21, "default_ccache_nam": [21, 136, 903, 960], "default_keytab_nam": [21, 906, 913], "sshd": 21, "default_rcache_nam": [21, 907], "replai": [21, 43, 48, 78, 325, 327, 328, 333, 356, 358, 361, 362, 526, 527, 881, 903, 905, 913, 920, 924, 925, 960], "dfl": [21, 907, 960], "default_realm": [21, 28, 33, 34, 932, 941], "req": [21, 26, 37, 247, 331, 332, 361, 509, 852, 918], "lowest": [21, 918], "delimit": [21, 313], "upgrad": [21, 23, 26, 34, 39, 925], "dns_canonicalize_hostnam": [21, 38, 925], "lookup": [21, 22, 33, 38, 39, 194, 821, 912, 918, 925, 940], "relianc": 21, "dns_lookup_kdc": 21, "srv": [21, 33, 34, 39, 925], "incomplet": 21, "denial": 21, "spoof": [21, 25, 39], "redirect": [21, 34], "wors": 21, "fake": [21, 46], "decod": [21, 46, 48, 159, 184, 361, 916, 928, 930], "anyth": [21, 37], "won": [21, 37, 946], "know": [21, 33, 35, 37, 907, 912, 931, 946], "dns_lookup_realm": [21, 39], "dns_uri_lookup": [21, 39], "enforce_ok_as_deleg": [21, 925], "enforc": [21, 43, 925], "err_fmt": [21, 925], "custom": [21, 914, 918, 924, 925, 928], "substitut": [21, 34, 37, 926], "extra_address": 21, "nat": [21, 23, 925], "noaddress": 21, "ignore_acceptor_hostnam": [21, 38, 43], "context": [21, 41, 43, 44, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 60, 61, 66, 70, 75, 83, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 186, 188, 189, 190, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 247, 248, 249, 250, 252, 253, 254, 255, 259, 262, 263, 266, 267, 269, 278, 279, 280, 281, 282, 283, 285, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 369, 370, 371, 372, 373, 374, 377, 378, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 395, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 419, 420, 421, 422, 569, 799, 800, 801, 802, 803, 804, 805, 806, 844, 871, 872, 878, 882, 894, 925, 927, 929, 930, 932, 938, 939, 940], "flexibl": [21, 38], "multihom": 21, "k5login_authorit": [21, 28, 959], "k5login": [21, 28, 944, 945, 953, 957], "k5login_directori": [21, 28], "kcm_mach_servic": 21, "maco": [21, 344, 903, 909, 925, 926], "bootstrap": 21, "kcm": [21, 323, 407, 903, 925, 926, 960], "mach": [21, 926], "h5l": [21, 44], "kcm_socket": 21, "heim_org": 21, "kdc_default_opt": 21, "xore": [21, 361], "0x00000010": [21, 501, 532, 754], "kdc_opt_renewable_ok": [21, 795], "kdc_timesync": 21, "nonzero": [21, 225, 955], "inaccur": 21, "clock": [21, 34, 48, 269, 358, 362, 904, 938, 949], "factor": [21, 917], "plugin_base_dir": 21, "subdirectori": [21, 28, 909, 914, 924], "preferred_preauth_typ": 21, "advertis": [21, 925, 926], "libkrb5": [21, 28, 43, 902, 925], "qualify_shortnam": [21, 38, 925], "suffix": [21, 28, 38, 43, 912, 925, 960], "qualif": [21, 925], "shortnam": [21, 925], "rdn": [21, 33, 38, 43], "realm_try_domain": 21, "try": [21, 25, 32, 35, 38, 39, 41, 43, 912, 925, 945, 953], "forth": 21, "involv": [21, 938], "consult": [21, 939], "renew_lifetim": 21, "request_timeout": [21, 925], "low": 21, "fewer": [21, 925], "word": [21, 34, 918, 946], "edwards25519": [21, 40, 926], "curv": [21, 40, 925], "7748": 21, "nist": [21, 40], "5480": 21, "ticket_lifetim": [21, 33], "udp_preference_limit": 21, "verify_ap_req_nofail": 21, "client_aware_channel_bind": [21, 43], "properti": [21, 944], "auth_to_loc": [21, 28, 939], "translat": [21, 56, 925], "formul": 21, "regexp": 21, "th": 21, "johndo": 21, "1foo": 21, "adminjohndoefoo": 21, "convers": [21, 917], "auth_to_local_nam": [21, 28], "default_domain": 21, "expand": [21, 922, 925], "rcmd": 21, "disable_encrypted_timestamp": [21, 25, 40], "help": [21, 23, 37, 907, 912, 925, 941, 943, 946, 952, 960], "persist": [21, 903], "offer": [21, 24, 40, 912], "http_anchor": [21, 29], "http": [21, 22, 25, 30, 38, 39, 42, 910, 911, 914, 925, 926, 943], "unspecifi": [21, 960], "wide": [21, 29, 36], "openssl": [21, 37, 912, 925], "bundl": [21, 926], "examin": [21, 37, 929, 938], "env": [21, 37, 41, 960], "envvar": 21, "conform": [21, 911, 925, 951], "x509_proxy_ca": 21, "my_proxi": 21, "ipv6": [21, 38, 925], "kpasswd_serv": [21, 29, 39], "forbidden": 21, "master_kdc": [21, 39], "primary_kdc": 21, "sitenam": [21, 39, 925], "discoveri": [21, 25, 33, 34, 925], "v4_instance_convert": 21, "v4_realm": 21, "krb524": 21, "routin": [21, 876], "subdomain": [21, 39, 958], "That": [21, 910], "third": [21, 28, 36, 37, 916, 925, 926, 960], "portion": [21, 36, 153, 268, 319, 387, 412, 757, 814, 819, 830, 842, 881, 926], "uppercas": [21, 939, 960], "particip": [21, 34], "subtag": 21, "anl": 21, "gov": [21, 926], "pnl": 21, "nersc": 21, "net": [21, 42], "telnet": [21, 649, 953], "option1": 21, "option2": 21, "four": [21, 24, 35, 40, 916, 917, 918, 919, 922, 931, 953], "wai": [21, 23, 28, 39, 43, 46, 126, 238, 252, 377, 902, 903, 904, 906, 912, 914, 925, 926, 934, 939, 945, 946, 958], "decreas": [21, 906], "dynam": [21, 930, 933, 935, 941], "pluggabl": [21, 28, 925, 930, 933, 936, 941], "ones": [21, 25, 34, 910, 930, 946], "enable_onli": [21, 28], "modulenam": 21, "come": [21, 46, 361, 910, 911, 945], "built": [21, 24, 28, 46, 48, 380, 903, 910, 912, 925, 931, 941, 946, 952], "collect": [21, 43, 48, 132, 154, 734, 735, 909, 925, 927, 948, 949, 950, 954, 958, 960], "k5ident": [21, 28, 944, 957], "guess": [21, 34, 925], "qualiti": [21, 28, 925, 933, 944], "hesiod": [21, 912, 926], "self": 21, "encrypted_challeng": 21, "encrypted_timestamp": 21, "choic": [21, 38, 43, 46, 252, 949], "heurist": [21, 154, 232, 927, 953, 958], "relationship": [21, 939], "method": [21, 25, 39, 232, 916, 925, 927, 928, 929, 930, 932, 935, 936, 937, 938, 939, 940, 941, 942, 949], "an2ln": [21, 939], "pkinit_san": 21, "pkinit_eku": 21, "dbmatch": 21, "otherrealm": 21, "public": [21, 40, 926, 934, 935, 936, 937], "keyfilenam": 21, "privat": [21, 37, 724, 912, 917, 919, 925, 943], "infrastructur": [21, 40, 909, 910, 925], "encourag": 21, "pkcs12": 21, "pkc": [21, 746], "pkcs11": [21, 912, 924, 925, 926], "module_nam": 21, "modnam": [21, 28], "slotid": 21, "label": [21, 926], "certid": 21, "certlabel": 21, "keyword": [21, 904], "encount": [21, 34, 950], "smard": 21, "reader": [21, 24], "x509_proxi": 21, "x509_anchor": [21, 949], "exactli": [21, 34, 153, 409, 754, 755, 759, 917, 953], "issuer": [21, 37, 322, 414], "comparison": 21, "2253": 21, "represent": [21, 43, 48, 346, 347, 400, 409, 410, 819, 838, 851, 852, 889, 902, 916, 918, 921, 926], "ku": 21, "mssclogin": 21, "clientauth": 21, "emailprotect": 21, "digitalsignatur": [21, 37], "keyencipher": [21, 37], "subjectalternativenam": 21, "encod": [21, 43, 46, 48, 189, 302, 325, 327, 357, 546, 889, 896, 916, 917, 918, 928, 931, 938], "certifi": 21, "kpkdc": 21, "kpserverauth": [21, 37], "serverauth": 21, "commerci": [21, 37, 926], "pkinit_kdc_hostnam": [21, 37], "presenc": [21, 916], "dnsname": 21, "temp": 21, "uid": [21, 43, 903, 907, 924, 953, 959, 960], "real": [21, 352, 387, 713, 953], "sid": [21, 644, 645, 666], "euid": [21, 907, 924], "userid": [21, 912], "binari": [21, 32, 912, 917, 918, 926], "appdata": [21, 907], "roam": 21, "common_appdata": 21, "local_appdata": 21, "folder": 21, "userconfig": 21, "commonconfig": 21, "common": [21, 23, 25, 34, 43, 912, 926, 929, 945, 959], "www": [22, 42, 914, 925], "doc": [22, 42, 914], "instruct": [22, 23, 34, 37, 43, 912, 943], "schema": [22, 24], "ldif": 22, "src": [22, 148, 910, 912, 914, 926], "libkdb_ldap": 22, "ldapadd": 22, "y": [22, 777, 807, 912], "skip": [22, 23, 37, 416, 418], "underneath": 22, "referenc": [22, 916, 926], "subschema": 22, "exact": [22, 911], "worri": [22, 910, 960], "eq": 22, "krbprincipalnam": [22, 918], "speed": [22, 25], "tune": [22, 39], "add_alia": [22, 23], "manipul": [22, 23, 45, 833, 906], "krbcanonicalnam": 22, "therefor": [22, 23, 25, 39, 916, 938], "whole": [23, 37, 141, 155, 344], "notabl": 23, "roll": 23, "input": [23, 43, 48, 49, 99, 100, 102, 103, 107, 113, 117, 119, 124, 144, 194, 195, 225, 289, 290, 291, 292, 296, 298, 354, 377, 378, 405, 927, 939, 942, 955], "variant": [23, 912, 925, 931], "mitig": [23, 25, 46, 907, 925], "modify_princip": [23, 26], "tomorrow": 23, "delete_princip": 23, "reus": 23, "change_password": [23, 26], "get_princip": 23, "list_princip": 23, "govern": [23, 926, 951], "dictat": 23, "add_polici": 23, "year": [23, 45, 904, 925], "stduser": 23, "modify_polici": 23, "delete_polici": 23, "nonexist": [23, 925], "did": [23, 34, 224, 269, 344, 946], "afterward": [23, 936], "better": [23, 24, 853, 925], "cost": [23, 29, 912, 926], "plan": 23, "backup": [23, 30, 32, 39, 908], "proceed": 23, "destroi": [23, 43, 48, 136, 147, 148, 388, 416, 903, 925, 927, 928, 929, 932, 935, 936, 937, 938, 939, 940, 942, 944, 948, 949], "kbd5_util": 23, "someprinc": 23, "loss": [23, 926], "list_mkei": 23, "thu": [23, 907, 912, 953], "jan": 23, "utc": 23, "1970": [23, 902], "unnecessari": 23, "unavail": [23, 34, 39], "unlock": [23, 35, 918, 925], "purge_mkei": 23, "clean": [23, 270, 271, 388, 914, 925, 941], "mandatori": [23, 113, 114, 129, 130, 296, 297, 300, 301, 919], "distinct": 23, "chiefli": 23, "create_polici": 23, "list_polici": 23, "view_polici": 23, "requires_pre_auth": 23, "disallow_svr": [23, 918], "destroy_polici": 23, "imposs": [23, 35], "26": [23, 609, 611], "newest": 23, "sometim": [23, 25, 38, 949], "accomplish": [23, 26], "set_str": [23, 26, 36, 37], "transmit": [23, 43, 281, 406, 925, 938], "circular": 23, "certain": [23, 32, 238, 912, 926, 955, 960], "side": [23, 43, 365, 377, 907], "lowercas": [23, 38, 907, 918], "wrap": [23, 48, 302, 322, 931], "around": [23, 912], "resum": 23, "setup": [23, 34, 910, 925], "arrang": 23, "hierarchi": 23, "upstreamhostnam": 23, "downstream": [23, 925], "upstream": [23, 912, 925], "transport": [23, 39, 281, 406], "interven": 23, "donat": [23, 926], "patch": 23, "reflect": [23, 34, 100, 103, 136, 158, 264, 290, 292, 327, 328, 333, 358, 362, 917, 919], "sunw_dbprop_en": 23, "sunw_dbprop_master_ulogs": 23, "sunw_dbprop_slave_pol": 23, "rpcbind": 23, "portmapp": 23, "replica_datatrans_hostnam": 23, "db": [24, 35, 912], "delai": [24, 39, 912, 925, 949], "featur": [24, 29, 370, 373, 923, 926, 943], "rare": [24, 37, 904, 906], "unclean": 24, "shutdown": 24, "inconsist": 24, "intern": [24, 36, 41, 107, 737, 853, 927, 928, 929, 933, 935, 936, 937, 938, 940, 942, 960], "pointer": [24, 43, 44, 46, 91, 135, 136, 173, 198, 200, 203, 210, 214, 218, 221, 232, 233, 258, 264, 265, 324, 325, 332, 334, 359, 367, 368, 388, 397, 409, 831, 833, 838, 878, 889, 927, 928, 929, 930, 935, 936, 938, 940, 942], "reliabl": 24, "mdb": [24, 918], "consum": [24, 902, 934], "primarili": [24, 55, 956], "platform": [24, 891, 902, 903, 910, 911, 912, 925], "hundr": 24, "thousand": 24, "512": [24, 524], "larger": [24, 32, 37, 902, 921, 925], "transact": [24, 960], "thread": [24, 853, 903, 912, 925], "latenc": 24, "pasword": 25, "sequenc": [25, 37, 48, 66, 78, 80, 83, 327, 328, 329, 333, 358, 360, 361, 362, 526, 533, 814, 819, 881, 908, 916, 917, 921, 931], "effort": 25, "trivial": [25, 925], "signific": [25, 35, 918], "fraction": 25, "concern": [25, 35, 926, 946], "capac": 25, "measur": [25, 902], "satisfactori": 25, "ciphertext": [25, 99, 100, 102, 103, 104, 289, 290, 291, 292, 813, 837, 917, 922], "categori": 25, "invis": 25, "faster": [25, 39, 903, 910], "defens": 25, "depend": [25, 33, 39, 43, 46, 126, 367, 375, 746, 882, 911, 912, 924, 925, 930, 942, 945, 946], "legitim": [25, 46, 907, 953], "princnam": [25, 35, 40, 46, 903], "passiv": 25, "monitor": 25, "insert": [25, 39, 831, 838], "observ": [25, 29, 35], "inject": 25, "fool": 25, "varieti": 26, "integr": [26, 33, 43, 46, 328, 333, 358, 362, 909, 911, 924, 925, 926, 946], "confidenti": [26, 43, 925], "subsess": [26, 332, 445], "submit": [26, 43], "intersect": 26, "assumpt": 26, "strongest": 26, "fashion": [26, 29, 926, 953], "2000": [26, 643, 645, 709, 926], "md4": [26, 926], "vista": [26, 925], "eventu": [26, 39], "legaci": [26, 46, 891], "tabdump": [26, 925], "rotat": [26, 38], "domain_realm": [28, 33, 39, 958], "openssh": [28, 38], "gssapiauthent": 28, "histor": [28, 33, 902, 918], "simplest": [28, 43, 903, 910], "unam": 28, "neg": [28, 891, 921], "safe": [28, 48, 747, 902, 925], "hostaccount": 28, "fred": 28, "localfr": 28, "hostrealm": [28, 925, 933], "parti": [28, 36, 43, 925, 926, 960], "dll": [28, 930, 931, 941], "unusu": [28, 37], "mypreauth": 28, "clpreauth": [28, 933], "ccselect": [28, 925, 930, 933, 940], "pwqual": [28, 925, 933], "mymodul": 28, "simpli": [28, 36, 37, 40, 43, 46, 745, 910, 931, 945, 946], "samba": [28, 925], "winbind": 28, "winbind_krb5_loc": 28, "gss": [28, 909, 916, 924, 925, 931, 960], "mech": [28, 924, 925, 960], "oid": [28, 43, 925, 931], "surround": 28, "interpos": [28, 933], "design": [28, 34, 46, 317, 903, 907, 960], "intercept": [28, 931], "gss_mech_config": [28, 924, 960], "rest": [28, 912], "rfc4120": 29, "kkdcp": [29, 39, 925, 926], "firewal": [29, 39, 41], "traffic": 29, "conduct": 29, "wsgi": 29, "kdcproxi": 29, "python": [29, 914, 925], "packag": [29, 34, 910, 926], "ssl": [29, 37], "cacert": [29, 37], "fqdn": 29, "properli": [29, 34, 37, 41, 902, 912], "decis": [30, 926, 935, 939, 960], "troubleshoot": [30, 34], "advic": 31, "debian": [31, 925], "solari": [31, 910, 912, 925], "unauthent": 32, "afford": 32, "capabl": [32, 925, 945], "break": [32, 908], "unrestrict": [32, 908, 918], "brief": [32, 909, 934], "descript": [32, 39, 43, 842, 909, 924, 925, 927, 928, 929, 932, 934, 935, 936, 937, 938, 939, 940, 941, 942], "ftp": [32, 34], "pop": 32, "destin": [32, 910, 925], "unencrypt": [32, 358, 819, 829, 851, 852], "ins": 32, "obvious": 32, "exhaust": 32, "countermeasur": 32, "worth": 32, "hole": [32, 34, 39, 921], "tape": 32, "physic": [32, 39], "kdestroi": [33, 903, 925, 944, 947, 949, 950, 954, 955, 960], "pam": 33, "cover": 33, "educ": 33, "nativ": [33, 370, 373, 902, 912, 916, 921, 924, 925], "precis": 33, "unqualifi": 33, "cname": [33, 34, 38, 39], "anticip": [33, 39], "eight": 33, "workdai": 33, "ten": [33, 946], "morn": 33, "shortli": [33, 945], "belong": [33, 161], "product": [34, 926], "alongsid": 34, "dedic": 34, "web": [34, 903, 925], "area": [34, 46], "build": [34, 39, 41, 48, 49, 136, 903, 909, 912, 923, 924, 925, 930, 934, 952], "relev": [34, 38, 78, 195, 302, 917], "explain": 34, "yourdir": 34, "suit": [34, 909, 910, 925], "krb5lib": 34, "rememb": [34, 37, 916], "els": [34, 930, 945, 946, 953], "bad": [34, 135, 156], "popular": 34, "famou": 34, "cartoon": 34, "mitiys4k5": 34, "sentenc": 34, "letter": [34, 39, 946], "util": [34, 39, 47, 910, 912, 926, 948, 960], "boot": [34, 908], "rc": 34, "inittab": 34, "startup": [34, 925], "tail": 34, "dec": [34, 35, 904], "02": [34, 925], "35": 34, "beeblebrox": 34, "3187": 34, "commenc": 34, "52": [34, 592, 946], "3189": 34, "mutual": [34, 332, 377, 442, 508, 813, 949, 953], "secondari": 34, "strictli": [34, 43], "handi": 34, "swap": [34, 39], "feasibl": 34, "stand": 34, "alon": [34, 930], "ll": 34, "bourn": 34, "bin": [34, 910, 912, 914, 924, 953], "sh": 34, "kdclist": 34, "decid": [34, 39, 247, 946], "discuss": [34, 907, 926, 934, 943], "solut": 34, "click": 34, "rout": 34, "occasion": 34, "changeov": 34, "kill": 34, "latest": [34, 225, 890, 910, 918, 925, 946], "difficult": 35, "lockout_polici": 35, "hopefulli": 35, "wrong": [35, 37, 926, 946, 953], "incorrect": [35, 39, 741, 742, 945, 946], "piec": [35, 267], "30": [35, 39, 548, 703, 904, 946, 949], "33": 35, "est": [35, 904], "2012": [35, 904], "multipli": 35, "40": [35, 39], "strategi": 35, "multi": [35, 37, 925], "impact": 35, "largest": 35, "box": 36, "deploi": [36, 37, 38, 910], "proprietari": 36, "companion": 36, "eas": 36, "vice": [37, 43, 925], "versa": [37, 43, 925], "establish": [37, 43, 907], "genrsa": 37, "cakei": 37, "x509": [37, 925, 949], "3650": 37, "far": 37, "2037": 37, "interoper": [37, 384, 385, 903, 931], "rsa": [37, 482, 485, 486, 487, 926], "carefulli": 37, "somewhat": [37, 907], "complic": [37, 912], "kdc_cert": 37, "basicconstraint": 37, "keyusag": 37, "nonrepudi": 37, "keyagr": 37, "extendedkeyusag": 37, "subjectkeyidentifi": 37, "authoritykeyidentifi": 37, "keyid": 37, "issueraltnam": 37, "subjectaltnam": 37, "othernam": 37, "kdc_princ_nam": 37, "generalstr": 37, "principal_nam": 37, "kdc_principal_seq": 37, "name_typ": 37, "name_str": 37, "kdc_princip": 37, "princ1": [37, 350, 351, 352, 364], "princ2": [37, 350, 351, 352, 364], "extens": [37, 39, 249, 914, 918, 925, 931], "kdckei": 37, "your_realmnam": 37, "365": 37, "extfil": 37, "cacreateseri": 37, "rm": 37, "noout": 37, "unsupport": [37, 912], "client_cert": 37, "princ_nam": [37, 948], "principal_seq": 37, "clientkei": 37, "your_princnam": 37, "client1": 37, "client2": 37, "lib": [37, 910, 912, 924, 926, 952], "oppos": 37, "save": [37, 40, 66, 83, 533, 534, 917, 925, 938], "clarifi": 37, "condit": [37, 154, 303, 925, 926, 953], "criteria": [37, 903], "procur": [37, 926], "wellknown": [37, 46, 507, 769], "lack": [37, 380, 925], "realmnam": [37, 46], "possess": [37, 946], "compos": 37, "disable_fresh": [37, 949], "unsuccess": 37, "difficulti": 38, "think": [38, 930, 945], "kind": [38, 43, 105, 903, 926, 929, 931, 938], "imap": [38, 912, 958], "nf": [38, 945], "publish": [38, 926], "vaniti": 38, "natur": 38, "sort": 38, "rnd": 38, "ipv4": 38, "getaddrinfo": 38, "internet": 38, "getnameinfo": 38, "ptr": [38, 43, 197, 283, 341, 355, 808, 809, 838, 839, 889], "dot": 38, "enterpris": [38, 43, 347, 716, 925, 949, 955], "influenc": 38, "gssapistrictacceptorcheck": 38, "idea": 38, "gethostnam": [38, 43], "sasl_nocanon": 38, "ldapsasl_nocanon": 38, "although": [39, 906, 926, 932, 942, 945, 946], "convent": [39, 408, 941], "boston": 39, "houston": 39, "subset": [39, 909], "fine": [39, 43], "prepend": [39, 348, 422, 912], "_kerbero": 39, "engin": 39, "thorough": 39, "treatment": 39, "event": [39, 48, 925, 926, 938], "inaccess": 39, "logic": [39, 925], "slack": 39, "consider": [39, 45], "down": 39, "partit": 39, "segment": 39, "cut": 39, "isol": 39, "fire": 39, "disast": 39, "predefin": 39, "2782": 39, "weight": 39, "priorit": 39, "_udp": 39, "_tcp": 39, "whatev": 39, "_kpasswd": 39, "her": [39, 946, 959], "foobar": [39, 912, 959], "daisi": 39, "luke": 39, "bunni": 39, "rabbit": 39, "benefit": 39, "unconfigur": [39, 914], "_site": 39, "proxim": 39, "7553": 39, "failov": 39, "insensit": [39, 352, 712, 904], "scheme": 39, "krb5srv": 39, "kdc1": 39, "kdc2": 39, "89": 39, "fall": [39, 40, 903, 925], "lot": 39, "techniqu": [40, 46], "modestli": 40, "cpu": 40, "ellipt": [40, 925], "defeat": 40, "round": [40, 925, 938], "trip": [40, 925, 938], "krb5_trace": [41, 388, 389, 960], "stdout": [41, 354], "honor": [41, 946], "setuid": [41, 925, 960], "9138": 41, "1332348778": 41, "823276": 41, "me": 41, "testdir": 41, "823381": 41, "inadequ": 41, "erron": 41, "trace_log": 41, "fulvio": 42, "ricciardi": 42, "_": 42, "wiki": [42, 910, 925], "ncsa": 42, "illinoi": 42, "ITS": [42, 926], "shrubberi": 42, "solaris9ab": 42, "sunwaadm": 42, "sysadv6": 42, "p27": 42, "oracl": [42, 926], "cd": [42, 910, 914], "e19253": 42, "816": 42, "4557": 42, "troubl": 42, "en": [42, 925], "u": [42, 925, 926, 955, 959], "tn": 42, "archiv": [42, 911], "bb463167": 42, "technet": 42, "ebaa": 42, "launchpad": 42, "ubuntu": [42, 925], "libpam": 42, "heimdal": [42, 43, 45, 903, 925], "86528": 42, "higher": [43, 903, 914, 925], "framework": [43, 925, 926], "encompass": 43, "gssapiv2": 43, "2743": 43, "2744": 43, "7546": 43, "entiti": [43, 926], "gss_import_nam": [43, 931], "gss_c_nt_hostbased_servic": 43, "gss_krb5_nt_principal_nam": 43, "gssapi_krb5": 43, "gss_c_nt_user_nam": 43, "gss_c_null_oid": 43, "unpars": [43, 48, 409, 411], "gss_c_nt_anonym": 43, "gss_c_nt_machine_uid_nam": 43, "uid_t": 43, "gss_c_nt_string_uid_nam": 43, "gss_c_nt_export_nam": [43, 931], "gss_export_nam": 43, "gss_krb5_nt_enterprise_nam": [43, 925], "6806": [43, 547, 916, 925], "gss_krb5_nt_x509_cert": [43, 925], "5280": 43, "desired_nam": 43, "gss_acquire_cred_impersonate_nam": 43, "gss_init_sec_context": [43, 925], "initiator_cred_handl": 43, "gss_c_no_credenti": 43, "gss_acquire_cr": [43, 925], "beforehand": 43, "gss_c_no_nam": 43, "gss_s_cred_unavail": 43, "mismatch": [43, 262, 344, 945], "acquisit": [43, 405], "defer": [43, 928, 932, 935, 939], "gss_inquire_cr": 43, "approach": 43, "gss_accept_sec_context": [43, 925, 931], "acceptor_cred_handl": 43, "krb5_ktname": [43, 906, 924, 960], "contrari": [43, 46], "cred_usag": 43, "gss_c_accept": 43, "gss_c_both": 43, "localhostnam": 43, "gss_inquire_nam": 43, "gss_get_name_attribut": 43, "6680": [43, 925], "src_name": 43, "declar": [43, 925, 931], "gssapi_ext": [43, 931], "struct": [43, 48, 51, 264, 271, 811, 813, 814, 815, 816, 817, 819, 822, 823, 824, 828, 829, 830, 831, 832, 833, 835, 837, 838, 839, 840, 842, 846, 847, 848, 851, 852, 853, 854, 855, 856, 860, 865, 866, 867, 868, 869, 875, 876, 879, 880, 881, 882, 884, 885, 886, 887, 888, 889, 890, 892, 893, 895, 896, 897, 900, 901, 918, 935, 941], "gss_key_value_element_struct": 43, "const": [43, 49, 52, 53, 54, 58, 59, 60, 91, 92, 93, 94, 99, 100, 101, 102, 103, 106, 107, 108, 113, 114, 117, 119, 120, 125, 126, 129, 130, 136, 141, 144, 146, 149, 152, 155, 156, 160, 166, 169, 172, 173, 174, 175, 177, 178, 180, 181, 183, 184, 185, 188, 189, 194, 195, 197, 214, 215, 224, 230, 233, 234, 235, 236, 237, 249, 254, 262, 266, 267, 269, 279, 280, 283, 286, 288, 289, 290, 291, 292, 296, 300, 301, 302, 303, 314, 319, 321, 322, 324, 326, 328, 331, 333, 335, 338, 341, 342, 343, 344, 345, 346, 347, 348, 353, 354, 355, 357, 358, 359, 360, 361, 362, 363, 367, 368, 371, 374, 375, 378, 379, 380, 381, 384, 385, 386, 389, 391, 395, 407, 414, 415, 419, 420, 421, 422, 798, 826, 827, 871, 872, 878, 894, 895, 941], "char": [43, 46, 49, 50, 56, 59, 60, 91, 92, 93, 94, 107, 136, 141, 143, 144, 146, 149, 152, 155, 156, 160, 166, 169, 170, 187, 192, 193, 194, 205, 211, 214, 215, 220, 223, 224, 228, 229, 230, 232, 233, 235, 237, 249, 254, 262, 266, 269, 279, 280, 308, 313, 314, 319, 321, 331, 338, 346, 347, 348, 354, 363, 365, 367, 368, 371, 374, 375, 376, 377, 379, 381, 384, 385, 386, 389, 391, 392, 393, 394, 396, 397, 399, 400, 408, 409, 410, 411, 419, 420, 421, 422, 809, 835, 847, 876, 878, 884, 885, 887, 895, 941], "typedef": [43, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901], "gss_key_value_element_desc": 43, "gss_key_value_set_struct": 43, "om_uint32": [43, 931], "element": [43, 46, 48, 189, 322, 414, 833, 879, 917, 918], "gss_key_value_set_desc": 43, "gss_const_key_value_set_t": 43, "gss_acquire_cred_from": [43, 925], "minor_statu": [43, 931], "gss_name_t": [43, 931], "time_req": 43, "gss_oid_set": [43, 931], "desired_mech": [43, 931], "gss_cred_usage_t": 43, "cred_stor": 43, "gss_cred_id_t": [43, 931], "output_cred_handl": 43, "actual_mech": 43, "time_rec": [43, 925], "gss_store_cred_into": 43, "input_cred_handl": 43, "gss_oid": [43, 931], "overwrite_cr": 43, "default_cr": 43, "elements_stor": 43, "cred_usage_stor": 43, "client_keytab": 43, "rcach": [43, 71, 85, 267, 325, 327, 907], "gss_s_duplicate_el": 43, "gss_export_cr": 43, "cred_handl": [43, 931], "gss_buffer_t": [43, 931], "gss_import_cr": [43, 931], "unser": 43, "gss_s_unavail": 43, "eavesdrop": 43, "tamper": 43, "untrust": [43, 960], "resourc": [43, 46, 910, 923, 925], "evid": 43, "underli": 43, "delegated_cred_handl": 43, "icr": 43, "output_cr": 43, "target_nam": 43, "gss_krb5_get_cred_imperson": [43, 925], "gss_inquire_cred_by_oid": [43, 925], "desired_object": 43, "gss_buffer_set_t": 43, "data_set": 43, "endpoint": [43, 62, 926], "input_chan_bind": 43, "ret_flag": 43, "inlud": 43, "req_flag": 43, "kerb_ap_options_cbt": [43, 440, 925], "unwrap": [43, 48], "gss_wrap_aead": 43, "gss_ctx_id_t": [43, 931], "context_handl": [43, 931], "int": [43, 51, 53, 56, 59, 62, 91, 92, 93, 94, 97, 111, 116, 120, 122, 166, 224, 243, 244, 245, 246, 251, 256, 257, 281, 308, 313, 347, 352, 354, 363, 384, 385, 406, 409, 410, 411, 418, 811, 817, 820, 824, 835, 846, 852, 854, 859, 863, 865, 876, 878, 879, 897, 900, 918, 930], "conf_req_flag": 43, "gss_qop_t": 43, "qop_req": 43, "input_assoc_buff": 43, "input_payload_buff": 43, "conf_stat": 43, "output_message_buff": 43, "gss_unwrap_aead": 43, "input_message_buff": 43, "output_payload_buff": 43, "qop_stat": 43, "grain": 43, "layout": [43, 924], "dce": [43, 48, 647, 686, 925], "gss_iov_buffer_desc_struct": 43, "gss_buffer_desc": 43, "gss_iov_buffer_desc": 43, "gss_iov_buffer_t": 43, "gss_wrap_iov": 43, "iov_count": 43, "gss_unwrap_iov": 43, "gss_wrap_iov_length": 43, "gss_release_iov_buff": 43, "structur": [43, 46, 47, 48, 92, 100, 103, 135, 156, 169, 173, 182, 213, 222, 239, 242, 243, 244, 245, 246, 247, 251, 254, 255, 256, 257, 259, 260, 261, 271, 277, 282, 284, 290, 292, 324, 326, 336, 347, 357, 358, 367, 370, 373, 377, 391, 416, 418, 423, 543, 811, 817, 829, 832, 833, 842, 869, 889, 896, 902, 929, 930, 935, 937, 938, 940], "gss_c_buffer_type_data": 43, "gss_c_buffer_type_head": 43, "gss_c_buffer_type_trail": 43, "trailer": [43, 48, 543], "gss_c_buffer_type_pad": 43, "pad": [43, 48, 99, 100, 103, 104, 289, 290, 292, 541, 922], "gss_c_buffer_type_stream": 43, "gss_c_buffer_type_sign_onli": 43, "sign_onli": 43, "contigu": 43, "gss_c_buffer_flag_alloc": 43, "alloc": [43, 46, 48, 61, 78, 93, 98, 99, 100, 102, 103, 107, 115, 117, 119, 121, 124, 148, 282, 289, 290, 291, 292, 298, 357, 359, 409, 833, 876, 928, 930, 932, 935, 939], "unset": [43, 48, 171, 960], "ctx": [43, 72, 73, 76, 77, 86, 87, 88, 89, 171, 176, 214, 230, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 348, 367, 368, 369, 370, 371, 372, 373, 374, 375, 381, 401, 402, 403, 404, 405, 406, 419, 420, 421, 422, 883], "major": [43, 911, 930], "str": 43, "gss_iov_buffer_type_head": 43, "gss_iov_buffer_flag_alloc": 43, "gss_iov_buffer_type_data": 43, "strlen": [43, 46], "gss_iov_buffer_type_pad": 43, "gss_iov_buffer_type_trail": 43, "gss_c_qop_default": 43, "gss_error": 43, "handle_error": 43, "void": [43, 46, 57, 58, 59, 60, 63, 80, 171, 179, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 219, 220, 221, 222, 223, 239, 241, 242, 243, 244, 245, 246, 247, 251, 256, 257, 258, 259, 260, 261, 262, 272, 277, 287, 293, 299, 336, 341, 348, 354, 369, 372, 381, 382, 383, 388, 401, 417, 418, 419, 420, 421, 422, 826, 844, 862, 870, 871, 872, 878, 883, 894, 940, 941], "sizeof": [43, 46, 941], "handle_out_of_space_error": 43, "gss_c_dce_styl": 43, "4757": [43, 451, 468, 469], "token_len": 43, "region": [43, 114, 130, 297, 301, 833], "gss_iov_buffer_type_stream": 43, "subregion": 43, "gss_get_mic_iov": 43, "gss_get_mic_iov_length": 43, "gss_verify_mic_iov": 43, "gss_c_buffer_type_mic_token": 43, "mic_token": 43, "sign1": 43, "gss_iov_buffer_type_sign_onli": 43, "sign2": 43, "gss_iov_buffer_type_mic_token": 43, "krb5_auth_con_getaddr": [44, 48], "local_addr": [44, 64, 82], "remote_addr": [44, 64, 82, 361], "freed": [44, 57, 58, 61, 78, 85, 106, 136, 144, 146, 198, 199, 200, 201, 202, 204, 208, 209, 211, 212, 213, 216, 217, 218, 219, 220, 222, 223, 230, 264, 314, 336, 367, 368, 370, 373, 871, 872], "realloc": 44, "krb5_auth_con_setaddr": [44, 48], "krb5_auth_con_setport": [44, 48], "krb5_auth_con_setrecvsubkei": [44, 48], "krb5_auth_con_setsendsubkei": [44, 48], "krb5_cc_set_config": [44, 48, 285], "krb5_cccol_last_change_tim": 44, "krb5_set_default_realm": [44, 48], "wasn": 44, "2038": [45, 891, 925], "krb5_timestamp": [45, 167, 268, 338, 342, 343, 344, 345, 387, 397, 398, 399, 400, 412, 810, 814, 819, 830, 838, 842, 844, 852, 856, 860, 867, 881, 888, 890], "datatyp": 45, "whenev": 46, "desktop": 46, "critic": [46, 943], "zanarotti": 46, "goal": 46, "krb5_get_init_creds_password": [46, 48, 235, 245, 247, 354, 925], "krb5_verify_init_cr": [46, 48, 418], "krb5_error_cod": [46, 49, 50, 55, 56, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 129, 130, 131, 132, 133, 134, 135, 137, 138, 139, 140, 141, 142, 143, 145, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 161, 162, 163, 164, 165, 166, 167, 169, 170, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 186, 187, 189, 190, 192, 193, 194, 195, 196, 197, 215, 218, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 240, 247, 248, 249, 250, 252, 253, 254, 255, 259, 262, 263, 264, 266, 267, 268, 269, 270, 271, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 288, 289, 290, 291, 292, 295, 296, 297, 298, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 315, 316, 317, 318, 319, 320, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 365, 366, 370, 371, 373, 374, 375, 376, 377, 378, 379, 380, 381, 384, 385, 386, 387, 388, 389, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 419, 420, 421, 422, 810, 861, 862, 871, 872, 878, 883, 930], "ret": [46, 349], "krb5_cred": [46, 48, 51, 150, 151, 153, 159, 166, 221, 225, 226, 227, 234, 235, 236, 237, 262, 266, 269, 274, 325, 327, 332, 356, 377, 384, 403, 405, 416, 795, 810], "cred": [46, 48, 150, 151, 153, 159, 166, 234, 235, 236, 237, 262, 266, 269, 274, 277, 323, 384, 403, 405, 407, 416, 536, 925, 953], "krb5_princip": [46, 47, 48, 49, 91, 92, 93, 94, 132, 145, 147, 154, 182, 219, 224, 231, 237, 262, 266, 269, 277, 317, 321, 365, 366, 377, 384, 385, 386, 391, 414, 416, 810, 819, 831, 832, 838, 839, 842, 851, 852, 856, 867, 868, 889], "client_princ": [46, 302], "memset": 46, "krb5_parse_nam": [46, 47, 48, 347, 408], "goto": 46, "cleanup": [46, 941], "krb5_free_princip": [46, 47, 48, 49, 91, 92, 93, 145, 154, 182, 346, 347, 391], "krb5_free_cred_cont": [46, 48, 150, 153, 274, 403], "krb5_get_init_creds_opt_alloc": [46, 48, 239, 241], "krb5_get_init_creds_opt_fre": [46, 48, 238], "free": [46, 47, 48, 49, 65, 67, 72, 76, 91, 93, 111, 115, 141, 143, 145, 150, 153, 169, 172, 173, 174, 175, 177, 178, 180, 181, 182, 183, 194, 195, 225, 228, 229, 231, 238, 263, 274, 277, 282, 288, 312, 317, 319, 323, 324, 326, 327, 328, 329, 330, 331, 332, 333, 334, 337, 340, 341, 346, 347, 356, 357, 358, 359, 361, 362, 365, 377, 391, 403, 405, 407, 408, 410, 926, 928, 930, 941], "krb5_get_init_creds_opt": [46, 231, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 277, 810], "opt": [46, 231, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 952], "krb5_get_init_creds_opt_set_tkt_lif": [46, 48], "krb5_get_init_creds_opt_set_anonym": [46, 48], "krb5_build_princip": [46, 47, 48, 92], "myrealm": 46, "prove": [46, 919, 929, 938], "membership": 46, "impend": 46, "banner": [46, 354, 878], "hidden": [46, 354, 876], "storag": [46, 48, 57, 58, 82, 84, 159, 170, 187, 192, 193, 282, 363, 376, 400, 903], "fill": [46, 48, 50, 56, 119, 121, 134, 150, 152, 225, 228, 232, 233, 305, 308, 313, 329, 349, 359, 360, 392, 393, 396, 398, 399, 921, 922, 930, 941], "krb5_get_prompt_typ": [46, 48], "constant": [46, 57, 58, 733, 739, 827], "programmat": 46, "semant": 46, "krb5_prompter_posix": [46, 48], "init_cr": 46, "krb5_get_init_creds_opt_set_respond": [46, 48], "sophist": 46, "rctx": [46, 367, 368, 369, 370, 371, 372, 373, 374, 375, 883], "krb5_responder_list_quest": [46, 48, 882], "krb5_responder_get_challeng": [46, 48, 368, 882], "krb5_responder_set_answ": [46, 48, 368, 882], "utf": [46, 352, 367, 375, 715, 925, 926], "understand": 46, "krb5_responder_question_password": [46, 795], "krb5_responder_question_otp": [46, 48, 795], "among": 46, "conveni": [46, 325, 370, 373, 910], "krb5_responder_otp_get_challeng": [46, 48], "krb5_responder_otp_challeng": [46, 369, 370, 810], "krb5_responder_otp_set_answ": [46, 48], "krb5_responder_question_pkinit": [46, 48, 795], "krb5_responder_pkinit_get_challeng": [46, 48], "krb5_responder_pkinit_challeng": [46, 372, 373, 810], "krb5_responder_pkinit_set_answ": [46, 48], "static": [46, 930, 941], "my_respond": 46, "krb5_context": [46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 183, 184, 186, 188, 189, 190, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 247, 248, 249, 250, 252, 253, 254, 255, 259, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 377, 378, 379, 381, 382, 383, 384, 385, 386, 388, 389, 390, 391, 395, 398, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 419, 420, 421, 422, 810, 844, 862, 871, 872, 878, 883, 894, 925, 930], "krb5_responder_context": [46, 367, 368, 369, 370, 371, 372, 373, 374, 375, 810, 883], "chl": [46, 369, 370, 372], "sesam": [46, 707], "1234": 46, "krb5_responder_otp_challenge_fre": [46, 48, 370], "get_cr": 46, "krb5_verify_init_creds_opt_init": [46, 48, 416], "krb5_verify_init_creds_opt_set_ap_req_nofail": [46, 48, 416], "nofail": 46, "krb5_verify_init_creds_opt": [46, 416, 417, 418, 810], "vopt": 46, "confusingli": 46, "accommod": [46, 907], "unkei": 46, "workstat": 46, "valuabl": [46, 926], "krb5_principal_data": [47, 810, 827, 874], "krb5_build_principal_alloc_va": [47, 48, 91, 94], "krb5_build_principal_ext": [47, 48], "krb5_copy_princip": [47, 48], "krb5_cc_get_princip": [47, 48], "compar": [47, 48, 129, 300, 917], "krb5_principal_compar": [47, 48, 351, 352, 390], "krb5_principal_compare_flag": [47, 48], "krb5_principal_compare_any_realm": [47, 48], "krb5_sname_match": [47, 48, 361], "krb5_sname_to_princip": [47, 48], "krb5_parse_name_flag": [47, 48], "krb5_unparse_nam": [47, 48, 409, 410], "krb5_unparse_name_flag": [47, 48], "krb5_is_config_princip": [47, 48], "krb5_kuserok": [47, 48, 925, 939], "krb5_set_password": [47, 48, 169], "krb5_set_password_using_ccach": [47, 48], "krb5_set_principal_realm": [47, 48], "krb5_realm_compar": [47, 48], "precomput": 48, "krb5_cc_close": [48, 132, 154, 164], "krb5_cc_default": 48, "krb5_cc_default_nam": [48, 135, 156], "krb5_cc_destroi": 48, "krb5_cc_dup": 48, "duplic": [48, 832, 907], "krb5_cc_get_nam": 48, "krb5_cc_get_typ": 48, "krb5_cc_initi": [48, 145], "krb5_cc_new_uniqu": 48, "krb5_cc_resolv": [48, 144], "krb5_change_password": [48, 169], "krb5_chpw_messag": 48, "krb5_expand_hostnam": 48, "krb5_free_config_fil": [48, 228], "krb5_get_default_config_fil": 48, "krb5_free_context": [48, 136, 176, 270, 284], "krb5_free_error_messag": [48, 230], "krb5_get_error_messag": [48, 843], "krb5_fwd_tgt_cred": 48, "krb": [48, 925, 926], "krb5_get_default_realm": 48, "krb5_get_host_realm": [48, 391], "krb5_get_credenti": [48, 377, 382, 383, 405], "krb5_get_fallback_host_realm": 48, "krb5_get_init_creds_keytab": [48, 234], "krb5_get_init_creds_opt_get_fast_flag": 48, "krb5_get_init_creds_opt_set_address_list": 48, "krb5_get_init_creds_opt_set_canonic": 48, "krb5_get_init_creds_opt_set_change_password_prompt": 48, "krb5_get_init_creds_opt_set_etype_list": [48, 231], "krb5_get_init_creds_opt_set_expire_callback": 48, "callback": [48, 262, 277, 354, 382, 383, 389, 862, 876, 878, 882, 925, 929, 938, 940], "krb5_get_init_creds_opt_set_fast_ccach": 48, "krb5_get_init_creds_opt_set_fast_ccache_nam": [48, 231, 248], "krb5_get_init_creds_opt_set_fast_flag": [48, 249], "krb5_get_init_creds_opt_set_forward": 48, "krb5_get_init_creds_opt_set_in_ccach": 48, "krb5_get_init_creds_opt_set_out_ccach": 48, "krb5_get_init_creds_opt_set_pa": [48, 256], "krb5_get_init_creds_opt_set_pac_request": 48, "krb5_get_init_creds_opt_set_preauth_list": 48, "krb5_get_init_creds_opt_set_proxi": 48, "krb5_get_init_creds_opt_set_renew_lif": 48, "krb5_get_init_creds_opt_set_salt": [48, 256], "krb5_get_profil": 48, "krb5_get_renewed_cr": [48, 226], "krb5_get_validated_cr": [48, 227], "krb5_init_context": [48, 206, 228], "krb5_init_secure_context": [48, 206, 270, 925], "krb5_is_thread_saf": 48, "multithread": 48, "krb5_kt_close": [48, 319], "krb5_kt_client_default": 48, "krb5_kt_default": 48, "krb5_kt_default_nam": 48, "krb5_kt_dup": 48, "krb5_kt_get_nam": 48, "krb5_kt_get_typ": 48, "krb5_kt_resolv": 48, "krb5_responder_pkinit_challenge_fre": [48, 373], "krb5_set_trace_callback": 48, "trace": [48, 895, 925, 960], "krb5_set_trace_filenam": 48, "krb5_unparse_name_ext": 48, "krb5_unparse_name_flags_ext": 48, "krb5_us_timeofdai": 48, "sec": [48, 819, 842, 904], "epoch": [48, 891], "krb5_verify_authdata_kdc_issu": 48, "kdcissu": 48, "krb5_425_conv_princip": 48, "krb5_524_conv_princip": 48, "krb5_address_compar": 48, "krb5_address_ord": 48, "krb5_address_search": 48, "krb5_allow_weak_crypto": 48, "krb5_aname_to_localnam": [48, 925, 939], "krb5_anonymous_princip": 48, "krb5_anonymous_realm": 48, "krb5_appdefault_boolean": [48, 60], "appdefault": 48, "krb5_appdefault_str": [48, 59], "krb5_auth_con_fre": [48, 78], "krb5_auth_context": [48, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, 224, 325, 327, 328, 329, 330, 331, 332, 333, 356, 358, 359, 360, 361, 362, 365, 366, 377, 810, 862], "krb5_auth_con_genaddr": [48, 82, 84], "krb5_auth_con_get_checksum_func": 48, "krb5_auth_con_getauthent": 48, "krb5_auth_con_getflag": 48, "krb5_auth_con_getkei": 48, "keyblock": [48, 70, 75, 90, 101, 107, 115, 117, 216, 217, 225, 282, 283, 333, 355, 361, 395, 832, 916], "krb5_auth_con_getkey_k": 48, "krb5_auth_con_getlocalseqnumb": 48, "krb5_auth_con_getrcach": 48, "krb5_auth_con_getrecvsubkei": [48, 75], "subkei": [48, 80, 327, 356, 361, 814, 819], "krb5_auth_con_getrecvsubkey_k": 48, "krb5_auth_con_getremoteseqnumb": 48, "krb5_auth_con_getsendsubkei": [48, 70], "krb5_auth_con_getsendsubkey_k": 48, "krb5_auth_con_init": [48, 61], "krb5_auth_con_set_checksum_func": 48, "krb5_auth_con_set_req_cksumtyp": 48, "krb5_auth_con_setflag": [48, 78], "krb5_auth_con_setrcach": 48, "krb5_auth_con_setrecvsubkey_k": 48, "krb5_auth_con_setsendsubkey_k": 48, "krb5_auth_con_setuseruserkei": [48, 361], "krb5_cc_cache_match": 48, "krb5_cc_copy_cr": 48, "krb5_cc_end_seq_get": [48, 158], "finish": 48, "seri": [48, 922], "sequenti": [48, 316, 821], "krb5_cc_get_config": 48, "krb5_cc_get_flag": 48, "krb5_cc_get_full_nam": 48, "krb5_cc_move": 48, "krb5_cc_next_cr": [48, 139, 158], "krb5_cc_remove_cr": [48, 925], "krb5_cc_retrieve_cr": [48, 151], "krb5_cc_select": 48, "krb5_cc_set_default_nam": [48, 136], "krb5_cc_set_flag": 48, "krb5_cc_start_seq_get": [48, 139, 150], "prepar": [48, 79, 320, 405], "krb5_cc_store_cr": 48, "krb5_cc_support_switch": 48, "krb5_cc_switch": 48, "krb5_cccol_cursor_fre": [48, 163, 164], "cursor": [48, 139, 150, 158, 163, 164, 316, 320, 821, 823], "krb5_cccol_cursor_new": [48, 162, 164], "krb5_cccol_cursor_next": [48, 162, 163], "krb5_cccol_have_cont": 48, "krb5_clear_error_messag": 48, "krb5_check_clockskew": 48, "skew": [48, 269, 358, 362, 938, 949], "krb5_copy_address": 48, "krb5_copy_authdata": 48, "krb5_copy_authent": 48, "krb5_authent": [48, 65, 810, 892], "krb5_copy_checksum": 48, "krb5_checksum": [48, 113, 129, 131, 296, 300, 415, 810, 819, 867], "krb5_copy_context": 48, "krb5_copy_cr": 48, "krb5_copy_data": [48, 871, 872], "krb5_data": [48, 58, 59, 60, 99, 100, 101, 102, 103, 106, 108, 113, 117, 119, 120, 121, 123, 124, 125, 126, 129, 141, 155, 166, 169, 185, 224, 231, 232, 260, 267, 281, 286, 289, 290, 291, 292, 296, 298, 300, 323, 325, 326, 327, 328, 329, 330, 331, 332, 333, 335, 337, 342, 343, 349, 356, 357, 358, 359, 360, 361, 362, 366, 377, 384, 385, 395, 406, 407, 810, 827, 832, 833, 837, 842, 846, 862, 867, 871, 872, 874, 875, 876, 888, 896, 901], "krb5_copy_error_messag": 48, "krb5_copy_keyblock": 48, "krb5_copy_keyblock_cont": 48, "krb5_copy_ticket": 48, "krb5_ticket": [48, 185, 222, 361, 365, 366, 378, 810, 815, 829, 851, 852, 892], "krb5_find_authdata": 48, "krb5_free_address": [48, 172, 334], "krb5_free_ap_rep_enc_part": [48, 359, 377], "krb5_ap_rep_enc_part": [48, 359, 377, 810], "krb5_free_authdata": [48, 173, 195, 324], "krb5_free_authent": [48, 65, 174], "krb5_free_cr": [48, 177, 225, 377, 407], "krb5_free_data": [48, 178, 323], "krb5_free_data_cont": [48, 141, 231, 326, 327, 328, 329, 330, 331, 332, 333, 337, 358, 362], "krb5_free_default_realm": [48, 229], "krb5_free_enctyp": [48, 263], "krb5_free_error": [48, 357, 377], "krb5_read_error": 48, "krb5_sendauth": [48, 365], "krb5_free_host_realm": [48, 232, 233], "krb5_free_keyblock": [48, 67, 72, 76, 180, 282, 317], "krb5_keyblock": [48, 67, 70, 72, 75, 76, 86, 88, 90, 99, 100, 101, 102, 103, 106, 107, 108, 113, 114, 115, 117, 119, 124, 125, 126, 129, 130, 180, 181, 236, 283, 288, 295, 302, 303, 317, 322, 342, 343, 344, 345, 353, 355, 395, 414, 810, 814, 819, 831, 832, 838, 839, 840, 856], "krb5_free_keyblock_cont": [48, 115, 125, 126, 181], "krb5_free_keytab_entry_cont": [48, 311, 312], "krb5_free_str": [48, 143, 169, 194], "krb5_free_ticket": [48, 183, 361, 365], "krb5_free_unparsed_nam": [48, 408, 410], "krb5_get_etype_info": [48, 925], "s2kparam": 48, "krb5_get_permitted_enctyp": 48, "krb5_get_server_rcach": 48, "krb5_get_time_offset": 48, "krb5_init_context_profil": [48, 925], "krb5_init_creds_fre": [48, 277], "krb5_init_creds_get": [48, 274, 276, 277], "krb5_init_creds_get_cr": [48, 273], "krb5_init_creds_get_error": 48, "krb5_init_creds_get_tim": 48, "krb5_init_creds_init": [48, 272, 273, 281, 354], "krb5_init_creds_set_keytab": 48, "krb5_init_creds_set_password": 48, "krb5_init_creds_set_servic": 48, "krb5_init_creds_step": [48, 274, 276, 277, 925], "krb5_init_keyblock": 48, "krb5_is_referral_realm": 48, "krb5_referral_realm": [48, 795], "krb5_kdc_sign_ticket": [48, 342, 343], "signatur": [48, 414, 481, 482, 487, 911, 931, 941], "krb5_kdc_verify_ticket": 48, "krb5_kt_add_entri": 48, "krb5_kt_end_seq_get": [48, 320], "krb5_kt_get_entri": 48, "krb5_kt_have_cont": 48, "krb5_kt_next_entri": 48, "krb5_kt_read_service_kei": 48, "krb5_kt_remove_entri": 48, "krb5_kt_start_seq_get": [48, 310], "krb5_make_authdata_kdc_issu": 48, "krb5_marshal_credenti": 48, "krb5_merge_authdata": 48, "krb5_mk_1cred": 48, "krb5_mk_error": 48, "krb_error": [48, 377], "krb5_mk_ncred": [48, 325], "krb5_mk_priv": [48, 79], "priv": [48, 925], "krb5_mk_rep": 48, "krb_ap_rep": 48, "krb5_mk_rep_dc": 48, "krb5_mk_req": [48, 80, 81, 332], "krb_ap_req": 48, "krb5_mk_req_extend": [48, 331], "krb5_mk_safe": [48, 328], "krb5_os_localaddr": 48, "krb5_pac_add_buff": 48, "krb5_pac_fre": [48, 340, 341], "krb5_pac_get_buff": 48, "krb5_pac_get_typ": 48, "krb5_pac_init": 48, "krb5_pac_pars": 48, "krb5_pac_sign": 48, "krb5_pac_sign_ext": 48, "krb5_pac_verifi": [48, 345], "krb5_pac_verify_ext": [48, 303], "krb5_pac_get_client_info": [48, 925], "krb5_prepend_error_messag": [48, 419, 925], "krb5_principal2salt": 48, "krb5_rd_cred": [48, 327], "krb5_rd_error": 48, "krb5_rd_priv": [48, 79, 881], "krb5_rd_rep": 48, "krb5_rd_rep_dc": 48, "krb5_rd_req": 48, "krb5_rd_safe": [48, 881], "krb5_read_password": 48, "krb5_salttype_to_str": 48, "krb5_server_decrypt_ticket_keytab": 48, "krb5_set_default_tgs_enctyp": [48, 263], "krb5_set_error_messag": 48, "krb5_set_kdc_recv_hook": 48, "post": [48, 903, 943], "hook": [48, 871, 872, 925, 933], "krb5_set_kdc_send_hook": 48, "krb5_set_real_tim": 48, "krb5_string_to_cksumtyp": 48, "krb5_string_to_deltat": 48, "krb5_string_to_enctyp": 48, "krb5_string_to_salttyp": 48, "krb5_string_to_timestamp": 48, "krb5_timeofdai": 48, "krb5_timestamp_to_sfstr": 48, "krb5_timestamp_to_str": 48, "krb5_tkt_creds_fre": [48, 405], "krb5_tkt_creds_get": [48, 403, 404, 405], "krb5_tkt_creds_get_cr": [48, 402], "krb5_tkt_creds_get_tim": 48, "krb5_tkt_creds_init": [48, 402], "krb5_tkt_creds_step": [48, 403, 404, 405], "krb5_unmarshal_credenti": 48, "deseri": 48, "krb5_vprepend_error_messag": 48, "va_list": [48, 92, 94], "krb5_vset_error_messag": 48, "krb5_vwrap_error_messag": 48, "krb5_wrap_error_messag": [48, 421, 925], "krb5_c_block_siz": 48, "krb5_c_checksum_length": [48, 168], "krb5_c_crypto_length": 48, "krb5_c_crypto_length_iov": 48, "iov": [48, 100, 103, 290, 292, 833, 925], "krb5_c_decrypt": [48, 289], "krb5_c_decrypt_iov": [48, 103, 290], "aead": 48, "krb5_c_derive_prfplu": [48, 925], "6113": [48, 674, 681, 682, 683, 916, 917, 925, 929], "prf": [48, 118, 917, 925], "krb5_c_encrypt": 48, "krb5_c_encrypt_iov": [48, 292], "krb5_c_encrypt_length": [48, 102, 291], "krb5_c_enctype_compar": 48, "krb5_c_free_stat": 48, "krb5_c_init_st": 48, "krb5_c_fx_cf2_simpl": 48, "fx": [48, 917, 925, 938], "cf2": 48, "pepper": 48, "krb5_c_is_coll_proof_cksum": 48, "collis": [48, 907], "proof": [48, 946], "krb5_c_is_keyed_cksum": 48, "krb5_c_keyed_checksum_typ": 48, "usabl": 48, "krb5_c_keylength": [48, 124], "krb5_c_make_checksum": [48, 131, 296], "krb5_c_make_checksum_iov": [48, 130, 297], "krb5_c_make_random_kei": 48, "krb5_c_padding_length": 48, "octet": 48, "krb5_c_prf": [48, 119, 298], "pseudo": [48, 909], "krb5_c_prfplu": [48, 925], "krb5_c_prf_length": [48, 117], "krb5_c_random_add_entropi": 48, "krb5_c_random_make_octet": 48, "krb5_c_random_os_entropi": 48, "krb5_c_random_to_kei": 48, "krb5_c_string_to_kei": [48, 126, 395], "krb5_c_string_to_key_with_param": 48, "krb5_c_valid_cksumtyp": 48, "krb5_c_valid_enctyp": 48, "krb5_c_verify_checksum": [48, 113, 296, 300, 415], "krb5_c_verify_checksum_iov": [48, 114, 301], "krb5_cksumtype_to_str": 48, "krb5_decode_authdata_contain": [48, 189], "krb5_decode_ticket": 48, "asn": [48, 917, 919, 928], "krb5_deltat_to_str": 48, "krb5_encode_authdata_contain": [48, 184], "krb5_enctype_to_nam": 48, "krb5_enctype_to_str": 48, "krb5_free_checksum": [48, 175], "krb5_free_checksum_cont": [48, 113, 296], "krb5_free_cksumtyp": [48, 111], "krb5_free_tgt_cr": [48, 356], "krb5_k_create_kei": 48, "krb5_kei": [48, 68, 73, 77, 87, 89, 289, 290, 291, 292, 293, 296, 297, 298, 299, 300, 301, 810], "krb5_k_decrypt": 48, "opaqu": [48, 288, 853, 918, 925], "krb5_k_decrypt_iov": [48, 292], "krb5_k_encrypt": 48, "krb5_k_encrypt_iov": [48, 290], "krb5_k_free_kei": [48, 68, 73, 77, 288], "decrement": 48, "hit": [48, 953], "krb5_k_key_enctyp": 48, "krb5_k_key_keyblock": 48, "krb5_k_make_checksum": [48, 113], "krb5_k_make_checksum_iov": [48, 114, 301], "krb5_k_prf": 48, "krb5_k_reference_kei": 48, "krb5_k_verify_checksum": [48, 129], "krb5_k_verify_checksum_iov": [48, 130, 297], "krb5_recvauth": [48, 366, 377], "krb5_recvauth_vers": 48, "krb5_524_convert_cr": [48, 796], "krb5_auth_con_getlocalsubkei": 48, "krb5_auth_con_getremotesubkei": 48, "krb5_auth_con_initivector": 48, "krb5_build_principal_va": 48, "krb5_c_random_se": 48, "krb5_calculate_checksum": 48, "krb5_checksum_s": 48, "krb5_encrypt": 48, "krb5_decrypt": 48, "krb5_eblock_enctyp": 48, "krb5_encrypt_s": 48, "krb5_finish_kei": 48, "krb5_finish_random_kei": 48, "krb5_cc_gen_new": 48, "krb5_get_credentials_renew": 48, "krb5_get_credentials_valid": 48, "krb5_get_in_tkt_with_password": 48, "krb5_get_in_tkt_with_skei": 48, "krb5_get_in_tkt_with_keytab": 48, "krb5_get_init_creds_opt_init": 48, "krb5_init_random_kei": 48, "krb5_kt_free_entri": [48, 316], "krb5_random_kei": 48, "krb5_process_kei": 48, "krb5_string_to_kei": 48, "krb5_use_enctyp": 48, "krb5_verify_checksum": 48, "param": [49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422], "retval": [49, 50, 51, 53, 55, 56, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 111, 112, 113, 114, 115, 116, 117, 118, 121, 124, 125, 126, 129, 130, 132, 133, 134, 135, 137, 139, 141, 142, 145, 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 169, 170, 172, 173, 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, 185, 187, 189, 192, 193, 215, 218, 224, 225, 229, 231, 233, 237, 238, 240, 250, 262, 263, 264, 266, 267, 268, 269, 270, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 284, 287, 288, 289, 290, 291, 292, 296, 297, 298, 300, 301, 302, 303, 304, 305, 306, 307, 308, 310, 312, 313, 315, 316, 317, 318, 319, 320, 321, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 337, 338, 339, 340, 341, 344, 346, 347, 349, 350, 351, 352, 354, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 375, 376, 377, 378, 379, 380, 384, 385, 386, 387, 389, 391, 392, 393, 394, 396, 397, 398, 399, 400, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 416, 930], "krb5_const_princip": [50, 56, 57, 141, 155, 182, 285, 302, 303, 312, 322, 342, 343, 344, 345, 349, 350, 351, 352, 361, 364, 390, 408, 409, 410, 411, 810], "inst": 50, "krb5_invalid_princip": 50, "krb5_config_cantopen": 50, "v5cred": 51, "v4cred": 51, "krb524_krb4_disabl": 51, "krb5_boolean": [52, 54, 55, 105, 109, 110, 127, 128, 129, 130, 160, 192, 255, 285, 286, 287, 300, 301, 302, 321, 343, 345, 350, 351, 352, 364, 390, 810, 832, 844, 866], "krb5_address": [52, 53, 54, 64, 82, 84, 172, 198, 234, 235, 236, 242, 334, 810, 830, 831, 832, 838, 839, 846, 852], "addr1": [52, 53], "addr2": [52, 53], "greater": 53, "addr": [54, 234, 235, 236, 334, 831, 832, 838], "addrlist": 54, "netbio": 54, "aklog": 55, "anam": [56, 953], "lnsize_in": 56, "lname": [56, 953], "krb5_lname_notran": 56, "small": 56, "krb5_config_notenufspac": [56, 308], "krb5_anonymous_princstr": [57, 795], "krb5_anonymous_realmstr": [58, 795], "appnam": [59, 60], "default_valu": [59, 60], "ret_valu": [59, 60], "auth_context": [61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 90, 224, 325, 327, 328, 329, 330, 331, 332, 333, 356, 358, 359, 360, 361, 362, 365, 366, 377], "infd": 62, "descriptor": [62, 365, 366, 377], "krb5_auth_context_generate_local_addr": [62, 795], "krb5_auth_context_generate_remote_addr": [62, 795], "krb5_auth_context_generate_local_full_addr": [62, 795], "krb5_auth_context_generate_remote_full_addr": [62, 795], "krb5_mk_req_checksum_func": [63, 80, 810], "func": [63, 80], "krb5_int32": [66, 69, 74, 83, 268, 365, 366, 376, 387, 391, 396, 412, 810, 812, 814, 818, 819, 825, 827, 830, 834, 836, 838, 841, 842, 843, 845, 852, 857, 860, 873, 874, 875, 877, 881, 885, 887, 888, 891, 897], "mask": [66, 83, 142, 153, 157, 918], "krb5_auth_context_do_tim": [66, 78, 83, 327, 328, 333, 358, 362, 795], "krb5_auth_context_ret_tim": [66, 83, 327, 328, 333, 356, 358, 362, 795], "krb5_auth_context_do_sequ": [66, 69, 74, 83, 327, 328, 329, 333, 358, 362, 795], "krb5_auth_context_ret_sequ": [66, 83, 327, 328, 329, 333, 356, 358, 362, 795], "seqnumb": [69, 74], "krb5_rcach": [71, 85, 267, 810], "ac": [72, 73, 76, 77, 86, 87, 88, 89], "krb5_cksumtyp": [81, 96, 109, 110, 111, 113, 114, 127, 130, 131, 168, 170, 204, 296, 297, 301, 392, 415, 810, 824], "cksumtyp": [81, 96, 111, 113, 114, 130, 170, 296, 297, 301], "local_port": 84, "remote_port": 84, "haddl": 85, "relinquish": 85, "unsign": [91, 92, 93, 94, 97, 111, 116, 120, 281, 313, 363, 406, 409, 411, 811, 817, 820, 824, 835, 854, 859, 863, 865, 897, 902, 918], "rlen": [91, 92, 93, 94], "infer": [91, 93, 346], "krb5_nt_srv_inst": [91, 93, 346, 795], "krb5_nt_wellknown": [91, 93, 346, 795], "krb5_nt_princip": [91, 93, 346, 795], "variad": [91, 419, 421], "vararg": 91, "ap": [92, 94, 195, 199, 329, 330, 331, 332, 359, 360, 361, 508, 813], "dealloc": [92, 932, 939], "krb5_enctyp": [95, 97, 98, 101, 104, 105, 111, 112, 115, 116, 118, 124, 125, 126, 128, 188, 191, 192, 193, 212, 231, 234, 235, 236, 246, 263, 282, 294, 312, 317, 380, 394, 413, 810, 837, 840, 846, 852, 854], "size_t": [95, 96, 98, 100, 103, 104, 112, 114, 116, 118, 130, 131, 168, 170, 186, 187, 190, 191, 192, 193, 282, 290, 292, 297, 301, 339, 341, 371, 376, 399, 400, 415], "blocksiz": 95, "krb5_cryptotyp": [97, 810, 833], "krb5_crypto_typ": [97, 833], "macro": [97, 99, 100, 102, 103, 108, 113, 114, 130, 184, 189, 289, 290, 291, 292, 296, 297, 301, 331, 332, 377, 405, 423, 833, 895, 953], "krb5_crypto_iov": [98, 100, 103, 114, 130, 290, 292, 297, 301, 810], "num_data": [98, 100, 103, 114, 130, 290, 292, 297, 301], "inout": [98, 99, 100, 102, 103, 114, 289, 290, 291, 292, 297, 331, 332, 361, 363, 365, 366, 377, 409], "krb5_crypto_type_sign_onli": [98, 114, 130, 297, 301, 795], "krb5_keyusag": [99, 100, 102, 103, 108, 113, 114, 129, 130, 289, 290, 291, 292, 296, 297, 300, 301, 810], "cipher_st": [99, 100, 102, 103, 289, 290, 291, 292], "krb5_enc_data": [99, 102, 289, 291, 810, 813, 815, 829, 851, 852, 889], "let": [99, 289, 940, 959], "trim": [99, 289], "contribut": [101, 107, 119, 923, 926, 960], "enctype_nul": [101, 231, 795], "inputlen": 104, "confound": 104, "e1": 105, "e2": 105, "k1": 107, "pepper1": 107, "k2": 107, "pepper2": 107, "keyexchang": 107, "new_stat": 108, "ctype": [109, 110, 127, 131, 168, 415], "keybyt": 112, "keylength": 112, "cksum": [113, 129, 296, 300, 415], "krb5_crypto_type_checksum": [114, 130, 297, 301, 795], "krb5_crypto_type_data": [114, 130, 297, 301, 795], "chunk": [114, 297], "k5_random_kei": [115, 124], "data_length": 116, "plaintext": [116, 538], "krb5_bad_enctyp": [116, 288], "preiniti": [117, 119, 121, 298], "e2big": 119, "enomem": [119, 224, 233, 304, 325, 327], "4402": 119, "randsourc": 120, "prng": [121, 925], "random_data": 124, "ktype": [128, 234, 235, 236, 263, 852], "krb5_const_point": [131, 186, 190, 415, 810], "in_length": [131, 415], "seed": [131, 333, 415, 922], "seed_length": [131, 415], "outcksum": 131, "krb5_ccach": [132, 133, 134, 135, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 157, 158, 159, 161, 164, 224, 225, 226, 227, 234, 235, 236, 248, 252, 253, 266, 269, 331, 377, 385, 405, 416, 810], "cache_out": [132, 154], "krb5_cc_notfound": [132, 154, 165], "incc": 134, "outcc": 134, "kv5m_context": [135, 156], "magic": [135, 156, 811, 813, 814, 815, 817, 819, 824, 827, 829, 830, 831, 832, 835, 837, 838, 839, 840, 842, 851, 852, 854, 856, 860, 865, 874, 875, 879, 888, 889, 892, 896, 897, 901], "_krb5_context": [135, 156, 828], "krb5_fcc_intern": 135, "recomput": 136, "krb5_cc_cursor": [139, 150, 158, 810], "krb5_flag": [142, 151, 153, 157, 225, 226, 227, 234, 235, 236, 240, 250, 271, 331, 332, 361, 377, 405, 810, 815, 831, 832, 838, 839, 846, 852, 885, 892, 900], "fullname_out": 143, "dst": 148, "reiniti": [148, 925], "unus": [149, 267, 354, 377, 925], "krb5_end_seq_get": 150, "bitwis": [151, 746], "ORed": 151, "krb5_cc_nosupp": 151, "mcred": 153, "krb5_tc_match_tim": [153, 795], "krb5_tc_match_is_skei": [153, 795], "is_skei": [153, 755, 832, 916], "krb5_tc_match_flag": [153, 795], "krb5_tc_match_times_exact": [153, 795], "krb5_tc_match_flags_exact": [153, 795], "krb5_tc_match_authdata": [153, 795], "krb5_tc_match_srv_nameonli": [153, 795], "krb5_tc_match_2nd_tkt": [153, 795], "krb5_tc_match_ktyp": [153, 795], "krb5_tc_supported_ktyp": [153, 795], "princ_out": 154, "fatal": 154, "krb5_cccol_cursor": [162, 163, 164, 810], "newpw": [166, 384, 385], "result_cod": [166, 384, 385], "result_code_str": [166, 384, 385], "result_str": [166, 169, 384, 385], "krb5_kpasswd_success": [166, 384, 795], "krb5_kpasswd_malform": [166, 795], "malform": [166, 224, 625, 916], "krb5_kpasswd_harderror": [166, 795], "krb5_kpasswd_autherror": [166, 795], "krb5_kpasswd_softerror": [166, 795], "krb5krb_ap_err_skew": 167, "server_str": 169, "message_out": 169, "display": 169, "human": [169, 904, 925], "buflen": [170, 187, 192, 193, 376, 399, 400], "mistakenli": 171, "occurr": 171, "inaddr": 172, "outaddr": 172, "krb5_authdata": [173, 184, 189, 195, 200, 322, 324, 414, 810, 819, 832, 839, 852], "in_authdat": 173, "authfrom": 174, "authto": 174, "ckfrom": 175, "ckto": 175, "nctx_out": 176, "incr": 177, "outcr": 177, "indata": 178, "outdata": 178, "dest_ctx": 179, "src_ctx": 179, "inprinc": 182, "outprinc": 182, "pto": 183, "krb5_authdatatyp": [184, 189, 195, 810, 817], "authdata": [184, 189, 225, 322, 324, 414, 832, 916, 925, 933, 949, 950], "rep": [185, 199, 329, 330, 359, 360, 813, 838, 851, 866], "inptr": [186, 190], "krb5_pointer": [186, 190, 197, 283, 317, 355, 365, 366, 377, 810, 821, 858], "outptr": [186, 190], "krb5_encrypt_block": [186, 188, 190, 196, 197, 283, 353, 355, 395, 413, 810], "eblock": [186, 188, 190, 196, 197, 283, 353, 355, 395, 413], "ivec": [186, 190], "krb5_c_": [186, 188, 190, 191, 196, 197, 283, 353, 355, 413], "krb5_deltat": [187, 237, 258, 261, 262, 277, 393, 810, 846], "deltat": 187, "shortest": 192, "canonhost_out": 194, "orig_hostnam": 194, "ticket_authdata": 195, "ap_req_authdata": 195, "ad_typ": [195, 817, 916], "IF": [195, 302, 926], "val": [198, 199, 200, 201, 202, 203, 204, 207, 208, 209, 210, 212, 213, 216, 219, 220, 222, 223], "lrealm": [211, 229, 379], "krb5_error": [213, 275, 326, 357, 377, 795, 810], "msg": 214, "realmlist": 215, "krb5_keytab_entri": [218, 304, 311, 312, 316, 318, 810], "rhost": 224, "cc": [224, 912, 926, 952], "outbuf": [224, 329, 330, 331, 332], "insuffici": [224, 233, 304, 325, 327, 912], "krb5_princ_nomatch": [224, 269], "krb5_no_tkt_suppli": [224, 269], "krb5_cc_badnam": 224, "krb5_nt_srv_hst": [224, 391, 795], "in_cr": [225, 226, 227, 323, 332, 377], "out_cr": [225, 226, 227, 377], "krb5_gc_cach": [225, 795], "krb5_gc_user_us": [225, 795], "endtim": [225, 890, 916], "uncondition": [230, 912], "enctype_out": 231, "salt_out": 231, "s2kparams_out": 231, "hdata": 232, "realmsp": [232, 233], "krb5_preauthtyp": [234, 235, 236, 256, 810, 846, 865], "pre_auth_typ": [234, 235, 236], "krb5_keytab": [234, 237, 278, 304, 305, 306, 307, 309, 310, 312, 313, 314, 315, 316, 318, 319, 320, 361, 365, 366, 378, 416, 810], "arg_keytab": [234, 237], "krb5_kdc_rep": [234, 235, 236, 810], "ret_as_repli": [234, 235, 236], "krb5_get_init_cr": [236, 252, 253], "start_tim": [237, 262, 277, 949], "in_tkt_servic": [237, 262, 266, 269], "k5_gic_opt": [237, 262], "out_flag": 240, "react": 245, "etype_list": [246, 846], "etype_list_length": [246, 846], "krb5_expire_callback_func": [247, 810], "cb": 247, "is_last_req": [247, 844], "unambigu": 247, "password_expir": [247, 844], "account_expir": [247, 844], "prompter": [247, 262, 265, 277, 354, 876, 878, 883], "fast_ccache_nam": 249, "krb5_fast_requir": [250, 795], "sensit": 252, "simplifi": [253, 925], "attr": [254, 847], "req_pac": 255, "pa": [255, 917, 918, 919, 938], "item": [255, 737, 930, 938], "preauth_list": [256, 846], "preauth_list_length": [256, 846], "renew_lif": [258, 846], "krb5_responder_fn": [259, 810, 882], "tkt_life": [261, 846], "krb5_prompter_fct": [262, 277, 810], "einval": [262, 375, 392, 394, 396, 397], "krb5_kdc_unreach": 262, "krb5_preauth_fail": 262, "athent": 262, "krb5_libos_pwdintr": 262, "krb5_realm_cant_resolv": 262, "krb5kdc_err_key_exp": 262, "krb5_libos_badpwdmatch": [262, 363], "krb5_chpw_pwdnull": 262, "krb5_chpw_fail": 262, "_profile_t": [264, 271], "profile_releas": 264, "krb5_prompt_typ": [265, 810], "krb5_prompt_type_password": [265, 795], "krb5_prompt_type_new_password": [265, 795], "krb5_prompt_type_new_password_again": [265, 795], "krb5_prompt_type_preauth": [265, 795], "rcptr": 267, "krb5_rc_close": 267, "microsecond": [268, 387, 412, 814, 830, 881, 916], "krb5_no_2nd_tkt": 269, "miss": [269, 914], "krb5_kdcrep_modifi": 269, "krb5_kdcrep_skew": 269, "krb5_init_context_secur": [271, 795], "krb5_init_context_kdc": [271, 795], "krb5_init_creds_context": [272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 810], "krb5_ticket_tim": [276, 404, 810, 831, 832, 838, 839], "krb5_init_creds_step_flag_continu": [281, 795], "krb5krb_err_response_too_big": [281, 406], "legal": [282, 953], "unalloc": 282, "threadsaf": 287, "key_data": [288, 295, 918], "krb5_enc_tkt_part": [302, 303, 810, 889], "enc_tkt": [302, 303], "krb5_pac": [302, 303, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 810], "server_princ": [302, 303], "privsvr": [302, 303, 344, 345], "with_realm": [302, 343, 345], "pac_client_info": [302, 303, 338, 345], "pac_out": 303, "krb5_kt_nowrit": [304, 318], "writeabl": 304, "keytab_out": 305, "name_s": 308, "krb5_kt_cursor": [310, 316, 320, 810], "krb5_kvno": [312, 317, 810, 837, 856], "namelen": 313, "krb5_kt_name_toolong": 313, "fit": [313, 926], "krb5_kt_notfound": 315, "krb5_kt_end": 316, "keyprocarg": 317, "ktid": 319, "luser": 321, "ad_kdcissu": [322, 414], "4120": [322, 414, 545, 670, 675, 676, 677, 678, 679, 684, 686, 697, 704, 707, 711, 907, 925, 929], "data_out": 323, "vesion": [323, 407], "inauthdat1": 324, "inauthdat2": 324, "outauthdat": 324, "der_out": [325, 327, 328, 333], "krb5_replay_data": [325, 327, 328, 333, 356, 358, 362, 810], "rdata_out": [325, 327, 328, 333, 356, 358, 362], "krb5_rc_requir": [325, 327], "dec_err": 326, "enc_err": 326, "sender": [327, 328, 333, 358, 362, 830], "userdata": [328, 333], "krb5_generate_seq_numb": 329, "ap_req_opt": [331, 332, 361, 377], "in_data": [331, 332, 377], "ap_opt": [331, 332, 377, 815, 892], "ap_opts_use_session_kei": [332, 795], "ap_opts_mutual_requir": [332, 361, 377, 795], "ap_opts_use_subkei": [332, 795], "krb5_ui_4": [335, 337, 339, 360, 810, 814, 819, 842, 881], "krb5_pac_logon_info": [335, 795], "krb5_pac_credentials_info": [335, 795], "krb5_pac_server_checksum": [335, 795], "krb5_pac_privsvr_checksum": [335, 795], "krb5_pac_client_info": [335, 795], "krb5_pac_delegation_info": [335, 795], "krb5_pac_upn_dns_info": [335, 795], "authtime_out": 338, "princname_out": 338, "enoent": 338, "erang": 338, "authtim": [342, 343, 344, 345, 890, 916], "server_kei": [342, 343], "privsvr_kei": [342, 343], "principal_out": [346, 347], "slash": [346, 960], "backslash": 346, "newlin": [346, 354], "backspac": 346, "b": [346, 925], "krb5_principal_parse_no_realm": [347, 795], "krb5_principal_parse_require_realm": [347, 795], "krb5_principal_parse_enterpris": [347, 795], "krb5_principal_parse_ignore_realm": [347, 795], "fmt": [348, 381, 419, 420, 421, 422], "pr": [349, 909], "krb5_principal_compare_ignore_realm": [352, 795], "krb5_principal_compare_enterpris": [352, 795], "krb5_principal_compare_casefold": [352, 795], "krb5_principal_compare_utf8": [352, 795], "num_prompt": [354, 878], "krb5_prompt": [354, 810, 878], "stdin": 354, "echo": [354, 363], "creddata": 356, "creds_out": [356, 407], "enc_errbuf": 357, "dec_error": 357, "inbuf": [358, 359, 360, 361, 362], "userdata_out": [358, 362], "repl": 359, "nonc": [360, 830, 838, 852, 925], "prompt2": 363, "return_pwd": 363, "size_return": 363, "fd": [365, 366, 377], "appl_vers": [365, 377], "recvauth": [365, 377], "printabl": [367, 375], "main": [370, 373, 918, 943], "ti": [371, 936], "pin": [371, 374, 734, 737, 741, 742, 743, 744, 876], "tokeninfo": [371, 744, 884], "chl_out": 373, "rep_result": 377, "kt": 378, "enc_part2": [378, 829, 851, 889], "krb5_prog_etype_nosupp": 380, "krb5_post_recv_fn": [382, 810], "recv_hook": 382, "synthet": [382, 916], "krb5_pre_send_fn": [383, 810], "send_hook": 383, "synthes": [383, 871], "change_password_for": [384, 385], "3244": [384, 385, 925], "nonnul": 385, "krb5_trace_callback": [388, 810, 895], "fn": 388, "cb_data": [388, 894], "krb5_trace_nosupp": [388, 389], "krb5_trace_info": [388, 810, 894], "former": 390, "latter": [390, 903], "sname": [391, 955], "ret_princ": 391, "krb5_nt_unknown": [391, 795], "cksumtypep": 392, "deltatp": 393, "krb5_deltat_badformat": 393, "enctypep": 394, "salttypep": 396, "timestampp": 397, "timeret": 398, "krb5_tkt_creds_context": [401, 402, 403, 404, 405, 406, 810], "krb5_gc": 405, "asynchron": [405, 938], "krb5_tkt_creds_step_flag_continu": [406, 795], "resiz": 409, "krb5_principal_unparse_short": [410, 795], "krb5_principal_unparse_no_realm": [410, 795], "krb5_principal_unparse_displai": [410, 795], "timeofdai": 412, "authdatum": 414, "demand": 416, "k5_vic_opt": [417, 418], "ap_req_nofail": [418, 900], "vprintf": [419, 420, 421], "old_cod": [421, 422], "0x0100": [424, 560], "0x0005": [425, 474], "0x0010": [426, 453, 475, 561], "0x0003": [427, 460, 478], "0x0002": [428, 459, 477, 565, 731, 734], "0x0018": [429, 469], "0x0101": 430, "0x0007": [431, 461], "addrtyp": [432, 811, 916], "0x8000": [432, 434, 439, 771, 773], "0x0014": [433, 456, 467], "0x0001": [434, 449, 476, 549, 567, 732, 735, 768], "0x0006": [435, 473], "0x4000": 436, "0x1fff": 437, "0x2000": 438, "0x00000004": [440, 526, 529, 753], "0x00000002": [441, 499, 530, 534, 755, 760], "0x20000000": [442, 495, 748, 781], "0x80000000": [443, 750], "0x40000000": [444, 494, 749, 780], "0x00000001": [445, 503, 527, 528, 758, 761], "0xfffffff0": 446, "6803": [447, 448, 470, 471, 925], "0x0011": [447, 464], "0x0012": [448, 466], "0x0004": [450, 479, 562, 736], "138": [451, 674], "3962": [452, 453, 464, 466], "enctype_aes128_cts_hmac_sha1_96": [452, 795], "0x000f": [452, 472], "enctype_aes256_cts_hmac_sha1_96": [453, 795], "0x000c": [454, 484], "8009": [455, 456, 465, 467], "0x0013": [455, 465], "137": [457, 682], "netlogon": 457, "0x0009": [458, 481], "0x0008": [462, 480, 564, 737], "3961": [463, 670, 917, 919, 922], "0x000e": [463, 486], "0x0017": 468, "0x0019": 470, "0x001a": 471, "cm": [472, 481, 482, 484, 485, 486, 487, 925], "envelop": [472, 484, 485, 486], "dsa": 481, "0x000a": 482, "0x0000": 483, "rc2": 484, "0x000d": 485, "oeap": 486, "0x000b": 487, "0x01ff": 488, "0x04000000": [489, 785], "0x00010000": [490, 779], "0x00020000": 491, "0x00000020": [492, 535, 752], "0x00000008": [493, 531, 533, 759], "0x02000000": [496, 787], "0x10000000": [497, 789], "0x08000000": [498, 790], "0x00800000": [500, 791], "0x00008000": [502, 778], "0x54800000": 504, "64": [505, 522, 552, 587, 891, 902], "krb5_msgtype": [508, 509, 510, 511, 536, 548, 724, 747, 765, 766, 810, 838, 851, 852], "143": 513, "97": 514, "4537": 516, "129": [516, 646, 680], "71": 517, "65": [523, 613], "mic": [537, 925], "decompos": 543, "cybersaf": [545, 926], "149": 547, "0x0020": 557, "0x0400": 558, "0x0200": 559, "0x0040": 563, "0x0080": 566, "0x2": [568, 720, 722, 725], "0x1": [569, 570, 719, 723, 727, 767], "65535": [571, 925], "krb5_int16_max": [572, 795], "2147483647": [573, 904], "krb5_int32_max": [574, 795], "54": 588, "55": 589, "51": 590, "53": 591, "50": 593, "41": 594, "514": [604, 919], "cooki": [605, 920, 925, 938], "513": [605, 917], "6560": [606, 687, 688, 689, 744, 925], "45": 606, "44": 607, "27": [608, 612, 904], "25": [610, 700, 946], "nt": [644, 646], "130": [644, 701], "smtp": 648, "rcommand": 649, "claim": [657, 661, 926], "requestor": 666, "cygnu": [670, 926], "132": 672, "8070": [673, 919], "150": 673, "securid": [675, 925], "passcod": 675, "133": 681, "136": 683, "embed": 684, "osf": 686, "141": 687, "144": 688, "142": 689, "kile": 690, "sfu": 690, "167": 690, "6112": [692, 925], "147": 692, "red": [698, 699, 926, 960], "hat": [698, 699, 926, 960], "idp": 698, "152": 698, "passkei": 699, "153": 699, "draft": [700, 703, 706, 925], "sam": [702, 704, 705, 925], "151": [708, 917], "6820": 709, "krb5_padata_ap_req": [710, 795], "principl": 716, "0x4": [716, 721, 728], "0x8": 717, "0x10": 718, "escap": 721, "0x3": 726, "krb5_responder_otp_flags_collect_pin": [737, 795], "concaten": [737, 917, 931], "vendor": [744, 885, 952], "tokenid": 744, "algid": 744, "OR": [746, 926], "krb5_responder_pkinit_flags_token_": 746, "resembl": 746, "ckf_": 746, "0x00000080": 751, "0x00000100": 756, "0x00000040": 757, "0x00000200": 762, "nt_wellknown": 769, "0x7fff": [770, 774], "maxpathlen": 772, "1100": 772, "uint_max": [775, 776, 794], "z": [777, 904, 953], "0x00100000": 782, "0x00400000": 783, "0x01000000": 784, "0x00040000": 786, "0x00200000": 788, "0x00080000": 792, "int_max": 793, "addrtype_addrport": 795, "addrtype_chao": 795, "addrtype_direct": 795, "addrtype_ddp": 795, "addrtype_inet": 795, "addrtype_inet6": 795, "addrtype_ipport": 795, "addrtype_iso": 795, "addrtype_is_loc": 795, "addrtype_netbio": 795, "addrtype_xn": 795, "addrtype_unixsock": 795, "ad_type_extern": 795, "ad_type_field_type_mask": 795, "ad_type_regist": 795, "ad_type_reserv": 795, "ap_opts_etype_negoti": 795, "ap_opts_cbt_flag": 795, "ap_opts_reserv": 795, "ap_opts_wire_mask": 795, "cksumtype_cmac_camellia128": 795, "cksumtype_cmac_camellia256": 795, "cksumtype_crc32": 795, "cksumtype_descbc": 795, "cksumtype_hmac_md5_arcfour": 795, "cksumtype_hmac_sha1_96_aes128": 795, "cksumtype_hmac_sha1_96_aes256": 795, "cksumtype_hmac_sha256_128_aes128": 795, "cksumtype_hmac_sha384_192_aes256": 795, "cksumtype_hmac_sha1_des3": 795, "cksumtype_md5_hmac_arcfour": 795, "cksumtype_nist_sha": 795, "cksumtype_rsa_md4": 795, "cksumtype_rsa_md4_d": 795, "cksumtype_rsa_md5": 795, "cksumtype_rsa_md5_d": 795, "cksumtype_sha1": 795, "enctype_aes128_cts_hmac_sha256_128": 795, "enctype_aes256_cts_hmac_sha384_192": 795, "enctype_arcfour_hmac": 795, "enctype_arcfour_hmac_exp": 795, "enctype_camellia128_cts_cmac": 795, "enctype_camellia256_cts_cmac": 795, "enctype_des3_cbc_env": 795, "enctype_des3_cbc_raw": 795, "enctype_des3_cbc_sha": 795, "enctype_des3_cbc_sha1": 795, "enctype_des_cbc_crc": 795, "enctype_des_cbc_md4": 795, "enctype_des_cbc_md5": 795, "enctype_des_cbc_raw": 795, "enctype_des_hmac_sha1": 795, "enctype_dsa_sha1_cm": 795, "enctype_md5_rsa_cm": 795, "enctype_rc2_cbc_env": 795, "enctype_rsa_env": 795, "enctype_rsa_es_oaep_env": 795, "enctype_sha1_rsa_cm": 795, "enctype_unknown": 795, "kdc_opt_allow_postd": 795, "kdc_opt_canonic": 795, "kdc_opt_cname_in_addl_tkt": 795, "kdc_opt_disable_transited_check": 795, "kdc_opt_enc_tkt_in_skei": 795, "kdc_opt_forward": 795, "kdc_opt_postd": 795, "kdc_opt_proxi": 795, "kdc_opt_renew": 795, "kdc_opt_request_anonym": 795, "kdc_opt_valid": 795, "kdc_tkt_common_mask": 795, "krb5_altauth_att_challenge_respons": 795, "krb5_ap_rep": [795, 810], "krb5_ap_req": [795, 810], "krb5_as_rep": [795, 851], "krb5_as_req": [795, 852], "krb5_authdata_and_or": 795, "krb5_authdata_ap_opt": 795, "krb5_authdata_auth_ind": 795, "krb5_authdata_cammac": 795, "krb5_authdata_etype_negoti": 795, "krb5_authdata_fx_armor": 795, "krb5_authdata_if_relev": 795, "krb5_authdata_initial_verified_ca": 795, "krb5_authdata_kdc_issu": 795, "krb5_authdata_mandatory_for_kdc": 795, "krb5_authdata_osf_dc": 795, "krb5_authdata_sesam": 795, "krb5_authdata_signticket": 795, "krb5_authdata_win2k_pac": 795, "krb5_auth_context_permit_al": 795, "krb5_auth_context_use_subkei": 795, "krb5_crypto_type_empti": 795, "krb5_crypto_type_head": 795, "krb5_crypto_type_pad": 795, "krb5_crypto_type_stream": 795, "krb5_crypto_type_trail": 795, "krb5_cybersafe_secureid": 795, "krb5_domain_x500_compress": 795, "krb5_encpadata_req_enc_pa_rep": 795, "krb5_gc_canonic": 795, "krb5_gc_constrained_deleg": 795, "krb5_gc_forward": 795, "krb5_gc_no_stor": 795, "krb5_gc_no_transit_check": 795, "krb5_get_init_creds_opt_address_list": 795, "krb5_get_init_creds_opt_anonym": 795, "krb5_get_init_creds_opt_canonic": 795, "krb5_get_init_creds_opt_chg_pwd_prmpt": 795, "krb5_get_init_creds_opt_etype_list": 795, "krb5_get_init_creds_opt_forward": 795, "krb5_get_init_creds_opt_preauth_list": 795, "krb5_get_init_creds_opt_proxi": 795, "krb5_get_init_creds_opt_renew_lif": 795, "krb5_get_init_creds_opt_salt": 795, "krb5_get_init_creds_opt_tkt_lif": 795, "krb5_int16_min": 795, "krb5_int32_min": 795, "krb5_keyusage_ad_it": 795, "krb5_keyusage_ad_kdcissued_cksum": 795, "krb5_keyusage_ad_mt": 795, "krb5_keyusage_ad_signedpath": 795, "krb5_keyusage_app_data_cksum": 795, "krb5_keyusage_app_data_encrypt": 795, "krb5_keyusage_ap_rep_encpart": 795, "krb5_keyusage_ap_req_auth": 795, "krb5_keyusage_ap_req_auth_cksum": 795, "krb5_keyusage_as_rep_encpart": 795, "krb5_keyusage_as_req": 795, "krb5_keyusage_as_req_pa_enc_t": 795, "krb5_keyusage_cammac": 795, "krb5_keyusage_enc_challenge_cli": 795, "krb5_keyusage_enc_challenge_kdc": 795, "krb5_keyusage_fast_enc": 795, "krb5_keyusage_fast_finish": 795, "krb5_keyusage_fast_rep": 795, "krb5_keyusage_fast_req_chksum": 795, "krb5_keyusage_gss_tok_m": 795, "krb5_keyusage_gss_tok_wrap_integ": 795, "krb5_keyusage_gss_tok_wrap_priv": 795, "krb5_keyusage_finish": 795, "krb5_keyusage_iakerb_finish": 795, "krb5_keyusage_kdc_rep_ticket": 795, "krb5_keyusage_krb_cred_encpart": 795, "krb5_keyusage_krb_error_cksum": 795, "krb5_keyusage_krb_priv_encpart": 795, "krb5_keyusage_krb_safe_cksum": 795, "krb5_keyusage_pa_as_fresh": 795, "krb5_keyusage_pa_fx_cooki": 795, "krb5_keyusage_pa_otp_request": 795, "krb5_keyusage_pa_pkinit_kx": 795, "krb5_keyusage_pa_s4u_x509_user_repli": 795, "krb5_keyusage_pa_s4u_x509_user_request": 795, "krb5_keyusage_pa_sam_challenge_cksum": 795, "krb5_keyusage_pa_sam_challenge_trackid": 795, "krb5_keyusage_pa_sam_respons": 795, "krb5_keyusage_spak": 795, "krb5_keyusage_tgs_rep_encpart_sesskei": 795, "krb5_keyusage_tgs_rep_encpart_subkei": 795, "krb5_keyusage_tgs_req_ad_sesskei": 795, "krb5_keyusage_tgs_req_ad_subkei": 795, "krb5_keyusage_tgs_req_auth": 795, "krb5_keyusage_tgs_req_auth_cksum": 795, "krb5_kpasswd_accessdeni": 795, "krb5_kpasswd_bad_vers": 795, "krb5_kpasswd_initial_flag_need": 795, "krb5_lrq_all_acct_exptim": 795, "krb5_lrq_all_last_initi": 795, "krb5_lrq_all_last_renew": 795, "krb5_lrq_all_last_req": 795, "krb5_lrq_all_last_tgt": 795, "krb5_lrq_all_last_tgt_issu": 795, "krb5_lrq_all_pw_exptim": 795, "krb5_lrq_none": 795, "krb5_lrq_one_acct_exptim": 795, "krb5_lrq_one_last_initi": 795, "krb5_lrq_one_last_renew": 795, "krb5_lrq_one_last_req": 795, "krb5_lrq_one_last_tgt": 795, "krb5_lrq_one_last_tgt_issu": 795, "krb5_lrq_one_pw_exptim": 795, "krb5_nt_enterprise_princip": 795, "krb5_nt_ent_principal_and_id": 795, "krb5_nt_ms_princip": 795, "krb5_nt_ms_principal_and_id": 795, "krb5_nt_smtp_name": 795, "krb5_nt_srv_xhst": 795, "krb5_nt_uid": 795, "krb5_nt_x500_princip": 795, "krb5_pac_attributes_info": 795, "krb5_pac_client_claim": 795, "krb5_pac_device_claim": 795, "krb5_pac_device_info": 795, "krb5_pac_requestor": 795, "krb5_pac_ticket_checksum": 795, "krb5_pac_full_checksum": 795, "krb5_padata_afs3_salt": 795, "krb5_padata_as_checksum": 795, "krb5_padata_as_fresh": 795, "krb5_padata_encrypted_challeng": 795, "krb5_padata_enc_sandia_securid": 795, "krb5_padata_enc_timestamp": 795, "krb5_padata_enc_unix_tim": 795, "krb5_padata_etype_info": 795, "krb5_padata_etype_info2": 795, "krb5_padata_for_us": 795, "krb5_padata_fx_cooki": 795, "krb5_padata_fx_error": 795, "krb5_padata_fx_fast": 795, "krb5_padata_get_from_typed_data": 795, "krb5_padata_non": 795, "krb5_padata_osf_dc": 795, "krb5_padata_otp_challeng": 795, "krb5_padata_otp_pin_chang": 795, "krb5_padata_otp_request": 795, "krb5_padata_pac_opt": 795, "krb5_padata_pac_request": 795, "krb5_padata_pkinit_kx": 795, "krb5_padata_pk_as_rep": 795, "krb5_padata_pk_as_rep_old": 795, "krb5_padata_pk_as_req": 795, "krb5_padata_pk_as_req_old": 795, "krb5_padata_pw_salt": 795, "krb5_padata_referr": 795, "krb5_padata_s4u_x509_us": 795, "krb5_padata_sam_challeng": 795, "krb5_padata_sam_challenge_2": 795, "krb5_padata_sam_redirect": 795, "krb5_padata_sam_respons": 795, "krb5_padata_sam_response_2": 795, "krb5_padata_sesam": 795, "krb5_padata_spak": 795, "krb5_padata_redhat_idp_oauth2": 795, "krb5_padata_redhat_passkei": 795, "krb5_padata_svr_referral_info": 795, "krb5_padata_tgs_req": 795, "krb5_padata_use_specified_kvno": 795, "krb5_principal_parse_no_def_realm": 795, "krb5_priv": 795, "krb5_pvno": 795, "krb5_realm_branch_char": 795, "krb5_recvauth_badauthv": 795, "krb5_recvauth_skip_vers": 795, "krb5_responder_pkinit_flags_token_user_pin_count_low": 795, "krb5_responder_pkinit_flags_token_user_pin_final_tri": 795, "krb5_responder_pkinit_flags_token_user_pin_lock": 795, "krb5_responder_otp_flags_collect_token": 795, "krb5_responder_otp_flags_nextotp": 795, "krb5_responder_otp_flags_separate_pin": 795, "krb5_responder_otp_format_alphanumer": 795, "krb5_responder_otp_format_decim": 795, "krb5_responder_otp_format_hexadecim": 795, "krb5_safe": 795, "krb5_sam_must_pk_encrypt_sad": 795, "krb5_sam_send_encrypted_sad": 795, "krb5_sam_use_sad_as_kei": 795, "krb5_tc_noticket": 795, "krb5_tc_openclos": 795, "krb5_tgs_name": 795, "krb5_tgs_name_s": 795, "krb5_tgs_rep": 795, "krb5_tgs_req": [795, 852], "krb5_verify_init_creds_opt_ap_req_nofail": 795, "krb5_wellknown_namestr": 795, "lr_type_interpretation_mask": 795, "lr_type_this_server_onli": 795, "max_keytab_name_len": 795, "msec_dirbit": 795, "msec_val_mask": 795, "salt_type_afs_length": 795, "salt_type_no_length": 795, "threeparamopen": 795, "tkt_flg_anonym": 795, "tkt_flg_enc_pa_rep": 795, "tkt_flg_forward": 795, "tkt_flg_hw_auth": 795, "tkt_flg_initi": 795, "tkt_flg_invalid": 795, "tkt_flg_may_postd": 795, "tkt_flg_ok_as_deleg": 795, "tkt_flg_postdat": 795, "tkt_flg_pre_auth": 795, "tkt_flg_proxiabl": 795, "tkt_flg_proxi": 795, "tkt_flg_renew": 795, "tkt_flg_transit_policy_check": 795, "valid_int_bit": 795, "valid_uint_bit": 795, "krb5_const": 795, "krb5_princ_compon": 795, "krb5_princ_nam": 795, "krb5_princ_realm": 795, "krb5_princ_set_realm": 795, "krb5_princ_set_realm_data": 795, "krb5_princ_set_realm_length": 795, "krb5_princ_siz": [795, 799], "krb5_princ_typ": 795, "krb5_roundup": 795, "krb5_x": 795, "krb5_xc": 795, "krb524_convert_creds_kdc": 795, "krb524_init_et": 795, "abort": [808, 809, 940], "krb5_addrtyp": [810, 811], "krb5_cred_enc_part": [810, 829], "krb5_cred_info": [810, 830], "krb5_enc_kdc_rep_part": [810, 851], "krb5_gic_opt_pa_data": 810, "krb5_int16": 810, "krb5_kdc_req": 810, "krb5_last_req_entri": [810, 838], "krb5_magic": [810, 811, 813, 814, 815, 817, 819, 824, 827, 829, 830, 831, 832, 835, 837, 838, 839, 840, 842, 851, 852, 854, 856, 860, 865, 874, 875, 879, 888, 889, 892, 896, 897, 901], "krb5_octet": [810, 811, 817, 824, 854, 865, 888, 896, 897], "krb5_pa_pac_req": 810, "krb5_pa_server_referral_data": 810, "krb5_pa_svr_referral_data": 810, "krb5_pa_data": [810, 838, 851, 852], "krb5_pwd_data": 810, "krb5_responder_otp_tokeninfo": [810, 884], "krb5_responder_pkinit_ident": [810, 886], "krb5_respons": 810, "krb5_tkt_authent": 810, "krb5_transit": [810, 839], "krb5_typed_data": 810, "krb5_ui_2": 810, "passwd_phrase_el": [810, 879], "_krb5_address": 811, "representaton": 813, "_krb5_ap_rep": [813, 814], "enc_part": [813, 829, 851, 889], "aprepencpart": 813, "cleartext": [814, 830, 838], "_krb5_ap_rep_enc_part": 814, "ctime": [814, 819, 842], "cusec": [814, 819, 842], "seq_numb": [814, 819], "_krb5_ap_req": 815, "_krb5_auth_context": 816, "_krb5_authdata": 817, "adtyp": 817, "_krb5_authent": 819, "usec": [819, 830, 842, 881], "authorization_data": [819, 839, 852], "authoriaz": 819, "_krb5_ccach": 822, "_krb5_cccol_cursor": 823, "_krb5_checksum": 824, "checksum_typ": 824, "_krb5_cred": [829, 832], "_krb5_cred_enc_part": 830, "s_address": 830, "r_address": 830, "recipi": [830, 926], "ticket_info": 830, "enckrbcredpart": 831, "_krb5_cred_info": 831, "renew_til": [831, 839, 890, 916], "caddr": [831, 838, 839], "second_ticket": [832, 852, 916], "tkt": 832, "IN": [832, 926], "_krb5_crypto_iov": 833, "_krb5_data": 835, "_krb5_enc_data": 837, "enckdcreppart": 838, "_krb5_enc_kdc_rep_part": 838, "msg_type": [838, 851, 852], "last_req": 838, "key_exp": 838, "enc_padata": 838, "_krb5_enc_tkt_part": 839, "_krb5_encrypt_block": 840, "crypto_entri": 840, "_krb5_error": 842, "susec": 842, "stime": 842, "e_data": [842, 938], "com_err": [843, 912, 925, 930], "_krb5_get_init_cr": 846, "_krb5_get_init_creds_opt": 846, "address_list": 846, "_krb5_gic_opt_pa_data": 847, "_krb5_init_creds_context": 848, "int16_t": 849, "int32_t": 850, "_krb5_kdc_rep": 851, "padata": [851, 852, 918, 929, 938], "bodi": [852, 938], "_krb5_kdc_req": 852, "kdc_option": 852, "till": 852, "rtime": 852, "nktype": 852, "authz": 852, "unenc_authdata": 852, "krb5_k": 853, "simultan": 853, "mutabl": 853, "mutex": 853, "krb5_key_st": 853, "_krb5_keyblock": 854, "_krb5_kt": 855, "krb5_keytab_entry_st": 856, "keytabl": 856, "_krb5_last_req_entri": 860, "lr_type": 860, "mk_req": 862, "uint8_t": 864, "_krb5_pa_data": 865, "pa_typ": [865, 916], "_krb5_pa_pac_req": 866, "include_pac": 866, "_krb5_pa_server_referral_data": 867, "referred_realm": 867, "true_principal_nam": 867, "requested_principal_nam": 867, "referral_valid_until": 867, "rep_cksum": 867, "_krb5_pa_svr_referral_data": 868, "krb5_pac_data": 869, "new_reply_out": [871, 872], "new_message_out": 872, "reply_out": 872, "_krb5_prompt": 876, "_krb5_pwd_data": 879, "sequence_count": 879, "krb5_rc_st": 880, "seq": 881, "krb5_responder_context_st": 882, "unansw": 883, "_krb5_responder_otp_challeng": 884, "_krb5_responder_otp_tokeninfo": 885, "token_id": 885, "alg_id": 885, "_krb5_responder_pkinit_challeng": 886, "_krb5_responder_pkinit_ident": 887, "token_flag": 887, "_krb5_respons": 888, "message_typ": 888, "expected_nonc": 888, "request_tim": 888, "_krb5_ticket": 889, "_krb5_ticket_tim": 890, "starttim": [890, 916], "abi": 891, "cast": [891, 902, 927, 929, 930, 935, 936, 937, 938, 940, 942], "uint32_t": [891, 899, 902], "2106": [891, 902, 925], "_krb5_tkt_authent": 892, "_krb5_tkt_creds_context": 893, "wrapper": [895, 917, 919], "_krb5_trace_info": 895, "_krb5_transit": 896, "tr_type": 896, "tr_content": 896, "_krb5_typed_data": 897, "uint16_t": 898, "_krb5_verify_init_creds_opt": 900, "_passwd_phrase_el": 901, "phrase": 901, "januari": [902, 904], "exce": [902, 904], "februari": 902, "damag": [903, 926], "deal": [903, 926], "dirpath": 903, "portabl": 903, "flat": 903, "keyr": [903, 912, 925, 960], "linux": [903, 912, 925], "kernel": [903, 909, 925], "unswapp": 903, "uidnumb": 903, "mslsa": 903, "kswitch": [903, 944, 947, 960], "cachenam": [903, 954], "descend": [903, 907], "mydir": 903, "hardcod": [903, 906, 941], "36": 904, "ndnhnmn": 904, "8h30": 904, "3600": 904, "30m": 904, "10d": 904, "mm": 904, "dd": 904, "yy": 904, "07": [904, 946], "month": [904, 925], "yyyi": 904, "jul": 904, "hh": 904, "ss": [904, 909, 912], "pp": 904, "08": [904, 946], "pm": 904, "tt": 904, "0400": 904, "2015": [904, 926], "05pm": 904, "gmt": 904, "test4": 904, "yyyymmddhhmmss": 904, "20141231235900": 904, "2014": [904, 925, 926], "yymmddhhmmss": 904, "141231235900": 904, "hhmmss": 904, "200000": 904, "juli": 904, "20120727203000": 904, "am": 904, "unit": [904, 926, 946], "digit": [904, 960], "alphabet": 904, "doubl": 904, "talk": 907, "But": 907, "eavesdropp": 907, "sai": 907, "harm": 907, "mailbox": 907, "guard": 907, "presum": 907, "seen": 907, "perfect": 907, "middl": 907, "arriv": 907, "uncommon": 907, "trigger": 907, "file2": [907, 922, 960], "grow": 907, "krb5rcachedir": [907, 924, 960], "tmpdir": [907, 960], "krb5_euid": 907, "rcache2": [907, 925], "ownership": 907, "krb5rcachenam": [907, 960], "krb5rcachetyp": [907, 960], "overview": 909, "appl": [909, 926], "ccapi": [909, 926], "po": 909, "prototyp": [909, 930], "templat": 909, "copyright": [909, 911, 926, 960], "placehold": [909, 911], "titl": [909, 926], "readm": [909, 911], "glue": [909, 918], "apputil": 909, "autoconf": 909, "lndir": [909, 911], "kbuild": 909, "reconf": 909, "makedepend": 909, "et": [909, 912, 926], "pty": [909, 926], "lightweight": 909, "confvalid": 909, "toolkit": 909, "mac": 909, "getopt": 909, "incompat": [910, 912, 934], "architectur": [910, 912], "abbrevi": [910, 950], "u1": [910, 911], "vpath": [910, 911], "gnu": [910, 912, 925, 926], "tmpbuild": 910, "mkdir": 910, "pwd": 910, "xconsortium": 910, "x11r6": 910, "destdir": 910, "makefil": [910, 912, 914], "regress": 910, "rpath": [910, 912, 952], "interfer": 910, "teardown": 910, "autom": [910, 925], "excess": 910, "k5wiki": [910, 925, 943], "manual_test": 910, "distclean": 910, "un": [910, 925], "tar": [910, 911], "prebuilt": 910, "autoreconf": 910, "autohead": 910, "approxim": [911, 925], "70": 911, "ansi": 911, "iso": 911, "iec": 911, "9899": 911, "1990": [911, 926], "c89": 911, "dist": 911, "compress": 911, "gz": 911, "pgp": [911, 943], "asc": 911, "highli": [911, 925], "xf": 911, "gpg": 911, "unpack": 911, "review": 911, "licens": [911, 912, 915, 925], "sprecif": 911, "organ": [911, 926], "osconf": 911, "hin": 911, "exec": [912, 952, 953], "execprefix": 912, "mostli": 912, "netlib": 912, "lnsl": 912, "lsocket": 912, "compile_et": 912, "cppflag": 912, "ldflag": 912, "subsystem": 912, "mk_cmd": 912, "ss_lib": 912, "berkelei": [912, 926], "85": 912, "untest": 912, "haven": [912, 960], "investig": 912, "cflag": [912, 952], "cpp": 912, "preprocessor": 912, "gcc": 912, "cppopt": 912, "db_header": 912, "headernam": 912, "db3": 912, "db_185": 912, "db_lib": 912, "ldb": 912, "ccachenam": 912, "expans": [912, 925], "keytabnam": 912, "ld": 912, "linker": 912, "loader": 912, "ldopt": 912, "ldname": 912, "lss": 912, "emac": 912, "yacc": 912, "bison": 912, "byacc": 912, "yflag": 912, "datarootdir": 912, "datadir": 912, "localedir": 912, "mandir": 912, "abc": [912, 960], "transform": 912, "sed": 912, "x86_64": [912, 925], "unrecogn": 912, "rebuild": [912, 914], "lookasid": 912, "retransmit": 912, "aesni": [912, 926], "x86": [912, 925], "asan": [912, 925], "fsanit": 912, "ossfuzz": 912, "fuzz": [912, 925, 926], "oss": [912, 925], "libedit": 912, "optim": 912, "few": [912, 945, 960], "vagu": 912, "impl": 912, "builtin": [912, 925, 926], "readlin": 912, "verto": [912, 926], "libverto": [912, 938], "keyutil": 912, "libkeyutil": 912, "suncc": 912, "slightli": 912, "curs": 912, "lcurs": 912, "default_profile_path": 913, "default_kdc_enctyp": 913, "rctmpdir": 913, "default_kdb_fil": 913, "requisit": 914, "sphinx": 914, "autodoc": 914, "prerequisit": 914, "cheetah": 914, "lxml": 914, "xml": 914, "rst": 914, "test_html": 914, "py": 914, "repositori": 914, "checkout": 914, "regener": 914, "top_srcdir": 914, "srcdir": 914, "sphinx_arg": 914, "htmlsrc": 914, "substhtml": 914, "html_subst": 914, "concret": 914, "1985": [915, 926, 960], "2025": [915, 926], "massachusett": [915, 926], "institut": [915, 926, 960], "technologi": [915, 926, 960], "contributor": [915, 926], "reserv": [915, 926], "big": [916, 917, 918, 919, 921, 931], "endian": [916, 917, 918, 919, 921, 931], "marshal": [916, 917, 925], "grammar": [916, 921], "component1": [916, 921], "component2": [916, 921], "frame": 916, "address1": 916, "address2": 916, "authdata1": 916, "authdata2": 916, "marker": [916, 925], "cacheconf": 916, "krb5_ccache_conf_data": 916, "awar": 916, "unimport": 916, "fast_avail": 916, "negoti": [916, 925, 931], "pa_config_data": 916, "proxy_imperson": 916, "refresh_tim": 916, "start_realm": 916, "mit1": 917, "1964": 917, "plain": 917, "der": [917, 918, 928, 931, 938], "securecooki": 917, "OF": [917, 926], "breviti": 917, "generalizedtim": 917, "transcript": 917, "encdata": 917, "scalar": 917, "38": 918, "disallow_postd": 918, "disallow_tgt_bas": 918, "disallow_renew": 918, "disallow_proxi": 918, "disallow_dup_skei": 918, "disallow_all_tix": 918, "pwchange_servic": 918, "support_desmd5": 918, "new_princ": 918, "unenforc": 918, "littl": [918, 931], "xdr": 918, "768": 918, "svr": 918, "appendix": 918, "1606": 918, "1792": 918, "32767": 918, "kadmin_data": 918, "numfield": 918, "keylen": 918, "saltlen": 918, "hist_entri": 918, "version_numb": 918, "nullstr": 918, "aux_attribut": 918, "old_key_next": 918, "admin_history_kvno": 918, "old_keyset": 918, "0x12345c01": 918, "0x800": 918, "aux": 918, "krbmaxticketlif": 918, "krbmaxrenewableag": 918, "krbticketflag": 918, "krbprincipalexpir": 918, "krbticketpolicyrefer": 918, "krbprincipalauthind": 918, "krbpwdpolicyrefer": 918, "krbpasswordexpir": 918, "krbprincipalkei": 918, "krblastpwdchang": 918, "krbextradata": 918, "krblastsuccessfulauth": 918, "krblastfailedauth": 918, "krbloginfailedcount": 918, "krblastadminunlock": 918, "krbpwdhistori": 918, "concept": [918, 923, 933], "max": 918, "tl_data": 918, "min_lif": 918, "max_pw_lif": 918, "min_length": 918, "min_class": 918, "history_num": 918, "refcount": [918, 925], "max_fail": 918, "failcount_interv": 918, "lockout_dur": 918, "allowed_keysalt": 918, "n_tl_data": 918, "tag_length_data": 918, "0x12345d01": 918, "0x12345d02": 918, "0x12345d03": 918, "pa_as_fresh": 919, "invers": 921, "coerc": 922, "truncat": [922, 946], "siphash": 922, "divid": 922, "16383": 922, "1023": 922, "16384": 922, "49151": 922, "49152": 922, "114687": 922, "spars": 922, "modulo": 922, "1022": 922, "2047": 922, "candid": [922, 953], "beyond": [922, 929, 934, 938, 960], "runtim": 924, "krb5cc_": [924, 953, 960], "opensc": 924, "stabl": [925, 935, 936, 937, 942], "cycl": 925, "kfw": 925, "xp": 925, "sparc": 925, "redhat": 925, "bsd": [925, 926], "netbsd": [925, 926], "krb4": 925, "leg": 925, "unencapsul": 925, "spnego": [925, 926, 931], "gss_wrapex": 925, "gss_iov": 925, "sspi": 925, "ntlm": 925, "recognit": [925, 926], "facilit": 925, "drop": 925, "gss_c_deleg_policy_flag": 925, "s4u": 925, "5896": 925, "iakerb": 925, "ietf": 925, "wg": 925, "bridg": 925, "msdn": 925, "cc246071": 925, "5588": 925, "kadm5_hook": [925, 933], "gs2": 925, "5801": 925, "5587": [925, 931], "localauth": [925, 933], "experiment": 925, "audit": 925, "cve": 925, "5351": 925, "cachetyp": 925, "lengthi": 925, "friendli": 925, "complex": 925, "principalnam": 925, "255": 925, "info2": 925, "identif": [925, 926], "sni": 925, "gss_acquire_cred_with_password": 925, "gss_store_cr": 925, "kdc_err_more_preauth_data_requir": 925, "get_cooki": [925, 938], "set_cooki": [925, 938], "kdcpreauth": [925, 933], "client_kei": 925, "add_auth_ind": [925, 938], "gss_krb5_cred_no_ci_flags_x": 925, "layer": [925, 931, 934], "prone": 925, "auto": 925, "getrandom": 925, "entropi": 925, "infrequ": 925, "fip": 925, "140": 925, "evolut": 925, "attach": 925, "nl": 925, "kdcpolici": [925, 933], "certauth": [925, 933], "gss_c_sec_context_sasl_ssf": 925, "gss_inquire_sec_context_by_oid": [925, 931], "imperson": 925, "friendlier": 925, "uc": 925, "german": 925, "clang": 925, "cleanli": 925, "addresssanit": 925, "lightn": 925, "robust": 925, "spuriou": 925, "visual": 925, "studio": 925, "volum": 925, "2013": [925, 926], "effici": 925, "negoex": [925, 933], "hhost": 925, "revis": [925, 926], "soft": 925, "harder": 925, "accident": 925, "gss_c_channel_bound_flag": 925, "hw": 925, "client_aware_gss_bind": 925, "dns_canonicalize_realm": 925, "inspir": 925, "kgetcr": 925, "atom": 925, "4gb": 925, "sign_authdata": 925, "issue_pac": 925, "reorgan": 925, "libk5crypto": 925, "pull": 925, "tcl": 925, "libkadm5": 925, "escal": 925, "libkrb5support": 925, "composit": 925, "indefinit": 925, "krb5_db_load_modul": 925, "gss_c_channel_bound": 925, "strict": [925, 926], "ecdh": 925, "pachecksum2": 925, "compli": [925, 926], "accomod": 925, "rewrot": 925, "safeti": 925, "cc246091": 925, "redistribut": 926, "met": [926, 953], "disclaim": 926, "reproduc": 926, "BY": 926, "THE": 926, "holder": 926, "AND": 926, "warranti": 926, "BUT": 926, "TO": 926, "merchant": 926, "FOR": 926, "NO": 926, "shall": 926, "BE": 926, "liabl": 926, "indirect": 926, "incident": 926, "exemplari": 926, "consequenti": 926, "profit": 926, "busi": 926, "ON": 926, "theori": 926, "liabil": 926, "contract": 926, "tort": 926, "neglig": 926, "aris": 926, "SUCH": 926, "constitut": 926, "america": 926, "regul": 926, "ear": 926, "cfr": 926, "730": 926, "774": 926, "law": 926, "contempl": 926, "countri": 926, "cuba": 926, "iran": 926, "north": 926, "korea": 926, "sudan": 926, "syria": 926, "nation": 926, "creativ": 926, "sharealik": 926, "unport": 926, "creativecommon": 926, "sa": 926, "novel": 926, "sun": 926, "microsystem": 926, "fundsxpress": 926, "muse": 926, "moira": 926, "trademark": 926, "firm": 926, "dbutil": 926, "inc": [926, 946, 960], "1993": 926, "agre": 926, "freeli": 926, "WILL": 926, "agreement": 926, "inclus": 926, "gratitud": 926, "matt": 926, "crawford": 926, "crawdad": 926, "fnal": 926, "fermi": 926, "acceler": 926, "laboratori": 926, "univers": 926, "research": 926, "ac02": 926, "76cho3000": 926, "depart": 926, "energi": 926, "1998": 926, "THAT": 926, "constraint": [926, 958], "fee": 926, "herebi": 926, "brian": 926, "gladman": 926, "worcest": 926, "uk": 926, "payment": 926, "royalti": 926, "plug": 926, "nss": 926, "2006": 926, "nor": [926, 950, 953], "endors": 926, "owner": 926, "2011": [926, 960], "charg": 926, "sublicens": 926, "sell": 926, "whom": [926, 945], "furnish": 926, "substanti": 926, "noninfring": 926, "WITH": 926, "mechglu": [926, 931], "gssapi_err_gener": 926, "g_accept_sec_context": 926, "g_acquire_cr": 926, "g_canon_nam": 926, "g_compare_nam": 926, "g_context_tim": 926, "g_delete_sec_context": 926, "g_dsp_name": 926, "g_dsp_statu": 926, "g_dup_nam": 926, "g_exp_sec_context": 926, "g_export_nam": 926, "g_glue": 926, "g_imp_nam": 926, "g_imp_sec_context": 926, "g_init_sec_context": 926, "g_initi": 926, "g_inquire_context": 926, "g_inquire_cr": 926, "g_inquire_nam": 926, "g_process_context": 926, "g_rel_buff": 926, "g_rel_cr": 926, "g_rel_nam": 926, "g_rel_oid_set": 926, "g_seal": 926, "g_sign": 926, "g_store_cr": 926, "g_unseal": 926, "g_userok": 926, "g_util": 926, "g_verifi": 926, "gssd_pname_to_uid": 926, "mgluep": 926, "oid_op": 926, "gssapip_spnego": 926, "spnego_mech": 926, "iprop_hdr": 926, "ipropd_svc": 926, "kdb_convert": 926, "kdb_log": 926, "error_t": 926, "kdb5_err": 926, "kpropd_rpc": 926, "california": 926, "1983": 926, "regent": 926, "2005": 926, "fund": 926, "sandia": 926, "michigan": 926, "2007": 926, "IT": 926, "hereaft": 926, "g10": 926, "gmbh": 926, "andrea": 926, "jellinghau": 926, "unlimit": 926, "hope": 926, "extent": 926, "2008": 926, "unicod": 926, "august": 926, "2003": 926, "statement": 926, "verbatim": 926, "foundat": 926, "sale": 926, "1999": 926, "redwood": 926, "citi": 926, "usa": 926, "kungliga": 926, "tekniska": 926, "h\u00f6gskola": 926, "royal": 926, "stockholm": 926, "sweden": 926, "kth": 926, "2009": 926, "gssrpc": 926, "2010": 926, "ntt": 926, "nippon": 926, "telegraph": 926, "telephon": 926, "corpor": [926, 960], "unmodifi": [926, 953], "carnegi": 926, "mellon": 926, "regard": 926, "whatsoev": 926, "tortiou": 926, "naval": 926, "nrl": 926, "thereof": 926, "2022": 926, "secretari": 926, "navi": 926, "1991": 926, "1992": 926, "1994": 926, "southern": 926, "acknowledg": 926, "held": [926, 950], "distributor": 926, "ksu": [926, 944, 947, 960], "1995": 926, "presid": 926, "fellow": 926, "harvard": 926, "jeremi": 926, "rassen": 926, "richard": 926, "basch": 926, "lehman": 926, "brother": 926, "strptime": 926, "1997": 926, "klau": 926, "klein": 926, "mexico": 926, "strlcpy": 926, "todd": 926, "miller": [926, 960], "courtesan": 926, "argv_pars": 926, "theodor": 926, "sick": 926, "cultur": 926, "lawsuit": 926, "happi": 926, "lawyer": 926, "portiion": 926, "dug": 926, "song": 926, "dugsong": 926, "umich": 926, "crypto_test": 926, "t_mddriver": 926, "confus": 926, "padl": 926, "ltd": 926, "libev": 926, "marc": 926, "alexand": 926, "lehmann": 926, "gpl": 926, "provis": 926, "intel": 926, "win": 926, "oldcc": 926, "autolock": 926, "hxx": 926, "danilo": 926, "almeida": 926, "edwards25519_t": 926, "2016": 926, "fiat": 926, "googl": 926, "2024": 926, "arjun": 926, "ccselect_plugin": [927, 930], "krb5_cccol": 927, "fini": [927, 928, 929, 932, 935, 936, 937, 938, 939, 940], "krb5_ccselect_moddata": 927, "abstract": [927, 929, 935, 936, 938, 942], "certauth_plugin": 928, "krb5_db_entri": 928, "libkdb5": 928, "krb5_certauth_hwauth": 928, "krb5_certauth_hwauth_pass": 928, "free_ind": 928, "core": [929, 934, 938, 941, 943], "clpreauth_plugin": 929, "preauth_plugin": [929, 938], "pa_type_list": [929, 938], "vtabl": [929, 930, 938, 941], "pa_real": 929, "preauth_requir": [929, 938], "more_preauth_data_requir": 929, "tryagain": 929, "gic_opt": 929, "request_init": 929, "request_fini": 929, "krb5_clpreauth_moddata": 929, "krb5_clpreauth_modreq": 929, "rock": [929, 938], "automak": 930, "libtool": 930, "interface_module_initvt": 930, "kdcpreauth_mymech_initvt": 930, "clpreauth_mymech_initvt": 930, "interface_plugin": 930, "initvt": 930, "interface_modname_initvt": 930, "maj_ver": 930, "min_ver": 930, "krb5_plugin_vt": 930, "krb5_plugin_ver_notsupp": 930, "unimpl": 930, "glorifi": 930, "liter": 930, "fiction": 930, "fenc": 930, "wicker": 930, "fences_wicker_initvt": 930, "krb5_ccselect_vt": 930, "vt": 930, "krb5_fences_vt": 930, "slat": 930, "wicker_slat": 930, "wicker_brac": 930, "krb5_fences_vtable_v2": 930, "wicker_materi": 930, "wicker_construct": 930, "foot": 930, "wicker_foot": 930, "wicker_appear": 930, "whoami": 930, "nitem": 930, "augment": 931, "dispatch": 931, "refrain": 931, "gracefulli": 931, "gss_add_cr": 931, "gss_add_cred_from": 931, "gss_add_cred_impersonate_nam": 931, "gss_add_cred_with_password": 931, "coordin": 931, "gss_display_statu": 931, "gssspi_query_meta_data": 931, "gssspi_exchange_meta_data": 931, "gssspi_query_mechanism_info": 931, "spi": 931, "gss_c_inq_negoex_kei": 931, "gss_c_inq_negoex_verify_kei": 931, "gss_inquire_attrs_for_mech": 931, "gss_c_ma_negoex_and_spnego": 931, "gss_mech_interpos": 931, "mech_typ": 931, "gss_create_empty_oid_set": 931, "gss_add_oid_set_memb": 931, "gssi_": 931, "gss_": 931, "unexport": 931, "concatent": 931, "verifier_cred_handl": 931, "gss_import_sec_context": 931, "gssi_import_sec_context_by_mech": 931, "interprocess_token": 931, "gssi_import_name_by_mech": 931, "input_name_buff": 931, "input_name_typ": 931, "output_nam": 931, "gssi_import_cred_by_mech": 931, "04": [931, 946], "06": [931, 946], "hostrealm_plugin": 932, "krb5_plugin_no_handl": [932, 935, 939, 940], "host_realm": 932, "fallback_realm": 932, "free_list": 932, "dal": 934, "authdata_plugin": 934, "kadm5_auth_plugin": 935, "kadm5_auth_modinfo": 935, "eperm": [935, 939], "impos": 935, "kadm5_auth_restrict": 935, "free_restrict": 935, "kadm5_hook_plugin": 936, "kadm5_hook_modinfo": 936, "unstabl": 936, "veto": 937, "kdcpolicy_plugin": 937, "check_a": 937, "check_tg": 937, "krb5_kdcpolicy_moddata": 937, "kdcpreauth_plugin": 938, "pa_replaces_kei": 938, "pa_hardwar": 938, "edata": 938, "return_padata": 938, "krb5_kdcpreauth_moddata": 938, "free_modreq": 938, "unfinish": 938, "krb5_kdcpreauth_modreq": 938, "yield": 938, "krb5kdc_err_more_preauth_data_requir": 938, "localauth_plugin": 939, "userok": 939, "an2ln_typ": 939, "krb5_lname_no_tran": 939, "free_str": [939, 941], "locate_plugin": 940, "krb5plugin_service_locate_ft": 940, "service_loc": 940, "af_unspec": 940, "sock_stream": 940, "sock_dgram": 940, "profile_module_init": 941, "profile_module_init_fn": 941, "basic": 941, "get_valu": 941, "free_valu": 941, "iterator_cr": 941, "iterator_fre": 941, "update_rel": 941, "rename_sect": 941, "add_rel": 941, "flush": 941, "concis": 941, "malloc": 941, "strdup": 941, "stdlib": 941, "cbdata": 941, "strcmp": 941, "prof_no_rel": 941, "profile_vt": 941, "cb_ret": 941, "pwqual_plugin": 942, "kadm5_pass_q_": 942, "krb5_pwqual_moddata": 942, "subscrib": 943, "mailman": 943, "listinfo": 943, "krbdev": 943, "notifi": 943, "krbcore": 943, "team": 943, "libera": 943, "chat": 943, "pipermail": 943, "consortium": [943, 960], "anyon": [945, 959], "mistak": 945, "anywher": [945, 960], "safer": 945, "inherit": [945, 953], "todo": 945, "logout": [946, 948], "intrud": 946, "safest": 946, "screensav": 946, "screen": 946, "meant": 946, "fictiti": 946, "compani": 946, "she": [946, 959], "incorrectli": 946, "suppos": [946, 959], "friend": 946, "visit": 946, "borrow": 946, "himself": 946, "went": 946, "3h": 946, "mix": 946, "3h30m": 946, "krb5cc_ttypa": 946, "49": 946, "05": 946, "gotten": 946, "odd": 946, "krb5cc_320": 946, "fdii": 946, "reforward": 946, "krb5cc_p11795": 946, "29": 946, "ff": 946, "48": 946, "inde": 946, "yourself": [946, 960], "stolen": 946, "beep": [946, 948], "quietli": 948, "renewable_lif": 949, "service_nam": 949, "input_ccach": 949, "armor_ccach": 949, "absent": 949, "5h30m": 949, "resubmit": 949, "rang": 949, "grace": 949, "preselect": 949, "keytab_nam": 950, "summar": 950, "silent": 950, "programm": 952, "kadm": 952, "wl": 952, "lkrb5": 952, "lk5crypto": 952, "lcom_err": 952, "target_us": 953, "target_principal_nam": 953, "source_cache_nam": 953, "su": 953, "mission": 953, "sake": 953, "clariti": 953, "likewis": 953, "fulfil": 953, "phase": 953, "jqpublic": 953, "usc": 953, "get_tgt_via_passwd": 953, "k5user": 953, "proce": 953, "undefin": 953, "local_realm": 953, "target_user_login_nam": 953, "source_us": 953, "princ_look_ahead": 953, "isi": 953, "my_cach": 953, "gen_sym": 953, "krb5cc_1984": 953, "bob": [953, 959], "lag": 953, "cmd_path": 953, "simul": 953, "have_getusershel": 953, "insist": 953, "getusershel": 953, "ksu_opt": 953, "dget_tgt_via_passwd": 953, "dprinc_look_ahead": 953, "dcmd_path": 953, "ucb": 953, "rlogin": 953, "nii": 953, "gennadi": 953, "ari": 953, "medvinski": 953, "cert_fil": 955, "for_us": 955, "u2u": 955, "service1": 955, "service2": 955, "conjunct": 955, "behalf": 955, "remotehost": 956, "blank": 958, "meet": 958, "therebi": 959, "xyz": 960, "convention": 960, "host01": 960, "joeuser": 960, "cbrown": 960, "transpar": 960, "sshing": 960, "illumin": 960, "steve": 960, "equip": 960, "clifford": 960, "neuman": 960, "greg": 960, "hudson": 960, "robbi": 960, "harwood": 960, "1986": 960, "1989": 960, "2018": 960, "masachusett": 960}, "objects": {"": [[49, 0, 1, "c.krb5_425_conv_principal", "krb5_425_conv_principal"], [50, 0, 1, "c.krb5_524_conv_principal", "krb5_524_conv_principal"], [51, 0, 1, "c.krb5_524_convert_creds", "krb5_524_convert_creds"], [811, 2, 1, "c.krb5_address", "krb5_address"], [52, 0, 1, "c.krb5_address_compare", "krb5_address_compare"], [53, 0, 1, "c.krb5_address_order", "krb5_address_order"], [54, 0, 1, "c.krb5_address_search", "krb5_address_search"], [812, 2, 1, "c.krb5_addrtype", "krb5_addrtype"], [55, 0, 1, "c.krb5_allow_weak_crypto", "krb5_allow_weak_crypto"], [56, 0, 1, "c.krb5_aname_to_localname", "krb5_aname_to_localname"], [57, 0, 1, "c.krb5_anonymous_principal", "krb5_anonymous_principal"], [58, 0, 1, "c.krb5_anonymous_realm", "krb5_anonymous_realm"], [813, 2, 1, "c.krb5_ap_rep", "krb5_ap_rep"], [814, 2, 1, "c.krb5_ap_rep_enc_part", "krb5_ap_rep_enc_part"], [815, 2, 1, "c.krb5_ap_req", "krb5_ap_req"], [59, 0, 1, "c.krb5_appdefault_boolean", "krb5_appdefault_boolean"], [60, 0, 1, "c.krb5_appdefault_string", "krb5_appdefault_string"], [61, 0, 1, "c.krb5_auth_con_free", "krb5_auth_con_free"], [62, 0, 1, "c.krb5_auth_con_genaddrs", "krb5_auth_con_genaddrs"], [63, 0, 1, "c.krb5_auth_con_get_checksum_func", "krb5_auth_con_get_checksum_func"], [64, 0, 1, "c.krb5_auth_con_getaddrs", "krb5_auth_con_getaddrs"], [65, 0, 1, "c.krb5_auth_con_getauthenticator", "krb5_auth_con_getauthenticator"], [66, 0, 1, "c.krb5_auth_con_getflags", "krb5_auth_con_getflags"], [67, 0, 1, "c.krb5_auth_con_getkey", "krb5_auth_con_getkey"], [68, 0, 1, "c.krb5_auth_con_getkey_k", "krb5_auth_con_getkey_k"], [69, 0, 1, "c.krb5_auth_con_getlocalseqnumber", "krb5_auth_con_getlocalseqnumber"], [70, 0, 1, "c.krb5_auth_con_getlocalsubkey", "krb5_auth_con_getlocalsubkey"], [71, 0, 1, "c.krb5_auth_con_getrcache", "krb5_auth_con_getrcache"], [72, 0, 1, "c.krb5_auth_con_getrecvsubkey", "krb5_auth_con_getrecvsubkey"], [73, 0, 1, "c.krb5_auth_con_getrecvsubkey_k", "krb5_auth_con_getrecvsubkey_k"], [74, 0, 1, "c.krb5_auth_con_getremoteseqnumber", "krb5_auth_con_getremoteseqnumber"], [75, 0, 1, "c.krb5_auth_con_getremotesubkey", "krb5_auth_con_getremotesubkey"], [76, 0, 1, "c.krb5_auth_con_getsendsubkey", "krb5_auth_con_getsendsubkey"], [77, 0, 1, "c.krb5_auth_con_getsendsubkey_k", "krb5_auth_con_getsendsubkey_k"], [78, 0, 1, "c.krb5_auth_con_init", "krb5_auth_con_init"], [79, 0, 1, "c.krb5_auth_con_initivector", "krb5_auth_con_initivector"], [80, 0, 1, "c.krb5_auth_con_set_checksum_func", "krb5_auth_con_set_checksum_func"], [81, 0, 1, "c.krb5_auth_con_set_req_cksumtype", "krb5_auth_con_set_req_cksumtype"], [82, 0, 1, "c.krb5_auth_con_setaddrs", "krb5_auth_con_setaddrs"], [83, 0, 1, "c.krb5_auth_con_setflags", "krb5_auth_con_setflags"], [84, 0, 1, "c.krb5_auth_con_setports", "krb5_auth_con_setports"], [85, 0, 1, "c.krb5_auth_con_setrcache", "krb5_auth_con_setrcache"], [86, 0, 1, "c.krb5_auth_con_setrecvsubkey", "krb5_auth_con_setrecvsubkey"], [87, 0, 1, "c.krb5_auth_con_setrecvsubkey_k", "krb5_auth_con_setrecvsubkey_k"], [88, 0, 1, "c.krb5_auth_con_setsendsubkey", "krb5_auth_con_setsendsubkey"], [89, 0, 1, "c.krb5_auth_con_setsendsubkey_k", "krb5_auth_con_setsendsubkey_k"], [90, 0, 1, "c.krb5_auth_con_setuseruserkey", "krb5_auth_con_setuseruserkey"], [816, 2, 1, "c.krb5_auth_context", "krb5_auth_context"], [817, 2, 1, "c.krb5_authdata", "krb5_authdata"], [818, 2, 1, "c.krb5_authdatatype", "krb5_authdatatype"], [819, 2, 1, "c.krb5_authenticator", "krb5_authenticator"], [820, 2, 1, "c.krb5_boolean", "krb5_boolean"], [91, 0, 1, "c.krb5_build_principal", "krb5_build_principal"], [92, 0, 1, "c.krb5_build_principal_alloc_va", "krb5_build_principal_alloc_va"], [93, 0, 1, "c.krb5_build_principal_ext", "krb5_build_principal_ext"], [94, 0, 1, "c.krb5_build_principal_va", "krb5_build_principal_va"], [95, 0, 1, "c.krb5_c_block_size", "krb5_c_block_size"], [96, 0, 1, "c.krb5_c_checksum_length", "krb5_c_checksum_length"], [97, 0, 1, "c.krb5_c_crypto_length", "krb5_c_crypto_length"], [98, 0, 1, "c.krb5_c_crypto_length_iov", "krb5_c_crypto_length_iov"], [99, 0, 1, "c.krb5_c_decrypt", "krb5_c_decrypt"], [100, 0, 1, "c.krb5_c_decrypt_iov", "krb5_c_decrypt_iov"], [101, 0, 1, "c.krb5_c_derive_prfplus", "krb5_c_derive_prfplus"], [102, 0, 1, "c.krb5_c_encrypt", "krb5_c_encrypt"], [103, 0, 1, "c.krb5_c_encrypt_iov", "krb5_c_encrypt_iov"], [104, 0, 1, "c.krb5_c_encrypt_length", "krb5_c_encrypt_length"], [105, 0, 1, "c.krb5_c_enctype_compare", "krb5_c_enctype_compare"], [106, 0, 1, "c.krb5_c_free_state", "krb5_c_free_state"], [107, 0, 1, "c.krb5_c_fx_cf2_simple", "krb5_c_fx_cf2_simple"], [108, 0, 1, "c.krb5_c_init_state", "krb5_c_init_state"], [109, 0, 1, "c.krb5_c_is_coll_proof_cksum", "krb5_c_is_coll_proof_cksum"], [110, 0, 1, "c.krb5_c_is_keyed_cksum", "krb5_c_is_keyed_cksum"], [111, 0, 1, "c.krb5_c_keyed_checksum_types", "krb5_c_keyed_checksum_types"], [112, 0, 1, "c.krb5_c_keylengths", "krb5_c_keylengths"], [113, 0, 1, "c.krb5_c_make_checksum", "krb5_c_make_checksum"], [114, 0, 1, "c.krb5_c_make_checksum_iov", "krb5_c_make_checksum_iov"], [115, 0, 1, "c.krb5_c_make_random_key", "krb5_c_make_random_key"], [116, 0, 1, "c.krb5_c_padding_length", "krb5_c_padding_length"], [117, 0, 1, "c.krb5_c_prf", "krb5_c_prf"], [118, 0, 1, "c.krb5_c_prf_length", "krb5_c_prf_length"], [119, 0, 1, "c.krb5_c_prfplus", "krb5_c_prfplus"], [120, 0, 1, "c.krb5_c_random_add_entropy", "krb5_c_random_add_entropy"], [121, 0, 1, "c.krb5_c_random_make_octets", "krb5_c_random_make_octets"], [122, 0, 1, "c.krb5_c_random_os_entropy", "krb5_c_random_os_entropy"], [123, 0, 1, "c.krb5_c_random_seed", "krb5_c_random_seed"], [124, 0, 1, "c.krb5_c_random_to_key", "krb5_c_random_to_key"], [125, 0, 1, "c.krb5_c_string_to_key", "krb5_c_string_to_key"], [126, 0, 1, "c.krb5_c_string_to_key_with_params", "krb5_c_string_to_key_with_params"], [127, 0, 1, "c.krb5_c_valid_cksumtype", "krb5_c_valid_cksumtype"], [128, 0, 1, "c.krb5_c_valid_enctype", "krb5_c_valid_enctype"], [129, 0, 1, "c.krb5_c_verify_checksum", "krb5_c_verify_checksum"], [130, 0, 1, "c.krb5_c_verify_checksum_iov", "krb5_c_verify_checksum_iov"], [131, 0, 1, "c.krb5_calculate_checksum", "krb5_calculate_checksum"], [132, 0, 1, "c.krb5_cc_cache_match", "krb5_cc_cache_match"], [133, 0, 1, "c.krb5_cc_close", "krb5_cc_close"], [134, 0, 1, "c.krb5_cc_copy_creds", "krb5_cc_copy_creds"], [821, 2, 1, "c.krb5_cc_cursor", "krb5_cc_cursor"], [135, 0, 1, "c.krb5_cc_default", "krb5_cc_default"], [136, 0, 1, "c.krb5_cc_default_name", "krb5_cc_default_name"], [137, 0, 1, "c.krb5_cc_destroy", "krb5_cc_destroy"], [138, 0, 1, "c.krb5_cc_dup", "krb5_cc_dup"], [139, 0, 1, "c.krb5_cc_end_seq_get", "krb5_cc_end_seq_get"], [140, 0, 1, "c.krb5_cc_gen_new", "krb5_cc_gen_new"], [141, 0, 1, "c.krb5_cc_get_config", "krb5_cc_get_config"], [142, 0, 1, "c.krb5_cc_get_flags", "krb5_cc_get_flags"], [143, 0, 1, "c.krb5_cc_get_full_name", "krb5_cc_get_full_name"], [144, 0, 1, "c.krb5_cc_get_name", "krb5_cc_get_name"], [145, 0, 1, "c.krb5_cc_get_principal", "krb5_cc_get_principal"], [146, 0, 1, "c.krb5_cc_get_type", "krb5_cc_get_type"], [147, 0, 1, "c.krb5_cc_initialize", "krb5_cc_initialize"], [148, 0, 1, "c.krb5_cc_move", "krb5_cc_move"], [149, 0, 1, "c.krb5_cc_new_unique", "krb5_cc_new_unique"], [150, 0, 1, "c.krb5_cc_next_cred", "krb5_cc_next_cred"], [151, 0, 1, "c.krb5_cc_remove_cred", "krb5_cc_remove_cred"], [152, 0, 1, "c.krb5_cc_resolve", "krb5_cc_resolve"], [153, 0, 1, "c.krb5_cc_retrieve_cred", "krb5_cc_retrieve_cred"], [154, 0, 1, "c.krb5_cc_select", "krb5_cc_select"], [155, 0, 1, "c.krb5_cc_set_config", "krb5_cc_set_config"], [156, 0, 1, "c.krb5_cc_set_default_name", "krb5_cc_set_default_name"], [157, 0, 1, "c.krb5_cc_set_flags", "krb5_cc_set_flags"], [158, 0, 1, "c.krb5_cc_start_seq_get", "krb5_cc_start_seq_get"], [159, 0, 1, "c.krb5_cc_store_cred", "krb5_cc_store_cred"], [160, 0, 1, "c.krb5_cc_support_switch", "krb5_cc_support_switch"], [161, 0, 1, "c.krb5_cc_switch", "krb5_cc_switch"], [822, 2, 1, "c.krb5_ccache", "krb5_ccache"], [823, 2, 1, "c.krb5_cccol_cursor", "krb5_cccol_cursor"], [162, 0, 1, "c.krb5_cccol_cursor_free", "krb5_cccol_cursor_free"], [163, 0, 1, "c.krb5_cccol_cursor_new", "krb5_cccol_cursor_new"], [164, 0, 1, "c.krb5_cccol_cursor_next", "krb5_cccol_cursor_next"], [165, 0, 1, "c.krb5_cccol_have_content", "krb5_cccol_have_content"], [166, 0, 1, "c.krb5_change_password", "krb5_change_password"], [167, 0, 1, "c.krb5_check_clockskew", "krb5_check_clockskew"], [824, 2, 1, "c.krb5_checksum", "krb5_checksum"], [168, 0, 1, "c.krb5_checksum_size", "krb5_checksum_size"], [169, 0, 1, "c.krb5_chpw_message", "krb5_chpw_message"], [825, 2, 1, "c.krb5_cksumtype", "krb5_cksumtype"], [170, 0, 1, "c.krb5_cksumtype_to_string", "krb5_cksumtype_to_string"], [171, 0, 1, "c.krb5_clear_error_message", "krb5_clear_error_message"], [826, 2, 1, "c.krb5_const_pointer", "krb5_const_pointer"], [827, 2, 1, "c.krb5_const_principal", "krb5_const_principal"], [828, 2, 1, "c.krb5_context", "krb5_context"], [172, 0, 1, "c.krb5_copy_addresses", "krb5_copy_addresses"], [173, 0, 1, "c.krb5_copy_authdata", "krb5_copy_authdata"], [174, 0, 1, "c.krb5_copy_authenticator", "krb5_copy_authenticator"], [175, 0, 1, "c.krb5_copy_checksum", "krb5_copy_checksum"], [176, 0, 1, "c.krb5_copy_context", "krb5_copy_context"], [177, 0, 1, "c.krb5_copy_creds", "krb5_copy_creds"], [178, 0, 1, "c.krb5_copy_data", "krb5_copy_data"], [179, 0, 1, "c.krb5_copy_error_message", "krb5_copy_error_message"], [180, 0, 1, "c.krb5_copy_keyblock", "krb5_copy_keyblock"], [181, 0, 1, "c.krb5_copy_keyblock_contents", "krb5_copy_keyblock_contents"], [182, 0, 1, "c.krb5_copy_principal", "krb5_copy_principal"], [183, 0, 1, "c.krb5_copy_ticket", "krb5_copy_ticket"], [829, 2, 1, "c.krb5_cred", "krb5_cred"], [830, 2, 1, "c.krb5_cred_enc_part", "krb5_cred_enc_part"], [831, 2, 1, "c.krb5_cred_info", "krb5_cred_info"], [832, 2, 1, "c.krb5_creds", "krb5_creds"], [833, 2, 1, "c.krb5_crypto_iov", "krb5_crypto_iov"], [834, 2, 1, "c.krb5_cryptotype", "krb5_cryptotype"], [835, 2, 1, "c.krb5_data", "krb5_data"], [184, 0, 1, "c.krb5_decode_authdata_container", "krb5_decode_authdata_container"], [185, 0, 1, "c.krb5_decode_ticket", "krb5_decode_ticket"], [186, 0, 1, "c.krb5_decrypt", "krb5_decrypt"], [836, 2, 1, "c.krb5_deltat", "krb5_deltat"], [187, 0, 1, "c.krb5_deltat_to_string", "krb5_deltat_to_string"], [188, 0, 1, "c.krb5_eblock_enctype", "krb5_eblock_enctype"], [837, 2, 1, "c.krb5_enc_data", "krb5_enc_data"], [838, 2, 1, "c.krb5_enc_kdc_rep_part", "krb5_enc_kdc_rep_part"], [839, 2, 1, "c.krb5_enc_tkt_part", "krb5_enc_tkt_part"], [189, 0, 1, "c.krb5_encode_authdata_container", "krb5_encode_authdata_container"], [190, 0, 1, "c.krb5_encrypt", "krb5_encrypt"], [840, 2, 1, "c.krb5_encrypt_block", "krb5_encrypt_block"], [191, 0, 1, "c.krb5_encrypt_size", "krb5_encrypt_size"], [841, 2, 1, "c.krb5_enctype", "krb5_enctype"], [192, 0, 1, "c.krb5_enctype_to_name", "krb5_enctype_to_name"], [193, 0, 1, "c.krb5_enctype_to_string", "krb5_enctype_to_string"], [842, 2, 1, "c.krb5_error", "krb5_error"], [843, 2, 1, "c.krb5_error_code", "krb5_error_code"], [194, 0, 1, "c.krb5_expand_hostname", "krb5_expand_hostname"], [844, 2, 1, "c.krb5_expire_callback_func", "krb5_expire_callback_func"], [195, 0, 1, "c.krb5_find_authdata", "krb5_find_authdata"], [196, 0, 1, "c.krb5_finish_key", "krb5_finish_key"], [197, 0, 1, "c.krb5_finish_random_key", "krb5_finish_random_key"], [845, 2, 1, "c.krb5_flags", "krb5_flags"], [198, 0, 1, "c.krb5_free_addresses", "krb5_free_addresses"], [199, 0, 1, "c.krb5_free_ap_rep_enc_part", "krb5_free_ap_rep_enc_part"], [200, 0, 1, "c.krb5_free_authdata", "krb5_free_authdata"], [201, 0, 1, "c.krb5_free_authenticator", "krb5_free_authenticator"], [202, 0, 1, "c.krb5_free_checksum", "krb5_free_checksum"], [203, 0, 1, "c.krb5_free_checksum_contents", "krb5_free_checksum_contents"], [204, 0, 1, "c.krb5_free_cksumtypes", "krb5_free_cksumtypes"], [205, 0, 1, "c.krb5_free_config_files", "krb5_free_config_files"], [206, 0, 1, "c.krb5_free_context", "krb5_free_context"], [207, 0, 1, "c.krb5_free_cred_contents", "krb5_free_cred_contents"], [208, 0, 1, "c.krb5_free_creds", "krb5_free_creds"], [209, 0, 1, "c.krb5_free_data", "krb5_free_data"], [210, 0, 1, "c.krb5_free_data_contents", "krb5_free_data_contents"], [211, 0, 1, "c.krb5_free_default_realm", "krb5_free_default_realm"], [212, 0, 1, "c.krb5_free_enctypes", "krb5_free_enctypes"], [213, 0, 1, "c.krb5_free_error", "krb5_free_error"], [214, 0, 1, "c.krb5_free_error_message", "krb5_free_error_message"], [215, 0, 1, "c.krb5_free_host_realm", "krb5_free_host_realm"], [216, 0, 1, "c.krb5_free_keyblock", "krb5_free_keyblock"], [217, 0, 1, "c.krb5_free_keyblock_contents", "krb5_free_keyblock_contents"], [218, 0, 1, "c.krb5_free_keytab_entry_contents", "krb5_free_keytab_entry_contents"], [219, 0, 1, "c.krb5_free_principal", "krb5_free_principal"], [220, 0, 1, "c.krb5_free_string", "krb5_free_string"], [221, 0, 1, "c.krb5_free_tgt_creds", "krb5_free_tgt_creds"], [222, 0, 1, "c.krb5_free_ticket", "krb5_free_ticket"], [223, 0, 1, "c.krb5_free_unparsed_name", "krb5_free_unparsed_name"], [224, 0, 1, "c.krb5_fwd_tgt_creds", "krb5_fwd_tgt_creds"], [225, 0, 1, "c.krb5_get_credentials", "krb5_get_credentials"], [226, 0, 1, "c.krb5_get_credentials_renew", "krb5_get_credentials_renew"], [227, 0, 1, "c.krb5_get_credentials_validate", "krb5_get_credentials_validate"], [228, 0, 1, "c.krb5_get_default_config_files", "krb5_get_default_config_files"], [229, 0, 1, "c.krb5_get_default_realm", "krb5_get_default_realm"], [230, 0, 1, "c.krb5_get_error_message", "krb5_get_error_message"], [231, 0, 1, "c.krb5_get_etype_info", "krb5_get_etype_info"], [232, 0, 1, "c.krb5_get_fallback_host_realm", "krb5_get_fallback_host_realm"], [233, 0, 1, "c.krb5_get_host_realm", "krb5_get_host_realm"], [234, 0, 1, "c.krb5_get_in_tkt_with_keytab", "krb5_get_in_tkt_with_keytab"], [235, 0, 1, "c.krb5_get_in_tkt_with_password", "krb5_get_in_tkt_with_password"], [236, 0, 1, "c.krb5_get_in_tkt_with_skey", "krb5_get_in_tkt_with_skey"], [237, 0, 1, "c.krb5_get_init_creds_keytab", "krb5_get_init_creds_keytab"], [846, 2, 1, "c.krb5_get_init_creds_opt", "krb5_get_init_creds_opt"], [238, 0, 1, "c.krb5_get_init_creds_opt_alloc", "krb5_get_init_creds_opt_alloc"], [239, 0, 1, "c.krb5_get_init_creds_opt_free", "krb5_get_init_creds_opt_free"], [240, 0, 1, "c.krb5_get_init_creds_opt_get_fast_flags", "krb5_get_init_creds_opt_get_fast_flags"], [241, 0, 1, "c.krb5_get_init_creds_opt_init", "krb5_get_init_creds_opt_init"], [242, 0, 1, "c.krb5_get_init_creds_opt_set_address_list", "krb5_get_init_creds_opt_set_address_list"], [243, 0, 1, "c.krb5_get_init_creds_opt_set_anonymous", "krb5_get_init_creds_opt_set_anonymous"], [244, 0, 1, "c.krb5_get_init_creds_opt_set_canonicalize", "krb5_get_init_creds_opt_set_canonicalize"], [245, 0, 1, "c.krb5_get_init_creds_opt_set_change_password_prompt", "krb5_get_init_creds_opt_set_change_password_prompt"], [246, 0, 1, "c.krb5_get_init_creds_opt_set_etype_list", "krb5_get_init_creds_opt_set_etype_list"], [247, 0, 1, "c.krb5_get_init_creds_opt_set_expire_callback", "krb5_get_init_creds_opt_set_expire_callback"], [248, 0, 1, "c.krb5_get_init_creds_opt_set_fast_ccache", "krb5_get_init_creds_opt_set_fast_ccache"], [249, 0, 1, "c.krb5_get_init_creds_opt_set_fast_ccache_name", "krb5_get_init_creds_opt_set_fast_ccache_name"], [250, 0, 1, "c.krb5_get_init_creds_opt_set_fast_flags", "krb5_get_init_creds_opt_set_fast_flags"], [251, 0, 1, "c.krb5_get_init_creds_opt_set_forwardable", "krb5_get_init_creds_opt_set_forwardable"], [252, 0, 1, "c.krb5_get_init_creds_opt_set_in_ccache", "krb5_get_init_creds_opt_set_in_ccache"], [253, 0, 1, "c.krb5_get_init_creds_opt_set_out_ccache", "krb5_get_init_creds_opt_set_out_ccache"], [254, 0, 1, "c.krb5_get_init_creds_opt_set_pa", "krb5_get_init_creds_opt_set_pa"], [255, 0, 1, "c.krb5_get_init_creds_opt_set_pac_request", "krb5_get_init_creds_opt_set_pac_request"], [256, 0, 1, "c.krb5_get_init_creds_opt_set_preauth_list", "krb5_get_init_creds_opt_set_preauth_list"], [257, 0, 1, "c.krb5_get_init_creds_opt_set_proxiable", "krb5_get_init_creds_opt_set_proxiable"], [258, 0, 1, "c.krb5_get_init_creds_opt_set_renew_life", "krb5_get_init_creds_opt_set_renew_life"], [259, 0, 1, "c.krb5_get_init_creds_opt_set_responder", "krb5_get_init_creds_opt_set_responder"], [260, 0, 1, "c.krb5_get_init_creds_opt_set_salt", "krb5_get_init_creds_opt_set_salt"], [261, 0, 1, "c.krb5_get_init_creds_opt_set_tkt_life", "krb5_get_init_creds_opt_set_tkt_life"], [262, 0, 1, "c.krb5_get_init_creds_password", "krb5_get_init_creds_password"], [263, 0, 1, "c.krb5_get_permitted_enctypes", "krb5_get_permitted_enctypes"], [264, 0, 1, "c.krb5_get_profile", "krb5_get_profile"], [265, 0, 1, "c.krb5_get_prompt_types", "krb5_get_prompt_types"], [266, 0, 1, "c.krb5_get_renewed_creds", "krb5_get_renewed_creds"], [267, 0, 1, "c.krb5_get_server_rcache", "krb5_get_server_rcache"], [268, 0, 1, "c.krb5_get_time_offsets", "krb5_get_time_offsets"], [269, 0, 1, "c.krb5_get_validated_creds", "krb5_get_validated_creds"], [847, 2, 1, "c.krb5_gic_opt_pa_data", "krb5_gic_opt_pa_data"], [270, 0, 1, "c.krb5_init_context", "krb5_init_context"], [271, 0, 1, "c.krb5_init_context_profile", "krb5_init_context_profile"], [848, 2, 1, "c.krb5_init_creds_context", "krb5_init_creds_context"], [272, 0, 1, "c.krb5_init_creds_free", "krb5_init_creds_free"], [273, 0, 1, "c.krb5_init_creds_get", "krb5_init_creds_get"], [274, 0, 1, "c.krb5_init_creds_get_creds", "krb5_init_creds_get_creds"], [275, 0, 1, "c.krb5_init_creds_get_error", "krb5_init_creds_get_error"], [276, 0, 1, "c.krb5_init_creds_get_times", "krb5_init_creds_get_times"], [277, 0, 1, "c.krb5_init_creds_init", "krb5_init_creds_init"], [278, 0, 1, "c.krb5_init_creds_set_keytab", "krb5_init_creds_set_keytab"], [279, 0, 1, "c.krb5_init_creds_set_password", "krb5_init_creds_set_password"], [280, 0, 1, "c.krb5_init_creds_set_service", "krb5_init_creds_set_service"], [281, 0, 1, "c.krb5_init_creds_step", "krb5_init_creds_step"], [282, 0, 1, "c.krb5_init_keyblock", "krb5_init_keyblock"], [283, 0, 1, "c.krb5_init_random_key", "krb5_init_random_key"], [284, 0, 1, "c.krb5_init_secure_context", "krb5_init_secure_context"], [849, 2, 1, "c.krb5_int16", "krb5_int16"], [850, 2, 1, "c.krb5_int32", "krb5_int32"], [285, 0, 1, "c.krb5_is_config_principal", "krb5_is_config_principal"], [286, 0, 1, "c.krb5_is_referral_realm", "krb5_is_referral_realm"], [287, 0, 1, "c.krb5_is_thread_safe", "krb5_is_thread_safe"], [288, 0, 1, "c.krb5_k_create_key", "krb5_k_create_key"], [289, 0, 1, "c.krb5_k_decrypt", "krb5_k_decrypt"], [290, 0, 1, "c.krb5_k_decrypt_iov", "krb5_k_decrypt_iov"], [291, 0, 1, "c.krb5_k_encrypt", "krb5_k_encrypt"], [292, 0, 1, "c.krb5_k_encrypt_iov", "krb5_k_encrypt_iov"], [293, 0, 1, "c.krb5_k_free_key", "krb5_k_free_key"], [294, 0, 1, "c.krb5_k_key_enctype", "krb5_k_key_enctype"], [295, 0, 1, "c.krb5_k_key_keyblock", "krb5_k_key_keyblock"], [296, 0, 1, "c.krb5_k_make_checksum", "krb5_k_make_checksum"], [297, 0, 1, "c.krb5_k_make_checksum_iov", "krb5_k_make_checksum_iov"], [298, 0, 1, "c.krb5_k_prf", "krb5_k_prf"], [299, 0, 1, "c.krb5_k_reference_key", "krb5_k_reference_key"], [300, 0, 1, "c.krb5_k_verify_checksum", "krb5_k_verify_checksum"], [301, 0, 1, "c.krb5_k_verify_checksum_iov", "krb5_k_verify_checksum_iov"], [851, 2, 1, "c.krb5_kdc_rep", "krb5_kdc_rep"], [852, 2, 1, "c.krb5_kdc_req", "krb5_kdc_req"], [302, 0, 1, "c.krb5_kdc_sign_ticket", "krb5_kdc_sign_ticket"], [303, 0, 1, "c.krb5_kdc_verify_ticket", "krb5_kdc_verify_ticket"], [853, 2, 1, "c.krb5_key", "krb5_key"], [854, 2, 1, "c.krb5_keyblock", "krb5_keyblock"], [855, 2, 1, "c.krb5_keytab", "krb5_keytab"], [856, 2, 1, "c.krb5_keytab_entry", "krb5_keytab_entry"], [857, 2, 1, "c.krb5_keyusage", "krb5_keyusage"], [304, 0, 1, "c.krb5_kt_add_entry", "krb5_kt_add_entry"], [305, 0, 1, "c.krb5_kt_client_default", "krb5_kt_client_default"], [306, 0, 1, "c.krb5_kt_close", "krb5_kt_close"], [858, 2, 1, "c.krb5_kt_cursor", "krb5_kt_cursor"], [307, 0, 1, "c.krb5_kt_default", "krb5_kt_default"], [308, 0, 1, "c.krb5_kt_default_name", "krb5_kt_default_name"], [309, 0, 1, "c.krb5_kt_dup", "krb5_kt_dup"], [310, 0, 1, "c.krb5_kt_end_seq_get", "krb5_kt_end_seq_get"], [311, 0, 1, "c.krb5_kt_free_entry", "krb5_kt_free_entry"], [312, 0, 1, "c.krb5_kt_get_entry", "krb5_kt_get_entry"], [313, 0, 1, "c.krb5_kt_get_name", "krb5_kt_get_name"], [314, 0, 1, "c.krb5_kt_get_type", "krb5_kt_get_type"], [315, 0, 1, "c.krb5_kt_have_content", "krb5_kt_have_content"], [316, 0, 1, "c.krb5_kt_next_entry", "krb5_kt_next_entry"], [317, 0, 1, "c.krb5_kt_read_service_key", "krb5_kt_read_service_key"], [318, 0, 1, "c.krb5_kt_remove_entry", "krb5_kt_remove_entry"], [319, 0, 1, "c.krb5_kt_resolve", "krb5_kt_resolve"], [320, 0, 1, "c.krb5_kt_start_seq_get", "krb5_kt_start_seq_get"], [321, 0, 1, "c.krb5_kuserok", "krb5_kuserok"], [859, 2, 1, "c.krb5_kvno", "krb5_kvno"], [860, 2, 1, "c.krb5_last_req_entry", "krb5_last_req_entry"], [861, 2, 1, "c.krb5_magic", "krb5_magic"], [322, 0, 1, "c.krb5_make_authdata_kdc_issued", "krb5_make_authdata_kdc_issued"], [323, 0, 1, "c.krb5_marshal_credentials", "krb5_marshal_credentials"], [324, 0, 1, "c.krb5_merge_authdata", "krb5_merge_authdata"], [325, 0, 1, "c.krb5_mk_1cred", "krb5_mk_1cred"], [326, 0, 1, "c.krb5_mk_error", "krb5_mk_error"], [327, 0, 1, "c.krb5_mk_ncred", "krb5_mk_ncred"], [328, 0, 1, "c.krb5_mk_priv", "krb5_mk_priv"], [329, 0, 1, "c.krb5_mk_rep", "krb5_mk_rep"], [330, 0, 1, "c.krb5_mk_rep_dce", "krb5_mk_rep_dce"], [331, 0, 1, "c.krb5_mk_req", "krb5_mk_req"], [862, 2, 1, "c.krb5_mk_req_checksum_func", "krb5_mk_req_checksum_func"], [332, 0, 1, "c.krb5_mk_req_extended", "krb5_mk_req_extended"], [333, 0, 1, "c.krb5_mk_safe", "krb5_mk_safe"], [863, 2, 1, "c.krb5_msgtype", "krb5_msgtype"], [864, 2, 1, "c.krb5_octet", "krb5_octet"], [334, 0, 1, "c.krb5_os_localaddr", "krb5_os_localaddr"], [865, 2, 1, "c.krb5_pa_data", "krb5_pa_data"], [866, 2, 1, "c.krb5_pa_pac_req", "krb5_pa_pac_req"], [867, 2, 1, "c.krb5_pa_server_referral_data", "krb5_pa_server_referral_data"], [868, 2, 1, "c.krb5_pa_svr_referral_data", "krb5_pa_svr_referral_data"], [869, 2, 1, "c.krb5_pac", "krb5_pac"], [335, 0, 1, "c.krb5_pac_add_buffer", "krb5_pac_add_buffer"], [336, 0, 1, "c.krb5_pac_free", "krb5_pac_free"], [337, 0, 1, "c.krb5_pac_get_buffer", "krb5_pac_get_buffer"], [338, 0, 1, "c.krb5_pac_get_client_info", "krb5_pac_get_client_info"], [339, 0, 1, "c.krb5_pac_get_types", "krb5_pac_get_types"], [340, 0, 1, "c.krb5_pac_init", "krb5_pac_init"], [341, 0, 1, "c.krb5_pac_parse", "krb5_pac_parse"], [342, 0, 1, "c.krb5_pac_sign", "krb5_pac_sign"], [343, 0, 1, "c.krb5_pac_sign_ext", "krb5_pac_sign_ext"], [344, 0, 1, "c.krb5_pac_verify", "krb5_pac_verify"], [345, 0, 1, "c.krb5_pac_verify_ext", "krb5_pac_verify_ext"], [346, 0, 1, "c.krb5_parse_name", "krb5_parse_name"], [347, 0, 1, "c.krb5_parse_name_flags", "krb5_parse_name_flags"], [870, 2, 1, "c.krb5_pointer", "krb5_pointer"], [871, 2, 1, "c.krb5_post_recv_fn", "krb5_post_recv_fn"], [872, 2, 1, "c.krb5_pre_send_fn", "krb5_pre_send_fn"], [873, 2, 1, "c.krb5_preauthtype", "krb5_preauthtype"], [348, 0, 1, "c.krb5_prepend_error_message", "krb5_prepend_error_message"], [874, 2, 1, "c.krb5_principal", "krb5_principal"], [349, 0, 1, "c.krb5_principal2salt", "krb5_principal2salt"], [350, 0, 1, "c.krb5_principal_compare", "krb5_principal_compare"], [351, 0, 1, "c.krb5_principal_compare_any_realm", "krb5_principal_compare_any_realm"], [352, 0, 1, "c.krb5_principal_compare_flags", "krb5_principal_compare_flags"], [875, 2, 1, "c.krb5_principal_data", "krb5_principal_data"], [353, 0, 1, "c.krb5_process_key", "krb5_process_key"], [876, 2, 1, "c.krb5_prompt", "krb5_prompt"], [877, 2, 1, "c.krb5_prompt_type", "krb5_prompt_type"], [878, 2, 1, "c.krb5_prompter_fct", "krb5_prompter_fct"], [354, 0, 1, "c.krb5_prompter_posix", "krb5_prompter_posix"], [879, 2, 1, "c.krb5_pwd_data", "krb5_pwd_data"], [355, 0, 1, "c.krb5_random_key", "krb5_random_key"], [880, 2, 1, "c.krb5_rcache", "krb5_rcache"], [356, 0, 1, "c.krb5_rd_cred", "krb5_rd_cred"], [357, 0, 1, "c.krb5_rd_error", "krb5_rd_error"], [358, 0, 1, "c.krb5_rd_priv", "krb5_rd_priv"], [359, 0, 1, "c.krb5_rd_rep", "krb5_rd_rep"], [360, 0, 1, "c.krb5_rd_rep_dce", "krb5_rd_rep_dce"], [361, 0, 1, "c.krb5_rd_req", "krb5_rd_req"], [362, 0, 1, "c.krb5_rd_safe", "krb5_rd_safe"], [363, 0, 1, "c.krb5_read_password", "krb5_read_password"], [364, 0, 1, "c.krb5_realm_compare", "krb5_realm_compare"], [365, 0, 1, "c.krb5_recvauth", "krb5_recvauth"], [366, 0, 1, "c.krb5_recvauth_version", "krb5_recvauth_version"], [881, 2, 1, "c.krb5_replay_data", "krb5_replay_data"], [882, 2, 1, "c.krb5_responder_context", "krb5_responder_context"], [883, 2, 1, "c.krb5_responder_fn", "krb5_responder_fn"], [367, 0, 1, "c.krb5_responder_get_challenge", "krb5_responder_get_challenge"], [368, 0, 1, "c.krb5_responder_list_questions", "krb5_responder_list_questions"], [884, 2, 1, "c.krb5_responder_otp_challenge", "krb5_responder_otp_challenge"], [369, 0, 1, "c.krb5_responder_otp_challenge_free", "krb5_responder_otp_challenge_free"], [370, 0, 1, "c.krb5_responder_otp_get_challenge", "krb5_responder_otp_get_challenge"], [371, 0, 1, "c.krb5_responder_otp_set_answer", "krb5_responder_otp_set_answer"], [885, 2, 1, "c.krb5_responder_otp_tokeninfo", "krb5_responder_otp_tokeninfo"], [886, 2, 1, "c.krb5_responder_pkinit_challenge", "krb5_responder_pkinit_challenge"], [372, 0, 1, "c.krb5_responder_pkinit_challenge_free", "krb5_responder_pkinit_challenge_free"], [373, 0, 1, "c.krb5_responder_pkinit_get_challenge", "krb5_responder_pkinit_get_challenge"], [887, 2, 1, "c.krb5_responder_pkinit_identity", "krb5_responder_pkinit_identity"], [374, 0, 1, "c.krb5_responder_pkinit_set_answer", "krb5_responder_pkinit_set_answer"], [375, 0, 1, "c.krb5_responder_set_answer", "krb5_responder_set_answer"], [888, 2, 1, "c.krb5_response", "krb5_response"], [376, 0, 1, "c.krb5_salttype_to_string", "krb5_salttype_to_string"], [377, 0, 1, "c.krb5_sendauth", "krb5_sendauth"], [378, 0, 1, "c.krb5_server_decrypt_ticket_keytab", "krb5_server_decrypt_ticket_keytab"], [379, 0, 1, "c.krb5_set_default_realm", "krb5_set_default_realm"], [380, 0, 1, "c.krb5_set_default_tgs_enctypes", "krb5_set_default_tgs_enctypes"], [381, 0, 1, "c.krb5_set_error_message", "krb5_set_error_message"], [382, 0, 1, "c.krb5_set_kdc_recv_hook", "krb5_set_kdc_recv_hook"], [383, 0, 1, "c.krb5_set_kdc_send_hook", "krb5_set_kdc_send_hook"], [384, 0, 1, "c.krb5_set_password", "krb5_set_password"], [385, 0, 1, "c.krb5_set_password_using_ccache", "krb5_set_password_using_ccache"], [386, 0, 1, "c.krb5_set_principal_realm", "krb5_set_principal_realm"], [387, 0, 1, "c.krb5_set_real_time", "krb5_set_real_time"], [388, 0, 1, "c.krb5_set_trace_callback", "krb5_set_trace_callback"], [389, 0, 1, "c.krb5_set_trace_filename", "krb5_set_trace_filename"], [390, 0, 1, "c.krb5_sname_match", "krb5_sname_match"], [391, 0, 1, "c.krb5_sname_to_principal", "krb5_sname_to_principal"], [392, 0, 1, "c.krb5_string_to_cksumtype", "krb5_string_to_cksumtype"], [393, 0, 1, "c.krb5_string_to_deltat", "krb5_string_to_deltat"], [394, 0, 1, "c.krb5_string_to_enctype", "krb5_string_to_enctype"], [395, 0, 1, "c.krb5_string_to_key", "krb5_string_to_key"], [396, 0, 1, "c.krb5_string_to_salttype", "krb5_string_to_salttype"], [397, 0, 1, "c.krb5_string_to_timestamp", "krb5_string_to_timestamp"], [889, 2, 1, "c.krb5_ticket", "krb5_ticket"], [890, 2, 1, "c.krb5_ticket_times", "krb5_ticket_times"], [398, 0, 1, "c.krb5_timeofday", "krb5_timeofday"], [891, 2, 1, "c.krb5_timestamp", "krb5_timestamp"], [399, 0, 1, "c.krb5_timestamp_to_sfstring", "krb5_timestamp_to_sfstring"], [400, 0, 1, "c.krb5_timestamp_to_string", "krb5_timestamp_to_string"], [892, 2, 1, "c.krb5_tkt_authent", "krb5_tkt_authent"], [893, 2, 1, "c.krb5_tkt_creds_context", "krb5_tkt_creds_context"], [401, 0, 1, "c.krb5_tkt_creds_free", "krb5_tkt_creds_free"], [402, 0, 1, "c.krb5_tkt_creds_get", "krb5_tkt_creds_get"], [403, 0, 1, "c.krb5_tkt_creds_get_creds", "krb5_tkt_creds_get_creds"], [404, 0, 1, "c.krb5_tkt_creds_get_times", "krb5_tkt_creds_get_times"], [405, 0, 1, "c.krb5_tkt_creds_init", "krb5_tkt_creds_init"], [406, 0, 1, "c.krb5_tkt_creds_step", "krb5_tkt_creds_step"], [894, 2, 1, "c.krb5_trace_callback", "krb5_trace_callback"], [895, 2, 1, "c.krb5_trace_info", "krb5_trace_info"], [896, 2, 1, "c.krb5_transited", "krb5_transited"], [897, 2, 1, "c.krb5_typed_data", "krb5_typed_data"], [898, 2, 1, "c.krb5_ui_2", "krb5_ui_2"], [899, 2, 1, "c.krb5_ui_4", "krb5_ui_4"], [407, 0, 1, "c.krb5_unmarshal_credentials", "krb5_unmarshal_credentials"], [408, 0, 1, "c.krb5_unparse_name", "krb5_unparse_name"], [409, 0, 1, "c.krb5_unparse_name_ext", "krb5_unparse_name_ext"], [410, 0, 1, "c.krb5_unparse_name_flags", "krb5_unparse_name_flags"], [411, 0, 1, "c.krb5_unparse_name_flags_ext", "krb5_unparse_name_flags_ext"], [412, 0, 1, "c.krb5_us_timeofday", "krb5_us_timeofday"], [413, 0, 1, "c.krb5_use_enctype", "krb5_use_enctype"], [414, 0, 1, "c.krb5_verify_authdata_kdc_issued", "krb5_verify_authdata_kdc_issued"], [415, 0, 1, "c.krb5_verify_checksum", "krb5_verify_checksum"], [416, 0, 1, "c.krb5_verify_init_creds", "krb5_verify_init_creds"], [900, 2, 1, "c.krb5_verify_init_creds_opt", "krb5_verify_init_creds_opt"], [417, 0, 1, "c.krb5_verify_init_creds_opt_init", "krb5_verify_init_creds_opt_init"], [418, 0, 1, "c.krb5_verify_init_creds_opt_set_ap_req_nofail", "krb5_verify_init_creds_opt_set_ap_req_nofail"], [419, 0, 1, "c.krb5_vprepend_error_message", "krb5_vprepend_error_message"], [420, 0, 1, "c.krb5_vset_error_message", "krb5_vset_error_message"], [421, 0, 1, "c.krb5_vwrap_error_message", "krb5_vwrap_error_message"], [422, 0, 1, "c.krb5_wrap_error_message", "krb5_wrap_error_message"], [901, 2, 1, "c.passwd_phrase_element", "passwd_phrase_element"], [424, 4, 1, "", "ADDRTYPE_ADDRPORT"], [425, 4, 1, "", "ADDRTYPE_CHAOS"], [426, 4, 1, "", "ADDRTYPE_DDP"], [427, 4, 1, "", "ADDRTYPE_DIRECTIONAL"], [428, 4, 1, "", "ADDRTYPE_INET"], [429, 4, 1, "", "ADDRTYPE_INET6"], [430, 4, 1, "", "ADDRTYPE_IPPORT"], [431, 4, 1, "", "ADDRTYPE_ISO"], [432, 4, 1, "", "ADDRTYPE_IS_LOCAL"], [433, 4, 1, "", "ADDRTYPE_NETBIOS"], [434, 4, 1, "", "ADDRTYPE_UNIXSOCK"], [435, 4, 1, "", "ADDRTYPE_XNS"], [436, 4, 1, "", "AD_TYPE_EXTERNAL"], [437, 4, 1, "", "AD_TYPE_FIELD_TYPE_MASK"], [438, 4, 1, "", "AD_TYPE_REGISTERED"], [439, 4, 1, "", "AD_TYPE_RESERVED"], [440, 4, 1, "", "AP_OPTS_CBT_FLAG"], [441, 4, 1, "", "AP_OPTS_ETYPE_NEGOTIATION"], [442, 4, 1, "", "AP_OPTS_MUTUAL_REQUIRED"], [443, 4, 1, "", "AP_OPTS_RESERVED"], [444, 4, 1, "", "AP_OPTS_USE_SESSION_KEY"], [445, 4, 1, "", "AP_OPTS_USE_SUBKEY"], [446, 4, 1, "", "AP_OPTS_WIRE_MASK"], [447, 4, 1, "", "CKSUMTYPE_CMAC_CAMELLIA128"], [448, 4, 1, "", "CKSUMTYPE_CMAC_CAMELLIA256"], [449, 4, 1, "", "CKSUMTYPE_CRC32"], [450, 4, 1, "", "CKSUMTYPE_DESCBC"], [451, 4, 1, "", "CKSUMTYPE_HMAC_MD5_ARCFOUR"], [452, 4, 1, "", "CKSUMTYPE_HMAC_SHA1_96_AES128"], [453, 4, 1, "", "CKSUMTYPE_HMAC_SHA1_96_AES256"], [454, 4, 1, "", "CKSUMTYPE_HMAC_SHA1_DES3"], [455, 4, 1, "", "CKSUMTYPE_HMAC_SHA256_128_AES128"], [456, 4, 1, "", "CKSUMTYPE_HMAC_SHA384_192_AES256"], [457, 4, 1, "", "CKSUMTYPE_MD5_HMAC_ARCFOUR"], [458, 4, 1, "", "CKSUMTYPE_NIST_SHA"], [459, 4, 1, "", "CKSUMTYPE_RSA_MD4"], [460, 4, 1, "", "CKSUMTYPE_RSA_MD4_DES"], [461, 4, 1, "", "CKSUMTYPE_RSA_MD5"], [462, 4, 1, "", "CKSUMTYPE_RSA_MD5_DES"], [463, 4, 1, "", "CKSUMTYPE_SHA1"], [464, 4, 1, "", "ENCTYPE_AES128_CTS_HMAC_SHA1_96"], [465, 4, 1, "", "ENCTYPE_AES128_CTS_HMAC_SHA256_128"], [466, 4, 1, "", "ENCTYPE_AES256_CTS_HMAC_SHA1_96"], [467, 4, 1, "", "ENCTYPE_AES256_CTS_HMAC_SHA384_192"], [468, 4, 1, "", "ENCTYPE_ARCFOUR_HMAC"], [469, 4, 1, "", "ENCTYPE_ARCFOUR_HMAC_EXP"], [470, 4, 1, "", "ENCTYPE_CAMELLIA128_CTS_CMAC"], [471, 4, 1, "", "ENCTYPE_CAMELLIA256_CTS_CMAC"], [472, 4, 1, "", "ENCTYPE_DES3_CBC_ENV"], [473, 4, 1, "", "ENCTYPE_DES3_CBC_RAW"], [474, 4, 1, "", "ENCTYPE_DES3_CBC_SHA"], [475, 4, 1, "", "ENCTYPE_DES3_CBC_SHA1"], [476, 4, 1, "", "ENCTYPE_DES_CBC_CRC"], [477, 4, 1, "", "ENCTYPE_DES_CBC_MD4"], [478, 4, 1, "", "ENCTYPE_DES_CBC_MD5"], [479, 4, 1, "", "ENCTYPE_DES_CBC_RAW"], [480, 4, 1, "", "ENCTYPE_DES_HMAC_SHA1"], [481, 4, 1, "", "ENCTYPE_DSA_SHA1_CMS"], [482, 4, 1, "", "ENCTYPE_MD5_RSA_CMS"], [483, 4, 1, "", "ENCTYPE_NULL"], [484, 4, 1, "", "ENCTYPE_RC2_CBC_ENV"], [485, 4, 1, "", "ENCTYPE_RSA_ENV"], [486, 4, 1, "", "ENCTYPE_RSA_ES_OAEP_ENV"], [487, 4, 1, "", "ENCTYPE_SHA1_RSA_CMS"], [488, 4, 1, "", "ENCTYPE_UNKNOWN"], [489, 4, 1, "", "KDC_OPT_ALLOW_POSTDATE"], [490, 4, 1, "", "KDC_OPT_CANONICALIZE"], [491, 4, 1, "", "KDC_OPT_CNAME_IN_ADDL_TKT"], [492, 4, 1, "", "KDC_OPT_DISABLE_TRANSITED_CHECK"], [493, 4, 1, "", "KDC_OPT_ENC_TKT_IN_SKEY"], [494, 4, 1, "", "KDC_OPT_FORWARDABLE"], [495, 4, 1, "", "KDC_OPT_FORWARDED"], [496, 4, 1, "", "KDC_OPT_POSTDATED"], [497, 4, 1, "", "KDC_OPT_PROXIABLE"], [498, 4, 1, "", "KDC_OPT_PROXY"], [499, 4, 1, "", "KDC_OPT_RENEW"], [500, 4, 1, "", "KDC_OPT_RENEWABLE"], [501, 4, 1, "", "KDC_OPT_RENEWABLE_OK"], [502, 4, 1, "", "KDC_OPT_REQUEST_ANONYMOUS"], [503, 4, 1, "", "KDC_OPT_VALIDATE"], [504, 4, 1, "", "KDC_TKT_COMMON_MASK"], [505, 4, 1, "", "KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE"], [506, 4, 1, "", "KRB5_ANONYMOUS_PRINCSTR"], [507, 4, 1, "", "KRB5_ANONYMOUS_REALMSTR"], [508, 4, 1, "", "KRB5_AP_REP"], [509, 4, 1, "", "KRB5_AP_REQ"], [510, 4, 1, "", "KRB5_AS_REP"], [511, 4, 1, "", "KRB5_AS_REQ"], [512, 4, 1, "", "KRB5_AUTHDATA_AND_OR"], [513, 4, 1, "", "KRB5_AUTHDATA_AP_OPTIONS"], [514, 4, 1, "", "KRB5_AUTHDATA_AUTH_INDICATOR"], [515, 4, 1, "", "KRB5_AUTHDATA_CAMMAC"], [516, 4, 1, "", "KRB5_AUTHDATA_ETYPE_NEGOTIATION"], [517, 4, 1, "", "KRB5_AUTHDATA_FX_ARMOR"], [518, 4, 1, "", "KRB5_AUTHDATA_IF_RELEVANT"], [519, 4, 1, "", "KRB5_AUTHDATA_INITIAL_VERIFIED_CAS"], [520, 4, 1, "", "KRB5_AUTHDATA_KDC_ISSUED"], [521, 4, 1, "", "KRB5_AUTHDATA_MANDATORY_FOR_KDC"], [522, 4, 1, "", "KRB5_AUTHDATA_OSF_DCE"], [523, 4, 1, "", "KRB5_AUTHDATA_SESAME"], [524, 4, 1, "", "KRB5_AUTHDATA_SIGNTICKET"], [525, 4, 1, "", "KRB5_AUTHDATA_WIN2K_PAC"], [526, 4, 1, "", "KRB5_AUTH_CONTEXT_DO_SEQUENCE"], [527, 4, 1, "", "KRB5_AUTH_CONTEXT_DO_TIME"], [528, 4, 1, "", "KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR"], [529, 4, 1, "", "KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR"], [530, 4, 1, "", "KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR"], [531, 4, 1, "", "KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR"], [532, 4, 1, "", "KRB5_AUTH_CONTEXT_PERMIT_ALL"], [533, 4, 1, "", "KRB5_AUTH_CONTEXT_RET_SEQUENCE"], [534, 4, 1, "", "KRB5_AUTH_CONTEXT_RET_TIME"], [535, 4, 1, "", "KRB5_AUTH_CONTEXT_USE_SUBKEY"], [536, 4, 1, "", "KRB5_CRED"], [537, 4, 1, "", "KRB5_CRYPTO_TYPE_CHECKSUM"], [538, 4, 1, "", "KRB5_CRYPTO_TYPE_DATA"], [539, 4, 1, "", "KRB5_CRYPTO_TYPE_EMPTY"], [540, 4, 1, "", "KRB5_CRYPTO_TYPE_HEADER"], [541, 4, 1, "", "KRB5_CRYPTO_TYPE_PADDING"], [542, 4, 1, "", "KRB5_CRYPTO_TYPE_SIGN_ONLY"], [543, 4, 1, "", "KRB5_CRYPTO_TYPE_STREAM"], [544, 4, 1, "", "KRB5_CRYPTO_TYPE_TRAILER"], [545, 4, 1, "", "KRB5_CYBERSAFE_SECUREID"], [546, 4, 1, "", "KRB5_DOMAIN_X500_COMPRESS"], [547, 4, 1, "", "KRB5_ENCPADATA_REQ_ENC_PA_REP"], [548, 4, 1, "", "KRB5_ERROR"], [549, 4, 1, "", "KRB5_FAST_REQUIRED"], [550, 4, 1, "", "KRB5_GC_CACHED"], [551, 4, 1, "", "KRB5_GC_CANONICALIZE"], [552, 4, 1, "", "KRB5_GC_CONSTRAINED_DELEGATION"], [553, 4, 1, "", "KRB5_GC_FORWARDABLE"], [554, 4, 1, "", "KRB5_GC_NO_STORE"], [555, 4, 1, "", "KRB5_GC_NO_TRANSIT_CHECK"], [556, 4, 1, "", "KRB5_GC_USER_USER"], [557, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST"], [558, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_ANONYMOUS"], [559, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_CANONICALIZE"], [560, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT"], [561, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST"], [562, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_FORWARDABLE"], [563, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST"], [564, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_PROXIABLE"], [565, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE"], [566, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_SALT"], [567, 4, 1, "", "KRB5_GET_INIT_CREDS_OPT_TKT_LIFE"], [568, 4, 1, "", "KRB5_INIT_CONTEXT_KDC"], [569, 4, 1, "", "KRB5_INIT_CONTEXT_SECURE"], [570, 4, 1, "", "KRB5_INIT_CREDS_STEP_FLAG_CONTINUE"], [571, 4, 1, "", "KRB5_INT16_MAX"], [572, 4, 1, "", "KRB5_INT16_MIN"], [573, 4, 1, "", "KRB5_INT32_MAX"], [574, 4, 1, "", "KRB5_INT32_MIN"], [575, 4, 1, "", "KRB5_KEYUSAGE_AD_ITE"], [576, 4, 1, "", "KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM"], [577, 4, 1, "", "KRB5_KEYUSAGE_AD_MTE"], [578, 4, 1, "", "KRB5_KEYUSAGE_AD_SIGNEDPATH"], [579, 4, 1, "", "KRB5_KEYUSAGE_APP_DATA_CKSUM"], [580, 4, 1, "", "KRB5_KEYUSAGE_APP_DATA_ENCRYPT"], [581, 4, 1, "", "KRB5_KEYUSAGE_AP_REP_ENCPART"], [582, 4, 1, "", "KRB5_KEYUSAGE_AP_REQ_AUTH"], [583, 4, 1, "", "KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM"], [584, 4, 1, "", "KRB5_KEYUSAGE_AS_REP_ENCPART"], [585, 4, 1, "", "KRB5_KEYUSAGE_AS_REQ"], [586, 4, 1, "", "KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS"], [587, 4, 1, "", "KRB5_KEYUSAGE_CAMMAC"], [588, 4, 1, "", "KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT"], [589, 4, 1, "", "KRB5_KEYUSAGE_ENC_CHALLENGE_KDC"], [590, 4, 1, "", "KRB5_KEYUSAGE_FAST_ENC"], [591, 4, 1, "", "KRB5_KEYUSAGE_FAST_FINISHED"], [592, 4, 1, "", "KRB5_KEYUSAGE_FAST_REP"], [593, 4, 1, "", "KRB5_KEYUSAGE_FAST_REQ_CHKSUM"], [594, 4, 1, "", "KRB5_KEYUSAGE_FINISHED"], [595, 4, 1, "", "KRB5_KEYUSAGE_GSS_TOK_MIC"], [596, 4, 1, "", "KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG"], [597, 4, 1, "", "KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV"], [598, 4, 1, "", "KRB5_KEYUSAGE_IAKERB_FINISHED"], [599, 4, 1, "", "KRB5_KEYUSAGE_KDC_REP_TICKET"], [600, 4, 1, "", "KRB5_KEYUSAGE_KRB_CRED_ENCPART"], [601, 4, 1, "", "KRB5_KEYUSAGE_KRB_ERROR_CKSUM"], [602, 4, 1, "", "KRB5_KEYUSAGE_KRB_PRIV_ENCPART"], [603, 4, 1, "", "KRB5_KEYUSAGE_KRB_SAFE_CKSUM"], [604, 4, 1, "", "KRB5_KEYUSAGE_PA_AS_FRESHNESS"], [605, 4, 1, "", "KRB5_KEYUSAGE_PA_FX_COOKIE"], [606, 4, 1, "", "KRB5_KEYUSAGE_PA_OTP_REQUEST"], [607, 4, 1, "", "KRB5_KEYUSAGE_PA_PKINIT_KX"], [608, 4, 1, "", "KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY"], [609, 4, 1, "", "KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST"], [610, 4, 1, "", "KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM"], [611, 4, 1, "", "KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID"], [612, 4, 1, "", "KRB5_KEYUSAGE_PA_SAM_RESPONSE"], [613, 4, 1, "", "KRB5_KEYUSAGE_SPAKE"], [614, 4, 1, "", "KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY"], [615, 4, 1, "", "KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY"], [616, 4, 1, "", "KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY"], [617, 4, 1, "", "KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY"], [618, 4, 1, "", "KRB5_KEYUSAGE_TGS_REQ_AUTH"], [619, 4, 1, "", "KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM"], [620, 4, 1, "", "KRB5_KPASSWD_ACCESSDENIED"], [621, 4, 1, "", "KRB5_KPASSWD_AUTHERROR"], [622, 4, 1, "", "KRB5_KPASSWD_BAD_VERSION"], [623, 4, 1, "", "KRB5_KPASSWD_HARDERROR"], [624, 4, 1, "", "KRB5_KPASSWD_INITIAL_FLAG_NEEDED"], [625, 4, 1, "", "KRB5_KPASSWD_MALFORMED"], [626, 4, 1, "", "KRB5_KPASSWD_SOFTERROR"], [627, 4, 1, "", "KRB5_KPASSWD_SUCCESS"], [628, 4, 1, "", "KRB5_LRQ_ALL_ACCT_EXPTIME"], [629, 4, 1, "", "KRB5_LRQ_ALL_LAST_INITIAL"], [630, 4, 1, "", "KRB5_LRQ_ALL_LAST_RENEWAL"], [631, 4, 1, "", "KRB5_LRQ_ALL_LAST_REQ"], [632, 4, 1, "", "KRB5_LRQ_ALL_LAST_TGT"], [633, 4, 1, "", "KRB5_LRQ_ALL_LAST_TGT_ISSUED"], [634, 4, 1, "", "KRB5_LRQ_ALL_PW_EXPTIME"], [635, 4, 1, "", "KRB5_LRQ_NONE"], [636, 4, 1, "", "KRB5_LRQ_ONE_ACCT_EXPTIME"], [637, 4, 1, "", "KRB5_LRQ_ONE_LAST_INITIAL"], [638, 4, 1, "", "KRB5_LRQ_ONE_LAST_RENEWAL"], [639, 4, 1, "", "KRB5_LRQ_ONE_LAST_REQ"], [640, 4, 1, "", "KRB5_LRQ_ONE_LAST_TGT"], [641, 4, 1, "", "KRB5_LRQ_ONE_LAST_TGT_ISSUED"], [642, 4, 1, "", "KRB5_LRQ_ONE_PW_EXPTIME"], [643, 4, 1, "", "KRB5_NT_ENTERPRISE_PRINCIPAL"], [644, 4, 1, "", "KRB5_NT_ENT_PRINCIPAL_AND_ID"], [645, 4, 1, "", "KRB5_NT_MS_PRINCIPAL"], [646, 4, 1, "", "KRB5_NT_MS_PRINCIPAL_AND_ID"], [647, 4, 1, "", "KRB5_NT_PRINCIPAL"], [648, 4, 1, "", "KRB5_NT_SMTP_NAME"], [649, 4, 1, "", "KRB5_NT_SRV_HST"], [650, 4, 1, "", "KRB5_NT_SRV_INST"], [651, 4, 1, "", "KRB5_NT_SRV_XHST"], [652, 4, 1, "", "KRB5_NT_UID"], [653, 4, 1, "", "KRB5_NT_UNKNOWN"], [654, 4, 1, "", "KRB5_NT_WELLKNOWN"], [655, 4, 1, "", "KRB5_NT_X500_PRINCIPAL"], [656, 4, 1, "", "KRB5_PAC_ATTRIBUTES_INFO"], [657, 4, 1, "", "KRB5_PAC_CLIENT_CLAIMS"], [658, 4, 1, "", "KRB5_PAC_CLIENT_INFO"], [659, 4, 1, "", "KRB5_PAC_CREDENTIALS_INFO"], [660, 4, 1, "", "KRB5_PAC_DELEGATION_INFO"], [661, 4, 1, "", "KRB5_PAC_DEVICE_CLAIMS"], [662, 4, 1, "", "KRB5_PAC_DEVICE_INFO"], [663, 4, 1, "", "KRB5_PAC_FULL_CHECKSUM"], [664, 4, 1, "", "KRB5_PAC_LOGON_INFO"], [665, 4, 1, "", "KRB5_PAC_PRIVSVR_CHECKSUM"], [666, 4, 1, "", "KRB5_PAC_REQUESTOR"], [667, 4, 1, "", "KRB5_PAC_SERVER_CHECKSUM"], [668, 4, 1, "", "KRB5_PAC_TICKET_CHECKSUM"], [669, 4, 1, "", "KRB5_PAC_UPN_DNS_INFO"], [670, 4, 1, "", "KRB5_PADATA_AFS3_SALT"], [671, 4, 1, "", "KRB5_PADATA_AP_REQ"], [672, 4, 1, "", "KRB5_PADATA_AS_CHECKSUM"], [673, 4, 1, "", "KRB5_PADATA_AS_FRESHNESS"], [674, 4, 1, "", "KRB5_PADATA_ENCRYPTED_CHALLENGE"], [675, 4, 1, "", "KRB5_PADATA_ENC_SANDIA_SECURID"], [676, 4, 1, "", "KRB5_PADATA_ENC_TIMESTAMP"], [677, 4, 1, "", "KRB5_PADATA_ENC_UNIX_TIME"], [678, 4, 1, "", "KRB5_PADATA_ETYPE_INFO"], [679, 4, 1, "", "KRB5_PADATA_ETYPE_INFO2"], [680, 4, 1, "", "KRB5_PADATA_FOR_USER"], [681, 4, 1, "", "KRB5_PADATA_FX_COOKIE"], [682, 4, 1, "", "KRB5_PADATA_FX_ERROR"], [683, 4, 1, "", "KRB5_PADATA_FX_FAST"], [684, 4, 1, "", "KRB5_PADATA_GET_FROM_TYPED_DATA"], [685, 4, 1, "", "KRB5_PADATA_NONE"], [686, 4, 1, "", "KRB5_PADATA_OSF_DCE"], [687, 4, 1, "", "KRB5_PADATA_OTP_CHALLENGE"], [688, 4, 1, "", "KRB5_PADATA_OTP_PIN_CHANGE"], [689, 4, 1, "", "KRB5_PADATA_OTP_REQUEST"], [690, 4, 1, "", "KRB5_PADATA_PAC_OPTIONS"], [691, 4, 1, "", "KRB5_PADATA_PAC_REQUEST"], [692, 4, 1, "", "KRB5_PADATA_PKINIT_KX"], [693, 4, 1, "", "KRB5_PADATA_PK_AS_REP"], [694, 4, 1, "", "KRB5_PADATA_PK_AS_REP_OLD"], [695, 4, 1, "", "KRB5_PADATA_PK_AS_REQ"], [696, 4, 1, "", "KRB5_PADATA_PK_AS_REQ_OLD"], [697, 4, 1, "", "KRB5_PADATA_PW_SALT"], [698, 4, 1, "", "KRB5_PADATA_REDHAT_IDP_OAUTH2"], [699, 4, 1, "", "KRB5_PADATA_REDHAT_PASSKEY"], [700, 4, 1, "", "KRB5_PADATA_REFERRAL"], [701, 4, 1, "", "KRB5_PADATA_S4U_X509_USER"], [702, 4, 1, "", "KRB5_PADATA_SAM_CHALLENGE"], [703, 4, 1, "", "KRB5_PADATA_SAM_CHALLENGE_2"], [704, 4, 1, "", "KRB5_PADATA_SAM_REDIRECT"], [705, 4, 1, "", "KRB5_PADATA_SAM_RESPONSE"], [706, 4, 1, "", "KRB5_PADATA_SAM_RESPONSE_2"], [707, 4, 1, "", "KRB5_PADATA_SESAME"], [708, 4, 1, "", "KRB5_PADATA_SPAKE"], [709, 4, 1, "", "KRB5_PADATA_SVR_REFERRAL_INFO"], [710, 4, 1, "", "KRB5_PADATA_TGS_REQ"], [711, 4, 1, "", "KRB5_PADATA_USE_SPECIFIED_KVNO"], [712, 4, 1, "", "KRB5_PRINCIPAL_COMPARE_CASEFOLD"], [713, 4, 1, "", "KRB5_PRINCIPAL_COMPARE_ENTERPRISE"], [714, 4, 1, "", "KRB5_PRINCIPAL_COMPARE_IGNORE_REALM"], [715, 4, 1, "", "KRB5_PRINCIPAL_COMPARE_UTF8"], [716, 4, 1, "", "KRB5_PRINCIPAL_PARSE_ENTERPRISE"], [717, 4, 1, "", "KRB5_PRINCIPAL_PARSE_IGNORE_REALM"], [718, 4, 1, "", "KRB5_PRINCIPAL_PARSE_NO_DEF_REALM"], [719, 4, 1, "", "KRB5_PRINCIPAL_PARSE_NO_REALM"], [720, 4, 1, "", "KRB5_PRINCIPAL_PARSE_REQUIRE_REALM"], [721, 4, 1, "", "KRB5_PRINCIPAL_UNPARSE_DISPLAY"], [722, 4, 1, "", "KRB5_PRINCIPAL_UNPARSE_NO_REALM"], [723, 4, 1, "", "KRB5_PRINCIPAL_UNPARSE_SHORT"], [724, 4, 1, "", "KRB5_PRIV"], [725, 4, 1, "", "KRB5_PROMPT_TYPE_NEW_PASSWORD"], [726, 4, 1, "", "KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN"], [727, 4, 1, "", "KRB5_PROMPT_TYPE_PASSWORD"], [728, 4, 1, "", "KRB5_PROMPT_TYPE_PREAUTH"], [729, 4, 1, "", "KRB5_PVNO"], [730, 4, 1, "", "KRB5_REALM_BRANCH_CHAR"], [731, 4, 1, "", "KRB5_RECVAUTH_BADAUTHVERS"], [732, 4, 1, "", "KRB5_RECVAUTH_SKIP_VERSION"], [733, 4, 1, "", "KRB5_REFERRAL_REALM"], [734, 4, 1, "", "KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN"], [735, 4, 1, "", "KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN"], [736, 4, 1, "", "KRB5_RESPONDER_OTP_FLAGS_NEXTOTP"], [737, 4, 1, "", "KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN"], [738, 4, 1, "", "KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC"], [739, 4, 1, "", "KRB5_RESPONDER_OTP_FORMAT_DECIMAL"], [740, 4, 1, "", "KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL"], [741, 4, 1, "", "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW"], [742, 4, 1, "", "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY"], [743, 4, 1, "", "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED"], [744, 4, 1, "", "KRB5_RESPONDER_QUESTION_OTP"], [745, 4, 1, "", "KRB5_RESPONDER_QUESTION_PASSWORD"], [746, 4, 1, "", "KRB5_RESPONDER_QUESTION_PKINIT"], [747, 4, 1, "", "KRB5_SAFE"], [748, 4, 1, "", "KRB5_SAM_MUST_PK_ENCRYPT_SAD"], [749, 4, 1, "", "KRB5_SAM_SEND_ENCRYPTED_SAD"], [750, 4, 1, "", "KRB5_SAM_USE_SAD_AS_KEY"], [751, 4, 1, "", "KRB5_TC_MATCH_2ND_TKT"], [752, 4, 1, "", "KRB5_TC_MATCH_AUTHDATA"], [753, 4, 1, "", "KRB5_TC_MATCH_FLAGS"], [754, 4, 1, "", "KRB5_TC_MATCH_FLAGS_EXACT"], [755, 4, 1, "", "KRB5_TC_MATCH_IS_SKEY"], [756, 4, 1, "", "KRB5_TC_MATCH_KTYPE"], [757, 4, 1, "", "KRB5_TC_MATCH_SRV_NAMEONLY"], [758, 4, 1, "", "KRB5_TC_MATCH_TIMES"], [759, 4, 1, "", "KRB5_TC_MATCH_TIMES_EXACT"], [760, 4, 1, "", "KRB5_TC_NOTICKET"], [761, 4, 1, "", "KRB5_TC_OPENCLOSE"], [762, 4, 1, "", "KRB5_TC_SUPPORTED_KTYPES"], [763, 4, 1, "", "KRB5_TGS_NAME"], [764, 4, 1, "", "KRB5_TGS_NAME_SIZE"], [765, 4, 1, "", "KRB5_TGS_REP"], [766, 4, 1, "", "KRB5_TGS_REQ"], [767, 4, 1, "", "KRB5_TKT_CREDS_STEP_FLAG_CONTINUE"], [768, 4, 1, "", "KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL"], [769, 4, 1, "", "KRB5_WELLKNOWN_NAMESTR"], [770, 4, 1, "", "LR_TYPE_INTERPRETATION_MASK"], [771, 4, 1, "", "LR_TYPE_THIS_SERVER_ONLY"], [772, 4, 1, "", "MAX_KEYTAB_NAME_LEN"], [773, 4, 1, "", "MSEC_DIRBIT"], [774, 4, 1, "", "MSEC_VAL_MASK"], [775, 4, 1, "", "SALT_TYPE_AFS_LENGTH"], [776, 4, 1, "", "SALT_TYPE_NO_LENGTH"], [777, 4, 1, "", "THREEPARAMOPEN"], [778, 4, 1, "", "TKT_FLG_ANONYMOUS"], [779, 4, 1, "", "TKT_FLG_ENC_PA_REP"], [780, 4, 1, "", "TKT_FLG_FORWARDABLE"], [781, 4, 1, "", "TKT_FLG_FORWARDED"], [782, 4, 1, "", "TKT_FLG_HW_AUTH"], [783, 4, 1, "", "TKT_FLG_INITIAL"], [784, 4, 1, "", "TKT_FLG_INVALID"], [785, 4, 1, "", "TKT_FLG_MAY_POSTDATE"], [786, 4, 1, "", "TKT_FLG_OK_AS_DELEGATE"], [787, 4, 1, "", "TKT_FLG_POSTDATED"], [788, 4, 1, "", "TKT_FLG_PRE_AUTH"], [789, 4, 1, "", "TKT_FLG_PROXIABLE"], [790, 4, 1, "", "TKT_FLG_PROXY"], [791, 4, 1, "", "TKT_FLG_RENEWABLE"], [792, 4, 1, "", "TKT_FLG_TRANSIT_POLICY_CHECKED"], [793, 4, 1, "", "VALID_INT_BITS"], [794, 4, 1, "", "VALID_UINT_BITS"], [796, 4, 1, "", "krb524_convert_creds_kdc"], [797, 4, 1, "", "krb524_init_ets"], [798, 4, 1, "", "krb5_const"], [799, 4, 1, "", "krb5_princ_component"], [800, 4, 1, "", "krb5_princ_name"], [801, 4, 1, "", "krb5_princ_realm"], [802, 4, 1, "", "krb5_princ_set_realm"], [803, 4, 1, "", "krb5_princ_set_realm_data"], [804, 4, 1, "", "krb5_princ_set_realm_length"], [805, 4, 1, "", "krb5_princ_size"], [806, 4, 1, "", "krb5_princ_type"], [807, 4, 1, "", "krb5_roundup"], [808, 4, 1, "", "krb5_x"], [809, 4, 1, "", "krb5_xc"]], "krb5_425_conv_principal": [[49, 1, 1, "c.krb5_425_conv_principal", "context"], [49, 1, 1, "c.krb5_425_conv_principal", "instance"], [49, 1, 1, "c.krb5_425_conv_principal", "name"], [49, 1, 1, "c.krb5_425_conv_principal", "princ"], [49, 1, 1, "c.krb5_425_conv_principal", "realm"]], "krb5_524_conv_principal": [[50, 1, 1, "c.krb5_524_conv_principal", "context"], [50, 1, 1, "c.krb5_524_conv_principal", "inst"], [50, 1, 1, "c.krb5_524_conv_principal", "name"], [50, 1, 1, "c.krb5_524_conv_principal", "princ"], [50, 1, 1, "c.krb5_524_conv_principal", "realm"]], "krb5_524_convert_creds": [[51, 1, 1, "c.krb5_524_convert_creds", "context"], [51, 1, 1, "c.krb5_524_convert_creds", "v4creds"], [51, 1, 1, "c.krb5_524_convert_creds", "v5creds"]], "krb5_address": [[811, 3, 1, "c.krb5_address.addrtype", "addrtype"], [811, 3, 1, "c.krb5_address.contents", "contents"], [811, 3, 1, "c.krb5_address.length", "length"], [811, 3, 1, "c.krb5_address.magic", "magic"]], "krb5_address_compare": [[52, 1, 1, "c.krb5_address_compare", "addr1"], [52, 1, 1, "c.krb5_address_compare", "addr2"], [52, 1, 1, "c.krb5_address_compare", "context"]], "krb5_address_order": [[53, 1, 1, "c.krb5_address_order", "addr1"], [53, 1, 1, "c.krb5_address_order", "addr2"], [53, 1, 1, "c.krb5_address_order", "context"]], "krb5_address_search": [[54, 1, 1, "c.krb5_address_search", "addr"], [54, 1, 1, "c.krb5_address_search", "addrlist"], [54, 1, 1, "c.krb5_address_search", "context"]], "krb5_allow_weak_crypto": [[55, 1, 1, "c.krb5_allow_weak_crypto", "context"], [55, 1, 1, "c.krb5_allow_weak_crypto", "enable"]], "krb5_aname_to_localname": [[56, 1, 1, "c.krb5_aname_to_localname", "aname"], [56, 1, 1, "c.krb5_aname_to_localname", "context"], [56, 1, 1, "c.krb5_aname_to_localname", "lname"], [56, 1, 1, "c.krb5_aname_to_localname", "lnsize_in"]], "krb5_anonymous_principal": [[57, 1, 1, "c.krb5_anonymous_principal", "None"]], "krb5_anonymous_realm": [[58, 1, 1, "c.krb5_anonymous_realm", "None"]], "krb5_ap_rep": [[813, 3, 1, "c.krb5_ap_rep.enc_part", "enc_part"], [813, 3, 1, "c.krb5_ap_rep.magic", "magic"]], "krb5_ap_rep_enc_part": [[814, 3, 1, "c.krb5_ap_rep_enc_part.ctime", "ctime"], [814, 3, 1, "c.krb5_ap_rep_enc_part.cusec", "cusec"], [814, 3, 1, "c.krb5_ap_rep_enc_part.magic", "magic"], [814, 3, 1, "c.krb5_ap_rep_enc_part.seq_number", "seq_number"], [814, 3, 1, "c.krb5_ap_rep_enc_part.subkey", "subkey"]], "krb5_ap_req": [[815, 3, 1, "c.krb5_ap_req.ap_options", "ap_options"], [815, 3, 1, "c.krb5_ap_req.authenticator", "authenticator"], [815, 3, 1, "c.krb5_ap_req.magic", "magic"], [815, 3, 1, "c.krb5_ap_req.ticket", "ticket"]], "krb5_appdefault_boolean": [[59, 1, 1, "c.krb5_appdefault_boolean", "appname"], [59, 1, 1, "c.krb5_appdefault_boolean", "context"], [59, 1, 1, "c.krb5_appdefault_boolean", "default_value"], [59, 1, 1, "c.krb5_appdefault_boolean", "option"], [59, 1, 1, "c.krb5_appdefault_boolean", "realm"], [59, 1, 1, "c.krb5_appdefault_boolean", "ret_value"]], "krb5_appdefault_string": [[60, 1, 1, "c.krb5_appdefault_string", "appname"], [60, 1, 1, "c.krb5_appdefault_string", "context"], [60, 1, 1, "c.krb5_appdefault_string", "default_value"], [60, 1, 1, "c.krb5_appdefault_string", "option"], [60, 1, 1, "c.krb5_appdefault_string", "realm"], [60, 1, 1, "c.krb5_appdefault_string", "ret_value"]], "krb5_auth_con_free": [[61, 1, 1, "c.krb5_auth_con_free", "auth_context"], [61, 1, 1, "c.krb5_auth_con_free", "context"]], "krb5_auth_con_genaddrs": [[62, 1, 1, "c.krb5_auth_con_genaddrs", "auth_context"], [62, 1, 1, "c.krb5_auth_con_genaddrs", "context"], [62, 1, 1, "c.krb5_auth_con_genaddrs", "flags"], [62, 1, 1, "c.krb5_auth_con_genaddrs", "infd"]], "krb5_auth_con_get_checksum_func": [[63, 1, 1, "c.krb5_auth_con_get_checksum_func", "auth_context"], [63, 1, 1, "c.krb5_auth_con_get_checksum_func", "context"], [63, 1, 1, "c.krb5_auth_con_get_checksum_func", "data"], [63, 1, 1, "c.krb5_auth_con_get_checksum_func", "func"]], "krb5_auth_con_getaddrs": [[64, 1, 1, "c.krb5_auth_con_getaddrs", "auth_context"], [64, 1, 1, "c.krb5_auth_con_getaddrs", "context"], [64, 1, 1, "c.krb5_auth_con_getaddrs", "local_addr"], [64, 1, 1, "c.krb5_auth_con_getaddrs", "remote_addr"]], "krb5_auth_con_getauthenticator": [[65, 1, 1, "c.krb5_auth_con_getauthenticator", "auth_context"], [65, 1, 1, "c.krb5_auth_con_getauthenticator", "authenticator"], [65, 1, 1, "c.krb5_auth_con_getauthenticator", "context"]], "krb5_auth_con_getflags": [[66, 1, 1, "c.krb5_auth_con_getflags", "auth_context"], [66, 1, 1, "c.krb5_auth_con_getflags", "context"], [66, 1, 1, "c.krb5_auth_con_getflags", "flags"]], "krb5_auth_con_getkey": [[67, 1, 1, "c.krb5_auth_con_getkey", "auth_context"], [67, 1, 1, "c.krb5_auth_con_getkey", "context"], [67, 1, 1, "c.krb5_auth_con_getkey", "keyblock"]], "krb5_auth_con_getkey_k": [[68, 1, 1, "c.krb5_auth_con_getkey_k", "auth_context"], [68, 1, 1, "c.krb5_auth_con_getkey_k", "context"], [68, 1, 1, "c.krb5_auth_con_getkey_k", "key"]], "krb5_auth_con_getlocalseqnumber": [[69, 1, 1, "c.krb5_auth_con_getlocalseqnumber", "auth_context"], [69, 1, 1, "c.krb5_auth_con_getlocalseqnumber", "context"], [69, 1, 1, "c.krb5_auth_con_getlocalseqnumber", "seqnumber"]], "krb5_auth_con_getlocalsubkey": [[70, 1, 1, "c.krb5_auth_con_getlocalsubkey", "auth_context"], [70, 1, 1, "c.krb5_auth_con_getlocalsubkey", "context"], [70, 1, 1, "c.krb5_auth_con_getlocalsubkey", "keyblock"]], "krb5_auth_con_getrcache": [[71, 1, 1, "c.krb5_auth_con_getrcache", "auth_context"], [71, 1, 1, "c.krb5_auth_con_getrcache", "context"], [71, 1, 1, "c.krb5_auth_con_getrcache", "rcache"]], "krb5_auth_con_getrecvsubkey": [[72, 1, 1, "c.krb5_auth_con_getrecvsubkey", "ac"], [72, 1, 1, "c.krb5_auth_con_getrecvsubkey", "ctx"], [72, 1, 1, "c.krb5_auth_con_getrecvsubkey", "keyblock"]], "krb5_auth_con_getrecvsubkey_k": [[73, 1, 1, "c.krb5_auth_con_getrecvsubkey_k", "ac"], [73, 1, 1, "c.krb5_auth_con_getrecvsubkey_k", "ctx"], [73, 1, 1, "c.krb5_auth_con_getrecvsubkey_k", "key"]], "krb5_auth_con_getremoteseqnumber": [[74, 1, 1, "c.krb5_auth_con_getremoteseqnumber", "auth_context"], [74, 1, 1, "c.krb5_auth_con_getremoteseqnumber", "context"], [74, 1, 1, "c.krb5_auth_con_getremoteseqnumber", "seqnumber"]], "krb5_auth_con_getremotesubkey": [[75, 1, 1, "c.krb5_auth_con_getremotesubkey", "auth_context"], [75, 1, 1, "c.krb5_auth_con_getremotesubkey", "context"], [75, 1, 1, "c.krb5_auth_con_getremotesubkey", "keyblock"]], "krb5_auth_con_getsendsubkey": [[76, 1, 1, "c.krb5_auth_con_getsendsubkey", "ac"], [76, 1, 1, "c.krb5_auth_con_getsendsubkey", "ctx"], [76, 1, 1, "c.krb5_auth_con_getsendsubkey", "keyblock"]], "krb5_auth_con_getsendsubkey_k": [[77, 1, 1, "c.krb5_auth_con_getsendsubkey_k", "ac"], [77, 1, 1, "c.krb5_auth_con_getsendsubkey_k", "ctx"], [77, 1, 1, "c.krb5_auth_con_getsendsubkey_k", "key"]], "krb5_auth_con_init": [[78, 1, 1, "c.krb5_auth_con_init", "auth_context"], [78, 1, 1, "c.krb5_auth_con_init", "context"]], "krb5_auth_con_initivector": [[79, 1, 1, "c.krb5_auth_con_initivector", "auth_context"], [79, 1, 1, "c.krb5_auth_con_initivector", "context"]], "krb5_auth_con_set_checksum_func": [[80, 1, 1, "c.krb5_auth_con_set_checksum_func", "auth_context"], [80, 1, 1, "c.krb5_auth_con_set_checksum_func", "context"], [80, 1, 1, "c.krb5_auth_con_set_checksum_func", "data"], [80, 1, 1, "c.krb5_auth_con_set_checksum_func", "func"]], "krb5_auth_con_set_req_cksumtype": [[81, 1, 1, "c.krb5_auth_con_set_req_cksumtype", "auth_context"], [81, 1, 1, "c.krb5_auth_con_set_req_cksumtype", "cksumtype"], [81, 1, 1, "c.krb5_auth_con_set_req_cksumtype", "context"]], "krb5_auth_con_setaddrs": [[82, 1, 1, "c.krb5_auth_con_setaddrs", "auth_context"], [82, 1, 1, "c.krb5_auth_con_setaddrs", "context"], [82, 1, 1, "c.krb5_auth_con_setaddrs", "local_addr"], [82, 1, 1, "c.krb5_auth_con_setaddrs", "remote_addr"]], "krb5_auth_con_setflags": [[83, 1, 1, "c.krb5_auth_con_setflags", "auth_context"], [83, 1, 1, "c.krb5_auth_con_setflags", "context"], [83, 1, 1, "c.krb5_auth_con_setflags", "flags"]], "krb5_auth_con_setports": [[84, 1, 1, "c.krb5_auth_con_setports", "auth_context"], [84, 1, 1, "c.krb5_auth_con_setports", "context"], [84, 1, 1, "c.krb5_auth_con_setports", "local_port"], [84, 1, 1, "c.krb5_auth_con_setports", "remote_port"]], "krb5_auth_con_setrcache": [[85, 1, 1, "c.krb5_auth_con_setrcache", "auth_context"], [85, 1, 1, "c.krb5_auth_con_setrcache", "context"], [85, 1, 1, "c.krb5_auth_con_setrcache", "rcache"]], "krb5_auth_con_setrecvsubkey": [[86, 1, 1, "c.krb5_auth_con_setrecvsubkey", "ac"], [86, 1, 1, "c.krb5_auth_con_setrecvsubkey", "ctx"], [86, 1, 1, "c.krb5_auth_con_setrecvsubkey", "keyblock"]], "krb5_auth_con_setrecvsubkey_k": [[87, 1, 1, "c.krb5_auth_con_setrecvsubkey_k", "ac"], [87, 1, 1, "c.krb5_auth_con_setrecvsubkey_k", "ctx"], [87, 1, 1, "c.krb5_auth_con_setrecvsubkey_k", "key"]], "krb5_auth_con_setsendsubkey": [[88, 1, 1, "c.krb5_auth_con_setsendsubkey", "ac"], [88, 1, 1, "c.krb5_auth_con_setsendsubkey", "ctx"], [88, 1, 1, "c.krb5_auth_con_setsendsubkey", "keyblock"]], "krb5_auth_con_setsendsubkey_k": [[89, 1, 1, "c.krb5_auth_con_setsendsubkey_k", "ac"], [89, 1, 1, "c.krb5_auth_con_setsendsubkey_k", "ctx"], [89, 1, 1, "c.krb5_auth_con_setsendsubkey_k", "key"]], "krb5_auth_con_setuseruserkey": [[90, 1, 1, "c.krb5_auth_con_setuseruserkey", "auth_context"], [90, 1, 1, "c.krb5_auth_con_setuseruserkey", "context"], [90, 1, 1, "c.krb5_auth_con_setuseruserkey", "keyblock"]], "krb5_authdata": [[817, 3, 1, "c.krb5_authdata.ad_type", "ad_type"], [817, 3, 1, "c.krb5_authdata.contents", "contents"], [817, 3, 1, "c.krb5_authdata.length", "length"], [817, 3, 1, "c.krb5_authdata.magic", "magic"]], "krb5_authenticator": [[819, 3, 1, "c.krb5_authenticator.authorization_data", "authorization_data"], [819, 3, 1, "c.krb5_authenticator.checksum", "checksum"], [819, 3, 1, "c.krb5_authenticator.client", "client"], [819, 3, 1, "c.krb5_authenticator.ctime", "ctime"], [819, 3, 1, "c.krb5_authenticator.cusec", "cusec"], [819, 3, 1, "c.krb5_authenticator.magic", "magic"], [819, 3, 1, "c.krb5_authenticator.seq_number", "seq_number"], [819, 3, 1, "c.krb5_authenticator.subkey", "subkey"]], "krb5_build_principal": [[91, 1, 1, "c.krb5_build_principal", "context"], [91, 1, 1, "c.krb5_build_principal", "princ"], [91, 1, 1, "c.krb5_build_principal", "realm"], [91, 1, 1, "c.krb5_build_principal", "rlen"]], "krb5_build_principal_alloc_va": [[92, 1, 1, "c.krb5_build_principal_alloc_va", "ap"], [92, 1, 1, "c.krb5_build_principal_alloc_va", "context"], [92, 1, 1, "c.krb5_build_principal_alloc_va", "princ"], [92, 1, 1, "c.krb5_build_principal_alloc_va", "realm"], [92, 1, 1, "c.krb5_build_principal_alloc_va", "rlen"]], "krb5_build_principal_ext": [[93, 1, 1, "c.krb5_build_principal_ext", "context"], [93, 1, 1, "c.krb5_build_principal_ext", "princ"], [93, 1, 1, "c.krb5_build_principal_ext", "realm"], [93, 1, 1, "c.krb5_build_principal_ext", "rlen"]], "krb5_build_principal_va": [[94, 1, 1, "c.krb5_build_principal_va", "ap"], [94, 1, 1, "c.krb5_build_principal_va", "context"], [94, 1, 1, "c.krb5_build_principal_va", "princ"], [94, 1, 1, "c.krb5_build_principal_va", "realm"], [94, 1, 1, "c.krb5_build_principal_va", "rlen"]], "krb5_c_block_size": [[95, 1, 1, "c.krb5_c_block_size", "blocksize"], [95, 1, 1, "c.krb5_c_block_size", "context"], [95, 1, 1, "c.krb5_c_block_size", "enctype"]], "krb5_c_checksum_length": [[96, 1, 1, "c.krb5_c_checksum_length", "cksumtype"], [96, 1, 1, "c.krb5_c_checksum_length", "context"], [96, 1, 1, "c.krb5_c_checksum_length", "length"]], "krb5_c_crypto_length": [[97, 1, 1, "c.krb5_c_crypto_length", "context"], [97, 1, 1, "c.krb5_c_crypto_length", "enctype"], [97, 1, 1, "c.krb5_c_crypto_length", "size"], [97, 1, 1, "c.krb5_c_crypto_length", "type"]], "krb5_c_crypto_length_iov": [[98, 1, 1, "c.krb5_c_crypto_length_iov", "context"], [98, 1, 1, "c.krb5_c_crypto_length_iov", "data"], [98, 1, 1, "c.krb5_c_crypto_length_iov", "enctype"], [98, 1, 1, "c.krb5_c_crypto_length_iov", "num_data"]], "krb5_c_decrypt": [[99, 1, 1, "c.krb5_c_decrypt", "cipher_state"], [99, 1, 1, "c.krb5_c_decrypt", "context"], [99, 1, 1, "c.krb5_c_decrypt", "input"], [99, 1, 1, "c.krb5_c_decrypt", "key"], [99, 1, 1, "c.krb5_c_decrypt", "output"], [99, 1, 1, "c.krb5_c_decrypt", "usage"]], "krb5_c_decrypt_iov": [[100, 1, 1, "c.krb5_c_decrypt_iov", "cipher_state"], [100, 1, 1, "c.krb5_c_decrypt_iov", "context"], [100, 1, 1, "c.krb5_c_decrypt_iov", "data"], [100, 1, 1, "c.krb5_c_decrypt_iov", "keyblock"], [100, 1, 1, "c.krb5_c_decrypt_iov", "num_data"], [100, 1, 1, "c.krb5_c_decrypt_iov", "usage"]], "krb5_c_derive_prfplus": [[101, 1, 1, "c.krb5_c_derive_prfplus", "context"], [101, 1, 1, "c.krb5_c_derive_prfplus", "enctype"], [101, 1, 1, "c.krb5_c_derive_prfplus", "input"], [101, 1, 1, "c.krb5_c_derive_prfplus", "k"], [101, 1, 1, "c.krb5_c_derive_prfplus", "out"]], "krb5_c_encrypt": [[102, 1, 1, "c.krb5_c_encrypt", "cipher_state"], [102, 1, 1, "c.krb5_c_encrypt", "context"], [102, 1, 1, "c.krb5_c_encrypt", "input"], [102, 1, 1, "c.krb5_c_encrypt", "key"], [102, 1, 1, "c.krb5_c_encrypt", "output"], [102, 1, 1, "c.krb5_c_encrypt", "usage"]], "krb5_c_encrypt_iov": [[103, 1, 1, "c.krb5_c_encrypt_iov", "cipher_state"], [103, 1, 1, "c.krb5_c_encrypt_iov", "context"], [103, 1, 1, "c.krb5_c_encrypt_iov", "data"], [103, 1, 1, "c.krb5_c_encrypt_iov", "keyblock"], [103, 1, 1, "c.krb5_c_encrypt_iov", "num_data"], [103, 1, 1, "c.krb5_c_encrypt_iov", "usage"]], "krb5_c_encrypt_length": [[104, 1, 1, "c.krb5_c_encrypt_length", "context"], [104, 1, 1, "c.krb5_c_encrypt_length", "enctype"], [104, 1, 1, "c.krb5_c_encrypt_length", "inputlen"], [104, 1, 1, "c.krb5_c_encrypt_length", "length"]], "krb5_c_enctype_compare": [[105, 1, 1, "c.krb5_c_enctype_compare", "context"], [105, 1, 1, "c.krb5_c_enctype_compare", "e1"], [105, 1, 1, "c.krb5_c_enctype_compare", "e2"], [105, 1, 1, "c.krb5_c_enctype_compare", "similar"]], "krb5_c_free_state": [[106, 1, 1, "c.krb5_c_free_state", "context"], [106, 1, 1, "c.krb5_c_free_state", "key"], [106, 1, 1, "c.krb5_c_free_state", "state"]], "krb5_c_fx_cf2_simple": [[107, 1, 1, "c.krb5_c_fx_cf2_simple", "context"], [107, 1, 1, "c.krb5_c_fx_cf2_simple", "k1"], [107, 1, 1, "c.krb5_c_fx_cf2_simple", "k2"], [107, 1, 1, "c.krb5_c_fx_cf2_simple", "out"], [107, 1, 1, "c.krb5_c_fx_cf2_simple", "pepper1"], [107, 1, 1, "c.krb5_c_fx_cf2_simple", "pepper2"]], "krb5_c_init_state": [[108, 1, 1, "c.krb5_c_init_state", "context"], [108, 1, 1, "c.krb5_c_init_state", "key"], [108, 1, 1, "c.krb5_c_init_state", "new_state"], [108, 1, 1, "c.krb5_c_init_state", "usage"]], "krb5_c_is_coll_proof_cksum": [[109, 1, 1, "c.krb5_c_is_coll_proof_cksum", "ctype"]], "krb5_c_is_keyed_cksum": [[110, 1, 1, "c.krb5_c_is_keyed_cksum", "ctype"]], "krb5_c_keyed_checksum_types": [[111, 1, 1, "c.krb5_c_keyed_checksum_types", "cksumtypes"], [111, 1, 1, "c.krb5_c_keyed_checksum_types", "context"], [111, 1, 1, "c.krb5_c_keyed_checksum_types", "count"], [111, 1, 1, "c.krb5_c_keyed_checksum_types", "enctype"]], "krb5_c_keylengths": [[112, 1, 1, "c.krb5_c_keylengths", "context"], [112, 1, 1, "c.krb5_c_keylengths", "enctype"], [112, 1, 1, "c.krb5_c_keylengths", "keybytes"], [112, 1, 1, "c.krb5_c_keylengths", "keylength"]], "krb5_c_make_checksum": [[113, 1, 1, "c.krb5_c_make_checksum", "cksum"], [113, 1, 1, "c.krb5_c_make_checksum", "cksumtype"], [113, 1, 1, "c.krb5_c_make_checksum", "context"], [113, 1, 1, "c.krb5_c_make_checksum", "input"], [113, 1, 1, "c.krb5_c_make_checksum", "key"], [113, 1, 1, "c.krb5_c_make_checksum", "usage"]], "krb5_c_make_checksum_iov": [[114, 1, 1, "c.krb5_c_make_checksum_iov", "cksumtype"], [114, 1, 1, "c.krb5_c_make_checksum_iov", "context"], [114, 1, 1, "c.krb5_c_make_checksum_iov", "data"], [114, 1, 1, "c.krb5_c_make_checksum_iov", "key"], [114, 1, 1, "c.krb5_c_make_checksum_iov", "num_data"], [114, 1, 1, "c.krb5_c_make_checksum_iov", "usage"]], "krb5_c_make_random_key": [[115, 1, 1, "c.krb5_c_make_random_key", "context"], [115, 1, 1, "c.krb5_c_make_random_key", "enctype"], [115, 1, 1, "c.krb5_c_make_random_key", "k5_random_key"]], "krb5_c_padding_length": [[116, 1, 1, "c.krb5_c_padding_length", "context"], [116, 1, 1, "c.krb5_c_padding_length", "data_length"], [116, 1, 1, "c.krb5_c_padding_length", "enctype"], [116, 1, 1, "c.krb5_c_padding_length", "size"]], "krb5_c_prf": [[117, 1, 1, "c.krb5_c_prf", "context"], [117, 1, 1, "c.krb5_c_prf", "input"], [117, 1, 1, "c.krb5_c_prf", "keyblock"], [117, 1, 1, "c.krb5_c_prf", "output"]], "krb5_c_prf_length": [[118, 1, 1, "c.krb5_c_prf_length", "context"], [118, 1, 1, "c.krb5_c_prf_length", "enctype"], [118, 1, 1, "c.krb5_c_prf_length", "len"]], "krb5_c_prfplus": [[119, 1, 1, "c.krb5_c_prfplus", "context"], [119, 1, 1, "c.krb5_c_prfplus", "input"], [119, 1, 1, "c.krb5_c_prfplus", "k"], [119, 1, 1, "c.krb5_c_prfplus", "output"]], "krb5_c_random_add_entropy": [[120, 1, 1, "c.krb5_c_random_add_entropy", "context"], [120, 1, 1, "c.krb5_c_random_add_entropy", "data"], [120, 1, 1, "c.krb5_c_random_add_entropy", "randsource"]], "krb5_c_random_make_octets": [[121, 1, 1, "c.krb5_c_random_make_octets", "context"], [121, 1, 1, "c.krb5_c_random_make_octets", "data"]], "krb5_c_random_os_entropy": [[122, 1, 1, "c.krb5_c_random_os_entropy", "context"], [122, 1, 1, "c.krb5_c_random_os_entropy", "strong"], [122, 1, 1, "c.krb5_c_random_os_entropy", "success"]], "krb5_c_random_seed": [[123, 1, 1, "c.krb5_c_random_seed", "context"], [123, 1, 1, "c.krb5_c_random_seed", "data"]], "krb5_c_random_to_key": [[124, 1, 1, "c.krb5_c_random_to_key", "context"], [124, 1, 1, "c.krb5_c_random_to_key", "enctype"], [124, 1, 1, "c.krb5_c_random_to_key", "k5_random_key"], [124, 1, 1, "c.krb5_c_random_to_key", "random_data"]], "krb5_c_string_to_key": [[125, 1, 1, "c.krb5_c_string_to_key", "context"], [125, 1, 1, "c.krb5_c_string_to_key", "enctype"], [125, 1, 1, "c.krb5_c_string_to_key", "key"], [125, 1, 1, "c.krb5_c_string_to_key", "salt"], [125, 1, 1, "c.krb5_c_string_to_key", "string"]], "krb5_c_string_to_key_with_params": [[126, 1, 1, "c.krb5_c_string_to_key_with_params", "context"], [126, 1, 1, "c.krb5_c_string_to_key_with_params", "enctype"], [126, 1, 1, "c.krb5_c_string_to_key_with_params", "key"], [126, 1, 1, "c.krb5_c_string_to_key_with_params", "params"], [126, 1, 1, "c.krb5_c_string_to_key_with_params", "salt"], [126, 1, 1, "c.krb5_c_string_to_key_with_params", "string"]], "krb5_c_valid_cksumtype": [[127, 1, 1, "c.krb5_c_valid_cksumtype", "ctype"]], "krb5_c_valid_enctype": [[128, 1, 1, "c.krb5_c_valid_enctype", "ktype"]], "krb5_c_verify_checksum": [[129, 1, 1, "c.krb5_c_verify_checksum", "cksum"], [129, 1, 1, "c.krb5_c_verify_checksum", "context"], [129, 1, 1, "c.krb5_c_verify_checksum", "data"], [129, 1, 1, "c.krb5_c_verify_checksum", "key"], [129, 1, 1, "c.krb5_c_verify_checksum", "usage"], [129, 1, 1, "c.krb5_c_verify_checksum", "valid"]], "krb5_c_verify_checksum_iov": [[130, 1, 1, "c.krb5_c_verify_checksum_iov", "cksumtype"], [130, 1, 1, "c.krb5_c_verify_checksum_iov", "context"], [130, 1, 1, "c.krb5_c_verify_checksum_iov", "data"], [130, 1, 1, "c.krb5_c_verify_checksum_iov", "key"], [130, 1, 1, "c.krb5_c_verify_checksum_iov", "num_data"], [130, 1, 1, "c.krb5_c_verify_checksum_iov", "usage"], [130, 1, 1, "c.krb5_c_verify_checksum_iov", "valid"]], "krb5_calculate_checksum": [[131, 1, 1, "c.krb5_calculate_checksum", "context"], [131, 1, 1, "c.krb5_calculate_checksum", "ctype"], [131, 1, 1, "c.krb5_calculate_checksum", "in"], [131, 1, 1, "c.krb5_calculate_checksum", "in_length"], [131, 1, 1, "c.krb5_calculate_checksum", "outcksum"], [131, 1, 1, "c.krb5_calculate_checksum", "seed"], [131, 1, 1, "c.krb5_calculate_checksum", "seed_length"]], "krb5_cc_cache_match": [[132, 1, 1, "c.krb5_cc_cache_match", "cache_out"], [132, 1, 1, "c.krb5_cc_cache_match", "client"], [132, 1, 1, "c.krb5_cc_cache_match", "context"]], "krb5_cc_close": [[133, 1, 1, "c.krb5_cc_close", "cache"], [133, 1, 1, "c.krb5_cc_close", "context"]], "krb5_cc_copy_creds": [[134, 1, 1, "c.krb5_cc_copy_creds", "context"], [134, 1, 1, "c.krb5_cc_copy_creds", "incc"], [134, 1, 1, "c.krb5_cc_copy_creds", "outcc"]], "krb5_cc_default": [[135, 1, 1, "c.krb5_cc_default", "ccache"], [135, 1, 1, "c.krb5_cc_default", "context"]], "krb5_cc_default_name": [[136, 1, 1, "c.krb5_cc_default_name", "context"]], "krb5_cc_destroy": [[137, 1, 1, "c.krb5_cc_destroy", "cache"], [137, 1, 1, "c.krb5_cc_destroy", "context"]], "krb5_cc_dup": [[138, 1, 1, "c.krb5_cc_dup", "context"], [138, 1, 1, "c.krb5_cc_dup", "in"], [138, 1, 1, "c.krb5_cc_dup", "out"]], "krb5_cc_end_seq_get": [[139, 1, 1, "c.krb5_cc_end_seq_get", "cache"], [139, 1, 1, "c.krb5_cc_end_seq_get", "context"], [139, 1, 1, "c.krb5_cc_end_seq_get", "cursor"]], "krb5_cc_gen_new": [[140, 1, 1, "c.krb5_cc_gen_new", "cache"], [140, 1, 1, "c.krb5_cc_gen_new", "context"]], "krb5_cc_get_config": [[141, 1, 1, "c.krb5_cc_get_config", "context"], [141, 1, 1, "c.krb5_cc_get_config", "data"], [141, 1, 1, "c.krb5_cc_get_config", "id"], [141, 1, 1, "c.krb5_cc_get_config", "key"], [141, 1, 1, "c.krb5_cc_get_config", "principal"]], "krb5_cc_get_flags": [[142, 1, 1, "c.krb5_cc_get_flags", "cache"], [142, 1, 1, "c.krb5_cc_get_flags", "context"], [142, 1, 1, "c.krb5_cc_get_flags", "flags"]], "krb5_cc_get_full_name": [[143, 1, 1, "c.krb5_cc_get_full_name", "cache"], [143, 1, 1, "c.krb5_cc_get_full_name", "context"], [143, 1, 1, "c.krb5_cc_get_full_name", "fullname_out"]], "krb5_cc_get_name": [[144, 1, 1, "c.krb5_cc_get_name", "cache"], [144, 1, 1, "c.krb5_cc_get_name", "context"]], "krb5_cc_get_principal": [[145, 1, 1, "c.krb5_cc_get_principal", "cache"], [145, 1, 1, "c.krb5_cc_get_principal", "context"], [145, 1, 1, "c.krb5_cc_get_principal", "principal"]], "krb5_cc_get_type": [[146, 1, 1, "c.krb5_cc_get_type", "cache"], [146, 1, 1, "c.krb5_cc_get_type", "context"]], "krb5_cc_initialize": [[147, 1, 1, "c.krb5_cc_initialize", "cache"], [147, 1, 1, "c.krb5_cc_initialize", "context"], [147, 1, 1, "c.krb5_cc_initialize", "principal"]], "krb5_cc_move": [[148, 1, 1, "c.krb5_cc_move", "context"], [148, 1, 1, "c.krb5_cc_move", "dst"], [148, 1, 1, "c.krb5_cc_move", "src"]], "krb5_cc_new_unique": [[149, 1, 1, "c.krb5_cc_new_unique", "context"], [149, 1, 1, "c.krb5_cc_new_unique", "hint"], [149, 1, 1, "c.krb5_cc_new_unique", "id"], [149, 1, 1, "c.krb5_cc_new_unique", "type"]], "krb5_cc_next_cred": [[150, 1, 1, "c.krb5_cc_next_cred", "cache"], [150, 1, 1, "c.krb5_cc_next_cred", "context"], [150, 1, 1, "c.krb5_cc_next_cred", "creds"], [150, 1, 1, "c.krb5_cc_next_cred", "cursor"]], "krb5_cc_remove_cred": [[151, 1, 1, "c.krb5_cc_remove_cred", "cache"], [151, 1, 1, "c.krb5_cc_remove_cred", "context"], [151, 1, 1, "c.krb5_cc_remove_cred", "creds"], [151, 1, 1, "c.krb5_cc_remove_cred", "flags"]], "krb5_cc_resolve": [[152, 1, 1, "c.krb5_cc_resolve", "cache"], [152, 1, 1, "c.krb5_cc_resolve", "context"], [152, 1, 1, "c.krb5_cc_resolve", "name"]], "krb5_cc_retrieve_cred": [[153, 1, 1, "c.krb5_cc_retrieve_cred", "cache"], [153, 1, 1, "c.krb5_cc_retrieve_cred", "context"], [153, 1, 1, "c.krb5_cc_retrieve_cred", "creds"], [153, 1, 1, "c.krb5_cc_retrieve_cred", "flags"], [153, 1, 1, "c.krb5_cc_retrieve_cred", "mcreds"]], "krb5_cc_select": [[154, 1, 1, "c.krb5_cc_select", "cache_out"], [154, 1, 1, "c.krb5_cc_select", "context"], [154, 1, 1, "c.krb5_cc_select", "princ_out"], [154, 1, 1, "c.krb5_cc_select", "server"]], "krb5_cc_set_config": [[155, 1, 1, "c.krb5_cc_set_config", "context"], [155, 1, 1, "c.krb5_cc_set_config", "data"], [155, 1, 1, "c.krb5_cc_set_config", "id"], [155, 1, 1, "c.krb5_cc_set_config", "key"], [155, 1, 1, "c.krb5_cc_set_config", "principal"]], "krb5_cc_set_default_name": [[156, 1, 1, "c.krb5_cc_set_default_name", "context"], [156, 1, 1, "c.krb5_cc_set_default_name", "name"]], "krb5_cc_set_flags": [[157, 1, 1, "c.krb5_cc_set_flags", "cache"], [157, 1, 1, "c.krb5_cc_set_flags", "context"], [157, 1, 1, "c.krb5_cc_set_flags", "flags"]], "krb5_cc_start_seq_get": [[158, 1, 1, "c.krb5_cc_start_seq_get", "cache"], [158, 1, 1, "c.krb5_cc_start_seq_get", "context"], [158, 1, 1, "c.krb5_cc_start_seq_get", "cursor"]], "krb5_cc_store_cred": [[159, 1, 1, "c.krb5_cc_store_cred", "cache"], [159, 1, 1, "c.krb5_cc_store_cred", "context"], [159, 1, 1, "c.krb5_cc_store_cred", "creds"]], "krb5_cc_support_switch": [[160, 1, 1, "c.krb5_cc_support_switch", "context"], [160, 1, 1, "c.krb5_cc_support_switch", "type"]], "krb5_cc_switch": [[161, 1, 1, "c.krb5_cc_switch", "cache"], [161, 1, 1, "c.krb5_cc_switch", "context"]], "krb5_cccol_cursor_free": [[162, 1, 1, "c.krb5_cccol_cursor_free", "context"], [162, 1, 1, "c.krb5_cccol_cursor_free", "cursor"]], "krb5_cccol_cursor_new": [[163, 1, 1, "c.krb5_cccol_cursor_new", "context"], [163, 1, 1, "c.krb5_cccol_cursor_new", "cursor"]], "krb5_cccol_cursor_next": [[164, 1, 1, "c.krb5_cccol_cursor_next", "ccache"], [164, 1, 1, "c.krb5_cccol_cursor_next", "context"], [164, 1, 1, "c.krb5_cccol_cursor_next", "cursor"]], "krb5_cccol_have_content": [[165, 1, 1, "c.krb5_cccol_have_content", "context"]], "krb5_change_password": [[166, 1, 1, "c.krb5_change_password", "context"], [166, 1, 1, "c.krb5_change_password", "creds"], [166, 1, 1, "c.krb5_change_password", "newpw"], [166, 1, 1, "c.krb5_change_password", "result_code"], [166, 1, 1, "c.krb5_change_password", "result_code_string"], [166, 1, 1, "c.krb5_change_password", "result_string"]], "krb5_check_clockskew": [[167, 1, 1, "c.krb5_check_clockskew", "context"], [167, 1, 1, "c.krb5_check_clockskew", "date"]], "krb5_checksum": [[824, 3, 1, "c.krb5_checksum.checksum_type", "checksum_type"], [824, 3, 1, "c.krb5_checksum.contents", "contents"], [824, 3, 1, "c.krb5_checksum.length", "length"], [824, 3, 1, "c.krb5_checksum.magic", "magic"]], "krb5_checksum_size": [[168, 1, 1, "c.krb5_checksum_size", "context"], [168, 1, 1, "c.krb5_checksum_size", "ctype"]], "krb5_chpw_message": [[169, 1, 1, "c.krb5_chpw_message", "context"], [169, 1, 1, "c.krb5_chpw_message", "message_out"], [169, 1, 1, "c.krb5_chpw_message", "server_string"]], "krb5_cksumtype_to_string": [[170, 1, 1, "c.krb5_cksumtype_to_string", "buffer"], [170, 1, 1, "c.krb5_cksumtype_to_string", "buflen"], [170, 1, 1, "c.krb5_cksumtype_to_string", "cksumtype"]], "krb5_clear_error_message": [[171, 1, 1, "c.krb5_clear_error_message", "ctx"]], "krb5_const_principal": [[827, 3, 1, "c.krb5_const_principal.data", "data"], [827, 3, 1, "c.krb5_const_principal.length", "length"], [827, 3, 1, "c.krb5_const_principal.magic", "magic"], [827, 3, 1, "c.krb5_const_principal.realm", "realm"], [827, 3, 1, "c.krb5_const_principal.type", "type"]], "krb5_copy_addresses": [[172, 1, 1, "c.krb5_copy_addresses", "context"], [172, 1, 1, "c.krb5_copy_addresses", "inaddr"], [172, 1, 1, "c.krb5_copy_addresses", "outaddr"]], "krb5_copy_authdata": [[173, 1, 1, "c.krb5_copy_authdata", "context"], [173, 1, 1, "c.krb5_copy_authdata", "in_authdat"], [173, 1, 1, "c.krb5_copy_authdata", "out"]], "krb5_copy_authenticator": [[174, 1, 1, "c.krb5_copy_authenticator", "authfrom"], [174, 1, 1, "c.krb5_copy_authenticator", "authto"], [174, 1, 1, "c.krb5_copy_authenticator", "context"]], "krb5_copy_checksum": [[175, 1, 1, "c.krb5_copy_checksum", "ckfrom"], [175, 1, 1, "c.krb5_copy_checksum", "ckto"], [175, 1, 1, "c.krb5_copy_checksum", "context"]], "krb5_copy_context": [[176, 1, 1, "c.krb5_copy_context", "ctx"], [176, 1, 1, "c.krb5_copy_context", "nctx_out"]], "krb5_copy_creds": [[177, 1, 1, "c.krb5_copy_creds", "context"], [177, 1, 1, "c.krb5_copy_creds", "incred"], [177, 1, 1, "c.krb5_copy_creds", "outcred"]], "krb5_copy_data": [[178, 1, 1, "c.krb5_copy_data", "context"], [178, 1, 1, "c.krb5_copy_data", "indata"], [178, 1, 1, "c.krb5_copy_data", "outdata"]], "krb5_copy_error_message": [[179, 1, 1, "c.krb5_copy_error_message", "dest_ctx"], [179, 1, 1, "c.krb5_copy_error_message", "src_ctx"]], "krb5_copy_keyblock": [[180, 1, 1, "c.krb5_copy_keyblock", "context"], [180, 1, 1, "c.krb5_copy_keyblock", "from"], [180, 1, 1, "c.krb5_copy_keyblock", "to"]], "krb5_copy_keyblock_contents": [[181, 1, 1, "c.krb5_copy_keyblock_contents", "context"], [181, 1, 1, "c.krb5_copy_keyblock_contents", "from"], [181, 1, 1, "c.krb5_copy_keyblock_contents", "to"]], "krb5_copy_principal": [[182, 1, 1, "c.krb5_copy_principal", "context"], [182, 1, 1, "c.krb5_copy_principal", "inprinc"], [182, 1, 1, "c.krb5_copy_principal", "outprinc"]], "krb5_copy_ticket": [[183, 1, 1, "c.krb5_copy_ticket", "context"], [183, 1, 1, "c.krb5_copy_ticket", "from"], [183, 1, 1, "c.krb5_copy_ticket", "pto"]], "krb5_cred": [[829, 3, 1, "c.krb5_cred.enc_part", "enc_part"], [829, 3, 1, "c.krb5_cred.enc_part2", "enc_part2"], [829, 3, 1, "c.krb5_cred.magic", "magic"], [829, 3, 1, "c.krb5_cred.tickets", "tickets"]], "krb5_cred_enc_part": [[830, 3, 1, "c.krb5_cred_enc_part.magic", "magic"], [830, 3, 1, "c.krb5_cred_enc_part.nonce", "nonce"], [830, 3, 1, "c.krb5_cred_enc_part.r_address", "r_address"], [830, 3, 1, "c.krb5_cred_enc_part.s_address", "s_address"], [830, 3, 1, "c.krb5_cred_enc_part.ticket_info", "ticket_info"], [830, 3, 1, "c.krb5_cred_enc_part.timestamp", "timestamp"], [830, 3, 1, "c.krb5_cred_enc_part.usec", "usec"]], "krb5_cred_info": [[831, 3, 1, "c.krb5_cred_info.caddrs", "caddrs"], [831, 3, 1, "c.krb5_cred_info.client", "client"], [831, 3, 1, "c.krb5_cred_info.flags", "flags"], [831, 3, 1, "c.krb5_cred_info.magic", "magic"], [831, 3, 1, "c.krb5_cred_info.server", "server"], [831, 3, 1, "c.krb5_cred_info.session", "session"], [831, 3, 1, "c.krb5_cred_info.times", "times"]], "krb5_creds": [[832, 3, 1, "c.krb5_creds.addresses", "addresses"], [832, 3, 1, "c.krb5_creds.authdata", "authdata"], [832, 3, 1, "c.krb5_creds.client", "client"], [832, 3, 1, "c.krb5_creds.is_skey", "is_skey"], [832, 3, 1, "c.krb5_creds.keyblock", "keyblock"], [832, 3, 1, "c.krb5_creds.magic", "magic"], [832, 3, 1, "c.krb5_creds.second_ticket", "second_ticket"], [832, 3, 1, "c.krb5_creds.server", "server"], [832, 3, 1, "c.krb5_creds.ticket", "ticket"], [832, 3, 1, "c.krb5_creds.ticket_flags", "ticket_flags"], [832, 3, 1, "c.krb5_creds.times", "times"]], "krb5_crypto_iov": [[833, 3, 1, "c.krb5_crypto_iov.data", "data"], [833, 3, 1, "c.krb5_crypto_iov.flags", "flags"]], "krb5_data": [[835, 3, 1, "c.krb5_data.data", "data"], [835, 3, 1, "c.krb5_data.length", "length"], [835, 3, 1, "c.krb5_data.magic", "magic"]], "krb5_decode_authdata_container": [[184, 1, 1, "c.krb5_decode_authdata_container", "authdata"], [184, 1, 1, "c.krb5_decode_authdata_container", "container"], [184, 1, 1, "c.krb5_decode_authdata_container", "context"], [184, 1, 1, "c.krb5_decode_authdata_container", "type"]], "krb5_decode_ticket": [[185, 1, 1, "c.krb5_decode_ticket", "code"], [185, 1, 1, "c.krb5_decode_ticket", "rep"]], "krb5_decrypt": [[186, 1, 1, "c.krb5_decrypt", "context"], [186, 1, 1, "c.krb5_decrypt", "eblock"], [186, 1, 1, "c.krb5_decrypt", "inptr"], [186, 1, 1, "c.krb5_decrypt", "ivec"], [186, 1, 1, "c.krb5_decrypt", "outptr"], [186, 1, 1, "c.krb5_decrypt", "size"]], "krb5_deltat_to_string": [[187, 1, 1, "c.krb5_deltat_to_string", "buffer"], [187, 1, 1, "c.krb5_deltat_to_string", "buflen"], [187, 1, 1, "c.krb5_deltat_to_string", "deltat"]], "krb5_eblock_enctype": [[188, 1, 1, "c.krb5_eblock_enctype", "context"], [188, 1, 1, "c.krb5_eblock_enctype", "eblock"]], "krb5_enc_data": [[837, 3, 1, "c.krb5_enc_data.ciphertext", "ciphertext"], [837, 3, 1, "c.krb5_enc_data.enctype", "enctype"], [837, 3, 1, "c.krb5_enc_data.kvno", "kvno"], [837, 3, 1, "c.krb5_enc_data.magic", "magic"]], "krb5_enc_kdc_rep_part": [[838, 3, 1, "c.krb5_enc_kdc_rep_part.caddrs", "caddrs"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.enc_padata", "enc_padata"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.flags", "flags"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.key_exp", "key_exp"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.last_req", "last_req"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.magic", "magic"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.msg_type", "msg_type"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.nonce", "nonce"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.server", "server"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.session", "session"], [838, 3, 1, "c.krb5_enc_kdc_rep_part.times", "times"]], "krb5_enc_tkt_part": [[839, 3, 1, "c.krb5_enc_tkt_part.authorization_data", "authorization_data"], [839, 3, 1, "c.krb5_enc_tkt_part.caddrs", "caddrs"], [839, 3, 1, "c.krb5_enc_tkt_part.client", "client"], [839, 3, 1, "c.krb5_enc_tkt_part.flags", "flags"], [839, 3, 1, "c.krb5_enc_tkt_part.magic", "magic"], [839, 3, 1, "c.krb5_enc_tkt_part.session", "session"], [839, 3, 1, "c.krb5_enc_tkt_part.times", "times"], [839, 3, 1, "c.krb5_enc_tkt_part.transited", "transited"]], "krb5_encode_authdata_container": [[189, 1, 1, "c.krb5_encode_authdata_container", "authdata"], [189, 1, 1, "c.krb5_encode_authdata_container", "container"], [189, 1, 1, "c.krb5_encode_authdata_container", "context"], [189, 1, 1, "c.krb5_encode_authdata_container", "type"]], "krb5_encrypt": [[190, 1, 1, "c.krb5_encrypt", "context"], [190, 1, 1, "c.krb5_encrypt", "eblock"], [190, 1, 1, "c.krb5_encrypt", "inptr"], [190, 1, 1, "c.krb5_encrypt", "ivec"], [190, 1, 1, "c.krb5_encrypt", "outptr"], [190, 1, 1, "c.krb5_encrypt", "size"]], "krb5_encrypt_block": [[840, 3, 1, "c.krb5_encrypt_block.crypto_entry", "crypto_entry"], [840, 3, 1, "c.krb5_encrypt_block.key", "key"], [840, 3, 1, "c.krb5_encrypt_block.magic", "magic"]], "krb5_encrypt_size": [[191, 1, 1, "c.krb5_encrypt_size", "crypto"], [191, 1, 1, "c.krb5_encrypt_size", "length"]], "krb5_enctype_to_name": [[192, 1, 1, "c.krb5_enctype_to_name", "buffer"], [192, 1, 1, "c.krb5_enctype_to_name", "buflen"], [192, 1, 1, "c.krb5_enctype_to_name", "enctype"], [192, 1, 1, "c.krb5_enctype_to_name", "shortest"]], "krb5_enctype_to_string": [[193, 1, 1, "c.krb5_enctype_to_string", "buffer"], [193, 1, 1, "c.krb5_enctype_to_string", "buflen"], [193, 1, 1, "c.krb5_enctype_to_string", "enctype"]], "krb5_error": [[842, 3, 1, "c.krb5_error.client", "client"], [842, 3, 1, "c.krb5_error.ctime", "ctime"], [842, 3, 1, "c.krb5_error.cusec", "cusec"], [842, 3, 1, "c.krb5_error.e_data", "e_data"], [842, 3, 1, "c.krb5_error.error", "error"], [842, 3, 1, "c.krb5_error.magic", "magic"], [842, 3, 1, "c.krb5_error.server", "server"], [842, 3, 1, "c.krb5_error.stime", "stime"], [842, 3, 1, "c.krb5_error.susec", "susec"], [842, 3, 1, "c.krb5_error.text", "text"]], "krb5_expand_hostname": [[194, 1, 1, "c.krb5_expand_hostname", "canonhost_out"], [194, 1, 1, "c.krb5_expand_hostname", "context"], [194, 1, 1, "c.krb5_expand_hostname", "host"]], "krb5_find_authdata": [[195, 1, 1, "c.krb5_find_authdata", "ad_type"], [195, 1, 1, "c.krb5_find_authdata", "ap_req_authdata"], [195, 1, 1, "c.krb5_find_authdata", "context"], [195, 1, 1, "c.krb5_find_authdata", "results"], [195, 1, 1, "c.krb5_find_authdata", "ticket_authdata"]], "krb5_finish_key": [[196, 1, 1, "c.krb5_finish_key", "context"], [196, 1, 1, "c.krb5_finish_key", "eblock"]], "krb5_finish_random_key": [[197, 1, 1, "c.krb5_finish_random_key", "context"], [197, 1, 1, "c.krb5_finish_random_key", "eblock"], [197, 1, 1, "c.krb5_finish_random_key", "ptr"]], "krb5_free_addresses": [[198, 1, 1, "c.krb5_free_addresses", "context"], [198, 1, 1, "c.krb5_free_addresses", "val"]], "krb5_free_ap_rep_enc_part": [[199, 1, 1, "c.krb5_free_ap_rep_enc_part", "context"], [199, 1, 1, "c.krb5_free_ap_rep_enc_part", "val"]], "krb5_free_authdata": [[200, 1, 1, "c.krb5_free_authdata", "context"], [200, 1, 1, "c.krb5_free_authdata", "val"]], "krb5_free_authenticator": [[201, 1, 1, "c.krb5_free_authenticator", "context"], [201, 1, 1, "c.krb5_free_authenticator", "val"]], "krb5_free_checksum": [[202, 1, 1, "c.krb5_free_checksum", "context"], [202, 1, 1, "c.krb5_free_checksum", "val"]], "krb5_free_checksum_contents": [[203, 1, 1, "c.krb5_free_checksum_contents", "context"], [203, 1, 1, "c.krb5_free_checksum_contents", "val"]], "krb5_free_cksumtypes": [[204, 1, 1, "c.krb5_free_cksumtypes", "context"], [204, 1, 1, "c.krb5_free_cksumtypes", "val"]], "krb5_free_config_files": [[205, 1, 1, "c.krb5_free_config_files", "filenames"]], "krb5_free_context": [[206, 1, 1, "c.krb5_free_context", "context"]], "krb5_free_cred_contents": [[207, 1, 1, "c.krb5_free_cred_contents", "context"], [207, 1, 1, "c.krb5_free_cred_contents", "val"]], "krb5_free_creds": [[208, 1, 1, "c.krb5_free_creds", "context"], [208, 1, 1, "c.krb5_free_creds", "val"]], "krb5_free_data": [[209, 1, 1, "c.krb5_free_data", "context"], [209, 1, 1, "c.krb5_free_data", "val"]], "krb5_free_data_contents": [[210, 1, 1, "c.krb5_free_data_contents", "context"], [210, 1, 1, "c.krb5_free_data_contents", "val"]], "krb5_free_default_realm": [[211, 1, 1, "c.krb5_free_default_realm", "context"], [211, 1, 1, "c.krb5_free_default_realm", "lrealm"]], "krb5_free_enctypes": [[212, 1, 1, "c.krb5_free_enctypes", "context"], [212, 1, 1, "c.krb5_free_enctypes", "val"]], "krb5_free_error": [[213, 1, 1, "c.krb5_free_error", "context"], [213, 1, 1, "c.krb5_free_error", "val"]], "krb5_free_error_message": [[214, 1, 1, "c.krb5_free_error_message", "ctx"], [214, 1, 1, "c.krb5_free_error_message", "msg"]], "krb5_free_host_realm": [[215, 1, 1, "c.krb5_free_host_realm", "context"], [215, 1, 1, "c.krb5_free_host_realm", "realmlist"]], "krb5_free_keyblock": [[216, 1, 1, "c.krb5_free_keyblock", "context"], [216, 1, 1, "c.krb5_free_keyblock", "val"]], "krb5_free_keyblock_contents": [[217, 1, 1, "c.krb5_free_keyblock_contents", "context"], [217, 1, 1, "c.krb5_free_keyblock_contents", "key"]], "krb5_free_keytab_entry_contents": [[218, 1, 1, "c.krb5_free_keytab_entry_contents", "context"], [218, 1, 1, "c.krb5_free_keytab_entry_contents", "entry"]], "krb5_free_principal": [[219, 1, 1, "c.krb5_free_principal", "context"], [219, 1, 1, "c.krb5_free_principal", "val"]], "krb5_free_string": [[220, 1, 1, "c.krb5_free_string", "context"], [220, 1, 1, "c.krb5_free_string", "val"]], "krb5_free_tgt_creds": [[221, 1, 1, "c.krb5_free_tgt_creds", "context"], [221, 1, 1, "c.krb5_free_tgt_creds", "tgts"]], "krb5_free_ticket": [[222, 1, 1, "c.krb5_free_ticket", "context"], [222, 1, 1, "c.krb5_free_ticket", "val"]], "krb5_free_unparsed_name": [[223, 1, 1, "c.krb5_free_unparsed_name", "context"], [223, 1, 1, "c.krb5_free_unparsed_name", "val"]], "krb5_fwd_tgt_creds": [[224, 1, 1, "c.krb5_fwd_tgt_creds", "auth_context"], [224, 1, 1, "c.krb5_fwd_tgt_creds", "cc"], [224, 1, 1, "c.krb5_fwd_tgt_creds", "client"], [224, 1, 1, "c.krb5_fwd_tgt_creds", "context"], [224, 1, 1, "c.krb5_fwd_tgt_creds", "forwardable"], [224, 1, 1, "c.krb5_fwd_tgt_creds", "outbuf"], [224, 1, 1, "c.krb5_fwd_tgt_creds", "rhost"], [224, 1, 1, "c.krb5_fwd_tgt_creds", "server"]], "krb5_get_credentials": [[225, 1, 1, "c.krb5_get_credentials", "ccache"], [225, 1, 1, "c.krb5_get_credentials", "context"], [225, 1, 1, "c.krb5_get_credentials", "in_creds"], [225, 1, 1, "c.krb5_get_credentials", "options"], [225, 1, 1, "c.krb5_get_credentials", "out_creds"]], "krb5_get_credentials_renew": [[226, 1, 1, "c.krb5_get_credentials_renew", "ccache"], [226, 1, 1, "c.krb5_get_credentials_renew", "context"], [226, 1, 1, "c.krb5_get_credentials_renew", "in_creds"], [226, 1, 1, "c.krb5_get_credentials_renew", "options"], [226, 1, 1, "c.krb5_get_credentials_renew", "out_creds"]], "krb5_get_credentials_validate": [[227, 1, 1, "c.krb5_get_credentials_validate", "ccache"], [227, 1, 1, "c.krb5_get_credentials_validate", "context"], [227, 1, 1, "c.krb5_get_credentials_validate", "in_creds"], [227, 1, 1, "c.krb5_get_credentials_validate", "options"], [227, 1, 1, "c.krb5_get_credentials_validate", "out_creds"]], "krb5_get_default_config_files": [[228, 1, 1, "c.krb5_get_default_config_files", "filenames"]], "krb5_get_default_realm": [[229, 1, 1, "c.krb5_get_default_realm", "context"], [229, 1, 1, "c.krb5_get_default_realm", "lrealm"]], "krb5_get_error_message": [[230, 1, 1, "c.krb5_get_error_message", "code"], [230, 1, 1, "c.krb5_get_error_message", "ctx"]], "krb5_get_etype_info": [[231, 1, 1, "c.krb5_get_etype_info", "context"], [231, 1, 1, "c.krb5_get_etype_info", "enctype_out"], [231, 1, 1, "c.krb5_get_etype_info", "opt"], [231, 1, 1, "c.krb5_get_etype_info", "principal"], [231, 1, 1, "c.krb5_get_etype_info", "s2kparams_out"], [231, 1, 1, "c.krb5_get_etype_info", "salt_out"]], "krb5_get_fallback_host_realm": [[232, 1, 1, "c.krb5_get_fallback_host_realm", "context"], [232, 1, 1, "c.krb5_get_fallback_host_realm", "hdata"], [232, 1, 1, "c.krb5_get_fallback_host_realm", "realmsp"]], "krb5_get_host_realm": [[233, 1, 1, "c.krb5_get_host_realm", "context"], [233, 1, 1, "c.krb5_get_host_realm", "host"], [233, 1, 1, "c.krb5_get_host_realm", "realmsp"]], "krb5_get_in_tkt_with_keytab": [[234, 1, 1, "c.krb5_get_in_tkt_with_keytab", "addrs"], [234, 1, 1, "c.krb5_get_in_tkt_with_keytab", "arg_keytab"], [234, 1, 1, "c.krb5_get_in_tkt_with_keytab", "ccache"], [234, 1, 1, "c.krb5_get_in_tkt_with_keytab", "context"], [234, 1, 1, "c.krb5_get_in_tkt_with_keytab", "creds"], [234, 1, 1, "c.krb5_get_in_tkt_with_keytab", "ktypes"], [234, 1, 1, "c.krb5_get_in_tkt_with_keytab", "options"], [234, 1, 1, "c.krb5_get_in_tkt_with_keytab", "pre_auth_types"], [234, 1, 1, "c.krb5_get_in_tkt_with_keytab", "ret_as_reply"]], "krb5_get_in_tkt_with_password": [[235, 1, 1, "c.krb5_get_in_tkt_with_password", "addrs"], [235, 1, 1, "c.krb5_get_in_tkt_with_password", "ccache"], [235, 1, 1, "c.krb5_get_in_tkt_with_password", "context"], [235, 1, 1, "c.krb5_get_in_tkt_with_password", "creds"], [235, 1, 1, "c.krb5_get_in_tkt_with_password", "ktypes"], [235, 1, 1, "c.krb5_get_in_tkt_with_password", "options"], [235, 1, 1, "c.krb5_get_in_tkt_with_password", "password"], [235, 1, 1, "c.krb5_get_in_tkt_with_password", "pre_auth_types"], [235, 1, 1, "c.krb5_get_in_tkt_with_password", "ret_as_reply"]], "krb5_get_in_tkt_with_skey": [[236, 1, 1, "c.krb5_get_in_tkt_with_skey", "addrs"], [236, 1, 1, "c.krb5_get_in_tkt_with_skey", "ccache"], [236, 1, 1, "c.krb5_get_in_tkt_with_skey", "context"], [236, 1, 1, "c.krb5_get_in_tkt_with_skey", "creds"], [236, 1, 1, "c.krb5_get_in_tkt_with_skey", "key"], [236, 1, 1, "c.krb5_get_in_tkt_with_skey", "ktypes"], [236, 1, 1, "c.krb5_get_in_tkt_with_skey", "options"], [236, 1, 1, "c.krb5_get_in_tkt_with_skey", "pre_auth_types"], [236, 1, 1, "c.krb5_get_in_tkt_with_skey", "ret_as_reply"]], "krb5_get_init_creds_keytab": [[237, 1, 1, "c.krb5_get_init_creds_keytab", "arg_keytab"], [237, 1, 1, "c.krb5_get_init_creds_keytab", "client"], [237, 1, 1, "c.krb5_get_init_creds_keytab", "context"], [237, 1, 1, "c.krb5_get_init_creds_keytab", "creds"], [237, 1, 1, "c.krb5_get_init_creds_keytab", "in_tkt_service"], [237, 1, 1, "c.krb5_get_init_creds_keytab", "k5_gic_options"], [237, 1, 1, "c.krb5_get_init_creds_keytab", "start_time"]], "krb5_get_init_creds_opt": [[846, 3, 1, "c.krb5_get_init_creds_opt.address_list", "address_list"], [846, 3, 1, "c.krb5_get_init_creds_opt.etype_list", "etype_list"], [846, 3, 1, "c.krb5_get_init_creds_opt.etype_list_length", "etype_list_length"], [846, 3, 1, "c.krb5_get_init_creds_opt.flags", "flags"], [846, 3, 1, "c.krb5_get_init_creds_opt.forwardable", "forwardable"], [846, 3, 1, "c.krb5_get_init_creds_opt.preauth_list", "preauth_list"], [846, 3, 1, "c.krb5_get_init_creds_opt.preauth_list_length", "preauth_list_length"], [846, 3, 1, "c.krb5_get_init_creds_opt.proxiable", "proxiable"], [846, 3, 1, "c.krb5_get_init_creds_opt.renew_life", "renew_life"], [846, 3, 1, "c.krb5_get_init_creds_opt.salt", "salt"], [846, 3, 1, "c.krb5_get_init_creds_opt.tkt_life", "tkt_life"]], "krb5_get_init_creds_opt_alloc": [[238, 1, 1, "c.krb5_get_init_creds_opt_alloc", "context"], [238, 1, 1, "c.krb5_get_init_creds_opt_alloc", "opt"]], "krb5_get_init_creds_opt_free": [[239, 1, 1, "c.krb5_get_init_creds_opt_free", "context"], [239, 1, 1, "c.krb5_get_init_creds_opt_free", "opt"]], "krb5_get_init_creds_opt_get_fast_flags": [[240, 1, 1, "c.krb5_get_init_creds_opt_get_fast_flags", "context"], [240, 1, 1, "c.krb5_get_init_creds_opt_get_fast_flags", "opt"], [240, 1, 1, "c.krb5_get_init_creds_opt_get_fast_flags", "out_flags"]], "krb5_get_init_creds_opt_init": [[241, 1, 1, "c.krb5_get_init_creds_opt_init", "opt"]], "krb5_get_init_creds_opt_set_address_list": [[242, 1, 1, "c.krb5_get_init_creds_opt_set_address_list", "addresses"], [242, 1, 1, "c.krb5_get_init_creds_opt_set_address_list", "opt"]], "krb5_get_init_creds_opt_set_anonymous": [[243, 1, 1, "c.krb5_get_init_creds_opt_set_anonymous", "anonymous"], [243, 1, 1, "c.krb5_get_init_creds_opt_set_anonymous", "opt"]], "krb5_get_init_creds_opt_set_canonicalize": [[244, 1, 1, "c.krb5_get_init_creds_opt_set_canonicalize", "canonicalize"], [244, 1, 1, "c.krb5_get_init_creds_opt_set_canonicalize", "opt"]], "krb5_get_init_creds_opt_set_change_password_prompt": [[245, 1, 1, "c.krb5_get_init_creds_opt_set_change_password_prompt", "opt"], [245, 1, 1, "c.krb5_get_init_creds_opt_set_change_password_prompt", "prompt"]], "krb5_get_init_creds_opt_set_etype_list": [[246, 1, 1, "c.krb5_get_init_creds_opt_set_etype_list", "etype_list"], [246, 1, 1, "c.krb5_get_init_creds_opt_set_etype_list", "etype_list_length"], [246, 1, 1, "c.krb5_get_init_creds_opt_set_etype_list", "opt"]], "krb5_get_init_creds_opt_set_expire_callback": [[247, 1, 1, "c.krb5_get_init_creds_opt_set_expire_callback", "cb"], [247, 1, 1, "c.krb5_get_init_creds_opt_set_expire_callback", "context"], [247, 1, 1, "c.krb5_get_init_creds_opt_set_expire_callback", "data"], [247, 1, 1, "c.krb5_get_init_creds_opt_set_expire_callback", "opt"]], "krb5_get_init_creds_opt_set_fast_ccache": [[248, 1, 1, "c.krb5_get_init_creds_opt_set_fast_ccache", "ccache"], [248, 1, 1, "c.krb5_get_init_creds_opt_set_fast_ccache", "context"], [248, 1, 1, "c.krb5_get_init_creds_opt_set_fast_ccache", "opt"]], "krb5_get_init_creds_opt_set_fast_ccache_name": [[249, 1, 1, "c.krb5_get_init_creds_opt_set_fast_ccache_name", "context"], [249, 1, 1, "c.krb5_get_init_creds_opt_set_fast_ccache_name", "fast_ccache_name"], [249, 1, 1, "c.krb5_get_init_creds_opt_set_fast_ccache_name", "opt"]], "krb5_get_init_creds_opt_set_fast_flags": [[250, 1, 1, "c.krb5_get_init_creds_opt_set_fast_flags", "context"], [250, 1, 1, "c.krb5_get_init_creds_opt_set_fast_flags", "flags"], [250, 1, 1, "c.krb5_get_init_creds_opt_set_fast_flags", "opt"]], "krb5_get_init_creds_opt_set_forwardable": [[251, 1, 1, "c.krb5_get_init_creds_opt_set_forwardable", "forwardable"], [251, 1, 1, "c.krb5_get_init_creds_opt_set_forwardable", "opt"]], "krb5_get_init_creds_opt_set_in_ccache": [[252, 1, 1, "c.krb5_get_init_creds_opt_set_in_ccache", "ccache"], [252, 1, 1, "c.krb5_get_init_creds_opt_set_in_ccache", "context"], [252, 1, 1, "c.krb5_get_init_creds_opt_set_in_ccache", "opt"]], "krb5_get_init_creds_opt_set_out_ccache": [[253, 1, 1, "c.krb5_get_init_creds_opt_set_out_ccache", "ccache"], [253, 1, 1, "c.krb5_get_init_creds_opt_set_out_ccache", "context"], [253, 1, 1, "c.krb5_get_init_creds_opt_set_out_ccache", "opt"]], "krb5_get_init_creds_opt_set_pa": [[254, 1, 1, "c.krb5_get_init_creds_opt_set_pa", "attr"], [254, 1, 1, "c.krb5_get_init_creds_opt_set_pa", "context"], [254, 1, 1, "c.krb5_get_init_creds_opt_set_pa", "opt"], [254, 1, 1, "c.krb5_get_init_creds_opt_set_pa", "value"]], "krb5_get_init_creds_opt_set_pac_request": [[255, 1, 1, "c.krb5_get_init_creds_opt_set_pac_request", "context"], [255, 1, 1, "c.krb5_get_init_creds_opt_set_pac_request", "opt"], [255, 1, 1, "c.krb5_get_init_creds_opt_set_pac_request", "req_pac"]], "krb5_get_init_creds_opt_set_preauth_list": [[256, 1, 1, "c.krb5_get_init_creds_opt_set_preauth_list", "opt"], [256, 1, 1, "c.krb5_get_init_creds_opt_set_preauth_list", "preauth_list"], [256, 1, 1, "c.krb5_get_init_creds_opt_set_preauth_list", "preauth_list_length"]], "krb5_get_init_creds_opt_set_proxiable": [[257, 1, 1, "c.krb5_get_init_creds_opt_set_proxiable", "opt"], [257, 1, 1, "c.krb5_get_init_creds_opt_set_proxiable", "proxiable"]], "krb5_get_init_creds_opt_set_renew_life": [[258, 1, 1, "c.krb5_get_init_creds_opt_set_renew_life", "opt"], [258, 1, 1, "c.krb5_get_init_creds_opt_set_renew_life", "renew_life"]], "krb5_get_init_creds_opt_set_responder": [[259, 1, 1, "c.krb5_get_init_creds_opt_set_responder", "context"], [259, 1, 1, "c.krb5_get_init_creds_opt_set_responder", "data"], [259, 1, 1, "c.krb5_get_init_creds_opt_set_responder", "opt"], [259, 1, 1, "c.krb5_get_init_creds_opt_set_responder", "responder"]], "krb5_get_init_creds_opt_set_salt": [[260, 1, 1, "c.krb5_get_init_creds_opt_set_salt", "opt"], [260, 1, 1, "c.krb5_get_init_creds_opt_set_salt", "salt"]], "krb5_get_init_creds_opt_set_tkt_life": [[261, 1, 1, "c.krb5_get_init_creds_opt_set_tkt_life", "opt"], [261, 1, 1, "c.krb5_get_init_creds_opt_set_tkt_life", "tkt_life"]], "krb5_get_init_creds_password": [[262, 1, 1, "c.krb5_get_init_creds_password", "client"], [262, 1, 1, "c.krb5_get_init_creds_password", "context"], [262, 1, 1, "c.krb5_get_init_creds_password", "creds"], [262, 1, 1, "c.krb5_get_init_creds_password", "data"], [262, 1, 1, "c.krb5_get_init_creds_password", "in_tkt_service"], [262, 1, 1, "c.krb5_get_init_creds_password", "k5_gic_options"], [262, 1, 1, "c.krb5_get_init_creds_password", "password"], [262, 1, 1, "c.krb5_get_init_creds_password", "prompter"], [262, 1, 1, "c.krb5_get_init_creds_password", "start_time"]], "krb5_get_permitted_enctypes": [[263, 1, 1, "c.krb5_get_permitted_enctypes", "context"], [263, 1, 1, "c.krb5_get_permitted_enctypes", "ktypes"]], "krb5_get_profile": [[264, 1, 1, "c.krb5_get_profile", "context"], [264, 1, 1, "c.krb5_get_profile", "profile"]], "krb5_get_prompt_types": [[265, 1, 1, "c.krb5_get_prompt_types", "context"]], "krb5_get_renewed_creds": [[266, 1, 1, "c.krb5_get_renewed_creds", "ccache"], [266, 1, 1, "c.krb5_get_renewed_creds", "client"], [266, 1, 1, "c.krb5_get_renewed_creds", "context"], [266, 1, 1, "c.krb5_get_renewed_creds", "creds"], [266, 1, 1, "c.krb5_get_renewed_creds", "in_tkt_service"]], "krb5_get_server_rcache": [[267, 1, 1, "c.krb5_get_server_rcache", "context"], [267, 1, 1, "c.krb5_get_server_rcache", "piece"], [267, 1, 1, "c.krb5_get_server_rcache", "rcptr"]], "krb5_get_time_offsets": [[268, 1, 1, "c.krb5_get_time_offsets", "context"], [268, 1, 1, "c.krb5_get_time_offsets", "microseconds"], [268, 1, 1, "c.krb5_get_time_offsets", "seconds"]], "krb5_get_validated_creds": [[269, 1, 1, "c.krb5_get_validated_creds", "ccache"], [269, 1, 1, "c.krb5_get_validated_creds", "client"], [269, 1, 1, "c.krb5_get_validated_creds", "context"], [269, 1, 1, "c.krb5_get_validated_creds", "creds"], [269, 1, 1, "c.krb5_get_validated_creds", "in_tkt_service"]], "krb5_gic_opt_pa_data": [[847, 3, 1, "c.krb5_gic_opt_pa_data.attr", "attr"], [847, 3, 1, "c.krb5_gic_opt_pa_data.value", "value"]], "krb5_init_context": [[270, 1, 1, "c.krb5_init_context", "context"]], "krb5_init_context_profile": [[271, 1, 1, "c.krb5_init_context_profile", "context"], [271, 1, 1, "c.krb5_init_context_profile", "flags"], [271, 1, 1, "c.krb5_init_context_profile", "profile"]], "krb5_init_creds_free": [[272, 1, 1, "c.krb5_init_creds_free", "context"], [272, 1, 1, "c.krb5_init_creds_free", "ctx"]], "krb5_init_creds_get": [[273, 1, 1, "c.krb5_init_creds_get", "context"], [273, 1, 1, "c.krb5_init_creds_get", "ctx"]], "krb5_init_creds_get_creds": [[274, 1, 1, "c.krb5_init_creds_get_creds", "context"], [274, 1, 1, "c.krb5_init_creds_get_creds", "creds"], [274, 1, 1, "c.krb5_init_creds_get_creds", "ctx"]], "krb5_init_creds_get_error": [[275, 1, 1, "c.krb5_init_creds_get_error", "context"], [275, 1, 1, "c.krb5_init_creds_get_error", "ctx"], [275, 1, 1, "c.krb5_init_creds_get_error", "error"]], "krb5_init_creds_get_times": [[276, 1, 1, "c.krb5_init_creds_get_times", "context"], [276, 1, 1, "c.krb5_init_creds_get_times", "ctx"], [276, 1, 1, "c.krb5_init_creds_get_times", "times"]], "krb5_init_creds_init": [[277, 1, 1, "c.krb5_init_creds_init", "client"], [277, 1, 1, "c.krb5_init_creds_init", "context"], [277, 1, 1, "c.krb5_init_creds_init", "ctx"], [277, 1, 1, "c.krb5_init_creds_init", "data"], [277, 1, 1, "c.krb5_init_creds_init", "options"], [277, 1, 1, "c.krb5_init_creds_init", "prompter"], [277, 1, 1, "c.krb5_init_creds_init", "start_time"]], "krb5_init_creds_set_keytab": [[278, 1, 1, "c.krb5_init_creds_set_keytab", "context"], [278, 1, 1, "c.krb5_init_creds_set_keytab", "ctx"], [278, 1, 1, "c.krb5_init_creds_set_keytab", "keytab"]], "krb5_init_creds_set_password": [[279, 1, 1, "c.krb5_init_creds_set_password", "context"], [279, 1, 1, "c.krb5_init_creds_set_password", "ctx"], [279, 1, 1, "c.krb5_init_creds_set_password", "password"]], "krb5_init_creds_set_service": [[280, 1, 1, "c.krb5_init_creds_set_service", "context"], [280, 1, 1, "c.krb5_init_creds_set_service", "ctx"], [280, 1, 1, "c.krb5_init_creds_set_service", "service"]], "krb5_init_creds_step": [[281, 1, 1, "c.krb5_init_creds_step", "context"], [281, 1, 1, "c.krb5_init_creds_step", "ctx"], [281, 1, 1, "c.krb5_init_creds_step", "flags"], [281, 1, 1, "c.krb5_init_creds_step", "in"], [281, 1, 1, "c.krb5_init_creds_step", "out"], [281, 1, 1, "c.krb5_init_creds_step", "realm"]], "krb5_init_keyblock": [[282, 1, 1, "c.krb5_init_keyblock", "context"], [282, 1, 1, "c.krb5_init_keyblock", "enctype"], [282, 1, 1, "c.krb5_init_keyblock", "length"], [282, 1, 1, "c.krb5_init_keyblock", "out"]], "krb5_init_random_key": [[283, 1, 1, "c.krb5_init_random_key", "context"], [283, 1, 1, "c.krb5_init_random_key", "eblock"], [283, 1, 1, "c.krb5_init_random_key", "keyblock"], [283, 1, 1, "c.krb5_init_random_key", "ptr"]], "krb5_init_secure_context": [[284, 1, 1, "c.krb5_init_secure_context", "context"]], "krb5_is_config_principal": [[285, 1, 1, "c.krb5_is_config_principal", "context"], [285, 1, 1, "c.krb5_is_config_principal", "principal"]], "krb5_is_referral_realm": [[286, 1, 1, "c.krb5_is_referral_realm", "r"]], "krb5_is_thread_safe": [[287, 1, 1, "c.krb5_is_thread_safe", "None"]], "krb5_k_create_key": [[288, 1, 1, "c.krb5_k_create_key", "context"], [288, 1, 1, "c.krb5_k_create_key", "key_data"], [288, 1, 1, "c.krb5_k_create_key", "out"]], "krb5_k_decrypt": [[289, 1, 1, "c.krb5_k_decrypt", "cipher_state"], [289, 1, 1, "c.krb5_k_decrypt", "context"], [289, 1, 1, "c.krb5_k_decrypt", "input"], [289, 1, 1, "c.krb5_k_decrypt", "key"], [289, 1, 1, "c.krb5_k_decrypt", "output"], [289, 1, 1, "c.krb5_k_decrypt", "usage"]], "krb5_k_decrypt_iov": [[290, 1, 1, "c.krb5_k_decrypt_iov", "cipher_state"], [290, 1, 1, "c.krb5_k_decrypt_iov", "context"], [290, 1, 1, "c.krb5_k_decrypt_iov", "data"], [290, 1, 1, "c.krb5_k_decrypt_iov", "key"], [290, 1, 1, "c.krb5_k_decrypt_iov", "num_data"], [290, 1, 1, "c.krb5_k_decrypt_iov", "usage"]], "krb5_k_encrypt": [[291, 1, 1, "c.krb5_k_encrypt", "cipher_state"], [291, 1, 1, "c.krb5_k_encrypt", "context"], [291, 1, 1, "c.krb5_k_encrypt", "input"], [291, 1, 1, "c.krb5_k_encrypt", "key"], [291, 1, 1, "c.krb5_k_encrypt", "output"], [291, 1, 1, "c.krb5_k_encrypt", "usage"]], "krb5_k_encrypt_iov": [[292, 1, 1, "c.krb5_k_encrypt_iov", "cipher_state"], [292, 1, 1, "c.krb5_k_encrypt_iov", "context"], [292, 1, 1, "c.krb5_k_encrypt_iov", "data"], [292, 1, 1, "c.krb5_k_encrypt_iov", "key"], [292, 1, 1, "c.krb5_k_encrypt_iov", "num_data"], [292, 1, 1, "c.krb5_k_encrypt_iov", "usage"]], "krb5_k_free_key": [[293, 1, 1, "c.krb5_k_free_key", "context"], [293, 1, 1, "c.krb5_k_free_key", "key"]], "krb5_k_key_enctype": [[294, 1, 1, "c.krb5_k_key_enctype", "context"], [294, 1, 1, "c.krb5_k_key_enctype", "key"]], "krb5_k_key_keyblock": [[295, 1, 1, "c.krb5_k_key_keyblock", "context"], [295, 1, 1, "c.krb5_k_key_keyblock", "key"], [295, 1, 1, "c.krb5_k_key_keyblock", "key_data"]], "krb5_k_make_checksum": [[296, 1, 1, "c.krb5_k_make_checksum", "cksum"], [296, 1, 1, "c.krb5_k_make_checksum", "cksumtype"], [296, 1, 1, "c.krb5_k_make_checksum", "context"], [296, 1, 1, "c.krb5_k_make_checksum", "input"], [296, 1, 1, "c.krb5_k_make_checksum", "key"], [296, 1, 1, "c.krb5_k_make_checksum", "usage"]], "krb5_k_make_checksum_iov": [[297, 1, 1, "c.krb5_k_make_checksum_iov", "cksumtype"], [297, 1, 1, "c.krb5_k_make_checksum_iov", "context"], [297, 1, 1, "c.krb5_k_make_checksum_iov", "data"], [297, 1, 1, "c.krb5_k_make_checksum_iov", "key"], [297, 1, 1, "c.krb5_k_make_checksum_iov", "num_data"], [297, 1, 1, "c.krb5_k_make_checksum_iov", "usage"]], "krb5_k_prf": [[298, 1, 1, "c.krb5_k_prf", "context"], [298, 1, 1, "c.krb5_k_prf", "input"], [298, 1, 1, "c.krb5_k_prf", "key"], [298, 1, 1, "c.krb5_k_prf", "output"]], "krb5_k_reference_key": [[299, 1, 1, "c.krb5_k_reference_key", "context"], [299, 1, 1, "c.krb5_k_reference_key", "key"]], "krb5_k_verify_checksum": [[300, 1, 1, "c.krb5_k_verify_checksum", "cksum"], [300, 1, 1, "c.krb5_k_verify_checksum", "context"], [300, 1, 1, "c.krb5_k_verify_checksum", "data"], [300, 1, 1, "c.krb5_k_verify_checksum", "key"], [300, 1, 1, "c.krb5_k_verify_checksum", "usage"], [300, 1, 1, "c.krb5_k_verify_checksum", "valid"]], "krb5_k_verify_checksum_iov": [[301, 1, 1, "c.krb5_k_verify_checksum_iov", "cksumtype"], [301, 1, 1, "c.krb5_k_verify_checksum_iov", "context"], [301, 1, 1, "c.krb5_k_verify_checksum_iov", "data"], [301, 1, 1, "c.krb5_k_verify_checksum_iov", "key"], [301, 1, 1, "c.krb5_k_verify_checksum_iov", "num_data"], [301, 1, 1, "c.krb5_k_verify_checksum_iov", "usage"], [301, 1, 1, "c.krb5_k_verify_checksum_iov", "valid"]], "krb5_kdc_rep": [[851, 3, 1, "c.krb5_kdc_rep.client", "client"], [851, 3, 1, "c.krb5_kdc_rep.enc_part", "enc_part"], [851, 3, 1, "c.krb5_kdc_rep.enc_part2", "enc_part2"], [851, 3, 1, "c.krb5_kdc_rep.magic", "magic"], [851, 3, 1, "c.krb5_kdc_rep.msg_type", "msg_type"], [851, 3, 1, "c.krb5_kdc_rep.padata", "padata"], [851, 3, 1, "c.krb5_kdc_rep.ticket", "ticket"]], "krb5_kdc_req": [[852, 3, 1, "c.krb5_kdc_req.addresses", "addresses"], [852, 3, 1, "c.krb5_kdc_req.authorization_data", "authorization_data"], [852, 3, 1, "c.krb5_kdc_req.client", "client"], [852, 3, 1, "c.krb5_kdc_req.from", "from"], [852, 3, 1, "c.krb5_kdc_req.kdc_options", "kdc_options"], [852, 3, 1, "c.krb5_kdc_req.ktype", "ktype"], [852, 3, 1, "c.krb5_kdc_req.magic", "magic"], [852, 3, 1, "c.krb5_kdc_req.msg_type", "msg_type"], [852, 3, 1, "c.krb5_kdc_req.nktypes", "nktypes"], [852, 3, 1, "c.krb5_kdc_req.nonce", "nonce"], [852, 3, 1, "c.krb5_kdc_req.padata", "padata"], [852, 3, 1, "c.krb5_kdc_req.rtime", "rtime"], [852, 3, 1, "c.krb5_kdc_req.second_ticket", "second_ticket"], [852, 3, 1, "c.krb5_kdc_req.server", "server"], [852, 3, 1, "c.krb5_kdc_req.till", "till"], [852, 3, 1, "c.krb5_kdc_req.unenc_authdata", "unenc_authdata"]], "krb5_kdc_sign_ticket": [[302, 1, 1, "c.krb5_kdc_sign_ticket", "client_princ"], [302, 1, 1, "c.krb5_kdc_sign_ticket", "context"], [302, 1, 1, "c.krb5_kdc_sign_ticket", "enc_tkt"], [302, 1, 1, "c.krb5_kdc_sign_ticket", "pac"], [302, 1, 1, "c.krb5_kdc_sign_ticket", "privsvr"], [302, 1, 1, "c.krb5_kdc_sign_ticket", "server"], [302, 1, 1, "c.krb5_kdc_sign_ticket", "server_princ"], [302, 1, 1, "c.krb5_kdc_sign_ticket", "with_realm"]], "krb5_kdc_verify_ticket": [[303, 1, 1, "c.krb5_kdc_verify_ticket", "context"], [303, 1, 1, "c.krb5_kdc_verify_ticket", "enc_tkt"], [303, 1, 1, "c.krb5_kdc_verify_ticket", "pac_out"], [303, 1, 1, "c.krb5_kdc_verify_ticket", "privsvr"], [303, 1, 1, "c.krb5_kdc_verify_ticket", "server"], [303, 1, 1, "c.krb5_kdc_verify_ticket", "server_princ"]], "krb5_keyblock": [[854, 3, 1, "c.krb5_keyblock.contents", "contents"], [854, 3, 1, "c.krb5_keyblock.enctype", "enctype"], [854, 3, 1, "c.krb5_keyblock.length", "length"], [854, 3, 1, "c.krb5_keyblock.magic", "magic"]], "krb5_keytab_entry": [[856, 3, 1, "c.krb5_keytab_entry.key", "key"], [856, 3, 1, "c.krb5_keytab_entry.magic", "magic"], [856, 3, 1, "c.krb5_keytab_entry.principal", "principal"], [856, 3, 1, "c.krb5_keytab_entry.timestamp", "timestamp"], [856, 3, 1, "c.krb5_keytab_entry.vno", "vno"]], "krb5_kt_add_entry": [[304, 1, 1, "c.krb5_kt_add_entry", "context"], [304, 1, 1, "c.krb5_kt_add_entry", "entry"], [304, 1, 1, "c.krb5_kt_add_entry", "id"]], "krb5_kt_client_default": [[305, 1, 1, "c.krb5_kt_client_default", "context"], [305, 1, 1, "c.krb5_kt_client_default", "keytab_out"]], "krb5_kt_close": [[306, 1, 1, "c.krb5_kt_close", "context"], [306, 1, 1, "c.krb5_kt_close", "keytab"]], "krb5_kt_default": [[307, 1, 1, "c.krb5_kt_default", "context"], [307, 1, 1, "c.krb5_kt_default", "id"]], "krb5_kt_default_name": [[308, 1, 1, "c.krb5_kt_default_name", "context"], [308, 1, 1, "c.krb5_kt_default_name", "name"], [308, 1, 1, "c.krb5_kt_default_name", "name_size"]], "krb5_kt_dup": [[309, 1, 1, "c.krb5_kt_dup", "context"], [309, 1, 1, "c.krb5_kt_dup", "in"], [309, 1, 1, "c.krb5_kt_dup", "out"]], "krb5_kt_end_seq_get": [[310, 1, 1, "c.krb5_kt_end_seq_get", "context"], [310, 1, 1, "c.krb5_kt_end_seq_get", "cursor"], [310, 1, 1, "c.krb5_kt_end_seq_get", "keytab"]], "krb5_kt_free_entry": [[311, 1, 1, "c.krb5_kt_free_entry", "context"], [311, 1, 1, "c.krb5_kt_free_entry", "entry"]], "krb5_kt_get_entry": [[312, 1, 1, "c.krb5_kt_get_entry", "context"], [312, 1, 1, "c.krb5_kt_get_entry", "enctype"], [312, 1, 1, "c.krb5_kt_get_entry", "entry"], [312, 1, 1, "c.krb5_kt_get_entry", "keytab"], [312, 1, 1, "c.krb5_kt_get_entry", "principal"], [312, 1, 1, "c.krb5_kt_get_entry", "vno"]], "krb5_kt_get_name": [[313, 1, 1, "c.krb5_kt_get_name", "context"], [313, 1, 1, "c.krb5_kt_get_name", "keytab"], [313, 1, 1, "c.krb5_kt_get_name", "name"], [313, 1, 1, "c.krb5_kt_get_name", "namelen"]], "krb5_kt_get_type": [[314, 1, 1, "c.krb5_kt_get_type", "context"], [314, 1, 1, "c.krb5_kt_get_type", "keytab"]], "krb5_kt_have_content": [[315, 1, 1, "c.krb5_kt_have_content", "context"], [315, 1, 1, "c.krb5_kt_have_content", "keytab"]], "krb5_kt_next_entry": [[316, 1, 1, "c.krb5_kt_next_entry", "context"], [316, 1, 1, "c.krb5_kt_next_entry", "cursor"], [316, 1, 1, "c.krb5_kt_next_entry", "entry"], [316, 1, 1, "c.krb5_kt_next_entry", "keytab"]], "krb5_kt_read_service_key": [[317, 1, 1, "c.krb5_kt_read_service_key", "context"], [317, 1, 1, "c.krb5_kt_read_service_key", "enctype"], [317, 1, 1, "c.krb5_kt_read_service_key", "key"], [317, 1, 1, "c.krb5_kt_read_service_key", "keyprocarg"], [317, 1, 1, "c.krb5_kt_read_service_key", "principal"], [317, 1, 1, "c.krb5_kt_read_service_key", "vno"]], "krb5_kt_remove_entry": [[318, 1, 1, "c.krb5_kt_remove_entry", "context"], [318, 1, 1, "c.krb5_kt_remove_entry", "entry"], [318, 1, 1, "c.krb5_kt_remove_entry", "id"]], "krb5_kt_resolve": [[319, 1, 1, "c.krb5_kt_resolve", "context"], [319, 1, 1, "c.krb5_kt_resolve", "ktid"], [319, 1, 1, "c.krb5_kt_resolve", "name"]], "krb5_kt_start_seq_get": [[320, 1, 1, "c.krb5_kt_start_seq_get", "context"], [320, 1, 1, "c.krb5_kt_start_seq_get", "cursor"], [320, 1, 1, "c.krb5_kt_start_seq_get", "keytab"]], "krb5_kuserok": [[321, 1, 1, "c.krb5_kuserok", "context"], [321, 1, 1, "c.krb5_kuserok", "luser"], [321, 1, 1, "c.krb5_kuserok", "principal"]], "krb5_last_req_entry": [[860, 3, 1, "c.krb5_last_req_entry.lr_type", "lr_type"], [860, 3, 1, "c.krb5_last_req_entry.magic", "magic"], [860, 3, 1, "c.krb5_last_req_entry.value", "value"]], "krb5_make_authdata_kdc_issued": [[322, 1, 1, "c.krb5_make_authdata_kdc_issued", "ad_kdcissued"], [322, 1, 1, "c.krb5_make_authdata_kdc_issued", "authdata"], [322, 1, 1, "c.krb5_make_authdata_kdc_issued", "context"], [322, 1, 1, "c.krb5_make_authdata_kdc_issued", "issuer"], [322, 1, 1, "c.krb5_make_authdata_kdc_issued", "key"]], "krb5_marshal_credentials": [[323, 1, 1, "c.krb5_marshal_credentials", "context"], [323, 1, 1, "c.krb5_marshal_credentials", "data_out"], [323, 1, 1, "c.krb5_marshal_credentials", "in_creds"]], "krb5_merge_authdata": [[324, 1, 1, "c.krb5_merge_authdata", "context"], [324, 1, 1, "c.krb5_merge_authdata", "inauthdat1"], [324, 1, 1, "c.krb5_merge_authdata", "inauthdat2"], [324, 1, 1, "c.krb5_merge_authdata", "outauthdat"]], "krb5_mk_1cred": [[325, 1, 1, "c.krb5_mk_1cred", "auth_context"], [325, 1, 1, "c.krb5_mk_1cred", "context"], [325, 1, 1, "c.krb5_mk_1cred", "creds"], [325, 1, 1, "c.krb5_mk_1cred", "der_out"], [325, 1, 1, "c.krb5_mk_1cred", "rdata_out"]], "krb5_mk_error": [[326, 1, 1, "c.krb5_mk_error", "context"], [326, 1, 1, "c.krb5_mk_error", "dec_err"], [326, 1, 1, "c.krb5_mk_error", "enc_err"]], "krb5_mk_ncred": [[327, 1, 1, "c.krb5_mk_ncred", "auth_context"], [327, 1, 1, "c.krb5_mk_ncred", "context"], [327, 1, 1, "c.krb5_mk_ncred", "creds"], [327, 1, 1, "c.krb5_mk_ncred", "der_out"], [327, 1, 1, "c.krb5_mk_ncred", "rdata_out"]], "krb5_mk_priv": [[328, 1, 1, "c.krb5_mk_priv", "auth_context"], [328, 1, 1, "c.krb5_mk_priv", "context"], [328, 1, 1, "c.krb5_mk_priv", "der_out"], [328, 1, 1, "c.krb5_mk_priv", "rdata_out"], [328, 1, 1, "c.krb5_mk_priv", "userdata"]], "krb5_mk_rep": [[329, 1, 1, "c.krb5_mk_rep", "auth_context"], [329, 1, 1, "c.krb5_mk_rep", "context"], [329, 1, 1, "c.krb5_mk_rep", "outbuf"]], "krb5_mk_rep_dce": [[330, 1, 1, "c.krb5_mk_rep_dce", "auth_context"], [330, 1, 1, "c.krb5_mk_rep_dce", "context"], [330, 1, 1, "c.krb5_mk_rep_dce", "outbuf"]], "krb5_mk_req": [[331, 1, 1, "c.krb5_mk_req", "ap_req_options"], [331, 1, 1, "c.krb5_mk_req", "auth_context"], [331, 1, 1, "c.krb5_mk_req", "ccache"], [331, 1, 1, "c.krb5_mk_req", "context"], [331, 1, 1, "c.krb5_mk_req", "hostname"], [331, 1, 1, "c.krb5_mk_req", "in_data"], [331, 1, 1, "c.krb5_mk_req", "outbuf"], [331, 1, 1, "c.krb5_mk_req", "service"]], "krb5_mk_req_extended": [[332, 1, 1, "c.krb5_mk_req_extended", "ap_req_options"], [332, 1, 1, "c.krb5_mk_req_extended", "auth_context"], [332, 1, 1, "c.krb5_mk_req_extended", "context"], [332, 1, 1, "c.krb5_mk_req_extended", "in_creds"], [332, 1, 1, "c.krb5_mk_req_extended", "in_data"], [332, 1, 1, "c.krb5_mk_req_extended", "outbuf"]], "krb5_mk_safe": [[333, 1, 1, "c.krb5_mk_safe", "auth_context"], [333, 1, 1, "c.krb5_mk_safe", "context"], [333, 1, 1, "c.krb5_mk_safe", "der_out"], [333, 1, 1, "c.krb5_mk_safe", "rdata_out"], [333, 1, 1, "c.krb5_mk_safe", "userdata"]], "krb5_os_localaddr": [[334, 1, 1, "c.krb5_os_localaddr", "addr"], [334, 1, 1, "c.krb5_os_localaddr", "context"]], "krb5_pa_data": [[865, 3, 1, "c.krb5_pa_data.contents", "contents"], [865, 3, 1, "c.krb5_pa_data.length", "length"], [865, 3, 1, "c.krb5_pa_data.magic", "magic"], [865, 3, 1, "c.krb5_pa_data.pa_type", "pa_type"]], "krb5_pa_pac_req": [[866, 3, 1, "c.krb5_pa_pac_req.include_pac", "include_pac"]], "krb5_pa_server_referral_data": [[867, 3, 1, "c.krb5_pa_server_referral_data.referral_valid_until", "referral_valid_until"], [867, 3, 1, "c.krb5_pa_server_referral_data.referred_realm", "referred_realm"], [867, 3, 1, "c.krb5_pa_server_referral_data.rep_cksum", "rep_cksum"], [867, 3, 1, "c.krb5_pa_server_referral_data.requested_principal_name", "requested_principal_name"], [867, 3, 1, "c.krb5_pa_server_referral_data.true_principal_name", "true_principal_name"]], "krb5_pa_svr_referral_data": [[868, 3, 1, "c.krb5_pa_svr_referral_data.principal", "principal"]], "krb5_pac_add_buffer": [[335, 1, 1, "c.krb5_pac_add_buffer", "context"], [335, 1, 1, "c.krb5_pac_add_buffer", "data"], [335, 1, 1, "c.krb5_pac_add_buffer", "pac"], [335, 1, 1, "c.krb5_pac_add_buffer", "type"]], "krb5_pac_free": [[336, 1, 1, "c.krb5_pac_free", "context"], [336, 1, 1, "c.krb5_pac_free", "pac"]], "krb5_pac_get_buffer": [[337, 1, 1, "c.krb5_pac_get_buffer", "context"], [337, 1, 1, "c.krb5_pac_get_buffer", "data"], [337, 1, 1, "c.krb5_pac_get_buffer", "pac"], [337, 1, 1, "c.krb5_pac_get_buffer", "type"]], "krb5_pac_get_client_info": [[338, 1, 1, "c.krb5_pac_get_client_info", "authtime_out"], [338, 1, 1, "c.krb5_pac_get_client_info", "context"], [338, 1, 1, "c.krb5_pac_get_client_info", "pac"], [338, 1, 1, "c.krb5_pac_get_client_info", "princname_out"]], "krb5_pac_get_types": [[339, 1, 1, "c.krb5_pac_get_types", "context"], [339, 1, 1, "c.krb5_pac_get_types", "len"], [339, 1, 1, "c.krb5_pac_get_types", "pac"], [339, 1, 1, "c.krb5_pac_get_types", "types"]], "krb5_pac_init": [[340, 1, 1, "c.krb5_pac_init", "context"], [340, 1, 1, "c.krb5_pac_init", "pac"]], "krb5_pac_parse": [[341, 1, 1, "c.krb5_pac_parse", "context"], [341, 1, 1, "c.krb5_pac_parse", "len"], [341, 1, 1, "c.krb5_pac_parse", "pac"], [341, 1, 1, "c.krb5_pac_parse", "ptr"]], "krb5_pac_sign": [[342, 1, 1, "c.krb5_pac_sign", "authtime"], [342, 1, 1, "c.krb5_pac_sign", "context"], [342, 1, 1, "c.krb5_pac_sign", "data"], [342, 1, 1, "c.krb5_pac_sign", "pac"], [342, 1, 1, "c.krb5_pac_sign", "principal"], [342, 1, 1, "c.krb5_pac_sign", "privsvr_key"], [342, 1, 1, "c.krb5_pac_sign", "server_key"]], "krb5_pac_sign_ext": [[343, 1, 1, "c.krb5_pac_sign_ext", "authtime"], [343, 1, 1, "c.krb5_pac_sign_ext", "context"], [343, 1, 1, "c.krb5_pac_sign_ext", "data"], [343, 1, 1, "c.krb5_pac_sign_ext", "pac"], [343, 1, 1, "c.krb5_pac_sign_ext", "principal"], [343, 1, 1, "c.krb5_pac_sign_ext", "privsvr_key"], [343, 1, 1, "c.krb5_pac_sign_ext", "server_key"], [343, 1, 1, "c.krb5_pac_sign_ext", "with_realm"]], "krb5_pac_verify": [[344, 1, 1, "c.krb5_pac_verify", "authtime"], [344, 1, 1, "c.krb5_pac_verify", "context"], [344, 1, 1, "c.krb5_pac_verify", "pac"], [344, 1, 1, "c.krb5_pac_verify", "principal"], [344, 1, 1, "c.krb5_pac_verify", "privsvr"], [344, 1, 1, "c.krb5_pac_verify", "server"]], "krb5_pac_verify_ext": [[345, 1, 1, "c.krb5_pac_verify_ext", "authtime"], [345, 1, 1, "c.krb5_pac_verify_ext", "context"], [345, 1, 1, "c.krb5_pac_verify_ext", "pac"], [345, 1, 1, "c.krb5_pac_verify_ext", "principal"], [345, 1, 1, "c.krb5_pac_verify_ext", "privsvr"], [345, 1, 1, "c.krb5_pac_verify_ext", "server"], [345, 1, 1, "c.krb5_pac_verify_ext", "with_realm"]], "krb5_parse_name": [[346, 1, 1, "c.krb5_parse_name", "context"], [346, 1, 1, "c.krb5_parse_name", "name"], [346, 1, 1, "c.krb5_parse_name", "principal_out"]], "krb5_parse_name_flags": [[347, 1, 1, "c.krb5_parse_name_flags", "context"], [347, 1, 1, "c.krb5_parse_name_flags", "flags"], [347, 1, 1, "c.krb5_parse_name_flags", "name"], [347, 1, 1, "c.krb5_parse_name_flags", "principal_out"]], "krb5_prepend_error_message": [[348, 1, 1, "c.krb5_prepend_error_message", "code"], [348, 1, 1, "c.krb5_prepend_error_message", "ctx"], [348, 1, 1, "c.krb5_prepend_error_message", "fmt"]], "krb5_principal": [[874, 3, 1, "c.krb5_principal.data", "data"], [874, 3, 1, "c.krb5_principal.length", "length"], [874, 3, 1, "c.krb5_principal.magic", "magic"], [874, 3, 1, "c.krb5_principal.realm", "realm"], [874, 3, 1, "c.krb5_principal.type", "type"]], "krb5_principal2salt": [[349, 1, 1, "c.krb5_principal2salt", "context"], [349, 1, 1, "c.krb5_principal2salt", "pr"], [349, 1, 1, "c.krb5_principal2salt", "ret"]], "krb5_principal_compare": [[350, 1, 1, "c.krb5_principal_compare", "context"], [350, 1, 1, "c.krb5_principal_compare", "princ1"], [350, 1, 1, "c.krb5_principal_compare", "princ2"]], "krb5_principal_compare_any_realm": [[351, 1, 1, "c.krb5_principal_compare_any_realm", "context"], [351, 1, 1, "c.krb5_principal_compare_any_realm", "princ1"], [351, 1, 1, "c.krb5_principal_compare_any_realm", "princ2"]], "krb5_principal_compare_flags": [[352, 1, 1, "c.krb5_principal_compare_flags", "context"], [352, 1, 1, "c.krb5_principal_compare_flags", "flags"], [352, 1, 1, "c.krb5_principal_compare_flags", "princ1"], [352, 1, 1, "c.krb5_principal_compare_flags", "princ2"]], "krb5_principal_data": [[875, 3, 1, "c.krb5_principal_data.data", "data"], [875, 3, 1, "c.krb5_principal_data.length", "length"], [875, 3, 1, "c.krb5_principal_data.magic", "magic"], [875, 3, 1, "c.krb5_principal_data.realm", "realm"], [875, 3, 1, "c.krb5_principal_data.type", "type"]], "krb5_process_key": [[353, 1, 1, "c.krb5_process_key", "context"], [353, 1, 1, "c.krb5_process_key", "eblock"], [353, 1, 1, "c.krb5_process_key", "key"]], "krb5_prompt": [[876, 3, 1, "c.krb5_prompt.hidden", "hidden"], [876, 3, 1, "c.krb5_prompt.prompt", "prompt"], [876, 3, 1, "c.krb5_prompt.reply", "reply"]], "krb5_prompter_posix": [[354, 1, 1, "c.krb5_prompter_posix", "banner"], [354, 1, 1, "c.krb5_prompter_posix", "context"], [354, 1, 1, "c.krb5_prompter_posix", "data"], [354, 1, 1, "c.krb5_prompter_posix", "name"], [354, 1, 1, "c.krb5_prompter_posix", "num_prompts"], [354, 1, 1, "c.krb5_prompter_posix", "prompts"]], "krb5_pwd_data": [[879, 3, 1, "c.krb5_pwd_data.element", "element"], [879, 3, 1, "c.krb5_pwd_data.magic", "magic"], [879, 3, 1, "c.krb5_pwd_data.sequence_count", "sequence_count"]], "krb5_random_key": [[355, 1, 1, "c.krb5_random_key", "context"], [355, 1, 1, "c.krb5_random_key", "eblock"], [355, 1, 1, "c.krb5_random_key", "keyblock"], [355, 1, 1, "c.krb5_random_key", "ptr"]], "krb5_rd_cred": [[356, 1, 1, "c.krb5_rd_cred", "auth_context"], [356, 1, 1, "c.krb5_rd_cred", "context"], [356, 1, 1, "c.krb5_rd_cred", "creddata"], [356, 1, 1, "c.krb5_rd_cred", "creds_out"], [356, 1, 1, "c.krb5_rd_cred", "rdata_out"]], "krb5_rd_error": [[357, 1, 1, "c.krb5_rd_error", "context"], [357, 1, 1, "c.krb5_rd_error", "dec_error"], [357, 1, 1, "c.krb5_rd_error", "enc_errbuf"]], "krb5_rd_priv": [[358, 1, 1, "c.krb5_rd_priv", "auth_context"], [358, 1, 1, "c.krb5_rd_priv", "context"], [358, 1, 1, "c.krb5_rd_priv", "inbuf"], [358, 1, 1, "c.krb5_rd_priv", "rdata_out"], [358, 1, 1, "c.krb5_rd_priv", "userdata_out"]], "krb5_rd_rep": [[359, 1, 1, "c.krb5_rd_rep", "auth_context"], [359, 1, 1, "c.krb5_rd_rep", "context"], [359, 1, 1, "c.krb5_rd_rep", "inbuf"], [359, 1, 1, "c.krb5_rd_rep", "repl"]], "krb5_rd_rep_dce": [[360, 1, 1, "c.krb5_rd_rep_dce", "auth_context"], [360, 1, 1, "c.krb5_rd_rep_dce", "context"], [360, 1, 1, "c.krb5_rd_rep_dce", "inbuf"], [360, 1, 1, "c.krb5_rd_rep_dce", "nonce"]], "krb5_rd_req": [[361, 1, 1, "c.krb5_rd_req", "ap_req_options"], [361, 1, 1, "c.krb5_rd_req", "auth_context"], [361, 1, 1, "c.krb5_rd_req", "context"], [361, 1, 1, "c.krb5_rd_req", "inbuf"], [361, 1, 1, "c.krb5_rd_req", "keytab"], [361, 1, 1, "c.krb5_rd_req", "server"], [361, 1, 1, "c.krb5_rd_req", "ticket"]], "krb5_rd_safe": [[362, 1, 1, "c.krb5_rd_safe", "auth_context"], [362, 1, 1, "c.krb5_rd_safe", "context"], [362, 1, 1, "c.krb5_rd_safe", "inbuf"], [362, 1, 1, "c.krb5_rd_safe", "rdata_out"], [362, 1, 1, "c.krb5_rd_safe", "userdata_out"]], "krb5_read_password": [[363, 1, 1, "c.krb5_read_password", "context"], [363, 1, 1, "c.krb5_read_password", "prompt"], [363, 1, 1, "c.krb5_read_password", "prompt2"], [363, 1, 1, "c.krb5_read_password", "return_pwd"], [363, 1, 1, "c.krb5_read_password", "size_return"]], "krb5_realm_compare": [[364, 1, 1, "c.krb5_realm_compare", "context"], [364, 1, 1, "c.krb5_realm_compare", "princ1"], [364, 1, 1, "c.krb5_realm_compare", "princ2"]], "krb5_recvauth": [[365, 1, 1, "c.krb5_recvauth", "appl_version"], [365, 1, 1, "c.krb5_recvauth", "auth_context"], [365, 1, 1, "c.krb5_recvauth", "context"], [365, 1, 1, "c.krb5_recvauth", "fd"], [365, 1, 1, "c.krb5_recvauth", "flags"], [365, 1, 1, "c.krb5_recvauth", "keytab"], [365, 1, 1, "c.krb5_recvauth", "server"], [365, 1, 1, "c.krb5_recvauth", "ticket"]], "krb5_recvauth_version": [[366, 1, 1, "c.krb5_recvauth_version", "auth_context"], [366, 1, 1, "c.krb5_recvauth_version", "context"], [366, 1, 1, "c.krb5_recvauth_version", "fd"], [366, 1, 1, "c.krb5_recvauth_version", "flags"], [366, 1, 1, "c.krb5_recvauth_version", "keytab"], [366, 1, 1, "c.krb5_recvauth_version", "server"], [366, 1, 1, "c.krb5_recvauth_version", "ticket"], [366, 1, 1, "c.krb5_recvauth_version", "version"]], "krb5_replay_data": [[881, 3, 1, "c.krb5_replay_data.seq", "seq"], [881, 3, 1, "c.krb5_replay_data.timestamp", "timestamp"], [881, 3, 1, "c.krb5_replay_data.usec", "usec"]], "krb5_responder_get_challenge": [[367, 1, 1, "c.krb5_responder_get_challenge", "ctx"], [367, 1, 1, "c.krb5_responder_get_challenge", "question"], [367, 1, 1, "c.krb5_responder_get_challenge", "rctx"]], "krb5_responder_list_questions": [[368, 1, 1, "c.krb5_responder_list_questions", "ctx"], [368, 1, 1, "c.krb5_responder_list_questions", "rctx"]], "krb5_responder_otp_challenge": [[884, 3, 1, "c.krb5_responder_otp_challenge.service", "service"], [884, 3, 1, "c.krb5_responder_otp_challenge.tokeninfo", "tokeninfo"]], "krb5_responder_otp_challenge_free": [[369, 1, 1, "c.krb5_responder_otp_challenge_free", "chl"], [369, 1, 1, "c.krb5_responder_otp_challenge_free", "ctx"], [369, 1, 1, "c.krb5_responder_otp_challenge_free", "rctx"]], "krb5_responder_otp_get_challenge": [[370, 1, 1, "c.krb5_responder_otp_get_challenge", "chl"], [370, 1, 1, "c.krb5_responder_otp_get_challenge", "ctx"], [370, 1, 1, "c.krb5_responder_otp_get_challenge", "rctx"]], "krb5_responder_otp_set_answer": [[371, 1, 1, "c.krb5_responder_otp_set_answer", "ctx"], [371, 1, 1, "c.krb5_responder_otp_set_answer", "pin"], [371, 1, 1, "c.krb5_responder_otp_set_answer", "rctx"], [371, 1, 1, "c.krb5_responder_otp_set_answer", "ti"], [371, 1, 1, "c.krb5_responder_otp_set_answer", "value"]], "krb5_responder_otp_tokeninfo": [[885, 3, 1, "c.krb5_responder_otp_tokeninfo.alg_id", "alg_id"], [885, 3, 1, "c.krb5_responder_otp_tokeninfo.challenge", "challenge"], [885, 3, 1, "c.krb5_responder_otp_tokeninfo.flags", "flags"], [885, 3, 1, "c.krb5_responder_otp_tokeninfo.format", "format"], [885, 3, 1, "c.krb5_responder_otp_tokeninfo.length", "length"], [885, 3, 1, "c.krb5_responder_otp_tokeninfo.token_id", "token_id"], [885, 3, 1, "c.krb5_responder_otp_tokeninfo.vendor", "vendor"]], "krb5_responder_pkinit_challenge": [[886, 3, 1, "c.krb5_responder_pkinit_challenge.identities", "identities"]], "krb5_responder_pkinit_challenge_free": [[372, 1, 1, "c.krb5_responder_pkinit_challenge_free", "chl"], [372, 1, 1, "c.krb5_responder_pkinit_challenge_free", "ctx"], [372, 1, 1, "c.krb5_responder_pkinit_challenge_free", "rctx"]], "krb5_responder_pkinit_get_challenge": [[373, 1, 1, "c.krb5_responder_pkinit_get_challenge", "chl_out"], [373, 1, 1, "c.krb5_responder_pkinit_get_challenge", "ctx"], [373, 1, 1, "c.krb5_responder_pkinit_get_challenge", "rctx"]], "krb5_responder_pkinit_identity": [[887, 3, 1, "c.krb5_responder_pkinit_identity.identity", "identity"], [887, 3, 1, "c.krb5_responder_pkinit_identity.token_flags", "token_flags"]], "krb5_responder_pkinit_set_answer": [[374, 1, 1, "c.krb5_responder_pkinit_set_answer", "ctx"], [374, 1, 1, "c.krb5_responder_pkinit_set_answer", "identity"], [374, 1, 1, "c.krb5_responder_pkinit_set_answer", "pin"], [374, 1, 1, "c.krb5_responder_pkinit_set_answer", "rctx"]], "krb5_responder_set_answer": [[375, 1, 1, "c.krb5_responder_set_answer", "answer"], [375, 1, 1, "c.krb5_responder_set_answer", "ctx"], [375, 1, 1, "c.krb5_responder_set_answer", "question"], [375, 1, 1, "c.krb5_responder_set_answer", "rctx"]], "krb5_response": [[888, 3, 1, "c.krb5_response.expected_nonce", "expected_nonce"], [888, 3, 1, "c.krb5_response.magic", "magic"], [888, 3, 1, "c.krb5_response.message_type", "message_type"], [888, 3, 1, "c.krb5_response.request_time", "request_time"], [888, 3, 1, "c.krb5_response.response", "response"]], "krb5_salttype_to_string": [[376, 1, 1, "c.krb5_salttype_to_string", "buffer"], [376, 1, 1, "c.krb5_salttype_to_string", "buflen"], [376, 1, 1, "c.krb5_salttype_to_string", "salttype"]], "krb5_sendauth": [[377, 1, 1, "c.krb5_sendauth", "ap_req_options"], [377, 1, 1, "c.krb5_sendauth", "appl_version"], [377, 1, 1, "c.krb5_sendauth", "auth_context"], [377, 1, 1, "c.krb5_sendauth", "ccache"], [377, 1, 1, "c.krb5_sendauth", "client"], [377, 1, 1, "c.krb5_sendauth", "context"], [377, 1, 1, "c.krb5_sendauth", "error"], [377, 1, 1, "c.krb5_sendauth", "fd"], [377, 1, 1, "c.krb5_sendauth", "in_creds"], [377, 1, 1, "c.krb5_sendauth", "in_data"], [377, 1, 1, "c.krb5_sendauth", "out_creds"], [377, 1, 1, "c.krb5_sendauth", "rep_result"], [377, 1, 1, "c.krb5_sendauth", "server"]], "krb5_server_decrypt_ticket_keytab": [[378, 1, 1, "c.krb5_server_decrypt_ticket_keytab", "context"], [378, 1, 1, "c.krb5_server_decrypt_ticket_keytab", "kt"], [378, 1, 1, "c.krb5_server_decrypt_ticket_keytab", "ticket"]], "krb5_set_default_realm": [[379, 1, 1, "c.krb5_set_default_realm", "context"], [379, 1, 1, "c.krb5_set_default_realm", "lrealm"]], "krb5_set_default_tgs_enctypes": [[380, 1, 1, "c.krb5_set_default_tgs_enctypes", "context"], [380, 1, 1, "c.krb5_set_default_tgs_enctypes", "etypes"]], "krb5_set_error_message": [[381, 1, 1, "c.krb5_set_error_message", "code"], [381, 1, 1, "c.krb5_set_error_message", "ctx"], [381, 1, 1, "c.krb5_set_error_message", "fmt"]], "krb5_set_kdc_recv_hook": [[382, 1, 1, "c.krb5_set_kdc_recv_hook", "context"], [382, 1, 1, "c.krb5_set_kdc_recv_hook", "data"], [382, 1, 1, "c.krb5_set_kdc_recv_hook", "recv_hook"]], "krb5_set_kdc_send_hook": [[383, 1, 1, "c.krb5_set_kdc_send_hook", "context"], [383, 1, 1, "c.krb5_set_kdc_send_hook", "data"], [383, 1, 1, "c.krb5_set_kdc_send_hook", "send_hook"]], "krb5_set_password": [[384, 1, 1, "c.krb5_set_password", "change_password_for"], [384, 1, 1, "c.krb5_set_password", "context"], [384, 1, 1, "c.krb5_set_password", "creds"], [384, 1, 1, "c.krb5_set_password", "newpw"], [384, 1, 1, "c.krb5_set_password", "result_code"], [384, 1, 1, "c.krb5_set_password", "result_code_string"], [384, 1, 1, "c.krb5_set_password", "result_string"]], "krb5_set_password_using_ccache": [[385, 1, 1, "c.krb5_set_password_using_ccache", "ccache"], [385, 1, 1, "c.krb5_set_password_using_ccache", "change_password_for"], [385, 1, 1, "c.krb5_set_password_using_ccache", "context"], [385, 1, 1, "c.krb5_set_password_using_ccache", "newpw"], [385, 1, 1, "c.krb5_set_password_using_ccache", "result_code"], [385, 1, 1, "c.krb5_set_password_using_ccache", "result_code_string"], [385, 1, 1, "c.krb5_set_password_using_ccache", "result_string"]], "krb5_set_principal_realm": [[386, 1, 1, "c.krb5_set_principal_realm", "context"], [386, 1, 1, "c.krb5_set_principal_realm", "principal"], [386, 1, 1, "c.krb5_set_principal_realm", "realm"]], "krb5_set_real_time": [[387, 1, 1, "c.krb5_set_real_time", "context"], [387, 1, 1, "c.krb5_set_real_time", "microseconds"], [387, 1, 1, "c.krb5_set_real_time", "seconds"]], "krb5_set_trace_callback": [[388, 1, 1, "c.krb5_set_trace_callback", "cb_data"], [388, 1, 1, "c.krb5_set_trace_callback", "context"], [388, 1, 1, "c.krb5_set_trace_callback", "fn"]], "krb5_set_trace_filename": [[389, 1, 1, "c.krb5_set_trace_filename", "context"], [389, 1, 1, "c.krb5_set_trace_filename", "filename"]], "krb5_sname_match": [[390, 1, 1, "c.krb5_sname_match", "context"], [390, 1, 1, "c.krb5_sname_match", "matching"], [390, 1, 1, "c.krb5_sname_match", "princ"]], "krb5_sname_to_principal": [[391, 1, 1, "c.krb5_sname_to_principal", "context"], [391, 1, 1, "c.krb5_sname_to_principal", "hostname"], [391, 1, 1, "c.krb5_sname_to_principal", "ret_princ"], [391, 1, 1, "c.krb5_sname_to_principal", "sname"], [391, 1, 1, "c.krb5_sname_to_principal", "type"]], "krb5_string_to_cksumtype": [[392, 1, 1, "c.krb5_string_to_cksumtype", "cksumtypep"], [392, 1, 1, "c.krb5_string_to_cksumtype", "string"]], "krb5_string_to_deltat": [[393, 1, 1, "c.krb5_string_to_deltat", "deltatp"], [393, 1, 1, "c.krb5_string_to_deltat", "string"]], "krb5_string_to_enctype": [[394, 1, 1, "c.krb5_string_to_enctype", "enctypep"], [394, 1, 1, "c.krb5_string_to_enctype", "string"]], "krb5_string_to_key": [[395, 1, 1, "c.krb5_string_to_key", "context"], [395, 1, 1, "c.krb5_string_to_key", "data"], [395, 1, 1, "c.krb5_string_to_key", "eblock"], [395, 1, 1, "c.krb5_string_to_key", "keyblock"], [395, 1, 1, "c.krb5_string_to_key", "salt"]], "krb5_string_to_salttype": [[396, 1, 1, "c.krb5_string_to_salttype", "salttypep"], [396, 1, 1, "c.krb5_string_to_salttype", "string"]], "krb5_string_to_timestamp": [[397, 1, 1, "c.krb5_string_to_timestamp", "string"], [397, 1, 1, "c.krb5_string_to_timestamp", "timestampp"]], "krb5_ticket": [[889, 3, 1, "c.krb5_ticket.enc_part", "enc_part"], [889, 3, 1, "c.krb5_ticket.enc_part2", "enc_part2"], [889, 3, 1, "c.krb5_ticket.magic", "magic"], [889, 3, 1, "c.krb5_ticket.server", "server"]], "krb5_ticket_times": [[890, 3, 1, "c.krb5_ticket_times.authtime", "authtime"], [890, 3, 1, "c.krb5_ticket_times.endtime", "endtime"], [890, 3, 1, "c.krb5_ticket_times.renew_till", "renew_till"], [890, 3, 1, "c.krb5_ticket_times.starttime", "starttime"]], "krb5_timeofday": [[398, 1, 1, "c.krb5_timeofday", "context"], [398, 1, 1, "c.krb5_timeofday", "timeret"]], "krb5_timestamp_to_sfstring": [[399, 1, 1, "c.krb5_timestamp_to_sfstring", "buffer"], [399, 1, 1, "c.krb5_timestamp_to_sfstring", "buflen"], [399, 1, 1, "c.krb5_timestamp_to_sfstring", "pad"], [399, 1, 1, "c.krb5_timestamp_to_sfstring", "timestamp"]], "krb5_timestamp_to_string": [[400, 1, 1, "c.krb5_timestamp_to_string", "buffer"], [400, 1, 1, "c.krb5_timestamp_to_string", "buflen"], [400, 1, 1, "c.krb5_timestamp_to_string", "timestamp"]], "krb5_tkt_authent": [[892, 3, 1, "c.krb5_tkt_authent.ap_options", "ap_options"], [892, 3, 1, "c.krb5_tkt_authent.authenticator", "authenticator"], [892, 3, 1, "c.krb5_tkt_authent.magic", "magic"], [892, 3, 1, "c.krb5_tkt_authent.ticket", "ticket"]], "krb5_tkt_creds_free": [[401, 1, 1, "c.krb5_tkt_creds_free", "context"], [401, 1, 1, "c.krb5_tkt_creds_free", "ctx"]], "krb5_tkt_creds_get": [[402, 1, 1, "c.krb5_tkt_creds_get", "context"], [402, 1, 1, "c.krb5_tkt_creds_get", "ctx"]], "krb5_tkt_creds_get_creds": [[403, 1, 1, "c.krb5_tkt_creds_get_creds", "context"], [403, 1, 1, "c.krb5_tkt_creds_get_creds", "creds"], [403, 1, 1, "c.krb5_tkt_creds_get_creds", "ctx"]], "krb5_tkt_creds_get_times": [[404, 1, 1, "c.krb5_tkt_creds_get_times", "context"], [404, 1, 1, "c.krb5_tkt_creds_get_times", "ctx"], [404, 1, 1, "c.krb5_tkt_creds_get_times", "times"]], "krb5_tkt_creds_init": [[405, 1, 1, "c.krb5_tkt_creds_init", "ccache"], [405, 1, 1, "c.krb5_tkt_creds_init", "context"], [405, 1, 1, "c.krb5_tkt_creds_init", "creds"], [405, 1, 1, "c.krb5_tkt_creds_init", "ctx"], [405, 1, 1, "c.krb5_tkt_creds_init", "options"]], "krb5_tkt_creds_step": [[406, 1, 1, "c.krb5_tkt_creds_step", "context"], [406, 1, 1, "c.krb5_tkt_creds_step", "ctx"], [406, 1, 1, "c.krb5_tkt_creds_step", "flags"], [406, 1, 1, "c.krb5_tkt_creds_step", "in"], [406, 1, 1, "c.krb5_tkt_creds_step", "out"], [406, 1, 1, "c.krb5_tkt_creds_step", "realm"]], "krb5_trace_info": [[895, 3, 1, "c.krb5_trace_info.message", "message"]], "krb5_transited": [[896, 3, 1, "c.krb5_transited.magic", "magic"], [896, 3, 1, "c.krb5_transited.tr_contents", "tr_contents"], [896, 3, 1, "c.krb5_transited.tr_type", "tr_type"]], "krb5_typed_data": [[897, 3, 1, "c.krb5_typed_data.data", "data"], [897, 3, 1, "c.krb5_typed_data.length", "length"], [897, 3, 1, "c.krb5_typed_data.magic", "magic"], [897, 3, 1, "c.krb5_typed_data.type", "type"]], "krb5_unmarshal_credentials": [[407, 1, 1, "c.krb5_unmarshal_credentials", "context"], [407, 1, 1, "c.krb5_unmarshal_credentials", "creds_out"], [407, 1, 1, "c.krb5_unmarshal_credentials", "data"]], "krb5_unparse_name": [[408, 1, 1, "c.krb5_unparse_name", "context"], [408, 1, 1, "c.krb5_unparse_name", "name"], [408, 1, 1, "c.krb5_unparse_name", "principal"]], "krb5_unparse_name_ext": [[409, 1, 1, "c.krb5_unparse_name_ext", "context"], [409, 1, 1, "c.krb5_unparse_name_ext", "name"], [409, 1, 1, "c.krb5_unparse_name_ext", "principal"], [409, 1, 1, "c.krb5_unparse_name_ext", "size"]], "krb5_unparse_name_flags": [[410, 1, 1, "c.krb5_unparse_name_flags", "context"], [410, 1, 1, "c.krb5_unparse_name_flags", "flags"], [410, 1, 1, "c.krb5_unparse_name_flags", "name"], [410, 1, 1, "c.krb5_unparse_name_flags", "principal"]], "krb5_unparse_name_flags_ext": [[411, 1, 1, "c.krb5_unparse_name_flags_ext", "context"], [411, 1, 1, "c.krb5_unparse_name_flags_ext", "flags"], [411, 1, 1, "c.krb5_unparse_name_flags_ext", "name"], [411, 1, 1, "c.krb5_unparse_name_flags_ext", "principal"], [411, 1, 1, "c.krb5_unparse_name_flags_ext", "size"]], "krb5_us_timeofday": [[412, 1, 1, "c.krb5_us_timeofday", "context"], [412, 1, 1, "c.krb5_us_timeofday", "microseconds"], [412, 1, 1, "c.krb5_us_timeofday", "seconds"]], "krb5_use_enctype": [[413, 1, 1, "c.krb5_use_enctype", "context"], [413, 1, 1, "c.krb5_use_enctype", "eblock"], [413, 1, 1, "c.krb5_use_enctype", "enctype"]], "krb5_verify_authdata_kdc_issued": [[414, 1, 1, "c.krb5_verify_authdata_kdc_issued", "ad_kdcissued"], [414, 1, 1, "c.krb5_verify_authdata_kdc_issued", "authdata"], [414, 1, 1, "c.krb5_verify_authdata_kdc_issued", "context"], [414, 1, 1, "c.krb5_verify_authdata_kdc_issued", "issuer"], [414, 1, 1, "c.krb5_verify_authdata_kdc_issued", "key"]], "krb5_verify_checksum": [[415, 1, 1, "c.krb5_verify_checksum", "cksum"], [415, 1, 1, "c.krb5_verify_checksum", "context"], [415, 1, 1, "c.krb5_verify_checksum", "ctype"], [415, 1, 1, "c.krb5_verify_checksum", "in"], [415, 1, 1, "c.krb5_verify_checksum", "in_length"], [415, 1, 1, "c.krb5_verify_checksum", "seed"], [415, 1, 1, "c.krb5_verify_checksum", "seed_length"]], "krb5_verify_init_creds": [[416, 1, 1, "c.krb5_verify_init_creds", "ccache"], [416, 1, 1, "c.krb5_verify_init_creds", "context"], [416, 1, 1, "c.krb5_verify_init_creds", "creds"], [416, 1, 1, "c.krb5_verify_init_creds", "keytab"], [416, 1, 1, "c.krb5_verify_init_creds", "options"], [416, 1, 1, "c.krb5_verify_init_creds", "server"]], "krb5_verify_init_creds_opt": [[900, 3, 1, "c.krb5_verify_init_creds_opt.ap_req_nofail", "ap_req_nofail"], [900, 3, 1, "c.krb5_verify_init_creds_opt.flags", "flags"]], "krb5_verify_init_creds_opt_init": [[417, 1, 1, "c.krb5_verify_init_creds_opt_init", "k5_vic_options"]], "krb5_verify_init_creds_opt_set_ap_req_nofail": [[418, 1, 1, "c.krb5_verify_init_creds_opt_set_ap_req_nofail", "ap_req_nofail"], [418, 1, 1, "c.krb5_verify_init_creds_opt_set_ap_req_nofail", "k5_vic_options"]], "krb5_vprepend_error_message": [[419, 1, 1, "c.krb5_vprepend_error_message", "args"], [419, 1, 1, "c.krb5_vprepend_error_message", "code"], [419, 1, 1, "c.krb5_vprepend_error_message", "ctx"], [419, 1, 1, "c.krb5_vprepend_error_message", "fmt"]], "krb5_vset_error_message": [[420, 1, 1, "c.krb5_vset_error_message", "args"], [420, 1, 1, "c.krb5_vset_error_message", "code"], [420, 1, 1, "c.krb5_vset_error_message", "ctx"], [420, 1, 1, "c.krb5_vset_error_message", "fmt"]], "krb5_vwrap_error_message": [[421, 1, 1, "c.krb5_vwrap_error_message", "args"], [421, 1, 1, "c.krb5_vwrap_error_message", "code"], [421, 1, 1, "c.krb5_vwrap_error_message", "ctx"], [421, 1, 1, "c.krb5_vwrap_error_message", "fmt"], [421, 1, 1, "c.krb5_vwrap_error_message", "old_code"]], "krb5_wrap_error_message": [[422, 1, 1, "c.krb5_wrap_error_message", "code"], [422, 1, 1, "c.krb5_wrap_error_message", "ctx"], [422, 1, 1, "c.krb5_wrap_error_message", "fmt"], [422, 1, 1, "c.krb5_wrap_error_message", "old_code"]], "passwd_phrase_element": [[901, 3, 1, "c.passwd_phrase_element.magic", "magic"], [901, 3, 1, "c.passwd_phrase_element.passwd", "passwd"], [901, 3, 1, "c.passwd_phrase_element.phrase", "phrase"]]}, "objtypes": {"0": "c:function", "1": "c:functionParam", "2": "c:type", "3": "c:member", "4": "py:data"}, "objnames": {"0": ["c", "function", "C function"], "1": ["c", "functionParam", "C function parameter"], "2": ["c", "type", "C type"], "3": ["c", "member", "C member"], "4": ["py", "data", "Python data"]}, "titleterms": {"contribut": 0, "mit": [0, 23, 44, 923, 924, 925, 926], "kerbero": [0, 15, 17, 22, 23, 34, 39, 44, 49, 50, 51, 52, 127, 128, 166, 233, 287, 905, 911, 918, 923, 924, 925, 926, 934, 946, 960], "document": [0, 904, 914, 923], "background": [0, 907], "administr": [1, 23, 30, 34], "program": [1, 912], "k5srvutil": 2, "synopsi": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 948, 949, 950, 951, 952, 953, 954, 955, 956], "descript": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 19, 948, 949, 950, 951, 952, 953, 954, 955, 956, 958, 959, 960], "environ": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 912, 948, 949, 950, 951, 953, 954, 955, 956, 960], "see": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 19, 20, 21, 948, 949, 950, 951, 952, 953, 954, 955, 956, 958, 959, 960], "also": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 19, 20, 21, 948, 949, 950, 951, 952, 953, 954, 955, 956, 958, 959, 960], "kadmin": [3, 918, 935], "option": [3, 4, 5, 6, 7, 8, 9, 10, 20, 21, 46, 157, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 256, 257, 258, 259, 260, 261, 399, 417, 912, 948, 949, 950, 951, 952, 953, 954, 955], "databas": [3, 14, 17, 23, 24, 34, 39, 918, 934], "command": [3, 5, 6, 11, 947], "add_princip": 3, "modify_princip": 3, "rename_princip": 3, "add_alia": 3, "delete_princip": 3, "change_password": 3, "purgekei": 3, "get_princip": 3, "list_princip": 3, "get_str": 3, "set_str": 3, "del_str": 3, "add_polici": 3, "modify_polici": [3, 5], "delete_polici": 3, "get_polici": 3, "list_polici": [3, 5], "ktadd": 3, "ktremov": 3, "lock": 3, "unlock": 3, "list_request": [3, 11], "quit": [3, 11], "histori": [3, 14, 23, 960], "kadmind": [4, 930], "kdb5_ldap_util": 5, "line": [5, 6], "creat": [5, 6, 34, 37, 41, 78, 149, 270, 271, 277, 284, 288, 331, 332, 340, 405, 953], "modifi": 5, "view": [5, 946], "destroi": [5, 6, 137, 946], "list": [5, 11, 20, 41, 54, 92, 111, 173, 205, 228, 263, 324, 368, 925, 943], "stashsrvpw": 5, "create_polici": 5, "view_polici": 5, "destroy_polici": 5, "kdb5_util": 6, "stash": [6, 908], "dump": [6, 23, 918], "load": [6, 23], "ark": 6, "add_mkei": 6, "use_mkei": 6, "list_mkei": 6, "purge_mkei": 6, "update_princ_encrypt": 6, "tabdump": 6, "kprop": [7, 41], "kpropd": 8, "file": [8, 18, 20, 21, 32, 33, 34, 284, 389, 908, 916, 920, 921, 922, 948, 949, 950, 954, 955, 957], "kproplog": 9, "krb5kdc": 10, "exampl": [10, 11, 19, 46, 912, 952, 958, 959], "ktutil": 11, "read_kt": 11, "write_kt": 11, "clear_list": 11, "delete_entri": 11, "add_entri": 11, "sserver": 12, "common": 12, "error": [12, 41, 171, 179, 213, 214, 230, 275, 348, 357, 381, 419, 420, 421, 422], "messag": [12, 43, 97, 169, 171, 179, 214, 224, 230, 325, 326, 327, 328, 329, 330, 331, 332, 333, 348, 356, 357, 358, 359, 360, 361, 362, 381, 419, 420, 421, 422], "advanc": 13, "topic": 13, "retir": 14, "de": 14, "type": [14, 20, 24, 26, 36, 41, 43, 81, 96, 97, 105, 109, 110, 111, 118, 127, 128, 144, 146, 149, 160, 170, 192, 193, 204, 212, 246, 256, 263, 265, 314, 339, 376, 380, 392, 394, 396, 810, 903, 907, 912], "kei": [14, 23, 26, 67, 68, 90, 99, 101, 102, 107, 110, 111, 112, 115, 124, 125, 126, 218, 237, 263, 288, 289, 290, 291, 292, 293, 296, 297, 298, 299, 300, 301, 304, 305, 306, 307, 308, 312, 313, 314, 316, 317, 318, 319, 320, 378, 918, 921], "upgrad": 14, "procedur": 14, "The": [14, 32, 36], "krbtgt": [14, 23], "kdc": [14, 20, 28, 34, 35, 37, 39, 41, 231, 255, 266, 269, 275, 281, 382, 383, 405, 406, 917, 924, 930, 937, 938], "ad": [14, 15, 322, 414], "strong": 14, "applic": [14, 15, 32, 38, 45, 55], "server": [14, 15, 32, 41, 154, 267, 365, 366, 940], "default": [14, 28, 36, 135, 136, 145, 156, 211, 228, 229, 305, 307, 308, 349, 379, 380, 903, 906, 907, 924], "remov": [14, 15, 151, 318], "from": [14, 15, 26, 59, 60, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 76, 77, 124, 141, 142, 150, 151, 153, 179, 231, 240, 264, 265, 266, 268, 269, 274, 275, 276, 288, 295, 312, 316, 317, 318, 337, 338, 345, 363, 391, 403, 404, 405, 914, 930], "usag": 14, "support": [14, 41, 100, 103, 160, 287, 290, 292, 904], "legaci": [14, 48], "servic": [14, 26, 38, 39, 194, 280, 317, 391, 405], "master": [14, 23, 918], "keytab": [15, 32, 34, 38, 278, 309, 310, 315, 416, 906, 921], "princip": [15, 23, 34, 35, 38, 47, 49, 50, 56, 57, 91, 92, 93, 132, 145, 154, 182, 219, 223, 280, 285, 321, 346, 347, 349, 350, 351, 352, 364, 384, 385, 386, 390, 391, 916, 918], "us": [15, 48, 79, 91, 92, 93, 99, 101, 102, 119, 154, 194, 237, 262, 266, 267, 271, 273, 278, 284, 289, 291, 332, 378, 384, 385, 402, 419, 420, 421, 902, 903, 904, 910, 912], "acquir": [15, 273, 274, 277, 278, 279, 280, 281, 403], "client": [15, 29, 33, 37, 132, 305, 338, 377, 906, 929], "credenti": [15, 41, 43, 46, 51, 132, 133, 134, 135, 136, 137, 139, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 221, 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 256, 257, 258, 259, 260, 261, 262, 266, 269, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 325, 327, 332, 384, 385, 402, 403, 405, 416, 417, 418, 903, 916, 927], "clock": [15, 167], "skew": [15, 167], "get": [15, 41, 46, 63, 118, 141, 145, 164, 169, 224, 225, 230, 233, 237, 262, 265, 266, 269, 275, 281, 308, 312, 313, 319, 405, 406], "dn": [15, 38], "inform": [15, 21, 338, 907, 918, 926], "correct": 15, "configur": [15, 18, 22, 26, 28, 29, 33, 34, 35, 36, 37, 39, 141, 155, 228, 264, 284, 285, 912, 916, 941], "your": [15, 945], "firewal": 15, "work": 15, "v5": [15, 49, 50, 51, 905, 911], "authent": [16, 23, 41, 65, 78, 200, 953], "indic": 16, "backup": 17, "secur": [17, 32, 38, 917, 953], "host": [17, 28, 32, 34, 41, 233, 334, 932], "back": [17, 22], "up": [17, 910], "content": [18, 31, 181, 203, 207, 210, 217, 218, 911, 933], "kadm5": [19, 936], "acl": [19, 34], "syntax": 19, "modul": [19, 24, 28, 930, 931, 933], "behavior": [19, 38, 43], "conf": [20, 21, 34, 59, 60], "structur": [20, 21, 61, 66, 83, 142, 174, 175, 176, 177, 183, 199, 201, 202, 203, 207, 208, 209, 210, 216, 217, 221, 238, 294, 295, 346, 380, 387, 408, 409, 410, 411, 417, 810], "section": [20, 21, 59, 60], "kdcdefault": 20, "realm": [20, 21, 23, 28, 39, 58, 211, 229, 233, 345, 351, 364, 379, 386, 932], "dbdefault": 20, "dbmodul": 20, "log": [20, 41, 321, 930], "otp": [20, 36], "pkinit": [20, 21, 37, 46, 919, 928], "encrypt": [20, 26, 41, 97, 102, 103, 104, 105, 111, 115, 118, 128, 192, 193, 212, 246, 263, 291, 292, 329, 330, 380, 394], "keysalt": 20, "sampl": [20, 21], "krb5": [21, 34, 48, 59, 60, 206, 220, 270, 271, 284, 795, 810, 952], "libdefault": 21, "domain_realm": 21, "capath": 21, "appdefault": [21, 59, 60], "plugin": [21, 28, 930, 933], "ccselect": [21, 927], "interfac": [21, 48, 334, 927, 928, 929, 931, 932, 934, 935, 936, 937, 938, 939, 940, 941, 942], "pwqual": [21, 942], "kadm5_hook": [21, 936], "kadm5_auth": [21, 935], "clpreauth": [21, 929], "kdcpreauth": [21, 938], "hostrealm": [21, 932], "localauth": [21, 939], "certauth": [21, 928], "specifi": [21, 53, 54, 112, 127, 128, 132, 149, 153, 271, 278, 280, 345, 378, 379, 384, 388, 389], "ident": [21, 374], "paramet": [21, 126, 366], "expans": 21, "openldap": [22, 38], "end": 22, "polici": [23, 918, 937], "updat": [23, 914], "privileg": [23, 340], "oper": [23, 99, 100, 102, 103, 113, 114, 129, 130, 289, 290, 291, 292, 296, 297, 298, 300, 301], "ldap": [23, 24, 918], "ticket": [23, 185, 222, 225, 255, 258, 261, 276, 302, 303, 378, 404, 405, 946], "cross": 23, "chang": [23, 166, 169, 245, 945], "increment": [23, 34, 299], "propag": [23, 34, 39, 924], "overview": 23, "sun": 23, "differ": [23, 44, 421, 422], "berkelei": 24, "db2": [24, 918], "lightn": 24, "memori": [24, 215], "map": [24, 39], "klmdb": 24, "kldap": 24, "address": [25, 52, 53, 54, 62, 64, 82, 172, 198, 242, 334], "dictionari": 25, "attack": 25, "risk": 25, "enctyp": [26, 115, 117, 124, 231, 288, 294, 298], "request": [26, 281, 401, 402, 403, 404, 406], "session": [26, 67, 68, 90, 263], "select": [26, 154, 927], "choos": 26, "variabl": [26, 27, 92, 912, 960], "compat": 26, "migrat": 26, "awai": 26, "older": 26, "login": 28, "author": [28, 37, 173, 184, 189, 195, 321, 322, 324, 414, 928, 934, 935, 939, 953, 960], "locat": [28, 249, 940], "gssapi": [28, 43, 931], "mechan": [28, 931], "profil": [28, 55, 264, 271, 941], "http": 29, "proxi": 29, "For": [30, 45, 933, 944], "instal": [31, 33, 34, 910, 912, 953], "guid": 31, "addit": [31, 126, 225, 352], "refer": [31, 293, 299, 423, 914], "unix": [32, 33, 924], "some": [32, 101], "advic": [32, 38], "about": 32, "machin": 33, "primari": [34, 161], "edit": 34, "add": [34, 304, 335, 348, 419, 421, 422], "start": [34, 320], "daemon": 34, "replica": [34, 39, 924], "each": 34, "fail": [34, 41], "switch": [34, 160], "account": [35, 166, 945], "lockout": 35, "test": [35, 109, 110, 285, 287, 390, 910], "state": [35, 79, 106, 108], "replic": 35, "perform": 35, "setup": 35, "preauthent": [36, 40, 254, 256, 260, 929, 938], "defin": 36, "token": [36, 37, 43, 919], "instanc": 36, "other": 36, "consider": [36, 902], "certif": [37, 41, 340, 928], "gener": [37, 62, 115, 117, 119, 121, 124, 214, 267, 298, 391, 924, 930], "anonym": [37, 46, 57, 58, 243], "fresh": [37, 919], "name": [38, 39, 43, 56, 91, 92, 93, 135, 136, 143, 144, 149, 152, 156, 192, 194, 233, 308, 313, 346, 347, 349, 368, 375, 389, 391, 903, 907, 912], "canonic": [38, 194, 244], "revers": 38, "mismatch": 38, "overrid": [38, 55, 379], "provis": 38, "specif": [38, 97, 115, 117, 124, 298, 398], "shell": [38, 953], "ssh": 38, "ldapsearch": 38, "etc": 38, "decis": 39, "hostnam": [39, 194], "onto": 39, "port": [39, 84], "admin": [39, 41], "discoveri": 39, "spake": [40, 917], "troubleshoot": [41, 42], "trace": [41, 388, 389], "frequent": [41, 48], "seen": 41, "ha": 41, "while": 41, "initi": [41, 43, 46, 78, 108, 147, 165, 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 256, 257, 258, 259, 260, 261, 262, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 416, 417], "verif": [41, 417, 418, 945], "cannot": 41, "cert": 41, "chain": 41, "expir": [41, 247], "No": 41, "rout": 41, "connect": [41, 62], "refus": 41, "reject": 41, "dure": 41, "sendauth": [41, 365, 366, 377], "exchang": [41, 406], "variou": 42, "link": 42, "whitepap": 42, "tutori": 42, "develop": [43, 45, 933], "acceptor": 43, "attribut": [43, 340], "store": [43, 155, 159, 198], "extens": 43, "import": 43, "export": 43, "constrain": 43, "deleg": 43, "s4u": 43, "channel": [43, 943], "bind": 43, "gss_c_channel_bound_flag": 43, "aead": [43, 100, 103, 290, 292], "wrap": [43, 189], "iov": [43, 98, 114, 130, 297, 301], "mic": 43, "between": 44, "heimdal": 44, "api": [44, 48, 423, 914], "get_init_cr": 46, "user": [46, 321, 354, 944, 947, 957], "interact": 46, "prompter": 46, "callback": [46, 63, 80, 247, 388], "respond": [46, 259, 367, 368, 375], "password": [46, 125, 126, 166, 169, 245, 262, 279, 354, 363, 384, 385, 942, 945], "question": [46, 367, 368, 371, 374, 375], "One": 46, "time": [46, 167, 187, 268, 276, 387, 393, 398, 404, 412, 904], "pin": 46, "verifi": [46, 127, 128, 129, 300, 303, 344, 345, 414, 416], "manipul": 47, "pars": [47, 359, 360, 361], "public": [48, 795, 810], "rare": 48, "should": 48, "call": 48, "directli": 48, "conveni": 48, "deprec": [48, 795], "krb5_425_conv_princip": 49, "convert": [49, 50, 51, 56, 125, 126, 170, 187, 192, 193, 346, 347, 349, 376, 392, 393, 394, 396, 397, 399, 400, 408, 409, 410, 411], "v4": [49, 50, 51], "krb5_524_conv_princip": 50, "krb5_524_convert_cr": 51, "krb5_address_compar": 52, "compar": [52, 105, 350, 351, 352, 364], "two": [52, 105, 107, 324, 350, 351, 352, 364], "krb5_address_ord": 53, "return": [53, 58, 95, 96, 97, 111, 112, 116, 136, 211, 228, 263, 268, 314, 334, 339, 369, 372], "an": [53, 57, 58, 63, 64, 65, 67, 68, 69, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, 111, 115, 118, 124, 166, 172, 173, 185, 192, 193, 204, 212, 213, 214, 221, 225, 247, 252, 253, 266, 272, 273, 274, 275, 276, 282, 312, 318, 327, 339, 340, 341, 348, 381, 394, 419, 420, 914], "order": 53, "krb5_address_search": 54, "search": 54, "krb5_allow_weak_crypto": 55, "allow": [55, 167, 246], "": [55, 405, 421, 422], "allow_weak_crypto": 55, "set": [55, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 156, 157, 169, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 256, 257, 258, 259, 260, 261, 279, 325, 380, 381, 382, 383, 384, 385, 386, 387, 418, 420], "krb5_aname_to_localnam": 56, "local": [56, 69, 82, 84, 321, 939], "krb5_anonymous_princip": 57, "build": [57, 91, 92, 93, 910, 911, 914], "krb5_anonymous_realm": 58, "data": [58, 99, 100, 101, 102, 103, 104, 124, 173, 184, 189, 195, 198, 200, 210, 288, 289, 290, 291, 292, 322, 324, 367, 414, 918, 934], "krb5_appdefault_boolean": 59, "retriev": [59, 60, 64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 76, 77, 142, 143, 144, 146, 150, 153, 229, 231, 240, 264, 274, 276, 294, 295, 316, 317, 320, 337, 367, 398, 403, 404, 412], "boolean": 59, "valu": [59, 60, 141, 155, 187, 337, 369, 372, 393], "krb5_appdefault_str": 60, "string": [60, 91, 93, 107, 125, 126, 170, 187, 193, 211, 220, 223, 346, 347, 376, 392, 393, 394, 396, 397, 399, 400, 408, 409, 410, 411], "krb5_auth_con_fre": 61, "free": [61, 106, 162, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 239, 272, 293, 336, 369, 372, 401], "krb5_auth_context": [61, 66, 83, 816], "krb5_auth_con_genaddr": 62, "auth": [62, 63, 64, 65, 67, 68, 69, 71, 72, 73, 74, 76, 77, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90], "context": [62, 63, 64, 65, 67, 68, 69, 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, 171, 179, 206, 264, 265, 268, 270, 271, 272, 273, 274, 275, 276, 277, 284, 367, 368, 375, 379, 398, 401, 402, 403, 404, 405, 953], "socket": 62, "krb5_auth_con_get_checksum_func": 63, "checksum": [63, 80, 81, 96, 109, 110, 111, 113, 114, 127, 129, 130, 170, 204, 296, 297, 300, 301, 392], "krb5_auth_con_getaddr": 64, "field": [64, 83, 84, 97, 210, 386, 387], "krb5_auth_con_getauthent": 65, "krb5_auth_con_getflag": 66, "flag": [66, 83, 142, 157, 240, 243, 244, 245, 250, 251, 257, 347, 352, 410, 411], "krb5_auth_con_getkei": 67, "keyblock": [67, 72, 73, 76, 86, 88, 99, 100, 102, 103, 113, 114, 129, 130, 180, 181, 288, 295], "krb5_auth_con_getkey_k": 68, "krb5_auth_con_getlocalseqnumb": 69, "sequenc": [69, 74], "number": [69, 74, 116], "krb5_auth_con_getlocalsubkei": 70, "krb5_auth_con_getrcach": 71, "replai": [71, 85, 267, 907, 922], "cach": [71, 85, 132, 133, 134, 135, 136, 137, 139, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 248, 252, 253, 267, 385, 903, 907, 916, 922, 927], "krb5_auth_con_getrecvsubkei": 72, "receiv": [72, 73, 86, 87, 382], "subkei": [72, 73, 76, 77, 86, 87, 88, 89], "krb5_auth_con_getrecvsubkey_k": 73, "krb5_auth_con_getremoteseqnumb": 74, "remot": [74, 82, 84], "krb5_auth_con_getremotesubkei": 75, "krb5_auth_con_getsendsubkei": 76, "send": [76, 77, 88, 89, 383], "krb5_auth_con_getsendsubkey_k": 77, "krb5_auth_con_init": 78, "krb5_auth_con_initivector": 79, "caus": 79, "cipher": [79, 95, 106, 108], "krb5_auth_con_set_checksum_func": 80, "krb5_auth_con_set_req_cksumtyp": 81, "krb5_auth_con_setaddr": 82, "krb5_auth_con_setflag": 83, "krb5_auth_con_setport": 84, "krb5_auth_con_setrcach": 85, "krb5_auth_con_setrecvsubkei": 86, "krb5_auth_con_setrecvsubkey_k": 87, "krb5_auth_con_setsendsubkei": 88, "krb5_auth_con_setsendsubkey_k": 89, "krb5_auth_con_setuseruserkei": 90, "krb5_build_princip": 91, "null": 91, "termin": 91, "krb5_build_principal_alloc_va": 92, "precomput": 92, "argument": 92, "krb5_build_principal_ext": 93, "length": [93, 96, 97, 98, 104, 112, 118, 409, 918], "count": [93, 293, 299], "krb5_build_principal_va": 94, "krb5_c_block_siz": 95, "block": 95, "size": 95, "krb5_c_checksum_length": 96, "krb5_c_crypto_length": 97, "krb5_c_crypto_length_iov": 98, "fill": [98, 114, 297], "header": [98, 916], "trailer": 98, "pad": [98, 116, 399], "arrai": [98, 114, 130, 172, 198, 200, 204, 212, 221, 265, 297, 301, 327, 339], "krb5_c_decrypt": 99, "decrypt": [99, 100, 289, 290, 359, 360, 361, 378], "krb5_c_decrypt_iov": 100, "place": [100, 103, 290, 292], "krb5_c_derive_prfplu": 101, "deriv": 101, "input": [101, 252, 363], "via": 101, "rfc": [101, 119], "6113": [101, 119], "prf": [101, 119], "krb5_c_encrypt": 102, "krb5_c_encrypt_iov": 103, "krb5_c_encrypt_length": 104, "comput": [104, 107, 113, 296], "krb5_c_enctype_compar": 105, "krb5_c_free_stat": 106, "previous": 106, "alloc": [106, 205, 213, 215, 220, 238], "krb5_c_init_st": [106, 108], "krb5_c_fx_cf2_simpl": 107, "krb": [107, 224, 325, 327, 328, 333, 356, 357, 358, 362], "fx": 107, "cf2": 107, "combin": 107, "pepper": 107, "new": [108, 149, 238, 304, 324, 341, 953], "krb5_c_is_coll_proof_cksum": 109, "whether": [109, 110, 160, 285, 287, 390, 418], "i": [109, 110, 127, 128, 167, 285, 321, 418], "collis": 109, "proof": 109, "krb5_c_is_keyed_cksum": 110, "krb5_c_keyed_checksum_typ": 111, "usabl": 111, "krb5_c_keylength": 112, "byte": [112, 117, 119, 121, 298], "krb5_c_make_checksum": 113, "krb5_c_make_checksum_iov": 114, "element": [114, 130, 195, 297, 301], "krb5_c_make_random_kei": 115, "random": [115, 117, 118, 119, 121, 124, 298], "krb5_c_padding_length": 116, "octet": 116, "krb5_c_prf": 117, "pseudo": [117, 118, 119, 121, 298], "krb5_c_prf_length": 118, "output": [118, 253, 399], "function": [118, 220, 259, 365, 366, 377, 382, 383, 388], "krb5_c_prfplu": 119, "krb5_c_random_add_entropi": 120, "krb5_c_random_make_octet": 121, "krb5_c_random_os_entropi": 122, "krb5_c_random_se": 123, "krb5_c_random_to_kei": 124, "krb5_c_string_to_kei": 125, "krb5_c_string_to_key_with_param": 126, "krb5_c_valid_cksumtyp": 127, "valid": [127, 128, 130, 269, 301, 356], "krb5_c_valid_enctyp": 128, "krb5_c_verify_checksum": 129, "krb5_c_verify_checksum_iov": 130, "krb5_calculate_checksum": 131, "krb5_cc_cache_match": 132, "find": [132, 195], "krb5_cc_close": 133, "close": [133, 306], "handl": [133, 138, 306, 309, 319, 335, 336, 339, 340, 341], "krb5_cc_copy_cr": 134, "copi": [134, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 295], "krb5_cc_default": 135, "resolv": [135, 152, 305, 307], "krb5_cc_default_nam": 136, "krb5_cc_destroi": 137, "krb5_cc_dup": 138, "duplic": [138, 309], "ccach": [138, 249, 903], "krb5_cc_end_seq_get": 139, "finish": 139, "seri": 139, "sequenti": [139, 158, 320], "process": [139, 358, 362], "entri": [139, 150, 218, 304, 312, 315, 316, 318, 320, 916, 918, 921], "krb5_cc_gen_new": 140, "krb5_cc_get_config": 141, "krb5_cc_get_flag": 142, "krb5_cc_get_full_nam": 143, "full": [143, 391], "krb5_cc_get_nam": 144, "krb5_cc_get_princip": 145, "krb5_cc_get_typ": 146, "krb5_cc_initi": 147, "krb5_cc_move": 148, "move": 148, "krb5_cc_new_uniqu": 149, "uniqu": 149, "krb5_cc_next_cr": 150, "next": [150, 164, 281, 316, 406], "krb5_cc_remove_cr": 151, "krb5_cc_resolv": 152, "krb5_cc_retrieve_cr": 153, "krb5_cc_select": 154, "krb5_cc_set_config": 155, "krb5_cc_set_default_nam": 156, "krb5_cc_set_flag": 157, "krb5_cc_start_seq_get": 158, "prepar": [158, 163], "read": [158, 338, 356, 363], "everi": 158, "krb5_cc_store_cr": 159, "krb5_cc_support_switch": 160, "determin": [160, 321], "krb5_cc_switch": 161, "make": 161, "its": 161, "collect": [161, 162, 163, 164, 165, 903], "krb5_cccol_cursor_fre": 162, "cursor": [162, 310], "krb5_cccol_cursor_new": 163, "iter": 163, "over": 163, "known": 163, "krb5_cccol_cursor_next": 164, "krb5_cccol_have_cont": 165, "check": [165, 167, 286, 315], "contain": [165, 189, 315, 368], "ani": 165, "krb5_change_password": 166, "exist": [166, 266, 315], "krb5_check_clockskew": 167, "timestamp": [167, 397, 399, 400], "within": [167, 910], "current": [167, 398], "krb5_checksum_s": 168, "krb5_chpw_messag": 169, "result": 169, "krb5_cksumtype_to_str": 170, "krb5_clear_error_messag": 171, "clear": 171, "extend": [171, 179, 230, 381, 420], "krb5_copy_address": 172, "krb5_copy_authdata": 173, "krb5_copy_authent": 174, "krb5_authent": [174, 201, 819], "krb5_copy_checksum": 175, "krb5_checksum": [175, 202, 203, 824], "krb5_copy_context": 176, "krb5_context": [176, 380, 387, 828], "krb5_copy_cr": 177, "krb5_cred": [177, 207, 208, 323, 407, 536, 829, 832], "krb5_copy_data": 178, "krb5_data": [178, 209, 210, 835], "object": [178, 267, 323, 407, 918], "krb5_copy_error_messag": 179, "most": [179, 912], "recent": 179, "one": [179, 374], "anoth": 179, "krb5_copy_keyblock": 180, "krb5_copy_keyblock_cont": 181, "krb5_copy_princip": 182, "krb5_copy_ticket": 183, "krb5_ticket": [183, 889], "krb5_decode_authdata_contain": 184, "unwrap": [184, 414], "krb5_decode_ticket": 185, "decod": [185, 357, 370, 373], "asn": 185, "1": [185, 917, 923], "format": [185, 224, 325, 326, 327, 328, 329, 330, 333, 411, 904, 916, 917, 918, 920, 921, 922], "krb5_decrypt": 186, "krb5_deltat_to_str": 187, "rel": 187, "krb5_eblock_enctyp": 188, "krb5_encode_authdata_contain": 189, "krb5_encrypt": 190, "krb5_encrypt_s": 191, "krb5_enctype_to_nam": 192, "alia": [192, 918], "krb5_enctype_to_str": 193, "krb5_expand_hostnam": 194, "possibli": [194, 230, 302, 303, 345], "krb5_find_authdata": 195, "krb5_finish_kei": 196, "krb5_finish_random_kei": 197, "krb5_free_address": 198, "krb5_free_ap_rep_enc_part": 199, "krb5_ap_rep_enc_part": [199, 814], "krb5_free_authdata": 200, "storag": [200, 219], "assign": [200, 219], "krb5_free_authent": 201, "krb5_free_checksum": 202, "krb5_free_checksum_cont": 203, "krb5_free_cksumtyp": 204, "krb5_free_config_fil": 205, "krb5_get_default_config_fil": [205, 228], "krb5_free_context": 206, "librari": [206, 270, 271, 284, 287], "krb5_free_cred_cont": 207, "krb5_free_cr": 208, "krb5_free_data": 209, "krb5_free_data_cont": 210, "zero": [210, 293], "krb5_free_default_realm": 211, "krb5_get_default_realm": [211, 229], "krb5_free_enctyp": 212, "krb5_free_error": 213, "krb5_read_error": 213, "krb5_sendauth": [213, 377], "krb5_free_error_messag": 214, "krb5_get_error_messag": [214, 230], "krb5_free_host_realm": 215, "krb5_get_host_realm": [215, 233], "krb5_free_keyblock": 216, "krb5_keyblock": [216, 217, 282, 854], "krb5_free_keyblock_cont": 217, "krb5_free_keytab_entry_cont": 218, "tabl": [218, 237, 304, 305, 306, 307, 308, 312, 313, 314, 316, 317, 318, 319, 320, 378], "krb5_free_princip": 219, "krb5_free_str": 220, "krb5_free_tgt_cr": 221, "krb5_free_ticket": 222, "krb5_free_unparsed_nam": 223, "represent": [223, 408], "krb5_fwd_tgt_cred": 224, "forward": [224, 251], "tgt": 224, "cred": [224, 325, 327, 356], "krb5_get_credenti": 225, "krb5_get_credentials_renew": 226, "krb5_get_credentials_valid": 227, "filenam": 228, "code": [230, 348, 381, 419, 420, 421, 422], "krb5_get_etype_info": 231, "salt": [231, 260, 349, 376, 396], "s2kparam": 231, "krb5_get_fallback_host_realm": 232, "krb5_get_in_tkt_with_keytab": 234, "krb5_get_in_tkt_with_password": 235, "krb5_get_in_tkt_with_skei": 236, "krb5_get_init_creds_keytab": 237, "krb5_get_init_creds_opt_alloc": 238, "krb5_get_init_creds_opt_fre": 239, "krb5_get_init_creds_opt_get_fast_flag": 240, "fast": [240, 248, 249, 250], "krb5_get_init_creds_opt_init": 241, "krb5_get_init_creds_opt_set_address_list": 242, "restrict": [242, 960], "krb5_get_init_creds_opt_set_anonym": 243, "unset": [243, 244, 245, 251, 257], "krb5_get_init_creds_opt_set_canonic": 244, "krb5_get_init_creds_opt_set_change_password_prompt": 245, "prompt": [245, 265, 354], "krb5_get_init_creds_opt_set_etype_list": 246, "krb5_get_init_creds_opt_set_expire_callback": 247, "krb5_get_init_creds_opt_set_fast_ccach": 248, "armor": [248, 249], "krb5_get_init_creds_opt_set_fast_ccache_nam": 249, "krb5_get_init_creds_opt_set_fast_flag": 250, "krb5_get_init_creds_opt_set_forward": 251, "krb5_get_init_creds_opt_set_in_ccach": 252, "krb5_get_init_creds_opt_set_out_ccach": 253, "krb5_get_init_creds_opt_set_pa": 254, "suppli": [254, 332], "krb5_get_init_creds_opt_set_pac_request": 255, "ask": 255, "includ": [255, 302, 303], "pac": [255, 302, 303, 335, 336, 337, 338, 339, 340, 341, 344, 345], "krb5_get_init_creds_opt_set_preauth_list": 256, "krb5_get_init_creds_opt_set_proxi": 257, "proxiabl": 257, "krb5_get_init_creds_opt_set_renew_lif": 258, "renew": [258, 266], "lifetim": [258, 261], "krb5_get_init_creds_opt_set_respond": 259, "krb5_get_init_creds_opt_set_salt": 260, "optimist": 260, "krb5_get_init_creds_opt_set_tkt_lif": 261, "krb5_get_init_creds_password": 262, "krb5_get_permitted_enctyp": 263, "permit": 263, "krb5_get_profil": 264, "krb5_get_prompt_typ": 265, "krb5_get_renewed_cr": 266, "krb5_get_server_rcach": 267, "open": 267, "krb5_get_time_offset": 268, "offset": [268, 387, 398], "o": [268, 914], "krb5_get_validated_cr": 269, "krb5_init_context": 270, "krb5_init_context_profil": 271, "krb5_init_creds_fre": 272, "krb5_init_creds_get": 273, "krb5_init_creds_get_cr": 274, "krb5_init_creds_get_error": 275, "last": 275, "krb5_init_creds_get_tim": 276, "krb5_init_creds_init": 277, "krb5_init_creds_set_keytab": 278, "krb5_init_creds_set_password": 279, "krb5_init_creds_set_servic": 280, "krb5_init_creds_step": 281, "krb5_init_keyblock": 282, "empti": [282, 340], "krb5_init_random_kei": 283, "krb5_init_secure_context": 284, "onli": 284, "krb5_is_config_princip": 285, "krb5_is_referral_realm": 286, "match": [286, 390], "krb5_referral_realm": [286, 733], "krb5_is_thread_saf": 287, "wa": 287, "built": 287, "multithread": 287, "krb5_k_create_kei": 288, "krb5_kei": [288, 294, 295, 853], "krb5_k_decrypt": 289, "opaqu": [289, 290, 291, 292, 296, 297, 298, 300, 301], "krb5_k_decrypt_iov": 290, "krb5_k_encrypt": 291, "krb5_k_encrypt_iov": 292, "krb5_k_free_kei": 293, "decrement": 293, "hit": 293, "krb5_k_key_enctyp": 294, "krb5_k_key_keyblock": 295, "krb5_k_make_checksum": 296, "krb5_k_make_checksum_iov": 297, "krb5_k_prf": 298, "krb5_k_reference_kei": 299, "krb5_k_verify_checksum": 300, "krb5_k_verify_checksum_iov": 301, "krb5_kdc_sign_ticket": 302, "sign": [302, 322], "signatur": [302, 303], "krb5_kdc_verify_ticket": 303, "krb5_kt_add_entri": 304, "krb5_kt_client_default": 305, "krb5_kt_close": 306, "krb5_kt_default": 307, "krb5_kt_default_nam": 308, "krb5_kt_dup": 309, "krb5_kt_end_seq_get": 310, "releas": [310, 914], "krb5_kt_free_entri": 311, "krb5_kt_get_entri": 312, "krb5_kt_get_nam": 313, "krb5_kt_get_typ": 314, "krb5_kt_have_cont": 315, "krb5_kt_next_entri": 316, "krb5_kt_read_service_kei": 317, "krb5_kt_remove_entri": 318, "krb5_kt_resolv": 319, "krb5_kt_start_seq_get": 320, "krb5_kuserok": 321, "krb5_make_authdata_kdc_issu": 322, "encod": [322, 326, 341], "kdcissu": [322, 414], "krb5_marshal_credenti": 323, "serial": 323, "krb5_merge_authdata": 324, "merg": 324, "krb5_mk_1cred": 325, "singl": [325, 910], "krb5_mk_error": 326, "krb_error": 326, "krb5_mk_ncred": 327, "krb5_mk_priv": 328, "priv": [328, 358], "krb5_mk_rep": 329, "krb_ap_rep": [329, 330, 359, 360], "krb5_mk_rep_dc": 330, "dce": [330, 360], "rpc": [330, 360], "krb5_mk_req": 331, "krb_ap_req": [331, 332, 361], "krb5_mk_req_extend": 332, "krb5_mk_safe": 333, "safe": [333, 362], "krb5_os_localaddr": 334, "all": 334, "thi": [334, 904, 914], "krb5_pac_add_buff": 335, "buffer": [335, 337, 339], "krb5_pac_fre": 336, "krb5_pac_get_buff": 337, "krb5_pac_get_client_info": 338, "krb5_pac_get_typ": 339, "krb5_pac_init": 340, "krb5_pac_pars": 341, "unpars": 341, "krb5_pac_sign": 342, "krb5_pac_sign_ext": 343, "krb5_pac_verifi": 344, "krb5_pac_verify_ext": 345, "krb5_parse_nam": 346, "krb5_princip": [346, 347, 408, 409, 410, 411, 874], "krb5_parse_name_flag": 347, "krb5_prepend_error_messag": 348, "prefix": [348, 419, 421, 422], "krb5_principal2salt": 349, "krb5_principal_compar": 350, "krb5_principal_compare_any_realm": 351, "ignor": 351, "compon": 351, "krb5_principal_compare_flag": 352, "krb5_process_kei": 353, "krb5_prompter_posix": 354, "krb5_random_kei": 355, "krb5_rd_cred": 356, "krb5_rd_error": 357, "krb5_rd_priv": 358, "krb5_rd_rep": 359, "krb5_rd_rep_dc": 360, "krb5_rd_req": 361, "krb5_rd_safe": 362, "krb5_read_password": 363, "keyboard": 363, "krb5_realm_compar": 364, "krb5_recvauth": 365, "protocol": [365, 366, 377, 920], "krb5_recvauth_vers": 366, "version": [366, 917], "krb5_responder_get_challeng": 367, "challeng": 367, "given": 367, "krb5_responder_list_quest": 368, "krb5_responder_otp_challenge_fre": 369, "krb5_responder_otp_get_challeng": [369, 370], "krb5_responder_question_otp": [370, 371, 744], "c": [370, 373], "struct": [370, 373], "krb5_responder_otp_set_answ": 371, "answer": [371, 374, 375], "krb5_responder_pkinit_challenge_fre": 372, "krb5_responder_pkinit_get_challeng": [372, 373], "krb5_responder_question_pkinit": [373, 374, 746], "krb5_responder_pkinit_set_answ": 374, "krb5_responder_set_answ": 375, "krb5_salttype_to_str": 376, "krb5_server_decrypt_ticket_keytab": 378, "krb5_set_default_realm": 379, "krb5_set_default_tgs_enctyp": 380, "tg": [380, 401, 402, 403, 404, 406], "krb5_set_error_messag": 381, "krb5_set_kdc_recv_hook": 382, "post": 382, "hook": [382, 383, 936], "krb5_set_kdc_send_hook": 383, "pre": 383, "krb5_set_password": 384, "krb5_set_password_using_ccach": 385, "krb5_set_principal_realm": 386, "krb5_set_real_tim": 387, "krb5_set_trace_callback": 388, "event": [388, 389], "krb5_set_trace_filenam": 389, "direct": 389, "krb5_sname_match": 390, "krb5_sname_to_princip": 391, "krb5_string_to_cksumtyp": 392, "krb5_string_to_deltat": 393, "delta": 393, "krb5_string_to_enctyp": 394, "krb5_string_to_kei": 395, "krb5_string_to_salttyp": 396, "krb5_string_to_timestamp": 397, "krb5_timeofdai": 398, "adjust": 398, "krb5_timestamp_to_sfstr": 399, "krb5_timestamp_to_str": 400, "krb5_tkt_creds_fre": 401, "krb5_tkt_creds_get": 402, "synchron": 402, "obtain": [402, 911, 946], "krb5_tkt_creds_get_cr": 403, "krb5_tkt_creds_get_tim": 404, "krb5_tkt_creds_init": 405, "grant": [405, 945], "krb5_tkt_creds_step": 406, "krb5_unmarshal_credenti": 407, "deseri": 407, "krb5_unparse_nam": 408, "krb5_unparse_name_ext": 409, "krb5_unparse_name_flag": 410, "krb5_unparse_name_flags_ext": 411, "krb5_us_timeofdai": 412, "system": [412, 912, 924], "dai": 412, "sec": 412, "m": 412, "sinc": 412, "epoch": 412, "krb5_use_enctyp": 413, "krb5_verify_authdata_kdc_issu": 414, "krb5_verify_checksum": 415, "krb5_verify_init_cr": 416, "against": 416, "krb5_verify_init_creds_opt_init": 417, "krb5_verify_init_creds_opt_set_ap_req_nofail": 418, "requir": [418, 953], "krb5_vprepend_error_messag": 419, "va_list": [419, 420, 421], "krb5_vset_error_messag": 420, "krb5_vwrap_error_messag": 421, "krb5_wrap_error_messag": 422, "complet": 423, "datatyp": 423, "addrtype_addrport": 424, "addrtype_chao": 425, "addrtype_ddp": 426, "addrtype_direct": 427, "addrtype_inet": 428, "addrtype_inet6": 429, "addrtype_ipport": 430, "addrtype_iso": 431, "addrtype_is_loc": 432, "addrtype_netbio": 433, "addrtype_unixsock": 434, "addrtype_xn": 435, "ad_type_extern": 436, "ad_type_field_type_mask": 437, "ad_type_regist": 438, "ad_type_reserv": 439, "ap_opts_cbt_flag": 440, "ap_opts_etype_negoti": 441, "ap_opts_mutual_requir": 442, "ap_opts_reserv": 443, "ap_opts_use_session_kei": 444, "ap_opts_use_subkei": 445, "ap_opts_wire_mask": 446, "cksumtype_cmac_camellia128": 447, "cksumtype_cmac_camellia256": 448, "cksumtype_crc32": 449, "cksumtype_descbc": 450, "cksumtype_hmac_md5_arcfour": 451, "cksumtype_hmac_sha1_96_aes128": 452, "cksumtype_hmac_sha1_96_aes256": 453, "cksumtype_hmac_sha1_des3": 454, "cksumtype_hmac_sha256_128_aes128": 455, "cksumtype_hmac_sha384_192_aes256": 456, "cksumtype_md5_hmac_arcfour": 457, "cksumtype_nist_sha": 458, "cksumtype_rsa_md4": 459, "cksumtype_rsa_md4_d": 460, "cksumtype_rsa_md5": 461, "cksumtype_rsa_md5_d": 462, "cksumtype_sha1": 463, "enctype_aes128_cts_hmac_sha1_96": 464, "enctype_aes128_cts_hmac_sha256_128": 465, "enctype_aes256_cts_hmac_sha1_96": 466, "enctype_aes256_cts_hmac_sha384_192": 467, "enctype_arcfour_hmac": 468, "enctype_arcfour_hmac_exp": 469, "enctype_camellia128_cts_cmac": 470, "enctype_camellia256_cts_cmac": 471, "enctype_des3_cbc_env": 472, "enctype_des3_cbc_raw": 473, "enctype_des3_cbc_sha": 474, "enctype_des3_cbc_sha1": 475, "enctype_des_cbc_crc": 476, "enctype_des_cbc_md4": 477, "enctype_des_cbc_md5": 478, "enctype_des_cbc_raw": 479, "enctype_des_hmac_sha1": 480, "enctype_dsa_sha1_cm": 481, "enctype_md5_rsa_cm": 482, "enctype_nul": 483, "enctype_rc2_cbc_env": 484, "enctype_rsa_env": 485, "enctype_rsa_es_oaep_env": 486, "enctype_sha1_rsa_cm": 487, "enctype_unknown": 488, "kdc_opt_allow_postd": 489, "kdc_opt_canonic": 490, "kdc_opt_cname_in_addl_tkt": 491, "kdc_opt_disable_transited_check": 492, "kdc_opt_enc_tkt_in_skei": 493, "kdc_opt_forward": [494, 495], "kdc_opt_postd": 496, "kdc_opt_proxi": [497, 498], "kdc_opt_renew": [499, 500], "kdc_opt_renewable_ok": 501, "kdc_opt_request_anonym": 502, "kdc_opt_valid": 503, "kdc_tkt_common_mask": 504, "krb5_altauth_att_challenge_respons": 505, "krb5_anonymous_princstr": 506, "krb5_anonymous_realmstr": 507, "krb5_ap_rep": [508, 813], "krb5_ap_req": [509, 815], "krb5_as_rep": 510, "krb5_as_req": 511, "krb5_authdata_and_or": 512, "krb5_authdata_ap_opt": 513, "krb5_authdata_auth_ind": 514, "krb5_authdata_cammac": 515, "krb5_authdata_etype_negoti": 516, "krb5_authdata_fx_armor": 517, "krb5_authdata_if_relev": 518, "krb5_authdata_initial_verified_ca": 519, "krb5_authdata_kdc_issu": 520, "krb5_authdata_mandatory_for_kdc": 521, "krb5_authdata_osf_dc": 522, "krb5_authdata_sesam": 523, "krb5_authdata_signticket": 524, "krb5_authdata_win2k_pac": 525, "krb5_auth_context_do_sequ": 526, "krb5_auth_context_do_tim": 527, "krb5_auth_context_generate_local_addr": 528, "krb5_auth_context_generate_local_full_addr": 529, "krb5_auth_context_generate_remote_addr": 530, "krb5_auth_context_generate_remote_full_addr": 531, "krb5_auth_context_permit_al": 532, "krb5_auth_context_ret_sequ": 533, "krb5_auth_context_ret_tim": 534, "krb5_auth_context_use_subkei": 535, "krb5_crypto_type_checksum": 537, "krb5_crypto_type_data": 538, "krb5_crypto_type_empti": 539, "krb5_crypto_type_head": 540, "krb5_crypto_type_pad": 541, "krb5_crypto_type_sign_onli": 542, "krb5_crypto_type_stream": 543, "krb5_crypto_type_trail": 544, "krb5_cybersafe_secureid": 545, "krb5_domain_x500_compress": 546, "krb5_encpadata_req_enc_pa_rep": 547, "krb5_error": [548, 842], "krb5_fast_requir": 549, "krb5_gc_cach": 550, "krb5_gc_canonic": 551, "krb5_gc_constrained_deleg": 552, "krb5_gc_forward": 553, "krb5_gc_no_stor": 554, "krb5_gc_no_transit_check": 555, "krb5_gc_user_us": 556, "krb5_get_init_creds_opt_address_list": 557, "krb5_get_init_creds_opt_anonym": 558, "krb5_get_init_creds_opt_canonic": 559, "krb5_get_init_creds_opt_chg_pwd_prmpt": 560, "krb5_get_init_creds_opt_etype_list": 561, "krb5_get_init_creds_opt_forward": 562, "krb5_get_init_creds_opt_preauth_list": 563, "krb5_get_init_creds_opt_proxi": 564, "krb5_get_init_creds_opt_renew_lif": 565, "krb5_get_init_creds_opt_salt": 566, "krb5_get_init_creds_opt_tkt_lif": 567, "krb5_init_context_kdc": 568, "krb5_init_context_secur": 569, "krb5_init_creds_step_flag_continu": 570, "krb5_int16_max": 571, "krb5_int16_min": 572, "krb5_int32_max": 573, "krb5_int32_min": 574, "krb5_keyusage_ad_it": 575, "krb5_keyusage_ad_kdcissued_cksum": 576, "krb5_keyusage_ad_mt": 577, "krb5_keyusage_ad_signedpath": 578, "krb5_keyusage_app_data_cksum": 579, "krb5_keyusage_app_data_encrypt": 580, "krb5_keyusage_ap_rep_encpart": 581, "krb5_keyusage_ap_req_auth": 582, "krb5_keyusage_ap_req_auth_cksum": 583, "krb5_keyusage_as_rep_encpart": 584, "krb5_keyusage_as_req": 585, "krb5_keyusage_as_req_pa_enc_t": 586, "krb5_keyusage_cammac": 587, "krb5_keyusage_enc_challenge_cli": 588, "krb5_keyusage_enc_challenge_kdc": 589, "krb5_keyusage_fast_enc": 590, "krb5_keyusage_fast_finish": 591, "krb5_keyusage_fast_rep": 592, "krb5_keyusage_fast_req_chksum": 593, "krb5_keyusage_finish": 594, "krb5_keyusage_gss_tok_m": 595, "krb5_keyusage_gss_tok_wrap_integ": 596, "krb5_keyusage_gss_tok_wrap_priv": 597, "krb5_keyusage_iakerb_finish": 598, "krb5_keyusage_kdc_rep_ticket": 599, "krb5_keyusage_krb_cred_encpart": 600, "krb5_keyusage_krb_error_cksum": 601, "krb5_keyusage_krb_priv_encpart": 602, "krb5_keyusage_krb_safe_cksum": 603, "krb5_keyusage_pa_as_fresh": 604, "krb5_keyusage_pa_fx_cooki": 605, "krb5_keyusage_pa_otp_request": 606, "krb5_keyusage_pa_pkinit_kx": 607, "krb5_keyusage_pa_s4u_x509_user_repli": 608, "krb5_keyusage_pa_s4u_x509_user_request": 609, "krb5_keyusage_pa_sam_challenge_cksum": 610, "krb5_keyusage_pa_sam_challenge_trackid": 611, "krb5_keyusage_pa_sam_respons": 612, "krb5_keyusage_spak": 613, "krb5_keyusage_tgs_rep_encpart_sesskei": 614, "krb5_keyusage_tgs_rep_encpart_subkei": 615, "krb5_keyusage_tgs_req_ad_sesskei": 616, "krb5_keyusage_tgs_req_ad_subkei": 617, "krb5_keyusage_tgs_req_auth": 618, "krb5_keyusage_tgs_req_auth_cksum": 619, "krb5_kpasswd_accessdeni": 620, "krb5_kpasswd_autherror": 621, "krb5_kpasswd_bad_vers": 622, "krb5_kpasswd_harderror": 623, "krb5_kpasswd_initial_flag_need": 624, "krb5_kpasswd_malform": 625, "krb5_kpasswd_softerror": 626, "krb5_kpasswd_success": 627, "krb5_lrq_all_acct_exptim": 628, "krb5_lrq_all_last_initi": 629, "krb5_lrq_all_last_renew": 630, "krb5_lrq_all_last_req": 631, "krb5_lrq_all_last_tgt": 632, "krb5_lrq_all_last_tgt_issu": 633, "krb5_lrq_all_pw_exptim": 634, "krb5_lrq_none": 635, "krb5_lrq_one_acct_exptim": 636, "krb5_lrq_one_last_initi": 637, "krb5_lrq_one_last_renew": 638, "krb5_lrq_one_last_req": 639, "krb5_lrq_one_last_tgt": 640, "krb5_lrq_one_last_tgt_issu": 641, "krb5_lrq_one_pw_exptim": 642, "krb5_nt_enterprise_princip": 643, "krb5_nt_ent_principal_and_id": 644, "krb5_nt_ms_princip": 645, "krb5_nt_ms_principal_and_id": 646, "krb5_nt_princip": 647, "krb5_nt_smtp_name": 648, "krb5_nt_srv_hst": 649, "krb5_nt_srv_inst": 650, "krb5_nt_srv_xhst": 651, "krb5_nt_uid": 652, "krb5_nt_unknown": 653, "krb5_nt_wellknown": 654, "krb5_nt_x500_princip": 655, "krb5_pac_attributes_info": 656, "krb5_pac_client_claim": 657, "krb5_pac_client_info": 658, "krb5_pac_credentials_info": 659, "krb5_pac_delegation_info": 660, "krb5_pac_device_claim": 661, "krb5_pac_device_info": 662, "krb5_pac_full_checksum": 663, "krb5_pac_logon_info": 664, "krb5_pac_privsvr_checksum": 665, "krb5_pac_requestor": 666, "krb5_pac_server_checksum": 667, "krb5_pac_ticket_checksum": 668, "krb5_pac_upn_dns_info": 669, "krb5_padata_afs3_salt": 670, "krb5_padata_ap_req": 671, "krb5_padata_as_checksum": 672, "krb5_padata_as_fresh": 673, "krb5_padata_encrypted_challeng": 674, "krb5_padata_enc_sandia_securid": 675, "krb5_padata_enc_timestamp": 676, "krb5_padata_enc_unix_tim": 677, "krb5_padata_etype_info": 678, "krb5_padata_etype_info2": 679, "krb5_padata_for_us": 680, "krb5_padata_fx_cooki": 681, "krb5_padata_fx_error": 682, "krb5_padata_fx_fast": 683, "krb5_padata_get_from_typed_data": 684, "krb5_padata_non": 685, "krb5_padata_osf_dc": 686, "krb5_padata_otp_challeng": 687, "krb5_padata_otp_pin_chang": 688, "krb5_padata_otp_request": 689, "krb5_padata_pac_opt": 690, "krb5_padata_pac_request": 691, "krb5_padata_pkinit_kx": 692, "krb5_padata_pk_as_rep": 693, "krb5_padata_pk_as_rep_old": 694, "krb5_padata_pk_as_req": 695, "krb5_padata_pk_as_req_old": 696, "krb5_padata_pw_salt": 697, "krb5_padata_redhat_idp_oauth2": 698, "krb5_padata_redhat_passkei": 699, "krb5_padata_referr": 700, "krb5_padata_s4u_x509_us": 701, "krb5_padata_sam_challeng": 702, "krb5_padata_sam_challenge_2": 703, "krb5_padata_sam_redirect": 704, "krb5_padata_sam_respons": 705, "krb5_padata_sam_response_2": 706, "krb5_padata_sesam": 707, "krb5_padata_spak": 708, "krb5_padata_svr_referral_info": 709, "krb5_padata_tgs_req": 710, "krb5_padata_use_specified_kvno": 711, "krb5_principal_compare_casefold": 712, "krb5_principal_compare_enterpris": 713, "krb5_principal_compare_ignore_realm": 714, "krb5_principal_compare_utf8": 715, "krb5_principal_parse_enterpris": 716, "krb5_principal_parse_ignore_realm": 717, "krb5_principal_parse_no_def_realm": 718, "krb5_principal_parse_no_realm": 719, "krb5_principal_parse_require_realm": 720, "krb5_principal_unparse_displai": 721, "krb5_principal_unparse_no_realm": 722, "krb5_principal_unparse_short": 723, "krb5_priv": 724, "krb5_prompt_type_new_password": 725, "krb5_prompt_type_new_password_again": 726, "krb5_prompt_type_password": 727, "krb5_prompt_type_preauth": 728, "krb5_pvno": 729, "krb5_realm_branch_char": 730, "krb5_recvauth_badauthv": 731, "krb5_recvauth_skip_vers": 732, "krb5_responder_otp_flags_collect_pin": 734, "krb5_responder_otp_flags_collect_token": 735, "krb5_responder_otp_flags_nextotp": 736, "krb5_responder_otp_flags_separate_pin": 737, "krb5_responder_otp_format_alphanumer": 738, "krb5_responder_otp_format_decim": 739, "krb5_responder_otp_format_hexadecim": 740, "krb5_responder_pkinit_flags_token_user_pin_count_low": 741, "krb5_responder_pkinit_flags_token_user_pin_final_tri": 742, "krb5_responder_pkinit_flags_token_user_pin_lock": 743, "krb5_responder_question_password": 745, "krb5_safe": 747, "krb5_sam_must_pk_encrypt_sad": 748, "krb5_sam_send_encrypted_sad": 749, "krb5_sam_use_sad_as_kei": 750, "krb5_tc_match_2nd_tkt": 751, "krb5_tc_match_authdata": 752, "krb5_tc_match_flag": 753, "krb5_tc_match_flags_exact": 754, "krb5_tc_match_is_skei": 755, "krb5_tc_match_ktyp": 756, "krb5_tc_match_srv_nameonli": 757, "krb5_tc_match_tim": 758, "krb5_tc_match_times_exact": 759, "krb5_tc_noticket": 760, "krb5_tc_openclos": 761, "krb5_tc_supported_ktyp": 762, "krb5_tgs_name": 763, "krb5_tgs_name_s": 764, "krb5_tgs_rep": 765, "krb5_tgs_req": 766, "krb5_tkt_creds_step_flag_continu": 767, "krb5_verify_init_creds_opt_ap_req_nofail": 768, "krb5_wellknown_namestr": 769, "lr_type_interpretation_mask": 770, "lr_type_this_server_onli": 771, "max_keytab_name_len": 772, "msec_dirbit": 773, "msec_val_mask": 774, "salt_type_afs_length": 775, "salt_type_no_length": 776, "threeparamopen": 777, "tkt_flg_anonym": 778, "tkt_flg_enc_pa_rep": 779, "tkt_flg_forward": [780, 781], "tkt_flg_hw_auth": 782, "tkt_flg_initi": 783, "tkt_flg_invalid": 784, "tkt_flg_may_postd": 785, "tkt_flg_ok_as_deleg": 786, "tkt_flg_postdat": 787, "tkt_flg_pre_auth": 788, "tkt_flg_proxiabl": 789, "tkt_flg_proxi": 790, "tkt_flg_renew": 791, "tkt_flg_transit_policy_check": 792, "valid_int_bit": 793, "valid_uint_bit": 794, "simpl": [795, 914], "macro": 795, "krb524_convert_creds_kdc": 796, "krb524_init_et": 797, "krb5_const": 798, "krb5_princ_compon": 799, "krb5_princ_nam": 800, "krb5_princ_realm": 801, "krb5_princ_set_realm": 802, "krb5_princ_set_realm_data": 803, "krb5_princ_set_realm_length": 804, "krb5_princ_siz": 805, "krb5_princ_typ": 806, "krb5_roundup": 807, "krb5_x": 808, "krb5_xc": 809, "intern": [810, 934], "krb5_address": 811, "declar": [811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901], "member": [811, 813, 814, 815, 817, 819, 824, 827, 829, 830, 831, 832, 833, 835, 837, 838, 839, 840, 842, 846, 847, 851, 852, 854, 856, 860, 865, 866, 867, 868, 874, 875, 876, 879, 881, 884, 885, 886, 887, 888, 889, 890, 892, 895, 896, 897, 900, 901], "krb5_addrtyp": 812, "krb5_authdata": 817, "krb5_authdatatyp": 818, "krb5_boolean": 820, "krb5_cc_cursor": 821, "krb5_ccach": 822, "krb5_cccol_cursor": 823, "krb5_cksumtyp": 825, "krb5_const_point": 826, "krb5_const_princip": 827, "krb5_cred_enc_part": 830, "krb5_cred_info": 831, "krb5_crypto_iov": 833, "krb5_cryptotyp": 834, "krb5_deltat": 836, "krb5_enc_data": 837, "krb5_enc_kdc_rep_part": 838, "krb5_enc_tkt_part": 839, "krb5_encrypt_block": 840, "krb5_enctyp": 841, "krb5_error_cod": 843, "krb5_expire_callback_func": 844, "krb5_flag": 845, "krb5_get_init_creds_opt": 846, "krb5_gic_opt_pa_data": 847, "krb5_init_creds_context": 848, "krb5_int16": 849, "krb5_int32": 850, "krb5_kdc_rep": 851, "krb5_kdc_req": 852, "krb5_keytab": 855, "krb5_keytab_entri": 856, "krb5_keyusag": 857, "krb5_kt_cursor": 858, "krb5_kvno": 859, "krb5_last_req_entri": 860, "krb5_magic": 861, "krb5_mk_req_checksum_func": 862, "krb5_msgtype": 863, "krb5_octet": 864, "krb5_pa_data": 865, "krb5_pa_pac_req": 866, "krb5_pa_server_referral_data": 867, "krb5_pa_svr_referral_data": 868, "krb5_pac": 869, "krb5_pointer": 870, "krb5_post_recv_fn": 871, "krb5_pre_send_fn": 872, "krb5_preauthtyp": 873, "krb5_principal_data": 875, "krb5_prompt": 876, "krb5_prompt_typ": 877, "krb5_prompter_fct": 878, "krb5_pwd_data": 879, "krb5_rcach": 880, "krb5_replay_data": 881, "krb5_responder_context": 882, "krb5_responder_fn": 883, "krb5_responder_otp_challeng": 884, "krb5_responder_otp_tokeninfo": 885, "krb5_responder_pkinit_challeng": 886, "krb5_responder_pkinit_ident": 887, "krb5_respons": 888, "krb5_ticket_tim": 890, "krb5_timestamp": [891, 902], "krb5_tkt_authent": 892, "krb5_tkt_creds_context": 893, "krb5_trace_callback": 894, "krb5_trace_info": 895, "krb5_transit": 896, "krb5_typed_data": 897, "krb5_ui_2": 898, "krb5_ui_4": 899, "krb5_verify_init_creds_opt": 900, "passwd_phrase_el": 901, "year": 902, "2038": 902, "tool": 903, "alter": 903, "date": 904, "durat": 904, "getdat": 904, "absolut": 904, "abbrevi": 904, "concept": [905, 930], "organ": 909, "sourc": [909, 914], "directori": [909, 910, 912], "lib": 909, "util": 909, "do": 910, "tree": 910, "separ": 910, "lndir": 910, "binari": 910, "clean": 910, "autoconf": 910, "prerequisit": 911, "softwar": 911, "commonli": 912, "fine": 912, "tune": 912, "featur": [912, 925], "packag": [912, 914], "osconf": 913, "hin": 913, "how": 914, "without": 914, "man": 914, "page": [914, 943], "tarbal": 914, "web": [914, 943], "site": 914, "copyright": 915, "cooki": 917, "trivial": 917, "0": 917, "kdb": [918, 934], "tag": 918, "per": 918, "activ": 918, "kvno": [918, 955], "auxiliari": 918, "lmdb": 918, "22": 923, "path": 924, "like": 924, "quick": 925, "fact": 925, "interoper": 925, "licens": 926, "negoex": 931, "interpos": 931, "pluggabl": 934, "authdata": 934, "kdcpolici": 937, "qualiti": [942, 945], "resourc": 943, "mail": 943, "irc": 943, "archiv": 943, "wiki": 943, "manag": [945, 946], "access": 945, "properti": 946, "kinit": [946, 949], "klist": [946, 950], "kdestroi": [946, 948], "note": 948, "kpasswd": 951, "config": [952, 957], "ksu": 953, "execut": 953, "OF": 953, "THE": 953, "target": 953, "A": 953, "instruct": 953, "side": 953, "effect": 953, "kswitch": 954, "sclient": 956, "k5ident": 958, "k5login": 959, "bug": 960}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 60}, "alltitles": {"Contributing to the MIT Kerberos Documentation": [[0, "contributing-to-the-mit-kerberos-documentation"]], "Background": [[0, "background"]], "Administration programs": [[1, "administration-programs"]], "k5srvutil": [[2, "k5srvutil"]], "SYNOPSIS": [[2, "synopsis"], [3, "synopsis"], [4, "synopsis"], [5, "synopsis"], [6, "synopsis"], [7, "synopsis"], [8, "synopsis"], [9, "synopsis"], [10, "synopsis"], [11, "synopsis"], [12, "synopsis"], [948, "synopsis"], [949, "synopsis"], [950, "synopsis"], [951, "synopsis"], [952, "synopsis"], [953, "synopsis"], [954, "synopsis"], [955, "synopsis"], [956, "synopsis"]], "DESCRIPTION": [[2, "description"], [3, "description"], [4, "description"], [5, "description"], [6, "description"], [7, "description"], [8, "description"], [9, "description"], [10, "description"], [11, "description"], [12, "description"], [19, "description"], [948, "description"], [949, "description"], [950, "description"], [951, "description"], [952, "description"], [953, "description"], [954, "description"], [955, "description"], [956, "description"], [958, "description"], [959, "description"], [960, "description"]], "ENVIRONMENT": [[2, "environment"], [3, "environment"], [4, "environment"], [5, "environment"], [6, "environment"], [7, "environment"], [8, "environment"], [9, "environment"], [10, "environment"], [11, "environment"], [12, "environment"], [948, "environment"], [949, "environment"], [950, "environment"], [951, "environment"], [953, "environment"], [954, "environment"], [955, "environment"], [956, "environment"]], "SEE ALSO": [[2, "see-also"], [3, "see-also"], [4, "see-also"], [5, "see-also"], [6, "see-also"], [7, "see-also"], [8, "see-also"], [9, "see-also"], [10, "see-also"], [11, "see-also"], [12, "see-also"], [19, "see-also"], [20, "see-also"], [21, "see-also"], [948, "see-also"], [949, "see-also"], [950, "see-also"], [951, "see-also"], [952, "see-also"], [953, "see-also"], [954, "see-also"], [955, "see-also"], [956, "see-also"], [958, "see-also"], [959, "see-also"], [960, "see-also"]], "kadmin": [[3, "kadmin"]], "OPTIONS": [[3, "options"], [4, "options"], [7, "options"], [8, "options"], [9, "options"], [10, "options"], [948, "options"], [949, "options"], [950, "options"], [951, "options"], [952, "options"], [953, "options"], [954, "options"], [955, "options"]], "DATABASE OPTIONS": [[3, "database-options"]], "COMMANDS": [[3, "commands"], [5, "commands"], [6, "commands"], [11, "commands"]], "add_principal": [[3, "add-principal"]], "modify_principal": [[3, "modify-principal"]], "rename_principal": [[3, "rename-principal"]], "add_alias": [[3, "add-alias"]], "delete_principal": [[3, "delete-principal"]], "change_password": [[3, "change-password"]], "purgekeys": [[3, "purgekeys"]], "get_principal": [[3, "get-principal"]], "list_principals": [[3, "list-principals"]], "get_strings": [[3, "get-strings"]], "set_string": [[3, "set-string"]], "del_string": [[3, "del-string"]], "add_policy": [[3, "add-policy"]], "modify_policy": [[3, "modify-policy"], [5, "modify-policy"]], "delete_policy": [[3, "delete-policy"]], "get_policy": [[3, "get-policy"]], "list_policies": [[3, "list-policies"]], "ktadd": [[3, "ktadd"]], "ktremove": [[3, "ktremove"]], "lock": [[3, "lock"]], "unlock": [[3, "unlock"]], "list_requests": [[3, "list-requests"], [11, "list-requests"]], "quit": [[3, "quit"], [11, "quit"]], "HISTORY": [[3, "history"], [960, "history"]], "kadmind": [[4, "kadmind"]], "kdb5_ldap_util": [[5, "kdb5-ldap-util"]], "COMMAND-LINE OPTIONS": [[5, "command-line-options"], [6, "command-line-options"]], "create": [[5, "create"], [6, "create"]], "modify": [[5, "modify"]], "view": [[5, "view"]], "destroy": [[5, "destroy"], [6, "destroy"]], "list": [[5, "list"], [11, "list"]], "stashsrvpw": [[5, "stashsrvpw"]], "create_policy": [[5, "create-policy"]], "view_policy": [[5, "view-policy"]], "destroy_policy": [[5, "destroy-policy"]], "list_policy": [[5, "list-policy"]], "kdb5_util": [[6, "kdb5-util"]], "stash": [[6, "stash"]], "dump": [[6, "dump"]], "load": [[6, "load"]], "ark": [[6, "ark"]], "add_mkey": [[6, "add-mkey"]], "use_mkey": [[6, "use-mkey"]], "list_mkeys": [[6, "list-mkeys"]], "purge_mkeys": [[6, "purge-mkeys"]], "update_princ_encryption": [[6, "update-princ-encryption"]], "tabdump": [[6, "tabdump"]], "kprop": [[7, "kprop"]], "kpropd": [[8, "kpropd"]], "FILES": [[8, "files"], [20, "files"], [21, "files"], [948, "files"], [949, "files"], [950, "files"], [954, "files"], [955, "files"]], "kproplog": [[9, "kproplog"]], "krb5kdc": [[10, "krb5kdc"]], "EXAMPLE": [[10, "example"], [11, "example"], [19, "example"], [958, "example"]], "ktutil": [[11, "ktutil"]], "read_kt": [[11, "read-kt"]], "write_kt": [[11, "write-kt"]], "clear_list": [[11, "clear-list"]], "delete_entry": [[11, "delete-entry"]], "add_entry": [[11, "add-entry"]], "sserver": [[12, "sserver"]], "COMMON ERROR MESSAGES": [[12, "common-error-messages"]], "Advanced topics": [[13, "advanced-topics"]], "Retiring DES": [[14, "retiring-des"]], "History": [[14, "history"]], "Types of keys": [[14, "types-of-keys"]], "Upgrade procedure": [[14, "upgrade-procedure"]], "The krbtgt key and KDC keys": [[14, "the-krbtgt-key-and-kdc-keys"]], "Adding strong keys to application servers": [[14, "adding-strong-keys-to-application-servers"]], "Adding strong keys by default": [[14, "adding-strong-keys-by-default"]], "Removing DES keys from usage": [[14, "removing-des-keys-from-usage"]], "Support for legacy services": [[14, "support-for-legacy-services"]], "The Database Master Key": [[14, "the-database-master-key"]], "Application servers": [[15, "application-servers"]], "Keytabs": [[15, "keytabs"]], "Adding principals to keytabs": [[15, "adding-principals-to-keytabs"]], "Removing principals from keytabs": [[15, "removing-principals-from-keytabs"]], "Using a keytab to acquire client credentials": [[15, "using-a-keytab-to-acquire-client-credentials"]], "Clock Skew": [[15, "clock-skew"]], "Getting DNS information correct": [[15, "getting-dns-information-correct"]], "Configuring your firewall to work with Kerberos V5": [[15, "configuring-your-firewall-to-work-with-kerberos-v5"]], "Authentication indicators": [[16, "authentication-indicators"]], "Backups of secure hosts": [[17, "backups-of-secure-hosts"]], "Backing up the Kerberos database": [[17, "backing-up-the-kerberos-database"]], "Configuration Files": [[18, "configuration-files"]], "Contents": [[18, "contents"], [31, "contents"], [911, "contents"], [933, "contents"]], "kadm5.acl": [[19, "kadm5-acl"]], "SYNTAX": [[19, "syntax"]], "MODULE BEHAVIOR": [[19, "module-behavior"]], "kdc.conf": [[20, "kdc-conf"], [34, "kdc-conf"]], "Structure": [[20, "structure"], [21, "structure"]], "Sections": [[20, "sections"], [21, "sections"]], "[kdcdefaults]": [[20, "kdcdefaults"]], "[realms]": [[20, "realms"], [21, "realms"]], "[dbdefaults]": [[20, "dbdefaults"]], "[dbmodules]": [[20, "dbmodules"]], "[logging]": [[20, "logging"]], "[otp]": [[20, "otp"]], "PKINIT options": [[20, "pkinit-options"], [21, "pkinit-options"]], "Encryption types": [[20, "encryption-types"], [26, "encryption-types"]], "Keysalt lists": [[20, "keysalt-lists"]], "Sample kdc.conf File": [[20, "sample-kdc-conf-file"]], "krb5.conf": [[21, "krb5-conf"], [34, "krb5-conf"]], "[libdefaults]": [[21, "libdefaults"]], "[domain_realm]": [[21, "domain-realm"]], "[capaths]": [[21, "capaths"]], "[appdefaults]": [[21, "appdefaults"]], "[plugins]": [[21, "plugins"]], "ccselect interface": [[21, "ccselect-interface"]], "pwqual interface": [[21, "pwqual-interface"]], "kadm5_hook interface": [[21, "kadm5-hook-interface"]], "kadm5_auth interface": [[21, "kadm5-auth-interface"]], "clpreauth and kdcpreauth interfaces": [[21, "clpreauth-and-kdcpreauth-interfaces"]], "hostrealm interface": [[21, "hostrealm-interface"]], "localauth interface": [[21, "localauth-interface"]], "certauth interface": [[21, "certauth-interface"]], "Specifying PKINIT identity information": [[21, "specifying-pkinit-identity-information"]], "PKINIT krb5.conf options": [[21, "pkinit-krb5-conf-options"]], "Parameter expansion": [[21, "parameter-expansion"]], "Sample krb5.conf file": [[21, "sample-krb5-conf-file"]], "Configuring Kerberos with OpenLDAP back-end": [[22, "configuring-kerberos-with-openldap-back-end"]], "Database administration": [[23, "database-administration"]], "Principals": [[23, "principals"]], "Policies": [[23, "policies"]], "Updating the history key": [[23, "updating-the-history-key"]], "Privileges": [[23, "privileges"]], "Operations on the Kerberos database": [[23, "operations-on-the-kerberos-database"]], "Dumping and loading a Kerberos database": [[23, "dumping-and-loading-a-kerberos-database"]], "Updating the master key": [[23, "updating-the-master-key"]], "Operations on the LDAP database": [[23, "operations-on-the-ldap-database"]], "Ticket Policy operations": [[23, "ticket-policy-operations"]], "Cross-realm authentication": [[23, "cross-realm-authentication"]], "Changing the krbtgt key": [[23, "changing-the-krbtgt-key"]], "Incremental database propagation": [[23, "incremental-database-propagation"], [34, "incremental-database-propagation"]], "Overview": [[23, "overview"]], "Sun/MIT incremental propagation differences": [[23, "sun-mit-incremental-propagation-differences"]], "Database types": [[24, "database-types"]], "Berkeley database module (db2)": [[24, "berkeley-database-module-db2"]], "Lightning Memory-Mapped Database module (klmdb)": [[24, "lightning-memory-mapped-database-module-klmdb"]], "LDAP module (kldap)": [[24, "ldap-module-kldap"]], "Addressing dictionary attack risks": [[25, "addressing-dictionary-attack-risks"]], "Enctypes in requests": [[26, "enctypes-in-requests"]], "Session key selection": [[26, "session-key-selection"]], "Choosing enctypes for a service": [[26, "choosing-enctypes-for-a-service"]], "Configuration variables": [[26, "configuration-variables"]], "Enctype compatibility": [[26, "enctype-compatibility"]], "Migrating away from older encryption types": [[26, "migrating-away-from-older-encryption-types"]], "Environment variables": [[27, "environment-variables"], [912, "environment-variables"]], "Host configuration": [[28, "host-configuration"]], "Default realm": [[28, "default-realm"]], "Login authorization": [[28, "login-authorization"]], "Plugin module configuration": [[28, "plugin-module-configuration"]], "KDC location modules": [[28, "kdc-location-modules"]], "GSSAPI mechanism modules": [[28, "gssapi-mechanism-modules"]], "Configuration profile modules": [[28, "configuration-profile-modules"]], "HTTPS proxy configuration": [[29, "https-proxy-configuration"]], "Configuring the clients": [[29, "configuring-the-clients"], [37, "configuring-the-clients"]], "For administrators": [[30, "for-administrators"]], "Installation guide": [[31, "installation-guide"]], "Additional references": [[31, "additional-references"]], "UNIX Application Servers": [[32, "unix-application-servers"]], "The keytab file": [[32, "the-keytab-file"]], "Some advice about secure hosts": [[32, "some-advice-about-secure-hosts"]], "Installing and configuring UNIX client machines": [[33, "installing-and-configuring-unix-client-machines"]], "Client machine configuration files": [[33, "client-machine-configuration-files"]], "Installing KDCs": [[34, "installing-kdcs"]], "Install and configure the primary KDC": [[34, "install-and-configure-the-primary-kdc"]], "Edit KDC configuration files": [[34, "edit-kdc-configuration-files"]], "Create the KDC database": [[34, "create-the-kdc-database"]], "Add administrators to the ACL file": [[34, "add-administrators-to-the-acl-file"]], "Add administrators to the Kerberos database": [[34, "add-administrators-to-the-kerberos-database"]], "Start the Kerberos daemons on the primary KDC": [[34, "start-the-kerberos-daemons-on-the-primary-kdc"]], "Install the replica KDCs": [[34, "install-the-replica-kdcs"]], "Create host keytabs for replica KDCs": [[34, "create-host-keytabs-for-replica-kdcs"]], "Configure replica KDCs": [[34, "configure-replica-kdcs"]], "Propagate the database to each replica KDC": [[34, "propagate-the-database-to-each-replica-kdc"]], "Propagation failed?": [[34, "propagation-failed"]], "Add Kerberos principals to the database": [[34, "add-kerberos-principals-to-the-database"]], "Switching primary and replica KDCs": [[34, "switching-primary-and-replica-kdcs"]], "Account lockout": [[35, "account-lockout"]], "Configuring account lockout": [[35, "configuring-account-lockout"]], "Testing account lockout": [[35, "testing-account-lockout"]], "Account lockout principal state": [[35, "account-lockout-principal-state"]], "KDC replication and account lockout": [[35, "kdc-replication-and-account-lockout"]], "KDC performance and account lockout": [[35, "kdc-performance-and-account-lockout"]], "KDC setup and account lockout": [[35, "kdc-setup-and-account-lockout"]], "OTP Preauthentication": [[36, "otp-preauthentication"]], "Defining token types": [[36, "defining-token-types"]], "The default token type": [[36, "the-default-token-type"]], "Token instance configuration": [[36, "token-instance-configuration"]], "Other considerations": [[36, "other-considerations"]], "PKINIT configuration": [[37, "pkinit-configuration"]], "Creating certificates": [[37, "creating-certificates"]], "Generating a certificate authority certificate": [[37, "generating-a-certificate-authority-certificate"]], "Generating a KDC certificate": [[37, "generating-a-kdc-certificate"]], "Generating client certificates": [[37, "generating-client-certificates"]], "Configuring the KDC": [[37, "configuring-the-kdc"]], "Anonymous PKINIT": [[37, "anonymous-pkinit"]], "Freshness tokens": [[37, "freshness-tokens"]], "Principal names and DNS": [[38, "principal-names-and-dns"]], "Service principal names": [[38, "service-principal-names"]], "Service principal canonicalization": [[38, "service-principal-canonicalization"]], "Reverse DNS mismatches": [[38, "reverse-dns-mismatches"]], "Overriding application behavior": [[38, "overriding-application-behavior"]], "Provisioning keytabs": [[38, "provisioning-keytabs"]], "Specific application advice": [[38, "specific-application-advice"]], "Secure shell (ssh)": [[38, "secure-shell-ssh"]], "OpenLDAP (ldapsearch, etc.)": [[38, "openldap-ldapsearch-etc"]], "Realm configuration decisions": [[39, "realm-configuration-decisions"]], "Realm name": [[39, "realm-name"]], "Mapping hostnames onto Kerberos realms": [[39, "mapping-hostnames-onto-kerberos-realms"]], "Ports for the KDC and admin services": [[39, "ports-for-the-kdc-and-admin-services"]], "Replica KDCs": [[39, "replica-kdcs"]], "Hostnames for KDCs": [[39, "hostnames-for-kdcs"]], "KDC Discovery": [[39, "kdc-discovery"]], "Database propagation": [[39, "database-propagation"]], "SPAKE Preauthentication": [[40, "spake-preauthentication"]], "Troubleshooting": [[41, "troubleshooting"], [42, "troubleshooting"]], "Trace logging": [[41, "trace-logging"]], "List of errors": [[41, "list-of-errors"]], "Frequently seen errors": [[41, "frequently-seen-errors"]], "Errors seen by admins": [[41, "errors-seen-by-admins"]], "KDC has no support for encryption type while getting initial credentials": [[41, "kdc-has-no-support-for-encryption-type-while-getting-initial-credentials"]], "credential verification failed: KDC has no support for encryption type": [[41, "credential-verification-failed-kdc-has-no-support-for-encryption-type"]], "Cannot create cert chain: certificate has expired": [[41, "cannot-create-cert-chain-certificate-has-expired"]], "kprop: No route to host while connecting to server": [[41, "kprop-no-route-to-host-while-connecting-to-server"]], "kprop: Connection refused while connecting to server": [[41, "kprop-connection-refused-while-connecting-to-server"]], "kprop: Server rejected authentication (during sendauth exchange) while authenticating to server": [[41, "kprop-server-rejected-authentication-during-sendauth-exchange-while-authenticating-to-server"]], "Various links": [[42, "various-links"]], "Whitepapers": [[42, "whitepapers"]], "Tutorials": [[42, "tutorials"]], "Developing with GSSAPI": [[43, "developing-with-gssapi"]], "Name types": [[43, "name-types"]], "Initiator credentials": [[43, "initiator-credentials"]], "Acceptor names": [[43, "acceptor-names"]], "Name Attributes": [[43, "name-attributes"]], "Credential store extensions": [[43, "credential-store-extensions"]], "Importing and exporting credentials": [[43, "importing-and-exporting-credentials"]], "Constrained delegation (S4U)": [[43, "constrained-delegation-s4u"]], "Channel binding behavior and GSS_C_CHANNEL_BOUND_FLAG": [[43, "channel-binding-behavior-and-gss-c-channel-bound-flag"]], "AEAD message wrapping": [[43, "aead-message-wrapping"]], "IOV message wrapping": [[43, "iov-message-wrapping"]], "IOV MIC tokens": [[43, "iov-mic-tokens"]], "Differences between Heimdal and MIT Kerberos API": [[44, "differences-between-heimdal-and-mit-kerberos-api"]], "For application developers": [[45, "for-application-developers"]], "Initial credentials": [[46, "initial-credentials"]], "Options for get_init_creds": [[46, "options-for-get-init-creds"]], "Getting anonymous credentials": [[46, "getting-anonymous-credentials"]], "User interaction": [[46, "user-interaction"]], "Prompter callback": [[46, "prompter-callback"]], "Responder callback": [[46, "responder-callback"]], "Password question": [[46, "password-question"]], "One-time password question": [[46, "one-time-password-question"]], "PKINIT password or PIN question": [[46, "pkinit-password-or-pin-question"]], "Example": [[46, "example"]], "Verifying initial credentials": [[46, "verifying-initial-credentials"]], "Principal manipulation and parsing": [[47, "principal-manipulation-and-parsing"]], "krb5 API": [[48, "krb5-api"]], "Frequently used public interfaces": [[48, "frequently-used-public-interfaces"]], "Rarely used public interfaces": [[48, "rarely-used-public-interfaces"]], "Public interfaces that should not be called directly": [[48, "public-interfaces-that-should-not-be-called-directly"]], "Legacy convenience interfaces": [[48, "legacy-convenience-interfaces"]], "Deprecated public interfaces": [[48, "deprecated-public-interfaces"]], "krb5_425_conv_principal - Convert a Kerberos V4 principal to a Kerberos V5 principal.": [[49, "krb5-425-conv-principal-convert-a-kerberos-v4-principal-to-a-kerberos-v5-principal"]], "krb5_524_conv_principal - Convert a Kerberos V5 principal to a Kerberos V4 principal.": [[50, "krb5-524-conv-principal-convert-a-kerberos-v5-principal-to-a-kerberos-v4-principal"]], "krb5_524_convert_creds - Convert a Kerberos V5 credentials to a Kerberos V4 credentials.": [[51, "krb5-524-convert-creds-convert-a-kerberos-v5-credentials-to-a-kerberos-v4-credentials"]], "krb5_address_compare - Compare two Kerberos addresses.": [[52, "krb5-address-compare-compare-two-kerberos-addresses"]], "krb5_address_order - Return an ordering of the specified addresses.": [[53, "krb5-address-order-return-an-ordering-of-the-specified-addresses"]], "krb5_address_search - Search a list of addresses for a specified address.": [[54, "krb5-address-search-search-a-list-of-addresses-for-a-specified-address"]], "krb5_allow_weak_crypto - Allow the application to override the profile\u2019s allow_weak_crypto setting.": [[55, "krb5-allow-weak-crypto-allow-the-application-to-override-the-profile-s-allow-weak-crypto-setting"]], "krb5_aname_to_localname - Convert a principal name to a local name.": [[56, "krb5-aname-to-localname-convert-a-principal-name-to-a-local-name"]], "krb5_anonymous_principal - Build an anonymous principal.": [[57, "krb5-anonymous-principal-build-an-anonymous-principal"]], "krb5_anonymous_realm - Return an anonymous realm data.": [[58, "krb5-anonymous-realm-return-an-anonymous-realm-data"]], "krb5_appdefault_boolean - Retrieve a boolean value from the appdefaults section of krb5.conf.": [[59, "krb5-appdefault-boolean-retrieve-a-boolean-value-from-the-appdefaults-section-of-krb5-conf"]], "krb5_appdefault_string - Retrieve a string value from the appdefaults section of krb5.conf.": [[60, "krb5-appdefault-string-retrieve-a-string-value-from-the-appdefaults-section-of-krb5-conf"]], "krb5_auth_con_free - Free a krb5_auth_context structure.": [[61, "krb5-auth-con-free-free-a-krb5-auth-context-structure"]], "krb5_auth_con_genaddrs - Generate auth context addresses from a connected socket.": [[62, "krb5-auth-con-genaddrs-generate-auth-context-addresses-from-a-connected-socket"]], "krb5_auth_con_get_checksum_func - Get the checksum callback from an auth context.": [[63, "krb5-auth-con-get-checksum-func-get-the-checksum-callback-from-an-auth-context"]], "krb5_auth_con_getaddrs - Retrieve address fields from an auth context.": [[64, "krb5-auth-con-getaddrs-retrieve-address-fields-from-an-auth-context"]], "krb5_auth_con_getauthenticator - Retrieve the authenticator from an auth context.": [[65, "krb5-auth-con-getauthenticator-retrieve-the-authenticator-from-an-auth-context"]], "krb5_auth_con_getflags - Retrieve flags from a krb5_auth_context structure.": [[66, "krb5-auth-con-getflags-retrieve-flags-from-a-krb5-auth-context-structure"]], "krb5_auth_con_getkey - Retrieve the session key from an auth context as a keyblock.": [[67, "krb5-auth-con-getkey-retrieve-the-session-key-from-an-auth-context-as-a-keyblock"]], "krb5_auth_con_getkey_k - Retrieve the session key from an auth context.": [[68, "krb5-auth-con-getkey-k-retrieve-the-session-key-from-an-auth-context"]], "krb5_auth_con_getlocalseqnumber - Retrieve the local sequence number from an auth context.": [[69, "krb5-auth-con-getlocalseqnumber-retrieve-the-local-sequence-number-from-an-auth-context"]], "krb5_auth_con_getlocalsubkey": [[70, "krb5-auth-con-getlocalsubkey"]], "krb5_auth_con_getrcache - Retrieve the replay cache from an auth context.": [[71, "krb5-auth-con-getrcache-retrieve-the-replay-cache-from-an-auth-context"]], "krb5_auth_con_getrecvsubkey - Retrieve the receiving subkey from an auth context as a keyblock.": [[72, "krb5-auth-con-getrecvsubkey-retrieve-the-receiving-subkey-from-an-auth-context-as-a-keyblock"]], "krb5_auth_con_getrecvsubkey_k - Retrieve the receiving subkey from an auth context as a keyblock.": [[73, "krb5-auth-con-getrecvsubkey-k-retrieve-the-receiving-subkey-from-an-auth-context-as-a-keyblock"]], "krb5_auth_con_getremoteseqnumber - Retrieve the remote sequence number from an auth context.": [[74, "krb5-auth-con-getremoteseqnumber-retrieve-the-remote-sequence-number-from-an-auth-context"]], "krb5_auth_con_getremotesubkey": [[75, "krb5-auth-con-getremotesubkey"]], "krb5_auth_con_getsendsubkey - Retrieve the send subkey from an auth context as a keyblock.": [[76, "krb5-auth-con-getsendsubkey-retrieve-the-send-subkey-from-an-auth-context-as-a-keyblock"]], "krb5_auth_con_getsendsubkey_k - Retrieve the send subkey from an auth context.": [[77, "krb5-auth-con-getsendsubkey-k-retrieve-the-send-subkey-from-an-auth-context"]], "krb5_auth_con_init - Create and initialize an authentication context.": [[78, "krb5-auth-con-init-create-and-initialize-an-authentication-context"]], "krb5_auth_con_initivector - Cause an auth context to use cipher state.": [[79, "krb5-auth-con-initivector-cause-an-auth-context-to-use-cipher-state"]], "krb5_auth_con_set_checksum_func - Set a checksum callback in an auth context.": [[80, "krb5-auth-con-set-checksum-func-set-a-checksum-callback-in-an-auth-context"]], "krb5_auth_con_set_req_cksumtype - Set checksum type in an an auth context.": [[81, "krb5-auth-con-set-req-cksumtype-set-checksum-type-in-an-an-auth-context"]], "krb5_auth_con_setaddrs - Set the local and remote addresses in an auth context.": [[82, "krb5-auth-con-setaddrs-set-the-local-and-remote-addresses-in-an-auth-context"]], "krb5_auth_con_setflags - Set a flags field in a krb5_auth_context structure.": [[83, "krb5-auth-con-setflags-set-a-flags-field-in-a-krb5-auth-context-structure"]], "krb5_auth_con_setports - Set local and remote port fields in an auth context.": [[84, "krb5-auth-con-setports-set-local-and-remote-port-fields-in-an-auth-context"]], "krb5_auth_con_setrcache - Set the replay cache in an auth context.": [[85, "krb5-auth-con-setrcache-set-the-replay-cache-in-an-auth-context"]], "krb5_auth_con_setrecvsubkey - Set the receiving subkey in an auth context with a keyblock.": [[86, "krb5-auth-con-setrecvsubkey-set-the-receiving-subkey-in-an-auth-context-with-a-keyblock"]], "krb5_auth_con_setrecvsubkey_k - Set the receiving subkey in an auth context.": [[87, "krb5-auth-con-setrecvsubkey-k-set-the-receiving-subkey-in-an-auth-context"]], "krb5_auth_con_setsendsubkey - Set the send subkey in an auth context with a keyblock.": [[88, "krb5-auth-con-setsendsubkey-set-the-send-subkey-in-an-auth-context-with-a-keyblock"]], "krb5_auth_con_setsendsubkey_k - Set the send subkey in an auth context.": [[89, "krb5-auth-con-setsendsubkey-k-set-the-send-subkey-in-an-auth-context"]], "krb5_auth_con_setuseruserkey - Set the session key in an auth context.": [[90, "krb5-auth-con-setuseruserkey-set-the-session-key-in-an-auth-context"]], "krb5_build_principal - Build a principal name using null-terminated strings.": [[91, "krb5-build-principal-build-a-principal-name-using-null-terminated-strings"]], "krb5_build_principal_alloc_va - Build a principal name, using a precomputed variable argument list.": [[92, "krb5-build-principal-alloc-va-build-a-principal-name-using-a-precomputed-variable-argument-list"]], "krb5_build_principal_ext - Build a principal name using length-counted strings.": [[93, "krb5-build-principal-ext-build-a-principal-name-using-length-counted-strings"]], "krb5_build_principal_va": [[94, "krb5-build-principal-va"]], "krb5_c_block_size - Return cipher block size.": [[95, "krb5-c-block-size-return-cipher-block-size"]], "krb5_c_checksum_length - Return the length of checksums for a checksum type.": [[96, "krb5-c-checksum-length-return-the-length-of-checksums-for-a-checksum-type"]], "krb5_c_crypto_length - Return a length of a message field specific to the encryption type.": [[97, "krb5-c-crypto-length-return-a-length-of-a-message-field-specific-to-the-encryption-type"]], "krb5_c_crypto_length_iov - Fill in lengths for header, trailer and padding in a IOV array.": [[98, "krb5-c-crypto-length-iov-fill-in-lengths-for-header-trailer-and-padding-in-a-iov-array"]], "krb5_c_decrypt - Decrypt data using a key (operates on keyblock).": [[99, "krb5-c-decrypt-decrypt-data-using-a-key-operates-on-keyblock"]], "krb5_c_decrypt_iov - Decrypt data in place supporting AEAD (operates on keyblock).": [[100, "krb5-c-decrypt-iov-decrypt-data-in-place-supporting-aead-operates-on-keyblock"]], "krb5_c_derive_prfplus - Derive a key using some input data (via RFC 6113 PRF+).": [[101, "krb5-c-derive-prfplus-derive-a-key-using-some-input-data-via-rfc-6113-prf"]], "krb5_c_encrypt - Encrypt data using a key (operates on keyblock).": [[102, "krb5-c-encrypt-encrypt-data-using-a-key-operates-on-keyblock"]], "krb5_c_encrypt_iov - Encrypt data in place supporting AEAD (operates on keyblock).": [[103, "krb5-c-encrypt-iov-encrypt-data-in-place-supporting-aead-operates-on-keyblock"]], "krb5_c_encrypt_length - Compute encrypted data length.": [[104, "krb5-c-encrypt-length-compute-encrypted-data-length"]], "krb5_c_enctype_compare - Compare two encryption types.": [[105, "krb5-c-enctype-compare-compare-two-encryption-types"]], "krb5_c_free_state - Free a cipher state previously allocated by krb5_c_init_state().": [[106, "krb5-c-free-state-free-a-cipher-state-previously-allocated-by-krb5-c-init-state"]], "krb5_c_fx_cf2_simple - Compute the KRB-FX-CF2 combination of two keys and pepper strings.": [[107, "krb5-c-fx-cf2-simple-compute-the-krb-fx-cf2-combination-of-two-keys-and-pepper-strings"]], "krb5_c_init_state - Initialize a new cipher state.": [[108, "krb5-c-init-state-initialize-a-new-cipher-state"]], "krb5_c_is_coll_proof_cksum - Test whether a checksum type is collision-proof.": [[109, "krb5-c-is-coll-proof-cksum-test-whether-a-checksum-type-is-collision-proof"]], "krb5_c_is_keyed_cksum - Test whether a checksum type is keyed.": [[110, "krb5-c-is-keyed-cksum-test-whether-a-checksum-type-is-keyed"]], "krb5_c_keyed_checksum_types - Return a list of keyed checksum types usable with an encryption type.": [[111, "krb5-c-keyed-checksum-types-return-a-list-of-keyed-checksum-types-usable-with-an-encryption-type"]], "krb5_c_keylengths - Return length of the specified key in bytes.": [[112, "krb5-c-keylengths-return-length-of-the-specified-key-in-bytes"]], "krb5_c_make_checksum - Compute a checksum (operates on keyblock).": [[113, "krb5-c-make-checksum-compute-a-checksum-operates-on-keyblock"]], "krb5_c_make_checksum_iov - Fill in a checksum element in IOV array (operates on keyblock)": [[114, "krb5-c-make-checksum-iov-fill-in-a-checksum-element-in-iov-array-operates-on-keyblock"]], "krb5_c_make_random_key - Generate an enctype-specific random encryption key.": [[115, "krb5-c-make-random-key-generate-an-enctype-specific-random-encryption-key"]], "krb5_c_padding_length - Return a number of padding octets.": [[116, "krb5-c-padding-length-return-a-number-of-padding-octets"]], "krb5_c_prf - Generate enctype-specific pseudo-random bytes.": [[117, "krb5-c-prf-generate-enctype-specific-pseudo-random-bytes"]], "krb5_c_prf_length - Get the output length of pseudo-random functions for an encryption type.": [[118, "krb5-c-prf-length-get-the-output-length-of-pseudo-random-functions-for-an-encryption-type"]], "krb5_c_prfplus - Generate pseudo-random bytes using RFC 6113 PRF+.": [[119, "krb5-c-prfplus-generate-pseudo-random-bytes-using-rfc-6113-prf"]], "krb5_c_random_add_entropy": [[120, "krb5-c-random-add-entropy"]], "krb5_c_random_make_octets - Generate pseudo-random bytes.": [[121, "krb5-c-random-make-octets-generate-pseudo-random-bytes"]], "krb5_c_random_os_entropy": [[122, "krb5-c-random-os-entropy"]], "krb5_c_random_seed": [[123, "krb5-c-random-seed"]], "krb5_c_random_to_key - Generate an enctype-specific key from random data.": [[124, "krb5-c-random-to-key-generate-an-enctype-specific-key-from-random-data"]], "krb5_c_string_to_key - Convert a string (such a password) to a key.": [[125, "krb5-c-string-to-key-convert-a-string-such-a-password-to-a-key"]], "krb5_c_string_to_key_with_params - Convert a string (such as a password) to a key with additional parameters.": [[126, "krb5-c-string-to-key-with-params-convert-a-string-such-as-a-password-to-a-key-with-additional-parameters"]], "krb5_c_valid_cksumtype - Verify that specified checksum type is a valid Kerberos checksum type.": [[127, "krb5-c-valid-cksumtype-verify-that-specified-checksum-type-is-a-valid-kerberos-checksum-type"]], "krb5_c_valid_enctype - Verify that a specified encryption type is a valid Kerberos encryption type.": [[128, "krb5-c-valid-enctype-verify-that-a-specified-encryption-type-is-a-valid-kerberos-encryption-type"]], "krb5_c_verify_checksum - Verify a checksum (operates on keyblock).": [[129, "krb5-c-verify-checksum-verify-a-checksum-operates-on-keyblock"]], "krb5_c_verify_checksum_iov - Validate a checksum element in IOV array (operates on keyblock).": [[130, "krb5-c-verify-checksum-iov-validate-a-checksum-element-in-iov-array-operates-on-keyblock"]], "krb5_calculate_checksum": [[131, "krb5-calculate-checksum"]], "krb5_cc_cache_match - Find a credential cache with a specified client principal.": [[132, "krb5-cc-cache-match-find-a-credential-cache-with-a-specified-client-principal"]], "krb5_cc_close - Close a credential cache handle.": [[133, "krb5-cc-close-close-a-credential-cache-handle"]], "krb5_cc_copy_creds - Copy a credential cache.": [[134, "krb5-cc-copy-creds-copy-a-credential-cache"]], "krb5_cc_default - Resolve the default credential cache name.": [[135, "krb5-cc-default-resolve-the-default-credential-cache-name"]], "krb5_cc_default_name - Return the name of the default credential cache.": [[136, "krb5-cc-default-name-return-the-name-of-the-default-credential-cache"]], "krb5_cc_destroy - Destroy a credential cache.": [[137, "krb5-cc-destroy-destroy-a-credential-cache"]], "krb5_cc_dup - Duplicate ccache handle.": [[138, "krb5-cc-dup-duplicate-ccache-handle"]], "krb5_cc_end_seq_get - Finish a series of sequential processing credential cache entries.": [[139, "krb5-cc-end-seq-get-finish-a-series-of-sequential-processing-credential-cache-entries"]], "krb5_cc_gen_new": [[140, "krb5-cc-gen-new"]], "krb5_cc_get_config - Get a configuration value from a credential cache.": [[141, "krb5-cc-get-config-get-a-configuration-value-from-a-credential-cache"]], "krb5_cc_get_flags - Retrieve flags from a credential cache structure.": [[142, "krb5-cc-get-flags-retrieve-flags-from-a-credential-cache-structure"]], "krb5_cc_get_full_name - Retrieve the full name of a credential cache.": [[143, "krb5-cc-get-full-name-retrieve-the-full-name-of-a-credential-cache"]], "krb5_cc_get_name - Retrieve the name, but not type of a credential cache.": [[144, "krb5-cc-get-name-retrieve-the-name-but-not-type-of-a-credential-cache"]], "krb5_cc_get_principal - Get the default principal of a credential cache.": [[145, "krb5-cc-get-principal-get-the-default-principal-of-a-credential-cache"]], "krb5_cc_get_type - Retrieve the type of a credential cache.": [[146, "krb5-cc-get-type-retrieve-the-type-of-a-credential-cache"]], "krb5_cc_initialize - Initialize a credential cache.": [[147, "krb5-cc-initialize-initialize-a-credential-cache"]], "krb5_cc_move - Move a credential cache.": [[148, "krb5-cc-move-move-a-credential-cache"]], "krb5_cc_new_unique - Create a new credential cache of the specified type with a unique name.": [[149, "krb5-cc-new-unique-create-a-new-credential-cache-of-the-specified-type-with-a-unique-name"]], "krb5_cc_next_cred - Retrieve the next entry from the credential cache.": [[150, "krb5-cc-next-cred-retrieve-the-next-entry-from-the-credential-cache"]], "krb5_cc_remove_cred - Remove credentials from a credential cache.": [[151, "krb5-cc-remove-cred-remove-credentials-from-a-credential-cache"]], "krb5_cc_resolve - Resolve a credential cache name.": [[152, "krb5-cc-resolve-resolve-a-credential-cache-name"]], "krb5_cc_retrieve_cred - Retrieve a specified credentials from a credential cache.": [[153, "krb5-cc-retrieve-cred-retrieve-a-specified-credentials-from-a-credential-cache"]], "krb5_cc_select - Select a credential cache to use with a server principal.": [[154, "krb5-cc-select-select-a-credential-cache-to-use-with-a-server-principal"]], "krb5_cc_set_config - Store a configuration value in a credential cache.": [[155, "krb5-cc-set-config-store-a-configuration-value-in-a-credential-cache"]], "krb5_cc_set_default_name - Set the default credential cache name.": [[156, "krb5-cc-set-default-name-set-the-default-credential-cache-name"]], "krb5_cc_set_flags - Set options flags on a credential cache.": [[157, "krb5-cc-set-flags-set-options-flags-on-a-credential-cache"]], "krb5_cc_start_seq_get - Prepare to sequentially read every credential in a credential cache.": [[158, "krb5-cc-start-seq-get-prepare-to-sequentially-read-every-credential-in-a-credential-cache"]], "krb5_cc_store_cred - Store credentials in a credential cache.": [[159, "krb5-cc-store-cred-store-credentials-in-a-credential-cache"]], "krb5_cc_support_switch - Determine whether a credential cache type supports switching.": [[160, "krb5-cc-support-switch-determine-whether-a-credential-cache-type-supports-switching"]], "krb5_cc_switch - Make a credential cache the primary cache for its collection.": [[161, "krb5-cc-switch-make-a-credential-cache-the-primary-cache-for-its-collection"]], "krb5_cccol_cursor_free - Free a credential cache collection cursor.": [[162, "krb5-cccol-cursor-free-free-a-credential-cache-collection-cursor"]], "krb5_cccol_cursor_new - Prepare to iterate over the collection of known credential caches.": [[163, "krb5-cccol-cursor-new-prepare-to-iterate-over-the-collection-of-known-credential-caches"]], "krb5_cccol_cursor_next - Get the next credential cache in the collection.": [[164, "krb5-cccol-cursor-next-get-the-next-credential-cache-in-the-collection"]], "krb5_cccol_have_content - Check if the credential cache collection contains any initialized caches.": [[165, "krb5-cccol-have-content-check-if-the-credential-cache-collection-contains-any-initialized-caches"]], "krb5_change_password - Change a password for an existing Kerberos account.": [[166, "krb5-change-password-change-a-password-for-an-existing-kerberos-account"]], "krb5_check_clockskew - Check if a timestamp is within the allowed clock skew of the current time.": [[167, "krb5-check-clockskew-check-if-a-timestamp-is-within-the-allowed-clock-skew-of-the-current-time"]], "krb5_checksum_size": [[168, "krb5-checksum-size"]], "krb5_chpw_message - Get a result message for changing or setting a password.": [[169, "krb5-chpw-message-get-a-result-message-for-changing-or-setting-a-password"]], "krb5_cksumtype_to_string - Convert a checksum type to a string.": [[170, "krb5-cksumtype-to-string-convert-a-checksum-type-to-a-string"]], "krb5_clear_error_message - Clear the extended error message in a context.": [[171, "krb5-clear-error-message-clear-the-extended-error-message-in-a-context"]], "krb5_copy_addresses - Copy an array of addresses.": [[172, "krb5-copy-addresses-copy-an-array-of-addresses"]], "krb5_copy_authdata - Copy an authorization data list.": [[173, "krb5-copy-authdata-copy-an-authorization-data-list"]], "krb5_copy_authenticator - Copy a krb5_authenticator structure.": [[174, "krb5-copy-authenticator-copy-a-krb5-authenticator-structure"]], "krb5_copy_checksum - Copy a krb5_checksum structure.": [[175, "krb5-copy-checksum-copy-a-krb5-checksum-structure"]], "krb5_copy_context - Copy a krb5_context structure.": [[176, "krb5-copy-context-copy-a-krb5-context-structure"]], "krb5_copy_creds - Copy a krb5_creds structure.": [[177, "krb5-copy-creds-copy-a-krb5-creds-structure"]], "krb5_copy_data - Copy a krb5_data object.": [[178, "krb5-copy-data-copy-a-krb5-data-object"]], "krb5_copy_error_message - Copy the most recent extended error message from one context to another.": [[179, "krb5-copy-error-message-copy-the-most-recent-extended-error-message-from-one-context-to-another"]], "krb5_copy_keyblock - Copy a keyblock.": [[180, "krb5-copy-keyblock-copy-a-keyblock"]], "krb5_copy_keyblock_contents - Copy the contents of a keyblock.": [[181, "krb5-copy-keyblock-contents-copy-the-contents-of-a-keyblock"]], "krb5_copy_principal - Copy a principal.": [[182, "krb5-copy-principal-copy-a-principal"]], "krb5_copy_ticket - Copy a krb5_ticket structure.": [[183, "krb5-copy-ticket-copy-a-krb5-ticket-structure"]], "krb5_decode_authdata_container - Unwrap authorization data.": [[184, "krb5-decode-authdata-container-unwrap-authorization-data"]], "krb5_decode_ticket - Decode an ASN.1-formatted ticket.": [[185, "krb5-decode-ticket-decode-an-asn-1-formatted-ticket"]], "krb5_decrypt": [[186, "krb5-decrypt"]], "krb5_deltat_to_string - Convert a relative time value to a string.": [[187, "krb5-deltat-to-string-convert-a-relative-time-value-to-a-string"]], "krb5_eblock_enctype": [[188, "krb5-eblock-enctype"]], "krb5_encode_authdata_container - Wrap authorization data in a container.": [[189, "krb5-encode-authdata-container-wrap-authorization-data-in-a-container"]], "krb5_encrypt": [[190, "krb5-encrypt"]], "krb5_encrypt_size": [[191, "krb5-encrypt-size"]], "krb5_enctype_to_name - Convert an encryption type to a name or alias.": [[192, "krb5-enctype-to-name-convert-an-encryption-type-to-a-name-or-alias"]], "krb5_enctype_to_string - Convert an encryption type to a string.": [[193, "krb5-enctype-to-string-convert-an-encryption-type-to-a-string"]], "krb5_expand_hostname - Canonicalize a hostname, possibly using name service.": [[194, "krb5-expand-hostname-canonicalize-a-hostname-possibly-using-name-service"]], "krb5_find_authdata - Find authorization data elements.": [[195, "krb5-find-authdata-find-authorization-data-elements"]], "krb5_finish_key": [[196, "krb5-finish-key"]], "krb5_finish_random_key": [[197, "krb5-finish-random-key"]], "krb5_free_addresses - Free the data stored in array of addresses.": [[198, "krb5-free-addresses-free-the-data-stored-in-array-of-addresses"]], "krb5_free_ap_rep_enc_part - Free a krb5_ap_rep_enc_part structure.": [[199, "krb5-free-ap-rep-enc-part-free-a-krb5-ap-rep-enc-part-structure"]], "krb5_free_authdata - Free the storage assigned to array of authentication data.": [[200, "krb5-free-authdata-free-the-storage-assigned-to-array-of-authentication-data"]], "krb5_free_authenticator - Free a krb5_authenticator structure.": [[201, "krb5-free-authenticator-free-a-krb5-authenticator-structure"]], "krb5_free_checksum - Free a krb5_checksum structure.": [[202, "krb5-free-checksum-free-a-krb5-checksum-structure"]], "krb5_free_checksum_contents - Free the contents of a krb5_checksum structure.": [[203, "krb5-free-checksum-contents-free-the-contents-of-a-krb5-checksum-structure"]], "krb5_free_cksumtypes - Free an array of checksum types.": [[204, "krb5-free-cksumtypes-free-an-array-of-checksum-types"]], "krb5_free_config_files - Free a list allocated by krb5_get_default_config_files()": [[205, "krb5-free-config-files-free-a-list-allocated-by-krb5-get-default-config-files"]], "krb5_free_context - Free a krb5 library context.": [[206, "krb5-free-context-free-a-krb5-library-context"]], "krb5_free_cred_contents - Free the contents of a krb5_creds structure.": [[207, "krb5-free-cred-contents-free-the-contents-of-a-krb5-creds-structure"]], "krb5_free_creds - Free a krb5_creds structure.": [[208, "krb5-free-creds-free-a-krb5-creds-structure"]], "krb5_free_data - Free a krb5_data structure.": [[209, "krb5-free-data-free-a-krb5-data-structure"]], "krb5_free_data_contents - Free the contents of a krb5_data structure and zero the data field.": [[210, "krb5-free-data-contents-free-the-contents-of-a-krb5-data-structure-and-zero-the-data-field"]], "krb5_free_default_realm - Free a default realm string returned by krb5_get_default_realm().": [[211, "krb5-free-default-realm-free-a-default-realm-string-returned-by-krb5-get-default-realm"]], "krb5_free_enctypes - Free an array of encryption types.": [[212, "krb5-free-enctypes-free-an-array-of-encryption-types"]], "krb5_free_error - Free an error allocated by krb5_read_error() or krb5_sendauth().": [[213, "krb5-free-error-free-an-error-allocated-by-krb5-read-error-or-krb5-sendauth"]], "krb5_free_error_message - Free an error message generated by krb5_get_error_message().": [[214, "krb5-free-error-message-free-an-error-message-generated-by-krb5-get-error-message"]], "krb5_free_host_realm - Free the memory allocated by krb5_get_host_realm().": [[215, "krb5-free-host-realm-free-the-memory-allocated-by-krb5-get-host-realm"]], "krb5_free_keyblock - Free a krb5_keyblock structure.": [[216, "krb5-free-keyblock-free-a-krb5-keyblock-structure"]], "krb5_free_keyblock_contents - Free the contents of a krb5_keyblock structure.": [[217, "krb5-free-keyblock-contents-free-the-contents-of-a-krb5-keyblock-structure"]], "krb5_free_keytab_entry_contents - Free the contents of a key table entry.": [[218, "krb5-free-keytab-entry-contents-free-the-contents-of-a-key-table-entry"]], "krb5_free_principal - Free the storage assigned to a principal.": [[219, "krb5-free-principal-free-the-storage-assigned-to-a-principal"]], "krb5_free_string - Free a string allocated by a krb5 function.": [[220, "krb5-free-string-free-a-string-allocated-by-a-krb5-function"]], "krb5_free_tgt_creds - Free an array of credential structures.": [[221, "krb5-free-tgt-creds-free-an-array-of-credential-structures"]], "krb5_free_ticket - Free a ticket.": [[222, "krb5-free-ticket-free-a-ticket"]], "krb5_free_unparsed_name - Free a string representation of a principal.": [[223, "krb5-free-unparsed-name-free-a-string-representation-of-a-principal"]], "krb5_fwd_tgt_creds - Get a forwarded TGT and format a KRB-CRED message.": [[224, "krb5-fwd-tgt-creds-get-a-forwarded-tgt-and-format-a-krb-cred-message"]], "krb5_get_credentials - Get an additional ticket.": [[225, "krb5-get-credentials-get-an-additional-ticket"]], "krb5_get_credentials_renew": [[226, "krb5-get-credentials-renew"]], "krb5_get_credentials_validate": [[227, "krb5-get-credentials-validate"]], "krb5_get_default_config_files - Return a list of default configuration filenames.": [[228, "krb5-get-default-config-files-return-a-list-of-default-configuration-filenames"]], "krb5_get_default_realm - Retrieve the default realm.": [[229, "krb5-get-default-realm-retrieve-the-default-realm"]], "krb5_get_error_message - Get the (possibly extended) error message for a code.": [[230, "krb5-get-error-message-get-the-possibly-extended-error-message-for-a-code"]], "krb5_get_etype_info - Retrieve enctype, salt and s2kparams from KDC.": [[231, "krb5-get-etype-info-retrieve-enctype-salt-and-s2kparams-from-kdc"]], "krb5_get_fallback_host_realm": [[232, "krb5-get-fallback-host-realm"]], "krb5_get_host_realm - Get the Kerberos realm names for a host.": [[233, "krb5-get-host-realm-get-the-kerberos-realm-names-for-a-host"]], "krb5_get_in_tkt_with_keytab": [[234, "krb5-get-in-tkt-with-keytab"]], "krb5_get_in_tkt_with_password": [[235, "krb5-get-in-tkt-with-password"]], "krb5_get_in_tkt_with_skey": [[236, "krb5-get-in-tkt-with-skey"]], "krb5_get_init_creds_keytab - Get initial credentials using a key table.": [[237, "krb5-get-init-creds-keytab-get-initial-credentials-using-a-key-table"]], "krb5_get_init_creds_opt_alloc - Allocate a new initial credential options structure.": [[238, "krb5-get-init-creds-opt-alloc-allocate-a-new-initial-credential-options-structure"]], "krb5_get_init_creds_opt_free - Free initial credential options.": [[239, "krb5-get-init-creds-opt-free-free-initial-credential-options"]], "krb5_get_init_creds_opt_get_fast_flags - Retrieve FAST flags from initial credential options.": [[240, "krb5-get-init-creds-opt-get-fast-flags-retrieve-fast-flags-from-initial-credential-options"]], "krb5_get_init_creds_opt_init": [[241, "krb5-get-init-creds-opt-init"]], "krb5_get_init_creds_opt_set_address_list - Set address restrictions in initial credential options.": [[242, "krb5-get-init-creds-opt-set-address-list-set-address-restrictions-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_anonymous - Set or unset the anonymous flag in initial credential options.": [[243, "krb5-get-init-creds-opt-set-anonymous-set-or-unset-the-anonymous-flag-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_canonicalize - Set or unset the canonicalize flag in initial credential options.": [[244, "krb5-get-init-creds-opt-set-canonicalize-set-or-unset-the-canonicalize-flag-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_change_password_prompt - Set or unset change-password-prompt flag in initial credential options.": [[245, "krb5-get-init-creds-opt-set-change-password-prompt-set-or-unset-change-password-prompt-flag-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_etype_list - Set allowable encryption types in initial credential options.": [[246, "krb5-get-init-creds-opt-set-etype-list-set-allowable-encryption-types-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_expire_callback - Set an expiration callback in initial credential options.": [[247, "krb5-get-init-creds-opt-set-expire-callback-set-an-expiration-callback-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_fast_ccache - Set FAST armor cache in initial credential options.": [[248, "krb5-get-init-creds-opt-set-fast-ccache-set-fast-armor-cache-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_fast_ccache_name - Set location of FAST armor ccache in initial credential options.": [[249, "krb5-get-init-creds-opt-set-fast-ccache-name-set-location-of-fast-armor-ccache-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_fast_flags - Set FAST flags in initial credential options.": [[250, "krb5-get-init-creds-opt-set-fast-flags-set-fast-flags-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_forwardable - Set or unset the forwardable flag in initial credential options.": [[251, "krb5-get-init-creds-opt-set-forwardable-set-or-unset-the-forwardable-flag-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_in_ccache - Set an input credential cache in initial credential options.": [[252, "krb5-get-init-creds-opt-set-in-ccache-set-an-input-credential-cache-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_out_ccache - Set an output credential cache in initial credential options.": [[253, "krb5-get-init-creds-opt-set-out-ccache-set-an-output-credential-cache-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_pa - Supply options for preauthentication in initial credential options.": [[254, "krb5-get-init-creds-opt-set-pa-supply-options-for-preauthentication-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_pac_request - Ask the KDC to include or not include a PAC in the ticket.": [[255, "krb5-get-init-creds-opt-set-pac-request-ask-the-kdc-to-include-or-not-include-a-pac-in-the-ticket"]], "krb5_get_init_creds_opt_set_preauth_list - Set preauthentication types in initial credential options.": [[256, "krb5-get-init-creds-opt-set-preauth-list-set-preauthentication-types-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_proxiable - Set or unset the proxiable flag in initial credential options.": [[257, "krb5-get-init-creds-opt-set-proxiable-set-or-unset-the-proxiable-flag-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_renew_life - Set the ticket renewal lifetime in initial credential options.": [[258, "krb5-get-init-creds-opt-set-renew-life-set-the-ticket-renewal-lifetime-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_responder - Set the responder function in initial credential options.": [[259, "krb5-get-init-creds-opt-set-responder-set-the-responder-function-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_salt - Set salt for optimistic preauthentication in initial credential options.": [[260, "krb5-get-init-creds-opt-set-salt-set-salt-for-optimistic-preauthentication-in-initial-credential-options"]], "krb5_get_init_creds_opt_set_tkt_life - Set the ticket lifetime in initial credential options.": [[261, "krb5-get-init-creds-opt-set-tkt-life-set-the-ticket-lifetime-in-initial-credential-options"]], "krb5_get_init_creds_password - Get initial credentials using a password.": [[262, "krb5-get-init-creds-password-get-initial-credentials-using-a-password"]], "krb5_get_permitted_enctypes - Return a list of encryption types permitted for session keys.": [[263, "krb5-get-permitted-enctypes-return-a-list-of-encryption-types-permitted-for-session-keys"]], "krb5_get_profile - Retrieve configuration profile from the context.": [[264, "krb5-get-profile-retrieve-configuration-profile-from-the-context"]], "krb5_get_prompt_types - Get prompt types array from a context.": [[265, "krb5-get-prompt-types-get-prompt-types-array-from-a-context"]], "krb5_get_renewed_creds - Get renewed credential from KDC using an existing credential.": [[266, "krb5-get-renewed-creds-get-renewed-credential-from-kdc-using-an-existing-credential"]], "krb5_get_server_rcache - Generate a replay cache object for server use and open it.": [[267, "krb5-get-server-rcache-generate-a-replay-cache-object-for-server-use-and-open-it"]], "krb5_get_time_offsets - Return the time offsets from the os context.": [[268, "krb5-get-time-offsets-return-the-time-offsets-from-the-os-context"]], "krb5_get_validated_creds - Get validated credentials from the KDC.": [[269, "krb5-get-validated-creds-get-validated-credentials-from-the-kdc"]], "krb5_init_context - Create a krb5 library context.": [[270, "krb5-init-context-create-a-krb5-library-context"]], "krb5_init_context_profile - Create a krb5 library context using a specified profile.": [[271, "krb5-init-context-profile-create-a-krb5-library-context-using-a-specified-profile"]], "krb5_init_creds_free - Free an initial credentials context.": [[272, "krb5-init-creds-free-free-an-initial-credentials-context"]], "krb5_init_creds_get - Acquire credentials using an initial credentials context.": [[273, "krb5-init-creds-get-acquire-credentials-using-an-initial-credentials-context"]], "krb5_init_creds_get_creds - Retrieve acquired credentials from an initial credentials context.": [[274, "krb5-init-creds-get-creds-retrieve-acquired-credentials-from-an-initial-credentials-context"]], "krb5_init_creds_get_error - Get the last error from KDC from an initial credentials context.": [[275, "krb5-init-creds-get-error-get-the-last-error-from-kdc-from-an-initial-credentials-context"]], "krb5_init_creds_get_times - Retrieve ticket times from an initial credentials context.": [[276, "krb5-init-creds-get-times-retrieve-ticket-times-from-an-initial-credentials-context"]], "krb5_init_creds_init - Create a context for acquiring initial credentials.": [[277, "krb5-init-creds-init-create-a-context-for-acquiring-initial-credentials"]], "krb5_init_creds_set_keytab - Specify a keytab to use for acquiring initial credentials.": [[278, "krb5-init-creds-set-keytab-specify-a-keytab-to-use-for-acquiring-initial-credentials"]], "krb5_init_creds_set_password - Set a password for acquiring initial credentials.": [[279, "krb5-init-creds-set-password-set-a-password-for-acquiring-initial-credentials"]], "krb5_init_creds_set_service - Specify a service principal for acquiring initial credentials.": [[280, "krb5-init-creds-set-service-specify-a-service-principal-for-acquiring-initial-credentials"]], "krb5_init_creds_step - Get the next KDC request for acquiring initial credentials.": [[281, "krb5-init-creds-step-get-the-next-kdc-request-for-acquiring-initial-credentials"]], "krb5_init_keyblock - Initialize an empty krb5_keyblock .": [[282, "krb5-init-keyblock-initialize-an-empty-krb5-keyblock"]], "krb5_init_random_key": [[283, "krb5-init-random-key"]], "krb5_init_secure_context - Create a krb5 library context using only configuration files.": [[284, "krb5-init-secure-context-create-a-krb5-library-context-using-only-configuration-files"]], "krb5_is_config_principal - Test whether a principal is a configuration principal.": [[285, "krb5-is-config-principal-test-whether-a-principal-is-a-configuration-principal"]], "krb5_is_referral_realm - Check for a match with KRB5_REFERRAL_REALM.": [[286, "krb5-is-referral-realm-check-for-a-match-with-krb5-referral-realm"]], "krb5_is_thread_safe - Test whether the Kerberos library was built with multithread support.": [[287, "krb5-is-thread-safe-test-whether-the-kerberos-library-was-built-with-multithread-support"]], "krb5_k_create_key - Create a krb5_key from the enctype and key data in a keyblock.": [[288, "krb5-k-create-key-create-a-krb5-key-from-the-enctype-and-key-data-in-a-keyblock"]], "krb5_k_decrypt - Decrypt data using a key (operates on opaque key).": [[289, "krb5-k-decrypt-decrypt-data-using-a-key-operates-on-opaque-key"]], "krb5_k_decrypt_iov - Decrypt data in place supporting AEAD (operates on opaque key).": [[290, "krb5-k-decrypt-iov-decrypt-data-in-place-supporting-aead-operates-on-opaque-key"]], "krb5_k_encrypt - Encrypt data using a key (operates on opaque key).": [[291, "krb5-k-encrypt-encrypt-data-using-a-key-operates-on-opaque-key"]], "krb5_k_encrypt_iov - Encrypt data in place supporting AEAD (operates on opaque key).": [[292, "krb5-k-encrypt-iov-encrypt-data-in-place-supporting-aead-operates-on-opaque-key"]], "krb5_k_free_key - Decrement the reference count on a key and free it if it hits zero.": [[293, "krb5-k-free-key-decrement-the-reference-count-on-a-key-and-free-it-if-it-hits-zero"]], "krb5_k_key_enctype - Retrieve the enctype of a krb5_key structure.": [[294, "krb5-k-key-enctype-retrieve-the-enctype-of-a-krb5-key-structure"]], "krb5_k_key_keyblock - Retrieve a copy of the keyblock from a krb5_key structure.": [[295, "krb5-k-key-keyblock-retrieve-a-copy-of-the-keyblock-from-a-krb5-key-structure"]], "krb5_k_make_checksum - Compute a checksum (operates on opaque key).": [[296, "krb5-k-make-checksum-compute-a-checksum-operates-on-opaque-key"]], "krb5_k_make_checksum_iov - Fill in a checksum element in IOV array (operates on opaque key)": [[297, "krb5-k-make-checksum-iov-fill-in-a-checksum-element-in-iov-array-operates-on-opaque-key"]], "krb5_k_prf - Generate enctype-specific pseudo-random bytes (operates on opaque key).": [[298, "krb5-k-prf-generate-enctype-specific-pseudo-random-bytes-operates-on-opaque-key"]], "krb5_k_reference_key - Increment the reference count on a key.": [[299, "krb5-k-reference-key-increment-the-reference-count-on-a-key"]], "krb5_k_verify_checksum - Verify a checksum (operates on opaque key).": [[300, "krb5-k-verify-checksum-verify-a-checksum-operates-on-opaque-key"]], "krb5_k_verify_checksum_iov - Validate a checksum element in IOV array (operates on opaque key).": [[301, "krb5-k-verify-checksum-iov-validate-a-checksum-element-in-iov-array-operates-on-opaque-key"]], "krb5_kdc_sign_ticket - Sign a PAC, possibly including a ticket signature.": [[302, "krb5-kdc-sign-ticket-sign-a-pac-possibly-including-a-ticket-signature"]], "krb5_kdc_verify_ticket - Verify a PAC, possibly including ticket signature.": [[303, "krb5-kdc-verify-ticket-verify-a-pac-possibly-including-ticket-signature"]], "krb5_kt_add_entry - Add a new entry to a key table.": [[304, "krb5-kt-add-entry-add-a-new-entry-to-a-key-table"]], "krb5_kt_client_default - Resolve the default client key table.": [[305, "krb5-kt-client-default-resolve-the-default-client-key-table"]], "krb5_kt_close - Close a key table handle.": [[306, "krb5-kt-close-close-a-key-table-handle"]], "krb5_kt_default - Resolve the default key table.": [[307, "krb5-kt-default-resolve-the-default-key-table"]], "krb5_kt_default_name - Get the default key table name.": [[308, "krb5-kt-default-name-get-the-default-key-table-name"]], "krb5_kt_dup - Duplicate keytab handle.": [[309, "krb5-kt-dup-duplicate-keytab-handle"]], "krb5_kt_end_seq_get - Release a keytab cursor.": [[310, "krb5-kt-end-seq-get-release-a-keytab-cursor"]], "krb5_kt_free_entry": [[311, "krb5-kt-free-entry"]], "krb5_kt_get_entry - Get an entry from a key table.": [[312, "krb5-kt-get-entry-get-an-entry-from-a-key-table"]], "krb5_kt_get_name - Get a key table name.": [[313, "krb5-kt-get-name-get-a-key-table-name"]], "krb5_kt_get_type - Return the type of a key table.": [[314, "krb5-kt-get-type-return-the-type-of-a-key-table"]], "krb5_kt_have_content - Check if a keytab exists and contains entries.": [[315, "krb5-kt-have-content-check-if-a-keytab-exists-and-contains-entries"]], "krb5_kt_next_entry - Retrieve the next entry from the key table.": [[316, "krb5-kt-next-entry-retrieve-the-next-entry-from-the-key-table"]], "krb5_kt_read_service_key - Retrieve a service key from a key table.": [[317, "krb5-kt-read-service-key-retrieve-a-service-key-from-a-key-table"]], "krb5_kt_remove_entry - Remove an entry from a key table.": [[318, "krb5-kt-remove-entry-remove-an-entry-from-a-key-table"]], "krb5_kt_resolve - Get a handle for a key table.": [[319, "krb5-kt-resolve-get-a-handle-for-a-key-table"]], "krb5_kt_start_seq_get - Start a sequential retrieval of key table entries.": [[320, "krb5-kt-start-seq-get-start-a-sequential-retrieval-of-key-table-entries"]], "krb5_kuserok - Determine if a principal is authorized to log in as a local user.": [[321, "krb5-kuserok-determine-if-a-principal-is-authorized-to-log-in-as-a-local-user"]], "krb5_make_authdata_kdc_issued - Encode and sign AD-KDCIssued authorization data.": [[322, "krb5-make-authdata-kdc-issued-encode-and-sign-ad-kdcissued-authorization-data"]], "krb5_marshal_credentials - Serialize a krb5_creds object.": [[323, "krb5-marshal-credentials-serialize-a-krb5-creds-object"]], "krb5_merge_authdata - Merge two authorization data lists into a new list.": [[324, "krb5-merge-authdata-merge-two-authorization-data-lists-into-a-new-list"]], "krb5_mk_1cred - Format a KRB-CRED message for a single set of credentials.": [[325, "krb5-mk-1cred-format-a-krb-cred-message-for-a-single-set-of-credentials"]], "krb5_mk_error - Format and encode a KRB_ERROR message.": [[326, "krb5-mk-error-format-and-encode-a-krb-error-message"]], "krb5_mk_ncred - Format a KRB-CRED message for an array of credentials.": [[327, "krb5-mk-ncred-format-a-krb-cred-message-for-an-array-of-credentials"]], "krb5_mk_priv - Format a KRB-PRIV message.": [[328, "krb5-mk-priv-format-a-krb-priv-message"]], "krb5_mk_rep - Format and encrypt a KRB_AP_REP message.": [[329, "krb5-mk-rep-format-and-encrypt-a-krb-ap-rep-message"]], "krb5_mk_rep_dce - Format and encrypt a KRB_AP_REP message for DCE RPC.": [[330, "krb5-mk-rep-dce-format-and-encrypt-a-krb-ap-rep-message-for-dce-rpc"]], "krb5_mk_req - Create a KRB_AP_REQ message.": [[331, "krb5-mk-req-create-a-krb-ap-req-message"]], "krb5_mk_req_extended - Create a KRB_AP_REQ message using supplied credentials.": [[332, "krb5-mk-req-extended-create-a-krb-ap-req-message-using-supplied-credentials"]], "krb5_mk_safe - Format a KRB-SAFE message.": [[333, "krb5-mk-safe-format-a-krb-safe-message"]], "krb5_os_localaddr - Return all interface addresses for this host.": [[334, "krb5-os-localaddr-return-all-interface-addresses-for-this-host"]], "krb5_pac_add_buffer - Add a buffer to a PAC handle.": [[335, "krb5-pac-add-buffer-add-a-buffer-to-a-pac-handle"]], "krb5_pac_free - Free a PAC handle.": [[336, "krb5-pac-free-free-a-pac-handle"]], "krb5_pac_get_buffer - Retrieve a buffer value from a PAC.": [[337, "krb5-pac-get-buffer-retrieve-a-buffer-value-from-a-pac"]], "krb5_pac_get_client_info - Read client information from a PAC.": [[338, "krb5-pac-get-client-info-read-client-information-from-a-pac"]], "krb5_pac_get_types - Return an array of buffer types in a PAC handle.": [[339, "krb5-pac-get-types-return-an-array-of-buffer-types-in-a-pac-handle"]], "krb5_pac_init - Create an empty Privilege Attribute Certificate (PAC) handle.": [[340, "krb5-pac-init-create-an-empty-privilege-attribute-certificate-pac-handle"]], "krb5_pac_parse - Unparse an encoded PAC into a new handle.": [[341, "krb5-pac-parse-unparse-an-encoded-pac-into-a-new-handle"]], "krb5_pac_sign": [[342, "krb5-pac-sign"]], "krb5_pac_sign_ext": [[343, "krb5-pac-sign-ext"]], "krb5_pac_verify - Verify a PAC.": [[344, "krb5-pac-verify-verify-a-pac"]], "krb5_pac_verify_ext - Verify a PAC, possibly from a specified realm.": [[345, "krb5-pac-verify-ext-verify-a-pac-possibly-from-a-specified-realm"]], "krb5_parse_name - Convert a string principal name to a krb5_principal structure.": [[346, "krb5-parse-name-convert-a-string-principal-name-to-a-krb5-principal-structure"]], "krb5_parse_name_flags - Convert a string principal name to a krb5_principal with flags.": [[347, "krb5-parse-name-flags-convert-a-string-principal-name-to-a-krb5-principal-with-flags"]], "krb5_prepend_error_message - Add a prefix to the message for an error code.": [[348, "krb5-prepend-error-message-add-a-prefix-to-the-message-for-an-error-code"]], "krb5_principal2salt - Convert a principal name into the default salt for that principal.": [[349, "krb5-principal2salt-convert-a-principal-name-into-the-default-salt-for-that-principal"]], "krb5_principal_compare - Compare two principals.": [[350, "krb5-principal-compare-compare-two-principals"]], "krb5_principal_compare_any_realm - Compare two principals ignoring realm components.": [[351, "krb5-principal-compare-any-realm-compare-two-principals-ignoring-realm-components"]], "krb5_principal_compare_flags - Compare two principals with additional flags.": [[352, "krb5-principal-compare-flags-compare-two-principals-with-additional-flags"]], "krb5_process_key": [[353, "krb5-process-key"]], "krb5_prompter_posix - Prompt user for password.": [[354, "krb5-prompter-posix-prompt-user-for-password"]], "krb5_random_key": [[355, "krb5-random-key"]], "krb5_rd_cred - Read and validate a KRB-CRED message.": [[356, "krb5-rd-cred-read-and-validate-a-krb-cred-message"]], "krb5_rd_error - Decode a KRB-ERROR message.": [[357, "krb5-rd-error-decode-a-krb-error-message"]], "krb5_rd_priv - Process a KRB-PRIV message.": [[358, "krb5-rd-priv-process-a-krb-priv-message"]], "krb5_rd_rep - Parse and decrypt a KRB_AP_REP message.": [[359, "krb5-rd-rep-parse-and-decrypt-a-krb-ap-rep-message"]], "krb5_rd_rep_dce - Parse and decrypt a KRB_AP_REP message for DCE RPC.": [[360, "krb5-rd-rep-dce-parse-and-decrypt-a-krb-ap-rep-message-for-dce-rpc"]], "krb5_rd_req - Parse and decrypt a KRB_AP_REQ message.": [[361, "krb5-rd-req-parse-and-decrypt-a-krb-ap-req-message"]], "krb5_rd_safe - Process KRB-SAFE message.": [[362, "krb5-rd-safe-process-krb-safe-message"]], "krb5_read_password - Read a password from keyboard input.": [[363, "krb5-read-password-read-a-password-from-keyboard-input"]], "krb5_realm_compare - Compare the realms of two principals.": [[364, "krb5-realm-compare-compare-the-realms-of-two-principals"]], "krb5_recvauth - Server function for sendauth protocol.": [[365, "krb5-recvauth-server-function-for-sendauth-protocol"]], "krb5_recvauth_version - Server function for sendauth protocol with version parameter.": [[366, "krb5-recvauth-version-server-function-for-sendauth-protocol-with-version-parameter"]], "krb5_responder_get_challenge - Retrieve the challenge data for a given question in the responder context.": [[367, "krb5-responder-get-challenge-retrieve-the-challenge-data-for-a-given-question-in-the-responder-context"]], "krb5_responder_list_questions - List the question names contained in the responder context.": [[368, "krb5-responder-list-questions-list-the-question-names-contained-in-the-responder-context"]], "krb5_responder_otp_challenge_free - Free the value returned by krb5_responder_otp_get_challenge().": [[369, "krb5-responder-otp-challenge-free-free-the-value-returned-by-krb5-responder-otp-get-challenge"]], "krb5_responder_otp_get_challenge - Decode the KRB5_RESPONDER_QUESTION_OTP to a C struct.": [[370, "krb5-responder-otp-get-challenge-decode-the-krb5-responder-question-otp-to-a-c-struct"]], "krb5_responder_otp_set_answer - Answer the KRB5_RESPONDER_QUESTION_OTP question.": [[371, "krb5-responder-otp-set-answer-answer-the-krb5-responder-question-otp-question"]], "krb5_responder_pkinit_challenge_free - Free the value returned by krb5_responder_pkinit_get_challenge().": [[372, "krb5-responder-pkinit-challenge-free-free-the-value-returned-by-krb5-responder-pkinit-get-challenge"]], "krb5_responder_pkinit_get_challenge - Decode the KRB5_RESPONDER_QUESTION_PKINIT to a C struct.": [[373, "krb5-responder-pkinit-get-challenge-decode-the-krb5-responder-question-pkinit-to-a-c-struct"]], "krb5_responder_pkinit_set_answer - Answer the KRB5_RESPONDER_QUESTION_PKINIT question for one identity.": [[374, "krb5-responder-pkinit-set-answer-answer-the-krb5-responder-question-pkinit-question-for-one-identity"]], "krb5_responder_set_answer - Answer a named question in the responder context.": [[375, "krb5-responder-set-answer-answer-a-named-question-in-the-responder-context"]], "krb5_salttype_to_string - Convert a salt type to a string.": [[376, "krb5-salttype-to-string-convert-a-salt-type-to-a-string"]], "krb5_sendauth - Client function for sendauth protocol.": [[377, "krb5-sendauth-client-function-for-sendauth-protocol"]], "krb5_server_decrypt_ticket_keytab - Decrypt a ticket using the specified key table.": [[378, "krb5-server-decrypt-ticket-keytab-decrypt-a-ticket-using-the-specified-key-table"]], "krb5_set_default_realm - Override the default realm for the specified context.": [[379, "krb5-set-default-realm-override-the-default-realm-for-the-specified-context"]], "krb5_set_default_tgs_enctypes - Set default TGS encryption types in a krb5_context structure.": [[380, "krb5-set-default-tgs-enctypes-set-default-tgs-encryption-types-in-a-krb5-context-structure"]], "krb5_set_error_message - Set an extended error message for an error code.": [[381, "krb5-set-error-message-set-an-extended-error-message-for-an-error-code"]], "krb5_set_kdc_recv_hook - Set a KDC post-receive hook function.": [[382, "krb5-set-kdc-recv-hook-set-a-kdc-post-receive-hook-function"]], "krb5_set_kdc_send_hook - Set a KDC pre-send hook function.": [[383, "krb5-set-kdc-send-hook-set-a-kdc-pre-send-hook-function"]], "krb5_set_password - Set a password for a principal using specified credentials.": [[384, "krb5-set-password-set-a-password-for-a-principal-using-specified-credentials"]], "krb5_set_password_using_ccache - Set a password for a principal using cached credentials.": [[385, "krb5-set-password-using-ccache-set-a-password-for-a-principal-using-cached-credentials"]], "krb5_set_principal_realm - Set the realm field of a principal.": [[386, "krb5-set-principal-realm-set-the-realm-field-of-a-principal"]], "krb5_set_real_time - Set time offset field in a krb5_context structure.": [[387, "krb5-set-real-time-set-time-offset-field-in-a-krb5-context-structure"]], "krb5_set_trace_callback - Specify a callback function for trace events.": [[388, "krb5-set-trace-callback-specify-a-callback-function-for-trace-events"]], "krb5_set_trace_filename - Specify a file name for directing trace events.": [[389, "krb5-set-trace-filename-specify-a-file-name-for-directing-trace-events"]], "krb5_sname_match - Test whether a principal matches a matching principal.": [[390, "krb5-sname-match-test-whether-a-principal-matches-a-matching-principal"]], "krb5_sname_to_principal - Generate a full principal name from a service name.": [[391, "krb5-sname-to-principal-generate-a-full-principal-name-from-a-service-name"]], "krb5_string_to_cksumtype - Convert a string to a checksum type.": [[392, "krb5-string-to-cksumtype-convert-a-string-to-a-checksum-type"]], "krb5_string_to_deltat - Convert a string to a delta time value.": [[393, "krb5-string-to-deltat-convert-a-string-to-a-delta-time-value"]], "krb5_string_to_enctype - Convert a string to an encryption type.": [[394, "krb5-string-to-enctype-convert-a-string-to-an-encryption-type"]], "krb5_string_to_key": [[395, "krb5-string-to-key"]], "krb5_string_to_salttype - Convert a string to a salt type.": [[396, "krb5-string-to-salttype-convert-a-string-to-a-salt-type"]], "krb5_string_to_timestamp - Convert a string to a timestamp.": [[397, "krb5-string-to-timestamp-convert-a-string-to-a-timestamp"]], "krb5_timeofday - Retrieve the current time with context specific time offset adjustment.": [[398, "krb5-timeofday-retrieve-the-current-time-with-context-specific-time-offset-adjustment"]], "krb5_timestamp_to_sfstring - Convert a timestamp to a string, with optional output padding.": [[399, "krb5-timestamp-to-sfstring-convert-a-timestamp-to-a-string-with-optional-output-padding"]], "krb5_timestamp_to_string - Convert a timestamp to a string.": [[400, "krb5-timestamp-to-string-convert-a-timestamp-to-a-string"]], "krb5_tkt_creds_free - Free a TGS request context.": [[401, "krb5-tkt-creds-free-free-a-tgs-request-context"]], "krb5_tkt_creds_get - Synchronously obtain credentials using a TGS request context.": [[402, "krb5-tkt-creds-get-synchronously-obtain-credentials-using-a-tgs-request-context"]], "krb5_tkt_creds_get_creds - Retrieve acquired credentials from a TGS request context.": [[403, "krb5-tkt-creds-get-creds-retrieve-acquired-credentials-from-a-tgs-request-context"]], "krb5_tkt_creds_get_times - Retrieve ticket times from a TGS request context.": [[404, "krb5-tkt-creds-get-times-retrieve-ticket-times-from-a-tgs-request-context"]], "krb5_tkt_creds_init - Create a context to get credentials from a KDC\u2019s Ticket Granting Service.": [[405, "krb5-tkt-creds-init-create-a-context-to-get-credentials-from-a-kdc-s-ticket-granting-service"]], "krb5_tkt_creds_step - Get the next KDC request in a TGS exchange.": [[406, "krb5-tkt-creds-step-get-the-next-kdc-request-in-a-tgs-exchange"]], "krb5_unmarshal_credentials - Deserialize a krb5_creds object.": [[407, "krb5-unmarshal-credentials-deserialize-a-krb5-creds-object"]], "krb5_unparse_name - Convert a krb5_principal structure to a string representation.": [[408, "krb5-unparse-name-convert-a-krb5-principal-structure-to-a-string-representation"]], "krb5_unparse_name_ext - Convert krb5_principal structure to string and length.": [[409, "krb5-unparse-name-ext-convert-krb5-principal-structure-to-string-and-length"]], "krb5_unparse_name_flags - Convert krb5_principal structure to a string with flags.": [[410, "krb5-unparse-name-flags-convert-krb5-principal-structure-to-a-string-with-flags"]], "krb5_unparse_name_flags_ext - Convert krb5_principal structure to string format with flags.": [[411, "krb5-unparse-name-flags-ext-convert-krb5-principal-structure-to-string-format-with-flags"]], "krb5_us_timeofday - Retrieve the system time of day, in sec and ms, since the epoch.": [[412, "krb5-us-timeofday-retrieve-the-system-time-of-day-in-sec-and-ms-since-the-epoch"]], "krb5_use_enctype": [[413, "krb5-use-enctype"]], "krb5_verify_authdata_kdc_issued - Unwrap and verify AD-KDCIssued authorization data.": [[414, "krb5-verify-authdata-kdc-issued-unwrap-and-verify-ad-kdcissued-authorization-data"]], "krb5_verify_checksum": [[415, "krb5-verify-checksum"]], "krb5_verify_init_creds - Verify initial credentials against a keytab.": [[416, "krb5-verify-init-creds-verify-initial-credentials-against-a-keytab"]], "krb5_verify_init_creds_opt_init - Initialize a credential verification options structure.": [[417, "krb5-verify-init-creds-opt-init-initialize-a-credential-verification-options-structure"]], "krb5_verify_init_creds_opt_set_ap_req_nofail - Set whether credential verification is required.": [[418, "krb5-verify-init-creds-opt-set-ap-req-nofail-set-whether-credential-verification-is-required"]], "krb5_vprepend_error_message - Add a prefix to the message for an error code using a va_list.": [[419, "krb5-vprepend-error-message-add-a-prefix-to-the-message-for-an-error-code-using-a-va-list"]], "krb5_vset_error_message - Set an extended error message for an error code using a va_list.": [[420, "krb5-vset-error-message-set-an-extended-error-message-for-an-error-code-using-a-va-list"]], "krb5_vwrap_error_message - Add a prefix to a different error code\u2019s message using a va_list.": [[421, "krb5-vwrap-error-message-add-a-prefix-to-a-different-error-code-s-message-using-a-va-list"]], "krb5_wrap_error_message - Add a prefix to a different error code\u2019s message.": [[422, "krb5-wrap-error-message-add-a-prefix-to-a-different-error-code-s-message"]], "Complete reference - API and datatypes": [[423, "complete-reference-api-and-datatypes"]], "ADDRTYPE_ADDRPORT": [[424, "addrtype-addrport"]], "ADDRTYPE_CHAOS": [[425, "addrtype-chaos"]], "ADDRTYPE_DDP": [[426, "addrtype-ddp"]], "ADDRTYPE_DIRECTIONAL": [[427, "addrtype-directional"]], "ADDRTYPE_INET": [[428, "addrtype-inet"]], "ADDRTYPE_INET6": [[429, "addrtype-inet6"]], "ADDRTYPE_IPPORT": [[430, "addrtype-ipport"]], "ADDRTYPE_ISO": [[431, "addrtype-iso"]], "ADDRTYPE_IS_LOCAL": [[432, "addrtype-is-local"]], "ADDRTYPE_NETBIOS": [[433, "addrtype-netbios"]], "ADDRTYPE_UNIXSOCK": [[434, "addrtype-unixsock"]], "ADDRTYPE_XNS": [[435, "addrtype-xns"]], "AD_TYPE_EXTERNAL": [[436, "ad-type-external"]], "AD_TYPE_FIELD_TYPE_MASK": [[437, "ad-type-field-type-mask"]], "AD_TYPE_REGISTERED": [[438, "ad-type-registered"]], "AD_TYPE_RESERVED": [[439, "ad-type-reserved"]], "AP_OPTS_CBT_FLAG": [[440, "ap-opts-cbt-flag"]], "AP_OPTS_ETYPE_NEGOTIATION": [[441, "ap-opts-etype-negotiation"]], "AP_OPTS_MUTUAL_REQUIRED": [[442, "ap-opts-mutual-required"]], "AP_OPTS_RESERVED": [[443, "ap-opts-reserved"]], "AP_OPTS_USE_SESSION_KEY": [[444, "ap-opts-use-session-key"]], "AP_OPTS_USE_SUBKEY": [[445, "ap-opts-use-subkey"]], "AP_OPTS_WIRE_MASK": [[446, "ap-opts-wire-mask"]], "CKSUMTYPE_CMAC_CAMELLIA128": [[447, "cksumtype-cmac-camellia128"]], "CKSUMTYPE_CMAC_CAMELLIA256": [[448, "cksumtype-cmac-camellia256"]], "CKSUMTYPE_CRC32": [[449, "cksumtype-crc32"]], "CKSUMTYPE_DESCBC": [[450, "cksumtype-descbc"]], "CKSUMTYPE_HMAC_MD5_ARCFOUR": [[451, "cksumtype-hmac-md5-arcfour"]], "CKSUMTYPE_HMAC_SHA1_96_AES128": [[452, "cksumtype-hmac-sha1-96-aes128"]], "CKSUMTYPE_HMAC_SHA1_96_AES256": [[453, "cksumtype-hmac-sha1-96-aes256"]], "CKSUMTYPE_HMAC_SHA1_DES3": [[454, "cksumtype-hmac-sha1-des3"]], "CKSUMTYPE_HMAC_SHA256_128_AES128": [[455, "cksumtype-hmac-sha256-128-aes128"]], "CKSUMTYPE_HMAC_SHA384_192_AES256": [[456, "cksumtype-hmac-sha384-192-aes256"]], "CKSUMTYPE_MD5_HMAC_ARCFOUR": [[457, "cksumtype-md5-hmac-arcfour"]], "CKSUMTYPE_NIST_SHA": [[458, "cksumtype-nist-sha"]], "CKSUMTYPE_RSA_MD4": [[459, "cksumtype-rsa-md4"]], "CKSUMTYPE_RSA_MD4_DES": [[460, "cksumtype-rsa-md4-des"]], "CKSUMTYPE_RSA_MD5": [[461, "cksumtype-rsa-md5"]], "CKSUMTYPE_RSA_MD5_DES": [[462, "cksumtype-rsa-md5-des"]], "CKSUMTYPE_SHA1": [[463, "cksumtype-sha1"]], "ENCTYPE_AES128_CTS_HMAC_SHA1_96": [[464, "enctype-aes128-cts-hmac-sha1-96"]], "ENCTYPE_AES128_CTS_HMAC_SHA256_128": [[465, "enctype-aes128-cts-hmac-sha256-128"]], "ENCTYPE_AES256_CTS_HMAC_SHA1_96": [[466, "enctype-aes256-cts-hmac-sha1-96"]], "ENCTYPE_AES256_CTS_HMAC_SHA384_192": [[467, "enctype-aes256-cts-hmac-sha384-192"]], "ENCTYPE_ARCFOUR_HMAC": [[468, "enctype-arcfour-hmac"]], "ENCTYPE_ARCFOUR_HMAC_EXP": [[469, "enctype-arcfour-hmac-exp"]], "ENCTYPE_CAMELLIA128_CTS_CMAC": [[470, "enctype-camellia128-cts-cmac"]], "ENCTYPE_CAMELLIA256_CTS_CMAC": [[471, "enctype-camellia256-cts-cmac"]], "ENCTYPE_DES3_CBC_ENV": [[472, "enctype-des3-cbc-env"]], "ENCTYPE_DES3_CBC_RAW": [[473, "enctype-des3-cbc-raw"]], "ENCTYPE_DES3_CBC_SHA": [[474, "enctype-des3-cbc-sha"]], "ENCTYPE_DES3_CBC_SHA1": [[475, "enctype-des3-cbc-sha1"]], "ENCTYPE_DES_CBC_CRC": [[476, "enctype-des-cbc-crc"]], "ENCTYPE_DES_CBC_MD4": [[477, "enctype-des-cbc-md4"]], "ENCTYPE_DES_CBC_MD5": [[478, "enctype-des-cbc-md5"]], "ENCTYPE_DES_CBC_RAW": [[479, "enctype-des-cbc-raw"]], "ENCTYPE_DES_HMAC_SHA1": [[480, "enctype-des-hmac-sha1"]], "ENCTYPE_DSA_SHA1_CMS": [[481, "enctype-dsa-sha1-cms"]], "ENCTYPE_MD5_RSA_CMS": [[482, "enctype-md5-rsa-cms"]], "ENCTYPE_NULL": [[483, "enctype-null"]], "ENCTYPE_RC2_CBC_ENV": [[484, "enctype-rc2-cbc-env"]], "ENCTYPE_RSA_ENV": [[485, "enctype-rsa-env"]], "ENCTYPE_RSA_ES_OAEP_ENV": [[486, "enctype-rsa-es-oaep-env"]], "ENCTYPE_SHA1_RSA_CMS": [[487, "enctype-sha1-rsa-cms"]], "ENCTYPE_UNKNOWN": [[488, "enctype-unknown"]], "KDC_OPT_ALLOW_POSTDATE": [[489, "kdc-opt-allow-postdate"]], "KDC_OPT_CANONICALIZE": [[490, "kdc-opt-canonicalize"]], "KDC_OPT_CNAME_IN_ADDL_TKT": [[491, "kdc-opt-cname-in-addl-tkt"]], "KDC_OPT_DISABLE_TRANSITED_CHECK": [[492, "kdc-opt-disable-transited-check"]], "KDC_OPT_ENC_TKT_IN_SKEY": [[493, "kdc-opt-enc-tkt-in-skey"]], "KDC_OPT_FORWARDABLE": [[494, "kdc-opt-forwardable"]], "KDC_OPT_FORWARDED": [[495, "kdc-opt-forwarded"]], "KDC_OPT_POSTDATED": [[496, "kdc-opt-postdated"]], "KDC_OPT_PROXIABLE": [[497, "kdc-opt-proxiable"]], "KDC_OPT_PROXY": [[498, "kdc-opt-proxy"]], "KDC_OPT_RENEW": [[499, "kdc-opt-renew"]], "KDC_OPT_RENEWABLE": [[500, "kdc-opt-renewable"]], "KDC_OPT_RENEWABLE_OK": [[501, "kdc-opt-renewable-ok"]], "KDC_OPT_REQUEST_ANONYMOUS": [[502, "kdc-opt-request-anonymous"]], "KDC_OPT_VALIDATE": [[503, "kdc-opt-validate"]], "KDC_TKT_COMMON_MASK": [[504, "kdc-tkt-common-mask"]], "KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE": [[505, "krb5-altauth-att-challenge-response"]], "KRB5_ANONYMOUS_PRINCSTR": [[506, "krb5-anonymous-princstr"]], "KRB5_ANONYMOUS_REALMSTR": [[507, "krb5-anonymous-realmstr"]], "KRB5_AP_REP": [[508, "krb5-ap-rep"]], "KRB5_AP_REQ": [[509, "krb5-ap-req"]], "KRB5_AS_REP": [[510, "krb5-as-rep"]], "KRB5_AS_REQ": [[511, "krb5-as-req"]], "KRB5_AUTHDATA_AND_OR": [[512, "krb5-authdata-and-or"]], "KRB5_AUTHDATA_AP_OPTIONS": [[513, "krb5-authdata-ap-options"]], "KRB5_AUTHDATA_AUTH_INDICATOR": [[514, "krb5-authdata-auth-indicator"]], "KRB5_AUTHDATA_CAMMAC": [[515, "krb5-authdata-cammac"]], "KRB5_AUTHDATA_ETYPE_NEGOTIATION": [[516, "krb5-authdata-etype-negotiation"]], "KRB5_AUTHDATA_FX_ARMOR": [[517, "krb5-authdata-fx-armor"]], "KRB5_AUTHDATA_IF_RELEVANT": [[518, "krb5-authdata-if-relevant"]], "KRB5_AUTHDATA_INITIAL_VERIFIED_CAS": [[519, "krb5-authdata-initial-verified-cas"]], "KRB5_AUTHDATA_KDC_ISSUED": [[520, "krb5-authdata-kdc-issued"]], "KRB5_AUTHDATA_MANDATORY_FOR_KDC": [[521, "krb5-authdata-mandatory-for-kdc"]], "KRB5_AUTHDATA_OSF_DCE": [[522, "krb5-authdata-osf-dce"]], "KRB5_AUTHDATA_SESAME": [[523, "krb5-authdata-sesame"]], "KRB5_AUTHDATA_SIGNTICKET": [[524, "krb5-authdata-signticket"]], "KRB5_AUTHDATA_WIN2K_PAC": [[525, "krb5-authdata-win2k-pac"]], "KRB5_AUTH_CONTEXT_DO_SEQUENCE": [[526, "krb5-auth-context-do-sequence"]], "KRB5_AUTH_CONTEXT_DO_TIME": [[527, "krb5-auth-context-do-time"]], "KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR": [[528, "krb5-auth-context-generate-local-addr"]], "KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR": [[529, "krb5-auth-context-generate-local-full-addr"]], "KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR": [[530, "krb5-auth-context-generate-remote-addr"]], "KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR": [[531, "krb5-auth-context-generate-remote-full-addr"]], "KRB5_AUTH_CONTEXT_PERMIT_ALL": [[532, "krb5-auth-context-permit-all"]], "KRB5_AUTH_CONTEXT_RET_SEQUENCE": [[533, "krb5-auth-context-ret-sequence"]], "KRB5_AUTH_CONTEXT_RET_TIME": [[534, "krb5-auth-context-ret-time"]], "KRB5_AUTH_CONTEXT_USE_SUBKEY": [[535, "krb5-auth-context-use-subkey"]], "KRB5_CRED": [[536, "krb5-cred"]], "KRB5_CRYPTO_TYPE_CHECKSUM": [[537, "krb5-crypto-type-checksum"]], "KRB5_CRYPTO_TYPE_DATA": [[538, "krb5-crypto-type-data"]], "KRB5_CRYPTO_TYPE_EMPTY": [[539, "krb5-crypto-type-empty"]], "KRB5_CRYPTO_TYPE_HEADER": [[540, "krb5-crypto-type-header"]], "KRB5_CRYPTO_TYPE_PADDING": [[541, "krb5-crypto-type-padding"]], "KRB5_CRYPTO_TYPE_SIGN_ONLY": [[542, "krb5-crypto-type-sign-only"]], "KRB5_CRYPTO_TYPE_STREAM": [[543, "krb5-crypto-type-stream"]], "KRB5_CRYPTO_TYPE_TRAILER": [[544, "krb5-crypto-type-trailer"]], "KRB5_CYBERSAFE_SECUREID": [[545, "krb5-cybersafe-secureid"]], "KRB5_DOMAIN_X500_COMPRESS": [[546, "krb5-domain-x500-compress"]], "KRB5_ENCPADATA_REQ_ENC_PA_REP": [[547, "krb5-encpadata-req-enc-pa-rep"]], "KRB5_ERROR": [[548, "krb5-error"]], "KRB5_FAST_REQUIRED": [[549, "krb5-fast-required"]], "KRB5_GC_CACHED": [[550, "krb5-gc-cached"]], "KRB5_GC_CANONICALIZE": [[551, "krb5-gc-canonicalize"]], "KRB5_GC_CONSTRAINED_DELEGATION": [[552, "krb5-gc-constrained-delegation"]], "KRB5_GC_FORWARDABLE": [[553, "krb5-gc-forwardable"]], "KRB5_GC_NO_STORE": [[554, "krb5-gc-no-store"]], "KRB5_GC_NO_TRANSIT_CHECK": [[555, "krb5-gc-no-transit-check"]], "KRB5_GC_USER_USER": [[556, "krb5-gc-user-user"]], "KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST": [[557, "krb5-get-init-creds-opt-address-list"]], "KRB5_GET_INIT_CREDS_OPT_ANONYMOUS": [[558, "krb5-get-init-creds-opt-anonymous"]], "KRB5_GET_INIT_CREDS_OPT_CANONICALIZE": [[559, "krb5-get-init-creds-opt-canonicalize"]], "KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT": [[560, "krb5-get-init-creds-opt-chg-pwd-prmpt"]], "KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST": [[561, "krb5-get-init-creds-opt-etype-list"]], "KRB5_GET_INIT_CREDS_OPT_FORWARDABLE": [[562, "krb5-get-init-creds-opt-forwardable"]], "KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST": [[563, "krb5-get-init-creds-opt-preauth-list"]], "KRB5_GET_INIT_CREDS_OPT_PROXIABLE": [[564, "krb5-get-init-creds-opt-proxiable"]], "KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE": [[565, "krb5-get-init-creds-opt-renew-life"]], "KRB5_GET_INIT_CREDS_OPT_SALT": [[566, "krb5-get-init-creds-opt-salt"]], "KRB5_GET_INIT_CREDS_OPT_TKT_LIFE": [[567, "krb5-get-init-creds-opt-tkt-life"]], "KRB5_INIT_CONTEXT_KDC": [[568, "krb5-init-context-kdc"]], "KRB5_INIT_CONTEXT_SECURE": [[569, "krb5-init-context-secure"]], "KRB5_INIT_CREDS_STEP_FLAG_CONTINUE": [[570, "krb5-init-creds-step-flag-continue"]], "KRB5_INT16_MAX": [[571, "krb5-int16-max"]], "KRB5_INT16_MIN": [[572, "krb5-int16-min"]], "KRB5_INT32_MAX": [[573, "krb5-int32-max"]], "KRB5_INT32_MIN": [[574, "krb5-int32-min"]], "KRB5_KEYUSAGE_AD_ITE": [[575, "krb5-keyusage-ad-ite"]], "KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM": [[576, "krb5-keyusage-ad-kdcissued-cksum"]], "KRB5_KEYUSAGE_AD_MTE": [[577, "krb5-keyusage-ad-mte"]], "KRB5_KEYUSAGE_AD_SIGNEDPATH": [[578, "krb5-keyusage-ad-signedpath"]], "KRB5_KEYUSAGE_APP_DATA_CKSUM": [[579, "krb5-keyusage-app-data-cksum"]], "KRB5_KEYUSAGE_APP_DATA_ENCRYPT": [[580, "krb5-keyusage-app-data-encrypt"]], "KRB5_KEYUSAGE_AP_REP_ENCPART": [[581, "krb5-keyusage-ap-rep-encpart"]], "KRB5_KEYUSAGE_AP_REQ_AUTH": [[582, "krb5-keyusage-ap-req-auth"]], "KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM": [[583, "krb5-keyusage-ap-req-auth-cksum"]], "KRB5_KEYUSAGE_AS_REP_ENCPART": [[584, "krb5-keyusage-as-rep-encpart"]], "KRB5_KEYUSAGE_AS_REQ": [[585, "krb5-keyusage-as-req"]], "KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS": [[586, "krb5-keyusage-as-req-pa-enc-ts"]], "KRB5_KEYUSAGE_CAMMAC": [[587, "krb5-keyusage-cammac"]], "KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT": [[588, "krb5-keyusage-enc-challenge-client"]], "KRB5_KEYUSAGE_ENC_CHALLENGE_KDC": [[589, "krb5-keyusage-enc-challenge-kdc"]], "KRB5_KEYUSAGE_FAST_ENC": [[590, "krb5-keyusage-fast-enc"]], "KRB5_KEYUSAGE_FAST_FINISHED": [[591, "krb5-keyusage-fast-finished"]], "KRB5_KEYUSAGE_FAST_REP": [[592, "krb5-keyusage-fast-rep"]], "KRB5_KEYUSAGE_FAST_REQ_CHKSUM": [[593, "krb5-keyusage-fast-req-chksum"]], "KRB5_KEYUSAGE_FINISHED": [[594, "krb5-keyusage-finished"]], "KRB5_KEYUSAGE_GSS_TOK_MIC": [[595, "krb5-keyusage-gss-tok-mic"]], "KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG": [[596, "krb5-keyusage-gss-tok-wrap-integ"]], "KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV": [[597, "krb5-keyusage-gss-tok-wrap-priv"]], "KRB5_KEYUSAGE_IAKERB_FINISHED": [[598, "krb5-keyusage-iakerb-finished"]], "KRB5_KEYUSAGE_KDC_REP_TICKET": [[599, "krb5-keyusage-kdc-rep-ticket"]], "KRB5_KEYUSAGE_KRB_CRED_ENCPART": [[600, "krb5-keyusage-krb-cred-encpart"]], "KRB5_KEYUSAGE_KRB_ERROR_CKSUM": [[601, "krb5-keyusage-krb-error-cksum"]], "KRB5_KEYUSAGE_KRB_PRIV_ENCPART": [[602, "krb5-keyusage-krb-priv-encpart"]], "KRB5_KEYUSAGE_KRB_SAFE_CKSUM": [[603, "krb5-keyusage-krb-safe-cksum"]], "KRB5_KEYUSAGE_PA_AS_FRESHNESS": [[604, "krb5-keyusage-pa-as-freshness"]], "KRB5_KEYUSAGE_PA_FX_COOKIE": [[605, "krb5-keyusage-pa-fx-cookie"]], "KRB5_KEYUSAGE_PA_OTP_REQUEST": [[606, "krb5-keyusage-pa-otp-request"]], "KRB5_KEYUSAGE_PA_PKINIT_KX": [[607, "krb5-keyusage-pa-pkinit-kx"]], "KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY": [[608, "krb5-keyusage-pa-s4u-x509-user-reply"]], "KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST": [[609, "krb5-keyusage-pa-s4u-x509-user-request"]], "KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM": [[610, "krb5-keyusage-pa-sam-challenge-cksum"]], "KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID": [[611, "krb5-keyusage-pa-sam-challenge-trackid"]], "KRB5_KEYUSAGE_PA_SAM_RESPONSE": [[612, "krb5-keyusage-pa-sam-response"]], "KRB5_KEYUSAGE_SPAKE": [[613, "krb5-keyusage-spake"]], "KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY": [[614, "krb5-keyusage-tgs-rep-encpart-sesskey"]], "KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY": [[615, "krb5-keyusage-tgs-rep-encpart-subkey"]], "KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY": [[616, "krb5-keyusage-tgs-req-ad-sesskey"]], "KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY": [[617, "krb5-keyusage-tgs-req-ad-subkey"]], "KRB5_KEYUSAGE_TGS_REQ_AUTH": [[618, "krb5-keyusage-tgs-req-auth"]], "KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM": [[619, "krb5-keyusage-tgs-req-auth-cksum"]], "KRB5_KPASSWD_ACCESSDENIED": [[620, "krb5-kpasswd-accessdenied"]], "KRB5_KPASSWD_AUTHERROR": [[621, "krb5-kpasswd-autherror"]], "KRB5_KPASSWD_BAD_VERSION": [[622, "krb5-kpasswd-bad-version"]], "KRB5_KPASSWD_HARDERROR": [[623, "krb5-kpasswd-harderror"]], "KRB5_KPASSWD_INITIAL_FLAG_NEEDED": [[624, "krb5-kpasswd-initial-flag-needed"]], "KRB5_KPASSWD_MALFORMED": [[625, "krb5-kpasswd-malformed"]], "KRB5_KPASSWD_SOFTERROR": [[626, "krb5-kpasswd-softerror"]], "KRB5_KPASSWD_SUCCESS": [[627, "krb5-kpasswd-success"]], "KRB5_LRQ_ALL_ACCT_EXPTIME": [[628, "krb5-lrq-all-acct-exptime"]], "KRB5_LRQ_ALL_LAST_INITIAL": [[629, "krb5-lrq-all-last-initial"]], "KRB5_LRQ_ALL_LAST_RENEWAL": [[630, "krb5-lrq-all-last-renewal"]], "KRB5_LRQ_ALL_LAST_REQ": [[631, "krb5-lrq-all-last-req"]], "KRB5_LRQ_ALL_LAST_TGT": [[632, "krb5-lrq-all-last-tgt"]], "KRB5_LRQ_ALL_LAST_TGT_ISSUED": [[633, "krb5-lrq-all-last-tgt-issued"]], "KRB5_LRQ_ALL_PW_EXPTIME": [[634, "krb5-lrq-all-pw-exptime"]], "KRB5_LRQ_NONE": [[635, "krb5-lrq-none"]], "KRB5_LRQ_ONE_ACCT_EXPTIME": [[636, "krb5-lrq-one-acct-exptime"]], "KRB5_LRQ_ONE_LAST_INITIAL": [[637, "krb5-lrq-one-last-initial"]], "KRB5_LRQ_ONE_LAST_RENEWAL": [[638, "krb5-lrq-one-last-renewal"]], "KRB5_LRQ_ONE_LAST_REQ": [[639, "krb5-lrq-one-last-req"]], "KRB5_LRQ_ONE_LAST_TGT": [[640, "krb5-lrq-one-last-tgt"]], "KRB5_LRQ_ONE_LAST_TGT_ISSUED": [[641, "krb5-lrq-one-last-tgt-issued"]], "KRB5_LRQ_ONE_PW_EXPTIME": [[642, "krb5-lrq-one-pw-exptime"]], "KRB5_NT_ENTERPRISE_PRINCIPAL": [[643, "krb5-nt-enterprise-principal"]], "KRB5_NT_ENT_PRINCIPAL_AND_ID": [[644, "krb5-nt-ent-principal-and-id"]], "KRB5_NT_MS_PRINCIPAL": [[645, "krb5-nt-ms-principal"]], "KRB5_NT_MS_PRINCIPAL_AND_ID": [[646, "krb5-nt-ms-principal-and-id"]], "KRB5_NT_PRINCIPAL": [[647, "krb5-nt-principal"]], "KRB5_NT_SMTP_NAME": [[648, "krb5-nt-smtp-name"]], "KRB5_NT_SRV_HST": [[649, "krb5-nt-srv-hst"]], "KRB5_NT_SRV_INST": [[650, "krb5-nt-srv-inst"]], "KRB5_NT_SRV_XHST": [[651, "krb5-nt-srv-xhst"]], "KRB5_NT_UID": [[652, "krb5-nt-uid"]], "KRB5_NT_UNKNOWN": [[653, "krb5-nt-unknown"]], "KRB5_NT_WELLKNOWN": [[654, "krb5-nt-wellknown"]], "KRB5_NT_X500_PRINCIPAL": [[655, "krb5-nt-x500-principal"]], "KRB5_PAC_ATTRIBUTES_INFO": [[656, "krb5-pac-attributes-info"]], "KRB5_PAC_CLIENT_CLAIMS": [[657, "krb5-pac-client-claims"]], "KRB5_PAC_CLIENT_INFO": [[658, "krb5-pac-client-info"]], "KRB5_PAC_CREDENTIALS_INFO": [[659, "krb5-pac-credentials-info"]], "KRB5_PAC_DELEGATION_INFO": [[660, "krb5-pac-delegation-info"]], "KRB5_PAC_DEVICE_CLAIMS": [[661, "krb5-pac-device-claims"]], "KRB5_PAC_DEVICE_INFO": [[662, "krb5-pac-device-info"]], "KRB5_PAC_FULL_CHECKSUM": [[663, "krb5-pac-full-checksum"]], "KRB5_PAC_LOGON_INFO": [[664, "krb5-pac-logon-info"]], "KRB5_PAC_PRIVSVR_CHECKSUM": [[665, "krb5-pac-privsvr-checksum"]], "KRB5_PAC_REQUESTOR": [[666, "krb5-pac-requestor"]], "KRB5_PAC_SERVER_CHECKSUM": [[667, "krb5-pac-server-checksum"]], "KRB5_PAC_TICKET_CHECKSUM": [[668, "krb5-pac-ticket-checksum"]], "KRB5_PAC_UPN_DNS_INFO": [[669, "krb5-pac-upn-dns-info"]], "KRB5_PADATA_AFS3_SALT": [[670, "krb5-padata-afs3-salt"]], "KRB5_PADATA_AP_REQ": [[671, "krb5-padata-ap-req"]], "KRB5_PADATA_AS_CHECKSUM": [[672, "krb5-padata-as-checksum"]], "KRB5_PADATA_AS_FRESHNESS": [[673, "krb5-padata-as-freshness"]], "KRB5_PADATA_ENCRYPTED_CHALLENGE": [[674, "krb5-padata-encrypted-challenge"]], "KRB5_PADATA_ENC_SANDIA_SECURID": [[675, "krb5-padata-enc-sandia-securid"]], "KRB5_PADATA_ENC_TIMESTAMP": [[676, "krb5-padata-enc-timestamp"]], "KRB5_PADATA_ENC_UNIX_TIME": [[677, "krb5-padata-enc-unix-time"]], "KRB5_PADATA_ETYPE_INFO": [[678, "krb5-padata-etype-info"]], "KRB5_PADATA_ETYPE_INFO2": [[679, "krb5-padata-etype-info2"]], "KRB5_PADATA_FOR_USER": [[680, "krb5-padata-for-user"]], "KRB5_PADATA_FX_COOKIE": [[681, "krb5-padata-fx-cookie"]], "KRB5_PADATA_FX_ERROR": [[682, "krb5-padata-fx-error"]], "KRB5_PADATA_FX_FAST": [[683, "krb5-padata-fx-fast"]], "KRB5_PADATA_GET_FROM_TYPED_DATA": [[684, "krb5-padata-get-from-typed-data"]], "KRB5_PADATA_NONE": [[685, "krb5-padata-none"]], "KRB5_PADATA_OSF_DCE": [[686, "krb5-padata-osf-dce"]], "KRB5_PADATA_OTP_CHALLENGE": [[687, "krb5-padata-otp-challenge"]], "KRB5_PADATA_OTP_PIN_CHANGE": [[688, "krb5-padata-otp-pin-change"]], "KRB5_PADATA_OTP_REQUEST": [[689, "krb5-padata-otp-request"]], "KRB5_PADATA_PAC_OPTIONS": [[690, "krb5-padata-pac-options"]], "KRB5_PADATA_PAC_REQUEST": [[691, "krb5-padata-pac-request"]], "KRB5_PADATA_PKINIT_KX": [[692, "krb5-padata-pkinit-kx"]], "KRB5_PADATA_PK_AS_REP": [[693, "krb5-padata-pk-as-rep"]], "KRB5_PADATA_PK_AS_REP_OLD": [[694, "krb5-padata-pk-as-rep-old"]], "KRB5_PADATA_PK_AS_REQ": [[695, "krb5-padata-pk-as-req"]], "KRB5_PADATA_PK_AS_REQ_OLD": [[696, "krb5-padata-pk-as-req-old"]], "KRB5_PADATA_PW_SALT": [[697, "krb5-padata-pw-salt"]], "KRB5_PADATA_REDHAT_IDP_OAUTH2": [[698, "krb5-padata-redhat-idp-oauth2"]], "KRB5_PADATA_REDHAT_PASSKEY": [[699, "krb5-padata-redhat-passkey"]], "KRB5_PADATA_REFERRAL": [[700, "krb5-padata-referral"]], "KRB5_PADATA_S4U_X509_USER": [[701, "krb5-padata-s4u-x509-user"]], "KRB5_PADATA_SAM_CHALLENGE": [[702, "krb5-padata-sam-challenge"]], "KRB5_PADATA_SAM_CHALLENGE_2": [[703, "krb5-padata-sam-challenge-2"]], "KRB5_PADATA_SAM_REDIRECT": [[704, "krb5-padata-sam-redirect"]], "KRB5_PADATA_SAM_RESPONSE": [[705, "krb5-padata-sam-response"]], "KRB5_PADATA_SAM_RESPONSE_2": [[706, "krb5-padata-sam-response-2"]], "KRB5_PADATA_SESAME": [[707, "krb5-padata-sesame"]], "KRB5_PADATA_SPAKE": [[708, "krb5-padata-spake"]], "KRB5_PADATA_SVR_REFERRAL_INFO": [[709, "krb5-padata-svr-referral-info"]], "KRB5_PADATA_TGS_REQ": [[710, "krb5-padata-tgs-req"]], "KRB5_PADATA_USE_SPECIFIED_KVNO": [[711, "krb5-padata-use-specified-kvno"]], "KRB5_PRINCIPAL_COMPARE_CASEFOLD": [[712, "krb5-principal-compare-casefold"]], "KRB5_PRINCIPAL_COMPARE_ENTERPRISE": [[713, "krb5-principal-compare-enterprise"]], "KRB5_PRINCIPAL_COMPARE_IGNORE_REALM": [[714, "krb5-principal-compare-ignore-realm"]], "KRB5_PRINCIPAL_COMPARE_UTF8": [[715, "krb5-principal-compare-utf8"]], "KRB5_PRINCIPAL_PARSE_ENTERPRISE": [[716, "krb5-principal-parse-enterprise"]], "KRB5_PRINCIPAL_PARSE_IGNORE_REALM": [[717, "krb5-principal-parse-ignore-realm"]], "KRB5_PRINCIPAL_PARSE_NO_DEF_REALM": [[718, "krb5-principal-parse-no-def-realm"]], "KRB5_PRINCIPAL_PARSE_NO_REALM": [[719, "krb5-principal-parse-no-realm"]], "KRB5_PRINCIPAL_PARSE_REQUIRE_REALM": [[720, "krb5-principal-parse-require-realm"]], "KRB5_PRINCIPAL_UNPARSE_DISPLAY": [[721, "krb5-principal-unparse-display"]], "KRB5_PRINCIPAL_UNPARSE_NO_REALM": [[722, "krb5-principal-unparse-no-realm"]], "KRB5_PRINCIPAL_UNPARSE_SHORT": [[723, "krb5-principal-unparse-short"]], "KRB5_PRIV": [[724, "krb5-priv"]], "KRB5_PROMPT_TYPE_NEW_PASSWORD": [[725, "krb5-prompt-type-new-password"]], "KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN": [[726, "krb5-prompt-type-new-password-again"]], "KRB5_PROMPT_TYPE_PASSWORD": [[727, "krb5-prompt-type-password"]], "KRB5_PROMPT_TYPE_PREAUTH": [[728, "krb5-prompt-type-preauth"]], "KRB5_PVNO": [[729, "krb5-pvno"]], "KRB5_REALM_BRANCH_CHAR": [[730, "krb5-realm-branch-char"]], "KRB5_RECVAUTH_BADAUTHVERS": [[731, "krb5-recvauth-badauthvers"]], "KRB5_RECVAUTH_SKIP_VERSION": [[732, "krb5-recvauth-skip-version"]], "KRB5_REFERRAL_REALM": [[733, "krb5-referral-realm"]], "KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN": [[734, "krb5-responder-otp-flags-collect-pin"]], "KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN": [[735, "krb5-responder-otp-flags-collect-token"]], "KRB5_RESPONDER_OTP_FLAGS_NEXTOTP": [[736, "krb5-responder-otp-flags-nextotp"]], "KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN": [[737, "krb5-responder-otp-flags-separate-pin"]], "KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC": [[738, "krb5-responder-otp-format-alphanumeric"]], "KRB5_RESPONDER_OTP_FORMAT_DECIMAL": [[739, "krb5-responder-otp-format-decimal"]], "KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL": [[740, "krb5-responder-otp-format-hexadecimal"]], "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW": [[741, "krb5-responder-pkinit-flags-token-user-pin-count-low"]], "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY": [[742, "krb5-responder-pkinit-flags-token-user-pin-final-try"]], "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED": [[743, "krb5-responder-pkinit-flags-token-user-pin-locked"]], "KRB5_RESPONDER_QUESTION_OTP": [[744, "krb5-responder-question-otp"]], "KRB5_RESPONDER_QUESTION_PASSWORD": [[745, "krb5-responder-question-password"]], "KRB5_RESPONDER_QUESTION_PKINIT": [[746, "krb5-responder-question-pkinit"]], "KRB5_SAFE": [[747, "krb5-safe"]], "KRB5_SAM_MUST_PK_ENCRYPT_SAD": [[748, "krb5-sam-must-pk-encrypt-sad"]], "KRB5_SAM_SEND_ENCRYPTED_SAD": [[749, "krb5-sam-send-encrypted-sad"]], "KRB5_SAM_USE_SAD_AS_KEY": [[750, "krb5-sam-use-sad-as-key"]], "KRB5_TC_MATCH_2ND_TKT": [[751, "krb5-tc-match-2nd-tkt"]], "KRB5_TC_MATCH_AUTHDATA": [[752, "krb5-tc-match-authdata"]], "KRB5_TC_MATCH_FLAGS": [[753, "krb5-tc-match-flags"]], "KRB5_TC_MATCH_FLAGS_EXACT": [[754, "krb5-tc-match-flags-exact"]], "KRB5_TC_MATCH_IS_SKEY": [[755, "krb5-tc-match-is-skey"]], "KRB5_TC_MATCH_KTYPE": [[756, "krb5-tc-match-ktype"]], "KRB5_TC_MATCH_SRV_NAMEONLY": [[757, "krb5-tc-match-srv-nameonly"]], "KRB5_TC_MATCH_TIMES": [[758, "krb5-tc-match-times"]], "KRB5_TC_MATCH_TIMES_EXACT": [[759, "krb5-tc-match-times-exact"]], "KRB5_TC_NOTICKET": [[760, "krb5-tc-noticket"]], "KRB5_TC_OPENCLOSE": [[761, "krb5-tc-openclose"]], "KRB5_TC_SUPPORTED_KTYPES": [[762, "krb5-tc-supported-ktypes"]], "KRB5_TGS_NAME": [[763, "krb5-tgs-name"]], "KRB5_TGS_NAME_SIZE": [[764, "krb5-tgs-name-size"]], "KRB5_TGS_REP": [[765, "krb5-tgs-rep"]], "KRB5_TGS_REQ": [[766, "krb5-tgs-req"]], "KRB5_TKT_CREDS_STEP_FLAG_CONTINUE": [[767, "krb5-tkt-creds-step-flag-continue"]], "KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL": [[768, "krb5-verify-init-creds-opt-ap-req-nofail"]], "KRB5_WELLKNOWN_NAMESTR": [[769, "krb5-wellknown-namestr"]], "LR_TYPE_INTERPRETATION_MASK": [[770, "lr-type-interpretation-mask"]], "LR_TYPE_THIS_SERVER_ONLY": [[771, "lr-type-this-server-only"]], "MAX_KEYTAB_NAME_LEN": [[772, "max-keytab-name-len"]], "MSEC_DIRBIT": [[773, "msec-dirbit"]], "MSEC_VAL_MASK": [[774, "msec-val-mask"]], "SALT_TYPE_AFS_LENGTH": [[775, "salt-type-afs-length"]], "SALT_TYPE_NO_LENGTH": [[776, "salt-type-no-length"]], "THREEPARAMOPEN": [[777, "threeparamopen"]], "TKT_FLG_ANONYMOUS": [[778, "tkt-flg-anonymous"]], "TKT_FLG_ENC_PA_REP": [[779, "tkt-flg-enc-pa-rep"]], "TKT_FLG_FORWARDABLE": [[780, "tkt-flg-forwardable"]], "TKT_FLG_FORWARDED": [[781, "tkt-flg-forwarded"]], "TKT_FLG_HW_AUTH": [[782, "tkt-flg-hw-auth"]], "TKT_FLG_INITIAL": [[783, "tkt-flg-initial"]], "TKT_FLG_INVALID": [[784, "tkt-flg-invalid"]], "TKT_FLG_MAY_POSTDATE": [[785, "tkt-flg-may-postdate"]], "TKT_FLG_OK_AS_DELEGATE": [[786, "tkt-flg-ok-as-delegate"]], "TKT_FLG_POSTDATED": [[787, "tkt-flg-postdated"]], "TKT_FLG_PRE_AUTH": [[788, "tkt-flg-pre-auth"]], "TKT_FLG_PROXIABLE": [[789, "tkt-flg-proxiable"]], "TKT_FLG_PROXY": [[790, "tkt-flg-proxy"]], "TKT_FLG_RENEWABLE": [[791, "tkt-flg-renewable"]], "TKT_FLG_TRANSIT_POLICY_CHECKED": [[792, "tkt-flg-transit-policy-checked"]], "VALID_INT_BITS": [[793, "valid-int-bits"]], "VALID_UINT_BITS": [[794, "valid-uint-bits"]], "krb5 simple macros": [[795, "krb5-simple-macros"]], "Public": [[795, "public"], [810, "public"]], "Deprecated macros": [[795, "deprecated-macros"]], "krb524_convert_creds_kdc": [[796, "krb524-convert-creds-kdc"]], "krb524_init_ets": [[797, "krb524-init-ets"]], "krb5_const": [[798, "krb5-const"]], "krb5_princ_component": [[799, "krb5-princ-component"]], "krb5_princ_name": [[800, "krb5-princ-name"]], "krb5_princ_realm": [[801, "krb5-princ-realm"]], "krb5_princ_set_realm": [[802, "krb5-princ-set-realm"]], "krb5_princ_set_realm_data": [[803, "krb5-princ-set-realm-data"]], "krb5_princ_set_realm_length": [[804, "krb5-princ-set-realm-length"]], "krb5_princ_size": [[805, "krb5-princ-size"]], "krb5_princ_type": [[806, "krb5-princ-type"]], "krb5_roundup": [[807, "krb5-roundup"]], "krb5_x": [[808, "krb5-x"]], "krb5_xc": [[809, "krb5-xc"]], "krb5 types and structures": [[810, "krb5-types-and-structures"]], "Internal": [[810, "internal"]], "krb5_address": [[811, "krb5-address"]], "Declaration": [[811, "declaration"], [812, "declaration"], [813, "declaration"], [814, "declaration"], [815, "declaration"], [816, "declaration"], [817, "declaration"], [818, "declaration"], [819, "declaration"], [820, "declaration"], [821, "declaration"], [822, "declaration"], [823, "declaration"], [824, "declaration"], [825, "declaration"], [826, "declaration"], [827, "declaration"], [828, "declaration"], [829, "declaration"], [830, "declaration"], [831, "declaration"], [832, "declaration"], [833, "declaration"], [834, "declaration"], [835, "declaration"], [836, "declaration"], [837, "declaration"], [838, "declaration"], [839, "declaration"], [840, "declaration"], [841, "declaration"], [842, "declaration"], [843, "declaration"], [844, "declaration"], [845, "declaration"], [846, "declaration"], [847, "declaration"], [848, "declaration"], [849, "declaration"], [850, "declaration"], [851, "declaration"], [852, "declaration"], [853, "declaration"], [854, "declaration"], [855, "declaration"], [856, "declaration"], [857, "declaration"], [858, "declaration"], [859, "declaration"], [860, "declaration"], [861, "declaration"], [862, "declaration"], [863, "declaration"], [864, "declaration"], [865, "declaration"], [866, "declaration"], [867, "declaration"], [868, "declaration"], [869, "declaration"], [870, "declaration"], [871, "declaration"], [872, "declaration"], [873, "declaration"], [874, "declaration"], [875, "declaration"], [876, "declaration"], [877, "declaration"], [878, "declaration"], [879, "declaration"], [880, "declaration"], [881, "declaration"], [882, "declaration"], [883, "declaration"], [884, "declaration"], [885, "declaration"], [886, "declaration"], [887, "declaration"], [888, "declaration"], [889, "declaration"], [890, "declaration"], [891, "declaration"], [892, "declaration"], [893, "declaration"], [894, "declaration"], [895, "declaration"], [896, "declaration"], [897, "declaration"], [898, "declaration"], [899, "declaration"], [900, "declaration"], [901, "declaration"]], "Members": [[811, "members"], [813, "members"], [814, "members"], [815, "members"], [817, "members"], [819, "members"], [824, "members"], [827, "members"], [829, "members"], [830, "members"], [831, "members"], [832, "members"], [833, "members"], [835, "members"], [837, "members"], [838, "members"], [839, "members"], [840, "members"], [842, "members"], [846, "members"], [847, "members"], [851, "members"], [852, "members"], [854, "members"], [856, "members"], [860, "members"], [865, "members"], [866, "members"], [867, "members"], [868, "members"], [874, "members"], [875, "members"], [876, "members"], [879, "members"], [881, "members"], [884, "members"], [885, "members"], [886, "members"], [887, "members"], [888, "members"], [889, "members"], [890, "members"], [892, "members"], [895, "members"], [896, "members"], [897, "members"], [900, "members"], [901, "members"]], "krb5_addrtype": [[812, "krb5-addrtype"]], "krb5_ap_rep": [[813, "krb5-ap-rep"]], "krb5_ap_rep_enc_part": [[814, "krb5-ap-rep-enc-part"]], "krb5_ap_req": [[815, "krb5-ap-req"]], "krb5_auth_context": [[816, "krb5-auth-context"]], "krb5_authdata": [[817, "krb5-authdata"]], "krb5_authdatatype": [[818, "krb5-authdatatype"]], "krb5_authenticator": [[819, "krb5-authenticator"]], "krb5_boolean": [[820, "krb5-boolean"]], "krb5_cc_cursor": [[821, "krb5-cc-cursor"]], "krb5_ccache": [[822, "krb5-ccache"]], "krb5_cccol_cursor": [[823, "krb5-cccol-cursor"]], "krb5_checksum": [[824, "krb5-checksum"]], "krb5_cksumtype": [[825, "krb5-cksumtype"]], "krb5_const_pointer": [[826, "krb5-const-pointer"]], "krb5_const_principal": [[827, "krb5-const-principal"]], "krb5_context": [[828, "krb5-context"]], "krb5_cred": [[829, "krb5-cred"]], "krb5_cred_enc_part": [[830, "krb5-cred-enc-part"]], "krb5_cred_info": [[831, "krb5-cred-info"]], "krb5_creds": [[832, "krb5-creds"]], "krb5_crypto_iov": [[833, "krb5-crypto-iov"]], "krb5_cryptotype": [[834, "krb5-cryptotype"]], "krb5_data": [[835, "krb5-data"]], "krb5_deltat": [[836, "krb5-deltat"]], "krb5_enc_data": [[837, "krb5-enc-data"]], "krb5_enc_kdc_rep_part": [[838, "krb5-enc-kdc-rep-part"]], "krb5_enc_tkt_part": [[839, "krb5-enc-tkt-part"]], "krb5_encrypt_block": [[840, "krb5-encrypt-block"]], "krb5_enctype": [[841, "krb5-enctype"]], "krb5_error": [[842, "krb5-error"]], "krb5_error_code": [[843, "krb5-error-code"]], "krb5_expire_callback_func": [[844, "krb5-expire-callback-func"]], "krb5_flags": [[845, "krb5-flags"]], "krb5_get_init_creds_opt": [[846, "krb5-get-init-creds-opt"]], "krb5_gic_opt_pa_data": [[847, "krb5-gic-opt-pa-data"]], "krb5_init_creds_context": [[848, "krb5-init-creds-context"]], "krb5_int16": [[849, "krb5-int16"]], "krb5_int32": [[850, "krb5-int32"]], "krb5_kdc_rep": [[851, "krb5-kdc-rep"]], "krb5_kdc_req": [[852, "krb5-kdc-req"]], "krb5_key": [[853, "krb5-key"]], "krb5_keyblock": [[854, "krb5-keyblock"]], "krb5_keytab": [[855, "krb5-keytab"]], "krb5_keytab_entry": [[856, "krb5-keytab-entry"]], "krb5_keyusage": [[857, "krb5-keyusage"]], "krb5_kt_cursor": [[858, "krb5-kt-cursor"]], "krb5_kvno": [[859, "krb5-kvno"]], "krb5_last_req_entry": [[860, "krb5-last-req-entry"]], "krb5_magic": [[861, "krb5-magic"]], "krb5_mk_req_checksum_func": [[862, "krb5-mk-req-checksum-func"]], "krb5_msgtype": [[863, "krb5-msgtype"]], "krb5_octet": [[864, "krb5-octet"]], "krb5_pa_data": [[865, "krb5-pa-data"]], "krb5_pa_pac_req": [[866, "krb5-pa-pac-req"]], "krb5_pa_server_referral_data": [[867, "krb5-pa-server-referral-data"]], "krb5_pa_svr_referral_data": [[868, "krb5-pa-svr-referral-data"]], "krb5_pac": [[869, "krb5-pac"]], "krb5_pointer": [[870, "krb5-pointer"]], "krb5_post_recv_fn": [[871, "krb5-post-recv-fn"]], "krb5_pre_send_fn": [[872, "krb5-pre-send-fn"]], "krb5_preauthtype": [[873, "krb5-preauthtype"]], "krb5_principal": [[874, "krb5-principal"]], "krb5_principal_data": [[875, "krb5-principal-data"]], "krb5_prompt": [[876, "krb5-prompt"]], "krb5_prompt_type": [[877, "krb5-prompt-type"]], "krb5_prompter_fct": [[878, "krb5-prompter-fct"]], "krb5_pwd_data": [[879, "krb5-pwd-data"]], "krb5_rcache": [[880, "krb5-rcache"]], "krb5_replay_data": [[881, "krb5-replay-data"]], "krb5_responder_context": [[882, "krb5-responder-context"]], "krb5_responder_fn": [[883, "krb5-responder-fn"]], "krb5_responder_otp_challenge": [[884, "krb5-responder-otp-challenge"]], "krb5_responder_otp_tokeninfo": [[885, "krb5-responder-otp-tokeninfo"]], "krb5_responder_pkinit_challenge": [[886, "krb5-responder-pkinit-challenge"]], "krb5_responder_pkinit_identity": [[887, "krb5-responder-pkinit-identity"]], "krb5_response": [[888, "krb5-response"]], "krb5_ticket": [[889, "krb5-ticket"]], "krb5_ticket_times": [[890, "krb5-ticket-times"]], "krb5_timestamp": [[891, "krb5-timestamp"]], "krb5_tkt_authent": [[892, "krb5-tkt-authent"]], "krb5_tkt_creds_context": [[893, "krb5-tkt-creds-context"]], "krb5_trace_callback": [[894, "krb5-trace-callback"]], "krb5_trace_info": [[895, "krb5-trace-info"]], "krb5_transited": [[896, "krb5-transited"]], "krb5_typed_data": [[897, "krb5-typed-data"]], "krb5_ui_2": [[898, "krb5-ui-2"]], "krb5_ui_4": [[899, "krb5-ui-4"]], "krb5_verify_init_creds_opt": [[900, "krb5-verify-init-creds-opt"]], "passwd_phrase_element": [[901, "passwd-phrase-element"]], "Year 2038 considerations for uses of krb5_timestamp": [[902, "year-2038-considerations-for-uses-of-krb5-timestamp"]], "Credential cache": [[903, "credential-cache"]], "ccache types": [[903, "ccache-types"]], "Collections of caches": [[903, "collections-of-caches"]], "Tool alterations to use cache collection": [[903, "tool-alterations-to-use-cache-collection"]], "Default ccache name": [[903, "default-ccache-name"]], "Supported date and time formats": [[904, "supported-date-and-time-formats"]], "Time duration": [[904, "time-duration"]], "getdate time": [[904, "getdate-time"]], "Absolute time": [[904, "absolute-time"]], "Abbreviations used in this document": [[904, "abbreviations-used-in-this-document"]], "Kerberos V5 concepts": [[905, "kerberos-v5-concepts"]], "keytab": [[906, "keytab"]], "Default keytab": [[906, "default-keytab"]], "Default client keytab": [[906, "default-client-keytab"]], "replay cache": [[907, "replay-cache"]], "Background information": [[907, "background-information"]], "Replay cache types": [[907, "replay-cache-types"]], "Default replay cache name": [[907, "default-replay-cache-name"]], "stash file": [[908, "stash-file"]], "Organization of the source directory": [[909, "organization-of-the-source-directory"]], "lib": [[909, "lib"]], "util": [[909, "util"]], "Doing the build": [[910, "doing-the-build"]], "Building within a single tree": [[910, "building-within-a-single-tree"]], "Building with separate build directories": [[910, "building-with-separate-build-directories"]], "Building using lndir": [[910, "building-using-lndir"]], "Installing the binaries": [[910, "installing-the-binaries"]], "Testing the build": [[910, "testing-the-build"]], "Cleaning up the build": [[910, "cleaning-up-the-build"]], "Using autoconf": [[910, "using-autoconf"]], "Building Kerberos V5": [[911, "building-kerberos-v5"]], "Prerequisites": [[911, "prerequisites"]], "Obtaining the software": [[911, "obtaining-the-software"]], "Options to configure": [[912, "options-to-configure"]], "Most commonly used options": [[912, "most-commonly-used-options"]], "Fine tuning of the installation directories": [[912, "fine-tuning-of-the-installation-directories"]], "Program names": [[912, "program-names"]], "System types": [[912, "system-types"]], "Optional features": [[912, "optional-features"]], "Optional packages": [[912, "optional-packages"]], "Examples": [[912, "examples"]], "osconf.hin": [[913, "osconf-hin"]], "How to build this documentation from the source": [[914, "how-to-build-this-documentation-from-the-source"]], "Simple build without API reference": [[914, "simple-build-without-api-reference"]], "Updating man pages": [[914, "updating-man-pages"]], "Building for a release tarball or web site": [[914, "building-for-a-release-tarball-or-web-site"]], "Building for an OS package or site documentation": [[914, "building-for-an-os-package-or-site-documentation"]], "Copyright": [[915, "copyright"]], "Credential cache file format": [[916, "credential-cache-file-format"]], "Header format": [[916, "header-format"]], "Principal format": [[916, "principal-format"]], "Credential format": [[916, "credential-format"]], "Credential cache configuration entries": [[916, "credential-cache-configuration-entries"]], "KDC cookie format": [[917, "kdc-cookie-format"]], "Trivial cookie (version 0)": [[917, "trivial-cookie-version-0"]], "Secure cookie (version 1)": [[917, "secure-cookie-version-1"]], "SPAKE cookie format (version 1)": [[917, "spake-cookie-format-version-1"]], "Kerberos Database (KDB) Formats": [[918, "kerberos-database-kdb-formats"]], "Dump format": [[918, "dump-format"]], "Tag-length data formats": [[918, "tag-length-data-formats"]], "Per-principal kadmin data": [[918, "per-principal-kadmin-data"]], "Active kvno and master key auxiliary data": [[918, "active-kvno-and-master-key-auxiliary-data"]], "LDAP object information": [[918, "ldap-object-information"]], "Alias principal entries": [[918, "alias-principal-entries"]], "DB2 principal and policy formats": [[918, "db2-principal-and-policy-formats"]], "LMDB principal and policy formats": [[918, "lmdb-principal-and-policy-formats"]], "PKINIT freshness tokens": [[919, "pkinit-freshness-tokens"]], "Protocols and file formats": [[920, "protocols-and-file-formats"]], "Keytab file format": [[921, "keytab-file-format"]], "Key entry format": [[921, "key-entry-format"]], "Replay cache file format": [[922, "replay-cache-file-format"]], "MIT Kerberos Documentation (1.22.1)": [[923, "mit-kerberos-documentation-release"]], "MIT Kerberos defaults": [[924, "mit-kerberos-defaults"]], "General defaults": [[924, "general-defaults"]], "Replica KDC propagation defaults": [[924, "replica-kdc-propagation-defaults"]], "Default paths for Unix-like systems": [[924, "default-paths-for-unix-like-systems"]], "MIT Kerberos features": [[925, "mit-kerberos-features"]], "Quick facts": [[925, "quick-facts"]], "Interoperability": [[925, "interoperability"]], "Feature list": [[925, "feature-list"]], "MIT Kerberos License information": [[926, "mit-kerberos-license-information"]], "Credential cache selection interface (ccselect)": [[927, "credential-cache-selection-interface-ccselect"]], "PKINIT certificate authorization interface (certauth)": [[928, "pkinit-certificate-authorization-interface-certauth"]], "Client preauthentication interface (clpreauth)": [[929, "client-preauthentication-interface-clpreauth"]], "General plugin concepts": [[930, "general-plugin-concepts"]], "Logging from KDC and kadmind plugin modules": [[930, "logging-from-kdc-and-kadmind-plugin-modules"]], "GSSAPI mechanism interface": [[931, "gssapi-mechanism-interface"]], "NegoEx modules": [[931, "negoex-modules"]], "Interposer modules": [[931, "interposer-modules"]], "Host-to-realm interface (hostrealm)": [[932, "host-to-realm-interface-hostrealm"]], "For plugin module developers": [[933, "for-plugin-module-developers"]], "Internal pluggable interfaces": [[934, "internal-pluggable-interfaces"]], "Kerberos database interface (KDB)": [[934, "kerberos-database-interface-kdb"]], "Authorization data interface (authdata)": [[934, "authorization-data-interface-authdata"]], "kadmin authorization interface (kadm5_auth)": [[935, "kadmin-authorization-interface-kadm5-auth"]], "KADM5 hook interface (kadm5_hook)": [[936, "kadm5-hook-interface-kadm5-hook"]], "KDC policy interface (kdcpolicy)": [[937, "kdc-policy-interface-kdcpolicy"]], "KDC preauthentication interface (kdcpreauth)": [[938, "kdc-preauthentication-interface-kdcpreauth"]], "Local authorization interface (localauth)": [[939, "local-authorization-interface-localauth"]], "Server location interface (locate)": [[940, "server-location-interface-locate"]], "Configuration interface (profile)": [[941, "configuration-interface-profile"]], "Password quality interface (pwqual)": [[942, "password-quality-interface-pwqual"]], "Resources": [[943, "resources"]], "Mailing lists": [[943, "mailing-lists"]], "IRC channels": [[943, "irc-channels"]], "Archives": [[943, "archives"]], "Wiki": [[943, "wiki"]], "Web pages": [[943, "web-pages"]], "For users": [[944, "for-users"]], "Password management": [[945, "password-management"]], "Changing your password": [[945, "changing-your-password"]], "Granting access to your account": [[945, "granting-access-to-your-account"]], "Password quality verification": [[945, "password-quality-verification"]], "Ticket management": [[946, "ticket-management"]], "Kerberos ticket properties": [[946, "kerberos-ticket-properties"]], "Obtaining tickets with kinit": [[946, "obtaining-tickets-with-kinit"]], "Viewing tickets with klist": [[946, "viewing-tickets-with-klist"]], "Destroying tickets with kdestroy": [[946, "destroying-tickets-with-kdestroy"]], "User commands": [[947, "user-commands"]], "kdestroy": [[948, "kdestroy"]], "NOTE": [[948, "note"]], "kinit": [[949, "kinit"]], "klist": [[950, "klist"]], "kpasswd": [[951, "kpasswd"]], "krb5-config": [[952, "krb5-config"]], "EXAMPLES": [[952, "examples"], [959, "examples"]], "ksu": [[953, "ksu"]], "REQUIREMENTS": [[953, "requirements"]], "AUTHENTICATION": [[953, "authentication"]], "AUTHORIZATION": [[953, "authorization"]], "EXECUTION OF THE TARGET SHELL": [[953, "execution-of-the-target-shell"]], "CREATING A NEW SECURITY CONTEXT": [[953, "creating-a-new-security-context"]], "INSTALLATION INSTRUCTIONS": [[953, "installation-instructions"]], "SIDE EFFECTS": [[953, "side-effects"]], "AUTHOR OF KSU": [[953, "author-of-ksu"]], "kswitch": [[954, "kswitch"]], "kvno": [[955, "kvno"]], "sclient": [[956, "sclient"]], "User config files": [[957, "user-config-files"]], ".k5identity": [[958, "k5identity"]], ".k5login": [[959, "k5login"]], "kerberos": [[960, "kerberos"]], "ENVIRONMENT VARIABLES": [[960, "environment-variables"]], "BUGS": [[960, "bugs"]], "AUTHORS": [[960, "authors"]], "RESTRICTIONS": [[960, "restrictions"]]}, "indexentries": {"rfc": [[14, "index-0"], [20, "index-0"], [20, "index-1"], [21, "index-0"], [21, "index-1"], [21, "index-2"], [21, "index-3"], [21, "index-4"], [21, "index-5"], [21, "index-6"], [39, "index-0"], [39, "index-1"], [43, "index-0"], [43, "index-1"], [43, "index-2"], [43, "index-3"], [43, "index-4"], [43, "index-5"], [43, "index-6"], [907, "index-0"], [916, "index-0"], [916, "index-1"], [917, "index-0"], [917, "index-1"], [917, "index-2"], [917, "index-3"], [917, "index-4"], [918, "index-0"], [919, "index-0"], [919, "index-1"], [922, "index-0"], [925, "index-0"], [925, "index-1"], [925, "index-10"], [925, "index-11"], [925, "index-12"], [925, "index-13"], [925, "index-14"], [925, "index-15"], [925, "index-16"], [925, "index-2"], [925, "index-3"], [925, "index-4"], [925, "index-5"], [925, "index-6"], [925, "index-7"], [925, "index-8"], [925, "index-9"], [929, "index-0"], [929, "index-1"]], "rfc 6649": [[14, "index-0"]], "rfc 4556": [[20, "index-0"], [20, "index-1"], [21, "index-5"], [21, "index-6"], [925, "index-15"], [925, "index-3"]], "rfc 2253": [[21, "index-4"]], "rfc 5480": [[21, "index-1"], [21, "index-2"], [21, "index-3"]], "rfc 7748": [[21, "index-0"]], "rfc 2782": [[39, "index-0"]], "rfc 7553": [[39, "index-1"]], "rfc 2743": [[43, "index-0"]], "rfc 2744": [[43, "index-1"]], "rfc 4757": [[43, "index-6"]], "rfc 5280": [[43, "index-4"]], "rfc 6680": [[43, "index-5"], [925, "index-5"]], "rfc 6806": [[43, "index-3"], [916, "index-1"], [925, "index-2"]], "rfc 7546": [[43, "index-2"]], "krb5_425_conv_principal (c function)": [[49, "c.krb5_425_conv_principal"]], "krb5_524_conv_principal (c function)": [[50, "c.krb5_524_conv_principal"]], "krb5_524_convert_creds (c function)": [[51, "c.krb5_524_convert_creds"]], "krb5_address_compare (c function)": [[52, "c.krb5_address_compare"]], "krb5_address_order (c function)": [[53, "c.krb5_address_order"]], "krb5_address_search (c function)": [[54, "c.krb5_address_search"]], "krb5_allow_weak_crypto (c function)": [[55, "c.krb5_allow_weak_crypto"]], "krb5_aname_to_localname (c function)": [[56, "c.krb5_aname_to_localname"]], "krb5_anonymous_principal (c function)": [[57, "c.krb5_anonymous_principal"]], "krb5_anonymous_realm (c function)": [[58, "c.krb5_anonymous_realm"]], "krb5_appdefault_boolean (c function)": [[59, "c.krb5_appdefault_boolean"]], "krb5_appdefault_string (c function)": [[60, "c.krb5_appdefault_string"]], "krb5_auth_con_free (c function)": [[61, "c.krb5_auth_con_free"]], "krb5_auth_con_genaddrs (c function)": [[62, "c.krb5_auth_con_genaddrs"]], "krb5_auth_con_get_checksum_func (c function)": [[63, "c.krb5_auth_con_get_checksum_func"]], "krb5_auth_con_getaddrs (c function)": [[64, "c.krb5_auth_con_getaddrs"]], "krb5_auth_con_getauthenticator (c function)": [[65, "c.krb5_auth_con_getauthenticator"]], "krb5_auth_con_getflags (c function)": [[66, "c.krb5_auth_con_getflags"]], "krb5_auth_con_getkey (c function)": [[67, "c.krb5_auth_con_getkey"]], "krb5_auth_con_getkey_k (c function)": [[68, "c.krb5_auth_con_getkey_k"]], "krb5_auth_con_getlocalseqnumber (c function)": [[69, "c.krb5_auth_con_getlocalseqnumber"]], "krb5_auth_con_getlocalsubkey (c function)": [[70, "c.krb5_auth_con_getlocalsubkey"]], "krb5_auth_con_getrcache (c function)": [[71, "c.krb5_auth_con_getrcache"]], "krb5_auth_con_getrecvsubkey (c function)": [[72, "c.krb5_auth_con_getrecvsubkey"]], "krb5_auth_con_getrecvsubkey_k (c function)": [[73, "c.krb5_auth_con_getrecvsubkey_k"]], "krb5_auth_con_getremoteseqnumber (c function)": [[74, "c.krb5_auth_con_getremoteseqnumber"]], "krb5_auth_con_getremotesubkey (c function)": [[75, "c.krb5_auth_con_getremotesubkey"]], "krb5_auth_con_getsendsubkey (c function)": [[76, "c.krb5_auth_con_getsendsubkey"]], "krb5_auth_con_getsendsubkey_k (c function)": [[77, "c.krb5_auth_con_getsendsubkey_k"]], "krb5_auth_con_init (c function)": [[78, "c.krb5_auth_con_init"]], "krb5_auth_con_initivector (c function)": [[79, "c.krb5_auth_con_initivector"]], "krb5_auth_con_set_checksum_func (c function)": [[80, "c.krb5_auth_con_set_checksum_func"]], "krb5_auth_con_set_req_cksumtype (c function)": [[81, "c.krb5_auth_con_set_req_cksumtype"]], "krb5_auth_con_setaddrs (c function)": [[82, "c.krb5_auth_con_setaddrs"]], "krb5_auth_con_setflags (c function)": [[83, "c.krb5_auth_con_setflags"]], "krb5_auth_con_setports (c function)": [[84, "c.krb5_auth_con_setports"]], "krb5_auth_con_setrcache (c function)": [[85, "c.krb5_auth_con_setrcache"]], "krb5_auth_con_setrecvsubkey (c function)": [[86, "c.krb5_auth_con_setrecvsubkey"]], "krb5_auth_con_setrecvsubkey_k (c function)": [[87, "c.krb5_auth_con_setrecvsubkey_k"]], "krb5_auth_con_setsendsubkey (c function)": [[88, "c.krb5_auth_con_setsendsubkey"]], "krb5_auth_con_setsendsubkey_k (c function)": [[89, "c.krb5_auth_con_setsendsubkey_k"]], "krb5_auth_con_setuseruserkey (c function)": [[90, "c.krb5_auth_con_setuseruserkey"]], "krb5_build_principal (c function)": [[91, "c.krb5_build_principal"]], "krb5_build_principal_alloc_va (c function)": [[92, "c.krb5_build_principal_alloc_va"]], "krb5_build_principal_ext (c function)": [[93, "c.krb5_build_principal_ext"]], "krb5_build_principal_va (c function)": [[94, "c.krb5_build_principal_va"]], "krb5_c_block_size (c function)": [[95, "c.krb5_c_block_size"]], "krb5_c_checksum_length (c function)": [[96, "c.krb5_c_checksum_length"]], "krb5_c_crypto_length (c function)": [[97, "c.krb5_c_crypto_length"]], "krb5_c_crypto_length_iov (c function)": [[98, "c.krb5_c_crypto_length_iov"]], "krb5_c_decrypt (c function)": [[99, "c.krb5_c_decrypt"]], "krb5_c_decrypt_iov (c function)": [[100, "c.krb5_c_decrypt_iov"]], "krb5_c_derive_prfplus (c function)": [[101, "c.krb5_c_derive_prfplus"]], "krb5_c_encrypt (c function)": [[102, "c.krb5_c_encrypt"]], "krb5_c_encrypt_iov (c function)": [[103, "c.krb5_c_encrypt_iov"]], "krb5_c_encrypt_length (c function)": [[104, "c.krb5_c_encrypt_length"]], "krb5_c_enctype_compare (c function)": [[105, "c.krb5_c_enctype_compare"]], "krb5_c_free_state (c function)": [[106, "c.krb5_c_free_state"]], "krb5_c_fx_cf2_simple (c function)": [[107, "c.krb5_c_fx_cf2_simple"]], "krb5_c_init_state (c function)": [[108, "c.krb5_c_init_state"]], "krb5_c_is_coll_proof_cksum (c function)": [[109, "c.krb5_c_is_coll_proof_cksum"]], "krb5_c_is_keyed_cksum (c function)": [[110, "c.krb5_c_is_keyed_cksum"]], "krb5_c_keyed_checksum_types (c function)": [[111, "c.krb5_c_keyed_checksum_types"]], "krb5_c_keylengths (c function)": [[112, "c.krb5_c_keylengths"]], "krb5_c_make_checksum (c function)": [[113, "c.krb5_c_make_checksum"]], "krb5_c_make_checksum_iov (c function)": [[114, "c.krb5_c_make_checksum_iov"]], "krb5_c_make_random_key (c function)": [[115, "c.krb5_c_make_random_key"]], "krb5_c_padding_length (c function)": [[116, "c.krb5_c_padding_length"]], "krb5_c_prf (c function)": [[117, "c.krb5_c_prf"]], "krb5_c_prf_length (c function)": [[118, "c.krb5_c_prf_length"]], "krb5_c_prfplus (c function)": [[119, "c.krb5_c_prfplus"]], "krb5_c_random_add_entropy (c function)": [[120, "c.krb5_c_random_add_entropy"]], "krb5_c_random_make_octets (c function)": [[121, "c.krb5_c_random_make_octets"]], "krb5_c_random_os_entropy (c function)": [[122, "c.krb5_c_random_os_entropy"]], "krb5_c_random_seed (c function)": [[123, "c.krb5_c_random_seed"]], "krb5_c_random_to_key (c function)": [[124, "c.krb5_c_random_to_key"]], "krb5_c_string_to_key (c function)": [[125, "c.krb5_c_string_to_key"]], "krb5_c_string_to_key_with_params (c function)": [[126, "c.krb5_c_string_to_key_with_params"]], "krb5_c_valid_cksumtype (c function)": [[127, "c.krb5_c_valid_cksumtype"]], "krb5_c_valid_enctype (c function)": [[128, "c.krb5_c_valid_enctype"]], "krb5_c_verify_checksum (c function)": [[129, "c.krb5_c_verify_checksum"]], "krb5_c_verify_checksum_iov (c function)": [[130, "c.krb5_c_verify_checksum_iov"]], "krb5_calculate_checksum (c function)": [[131, "c.krb5_calculate_checksum"]], "krb5_cc_cache_match (c function)": [[132, "c.krb5_cc_cache_match"]], "krb5_cc_close (c function)": [[133, "c.krb5_cc_close"]], "krb5_cc_copy_creds (c function)": [[134, "c.krb5_cc_copy_creds"]], "krb5_cc_default (c function)": [[135, "c.krb5_cc_default"]], "krb5_cc_default_name (c function)": [[136, "c.krb5_cc_default_name"]], "krb5_cc_destroy (c function)": [[137, "c.krb5_cc_destroy"]], "krb5_cc_dup (c function)": [[138, "c.krb5_cc_dup"]], "krb5_cc_end_seq_get (c function)": [[139, "c.krb5_cc_end_seq_get"]], "krb5_cc_gen_new (c function)": [[140, "c.krb5_cc_gen_new"]], "krb5_cc_get_config (c function)": [[141, "c.krb5_cc_get_config"]], "krb5_cc_get_flags (c function)": [[142, "c.krb5_cc_get_flags"]], "krb5_cc_get_full_name (c function)": [[143, "c.krb5_cc_get_full_name"]], "krb5_cc_get_name (c function)": [[144, "c.krb5_cc_get_name"]], "krb5_cc_get_principal (c function)": [[145, "c.krb5_cc_get_principal"]], "krb5_cc_get_type (c function)": [[146, "c.krb5_cc_get_type"]], "krb5_cc_initialize (c function)": [[147, "c.krb5_cc_initialize"]], "krb5_cc_move (c function)": [[148, "c.krb5_cc_move"]], "krb5_cc_new_unique (c function)": [[149, "c.krb5_cc_new_unique"]], "krb5_cc_next_cred (c function)": [[150, "c.krb5_cc_next_cred"]], "krb5_cc_remove_cred (c function)": [[151, "c.krb5_cc_remove_cred"]], "krb5_cc_resolve (c function)": [[152, "c.krb5_cc_resolve"]], "krb5_cc_retrieve_cred (c function)": [[153, "c.krb5_cc_retrieve_cred"]], "krb5_cc_select (c function)": [[154, "c.krb5_cc_select"]], "krb5_cc_set_config (c function)": [[155, "c.krb5_cc_set_config"]], "krb5_cc_set_default_name (c function)": [[156, "c.krb5_cc_set_default_name"]], "krb5_cc_set_flags (c function)": [[157, "c.krb5_cc_set_flags"]], "krb5_cc_start_seq_get (c function)": [[158, "c.krb5_cc_start_seq_get"]], "krb5_cc_store_cred (c function)": [[159, "c.krb5_cc_store_cred"]], "krb5_cc_support_switch (c function)": [[160, "c.krb5_cc_support_switch"]], "krb5_cc_switch (c function)": [[161, "c.krb5_cc_switch"]], "krb5_cccol_cursor_free (c function)": [[162, "c.krb5_cccol_cursor_free"]], "krb5_cccol_cursor_new (c function)": [[163, "c.krb5_cccol_cursor_new"]], "krb5_cccol_cursor_next (c function)": [[164, "c.krb5_cccol_cursor_next"]], "krb5_cccol_have_content (c function)": [[165, "c.krb5_cccol_have_content"]], "krb5_change_password (c function)": [[166, "c.krb5_change_password"]], "krb5_check_clockskew (c function)": [[167, "c.krb5_check_clockskew"]], "krb5_checksum_size (c function)": [[168, "c.krb5_checksum_size"]], "krb5_chpw_message (c function)": [[169, "c.krb5_chpw_message"]], "krb5_cksumtype_to_string (c function)": [[170, "c.krb5_cksumtype_to_string"]], "krb5_clear_error_message (c function)": [[171, "c.krb5_clear_error_message"]], "krb5_copy_addresses (c function)": [[172, "c.krb5_copy_addresses"]], "krb5_copy_authdata (c function)": [[173, "c.krb5_copy_authdata"]], "krb5_copy_authenticator (c function)": [[174, "c.krb5_copy_authenticator"]], "krb5_copy_checksum (c function)": [[175, "c.krb5_copy_checksum"]], "krb5_copy_context (c function)": [[176, "c.krb5_copy_context"]], "krb5_copy_creds (c function)": [[177, "c.krb5_copy_creds"]], "krb5_copy_data (c function)": [[178, "c.krb5_copy_data"]], "krb5_copy_error_message (c function)": [[179, "c.krb5_copy_error_message"]], "krb5_copy_keyblock (c function)": [[180, "c.krb5_copy_keyblock"]], "krb5_copy_keyblock_contents (c function)": [[181, "c.krb5_copy_keyblock_contents"]], "krb5_copy_principal (c function)": [[182, "c.krb5_copy_principal"]], "krb5_copy_ticket (c function)": [[183, "c.krb5_copy_ticket"]], "krb5_decode_authdata_container (c function)": [[184, "c.krb5_decode_authdata_container"]], "krb5_decode_ticket (c function)": [[185, "c.krb5_decode_ticket"]], "krb5_decrypt (c function)": [[186, "c.krb5_decrypt"]], "krb5_deltat_to_string (c function)": [[187, "c.krb5_deltat_to_string"]], "krb5_eblock_enctype (c function)": [[188, "c.krb5_eblock_enctype"]], "krb5_encode_authdata_container (c function)": [[189, "c.krb5_encode_authdata_container"]], "krb5_encrypt (c function)": [[190, "c.krb5_encrypt"]], "krb5_encrypt_size (c function)": [[191, "c.krb5_encrypt_size"]], "krb5_enctype_to_name (c function)": [[192, "c.krb5_enctype_to_name"]], "krb5_enctype_to_string (c function)": [[193, "c.krb5_enctype_to_string"]], "krb5_expand_hostname (c function)": [[194, "c.krb5_expand_hostname"]], "krb5_find_authdata (c function)": [[195, "c.krb5_find_authdata"]], "krb5_finish_key (c function)": [[196, "c.krb5_finish_key"]], "krb5_finish_random_key (c function)": [[197, "c.krb5_finish_random_key"]], "krb5_free_addresses (c function)": [[198, "c.krb5_free_addresses"]], "krb5_free_ap_rep_enc_part (c function)": [[199, "c.krb5_free_ap_rep_enc_part"]], "krb5_free_authdata (c function)": [[200, "c.krb5_free_authdata"]], "krb5_free_authenticator (c function)": [[201, "c.krb5_free_authenticator"]], "krb5_free_checksum (c function)": [[202, "c.krb5_free_checksum"]], "krb5_free_checksum_contents (c function)": [[203, "c.krb5_free_checksum_contents"]], "krb5_free_cksumtypes (c function)": [[204, "c.krb5_free_cksumtypes"]], "krb5_free_config_files (c function)": [[205, "c.krb5_free_config_files"]], "krb5_free_context (c function)": [[206, "c.krb5_free_context"]], "krb5_free_cred_contents (c function)": [[207, "c.krb5_free_cred_contents"]], "krb5_free_creds (c function)": [[208, "c.krb5_free_creds"]], "krb5_free_data (c function)": [[209, "c.krb5_free_data"]], "krb5_free_data_contents (c function)": [[210, "c.krb5_free_data_contents"]], "krb5_free_default_realm (c function)": [[211, "c.krb5_free_default_realm"]], "krb5_free_enctypes (c function)": [[212, "c.krb5_free_enctypes"]], "krb5_free_error (c function)": [[213, "c.krb5_free_error"]], "krb5_free_error_message (c function)": [[214, "c.krb5_free_error_message"]], "krb5_free_host_realm (c function)": [[215, "c.krb5_free_host_realm"]], "krb5_free_keyblock (c function)": [[216, "c.krb5_free_keyblock"]], "krb5_free_keyblock_contents (c function)": [[217, "c.krb5_free_keyblock_contents"]], "krb5_free_keytab_entry_contents (c function)": [[218, "c.krb5_free_keytab_entry_contents"]], "krb5_free_principal (c function)": [[219, "c.krb5_free_principal"]], "krb5_free_string (c function)": [[220, "c.krb5_free_string"]], "krb5_free_tgt_creds (c function)": [[221, "c.krb5_free_tgt_creds"]], "krb5_free_ticket (c function)": [[222, "c.krb5_free_ticket"]], "krb5_free_unparsed_name (c function)": [[223, "c.krb5_free_unparsed_name"]], "krb5_fwd_tgt_creds (c function)": [[224, "c.krb5_fwd_tgt_creds"]], "krb5_get_credentials (c function)": [[225, "c.krb5_get_credentials"]], "krb5_get_credentials_renew (c function)": [[226, "c.krb5_get_credentials_renew"]], "krb5_get_credentials_validate (c function)": [[227, "c.krb5_get_credentials_validate"]], "krb5_get_default_config_files (c function)": [[228, "c.krb5_get_default_config_files"]], "krb5_get_default_realm (c function)": [[229, "c.krb5_get_default_realm"]], "krb5_get_error_message (c function)": [[230, "c.krb5_get_error_message"]], "krb5_get_etype_info (c function)": [[231, "c.krb5_get_etype_info"]], "krb5_get_fallback_host_realm (c function)": [[232, "c.krb5_get_fallback_host_realm"]], "krb5_get_host_realm (c function)": [[233, "c.krb5_get_host_realm"]], "krb5_get_in_tkt_with_keytab (c function)": [[234, "c.krb5_get_in_tkt_with_keytab"]], "krb5_get_in_tkt_with_password (c function)": [[235, "c.krb5_get_in_tkt_with_password"]], "krb5_get_in_tkt_with_skey (c function)": [[236, "c.krb5_get_in_tkt_with_skey"]], "krb5_get_init_creds_keytab (c function)": [[237, "c.krb5_get_init_creds_keytab"]], "krb5_get_init_creds_opt_alloc (c function)": [[238, "c.krb5_get_init_creds_opt_alloc"]], "krb5_get_init_creds_opt_free (c function)": [[239, "c.krb5_get_init_creds_opt_free"]], "krb5_get_init_creds_opt_get_fast_flags (c function)": [[240, "c.krb5_get_init_creds_opt_get_fast_flags"]], "krb5_get_init_creds_opt_init (c function)": [[241, "c.krb5_get_init_creds_opt_init"]], "krb5_get_init_creds_opt_set_address_list (c function)": [[242, "c.krb5_get_init_creds_opt_set_address_list"]], "krb5_get_init_creds_opt_set_anonymous (c function)": [[243, "c.krb5_get_init_creds_opt_set_anonymous"]], "krb5_get_init_creds_opt_set_canonicalize (c function)": [[244, "c.krb5_get_init_creds_opt_set_canonicalize"]], "krb5_get_init_creds_opt_set_change_password_prompt (c function)": [[245, "c.krb5_get_init_creds_opt_set_change_password_prompt"]], "krb5_get_init_creds_opt_set_etype_list (c function)": [[246, "c.krb5_get_init_creds_opt_set_etype_list"]], "krb5_get_init_creds_opt_set_expire_callback (c function)": [[247, "c.krb5_get_init_creds_opt_set_expire_callback"]], "krb5_get_init_creds_opt_set_fast_ccache (c function)": [[248, "c.krb5_get_init_creds_opt_set_fast_ccache"]], "krb5_get_init_creds_opt_set_fast_ccache_name (c function)": [[249, "c.krb5_get_init_creds_opt_set_fast_ccache_name"]], "krb5_get_init_creds_opt_set_fast_flags (c function)": [[250, "c.krb5_get_init_creds_opt_set_fast_flags"]], "krb5_get_init_creds_opt_set_forwardable (c function)": [[251, "c.krb5_get_init_creds_opt_set_forwardable"]], "krb5_get_init_creds_opt_set_in_ccache (c function)": [[252, "c.krb5_get_init_creds_opt_set_in_ccache"]], "krb5_get_init_creds_opt_set_out_ccache (c function)": [[253, "c.krb5_get_init_creds_opt_set_out_ccache"]], "krb5_get_init_creds_opt_set_pa (c function)": [[254, "c.krb5_get_init_creds_opt_set_pa"]], "krb5_get_init_creds_opt_set_pac_request (c function)": [[255, "c.krb5_get_init_creds_opt_set_pac_request"]], "krb5_get_init_creds_opt_set_preauth_list (c function)": [[256, "c.krb5_get_init_creds_opt_set_preauth_list"]], "krb5_get_init_creds_opt_set_proxiable (c function)": [[257, "c.krb5_get_init_creds_opt_set_proxiable"]], "krb5_get_init_creds_opt_set_renew_life (c function)": [[258, "c.krb5_get_init_creds_opt_set_renew_life"]], "krb5_get_init_creds_opt_set_responder (c function)": [[259, "c.krb5_get_init_creds_opt_set_responder"]], "krb5_get_init_creds_opt_set_salt (c function)": [[260, "c.krb5_get_init_creds_opt_set_salt"]], "krb5_get_init_creds_opt_set_tkt_life (c function)": [[261, "c.krb5_get_init_creds_opt_set_tkt_life"]], "krb5_get_init_creds_password (c function)": [[262, "c.krb5_get_init_creds_password"]], "krb5_get_permitted_enctypes (c function)": [[263, "c.krb5_get_permitted_enctypes"]], "krb5_get_profile (c function)": [[264, "c.krb5_get_profile"]], "krb5_get_prompt_types (c function)": [[265, "c.krb5_get_prompt_types"]], "krb5_get_renewed_creds (c function)": [[266, "c.krb5_get_renewed_creds"]], "krb5_get_server_rcache (c function)": [[267, "c.krb5_get_server_rcache"]], "krb5_get_time_offsets (c function)": [[268, "c.krb5_get_time_offsets"]], "krb5_get_validated_creds (c function)": [[269, "c.krb5_get_validated_creds"]], "krb5_init_context (c function)": [[270, "c.krb5_init_context"]], "krb5_init_context_profile (c function)": [[271, "c.krb5_init_context_profile"]], "krb5_init_creds_free (c function)": [[272, "c.krb5_init_creds_free"]], "krb5_init_creds_get (c function)": [[273, "c.krb5_init_creds_get"]], "krb5_init_creds_get_creds (c function)": [[274, "c.krb5_init_creds_get_creds"]], "krb5_init_creds_get_error (c function)": [[275, "c.krb5_init_creds_get_error"]], "krb5_init_creds_get_times (c function)": [[276, "c.krb5_init_creds_get_times"]], "krb5_init_creds_init (c function)": [[277, "c.krb5_init_creds_init"]], "krb5_init_creds_set_keytab (c function)": [[278, "c.krb5_init_creds_set_keytab"]], "krb5_init_creds_set_password (c function)": [[279, "c.krb5_init_creds_set_password"]], "krb5_init_creds_set_service (c function)": [[280, "c.krb5_init_creds_set_service"]], "krb5_init_creds_step (c function)": [[281, "c.krb5_init_creds_step"]], "krb5_init_keyblock (c function)": [[282, "c.krb5_init_keyblock"]], "krb5_init_random_key (c function)": [[283, "c.krb5_init_random_key"]], "krb5_init_secure_context (c function)": [[284, "c.krb5_init_secure_context"]], "krb5_is_config_principal (c function)": [[285, "c.krb5_is_config_principal"]], "krb5_is_referral_realm (c function)": [[286, "c.krb5_is_referral_realm"]], "krb5_is_thread_safe (c function)": [[287, "c.krb5_is_thread_safe"]], "krb5_k_create_key (c function)": [[288, "c.krb5_k_create_key"]], "krb5_k_decrypt (c function)": [[289, "c.krb5_k_decrypt"]], "krb5_k_decrypt_iov (c function)": [[290, "c.krb5_k_decrypt_iov"]], "krb5_k_encrypt (c function)": [[291, "c.krb5_k_encrypt"]], "krb5_k_encrypt_iov (c function)": [[292, "c.krb5_k_encrypt_iov"]], "krb5_k_free_key (c function)": [[293, "c.krb5_k_free_key"]], "krb5_k_key_enctype (c function)": [[294, "c.krb5_k_key_enctype"]], "krb5_k_key_keyblock (c function)": [[295, "c.krb5_k_key_keyblock"]], "krb5_k_make_checksum (c function)": [[296, "c.krb5_k_make_checksum"]], "krb5_k_make_checksum_iov (c function)": [[297, "c.krb5_k_make_checksum_iov"]], "krb5_k_prf (c function)": [[298, "c.krb5_k_prf"]], "krb5_k_reference_key (c function)": [[299, "c.krb5_k_reference_key"]], "krb5_k_verify_checksum (c function)": [[300, "c.krb5_k_verify_checksum"]], "krb5_k_verify_checksum_iov (c function)": [[301, "c.krb5_k_verify_checksum_iov"]], "krb5_kdc_sign_ticket (c function)": [[302, "c.krb5_kdc_sign_ticket"]], "krb5_kdc_verify_ticket (c function)": [[303, "c.krb5_kdc_verify_ticket"]], "krb5_kt_add_entry (c function)": [[304, "c.krb5_kt_add_entry"]], "krb5_kt_client_default (c function)": [[305, "c.krb5_kt_client_default"]], "krb5_kt_close (c function)": [[306, "c.krb5_kt_close"]], "krb5_kt_default (c function)": [[307, "c.krb5_kt_default"]], "krb5_kt_default_name (c function)": [[308, "c.krb5_kt_default_name"]], "krb5_kt_dup (c function)": [[309, "c.krb5_kt_dup"]], "krb5_kt_end_seq_get (c function)": [[310, "c.krb5_kt_end_seq_get"]], "krb5_kt_free_entry (c function)": [[311, "c.krb5_kt_free_entry"]], "krb5_kt_get_entry (c function)": [[312, "c.krb5_kt_get_entry"]], "krb5_kt_get_name (c function)": [[313, "c.krb5_kt_get_name"]], "krb5_kt_get_type (c function)": [[314, "c.krb5_kt_get_type"]], "krb5_kt_have_content (c function)": [[315, "c.krb5_kt_have_content"]], "krb5_kt_next_entry (c function)": [[316, "c.krb5_kt_next_entry"]], "krb5_kt_read_service_key (c function)": [[317, "c.krb5_kt_read_service_key"]], "krb5_kt_remove_entry (c function)": [[318, "c.krb5_kt_remove_entry"]], "krb5_kt_resolve (c function)": [[319, "c.krb5_kt_resolve"]], "krb5_kt_start_seq_get (c function)": [[320, "c.krb5_kt_start_seq_get"]], "krb5_kuserok (c function)": [[321, "c.krb5_kuserok"]], "krb5_make_authdata_kdc_issued (c function)": [[322, "c.krb5_make_authdata_kdc_issued"]], "krb5_marshal_credentials (c function)": [[323, "c.krb5_marshal_credentials"]], "krb5_merge_authdata (c function)": [[324, "c.krb5_merge_authdata"]], "krb5_mk_1cred (c function)": [[325, "c.krb5_mk_1cred"]], "krb5_mk_error (c function)": [[326, "c.krb5_mk_error"]], "krb5_mk_ncred (c function)": [[327, "c.krb5_mk_ncred"]], "krb5_mk_priv (c function)": [[328, "c.krb5_mk_priv"]], "krb5_mk_rep (c function)": [[329, "c.krb5_mk_rep"]], "krb5_mk_rep_dce (c function)": [[330, "c.krb5_mk_rep_dce"]], "krb5_mk_req (c function)": [[331, "c.krb5_mk_req"]], "krb5_mk_req_extended (c function)": [[332, "c.krb5_mk_req_extended"]], "krb5_mk_safe (c function)": [[333, "c.krb5_mk_safe"]], "krb5_os_localaddr (c function)": [[334, "c.krb5_os_localaddr"]], "krb5_pac_add_buffer (c function)": [[335, "c.krb5_pac_add_buffer"]], "krb5_pac_free (c function)": [[336, "c.krb5_pac_free"]], "krb5_pac_get_buffer (c function)": [[337, "c.krb5_pac_get_buffer"]], "krb5_pac_get_client_info (c function)": [[338, "c.krb5_pac_get_client_info"]], "krb5_pac_get_types (c function)": [[339, "c.krb5_pac_get_types"]], "krb5_pac_init (c function)": [[340, "c.krb5_pac_init"]], "krb5_pac_parse (c function)": [[341, "c.krb5_pac_parse"]], "krb5_pac_sign (c function)": [[342, "c.krb5_pac_sign"]], "krb5_pac_sign_ext (c function)": [[343, "c.krb5_pac_sign_ext"]], "krb5_pac_verify (c function)": [[344, "c.krb5_pac_verify"]], "krb5_pac_verify_ext (c function)": [[345, "c.krb5_pac_verify_ext"]], "krb5_parse_name (c function)": [[346, "c.krb5_parse_name"]], "krb5_parse_name_flags (c function)": [[347, "c.krb5_parse_name_flags"]], "krb5_prepend_error_message (c function)": [[348, "c.krb5_prepend_error_message"]], "krb5_principal2salt (c function)": [[349, "c.krb5_principal2salt"]], "krb5_principal_compare (c function)": [[350, "c.krb5_principal_compare"]], "krb5_principal_compare_any_realm (c function)": [[351, "c.krb5_principal_compare_any_realm"]], "krb5_principal_compare_flags (c function)": [[352, "c.krb5_principal_compare_flags"]], "krb5_process_key (c function)": [[353, "c.krb5_process_key"]], "krb5_prompter_posix (c function)": [[354, "c.krb5_prompter_posix"]], "krb5_random_key (c function)": [[355, "c.krb5_random_key"]], "krb5_rd_cred (c function)": [[356, "c.krb5_rd_cred"]], "krb5_rd_error (c function)": [[357, "c.krb5_rd_error"]], "krb5_rd_priv (c function)": [[358, "c.krb5_rd_priv"]], "krb5_rd_rep (c function)": [[359, "c.krb5_rd_rep"]], "krb5_rd_rep_dce (c function)": [[360, "c.krb5_rd_rep_dce"]], "krb5_rd_req (c function)": [[361, "c.krb5_rd_req"]], "krb5_rd_safe (c function)": [[362, "c.krb5_rd_safe"]], "krb5_read_password (c function)": [[363, "c.krb5_read_password"]], "krb5_realm_compare (c function)": [[364, "c.krb5_realm_compare"]], "krb5_recvauth (c function)": [[365, "c.krb5_recvauth"]], "krb5_recvauth_version (c function)": [[366, "c.krb5_recvauth_version"]], "krb5_responder_get_challenge (c function)": [[367, "c.krb5_responder_get_challenge"]], "krb5_responder_list_questions (c function)": [[368, "c.krb5_responder_list_questions"]], "krb5_responder_otp_challenge_free (c function)": [[369, "c.krb5_responder_otp_challenge_free"]], "krb5_responder_otp_get_challenge (c function)": [[370, "c.krb5_responder_otp_get_challenge"]], "krb5_responder_otp_set_answer (c function)": [[371, "c.krb5_responder_otp_set_answer"]], "krb5_responder_pkinit_challenge_free (c function)": [[372, "c.krb5_responder_pkinit_challenge_free"]], "krb5_responder_pkinit_get_challenge (c function)": [[373, "c.krb5_responder_pkinit_get_challenge"]], "krb5_responder_pkinit_set_answer (c function)": [[374, "c.krb5_responder_pkinit_set_answer"]], "krb5_responder_set_answer (c function)": [[375, "c.krb5_responder_set_answer"]], "krb5_salttype_to_string (c function)": [[376, "c.krb5_salttype_to_string"]], "krb5_sendauth (c function)": [[377, "c.krb5_sendauth"]], "krb5_server_decrypt_ticket_keytab (c function)": [[378, "c.krb5_server_decrypt_ticket_keytab"]], "krb5_set_default_realm (c function)": [[379, "c.krb5_set_default_realm"]], "krb5_set_default_tgs_enctypes (c function)": [[380, "c.krb5_set_default_tgs_enctypes"]], "krb5_set_error_message (c function)": [[381, "c.krb5_set_error_message"]], "krb5_set_kdc_recv_hook (c function)": [[382, "c.krb5_set_kdc_recv_hook"]], "krb5_set_kdc_send_hook (c function)": [[383, "c.krb5_set_kdc_send_hook"]], "krb5_set_password (c function)": [[384, "c.krb5_set_password"]], "krb5_set_password_using_ccache (c function)": [[385, "c.krb5_set_password_using_ccache"]], "krb5_set_principal_realm (c function)": [[386, "c.krb5_set_principal_realm"]], "krb5_set_real_time (c function)": [[387, "c.krb5_set_real_time"]], "krb5_set_trace_callback (c function)": [[388, "c.krb5_set_trace_callback"]], "krb5_set_trace_filename (c function)": [[389, "c.krb5_set_trace_filename"]], "krb5_sname_match (c function)": [[390, "c.krb5_sname_match"]], "krb5_sname_to_principal (c function)": [[391, "c.krb5_sname_to_principal"]], "krb5_string_to_cksumtype (c function)": [[392, "c.krb5_string_to_cksumtype"]], "krb5_string_to_deltat (c function)": [[393, "c.krb5_string_to_deltat"]], "krb5_string_to_enctype (c function)": [[394, "c.krb5_string_to_enctype"]], "krb5_string_to_key (c function)": [[395, "c.krb5_string_to_key"]], "krb5_string_to_salttype (c function)": [[396, "c.krb5_string_to_salttype"]], "krb5_string_to_timestamp (c function)": [[397, "c.krb5_string_to_timestamp"]], "krb5_timeofday (c function)": [[398, "c.krb5_timeofday"]], "krb5_timestamp_to_sfstring (c function)": [[399, "c.krb5_timestamp_to_sfstring"]], "krb5_timestamp_to_string (c function)": [[400, "c.krb5_timestamp_to_string"]], "krb5_tkt_creds_free (c function)": [[401, "c.krb5_tkt_creds_free"]], "krb5_tkt_creds_get (c function)": [[402, "c.krb5_tkt_creds_get"]], "krb5_tkt_creds_get_creds (c function)": [[403, "c.krb5_tkt_creds_get_creds"]], "krb5_tkt_creds_get_times (c function)": [[404, "c.krb5_tkt_creds_get_times"]], "krb5_tkt_creds_init (c function)": [[405, "c.krb5_tkt_creds_init"]], "krb5_tkt_creds_step (c function)": [[406, "c.krb5_tkt_creds_step"]], "krb5_unmarshal_credentials (c function)": [[407, "c.krb5_unmarshal_credentials"]], "krb5_unparse_name (c function)": [[408, "c.krb5_unparse_name"]], "krb5_unparse_name_ext (c function)": [[409, "c.krb5_unparse_name_ext"]], "krb5_unparse_name_flags (c function)": [[410, "c.krb5_unparse_name_flags"]], "krb5_unparse_name_flags_ext (c function)": [[411, "c.krb5_unparse_name_flags_ext"]], "krb5_us_timeofday (c function)": [[412, "c.krb5_us_timeofday"]], "krb5_use_enctype (c function)": [[413, "c.krb5_use_enctype"]], "krb5_verify_authdata_kdc_issued (c function)": [[414, "c.krb5_verify_authdata_kdc_issued"]], "krb5_verify_checksum (c function)": [[415, "c.krb5_verify_checksum"]], "krb5_verify_init_creds (c function)": [[416, "c.krb5_verify_init_creds"]], "krb5_verify_init_creds_opt_init (c function)": [[417, "c.krb5_verify_init_creds_opt_init"]], "krb5_verify_init_creds_opt_set_ap_req_nofail (c function)": [[418, "c.krb5_verify_init_creds_opt_set_ap_req_nofail"]], "krb5_vprepend_error_message (c function)": [[419, "c.krb5_vprepend_error_message"]], "krb5_vset_error_message (c function)": [[420, "c.krb5_vset_error_message"]], "krb5_vwrap_error_message (c function)": [[421, "c.krb5_vwrap_error_message"]], "krb5_wrap_error_message (c function)": [[422, "c.krb5_wrap_error_message"]], "addrtype_addrport (built-in variable)": [[424, "ADDRTYPE_ADDRPORT"]], "addrtype_chaos (built-in variable)": [[425, "ADDRTYPE_CHAOS"]], "addrtype_ddp (built-in variable)": [[426, "ADDRTYPE_DDP"]], "addrtype_directional (built-in variable)": [[427, "ADDRTYPE_DIRECTIONAL"]], "addrtype_inet (built-in variable)": [[428, "ADDRTYPE_INET"]], "addrtype_inet6 (built-in variable)": [[429, "ADDRTYPE_INET6"]], "addrtype_ipport (built-in variable)": [[430, "ADDRTYPE_IPPORT"]], "addrtype_iso (built-in variable)": [[431, "ADDRTYPE_ISO"]], "addrtype_is_local (built-in variable)": [[432, "ADDRTYPE_IS_LOCAL"]], "addrtype_netbios (built-in variable)": [[433, "ADDRTYPE_NETBIOS"]], "addrtype_unixsock (built-in variable)": [[434, "ADDRTYPE_UNIXSOCK"]], "addrtype_xns (built-in variable)": [[435, "ADDRTYPE_XNS"]], "ad_type_external (built-in variable)": [[436, "AD_TYPE_EXTERNAL"]], "ad_type_field_type_mask (built-in variable)": [[437, "AD_TYPE_FIELD_TYPE_MASK"]], "ad_type_registered (built-in variable)": [[438, "AD_TYPE_REGISTERED"]], "ad_type_reserved (built-in variable)": [[439, "AD_TYPE_RESERVED"]], "ap_opts_cbt_flag (built-in variable)": [[440, "AP_OPTS_CBT_FLAG"]], "ap_opts_etype_negotiation (built-in variable)": [[441, "AP_OPTS_ETYPE_NEGOTIATION"]], "ap_opts_mutual_required (built-in variable)": [[442, "AP_OPTS_MUTUAL_REQUIRED"]], "ap_opts_reserved (built-in variable)": [[443, "AP_OPTS_RESERVED"]], "ap_opts_use_session_key (built-in variable)": [[444, "AP_OPTS_USE_SESSION_KEY"]], "ap_opts_use_subkey (built-in variable)": [[445, "AP_OPTS_USE_SUBKEY"]], "ap_opts_wire_mask (built-in variable)": [[446, "AP_OPTS_WIRE_MASK"]], "cksumtype_cmac_camellia128 (built-in variable)": [[447, "CKSUMTYPE_CMAC_CAMELLIA128"]], "cksumtype_cmac_camellia256 (built-in variable)": [[448, "CKSUMTYPE_CMAC_CAMELLIA256"]], "cksumtype_crc32 (built-in variable)": [[449, "CKSUMTYPE_CRC32"]], "cksumtype_descbc (built-in variable)": [[450, "CKSUMTYPE_DESCBC"]], "cksumtype_hmac_md5_arcfour (built-in variable)": [[451, "CKSUMTYPE_HMAC_MD5_ARCFOUR"]], "cksumtype_hmac_sha1_96_aes128 (built-in variable)": [[452, "CKSUMTYPE_HMAC_SHA1_96_AES128"]], "cksumtype_hmac_sha1_96_aes256 (built-in variable)": [[453, "CKSUMTYPE_HMAC_SHA1_96_AES256"]], "cksumtype_hmac_sha1_des3 (built-in variable)": [[454, "CKSUMTYPE_HMAC_SHA1_DES3"]], "cksumtype_hmac_sha256_128_aes128 (built-in variable)": [[455, "CKSUMTYPE_HMAC_SHA256_128_AES128"]], "cksumtype_hmac_sha384_192_aes256 (built-in variable)": [[456, "CKSUMTYPE_HMAC_SHA384_192_AES256"]], "cksumtype_md5_hmac_arcfour (built-in variable)": [[457, "CKSUMTYPE_MD5_HMAC_ARCFOUR"]], "cksumtype_nist_sha (built-in variable)": [[458, "CKSUMTYPE_NIST_SHA"]], "cksumtype_rsa_md4 (built-in variable)": [[459, "CKSUMTYPE_RSA_MD4"]], "cksumtype_rsa_md4_des (built-in variable)": [[460, "CKSUMTYPE_RSA_MD4_DES"]], "cksumtype_rsa_md5 (built-in variable)": [[461, "CKSUMTYPE_RSA_MD5"]], "cksumtype_rsa_md5_des (built-in variable)": [[462, "CKSUMTYPE_RSA_MD5_DES"]], "cksumtype_sha1 (built-in variable)": [[463, "CKSUMTYPE_SHA1"]], "enctype_aes128_cts_hmac_sha1_96 (built-in variable)": [[464, "ENCTYPE_AES128_CTS_HMAC_SHA1_96"]], "enctype_aes128_cts_hmac_sha256_128 (built-in variable)": [[465, "ENCTYPE_AES128_CTS_HMAC_SHA256_128"]], "enctype_aes256_cts_hmac_sha1_96 (built-in variable)": [[466, "ENCTYPE_AES256_CTS_HMAC_SHA1_96"]], "enctype_aes256_cts_hmac_sha384_192 (built-in variable)": [[467, "ENCTYPE_AES256_CTS_HMAC_SHA384_192"]], "enctype_arcfour_hmac (built-in variable)": [[468, "ENCTYPE_ARCFOUR_HMAC"]], "enctype_arcfour_hmac_exp (built-in variable)": [[469, "ENCTYPE_ARCFOUR_HMAC_EXP"]], "enctype_camellia128_cts_cmac (built-in variable)": [[470, "ENCTYPE_CAMELLIA128_CTS_CMAC"]], "enctype_camellia256_cts_cmac (built-in variable)": [[471, "ENCTYPE_CAMELLIA256_CTS_CMAC"]], "enctype_des3_cbc_env (built-in variable)": [[472, "ENCTYPE_DES3_CBC_ENV"]], "enctype_des3_cbc_raw (built-in variable)": [[473, "ENCTYPE_DES3_CBC_RAW"]], "enctype_des3_cbc_sha (built-in variable)": [[474, "ENCTYPE_DES3_CBC_SHA"]], "enctype_des3_cbc_sha1 (built-in variable)": [[475, "ENCTYPE_DES3_CBC_SHA1"]], "enctype_des_cbc_crc (built-in variable)": [[476, "ENCTYPE_DES_CBC_CRC"]], "enctype_des_cbc_md4 (built-in variable)": [[477, "ENCTYPE_DES_CBC_MD4"]], "enctype_des_cbc_md5 (built-in variable)": [[478, "ENCTYPE_DES_CBC_MD5"]], "enctype_des_cbc_raw (built-in variable)": [[479, "ENCTYPE_DES_CBC_RAW"]], "enctype_des_hmac_sha1 (built-in variable)": [[480, "ENCTYPE_DES_HMAC_SHA1"]], "enctype_dsa_sha1_cms (built-in variable)": [[481, "ENCTYPE_DSA_SHA1_CMS"]], "enctype_md5_rsa_cms (built-in variable)": [[482, "ENCTYPE_MD5_RSA_CMS"]], "enctype_null (built-in variable)": [[483, "ENCTYPE_NULL"]], "enctype_rc2_cbc_env (built-in variable)": [[484, "ENCTYPE_RC2_CBC_ENV"]], "enctype_rsa_env (built-in variable)": [[485, "ENCTYPE_RSA_ENV"]], "enctype_rsa_es_oaep_env (built-in variable)": [[486, "ENCTYPE_RSA_ES_OAEP_ENV"]], "enctype_sha1_rsa_cms (built-in variable)": [[487, "ENCTYPE_SHA1_RSA_CMS"]], "enctype_unknown (built-in variable)": [[488, "ENCTYPE_UNKNOWN"]], "kdc_opt_allow_postdate (built-in variable)": [[489, "KDC_OPT_ALLOW_POSTDATE"]], "kdc_opt_canonicalize (built-in variable)": [[490, "KDC_OPT_CANONICALIZE"]], "kdc_opt_cname_in_addl_tkt (built-in variable)": [[491, "KDC_OPT_CNAME_IN_ADDL_TKT"]], "kdc_opt_disable_transited_check (built-in variable)": [[492, "KDC_OPT_DISABLE_TRANSITED_CHECK"]], "kdc_opt_enc_tkt_in_skey (built-in variable)": [[493, "KDC_OPT_ENC_TKT_IN_SKEY"]], "kdc_opt_forwardable (built-in variable)": [[494, "KDC_OPT_FORWARDABLE"]], "kdc_opt_forwarded (built-in variable)": [[495, "KDC_OPT_FORWARDED"]], "kdc_opt_postdated (built-in variable)": [[496, "KDC_OPT_POSTDATED"]], "kdc_opt_proxiable (built-in variable)": [[497, "KDC_OPT_PROXIABLE"]], "kdc_opt_proxy (built-in variable)": [[498, "KDC_OPT_PROXY"]], "kdc_opt_renew (built-in variable)": [[499, "KDC_OPT_RENEW"]], "kdc_opt_renewable (built-in variable)": [[500, "KDC_OPT_RENEWABLE"]], "kdc_opt_renewable_ok (built-in variable)": [[501, "KDC_OPT_RENEWABLE_OK"]], "kdc_opt_request_anonymous (built-in variable)": [[502, "KDC_OPT_REQUEST_ANONYMOUS"]], "kdc_opt_validate (built-in variable)": [[503, "KDC_OPT_VALIDATE"]], "kdc_tkt_common_mask (built-in variable)": [[504, "KDC_TKT_COMMON_MASK"]], "krb5_altauth_att_challenge_response (built-in variable)": [[505, "KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE"]], "krb5_anonymous_princstr (built-in variable)": [[506, "KRB5_ANONYMOUS_PRINCSTR"]], "krb5_anonymous_realmstr (built-in variable)": [[507, "KRB5_ANONYMOUS_REALMSTR"]], "krb5_ap_rep (built-in variable)": [[508, "KRB5_AP_REP"]], "krb5_ap_req (built-in variable)": [[509, "KRB5_AP_REQ"]], "krb5_as_rep (built-in variable)": [[510, "KRB5_AS_REP"]], "krb5_as_req (built-in variable)": [[511, "KRB5_AS_REQ"]], "krb5_authdata_and_or (built-in variable)": [[512, "KRB5_AUTHDATA_AND_OR"]], "krb5_authdata_ap_options (built-in variable)": [[513, "KRB5_AUTHDATA_AP_OPTIONS"]], "krb5_authdata_auth_indicator (built-in variable)": [[514, "KRB5_AUTHDATA_AUTH_INDICATOR"]], "krb5_authdata_cammac (built-in variable)": [[515, "KRB5_AUTHDATA_CAMMAC"]], "krb5_authdata_etype_negotiation (built-in variable)": [[516, "KRB5_AUTHDATA_ETYPE_NEGOTIATION"]], "krb5_authdata_fx_armor (built-in variable)": [[517, "KRB5_AUTHDATA_FX_ARMOR"]], "krb5_authdata_if_relevant (built-in variable)": [[518, "KRB5_AUTHDATA_IF_RELEVANT"]], "krb5_authdata_initial_verified_cas (built-in variable)": [[519, "KRB5_AUTHDATA_INITIAL_VERIFIED_CAS"]], "krb5_authdata_kdc_issued (built-in variable)": [[520, "KRB5_AUTHDATA_KDC_ISSUED"]], "krb5_authdata_mandatory_for_kdc (built-in variable)": [[521, "KRB5_AUTHDATA_MANDATORY_FOR_KDC"]], "krb5_authdata_osf_dce (built-in variable)": [[522, "KRB5_AUTHDATA_OSF_DCE"]], "krb5_authdata_sesame (built-in variable)": [[523, "KRB5_AUTHDATA_SESAME"]], "krb5_authdata_signticket (built-in variable)": [[524, "KRB5_AUTHDATA_SIGNTICKET"]], "krb5_authdata_win2k_pac (built-in variable)": [[525, "KRB5_AUTHDATA_WIN2K_PAC"]], "krb5_auth_context_do_sequence (built-in variable)": [[526, "KRB5_AUTH_CONTEXT_DO_SEQUENCE"]], "krb5_auth_context_do_time (built-in variable)": [[527, "KRB5_AUTH_CONTEXT_DO_TIME"]], "krb5_auth_context_generate_local_addr (built-in variable)": [[528, "KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR"]], "krb5_auth_context_generate_local_full_addr (built-in variable)": [[529, "KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR"]], "krb5_auth_context_generate_remote_addr (built-in variable)": [[530, "KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR"]], "krb5_auth_context_generate_remote_full_addr (built-in variable)": [[531, "KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR"]], "krb5_auth_context_permit_all (built-in variable)": [[532, "KRB5_AUTH_CONTEXT_PERMIT_ALL"]], "krb5_auth_context_ret_sequence (built-in variable)": [[533, "KRB5_AUTH_CONTEXT_RET_SEQUENCE"]], "krb5_auth_context_ret_time (built-in variable)": [[534, "KRB5_AUTH_CONTEXT_RET_TIME"]], "krb5_auth_context_use_subkey (built-in variable)": [[535, "KRB5_AUTH_CONTEXT_USE_SUBKEY"]], "krb5_cred (built-in variable)": [[536, "KRB5_CRED"]], "krb5_crypto_type_checksum (built-in variable)": [[537, "KRB5_CRYPTO_TYPE_CHECKSUM"]], "krb5_crypto_type_data (built-in variable)": [[538, "KRB5_CRYPTO_TYPE_DATA"]], "krb5_crypto_type_empty (built-in variable)": [[539, "KRB5_CRYPTO_TYPE_EMPTY"]], "krb5_crypto_type_header (built-in variable)": [[540, "KRB5_CRYPTO_TYPE_HEADER"]], "krb5_crypto_type_padding (built-in variable)": [[541, "KRB5_CRYPTO_TYPE_PADDING"]], "krb5_crypto_type_sign_only (built-in variable)": [[542, "KRB5_CRYPTO_TYPE_SIGN_ONLY"]], "krb5_crypto_type_stream (built-in variable)": [[543, "KRB5_CRYPTO_TYPE_STREAM"]], "krb5_crypto_type_trailer (built-in variable)": [[544, "KRB5_CRYPTO_TYPE_TRAILER"]], "krb5_cybersafe_secureid (built-in variable)": [[545, "KRB5_CYBERSAFE_SECUREID"]], "krb5_domain_x500_compress (built-in variable)": [[546, "KRB5_DOMAIN_X500_COMPRESS"]], "krb5_encpadata_req_enc_pa_rep (built-in variable)": [[547, "KRB5_ENCPADATA_REQ_ENC_PA_REP"]], "krb5_error (built-in variable)": [[548, "KRB5_ERROR"]], "krb5_fast_required (built-in variable)": [[549, "KRB5_FAST_REQUIRED"]], "krb5_gc_cached (built-in variable)": [[550, "KRB5_GC_CACHED"]], "krb5_gc_canonicalize (built-in variable)": [[551, "KRB5_GC_CANONICALIZE"]], "krb5_gc_constrained_delegation (built-in variable)": [[552, "KRB5_GC_CONSTRAINED_DELEGATION"]], "krb5_gc_forwardable (built-in variable)": [[553, "KRB5_GC_FORWARDABLE"]], "krb5_gc_no_store (built-in variable)": [[554, "KRB5_GC_NO_STORE"]], "krb5_gc_no_transit_check (built-in variable)": [[555, "KRB5_GC_NO_TRANSIT_CHECK"]], "krb5_gc_user_user (built-in variable)": [[556, "KRB5_GC_USER_USER"]], "krb5_get_init_creds_opt_address_list (built-in variable)": [[557, "KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST"]], "krb5_get_init_creds_opt_anonymous (built-in variable)": [[558, "KRB5_GET_INIT_CREDS_OPT_ANONYMOUS"]], "krb5_get_init_creds_opt_canonicalize (built-in variable)": [[559, "KRB5_GET_INIT_CREDS_OPT_CANONICALIZE"]], "krb5_get_init_creds_opt_chg_pwd_prmpt (built-in variable)": [[560, "KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT"]], "krb5_get_init_creds_opt_etype_list (built-in variable)": [[561, "KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST"]], "krb5_get_init_creds_opt_forwardable (built-in variable)": [[562, "KRB5_GET_INIT_CREDS_OPT_FORWARDABLE"]], "krb5_get_init_creds_opt_preauth_list (built-in variable)": [[563, "KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST"]], "krb5_get_init_creds_opt_proxiable (built-in variable)": [[564, "KRB5_GET_INIT_CREDS_OPT_PROXIABLE"]], "krb5_get_init_creds_opt_renew_life (built-in variable)": [[565, "KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE"]], "krb5_get_init_creds_opt_salt (built-in variable)": [[566, "KRB5_GET_INIT_CREDS_OPT_SALT"]], "krb5_get_init_creds_opt_tkt_life (built-in variable)": [[567, "KRB5_GET_INIT_CREDS_OPT_TKT_LIFE"]], "krb5_init_context_kdc (built-in variable)": [[568, "KRB5_INIT_CONTEXT_KDC"]], "krb5_init_context_secure (built-in variable)": [[569, "KRB5_INIT_CONTEXT_SECURE"]], "krb5_init_creds_step_flag_continue (built-in variable)": [[570, "KRB5_INIT_CREDS_STEP_FLAG_CONTINUE"]], "krb5_int16_max (built-in variable)": [[571, "KRB5_INT16_MAX"]], "krb5_int16_min (built-in variable)": [[572, "KRB5_INT16_MIN"]], "krb5_int32_max (built-in variable)": [[573, "KRB5_INT32_MAX"]], "krb5_int32_min (built-in variable)": [[574, "KRB5_INT32_MIN"]], "krb5_keyusage_ad_ite (built-in variable)": [[575, "KRB5_KEYUSAGE_AD_ITE"]], "krb5_keyusage_ad_kdcissued_cksum (built-in variable)": [[576, "KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM"]], "krb5_keyusage_ad_mte (built-in variable)": [[577, "KRB5_KEYUSAGE_AD_MTE"]], "krb5_keyusage_ad_signedpath (built-in variable)": [[578, "KRB5_KEYUSAGE_AD_SIGNEDPATH"]], "krb5_keyusage_app_data_cksum (built-in variable)": [[579, "KRB5_KEYUSAGE_APP_DATA_CKSUM"]], "krb5_keyusage_app_data_encrypt (built-in variable)": [[580, "KRB5_KEYUSAGE_APP_DATA_ENCRYPT"]], "krb5_keyusage_ap_rep_encpart (built-in variable)": [[581, "KRB5_KEYUSAGE_AP_REP_ENCPART"]], "krb5_keyusage_ap_req_auth (built-in variable)": [[582, "KRB5_KEYUSAGE_AP_REQ_AUTH"]], "krb5_keyusage_ap_req_auth_cksum (built-in variable)": [[583, "KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM"]], "krb5_keyusage_as_rep_encpart (built-in variable)": [[584, "KRB5_KEYUSAGE_AS_REP_ENCPART"]], "krb5_keyusage_as_req (built-in variable)": [[585, "KRB5_KEYUSAGE_AS_REQ"]], "krb5_keyusage_as_req_pa_enc_ts (built-in variable)": [[586, "KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS"]], "krb5_keyusage_cammac (built-in variable)": [[587, "KRB5_KEYUSAGE_CAMMAC"]], "krb5_keyusage_enc_challenge_client (built-in variable)": [[588, "KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT"]], "krb5_keyusage_enc_challenge_kdc (built-in variable)": [[589, "KRB5_KEYUSAGE_ENC_CHALLENGE_KDC"]], "krb5_keyusage_fast_enc (built-in variable)": [[590, "KRB5_KEYUSAGE_FAST_ENC"]], "krb5_keyusage_fast_finished (built-in variable)": [[591, "KRB5_KEYUSAGE_FAST_FINISHED"]], "krb5_keyusage_fast_rep (built-in variable)": [[592, "KRB5_KEYUSAGE_FAST_REP"]], "krb5_keyusage_fast_req_chksum (built-in variable)": [[593, "KRB5_KEYUSAGE_FAST_REQ_CHKSUM"]], "krb5_keyusage_finished (built-in variable)": [[594, "KRB5_KEYUSAGE_FINISHED"]], "krb5_keyusage_gss_tok_mic (built-in variable)": [[595, "KRB5_KEYUSAGE_GSS_TOK_MIC"]], "krb5_keyusage_gss_tok_wrap_integ (built-in variable)": [[596, "KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG"]], "krb5_keyusage_gss_tok_wrap_priv (built-in variable)": [[597, "KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV"]], "krb5_keyusage_iakerb_finished (built-in variable)": [[598, "KRB5_KEYUSAGE_IAKERB_FINISHED"]], "krb5_keyusage_kdc_rep_ticket (built-in variable)": [[599, "KRB5_KEYUSAGE_KDC_REP_TICKET"]], "krb5_keyusage_krb_cred_encpart (built-in variable)": [[600, "KRB5_KEYUSAGE_KRB_CRED_ENCPART"]], "krb5_keyusage_krb_error_cksum (built-in variable)": [[601, "KRB5_KEYUSAGE_KRB_ERROR_CKSUM"]], "krb5_keyusage_krb_priv_encpart (built-in variable)": [[602, "KRB5_KEYUSAGE_KRB_PRIV_ENCPART"]], "krb5_keyusage_krb_safe_cksum (built-in variable)": [[603, "KRB5_KEYUSAGE_KRB_SAFE_CKSUM"]], "krb5_keyusage_pa_as_freshness (built-in variable)": [[604, "KRB5_KEYUSAGE_PA_AS_FRESHNESS"]], "krb5_keyusage_pa_fx_cookie (built-in variable)": [[605, "KRB5_KEYUSAGE_PA_FX_COOKIE"]], "krb5_keyusage_pa_otp_request (built-in variable)": [[606, "KRB5_KEYUSAGE_PA_OTP_REQUEST"]], "krb5_keyusage_pa_pkinit_kx (built-in variable)": [[607, "KRB5_KEYUSAGE_PA_PKINIT_KX"]], "krb5_keyusage_pa_s4u_x509_user_reply (built-in variable)": [[608, "KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY"]], "krb5_keyusage_pa_s4u_x509_user_request (built-in variable)": [[609, "KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST"]], "krb5_keyusage_pa_sam_challenge_cksum (built-in variable)": [[610, "KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM"]], "krb5_keyusage_pa_sam_challenge_trackid (built-in variable)": [[611, "KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID"]], "krb5_keyusage_pa_sam_response (built-in variable)": [[612, "KRB5_KEYUSAGE_PA_SAM_RESPONSE"]], "krb5_keyusage_spake (built-in variable)": [[613, "KRB5_KEYUSAGE_SPAKE"]], "krb5_keyusage_tgs_rep_encpart_sesskey (built-in variable)": [[614, "KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY"]], "krb5_keyusage_tgs_rep_encpart_subkey (built-in variable)": [[615, "KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY"]], "krb5_keyusage_tgs_req_ad_sesskey (built-in variable)": [[616, "KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY"]], "krb5_keyusage_tgs_req_ad_subkey (built-in variable)": [[617, "KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY"]], "krb5_keyusage_tgs_req_auth (built-in variable)": [[618, "KRB5_KEYUSAGE_TGS_REQ_AUTH"]], "krb5_keyusage_tgs_req_auth_cksum (built-in variable)": [[619, "KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM"]], "krb5_kpasswd_accessdenied (built-in variable)": [[620, "KRB5_KPASSWD_ACCESSDENIED"]], "krb5_kpasswd_autherror (built-in variable)": [[621, "KRB5_KPASSWD_AUTHERROR"]], "krb5_kpasswd_bad_version (built-in variable)": [[622, "KRB5_KPASSWD_BAD_VERSION"]], "krb5_kpasswd_harderror (built-in variable)": [[623, "KRB5_KPASSWD_HARDERROR"]], "krb5_kpasswd_initial_flag_needed (built-in variable)": [[624, "KRB5_KPASSWD_INITIAL_FLAG_NEEDED"]], "krb5_kpasswd_malformed (built-in variable)": [[625, "KRB5_KPASSWD_MALFORMED"]], "krb5_kpasswd_softerror (built-in variable)": [[626, "KRB5_KPASSWD_SOFTERROR"]], "krb5_kpasswd_success (built-in variable)": [[627, "KRB5_KPASSWD_SUCCESS"]], "krb5_lrq_all_acct_exptime (built-in variable)": [[628, "KRB5_LRQ_ALL_ACCT_EXPTIME"]], "krb5_lrq_all_last_initial (built-in variable)": [[629, "KRB5_LRQ_ALL_LAST_INITIAL"]], "krb5_lrq_all_last_renewal (built-in variable)": [[630, "KRB5_LRQ_ALL_LAST_RENEWAL"]], "krb5_lrq_all_last_req (built-in variable)": [[631, "KRB5_LRQ_ALL_LAST_REQ"]], "krb5_lrq_all_last_tgt (built-in variable)": [[632, "KRB5_LRQ_ALL_LAST_TGT"]], "krb5_lrq_all_last_tgt_issued (built-in variable)": [[633, "KRB5_LRQ_ALL_LAST_TGT_ISSUED"]], "krb5_lrq_all_pw_exptime (built-in variable)": [[634, "KRB5_LRQ_ALL_PW_EXPTIME"]], "krb5_lrq_none (built-in variable)": [[635, "KRB5_LRQ_NONE"]], "krb5_lrq_one_acct_exptime (built-in variable)": [[636, "KRB5_LRQ_ONE_ACCT_EXPTIME"]], "krb5_lrq_one_last_initial (built-in variable)": [[637, "KRB5_LRQ_ONE_LAST_INITIAL"]], "krb5_lrq_one_last_renewal (built-in variable)": [[638, "KRB5_LRQ_ONE_LAST_RENEWAL"]], "krb5_lrq_one_last_req (built-in variable)": [[639, "KRB5_LRQ_ONE_LAST_REQ"]], "krb5_lrq_one_last_tgt (built-in variable)": [[640, "KRB5_LRQ_ONE_LAST_TGT"]], "krb5_lrq_one_last_tgt_issued (built-in variable)": [[641, "KRB5_LRQ_ONE_LAST_TGT_ISSUED"]], "krb5_lrq_one_pw_exptime (built-in variable)": [[642, "KRB5_LRQ_ONE_PW_EXPTIME"]], "krb5_nt_enterprise_principal (built-in variable)": [[643, "KRB5_NT_ENTERPRISE_PRINCIPAL"]], "krb5_nt_ent_principal_and_id (built-in variable)": [[644, "KRB5_NT_ENT_PRINCIPAL_AND_ID"]], "krb5_nt_ms_principal (built-in variable)": [[645, "KRB5_NT_MS_PRINCIPAL"]], "krb5_nt_ms_principal_and_id (built-in variable)": [[646, "KRB5_NT_MS_PRINCIPAL_AND_ID"]], "krb5_nt_principal (built-in variable)": [[647, "KRB5_NT_PRINCIPAL"]], "krb5_nt_smtp_name (built-in variable)": [[648, "KRB5_NT_SMTP_NAME"]], "krb5_nt_srv_hst (built-in variable)": [[649, "KRB5_NT_SRV_HST"]], "krb5_nt_srv_inst (built-in variable)": [[650, "KRB5_NT_SRV_INST"]], "krb5_nt_srv_xhst (built-in variable)": [[651, "KRB5_NT_SRV_XHST"]], "krb5_nt_uid (built-in variable)": [[652, "KRB5_NT_UID"]], "krb5_nt_unknown (built-in variable)": [[653, "KRB5_NT_UNKNOWN"]], "krb5_nt_wellknown (built-in variable)": [[654, "KRB5_NT_WELLKNOWN"]], "krb5_nt_x500_principal (built-in variable)": [[655, "KRB5_NT_X500_PRINCIPAL"]], "krb5_pac_attributes_info (built-in variable)": [[656, "KRB5_PAC_ATTRIBUTES_INFO"]], "krb5_pac_client_claims (built-in variable)": [[657, "KRB5_PAC_CLIENT_CLAIMS"]], "krb5_pac_client_info (built-in variable)": [[658, "KRB5_PAC_CLIENT_INFO"]], "krb5_pac_credentials_info (built-in variable)": [[659, "KRB5_PAC_CREDENTIALS_INFO"]], "krb5_pac_delegation_info (built-in variable)": [[660, "KRB5_PAC_DELEGATION_INFO"]], "krb5_pac_device_claims (built-in variable)": [[661, "KRB5_PAC_DEVICE_CLAIMS"]], "krb5_pac_device_info (built-in variable)": [[662, "KRB5_PAC_DEVICE_INFO"]], "krb5_pac_full_checksum (built-in variable)": [[663, "KRB5_PAC_FULL_CHECKSUM"]], "krb5_pac_logon_info (built-in variable)": [[664, "KRB5_PAC_LOGON_INFO"]], "krb5_pac_privsvr_checksum (built-in variable)": [[665, "KRB5_PAC_PRIVSVR_CHECKSUM"]], "krb5_pac_requestor (built-in variable)": [[666, "KRB5_PAC_REQUESTOR"]], "krb5_pac_server_checksum (built-in variable)": [[667, "KRB5_PAC_SERVER_CHECKSUM"]], "krb5_pac_ticket_checksum (built-in variable)": [[668, "KRB5_PAC_TICKET_CHECKSUM"]], "krb5_pac_upn_dns_info (built-in variable)": [[669, "KRB5_PAC_UPN_DNS_INFO"]], "krb5_padata_afs3_salt (built-in variable)": [[670, "KRB5_PADATA_AFS3_SALT"]], "krb5_padata_ap_req (built-in variable)": [[671, "KRB5_PADATA_AP_REQ"]], "krb5_padata_as_checksum (built-in variable)": [[672, "KRB5_PADATA_AS_CHECKSUM"]], "krb5_padata_as_freshness (built-in variable)": [[673, "KRB5_PADATA_AS_FRESHNESS"]], "krb5_padata_encrypted_challenge (built-in variable)": [[674, "KRB5_PADATA_ENCRYPTED_CHALLENGE"]], "krb5_padata_enc_sandia_securid (built-in variable)": [[675, "KRB5_PADATA_ENC_SANDIA_SECURID"]], "krb5_padata_enc_timestamp (built-in variable)": [[676, "KRB5_PADATA_ENC_TIMESTAMP"]], "krb5_padata_enc_unix_time (built-in variable)": [[677, "KRB5_PADATA_ENC_UNIX_TIME"]], "krb5_padata_etype_info (built-in variable)": [[678, "KRB5_PADATA_ETYPE_INFO"]], "krb5_padata_etype_info2 (built-in variable)": [[679, "KRB5_PADATA_ETYPE_INFO2"]], "krb5_padata_for_user (built-in variable)": [[680, "KRB5_PADATA_FOR_USER"]], "krb5_padata_fx_cookie (built-in variable)": [[681, "KRB5_PADATA_FX_COOKIE"]], "krb5_padata_fx_error (built-in variable)": [[682, "KRB5_PADATA_FX_ERROR"]], "krb5_padata_fx_fast (built-in variable)": [[683, "KRB5_PADATA_FX_FAST"]], "krb5_padata_get_from_typed_data (built-in variable)": [[684, "KRB5_PADATA_GET_FROM_TYPED_DATA"]], "krb5_padata_none (built-in variable)": [[685, "KRB5_PADATA_NONE"]], "krb5_padata_osf_dce (built-in variable)": [[686, "KRB5_PADATA_OSF_DCE"]], "krb5_padata_otp_challenge (built-in variable)": [[687, "KRB5_PADATA_OTP_CHALLENGE"]], "krb5_padata_otp_pin_change (built-in variable)": [[688, "KRB5_PADATA_OTP_PIN_CHANGE"]], "krb5_padata_otp_request (built-in variable)": [[689, "KRB5_PADATA_OTP_REQUEST"]], "krb5_padata_pac_options (built-in variable)": [[690, "KRB5_PADATA_PAC_OPTIONS"]], "krb5_padata_pac_request (built-in variable)": [[691, "KRB5_PADATA_PAC_REQUEST"]], "krb5_padata_pkinit_kx (built-in variable)": [[692, "KRB5_PADATA_PKINIT_KX"]], "krb5_padata_pk_as_rep (built-in variable)": [[693, "KRB5_PADATA_PK_AS_REP"]], "krb5_padata_pk_as_rep_old (built-in variable)": [[694, "KRB5_PADATA_PK_AS_REP_OLD"]], "krb5_padata_pk_as_req (built-in variable)": [[695, "KRB5_PADATA_PK_AS_REQ"]], "krb5_padata_pk_as_req_old (built-in variable)": [[696, "KRB5_PADATA_PK_AS_REQ_OLD"]], "krb5_padata_pw_salt (built-in variable)": [[697, "KRB5_PADATA_PW_SALT"]], "krb5_padata_redhat_idp_oauth2 (built-in variable)": [[698, "KRB5_PADATA_REDHAT_IDP_OAUTH2"]], "krb5_padata_redhat_passkey (built-in variable)": [[699, "KRB5_PADATA_REDHAT_PASSKEY"]], "krb5_padata_referral (built-in variable)": [[700, "KRB5_PADATA_REFERRAL"]], "krb5_padata_s4u_x509_user (built-in variable)": [[701, "KRB5_PADATA_S4U_X509_USER"]], "krb5_padata_sam_challenge (built-in variable)": [[702, "KRB5_PADATA_SAM_CHALLENGE"]], "krb5_padata_sam_challenge_2 (built-in variable)": [[703, "KRB5_PADATA_SAM_CHALLENGE_2"]], "krb5_padata_sam_redirect (built-in variable)": [[704, "KRB5_PADATA_SAM_REDIRECT"]], "krb5_padata_sam_response (built-in variable)": [[705, "KRB5_PADATA_SAM_RESPONSE"]], "krb5_padata_sam_response_2 (built-in variable)": [[706, "KRB5_PADATA_SAM_RESPONSE_2"]], "krb5_padata_sesame (built-in variable)": [[707, "KRB5_PADATA_SESAME"]], "krb5_padata_spake (built-in variable)": [[708, "KRB5_PADATA_SPAKE"]], "krb5_padata_svr_referral_info (built-in variable)": [[709, "KRB5_PADATA_SVR_REFERRAL_INFO"]], "krb5_padata_tgs_req (built-in variable)": [[710, "KRB5_PADATA_TGS_REQ"]], "krb5_padata_use_specified_kvno (built-in variable)": [[711, "KRB5_PADATA_USE_SPECIFIED_KVNO"]], "krb5_principal_compare_casefold (built-in variable)": [[712, "KRB5_PRINCIPAL_COMPARE_CASEFOLD"]], "krb5_principal_compare_enterprise (built-in variable)": [[713, "KRB5_PRINCIPAL_COMPARE_ENTERPRISE"]], "krb5_principal_compare_ignore_realm (built-in variable)": [[714, "KRB5_PRINCIPAL_COMPARE_IGNORE_REALM"]], "krb5_principal_compare_utf8 (built-in variable)": [[715, "KRB5_PRINCIPAL_COMPARE_UTF8"]], "krb5_principal_parse_enterprise (built-in variable)": [[716, "KRB5_PRINCIPAL_PARSE_ENTERPRISE"]], "krb5_principal_parse_ignore_realm (built-in variable)": [[717, "KRB5_PRINCIPAL_PARSE_IGNORE_REALM"]], "krb5_principal_parse_no_def_realm (built-in variable)": [[718, "KRB5_PRINCIPAL_PARSE_NO_DEF_REALM"]], "krb5_principal_parse_no_realm (built-in variable)": [[719, "KRB5_PRINCIPAL_PARSE_NO_REALM"]], "krb5_principal_parse_require_realm (built-in variable)": [[720, "KRB5_PRINCIPAL_PARSE_REQUIRE_REALM"]], "krb5_principal_unparse_display (built-in variable)": [[721, "KRB5_PRINCIPAL_UNPARSE_DISPLAY"]], "krb5_principal_unparse_no_realm (built-in variable)": [[722, "KRB5_PRINCIPAL_UNPARSE_NO_REALM"]], "krb5_principal_unparse_short (built-in variable)": [[723, "KRB5_PRINCIPAL_UNPARSE_SHORT"]], "krb5_priv (built-in variable)": [[724, "KRB5_PRIV"]], "krb5_prompt_type_new_password (built-in variable)": [[725, "KRB5_PROMPT_TYPE_NEW_PASSWORD"]], "krb5_prompt_type_new_password_again (built-in variable)": [[726, "KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN"]], "krb5_prompt_type_password (built-in variable)": [[727, "KRB5_PROMPT_TYPE_PASSWORD"]], "krb5_prompt_type_preauth (built-in variable)": [[728, "KRB5_PROMPT_TYPE_PREAUTH"]], "krb5_pvno (built-in variable)": [[729, "KRB5_PVNO"]], "krb5_realm_branch_char (built-in variable)": [[730, "KRB5_REALM_BRANCH_CHAR"]], "krb5_recvauth_badauthvers (built-in variable)": [[731, "KRB5_RECVAUTH_BADAUTHVERS"]], "krb5_recvauth_skip_version (built-in variable)": [[732, "KRB5_RECVAUTH_SKIP_VERSION"]], "krb5_referral_realm (built-in variable)": [[733, "KRB5_REFERRAL_REALM"]], "krb5_responder_otp_flags_collect_pin (built-in variable)": [[734, "KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN"]], "krb5_responder_otp_flags_collect_token (built-in variable)": [[735, "KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN"]], "krb5_responder_otp_flags_nextotp (built-in variable)": [[736, "KRB5_RESPONDER_OTP_FLAGS_NEXTOTP"]], "krb5_responder_otp_flags_separate_pin (built-in variable)": [[737, "KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN"]], "krb5_responder_otp_format_alphanumeric (built-in variable)": [[738, "KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC"]], "krb5_responder_otp_format_decimal (built-in variable)": [[739, "KRB5_RESPONDER_OTP_FORMAT_DECIMAL"]], "krb5_responder_otp_format_hexadecimal (built-in variable)": [[740, "KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL"]], "krb5_responder_pkinit_flags_token_user_pin_count_low (built-in variable)": [[741, "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW"]], "krb5_responder_pkinit_flags_token_user_pin_final_try (built-in variable)": [[742, "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY"]], "krb5_responder_pkinit_flags_token_user_pin_locked (built-in variable)": [[743, "KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED"]], "krb5_responder_question_otp (built-in variable)": [[744, "KRB5_RESPONDER_QUESTION_OTP"]], "krb5_responder_question_password (built-in variable)": [[745, "KRB5_RESPONDER_QUESTION_PASSWORD"]], "krb5_responder_question_pkinit (built-in variable)": [[746, "KRB5_RESPONDER_QUESTION_PKINIT"]], "krb5_safe (built-in variable)": [[747, "KRB5_SAFE"]], "krb5_sam_must_pk_encrypt_sad (built-in variable)": [[748, "KRB5_SAM_MUST_PK_ENCRYPT_SAD"]], "krb5_sam_send_encrypted_sad (built-in variable)": [[749, "KRB5_SAM_SEND_ENCRYPTED_SAD"]], "krb5_sam_use_sad_as_key (built-in variable)": [[750, "KRB5_SAM_USE_SAD_AS_KEY"]], "krb5_tc_match_2nd_tkt (built-in variable)": [[751, "KRB5_TC_MATCH_2ND_TKT"]], "krb5_tc_match_authdata (built-in variable)": [[752, "KRB5_TC_MATCH_AUTHDATA"]], "krb5_tc_match_flags (built-in variable)": [[753, "KRB5_TC_MATCH_FLAGS"]], "krb5_tc_match_flags_exact (built-in variable)": [[754, "KRB5_TC_MATCH_FLAGS_EXACT"]], "krb5_tc_match_is_skey (built-in variable)": [[755, "KRB5_TC_MATCH_IS_SKEY"]], "krb5_tc_match_ktype (built-in variable)": [[756, "KRB5_TC_MATCH_KTYPE"]], "krb5_tc_match_srv_nameonly (built-in variable)": [[757, "KRB5_TC_MATCH_SRV_NAMEONLY"]], "krb5_tc_match_times (built-in variable)": [[758, "KRB5_TC_MATCH_TIMES"]], "krb5_tc_match_times_exact (built-in variable)": [[759, "KRB5_TC_MATCH_TIMES_EXACT"]], "krb5_tc_noticket (built-in variable)": [[760, "KRB5_TC_NOTICKET"]], "krb5_tc_openclose (built-in variable)": [[761, "KRB5_TC_OPENCLOSE"]], "krb5_tc_supported_ktypes (built-in variable)": [[762, "KRB5_TC_SUPPORTED_KTYPES"]], "krb5_tgs_name (built-in variable)": [[763, "KRB5_TGS_NAME"]], "krb5_tgs_name_size (built-in variable)": [[764, "KRB5_TGS_NAME_SIZE"]], "krb5_tgs_rep (built-in variable)": [[765, "KRB5_TGS_REP"]], "krb5_tgs_req (built-in variable)": [[766, "KRB5_TGS_REQ"]], "krb5_tkt_creds_step_flag_continue (built-in variable)": [[767, "KRB5_TKT_CREDS_STEP_FLAG_CONTINUE"]], "krb5_verify_init_creds_opt_ap_req_nofail (built-in variable)": [[768, "KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL"]], "krb5_wellknown_namestr (built-in variable)": [[769, "KRB5_WELLKNOWN_NAMESTR"]], "lr_type_interpretation_mask (built-in variable)": [[770, "LR_TYPE_INTERPRETATION_MASK"]], "lr_type_this_server_only (built-in variable)": [[771, "LR_TYPE_THIS_SERVER_ONLY"]], "max_keytab_name_len (built-in variable)": [[772, "MAX_KEYTAB_NAME_LEN"]], "msec_dirbit (built-in variable)": [[773, "MSEC_DIRBIT"]], "msec_val_mask (built-in variable)": [[774, "MSEC_VAL_MASK"]], "salt_type_afs_length (built-in variable)": [[775, "SALT_TYPE_AFS_LENGTH"]], "salt_type_no_length (built-in variable)": [[776, "SALT_TYPE_NO_LENGTH"]], "threeparamopen (built-in variable)": [[777, "THREEPARAMOPEN"]], "tkt_flg_anonymous (built-in variable)": [[778, "TKT_FLG_ANONYMOUS"]], "tkt_flg_enc_pa_rep (built-in variable)": [[779, "TKT_FLG_ENC_PA_REP"]], "tkt_flg_forwardable (built-in variable)": [[780, "TKT_FLG_FORWARDABLE"]], "tkt_flg_forwarded (built-in variable)": [[781, "TKT_FLG_FORWARDED"]], "tkt_flg_hw_auth (built-in variable)": [[782, "TKT_FLG_HW_AUTH"]], "tkt_flg_initial (built-in variable)": [[783, "TKT_FLG_INITIAL"]], "tkt_flg_invalid (built-in variable)": [[784, "TKT_FLG_INVALID"]], "tkt_flg_may_postdate (built-in variable)": [[785, "TKT_FLG_MAY_POSTDATE"]], "tkt_flg_ok_as_delegate (built-in variable)": [[786, "TKT_FLG_OK_AS_DELEGATE"]], "tkt_flg_postdated (built-in variable)": [[787, "TKT_FLG_POSTDATED"]], "tkt_flg_pre_auth (built-in variable)": [[788, "TKT_FLG_PRE_AUTH"]], "tkt_flg_proxiable (built-in variable)": [[789, "TKT_FLG_PROXIABLE"]], "tkt_flg_proxy (built-in variable)": [[790, "TKT_FLG_PROXY"]], "tkt_flg_renewable (built-in variable)": [[791, "TKT_FLG_RENEWABLE"]], "tkt_flg_transit_policy_checked (built-in variable)": [[792, "TKT_FLG_TRANSIT_POLICY_CHECKED"]], "valid_int_bits (built-in variable)": [[793, "VALID_INT_BITS"]], "valid_uint_bits (built-in variable)": [[794, "VALID_UINT_BITS"]], "krb524_convert_creds_kdc (built-in variable)": [[796, "krb524_convert_creds_kdc"]], "krb524_init_ets (built-in variable)": [[797, "krb524_init_ets"]], "krb5_const (built-in variable)": [[798, "krb5_const"]], "krb5_princ_component (built-in variable)": [[799, "krb5_princ_component"]], "krb5_princ_name (built-in variable)": [[800, "krb5_princ_name"]], "krb5_princ_realm (built-in variable)": [[801, "krb5_princ_realm"]], "krb5_princ_set_realm (built-in variable)": [[802, "krb5_princ_set_realm"]], "krb5_princ_set_realm_data (built-in variable)": [[803, "krb5_princ_set_realm_data"]], "krb5_princ_set_realm_length (built-in variable)": [[804, "krb5_princ_set_realm_length"]], "krb5_princ_size (built-in variable)": [[805, "krb5_princ_size"]], "krb5_princ_type (built-in variable)": [[806, "krb5_princ_type"]], "krb5_roundup (built-in variable)": [[807, "krb5_roundup"]], "krb5_x (built-in variable)": [[808, "krb5_x"]], "krb5_xc (built-in variable)": [[809, "krb5_xc"]], "krb5_address (c type)": [[811, "c.krb5_address"]], "krb5_address.addrtype (c member)": [[811, "c.krb5_address.addrtype"]], "krb5_address.contents (c member)": [[811, "c.krb5_address.contents"]], "krb5_address.length (c member)": [[811, "c.krb5_address.length"]], "krb5_address.magic (c member)": [[811, "c.krb5_address.magic"]], "krb5_addrtype (c type)": [[812, "c.krb5_addrtype"]], "krb5_ap_rep (c type)": [[813, "c.krb5_ap_rep"]], "krb5_ap_rep.enc_part (c member)": [[813, "c.krb5_ap_rep.enc_part"]], "krb5_ap_rep.magic (c member)": [[813, "c.krb5_ap_rep.magic"]], "krb5_ap_rep_enc_part (c type)": [[814, "c.krb5_ap_rep_enc_part"]], "krb5_ap_rep_enc_part.ctime (c member)": [[814, "c.krb5_ap_rep_enc_part.ctime"]], "krb5_ap_rep_enc_part.cusec (c member)": [[814, "c.krb5_ap_rep_enc_part.cusec"]], "krb5_ap_rep_enc_part.magic (c member)": [[814, "c.krb5_ap_rep_enc_part.magic"]], "krb5_ap_rep_enc_part.seq_number (c member)": [[814, "c.krb5_ap_rep_enc_part.seq_number"]], "krb5_ap_rep_enc_part.subkey (c member)": [[814, "c.krb5_ap_rep_enc_part.subkey"]], "krb5_ap_req (c type)": [[815, "c.krb5_ap_req"]], "krb5_ap_req.ap_options (c member)": [[815, "c.krb5_ap_req.ap_options"]], "krb5_ap_req.authenticator (c member)": [[815, "c.krb5_ap_req.authenticator"]], "krb5_ap_req.magic (c member)": [[815, "c.krb5_ap_req.magic"]], "krb5_ap_req.ticket (c member)": [[815, "c.krb5_ap_req.ticket"]], "krb5_auth_context (c type)": [[816, "c.krb5_auth_context"]], "krb5_authdata (c type)": [[817, "c.krb5_authdata"]], "krb5_authdata.ad_type (c member)": [[817, "c.krb5_authdata.ad_type"]], "krb5_authdata.contents (c member)": [[817, "c.krb5_authdata.contents"]], "krb5_authdata.length (c member)": [[817, "c.krb5_authdata.length"]], "krb5_authdata.magic (c member)": [[817, "c.krb5_authdata.magic"]], "krb5_authdatatype (c type)": [[818, "c.krb5_authdatatype"]], "krb5_authenticator (c type)": [[819, "c.krb5_authenticator"]], "krb5_authenticator.authorization_data (c member)": [[819, "c.krb5_authenticator.authorization_data"]], "krb5_authenticator.checksum (c member)": [[819, "c.krb5_authenticator.checksum"]], "krb5_authenticator.client (c member)": [[819, "c.krb5_authenticator.client"]], "krb5_authenticator.ctime (c member)": [[819, "c.krb5_authenticator.ctime"]], "krb5_authenticator.cusec (c member)": [[819, "c.krb5_authenticator.cusec"]], "krb5_authenticator.magic (c member)": [[819, "c.krb5_authenticator.magic"]], "krb5_authenticator.seq_number (c member)": [[819, "c.krb5_authenticator.seq_number"]], "krb5_authenticator.subkey (c member)": [[819, "c.krb5_authenticator.subkey"]], "krb5_boolean (c type)": [[820, "c.krb5_boolean"]], "krb5_cc_cursor (c type)": [[821, "c.krb5_cc_cursor"]], "krb5_ccache (c type)": [[822, "c.krb5_ccache"]], "krb5_cccol_cursor (c type)": [[823, "c.krb5_cccol_cursor"]], "krb5_checksum (c type)": [[824, "c.krb5_checksum"]], "krb5_checksum.checksum_type (c member)": [[824, "c.krb5_checksum.checksum_type"]], "krb5_checksum.contents (c member)": [[824, "c.krb5_checksum.contents"]], "krb5_checksum.length (c member)": [[824, "c.krb5_checksum.length"]], "krb5_checksum.magic (c member)": [[824, "c.krb5_checksum.magic"]], "krb5_cksumtype (c type)": [[825, "c.krb5_cksumtype"]], "krb5_const_pointer (c type)": [[826, "c.krb5_const_pointer"]], "krb5_const_principal (c type)": [[827, "c.krb5_const_principal"]], "krb5_const_principal.data (c member)": [[827, "c.krb5_const_principal.data"]], "krb5_const_principal.length (c member)": [[827, "c.krb5_const_principal.length"]], "krb5_const_principal.magic (c member)": [[827, "c.krb5_const_principal.magic"]], "krb5_const_principal.realm (c member)": [[827, "c.krb5_const_principal.realm"]], "krb5_const_principal.type (c member)": [[827, "c.krb5_const_principal.type"]], "krb5_context (c type)": [[828, "c.krb5_context"]], "krb5_cred (c type)": [[829, "c.krb5_cred"]], "krb5_cred.enc_part (c member)": [[829, "c.krb5_cred.enc_part"]], "krb5_cred.enc_part2 (c member)": [[829, "c.krb5_cred.enc_part2"]], "krb5_cred.magic (c member)": [[829, "c.krb5_cred.magic"]], "krb5_cred.tickets (c member)": [[829, "c.krb5_cred.tickets"]], "krb5_cred_enc_part (c type)": [[830, "c.krb5_cred_enc_part"]], "krb5_cred_enc_part.magic (c member)": [[830, "c.krb5_cred_enc_part.magic"]], "krb5_cred_enc_part.nonce (c member)": [[830, "c.krb5_cred_enc_part.nonce"]], "krb5_cred_enc_part.r_address (c member)": [[830, "c.krb5_cred_enc_part.r_address"]], "krb5_cred_enc_part.s_address (c member)": [[830, "c.krb5_cred_enc_part.s_address"]], "krb5_cred_enc_part.ticket_info (c member)": [[830, "c.krb5_cred_enc_part.ticket_info"]], "krb5_cred_enc_part.timestamp (c member)": [[830, "c.krb5_cred_enc_part.timestamp"]], "krb5_cred_enc_part.usec (c member)": [[830, "c.krb5_cred_enc_part.usec"]], "krb5_cred_info (c type)": [[831, "c.krb5_cred_info"]], "krb5_cred_info.caddrs (c member)": [[831, "c.krb5_cred_info.caddrs"]], "krb5_cred_info.client (c member)": [[831, "c.krb5_cred_info.client"]], "krb5_cred_info.flags (c member)": [[831, "c.krb5_cred_info.flags"]], "krb5_cred_info.magic (c member)": [[831, "c.krb5_cred_info.magic"]], "krb5_cred_info.server (c member)": [[831, "c.krb5_cred_info.server"]], "krb5_cred_info.session (c member)": [[831, "c.krb5_cred_info.session"]], "krb5_cred_info.times (c member)": [[831, "c.krb5_cred_info.times"]], "krb5_creds (c type)": [[832, "c.krb5_creds"]], "krb5_creds.addresses (c member)": [[832, "c.krb5_creds.addresses"]], "krb5_creds.authdata (c member)": [[832, "c.krb5_creds.authdata"]], "krb5_creds.client (c member)": [[832, "c.krb5_creds.client"]], "krb5_creds.is_skey (c member)": [[832, "c.krb5_creds.is_skey"]], "krb5_creds.keyblock (c member)": [[832, "c.krb5_creds.keyblock"]], "krb5_creds.magic (c member)": [[832, "c.krb5_creds.magic"]], "krb5_creds.second_ticket (c member)": [[832, "c.krb5_creds.second_ticket"]], "krb5_creds.server (c member)": [[832, "c.krb5_creds.server"]], "krb5_creds.ticket (c member)": [[832, "c.krb5_creds.ticket"]], "krb5_creds.ticket_flags (c member)": [[832, "c.krb5_creds.ticket_flags"]], "krb5_creds.times (c member)": [[832, "c.krb5_creds.times"]], "krb5_crypto_iov (c type)": [[833, "c.krb5_crypto_iov"]], "krb5_crypto_iov.data (c member)": [[833, "c.krb5_crypto_iov.data"]], "krb5_crypto_iov.flags (c member)": [[833, "c.krb5_crypto_iov.flags"]], "krb5_cryptotype (c type)": [[834, "c.krb5_cryptotype"]], "krb5_data (c type)": [[835, "c.krb5_data"]], "krb5_data.data (c member)": [[835, "c.krb5_data.data"]], "krb5_data.length (c member)": [[835, "c.krb5_data.length"]], "krb5_data.magic (c member)": [[835, "c.krb5_data.magic"]], "krb5_deltat (c type)": [[836, "c.krb5_deltat"]], "krb5_enc_data (c type)": [[837, "c.krb5_enc_data"]], "krb5_enc_data.ciphertext (c member)": [[837, "c.krb5_enc_data.ciphertext"]], "krb5_enc_data.enctype (c member)": [[837, "c.krb5_enc_data.enctype"]], "krb5_enc_data.kvno (c member)": [[837, "c.krb5_enc_data.kvno"]], "krb5_enc_data.magic (c member)": [[837, "c.krb5_enc_data.magic"]], "krb5_enc_kdc_rep_part (c type)": [[838, "c.krb5_enc_kdc_rep_part"]], "krb5_enc_kdc_rep_part.caddrs (c member)": [[838, "c.krb5_enc_kdc_rep_part.caddrs"]], "krb5_enc_kdc_rep_part.enc_padata (c member)": [[838, "c.krb5_enc_kdc_rep_part.enc_padata"]], "krb5_enc_kdc_rep_part.flags (c member)": [[838, "c.krb5_enc_kdc_rep_part.flags"]], "krb5_enc_kdc_rep_part.key_exp (c member)": [[838, "c.krb5_enc_kdc_rep_part.key_exp"]], "krb5_enc_kdc_rep_part.last_req (c member)": [[838, "c.krb5_enc_kdc_rep_part.last_req"]], "krb5_enc_kdc_rep_part.magic (c member)": [[838, "c.krb5_enc_kdc_rep_part.magic"]], "krb5_enc_kdc_rep_part.msg_type (c member)": [[838, "c.krb5_enc_kdc_rep_part.msg_type"]], "krb5_enc_kdc_rep_part.nonce (c member)": [[838, "c.krb5_enc_kdc_rep_part.nonce"]], "krb5_enc_kdc_rep_part.server (c member)": [[838, "c.krb5_enc_kdc_rep_part.server"]], "krb5_enc_kdc_rep_part.session (c member)": [[838, "c.krb5_enc_kdc_rep_part.session"]], "krb5_enc_kdc_rep_part.times (c member)": [[838, "c.krb5_enc_kdc_rep_part.times"]], "krb5_enc_tkt_part (c type)": [[839, "c.krb5_enc_tkt_part"]], "krb5_enc_tkt_part.authorization_data (c member)": [[839, "c.krb5_enc_tkt_part.authorization_data"]], "krb5_enc_tkt_part.caddrs (c member)": [[839, "c.krb5_enc_tkt_part.caddrs"]], "krb5_enc_tkt_part.client (c member)": [[839, "c.krb5_enc_tkt_part.client"]], "krb5_enc_tkt_part.flags (c member)": [[839, "c.krb5_enc_tkt_part.flags"]], "krb5_enc_tkt_part.magic (c member)": [[839, "c.krb5_enc_tkt_part.magic"]], "krb5_enc_tkt_part.session (c member)": [[839, "c.krb5_enc_tkt_part.session"]], "krb5_enc_tkt_part.times (c member)": [[839, "c.krb5_enc_tkt_part.times"]], "krb5_enc_tkt_part.transited (c member)": [[839, "c.krb5_enc_tkt_part.transited"]], "krb5_encrypt_block (c type)": [[840, "c.krb5_encrypt_block"]], "krb5_encrypt_block.crypto_entry (c member)": [[840, "c.krb5_encrypt_block.crypto_entry"]], "krb5_encrypt_block.key (c member)": [[840, "c.krb5_encrypt_block.key"]], "krb5_encrypt_block.magic (c member)": [[840, "c.krb5_encrypt_block.magic"]], "krb5_enctype (c type)": [[841, "c.krb5_enctype"]], "krb5_error (c type)": [[842, "c.krb5_error"]], "krb5_error.client (c member)": [[842, "c.krb5_error.client"]], "krb5_error.ctime (c member)": [[842, "c.krb5_error.ctime"]], "krb5_error.cusec (c member)": [[842, "c.krb5_error.cusec"]], "krb5_error.e_data (c member)": [[842, "c.krb5_error.e_data"]], "krb5_error.error (c member)": [[842, "c.krb5_error.error"]], "krb5_error.magic (c member)": [[842, "c.krb5_error.magic"]], "krb5_error.server (c member)": [[842, "c.krb5_error.server"]], "krb5_error.stime (c member)": [[842, "c.krb5_error.stime"]], "krb5_error.susec (c member)": [[842, "c.krb5_error.susec"]], "krb5_error.text (c member)": [[842, "c.krb5_error.text"]], "krb5_error_code (c type)": [[843, "c.krb5_error_code"]], "krb5_expire_callback_func (c type)": [[844, "c.krb5_expire_callback_func"]], "krb5_flags (c type)": [[845, "c.krb5_flags"]], "krb5_get_init_creds_opt (c type)": [[846, "c.krb5_get_init_creds_opt"]], "krb5_get_init_creds_opt.address_list (c member)": [[846, "c.krb5_get_init_creds_opt.address_list"]], "krb5_get_init_creds_opt.etype_list (c member)": [[846, "c.krb5_get_init_creds_opt.etype_list"]], "krb5_get_init_creds_opt.etype_list_length (c member)": [[846, "c.krb5_get_init_creds_opt.etype_list_length"]], "krb5_get_init_creds_opt.flags (c member)": [[846, "c.krb5_get_init_creds_opt.flags"]], "krb5_get_init_creds_opt.forwardable (c member)": [[846, "c.krb5_get_init_creds_opt.forwardable"]], "krb5_get_init_creds_opt.preauth_list (c member)": [[846, "c.krb5_get_init_creds_opt.preauth_list"]], "krb5_get_init_creds_opt.preauth_list_length (c member)": [[846, "c.krb5_get_init_creds_opt.preauth_list_length"]], "krb5_get_init_creds_opt.proxiable (c member)": [[846, "c.krb5_get_init_creds_opt.proxiable"]], "krb5_get_init_creds_opt.renew_life (c member)": [[846, "c.krb5_get_init_creds_opt.renew_life"]], "krb5_get_init_creds_opt.salt (c member)": [[846, "c.krb5_get_init_creds_opt.salt"]], "krb5_get_init_creds_opt.tkt_life (c member)": [[846, "c.krb5_get_init_creds_opt.tkt_life"]], "krb5_gic_opt_pa_data (c type)": [[847, "c.krb5_gic_opt_pa_data"]], "krb5_gic_opt_pa_data.attr (c member)": [[847, "c.krb5_gic_opt_pa_data.attr"]], "krb5_gic_opt_pa_data.value (c member)": [[847, "c.krb5_gic_opt_pa_data.value"]], "krb5_init_creds_context (c type)": [[848, "c.krb5_init_creds_context"]], "krb5_int16 (c type)": [[849, "c.krb5_int16"]], "krb5_int32 (c type)": [[850, "c.krb5_int32"]], "krb5_kdc_rep (c type)": [[851, "c.krb5_kdc_rep"]], "krb5_kdc_rep.client (c member)": [[851, "c.krb5_kdc_rep.client"]], "krb5_kdc_rep.enc_part (c member)": [[851, "c.krb5_kdc_rep.enc_part"]], "krb5_kdc_rep.enc_part2 (c member)": [[851, "c.krb5_kdc_rep.enc_part2"]], "krb5_kdc_rep.magic (c member)": [[851, "c.krb5_kdc_rep.magic"]], "krb5_kdc_rep.msg_type (c member)": [[851, "c.krb5_kdc_rep.msg_type"]], "krb5_kdc_rep.padata (c member)": [[851, "c.krb5_kdc_rep.padata"]], "krb5_kdc_rep.ticket (c member)": [[851, "c.krb5_kdc_rep.ticket"]], "krb5_kdc_req (c type)": [[852, "c.krb5_kdc_req"]], "krb5_kdc_req.addresses (c member)": [[852, "c.krb5_kdc_req.addresses"]], "krb5_kdc_req.authorization_data (c member)": [[852, "c.krb5_kdc_req.authorization_data"]], "krb5_kdc_req.client (c member)": [[852, "c.krb5_kdc_req.client"]], "krb5_kdc_req.from (c member)": [[852, "c.krb5_kdc_req.from"]], "krb5_kdc_req.kdc_options (c member)": [[852, "c.krb5_kdc_req.kdc_options"]], "krb5_kdc_req.ktype (c member)": [[852, "c.krb5_kdc_req.ktype"]], "krb5_kdc_req.magic (c member)": [[852, "c.krb5_kdc_req.magic"]], "krb5_kdc_req.msg_type (c member)": [[852, "c.krb5_kdc_req.msg_type"]], "krb5_kdc_req.nktypes (c member)": [[852, "c.krb5_kdc_req.nktypes"]], "krb5_kdc_req.nonce (c member)": [[852, "c.krb5_kdc_req.nonce"]], "krb5_kdc_req.padata (c member)": [[852, "c.krb5_kdc_req.padata"]], "krb5_kdc_req.rtime (c member)": [[852, "c.krb5_kdc_req.rtime"]], "krb5_kdc_req.second_ticket (c member)": [[852, "c.krb5_kdc_req.second_ticket"]], "krb5_kdc_req.server (c member)": [[852, "c.krb5_kdc_req.server"]], "krb5_kdc_req.till (c member)": [[852, "c.krb5_kdc_req.till"]], "krb5_kdc_req.unenc_authdata (c member)": [[852, "c.krb5_kdc_req.unenc_authdata"]], "krb5_key (c type)": [[853, "c.krb5_key"]], "krb5_keyblock (c type)": [[854, "c.krb5_keyblock"]], "krb5_keyblock.contents (c member)": [[854, "c.krb5_keyblock.contents"]], "krb5_keyblock.enctype (c member)": [[854, "c.krb5_keyblock.enctype"]], "krb5_keyblock.length (c member)": [[854, "c.krb5_keyblock.length"]], "krb5_keyblock.magic (c member)": [[854, "c.krb5_keyblock.magic"]], "krb5_keytab (c type)": [[855, "c.krb5_keytab"]], "krb5_keytab_entry (c type)": [[856, "c.krb5_keytab_entry"]], "krb5_keytab_entry.key (c member)": [[856, "c.krb5_keytab_entry.key"]], "krb5_keytab_entry.magic (c member)": [[856, "c.krb5_keytab_entry.magic"]], "krb5_keytab_entry.principal (c member)": [[856, "c.krb5_keytab_entry.principal"]], "krb5_keytab_entry.timestamp (c member)": [[856, "c.krb5_keytab_entry.timestamp"]], "krb5_keytab_entry.vno (c member)": [[856, "c.krb5_keytab_entry.vno"]], "krb5_keyusage (c type)": [[857, "c.krb5_keyusage"]], "krb5_kt_cursor (c type)": [[858, "c.krb5_kt_cursor"]], "krb5_kvno (c type)": [[859, "c.krb5_kvno"]], "krb5_last_req_entry (c type)": [[860, "c.krb5_last_req_entry"]], "krb5_last_req_entry.lr_type (c member)": [[860, "c.krb5_last_req_entry.lr_type"]], "krb5_last_req_entry.magic (c member)": [[860, "c.krb5_last_req_entry.magic"]], "krb5_last_req_entry.value (c member)": [[860, "c.krb5_last_req_entry.value"]], "krb5_magic (c type)": [[861, "c.krb5_magic"]], "krb5_mk_req_checksum_func (c type)": [[862, "c.krb5_mk_req_checksum_func"]], "krb5_msgtype (c type)": [[863, "c.krb5_msgtype"]], "krb5_octet (c type)": [[864, "c.krb5_octet"]], "krb5_pa_data (c type)": [[865, "c.krb5_pa_data"]], "krb5_pa_data.contents (c member)": [[865, "c.krb5_pa_data.contents"]], "krb5_pa_data.length (c member)": [[865, "c.krb5_pa_data.length"]], "krb5_pa_data.magic (c member)": [[865, "c.krb5_pa_data.magic"]], "krb5_pa_data.pa_type (c member)": [[865, "c.krb5_pa_data.pa_type"]], "krb5_pa_pac_req (c type)": [[866, "c.krb5_pa_pac_req"]], "krb5_pa_pac_req.include_pac (c member)": [[866, "c.krb5_pa_pac_req.include_pac"]], "krb5_pa_server_referral_data (c type)": [[867, "c.krb5_pa_server_referral_data"]], "krb5_pa_server_referral_data.referral_valid_until (c member)": [[867, "c.krb5_pa_server_referral_data.referral_valid_until"]], "krb5_pa_server_referral_data.referred_realm (c member)": [[867, "c.krb5_pa_server_referral_data.referred_realm"]], "krb5_pa_server_referral_data.rep_cksum (c member)": [[867, "c.krb5_pa_server_referral_data.rep_cksum"]], "krb5_pa_server_referral_data.requested_principal_name (c member)": [[867, "c.krb5_pa_server_referral_data.requested_principal_name"]], "krb5_pa_server_referral_data.true_principal_name (c member)": [[867, "c.krb5_pa_server_referral_data.true_principal_name"]], "krb5_pa_svr_referral_data (c type)": [[868, "c.krb5_pa_svr_referral_data"]], "krb5_pa_svr_referral_data.principal (c member)": [[868, "c.krb5_pa_svr_referral_data.principal"]], "krb5_pac (c type)": [[869, "c.krb5_pac"]], "krb5_pointer (c type)": [[870, "c.krb5_pointer"]], "krb5_post_recv_fn (c type)": [[871, "c.krb5_post_recv_fn"]], "krb5_pre_send_fn (c type)": [[872, "c.krb5_pre_send_fn"]], "krb5_preauthtype (c type)": [[873, "c.krb5_preauthtype"]], "krb5_principal (c type)": [[874, "c.krb5_principal"]], "krb5_principal.data (c member)": [[874, "c.krb5_principal.data"]], "krb5_principal.length (c member)": [[874, "c.krb5_principal.length"]], "krb5_principal.magic (c member)": [[874, "c.krb5_principal.magic"]], "krb5_principal.realm (c member)": [[874, "c.krb5_principal.realm"]], "krb5_principal.type (c member)": [[874, "c.krb5_principal.type"]], "krb5_principal_data (c type)": [[875, "c.krb5_principal_data"]], "krb5_principal_data.data (c member)": [[875, "c.krb5_principal_data.data"]], "krb5_principal_data.length (c member)": [[875, "c.krb5_principal_data.length"]], "krb5_principal_data.magic (c member)": [[875, "c.krb5_principal_data.magic"]], "krb5_principal_data.realm (c member)": [[875, "c.krb5_principal_data.realm"]], "krb5_principal_data.type (c member)": [[875, "c.krb5_principal_data.type"]], "krb5_prompt (c type)": [[876, "c.krb5_prompt"]], "krb5_prompt.hidden (c member)": [[876, "c.krb5_prompt.hidden"]], "krb5_prompt.prompt (c member)": [[876, "c.krb5_prompt.prompt"]], "krb5_prompt.reply (c member)": [[876, "c.krb5_prompt.reply"]], "krb5_prompt_type (c type)": [[877, "c.krb5_prompt_type"]], "krb5_prompter_fct (c type)": [[878, "c.krb5_prompter_fct"]], "krb5_pwd_data (c type)": [[879, "c.krb5_pwd_data"]], "krb5_pwd_data.element (c member)": [[879, "c.krb5_pwd_data.element"]], "krb5_pwd_data.magic (c member)": [[879, "c.krb5_pwd_data.magic"]], "krb5_pwd_data.sequence_count (c member)": [[879, "c.krb5_pwd_data.sequence_count"]], "krb5_rcache (c type)": [[880, "c.krb5_rcache"]], "krb5_replay_data (c type)": [[881, "c.krb5_replay_data"]], "krb5_replay_data.seq (c member)": [[881, "c.krb5_replay_data.seq"]], "krb5_replay_data.timestamp (c member)": [[881, "c.krb5_replay_data.timestamp"]], "krb5_replay_data.usec (c member)": [[881, "c.krb5_replay_data.usec"]], "krb5_responder_context (c type)": [[882, "c.krb5_responder_context"]], "krb5_responder_fn (c type)": [[883, "c.krb5_responder_fn"]], "krb5_responder_otp_challenge (c type)": [[884, "c.krb5_responder_otp_challenge"]], "krb5_responder_otp_challenge.service (c member)": [[884, "c.krb5_responder_otp_challenge.service"]], "krb5_responder_otp_challenge.tokeninfo (c member)": [[884, "c.krb5_responder_otp_challenge.tokeninfo"]], "krb5_responder_otp_tokeninfo (c type)": [[885, "c.krb5_responder_otp_tokeninfo"]], "krb5_responder_otp_tokeninfo.alg_id (c member)": [[885, "c.krb5_responder_otp_tokeninfo.alg_id"]], "krb5_responder_otp_tokeninfo.challenge (c member)": [[885, "c.krb5_responder_otp_tokeninfo.challenge"]], "krb5_responder_otp_tokeninfo.flags (c member)": [[885, "c.krb5_responder_otp_tokeninfo.flags"]], "krb5_responder_otp_tokeninfo.format (c member)": [[885, "c.krb5_responder_otp_tokeninfo.format"]], "krb5_responder_otp_tokeninfo.length (c member)": [[885, "c.krb5_responder_otp_tokeninfo.length"]], "krb5_responder_otp_tokeninfo.token_id (c member)": [[885, "c.krb5_responder_otp_tokeninfo.token_id"]], "krb5_responder_otp_tokeninfo.vendor (c member)": [[885, "c.krb5_responder_otp_tokeninfo.vendor"]], "krb5_responder_pkinit_challenge (c type)": [[886, "c.krb5_responder_pkinit_challenge"]], "krb5_responder_pkinit_challenge.identities (c member)": [[886, "c.krb5_responder_pkinit_challenge.identities"]], "krb5_responder_pkinit_identity (c type)": [[887, "c.krb5_responder_pkinit_identity"]], "krb5_responder_pkinit_identity.identity (c member)": [[887, "c.krb5_responder_pkinit_identity.identity"]], "krb5_responder_pkinit_identity.token_flags (c member)": [[887, "c.krb5_responder_pkinit_identity.token_flags"]], "krb5_response (c type)": [[888, "c.krb5_response"]], "krb5_response.expected_nonce (c member)": [[888, "c.krb5_response.expected_nonce"]], "krb5_response.magic (c member)": [[888, "c.krb5_response.magic"]], "krb5_response.message_type (c member)": [[888, "c.krb5_response.message_type"]], "krb5_response.request_time (c member)": [[888, "c.krb5_response.request_time"]], "krb5_response.response (c member)": [[888, "c.krb5_response.response"]], "krb5_ticket (c type)": [[889, "c.krb5_ticket"]], "krb5_ticket.enc_part (c member)": [[889, "c.krb5_ticket.enc_part"]], "krb5_ticket.enc_part2 (c member)": [[889, "c.krb5_ticket.enc_part2"]], "krb5_ticket.magic (c member)": [[889, "c.krb5_ticket.magic"]], "krb5_ticket.server (c member)": [[889, "c.krb5_ticket.server"]], "krb5_ticket_times (c type)": [[890, "c.krb5_ticket_times"]], "krb5_ticket_times.authtime (c member)": [[890, "c.krb5_ticket_times.authtime"]], "krb5_ticket_times.endtime (c member)": [[890, "c.krb5_ticket_times.endtime"]], "krb5_ticket_times.renew_till (c member)": [[890, "c.krb5_ticket_times.renew_till"]], "krb5_ticket_times.starttime (c member)": [[890, "c.krb5_ticket_times.starttime"]], "krb5_timestamp (c type)": [[891, "c.krb5_timestamp"]], "krb5_tkt_authent (c type)": [[892, "c.krb5_tkt_authent"]], "krb5_tkt_authent.ap_options (c member)": [[892, "c.krb5_tkt_authent.ap_options"]], "krb5_tkt_authent.authenticator (c member)": [[892, "c.krb5_tkt_authent.authenticator"]], "krb5_tkt_authent.magic (c member)": [[892, "c.krb5_tkt_authent.magic"]], "krb5_tkt_authent.ticket (c member)": [[892, "c.krb5_tkt_authent.ticket"]], "krb5_tkt_creds_context (c type)": [[893, "c.krb5_tkt_creds_context"]], "krb5_trace_callback (c type)": [[894, "c.krb5_trace_callback"]], "krb5_trace_info (c type)": [[895, "c.krb5_trace_info"]], "krb5_trace_info.message (c member)": [[895, "c.krb5_trace_info.message"]], "krb5_transited (c type)": [[896, "c.krb5_transited"]], "krb5_transited.magic (c member)": [[896, "c.krb5_transited.magic"]], "krb5_transited.tr_contents (c member)": [[896, "c.krb5_transited.tr_contents"]], "krb5_transited.tr_type (c member)": [[896, "c.krb5_transited.tr_type"]], "krb5_typed_data (c type)": [[897, "c.krb5_typed_data"]], "krb5_typed_data.data (c member)": [[897, "c.krb5_typed_data.data"]], "krb5_typed_data.length (c member)": [[897, "c.krb5_typed_data.length"]], "krb5_typed_data.magic (c member)": [[897, "c.krb5_typed_data.magic"]], "krb5_typed_data.type (c member)": [[897, "c.krb5_typed_data.type"]], "krb5_ui_2 (c type)": [[898, "c.krb5_ui_2"]], "krb5_ui_4 (c type)": [[899, "c.krb5_ui_4"]], "krb5_verify_init_creds_opt (c type)": [[900, "c.krb5_verify_init_creds_opt"]], "krb5_verify_init_creds_opt.ap_req_nofail (c member)": [[900, "c.krb5_verify_init_creds_opt.ap_req_nofail"]], "krb5_verify_init_creds_opt.flags (c member)": [[900, "c.krb5_verify_init_creds_opt.flags"]], "passwd_phrase_element (c type)": [[901, "c.passwd_phrase_element"]], "passwd_phrase_element.magic (c member)": [[901, "c.passwd_phrase_element.magic"]], "passwd_phrase_element.passwd (c member)": [[901, "c.passwd_phrase_element.passwd"]], "passwd_phrase_element.phrase (c member)": [[901, "c.passwd_phrase_element.phrase"]], "rfc 4120#section-10": [[907, "index-0"]], "rfc 6113": [[916, "index-0"], [917, "index-0"], [917, "index-3"], [925, "index-13"], [925, "index-14"], [929, "index-1"]], "rfc 1964": [[917, "index-4"]], "rfc 3961": [[917, "index-1"], [917, "index-2"], [919, "index-1"], [922, "index-0"]], "rfc 1606": [[918, "index-0"]], "rfc 8070": [[919, "index-0"]], "rfc 3244": [[925, "index-0"]], "rfc 4120#section-5.2.7.2": [[925, "index-12"]], "rfc 4120#section-5.2.7.3": [[925, "index-11"]], "rfc 5587": [[925, "index-9"]], "rfc 5588": [[925, "index-6"]], "rfc 5801": [[925, "index-8"]], "rfc 5896": [[925, "index-1"]], "rfc 6112": [[925, "index-4"]], "rfc 6113#section-5.2": [[925, "index-16"]], "rfc 6560": [[925, "index-10"]], "rfc 6803": [[925, "index-7"]], "rfc 4120": [[929, "index-0"]]}})krb5-1.22.1/doc/html/search.html0000664000175000017500000001211015051422714016202 0ustar ghudsonghudson Search — MIT Kerberos Documentation krb5-1.22.1/doc/html/genindex-P.html0000664000175000017500000001212115051422714016735 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/plugindev/0000775000175000017500000000000015051422713016050 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/plugindev/index.html0000664000175000017500000002502015051422713020044 0ustar ghudsonghudson For plugin module developers — MIT Kerberos Documentation
krb5-1.22.1/doc/html/plugindev/gssapi.html0000664000175000017500000003731515051422713020235 0ustar ghudsonghudson GSSAPI mechanism interface — MIT Kerberos Documentation

GSSAPI mechanism interface¶

The GSSAPI library in MIT krb5 can load mechanism modules to augment the set of built-in mechanisms.

A mechanism module is a Unix shared object or Windows DLL, built separately from the krb5 tree. Modules are loaded according to the GSS mechanism config files described in GSSAPI mechanism modules.

For the most part, a GSSAPI mechanism module exports the same functions as would a GSSAPI implementation itself, with the same function signatures. The mechanism selection layer within the GSSAPI library (called the “mechglueâ€) will dispatch calls from the application to the module if the module’s mechanism is requested. If a module does not wish to implement a GSSAPI extension, it can simply refrain from exporting it, and the mechglue will fail gracefully if the application calls that function.

The mechglue does not invoke a module’s gss_add_cred, gss_add_cred_from, gss_add_cred_impersonate_name, or gss_add_cred_with_password function. A mechanism only needs to implement the “acquire†variants of those functions.

A module does not need to coordinate its minor status codes with those of other mechanisms. If the mechglue detects conflicts, it will map the mechanism’s status codes onto unique values, and then map them back again when gss_display_status is called.

NegoEx modules¶

Some Windows GSSAPI mechanisms can only be negotiated via a Microsoft extension to SPNEGO called NegoEx. Beginning with release 1.18, mechanism modules can support NegoEx as follows:

  • Implement the gssspi_query_meta_data(), gssspi_exchange_meta_data(), and gssspi_query_mechanism_info() SPIs declared in <gssapi/gssapi_ext.h>.

  • Implement gss_inquire_sec_context_by_oid() and answer the GSS_C_INQ_NEGOEX_KEY and GSS_C_INQ_NEGOEX_VERIFY_KEY OIDs to provide the checksum keys for outgoing and incoming checksums, respectively. The answer must be in two buffers: the first buffer contains the key contents, and the second buffer contains the key encryption type as a four-byte little-endian integer.

By default, NegoEx mechanisms will not be directly negotiated via SPNEGO. If direct SPNEGO negotiation is required for interoperability, implement gss_inquire_attrs_for_mech() and assert the GSS_C_MA_NEGOEX_AND_SPNEGO attribute (along with any applicable RFC 5587 attributes).

Interposer modules¶

The mechglue also supports a kind of loadable module, called an interposer module, which intercepts calls to existing mechanisms rather than implementing a new mechanism.

An interposer module must export the symbol gss_mech_interposer with the following signature:

gss_OID_set gss_mech_interposer(gss_OID mech_type);

This function is invoked with the OID of the interposer mechanism as specified in the mechanism config file, and returns a set of mechanism OIDs to be interposed. The returned OID set must have been created using the mechglue’s gss_create_empty_oid_set and gss_add_oid_set_member functions.

An interposer module must use the prefix gssi_ for the GSSAPI functions it exports, instead of the prefix gss_. In most cases, unexported gssi_ functions will result in failure from their corresponding gss_ calls.

An interposer module can link against the GSSAPI library in order to make calls to the original mechanism. To do so, it must specify a special mechanism OID which is the concatention of the interposer’s own OID byte string and the original mechanism’s OID byte string.

Functions that do not accept a mechanism argument directly require no special handling, with the following exceptions:

Since gss_accept_sec_context does not accept a mechanism argument, an interposer mechanism must, in order to invoke the original mechanism’s function, acquire a credential for the concatenated OID and pass that as the verifier_cred_handle parameter.

Since gss_import_name, gss_import_cred, and gss_import_sec_context do not accept mechanism parameters, the SPI has been extended to include variants which do. This allows the interposer module to know which mechanism should be used to interpret the token. These functions have the following signatures:

OM_uint32 gssi_import_sec_context_by_mech(OM_uint32 *minor_status,
    gss_OID desired_mech, gss_buffer_t interprocess_token,
    gss_ctx_id_t *context_handle);

OM_uint32 gssi_import_name_by_mech(OM_uint32 *minor_status,
    gss_OID mech_type, gss_buffer_t input_name_buffer,
    gss_OID input_name_type, gss_name_t output_name);

OM_uint32 gssi_import_cred_by_mech(OM_uint32 *minor_status,
    gss_OID mech_type, gss_buffer_t token,
    gss_cred_id_t *cred_handle);

To re-enter the original mechanism when importing tokens for the above functions, the interposer module must wrap the mechanism token in the mechglue’s format, using the concatenated OID (except in gss_import_name). The mechglue token formats are:

  • For gss_import_sec_context, a four-byte OID length in big-endian order, followed by the concatenated OID, followed by the mechanism token.

  • For gss_import_name, the bytes 04 01, followed by a two-byte OID length in big-endian order, followed by the mechanism OID, followed by a four-byte token length in big-endian order, followed by the mechanism token. Unlike most uses of OIDs in the API, the mechanism OID encoding must include the DER tag and length for an object identifier (06 followed by the DER length of the OID byte string), and this prefix must be included in the two-byte OID length. input_name_type must also be set to GSS_C_NT_EXPORT_NAME.

  • For gss_import_cred, a four-byte OID length in big-endian order, followed by the concatenated OID, followed by a four-byte token length in big-endian order, followed by the mechanism token. This sequence may be repeated multiple times.

krb5-1.22.1/doc/html/plugindev/general.html0000664000175000017500000004123415051422713020357 0ustar ghudsonghudson General plugin concepts — MIT Kerberos Documentation

General plugin concepts¶

A krb5 dynamic plugin module is a Unix shared object or Windows DLL. Typically, the source code for a dynamic plugin module should live in its own project with a build system using automake and libtool, or tools with similar functionality.

A plugin module must define a specific symbol name, which depends on the pluggable interface and module name. For most pluggable interfaces, the exported symbol is a function named INTERFACE_MODULE_initvt, where INTERFACE is the name of the pluggable interface and MODULE is the name of the module. For these interfaces, it is possible for one shared object or DLL to implement multiple plugin modules, either for the same pluggable interface or for different ones. For example, a shared object could implement both KDC and client preauthentication mechanisms, by exporting functions named kdcpreauth_mymech_initvt and clpreauth_mymech_initvt.

A plugin module implementation should include the header file <krb5/INTERFACE_plugin.h>, where INTERFACE is the name of the pluggable interface. For instance, a ccselect plugin module implementation should use #include <krb5/ccselect_plugin.h>.

initvt functions have the following prototype:

krb5_error_code interface_modname_initvt(krb5_context context,
                                         int maj_ver, int min_ver,
                                         krb5_plugin_vtable vtable);

and should do the following:

  1. Check that the supplied maj_ver argument is supported by the module. If it is not supported, the function should return KRB5_PLUGIN_VER_NOTSUPP.

  2. Cast the supplied vtable pointer to the structure type corresponding to the major version, as documented in the pluggable interface header file.

  3. Fill in the structure fields with pointers to method functions and static data, stopping at the field indicated by the supplied minor version. Fields for unimplemented optional methods can be left alone; it is not necessary to initialize them to NULL.

In most cases, the context argument will not be used. The initvt function should not allocate memory; think of it as a glorified structure initializer. Each pluggable interface defines methods for allocating and freeing module state if doing so is necessary for the interface.

Pluggable interfaces typically include a name field in the vtable structure, which should be filled in with a pointer to a string literal containing the module name.

Here is an example of what an initvt function might look like for a fictional pluggable interface named fences, for a module named “wickerâ€:

krb5_error_code
fences_wicker_initvt(krb5_context context, int maj_ver,
                     int min_ver, krb5_plugin_vtable vtable)
{
    krb5_ccselect_vtable vt;

    if (maj_ver == 1) {
        krb5_fences_vtable vt = (krb5_fences_vtable)vtable;
        vt->name = "wicker";
        vt->slats = wicker_slats;
        vt->braces = wicker_braces;
    } else if (maj_ver == 2) {
        krb5_fences_vtable_v2 vt = (krb5_fences_vtable_v2)vtable;
        vt->name = "wicker";
        vt->material = wicker_material;
        vt->construction = wicker_construction;
        if (min_ver < 2)
            return 0;
        vt->footing = wicker_footing;
        if (min_ver < 3)
            return 0;
        vt->appearance = wicker_appearance;
    } else {
        return KRB5_PLUGIN_VER_NOTSUPP;
    }
    return 0;
}

Logging from KDC and kadmind plugin modules¶

Plugin modules for the KDC or kadmind daemons can write to the configured logging outputs (see [logging]) by calling the com_err function. The first argument (whoami) is ignored. If the second argument (code) is zero, the formatted message is logged at informational severity; otherwise, the formatted message is logged at error severity and includes the error message for the supplied code. Here are examples:

com_err("", 0, "Client message contains %d items", nitems);
com_err("", retval, "while decoding client message");

(The behavior described above is new in release 1.17. In prior releases, the whoami argument is included for some logging output types, the logged message does not include the usual header for some output types, and the severity for syslog outputs is configured as part of the logging specification, defaulting to error severity.)

krb5-1.22.1/doc/html/plugindev/hostrealm.html0000664000175000017500000002176515051422713020747 0ustar ghudsonghudson Host-to-realm interface (hostrealm) — MIT Kerberos Documentation

Host-to-realm interface (hostrealm)¶

The host-to-realm interface was first introduced in release 1.12. It allows modules to control the local mapping of hostnames to realm names as well as the default realm. For a detailed description of the hostrealm interface, see the header file <krb5/hostrealm_plugin.h>.

Although the mapping methods in the hostrealm interface return a list of one or more realms, only the first realm in the list is currently used by callers. Callers may begin using later responses in the future.

Any mapping method may return KRB5_PLUGIN_NO_HANDLE to defer processing to a later module.

A module can create and destroy per-library-context state objects using the init and fini methods. If the module does not need any state, it does not need to implement these methods.

The optional host_realm method allows a module to determine authoritative realm mappings for a hostname. The first authoritative mapping is used in preference to KDC referrals when getting service credentials.

The optional fallback_realm method allows a module to determine fallback mappings for a hostname. The first fallback mapping is tried if there is no authoritative mapping for a realm, and KDC referrals failed to produce a successful result.

The optional default_realm method allows a module to determine the local default realm.

If a module implements any of the above methods, it must also implement free_list to ensure that memory is allocated and deallocated consistently.

krb5-1.22.1/doc/html/plugindev/internal.html0000664000175000017500000002210115051422713020546 0ustar ghudsonghudson Internal pluggable interfaces — MIT Kerberos Documentation

Internal pluggable interfaces¶

Following are brief discussions of pluggable interfaces which have not yet been made public. These interfaces are functional, but the interfaces are likely to change in incompatible ways from release to release. In some cases, it may be necessary to copy header files from the krb5 source tree to use an internal interface. Use these with care, and expect to need to update your modules for each new release of MIT krb5.

Kerberos database interface (KDB)¶

A KDB module implements a database back end for KDC principal and policy information, and can also control many aspects of KDC behavior. For a full description of the interface, see the header file <kdb.h>.

The KDB pluggable interface is often referred to as the DAL (Database Access Layer).

Authorization data interface (authdata)¶

The authdata interface allows a module to provide (from the KDC) or consume (in application servers) authorization data of types beyond those handled by the core MIT krb5 code base. The interface is defined in the header file <krb5/authdata_plugin.h>, which is not installed by the build.

krb5-1.22.1/doc/html/plugindev/certauth.html0000664000175000017500000002232415051422713020560 0ustar ghudsonghudson PKINIT certificate authorization interface (certauth) — MIT Kerberos Documentation

PKINIT certificate authorization interface (certauth)¶

The certauth interface was first introduced in release 1.16. It allows customization of the X.509 certificate attribute requirements placed on certificates used by PKINIT enabled clients. For a detailed description of the certauth interface, see the header file <krb5/certauth_plugin.h>

A certauth module implements the authorize method to determine whether a client’s certificate is authorized to authenticate a client principal. authorize receives the DER-encoded certificate, the requested client principal, and a pointer to the client’s krb5_db_entry (for modules that link against libkdb5). The method must decode the certificate and inspect its attributes to determine if it should authorize PKINIT authentication. It returns the authorization status and optionally outputs a list of authentication indicator strings to be added to the ticket.

Beginning in release 1.19, the authorize method can request that the hardware authentication bit be set in the ticket by returning KRB5_CERTAUTH_HWAUTH. Beginning in release 1.20, the authorize method can return KRB5_CERTAUTH_HWAUTH_PASS to request that the hardware authentication bit be set in the ticket but otherwise defer authorization to another certauth module. A module must use its own internal or library-provided ASN.1 certificate decoder.

A module can optionally create and destroy module data with the init and fini methods. Module data objects last for the lifetime of the KDC process.

If a module allocates and returns a list of authentication indicators from authorize, it must also implement the free_ind method to free the list.

krb5-1.22.1/doc/html/plugindev/kadm5_hook.html0000664000175000017500000002134315051422713020762 0ustar ghudsonghudson KADM5 hook interface (kadm5_hook) — MIT Kerberos Documentation

KADM5 hook interface (kadm5_hook)¶

The kadm5_hook interface allows modules to perform actions when changes are made to the Kerberos database through kadmin. For a detailed description of the kadm5_hook interface, see the header file <krb5/kadm5_hook_plugin.h>.

The kadm5_hook interface has five primary methods: chpass, create, modify, remove, and rename. (The rename method was introduced in release 1.14.) Each of these methods is called twice when the corresponding administrative action takes place, once before the action is committed and once afterwards. A module can prevent the action from taking place by returning an error code during the pre-commit stage.

A module can create and destroy per-process state objects by implementing the init and fini methods. State objects have the type kadm5_hook_modinfo, which is an abstract pointer type. A module should typically cast this to an internal type for the state object.

Because the kadm5_hook interface is tied closely to the kadmin interface (which is explicitly unstable), it may not remain as stable across versions as other public pluggable interfaces.

krb5-1.22.1/doc/html/plugindev/profile.html0000664000175000017500000004020115051422713020373 0ustar ghudsonghudson Configuration interface (profile) — MIT Kerberos Documentation

Configuration interface (profile)¶

The profile interface allows a module to control how krb5 configuration information is obtained by the Kerberos library and applications. For a detailed description of the profile interface, see the header file <profile.h>.

Note

The profile interface does not follow the normal conventions for MIT krb5 pluggable interfaces, because it is part of a lower-level component of the krb5 library.

As with other types of plugin modules, a profile module is a Unix shared object or Windows DLL, built separately from the krb5 tree. The krb5 library will dynamically load and use a profile plugin module if it reads a module directive at the beginning of krb5.conf, as described in Configuration profile modules.

A profile module exports a function named profile_module_init matching the signature of the profile_module_init_fn type. This function accepts a residual string, which may be used to help locate the configuration source. The function fills in a vtable and may also create a per-profile state object. If the module uses state objects, it should implement the copy and cleanup methods to manage them.

A basic read-only profile module need only implement the get_values and free_values methods. The get_values method accepts a null-terminated list of C string names (e.g., an array containing “libdefaultsâ€, “clockskewâ€, and NULL for the clockskew variable in the [libdefaults] section) and returns a null-terminated list of values, which will be cleaned up with the free_values method when the caller is done with them.

Iterable profile modules must also define the iterator_create, iterator, iterator_free, and free_string methods. The core krb5 code does not require profiles to be iterable, but some applications may iterate over the krb5 profile object in order to present configuration interfaces.

Writable profile modules must also define the writable, modified, update_relation, rename_section, add_relation, and flush methods. The core krb5 code does not require profiles to be writable, but some applications may write to the krb5 profile in order to present configuration interfaces.

The following is an example of a very basic read-only profile module which returns a hardcoded value for the default_realm variable in [libdefaults], and provides no other configuration information. (For conciseness, the example omits code for checking the return values of malloc and strdup.)

#include <stdlib.h>
#include <string.h>
#include <profile.h>

static long
get_values(void *cbdata, const char *const *names, char ***values)
{
    if (names[0] != NULL && strcmp(names[0], "libdefaults") == 0 &&
        names[1] != NULL && strcmp(names[1], "default_realm") == 0) {
        *values = malloc(2 * sizeof(char *));
        (*values)[0] = strdup("ATHENA.MIT.EDU");
        (*values)[1] = NULL;
        return 0;
    }
    return PROF_NO_RELATION;
}

static void
free_values(void *cbdata, char **values)
{
    char **v;

    for (v = values; *v; v++)
        free(*v);
    free(values);
}

long
profile_module_init(const char *residual, struct profile_vtable *vtable,
                    void **cb_ret);

long
profile_module_init(const char *residual, struct profile_vtable *vtable,
                    void **cb_ret)
{
    *cb_ret = NULL;
    vtable->get_values = get_values;
    vtable->free_values = free_values;
    return 0;
}
krb5-1.22.1/doc/html/plugindev/clpreauth.html0000664000175000017500000002530315051422713020730 0ustar ghudsonghudson Client preauthentication interface (clpreauth) — MIT Kerberos Documentation

Client preauthentication interface (clpreauth)¶

During an initial ticket request, a KDC may ask a client to prove its knowledge of the password before issuing an encrypted ticket, or to use credentials other than a password. This process is called preauthentication, and is described in RFC 4120 and RFC 6113. The clpreauth interface allows the addition of client support for preauthentication mechanisms beyond those included in the core MIT krb5 code base. For a detailed description of the clpreauth interface, see the header file <krb5/clpreauth_plugin.h> (or <krb5/preauth_plugin.h> before release 1.12).

A clpreauth module is generally responsible for:

  • Supplying a list of preauth type numbers used by the module in the pa_type_list field of the vtable structure.

  • Indicating what kind of preauthentication mechanism it implements, with the flags method. In the most common case, this method just returns PA_REAL, indicating that it implements a normal preauthentication type.

  • Examining the padata information included in a PREAUTH_REQUIRED or MORE_PREAUTH_DATA_REQUIRED error and producing padata values for the next AS request. This is done with the process method.

  • Examining the padata information included in a successful ticket reply, possibly verifying the KDC identity and computing a reply key. This is also done with the process method.

  • For preauthentication types which support it, recovering from errors by examining the error data from the KDC and producing a padata value for another AS request. This is done with the tryagain method.

  • Receiving option information (supplied by kinit -X or by an application), with the gic_opts method.

A clpreauth module can create and destroy per-library-context and per-request state objects by implementing the init, fini, request_init, and request_fini methods. Per-context state objects have the type krb5_clpreauth_moddata, and per-request state objects have the type krb5_clpreauth_modreq. These are abstract pointer types; a module should typically cast these to internal types for the state objects.

The process and tryagain methods have access to a callback function and handle (called a “rockâ€) which can be used to get additional information about the current request, including the expected enctype of the AS reply, the FAST armor key, and the client long-term key (prompting for the user password if necessary). A callback can also be used to replace the AS reply key if the preauthentication mechanism computes one.

krb5-1.22.1/doc/html/plugindev/kdcpolicy.html0000664000175000017500000002101415051422713020715 0ustar ghudsonghudson KDC policy interface (kdcpolicy) — MIT Kerberos Documentation

KDC policy interface (kdcpolicy)¶

The kdcpolicy interface was first introduced in release 1.16. It allows modules to veto otherwise valid AS and TGS requests or restrict the lifetime and renew time of the resulting ticket. For a detailed description of the kdcpolicy interface, see the header file <krb5/kdcpolicy_plugin.h>.

The optional check_as and check_tgs functions allow the module to perform access control. Additionally, a module can create and destroy module data with the init and fini methods. Module data objects last for the lifetime of the KDC process, and are provided to all other methods. The data has the type krb5_kdcpolicy_moddata, which should be cast to the appropriate internal type.

kdcpolicy modules can optionally inspect principal entries. To do this, the module must also include <kdb.h> to gain access to the principal entry structure definition. As the KDB interface is explicitly not as stable as other public interfaces, modules which do this may not retain compatibility across releases.

krb5-1.22.1/doc/html/plugindev/localauth.html0000664000175000017500000002536115051422713020721 0ustar ghudsonghudson Local authorization interface (localauth) — MIT Kerberos Documentation

Local authorization interface (localauth)¶

The localauth interface was first introduced in release 1.12. It allows modules to control the relationship between Kerberos principals and local system accounts. When an application calls krb5_kuserok() or krb5_aname_to_localname(), localauth modules are consulted to determine the result. For a detailed description of the localauth interface, see the header file <krb5/localauth_plugin.h>.

A module can create and destroy per-library-context state objects using the init and fini methods. If the module does not need any state, it does not need to implement these methods.

The optional userok method allows a module to control the behavior of krb5_kuserok(). The module receives the authenticated name and the local account name as inputs, and can return either 0 to authorize access, KRB5_PLUGIN_NO_HANDLE to defer the decision to other modules, or another error (canonically EPERM) to authoritatively deny access. Access is granted if at least one module grants access and no module authoritatively denies access.

The optional an2ln method can work in two different ways. If the module sets an array of uppercase type names in an2ln_types, then the module’s an2ln method will only be invoked by krb5_aname_to_localname() if an auth_to_local value in krb5.conf refers to one of the module’s types. In this case, the type and residual arguments will give the type name and residual string of the auth_to_local value.

If the module does not set an2ln_types but does implement an2ln, the module’s an2ln method will be invoked for all krb5_aname_to_localname() operations unless an earlier module determines a mapping, with type and residual set to NULL. The module can return KRB5_LNAME_NO_TRANS to defer mapping to later modules.

If a module implements an2ln, it must also implement free_string to ensure that memory is allocated and deallocated consistently.

krb5-1.22.1/doc/html/plugindev/ccselect.html0000664000175000017500000002110515051422713020522 0ustar ghudsonghudson Credential cache selection interface (ccselect) — MIT Kerberos Documentation

Credential cache selection interface (ccselect)¶

The ccselect interface allows modules to control how credential caches are chosen when a GSSAPI client contacts a service. For a detailed description of the ccselect interface, see the header file <krb5/ccselect_plugin.h>.

The primary ccselect method is choose, which accepts a server principal as input and returns a ccache and/or principal name as output. A module can use the krb5_cccol APIs to iterate over the cache collection in order to find an appropriate ccache to use.

A module can create and destroy per-library-context state objects by implementing the init and fini methods. State objects have the type krb5_ccselect_moddata, which is an abstract pointer type. A module should typically cast this to an internal type for the state object.

A module can have one of two priorities, “authoritative†or “heuristicâ€. Results from authoritative modules, if any are available, will take priority over results from heuristic modules. A module communicates its priority as a result of the init method.

krb5-1.22.1/doc/html/plugindev/locate.html0000664000175000017500000002140215051422713020204 0ustar ghudsonghudson Server location interface (locate) — MIT Kerberos Documentation

Server location interface (locate)¶

The locate interface allows modules to control how KDCs and similar services are located by clients. For a detailed description of the ccselect interface, see the header file <krb5/locate_plugin.h>.

A locate module exports a structure object of type krb5plugin_service_locate_ftable, with the name service_locator. The structure contains a minor version and pointers to the module’s methods.

The primary locate method is lookup, which accepts a service type, realm name, desired socket type, and desired address family (which will be AF_UNSPEC if no specific address family is desired). The method should invoke the callback function once for each server address it wants to return, passing a socket type (SOCK_STREAM for TCP or SOCK_DGRAM for UDP) and socket address. The lookup method should return 0 if it has authoritatively determined the server addresses for the realm, KRB5_PLUGIN_NO_HANDLE if it wants to let other location mechanisms determine the server addresses, or another code if it experienced a failure which should abort the location process.

A module can create and destroy per-library-context state objects by implementing the init and fini methods. State objects have the type void *, and should be cast to an internal type for the state object.

krb5-1.22.1/doc/html/plugindev/kadm5_auth.html0000664000175000017500000002244415051422713020766 0ustar ghudsonghudson kadmin authorization interface (kadm5_auth) — MIT Kerberos Documentation

kadmin authorization interface (kadm5_auth)¶

The kadm5_auth interface (new in release 1.16) allows modules to determine whether a client principal is authorized to perform an operation in the kadmin protocol, and to apply restrictions to principal operations. For a detailed description of the kadm5_auth interface, see the header file <krb5/kadm5_auth_plugin.h>.

A module can create and destroy per-process state objects by implementing the init and fini methods. State objects have the type kadm5_auth_modinfo, which is an abstract pointer type. A module should typically cast this to an internal type for the state object.

The kadm5_auth interface has one method for each kadmin operation, with parameters specific to the operation. Each method can return either 0 to authorize access, KRB5_PLUGIN_NO_HANDLE to defer the decision to other modules, or another error (canonically EPERM) to authoritatively deny access. Access is granted if at least one module grants access and no module authoritatively denies access.

The addprinc and modprinc methods can also impose restrictions on the principal operation by returning a struct kadm5_auth_restrictions object. The module should also implement the free_restrictions method if it dynamically allocates restrictions objects for principal operations.

kadm5_auth modules can optionally inspect principal or policy objects. To do this, the module must also include <kadm5/admin.h> to gain access to the structure definitions for those objects. As the kadmin interface is explicitly not as stable as other public interfaces, modules which do this may not retain compatibility across releases.

krb5-1.22.1/doc/html/plugindev/kdcpreauth.html0000664000175000017500000003042315051422713021072 0ustar ghudsonghudson KDC preauthentication interface (kdcpreauth) — MIT Kerberos Documentation

KDC preauthentication interface (kdcpreauth)¶

The kdcpreauth interface allows the addition of KDC support for preauthentication mechanisms beyond those included in the core MIT krb5 code base. For a detailed description of the kdcpreauth interface, see the header file <krb5/kdcpreauth_plugin.h> (or <krb5/preauth_plugin.h> before release 1.12).

A kdcpreauth module is generally responsible for:

  • Supplying a list of preauth type numbers used by the module in the pa_type_list field of the vtable structure.

  • Indicating what kind of preauthentication mechanism it implements, with the flags method. If the mechanism computes a new reply key, it must specify the PA_REPLACES_KEY flag. If the mechanism is generally only used with hardware tokens, the PA_HARDWARE flag allows the mechanism to work with principals which have the requires_hwauth flag set.

  • Producing a padata value to be sent with a preauth_required error, with the edata method.

  • Examining a padata value sent by a client and verifying that it proves knowledge of the appropriate client credential information. This is done with the verify method.

  • Producing a padata response value for the client, and possibly computing a reply key. This is done with the return_padata method.

A module can create and destroy per-KDC state objects by implementing the init and fini methods. Per-KDC state objects have the type krb5_kdcpreauth_moddata, which is an abstract pointer types. A module should typically cast this to an internal type for the state object.

A module can create a per-request state object by returning one in the verify method, receiving it in the return_padata method, and destroying it in the free_modreq method. Note that these state objects only apply to the processing of a single AS request packet, not to an entire authentication exchange (since an authentication exchange may remain unfinished by the client or may involve multiple different KDC hosts). Per-request state objects have the type krb5_kdcpreauth_modreq, which is an abstract pointer type.

The edata, verify, and return_padata methods have access to a callback function and handle (called a “rockâ€) which can be used to get additional information about the current request, including the maximum allowable clock skew, the client’s long-term keys, the DER-encoded request body, the FAST armor key, string attributes on the client’s database entry, and the client’s database entry itself. The verify method can assert one or more authentication indicators to be included in the issued ticket using the add_auth_indicator callback (new in release 1.14).

A module can generate state information to be included with the next client request using the set_cookie callback (new in release 1.14). On the next request, the module can read this state information using the get_cookie callback. Cookie information is encrypted, timestamped, and transmitted to the client in a PA-FX-COOKIE pa-data item. Older clients may not support cookies and therefore may not transmit the cookie in the next request; in this case, get_cookie will not yield the saved information.

If a module implements a mechanism which requires multiple round trips, its verify method can respond with the code KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and a list of pa-data in the e_data parameter to be processed by the client.

The edata and verify methods can be implemented asynchronously. Because of this, they do not return values directly to the caller, but must instead invoke responder functions with their results. A synchronous implementation can invoke the responder function immediately. An asynchronous implementation can use the callback to get an event context for use with the libverto API.

krb5-1.22.1/doc/html/plugindev/pwqual.html0000664000175000017500000002163715051422713020260 0ustar ghudsonghudson Password quality interface (pwqual) — MIT Kerberos Documentation

Password quality interface (pwqual)¶

The pwqual interface allows modules to control what passwords are allowed when a user changes passwords. For a detailed description of the pwqual interface, see the header file <krb5/pwqual_plugin.h>.

The primary pwqual method is check, which receives a password as input and returns success (0) or a KADM5_PASS_Q_ failure code depending on whether the password is allowed. The check method also receives the principal name and the name of the principal’s password policy as input; although there is no stable interface for the module to obtain the fields of the password policy, it can define its own configuration or data store based on the policy name.

A module can create and destroy per-process state objects by implementing the open and close methods. State objects have the type krb5_pwqual_moddata, which is an abstract pointer type. A module should typically cast this to an internal type for the state object. The open method also receives the name of the realm’s dictionary file (as configured by the dict_file variable in the [realms] section of kdc.conf) if it wishes to use it.

krb5-1.22.1/doc/html/genindex-M.html0000664000175000017500000001160315051422714016736 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/genindex-S.html0000664000175000017500000001145215051422714016746 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/genindex-T.html0000664000175000017500000001507115051422714016750 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/about.html0000664000175000017500000001717715051422656016076 0ustar ghudsonghudson Contributing to the MIT Kerberos Documentation — MIT Kerberos Documentation

Contributing to the MIT Kerberos Documentation¶

We are looking for documentation writers and editors who could contribute towards improving the MIT KC documentation content. If you are an experienced Kerberos developer and/or administrator, please consider sharing your knowledge and experience with the Kerberos Community. You can suggest your own topic or write about any of the topics listed here.

If you have any questions, comments, or suggestions on the existing documents, please send your feedback via email to krb5-bugs@mit.edu. The HTML version of this documentation has a “FEEDBACK†link to the krb5-bugs@mit.edu email address with a pre-constructed subject line.

Background¶

Starting with release 1.11, the Kerberos documentation set is unified in a central form. Man pages, HTML documentation, and PDF documents are compiled from reStructuredText sources, and the application developer documentation incorporates Doxygen markup from the source tree. This project was undertaken along the outline described here.

Previous versions of Kerberos 5 attempted to maintain separate documentation in the texinfo format, with separate groff manual pages. Having the API documentation disjoint from the source code implementing that API resulted in the documentation becoming stale, and over time the documentation ceased to match reality. With a fresh start and a source format that is easier to use and maintain, reStructuredText-based documents should provide an improved experience for the user. Consolidating all the documentation formats into a single source document makes the documentation set easier to maintain.

krb5-1.22.1/doc/html/appdev/0000775000175000017500000000000015051422713015332 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/appdev/y2038.html0000664000175000017500000001773615051422713017023 0ustar ghudsonghudson Year 2038 considerations for uses of krb5_timestamp — MIT Kerberos Documentation

Year 2038 considerations for uses of krb5_timestamp¶

POSIX time values, which measure the number of seconds since January 1 1970, will exceed the maximum value representable in a signed 32-bit integer in January 2038. This documentation describes considerations for consumers of the MIT krb5 libraries.

Applications or libraries which use libkrb5 and consume the timestamps included in credentials or other structures make use of the krb5_timestamp type. For historical reasons, krb5_timestamp is a signed 32-bit integer, even on platforms where a larger type is natively used to represent time values. To behave properly for time values after January 2038, calling code should cast krb5_timestamp values to uint32_t, and then to time_t:

(time_t)(uint32_t)timestamp

Used in this way, krb5_timestamp values can represent time values up until February 2106, provided that the platform uses a 64-bit or larger time_t type. This usage will also remain safe if a later version of MIT krb5 changes krb5_timestamp to an unsigned 32-bit integer.

The GSSAPI only uses representations of time intervals, not absolute times. Callers of the GSSAPI should require no changes to behave correctly after January 2038, provided that they use MIT krb5 release 1.16 or later.

krb5-1.22.1/doc/html/appdev/index.html0000664000175000017500000001560315051422657017343 0ustar ghudsonghudson For application developers — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/gssapi.html0000664000175000017500000023014615051422657017523 0ustar ghudsonghudson Developing with GSSAPI — MIT Kerberos Documentation

Developing with GSSAPI¶

The GSSAPI (Generic Security Services API) allows applications to communicate securely using Kerberos 5 or other security mechanisms. We recommend using the GSSAPI (or a higher-level framework which encompasses GSSAPI, such as SASL) for secure network communication over using the libkrb5 API directly.

GSSAPIv2 is specified in RFC 2743 and RFC 2744. Also see RFC 7546 for a description of how to use the GSSAPI in a client or server program.

This documentation will describe how various ways of using the GSSAPI will behave with the krb5 mechanism as implemented in MIT krb5, as well as krb5-specific extensions to the GSSAPI.

Name types¶

A GSSAPI application can name a local or remote entity by calling gss_import_name, specifying a name type and a value. The following name types are supported by the krb5 mechanism:

  • GSS_C_NT_HOSTBASED_SERVICE: The value should be a string of the form service or service@hostname. This is the most common way to name target services when initiating a security context, and is the most likely name type to work across multiple mechanisms.

  • GSS_KRB5_NT_PRINCIPAL_NAME: The value should be a principal name string. This name type only works with the krb5 mechanism, and is defined in the <gssapi/gssapi_krb5.h> header.

  • GSS_C_NT_USER_NAME or GSS_C_NULL_OID: The value is treated as an unparsed principal name string, as above. These name types may work with mechanisms other than krb5, but will have different interpretations in those mechanisms. GSS_C_NT_USER_NAME is intended to be used with a local username, which will parse into a single-component principal in the default realm.

  • GSS_C_NT_ANONYMOUS: The value is ignored. The anonymous principal is used, allowing a client to authenticate to a server without asserting a particular identity (which may or may not be allowed by a particular server or Kerberos realm).

  • GSS_C_NT_MACHINE_UID_NAME: The value is uid_t object. On Unix-like systems, the username of the uid is looked up in the system user database and the resulting username is parsed as a principal name.

  • GSS_C_NT_STRING_UID_NAME: As above, but the value is a decimal string representation of the uid.

  • GSS_C_NT_EXPORT_NAME: The value must be the result of a gss_export_name call.

  • GSS_KRB5_NT_ENTERPRISE_NAME: The value should be a krb5 enterprise name string (see RFC 6806 section 5), in the form user@suffix. This name type is used to convey alias names, and is defined in the <gssapi/gssapi_krb5.h> header. (New in release 1.17.)

  • GSS_KRB5_NT_X509_CERT: The value should be an X.509 certificate encoded according to RFC 5280. This name form can be used for the desired_name parameter of gss_acquire_cred_impersonate_name(), to identify the S4U2Self user by certificate. (New in release 1.19.)

Initiator credentials¶

A GSSAPI client application uses gss_init_sec_context to establish a security context. The initiator_cred_handle parameter determines what tickets are used to establish the connection. An application can either pass GSS_C_NO_CREDENTIAL to use the default client credential, or it can use gss_acquire_cred beforehand to acquire an initiator credential. The call to gss_acquire_cred may include a desired_name parameter, or it may pass GSS_C_NO_NAME if it does not have a specific name preference.

If the desired name for a krb5 initiator credential is a host-based name, it is converted to a principal name of the form service/hostname in the local realm, where hostname is the local hostname if not specified. The hostname will be canonicalized using forward name resolution, and possibly also using reverse name resolution depending on the value of the rdns variable in [libdefaults].

If a desired name is specified in the call to gss_acquire_cred, the krb5 mechanism will attempt to find existing tickets for that client principal name in the default credential cache or collection. If the default cache type does not support a collection, and the default cache contains credentials for a different principal than the desired name, a GSS_S_CRED_UNAVAIL error will be returned with a minor code indicating a mismatch.

If no existing tickets are available for the desired name, but the name has an entry in the default client keytab, the krb5 mechanism will acquire initial tickets for the name using the default client keytab.

If no desired name is specified, credential acquisition will be deferred until the credential is used in a call to gss_init_sec_context or gss_inquire_cred. If the call is to gss_init_sec_context, the target name will be used to choose a client principal name using the credential cache selection facility. (This facility might, for instance, try to choose existing tickets for a client principal in the same realm as the target service). If there are no existing tickets for the chosen principal, but it is present in the default client keytab, the krb5 mechanism will acquire initial tickets using the keytab.

If the target name cannot be used to select a client principal (because the credentials are used in a call to gss_inquire_cred), or if the credential cache selection facility cannot choose a principal for it, the default credential cache will be selected if it exists and contains tickets.

If the default credential cache does not exist, but the default client keytab does, the krb5 mechanism will try to acquire initial tickets for the first principal in the default client keytab.

If the krb5 mechanism acquires initial tickets using the default client keytab, the resulting tickets will be stored in the default cache or collection, and will be refreshed by future calls to gss_acquire_cred as they approach their expire time.

Acceptor names¶

A GSSAPI server application uses gss_accept_sec_context to establish a security context based on tokens provided by the client. The acceptor_cred_handle parameter determines what keytab entries may be authenticated to by the client, if the krb5 mechanism is used.

The simplest choice is to pass GSS_C_NO_CREDENTIAL as the acceptor credential. In this case, clients may authenticate to any service principal in the default keytab (typically DEFKTNAME, or the value of the KRB5_KTNAME environment variable). This is the recommended approach if the server application has no specific requirements to the contrary.

A server may acquire an acceptor credential with gss_acquire_cred and a cred_usage of GSS_C_ACCEPT or GSS_C_BOTH. If the desired_name parameter is GSS_C_NO_NAME, then clients will be allowed to authenticate to any service principal in the default keytab, just as if no acceptor credential was supplied.

If a server wishes to specify a desired_name to gss_acquire_cred, the most common choice is a host-based name. If the host-based desired_name contains just a service, then clients will be allowed to authenticate to any host-based service principal (that is, a principal of the form service/hostname@REALM) for the named service, regardless of hostname or realm, as long as it is present in the default keytab. If the input name contains both a service and a hostname, clients will be allowed to authenticate to any host-based principal for the named service and hostname, regardless of realm.

Note

If a hostname is specified, it will be canonicalized using forward name resolution, and possibly also using reverse name resolution depending on the value of the rdns variable in [libdefaults].

Note

If the ignore_acceptor_hostname variable in [libdefaults] is enabled, then hostname will be ignored even if one is specified in the input name.

Note

In MIT krb5 versions prior to 1.10, and in Heimdal’s implementation of the krb5 mechanism, an input name with just a service is treated like an input name of service@localhostname, where localhostname is the string returned by gethostname().

If the desired_name is a krb5 principal name or a local system name type which is mapped to a krb5 principal name, clients will only be allowed to authenticate to that principal in the default keytab.

Name Attributes¶

In release 1.8 or later, the gss_inquire_name and gss_get_name_attribute functions, specified in RFC 6680, can be used to retrieve name attributes from the src_name returned by gss_accept_sec_context. The following attributes are defined when the krb5 mechanism is used:

  • “auth-indicators†attribute:

This attribute will be included in the gss_inquire_name output if the ticket contains authentication indicators. One indicator is returned per invocation of gss_get_name_attribute, so multiple invocations may be necessary to retrieve all of the indicators from the ticket. (New in release 1.15.)

Credential store extensions¶

Beginning with release 1.11, the following GSSAPI extensions declared in <gssapi/gssapi_ext.h> can be used to specify how credentials are acquired or stored:

struct gss_key_value_element_struct {
    const char *key;
    const char *value;
};
typedef struct gss_key_value_element_struct gss_key_value_element_desc;

struct gss_key_value_set_struct {
    OM_uint32 count;
    gss_key_value_element_desc *elements;
};
typedef const struct gss_key_value_set_struct gss_key_value_set_desc;
typedef const gss_key_value_set_desc *gss_const_key_value_set_t;

OM_uint32 gss_acquire_cred_from(OM_uint32 *minor_status,
                                const gss_name_t desired_name,
                                OM_uint32 time_req,
                                const gss_OID_set desired_mechs,
                                gss_cred_usage_t cred_usage,
                                gss_const_key_value_set_t cred_store,
                                gss_cred_id_t *output_cred_handle,
                                gss_OID_set *actual_mechs,
                                OM_uint32 *time_rec);

OM_uint32 gss_store_cred_into(OM_uint32 *minor_status,
                              gss_cred_id_t input_cred_handle,
                              gss_cred_usage_t cred_usage,
                              const gss_OID desired_mech,
                              OM_uint32 overwrite_cred,
                              OM_uint32 default_cred,
                              gss_const_key_value_set_t cred_store,
                              gss_OID_set *elements_stored,
                              gss_cred_usage_t *cred_usage_stored);

The additional cred_store parameter allows the caller to specify information about how the credentials should be obtained and stored. The following options are supported by the krb5 mechanism:

  • ccache: For acquiring initiator credentials, the name of the credential cache to which the handle will refer. For storing credentials, the name of the cache or collection where the credentials will be stored (see below).

  • client_keytab: For acquiring initiator credentials, the name of the keytab which will be used, if necessary, to refresh the credentials in the cache.

  • keytab: For acquiring acceptor credentials, the name of the keytab to which the handle will refer. In release 1.19 and later, this option also determines the keytab to be used for verification when initiator credentials are acquired using a password and verified.

  • password: For acquiring initiator credentials, this option instructs the mechanism to acquire fresh credentials into a unique memory credential cache. This option may not be used with the ccache or client_keytab options, and a desired_name must be specified. (New in release 1.19.)

  • rcache: For acquiring acceptor credentials, the name of the replay cache to be used when processing the initiator tokens. (New in release 1.13.)

  • verify: For acquiring initiator credentials, this option instructs the mechanism to verify the credentials by obtaining a ticket to a service with a known key. The service key is obtained from the keytab specified with the keytab option or the default keytab. The value may be the name of a principal in the keytab, or the empty string. If the empty string is given, any host service principal in the keytab may be used. (New in release 1.19.)

In release 1.20 or later, if a collection name is specified for cache in a call to gss_store_cred_into(), an existing cache for the client principal within the collection will be selected, or a new cache will be created within the collection. If overwrite_cred is false and the selected credential cache already exists, a GSS_S_DUPLICATE_ELEMENT error will be returned. If default_cred is true, the primary cache of the collection will be switched to the selected cache.

Importing and exporting credentials¶

The following GSSAPI extensions can be used to import and export credentials (declared in <gssapi/gssapi_ext.h>):

OM_uint32 gss_export_cred(OM_uint32 *minor_status,
                          gss_cred_id_t cred_handle,
                          gss_buffer_t token);

OM_uint32 gss_import_cred(OM_uint32 *minor_status,
                          gss_buffer_t token,
                          gss_cred_id_t *cred_handle);

The first function serializes a GSSAPI credential handle into a buffer; the second unseralizes a buffer into a GSSAPI credential handle. Serializing a credential does not destroy it. If any of the mechanisms used in cred_handle do not support serialization, gss_export_cred will return GSS_S_UNAVAILABLE. As with other GSSAPI serialization functions, these extensions are only intended to work with a matching implementation on the other side; they do not serialize credentials in a standardized format.

A serialized credential may contain secret information such as ticket session keys. The serialization format does not protect this information from eavesdropping or tampering. The calling application must take care to protect the serialized credential when communicating it over an insecure channel or to an untrusted party.

A krb5 GSSAPI credential may contain references to a credential cache, a client keytab, an acceptor keytab, and a replay cache. These resources are normally serialized as references to their external locations (such as the filename of the credential cache). Because of this, a serialized krb5 credential can only be imported by a process with similar privileges to the exporter. A serialized credential should not be trusted if it originates from a source with lower privileges than the importer, as it may contain references to external credential cache, keytab, or replay cache resources not accessible to the originator.

An exception to the above rule applies when a krb5 GSSAPI credential refers to a memory credential cache, as is normally the case for delegated credentials received by gss_accept_sec_context. In this case, the contents of the credential cache are serialized, so that the resulting token may be imported even if the original memory credential cache no longer exists.

Constrained delegation (S4U)¶

The Microsoft S4U2Self and S4U2Proxy Kerberos protocol extensions allow an intermediate service to acquire credentials from a client to a target service without requiring the client to delegate a ticket-granting ticket, if the KDC is configured to allow it.

To perform a constrained delegation operation, the intermediate service must submit to the KDC an “evidence ticket†from the client to the intermediate service. An evidence ticket can be acquired when the client authenticates to the intermediate service with Kerberos, or with an S4U2Self request if the KDC allows it. The MIT krb5 GSSAPI library represents an evidence ticket using a “proxy credentialâ€, which is a special kind of gss_cred_id_t object whose underlying credential cache contains the evidence ticket and a krbtgt ticket for the intermediate service.

To acquire a proxy credential during client authentication, the service should first create an acceptor credential using the GSS_C_BOTH usage. The application should then pass this credential as the acceptor_cred_handle to gss_accept_sec_context, and also pass a delegated_cred_handle output parameter to receive a proxy credential containing the evidence ticket. The output value of delegated_cred_handle may be a delegated ticket-granting ticket if the client sent one, or a proxy credential if not. If the library can determine that the client’s ticket is not a valid evidence ticket, it will place GSS_C_NO_CREDENTIAL in delegated_cred_handle.

To acquire a proxy credential using an S4U2Self request, the service can use the following GSSAPI extension:

OM_uint32 gss_acquire_cred_impersonate_name(OM_uint32 *minor_status,
                                            gss_cred_id_t icred,
                                            gss_name_t desired_name,
                                            OM_uint32 time_req,
                                            gss_OID_set desired_mechs,
                                            gss_cred_usage_t cred_usage,
                                            gss_cred_id_t *output_cred,
                                            gss_OID_set *actual_mechs,
                                            OM_uint32 *time_rec);

The parameters to this function are similar to those of gss_acquire_cred, except that icred is used to make an S4U2Self request to the KDC for a ticket from desired_name to the intermediate service. Both icred and desired_name are required for this function; passing GSS_C_NO_CREDENTIAL or GSS_C_NO_NAME will cause the call to fail. icred must contain a krbtgt ticket for the intermediate service. The result of this operation is a proxy credential. (Prior to release 1.18, the result of this operation may be a regular credential for desired_name, if the KDC issues a non-forwardable ticket.)

Once the intermediate service has a proxy credential, it can simply pass it to gss_init_sec_context as the initiator_cred_handle parameter, and the desired service as the target_name parameter. The GSSAPI library will present the krbtgt ticket and evidence ticket in the proxy credential to the KDC in an S4U2Proxy request; if the intermediate service has the appropriate permissions, the KDC will issue a ticket from the client to the target service. The GSSAPI library will then use this ticket to authenticate to the target service.

If an application needs to find out whether a credential it holds is a proxy credential and the name of the intermediate service, it can query the credential with the GSS_KRB5_GET_CRED_IMPERSONATOR OID (new in release 1.16, declared in <gssapi/gssapi_krb5.h>) using the gss_inquire_cred_by_oid extension (declared in <gssapi/gssapi_ext.h>):

OM_uint32 gss_inquire_cred_by_oid(OM_uint32 *minor_status,
                                  const gss_cred_id_t cred_handle,
                                  gss_OID desired_object,
                                  gss_buffer_set_t *data_set);

If the call succeeds and cred_handle is a proxy credential, data_set will be set to a single-element buffer set containing the unparsed principal name of the intermediate service. If cred_handle is not a proxy credential, data_set will be set to an empty buffer set. If the library does not support the query, gss_inquire_cred_by_oid will return GSS_S_UNAVAILABLE.

Channel binding behavior and GSS_C_CHANNEL_BOUND_FLAG¶

GSSAPI channel bindings can be used to limit the scope of a context establishment token to a particular protected channel or endpoint, such as a TLS channel or server certificate. Channel bindings can be supplied via the input_chan_bindings parameter to either gss_init_sec_context() or gss_accept_sec_context().

If both the initiator and acceptor of a GSSAPI exchange supply matching channel bindings, GSS_C_CHANNEL_BOUND_FLAG will be included in the gss_accept_sec_context() ret_flags result. If either the initiator or acceptor (or both) do not supply channel bindings, the exchange will succeed, but GSS_C_CHANNEL_BOUND_FLAG will not be included in the return flags. If the acceptor and initiator both inlude channel bindings but they do not match, the exchange will fail.

If GSS_C_CHANNEL_BOUND_FLAG is included in the req_flags parameter of gss_init_sec_context(), the initiator will add the Microsoft KERB_AP_OPTIONS_CBT extension to the Kerberos authenticator. This extension requests that the acceptor strictly enforce channel bindings, causing the exchange to fail if the acceptor supplies channel bindings and the initiator does not. The KERB_AP_OPTIONS_CBT extension will also be included if the client_aware_channel_bindings variable is set to true in [libdefaults].

Prior to release 1.19, GSS_C_CHANNEL_BOUND_FLAG is not implemented, and the exchange will fail if the acceptor supply channel bindings and the initiator does not (but not vice versa). Between releases 1.19 and 1.21, GSS_C_CHANNEL_BOUND_FLAG is not recognized as an initiator flag, so client_aware_channel_bindings is the only way to cause KERB_AP_OPTIONS_CBT to be included.

AEAD message wrapping¶

The following GSSAPI extensions (declared in <gssapi/gssapi_ext.h>) can be used to wrap and unwrap messages with additional “associated data†which is integrity-checked but is not included in the output buffer:

OM_uint32 gss_wrap_aead(OM_uint32 *minor_status,
                        gss_ctx_id_t context_handle,
                        int conf_req_flag, gss_qop_t qop_req,
                        gss_buffer_t input_assoc_buffer,
                        gss_buffer_t input_payload_buffer,
                        int *conf_state,
                        gss_buffer_t output_message_buffer);

OM_uint32 gss_unwrap_aead(OM_uint32 *minor_status,
                          gss_ctx_id_t context_handle,
                          gss_buffer_t input_message_buffer,
                          gss_buffer_t input_assoc_buffer,
                          gss_buffer_t output_payload_buffer,
                          int *conf_state,
                          gss_qop_t *qop_state);

Wrap tokens created with gss_wrap_aead will successfully unwrap only if the same input_assoc_buffer contents are presented to gss_unwrap_aead.

IOV message wrapping¶

The following extensions (declared in <gssapi/gssapi_ext.h>) can be used for in-place encryption, fine-grained control over wrap token layout, and for constructing wrap tokens compatible with Microsoft DCE RPC:

typedef struct gss_iov_buffer_desc_struct {
    OM_uint32 type;
    gss_buffer_desc buffer;
} gss_iov_buffer_desc, *gss_iov_buffer_t;

OM_uint32 gss_wrap_iov(OM_uint32 *minor_status,
                       gss_ctx_id_t context_handle,
                       int conf_req_flag, gss_qop_t qop_req,
                       int *conf_state,
                       gss_iov_buffer_desc *iov, int iov_count);

OM_uint32 gss_unwrap_iov(OM_uint32 *minor_status,
                         gss_ctx_id_t context_handle,
                         int *conf_state, gss_qop_t *qop_state,
                         gss_iov_buffer_desc *iov, int iov_count);

OM_uint32 gss_wrap_iov_length(OM_uint32 *minor_status,
                              gss_ctx_id_t context_handle,
                              int conf_req_flag,
                              gss_qop_t qop_req, int *conf_state,
                              gss_iov_buffer_desc *iov,
                              int iov_count);

OM_uint32 gss_release_iov_buffer(OM_uint32 *minor_status,
                                 gss_iov_buffer_desc *iov,
                                 int iov_count);

The caller of gss_wrap_iov provides an array of gss_iov_buffer_desc structures, each containing a type and a gss_buffer_desc structure. Valid types include:

  • GSS_C_BUFFER_TYPE_DATA: A data buffer to be included in the token, and to be encrypted or decrypted in-place if the token is confidentiality-protected.

  • GSS_C_BUFFER_TYPE_HEADER: The GSSAPI wrap token header and underlying cryptographic header.

  • GSS_C_BUFFER_TYPE_TRAILER: The cryptographic trailer, if one is required.

  • GSS_C_BUFFER_TYPE_PADDING: Padding to be combined with the data during encryption and decryption. (The implementation may choose to place padding in the trailer buffer, in which case it will set the padding buffer length to 0.)

  • GSS_C_BUFFER_TYPE_STREAM: For unwrapping only, a buffer containing a complete wrap token in standard format to be unwrapped.

  • GSS_C_BUFFER_TYPE_SIGN_ONLY: A buffer to be included in the token’s integrity protection checksum, but not to be encrypted or included in the token itself.

For gss_wrap_iov, the IOV list should contain one HEADER buffer, followed by zero or more SIGN_ONLY buffers, followed by one or more DATA buffers, followed by a TRAILER buffer. The memory pointed to by the buffers is not required to be contiguous or in any particular order. If conf_req_flag is true, DATA buffers will be encrypted in-place, while SIGN_ONLY buffers will not be modified.

The type of an output buffer may be combined with GSS_C_BUFFER_FLAG_ALLOCATE to request that gss_wrap_iov allocate the buffer contents. If gss_wrap_iov allocates a buffer, it sets the GSS_C_BUFFER_FLAG_ALLOCATED flag on the buffer type. gss_release_iov_buffer can be used to release all allocated buffers within an iov list and unset their allocated flags. Here is an example of how gss_wrap_iov can be used with allocation requested (ctx is assumed to be a previously established gss_ctx_id_t):

OM_uint32 major, minor;
gss_iov_buffer_desc iov[4];
char str[] = "message";

iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE;
iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
iov[1].buffer.value = str;
iov[1].buffer.length = strlen(str);
iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_FLAG_ALLOCATE;
iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_FLAG_ALLOCATE;

major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL,
                     iov, 4);
if (GSS_ERROR(major))
    handle_error(major, minor);

/* Transmit or otherwise use resulting buffers. */

(void)gss_release_iov_buffer(&minor, iov, 4);

If the caller does not choose to request buffer allocation by gss_wrap_iov, it should first call gss_wrap_iov_length to query the lengths of the HEADER, PADDING, and TRAILER buffers. DATA buffers must be provided in the iov list so that padding length can be computed correctly, but the output buffers need not be initialized. Here is an example of using gss_wrap_iov_length and gss_wrap_iov:

OM_uint32 major, minor;
gss_iov_buffer_desc iov[4];
char str[1024] = "message", *ptr;

iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
iov[1].buffer.value = str;
iov[1].buffer.length = strlen(str);

iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING;
iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER;

major = gss_wrap_iov_length(&minor, ctx, 1, GSS_C_QOP_DEFAULT,
                            NULL, iov, 4);
if (GSS_ERROR(major))
    handle_error(major, minor);
if (strlen(str) + iov[0].buffer.length + iov[2].buffer.length +
    iov[3].buffer.length > sizeof(str))
    handle_out_of_space_error();
ptr = str + strlen(str);
iov[0].buffer.value = ptr;
ptr += iov[0].buffer.length;
iov[2].buffer.value = ptr;
ptr += iov[2].buffer.length;
iov[3].buffer.value = ptr;

major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL,
                     iov, 4);
if (GSS_ERROR(major))
    handle_error(major, minor);

If the context was established using the GSS_C_DCE_STYLE flag (described in RFC 4757), wrap tokens compatible with Microsoft DCE RPC can be constructed. In this case, the IOV list must include a SIGN_ONLY buffer, a DATA buffer, a second SIGN_ONLY buffer, and a HEADER buffer in that order (the order of the buffer contents remains arbitrary). The application must pad the DATA buffer to a multiple of 16 bytes as no padding or trailer buffer is used.

gss_unwrap_iov may be called with an IOV list just like one which would be provided to gss_wrap_iov. DATA buffers will be decrypted in-place if they were encrypted, and SIGN_ONLY buffers will not be modified.

Alternatively, gss_unwrap_iov may be called with a single STREAM buffer, zero or more SIGN_ONLY buffers, and a single DATA buffer. The STREAM buffer is interpreted as a complete wrap token. The STREAM buffer will be modified in-place to decrypt its contents. The DATA buffer will be initialized to point to the decrypted data within the STREAM buffer, unless it has the GSS_C_BUFFER_FLAG_ALLOCATE flag set, in which case it will be initialized with a copy of the decrypted data. Here is an example (token and token_len are assumed to be a pre-existing pointer and length for a modifiable region of data):

OM_uint32 major, minor;
gss_iov_buffer_desc iov[2];

iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;
iov[0].buffer.value = token;
iov[0].buffer.length = token_len;
iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
if (GSS_ERROR(major))
    handle_error(major, minor);

/* Decrypted data is in iov[1].buffer, pointing to a subregion of
 * token. */

IOV MIC tokens¶

The following extensions (declared in <gssapi/gssapi_ext.h>) can be used in release 1.12 or later to construct and verify MIC tokens using an IOV list:

OM_uint32 gss_get_mic_iov(OM_uint32 *minor_status,
                          gss_ctx_id_t context_handle,
                          gss_qop_t qop_req,
                          gss_iov_buffer_desc *iov,
                          int iov_count);

OM_uint32 gss_get_mic_iov_length(OM_uint32 *minor_status,
                                 gss_ctx_id_t context_handle,
                                 gss_qop_t qop_req,
                                 gss_iov_buffer_desc *iov,
                                 iov_count);

OM_uint32 gss_verify_mic_iov(OM_uint32 *minor_status,
                             gss_ctx_id_t context_handle,
                             gss_qop_t *qop_state,
                             gss_iov_buffer_desc *iov,
                             int iov_count);

The caller of gss_get_mic_iov provides an array of gss_iov_buffer_desc structures, each containing a type and a gss_buffer_desc structure. Valid types include:

  • GSS_C_BUFFER_TYPE_DATA and GSS_C_BUFFER_TYPE_SIGN_ONLY: The corresponding buffer for each of these types will be signed for the MIC token, in the order provided.

  • GSS_C_BUFFER_TYPE_MIC_TOKEN: The GSSAPI MIC token.

The type of the MIC_TOKEN buffer may be combined with GSS_C_BUFFER_FLAG_ALLOCATE to request that gss_get_mic_iov allocate the buffer contents. If gss_get_mic_iov allocates the buffer, it sets the GSS_C_BUFFER_FLAG_ALLOCATED flag on the buffer type. gss_release_iov_buffer can be used to release all allocated buffers within an iov list and unset their allocated flags. Here is an example of how gss_get_mic_iov can be used with allocation requested (ctx is assumed to be a previously established gss_ctx_id_t):

OM_uint32 major, minor;
gss_iov_buffer_desc iov[3];

iov[0].type = GSS_IOV_BUFFER_TYPE_DATA;
iov[0].buffer.value = "sign1";
iov[0].buffer.length = 5;
iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
iov[1].buffer.value = "sign2";
iov[1].buffer.length = 5;
iov[2].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN | GSS_IOV_BUFFER_FLAG_ALLOCATE;

major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 3);
if (GSS_ERROR(major))
    handle_error(major, minor);

/* Transmit or otherwise use iov[2].buffer. */

(void)gss_release_iov_buffer(&minor, iov, 3);

If the caller does not choose to request buffer allocation by gss_get_mic_iov, it should first call gss_get_mic_iov_length to query the length of the MIC_TOKEN buffer. Here is an example of using gss_get_mic_iov_length and gss_get_mic_iov:

OM_uint32 major, minor;
gss_iov_buffer_desc iov[2];
char data[1024];

iov[0].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN;
iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
iov[1].buffer.value = "message";
iov[1].buffer.length = 7;

major = gss_get_mic_iov_length(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 2);
if (GSS_ERROR(major))
    handle_error(major, minor);
if (iov[0].buffer.length > sizeof(data))
    handle_out_of_space_error();
iov[0].buffer.value = data;

major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 2);
if (GSS_ERROR(major))
    handle_error(major, minor);
krb5-1.22.1/doc/html/appdev/princ_handle.html0000664000175000017500000002767315051422657020674 0ustar ghudsonghudson Principal manipulation and parsing — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/h5l_mit_apidiff.html0000664000175000017500000002260515051422657021257 0ustar ghudsonghudson Differences between Heimdal and MIT Kerberos API — MIT Kerberos Documentation

Differences between Heimdal and MIT Kerberos API¶

krb5_auth_con_getaddrs()

H5l: If either of the pointers to local_addr and remote_addr is not NULL, it is freed first and then reallocated before being populated with the content of corresponding address from authentication context.

krb5_auth_con_setaddrs()

H5l: If either address is NULL, the previous address remains in place

krb5_auth_con_setports()

H5l: Not implemented as of version 1.3.3

krb5_auth_con_setrecvsubkey()

H5l: If either port is NULL, the previous port remains in place

krb5_auth_con_setsendsubkey()

H5l: Not implemented as of version 1.3.3

krb5_cc_set_config()

MIT: Before version 1.10 it was assumed that the last argument data is ALWAYS non-zero.

krb5_cccol_last_change_time()

MIT: not implemented

krb5_set_default_realm()

H5l: Caches the computed default realm context field. If the second argument is NULL, it tries to retrieve it from libdefaults or DNS. MIT: Computes the default realm each time if it wasn’t explicitly set in the context

krb5-1.22.1/doc/html/appdev/init_creds.html0000664000175000017500000012016515051422657020357 0ustar ghudsonghudson Initial credentials — MIT Kerberos Documentation

Initial credentials¶

Software that performs tasks such as logging users into a computer when they type their Kerberos password needs to get initial credentials (usually ticket granting tickets) from Kerberos. Such software shares some behavior with the kinit program.

Whenever a program grants access to a resource (such as a local login session on a desktop computer) based on a user successfully getting initial Kerberos credentials, it must verify those credentials against a secure shared secret (e.g., a host keytab) to ensure that the user credentials actually originate from a legitimate KDC. Failure to perform this verification is a critical vulnerability, because a malicious user can execute the “Zanarotti attackâ€: the user constructs a fake response that appears to come from the legitimate KDC, but whose contents come from an attacker-controlled KDC.

Some applications read a Kerberos password over the network (ideally over a secure channel), which they then verify against the KDC. While this technique may be the only practical way to integrate Kerberos into some existing legacy systems, its use is contrary to the original design goals of Kerberos.

The function krb5_get_init_creds_password() will get initial credentials for a client using a password. An application that needs to verify the credentials can call krb5_verify_init_creds(). Here is an example of code to obtain and verify TGT credentials, given strings princname and password for the client principal name and password:

krb5_error_code ret;
krb5_creds creds;
krb5_principal client_princ = NULL;

memset(&creds, 0, sizeof(creds));
ret = krb5_parse_name(context, princname, &client_princ);
if (ret)
    goto cleanup;
ret = krb5_get_init_creds_password(context, &creds, client_princ,
                                   password, NULL, NULL, 0, NULL, NULL);
if (ret)
    goto cleanup;
ret = krb5_verify_init_creds(context, &creds, NULL, NULL, NULL, NULL);

cleanup:
krb5_free_principal(context, client_princ);
krb5_free_cred_contents(context, &creds);
return ret;

Options for get_init_creds¶

The function krb5_get_init_creds_password() takes an options parameter (which can be a null pointer). Use the function krb5_get_init_creds_opt_alloc() to allocate an options structure, and krb5_get_init_creds_opt_free() to free it. For example:

krb5_error_code ret;
krb5_get_init_creds_opt *opt = NULL;
krb5_creds creds;

memset(&creds, 0, sizeof(creds));
ret = krb5_get_init_creds_opt_alloc(context, &opt);
if (ret)
    goto cleanup;
krb5_get_init_creds_opt_set_tkt_life(opt, 24 * 60 * 60);
ret = krb5_get_init_creds_password(context, &creds, client_princ,
                                   password, NULL, NULL, 0, NULL, opt);
if (ret)
    goto cleanup;

cleanup:
krb5_get_init_creds_opt_free(context, opt);
krb5_free_cred_contents(context, &creds);
return ret;

Getting anonymous credentials¶

As of release 1.8, it is possible to obtain fully anonymous or partially anonymous (realm-exposed) credentials, if the KDC supports it. The MIT KDC supports issuing fully anonymous credentials as of release 1.8 if configured appropriately (see Anonymous PKINIT), but does not support issuing realm-exposed anonymous credentials at this time.

To obtain fully anonymous credentials, call krb5_get_init_creds_opt_set_anonymous() on the options structure to set the anonymous flag, and specify a client principal with the KDC’s realm and a single empty data component (the principal obtained by parsing @realmname). Authentication will take place using anonymous PKINIT; if successful, the client principal of the resulting tickets will be WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS. Here is an example:

krb5_get_init_creds_opt_set_anonymous(opt, 1);
ret = krb5_build_principal(context, &client_princ, strlen(myrealm),
                           myrealm, "", (char *)NULL);
if (ret)
    goto cleanup;
ret = krb5_get_init_creds_password(context, &creds, client_princ,
                                   password, NULL, NULL, 0, NULL, opt);
if (ret)
    goto cleanup;

To obtain realm-exposed anonymous credentials, set the anonymous flag on the options structure as above, but specify a normal client principal in order to prove membership in the realm. Authentication will take place as it normally does; if successful, the client principal of the resulting tickets will be WELLKNOWN/ANONYMOUS@realmname.

User interaction¶

Authenticating a user usually requires the entry of secret information, such as a password. A password can be supplied directly to krb5_get_init_creds_password() via the password parameter, or the application can supply prompter and/or responder callbacks instead. If callbacks are used, the user can also be queried for other secret information such as a PIN, informed of impending password expiration, or prompted to change a password which has expired.

Prompter callback¶

A prompter callback can be specified via the prompter and data parameters to krb5_get_init_creds_password(). The prompter will be invoked each time the krb5 library has a question to ask or information to present. When the prompter callback is invoked, the banner argument (if not null) is intended to be displayed to the user, and the questions to be answered are specified in the prompts array. Each prompt contains a text question in the prompt field, a hidden bit to indicate whether the answer should be hidden from display, and a storage area for the answer in the reply field. The callback should fill in each question’s reply->data with the answer, up to a maximum number of reply->length bytes, and then reset reply->length to the length of the answer.

A prompter callback can call krb5_get_prompt_types() to get an array of type constants corresponding to the prompts, to get programmatic information about the semantic meaning of the questions. krb5_get_prompt_types() may return a null pointer if no prompt type information is available.

Text-based applications can use a built-in text prompter implementation by supplying krb5_prompter_posix() as the prompter parameter and a null pointer as the data parameter. For example:

ret = krb5_get_init_creds_password(context, &creds, client_princ,
                                   NULL, krb5_prompter_posix, NULL, 0,
                                   NULL, NULL);

Responder callback¶

A responder callback can be specified through the init_creds options using the krb5_get_init_creds_opt_set_responder() function. Responder callbacks can present a more sophisticated user interface for authentication secrets. The responder callback is usually invoked only once per authentication, with a list of questions produced by all of the allowed preauthentication mechanisms.

When the responder callback is invoked, the rctx argument can be accessed to obtain the list of questions and to answer them. The krb5_responder_list_questions() function retrieves an array of question types. For each question type, the krb5_responder_get_challenge() function retrieves additional information about the question, if applicable, and the krb5_responder_set_answer() function sets the answer.

Responder question types, challenges, and answers are UTF-8 strings. The question type is a well-known string; the meaning of the challenge and answer depend on the question type. If an application does not understand a question type, it cannot interpret the challenge or provide an answer. Failing to answer a question typically results in the prompter callback being used as a fallback.

Password question¶

The KRB5_RESPONDER_QUESTION_PASSWORD (or "password") question type requests the user’s password. This question does not have a challenge, and the response is simply the password string.

One-time password question¶

The KRB5_RESPONDER_QUESTION_OTP (or "otp") question type requests a choice among one-time password tokens and the PIN and value for the chosen token. The challenge and answer are JSON-encoded strings, but an application can use convenience functions to avoid doing any JSON processing itself.

The krb5_responder_otp_get_challenge() function decodes the challenge into a krb5_responder_otp_challenge structure. The krb5_responder_otp_set_answer() function selects one of the token information elements from the challenge and supplies the value and pin for that token.

PKINIT password or PIN question¶

The KRB5_RESPONDER_QUESTION_PKINIT (or "pkinit") question type requests PINs for hardware devices and/or passwords for encrypted credentials which are stored on disk, potentially also supplying information about the state of the hardware devices. The challenge and answer are JSON-encoded strings, but an application can use convenience functions to avoid doing any JSON processing itself.

The krb5_responder_pkinit_get_challenge() function decodes the challenges into a krb5_responder_pkinit_challenge structure. The krb5_responder_pkinit_set_answer() function can be used to supply the PIN or password for a particular client credential, and can be called multiple times.

Example¶

Here is an example of using a responder callback:

static krb5_error_code
my_responder(krb5_context context, void *data,
             krb5_responder_context rctx)
{
    krb5_error_code ret;
    krb5_responder_otp_challenge *chl;

    if (krb5_responder_get_challenge(context, rctx,
                                     KRB5_RESPONDER_QUESTION_PASSWORD)) {
        ret = krb5_responder_set_answer(context, rctx,
                                        KRB5_RESPONDER_QUESTION_PASSWORD,
                                        "open sesame");
        if (ret)
            return ret;
    }
    ret = krb5_responder_otp_get_challenge(context, rctx, &chl);
    if (ret == 0 && chl != NULL) {
        ret = krb5_responder_otp_set_answer(context, rctx, 0, "1234",
                                            NULL);
        krb5_responder_otp_challenge_free(context, rctx, chl);
        if (ret)
            return ret;
    }
    return 0;
}

static krb5_error_code
get_creds(krb5_context context, krb5_principal client_princ)
{
    krb5_error_code ret;
    krb5_get_init_creds_opt *opt = NULL;
    krb5_creds creds;

    memset(&creds, 0, sizeof(creds));
    ret = krb5_get_init_creds_opt_alloc(context, &opt);
    if (ret)
        goto cleanup;
    ret = krb5_get_init_creds_opt_set_responder(context, opt, my_responder,
                                                NULL);
    if (ret)
        goto cleanup;
    ret = krb5_get_init_creds_password(context, &creds, client_princ,
                                       NULL, NULL, NULL, 0, NULL, opt);

cleanup:
    krb5_get_init_creds_opt_free(context, opt);
    krb5_free_cred_contents(context, &creds);
    return ret;
}

Verifying initial credentials¶

Use the function krb5_verify_init_creds() to verify initial credentials. It takes an options structure (which can be a null pointer). Use krb5_verify_init_creds_opt_init() to initialize the caller-allocated options structure, and krb5_verify_init_creds_opt_set_ap_req_nofail() to set the “nofail†option. For example:

krb5_verify_init_creds_opt vopt;

krb5_verify_init_creds_opt_init(&vopt);
krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, 1);
ret = krb5_verify_init_creds(context, &creds, NULL, NULL, NULL, &vopt);

The confusingly named “nofail†option, when set, means that the verification must actually succeed in order for krb5_verify_init_creds() to indicate success. The default state of this option (cleared) means that if there is no key material available to verify the user credentials, the verification will succeed anyway. (The default can be changed by a configuration file setting.)

This accommodates a use case where a large number of unkeyed shared desktop workstations need to allow users to log in using Kerberos. The security risks from this practice are mitigated by the absence of valuable state on the shared workstations—any valuable resources that the users would access reside on networked servers.

krb5-1.22.1/doc/html/appdev/refs/0000775000175000017500000000000015051422712016270 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/appdev/refs/index.html0000664000175000017500000001570015051422674020277 0ustar ghudsonghudson Complete reference - API and datatypes — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/0000775000175000017500000000000015051422674017050 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_canonicalize.html0000664000175000017500000002224415051422665030123 0ustar ghudsonghudson krb5_get_init_creds_opt_set_canonicalize - Set or unset the canonicalize flag in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_principal_compare.html0000664000175000017500000002217615051422671024355 0ustar ghudsonghudson krb5_principal_compare - Compare two principals. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_eblock_enctype.html0000664000175000017500000001772715051422663023663 0ustar ghudsonghudson krb5_eblock_enctype — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_salt.html0000664000175000017500000002256315051422666026434 0ustar ghudsonghudson krb5_get_init_creds_opt_set_salt - Set salt for optimistic preauthentication in initial credential options. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_salt - Set salt for optimistic preauthentication in initial credential options.¶

void krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt, krb5_data *salt)¶
param:

[in] opt - Options structure

[in] salt - Salt data

When getting initial credentials with a password, a salt string it used to convert the password to a key. Normally this salt is obtained from the first KDC reply, but when performing optimistic preauthentication, the client may need to supply the salt string with this function.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_responder.html0000664000175000017500000002355115051422666027470 0ustar ghudsonghudson krb5_get_init_creds_opt_set_responder - Set the responder function in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_address_list.html0000664000175000017500000002224315051422665030143 0ustar ghudsonghudson krb5_get_init_creds_opt_set_address_list - Set address restrictions in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_sname_match.html0000664000175000017500000002337215051422673023146 0ustar ghudsonghudson krb5_sname_match - Test whether a principal matches a matching principal. — MIT Kerberos Documentation

krb5_sname_match - Test whether a principal matches a matching principal.¶

krb5_boolean krb5_sname_match(krb5_context context, krb5_const_principal matching, krb5_const_principal princ)¶
param:

[in] context - Library context

[in] matching - Matching principal

[in] princ - Principal to test

return:
  • TRUE if princ matches matching , FALSE otherwise.

If matching is NULL, return TRUE. If matching is not a matching principal, return the value of krb5_principal_compare(context, matching,princ).

Note

A matching principal is a host-based principal with an empty realm and/or second data component (hostname). Profile configuration may cause the hostname to be ignored even if it is present. A principal matches a matching principal if the former has the same non-empty (and non-ignored) components of the latter.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_close.html0000664000175000017500000002106715051422670022466 0ustar ghudsonghudson krb5_kt_close - Close a key table handle. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_get_flags.html0000664000175000017500000002237115051422662023263 0ustar ghudsonghudson krb5_cc_get_flags - Retrieve flags from a credential cache structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_salttype_to_string.html0000664000175000017500000002164515051422672024624 0ustar ghudsonghudson krb5_salttype_to_string - Convert a salt type to a string. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_select.html0000664000175000017500000002527415051422662022614 0ustar ghudsonghudson krb5_cc_select - Select a credential cache to use with a server principal. — MIT Kerberos Documentation

krb5_cc_select - Select a credential cache to use with a server principal.¶

krb5_error_code krb5_cc_select(krb5_context context, krb5_principal server, krb5_ccache *cache_out, krb5_principal *princ_out)¶
param:

[in] context - Library context

[in] server - Server principal

[out] cache_out - Credential cache handle

[out] princ_out - Client principal

return:
  • If an appropriate cache is found, 0 is returned, cache_out is set to the selected cache, and princ_out is set to the default principal of that cache.

Select a cache within the collection containing credentials most appropriate for use with server , according to configured rules and heuristics.

Use krb5_cc_close() to release cache_out when it is no longer needed. Use krb5_free_principal() to release princ_out when it is no longer needed. Note that princ_out is set in some error conditions.

If the appropriate client principal can be authoritatively determined but the cache collection contains no credentials for that principal, then KRB5_CC_NOTFOUND is returned, cache_out is set to NULL, and princ_out is set to the appropriate client principal.

If no configured mechanism can determine the appropriate cache or principal, KRB5_CC_NOTFOUND is returned and cache_out and princ_out are set to NULL.

Any other error code indicates a fatal error in the processing of a cache selection mechanism.

Note

New in 1.10

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_keyed_checksum_types.html0000664000175000017500000002350015051422661025366 0ustar ghudsonghudson krb5_c_keyed_checksum_types - Return a list of keyed checksum types usable with an encryption type. — MIT Kerberos Documentation

krb5_c_keyed_checksum_types - Return a list of keyed checksum types usable with an encryption type.¶

krb5_error_code krb5_c_keyed_checksum_types(krb5_context context, krb5_enctype enctype, unsigned int *count, krb5_cksumtype **cksumtypes)¶
param:

[in] context - Library context

[in] enctype - Encryption type

[out] count - Count of allowable checksum types

[out] cksumtypes - Array of allowable checksum types

retval:
  • 0 Success; otherwise - Kerberos error codes

Use krb5_free_cksumtypes() to free cksumtypes when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_find_authdata.html0000664000175000017500000002463115051422664023461 0ustar ghudsonghudson krb5_find_authdata - Find authorization data elements. — MIT Kerberos Documentation

krb5_find_authdata - Find authorization data elements.¶

krb5_error_code krb5_find_authdata(krb5_context context, krb5_authdata *const *ticket_authdata, krb5_authdata *const *ap_req_authdata, krb5_authdatatype ad_type, krb5_authdata ***results)¶
param:

[in] context - Library context

[in] ticket_authdata - Authorization data list from ticket

[in] ap_req_authdata - Authorization data list from AP request

[in] ad_type - Authorization data type to find

[out] results - List of matching entries

This function searches ticket_authdata and ap_req_authdata for elements of type ad_type . Either input list may be NULL, in which case it will not be searched; otherwise, the input lists must be terminated by NULL entries. This function will search inside AD-IF-RELEVANT containers if found in either list. Use krb5_free_authdata() to free results when it is no longer needed.

Note

New in 1.10

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_start_seq_get.html0000664000175000017500000002267415051422670024232 0ustar ghudsonghudson krb5_kt_start_seq_get - Start a sequential retrieval of key table entries. — MIT Kerberos Documentation

krb5_kt_start_seq_get - Start a sequential retrieval of key table entries.¶

krb5_error_code krb5_kt_start_seq_get(krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor)¶
param:

[in] context - Library context

[in] keytab - Key table handle

[out] cursor - Cursor

retval:
  • 0 Success

return:
  • Kerberos error codes

Prepare to read sequentially every key in the specified key table. Use krb5_kt_end_seq_get() to release the cursor when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_appdefault_string.html0000664000175000017500000002446015051422657024403 0ustar ghudsonghudson krb5_appdefault_string - Retrieve a string value from the appdefaults section of krb5.conf. — MIT Kerberos Documentation

krb5_appdefault_string - Retrieve a string value from the appdefaults section of krb5.conf.¶

void krb5_appdefault_string(krb5_context context, const char *appname, const krb5_data *realm, const char *option, const char *default_value, char **ret_value)¶
param:

[in] context - Library context

[in] appname - Application name

[in] realm - Realm name

[in] option - Option to be checked

[in] default_value - Default value to return if no match is found

[out] ret_value - String value of option

This function gets the application defaults for option based on the given appname and/or realm .

See also

krb5_appdefault_boolean()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_random_seed.html0000664000175000017500000001771315051422661023450 0ustar ghudsonghudson krb5_c_random_seed — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_make_authdata_kdc_issued.html0000664000175000017500000002455215051422670025652 0ustar ghudsonghudson krb5_make_authdata_kdc_issued - Encode and sign AD-KDCIssued authorization data. — MIT Kerberos Documentation

krb5_make_authdata_kdc_issued - Encode and sign AD-KDCIssued authorization data.¶

krb5_error_code krb5_make_authdata_kdc_issued(krb5_context context, const krb5_keyblock *key, krb5_const_principal issuer, krb5_authdata *const *authdata, krb5_authdata ***ad_kdcissued)¶
param:

[in] context - Library context

[in] key - Session key

[in] issuer - The name of the issuing principal

[in] authdata - List of authorization data to be signed

[out] ad_kdcissued - List containing AD-KDCIssued authdata

This function wraps a list of authorization data entries authdata in an AD-KDCIssued container (see RFC 4120 section 5.2.6.2) signed with key . The result is returned in ad_kdcissued as a single-element list.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_free_key.html0000664000175000017500000002071115051422667022767 0ustar ghudsonghudson krb5_k_free_key - Decrement the reference count on a key and free it if it hits zero. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_fast_flags.html0000664000175000017500000002350315051422665027574 0ustar ghudsonghudson krb5_get_init_creds_opt_set_fast_flags - Set FAST flags in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache_name.html0000664000175000017500000002374415051422665030715 0ustar ghudsonghudson krb5_get_init_creds_opt_set_fast_ccache_name - Set location of FAST armor ccache in initial credential options. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_fast_ccache_name - Set location of FAST armor ccache in initial credential options.¶

krb5_error_code krb5_get_init_creds_opt_set_fast_ccache_name(krb5_context context, krb5_get_init_creds_opt *opt, const char *fast_ccache_name)¶
param:

[in] context - Library context

[in] opt - Options

[in] fast_ccache_name - Credential cache name

Sets the location of a credential cache containing an armor ticket to protect an initial credential exchange using the FAST protocol extension.

In version 1.7, setting an armor ccache requires that FAST be used for the exchange. In version 1.8 or later, setting the armor ccache causes FAST to be used if the KDC supports it; krb5_get_init_creds_opt_set_fast_flags() must be used to require that FAST be used.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_425_conv_principal.html0000664000175000017500000002432315051422657024266 0ustar ghudsonghudson krb5_425_conv_principal - Convert a Kerberos V4 principal to a Kerberos V5 principal. — MIT Kerberos Documentation

krb5_425_conv_principal - Convert a Kerberos V4 principal to a Kerberos V5 principal.¶

krb5_error_code krb5_425_conv_principal(krb5_context context, const char *name, const char *instance, const char *realm, krb5_principal *princ)¶
param:

[in] context - Library context

[in] name - V4 name

[in] instance - V4 instance

[in] realm - Realm

[out] princ - V5 principal

retval:
  • 0 Success; otherwise - Kerberos error codes

This function builds a princ from V4 specification based on given input name.instance@realm .

Use krb5_free_principal() to free princ when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_fallback_host_realm.html0000664000175000017500000002220715051422665025477 0ustar ghudsonghudson krb5_get_fallback_host_realm — MIT Kerberos Documentation

krb5_get_fallback_host_realm¶

krb5_error_code krb5_get_fallback_host_realm(krb5_context context, krb5_data *hdata, char ***realmsp)¶
param:

[in] context - Library context

[in] hdata - Host name (or NULL)

[out] realmsp - Null-terminated list of realm names

Fill in realmsp with a pointer to a null-terminated list of realm names obtained through heuristics or insecure resolution methods which have lower priority than KDC referrals.

If host is NULL, the local host’s realms are determined.

Use krb5_free_host_realm() to release realmsp when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_step.html0000664000175000017500000002644315051422667024052 0ustar ghudsonghudson krb5_init_creds_step - Get the next KDC request for acquiring initial credentials. — MIT Kerberos Documentation

krb5_init_creds_step - Get the next KDC request for acquiring initial credentials.¶

krb5_error_code krb5_init_creds_step(krb5_context context, krb5_init_creds_context ctx, krb5_data *in, krb5_data *out, krb5_data *realm, unsigned int *flags)¶
param:

[in] context - Library context

[in] ctx - Initial credentials context

[in] in - KDC response (empty on the first call)

[out] out - Next KDC request

[out] realm - Realm for next KDC request

[out] flags - Output flags

retval:
  • 0 Success; otherwise - Kerberos error codes

This function constructs the next KDC request in an initial credential exchange, allowing the caller to control the transport of KDC requests and replies. On the first call, in should be set to an empty buffer; on subsequent calls, it should be set to the KDC’s reply to the previous request.

If more requests are needed, flags will be set to KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in out . If no more requests are needed, flags will not contain KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and out will be empty.

If this function returns KRB5KRB_ERR_RESPONSE_TOO_BIG , the caller should transmit the next request using TCP rather than UDP. If this function returns any other error, the initial credential exchange has failed.

context must be the same as the one passed to krb5_init_creds_init() for this initial credentials context.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kuserok.html0000664000175000017500000002230015051422670022335 0ustar ghudsonghudson krb5_kuserok - Determine if a principal is authorized to log in as a local user. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_get_buffer.html0000664000175000017500000002237215051422671023617 0ustar ghudsonghudson krb5_pac_get_buffer - Retrieve a buffer value from a PAC. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_responder_otp_set_answer.html0000664000175000017500000002357015051422672026003 0ustar ghudsonghudson krb5_responder_otp_set_answer - Answer the KRB5_RESPONDER_QUESTION_OTP question. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_random_os_entropy.html0000664000175000017500000002050515051422661024722 0ustar ghudsonghudson krb5_c_random_os_entropy — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_us_timeofday.html0000664000175000017500000002330015051422673023346 0ustar ghudsonghudson krb5_us_timeofday - Retrieve the system time of day, in sec and ms, since the epoch. — MIT Kerberos Documentation

krb5_us_timeofday - Retrieve the system time of day, in sec and ms, since the epoch.¶

krb5_error_code krb5_us_timeofday(krb5_context context, krb5_timestamp *seconds, krb5_int32 *microseconds)¶
param:

[in] context - Library context

[out] seconds - System timeofday, seconds portion

[out] microseconds - System timeofday, microseconds portion

retval:
  • 0 Success

return:
  • Kerberos error codes

This function retrieves the system time of day with the context specific time offset adjustment.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_ap_rep_enc_part.html0000664000175000017500000002114215051422664025002 0ustar ghudsonghudson krb5_free_ap_rep_enc_part - Free a krb5_ap_rep_enc_part structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_error_message.html0000664000175000017500000002073715051422664024527 0ustar ghudsonghudson krb5_free_error_message - Free an error message generated by krb5_get_error_message(). — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getremoteseqnumber.html0000664000175000017500000002340115051422660026451 0ustar ghudsonghudson krb5_auth_con_getremoteseqnumber - Retrieve the remote sequence number from an auth context. — MIT Kerberos Documentation

krb5_auth_con_getremoteseqnumber - Retrieve the remote sequence number from an auth context.¶

krb5_error_code krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[out] seqnumber - Remote sequence number

retval:
  • 0 Success; otherwise - Kerberos error codes

Retrieve the remote sequence number from auth_context and return it in seqnumber . The KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in auth_context for this function to be useful.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_prf.html0000664000175000017500000002366115051422667021774 0ustar ghudsonghudson krb5_k_prf - Generate enctype-specific pseudo-random bytes (operates on opaque key). — MIT Kerberos Documentation

krb5_k_prf - Generate enctype-specific pseudo-random bytes (operates on opaque key).¶

krb5_error_code krb5_k_prf(krb5_context context, krb5_key key, krb5_data *input, krb5_data *output)¶
param:

[in] context - Library context

[in] key - Key

[in] input - Input data

[out] output - Output data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function selects a pseudo-random function based on key and computes its value over input , placing the result into output . The caller must preinitialize output and allocate space for the result.

Note

This function is similar to krb5_c_prf(), but operates on opaque key .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_timestamp_to_sfstring.html0000664000175000017500000002307415051422673025312 0ustar ghudsonghudson krb5_timestamp_to_sfstring - Convert a timestamp to a string, with optional output padding. — MIT Kerberos Documentation

krb5_timestamp_to_sfstring - Convert a timestamp to a string, with optional output padding.¶

krb5_error_code krb5_timestamp_to_sfstring(krb5_timestamp timestamp, char *buffer, size_t buflen, char *pad)¶
param:

[in] timestamp - Timestamp to convert

[out] buffer - Buffer to hold the converted timestamp

[in] buflen - Length of buffer

[in] pad - Optional value to pad buffer if converted timestamp does not fill it

retval:
  • 0 Success; otherwise - Kerberos error codes

If pad is not NULL, buffer is padded out to buflen - 1 characters with the value of * pad .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_init_state.html0000664000175000017500000002301215051422661023320 0ustar ghudsonghudson krb5_c_init_state - Initialize a new cipher state. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_prf.html0000664000175000017500000002332015051422661021746 0ustar ghudsonghudson krb5_c_prf - Generate enctype-specific pseudo-random bytes. — MIT Kerberos Documentation

krb5_c_prf - Generate enctype-specific pseudo-random bytes.¶

krb5_error_code krb5_c_prf(krb5_context context, const krb5_keyblock *keyblock, krb5_data *input, krb5_data *output)¶
param:

[in] context - Library context

[in] keyblock - Key

[in] input - Input data

[out] output - Output data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function selects a pseudo-random function based on keyblock and computes its value over input , placing the result into output . The caller must preinitialize output and allocate space for the result, using krb5_c_prf_length() to determine the required length.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_encrypt.html0000664000175000017500000002610215051422667022662 0ustar ghudsonghudson krb5_k_encrypt - Encrypt data using a key (operates on opaque key). — MIT Kerberos Documentation

krb5_k_encrypt - Encrypt data using a key (operates on opaque key).¶

krb5_error_code krb5_k_encrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_data *input, krb5_enc_data *output)¶
param:

[in] context - Library context

[in] key - Encryption key

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[inout] cipher_state - Cipher state; specify NULL if not needed

[in] input - Data to be encrypted

[out] output - Encrypted data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function encrypts the data block input and stores the output into output . The actual encryption key will be derived from key and usage if key derivation is specified for the encryption type. If non-null, cipher_state specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation.

Note

The caller must initialize output and allocate at least enough space for the result (using krb5_c_encrypt_length() to determine the amount of space needed). output->length will be set to the actual length of the ciphertext.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getkey.html0000664000175000017500000002300615051422657024033 0ustar ghudsonghudson krb5_auth_con_getkey - Retrieve the session key from an auth context as a keyblock. — MIT Kerberos Documentation

krb5_auth_con_getkey - Retrieve the session key from an auth context as a keyblock.¶

krb5_error_code krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[out] keyblock - Session key

retval:
  • 0 Success. Otherwise - Kerberos error codes

This function creates a keyblock containing the session key from auth_context . Use krb5_free_keyblock() to free keyblock when it is no longer needed

krb5-1.22.1/doc/html/appdev/refs/api/krb5_responder_pkinit_get_challenge.html0000664000175000017500000002371115051422672027103 0ustar ghudsonghudson krb5_responder_pkinit_get_challenge - Decode the KRB5_RESPONDER_QUESTION_PKINIT to a C struct. — MIT Kerberos Documentation

krb5_responder_pkinit_get_challenge - Decode the KRB5_RESPONDER_QUESTION_PKINIT to a C struct.¶

krb5_error_code krb5_responder_pkinit_get_challenge(krb5_context ctx, krb5_responder_context rctx, krb5_responder_pkinit_challenge **chl_out)¶
param:

[in] ctx - Library context

[in] rctx - Responder context

[out] chl_out - Challenge structure

A convenience function which parses the KRB5_RESPONDER_QUESTION_PKINIT question challenge data, making it available in native C. The main feature of this function is the ability to read the challenge without parsing the JSON.

The returned value must be passed to krb5_responder_pkinit_challenge_free() to be freed.

Note

New in 1.12

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_free.html0000664000175000017500000002150315051422665025527 0ustar ghudsonghudson krb5_get_init_creds_opt_free - Free initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_kdc_send_hook.html0000664000175000017500000002200315051422672024321 0ustar ghudsonghudson krb5_set_kdc_send_hook - Set a KDC pre-send hook function. — MIT Kerberos Documentation

krb5_set_kdc_send_hook - Set a KDC pre-send hook function.¶

void krb5_set_kdc_send_hook(krb5_context context, krb5_pre_send_fn send_hook, void *data)¶
param:

[in] context - Library context

[in] send_hook - Hook function (or NULL to disable the hook)

[in] data - Callback data to be passed to send_hook

send_hook will be called before messages are sent to KDCs by library functions such as krb5_get_credentials(). The hook function may inspect, override, or synthesize its own reply to the message.

Note

New in 1.15

krb5-1.22.1/doc/html/appdev/refs/api/krb5_string_to_key.html0000664000175000017500000002206315051422673023543 0ustar ghudsonghudson krb5_string_to_key — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_default_realm.html0000664000175000017500000002233015051422672024336 0ustar ghudsonghudson krb5_set_default_realm - Override the default realm for the specified context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_tkt_creds_init.html0000664000175000017500000002520615051422673023672 0ustar ghudsonghudson krb5_tkt_creds_init - Create a context to get credentials from a KDC’s Ticket Granting Service. — MIT Kerberos Documentation

krb5_tkt_creds_init - Create a context to get credentials from a KDC’s Ticket Granting Service.¶

krb5_error_code krb5_tkt_creds_init(krb5_context context, krb5_ccache ccache, krb5_creds *creds, krb5_flags options, krb5_tkt_creds_context *ctx)¶
param:

[in] context - Library context

[in] ccache - Credential cache handle

[in] creds - Input credentials

[in] options - Options (see KRB5_GC macros)

[out] ctx - New TGS request context

retval:
  • 0 Success; otherwise - Kerberos error codes

This function prepares to obtain credentials matching creds , either by retrieving them from ccache or by making requests to ticket-granting services beginning with a ticket-granting ticket for the client principal’s realm.

The resulting TGS acquisition context can be used asynchronously with krb5_tkt_creds_step() or synchronously with krb5_tkt_creds_get(). See also krb5_get_credentials() for synchronous use.

Use krb5_tkt_creds_free() to free ctx when it is no longer needed.

Note

New in 1.9

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_verify_checksum.html0000664000175000017500000002610115051422667024363 0ustar ghudsonghudson krb5_k_verify_checksum - Verify a checksum (operates on opaque key). — MIT Kerberos Documentation

krb5_k_verify_checksum - Verify a checksum (operates on opaque key).¶

krb5_error_code krb5_k_verify_checksum(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *data, const krb5_checksum *cksum, krb5_boolean *valid)¶
param:

[in] context - Library context

[in] key - Encryption key for a keyed checksum

[in] usage - key usage

[in] data - Data to be used to compute a new checksum using key to compare cksum against

[in] cksum - Checksum to be verified

[out] valid - Non-zero for success, zero for failure

retval:
  • 0 Success; otherwise - Kerberos error codes

This function verifies that cksum is a valid checksum for data . If the checksum type of cksum is a keyed checksum, key is used to verify the checksum. If the checksum type in cksum is 0 and key is not NULL, the mandatory checksum type for key will be used. The actual checksum key will be derived from key and usage if key derivation is specified for the checksum type.

Note

This function is similar to krb5_c_verify_checksum(), but operates on opaque key .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_setsendsubkey_k.html0000664000175000017500000002260715051422660025745 0ustar ghudsonghudson krb5_auth_con_setsendsubkey_k - Set the send subkey in an auth context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_string_to_key.html0000664000175000017500000002454115051422661024045 0ustar ghudsonghudson krb5_c_string_to_key - Convert a string (such a password) to a key. — MIT Kerberos Documentation

krb5_c_string_to_key - Convert a string (such a password) to a key.¶

krb5_error_code krb5_c_string_to_key(krb5_context context, krb5_enctype enctype, const krb5_data *string, const krb5_data *salt, krb5_keyblock *key)¶
param:

[in] context - Library context

[in] enctype - Encryption type

[in] string - String to be converted

[in] salt - Salt value

[out] key - Generated key

retval:
  • 0 Success; otherwise - Kerberos error codes

This function converts string to a key of encryption type enctype , using the specified salt . The newly created key must be released by calling krb5_free_keyblock_contents() when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_recvauth.html0000664000175000017500000002633515051422672022511 0ustar ghudsonghudson krb5_recvauth - Server function for sendauth protocol. — MIT Kerberos Documentation

krb5_recvauth - Server function for sendauth protocol.¶

krb5_error_code krb5_recvauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, char *appl_version, krb5_principal server, krb5_int32 flags, krb5_keytab keytab, krb5_ticket **ticket)¶
param:

[in] context - Library context

[inout] auth_context - Pre-existing or newly created auth context

[in] fd - File descriptor

[in] appl_version - Application protocol version to be matched against the client’s application version

[in] server - Server principal (NULL for any in keytab )

[in] flags - Additional specifications

[in] keytab - Key table containing service keys

[out] ticket - Ticket (NULL if not needed)

retval:
  • 0 Success; otherwise - Kerberos error codes

This function performs the server side of a sendauth/recvauth exchange by sending and receiving messages over fd .

Use krb5_free_ticket() to free ticket when it is no longer needed.

See also

krb5_sendauth()

krb5-1.22.1/doc/html/appdev/refs/api/index.html0000664000175000017500000021326515051422657021057 0ustar ghudsonghudson krb5 API — MIT Kerberos Documentation

krb5 API¶

Frequently used public interfaces¶

Rarely used public interfaces¶

Public interfaces that should not be called directly¶

Legacy convenience interfaces¶

Deprecated public interfaces¶

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_store_cred.html0000664000175000017500000002311415051422663023456 0ustar ghudsonghudson krb5_cc_store_cred - Store credentials in a credential cache. — MIT Kerberos Documentation

krb5_cc_store_cred - Store credentials in a credential cache.¶

krb5_error_code krb5_cc_store_cred(krb5_context context, krb5_ccache cache, krb5_creds *creds)¶
param:

[in] context - Library context

[in] cache - Credential cache handle

[in] creds - Credentials to be stored in cache

retval:
  • 0 Success

return:
  • Permission errors; storage failure errors; Kerberos error codes

This function stores creds into cache . If creds->server and the server in the decoded ticket creds->ticket differ, the credentials will be stored under both server principal names.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_rd_priv.html0000664000175000017500000002566115051422672022336 0ustar ghudsonghudson krb5_rd_priv - Process a KRB-PRIV message. — MIT Kerberos Documentation

krb5_rd_priv - Process a KRB-PRIV message.¶

krb5_error_code krb5_rd_priv(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_data *userdata_out, krb5_replay_data *rdata_out)¶
param:

[in] context - Library context

[in] auth_context - Authentication structure

[in] inbuf - KRB-PRIV message to be parsed

[out] userdata_out - Data parsed from KRB-PRIV message

[out] rdata_out - Replay data. Specify NULL if not needed

retval:
  • 0 Success; otherwise - Kerberos error codes

This function parses a KRB-PRIV message, verifies its integrity, and stores its unencrypted data into userdata_out .

If auth_context has a remote address set, the address will be used to verify the sender address in the KRB-PRIV message. If auth_context has a local address set, it will be used to verify the receiver address in the KRB-PRIV message if the message contains one.

If the KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in auth_context , the sequence number of the KRB-PRIV message is checked against the remote sequence number field of auth_context . Otherwise, the sequence number is not used.

If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in auth_context , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in-memory replay cache to detect reflections or replays.

Use krb5_free_data_contents() to free userdata_out when it is no longer needed.

Note

The rdata_out argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in auth_context .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_verify_checksum.html0000664000175000017500000002226715051422673024057 0ustar ghudsonghudson krb5_verify_checksum — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_mk_error.html0000664000175000017500000002241715051422670022503 0ustar ghudsonghudson krb5_mk_error - Format and encode a KRB_ERROR message. — MIT Kerberos Documentation

krb5_mk_error - Format and encode a KRB_ERROR message.¶

krb5_error_code krb5_mk_error(krb5_context context, const krb5_error *dec_err, krb5_data *enc_err)¶
param:

[in] context - Library context

[in] dec_err - Error structure to be encoded

[out] enc_err - Encoded error structure

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a KRB_ERROR message in enc_err . Use krb5_free_data_contents() to free enc_err when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_remove_cred.html0000664000175000017500000002353315051422662023623 0ustar ghudsonghudson krb5_cc_remove_cred - Remove credentials from a credential cache. — MIT Kerberos Documentation

krb5_cc_remove_cred - Remove credentials from a credential cache.¶

krb5_error_code krb5_cc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *creds)¶
param:

[in] context - Library context

[in] cache - Credential cache handle

[in] flags - Bitwise-ORed search flags

[in] creds - Credentials to be matched

retval:
  • KRB5_CC_NOSUPP Not implemented for this cache type

return:
  • No matches found; Data cannot be deleted; Kerberos error codes

This function accepts the same flag values as krb5_cc_retrieve_cred().

Warning

This function is not implemented for some cache types.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_init.html0000664000175000017500000002270415051422660023504 0ustar ghudsonghudson krb5_auth_con_init - Create and initialize an authentication context. — MIT Kerberos Documentation

krb5_auth_con_init - Create and initialize an authentication context.¶

krb5_error_code krb5_auth_con_init(krb5_context context, krb5_auth_context *auth_context)¶
param:

[in] context - Library context

[out] auth_context - Authentication context

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates an authentication context to hold configuration and state relevant to krb5 functions for authenticating principals and protecting messages once authentication has occurred.

By default, flags for the context are set to enable the use of the replay cache (KRB5_AUTH_CONTEXT_DO_TIME), but not sequence numbers. Use krb5_auth_con_setflags() to change the flags.

The allocated auth_context must be freed with krb5_auth_con_free() when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_secure_context.html0000664000175000017500000002176615051422667024754 0ustar ghudsonghudson krb5_init_secure_context - Create a krb5 library context using only configuration files. — MIT Kerberos Documentation

krb5_init_secure_context - Create a krb5 library context using only configuration files.¶

krb5_error_code krb5_init_secure_context(krb5_context *context)¶
param:

[out] context - Library context

retval:
  • 0 Success

return:
  • Kerberos error codes

Create a context structure, using only system configuration files. All information passed through the environment variables is ignored.

The context must be released by calling krb5_free_context() when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_genaddrs.html0000664000175000017500000002363615051422657024343 0ustar ghudsonghudson krb5_auth_con_genaddrs - Generate auth context addresses from a connected socket. — MIT Kerberos Documentation

krb5_auth_con_genaddrs - Generate auth context addresses from a connected socket.¶

krb5_error_code krb5_auth_con_genaddrs(krb5_context context, krb5_auth_context auth_context, int infd, int flags)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] infd - Connected socket descriptor

[in] flags - Flags

retval:
  • 0 Success; otherwise - Kerberos error codes

This function sets the local and/or remote addresses in auth_context based on the local and remote endpoints of the socket infd . The following flags determine the operations performed:

  • KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR Generate local address.

  • KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR Generate remote address.

  • KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR Generate local address and port.

  • KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR Generate remote address and port.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_set_flags.html0000664000175000017500000002217615051422663023303 0ustar ghudsonghudson krb5_cc_set_flags - Set options flags on a credential cache. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_random_key.html0000664000175000017500000002145215051422667024042 0ustar ghudsonghudson krb5_init_random_key — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_enctype_to_name.html0000664000175000017500000002312015051422664024027 0ustar ghudsonghudson krb5_enctype_to_name - Convert an encryption type to a name or alias. — MIT Kerberos Documentation

krb5_enctype_to_name - Convert an encryption type to a name or alias.¶

krb5_error_code krb5_enctype_to_name(krb5_enctype enctype, krb5_boolean shortest, char *buffer, size_t buflen)¶
param:

[in] enctype - Encryption type

[in] shortest - Flag

[out] buffer - Buffer to hold encryption type string

[in] buflen - Storage available in buffer

retval:
  • 0 Success; otherwise - Kerberos error codes

If shortest is FALSE, this function returns the enctype’s canonical name (likeâ€aes128-cts-hmac-sha1-96â€). If shortest is TRUE, it return the enctype’s shortest alias (likeâ€aes128-ctsâ€).

Note

New in 1.9

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_pa.html0000664000175000017500000002405415051422666026066 0ustar ghudsonghudson krb5_get_init_creds_opt_set_pa - Supply options for preauthentication in initial credential options. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_pa - Supply options for preauthentication in initial credential options.¶

krb5_error_code krb5_get_init_creds_opt_set_pa(krb5_context context, krb5_get_init_creds_opt *opt, const char *attr, const char *value)¶
param:

[in] context - Library context

[in] opt - Options structure

[in] attr - Preauthentication option name

[in] value - Preauthentication option value

This function allows the caller to supply options for preauthentication. The values of attr and value are supplied to each preauthentication module available within context .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_address_compare.html0000664000175000017500000002242415051422657024021 0ustar ghudsonghudson krb5_address_compare - Compare two Kerberos addresses. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_principal2salt.html0000664000175000017500000002236215051422671023612 0ustar ghudsonghudson krb5_principal2salt - Convert a principal name into the default salt for that principal. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_fx_cf2_simple.html0000664000175000017500000002553415051422661023710 0ustar ghudsonghudson krb5_c_fx_cf2_simple - Compute the KRB-FX-CF2 combination of two keys and pepper strings. — MIT Kerberos Documentation

krb5_c_fx_cf2_simple - Compute the KRB-FX-CF2 combination of two keys and pepper strings.¶

krb5_error_code krb5_c_fx_cf2_simple(krb5_context context, const krb5_keyblock *k1, const char *pepper1, const krb5_keyblock *k2, const char *pepper2, krb5_keyblock **out)¶
param:

[in] context - Library context

[in] k1 - KDC contribution key

[in] pepper1 - Stringâ€PKINITâ€

[in] k2 - Reply key

[in] pepper2 - Stringâ€KeyExchangeâ€

[out] out - Output key

retval:
  • 0 Success; otherwise - Kerberos error codes

This function computes the KRB-FX-CF2 function over its inputs and places the results in a newly allocated keyblock. This function is simple in that it assumes that pepper1 and pepper2 are C strings with no internal nulls and that the enctype of the result will be the same as that of k1 . k1 and k2 may be of different enctypes.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_address_order.html0000664000175000017500000002236515051422657023512 0ustar ghudsonghudson krb5_address_order - Return an ordering of the specified addresses. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_anonymous.html0000664000175000017500000002242115051422665027511 0ustar ghudsonghudson krb5_get_init_creds_opt_set_anonymous - Set or unset the anonymous flag in initial credential options. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_anonymous - Set or unset the anonymous flag in initial credential options.¶

void krb5_get_init_creds_opt_set_anonymous(krb5_get_init_creds_opt *opt, int anonymous)¶
param:

[in] opt - Options structure

[in] anonymous - Whether to make an anonymous request

This function may be used to request anonymous credentials from the KDC by setting anonymous to non-zero. Note that anonymous credentials are only a request; clients must verify that credentials are anonymous if that is a requirement.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_524_convert_creds.html0000664000175000017500000002171315051422657024120 0ustar ghudsonghudson krb5_524_convert_creds - Convert a Kerberos V5 credentials to a Kerberos V4 credentials. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_fwd_tgt_creds.html0000664000175000017500000002634415051422665023510 0ustar ghudsonghudson krb5_fwd_tgt_creds - Get a forwarded TGT and format a KRB-CRED message. — MIT Kerberos Documentation

krb5_fwd_tgt_creds - Get a forwarded TGT and format a KRB-CRED message.¶

krb5_error_code krb5_fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context, const char *rhost, krb5_principal client, krb5_principal server, krb5_ccache cc, int forwardable, krb5_data *outbuf)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] rhost - Remote host

[in] client - Client principal of TGT

[in] server - Principal of server to receive TGT

[in] cc - Credential cache handle (NULL to use default)

[in] forwardable - Whether TGT should be forwardable

[out] outbuf - KRB-CRED message

retval:
  • 0 Success

  • ENOMEM Insufficient memory

  • KRB5_PRINC_NOMATCH Requested principal and ticket do not match

  • KRB5_NO_TKT_SUPPLIED Request did not supply a ticket

  • KRB5_CC_BADNAME Credential cache name or principal name malformed

return:
  • Kerberos error codes

Get a TGT for use at the remote host rhost and format it into a KRB-CRED message. If rhost is NULL and server is of type KRB5_NT_SRV_HST, the second component of server will be used.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_unparse_name_flags_ext.html0000664000175000017500000002403415051422673025374 0ustar ghudsonghudson krb5_unparse_name_flags_ext - Convert krb5_principal structure to string format with flags. — MIT Kerberos Documentation

krb5_unparse_name_flags_ext - Convert krb5_principal structure to string format with flags.¶

krb5_error_code krb5_unparse_name_flags_ext(krb5_context context, krb5_const_principal principal, int flags, char **name, unsigned int *size)¶
param:

[in] context - Library context

[in] principal - Principal

[in] flags - Flags

[out] name - Single string format of principal name

[out] size - Size of unparsed name buffer

retval:
  • 0 Success

return:
  • Kerberos error codes. On failure name is set to NULL

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_decrypt_iov.html0000664000175000017500000002612715051422667023534 0ustar ghudsonghudson krb5_k_decrypt_iov - Decrypt data in place supporting AEAD (operates on opaque key). — MIT Kerberos Documentation

krb5_k_decrypt_iov - Decrypt data in place supporting AEAD (operates on opaque key).¶

krb5_error_code krb5_k_decrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data)¶
param:

[in] context - Library context

[in] key - Encryption key

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[in] cipher_state - Cipher state; specify NULL if not needed

[inout] data - IOV array. Modified in-place.

[in] num_data - Size of data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function decrypts the data block data and stores the output in-place. The actual decryption key will be derived from key and usage if key derivation is specified for the encryption type. If non-null, cipher_state specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5_crypto_iov structures before calling into this API.

See also

krb5_k_encrypt_iov()

Note

On return from a krb5_c_decrypt_iov() call, the data->length in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cccol_cursor_new.html0000664000175000017500000002246315051422663024217 0ustar ghudsonghudson krb5_cccol_cursor_new - Prepare to iterate over the collection of known credential caches. — MIT Kerberos Documentation

krb5_cccol_cursor_new - Prepare to iterate over the collection of known credential caches.¶

krb5_error_code krb5_cccol_cursor_new(krb5_context context, krb5_cccol_cursor *cursor)¶
param:

[in] context - Library context

[out] cursor - Cursor

retval:
  • 0 Success; otherwise - Kerberos error codes

Get a new cache iteration cursor that will iterate over all known credential caches independent of type.

Use krb5_cccol_cursor_free() to release cursor when it is no longer needed.

See also

krb5_cccol_cursor_next()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_dup.html0000664000175000017500000002134215051422662022115 0ustar ghudsonghudson krb5_cc_dup - Duplicate ccache handle. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_responder_set_answer.html0000664000175000017500000002371315051422672025120 0ustar ghudsonghudson krb5_responder_set_answer - Answer a named question in the responder context. — MIT Kerberos Documentation

krb5_responder_set_answer - Answer a named question in the responder context.¶

krb5_error_code krb5_responder_set_answer(krb5_context ctx, krb5_responder_context rctx, const char *question, const char *answer)¶
param:

[in] ctx - Library context

[in] rctx - Responder context

[in] question - Question name

[in] answer - The string to set (MUST be printable UTF-8)

retval:
  • EINVAL question is not present within rctx

This function supplies an answer to question within rctx . The appropriate form of the answer depends on the question name.

Note

New in 1.11

krb5-1.22.1/doc/html/appdev/refs/api/krb5_parse_name.html0000664000175000017500000002522115051422671022772 0ustar ghudsonghudson krb5_parse_name - Convert a string principal name to a krb5_principal structure. — MIT Kerberos Documentation

krb5_parse_name - Convert a string principal name to a krb5_principal structure.¶

krb5_error_code krb5_parse_name(krb5_context context, const char *name, krb5_principal *principal_out)¶
param:

[in] context - Library context

[in] name - String representation of a principal name

[out] principal_out - New principal

retval:
  • 0 Success

return:
  • Kerberos error codes

Convert a string representation of a principal name to a krb5_principal structure.

A string representation of a Kerberos name consists of one or more principal name components, separated by slashes, optionally followed by the @ character and a realm name. If the realm name is not specified, the local realm is used.

To use the slash and @ symbols as part of a component (quoted) instead of using them as a component separator or as a realm prefix), put a backslash () character in front of the symbol. Similarly, newline, tab, backspace, and NULL characters can be included in a component by using n , t , b or 0 , respectively.

Beginning with release 1.20, the name type of the principal will be inferred as KRB5_NT_SRV_INST or KRB5_NT_WELLKNOWN based on the principal name. The type will be KRB5_NT_PRINCIPAL if a type cannot be inferred.

Use krb5_free_principal() to free principal_out when it is no longer needed.

Note

The realm in a Kerberos name cannot contain slash, colon, or NULL characters.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_string_to_enctype.html0000664000175000017500000002130415051422673024417 0ustar ghudsonghudson krb5_string_to_enctype - Convert a string to an encryption type. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_verify_checksum_iov.html0000664000175000017500000002633515051422661025233 0ustar ghudsonghudson krb5_c_verify_checksum_iov - Validate a checksum element in IOV array (operates on keyblock). — MIT Kerberos Documentation

krb5_c_verify_checksum_iov - Validate a checksum element in IOV array (operates on keyblock).¶

krb5_error_code krb5_c_verify_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock *key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_boolean *valid)¶
param:

[in] context - Library context

[in] cksumtype - Checksum type (0 for mandatory type)

[in] key - Encryption key for a keyed checksum

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[in] data - IOV array

[in] num_data - Size of data

[out] valid - Non-zero for success, zero for failure

retval:
  • 0 Success; otherwise - Kerberos error codes

Confirm that the checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element is a valid checksum of the KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY regions in the iov.

See also

krb5_c_make_checksum_iov()

Note

This function is similar to krb5_k_verify_checksum_iov(), but operates on keyblock key .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_keyblock_contents.html0000664000175000017500000002225215051422663025434 0ustar ghudsonghudson krb5_copy_keyblock_contents - Copy the contents of a keyblock. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getlocalseqnumber.html0000664000175000017500000002311415051422657026257 0ustar ghudsonghudson krb5_auth_con_getlocalseqnumber - Retrieve the local sequence number from an auth context. — MIT Kerberos Documentation

krb5_auth_con_getlocalseqnumber - Retrieve the local sequence number from an auth context.¶

krb5_error_code krb5_auth_con_getlocalseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[out] seqnumber - Local sequence number

retval:
  • 0 Success; otherwise - Kerberos error codes

Retrieve the local sequence number from auth_context and return it in seqnumber . The KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in auth_context for this function to be useful.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_encrypt_size.html0000664000175000017500000001715515051422664023407 0ustar ghudsonghudson krb5_encrypt_size — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_new_unique.html0000664000175000017500000002312415051422662023504 0ustar ghudsonghudson krb5_cc_new_unique - Create a new credential cache of the specified type with a unique name. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_initialize.html0000664000175000017500000002237615051422662023476 0ustar ghudsonghudson krb5_cc_initialize - Initialize a credential cache. — MIT Kerberos Documentation

krb5_cc_initialize - Initialize a credential cache.¶

krb5_error_code krb5_cc_initialize(krb5_context context, krb5_ccache cache, krb5_principal principal)¶
param:

[in] context - Library context

[in] cache - Credential cache handle

[in] principal - Default principal name

retval:
  • 0 Success

return:
  • System errors; Permission errors; Kerberos error codes

Destroy any existing contents of cache and initialize it for the default principal principal .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_mk_req.html0000664000175000017500000002616315051422670022143 0ustar ghudsonghudson krb5_mk_req - Create a KRB_AP_REQ message. — MIT Kerberos Documentation

krb5_mk_req - Create a KRB_AP_REQ message.¶

krb5_error_code krb5_mk_req(krb5_context context, krb5_auth_context *auth_context, krb5_flags ap_req_options, const char *service, const char *hostname, krb5_data *in_data, krb5_ccache ccache, krb5_data *outbuf)¶
param:

[in] context - Library context

[inout] auth_context - Pre-existing or newly created auth context

[in] ap_req_options - Options (see AP_OPTS macros)

[in] service - Service name, or NULL to use “hostâ€

[in] hostname - Host name, or NULL to use local hostname

[in] in_data - Application data to be checksummed in the authenticator, or NULL

[in] ccache - Credential cache used to obtain credentials for the desired service.

[out] outbuf - AP-REQ message

retval:
  • 0 Success; otherwise - Kerberos error codes

This function is similar to krb5_mk_req_extended() except that it uses a given hostname , service , and ccache to construct a service principal name and obtain credentials.

Use krb5_free_data_contents() to free outbuf when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_switch.html0000664000175000017500000002224515051422663022632 0ustar ghudsonghudson krb5_cc_switch - Make a credential cache the primary cache for its collection. — MIT Kerberos Documentation

krb5_cc_switch - Make a credential cache the primary cache for its collection.¶

krb5_error_code krb5_cc_switch(krb5_context context, krb5_ccache cache)¶
param:

[in] context - Library context

[in] cache - Credential cache handle

retval:
  • 0 Success, or the type of cache doesn’t support switching

return:
  • Kerberos error codes

If the type of cache supports it, set cache to be the primary credential cache for the collection it belongs to.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_responder_get_challenge.html0000664000175000017500000002333315051422672025525 0ustar ghudsonghudson krb5_responder_get_challenge - Retrieve the challenge data for a given question in the responder context. — MIT Kerberos Documentation

krb5_responder_get_challenge - Retrieve the challenge data for a given question in the responder context.¶

const char *krb5_responder_get_challenge(krb5_context ctx, krb5_responder_context rctx, const char *question)¶
param:

[in] ctx - Library context

[in] rctx - Responder context

[in] question - Question name

Return a pointer to a C string containing the challenge for question within rctx , or NULL if the question is not present in rctx . The structure of the question depends on the question name, but will always be printable UTF-8 text. The returned pointer is an alias, valid only as long as the lifetime of rctx , and should not be modified or freed by the caller.

Note

New in 1.11

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_end_seq_get.html0000664000175000017500000002204515051422670023633 0ustar ghudsonghudson krb5_kt_end_seq_get - Release a keytab cursor. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_responder_pkinit_challenge_free.html0000664000175000017500000002266515051422672027254 0ustar ghudsonghudson krb5_responder_pkinit_challenge_free - Free the value returned by krb5_responder_pkinit_get_challenge(). — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_crypto_length_iov.html0000664000175000017500000002342315051422661024721 0ustar ghudsonghudson krb5_c_crypto_length_iov - Fill in lengths for header, trailer and padding in a IOV array. — MIT Kerberos Documentation

krb5_c_crypto_length_iov - Fill in lengths for header, trailer and padding in a IOV array.¶

krb5_error_code krb5_c_crypto_length_iov(krb5_context context, krb5_enctype enctype, krb5_crypto_iov *data, size_t num_data)¶
param:

[in] context - Library context

[in] enctype - Encryption type

[inout] data - IOV array

[in] num_data - Size of data

retval:
  • 0 Success; otherwise - Kerberos error codes

Padding is set to the actual padding required based on the provided data buffers. Typically this API is used after setting up the data buffers and KRB5_CRYPTO_TYPE_SIGN_ONLY buffers, but before actually allocating header, trailer and padding.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_realm_compare.html0000664000175000017500000002215615051422672023473 0ustar ghudsonghudson krb5_realm_compare - Compare the realms of two principals. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_cred_contents.html0000664000175000017500000002077215051422664024523 0ustar ghudsonghudson krb5_free_cred_contents - Free the contents of a krb5_creds structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_default_realm.html0000664000175000017500000002173115051422665024330 0ustar ghudsonghudson krb5_get_default_realm - Retrieve the default realm. — MIT Kerberos Documentation

krb5_get_default_realm - Retrieve the default realm.¶

krb5_error_code krb5_get_default_realm(krb5_context context, char **lrealm)¶
param:

[in] context - Library context

[out] lrealm - Default realm name

retval:
  • 0 Success

return:
  • Kerberos error codes

Retrieves the default realm to be used if no user-specified realm is available.

Use krb5_free_default_realm() to free lrealm when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_build_principal_alloc_va.html0000664000175000017500000002440615051422661025663 0ustar ghudsonghudson krb5_build_principal_alloc_va - Build a principal name, using a precomputed variable argument list. — MIT Kerberos Documentation

krb5_build_principal_alloc_va - Build a principal name, using a precomputed variable argument list.¶

krb5_error_code krb5_build_principal_alloc_va(krb5_context context, krb5_principal *princ, unsigned int rlen, const char *realm, va_list ap)¶
param:

[in] context - Library context

[out] princ - Principal structure

[in] rlen - Realm name length

[in] realm - Realm name

[in] ap - List of char * components, ending with NULL

retval:
  • 0 Success

return:
  • Kerberos error codes

Similar to krb5_build_principal(), this function builds a principal name, but its name components are specified as a va_list.

Use krb5_free_principal() to deallocate princ when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_real_time.html0000664000175000017500000002241315051422672023475 0ustar ghudsonghudson krb5_set_real_time - Set time offset field in a krb5_context structure. — MIT Kerberos Documentation

krb5_set_real_time - Set time offset field in a krb5_context structure.¶

krb5_error_code krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds)¶
param:

[in] context - Library context

[in] seconds - Real time, seconds portion

[in] microseconds - Real time, microseconds portion

retval:
  • 0 Success; otherwise - Kerberos error codes

This function sets the time offset in context to the difference between the system time and the real time as determined by seconds and microseconds .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_decrypt_iov.html0000664000175000017500000002643515051422661023520 0ustar ghudsonghudson krb5_c_decrypt_iov - Decrypt data in place supporting AEAD (operates on keyblock). — MIT Kerberos Documentation

krb5_c_decrypt_iov - Decrypt data in place supporting AEAD (operates on keyblock).¶

krb5_error_code krb5_c_decrypt_iov(krb5_context context, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data)¶
param:

[in] context - Library context

[in] keyblock - Encryption key

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[in] cipher_state - Cipher state; specify NULL if not needed

[inout] data - IOV array. Modified in-place.

[in] num_data - Size of data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function decrypts the data block data and stores the output in-place. The actual decryption key will be derived from keyblock and usage if key derivation is specified for the encryption type. If non-null, cipher_state specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5_crypto_iov structures before calling into this API.

See also

krb5_c_decrypt_iov()

Note

On return from a krb5_c_decrypt_iov() call, the data->length in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_expire_callback.html0000664000175000017500000002670315051422665030600 0ustar ghudsonghudson krb5_get_init_creds_opt_set_expire_callback - Set an expiration callback in initial credential options. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_expire_callback - Set an expiration callback in initial credential options.¶

krb5_error_code krb5_get_init_creds_opt_set_expire_callback(krb5_context context, krb5_get_init_creds_opt *opt, krb5_expire_callback_func cb, void *data)¶
param:

[in] context - Library context

[in] opt - Options structure

[in] cb - Callback function

[in] data - Callback argument

Set a callback to receive password and account expiration times.

cb will be invoked if and only if credentials are successfully acquired. The callback will receive the context from the calling function and the data argument supplied with this API. The remaining arguments should be interpreted as follows:

If is_last_req is true, then the KDC reply contained last-req entries which unambiguously indicated the password expiration, account expiration, or both. (If either value was not present, the corresponding argument will be 0.) Furthermore, a non-zero password_expiration should be taken as a suggestion from the KDC that a warning be displayed.

If is_last_req is false, then account_expiration will be 0 and password_expiration will contain the expiration time of either the password or account, or 0 if no expiration time was indicated in the KDC reply. The callback should independently decide whether to display a password expiration warning.

Note that cb may be invoked even if credentials are being acquired for the kadmin/changepw service in order to change the password. It is the caller’s responsibility to avoid displaying a password expiry warning in this case.

Warning

Setting an expire callback with this API will cause krb5_get_init_creds_password() not to send password expiry warnings to the prompter, as it ordinarily may.

Note

New in 1.9

krb5-1.22.1/doc/html/appdev/refs/api/krb5_string_to_timestamp.html0000664000175000017500000002133515051422673024757 0ustar ghudsonghudson krb5_string_to_timestamp - Convert a string to a timestamp. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_os_localaddr.html0000664000175000017500000002150315051422671023305 0ustar ghudsonghudson krb5_os_localaddr - Return all interface addresses for this host. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_mk_req_extended.html0000664000175000017500000002671015051422670024021 0ustar ghudsonghudson krb5_mk_req_extended - Create a KRB_AP_REQ message using supplied credentials. — MIT Kerberos Documentation

krb5_mk_req_extended - Create a KRB_AP_REQ message using supplied credentials.¶

krb5_error_code krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context, krb5_flags ap_req_options, krb5_data *in_data, krb5_creds *in_creds, krb5_data *outbuf)¶
param:

[in] context - Library context

[inout] auth_context - Pre-existing or newly created auth context

[in] ap_req_options - Options (see AP_OPTS macros)

[in] in_data - Application data to be checksummed in the authenticator, or NULL

[in] in_creds - Credentials for the service with valid ticket and key

[out] outbuf - AP-REQ message

retval:
  • 0 Success; otherwise - Kerberos error codes

Valid ap_req_options are:

  • AP_OPTS_USE_SESSION_KEY - Use the session key when creating the request used for user to user authentication.

  • AP_OPTS_MUTUAL_REQUIRED - Request a mutual authentication packet from the receiver.

  • AP_OPTS_USE_SUBKEY - Generate a subsession key from the current session key obtained from the credentials.

This function creates a KRB_AP_REQ message using supplied credentials in_creds . auth_context may point to an existing auth context or to NULL, in which case a new one will be created. If in_data is non-null, a checksum of it will be included in the authenticator contained in the KRB_AP_REQ message. Use krb5_free_data_contents() to free outbuf when it is no longer needed.

On successful return, the authenticator is stored in auth_context with the client and checksum fields nulled out. (This is to prevent pointer-sharing problems; the caller should not need these fields anyway, since the caller supplied them.)

See also

krb5_mk_req()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_get_full_name.html0000664000175000017500000002165715051422662024137 0ustar ghudsonghudson krb5_cc_get_full_name - Retrieve the full name of a credential cache. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_setrecvsubkey.html0000664000175000017500000002267715051422660025450 0ustar ghudsonghudson krb5_auth_con_setrecvsubkey - Set the receiving subkey in an auth context with a keyblock. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_524_conv_principal.html0000664000175000017500000002416215051422657024267 0ustar ghudsonghudson krb5_524_conv_principal - Convert a Kerberos V5 principal to a Kerberos V4 principal. — MIT Kerberos Documentation

krb5_524_conv_principal - Convert a Kerberos V5 principal to a Kerberos V4 principal.¶

krb5_error_code krb5_524_conv_principal(krb5_context context, krb5_const_principal princ, char *name, char *inst, char *realm)¶
param:

[in] context - Library context

[in] princ - V5 Principal

[out] name - V4 principal’s name to be filled in

[out] inst - V4 principal’s instance name to be filled in

[out] realm - Principal’s realm name to be filled in

retval:
  • 0 Success

  • KRB5_INVALID_PRINCIPAL Invalid principal name

  • KRB5_CONFIG_CANTOPEN Can’t open or find Kerberos configuration file

return:
  • Kerberos error codes

This function separates a V5 principal princ into name , instance , and realm .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_in_tkt_with_keytab.html0000664000175000017500000002457115051422665025413 0ustar ghudsonghudson krb5_get_in_tkt_with_keytab — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_end_seq_get.html0000664000175000017500000002256115051422662023606 0ustar ghudsonghudson krb5_cc_end_seq_get - Finish a series of sequential processing credential cache entries. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_tkt_creds_get_times.html0000664000175000017500000002315115051422673024704 0ustar ghudsonghudson krb5_tkt_creds_get_times - Retrieve ticket times from a TGS request context. — MIT Kerberos Documentation

krb5_tkt_creds_get_times - Retrieve ticket times from a TGS request context.¶

krb5_error_code krb5_tkt_creds_get_times(krb5_context context, krb5_tkt_creds_context ctx, krb5_ticket_times *times)¶
param:

[in] context - Library context

[in] ctx - TGS request context

[out] times - Ticket times for acquired credentials

retval:
  • 0 Success; otherwise - Kerberos error codes

The TGS request context must have completed obtaining credentials via either krb5_tkt_creds_get() or krb5_tkt_creds_step().

Note

New in 1.9

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_reference_key.html0000664000175000017500000002046115051422667024006 0ustar ghudsonghudson krb5_k_reference_key - Increment the reference count on a key. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_rd_cred.html0000664000175000017500000002463615051422671022273 0ustar ghudsonghudson krb5_rd_cred - Read and validate a KRB-CRED message. — MIT Kerberos Documentation

krb5_rd_cred - Read and validate a KRB-CRED message.¶

krb5_error_code krb5_rd_cred(krb5_context context, krb5_auth_context auth_context, krb5_data *creddata, krb5_creds ***creds_out, krb5_replay_data *rdata_out)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] creddata - KRB-CRED message

[out] creds_out - Null-terminated array of forwarded credentials

[out] rdata_out - Replay data (NULL if not needed)

retval:
  • 0 Success; otherwise - Kerberos error codes

creddata will be decrypted using the receiving subkey if it is present in auth_context , or the session key if the receiving subkey is not present or fails to decrypt the message.

Use krb5_free_tgt_creds() to free creds_out when it is no longer needed.

Note

The rdata_out argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in auth_context .`

krb5-1.22.1/doc/html/appdev/refs/api/krb5_marshal_credentials.html0000664000175000017500000002265315051422670024671 0ustar ghudsonghudson krb5_marshal_credentials - Serialize a krb5_creds object. — MIT Kerberos Documentation

krb5_marshal_credentials - Serialize a krb5_creds object.¶

krb5_error_code krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds, krb5_data **data_out)¶
param:

[in] context - Library context

[in] in_creds - The credentials object to serialize

[out] data_out - The serialized credentials

retval:
  • 0 Success; otherwise - Kerberos error codes

Serialize creds in the format used by the FILE ccache format (vesion 4) and KCM ccache protocol.

Use krb5_free_data() to free data_out when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_unparse_name.html0000664000175000017500000002310115051422673023332 0ustar ghudsonghudson krb5_unparse_name - Convert a krb5_principal structure to a string representation. — MIT Kerberos Documentation

krb5_unparse_name - Convert a krb5_principal structure to a string representation.¶

krb5_error_code krb5_unparse_name(krb5_context context, krb5_const_principal principal, char **name)¶
param:

[in] context - Library context

[in] principal - Principal

[out] name - String representation of principal name

retval:
  • 0 Success

return:
  • Kerberos error codes

The resulting string representation uses the format and quoting conventions described for krb5_parse_name().

Use krb5_free_unparsed_name() to free name when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_setrcache.html0000664000175000017500000002264215051422660024503 0ustar ghudsonghudson krb5_auth_con_setrcache - Set the replay cache in an auth context. — MIT Kerberos Documentation

krb5_auth_con_setrcache - Set the replay cache in an auth context.¶

krb5_error_code krb5_auth_con_setrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache rcache)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] rcache - Replay cache haddle

retval:
  • 0 Success; otherwise - Kerberos error codes

This function sets the replay cache in auth_context to rcache . rcache will be closed when auth_context is freed, so the caller should relinquish that responsibility.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_timestamp_to_string.html0000664000175000017500000002200615051422673024753 0ustar ghudsonghudson krb5_timestamp_to_string - Convert a timestamp to a string. — MIT Kerberos Documentation

krb5_timestamp_to_string - Convert a timestamp to a string.¶

krb5_error_code krb5_timestamp_to_string(krb5_timestamp timestamp, char *buffer, size_t buflen)¶
param:

[in] timestamp - Timestamp to convert

[out] buffer - Buffer to hold converted timestamp

[in] buflen - Storage available in buffer

retval:
  • 0 Success; otherwise - Kerberos error codes

The string is returned in the locale’s appropriate date and time representation.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_verify_init_creds.html0000664000175000017500000002677115051422673024404 0ustar ghudsonghudson krb5_verify_init_creds - Verify initial credentials against a keytab. — MIT Kerberos Documentation

krb5_verify_init_creds - Verify initial credentials against a keytab.¶

krb5_error_code krb5_verify_init_creds(krb5_context context, krb5_creds *creds, krb5_principal server, krb5_keytab keytab, krb5_ccache *ccache, krb5_verify_init_creds_opt *options)¶
param:

[in] context - Library context

[in] creds - Initial credentials to be verified

[in] server - Server principal (or NULL)

[in] keytab - Key table (NULL to use default keytab)

[in] ccache - Credential cache for fetched creds (or NULL)

[in] options - Verification options (NULL for default options)

retval:
  • 0 Success; otherwise - Kerberos error codes

This function attempts to verify that creds were obtained from a KDC with knowledge of a key in keytab , or the default keytab if keytab is NULL. If server is provided, the highest-kvno key entry for that principal name is used to verify the credentials; otherwise, all uniqueâ€hostâ€service principals in the keytab are tried.

If the specified keytab does not exist, or is empty, or cannot be read, or does not contain an entry for server , then credential verification may be skipped unless configuration demands that it succeed. The caller can control this behavior by providing a verification options structure; see krb5_verify_init_creds_opt_init() and krb5_verify_init_creds_opt_set_ap_req_nofail().

If ccache is NULL, any additional credentials fetched during the verification process will be destroyed. If ccache points to NULL, a memory ccache will be created for the additional credentials and returned in ccache . If ccache points to a valid credential cache handle, the additional credentials will be stored in that cache.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_get.html0000664000175000017500000002243515051422667023653 0ustar ghudsonghudson krb5_init_creds_get - Acquire credentials using an initial credentials context. — MIT Kerberos Documentation

krb5_init_creds_get - Acquire credentials using an initial credentials context.¶

krb5_error_code krb5_init_creds_get(krb5_context context, krb5_init_creds_context ctx)¶
param:

[in] context - Library context

[in] ctx - Initial credentials context

retval:
  • 0 Success; otherwise - Kerberos error codes

This function synchronously obtains credentials using a context created by krb5_init_creds_init(). On successful return, the credentials can be retrieved with krb5_init_creds_get_creds().

context must be the same as the one passed to krb5_init_creds_init() for this initial credentials context.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_vwrap_error_message.html0000664000175000017500000002331015051422674024734 0ustar ghudsonghudson krb5_vwrap_error_message - Add a prefix to a different error code’s message using a va_list. — MIT Kerberos Documentation

krb5_vwrap_error_message - Add a prefix to a different error code’s message using a va_list.¶

void krb5_vwrap_error_message(krb5_context ctx, krb5_error_code old_code, krb5_error_code code, const char *fmt, va_list args)¶
param:

[in] ctx - Library context

[in] old_code - Previous error code

[in] code - Error code

[in] fmt - Format string for error message prefix

[in] args - List of vprintf(3) style arguments

This function is similar to krb5_wrap_error_message(), but uses a va_list instead of variadic arguments.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_renew_life.html0000664000175000017500000002215215051422666027602 0ustar ghudsonghudson krb5_get_init_creds_opt_set_renew_life - Set the ticket renewal lifetime in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_calculate_checksum.html0000664000175000017500000002221715051422661024500 0ustar ghudsonghudson krb5_calculate_checksum — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_fast_ccache.html0000664000175000017500000002336615051422665027715 0ustar ghudsonghudson krb5_get_init_creds_opt_set_fast_ccache - Set FAST armor cache in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_random_make_octets.html0000664000175000017500000002123615051422661025021 0ustar ghudsonghudson krb5_c_random_make_octets - Generate pseudo-random bytes. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_allow_weak_crypto.html0000664000175000017500000002211215051422657024405 0ustar ghudsonghudson krb5_allow_weak_crypto - Allow the application to override the profile’s allow_weak_crypto setting. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_mk_safe.html0000664000175000017500000002665315051422670022276 0ustar ghudsonghudson krb5_mk_safe - Format a KRB-SAFE message. — MIT Kerberos Documentation

krb5_mk_safe - Format a KRB-SAFE message.¶

krb5_error_code krb5_mk_safe(krb5_context context, krb5_auth_context auth_context, const krb5_data *userdata, krb5_data *der_out, krb5_replay_data *rdata_out)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] userdata - User data in the message

[out] der_out - Formatted KRB-SAFE buffer

[out] rdata_out - Replay data. Specify NULL if not needed

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates an integrity protected KRB-SAFE message using data supplied by the application.

Fields in auth_context specify the checksum type, the keyblock that can be used to seed the checksum, full addresses (host and port) for the sender and receiver, and KRB5_AUTH_CONTEXT flags.

The local address in auth_context must be set, and is used to form the sender address used in the KRB-SAFE message. The remote address is optional; if specified, it will be used to form the receiver address used in the message.

If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in auth_context , a timestamp is included in the KRB-SAFE message, and an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If KRB5_AUTH_CONTEXT_RET_TIME is set in auth_context , a timestamp is included in the KRB-SAFE message and is stored in rdata_out .

If either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the auth_context local sequence number is included in the KRB-SAFE message and then incremented. If KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in rdata_out .

Use krb5_free_data_contents() to free der_out when it is no longer needed.

Note

The rdata_out argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in auth_context .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_valid_enctype.html0000664000175000017500000002133615051422661024012 0ustar ghudsonghudson krb5_c_valid_enctype - Verify that a specified encryption type is a valid Kerberos encryption type. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_get_creds.html0000664000175000017500000002333215051422667025030 0ustar ghudsonghudson krb5_init_creds_get_creds - Retrieve acquired credentials from an initial credentials context. — MIT Kerberos Documentation

krb5_init_creds_get_creds - Retrieve acquired credentials from an initial credentials context.¶

krb5_error_code krb5_init_creds_get_creds(krb5_context context, krb5_init_creds_context ctx, krb5_creds *creds)¶
param:

[in] context - Library context

[in] ctx - Initial credentials context

[out] creds - Acquired credentials

retval:
  • 0 Success; otherwise - Kerberos error codes

This function copies the acquired initial credentials from ctx into creds , after the successful completion of krb5_init_creds_get() or krb5_init_creds_step(). Use krb5_free_cred_contents() to free creds when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_is_coll_proof_cksum.html0000664000175000017500000002076515051422661025224 0ustar ghudsonghudson krb5_c_is_coll_proof_cksum - Test whether a checksum type is collision-proof. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_derive_prfplus.html0000664000175000017500000002417415051422661024220 0ustar ghudsonghudson krb5_c_derive_prfplus - Derive a key using some input data (via RFC 6113 PRF+). — MIT Kerberos Documentation

krb5_c_derive_prfplus - Derive a key using some input data (via RFC 6113 PRF+).¶

krb5_error_code krb5_c_derive_prfplus(krb5_context context, const krb5_keyblock *k, const krb5_data *input, krb5_enctype enctype, krb5_keyblock **out)¶
param:

[in] context - Library context

[in] k - KDC contribution key

[in] input - Input string

[in] enctype - Output key enctype (or ENCTYPE_NULL )

[out] out - Derived keyblock

This function uses PRF+ as defined in RFC 6113 to derive a key from another key and an input string. If enctype is ENCTYPE_NULL , the output key will have the same enctype as the input key.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cksumtype_to_string.html0000664000175000017500000002201215051422663024770 0ustar ghudsonghudson krb5_cksumtype_to_string - Convert a checksum type to a string. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_tkt_creds_get_creds.html0000664000175000017500000002326215051422673024666 0ustar ghudsonghudson krb5_tkt_creds_get_creds - Retrieve acquired credentials from a TGS request context. — MIT Kerberos Documentation

krb5_tkt_creds_get_creds - Retrieve acquired credentials from a TGS request context.¶

krb5_error_code krb5_tkt_creds_get_creds(krb5_context context, krb5_tkt_creds_context ctx, krb5_creds *creds)¶
param:

[in] context - Library context

[in] ctx - TGS request context

[out] creds - Acquired credentials

retval:
  • 0 Success; otherwise - Kerberos error codes

This function copies the acquired initial credentials from ctx into creds , after the successful completion of krb5_tkt_creds_get() or krb5_tkt_creds_step(). Use krb5_free_cred_contents() to free creds when it is no longer needed.

Note

New in 1.9

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_setports.html0000664000175000017500000002364515051422660024431 0ustar ghudsonghudson krb5_auth_con_setports - Set local and remote port fields in an auth context. — MIT Kerberos Documentation

krb5_auth_con_setports - Set local and remote port fields in an auth context.¶

krb5_error_code krb5_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb5_address *local_port, krb5_address *remote_port)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] local_port - Local port

[in] remote_port - Remote port

retval:
  • 0 Success; otherwise - Kerberos error codes

This function releases the storage assigned to the contents of the local and remote ports of auth_context and then sets them to local_port and remote_port respectively.

See also

krb5_auth_con_genaddrs()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_default.html0000664000175000017500000002144415051422670023004 0ustar ghudsonghudson krb5_kt_default - Resolve the default key table. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_renewed_creds.html0000664000175000017500000002454715051422666024346 0ustar ghudsonghudson krb5_get_renewed_creds - Get renewed credential from KDC using an existing credential. — MIT Kerberos Documentation

krb5_get_renewed_creds - Get renewed credential from KDC using an existing credential.¶

krb5_error_code krb5_get_renewed_creds(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_ccache ccache, const char *in_tkt_service)¶
param:

[in] context - Library context

[out] creds - Renewed credentials

[in] client - Client principal name

[in] ccache - Credential cache

[in] in_tkt_service - Server principal string (or NULL)

retval:
  • 0 Success

return:
  • Kerberos error codes

This function gets a renewed credential using an existing one from ccache . If in_tkt_service is specified, it is parsed (with the realm part ignored) and used as the server principal of the credential; otherwise, the ticket-granting service is used.

If successful, the renewed credential is placed in creds .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_free.html0000664000175000017500000002157115051422657023471 0ustar ghudsonghudson krb5_auth_con_free - Free a krb5_auth_context structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_mk_rep.html0000664000175000017500000002262415051422670022140 0ustar ghudsonghudson krb5_mk_rep - Format and encrypt a KRB_AP_REP message. — MIT Kerberos Documentation

krb5_mk_rep - Format and encrypt a KRB_AP_REP message.¶

krb5_error_code krb5_mk_rep(krb5_context context, krb5_auth_context auth_context, krb5_data *outbuf)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[out] outbuf - AP-REP message

retval:
  • 0 Success; otherwise - Kerberos error codes

This function fills in outbuf with an AP-REP message using information from auth_context .

If the flags in auth_context indicate that a sequence number should be used (either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE) and the local sequence number in auth_context is 0, a new number will be generated with krb5_generate_seq_number().

Use krb5_free_data_contents() to free outbuf when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_add_buffer.html0000664000175000017500000002363015051422671023566 0ustar ghudsonghudson krb5_pac_add_buffer - Add a buffer to a PAC handle. — MIT Kerberos Documentation

krb5_pac_add_buffer - Add a buffer to a PAC handle.¶

krb5_error_code krb5_pac_add_buffer(krb5_context context, krb5_pac pac, krb5_ui_4 type, const krb5_data *data)¶
param:

[in] context - Library context

[in] pac - PAC handle

[in] type - Buffer type

[in] data - contents

retval:
  • 0 Success; otherwise - Kerberos error codes

This function adds a buffer of type type and contents data to pac if there isn’t already a buffer of this type present.

The valid values of type is one of the following:

  • KRB5_PAC_LOGON_INFO - Logon information

  • KRB5_PAC_CREDENTIALS_INFO - Credentials information

  • KRB5_PAC_SERVER_CHECKSUM - Server checksum

  • KRB5_PAC_PRIVSVR_CHECKSUM - KDC checksum

  • KRB5_PAC_CLIENT_INFO - Client name and ticket information

  • KRB5_PAC_DELEGATION_INFO - Constrained delegation information

  • KRB5_PAC_UPN_DNS_INFO - User principal name and DNS information

krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_data.html0000664000175000017500000002237315051422663022631 0ustar ghudsonghudson krb5_copy_data - Copy a krb5_data object. — MIT Kerberos Documentation

krb5_copy_data - Copy a krb5_data object.¶

krb5_error_code krb5_copy_data(krb5_context context, const krb5_data *indata, krb5_data **outdata)¶
param:

[in] context - Library context

[in] indata - Data object to be copied

[out] outdata - Copy of indata

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new krb5_data object with the contents of indata . Use krb5_free_data() to free outdata when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_etype_info.html0000664000175000017500000002677715051422665023704 0ustar ghudsonghudson krb5_get_etype_info - Retrieve enctype, salt and s2kparams from KDC. — MIT Kerberos Documentation

krb5_get_etype_info - Retrieve enctype, salt and s2kparams from KDC.¶

krb5_error_code krb5_get_etype_info(krb5_context context, krb5_principal principal, krb5_get_init_creds_opt *opt, krb5_enctype *enctype_out, krb5_data *salt_out, krb5_data *s2kparams_out)¶
param:

[in] context - Library context

[in] principal - Principal whose information is requested

[in] opt - Initial credential options

[out] enctype_out - The enctype chosen by KDC

[out] salt_out - Salt returned from KDC

[out] s2kparams_out - String-to-key parameters returned from KDC

retval:
  • 0 Success

return:
  • A Kerberos error code

Send an initial ticket request for principal and extract the encryption type, salt type, and string-to-key parameters from the KDC response. If the KDC provides no etype-info, set enctype_out to ENCTYPE_NULL and set salt_out and s2kparams_out to empty. If the KDC etype-info provides no salt, compute the default salt and place it in salt_out . If the KDC etype-info provides no string-to-key parameters, set s2kparams_out to empty.

opt may be used to specify options which affect the initial request, such as request encryption types or a FAST armor cache (see krb5_get_init_creds_opt_set_etype_list() and krb5_get_init_creds_opt_set_fast_ccache_name()).

Use krb5_free_data_contents() to free salt_out and s2kparams_out when they are no longer needed.

Note

New in 1.17

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_keytab.html0000664000175000017500000002600015051422665025200 0ustar ghudsonghudson krb5_get_init_creds_keytab - Get initial credentials using a key table. — MIT Kerberos Documentation

krb5_get_init_creds_keytab - Get initial credentials using a key table.¶

krb5_error_code krb5_get_init_creds_keytab(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_keytab arg_keytab, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *k5_gic_options)¶
param:

[in] context - Library context

[out] creds - New credentials

[in] client - Client principal

[in] arg_keytab - Key table handle

[in] start_time - Time when ticket becomes valid (0 for now)

[in] in_tkt_service - Service name of initial credentials (or NULL)

[in] k5_gic_options - Initial credential options

retval:
  • 0 Success

return:
  • Kerberos error codes

This function requests KDC for an initial credentials for client using a client key stored in arg_keytab . If in_tkt_service is specified, it is parsed as a principal name (with the realm ignored) and used as the service principal for the request; otherwise the ticket-granting service is used.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_principal_compare_flags.html0000664000175000017500000002360515051422671025527 0ustar ghudsonghudson krb5_principal_compare_flags - Compare two principals with additional flags. — MIT Kerberos Documentation

krb5_principal_compare_flags - Compare two principals with additional flags.¶

krb5_boolean krb5_principal_compare_flags(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2, int flags)¶
param:

[in] context - Library context

[in] princ1 - First principal

[in] princ2 - Second principal

[in] flags - Flags

retval:
  • TRUE if the principal names are the same; FALSE otherwise

Valid flags are:

  • KRB5_PRINCIPAL_COMPARE_IGNORE_REALM - ignore realm component

  • KRB5_PRINCIPAL_COMPARE_ENTERPRISE - UPNs as real principals

  • KRB5_PRINCIPAL_COMPARE_CASEFOLD case-insensitive

  • KRB5_PRINCIPAL_COMPARE_UTF8 - treat principals as UTF-8

See also

krb5_principal_compare()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_setrecvsubkey_k.html0000664000175000017500000002275415051422660025756 0ustar ghudsonghudson krb5_auth_con_setrecvsubkey_k - Set the receiving subkey in an auth context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_alloc.html0000664000175000017500000002244415051422665025705 0ustar ghudsonghudson krb5_get_init_creds_opt_alloc - Allocate a new initial credential options structure. — MIT Kerberos Documentation

krb5_get_init_creds_opt_alloc - Allocate a new initial credential options structure.¶

krb5_error_code krb5_get_init_creds_opt_alloc(krb5_context context, krb5_get_init_creds_opt **opt)¶
param:

[in] context - Library context

[out] opt - New options structure

retval:
  • 0 - Success; Kerberos errors otherwise.

This function is the preferred way to create an options structure for getting initial credentials, and is required to make use of certain options. Use krb5_get_init_creds_opt_free() to free opt when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_merge_authdata.html0000664000175000017500000002450515051422670023635 0ustar ghudsonghudson krb5_merge_authdata - Merge two authorization data lists into a new list. — MIT Kerberos Documentation

krb5_merge_authdata - Merge two authorization data lists into a new list.¶

krb5_error_code krb5_merge_authdata(krb5_context context, krb5_authdata *const *inauthdat1, krb5_authdata *const *inauthdat2, krb5_authdata ***outauthdat)¶
param:

[in] context - Library context

[in] inauthdat1 - First list of krb5_authdata structures

[in] inauthdat2 - Second list of krb5_authdata structures

[out] outauthdat - Merged list of krb5_authdata structures

retval:
  • 0 Success; otherwise - Kerberos error codes

Merge two authdata arrays, such as the array from a ticket and authenticator. Use krb5_free_authdata() to free outauthdat when it is no longer needed.

Note

The last array entry in inauthdat1 and inauthdat2 must be a NULL pointer.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_setflags.html0000664000175000017500000002303715051422660024351 0ustar ghudsonghudson krb5_auth_con_setflags - Set a flags field in a krb5_auth_context structure. — MIT Kerberos Documentation

krb5_auth_con_setflags - Set a flags field in a krb5_auth_context structure.¶

krb5_error_code krb5_auth_con_setflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 flags)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] flags - Flags bit mask

retval:
  • 0 (always)

Valid values for flags are:

  • KRB5_AUTH_CONTEXT_DO_TIME Use timestamps

  • KRB5_AUTH_CONTEXT_RET_TIME Save timestamps

  • KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers

  • KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers

krb5-1.22.1/doc/html/appdev/refs/api/krb5_rd_safe.html0000664000175000017500000002571615051422672022275 0ustar ghudsonghudson krb5_rd_safe - Process KRB-SAFE message. — MIT Kerberos Documentation

krb5_rd_safe - Process KRB-SAFE message.¶

krb5_error_code krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_data *userdata_out, krb5_replay_data *rdata_out)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] inbuf - KRB-SAFE message to be parsed

[out] userdata_out - Data parsed from KRB-SAFE message

[out] rdata_out - Replay data. Specify NULL if not needed

retval:
  • 0 Success; otherwise - Kerberos error codes

This function parses a KRB-SAFE message, verifies its integrity, and stores its data into userdata_out .

If auth_context has a remote address set, the address will be used to verify the sender address in the KRB-SAFE message. If auth_context has a local address set, it will be used to verify the receiver address in the KRB-SAFE message if the message contains one.

If the KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in auth_context , the sequence number of the KRB-SAFE message is checked against the remote sequence number field of auth_context . Otherwise, the sequence number is not used.

If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in auth_context , then the timestamp in the message is verified to be within the permitted clock skew of the current time, and the message is checked against an in-memory replay cache to detect reflections or replays.

Use krb5_free_data_contents() to free userdata_out when it is no longer needed.

Note

The rdata_out argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in auth_context .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getsendsubkey_k.html0000664000175000017500000002266015051422660025730 0ustar ghudsonghudson krb5_auth_con_getsendsubkey_k - Retrieve the send subkey from an auth context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_config_files.html0000664000175000017500000002040715051422664024313 0ustar ghudsonghudson krb5_free_config_files - Free a list allocated by krb5_get_default_config_files() — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_free_entry.html0000664000175000017500000001766615051422670023535 0ustar ghudsonghudson krb5_kt_free_entry — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_get_checksum_func.html0000664000175000017500000002320215051422657026215 0ustar ghudsonghudson krb5_auth_con_get_checksum_func - Get the checksum callback from an auth context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_start_seq_get.html0000664000175000017500000002313715051422663024176 0ustar ghudsonghudson krb5_cc_start_seq_get - Prepare to sequentially read every credential in a credential cache. — MIT Kerberos Documentation

krb5_cc_start_seq_get - Prepare to sequentially read every credential in a credential cache.¶

krb5_error_code krb5_cc_start_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor)¶
param:

[in] context - Library context

[in] cache - Credential cache handle

[out] cursor - Cursor

retval:
  • 0 Success; otherwise - Kerberos error codes

krb5_cc_end_seq_get() must be called to complete the retrieve operation.

Note

If the cache represented by cache is modified between the time of the call to this function and the time of the final krb5_cc_end_seq_get(), these changes may not be reflected in the results of krb5_cc_next_cred() calls.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_etype_list.html0000664000175000017500000002300615051422665027642 0ustar ghudsonghudson krb5_get_init_creds_opt_set_etype_list - Set allowable encryption types in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_error_message.html0000664000175000017500000002166015051422672024374 0ustar ghudsonghudson krb5_set_error_message - Set an extended error message for an error code. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_read_service_key.html0000664000175000017500000002523315051422670024663 0ustar ghudsonghudson krb5_kt_read_service_key - Retrieve a service key from a key table. — MIT Kerberos Documentation

krb5_kt_read_service_key - Retrieve a service key from a key table.¶

krb5_error_code krb5_kt_read_service_key(krb5_context context, krb5_pointer keyprocarg, krb5_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keyblock **key)¶
param:

[in] context - Library context

[in] keyprocarg - Name of a key table (NULL to use default name)

[in] principal - Service principal

[in] vno - Key version number (0 for highest available)

[in] enctype - Encryption type (0 for any type)

[out] key - Service key from key table

retval:
  • 0 Success

return:
  • Kerberos error code if not found or keyprocarg is invalid.

Open and search the specified key table for the entry identified by principal , enctype , and vno . If no key is found, return an error code.

The default key table is used, unless keyprocarg is non-null. keyprocarg designates a specific key table.

Use krb5_free_keyblock() to free key when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_padding_length.html0000664000175000017500000002251415051422661024132 0ustar ghudsonghudson krb5_c_padding_length - Return a number of padding octets. — MIT Kerberos Documentation

krb5_c_padding_length - Return a number of padding octets.¶

krb5_error_code krb5_c_padding_length(krb5_context context, krb5_enctype enctype, size_t data_length, unsigned int *size)¶
param:

[in] context - Library context

[in] enctype - Encryption type

[in] data_length - Length of the plaintext to pad

[out] size - Number of padding octets

retval:
  • 0 Success; otherwise - KRB5_BAD_ENCTYPE

This function returns the number of the padding octets required to pad data_length octets of plaintext.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_forwardable.html0000664000175000017500000002176615051422666027765 0ustar ghudsonghudson krb5_get_init_creds_opt_set_forwardable - Set or unset the forwardable flag in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_creds.html0000664000175000017500000002047415051422664022770 0ustar ghudsonghudson krb5_free_creds - Free a krb5_creds structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_authdata.html0000664000175000017500000002315515051422663023512 0ustar ghudsonghudson krb5_copy_authdata - Copy an authorization data list. — MIT Kerberos Documentation

krb5_copy_authdata - Copy an authorization data list.¶

krb5_error_code krb5_copy_authdata(krb5_context context, krb5_authdata *const *in_authdat, krb5_authdata ***out)¶
param:

[in] context - Library context

[in] in_authdat - List of krb5_authdata structures

[out] out - New array of krb5_authdata structures

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new authorization data list containing a copy of in_authdat , which must be null-terminated. Use krb5_free_authdata() to free out when it is no longer needed.

Note

The last array entry in in_authdat must be a NULL pointer.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kdc_sign_ticket.html0000664000175000017500000002741715051422667024022 0ustar ghudsonghudson krb5_kdc_sign_ticket - Sign a PAC, possibly including a ticket signature. — MIT Kerberos Documentation

krb5_kdc_sign_ticket - Sign a PAC, possibly including a ticket signature.¶

krb5_error_code krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt, const krb5_pac pac, krb5_const_principal server_princ, krb5_const_principal client_princ, const krb5_keyblock *server, const krb5_keyblock *privsvr, krb5_boolean with_realm)¶
param:

[in] context - Library context

[in] enc_tkt - The ticket for the signature

[in] pac - PAC handle

[in] server_princ - Canonical ticket server name

[in] client_princ - PAC_CLIENT_INFO principal (or NULL)

[in] server - Key for server checksum

[in] privsvr - Key for KDC and ticket checksum

[in] with_realm - If true, include the realm of principal

retval:
  • 0 on success, otherwise - Kerberos error codes

Sign pac using the keys server and privsvr . Include a ticket signature over enc_tkt if server_princ is not a TGS or kadmin/changepw principal name. Add the signed PAC’s encoding to the authorization data of enc_tkt in the first slot, wrapped in an AD-IF-RELEVANT container. If client_princ is non-null, add a PAC_CLIENT_INFO buffer, including the realm if with_realm is true.

Note

New in 1.20

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_in_tkt_with_skey.html0000664000175000017500000002475015051422665025106 0ustar ghudsonghudson krb5_get_in_tkt_with_skey — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_server_rcache.html0000664000175000017500000002342115051422666024336 0ustar ghudsonghudson krb5_get_server_rcache - Generate a replay cache object for server use and open it. — MIT Kerberos Documentation

krb5_get_server_rcache - Generate a replay cache object for server use and open it.¶

krb5_error_code krb5_get_server_rcache(krb5_context context, const krb5_data *piece, krb5_rcache *rcptr)¶
param:

[in] context - Library context

[in] piece - Unused (replay cache identifier)

[out] rcptr - Handle to an open rcache

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a handle to the default replay cache. Use krb5_rc_close() to close rcptr when it is no longer needed.

Note

Prior to release 1.18, this function creates a handle to a different replay cache for each unique value of piece .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_encode_authdata_container.html0000664000175000017500000002403515051422664026036 0ustar ghudsonghudson krb5_encode_authdata_container - Wrap authorization data in a container. — MIT Kerberos Documentation

krb5_encode_authdata_container - Wrap authorization data in a container.¶

krb5_error_code krb5_encode_authdata_container(krb5_context context, krb5_authdatatype type, krb5_authdata *const *authdata, krb5_authdata ***container)¶
param:

[in] context - Library context

[in] type - Container type (see KRB5_AUTHDATA macros)

[in] authdata - List of authorization data to be encoded

[out] container - List of encoded authorization data

retval:
  • 0 Success; otherwise - Kerberos error codes

The result is returned in container as a single-element list.

See also

krb5_decode_authdata_container()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_default_tgs_enctypes.html0000664000175000017500000002321015051422672025743 0ustar ghudsonghudson krb5_set_default_tgs_enctypes - Set default TGS encryption types in a krb5_context structure. — MIT Kerberos Documentation

krb5_set_default_tgs_enctypes - Set default TGS encryption types in a krb5_context structure.¶

krb5_error_code krb5_set_default_tgs_enctypes(krb5_context context, const krb5_enctype *etypes)¶
param:

[in] context - Library context

[in] etypes - Encryption type(s) to set

retval:
  • 0 Success

  • KRB5_PROG_ETYPE_NOSUPP Program lacks support for encryption type

return:
  • Kerberos error codes

This function sets the default enctype list for TGS requests made using context to etypes .

Note

This overrides the default list (from config file or built-in).

krb5-1.22.1/doc/html/appdev/refs/api/krb5_unmarshal_credentials.html0000664000175000017500000002271715051422673025240 0ustar ghudsonghudson krb5_unmarshal_credentials - Deserialize a krb5_creds object. — MIT Kerberos Documentation

krb5_unmarshal_credentials - Deserialize a krb5_creds object.¶

krb5_error_code krb5_unmarshal_credentials(krb5_context context, const krb5_data *data, krb5_creds **creds_out)¶
param:

[in] context - Library context

[in] data - The serialized credentials

[out] creds_out - The resulting creds object

retval:
  • 0 Success; otherwise - Kerberos error codes

Deserialize data to credentials in the format used by the FILE ccache format (vesion 4) and KCM ccache protocol.

Use krb5_free_creds() to free creds_out when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_parse.html0000664000175000017500000002214015051422671022612 0ustar ghudsonghudson krb5_pac_parse - Unparse an encoded PAC into a new handle. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_remove_entry.html0000664000175000017500000002237415051422670024101 0ustar ghudsonghudson krb5_kt_remove_entry - Remove an entry from a key table. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_is_referral_realm.html0000664000175000017500000002100715051422667024340 0ustar ghudsonghudson krb5_is_referral_realm - Check for a match with KRB5_REFERRAL_REALM. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_keytab_entry_contents.html0000664000175000017500000002203615051422665026302 0ustar ghudsonghudson krb5_free_keytab_entry_contents - Free the contents of a key table entry. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_setaddrs.html0000664000175000017500000002375515051422660024361 0ustar ghudsonghudson krb5_auth_con_setaddrs - Set the local and remote addresses in an auth context. — MIT Kerberos Documentation

krb5_auth_con_setaddrs - Set the local and remote addresses in an auth context.¶

krb5_error_code krb5_auth_con_setaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address *local_addr, krb5_address *remote_addr)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] local_addr - Local address

[in] remote_addr - Remote address

retval:
  • 0 Success; otherwise - Kerberos error codes

This function releases the storage assigned to the contents of the local and remote addresses of auth_context and then sets them to local_addr and remote_addr respectively.

See also

krb5_auth_con_genaddrs()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_make_checksum.html0000664000175000017500000002627515051422661023772 0ustar ghudsonghudson krb5_c_make_checksum - Compute a checksum (operates on keyblock). — MIT Kerberos Documentation

krb5_c_make_checksum - Compute a checksum (operates on keyblock).¶

krb5_error_code krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *input, krb5_checksum *cksum)¶
param:

[in] context - Library context

[in] cksumtype - Checksum type (0 for mandatory type)

[in] key - Encryption key for a keyed checksum

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[in] input - Input data

[out] cksum - Generated checksum

retval:
  • 0 Success; otherwise - Kerberos error codes

This function computes a checksum of type cksumtype over input , using key if the checksum type is a keyed checksum. If cksumtype is 0 and key is non-null, the checksum type will be the mandatory-to-implement checksum type for the key’s encryption type. The actual checksum key will be derived from key and usage if key derivation is specified for the checksum type. The newly created cksum must be released by calling krb5_free_checksum_contents() when it is no longer needed.

See also

krb5_c_verify_checksum()

Note

This function is similar to krb5_k_make_checksum(), but operates on keyblock key .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_random_key.html0000664000175000017500000002114315051422671023007 0ustar ghudsonghudson krb5_random_key — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_next_cred.html0000664000175000017500000002326015051422662023301 0ustar ghudsonghudson krb5_cc_next_cred - Retrieve the next entry from the credential cache. — MIT Kerberos Documentation

krb5_cc_next_cred - Retrieve the next entry from the credential cache.¶

krb5_error_code krb5_cc_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, krb5_creds *creds)¶
param:

[in] context - Library context

[in] cache - Credential cache handle

[in] cursor - Cursor

[out] creds - Next credential cache entry

retval:
  • 0 Success; otherwise - Kerberos error codes

This function fills in creds with the next entry in cache and advances cursor .

Use krb5_free_cred_contents() to free creds when it is no longer needed.

See also

krb5_cc_start_seq_get(), krb5_end_seq_get()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_keyblock.html0000664000175000017500000002251715051422663023523 0ustar ghudsonghudson krb5_copy_keyblock - Copy a keyblock. — MIT Kerberos Documentation

krb5_copy_keyblock - Copy a keyblock.¶

krb5_error_code krb5_copy_keyblock(krb5_context context, const krb5_keyblock *from, krb5_keyblock **to)¶
param:

[in] context - Library context

[in] from - Keyblock to be copied

[out] to - Copy of keyblock from

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new keyblock with the same contents as from . Use krb5_free_keyblock() to free to when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_free.html0000664000175000017500000002021015051422671022415 0ustar ghudsonghudson krb5_pac_free - Free a PAC handle. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_string_to_cksumtype.html0000664000175000017500000002134415051422673025000 0ustar ghudsonghudson krb5_string_to_cksumtype - Convert a string to a checksum type. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_string_to_salttype.html0000664000175000017500000002125515051422673024622 0ustar ghudsonghudson krb5_string_to_salttype - Convert a string to a salt type. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_verify_init_creds_opt_init.html0000664000175000017500000002112115051422673026271 0ustar ghudsonghudson krb5_verify_init_creds_opt_init - Initialize a credential verification options structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_credentials.html0000664000175000017500000002630215051422665024020 0ustar ghudsonghudson krb5_get_credentials - Get an additional ticket. — MIT Kerberos Documentation

krb5_get_credentials - Get an additional ticket.¶

krb5_error_code krb5_get_credentials(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **out_creds)¶
param:

[in] context - Library context

[in] options - Options

[in] ccache - Credential cache handle

[in] in_creds - Input credentials

[out] out_creds - Output updated credentials

retval:
  • 0 Success

return:
  • Kerberos error codes

Use ccache or a TGS exchange to get a service ticket matching in_creds .

Valid values for options are:

  • KRB5_GC_CACHED Search only credential cache for the ticket

  • KRB5_GC_USER_USER Return a user to user authentication ticket

in_creds must be non-null. in_creds->client and in_creds->server must be filled in to specify the client and the server respectively. If any authorization data needs to be requested for the service ticket (such as restrictions on how the ticket can be used), specify it in in_creds->authdata ; otherwise set in_creds->authdata to NULL. The session key type is specified in in_creds->keyblock.enctype , if it is nonzero.

If in_creds->times.endtime is specified, it is used as the requested expiration date if a TGS request is made. If in_creds->times.endtime is set to 0, the latest possible expiration date will be requested. The KDC or cache may return a ticket with an earlier expiration date.

Any returned ticket and intermediate ticket-granting tickets are stored in ccache .

Use krb5_free_creds() to free out_creds when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_in_ccache.html0000664000175000017500000002400515051422666027356 0ustar ghudsonghudson krb5_get_init_creds_opt_set_in_ccache - Set an input credential cache in initial credential options. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_in_ccache - Set an input credential cache in initial credential options.¶

krb5_error_code krb5_get_init_creds_opt_set_in_ccache(krb5_context context, krb5_get_init_creds_opt *opt, krb5_ccache ccache)¶
param:

[in] context - Library context

[in] opt - Options

[in] ccache - Credential cache handle

If an input credential cache is set, then the krb5_get_init_creds family of APIs will read settings from it. Setting an input ccache is desirable when the application wishes to perform authentication in the same way (using the same preauthentication mechanisms, and making the same non-security- sensitive choices) as the previous authentication attempt, which stored information in the passed-in ccache.

Note

New in 1.11

krb5-1.22.1/doc/html/appdev/refs/api/krb5_verify_init_creds_opt_set_ap_req_nofail.html0000664000175000017500000002266115051422674031013 0ustar ghudsonghudson krb5_verify_init_creds_opt_set_ap_req_nofail - Set whether credential verification is required. — MIT Kerberos Documentation

krb5_verify_init_creds_opt_set_ap_req_nofail - Set whether credential verification is required.¶

void krb5_verify_init_creds_opt_set_ap_req_nofail(krb5_verify_init_creds_opt *k5_vic_options, int ap_req_nofail)¶
param:

[in] k5_vic_options - Verification options structure

[in] ap_req_nofail - Whether to require successful verification

This function determines how krb5_verify_init_creds() behaves if no keytab information is available. If ap_req_nofail is FALSE , verification will be skipped in this case and krb5_verify_init_creds() will return successfully. If ap_req_nofail is TRUE , krb5_verify_init_creds() will not return successfully unless verification can be performed.

If this function is not used, the behavior of krb5_verify_init_creds() is determined through configuration.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_chpw_message.html0000664000175000017500000002367015051422663023334 0ustar ghudsonghudson krb5_chpw_message - Get a result message for changing or setting a password. — MIT Kerberos Documentation

krb5_chpw_message - Get a result message for changing or setting a password.¶

krb5_error_code krb5_chpw_message(krb5_context context, const krb5_data *server_string, char **message_out)¶
param:

[in] context - Library context

[in] server_string - Data returned from the remote system

[out] message_out - A message displayable to the user

retval:
  • 0 Success

return:
  • Kerberos error codes

This function processes the server_string returned in the result_string parameter of krb5_change_password(), krb5_set_password(), and related functions, and returns a displayable string. If server_string contains Active Directory structured policy information, it will be converted into human-readable text.

Use krb5_free_string() to free message_out when it is no longer needed.

Note

New in 1.11

krb5-1.22.1/doc/html/appdev/refs/api/krb5_mk_priv.html0000664000175000017500000002622615051422670022334 0ustar ghudsonghudson krb5_mk_priv - Format a KRB-PRIV message. — MIT Kerberos Documentation

krb5_mk_priv - Format a KRB-PRIV message.¶

krb5_error_code krb5_mk_priv(krb5_context context, krb5_auth_context auth_context, const krb5_data *userdata, krb5_data *der_out, krb5_replay_data *rdata_out)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] userdata - User data for KRB-PRIV message

[out] der_out - Formatted KRB-PRIV message

[out] rdata_out - Replay data (NULL if not needed)

retval:
  • 0 Success; otherwise - Kerberos error codes

This function is similar to krb5_mk_safe(), but the message is encrypted and integrity-protected, not just integrity-protected.

The local address in auth_context must be set, and is used to form the sender address used in the KRB-PRIV message. The remote address is optional; if specified, it will be used to form the receiver address used in the message.

If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in auth_context , a timestamp is included in the KRB-PRIV message, and an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If KRB5_AUTH_CONTEXT_RET_TIME is set in auth_context , a timestamp is included in the KRB-PRIV message and is stored in rdata_out .

If either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the auth_context local sequence number is included in the KRB-PRIV message and then incremented. If KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in rdata_out .

Use krb5_free_data_contents() to free der_out when it is no longer needed.

Note

The rdata_out argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in auth_context .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_string.html0000664000175000017500000002051215051422665023170 0ustar ghudsonghudson krb5_free_string - Free a string allocated by a krb5 function. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_trace_filename.html0000664000175000017500000002234515051422673024477 0ustar ghudsonghudson krb5_set_trace_filename - Specify a file name for directing trace events. — MIT Kerberos Documentation

krb5_set_trace_filename - Specify a file name for directing trace events.¶

krb5_error_code krb5_set_trace_filename(krb5_context context, const char *filename)¶
param:

[in] context - Library context

[in] filename - File name

retval:
  • KRB5_TRACE_NOSUPP Tracing is not supported in the library.

Open filename for appending (creating it, if necessary) and set up a callback to write trace events to it.

Note

This function overrides the information passed through the KRB5_TRACE environment variable.

Note

New in 1.9

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_create_key.html0000664000175000017500000002257215051422667023320 0ustar ghudsonghudson krb5_k_create_key - Create a krb5_key from the enctype and key data in a keyblock. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_anonymous_principal.html0000664000175000017500000002026115051422657024754 0ustar ghudsonghudson krb5_anonymous_principal - Build an anonymous principal. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_rd_rep.html0000664000175000017500000002326415051422672022141 0ustar ghudsonghudson krb5_rd_rep - Parse and decrypt a KRB_AP_REP message. — MIT Kerberos Documentation

krb5_rd_rep - Parse and decrypt a KRB_AP_REP message.¶

krb5_error_code krb5_rd_rep(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_ap_rep_enc_part **repl)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] inbuf - AP-REP message

[out] repl - Decrypted reply message

retval:
  • 0 Success; otherwise - Kerberos error codes

This function parses, decrypts and verifies a message from inbuf and fills in repl with a pointer to allocated memory containing the fields from the encrypted response.

Use krb5_free_ap_rep_enc_part() to free repl when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_principal.html0000664000175000017500000002071515051422665023650 0ustar ghudsonghudson krb5_free_principal - Free the storage assigned to a principal. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_decrypt.html0000664000175000017500000002644715051422661022646 0ustar ghudsonghudson krb5_c_decrypt - Decrypt data using a key (operates on keyblock). — MIT Kerberos Documentation

krb5_c_decrypt - Decrypt data using a key (operates on keyblock).¶

krb5_error_code krb5_c_decrypt(krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_enc_data *input, krb5_data *output)¶
param:

[in] context - Library context

[in] key - Encryption key

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[inout] cipher_state - Cipher state; specify NULL if not needed

[in] input - Encrypted data

[out] output - Decrypted data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function decrypts the data block input and stores the output into output . The actual decryption key will be derived from key and usage if key derivation is specified for the encryption type. If non-null, cipher_state specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation.

Note

The caller must initialize output and allocate at least enough space for the result. The usual practice is to allocate an output buffer as long as the ciphertext, and let krb5_c_decrypt() trim output->length . For some enctypes, the resulting output->length may include padding bytes.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_keylengths.html0000664000175000017500000002254415051422661023343 0ustar ghudsonghudson krb5_c_keylengths - Return length of the specified key in bytes. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_address_search.html0000664000175000017500000002327315051422657023643 0ustar ghudsonghudson krb5_address_search - Search a list of addresses for a specified address. — MIT Kerberos Documentation

krb5_address_search - Search a list of addresses for a specified address.¶

param:

[in] context - Library context

[in] addr - Address to search for

[in] addrlist - Address list to be searched (or NULL)

return:
  • TRUE if addr is listed in addrlist , or addrlist is NULL; FALSE otherwise

Note

If addrlist contains only a NetBIOS addresses, it will be treated as a null list.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_tkt_life.html0000664000175000017500000002163415051422666027270 0ustar ghudsonghudson krb5_get_init_creds_opt_set_tkt_life - Set the ticket lifetime in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_set_keytab.html0000664000175000017500000002265715051422667025234 0ustar ghudsonghudson krb5_init_creds_set_keytab - Specify a keytab to use for acquiring initial credentials. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_is_keyed_cksum.html0000664000175000017500000002110015051422661024147 0ustar ghudsonghudson krb5_c_is_keyed_cksum - Test whether a checksum type is keyed. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_anonymous_realm.html0000664000175000017500000002051115051422657024071 0ustar ghudsonghudson krb5_anonymous_realm - Return an anonymous realm data. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_prompter_posix.html0000664000175000017500000002451515051422671023757 0ustar ghudsonghudson krb5_prompter_posix - Prompt user for password. — MIT Kerberos Documentation

krb5_prompter_posix - Prompt user for password.¶

krb5_error_code krb5_prompter_posix(krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts)¶
param:

[in] context - Library context

data - Unused (callback argument)

[in] name - Name to output during prompt

[in] banner - Banner to output during prompt

[in] num_prompts - Number of prompts in prompts

[in] prompts - Array of prompts and replies

retval:
  • 0 Success

return:
  • Kerberos error codes

This function is intended to be used as a prompter callback for krb5_get_init_creds_password() or krb5_init_creds_init().

Writes name and banner to stdout, each followed by a newline, then writes each prompt field in the prompts array, followed byâ€:â€, and sets the reply field of the entry to a line of input read from stdin. If the hidden flag is set for a prompt, then terminal echoing is turned off when input is read.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_authenticator.html0000664000175000017500000002113315051422664024533 0ustar ghudsonghudson krb5_free_authenticator - Free a krb5_authenticator structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_tkt_creds_get.html0000664000175000017500000002223215051422673023502 0ustar ghudsonghudson krb5_tkt_creds_get - Synchronously obtain credentials using a TGS request context. — MIT Kerberos Documentation

krb5_tkt_creds_get - Synchronously obtain credentials using a TGS request context.¶

krb5_error_code krb5_tkt_creds_get(krb5_context context, krb5_tkt_creds_context ctx)¶
param:

[in] context - Library context

[in] ctx - TGS request context

retval:
  • 0 Success; otherwise - Kerberos error codes

This function synchronously obtains credentials using a context created by krb5_tkt_creds_init(). On successful return, the credentials can be retrieved with krb5_tkt_creds_get_creds().

Note

New in 1.9

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getaddrs.html0000664000175000017500000002347015051422657024345 0ustar ghudsonghudson krb5_auth_con_getaddrs - Retrieve address fields from an auth context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_decode_ticket.html0000664000175000017500000002155215051422663023452 0ustar ghudsonghudson krb5_decode_ticket - Decode an ASN.1-formatted ticket. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_unparse_name_ext.html0000664000175000017500000002444215051422673024223 0ustar ghudsonghudson krb5_unparse_name_ext - Convert krb5_principal structure to string and length. — MIT Kerberos Documentation

krb5_unparse_name_ext - Convert krb5_principal structure to string and length.¶

krb5_error_code krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, char **name, unsigned int *size)¶
param:

[in] context - Library context

[in] principal - Principal

[inout] name - String representation of principal name

[inout] size - Size of unparsed name

retval:
  • 0 Success

return:
  • Kerberos error codes. On failure name is set to NULL

This function is similar to krb5_unparse_name(), but allows the use of an existing buffer for the result. If size is not NULL, then name must point to either NULL or an existing buffer of at least the size pointed to by size . The buffer will be allocated or resized if necessary, with the new pointer stored into name . Whether or not the buffer is resized, the necessary space for the result, including null terminator, will be stored into size .

If size is NULL, this function behaves exactly as krb5_unparse_name().

krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_get_types.html0000664000175000017500000002254615051422671023515 0ustar ghudsonghudson krb5_pac_get_types - Return an array of buffer types in a PAC handle. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_add_entry.html0000664000175000017500000002225115051422667023334 0ustar ghudsonghudson krb5_kt_add_entry - Add a new entry to a key table. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_host_realm.html0000664000175000017500000002173015051422665024022 0ustar ghudsonghudson krb5_free_host_realm - Free the memory allocated by krb5_get_host_realm(). — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_verify_checksum.html0000664000175000017500000002646015051422661024355 0ustar ghudsonghudson krb5_c_verify_checksum - Verify a checksum (operates on keyblock). — MIT Kerberos Documentation

krb5_c_verify_checksum - Verify a checksum (operates on keyblock).¶

krb5_error_code krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *data, const krb5_checksum *cksum, krb5_boolean *valid)¶
param:

[in] context - Library context

[in] key - Encryption key for a keyed checksum

[in] usage - key usage

[in] data - Data to be used to compute a new checksum using key to compare cksum against

[in] cksum - Checksum to be verified

[out] valid - Non-zero for success, zero for failure

retval:
  • 0 Success; otherwise - Kerberos error codes

This function verifies that cksum is a valid checksum for data . If the checksum type of cksum is a keyed checksum, key is used to verify the checksum. If the checksum type in cksum is 0 and key is not NULL, the mandatory checksum type for key will be used. The actual checksum key will be derived from key and usage if key derivation is specified for the checksum type.

Note

This function is similar to krb5_k_verify_checksum(), but operates on keyblock key .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_encrypt.html0000664000175000017500000002150215051422664022344 0ustar ghudsonghudson krb5_encrypt — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_get_error.html0000664000175000017500000002306715051422667025066 0ustar ghudsonghudson krb5_init_creds_get_error - Get the last error from KDC from an initial credentials context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_get_type.html0000664000175000017500000002127215051422662023147 0ustar ghudsonghudson krb5_cc_get_type - Retrieve the type of a credential cache. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_default_name.html0000664000175000017500000002162115051422670024001 0ustar ghudsonghudson krb5_kt_default_name - Get the default key table name. — MIT Kerberos Documentation

krb5_kt_default_name - Get the default key table name.¶

krb5_error_code krb5_kt_default_name(krb5_context context, char *name, int name_size)¶
param:

[in] context - Library context

[out] name - Default key table name

[in] name_size - Space available in name

retval:
  • 0 Success

  • KRB5_CONFIG_NOTENUFSPACE Buffer is too short

return:
  • Kerberos error codes

Fill name with the name of the default key table for context .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_vprepend_error_message.html0000664000175000017500000002276015051422674025430 0ustar ghudsonghudson krb5_vprepend_error_message - Add a prefix to the message for an error code using a va_list. — MIT Kerberos Documentation

krb5_vprepend_error_message - Add a prefix to the message for an error code using a va_list.¶

void krb5_vprepend_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, va_list args)¶
param:

[in] ctx - Library context

[in] code - Error code

[in] fmt - Format string for error message prefix

[in] args - List of vprintf(3) style arguments

This function is similar to krb5_prepend_error_message(), but uses a va_list instead of variadic arguments.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_responder_otp_challenge_free.html0000664000175000017500000002257715051422672026562 0ustar ghudsonghudson krb5_responder_otp_challenge_free - Free the value returned by krb5_responder_otp_get_challenge(). — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_prepend_error_message.html0000664000175000017500000002210615051422671025231 0ustar ghudsonghudson krb5_prepend_error_message - Add a prefix to the message for an error code. — MIT Kerberos Documentation

krb5_prepend_error_message - Add a prefix to the message for an error code.¶

void krb5_prepend_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, ...)¶
param:

[in] ctx - Library context

[in] code - Error code

[in] fmt - Format string for error message prefix

Format a message and prepend it to the current message for code . The prefix will be separated from the old message with a colon and space.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_setsendsubkey.html0000664000175000017500000002266315051422660025435 0ustar ghudsonghudson krb5_auth_con_setsendsubkey - Set the send subkey in an auth context with a keyblock. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_build_principal.html0000664000175000017500000002422315051422660024017 0ustar ghudsonghudson krb5_build_principal - Build a principal name using null-terminated strings. — MIT Kerberos Documentation

krb5_build_principal - Build a principal name using null-terminated strings.¶

krb5_error_code krb5_build_principal(krb5_context context, krb5_principal *princ, unsigned int rlen, const char *realm, ...)¶
param:

[in] context - Library context

[out] princ - Principal name

[in] rlen - Realm name length

[in] realm - Realm name

retval:
  • 0 Success

return:
  • Kerberos error codes

Call krb5_free_principal() to free princ when it is no longer needed.

Beginning with release 1.20, the name type of the principal will be inferred as KRB5_NT_SRV_INST or KRB5_NT_WELLKNOWN based on the principal name. The type will be KRB5_NT_PRINCIPAL if a type cannot be inferred.

Note

krb5_build_principal() and krb5_build_principal_alloc_va() perform the same task. krb5_build_principal() takes variadic arguments. krb5_build_principal_alloc_va() takes a pre-computed varargs pointer.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_error.html0000664000175000017500000002113715051422664023016 0ustar ghudsonghudson krb5_free_error - Free an error allocated by krb5_read_error() or krb5_sendauth(). — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_retrieve_cred.html0000664000175000017500000002613615051422662024155 0ustar ghudsonghudson krb5_cc_retrieve_cred - Retrieve a specified credentials from a credential cache. — MIT Kerberos Documentation

krb5_cc_retrieve_cred - Retrieve a specified credentials from a credential cache.¶

krb5_error_code krb5_cc_retrieve_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *mcreds, krb5_creds *creds)¶
param:

[in] context - Library context

[in] cache - Credential cache handle

[in] flags - Flags bit mask

[in] mcreds - Credentials to match

[out] creds - Credentials matching the requested value

retval:
  • 0 Success; otherwise - Kerberos error codes

This function searches a credential cache for credentials matching mcreds and returns it if found.

Valid values for flags are:

  • KRB5_TC_MATCH_TIMES The requested lifetime must be at least as great as in mcreds .

  • KRB5_TC_MATCH_IS_SKEY The is_skey field much match exactly.

  • KRB5_TC_MATCH_FLAGS Flags set in mcreds must be set.

  • KRB5_TC_MATCH_TIMES_EXACT The requested lifetime must match exactly.

  • KRB5_TC_MATCH_FLAGS_EXACT Flags must match exactly.

  • KRB5_TC_MATCH_AUTHDATA The authorization data must match.

  • KRB5_TC_MATCH_SRV_NAMEONLY Only the name portion of the principal name must match, not the realm.

  • KRB5_TC_MATCH_2ND_TKT The second tickets must match.

  • KRB5_TC_MATCH_KTYPE The encryption key types must match.

  • KRB5_TC_SUPPORTED_KTYPES Check all matching entries that have any supported encryption type and return the one with the encryption type listed earliest.

Use krb5_free_cred_contents() to free creds when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_principal_compare_any_realm.html0000664000175000017500000002255115051422671026401 0ustar ghudsonghudson krb5_principal_compare_any_realm - Compare two principals ignoring realm components. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_string_to_deltat.html0000664000175000017500000002132515051422673024230 0ustar ghudsonghudson krb5_string_to_deltat - Convert a string to a delta time value. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_vset_error_message.html0000664000175000017500000002245715051422674024571 0ustar ghudsonghudson krb5_vset_error_message - Set an extended error message for an error code using a va_list. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_read_password.html0000664000175000017500000002474215051422672023525 0ustar ghudsonghudson krb5_read_password - Read a password from keyboard input. — MIT Kerberos Documentation

krb5_read_password - Read a password from keyboard input.¶

krb5_error_code krb5_read_password(krb5_context context, const char *prompt, const char *prompt2, char *return_pwd, unsigned int *size_return)¶
param:

[in] context - Library context

[in] prompt - First user prompt when reading password

[in] prompt2 - Second user prompt (NULL to prompt only once)

[out] return_pwd - Returned password

[inout] size_return - On input, maximum size of password; on output, size of password read

retval:
  • 0 Success

return:
  • Error in reading or verifying the password

  • Kerberos error codes

This function reads a password from keyboard input and stores it in return_pwd . size_return should be set by the caller to the amount of storage space available in return_pwd ; on successful return, it will be set to the length of the password read.

prompt is printed to the terminal, followed byâ€:â€, and then a password is read from the keyboard.

If prompt2 is NULL, the password is read only once. Otherwise, prompt2 is printed to the terminal and a second password is read. If the two passwords entered are not identical, KRB5_LIBOS_BADPWDMATCH is returned.

Echoing is turned off when the password is read.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_responder_list_questions.html0000664000175000017500000002276715051422672026043 0ustar ghudsonghudson krb5_responder_list_questions - List the question names contained in the responder context. — MIT Kerberos Documentation

krb5_responder_list_questions - List the question names contained in the responder context.¶

const char *const *krb5_responder_list_questions(krb5_context ctx, krb5_responder_context rctx)¶
param:

[in] ctx - Library context

[in] rctx - Responder context

Return a pointer to a null-terminated list of question names which are present in rctx . The pointer is an alias, valid only as long as the lifetime of rctx , and should not be modified or freed by the caller. A question’s challenge can be retrieved using krb5_responder_get_challenge() and answered using krb5_responder_set_answer().

Note

New in 1.11

krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_password.html0000664000175000017500000002710115051422672023375 0ustar ghudsonghudson krb5_set_password - Set a password for a principal using specified credentials. — MIT Kerberos Documentation

krb5_set_password - Set a password for a principal using specified credentials.¶

krb5_error_code krb5_set_password(krb5_context context, krb5_creds *creds, const char *newpw, krb5_principal change_password_for, int *result_code, krb5_data *result_code_string, krb5_data *result_string)¶
param:

[in] context - Library context

[in] creds - Credentials for kadmin/changepw service

[in] newpw - New password

[in] change_password_for - Change the password for this principal

[out] result_code - Numeric error code from server

[out] result_code_string - String equivalent to result_code

[out] result_string - Data returned from the remote system

retval:
  • 0 Success and result_code is set to KRB5_KPASSWD_SUCCESS.

return:
  • Kerberos error codes.

This function uses the credentials creds to set the password newpw for the principal change_password_for . It implements the set password operation of RFC 3244, for interoperability with Microsoft Windows implementations.

The error code and strings are returned in result_code , result_code_string and result_string .

Note

If change_password_for is NULL, the change is performed on the current principal. If change_password_for is non-null, the change is performed on the principal name passed in change_password_for .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_error_message.html0000664000175000017500000002217415051422665024363 0ustar ghudsonghudson krb5_get_error_message - Get the (possibly extended) error message for a code. — MIT Kerberos Documentation

krb5_get_error_message - Get the (possibly extended) error message for a code.¶

const char *krb5_get_error_message(krb5_context ctx, krb5_error_code code)¶
param:

[in] ctx - Library context

[in] code - Error code

The behavior of krb5_get_error_message() is only defined the first time it is called after a failed call to a krb5 function using the same context, and only when the error code passed in is the same as that returned by the krb5 function.

This function never returns NULL, so its result may be used unconditionally as a C string.

The string returned by this function must be freed using krb5_free_error_message()

Note

Future versions may return the same string for the second and following calls.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_sign_ext.html0000664000175000017500000002346315051422671023331 0ustar ghudsonghudson krb5_pac_sign_ext — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_rd_error.html0000664000175000017500000002224315051422672022500 0ustar ghudsonghudson krb5_rd_error - Decode a KRB-ERROR message. — MIT Kerberos Documentation

krb5_rd_error - Decode a KRB-ERROR message.¶

krb5_error_code krb5_rd_error(krb5_context context, const krb5_data *enc_errbuf, krb5_error **dec_error)¶
param:

[in] context - Library context

[in] enc_errbuf - Encoded error message

[out] dec_error - Decoded error message

retval:
  • 0 Success; otherwise - Kerberos error codes

This function processes KRB-ERROR message enc_errbuf and returns an allocated structure dec_error containing the error message. Use krb5_free_error() to free dec_error when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_tkt_creds_free.html0000664000175000017500000002067015051422673023650 0ustar ghudsonghudson krb5_tkt_creds_free - Free a TGS request context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_pac_request.html0000664000175000017500000002363015051422666030000 0ustar ghudsonghudson krb5_get_init_creds_opt_set_pac_request - Ask the KDC to include or not include a PAC in the ticket. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_pac_request - Ask the KDC to include or not include a PAC in the ticket.¶

krb5_error_code krb5_get_init_creds_opt_set_pac_request(krb5_context context, krb5_get_init_creds_opt *opt, krb5_boolean req_pac)¶
param:

[in] context - Library context

[in] opt - Options structure

[in] req_pac - Whether to request a PAC or not

If this option is set, the AS request will include a PAC-REQUEST pa-data item explicitly asking the KDC to either include or not include a privilege attribute certificate in the ticket authorization data. By default, no request is made; typically the KDC will default to including a PAC if it supports them.

Note

New in 1.15

krb5-1.22.1/doc/html/appdev/refs/api/krb5_rd_req.html0000664000175000017500000003134415051422672022140 0ustar ghudsonghudson krb5_rd_req - Parse and decrypt a KRB_AP_REQ message. — MIT Kerberos Documentation

krb5_rd_req - Parse and decrypt a KRB_AP_REQ message.¶

krb5_error_code krb5_rd_req(krb5_context context, krb5_auth_context *auth_context, const krb5_data *inbuf, krb5_const_principal server, krb5_keytab keytab, krb5_flags *ap_req_options, krb5_ticket **ticket)¶
param:

[in] context - Library context

[inout] auth_context - Pre-existing or newly created auth context

[in] inbuf - AP-REQ message to be parsed

[in] server - Matching principal for server, or NULL to allow any principal in keytab

[in] keytab - Key table, or NULL to use the default

[out] ap_req_options - If non-null, the AP-REQ flags on output

[out] ticket - If non-null, ticket from the AP-REQ message

retval:
  • 0 Success; otherwise - Kerberos error codes

This function parses, decrypts and verifies a AP-REQ message from inbuf and stores the authenticator in auth_context .

If a keyblock was specified in auth_context using krb5_auth_con_setuseruserkey(), that key is used to decrypt the ticket in AP-REQ message and keytab is ignored. In this case, server should be specified as a complete principal name to allow for proper transited-path checking and replay cache selection.

Otherwise, the decryption key is obtained from keytab , or from the default keytab if it is NULL. In this case, server may be a complete principal name, a matching principal (see krb5_sname_match()), or NULL to match any principal name. The keys tried against the encrypted part of the ticket are determined as follows:

  • If server is a complete principal name, then its entry in keytab is tried.

  • Otherwise, if keytab is iterable, then all entries in keytab which match server are tried.

  • Otherwise, the server principal in the ticket must match server , and its entry in keytab is tried.

The client specified in the decrypted authenticator must match the client specified in the decrypted ticket.

If the remote_addr field of auth_context is set, the request must come from that address.

If a replay cache handle is provided in the auth_context , the authenticator and ticket are verified against it. If no conflict is found, the new authenticator is then stored in the replay cache of auth_context .

Various other checks are performed on the decoded data, including cross-realm policy, clockskew, and ticket validation times.

On success the authenticator, subkey, and remote sequence number of the request are stored in auth_context . If the AP_OPTS_MUTUAL_REQUIRED bit is set, the local sequence number is XORed with the remote sequence number in the request.

Use krb5_free_ticket() to free ticket when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_checksum_contents.html0000664000175000017500000002124515051422664025404 0ustar ghudsonghudson krb5_free_checksum_contents - Free the contents of a krb5_checksum structure. — MIT Kerberos Documentation

krb5_free_checksum_contents - Free the contents of a krb5_checksum structure.¶

void krb5_free_checksum_contents(krb5_context context, krb5_checksum *val)¶
param:

[in] context - Library context

[in] val - Checksum structure to free contents of

This function frees the contents of val , but not the structure itself. It sets the checksum’s data pointer to null and (beginning in release 1.19) sets its length to zero.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_unparse_name_flags.html0000664000175000017500000002432615051422673024520 0ustar ghudsonghudson krb5_unparse_name_flags - Convert krb5_principal structure to a string with flags. — MIT Kerberos Documentation

krb5_unparse_name_flags - Convert krb5_principal structure to a string with flags.¶

krb5_error_code krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal, int flags, char **name)¶
param:

[in] context - Library context

[in] principal - Principal

[in] flags - Flags

[out] name - String representation of principal name

retval:
  • 0 Success

return:
  • Kerberos error codes. On failure name is set to NULL

Similar to krb5_unparse_name(), this function converts a krb5_principal structure to a string representation.

The following flags are valid:

  • KRB5_PRINCIPAL_UNPARSE_SHORT - omit realm if it is the local realm

  • KRB5_PRINCIPAL_UNPARSE_NO_REALM - omit realm

  • KRB5_PRINCIPAL_UNPARSE_DISPLAY - do not quote special characters

Use krb5_free_unparsed_name() to free name when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_checksum.html0000664000175000017500000002244115051422663023516 0ustar ghudsonghudson krb5_copy_checksum - Copy a krb5_checksum structure. — MIT Kerberos Documentation

krb5_copy_checksum - Copy a krb5_checksum structure.¶

krb5_error_code krb5_copy_checksum(krb5_context context, const krb5_checksum *ckfrom, krb5_checksum **ckto)¶
param:

[in] context - Library context

[in] ckfrom - Checksum to be copied

[out] ckto - Copy of krb5_checksum structure

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new krb5_checksum structure with the contents of ckfrom . Use krb5_free_checksum() to free ckto when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_set_req_cksumtype.html0000664000175000017500000002263015051422660026305 0ustar ghudsonghudson krb5_auth_con_set_req_cksumtype - Set checksum type in an an auth context. — MIT Kerberos Documentation

krb5_auth_con_set_req_cksumtype - Set checksum type in an an auth context.¶

krb5_error_code krb5_auth_con_set_req_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] cksumtype - Checksum type

retval:
  • 0 Success. Otherwise - Kerberos error codes

This function sets the checksum type in auth_context to be used by krb5_mk_req() for the authenticator checksum.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_random_add_entropy.html0000664000175000017500000002120315051422661025025 0ustar ghudsonghudson krb5_c_random_add_entropy — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_close.html0000664000175000017500000002151515051422662022434 0ustar ghudsonghudson krb5_cc_close - Close a credential cache handle. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cccol_have_content.html0000664000175000017500000002161515051422663024504 0ustar ghudsonghudson krb5_cccol_have_content - Check if the credential cache collection contains any initialized caches. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_default_name.html0000664000175000017500000002245615051422662023760 0ustar ghudsonghudson krb5_cc_default_name - Return the name of the default credential cache. — MIT Kerberos Documentation

krb5_cc_default_name - Return the name of the default credential cache.¶

const char *krb5_cc_default_name(krb5_context context)¶
param:

[in] context - Library context

return:
  • Name of default credential cache for the current user.

Return a pointer to the default credential cache name for context , as determined by a prior call to krb5_cc_set_default_name(), by the KRB5CCNAME environment variable, by the default_ccache_name profile variable, or by the operating system or build-time default value. The returned value must not be modified or freed by the caller. The returned value becomes invalid when context is destroyed krb5_free_context() or if a subsequent call to krb5_cc_set_default_name() is made on context .

The default credential cache name is cached in context between calls to this function, so if the value of KRB5CCNAME changes in the process environment after the first call to this function on, that change will not be reflected in later calls with the same context. The caller can invoke krb5_cc_set_default_name() with a NULL value of name to clear the cached value and force the default name to be recomputed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_have_content.html0000664000175000017500000002150715051422670024035 0ustar ghudsonghudson krb5_kt_have_content - Check if a keytab exists and contains entries. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_get_client_info.html0000664000175000017500000002364415051422671024642 0ustar ghudsonghudson krb5_pac_get_client_info - Read client information from a PAC. — MIT Kerberos Documentation

krb5_pac_get_client_info - Read client information from a PAC.¶

krb5_error_code krb5_pac_get_client_info(krb5_context context, const krb5_pac pac, krb5_timestamp *authtime_out, char **princname_out)¶
param:

[in] context - Library context

[in] pac - PAC handle

[out] authtime_out - Authentication timestamp (NULL if not needed)

[out] princname_out - Client account name

retval:
  • 0 on success, ENOENT if no PAC_CLIENT_INFO buffer is present in pac , ERANGE if the buffer contains invalid lengths.

Read the PAC_CLIENT_INFO buffer in pac . Place the client account name as a string in princname_out . If authtime_out is not NULL, place the initial authentication timestamp in authtime_out .

Note

New in 1.18

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getauthenticator.html0000664000175000017500000002274515051422657026126 0ustar ghudsonghudson krb5_auth_con_getauthenticator - Retrieve the authenticator from an auth context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_enctype_to_string.html0000664000175000017500000002155515051422664024427 0ustar ghudsonghudson krb5_enctype_to_string - Convert an encryption type to a string. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_set_config.html0000664000175000017500000002440015051422663023444 0ustar ghudsonghudson krb5_cc_set_config - Store a configuration value in a credential cache. — MIT Kerberos Documentation

krb5_cc_set_config - Store a configuration value in a credential cache.¶

krb5_error_code krb5_cc_set_config(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *key, krb5_data *data)¶
param:

[in] context - Library context

[in] id - Credential cache handle

[in] principal - Configuration for a specific principal; if NULL, global for the whole cache

[in] key - Name of config variable

[in] data - Data to store, or NULL to remove

retval:
  • 0 Success

return:
  • Kerberos error codes

Warning

Before version 1.10 data was assumed to be always non-null.

Note

Existing configuration under the same key is over-written.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_get_type.html0000664000175000017500000002075315051422670023202 0ustar ghudsonghudson krb5_kt_get_type - Return the type of a key table. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_verify_authdata_kdc_issued.html0000664000175000017500000002500715051422673026240 0ustar ghudsonghudson krb5_verify_authdata_kdc_issued - Unwrap and verify AD-KDCIssued authorization data. — MIT Kerberos Documentation

krb5_verify_authdata_kdc_issued - Unwrap and verify AD-KDCIssued authorization data.¶

krb5_error_code krb5_verify_authdata_kdc_issued(krb5_context context, const krb5_keyblock *key, const krb5_authdata *ad_kdcissued, krb5_principal *issuer, krb5_authdata ***authdata)¶
param:

[in] context - Library context

[in] key - Session key

[in] ad_kdcissued - AD-KDCIssued authorization data to be unwrapped

[out] issuer - Name of issuing principal (or NULL)

[out] authdata - Unwrapped list of authorization data

This function unwraps an AD-KDCIssued authdatum (see RFC 4120 section 5.2.6.2) and verifies its signature against key . The issuer field of the authdatum element is returned in issuer , and the unwrapped list of authdata is returned in authdata .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_make_random_key.html0000664000175000017500000002256415051422661024315 0ustar ghudsonghudson krb5_c_make_random_key - Generate an enctype-specific random encryption key. — MIT Kerberos Documentation

krb5_c_make_random_key - Generate an enctype-specific random encryption key.¶

krb5_error_code krb5_c_make_random_key(krb5_context context, krb5_enctype enctype, krb5_keyblock *k5_random_key)¶
param:

[in] context - Library context

[in] enctype - Encryption type of the generated key

[out] k5_random_key - An allocated and initialized keyblock

retval:
  • 0 Success; otherwise - Kerberos error codes

Use krb5_free_keyblock_contents() to free k5_random_key when no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_clear_error_message.html0000664000175000017500000002077015051422663024670 0ustar ghudsonghudson krb5_clear_error_message - Clear the extended error message in a context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_set_service.html0000664000175000017500000002316315051422667025406 0ustar ghudsonghudson krb5_init_creds_set_service - Specify a service principal for acquiring initial credentials. — MIT Kerberos Documentation

krb5_init_creds_set_service - Specify a service principal for acquiring initial credentials.¶

krb5_error_code krb5_init_creds_set_service(krb5_context context, krb5_init_creds_context ctx, const char *service)¶
param:

[in] context - Library context

[in] ctx - Initial credentials context

[in] service - Service principal string

retval:
  • 0 Success; otherwise - Kerberos error codes

This function supplies a service principal string to acquire initial credentials for instead of the default krbtgt service. service is parsed as a principal name; any realm part is ignored.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_cache_match.html0000664000175000017500000002264315051422662023551 0ustar ghudsonghudson krb5_cc_cache_match - Find a credential cache with a specified client principal. — MIT Kerberos Documentation

krb5_cc_cache_match - Find a credential cache with a specified client principal.¶

krb5_error_code krb5_cc_cache_match(krb5_context context, krb5_principal client, krb5_ccache *cache_out)¶
param:

[in] context - Library context

[in] client - Client principal

[out] cache_out - Credential cache handle

retval:
  • 0 Success

  • KRB5_CC_NOTFOUND

Find a cache within the collection whose default principal is client . Use krb5_cc_close to close ccache when it is no longer needed.

Note

New in 1.10

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_make_checksum_iov.html0000664000175000017500000002523415051422667024657 0ustar ghudsonghudson krb5_k_make_checksum_iov - Fill in a checksum element in IOV array (operates on opaque key) — MIT Kerberos Documentation

krb5_k_make_checksum_iov - Fill in a checksum element in IOV array (operates on opaque key)¶

krb5_error_code krb5_k_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, krb5_crypto_iov *data, size_t num_data)¶
param:

[in] context - Library context

[in] cksumtype - Checksum type (0 for mandatory type)

[in] key - Encryption key for a keyed checksum

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[inout] data - IOV array

[in] num_data - Size of data

retval:
  • 0 Success; otherwise - Kerberos error codes

Create a checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element over KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in data . Only the KRB5_CRYPTO_TYPE_CHECKSUM region is modified.

See also

krb5_k_verify_checksum_iov()

Note

This function is similar to krb5_c_make_checksum_iov(), but operates on opaque key .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_proxiable.html0000664000175000017500000002201515051422666027446 0ustar ghudsonghudson krb5_get_init_creds_opt_set_proxiable - Set or unset the proxiable flag in initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_in_tkt_with_password.html0000664000175000017500000002464415051422665025777 0ustar ghudsonghudson krb5_get_in_tkt_with_password — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_password.html0000664000175000017500000003062715051422666025576 0ustar ghudsonghudson krb5_get_init_creds_password - Get initial credentials using a password. — MIT Kerberos Documentation

krb5_get_init_creds_password - Get initial credentials using a password.¶

krb5_error_code krb5_get_init_creds_password(krb5_context context, krb5_creds *creds, krb5_principal client, const char *password, krb5_prompter_fct prompter, void *data, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *k5_gic_options)¶
param:

[in] context - Library context

[out] creds - New credentials

[in] client - Client principal

[in] password - Password (or NULL)

[in] prompter - Prompter function

[in] data - Prompter callback data

[in] start_time - Time when ticket becomes valid (0 for now)

[in] in_tkt_service - Service name of initial credentials (or NULL)

[in] k5_gic_options - Initial credential options

retval:
  • 0 Success

  • EINVAL Invalid argument

  • KRB5_KDC_UNREACH Cannot contact any KDC for requested realm

  • KRB5_PREAUTH_FAILED Generic Pre-athentication failure

  • KRB5_LIBOS_PWDINTR Password read interrupted

  • KRB5_REALM_CANT_RESOLVE Cannot resolve network address for KDC in requested realm

  • KRB5KDC_ERR_KEY_EXP Password has expired

  • KRB5_LIBOS_BADPWDMATCH Password mismatch

  • KRB5_CHPW_PWDNULL New password cannot be zero length

  • KRB5_CHPW_FAIL Password change failed

return:
  • Kerberos error codes

This function requests KDC for an initial credentials for client using password . If password is NULL, a password will be prompted for using prompter if necessary. If in_tkt_service is specified, it is parsed as a principal name (with the realm ignored) and used as the service principal for the request; otherwise the ticket-granting service is used.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getlocalsubkey.html0000664000175000017500000002123015051422660025547 0ustar ghudsonghudson krb5_auth_con_getlocalsubkey — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_ticket.html0000664000175000017500000002042515051422665023150 0ustar ghudsonghudson krb5_free_ticket - Free a ticket. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_appdefault_boolean.html0000664000175000017500000002420715051422657024513 0ustar ghudsonghudson krb5_appdefault_boolean - Retrieve a boolean value from the appdefaults section of krb5.conf. — MIT Kerberos Documentation

krb5_appdefault_boolean - Retrieve a boolean value from the appdefaults section of krb5.conf.¶

void krb5_appdefault_boolean(krb5_context context, const char *appname, const krb5_data *realm, const char *option, int default_value, int *ret_value)¶
param:

[in] context - Library context

[in] appname - Application name

[in] realm - Realm name

[in] option - Option to be checked

[in] default_value - Default value to return if no match is found

[out] ret_value - Boolean value of option

This function gets the application defaults for option based on the given appname and/or realm .

See also

krb5_appdefault_string()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cccol_cursor_free.html0000664000175000017500000002202115051422663024335 0ustar ghudsonghudson krb5_cccol_cursor_free - Free a credential cache collection cursor. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_mk_rep_dce.html0000664000175000017500000002207615051422670022754 0ustar ghudsonghudson krb5_mk_rep_dce - Format and encrypt a KRB_AP_REP message for DCE RPC. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_default.html0000664000175000017500000002205315051422662022751 0ustar ghudsonghudson krb5_cc_default - Resolve the default credential cache name. — MIT Kerberos Documentation

krb5_cc_default - Resolve the default credential cache name.¶

krb5_error_code krb5_cc_default(krb5_context context, krb5_ccache *ccache)¶
param:

[in] context - Library context

[out] ccache - Pointer to credential cache name

retval:
  • 0 Success

  • KV5M_CONTEXT Bad magic number for _krb5_context structure

  • KRB5_FCC_INTERNAL The name of the default credential cache cannot be obtained

return:
  • Kerberos error codes

Create a handle to the default credential cache as given by krb5_cc_default_name().

krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_verify.html0000664000175000017500000002544215051422671023014 0ustar ghudsonghudson krb5_pac_verify - Verify a PAC. — MIT Kerberos Documentation

krb5_pac_verify - Verify a PAC.¶

krb5_error_code krb5_pac_verify(krb5_context context, const krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock *server, const krb5_keyblock *privsvr)¶
param:

[in] context - Library context

[in] pac - PAC handle

[in] authtime - Expected timestamp

[in] principal - Expected principal name (or NULL)

[in] server - Key to validate server checksum (or NULL)

[in] privsvr - Key to validate KDC checksum (or NULL)

retval:
  • 0 Success; otherwise - Kerberos error codes

This function validates pac against the supplied server , privsvr , principal and authtime . If principal is NULL, the principal and authtime are not verified. If server or privsvr is NULL, the corresponding checksum is not verified.

If successful, pac is marked as verified.

Note

A checksum mismatch can occur if the PAC was copied from a cross-realm TGT by an ignorant KDC; also macOS Server Open Directory (as of 10.6) generates PACs with no server checksum at all. One should consider not failing the whole authentication because of this reason, but, instead, treating the ticket as if it did not contain a PAC or marking the PAC information as non-verified.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_key_enctype.html0000664000175000017500000002074315051422667023522 0ustar ghudsonghudson krb5_k_key_enctype - Retrieve the enctype of a krb5_key structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_get_config.html0000664000175000017500000002411515051422662023432 0ustar ghudsonghudson krb5_cc_get_config - Get a configuration value from a credential cache. — MIT Kerberos Documentation

krb5_cc_get_config - Get a configuration value from a credential cache.¶

krb5_error_code krb5_cc_get_config(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *key, krb5_data *data)¶
param:

[in] context - Library context

[in] id - Credential cache handle

[in] principal - Configuration for this principal; if NULL, global for the whole cache

[in] key - Name of config variable

[out] data - Data to be fetched

retval:
  • 0 Success

return:
  • Kerberos error codes

Use krb5_free_data_contents() to free data when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_get_name.html0000664000175000017500000002175715051422662023116 0ustar ghudsonghudson krb5_cc_get_name - Retrieve the name, but not type of a credential cache. — MIT Kerberos Documentation

krb5_cc_get_name - Retrieve the name, but not type of a credential cache.¶

const char *krb5_cc_get_name(krb5_context context, krb5_ccache cache)¶
param:

[in] context - Library context

[in] cache - Credential cache handle

return:
  • On success - the name of the credential cache.

Warning

Returns the name of the credential cache. The result is an alias into cache and should not be freed or modified by the caller. This name does not include the cache type, so should not be used as input to krb5_cc_resolve().

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kdc_verify_ticket.html0000664000175000017500000002672415051422667024366 0ustar ghudsonghudson krb5_kdc_verify_ticket - Verify a PAC, possibly including ticket signature. — MIT Kerberos Documentation

krb5_kdc_verify_ticket - Verify a PAC, possibly including ticket signature.¶

krb5_error_code krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt, krb5_const_principal server_princ, const krb5_keyblock *server, const krb5_keyblock *privsvr, krb5_pac *pac_out)¶
param:

[in] context - Library context

[in] enc_tkt - Ticket enc-part, possibly containing a PAC

[in] server_princ - Canonicalized name of ticket server

[in] server - Key to validate server checksum (or NULL)

[in] privsvr - Key to validate KDC checksum (or NULL)

[out] pac_out - Verified PAC (NULL if no PAC included)

retval:
  • 0 Success; otherwise - Kerberos error codes

If a PAC is present in enc_tkt , verify its signatures. If privsvr is not NULL and server_princ is not a krbtgt or kadmin/changepw service, require a ticket signature over enc_tkt in addition to the KDC signature. Place the verified PAC in pac_out . If an invalid PAC signature is found, return an error matching the Windows KDC protocol code for that condition as closely as possible.

If no PAC is present in enc_tkt , set pac_out to NULL and return successfully.

Note

This function does not validate the PAC_CLIENT_INFO buffer. If a specific value is expected, the caller can make a separate call to krb5_pac_verify_ext() with a principal but no keys.

Note

New in 1.20

krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_context.html0000664000175000017500000002161415051422667023376 0ustar ghudsonghudson krb5_init_context - Create a krb5 library context. — MIT Kerberos Documentation

krb5_init_context - Create a krb5 library context.¶

krb5_error_code krb5_init_context(krb5_context *context)¶
param:

[out] context - Library context

retval:
  • 0 Success

return:
  • Kerberos error codes

The context must be released by calling krb5_free_context() when it is no longer needed.

Warning

Any program or module that needs the Kerberos code to not trust the environment must use krb5_init_secure_context(), or clean out the environment.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_make_checksum_iov.html0000664000175000017500000002545015051422661024641 0ustar ghudsonghudson krb5_c_make_checksum_iov - Fill in a checksum element in IOV array (operates on keyblock) — MIT Kerberos Documentation

krb5_c_make_checksum_iov - Fill in a checksum element in IOV array (operates on keyblock)¶

krb5_error_code krb5_c_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock *key, krb5_keyusage usage, krb5_crypto_iov *data, size_t num_data)¶
param:

[in] context - Library context

[in] cksumtype - Checksum type (0 for mandatory type)

[in] key - Encryption key for a keyed checksum

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[inout] data - IOV array

[in] num_data - Size of data

retval:
  • 0 Success; otherwise - Kerberos error codes

Create a checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element over KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in data . Only the KRB5_CRYPTO_TYPE_CHECKSUM region is modified.

See also

krb5_c_verify_checksum_iov()

Note

This function is similar to krb5_k_make_checksum_iov(), but operates on keyblock key .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_enctype_compare.html0000664000175000017500000002273015051422661024340 0ustar ghudsonghudson krb5_c_enctype_compare - Compare two encryption types. — MIT Kerberos Documentation

krb5_c_enctype_compare - Compare two encryption types.¶

krb5_error_code krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2, krb5_boolean *similar)¶
param:

[in] context - Library context

[in] e1 - First encryption type

[in] e2 - Second encryption type

[out] similar - TRUE if types are similar, FALSE if not

retval:
  • 0 Success; otherwise - Kerberos error codes

This function determines whether two encryption types use the same kind of keys.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_credentials_validate.html0000664000175000017500000002201615051422665025667 0ustar ghudsonghudson krb5_get_credentials_validate — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_parse_name_flags.html0000664000175000017500000002512015051422671024144 0ustar ghudsonghudson krb5_parse_name_flags - Convert a string principal name to a krb5_principal with flags. — MIT Kerberos Documentation

krb5_parse_name_flags - Convert a string principal name to a krb5_principal with flags.¶

krb5_error_code krb5_parse_name_flags(krb5_context context, const char *name, int flags, krb5_principal *principal_out)¶
param:

[in] context - Library context

[in] name - String representation of a principal name

[in] flags - Flag

[out] principal_out - New principal

retval:
  • 0 Success

return:
  • Kerberos error codes

Similar to krb5_parse_name(), this function converts a single-string representation of a principal name to a krb5_principal structure.

The following flags are valid:

  • KRB5_PRINCIPAL_PARSE_NO_REALM - no realm must be present in name

  • KRB5_PRINCIPAL_PARSE_REQUIRE_REALM - realm must be present in name

  • KRB5_PRINCIPAL_PARSE_ENTERPRISE - create single-component enterprise principal

  • KRB5_PRINCIPAL_PARSE_IGNORE_REALM - ignore realm if present in name

If KRB5_PRINCIPAL_PARSE_NO_REALM or KRB5_PRINCIPAL_PARSE_IGNORE_REALM is specified in flags , the realm of the new principal will be empty. Otherwise, the default realm for context will be used if name does not specify a realm.

Use krb5_free_principal() to free principal_out when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_host_realm.html0000664000175000017500000002310515051422665023656 0ustar ghudsonghudson krb5_get_host_realm - Get the Kerberos realm names for a host. — MIT Kerberos Documentation

krb5_get_host_realm - Get the Kerberos realm names for a host.¶

krb5_error_code krb5_get_host_realm(krb5_context context, const char *host, char ***realmsp)¶
param:

[in] context - Library context

[in] host - Host name (or NULL)

[out] realmsp - Null-terminated list of realm names

retval:
  • 0 Success

  • ENOMEM Insufficient memory

return:
  • Kerberos error codes

Fill in realmsp with a pointer to a null-terminated list of realm names. If there are no known realms for the host, a list containing the referral (empty) realm is returned.

If host is NULL, the local host’s realms are determined.

Use krb5_free_host_realm() to release realmsp when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_check_clockskew.html0000664000175000017500000002227115051422663024005 0ustar ghudsonghudson krb5_check_clockskew - Check if a timestamp is within the allowed clock skew of the current time. — MIT Kerberos Documentation

krb5_check_clockskew - Check if a timestamp is within the allowed clock skew of the current time.¶

krb5_error_code krb5_check_clockskew(krb5_context context, krb5_timestamp date)¶
param:

[in] context - Library context

[in] date - Timestamp to check

retval:
  • 0 Success

  • KRB5KRB_AP_ERR_SKEW date is not within allowable clock skew

This function checks if date is close enough to the current time according to the configured allowable clock skew.

Note

New in 1.10

krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_sign.html0000664000175000017500000002312615051422671022445 0ustar ghudsonghudson krb5_pac_sign — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_key_keyblock.html0000664000175000017500000002157515051422667023662 0ustar ghudsonghudson krb5_k_key_keyblock - Retrieve a copy of the keyblock from a krb5_key structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_prompt_types.html0000664000175000017500000002131515051422666024270 0ustar ghudsonghudson krb5_get_prompt_types - Get prompt types array from a context. — MIT Kerberos Documentation

krb5_get_prompt_types - Get prompt types array from a context.¶

krb5_prompt_type *krb5_get_prompt_types(krb5_context context)¶
param:

[in] context - Library context

return:
  • Pointer to an array of prompt types corresponding to the prompter’s prompts arguments. Each type has one of the following values: KRB5_PROMPT_TYPE_PASSWORD KRB5_PROMPT_TYPE_NEW_PASSWORD KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN KRB5_PROMPT_TYPE_PREAUTH

krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_init.html0000664000175000017500000002613015051422667024033 0ustar ghudsonghudson krb5_init_creds_init - Create a context for acquiring initial credentials. — MIT Kerberos Documentation

krb5_init_creds_init - Create a context for acquiring initial credentials.¶

krb5_error_code krb5_init_creds_init(krb5_context context, krb5_principal client, krb5_prompter_fct prompter, void *data, krb5_deltat start_time, krb5_get_init_creds_opt *options, krb5_init_creds_context *ctx)¶
param:

[in] context - Library context

[in] client - Client principal to get initial creds for

[in] prompter - Prompter callback

[in] data - Prompter callback argument

[in] start_time - Time when credentials become valid (0 for now)

[in] options - Options structure (NULL for default)

[out] ctx - New initial credentials context

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new context for acquiring initial credentials. Use krb5_init_creds_free() to free ctx when it is no longer needed.

Any subsequent calls to krb5_init_creds_step(), krb5_init_creds_get(), or krb5_init_creds_free() for this initial credentials context must use the same context argument as the one passed to this function.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_block_size.html0000664000175000017500000002165215051422661023311 0ustar ghudsonghudson krb5_c_block_size - Return cipher block size. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getflags.html0000664000175000017500000002316415051422657024344 0ustar ghudsonghudson krb5_auth_con_getflags - Retrieve flags from a krb5_auth_context structure. — MIT Kerberos Documentation

krb5_auth_con_getflags - Retrieve flags from a krb5_auth_context structure.¶

krb5_error_code krb5_auth_con_getflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 *flags)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[out] flags - Flags bit mask

retval:
  • 0 (always)

Valid values for flags are:

  • KRB5_AUTH_CONTEXT_DO_TIME Use timestamps

  • KRB5_AUTH_CONTEXT_RET_TIME Save timestamps

  • KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers

  • KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_client_default.html0000664000175000017500000002160215051422667024344 0ustar ghudsonghudson krb5_kt_client_default - Resolve the default client key table. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_resolve.html0000664000175000017500000002315315051422670023036 0ustar ghudsonghudson krb5_kt_resolve - Get a handle for a key table. — MIT Kerberos Documentation

krb5_kt_resolve - Get a handle for a key table.¶

krb5_error_code krb5_kt_resolve(krb5_context context, const char *name, krb5_keytab *ktid)¶
param:

[in] context - Library context

[in] name - Name of the key table

[out] ktid - Key table handle

retval:
  • 0 Success

return:
  • Kerberos error codes

Resolve the key table name name and set ktid to a handle identifying the key table. Use krb5_kt_close() to free ktid when it is no longer needed.

name must be of the form type:residual , where type must be a type known to the library and residual portion should be specific to the particular keytab type. If no type is given, the default is FILE .

If name is of type FILE , the keytab file is not opened by this call.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_change_password.html0000664000175000017500000002526315051422663024036 0ustar ghudsonghudson krb5_change_password - Change a password for an existing Kerberos account. — MIT Kerberos Documentation

krb5_change_password - Change a password for an existing Kerberos account.¶

krb5_error_code krb5_change_password(krb5_context context, krb5_creds *creds, const char *newpw, int *result_code, krb5_data *result_code_string, krb5_data *result_string)¶
param:

[in] context - Library context

[in] creds - Credentials for kadmin/changepw service

[in] newpw - New password

[out] result_code - Numeric error code from server

[out] result_code_string - String equivalent to result_code

[out] result_string - Change password response from the KDC

retval:
  • 0 Success; otherwise - Kerberos error codes

Change the password for the existing principal identified by creds .

The possible values of the output result_code are:

  • KRB5_KPASSWD_SUCCESS (0) - success

  • KRB5_KPASSWD_MALFORMED (1) - Malformed request error

  • KRB5_KPASSWD_HARDERROR (2) - Server error

  • KRB5_KPASSWD_AUTHERROR (3) - Authentication error

  • KRB5_KPASSWD_SOFTERROR (4) - Password change rejected

krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_free.html0000664000175000017500000002123215051422667024007 0ustar ghudsonghudson krb5_init_creds_free - Free an initial credentials context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_authenticator.html0000664000175000017500000002265315051422663024573 0ustar ghudsonghudson krb5_copy_authenticator - Copy a krb5_authenticator structure. — MIT Kerberos Documentation

krb5_copy_authenticator - Copy a krb5_authenticator structure.¶

krb5_error_code krb5_copy_authenticator(krb5_context context, const krb5_authenticator *authfrom, krb5_authenticator **authto)¶
param:

[in] context - Library context

[in] authfrom - krb5_authenticator structure to be copied

[out] authto - Copy of krb5_authenticator structure

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new krb5_authenticator structure with the content of authfrom . Use krb5_free_authenticator() to free authto when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getkey_k.html0000664000175000017500000002264115051422657024351 0ustar ghudsonghudson krb5_auth_con_getkey_k - Retrieve the session key from an auth context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_aname_to_localname.html0000664000175000017500000002352115051422657024463 0ustar ghudsonghudson krb5_aname_to_localname - Convert a principal name to a local name. — MIT Kerberos Documentation

krb5_aname_to_localname - Convert a principal name to a local name.¶

krb5_error_code krb5_aname_to_localname(krb5_context context, krb5_const_principal aname, int lnsize_in, char *lname)¶
param:

[in] context - Library context

[in] aname - Principal name

[in] lnsize_in - Space available in lname

[out] lname - Local name buffer to be filled in

retval:
  • 0 Success

  • System errors

return:
  • Kerberos error codes

If aname does not correspond to any local account, KRB5_LNAME_NOTRANS is returned. If lnsize_in is too small for the local name, KRB5_CONFIG_NOTENUFSPACE is returned.

Local names, rather than principal names, can be used by programs that translate to an environment-specific name (for example, a user account name).

krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_creds.html0000664000175000017500000002217215051422663023015 0ustar ghudsonghudson krb5_copy_creds - Copy a krb5_creds structure. — MIT Kerberos Documentation

krb5_copy_creds - Copy a krb5_creds structure.¶

krb5_error_code krb5_copy_creds(krb5_context context, const krb5_creds *incred, krb5_creds **outcred)¶
param:

[in] context - Library context

[in] incred - Credentials structure to be copied

[out] outcred - Copy of incred

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new credential with the contents of incred . Use krb5_free_creds() to free outcred when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_encrypt_length.html0000664000175000017500000002244515051422661024213 0ustar ghudsonghudson krb5_c_encrypt_length - Compute encrypted data length. — MIT Kerberos Documentation

krb5_c_encrypt_length - Compute encrypted data length.¶

krb5_error_code krb5_c_encrypt_length(krb5_context context, krb5_enctype enctype, size_t inputlen, size_t *length)¶
param:

[in] context - Library context

[in] enctype - Encryption type

[in] inputlen - Length of the data to be encrypted

[out] length - Length of the encrypted data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function computes the length of the ciphertext produced by encrypting inputlen bytes including padding, confounder, and checksum.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_password_using_ccache.html0000664000175000017500000002672715051422672026105 0ustar ghudsonghudson krb5_set_password_using_ccache - Set a password for a principal using cached credentials. — MIT Kerberos Documentation

krb5_set_password_using_ccache - Set a password for a principal using cached credentials.¶

krb5_error_code krb5_set_password_using_ccache(krb5_context context, krb5_ccache ccache, const char *newpw, krb5_principal change_password_for, int *result_code, krb5_data *result_code_string, krb5_data *result_string)¶
param:

[in] context - Library context

[in] ccache - Credential cache

[in] newpw - New password

[in] change_password_for - Change the password for this principal

[out] result_code - Numeric error code from server

[out] result_code_string - String equivalent to result_code

[out] result_string - Data returned from the remote system

retval:
  • 0 Success

return:
  • Kerberos error codes

This function uses the cached credentials from ccache to set the password newpw for the principal change_password_for . It implements RFC 3244 set password operation (interoperable with MS Windows implementations) using the credential cache.

The error code and strings are returned in result_code , result_code_string and result_string .

Note

If change_password_for is set to NULL, the change is performed on the default principal in ccache . If change_password_for is nonnull, the change is performed on the specified principal.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_set_checksum_func.html0000664000175000017500000002324715051422660026234 0ustar ghudsonghudson krb5_auth_con_set_checksum_func - Set a checksum callback in an auth context. — MIT Kerberos Documentation

krb5_auth_con_set_checksum_func - Set a checksum callback in an auth context.¶

krb5_error_code krb5_auth_con_set_checksum_func(krb5_context context, krb5_auth_context auth_context, krb5_mk_req_checksum_func func, void *data)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] func - Checksum callback

[in] data - Callback argument

retval:
  • 0 (always)

Set a callback to obtain checksum data in krb5_mk_req(). The callback will be invoked after the subkey and local sequence number are stored in auth_context .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_encrypt.html0000664000175000017500000002627215051422661022654 0ustar ghudsonghudson krb5_c_encrypt - Encrypt data using a key (operates on keyblock). — MIT Kerberos Documentation

krb5_c_encrypt - Encrypt data using a key (operates on keyblock).¶

krb5_error_code krb5_c_encrypt(krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_data *input, krb5_enc_data *output)¶
param:

[in] context - Library context

[in] key - Encryption key

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[inout] cipher_state - Cipher state; specify NULL if not needed

[in] input - Data to be encrypted

[out] output - Encrypted data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function encrypts the data block input and stores the output into output . The actual encryption key will be derived from key and usage if key derivation is specified for the encryption type. If non-null, cipher_state specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation.

Note

The caller must initialize output and allocate at least enough space for the result (using krb5_c_encrypt_length() to determine the amount of space needed). output->length will be set to the actual length of the ciphertext.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_support_switch.html0000664000175000017500000002202615051422663024423 0ustar ghudsonghudson krb5_cc_support_switch - Determine whether a credential cache type supports switching. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_preauth_list.html0000664000175000017500000002316015051422666030166 0ustar ghudsonghudson krb5_get_init_creds_opt_set_preauth_list - Set preauthentication types in initial credential options. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_preauth_list - Set preauthentication types in initial credential options.¶

void krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt, krb5_preauthtype *preauth_list, int preauth_list_length)¶
param:

[in] opt - Options structure

[in] preauth_list - Array of preauthentication types

[in] preauth_list_length - Length of preauth_list

This function can be used to perform optimistic preauthentication when getting initial credentials, in combination with krb5_get_init_creds_opt_set_salt() and krb5_get_init_creds_opt_set_pa().

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cccol_cursor_next.html0000664000175000017500000002333515051422663024403 0ustar ghudsonghudson krb5_cccol_cursor_next - Get the next credential cache in the collection. — MIT Kerberos Documentation

krb5_cccol_cursor_next - Get the next credential cache in the collection.¶

krb5_error_code krb5_cccol_cursor_next(krb5_context context, krb5_cccol_cursor cursor, krb5_ccache *ccache)¶
param:

[in] context - Library context

[in] cursor - Cursor

[out] ccache - Credential cache handle

retval:
  • 0 Success; otherwise - Kerberos error codes

Use krb5_cc_close() to close ccache when it is no longer needed.

See also

krb5_cccol_cursor_new(), krb5_cccol_cursor_free()

Note

When all caches are iterated over and the end of the list is reached, ccache is set to NULL.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_keyblock.html0000664000175000017500000002077315051422665023476 0ustar ghudsonghudson krb5_free_keyblock - Free a krb5_keyblock structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_crypto_length.html0000664000175000017500000002332215051422661024042 0ustar ghudsonghudson krb5_c_crypto_length - Return a length of a message field specific to the encryption type. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_is_thread_safe.html0000664000175000017500000002062015051422667023623 0ustar ghudsonghudson krb5_is_thread_safe - Test whether the Kerberos library was built with multithread support. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_get_times.html0000664000175000017500000002310515051422667025047 0ustar ghudsonghudson krb5_init_creds_get_times - Retrieve ticket times from an initial credentials context. — MIT Kerberos Documentation

krb5_init_creds_get_times - Retrieve ticket times from an initial credentials context.¶

krb5_error_code krb5_init_creds_get_times(krb5_context context, krb5_init_creds_context ctx, krb5_ticket_times *times)¶
param:

[in] context - Library context

[in] ctx - Initial credentials context

[out] times - Ticket times for acquired credentials

retval:
  • 0 Success; otherwise - Kerberos error codes

The initial credentials context must have completed obtaining credentials via either krb5_init_creds_get() or krb5_init_creds_step().

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getrecvsubkey_k.html0000664000175000017500000002327515051422660025741 0ustar ghudsonghudson krb5_auth_con_getrecvsubkey_k - Retrieve the receiving subkey from an auth context as a keyblock. — MIT Kerberos Documentation

krb5_auth_con_getrecvsubkey_k - Retrieve the receiving subkey from an auth context as a keyblock.¶

krb5_error_code krb5_auth_con_getrecvsubkey_k(krb5_context ctx, krb5_auth_context ac, krb5_key *key)¶
param:

[in] ctx - Library context

[in] ac - Authentication context

[out] key - Receiving subkey

retval:
  • 0 Success; otherwise - Kerberos error codes

This function sets key to the receiving subkey from auth_context . Use krb5_k_free_key() to release key when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_get_name.html0000664000175000017500000002230115051422670023130 0ustar ghudsonghudson krb5_kt_get_name - Get a key table name. — MIT Kerberos Documentation

krb5_kt_get_name - Get a key table name.¶

krb5_error_code krb5_kt_get_name(krb5_context context, krb5_keytab keytab, char *name, unsigned int namelen)¶
param:

[in] context - Library context

[in] keytab - Key table handle

[out] name - Key table name

[in] namelen - Maximum length to fill in name

retval:
  • 0 Success

  • KRB5_KT_NAME_TOOLONG Key table name does not fit in namelen bytes

return:
  • Kerberos error codes

Fill name with the name of keytab including the type and delimiter.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_error_message.html0000664000175000017500000002075215051422663024554 0ustar ghudsonghudson krb5_copy_error_message - Copy the most recent extended error message from one context to another. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_profile.html0000664000175000017500000002232315051422666023163 0ustar ghudsonghudson krb5_get_profile - Retrieve configuration profile from the context. — MIT Kerberos Documentation

krb5_get_profile - Retrieve configuration profile from the context.¶

krb5_error_code krb5_get_profile(krb5_context context, struct _profile_t **profile)¶
param:

[in] context - Library context

[out] profile - Pointer to data read from a configuration file

retval:
  • 0 Success

return:
  • Kerberos error codes

This function creates a new profile object that reflects profile in the supplied context .

The profile object may be freed with profile_release() function. See profile.h and profile API for more details.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_out_ccache.html0000664000175000017500000002344615051422666027567 0ustar ghudsonghudson krb5_get_init_creds_opt_set_out_ccache - Set an output credential cache in initial credential options. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_out_ccache - Set an output credential cache in initial credential options.¶

krb5_error_code krb5_get_init_creds_opt_set_out_ccache(krb5_context context, krb5_get_init_creds_opt *opt, krb5_ccache ccache)¶
param:

[in] context - Library context

[in] opt - Options

[in] ccache - Credential cache handle

If an output credential cache is set, then the krb5_get_init_creds family of APIs will write credentials to it. Setting an output ccache is desirable both because it simplifies calling code and because it permits the krb5_get_init_creds APIs to write out configuration information about the realm to the ccache.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_sendauth.html0000664000175000017500000003451215051422672022477 0ustar ghudsonghudson krb5_sendauth - Client function for sendauth protocol. — MIT Kerberos Documentation

krb5_sendauth - Client function for sendauth protocol.¶

krb5_error_code krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, char *appl_version, krb5_principal client, krb5_principal server, krb5_flags ap_req_options, krb5_data *in_data, krb5_creds *in_creds, krb5_ccache ccache, krb5_error **error, krb5_ap_rep_enc_part **rep_result, krb5_creds **out_creds)¶
param:

[in] context - Library context

[inout] auth_context - Pre-existing or newly created auth context

[in] fd - File descriptor that describes network socket

[in] appl_version - Application protocol version to be matched with the receiver’s application version

[in] client - Client principal

[in] server - Server principal

[in] ap_req_options - Options (see AP_OPTS macros)

[in] in_data - Data to be sent to the server

[in] in_creds - Input credentials, or NULL to use ccache

[in] ccache - Credential cache

[out] error - If non-null, contains KRB_ERROR message returned from server

[out] rep_result - If non-null and ap_req_options is AP_OPTS_MUTUAL_REQUIRED, contains the result of mutual authentication exchange

[out] out_creds - If non-null, the retrieved credentials

retval:
  • 0 Success; otherwise - Kerberos error codes

This function performs the client side of a sendauth/recvauth exchange by sending and receiving messages over fd .

Credentials may be specified in three ways:

  • If in_creds is NULL, credentials are obtained with krb5_get_credentials() using the principals client and server . server must be non-null; client may NULL to use the default principal of ccache .

  • If in_creds is non-null, but does not contain a ticket, credentials for the exchange are obtained with krb5_get_credentials() using in_creds . In this case, the values of client and server are unused.

  • If in_creds is a complete credentials structure, it used directly. In this case, the values of client , server , and ccache are unused.

If the server is using a different application protocol than that specified in appl_version , an error will be returned.

Use krb5_free_creds() to free out_creds , krb5_free_ap_rep_enc_part() to free rep_result , and krb5_free_error() to free error when they are no longer needed.

See also

krb5_recvauth()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_decrypt.html0000664000175000017500000002151015051422663022330 0ustar ghudsonghudson krb5_decrypt — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_checksum.html0000664000175000017500000002075515051422664023474 0ustar ghudsonghudson krb5_free_checksum - Free a krb5_checksum structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_encrypt_iov.html0000664000175000017500000002632215051422661023525 0ustar ghudsonghudson krb5_c_encrypt_iov - Encrypt data in place supporting AEAD (operates on keyblock). — MIT Kerberos Documentation

krb5_c_encrypt_iov - Encrypt data in place supporting AEAD (operates on keyblock).¶

krb5_error_code krb5_c_encrypt_iov(krb5_context context, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data)¶
param:

[in] context - Library context

[in] keyblock - Encryption key

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[in] cipher_state - Cipher state; specify NULL if not needed

[inout] data - IOV array. Modified in-place.

[in] num_data - Size of data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function encrypts the data block data and stores the output in-place. The actual encryption key will be derived from keyblock and usage if key derivation is specified for the encryption type. If non-null, cipher_state specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5_crypto_iov structures before calling into this API.

See also

krb5_c_decrypt_iov()

Note

On return from a krb5_c_encrypt_iov() call, the data->length in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_context_profile.html0000664000175000017500000002312015051422667025110 0ustar ghudsonghudson krb5_init_context_profile - Create a krb5 library context using a specified profile. — MIT Kerberos Documentation

krb5_init_context_profile - Create a krb5 library context using a specified profile.¶

krb5_error_code krb5_init_context_profile(struct _profile_t *profile, krb5_flags flags, krb5_context *context)¶
param:

[in] profile - Profile object (NULL to create default profile)

[in] flags - Context initialization flags

[out] context - Library context

Create a context structure, optionally using a specified profile and initialization flags. If profile is NULL, the default profile will be created from config files. If profile is non-null, a copy of it will be made for the new context; the caller should still clean up its copy. Valid flag values are:

  • KRB5_INIT_CONTEXT_SECURE Ignore environment variables

  • KRB5_INIT_CONTEXT_KDC Use KDC configuration if creating profile

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_unparsed_name.html0000664000175000017500000002041415051422665024504 0ustar ghudsonghudson krb5_free_unparsed_name - Free a string representation of a principal. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_prfplus.html0000664000175000017500000002421215051422661022653 0ustar ghudsonghudson krb5_c_prfplus - Generate pseudo-random bytes using RFC 6113 PRF+. — MIT Kerberos Documentation

krb5_c_prfplus - Generate pseudo-random bytes using RFC 6113 PRF+.¶

krb5_error_code krb5_c_prfplus(krb5_context context, const krb5_keyblock *k, const krb5_data *input, krb5_data *output)¶
param:

[in] context - Library context

[in] k - KDC contribution key

[in] input - Input data

[out] output - Pseudo-random output buffer

return:
  • 0 on success, E2BIG if output->length is too large for PRF+ to generate, ENOMEM on allocation failure, or an error code from krb5_c_prf()

This function fills output with PRF+(k, input) as defined in RFC 6113 section 5.1. The caller must preinitialize output and allocate the desired amount of space. The length of the pseudo-random output will match the length of output .

Note

RFC 4402 defines a different PRF+ operation. This function does not implement that operation.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_free_state.html0000664000175000017500000002252015051422661023301 0ustar ghudsonghudson krb5_c_free_state - Free a cipher state previously allocated by krb5_c_init_state(). — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_expand_hostname.html0000664000175000017500000002240415051422664024037 0ustar ghudsonghudson krb5_expand_hostname - Canonicalize a hostname, possibly using name service. — MIT Kerberos Documentation

krb5_expand_hostname - Canonicalize a hostname, possibly using name service.¶

krb5_error_code krb5_expand_hostname(krb5_context context, const char *host, char **canonhost_out)¶
param:

[in] context - Library context

[in] host - Input hostname

[out] canonhost_out - Canonicalized hostname

This function canonicalizes orig_hostname, possibly using name service lookups if configuration permits. Use krb5_free_string() to free canonhost_out when it is no longer needed.

Note

New in 1.15

krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_keyblock.html0000664000175000017500000002331415051422667023514 0ustar ghudsonghudson krb5_init_keyblock - Initialize an empty krb5_keyblock . — MIT Kerberos Documentation

krb5_init_keyblock - Initialize an empty krb5_keyblock .¶

krb5_error_code krb5_init_keyblock(krb5_context context, krb5_enctype enctype, size_t length, krb5_keyblock **out)¶
param:

[in] context - Library context

[in] enctype - Encryption type

[in] length - Length of keyblock (or 0)

[out] out - New keyblock structure

retval:
  • 0 Success; otherwise - Kerberos error codes

Initialize a new keyblock and allocate storage for the contents of the key. It is legal to pass in a length of 0, in which case contents are left unallocated. Use krb5_free_keyblock() to free out when it is no longer needed.

Note

If length is set to 0, contents are left unallocated.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_context.html0000664000175000017500000002141015051422663023373 0ustar ghudsonghudson krb5_copy_context - Copy a krb5_context structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_verify_ext.html0000664000175000017500000002545315051422671023676 0ustar ghudsonghudson krb5_pac_verify_ext - Verify a PAC, possibly from a specified realm. — MIT Kerberos Documentation

krb5_pac_verify_ext - Verify a PAC, possibly from a specified realm.¶

krb5_error_code krb5_pac_verify_ext(krb5_context context, const krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock *server, const krb5_keyblock *privsvr, krb5_boolean with_realm)¶
param:

[in] context - Library context

[in] pac - PAC handle

[in] authtime - Expected timestamp

[in] principal - Expected principal name (or NULL)

[in] server - Key to validate server checksum (or NULL)

[in] privsvr - Key to validate KDC checksum (or NULL)

[in] with_realm - If true, expect the realm of principal

This function is similar to krb5_pac_verify(), but adds a parameter with_realm . If with_realm is true, the PAC_CLIENT_INFO field is expected to include the realm of principal as well as the name. This flag is necessary to verify PACs in cross-realm S4U2Self referral TGTs.

Note

New in 1.17

krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_principal.html0000664000175000017500000002210315051422663023670 0ustar ghudsonghudson krb5_copy_principal - Copy a principal. — MIT Kerberos Documentation

krb5_copy_principal - Copy a principal.¶

krb5_error_code krb5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_principal *outprinc)¶
param:

[in] context - Library context

[in] inprinc - Principal to be copied

[out] outprinc - Copy of inprinc

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new principal structure with the contents of inprinc . Use krb5_free_principal() to free outprinc when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_copy_creds.html0000664000175000017500000002200315051422662023452 0ustar ghudsonghudson krb5_cc_copy_creds - Copy a credential cache. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_ticket.html0000664000175000017500000002222315051422663023175 0ustar ghudsonghudson krb5_copy_ticket - Copy a krb5_ticket structure. — MIT Kerberos Documentation

krb5_copy_ticket - Copy a krb5_ticket structure.¶

krb5_error_code krb5_copy_ticket(krb5_context context, const krb5_ticket *from, krb5_ticket **pto)¶
param:

[in] context - Library context

[in] from - Ticket to be copied

[out] pto - Copy of ticket

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new krb5_ticket structure containing the contents of from . Use krb5_free_ticket() to free pto when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_credentials_renew.html0000664000175000017500000002165415051422665025225 0ustar ghudsonghudson krb5_get_credentials_renew — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_default_realm.html0000664000175000017500000002107215051422664024467 0ustar ghudsonghudson krb5_free_default_realm - Free a default realm string returned by krb5_get_default_realm(). — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_build_principal_ext.html0000664000175000017500000002446015051422661024703 0ustar ghudsonghudson krb5_build_principal_ext - Build a principal name using length-counted strings. — MIT Kerberos Documentation

krb5_build_principal_ext - Build a principal name using length-counted strings.¶

krb5_error_code krb5_build_principal_ext(krb5_context context, krb5_principal *princ, unsigned int rlen, const char *realm, ...)¶
param:

[in] context - Library context

[out] princ - Principal name

[in] rlen - Realm name length

[in] realm - Realm name

retval:
  • 0 Success

return:
  • Kerberos error codes

This function creates a principal from a length-counted string and a variable-length list of length-counted components. The list of components ends with the first 0 length argument (so it is not possible to specify an empty component with this function). Call krb5_free_principal() to free allocated memory for principal when it is no longer needed.

Beginning with release 1.20, the name type of the principal will be inferred as KRB5_NT_SRV_INST or KRB5_NT_WELLKNOWN based on the principal name. The type will be KRB5_NT_PRINCIPAL if a type cannot be inferred.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_dup.html0000664000175000017500000002137415051422670022152 0ustar ghudsonghudson krb5_kt_dup - Duplicate keytab handle. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_random_to_key.html0000664000175000017500000002356715051422661024026 0ustar ghudsonghudson krb5_c_random_to_key - Generate an enctype-specific key from random data. — MIT Kerberos Documentation

krb5_c_random_to_key - Generate an enctype-specific key from random data.¶

krb5_error_code krb5_c_random_to_key(krb5_context context, krb5_enctype enctype, krb5_data *random_data, krb5_keyblock *k5_random_key)¶
param:

[in] context - Library context

[in] enctype - Encryption type

[in] random_data - Random input data

[out] k5_random_key - Resulting key

retval:
  • 0 Success; otherwise - Kerberos error codes

This function takes random input data random_data and produces a valid key k5_random_key for a given enctype .

See also

krb5_c_keylengths()

Note

It is assumed that k5_random_key has already been initialized and k5_random_key->contents has been allocated with the correct length.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_enctypes.html0000664000175000017500000002110715051422664023514 0ustar ghudsonghudson krb5_free_enctypes - Free an array of encryption types. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_get_fast_flags.html0000664000175000017500000002306015051422665027556 0ustar ghudsonghudson krb5_get_init_creds_opt_get_fast_flags - Retrieve FAST flags from initial credential options. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_sname_to_principal.html0000664000175000017500000002544415051422673024537 0ustar ghudsonghudson krb5_sname_to_principal - Generate a full principal name from a service name. — MIT Kerberos Documentation

krb5_sname_to_principal - Generate a full principal name from a service name.¶

krb5_error_code krb5_sname_to_principal(krb5_context context, const char *hostname, const char *sname, krb5_int32 type, krb5_principal *ret_princ)¶
param:

[in] context - Library context

[in] hostname - Host name, or NULL to use local host

[in] sname - Service name, or NULL to use “hostâ€

[in] type - Principal type

[out] ret_princ - Generated principal

retval:
  • 0 Success

return:
  • Kerberos error codes

This function converts a hostname and sname into krb5_principal structure ret_princ . The returned principal will be of the form sname/hostname@REALM where REALM is determined by krb5_get_host_realm(). In some cases this may be the referral (empty) realm.

The type can be one of the following:

  • KRB5_NT_SRV_HST canonicalizes the host name before looking up the realm and generating the principal.

  • KRB5_NT_UNKNOWN accepts the hostname as given, and does not canonicalize it.

Use krb5_free_principal to free ret_princ when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getsendsubkey.html0000664000175000017500000002325415051422660025416 0ustar ghudsonghudson krb5_auth_con_getsendsubkey - Retrieve the send subkey from an auth context as a keyblock. — MIT Kerberos Documentation

krb5_auth_con_getsendsubkey - Retrieve the send subkey from an auth context as a keyblock.¶

krb5_error_code krb5_auth_con_getsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)¶
param:

[in] ctx - Library context

[in] ac - Authentication context

[out] keyblock - Send subkey

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a keyblock containing the send subkey from auth_context . Use krb5_free_keyblock() to free keyblock when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_is_config_principal.html0000664000175000017500000002211115051422667024661 0ustar ghudsonghudson krb5_is_config_principal - Test whether a principal is a configuration principal. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_wrap_error_message.html0000664000175000017500000002266715051422674024564 0ustar ghudsonghudson krb5_wrap_error_message - Add a prefix to a different error code’s message. — MIT Kerberos Documentation

krb5_wrap_error_message - Add a prefix to a different error code’s message.¶

void krb5_wrap_error_message(krb5_context ctx, krb5_error_code old_code, krb5_error_code code, const char *fmt, ...)¶
param:

[in] ctx - Library context

[in] old_code - Previous error code

[in] code - Error code

[in] fmt - Format string for error message prefix

Format a message and prepend it to the message for old_code . The prefix will be separated from the old message with a colon and space. Set the resulting message as the extended error message for code .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_gen_new.html0000664000175000017500000001761715051422662022761 0ustar ghudsonghudson krb5_cc_gen_new — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_mk_1cred.html0000664000175000017500000002437615051422670022356 0ustar ghudsonghudson krb5_mk_1cred - Format a KRB-CRED message for a single set of credentials. — MIT Kerberos Documentation

krb5_mk_1cred - Format a KRB-CRED message for a single set of credentials.¶

krb5_error_code krb5_mk_1cred(krb5_context context, krb5_auth_context auth_context, krb5_creds *creds, krb5_data **der_out, krb5_replay_data *rdata_out)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] creds - Pointer to credentials

[out] der_out - Encoded credentials

[out] rdata_out - Replay cache data (NULL if not needed)

retval:
  • 0 Success

  • ENOMEM Insufficient memory

  • KRB5_RC_REQUIRED Message replay detection requires rcache parameter

return:
  • Kerberos error codes

This is a convenience function that calls krb5_mk_ncred() with a single set of credentials.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_copy_addresses.html0000664000175000017500000002273215051422663023674 0ustar ghudsonghudson krb5_copy_addresses - Copy an array of addresses. — MIT Kerberos Documentation

krb5_copy_addresses - Copy an array of addresses.¶

krb5_error_code krb5_copy_addresses(krb5_context context, krb5_address *const *inaddr, krb5_address ***outaddr)¶
param:

[in] context - Library context

[in] inaddr - Array of addresses to be copied

[out] outaddr - Copy of array of addresses

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a new address array containing a copy of inaddr . Use krb5_free_addresses() to free outaddr when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_tgt_creds.html0000664000175000017500000002116515051422665023645 0ustar ghudsonghudson krb5_free_tgt_creds - Free an array of credential structures. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_init_creds_set_password.html0000664000175000017500000002277415051422667025617 0ustar ghudsonghudson krb5_init_creds_set_password - Set a password for acquiring initial credentials. — MIT Kerberos Documentation

krb5_init_creds_set_password - Set a password for acquiring initial credentials.¶

krb5_error_code krb5_init_creds_set_password(krb5_context context, krb5_init_creds_context ctx, const char *password)¶
param:

[in] context - Library context

[in] ctx - Initial credentials context

[in] password - Password

retval:
  • 0 Success; otherwise - Kerberos error codes

This function supplies a password to be used to construct the client key for an initial credentials request.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_mk_ncred.html0000664000175000017500000002732215051422670022445 0ustar ghudsonghudson krb5_mk_ncred - Format a KRB-CRED message for an array of credentials. — MIT Kerberos Documentation

krb5_mk_ncred - Format a KRB-CRED message for an array of credentials.¶

krb5_error_code krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds **creds, krb5_data **der_out, krb5_replay_data *rdata_out)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] creds - Null-terminated array of credentials

[out] der_out - Encoded credentials

[out] rdata_out - Replay cache information (NULL if not needed)

retval:
  • 0 Success

  • ENOMEM Insufficient memory

  • KRB5_RC_REQUIRED Message replay detection requires rcache parameter

return:
  • Kerberos error codes

This function takes an array of credentials creds and formats a KRB-CRED message der_out to pass to krb5_rd_cred().

The local and remote addresses in auth_context are optional; if either is specified, they are used to form the sender and receiver addresses in the KRB-CRED message.

If the KRB5_AUTH_CONTEXT_DO_TIME flag is set in auth_context , an entry for the message is entered in an in-memory replay cache to detect if the message is reflected by an attacker. If KRB5_AUTH_CONTEXT_DO_TIME is not set, no replay cache is used. If KRB5_AUTH_CONTEXT_RET_TIME is set in auth_context , the timestamp used for the KRB-CRED message is stored in rdata_out .

If either KRB5_AUTH_CONTEXT_DO_SEQUENCE or KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the auth_context local sequence number is included in the KRB-CRED message and then incremented. If KRB5_AUTH_CONTEXT_RET_SEQUENCE is set, the sequence number used is stored in rdata_out .

Use krb5_free_data_contents() to free der_out when it is no longer needed.

The message will be encrypted using the send subkey of auth_context if it is present, or the session key otherwise. If neither key is present, the credentials will not be encrypted, and the message should only be sent over a secure channel. No replay cache entry is used in this case.

Note

The rdata_out argument is required if the KRB5_AUTH_CONTEXT_RET_TIME or KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set in auth_context .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_valid_cksumtype.html0000664000175000017500000002156315051422661024371 0ustar ghudsonghudson krb5_c_valid_cksumtype - Verify that specified checksum type is a valid Kerberos checksum type. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_use_enctype.html0000664000175000017500000002030315051422673023201 0ustar ghudsonghudson krb5_use_enctype — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getrecvsubkey.html0000664000175000017500000002327615051422660025430 0ustar ghudsonghudson krb5_auth_con_getrecvsubkey - Retrieve the receiving subkey from an auth context as a keyblock. — MIT Kerberos Documentation

krb5_auth_con_getrecvsubkey - Retrieve the receiving subkey from an auth context as a keyblock.¶

krb5_error_code krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock)¶
param:

[in] ctx - Library context

[in] ac - Authentication context

[out] keyblock - Receiving subkey

retval:
  • 0 Success; otherwise - Kerberos error codes

This function creates a keyblock containing the receiving subkey from auth_context . Use krb5_free_keyblock() to free keyblock when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_tkt_creds_step.html0000664000175000017500000002612615051422673023704 0ustar ghudsonghudson krb5_tkt_creds_step - Get the next KDC request in a TGS exchange. — MIT Kerberos Documentation

krb5_tkt_creds_step - Get the next KDC request in a TGS exchange.¶

krb5_error_code krb5_tkt_creds_step(krb5_context context, krb5_tkt_creds_context ctx, krb5_data *in, krb5_data *out, krb5_data *realm, unsigned int *flags)¶
param:

[in] context - Library context

[in] ctx - TGS request context

[in] in - KDC response (empty on the first call)

[out] out - Next KDC request

[out] realm - Realm for next KDC request

[out] flags - Output flags

retval:
  • 0 Success; otherwise - Kerberos error codes

This function constructs the next KDC request for a TGS exchange, allowing the caller to control the transport of KDC requests and replies. On the first call, in should be set to an empty buffer; on subsequent calls, it should be set to the KDC’s reply to the previous request.

If more requests are needed, flags will be set to KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in out . If no more requests are needed, flags will not contain KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and out will be empty.

If this function returns KRB5KRB_ERR_RESPONSE_TOO_BIG , the caller should transmit the next request using TCP rather than UDP. If this function returns any other error, the TGS exchange has failed.

Note

New in 1.9

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_validated_creds.html0000664000175000017500000002513515051422666024644 0ustar ghudsonghudson krb5_get_validated_creds - Get validated credentials from the KDC. — MIT Kerberos Documentation

krb5_get_validated_creds - Get validated credentials from the KDC.¶

krb5_error_code krb5_get_validated_creds(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_ccache ccache, const char *in_tkt_service)¶
param:

[in] context - Library context

[out] creds - Validated credentials

[in] client - Client principal name

[in] ccache - Credential cache

[in] in_tkt_service - Server principal string (or NULL)

retval:
  • 0 Success

  • KRB5_NO_2ND_TKT Request missing second ticket

  • KRB5_NO_TKT_SUPPLIED Request did not supply a ticket

  • KRB5_PRINC_NOMATCH Requested principal and ticket do not match

  • KRB5_KDCREP_MODIFIED KDC reply did not match expectations

  • KRB5_KDCREP_SKEW Clock skew too great in KDC reply

return:
  • Kerberos error codes

This function gets a validated credential using a postdated credential from ccache . If in_tkt_service is specified, it is parsed (with the realm part ignored) and used as the server principal of the credential; otherwise, the ticket-granting service is used.

If successful, the validated credential is placed in creds .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_default_config_files.html0000664000175000017500000002113315051422665025653 0ustar ghudsonghudson krb5_get_default_config_files - Return a list of default configuration filenames. — MIT Kerberos Documentation

krb5_get_default_config_files - Return a list of default configuration filenames.¶

krb5_error_code krb5_get_default_config_files(char ***filenames)¶
param:

[out] filenames - Configuration filename list

Fill in filenames with a null-terminated list of configuration files which will be read by krb5_init_context() in the current process environment.

Use krb5_free_config_files() to free filenames when it is no longer needed.

Note

New in 1.22

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_verify_checksum_iov.html0000664000175000017500000002604115051422667025243 0ustar ghudsonghudson krb5_k_verify_checksum_iov - Validate a checksum element in IOV array (operates on opaque key). — MIT Kerberos Documentation

krb5_k_verify_checksum_iov - Validate a checksum element in IOV array (operates on opaque key).¶

krb5_error_code krb5_k_verify_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_boolean *valid)¶
param:

[in] context - Library context

[in] cksumtype - Checksum type (0 for mandatory type)

[in] key - Encryption key for a keyed checksum

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[in] data - IOV array

[in] num_data - Size of data

[out] valid - Non-zero for success, zero for failure

retval:
  • 0 Success; otherwise - Kerberos error codes

Confirm that the checksum in the KRB5_CRYPTO_TYPE_CHECKSUM element is a valid checksum of the KRB5_CRYPTO_TYPE_DATA and KRB5_CRYPTO_TYPE_SIGN_ONLY regions in the iov.

See also

krb5_k_make_checksum_iov()

Note

This function is similar to krb5_c_verify_checksum_iov(), but operates on opaque key .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_time_offsets.html0000664000175000017500000002260015051422666024210 0ustar ghudsonghudson krb5_get_time_offsets - Return the time offsets from the os context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_build_principal_va.html0000664000175000017500000002142015051422661024502 0ustar ghudsonghudson krb5_build_principal_va — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_cksumtypes.html0000664000175000017500000002065515051422664024100 0ustar ghudsonghudson krb5_free_cksumtypes - Free an array of checksum types. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_kdc_recv_hook.html0000664000175000017500000002216015051422672024333 0ustar ghudsonghudson krb5_set_kdc_recv_hook - Set a KDC post-receive hook function. — MIT Kerberos Documentation

krb5_set_kdc_recv_hook - Set a KDC post-receive hook function.¶

void krb5_set_kdc_recv_hook(krb5_context context, krb5_post_recv_fn recv_hook, void *data)¶
param:

[in] context - The library context.

[in] recv_hook - Hook function (or NULL to disable the hook)

[in] data - Callback data to be passed to recv_hook

recv_hook will be called after a reply is received from a KDC during a call to a library function such as krb5_get_credentials(). The hook function may inspect or override the reply. This hook will not be executed if the pre-send hook returns a synthetic reply.

Note

New in 1.15

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_make_checksum.html0000664000175000017500000002616315051422667024004 0ustar ghudsonghudson krb5_k_make_checksum - Compute a checksum (operates on opaque key). — MIT Kerberos Documentation

krb5_k_make_checksum - Compute a checksum (operates on opaque key).¶

krb5_error_code krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, const krb5_data *input, krb5_checksum *cksum)¶
param:

[in] context - Library context

[in] cksumtype - Checksum type (0 for mandatory type)

[in] key - Encryption key for a keyed checksum

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[in] input - Input data

[out] cksum - Generated checksum

retval:
  • 0 Success; otherwise - Kerberos error codes

This function computes a checksum of type cksumtype over input , using key if the checksum type is a keyed checksum. If cksumtype is 0 and key is non-null, the checksum type will be the mandatory-to-implement checksum type for the key’s encryption type. The actual checksum key will be derived from key and usage if key derivation is specified for the checksum type. The newly created cksum must be released by calling krb5_free_checksum_contents() when it is no longer needed.

See also

krb5_c_verify_checksum()

Note

This function is similar to krb5_c_make_checksum(), but operates on opaque key .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_deltat_to_string.html0000664000175000017500000002164315051422663024232 0ustar ghudsonghudson krb5_deltat_to_string - Convert a relative time value to a string. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_finish_random_key.html0000664000175000017500000002050515051422664024352 0ustar ghudsonghudson krb5_finish_random_key — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_initivector.html0000664000175000017500000002133715051422660025101 0ustar ghudsonghudson krb5_auth_con_initivector - Cause an auth context to use cipher state. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_context.html0000664000175000017500000002030115051422664023341 0ustar ghudsonghudson krb5_free_context - Free a krb5 library context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_trace_callback.html0000664000175000017500000002363515051422673024456 0ustar ghudsonghudson krb5_set_trace_callback - Specify a callback function for trace events. — MIT Kerberos Documentation

krb5_set_trace_callback - Specify a callback function for trace events.¶

krb5_error_code krb5_set_trace_callback(krb5_context context, krb5_trace_callback fn, void *cb_data)¶
param:

[in] context - Library context

[in] fn - Callback function

[in] cb_data - Callback data

return:
  • Returns KRB5_TRACE_NOSUPP if tracing is not supported in the library (unless fn is NULL).

Specify a callback for trace events occurring in krb5 operations performed within context . fn will be invoked with context as the first argument, cb_data as the last argument, and a pointer to a krb5_trace_info as the second argument. If the trace callback is reset via this function or context is destroyed, fn will be invoked with a NULL second argument so it can clean up cb_data . Supply a NULL value for fn to disable trace callbacks within context .

Note

This function overrides the information passed through the KRB5_TRACE environment variable.

Note

New in 1.9

krb5-1.22.1/doc/html/appdev/refs/api/krb5_rd_rep_dce.html0000664000175000017500000002310115051422672022742 0ustar ghudsonghudson krb5_rd_rep_dce - Parse and decrypt a KRB_AP_REP message for DCE RPC. — MIT Kerberos Documentation

krb5_rd_rep_dce - Parse and decrypt a KRB_AP_REP message for DCE RPC.¶

krb5_error_code krb5_rd_rep_dce(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_ui_4 *nonce)¶
param:

[in] context - Library context

[in] auth_context - Authentication context

[in] inbuf - AP-REP message

[out] nonce - Sequence number from the decrypted reply

retval:
  • 0 Success; otherwise - Kerberos error codes

This function parses, decrypts and verifies a message from inbuf and fills in nonce with a decrypted reply sequence number.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_next_entry.html0000664000175000017500000002346215051422670023561 0ustar ghudsonghudson krb5_kt_next_entry - Retrieve the next entry from the key table. — MIT Kerberos Documentation

krb5_kt_next_entry - Retrieve the next entry from the key table.¶

krb5_error_code krb5_kt_next_entry(krb5_context context, krb5_keytab keytab, krb5_keytab_entry *entry, krb5_kt_cursor *cursor)¶
param:

[in] context - Library context

[in] keytab - Key table handle

[out] entry - Returned key table entry

[in] cursor - Key table cursor

retval:
  • 0 Success

  • KRB5_KT_END - if the last entry was reached

return:
  • Kerberos error codes

Return the next sequential entry in keytab and advance cursor . Callers must release the returned entry with krb5_kt_free_entry().

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_data.html0000664000175000017500000002055615051422664022602 0ustar ghudsonghudson krb5_free_data - Free a krb5_data structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_decrypt.html0000664000175000017500000002617415051422667022661 0ustar ghudsonghudson krb5_k_decrypt - Decrypt data using a key (operates on opaque key). — MIT Kerberos Documentation

krb5_k_decrypt - Decrypt data using a key (operates on opaque key).¶

krb5_error_code krb5_k_decrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_enc_data *input, krb5_data *output)¶
param:

[in] context - Library context

[in] key - Encryption key

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[inout] cipher_state - Cipher state; specify NULL if not needed

[in] input - Encrypted data

[out] output - Decrypted data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function decrypts the data block input and stores the output into output . The actual decryption key will be derived from key and usage if key derivation is specified for the encryption type. If non-null, cipher_state specifies the beginning state for the decryption operation, and is updated with the state to be passed as input to the next operation.

Note

The caller must initialize output and allocate at least enough space for the result. The usual practice is to allocate an output buffer as long as the ciphertext, and let krb5_c_decrypt() trim output->length . For some enctypes, the resulting output->length may include padding bytes.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_setuseruserkey.html0000664000175000017500000002237215051422660025644 0ustar ghudsonghudson krb5_auth_con_setuseruserkey - Set the session key in an auth context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_server_decrypt_ticket_keytab.html0000664000175000017500000002305015051422672026621 0ustar ghudsonghudson krb5_server_decrypt_ticket_keytab - Decrypt a ticket using the specified key table. — MIT Kerberos Documentation

krb5_server_decrypt_ticket_keytab - Decrypt a ticket using the specified key table.¶

krb5_error_code krb5_server_decrypt_ticket_keytab(krb5_context context, const krb5_keytab kt, krb5_ticket *ticket)¶
param:

[in] context - Library context

[in] kt - Key table

[in] ticket - Ticket to be decrypted

retval:
  • 0 Success; otherwise - Kerberos error codes

This function takes a ticket as input and decrypts it using key data from kt . The result is placed into ticket->enc_part2 .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_timeofday.html0000664000175000017500000002233715051422673022650 0ustar ghudsonghudson krb5_timeofday - Retrieve the current time with context specific time offset adjustment. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getremotesubkey.html0000664000175000017500000002115715051422660025760 0ustar ghudsonghudson krb5_auth_con_getremotesubkey — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_finish_key.html0000664000175000017500000001765215051422664023023 0ustar ghudsonghudson krb5_finish_key — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_keyblock_contents.html0000664000175000017500000002120315051422665025400 0ustar ghudsonghudson krb5_free_keyblock_contents - Free the contents of a krb5_keyblock structure. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_move.html0000664000175000017500000002231115051422662022270 0ustar ghudsonghudson krb5_cc_move - Move a credential cache. — MIT Kerberos Documentation

krb5_cc_move - Move a credential cache.¶

krb5_error_code krb5_cc_move(krb5_context context, krb5_ccache src, krb5_ccache dst)¶
param:

[in] context - Library context

[in] src - The credential cache to move the content from

[in] dst - The credential cache to move the content to

retval:
  • 0 Success; src is closed.

return:
  • Kerberos error codes; src is still allocated.

This function reinitializes dst and populates it with the credentials and default principal of src ; then, if successful, destroys src .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_pac_init.html0000664000175000017500000002152615051422671022452 0ustar ghudsonghudson krb5_pac_init - Create an empty Privilege Attribute Certificate (PAC) handle. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_destroy.html0000664000175000017500000002127215051422662023020 0ustar ghudsonghudson krb5_cc_destroy - Destroy a credential cache. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_checksum_length.html0000664000175000017500000002207015051422661024323 0ustar ghudsonghudson krb5_c_checksum_length - Return the length of checksums for a checksum type. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_set_change_password_prompt.html0000664000175000017500000002263315051422665032236 0ustar ghudsonghudson krb5_get_init_creds_opt_set_change_password_prompt - Set or unset change-password-prompt flag in initial credential options. — MIT Kerberos Documentation

krb5_get_init_creds_opt_set_change_password_prompt - Set or unset change-password-prompt flag in initial credential options.¶

void krb5_get_init_creds_opt_set_change_password_prompt(krb5_get_init_creds_opt *opt, int prompt)¶
param:

[in] opt - Options structure

[in] prompt - Whether to prompt to change password

This flag is on by default. It controls whether krb5_get_init_creds_password() will react to an expired-password error by prompting for a new password and attempting to change the old one.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_resolve.html0000664000175000017500000002277615051422662023020 0ustar ghudsonghudson krb5_cc_resolve - Resolve a credential cache name. — MIT Kerberos Documentation

krb5_cc_resolve - Resolve a credential cache name.¶

krb5_error_code krb5_cc_resolve(krb5_context context, const char *name, krb5_ccache *cache)¶
param:

[in] context - Library context

[in] name - Credential cache name to be resolved

[out] cache - Credential cache handle

retval:
  • 0 Success

return:
  • Kerberos error codes

Fills in cache with a cache handle that corresponds to the name in name . name should be of the form type:residual , and type must be a type known to the library. If the name does not contain a colon, interpret it as a file name.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_init_creds_opt_init.html0000664000175000017500000001735515051422665025563 0ustar ghudsonghudson krb5_get_init_creds_opt_init — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_string_to_key_with_params.html0000664000175000017500000002600015051422661026433 0ustar ghudsonghudson krb5_c_string_to_key_with_params - Convert a string (such as a password) to a key with additional parameters. — MIT Kerberos Documentation

krb5_c_string_to_key_with_params - Convert a string (such as a password) to a key with additional parameters.¶

krb5_error_code krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key)¶
param:

[in] context - Library context

[in] enctype - Encryption type

[in] string - String to be converted

[in] salt - Salt value

[in] params - Parameters

[out] key - Generated key

retval:
  • 0 Success; otherwise - Kerberos error codes

This function is similar to krb5_c_string_to_key(), but also takes parameters which may affect the algorithm in an enctype-dependent way. The newly created key must be released by calling krb5_free_keyblock_contents() when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_responder_pkinit_set_answer.html0000664000175000017500000002362315051422672026476 0ustar ghudsonghudson krb5_responder_pkinit_set_answer - Answer the KRB5_RESPONDER_QUESTION_PKINIT question for one identity. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_checksum_size.html0000664000175000017500000001735715051422663023530 0ustar ghudsonghudson krb5_checksum_size — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_c_prf_length.html0000664000175000017500000002202015051422661023303 0ustar ghudsonghudson krb5_c_prf_length - Get the output length of pseudo-random functions for an encryption type. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_auth_con_getrcache.html0000664000175000017500000002273415051422660024471 0ustar ghudsonghudson krb5_auth_con_getrcache - Retrieve the replay cache from an auth context. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_set_default_name.html0000664000175000017500000002246515051422663024634 0ustar ghudsonghudson krb5_cc_set_default_name - Set the default credential cache name. — MIT Kerberos Documentation

krb5_cc_set_default_name - Set the default credential cache name.¶

krb5_error_code krb5_cc_set_default_name(krb5_context context, const char *name)¶
param:

[in] context - Library context

[in] name - Default credential cache name or NULL

retval:
  • 0 Success

  • KV5M_CONTEXT Bad magic number for _krb5_context structure

return:
  • Kerberos error codes

Set the default credential cache name to name for future operations using context . If name is NULL, clear any previous application-set default name and forget any cached value of the default name for context .

Calls to this function invalidate the result of any previous calls to krb5_cc_default_name() using context .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_authdata.html0000664000175000017500000002147415051422664023464 0ustar ghudsonghudson krb5_free_authdata - Free the storage assigned to array of authentication data. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_process_key.html0000664000175000017500000002043715051422671023212 0ustar ghudsonghudson krb5_process_key — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_recvauth_version.html0000664000175000017500000002602115051422672024246 0ustar ghudsonghudson krb5_recvauth_version - Server function for sendauth protocol with version parameter. — MIT Kerberos Documentation

krb5_recvauth_version - Server function for sendauth protocol with version parameter.¶

krb5_error_code krb5_recvauth_version(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, krb5_principal server, krb5_int32 flags, krb5_keytab keytab, krb5_ticket **ticket, krb5_data *version)¶
param:

[in] context - Library context

[inout] auth_context - Pre-existing or newly created auth context

[in] fd - File descriptor

[in] server - Server principal (NULL for any in keytab )

[in] flags - Additional specifications

[in] keytab - Decryption key

[out] ticket - Ticket (NULL if not needed)

[out] version - sendauth protocol version (NULL if not needed)

retval:
  • 0 Success; otherwise - Kerberos error codes

This function is similar to krb5_recvauth() with the additional output information place into version .

krb5-1.22.1/doc/html/appdev/refs/api/krb5_responder_otp_get_challenge.html0000664000175000017500000002333515051422672026411 0ustar ghudsonghudson krb5_responder_otp_get_challenge - Decode the KRB5_RESPONDER_QUESTION_OTP to a C struct. — MIT Kerberos Documentation

krb5_responder_otp_get_challenge - Decode the KRB5_RESPONDER_QUESTION_OTP to a C struct.¶

krb5_error_code krb5_responder_otp_get_challenge(krb5_context ctx, krb5_responder_context rctx, krb5_responder_otp_challenge **chl)¶
param:

[in] ctx - Library context

[in] rctx - Responder context

[out] chl - Challenge structure

A convenience function which parses the KRB5_RESPONDER_QUESTION_OTP question challenge data, making it available in native C. The main feature of this function is the ability to interact with OTP tokens without parsing the JSON.

The returned value must be passed to krb5_responder_otp_challenge_free() to be freed.

Note

New in 1.11

krb5-1.22.1/doc/html/appdev/refs/api/krb5_set_principal_realm.html0000664000175000017500000002257615051422672024707 0ustar ghudsonghudson krb5_set_principal_realm - Set the realm field of a principal. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_get_permitted_enctypes.html0000664000175000017500000002257215051422666025440 0ustar ghudsonghudson krb5_get_permitted_enctypes - Return a list of encryption types permitted for session keys. — MIT Kerberos Documentation

krb5_get_permitted_enctypes - Return a list of encryption types permitted for session keys.¶

krb5_error_code krb5_get_permitted_enctypes(krb5_context context, krb5_enctype **ktypes)¶
param:

[in] context - Library context

[out] ktypes - Zero-terminated list of encryption types

retval:
  • 0 Success; otherwise - Kerberos error codes

This function returns the list of encryption types permitted for session keys within context , as determined by configuration or by a previous call to krb5_set_default_tgs_enctypes().

Use krb5_free_enctypes() to free ktypes when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_addresses.html0000664000175000017500000002125015051422664023636 0ustar ghudsonghudson krb5_free_addresses - Free the data stored in array of addresses. — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/api/krb5_kt_get_entry.html0000664000175000017500000002477515051422670023372 0ustar ghudsonghudson krb5_kt_get_entry - Get an entry from a key table. — MIT Kerberos Documentation

krb5_kt_get_entry - Get an entry from a key table.¶

krb5_error_code krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, krb5_const_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keytab_entry *entry)¶
param:

[in] context - Library context

[in] keytab - Key table handle

[in] principal - Principal name

[in] vno - Key version number (0 for highest available)

[in] enctype - Encryption type (0 zero for any enctype)

[out] entry - Returned entry from key table

retval:
  • 0 Success

  • Kerberos error codes on failure

Retrieve an entry from a key table which matches the keytab , principal , vno , and enctype . If vno is zero, retrieve the highest-numbered kvno matching the other fields. If enctype is 0, match any enctype.

Use krb5_free_keytab_entry_contents() to free entry when it is no longer needed.

Note

If vno is zero, the function retrieves the highest-numbered-kvno entry that matches the specified principal.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_k_encrypt_iov.html0000664000175000017500000002622015051422667023540 0ustar ghudsonghudson krb5_k_encrypt_iov - Encrypt data in place supporting AEAD (operates on opaque key). — MIT Kerberos Documentation

krb5_k_encrypt_iov - Encrypt data in place supporting AEAD (operates on opaque key).¶

krb5_error_code krb5_k_encrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data)¶
param:

[in] context - Library context

[in] key - Encryption key

[in] usage - Key usage (see KRB5_KEYUSAGE macros)

[in] cipher_state - Cipher state; specify NULL if not needed

[inout] data - IOV array. Modified in-place.

[in] num_data - Size of data

retval:
  • 0 Success; otherwise - Kerberos error codes

This function encrypts the data block data and stores the output in-place. The actual encryption key will be derived from key and usage if key derivation is specified for the encryption type. If non-null, cipher_state specifies the beginning state for the encryption operation, and is updated with the state to be passed as input to the next operation. The caller must allocate the right number of krb5_crypto_iov structures before calling into this API.

See also

krb5_k_decrypt_iov()

Note

On return from a krb5_c_encrypt_iov() call, the data->length in the iov structure are adjusted to reflect actual lengths of the ciphertext used. For example, if the padding length is too large, the length will be reduced. Lengths are never increased.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_cc_get_principal.html0000664000175000017500000002265115051422662024151 0ustar ghudsonghudson krb5_cc_get_principal - Get the default principal of a credential cache. — MIT Kerberos Documentation

krb5_cc_get_principal - Get the default principal of a credential cache.¶

krb5_error_code krb5_cc_get_principal(krb5_context context, krb5_ccache cache, krb5_principal *principal)¶
param:

[in] context - Library context

[in] cache - Credential cache handle

[out] principal - Primary principal

retval:
  • 0 Success

return:
  • Kerberos error codes

Returns the default client principal of a credential cache as set by krb5_cc_initialize().

Use krb5_free_principal() to free principal when it is no longer needed.

krb5-1.22.1/doc/html/appdev/refs/api/krb5_decode_authdata_container.html0000664000175000017500000002341015051422663026017 0ustar ghudsonghudson krb5_decode_authdata_container - Unwrap authorization data. — MIT Kerberos Documentation

krb5_decode_authdata_container - Unwrap authorization data.¶

krb5_error_code krb5_decode_authdata_container(krb5_context context, krb5_authdatatype type, const krb5_authdata *container, krb5_authdata ***authdata)¶
param:

[in] context - Library context

[in] type - Container type (see KRB5_AUTHDATA macros)

[in] container - Authorization data to be decoded

[out] authdata - List of decoded authorization data

retval:
  • 0 Success; otherwise - Kerberos error codes

See also

krb5_encode_authdata_container()

krb5-1.22.1/doc/html/appdev/refs/api/krb5_free_data_contents.html0000664000175000017500000002150715051422664024514 0ustar ghudsonghudson krb5_free_data_contents - Free the contents of a krb5_data structure and zero the data field. — MIT Kerberos Documentation

krb5_free_data_contents - Free the contents of a krb5_data structure and zero the data field.¶

void krb5_free_data_contents(krb5_context context, krb5_data *val)¶
param:

[in] context - Library context

[in] val - Data structure to free contents of

This function frees the contents of val , but not the structure itself. It sets the structure’s data pointer to null and (beginning in release 1.19) sets its length to zero.

krb5-1.22.1/doc/html/appdev/refs/macros/0000775000175000017500000000000015051422712017554 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DES_HMAC_SHA1.html0000664000175000017500000001665715051422676023640 0ustar ghudsonghudson ENCTYPE_DES_HMAC_SHA1 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_DIRECTIONAL.html0000664000175000017500000001652315051422674023511 0ustar ghudsonghudson ADDRTYPE_DIRECTIONAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR.html0000664000175000017500000001771115051422700027137 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_DEVICE_CLAIMS.html0000664000175000017500000001677115051422704023714 0ustar ghudsonghudson KRB5_PAC_DEVICE_CLAIMS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY.html0000664000175000017500000001735415051422703025452 0ustar ghudsonghudson KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/MSEC_DIRBIT.html0000664000175000017500000001637115051422710022234 0ustar ghudsonghudson MSEC_DIRBIT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_DESCBC.html0000664000175000017500000001656515051422675023056 0ustar ghudsonghudson CKSUMTYPE_DESCBC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_AS_FRESHNESS.html0000664000175000017500000001710115051422704024163 0ustar ghudsonghudson KRB5_PADATA_AS_FRESHNESS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_princ_realm.html0000664000175000017500000001664615051422711023674 0ustar ghudsonghudson krb5_princ_realm — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_MANDATORY_FOR_KDC.html0000664000175000017500000001713215051422677025243 0ustar ghudsonghudson KRB5_AUTHDATA_MANDATORY_FOR_KDC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/VALID_UINT_BITS.html0000664000175000017500000001640315051422711022764 0ustar ghudsonghudson VALID_UINT_BITS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_X500_PRINCIPAL.html0000664000175000017500000001672315051422704023675 0ustar ghudsonghudson KRB5_NT_X500_PRINCIPAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_ERROR.html0000664000175000017500000001655015051422700022122 0ustar ghudsonghudson KRB5_ERROR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DES3_CBC_SHA1.html0000664000175000017500000001665715051422676023602 0ustar ghudsonghudson ENCTYPE_DES3_CBC_SHA1 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_POSTDATED.html0000664000175000017500000001653515051422676023217 0ustar ghudsonghudson KDC_OPT_POSTDATED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb524_init_ets.html0000664000175000017500000001666715051422711023370 0ustar ghudsonghudson krb524_init_ets — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_SESAME.html0000664000175000017500000001667715051422706023240 0ustar ghudsonghudson KRB5_PADATA_SESAME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ.html0000664000175000017500000001701715051422701023540 0ustar ghudsonghudson KRB5_KEYUSAGE_AS_REQ — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AP_OPTS_MUTUAL_REQUIRED.html0000664000175000017500000001672615051422674024221 0ustar ghudsonghudson AP_OPTS_MUTUAL_REQUIRED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PVNO.html0000664000175000017500000001651415051422707022022 0ustar ghudsonghudson KRB5_PVNO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_SHA1.html0000664000175000017500000001665415051422675022626 0ustar ghudsonghudson CKSUMTYPE_SHA1 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/LR_TYPE_INTERPRETATION_MASK.html0000664000175000017500000001705515051422710024670 0ustar ghudsonghudson LR_TYPE_INTERPRETATION_MASK — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_SPAKE.html0000664000175000017500000001664415051422706023120 0ustar ghudsonghudson KRB5_PADATA_SPAKE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE_2.html0000664000175000017500000001705215051422706024426 0ustar ghudsonghudson KRB5_PADATA_SAM_RESPONSE_2 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_PA_AS_FRESHNESS.html0000664000175000017500000001723015051422702025027 0ustar ghudsonghudson KRB5_KEYUSAGE_PA_AS_FRESHNESS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_INIT_CREDS_STEP_FLAG_CONTINUE.html0000664000175000017500000001715015051422701025642 0ustar ghudsonghudson KRB5_INIT_CREDS_STEP_FLAG_CONTINUE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AP_OPTS_WIRE_MASK.html0000664000175000017500000001663115051422675023267 0ustar ghudsonghudson AP_OPTS_WIRE_MASK — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_HMAC_SHA384_192_AES256.html0000664000175000017500000001730015051422675025101 0ustar ghudsonghudson CKSUMTYPE_HMAC_SHA384_192_AES256 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS.html0000664000175000017500000001705615051422701025216 0ustar ghudsonghudson KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_NULL.html0000664000175000017500000001645315051422676022425 0ustar ghudsonghudson ENCTYPE_NULL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_KDC_REP_TICKET.html0000664000175000017500000001720415051422702024677 0ustar ghudsonghudson KRB5_KEYUSAGE_KDC_REP_TICKET — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/VALID_INT_BITS.html0000664000175000017500000001656215051422711022645 0ustar ghudsonghudson VALID_INT_BITS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_SAM_USE_SAD_AS_KEY.html0000664000175000017500000001700515051422707024152 0ustar ghudsonghudson KRB5_SAM_USE_SAD_AS_KEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_UNKNOWN.html0000664000175000017500000001655515051422676023015 0ustar ghudsonghudson ENCTYPE_UNKNOWN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_FX_ERROR.html0000664000175000017500000001666515051422705023545 0ustar ghudsonghudson KRB5_PADATA_FX_ERROR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_MATCH_FLAGS.html0000664000175000017500000001700615051422707023373 0ustar ghudsonghudson KRB5_TC_MATCH_FLAGS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM.html0000664000175000017500000001753315051422702026036 0ustar ghudsonghudson KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_NO_REALM.html0000664000175000017500000001730415051422706025267 0ustar ghudsonghudson KRB5_PRINCIPAL_UNPARSE_NO_REALM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_DEF_REALM.html0000664000175000017500000001740115051422706025500 0ustar ghudsonghudson KRB5_PRINCIPAL_PARSE_NO_DEF_REALM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_SALT.html0000664000175000017500000001726315051422701024763 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_SALT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CRYPTO_TYPE_PADDING.html0000664000175000017500000001704515051422700024240 0ustar ghudsonghudson KRB5_CRYPTO_TYPE_PADDING — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_INET6.html0000664000175000017500000001641315051422674022577 0ustar ghudsonghudson ADDRTYPE_INET6 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/index.html0000664000175000017500000015254615051422711021565 0ustar ghudsonghudson krb5 simple macros — MIT Kerberos Documentation

krb5 simple macros¶

Public¶

Deprecated macros¶

krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GC_CANONICALIZE.html0000664000175000017500000001673615051422700023447 0ustar ghudsonghudson KRB5_GC_CANONICALIZE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_PROXY.html0000664000175000017500000001644515051422711022606 0ustar ghudsonghudson TKT_FLG_PROXY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_HMAC_SHA256_128_AES128.html0000664000175000017500000001733615051422675025105 0ustar ghudsonghudson CKSUMTYPE_HMAC_SHA256_128_AES128 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_NIST_SHA.html0000664000175000017500000001663515051422675023401 0ustar ghudsonghudson CKSUMTYPE_NIST_SHA — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_princ_size.html0000664000175000017500000001667415051422711023547 0ustar ghudsonghudson krb5_princ_size — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_ETYPE_INFO2.html0000664000175000017500000001675215051422705024037 0ustar ghudsonghudson KRB5_PADATA_ETYPE_INFO2 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_SHA1_RSA_CMS.html0000664000175000017500000001670015051422676023551 0ustar ghudsonghudson ENCTYPE_SHA1_RSA_CMS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PROMPT_TYPE_PASSWORD.html0000664000175000017500000001717015051422707024443 0ustar ghudsonghudson KRB5_PROMPT_TYPE_PASSWORD — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DES_CBC_MD5.html0000664000175000017500000001661515051422676023402 0ustar ghudsonghudson ENCTYPE_DES_CBC_MD5 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA128.html0000664000175000017500000001703615051422675024312 0ustar ghudsonghudson CKSUMTYPE_CMAC_CAMELLIA128 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC.html0000664000175000017500000001704415051422675023540 0ustar ghudsonghudson ENCTYPE_ARCFOUR_HMAC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_INT32_MAX.html0000664000175000017500000001641715051422701022540 0ustar ghudsonghudson KRB5_INT32_MAX — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_AP_REQ.html0000664000175000017500000001663615051422704023263 0ustar ghudsonghudson KRB5_PADATA_AP_REQ — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_MATCH_TIMES.html0000664000175000017500000001705615051422710023417 0ustar ghudsonghudson KRB5_TC_MATCH_TIMES — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST.html0000664000175000017500000001745715051422701026170 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_PERMIT_ALL.html0000664000175000017500000001734115051422700024745 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_PERMIT_ALL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb524_convert_creds_kdc.html0000664000175000017500000001660315051422711025221 0ustar ghudsonghudson krb524_convert_creds_kdc — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY.html0000664000175000017500000001735215051422703026257 0ustar ghudsonghudson KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TGS_NAME.html0000664000175000017500000001653515051422710022472 0ustar ghudsonghudson KRB5_TGS_NAME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_roundup.html0000664000175000017500000001656715051422712023100 0ustar ghudsonghudson krb5_roundup — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DES_CBC_RAW.html0000664000175000017500000001663115051422676023444 0ustar ghudsonghudson ENCTYPE_DES_CBC_RAW — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_DISABLE_TRANSITED_CHECK.html0000664000175000017500000001716515051422676025245 0ustar ghudsonghudson KDC_OPT_DISABLE_TRANSITED_CHECK — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_RC2_CBC_ENV.html0000664000175000017500000001656415051422676023423 0ustar ghudsonghudson ENCTYPE_RC2_CBC_ENV — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_princ_component.html0000664000175000017500000001665715051422711024600 0ustar ghudsonghudson krb5_princ_component — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_HW_AUTH.html0000664000175000017500000001646515051422710023025 0ustar ghudsonghudson TKT_FLG_HW_AUTH — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_x.html0000664000175000017500000001633115051422712021640 0ustar ghudsonghudson krb5_x — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_SAM_MUST_PK_ENCRYPT_SAD.html0000664000175000017500000001704115051422707025011 0ustar ghudsonghudson KRB5_SAM_MUST_PK_ENCRYPT_SAD — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_PROXIABLE.html0000664000175000017500000001650515051422676023212 0ustar ghudsonghudson KDC_OPT_PROXIABLE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_OTP_PIN_CHANGE.html0000664000175000017500000001710515051422705024422 0ustar ghudsonghudson KRB5_PADATA_OTP_PIN_CHANGE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA256_128.html0000664000175000017500000001740015051422675025331 0ustar ghudsonghudson ENCTYPE_AES128_CTS_HMAC_SHA256_128 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA1_96.html0000664000175000017500000001737215051422675025113 0ustar ghudsonghudson ENCTYPE_AES256_CTS_HMAC_SHA1_96 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_IS_LOCAL.html0000664000175000017500000001663415051422674023204 0ustar ghudsonghudson ADDRTYPE_IS_LOCAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_RSA_MD4_DES.html0000664000175000017500000001662115051422675023710 0ustar ghudsonghudson CKSUMTYPE_RSA_MD4_DES — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_NONE.html0000664000175000017500000001656015051422703022512 0ustar ghudsonghudson KRB5_LRQ_NONE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_PK_AS_REP.html0000664000175000017500000001676415051422705023662 0ustar ghudsonghudson KRB5_PADATA_PK_AS_REP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_MS_PRINCIPAL.html0000664000175000017500000001704015051422704023551 0ustar ghudsonghudson KRB5_NT_MS_PRINCIPAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ALL_PW_EXPTIME.html0000664000175000017500000001672215051422703024164 0ustar ghudsonghudson KRB5_LRQ_ALL_PW_EXPTIME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_ENCRYPT.html0000664000175000017500000001721715051422701025145 0ustar ghudsonghudson KRB5_KEYUSAGE_APP_DATA_ENCRYPT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RECVAUTH_SKIP_VERSION.html0000664000175000017500000001702315051422707024510 0ustar ghudsonghudson KRB5_RECVAUTH_SKIP_VERSION — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT.html0000664000175000017500000001674615051422703023732 0ustar ghudsonghudson KRB5_LRQ_ALL_LAST_TGT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_CLIENT_INFO.html0000664000175000017500000001675315051422704023516 0ustar ghudsonghudson KRB5_PAC_CLIENT_INFO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_xc.html0000664000175000017500000001646015051422712022006 0ustar ghudsonghudson krb5_xc — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ONE_ACCT_EXPTIME.html0000664000175000017500000001673715051422703024367 0ustar ghudsonghudson KRB5_LRQ_ONE_ACCT_EXPTIME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/MSEC_VAL_MASK.html0000664000175000017500000001641715051422710022515 0ustar ghudsonghudson MSEC_VAL_MASK — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CRYPTO_TYPE_SIGN_ONLY.html0000664000175000017500000001707415051422700024575 0ustar ghudsonghudson KRB5_CRYPTO_TYPE_SIGN_ONLY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ONE_LAST_RENEWAL.html0000664000175000017500000001701715051422703024372 0ustar ghudsonghudson KRB5_LRQ_ONE_LAST_RENEWAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GC_USER_USER.html0000664000175000017500000001701615051422700023214 0ustar ghudsonghudson KRB5_GC_USER_USER — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_POSTDATED.html0000664000175000017500000001656515051422711023217 0ustar ghudsonghudson TKT_FLG_POSTDATED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES128.html0000664000175000017500000001730115051422675024645 0ustar ghudsonghudson CKSUMTYPE_HMAC_SHA1_96_AES128 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_ENC_TIMESTAMP.html0000664000175000017500000001712315051422705024275 0ustar ghudsonghudson KRB5_PADATA_ENC_TIMESTAMP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_ADDRPORT.html0000664000175000017500000001644615051422674023177 0ustar ghudsonghudson ADDRTYPE_ADDRPORT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_AP_OPTIONS.html0000664000175000017500000001701415051422677024230 0ustar ghudsonghudson KRB5_AUTHDATA_AP_OPTIONS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_KRB_ERROR_CKSUM.html0000664000175000017500000001723115051422702025056 0ustar ghudsonghudson KRB5_KEYUSAGE_KRB_ERROR_CKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_PRIVSVR_CHECKSUM.html0000664000175000017500000001675315051422704024362 0ustar ghudsonghudson KRB5_PAC_PRIVSVR_CHECKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_FAST_ENC.html0000664000175000017500000001705315051422702023751 0ustar ghudsonghudson KRB5_KEYUSAGE_FAST_ENC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_ENC_SANDIA_SECURID.html0000664000175000017500000001726715051422705025060 0ustar ghudsonghudson KRB5_PADATA_ENC_SANDIA_SECURID — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_AS_CHECKSUM.html0000664000175000017500000001675615051422704024044 0ustar ghudsonghudson KRB5_PADATA_AS_CHECKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_ANONYMOUS_PRINCSTR.html0000664000175000017500000001715515051422677024164 0ustar ghudsonghudson KRB5_ANONYMOUS_PRINCSTR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CRYPTO_TYPE_STREAM.html0000664000175000017500000001715315051422700024165 0ustar ghudsonghudson KRB5_CRYPTO_TYPE_STREAM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_IF_RELEVANT.html0000664000175000017500000001711015051422677024310 0ustar ghudsonghudson KRB5_AUTHDATA_IF_RELEVANT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_REQUIRE_REALM.html0000664000175000017500000001740015051422706025621 0ustar ghudsonghudson KRB5_PRINCIPAL_PARSE_REQUIRE_REALM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT_ISSUED.html0000664000175000017500000001705515051422703025011 0ustar ghudsonghudson KRB5_LRQ_ONE_LAST_TGT_ISSUED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_FORWARDABLE.html0000664000175000017500000001663515051422676023421 0ustar ghudsonghudson KDC_OPT_FORWARDABLE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_MATCH_FLAGS_EXACT.html0000664000175000017500000001703215051422707024316 0ustar ghudsonghudson KRB5_TC_MATCH_FLAGS_EXACT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_MS_PRINCIPAL_AND_ID.html0000664000175000017500000001701515051422704024611 0ustar ghudsonghudson KRB5_NT_MS_PRINCIPAL_AND_ID — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GC_NO_TRANSIT_CHECK.html0000664000175000017500000001672115051422700024217 0ustar ghudsonghudson KRB5_GC_NO_TRANSIT_CHECK — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TGS_REP.html0000664000175000017500000001644715051422710022402 0ustar ghudsonghudson KRB5_TGS_REP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_AUTH_INDICATOR.html0000664000175000017500000001705315051422677024655 0ustar ghudsonghudson KRB5_AUTHDATA_AUTH_INDICATOR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_FX_ARMOR.html0000664000175000017500000001703715051422677023777 0ustar ghudsonghudson KRB5_AUTHDATA_FX_ARMOR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_RSA_MD4.html0000664000175000017500000001656715051422675023226 0ustar ghudsonghudson CKSUMTYPE_RSA_MD4 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GC_FORWARDABLE.html0000664000175000017500000001673515051422700023337 0ustar ghudsonghudson KRB5_GC_FORWARDABLE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID.html0000664000175000017500000001746515051422702026241 0ustar ghudsonghudson KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_CAMMAC.html0000664000175000017500000001702515051422677023440 0ustar ghudsonghudson KRB5_AUTHDATA_CAMMAC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_SVR_REFERRAL_INFO.html0000664000175000017500000001715615051422706025023 0ustar ghudsonghudson KRB5_PADATA_SVR_REFERRAL_INFO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_MATCH_SRV_NAMEONLY.html0000664000175000017500000001706215051422710024507 0ustar ghudsonghudson KRB5_TC_MATCH_SRV_NAMEONLY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_NO_REALM.html0000664000175000017500000001734615051422706025032 0ustar ghudsonghudson KRB5_PRINCIPAL_PARSE_NO_REALM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_KRB_CRED_ENCPART.html0000664000175000017500000001722515051422702025117 0ustar ghudsonghudson KRB5_KEYUSAGE_KRB_CRED_ENCPART — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GC_CACHED.html0000664000175000017500000001654215051422700022512 0ustar ghudsonghudson KRB5_GC_CACHED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AP_OPTS_CBT_FLAG.html0000664000175000017500000001705115051422674023103 0ustar ghudsonghudson AP_OPTS_CBT_FLAG — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN.html0000664000175000017500000002031415051422707026222 0ustar ghudsonghudson KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN — MIT Kerberos Documentation

KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN¶

KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN¶

This flag indicates that the PIN MUST be returned as a separate item.

This flag only takes effect if KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN is set. If this flag is not set, the responder may either concatenate PIN + token value and store it as “value†in the answer or it may return them separately. If they are returned separately, they will be concatenated internally.

KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN

0x0008

krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_REFERRAL_REALM.html0000664000175000017500000001725015051422707023360 0ustar ghudsonghudson KRB5_REFERRAL_REALM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_WELLKNOWN.html0000664000175000017500000001661615051422704023221 0ustar ghudsonghudson KRB5_NT_WELLKNOWN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_DEVICE_INFO.html0000664000175000017500000001670415051422704023473 0ustar ghudsonghudson KRB5_PAC_DEVICE_INFO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_INVALID.html0000664000175000017500000001650715051422711022752 0ustar ghudsonghudson TKT_FLG_INVALID — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_S4U_X509_USER.html0000664000175000017500000001706715051422706024253 0ustar ghudsonghudson KRB5_PADATA_S4U_X509_USER — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CRYPTO_TYPE_EMPTY.html0000664000175000017500000001675215051422700024074 0ustar ghudsonghudson KRB5_CRYPTO_TYPE_EMPTY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_FORWARDED.html0000664000175000017500000001655115051422676023203 0ustar ghudsonghudson KDC_OPT_FORWARDED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_OPENCLOSE.html0000664000175000017500000001667215051422710023154 0ustar ghudsonghudson KRB5_TC_OPENCLOSE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_OSF_DCE.html0000664000175000017500000001667215051422705023357 0ustar ghudsonghudson KRB5_PADATA_OSF_DCE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN.html0000664000175000017500000001761615051422707026350 0ustar ghudsonghudson KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AD_SIGNEDPATH.html0000664000175000017500000001706615051422701024524 0ustar ghudsonghudson KRB5_KEYUSAGE_AD_SIGNEDPATH — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_CMAC_CAMELLIA256.html0000664000175000017500000001702215051422675024307 0ustar ghudsonghudson CKSUMTYPE_CMAC_CAMELLIA256 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST.html0000664000175000017500000001730315051422701026133 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_RENEW.html0000664000175000017500000001641515051422676022545 0ustar ghudsonghudson KDC_OPT_RENEW — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_ENC_UNIX_TIME.html0000664000175000017500000001710515051422705024333 0ustar ghudsonghudson KRB5_PADATA_ENC_UNIX_TIME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_AES256_CTS_HMAC_SHA384_192.html0000664000175000017500000001727615051422675025351 0ustar ghudsonghudson ENCTYPE_AES256_CTS_HMAC_SHA384_192 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_PAC_REQUEST.html0000664000175000017500000001700115051422705024053 0ustar ghudsonghudson KRB5_PADATA_PAC_REQUEST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_OSF_DCE.html0000664000175000017500000001676315051422677023631 0ustar ghudsonghudson KRB5_AUTHDATA_OSF_DCE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_TIME.html0000664000175000017500000001722315051422700024524 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_RET_TIME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_FORWARDABLE.html0000664000175000017500000001745515051422701025753 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_FORWARDABLE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_SRV_HST.html0000664000175000017500000001656015051422704023027 0ustar ghudsonghudson KRB5_NT_SRV_HST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_CAMELLIA256_CTS_CMAC.html0000664000175000017500000001713015051422676024544 0ustar ghudsonghudson ENCTYPE_CAMELLIA256_CTS_CMAC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_VALIDATE.html0000664000175000017500000001661315051422676023056 0ustar ghudsonghudson KDC_OPT_VALIDATE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_REQUESTOR.html0000664000175000017500000001672715051422704023317 0ustar ghudsonghudson KRB5_PAC_REQUESTOR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_KRB_PRIV_ENCPART.html0000664000175000017500000001722515051422702025162 0ustar ghudsonghudson KRB5_KEYUSAGE_KRB_PRIV_ENCPART — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_CANONICALIZE.html0000664000175000017500000001672515051422676023530 0ustar ghudsonghudson KDC_OPT_CANONICALIZE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_CLIENT_CLAIMS.html0000664000175000017500000001677715051422704023741 0ustar ghudsonghudson KRB5_PAC_CLIENT_CLAIMS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_SMTP_NAME.html0000664000175000017500000001656015051422704023222 0ustar ghudsonghudson KRB5_NT_SMTP_NAME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_ANONYMOUS_REALMSTR.html0000664000175000017500000001673615051422677024155 0ustar ghudsonghudson KRB5_ANONYMOUS_REALMSTR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE_2.html0000664000175000017500000001714215051422706024452 0ustar ghudsonghudson KRB5_PADATA_SAM_CHALLENGE_2 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_SHORT.html0000664000175000017500000001710015051422706024724 0ustar ghudsonghudson KRB5_PRINCIPAL_UNPARSE_SHORT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ONE_LAST_REQ.html0000664000175000017500000001672715051422703023733 0ustar ghudsonghudson KRB5_LRQ_ONE_LAST_REQ — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_MD5_HMAC_ARCFOUR.html0000664000175000017500000001720215051422675024456 0ustar ghudsonghudson CKSUMTYPE_MD5_HMAC_ARCFOUR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_INIT_CONTEXT_KDC.html0000664000175000017500000001711115051422701023654 0ustar ghudsonghudson KRB5_INIT_CONTEXT_KDC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/SALT_TYPE_AFS_LENGTH.html0000664000175000017500000001657115051422710023610 0ustar ghudsonghudson SALT_TYPE_AFS_LENGTH — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AP_OPTS_USE_SUBKEY.html0000664000175000017500000001675415051422675023432 0ustar ghudsonghudson AP_OPTS_USE_SUBKEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_CASEFOLD.html0000664000175000017500000001733615051422706025171 0ustar ghudsonghudson KRB5_PRINCIPAL_COMPARE_CASEFOLD — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_ETYPE_NEGOTIATION.html0000664000175000017500000001713315051422677025245 0ustar ghudsonghudson KRB5_AUTHDATA_ETYPE_NEGOTIATION — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_PAC_OPTIONS.html0000664000175000017500000001701515051422705024063 0ustar ghudsonghudson KRB5_PADATA_PAC_OPTIONS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_INT32_MIN.html0000664000175000017500000001647415051422701022541 0ustar ghudsonghudson KRB5_INT32_MIN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_SPAKE.html0000664000175000017500000001706115051422703023372 0ustar ghudsonghudson KRB5_KEYUSAGE_SPAKE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CRYPTO_TYPE_CHECKSUM.html0000664000175000017500000001671215051422700024374 0ustar ghudsonghudson KRB5_CRYPTO_TYPE_CHECKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_MATCH_IS_SKEY.html0000664000175000017500000001677615051422710023714 0ustar ghudsonghudson KRB5_TC_MATCH_IS_SKEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_DES3.html0000664000175000017500000001711315051422675024163 0ustar ghudsonghudson CKSUMTYPE_HMAC_SHA1_DES3 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ONE_PW_EXPTIME.html0000664000175000017500000001705715051422703024177 0ustar ghudsonghudson KRB5_LRQ_ONE_PW_EXPTIME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ALL_LAST_RENEWAL.html0000664000175000017500000001701415051422703024356 0ustar ghudsonghudson KRB5_LRQ_ALL_LAST_RENEWAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ONE_LAST_TGT.html0000664000175000017500000001675115051422703023737 0ustar ghudsonghudson KRB5_LRQ_ONE_LAST_TGT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_princ_set_realm.html0000664000175000017500000001713215051422711024536 0ustar ghudsonghudson krb5_princ_set_realm — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_UNKNOWN.html0000664000175000017500000001646015051422704022775 0ustar ghudsonghudson KRB5_NT_UNKNOWN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_INITIAL_VERIFIED_CAS.html0000664000175000017500000001723415051422677025555 0ustar ghudsonghudson KRB5_AUTHDATA_INITIAL_VERIFIED_CAS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_CAMMAC.html0000664000175000017500000001706315051422701023450 0ustar ghudsonghudson KRB5_KEYUSAGE_CAMMAC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED.html0000664000175000017500000002033015051422707030107 0ustar ghudsonghudson KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_PW_SALT.html0000664000175000017500000001670315051422706023422 0ustar ghudsonghudson KRB5_PADATA_PW_SALT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM.html0000664000175000017500000001711315051422701025347 0ustar ghudsonghudson KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_ANONYMOUS.html0000664000175000017500000001652115051422710023247 0ustar ghudsonghudson TKT_FLG_ANONYMOUS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CRYPTO_TYPE_TRAILER.html0000664000175000017500000001704015051422700024267 0ustar ghudsonghudson KRB5_CRYPTO_TYPE_TRAILER — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_OTP_REQUEST.html0000664000175000017500000001704115051422705024116 0ustar ghudsonghudson KRB5_PADATA_OTP_REQUEST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_DDP.html0000664000175000017500000001641515051422674022363 0ustar ghudsonghudson ADDRTYPE_DDP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST.html0000664000175000017500000001745315051422701025742 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_ENTERPRISE_PRINCIPAL.html0000664000175000017500000001715615051422704024722 0ustar ghudsonghudson KRB5_NT_ENTERPRISE_PRINCIPAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE.html0000664000175000017500000001735115051422701025675 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_SAFE.html0000664000175000017500000001666215051422707021762 0ustar ghudsonghudson KRB5_SAFE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_ANONYMOUS.html0000664000175000017500000001743515051422701025611 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_ANONYMOUS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_AND_OR.html0000664000175000017500000001660415051422677023523 0ustar ghudsonghudson KRB5_AUTHDATA_AND_OR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_INT16_MAX.html0000664000175000017500000001660215051422701022536 0ustar ghudsonghudson KRB5_INT16_MAX — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG.html0000664000175000017500000001725315051422702025461 0ustar ghudsonghudson KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_MATCH_KTYPE.html0000664000175000017500000001676215051422710023435 0ustar ghudsonghudson KRB5_TC_MATCH_KTYPE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DES_CBC_MD4.html0000664000175000017500000001661515051422676023401 0ustar ghudsonghudson ENCTYPE_DES_CBC_MD4 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AS_REQ.html0000664000175000017500000001644615051422677022264 0ustar ghudsonghudson KRB5_AS_REQ — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_KDC_ISSUED.html0000664000175000017500000001716015051422677024174 0ustar ghudsonghudson KRB5_AUTHDATA_KDC_ISSUED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AP_REP.html0000664000175000017500000001646715051422677022263 0ustar ghudsonghudson KRB5_AP_REP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_SEQUENCE.html0000664000175000017500000001720715051422677025065 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_DO_SEQUENCE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY.html0000664000175000017500000001746015051422703026133 0ustar ghudsonghudson KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CRYPTO_TYPE_HEADER.html0000664000175000017500000001700415051422700024115 0ustar ghudsonghudson KRB5_CRYPTO_TYPE_HEADER — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_SUPPORTED_KTYPES.html0000664000175000017500000001672215051422710024305 0ustar ghudsonghudson KRB5_TC_SUPPORTED_KTYPES — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_RSA_ES_OAEP_ENV.html0000664000175000017500000001674515051422676024207 0ustar ghudsonghudson ENCTYPE_RSA_ES_OAEP_ENV — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ALL_LAST_INITIAL.html0000664000175000017500000001704415051422703024355 0ustar ghudsonghudson KRB5_LRQ_ALL_LAST_INITIAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CRYPTO_TYPE_DATA.html0000664000175000017500000001676515051422700023713 0ustar ghudsonghudson KRB5_CRYPTO_TYPE_DATA — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_DOMAIN_X500_COMPRESS.html0000664000175000017500000001712115051422700024222 0ustar ghudsonghudson KRB5_DOMAIN_X500_COMPRESS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DES3_CBC_RAW.html0000664000175000017500000001664715051422676023536 0ustar ghudsonghudson ENCTYPE_DES3_CBC_RAW — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR.html0000664000175000017500000001754615051422677026177 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_OTP_CHALLENGE.html0000664000175000017500000001704515051422705024254 0ustar ghudsonghudson KRB5_PADATA_OTP_CHALLENGE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL.html0000664000175000017500000001741015051422707026153 0ustar ghudsonghudson KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_CREDENTIALS_INFO.html0000664000175000017500000001705415051422704024270 0ustar ghudsonghudson KRB5_PAC_CREDENTIALS_INFO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_PKINIT_KX.html0000664000175000017500000001673315051422705023653 0ustar ghudsonghudson KRB5_PADATA_PKINIT_KX — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_ENTERPRISE.html0000664000175000017500000001742415051422706025467 0ustar ghudsonghudson KRB5_PRINCIPAL_COMPARE_ENTERPRISE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_PA_OTP_REQUEST.html0000664000175000017500000001717415051422702024765 0ustar ghudsonghudson KRB5_KEYUSAGE_PA_OTP_REQUEST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_SAM_SEND_ENCRYPTED_SAD.html0000664000175000017500000001711715051422707024575 0ustar ghudsonghudson KRB5_SAM_SEND_ENCRYPTED_SAD — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_IPPORT.html0000664000175000017500000001641515051422674022771 0ustar ghudsonghudson ADDRTYPE_IPPORT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_MATCH_AUTHDATA.html0000664000175000017500000001676115051422707023741 0ustar ghudsonghudson KRB5_TC_MATCH_AUTHDATA — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_MATCH_TIMES_EXACT.html0000664000175000017500000001700215051422710024332 0ustar ghudsonghudson KRB5_TC_MATCH_TIMES_EXACT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AD_ITE.html0000664000175000017500000001670715051422701023520 0ustar ghudsonghudson KRB5_KEYUSAGE_AD_ITE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AS_REP_ENCPART.html0000664000175000017500000001712415051422701024712 0ustar ghudsonghudson KRB5_KEYUSAGE_AS_REP_ENCPART — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_HMAC_MD5_ARCFOUR.html0000664000175000017500000001705015051422675024457 0ustar ghudsonghudson CKSUMTYPE_HMAC_MD5_ARCFOUR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KPASSWD_MALFORMED.html0000664000175000017500000001705415051422703023736 0ustar ghudsonghudson KRB5_KPASSWD_MALFORMED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AP_REP_ENCPART.html0000664000175000017500000001715515051422701024713 0ustar ghudsonghudson KRB5_KEYUSAGE_AP_REP_ENCPART — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_CHAOS.html0000664000175000017500000001650115051422674022605 0ustar ghudsonghudson ADDRTYPE_CHAOS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CYBERSAFE_SECUREID.html0000664000175000017500000001704415051422700024016 0ustar ghudsonghudson KRB5_CYBERSAFE_SECUREID — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV.html0000664000175000017500000001722115051422702025366 0ustar ghudsonghudson KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AD_TYPE_REGISTERED.html0000664000175000017500000001660515051422674023323 0ustar ghudsonghudson AD_TYPE_REGISTERED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL.html0000664000175000017500000001743115051422710026641 0ustar ghudsonghudson KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH.html0000664000175000017500000001720015051422703024507 0ustar ghudsonghudson KRB5_KEYUSAGE_TGS_REQ_AUTH — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_ARCFOUR_HMAC_EXP.html0000664000175000017500000001704015051422675024250 0ustar ghudsonghudson ENCTYPE_ARCFOUR_HMAC_EXP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_GET_FROM_TYPED_DATA.html0000664000175000017500000001711615051422705025247 0ustar ghudsonghudson KRB5_PADATA_GET_FROM_TYPED_DATA — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_KRB_SAFE_CKSUM.html0000664000175000017500000001720515051422702024704 0ustar ghudsonghudson KRB5_KEYUSAGE_KRB_SAFE_CKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_INET.html0000664000175000017500000001636115051422674022513 0ustar ghudsonghudson ADDRTYPE_INET — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_AES128_CTS_HMAC_SHA1_96.html0000664000175000017500000001720215051422675025101 0ustar ghudsonghudson ENCTYPE_AES128_CTS_HMAC_SHA1_96 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_MD5_RSA_CMS.html0000664000175000017500000001661515051422676023447 0ustar ghudsonghudson ENCTYPE_MD5_RSA_CMS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_TKT_COMMON_MASK.html0000664000175000017500000001673715051422676023477 0ustar ghudsonghudson KDC_TKT_COMMON_MASK — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_PA_PKINIT_KX.html0000664000175000017500000001720715051422702024510 0ustar ghudsonghudson KRB5_KEYUSAGE_PA_PKINIT_KX — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KPASSWD_BAD_VERSION.html0000664000175000017500000001701615051422703024221 0ustar ghudsonghudson KRB5_KPASSWD_BAD_VERSION — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_DECIMAL.html0000664000175000017500000001756015051422707025513 0ustar ghudsonghudson KRB5_RESPONDER_OTP_FORMAT_DECIMAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_UNIXSOCK.html0000664000175000017500000001656215051422674023222 0ustar ghudsonghudson ADDRTYPE_UNIXSOCK — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_INT16_MIN.html0000664000175000017500000001643015051422701022533 0ustar ghudsonghudson KRB5_INT16_MIN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN.html0000664000175000017500000001736015051422707026054 0ustar ghudsonghudson KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_INIT_CONTEXT_SECURE.html0000664000175000017500000001712315051422701024244 0ustar ghudsonghudson KRB5_INIT_CONTEXT_SECURE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_FAST_FINISHED.html0000664000175000017500000001703515051422702024535 0ustar ghudsonghudson KRB5_KEYUSAGE_FAST_FINISHED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AS_REP.html0000664000175000017500000001635015051422677022255 0ustar ghudsonghudson KRB5_AS_REP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_SAM_RESPONSE.html0000664000175000017500000001704715051422706024211 0ustar ghudsonghudson KRB5_PADATA_SAM_RESPONSE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_FULL_CHECKSUM.html0000664000175000017500000001674515051422704023752 0ustar ghudsonghudson KRB5_PAC_FULL_CHECKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_IAKERB_FINISHED.html0000664000175000017500000001713515051422702024736 0ustar ghudsonghudson KRB5_KEYUSAGE_IAKERB_FINISHED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KPASSWD_AUTHERROR.html0000664000175000017500000001702115051422703023775 0ustar ghudsonghudson KRB5_KPASSWD_AUTHERROR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_ALLOW_POSTDATE.html0000664000175000017500000001665115051422676024050 0ustar ghudsonghudson KDC_OPT_ALLOW_POSTDATE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_princ_set_realm_length.html0000664000175000017500000001727215051422711026104 0ustar ghudsonghudson krb5_princ_set_realm_length — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_GSS_TOK_MIC.html0000664000175000017500000001714715051422702024374 0ustar ghudsonghudson KRB5_KEYUSAGE_GSS_TOK_MIC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_PROXIABLE.html0000664000175000017500000001647715051422711023217 0ustar ghudsonghudson TKT_FLG_PROXIABLE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_NOTICKET.html0000664000175000017500000001657715051422710023051 0ustar ghudsonghudson KRB5_TC_NOTICKET — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_APP_DATA_CKSUM.html0000664000175000017500000001717115051422701024702 0ustar ghudsonghudson KRB5_KEYUSAGE_APP_DATA_CKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_ENC_TKT_IN_SKEY.html0000664000175000017500000001702115051422676024227 0ustar ghudsonghudson KDC_OPT_ENC_TKT_IN_SKEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_SERVER_CHECKSUM.html0000664000175000017500000001677615051422704024222 0ustar ghudsonghudson KRB5_PAC_SERVER_CHECKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_NETBIOS.html0000664000175000017500000001645515051422674023063 0ustar ghudsonghudson ADDRTYPE_NETBIOS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_princ_type.html0000664000175000017500000001654015051422711023546 0ustar ghudsonghudson krb5_princ_type — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_REFERRAL.html0000664000175000017500000001673015051422706023453 0ustar ghudsonghudson KRB5_PADATA_REFERRAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KPASSWD_SUCCESS.html0000664000175000017500000001673415051422703023544 0ustar ghudsonghudson KRB5_KPASSWD_SUCCESS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST.html0000664000175000017500000001753715051422702026324 0ustar ghudsonghudson KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_RENEWABLE.html0000664000175000017500000001652715051422676023175 0ustar ghudsonghudson KDC_OPT_RENEWABLE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_princ_set_realm_data.html0000664000175000017500000001730615051422711025532 0ustar ghudsonghudson krb5_princ_set_realm_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KPASSWD_INITIAL_FLAG_NEEDED.html0000664000175000017500000001726015051422703025315 0ustar ghudsonghudson KRB5_KPASSWD_INITIAL_FLAG_NEEDED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_FORWARDED.html0000664000175000017500000001653515051422710023201 0ustar ghudsonghudson TKT_FLG_FORWARDED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PROMPT_TYPE_PREAUTH.html0000664000175000017500000001677015051422707024316 0ustar ghudsonghudson KRB5_PROMPT_TYPE_PREAUTH — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/LR_TYPE_THIS_SERVER_ONLY.html0000664000175000017500000001700315051422710024375 0ustar ghudsonghudson LR_TYPE_THIS_SERVER_ONLY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT.html0000664000175000017500000001725115051422702025534 0ustar ghudsonghudson KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_UPN_DNS_INFO.html0000664000175000017500000001677615051422704023713 0ustar ghudsonghudson KRB5_PAC_UPN_DNS_INFO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RECVAUTH_BADAUTHVERS.html0000664000175000017500000001703515051422707024310 0ustar ghudsonghudson KRB5_RECVAUTH_BADAUTHVERS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TKT_CREDS_STEP_FLAG_CONTINUE.html0000664000175000017500000001730015051422710025536 0ustar ghudsonghudson KRB5_TKT_CREDS_STEP_FLAG_CONTINUE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR.html0000664000175000017500000001774115051422700026320 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TGS_REQ.html0000664000175000017500000001661015051422710022373 0ustar ghudsonghudson KRB5_TGS_REQ — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_FX_FAST.html0000664000175000017500000001675115051422705023405 0ustar ghudsonghudson KRB5_PADATA_FX_FAST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_RENEWABLE.html0000664000175000017500000001662315051422711023167 0ustar ghudsonghudson TKT_FLG_RENEWABLE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_REDHAT_IDP_OAUTH2.html0000664000175000017500000001712215051422706024732 0ustar ghudsonghudson KRB5_PADATA_REDHAT_IDP_OAUTH2 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_SRV_INST.html0000664000175000017500000001654615051422704023152 0ustar ghudsonghudson KRB5_NT_SRV_INST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_PRE_AUTH.html0000664000175000017500000001651715051422711023134 0ustar ghudsonghudson TKT_FLG_PRE_AUTH — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ALL_LAST_REQ.html0000664000175000017500000001672415051422703023717 0ustar ghudsonghudson KRB5_LRQ_ALL_LAST_REQ — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_FX_COOKIE.html0000664000175000017500000001670315051422705023616 0ustar ghudsonghudson KRB5_PADATA_FX_COOKIE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AD_TYPE_FIELD_TYPE_MASK.html0000664000175000017500000001665515051422674024172 0ustar ghudsonghudson AD_TYPE_FIELD_TYPE_MASK — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_QUESTION_OTP.html0000664000175000017500000002773715051422707024663 0ustar ghudsonghudson KRB5_RESPONDER_QUESTION_OTP — MIT Kerberos Documentation

KRB5_RESPONDER_QUESTION_OTP¶

KRB5_RESPONDER_QUESTION_OTP¶

OTP responder question.

The OTP responder question is asked when the KDC indicates that an OTP value is required in order to complete the authentication. The JSON format of the challenge is:

{
  "service": <string (optional)>,
  "tokenInfo": [
    {
      "flags":     <number>,
      "vendor":    <string (optional)>,
      "challenge": <string (optional)>,
      "length":    <number (optional)>,
      "format":    <number (optional)>,
      "tokenID":   <string (optional)>,
      "algID":     <string (optional)>,
    },
    ...
  ]
}

The answer to the question MUST be JSON formatted:

{
  "tokeninfo": <number>,
  "value":     <string (optional)>,
  "pin":       <string (optional)>,
}

For more detail, please see RFC 6560.

KRB5_RESPONDER_QUESTION_OTP

"otp"

krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_TICKET_CHECKSUM.html0000664000175000017500000001702115051422704024157 0ustar ghudsonghudson KRB5_PAC_TICKET_CHECKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_FAST_REQUIRED.html0000664000175000017500000001651715051422700023271 0ustar ghudsonghudson KRB5_FAST_REQUIRED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_REALM_BRANCH_CHAR.html0000664000175000017500000001663415051422707023715 0ustar ghudsonghudson KRB5_REALM_BRANCH_CHAR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_ENCPADATA_REQ_ENC_PA_REP.html0000664000175000017500000001702515051422700024771 0ustar ghudsonghudson KRB5_ENCPADATA_REQ_ENC_PA_REP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM.html0000664000175000017500000001721415051422703025456 0ustar ghudsonghudson KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_PK_AS_REQ.html0000664000175000017500000001701415051422705023650 0ustar ghudsonghudson KRB5_PADATA_PK_AS_REQ — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KPASSWD_ACCESSDENIED.html0000664000175000017500000001712315051422703024237 0ustar ghudsonghudson KRB5_KPASSWD_ACCESSDENIED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_SRV_XHST.html0000664000175000017500000001651615051422704023160 0ustar ghudsonghudson KRB5_NT_SRV_XHST — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY.html0000664000175000017500000001742315051422702026061 0ustar ghudsonghudson KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_const.html0000664000175000017500000001637415051422711022525 0ustar ghudsonghudson krb5_const — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GC_NO_STORE.html0000664000175000017500000001664515051422700023077 0ustar ghudsonghudson KRB5_GC_NO_STORE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CANONICALIZE.html0000664000175000017500000001747315051422701026062 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_CANONICALIZE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_WELLKNOWN_NAMESTR.html0000664000175000017500000001724715051422710024007 0ustar ghudsonghudson KRB5_WELLKNOWN_NAMESTR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_CRC32.html0000664000175000017500000001655515051422675022706 0ustar ghudsonghudson CKSUMTYPE_CRC32 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_NEXTOTP.html0000664000175000017500000001771615051422707025465 0ustar ghudsonghudson KRB5_RESPONDER_OTP_FLAGS_NEXTOTP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TGS_NAME_SIZE.html0000664000175000017500000001645415051422710023324 0ustar ghudsonghudson KRB5_TGS_NAME_SIZE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DES_CBC_CRC.html0000664000175000017500000001663115051422676023422 0ustar ghudsonghudson ENCTYPE_DES_CBC_CRC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT.html0000664000175000017500000001751115051422701026311 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY.html0000664000175000017500000002055715051422707030550 0ustar ghudsonghudson KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_UID.html0000664000175000017500000001640015051422704022251 0ustar ghudsonghudson KRB5_NT_UID — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_RENEWABLE_OK.html0000664000175000017500000001666715051422676023573 0ustar ghudsonghudson KDC_OPT_RENEWABLE_OK — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PROMPT_TYPE_NEW_PASSWORD.html0000664000175000017500000001716215051422707025155 0ustar ghudsonghudson KRB5_PROMPT_TYPE_NEW_PASSWORD — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_QUESTION_PKINIT.html0000664000175000017500000002303115051422707025176 0ustar ghudsonghudson KRB5_RESPONDER_QUESTION_PKINIT — MIT Kerberos Documentation

KRB5_RESPONDER_QUESTION_PKINIT¶

KRB5_RESPONDER_QUESTION_PKINIT¶

PKINIT responder question.

The PKINIT responder question is asked when the client needs a password that’s being used to protect key information, and is formatted as a JSON object. A specific identity’s flags value, if not zero, is the bitwise-OR of one or more of the KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_* flags defined below, and possibly other flags to be added later. Any resemblance to similarly-named CKF_* values in the PKCS#11 API should not be depended on.

{
    identity <string> : flags <number>,
    ...
}

The answer to the question MUST be JSON formatted:

{
    identity <string> : password <string>,
    ...
}

KRB5_RESPONDER_QUESTION_PKINIT

"pkinit"

krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_AFS3_SALT.html0000664000175000017500000001672615051422704023573 0ustar ghudsonghudson KRB5_PADATA_AFS3_SALT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_RET_SEQUENCE.html0000664000175000017500000001727115051422700025201 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_RET_SEQUENCE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_TKT_LIFE.html0000664000175000017500000001722715051422701025461 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_TKT_LIFE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AP_OPTS_RESERVED.html0000664000175000017500000001662715051422675023132 0ustar ghudsonghudson AP_OPTS_RESERVED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_PK_AS_REP_OLD.html0000664000175000017500000001700415051422705024344 0ustar ghudsonghudson KRB5_PADATA_PK_AS_REP_OLD — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KPASSWD_HARDERROR.html0000664000175000017500000001706315051422703023760 0ustar ghudsonghudson KRB5_KPASSWD_HARDERROR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_UNPARSE_DISPLAY.html0000664000175000017500000001736015051422706025142 0ustar ghudsonghudson KRB5_PRINCIPAL_UNPARSE_DISPLAY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_FORWARDABLE.html0000664000175000017500000001657715051422710023422 0ustar ghudsonghudson TKT_FLG_FORWARDABLE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_FAST_REP.html0000664000175000017500000001703715051422702023774 0ustar ghudsonghudson KRB5_KEYUSAGE_FAST_REP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AP_OPTS_USE_SESSION_KEY.html0000664000175000017500000001671115051422675024254 0ustar ghudsonghudson AP_OPTS_USE_SESSION_KEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_REDHAT_PASSKEY.html0000664000175000017500000001720615051422706024416 0ustar ghudsonghudson KRB5_PADATA_REDHAT_PASSKEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_NONE.html0000664000175000017500000001664615051422705023015 0ustar ghudsonghudson KRB5_PADATA_NONE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_PROXY.html0000664000175000017500000001641515051422676022606 0ustar ghudsonghudson KDC_OPT_PROXY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AP_OPTS_ETYPE_NEGOTIATION.html0000664000175000017500000001670115051422674024431 0ustar ghudsonghudson AP_OPTS_ETYPE_NEGOTIATION — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_UTF8.html0000664000175000017500000001730115051422706024527 0ustar ghudsonghudson KRB5_PRINCIPAL_COMPARE_UTF8 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_OK_AS_DELEGATE.html0000664000175000017500000001666515051422711024017 0ustar ghudsonghudson TKT_FLG_OK_AS_DELEGATE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ALL_ACCT_EXPTIME.html0000664000175000017500000001700615051422703024344 0ustar ghudsonghudson KRB5_LRQ_ALL_ACCT_EXPTIME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AD_MTE.html0000664000175000017500000001702515051422701023516 0ustar ghudsonghudson KRB5_KEYUSAGE_AD_MTE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM.html0000664000175000017500000001721315051422701025316 0ustar ghudsonghudson KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_SAM_CHALLENGE.html0000664000175000017500000001710115051422706024224 0ustar ghudsonghudson KRB5_PADATA_SAM_CHALLENGE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_RSA_MD5_DES.html0000664000175000017500000001657715051422675023723 0ustar ghudsonghudson CKSUMTYPE_RSA_MD5_DES — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_TRANSIT_POLICY_CHECKED.html0000664000175000017500000001700115051422711025163 0ustar ghudsonghudson TKT_FLG_TRANSIT_POLICY_CHECKED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW.html0000664000175000017500000002033115051422707030560 0ustar ghudsonghudson KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AD_TYPE_RESERVED.html0000664000175000017500000001660115051422674023101 0ustar ghudsonghudson AD_TYPE_RESERVED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_QUESTION_PASSWORD.html0000664000175000017500000001737415051422707025457 0ustar ghudsonghudson KRB5_RESPONDER_QUESTION_PASSWORD — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_DO_TIME.html0000664000175000017500000001730615051422677024413 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_DO_TIME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_WIN2K_PAC.html0000664000175000017500000001703415051422677024034 0ustar ghudsonghudson KRB5_AUTHDATA_WIN2K_PAC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_ATTRIBUTES_INFO.html0000664000175000017500000001677615051422704024233 0ustar ghudsonghudson KRB5_PAC_ATTRIBUTES_INFO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_SAM_REDIRECT.html0000664000175000017500000001707515051422706024155 0ustar ghudsonghudson KRB5_PADATA_SAM_REDIRECT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_MAY_POSTDATE.html0000664000175000017500000001663115051422711023613 0ustar ghudsonghudson TKT_FLG_MAY_POSTDATE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AP_REQ.html0000664000175000017500000001636015051422677022254 0ustar ghudsonghudson KRB5_AP_REQ — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_ENT_PRINCIPAL_AND_ID.html0000664000175000017500000001714515051422704024724 0ustar ghudsonghudson KRB5_NT_ENT_PRINCIPAL_AND_ID — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_PA_SAM_RESPONSE.html0000664000175000017500000001720715051422702025046 0ustar ghudsonghudson KRB5_KEYUSAGE_PA_SAM_RESPONSE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_TC_MATCH_2ND_TKT.html0000664000175000017500000001677415051422707023657 0ustar ghudsonghudson KRB5_TC_MATCH_2ND_TKT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_ISO.html0000664000175000017500000001640715051422674022407 0ustar ghudsonghudson ADDRTYPE_ISO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRIV.html0000664000175000017500000001664315051422706022022 0ustar ghudsonghudson KRB5_PRIV — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_TGS_REQ.html0000664000175000017500000001702715051422706023415 0ustar ghudsonghudson KRB5_PADATA_TGS_REQ — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GET_INIT_CREDS_OPT_PROXIABLE.html0000664000175000017500000001742115051422701025541 0ustar ghudsonghudson KRB5_GET_INIT_CREDS_OPT_PROXIABLE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/krb5_princ_name.html0000664000175000017500000001662615051422711023512 0ustar ghudsonghudson krb5_princ_name — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE.html0000664000175000017500000001724715051422676025743 0ustar ghudsonghudson KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_ENC_PA_REP.html0000664000175000017500000001656715051422710023364 0ustar ghudsonghudson TKT_FLG_ENC_PA_REP — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_SIGNTICKET.html0000664000175000017500000001675615051422677024175 0ustar ghudsonghudson KRB5_AUTHDATA_SIGNTICKET — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_PA_FX_COOKIE.html0000664000175000017500000001720615051422702024455 0ustar ghudsonghudson KRB5_KEYUSAGE_PA_FX_COOKIE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_ETYPE_INFO.html0000664000175000017500000001703615051422705023751 0ustar ghudsonghudson KRB5_PADATA_ETYPE_INFO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_ENTERPRISE.html0000664000175000017500000001735315051422706025254 0ustar ghudsonghudson KRB5_PRINCIPAL_PARSE_ENTERPRISE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_CRED.html0000664000175000017500000001660715051422700021751 0ustar ghudsonghudson KRB5_CRED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_FINISHED.html0000664000175000017500000001706715051422702023725 0ustar ghudsonghudson KRB5_KEYUSAGE_FINISHED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/MAX_KEYTAB_NAME_LEN.html0000664000175000017500000001665115051422710023433 0ustar ghudsonghudson MAX_KEYTAB_NAME_LEN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY.html0000664000175000017500000001725015051422703025321 0ustar ghudsonghudson KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KPASSWD_SOFTERROR.html0000664000175000017500000001675315051422703024022 0ustar ghudsonghudson KRB5_KPASSWD_SOFTERROR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_GC_CONSTRAINED_DELEGATION.html0000664000175000017500000001711015051422700025037 0ustar ghudsonghudson KRB5_GC_CONSTRAINED_DELEGATION — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DES3_CBC_SHA.html0000664000175000017500000001665515051422676023517 0ustar ghudsonghudson ENCTYPE_DES3_CBC_SHA — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ALL_LAST_TGT_ISSUED.html0000664000175000017500000001705215051422703024775 0ustar ghudsonghudson KRB5_LRQ_ALL_LAST_TGT_ISSUED — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_AP_REQ_AUTH.html0000664000175000017500000001713315051422701024355 0ustar ghudsonghudson KRB5_KEYUSAGE_AP_REQ_AUTH — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/AD_TYPE_EXTERNAL.html0000664000175000017500000001655715051422674023116 0ustar ghudsonghudson AD_TYPE_EXTERNAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_REQUEST_ANONYMOUS.html0000664000175000017500000001673115051422676024466 0ustar ghudsonghudson KDC_OPT_REQUEST_ANONYMOUS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_RSA_MD5.html0000664000175000017500000001661115051422675023215 0ustar ghudsonghudson CKSUMTYPE_RSA_MD5 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ADDRTYPE_XNS.html0000664000175000017500000001641515051422674022424 0ustar ghudsonghudson ADDRTYPE_XNS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_FOR_USER.html0000664000175000017500000001675015051422705023536 0ustar ghudsonghudson KRB5_PADATA_FOR_USER — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KDC_OPT_CNAME_IN_ADDL_TKT.html0000664000175000017500000001706315051422676024404 0ustar ghudsonghudson KDC_OPT_CNAME_IN_ADDL_TKT — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/TKT_FLG_INITIAL.html0000664000175000017500000001645115051422711022753 0ustar ghudsonghudson TKT_FLG_INITIAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_RSA_ENV.html0000664000175000017500000001663015051422676023005 0ustar ghudsonghudson ENCTYPE_RSA_ENV — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_PARSE_IGNORE_REALM.html0000664000175000017500000001741215051422706025473 0ustar ghudsonghudson KRB5_PRINCIPAL_PARSE_IGNORE_REALM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_NT_PRINCIPAL.html0000664000175000017500000001671715051422704023164 0ustar ghudsonghudson KRB5_NT_PRINCIPAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/SALT_TYPE_NO_LENGTH.html0000664000175000017500000001656715051422710023520 0ustar ghudsonghudson SALT_TYPE_NO_LENGTH — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_LRQ_ONE_LAST_INITIAL.html0000664000175000017500000001704715051422703024371 0ustar ghudsonghudson KRB5_LRQ_ONE_LAST_INITIAL — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/CKSUMTYPE_HMAC_SHA1_96_AES256.html0000664000175000017500000001734515051422675024657 0ustar ghudsonghudson CKSUMTYPE_HMAC_SHA1_96_AES256 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_CAMELLIA128_CTS_CMAC.html0000664000175000017500000001716015051422675024544 0ustar ghudsonghudson ENCTYPE_CAMELLIA128_CTS_CMAC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_DELEGATION_INFO.html0000664000175000017500000001705115051422704024143 0ustar ghudsonghudson KRB5_PAC_DELEGATION_INFO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_ENCRYPTED_CHALLENGE.html0000664000175000017500000001724315051422705025147 0ustar ghudsonghudson KRB5_PADATA_ENCRYPTED_CHALLENGE — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DES3_CBC_ENV.html0000664000175000017500000001700215051422676023517 0ustar ghudsonghudson ENCTYPE_DES3_CBC_ENV — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_USE_SUBKEY.html0000664000175000017500000001677515051422700025005 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_USE_SUBKEY — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTHDATA_SESAME.html0000664000175000017500000001670115051422677023474 0ustar ghudsonghudson KRB5_AUTHDATA_SESAME — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN.html0000664000175000017500000001756015051422707026114 0ustar ghudsonghudson KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/THREEPARAMOPEN.html0000664000175000017500000001662515051422710022564 0ustar ghudsonghudson THREEPARAMOPEN — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_PK_AS_REQ_OLD.html0000664000175000017500000001677015051422705024356 0ustar ghudsonghudson KRB5_PADATA_PK_AS_REQ_OLD — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC.html0000664000175000017500000001752215051422707026323 0ustar ghudsonghudson KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PRINCIPAL_COMPARE_IGNORE_REALM.html0000664000175000017500000001741215051422706025707 0ustar ghudsonghudson KRB5_PRINCIPAL_COMPARE_IGNORE_REALM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PADATA_USE_SPECIFIED_KVNO.html0000664000175000017500000001717415051422706025120 0ustar ghudsonghudson KRB5_PADATA_USE_SPECIFIED_KVNO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_PAC_LOGON_INFO.html0000664000175000017500000001671415051422704023413 0ustar ghudsonghudson KRB5_PAC_LOGON_INFO — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_ENC_CHALLENGE_KDC.html0000664000175000017500000001723515051422702025161 0ustar ghudsonghudson KRB5_KEYUSAGE_ENC_CHALLENGE_KDC — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR.html0000664000175000017500000001775715051422677027025 0ustar ghudsonghudson KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/KRB5_KEYUSAGE_FAST_REQ_CHKSUM.html0000664000175000017500000001711315051422702025042 0ustar ghudsonghudson KRB5_KEYUSAGE_FAST_REQ_CHKSUM — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/macros/ENCTYPE_DSA_SHA1_CMS.html0000664000175000017500000001671415051422676023540 0ustar ghudsonghudson ENCTYPE_DSA_SHA1_CMS — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/0000775000175000017500000000000015051422713017435 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/appdev/refs/types/krb5_rcache.html0000664000175000017500000001624215051422712022477 0ustar ghudsonghudson krb5_rcache — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_data.html0000664000175000017500000002234415051422712022163 0ustar ghudsonghudson krb5_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_responder_pkinit_challenge.html0000664000175000017500000002134215051422712026630 0ustar ghudsonghudson krb5_responder_pkinit_challenge — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_keyusage.html0000664000175000017500000001627015051422712023070 0ustar ghudsonghudson krb5_keyusage — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_kt_cursor.html0000664000175000017500000001622015051422712023261 0ustar ghudsonghudson krb5_kt_cursor — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_trace_info.html0000664000175000017500000002063415051422713023364 0ustar ghudsonghudson krb5_trace_info — MIT Kerberos Documentation

krb5_trace_info¶

type krb5_trace_info¶

A wrapper for passing information to a krb5_trace_callback .

Currently, it only contains the formatted message as determined the the format string and arguments of the tracing macro, but it may be extended to contain more fields in the future.

Declaration¶

typedef struct _krb5_trace_info krb5_trace_info

Members¶

const char *krb5_trace_info.message¶
krb5-1.22.1/doc/html/appdev/refs/types/krb5_enctype.html0000664000175000017500000001623215051422712022720 0ustar ghudsonghudson krb5_enctype — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_pwd_data.html0000664000175000017500000002305515051422712023035 0ustar ghudsonghudson krb5_pwd_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_cksumtype.html0000664000175000017500000001627015051422712023277 0ustar ghudsonghudson krb5_cksumtype — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_cryptotype.html0000664000175000017500000001624615051422712023500 0ustar ghudsonghudson krb5_cryptotype — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_enc_tkt_part.html0000664000175000017500000003330115051422712023722 0ustar ghudsonghudson krb5_enc_tkt_part — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_ticket.html0000664000175000017500000002466315051422713022544 0ustar ghudsonghudson krb5_ticket — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/index.html0000664000175000017500000004124715051422712021441 0ustar ghudsonghudson krb5 types and structures — MIT Kerberos Documentation

krb5 types and structures¶

Public¶

Internal¶

krb5-1.22.1/doc/html/appdev/refs/types/krb5_address.html0000664000175000017500000002422515051422712022677 0ustar ghudsonghudson krb5_address — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_msgtype.html0000664000175000017500000001630615051422712022743 0ustar ghudsonghudson krb5_msgtype — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_boolean.html0000664000175000017500000001625615051422712022676 0ustar ghudsonghudson krb5_boolean — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_enc_data.html0000664000175000017500000002417615051422712023015 0ustar ghudsonghudson krb5_enc_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_error_code.html0000664000175000017500000001664315051422712023402 0ustar ghudsonghudson krb5_error_code — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_trace_callback.html0000664000175000017500000001650115051422713024163 0ustar ghudsonghudson krb5_trace_callback — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_crypto_iov.html0000664000175000017500000002245015051422712023445 0ustar ghudsonghudson krb5_crypto_iov — MIT Kerberos Documentation

krb5_crypto_iov¶

type krb5_crypto_iov¶

Structure to describe a region of text to be encrypted or decrypted.

The flags member describes the type of the iov. The data member points to the memory that will be manipulated. All iov APIs take a pointer to the first element of an array of krb5_crypto_iov’s along with the size of that array. Buffer contents are manipulated in-place; data is overwritten. Callers must allocate the right number of krb5_crypto_iov structures before calling into an iov API.

Declaration¶

typedef struct _krb5_crypto_iov krb5_crypto_iov

Members¶

krb5_cryptotype krb5_crypto_iov.flags¶

iov type (see KRB5_CRYPTO_TYPE macros)

krb5_data krb5_crypto_iov.data¶
krb5-1.22.1/doc/html/appdev/refs/types/krb5_ui_2.html0000664000175000017500000001613415051422713022111 0ustar ghudsonghudson krb5_ui_2 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_const_principal.html0000664000175000017500000002651715051422712024447 0ustar ghudsonghudson krb5_const_principal — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_creds.html0000664000175000017500000003674115051422712022360 0ustar ghudsonghudson krb5_creds — MIT Kerberos Documentation

krb5_creds¶

type krb5_creds¶

Credentials structure including ticket, session key, and lifetime info.

Declaration¶

typedef struct _krb5_creds krb5_creds

Members¶

krb5_magic krb5_creds.magic¶
krb5_principal krb5_creds.client¶

client’s principal identifier

krb5_principal krb5_creds.server¶

server’s principal identifier

krb5_keyblock krb5_creds.keyblock¶

session encryption key info

krb5_ticket_times krb5_creds.times¶

lifetime info

krb5_boolean krb5_creds.is_skey¶

true if ticket is encrypted in another ticket’s skey

krb5_flags krb5_creds.ticket_flags¶

flags in ticket

krb5_address **krb5_creds.addresses¶

addrs in ticket

krb5_data krb5_creds.ticket¶

ticket string itself

krb5_data krb5_creds.second_ticket¶

second ticket, if related to ticket (via DUPLICATE-SKEY or ENC-TKT-IN-SKEY)

krb5_authdata **krb5_creds.authdata¶

authorization data

krb5-1.22.1/doc/html/appdev/refs/types/krb5_timestamp.html0000664000175000017500000001706015051422713023255 0ustar ghudsonghudson krb5_timestamp — MIT Kerberos Documentation

krb5_timestamp¶

type krb5_timestamp¶

Represents a timestamp in seconds since the POSIX epoch.

This legacy type is used frequently in the ABI, but cannot represent timestamps after 2038 as a positive number. Code which uses this type should cast values of it to uint32_t so that negative values are treated as timestamps between 2038 and 2106 on platforms with 64-bit time_t.

Declaration¶

typedef krb5_int32 krb5_timestamp

krb5-1.22.1/doc/html/appdev/refs/types/krb5_transited.html0000664000175000017500000002306115051422713023245 0ustar ghudsonghudson krb5_transited — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_verify_init_creds_opt.html0000664000175000017500000002174115051422713025644 0ustar ghudsonghudson krb5_verify_init_creds_opt — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_responder_fn.html0000664000175000017500000001704615051422712023741 0ustar ghudsonghudson krb5_responder_fn — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_ap_rep.html0000664000175000017500000002157215051422712022522 0ustar ghudsonghudson krb5_ap_rep — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_cred_info.html0000664000175000017500000003130015051422712023172 0ustar ghudsonghudson krb5_cred_info — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/passwd_phrase_element.html0000664000175000017500000002346515051422713024711 0ustar ghudsonghudson passwd_phrase_element — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_preauthtype.html0000664000175000017500000001632615051422712023627 0ustar ghudsonghudson krb5_preauthtype — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_deltat.html0000664000175000017500000001615215051422712022527 0ustar ghudsonghudson krb5_deltat — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_ticket_times.html0000664000175000017500000002513215051422713023735 0ustar ghudsonghudson krb5_ticket_times — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_post_recv_fn.html0000664000175000017500000001752615051422712023747 0ustar ghudsonghudson krb5_post_recv_fn — MIT Kerberos Documentation

krb5_post_recv_fn¶

type krb5_post_recv_fn¶

Hook function for inspecting or overriding KDC replies.

If code is non-zero, KDC communication failed and reply should be ignored. The hook function may return code or a different error code, or may synthesize a reply by setting new_reply_out and return successfully. The hook function should use krb5_copy_data() to construct the value for new_reply_out , to ensure that it can be freed correctly by the library.

Declaration¶

typedef krb5_error_code( * krb5_post_recv_fn) (krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply_out)

krb5-1.22.1/doc/html/appdev/refs/types/krb5_magic.html0000664000175000017500000001634715051422712022340 0ustar ghudsonghudson krb5_magic — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_authdata.html0000664000175000017500000002445615051422712023053 0ustar ghudsonghudson krb5_authdata — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_kvno.html0000664000175000017500000001622615051422712022231 0ustar ghudsonghudson krb5_kvno — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_gic_opt_pa_data.html0000664000175000017500000002157115051422712024350 0ustar ghudsonghudson krb5_gic_opt_pa_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_const_pointer.html0000664000175000017500000001640115051422712024135 0ustar ghudsonghudson krb5_const_pointer — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_pre_send_fn.html0000664000175000017500000002000215051422712023521 0ustar ghudsonghudson krb5_pre_send_fn — MIT Kerberos Documentation

krb5_pre_send_fn¶

type krb5_pre_send_fn¶

Hook function for inspecting or modifying messages sent to KDCs.

If the hook function sets new_reply_out , message will not be sent to the KDC, and the given reply will used instead. If the hook function sets new_message_out , the given message will be sent to the KDC in place of message . If the hook function returns successfully without setting either output, message will be sent to the KDC normally. The hook function should use krb5_copy_data() to construct the value for new_message_out or reply_out , to ensure that it can be freed correctly by the library.

Declaration¶

typedef krb5_error_code( * krb5_pre_send_fn) (krb5_context context, void *data, const krb5_data *realm, const krb5_data *message, krb5_data **new_message_out, krb5_data **new_reply_out)

krb5-1.22.1/doc/html/appdev/refs/types/krb5_cc_cursor.html0000664000175000017500000001627315051422712023240 0ustar ghudsonghudson krb5_cc_cursor — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_response.html0000664000175000017500000002572315051422713023115 0ustar ghudsonghudson krb5_response — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_typed_data.html0000664000175000017500000002423015051422713023365 0ustar ghudsonghudson krb5_typed_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_kdc_req.html0000664000175000017500000004650215051422712022664 0ustar ghudsonghudson krb5_kdc_req — MIT Kerberos Documentation

krb5_kdc_req¶

type krb5_kdc_req¶

C representation of KDC-REQ protocol message, including KDC-REQ-BODY.

Declaration¶

typedef struct _krb5_kdc_req krb5_kdc_req

Members¶

krb5_magic krb5_kdc_req.magic¶
krb5_msgtype krb5_kdc_req.msg_type¶

KRB5_AS_REQ or KRB5_TGS_REQ.

krb5_pa_data **krb5_kdc_req.padata¶

Preauthentication data.

krb5_flags krb5_kdc_req.kdc_options¶

Requested options.

krb5_principal krb5_kdc_req.client¶

Client principal and realm.

krb5_principal krb5_kdc_req.server¶

Server principal and realm.

krb5_timestamp krb5_kdc_req.from¶

Requested start time.

krb5_timestamp krb5_kdc_req.till¶

Requested end time.

krb5_timestamp krb5_kdc_req.rtime¶

Requested renewable end time.

krb5_int32 krb5_kdc_req.nonce¶

Nonce to match request and response.

int krb5_kdc_req.nktypes¶

Number of enctypes.

krb5_enctype *krb5_kdc_req.ktype¶

Requested enctypes.

krb5_address **krb5_kdc_req.addresses¶

Requested addresses (optional)

krb5_enc_data krb5_kdc_req.authorization_data¶

Encrypted authz data (optional)

krb5_authdata **krb5_kdc_req.unenc_authdata¶

Unencrypted authz data.

krb5_ticket **krb5_kdc_req.second_ticket¶

Second ticket array (optional)

krb5-1.22.1/doc/html/appdev/refs/types/krb5_cred_enc_part.html0000664000175000017500000003152615051422712024044 0ustar ghudsonghudson krb5_cred_enc_part — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_mk_req_checksum_func.html0000664000175000017500000001664415051422712025433 0ustar ghudsonghudson krb5_mk_req_checksum_func — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_tkt_authent.html0000664000175000017500000002465015051422713023607 0ustar ghudsonghudson krb5_tkt_authent — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_encrypt_block.html0000664000175000017500000002320115051422712024101 0ustar ghudsonghudson krb5_encrypt_block — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_prompter_fct.html0000664000175000017500000001660615051422712023762 0ustar ghudsonghudson krb5_prompter_fct — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_keyblock.html0000664000175000017500000002427115051422712023056 0ustar ghudsonghudson krb5_keyblock — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_cccol_cursor.html0000664000175000017500000001647015051422712023735 0ustar ghudsonghudson krb5_cccol_cursor — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_flags.html0000664000175000017500000001637215051422712022352 0ustar ghudsonghudson krb5_flags — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_ap_rep_enc_part.html0000664000175000017500000002656215051422712024401 0ustar ghudsonghudson krb5_ap_rep_enc_part — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_ap_req.html0000664000175000017500000002431415051422712022520 0ustar ghudsonghudson krb5_ap_req — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_int32.html0000664000175000017500000001613315051422712022210 0ustar ghudsonghudson krb5_int32 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_prompt_type.html0000664000175000017500000001631215051422712023632 0ustar ghudsonghudson krb5_prompt_type — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_responder_pkinit_identity.html0000664000175000017500000002226715051422712026546 0ustar ghudsonghudson krb5_responder_pkinit_identity — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_principal_data.html0000664000175000017500000002604015051422712024221 0ustar ghudsonghudson krb5_principal_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_ccache.html0000664000175000017500000001625215051422712022461 0ustar ghudsonghudson krb5_ccache — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_pointer.html0000664000175000017500000001623315051422712022732 0ustar ghudsonghudson krb5_pointer — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_pa_svr_referral_data.html0000664000175000017500000002062315051422712025415 0ustar ghudsonghudson krb5_pa_svr_referral_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_context.html0000664000175000017500000001624515051422712022741 0ustar ghudsonghudson krb5_context — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_keytab.html0000664000175000017500000001611415051422712022527 0ustar ghudsonghudson krb5_keytab — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_responder_otp_tokeninfo.html0000664000175000017500000003156615051422712026217 0ustar ghudsonghudson krb5_responder_otp_tokeninfo — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_pa_pac_req.html0000664000175000017500000002032715051422712023343 0ustar ghudsonghudson krb5_pa_pac_req — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_kdc_rep.html0000664000175000017500000003117215051422712022660 0ustar ghudsonghudson krb5_kdc_rep — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_pac.html0000664000175000017500000001622015051422712022011 0ustar ghudsonghudson krb5_pac — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_expire_callback_func.html0000664000175000017500000001664615051422712025405 0ustar ghudsonghudson krb5_expire_callback_func — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_auth_context.html0000664000175000017500000001642015051422712023755 0ustar ghudsonghudson krb5_auth_context — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_pa_data.html0000664000175000017500000002443615051422712022647 0ustar ghudsonghudson krb5_pa_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_prompt.html0000664000175000017500000002300615051422712022567 0ustar ghudsonghudson krb5_prompt — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_octet.html0000664000175000017500000001617115051422712022371 0ustar ghudsonghudson krb5_octet — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_int16.html0000664000175000017500000001621315051422712022211 0ustar ghudsonghudson krb5_int16 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_init_creds_context.html0000664000175000017500000001644215051422712025143 0ustar ghudsonghudson krb5_init_creds_context — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_pa_server_referral_data.html0000664000175000017500000002725715051422712026123 0ustar ghudsonghudson krb5_pa_server_referral_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_authenticator.html0000664000175000017500000003327215051422712024126 0ustar ghudsonghudson krb5_authenticator — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_enc_kdc_rep_part.html0000664000175000017500000004054515051422712024537 0ustar ghudsonghudson krb5_enc_kdc_rep_part — MIT Kerberos Documentation

krb5_enc_kdc_rep_part¶

type krb5_enc_kdc_rep_part¶

C representation of EncKDCRepPart protocol message.

This is the cleartext message that is encrypted and inserted in KDC-REP .

Declaration¶

typedef struct _krb5_enc_kdc_rep_part krb5_enc_kdc_rep_part

Members¶

krb5_magic krb5_enc_kdc_rep_part.magic¶
krb5_msgtype krb5_enc_kdc_rep_part.msg_type¶

krb5 message type

krb5_keyblock *krb5_enc_kdc_rep_part.session¶

Session key.

krb5_last_req_entry **krb5_enc_kdc_rep_part.last_req¶

Array of pointers to entries.

krb5_int32 krb5_enc_kdc_rep_part.nonce¶

Nonce from request.

krb5_timestamp krb5_enc_kdc_rep_part.key_exp¶

Expiration date.

krb5_flags krb5_enc_kdc_rep_part.flags¶

Ticket flags.

krb5_ticket_times krb5_enc_kdc_rep_part.times¶

Lifetime info.

krb5_principal krb5_enc_kdc_rep_part.server¶

Server’s principal identifier.

krb5_address **krb5_enc_kdc_rep_part.caddrs¶

Array of ptrs to addrs, optional.

krb5_pa_data **krb5_enc_kdc_rep_part.enc_padata¶

Encrypted preauthentication data.

krb5-1.22.1/doc/html/appdev/refs/types/krb5_error.html0000664000175000017500000003456415051422712022412 0ustar ghudsonghudson krb5_error — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_checksum.html0000664000175000017500000002426715051422712023062 0ustar ghudsonghudson krb5_checksum — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_replay_data.html0000664000175000017500000002327215051422712023540 0ustar ghudsonghudson krb5_replay_data — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_addrtype.html0000664000175000017500000001621015051422712023061 0ustar ghudsonghudson krb5_addrtype — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_principal.html0000664000175000017500000002563515051422712023241 0ustar ghudsonghudson krb5_principal — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_authdatatype.html0000664000175000017500000001635015051422712023747 0ustar ghudsonghudson krb5_authdatatype — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_tkt_creds_context.html0000664000175000017500000001644415051422713025005 0ustar ghudsonghudson krb5_tkt_creds_context — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_cred.html0000664000175000017500000002453615051422712022174 0ustar ghudsonghudson krb5_cred — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_keytab_entry.html0000664000175000017500000002614015051422712023750 0ustar ghudsonghudson krb5_keytab_entry — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_key.html0000664000175000017500000001667015051422712022047 0ustar ghudsonghudson krb5_key — MIT Kerberos Documentation

krb5_key¶

type krb5_key¶

Opaque identifier for a key.

Use with the krb5_k APIs for better performance for repeated operations with the same key and usage. Key identifiers must not be used simultaneously within multiple threads, as they may contain mutable internal state and are not mutex-protected.

Declaration¶

typedef struct krb5_key_st* krb5_key

krb5-1.22.1/doc/html/appdev/refs/types/krb5_responder_context.html0000664000175000017500000001745515051422712025026 0ustar ghudsonghudson krb5_responder_context — MIT Kerberos Documentation

krb5_responder_context¶

type krb5_responder_context¶

A container for a set of preauthentication questions and answers.

A responder context is supplied by the krb5 authentication system to a krb5_responder_fn callback. It contains a list of questions and can receive answers. Questions contained in a responder context can be listed using krb5_responder_list_questions(), retrieved using krb5_responder_get_challenge(), or answered using krb5_responder_set_answer(). The form of a question’s challenge and answer depend on the question name.

Declaration¶

typedef struct krb5_responder_context_st* krb5_responder_context

krb5-1.22.1/doc/html/appdev/refs/types/krb5_last_req_entry.html0000664000175000017500000002314015051422712024300 0ustar ghudsonghudson krb5_last_req_entry — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_get_init_creds_opt.html0000664000175000017500000003725715051422712025127 0ustar ghudsonghudson krb5_get_init_creds_opt — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_ui_4.html0000664000175000017500000001623615051422713022116 0ustar ghudsonghudson krb5_ui_4 — MIT Kerberos Documentation krb5-1.22.1/doc/html/appdev/refs/types/krb5_responder_otp_challenge.html0000664000175000017500000002246015051422712026136 0ustar ghudsonghudson krb5_responder_otp_challenge — MIT Kerberos Documentation krb5-1.22.1/doc/html/_static/0000775000175000017500000000000015051422656015507 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/_static/language_data.js0000664000175000017500000001122615051422656020623 0ustar ghudsonghudson/* * language_data.js * ~~~~~~~~~~~~~~~~ * * This script contains the language-specific data used by searchtools.js, * namely the list of stopwords, stemmer, scorer and splitter. * * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; /* Non-minified version is copied as a separate JS file, is available */ /** * Porter Stemmer */ var Stemmer = function() { var step2list = { ational: 'ate', tional: 'tion', enci: 'ence', anci: 'ance', izer: 'ize', bli: 'ble', alli: 'al', entli: 'ent', eli: 'e', ousli: 'ous', ization: 'ize', ation: 'ate', ator: 'ate', alism: 'al', iveness: 'ive', fulness: 'ful', ousness: 'ous', aliti: 'al', iviti: 'ive', biliti: 'ble', logi: 'log' }; var step3list = { icate: 'ic', ative: '', alize: 'al', iciti: 'ic', ical: 'ic', ful: '', ness: '' }; var c = "[^aeiou]"; // consonant var v = "[aeiouy]"; // vowel var C = c + "[^aeiouy]*"; // consonant sequence var V = v + "[aeiou]*"; // vowel sequence var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 var s_v = "^(" + C + ")?" + v; // vowel in stem this.stemWord = function (w) { var stem; var suffix; var firstch; var origword = w; if (w.length < 3) return w; var re; var re2; var re3; var re4; firstch = w.substr(0,1); if (firstch == "y") w = firstch.toUpperCase() + w.substr(1); // Step 1a re = /^(.+?)(ss|i)es$/; re2 = /^(.+?)([^s])s$/; if (re.test(w)) w = w.replace(re,"$1$2"); else if (re2.test(w)) w = w.replace(re2,"$1$2"); // Step 1b re = /^(.+?)eed$/; re2 = /^(.+?)(ed|ing)$/; if (re.test(w)) { var fp = re.exec(w); re = new RegExp(mgr0); if (re.test(fp[1])) { re = /.$/; w = w.replace(re,""); } } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1]; re2 = new RegExp(s_v); if (re2.test(stem)) { w = stem; re2 = /(at|bl|iz)$/; re3 = new RegExp("([^aeiouylsz])\\1$"); re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re2.test(w)) w = w + "e"; else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } else if (re4.test(w)) w = w + "e"; } } // Step 1c re = /^(.+?)y$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(s_v); if (re.test(stem)) w = stem + "i"; } // Step 2 re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step2list[suffix]; } // Step 3 re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step3list[suffix]; } // Step 4 re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; re2 = /^(.+?)(s|t)(ion)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); if (re.test(stem)) w = stem; } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1] + fp[2]; re2 = new RegExp(mgr1); if (re2.test(stem)) w = stem; } // Step 5 re = /^(.+?)e$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); re2 = new RegExp(meq1); re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) w = stem; } re = /ll$/; re2 = new RegExp(mgr1); if (re.test(w) && re2.test(w)) { re = /.$/; w = w.replace(re,""); } // and turn initial Y back to y if (firstch == "y") w = firstch.toLowerCase() + w.substr(1); return w; } } krb5-1.22.1/doc/html/_static/doctools.js0000664000175000017500000001057014577122106017675 0ustar ghudsonghudson/* * doctools.js * ~~~~~~~~~~~ * * Base JavaScript utilities for all Sphinx HTML documentation. * * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ "use strict"; const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ "TEXTAREA", "INPUT", "SELECT", "BUTTON", ]); const _ready = (callback) => { if (document.readyState !== "loading") { callback(); } else { document.addEventListener("DOMContentLoaded", callback); } }; /** * Small JavaScript module for the documentation. */ const Documentation = { init: () => { Documentation.initDomainIndexTable(); Documentation.initOnKeyListeners(); }, /** * i18n support */ TRANSLATIONS: {}, PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), LOCALE: "unknown", // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) gettext: (string) => { const translated = Documentation.TRANSLATIONS[string]; switch (typeof translated) { case "undefined": return string; // no translation case "string": return translated; // translation exists default: return translated[0]; // (singular, plural) translation tuple exists } }, ngettext: (singular, plural, n) => { const translated = Documentation.TRANSLATIONS[singular]; if (typeof translated !== "undefined") return translated[Documentation.PLURAL_EXPR(n)]; return n === 1 ? singular : plural; }, addTranslations: (catalog) => { Object.assign(Documentation.TRANSLATIONS, catalog.messages); Documentation.PLURAL_EXPR = new Function( "n", `return (${catalog.plural_expr})` ); Documentation.LOCALE = catalog.locale; }, /** * helper function to focus on search bar */ focusSearchBar: () => { document.querySelectorAll("input[name=q]")[0]?.focus(); }, /** * Initialise the domain index toggle buttons */ initDomainIndexTable: () => { const toggler = (el) => { const idNumber = el.id.substr(7); const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); if (el.src.substr(-9) === "minus.png") { el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; toggledRows.forEach((el) => (el.style.display = "none")); } else { el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; toggledRows.forEach((el) => (el.style.display = "")); } }; const togglerElements = document.querySelectorAll("img.toggler"); togglerElements.forEach((el) => el.addEventListener("click", (event) => toggler(event.currentTarget)) ); togglerElements.forEach((el) => (el.style.display = "")); if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); }, initOnKeyListeners: () => { // only install a listener if it is really needed if ( !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS ) return; document.addEventListener("keydown", (event) => { // bail for input elements if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; // bail with special keys if (event.altKey || event.ctrlKey || event.metaKey) return; if (!event.shiftKey) { switch (event.key) { case "ArrowLeft": if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; const prevLink = document.querySelector('link[rel="prev"]'); if (prevLink && prevLink.href) { window.location.href = prevLink.href; event.preventDefault(); } break; case "ArrowRight": if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; const nextLink = document.querySelector('link[rel="next"]'); if (nextLink && nextLink.href) { window.location.href = nextLink.href; event.preventDefault(); } break; } } // some keyboard layouts may need Shift to get / switch (event.key) { case "/": if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; Documentation.focusSearchBar(); event.preventDefault(); } }); }, }; // quick alias for translations const _ = Documentation.gettext; _ready(Documentation.init); krb5-1.22.1/doc/html/_static/documentation_options.js0000664000175000017500000000051115051422656022466 0ustar ghudsonghudsonconst DOCUMENTATION_OPTIONS = { VERSION: '1.22.1', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', FILE_SUFFIX: '.html', LINK_SUFFIX: '.html', HAS_SOURCE: true, SOURCELINK_SUFFIX: '.txt', NAVIGATION_WITH_KEYS: false, SHOW_SEARCH_SUMMARY: true, ENABLE_SEARCH_SHORTCUTS: true, };krb5-1.22.1/doc/html/_static/minus.png0000664000175000017500000000013214577122106017343 0ustar ghudsonghudson‰PNG  IHDR ŒÇ(ú!IDATxc8ƒ g>@Á;(û!¶&«þ€Ø]ìf2nüNIEND®B`‚krb5-1.22.1/doc/html/_static/searchtools.js0000664000175000017500000004476314577122106020410 0ustar ghudsonghudson/* * searchtools.js * ~~~~~~~~~~~~~~~~ * * Sphinx JavaScript utilities for the full-text search. * * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ "use strict"; /** * Simple result scoring code. */ if (typeof Scorer === "undefined") { var Scorer = { // Implement the following function to further tweak the score for each result // The function takes a result array [docname, title, anchor, descr, score, filename] // and returns the new score. /* score: result => { const [docname, title, anchor, descr, score, filename] = result return score }, */ // query matches the full name of an object objNameMatch: 11, // or matches in the last dotted part of the object name objPartialMatch: 6, // Additive scores depending on the priority of the object objPrio: { 0: 15, // used to be importantResults 1: 5, // used to be objectResults 2: -5, // used to be unimportantResults }, // Used when the priority is not in the mapping. objPrioDefault: 0, // query found in title title: 15, partialTitle: 7, // query found in terms term: 5, partialTerm: 2, }; } const _removeChildren = (element) => { while (element && element.lastChild) element.removeChild(element.lastChild); }; /** * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping */ const _escapeRegExp = (string) => string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string const _displayItem = (item, searchTerms, highlightTerms) => { const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; const contentRoot = document.documentElement.dataset.content_root ?? DOCUMENTATION_OPTIONS.URL_ROOT; const [docName, title, anchor, descr, score, _filename] = item; let listItem = document.createElement("li"); let requestUrl; let linkUrl; if (docBuilder === "dirhtml") { // dirhtml builder let dirname = docName + "/"; if (dirname.match(/\/index\/$/)) dirname = dirname.substring(0, dirname.length - 6); else if (dirname === "index/") dirname = ""; requestUrl = contentRoot + dirname; linkUrl = requestUrl; } else { // normal html builders requestUrl = contentRoot + docName + docFileSuffix; linkUrl = docName + docLinkSuffix; } let linkEl = listItem.appendChild(document.createElement("a")); linkEl.href = linkUrl + anchor; linkEl.dataset.score = score; linkEl.innerHTML = title; if (descr) { listItem.appendChild(document.createElement("span")).innerHTML = " (" + descr + ")"; // highlight search terms in the description if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); } else if (showSearchSummary) fetch(requestUrl) .then((responseData) => responseData.text()) .then((data) => { if (data) listItem.appendChild( Search.makeSearchSummary(data, searchTerms) ); // highlight search terms in the summary if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); }); Search.output.appendChild(listItem); }; const _finishSearch = (resultCount) => { Search.stopPulse(); Search.title.innerText = _("Search Results"); if (!resultCount) Search.status.innerText = Documentation.gettext( "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." ); else Search.status.innerText = _( `Search finished, found ${resultCount} page(s) matching the search query.` ); }; const _displayNextItem = ( results, resultCount, searchTerms, highlightTerms, ) => { // results left, load the summary and display it // this is intended to be dynamic (don't sub resultsCount) if (results.length) { _displayItem(results.pop(), searchTerms, highlightTerms); setTimeout( () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), 5 ); } // search finished, update title and status message else _finishSearch(resultCount); }; /** * Default splitQuery function. Can be overridden in ``sphinx.search`` with a * custom function per language. * * The regular expression works by splitting the string on consecutive characters * that are not Unicode letters, numbers, underscores, or emoji characters. * This is the same as ``\W+`` in Python, preserving the surrogate pair area. */ if (typeof splitQuery === "undefined") { var splitQuery = (query) => query .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) .filter(term => term) // remove remaining empty strings } /** * Search Module */ const Search = { _index: null, _queued_query: null, _pulse_status: -1, htmlToText: (htmlString) => { const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); const docContent = htmlElement.querySelector('[role="main"]'); if (docContent !== undefined) return docContent.textContent; console.warn( "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." ); return ""; }, init: () => { const query = new URLSearchParams(window.location.search).get("q"); document .querySelectorAll('input[name="q"]') .forEach((el) => (el.value = query)); if (query) Search.performSearch(query); }, loadIndex: (url) => (document.body.appendChild(document.createElement("script")).src = url), setIndex: (index) => { Search._index = index; if (Search._queued_query !== null) { const query = Search._queued_query; Search._queued_query = null; Search.query(query); } }, hasIndex: () => Search._index !== null, deferQuery: (query) => (Search._queued_query = query), stopPulse: () => (Search._pulse_status = -1), startPulse: () => { if (Search._pulse_status >= 0) return; const pulse = () => { Search._pulse_status = (Search._pulse_status + 1) % 4; Search.dots.innerText = ".".repeat(Search._pulse_status); if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); }; pulse(); }, /** * perform a search for something (or wait until index is loaded) */ performSearch: (query) => { // create the required interface elements const searchText = document.createElement("h2"); searchText.textContent = _("Searching"); const searchSummary = document.createElement("p"); searchSummary.classList.add("search-summary"); searchSummary.innerText = ""; const searchList = document.createElement("ul"); searchList.classList.add("search"); const out = document.getElementById("search-results"); Search.title = out.appendChild(searchText); Search.dots = Search.title.appendChild(document.createElement("span")); Search.status = out.appendChild(searchSummary); Search.output = out.appendChild(searchList); const searchProgress = document.getElementById("search-progress"); // Some themes don't use the search progress node if (searchProgress) { searchProgress.innerText = _("Preparing search..."); } Search.startPulse(); // index already loaded, the browser was quick! if (Search.hasIndex()) Search.query(query); else Search.deferQuery(query); }, /** * execute search (requires search index to be loaded) */ query: (query) => { const filenames = Search._index.filenames; const docNames = Search._index.docnames; const titles = Search._index.titles; const allTitles = Search._index.alltitles; const indexEntries = Search._index.indexentries; // stem the search terms and add them to the correct list const stemmer = new Stemmer(); const searchTerms = new Set(); const excludedTerms = new Set(); const highlightTerms = new Set(); const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); splitQuery(query.trim()).forEach((queryTerm) => { const queryTermLower = queryTerm.toLowerCase(); // maybe skip this "word" // stopwords array is from language_data.js if ( stopwords.indexOf(queryTermLower) !== -1 || queryTerm.match(/^\d+$/) ) return; // stem the word let word = stemmer.stemWord(queryTermLower); // select the correct list if (word[0] === "-") excludedTerms.add(word.substr(1)); else { searchTerms.add(word); highlightTerms.add(queryTermLower); } }); if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) } // console.debug("SEARCH: searching for:"); // console.info("required: ", [...searchTerms]); // console.info("excluded: ", [...excludedTerms]); // array of [docname, title, anchor, descr, score, filename] let results = []; _removeChildren(document.getElementById("search-progress")); const queryLower = query.toLowerCase(); for (const [title, foundTitles] of Object.entries(allTitles)) { if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { for (const [file, id] of foundTitles) { let score = Math.round(100 * queryLower.length / title.length) results.push([ docNames[file], titles[file] !== title ? `${titles[file]} > ${title}` : title, id !== null ? "#" + id : "", null, score, filenames[file], ]); } } } // search for explicit entries in index directives for (const [entry, foundEntries] of Object.entries(indexEntries)) { if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { for (const [file, id] of foundEntries) { let score = Math.round(100 * queryLower.length / entry.length) results.push([ docNames[file], titles[file], id ? "#" + id : "", null, score, filenames[file], ]); } } } // lookup as object objectTerms.forEach((term) => results.push(...Search.performObjectSearch(term, objectTerms)) ); // lookup as search terms in fulltext results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); // let the scorer override scores with a custom scoring function if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); // now sort the results by score (in opposite order of appearance, since the // display function below uses pop() to retrieve items) and then // alphabetically results.sort((a, b) => { const leftScore = a[4]; const rightScore = b[4]; if (leftScore === rightScore) { // same score: sort alphabetically const leftTitle = a[1].toLowerCase(); const rightTitle = b[1].toLowerCase(); if (leftTitle === rightTitle) return 0; return leftTitle > rightTitle ? -1 : 1; // inverted is intentional } return leftScore > rightScore ? 1 : -1; }); // remove duplicate search results // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept let seen = new Set(); results = results.reverse().reduce((acc, result) => { let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); if (!seen.has(resultStr)) { acc.push(result); seen.add(resultStr); } return acc; }, []); results = results.reverse(); // for debugging //Search.lastresults = results.slice(); // a copy // console.info("search results:", Search.lastresults); // print the results _displayNextItem(results, results.length, searchTerms, highlightTerms); }, /** * search for object names */ performObjectSearch: (object, objectTerms) => { const filenames = Search._index.filenames; const docNames = Search._index.docnames; const objects = Search._index.objects; const objNames = Search._index.objnames; const titles = Search._index.titles; const results = []; const objectSearchCallback = (prefix, match) => { const name = match[4] const fullname = (prefix ? prefix + "." : "") + name; const fullnameLower = fullname.toLowerCase(); if (fullnameLower.indexOf(object) < 0) return; let score = 0; const parts = fullnameLower.split("."); // check for different match types: exact matches of full name or // "last name" (i.e. last dotted part) if (fullnameLower === object || parts.slice(-1)[0] === object) score += Scorer.objNameMatch; else if (parts.slice(-1)[0].indexOf(object) > -1) score += Scorer.objPartialMatch; // matches in last name const objName = objNames[match[1]][2]; const title = titles[match[0]]; // If more than one term searched for, we require other words to be // found in the name/title/description const otherTerms = new Set(objectTerms); otherTerms.delete(object); if (otherTerms.size > 0) { const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); if ( [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) ) return; } let anchor = match[3]; if (anchor === "") anchor = fullname; else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; const descr = objName + _(", in ") + title; // add custom score for some objects according to scorer if (Scorer.objPrio.hasOwnProperty(match[2])) score += Scorer.objPrio[match[2]]; else score += Scorer.objPrioDefault; results.push([ docNames[match[0]], fullname, "#" + anchor, descr, score, filenames[match[0]], ]); }; Object.keys(objects).forEach((prefix) => { if (!(objects[prefix] instanceof Array)) { objects[prefix] = Object.entries(objects[prefix]).map(([name, match]) => [...match, name]); } objects[prefix].forEach((array) => objectSearchCallback(prefix, array) ); }); return results; }, /** * search for full-text terms in the index */ performTermsSearch: (searchTerms, excludedTerms) => { // prepare search const terms = Search._index.terms; const titleTerms = Search._index.titleterms; const filenames = Search._index.filenames; const docNames = Search._index.docnames; const titles = Search._index.titles; const scoreMap = new Map(); const fileMap = new Map(); // perform the search on the required terms searchTerms.forEach((word) => { const files = []; const arr = [ { files: terms[word], score: Scorer.term }, { files: titleTerms[word], score: Scorer.title }, ]; // add support for partial matches if (word.length > 2) { const escapedWord = _escapeRegExp(word); Object.keys(terms).forEach((term) => { if (term.match(escapedWord) && !terms[word]) arr.push({ files: terms[term], score: Scorer.partialTerm }); }); Object.keys(titleTerms).forEach((term) => { if (term.match(escapedWord) && !titleTerms[word]) arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); }); } // no match but word was a required one if (arr.every((record) => record.files === undefined)) return; // found search word in contents arr.forEach((record) => { if (record.files === undefined) return; let recordFiles = record.files; if (recordFiles.length === undefined) recordFiles = [recordFiles]; files.push(...recordFiles); // set score for the word in each file recordFiles.forEach((file) => { if (!scoreMap.has(file)) scoreMap.set(file, {}); scoreMap.get(file)[word] = record.score; }); }); // create the mapping files.forEach((file) => { if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); else fileMap.set(file, [word]); }); }); // now check if the files don't contain excluded terms const results = []; for (const [file, wordList] of fileMap) { // check if all requirements are matched // as search terms with length < 3 are discarded const filteredTermCount = [...searchTerms].filter( (term) => term.length > 2 ).length; if ( wordList.length !== searchTerms.size && wordList.length !== filteredTermCount ) continue; // ensure that none of the excluded terms is in the search result if ( [...excludedTerms].some( (term) => terms[term] === file || titleTerms[term] === file || (terms[term] || []).includes(file) || (titleTerms[term] || []).includes(file) ) ) break; // select one (max) score for the file. const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); // add result to the result list results.push([ docNames[file], titles[file], "", null, score, filenames[file], ]); } return results; }, /** * helper function to return a node containing the * search summary for a given text. keywords is a list * of stemmed words. */ makeSearchSummary: (htmlText, keywords) => { const text = Search.htmlToText(htmlText); if (text === "") return null; const textLower = text.toLowerCase(); const actualStartPosition = [...keywords] .map((k) => textLower.indexOf(k.toLowerCase())) .filter((i) => i > -1) .slice(-1)[0]; const startWithContext = Math.max(actualStartPosition - 120, 0); const top = startWithContext === 0 ? "" : "..."; const tail = startWithContext + 240 < text.length ? "..." : ""; let summary = document.createElement("p"); summary.classList.add("context"); summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; return summary; }, }; _ready(Search.init); krb5-1.22.1/doc/html/_static/sphinx_highlight.js0000664000175000017500000001200314577122106021400 0ustar ghudsonghudson/* Highlighting utilities for Sphinx HTML documentation. */ "use strict"; const SPHINX_HIGHLIGHT_ENABLED = true /** * highlight a given string on a node by wrapping it in * span elements with the given class name. */ const _highlight = (node, addItems, text, className) => { if (node.nodeType === Node.TEXT_NODE) { const val = node.nodeValue; const parent = node.parentNode; const pos = val.toLowerCase().indexOf(text); if ( pos >= 0 && !parent.classList.contains(className) && !parent.classList.contains("nohighlight") ) { let span; const closestNode = parent.closest("body, svg, foreignObject"); const isInSVG = closestNode && closestNode.matches("svg"); if (isInSVG) { span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); } else { span = document.createElement("span"); span.classList.add(className); } span.appendChild(document.createTextNode(val.substr(pos, text.length))); const rest = document.createTextNode(val.substr(pos + text.length)); parent.insertBefore( span, parent.insertBefore( rest, node.nextSibling ) ); node.nodeValue = val.substr(0, pos); /* There may be more occurrences of search term in this node. So call this * function recursively on the remaining fragment. */ _highlight(rest, addItems, text, className); if (isInSVG) { const rect = document.createElementNS( "http://www.w3.org/2000/svg", "rect" ); const bbox = parent.getBBox(); rect.x.baseVal.value = bbox.x; rect.y.baseVal.value = bbox.y; rect.width.baseVal.value = bbox.width; rect.height.baseVal.value = bbox.height; rect.setAttribute("class", className); addItems.push({ parent: parent, target: rect }); } } } else if (node.matches && !node.matches("button, select, textarea")) { node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); } }; const _highlightText = (thisNode, text, className) => { let addItems = []; _highlight(thisNode, addItems, text, className); addItems.forEach((obj) => obj.parent.insertAdjacentElement("beforebegin", obj.target) ); }; /** * Small JavaScript module for the documentation. */ const SphinxHighlight = { /** * highlight the search words provided in localstorage in the text */ highlightSearchWords: () => { if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight // get and clear terms from localstorage const url = new URL(window.location); const highlight = localStorage.getItem("sphinx_highlight_terms") || url.searchParams.get("highlight") || ""; localStorage.removeItem("sphinx_highlight_terms") url.searchParams.delete("highlight"); window.history.replaceState({}, "", url); // get individual terms from highlight string const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); if (terms.length === 0) return; // nothing to do // There should never be more than one element matching "div.body" const divBody = document.querySelectorAll("div.body"); const body = divBody.length ? divBody[0] : document.querySelector("body"); window.setTimeout(() => { terms.forEach((term) => _highlightText(body, term, "highlighted")); }, 10); const searchBox = document.getElementById("searchbox"); if (searchBox === null) return; searchBox.appendChild( document .createRange() .createContextualFragment( '" ) ); }, /** * helper function to hide the search marks again */ hideSearchWords: () => { document .querySelectorAll("#searchbox .highlight-link") .forEach((el) => el.remove()); document .querySelectorAll("span.highlighted") .forEach((el) => el.classList.remove("highlighted")); localStorage.removeItem("sphinx_highlight_terms") }, initEscapeListener: () => { // only install a listener if it is really needed if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; document.addEventListener("keydown", (event) => { // bail for input elements if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; // bail with special keys if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { SphinxHighlight.hideSearchWords(); event.preventDefault(); } }); }, }; _ready(() => { /* Do not call highlightSearchWords() when we are on the search page. * It will highlight words from the *previous* search query. */ if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); SphinxHighlight.initEscapeListener(); }); krb5-1.22.1/doc/html/_static/pygments.css0000664000175000017500000001150115051422656020065 0ustar ghudsonghudsonpre { line-height: 125%; } td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight { background: #eeffcc; } .highlight .c { color: #408090; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #007020; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #007020 } /* Comment.Preproc */ .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #FF0000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ .highlight .go { color: #333333 } /* Generic.Output */ .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .highlight .gt { color: #0044DD } /* Generic.Traceback */ .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #007020 } /* Keyword.Pseudo */ .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #902000 } /* Keyword.Type */ .highlight .m { color: #208050 } /* Literal.Number */ .highlight .s { color: #4070a0 } /* Literal.String */ .highlight .na { color: #4070a0 } /* Name.Attribute */ .highlight .nb { color: #007020 } /* Name.Builtin */ .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ .highlight .no { color: #60add5 } /* Name.Constant */ .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #007020 } /* Name.Exception */ .highlight .nf { color: #06287e } /* Name.Function */ .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #bb60d5 } /* Name.Variable */ .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #208050 } /* Literal.Number.Bin */ .highlight .mf { color: #208050 } /* Literal.Number.Float */ .highlight .mh { color: #208050 } /* Literal.Number.Hex */ .highlight .mi { color: #208050 } /* Literal.Number.Integer */ .highlight .mo { color: #208050 } /* Literal.Number.Oct */ .highlight .sa { color: #4070a0 } /* Literal.String.Affix */ .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ .highlight .sc { color: #4070a0 } /* Literal.String.Char */ .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ .highlight .sx { color: #c65d09 } /* Literal.String.Other */ .highlight .sr { color: #235388 } /* Literal.String.Regex */ .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ .highlight .ss { color: #517918 } /* Literal.String.Symbol */ .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #06287e } /* Name.Function.Magic */ .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */krb5-1.22.1/doc/html/_static/plus.png0000664000175000017500000000013214577122106017173 0ustar ghudsonghudson‰PNG  IHDR ŒÇ(ú!IDATxc8ƒ g>@Á;([“[ˆUÿ @l-!a”óð@IEND®B`‚krb5-1.22.1/doc/html/_static/file.png0000664000175000017500000000043614577122106017136 0ustar ghudsonghudson‰PNG  IHDRóÿaåIDATx­“ƒR…÷){…l× Û¶ÙfÛ=@®å œ:¿¹¾3ßú~箄þþþ¹òòrX$AðX-öD ~ñýý òóó€Ç‰(ŠP%¾€8<<9:: ãøøØP•êO&’$é Øl~‚X÷ìãûæ&ȽÖEWÀ^4µwQ}ÂÎö^ü˜Ô÷Í£¾ ‹¨iê©ïš0/H/é@F)éDzq+’ój”[žSU5¾€Ìèhš¦/ð¿oY– G&Lfs|£¡»»{Íêßøß3%¸U+S°é`AFÒIEND®B`‚krb5-1.22.1/doc/html/_static/agogo.css0000664000175000017500000002132615051422656017321 0ustar ghudsonghudson/* * agogo.css_t * ~~~~~~~~~~~ * * Sphinx stylesheet -- agogo theme. * * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ * { margin: 0px; padding: 0px; } body { font-family: "Verdana", Arial, sans-serif; line-height: 1.4em; color: black; background-color: #5d1509; /* fix for background colors breaking at horizontal scrolling on smaller devices */ min-width: fit-content; } /* Page layout */ div.header, div.content, div.footer { width: auto; margin-left: auto; margin-right: auto; } div.header-wrapper { background: #555573 url(bgtop.png) top left repeat-x; border-bottom: 3px solid #2e3436; } /* Default body styles */ a { color: #881f0d; } a:visited { color: #551a8b; } div.bodywrapper a, div.footer a { text-decoration: underline; } .clearer { clear: both; } .left { float: left; } .right { float: right; } .line-block { display: block; margin-top: 1em; margin-bottom: 1em; } .line-block .line-block { margin-top: 0; margin-bottom: 0; margin-left: 1.5em; } h1, h2, h3, h4 { font-family: "Georgia", "Times New Roman", serif; font-weight: normal; color: #3465a4; margin-bottom: .8em; } h1 { color: #204a87; } h2 { padding-bottom: .5em; border-bottom: 1px solid #3465a4; } a.headerlink { visibility: hidden; color: #dddddd; padding-left: .3em; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink, caption:hover > a.headerlink, p.caption:hover > a.headerlink, div.code-block-caption:hover > a.headerlink { visibility: visible; } img { border: 0; } div.admonition { margin-top: 10px; margin-bottom: 10px; padding: 2px 7px 1px 7px; border-left: 0.2em solid black; } p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; } dt:target, .highlighted { background-color: #fbe54e; } /* Header */ div.header { padding: 1em; } div.header .headertitle { font-family: "Georgia", "Times New Roman", serif; font-weight: normal; font-size: 180%; letter-spacing: .08em; margin-bottom: .8em; } div.header .headertitle a { color: white; } div.header div.rel { margin-top: 1em; } div.header div.rel a { color: #fcaf3e; letter-spacing: .1em; text-transform: uppercase; } p.logo { float: right; } img.logo { border: 0; } /* Content */ div.content-wrapper { background-color: white; padding: 1em; } div.document { width: 80%; float: left; } div.body { padding-right: 2em; text-align: justify; } div.document h1 { line-height: 120%; } div.document ul { margin: 1.5em; list-style-type: square; } div.document dd { margin-left: 1.2em; margin-top: .4em; margin-bottom: 1em; } div.document .section { margin-top: 1.7em; } div.document .section:first-child { margin-top: 0px; } div.document div.highlight { padding: 3px; border-top: 2px solid #dddddd; border-bottom: 2px solid #dddddd; margin-top: .8em; margin-bottom: .8em; } div.document div.literal-block-wrapper { margin-top: .8em; margin-bottom: .8em; } div.document div.literal-block-wrapper div.highlight { margin: 0; } div.document div.code-block-caption span.caption-number { padding: 0.1em 0.3em; font-style: italic; } div.document div.code-block-caption span.caption-text { } div.document h2 { margin-top: .7em; } div.document p { margin-bottom: .5em; } div.document li.toctree-l1 { margin-bottom: 1em; } div.document .descname { font-weight: bold; } div.document .sig-paren { font-size: larger; } div.document .docutils.literal { background-color: #eeeeec; padding: 1px; } div.document .docutils.xref.literal { background-color: transparent; padding: 0px; } div.document blockquote { margin: 1em; } div.document ol { margin: 1.5em; } /* Sidebar */ div.sidebar, aside.sidebar { width: 20%; float: right; font-size: .9em; } div.sidebar a, aside.sidebar a, div.header a { text-decoration: none; } div.sidebar a:hover, aside.sidebar a:hover, div.header a:hover { text-decoration: underline; } div.sidebar h3, aside.sidebar h3 { color: #2e3436; text-transform: uppercase; font-size: 130%; letter-spacing: .1em; } div.sidebar ul, aside.sidebar ul { list-style-type: none; } div.sidebar li.toctree-l1 a, aside.sidebar li.toctree-l1 a { display: block; padding: 1px; border: 1px solid #dddddd; background-color: #eeeeec; margin-bottom: .4em; padding-left: 3px; color: #2e3436; } div.sidebar li.toctree-l2 a, aside.sidebar li.toctree-l2 a { background-color: transparent; border: none; margin-left: 1em; border-bottom: 1px solid #dddddd; } div.sidebar li.toctree-l3 a, aside.sidebar li.toctree-l3 a { background-color: transparent; border: none; margin-left: 2em; border-bottom: 1px solid #dddddd; } div.sidebar li.toctree-l2:last-child a, aside.sidebar li.toctree-l2:last-child a { border-bottom: none; } div.sidebar li.toctree-l1.current a, aside.sidebar li.toctree-l1.current a { border-right: 5px solid #fcaf3e; } div.sidebar li.toctree-l1.current li.toctree-l2 a, aside.sidebar li.toctree-l1.current li.toctree-l2 a { border-right: none; } div.sidebar input[type="text"], aside.sidebar input[type="text"] { width: 170px; } div.sidebar input[type="submit"], aside.sidebar input[type="submit"] { width: 30px; } /* Footer */ div.footer-wrapper { background: #5d1509; border-top: 4px solid #babdb6; padding-top: 10px; padding-bottom: 10px; min-height: 80px; } div.footer, div.footer a { color: #888a85; } div.footer .right { text-align: right; } div.footer .left { text-transform: uppercase; } /* Styles copied from basic theme */ img.align-left, figure.align-left, .figure.align-left, object.align-left { clear: left; float: left; margin-right: 1em; } img.align-right, figure.align-right, .figure.align-right, object.align-right { clear: right; float: right; margin-left: 1em; } img.align-center, figure.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } img.align-default, figure.align-default, .figure.align-default { display: block; margin-left: auto; margin-right: auto; } .align-left { text-align: left; } .align-center { text-align: center; } .align-right { text-align: right; } table caption span.caption-number { font-style: italic; } table caption span.caption-text { } div.figure p.caption span.caption-number, figcaption span.caption-number { font-style: italic; } div.figure p.caption span.caption-text, figcaption span.caption-text { } /* -- search page ----------------------------------------------------------- */ ul.search { margin: 10px 0 0 20px; padding: 0; } ul.search li { padding: 5px 0 5px 20px; background-image: url(file.png); background-repeat: no-repeat; background-position: 0 7px; } ul.search li a { font-weight: bold; } ul.search li div.context { color: #888; margin: 2px 0 0 30px; text-align: left; } ul.keywordmatches li.goodmatch a { font-weight: bold; } /* -- index page ------------------------------------------------------------ */ table.contentstable { width: 90%; } table.contentstable p.biglink { line-height: 150%; } a.biglink { font-size: 1.3em; } span.linkdescr { font-style: italic; padding-top: 5px; font-size: 90%; } /* -- general index --------------------------------------------------------- */ table.indextable td { text-align: left; vertical-align: top; } table.indextable ul { margin-top: 0; margin-bottom: 0; list-style-type: none; } table.indextable > tbody > tr > td > ul { padding-left: 0em; } table.indextable tr.pcap { height: 10px; } table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2; } img.toggler { margin-right: 3px; margin-top: 3px; cursor: pointer; } /* -- domain module index --------------------------------------------------- */ table.modindextable td { padding: 2px; border-collapse: collapse; } /* -- viewcode extension ---------------------------------------------------- */ .viewcode-link { float: right; } .viewcode-back { float: right; font-family:: "Verdana", Arial, sans-serif; } div.viewcode-block:target { margin: -1px -3px; padding: 0 3px; background-color: #f4debf; border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; } div.code-block-caption { background-color: #ddd; color: #333; padding: 2px 5px; font-size: small; } /* -- math display ---------------------------------------------------------- */ div.body div.math p { text-align: center; } span.eqno { float: right; }krb5-1.22.1/doc/html/_static/basic.css0000664000175000017500000003536415051422656017315 0ustar ghudsonghudson/* * basic.css * ~~~~~~~~~ * * Sphinx stylesheet -- basic theme. * * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /* -- main layout ----------------------------------------------------------- */ div.clearer { clear: both; } div.section::after { display: block; content: ''; clear: left; } /* -- relbar ---------------------------------------------------------------- */ div.related { width: 100%; font-size: 90%; } div.related h3 { display: none; } div.related ul { margin: 0; padding: 0 0 0 10px; list-style: none; } div.related li { display: inline; } div.related li.right { float: right; margin-right: 5px; } /* -- sidebar --------------------------------------------------------------- */ div.sphinxsidebarwrapper { padding: 10px 5px 0 10px; } div.sphinxsidebar { float: left; width: 20%; margin-left: -100%; font-size: 90%; word-wrap: break-word; overflow-wrap : break-word; } div.sphinxsidebar ul { list-style: none; } div.sphinxsidebar ul ul, div.sphinxsidebar ul.want-points { margin-left: 20px; list-style: square; } div.sphinxsidebar ul ul { margin-top: 0; margin-bottom: 0; } div.sphinxsidebar form { margin-top: 10px; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } div.sphinxsidebar #searchbox form.search { overflow: hidden; } div.sphinxsidebar #searchbox input[type="text"] { float: left; width: 80%; padding: 0.25em; box-sizing: border-box; } div.sphinxsidebar #searchbox input[type="submit"] { float: left; width: 20%; border-left: none; padding: 0.25em; box-sizing: border-box; } img { border: 0; max-width: 100%; } /* -- search page ----------------------------------------------------------- */ ul.search { margin: 10px 0 0 20px; padding: 0; } ul.search li { padding: 5px 0 5px 20px; background-image: url(file.png); background-repeat: no-repeat; background-position: 0 7px; } ul.search li a { font-weight: bold; } ul.search li p.context { color: #888; margin: 2px 0 0 30px; text-align: left; } ul.keywordmatches li.goodmatch a { font-weight: bold; } /* -- index page ------------------------------------------------------------ */ table.contentstable { width: 90%; margin-left: auto; margin-right: auto; } table.contentstable p.biglink { line-height: 150%; } a.biglink { font-size: 1.3em; } span.linkdescr { font-style: italic; padding-top: 5px; font-size: 90%; } /* -- general index --------------------------------------------------------- */ table.indextable { width: 100%; } table.indextable td { text-align: left; vertical-align: top; } table.indextable ul { margin-top: 0; margin-bottom: 0; list-style-type: none; } table.indextable > tbody > tr > td > ul { padding-left: 0em; } table.indextable tr.pcap { height: 10px; } table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2; } img.toggler { margin-right: 3px; margin-top: 3px; cursor: pointer; } div.modindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } div.genindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } /* -- domain module index --------------------------------------------------- */ table.modindextable td { padding: 2px; border-collapse: collapse; } /* -- general body styles --------------------------------------------------- */ div.body { min-width: 360px; max-width: 800px; } div.body p, div.body dd, div.body li, div.body blockquote { -moz-hyphens: auto; -ms-hyphens: auto; -webkit-hyphens: auto; hyphens: auto; } a.headerlink { visibility: hidden; } a:visited { color: #551A8B; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink, caption:hover > a.headerlink, p.caption:hover > a.headerlink, div.code-block-caption:hover > a.headerlink { visibility: visible; } div.body p.caption { text-align: inherit; } div.body td { text-align: left; } .first { margin-top: 0 !important; } p.rubric { margin-top: 30px; font-weight: bold; } img.align-left, figure.align-left, .figure.align-left, object.align-left { clear: left; float: left; margin-right: 1em; } img.align-right, figure.align-right, .figure.align-right, object.align-right { clear: right; float: right; margin-left: 1em; } img.align-center, figure.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } img.align-default, figure.align-default, .figure.align-default { display: block; margin-left: auto; margin-right: auto; } .align-left { text-align: left; } .align-center { text-align: center; } .align-default { text-align: center; } .align-right { text-align: right; } /* -- sidebars -------------------------------------------------------------- */ div.sidebar, aside.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; padding: 7px; background-color: #ffe; width: 40%; float: right; clear: right; overflow-x: auto; } p.sidebar-title { font-weight: bold; } nav.contents, aside.topic, div.admonition, div.topic, blockquote { clear: left; } /* -- topics ---------------------------------------------------------------- */ nav.contents, aside.topic, div.topic { border: 1px solid #ccc; padding: 7px; margin: 10px 0 10px 0; } p.topic-title { font-size: 1.1em; font-weight: bold; margin-top: 10px; } /* -- admonitions ----------------------------------------------------------- */ div.admonition { margin-top: 10px; margin-bottom: 10px; padding: 7px; } div.admonition dt { font-weight: bold; } p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; } div.body p.centered { text-align: center; margin-top: 25px; } /* -- content of sidebars/topics/admonitions -------------------------------- */ div.sidebar > :last-child, aside.sidebar > :last-child, nav.contents > :last-child, aside.topic > :last-child, div.topic > :last-child, div.admonition > :last-child { margin-bottom: 0; } div.sidebar::after, aside.sidebar::after, nav.contents::after, aside.topic::after, div.topic::after, div.admonition::after, blockquote::after { display: block; content: ''; clear: both; } /* -- tables ---------------------------------------------------------------- */ table.docutils { margin-top: 10px; margin-bottom: 10px; border: 0; border-collapse: collapse; } table.align-center { margin-left: auto; margin-right: auto; } table.align-default { margin-left: auto; margin-right: auto; } table caption span.caption-number { font-style: italic; } table caption span.caption-text { } table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; border-top: 0; border-left: 0; border-right: 0; border-bottom: 1px solid #aaa; } th { text-align: left; padding-right: 5px; } table.citation { border-left: solid 1px gray; margin-left: 1px; } table.citation td { border-bottom: none; } th > :first-child, td > :first-child { margin-top: 0px; } th > :last-child, td > :last-child { margin-bottom: 0px; } /* -- figures --------------------------------------------------------------- */ div.figure, figure { margin: 0.5em; padding: 0.5em; } div.figure p.caption, figcaption { padding: 0.3em; } div.figure p.caption span.caption-number, figcaption span.caption-number { font-style: italic; } div.figure p.caption span.caption-text, figcaption span.caption-text { } /* -- field list styles ----------------------------------------------------- */ table.field-list td, table.field-list th { border: 0 !important; } .field-list ul { margin: 0; padding-left: 1em; } .field-list p { margin: 0; } .field-name { -moz-hyphens: manual; -ms-hyphens: manual; -webkit-hyphens: manual; hyphens: manual; } /* -- hlist styles ---------------------------------------------------------- */ table.hlist { margin: 1em 0; } table.hlist td { vertical-align: top; } /* -- object description styles --------------------------------------------- */ .sig { font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; } .sig-name, code.descname { background-color: transparent; font-weight: bold; } .sig-name { font-size: 1.1em; } code.descname { font-size: 1.2em; } .sig-prename, code.descclassname { background-color: transparent; } .optional { font-size: 1.3em; } .sig-paren { font-size: larger; } .sig-param.n { font-style: italic; } /* C++ specific styling */ .sig-inline.c-texpr, .sig-inline.cpp-texpr { font-family: unset; } .sig.c .k, .sig.c .kt, .sig.cpp .k, .sig.cpp .kt { color: #0033B3; } .sig.c .m, .sig.cpp .m { color: #1750EB; } .sig.c .s, .sig.c .sc, .sig.cpp .s, .sig.cpp .sc { color: #067D17; } /* -- other body styles ----------------------------------------------------- */ ol.arabic { list-style: decimal; } ol.loweralpha { list-style: lower-alpha; } ol.upperalpha { list-style: upper-alpha; } ol.lowerroman { list-style: lower-roman; } ol.upperroman { list-style: upper-roman; } :not(li) > ol > li:first-child > :first-child, :not(li) > ul > li:first-child > :first-child { margin-top: 0px; } :not(li) > ol > li:last-child > :last-child, :not(li) > ul > li:last-child > :last-child { margin-bottom: 0px; } ol.simple ol p, ol.simple ul p, ul.simple ol p, ul.simple ul p { margin-top: 0; } ol.simple > li:not(:first-child) > p, ul.simple > li:not(:first-child) > p { margin-top: 0; } ol.simple p, ul.simple p { margin-bottom: 0; } aside.footnote > span, div.citation > span { float: left; } aside.footnote > span:last-of-type, div.citation > span:last-of-type { padding-right: 0.5em; } aside.footnote > p { margin-left: 2em; } div.citation > p { margin-left: 4em; } aside.footnote > p:last-of-type, div.citation > p:last-of-type { margin-bottom: 0em; } aside.footnote > p:last-of-type:after, div.citation > p:last-of-type:after { content: ""; clear: both; } dl.field-list { display: grid; grid-template-columns: fit-content(30%) auto; } dl.field-list > dt { font-weight: bold; word-break: break-word; padding-left: 0.5em; padding-right: 5px; } dl.field-list > dd { padding-left: 0.5em; margin-top: 0em; margin-left: 0em; margin-bottom: 0em; } dl { margin-bottom: 15px; } dd > :first-child { margin-top: 0px; } dd ul, dd table { margin-bottom: 10px; } dd { margin-top: 3px; margin-bottom: 10px; margin-left: 30px; } .sig dd { margin-top: 0px; margin-bottom: 0px; } .sig dl { margin-top: 0px; margin-bottom: 0px; } dl > dd:last-child, dl > dd:last-child > :last-child { margin-bottom: 0; } dt:target, span.highlighted { background-color: #fbe54e; } rect.highlighted { fill: #fbe54e; } dl.glossary dt { font-weight: bold; font-size: 1.1em; } .versionmodified { font-style: italic; } .system-message { background-color: #fda; padding: 5px; border: 3px solid red; } .footnote:target { background-color: #ffa; } .line-block { display: block; margin-top: 1em; margin-bottom: 1em; } .line-block .line-block { margin-top: 0; margin-bottom: 0; margin-left: 1.5em; } .guilabel, .menuselection { font-family: sans-serif; } .accelerator { text-decoration: underline; } .classifier { font-style: oblique; } .classifier:before { font-style: normal; margin: 0 0.5em; content: ":"; display: inline-block; } abbr, acronym { border-bottom: dotted 1px; cursor: help; } .translated { background-color: rgba(207, 255, 207, 0.2) } .untranslated { background-color: rgba(255, 207, 207, 0.2) } /* -- code displays --------------------------------------------------------- */ pre { overflow: auto; overflow-y: hidden; /* fixes display issues on Chrome browsers */ } pre, div[class*="highlight-"] { clear: both; } span.pre { -moz-hyphens: none; -ms-hyphens: none; -webkit-hyphens: none; hyphens: none; white-space: nowrap; } div[class*="highlight-"] { margin: 1em 0; } td.linenos pre { border: 0; background-color: transparent; color: #aaa; } table.highlighttable { display: block; } table.highlighttable tbody { display: block; } table.highlighttable tr { display: flex; } table.highlighttable td { margin: 0; padding: 0; } table.highlighttable td.linenos { padding-right: 0.5em; } table.highlighttable td.code { flex: 1; overflow: hidden; } .highlight .hll { display: block; } div.highlight pre, table.highlighttable pre { margin: 0; } div.code-block-caption + div { margin-top: 0; } div.code-block-caption { margin-top: 1em; padding: 2px 5px; font-size: small; } div.code-block-caption code { background-color: transparent; } table.highlighttable td.linenos, span.linenos, div.highlight span.gp { /* gp: Generic.Prompt */ user-select: none; -webkit-user-select: text; /* Safari fallback only */ -webkit-user-select: none; /* Chrome/Safari */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* IE10+ */ } div.code-block-caption span.caption-number { padding: 0.1em 0.3em; font-style: italic; } div.code-block-caption span.caption-text { } div.literal-block-wrapper { margin: 1em 0; } code.xref, a code { background-color: transparent; font-weight: bold; } h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { background-color: transparent; } .viewcode-link { float: right; } .viewcode-back { float: right; font-family: sans-serif; } div.viewcode-block:target { margin: -1px -10px; padding: 0 10px; } /* -- math display ---------------------------------------------------------- */ img.math { vertical-align: middle; } div.body div.math p { text-align: center; } span.eqno { float: right; } span.eqno a.headerlink { position: absolute; z-index: 1; } div.math:hover a.headerlink { visibility: visible; } /* -- printout stylesheet --------------------------------------------------- */ @media print { div.document, div.documentwrapper, div.bodywrapper { margin: 0 !important; width: 100%; } div.sphinxsidebar, div.related, div.footer, #top-link { display: none; } }krb5-1.22.1/doc/html/_static/bgtop.png0000664000175000017500000000041214577122106017324 0ustar ghudsonghudson‰PNG  IHDRPSPX±ÑIDATx]Òª 0 EÑÈÒÇÝ;^ÊGCüÉ~ûñXܨŒÚ“Ñÿ\°Jcl!Ù$3¶Ó˜XTØÊŒZ¸9`%onl‚l11KBïle°QÍØjLµQ‡9±îŠ‘ ºû0+ µI“¶Ð°„r™- ¥2Ñi6 Ø´ ™us)˜»¹§zj†ìÎýÔ™G‹:Ìv˜éªu•1Y8š‹¨Äô2©ÛÑ䨼Ê\š‰íQß(6‡¹(36MÊÿœùŸ»}ïo$F¼(ÅÐ:rÌl‚zÝòÎþRâ "¾6IEND®B`‚krb5-1.22.1/doc/html/_static/bgfooter.png0000664000175000017500000000042414577122106020023 0ustar ghudsonghudson‰PNG  IHDRPSPX±ÛIDATx]ч K…áÿ£ÿÚ^t(4Ò•Ù¼'ÍÀüÿýï;§WoªÂTT;Ñ*Sr<Me;ʨµªS84¶ÔØœß=ÓLJçwuh0.X³ÛH{.ºÏ±Ç49¦ ¥âr«-/ãÒÊjˆäx§Õö¹sF¤š'mì%ŸÖt>>;¾A5ËKÓ8¬S>mš´Î9“øsªh"¹´L\/ß´^w©éÄ‹^Ú¶5e Ñ•Œ*ʈ}ÿÒé*ç—Óö–>mº V1$œKêõEÞ |vèž>:y.Î9G˜^ýGI.ùôÀArIEND®B`‚krb5-1.22.1/doc/html/_static/kerb.css0000664000175000017500000000461415051422656017151 0ustar ghudsonghudson/* * kerb.css * ~~~~~~~~~~~ * * Sphinx stylesheet -- modification to agogo theme. * */ div.body { padding-right: .5em; text-align: left; overflow-x: hidden; } /* Page layout */ div.header, div.content, div.footer { margin-left: auto; margin-right: auto; padding-left: 1em; padding-right: 1em; max-width: 60em; } div.header-wrapper { background: white; border-bottom: 3px solid #2e3436; border-top: 13px solid #5d1509; } /* Header */ div.header { padding-top: 10px; padding-bottom: 0px; } div.header h1 { font-family: "Georgia", "Times New Roman", serif, black; font-weight: normal; } div.header h1 a { color: #5d1509; font-size: 120%; padding-top: 10px; } div.header div.right a { color: #fcaf3e; letter-spacing: .1em; text-transform: lowercase; float: right; } div.header div.rel { font-family: "Georgia", "Times New Roman", serif, black; font-weight: normal; margin-bottom: 1.6em; } /* Content */ div.document { width: 80%; float: left; margin: 0; background-color: white; padding-top: 20px; padding-bottom: 20px; } div.document div.section h1 { margin-bottom: 20px; padding: 1px; line-height: 130%; } div.document div.section dl { margin-top: 15px; margin-bottom: 5px; padding: 1px; text-align: left; } /* Sidebar */ div.sidebar { float: right; font-size: .9em; width: 20%; margin: 0; padding: 0; background-color: #F9F9F9; } div.sidebar ul { list-style-type: none; margin-left: .5em; } div.sidebar li.toctree-l1 a { margin-left: .5em; } div.sidebar li.toctree-l2 a { margin-left: .5em; } div.sidebar li.toctree-l3 a { margin-left: .5em; } div.sidebar li.toctree-l2.current a { border-right: 2px solid #fcaf3e !important; } div.sidebar li.toctree-l3.current a { font-weight: bold; } div.sidebar li.toctree-l4 a { display: none; } div.sidebar input[type=text] { width: auto; } /* Other body styles */ dt:target, .highlighted { background-color: #c1c1c1; } /* Code displays */ pre { overflow: auto; overflow-y: hidden; } td.linenos pre { padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } /* ordered lists */ ol.arabic { list-style: decimal; } ol.loweralpha { list-style: lower-alpha; } ol.upperalpha { list-style: upper-alpha; } ol.lowerroman { list-style-type: lower-roman; } ol.upperroman { list-style-type: upper-roman; }krb5-1.22.1/doc/html/build/0000775000175000017500000000000015051422713015152 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/build/index.html0000664000175000017500000002324215051422713017152 0ustar ghudsonghudson Building Kerberos V5 — MIT Kerberos Documentation

Building Kerberos V5¶

This section details how to build and install MIT Kerberos software from the source.

Prerequisites¶

In order to build Kerberos V5, you will need approximately 60-70 megabytes of disk space. The exact amount will vary depending on the platform and whether the distribution is compiled with debugging symbol tables or not.

Your C compiler must conform to ANSI C (ISO/IEC 9899:1990, “c89â€). Some operating systems do not have an ANSI C compiler, or their default compiler requires extra command-line options to enable ANSI C conformance.

If you wish to keep a separate build tree, which contains the compiled *.o file and executables, separate from your source tree, you will need a make program which supports VPATH, or you will need to use a tool such as lndir to produce a symbolic link tree for your build tree.

Obtaining the software¶

The source code can be obtained from MIT Kerberos Distribution page, at https://kerberos.org/dist/index.html. The MIT Kerberos distribution comes in an archive file, generally named krb5-VERSION-signed.tar, where VERSION is a placeholder for the major and minor versions of MIT Kerberos. (For example, MIT Kerberos 1.9 has major version “1†and minor version “9â€.)

The krb5-VERSION-signed.tar contains a compressed tar file consisting of the sources for all of Kerberos (generally named krb5-VERSION.tar.gz) and a PGP signature file for this source tree (generally named krb5-VERSION.tar.gz.asc). MIT highly recommends that you verify the integrity of the source code using this signature, e.g., by running:

tar xf krb5-VERSION-signed.tar
gpg --verify krb5-VERSION.tar.gz.asc

Unpack krb5-VERSION.tar.gz in some directory. In this section we will assume that you have chosen the top directory of the distribution the directory /u1/krb5-VERSION.

Review the README file for the license, copyright and other sprecific to the distribution information.

Contents¶

krb5-1.22.1/doc/html/build/options2configure.html0000664000175000017500000007457415051422713021540 0ustar ghudsonghudson Options to configure — MIT Kerberos Documentation

Options to configure¶

There are a number of options to configure which you can use to control how the Kerberos distribution is built.

Most commonly used options¶

--help

Provides help to configure. This will list the set of commonly used options for building Kerberos.

--prefix=PREFIX

By default, Kerberos will install the package’s files rooted at /usr/local. If you desire to place the binaries into the directory PREFIX, use this option.

--exec-prefix=EXECPREFIX

This option allows one to separate the architecture independent programs from the host-dependent files (configuration files, manual pages). Use this option to install architecture-dependent programs in EXECPREFIX. The default location is the value of specified by --prefix option.

--localstatedir=LOCALSTATEDIR

This option sets the directory for locally modifiable single-machine data. In Kerberos, this mostly is useful for setting a location for the KDC data files, as they will be installed in LOCALSTATEDIR/krb5kdc, which is by default PREFIX/var/krb5kdc.

--with-netlib[=libs]

Allows for suppression of or replacement of network libraries. By default, Kerberos V5 configuration will look for -lnsl and -lsocket. If your operating system has a broken resolver library or fails to pass the tests in src/tests/resolv, you will need to use this option.

--enable-dns-for-realm

Enable the use of DNS to look up a host’s Kerberos realm, if the information is not provided in krb5.conf. See Mapping hostnames onto Kerberos realms for information about using DNS to determine the default realm. DNS lookups for realm names are disabled by default.

--with-system-et

Use an installed version of the error-table (et) support software, the compile_et program, the com_err.h header file and the com_err library. If these are not in the default locations, you may wish to specify CPPFLAGS=-I/some/dir and LDFLAGS=-L/some/other/dir options at configuration time as well.

If this option is not given, a version supplied with the Kerberos sources will be built and installed along with the rest of the Kerberos tree, for Kerberos applications to link against.

--with-system-ss

Use an installed version of the subsystem command-line interface software, the mk_cmds program, the ss/ss.h header file and the ss library. If these are not in the default locations, you may wish to specify CPPFLAGS=-I/some/dir and LDFLAGS=-L/some/other/dir options at configuration time as well. See also the SS_LIB option.

If this option is not given, the ss library supplied with the Kerberos sources will be compiled and linked into those programs that need it; it will not be installed separately.

--with-system-db

Use an installed version of the Berkeley DB package, which must provide an API compatible with version 1.85. This option is unsupported and untested. In particular, we do not know if the database-rename code used in the dumpfile load operation will behave properly.

If this option is not given, a version supplied with the Kerberos sources will be built and installed. (We are not updating this version at this time because of licensing issues with newer versions that we haven’t investigated sufficiently yet.)

Environment variables¶

CC=COMPILER

Use COMPILER as the C compiler.

CFLAGS=FLAGS

Use FLAGS as the default set of C compiler flags.

CPP=CPP

C preprocessor to use. (e.g., CPP='gcc -E')

CPPFLAGS=CPPOPTS

Use CPPOPTS as the default set of C preprocessor flags. The most common use of this option is to select certain #define’s for use with the operating system’s include files.

DB_HEADER=headername

If db.h is not the correct header file to include to compile against the Berkeley DB 1.85 API, specify the correct header file name with this option. For example, DB_HEADER=db3/db_185.h.

DB_LIB=libs…

If -ldb is not the correct library specification for the Berkeley DB library version to be used, override it with this option. For example, DB_LIB=-ldb-3.3.

DEFCCNAME=ccachename

Override the built-in default credential cache name. For example, DEFCCNAME=DIR:/var/run/user/%{USERID}/ccache See Parameter expansion for information about supported parameter expansions.

DEFCKTNAME=keytabname

Override the built-in default client keytab name. The format is the same as for DEFCCNAME.

DEFKTNAME=keytabname

Override the built-in default keytab name. The format is the same as for DEFCCNAME.

LD=LINKER

Use LINKER as the default loader if it should be different from C compiler as specified above.

LDFLAGS=LDOPTS

This option informs the linker where to get additional libraries (e.g., -L<lib dir>).

LIBS=LDNAME

This option allows one to specify libraries to be passed to the linker (e.g., -l<library>)

PKCS11_MODNAME=library

Override the built-in default PKCS11 library name.

SS_LIB=libs…

If -lss is not the correct way to link in your installed ss library, for example if additional support libraries are needed, specify the correct link options here. Some variants of this library are around which allow for Emacs-like line editing, but different versions require different support libraries to be explicitly specified.

This option is ignored if --with-system-ss is not specified.

YACC

The ‘Yet Another C Compiler’ implementation to use. Defaults to the first program found out of: ‘bison -y’, ‘byacc’, ‘yacc’.

YFLAGS

The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of -d given by some make applications.

Fine tuning of the installation directories¶

--bindir=DIR

User executables. Defaults to EXECPREFIX/bin, where EXECPREFIX is the path specified by --exec-prefix configuration option.

--sbindir=DIR

System admin executables. Defaults to EXECPREFIX/sbin, where EXECPREFIX is the path specified by --exec-prefix configuration option.

--sysconfdir=DIR

Read-only single-machine data such as krb5.conf. Defaults to PREFIX/etc, where PREFIX is the path specified by --prefix configuration option.

--libdir=DIR

Object code libraries. Defaults to EXECPREFIX/lib, where EXECPREFIX is the path specified by --exec-prefix configuration option.

--includedir=DIR

C header files. Defaults to PREFIX/include, where PREFIX is the path specified by --prefix configuration option.

--datarootdir=DATAROOTDIR

Read-only architecture-independent data root. Defaults to PREFIX/share, where PREFIX is the path specified by --prefix configuration option.

--datadir=DIR

Read-only architecture-independent data. Defaults to path specified by --datarootdir configuration option.

--localedir=DIR

Locale-dependent data. Defaults to DATAROOTDIR/locale, where DATAROOTDIR is the path specified by --datarootdir configuration option.

--mandir=DIR

Man documentation. Defaults to DATAROOTDIR/man, where DATAROOTDIR is the path specified by --datarootdir configuration option.

Program names¶

--program-prefix=PREFIX

Prepend PREFIX to the names of the programs when installing them. For example, specifying --program-prefix=mit- at the configure time will cause the program named abc to be installed as mit-abc.

--program-suffix=SUFFIX

Append SUFFIX to the names of the programs when installing them. For example, specifying --program-suffix=-mit at the configure time will cause the program named abc to be installed as abc-mit.

--program-transform-name=PROGRAM

Run sed -e PROGRAM on installed program names. (PROGRAM is a sed script).

System types¶

--build=BUILD

Configure for building on BUILD (e.g., --build=x86_64-linux-gnu).

--host=HOST

Cross-compile to build programs to run on HOST (e.g., --host=x86_64-linux-gnu). By default, Kerberos V5 configuration will look for “build†option.

Optional features¶

--disable-option-checking

Ignore unrecognized –enable/–with options.

--disable-FEATURE

Do not include FEATURE (same as –enable-FEATURE=no).

--enable-FEATURE[=ARG]

Include FEATURE [ARG=yes].

--enable-maintainer-mode

Enable rebuilding of source files, Makefiles, etc.

--disable-delayed-initialization

Initialize library code when loaded. Defaults to delay until first use.

--disable-thread-support

Don’t enable thread support. Defaults to enabled.

--disable-rpath

Suppress run path flags in link lines.

--enable-athena

Build with MIT Project Athena configuration.

--disable-kdc-lookaside-cache

Disable the cache which detects client retransmits.

--disable-pkinit

Disable PKINIT plugin support.

--disable-aesni

Disable support for using AES instructions on x86 platforms.

--enable-asan[=ARG]

Enable building with asan memory error checking. If ARG is given, it controls the -fsanitize compilation flag value (the default is “addressâ€).

--enable-ossfuzz

Enable building fuzzing targets with OSS-Fuzz build support.

Optional packages¶

--with-PACKAGE[=ARG]

Use PACKAGE (e.g., --with-imap). The default value of ARG is yes.

--without-PACKAGE

Do not use PACKAGE (same as --with-PACKAGE=no) (e.g., --without-libedit).

--with-size-optimizations

Enable a few optimizations to reduce code size possibly at some run-time cost.

--with-system-et

Use the com_err library and compile_et utility that are already installed on the system, instead of building and installing local versions.

--with-system-ss

Use the ss library and mk_cmds utility that are already installed on the system, instead of building and using private versions.

--with-system-db

Use the berkeley db utility already installed on the system, instead of using a private version. This option is not recommended; enabling it may result in incompatibility with key databases originating on other systems.

--with-netlib=LIBS

Use the resolver library specified in LIBS. Use this variable if the C library resolver is insufficient or broken.

--with-hesiod=path

Compile with Hesiod support. The path points to the Hesiod directory. By default Hesiod is unsupported.

--with-ldap

Compile OpenLDAP database backend module.

--with-lmdb

Compile LMDB database backend module.

--with-vague-errors

Do not send helpful errors to client. For example, if the KDC should return only vague error codes to clients.

--with-crypto-impl=IMPL

Use specified crypto implementation (e.g., --with-crypto-impl=openssl). The default is the native MIT Kerberos implementation builtin. The other currently implemented crypto backend is openssl. (See MIT Kerberos features)

--without-libedit

Do not compile and link against libedit. Some utilities will no longer offer command history or completion in interactive mode if libedit is disabled.

--with-readline

Compile and link against GNU readline, as an alternative to libedit.

--with-system-verto

Use an installed version of libverto. If the libverto header and library are not in default locations, you may wish to specify CPPFLAGS=-I/some/dir and LDFLAGS=-L/some/other/dir options at configuration time as well.

If this option is not given, the build system will try to detect an installed version of libverto and use it if it is found. Otherwise, a version supplied with the Kerberos sources will be built and installed. The built-in version does not contain the full set of back-end modules and is not a suitable general replacement for the upstream version, but will work for the purposes of Kerberos.

Specifying --without-system-verto will cause the built-in version of libverto to be used unconditionally.

--with-krb5-config=PATH

Use the krb5-config program at PATH to obtain the build-time default credential cache, keytab, and client keytab names. The default is to use krb5-config from the program path. Specify --without-krb5-config to disable the use of krb5-config and use the usual built-in defaults.

--without-keyutils

Build without libkeyutils support. This disables the KEYRING credential cache type.

Examples¶

For example, in order to configure Kerberos on a Solaris machine using the suncc compiler with the optimizer turned on, run the configure script with the following options:

% ./configure CC=suncc CFLAGS=-O

For a slightly more complicated example, consider a system where several packages to be used by Kerberos are installed in /usr/foobar, including Berkeley DB 3.3, and an ss library that needs to link against the curses library. The configuration of Kerberos might be done thus:

./configure CPPFLAGS=-I/usr/foobar/include LDFLAGS=-L/usr/foobar/lib \
--with-system-et --with-system-ss --with-system-db  \
SS_LIB='-lss -lcurses'  DB_HEADER=db3/db_185.h DB_LIB=-ldb-3.3
krb5-1.22.1/doc/html/build/doing_build.html0000664000175000017500000003732615051422713020332 0ustar ghudsonghudson Doing the build — MIT Kerberos Documentation

Doing the build¶

Building within a single tree¶

If you only need to build Kerberos for one platform, using a single directory tree which contains both the source files and the object files is the simplest. However, if you need to maintain Kerberos for a large number of platforms, you will probably want to use separate build trees for each platform. We recommend that you look at OS Incompatibilities, for notes that we have on particular operating systems.

If you don’t want separate build trees for each architecture, then use the following abbreviated procedure:

cd /u1/krb5-VERSION/src
./configure
make

That’s it!

Building with separate build directories¶

If you wish to keep separate build directories for each platform, you can do so using the following procedure. (Note, this requires that your make program support VPATH. GNU’s make will provide this functionality, for example.) If your make program does not support this, see the next section.

For example, if you wish to store the binaries in tmpbuild build directory you might use the following procedure:

mkdir /u1/tmpbuild
cd /u1/tmpbuild
/u1/krb5-VERSION/src/configure
make

Building using lndir¶

If you wish to keep separate build directories for each platform, and you do not have access to a make program which supports VPATH, all is not lost. You can use the lndir program to create symbolic link trees in your build directory.

For example, if you wish to create a build directory for solaris binaries you might use the following procedure:

mkdir /u1/krb5-VERSION/solaris
cd /u1/krb5-VERSION/solaris
/u1/krb5-VERSION/src/util/lndir `pwd`/../src
./configure
make

You must give an absolute pathname to lndir because it has a bug that makes it fail for relative pathnames. Note that this version differs from the latest version as distributed and installed by the XConsortium with X11R6. Either version should be acceptable.

Installing the binaries¶

Once you have built Kerberos, you should install the binaries. You can do this by running:

make install

If you want to install the binaries into a destination directory that is not their final destination, which may be convenient if you want to build a binary distribution to be deployed on multiple hosts, you may use:

make install DESTDIR=/path/to/destdir

This will install the binaries under DESTDIR/PREFIX, e.g., the user programs will install into DESTDIR/PREFIX/bin, the libraries into DESTDIR/PREFIX/lib, etc. DESTDIR must be an absolute path.

Some implementations of make allow multiple commands to be run in parallel, for faster builds. We test our Makefiles in parallel builds with GNU make only; they may not be compatible with other parallel build implementations.

Testing the build¶

The Kerberos V5 distribution comes with built-in regression tests. To run them, simply type the following command while in the top-level build directory (i.e., the directory where you sent typed make to start building Kerberos; see Building within a single tree):

make check

On some operating systems, you have to run make install before running make check, or the test suite will pick up installed versions of Kerberos libraries rather than the newly built ones. You can install into a prefix that isn’t in the system library search path, though. Alternatively, you can configure with --disable-rpath, which renders the build tree less suitable for installation, but allows testing without interference from previously installed libraries.

There are additional regression tests available, which are not run by make check. These tests require manual setup and teardown of support infrastructure which is not easily automated, or require excessive resources for ordinary use. The procedure for running the manual tests is documented at https://k5wiki.kerberos.org/wiki/Manual_Testing.

Cleaning up the build¶

  • Use make clean to remove all files generated by running make command.

  • Use make distclean to remove all files generated by running ./configure script. After running make distclean your source tree (ideally) should look like the raw (just un-tarred) source tree.

Using autoconf¶

(If you are not a developer, you can ignore this section.)

In the Kerberos V5 source directory, there is a configure script which automatically determines the compilation environment and creates the proper Makefiles for a particular platform. This configure script is generated using autoconf, which you should already have installed if you will be making changes to src/configure.in.

Normal users will not need to worry about running autoconf; the distribution comes with the configure script already prebuilt.

The autoconf package comes with a script called autoreconf that will automatically run autoconf and autoheader as needed. You should run autoreconf from the top source directory, e.g.:

cd /u1/krb5-VERSION/src
autoreconf --verbose
krb5-1.22.1/doc/html/build/directory_org.html0000664000175000017500000002575015051422713020724 0ustar ghudsonghudson Organization of the source directory — MIT Kerberos Documentation

Organization of the source directory¶

Below is a brief overview of the organization of the complete source directory. More detailed descriptions follow.

appl

Kerberos application client and server programs

ccapi

Credential cache services

clients

Kerberos V5 user programs (See User commands)

config

Configure scripts

config-files

Sample Kerberos configuration files

include

include files needed to build the Kerberos system

kadmin

Administrative interface to the Kerberos database: kadmin, kdb5_util, ktutil.

kdc

Kerberos V5 Authentication Service and Key Distribution Center

lib

Libraries for use with/by Kerberos V5

plugins

Kerberos plugins directory

po

Localization infrastructure

prototype

Templates files containing the MIT copyright message and a placeholder for the title and description of the file.

kprop

Utilities for propagating the database to replica KDCs kprop and kpropd

tests

Test suite

util

Various utilities for building/configuring the code, sending bug reports, etc.

windows

Source code for building Kerberos V5 on Windows (see windows/README)

lib¶

The lib directory contain several subdirectories as well as some definition and glue files.

  • The apputils directory contains the code for the generic network servicing.

  • The crypto subdirectory contains the Kerberos V5 encryption library.

  • The gssapi library contains the Generic Security Services API, which is a library of commands to be used in secure client-server communication.

  • The kadm5 directory contains the libraries for the KADM5 administration utilities.

  • The Kerberos 5 database libraries are contained in kdb.

  • The krb5 directory contains Kerberos 5 API.

  • The rpc directory contains the API for the Kerberos Remote Procedure Call protocol.

util¶

The util directory contains several utility programs and libraries.
  • the programs used to configure and build the code, such as autoconf, lndir, kbuild, reconf, and makedepend, are in this directory.

  • the profile directory contains most of the functions which parse the Kerberos configuration files (krb5.conf and kdc.conf).

  • the Kerberos error table library and utilities (et);

  • the Sub-system library and utilities (ss);

  • database utilities (db2);

  • pseudo-terminal utilities (pty);

  • bug-reporting program send-pr;

  • a generic support library support used by several of our other libraries;

  • the build infrastructure for building lightweight Kerberos client (collected-client-lib)

  • the tool for validating Kerberos configuration files (confvalidator);

  • the toolkit for kernel integrators for building krb5 code subsets (gss-kernel-lib);

  • source code for building Kerberos V5 on MacOS (mac)

  • Windows getopt operations (windows)

krb5-1.22.1/doc/html/build/osconf.html0000664000175000017500000001703215051422713017332 0ustar ghudsonghudson osconf.hin — MIT Kerberos Documentation

osconf.hin¶

There is one configuration file which you may wish to edit to control various compile-time parameters in the Kerberos distribution:

include/osconf.hin

The list that follows is by no means complete, just some of the more interesting variables.

DEFAULT_PROFILE_PATH

The pathname to the file which contains the profiles for the known realms, their KDCs, etc. The default value is /etc/krb5.conf.

DEFAULT_KEYTAB_NAME

The type and pathname to the default server keytab file. The default is DEFKTNAME.

DEFAULT_KDC_ENCTYPE

The default encryption type for the KDC database master key. The default value is aes256-cts-hmac-sha1-96.

RCTMPDIR

The directory which stores replay caches. The default is /var/tmp.

DEFAULT_KDB_FILE

The location of the default database. The default value is LOCALSTATEDIR/krb5kdc/principal.

krb5-1.22.1/doc/html/formats/0000775000175000017500000000000015051422713015526 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/formats/index.html0000664000175000017500000001553315051422713017532 0ustar ghudsonghudson Protocols and file formats — MIT Kerberos Documentation krb5-1.22.1/doc/html/formats/keytab_file_format.html0000664000175000017500000002427015051422713022247 0ustar ghudsonghudson Keytab file format — MIT Kerberos Documentation

Keytab file format¶

There are two versions of the file format used by the FILE keytab type. The first byte of the file always has the value 5, and the value of the second byte contains the version number (1 or 2). Version 1 of the file format uses native byte order for integer representations. Version 2 always uses big-endian byte order.

After the two-byte version indicator, the file contains a sequence of signed 32-bit record lengths followed by key records or holes. A positive record length indicates a valid key entry whose size is equal to or less than the record length. A negative length indicates a zero-filled hole whose size is the inverse of the length. A length of 0 indicates the end of the file.

Key entry format¶

A key entry may be smaller in size than the record length which precedes it, because it may have replaced a hole which is larger than the key entry. Key entries use the following informal grammar:

entry ::=
    principal
    timestamp (32 bits)
    key version (8 bits)
    enctype (16 bits)
    key length (16 bits)
    key contents
    key version (32 bits) [in release 1.14 and later]

principal ::=
    count of components (16 bits) [includes realm in version 1]
    realm (data)
    component1 (data)
    component2 (data)
    ...
    name type (32 bits) [omitted in version 1]

data ::=
    length (16 bits)
    value (length bytes)

The 32-bit key version overrides the 8-bit key version. To determine if it is present, the implementation must check that at least 4 bytes remain in the record after the other fields are read, and that the value of the 32-bit integer contained in those bytes is non-zero.

krb5-1.22.1/doc/html/formats/rcache_file_format.html0000664000175000017500000002115115051422713022210 0ustar ghudsonghudson Replay cache file format — MIT Kerberos Documentation

Replay cache file format¶

This section documents the second version of the replay cache file format, used by the “file2†replay cache type (new in release 1.18). The first version of the file replay cache format is not documented.

All accesses to the replay cache file take place under an exclusive POSIX or Windows file lock, obtained when the file is opened and released when it is closed. Replay cache files are automatically created when first accessed.

For each store operation, a tag is derived from the checksum part of the RFC 3961 ciphertext of the authenticator. The checksum is coerced to a fixed length of 12 bytes, either through truncation or right-padding with zero bytes. A four-byte timestamp is appended to the tag to produce a total record length of 16 bytes.

Bytes 0 through 15 of the file contain a hash seed for the SipHash-2-4 algorithm (siphash); this field is populated with random bytes when the file is first created. All remaining bytes are divided into a series of expanding hash tables:

  • Bytes 16-16383: hash table 1 (1023 slots)

  • Bytes 16384-49151: hash table 2 (2048 slots)

  • Bytes 49152-114687: hash table 3 (4096 slots)

  • …

Only some hash tables will be present in the file at any specific time, and the final table may be only partially filled. Replay cache files may be sparse if the filesystem supports it.

For each table present in the file, the tag is hashed with SipHash-2-4 using the seed recorded in the file. The first byte of the seed is incremented by one (modulo 256) for each table after the first. The resulting hash value is taken modulo one less than the table size (1022 for the first hash table, 2047 for the second) to produce the index. The record may be found at the slot given by the index or at the next slot.

All candidate locations for the record must be searched until a slot is found with a timestamp of zero (indicating a slot which has never been written to) or an offset is reached at or beyond the end of the file. Any candidate location with a timestamp value of zero, with a timestamp value less than the current time minus clockskew, or at or beyond the end of the file is available for writing. When all candidate locations have been searched without finding a match, the new entry is written to the earliest candidate available for writing.

krb5-1.22.1/doc/html/formats/database_formats.html0000664000175000017500000007625115051422713021726 0ustar ghudsonghudson Kerberos Database (KDB) Formats — MIT Kerberos Documentation

Kerberos Database (KDB) Formats¶

Dump format¶

Files created with the kdb5_util dump command begin with a versioned header “kdb5_util load_dump version 7â€. This version has been in use since MIT krb5 release 1.11; some previous versions are supported but are not described here.

Each subsequent line of the dump file contains one or more tab-separated fields describing either a principal entry or a policy entry. The fields of a principal entry line are:

  • the word “princâ€

  • the string “38†(this was originally a length field)

  • the length of the principal name in string form

  • the decimal number of tag-length data elements

  • the decimal number of key-data elements

  • the string “0†(this was originally an extension length field)

  • the principal name in string form

  • the principal attributes as a decimal number; when converted to binary, the bits from least significant to most significant are:

    • disallow_postdated

    • disallow_forwardable

    • disallow_tgt_based

    • disallow_renewable

    • disallow_proxiable

    • disallow_dup_skey

    • disallow_all_tix

    • requires_preauth

    • requires_hwauth

    • requires_pwchange

    • disallow_svr

    • pwchange_service

    • support_desmd5

    • new_princ

    • ok_as_delegate

    • ok_to_auth_as_delegate

    • no_auth_data_required

    • lockdown_keys

  • the maximum ticket lifetime, as a decimal number of seconds

  • the maximum renewable ticket lifetime, as a decimal number of seconds

  • the principal expiration time, as a decimal POSIX timestamp

  • the password expiration time, as a decimal POSIX timestamp

  • the last successful authentication time, as a decimal POSIX timestamp

  • the last failed authentication time, as a decimal POSIX timestamp

  • the decimal number of failed authentications since the last successful authentication time

  • for each tag-length data value:

    • the tag value in decimal

    • the length in decimal

    • the data as a lowercase hexadecimal byte string, or “-1†if the length is 0

  • for each key-data element:

    • the string “2†if this element has non-normal salt type, “1†otherwise

    • the key version number of this element

    • the encryption type

    • the length of the encrypted key value

    • the encrypted key as a lowercase hexadecimal byte string

    • if this element has non-normal salt type:

      • the salt type

      • the length of the salt data

      • the salt data as a lowercase hexadecimal byte string, or the string “-1†if the salt data length is 0

  • the string “-1;†(this was originally an extension field)

The fields of a policy entry line are:

  • the string “policyâ€

  • the policy name

  • the minimum password lifetime as a decimal number of seconds

  • the maximum password lifetime as a decimal number of seconds

  • the minimum password length, in decimal

  • the minimum number of character classes, in decimal

  • the number of historical keys to be stored, in decimal

  • the policy reference count (no longer used)

  • the maximum number of failed authentications before lockout

  • the time interval after which the failed authentication count is reset, as a decimal number of seconds

  • the lockout duration, as a decimal number of seconds

  • the required principal attributes, in decimal (currently unenforced)

  • the maximum ticket lifetime as a decimal number of seconds (currently unenforced)

  • the maximum renewable lifetime as a decimal number of seconds (currently unenforced)

  • the allowed key/salt types, or “-†if unrestricted

  • the number of tag-length values

  • for each tag-length data value:

    • the tag value in decimal

    • the length in decimal

    • the data as a lowercase hexadecimal byte string, or “-1†if the length is 0

Tag-length data formats¶

The currently defined tag-length data types are:

  • (1) last password change: a four-byte little-endian POSIX timestamp giving the last password change time

  • (2) last modification data: a four-byte little-endian POSIX timestamp followed by a zero-terminated principal name in string form, giving the time of the last principal change and the principal who performed it

  • (3) kadmin data: the XDR encoding of a per-principal kadmin data record (see below)

  • (8) master key version: a two-byte little-endian integer containing the master key version used to encrypt this principal’s key data

    1. active kvno: see below

    1. master key auxiliary data: see below

  • (11) string attributes: one or more iterations of a zero-terminated string key followed by a zero-terminated string value

  • (12) alias target principal: a zero-terminated principal name in string form

    1. LDAP object information: see below

  • (768) referral padata: a DER-encoded PA-SVR-REFERRAL-DATA to be sent to a TGS-REQ client within encrypted padata (see Appendix A of RFC 1606)

  • (1792) last admin unlock: a four-byte little-endian POSIX timestamp giving the time of the last administrative account unlock

  • (32767) database arguments: a zero-terminated key=value string (may appear multiple times); used by the kadmin protocol to communicate -x arguments to kadmind

Per-principal kadmin data¶

Per-principal kadmin data records use a modified XDR encoding of the kadmin_data type defined as follows:

struct key_data {
    int numfields;
    unsigned int kvno;
    int enctype;
    int salttype;
    unsigned int keylen;
    unsigned int saltlen;
    opaque key<>;
    opaque salt<>;
};

struct hist_entry {
    key_data keys<>;
};

struct kadmin_data {
    int version_number;
    nullstring policy;
    int aux_attributes;
    unsigned int old_key_next;
    unsigned int admin_history_kvno;
    hist_entry old_keysets<>;
};

The type “nullstring†uses a custom string encoder where the length field is zero or the string length plus one; a length of zero indicates that no policy object is specified for the principal. The field “version_number†contains 0x12345C01. The aux_attributes field contains the bit 0x800 if a policy object is associated with the principal.

Within a key_data record, numfields is 2 if the key data has non-normal salt type, 1 otherwise.

Active kvno and master key auxiliary data¶

These types only appear in the entry of the master key principal (K/M). They use little-endian binary integer encoding.

The active kvno table determines which master key version is active for a given timestamp. It uses the following binary format:

active-key-version-table ::=
    version (16 bits) [with the value 1]
    version entry 1 (key-version-entry)
    version entry 2 (key-version-entry)
    ...

key-version-entry ::=
    key version (16 bits)
    timestamp (32 bits) [when this key version becomes active]

The master key auxiliary data record contains copies of the current master key encrypted in each older master key. It uses the following binary format:

master-key-aux ::=
    version (16 bits) [with the value 1]
    key entry 1 (key-entry)
    key entry 2 (key-entry)
    ...

key-entry ::=
    old master key version (16 bits)
    latest master key version (16 bits)
    latest master key encryption type (16 bits)
    encrypted key length (16 bits)
    encrypted key contents

LDAP object information¶

This type appears in principal entries retrieved with the LDAP KDB module. The value uses the following binary format, using big-endian integer encoding:

ldap-principal-data ::=
    record 1 (ldap-tl-data)
    record 2 (ldap-tl-data)
    ...

ldap-tl-data ::=
    type (8 bits)
    length (16 bits)
    data

The currently defined ldap-tl-data types are (all integers are big-endian):

  • (1) principal type: 16 bits containing the value 1, indicating that the LDAP object containing the principal entry is a standalone principal object

  • (2) principal count: 16 bits containing the number of krbPrincipalName values in the LDAP object

  • (3) user DN: the string representation of the distinguished name of the LDAP object

  • (5) attribute mask: 16 bits indicating which Kerberos-specific LDAP attributes are present in the LDAP object (see below)

  • (7) link DN: the string representation of the distinguished name of an LDAP object this object is linked to; may appear multiple times

When converted to binary, the attribute mask bits, from least significant to most significant, correspond to the following LDAP attributes:

  • krbMaxTicketLife

  • krbMaxRenewableAge

  • krbTicketFlags

  • krbPrincipalExpiration

  • krbTicketPolicyReference

  • krbPrincipalAuthInd

  • krbPwdPolicyReference

  • krbPasswordExpiration

  • krbPrincipalKey

  • krbLastPwdChange

  • krbExtraData

  • krbLastSuccessfulAuth

  • krbLastFailedAuth

  • krbLoginFailedCount

  • krbLastAdminUnlock

  • krbPwdHistory

Alias principal entries¶

To allow aliases to be represented in dump files and within the incremental update protocol, the krb5 database library supports the concept of an alias principal entry. An alias principal entry contains an alias target principal in its tag-length data, has its attributes set to disallow_all_tix, and has zero or empty values for all other fields. The database glue library recognizes alias entries and iteratively looks up the alias target up to a depth of 10 chained aliases. (Added in release 1.22.)

DB2 principal and policy formats¶

The DB2 KDB module uses the string form of a principal name, with zero terminator, as a lookup key for principal entries. Principal entry values use the following binary format with little-endian integer encoding:

db2-principal-entry ::=
    len (16 bits) [always has the value 38]
    attributes (32 bits)
    max ticket lifetime (32 bits)
    max renewable lifetime (32 bits)
    principal expiration timestamp (32 bits)
    password expiration timestamp (32 bits)
    last successful authentication timestamp (32 bits)
    last failed authentication timestamp (32 bits)
    failed authentication counter (32 bits)
    number of tag-length elements (16 bits)
    number of key-data elements (16 bits)
    length of string-form principal with zero terminator (16 bits)
    string-form principal with zero terminator
    tag-length entry 1 (tag-length-data)
    tag-length entry 2 (tag-length-data)
    ...
    key-data entry 1 (key-data)
    key-data entry 2 (key-data)
    ...

tag-length-data ::=
    type tag (16 bits)
    data length (16 bits)
    data

key-data ::=
    salt indicator (16 bits) [1 for default salt, 2 otherwise]
    key version (16 bits)
    encryption type (16 bits)
    encrypted key length (16 bits)
    encrypted key
    salt type (16 bits) [omitted if salt indicator is 1]
    salt data length (16 bits) [omitted if salt indicator is 1]
    salt data [omitted if salt indicator is 1]

DB2 policy entries reside in a separate database file. The lookup key is the policy name with zero terminator. Policy entry values use a modified XDR encoding of the policy type defined as follows:

struct tl_data {
    int type;
    opaque data<>;
    tl_data *next;
};

struct policy {
    int version_number;
    unsigned int min_life;
    unsigned int max_pw_life;
    unsigned int min_length;
    unsigned int min_classes;
    unsigned int history_num;
    unsigned int refcount;
    unsigned int max_fail;
    unsigned int failcount_interval;
    unsigned int lockout_duration;
    unsigned int attributes;
    unsigned int max_ticket_life;
    unsigned int max_renewable_life;
    nullstring allowed_keysalts;
    int n_tl_data;
    tl_data *tag_length_data;
};

The type “nullstring†uses the same custom encoder as in the per-principal kadmin data.

The field “version_number†contains 0x12345D01, 0x12345D02, or 0x12345D03 for versions 1, 2, and 3 respectively. Versions 1 and 2 omit the fields “attributes†through “tag_length_dataâ€. Version 1 also omits the fields “max_fail†through “lockout_durationâ€. Encoding uses the lowest version that can represent the policy entry.

The field “refcount†is no longer used and its value is ignored.

LMDB principal and policy formats¶

In the LMDB KDB module, principal entries are stored in the “principal†database within the main LMDB environment (typically named “principal.mdbâ€), with the exception of lockout-related fields which are stored in the “lockout†table of the lockout LMDB environment (typically named “principal.lockout.mdbâ€). For both databases the key is the principal name in string form, with no zero terminator. Values in the “principal†database use the following binary format with little-endian integer encoding:

lmdb-principal-entry ::=
    attributes (32 bits)
    max ticket lifetime (32 bits)
    max renewable lifetime (32 bits)
    principal expiration timestamp (32 bits)
    password expiration timestamp (32 bits)
    number of tag-length elements (16 bits)
    number of key-data elements (16 bits)
    tag-length entry 1 (tag-length-data)
    tag-length entry 2 (tag-length-data)
    ...
    key-data entry 1 (key-data)
    key-data entry 2 (key-data)
    ...

tag-length-data ::=
    type tag (16 bits)
    data length (16 bits)
    data value

key-data ::=
    salt indicator (16 bits) [1 for default salt, 2 otherwise]
    key version (16 bits)
    encryption type (16 bits)
    encrypted key length (16 bits)
    encrypted key
    salt type (16 bits) [omitted if salt indicator is 1]
    salt data length (16 bits) [omitted if salt indicator is 1]
    salt data [omitted if salt indicator is 1]

Values in the “lockout†database have the following binary format with little-endian integer encoding:

lmdb-lockout-entry ::=
    last successful authentication timestamp (32 bits)
    last failed authentication timestamp (32 bits)
    failed authentication counter (32 bits)

In the “policy†database, the lookup key is the policy name with no zero terminator. Values in this database use the following binary format with little-endian integer encoding:

lmdb-policy-entry ::=
    minimum password lifetime (32 bits)
    maximum password lifetime (32 bits)
    minimum password length (32 bits)
    minimum character classes (32 bits)
    number of historical keys (32 bits)
    maximum failed authentications before lockout (32 bits)
    time interval to reset failed authentication counter (32 bits)
    lockout duration (32 bits)
    required principal attributes (32 bits) [currently unenforced]
    maximum ticket lifetime (32 bits) [currently unenforced]
    maximum renewable lifetime (32 bits) [currently unenforced]
    allowed key/salt type specification length [32 bits]
    allowed key/salt type specification
    number of tag-length values (16 bits)
    tag-length entry 1 (tag-length-data)
    tag-length entry 2 (tag-length-data)
    ...

tag-length-data ::=
    type tag (16 bits)
    data length (16 bits)
    data value
krb5-1.22.1/doc/html/formats/freshness_token.html0000664000175000017500000001654715051422713021631 0ustar ghudsonghudson PKINIT freshness tokens — MIT Kerberos Documentation

PKINIT freshness tokens¶

RFC 8070 specifies a pa-data type PA_AS_FRESHNESS, which clients should reflect within signed PKINIT data to prove recent access to the client certificate private key. The contents of a freshness token are left to the KDC implementation. The MIT krb5 KDC uses the following format for freshness tokens (starting in release 1.17):

  • a four-byte big-endian POSIX timestamp

  • a four-byte big-endian key version number

  • an RFC 3961 checksum, with no ASN.1 wrapper

The checksum is computed using the first key in the local krbtgt principal entry for the realm (e.g. krbtgt/KRBTEST.COM@KRBTEST.COM if the request is to the KRBTEST.COM realm) of the indicated key version. The checksum type must be the mandatory checksum type for the encryption type of the krbtgt key. The key usage value for the checksum is 514.

krb5-1.22.1/doc/html/formats/ccache_file_format.html0000664000175000017500000004350615051422713022201 0ustar ghudsonghudson Credential cache file format — MIT Kerberos Documentation

Credential cache file format¶

There are four versions of the file format used by the FILE credential cache type. The first byte of the file always has the value 5, and the value of the second byte contains the version number (1 through 4). Versions 1 and 2 of the file format use native byte order for integer representations. Versions 3 and 4 always use big-endian byte order.

After the two-byte version indicator, the file has three parts: the header (in version 4 only), the default principal name, and a sequence of credentials.

Header format¶

The header appears only in format version 4. It begins with a 16-bit integer giving the length of the entire header, followed by a sequence of fields. Each field consists of a 16-bit tag, a 16-bit length, and a value of the given length. A file format implementation should ignore fields with unknown tags.

At this time there is only one defined header field. Its tag value is 1, its length is always 8, and its contents are two 32-bit integers giving the seconds and microseconds of the time offset of the KDC relative to the client. Adding this offset to the current time on the client should give the current time on the KDC, if that offset has not changed since the initial authentication.

Principal format¶

The default principal is marshalled using the following informal grammar:

principal ::=
    name type (32 bits) [omitted in version 1]
    count of components (32 bits) [includes realm in version 1]
    realm (data)
    component1 (data)
    component2 (data)
    ...

data ::=
    length (32 bits)
    value (length bytes)

There is no external framing on the default principal, so it must be parsed according to the above grammar in order to find the sequence of credentials which follows.

Credential format¶

The credential format uses the following informal grammar (referencing the principal and data types from the previous section):

credential ::=
    client (principal)
    server (principal)
    keyblock (keyblock)
    authtime (32 bits)
    starttime (32 bits)
    endtime (32 bits)
    renew_till (32 bits)
    is_skey (1 byte, 0 or 1)
    ticket_flags (32 bits)
    addresses (addresses)
    authdata (authdata)
    ticket (data)
    second_ticket (data)

keyblock ::=
    enctype (16 bits) [repeated twice in version 3]
    data

addresses ::=
    count (32 bits)
    address1
    address2
    ...

address ::=
    addrtype (16 bits)
    data

authdata ::=
    count (32 bits)
    authdata1
    authdata2
    ...

authdata ::=
    ad_type (16 bits)
    data

There is no external framing on a marshalled credential, so it must be parsed according to the above grammar in order to find the next credential. There is also no count of credentials or marker at the end of the sequence of credentials; the sequence ends when the file ends.

Credential cache configuration entries¶

Configuration entries are encoded as credential entries. The client principal of the entry is the default principal of the cache. The server principal has the realm X-CACHECONF: and two or three components, the first of which is krb5_ccache_conf_data. The server principal’s second component is the configuration key. The third component, if it exists, is a principal to which the configuration key is associated. The configuration value is stored in the ticket field of the entry. All other entry fields are zeroed.

Programs using credential caches must be aware of configuration entries for several reasons:

  • A program which displays the contents of a cache should not generally display configuration entries.

  • The ticket field of a configuration entry is not (usually) a valid encoding of a Kerberos ticket. An implementation must not treat the cache file as malformed if it cannot decode the ticket field.

  • Configuration entries have an endtime field of 0 and might therefore always be considered expired, but they should not be treated as unimportant as a result. For instance, a program which copies credentials from one cache to another should not omit configuration entries because of the endtime.

The following configuration keys are currently used in MIT krb5:

fast_avail

The presence of this key with a non-empty value indicates that the KDC asserted support for FAST (see RFC 6113) during the initial authentication, using the negotiation method described in RFC 6806 section 11. This key is not associated with any principal.

pa_config_data

The value of this key contains a JSON object representation of parameters remembered by the preauthentication mechanism used during the initial authentication. These parameters may be used when refreshing credentials. This key is associated with the server principal of the initial authentication (usually the local krbtgt principal of the client realm).

pa_type

The value of this key is the ASCII decimal representation of the preauth type number used during the initial authentication. This key is associated with the server principal of the initial authentication.

proxy_impersonator

The presence of this key indicates that the cache is a synthetic delegated credential for use with S4U2Proxy. The value is the name of the intermediate service whose TGT can be used to make S4U2Proxy requests for target services. This key is not associated with any principal.

refresh_time

The presence of this key indicates that the cache was acquired by the GSS mechanism using a client keytab. The value is the ASCII decimal representation of a timestamp at which the GSS mechanism should attempt to refresh the credential cache from the client keytab.

start_realm

This key indicates the realm of the ticket-granting ticket to be used for TGS requests, when making a referrals request or beginning a cross-realm request. If it is not present, the client realm is used.

krb5-1.22.1/doc/html/formats/cookie.html0000664000175000017500000003044015051422713017666 0ustar ghudsonghudson KDC cookie format — MIT Kerberos Documentation
krb5-1.22.1/doc/html/genindex-C.html0000664000175000017500000001570715051422714016735 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/copyright.html0000664000175000017500000001300615051422713016751 0ustar ghudsonghudson Copyright — MIT Kerberos Documentation
krb5-1.22.1/doc/html/admin/0000775000175000017500000000000015051422657015152 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/admin/pkinit.html0000664000175000017500000011032015051422656017332 0ustar ghudsonghudson PKINIT configuration — MIT Kerberos Documentation

PKINIT configuration¶

PKINIT is a preauthentication mechanism for Kerberos 5 which uses X.509 certificates to authenticate the KDC to clients and vice versa. PKINIT can also be used to enable anonymity support, allowing clients to communicate securely with the KDC or with application servers without authenticating as a particular client principal.

Creating certificates¶

PKINIT requires an X.509 certificate for the KDC and one for each client principal which will authenticate using PKINIT. For anonymous PKINIT, a KDC certificate is required, but client certificates are not. A commercially issued server certificate can be used for the KDC certificate, but generally cannot be used for client certificates.

The instruction in this section describe how to establish a certificate authority and create standard PKINIT certificates. Skip this section if you are using a commercially issued server certificate as the KDC certificate for anonymous PKINIT, or if you are configuring a client to use an Active Directory KDC.

Generating a certificate authority certificate¶

You can establish a new certificate authority (CA) for use with a PKINIT deployment with the commands:

openssl genrsa -out cakey.pem 2048
openssl req -key cakey.pem -new -x509 -out cacert.pem -days 3650

The second command will ask for the values of several certificate fields. These fields can be set to any values. You can adjust the expiration time of the CA certificate by changing the number after -days. Since the CA certificate must be deployed to client machines each time it changes, it should normally have an expiration time far in the future; however, expiration times after 2037 may cause interoperability issues in rare circumstances.

The result of these commands will be two files, cakey.pem and cacert.pem. cakey.pem will contain a 2048-bit RSA private key, which must be carefully protected. cacert.pem will contain the CA certificate, which must be placed in the filesystems of the KDC and each client host. cakey.pem will be required to create KDC and client certificates.

Generating a KDC certificate¶

A KDC certificate for use with PKINIT is required to have some unusual fields, which makes generating them with OpenSSL somewhat complicated. First, you will need a file containing the following:

[kdc_cert]
basicConstraints=CA:FALSE
keyUsage=nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
extendedKeyUsage=1.3.6.1.5.2.3.5
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
issuerAltName=issuer:copy
subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name

[kdc_princ_name]
realm=EXP:0,GeneralString:${ENV::REALM}
principal_name=EXP:1,SEQUENCE:kdc_principal_seq

[kdc_principal_seq]
name_type=EXP:0,INTEGER:2
name_string=EXP:1,SEQUENCE:kdc_principals

[kdc_principals]
princ1=GeneralString:krbtgt
princ2=GeneralString:${ENV::REALM}

If the above contents are placed in extensions.kdc, you can generate and sign a KDC certificate with the following commands:

openssl genrsa -out kdckey.pem 2048
openssl req -new -out kdc.req -key kdckey.pem
env REALM=YOUR_REALMNAME openssl x509 -req -in kdc.req \
    -CAkey cakey.pem -CA cacert.pem -out kdc.pem -days 365 \
    -extfile extensions.kdc -extensions kdc_cert -CAcreateserial
rm kdc.req

The second command will ask for the values of certificate fields, which can be set to any values. In the third command, substitute your KDC’s realm name for YOUR_REALMNAME. You can adjust the certificate’s expiration date by changing the number after -days. Remember to create a new KDC certificate before the old one expires.

The result of this operation will be in two files, kdckey.pem and kdc.pem. Both files must be placed in the KDC’s filesystem. kdckey.pem, which contains the KDC’s private key, must be carefully protected.

If you examine the KDC certificate with openssl x509 -in kdc.pem -text -noout, OpenSSL will not know how to display the KDC principal name in the Subject Alternative Name extension, so it will appear as othername:<unsupported>. This is normal and does not mean anything is wrong with the KDC certificate.

Generating client certificates¶

PKINIT client certificates also must have some unusual certificate fields. To generate a client certificate with OpenSSL for a single-component principal name, you will need an extensions file (different from the KDC extensions file above) containing:

[client_cert]
basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment,keyAgreement
extendedKeyUsage=1.3.6.1.5.2.3.4
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
issuerAltName=issuer:copy
subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:princ_name

[princ_name]
realm=EXP:0,GeneralString:${ENV::REALM}
principal_name=EXP:1,SEQUENCE:principal_seq

[principal_seq]
name_type=EXP:0,INTEGER:1
name_string=EXP:1,SEQUENCE:principals

[principals]
princ1=GeneralString:${ENV::CLIENT}

If the above contents are placed in extensions.client, you can generate and sign a client certificate with the following commands:

openssl genrsa -out clientkey.pem 2048
openssl req -new -key clientkey.pem -out client.req
env REALM=YOUR_REALMNAME CLIENT=YOUR_PRINCNAME openssl x509 \
    -CAkey cakey.pem -CA cacert.pem -req -in client.req \
    -extensions client_cert -extfile extensions.client \
    -days 365 -out client.pem
rm client.req

Normally, the first two commands should be run on the client host, and the resulting client.req file transferred to the certificate authority host for the third command. As in the previous steps, the second command will ask for the values of certificate fields, which can be set to any values. In the third command, substitute your realm’s name for YOUR_REALMNAME and the client’s principal name (without realm) for YOUR_PRINCNAME. You can adjust the certificate’s expiration date by changing the number after -days.

The result of this operation will be two files, clientkey.pem and client.pem. Both files must be present on the client’s host; clientkey.pem, which contains the client’s private key, must be protected from access by others.

As in the KDC certificate, OpenSSL will display the client principal name as othername:<unsupported> in the Subject Alternative Name extension of a PKINIT client certificate.

If the client principal name contains more than one component (e.g. host/example.com@REALM), the [principals] section of extensions.client must be altered to contain multiple entries. (Simply setting CLIENT to host/example.com would generate a certificate for host\/example.com@REALM which would not match the multi-component principal name.) For a two-component principal, the section should read:

[principals]
princ1=GeneralString:${ENV::CLIENT1}
princ2=GeneralString:${ENV::CLIENT2}

The environment variables CLIENT1 and CLIENT2 must then be set to the first and second components when running openssl x509.

Configuring the KDC¶

The KDC must have filesystem access to the KDC certificate (kdc.pem) and the KDC private key (kdckey.pem). Configure the following relation in the KDC’s kdc.conf file, either in the [kdcdefaults] section or in a [realms] subsection (with appropriate pathnames):

pkinit_identity = FILE:/var/lib/krb5kdc/kdc.pem,/var/lib/krb5kdc/kdckey.pem

If any clients will authenticate using regular (as opposed to anonymous) PKINIT, the KDC must also have filesystem access to the CA certificate (cacert.pem), and the following configuration (with the appropriate pathname):

pkinit_anchors = FILE:/var/lib/krb5kdc/cacert.pem

Because of the larger size of requests and responses using PKINIT, you may also need to allow TCP access to the KDC:

kdc_tcp_listen = 88

Restart the krb5kdc daemon to pick up the configuration changes.

The principal entry for each PKINIT-using client must be configured to require preauthentication. Ensure this with the command:

kadmin -q 'modprinc +requires_preauth YOUR_PRINCNAME'

Starting with release 1.12, it is possible to remove the long-term keys of a principal entry, which can save some space in the database and help to clarify some PKINIT-related error conditions by not asking for a password:

kadmin -q 'purgekeys -all YOUR_PRINCNAME'

These principal options can also be specified at principal creation time as follows:

kadmin -q 'add_principal +requires_preauth -nokey YOUR_PRINCNAME'

By default, the KDC requires PKINIT client certificates to have the standard Extended Key Usage and Subject Alternative Name attributes for PKINIT. Starting in release 1.16, it is possible to authorize client certificates based on the subject or other criteria instead of the standard PKINIT Subject Alternative Name, by setting the pkinit_cert_match string attribute on each client principal entry. For example:

kadmin set_string user@REALM pkinit_cert_match "<SUBJECT>CN=user@REALM$"

The pkinit_cert_match string attribute follows the syntax used by the krb5.conf pkinit_cert_match relation. To allow the use of non-PKINIT client certificates, it will also be necessary to disable key usage checking using the pkinit_eku_checking relation; for example:

[kdcdefaults]
    pkinit_eku_checking = none

Configuring the clients¶

Client hosts must be configured to trust the issuing authority for the KDC certificate. For a newly established certificate authority, the client host must have filesystem access to the CA certificate (cacert.pem) and the following relation in krb5.conf in the appropriate [realms] subsection (with appropriate pathnames):

pkinit_anchors = FILE:/etc/krb5/cacert.pem

If the KDC certificate is a commercially issued server certificate, the issuing certificate is most likely included in a system directory. You can specify it by filename as above, or specify the whole directory like so:

pkinit_anchors = DIR:/etc/ssl/certs

A commercially issued server certificate will usually not have the standard PKINIT principal name or Extended Key Usage extensions, so the following additional configuration is required:

pkinit_eku_checking = kpServerAuth
pkinit_kdc_hostname = hostname.of.kdc.certificate

Multiple pkinit_kdc_hostname relations can be configured to recognize multiple KDC certificates. If the KDC is an Active Directory domain controller, setting pkinit_kdc_hostname is necessary, but it should not be necessary to set pkinit_eku_checking.

To perform regular (as opposed to anonymous) PKINIT authentication, a client host must have filesystem access to a client certificate (client.pem), and the corresponding private key (clientkey.pem). Configure the following relations in the client host’s krb5.conf file in the appropriate [realms] subsection (with appropriate pathnames):

pkinit_identities = FILE:/etc/krb5/client.pem,/etc/krb5/clientkey.pem

If the KDC and client are properly configured, it should now be possible to run kinit username without entering a password.

Anonymous PKINIT¶

Anonymity support in Kerberos allows a client to obtain a ticket without authenticating as any particular principal. Such a ticket can be used as a FAST armor ticket, or to securely communicate with an application server anonymously.

To configure anonymity support, you must generate or otherwise procure a KDC certificate and configure the KDC host, but you do not need to generate any client certificates. On the KDC, you must set the pkinit_identity variable to provide the KDC certificate, but do not need to set the pkinit_anchors variable or store the issuing certificate if you won’t have any client certificates to verify. On client hosts, you must set the pkinit_anchors variable (and possibly pkinit_kdc_hostname and pkinit_eku_checking) in order to trust the issuing authority for the KDC certificate, but do not need to set the pkinit_identities variable.

Anonymity support is not enabled by default. To enable it, you must create the principal WELLKNOWN/ANONYMOUS using the command:

kadmin -q 'addprinc -randkey WELLKNOWN/ANONYMOUS'

Some Kerberos deployments include application servers which lack proper access control, and grant some level of access to any user who can authenticate. In such an environment, enabling anonymity support on the KDC would present a security issue. If you need to enable anonymity support for TGTs (for use as FAST armor tickets) without enabling anonymous authentication to application servers, you can set the variable restrict_anonymous_to_tgt to true in the appropriate [realms] subsection of the KDC’s kdc.conf file.

To obtain anonymous credentials on a client, run kinit -n, or kinit -n @REALMNAME to specify a realm. The resulting tickets will have the client name WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS.

Freshness tokens¶

Freshness tokens can ensure that the client has recently had access to its certificate private key. If freshness tokens are not required by the KDC, a client program with temporary possession of the private key can compose requests for future timestamps and use them later.

In release 1.17 and later, freshness tokens are supported by the client and are sent by the KDC when the client indicates support for them. Because not all clients support freshness tokens yet, they are not required by default. To check if freshness tokens are supported by a realm’s clients, look in the KDC logs for the lines:

PKINIT: freshness token received from <client principal>
PKINIT: no freshness token received from <client principal>

To require freshness tokens for all clients in a realm (except for clients authenticating anonymously), set the pkinit_require_freshness variable to true in the appropriate [realms] subsection of the KDC’s kdc.conf file. To test that this option is in effect, run kinit -X disable_freshness and verify that authentication is unsuccessful.

krb5-1.22.1/doc/html/admin/index.html0000664000175000017500000002472515051422656017160 0ustar ghudsonghudson For administrators — MIT Kerberos Documentation krb5-1.22.1/doc/html/admin/advanced/0000775000175000017500000000000015051422656016716 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/admin/advanced/index.html0000664000175000017500000002032215051422656020712 0ustar ghudsonghudson Advanced topics — MIT Kerberos Documentation krb5-1.22.1/doc/html/admin/advanced/retiring-des.html0000664000175000017500000020061115051422656022200 0ustar ghudsonghudson Retiring DES — MIT Kerberos Documentation

Retiring DES¶

Version 5 of the Kerberos protocol was originally implemented using the Data Encryption Standard (DES) as a block cipher for encryption. While it was considered secure at the time, advancements in computational ability have rendered DES vulnerable to brute force attacks on its 56-bit keyspace. As such, it is now considered insecure and should not be used (RFC 6649).

History¶

DES was used in the original Kerberos implementation, and was the only cryptosystem in krb5 1.0. Partial support for triple-DES (3DES) was added in version 1.1, with full support following in version 1.2. The Advanced Encryption Standard (AES), which supersedes DES, gained partial support in version 1.3.0 of krb5 and full support in version 1.3.2. However, deployments of krb5 using Kerberos databases created with older versions of krb5 will not necessarily start using strong crypto for ordinary operation without administrator intervention.

MIT krb5 began flagging deprecated encryption types with release 1.17, and removed DES (single-DES) support in release 1.18. As a consequence, a release prior to 1.18 is required to perform these migrations.

Types of keys¶

  • The database master key: This key is not exposed to user requests, but is used to encrypt other key material stored in the kerberos database. The database master key is currently stored as K/M by default.

  • Password-derived keys: User principals frequently have keys derived from a password. When a new password is set, the KDC uses various string2key functions to generate keys in the database for that principal.

  • Keytab keys: Application server principals generally use random keys which are not derived from a password. When the database entry is created, the KDC generates random keys of various enctypes to enter in the database, which are conveyed to the application server and stored in a keytab.

  • Session keys: These are short-term keys generated by the KDC while processing client requests, with an enctype selected by the KDC.

For details on the various enctypes and how enctypes are selected by the KDC for session keys and client/server long-term keys, see Encryption types. When using the kadmin interface to generate new long-term keys, the -e argument can be used to force a particular set of enctypes, overriding the KDC default values.

Note

When the KDC is selecting a session key, it has no knowledge about the kerberos installation on the server which will receive the service ticket, only what keys are in the database for the service principal. In order to allow uninterrupted operation to clients while migrating away from DES, care must be taken to ensure that kerberos installations on application server machines are configured to support newer encryption types before keys of those new encryption types are created in the Kerberos database for those server principals.

Upgrade procedure¶

This procedure assumes that the KDC software has already been upgraded to a modern version of krb5 that supports non-DES keys, so that the only remaining task is to update the actual keys used to service requests. The realm used for demonstrating this procedure, ZONE.MIT.EDU, is an example of the worst-case scenario, where all keys in the realm are DES. The realm was initially created with a very old version of krb5, and supported_enctypes in kdc.conf was set to a value appropriate when the KDC was installed, but was not updated as the KDC was upgraded:

[realms]
        ZONE.MIT.EDU = {
                [...]
                master_key_type = des-cbc-crc
                supported_enctypes = des-cbc-crc:normal des:normal des:v4 des:norealm des:onlyrealm des:afs3
        }

This resulted in the keys for all principals in the realm being forced to DES-only, unless specifically requested using kadmin.

Before starting the upgrade, all KDCs were running krb5 1.11, and the database entries for some “high-value†principals were:

[root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc krbtgt/ZONE.MIT.EDU'
[...]
Number of keys: 1
Key: vno 1, des-cbc-crc:v4
[...]
[root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc kadmin/admin'
[...]
Number of keys: 1
Key: vno 15, des-cbc-crc
[...]
[root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc kadmin/changepw'
[...]
Number of keys: 1
Key: vno 14, des-cbc-crc
[...]

The krbtgt/REALM key appears to have never been changed since creation (its kvno is 1), and all three database entries have only a des-cbc-crc key.

The krbtgt key and KDC keys¶

Perhaps the biggest single-step improvement in the security of the cell is gained by strengthening the key of the ticket-granting service principal, krbtgt/REALM—if this principal’s key is compromised, so is the entire realm. Since the server that will handle service tickets for this principal is the KDC itself, it is easy to guarantee that it will be configured to support any encryption types which might be selected. However, the default KDC behavior when creating new keys is to remove the old keys, which would invalidate all existing tickets issued against that principal, rendering the TGTs cached by clients useless. Instead, a new key can be created with the old key retained, so that existing tickets will still function until their scheduled expiry (see Changing the krbtgt key).

[root@casio krb5kdc]# enctypes=aes256-cts-hmac-sha1-96:normal,\
> aes128-cts-hmac-sha1-96:normal,des3-hmac-sha1:normal,des-cbc-crc:normal
[root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -e ${enctypes} -randkey \
> -keepold krbtgt/ZONE.MIT.EDU"
Authenticating as principal root/admin@ZONE.MIT.EDU with password.
Key for "krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU" randomized.

Note

The new krbtgt@REALM key should be propagated to replica KDCs immediately so that TGTs issued by the primary KDC can be used to issue service tickets on replica KDCs. Replica KDCs will refuse requests using the new TGT kvno until the new krbtgt entry has been propagated to them.

It is necessary to explicitly specify the enctypes for the new database entry, since supported_enctypes has not been changed. Leaving supported_enctypes unchanged makes a potential rollback operation easier, since all new keys of new enctypes are the result of explicit administrator action and can be easily enumerated. Upgrading the krbtgt key should have minimal user-visible disruption other than that described in the note above, since only clients which list the new enctypes as supported will use them, per the procedure in Session key selection. Once the krbtgt key is updated, the session and ticket keys for user TGTs will be strong keys, but subsequent requests for service tickets will still get DES keys until the service principals have new keys generated. Application service remains uninterrupted due to the key-selection procedure on the KDC.

After the change, the database entry is now:

[root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'getprinc krbtgt/ZONE.MIT.EDU'
[...]
Number of keys: 5
Key: vno 2, aes256-cts-hmac-sha1-96
Key: vno 2, aes128-cts-hmac-sha1-96
Key: vno 2, des3-cbc-sha1
Key: vno 2, des-cbc-crc
Key: vno 1, des-cbc-crc:v4
[...]

Since the expected disruptions from rekeying the krbtgt principal are minor, after a short testing period, it is appropriate to rekey the other high-value principals, kadmin/admin@REALM and kadmin/changepw@REALM. These are the service principals used for changing user passwords and updating application keytabs. The kadmin and password-changing services are regular kerberized services, so the session-key-selection algorithm described in Session key selection applies. It is particularly important to have strong session keys for these services, since user passwords and new long-term keys are conveyed over the encrypted channel.

[root@casio krb5kdc]# enctypes=aes256-cts-hmac-sha1-96:normal,\
> aes128-cts-hmac-sha1-96:normal,des3-hmac-sha1:normal
[root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -e ${enctypes} -randkey \
> kadmin/admin"
Authenticating as principal root/admin@ZONE.MIT.EDU with password.
Key for "kadmin/admin@ZONE.MIT.EDU" randomized.
[root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -e ${enctypes} -randkey \
> kadmin/changepw"
Authenticating as principal root/admin@ZONE.MIT.EDU with password.
Key for "kadmin/changepw@ZONE.MIT.EDU" randomized.

It is not necessary to retain a single-DES key for these services, since password changes are not part of normal daily workflow, and disruption from a client failure is likely to be minimal. Furthermore, if a kerberos client experiences failure changing a user password or keytab key, this indicates that that client will become inoperative once services are rekeyed to non-DES enctypes. Such problems can be detected early at this stage, giving more time for corrective action.

Adding strong keys to application servers¶

Before switching the default enctypes for new keys over to strong enctypes, it may be desired to test upgrading a handful of services with the new configuration before flipping the switch for the defaults. This still requires using the -e argument in kadmin to get non-default enctypes:

[root@casio krb5kdc]# enctypes=aes256-cts-hmac-sha1-96:normal,\
> aes128-cts-hmac-sha1-96:normal,des3-cbc-sha1:normal,des-cbc-crc:normal
[root@casio krb5kdc]# kadmin -r ZONE.MIT.EDU -p zephyr/zephyr@ZONE.MIT.EDU -k -t \
> /etc/zephyr/krb5.keytab  -q "ktadd -e ${enctypes} \
> -k /etc/zephyr/krb5.keytab zephyr/zephyr@ZONE.MIT.EDU"
Authenticating as principal zephyr/zephyr@ZONE.MIT.EDU with keytab /etc/zephyr/krb5.keytab.
Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/zephyr/krb5.keytab.
Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/zephyr/krb5.keytab.
Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/zephyr/krb5.keytab.
Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 4, encryption type des-cbc-crc added to keytab WRFILE:/etc/zephyr/krb5.keytab.

Be sure to remove the old keys from the application keytab, per best practice.

[root@casio krb5kdc]# k5srvutil -f /etc/zephyr/krb5.keytab delold
Authenticating as principal zephyr/zephyr@ZONE.MIT.EDU with keytab /etc/zephyr/krb5.keytab.
Entry for principal zephyr/zephyr@ZONE.MIT.EDU with kvno 3 removed from keytab WRFILE:/etc/zephyr/krb5.keytab.

Adding strong keys by default¶

Once the high-visibility services have been rekeyed, it is probably appropriate to change kdc.conf to generate keys with the new encryption types by default. This enables server administrators to generate new enctypes with the change subcommand of k5srvutil, and causes user password changes to add new encryption types for their entries. It will probably be necessary to implement administrative controls to cause all user principal keys to be updated in a reasonable period of time, whether by forcing password changes or a password synchronization service that has access to the current password and can add the new keys.

[realms]
        ZONE.MIT.EDU = {
                supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des3-hmac-sha1:normal des-cbc-crc:normal

Note

The krb5kdc process must be restarted for these changes to take effect.

At this point, all service administrators can update their services and the servers behind them to take advantage of strong cryptography. If necessary, the server’s krb5 installation should be configured and/or upgraded to a version supporting non-DES keys. See Encryption types for krb5 version and configuration settings. Only when the service is configured to accept non-DES keys should the key version number be incremented and new keys generated (k5srvutil change && k5srvutil delold).

root@dr-willy:~# k5srvutil change
Authenticating as principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with keytab /etc/krb5.keytab.
Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type AES-256 CTS mode with 96-bit SHA-1 HMAC added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type AES-128 CTS mode with 96-bit SHA-1 HMAC added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/etc/krb5.keytab.
root@dr-willy:~# klist -e -k -t /etc/krb5.keytab
Keytab name: WRFILE:/etc/krb5.keytab
KVNO Timestamp         Principal
---- ----------------- --------------------------------------------------------
   2 10/10/12 17:03:59 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (DES cbc mode with CRC-32)
   3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (AES-256 CTS mode with 96-bit SHA-1 HMAC)
   3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (AES-128 CTS mode with 96-bit SHA-1 HMAC)
   3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (Triple DES cbc mode with HMAC/sha1)
   3 12/12/12 15:31:19 host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU (DES cbc mode with CRC-32)
root@dr-willy:~# k5srvutil delold
Authenticating as principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with keytab /etc/krb5.keytab.
Entry for principal host/dr-willy.xvm.mit.edu@ZONE.MIT.EDU with kvno 2 removed from keytab WRFILE:/etc/krb5.keytab.

When a single service principal is shared by multiple backend servers in a load-balanced environment, it may be necessary to schedule downtime or adjust the population in the load-balanced pool in order to propagate the updated keytab to all hosts in the pool with minimal service interruption.

Removing DES keys from usage¶

This situation remains something of a testing or transitory state, as new DES keys are still being generated, and will be used if requested by a client. To make more progress removing DES from the realm, the KDC should be configured to not generate such keys by default.

Note

An attacker posing as a client can implement a brute force attack against a DES key for any principal, if that key is in the current (highest-kvno) key list. This attack is only possible if allow_weak_crypto = true is enabled on the KDC. Setting the +requires_preauth flag on a principal forces this attack to be an online attack, much slower than the offline attack otherwise available to the attacker. However, setting this flag on a service principal is not always advisable; see the entry in add_principal for details.

The following KDC configuration will not generate DES keys by default:

[realms]
        ZONE.MIT.EDU = {
                supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal des3-cbc-sha1:normal des3-hmac-sha1:normal

Note

As before, the KDC process must be restarted for this change to take effect. It is best practice to update kdc.conf on all KDCs, not just the primary, to avoid unpleasant surprises should the primary fail and a replica need to be promoted.

It is now appropriate to remove the legacy single-DES key from the krbtgt/REALM entry:

[root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q "cpw -randkey -keepold \
> krbtgt/ZONE.MIT.EDU"
Authenticating as principal host/admin@ATHENA.MIT.EDU with password.
Key for "krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU" randomized.

After the maximum ticket lifetime has passed, the old database entry should be removed.

[root@casio krb5kdc]# kadmin.local -r ZONE.MIT.EDU -q 'purgekeys krbtgt/ZONE.MIT.EDU'
Authenticating as principal root/admin@ZONE.MIT.EDU with password.
Old keys for principal "krbtgt/ZONE.MIT.EDU@ZONE.MIT.EDU" purged.

After the KDC is restarted with the new supported_enctypes, all user password changes and application keytab updates will not generate DES keys by default.

contents-vnder-pressvre:~> kpasswd zonetest@ZONE.MIT.EDU
Password for zonetest@ZONE.MIT.EDU:  [enter old password]
Enter new password:                  [enter new password]
Enter it again:                      [enter new password]
Password changed.
contents-vnder-pressvre:~> kadmin -r ZONE.MIT.EDU -q 'getprinc zonetest'
[...]
Number of keys: 3
Key: vno 9, aes256-cts-hmac-sha1-96
Key: vno 9, aes128-cts-hmac-sha1-96
Key: vno 9, des3-cbc-sha1
[...]

[kaduk@glossolalia ~]$ kadmin -p kaduk@ZONE.MIT.EDU -r ZONE.MIT.EDU -k \
> -t kaduk-zone.keytab -q 'ktadd -k kaduk-zone.keytab kaduk@ZONE.MIT.EDU'
Authenticating as principal kaduk@ZONE.MIT.EDU with keytab kaduk-zone.keytab.
Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:kaduk-zone.keytab.
Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:kaduk-zone.keytab.
Entry for principal kaduk@ZONE.MIT.EDU with kvno 3, encryption type des3-cbc-sha1 added to keytab WRFILE:kaduk-zone.keytab.

Once all principals have been re-keyed, DES support can be disabled on the KDC (allow_weak_crypto = false), and client machines can remove allow_weak_crypto = true from their krb5.conf configuration files, completing the migration. allow_weak_crypto takes precedence over all places where DES enctypes could be explicitly configured. DES keys will not be used, even if they are present, when allow_weak_crypto = false.

Support for legacy services¶

If there remain legacy services which do not support non-DES enctypes (such as older versions of AFS), allow_weak_crypto must remain enabled on the KDC. Client machines need not have this setting, though—applications which require DES can use API calls to allow weak crypto on a per-request basis, overriding the system krb5.conf. However, having allow_weak_crypto set on the KDC means that any principals which have a DES key in the database could still use those keys. To minimize the use of DES in the realm and restrict it to just legacy services which require DES, it is necessary to remove all other DES keys. The realm has been configured such that at password and keytab change, no DES keys will be generated by default. The task then reduces to requiring user password changes and having server administrators update their service keytabs. Administrative outreach will be necessary, and if the desire to eliminate DES is sufficiently strong, the KDC administrators may choose to randkey any principals which have not been rekeyed after some timeout period, forcing the user to contact the helpdesk for access.

The Database Master Key¶

This procedure does not alter K/M@REALM, the key used to encrypt key material in the Kerberos database. (This is the key stored in the stash file on the KDC if stash files are used.) However, the security risk of a single-DES key for K/M is minimal, given that access to material encrypted in K/M (the Kerberos database) is generally tightly controlled. If an attacker can gain access to the encrypted database, they likely have access to the stash file as well, rendering the weak cryptography broken by non-cryptographic means. As such, upgrading K/M to a stronger encryption type is unlikely to be a high-priority task.

Is is possible to upgrade the master key used for the database, if desired. Using kdb5_util’s add_mkey, use_mkey, and update_princ_encryption commands, a new master key can be added and activated for use on new key material, and the existing entries converted to the new master key.

krb5-1.22.1/doc/html/admin/princ_dns.html0000664000175000017500000004157215051422657020030 0ustar ghudsonghudson Principal names and DNS — MIT Kerberos Documentation

Principal names and DNS¶

Kerberos clients can do DNS lookups to canonicalize service principal names. This can cause difficulties when setting up Kerberos application servers, especially when the client’s name for the service is different from what the service thinks its name is.

Service principal names¶

A frequently used kind of principal name is the host-based service principal name. This kind of principal name has two components: a service name and a hostname. For example, imap/imap.example.com is the principal name of the “imap†service on the host “imap.example.comâ€. Other possible service names for the first component include “host†(remote login services such as ssh), “HTTPâ€, and “nfs†(Network File System).

Service administrators often publish well-known hostname aliases that they would prefer users to use instead of the canonical name of the service host. This gives service administrators more flexibility in deploying services. For example, a shell login server might be named “long-vanity-hostname.example.comâ€, but users will naturally prefer to type something like “login.example.comâ€. Hostname aliases also allow for administrators to set up load balancing for some sorts of services based on rotating CNAME records in DNS.

Service principal canonicalization¶

In the MIT krb5 client library, canonicalization of host-based service principals is controlled by the dns_canonicalize_hostname, rnds, and qualify_shortname variables in [libdefaults].

If dns_canonicalize_hostname is set to true (the default value), the client performs forward resolution by looking up the IPv4 and/or IPv6 addresses of the hostname using getaddrinfo(). This process will typically add a domain suffix to the hostname if needed, and follow CNAME records in the DNS. If rdns is also set to true (the default), the client will then perform a reverse lookup of the first returned Internet address using getnameinfo(), finding the name associated with the PTR record.

If dns_canonicalize_hostname is set to false, the hostname is not canonicalized using DNS. If the hostname has only one component (i.e. it contains no “.†characters), the host’s primary DNS search domain will be appended, if there is one. The qualify_shortname variable can be used to override or disable this suffix.

If dns_canonicalize_hostname is set to fallback (added in release 1.18), the hostname is initially treated according to the rules for dns_canonicalize_hostname=false. If a ticket request fails because the service principal is unknown, the hostname will be canonicalized according to the rules for dns_canonicalize_hostname=true and the request will be retried.

In all cases, the hostname is converted to lowercase, and any trailing dot is removed.

Reverse DNS mismatches¶

Sometimes, an enterprise will have control over its forward DNS but not its reverse DNS. The reverse DNS is sometimes under the control of the Internet service provider of the enterprise, and the enterprise may not have much influence in setting up reverse DNS records for its address space. If there are difficulties with getting forward and reverse DNS to match, it is best to set rdns = false on client machines.

Overriding application behavior¶

Applications can choose to use a default hostname component in their service principal name when accepting authentication, which avoids some sorts of hostname mismatches. Because not all relevant applications do this yet, using the krb5.conf setting:

[libdefaults]
    ignore_acceptor_hostname = true

will allow the Kerberos library to override the application’s choice of service principal hostname and will allow a server program to accept incoming authentications using any key in its keytab that matches the service name and realm name (if given). This setting defaults to “false†and is available in releases krb5-1.10 and later.

Provisioning keytabs¶

One service principal entry that should be in the keytab is a principal whose hostname component is the canonical hostname that getaddrinfo() reports for all known aliases for the host. If the reverse DNS information does not match this canonical hostname, an additional service principal entry should be in the keytab for this different hostname.

Specific application advice¶

Secure shell (ssh)¶

Setting GSSAPIStrictAcceptorCheck = no in the configuration file of modern versions of the openssh daemon will allow the daemon to try any key in its keytab when accepting a connection, rather than looking for the keytab entry that matches the host’s own idea of its name (typically the name that gethostname() returns). This requires krb5-1.10 or later.

OpenLDAP (ldapsearch, etc.)¶

OpenLDAP’s SASL implementation performs reverse DNS lookup in order to canonicalize service principal names, even if rdns is set to false in the Kerberos configuration. To disable this behavior, add SASL_NOCANON on to ldap.conf, or set the LDAPSASL_NOCANON environment variable.

krb5-1.22.1/doc/html/admin/lockout.html0000664000175000017500000004456015051422656017530 0ustar ghudsonghudson Account lockout — MIT Kerberos Documentation

Account lockout¶

As of release 1.8, the KDC can be configured to lock out principals after a number of failed authentication attempts within a period of time. Account lockout can make it more difficult to attack a principal’s password by brute force, but also makes it easy for an attacker to deny access to a principal.

Configuring account lockout¶

Account lockout only works for principals with the +requires_preauth flag set. Without this flag, the KDC cannot know whether or not a client successfully decrypted the ticket it issued. It is also important to set the -allow_svr flag on a principal to protect its password from an off-line dictionary attack through a TGS request. You can set these flags on a principal with kadmin as follows:

kadmin: modprinc +requires_preauth -allow_svr PRINCNAME

Account lockout parameters are configured via policy objects. There may be an existing policy associated with user principals (such as the “default†policy), or you may need to create a new one and associate it with each user principal.

The policy parameters related to account lockout are:

Here is an example of setting these parameters on a new policy and associating it with a principal:

kadmin: addpol -maxfailure 10 -failurecountinterval 180
    -lockoutduration 60 lockout_policy
kadmin: modprinc -policy lockout_policy PRINCNAME

Testing account lockout¶

To test that account lockout is working, try authenticating as the principal (hopefully not one that might be in use) multiple times with the wrong password. For instance, if maxfailure is set to 2, you might see:

$ kinit user
Password for user@KRBTEST.COM:
kinit: Password incorrect while getting initial credentials
$ kinit user
Password for user@KRBTEST.COM:
kinit: Password incorrect while getting initial credentials
$ kinit user
kinit: Client's credentials have been revoked while getting initial credentials

Account lockout principal state¶

A principal entry keeps three pieces of state related to account lockout:

  • The time of last successful authentication

  • The time of last failed authentication

  • A counter of failed attempts

The time of last successful authentication is not actually needed for the account lockout system to function, but may be of administrative interest. These fields can be observed with the getprinc kadmin command. For example:

kadmin: getprinc user
Principal: user@KRBTEST.COM
...
Last successful authentication: [never]
Last failed authentication: Mon Dec 03 12:30:33 EST 2012
Failed password attempts: 2
...

A principal which has been locked out can be administratively unlocked with the -unlock option to the modprinc kadmin command:

kadmin: modprinc -unlock PRINCNAME

This command will reset the number of failed attempts to 0.

KDC replication and account lockout¶

The account lockout state of a principal is not replicated by either traditional kprop or incremental propagation. Because of this, the number of attempts an attacker can make within a time period is multiplied by the number of KDCs. For instance, if the maxfailure parameter on a policy is 10 and there are four KDCs in the environment (a primary and three replicas), an attacker could make as many as 40 attempts before the principal is locked out on all four KDCs.

An administrative unlock is propagated from the primary to the replica KDCs during the next propagation. Propagation of an administrative unlock will cause the counter of failed attempts on each replica to reset to 1 on the next failure.

If a KDC environment uses a replication strategy other than kprop or incremental propagation, such as the LDAP KDB module with multi-master LDAP replication, then account lockout state may be replicated between KDCs and the concerns of this section may not apply.

KDC performance and account lockout¶

In order to fully track account lockout state, the KDC must write to the the database on each successful and failed authentication. Writing to the database is generally more expensive than reading from it, so these writes may have a significant impact on KDC performance. As of release 1.9, it is possible to turn off account lockout state tracking in order to improve performance, by setting the disable_last_success and disable_lockout variables in the database module subsection of kdc.conf. For example:

[dbmodules]
    DB = {
        disable_last_success = true
        disable_lockout = true
    }

Of the two variables, setting disable_last_success will usually have the largest positive impact on performance, and will still allow account lockout policies to operate. However, it will make it impossible to observe the last successful authentication time with kadmin.

KDC setup and account lockout¶

To update the account lockout state on principals, the KDC must be able to write to the principal database. For the DB2 module, no special setup is required. For the LDAP module, the KDC DN must be granted write access to the principal objects. If the KDC DN has only read access, account lockout will not function.

krb5-1.22.1/doc/html/admin/auth_indicator.html0000664000175000017500000002631715051422656021045 0ustar ghudsonghudson Authentication indicators — MIT Kerberos Documentation

Authentication indicators¶

As of release 1.14, the KDC can be configured to annotate tickets if the client authenticated using a stronger preauthentication mechanism such as PKINIT or OTP. These annotations are called “authentication indicators.†Service principals can be configured to require particular authentication indicators in order to authenticate to that service. An authentication indicator value can be any string chosen by the KDC administrator; there are no pre-set values.

To use authentication indicators with PKINIT or OTP, first configure the KDC to include an indicator when that preauthentication mechanism is used. For PKINIT, use the pkinit_indicator variable in kdc.conf. For OTP, use the indicator variable in the token type definition, or specify the indicators in the otp user string as described in OTP Preauthentication.

To require an indicator to be present in order to authenticate to a service principal, set the require_auth string attribute on the principal to the indicator value to be required. If you wish to allow one of several indicators to be accepted, you can specify multiple indicator values separated by spaces.

For example, a realm could be configured to set the authentication indicator value “strong†when PKINIT is used to authenticate, using a setting in the [realms] subsection:

pkinit_indicator = strong

A service principal could be configured to require the “strong†authentication indicator value:

$ kadmin setstr host/high.value.server require_auth strong
Password for user/admin@KRBTEST.COM:

A user who authenticates with PKINIT would be able to obtain a ticket for the service principal:

$ kinit -X X509_user_identity=FILE:/my/cert.pem,/my/key.pem user
$ kvno host/high.value.server
host/high.value.server@KRBTEST.COM: kvno = 1

but a user who authenticates with a password would not:

$ kinit user
Password for user@KRBTEST.COM:
$ kvno host/high.value.server
kvno: KDC policy rejects request while getting credentials for
  host/high.value.server@KRBTEST.COM

GSSAPI server applications can inspect authentication indicators through the auth-indicators name attribute.

krb5-1.22.1/doc/html/admin/install.html0000664000175000017500000002652515051422656017517 0ustar ghudsonghudson Installation guide — MIT Kerberos Documentation
krb5-1.22.1/doc/html/admin/realm_config.html0000664000175000017500000006636215051422657020502 0ustar ghudsonghudson Realm configuration decisions — MIT Kerberos Documentation

Realm configuration decisions¶

Before installing Kerberos V5, it is necessary to consider the following issues:

  • The name of your Kerberos realm (or the name of each realm, if you need more than one).

  • How you will assign your hostnames to Kerberos realms.

  • Which ports your KDC and and kadmind services will use, if they will not be using the default ports.

  • How many replica KDCs you need and where they should be located.

  • The hostnames of your primary and replica KDCs.

  • How frequently you will propagate the database from the primary KDC to the replica KDCs.

Realm name¶

Although your Kerberos realm can be any ASCII string, convention is to make it the same as your domain name, in upper-case letters.

For example, hosts in the domain example.com would be in the Kerberos realm:

EXAMPLE.COM

If you need multiple Kerberos realms, MIT recommends that you use descriptive names which end with your domain name, such as:

BOSTON.EXAMPLE.COM
HOUSTON.EXAMPLE.COM

Mapping hostnames onto Kerberos realms¶

Mapping hostnames onto Kerberos realms is done in one of three ways.

The first mechanism works through a set of rules in the [domain_realm] section of krb5.conf. You can specify mappings for an entire domain or on a per-hostname basis. Typically you would do this by specifying the mappings for a given domain or subdomain and listing the exceptions.

The second mechanism is to use KDC host-based service referrals. With this method, the KDC’s krb5.conf has a full [domain_realm] mapping for hosts, but the clients do not, or have mappings for only a subset of the hosts they might contact. When a client needs to contact a server host for which it has no mapping, it will ask the client realm’s KDC for the service ticket, and will receive a referral to the appropriate service realm.

To use referrals, clients must be running MIT krb5 1.6 or later, and the KDC must be running MIT krb5 1.7 or later. The host_based_services and no_host_referral variables in the [realms] section of kdc.conf can be used to fine-tune referral behavior on the KDC.

It is also possible for clients to use DNS TXT records, if dns_lookup_realm is enabled in krb5.conf. Such lookups are disabled by default because DNS is an insecure protocol and security holes could result if DNS records are spoofed. If enabled, the client will try to look up a TXT record formed by prepending the prefix _kerberos to the hostname in question. If that record is not found, the client will attempt a lookup by prepending _kerberos to the host’s domain name, then its parent domain, up to the top-level domain. For the hostname boston.engineering.example.com, the names looked up would be:

_kerberos.boston.engineering.example.com
_kerberos.engineering.example.com
_kerberos.example.com
_kerberos.com

The value of the first TXT record found is taken as the realm name.

Even if you do not choose to use this mechanism within your site, you may wish to set it up anyway, for use when interacting with other sites.

Ports for the KDC and admin services¶

The default ports used by Kerberos are port 88 for the KDC and port 749 for the admin server. You can, however, choose to run on other ports, as long as they are specified in each host’s krb5.conf files or in DNS SRV records, and the kdc.conf file on each KDC. For a more thorough treatment of port numbers used by the Kerberos V5 programs, refer to the Configuring your firewall to work with Kerberos V5.

Replica KDCs¶

Replica KDCs provide an additional source of Kerberos ticket-granting services in the event of inaccessibility of the primary KDC. The number of replica KDCs you need and the decision of where to place them, both physically and logically, depends on the specifics of your network.

Kerberos authentication requires that each client be able to contact a KDC. Therefore, you need to anticipate any likely reason a KDC might be unavailable and have a replica KDC to take up the slack.

Some considerations include:

  • Have at least one replica KDC as a backup, for when the primary KDC is down, is being upgraded, or is otherwise unavailable.

  • If your network is split such that a network outage is likely to cause a network partition (some segment or segments of the network to become cut off or isolated from other segments), have a replica KDC accessible to each segment.

  • If possible, have at least one replica KDC in a different building from the primary, in case of power outages, fires, or other localized disasters.

Hostnames for KDCs¶

MIT recommends that your KDCs have a predefined set of CNAME records (DNS hostname aliases), such as kerberos for the primary KDC and kerberos-1, kerberos-2, … for the replica KDCs. This way, if you need to swap a machine, you only need to change a DNS entry, rather than having to change hostnames.

As of MIT krb5 1.4, clients can locate a realm’s KDCs through DNS using SRV records (RFC 2782), assuming the Kerberos realm name is also a DNS domain name. These records indicate the hostname and port number to contact for that service, optionally with weighting and prioritization. The domain name used in the SRV record name is the realm name. Several different Kerberos-related service names are used:

_kerberos._udp

This is for contacting any KDC by UDP. This entry will be used the most often. Normally you should list port 88 on each of your KDCs.

_kerberos._tcp

This is for contacting any KDC by TCP. Normally you should use port 88. This entry should be omitted if the KDC does not listen on TCP ports, as was the default prior to release 1.13.

_kerberos-master._udp

This entry should refer to those KDCs, if any, that will immediately see password changes to the Kerberos database. If a user is logging in and the password appears to be incorrect, the client will retry with the primary KDC before failing with an “incorrect password†error given.

If you have only one KDC, or for whatever reason there is no accessible KDC that would get database changes faster than the others, you do not need to define this entry.

_kerberos-adm._tcp

This should list port 749 on your primary KDC. Support for it is not complete at this time, but it will eventually be used by the kadmin program and related utilities. For now, you will also need the admin_server variable in krb5.conf.

_kerberos-master._tcp

The corresponding TCP port for _kerberos-master._udp, assuming the primary KDC listens on a TCP port.

_kpasswd._udp

This entry should list port 464 on your primary KDC. It is used when a user changes her password. If this entry is not defined but a _kerberos-adm._tcp entry is defined, the client will use the _kerberos-adm._tcp entry with the port number changed to 464.

_kpasswd._tcp

The corresponding TCP port for _kpasswd._udp.

The DNS SRV specification requires that the hostnames listed be the canonical names, not aliases. So, for example, you might include the following records in your (BIND-style) zone file:

$ORIGIN foobar.com.
_kerberos               TXT       "FOOBAR.COM"
kerberos                CNAME     daisy
kerberos-1              CNAME     use-the-force-luke
kerberos-2              CNAME     bunny-rabbit
_kerberos._udp          SRV       0 0 88 daisy
                        SRV       0 0 88 use-the-force-luke
                        SRV       0 0 88 bunny-rabbit
_kerberos-master._udp   SRV       0 0 88 daisy
_kerberos-adm._tcp      SRV       0 0 749 daisy
_kpasswd._udp           SRV       0 0 464 daisy

Clients can also be configured with the explicit location of services using the kdc, master_kdc, admin_server, and kpasswd_server variables in the [realms] section of krb5.conf. Even if some clients will be configured with explicit server locations, providing SRV records will still benefit unconfigured clients, and be useful for other sites.

Clients can be configured with the sitename realm variable (new in release 1.22). If a site name is set, the client first attempts SRV record lookups with “.*sitename*._sites†inserted after the service and protocol name and before the Kerberos realm. Site-specific records may indicate servers more proximal to the client, allowing for faster access.

KDC Discovery¶

As of MIT krb5 1.15, clients can also locate KDCs in DNS through URI records (RFC 7553). Limitations with the SRV record format may result in extra DNS queries in situations where a client must failover to other transport types, or find a primary server. The URI record can convey more information about a realm’s KDCs with a single query.

The client performs a query for the following URI records:

  • _kerberos.REALM for finding KDCs.

  • _kerberos-adm.REALM for finding kadmin services.

  • _kpasswd.REALM for finding password services.

The URI record includes a priority, weight, and a URI string that consists of case-insensitive colon separated fields, in the form scheme:[flags]:transport:residual.

  • scheme defines the registered URI type. It should always be krb5srv.

  • flags contains zero or more flag characters. Currently the only valid flag is m, which indicates that the record is for a primary server.

  • transport defines the transport type of the residual URL or address. Accepted values are tcp, udp, or kkdcp for the MS-KKDCP type.

  • residual contains the hostname, IP address, or URL to be contacted using the specified transport, with an optional port extension. The MS-KKDCP transport type uses a HTTPS URL, and can include a port and/or path extension.

An example of URI records in a zone file:

_kerberos.EXAMPLE.COM  URI  10 1 krb5srv:m:tcp:kdc1.example.com
                       URI  20 1 krb5srv:m:udp:kdc2.example.com:89
                       URI  40 1 krb5srv::udp:10.10.0.23
                       URI  30 1 krb5srv::kkdcp:https://proxy:89/auth

URI lookups are enabled by default, and can be disabled by setting dns_uri_lookup in the [libdefaults] section of krb5.conf to False. When enabled, URI lookups take precedence over SRV lookups, falling back to SRV lookups if no URI records are found.

The sitename variable in the [realms] section of krb5.conf applies to URI lookups as well as SRV lookups.

Database propagation¶

The Kerberos database resides on the primary KDC, and must be propagated regularly (usually by a cron job) to the replica KDCs. In deciding how frequently the propagation should happen, you will need to balance the amount of time the propagation takes against the maximum reasonable amount of time a user should have to wait for a password change to take effect.

If the propagation time is longer than this maximum reasonable time (e.g., you have a particularly large database, you have a lot of replicas, or you experience frequent network delays), you may wish to cut down on your propagation delay by performing the propagation in parallel. To do this, have the primary KDC propagate the database to one set of replicas, and then have each of these replicas propagate the database to additional replicas.

See also Incremental database propagation

krb5-1.22.1/doc/html/admin/backup_host.html0000664000175000017500000002406015051422656020343 0ustar ghudsonghudson Backups of secure hosts — MIT Kerberos Documentation

Backups of secure hosts¶

When you back up a secure host, you should exclude the host’s keytab file from the backup. If someone obtained a copy of the keytab from a backup, that person could make any host masquerade as the host whose keytab was compromised. In many configurations, knowledge of the host’s keytab also allows root access to the host. This could be particularly dangerous if the compromised keytab was from one of your KDCs. If the machine has a disk crash and the keytab file is lost, it is easy to generate another keytab file. (See Adding principals to keytabs.) If you are unable to exclude particular files from backups, you should ensure that the backups are kept as secure as the host’s root password.

Backing up the Kerberos database¶

As with any file, it is possible that your Kerberos database could become corrupted. If this happens on one of the replica KDCs, you might never notice, since the next automatic propagation of the database would install a fresh copy. However, if it happens to the primary KDC, the corrupted database would be propagated to all of the replicas during the next propagation. For this reason, MIT recommends that you back up your Kerberos database regularly. Because the primary KDC is continuously dumping the database to a file in order to propagate it to the replica KDCs, it is a simple matter to have a cron job periodically copy the dump file to a secure machine elsewhere on your network. (Of course, it is important to make the host where these backups are stored as secure as your KDCs, and to encrypt its transmission across your network.) Then if your database becomes corrupted, you can load the most recent dump onto the primary KDC. (See Dumping and loading a Kerberos database.)

krb5-1.22.1/doc/html/admin/various_envs.html0000664000175000017500000002357415051422657020576 0ustar ghudsonghudson Various links — MIT Kerberos Documentation krb5-1.22.1/doc/html/admin/dbtypes.html0000664000175000017500000005004715051422656017517 0ustar ghudsonghudson Database types — MIT Kerberos Documentation

Database types¶

A Kerberos database can be implemented with one of three built-in database providers, called KDB modules. Software which incorporates the MIT krb5 KDC may also provide its own KDB module. The following subsections describe the three built-in KDB modules and the configuration specific to them.

The database type can be configured with the db_library variable in the [dbmodules] subsection for the realm. For example:

[dbmodules]
    ATHENA.MIT.EDU = {
        db_library = db2
    }

If the ATHENA.MIT.EDU realm subsection contains a database_module setting, then the subsection within [dbmodules] should use that name instead of ATHENA.MIT.EDU.

To transition from one database type to another, stop the kadmind service, use kdb5_util dump to create a dump file, change the db_library value and set any appropriate configuration for the new database type, and use kdb5_util load to create and populate the new database. If the new database type is LDAP, create the new database using kdb5_ldap_util and populate it from the dump file using kdb5_util load -update. Then restart the krb5kdc and kadmind services.

Berkeley database module (db2)¶

The default KDB module is db2, which uses a version of the Berkeley DB library. It creates four files based on the database pathname. If the pathname ends with principal then the four files are:

  • principal, containing principal entry data

  • principal.ok, a lock file for the principal database

  • principal.kadm5, containing policy object data

  • principal.kadm5.lock, a lock file for the policy database

For large databases, the kdb5_util dump command (perhaps invoked by kprop or by kadmind for incremental propagation) may cause krb5kdc to stop for a noticeable period of time while it iterates over the database. This delay can be avoided by disabling account lockout features so that the KDC does not perform database writes (see KDC performance and account lockout). Alternatively, a slower form of iteration can be enabled by setting the unlockiter variable to true. For example:

[dbmodules]
    ATHENA.MIT.EDU = {
        db_library = db2
        unlockiter = true
    }

In rare cases, a power failure or other unclean system shutdown may cause inconsistencies in the internal pointers within a database file, such that kdb5_util dump cannot retrieve all principal entries in the database. In this situation, it may be possible to retrieve all of the principal data by running kdb5_util dump -recurse to iterate over the database using the tree pointers instead of the iteration pointers. Running kdb5_util dump -rev to iterate over the database backwards may also retrieve some of the data which is not retrieved by a normal dump operation.

Lightning Memory-Mapped Database module (klmdb)¶

The klmdb module was added in release 1.17. It uses the LMDB library, and may offer better performance and reliability than the db2 module. It creates four files based on the database pathname. If the pathname ends with principal, then the four files are:

  • principal.mdb, containing policy object data and most principal entry data

  • principal.mdb-lock, a lock file for the primary database

  • principal.lockout.mdb, containing the account lockout attributes (last successful authentication time, last failed authentication time, and number of failed attempts) for each principal entry

  • principal.lockout.mdb-lock, a lock file for the lockout database

Separating out the lockout attributes ensures that the KDC will never block on an administrative operation such as a database dump or load. It also allows the KDC to operate without write access to the primary database. If both account lockout features are disabled (see KDC performance and account lockout), the lockout database files will be created but will not subsequently be opened, and the account lockout attributes will always have zero values.

Because LMDB creates a memory map to the database files, it requires a configured memory map size which also determines the maximum size of the database. This size is applied equally to the two databases, so twice the configured size will be consumed in the process address space; this is primarily a limitation on 32-bit platforms. The default value of 128 megabytes should be sufficient for several hundred thousand principal entries. If the limit is reached, kadmin operations will fail and the error message “Environment mapsize limit reached†will appear in the kadmind log file. In this case, the mapsize variable can be used to increase the map size. The following example sets the map size to 512 megabytes:

[dbmodules]
    ATHENA.MIT.EDU = {
        db_library = klmdb
        mapsize = 512
    }

LMDB has a configurable maximum number of readers. The default value of 128 should be sufficient for most deployments. If you are going to use a large number of KDC worker processes, it may be necessary to set the max_readers variable to a larger number.

By default, LMDB synchronizes database files to disk after each write transaction to ensure durability in the case of an unclean system shutdown. The klmdb module always turns synchronization off for the lockout database to ensure reasonable KDC performance, but leaves it on for the primary database. If high throughput for administrative operations (including password changes) is required, the nosync variable can be set to “true†to disable synchronization for the primary database.

The klmdb module does not support explicit locking with the kadmin lock command.

LDAP module (kldap)¶

The kldap module stores principal and policy data using an LDAP server. To use it you must configure an LDAP server to use the Kerberos schema. See Configuring Kerberos with OpenLDAP back-end for details.

Because krb5kdc is single-threaded, latency in LDAP database accesses may limit KDC operation throughput. If the LDAP server is located on the same server host as the KDC and accessed through an ldapi:// URL, latency should be minimal. If this is not possible, consider starting multiple KDC worker processes with the krb5kdc -w option to enable concurrent processing of KDC requests.

The kldap module does not support explicit locking with the kadmin lock command.

krb5-1.22.1/doc/html/admin/install_kdc.html0000664000175000017500000016740215051422656020340 0ustar ghudsonghudson Installing KDCs — MIT Kerberos Documentation

Installing KDCs¶

When setting up Kerberos in a production environment, it is best to have multiple replica KDCs alongside with a primary KDC to ensure the continued availability of the Kerberized services. Each KDC contains a copy of the Kerberos database. The primary KDC contains the writable copy of the realm database, which it replicates to the replica KDCs at regular intervals. All database changes (such as password changes) are made on the primary KDC. Replica KDCs provide Kerberos ticket-granting services, but not database administration, when the primary KDC is unavailable. MIT recommends that you install all of your KDCs to be able to function as either the primary or one of the replicas. This will enable you to easily switch your primary KDC with one of the replicas if necessary (see Switching primary and replica KDCs). This installation procedure is based on that recommendation.

Warning

  • The Kerberos system relies on the availability of correct time information. Ensure that the primary and all replica KDCs have properly synchronized clocks.

  • It is best to install and run KDCs on secured and dedicated hardware with limited access. If your KDC is also a file server, FTP server, Web server, or even just a client machine, someone who obtained root access through a security hole in any of those areas could potentially gain access to the Kerberos database.

Install and configure the primary KDC¶

Install Kerberos either from the OS-provided packages or from the source (See Building within a single tree).

Note

For the purpose of this document we will use the following names:

kerberos.mit.edu    - primary KDC
kerberos-1.mit.edu  - replica KDC
ATHENA.MIT.EDU      - realm name
.k5.ATHENA.MIT.EDU  - stash file
admin/admin         - admin principal

See MIT Kerberos defaults for the default names and locations of the relevant to this topic files. Adjust the names and paths to your system environment.

Edit KDC configuration files¶

Modify the configuration files, krb5.conf and kdc.conf, to reflect the correct information (such as domain-realm mappings and Kerberos servers names) for your realm. (See MIT Kerberos defaults for the recommended default locations for these files).

Most of the tags in the configuration have default values that will work well for most sites. There are some tags in the krb5.conf file whose values must be specified, and this section will explain those.

If the locations for these configuration files differs from the default ones, set KRB5_CONFIG and KRB5_KDC_PROFILE environment variables to point to the krb5.conf and kdc.conf respectively. For example:

export KRB5_CONFIG=/yourdir/krb5.conf
export KRB5_KDC_PROFILE=/yourdir/kdc.conf

krb5.conf¶

If you are not using DNS TXT records (see Mapping hostnames onto Kerberos realms), you must specify the default_realm in the [libdefaults] section. If you are not using DNS URI or SRV records (see Hostnames for KDCs and KDC Discovery), you must include the kdc tag for each realm in the [realms] section. To communicate with the kadmin server in each realm, the admin_server tag must be set in the [realms] section.

An example krb5.conf file:

[libdefaults]
    default_realm = ATHENA.MIT.EDU

[realms]
    ATHENA.MIT.EDU = {
        kdc = kerberos.mit.edu
        kdc = kerberos-1.mit.edu
        admin_server = kerberos.mit.edu
    }

kdc.conf¶

The kdc.conf file can be used to control the listening ports of the KDC and kadmind, as well as realm-specific defaults, the database type and location, and logging.

An example kdc.conf file:

[kdcdefaults]
    kdc_listen = 88
    kdc_tcp_listen = 88

[realms]
    ATHENA.MIT.EDU = {
        kadmind_port = 749
        max_life = 12h 0m 0s
        max_renewable_life = 7d 0h 0m 0s
        master_key_type = aes256-cts
        supported_enctypes = aes256-cts:normal aes128-cts:normal
        # If the default location does not suit your setup,
        # explicitly configure the following values:
        #    database_name = /var/krb5kdc/principal
        #    key_stash_file = /var/krb5kdc/.k5.ATHENA.MIT.EDU
        #    acl_file = /var/krb5kdc/kadm5.acl
    }

[logging]
    # By default, the KDC and kadmind will log output using
    # syslog.  You can instead send log output to files like this:
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmin.log
    default = FILE:/var/log/krb5lib.log

Replace ATHENA.MIT.EDU and kerberos.mit.edu with the name of your Kerberos realm and server respectively.

Note

You have to have write permission on the target directories (these directories must exist) used by database_name, key_stash_file, and acl_file.

Create the KDC database¶

You will use the kdb5_util command on the primary KDC to create the Kerberos database and the optional stash file.

Note

If you choose not to install a stash file, the KDC will prompt you for the master key each time it starts up. This means that the KDC will not be able to start automatically, such as after a system reboot.

kdb5_util will prompt you for the master password for the Kerberos database. This password can be any string. A good password is one you can remember, but that no one else can guess. Examples of bad passwords are words that can be found in a dictionary, any common or popular name, especially a famous person (or cartoon character), your username in any form (e.g., forward, backward, repeated twice, etc.), and any of the sample passwords that appear in this manual. One example of a password which might be good if it did not appear in this manual is “MITiys4K5!â€, which represents the sentence “MIT is your source for Kerberos 5!†(It’s the first letter of each word, substituting the numeral “4†for the word “forâ€, and includes the punctuation mark at the end.)

The following is an example of how to create a Kerberos database and stash file on the primary KDC, using the kdb5_util command. Replace ATHENA.MIT.EDU with the name of your Kerberos realm:

shell% kdb5_util create -r ATHENA.MIT.EDU -s

Initializing database '/usr/local/var/krb5kdc/principal' for realm 'ATHENA.MIT.EDU',
master key name 'K/M@ATHENA.MIT.EDU'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key:  <= Type the master password.
Re-enter KDC database master key to verify:  <= Type it again.
shell%

This will create five files in LOCALSTATEDIR/krb5kdc (or at the locations specified in kdc.conf):

  • two Kerberos database files, principal, and principal.ok

  • the Kerberos administrative database file, principal.kadm5

  • the administrative database lock file, principal.kadm5.lock

  • the stash file, in this example .k5.ATHENA.MIT.EDU. If you do not want a stash file, run the above command without the -s option.

For more information on administrating Kerberos database see Operations on the Kerberos database.

Add administrators to the ACL file¶

Next, you need create an Access Control List (ACL) file and put the Kerberos principal of at least one of the administrators into it. This file is used by the kadmind daemon to control which principals may view and make privileged modifications to the Kerberos database files. The ACL filename is determined by the acl_file variable in kdc.conf; the default is LOCALSTATEDIR/krb5kdc/kadm5.acl.

For more information on Kerberos ACL file see kadm5.acl.

Add administrators to the Kerberos database¶

Next you need to add administrative principals (i.e., principals who are allowed to administer Kerberos database) to the Kerberos database. You must add at least one principal now to allow communication between the Kerberos administration daemon kadmind and the kadmin program over the network for further administration. To do this, use the kadmin.local utility on the primary KDC. kadmin.local is designed to be run on the primary KDC host without using Kerberos authentication to an admin server; instead, it must have read and write access to the Kerberos database on the local filesystem.

The administrative principals you create should be the ones you added to the ACL file (see Add administrators to the ACL file).

In the following example, the administrative principal admin/admin is created:

shell% kadmin.local

kadmin.local: addprinc admin/admin@ATHENA.MIT.EDU

No policy specified for "admin/admin@ATHENA.MIT.EDU";
assigning "default".
Enter password for principal admin/admin@ATHENA.MIT.EDU:  <= Enter a password.
Re-enter password for principal admin/admin@ATHENA.MIT.EDU:  <= Type it again.
Principal "admin/admin@ATHENA.MIT.EDU" created.
kadmin.local:

Start the Kerberos daemons on the primary KDC¶

At this point, you are ready to start the Kerberos KDC (krb5kdc) and administrative daemons on the primary KDC. To do so, type:

shell% krb5kdc
shell% kadmind

Each server daemon will fork and run in the background.

Note

Assuming you want these daemons to start up automatically at boot time, you can add them to the KDC’s /etc/rc or /etc/inittab file. You need to have a stash file in order to do this.

You can verify that they started properly by checking for their startup messages in the logging locations you defined in krb5.conf (see [logging]). For example:

shell% tail /var/log/krb5kdc.log
Dec 02 12:35:47 beeblebrox krb5kdc[3187](info): commencing operation
shell% tail /var/log/kadmin.log
Dec 02 12:35:52 beeblebrox kadmind[3189](info): starting

Any errors the daemons encounter while starting will also be listed in the logging output.

As an additional verification, check if kinit succeeds against the principals that you have created on the previous step (Add administrators to the Kerberos database). Run:

shell% kinit admin/admin@ATHENA.MIT.EDU

Install the replica KDCs¶

You are now ready to start configuring the replica KDCs.

Note

Assuming you are setting the KDCs up so that you can easily switch the primary KDC with one of the replicas, you should perform each of these steps on the primary KDC as well as the replica KDCs, unless these instructions specify otherwise.

Create host keytabs for replica KDCs¶

Each KDC needs a host key in the Kerberos database. These keys are used for mutual authentication when propagating the database dump file from the primary KDC to the secondary KDC servers.

On the primary KDC, connect to administrative interface and create the host principal for each of the KDCs’ host services. For example, if the primary KDC were called kerberos.mit.edu, and you had a replica KDC named kerberos-1.mit.edu, you would type the following:

shell% kadmin
kadmin: addprinc -randkey host/kerberos.mit.edu
No policy specified for "host/kerberos.mit.edu@ATHENA.MIT.EDU"; assigning "default"
Principal "host/kerberos.mit.edu@ATHENA.MIT.EDU" created.

kadmin: addprinc -randkey host/kerberos-1.mit.edu
No policy specified for "host/kerberos-1.mit.edu@ATHENA.MIT.EDU"; assigning "default"
Principal "host/kerberos-1.mit.edu@ATHENA.MIT.EDU" created.

It is not strictly necessary to have the primary KDC server in the Kerberos database, but it can be handy if you want to be able to swap the primary KDC with one of the replicas.

Next, extract host random keys for all participating KDCs and store them in each host’s default keytab file. Ideally, you should extract each keytab locally on its own KDC. If this is not feasible, you should use an encrypted session to send them across the network. To extract a keytab directly on a replica KDC called kerberos-1.mit.edu, you would execute the following command:

kadmin: ktadd host/kerberos-1.mit.edu
Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption
    type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption
    type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption
    type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption
    type arcfour-hmac added to keytab FILE:/etc/krb5.keytab.

If you are instead extracting a keytab for the replica KDC called kerberos-1.mit.edu on the primary KDC, you should use a dedicated temporary keytab file for that machine’s keytab:

kadmin: ktadd -k /tmp/kerberos-1.keytab host/kerberos-1.mit.edu
Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption
    type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kerberos-1.mit.edu with kvno 2, encryption
    type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.

The file /tmp/kerberos-1.keytab can then be installed as /etc/krb5.keytab on the host kerberos-1.mit.edu.

Configure replica KDCs¶

Database propagation copies the contents of the primary’s database, but does not propagate configuration files, stash files, or the kadm5 ACL file. The following files must be copied by hand to each replica (see MIT Kerberos defaults for the default locations for these files):

  • krb5.conf

  • kdc.conf

  • kadm5.acl

  • master key stash file

Move the copied files into their appropriate directories, exactly as on the primary KDC. kadm5.acl is only needed to allow a replica to swap with the primary KDC.

The database is propagated from the primary KDC to the replica KDCs via the kpropd daemon. You must explicitly specify the principals which are allowed to provide Kerberos dump updates on the replica machine with a new database. Create a file named kpropd.acl in the KDC state directory containing the host principals for each of the KDCs:

host/kerberos.mit.edu@ATHENA.MIT.EDU
host/kerberos-1.mit.edu@ATHENA.MIT.EDU

Note

If you expect that the primary and replica KDCs will be switched at some point of time, list the host principals from all participating KDC servers in kpropd.acl files on all of the KDCs. Otherwise, you only need to list the primary KDC’s host principal in the kpropd.acl files of the replica KDCs.

Then, add the following line to /etc/inetd.conf on each KDC (adjust the path to kpropd):

krb5_prop stream tcp nowait root /usr/local/sbin/kpropd kpropd

You also need to add the following line to /etc/services on each KDC, if it is not already present (assuming that the default port is used):

krb5_prop       754/tcp               # Kerberos replica propagation

Restart inetd daemon.

Alternatively, start kpropd as a stand-alone daemon. This is required when incremental propagation is enabled.

Now that the replica KDC is able to accept database propagation, you’ll need to propagate the database from the primary server.

NOTE: Do not start the replica KDC yet; you still do not have a copy of the primary’s database.

Propagate the database to each replica KDC¶

First, create a dump file of the database on the primary KDC, as follows:

shell% kdb5_util dump /usr/local/var/krb5kdc/replica_datatrans

Then, manually propagate the database to each replica KDC, as in the following example:

shell% kprop -f /usr/local/var/krb5kdc/replica_datatrans kerberos-1.mit.edu

Database propagation to kerberos-1.mit.edu: SUCCEEDED

You will need a script to dump and propagate the database. The following is an example of a Bourne shell script that will do this.

Note

Remember that you need to replace /usr/local/var/krb5kdc with the name of the KDC state directory.

#!/bin/sh

kdclist = "kerberos-1.mit.edu kerberos-2.mit.edu"

kdb5_util dump /usr/local/var/krb5kdc/replica_datatrans

for kdc in $kdclist
do
    kprop -f /usr/local/var/krb5kdc/replica_datatrans $kdc
done

You will need to set up a cron job to run this script at the intervals you decided on earlier (see Database propagation).

Now that the replica KDC has a copy of the Kerberos database, you can start the krb5kdc daemon:

shell% krb5kdc

As with the primary KDC, you will probably want to add this command to the KDCs’ /etc/rc or /etc/inittab files, so they will start the krb5kdc daemon automatically at boot time.

Propagation failed?¶

You may encounter the following error messages. For a more detailed discussion on possible causes and solutions click on the error link to be redirected to Troubleshooting section.

  1. kprop: No route to host while connecting to server

  2. kprop: Connection refused while connecting to server

  3. kprop: Server rejected authentication (during sendauth exchange) while authenticating to server

Add Kerberos principals to the database¶

Once your KDCs are set up and running, you are ready to use kadmin to load principals for your users, hosts, and other services into the Kerberos database. This procedure is described fully in Principals.

You may occasionally want to use one of your replica KDCs as the primary. This might happen if you are upgrading the primary KDC, or if your primary KDC has a disk crash. See the following section for the instructions.

Switching primary and replica KDCs¶

You may occasionally want to use one of your replica KDCs as the primary. This might happen if you are upgrading the primary KDC, or if your primary KDC has a disk crash.

Assuming you have configured all of your KDCs to be able to function as either the primary KDC or a replica KDC (as this document recommends), all you need to do to make the changeover is:

If the primary KDC is still running, do the following on the old primary KDC:

  1. Kill the kadmind process.

  2. Disable the cron job that propagates the database.

  3. Run your database propagation script manually, to ensure that the replicas all have the latest copy of the database (see Propagate the database to each replica KDC).

On the new primary KDC:

  1. Start the kadmind daemon (see Start the Kerberos daemons on the primary KDC).

  2. Set up the cron job to propagate the database (see Propagate the database to each replica KDC).

  3. Switch the CNAMEs of the old and new primary KDCs. If you can’t do this, you’ll need to change the krb5.conf file on every client machine in your Kerberos realm.

Incremental database propagation¶

If you expect your Kerberos database to become large, you may wish to set up incremental propagation to replica KDCs. See Incremental database propagation for details.

krb5-1.22.1/doc/html/admin/conf_files/0000775000175000017500000000000015051422656017260 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/admin/conf_files/index.html0000664000175000017500000002311715051422656021261 0ustar ghudsonghudson Configuration Files — MIT Kerberos Documentation krb5-1.22.1/doc/html/admin/conf_files/kdc_conf.html0000664000175000017500000021626315051422656021726 0ustar ghudsonghudson kdc.conf — MIT Kerberos Documentation

kdc.conf¶

The kdc.conf file supplements krb5.conf for programs which are typically only used on a KDC, such as the krb5kdc and kadmind daemons and the kdb5_util program. Relations documented here may also be specified in krb5.conf; for the KDC programs mentioned, krb5.conf and kdc.conf will be merged into a single configuration profile.

Normally, the kdc.conf file is found in the KDC state directory, LOCALSTATEDIR/krb5kdc. You can override the default location by setting the environment variable KRB5_KDC_PROFILE.

Please note that you need to restart the KDC daemon for any configuration changes to take effect.

Structure¶

The kdc.conf file is set up in the same format as the krb5.conf file.

Sections¶

The kdc.conf file may contain the following sections:

[kdcdefaults]

Default values for KDC behavior

[realms]

Realm-specific database configuration and settings

[dbdefaults]

Default database settings

[dbmodules]

Per-database settings

[logging]

Controls how Kerberos daemons perform logging

[kdcdefaults]¶

Some relations in the [kdcdefaults] section specify default values for realm variables, to be used if the [realms] subsection does not contain a relation for the tag. See the [realms] section for the definitions of these relations.

  • host_based_services

  • kdc_listen

  • kdc_ports

  • kdc_tcp_listen

  • kdc_tcp_ports

  • no_host_referral

  • restrict_anonymous_to_tgt

The following [kdcdefaults] variables have no per-realm equivalent:

kdc_max_dgram_reply_size

Specifies the maximum packet size that can be sent over UDP. The default value is 4096 bytes.

kdc_tcp_listen_backlog

(Integer.) Set the size of the listen queue length for the KDC daemon. The value may be limited by OS settings. The default value is 5.

spake_preauth_kdc_challenge

(String.) Specifies the group for a SPAKE optimistic challenge. See the spake_preauth_groups variable in [libdefaults] for possible values. The default is not to issue an optimistic challenge. (New in release 1.17.)

[realms]¶

Each tag in the [realms] section is the name of a Kerberos realm. The value of the tag is a subsection where the relations define KDC parameters for that particular realm. The following example shows how to define one parameter for the ATHENA.MIT.EDU realm:

[realms]
    ATHENA.MIT.EDU = {
        max_renewable_life = 7d 0h 0m 0s
    }

The following tags may be specified in a [realms] subsection:

acl_file

(String.) Location of the access control list file that kadmind uses to determine which principals are allowed which permissions on the Kerberos database. To operate without an ACL file, set this relation to the empty string with acl_file = "". The default value is LOCALSTATEDIR/krb5kdc/kadm5.acl. For more information on Kerberos ACL file see kadm5.acl.

database_module

(String.) This relation indicates the name of the configuration section under [dbmodules] for database-specific parameters used by the loadable database library. The default value is the realm name. If this configuration section does not exist, default values will be used for all database parameters.

database_name

(String, deprecated.) This relation specifies the location of the Kerberos database for this realm, if the DB2 module is being used and the [dbmodules] configuration section does not specify a database name. The default value is LOCALSTATEDIR/krb5kdc/principal.

default_principal_expiration

(Absolute time string.) Specifies the default expiration date of principals created in this realm. The default value is 0, which means no expiration date.

default_principal_flags

(Flag string.) Specifies the default attributes of principals created in this realm. The format for this string is a comma-separated list of flags, with ‘+’ before each flag that should be enabled and ‘-’ before each flag that should be disabled. The postdateable, forwardable, tgt-based, renewable, proxiable, dup-skey, allow-tickets, and service flags default to enabled.

There are a number of possible flags:

allow-tickets

Enabling this flag means that the KDC will issue tickets for this principal. Disabling this flag essentially deactivates the principal within this realm.

dup-skey

Enabling this flag allows the KDC to issue user-to-user service tickets for this principal.

forwardable

Enabling this flag allows the principal to obtain forwardable tickets.

hwauth

If this flag is enabled, then the principal is required to preauthenticate using a hardware device before receiving any tickets.

no-auth-data-required

Enabling this flag prevents PAC or AD-SIGNEDPATH data from being added to service tickets for the principal.

ok-as-delegate

If this flag is enabled, it hints the client that credentials can and should be delegated when authenticating to the service.

ok-to-auth-as-delegate

Enabling this flag allows the principal to use S4USelf tickets.

postdateable

Enabling this flag allows the principal to obtain postdateable tickets.

preauth

If this flag is enabled on a client principal, then that principal is required to preauthenticate to the KDC before receiving any tickets. On a service principal, enabling this flag means that service tickets for this principal will only be issued to clients with a TGT that has the preauthenticated bit set.

proxiable

Enabling this flag allows the principal to obtain proxy tickets.

pwchange

Enabling this flag forces a password change for this principal.

pwservice

If this flag is enabled, it marks this principal as a password change service. This should only be used in special cases, for example, if a user’s password has expired, then the user has to get tickets for that principal without going through the normal password authentication in order to be able to change the password.

renewable

Enabling this flag allows the principal to obtain renewable tickets.

service

Enabling this flag allows the the KDC to issue service tickets for this principal. In release 1.17 and later, user-to-user service tickets are still allowed if the dup-skey flag is set.

tgt-based

Enabling this flag allows a principal to obtain tickets based on a ticket-granting-ticket, rather than repeating the authentication process that was used to obtain the TGT.

dict_file

(String.) Location of the dictionary file containing strings that are not allowed as passwords. The file should contain one string per line, with no additional whitespace. If none is specified or if there is no policy assigned to the principal, no dictionary checks of passwords will be performed.

disable_pac

(Boolean value.) If true, the KDC will not issue PACs for this realm, and S4U2Self and S4U2Proxy operations will be disabled. The default is false, which will permit the KDC to issue PACs. New in release 1.20.

encrypted_challenge_indicator

(String.) Specifies the authentication indicator value that the KDC asserts into tickets obtained using FAST encrypted challenge pre-authentication. New in 1.16.

host_based_services

(Whitespace- or comma-separated list.) Lists services which will get host-based referral processing even if the server principal is not marked as host-based by the client.

iprop_enable

(Boolean value.) Specifies whether incremental database propagation is enabled. The default value is false.

iprop_ulogsize

(Integer.) Specifies the maximum number of log entries to be retained for incremental propagation. The default value is 1000. Prior to release 1.11, the maximum value was 2500. New in release 1.19.

iprop_master_ulogsize

The name for iprop_ulogsize prior to release 1.19. Its value is used as a fallback if iprop_ulogsize is not specified.

iprop_replica_poll

(Delta time string.) Specifies how often the replica KDC polls for new updates from the primary. The default value is 2m (that is, two minutes). New in release 1.17.

iprop_slave_poll

(Delta time string.) The name for iprop_replica_poll prior to release 1.17. Its value is used as a fallback if iprop_replica_poll is not specified.

iprop_listen

(Whitespace- or comma-separated list.) Specifies the iprop RPC listening addresses and/or ports for the kadmind daemon. Each entry may be an interface address, a port number, or an address and port number separated by a colon. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If kadmind fails to bind to any of the specified addresses, it will fail to start. The default (when iprop_enable is true) is to bind to the wildcard address at the port specified in iprop_port. New in release 1.15.

iprop_port

(Port number.) Specifies the port number to be used for incremental propagation. When iprop_enable is true, this relation is required in the replica KDC configuration file, and this relation or iprop_listen is required in the primary configuration file, as there is no default port number. Port numbers specified in iprop_listen entries will override this port number for the kadmind daemon.

iprop_resync_timeout

(Delta time string.) Specifies the amount of time to wait for a full propagation to complete. This is optional in configuration files, and is used by replica KDCs only. The default value is 5 minutes (5m). New in release 1.11.

iprop_logfile

(File name.) Specifies where the update log file for the realm database is to be stored. The default is to use the database_name entry from the realms section of the krb5 config file, with .ulog appended. (NOTE: If database_name isn’t specified in the realms section, perhaps because the LDAP database back end is being used, or the file name is specified in the [dbmodules] section, then the hard-coded default for database_name is used. Determination of the iprop_logfile default value will not use values from the [dbmodules] section.)

kadmind_listen

(Whitespace- or comma-separated list.) Specifies the kadmin RPC listening addresses and/or ports for the kadmind daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. To disable listening for kadmin RPC connections, set this relation to the empty string with kadmind_listen = "". If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in kadmind_port, or the standard kadmin port (749). New in release 1.15.

kadmind_port

(Port number.) Specifies the port on which the kadmind daemon is to listen for this realm. Port numbers specified in kadmind_listen entries will override this port number. The assigned port for kadmind is 749, which is used by default.

key_stash_file

(String.) Specifies the location where the master key has been stored (via kdb5_util stash). The default is LOCALSTATEDIR/krb5kdc/.k5.REALM, where REALM is the Kerberos realm.

kdc_listen

(Whitespace- or comma-separated list.) Specifies the listening addresses and/or ports for the krb5kdc daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. If no port is specified, the standard port (88) is used. To disable listening on UDP, set this relation to the empty string with kdc_listen = "". If the KDC daemon fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address on the standard port. New in release 1.15.

kdc_ports

(Whitespace- or comma-separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the krb5kdc daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as kdc_listen if that relation is not defined.

kdc_tcp_listen

(Whitespace- or comma-separated list.) Specifies the TCP listening addresses and/or ports for the krb5kdc daemon. The syntax is identical to that of kdc_listen. To disable listening on TCP, set this relation to the empty string with kdc_tcp_listen = "". The default is to bind to the same addresses and ports as for UDP. New in release 1.15.

kdc_tcp_ports

(Whitespace- or comma-separated list, deprecated.) Prior to release 1.15, this relation lists the ports for the krb5kdc daemon to listen on for UDP requests. In release 1.15 and later, it has the same meaning as kdc_tcp_listen if that relation is not defined.

kpasswd_listen

(Comma-separated list.) Specifies the kpasswd listening addresses and/or ports for the kadmind daemon. Each entry may be an interface address, a port number, an address and port number separated by a colon, or a UNIX domain socket pathname. If the address contains colons, enclose it in square brackets. If no address is specified, the wildcard address is used. To disable listening for kpasswd requests, set this relation to the empty string with kpasswd_listen = "". If kadmind fails to bind to any of the specified addresses, it will fail to start. The default is to bind to the wildcard address at the port specified in kpasswd_port, or the standard kpasswd port (464). New in release 1.15.

kpasswd_port

(Port number.) Specifies the port on which the kadmind daemon is to listen for password change requests for this realm. Port numbers specified in kpasswd_listen entries will override this port number. The assigned port for password change requests is 464, which is used by default.

master_key_name

(String.) Specifies the name of the principal associated with the master key. The default is K/M.

master_key_type

(Key type string.) Specifies the master key’s key type. The default value for this is aes256-cts-hmac-sha1-96. For a list of all possible values, see Encryption types.

max_life

(Time duration string.) Specifies the maximum time period for which a ticket may be valid in this realm. The default value is 24 hours.

max_renewable_life

(Time duration string.) Specifies the maximum time period during which a valid ticket may be renewed in this realm. The default value is 0.

no_host_referral

(Whitespace- or comma-separated list.) Lists services to block from getting host-based referral processing, even if the client marks the server principal as host-based or the service is also listed in host_based_services. no_host_referral = * will disable referral processing altogether.

reject_bad_transit

(Boolean value.) If set to true, the KDC will check the list of transited realms for cross-realm tickets against the transit path computed from the realm names and the capaths section of its krb5.conf file; if the path in the ticket to be issued contains any realms not in the computed path, the ticket will not be issued, and an error will be returned to the client instead. If this value is set to false, such tickets will be issued anyways, and it will be left up to the application server to validate the realm transit path.

If the disable-transited-check flag is set in the incoming request, this check is not performed at all. Having the reject_bad_transit option will cause such ticket requests to be rejected always.

This transit path checking and config file option currently apply only to TGS requests.

The default value is true.

restrict_anonymous_to_tgt

(Boolean value.) If set to true, the KDC will reject ticket requests from anonymous principals to service principals other than the realm’s ticket-granting service. This option allows anonymous PKINIT to be enabled for use as FAST armor tickets without allowing anonymous authentication to services. The default value is false. New in release 1.9.

spake_preauth_indicator

(String.) Specifies an authentication indicator value that the KDC asserts into tickets obtained using SPAKE pre-authentication. The default is not to add any indicators. This option may be specified multiple times. New in release 1.17.

supported_enctypes

(List of key:salt strings.) Specifies the default key/salt combinations of principals for this realm. Any principals created through kadmin will have keys of these types. The default value for this tag is aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal. For lists of possible values, see Keysalt lists.

[dbdefaults]¶

The [dbdefaults] section specifies default values for some database parameters, to be used if the [dbmodules] subsection does not contain a relation for the tag. See the [dbmodules] section for the definitions of these relations.

  • ldap_kerberos_container_dn

  • ldap_kdc_dn

  • ldap_kdc_sasl_authcid

  • ldap_kdc_sasl_authzid

  • ldap_kdc_sasl_mech

  • ldap_kdc_sasl_realm

  • ldap_kadmind_dn

  • ldap_kadmind_sasl_authcid

  • ldap_kadmind_sasl_authzid

  • ldap_kadmind_sasl_mech

  • ldap_kadmind_sasl_realm

  • ldap_service_password_file

  • ldap_conns_per_server

[dbmodules]¶

The [dbmodules] section contains parameters used by the KDC database library and database modules. Each tag in the [dbmodules] section is the name of a Kerberos realm or a section name specified by a realm’s database_module parameter. The following example shows how to define one database parameter for the ATHENA.MIT.EDU realm:

[dbmodules]
    ATHENA.MIT.EDU = {
        disable_last_success = true
    }

The following tags may be specified in a [dbmodules] subsection:

database_name

This DB2-specific tag indicates the location of the database in the filesystem. The default is LOCALSTATEDIR/krb5kdc/principal.

db_library

This tag indicates the name of the loadable database module. The value should be db2 for the DB2 module, klmdb for the LMDB module, or kldap for the LDAP module.

disable_last_success

If set to true, suppresses KDC updates to the “Last successful authentication†field of principal entries requiring preauthentication. Setting this flag may improve performance. (Principal entries which do not require preauthentication never update the “Last successful authentication†field.). First introduced in release 1.9.

disable_lockout

If set to true, suppresses KDC updates to the “Last failed authentication†and “Failed password attempts†fields of principal entries requiring preauthentication. Setting this flag may improve performance, but also disables account lockout. First introduced in release 1.9.

ldap_conns_per_server

This LDAP-specific tag indicates the number of connections to be maintained per LDAP server.

ldap_kdc_dn and ldap_kadmind_dn

These LDAP-specific tags indicate the default DN for binding to the LDAP server. The krb5kdc daemon uses ldap_kdc_dn, while the kadmind daemon and other administrative programs use ldap_kadmind_dn. The kadmind DN must have the rights to read and write the Kerberos data in the LDAP database. The KDC DN must have the same rights, unless disable_lockout and disable_last_success are true, in which case it only needs to have rights to read the Kerberos data. These tags are ignored if a SASL mechanism is set with ldap_kdc_sasl_mech or ldap_kadmind_sasl_mech.

ldap_kdc_sasl_mech and ldap_kadmind_sasl_mech

These LDAP-specific tags specify the SASL mechanism (such as EXTERNAL) to use when binding to the LDAP server. New in release 1.13.

ldap_kdc_sasl_authcid and ldap_kadmind_sasl_authcid

These LDAP-specific tags specify the SASL authentication identity to use when binding to the LDAP server. Not all SASL mechanisms require an authentication identity. If the SASL mechanism requires a secret (such as the password for DIGEST-MD5), these tags also determine the name within the ldap_service_password_file where the secret is stashed. New in release 1.13.

ldap_kdc_sasl_authzid and ldap_kadmind_sasl_authzid

These LDAP-specific tags specify the SASL authorization identity to use when binding to the LDAP server. In most circumstances they do not need to be specified. New in release 1.13.

ldap_kdc_sasl_realm and ldap_kadmind_sasl_realm

These LDAP-specific tags specify the SASL realm to use when binding to the LDAP server. In most circumstances they do not need to be set. New in release 1.13.

ldap_kerberos_container_dn

This LDAP-specific tag indicates the DN of the container object where the realm objects will be located.

ldap_servers

This LDAP-specific tag indicates the list of LDAP servers that the Kerberos servers can connect to. The list of LDAP servers is whitespace-separated. The LDAP server is specified by a LDAP URI. It is recommended to use ldapi: or ldaps: URLs to connect to the LDAP server.

ldap_service_password_file

This LDAP-specific tag indicates the file containing the stashed passwords (created by kdb5_ldap_util stashsrvpw) for the ldap_kdc_dn and ldap_kadmind_dn objects, or for the ldap_kdc_sasl_authcid or ldap_kadmind_sasl_authcid names for SASL authentication. This file must be kept secure.

mapsize

This LMDB-specific tag indicates the maximum size of the two database environments in megabytes. The default value is 128. Increase this value to address “Environment mapsize limit reached†errors. New in release 1.17.

max_readers

This LMDB-specific tag indicates the maximum number of concurrent reading processes for the databases. The default value is 128. New in release 1.17.

nosync

This LMDB-specific tag can be set to improve the throughput of kadmind and other administrative agents, at the expense of durability (recent database changes may not survive a power outage or other sudden reboot). It does not affect the throughput of the KDC. The default value is false. New in release 1.17.

unlockiter

If set to true, this DB2-specific tag causes iteration operations to release the database lock while processing each principal. Setting this flag to true can prevent extended blocking of KDC or kadmin operations when dumps of large databases are in progress. First introduced in release 1.13.

The following tag may be specified directly in the [dbmodules] section to control where database modules are loaded from:

db_module_dir

This tag controls where the plugin system looks for database modules. The value should be an absolute path.

[logging]¶

The [logging] section indicates how krb5kdc and kadmind perform logging. It may contain the following relations:

admin_server

Specifies how kadmind performs logging.

kdc

Specifies how krb5kdc performs logging.

default

Specifies how either daemon performs logging in the absence of relations specific to the daemon.

debug

(Boolean value.) Specifies whether debugging messages are included in log outputs other than SYSLOG. Debugging messages are always included in the system log output because syslog performs its own priority filtering. The default value is false. New in release 1.15.

Logging specifications may have the following forms:

FILE=filename or FILE:filename

This value causes the daemon’s logging messages to go to the filename. If the = form is used, the file is overwritten. If the : form is used, the file is appended to.

STDERR

This value causes the daemon’s logging messages to go to its standard error stream.

CONSOLE

This value causes the daemon’s logging messages to go to the console, if the system supports it.

DEVICE=<devicename>

This causes the daemon’s logging messages to go to the specified device.

SYSLOG[:severity[:facility]]

This causes the daemon’s logging messages to go to the system log.

For backward compatibility, a severity argument may be specified, and must be specified in order to specify a facility. This argument will be ignored.

The facility argument specifies the facility under which the messages are logged. This may be any of the following facilities supported by the syslog(3) call minus the LOG_ prefix: KERN, USER, MAIL, DAEMON, AUTH, LPR, NEWS, UUCP, CRON, and LOCAL0 through LOCAL7. If no facility is specified, the default is AUTH.

In the following example, the logging messages from the KDC will go to the console and to the system log under the facility LOG_DAEMON, and the logging messages from the administrative server will be appended to the file /var/adm/kadmin.log and sent to the device /dev/tty04.

[logging]
    kdc = CONSOLE
    kdc = SYSLOG:INFO:DAEMON
    admin_server = FILE:/var/adm/kadmin.log
    admin_server = DEVICE=/dev/tty04

If no logging specification is given, the default is to use syslog. To disable logging entirely, specify default = DEVICE=/dev/null.

[otp]¶

Each subsection of [otp] is the name of an OTP token type. The tags within the subsection define the configuration required to forward a One Time Password request to a RADIUS server.

For each token type, the following tags may be specified:

server

This is the server to send the RADIUS request to. It can be a hostname with optional port, an ip address with optional port, or a Unix domain socket address. The default is LOCALSTATEDIR/krb5kdc/<name>.socket.

secret

This tag indicates a filename (which may be relative to LOCALSTATEDIR/krb5kdc) containing the secret used to encrypt the RADIUS packets. The secret should appear in the first line of the file by itself; leading and trailing whitespace on the line will be removed. If the value of server is a Unix domain socket address, this tag is optional, and an empty secret will be used if it is not specified. Otherwise, this tag is required.

timeout

An integer which specifies the time in seconds during which the KDC should attempt to contact the RADIUS server. This tag is the total time across all retries and should be less than the time which an OTP value remains valid for. The default is 5 seconds.

retries

This tag specifies the number of retries to make to the RADIUS server. The default is 3 retries (4 tries).

strip_realm

If this tag is true, the principal without the realm will be passed to the RADIUS server. Otherwise, the realm will be included. The default value is true.

indicator

This tag specifies an authentication indicator to be included in the ticket if this token type is used to authenticate. This option may be specified multiple times. (New in release 1.14.)

In the following example, requests are sent to a remote server via UDP:

[otp]
    MyRemoteTokenType = {
        server = radius.mydomain.com:1812
        secret = SEmfiajf42$
        timeout = 15
        retries = 5
        strip_realm = true
    }

An implicit default token type named DEFAULT is defined for when the per-principal configuration does not specify a token type. Its configuration is shown below. You may override this token type to something applicable for your situation:

[otp]
    DEFAULT = {
        strip_realm = false
    }

PKINIT options¶

Note

The following are pkinit-specific options. These values may be specified in [kdcdefaults] as global defaults, or within a realm-specific subsection of [realms]. Also note that a realm-specific value over-rides, does not add to, a generic [kdcdefaults] specification. The search order is:

  1. realm-specific subsection of [realms]:

    [realms]
        EXAMPLE.COM = {
            pkinit_anchors = FILE:/usr/local/example.com.crt
        }
    
  2. generic value in the [kdcdefaults] section:

    [kdcdefaults]
        pkinit_anchors = DIR:/usr/local/generic_trusted_cas/
    

For information about the syntax of some of these options, see Specifying PKINIT identity information in krb5.conf.

pkinit_anchors

Specifies the location of trusted anchor (root) certificates which the KDC trusts to sign client certificates. This option is required if pkinit is to be supported by the KDC. This option may be specified multiple times.

pkinit_dh_min_bits

Specifies the minimum strength of Diffie-Hellman group the KDC is willing to accept for key exchange. Valid values in order of increasing strength are 1024, 2048, P-256, 4096, P-384, and P-521. The default is 2048. (P-256, P-384, and P-521 are new in release 1.22.)

pkinit_allow_upn

Specifies that the KDC is willing to accept client certificates with the Microsoft UserPrincipalName (UPN) Subject Alternative Name (SAN). This means the KDC accepts the binding of the UPN in the certificate to the Kerberos principal name. The default value is false.

Without this option, the KDC will only accept certificates with the id-pkinit-san as defined in RFC 4556. There is currently no option to disable SAN checking in the KDC.

pkinit_eku_checking

This option specifies what Extended Key Usage (EKU) values the KDC is willing to accept in client certificates. The values recognized in the kdc.conf file are:

kpClientAuth

This is the default value and specifies that client certificates must have the id-pkinit-KPClientAuth EKU as defined in RFC 4556.

scLogin

If scLogin is specified, client certificates with the Microsoft Smart Card Login EKU (id-ms-kp-sc-logon) will be accepted.

none

If none is specified, then client certificates will not be checked to verify they have an acceptable EKU. The use of this option is not recommended.

pkinit_identity

Specifies the location of the KDC’s X.509 identity information. This option is required if pkinit is to be supported by the KDC.

pkinit_indicator

Specifies an authentication indicator to include in the ticket if pkinit is used to authenticate. This option may be specified multiple times. (New in release 1.14.)

pkinit_pool

Specifies the location of intermediate certificates which may be used by the KDC to complete the trust chain between a client’s certificate and a trusted anchor. This option may be specified multiple times.

pkinit_revoke

Specifies the location of Certificate Revocation List (CRL) information to be used by the KDC when verifying the validity of client certificates. This option may be specified multiple times.

pkinit_require_crl_checking

The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and pkinit_require_crl_checking is false, then verification succeeds.

However, if pkinit_require_crl_checking is true and there is no CRL information available for the issuing CA, then verification fails.

pkinit_require_crl_checking should be set to true if the policy is such that up-to-date CRLs must be present for every CA.

pkinit_require_freshness

Specifies whether to require clients to include a freshness token in PKINIT requests. The default value is false. (New in release 1.17.)

Encryption types¶

Any tag in the configuration files which requires a list of encryption types can be set to some combination of the following strings. Encryption types marked as “weak†and “deprecated†are available for compatibility but not recommended for use.

des3-cbc-raw

Triple DES cbc mode raw (weak)

des3-cbc-sha1 des3-hmac-sha1 des3-cbc-sha1-kd

Triple DES cbc mode with HMAC/sha1 (deprecated)

aes256-cts-hmac-sha1-96 aes256-cts aes256-sha1

AES-256 CTS mode with 96-bit SHA-1 HMAC

aes128-cts-hmac-sha1-96 aes128-cts aes128-sha1

AES-128 CTS mode with 96-bit SHA-1 HMAC

aes256-cts-hmac-sha384-192 aes256-sha2

AES-256 CTS mode with 192-bit SHA-384 HMAC

aes128-cts-hmac-sha256-128 aes128-sha2

AES-128 CTS mode with 128-bit SHA-256 HMAC

arcfour-hmac rc4-hmac arcfour-hmac-md5

RC4 with HMAC/MD5 (deprecated)

arcfour-hmac-exp rc4-hmac-exp arcfour-hmac-md5-exp

Exportable RC4 with HMAC/MD5 (weak)

camellia256-cts-cmac camellia256-cts

Camellia-256 CTS mode with CMAC

camellia128-cts-cmac camellia128-cts

Camellia-128 CTS mode with CMAC

des3

The triple DES family: des3-cbc-sha1

aes

The AES family: aes256-cts-hmac-sha1-96, aes128-cts-hmac-sha1-96, aes256-cts-hmac-sha384-192, and aes128-cts-hmac-sha256-128

rc4

The RC4 family: arcfour-hmac

camellia

The Camellia family: camellia256-cts-cmac and camellia128-cts-cmac

The string DEFAULT can be used to refer to the default set of types for the variable in question. Types or families can be removed from the current list by prefixing them with a minus sign (“-“). Types or families can be prefixed with a plus sign (“+â€) for symmetry; it has the same meaning as just listing the type or family. For example, “DEFAULT -rc4†would be the default set of encryption types with RC4 types removed, and “des3 DEFAULT†would be the default set of encryption types with triple DES types moved to the front.

While aes128-cts and aes256-cts are supported for all Kerberos operations, they are not supported by very old versions of our GSSAPI implementation (krb5-1.3.1 and earlier). Services running versions of krb5 without AES support must not be given keys of these encryption types in the KDC database.

The aes128-sha2 and aes256-sha2 encryption types are new in release 1.15. Services running versions of krb5 without support for these newer encryption types must not be given keys of these encryption types in the KDC database.

Keysalt lists¶

Kerberos keys for users are usually derived from passwords. Kerberos commands and configuration parameters that affect generation of keys take lists of enctype-salttype (“keysaltâ€) pairs, known as keysalt lists. Each keysalt pair is an enctype name followed by a salttype name, in the format enc:salt. Individual keysalt list members are separated by comma (“,â€) characters or space characters. For example:

kadmin -e aes256-cts:normal,aes128-cts:normal

would start up kadmin so that by default it would generate password-derived keys for the aes256-cts and aes128-cts encryption types, using a normal salt.

To ensure that people who happen to pick the same password do not have the same key, Kerberos 5 incorporates more information into the key using something called a salt. The supported salt types are as follows:

normal

default for Kerberos Version 5

norealm

same as the default, without using realm information

onlyrealm

uses only realm information as the salt

special

generate a random salt

Sample kdc.conf File¶

Here’s an example of a kdc.conf file:

[kdcdefaults]
    kdc_listen = 88
    kdc_tcp_listen = 88
[realms]
    ATHENA.MIT.EDU = {
        kadmind_port = 749
        max_life = 12h 0m 0s
        max_renewable_life = 7d 0h 0m 0s
        master_key_type = aes256-cts-hmac-sha1-96
        supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal
        database_module = openldap_ldapconf
    }

[logging]
    kdc = FILE:/usr/local/var/krb5kdc/kdc.log
    admin_server = FILE:/usr/local/var/krb5kdc/kadmin.log

[dbdefaults]
    ldap_kerberos_container_dn = cn=krbcontainer,dc=mit,dc=edu

[dbmodules]
    openldap_ldapconf = {
        db_library = kldap
        disable_last_success = true
        ldap_kdc_dn = "cn=krbadmin,dc=mit,dc=edu"
            # this object needs to have read rights on
            # the realm container and principal subtrees
        ldap_kadmind_dn = "cn=krbadmin,dc=mit,dc=edu"
            # this object needs to have read and write rights on
            # the realm container and principal subtrees
        ldap_service_password_file = /etc/kerberos/service.keyfile
        ldap_servers = ldaps://kerberos.mit.edu
        ldap_conns_per_server = 5
    }

FILES¶

LOCALSTATEDIR/krb5kdc/kdc.conf

SEE ALSO¶

krb5.conf, krb5kdc, kadm5.acl

krb5-1.22.1/doc/html/admin/conf_files/kadm5_acl.html0000664000175000017500000005246115051422656021776 0ustar ghudsonghudson kadm5.acl — MIT Kerberos Documentation

kadm5.acl¶

DESCRIPTION¶

The Kerberos kadmind daemon uses an Access Control List (ACL) file to manage access rights to the Kerberos database. For operations that affect principals, the ACL file also controls which principals can operate on which other principals.

The default location of the Kerberos ACL file is LOCALSTATEDIR/krb5kdc/kadm5.acl unless this is overridden by the acl_file variable in kdc.conf.

SYNTAX¶

Empty lines and lines starting with the sharp sign (#) are ignored. Lines containing ACL entries have the format:

principal  permissions  [target_principal  [restrictions] ]

Note

Line order in the ACL file is important. The first matching entry will control access for an actor principal on a target principal.

principal

(Partially or fully qualified Kerberos principal name.) Specifies the principal whose permissions are to be set.

Each component of the name may be wildcarded using the * character.

permissions

Specifies what operations may or may not be performed by a principal matching a particular entry. This is a string of one or more of the following list of characters or their upper-case counterparts. If the character is upper-case, then the operation is disallowed. If the character is lower-case, then the operation is permitted.

a

[Dis]allows the addition of principals or policies

c

[Dis]allows the changing of passwords for principals

d

[Dis]allows the deletion of principals or policies

e

[Dis]allows the extraction of principal keys

i

[Dis]allows inquiries about principals or policies

l

[Dis]allows the listing of all principals or policies

m

[Dis]allows the modification of principals or policies

p

[Dis]allows the propagation of the principal database (used in Incremental database propagation)

s

[Dis]allows the explicit setting of the key for a principal

x

Short for admcilsp. All privileges (except e)

*

Same as x.

Note

The extract privilege is not included in the wildcard privilege; it must be explicitly assigned. This privilege allows the user to extract keys from the database, and must be handled with great care to avoid disclosure of important keys like those of the kadmin/* or krbtgt/* principals. The lockdown_keys principal attribute can be used to prevent key extraction from specific principals regardless of the granted privilege.

target_principal

(Optional. Partially or fully qualified Kerberos principal name.) Specifies the principal on which permissions may be applied. Each component of the name may be wildcarded using the * character.

target_principal can also include back-references to principal, in which *number matches the corresponding wildcard in principal.

restrictions

(Optional) A string of flags. Allowed restrictions are:

{+|-}flagname

flag is forced to the indicated value. The permissible flags are the same as those for the default_principal_flags variable in kdc.conf.

-clearpolicy

policy is forced to be empty.

-policy pol

policy is forced to be pol.

-{expire, pwexpire, maxlife, maxrenewlife} time

(getdate time string) associated value will be forced to MIN(time, requested value).

The above flags act as restrictions on any add or modify operation which is allowed due to that ACL line.

Warning

If the kadmind ACL file is modified, the kadmind daemon needs to be restarted for changes to take effect.

EXAMPLE¶

Here is an example of a kadm5.acl file:

*/admin@ATHENA.MIT.EDU    *                               # line 1
joeadmin@ATHENA.MIT.EDU   ADMCIL                          # line 2
joeadmin/*@ATHENA.MIT.EDU i   */root@ATHENA.MIT.EDU       # line 3
*/root@ATHENA.MIT.EDU     ci  *1@ATHENA.MIT.EDU           # line 4
*/root@ATHENA.MIT.EDU     l   *                           # line 5
sms@ATHENA.MIT.EDU        x   * -maxlife 9h -postdateable # line 6

(line 1) Any principal in the ATHENA.MIT.EDU realm with an admin instance has all administrative privileges except extracting keys.

(lines 1-3) The user joeadmin has all permissions except extracting keys with his admin instance, joeadmin/admin@ATHENA.MIT.EDU (matches line 1). He has no permissions at all with his null instance, joeadmin@ATHENA.MIT.EDU (matches line 2). His root and other non-admin, non-null instances (e.g., extra or dbadmin) have inquire permissions with any principal that has the instance root (matches line 3).

(line 4) Any root principal in ATHENA.MIT.EDU can inquire or change the password of their null instance, but not any other null instance. (Here, *1 denotes a back-reference to the component matching the first wildcard in the actor principal.)

(line 5) Any root principal in ATHENA.MIT.EDU can generate the list of principals in the database, and the list of policies in the database. This line is separate from line 4, because list permission can only be granted globally, not to specific target principals.

(line 6) Finally, the Service Management System principal sms@ATHENA.MIT.EDU has all permissions except extracting keys, but any principal that it creates or modifies will not be able to get postdateable tickets or tickets with a life of longer than 9 hours.

MODULE BEHAVIOR¶

The ACL file can coexist with other authorization modules in release 1.16 and later, as configured in the kadm5_auth interface section of krb5.conf. The ACL file will positively authorize operations according to the rules above, but will never authoritatively deny an operation, so other modules can authorize operations in addition to those authorized by the ACL file.

To operate without an ACL file, set the acl_file variable in kdc.conf to the empty string with acl_file = "".

SEE ALSO¶

kdc.conf, kadmind

krb5-1.22.1/doc/html/admin/conf_files/krb5_conf.html0000664000175000017500000026423515051422656022032 0ustar ghudsonghudson krb5.conf — MIT Kerberos Documentation

krb5.conf¶

The krb5.conf file contains Kerberos configuration information, including the locations of KDCs and admin servers for the Kerberos realms of interest, defaults for the current realm and for Kerberos applications, and mappings of hostnames onto Kerberos realms. Normally, you should install your krb5.conf file in the directory /etc. You can override the default location by setting the environment variable KRB5_CONFIG. Multiple colon-separated filenames may be specified in KRB5_CONFIG; all files which are present will be read. Starting in release 1.14, directory names can also be specified in KRB5_CONFIG; all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores will be read.

Structure¶

The krb5.conf file is set up in the style of a Windows INI file. Lines beginning with ‘#’ or ‘;’ (possibly after initial whitespace) are ignored as comments. Sections are headed by the section name, in square brackets. Each section may contain zero or more relations, of the form:

foo = bar

or:

fubar = {
    foo = bar
    baz = quux
}

The krb5.conf file can include other files using either of the following directives at the beginning of a line:

include FILENAME
includedir DIRNAME

FILENAME or DIRNAME should be an absolute path. The named file or directory must exist and be readable. Including a directory includes all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores. Starting in release 1.15, files with names ending in “.conf†are also included, unless the name begins with “.â€. Included profile files are syntactically independent of their parents, so each included file must begin with a section header. Starting in release 1.17, files are read in alphanumeric order; in previous releases, they may be read in any order.

Placing a ‘*’ after the closing bracket of a section name indicates that the section is final, meaning that if the same section appears again later, it will be ignored. A subsection can be marked as final by placing a ‘*’ after either the tag name or the closing brace. A relation can be marked as final by placing a ‘*’ after the tag name. Prior to release 1.22, only sections and subsections can be marked as final, and the flag only causes values to be ignored if they appear in later files specified in KRB5_CONFIG, not if they appear later within the same file or an included file.

The krb5.conf file can specify that configuration should be obtained from a loadable module, rather than the file itself, using the following directive at the beginning of a line before any section headers:

module MODULEPATH:RESIDUAL

MODULEPATH may be relative to the library path of the krb5 installation, or it may be an absolute path. RESIDUAL is provided to the module at initialization time. If krb5.conf uses a module directive, kdc.conf should also use one if it exists.

Sections¶

The krb5.conf file may contain the following sections:

[libdefaults]

Settings used by the Kerberos V5 library

[realms]

Realm-specific contact information and settings

[domain_realm]

Maps server hostnames to Kerberos realms

[capaths]

Authentication paths for non-hierarchical cross-realm

[appdefaults]

Settings used by some Kerberos V5 applications

[plugins]

Controls plugin module registration

Additionally, krb5.conf may include any of the relations described in kdc.conf, but it is not a recommended practice.

[libdefaults]¶

The libdefaults section may contain any of the following relations:

allow_des3

Permit the KDC to issue tickets with des3-cbc-sha1 session keys. In future releases, this flag will allow des3-cbc-sha1 to be used at all. The default value for this tag is false. (Added in release 1.21.)

allow_rc4

Permit the KDC to issue tickets with arcfour-hmac session keys. In future releases, this flag will allow arcfour-hmac to be used at all. The default value for this tag is false. (Added in release 1.21.)

allow_weak_crypto

If this flag is set to false, then weak encryption types (as noted in Encryption types in kdc.conf) will be filtered out of the lists default_tgs_enctypes, default_tkt_enctypes, and permitted_enctypes. The default value for this tag is false.

canonicalize

If this flag is set to true, initial ticket requests to the KDC will request canonicalization of the client principal name, and answers with different client principals than the requested principal will be accepted. The default value is false.

ccache_type

This parameter determines the format of credential cache types created by kinit or other programs. The default value is 4, which represents the most current format. Smaller values can be used for compatibility with very old implementations of Kerberos which interact with credential caches on the same host.

clockskew

Sets the maximum allowable amount of clockskew in seconds that the library will tolerate before assuming that a Kerberos message is invalid. The default value is 300 seconds, or five minutes.

The clockskew setting is also used when evaluating ticket start and expiration times. For example, tickets that have reached their expiration time can still be used (and renewed if they are renewable tickets) if they have been expired for a shorter duration than the clockskew setting.

default_ccache_name

This relation specifies the name of the default credential cache. The default is DEFCCNAME. This relation is subject to parameter expansion (see below). New in release 1.11.

default_client_keytab_name

This relation specifies the name of the default keytab for obtaining client credentials. The default is DEFCKTNAME. This relation is subject to parameter expansion (see below). New in release 1.11.

default_keytab_name

This relation specifies the default keytab name to be used by application servers such as sshd. The default is DEFKTNAME. This relation is subject to parameter expansion (see below).

default_rcache_name

This relation specifies the name of the default replay cache. The default is dfl:. This relation is subject to parameter expansion (see below). New in release 1.18.

default_realm

Identifies the default Kerberos realm for the client. Set its value to your Kerberos realm. If this value is not set, then a realm must be specified with every Kerberos principal when invoking programs such as kinit.

default_tgs_enctypes

Identifies the supported list of session key encryption types that the client should request when making a TGS-REQ, in order of preference from highest to lowest. The list may be delimited with commas or whitespace. See Encryption types in kdc.conf for a list of the accepted values for this tag. Starting in release 1.18, the default value is the value of permitted_enctypes. For previous releases or if permitted_enctypes is not set, the default value is aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 aes128-cts-hmac-sha256-128 des3-cbc-sha1 arcfour-hmac-md5 camellia256-cts-cmac camellia128-cts-cmac.

Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded.

default_tkt_enctypes

Identifies the supported list of session key encryption types that the client should request when making an AS-REQ, in order of preference from highest to lowest. The format is the same as for default_tgs_enctypes. Starting in release 1.18, the default value is the value of permitted_enctypes. For previous releases or if permitted_enctypes is not set, the default value is aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 aes128-cts-hmac-sha256-128 des3-cbc-sha1 arcfour-hmac-md5 camellia256-cts-cmac camellia128-cts-cmac.

Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded.

dns_canonicalize_hostname

Indicate whether name lookups will be used to canonicalize hostnames for use in service principal names. Setting this flag to false can improve security by reducing reliance on DNS, but means that short hostnames will not be canonicalized to fully-qualified hostnames. If this option is set to fallback (new in release 1.18), DNS canonicalization will only be performed the server hostname is not found with the original name when requesting credentials. The default value is true.

dns_lookup_kdc

Indicate whether DNS SRV records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. (Note that the admin_server entry must be in the krb5.conf realm information in order to contact kadmind, because the DNS implementation for kadmin is incomplete.)

Enabling this option does open up a type of denial-of-service attack, if someone spoofs the DNS records and redirects you to another server. However, it’s no worse than a denial of service, because that fake KDC will be unable to decode anything you send it (besides the initial ticket request, which has no encrypted data), and anything the fake KDC sends will not be trusted without verification using some secret that it won’t know.

dns_lookup_realm

Indicate whether DNS TXT records should be used to map hostnames to realm names for hostnames not listed in the [domain_realm] section, and to determine the default realm if default_realm is not set. The default value is false.

dns_uri_lookup

Indicate whether DNS URI records should be used to locate the KDCs and other servers for a realm, if they are not listed in the krb5.conf information for the realm. SRV records are used as a fallback if no URI records were found. The default value is true. New in release 1.15.

enforce_ok_as_delegate

If this flag to true, GSSAPI credential delegation will be disabled when the ok-as-delegate flag is not set in the service ticket. If this flag is false, the ok-as-delegate ticket flag is only enforced when an application specifically requests enforcement. The default value is false.

err_fmt

This relation allows for custom error message formatting. If a value is set, error messages will be formatted by substituting a normal error message for %M and an error code for %C in the value.

extra_addresses

This allows a computer to use multiple local addresses, in order to allow Kerberos to work in a network that uses NATs while still using address-restricted tickets. The addresses should be in a comma-separated list. This option has no effect if noaddresses is true.

forwardable

If this flag is true, initial tickets will be forwardable by default, if allowed by the KDC. The default value is false.

ignore_acceptor_hostname

When accepting GSSAPI or krb5 security contexts for host-based service principals, ignore any hostname passed by the calling application, and allow clients to authenticate to any service principal in the keytab matching the service name and realm name (if given). This option can improve the administrative flexibility of server applications on multihomed hosts, but could compromise the security of virtual hosting environments. The default value is false. New in release 1.10.

k5login_authoritative

If this flag is true, principals must be listed in a local user’s k5login file to be granted login access, if a .k5login file exists. If this flag is false, a principal may still be granted login access through other mechanisms even if a k5login file exists but does not list the principal. The default value is true.

k5login_directory

If set, the library will look for a local user’s k5login file within the named directory, with a filename corresponding to the local username. If not set, the library will look for k5login files in the user’s home directory, with the filename .k5login. For security reasons, .k5login files must be owned by the local user or by root.

kcm_mach_service

On macOS only, determines the name of the bootstrap service used to contact the KCM daemon for the KCM credential cache type. If the value is -, Mach RPC will not be used to contact the KCM daemon. The default value is org.h5l.kcm.

kcm_socket

Determines the path to the Unix domain socket used to access the KCM daemon for the KCM credential cache type. If the value is -, Unix domain sockets will not be used to contact the KCM daemon. The default value is /var/run/.heim_org.h5l.kcm-socket.

kdc_default_options

Default KDC options (Xored for multiple values) when requesting initial tickets. By default it is set to 0x00000010 (KDC_OPT_RENEWABLE_OK).

kdc_timesync

Accepted values for this relation are 1 or 0. If it is nonzero, client machines will compute the difference between their time and the time returned by the KDC in the timestamps in the tickets and use this value to correct for an inaccurate system clock when requesting service tickets or authenticating to services. This corrective factor is only used by the Kerberos library; it is not used to change the system clock. The default value is 1.

noaddresses

If this flag is true, requests for initial tickets will not be made with address restrictions set, allowing the tickets to be used across NATs. The default value is true.

permitted_enctypes

Identifies the encryption types that servers will permit for session keys and for ticket and authenticator encryption, ordered by preference from highest to lowest. Starting in release 1.18, this tag also acts as the default value for default_tgs_enctypes and default_tkt_enctypes. The default value for this tag is aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha384-192 aes128-cts-hmac-sha256-128 des3-cbc-sha1 arcfour-hmac-md5 camellia256-cts-cmac camellia128-cts-cmac.

plugin_base_dir

If set, determines the base directory where krb5 plugins are located. The default value is the krb5/plugins subdirectory of the krb5 library directory. This relation is subject to parameter expansion (see below) in release 1.17 and later.

preferred_preauth_types

This allows you to set the preferred preauthentication types which the client will attempt before others which may be advertised by a KDC. The default value for this setting is “17, 16, 15, 14â€, which forces libkrb5 to attempt to use PKINIT if it is supported.

proxiable

If this flag is true, initial tickets will be proxiable by default, if allowed by the KDC. The default value is false.

qualify_shortname

If this string is set, it determines the domain suffix for single-component hostnames when DNS canonicalization is not used (either because dns_canonicalize_hostname is false or because forward canonicalization failed). The default value is the first search domain of the system’s DNS configuration. To disable qualification of shortnames, set this relation to the empty string with qualify_shortname = "". (New in release 1.18.)

rdns

If this flag is true, reverse name lookup will be used in addition to forward name lookup to canonicalizing hostnames for use in service principal names. If dns_canonicalize_hostname is set to false, this flag has no effect. The default value is true.

realm_try_domains

Indicate whether a host’s domain components should be used to determine the Kerberos realm of the host. The value of this variable is an integer: -1 means not to search, 0 means to try the host’s domain itself, 1 means to also try the domain’s immediate parent, and so forth. The library’s usual mechanism for locating Kerberos realms is used to determine whether a domain is a valid realm, which may involve consulting DNS if dns_lookup_kdc is set. The default is not to search domain components.

renew_lifetime

(Time duration string.) Sets the default renewable lifetime for initial ticket requests. The default value is 0.

request_timeout

(Time duration string.) Sets the maximum total time for KDC and password change requests. This timeout does not affect the intervals between requests, so setting a low timeout may result in fewer requests being attempted and/or some servers not being contacted. A value of 0 indicates no specific maximum, in which case requests will time out if no server responds after several tries. The default value is 0. (New in release 1.22.)

spake_preauth_groups

A whitespace or comma-separated list of words which specifies the groups allowed for SPAKE preauthentication. The possible values are:

edwards25519

Edwards25519 curve (RFC 7748)

P-256

NIST P-256 curve (RFC 5480)

P-384

NIST P-384 curve (RFC 5480)

P-521

NIST P-521 curve (RFC 5480)

The default value for the client is edwards25519. The default value for the KDC is empty. New in release 1.17.

ticket_lifetime

(Time duration string.) Sets the default lifetime for initial ticket requests. The default value is 1 day.

udp_preference_limit

When sending a message to the KDC, the library will try using TCP before UDP if the size of the message is above udp_preference_limit. If the message is smaller than udp_preference_limit, then UDP will be tried before TCP. Regardless of the size, both protocols will be tried if the first attempt fails.

verify_ap_req_nofail

If this flag is true, then an attempt to verify initial credentials will fail if the client machine does not have a keytab. The default value is false.

client_aware_channel_bindings

If this flag is true, then all application protocol authentication requests will be flagged to indicate that the application supports channel bindings when operating over a secure channel. The default value is false.

[realms]¶

Each tag in the [realms] section of the file is the name of a Kerberos realm. The value of the tag is a subsection with relations that define the properties of that particular realm. For each realm, the following tags may be specified in the realm’s subsection:

admin_server

Identifies the host where the administration server is running. Typically, this is the primary Kerberos server. This tag must be given a value in order to communicate with the kadmind server for the realm.

auth_to_local

This tag allows you to set a general rule for mapping principal names to local user names. It will be used if there is not an explicit mapping for the principal name that is being translated. The possible values are:

RULE:exp

The local name will be formulated from exp.

The format for exp is [n:string](regexp)s/pattern/replacement/g. The integer n indicates how many components the target principal should have. If this matches, then a string will be formed from string, substituting the realm of the principal for $0 and the n’th component of the principal for $n (e.g., if the principal was johndoe/admin then [2:$2$1foo] would result in the string adminjohndoefoo). If this string matches regexp, then the s//[g] substitution command will be run over the string. The optional g will cause the substitution to be global over the string, instead of replacing only the first match in the string.

DEFAULT

The principal name will be used as the local user name. If the principal has more than one component or is not in the default realm, this rule is not applicable and the conversion will fail.

For example:

[realms]
    ATHENA.MIT.EDU = {
        auth_to_local = RULE:[2:$1](johndoe)s/^.*$/guest/
        auth_to_local = RULE:[2:$1;$2](^.*;admin$)s/;admin$//
        auth_to_local = RULE:[2:$2](^.*;root)s/^.*$/root/
        auth_to_local = DEFAULT
    }

would result in any principal without root or admin as the second component to be translated with the default rule. A principal with a second component of admin will become its first component. root will be used as the local name for any principal with a second component of root. The exception to these two rules are any principals johndoe/*, which will always get the local name guest.

auth_to_local_names

This subsection allows you to set explicit mappings from principal names to local user names. The tag is the mapping name, and the value is the corresponding local user name.

default_domain

This tag specifies the domain used to expand hostnames when translating Kerberos 4 service principals to Kerberos 5 principals (for example, when converting rcmd.hostname to host/hostname.domain).

disable_encrypted_timestamp

If this flag is true, the client will not perform encrypted timestamp preauthentication if requested by the KDC. Setting this flag can help to prevent dictionary attacks by active attackers, if the realm’s KDCs support SPAKE preauthentication or if initial authentication always uses another mechanism or always uses FAST. This flag persists across client referrals during initial authentication. This flag does not prevent the KDC from offering encrypted timestamp. New in release 1.17.

http_anchors

When KDCs and kpasswd servers are accessed through HTTPS proxies, this tag can be used to specify the location of the CA certificate which should be trusted to issue the certificate for a proxy server. If left unspecified, the system-wide default set of CA certificates is used.

The syntax for values is similar to that of values for the pkinit_anchors tag:

FILE: filename

filename is assumed to be the name of an OpenSSL-style ca-bundle file.

DIR: dirname

dirname is assumed to be an directory which contains CA certificates. All files in the directory will be examined; if they contain certificates (in PEM format), they will be used.

ENV: envvar

envvar specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, ENV:X509_PROXY_CA, where environment variable X509_PROXY_CA has been set to FILE:/tmp/my_proxy.pem.

kdc

The name or address of a host running a KDC for the realm, or a UNIX domain socket path of a locally running KDC. An optional port number, separated from the hostname by a colon, may be included. If the name or address contains colons (for example, if it is an IPv6 address), enclose it in square brackets to distinguish the colon from a port separator. For your computer to be able to communicate with the KDC for each realm, this tag must be given a value in each realm subsection in the configuration file, or there must be DNS SRV records specifying the KDCs.

kpasswd_server

The location of the password change server for the realm, using the same syntax as kdc. If there is no such entry, DNS will be queried (unless forbidden by dns_lookup_kdc). Finally, port 464 on the admin_server host will be tried.

master_kdc

The name for primary_kdc prior to release 1.19. Its value is used as a fallback if primary_kdc is not specified.

primary_kdc

Identifies the primary KDC(s). Currently, this tag is used in only one case: If an attempt to get credentials fails because of an invalid password, the client software will attempt to contact the primary KDC, in case the user’s password has just been changed, and the updated database has not been propagated to the replica servers yet. New in release 1.19.

sitename

Specifies the name of the host’s site for the purpose of DNS-based KDC discovery for this realm. New in release 1.22.

v4_instance_convert

This subsection allows the administrator to configure exceptions to the default_domain mapping rule. It contains V4 instances (the tag name) which should be translated to some specific hostname (the tag value) as the second component in a Kerberos V5 principal name.

v4_realm

This relation is used by the krb524 library routines when converting a V5 principal name to a V4 principal name. It is used when the V4 realm name and the V5 realm name are not the same, but still share the same principal names and passwords. The tag value is the Kerberos V4 realm name.

[domain_realm]¶

The [domain_realm] section provides a translation from hostnames to Kerberos realms. Each tag is a domain name, providing the mapping for that domain and all subdomains. If the tag begins with a period (.) then it applies only to subdomains. The Kerberos realm may be identified either in the realms section or using DNS SRV records. Tag names should be in lower case. For example:

[domain_realm]
    crash.mit.edu = TEST.ATHENA.MIT.EDU
    .dev.mit.edu = TEST.ATHENA.MIT.EDU
    mit.edu = ATHENA.MIT.EDU

maps the host with the name crash.mit.edu into the TEST.ATHENA.MIT.EDU realm. The second entry maps all hosts under the domain dev.mit.edu into the TEST.ATHENA.MIT.EDU realm, but not the host with the name dev.mit.edu. That host is matched by the third entry, which maps the host mit.edu and all hosts under the domain mit.edu that do not match a preceding rule into the realm ATHENA.MIT.EDU.

If no translation entry applies to a hostname used for a service principal for a service ticket request, the library will try to get a referral to the appropriate realm from the client realm’s KDC. If that does not succeed, the host’s realm is considered to be the hostname’s domain portion converted to uppercase, unless the realm_try_domains setting in [libdefaults] causes a different parent domain to be used.

[capaths]¶

In order to perform direct (non-hierarchical) cross-realm authentication, configuration is needed to determine the authentication paths between realms.

A client will use this section to find the authentication path between its realm and the realm of the server. The server will use this section to verify the authentication path used by the client, by checking the transited field of the received ticket.

There is a tag for each participating client realm, and each tag has subtags for each of the server realms. The value of the subtags is an intermediate realm which may participate in the cross-realm authentication. The subtags may be repeated if there is more then one intermediate realm. A value of “.†means that the two realms share keys directly, and no intermediate realms should be allowed to participate.

Only those entries which will be needed on the client or the server need to be present. A client needs a tag for its local realm with subtags for all the realms of servers it will need to authenticate to. A server needs a tag for each realm of the clients it will serve, with a subtag of the server realm.

For example, ANL.GOV, PNL.GOV, and NERSC.GOV all wish to use the ES.NET realm as an intermediate realm. ANL has a sub realm of TEST.ANL.GOV which will authenticate with NERSC.GOV but not PNL.GOV. The [capaths] section for ANL.GOV systems would look like this:

[capaths]
    ANL.GOV = {
        TEST.ANL.GOV = .
        PNL.GOV = ES.NET
        NERSC.GOV = ES.NET
        ES.NET = .
    }
    TEST.ANL.GOV = {
        ANL.GOV = .
    }
    PNL.GOV = {
        ANL.GOV = ES.NET
    }
    NERSC.GOV = {
        ANL.GOV = ES.NET
    }
    ES.NET = {
        ANL.GOV = .
    }

The [capaths] section of the configuration file used on NERSC.GOV systems would look like this:

[capaths]
    NERSC.GOV = {
        ANL.GOV = ES.NET
        TEST.ANL.GOV = ES.NET
        TEST.ANL.GOV = ANL.GOV
        PNL.GOV = ES.NET
        ES.NET = .
    }
    ANL.GOV = {
        NERSC.GOV = ES.NET
    }
    PNL.GOV = {
        NERSC.GOV = ES.NET
    }
    ES.NET = {
        NERSC.GOV = .
    }
    TEST.ANL.GOV = {
        NERSC.GOV = ANL.GOV
        NERSC.GOV = ES.NET
    }

When a subtag is used more than once within a tag, clients will use the order of values to determine the path. The order of values is not important to servers.

[appdefaults]¶

Each tag in the [appdefaults] section names a Kerberos V5 application or an option that is used by some Kerberos V5 application[s]. The value of the tag defines the default behaviors for that application.

For example:

[appdefaults]
    telnet = {
        ATHENA.MIT.EDU = {
            option1 = false
        }
    }
    telnet = {
        option1 = true
        option2 = true
    }
    ATHENA.MIT.EDU = {
        option2 = false
    }
    option2 = true

The above four ways of specifying the value of an option are shown in order of decreasing precedence. In this example, if telnet is running in the realm EXAMPLE.COM, it should, by default, have option1 and option2 set to true. However, a telnet program in the realm ATHENA.MIT.EDU should have option1 set to false and option2 set to true. Any other programs in ATHENA.MIT.EDU should have option2 set to false by default. Any programs running in other realms should have option2 set to true.

The list of specifiable options for each application may be found in that application’s man pages. The application defaults specified here are overridden by those specified in the realms section.

[plugins]¶

Tags in the [plugins] section can be used to register dynamic plugin modules and to turn modules on and off. Not every krb5 pluggable interface uses the [plugins] section; the ones that do are documented here.

New in release 1.9.

Each pluggable interface corresponds to a subsection of [plugins]. All subsections support the same tags:

disable

This tag may have multiple values. If there are values for this tag, then the named modules will be disabled for the pluggable interface.

enable_only

This tag may have multiple values. If there are values for this tag, then only the named modules will be enabled for the pluggable interface.

module

This tag may have multiple values. Each value is a string of the form modulename:pathname, which causes the shared object located at pathname to be registered as a dynamic module named modulename for the pluggable interface. If pathname is not an absolute path, it will be treated as relative to the plugin_base_dir value from [libdefaults].

For pluggable interfaces where module order matters, modules registered with a module tag normally come first, in the order they are registered, followed by built-in modules in the order they are documented below. If enable_only tags are used, then the order of those tags overrides the normal module order.

The following subsections are currently supported within the [plugins] section:

ccselect interface¶

The ccselect subsection controls modules for credential cache selection within a cache collection. In addition to any registered dynamic modules, the following built-in modules exist (and may be disabled with the disable tag):

k5identity

Uses a .k5identity file in the user’s home directory to select a client principal

realm

Uses the service realm to guess an appropriate cache from the collection

hostname

If the service principal is host-based, uses the service hostname to guess an appropriate cache from the collection

pwqual interface¶

The pwqual subsection controls modules for the password quality interface, which is used to reject weak passwords when passwords are changed. The following built-in modules exist for this interface:

dict

Checks against the realm dictionary file

empty

Rejects empty passwords

hesiod

Checks against user information stored in Hesiod (only if Kerberos was built with Hesiod support)

princ

Checks against components of the principal name

kadm5_hook interface¶

The kadm5_hook interface provides plugins with information on principal creation, modification, password changes and deletion. This interface can be used to write a plugin to synchronize MIT Kerberos with another database such as Active Directory. No plugins are built in for this interface.

kadm5_auth interface¶

The kadm5_auth section (introduced in release 1.16) controls modules for the kadmin authorization interface, which determines whether a client principal is allowed to perform a kadmin operation. The following built-in modules exist for this interface:

acl

This module reads the kadm5.acl file, and authorizes operations which are allowed according to the rules in the file.

self

This module authorizes self-service operations including password changes, creation of new random keys, fetching the client’s principal record or string attributes, and fetching the policy record associated with the client principal.

clpreauth and kdcpreauth interfaces¶

The clpreauth and kdcpreauth interfaces allow plugin modules to provide client and KDC preauthentication mechanisms. The following built-in modules exist for these interfaces:

pkinit

This module implements the PKINIT preauthentication mechanism.

encrypted_challenge

This module implements the encrypted challenge FAST factor.

encrypted_timestamp

This module implements the encrypted timestamp mechanism.

hostrealm interface¶

The hostrealm section (introduced in release 1.12) controls modules for the host-to-realm interface, which affects the local mapping of hostnames to realm names and the choice of default realm. The following built-in modules exist for this interface:

profile

This module consults the [domain_realm] section of the profile for authoritative host-to-realm mappings, and the default_realm variable for the default realm.

dns

This module looks for DNS records for fallback host-to-realm mappings and the default realm. It only operates if the dns_lookup_realm variable is set to true.

domain

This module applies heuristics for fallback host-to-realm mappings. It implements the realm_try_domains variable, and uses the uppercased parent domain of the hostname if that does not produce a result.

localauth interface¶

The localauth section (introduced in release 1.12) controls modules for the local authorization interface, which affects the relationship between Kerberos principals and local system accounts. The following built-in modules exist for this interface:

default

This module implements the DEFAULT type for auth_to_local values.

rule

This module implements the RULE type for auth_to_local values.

names

This module looks for an auth_to_local_names mapping for the principal name.

auth_to_local

This module processes auth_to_local values in the default realm’s section, and applies the default method if no auth_to_local values exist.

k5login

This module authorizes a principal to a local account according to the account’s .k5login file.

an2ln

This module authorizes a principal to a local account if the principal name maps to the local account name.

certauth interface¶

The certauth section (introduced in release 1.16) controls modules for the certificate authorization interface, which determines whether a certificate is allowed to preauthenticate a user via PKINIT. The following built-in modules exist for this interface:

pkinit_san

This module authorizes the certificate if it contains a PKINIT Subject Alternative Name for the requested client principal, or a Microsoft UPN SAN matching the principal if pkinit_allow_upn is set to true for the realm.

pkinit_eku

This module rejects the certificate if it does not contain an Extended Key Usage attribute consistent with the pkinit_eku_checking value for the realm.

dbmatch

This module authorizes or rejects the certificate according to whether it matches the pkinit_cert_match string attribute on the client principal, if that attribute is present.

PKINIT options¶

Note

The following are PKINIT-specific options. These values may be specified in [libdefaults] as global defaults, or within a realm-specific subsection of [libdefaults], or may be specified as realm-specific values in the [realms] section. A realm-specific value overrides, not adds to, a generic [libdefaults] specification. The search order is:

  1. realm-specific subsection of [libdefaults]:

    [libdefaults]
        EXAMPLE.COM = {
            pkinit_anchors = FILE:/usr/local/example.com.crt
        }
    
  2. realm-specific value in the [realms] section:

    [realms]
        OTHERREALM.ORG = {
            pkinit_anchors = FILE:/usr/local/otherrealm.org.crt
        }
    
  3. generic value in the [libdefaults] section:

    [libdefaults]
        pkinit_anchors = DIR:/usr/local/generic_trusted_cas/
    

Specifying PKINIT identity information¶

The syntax for specifying Public Key identity, trust, and revocation information for PKINIT is as follows:

FILE:filename[,keyfilename]

This option has context-specific behavior.

In pkinit_identity or pkinit_identities, filename specifies the name of a PEM-format file containing the user’s certificate. If keyfilename is not specified, the user’s private key is expected to be in filename as well. Otherwise, keyfilename is the name of the file containing the private key.

In pkinit_anchors or pkinit_pool, filename is assumed to be the name of an OpenSSL-style ca-bundle file.

DIR:dirname

This option has context-specific behavior.

In pkinit_identity or pkinit_identities, dirname specifies a directory with files named *.crt and *.key where the first part of the file name is the same for matching pairs of certificate and private key files. When a file with a name ending with .crt is found, a matching file ending with .key is assumed to contain the private key. If no such file is found, then the certificate in the .crt is not used.

In pkinit_anchors or pkinit_pool, dirname is assumed to be an OpenSSL-style hashed CA directory where each CA cert is stored in a file named hash-of-ca-cert.#. This infrastructure is encouraged, but all files in the directory will be examined and if they contain certificates (in PEM format), they will be used.

In pkinit_revoke, dirname is assumed to be an OpenSSL-style hashed CA directory where each revocation list is stored in a file named hash-of-ca-cert.r#. This infrastructure is encouraged, but all files in the directory will be examined and if they contain a revocation list (in PEM format), they will be used.

PKCS12:filename

filename is the name of a PKCS #12 format file, containing the user’s certificate and private key.

PKCS11:[module_name=]modname[:slotid=slot-id][:token=token-label][:certid=cert-id][:certlabel=cert-label]

All keyword/values are optional. modname specifies the location of a library implementing PKCS #11. If a value is encountered with no keyword, it is assumed to be the modname. If no module-name is specified, the default is PKCS11_MODNAME. slotid= and/or token= may be specified to force the use of a particular smard card reader or token if there is more than one available. certid= and/or certlabel= may be specified to force the selection of a particular certificate on the device. Specifier values must not contain colon characters, as colons are always treated as separators. See the pkinit_cert_match configuration option for more ways to select a particular certificate to use for PKINIT.

ENV:envvar

envvar specifies the name of an environment variable which has been set to a value conforming to one of the previous values. For example, ENV:X509_PROXY, where environment variable X509_PROXY has been set to FILE:/tmp/my_proxy.pem.

PKINIT krb5.conf options¶

pkinit_anchors

Specifies the location of trusted anchor (root) certificates which the client trusts to sign KDC certificates. This option may be specified multiple times. These values from the config file are not used if the user specifies X509_anchors on the command line.

pkinit_cert_match

Specifies matching rules that the client certificate must match before it is used to attempt PKINIT authentication. If a user has multiple certificates available (on a smart card, or via other media), there must be exactly one certificate chosen before attempting PKINIT authentication. This option may be specified multiple times. All the available certificates are checked against each rule in order until there is a match of exactly one certificate.

The Subject and Issuer comparison strings are the RFC 2253 string representations from the certificate Subject DN and Issuer DN values.

The syntax of the matching rules is:

[relation-operator]component-rule …

where:

relation-operator

can be either &&, meaning all component rules must match, or ||, meaning only one component rule must match. The default is &&.

component-rule

can be one of the following. Note that there is no punctuation or whitespace between component rules.

<SUBJECT>regular-expression
<ISSUER>regular-expression
<SAN>regular-expression
<EKU>extended-key-usage-list
<KU>key-usage-list

extended-key-usage-list is a comma-separated list of required Extended Key Usage values. All values in the list must be present in the certificate. Extended Key Usage values can be:

  • pkinit

  • msScLogin

  • clientAuth

  • emailProtection

key-usage-list is a comma-separated list of required Key Usage values. All values in the list must be present in the certificate. Key Usage values can be:

  • digitalSignature

  • keyEncipherment

Examples:

pkinit_cert_match = ||<SUBJECT>.*DoE.*<SAN>.*@EXAMPLE.COM
pkinit_cert_match = &&<EKU>msScLogin,clientAuth<ISSUER>.*DoE.*
pkinit_cert_match = <EKU>msScLogin,clientAuth<KU>digitalSignature
pkinit_eku_checking

This option specifies what Extended Key Usage value the KDC certificate presented to the client must contain. (Note that if the KDC certificate has the pkinit SubjectAlternativeName encoded as the Kerberos TGS name, EKU checking is not necessary since the issuing CA has certified this as a KDC certificate.) The values recognized in the krb5.conf file are:

kpKDC

This is the default value and specifies that the KDC must have the id-pkinit-KPKdc EKU as defined in RFC 4556.

kpServerAuth

If kpServerAuth is specified, a KDC certificate with the id-kp-serverAuth EKU will be accepted. This key usage value is used in most commercially issued server certificates.

none

If none is specified, then the KDC certificate will not be checked to verify it has an acceptable EKU. The use of this option is not recommended.

pkinit_dh_min_bits

Specifies the group of the Diffie-Hellman key the client will attempt to use. The acceptable values are 1024, 2048, P-256, 4096, P-384, and P-521. The default is 2048. (P-256, P-384, and P-521 are new in release 1.22.)

pkinit_identities

Specifies the location(s) to be used to find the user’s X.509 identity information. If this option is specified multiple times, each value is attempted in order until certificates are found. Note that these values are not used if the user specifies X509_user_identity on the command line.

pkinit_kdc_hostname

The presence of this option indicates that the client is willing to accept a KDC certificate with a dNSName SAN (Subject Alternative Name) rather than requiring the id-pkinit-san as defined in RFC 4556. This option may be specified multiple times. Its value should contain the acceptable hostname for the KDC (as contained in its certificate).

pkinit_pool

Specifies the location of intermediate certificates which may be used by the client to complete the trust chain between a KDC certificate and a trusted anchor. This option may be specified multiple times.

pkinit_require_crl_checking

The default certificate verification process will always check the available revocation information to see if a certificate has been revoked. If a match is found for the certificate in a CRL, verification fails. If the certificate being verified is not listed in a CRL, or there is no CRL present for its issuing CA, and pkinit_require_crl_checking is false, then verification succeeds.

However, if pkinit_require_crl_checking is true and there is no CRL information available for the issuing CA, then verification fails.

pkinit_require_crl_checking should be set to true if the policy is such that up-to-date CRLs must be present for every CA.

pkinit_revoke

Specifies the location of Certificate Revocation List (CRL) information to be used by the client when verifying the validity of the KDC certificate presented. This option may be specified multiple times.

Parameter expansion¶

Starting with release 1.11, several variables, such as default_keytab_name, allow parameters to be expanded. Valid parameters are:

%{TEMP}

Temporary directory

%{uid}

Unix real UID or Windows SID

%{euid}

Unix effective user ID or Windows SID

%{USERID}

Same as %{uid}

%{null}

Empty string

%{LIBDIR}

Installation library directory

%{BINDIR}

Installation binary directory

%{SBINDIR}

Installation admin binary directory

%{username}

(Unix) Username of effective user ID

%{APPDATA}

(Windows) Roaming application data for current user

%{COMMON_APPDATA}

(Windows) Application data for all users

%{LOCAL_APPDATA}

(Windows) Local application data for current user

%{SYSTEM}

(Windows) Windows system folder

%{WINDOWS}

(Windows) Windows folder

%{USERCONFIG}

(Windows) Per-user MIT krb5 config file directory

%{COMMONCONFIG}

(Windows) Common MIT krb5 config file directory

Sample krb5.conf file¶

Here is an example of a generic krb5.conf file:

[libdefaults]
    default_realm = ATHENA.MIT.EDU
    dns_lookup_kdc = true
    dns_lookup_realm = false

[realms]
    ATHENA.MIT.EDU = {
        kdc = kerberos.mit.edu
        kdc = kerberos-1.mit.edu
        kdc = kerberos-2.mit.edu
        admin_server = kerberos.mit.edu
        primary_kdc = kerberos.mit.edu
    }
    EXAMPLE.COM = {
        kdc = kerberos.example.com
        kdc = kerberos-1.example.com
        admin_server = kerberos.example.com
    }

[domain_realm]
    mit.edu = ATHENA.MIT.EDU

[capaths]
    ATHENA.MIT.EDU = {
           EXAMPLE.COM = .
    }
    EXAMPLE.COM = {
           ATHENA.MIT.EDU = .
    }

FILES¶

/etc/krb5.conf

SEE ALSO¶

syslog(3)

krb5-1.22.1/doc/html/admin/install_clients.html0000664000175000017500000003130215051422656021225 0ustar ghudsonghudson Installing and configuring UNIX client machines — MIT Kerberos Documentation

Installing and configuring UNIX client machines¶

The Kerberized client programs include kinit, klist, kdestroy, and kpasswd. All of these programs are in the directory BINDIR.

You can often integrate Kerberos with the login system on client machines, typically through the use of PAM. The details vary by operating system, and should be covered in your operating system’s documentation. If you do this, you will need to make sure your users know to use their Kerberos passwords when they log in.

You will also need to educate your users to use the ticket management programs kinit, klist, and kdestroy. If you do not have Kerberos password changing integrated into the native password program (again, typically through PAM), you will need to educate users to use kpasswd in place of its non-Kerberos counterparts passwd.

Client machine configuration files¶

Each machine running Kerberos should have a krb5.conf file. At a minimum, it should define a default_realm setting in [libdefaults]. If you are not using DNS SRV records (Hostnames for KDCs) or URI records (KDC Discovery), it must also contain a [realms] section containing information for your realm’s KDCs.

Consider setting rdns to false in order to reduce your dependence on precisely correct DNS information for service hostnames. Turning this flag off means that service hostnames will be canonicalized through forward name resolution (which adds your domain name to unqualified hostnames, and resolves CNAME records in DNS), but not through reverse address lookup. The default value of this flag is true for historical reasons only.

If you anticipate users frequently logging into remote hosts (e.g., using ssh) using forwardable credentials, consider setting forwardable to true so that users obtain forwardable tickets by default. Otherwise users will need to use kinit -f to get forwardable tickets.

Consider adjusting the ticket_lifetime setting to match the likely length of sessions for your users. For instance, if most of your users will be logging in for an eight-hour workday, you could set the default to ten hours so that tickets obtained in the morning expire shortly after the end of the workday. Users can still manually request longer tickets when necessary, up to the maximum allowed by each user’s principal record on the KDC.

If a client host may access services in different realms, it may be useful to define a [domain_realm] mapping so that clients know which hosts belong to which realms. However, if your clients and KDC are running release 1.7 or later, it is also reasonable to leave this section out on client machines and just define it in the KDC’s krb5.conf.

krb5-1.22.1/doc/html/admin/troubleshoot.html0000664000175000017500000004652015051422657020600 0ustar ghudsonghudson Troubleshooting — MIT Kerberos Documentation

Troubleshooting¶

Trace logging¶

Most programs using MIT krb5 1.9 or later can be made to provide information about internal krb5 library operations using trace logging. To enable this, set the KRB5_TRACE environment variable to a filename before running the program. On many operating systems, the filename /dev/stdout can be used to send trace logging output to standard output.

Some programs do not honor KRB5_TRACE, either because they use secure library contexts (this generally applies to setuid programs and parts of the login system) or because they take direct control of the trace logging system using the API.

Here is a short example showing trace logging output for an invocation of the kvno command:

shell% env KRB5_TRACE=/dev/stdout kvno krbtgt/KRBTEST.COM
[9138] 1332348778.823276: Getting credentials user@KRBTEST.COM ->
    krbtgt/KRBTEST.COM@KRBTEST.COM using ccache
    FILE:/me/krb5/build/testdir/ccache
[9138] 1332348778.823381: Retrieving user@KRBTEST.COM ->
    krbtgt/KRBTEST.COM@KRBTEST.COM from
    FILE:/me/krb5/build/testdir/ccache with result: 0/Unknown code 0
krbtgt/KRBTEST.COM@KRBTEST.COM: kvno = 1

List of errors¶

Frequently seen errors¶

  1. KDC has no support for encryption type while getting initial credentials

  2. credential verification failed: KDC has no support for encryption type

  3. Cannot create cert chain: certificate has expired

Errors seen by admins¶

  1. kprop: No route to host while connecting to server

  2. kprop: Connection refused while connecting to server

  3. kprop: Server rejected authentication (during sendauth exchange) while authenticating to server


KDC has no support for encryption type while getting initial credentials¶

credential verification failed: KDC has no support for encryption type¶

This most commonly happens when trying to use a principal with only DES keys, in a release (MIT krb5 1.7 or later) which disables DES by default. DES encryption is considered weak due to its inadequate key size. If you cannot migrate away from its use, you can re-enable DES by adding allow_weak_crypto = true to the [libdefaults] section of krb5.conf.

Cannot create cert chain: certificate has expired¶

This error message indicates that PKINIT authentication failed because the client certificate, KDC certificate, or one of the certificates in the signing chain above them has expired.

If the KDC certificate has expired, this message appears in the KDC log file, and the client will receive a “Preauthentication failed†error. (Prior to release 1.11, the KDC log file message erroneously appears as “Out of memoryâ€. Prior to release 1.12, the client will receive a “Generic errorâ€.)

If the client or a signing certificate has expired, this message may appear in trace_logging output from kinit or, starting in release 1.12, as an error message from kinit or another program which gets initial tickets. The error message is more likely to appear properly on the client if the principal entry has no long-term keys.

kprop: No route to host while connecting to server¶

Make sure that the hostname of the replica KDC (as given to kprop) is correct, and that any firewalls between the primary and the replica allow a connection on port 754.

kprop: Connection refused while connecting to server¶

If the replica KDC is intended to run kpropd out of inetd, make sure that inetd is configured to accept krb5_prop connections. inetd may need to be restarted or sent a SIGHUP to recognize the new configuration. If the replica is intended to run kpropd in standalone mode, make sure that it is running.

kprop: Server rejected authentication (during sendauth exchange) while authenticating to server¶

Make sure that:

  1. The time is synchronized between the primary and replica KDCs.

  2. The master stash file was copied from the primary to the expected location on the replica.

  3. The replica has a keytab file in the default location containing a host principal for the replica’s hostname.

krb5-1.22.1/doc/html/admin/enctypes.html0000664000175000017500000005413215051422656017676 0ustar ghudsonghudson Encryption types — MIT Kerberos Documentation

Encryption types¶

Kerberos can use a variety of cipher algorithms to protect data. A Kerberos encryption type (also known as an enctype) is a specific combination of a cipher algorithm with an integrity algorithm to provide both confidentiality and integrity to data.

Enctypes in requests¶

Clients make two types of requests (KDC-REQ) to the KDC: AS-REQs and TGS-REQs. The client uses the AS-REQ to obtain initial tickets (typically a Ticket-Granting Ticket (TGT)), and uses the TGS-REQ to obtain service tickets.

The KDC uses three different keys when issuing a ticket to a client:

  • The long-term key of the service: the KDC uses this to encrypt the actual service ticket. The KDC only uses the first long-term key in the most recent kvno for this purpose.

  • The session key: the KDC randomly chooses this key and places one copy inside the ticket and the other copy inside the encrypted part of the reply.

  • The reply-encrypting key: the KDC uses this to encrypt the reply it sends to the client. For AS replies, this is a long-term key of the client principal. For TGS replies, this is either the session key of the authenticating ticket, or a subsession key.

Each of these keys is of a specific enctype.

Each request type allows the client to submit a list of enctypes that it is willing to accept. For the AS-REQ, this list affects both the session key selection and the reply-encrypting key selection. For the TGS-REQ, this list only affects the session key selection.

Session key selection¶

The KDC chooses the session key enctype by taking the intersection of its permitted_enctypes list, the list of long-term keys for the most recent kvno of the service, and the client’s requested list of enctypes. Starting in krb5-1.21, all services are assumed to support aes256-cts-hmac-sha1-96; also, des3-cbc-sha1 and arcfour-hmac session keys will not be issued by default.

Starting in krb5-1.11, it is possible to set a string attribute on a service principal to control what session key enctypes the KDC may issue for service tickets for that principal, overriding the service’s long-term keys and the assumption of aes256-cts-hmac-sha1-96 support. See set_string in kadmin for details.

Choosing enctypes for a service¶

Generally, a service should have a key of the strongest enctype that both it and the KDC support. If the KDC is running a release earlier than krb5-1.11, it is also useful to generate an additional key for each enctype that the service can support. The KDC will only use the first key in the list of long-term keys for encrypting the service ticket, but the additional long-term keys indicate the other enctypes that the service supports.

As noted above, starting with release krb5-1.11, there are additional configuration settings that control session key enctype selection independently of the set of long-term keys that the KDC has stored for a service principal.

Configuration variables¶

The following [libdefaults] settings in krb5.conf will affect how enctypes are chosen.

allow_weak_crypto

defaults to false starting with krb5-1.8. When false, removes weak enctypes from permitted_enctypes, default_tkt_enctypes, and default_tgs_enctypes. Do not set this to true unless the use of weak enctypes is an acceptable risk for your environment and the weak enctypes are required for backward compatibility.

allow_des3

was added in release 1.21 and defaults to false. Unless this flag is set to true, the KDC will not issue tickets with des3-cbc-sha1 session keys. In a future release, this flag will control whether des3-cbc-sha1 is permitted in similar fashion to weak enctypes.

allow_rc4

was added in release 1.21 and defaults to false. Unless this flag is set to true, the KDC will not issue tickets with arcfour-hmac session keys. In a future release, this flag will control whether arcfour-hmac is permitted in similar fashion to weak enctypes.

permitted_enctypes

controls the set of enctypes that a service will permit for session keys and for ticket and authenticator encryption. The KDC and other programs that access the Kerberos database will ignore keys of non-permitted enctypes. Starting in release 1.18, this setting also acts as the default for default_tkt_enctypes and default_tgs_enctypes.

default_tkt_enctypes

controls the default set of enctypes that the Kerberos client library requests when making an AS-REQ. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded.

default_tgs_enctypes

controls the default set of enctypes that the Kerberos client library requests when making a TGS-REQ. Do not set this unless required for specific backward compatibility purposes; stale values of this setting can prevent clients from taking advantage of new stronger enctypes when the libraries are upgraded.

The following per-realm setting in kdc.conf affects the generation of long-term keys.

supported_enctypes

controls the default set of enctype-salttype pairs that kadmind will use for generating long-term keys, either randomly or from passwords

Enctype compatibility¶

See Encryption types for additional information about enctypes.

enctype

weak?

krb5

Windows

des-cbc-crc

weak

<1.18

>=2000

des-cbc-md4

weak

<1.18

?

des-cbc-md5

weak

<1.18

>=2000

des3-cbc-sha1

deprecated

>=1.1

none

arcfour-hmac

deprecated

>=1.3

>=2000

arcfour-hmac-exp

weak

>=1.3

>=2000

aes128-cts-hmac-sha1-96

>=1.3

>=Vista

aes256-cts-hmac-sha1-96

>=1.3

>=Vista

aes128-cts-hmac-sha256-128

>=1.15

none

aes256-cts-hmac-sha384-192

>=1.15

none

camellia128-cts-cmac

>=1.9

none

camellia256-cts-cmac

>=1.9

none

krb5 releases 1.18 and later do not support single-DES. krb5 releases 1.8 and later disable the single-DES enctypes by default. Microsoft Windows releases Windows 7 and later disable single-DES enctypes by default.

krb5 releases 1.17 and later flag deprecated encryption types (including des3-cbc-sha1 and arcfour-hmac) in KDC logs and kadmin output. krb5 release 1.19 issues a warning during initial authentication if des3-cbc-sha1 is used. Future releases will disable des3-cbc-sha1 by default and eventually remove support for it.

Migrating away from older encryption types¶

Administrator intervention may be required to migrate a realm away from legacy encryption types, especially if the realm was created using krb5 release 1.2 or earlier. This migration should be performed before upgrading to krb5 versions which disable or remove support for legacy encryption types.

If there is a supported_enctypes setting in kdc.conf on the KDC, make sure that it does not include weak or deprecated encryption types. This will ensure that newly created keys do not use those encryption types by default.

Check the krbtgt/REALM principal using the kadmin getprinc command. If it lists a weak or deprecated encryption type as the first key, it must be migrated using the procedure in Changing the krbtgt key.

Check the kadmin/history principal, which should have only one key entry. If it uses a weak or deprecated encryption type, it should be upgraded following the notes in Updating the history key.

Check the other kadmin principals: kadmin/changepw, kadmin/admin, and any kadmin/hostname principals that may exist. These principals can be upgraded with change_password -randkey in kadmin.

Check the K/M entry. If it uses a weak or deprecated encryption type, it should be upgraded following the procedure in Updating the master key.

User and service principals using legacy encryption types can be enumerated with the kdb5_util tabdump keyinfo command.

Service principals can be migrated with a keytab rotation on the service host, which can be accomplished using the k5srvutil change and delold commands. Allow enough time for existing tickets to expire between the change and delold operations.

User principals with password-based keys can be migrated with a password change. The realm administrator can set a password expiration date using the kadmin modify_principal -pwexpire command to force a password change.

If a legacy encryption type has not yet been disabled by default in the version of krb5 running on the KDC, it can be disabled administratively with the permitted_enctypes variable. For example, setting permitted_enctypes to DEFAULT -des3 -rc4 will cause any database keys of the triple-DES and RC4 encryption types to be ignored.

krb5-1.22.1/doc/html/admin/conf_ldap.html0000664000175000017500000004516615051422656020000 0ustar ghudsonghudson Configuring Kerberos with OpenLDAP back-end — MIT Kerberos Documentation

Configuring Kerberos with OpenLDAP back-end¶

  1. Make sure the LDAP server is using local authentication (ldapi://) or TLS (ldaps). See https://www.openldap.org/doc/admin/tls.html for instructions on configuring TLS support in OpenLDAP.

  2. Add the Kerberos schema file to the LDAP Server using the OpenLDAP LDIF file from the krb5 source directory (src/plugins/kdb/ldap/libkdb_ldap/kerberos.openldap.ldif). The following example uses local authentication:

    ldapadd -Y EXTERNAL -H ldapi:/// -f /path/to/kerberos.openldap.ldif
    
  3. Choose DNs for the krb5kdc and kadmind servers to bind to the LDAP server, and create them if necessary. Specify these DNs with the ldap_kdc_dn and ldap_kadmind_dn directives in kdc.conf. The kadmind DN will also be used for administrative commands such as kdb5_util.

    Alternatively, you may configure krb5kdc and kadmind to use SASL authentication to access the LDAP server; see the [dbmodules] relations ldap_kdc_sasl_mech and similar.

  4. Specify a location for the LDAP service password file by setting ldap_service_password_file. Use kdb5_ldap_util stashsrvpw to stash passwords for the KDC and kadmind DNs chosen above. For example:

    kdb5_ldap_util stashsrvpw -f /path/to/service.keyfile cn=krbadmin,dc=example,dc=com
    

    Skip this step if you are using SASL authentication and the mechanism does not require a password.

  5. Choose a DN for the global Kerberos container entry (but do not create the entry at this time). Specify this DN with the ldap_kerberos_container_dn directive in kdc.conf. Realm container entries will be created underneath this DN. Principal entries may exist either underneath the realm container (the default) or in separate trees referenced from the realm container.

  6. Configure the LDAP server ACLs to enable the KDC and kadmin server DNs to read and write the Kerberos data. If disable_last_success and disable_lockout are both set to true in the [dbmodules] subsection for the realm, then the KDC DN only requires read access to the Kerberos data.

    Sample access control information:

    access to dn.base=""
        by * read
    
    access to dn.base="cn=Subschema"
        by * read
    
    # Provide access to the realm container.
    access to dn.subtree= "cn=EXAMPLE.COM,cn=krbcontainer,dc=example,dc=com"
        by dn.exact="cn=kdc-service,dc=example,dc=com" write
        by dn.exact="cn=adm-service,dc=example,dc=com" write
        by * none
    
    # Provide access to principals, if not underneath the realm container.
    access to dn.subtree= "ou=users,dc=example,dc=com"
        by dn.exact="cn=kdc-service,dc=example,dc=com" write
        by dn.exact="cn=adm-service,dc=example,dc=com" write
        by * none
    
    access to *
        by * read
    

    If the locations of the container and principals or the DNs of the service objects for a realm are changed then this information should be updated.

  7. In kdc.conf, make sure the following relations are set in the [dbmodules] subsection for the realm:

    db_library (set to ``kldap``)
    ldap_kerberos_container_dn
    ldap_kdc_dn
    ldap_kadmind_dn
    ldap_service_password_file
    ldap_servers
    
  8. Create the realm using kdb5_ldap_util:

    kdb5_ldap_util create -subtrees ou=users,dc=example,dc=com -s

    Use the -subtrees option if the principals are to exist in a separate subtree from the realm container. Before executing the command, make sure that the subtree mentioned above (ou=users,dc=example,dc=com) exists. If the principals will exist underneath the realm container, omit the -subtrees option and do not worry about creating the principal subtree.

    For more information, refer to the section Operations on the LDAP database.

    The realm object is created under the ldap_kerberos_container_dn specified in the configuration file. This operation will also create the Kerberos container, if not present already. This container can be used to store information related to multiple realms.

  9. Add an eq index for krbPrincipalName to speed up principal lookup operations. See https://www.openldap.org/doc/admin/tuning.html#Indexes for details.

With the LDAP back end it is possible to provide aliases for principal entries. Beginning in release 1.22, aliases can be added with the kadmin add_alias command, but it is also possible (in release 1.7 or later) to provide aliases through direct manipulation of the LDAP entries.

An entry with aliases contains multiple values of the krbPrincipalName attribute. Since LDAP attribute values are not ordered, it is necessary to specify which principal name is canonical, by using the krbCanonicalName attribute. Therefore, to create aliases for an entry, first set the krbCanonicalName attribute of the entry to the canonical principal name (which should be identical to the pre-existing krbPrincipalName value), and then add additional krbPrincipalName attributes for the aliases.

Principal aliases are only returned by the KDC when the client requests canonicalization. Canonicalization is normally requested for service principals; for client principals, an explicit flag is often required (e.g., kinit -C) and canonicalization is only performed for initial ticket requests.

krb5-1.22.1/doc/html/admin/appl_servers.html0000664000175000017500000005670215051422656020556 0ustar ghudsonghudson Application servers — MIT Kerberos Documentation

Application servers¶

If you need to install the Kerberos V5 programs on an application server, please refer to the Kerberos V5 Installation Guide. Once you have installed the software, you need to add that host to the Kerberos database (see Principals), and generate a keytab for that host, that contains the host’s key. You also need to make sure the host’s clock is within your maximum clock skew of the KDCs.

Keytabs¶

A keytab is a host’s copy of its own keylist, which is analogous to a user’s password. An application server that needs to authenticate itself to the KDC has to have a keytab that contains its own principal and key. Just as it is important for users to protect their passwords, it is equally important for hosts to protect their keytabs. You should always store keytab files on local disk, and make them readable only by root, and you should never send a keytab file over a network in the clear. Ideally, you should run the kadmin command to extract a keytab on the host on which the keytab is to reside.

Adding principals to keytabs¶

To generate a keytab, or to add a principal to an existing keytab, use the ktadd command from kadmin. Here is a sample session, using configuration files that enable only AES encryption:

kadmin: ktadd host/daffodil.mit.edu@ATHENA.MIT.EDU
Entry for principal host/daffodil.mit.edu with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab
Entry for principal host/daffodil.mit.edu with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab

Removing principals from keytabs¶

To remove a principal from an existing keytab, use the kadmin ktremove command:

kadmin:  ktremove host/daffodil.mit.edu@ATHENA.MIT.EDU
Entry for principal host/daffodil.mit.edu with kvno 2 removed from keytab FILE:/etc/krb5.keytab.
Entry for principal host/daffodil.mit.edu with kvno 2 removed from keytab FILE:/etc/krb5.keytab.

Using a keytab to acquire client credentials¶

While keytabs are ordinarily used to accept credentials from clients, they can also be used to acquire initial credentials, allowing one service to authenticate to another.

To manually obtain credentials using a keytab, use the kinit -k option, together with the -t option if the keytab is not in the default location.

Beginning with release 1.11, GSSAPI applications can be configured to automatically obtain initial credentials from a keytab as needed. The recommended configuration is as follows:

  1. Create a keytab containing a single entry for the desired client identity.

  2. Place the keytab in a location readable by the service, and set the KRB5_CLIENT_KTNAME environment variable to its filename. Alternatively, use the default_client_keytab_name profile variable in [libdefaults], or use the default location of DEFCKTNAME.

  3. Set KRB5CCNAME to a filename writable by the service, which will not be used for any other purpose. Do not manually obtain credentials at this location. (Another credential cache type besides FILE can be used if desired, as long the cache will not conflict with another use. A MEMORY cache can be used if the service runs as a long-lived process. See Credential cache for details.)

  4. Start the service. When it authenticates using GSSAPI, it will automatically obtain credentials from the client keytab into the specified credential cache, and refresh them before they expire.

Clock Skew¶

A Kerberos application server host must keep its clock synchronized or it will reject authentication requests from clients. Modern operating systems typically provide a facility to maintain the correct time; make sure it is enabled. This is especially important on virtual machines, where clocks tend to drift more rapidly than normal machine clocks.

The default allowable clock skew is controlled by the clockskew variable in [libdefaults].

Getting DNS information correct¶

Several aspects of Kerberos rely on name service. When a hostname is used to name a service, clients may canonicalize the hostname using forward and possibly reverse name resolution. The result of this canonicalization must match the principal entry in the host’s keytab, or authentication will fail. To work with all client canonicalization configurations, each host’s canonical name must be the fully-qualified host name (including the domain), and each host’s IP address must reverse-resolve to the canonical name.

Configuration of hostnames varies by operating system. On the application server itself, canonicalization will typically use the /etc/hosts file rather than the DNS. Ensure that the line for the server’s hostname is in the following form:

IP address      fully-qualified hostname        aliases

Here is a sample /etc/hosts file:

# this is a comment
127.0.0.1      localhost localhost.mit.edu
10.0.0.6       daffodil.mit.edu daffodil trillium wake-robin

The output of klist -k for this example host should look like:

viola# klist -k
Keytab name: /etc/krb5.keytab
KVNO Principal
---- ------------------------------------------------------------
   2 host/daffodil.mit.edu@ATHENA.MIT.EDU

If you were to ssh to this host with a fresh credentials cache (ticket file), and then klist, the output should list a service principal of host/daffodil.mit.edu@ATHENA.MIT.EDU.

Configuring your firewall to work with Kerberos V5¶

If you need off-site users to be able to get Kerberos tickets in your realm, they must be able to get to your KDC. This requires either that you have a replica KDC outside your firewall, or that you configure your firewall to allow UDP requests into at least one of your KDCs, on whichever port the KDC is running. (The default is port 88; other ports may be specified in the KDC’s kdc.conf file.) Similarly, if you need off-site users to be able to change their passwords in your realm, they must be able to get to your Kerberos admin server on the kpasswd port (which defaults to 464). If you need off-site users to be able to administer your Kerberos realm, they must be able to get to your Kerberos admin server on the administrative port (which defaults to 749).

If your on-site users inside your firewall will need to get to KDCs in other realms, you will also need to configure your firewall to allow outgoing TCP and UDP requests to port 88, and to port 464 to allow password changes. If your on-site users inside your firewall will need to get to Kerberos admin servers in other realms, you will also need to allow outgoing TCP and UDP requests to port 749.

If any of your KDCs are outside your firewall, you will need to allow kprop requests to get through to the remote KDC. kprop uses the krb5_prop service on port 754 (tcp).

The book UNIX System Security, by David Curry, is a good starting point for learning to configure firewalls.

krb5-1.22.1/doc/html/admin/admin_commands/0000775000175000017500000000000015051422656020122 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/admin/admin_commands/index.html0000664000175000017500000002406615051422656022127 0ustar ghudsonghudson Administration programs — MIT Kerberos Documentation krb5-1.22.1/doc/html/admin/admin_commands/ktutil.html0000664000175000017500000004107015051422656022326 0ustar ghudsonghudson ktutil — MIT Kerberos Documentation

ktutil¶

SYNOPSIS¶

ktutil

DESCRIPTION¶

The ktutil command invokes a command interface from which an administrator can read, write, or edit entries in a keytab. (Kerberos V4 srvtab files are no longer supported.)

COMMANDS¶

list¶

list [-t] [-k] [-e]

Displays the current keylist. If -t, -k, and/or -e are specified, also display the timestamp, key contents, or enctype (respectively).

Alias: l

read_kt¶

read_kt keytab

Read the Kerberos V5 keytab file keytab into the current keylist.

Alias: rkt

write_kt¶

write_kt keytab

Write the current keylist into the Kerberos V5 keytab file keytab.

Alias: wkt

clear_list¶

clear_list

Clear the current keylist.

Alias: clear

delete_entry¶

delete_entry slot

Delete the entry in slot number slot from the current keylist.

Alias: delent

add_entry¶

add_entry {-key|-password} -p principal -k kvno [-e enctype] [-f|-s salt]

Add principal to keylist using key or password. If the -f flag is specified, salt information will be fetched from the KDC; in this case the -e flag may be omitted, or it may be supplied to force a particular enctype. If the -f flag is not specified, the -e flag must be specified, and the default salt will be used unless overridden with the -s option.

Alias: addent

list_requests¶

list_requests

Displays a listing of available commands.

Aliases: lr, ?

quit¶

quit

Quits ktutil.

Aliases: exit, q

EXAMPLE¶

ktutil:  add_entry -password -p alice@BLEEP.COM -k 1 -e
    aes128-cts-hmac-sha1-96
Password for alice@BLEEP.COM:
ktutil:  add_entry -password -p alice@BLEEP.COM -k 1 -e
    aes256-cts-hmac-sha1-96
Password for alice@BLEEP.COM:
ktutil:  write_kt alice.keytab
ktutil:

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kadmin, kdb5_util, kerberos

krb5-1.22.1/doc/html/admin/admin_commands/kdb5_ldap_util.html0000664000175000017500000012010115051422656023665 0ustar ghudsonghudson kdb5_ldap_util — MIT Kerberos Documentation

kdb5_ldap_util¶

SYNOPSIS¶

kdb5_ldap_util [-D user_dn [-w passwd]] [-H ldapuri] command [command_options]

DESCRIPTION¶

kdb5_ldap_util allows an administrator to manage realms, Kerberos services and ticket policies.

COMMAND-LINE OPTIONS¶

-r realm

Specifies the realm to be operated on.

-D user_dn

Specifies the Distinguished Name (DN) of the user who has sufficient rights to perform the operation on the LDAP server.

-w passwd

Specifies the password of user_dn. This option is not recommended.

-H ldapuri

Specifies the URI of the LDAP server.

By default, kdb5_ldap_util operates on the default realm (as specified in krb5.conf) and connects and authenticates to the LDAP server in the same manner as :ref:kadmind(8)` would given the parameters in [dbdefaults] in kdc.conf.

COMMANDS¶

create¶

create [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn] [-k mkeytype] [-kv mkeyVNO] [-M mkeyname] [-m|-P password|-sf stashfilename] [-s] [-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life] [ticket_flags]

Creates realm in directory. Options:

-subtrees subtree_dn_list

Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (:).

-sscope search_scope

Specifies the scope for searching the principals under the subtree. The possible values are 1 or one (one level), 2 or sub (subtrees).

-containerref container_reference_dn

Specifies the DN of the container object in which the principals of a realm will be created. If the container reference is not configured for a realm, the principals will be created in the realm container.

-k mkeytype

Specifies the key type of the master key in the database. The default is given by the master_key_type variable in kdc.conf.

-kv mkeyVNO

Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed.

-M mkeyname

Specifies the principal name for the master key in the database. If not specified, the name is determined by the master_key_name variable in kdc.conf.

-m

Specifies that the master database password should be read from the TTY rather than fetched from a file on the disk.

-P password

Specifies the master database password. This option is not recommended.

-sf stashfilename

Specifies the stash file of the master database password.

-s

Specifies that the stash file is to be created.

-maxtktlife max_ticket_life

(getdate time string) Specifies maximum ticket life for principals in this realm.

-maxrenewlife max_renewable_ticket_life

(getdate time string) Specifies maximum renewable life of tickets for principals in this realm.

ticket_flags

Specifies global ticket flags for the realm. Allowable flags are documented in the description of the add_principal command in kadmin.

Example:

kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu
    -r ATHENA.MIT.EDU create -subtrees o=org -sscope SUB
Password for "cn=admin,o=org":
Initializing database for realm 'ATHENA.MIT.EDU'
You will be prompted for the database Master Password.
It is important that you NOT FORGET this password.
Enter KDC database master key:
Re-enter KDC database master key to verify:

modify¶

modify [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn] [-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life] [ticket_flags]

Modifies the attributes of a realm. Options:

-subtrees subtree_dn_list

Specifies the list of subtrees containing the principals of a realm. The list contains the DNs of the subtree objects separated by colon (:). This list replaces the existing list.

-sscope search_scope

Specifies the scope for searching the principals under the subtrees. The possible values are 1 or one (one level), 2 or sub (subtrees).

-containerref container_reference_dn Specifies the DN of the

container object in which the principals of a realm will be created.

-maxtktlife max_ticket_life

(getdate time string) Specifies maximum ticket life for principals in this realm.

-maxrenewlife max_renewable_ticket_life

(getdate time string) Specifies maximum renewable life of tickets for principals in this realm.

ticket_flags

Specifies global ticket flags for the realm. Allowable flags are documented in the description of the add_principal command in kadmin.

Example:

shell% kdb5_ldap_util -r ATHENA.MIT.EDU -D cn=admin,o=org -H
    ldaps://ldap-server1.mit.edu modify +requires_preauth
Password for "cn=admin,o=org":
shell%

view¶

view

Displays the attributes of a realm.

Example:

kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu
    -r ATHENA.MIT.EDU view
Password for "cn=admin,o=org":
Realm Name: ATHENA.MIT.EDU
Subtree: ou=users,o=org
Subtree: ou=servers,o=org
SearchScope: ONE
Maximum ticket life: 0 days 01:00:00
Maximum renewable life: 0 days 10:00:00
Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PWCHANGE

destroy¶

destroy [-f]

Destroys an existing realm. Options:

-f

If specified, will not prompt the user for confirmation.

Example:

shell% kdb5_ldap_util -r ATHENA.MIT.EDU -D cn=admin,o=org -H
    ldaps://ldap-server1.mit.edu destroy
Password for "cn=admin,o=org":
Deleting KDC database of 'ATHENA.MIT.EDU', are you sure?
(type 'yes' to confirm)? yes
OK, deleting database of 'ATHENA.MIT.EDU'...
shell%

list¶

list

Lists the names of realms under the container.

Example:

shell% kdb5_ldap_util -D cn=admin,o=org -H
    ldaps://ldap-server1.mit.edu list
Password for "cn=admin,o=org":
ATHENA.MIT.EDU
OPENLDAP.MIT.EDU
MEDIA-LAB.MIT.EDU
shell%

stashsrvpw¶

stashsrvpw [-f filename] name

Allows an administrator to store the password for service object in a file so that KDC and Administration server can use it to authenticate to the LDAP server. Options:

-f filename

Specifies the complete path of the service password file. By default, /usr/local/var/service_passwd is used.

name

Specifies the name of the object whose password is to be stored. If krb5kdc or kadmind are configured for simple binding, this should be the distinguished name it will use as given by the ldap_kdc_dn or ldap_kadmind_dn variable in kdc.conf. If the KDC or kadmind is configured for SASL binding, this should be the authentication name it will use as given by the ldap_kdc_sasl_authcid or ldap_kadmind_sasl_authcid variable.

Example:

kdb5_ldap_util stashsrvpw -f /home/andrew/conf_keyfile
    cn=service-kdc,o=org
Password for "cn=service-kdc,o=org":
Re-enter password for "cn=service-kdc,o=org":

create_policy¶

create_policy [-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy_name

Creates a ticket policy in the directory. Options:

-maxtktlife max_ticket_life

(getdate time string) Specifies maximum ticket life for principals.

-maxrenewlife max_renewable_ticket_life

(getdate time string) Specifies maximum renewable life of tickets for principals.

ticket_flags

Specifies the ticket flags. If this option is not specified, by default, no restriction will be set by the policy. Allowable flags are documented in the description of the add_principal command in kadmin.

policy_name

Specifies the name of the ticket policy.

Example:

kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu
    -r ATHENA.MIT.EDU create_policy -maxtktlife "1 day"
    -maxrenewlife "1 week" -allow_postdated +needchange
    -allow_forwardable tktpolicy
Password for "cn=admin,o=org":

modify_policy¶

modify_policy [-maxtktlife max_ticket_life] [-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy_name

Modifies the attributes of a ticket policy. Options are same as for create_policy.

Example:

kdb5_ldap_util -D cn=admin,o=org -H
    ldaps://ldap-server1.mit.edu -r ATHENA.MIT.EDU modify_policy
    -maxtktlife "60 minutes" -maxrenewlife "10 hours"
    +allow_postdated -requires_preauth tktpolicy
Password for "cn=admin,o=org":

view_policy¶

view_policy policy_name

Displays the attributes of the named ticket policy.

Example:

kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu
    -r ATHENA.MIT.EDU view_policy tktpolicy
Password for "cn=admin,o=org":
Ticket policy: tktpolicy
Maximum ticket life: 0 days 01:00:00
Maximum renewable life: 0 days 10:00:00
Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PWCHANGE

destroy_policy¶

destroy_policy [-force] policy_name

Destroys an existing ticket policy. Options:

-force

Forces the deletion of the policy object. If not specified, the user will be prompted for confirmation before deleting the policy.

policy_name

Specifies the name of the ticket policy.

Example:

kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu
    -r ATHENA.MIT.EDU destroy_policy tktpolicy
Password for "cn=admin,o=org":
This will delete the policy object 'tktpolicy', are you sure?
(type 'yes' to confirm)? yes
** policy object 'tktpolicy' deleted.

list_policy¶

list_policy

Lists ticket policies.

Example:

kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu
    -r ATHENA.MIT.EDU list_policy
Password for "cn=admin,o=org":
tktpolicy
tmppolicy
userpolicy

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kadmin, kerberos

krb5-1.22.1/doc/html/admin/admin_commands/sserver.html0000664000175000017500000004226615051422656022513 0ustar ghudsonghudson sserver — MIT Kerberos Documentation

sserver¶

SYNOPSIS¶

sserver [ -p port ] [ -S keytab ] [ server_port ]

DESCRIPTION¶

sserver and sclient are a simple demonstration client/server application. When sclient connects to sserver, it performs a Kerberos authentication, and then sserver returns to sclient the Kerberos principal which was used for the Kerberos authentication. It makes a good test that Kerberos has been successfully installed on a machine.

The service name used by sserver and sclient is sample. Hence, sserver will require that there be a keytab entry for the service sample/hostname.domain.name@REALM.NAME. This keytab is generated using the kadmin program. The keytab file is usually installed as DEFKTNAME.

The -S option allows for a different keytab than the default.

sserver is normally invoked out of inetd(8), using a line in /etc/inetd.conf that looks like this:

sample stream tcp nowait root /usr/local/sbin/sserver sserver

Since sample is normally not a port defined in /etc/services, you will usually have to add a line to /etc/services which looks like this:

sample          13135/tcp

When using sclient, you will first have to have an entry in the Kerberos database, by using kadmin, and then you have to get Kerberos tickets, by using kinit. Also, if you are running the sclient program on a different host than the sserver it will be connecting to, be sure that both hosts have an entry in /etc/services for the sample tcp port, and that the same port number is in both files.

When you run sclient you should see something like this:

sendauth succeeded, reply is:
reply len 32, contents:
You are nlgilman@JIMI.MIT.EDU

COMMON ERROR MESSAGES¶

  1. kinit returns the error:

    kinit: Client not found in Kerberos database while getting
           initial credentials
    

    This means that you didn’t create an entry for your username in the Kerberos database.

  2. sclient returns the error:

    unknown service sample/tcp; check /etc/services
    

    This means that you don’t have an entry in /etc/services for the sample tcp port.

  3. sclient returns the error:

    connect: Connection refused
    

    This probably means you didn’t edit /etc/inetd.conf correctly, or you didn’t restart inetd after editing inetd.conf.

  4. sclient returns the error:

    sclient: Server not found in Kerberos database while using
             sendauth
    

    This means that the sample/hostname@LOCAL.REALM service was not defined in the Kerberos database; it should be created using kadmin, and a keytab file needs to be generated to make the key for that service principal available for sclient.

  5. sclient returns the error:

    sendauth rejected, error reply is:
        "No such file or directory"
    

    This probably means sserver couldn’t find the keytab file. It was probably not installed in the proper directory.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

sclient, kerberos, services(5), inetd(8)

krb5-1.22.1/doc/html/admin/admin_commands/kproplog.html0000664000175000017500000003415615051422656022656 0ustar ghudsonghudson kproplog — MIT Kerberos Documentation

kproplog¶

SYNOPSIS¶

kproplog [-h] [-e num] [-v] kproplog [-R]

DESCRIPTION¶

The kproplog command displays the contents of the KDC database update log to standard output. It can be used to keep track of incremental updates to the principal database. The update log file contains the update log maintained by the kadmind process on the primary KDC server and the kpropd process on the replica KDC servers. When updates occur, they are logged to this file. Subsequently any KDC replica configured for incremental updates will request the current data from the primary KDC and update their log file with any updates returned.

The kproplog command requires read access to the update log file. It will display update entries only for the KDC it runs on.

If no options are specified, kproplog displays a summary of the update log. If invoked on the primary, kproplog also displays all of the update entries. If invoked on a replica KDC server, kproplog displays only a summary of the updates, which includes the serial number of the last update received and the associated time stamp of the last update.

OPTIONS¶

-R

Reset the update log. This forces full resynchronization. If used on a replica then that replica will request a full resync. If used on the primary then all replicas will request full resyncs.

-h

Display a summary of the update log. This information includes the database version number, state of the database, the number of updates in the log, the time stamp of the first and last update, and the version number of the first and last update entry.

-e num

Display the last num update entries in the log. This is useful when debugging synchronization between KDC servers.

-v

Display individual attributes per update. An example of the output generated for one entry:

Update Entry
   Update serial # : 4
   Update operation : Add
   Update principal : test@EXAMPLE.COM
   Update size : 424
   Update committed : True
   Update time stamp : Fri Feb 20 23:37:42 2004
   Attributes changed : 6
         Principal
         Key data
         Password last changed
         Modifying principal
         Modification time
         TL data

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kpropd, kerberos

krb5-1.22.1/doc/html/admin/admin_commands/kpropd.html0000664000175000017500000004367415051422656022325 0ustar ghudsonghudson kpropd — MIT Kerberos Documentation

kpropd¶

SYNOPSIS¶

kpropd [-r realm] [-A admin_server] [-a acl_file] [-f replica_dumpfile] [-F principal_database] [-p kdb5_util_prog] [-P port] [–pid-file=pid_file] [-D] [-d] [-s keytab_file]

DESCRIPTION¶

The kpropd command runs on the replica KDC server. It listens for update requests made by the kprop program. If incremental propagation is enabled, it periodically requests incremental updates from the primary KDC.

When the replica receives a kprop request from the primary, kpropd accepts the dumped KDC database and places it in a file, and then runs kdb5_util to load the dumped database into the active database which is used by krb5kdc. This allows the primary Kerberos server to use kprop to propagate its database to the replica servers. Upon a successful download of the KDC database file, the replica Kerberos server will have an up-to-date KDC database.

Where incremental propagation is not used, kpropd is commonly invoked out of inetd(8) as a nowait service. This is done by adding a line to the /etc/inetd.conf file which looks like this:

kprop  stream  tcp  nowait  root  /usr/local/sbin/kpropd  kpropd

kpropd can also run as a standalone daemon, backgrounding itself and waiting for connections on port 754 (or the port specified with the -P option if given). Standalone mode is required for incremental propagation. Starting in release 1.11, kpropd automatically detects whether it was run from inetd and runs in standalone mode if it is not. Prior to release 1.11, the -S option is required to run kpropd in standalone mode; this option is now accepted for backward compatibility but does nothing.

Incremental propagation may be enabled with the iprop_enable variable in kdc.conf. If incremental propagation is enabled, the replica periodically polls the primary KDC for updates, at an interval determined by the iprop_replica_poll variable. If the replica receives updates, kpropd updates its log file with any updates from the primary. kproplog can be used to view a summary of the update entry log on the replica KDC. If incremental propagation is enabled, the principal kiprop/replicahostname@REALM (where replicahostname is the name of the replica KDC host, and REALM is the name of the Kerberos realm) must be present in the replica’s keytab file.

kproplog can be used to force full replication when iprop is enabled.

OPTIONS¶

-r realm

Specifies the realm of the primary server.

-A admin_server

Specifies the server to be contacted for incremental updates; by default, the primary admin server is contacted.

-f file

Specifies the filename where the dumped principal database file is to be stored; by default the dumped database file is LOCALSTATEDIR/krb5kdc/from_master.

-F kerberos_db

Path to the Kerberos database file, if not the default.

-p

Allows the user to specify the pathname to the kdb5_util program; by default the pathname used is SBINDIR/kdb5_util.

-D

In this mode, kpropd will not detach itself from the current job and run in the background. Instead, it will run in the foreground.

-d

Turn on debug mode. kpropd will print out debugging messages during the database propogation and will run in the foreground (implies -D).

-P

Allow for an alternate port number for kpropd to listen on. This is only useful in combination with the -S option.

-a acl_file

Allows the user to specify the path to the kpropd.acl file; by default the path used is LOCALSTATEDIR/krb5kdc/kpropd.acl.

–pid-file=pid_file

In standalone mode, write the process ID of the daemon into pid_file.

-s keytab_file

Path to a keytab to use for acquiring acceptor credentials.

-x db_args

Database-specific arguments. See Database Options in kadmin for supported arguments.

FILES¶

kpropd.acl

Access file for kpropd; the default location is /usr/local/var/krb5kdc/kpropd.acl. Each entry is a line containing the principal of a host from which the local machine will allow Kerberos database propagation via kprop.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kprop, kdb5_util, krb5kdc, kerberos, inetd(8)

krb5-1.22.1/doc/html/admin/admin_commands/kadmin_local.html0000664000175000017500000021301315051422656023425 0ustar ghudsonghudson kadmin — MIT Kerberos Documentation

kadmin¶

SYNOPSIS¶

kadmin [-O|-N] [-r realm] [-p principal] [-q query] [[-c cache_name]|[-k [-t keytab]]|-n] [-w password] [-s admin_server[:port]] [command args…]

kadmin.local [-r realm] [-p principal] [-q query] [-d dbname] [-e enc:salt …] [-m] [-x db_args] [command args…]

DESCRIPTION¶

kadmin and kadmin.local are command-line interfaces to the Kerberos V5 administration system. They provide nearly identical functionalities; the difference is that kadmin.local directly accesses the KDC database, while kadmin performs operations using kadmind. Except as explicitly noted otherwise, this man page will use “kadmin†to refer to both versions. kadmin provides for the maintenance of Kerberos principals, password policies, and service key tables (keytabs).

The remote kadmin client uses Kerberos to authenticate to kadmind using the service principal kadmin/admin or kadmin/ADMINHOST (where ADMINHOST is the fully-qualified hostname of the admin server). If the credentials cache contains a ticket for one of these principals, and the -c credentials_cache option is specified, that ticket is used to authenticate to kadmind. Otherwise, the -p and -k options are used to specify the client Kerberos principal name used to authenticate. Once kadmin has determined the principal name, it requests a service ticket from the KDC, and uses that service ticket to authenticate to kadmind.

Since kadmin.local directly accesses the KDC database, it usually must be run directly on the primary KDC with sufficient permissions to read the KDC database. If the KDC database uses the LDAP database module, kadmin.local can be run on any host which can access the LDAP server.

OPTIONS¶

-r realm

Use realm as the default database realm.

-p principal

Use principal to authenticate. Otherwise, kadmin will append /admin to the primary principal name of the default ccache, the value of the USER environment variable, or the username as obtained with getpwuid, in order of preference.

-k

Use a keytab to decrypt the KDC response instead of prompting for a password. In this case, the default principal will be host/hostname. If there is no keytab specified with the -t option, then the default keytab will be used.

-t keytab

Use keytab to decrypt the KDC response. This can only be used with the -k option.

-n

Requests anonymous processing. Two types of anonymous principals are supported. For fully anonymous Kerberos, configure PKINIT on the KDC and configure pkinit_anchors in the client’s krb5.conf. Then use the -n option with a principal of the form @REALM (an empty principal name followed by the at-sign and a realm name). If permitted by the KDC, an anonymous ticket will be returned. A second form of anonymous tickets is supported; these realm-exposed tickets hide the identity of the client but not the client’s realm. For this mode, use kinit -n with a normal principal name. If supported by the KDC, the principal (but not realm) will be replaced by the anonymous principal. As of release 1.8, the MIT Kerberos KDC only supports fully anonymous operation.

-c credentials_cache

Use credentials_cache as the credentials cache. The cache should contain a service ticket for the kadmin/admin or kadmin/ADMINHOST (where ADMINHOST is the fully-qualified hostname of the admin server) service; it can be acquired with the kinit program. If this option is not specified, kadmin requests a new service ticket from the KDC, and stores it in its own temporary ccache.

-w password

Use password instead of prompting for one. Use this option with care, as it may expose the password to other users on the system via the process list.

-q query

Perform the specified query and then exit.

-d dbname

Specifies the name of the KDC database. This option does not apply to the LDAP database module.

-s admin_server[:port]

Specifies the admin server which kadmin should contact.

-m

If using kadmin.local, prompt for the database master password instead of reading it from a stash file.

-e “enc:salt …â€

Sets the keysalt list to be used for any new keys created. See Keysalt lists in kdc.conf for a list of possible values.

-O

Force use of old AUTH_GSSAPI authentication flavor.

-N

Prevent fallback to AUTH_GSSAPI authentication flavor.

-x db_args

Specifies the database specific arguments. See the next section for supported options.

Starting with release 1.14, if any command-line arguments remain after the options, they will be treated as a single query to be executed. This mode of operation is intended for scripts and behaves differently from the interactive mode in several respects:

  • Query arguments are split by the shell, not by kadmin.

  • Informational and warning messages are suppressed. Error messages and query output (e.g. for get_principal) will still be displayed.

  • Confirmation prompts are disabled (as if -force was given). Password prompts will still be issued as required.

  • The exit status will be non-zero if the query fails.

The -q option does not carry these behavior differences; the query will be processed as if it was entered interactively. The -q option cannot be used in combination with a query in the remaining arguments.

DATABASE OPTIONS¶

Database options can be used to override database-specific defaults. Supported options for the DB2 module are:

-x dbname=*filename*

Specifies the base filename of the DB2 database.

-x lockiter

Make iteration operations hold the lock for the duration of the entire operation, rather than temporarily releasing the lock while handling each principal. This is the default behavior, but this option exists to allow command line override of a [dbmodules] setting. First introduced in release 1.13.

-x unlockiter

Make iteration operations unlock the database for each principal, instead of holding the lock for the duration of the entire operation. First introduced in release 1.13.

Supported options for the LDAP module are:

-x host=ldapuri

Specifies the LDAP server to connect to by a LDAP URI.

-x binddn=bind_dn

Specifies the DN used to bind to the LDAP server.

-x bindpwd=password

Specifies the password or SASL secret used to bind to the LDAP server. Using this option may expose the password to other users on the system via the process list; to avoid this, instead stash the password using the stashsrvpw command of kdb5_ldap_util.

-x sasl_mech=mechanism

Specifies the SASL mechanism used to bind to the LDAP server. The bind DN is ignored if a SASL mechanism is used. New in release 1.13.

-x sasl_authcid=name

Specifies the authentication name used when binding to the LDAP server with a SASL mechanism, if the mechanism requires one. New in release 1.13.

-x sasl_authzid=name

Specifies the authorization name used when binding to the LDAP server with a SASL mechanism. New in release 1.13.

-x sasl_realm=realm

Specifies the realm used when binding to the LDAP server with a SASL mechanism, if the mechanism uses one. New in release 1.13.

-x debug=level

sets the OpenLDAP client library debug level. level is an integer to be interpreted by the library. Debugging messages are printed to standard error. New in release 1.12.

COMMANDS¶

When using the remote client, available commands may be restricted according to the privileges specified in the kadm5.acl file on the admin server.

add_principal¶

add_principal [options] newprinc

Creates the principal newprinc, prompting twice for a password. If no password policy is specified with the -policy option, and the policy named default is assigned to the principal if it exists. However, creating a policy named default will not automatically assign this policy to previously existing principals. This policy assignment can be suppressed with the -clearpolicy option.

This command requires the add privilege.

Aliases: addprinc, ank

Options:

-expire expdate

(getdate time string) The expiration date of the principal.

-pwexpire pwexpdate

(getdate time string) The password expiration date.

-maxlife maxlife

(Time duration or getdate time string) The maximum ticket life for the principal.

-maxrenewlife maxrenewlife

(Time duration or getdate time string) The maximum renewable life of tickets for the principal.

-kvno kvno

The initial key version number.

-policy policy

The password policy used by this principal. If not specified, the policy default is used if it exists (unless -clearpolicy is specified).

-clearpolicy

Prevents any policy from being assigned when -policy is not specified.

{-|+}allow_postdated

-allow_postdated prohibits this principal from obtaining postdated tickets. +allow_postdated clears this flag.

{-|+}allow_forwardable

-allow_forwardable prohibits this principal from obtaining forwardable tickets. +allow_forwardable clears this flag.

{-|+}allow_renewable

-allow_renewable prohibits this principal from obtaining renewable tickets. +allow_renewable clears this flag.

{-|+}allow_proxiable

-allow_proxiable prohibits this principal from obtaining proxiable tickets. +allow_proxiable clears this flag.

{-|+}allow_dup_skey

-allow_dup_skey disables user-to-user authentication for this principal by prohibiting others from obtaining a service ticket encrypted in this principal’s TGT session key. +allow_dup_skey clears this flag.

{-|+}requires_preauth

+requires_preauth requires this principal to preauthenticate before being allowed to kinit. -requires_preauth clears this flag. When +requires_preauth is set on a service principal, the KDC will only issue service tickets for that service principal if the client’s initial authentication was performed using preauthentication.

{-|+}requires_hwauth

+requires_hwauth requires this principal to preauthenticate using a hardware device before being allowed to kinit. -requires_hwauth clears this flag. When +requires_hwauth is set on a service principal, the KDC will only issue service tickets for that service principal if the client’s initial authentication was performed using a hardware device to preauthenticate.

{-|+}ok_as_delegate

+ok_as_delegate sets the okay as delegate flag on tickets issued with this principal as the service. Clients may use this flag as a hint that credentials should be delegated when authenticating to the service. -ok_as_delegate clears this flag.

{-|+}allow_svr

-allow_svr prohibits the issuance of service tickets for this principal. In release 1.17 and later, user-to-user service tickets are still allowed unless the -allow_dup_skey flag is also set. +allow_svr clears this flag.

{-|+}allow_tgs_req

-allow_tgs_req specifies that a Ticket-Granting Service (TGS) request for a service ticket for this principal is not permitted. +allow_tgs_req clears this flag.

{-|+}allow_tix

-allow_tix forbids the issuance of any tickets for this principal. +allow_tix clears this flag.

{-|+}needchange

+needchange forces a password change on the next initial authentication to this principal. -needchange clears this flag.

{-|+}password_changing_service

+password_changing_service marks this principal as a password change service principal.

{-|+}ok_to_auth_as_delegate

+ok_to_auth_as_delegate allows this principal to acquire forwardable tickets to itself from arbitrary users, for use with constrained delegation.

{-|+}no_auth_data_required

+no_auth_data_required prevents PAC or AD-SIGNEDPATH data from being added to service tickets for the principal.

{-|+}lockdown_keys

+lockdown_keys prevents keys for this principal from leaving the KDC via kadmind. The chpass and extract operations are denied for a principal with this attribute. The chrand operation is allowed, but will not return the new keys. The delete and rename operations are also denied if this attribute is set, in order to prevent a malicious administrator from replacing principals like krbtgt/* or kadmin/* with new principals without the attribute. This attribute can be set via the network protocol, but can only be removed using kadmin.local.

-randkey

Sets the key of the principal to a random value.

-nokey

Causes the principal to be created with no key. New in release 1.12.

-pw password

Sets the password of the principal to the specified string and does not prompt for a password. Note: using this option in a shell script may expose the password to other users on the system via the process list.

-e enc:salt,…

Uses the specified keysalt list for setting the keys of the principal. See Keysalt lists in kdc.conf for a list of possible values.

-x db_princ_args

Indicates database-specific options. The options for the LDAP database module are:

-x dn=dn

Specifies the LDAP object that will contain the Kerberos principal being created.

-x linkdn=dn

Specifies the LDAP object to which the newly created Kerberos principal object will point.

-x containerdn=container_dn

Specifies the container object under which the Kerberos principal is to be created.

-x tktpolicy=policy

Associates a ticket policy to the Kerberos principal.

Note

  • The containerdn and linkdn options cannot be specified with the dn option.

  • If the dn or containerdn options are not specified while adding the principal, the principals are created under the principal container configured in the realm or the realm container.

  • dn and containerdn should be within the subtrees or principal container configured in the realm.

Example:

kadmin: addprinc jennifer
No policy specified for "jennifer@ATHENA.MIT.EDU";
defaulting to no policy.
Enter password for principal jennifer@ATHENA.MIT.EDU:
Re-enter password for principal jennifer@ATHENA.MIT.EDU:
Principal "jennifer@ATHENA.MIT.EDU" created.
kadmin:

modify_principal¶

modify_principal [options] principal

Modifies the specified principal, changing the fields as specified. The options to add_principal also apply to this command, except for the -randkey, -pw, and -e options. In addition, the option -clearpolicy will clear the current policy of a principal.

This command requires the modify privilege.

Alias: modprinc

Options (in addition to the addprinc options):

-unlock

Unlocks a locked principal (one which has received too many failed authentication attempts without enough time between them according to its password policy) so that it can successfully authenticate.

rename_principal¶

rename_principal [-force] old_principal new_principal

Renames the specified old_principal to new_principal. This command prompts for confirmation, unless the -force option is given.

This command requires the add and delete privileges.

Alias: renprinc

add_alias¶

add_alias alias_princ target_princ

Create an alias alias_princ pointing to target_princ. Aliases may be chained (that is, target_princ may itself be an alias) up to a depth of 10.

This command requires the add privilege for alias_princ and the modify privilege for target_princ.

(New in release 1.22.)

Aliases: alias

delete_principal¶

delete_principal [-force] principal

Deletes the specified principal or alias from the database. This command prompts for deletion, unless the -force option is given.

This command requires the delete privilege.

Alias: delprinc

change_password¶

change_password [options] principal

Changes the password of principal. Prompts for a new password if neither -randkey or -pw is specified.

This command requires the changepw privilege, or that the principal running the program is the same as the principal being changed.

Alias: cpw

The following options are available:

-randkey

Sets the key of the principal to a random value.

-pw password

Set the password to the specified string. Using this option in a script may expose the password to other users on the system via the process list.

-e enc:salt,…

Uses the specified keysalt list for setting the keys of the principal. See Keysalt lists in kdc.conf for a list of possible values.

-keepold

Keeps the existing keys in the database. This flag is usually not necessary except perhaps for krbtgt principals.

Example:

kadmin: cpw systest
Enter password for principal systest@BLEEP.COM:
Re-enter password for principal systest@BLEEP.COM:
Password for systest@BLEEP.COM changed.
kadmin:

purgekeys¶

purgekeys [-all|-keepkvno oldest_kvno_to_keep] principal

Purges previously retained old keys (e.g., from change_password -keepold) from principal. If -keepkvno is specified, then only purges keys with kvnos lower than oldest_kvno_to_keep. If -all is specified, then all keys are purged. The -all option is new in release 1.12.

This command requires the modify privilege.

get_principal¶

get_principal [-terse] principal

Gets the attributes of principal. With the -terse option, outputs fields as quoted tab-separated strings.

This command requires the inquire privilege, or that the principal running the the program to be the same as the one being listed.

Alias: getprinc

Examples:

kadmin: getprinc tlyu/admin
Principal: tlyu/admin@BLEEP.COM
Expiration date: [never]
Last password change: Mon Aug 12 14:16:47 EDT 1996
Password expiration date: [never]
Maximum ticket life: 0 days 10:00:00
Maximum renewable life: 7 days 00:00:00
Last modified: Mon Aug 12 14:16:47 EDT 1996 (bjaspan/admin@BLEEP.COM)
Last successful authentication: [never]
Last failed authentication: [never]
Failed password attempts: 0
Number of keys: 1
Key: vno 1, aes256-cts-hmac-sha384-192
MKey: vno 1
Attributes:
Policy: [none]

kadmin: getprinc -terse systest
systest@BLEEP.COM   3    86400     604800    1
785926535 753241234 785900000
tlyu/admin@BLEEP.COM     786100034 0    0
kadmin:

list_principals¶

list_principals [expression]

Retrieves all or some principal names. expression is a shell-style glob expression that can contain the wild-card characters ?, *, and []. All principal names matching the expression are printed. If no expression is provided, all principal names are printed. If the expression does not contain an @ character, an @ character followed by the local realm is appended to the expression.

This command requires the list privilege.

Alias: listprincs, get_principals, getprincs

Example:

kadmin:  listprincs test*
test3@SECURE-TEST.OV.COM
test2@SECURE-TEST.OV.COM
test1@SECURE-TEST.OV.COM
testuser@SECURE-TEST.OV.COM
kadmin:

get_strings¶

get_strings principal

Displays string attributes on principal.

This command requires the inquire privilege.

Alias: getstrs

set_string¶

set_string principal name value

Sets a string attribute on principal. String attributes are used to supply per-principal configuration to the KDC and some KDC plugin modules. The following string attribute names are recognized by the KDC:

require_auth

Specifies an authentication indicator which is required to authenticate to the principal as a service. Multiple indicators can be specified, separated by spaces; in this case any of the specified indicators will be accepted. (New in release 1.14.)

session_enctypes

Specifies the encryption types supported for session keys when the principal is authenticated to as a server. See Encryption types in kdc.conf for a list of the accepted values.

otp

Enables One Time Passwords (OTP) preauthentication for a client principal. The value is a JSON string representing an array of objects, each having optional type and username fields.

pkinit_cert_match

Specifies a matching expression that defines the certificate attributes required for the client certificate used by the principal during PKINIT authentication. The matching expression is in the same format as those used by the pkinit_cert_match option in krb5.conf. (New in release 1.16.)

pac_privsvr_enctype

Forces the encryption type of the PAC KDC checksum buffers to the specified encryption type for tickets issued to this server, by deriving a key from the local krbtgt key if it is of a different encryption type. It may be necessary to set this value to “aes256-sha1†on the cross-realm krbtgt entry for an Active Directory realm when using aes-sha2 keys on the local krbtgt entry.

This command requires the modify privilege.

Alias: setstr

Example:

set_string host/foo.mit.edu session_enctypes aes128-cts
set_string user@FOO.COM otp "[{""type"":""hotp"",""username"":""al""}]"

del_string¶

del_string principal key

Deletes a string attribute from principal.

This command requires the delete privilege.

Alias: delstr

add_policy¶

add_policy [options] policy

Adds a password policy named policy to the database.

This command requires the add privilege.

Alias: addpol

The following options are available:

-maxlife time

(Time duration or getdate time string) Sets the maximum lifetime of a password.

-minlife time

(Time duration or getdate time string) Sets the minimum lifetime of a password.

-minlength length

Sets the minimum length of a password.

-minclasses number

Sets the minimum number of character classes required in a password. The five character classes are lower case, upper case, numbers, punctuation, and whitespace/unprintable characters.

-history number

Sets the number of past keys kept for a principal. This option is not supported with the LDAP KDC database module.

-maxfailure maxnumber

Sets the number of authentication failures before the principal is locked. Authentication failures are only tracked for principals which require preauthentication. The counter of failed attempts resets to 0 after a successful attempt to authenticate. A maxnumber value of 0 (the default) disables lockout.

-failurecountinterval failuretime

(Time duration or getdate time string) Sets the allowable time between authentication failures. If an authentication failure happens after failuretime has elapsed since the previous failure, the number of authentication failures is reset to 1. A failuretime value of 0 (the default) means forever.

-lockoutduration lockouttime

(Time duration or getdate time string) Sets the duration for which the principal is locked from authenticating if too many authentication failures occur without the specified failure count interval elapsing. A duration of 0 (the default) means the principal remains locked out until it is administratively unlocked with modprinc -unlock.

-allowedkeysalts

Specifies the key/salt tuples supported for long-term keys when setting or changing a principal’s password/keys. See Keysalt lists in kdc.conf for a list of the accepted values, but note that key/salt tuples must be separated with commas (‘,’) only. To clear the allowed key/salt policy use a value of ‘-‘.

Example:

kadmin: add_policy -maxlife "2 days" -minlength 5 guests
kadmin:

modify_policy¶

modify_policy [options] policy

Modifies the password policy named policy. Options are as described for add_policy.

This command requires the modify privilege.

Alias: modpol

delete_policy¶

delete_policy [-force] policy

Deletes the password policy named policy. Prompts for confirmation before deletion. The command will fail if the policy is in use by any principals.

This command requires the delete privilege.

Alias: delpol

Example:

kadmin: del_policy guests
Are you sure you want to delete the policy "guests"?
(yes/no): yes
kadmin:

get_policy¶

get_policy [ -terse ] policy

Displays the values of the password policy named policy. With the -terse flag, outputs the fields as quoted strings separated by tabs.

This command requires the inquire privilege.

Alias: getpol

Examples:

kadmin: get_policy admin
Policy: admin
Maximum password life: 180 days 00:00:00
Minimum password life: 00:00:00
Minimum password length: 6
Minimum number of password character classes: 2
Number of old keys kept: 5
Reference count: 17

kadmin: get_policy -terse admin
admin     15552000  0    6    2    5    17
kadmin:

The “Reference count†is the number of principals using that policy. With the LDAP KDC database module, the reference count field is not meaningful.

list_policies¶

list_policies [expression]

Retrieves all or some policy names. expression is a shell-style glob expression that can contain the wild-card characters ?, *, and []. All policy names matching the expression are printed. If no expression is provided, all existing policy names are printed.

This command requires the list privilege.

Aliases: listpols, get_policies, getpols.

Examples:

kadmin:  listpols
test-pol
dict-only
once-a-min
test-pol-nopw

kadmin:  listpols t*
test-pol
test-pol-nopw
kadmin:

ktadd¶

ktadd [options] principal
ktadd [options] -glob princ-exp

Adds a principal, or all principals matching princ-exp, to a keytab file. Each principal’s keys are randomized in the process. The rules for princ-exp are described in the list_principals command.

This command requires the inquire and changepw privileges. With the -glob form, it also requires the list privilege.

The options are:

-k[eytab] keytab

Use keytab as the keytab file. Otherwise, the default keytab is used.

-e enc:salt,…

Uses the specified keysalt list for setting the new keys of the principal. See Keysalt lists in kdc.conf for a list of possible values.

-q

Display less verbose information.

-norandkey

Do not randomize the keys. The keys and their version numbers stay unchanged. This option cannot be specified in combination with the -e option.

An entry for each of the principal’s unique encryption types is added, ignoring multiple keys with the same encryption type but different salt types.

Alias: xst

Example:

kadmin: ktadd -k /tmp/foo-new-keytab host/foo.mit.edu
Entry for principal host/foo.mit.edu@ATHENA.MIT.EDU with kvno 3,
     encryption type aes256-cts-hmac-sha1-96 added to keytab
     FILE:/tmp/foo-new-keytab
kadmin:

ktremove¶

ktremove [options] principal [kvno | all | old]

Removes entries for the specified principal from a keytab. Requires no permissions, since this does not require database access.

If the string “all†is specified, all entries for that principal are removed; if the string “old†is specified, all entries for that principal except those with the highest kvno are removed. Otherwise, the value specified is parsed as an integer, and all entries whose kvno match that integer are removed.

The options are:

-k[eytab] keytab

Use keytab as the keytab file. Otherwise, the default keytab is used.

-q

Display less verbose information.

Alias: ktrem

Example:

kadmin: ktremove kadmin/admin all
Entry for principal kadmin/admin with kvno 3 removed from keytab
     FILE:/etc/krb5.keytab
kadmin:

lock¶

Lock database exclusively. Use with extreme caution! This command only works with the DB2 KDC database module.

unlock¶

Release the exclusive database lock.

list_requests¶

Lists available for kadmin requests.

Aliases: lr, ?

quit¶

Exit program. If the database was locked, the lock is released.

Aliases: exit, q

HISTORY¶

The kadmin program was originally written by Tom Yu at MIT, as an interface to the OpenVision Kerberos administration program.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kpasswd, kadmind, kerberos

krb5-1.22.1/doc/html/admin/admin_commands/kprop.html0000664000175000017500000002777615051422656022166 0ustar ghudsonghudson kprop — MIT Kerberos Documentation

kprop¶

SYNOPSIS¶

kprop [-r realm] [-f file] [-d] [-P port] [-s keytab] replica_host

DESCRIPTION¶

kprop is used to securely propagate a Kerberos V5 database dump file from the primary Kerberos server to a replica Kerberos server, which is specified by replica_host. The dump file must be created by kdb5_util.

OPTIONS¶

-r realm

Specifies the realm of the primary server.

-f file

Specifies the filename where the dumped principal database file is to be found; by default the dumped database file is normally LOCALSTATEDIR/krb5kdc/replica_datatrans.

-P port

Specifies the port to use to contact the kpropd server on the remote host.

-d

Prints debugging information.

-s keytab

Specifies the location of the keytab file.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kpropd, kdb5_util, krb5kdc, kerberos

krb5-1.22.1/doc/html/admin/admin_commands/krb5kdc.html0000664000175000017500000004072515051422656022345 0ustar ghudsonghudson krb5kdc — MIT Kerberos Documentation

krb5kdc¶

SYNOPSIS¶

krb5kdc [-x db_args] [-d dbname] [-k keytype] [-M mkeyname] [-p portnum] [-m] [-r realm] [-n] [-w numworkers] [-P pid_file] [-T time_offset]

DESCRIPTION¶

krb5kdc is the Kerberos version 5 Authentication Service and Key Distribution Center (AS/KDC).

OPTIONS¶

The -r realm option specifies the realm for which the server should provide service. This option may be specified multiple times to serve multiple realms. If no -r option is given, the default realm (as specified in krb5.conf) will be served.

The -d dbname option specifies the name under which the principal database can be found. This option does not apply to the LDAP database.

The -k keytype option specifies the key type of the master key to be entered manually as a password when -m is given; the default is aes256-cts-hmac-sha1-96.

The -M mkeyname option specifies the principal name for the master key in the database (usually K/M in the KDC’s realm).

The -m option specifies that the master database password should be fetched from the keyboard rather than from a stash file.

The -n option specifies that the KDC does not put itself in the background and does not disassociate itself from the terminal.

The -P pid_file option tells the KDC to write its PID into pid_file after it starts up. This can be used to identify whether the KDC is still running and to allow init scripts to stop the correct process.

The -p portnum option specifies the default UDP and TCP port numbers which the KDC should listen on for Kerberos version 5 requests, as a comma-separated list. This value overrides the port numbers specified in the [kdcdefaults] section of kdc.conf, but may be overridden by realm-specific values. If no value is given from any source, the default port is 88.

The -w numworkers option tells the KDC to fork numworkers processes to listen to the KDC ports and process requests in parallel. The top level KDC process (whose pid is recorded in the pid file if the -P option is also given) acts as a supervisor. The supervisor will relay SIGHUP signals to the worker subprocesses, and will terminate the worker subprocess if the it is itself terminated or if any other worker process exits.

The -x db_args option specifies database-specific arguments. See Database Options in kadmin for supported arguments.

The -T offset option specifies a time offset, in seconds, which the KDC will operate under. It is intended only for testing purposes.

EXAMPLE¶

The KDC may service requests for multiple realms (maximum 32 realms). The realms are listed on the command line. Per-realm options that can be specified on the command line pertain for each realm that follows it and are superseded by subsequent definitions of the same option.

For example:

krb5kdc -p 2001 -r REALM1 -p 2002 -r REALM2 -r REALM3

specifies that the KDC listen on port 2001 for REALM1 and on port 2002 for REALM2 and REALM3. Additionally, per-realm parameters may be specified in the kdc.conf file. The location of this file may be specified by the KRB5_KDC_PROFILE environment variable. Per-realm parameters specified in this file take precedence over options specified on the command line. See the kdc.conf description for further details.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

As of release 1.22, krb5kdc supports systemd socket activation via the LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by the caller must correspond to configured listener addresses (via the kdc_listen variable or equivalent) or they will be ignored. Any configured listener addresses that do not correspond to caller-provided sockets will be ignored if socket activation is used.

SEE ALSO¶

kdb5_util, kdc.conf, krb5.conf, kdb5_ldap_util, kerberos

krb5-1.22.1/doc/html/admin/admin_commands/kadmind.html0000664000175000017500000004213715051422656022426 0ustar ghudsonghudson kadmind — MIT Kerberos Documentation

kadmind¶

SYNOPSIS¶

kadmind [-x db_args] [-r realm] [-m] [-nofork] [-proponly] [-port port-number] [-P pid_file] [-p kdb5_util_path] [-K kprop_path] [-k kprop_port] [-F dump_file]

DESCRIPTION¶

kadmind starts the Kerberos administration server. kadmind typically runs on the primary Kerberos server, which stores the KDC database. If the KDC database uses the LDAP module, the administration server and the KDC server need not run on the same machine. kadmind accepts remote requests from programs such as kadmin and kpasswd to administer the information in these database.

kadmind requires a number of configuration files to be set up in order for it to work:

kdc.conf

The KDC configuration file contains configuration information for the KDC and admin servers. kadmind uses settings in this file to locate the Kerberos database, and is also affected by the acl_file, dict_file, kadmind_port, and iprop-related settings.

kadm5.acl

kadmind’s ACL (access control list) tells it which principals are allowed to perform administration actions. The pathname to the ACL file can be specified with the acl_file kdc.conf variable; by default, it is LOCALSTATEDIR/krb5kdc/kadm5.acl.

After the server begins running, it puts itself in the background and disassociates itself from its controlling terminal.

kadmind can be configured for incremental database propagation. Incremental propagation allows replica KDC servers to receive principal and policy updates incrementally instead of receiving full dumps of the database. This facility can be enabled in the kdc.conf file with the iprop_enable option. Incremental propagation requires the principal kiprop/PRIMARY\@REALM (where PRIMARY is the primary KDC’s canonical host name, and REALM the realm name). In release 1.13, this principal is automatically created and registered into the datebase.

OPTIONS¶

-r realm

specifies the realm that kadmind will serve; if it is not specified, the default realm of the host is used.

-m

causes the master database password to be fetched from the keyboard (before the server puts itself in the background, if not invoked with the -nofork option) rather than from a file on disk.

-nofork

causes the server to remain in the foreground and remain associated to the terminal.

-proponly

causes the server to only listen and respond to Kerberos replica incremental propagation polling requests. This option can be used to set up a hierarchical propagation topology where a replica KDC provides incremental updates to other Kerberos replicas.

-port port-number

specifies the port on which the administration server listens for connections. The default port is determined by the kadmind_port configuration variable in kdc.conf.

-P pid_file

specifies the file to which the PID of kadmind process should be written after it starts up. This file can be used to identify whether kadmind is still running and to allow init scripts to stop the correct process.

-p kdb5_util_path

specifies the path to the kdb5_util command to use when dumping the KDB in response to full resync requests when iprop is enabled.

-K kprop_path

specifies the path to the kprop command to use to send full dumps to replicas in response to full resync requests.

-k kprop_port

specifies the port by which the kprop process that is spawned by kadmind connects to the replica kpropd, in order to transfer the dump file during an iprop full resync request.

-F dump_file

specifies the file path to be used for dumping the KDB in response to full resync requests when iprop is enabled.

-x db_args

specifies database-specific arguments. See Database Options in kadmin for supported arguments.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

As of release 1.22, kadmind supports systemd socket activation via the LISTEN_PID and LISTEN_FDS environment variables. Sockets provided by the caller must correspond to configured listener addresses (via the kadmind_listen or kpasswd_listen variables or equivalents) or they will be ignored. Any configured listener addresses that do not correspond to caller-provided sockets will be ignored if socket activation is used.

SEE ALSO¶

kpasswd, kadmin, kdb5_util, kdb5_ldap_util, kadm5.acl, kerberos

krb5-1.22.1/doc/html/admin/admin_commands/kdb5_util.html0000664000175000017500000010135315051422656022675 0ustar ghudsonghudson kdb5_util — MIT Kerberos Documentation

kdb5_util¶

SYNOPSIS¶

kdb5_util [-r realm] [-d dbname] [-k mkeytype] [-kv mkeyVNO] [-M mkeyname] [-m] [-sf stashfilename] [-P password] [-x db_args] command [command_options]

DESCRIPTION¶

kdb5_util allows an administrator to perform maintenance procedures on the KDC database. Databases can be created, destroyed, and dumped to or loaded from ASCII files. kdb5_util can create a Kerberos master key stash file or perform live rollover of the master key.

When kdb5_util is run, it attempts to acquire the master key and open the database. However, execution continues regardless of whether or not kdb5_util successfully opens the database, because the database may not exist yet or the stash file may be corrupt.

Note that some KDC database modules may not support all kdb5_util commands.

COMMAND-LINE OPTIONS¶

-r realm

specifies the Kerberos realm of the database.

-d dbname

specifies the name under which the principal database is stored; by default the database is that listed in kdc.conf. The password policy database and lock files are also derived from this value.

-k mkeytype

specifies the key type of the master key in the database. The default is given by the master_key_type variable in kdc.conf.

-kv mkeyVNO

Specifies the version number of the master key in the database; the default is 1. Note that 0 is not allowed.

-M mkeyname

principal name for the master key in the database. If not specified, the name is determined by the master_key_name variable in kdc.conf.

-m

specifies that the master database password should be read from the keyboard rather than fetched from a file on disk.

-sf stash_file

specifies the stash filename of the master database password. If not specified, the filename is determined by the key_stash_file variable in kdc.conf.

-P password

specifies the master database password. Using this option may expose the password to other users on the system via the process list.

-x db_args

specifies database-specific options. See kadmin for supported options.

COMMANDS¶

create¶

create [-s]

Creates a new database. If the -s option is specified, the stash file is also created. This command fails if the database already exists. If the command is successful, the database is opened just as if it had already existed when the program was first run.

destroy¶

destroy [-f]

Destroys the database, first overwriting the disk sectors and then unlinking the files, after prompting the user for confirmation. With the -f argument, does not prompt the user.

stash¶

stash [-f keyfile]

Stores the master principal’s keys in a stash file. The -f argument can be used to override the keyfile specified in kdc.conf.

dump¶

dump [-b7|-r13|-r18] [-verbose] [-mkey_convert] [-new_mkey_file mkey_file] [-rev] [-recurse] [filename [principals…]]

Dumps the current Kerberos and KADM5 database into an ASCII file. By default, the database is dumped in current format, “kdb5_util load_dump version 7â€. If filename is not specified, or is the string “-â€, the dump is sent to standard output. Options:

-b7

causes the dump to be in the Kerberos 5 Beta 7 format (“kdb5_util load_dump version 4â€). This was the dump format produced on releases prior to 1.2.2.

-r13

causes the dump to be in the Kerberos 5 1.3 format (“kdb5_util load_dump version 5â€). This was the dump format produced on releases prior to 1.8.

-r18

causes the dump to be in the Kerberos 5 1.8 format (“kdb5_util load_dump version 6â€). This was the dump format produced on releases prior to 1.11.

-verbose

causes the name of each principal and policy to be printed as it is dumped.

-mkey_convert

prompts for a new master key. This new master key will be used to re-encrypt principal key data in the dumpfile. The principal keys themselves will not be changed.

-new_mkey_file mkey_file

the filename of a stash file. The master key in this stash file will be used to re-encrypt the key data in the dumpfile. The key data in the database will not be changed.

-rev

dumps in reverse order. This may recover principals that do not dump normally, in cases where database corruption has occurred.

-recurse

causes the dump to walk the database recursively (btree only). This may recover principals that do not dump normally, in cases where database corruption has occurred. In cases of such corruption, this option will probably retrieve more principals than the -rev option will.

Changed in version 1.15: Release 1.15 restored the functionality of the -recurse option.

Changed in version 1.5: The -recurse option ceased working until release 1.15, doing a normal dump instead of a recursive traversal.

load¶

load [-b7|-r13|-r18] [-hash] [-verbose] [-update] filename

Loads a database dump from the named file into the named database. If no option is given to determine the format of the dump file, the format is detected automatically and handled as appropriate. Unless the -update option is given, load creates a new database containing only the data in the dump file, overwriting the contents of any previously existing database. Note that when using the LDAP KDC database module, the -update flag is required.

Options:

-b7

requires the database to be in the Kerberos 5 Beta 7 format (“kdb5_util load_dump version 4â€). This was the dump format produced on releases prior to 1.2.2.

-r13

requires the database to be in Kerberos 5 1.3 format (“kdb5_util load_dump version 5â€). This was the dump format produced on releases prior to 1.8.

-r18

requires the database to be in Kerberos 5 1.8 format (“kdb5_util load_dump version 6â€). This was the dump format produced on releases prior to 1.11.

-hash

stores the database in hash format, if using the DB2 database type. If this option is not specified, the database will be stored in btree format. This option is not recommended, as databases stored in hash format are known to corrupt data and lose principals.

-verbose

causes the name of each principal and policy to be printed as it is dumped.

-update

records from the dump file are added to or updated in the existing database. Otherwise, a new database is created containing only what is in the dump file and the old one destroyed upon successful completion.

ark¶

ark [-e enc:salt,…] principal

Adds new random keys to principal at the next available key version number. Keys for the current highest key version number will be preserved. The -e option specifies the list of encryption and salt types to be used for the new keys.

add_mkey¶

add_mkey [-e etype] [-s]

Adds a new master key to the master key principal, but does not mark it as active. Existing master keys will remain. The -e option specifies the encryption type of the new master key; see Encryption types in kdc.conf for a list of possible values. The -s option stashes the new master key in the stash file, which will be created if it doesn’t already exist.

After a new master key is added, it should be propagated to replica servers via a manual or periodic invocation of kprop. Then, the stash files on the replica servers should be updated with the kdb5_util stash command. Once those steps are complete, the key is ready to be marked active with the kdb5_util use_mkey command.

use_mkey¶

use_mkey mkeyVNO [time]

Sets the activation time of the master key specified by mkeyVNO. Once a master key becomes active, it will be used to encrypt newly created principal keys. If no time argument is given, the current time is used, causing the specified master key version to become active immediately. The format for time is getdate time string.

After a new master key becomes active, the kdb5_util update_princ_encryption command can be used to update all principal keys to be encrypted in the new master key.

list_mkeys¶

list_mkeys

List all master keys, from most recent to earliest, in the master key principal. The output will show the kvno, enctype, and salt type for each mkey, similar to the output of kadmin getprinc. A * following an mkey denotes the currently active master key.

purge_mkeys¶

purge_mkeys [-f] [-n] [-v]

Delete master keys from the master key principal that are not used to protect any principals. This command can be used to remove old master keys all principal keys are protected by a newer master key.

-f

does not prompt for confirmation.

-n

performs a dry run, showing master keys that would be purged, but not actually purging any keys.

-v

gives more verbose output.

update_princ_encryption¶

update_princ_encryption [-f] [-n] [-v] [princ-pattern]

Update all principal records (or only those matching the princ-pattern glob pattern) to re-encrypt the key data using the active database master key, if they are encrypted using a different version, and give a count at the end of the number of principals updated. If the -f option is not given, ask for confirmation before starting to make changes. The -v option causes each principal processed to be listed, with an indication as to whether it needed updating or not. The -n option performs a dry run, only showing the actions which would have been taken.

tabdump¶

tabdump [-H] [-c] [-e] [-n] [-o outfile] dumptype

Dump selected fields of the database in a tabular format suitable for reporting (e.g., using traditional Unix text processing tools) or importing into relational databases. The data format is tab-separated (default), or optionally comma-separated (CSV), with a fixed number of columns. The output begins with a header line containing field names, unless suppression is requested using the -H option.

The dumptype parameter specifies the name of an output table (see below).

Options:

-H

suppress writing the field names in a header line

-c

use comma separated values (CSV) format, with minimal quoting, instead of the default tab-separated (unquoted, unescaped) format

-e

write empty hexadecimal string fields as empty fields instead of as “-1â€.

-n

produce numeric output for fields that normally have symbolic output, such as enctypes and flag names. Also requests output of time stamps as decimal POSIX time_t values.

-o outfile

write the dump to the specified output file instead of to standard output

Dump types:

alias

principal alias information

aliasname

the name of the alias

targetname

the target of the alias

keydata

principal encryption key information, including actual key data (which is still encrypted in the master key)

name

principal name

keyindex

index of this key in the principal’s key list

kvno

key version number

enctype

encryption type

key

key data as a hexadecimal string

salttype

salt type

salt

salt data as a hexadecimal string

keyinfo

principal encryption key information (as in keydata above), excluding actual key data

princ_flags

principal boolean attributes. Flag names print as hexadecimal numbers if the -n option is specified, and all flag positions are printed regardless of whether or not they are set. If -n is not specified, print all known flag names for each principal, but only print hexadecimal flag names if the corresponding flag is set.

name

principal name

flag

flag name

value

boolean value (0 for clear, or 1 for set)

princ_lockout

state information used for tracking repeated password failures

name

principal name

last_success

time stamp of most recent successful authentication

last_failed

time stamp of most recent failed authentication

fail_count

count of failed attempts

princ_meta

principal metadata

name

principal name

modby

name of last principal to modify this principal

modtime

timestamp of last modification

lastpwd

timestamp of last password change

policy

policy object name

mkvno

key version number of the master key that encrypts this principal’s key data

hist_kvno

key version number of the history key that encrypts the key history data for this principal

princ_stringattrs

string attributes (key/value pairs)

name

principal name

key

attribute name

value

attribute value

princ_tktpolicy

per-principal ticket policy data, including maximum ticket lifetimes

name

principal name

expiration

principal expiration date

pw_expiration

password expiration date

max_life

maximum ticket lifetime

max_renew_life

maximum renewable ticket lifetime

Examples:

$ kdb5_util tabdump -o keyinfo.txt keyinfo
$ cat keyinfo.txt
name        keyindex        kvno    enctype salttype        salt
K/M@EXAMPLE.COM     0       1       aes256-cts-hmac-sha384-192      normal  -1
foo@EXAMPLE.COM     0       1       aes128-cts-hmac-sha1-96 normal  -1
bar@EXAMPLE.COM     0       1       aes128-cts-hmac-sha1-96 normal  -1
$ sqlite3
sqlite> .mode tabs
sqlite> .import keyinfo.txt keyinfo
sqlite> select * from keyinfo where enctype like 'aes256-%';
K/M@EXAMPLE.COM     1       1       aes256-cts-hmac-sha384-192      normal  -1
sqlite> .quit
$ awk -F'\t' '$4 ~ /aes256-/ { print }' keyinfo.txt
K/M@EXAMPLE.COM     1       1       aes256-cts-hmac-sha384-192      normal  -1

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kadmin, kerberos

krb5-1.22.1/doc/html/admin/admin_commands/k5srvutil.html0000664000175000017500000003050615051422656022764 0ustar ghudsonghudson k5srvutil — MIT Kerberos Documentation

k5srvutil¶

SYNOPSIS¶

k5srvutil operation [-i] [-f filename] [-e keysalts]

DESCRIPTION¶

k5srvutil allows an administrator to list keys currently in a keytab, to obtain new keys for a principal currently in a keytab, or to delete non-current keys from a keytab.

operation must be one of the following:

list

Lists the keys in a keytab, showing version number and principal name.

change

Uses the kadmin protocol to update the keys in the Kerberos database to new randomly-generated keys, and updates the keys in the keytab to match. If a key’s version number doesn’t match the version number stored in the Kerberos server’s database, then the operation will fail. If the -i flag is given, k5srvutil will prompt for confirmation before changing each key. If the -k option is given, the old and new keys will be displayed. Ordinarily, keys will be generated with the default encryption types and key salts. This can be overridden with the -e option. Old keys are retained in the keytab so that existing tickets continue to work, but delold should be used after such tickets expire, to prevent attacks against the old keys.

delold

Deletes keys that are not the most recent version from the keytab. This operation should be used some time after a change operation to remove old keys, after existing tickets issued for the service have expired. If the -i flag is given, then k5srvutil will prompt for confirmation for each principal.

delete

Deletes particular keys in the keytab, interactively prompting for each key.

In all cases, the default keytab is used unless this is overridden by the -f option.

k5srvutil uses the kadmin program to edit the keytab in place.

ENVIRONMENT¶

See kerberos for a description of Kerberos environment variables.

SEE ALSO¶

kadmin, ktutil, kerberos

krb5-1.22.1/doc/html/admin/dictionary.html0000664000175000017500000003264215051422656020213 0ustar ghudsonghudson Addressing dictionary attack risks — MIT Kerberos Documentation

Addressing dictionary attack risks¶

Kerberos initial authentication is normally secured using the client principal’s long-term key, which for users is generally derived from a password. Using a pasword-derived long-term key carries the risk of a dictionary attack, where an attacker tries a sequence of possible passwords, possibly requiring much less effort than would be required to try all possible values of the key. Even if password policy objects are used to force users not to pick trivial passwords, dictionary attacks can sometimes be successful against a significant fraction of the users in a realm. Dictionary attacks are not a concern for principals using random keys.

A dictionary attack may be online or offline. An online dictionary attack is performed by trying each password in a separate request to the KDC, and is therefore visible to the KDC and also limited in speed by the KDC’s processing power and the network capacity between the client and the KDC. Online dictionary attacks can be mitigated using account lockout. This measure is not totally satisfactory, as it makes it easy for an attacker to deny access to a client principal.

An offline dictionary attack is performed by obtaining a ciphertext generated using the password-derived key, and trying each password against the ciphertext. This category of attack is invisible to the KDC and can be performed much faster than an online attack. The attack will generally take much longer with more recent encryption types (particularly the ones based on AES), because those encryption types use a much more expensive string-to-key function. However, the best defense is to deny the attacker access to a useful ciphertext. The required defensive measures depend on the attacker’s level of network access.

An off-path attacker has no access to packets sent between legitimate users and the KDC. An off-path attacker could gain access to an attackable ciphertext either by making an AS request for a client principal which does not have the +requires_preauth flag, or by making a TGS request (after authenticating as a different user) for a server principal which does not have the -allow_svr flag. To address off-path attackers, a KDC administrator should set those flags on principals with password-derived keys:

kadmin: add_principal +requires_preauth -allow_svr princname

An attacker with passive network access (one who can monitor packets sent between legitimate users and the KDC, but cannot change them or insert their own packets) can gain access to an attackable ciphertext by observing an authentication by a user using the most common form of preauthentication, encrypted timestamp. Any of the following methods can prevent dictionary attacks by attackers with passive network access:

  • Enabling SPAKE preauthentication (added in release 1.17) on the KDC, and ensuring that all clients are able to support it.

  • Using an HTTPS proxy for communication with the KDC, if the attacker cannot monitor communication between the proxy server and the KDC.

  • Using FAST, protecting the initial authentication with either a random key (such as a host key) or with anonymous PKINIT.

An attacker with active network access (one who can inject or modify packets sent between legitimate users and the KDC) can try to fool the client software into sending an attackable ciphertext using an encryption type and salt string of the attacker’s choosing. Any of the following methods can prevent dictionary attacks by active attackers:

  • Enabling SPAKE preauthentication and setting the disable_encrypted_timestamp variable to true in the [realms] subsection of the client configuration.

  • Using an HTTPS proxy as described above, configured in the client’s krb5.conf realm configuration. If KDC discovery is used to locate a proxy server, an active attacker may be able to use DNS spoofing to cause the client to use a different HTTPS server or to not use HTTPS.

  • Using FAST as described above.

If PKINIT or OTP are used for initial authentication, the principal’s long-term keys are not used and dictionary attacks are usually not a concern.

krb5-1.22.1/doc/html/admin/database.html0000664000175000017500000015145215051422656017613 0ustar ghudsonghudson Database administration — MIT Kerberos Documentation

Database administration¶

A Kerberos database contains all of a realm’s Kerberos principals, their passwords, and other administrative information about each principal. For the most part, you will use the kdb5_util program to manipulate the Kerberos database as a whole, and the kadmin program to make changes to the entries in the database. (One notable exception is that users will use the kpasswd program to change their own passwords.) The kadmin program has its own command-line interface, to which you type the database administrating commands.

kdb5_util provides a means to create, delete, load, or dump a Kerberos database. It also contains commands to roll over the database master key, and to stash a copy of the key so that the kadmind and krb5kdc daemons can use the database without manual input.

kadmin provides for the maintenance of Kerberos principals, password policies, and service key tables (keytabs). Normally it operates as a network client using Kerberos authentication to communicate with kadmind, but there is also a variant, named kadmin.local, which directly accesses the Kerberos database on the local filesystem (or through LDAP). kadmin.local is necessary to set up enough of the database to be able to use the remote version.

kadmin can authenticate to the admin server using the service principal kadmin/admin or kadmin/HOST (where HOST is the hostname of the admin server). If the credentials cache contains a ticket for either service principal and the -c ccache option is specified, that ticket is used to authenticate to KADM5. Otherwise, the -p and -k options are used to specify the client Kerberos principal name used to authenticate. Once kadmin has determined the principal name, it requests a kadmin/admin Kerberos service ticket from the KDC, and uses that service ticket to authenticate to KADM5.

See kadmin for the available kadmin and kadmin.local commands and options.

Principals¶

Each entry in the Kerberos database contains a Kerberos principal and the attributes and policies associated with that principal.

To add a principal to the database, use the kadmin add_principal command. User principals should usually be created with the +requires_preauth -allow_svr options to help mitigate dictionary attacks (see Addressing dictionary attack risks):

kadmin: addprinc +requires_preauth -allow_svr alice
Enter password for principal "alice@KRBTEST.COM":
Re-enter password for principal "alice@KRBTEST.COM":

User principals which will authenticate with PKINIT configuration should instead by created with the -nokey option:

kadmin: addprinc -nokey alice

Service principals can be created with the -nokey option; long-term keys will be added when a keytab is generated:

kadmin: addprinc -nokey host/foo.mit.edu
kadmin: ktadd -k foo.keytab host/foo.mit.edu
Entry for principal host/foo.mit.edu with kvno 1, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:foo.keytab.
Entry for principal host/foo.mit.edu with kvno 1, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:foo.keytab.

To modify attributes of an existing principal, use the kadmin modify_principal command:

kadmin: modprinc -expire tomorrow alice
Principal "alice@KRBTEST.COM" modified.

To delete a principal, use the kadmin delete_principal command:

kadmin: delprinc alice
Are you sure you want to delete the principal "alice@KRBTEST.COM"? (yes/no): yes
Principal "alice@KRBTEST.COM" deleted.
Make sure that you have removed this principal from all ACLs before reusing.

To change a principal’s password, use the kadmin change_password command. Password changes made through kadmin are subject to the same password policies as would apply to password changes made through kpasswd.

To view the attributes of a principal, use the kadmin` get_principal command.

To generate a listing of principals, use the kadmin list_principals command.

To give a principal additional names, use the kadmin add_alias command to create aliases to the principal (new in release 1.22). Aliases can be removed with the delete_principal command.

Policies¶

A policy is a set of rules governing passwords. Policies can dictate minimum and maximum password lifetimes, minimum number of characters and character classes a password must contain, and the number of old passwords kept in the database.

To add a new policy, use the kadmin add_policy command:

kadmin: addpol -maxlife "1 year" -history 3 stduser

To modify attributes of a principal, use the kadmin modify_policy command. To delete a policy, use the kadmin delete_policy command.

To associate a policy with a principal, use the kadmin modify_principal command with the -policy option:

kadmin: modprinc -policy stduser alice Principal “alice@KRBTEST.COM†modified.

A principal entry may be associated with a nonexistent policy, either because the policy did not exist at the time of associated or was deleted afterwards. kadmin will warn when associated a principal with a nonexistent policy, and will annotate the policy name with “[does not exist]†in the get_principal output.

Updating the history key¶

If a policy specifies a number of old keys kept of two or more, the stored old keys are encrypted in a history key, which is found in the key data of the kadmin/history principal.

Currently there is no support for proper rollover of the history key, but you can change the history key (for example, to use a better encryption type) at the cost of invalidating currently stored old keys. To change the history key, run:

kadmin: change_password -randkey kadmin/history

This command will fail if you specify the -keepold flag. Only one new history key will be created, even if you specify multiple key/salt combinations.

In the future, we plan to migrate towards encrypting old keys in the master key instead of the history key, and implementing proper rollover support for stored old keys.

Privileges¶

Administrative privileges for the Kerberos database are stored in the file kadm5.acl.

Note

A common use of an admin instance is so you can grant separate permissions (such as administrator access to the Kerberos database) to a separate Kerberos principal. For example, the user joeadmin might have a principal for his administrative use, called joeadmin/admin. This way, joeadmin would obtain joeadmin/admin tickets only when he actually needs to use those permissions.

Operations on the Kerberos database¶

The kdb5_util command is the primary tool for administrating the Kerberos database when using the DB2 or LMDB modules (see Database types). Creating a database is described in Create the KDC database.

To create a stash file using the master password (because the database was not created with one using the create -s flag, or after restoring from a backup which did not contain the stash file), use the kdb5_util stash command:

$ kdb5_util stash
kdb5_util: Cannot find/read stored master key while reading master key
kdb5_util: Warning: proceeding without master key
Enter KDC database master key:  <= Type the KDC database master password.

To destroy a database, use the kdb5_util destroy command:

$ kdb5_util destroy
Deleting KDC database stored in '/var/krb5kdc/principal', are you sure?
(type 'yes' to confirm)? yes
OK, deleting database '/var/krb5kdc/principal'...
** Database '/var/krb5kdc/principal' destroyed.

Dumping and loading a Kerberos database¶

To dump a Kerberos database into a text file for backup or transfer purposes, use the kdb5_util dump command on one of the KDCs:

$ kdb5_util dump dumpfile

$ kbd5_util dump -verbose dumpfile
kadmin/admin@ATHENA.MIT.EDU
krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU
kadmin/history@ATHENA.MIT.EDU
K/M@ATHENA.MIT.EDU
kadmin/changepw@ATHENA.MIT.EDU

You may specify which principals to dump, using full principal names including realm:

$ kdb5_util dump -verbose someprincs K/M@ATHENA.MIT.EDU kadmin/admin@ATHENA.MIT.EDU
kadmin/admin@ATHENA.MIT.EDU
K/M@ATHENA.MIT.EDU

To restore a Kerberos database dump from a file, use the kdb5_util load command:

$ kdb5_util load dumpfile

To update an existing database with a partial dump file containing only some principals, use the -update flag:

$ kdb5_util load -update someprincs

Note

If the database file exists, and the -update flag was not given, kdb5_util will overwrite the existing database.

Updating the master key¶

Starting with release 1.7, kdb5_util allows the master key to be changed using a rollover process, with minimal loss of availability. To roll over the master key, follow these steps:

  1. On the primary KDC, run kdb5_util list_mkeys to view the current master key version number (KVNO). If you have never rolled over the master key before, this will likely be version 1:

    $ kdb5_util list_mkeys
    Master keys for Principal: K/M@KRBTEST.COM
    KVNO: 1, Enctype: aes256-cts-hmac-sha384-192, Active on: Thu Jan 01 00:00:00 UTC 1970 *
    
  2. On the primary KDC, run kdb5_util use_mkey 1 to ensure that a master key activation list is present in the database. This step is unnecessary in release 1.11.4 or later, or if the database was initially created with release 1.7 or later.

  3. On the primary KDC, run kdb5_util add_mkey -s to create a new master key and write it to the stash file. Enter a secure password when prompted. If this is the first time you are changing the master key, the new key will have version 2. The new master key will not be used until you make it active.

  4. Propagate the database to all replica KDCs, either manually or by waiting until the next scheduled propagation. If you do not have any replica KDCs, you can skip this and the next step.

  5. On each replica KDC, run kdb5_util list_mkeys to verify that the new master key is present, and then kdb5_util stash to write the new master key to the replica KDC’s stash file.

  6. On the primary KDC, run kdb5_util use_mkey 2 to begin using the new master key. Replace 2 with the version of the new master key, as appropriate. You can optionally specify a date for the new master key to become active; by default, it will become active immediately. Prior to release 1.12, kadmind must be restarted for this change to take full effect.

  7. On the primary KDC, run kdb5_util update_princ_encryption. This command will iterate over the database and re-encrypt all keys in the new master key. If the database is large and uses DB2, the primary KDC will become unavailable while this command runs, but clients should fail over to replica KDCs (if any are present) during this time period. In release 1.13 and later, you can instead run kdb5_util -x unlockiter update_princ_encryption to use unlocked iteration; this variant will take longer, but will keep the database available to the KDC and kadmind while it runs.

  8. Wait until the above changes have propagated to all replica KDCs and until all running KDC and kadmind processes have serviced requests using updated principal entries.

  9. On the primary KDC, run kdb5_util purge_mkeys to clean up the old master key.

Operations on the LDAP database¶

The kdb5_ldap_util command is the primary tool for administrating the Kerberos database when using the LDAP module. Creating an LDAP Kerberos database is describe in Configuring Kerberos with OpenLDAP back-end.

To view a list of realms in the LDAP database, use the kdb5_ldap_util list command:

$ kdb5_ldap_util list
KRBTEST.COM

To modify the attributes of a realm, use the kdb5_ldap_util modify command. For example, to change the default realm’s maximum ticket life:

$ kdb5_ldap_util modify -maxtktlife "10 hours"

To display the attributes of a realm, use the kdb5_ldap_util view command:

$ kdb5_ldap_util view
               Realm Name: KRBTEST.COM
      Maximum Ticket Life: 0 days 00:10:00

To remove a realm from the LDAP database, destroying its contents, use the kdb5_ldap_util destroy command:

$ kdb5_ldap_util destroy
Deleting KDC database of 'KRBTEST.COM', are you sure?
(type 'yes' to confirm)? yes
OK, deleting database of 'KRBTEST.COM'...
** Database of 'KRBTEST.COM' destroyed.

Ticket Policy operations¶

Unlike the DB2 and LMDB modules, the LDAP module supports ticket policy objects, which can be associated with principals to restrict maximum ticket lifetimes and set mandatory principal flags. Ticket policy objects are distinct from the password policies described earlier on this page, and are chiefly managed through kdb5_ldap_util rather than kadmin. To create a new ticket policy, use the kdb5_ldap_util create_policy command:

$ kdb5_ldap_util create_policy -maxrenewlife "2 days" users

To associate a ticket policy with a principal, use the kadmin modify_principal (or add_principal) command with the -x tktpolicy=policy option:

$ kadmin.local modprinc -x tktpolicy=users alice

To remove a ticket policy reference from a principal, use the same command with an empty policy:

$ kadmin.local modprinc -x tktpolicy= alice

To list the existing ticket policy objects, use the kdb5_ldap_util list_policy command:

$ kdb5_ldap_util list_policy
users

To modify the attributes of a ticket policy object, use the kdb5_ldap_util modify_policy command:

$ kdb5_ldap_util modify_policy -allow_svr +requires_preauth users

To view the attributes of a ticket policy object, use the kdb5_ldap_util view_policy command:

$ kdb5_ldap_util view_policy users
            Ticket policy: users
   Maximum renewable life: 2 days 00:00:00
             Ticket flags: REQUIRES_PRE_AUTH DISALLOW_SVR

To destroy an ticket policy object, use the kdb5_ldap_util destroy_policy command:

$ kdb5_ldap_util destroy_policy users
This will delete the policy object 'users', are you sure?
(type 'yes' to confirm)? yes
** policy object 'users' deleted.

Cross-realm authentication¶

In order for a KDC in one realm to authenticate Kerberos users in a different realm, it must share a key with the KDC in the other realm. In both databases, there must be krbtgt service principals for both realms. For example, if you need to do cross-realm authentication between the realms ATHENA.MIT.EDU and EXAMPLE.COM, you would need to add the principals krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU and krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM to both databases. These principals must all have the same passwords, key version numbers, and encryption types; this may require explicitly setting the key version number with the -kvno option.

In the ATHENA.MIT.EDU and EXAMPLE.COM cross-realm case, the administrators would run the following commands on the KDCs in both realms:

shell%: kadmin.local -e "aes256-cts:normal"
kadmin: addprinc -requires_preauth krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM
Enter password for principal krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM:
Re-enter password for principal krbtgt/ATHENA.MIT.EDU@EXAMPLE.COM:
kadmin: addprinc -requires_preauth krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU
Enter password for principal krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU:
Enter password for principal krbtgt/EXAMPLE.COM@ATHENA.MIT.EDU:
kadmin:

Note

Even if most principals in a realm are generally created with the requires_preauth flag enabled, this flag is not desirable on cross-realm authentication keys because doing so makes it impossible to disable preauthentication on a service-by-service basis. Disabling it as in the example above is recommended.

Note

It is very important that these principals have good passwords. MIT recommends that TGT principal passwords be at least 26 characters of random ASCII text.

Changing the krbtgt key¶

A Kerberos Ticket Granting Ticket (TGT) is a service ticket for the principal krbtgt/REALM. The key for this principal is created when the Kerberos database is initialized and need not be changed. However, it will only have the encryption types supported by the KDC at the time of the initial database creation. To allow use of newer encryption types for the TGT, this key has to be changed.

Changing this key using the normal kadmin change_password command would invalidate any previously issued TGTs. Therefore, when changing this key, normally one should use the -keepold flag to change_password to retain the previous key in the database as well as the new key. For example:

kadmin: change_password -randkey -keepold krbtgt/ATHENA.MIT.EDU@ATHENA.MIT.EDU

Warning

After issuing this command, the old key is still valid and is still vulnerable to (for instance) brute force attacks. To completely retire an old key or encryption type, run the kadmin purgekeys command to delete keys with older kvnos, ideally first making sure that all tickets issued with the old keys have expired.

Only the first krbtgt key of the newest key version is used to encrypt ticket-granting tickets. However, the set of encryption types present in the krbtgt keys is used by default to determine the session key types supported by the krbtgt service (see Session key selection). Because non-MIT Kerberos clients sometimes send a limited set of encryption types when making AS requests, it can be important for the krbtgt service to support multiple encryption types. This can be accomplished by giving the krbtgt principal multiple keys, which is usually as simple as not specifying any -e option when changing the krbtgt key, or by setting the session_enctypes string attribute on the krbtgt principal (see set_string).

Due to a bug in releases 1.8 through 1.13, renewed and forwarded tickets may not work if the original ticket was obtained prior to a krbtgt key change and the modified ticket is obtained afterwards. Upgrading the KDC to release 1.14 or later will correct this bug.

Incremental database propagation¶

Overview¶

At some very large sites, dumping and transmitting the database can take more time than is desirable for changes to propagate from the primary KDC to the replica KDCs. The incremental propagation support added in the 1.7 release is intended to address this.

With incremental propagation enabled, all programs on the primary KDC that change the database also write information about the changes to an “update log†file, maintained as a circular buffer of a certain size. A process on each replica KDC connects to a service on the primary KDC (currently implemented in the kadmind server) and periodically requests the changes that have been made since the last check. By default, this check is done every two minutes.

Incremental propagation uses the following entries in the per-realm data in the KDC config file (See kdc.conf):

iprop_enable

boolean

If true, then incremental propagation is enabled, and (as noted below) normal kprop propagation is disabled. The default is false.

iprop_master_ulogsize

integer

Indicates the number of entries that should be retained in the update log. The default is 1000; the maximum number is 2500.

iprop_replica_poll

time interval

Indicates how often the replica should poll the primary KDC for changes to the database. The default is two minutes.

iprop_port

integer

Specifies the port number to be used for incremental propagation. This is required in both primary and replica configuration files.

iprop_resync_timeout

integer

Specifies the number of seconds to wait for a full propagation to complete. This is optional on replica configurations. Defaults to 300 seconds (5 minutes).

iprop_logfile

file name

Specifies where the update log file for the realm database is to be stored. The default is to use the database_name entry from the realms section of the config file kdc.conf, with .ulog appended. (NOTE: If database_name isn’t specified in the realms section, perhaps because the LDAP database back end is being used, or the file name is specified in the dbmodules section, then the hard-coded default for database_name is used. Determination of the iprop_logfile default value will not use values from the dbmodules section.)

Both primary and replica sides must have a principal named kiprop/hostname (where hostname is the lowercase, fully-qualified, canonical name for the host) registered in the Kerberos database, and have keys for that principal stored in the default keytab file (DEFKTNAME). The kiprop/hostname principal may have been created automatically for the primary KDC, but it must always be created for replica KDCs.

On the primary KDC side, the kiprop/hostname principal must be listed in the kadmind ACL file kadm5.acl, and given the p privilege (see Privileges).

On the replica KDC side, kpropd should be run. When incremental propagation is enabled, it will connect to the kadmind on the primary KDC and start requesting updates.

The normal kprop mechanism is disabled by the incremental propagation support. However, if the replica has been unable to fetch changes from the primary KDC for too long (network problems, perhaps), the log on the primary may wrap around and overwrite some of the updates that the replica has not yet retrieved. In this case, the replica will instruct the primary KDC to dump the current database out to a file and invoke a one-time kprop propagation, with special options to also convey the point in the update log at which the replica should resume fetching incremental updates. Thus, all the keytab and ACL setup previously described for kprop propagation is still needed.

If an environment has a large number of replicas, it may be desirable to arrange them in a hierarchy instead of having the primary serve updates to every replica. To do this, run kadmind -proponly on each intermediate replica, and kpropd -A upstreamhostname on downstream replicas to direct each one to the appropriate upstream replica.

There are several known restrictions in the current implementation:

  • The incremental update protocol does not transport changes to policy objects. Any policy changes on the primary will result in full resyncs to all replicas.

  • The replica’s KDB module must support locking; it cannot be using the LDAP KDB module.

  • The primary and replica must be able to initiate TCP connections in both directions, without an intervening NAT.

Sun/MIT incremental propagation differences¶

Sun donated the original code for supporting incremental database propagation to MIT. Some changes have been made in the MIT source tree that will be visible to administrators. (These notes are based on Sun’s patches. Changes to Sun’s implementation since then may not be reflected here.)

The Sun config file support looks for sunw_dbprop_enable, sunw_dbprop_master_ulogsize, and sunw_dbprop_slave_poll.

The incremental propagation service is implemented as an ONC RPC service. In the Sun implementation, the service is registered with rpcbind (also known as portmapper) and the client looks up the port number to contact. In the MIT implementation, where interaction with some modern versions of rpcbind doesn’t always work well, the port number must be specified in the config file on both the primary and replica sides.

The Sun implementation hard-codes pathnames in /var/krb5 for the update log and the per-replica kprop dump files. In the MIT implementation, the pathname for the update log is specified in the config file, and the per-replica dump files are stored in LOCALSTATEDIR/krb5kdc/replica_datatrans_hostname.

krb5-1.22.1/doc/html/admin/host_config.html0000664000175000017500000006133715051422656020353 0ustar ghudsonghudson Host configuration — MIT Kerberos Documentation

Host configuration¶

All hosts running Kerberos software, whether they are clients, application servers, or KDCs, can be configured using krb5.conf. Here we describe some of the behavior changes you might want to make.

Default realm¶

In the [libdefaults] section, the default_realm realm relation sets the default Kerberos realm. For example:

[libdefaults]
    default_realm = ATHENA.MIT.EDU

The default realm affects Kerberos behavior in the following ways:

  • When a principal name is parsed from text, the default realm is used if no @REALM component is specified.

  • The default realm affects login authorization as described below.

  • For programs which operate on a Kerberos database, the default realm is used to determine which database to operate on, unless the -r parameter is given to specify a realm.

  • A server program may use the default realm when looking up its key in a keytab file, if its realm is not determined by [domain_realm] configuration or by the server program itself.

  • If kinit is passed the -n flag, it requests anonymous tickets from the default realm.

In some situations, these uses of the default realm might conflict. For example, it might be desirable for principal name parsing to use one realm by default, but for login authorization to use a second realm. In this situation, the first realm can be configured as the default realm, and auth_to_local relations can be used as described below to use the second realm for login authorization.

Login authorization¶

If a host runs a Kerberos-enabled login service such as OpenSSH with GSSAPIAuthentication enabled, login authorization rules determine whether a Kerberos principal is allowed to access a local account.

By default, a Kerberos principal is allowed access to an account if its realm matches the default realm and its name matches the account name. (For historical reasons, access is also granted by default if the name has two components and the second component matches the default realm; for instance, alice/ATHENA.MIT.EDU@ATHENA.MIT.EDU is granted access to the alice account if ATHENA.MIT.EDU is the default realm.)

The simplest way to control local access is using .k5login files. To use these, place a .k5login file in the home directory of each account listing the principal names which should have login access to that account. If it is not desirable to use .k5login files located in account home directories, the k5login_directory relation in the [libdefaults] section can specify a directory containing one file per account uname.

By default, if a .k5login file is present, it controls authorization both positively and negatively–any principal name contained in the file is granted access and any other principal name is denied access, even if it would have had access if the .k5login file didn’t exist. The k5login_authoritative relation in the [libdefaults] section can be set to false to make .k5login files provide positive authorization only.

The auth_to_local relation in the [realms] section for the default realm can specify pattern-matching rules to control login authorization. For example, the following configuration allows access to principals from a different realm than the default realm:

[realms]
    DEFAULT.REALM = {
        # Allow access to principals from OTHER.REALM.
        #
        # [1:$1@$0] matches single-component principal names and creates
        # a selection string containing the principal name and realm.
        #
        # (.*@OTHER\.REALM) matches against the selection string, so that
        # only principals in OTHER.REALM are matched.
        #
        # s/@OTHER\.REALM$// removes the realm name, leaving behind the
        # principal name as the account name.
        auth_to_local = RULE:[1:$1@$0](.*@OTHER\.REALM)s/@OTHER\.REALM$//

        # Also allow principals from the default realm.  Omit this line
        # to only allow access to principals in OTHER.REALM.
        auth_to_local = DEFAULT
    }

The auth_to_local_names subsection of the [realms] section for the default realm can specify explicit mappings from principal names to local accounts. The key used in this subsection is the principal name without realm, so it is only safe to use in a Kerberos environment with a single realm or a tightly controlled set of realms. An example use of auth_to_local_names might be:

[realms]
    ATHENA.MIT.EDU = {
        auth_to_local_names = {
            # Careful, these match principals in any realm!
            host/example.com = hostaccount
            fred = localfred
        }
    }

Local authorization behavior can also be modified using plugin modules; see Host-to-realm interface (hostrealm) for details.

Plugin module configuration¶

Many aspects of Kerberos behavior, such as client preauthentication and KDC service location, can be modified through the use of plugin modules. For most of these behaviors, you can use the [plugins] section of krb5.conf to register third-party modules, and to switch off registered or built-in modules.

A plugin module takes the form of a Unix shared object (modname.so) or Windows DLL (modname.dll). If you have installed a third-party plugin module and want to register it, you do so using the module relation in the appropriate subsection of the [plugins] section. The value for module must give the module name and the path to the module, separated by a colon. The module name will often be the same as the shared object’s name, but in unusual cases (such as a shared object which implements multiple modules for the same interface) it might not be. For example, to register a client preauthentication module named mypreauth installed at /path/to/mypreauth.so, you could write:

[plugins]
    clpreauth = {
        module = mypreauth:/path/to/mypreauth.so
    }

Many of the pluggable behaviors in MIT krb5 contain built-in modules which can be switched off. You can disable a built-in module (or one you have registered) using the disable directive in the appropriate subsection of the [plugins] section. For example, to disable the use of .k5identity files to select credential caches, you could write:

[plugins]
    ccselect = {
        disable = k5identity
    }

If you want to disable multiple modules, specify the disable directive multiple times, giving one module to disable each time.

Alternatively, you can explicitly specify which modules you want to be enabled for that behavior using the enable_only directive. For example, to make kadmind check password quality using only a module you have registered, and no other mechanism, you could write:

[plugins]
    pwqual = {
        module = mymodule:/path/to/mymodule.so
        enable_only = mymodule
    }

Again, if you want to specify multiple modules, specify the enable_only directive multiple times, giving one module to enable each time.

Some Kerberos interfaces use different mechanisms to register plugin modules.

KDC location modules¶

For historical reasons, modules to control how KDC servers are located are registered simply by placing the shared object or DLL into the “libkrb5†subdirectory of the krb5 plugin directory, which defaults to LIBDIR/krb5/plugins. For example, Samba’s winbind krb5 locator plugin would be registered by placing its shared object in LIBDIR/krb5/plugins/libkrb5/winbind_krb5_locator.so.

GSSAPI mechanism modules¶

GSSAPI mechanism modules are registered using the file SYSCONFDIR/gss/mech or configuration files in the SYSCONFDIR/gss/mech.d directory with a .conf suffix. Each line in these files has the form:

name  oid  pathname  [options]  <type>

Only the name, oid, and pathname are required. name is the mechanism name, which may be used for debugging or logging purposes. oid is the object identifier of the GSSAPI mechanism to be registered. pathname is a path to the module shared object or DLL. options (if present) are options provided to the plugin module, surrounded in square brackets. type (if present) can be used to indicate a special type of module. Currently the only special module type is “interposerâ€, for a module designed to intercept calls to other mechanisms.

If the environment variable GSS_MECH_CONFIG is set, its value is used as the sole mechanism configuration filename.

Configuration profile modules¶

A configuration profile module replaces the information source for krb5.conf itself. To use a profile module, begin krb5.conf with the line:

module PATHNAME:STRING

where PATHNAME is a path to the module shared object or DLL, and STRING is a string to provide to the module. The module will then take over, and the rest of krb5.conf will be ignored.

krb5-1.22.1/doc/html/admin/env_variables.html0000664000175000017500000002001415051422656020654 0ustar ghudsonghudson Environment variables — MIT Kerberos Documentation krb5-1.22.1/doc/html/admin/https.html0000664000175000017500000002710615051422656017207 0ustar ghudsonghudson HTTPS proxy configuration — MIT Kerberos Documentation

HTTPS proxy configuration¶

In addition to being able to use UDP or TCP to communicate directly with a KDC as is outlined in RFC4120, and with kpasswd services in a similar fashion, the client libraries can attempt to use an HTTPS proxy server to communicate with a KDC or kpasswd service, using the protocol outlined in [MS-KKDCP].

Communicating with a KDC through an HTTPS proxy allows clients to contact servers when network firewalls might otherwise prevent them from doing so. The use of TLS also encrypts all traffic between the clients and the KDC, preventing observers from conducting password dictionary attacks or from observing the client and server principals being authenticated, at additional computational cost to both clients and servers.

An HTTPS proxy server is provided as a feature in some versions of Microsoft Windows Server, and a WSGI implementation named kdcproxy is available in the python package index.

Configuring the clients¶

To use an HTTPS proxy, a client host must trust the CA which issued that proxy’s SSL certificate. If that CA’s certificate is not in the system-wide default set of trusted certificates, configure the following relation in the client host’s krb5.conf file in the appropriate [realms] subsection:

http_anchors = FILE:/etc/krb5/cacert.pem

Adjust the pathname to match the path of the file which contains a copy of the CA’s certificate. The http_anchors option is documented more fully in krb5.conf.

Configure the client to access the KDC and kpasswd service by specifying their locations in its krb5.conf file in the form of HTTPS URLs for the proxy server:

kdc = https://server.fqdn/KdcProxy
kpasswd_server = https://server.fqdn/KdcProxy

If the proxy and client are properly configured, client commands such as kinit, kvno, and kpasswd should all function normally.

krb5-1.22.1/doc/html/admin/install_appl_srv.html0000664000175000017500000004316115051422656021420 0ustar ghudsonghudson UNIX Application Servers — MIT Kerberos Documentation

UNIX Application Servers¶

An application server is a host that provides one or more services over the network. Application servers can be “secure†or “insecure.†A “secure†host is set up to require authentication from every client connecting to it. An “insecure†host will still provide Kerberos authentication, but will also allow unauthenticated clients to connect.

If you have Kerberos V5 installed on all of your client machines, MIT recommends that you make your hosts secure, to take advantage of the security that Kerberos authentication affords. However, if you have some clients that do not have Kerberos V5 installed, you can run an insecure server, and still take advantage of Kerberos V5’s single sign-on capability.

The keytab file¶

All Kerberos server machines need a keytab file to authenticate to the KDC. By default on UNIX-like systems this file is named DEFKTNAME. The keytab file is an local copy of the host’s key. The keytab file is a potential point of entry for a break-in, and if compromised, would allow unrestricted access to its host. The keytab file should be readable only by root, and should exist only on the machine’s local disk. The file should not be part of any backup of the machine, unless access to the backup data is secured as tightly as access to the machine’s root password.

In order to generate a keytab for a host, the host must have a principal in the Kerberos database. The procedure for adding hosts to the database is described fully in Principals. (See Create host keytabs for replica KDCs for a brief description.) The keytab is generated by running kadmin and issuing the ktadd command.

For example, to generate a keytab file to allow the host trillium.mit.edu to authenticate for the services host, ftp, and pop, the administrator joeadmin would issue the command (on trillium.mit.edu):

trillium% kadmin
Authenticating as principal root/admin@ATHENA.MIT.EDU with password.
Password for root/admin@ATHENA.MIT.EDU:
kadmin: ktadd host/trillium.mit.edu ftp/trillium.mit.edu pop/trillium.mit.edu
Entry for principal host/trillium.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab.
kadmin: Entry for principal ftp/trillium.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab.
kadmin: Entry for principal pop/trillium.mit.edu@ATHENA.MIT.EDU with kvno 3, encryption type aes256-cts-hmac-sha384-192 added to keytab FILE:/etc/krb5.keytab.
kadmin: quit
trillium%

If you generate the keytab file on another host, you need to get a copy of the keytab file onto the destination host (trillium, in the above example) without sending it unencrypted over the network.

Some advice about secure hosts¶

Kerberos V5 can protect your host from certain types of break-ins, but it is possible to install Kerberos V5 and still leave your host vulnerable to attack. Obviously an installation guide is not the place to try to include an exhaustive list of countermeasures for every possible attack, but it is worth noting some of the larger holes and how to close them.

We recommend that backups of secure machines exclude the keytab file (DEFKTNAME). If this is not possible, the backups should at least be done locally, rather than over a network, and the backup tapes should be physically secured.

The keytab file and any programs run by root, including the Kerberos V5 binaries, should be kept on local disk. The keytab file should be readable only by root.

krb5-1.22.1/doc/html/admin/otp.html0000664000175000017500000003712615051422656016652 0ustar ghudsonghudson OTP Preauthentication — MIT Kerberos Documentation

OTP Preauthentication¶

OTP is a preauthentication mechanism for Kerberos 5 which uses One Time Passwords (OTP) to authenticate the client to the KDC. The OTP is passed to the KDC over an encrypted FAST channel in clear-text. The KDC uses the password along with per-user configuration to proxy the request to a third-party RADIUS system. This enables out-of-the-box compatibility with a large number of already widely deployed proprietary systems.

Additionally, our implementation of the OTP system allows for the passing of RADIUS requests over a UNIX domain stream socket. This permits the use of a local companion daemon which can handle the details of authentication.

Defining token types¶

Token types are defined in either krb5.conf or kdc.conf according to the following format:

[otp]
    <name> = {
        server = <host:port or filename> (default: see below)
        secret = <filename>
        timeout = <integer> (default: 5 [seconds])
        retries = <integer> (default: 3)
        strip_realm = <boolean> (default: true)
        indicator = <string> (default: none)
    }

If the server field begins with ‘/’, it will be interpreted as a UNIX socket. Otherwise, it is assumed to be in the format host:port. When a UNIX domain socket is specified, the secret field is optional and an empty secret is used by default. If the server field is not specified, it defaults to RUNSTATEDIR/krb5kdc/<name>.socket.

When forwarding the request over RADIUS, by default the principal is used in the User-Name attribute of the RADIUS packet. The strip_realm parameter controls whether the principal is forwarded with or without the realm portion.

If an indicator field is present, tickets issued using this token type will be annotated with the specified authentication indicator (see Authentication indicators). This key may be specified multiple times to add multiple indicators.

The default token type¶

A default token type is used internally when no token type is specified for a given user. It is defined as follows:

[otp]
    DEFAULT = {
        strip_realm = false
    }

The administrator may override the internal DEFAULT token type simply by defining a configuration with the same name.

Token instance configuration¶

To enable OTP for a client principal, the administrator must define the otp string attribute for that principal. (See set_string.) The otp user string is a JSON string of the format:

[{
    "type": <string>,
    "username": <string>,
    "indicators": [<string>, ...]
 }, ...]

This is an array of token objects. Both fields of token objects are optional. The type field names the token type of this token; if not specified, it defaults to DEFAULT. The username field specifies the value to be sent in the User-Name RADIUS attribute. If not specified, the principal name is sent, with or without realm as defined in the token type. The indicators field specifies a list of authentication indicators to annotate tickets with, overriding any indicators specified in the token type.

For ease of configuration, an empty array ([]) is treated as equivalent to one DEFAULT token ([{}]).

Other considerations¶

  1. FAST is required for OTP to work.

krb5-1.22.1/doc/html/admin/spake.html0000664000175000017500000002771115051422657017153 0ustar ghudsonghudson SPAKE Preauthentication — MIT Kerberos Documentation

SPAKE Preauthentication¶

SPAKE preauthentication (added in release 1.17) uses public key cryptography techniques to protect against password dictionary attacks. Unlike PKINIT, it does not require any additional infrastructure such as certificates; it simply needs to be turned on. Using SPAKE preauthentication may modestly increase the CPU and network load on the KDC.

SPAKE preauthentication can use one of four elliptic curve groups for its password-authenticated key exchange. The recommended group is edwards25519; three NIST curves (P-256, P-384, and P-521) are also supported.

By default, SPAKE with the edwards25519 group is enabled on clients, but the KDC does not offer SPAKE by default. To turn it on, set the spake_preauth_groups variable in [libdefaults] to a list of allowed groups. This variable affects both the client and the KDC. Simply setting it to edwards25519 is recommended:

[libdefaults]
    spake_preauth_groups = edwards25519

Set the +requires_preauth and -allow_svr flags on client principal entries, as you would for any preauthentication mechanism:

kadmin: modprinc +requires_preauth -allow_svr PRINCNAME

Clients which do not implement SPAKE preauthentication will fall back to encrypted timestamp.

An active attacker can force a fallback to encrypted timestamp by modifying the initial KDC response, defeating the protection against dictionary attacks. To prevent this fallback on clients which do implement SPAKE preauthentication, set the disable_encrypted_timestamp variable to true in the [realms] subsection for realms whose KDCs offer SPAKE preauthentication.

By default, SPAKE preauthentication requires an extra network round trip to the KDC during initial authentication. If most of the clients in a realm support SPAKE, this extra round trip can be eliminated using an optimistic challenge, by setting the spake_preauth_kdc_challenge variable in [kdcdefaults] to a single group name:

[kdcdefaults]
    spake_preauth_kdc_challenge = edwards25519

Using optimistic challenge will cause the KDC to do extra work for initial authentication requests that do not result in SPAKE preauthentication, but will save work when SPAKE preauthentication is used.

krb5-1.22.1/doc/html/genindex-R.html0000664000175000017500000001735115051422714016751 0ustar ghudsonghudson Index — MIT Kerberos Documentation krb5-1.22.1/doc/html/basic/0000775000175000017500000000000015051422713015134 5ustar ghudsonghudsonkrb5-1.22.1/doc/html/basic/ccache_def.html0000664000175000017500000003710415051422713020053 0ustar ghudsonghudson Credential cache — MIT Kerberos Documentation

Credential cache¶

A credential cache (or “ccacheâ€) holds Kerberos credentials while they remain valid and, generally, while the user’s session lasts, so that authenticating to a service multiple times (e.g., connecting to a web or mail server more than once) doesn’t require contacting the KDC every time.

A credential cache usually contains one initial ticket which is obtained using a password or another form of identity verification. If this ticket is a ticket-granting ticket, it can be used to obtain additional credentials without the password. Because the credential cache does not store the password, less long-term damage can be done to the user’s account if the machine is compromised.

A credentials cache stores a default client principal name, set when the cache is created. This is the name shown at the top of the klist -A output.

Each normal cache entry includes a service principal name, a client principal name (which, in some ccache types, need not be the same as the default), lifetime information, and flags, along with the credential itself. There are also other entries, indicated by special names, that store additional information.

ccache types¶

The credential cache interface, like the keytab and replay cache interfaces, uses TYPE:value strings to indicate the type of credential cache and any associated cache naming data to use.

There are several kinds of credentials cache supported in the MIT Kerberos library. Not all are supported on every platform. In most cases, it should be correct to use the default type built into the library.

  1. API is only implemented on Windows. It communicates with a server process that holds the credentials in memory for the user, rather than writing them to disk.

  2. DIR points to the storage location of the collection of the credential caches in FILE: format. It is most useful when dealing with multiple Kerberos realms and KDCs. For release 1.10 the directory must already exist. In post-1.10 releases the requirement is for parent directory to exist and the current process must have permissions to create the directory if it does not exist. See Collections of caches for details. New in release 1.10. The following residual forms are supported:

    • DIR:dirname

    • DIR::dirpath/filename - a single cache within the directory

    Switching to a ccache of the latter type causes it to become the primary for the directory.

  3. FILE caches are the simplest and most portable. A simple flat file format is used to store one credential after another. This is the default ccache type if no type is specified in a ccache name.

  4. KCM caches work by contacting a daemon process called kcm to perform cache operations. If the cache name is just KCM:, the default cache as determined by the KCM daemon will be used. Newly created caches must generally be named KCM:uid:name, where uid is the effective user ID of the running process.

    KCM client support is new in release 1.13. A KCM daemon has not yet been implemented in MIT krb5, but the client will interoperate with the KCM daemon implemented by Heimdal. macOS 10.7 and higher provides a KCM daemon as part of the operating system, and the KCM cache type is used as the default cache on that platform in a default build.

  5. KEYRING is Linux-specific, and uses the kernel keyring support to store credential data in unswappable kernel memory where only the current user should be able to access it. The following residual forms are supported:

    • KEYRING:name

    • KEYRING:process:name - process keyring

    • KEYRING:thread:name - thread keyring

    Starting with release 1.12 the KEYRING type supports collections. The following new residual forms were added:

    • KEYRING:session:name - session keyring

    • KEYRING:user:name - user keyring

    • KEYRING:persistent:uidnumber - persistent per-UID collection. Unlike the user keyring, this collection survives after the user logs out, until the cache credentials expire. This type of ccache requires support from the kernel; otherwise, it will fall back to the user keyring.

    See Collections of caches for details.

  6. MEMORY caches are for storage of credentials that don’t need to be made available outside of the current process. For example, a memory ccache is used by kadmin to store the administrative ticket used to contact the admin server. Memory ccaches are faster than file ccaches and are automatically destroyed when the process exits.

  7. MSLSA is a Windows-specific cache type that accesses the Windows credential store.

Collections of caches¶

Some credential cache types can support collections of multiple caches. One of the caches in the collection is designated as the primary and will be used when the collection is resolved as a cache. When a collection-enabled cache type is the default cache for a process, applications can search the specified collection for a specific client principal, and GSSAPI applications will automatically select between the caches in the collection based on criteria such as the target service realm.

Credential cache collections are new in release 1.10, with support from the DIR and API ccache types. Starting in release 1.12, collections are also supported by the KEYRING ccache type. Collections are supported by the KCM ccache type in release 1.13.

Tool alterations to use cache collection¶

  • kdestroy -A will destroy all caches in the collection.

  • If the default cache type supports switching, kinit princname will search the collection for a matching cache and store credentials there, or will store credentials in a new unique cache of the default type if no existing cache for the principal exists. Either way, kinit will switch to the selected cache.

  • klist -l will list the caches in the collection.

  • klist -A will show the content of all caches in the collection.

  • kswitch -p princname will search the collection for a matching cache and switch to it.

  • kswitch -c cachename will switch to a specified cache.

Default ccache name¶

The default credential cache name is determined by the following, in descending order of priority:

  1. The KRB5CCNAME environment variable. For example, KRB5CCNAME=DIR:/mydir/.

  2. The default_ccache_name profile variable in [libdefaults].

  3. The hardcoded default, DEFCCNAME.

krb5-1.22.1/doc/html/basic/index.html0000664000175000017500000001454615051422713017143 0ustar ghudsonghudson Kerberos V5 concepts — MIT Kerberos Documentation krb5-1.22.1/doc/html/basic/date_format.html0000664000175000017500000003476415051422713020325 0ustar ghudsonghudson Supported date and time formats — MIT Kerberos Documentation

Supported date and time formats¶

Time duration¶

This format is used to express a time duration in the Kerberos configuration files and user commands. The allowed formats are:

Format

Example

Value

h:m[:s]

36:00

36 hours

NdNhNmNs

8h30s

8 hours 30 seconds

N (number of seconds)

3600

1 hour

Here N denotes a number, d - days, h - hours, m - minutes, s - seconds.

Note

The time interval should not exceed 2147483647 seconds.

Examples:

Request a ticket valid for one hour, five hours, 30 minutes
and 10 days respectively:

  kinit -l 3600
  kinit -l 5:00
  kinit -l 30m
  kinit -l "10d 0h 0m 0s"

getdate time¶

Some of the kadmin and kdb5_util commands take a date-time in a human-readable format. Some of the acceptable date-time strings are:

Format

Example

Date

mm/dd/yy

07/27/12

month dd, yyyy

Jul 27, 2012

yyyy-mm-dd

2012-07-27

Absolute time

HH:mm[:ss]pp

08:30 PM

hh:mm[:ss]

20:30

Relative time

N tt

30 sec

Time zone

Z

EST

z

-0400

(See Abbreviations used in this document.)

Examples:

Create a principal that expires on the date indicated:
    addprinc test1 -expire "3/27/12 10:00:07 EST"
    addprinc test2 -expire "January 23, 2015 10:05pm"
    addprinc test3 -expire "22:00 GMT"
Add a principal that will expire in 30 minutes:
    addprinc test4 -expire "30 minutes"

Absolute time¶

This rarely used date-time format can be noted in one of the following ways:

Format

Example

Value

yyyymmddhhmmss

20141231235900

One minute before 2015

yyyy.mm.dd.hh.mm.ss

2014.12.31.23.59.00

yymmddhhmmss

141231235900

yy.mm.dd.hh.mm.ss

14.12.31.23.59.00

dd-month-yyyy:hh:mm:ss

31-Dec-2014:23:59:00

hh:mm:ss

20:00:00

8 o’clock in the evening

hhmmss

200000

(See Abbreviations used in this document.)

Example:

Set the default expiration date to July 27, 2012 at 20:30
default_principal_expiration = 20120727203000

Abbreviations used in this document¶

month : locale’s month name or its abbreviation;
dd : day of month (01-31);
HH : hours (00-12);
hh : hours (00-23);
mm : in time - minutes (00-59); in date - month (01-12);
N : number;
pp : AM or PM;
ss : seconds (00-60);
tt : time units (hours, minutes, min, seconds, sec);
yyyy : year;
yy : last two digits of the year;
Z : alphabetic time zone abbreviation;
z : numeric time zone;

Note

  • If the date specification contains spaces, you may need to enclose it in double quotes;

  • All keywords are case-insensitive.

krb5-1.22.1/doc/html/basic/rcache_def.html0000664000175000017500000003011015051422713020060 0ustar ghudsonghudson replay cache — MIT Kerberos Documentation

replay cache¶

A replay cache (or “rcacheâ€) keeps track of all authenticators recently presented to a service. If a duplicate authentication request is detected in the replay cache, an error message is sent to the application program.

The replay cache interface, like the credential cache and keytab interfaces, uses type:residual strings to indicate the type of replay cache and any associated cache naming data to use.

Background information¶

Some Kerberos or GSSAPI services use a simple authentication mechanism where a message is sent containing an authenticator, which establishes the encryption key that the client will use for talking to the service. But nothing about that prevents an eavesdropper from recording the messages sent by the client, establishing a new connection, and re-sending or “replaying†the same messages; the replayed authenticator will establish the same encryption key for the new session, and the following messages will be decrypted and processed. The attacker may not know what the messages say, and can’t generate new messages under the same encryption key, but in some instances it may be harmful to the user (or helpful to the attacker) to cause the server to see the same messages again a second time. For example, if the legitimate client sends “delete first message in mailboxâ€, a replay from an attacker may delete another, different “first†message. (Protocol design to guard against such problems has been discussed in RFC 4120#section-10.)

Even if one protocol uses further protection to verify that the client side of the connection actually knows the encryption keys (and thus is presumably a legitimate user), if another service uses the same service principal name, it may be possible to record an authenticator used with the first protocol and “replay†it against the second.

The replay cache mitigates these attacks somewhat, by keeping track of authenticators that have been seen until their five-minute window expires. Different authenticators generated by multiple connections from the same legitimate client will generally have different timestamps, and thus will not be considered the same.

This mechanism isn’t perfect. If a message is sent to one application server but a man-in-the-middle attacker can prevent it from actually arriving at that server, the attacker could then use the authenticator (once!) against a different service on the same host. This could be a problem if the message from the client included something more than authentication in the first message that could be useful to the attacker (which is uncommon; in most protocols the server has to indicate a successful authentication before the client sends additional messages), or if the simple act of presenting the authenticator triggers some interesting action in the service being attacked.

Replay cache types¶

Unlike the credential cache and keytab interfaces, replay cache types are in lowercase. The following types are defined:

  1. none disables the replay cache. The residual value is ignored.

  2. file2 (new in release 1.18) uses a hash-based format to store replay records. The file may grow to accommodate hash collisions. The residual value is the filename.

  3. dfl is the default type if no environment variable or configuration specifies a different type. It stores replay data in a file2 replay cache with a filename based on the effective uid. The residual value is ignored.

For the dfl type, the location of the replay cache file is determined as follows:

  1. The directory is taken from the KRB5RCACHEDIR environment variable, or the TMPDIR environment variable, or a temporary directory determined at configuration time such as /var/tmp, in descending order of preference.

  2. The filename is krb5_EUID.rcache2 where EUID is the effective uid of the process.

  3. The file is opened without following symbolic links, and ownership of the file is verified to match the effective uid.

On Windows, the directory for the dfl type is the local appdata directory, unless overridden by the KRB5RCACHEDIR environment variable. The filename on Windows is krb5.rcache2, and the file is opened normally.

Default replay cache name¶

The default replay cache name is determined by the following, in descending order of priority:

  1. The KRB5RCACHENAME environment variable (new in release 1.18).

  2. The KRB5RCACHETYPE environment variable. If this variable is set, the residual value is empty.

  3. The default_rcache_name profile variable in [libdefaults] (new in release 1.18).

  4. If none of the above are set, the default replay cache name is dfl:.

krb5-1.22.1/doc/html/basic/stash_file_def.html0000664000175000017500000001622215051422713020764 0ustar ghudsonghudson stash file — MIT Kerberos Documentation

stash file¶

The stash file is a local copy of the master key that resides in encrypted form on the KDC’s local disk. The stash file is used to authenticate the KDC to itself automatically before starting the kadmind and krb5kdc daemons (e.g., as part of the machine’s boot sequence). The stash file, like the keytab file (see The keytab file) is a potential point-of-entry for a break-in, and if compromised, would allow unrestricted access to the Kerberos database. If you choose to install a stash file, it should be readable only by root, and should exist only on the KDC’s local disk. The file should not be part of any backup of the machine, unless access to the backup data is secured as tightly as access to the master password itself.

Note

If you choose not to install a stash file, the KDC will prompt you for the master key each time it starts up. This means that the KDC will not be able to start automatically, such as after a system reboot.

krb5-1.22.1/doc/html/basic/keytab_def.html0000664000175000017500000002335715051422713020131 0ustar ghudsonghudson keytab — MIT Kerberos Documentation

keytab¶

A keytab (short for “key tableâ€) stores long-term keys for one or more principals. Keytabs are normally represented by files in a standard format, although in rare cases they can be represented in other ways. Keytabs are used most often to allow server applications to accept authentications from clients, but can also be used to obtain initial credentials for client applications.

Keytabs are named using the format type:value. Usually type is FILE and value is the absolute pathname of the file. The other possible value for type is MEMORY, which indicates a temporary keytab stored in the memory of the current process.

A keytab contains one or more entries, where each entry consists of a timestamp (indicating when the entry was written to the keytab), a principal name, a key version number, an encryption type, and the encryption key itself.

A keytab can be displayed using the klist command with the -k option. Keytabs can be created or appended to by extracting keys from the KDC database using the kadmin ktadd command. Keytabs can be manipulated using the ktutil and k5srvutil commands.

Default keytab¶

The default keytab is used by server applications if the application does not request a specific keytab. The name of the default keytab is determined by the following, in decreasing order of preference:

  1. The KRB5_KTNAME environment variable.

  2. The default_keytab_name profile variable in [libdefaults].

  3. The hardcoded default, DEFKTNAME.

Default client keytab¶

The default client keytab is used, if it is present and readable, to automatically obtain initial credentials for GSSAPI client applications. The principal name of the first entry in the client keytab is used by default when obtaining initial credentials. The name of the default client keytab is determined by the following, in decreasing order of preference:

  1. The KRB5_CLIENT_KTNAME environment variable.

  2. The default_client_keytab_name profile variable in [libdefaults].

  3. The hardcoded default, DEFCKTNAME.

krb5-1.22.1/README0000664000175000017500000003702615051422640013231 0ustar ghudsonghudson Kerberos Version 5, Release 1.22 Release Notes The MIT Kerberos Team Copyright and Other Notices --------------------------- Copyright (C) 1985-2025 by the Massachusetts Institute of Technology and its contributors. All rights reserved. Please see the file named NOTICE for additional notices. Documentation ------------- Unified documentation for Kerberos V5 is available in both HTML and PDF formats. The table of contents of the HTML format documentation is at doc/html/index.html, and the PDF format documentation is in the doc/pdf directory. Additionally, you may find copies of the HTML format documentation online at https://web.mit.edu/kerberos/krb5-latest/doc/ for the most recent supported release, or at https://web.mit.edu/kerberos/krb5-devel/doc/ for the release under development. More information about Kerberos may be found at https://web.mit.edu/kerberos/ and at the MIT Kerberos Consortium web site https://kerberos.org/ Building and Installing Kerberos 5 ---------------------------------- Build documentation is in doc/html/build/index.html or doc/pdf/build.pdf. The installation guide is in doc/html/admin/install.html or doc/pdf/install.pdf. If you are attempting to build under Windows, please see the src/windows/README file. Reporting Bugs -------------- Please report any problems/bugs/comments by sending email to krb5-bugs@mit.edu. You may view bug reports by visiting https://krbdev.mit.edu/rt/ and using the "Guest Login" button. Please note that the web interface to our bug database is read-only for guests, and the primary way to interact with our bug database is via email. PAC transitions --------------- Beginning with release 1.20, the KDC will include minimal PACs in tickets instead of AD-SIGNEDPATH authdata. S4U requests (protocol transition and constrained delegation) must now contain valid PACs in the incoming tickets. Beginning with release 1.21, service ticket PACs will contain a new KDC checksum buffer, to mitigate a hash collision attack against the old KDC checksum. If only some KDCs in a realm have been upgraded across versions 1.20 or 1.21, the upgraded KDCs will reject S4U requests containing tickets from non-upgraded KDCs and vice versa. Triple-DES and RC4 transitions ------------------------------ Beginning with the krb5-1.21 release, the KDC will not issue tickets with triple-DES or RC4 session keys unless explicitly configured using the new allow_des3 and allow_rc4 variables in [libdefaults]. To facilitate the negotiation of session keys, the KDC will assume that all services can handle aes256-sha1 session keys unless the service principal has a session_enctypes string attribute. Beginning with the krb5-1.19 release, a warning will be issued if initial credentials are acquired using the des3-cbc-sha1 encryption type. Beginning with the krb5-1.21 release, a warning will also be issued for the arcfour-hmac encryption type. In future releases, these encryption types will be disabled by default and eventually removed. Beginning with the krb5-1.18 release, all support for single-DES encryption types has been removed. Major changes in 1.22.1 (2025-08-20) ------------------------------------ This is a bug fix release. * Fix a vulnerability in GSS MIC verification [CVE-2025-57736]. krb5-1.22.1 changes by ticket ID -------------------------------- 9181 verify_mic_v3 broken in 1.22 Major changes in 1.22 (2025-08-05) ---------------------------------- User experience: * The libdefaults configuration variable "request_timeout" can be set to limit the total timeout for KDC requests. When making a KDC request, the client will now wait indefinitely (or until the request timeout has elapsed) on a KDC which accepts a TCP connection, without contacting any additional KDCs. Clients will make fewer DNS queries in some configurations. * The realm configuration variable "sitename" can be set to cause the client to query site-specific DNS records when making KDC requests. Administrator experience: * Principal aliases are supported in the DB2 and LMDB KDB modules and in the kadmin protocol. (The LDAP KDB module has supported aliases since release 1.7.) * UNIX domain sockets are supported for the Kerberos and kpasswd protocols. * systemd socket activation is supported for krb5kdc and kadmind. Developer experience: * KDB modules can be be implemented in terms of other modules using the new krb5_db_load_module() function. * The profile library supports the modification of empty profiles and the copying of modified profiles, making it possible to construct an in-memory profile and pass it to krb5_init_context_profile(). * GSS-API applications can pass the GSS_C_CHANNEL_BOUND flag to gss_init_sec_context() to request strict enforcement of channel bindings by the acceptor. Protocol evolution: * The PKINIT preauth module supports elliptic curve client certificates, ECDH key exchange, and the Microsoft paChecksum2 field. * The IAKERB implementation has been changed to comply with the most recent draft standard and to support realm discovery. * Message-Authenticator is supported in the RADIUS implementation used by the OTP kdcpreauth module. Code quality: * Removed old-style function declarations, to accomodate compilers which have removed support for them. * Added OSS-Fuzz to the project's continuous integration infrastructure. * Rewrote the GSS per-message token parsing code for improved safety. krb5-1.22 changes by ticket ID ------------------------------ 7721 Primary KDC lookups happen sooner than necessary 7899 Client waits before moving on after KDC_ERR_SVC_UNAVAILABLE 8618 ksu doesn't exit nonzero 9094 Get arm64-windows builds working 9095 PKINIT ECDH support 9096 Enable PKINIT if at least one group is available 9100 Add ecdsa-with-sha512/256 to supportedCMSTypes 9105 Wait indefinitely on KDC TCP connections 9106 Add request_timeout configuration parameter 9108 Remove PKINIT RSA support 9110 profile library null dereference when modifying empty profile 9111 Correct PKINIT EC cert signature metadata 9112 Support PKCS11 EC client certs in PKINIT 9113 Improve PKCS11 error reporting in PKINIT 9114 Build fails with link-time optimization 9116 Improve error message for DES kadmin/history key 9118 profile write operation interactions with reloading 9119 Make profile_copy() work on dirty profiles 9120 profile final flag limitations 9121 Don't flush libkrb5 context profiles 9122 Add GSS flag to include KERB_AP_OPTIONS_CBT 9123 Correct IAKERB protocol implementation 9124 Support site-local KDC discovery via DNS 9126 Handle empty initial buffer in IAKERB initiator 9130 make krb5_get_default_config_files public 9131 Adjust removed cred detection in FILE ccache 9132 Change krb5_get_credentials() endtime behavior 9133 Add acceptor-side IAKERB realm discovery 9135 Replace Windows installer FilesInUse dialog text 9139 Block library unloading to avoid finalizer races 9141 Fix krb5_crypto_us_timeofday() microseconds check 9142 Generate and verify message MACs in libkrad 9143 Fix memory leak in PAC checksum verification 9144 Fix potential PAC processing crash 9145 Prevent late initialization of GSS error map 9146 Allow null keyblocks in IOV checksum functions 9147 Add numeric constants to krad.h and use them 9148 Fix krb5_ldap_list_policy() filtering loop 9149 Use getentropy() when available 9151 Add kadmind support for disabling listening 9152 Default kdc_tcp_listen to kdc_listen value 9153 Fix LDAP module leak on authentication error 9154 Components of the X509_user_identity string cannot contain ':' 9155 UNIX domain socket support 9156 Allow KDB module stacking 9157 Add support for systemd socket activation 9158 Set missing mask flags for kdb5_util operations 9159 Prevent overflow when calculating ulog block size 9160 Allow only one salt type per enctype in key data 9161 Improve ulog block resize efficiency 9162 Build PKINIT on Windows 9163 Add alias support 9164 Add database format documentation 9165 Display NetBIOS ticket addresses in klist 9166 Add PKINIT paChecksum2 from MS-PKCA v20230920 9167 Add initiator-side IAKERB realm discovery 9168 Fix IAKERB accept_sec_context null pointer crash 9169 Fix IAKERB error handling 9170 Avoid gss_inquire_attrs_for_mech() null outputs 9171 Fix getsockname() call in Windows localaddr 9172 Check lengths in xdr_krb5_key_data() 9173 Limit -keepold for self-service key changes 9179 Avoid large numbers of refresh_time cache entries Acknowledgements ---------------- Past Sponsors of the MIT Kerberos Consortium: Apple Carnegie Mellon University Centrify Corporation Columbia University Cornell University The Department of Defense of the United States of America (DoD) Fidelity Investments Google Iowa State University MIT Michigan State University Microsoft MITRE Corporation Morgan-Stanley The National Aeronautics and Space Administration of the United States of America (NASA) Network Appliance (NetApp) Nippon Telephone and Telegraph (NTT) US Government Office of the National Coordinator for Health Information Technology (ONC) Oracle Pennsylvania State University Red Hat Stanford University TeamF1, Inc. The University of Alaska The University of Michigan The University of Pennsylvania Past and present members of the Kerberos Team at MIT: Danilo Almeida Jeffrey Altman Justin Anderson Richard Basch Mitch Berger Jay Berkenbilt Andrew Boardman Bill Bryant Steve Buckley Joe Calzaretta John Carr Mark Colan Don Davis Sarah Day Alexandra Ellwood Carlos Garay Dan Geer Nancy Gilman Matt Hancher Thomas Hardjono Sam Hartman Paul Hill Marc Horowitz Eva Jacobus Miroslav Jurisic Barry Jaspan Benjamin Kaduk Geoffrey King Kevin Koch John Kohl HaoQi Li Jonathan Lin Peter Litwack Scott McGuire Steve Miller Kevin Mitchell Cliff Neuman Paul Park Ezra Peisach Chris Provenzano Ken Raeburn Jon Rochlis Jeff Schiller Jen Selby Robert Silk Bill Sommerfeld Jennifer Steiner Ralph Swick Brad Thompson Harry Tsai Zhanna Tsitkova Ted Ts'o Marshall Vale Taylor Yu The following external contributors have provided code, patches, bug reports, suggestions, and valuable resources: Ian Abbott Daniel Albers Brandon Allbery Russell Allbery Brian Almeida Michael B Allen Pooja Anil Jeffrey Arbuckle Heinz-Ado Arnolds Derek Atkins Mark Bannister David Bantz Alex Baule Nikhil Benesch David Benjamin Thomas Bernard Adam Bernstein Arlene Berry Jeff Blaine Toby Blake Radoslav Bodo Alexander Bokovoy Zoltan Borbely Sumit Bose Emmanuel Bouillon Isaac Boukris Ulf Bremer Pavel BÅ™ezina Philip Brown Samuel Cabrero Michael Calmer Andrea Campi Julien Chaffraix Jacob Champion Puran Chand Ravi Channavajhala Srinivas Cheruku Leonardo Chiquitto Rachit Chokshi Seemant Choudhary Howard Chu Andrea Cirulli Christopher D. Clausen Kevin Coffman Gerald Combs Simon Cooper Sylvain Cortes Ian Crowther Arran Cudbard-Bell Adam Dabrowski Jeff D'Angelo Nalin Dahyabhai Mark Davies Dennis Davis Rull Deef Alex Dehnert Misty De Meo Mark Deneen Günther Deschner John Devitofranceschi Marc Dionne Roland Dowdeswell Ken Dreyer Dorian Ducournau Francis Dupont Viktor Dukhovni Jason Edgecombe Mark Eichin Shawn M. Emery Douglas E. Engert Peter Eriksson Juha Erkkilä Gilles Espinasse Valery Fedorenko Sergey Fedorov Ronni Feldt Bill Fellows JC Ferguson Remi Ferrand Paul Fertser Fabiano Fidêncio Frank Filz William Fiveash Jacques Florent Oliver Freyermuth Ãkos Frohner Sebastian Galiano Ilya Gladyshev Marcus Granado Dylan Gray Norm Green Scott Grizzard Helmut Grohne Steve Grubb Philip Guenther Feng Guo Timo Gurr Dominic Hargreaves Robbie Harwood John Hascall Jakob Haufe Matthieu Hautreux Jochen Hein Paul B. Henson Kihong Heo Jeff Hodges Christopher Hogan Love Hörnquist Ã…strand Ken Hornstein Henry B. Hotz Luke Howard Jakub Hrozek Shumon Huque Jeffrey Hutzelman Sergey Ilinykh Wyllys Ingersoll Holger Isenberg Spencer Jackson Diogenes S. Jesus Mike Jetzer Pavel Jindra Brian Johannesmeyer Joel Johnson Lutz Justen Ganesh Kamath Alexander Karaivanov Anders Kaseorg Bar Katz Zentaro Kavanagh Mubashir Kazia W. Trevor King Steffen Kieß Patrik Kis Martin Kittel Thomas Klausner Tomasz KÅ‚oczko Ivan Korytov Matthew Krupcale Mikkel Kruse Reinhard Kugler Harshawardhan Kulkarni Tomas Kuthan Pierre Labastie Andreas Ladanyi Chris Leick Volker Lendecke Jan iankko Lieskovsky Todd Lipcon Oliver Loch Chris Long Kevin Longfellow Frank Lonigro Jon Looney Nuno Lopes Todd Lubin Ryan Lynch Glenn Machin Roland Mainz Sorin Manolache Robert Marshall Andrei Maslennikov Michael Mattioli Nathaniel McCallum Greg McClement Cameron Meadors Vipul Mehta Alexey Melnikov Ivan A. Melnikov Franklyn Mendez Stefan Metzmacher Mantas MikulÄ—nas Markus Moeller Kyle Moffett Jon Moore Paul Moore Keiichi Mori Michael Morony Robert Morris Sam Morris Zbysek Mraz Edward Murrell Bahaa Naamneh Joshua Neuheisel Nikos Nikoleris Demi Obenour Felipe Ortega Michael Osipov Andrej Ota Dmitri Pal Javier Palacios Dilyan Palauzov Tom Parker Eric Pauly Leonard Peirce Ezra Peisach Alejandro Perez Zoran Pericic W. Michael Petullo Mark Phalan Sharwan Ram Brett Randall Jonathan Reams Jonathan Reed Robert Relyea Tony Reix Martin Rex Pat Riehecky Julien Rische Jason Rogers Matt Rogers Nate Rosenblum Solly Ross Mike Roszkowski Guillaume Rousse Joshua Schaeffer Alexander Scheel Jens Schleusener Ryan Schmidt Andreas Schneider Eli Schwartz Paul Seyfert Tom Shaw Jim Shi Jerry Shipman Peter Shoults Richard Silverman Cel Skeggs Simo Sorce Anthony Sottile Michael Spang Michael Ströder Bjørn Tore Sund OndÅ™ej Surý Joseph Sutton Alexey Tikhonov Joe Travaglini Sergei Trofimovich Greg Troxel Fraser Tweedale Tim Uglow Rathor Vipin Denis Vlasenko Thomas Wagner Jorgen Wahlsten Stef Walter Max (Weijun) Wang John Washington Stef Walter Xi Wang Nehal J Wani Kevin Wasserman Margaret Wasserman Marcus Watts Andreas Wiese Simon Wilkinson Nicolas Williams Ross Wilper Augustin Wolf Garrett Wollman David Woodhouse Tsu-Phong Wu Xu Qiang Neng Xue Zhaomo Yang Tianjiao Yin Nickolai Zeldovich Bean Zhang ChenChen Zhou Hanz van Zijst Gertjan Zwartjes The above is not an exhaustive list; many others have contributed in various ways to the MIT Kerberos development effort over the years. krb5-1.22.1/NOTICE0000664000175000017500000017431215051422640013255 0ustar ghudsonghudsonCopyright (C) 1985-2025 by the Massachusetts Institute of Technology. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Downloading of this software may constitute an export of cryptographic software from the United States of America that is subject to the United States Export Administration Regulations (EAR), 15 CFR 730-774. Additional laws or regulations may apply. It is the responsibility of the person or entity contemplating export to comply with all applicable export laws and regulations, including obtaining any required license from the U.S. government. The U.S. government prohibits export of encryption source code to certain countries and individuals, including, but not limited to, the countries of Cuba, Iran, North Korea, Sudan, Syria, and residents and nationals of those countries. Documentation components of this software distribution are licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. (https://creativecommons.org/licenses/by-sa/3.0/) Individual source code files are copyright MIT, Cygnus Support, Novell, OpenVision Technologies, Oracle, Red Hat, Sun Microsystems, FundsXpress, and others. Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, and Zephyr are trademarks of the Massachusetts Institute of Technology (MIT). No commercial use of these trademarks may be made without prior written permission of MIT. "Commercial use" means use of a name in a product or other for-profit manner. It does NOT prevent a commercial firm from referring to the MIT trademarks in order to convey information (although in doing so, recognition of their trademark status should be given). ====================================================================== The following copyright and permission notice applies to the OpenVision Kerberos Administration system located in "kadmin/create", "kadmin/dbutil", "kadmin/passwd", "kadmin/server", "lib/kadm5", and portions of "lib/rpc": Copyright, OpenVision Technologies, Inc., 1993-1996, All Rights Reserved WARNING: Retrieving the OpenVision Kerberos Administration system source code, as described below, indicates your acceptance of the following terms. If you do not agree to the following terms, do not retrieve the OpenVision Kerberos administration system. You may freely use and distribute the Source Code and Object Code compiled from it, with or without modification, but this Source Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY, INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY OTHER REASON. OpenVision retains all copyrights in the donated Source Code. OpenVision also retains copyright to derivative works of the Source Code, whether created by OpenVision or by a third party. The OpenVision copyright notice must be preserved if derivative works are made based on the donated Source Code. OpenVision Technologies, Inc. has donated this Kerberos Administration system to MIT for inclusion in the standard Kerberos 5 distribution. This donation underscores our commitment to continuing Kerberos technology development and our gratitude for the valuable work which has been performed by MIT and the Kerberos community. ====================================================================== Portions contributed by Matt Crawford "crawdad@fnal.gov" were work performed at Fermi National Accelerator Laboratory, which is operated by Universities Research Association, Inc., under contract DE-AC02-76CHO3000 with the U.S. Department of Energy. ====================================================================== Portions of "src/lib/crypto" have the following copyright: Copyright (C) 1998 by the FundsXpress, INC. All rights reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of FundsXpress. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. FundsXpress makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ====================================================================== The implementation of the AES encryption algorithm in "src/lib/crypto/builtin/aes" has the following copyright: Copyright (C) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. ====================================================================== Portions contributed by Red Hat, including the pre-authentication plug-in framework and the NSS crypto implementation, contain the following copyright: Copyright (C) 2006 Red Hat, Inc. Portions copyright (C) 2006 Massachusetts Institute of Technology All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Red Hat, Inc., nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== The bundled verto source code is subject to the following license: Copyright 2011 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ====================================================================== The MS-KKDCP client implementation has the following copyright: Copyright 2013,2014 Red Hat, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== The implementations of GSSAPI mechglue in GSSAPI-SPNEGO in "src/lib/gssapi", including the following files: lib/gssapi/generic/gssapi_err_generic.et lib/gssapi/mechglue/g_accept_sec_context.c lib/gssapi/mechglue/g_acquire_cred.c lib/gssapi/mechglue/g_canon_name.c lib/gssapi/mechglue/g_compare_name.c lib/gssapi/mechglue/g_context_time.c lib/gssapi/mechglue/g_delete_sec_context.c lib/gssapi/mechglue/g_dsp_name.c lib/gssapi/mechglue/g_dsp_status.c lib/gssapi/mechglue/g_dup_name.c lib/gssapi/mechglue/g_exp_sec_context.c lib/gssapi/mechglue/g_export_name.c lib/gssapi/mechglue/g_glue.c lib/gssapi/mechglue/g_imp_name.c lib/gssapi/mechglue/g_imp_sec_context.c lib/gssapi/mechglue/g_init_sec_context.c lib/gssapi/mechglue/g_initialize.c lib/gssapi/mechglue/g_inquire_context.c lib/gssapi/mechglue/g_inquire_cred.c lib/gssapi/mechglue/g_inquire_names.c lib/gssapi/mechglue/g_process_context.c lib/gssapi/mechglue/g_rel_buffer.c lib/gssapi/mechglue/g_rel_cred.c lib/gssapi/mechglue/g_rel_name.c lib/gssapi/mechglue/g_rel_oid_set.c lib/gssapi/mechglue/g_seal.c lib/gssapi/mechglue/g_sign.c lib/gssapi/mechglue/g_store_cred.c lib/gssapi/mechglue/g_unseal.c lib/gssapi/mechglue/g_userok.c lib/gssapi/mechglue/g_utils.c lib/gssapi/mechglue/g_verify.c lib/gssapi/mechglue/gssd_pname_to_uid.c lib/gssapi/mechglue/mglueP.h lib/gssapi/mechglue/oid_ops.c lib/gssapi/spnego/gssapiP_spnego.h lib/gssapi/spnego/spnego_mech.c and the initial implementation of incremental propagation, including the following new or changed files: include/iprop_hdr.h kadmin/server/ipropd_svc.c lib/kdb/iprop.x lib/kdb/kdb_convert.c lib/kdb/kdb_log.c lib/kdb/kdb_log.h lib/krb5/error_tables/kdb5_err.et kprop/kpropd_rpc.c kprop/kproplog.c are subject to the following license: Copyright (C) 2004 Sun Microsystems, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ====================================================================== Kerberos V5 includes documentation and software developed at the University of California at Berkeley, which includes this copyright notice: Copyright (C) 1983 Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Portions contributed by Novell, Inc., including the LDAP database backend, are subject to the following license: Copyright (C) 2004-2005, Novell, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The copyright holder's name is not used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Portions funded by Sandia National Laboratory and developed by the University of Michigan's Center for Information Technology Integration, including the PKINIT implementation, are subject to the following license: COPYRIGHT (C) 2006-2007 THE REGENTS OF THE UNIVERSITY OF MICHIGAN ALL RIGHTS RESERVED Permission is granted to use, copy, create derivative works and redistribute this software and such derivative works for any purpose, so long as the name of The University of Michigan is not used in any advertising or publicity pertaining to the use of distribution of this software without specific, written prior authorization. If the above copyright notice or any other identification of the University of Michigan is included in any copy of any portion of this software, then the disclaimer below must also be included. THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ====================================================================== The pkcs11.h file included in the PKINIT code has the following license: Copyright 2006 g10 Code GmbH Copyright 2006 Andreas Jellinghaus This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ====================================================================== Portions contributed by Apple Inc. are subject to the following license: Copyright 2004-2008 Apple Inc. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Apple Inc. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Apple Inc. makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ====================================================================== The implementations of UTF-8 string handling in src/util/support and src/lib/krb5/unicode are subject to the following copyright and permission notice: The OpenLDAP Public License Version 2.8, 17 August 2003 Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met: 1. Redistributions in source form must retain copyright statements and notices, 2. Redistributions in binary form must reproduce applicable copyright statements and notices, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution, and 3. Redistributions must contain a verbatim copy of this document. The OpenLDAP Foundation may revise this license from time to time. Each revision is distinguished by a version number. You may use this Software under terms of this license revision or under the terms of any subsequent revision of the license. THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S) OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The names of the authors and copyright holders must not be used in advertising or otherwise to promote the sale, use or other dealing in this Software without specific, written prior permission. Title to copyright in this Software shall at all times remain with copyright holders. OpenLDAP is a registered trademark of the OpenLDAP Foundation. Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, California, USA. All Rights Reserved. Permission to copy and distribute verbatim copies of this document is granted. ====================================================================== Marked test programs in src/lib/krb5/krb have the following copyright: Copyright (C) 2006 Kungliga Tekniska Högskola (Royal Institute of Technology, Stockholm, Sweden). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of KTH nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== The KCM Mach RPC definition file used on macOS has the following copyright: Copyright (C) 2009 Kungliga Tekniska Högskola (Royal Institute of Technology, Stockholm, Sweden). All rights reserved. Portions Copyright (C) 2009 Apple Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Portions of the RPC implementation in src/lib/rpc and src/include/gssrpc have the following copyright and permission notice: Copyright (C) 2010, Oracle America, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the "Oracle America, Inc." nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Copyright (C) 2006,2007,2009 NTT (Nippon Telegraph and Telephone Corporation). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer as the first lines of this file unmodified. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY NTT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Copyright 2000 by Carnegie Mellon University All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Carnegie Mellon University not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ====================================================================== Copyright (C) 2002 Naval Research Laboratory (NRL/CCS) Permission to use, copy, modify and distribute this software and its documentation is hereby granted, provided that both the copyright notice and this permission notice appear in all copies of the software, derivative works or modified versions, and any portions thereof. NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ====================================================================== Copyright (C) 2022 United States Government as represented by the Secretary of the Navy. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Copyright (C) 1991, 1992, 1994 by Cygnus Support. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Cygnus Support makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ====================================================================== Copyright (C) 2006 Secure Endpoints Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ====================================================================== Copyright (C) 1994 by the University of Southern California EXPORT OF THIS SOFTWARE from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute this software and its documentation in source and binary forms is hereby granted, provided that any documentation or other materials related to such distribution or use acknowledge that the software was developed by the University of Southern California. DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The University of Southern California MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not limitation, the University of Southern California MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. The University of Southern California shall not be held liable for any liability nor for any direct, indirect, or consequential damages with respect to any claim by the user or distributor of the ksu software. ====================================================================== Copyright (C) 1995 The President and Fellows of Harvard University This code is derived from software contributed to Harvard by Jeremy Rassen. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the University of California, Berkeley and its contributors. 4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Copyright (C) 2008 by the Massachusetts Institute of Technology. Copyright 1995 by Richard P. Basch. All Rights Reserved. Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Richard P. Basch, Lehman Brothers and M.I.T. make no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ====================================================================== The following notice applies to "src/lib/krb5/krb/strptime.c" and "src/include/k5-queue.h". Copyright (C) 1997, 1998 The NetBSD Foundation, Inc. All rights reserved. This code was contributed to The NetBSD Foundation by Klaus Klein. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the NetBSD Foundation, Inc. and its contributors. 4. Neither the name of The NetBSD Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== The following notice applies to Unicode library files in "src/lib/krb5/unicode": Copyright 1997, 1998, 1999 Computing Research Labs, New Mexico State University Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ====================================================================== The following notice applies to "src/util/support/strlcpy.c": Copyright (C) 1998 Todd C. Miller "Todd.Miller@courtesan.com" Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ====================================================================== The following notice applies to "src/util/profile/argv_parse.c" and "src/util/profile/argv_parse.h": Copyright 1999 by Theodore Ts'o. Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't it sick that the U.S. culture of lawsuit-happy lawyers requires this kind of disclaimer?) ====================================================================== The following notice applies to portiions of "src/lib/rpc" and "src/include/gssrpc": Copyright (C) 2000 The Regents of the University of Michigan. All rights reserved. Copyright (C) 2000 Dug Song "dugsong@UMICH.EDU". All rights reserved, all wrongs reversed. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== Implementations of the MD4 algorithm are subject to the following notice: Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD4 Message Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD4 Message Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. ====================================================================== Implementations of the MD5 algorithm are subject to the following notice: Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message- Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. ====================================================================== The following notice applies to "src/lib/crypto/crypto_tests/t_mddriver.c": Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All rights reserved. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. ====================================================================== Portions of "src/lib/krb5" are subject to the following notice: Copyright (C) 1994 CyberSAFE Corporation. Copyright 1990,1991,2007,2008 by the Massachusetts Institute of Technology. All Rights Reserved. Export of this software from the United States of America may require a specific license from the United States Government. It is the responsibility of any person or organization contemplating export to obtain such a license before exporting. WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of M.I.T. not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Furthermore if you modify this software you must label your software as modified software and not distribute it in such a fashion that it might be confused with the original M.I.T. software. Neither M.I.T., the Open Computing Security Group, nor CyberSAFE Corporation make any representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ====================================================================== Portions contributed by PADL Software are subject to the following license: Copyright (c) 2011, PADL Software Pty Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of PADL Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== The bundled libev source code is subject to the following license: All files in libev are Copyright (C)2007,2008,2009 Marc Alexander Lehmann. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Alternatively, the contents of this package may be used under the terms of the GNU General Public License ("GPL") version 2 or any later version, in which case the provisions of the GPL are applicable instead of the above. If you wish to allow the use of your version of this package only under the terms of the GPL and not to allow others to use your version of this file under the BSD license, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL in this and the other files of this package. If you do not delete the provisions above, a recipient may use your version of this file under either the BSD or the GPL. ====================================================================== Files copied from the Intel AESNI Sample Library are subject to the following license: Copyright (C) 2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== The following notice applies to "src/ccapi/common/win/OldCC/autolock.hxx": Copyright (C) 1998 by Danilo Almeida. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ====================================================================== The following notice applies to portions of "src/plugins/preauth/spake/edwards25519.c" and "src/plugins/preauth/spake/edwards25519_tables.h": The MIT License (MIT) Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ====================================================================== The following notice applies to portions of "src/plugins/preauth/spake/edwards25519.c": Copyright (c) 2015-2016, Google Inc. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ====================================================================== The following notice applies to files in "src/tests/fuzzing": Copyright (C) 2024 by Arjun. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. krb5-1.22.1/src/0000775000175000017500000000000015051422641013131 5ustar ghudsonghudsonkrb5-1.22.1/src/build-tools/0000775000175000017500000000000015051422640015365 5ustar ghudsonghudsonkrb5-1.22.1/src/build-tools/Makefile.in0000664000175000017500000000306415051422640017435 0ustar ghudsonghudsonmydir=build-tools BUILDTOP=$(REL).. PKGCONFIG_FILES = \ kadm-client.pc \ kadm-server.pc \ kdb.pc \ mit-krb5.pc \ krb5.pc \ mit-krb5-gssapi.pc \ krb5-gssapi.pc \ gssrpc.pc all-unix: krb5-config $(PKGCONFIG_FILES) krb5-config $(PKGCONFIG_FILES): $(BUILDTOP)/config.status (cd $(BUILDTOP) && $(SHELL) config.status $(mydir)/$@) krb5-config: $(srcdir)/krb5-config.in kadm-client.pc: $(srcdir)/kadm-client.pc.in kadm-server.pc: $(srcdir)/kadm-server.pc.in kdb.pc: $(srcdir)/kdb.pc.in mit-krb5.pc: $(srcdir)/mit-krb5.pc.in krb5.pc: $(srcdir)/krb5.pc.in mit-krb5-gssapi.pc: $(srcdir)/mit-krb5-gssapi.pc.in krb5-gssapi.pc: $(srcdir)/krb5-gssapi.pc.in gssrpc.pc: $(srcdir)/gssrpc.pc.in install-unix: $(INSTALL_SCRIPT) krb5-config $(DESTDIR)$(CLIENT_BINDIR)/krb5-config $(INSTALL_DATA) kadm-client.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/kadm-client.pc $(INSTALL_DATA) kadm-server.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/kadm-server.pc $(INSTALL_DATA) kdb.pc $(DESTDIR)$(PKGCONFIG_DIR)/kdb.pc $(INSTALL_DATA) mit-krb5.pc $(DESTDIR)$(PKGCONFIG_DIR)/mit-krb5.pc $(INSTALL_DATA) krb5.pc $(DESTDIR)$(PKGCONFIG_DIR)/krb5.pc $(INSTALL_DATA) mit-krb5-gssapi.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/mit-krb5-gssapi.pc $(INSTALL_DATA) krb5-gssapi.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/krb5-gssapi.pc $(INSTALL_DATA) gssrpc.pc \ $(DESTDIR)$(PKGCONFIG_DIR)/gssrpc.pc # Test to ensure that krb5-config does not spit out things like # $(PURE) or $(LDFLAGS) in case someone changes config/shlib.conf check-unix: krb5-config $(SHELL) $(srcdir)/t_krbconf distclean-unix: $(RM) $(PKGCONFIG_FILES) krb5-config krb5-1.22.1/src/build-tools/krb5-config.in0000775000175000017500000001474115051422640020035 0ustar ghudsonghudson#!/bin/sh # Copyright 2001, 2002, 2003 by the Massachusetts Institute of Technology. # All Rights Reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. # # # Configurable parameters set by autoconf version_string="Kerberos 5 release @KRB5_VERSION@" prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ CC_LINK='@CC_LINK@' KDB5_DB_LIB=@KDB5_DB_LIB@ RPATH_FLAG='@RPATH_FLAG@' PROG_RPATH_FLAGS='@PROG_RPATH_FLAGS@' PTHREAD_CFLAGS='@PTHREAD_CFLAGS@' DL_LIB='@DL_LIB@' DEFCCNAME='@DEFCCNAME@' DEFKTNAME='@DEFKTNAME@' DEFCKTNAME='@DEFCKTNAME@' LIBS='@LIBS@' # Defaults for program library=krb5 # Some constants vendor_string="Massachusetts Institute of Technology" # Process arguments # Yes, we are sloppy, library specifications can come before options while test $# != 0; do case $1 in --all) do_all=1 ;; --cflags) do_cflags=1 ;; --defccname) do_defccname=1 ;; --defcktname) do_defcktname=1 ;; --defktname) do_defktname=1 ;; --deps) # historically a no-op ;; --exec-prefix) do_exec_prefix=1 ;; --help) do_help=1 ;; --libs) do_libs=1 ;; --prefix) do_prefix=1 ;; --vendor) do_vendor=1 ;; --version) do_version=1 ;; krb5) library=krb5 ;; gssapi) library=gssapi ;; gssrpc) library=gssrpc ;; kadm-client) library=kadm_client ;; kadm-server) library=kadm_server ;; kdb) library=kdb ;; *) echo "$0: Unknown option \`$1' -- use \`--help' for usage" exit 1 esac shift done # If required options - provide help if test -z "$do_all" -a -z "$do_version" -a -z "$do_vendor" -a \ -z "$do_prefix" -a -z "$do_vendor" -a -z "$do_exec_prefix" -a \ -z "$do_defccname" -a -z "$do_defktname" -a -z "$do_defcktname" -a \ -z "$do_cflags" -a -z "$do_libs"; then do_help=1 fi if test -n "$do_help"; then echo "Usage: $0 [OPTIONS] [LIBRARIES]" echo "Options:" echo " [--help] Help" echo " [--all] Display version, vendor, and various values" echo " [--version] Version information" echo " [--vendor] Vendor information" echo " [--prefix] Kerberos installed prefix" echo " [--exec-prefix] Kerberos installed exec_prefix" echo " [--defccname] Show built-in default ccache name" echo " [--defktname] Show built-in default keytab name" echo " [--defcktname] Show built-in default client keytab name" echo " [--cflags] Compile time CFLAGS" echo " [--libs] List libraries required to link [LIBRARIES]" echo "Libraries:" echo " krb5 Kerberos 5 application" echo " gssapi GSSAPI application with Kerberos 5 bindings" echo " gssrpc GSSAPI RPC application" echo " kadm-client Kadmin client" echo " kadm-server Kadmin server" echo " kdb Application that accesses the kerberos database" exit 0 fi if test -n "$do_all"; then all_exit= do_version=1 do_prefix=1 do_exec_prefix=1 do_vendor=1 title_version="Version: " title_prefix="Prefix: " title_exec_prefix="Exec_prefix: " title_vendor="Vendor: " else all_exit="exit 0" fi if test -n "$do_version"; then echo "$title_version$version_string" $all_exit fi if test -n "$do_vendor"; then echo "$title_vendor$vendor_string" $all_exit fi if test -n "$do_prefix"; then echo "$title_prefix$prefix" $all_exit fi if test -n "$do_exec_prefix"; then echo "$title_exec_prefix$exec_prefix" $all_exit fi if test -n "$do_defccname"; then echo "$DEFCCNAME" $all_exit fi if test -n "$do_defktname"; then echo "$DEFKTNAME" $all_exit fi if test -n "$do_defcktname"; then echo "$DEFCKTNAME" $all_exit fi if test -n "$do_cflags"; then if test x"$includedir" != x"/usr/include" ; then echo "-I${includedir}" else echo '' fi fi if test -n "$do_libs"; then # Assumes /usr/lib is the standard library directory everywhere... if test "$libdir" = /usr/lib; then libdirarg= else libdirarg="-L$libdir" fi # Ugly gross hack for our build tree lib_flags=`echo $CC_LINK | sed -e 's/\$(CC)//' \ -e 's/\$(PURE)//' \ -e 's#\$(PROG_RPATH_FLAGS)#'"$PROG_RPATH_FLAGS"'#' \ -e 's#\$(PROG_RPATH)#'$libdir'#' \ -e 's#\$(PROG_LIBPATH)#'$libdirarg'#' \ -e 's#\$(RPATH_FLAG)#'"$RPATH_FLAG"'#' \ -e 's#\$(LDFLAGS)##' \ -e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \ -e 's#\$(CFLAGS)##'` if test $library = 'kdb'; then lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB" library=krb5 fi if test $library = 'kadm_server'; then lib_flags="$lib_flags -lkadm5srv_mit -lkdb5 $KDB5_DB_LIB" library=gssrpc fi if test $library = 'kadm_client'; then lib_flags="$lib_flags -lkadm5clnt_mit" library=gssrpc fi if test $library = 'gssrpc'; then lib_flags="$lib_flags -lgssrpc" library=gssapi fi if test $library = 'gssapi'; then lib_flags="$lib_flags -lgssapi_krb5" library=krb5 fi if test $library = 'krb5'; then lib_flags="$lib_flags -lkrb5 -lk5crypto @COM_ERR_LIB@" fi # If we ever support a flag to generate output suitable for static # linking, we would output "-lkrb5support $LIBS $DL_LIB" here. echo $lib_flags fi exit 0 krb5-1.22.1/src/build-tools/mit-krb5-gssapi.pc.in0000664000175000017500000000040715051422640021235 0ustar ghudsonghudsonprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: mit-krb5-gssapi Description: Kerberos implementation of the GSSAPI Version: @KRB5_VERSION@ Requires.private: mit-krb5 Cflags: -I${includedir} Libs: -L${libdir} -lgssapi_krb5 krb5-1.22.1/src/build-tools/deps0000664000175000017500000000003015051422640016234 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/build-tools/kadm-server.pc.in0000664000175000017500000000042015051422640020532 0ustar ghudsonghudsonprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: kadm-server Description: Kerberos administration server library Version: @KRB5_VERSION@ Requires.private: kdb mit-krb5-gssapi Cflags: -I${includedir} Libs: -L${libdir} -lkadm5srv_mit krb5-1.22.1/src/build-tools/t_krbconf0000664000175000017500000000314315051422640017260 0ustar ghudsonghudson#!/bin/sh # Copyright 2003 by the Massachusetts Institute of Technology. # All Rights Reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. echo "Testing if krb5-config outputs shell variables" echo " Testing --libs argument" if ./krb5-config --libs kdb | egrep -s '\$' > /dev/null; then echo "Error './krb5-config --libs kdb' contains shell variables" exit 1 fi echo " Testing --cflags argument" if ./krb5-config --cflags | egrep -s '\$' > /dev/null; then echo "Error './krb5-config --cflags' contains shell variables" exit 1 fi echo "krb5-config tests pass" exit 0 krb5-1.22.1/src/build-tools/krb5.pc.in0000664000175000017500000000043315051422640017161 0ustar ghudsonghudsonprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ vendor=MIT defccname=@DEFCCNAME@ defktname=@DEFKTNAME@ defcktname=@DEFCKTNAME@ Name: krb5 Description: An implementation of Kerberos network authentication Version: @KRB5_VERSION@ Requires: mit-krb5 krb5-1.22.1/src/build-tools/kdb.pc.in0000664000175000017500000000050015051422640017051 0ustar ghudsonghudsonprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ KDB5_DB_LIB=@KDB5_DB_LIB@ Name: kdb Description: Kerberos database access libraries Version: @KRB5_VERSION@ Requires.private: mit-krb5-gssapi mit-krb5 gssrpc Cflags: -I${includedir} Libs: -L${libdir} -lkdb5 Libs.private: ${KDB5_DB_LIB} krb5-1.22.1/src/build-tools/kadm-client.pc.in0000664000175000017500000000042415051422640020506 0ustar ghudsonghudsonprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: kadm-client Description: Kerberos administration client library Version: @KRB5_VERSION@ Requires.private: mit-krb5-gssapi gssrpc Cflags: -I${includedir} Libs: -L${libdir} -lkadm5clnt_mit krb5-1.22.1/src/build-tools/gssrpc.pc.in0000664000175000017500000000037715051422640017626 0ustar ghudsonghudsonprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ vendor=MIT Name: gssrpc Description: GSSAPI RPC implementation Version: @KRB5_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lgssrpc Requires.private: mit-krb5-gssapi krb5-1.22.1/src/build-tools/krb5-gssapi.pc.in0000664000175000017500000000032515051422640020445 0ustar ghudsonghudsonprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ vendor=MIT Name: krb5-gssapi Description: Kerberos implementation of the GSSAPI Version: @KRB5_VERSION@ Requires: mit-krb5-gssapi krb5-1.22.1/src/build-tools/mit-krb5.pc.in0000664000175000017500000000054715051422640017756 0ustar ghudsonghudsonprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ defccname=@DEFCCNAME@ defktname=@DEFKTNAME@ defcktname=@DEFCKTNAME@ Name: mit-krb5 Description: An implementation of Kerberos network authentication Version: @KRB5_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lkrb5 -lk5crypto @COM_ERR_LIB@ Libs.private: -lkrb5support krb5-1.22.1/src/clients/0000775000175000017500000000000015051422640014571 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/kdeltkt/0000775000175000017500000000000015051422640016233 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/kdeltkt/Makefile.in0000664000175000017500000000144415051422640020303 0ustar ghudsonghudsonmydir=kvno BUILDTOP=$(REL)..$(S).. ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##KDELTKT=$(OUTPRE)kdeltkt.exe ##WIN32##EXERES=$(KDELTKT:.exe=.res) ##WIN32##$(EXERES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DKDELTKT_APP -fo $@ -r $** all-unix: kdeltkt ##WIN32##all-windows: $(KDELTKT) all-mac: kdeltkt: kdeltkt.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ kdeltkt.o $(KRB5_BASE_LIBS) ##WIN32##$(KDELTKT): $(OUTPRE)kdeltkt.obj $(SLIB) $(KLIB) $(CLIB) $(EXERES) ##WIN32## link $(EXE_LINKOPTS) /out:$@ $** ##WIN32## $(_VC_MANIFEST_EMBED_EXE) clean-unix:: $(RM) kdeltkt.o kdeltkt install-unix: for f in kdeltkt; do \ $(INSTALL_PROGRAM) $$f \ $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \ done krb5-1.22.1/src/clients/kdeltkt/kdeltkt.c0000664000175000017500000001024415051422640020042 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include #include #include #include #include "k5-platform.h" static char *prog; static int quiet = 0; static void xusage(void) { fprintf(stderr, "xusage: %s [-c ccache] [-e etype] [-f flags] service1 " "service2 ...\n", prog); exit(1); } static void do_kdeltkt(int argc, char *argv[], char *ccachestr, char *etypestr, int flags); int main(int argc, char *argv[]) { int option; char *etypestr = NULL, *ccachestr = NULL; int flags = 0; prog = strrchr(argv[0], '/'); prog = (prog != NULL) ? prog + 1 : argv[0]; while ((option = getopt(argc, argv, "c:e:f:hq")) != -1) { switch (option) { case 'c': ccachestr = optarg; break; case 'e': etypestr = optarg; break; case 'f': flags = atoi(optarg); break; case 'q': quiet = 1; break; case 'h': default: xusage(); break; } } if (argc - optind < 1) xusage(); do_kdeltkt(argc - optind, argv + optind, ccachestr, etypestr, flags); return 0; } static void do_kdeltkt(int count, char *names[], const char *ccachestr, char *etypestr, int flags) { krb5_context context; krb5_error_code ret; int i, errors; krb5_enctype etype; krb5_ccache ccache; krb5_principal me; krb5_creds in_creds, out_creds; int retflags; char *princ; ret = krb5_init_context(&context); if (ret) { com_err(prog, ret, "while initializing krb5 library"); exit(1); } if (etypestr != NULL) { ret = krb5_string_to_enctype(etypestr, &etype); if (ret) { com_err(prog, ret, "while converting etype"); exit(1); } retflags = KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES; } else { etype = 0; retflags = KRB5_TC_MATCH_SRV_NAMEONLY; } if (ccachestr) ret = krb5_cc_resolve(context, ccachestr, &ccache); else ret = krb5_cc_default(context, &ccache); if (ret) { com_err(prog, ret, "while opening ccache"); exit(1); } ret = krb5_cc_get_principal(context, ccache, &me); if (ret) { com_err(prog, ret, "while getting client principal name"); exit(1); } errors = 0; for (i = 0; i < count; i++) { memset(&in_creds, 0, sizeof(in_creds)); in_creds.client = me; ret = krb5_parse_name(context, names[i], &in_creds.server); if (ret) { if (!quiet) { fprintf(stderr, "%s: %s while parsing principal name\n", names[i], error_message(ret)); } errors++; continue; } ret = krb5_unparse_name(context, in_creds.server, &princ); if (ret) { fprintf(stderr, "%s: %s while printing principal name\n", names[i], error_message(ret)); errors++; continue; } in_creds.keyblock.enctype = etype; ret = krb5_cc_retrieve_cred(context, ccache, retflags, &in_creds, &out_creds); if (ret) { fprintf(stderr, "%s: %s while retrieving credentials\n", princ, error_message(ret)); krb5_free_unparsed_name(context, princ); errors++; continue; } ret = krb5_cc_remove_cred(context, ccache, flags, &out_creds); krb5_free_principal(context, in_creds.server); if (ret) { fprintf(stderr, "%s: %s while removing credentials\n", princ, error_message(ret)); krb5_free_cred_contents(context, &out_creds); krb5_free_unparsed_name(context, princ); errors++; continue; } krb5_free_unparsed_name(context, princ); krb5_free_cred_contents(context, &out_creds); } krb5_free_principal(context, me); krb5_cc_close(context, ccache); krb5_free_context(context); if (errors) exit(1); exit(0); } krb5-1.22.1/src/clients/Makefile.in0000664000175000017500000000027315051422640016640 0ustar ghudsonghudsonmydir=clients BUILDTOP=$(REL).. SUBDIRS= klist kinit kdestroy kpasswd ksu kvno kcpytkt kdeltkt kswitch WINSUBDIRS= klist kinit kdestroy kpasswd kvno kcpytkt kdeltkt kswitch NO_OUTPRE=1 krb5-1.22.1/src/clients/kcpytkt/0000775000175000017500000000000015051422640016262 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/kcpytkt/Makefile.in0000664000175000017500000000144715051422640020335 0ustar ghudsonghudsonmydir=kcpytkt BUILDTOP=$(REL)..$(S).. ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##KCPYTKT=$(OUTPRE)kcpytkt.exe ##WIN32##EXERES=$(KCPYTKT:.exe=.res) ##WIN32##$(EXERES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DKCPYTKT_APP -fo $@ -r $** all-unix: kcpytkt ##WIN32##all-windows: $(KCPYTKT) all-mac: kcpytkt: kcpytkt.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ kcpytkt.o $(KRB5_BASE_LIBS) ##WIN32##$(KCPYTKT): $(OUTPRE)kcpytkt.obj $(SLIB) $(KLIB) $(CLIB) $(EXERES) ##WIN32## link $(EXE_LINKOPTS) /out:$@ $** ##WIN32## $(_VC_MANIFEST_EMBED_EXE) clean-unix:: $(RM) kcpytkt.o kcpytkt install-unix: for f in kcpytkt; do \ $(INSTALL_PROGRAM) $$f \ $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \ done krb5-1.22.1/src/clients/kcpytkt/kcpytkt.c0000664000175000017500000001071215051422640020120 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include #include #include #include #include "k5-platform.h" static char *prog; static int quiet = 0; static void xusage(void) { fprintf(stderr, "xusage: %s [-c from_ccache] [-e etype] [-f flags] " "dest_ccache service1 service2 ...\n", prog); exit(1); } static void do_kcpytkt(int argc, char *argv[], char *fromccachestr, char *etypestr, int flags); int main(int argc, char *argv[]) { int option; char *etypestr = NULL, *fromccachestr = NULL; int flags = 0; prog = strrchr(argv[0], '/'); prog = (prog != NULL) ? prog + 1 : argv[0]; while ((option = getopt(argc, argv, "c:e:f:hq")) != -1) { switch (option) { case 'c': fromccachestr = optarg; break; case 'e': etypestr = optarg; break; case 'f': flags = atoi(optarg); break; case 'q': quiet = 1; break; case 'h': default: xusage(); break; } } if (argc - optind < 2) xusage(); do_kcpytkt(argc - optind, argv + optind, fromccachestr, etypestr, flags); return 0; } static void do_kcpytkt(int count, char *names[], const char *fromccachestr, char *etypestr, int flags) { krb5_context context; krb5_error_code ret; krb5_enctype etype; krb5_ccache fromccache, destccache; krb5_principal me; krb5_creds in_creds, out_creds; int i, errors, retflags; char *princ; ret = krb5_init_context(&context); if (ret) { com_err(prog, ret, "while initializing krb5 library"); exit(1); } if (etypestr != NULL) { ret = krb5_string_to_enctype(etypestr, &etype); if (ret) { com_err(prog, ret, "while converting etype"); exit(1); } retflags = KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES; } else { etype = 0; retflags = KRB5_TC_MATCH_SRV_NAMEONLY; } if (fromccachestr != NULL) ret = krb5_cc_resolve(context, fromccachestr, &fromccache); else ret = krb5_cc_default(context, &fromccache); if (ret) { com_err(prog, ret, "while opening source ccache"); exit(1); } ret = krb5_cc_get_principal(context, fromccache, &me); if (ret) { com_err(prog, ret, "while getting client principal name"); exit(1); } ret = krb5_cc_resolve(context, names[0], &destccache); if (ret) { com_err(prog, ret, "while opening destination cache"); exit(1); } errors = 0; for (i = 1; i < count; i++) { memset(&in_creds, 0, sizeof(in_creds)); in_creds.client = me; ret = krb5_parse_name(context, names[i], &in_creds.server); if (ret) { if (!quiet) { fprintf(stderr, "%s: %s while parsing principal name\n", names[i], error_message(ret)); } errors++; continue; } ret = krb5_unparse_name(context, in_creds.server, &princ); if (ret) { fprintf(stderr, "%s: %s while printing principal name\n", names[i], error_message(ret)); errors++; continue; } in_creds.keyblock.enctype = etype; ret = krb5_cc_retrieve_cred(context, fromccache, retflags, &in_creds, &out_creds); if (ret) { fprintf(stderr, "%s: %s while retrieving credentials\n", princ, error_message(ret)); krb5_free_unparsed_name(context, princ); errors++; continue; } ret = krb5_cc_store_cred(context, destccache, &out_creds); krb5_free_principal(context, in_creds.server); if (ret) { fprintf(stderr, "%s: %s while removing credentials\n", princ, error_message(ret)); krb5_free_cred_contents(context, &out_creds); krb5_free_unparsed_name(context, princ); errors++; continue; } krb5_free_unparsed_name(context, princ); krb5_free_cred_contents(context, &out_creds); } krb5_free_principal(context, me); krb5_cc_close(context, fromccache); krb5_cc_close(context, destccache); krb5_free_context(context); if (errors) exit(1); exit(0); } krb5-1.22.1/src/clients/ksu/0000775000175000017500000000000015051422640015373 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/ksu/Makefile.in0000664000175000017500000000205615051422640017443 0ustar ghudsonghudsonmydir=clients$(S)ksu BUILDTOP=$(REL)..$(S).. DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"' KSU_LIBS=@KSU_LIBS@ SRCS = \ $(srcdir)/krb_auth_su.c \ $(srcdir)/ccache.c \ $(srcdir)/authorization.c \ $(srcdir)/main.c \ $(srcdir)/heuristic.c \ $(srcdir)/xmalloc.c \ $(srcdir)/setenv.c OBJS = \ krb_auth_su.o \ ccache.o \ authorization.o \ main.o \ heuristic.o \ xmalloc.o @SETENVOBJ@ all: ksu ksu: $(OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) clean: $(RM) ksu install: -for f in ksu; do \ $(INSTALL_SETUID) $$f \ $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \ done # The ksu tests must be run as root and may be disruptive to the host # system, so they are not included in "make check". asan's leak # checker does not work with setuid binaries (and causes them to # always exit with status 1), so it is disabled here. check-ksu: sudo LSAN_OPTIONS=detect_leaks=0 $(RUNPYTEST) $(srcdir)/t_ksu.py \ $(PYTESTFLAGS) krb5-1.22.1/src/clients/ksu/authorization.c0000664000175000017500000004241515051422640020445 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 1994 by the University of Southern California * * EXPORT OF THIS SOFTWARE from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute * this software and its documentation in source and binary forms is * hereby granted, provided that any documentation or other materials * related to such distribution or use acknowledge that the software * was developed by the University of Southern California. * * DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The * University of Southern California MAKES NO REPRESENTATIONS OR * WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not * limitation, the University of Southern California MAKES NO * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY * PARTICULAR PURPOSE. The University of Southern * California shall not be held liable for any liability nor for any * direct, indirect, or consequential damages with respect to any * claim by the user or distributor of the ksu software. * * KSU was written by: Ari Medvinsky, ari@isi.edu */ #include "ksu.h" static void free_fcmd_list(char **list) { size_t i; if (list == NULL) return; for (i = 0; i < MAX_CMD && list[i] != NULL; i++) free(list[i]); free(list); } krb5_boolean fowner(FILE *fp, uid_t uid) { struct stat sbuf; /* * For security reasons, file must be owned either by * the user himself, or by root. Otherwise, don't grant access. */ if (fstat(fileno(fp), &sbuf)) { return(FALSE); } if ((sbuf.st_uid != uid) && sbuf.st_uid) { return(FALSE); } return(TRUE); } /* * Given a Kerberos principal "principal", and a local username "luser", * determine whether user is authorized to login according to the authorization * files ~luser/.k5login" and ~luser/.k5users. Set *ok to TRUE if authorized, * FALSE if not authorized. Return 0 if the authorization check succeeded * (regardless of its result), non-zero if it encountered an error. */ krb5_error_code krb5_authorization(krb5_context context, krb5_principal principal, const char *luser, char *cmd, krb5_boolean *ok, char **out_fcmd) { struct passwd *pwd; char *princname = NULL; int k5login_flag =0; int k5users_flag =0; krb5_boolean retbool =FALSE; FILE * login_fp = 0, * users_fp = 0; krb5_error_code retval = 0; struct stat st_temp; *ok =FALSE; /* no account => no access */ if ((pwd = getpwnam(luser)) == NULL) goto cleanup; retval = krb5_unparse_name(context, principal, &princname); if (retval) return retval; #ifdef DEBUG printf("principal to be authorized %s\n", princname); printf("login file: %s\n", k5login_path); printf("users file: %s\n", k5users_path); #endif k5login_flag = stat(k5login_path, &st_temp); k5users_flag = stat(k5users_path, &st_temp); /* k5login and k5users must be owned by target user or root */ if (!k5login_flag){ login_fp = fopen(k5login_path, "r"); if (login_fp == NULL) goto cleanup; if (fowner(login_fp, pwd->pw_uid) == FALSE) goto cleanup; } if (!k5users_flag){ users_fp = fopen(k5users_path, "r"); if (users_fp == NULL) goto cleanup; if (fowner(users_fp, pwd->pw_uid) == FALSE) goto cleanup; } if (auth_debug){ fprintf(stderr, "In krb5_authorization: if auth files exist -> can access\n"); } /* if either file exists, first see if the principal is in the login in file, if it's not there check the k5users file */ if (!k5login_flag){ if (auth_debug) fprintf(stderr, "In krb5_authorization: principal to be authorized %s\n", princname); retval = k5login_lookup(login_fp, princname, &retbool); if (retval) goto cleanup; if (retbool) { if (cmd) *out_fcmd = xstrdup(cmd); } } if ((!k5users_flag) && (retbool == FALSE) ){ retval = k5users_lookup (users_fp, princname, cmd, &retbool, out_fcmd); if (retval) goto cleanup; } if (k5login_flag && k5users_flag){ char * kuser = (char *) xcalloc (strlen(princname), sizeof(char)); if (!(krb5_aname_to_localname(context, principal, strlen(princname), kuser)) && (strcmp(kuser, luser) == 0)) { retbool = TRUE; } free(kuser); } *ok =retbool; cleanup: if (users_fp != NULL) fclose(users_fp); if (login_fp != NULL) fclose(login_fp); free(princname); return retval; } /*********************************************************** k5login_lookup looks for princname in file fp. Spaces before the princaname (in the file ) are not ignored spaces after the princname are ignored. If there are any tokens after the principal name FALSE is returned. ***********************************************************/ krb5_error_code k5login_lookup(FILE *fp, char *princname, krb5_boolean *found) { krb5_error_code retval; char * line; char * fprinc; char * lp; krb5_boolean loc_found = FALSE; retval = get_line(fp, &line); if (retval) return retval; while (line){ fprinc = get_first_token (line, &lp); if (fprinc && (!strcmp(princname, fprinc))){ if( get_next_token (&lp) ){ free (line); break; /* nothing should follow princname*/ } else{ loc_found = TRUE; free (line); break; } } free (line); retval = get_line(fp, &line); if (retval) return retval; } *found = loc_found; return 0; } /*********************************************************** k5users_lookup looks for princname in file fp. Spaces before the princaname (in the file ) are not ignored spaces after the princname are ignored. authorization alg: if princname is not found return false. if princname is found{ if cmd == NULL then the file entry after principal name must be nothing or * if cmd !=NULL then entry must be matched (* is ok) } ***********************************************************/ krb5_error_code k5users_lookup(FILE *fp, char *princname, char *cmd, krb5_boolean *found, char **out_fcmd) { krb5_error_code retval; char * line; char * fprinc, *fcmd; char * lp; char * loc_fcmd = NULL; krb5_boolean loc_found = FALSE; retval = get_line(fp, &line); if (retval) return retval; while (line){ fprinc = get_first_token (line, &lp); if (fprinc && (!strcmp(princname, fprinc))){ fcmd = get_next_token (&lp); if ((fcmd) && (!strcmp(fcmd, PERMIT_ALL_COMMANDS))){ if (get_next_token(&lp) == NULL){ loc_fcmd =cmd ? xstrdup(cmd): NULL; loc_found = TRUE; } free (line); break; } if (cmd == NULL){ if (fcmd == NULL) loc_found = TRUE; free (line); break; }else{ if (fcmd != NULL) { char * temp_rfcmd, *err; krb5_boolean match; do { if(match_commands(fcmd,cmd,&match, &temp_rfcmd, &err)){ if (auth_debug){ fprintf(stderr,"%s",err); } loc_fcmd = err; break; }else{ if (match == TRUE){ loc_fcmd = temp_rfcmd; loc_found = TRUE; break; } } }while ((fcmd = get_next_token( &lp))); } free (line); break; } } free (line); retval = get_line(fp, &line); if (retval) { return retval; } } *out_fcmd = loc_fcmd; *found = loc_found; return 0; } /*********************************************** fcmd_resolve - takes a command specified .k5users file and resolves it into a full path name. ************************************************/ krb5_boolean fcmd_resolve(char *fcmd, char ***out_fcmd, char **out_err) { char * err; char ** tmp_fcmd = NULL; char * path_ptr, *path; char * lp, * tc; int i=0; krb5_boolean ok = FALSE; tmp_fcmd = (char **) xcalloc (MAX_CMD, sizeof(char *)); if (*fcmd == '/'){ /* must be full path */ tmp_fcmd[0] = xstrdup(fcmd); tmp_fcmd[1] = NULL; *out_fcmd = tmp_fcmd; tmp_fcmd = NULL; }else{ /* must be either full path or just the cmd name */ if (strchr(fcmd, '/')){ asprintf(&err, _("Error: bad entry - %s in %s file, must be " "either full path or just the cmd name\n"), fcmd, KRB5_USERS_NAME); *out_err = err; goto cleanup; } #ifndef CMD_PATH asprintf(&err, _("Error: bad entry - %s in %s file, since %s is just " "the cmd name, CMD_PATH must be defined \n"), fcmd, KRB5_USERS_NAME, fcmd); *out_err = err; goto cleanup; #else path = xstrdup (CMD_PATH); path_ptr = path; while ((*path_ptr == ' ') || (*path_ptr == '\t')) path_ptr ++; tc = get_first_token (path_ptr, &lp); if (! tc){ asprintf(&err, _("Error: bad entry - %s in %s file, CMD_PATH " "contains no paths \n"), fcmd, KRB5_USERS_NAME); *out_err = err; goto cleanup; } i=0; do{ if (*tc != '/'){ /* must be full path */ asprintf(&err, _("Error: bad path %s in CMD_PATH for %s must " "start with '/' \n"), tc, KRB5_USERS_NAME ); *out_err = err; goto cleanup; } tmp_fcmd[i] = xasprintf("%s/%s", tc, fcmd); i++; } while((tc = get_next_token (&lp))); tmp_fcmd[i] = NULL; *out_fcmd = tmp_fcmd; tmp_fcmd = NULL; #endif /* CMD_PATH */ } ok = TRUE; cleanup: free_fcmd_list(tmp_fcmd); return ok; } /******************************************** cmd_single - checks if cmd consists of a path or a single token ********************************************/ krb5_boolean cmd_single(char *cmd) { if ( ( strrchr( cmd, '/')) == NULL){ return TRUE; }else{ return FALSE; } } /******************************************** cmd_arr_cmp_postfix - compares a command with the postfix of fcmd ********************************************/ int cmd_arr_cmp_postfix(char **fcmd_arr, char *cmd) { char * temp_fcmd; char *ptr; int result =1; int i = 0; while(fcmd_arr[i]){ if ( (ptr = strrchr( fcmd_arr[i], '/')) == NULL){ temp_fcmd = fcmd_arr[i]; }else { temp_fcmd = ptr + 1; } result = strcmp (temp_fcmd, cmd); if (result == 0){ break; } i++; } return result; } /********************************************** cmd_arr_cmp - checks if cmd matches any of the fcmd entries. **********************************************/ int cmd_arr_cmp(char **fcmd_arr, char *cmd) { int result =1; int i = 0; while(fcmd_arr[i]){ result = strcmp (fcmd_arr[i], cmd); if (result == 0){ break; } i++; } return result; } krb5_boolean find_first_cmd_that_exists(char **fcmd_arr, char **cmd_out, char **err_out) { struct stat st_temp; int i = 0; krb5_boolean retbool= FALSE; int j =0; struct k5buf buf; while(fcmd_arr[i]){ if (!stat (fcmd_arr[i], &st_temp )){ *cmd_out = xstrdup(fcmd_arr[i]); retbool = TRUE; break; } i++; } if (retbool == FALSE ){ k5_buf_init_dynamic(&buf); k5_buf_add(&buf, _("Error: not found -> ")); for(j= 0; j < i; j ++) k5_buf_add_fmt(&buf, " %s ", fcmd_arr[j]); k5_buf_add(&buf, "\n"); *err_out = k5_buf_cstring(&buf); if (*err_out == NULL) { perror(prog_name); exit(1); } } return retbool; } /*************************************************************** returns 1 if there is an error, 0 if no error. ***************************************************************/ int match_commands(char *fcmd, char *cmd, krb5_boolean *match, char **cmd_out, char **err_out) { char ** fcmd_arr = NULL; char * err; char * cmd_temp; int result = 1; if(fcmd_resolve(fcmd, &fcmd_arr, &err )== FALSE ){ *err_out = err; goto cleanup; } if (cmd_single( cmd ) == TRUE){ if (!cmd_arr_cmp_postfix(fcmd_arr, cmd)){ /* found */ if (!find_first_cmd_that_exists(fcmd_arr, &cmd_temp, &err)) { *err_out = err; goto cleanup; } *match = TRUE; *cmd_out = cmd_temp; } else { *match = FALSE; } }else{ if (!cmd_arr_cmp(fcmd_arr, cmd)){ /* found */ *match = TRUE; *cmd_out = xstrdup(cmd); } else{ *match = FALSE; } } result = 0; cleanup: free_fcmd_list(fcmd_arr); return result; } /********************************************************* get_line - returns a line of any length. out_line is set to null if eof. *********************************************************/ krb5_error_code get_line(FILE *fp, char **out_line) { char * line, *r, *newline , *line_ptr; int chunk_count = 1; line = (char *) xcalloc (BUFSIZ, sizeof (char )); line_ptr = line; line[0] = '\0'; while (( r = fgets(line_ptr, BUFSIZ , fp)) != NULL){ newline = strchr(line_ptr, '\n'); if (newline) { *newline = '\0'; break; } else { chunk_count ++; line = xrealloc(line, chunk_count * BUFSIZ); line_ptr = line + (BUFSIZ -1) *( chunk_count -1) ; } } if ((r == NULL) && (strlen(line) == 0)) { *out_line = NULL; } else{ *out_line = line; } return 0; } /******************************************************* get_first_token - Expects a '\0' terminated input line . If there are any spaces before the first token, they will be returned as part of the first token. Note: this routine reuses the space pointed to by line ******************************************************/ char * get_first_token(char *line, char **lnext) { char * lptr, * out_ptr; out_ptr = line; lptr = line; while (( *lptr == ' ') || (*lptr == '\t')) lptr ++; if (strlen(lptr) == 0) return NULL; while (( *lptr != ' ') && (*lptr != '\t') && (*lptr != '\0')) lptr ++; if (*lptr == '\0'){ *lnext = lptr; } else{ *lptr = '\0'; *lnext = lptr + 1; } return out_ptr; } /********************************************************** get_next_token - returns the next token pointed to by *lnext. returns NULL if there is no more tokens. Note: that this function modifies the stream pointed to by *lnext and does not allocate space for the returned tocken. It also advances lnext to the next tocken. **********************************************************/ char * get_next_token (char **lnext) { char * lptr, * out_ptr; lptr = *lnext; while (( *lptr == ' ') || (*lptr == '\t')) lptr ++; if (strlen(lptr) == 0) return NULL; out_ptr = lptr; while (( *lptr != ' ') && (*lptr != '\t') && (*lptr != '\0')) lptr ++; if (*lptr == '\0'){ *lnext = lptr; } else{ *lptr = '\0'; *lnext = lptr + 1; } return out_ptr; } void init_auth_names(char *pw_dir) { const char *sep; int r1, r2; sep = ((strlen(pw_dir) == 1) && (*pw_dir == '/')) ? "" : "/"; r1 = snprintf(k5login_path, sizeof(k5login_path), "%s%s%s", pw_dir, sep, KRB5_LOGIN_NAME); r2 = snprintf(k5users_path, sizeof(k5users_path), "%s%s%s", pw_dir, sep, KRB5_USERS_NAME); if (SNPRINTF_OVERFLOW(r1, sizeof(k5login_path)) || SNPRINTF_OVERFLOW(r2, sizeof(k5users_path))) { fprintf(stderr, _("home directory name `%s' too long, can't search " "for .k5login\n"), pw_dir); exit (1); } } krb5-1.22.1/src/clients/ksu/deps0000664000175000017500000001113715051422640016254 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)krb_auth_su.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/k5-util.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ krb_auth_su.c ksu.h $(OUTPRE)ccache.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/adm_proto.h \ $(top_srcdir)/include/k5-base64.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/k5-util.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ccache.c ksu.h $(OUTPRE)authorization.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/k5-util.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ authorization.c ksu.h $(OUTPRE)main.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/adm_proto.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-util.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ksu.h main.c $(OUTPRE)heuristic.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/k5-util.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ heuristic.c ksu.h $(OUTPRE)xmalloc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/k5-util.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ksu.h xmalloc.c $(OUTPRE)setenv.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ setenv.c krb5-1.22.1/src/clients/ksu/ccache.c0000664000175000017500000004134415051422640016753 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 1994 by the University of Southern California * * EXPORT OF THIS SOFTWARE from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute * this software and its documentation in source and binary forms is * hereby granted, provided that any documentation or other materials * related to such distribution or use acknowledge that the software * was developed by the University of Southern California. * * DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The * University of Southern California MAKES NO REPRESENTATIONS OR * WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not * limitation, the University of Southern California MAKES NO * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY * PARTICULAR PURPOSE. The University of Southern * California shall not be held liable for any liability nor for any * direct, indirect, or consequential damages with respect to any * claim by the user or distributor of the ksu software. * * KSU was written by: Ari Medvinsky, ari@isi.edu */ #include "ksu.h" #include "k5-base64.h" #include "adm_proto.h" #include #include /****************************************************************** krb5_cache_copy gets rid of any expired tickets in the secondary cache, copies the default cache into the secondary cache, ************************************************************************/ static void free_creds_list(krb5_context context, krb5_creds **list) { size_t i; if (list == NULL) return; for (i = 0; list[i]; i++) krb5_free_creds(context, list[i]); free(list); } void show_credential(krb5_context, krb5_creds *, krb5_ccache); /* modifies only the cc_other, the algorithm may look a bit funny, but I had to do it this way, since remove function did not come with k5 beta 3 release. */ krb5_error_code krb5_ccache_copy(krb5_context context, krb5_ccache cc_def, krb5_principal target_principal, krb5_ccache cc_target, krb5_boolean restrict_creds, krb5_principal primary_principal, krb5_boolean *stored) { krb5_error_code retval=0; krb5_creds ** cc_def_creds_arr = NULL; krb5_creds ** cc_other_creds_arr = NULL; if (ks_ccache_is_initialized(context, cc_def)) { retval = krb5_get_nonexp_tkts(context, cc_def, &cc_def_creds_arr); if (retval) goto cleanup; } retval = krb5_cc_initialize(context, cc_target, target_principal); if (retval) goto cleanup; if (restrict_creds) { retval = krb5_store_some_creds(context, cc_target, cc_def_creds_arr, cc_other_creds_arr, primary_principal, stored); } else { *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr, primary_principal); retval = krb5_store_all_creds(context, cc_target, cc_def_creds_arr, cc_other_creds_arr); } cleanup: free_creds_list(context, cc_def_creds_arr); free_creds_list(context, cc_other_creds_arr); return retval; } krb5_error_code krb5_store_all_creds(krb5_context context, krb5_ccache cc, krb5_creds **creds_def, krb5_creds **creds_other) { int i = 0; krb5_error_code retval = 0; krb5_creds ** temp_creds= NULL; if ((creds_def == NULL) && (creds_other == NULL)) return 0; if ((creds_def == NULL) && (creds_other != NULL)) temp_creds = creds_other; if ((creds_def != NULL) && (creds_other == NULL)) temp_creds = creds_def; if (temp_creds){ while(temp_creds[i]){ if ((retval= krb5_cc_store_cred(context, cc, temp_creds[i]))){ return retval; } i++; } } else { /* both arrays have elements in them */ return KRB5KRB_ERR_GENERIC; /************ while(creds_other[i]){ cmp = FALSE; j = 0; while(creds_def[j]){ cmp = compare_creds(creds_other[i],creds_def[j]); if( cmp == TRUE) break; j++; } if (cmp == FALSE){ if (retval= krb5_cc_store_cred(context, cc, creds_other[i])){ return retval; } } i ++; } i=0; while(creds_def[i]){ if (retval= krb5_cc_store_cred(context, cc, creds_def[i])){ return retval; } i++; } **************/ } return 0; } krb5_boolean compare_creds(krb5_context context, krb5_creds *cred1, krb5_creds *cred2) { krb5_boolean retval; retval = krb5_principal_compare (context, cred1->client, cred2->client); if (retval == TRUE) retval = krb5_principal_compare (context, cred1->server, cred2->server); return retval; } krb5_error_code krb5_get_nonexp_tkts(krb5_context context, krb5_ccache cc, krb5_creds ***creds_array) { krb5_creds creds, temp_tktq, temp_tkt; krb5_creds **temp_creds = NULL; krb5_error_code retval=0; krb5_cc_cursor cur; int count = 0; int chunk_count = 1; temp_creds = xcalloc(CHUNK, sizeof(*temp_creds)); memset(&temp_tktq, 0, sizeof(temp_tktq)); memset(&temp_tkt, 0, sizeof(temp_tkt)); memset(&creds, 0, sizeof(creds)); /* initialize the cursor */ retval = krb5_cc_start_seq_get(context, cc, &cur); if (retval) goto cleanup; while (!(retval = krb5_cc_next_cred(context, cc, &cur, &creds))){ if (!krb5_is_config_principal(context, creds.server) && (retval = krb5_check_exp(context, creds.times))){ krb5_free_cred_contents(context, &creds); if (retval != KRB5KRB_AP_ERR_TKT_EXPIRED){ goto cleanup; } if (auth_debug){ fprintf(stderr,"krb5_ccache_copy: CREDS EXPIRED:\n"); fputs(" Valid starting Expires Service principal\n",stdout); show_credential(context, &creds, cc); fprintf(stderr,"\n"); } } else { /* these credentials didn't expire */ retval = krb5_copy_creds(context, &creds, &temp_creds[count]); krb5_free_cred_contents(context, &creds); temp_creds[count+1] = NULL; if (retval) goto cleanup; count ++; if (count == (chunk_count * CHUNK -1)){ chunk_count ++; temp_creds = xrealloc(temp_creds, chunk_count * CHUNK * sizeof(*temp_creds)); } } } temp_creds[count] = NULL; *creds_array = temp_creds; temp_creds = NULL; if (retval == KRB5_CC_END) { retval = krb5_cc_end_seq_get(context, cc, &cur); } cleanup: free_creds_list(context, temp_creds); return retval; } krb5_error_code krb5_check_exp(krb5_context context, krb5_ticket_times tkt_time) { krb5_error_code retval =0; krb5_timestamp currenttime; if ((retval = krb5_timeofday (context, ¤ttime))){ return retval; } if (auth_debug){ fprintf(stderr,"krb5_check_exp: the krb5_clockskew is %d \n", context->clockskew); fprintf(stderr,"krb5_check_exp: currenttime - endtime %d \n", ts_delta(currenttime, tkt_time.endtime)); } if (ts_after(currenttime, ts_incr(tkt_time.endtime, context->clockskew))) { retval = KRB5KRB_AP_ERR_TKT_EXPIRED ; return retval; } return 0; } char * flags_string(krb5_creds *cred) { static char buf[32]; int i = 0; if (cred->ticket_flags & TKT_FLG_FORWARDABLE) buf[i++] = 'F'; if (cred->ticket_flags & TKT_FLG_FORWARDED) buf[i++] = 'f'; if (cred->ticket_flags & TKT_FLG_PROXIABLE) buf[i++] = 'P'; if (cred->ticket_flags & TKT_FLG_PROXY) buf[i++] = 'p'; if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE) buf[i++] = 'D'; if (cred->ticket_flags & TKT_FLG_POSTDATED) buf[i++] = 'd'; if (cred->ticket_flags & TKT_FLG_INVALID) buf[i++] = 'i'; if (cred->ticket_flags & TKT_FLG_RENEWABLE) buf[i++] = 'R'; if (cred->ticket_flags & TKT_FLG_INITIAL) buf[i++] = 'I'; if (cred->ticket_flags & TKT_FLG_HW_AUTH) buf[i++] = 'H'; if (cred->ticket_flags & TKT_FLG_PRE_AUTH) buf[i++] = 'A'; buf[i] = '\0'; return(buf); } void printtime(krb5_timestamp ts) { char fmtbuf[18], fill = ' '; if (!krb5_timestamp_to_sfstring(ts, fmtbuf, sizeof(fmtbuf), &fill)) printf("%s", fmtbuf); } void show_credential(krb5_context context, krb5_creds *cred, krb5_ccache cc) { krb5_error_code retval; char *name = NULL, *sname = NULL, *defname = NULL, *flags; int first = 1; krb5_principal princ = NULL; int show_flags =1; retval = krb5_unparse_name(context, cred->client, &name); if (retval) { com_err(prog_name, retval, _("while unparsing client name")); goto cleanup; } retval = krb5_unparse_name(context, cred->server, &sname); if (retval) { com_err(prog_name, retval, _("while unparsing server name")); goto cleanup; } if ((retval = krb5_cc_get_principal(context, cc, &princ))) { com_err(prog_name, retval, _("while retrieving principal name")); goto cleanup; } if ((retval = krb5_unparse_name(context, princ, &defname))) { com_err(prog_name, retval, _("while unparsing principal name")); goto cleanup; } if (!cred->times.starttime) cred->times.starttime = cred->times.authtime; printtime(cred->times.starttime); putchar(' '); putchar(' '); printtime(cred->times.endtime); putchar(' '); putchar(' '); printf("%s\n", sname); if (strcmp(name, defname)) { printf(_("\tfor client %s"), name); first = 0; } if (cred->times.renew_till) { if (first) fputs("\t",stdout); else fputs(", ",stdout); fputs(_("renew until "), stdout); printtime(cred->times.renew_till); } if (show_flags) { flags = flags_string(cred); if (flags && *flags) { if (first) fputs("\t",stdout); else fputs(", ",stdout); printf(_("Flags: %s"), flags); first = 0; } } putchar('\n'); cleanup: free(name); free(sname); free(defname); krb5_free_principal(context, princ); } /* Create a random string suitable for a filename extension. */ krb5_error_code gen_sym(krb5_context context, char **sym_out) { krb5_error_code retval; char bytes[6], *p, *sym; krb5_data data = make_data(bytes, sizeof(bytes)); *sym_out = NULL; retval = krb5_c_random_make_octets(context, &data); if (retval) return retval; sym = k5_base64_encode(data.data, data.length); if (sym == NULL) return ENOMEM; /* Tweak the output alphabet just a bit. */ while ((p = strchr(sym, '/')) != NULL) *p = '_'; while ((p = strchr(sym, '+')) != NULL) *p = '-'; *sym_out = sym; return 0; } krb5_error_code krb5_ccache_overwrite(krb5_context context, krb5_ccache ccs, krb5_ccache cct, krb5_principal primary_principal) { krb5_error_code retval=0; krb5_principal defprinc = NULL, princ; krb5_creds ** ccs_creds_arr = NULL; if (ks_ccache_is_initialized(context, ccs)) { retval = krb5_get_nonexp_tkts(context, ccs, &ccs_creds_arr); if (retval) goto cleanup; } retval = krb5_cc_get_principal(context, cct, &defprinc); princ = (retval == 0) ? defprinc : primary_principal; retval = krb5_cc_initialize(context, cct, princ); if (retval) goto cleanup; retval = krb5_store_all_creds(context, cct, ccs_creds_arr, NULL); cleanup: free_creds_list(context, ccs_creds_arr); krb5_free_principal(context, defprinc); return retval; } krb5_error_code krb5_store_some_creds(krb5_context context, krb5_ccache cc, krb5_creds **creds_def, krb5_creds **creds_other, krb5_principal prst, krb5_boolean *stored) { int i = 0; krb5_error_code retval = 0; krb5_creds ** temp_creds= NULL; krb5_boolean temp_stored = FALSE; if ((creds_def == NULL) && (creds_other == NULL)) return 0; if ((creds_def == NULL) && (creds_other != NULL)) temp_creds = creds_other; if ((creds_def != NULL) && (creds_other == NULL)) temp_creds = creds_def; if (temp_creds){ while(temp_creds[i]){ if (krb5_principal_compare(context, temp_creds[i]->client, prst)== TRUE) { if ((retval = krb5_cc_store_cred(context, cc,temp_creds[i]))){ return retval; } temp_stored = TRUE; } i++; } } else { /* both arrays have elements in them */ return KRB5KRB_ERR_GENERIC; } *stored = temp_stored; return 0; } krb5_error_code krb5_ccache_filter(krb5_context context, krb5_ccache cc, krb5_principal prst) { krb5_error_code retval=0; krb5_principal temp_principal = NULL; krb5_creds ** cc_creds_arr = NULL; const char * cc_name; krb5_boolean stored; if (!ks_ccache_is_initialized(context, cc)) return 0; if (auth_debug) { cc_name = krb5_cc_get_name(context, cc); fprintf(stderr, "putting cache %s through a filter for -z option\n", cc_name); } retval = krb5_get_nonexp_tkts(context, cc, &cc_creds_arr); if (retval) goto cleanup; retval = krb5_cc_get_principal(context, cc, &temp_principal); if (retval) goto cleanup; retval = krb5_cc_initialize(context, cc, temp_principal); if (retval) goto cleanup; retval = krb5_store_some_creds(context, cc, cc_creds_arr, NULL, prst, &stored); cleanup: free_creds_list(context, cc_creds_arr); krb5_free_principal(context, temp_principal); return retval; } krb5_boolean krb5_find_princ_in_cred_list(krb5_context context, krb5_creds **creds_list, krb5_principal princ) { int i = 0; krb5_boolean temp_stored = FALSE; if (creds_list){ while(creds_list[i]){ if (krb5_principal_compare(context, creds_list[i]->client, princ)== TRUE){ temp_stored = TRUE; break; } i++; } } return temp_stored; } krb5_error_code krb5_find_princ_in_cache(krb5_context context, krb5_ccache cc, krb5_principal princ, krb5_boolean *found) { krb5_error_code retval = 0; krb5_creds ** creds_list = NULL; if (ks_ccache_is_initialized(context, cc)) { retval = krb5_get_nonexp_tkts(context, cc, &creds_list); if (retval) goto cleanup; } *found = krb5_find_princ_in_cred_list(context, creds_list, princ); cleanup: free_creds_list(context, creds_list); return retval; } krb5_boolean ks_ccache_name_is_initialized(krb5_context context, const char *cctag) { krb5_boolean result; krb5_ccache cc; if (krb5_cc_resolve(context, cctag, &cc) != 0) return FALSE; result = ks_ccache_is_initialized(context, cc); krb5_cc_close(context, cc); return result; } krb5_boolean ks_ccache_is_initialized(krb5_context context, krb5_ccache cc) { krb5_principal princ; krb5_error_code retval; if (cc == NULL) return FALSE; retval = krb5_cc_get_principal(context, cc, &princ); if (retval == 0) krb5_free_principal(context, princ); return retval == 0; } krb5-1.22.1/src/clients/ksu/krb_auth_su.c0000664000175000017500000001737315051422640020060 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 1994 by the University of Southern California * * EXPORT OF THIS SOFTWARE from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute * this software and its documentation in source and binary forms is * hereby granted, provided that any documentation or other materials * related to such distribution or use acknowledge that the software * was developed by the University of Southern California. * * DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The * University of Southern California MAKES NO REPRESENTATIONS OR * WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not * limitation, the University of Southern California MAKES NO * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY * PARTICULAR PURPOSE. The University of Southern * California shall not be held liable for any liability nor for any * direct, indirect, or consequential damages with respect to any * claim by the user or distributor of the ksu software. * * KSU was written by: Ari Medvinsky, ari@isi.edu */ #include "ksu.h" void plain_dump_principal(krb5_context, krb5_principal); krb5_boolean krb5_auth_check(krb5_context context, krb5_principal client_pname, char *hostname, krb5_get_init_creds_opt *options, char *target_user, krb5_ccache cc, int *path_passwd, uid_t target_uid) { krb5_principal client = NULL; krb5_verify_init_creds_opt vfy_opts; krb5_creds tgt = { 0 }, tgtq = { 0 }; krb5_error_code retval =0; int got_it = 0; krb5_boolean zero_password; krb5_boolean ok = FALSE; *path_passwd = 0; if ((retval= krb5_copy_principal(context, client_pname, &client))){ com_err(prog_name, retval, _("while copying client principal")); goto cleanup; } if ((retval= krb5_copy_principal(context, client, &tgtq.client))){ com_err(prog_name, retval, _("while copying client principal")); goto cleanup; } if ((retval = ksu_tgtname(context, krb5_princ_realm(context, client), krb5_princ_realm(context, client), &tgtq.server))){ com_err(prog_name, retval, _("while creating tgt for local realm")); goto cleanup; } if (auth_debug){ dump_principal(context, "local tgt principal name", tgtq.server ); } retval = krb5_cc_retrieve_cred(context, cc, KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES, &tgtq, &tgt); if (! retval) retval = krb5_check_exp(context, tgt.times); if (retval){ if ((retval != KRB5_CC_NOTFOUND) && (retval != KRB5KRB_AP_ERR_TKT_EXPIRED)){ com_err(prog_name, retval, _("while retrieving creds from cache")); goto cleanup; } } else{ got_it = 1; } if (! got_it){ #ifdef GET_TGT_VIA_PASSWD if (krb5_seteuid(0)||krb5_seteuid(target_uid)) { com_err("ksu", errno, _("while switching to target uid")); goto cleanup; } fprintf(stderr, _("WARNING: Your password may be exposed if you enter " "it here and are logged \n")); fprintf(stderr, _(" in remotely using an unsecure " "(non-encrypted) channel. \n")); /*get the ticket granting ticket, via passwd(prompt for passwd)*/ if (ksu_get_tgt_via_passwd(context, client, options, &zero_password, &tgt) == FALSE) { krb5_seteuid(0); goto cleanup; } *path_passwd = 1; if (krb5_seteuid(0)) { com_err("ksu", errno, _("while reclaiming root uid")); goto cleanup; } #else plain_dump_principal (context, client); fprintf(stderr, _("does not have any appropriate tickets in the cache.\n")); goto cleanup; #endif /* GET_TGT_VIA_PASSWD */ } krb5_verify_init_creds_opt_init(&vfy_opts); krb5_verify_init_creds_opt_set_ap_req_nofail( &vfy_opts, 1); retval = krb5_verify_init_creds(context, &tgt, NULL, NULL, NULL, &vfy_opts); if (retval) { com_err(prog_name, retval, _("while verifying ticket for server")); goto cleanup; } ok = TRUE; cleanup: krb5_free_principal(context, client); krb5_free_cred_contents(context, &tgt); krb5_free_cred_contents(context, &tgtq); return ok; } krb5_boolean ksu_get_tgt_via_passwd(krb5_context context, krb5_principal client, krb5_get_init_creds_opt *options, krb5_boolean *zero_password, krb5_creds *creds_out) { krb5_boolean ok = FALSE; krb5_error_code code; krb5_creds creds = { 0 }; krb5_timestamp now; unsigned int pwsize; char password[255], prompt[255], *client_name = NULL; int result; *zero_password = FALSE; if (creds_out != NULL) memset(creds_out, 0, sizeof(*creds_out)); if ((code = krb5_unparse_name(context, client, &client_name))) { com_err (prog_name, code, _("when unparsing name")); goto cleanup; } memset(&creds, 0, sizeof(creds)); if ((code = krb5_timeofday(context, &now))) { com_err(prog_name, code, _("while getting time of day")); goto cleanup; } result = snprintf(prompt, sizeof(prompt), _("Kerberos password for %s: "), client_name); if (SNPRINTF_OVERFLOW(result, sizeof(prompt))) { fprintf(stderr, _("principal name %s too long for internal buffer space\n"), client_name); goto cleanup; } pwsize = sizeof(password); code = krb5_read_password(context, prompt, 0, password, &pwsize); if (code ) { com_err(prog_name, code, _("while reading password for '%s'\n"), client_name); goto cleanup; } if ( pwsize == 0) { fprintf(stderr, _("No password given\n")); *zero_password = TRUE; goto cleanup; } code = krb5_get_init_creds_password(context, &creds, client, password, krb5_prompter_posix, NULL, 0, NULL, options); zap(password, sizeof(password)); if (code) { if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) fprintf(stderr, _("%s: Password incorrect\n"), prog_name); else com_err(prog_name, code, _("while getting initial credentials")); goto cleanup; } if (creds_out != NULL) { *creds_out = creds; memset(&creds, 0, sizeof(creds)); } ok = TRUE; cleanup: krb5_free_cred_contents(context, &creds); free(client_name); return ok; } void dump_principal(krb5_context context, char *str, krb5_principal p) { char * stname; krb5_error_code retval; if ((retval = krb5_unparse_name(context, p, &stname))) { fprintf(stderr, _(" %s while unparsing name\n"), error_message(retval)); return; } fprintf(stderr, " %s: %s\n", str, stname); free(stname); } void plain_dump_principal (krb5_context context, krb5_principal p) { char * stname; krb5_error_code retval; if ((retval = krb5_unparse_name(context, p, &stname))) { fprintf(stderr, _(" %s while unparsing name\n"), error_message(retval)); return; } fprintf(stderr, "%s ", stname); free(stname); } krb5-1.22.1/src/clients/ksu/t_ksu.py0000664000175000017500000002465115051422640017102 0ustar ghudsonghudsonfrom k5test import * import pwd import stat krb5_conf = '/etc/krb5.conf' krb5_conf_save = krb5_conf + '.save-ksutest' krb5_conf_nosave = krb5_conf + '.nosave-ksutest' ksu = './ksu.ksutest' if 'SUDO_UID' not in os.environ or os.geteuid() != 0: fail('this script must be run as root via sudo') caller_uid = int(os.environ['SUDO_UID']) if caller_uid == 0: fail('the user invoking sudo must not be root') caller_username = os.environ['SUDO_USER'] os.chown('testlog', caller_uid, -1) # Set the real and effective UIDs to the calling user, but preserve # the ability to restore root privileges. def be_caller(): os.setresuid(caller_uid, caller_uid, 0) # Restore root privileges. def be_root(): os.setresuid(0, 0, 0) # Remove the ksutest account. def cleanup_user(): # userdel commonly gives a warning about being unable to delete # the mail spool; filter it out. out = subprocess.check_output(['userdel', '-r', 'ksutest'], stderr=subprocess.STDOUT) if out.count(b'\n') > 1 or b'ksutest mail spool' not in out: print(out) # Restore /etc/krb5.conf to the state it was in previously. def cleanup_krb5_conf(): if os.path.exists(krb5_conf_save): os.unlink(krb5_conf) os.rename(krb5_conf_save, krb5_conf) elif os.path.exists(krb5_conf_nosave): os.unlink(krb5_conf) os.unlink(krb5_conf_nosave) def onexit(): if len(sys.argv) >= 2 and sys.argv[1] == 'nocleanup': return be_root() cleanup_user() cleanup_krb5_conf() if os.path.exists(ksu): os.unlink(ksu) # Create a ksutest account and return its home directory. def setup_user(): try: ent = pwd.getpwnam('ksutest') return ent.pw_dir except KeyError: subprocess.check_call(['useradd', '-m', '-r', 'ksutest']) return pwd.getpwnam('ksutest').pw_dir # Make krb5.conf a copy of realm's krb5.conf file. Save the old # contents in krb5_conf_save, or create krb5_conf_noexist to indicate # that the file didn't previously exist. def setup_krb5_conf(realm): if not os.path.exists(krb5_conf): open(krb5_conf_nosave, 'w').close() elif not os.path.exists(krb5_conf_save): os.rename(krb5_conf, krb5_conf_save) shutil.copyfile(os.path.join(realm.testdir, 'krb5.conf'), krb5_conf) # Temporarily acting as root, write a file named fname in ksutest's # home directory with the given contents. If wrong_owner is set, make # the file owned by the caller uid in order to trip ksu's owner check. def write_authz_file(fname, contents, wrong_owner=False): be_root() path = os.path.join(ksutest_home, fname) with open(path, 'w') as f: f.write('\n'.join(contents) + '\n') if wrong_owner: os.chown(path, caller_uid, -1) be_caller() # Temporarily acting as root, remove fname from ksutest's home # directory. def remove_authz_file(fname): be_root() path = os.path.join(ksutest_home, fname) if os.path.exists(path): os.remove(path) be_caller() be_caller() # Set up a realm. Set default_keytab_name since ksu won't respect the # KRB5_KTNAME environment variable. keytab = os.path.join(os.getcwd(), 'testdir', 'keytab') realm = K5Realm(create_user=False, krb5_conf={'libdefaults': {'default_keytab_name': keytab}}) realm.addprinc('alice', 'pwalice') realm.addprinc('ksutest', 'pwksutest') realm.addprinc('ksutest/root', 'pwroot') realm.addprinc(caller_username, 'pwcaller') # Root setup: # - /etc/krb5.conf is a copy of the test realm krb5.conf # - a newly created user named ksutest exists (with homedir ksutest_home) # - a setuid copy of ksu exists in the build dir # Register an atexit handler to undo these changes. atexit.register(onexit) be_root() ksutest_home = setup_user() setup_krb5_conf(realm) if os.path.exists(ksu): os.unlink(ksu) shutil.copyfile('ksu', ksu) os.chmod(ksu, 0o4755) be_caller() mark('no authorization') realm.kinit('alice', 'pwalice') realm.run([ksu, 'ksutest', '-n', 'alice', '-a', '-c', klist], expected_code=1, expected_msg='authorization of alice@KRBTEST.COM failed') mark('an2ln authorization') realm.kinit('ksutest', 'pwksutest') realm.run([ksu, 'ksutest', '-a', '-c', klist], expected_msg='authorization for ksutest@KRBTEST.COM successful') realm.run([ksu, 'ksutest', '-e', klist], expected_code=1, expected_msg='account ksutest: authorization failed') mark('.k5login wrong owner') write_authz_file('.k5login', ['ksutest@KRBTEST.COM'], wrong_owner=True) realm.run([ksu, 'ksutest', '-e', klist], expected_code=1, expected_msg='account ksutest: authorization failed') remove_authz_file('.k5login') mark('.k5users wrong owner') write_authz_file('.k5users', ['ksutest@KRBTEST.COM'], wrong_owner=True) realm.run([ksu, 'ksutest', '-e', klist], expected_code=1, expected_msg='account ksutest: authorization failed') remove_authz_file('.k5users') mark('.k5login authorization') realm.kinit('alice', 'pwalice') write_authz_file('.k5login', ['alice@KRBTEST.COM']) realm.run([ksu, 'ksutest', '-a', '-c', klist], expected_msg='authorization for alice@KRBTEST.COM successful') realm.run([ksu, 'ksutest', '-e', klist], expected_msg='authorization for alice@KRBTEST.COM for execution of') write_authz_file('.k5login', ['bob@KRBTEST.COM']) realm.run([ksu, 'ksutest', '-a', '-c', klist], expected_code=1, expected_msg='account ksutest: authorization failed') remove_authz_file('.k5login') mark('.k5users authorization (no second field)') write_authz_file('.k5users', ['alice@KRBTEST.COM']) realm.run([ksu, 'ksutest', '-a', '-c', klist], expected_msg='authorization for alice@KRBTEST.COM successful') realm.run([ksu, 'ksutest', '-e', klist], expected_code=1, expected_msg='account ksutest: authorization failed') write_authz_file('.k5users', ['bob@KRBTEST.COM']) realm.run([ksu, 'ksutest', '-a', '-c', klist], expected_code=1, expected_msg='account ksutest: authorization failed') mark('k5users authorization (wildcard)') write_authz_file('.k5users', ['alice@KRBTEST.COM *']) realm.run([ksu, 'ksutest', '-a', '-c', klist], expected_msg='authorization for alice@KRBTEST.COM successful') realm.run([ksu, 'ksutest', '-e', klist], expected_msg='authorization for alice@KRBTEST.COM for execution of') mark('k5users authorization (command list)') write_authz_file('.k5users', ['alice@KRBTEST.COM doesnotexist ' + klist]) realm.run([ksu, 'ksutest', '-a', '-c', klist], expected_code=1, expected_msg='account ksutest: authorization failed') realm.run([ksu, 'ksutest', '-e', klist], expected_msg='authorization for alice@KRBTEST.COM for execution of') realm.run([ksu, 'ksutest', '-e', kvno], expected_code=1, expected_msg='account ksutest: authorization failed') realm.run([ksu, 'ksutest', '-e', 'doesnotexist'], expected_code=1, expected_msg='Error: not found ->') remove_authz_file('.k5users') mark('principal heuristic (no authz files)') realm.run([ksu, 'ksutest', '-a', '-c', klist], input='pwksutest\n', expected_msg='Authenticated ksutest@KRBTEST.COM') realm.run([ksu, 'ksutest', '-e', klist], expected_code=1, expected_msg='account ksutest: authorization failed') mark('principal heuristic (empty authz files)') write_authz_file('.k5login', []) write_authz_file('.k5users', []) realm.run([ksu, 'ksutest', '-e', klist], expected_code=1, expected_msg='account ksutest: authorization failed') remove_authz_file('.k5login') remove_authz_file('.k5users') # Untested: if the ccache default principal is not authorized, # get_best_princ_for_target() looks for a TGT or host service ticket # for the target and source users (if authorized) or any other # authorized user. This is not really useful because a ccache usually # only contains tickets for its default client principal (aside from # caches created for S4U2Proxy). If the heuristic is ever changed to # search the cache collection instead of only the primary cache, we # should add tests for that here. mark('principal heuristic (.k5login)') write_authz_file('.k5login', ['ksutest@KRBTEST.COM']) realm.run([ksu, 'ksutest', '-a', '-c', klist], input='pwksutest\n', expected_msg='Authenticated ksutest@KRBTEST.COM') realm.run([ksu, 'ksutest', '-e', klist], input='pwksutest\n', expected_msg='Authenticated ksutest@KRBTEST.COM') write_authz_file('.k5login', [caller_username + '@KRBTEST.COM']) realm.run([ksu, 'ksutest', '-e', klist], input='pwcaller\n', expected_msg='Authenticated %s@KRBTEST.COM' % caller_username) remove_authz_file('.k5login') mark('principal heuristic (.k5users)') write_authz_file('.k5users', ['alice@KRBTEST.COM ' + klist, 'ksutest@KRBTEST.COM', caller_username + '@KRBTEST.COM *']) realm.run([ksu, 'ksutest', '-e', klist], expected_msg='Authenticated alice@KRBTEST.COM') realm.run([ksu, 'ksutest', '-a', '-c', klist], input='pwksutest\n', expected_msg='Authenticated ksutest@KRBTEST.COM') realm.run([ksu, 'ksutest', '-e', kvno, 'alice'], input='pwcaller\n', expected_msg='Authenticated %s@KRBTEST.COM' % caller_username) write_authz_file('.k5users', ['alice@KRBTEST.COM ' + klist, 'ksutest/root@KRBTEST.COM ' + kvno]) realm.run([ksu, 'ksutest', '-e', kvno, 'alice'], input='pwroot\n', expected_msg='Authenticated ksutest/root@KRBTEST.COM') mark('principal heuristic (no authorization)') realm.run([ksu, '.', '-e', klist], expected_msg='Default principal: alice@KRBTEST.COM') be_root() realm.run([ksu, 'ksutest', '-e', klist], expected_code=1, expected_msg='No credentials cache found') be_caller() realm.kinit('ksutest', 'pwksutest') be_root() realm.run([ksu, 'ksutest', '-e', klist], expected_msg='Default principal: ksutest@KRBTEST.COM') be_caller() realm.run([kdestroy]) realm.run([ksu, '.', '-e', klist], expected_code=1, expected_msg='No credentials cache found') mark('authentication without authorization') realm.run([ksu, '.', '-n', 'ksutest', '-e', klist], input='pwksutest\n', expected_msg='Leaving uid as ' + caller_username) # It's hard to make this flag do anything detectable, but we can # exercise the code. mark('-z flag') realm.kinit(caller_username, 'pwcaller') realm.run([ksu, '.', '-z', '-e', klist], expected_msg='Default principal: ' + caller_username) realm.run([ksu, '.', '-Z', '-e', klist], expected_code=1, expected_msg='No credentials cache found') success('ksu tests') krb5-1.22.1/src/clients/ksu/xmalloc.c0000664000175000017500000000442615051422640017204 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* clients/ksu/xmalloc.c - Exit-on-failure allocation wrappers */ /* * Copyright 1999 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-platform.h" #include "ksu.h" void *xmalloc (size_t sz) { void *ret = malloc (sz); if (ret == 0 && sz != 0) { perror (prog_name); exit (1); } return ret; } void *xrealloc (void *old, size_t newsz) { void *ret = realloc (old, newsz); if (ret == 0 && newsz != 0) { perror (prog_name); exit (1); } return ret; } void *xcalloc (size_t nelts, size_t eltsz) { void *ret = calloc (nelts, eltsz); if (ret == 0 && nelts != 0 && eltsz != 0) { perror (prog_name); exit (1); } return ret; } char *xstrdup (const char *src) { size_t len = strlen (src) + 1; char *dst = xmalloc (len); memcpy (dst, src, len); return dst; } char *xasprintf (const char *format, ...) { char *out; va_list args; va_start (args, format); if (vasprintf(&out, format, args) < 0) { perror (prog_name); exit (1); } va_end(args); return out; } krb5-1.22.1/src/clients/ksu/main.c0000664000175000017500000010171015051422640016463 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 1994 by the University of Southern California * * EXPORT OF THIS SOFTWARE from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute * this software and its documentation in source and binary forms is * hereby granted, provided that any documentation or other materials * related to such distribution or use acknowledge that the software * was developed by the University of Southern California. * * DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The * University of Southern California MAKES NO REPRESENTATIONS OR * WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not * limitation, the University of Southern California MAKES NO * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY * PARTICULAR PURPOSE. The University of Southern * California shall not be held liable for any liability nor for any * direct, indirect, or consequential damages with respect to any * claim by the user or distributor of the ksu software. * * KSU was written by: Ari Medvinsky, ari@isi.edu */ #include "ksu.h" #include "adm_proto.h" #include #include #include #include /* globals */ char * prog_name; int auth_debug =0; char k5login_path[MAXPATHLEN]; char k5users_path[MAXPATHLEN]; char * gb_err = NULL; int quiet = 0; /***********/ #define KS_TEMPORARY_CACHE "MEMORY:_ksu" #define KS_TEMPORARY_PRINC "_ksu/_ksu@_ksu" #define _DEF_CSH "/bin/csh" static int set_env_var (char *, char *); static void sweep_up (krb5_context, krb5_ccache); static char * ontty (void); static krb5_error_code init_ksu_context(krb5_context *); static krb5_error_code set_ccname_env(krb5_context, krb5_ccache); static void print_status( const char *fmt, ...) #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) __attribute__ ((__format__ (__printf__, 1, 2))) #endif ; static krb5_error_code resolve_target_cache(krb5_context ksu_context, krb5_principal princ, krb5_ccache *ccache_out, krb5_boolean *ccache_reused); /* Note -e and -a options are mutually exclusive */ /* insure the proper specification of target user as well as catching ill specified arguments to commands */ void usage(void) { fprintf(stderr, _("Usage: %s [target user] [-n principal] [-c source cachename] " "[-k] [-r time] [-p|-P] [-f|-F] [-l lifetime] [-zZ] [-q] " "[-e command [args... ] ] [-a [args... ] ]\n"), prog_name); } /* for Ultrix and friends ... */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif /* These are file static so sweep_up can get to them*/ static uid_t source_uid, target_uid; int main(int argc, char ** argv) { int hp =0; int some_rest_copy = 0; int all_rest_copy = 0; char *localhostname = NULL; krb5_get_init_creds_opt *options = NULL; int option=0; int statusp=0; krb5_error_code retval = 0; krb5_principal client = NULL, tmp_princ = NULL; krb5_ccache cc_tmp = NULL, cc_target = NULL; krb5_context ksu_context; char * cc_target_tag = NULL; char * target_user = NULL; char * source_user; krb5_ccache cc_source = NULL; const char * cc_source_tag = NULL; char * cmd = NULL, * exec_cmd = NULL; int errflg = 0; krb5_boolean auth_val; krb5_boolean authorization_val = FALSE; int path_passwd = 0; int done =0,i,j; uid_t ruid = getuid (); struct passwd *pwd=NULL, *target_pwd ; char * shell; char ** params; int keep_target_cache = 0; int child_pid, child_pgrp, ret_pid; int pargc; char ** pargv; krb5_boolean stored = FALSE, cc_reused = FALSE, given_princ = FALSE; krb5_boolean zero_password; krb5_boolean restrict_creds; krb5_deltat lifetime, rlife; if (argc == 0) exit(1); params = (char **) xcalloc (2, sizeof (char *)); params[1] = NULL; unsetenv ("KRB5_CONFIG"); retval = init_ksu_context(&ksu_context); if (retval) { com_err(argv[0], retval, _("while initializing krb5")); exit(1); } retval = krb5_get_init_creds_opt_alloc(ksu_context, &options); if (retval) { com_err(argv[0], retval, _("while initializing krb5")); exit(1); } if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; prog_name = argv[0]; if (strlen (prog_name) > 50) { /* this many chars *after* last / ?? */ com_err(prog_name, 0, _("program name too long - quitting to avoid triggering " "system logging bugs")); exit (1); } #ifndef LOG_NDELAY #define LOG_NDELAY 0 #endif #ifndef LOG_AUTH /* 4.2 syslog */ openlog(prog_name, LOG_PID|LOG_NDELAY); #else openlog(prog_name, LOG_PID | LOG_NDELAY, LOG_AUTH); #endif /* 4.2 syslog */ if (( argc == 1) || (argv[1][0] == '-')){ target_user = xstrdup("root"); pargc = argc; pargv = argv; } else { target_user = xstrdup(argv[1]); pargc = argc -1; if ((pargv =(char **) calloc(pargc +1,sizeof(char *)))==NULL){ com_err(prog_name, errno, _("while allocating memory")); exit(1); } pargv[pargc] = NULL; pargv[0] = argv[0]; for(i =1; i< pargc; i ++){ pargv[i] = argv[i + 1]; } } if (krb5_seteuid (ruid)) { com_err (prog_name, errno, _("while setting euid to source user")); exit (1); } while (!done && (option = getopt(pargc, pargv,"n:c:r:a:zZDfFpPkql:e:")) != -1) { switch (option) { case 'r': if (strlen (optarg) >= 14) optarg = "bad-time"; retval = krb5_string_to_deltat(optarg, &rlife); if (retval != 0 || rlife == 0) { fprintf(stderr, _("Bad lifetime value (%s hours?)\n"), optarg); errflg++; } krb5_get_init_creds_opt_set_renew_life(options, rlife); break; case 'a': /* when integrating this remember to pass in pargc, pargv and take care of params argument */ optind --; if (auth_debug){printf("Before get_params optind=%d\n", optind);} if ((retval = get_params( & optind, pargc, pargv, ¶ms))){ com_err(prog_name, retval, _("when gathering parameters")); errflg++; } if(auth_debug){ printf("After get_params optind=%d\n", optind);} done = 1; break; case 'p': krb5_get_init_creds_opt_set_proxiable(options, 1); break; case 'P': krb5_get_init_creds_opt_set_proxiable(options, 0); break; case 'f': krb5_get_init_creds_opt_set_forwardable(options, 1); break; case 'F': krb5_get_init_creds_opt_set_forwardable(options, 0); break; case 'k': keep_target_cache =1; break; case 'q': quiet =1; break; case 'l': if (strlen (optarg) >= 14) optarg = "bad-time"; retval = krb5_string_to_deltat(optarg, &lifetime); if (retval != 0 || lifetime == 0) { fprintf(stderr, _("Bad lifetime value (%s hours?)\n"), optarg); errflg++; } krb5_get_init_creds_opt_set_tkt_life(options, lifetime); break; case 'n': if ((retval = krb5_parse_name(ksu_context, optarg, &client))){ com_err(prog_name, retval, _("when parsing name %s"), optarg); errflg++; } given_princ = TRUE; break; #ifdef DEBUG case 'D': auth_debug = 1; break; #endif case 'z': some_rest_copy = 1; if(all_rest_copy) { fprintf(stderr, _("-z option is mutually exclusive with -Z.\n")); errflg++; } break; case 'Z': all_rest_copy = 1; if(some_rest_copy) { fprintf(stderr, _("-Z option is mutually exclusive with -z.\n")); errflg++; } break; case 'c': if (cc_source_tag == NULL) { cc_source_tag = xstrdup(optarg); if (!ks_ccache_name_is_initialized(ksu_context, cc_source_tag)) { com_err(prog_name, errno, _("while looking for credentials cache %s"), cc_source_tag); exit(1); } } else { fprintf(stderr, _("Only one -c option allowed\n")); errflg++; } break; case 'e': cmd = xstrdup(optarg); if(auth_debug){printf("Before get_params optind=%d\n", optind);} if ((retval = get_params( & optind, pargc, pargv, ¶ms))){ com_err(prog_name, retval, _("when gathering parameters")); errflg++; } if(auth_debug){printf("After get_params optind=%d\n", optind);} done = 1; if (auth_debug){ fprintf(stderr,"Command to be executed: %s\n", cmd); } break; case '?': default: errflg++; break; } } if (errflg) { usage(); exit(2); } if (optind != pargc ){ usage(); exit(2); } if (auth_debug){ for(j=1; params[j] != NULL; j++){ fprintf (stderr,"params[%d]= %s\n", j,params[j]); } } /***********************************/ source_user = getlogin(); /*checks for the the login name in /etc/utmp*/ /* verify that that the user exists and get his passwd structure */ if (source_user == NULL ||(pwd = getpwnam(source_user)) == NULL || pwd->pw_uid != ruid){ pwd = getpwuid(ruid); } if (pwd == NULL) { fprintf(stderr, _("ksu: who are you?\n")); exit(1); } if (pwd->pw_uid != ruid) { fprintf (stderr, _("Your uid doesn't match your passwd entry?!\n")); exit (1); } /* Okay, now we have *some* passwd entry that matches the current real uid. */ /* allocate space and copy the usernamane there */ source_user = xstrdup(pwd->pw_name); source_uid = pwd->pw_uid; if (!strcmp(SOURCE_USER_LOGIN, target_user)){ target_user = xstrdup (source_user); } if ((target_pwd = getpwnam(target_user)) == NULL){ fprintf(stderr, _("ksu: unknown login %s\n"), target_user); exit(1); } target_uid = target_pwd->pw_uid; init_auth_names(target_pwd->pw_dir); /***********************************/ if (cc_source_tag == NULL){ cc_source_tag = krb5_cc_default_name(ksu_context); if (cc_source_tag == NULL) { fprintf(stderr, _("ksu: failed to get default ccache name\n")); exit(1); } } /* get a handle for the cache */ if ((retval = krb5_cc_resolve(ksu_context, cc_source_tag, &cc_source))){ com_err(prog_name, retval, _("while getting source cache")); exit(1); } if ((retval = get_best_princ_for_target(ksu_context, source_uid, target_uid, source_user, target_user, cc_source, options, cmd, localhostname, &client, &hp))){ com_err(prog_name,retval, _("while selecting the best principal")); exit(1); } /* We may be running as either source or target, depending on what happened; become source.*/ if ( geteuid() != source_uid) { if (krb5_seteuid(0) || krb5_seteuid(source_uid) ) { com_err(prog_name, errno, _("while returning to source uid after " "finding best principal")); exit(1); } } if (auth_debug){ if (hp){ fprintf(stderr, "GET_best_princ_for_target result: NOT AUTHORIZED\n"); }else{ fprintf(stderr, "GET_best_princ_for_target result-best principal "); plain_dump_principal (ksu_context, client); fprintf(stderr,"\n"); } } if (hp){ if (gb_err) fprintf(stderr, "%s", gb_err); fprintf(stderr, _("account %s: authorization failed\n"), target_user); if (cmd != NULL) { syslog(LOG_WARNING, "Account %s: authorization for %s for execution of %s failed", target_user, source_user, cmd); } else { syslog(LOG_WARNING, "Account %s: authorization of %s failed", target_user, source_user); } exit(1); } if (auth_debug) fprintf(stderr, " source cache = %s\n", cc_source_tag); /* * After proper authentication and authorization, populate a cache for the * target user. */ /* * We read the set of creds we want to copy from the source ccache as the * source uid, become root for authentication, and then become the target * user to handle authorization and creating the target user's cache. */ /* if root ksu's to a regular user, then then only the credentials for that particular user should be copied */ restrict_creds = (source_uid == 0) && (target_uid != 0); retval = krb5_parse_name(ksu_context, KS_TEMPORARY_PRINC, &tmp_princ); if (retval) { com_err(prog_name, retval, _("while parsing temporary name")); exit(1); } retval = krb5_cc_resolve(ksu_context, KS_TEMPORARY_CACHE, &cc_tmp); if (retval) { com_err(prog_name, retval, _("while creating temporary cache")); exit(1); } retval = krb5_ccache_copy(ksu_context, cc_source, tmp_princ, cc_tmp, restrict_creds, client, &stored); if (retval) { com_err(prog_name, retval, _("while copying cache %s to %s"), krb5_cc_get_name(ksu_context, cc_source), KS_TEMPORARY_CACHE); exit(1); } krb5_cc_close(ksu_context, cc_source); krb5_get_init_creds_opt_set_out_ccache(ksu_context, options, cc_tmp); /* Become root for authentication*/ if (krb5_seteuid(0)) { com_err(prog_name, errno, _("while reclaiming root uid")); exit(1); } if ((source_uid == 0) || (target_uid == source_uid)){ #ifdef GET_TGT_VIA_PASSWD if (!all_rest_copy && given_princ && client != NULL && !stored) { fprintf(stderr, _("WARNING: Your password may be exposed if you " "enter it here and are logged\n")); fprintf(stderr, _(" in remotely using an unsecure " "(non-encrypted) channel.\n")); if (ksu_get_tgt_via_passwd(ksu_context, client, options, &zero_password, NULL) == FALSE) { if (zero_password == FALSE){ fprintf(stderr, _("Goodbye\n")); exit(1); } fprintf(stderr, _("Could not get a tgt for ")); plain_dump_principal (ksu_context, client); fprintf(stderr, "\n"); } stored = TRUE; } #endif /* GET_TGT_VIA_PASSWD */ } /* if the user is root or same uid then authentication is not necessary, root gets in automatically */ if (source_uid && (source_uid != target_uid)) { char * client_name; auth_val = krb5_auth_check(ksu_context, client, localhostname, options, target_user, cc_tmp, &path_passwd, target_uid); /* if Kerberos authentication failed then exit */ if (auth_val ==FALSE){ fprintf(stderr, _("Authentication failed.\n")); syslog(LOG_WARNING, "'%s %s' authentication failed for %s%s", prog_name,target_user,source_user,ontty()); exit(1); } stored = TRUE; if ((retval = krb5_unparse_name(ksu_context, client, &client_name))) { com_err(prog_name, retval, _("When unparsing name")); exit(1); } print_status(_("Authenticated %s\n"), client_name); syslog(LOG_NOTICE,"'%s %s' authenticated %s for %s%s", prog_name,target_user,client_name, source_user,ontty()); /* Run authorization as target.*/ if (krb5_seteuid(target_uid)) { com_err(prog_name, errno, _("while switching to target for " "authorization check")); exit(1); } if ((retval = krb5_authorization(ksu_context, client,target_user, cmd, &authorization_val, &exec_cmd))){ com_err(prog_name,retval, _("while checking authorization")); krb5_seteuid(0); /*So we have some chance of sweeping up*/ exit(1); } if (krb5_seteuid(0)) { com_err(prog_name, errno, _("while switching back from target " "after authorization check")); exit(1); } if (authorization_val == TRUE){ if (cmd) { print_status(_("Account %s: authorization for %s for " "execution of\n"), target_user, client_name); print_status(_(" %s successful\n"), exec_cmd); syslog(LOG_NOTICE, "Account %s: authorization for %s for execution of %s successful", target_user, client_name, exec_cmd); }else{ print_status(_("Account %s: authorization for %s " "successful\n"), target_user, client_name); syslog(LOG_NOTICE, "Account %s: authorization for %s successful", target_user, client_name); } }else { if (cmd){ if (exec_cmd){ /* was used to pass back the error msg */ fprintf(stderr, "%s", exec_cmd ); syslog(LOG_WARNING, "%s",exec_cmd); } fprintf(stderr, _("Account %s: authorization for %s for " "execution of %s failed\n"), target_user, client_name, cmd ); syslog(LOG_WARNING, "Account %s: authorization for %s for execution of %s failed", target_user, client_name, cmd ); }else{ fprintf(stderr, _("Account %s: authorization of %s failed\n"), target_user, client_name); syslog(LOG_WARNING, "Account %s: authorization of %s failed", target_user, client_name); } exit(1); } } if( some_rest_copy){ retval = krb5_ccache_filter(ksu_context, cc_tmp, client); if (retval) { com_err(prog_name,retval, _("while calling cc_filter")); exit(1); } } if (all_rest_copy){ retval = krb5_cc_initialize(ksu_context, cc_tmp, tmp_princ); if (retval) { com_err(prog_name, retval, _("while erasing target cache")); exit(1); } stored = FALSE; } /* get the shell of the user, this will be the shell used by su */ target_pwd = getpwnam(target_user); if (target_pwd->pw_shell) shell = xstrdup(target_pwd->pw_shell); else { shell = _DEF_CSH; /* default is cshell */ } #ifdef HAVE_GETUSERSHELL /* insist that the target login uses a standard shell (root is omitted) */ if (!standard_shell(target_pwd->pw_shell) && source_uid) { fprintf(stderr, _("ksu: permission denied (shell).\n")); exit(1); } #endif /* HAVE_GETUSERSHELL */ if (target_pwd->pw_uid){ if(set_env_var("USER", target_pwd->pw_name)){ fprintf(stderr, _("ksu: couldn't set environment variable USER\n")); exit(1); } } if(set_env_var( "HOME", target_pwd->pw_dir)){ fprintf(stderr, _("ksu: couldn't set environment variable HOME\n")); exit(1); } if(set_env_var( "SHELL", shell)){ fprintf(stderr, _("ksu: couldn't set environment variable SHELL\n")); exit(1); } /* set permissions */ if (setgid(target_pwd->pw_gid) < 0) { perror("ksu: setgid"); exit(1); } if (initgroups(target_user, target_pwd->pw_gid)) { fprintf(stderr, _("ksu: initgroups failed.\n")); exit(1); } if ( ! strcmp(target_user, source_user)){ print_status(_("Leaving uid as %s (%ld)\n"), target_user, (long) target_pwd->pw_uid); }else{ print_status(_("Changing uid to %s (%ld)\n"), target_user, (long) target_pwd->pw_uid); } #ifdef HAVE_SETLUID /* * If we're on a system which keeps track of login uids, then * set the login uid. If this fails this opens up a problem on DEC OSF * with C2 enabled. */ if (setluid((uid_t) pwd->pw_uid) < 0) { perror("setluid"); exit(1); } #endif /* HAVE_SETLUID */ if (setuid(target_pwd->pw_uid) < 0) { perror("ksu: setuid"); exit(1); } retval = resolve_target_cache(ksu_context, client, &cc_target, &cc_reused); if (retval) exit(1); retval = krb5_cc_get_full_name(ksu_context, cc_target, &cc_target_tag); if (retval) { com_err(prog_name, retval, _("while getting name of target ccache")); sweep_up(ksu_context, cc_target); exit(1); } if (auth_debug) fprintf(stderr, " target cache = %s\n", cc_target_tag); if (cc_reused) keep_target_cache = TRUE; if (stored) { retval = krb5_ccache_copy(ksu_context, cc_tmp, client, cc_target, FALSE, client, &stored); if (retval) { com_err(prog_name, retval, _("while copying cache %s to %s"), KS_TEMPORARY_CACHE, cc_target_tag); exit(1); } if (!ks_ccache_is_initialized(ksu_context, cc_target)) { com_err(prog_name, errno, _("%s does not have correct permissions for %s, " "%s aborted"), target_user, cc_target_tag, prog_name); exit(1); } } krb5_free_string(ksu_context, cc_target_tag); /* Set the cc env name to target. */ retval = set_ccname_env(ksu_context, cc_target); if (retval != 0) { sweep_up(ksu_context, cc_target); exit(1); } if (cmd){ if ((source_uid == 0) || (source_uid == target_uid )){ exec_cmd = cmd; } if( !exec_cmd){ fprintf(stderr, _("Internal error: command %s did not get " "resolved\n"), cmd); exit(1); } params[0] = exec_cmd; } else{ params[0] = shell; } if (auth_debug){ fprintf(stderr, "program to be execed %s\n",params[0]); } if( keep_target_cache ) { execv(params[0], params); com_err(prog_name, errno, _("while trying to execv %s"), params[0]); sweep_up(ksu_context, cc_target); exit(1); }else{ statusp = 1; switch ((child_pid = fork())) { default: if (auth_debug){ printf(" The child pid is %ld\n", (long) child_pid); printf(" The parent pid is %ld\n", (long) getpid()); } while ((ret_pid = waitpid(child_pid, &statusp, WUNTRACED)) != -1) { if (WIFSTOPPED(statusp)) { child_pgrp = tcgetpgrp(1); kill(getpid(), SIGSTOP); tcsetpgrp(1, child_pgrp); kill(child_pid, SIGCONT); statusp = 1; continue; } break; } if (auth_debug){ printf("The exit status of the child is %d\n", statusp); } if (ret_pid == -1) { com_err(prog_name, errno, _("while calling waitpid")); } sweep_up(ksu_context, cc_target); exit (WIFEXITED(statusp) ? WEXITSTATUS(statusp) : 1); case -1: com_err(prog_name, errno, _("while trying to fork.")); sweep_up(ksu_context, cc_target); exit (1); case 0: execv(params[0], params); com_err(prog_name, errno, _("while trying to execv %s"), params[0]); exit (1); } } } static krb5_error_code init_ksu_context(krb5_context *context_out) { krb5_error_code retval; const char *env_ccname; krb5_context context; *context_out = NULL; retval = krb5_init_secure_context(&context); if (retval) return retval; /* We want to obey KRB5CCNAME in this context even though this is a setuid * program. (It will only be used when operating as the real uid.) */ env_ccname = getenv(KRB5_ENV_CCNAME); if (env_ccname != NULL) { retval = krb5_cc_set_default_name(context, env_ccname); if (retval) { krb5_free_context(context); return retval; } } *context_out = context; return 0; } /* Set KRB5CCNAME in the environment to point to ccache. Print an error * message on failure. */ static krb5_error_code set_ccname_env(krb5_context ksu_context, krb5_ccache ccache) { krb5_error_code retval; char *ccname; retval = krb5_cc_get_full_name(ksu_context, ccache, &ccname); if (retval) { com_err(prog_name, retval, _("while reading cache name from ccache")); return retval; } if (set_env_var(KRB5_ENV_CCNAME, ccname)) { retval = errno; fprintf(stderr, _("ksu: couldn't set environment variable %s\n"), KRB5_ENV_CCNAME); } krb5_free_string(ksu_context, ccname); return retval; } /* * Get the configured default ccache name. Unset KRB5CCNAME and force a * recomputation so we don't use values for the source user. Print an error * message on failure. */ static krb5_error_code get_configured_defccname(krb5_context context, char **target_out) { krb5_error_code retval; const char *defname; char *target = NULL; *target_out = NULL; unsetenv(KRB5_ENV_CCNAME); /* Make sure we don't have a cached value for a different uid. */ retval = krb5_cc_set_default_name(context, NULL); if (retval != 0) { com_err(prog_name, retval, _("while resetting target ccache name")); return retval; } defname = krb5_cc_default_name(context); if (defname != NULL) { if (strchr(defname, ':') != NULL) { target = strdup(defname); } else { if (asprintf(&target, "FILE:%s", defname) < 0) target = NULL; } } if (target == NULL) { com_err(prog_name, ENOMEM, _("while determining target ccache name")); return ENOMEM; } *target_out = target; return 0; } /* Determine where the target user's creds should be stored. Print an error * message on failure. */ static krb5_error_code resolve_target_cache(krb5_context context, krb5_principal princ, krb5_ccache *ccache_out, krb5_boolean *ccache_reused) { krb5_error_code retval; krb5_boolean switchable, reused = FALSE; krb5_ccache ccache = NULL; char *sep, *ccname = NULL, *sym = NULL, *target; *ccache_out = NULL; *ccache_reused = FALSE; retval = get_configured_defccname(context, &target); if (retval != 0) return retval; /* Check if the configured default name uses a switchable type. */ sep = strchr(target, ':'); *sep = '\0'; switchable = krb5_cc_support_switch(context, target); *sep = ':'; if (!switchable) { /* Try to avoid destroying an in-use target ccache by coming up with * the name of a cache that doesn't exist yet. */ do { free(ccname); retval = gen_sym(context, &sym); if (retval) { com_err(prog_name, retval, _("while generating part of the target ccache name")); goto cleanup; } if (asprintf(&ccname, "%s.%s", target, sym) < 0) { retval = ENOMEM; free(sym); com_err(prog_name, retval, _("while allocating memory for the " "target ccache name")); goto cleanup; } free(sym); } while (ks_ccache_name_is_initialized(context, ccname)); retval = krb5_cc_resolve(context, ccname, &ccache); free(ccname); } else { /* Look for a cache in the collection that we can reuse. */ retval = krb5_cc_cache_match(context, princ, &ccache); if (retval == 0) { reused = TRUE; } else { /* There isn't one, so create a new one. */ *sep = '\0'; retval = krb5_cc_new_unique(context, target, NULL, &ccache); *sep = ':'; if (retval) { com_err(prog_name, retval, _("while creating new target ccache")); goto cleanup; } retval = krb5_cc_initialize(context, ccache, princ); if (retval) { com_err(prog_name, retval, _("while initializing target cache")); goto cleanup; } } } *ccache_out = ccache; *ccache_reused = reused; cleanup: free(target); return retval; } #ifdef HAVE_GETUSERSHELL int standard_shell(char *sh) { char *cp; while ((cp = getusershell()) != NULL) if (!strcmp(cp, sh)) return (1); return (0); } #endif /* HAVE_GETUSERSHELL */ static char * ontty(void) { char *p; static char buf[MAXPATHLEN + 5]; int result; buf[0] = 0; if ((p = ttyname(STDERR_FILENO))) { result = snprintf(buf, sizeof(buf), " on %s", p); if (SNPRINTF_OVERFLOW(result, sizeof(buf))) { fprintf(stderr, _("terminal name %s too long\n"), p); exit (1); } } return (buf); } static int set_env_var(char *name, char *value) { char * env_var_buf; asprintf(&env_var_buf,"%s=%s",name, value); return putenv(env_var_buf); } static void sweep_up(krb5_context context, krb5_ccache cc) { krb5_error_code retval; krb5_seteuid(0); if (krb5_seteuid(target_uid) < 0) { com_err(prog_name, errno, _("while changing to target uid for destroying ccache")); exit(1); } if (ks_ccache_is_initialized(context, cc)) { if ((retval = krb5_cc_destroy(context, cc))) com_err(prog_name, retval, _("while destroying cache")); } } /***************************************************************** get_params is to be called for the -a option or -e option to collect all params passed in for the shell or for cmd. An array is returned containing all params. optindex is incremented accordingly and the first element in the returned array is reserved for the name of the command to be executed or the name of the shell. *****************************************************************/ krb5_error_code get_params(int *optindex, int pargc, char **pargv, char ***params) { int i,j; char ** ret_params; int size = pargc - *optindex + 2; if ((ret_params = (char **) calloc(size, sizeof (char *)))== NULL ){ return ENOMEM; } for (i = *optindex, j=1; i < pargc; i++,j++){ ret_params[j] = pargv[i]; *optindex = *optindex + 1; } ret_params[size-1] = NULL; *params = ret_params; return 0; } static void print_status(const char *fmt, ...) { va_list ap; if (! quiet){ va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } } krb5_error_code ksu_tgtname(krb5_context context, const krb5_data *server, const krb5_data *client, krb5_principal *tgtprinc) { return krb5_build_principal_ext(context, tgtprinc, client->length, client->data, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, server->length, server->data, 0); } krb5-1.22.1/src/clients/ksu/heuristic.c0000664000175000017500000004774315051422640017555 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 1994 by the University of Southern California * * EXPORT OF THIS SOFTWARE from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute * this software and its documentation in source and binary forms is * hereby granted, provided that any documentation or other materials * related to such distribution or use acknowledge that the software * was developed by the University of Southern California. * * DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The * University of Southern California MAKES NO REPRESENTATIONS OR * WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not * limitation, the University of Southern California MAKES NO * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY * PARTICULAR PURPOSE. The University of Southern * California shall not be held liable for any liability nor for any * direct, indirect, or consequential damages with respect to any * claim by the user or distributor of the ksu software. * * KSU was written by: Ari Medvinsky, ari@isi.edu */ #include "ksu.h" #ifdef HAVE_UNISTD_H #include #endif /******************************************************************* get_all_princ_from_file - retrieves all principal names from file pointed to by fp. *******************************************************************/ static void close_time (int, FILE *, int, FILE *); static krb5_boolean find_str_in_list (char **, char *); krb5_error_code get_all_princ_from_file(FILE *fp, char ***plist) { krb5_error_code retval; char * line, * fprinc, * lp, ** temp_list = NULL; int count = 0, chunk_count = 1; if (!(temp_list = (char **) malloc( CHUNK * sizeof(char *)))) return ENOMEM; retval = get_line(fp, &line); if (retval) return retval; while (line){ fprinc = get_first_token (line, &lp); if (fprinc ){ temp_list[count] = xstrdup(fprinc); count ++; } if(count == (chunk_count * CHUNK -1)){ chunk_count ++; if (!(temp_list = (char **) realloc(temp_list, chunk_count * CHUNK * sizeof(char *)))){ return ENOMEM; } } free (line); retval = get_line(fp, &line); if (retval) return retval; } temp_list[count] = NULL; *plist = temp_list; return 0; } /************************************************************* list_union - combines list1 and list2 into combined_list. the space for list1 and list2 is either freed or used by combined_list. **************************************************************/ krb5_error_code list_union(char **list1, char **list2, char ***combined_list) { unsigned int c1 =0, c2 = 0, i=0, j=0; char ** tlist; if (! list1){ *combined_list = list2; return 0; } if (! list2){ *combined_list = list1; return 0; } while (list1[c1]) c1++; while (list2[c2]) c2++; if (!(tlist = (char **) calloc( c1 + c2 + 1, sizeof ( char *)))) return ENOMEM; i = 0; while(list1[i]) { tlist[i] = list1[i]; i++; } j = 0; while(list2[j]){ if(find_str_in_list(list1, list2[j])==FALSE){ tlist[i] = list2[j]; i++; } j++; } free (list1); free (list2); tlist[i]= NULL; *combined_list = tlist; return 0; } krb5_error_code filter(FILE *fp, char *cmd, char **k5users_list, char ***k5users_filt_list) { krb5_error_code retval =0; krb5_boolean found = FALSE; char * out_cmd = NULL; unsigned int i=0, j=0, found_count = 0, k=0; char ** temp_filt_list; *k5users_filt_list = NULL; if (k5users_list == NULL) return 0; while(k5users_list[i]){ free(out_cmd); out_cmd = NULL; retval= k5users_lookup(fp, k5users_list[i], cmd, &found, &out_cmd); if (retval) goto cleanup; if (found == FALSE){ free (k5users_list[i]); k5users_list[i] = NULL; if (out_cmd) { gb_err = out_cmd; out_cmd = NULL; } } else found_count ++; i++; } temp_filt_list = xcalloc(found_count + 1, sizeof(*temp_filt_list)); for(j= 0, k=0; j < i; j++ ) { if (k5users_list[j]){ temp_filt_list[k] = k5users_list[j]; k++; } } temp_filt_list[k] = NULL; free (k5users_list); *k5users_filt_list = temp_filt_list; cleanup: free(out_cmd); return retval; } krb5_error_code get_authorized_princ_names(const char *luser, char *cmd, char ***princ_list) { struct passwd *pwd; int k5login_flag =0; int k5users_flag =0; FILE * login_fp = NULL , * users_fp = NULL; char ** k5login_list = NULL, ** k5users_list = NULL; char ** k5users_filt_list = NULL; char ** combined_list = NULL; struct stat tb; krb5_error_code retval; *princ_list = NULL; /* no account => no access */ if ((pwd = getpwnam(luser)) == NULL) return 0; k5login_flag = stat(k5login_path, &tb); k5users_flag = stat(k5users_path, &tb); if (!k5login_flag){ if ((login_fp = fopen(k5login_path, "r")) == NULL) return 0; if ( fowner(login_fp, pwd->pw_uid) == FALSE){ close_time(1 /*k5users_flag*/, (FILE *) 0 /*users_fp*/, k5login_flag,login_fp); return 0; } } if (!k5users_flag){ users_fp = fopen(k5users_path, "r"); if (users_fp == NULL) { close_time(1, NULL, k5login_flag, login_fp); return 0; } if ( fowner(users_fp, pwd->pw_uid) == FALSE){ close_time(k5users_flag,users_fp, k5login_flag,login_fp); return 0; } retval = get_all_princ_from_file (users_fp, &k5users_list); if(retval) { close_time(k5users_flag,users_fp, k5login_flag,login_fp); return retval; } rewind(users_fp); retval = filter(users_fp,cmd, k5users_list, &k5users_filt_list); if(retval) { close_time(k5users_flag,users_fp, k5login_flag, login_fp); return retval; } } if (!k5login_flag){ retval = get_all_princ_from_file (login_fp, &k5login_list); if(retval) { close_time(k5users_flag,users_fp, k5login_flag,login_fp); return retval; } } close_time(k5users_flag,users_fp, k5login_flag, login_fp); retval = list_union(k5login_list, k5users_filt_list, &combined_list); if (retval){ return retval; } *princ_list = combined_list; return 0; } static void close_time(int k5users_flag, FILE *users_fp, int k5login_flag, FILE *login_fp) { if (!k5users_flag) fclose(users_fp); if (!k5login_flag) fclose(login_fp); } static krb5_boolean find_str_in_list(char **list, char *elm) { int i=0; krb5_boolean found = FALSE; if (!list) return found; while (list[i] ){ if (!strcmp(list[i], elm)){ found = TRUE; break; } i++; } return found; } /********************************************************************** returns the principal that is closes to client (can be the the client himself). plist contains a principal list obtained from .k5login and .k5users file. A principal is picked that has the best chance of getting in. **********************************************************************/ krb5_error_code get_closest_principal(krb5_context context, char **plist, krb5_principal *client, krb5_boolean *found) { krb5_error_code retval =0; krb5_principal temp_client, best_client = NULL; int i = 0, j=0, cnelem, pnelem; krb5_boolean got_one; *found = FALSE; if (! plist ) return 0; cnelem = krb5_princ_size(context, *client); while(plist[i]){ retval = krb5_parse_name(context, plist[i], &temp_client); if (retval) goto cleanup; pnelem = krb5_princ_size(context, temp_client); if ( cnelem > pnelem){ i++; continue; } if (data_eq(*krb5_princ_realm(context, *client), *krb5_princ_realm(context, temp_client))) { got_one = TRUE; for(j =0; j < cnelem; j ++){ krb5_data *p1 = krb5_princ_component(context, *client, j); krb5_data *p2 = krb5_princ_component(context, temp_client, j); if (!p1 || !p2 || !data_eq(*p1, *p2)) { got_one = FALSE; break; } } if (got_one == TRUE){ if(best_client){ if(krb5_princ_size(context, best_client) > krb5_princ_size(context, temp_client)){ krb5_free_principal(context, best_client); best_client = temp_client; } }else best_client = temp_client; } } i++; } if (best_client) { *found = TRUE; *client = best_client; best_client = NULL; } cleanup: krb5_free_principal(context, best_client); return retval; } /**************************************************************** find_either_ticket checks to see whether there is a ticket for the end server or tgt, if neither is there the return FALSE, *****************************************************************/ krb5_error_code find_either_ticket(krb5_context context, krb5_ccache cc, krb5_principal client, krb5_principal end_server, krb5_boolean *found) { krb5_principal kdc_server; krb5_error_code retval; krb5_boolean temp_found = FALSE; if (ks_ccache_is_initialized(context, cc)) { retval = find_ticket(context, cc, client, end_server, &temp_found); if (retval) return retval; if (temp_found == FALSE){ retval = ksu_tgtname(context, krb5_princ_realm(context, client), krb5_princ_realm(context, client), &kdc_server); if (retval) return retval; retval = find_ticket(context, cc,client, kdc_server, &temp_found); if(retval) return retval; } else if (auth_debug) printf("find_either_ticket: found end server ticket\n"); } *found = temp_found; return 0; } krb5_error_code find_ticket(krb5_context context, krb5_ccache cc, krb5_principal client, krb5_principal server, krb5_boolean *found) { krb5_creds tgt, tgtq; krb5_error_code retval; *found = FALSE; memset(&tgtq, 0, sizeof(tgtq)); memset(&tgt, 0, sizeof(tgt)); retval= krb5_copy_principal(context, client, &tgtq.client); if (retval) return retval; retval= krb5_copy_principal(context, server, &tgtq.server); if (retval) return retval ; retval = krb5_cc_retrieve_cred(context, cc, KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES, &tgtq, &tgt); if (! retval) retval = krb5_check_exp(context, tgt.times); if (retval){ if ((retval != KRB5_CC_NOTFOUND) && (retval != KRB5KRB_AP_ERR_TKT_EXPIRED)){ return retval ; } } else{ *found = TRUE; return 0; } free(tgtq.server); free(tgtq.client); return 0; } krb5_error_code find_princ_in_list(krb5_context context, krb5_principal princ, char **plist, krb5_boolean *found) { int i=0; char * princname; krb5_error_code retval; *found = FALSE; if (!plist) return 0; retval = krb5_unparse_name(context, princ, &princname); if (retval) return retval; while (plist[i] ){ if (!strcmp(plist[i], princname)){ *found = TRUE; break; } i++; } free(princname); return 0; } typedef struct princ_info { krb5_principal p; krb5_boolean found; }princ_info; /********************************************************************** get_best_princ_for_target - sets the client name, path_out gets set, if authorization is not possible path_out gets set to ... ***********************************************************************/ krb5_error_code get_best_princ_for_target(krb5_context context, uid_t source_uid, uid_t target_uid, char *source_user, char *target_user, krb5_ccache cc_source, krb5_get_init_creds_opt *options, char *cmd, char *hostname, krb5_principal *client, int *path_out) { princ_info princ_trials[10]; krb5_principal cc_def_princ = NULL, temp_client = NULL; krb5_principal target_client = NULL, source_client = NULL; krb5_principal end_server = NULL; krb5_error_code retval; char ** aplist =NULL; krb5_boolean found = FALSE; struct stat tb; int count =0; int i; *path_out = 0; /* -n option was specified client is set we are done */ if (*client != NULL) return 0; if (ks_ccache_is_initialized(context, cc_source)) { retval = krb5_cc_get_principal(context, cc_source, &cc_def_princ); if (retval) goto cleanup; } retval=krb5_parse_name(context, target_user, &target_client); if (retval) goto cleanup; retval=krb5_parse_name(context, source_user, &source_client); if (retval) goto cleanup; if (source_uid == 0) { if (target_uid != 0) { /* This will be used to restrict the cache copy. */ *client = target_client; target_client = NULL; } else if (cc_def_princ != NULL) { *client = cc_def_princ; cc_def_princ = NULL; } else { *client = target_client; target_client = NULL; } if (auth_debug) printf(" GET_best_princ_for_target: via source_uid == 0\n"); goto cleanup; } /* from here on, the code is for source_uid != 0 */ if (source_uid && (source_uid == target_uid)){ if (cc_def_princ != NULL) { *client = cc_def_princ; cc_def_princ = NULL; } else { *client = target_client; target_client = NULL; } if (auth_debug) printf("GET_best_princ_for_target: via source_uid == target_uid\n"); goto cleanup; } /* Become root, then target for looking at .k5login.*/ if (krb5_seteuid(0) || krb5_seteuid(target_uid) ) { retval = errno; goto cleanup; } /* if .k5users and .k5login do not exist */ if (stat(k5login_path, &tb) && stat(k5users_path, &tb) ){ *client = target_client; target_client = NULL; if (cmd) *path_out = NOT_AUTHORIZED; if (auth_debug) printf(" GET_best_princ_for_target: via no auth files path\n"); goto cleanup; }else{ retval = get_authorized_princ_names(target_user, cmd, &aplist); if (retval) goto cleanup; /* .k5users or .k5login exist, but no authorization */ if ((!aplist) || (!aplist[0])) { *path_out = NOT_AUTHORIZED; if (auth_debug) printf("GET_best_princ_for_target: via empty auth files path\n"); goto cleanup; } } retval = krb5_sname_to_principal(context, hostname, NULL, KRB5_NT_SRV_HST, &end_server); if (retval) goto cleanup; /* first see if default principal of the source cache * can get us in, then the target_user@realm, then the * source_user@realm. If all of them fail, try any * other ticket in the cache. */ if (cc_def_princ) princ_trials[count ++].p = cc_def_princ; else princ_trials[count ++].p = NULL; princ_trials[count ++].p = target_client; princ_trials[count ++].p = source_client; for (i= 0; i < count; i ++) princ_trials[i].found = FALSE; for (i= 0; i < count; i ++){ if(princ_trials[i].p) { retval= find_princ_in_list(context, princ_trials[i].p, aplist, &found); if (retval) goto cleanup; if (found == TRUE){ princ_trials[i].found = TRUE; retval = find_either_ticket (context, cc_source, princ_trials[i].p, end_server, &found); if (retval) goto cleanup; if (found == TRUE){ retval = krb5_copy_principal(context, princ_trials[i].p, client); if (auth_debug) printf("GET_best_princ_for_target: via ticket file, choice #%d\n", i); goto cleanup; } } } } /* out of preferred principals, see if there is any ticket that will get us in */ i=0; while (aplist[i]){ retval = krb5_parse_name(context, aplist[i], &temp_client); if (retval) goto cleanup; retval = find_either_ticket (context, cc_source, temp_client, end_server, &found); if (retval) goto cleanup; if (found == TRUE){ if (auth_debug) printf("GET_best_princ_for_target: via ticket file, choice: any ok ticket \n" ); *client = temp_client; temp_client = NULL; goto cleanup; } krb5_free_principal(context, temp_client); temp_client = NULL; i++; } /* no tickets qualified, select a principal, that may be used for password promting */ for (i=0; i < count; i ++){ if (princ_trials[i].found == TRUE){ retval = krb5_copy_principal(context, princ_trials[i].p, client); if (auth_debug) printf("GET_best_princ_for_target: via prompt passwd list choice #%d \n",i); goto cleanup; } } #ifdef PRINC_LOOK_AHEAD for (i=0; i < count; i ++){ if (princ_trials[i].p){ retval=krb5_copy_principal(context, princ_trials[i].p, &temp_client); if(retval) goto cleanup; /* get the client name that is the closest to the three princ in trials */ retval=get_closest_principal(context, aplist, &temp_client, &found); if(retval) goto cleanup; if (found == TRUE){ *client = temp_client; temp_client = NULL; if (auth_debug) printf("GET_best_princ_for_target: via prompt passwd list choice: approximation of princ in trials # %d \n",i); goto cleanup; } } } #endif /* PRINC_LOOK_AHEAD */ if(auth_debug) printf( "GET_best_princ_for_target: out of luck, can't get appropriate default principal\n"); *path_out = NOT_AUTHORIZED; retval = 0; cleanup: krb5_free_principal(context, cc_def_princ); krb5_free_principal(context, target_client); krb5_free_principal(context, source_client); krb5_free_principal(context, temp_client); krb5_free_principal(context, end_server); return retval; } krb5-1.22.1/src/clients/ksu/setenv.c0000664000175000017500000001235515051422640017051 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 1987 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* * Copyright (c) 1987 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* based on @(#)setenv.c 5.2 (Berkeley) 6/27/88 */ #include "autoconf.h" #include #include #include #include static char *_findenv(char *, int *); #ifndef HAVE_SETENV extern int setenv(char *, char *, int); #endif #ifndef HAVE_UNSETENV extern void unsetenv(char *); #endif /* * setenv -- * Set the value of the environmental variable "name" to be * "value". If rewrite is set, replace any current value. */ #ifndef HAVE_SETENV int setenv(name, value, rewrite) char *name, *value; int rewrite; { extern char **environ; static int alloced; /* if allocated space before */ char *C; int l_value, offset; if (*value == '=') /* no `=' in value */ ++value; l_value = strlen(value); if ((C = _findenv(name, &offset))) { /* find if already exists */ if (!rewrite) return(0); if (strlen(C) >= l_value) { /* old larger; copy over */ while ((*C++ = *value++)); return(0); } } else { /* create new slot */ int cnt; char **P; for (P = environ, cnt = 0; *P; ++P, ++cnt); if (alloced) { /* just increase size */ environ = (char **)realloc((char *)environ, (u_int)(sizeof(char *) * (cnt + 2))); if (!environ) return(-1); } else { /* get new space */ alloced = 1; /* copy old entries into it */ P = (char **)malloc((u_int)(sizeof(char *) * (cnt + 2))); if (!P) return(-1); memcpy(P, environ, cnt * sizeof(char *)); environ = P; } environ[cnt + 1] = NULL; offset = cnt; } for (C = name; *C && *C != '='; ++C); /* no `=' in name */ if (!(environ[offset] = /* name + `=' + value */ malloc((u_int)((int)(C - name) + l_value + 2)))) return(-1); for (C = environ[offset]; (*C = *name++) &&( *C != '='); ++C); for (*C++ = '='; (*C++ = *value++) != NULL;); return(0); } #endif /* * unsetenv(name) -- * Delete environmental variable "name". */ #ifndef HAVE_UNSETENV void unsetenv(name) char *name; { extern char **environ; char **P; int offset; while (_findenv(name, &offset)) /* if set multiple times */ for (P = &environ[offset];; ++P) if (!(*P = *(P + 1))) break; } #endif /* based on @(#)getenv.c 5.5 (Berkeley) 6/27/88 */ /* * getenv -- * Returns ptr to value associated with name, if any, else NULL. */ #ifndef HAVE_GETENV char * getenv(name) char *name; { int offset; return(_findenv(name, &offset)); } #endif /* * _findenv -- * Returns pointer to value associated with name, if any, else NULL. * Sets offset to be the offset of the name/value combination in the * environmental array, for use by setenv(3) and unsetenv(3). * Explicitly removes '=' in argument name. * */ static char * _findenv(name, offset) char *name; int *offset; { extern char **environ; int len; char **P, *C; for (C = name, len = 0; *C && *C != '='; ++C, ++len); for (P = environ; *P; ++P) if (!strncmp(*P, name, len)) if (*(C = *P + len) == '=') { *offset = P - environ; return(++C); } return(NULL); } krb5-1.22.1/src/clients/ksu/ksu.h0000664000175000017500000001623215051422640016352 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 1994 by the University of Southern California * * EXPORT OF THIS SOFTWARE from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute * this software and its documentation in source and binary forms is * hereby granted, provided that any documentation or other materials * related to such distribution or use acknowledge that the software * was developed by the University of Southern California. * * DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The * University of Southern California MAKES NO REPRESENTATIONS OR * WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not * limitation, the University of Southern California MAKES NO * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY * PARTICULAR PURPOSE. The University of Southern * California shall not be held liable for any liability nor for any * direct, indirect, or consequential damages with respect to any * claim by the user or distributor of the ksu software. * * KSU was written by: Ari Medvinsky, ari@isi.edu */ #include "k5-int.h" #include "k5-util.h" #include #include "com_err.h" #include #include #include #include #include #include /* or is already included by com_err.h. */ #define NO_TARGET_FILE '.' #define SOURCE_USER_LOGIN "." #define KRB5_DEFAULT_OPTIONS 0 #define KRB5_DEFAULT_TKT_LIFE 60*60*12 /* 12 hours */ #define KRB5_LOGIN_NAME ".k5login" #define KRB5_USERS_NAME ".k5users" #define USE_DEFAULT_REALM_NAME "." #define PERMIT_ALL_COMMANDS "*" #define KRB5_SEC_BUFFSIZE 80 #define NOT_AUTHORIZED 1 #define CHUNK 3 #define CACHE_MODE 0600 #define MAX_CMD 2048 /* this is temp, should use realloc instead, as done in most of the code */ extern int optind; extern char * optarg; /* globals */ extern char * prog_name; extern int auth_debug; extern int quiet; extern char k5login_path[MAXPATHLEN]; extern char k5users_path[MAXPATHLEN]; extern char * gb_err; /***********/ /* krb_auth_su.c */ extern krb5_boolean krb5_auth_check (krb5_context, krb5_principal, char *, krb5_get_init_creds_opt *, char *, krb5_ccache, int *, uid_t); extern krb5_boolean krb5_fast_auth (krb5_context, krb5_principal, krb5_principal, char *, krb5_ccache); extern krb5_boolean ksu_get_tgt_via_passwd (krb5_context, krb5_principal, krb5_get_init_creds_opt *, krb5_boolean *, krb5_creds *); extern void dump_principal (krb5_context, char *, krb5_principal); extern void plain_dump_principal (krb5_context, krb5_principal); extern krb5_error_code krb5_parse_lifetime (char *, long *); /* ccache.c */ extern krb5_error_code krb5_ccache_copy (krb5_context, krb5_ccache, krb5_principal, krb5_ccache, krb5_boolean, krb5_principal, krb5_boolean *); extern krb5_error_code krb5_store_all_creds (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **); extern krb5_error_code krb5_store_all_creds (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **); extern krb5_boolean compare_creds (krb5_context, krb5_creds *, krb5_creds *); extern krb5_error_code krb5_get_nonexp_tkts (krb5_context, krb5_ccache, krb5_creds ***); extern krb5_error_code krb5_check_exp (krb5_context, krb5_ticket_times); extern char *flags_string (krb5_creds *); extern void show_credential (krb5_context, krb5_creds *, krb5_ccache); krb5_error_code gen_sym(krb5_context context, char **sym); extern krb5_error_code krb5_ccache_overwrite (krb5_context, krb5_ccache, krb5_ccache, krb5_principal); extern krb5_error_code krb5_store_some_creds (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **, krb5_principal, krb5_boolean *); extern krb5_boolean ks_ccache_name_is_initialized (krb5_context, const char *); extern krb5_boolean ks_ccache_is_initialized (krb5_context, krb5_ccache); extern krb5_error_code krb5_ccache_refresh (krb5_context, krb5_ccache); extern krb5_error_code krb5_ccache_filter (krb5_context, krb5_ccache, krb5_principal); extern krb5_boolean krb5_find_princ_in_cred_list (krb5_context, krb5_creds **, krb5_principal); extern krb5_error_code krb5_find_princ_in_cache (krb5_context, krb5_ccache, krb5_principal, krb5_boolean *); extern void printtime (krb5_timestamp); /* authorization.c */ extern krb5_boolean fowner (FILE *, uid_t); extern krb5_error_code krb5_authorization (krb5_context, krb5_principal, const char *, char *, krb5_boolean *, char **); extern krb5_error_code k5login_lookup (FILE *, char *, krb5_boolean *); extern krb5_error_code k5users_lookup (FILE *, char *, char *, krb5_boolean *, char **); extern krb5_boolean fcmd_resolve (char *, char ***, char **); extern krb5_boolean cmd_single (char *); extern int cmd_arr_cmp_postfix (char **, char *); extern int cmd_arr_cmp (char **, char *); extern krb5_boolean find_first_cmd_that_exists (char **, char **, char **); extern int match_commands (char *, char *, krb5_boolean *, char **, char **); extern krb5_error_code get_line (FILE *, char **); extern char * get_first_token (char *, char **); extern char * get_next_token (char **); extern void init_auth_names (char *); /* main.c */ extern void usage (void); extern int standard_shell (char *); extern krb5_error_code get_params (int *, int, char **, char ***); /* heuristic.c */ extern krb5_error_code get_all_princ_from_file (FILE *, char ***); extern krb5_error_code list_union (char **, char **, char ***); extern krb5_error_code filter (FILE *, char *, char **, char ***); extern krb5_error_code get_authorized_princ_names (const char *, char *, char ***); extern krb5_error_code get_closest_principal (krb5_context, char **, krb5_principal *, krb5_boolean *); extern krb5_error_code find_either_ticket (krb5_context, krb5_ccache, krb5_principal, krb5_principal, krb5_boolean *); extern krb5_error_code find_ticket (krb5_context, krb5_ccache, krb5_principal, krb5_principal, krb5_boolean *); extern krb5_error_code find_princ_in_list (krb5_context, krb5_principal, char **, krb5_boolean *); extern krb5_error_code get_best_princ_for_target (krb5_context, uid_t, uid_t, char *, char *, krb5_ccache, krb5_get_init_creds_opt *, char *, char *, krb5_principal *, int *); extern krb5_error_code ksu_tgtname (krb5_context, const krb5_data *, const krb5_data *, krb5_principal *tgtprinc); #ifndef min #define min(a,b) ((a) > (b) ? (b) : (a)) #endif /* min */ extern char *krb5_lname_file; /* Note: print this out just be sure that it gets set */ extern void *xmalloc (size_t), *xrealloc (void *, size_t), *xcalloc (size_t, size_t); extern char *xstrdup (const char *); extern char *xasprintf (const char *format, ...); #ifndef HAVE_UNSETENV void unsetenv (char *); #endif krb5-1.22.1/src/clients/deps0000664000175000017500000000003015051422640015440 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/clients/kdestroy/0000775000175000017500000000000015051422640016435 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/kdestroy/Makefile.in0000664000175000017500000000157515051422640020512 0ustar ghudsonghudsonmydir=clients$(S)kdestroy BUILDTOP=$(REL)..$(S).. ##WIN32##LOCALINCLUDES=-I$(BUILDTOP)\util\windows\ SRCS=kdestroy.c ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##KDESTROY=$(OUTPRE)kdestroy.exe ##WIN32##EXERES=$(KDESTROY:.exe=.res) ##WIN32##$(EXERES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DKDESTROY_APP -fo $@ -r $** all-unix: kdestroy ##WIN32##all-windows: $(KDESTROY) kdestroy: kdestroy.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ kdestroy.o $(KRB5_BASE_LIBS) ##WIN32##$(KDESTROY): $(OUTPRE)kdestroy.obj $(SLIB) $(KLIB) $(CLIB) $(EXERES) ##WIN32## link $(EXE_LINKOPTS) -out:$@ $** ##WIN32## $(_VC_MANIFEST_EMBED_EXE) clean-unix:: $(RM) kdestroy.o kdestroy install-unix: for f in kdestroy; do \ $(INSTALL_PROGRAM) $$f \ $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \ done krb5-1.22.1/src/clients/kdestroy/deps0000664000175000017500000000042415051422640017313 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)kdestroy.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ kdestroy.c krb5-1.22.1/src/clients/kdestroy/kdestroy.c0000664000175000017500000001537115051422640020454 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* clients/kdestroy/kdestroy.c - Destroy contents of credential cache */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-platform.h" #include #include #include #include #include #ifdef __STDC__ #define BELL_CHAR '\a' #else #define BELL_CHAR '\007' #endif #ifndef _WIN32 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/') + 1 : (x)) #else #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x)) #endif char *progname; static void usage(void) { fprintf(stderr, _("Usage: %s [-A] [-q] [-c cache_name] [-p princ_name]\n"), progname); fprintf(stderr, _("\t-A destroy all credential caches in collection\n")); fprintf(stderr, _("\t-q quiet mode\n")); fprintf(stderr, _("\t-c specify name of credentials cache\n")); fprintf(stderr, _("\t-p specify principal name within collection\n")); exit(2); } /* Print a warning if there are still un-destroyed caches in the collection. */ static void print_remaining_cc_warning(krb5_context context) { krb5_error_code ret; krb5_ccache cache; krb5_cccol_cursor cursor; ret = krb5_cccol_cursor_new(context, &cursor); if (ret) { com_err(progname, ret, _("while listing credential caches")); exit(1); } ret = krb5_cccol_cursor_next(context, cursor, &cache); if (ret == 0 && cache != NULL) { fprintf(stderr, _("Other credential caches present, use -A to destroy all\n")); krb5_cc_close(context, cache); } krb5_cccol_cursor_free(context, &cursor); } int main(int argc, char *argv[]) { krb5_context context; krb5_error_code ret; krb5_ccache cache = NULL; krb5_cccol_cursor cursor; krb5_principal princ; char *cache_name = NULL; const char *princ_name = NULL; int code = 0, errflg = 0, quiet = 0, all = 0, c; setlocale(LC_ALL, ""); progname = GET_PROGNAME(argv[0]); while ((c = getopt(argc, argv, "54Aqc:p:")) != -1) { switch (c) { case 'A': all = 1; break; case 'q': quiet = 1; break; case 'c': if (cache_name) { fprintf(stderr, _("Only one -c option allowed\n")); errflg++; } else { cache_name = optarg; } break; case 'p': if (princ_name != NULL) { fprintf(stderr, _("Only one -p option allowed\n")); errflg++; } else { princ_name = optarg; } break; case '4': fprintf(stderr, _("Kerberos 4 is no longer supported\n")); exit(3); break; case '5': break; case '?': default: errflg++; break; } } if (all && princ_name != NULL) { fprintf(stderr, _("-A option is exclusive with -p option\n")); errflg++; } if (optind != argc) errflg++; if (errflg) usage(); ret = krb5_init_context(&context); if (ret) { com_err(progname, ret, _("while initializing krb5")); exit(1); } if (cache_name != NULL) { code = krb5_cc_set_default_name(context, cache_name); if (code) { com_err(progname, code, _("while setting default cache name")); exit(1); } } if (all) { code = krb5_cccol_cursor_new(context, &cursor); if (code) { com_err(progname, code, _("while listing credential caches")); exit(1); } while (krb5_cccol_cursor_next(context, cursor, &cache) == 0 && cache != NULL) { code = krb5_cc_get_full_name(context, cache, &cache_name); if (code) { com_err(progname, code, _("composing ccache name")); exit(1); } code = krb5_cc_destroy(context, cache); if (code && code != KRB5_FCC_NOFILE) { com_err(progname, code, _("while destroying cache %s"), cache_name); } krb5_free_string(context, cache_name); } krb5_cccol_cursor_free(context, &cursor); krb5_free_context(context); return 0; } if (princ_name != NULL) { code = krb5_parse_name(context, princ_name, &princ); if (code) { com_err(progname, code, _("while parsing principal name %s"), princ_name); exit(1); } code = krb5_cc_cache_match(context, princ, &cache); if (code) { com_err(progname, code, _("while finding cache for %s"), princ_name); exit(1); } krb5_free_principal(context, princ); } else { code = krb5_cc_default(context, &cache); if (code) { com_err(progname, code, _("while resolving ccache")); exit(1); } } code = krb5_cc_destroy(context, cache); if (code != 0) { com_err(progname, code, _("while destroying cache")); if (code != KRB5_FCC_NOFILE) { if (quiet) { fprintf(stderr, _("Ticket cache NOT destroyed!\n")); } else { fprintf(stderr, _("Ticket cache %cNOT%c destroyed!\n"), BELL_CHAR, BELL_CHAR); } errflg = 1; } } if (!quiet && !errflg && princ_name == NULL) print_remaining_cc_warning(context); krb5_free_context(context); return errflg; } krb5-1.22.1/src/clients/kvno/0000775000175000017500000000000015051422640015546 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/kvno/kvno.c0000664000175000017500000004434515051422640016701 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "k5-platform.h" #include "k5-buf.h" #include "k5-base64.h" #include #ifdef HAVE_UNISTD_H #include #endif #include #include static char *prog; static int quiet = 0; static void xusage(void) { fprintf(stderr, _("usage: %s [-c ccache] [-e etype] [-k keytab] [-q] " "[-u | -S sname]\n" "\t[[{-F cert_file | {-I | -U} for_user} [-P]] | " "--u2u ccache]\n" "\t[--cached-only] [--no-store] [--out-cache] " "service1 service2 ...\n"), prog); exit(1); } static void do_v5_kvno(int argc, char *argv[], char *ccachestr, char *etypestr, char *keytab_name, char *sname, int cached_only, int canon, int no_store, int unknown, char *for_user, int for_user_enterprise, char *for_user_cert_file, int proxy, const char *out_ccname, const char *u2u_ccname); #include static void extended_com_err_fn(const char *myprog, errcode_t code, const char *fmt, va_list args); int main(int argc, char *argv[]) { enum { OPTION_U2U = 256, OPTION_OUT_CACHE = 257 }; const char *shopts = "uCc:e:hk:qPS:I:U:F:"; int option; char *etypestr = NULL, *ccachestr = NULL, *keytab_name = NULL; char *sname = NULL, *for_user = NULL, *u2u_ccname = NULL; char *for_user_cert_file = NULL, *out_ccname = NULL; int canon = 0, unknown = 0, proxy = 0, for_user_enterprise = 0; int impersonate = 0, cached_only = 0, no_store = 0; struct option lopts[] = { { "cached-only", 0, &cached_only, 1 }, { "no-store", 0, &no_store, 1 }, { "out-cache", 1, NULL, OPTION_OUT_CACHE }, { "u2u", 1, NULL, OPTION_U2U }, { NULL, 0, NULL, 0 } }; setlocale(LC_ALL, ""); set_com_err_hook(extended_com_err_fn); prog = strrchr(argv[0], '/'); prog = prog ? (prog + 1) : argv[0]; while ((option = getopt_long(argc, argv, shopts, lopts, NULL)) != -1) { switch (option) { case 'C': canon = 1; break; case 'c': ccachestr = optarg; break; case 'e': etypestr = optarg; break; case 'h': xusage(); break; case 'k': keytab_name = optarg; break; case 'q': quiet = 1; break; case 'P': proxy = 1; /* S4U2Proxy - constrained delegation */ break; case 'S': sname = optarg; if (unknown == 1) { fprintf(stderr, _("Options -u and -S are mutually exclusive\n")); xusage(); } break; case 'u': unknown = 1; if (sname != NULL) { fprintf(stderr, _("Options -u and -S are mutually exclusive\n")); xusage(); } break; case 'I': impersonate = 1; for_user = optarg; break; case 'U': impersonate = 1; for_user_enterprise = 1; for_user = optarg; break; case 'F': impersonate = 1; for_user_cert_file = optarg; break; case OPTION_U2U: u2u_ccname = optarg; break; case OPTION_OUT_CACHE: out_ccname = optarg; break; case 0: /* If this option set a flag, do nothing else now. */ break; default: xusage(); break; } } if (u2u_ccname != NULL && impersonate) { fprintf(stderr, _("Options --u2u and -I|-U|-F are mutually exclusive\n")); xusage(); } if (proxy) { if (!impersonate) { fprintf(stderr, _("Option -P (constrained delegation) requires " "option -I|-U|-F (protocol transition)\n")); xusage(); } } if (argc - optind < 1) xusage(); do_v5_kvno(argc - optind, argv + optind, ccachestr, etypestr, keytab_name, sname, cached_only, canon, no_store, unknown, for_user, for_user_enterprise, for_user_cert_file, proxy, out_ccname, u2u_ccname); return 0; } #include static krb5_context context; static void extended_com_err_fn(const char *myprog, errcode_t code, const char *fmt, va_list args) { const char *emsg; emsg = krb5_get_error_message(context, code); fprintf(stderr, "%s: %s ", myprog, emsg); krb5_free_error_message(context, emsg); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } /* Read a line from fp into buf. Trim any trailing whitespace, and return a * pointer to the first non-whitespace character. */ static const char * read_line(FILE *fp, char *buf, size_t bufsize) { char *end, *begin; if (fgets(buf, bufsize, fp) == NULL) return NULL; end = buf + strlen(buf); while (end > buf && isspace((uint8_t)end[-1])) *--end = '\0'; begin = buf; while (isspace((uint8_t)*begin)) begin++; return begin; } /* Read a certificate from file_name in PEM format, placing the DER * representation of the certificate in *der_out. */ static krb5_error_code read_pem_file(char *file_name, krb5_data *der_out) { krb5_error_code ret = 0; FILE *fp = NULL; const char *begin_line = "-----BEGIN CERTIFICATE-----"; const char *end_line = "-----END ", *line; char linebuf[256], *b64; struct k5buf buf = EMPTY_K5BUF; uint8_t *der_cert; size_t dlen; *der_out = empty_data(); fp = fopen(file_name, "r"); if (fp == NULL) return errno; for (;;) { line = read_line(fp, linebuf, sizeof(linebuf)); if (line == NULL) { ret = EINVAL; k5_setmsg(context, ret, _("No begin line not found")); goto cleanup; } if (strncmp(line, begin_line, strlen(begin_line)) == 0) break; } k5_buf_init_dynamic(&buf); for (;;) { line = read_line(fp, linebuf, sizeof(linebuf)); if (line == NULL) { ret = EINVAL; k5_setmsg(context, ret, _("No end line found")); goto cleanup; } if (strncmp(line, end_line, strlen(end_line)) == 0) break; /* Header lines would be expected for an actual privacy-enhanced mail * message, but not for a certificate. */ if (*line == '\0' || strchr(line, ':') != NULL) { ret = EINVAL; k5_setmsg(context, ret, _("Unexpected header line")); goto cleanup; } k5_buf_add(&buf, line); } b64 = k5_buf_cstring(&buf); if (b64 == NULL) { ret = ENOMEM; goto cleanup; } der_cert = k5_base64_decode(b64, &dlen); if (der_cert == NULL) { ret = EINVAL; k5_setmsg(context, ret, _("Invalid base64")); goto cleanup; } *der_out = make_data(der_cert, dlen); cleanup: fclose(fp); k5_buf_free(&buf); return ret; } /* Request a single service ticket and display its status (unless quiet is * set). On failure, display an error message and return non-zero. */ static krb5_error_code kvno(const char *name, krb5_ccache ccache, krb5_principal me, krb5_enctype etype, krb5_keytab keytab, const char *sname, krb5_flags options, int unknown, krb5_principal for_user_princ, krb5_data *for_user_cert, int proxy, krb5_data *u2u_ticket, krb5_creds **creds_out) { krb5_error_code ret; krb5_principal server = NULL; krb5_ticket *ticket = NULL; krb5_creds in_creds, *creds = NULL; char *princ = NULL; *creds_out = NULL; memset(&in_creds, 0, sizeof(in_creds)); if (sname != NULL) { ret = krb5_sname_to_principal(context, name, sname, KRB5_NT_SRV_HST, &server); } else { ret = krb5_parse_name(context, name, &server); } if (ret) { if (!quiet) com_err(prog, ret, _("while parsing principal name %s"), name); goto cleanup; } if (unknown) krb5_princ_type(context, server) = KRB5_NT_UNKNOWN; ret = krb5_unparse_name(context, server, &princ); if (ret) { com_err(prog, ret, _("while formatting parsed principal name for " "'%s'"), name); goto cleanup; } in_creds.keyblock.enctype = etype; if (u2u_ticket != NULL) in_creds.second_ticket = *u2u_ticket; if (for_user_princ != NULL || for_user_cert != NULL) { if (!proxy && !krb5_principal_compare(context, me, server)) { ret = EINVAL; com_err(prog, ret, _("client and server principal names must match")); goto cleanup; } in_creds.client = for_user_princ; in_creds.server = me; ret = krb5_get_credentials_for_user(context, options, ccache, &in_creds, for_user_cert, &creds); } else { in_creds.client = me; in_creds.server = server; ret = krb5_get_credentials(context, options, ccache, &in_creds, &creds); } if (ret) { com_err(prog, ret, _("while getting credentials for %s"), princ); goto cleanup; } /* We need a native ticket. */ ret = krb5_decode_ticket(&creds->ticket, &ticket); if (ret) { com_err(prog, ret, _("while decoding ticket for %s"), princ); goto cleanup; } if (keytab != NULL) { ret = krb5_server_decrypt_ticket_keytab(context, keytab, ticket); if (ret) { if (!quiet) { fprintf(stderr, "%s: kvno = %d, keytab entry invalid\n", princ, ticket->enc_part.kvno); } com_err(prog, ret, _("while decrypting ticket for %s"), princ); goto cleanup; } if (!quiet) { printf(_("%s: kvno = %d, keytab entry valid\n"), princ, ticket->enc_part.kvno); } } else { if (!quiet) printf(_("%s: kvno = %d\n"), princ, ticket->enc_part.kvno); } if (proxy) { in_creds.client = creds->client; creds->client = NULL; krb5_free_creds(context, creds); creds = NULL; in_creds.server = server; ret = krb5_get_credentials_for_proxy(context, KRB5_GC_CANONICALIZE, ccache, &in_creds, ticket, &creds); krb5_free_principal(context, in_creds.client); if (ret) { com_err(prog, ret, _("%s: constrained delegation failed"), princ); goto cleanup; } } *creds_out = creds; creds = NULL; cleanup: krb5_free_principal(context, server); krb5_free_ticket(context, ticket); krb5_free_creds(context, creds); krb5_free_unparsed_name(context, princ); return ret; } /* Fetch the encoded local TGT for ccname's default client principal. */ static krb5_error_code get_u2u_ticket(const char *ccname, krb5_data **ticket_out) { krb5_error_code ret; krb5_ccache cc = NULL; krb5_creds mcred, *creds = NULL; *ticket_out = NULL; memset(&mcred, 0, sizeof(mcred)); ret = krb5_cc_resolve(context, ccname, &cc); if (ret) goto cleanup; ret = krb5_cc_get_principal(context, cc, &mcred.client); if (ret) goto cleanup; ret = krb5_build_principal_ext(context, &mcred.server, mcred.client->realm.length, mcred.client->realm.data, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, mcred.client->realm.length, mcred.client->realm.data, 0); if (ret) goto cleanup; ret = krb5_get_credentials(context, KRB5_GC_CACHED, cc, &mcred, &creds); if (ret) goto cleanup; ret = krb5_copy_data(context, &creds->ticket, ticket_out); cleanup: if (cc != NULL) krb5_cc_close(context, cc); krb5_free_cred_contents(context, &mcred); krb5_free_creds(context, creds); return ret; } static void do_v5_kvno(int count, char *names[], char * ccachestr, char *etypestr, char *keytab_name, char *sname, int cached_only, int canon, int no_store, int unknown, char *for_user, int for_user_enterprise, char *for_user_cert_file, int proxy, const char *out_ccname, const char *u2u_ccname) { krb5_error_code ret; int i, errors, flags, initialized = 0; krb5_enctype etype; krb5_ccache ccache, mcc, out_ccache = NULL; krb5_principal me; krb5_keytab keytab = NULL; krb5_principal for_user_princ = NULL; krb5_flags options = 0; krb5_data cert_data = empty_data(), *user_cert = NULL, *u2u_ticket = NULL; krb5_creds *creds; if (canon) options |= KRB5_GC_CANONICALIZE; if (cached_only) options |= KRB5_GC_CACHED; if (no_store || out_ccname != NULL) options |= KRB5_GC_NO_STORE; ret = krb5_init_context(&context); if (ret) { com_err(prog, ret, _("while initializing krb5 library")); exit(1); } if (etypestr) { ret = krb5_string_to_enctype(etypestr, &etype); if (ret) { com_err(prog, ret, _("while converting etype")); exit(1); } } else { etype = 0; } if (ccachestr) ret = krb5_cc_resolve(context, ccachestr, &ccache); else ret = krb5_cc_default(context, &ccache); if (ret) { com_err(prog, ret, _("while opening ccache")); exit(1); } if (out_ccname != NULL) { ret = krb5_cc_resolve(context, out_ccname, &out_ccache); if (ret) { com_err(prog, ret, _("while resolving output ccache")); exit(1); } } if (keytab_name != NULL) { ret = krb5_kt_resolve(context, keytab_name, &keytab); if (ret) { com_err(prog, ret, _("resolving keytab %s"), keytab_name); exit(1); } } if (for_user) { flags = for_user_enterprise ? KRB5_PRINCIPAL_PARSE_ENTERPRISE : 0; ret = krb5_parse_name_flags(context, for_user, flags, &for_user_princ); if (ret) { com_err(prog, ret, _("while parsing principal name %s"), for_user); exit(1); } } if (for_user_cert_file != NULL) { ret = read_pem_file(for_user_cert_file, &cert_data); if (ret) { com_err(prog, ret, _("while reading certificate file %s"), for_user_cert_file); exit(1); } user_cert = &cert_data; } if (u2u_ccname != NULL) { ret = get_u2u_ticket(u2u_ccname, &u2u_ticket); if (ret) { com_err(prog, ret, _("while getting user-to-user ticket from %s"), u2u_ccname); exit(1); } options |= KRB5_GC_USER_USER; } ret = krb5_cc_get_principal(context, ccache, &me); if (ret) { com_err(prog, ret, _("while getting client principal name")); exit(1); } if (out_ccache != NULL) { ret = krb5_cc_new_unique(context, "MEMORY", NULL, &mcc); if (ret) { com_err(prog, ret, _("while creating temporary output ccache")); exit(1); } } errors = 0; for (i = 0; i < count; i++) { if (kvno(names[i], ccache, me, etype, keytab, sname, options, unknown, for_user_princ, user_cert, proxy, u2u_ticket, &creds) != 0) { errors++; } else if (out_ccache != NULL) { if (!initialized) { ret = krb5_cc_initialize(context, mcc, creds->client); if (ret) { com_err(prog, ret, _("while initializing output ccache")); exit(1); } initialized = 1; } if (count == 1) ret = k5_cc_store_primary_cred(context, mcc, creds); else ret = krb5_cc_store_cred(context, mcc, creds); if (ret) { com_err(prog, ret, _("while storing creds in output ccache")); exit(1); } } krb5_free_creds(context, creds); } if (!errors && out_ccache != NULL) { ret = krb5_cc_move(context, mcc, out_ccache); if (ret) { com_err(prog, ret, _("while writing output ccache")); exit(1); } } if (keytab != NULL) krb5_kt_close(context, keytab); krb5_free_principal(context, me); krb5_free_principal(context, for_user_princ); krb5_cc_close(context, ccache); krb5_free_data(context, u2u_ticket); krb5_free_data_contents(context, &cert_data); krb5_free_context(context); if (errors) exit(1); exit(0); } krb5-1.22.1/src/clients/kvno/Makefile.in0000664000175000017500000000160415051422640017614 0ustar ghudsonghudsonmydir=clients$(S)kvno BUILDTOP=$(REL)..$(S).. ##WIN32##LOCALINCLUDES=-I$(BUILDTOP)\util\windows\ SRCS=kvno.c ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##KVNO=$(OUTPRE)kvno.exe ##WIN32##EXERES=$(KVNO:.exe=.res) ##WIN32##$(EXERES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DKVNO_APP -fo $@ -r $** all-unix: kvno ##WIN32##all-windows: $(KVNO) kvno: kvno.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ kvno.o $(KRB5_BASE_LIBS) ##WIN32##$(KVNO): $(OUTPRE)kvno.obj $(SLIB) $(KLIB) $(CLIB) $(EXERES) ##WIN32## link $(EXE_LINKOPTS) /out:$@ $** ##WIN32## $(_VC_MANIFEST_EMBED_EXE) check-pytests: kvno $(RUNPYTEST) $(srcdir)/t_kvno.py $(PYTESTFLAGS) clean-unix:: $(RM) kvno.o kvno install-unix: for f in kvno; do \ $(INSTALL_PROGRAM) $$f \ $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \ done krb5-1.22.1/src/clients/kvno/t_kvno.py0000664000175000017500000000561115051422640017423 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm() def check_cache(ccache, expected_services): # Fetch the klist output and skip past the header. lines = realm.run([klist, '-c', ccache]).splitlines() lines = lines[4:] # For each line not beginning with an indent, match against the # expected service principals. svcs = {x: True for x in expected_services} for l in lines: if not l.startswith('\t'): svcprinc = l.split()[4] if svcprinc in svcs: del svcs[svcprinc] else: fail('unexpected service princ ' + svcprinc) if svcs: fail('services not found in klist output: ' + ' '.join(svcs.keys())) mark('no options') realm.run([kvno, realm.user_princ], expected_msg='user@KRBTEST.COM: kvno = 1') check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ]) mark('-e') msgs = ('etypes requested in TGS request: camellia128-cts', '/KDC has no support for encryption type') realm.run([kvno, '-e', 'camellia128-cts', realm.host_princ], expected_code=1, expected_trace=msgs) mark('--cached-only') realm.run([kvno, '--cached-only', realm.user_princ], expected_msg='kvno = 1') realm.run([kvno, '--cached-only', realm.host_princ], expected_code=1, expected_msg='Matching credential not found') check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ]) mark('--no-store') realm.run([kvno, '--no-store', realm.host_princ], expected_msg='kvno = 1') check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ]) mark('--out-cache') # and multiple services out_ccache = os.path.join(realm.testdir, 'ccache.out') realm.run([kvno, '--out-cache', out_ccache, realm.host_princ, realm.admin_princ]) check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ]) check_cache(out_ccache, [realm.host_princ, realm.admin_princ]) mark('--out-cache --cached-only') # tests out-cache overwriting, and -q realm.run([kvno, '--out-cache', out_ccache, '--cached-only', realm.host_princ], expected_code=1, expected_msg='Matching credential not found') out = realm.run([kvno, '-q', '--out-cache', out_ccache, '--cached-only', realm.user_princ]) if out: fail('unexpected kvno output with -q') check_cache(out_ccache, [realm.user_princ]) mark('-U') # and -c svc_ccache = os.path.join(realm.testdir, 'ccache.svc') realm.run([kinit, '-k', '-c', svc_ccache, realm.host_princ]) realm.run([kvno, '-c', svc_ccache, '-U', 'user', realm.host_princ]) realm.run([klist, '-c', svc_ccache], expected_msg='for client user@') realm.run([kvno, '-c', svc_ccache, '-U', 'user', '--out-cache', out_ccache, realm.host_princ]) out = realm.run([klist, '-c', out_ccache]) if ('Default principal: user@KRBTEST.COM' not in out): fail('wrong default principal in klist output') # More S4U options are tested in tests/gssapi/t_s4u.py. # --u2u is tested in tests/t_u2u.py. success('kvno tests') krb5-1.22.1/src/clients/kvno/deps0000664000175000017500000000141415051422640016424 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)kvno.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-base64.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ kvno.c krb5-1.22.1/src/clients/kinit/0000775000175000017500000000000015051422640015707 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/kinit/Makefile.in0000664000175000017500000000170615051422640017760 0ustar ghudsonghudsonmydir=clients$(S)kinit BUILDTOP=$(REL)..$(S).. SRCS=kinit.c kinit_kdb.c ##WIN32##LOCALINCLUDES=-I$(BUILDTOP)\util\windows -I$(BUILDTOP)\util\support ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##KINIT=$(OUTPRE)kinit.exe ##WIN32##EXERES=$(KINIT:.exe=.res) ##WIN32##$(EXERES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DKINIT_APP -fo $@ -r $** all-unix: kinit ##WIN32##all-windows: $(KINIT) kinit: kinit.o kinit_kdb.o $(KRB5_BASE_DEPLIBS) $(KADMSRV_DEPLIBS) $(CC_LINK) -o $@ kinit.o kinit_kdb.o $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) ##WIN32##$(KINIT): $(OUTPRE)kinit.obj $(SLIB) $(KLIB) $(CLIB) $(EXERES) ##WIN32## link $(EXE_LINKOPTS) -out:$@ $** advapi32.lib ##WIN32## $(_VC_MANIFEST_EMBED_EXE) clean-unix:: $(RM) kinit.o kinit_kdb.o kinit install-unix: for f in kinit; do \ $(INSTALL_PROGRAM) $$f \ $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \ done krb5-1.22.1/src/clients/kinit/kinit.c0000664000175000017500000006776415051422640017215 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* clients/kinit/kinit.c - Initialize a credential cache */ /* * Copyright 1990, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #include #include "k5-platform.h" /* For asprintf and getopt */ #include #include "extern.h" #include #include #include #include #include #include #ifndef _WIN32 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/') + 1 : (x)) #else #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x)) #endif #ifdef HAVE_PWD_H #include static char * get_name_from_os(void) { struct passwd *pw; pw = getpwuid(getuid()); return (pw != NULL) ? pw->pw_name : NULL; } #else /* HAVE_PWD_H */ #ifdef _WIN32 static char * get_name_from_os(void) { static char name[1024]; DWORD name_size = sizeof(name); if (GetUserName(name, &name_size)) { name[sizeof(name) - 1] = '\0'; /* Just to be extra safe */ return name; } else { return NULL; } } #else /* _WIN32 */ static char * get_name_from_os(void) { return NULL; } #endif /* _WIN32 */ #endif /* HAVE_PWD_H */ static char *progname; typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type; struct k_opts { /* In seconds */ krb5_deltat starttime; krb5_deltat lifetime; krb5_deltat rlife; int forwardable; int proxiable; int request_pac; int anonymous; int addresses; int not_forwardable; int not_proxiable; int not_request_pac; int no_addresses; int verbose; char *principal_name; char *service_name; char *keytab_name; char *k5_in_cache_name; char *k5_out_cache_name; char *armor_ccache; action_type action; int use_client_keytab; int num_pa_opts; krb5_gic_opt_pa_data *pa_opts; int canonicalize; int enterprise; }; struct k5_data { krb5_context ctx; krb5_ccache in_cc, out_cc; krb5_principal me; char *name; krb5_boolean switch_to_cache; }; /* * If struct[2] == NULL, then long_getopt acts as if the short flag struct[3] * were specified. If struct[2] != NULL, then struct[3] is stored in * *(struct[2]), the array index which was specified is stored in *index, and * long_getopt() returns 0. */ const char *shopts = "r:fpFPn54aAVl:s:c:kit:T:RS:vX:CEI:"; #define USAGE_BREAK "\n\t" static void usage(void) { fprintf(stderr, _("Usage: %s [-V] [-l lifetime] [-s start_time] " "[-r renewable_life]\n" "\t[-f | -F] [-p | -P] [-n] [-a | -A] [-C] [-E]\n" "\t[--request-pac | --no-request-pac]\n" "\t[-v] [-R] [-k [-i|-t keytab_file]] [-c cachename]\n" "\t[-S service_name] [-I input_ccache] [-T ticket_armor_cache]\n" "\t[-X [=]] [principal]\n" "\n"), progname); fprintf(stderr, " options:\n"); fprintf(stderr, _("\t-V verbose\n")); fprintf(stderr, _("\t-l lifetime\n")); fprintf(stderr, _("\t-s start time\n")); fprintf(stderr, _("\t-r renewable lifetime\n")); fprintf(stderr, _("\t-f forwardable\n")); fprintf(stderr, _("\t-F not forwardable\n")); fprintf(stderr, _("\t-p proxiable\n")); fprintf(stderr, _("\t-P not proxiable\n")); fprintf(stderr, _("\t-n anonymous\n")); fprintf(stderr, _("\t-a include addresses\n")); fprintf(stderr, _("\t-A do not include addresses\n")); fprintf(stderr, _("\t-v validate\n")); fprintf(stderr, _("\t-R renew\n")); fprintf(stderr, _("\t-C canonicalize\n")); fprintf(stderr, _("\t-E client is enterprise principal name\n")); fprintf(stderr, _("\t-k use keytab\n")); fprintf(stderr, _("\t-i use default client keytab (with -k)\n")); fprintf(stderr, _("\t-t filename of keytab to use\n")); fprintf(stderr, _("\t-c Kerberos 5 cache name\n")); fprintf(stderr, _("\t-S service\n")); fprintf(stderr, _("\t-I input credential cache\n")); fprintf(stderr, _("\t-T armor credential cache\n")); fprintf(stderr, _("\t-X [=]\n")); fprintf(stderr, _("\t--{,no}-request-pac request KDC include/exclude a PAC\n")); exit(2); } static krb5_context errctx; static void extended_com_err_fn(const char *myprog, errcode_t code, const char *fmt, va_list args) { const char *emsg; emsg = krb5_get_error_message(errctx, code); fprintf(stderr, "%s: %s ", myprog, emsg); krb5_free_error_message(errctx, emsg); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } static int add_preauth_opt(struct k_opts *opts, char *av) { char *sep, *v; krb5_gic_opt_pa_data *p, *x; size_t newsize = (opts->num_pa_opts + 1) * sizeof(*opts->pa_opts); x = realloc(opts->pa_opts, newsize); if (x == NULL) return ENOMEM; opts->pa_opts = x; p = &opts->pa_opts[opts->num_pa_opts]; sep = strchr(av, '='); if (sep) { *sep = '\0'; v = ++sep; p->value = v; } else { p->value = "yes"; } p->attr = av; opts->num_pa_opts++; return 0; } static char * parse_options(int argc, char **argv, struct k_opts *opts) { struct option long_options[] = { { "noforwardable", 0, NULL, 'F' }, { "noproxiable", 0, NULL, 'P' }, { "addresses", 0, NULL, 'a'}, { "forwardable", 0, NULL, 'f' }, { "proxiable", 0, NULL, 'p' }, { "noaddresses", 0, NULL, 'A' }, { "canonicalize", 0, NULL, 'C' }, { "enterprise", 0, NULL, 'E' }, { "request-pac", 0, &opts->request_pac, 1 }, { "no-request-pac", 0, &opts->not_request_pac, 1 }, { NULL, 0, NULL, 0 } }; krb5_error_code ret; int errflg = 0; int i; while ((i = getopt_long(argc, argv, shopts, long_options, 0)) != -1) { switch (i) { case 'V': opts->verbose = 1; break; case 'l': /* Lifetime */ ret = krb5_string_to_deltat(optarg, &opts->lifetime); if (ret || opts->lifetime == 0) { fprintf(stderr, _("Bad lifetime value %s\n"), optarg); errflg++; } break; case 'r': /* Renewable Time */ ret = krb5_string_to_deltat(optarg, &opts->rlife); if (ret || opts->rlife == 0) { fprintf(stderr, _("Bad lifetime value %s\n"), optarg); errflg++; } break; case 'f': opts->forwardable = 1; break; case 'F': opts->not_forwardable = 1; break; case 'p': opts->proxiable = 1; break; case 'P': opts->not_proxiable = 1; break; case 'n': opts->anonymous = 1; break; case 'a': opts->addresses = 1; break; case 'A': opts->no_addresses = 1; break; case 's': ret = krb5_string_to_deltat(optarg, &opts->starttime); if (ret || opts->starttime == 0) { /* Parse as an absolute time; intentionally undocumented * but left for backwards compatibility. */ krb5_timestamp abs_starttime; ret = krb5_string_to_timestamp(optarg, &abs_starttime); if (ret || abs_starttime == 0) { fprintf(stderr, _("Bad start time value %s\n"), optarg); errflg++; } else { opts->starttime = ts_delta(abs_starttime, time(NULL)); } } break; case 'S': opts->service_name = optarg; break; case 'k': opts->action = INIT_KT; break; case 'i': opts->use_client_keytab = 1; break; case 't': if (opts->keytab_name != NULL) { fprintf(stderr, _("Only one -t option allowed.\n")); errflg++; } else { opts->keytab_name = optarg; } break; case 'T': if (opts->armor_ccache != NULL) { fprintf(stderr, _("Only one armor_ccache\n")); errflg++; } else { opts->armor_ccache = optarg; } break; case 'R': opts->action = RENEW; break; case 'v': opts->action = VALIDATE; break; case 'c': if (opts->k5_out_cache_name != NULL) { fprintf(stderr, _("Only one -c option allowed\n")); errflg++; } else { opts->k5_out_cache_name = optarg; } break; case 'I': if (opts->k5_in_cache_name != NULL) { fprintf(stderr, _("Only one -I option allowed\n")); errflg++; } else { opts->k5_in_cache_name = optarg; } break; case 'X': ret = add_preauth_opt(opts, optarg); if (ret) { com_err(progname, ret, _("while adding preauth option")); errflg++; } break; case 'C': opts->canonicalize = 1; break; case 'E': opts->enterprise = 1; break; case '4': fprintf(stderr, _("Kerberos 4 is no longer supported\n")); exit(3); break; case '5': break; case 0: /* If this option set a flag, do nothing else now. */ break; default: errflg++; break; } } if (opts->forwardable && opts->not_forwardable) { fprintf(stderr, _("Only one of -f and -F allowed\n")); errflg++; } if (opts->proxiable && opts->not_proxiable) { fprintf(stderr, _("Only one of -p and -P allowed\n")); errflg++; } if (opts->request_pac && opts->not_request_pac) { fprintf(stderr, _("Only one of --request-pac and --no-request-pac " "allowed\n")); errflg++; } if (opts->addresses && opts->no_addresses) { fprintf(stderr, _("Only one of -a and -A allowed\n")); errflg++; } if (opts->keytab_name != NULL && opts->use_client_keytab == 1) { fprintf(stderr, _("Only one of -t and -i allowed\n")); errflg++; } if ((opts->keytab_name != NULL || opts->use_client_keytab == 1) && opts->action != INIT_KT) { opts->action = INIT_KT; fprintf(stderr, _("keytab specified, forcing -k\n")); } if (argc - optind > 1) { fprintf(stderr, _("Extra arguments (starting with \"%s\").\n"), argv[optind + 1]); errflg++; } if (errflg) usage(); opts->principal_name = (optind == argc - 1) ? argv[optind] : 0; return opts->principal_name; } static int k5_begin(struct k_opts *opts, struct k5_data *k5) { krb5_error_code ret; int success = 0; int flags = opts->enterprise ? KRB5_PRINCIPAL_PARSE_ENTERPRISE : 0; krb5_ccache defcache = NULL; krb5_principal defcache_princ = NULL, princ; krb5_keytab keytab; const char *deftype = NULL; char *defrealm, *name; ret = krb5_init_context(&k5->ctx); if (ret) { com_err(progname, ret, _("while initializing Kerberos 5 library")); return 0; } errctx = k5->ctx; if (opts->k5_out_cache_name) { ret = krb5_cc_resolve(k5->ctx, opts->k5_out_cache_name, &k5->out_cc); if (ret) { com_err(progname, ret, _("resolving ccache %s"), opts->k5_out_cache_name); goto cleanup; } if (opts->verbose) { fprintf(stderr, _("Using specified cache: %s\n"), opts->k5_out_cache_name); } } else { /* Resolve the default ccache and get its type and default principal * (if it is initialized). */ ret = krb5_cc_default(k5->ctx, &defcache); if (ret) { com_err(progname, ret, _("while getting default ccache")); goto cleanup; } deftype = krb5_cc_get_type(k5->ctx, defcache); if (krb5_cc_get_principal(k5->ctx, defcache, &defcache_princ) != 0) defcache_princ = NULL; } /* Choose a client principal name. */ if (opts->principal_name != NULL) { /* Use the specified principal name. */ ret = krb5_parse_name_flags(k5->ctx, opts->principal_name, flags, &k5->me); if (ret) { com_err(progname, ret, _("when parsing name %s"), opts->principal_name); goto cleanup; } } else if (opts->anonymous) { /* Use the anonymous principal for the local realm. */ ret = krb5_get_default_realm(k5->ctx, &defrealm); if (ret) { com_err(progname, ret, _("while getting default realm")); goto cleanup; } ret = krb5_build_principal_ext(k5->ctx, &k5->me, strlen(defrealm), defrealm, strlen(KRB5_WELLKNOWN_NAMESTR), KRB5_WELLKNOWN_NAMESTR, strlen(KRB5_ANONYMOUS_PRINCSTR), KRB5_ANONYMOUS_PRINCSTR, 0); krb5_free_default_realm(k5->ctx, defrealm); if (ret) { com_err(progname, ret, _("while building principal")); goto cleanup; } } else if (opts->action == INIT_KT && opts->use_client_keytab) { /* Use the first entry from the client keytab. */ ret = krb5_kt_client_default(k5->ctx, &keytab); if (ret) { com_err(progname, ret, _("When resolving the default client keytab")); goto cleanup; } ret = k5_kt_get_principal(k5->ctx, keytab, &k5->me); krb5_kt_close(k5->ctx, keytab); if (ret) { com_err(progname, ret, _("When determining client principal name from keytab")); goto cleanup; } } else if (opts->action == INIT_KT) { /* Use the default host/service name. */ ret = krb5_sname_to_principal(k5->ctx, NULL, NULL, KRB5_NT_SRV_HST, &k5->me); if (ret) { com_err(progname, ret, _("when creating default server principal name")); goto cleanup; } } else if (k5->out_cc != NULL) { /* If the output ccache is initialized, use its principal. */ if (krb5_cc_get_principal(k5->ctx, k5->out_cc, &princ) == 0) k5->me = princ; } else if (defcache_princ != NULL) { /* Use the default cache's principal, and use the default cache as the * output cache. */ k5->out_cc = defcache; defcache = NULL; k5->me = defcache_princ; defcache_princ = NULL; } /* If we still haven't chosen, use the local username. */ if (k5->me == NULL) { name = get_name_from_os(); if (name == NULL) { fprintf(stderr, _("Unable to identify user\n")); goto cleanup; } ret = krb5_parse_name_flags(k5->ctx, name, flags, &k5->me); if (ret) { com_err(progname, ret, _("when parsing name %s"), name); goto cleanup; } } if (k5->out_cc == NULL && krb5_cc_support_switch(k5->ctx, deftype)) { /* Use an existing cache for the client principal if we can. */ ret = krb5_cc_cache_match(k5->ctx, k5->me, &k5->out_cc); if (ret && ret != KRB5_CC_NOTFOUND) { com_err(progname, ret, _("while searching for ccache for %s"), opts->principal_name); goto cleanup; } if (!ret) { if (opts->verbose) { fprintf(stderr, _("Using existing cache: %s\n"), krb5_cc_get_name(k5->ctx, k5->out_cc)); } k5->switch_to_cache = 1; } else if (defcache_princ != NULL) { /* Create a new cache to avoid overwriting the initialized default * cache. */ ret = krb5_cc_new_unique(k5->ctx, deftype, NULL, &k5->out_cc); if (ret) { com_err(progname, ret, _("while generating new ccache")); goto cleanup; } if (opts->verbose) { fprintf(stderr, _("Using new cache: %s\n"), krb5_cc_get_name(k5->ctx, k5->out_cc)); } k5->switch_to_cache = 1; } } /* Use the default cache if we haven't picked one yet. */ if (k5->out_cc == NULL) { k5->out_cc = defcache; defcache = NULL; if (opts->verbose) { fprintf(stderr, _("Using default cache: %s\n"), krb5_cc_get_name(k5->ctx, k5->out_cc)); } } if (opts->k5_in_cache_name) { ret = krb5_cc_resolve(k5->ctx, opts->k5_in_cache_name, &k5->in_cc); if (ret) { com_err(progname, ret, _("resolving ccache %s"), opts->k5_in_cache_name); goto cleanup; } if (opts->verbose) { fprintf(stderr, _("Using specified input cache: %s\n"), opts->k5_in_cache_name); } } ret = krb5_unparse_name(k5->ctx, k5->me, &k5->name); if (ret) { com_err(progname, ret, _("when unparsing name")); goto cleanup; } if (opts->verbose) fprintf(stderr, _("Using principal: %s\n"), k5->name); opts->principal_name = k5->name; success = 1; cleanup: if (defcache != NULL) krb5_cc_close(k5->ctx, defcache); krb5_free_principal(k5->ctx, defcache_princ); return success; } static void k5_end(struct k5_data *k5) { krb5_free_unparsed_name(k5->ctx, k5->name); krb5_free_principal(k5->ctx, k5->me); if (k5->in_cc != NULL) krb5_cc_close(k5->ctx, k5->in_cc); if (k5->out_cc != NULL) krb5_cc_close(k5->ctx, k5->out_cc); krb5_free_context(k5->ctx); errctx = NULL; memset(k5, 0, sizeof(*k5)); } static krb5_error_code KRB5_CALLCONV kinit_prompter(krb5_context ctx, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]) { krb5_boolean *pwprompt = data; krb5_prompt_type *ptypes; int i; /* Make a note if we receive a password prompt. */ ptypes = krb5_get_prompt_types(ctx); for (i = 0; i < num_prompts; i++) { if (ptypes != NULL && ptypes[i] == KRB5_PROMPT_TYPE_PASSWORD) *pwprompt = TRUE; } return krb5_prompter_posix(ctx, data, name, banner, num_prompts, prompts); } static int k5_kinit(struct k_opts *opts, struct k5_data *k5) { int notix = 1; krb5_keytab keytab = 0; krb5_creds my_creds; krb5_error_code ret; krb5_get_init_creds_opt *options = NULL; krb5_boolean pwprompt = FALSE; krb5_address **addresses = NULL; krb5_principal cprinc; krb5_ccache mcc = NULL; int i; memset(&my_creds, 0, sizeof(my_creds)); ret = krb5_get_init_creds_opt_alloc(k5->ctx, &options); if (ret) goto cleanup; if (opts->lifetime) krb5_get_init_creds_opt_set_tkt_life(options, opts->lifetime); if (opts->rlife) krb5_get_init_creds_opt_set_renew_life(options, opts->rlife); if (opts->forwardable) krb5_get_init_creds_opt_set_forwardable(options, 1); if (opts->not_forwardable) krb5_get_init_creds_opt_set_forwardable(options, 0); if (opts->proxiable) krb5_get_init_creds_opt_set_proxiable(options, 1); if (opts->not_proxiable) krb5_get_init_creds_opt_set_proxiable(options, 0); if (opts->canonicalize) krb5_get_init_creds_opt_set_canonicalize(options, 1); if (opts->anonymous) krb5_get_init_creds_opt_set_anonymous(options, 1); if (opts->addresses) { ret = krb5_os_localaddr(k5->ctx, &addresses); if (ret) { com_err(progname, ret, _("getting local addresses")); goto cleanup; } krb5_get_init_creds_opt_set_address_list(options, addresses); } if (opts->no_addresses) krb5_get_init_creds_opt_set_address_list(options, NULL); if (opts->armor_ccache != NULL) { krb5_get_init_creds_opt_set_fast_ccache_name(k5->ctx, options, opts->armor_ccache); } if (opts->request_pac) krb5_get_init_creds_opt_set_pac_request(k5->ctx, options, TRUE); if (opts->not_request_pac) krb5_get_init_creds_opt_set_pac_request(k5->ctx, options, FALSE); if (opts->action == INIT_KT && opts->keytab_name != NULL) { #ifndef _WIN32 if (strncmp(opts->keytab_name, "KDB:", 4) == 0) { ret = kinit_kdb_init(&k5->ctx, k5->me->realm.data); errctx = k5->ctx; if (ret) { com_err(progname, ret, _("while setting up KDB keytab for realm %s"), k5->me->realm.data); goto cleanup; } } #endif ret = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab); if (ret) { com_err(progname, ret, _("resolving keytab %s"), opts->keytab_name); goto cleanup; } if (opts->verbose) fprintf(stderr, _("Using keytab: %s\n"), opts->keytab_name); } else if (opts->action == INIT_KT && opts->use_client_keytab) { ret = krb5_kt_client_default(k5->ctx, &keytab); if (ret) { com_err(progname, ret, _("resolving default client keytab")); goto cleanup; } } for (i = 0; i < opts->num_pa_opts; i++) { ret = krb5_get_init_creds_opt_set_pa(k5->ctx, options, opts->pa_opts[i].attr, opts->pa_opts[i].value); if (ret) { com_err(progname, ret, _("while setting '%s'='%s'"), opts->pa_opts[i].attr, opts->pa_opts[i].value); goto cleanup; } if (opts->verbose) { fprintf(stderr, _("PA Option %s = %s\n"), opts->pa_opts[i].attr, opts->pa_opts[i].value); } } if (k5->in_cc) { ret = krb5_get_init_creds_opt_set_in_ccache(k5->ctx, options, k5->in_cc); if (ret) goto cleanup; } ret = krb5_get_init_creds_opt_set_out_ccache(k5->ctx, options, k5->out_cc); if (ret) goto cleanup; switch (opts->action) { case INIT_PW: ret = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me, 0, kinit_prompter, &pwprompt, opts->starttime, opts->service_name, options); break; case INIT_KT: ret = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me, keytab, opts->starttime, opts->service_name, options); break; case VALIDATE: ret = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->out_cc, opts->service_name); break; case RENEW: ret = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->out_cc, opts->service_name); break; } if (ret) { char *doing = NULL; switch (opts->action) { case INIT_PW: case INIT_KT: doing = _("getting initial credentials"); break; case VALIDATE: doing = _("validating credentials"); break; case RENEW: doing = _("renewing credentials"); break; } /* If reply decryption failed, or if pre-authentication failed and we * were prompted for a password, assume the password was wrong. */ if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY || (pwprompt && ret == KRB5KDC_ERR_PREAUTH_FAILED)) { fprintf(stderr, _("%s: Password incorrect while %s\n"), progname, doing); } else { com_err(progname, ret, _("while %s"), doing); } goto cleanup; } if (opts->action != INIT_PW && opts->action != INIT_KT) { cprinc = opts->canonicalize ? my_creds.client : k5->me; ret = krb5_cc_new_unique(k5->ctx, "MEMORY", NULL, &mcc); if (!ret) ret = krb5_cc_initialize(k5->ctx, mcc, cprinc); if (ret) { com_err(progname, ret, _("when creating temporary cache")); goto cleanup; } if (opts->verbose) fprintf(stderr, _("Initialized cache\n")); ret = k5_cc_store_primary_cred(k5->ctx, mcc, &my_creds); if (ret) { com_err(progname, ret, _("while storing credentials")); goto cleanup; } ret = krb5_cc_move(k5->ctx, mcc, k5->out_cc); if (ret) { com_err(progname, ret, _("while saving to cache %s"), opts->k5_out_cache_name ? opts->k5_out_cache_name : ""); goto cleanup; } mcc = NULL; if (opts->verbose) fprintf(stderr, _("Stored credentials\n")); } notix = 0; if (k5->switch_to_cache) { ret = krb5_cc_switch(k5->ctx, k5->out_cc); if (ret) { com_err(progname, ret, _("while switching to new ccache")); goto cleanup; } } cleanup: #ifndef _WIN32 kinit_kdb_fini(); #endif if (mcc != NULL) krb5_cc_destroy(k5->ctx, mcc); if (options) krb5_get_init_creds_opt_free(k5->ctx, options); if (my_creds.client == k5->me) my_creds.client = 0; if (opts->pa_opts) { free(opts->pa_opts); opts->pa_opts = NULL; opts->num_pa_opts = 0; } krb5_free_cred_contents(k5->ctx, &my_creds); if (keytab != NULL) krb5_kt_close(k5->ctx, keytab); return notix ? 0 : 1; } int main(int argc, char *argv[]) { struct k_opts opts; struct k5_data k5; int authed_k5 = 0; setlocale(LC_ALL, ""); progname = GET_PROGNAME(argv[0]); /* Ensure we can be driven from a pipe */ if (!isatty(fileno(stdin))) setvbuf(stdin, 0, _IONBF, 0); if (!isatty(fileno(stdout))) setvbuf(stdout, 0, _IONBF, 0); if (!isatty(fileno(stderr))) setvbuf(stderr, 0, _IONBF, 0); memset(&opts, 0, sizeof(opts)); opts.action = INIT_PW; memset(&k5, 0, sizeof(k5)); set_com_err_hook(extended_com_err_fn); parse_options(argc, argv, &opts); if (k5_begin(&opts, &k5)) authed_k5 = k5_kinit(&opts, &k5); if (authed_k5 && opts.verbose) fprintf(stderr, _("Authenticated to Kerberos v5\n")); k5_end(&k5); if (!authed_k5) exit(1); return 0; } krb5-1.22.1/src/clients/kinit/deps0000664000175000017500000000406115051422640016566 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)kinit.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h extern.h kinit.c $(OUTPRE)kinit_kdb.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ extern.h kinit_kdb.c krb5-1.22.1/src/clients/kinit/kinit_kdb.c0000664000175000017500000000457015051422640020017 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* clients/kinit/kinit_kdb.c */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /** * @file kinit_kdb.c * Operations to open the KDB and make the KDB key table available * for kinit. */ #include #include #include #include "extern.h" /* Server handle */ static void *server_handle; /* Free and reinitialize *pcontext with the KDB opened to the given realm, so * that it can be used with the KDB keytab type. */ krb5_error_code kinit_kdb_init(krb5_context *pcontext, char *realm) { kadm5_config_params config; krb5_error_code ret; if (*pcontext) { krb5_free_context(*pcontext); *pcontext = NULL; } memset(&config, 0, sizeof config); ret = kadm5_init_krb5_context(pcontext); if (ret) return ret; config.mask = KADM5_CONFIG_REALM; config.realm = realm; ret = kadm5_init(*pcontext, "kinit", NULL, "kinit", &config, KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL, &server_handle); if (ret) return ret; return krb5_db_register_keytab(*pcontext); } void kinit_kdb_fini(void) { kadm5_destroy(server_handle); } krb5-1.22.1/src/clients/kinit/extern.h0000664000175000017500000000275715051422640017400 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* clients/kinit/extern.h - Global declarations for kinit */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef KINIT_EXTERN_H #define KINIT_EXTERN_H krb5_error_code kinit_kdb_init(krb5_context *pcontext, char *realm); void kinit_kdb_fini(void); #endif /* KINIT_EXTERN_H */ krb5-1.22.1/src/clients/kpasswd/0000775000175000017500000000000015051422640016245 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/kpasswd/Makefile.in0000664000175000017500000000154215051422640020314 0ustar ghudsonghudsonmydir=clients$(S)kpasswd BUILDTOP=$(REL)..$(S).. SRCS=kpasswd.c kpasswd: kpasswd.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kpasswd kpasswd.o $(KRB5_BASE_LIBS) kpasswd.o: $(srcdir)/kpasswd.c ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##KPWD=$(OUTPRE)kpasswd.exe ##WIN32##EXERES=$(KPWD:.exe=.res) ##WIN32##$(EXERES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DKPASSWD_APP -fo $@ -r $** all-unix: kpasswd clean-unix:: $(RM) kpasswd.o kpasswd install-all install-kdc install-server install-client install-unix: $(INSTALL_PROGRAM) kpasswd $(DESTDIR)$(CLIENT_BINDIR)/`echo kpasswd|sed '$(transform)'` ##WIN32##all-windows: $(KPWD) ##WIN32##$(KPWD): $(OUTPRE)kpasswd.obj $(KLIB) $(CLIB) $(EXERES) ##WIN32## link $(EXE_LINKOPTS) -out:$@ $** ##WIN32## $(_VC_MANIFEST_EMBED_EXE) krb5-1.22.1/src/clients/kpasswd/deps0000664000175000017500000000042215051422640017121 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)kpasswd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ kpasswd.c krb5-1.22.1/src/clients/kpasswd/kpasswd.c0000664000175000017500000001203515051422640020066 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "k5-platform.h" #include #include #ifndef _WIN32 #include #endif #include #define P1 _("Enter new password") #define P2 _("Enter it again") #ifdef HAVE_PWD_H #include static void get_name_from_passwd_file(char *program_name, krb5_context context, krb5_principal *me) { struct passwd *pw; krb5_error_code ret; pw = getpwuid(getuid()); if (pw != NULL) { ret = krb5_parse_name(context, pw->pw_name, me); if (ret) { com_err(program_name, ret, _("when parsing name %s"), pw->pw_name); exit(1); } } else { fprintf(stderr, _("Unable to identify user from password file\n")); exit(1); } } #else /* HAVE_PWD_H */ static void get_name_from_passwd_file(char *program_name, krb5_context context, krb5_principal *me) { fprintf(stderr, _("Unable to identify user\n")); exit(1); } #endif /* HAVE_PWD_H */ int main(int argc, char *argv[]) { krb5_error_code ret; krb5_context context; krb5_principal princ = NULL; char *pname, *message; char pw[1024]; krb5_ccache ccache; krb5_get_init_creds_opt *opts = NULL; krb5_creds creds; unsigned int pwlen; int result_code; krb5_data result_code_string, result_string; setlocale(LC_ALL, ""); if (argc > 2) { fprintf(stderr, _("usage: %s [principal]\n"), argv[0]); exit(1); } pname = argv[1]; ret = krb5_init_context(&context); if (ret) { com_err(argv[0], ret, _("initializing kerberos library")); exit(1); } ret = krb5_get_init_creds_opt_alloc(context, &opts); if (ret) { com_err(argv[0], ret, _("allocating krb5_get_init_creds_opt")); exit(1); } /* * In order, use the first of: * - A name specified on the command line * - The principal name from an existing ccache * - The name corresponding to the ruid of the process * * Otherwise, it's an error. * We always attempt to open the default ccache in order to use FAST if * possible. */ ret = krb5_cc_default(context, &ccache); if (ret) { com_err(argv[0], ret, _("opening default ccache")); exit(1); } ret = krb5_cc_get_principal(context, ccache, &princ); if (ret && ret != KRB5_CC_NOTFOUND && ret != KRB5_FCC_NOFILE) { com_err(argv[0], ret, _("getting principal from ccache")); exit(1); } else if (princ != NULL) { ret = krb5_get_init_creds_opt_set_fast_ccache(context, opts, ccache); if (ret) { com_err(argv[0], ret, _("while setting FAST ccache")); exit(1); } } ret = krb5_cc_close(context, ccache); if (ret) { com_err(argv[0], ret, _("closing ccache")); exit(1); } if (pname != NULL) { krb5_free_principal(context, princ); princ = NULL; ret = krb5_parse_name(context, pname, &princ); if (ret) { com_err(argv[0], ret, _("parsing client name")); exit(1); } } if (princ == NULL) get_name_from_passwd_file(argv[0], context, &princ); krb5_get_init_creds_opt_set_tkt_life(opts, 5 * 60); krb5_get_init_creds_opt_set_renew_life(opts, 0); krb5_get_init_creds_opt_set_forwardable(opts, 0); krb5_get_init_creds_opt_set_proxiable(opts, 0); ret = krb5_get_init_creds_password(context, &creds, princ, NULL, krb5_prompter_posix, NULL, 0, "kadmin/changepw", opts); if (ret) { if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) { com_err(argv[0], 0, _("Password incorrect while getting initial ticket")); } else { com_err(argv[0], ret, _("getting initial ticket")); } krb5_get_init_creds_opt_free(context, opts); exit(1); } pwlen = sizeof(pw); ret = krb5_read_password(context, P1, P2, pw, &pwlen); if (ret) { com_err(argv[0], ret, _("while reading password")); krb5_get_init_creds_opt_free(context, opts); exit(1); } ret = krb5_change_password(context, &creds, pw, &result_code, &result_code_string, &result_string); if (ret) { com_err(argv[0], ret, _("changing password")); krb5_get_init_creds_opt_free(context, opts); exit(1); } if (result_code) { if (krb5_chpw_message(context, &result_string, &message) != 0) message = NULL; printf("%.*s%s%s\n", (int)result_code_string.length, result_code_string.data, message ? ": " : "", message ? message : NULL); krb5_free_string(context, message); krb5_get_init_creds_opt_free(context, opts); exit(2); } free(result_string.data); free(result_code_string.data); krb5_get_init_creds_opt_free(context, opts); printf(_("Password changed.\n")); exit(0); } krb5-1.22.1/src/clients/klist/0000775000175000017500000000000015051422640015717 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/klist/Makefile.in0000664000175000017500000000153215051422640017765 0ustar ghudsonghudsonmydir=clients$(S)klist BUILDTOP=$(REL)..$(S).. ##WIN32##LOCALINCLUDES=-I$(BUILDTOP)\util\windows\ SRCS = klist.c ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##KLIST=$(OUTPRE)klist.exe ##WIN32##EXERES=$(KLIST:.exe=.res) ##WIN32##$(EXERES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DKLIST_APP -fo $@ -r $** all-unix: klist ##WIN32##all-windows: $(KLIST) klist: klist.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ klist.o $(KRB5_BASE_LIBS) ##WIN32##$(KLIST): $(OUTPRE)klist.obj $(SLIB) $(KLIB) $(CLIB) $(EXERES) ##WIN32## link $(EXE_LINKOPTS) -out:$@ $** ws2_32.lib ##WIN32## $(_VC_MANIFEST_EMBED_EXE) clean-unix:: $(RM) klist.o klist install-unix: for f in klist; do \ $(INSTALL_PROGRAM) $$f \ $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \ done krb5-1.22.1/src/clients/klist/deps0000664000175000017500000000142215051422640016574 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)klist.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ klist.c krb5-1.22.1/src/clients/klist/klist.c0000664000175000017500000006330215051422640017215 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* clients/klist/klist.c - List contents of credential cache or keytab */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include #include #include #include #include #include #include /* Need definition of INET6 before network headers, for IRIX. */ #if defined(HAVE_ARPA_INET_H) #include #endif #ifndef _WIN32 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/') + 1 : (x)) #else #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x)) #endif #ifndef _WIN32 #include #include #endif int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0; int show_etype = 0, show_addresses = 0, no_resolve = 0, print_version = 0; int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0; int show_config = 0; char *progname; krb5_timestamp now; unsigned int timestamp_width; krb5_context context; static krb5_boolean is_local_tgt(krb5_principal princ, krb5_data *realm); static char *etype_string(krb5_enctype ); static void show_credential(krb5_creds *, const char *); static void list_all_ccaches(void); static int list_ccache(krb5_ccache); static void show_all_ccaches(void); static void do_ccache(void); static int show_ccache(krb5_ccache); static int check_ccache(krb5_ccache); static void do_keytab(const char *); static void printtime(krb5_timestamp); static void one_addr(krb5_address *); static void fillit(FILE *, unsigned int, int); #define DEFAULT 0 #define CCACHE 1 #define KEYTAB 2 static void usage(void) { fprintf(stderr, _("Usage: %s [-e] [-V] [[-c] [-l] [-A] [-d] [-f] [-s] " "[-a [-n]]] [-k [-i] [-t] [-K]] [-C] [name]\n"), progname); fprintf(stderr, _("\t-c specifies credentials cache\n")); fprintf(stderr, _("\t-k specifies keytab\n")); fprintf(stderr, _("\t (Default is credentials cache)\n")); fprintf(stderr, _("\t-i uses default client keytab if no name given\n")); fprintf(stderr, _("\t-l lists credential caches in collection\n")); fprintf(stderr, _("\t-A shows content of all credential caches\n")); fprintf(stderr, _("\t-e shows the encryption type\n")); fprintf(stderr, _("\t-V shows the Kerberos version and exits\n")); fprintf(stderr, _("\toptions for credential caches:\n")); fprintf(stderr, _("\t\t-d shows the submitted authorization data " "types\n")); fprintf(stderr, _("\t\t-f shows credentials flags\n")); fprintf(stderr, _("\t\t-s sets exit status based on valid tgt " "existence\n")); fprintf(stderr, _("\t\t-a displays the address list\n")); fprintf(stderr, _("\t\t\t-n do not reverse-resolve\n")); fprintf(stderr, _("\toptions for keytabs:\n")); fprintf(stderr, _("\t\t-t shows keytab entry timestamps\n")); fprintf(stderr, _("\t\t-K shows keytab entry keys\n")); fprintf(stderr, _("\t\t-C includes configuration data entries\n")); exit(1); } static void extended_com_err_fn(const char *prog, errcode_t code, const char *fmt, va_list args) { const char *msg; msg = krb5_get_error_message(context, code); fprintf(stderr, "%s: %s%s", prog, msg, (*fmt == '\0') ? "" : " "); krb5_free_error_message(context, msg); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } int main(int argc, char *argv[]) { krb5_error_code ret; char *name, tmp[BUFSIZ]; int c, mode; setlocale(LC_ALL, ""); progname = GET_PROGNAME(argv[0]); set_com_err_hook(extended_com_err_fn); name = NULL; mode = DEFAULT; /* V = version so v can be used for verbose later if desired. */ while ((c = getopt(argc, argv, "dfetKsnacki45lAVC")) != -1) { switch (c) { case 'd': show_adtype = 1; break; case 'f': show_flags = 1; break; case 'e': show_etype = 1; break; case 't': show_time = 1; break; case 'K': show_keys = 1; break; case 's': status_only = 1; break; case 'n': no_resolve = 1; break; case 'a': show_addresses = 1; break; case 'c': if (mode != DEFAULT) usage(); mode = CCACHE; break; case 'k': if (mode != DEFAULT) usage(); mode = KEYTAB; break; case 'i': use_client_keytab = 1; break; case '4': fprintf(stderr, _("Kerberos 4 is no longer supported\n")); exit(3); break; case '5': break; case 'l': list_all = 1; break; case 'A': show_all = 1; break; case 'C': show_config = 1; break; case 'V': print_version = 1; break; default: usage(); break; } } if (no_resolve && !show_addresses) usage(); if (mode == DEFAULT || mode == CCACHE) { if (show_time || show_keys) usage(); if ((show_all && list_all) || (status_only && list_all)) usage(); } else { if (show_flags || status_only || show_addresses || show_all || list_all) usage(); } if (argc - optind > 1) { fprintf(stderr, _("Extra arguments (starting with \"%s\").\n"), argv[optind + 1]); usage(); } if (print_version) { #ifdef _WIN32 /* No access to autoconf vars; fix somehow. */ printf("Kerberos for Windows\n"); #else printf(_("%s version %s\n"), PACKAGE_NAME, PACKAGE_VERSION); #endif exit(0); } name = (optind == argc - 1) ? argv[optind] : NULL; now = time(0); if (!krb5_timestamp_to_sfstring(now, tmp, 20, NULL) || !krb5_timestamp_to_sfstring(now, tmp, sizeof(tmp), NULL)) timestamp_width = (int)strlen(tmp); else timestamp_width = 15; ret = krb5_init_context(&context); if (ret) { com_err(progname, ret, _("while initializing krb5")); exit(1); } if (name != NULL && mode != KEYTAB) { ret = krb5_cc_set_default_name(context, name); if (ret) { com_err(progname, ret, _("while setting default cache name")); exit(1); } } if (list_all) list_all_ccaches(); else if (show_all) show_all_ccaches(); else if (mode == DEFAULT || mode == CCACHE) do_ccache(); else do_keytab(name); return 0; } static void do_keytab(const char *name) { krb5_error_code ret; krb5_keytab kt; krb5_keytab_entry entry; krb5_kt_cursor cursor; unsigned int i; char buf[BUFSIZ]; /* Hopefully large enough for any type */ char *pname; if (name == NULL && use_client_keytab) { ret = krb5_kt_client_default(context, &kt); if (ret) { com_err(progname, ret, _("while getting default client keytab")); exit(1); } } else if (name == NULL) { ret = krb5_kt_default(context, &kt); if (ret) { com_err(progname, ret, _("while getting default keytab")); exit(1); } } else { ret = krb5_kt_resolve(context, name, &kt); if (ret) { com_err(progname, ret, _("while resolving keytab %s"), name); exit(1); } } ret = krb5_kt_get_name(context, kt, buf, BUFSIZ); if (ret) { com_err(progname, ret, _("while getting keytab name")); exit(1); } printf("Keytab name: %s\n", buf); ret = krb5_kt_start_seq_get(context, kt, &cursor); if (ret) { com_err(progname, ret, _("while starting keytab scan")); exit(1); } /* XXX Translating would disturb table alignment; skip for now. */ if (show_time) { printf("KVNO Timestamp"); fillit(stdout, timestamp_width - sizeof("Timestamp") + 2, (int) ' '); printf("Principal\n"); printf("---- "); fillit(stdout, timestamp_width, (int) '-'); printf(" "); fillit(stdout, 78 - timestamp_width - sizeof("KVNO"), (int) '-'); printf("\n"); } else { printf("KVNO Principal\n"); printf("---- ------------------------------------------------" "--------------------------\n"); } while ((ret = krb5_kt_next_entry(context, kt, &entry, &cursor)) == 0) { ret = krb5_unparse_name(context, entry.principal, &pname); if (ret) { com_err(progname, ret, _("while unparsing principal name")); exit(1); } printf("%4d ", entry.vno); if (show_time) { printtime(entry.timestamp); printf(" "); } printf("%s", pname); if (show_etype) printf(" (%s) " , etype_string(entry.key.enctype)); if (show_keys) { printf(" (0x"); for (i = 0; i < entry.key.length; i++) printf("%02x", entry.key.contents[i]); printf(")"); } printf("\n"); krb5_free_unparsed_name(context, pname); krb5_free_keytab_entry_contents(context, &entry); } if (ret && ret != KRB5_KT_END) { com_err(progname, ret, _("while scanning keytab")); exit(1); } ret = krb5_kt_end_seq_get(context, kt, &cursor); if (ret) { com_err(progname, ret, _("while ending keytab scan")); exit(1); } exit(0); } static void list_all_ccaches(void) { krb5_error_code ret; krb5_ccache cache; krb5_cccol_cursor cursor; int exit_status; ret = krb5_cccol_cursor_new(context, &cursor); if (ret) { if (!status_only) com_err(progname, ret, _("while listing ccache collection")); exit(1); } /* XXX Translating would disturb table alignment; skip for now. */ printf("%-30s %s\n", "Principal name", "Cache name"); printf("%-30s %s\n", "--------------", "----------"); exit_status = 1; while ((ret = krb5_cccol_cursor_next(context, cursor, &cache)) == 0 && cache != NULL) { exit_status = list_ccache(cache) && exit_status; krb5_cc_close(context, cache); } krb5_cccol_cursor_free(context, &cursor); exit(exit_status); } static int list_ccache(krb5_ccache cache) { krb5_error_code ret; krb5_principal princ = NULL; char *princname = NULL, *ccname = NULL; int expired, status = 1; ret = krb5_cc_get_principal(context, cache, &princ); if (ret) /* Uninitialized cache file, probably. */ goto cleanup; ret = krb5_unparse_name(context, princ, &princname); if (ret) goto cleanup; ret = krb5_cc_get_full_name(context, cache, &ccname); if (ret) goto cleanup; expired = check_ccache(cache); printf("%-30.30s %s", princname, ccname); if (expired) printf(" %s", _("(Expired)")); printf("\n"); status = 0; cleanup: krb5_free_principal(context, princ); krb5_free_unparsed_name(context, princname); krb5_free_string(context, ccname); return status; } static void show_all_ccaches(void) { krb5_error_code ret; krb5_ccache cache; krb5_cccol_cursor cursor; krb5_boolean first; int exit_status, st; ret = krb5_cccol_cursor_new(context, &cursor); if (ret) { if (!status_only) com_err(progname, ret, _("while listing ccache collection")); exit(1); } exit_status = 1; first = TRUE; while ((ret = krb5_cccol_cursor_next(context, cursor, &cache)) == 0 && cache != NULL) { if (!status_only && !first) printf("\n"); first = FALSE; st = status_only ? check_ccache(cache) : show_ccache(cache); exit_status = st && exit_status; krb5_cc_close(context, cache); } krb5_cccol_cursor_free(context, &cursor); exit(exit_status); } static void do_ccache(void) { krb5_error_code ret; krb5_ccache cache; ret = krb5_cc_default(context, &cache); if (ret) { if (!status_only) com_err(progname, ret, _("while resolving ccache")); exit(1); } exit(status_only ? check_ccache(cache) : show_ccache(cache)); } /* Display the contents of cache. */ static int show_ccache(krb5_ccache cache) { krb5_cc_cursor cur = NULL; krb5_creds creds; krb5_principal princ = NULL; krb5_error_code ret; char *defname = NULL; int status = 1; ret = krb5_cc_get_principal(context, cache, &princ); if (ret) { com_err(progname, ret, ""); goto cleanup; } ret = krb5_unparse_name(context, princ, &defname); if (ret) { com_err(progname, ret, _("while unparsing principal name")); goto cleanup; } printf(_("Ticket cache: %s:%s\nDefault principal: %s\n\n"), krb5_cc_get_type(context, cache), krb5_cc_get_name(context, cache), defname); /* XXX Translating would disturb table alignment; skip for now. */ fputs("Valid starting", stdout); fillit(stdout, timestamp_width - sizeof("Valid starting") + 3, (int) ' '); fputs("Expires", stdout); fillit(stdout, timestamp_width - sizeof("Expires") + 3, (int) ' '); fputs("Service principal\n", stdout); ret = krb5_cc_start_seq_get(context, cache, &cur); if (ret) { com_err(progname, ret, _("while starting to retrieve tickets")); goto cleanup; } while ((ret = krb5_cc_next_cred(context, cache, &cur, &creds)) == 0) { if (show_config || !krb5_is_config_principal(context, creds.server)) show_credential(&creds, defname); krb5_free_cred_contents(context, &creds); } if (ret == KRB5_CC_END) { ret = krb5_cc_end_seq_get(context, cache, &cur); cur = NULL; if (ret) { com_err(progname, ret, _("while finishing ticket retrieval")); goto cleanup; } } else { com_err(progname, ret, _("while retrieving a ticket")); goto cleanup; } status = 0; cleanup: if (cur != NULL) (void)krb5_cc_end_seq_get(context, cache, &cur); krb5_free_principal(context, princ); krb5_free_unparsed_name(context, defname); return status; } /* Return 0 if cache is accessible, present, and unexpired; return 1 if not. */ static int check_ccache(krb5_ccache cache) { krb5_error_code ret; krb5_cc_cursor cur = NULL; krb5_creds creds; krb5_principal princ = NULL; krb5_boolean found_tgt = FALSE, found_current_tgt = FALSE; krb5_boolean found_current_cred = FALSE; ret = krb5_cc_get_principal(context, cache, &princ); if (ret) goto cleanup; ret = krb5_cc_start_seq_get(context, cache, &cur); if (ret) goto cleanup; found_tgt = found_current_tgt = found_current_cred = FALSE; while ((ret = krb5_cc_next_cred(context, cache, &cur, &creds)) == 0) { if (is_local_tgt(creds.server, &princ->realm)) { found_tgt = TRUE; if (ts_after(creds.times.endtime, now)) found_current_tgt = TRUE; } else if (!krb5_is_config_principal(context, creds.server) && ts_after(creds.times.endtime, now)) { found_current_cred = TRUE; } krb5_free_cred_contents(context, &creds); } if (ret != KRB5_CC_END) goto cleanup; ret = krb5_cc_end_seq_get(context, cache, &cur); cur = NULL; cleanup: if (cur != NULL) (void)krb5_cc_end_seq_get(context, cache, &cur); krb5_free_principal(context, princ); if (ret) return 1; /* If the cache contains at least one local TGT, require that it be * current. Otherwise accept any current cred. */ if (found_tgt) return found_current_tgt ? 0 : 1; return found_current_cred ? 0 : 1; } /* Return true if princ is the local krbtgt principal for local_realm. */ static krb5_boolean is_local_tgt(krb5_principal princ, krb5_data *realm) { return princ->length == 2 && data_eq(princ->realm, *realm) && data_eq_string(princ->data[0], KRB5_TGS_NAME) && data_eq(princ->data[1], *realm); } static char * etype_string(krb5_enctype enctype) { static char buf[100]; char *bp = buf; size_t deplen, buflen = sizeof(buf); if (krb5int_c_deprecated_enctype(enctype)) { deplen = strlcpy(bp, "DEPRECATED:", buflen); buflen -= deplen; bp += deplen; } if (krb5_enctype_to_name(enctype, FALSE, bp, buflen)) snprintf(bp, buflen, "etype %d", enctype); return buf; } static char * flags_string(krb5_creds *cred) { static char buf[32]; int i = 0; if (cred->ticket_flags & TKT_FLG_FORWARDABLE) buf[i++] = 'F'; if (cred->ticket_flags & TKT_FLG_FORWARDED) buf[i++] = 'f'; if (cred->ticket_flags & TKT_FLG_PROXIABLE) buf[i++] = 'P'; if (cred->ticket_flags & TKT_FLG_PROXY) buf[i++] = 'p'; if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE) buf[i++] = 'D'; if (cred->ticket_flags & TKT_FLG_POSTDATED) buf[i++] = 'd'; if (cred->ticket_flags & TKT_FLG_INVALID) buf[i++] = 'i'; if (cred->ticket_flags & TKT_FLG_RENEWABLE) buf[i++] = 'R'; if (cred->ticket_flags & TKT_FLG_INITIAL) buf[i++] = 'I'; if (cred->ticket_flags & TKT_FLG_HW_AUTH) buf[i++] = 'H'; if (cred->ticket_flags & TKT_FLG_PRE_AUTH) buf[i++] = 'A'; if (cred->ticket_flags & TKT_FLG_TRANSIT_POLICY_CHECKED) buf[i++] = 'T'; if (cred->ticket_flags & TKT_FLG_OK_AS_DELEGATE) buf[i++] = 'O'; /* D/d are taken. Use short strings? */ if (cred->ticket_flags & TKT_FLG_ANONYMOUS) buf[i++] = 'a'; buf[i] = '\0'; return buf; } static void printtime(krb5_timestamp ts) { char timestring[BUFSIZ], fill = ' '; if (!krb5_timestamp_to_sfstring(ts, timestring, timestamp_width + 1, &fill)) printf("%s", timestring); } static void print_config_data(int col, krb5_data *data) { unsigned int i; for (i = 0; i < data->length; i++) { while (col < 8) { putchar(' '); col++; } if (data->data[i] > 0x20 && data->data[i] < 0x7f) { putchar(data->data[i]); col++; } else { col += printf("\\%03o", (unsigned char)data->data[i]); } if (col > 72) { putchar('\n'); col = 0; } } if (col > 0) putchar('\n'); } static void show_credential(krb5_creds *cred, const char *defname) { krb5_error_code ret; krb5_ticket *tkt = NULL; char *name = NULL, *sname = NULL, *tktsname, *flags; int extra_field = 0, ccol = 0, i, r; krb5_boolean is_config = krb5_is_config_principal(context, cred->server); ret = krb5_unparse_name(context, cred->client, &name); if (ret) { com_err(progname, ret, _("while unparsing client name")); goto cleanup; } ret = krb5_unparse_name(context, cred->server, &sname); if (ret) { com_err(progname, ret, _("while unparsing server name")); goto cleanup; } if (!is_config) (void)krb5_decode_ticket(&cred->ticket, &tkt); if (!cred->times.starttime) cred->times.starttime = cred->times.authtime; if (!is_config) { printtime(cred->times.starttime); putchar(' '); putchar(' '); printtime(cred->times.endtime); putchar(' '); putchar(' '); printf("%s\n", sname); } else { fputs("config: ", stdout); ccol = 8; for (i = 1; i < cred->server->length; i++) { r = printf("%s%.*s%s", i > 1 ? "(" : "", (int)cred->server->data[i].length, cred->server->data[i].data, i > 1 ? ")" : ""); if (r >= 0) ccol += r; } fputs(" = ", stdout); ccol += 3; } if (strcmp(name, defname)) { printf(_("\tfor client %s"), name); extra_field++; } if (is_config) print_config_data(ccol, &cred->ticket); if (cred->times.renew_till) { if (!extra_field) fputs("\t",stdout); else fputs(", ",stdout); fputs(_("renew until "), stdout); printtime(cred->times.renew_till); extra_field += 2; } if (show_flags) { flags = flags_string(cred); if (flags && *flags) { if (!extra_field) fputs("\t",stdout); else fputs(", ",stdout); printf(_("Flags: %s"), flags); extra_field++; } } if (extra_field > 2) { fputs("\n", stdout); extra_field = 0; } if (show_etype && tkt != NULL) { if (!extra_field) fputs("\t",stdout); else fputs(", ",stdout); printf(_("Etype (skey, tkt): %s, "), etype_string(cred->keyblock.enctype)); printf("%s ", etype_string(tkt->enc_part.enctype)); extra_field++; } if (show_adtype) { if (cred->authdata != NULL) { if (!extra_field) fputs("\t",stdout); else fputs(", ",stdout); printf(_("AD types: ")); for (i = 0; cred->authdata[i] != NULL; i++) { if (i) printf(", "); printf("%d", cred->authdata[i]->ad_type); } extra_field++; } } /* If any additional info was printed, extra_field is non-zero. */ if (extra_field) putchar('\n'); if (show_addresses) { if (cred->addresses == NULL || cred->addresses[0] == NULL) { printf(_("\tAddresses: (none)\n")); } else { printf(_("\tAddresses: ")); one_addr(cred->addresses[0]); for (i = 1; cred->addresses[i] != NULL; i++) { printf(", "); one_addr(cred->addresses[i]); } printf("\n"); } } /* Display the ticket server if it is different from the server name the * entry was cached under (most commonly for referrals). */ if (tkt != NULL && !krb5_principal_compare(context, cred->server, tkt->server)) { ret = krb5_unparse_name(context, tkt->server, &tktsname); if (ret) { com_err(progname, ret, _("while unparsing ticket server name")); goto cleanup; } printf(_("\tTicket server: %s\n"), tktsname); krb5_free_unparsed_name(context, tktsname); } cleanup: krb5_free_unparsed_name(context, name); krb5_free_unparsed_name(context, sname); krb5_free_ticket(context, tkt); } #include "port-sockets.h" #include "socket-utils.h" /* For ss2sin etc. */ #include "fake-addrinfo.h" static void one_addr(krb5_address *a) { struct sockaddr_storage ss; struct sockaddr_in *sinp; struct sockaddr_in6 *sin6p; int err, i; char namebuf[NI_MAXHOST]; const uint8_t *p; memset(&ss, 0, sizeof(ss)); switch (a->addrtype) { case ADDRTYPE_INET: if (a->length != 4) { printf(_("broken address (type %d length %d)"), a->addrtype, a->length); return; } sinp = ss2sin(&ss); sinp->sin_family = AF_INET; memcpy(&sinp->sin_addr, a->contents, 4); break; case ADDRTYPE_INET6: if (a->length != 16) { printf(_("broken address (type %d length %d)"), a->addrtype, a->length); return; } sin6p = ss2sin6(&ss); sin6p->sin6_family = AF_INET6; memcpy(&sin6p->sin6_addr, a->contents, 16); break; case ADDRTYPE_NETBIOS: if (a->length != 16) { printf(_("broken address (type %d length %d)"), a->addrtype, a->length); return; } p = a->contents; for (i = 0; i < 15 && p[i] != '\0' && p[i] != ' '; i++) putchar(p[i]); return; default: printf(_("unknown addrtype %d"), a->addrtype); return; } namebuf[0] = 0; err = getnameinfo(ss2sa(&ss), sa_socklen(ss2sa(&ss)), namebuf, sizeof(namebuf), 0, 0, no_resolve ? NI_NUMERICHOST : 0U); if (err) { printf(_("unprintable address (type %d, error %d %s)"), a->addrtype, err, gai_strerror(err)); return; } printf("%s", namebuf); } static void fillit(FILE *f, unsigned int num, int c) { unsigned int i; for (i = 0; i < num; i++) fputc(c, f); } krb5-1.22.1/src/clients/kswitch/0000775000175000017500000000000015051422640016245 5ustar ghudsonghudsonkrb5-1.22.1/src/clients/kswitch/Makefile.in0000664000175000017500000000147115051422640020315 0ustar ghudsonghudsonmydir=clients$(S)kswitch BUILDTOP=$(REL)..$(S).. SRCS=kswitch.c ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##KSWITCH=$(OUTPRE)kswitch.exe ##WIN32##EXERES=$(KSWITCH:.exe=.res) ##WIN32##$(EXERES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DKSWITCH_APP -fo $@ -r $** all-unix: kswitch ##WIN32##all-windows: $(KSWITCH) kswitch: kswitch.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ kswitch.o $(KRB5_BASE_LIBS) ##WIN32##$(KSWITCH): $(OUTPRE)kswitch.obj $(SLIB) $(KLIB) $(CLIB) $(EXERES) ##WIN32## link $(EXE_LINKOPTS) -out:$@ $** ##WIN32## $(_VC_MANIFEST_EMBED_EXE) clean-unix:: $(RM) kswitch.o kswitch install-unix: for f in kswitch; do \ $(INSTALL_PROGRAM) $$f \ $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'`; \ done krb5-1.22.1/src/clients/kswitch/deps0000664000175000017500000000135415051422640017126 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)kswitch.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kswitch.c krb5-1.22.1/src/clients/kswitch/kswitch.c0000664000175000017500000000763015051422640020073 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* clients/kswitch/kswitch.c - Switch primary credential cache */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include #ifndef _WIN32 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x)) #else #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x)) #endif static char *progname; static void usage(void) { fprintf(stderr, _("Usage: %s {-c cache_name | -p principal}\n"), progname); fprintf(stderr, _("\t-c specify name of credentials cache\n")); fprintf(stderr, _("\t-p specify name of principal\n")); exit(2); } int main(int argc, char **argv) { krb5_context context; krb5_error_code ret; int c; krb5_ccache cache = NULL; krb5_principal princ = NULL; const char *cache_name = NULL, *princ_name = NULL; krb5_boolean errflag = FALSE; setlocale(LC_ALL, ""); progname = GET_PROGNAME(argv[0]); while ((c = getopt(argc, argv, "c:p:")) != -1) { switch (c) { case 'c': case 'p': if (cache_name || princ_name) { fprintf(stderr, _("Only one -c or -p option allowed\n")); errflag = TRUE; } else if (c == 'c') { cache_name = optarg; } else { princ_name = optarg; } break; case '?': default: errflag = TRUE; break; } } if (optind != argc) errflag = TRUE; if (!cache_name && !princ_name) { fprintf(stderr, _("One of -c or -p must be specified\n")); errflag = TRUE; } if (errflag) usage(); ret = krb5_init_context(&context); if (ret) { com_err(progname, ret, _("while initializing krb5")); exit(1); } if (cache_name) { ret = krb5_cc_resolve(context, cache_name, &cache); if (ret != 0) { com_err(progname, ret, _("while resolving %s"), cache_name); exit(1); } } else { ret = krb5_parse_name(context, princ_name, &princ); if (ret) { com_err(progname, ret, _("while parsing principal name %s"), princ_name); exit(1); } ret = krb5_cc_cache_match(context, princ, &cache); if (ret) { com_err(progname, ret, _("while searching for ccache for %s"), princ_name); exit(1); } krb5_free_principal(context, princ); } ret = krb5_cc_switch(context, cache); if (ret != 0) { com_err(progname, ret, _("while switching to credential cache")); exit(1); } krb5_cc_close(context, cache); krb5_free_context(context); return 0; } krb5-1.22.1/src/doc/0000775000175000017500000000000015051422775013706 5ustar ghudsonghudsonkrb5-1.22.1/src/doc/version.py.in0000664000175000017500000000047215051422640016344 0ustar ghudsonghudson#include "patchlevel.h" r_major = KRB5_MAJOR_RELEASE r_minor = KRB5_MINOR_RELEASE r_patch = KRB5_PATCHLEVEL #ifdef KRB5_RELTAIL r_tail = KRB5_RELTAIL #else r_tail = None #endif #ifdef KRB5_RELDATE r_date = KRB5_RELDATE #else r_date = None #endif #ifdef KRB5_RELTAG r_tag = KRB5_RELTAG #else r_date = None #endif krb5-1.22.1/src/doc/Makefile.in0000664000175000017500000001024415051422640015743 0ustar ghudsonghudsonmydir=doc BUILDTOP=$(REL).. SPHINX_ARGS=@MAINT@-W SPHINX_BUILD=sphinx-build $(SPHINX_ARGS) DOXYGEN=doxygen docsrc=$(top_srcdir)/../doc sysconfdir=@sysconfdir@ DEFCCNAME=@DEFCCNAME@ DEFKTNAME=@DEFKTNAME@ DEFCKTNAME=@DEFCKTNAME@ PKCS11_MODNAME=@PKCS11_MODNAME@ RST_SOURCES= _static \ _templates \ conf.py \ index.rst \ admin \ appdev \ basic \ build \ formats \ plugindev \ user \ about.rst \ build_this.rst \ copyright.rst \ mitK5defaults.rst \ mitK5features.rst \ mitK5license.rst \ notice.rst \ resources.rst PDFDIR=$(docsrc)/pdf PDFDOCS= admin appdev basic build plugindev user LATEXOPTS= # Create HTML documentation in $(docsrc)/html suitable for a # release tarball or the web site (that is, without substitutions for # configured paths). This can be done in an unconfigured source tree # as: # make -f Makefile.in SPHINX_ARGS= htmlsrc html: composite rm -rf $(docsrc)/html $(SPHINX_BUILD) -q rst_composite $(docsrc)/html # Dummy target for use in an unconfigured source tree. htmlsrc: $(MAKE) -f Makefile.in srcdir=. top_srcdir=.. PYTHON=python3 html clean # Create HTML documentation in html_subst suitable for # installation by an OS package, with substitutions for configured # paths. substhtml: composite paths.py rm -rf html_subst cp paths.py rst_composite $(SPHINX_BUILD) -t pathsubs -q rst_composite html_subst # Create an ASCII (okay, UTF-8) version of the NOTICE file notice.txt: $(docsrc)/conf.py $(docsrc)/notice.rst $(docsrc)/version.py $(SPHINX_BUILD) -b text -t notice -q $(docsrc) . NOTICE: notice.txt cp notice.txt $(top_srcdir)/../NOTICE $(PDFDIR): composite $(SPHINX_BUILD) -b latex -q rst_composite $(PDFDIR) # sphinx-build generates a gmake-specific Makefile that we don't use mv $(PDFDIR)/Makefile $(PDFDIR)/GMakefile # Not pretty. Can't use a suffix rule .tex.pdf without a Makefile in # $(PDFDIR) because pdflatex looks for include files in the current # working directory. The sphinx-build Makefile is quite conservative # and runs pdflatex five times; we can be slightly less conservative. pdf: $(PDFDIR) (cd $(PDFDIR) && \ for i in $(PDFDOCS); do \ texfile=`echo $${i}.tex` && \ idxfile=`echo $${i}.idx` && \ pdflatex $(LATEXOPTS) $$texfile && \ pdflatex $(LATEXOPTS) $$texfile && \ makeindex -s python.ist $$idxfile || true; \ pdflatex $(LATEXOPTS) $$texfile && \ pdflatex $(LATEXOPTS) $$texfile; done && \ rm -f *.dvi *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla \ ) # Use doxygen to generate API documentation, translate it into RST # format, and then create a composite of $(docsrc)'s RST and the # generated files in rst_composite. Used by the html and substhtml targets. composite: Doxyfile $(docsrc)/version.py rm -rf doxy rst_apiref rst_composite $(DOXYGEN) (cwd=`pwd`; cd $(docsrc)/tools && \ $(PYTHON) doxy.py -i $$cwd/doxy/xml -o $$cwd/rst_apiref) mkdir -p rst_composite do_subdirs="$(RST_SOURCES)" ; \ for i in $$do_subdirs; do \ cp -r $(docsrc)/$$i rst_composite; \ done cp rst_apiref/*.rst rst_composite/appdev/refs/api cp rst_apiref/types/*.rst rst_composite/appdev/refs/types cp rst_apiref/macros/*.rst rst_composite/appdev/refs/macros cp $(docsrc)/version.py rst_composite Doxyfile: $(srcdir)/Doxyfile.in sed -e 's|@SRC@|$(top_srcdir)|g' \ -e 's|@DOC@|$(top_srcdir)/../doc|g' $(srcdir)/Doxyfile.in > $@ paths.py: rm -f $@ echo 'bindir = "``$(CLIENT_BINDIR)``"' > $@ echo 'sbindir = "``$(SERVER_BINDIR)``"' >> $@ echo 'libdir = "``$(KRB5_LIBDIR)``"' >> $@ echo 'localstatedir = "``$(localstatedir)``"' >> $@ echo 'runstatedir = "``$(runstatedir)``"' >> $@ echo 'sysconfdir = "``$(sysconfdir)``"' >> $@ echo 'ccache = "``$(DEFCCNAME)``"' >> $@ echo 'keytab = "``$(DEFKTNAME)``"' >> $@ echo 'ckeytab = "``$(DEFCKTNAME)``"' >> $@ echo 'pkcs11_modname = "``$(PKCS11_MODNAME)``"' >> $@ # Dummy rule that man/Makefile can invoke version.py: $(docsrc)/version.py $(docsrc)/version.py: $(top_srcdir)/patchlevel.h $(srcdir)/version.py.in rm -f $@ $(CC) -E -I$(top_srcdir) - < $(srcdir)/version.py.in > $@ clean: rm -rf doxy rst_apiref rst_composite rst_notice html_subst \ Doxyfile paths.py $(docsrc)/version.py notice.txt \ $(docsrc)/html/.doctrees $(docsrc)/pdf/.doctrees \ $(docsrc)/tools/*.pyc krb5-1.22.1/src/doc/Doxyfile.in0000664000175000017500000000102615051422640016007 0ustar ghudsonghudsonPROJECT_NAME = Kerberos_doxygen OUTPUT_DIRECTORY = doxy JAVADOC_AUTOBRIEF = YES OPTIMIZE_OUTPUT_FOR_C = YES WARN_IF_UNDOCUMENTED = NO SHOW_FILES = NO EXTENSION_MAPPING = hin=C INPUT = @SRC@/include/krb5/krb5.hin @DOC@/doxy_examples EXAMPLE_PATH = @DOC@/doxy_examples GENERATE_HTML = NO GENERATE_LATEX = NO GENERATE_XML = YES PREDEFINED = KRB5_DEPRECATED KRB5_OLD_CRYPTO CASE_SENSE_NAMES = NO QUIET = YES krb5-1.22.1/src/doc/deps0000664000175000017500000000003015051422640014544 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/configure.ac0000664000175000017500000014174715051422640015434 0ustar ghudsonghudsonK5_AC_INIT([aclocal.m4]) # If $runstatedir isn't set by autoconf (<2.70), set it manually. if test x"$runstatedir" = x; then runstatedir='${localstatedir}/run' fi AC_SUBST(runstatedir) # Don't make duplicate profile path entries for /etc/krb5.conf if # $sysconfdir is /etc if test "$sysconfdir" = /etc; then SYSCONFCONF="" else SYSCONFCONF=":${sysconfdir}/krb5.conf" fi AC_SUBST(SYSCONFCONF) CONFIG_RULES KRB5_VERSION=K5_VERSION AC_SUBST(KRB5_VERSION) AC_REQUIRE_CPP PKG_PROG_PKG_CONFIG AC_CHECK_HEADER([stdint.h], [], [AC_MSG_ERROR([stdint.h is required])]) AC_CACHE_CHECK([whether integers are two's complement], [krb5_cv_ints_twos_compl], [AC_COMPILE_IFELSE( [AC_LANG_BOOL_COMPILE_TRY( [#include ], [/* Basic two's complement check */ ~(-1) == 0 && ~(-1L) == 0L && /* Check that values with sign bit 1 and value bits 0 are valid */ -(INT_MIN + 1) == INT_MAX && -(LONG_MIN + 1) == LONG_MAX && /* Check that unsigned-to-signed conversions preserve bit patterns */ (int)((unsigned int)INT_MAX + 1) == INT_MIN && (long)((unsigned long)LONG_MAX + 1) == LONG_MIN])], [krb5_cv_ints_twos_compl=yes], [krb5_cv_ints_twos_compl=no])]) if test "$krb5_cv_ints_twos_compl" = "no"; then AC_MSG_ERROR([integers are not two's complement]) fi AC_CACHE_CHECK([whether CHAR_BIT is 8], [krb5_cv_char_bit_8], [AC_PREPROC_IFELSE([AC_LANG_SOURCE( [[#include #if CHAR_BIT != 8 #error CHAR_BIT != 8 #endif ]])], [krb5_cv_char_bit_8=yes], [krb5_cv_char_bit_8=no])]) if test "$krb5_cv_char_bit_8" = "no"; then AC_MSG_ERROR([CHAR_BIT is not 8]) fi AC_CACHE_CHECK(if va_copy is available, krb5_cv_va_copy, [AC_LINK_IFELSE([AC_LANG_SOURCE([ #include void f(va_list ap) { va_list ap2; va_copy(ap2, ap); va_end(ap2); } va_list x; int main() { f(x); return 0; }])], krb5_cv_va_copy=yes, krb5_cv_va_copy=no)]) if test "$krb5_cv_va_copy" = yes; then AC_DEFINE(HAS_VA_COPY,1,[Define if va_copy macro or function is available.]) fi # Note that this isn't checking if the copied value *works*, just # whether the C language constraints permit the copying. If # va_list is defined as an array type, it can't be assigned. AC_CACHE_CHECK(if va_list objects can be copied by assignment, krb5_cv_va_simple_copy, [AC_COMPILE_IFELSE([ AC_LANG_SOURCE([#include void f(va_list va2) { va_list va1; va1 = va2; }])], krb5_cv_va_simple_copy=yes, krb5_cv_va_simple_copy=no)]) if test "$krb5_cv_va_simple_copy" = yes; then AC_DEFINE(CAN_COPY_VA_LIST,1,[Define if va_list objects can be simply copied by assignment.]) fi # The following lines are so that configure --help gives some global # configuration options. KRB5_LIB_AUX AC_ARG_ENABLE([athena], [ --enable-athena build with MIT Project Athena configuration],,) # Begin autoconf tests for the Makefiles generated out of the top-level # configure.in... KRB5_BUILD_LIBOBJS KRB5_BUILD_LIBRARY KRB5_BUILD_PROGRAM # for kprop AC_TYPE_MODE_T AC_PROG_INSTALL KRB5_AC_NEED_DAEMON KRB5_GETSOCKNAME_ARGS KRB5_GETPEERNAME_ARGS LIBUTIL= AC_CHECK_LIB(util,main,[AC_DEFINE(HAVE_LIBUTIL,1,[Define if the util library is available]) LIBUTIL=-lutil ]) AC_SUBST(LIBUTIL) # Determine if NLS is desired and supported. po= AC_ARG_ENABLE([nls], [AS_HELP_STRING([--disable-nls], [disable native language support])], [], [enable_nls=check]) if test "$enable_nls" != no; then AC_CHECK_HEADER(libintl.h, [ AC_SEARCH_LIBS(dgettext, intl, [ AC_DEFINE(ENABLE_NLS, 1, [Define if translation functions should be used.]) nls_enabled=yes])]) AC_CHECK_PROG(MSGFMT,msgfmt,msgfmt) if test x"$MSGFMT" != x; then K5_GEN_MAKEFILE(po) po=po fi # Error out if --enable-nls was explicitly requested but can't be enabled. if test "$enable_nls" = yes; then if test "$nls_enabled" != yes -o "x$po" = x; then AC_MSG_ERROR([NLS support requested but cannot be built]) fi fi fi AC_SUBST(po) # for kdc AC_CHECK_HEADERS(sys/sockio.h ifaddrs.h unistd.h fnmatch.h) AC_CHECK_FUNCS(vsprintf vasprintf vsnprintf strlcpy fnmatch secure_getenv) EXTRA_SUPPORT_SYMS= AC_CHECK_FUNC(strlcpy, [STRLCPY_ST_OBJ= STRLCPY_OBJ=], [STRLCPY_ST_OBJ=strlcpy.o STRLCPY_OBJ='$(OUTPRE)strlcpy.$(OBJEXT)' EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_strlcpy krb5int_strlcat"]) AC_SUBST(STRLCPY_OBJ) AC_SUBST(STRLCPY_ST_OBJ) AC_CHECK_FUNC(getopt, [GETOPT_ST_OBJ= GETOPT_OBJ= AC_DEFINE(HAVE_GETOPT, 1, [Define if system getopt should be used.])], [GETOPT_ST_OBJ='getopt.o' GETOPT_OBJ='$(OUTPRE)getopt.$(OBJEXT)' EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS k5_optind k5_optarg k5_opterr k5_optopt k5_getopt"]) AC_SUBST(GETOPT_OBJ) AC_SUBST(GETOPT_ST_OBJ) AC_CHECK_FUNC(getopt_long, [GETOPT_LONG_ST_OBJ= GETOPT_LONG_OBJ= AC_DEFINE(HAVE_GETOPT_LONG, 1, [Define if system getopt_long should be used.])], [GETOPT_LONG_ST_OBJ='getopt_long.o' GETOPT_LONG_OBJ='$(OUTPRE)getopt_long.$(OBJEXT)' EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS k5_getopt_long"]) AC_SUBST(GETOPT_LONG_OBJ) AC_SUBST(GETOPT_LONG_ST_OBJ) AC_CHECK_FUNC(fnmatch, [FNMATCH_ST_OBJ= FNMATCH_OBJ=], [FNMATCH_ST_OBJ=fnmatch.o FNMATCH_OBJ='$(OUTPRE)fnmatch.$(OBJEXT)' EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS k5_fnmatch"]) AC_SUBST(FNMATCH_OBJ) AC_SUBST(FNMATCH_ST_OBJ) AC_CHECK_FUNC(vasprintf, [PRINTF_ST_OBJ= PRINTF_OBJ=], [PRINTF_ST_OBJ=printf.o PRINTF_OBJ='$(OUTPRE)printf.$(OBJEXT)' EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_asprintf krb5int_vasprintf"]) AC_SUBST(PRINTF_OBJ) AC_SUBST(PRINTF_ST_OBJ) KRB5_NEED_PROTO([#include #include ],vasprintf) KRB5_NEED_PROTO([#include #ifdef HAVE_UNISTD_H #include #endif /* Solaris 8 declares swab in stdlib.h. */ #include ],swab,1) AC_CHECK_FUNC(secure_getenv, [SECURE_GETENV_ST_OBJ= SECURE_GETENV_OBJ= SECURE_GETENV_INIT=], [SECURE_GETENV_ST_OBJ=secure_getenv.o SECURE_GETENV_OBJ='$(OUTPRE)secure_getenv.$(OBJEXT)' SECURE_GETENV_INIT=k5_secure_getenv_init EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS k5_secure_getenv"]) AC_SUBST(SECURE_GETENV_OBJ) AC_SUBST(SECURE_GETENV_ST_OBJ) AC_SUBST(SECURE_GETENV_INIT) AC_PROG_AWK KRB5_AC_INET6 KRB5_SOCKADDR_SA_LEN CHECK_SIGNALS # --with-vague-errors disables useful error messages. AC_ARG_WITH([vague-errors], [AS_HELP_STRING([--with-vague-errors], [Do not @<:@do@:>@ send helpful errors to client])], [], [withval=no]) if test "$withval" = yes; then AC_MSG_NOTICE(Supplying vague error messages to KDC clients) AC_DEFINE(KRBCONF_VAGUE_ERRORS,1,[Define if the KDC should return only vague error codes to clients]) fi # Check which (if any) audit plugin to build audit_plugin="" AC_ARG_ENABLE([audit-plugin], [AS_HELP_STRING([--enable-audit-plugin=IMPL], [use audit plugin @<:@ do not use audit @:>@])], [], enableval=no) if test "$enableval" != no; then case "$enableval" in simple) # if audit_log_user_message is found, we assume # that audit_open and audit_close are also defined. AC_CHECK_LIB(audit, audit_log_user_message, [AUDIT_IMPL_LIBS=-laudit K5_GEN_MAKEFILE(plugins/audit/simple) audit_plugin=plugins/audit/simple ], AC_MSG_ERROR([libaudit not found or undefined symbol audit_log_user_message])) ;; *) AC_MSG_ERROR([Unknown audit plugin implementation $enableval.]) ;; esac fi AC_SUBST(AUDIT_IMPL_LIBS) AC_SUBST(audit_plugin) # WITH_CRYPTO_IMPL CRYPTO_IMPL=builtin AC_ARG_WITH([crypto-impl], [AS_HELP_STRING([--with-crypto-impl=IMPL], [use specified crypto implementation @<:@builtin@:>@])], [CRYPTO_IMPL=$withval AC_MSG_NOTICE(k5crypto will use '$withval')]) CRYPTO_BUILTIN_TESTS=no case $CRYPTO_IMPL in builtin) CRYPTO_BUILTIN_TESTS=yes ;; openssl) AC_CHECK_LIB(crypto, PKCS7_get_signer_info) AC_DEFINE([CRYPTO_OPENSSL], 1, [Define to use OpenSSL crypto library]) ;; *) AC_MSG_ERROR([Unknown crypto implementation $withval]) ;; esac AC_SUBST([CRYPTO_IMPL_CFLAGS]) AC_SUBST([CRYPTO_IMPL_LIBS]) AC_SUBST([CRYPTO_BUILTIN_TESTS]) # WITH_TLS_IMPL AC_ARG_WITH([tls-impl], [AS_HELP_STRING([--with-tls-impl=IMPL], [use specified TLS implementation @<:@auto@:>@])], [TLS_IMPL=$withval], [TLS_IMPL=auto]) case "$TLS_IMPL" in openssl|auto) AC_CHECK_LIB(ssl,SSL_CTX_new,[have_lib_ssl=true],[have_lib_ssl=false], -lcrypto) AC_MSG_CHECKING([for OpenSSL]) if test x$have_lib_ssl = xtrue ; then AC_DEFINE(TLS_IMPL_OPENSSL,1,[Define if TLS implementation is OpenSSL]) AC_MSG_RESULT([yes]) TLS_IMPL_LIBS="-lssl -lcrypto" TLS_IMPL=openssl AC_MSG_NOTICE([TLS module will use OpenSSL]) else if test "$TLS_IMPL" = openssl ; then AC_MSG_ERROR([OpenSSL not found!]) else AC_MSG_WARN([OpenSSL not found!]) fi TLS_IMPL=no AC_MSG_NOTICE(building without TLS support) fi ;; no) AC_MSG_NOTICE(building without TLS support) ;; *) AC_MSG_ERROR([Unsupported TLS implementation $withval]) ;; esac if test "$TLS_IMPL" = no; then AC_DEFINE(TLS_IMPL_NONE,1,[Define if no TLS implementation is selected]) fi AC_SUBST(TLS_IMPL) AC_SUBST(TLS_IMPL_CFLAGS) AC_SUBST(TLS_IMPL_LIBS) AC_ARG_WITH([keyutils], [AS_HELP_STRING([--without-keyutils], [do not link with libkeyutils])], [], [with_keyutils=check]) if test "$with_keyutils" != no; then have_keyutils=false AC_CHECK_HEADERS([keyutils.h], AC_CHECK_LIB(keyutils, add_key, [have_keyutils=true])) if test "$have_keyutils" = true; then AC_DEFINE(USE_KEYRING_CCACHE, 1, [Define if the keyring ccache should be enabled]) LIBS="-lkeyutils $LIBS" # If libkeyutils supports persistent keyrings, use them. AC_CHECK_LIB(keyutils, keyctl_get_persistent, [AC_DEFINE(HAVE_PERSISTENT_KEYRING, 1, [Define if persistent keyrings are supported]) ]) elif test "$with_keyutils" = yes; then AC_MSG_ERROR([libkeyutils not found]) fi fi # The SPAKE preauth plugin currently supports edwards25519 natively, # and can support three NIST groups using OpenSSL. HAVE_SPAKE_OPENSSL=no AC_ARG_WITH([spake-openssl], [AS_HELP_STRING([--with-spake-openssl], [use OpenSSL for SPAKE preauth @<:@auto@:>@])], [], [withval=auto]) if test "$withval" = auto -o "$withval" = yes; then AC_CHECK_LIB([crypto],[EC_POINT_new],[have_crypto=true],[have_crypto=false]) if test "$have_crypto" = true; then AC_DEFINE(SPAKE_OPENSSL,1,[Define to use OpenSSL for SPAKE preauth]) SPAKE_OPENSSL_LIBS=-lcrypto HAVE_SPAKE_OPENSSL=yes elif test "$withval" = yes; then AC_MSG_ERROR([OpenSSL libcrypto not found]) fi fi AC_SUBST(HAVE_SPAKE_OPENSSL) AC_SUBST(SPAKE_OPENSSL_LIBS) AC_ARG_ENABLE([aesni], [AS_HELP_STRING([--disable-aesni], [Do not build with AES-NI support])], [], [enable_aesni=check]) if test "$CRYPTO_IMPL" = builtin -a "x$enable_aesni" != xno; then case "$host" in i686-*) aesni_obj=iaesx86.o aesni_machine=x86 ;; x86_64-*) aesni_obj=iaesx64.o aesni_machine=amd64 ;; esac case "$host" in *-*-linux* | *-*-gnu* | *-*-*bsd* | *-*-solaris*) # All Unix-like platforms need -D__linux__ for iaesx64.s to # use the System V x86-64 calling convention. aesni_flags="-D__linux__ -f elf -m $aesni_machine" ;; esac if test "x$aesni_obj" != x && test "x$aesni_flags" != x; then AC_CHECK_PROG(YASM,yasm,yasm) AC_CHECK_HEADERS(cpuid.h) if test x"$YASM" != x -a "x$ac_cv_header_cpuid_h" = xyes; then AESNI_OBJ=$aesni_obj AESNI_FLAGS=$aesni_flags AC_DEFINE(AESNI,1,[Define if AES-NI support is enabled]) AC_MSG_NOTICE([Building with AES-NI support]) fi fi if test "x$enable_aesni" = xyes -a "x$AESNI_OBJ" = x; then AC_MSG_ERROR([AES-NI support requested but cannot be built]) fi fi AC_SUBST(AESNI_OBJ) AC_SUBST(AESNI_FLAGS) AC_ARG_ENABLE([kdc-lookaside-cache], AS_HELP_STRING([--disable-kdc-lookaside-cache], [Disable the cache which detects client retransmits]), [], [enableval=yes]) if test "$enableval" = no ; then AC_DEFINE(NOCACHE,1,[Define if the KDC should use no lookaside cache]) fi KRB5_RUN_FLAGS # asan is a gcc and clang facility to instrument the code with memory # error checking. To use it, we compile C and C++ source files with # -fsanitize=address, and set ASAN=yes to suppress the undefined # symbols check when building shared libraries. AC_ARG_ENABLE([asan], [AS_HELP_STRING([--enable-asan], [Build with asan memory checking])], [], [enable_asan=no]) if test "$enable_asan" != no; then if test "$enable_asan" = yes; then enable_asan=address fi ASAN_FLAGS="$DEFS -fsanitize=$enable_asan" ASAN=yes UNDEF_CHECK= else ASAN_FLAGS= ASAN=no fi AC_SUBST(ASAN_FLAGS) AC_SUBST(ASAN) # Build using OSS-Fuzz build processes for compiling fuzzing targets. # LIB_FUZZING_ENGINE is used for supporting various types of fuzzers. fuzz_dir="" FUZZ_LDFLAGS= AC_ARG_ENABLE([ossfuzz], [AS_HELP_STRING([--enable-ossfuzz], [Build with fuzzing targets])], [], [enable_ossfuzz=no]) if test "$enable_ossfuzz" != no; then # Check if LIB_FUZZING_ENGINE environment is not empty. if test -z "$LIB_FUZZING_ENGINE"; then AC_MSG_ERROR([LIB_FUZZING_ENGINE environment variable is not set]) fi fuzz_dir="fuzzing" FUZZ_LDFLAGS="$LIB_FUZZING_ENGINE" K5_GEN_MAKEFILE(tests/fuzzing) fi AC_SUBST(fuzz_dir) AC_SUBST(FUZZ_LDFLAGS) # from old include/configure.in AH_TEMPLATE([HAVE_STRUCT_SOCKADDR_STORAGE], [Define if "struct sockaddr_storage" is available.]) AC_CONFIG_HEADERS(include/autoconf.h, [echo timestamp > include/autoconf.stamp]) AC_C_CONST AC_HEADER_DIRENT AC_FUNC_STRERROR_R AC_CHECK_FUNCS(strdup setvbuf seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strptime geteuid setenv unsetenv getenv gmtime_r localtime_r bswap16 bswap64 mkstemp getusershell access getcwd srand48 srand srandom stat strchr strerror timegm explicit_bzero explicit_memset getresuid getresgid getentropy) AC_CHECK_FUNC(mkstemp, [MKSTEMP_ST_OBJ= MKSTEMP_OBJ=], [MKSTEMP_ST_OBJ='mkstemp.o' MKSTEMP_OBJ='$(OUTPRE)mkstemp.$(OBJEXT)' EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_mkstemp"]) AC_SUBST(MKSTEMP_OBJ) AC_SUBST(MKSTEMP_ST_OBJ) AC_CHECK_FUNC(gettimeofday, [GETTIMEOFDAY_ST_OBJ= GETTIMEOFDAY_OBJ= AC_DEFINE(HAVE_GETTIMEOFDAY, 1, [Have the gettimeofday function]) ], [GETTIMEOFDAY_ST_OBJ='gettimeofday.o' GETTIMEOFDAY_OBJ='$(OUTPRE)gettimeofday.$(OBJEXT)' EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_gettimeofday"]) AC_SUBST(GETTIMEOFDAY_OBJ) AC_SUBST(GETTIMEOFDAY_ST_OBJ) AC_SUBST(EXTRA_SUPPORT_SYMS) DECLARE_SYS_ERRLIST AC_CHECK_HEADERS(unistd.h paths.h fcntl.h memory.h ifaddrs.h sys/filio.h byteswap.h machine/endian.h machine/byte_order.h sys/bswap.h endian.h pwd.h arpa/inet.h alloca.h dlfcn.h limits.h sys/random.h) AC_CHECK_MEMBERS([struct stat.st_mtimensec,struct stat.st_mtimespec.tv_nsec,struct stat.st_mtim.tv_nsec],,,[#include #include ]) AC_TYPE_OFF_T # Fancy caching of perror result... AC_MSG_CHECKING(for perror declaration) AC_CACHE_VAL(krb5_cv_decl_perror, [AC_EGREP_HEADER(perror, errno.h, krb5_cv_decl_perror=yes, krb5_cv_decl_perror=no)]) AC_MSG_RESULT($krb5_cv_decl_perror) if test $krb5_cv_decl_perror = yes; then AC_DEFINE(HDR_HAS_PERROR,1,[Define if errno.h declares perror]) fi KRB5_NEED_PROTO([#include ],strptime) CHECK_WAIT_TYPE CHECK_SIGPROCMASK AC_TYPE_GETGROUPS CHECK_SETJMP # *rpcent return types needed for lib/rpc AC_MSG_CHECKING([return type of setrpcent]) AC_CACHE_VAL(k5_cv_type_setrpcent, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE([[#include extern void setrpcent();]])], [k5_cv_type_setrpcent=void], [k5_cv_type_setrpcent=int])]) AC_MSG_RESULT($k5_cv_type_setrpcent) AC_DEFINE_UNQUOTED(SETRPCENT_TYPE, $k5_cv_type_setrpcent, [Define as return type of setrpcent]) AC_MSG_CHECKING([return type of endrpcent]) AC_CACHE_VAL(k5_cv_type_endrpcent, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern void endrpcent();]])], [k5_cv_type_endrpcent=void], [k5_cv_type_endrpcent=int])]) AC_MSG_RESULT($k5_cv_type_endrpcent) AC_DEFINE_UNQUOTED(ENDRPCENT_TYPE, $k5_cv_type_endrpcent, [Define as return type of endrpcent]) # bswap_16 is a macro in byteswap.h under GNU libc AC_MSG_CHECKING(for bswap_16) AC_CACHE_VAL(krb5_cv_bswap_16, [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#if HAVE_BYTESWAP_H #include #endif ]], [[bswap_16(37);]])], [krb5_cv_bswap_16=yes], [krb5_cv_bswap_16=no])]) AC_MSG_RESULT($krb5_cv_bswap_16) if test "$krb5_cv_bswap_16" = yes; then AC_DEFINE(HAVE_BSWAP_16,1,[Define to 1 if bswap_16 is available via byteswap.h]) fi AC_MSG_CHECKING(for bswap_64) AC_CACHE_VAL(krb5_cv_bswap_64, [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#if HAVE_BYTESWAP_H #include #endif ]], [[bswap_64(37);]])], [krb5_cv_bswap_64=yes], [krb5_cv_bswap_64=no])]) AC_MSG_RESULT($krb5_cv_bswap_64) if test "$krb5_cv_bswap_64" = yes; then AC_DEFINE(HAVE_BSWAP_64,1,[Define to 1 if bswap_64 is available via byteswap.h]) fi # Needed for ksu and some appl stuff. case $krb5_cv_host in alpha*-dec-osf*) AC_CHECK_LIB(security,setluid, AC_DEFINE(HAVE_SETLUID,1,[Define if setluid provided in OSF/1 security library]) KSU_LIBS="-lsecurity" ) ;; esac AC_SUBST(KSU_LIBS) if test $ac_cv_func_setenv = no || test $ac_cv_func_unsetenv = no \ || test $ac_cv_func_getenv = no; then SETENVOBJ=setenv.o else SETENVOBJ= fi AC_SUBST(SETENVOBJ) # Check what the return types for gethostbyname_r and getservbyname_r are. AC_CHECK_FUNC(gethostbyname_r,[ ac_cv_func_gethostbyname_r=yes if test "$ac_cv_func_gethostbyname_r" = yes; then AC_MSG_CHECKING([if gethostbyname_r returns an int]) AC_CACHE_VAL(krb5_cv_gethostbyname_r_returns_int, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern int gethostbyname_r();]])], [krb5_cv_gethostbyname_r_returns_int=yes], [krb5_cv_gethostbyname_r_returns_int=no])]) AC_MSG_RESULT($krb5_cv_gethostbyname_r_returns_int) AC_MSG_CHECKING([if gethostbyname_r returns a pointer]) AC_CACHE_VAL(krb5_cv_gethostbyname_r_returns_ptr, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern struct hostent *gethostbyname_r();]])], [krb5_cv_gethostbyname_r_returns_ptr=yes], [krb5_cv_gethostbyname_r_returns_ptr=no])]) AC_MSG_RESULT($krb5_cv_gethostbyname_r_returns_ptr) if test "$krb5_cv_gethostbyname_r_returns_int" = "$krb5_cv_gethostbyname_r_returns_ptr"; then AC_MSG_WARN(cannot determine return type of gethostbyname_r -- disabling) ac_cv_func_gethostbyname_r=no fi if test "$krb5_cv_gethostbyname_r_returns_int" = yes; then AC_DEFINE(GETHOSTBYNAME_R_RETURNS_INT, 1, [Define if gethostbyname_r returns int rather than struct hostent * ]) fi fi if test "$ac_cv_func_gethostbyname_r" = yes; then AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1, [Define if gethostbyname_r exists and its return type is known]) AC_CHECK_FUNC(gethostbyaddr_r) fi ]) # PTHREAD_CFLAGS changes which variant of these functions is declared # on Solaris 11, so use it for these tests. old_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $PTHREAD_CFLAGS" AC_CHECK_FUNC(getpwnam_r,ac_cv_func_getpwnam_r=yes,ac_cv_func_getpwnam_r=no) AC_CHECK_FUNC(getpwuid_r,ac_cv_func_getpwuid_r=yes,ac_cv_func_getpwuid_r=no) if test "$ac_cv_func_getpwnam_r" = yes; then AC_MSG_CHECKING([return type of getpwnam_r]) AC_CACHE_VAL(krb5_cv_getpwnam_r_return_type, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern int getpwnam_r();]])], [getpwnam_r_returns_int=yes], [getpwnam_r_returns_int=no]) AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern struct passwd *getpwnam_r();]])], [getpwnam_r_returns_ptr=yes], [getpwnam_r_returns_ptr=no]) case "$getpwnam_r_returns_int/$getpwnam_r_returns_ptr" in yes/no) krb5_cv_getpwnam_r_return_type=int ;; no/yes) krb5_cv_getpwnam_r_return_type=ptr ;; *) krb5_cv_getpwnam_r_return_type=unknown ;; esac]) AC_MSG_RESULT($krb5_cv_getpwnam_r_return_type) if test $krb5_cv_getpwnam_r_return_type = int; then AC_DEFINE(GETPWNAM_R_RETURNS_INT, 1, [Define if getpwnam_r returns an int]) elif test $krb5_cv_getpwnam_r_return_type = unknown; then AC_MSG_WARN([Cannot determine getpwnam_r return type, disabling getpwnam_r]) ac_cv_func_getpwnam_r=no fi fi if test "$ac_cv_func_getpwnam_r" = yes; then AC_MSG_CHECKING([number of arguments to getpwnam_r]) AC_CACHE_VAL(krb5_cv_getpwnam_r_args, [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include struct passwd pwx; char buf[1024];]], [[getpwnam_r("", &pwx, buf, sizeof(buf));]])], [args4=yes], [args4=no]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include struct passwd pwx, *p; char buf[1024];]], [[getpwnam_r("", &pwx, buf, sizeof(buf), &p);]])], [args5=yes], [args5=no]) case $args4/$args5 in yes/no) krb5_cv_getpwnam_r_args=4 ;; no/yes) krb5_cv_getpwnam_r_args=5 ;; *) krb5_cv_getpwnam_r_args=unknown ;; esac]) AC_MSG_RESULT($krb5_cv_getpwnam_r_args) if test "$krb5_cv_getpwnam_r_args" = unknown; then AC_MSG_WARN([Cannot determine number of arguments to getpwnam_r, disabling its use.]) ac_cv_func_getpwnam_r=no else AC_DEFINE(HAVE_GETPWNAM_R,1,[Define if getpwnam_r is available and useful.]) if test "$krb5_cv_getpwnam_r_args" = 4; then AC_DEFINE(GETPWNAM_R_4_ARGS,1,[Define if getpwnam_r exists but takes only 4 arguments (e.g., POSIX draft 6 implementations like some Solaris releases).]) fi fi fi CFLAGS=$old_CFLAGS if test "$ac_cv_func_getpwnam_r" = no && test "$ac_cv_func_getpwuid_r" = yes; then # Actually, we could do this check, and the corresponding checks # for return type and number of arguments, but I doubt we'll run # into a system where we'd get to use getpwuid_r but not getpwnam_r. AC_MSG_NOTICE([getpwnam_r not useful, so disabling getpwuid_r too]) ac_cv_func_getpwuid_r=no fi if test "$ac_cv_func_getpwuid_r" = yes; then AC_DEFINE(HAVE_GETPWUID_R,1,[Define if getpwuid_r is available and useful.]) # Hack: Assume getpwuid_r is the shorter form if getpwnam_r is. if test "$krb5_cv_getpwnam_r_args" = 4; then AC_DEFINE(GETPWUID_R_4_ARGS,1,[Define if getpwuid_r exists but takes only 4 arguments (e.g., POSIX draft 6 implementations like some Solaris releases).]) fi fi if test "$ac_cv_func_gmtime_r" = yes; then AC_MSG_CHECKING([whether gmtime_r returns int]) AC_CACHE_VAL(krb5_cv_gmtime_r_returns_int, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern int gmtime_r();]])], [return_int=yes], [return_int=no]) AC_COMPILE_IFELSE([ AC_LANG_SOURCE( [[#include extern struct tm *gmtime_r();]])], [return_ptr=yes], [return_ptr=no]) case $return_int/$return_ptr in yes/no) krb5_cv_gmtime_r_returns_int=yes ;; no/yes) krb5_cv_gmtime_r_returns_int=no ;; *) # Can't figure it out, punt the function. ac_cv_func_gmtime_r=no ;; esac]) if test "$ac_cv_func_gmtime_r" = no; then AC_MSG_RESULT(unknown -- ignoring gmtime_r) else AC_MSG_RESULT($krb5_cv_gmtime_r_returns_int) if test "$krb5_cv_gmtime_r_returns_int" = yes; then AC_DEFINE(GMTIME_R_RETURNS_INT,1,[Define if gmtime_r returns int instead of struct tm pointer, as on old HP-UX systems.]) fi fi fi AC_CHECK_FUNC(getservbyname_r,[ ac_cv_func_getservbyname_r=yes if test "$ac_cv_func_getservbyname_r" = yes; then AC_MSG_CHECKING([if getservbyname_r returns an int]) AC_CACHE_VAL(krb5_cv_getservbyname_r_returns_int, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern int getservbyname_r();]])], [krb5_cv_getservbyname_r_returns_int=yes], [krb5_cv_getservbyname_r_returns_int=no])]) AC_MSG_RESULT($krb5_cv_getservbyname_r_returns_int) AC_MSG_CHECKING([if getservbyname_r returns a pointer]) AC_CACHE_VAL(krb5_cv_getservbyname_r_returns_ptr, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern struct servent *getservbyname_r();]])], [krb5_cv_getservbyname_r_returns_ptr=yes], [krb5_cv_getservbyname_r_returns_ptr=no])]) AC_MSG_RESULT($krb5_cv_getservbyname_r_returns_ptr) if test "$krb5_cv_getservbyname_r_returns_int" = "$krb5_cv_getservbyname_r_returns_ptr"; then AC_MSG_WARN(cannot determine return type of getservbyname_r -- disabling) ac_cv_func_getservbyname_r=no fi if test "$krb5_cv_getservbyname_r_returns_int" = yes; then AC_DEFINE(GETSERVBYNAME_R_RETURNS_INT, 1, [Define if getservbyname_r returns int rather than struct servent * ]) fi fi if test "$ac_cv_func_getservbyname_r" = yes; then AC_DEFINE(HAVE_GETSERVBYNAME_R, 1, [Define if getservbyname_r exists and its return type is known]) AC_CHECK_FUNC(getservbyport_r) fi ]) CHECK_DIRENT AC_TYPE_UID_T AC_CHECK_HEADER(termios.h, [AC_CHECK_FUNC([tcsetattr], AC_DEFINE(POSIX_TERMIOS,1,[Define if termios.h exists and tcsetattr exists]))]) AC_CHECK_HEADERS(poll.h stdlib.h string.h stddef.h sys/types.h sys/file.h sys/param.h sys/stat.h sys/time.h netinet/in.h sys/uio.h sys/filio.h sys/select.h time.h paths.h errno.h) # If compiling with IPv6 support, test if in6addr_any functions. # Irix 6.5.16 defines it, but lacks support in the C library. if test $krb5_cv_inet6 = yes || test "$krb5_cv_inet6_with_dinet6" = yes ; then AC_CACHE_CHECK([for in6addr_any definition in library], [krb5_cv_var_in6addr_any], [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#ifdef HAVE_SYS_TYPES_H #include #endif #include #include #include #include ]], [[struct sockaddr_in6 in; in.sin6_addr = in6addr_any; printf("%x", &in);]])], [krb5_cv_var_in6addr_any=yes], [krb5_cv_var_in6addr_any=no])]) if test $krb5_cv_var_in6addr_any = no; then AC_DEFINE(NEED_INSIXADDR_ANY,1,[Define if in6addr_any is not defined in libc]) fi fi # then from osconf.h, we have AC_CHECK_TYPE(time_t, long) AC_CHECK_SIZEOF(time_t) SIZEOF_TIME_T=$ac_cv_sizeof_time_t AC_SUBST(SIZEOF_TIME_T) # Determine where to put the replay cache. AC_MSG_CHECKING([for replay cache directory]) AC_CACHE_VAL(krb5_cv_sys_rcdir, [ if test $cross_compiling = yes; then krb5_cv_sys_rcdir=/var/tmp else for t_dir in /var/tmp /usr/tmp /var/usr/tmp /tmp ; do test -d $t_dir || continue krb5_cv_sys_rcdir=$t_dir break done fi]) AC_MSG_RESULT($krb5_cv_sys_rcdir) KRB5_RCTMPDIR=$krb5_cv_sys_rcdir AC_SUBST(KRB5_RCTMPDIR) AC_MSG_CHECKING(for socklen_t) AC_CACHE_VAL(krb5_cv_has_type_socklen_t, [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include #include ]], [[sizeof(socklen_t);]])], [krb5_cv_has_type_socklen_t=yes], [krb5_cv_has_type_socklen_t=no])]) AC_MSG_RESULT($krb5_cv_has_type_socklen_t) if test $krb5_cv_has_type_socklen_t = yes; then AC_DEFINE(HAVE_SOCKLEN_T,1,[Define if there is a socklen_t type. If not, probably use size_t]) fi AC_MSG_CHECKING(for struct lifconf) AC_CACHE_VAL(krb5_cv_has_struct_lifconf, [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include #include ]], [[sizeof (struct lifconf);]])], [krb5_cv_has_struct_lifconf=yes], [krb5_cv_has_struct_lifconf=no])]) AC_MSG_RESULT($krb5_cv_has_struct_lifconf) if test $krb5_cv_has_struct_lifconf = yes; then AC_DEFINE(HAVE_STRUCT_LIFCONF,1,[Define if there is a struct lifconf.]) fi # HP-UX 11 uses stuct if_laddrconf AC_MSG_CHECKING(for struct if_laddrconf) AC_CACHE_VAL(krb5_cv_has_struct_if_laddrconf, [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include #include #include ]], [[sizeof(struct if_laddrconf);]])], [krb5_cv_has_struct_if_laddrconf=yes], [krb5_cv_has_struct_if_laddrconf=no])]) AC_MSG_RESULT($krb5_cv_has_struct_if_laddrconf) if test $krb5_cv_has_struct_if_laddrconf = yes; then AC_DEFINE(HAVE_STRUCT_IF_LADDRCONF,1,[Define if there is a struct if_laddrconf.]) fi AC_MSG_CHECKING([for h_errno in netdb.h]) AC_CACHE_VAL(krb5_cv_header_netdb_h_h_errno, [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[int x = h_errno;]])], [krb5_cv_header_netdb_h_h_errno=yes], [krb5_cv_header_netdb_h_h_errno=no])]) AC_MSG_RESULT($krb5_cv_header_netdb_h_h_errno) if test $krb5_cv_header_netdb_h_h_errno = yes; then AC_DEFINE([HAVE_NETDB_H_H_ERRNO], 1, [Define if netdb.h declares h_errno]) fi AC_ARG_ENABLE([athena], [ --enable-athena build with MIT Project Athena configuration], AC_DEFINE(KRB5_ATHENA_COMPAT,1,[Define if MIT Project Athena default configuration should be used]),) AC_C_INLINE AH_TOP([ #ifndef KRB5_AUTOCONF_H #define KRB5_AUTOCONF_H ]) AH_BOTTOM([ #if defined(__GNUC__) && !defined(inline) /* Silence gcc pedantic warnings about ANSI C. */ # define inline __inline__ #endif #endif /* KRB5_AUTOCONF_H */ ]) AC_CHECK_TYPES([struct cmsghdr, struct in_pktinfo, struct in6_pktinfo, struct sockaddr_storage], , , [ #include #include #include ]) AC_CHECK_TYPES([struct rt_msghdr], , , [ #include #include #include ]) # Tests for 64-bit edwards25519 code. AC_CHECK_SIZEOF([size_t]) AC_CHECK_TYPES([__int128_t, __uint128_t]) # types libdb2 wants AC_CHECK_TYPES([ssize_t, u_char, u_int, u_long, u_int8_t, u_int16_t, u_int32_t, int8_t, int16_t, int32_t]) # Some libdb2 test programs want a shell that supports functions. FCTSH=false AC_PATH_PROG(SH,sh,false) AC_PATH_PROG(SH5,sh5,false) AC_PATH_PROG(BASH,bash,false) for prog in $SH $SH5 $BASH; do AC_MSG_CHECKING(if $prog supports functions) if $prog -c 'foo() { true; }; foo' >/dev/null 2>&1; then AC_MSG_RESULT(yes) FCTSH=$prog break else AC_MSG_RESULT(no) fi done AC_SUBST(FCTSH) # Test for POSIX 2001 *printf support (X/Open System Interfaces extension # to ANSI/ISO C 1999 specification). Specifically, positional # specifications; not checking for other features like %zx at present. AC_MSG_CHECKING(for POSIX printf positional specification support) AC_CACHE_VAL(ac_cv_printf_positional, [AC_RUN_IFELSE( [AC_LANG_SOURCE( [[#include #include const char expected[] = "200 100"; int main() { char buf[30]; sprintf(buf, "%2\$x %1\$d", 100, 512); if (strcmp(expected, buf)) { fprintf(stderr, "bad result: <%s> wanted: <%s>\n", buf, expected); return 1; } return 0; }]])], [ac_cv_printf_positional=yes], [ac_cv_printf_positional=no], [AC_MSG_ERROR(Cannot test for printf positional argument support when cross compiling)])]) # Nothing for autoconf.h for now. AC_MSG_RESULT($ac_cv_printf_positional) # for t_locate_kdc test AC_PATH_PROG(DIG, dig, false) AC_PATH_PROG(NSLOOKUP, nslookup, false) # for kadmin AC_PROG_YACC ath_compat= AC_ARG_ENABLE([athena], [ --enable-athena build with MIT Project Athena configuration], ath_compat=compat,) KRB5_AC_PRIOCNTL_HACK AC_CHECK_PROG(PERL,perl,perl) # lib/gssapi AC_CHECK_HEADER(xom.h,[ include_xom='awk '\''END{printf("%cinclude \n", 35);}'\'' < /dev/null'], [ include_xom='echo "/* no xom.h */"']) AC_SUBST(include_xom) # lib/rpc ### Check where struct rpcent is declared. # This is necessary to determine: # 1. If /usr/include/netdb.h declares struct rpcent # 2. If /usr/include/rpc/netdb.h declares struct rpcent # We have our own rpc/netdb.h, and if /usr/include/netdb.h includes # rpc/netdb.h, then nastiness could happen. # Logic: If /usr/include/netdb.h declares struct rpcent, then check # rpc/netdb.h. If /usr/include/rpc/netdb.h declares struct rpcent, # then define STRUCT_RPCENT_IN_RPC_NETDB_H, otherwise do not. If # neither netdb.h nor rpc/netdb.h declares struct rpcent, then define # STRUCT_RPCENT_IN_RPC_NETDB_H anyway. AC_MSG_CHECKING([where struct rpcent is declared]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[struct rpcent e; char c = e.r_name[0]; int i = e.r_number;]])], [netdb_rpcent=yes], [netdb_rpcent=no]) if test "$netdb_rpcent" = yes; then AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[struct rpcent e; char c = e.r_name[0]; int i = e.r_number;]])], [rpc_netdb_rpcent=yes], [rpc_netdb_rpcent=no]) if test "$rpc_netdb_rpcent" = yes; then AC_MSG_RESULT([rpc/netdb.h]) rpcent_define='#define STRUCT_RPCENT_IN_RPC_NETDB_H' else AC_MSG_RESULT([netdb.h]) fi else AC_MSG_RESULT([nowhere]) rpcent_define='#define STRUCT_RPCENT_IN_RPC_NETDB_H' fi AC_SUBST(rpcent_define) AC_CHECK_HEADERS(sys/select.h sys/time.h unistd.h) if test $ac_cv_header_sys_select_h = yes; then GSSRPC__SYS_SELECT_H='#include ' else GSSRPC__SYS_SELECT_H='/* #include */' fi AC_SUBST(GSSRPC__SYS_SELECT_H) if test $ac_cv_header_sys_time_h = yes; then GSSRPC__SYS_TIME_H='#include ' else GSSRPC__SYS_TIME_H='/* #include */' fi AC_SUBST(GSSRPC__SYS_TIME_H) if test $ac_cv_header_unistd_h = yes; then GSSRPC__UNISTD_H='#include ' else GSSRPC__UNISTD_H='/* #include */' fi AC_SUBST(GSSRPC__UNISTD_H) AC_CACHE_CHECK([for MAXHOSTNAMELEN in sys/param.h], [krb5_cv_header_sys_param_h_maxhostnamelen], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[int i = MAXHOSTNAMELEN;]])], [krb5_cv_header_sys_param_h_maxhostnamelen=yes], [krb5_cv_header_sys_param_h_maxhostnamelen=no])]) AC_CACHE_CHECK([for MAXHOSTNAMELEN in netdb.h], [krb5_cv_header_netdb_h_maxhostnamelen], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[int i = MAXHOSTNAMELEN;]])], [krb5_cv_header_netdb_h_maxhostnamelen=yes], [krb5_cv_header_netdb_h_maxhostnamelen=no])]) GSSRPC__SYS_PARAM_H='/* #include */' GSSRPC__NETDB_H='/* #include */' if test $krb5_cv_header_sys_param_h_maxhostnamelen = yes; then GSSRPC__SYS_PARAM_H='#include ' else if test $krb5_cv_header_netdb_h_maxhostnamelen = yes; then GSSRPC__NETDB_H='#include ' else AC_MSG_WARN([can't find MAXHOSTNAMELEN definition; faking it]) fi fi AC_SUBST(GSSRPC__SYS_PARAM_H) AC_SUBST(GSSRPC__NETDB_H) AC_CACHE_CHECK([for BSD type aliases], [krb5_cv_type_bsdaliases], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include #if HAVE_UNISTD_H #include #endif ]], [[u_char c; u_int i; u_long l;]])], [krb5_cv_type_bsdaliases=yes], [krb5_cv_type_bsdaliases=no])]) if test $krb5_cv_type_bsdaliases = yes; then GSSRPC__BSD_TYPEALIASES='/* #undef GSSRPC__BSD_TYPEALIASES */' else GSSRPC__BSD_TYPEALIASES='#define GSSRPC__BSD_TYPEALIASES 1' fi AC_SUBST(GSSRPC__BSD_TYPEALIASES) AC_MSG_CHECKING([return type of setrpcent]) AC_CACHE_VAL(k5_cv_type_setrpcent, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern void setrpcent();]])], [k5_cv_type_setrpcent=void], [k5_cv_type_setrpcent=int])]) AC_MSG_RESULT($k5_cv_type_setrpcent) AC_DEFINE_UNQUOTED(SETRPCENT_TYPE, $k5_cv_type_setrpcent, [Define as return type of setrpcent]) AC_MSG_CHECKING([return type of endrpcent]) AC_CACHE_VAL(k5_cv_type_endrpcent, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include extern void endrpcent();]])], [k5_cv_type_endrpcent=void], [k5_cv_type_endrpcent=int])]) AC_MSG_RESULT($k5_cv_type_endrpcent) AC_DEFINE_UNQUOTED(ENDRPCENT_TYPE, $k5_cv_type_endrpcent, [Define as return type of endrpcent]) K5_GEN_FILE(include/gssrpc/types.h:include/gssrpc/types.hin) # for pkinit AC_ARG_ENABLE([pkinit], [ --disable-pkinit disable PKINIT plugin support],, enable_pkinit=try) if test "$enable_pkinit" = yes || test "$enable_pkinit" = try; then AC_CACHE_CHECK(for a recent enough OpenSSL, k5_cv_openssl_version_okay, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([#include #if OPENSSL_VERSION_NUMBER < 0x10000000L # error openssl is too old, need 1.0.0 #endif int i = 1; ])], k5_cv_openssl_version_okay=yes, k5_cv_openssl_version_okay=no)]) old_LIBS="$LIBS" AC_CHECK_LIB(crypto, PKCS7_get_signer_info) AC_CHECK_FUNCS(EVP_PKEY_get_bn_param) LIBS="$old_LIBS" fi if test "$k5_cv_openssl_version_okay" = yes && (test "$enable_pkinit" = yes || test "$enable_pkinit" = try); then K5_GEN_MAKEFILE(plugins/preauth/pkinit) PKINIT=yes elif test "$k5_cv_openssl_version_okay" = no && test "$enable_pkinit" = yes; then AC_MSG_ERROR([Version of OpenSSL is too old; cannot enable PKINIT.]) else AC_DEFINE([DISABLE_PKINIT], 1, [Define to disable PKINIT plugin support]) AC_MSG_NOTICE([Disabling PKINIT support.]) PKINIT=no fi AC_SUBST(PKINIT) # for lib/apputils AC_REPLACE_FUNCS(daemon) # For Python tests. Python version 3.4 is required for # ssl.create_default_context(). PYTHON_MINVERSION=3.4 AC_SUBST(PYTHON_MINVERSION) AC_CHECK_PROG(PYTHON,python3,python3) if test x"$PYTHON" = x; then AC_CHECK_PROG(PYTHON,python,python) fi HAVE_PYTHON=no if test x"$PYTHON" != x; then wantver="(sys.hexversion >= 0x30400F0)" if "$PYTHON" -c "import sys; sys.exit(not $wantver and 1 or 0)"; then HAVE_PYTHON=yes fi fi AC_SUBST(HAVE_PYTHON) # For cmocka tests. CMOCKA_LIBS= HAVE_CMOCKA=no HAVE_CMOCKA_H=no HAVE_CMOCKA_LIB=no AC_CHECK_HEADER(cmocka.h, [HAVE_CMOCKA_H=yes], :, [ #include #include #include ]) AC_CHECK_LIB(cmocka, _cmocka_run_group_tests, [HAVE_CMOCKA_LIB=yes]) if test "$HAVE_CMOCKA_LIB" = yes && test "$HAVE_CMOCKA_H" = yes; then HAVE_CMOCKA=yes CMOCKA_LIBS='-lcmocka' AC_DEFINE([HAVE_CMOCKA],1,[Define if cmocka library is available.]) fi AC_SUBST(HAVE_CMOCKA) AC_SUBST(CMOCKA_LIBS) # For URI lookup tests. Requires resolv_wrapper >= 1.1.5 for URI # support. HAVE_RESOLV_WRAPPER=0 PKG_CHECK_EXISTS([resolv_wrapper >= 1.1.5], [HAVE_RESOLV_WRAPPER=1]) AC_SUBST(HAVE_RESOLV_WRAPPER) # for plugins/kdb/db2 # AIX is unusual in that it wants all symbols resolved at link time # Fortunately, it will allow us to link the kdb library now, even if # it is linked again later. case $krb5_cv_host in *-*-aix*) DB_EXTRA_LIBS=-ldb ;; *) DB_EXTRA_LIBS= ;; esac AC_SUBST(DB_EXTRA_LIBS) # Warn about possible thread safety issues. These functions have all # been checked for previously. tsfuncs="getpwnam_r getpwuid_r gethostbyname_r getservbyname_r gmtime_r localtime_r" if test "$enable_thread_support" = yes; then tsmissing="" for ts in $tsfuncs; do if eval "test \"\${ac_cv_func_$ts}\" != yes"; then tsmissing="$tsmissing $ts" fi done if test "$ac_cv_func_res_nsearch/$ac_cv_lib_resolv_res_nsearch" = "no/no"; then tsmissing="$tsmissing res_nsearch" fi if test "$tsmissing" != ""; then AC_MSG_WARN([Some functions that are needed for library thread]) AC_MSG_WARN([safety appear to be missing.]) for ts in $tsmissing; do AC_MSG_WARN([ missing thread-safe function: $ts]) done AC_MSG_WARN([Without these functions, the installed libraries]) AC_MSG_WARN([may not be thread-safe.]) fi # tsmissing not empty fi # enable_thread_support # Sadly, we seem to have accidentally committed ourselves in 1.4 to # an ABI that includes the existence of libkrb5support.0 even # though random apps should never use anything from it. And on # the Mac, to which that didn't apply, we can't use major version 0. case $krb5_cv_host in *-*-darwin* | *-*-rhapsody*) SUPPORTLIB_MAJOR=1 ;; *) SUPPORTLIB_MAJOR=0 ;; esac AC_SUBST(SUPPORTLIB_MAJOR) if test "$COM_ERR_VERSION" = k5 ; then K5_GEN_MAKEFILE(util/et) fi if test "$SS_VERSION" = k5 ; then K5_GEN_MAKEFILE(util/ss) fi ldap_plugin_dir="" ldap_lib="" if test -n "$OPENLDAP_PLUGIN"; then AC_CHECK_HEADERS(ldap.h lber.h, :, [AC_MSG_ERROR($ac_header not found)]) AC_CHECK_LIB(ldap, ldap_str2dn, :, [AC_MSG_ERROR(libldap not found or missing ldap_str2dn)]) BER_OKAY=0 AC_CHECK_LIB(ldap, ber_init, [BER_OKAY=1]) if test "$BER_OKAY" = "1"; then LDAP_LIBS='-lldap' else AC_CHECK_LIB(lber, ber_init, [BER_OKAY=1], [AC_MSG_WARN([libber not found])]) if test "$BER_OKAY" = "1"; then LDAP_LIBS='-lldap -llber' else AC_MSG_ERROR("BER library missing - cannot build LDAP database module") fi fi AC_DEFINE([ENABLE_LDAP], 1, [Define if LDAP KDB support within the Kerberos library (mainly ASN.1 code) should be enabled.]) AC_SUBST(LDAP_LIBS) AC_CHECK_HEADERS([sasl/sasl.h], [HAVE_SASL=yes], [HAVE_SASL=no]) AC_SUBST(HAVE_SASL) if test "$HAVE_SASL" = no; then AC_MSG_WARN([not building LDAP SASL support]) fi K5_GEN_MAKEFILE(plugins/kdb/ldap) K5_GEN_MAKEFILE(plugins/kdb/ldap/ldap_util) K5_GEN_MAKEFILE(plugins/kdb/ldap/libkdb_ldap) ldap_plugin_dir='plugins/kdb/ldap plugins/kdb/ldap/ldap_util' LDAP=yes else LDAP=no fi AC_SUBST(ldap_plugin_dir) AC_SUBST(LDAP) # This check is for plugins/preauth/securid_sam2 sam2_plugin="" old_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $PTHREAD_CFLAGS" AC_CHECK_LIB(aceclnt, SD_Init, [ AC_MSG_NOTICE([Enabling RSA securID support]) K5_GEN_MAKEFILE(plugins/preauth/securid_sam2) sam2_plugin=plugins/preauth/securid_sam2 ]) AC_SUBST(sam2_plugin) CFLAGS=$old_CFLAGS lmdb_plugin_dir="" HAVE_LMDB=no AC_ARG_WITH([lmdb], [AS_HELP_STRING([--with-lmdb], [compile LMDB database backend module @<:@auto@:>@])], [], [withval=auto]) if test "$withval" = auto -o "$withval" = yes; then AC_CHECK_LIB([lmdb],[mdb_env_create],[have_lmdb=true],[have_lmdb=false]) if test "$have_lmdb" = true; then LMDB_LIBS=-llmdb HAVE_LMDB=yes lmdb_plugin_dir='plugins/kdb/lmdb' K5_GEN_MAKEFILE(plugins/kdb/lmdb) elif test "$withval" = yes; then AC_MSG_ERROR([liblmdb not found]) fi fi AC_SUBST(HAVE_LMDB) AC_SUBST(LMDB_LIBS) AC_SUBST(lmdb_plugin_dir) # Kludge for simple server --- FIXME is this the best way to do this? if test "$ac_cv_lib_socket" = "yes" -a "$ac_cv_lib_nsl" = "yes"; then AC_DEFINE(BROKEN_STREAMS_SOCKETS,1,[Define if socket can't be bound to 0.0.0.0]) fi # Compile with libedit support in ss by default if available. Compile # with readline only if asked, to avoid a default GPL dependency. AC_ARG_WITH([libedit], [AS_HELP_STRING([--without-libedit], [do not compile with libedit])], [], [with_libedit=default]) AC_ARG_WITH([readline], [AS_HELP_STRING([--with-readline], [compile with GNU Readline])], [], [with_readline=no]) if test "x$with_readline" = xyes; then with_libedit=no fi RL_CFLAGS= RL_LIBS= if test "x$with_libedit" != xno; then PKG_CHECK_MODULES(LIBEDIT, libedit, [have_libedit=yes], [have_libedit=no]) if test "x$have_libedit" = xyes; then RL_CFLAGS=$LIBEDIT_CFLAGS RL_LIBS=$LIBEDIT_LIBS AC_DEFINE([HAVE_LIBEDIT], 1, [Define if building with libedit.]) AC_MSG_NOTICE([Using libedit for readline support]) elif test "x$with_libedit" = xyes; then # We were explicitly asked for libedit and couldn't find it. AC_MSG_ERROR([Could not detect libedit with pkg-config]) else AC_MSG_NOTICE([Not using any readline support]) fi elif test "x$with_readline" = xyes; then AC_MSG_NOTICE([Using GNU Readline]) AC_CHECK_LIB([readline], [main], :, AC_MSG_FAILURE([Cannot find readline library.])) AC_DEFINE([HAVE_READLINE], 1, [Define if building with GNU Readline.]) RL_LIBS='-lreadline' else AC_MSG_RESULT([Not using any readline support]) fi AC_SUBST([RL_CFLAGS]) AC_SUBST([RL_LIBS]) AC_ARG_WITH([system-verto], [AS_HELP_STRING([--with-system-verto], [always use system verto library])], [], [with_system_verto=default]) VERTO_VERSION=k5 if test "x$with_system_verto" != xno; then PKG_CHECK_MODULES(VERTO, libverto, [have_sysverto=yes], [have_sysverto=no]) if test "x$have_sysverto" = xyes; then VERTO_VERSION=sys elif test "x$with_system_verto" = xyes; then AC_MSG_ERROR([cannot detect system libverto]) fi fi if test "x$VERTO_VERSION" = xsys; then AC_MSG_NOTICE([Using system libverto]) else VERTO_CFLAGS= VERTO_LIBS="-lverto" AC_MSG_NOTICE([Using built-in libverto]) fi AC_SUBST([VERTO_CFLAGS]) AC_SUBST([VERTO_LIBS]) AC_SUBST([VERTO_VERSION]) AC_PATH_PROG(GROFF, groff) # Make localedir work in autoconf 2.5x. if test "${localedir+set}" != set; then localedir='$(datadir)/locale' fi AC_SUBST(localedir) # Determine the default macOS ccache type and whether to build the KCM # Mach RPC support. MACOS_FRAMEWORK= dnl The outer brackets around the case statement prevent m4 from dnl eating the brackets in the glob patterns, but also prevent us from dnl using AC_DEFINE within the body. [case $host in *-*-darwin[0-9].* | *-*-darwin10.*) # Use the normal default cache type for macOS 10.6 (Darwin 10) and # prior. Build the KCM Mach RPC support. OSX=osx ;; *-*-darwin*) # macOS 10.6 (Darwin 11) uses the KCM type by default. macOS 11 # (Darwin 20) uses an xpc-based cache type called XCACHE by default. # We can access either of these collections via a macos-specific # implementation of the API cache type. Build the KCM Mach RPC # support. OSX=osx macos_defccname=API: MACOS_FRAMEWORK="-framework Kerberos" ;; *) # This is not macOS; do not build the Mach RPC support and use the # normal default cache type. OSX=no ;; esac] if test "$macos_defccname" = API:; then AC_DEFINE(USE_CCAPI_MACOS, 1, [Define to build macOS CCAPI client]) fi AC_SUBST(OSX) AC_SUBST(MACOS_FRAMEWORK) # Build-time default ccache, keytab, and client keytab names. These # can be given as variable arguments DEFCCNAME, DEFKTNAME, and # DEFCKTNAME. Otherwise, we try to get the OS defaults from # krb5-config if we can, or fall back to hardcoded defaults. AC_ARG_VAR(DEFCCNAME, [Default ccache name]) AC_ARG_VAR(DEFKTNAME, [Default keytab name]) AC_ARG_VAR(DEFCKTNAME, [Default client keytab name]) AC_ARG_WITH([krb5-config], [AS_HELP_STRING([--with-krb5-config=PATH], [path to existing krb5-config program for defaults])], [], [with_krb5_config=krb5-config]) if test "x$with_krb5_config" != xno; then if test "x$with_krb5_config" = xyes; then with_krb5_config=krb5-config fi if $with_krb5_config --help 2>&1 | grep defccname >/dev/null; then AC_MSG_NOTICE([Using $with_krb5_config for build defaults]) : "${DEFCCNAME=`$with_krb5_config --defccname`}" : "${DEFKTNAME=`$with_krb5_config --defktname`}" : "${DEFCKTNAME=`$with_krb5_config --defcktname`}" fi fi if test "${DEFCCNAME+set}" != set; then if test "${macos_defccname+set}" = set; then DEFCCNAME=$macos_defccname else DEFCCNAME=FILE:/tmp/krb5cc_%{uid} fi fi if test "${DEFKTNAME+set}" != set; then DEFKTNAME=FILE:/etc/krb5.keytab fi if test "${DEFCKTNAME+set}" != set; then AX_RECURSIVE_EVAL($localstatedir, exp_localstatedir) DEFCKTNAME=FILE:$exp_localstatedir/krb5/user/%{euid}/client.keytab fi AC_MSG_NOTICE([Default ccache name: $DEFCCNAME]) AC_MSG_NOTICE([Default keytab name: $DEFKTNAME]) AC_MSG_NOTICE([Default client keytab name: $DEFCKTNAME]) AC_DEFINE_UNQUOTED(DEFCCNAME, ["$DEFCCNAME"], [Define to default ccache name]) AC_DEFINE_UNQUOTED(DEFKTNAME, ["$DEFKTNAME"], [Define to default keytab name]) AC_DEFINE_UNQUOTED(DEFCKTNAME, ["$DEFCKTNAME"], [Define to default client keytab name]) AC_ARG_VAR(PKCS11_MODNAME, [Default PKCS11 module name]) if test "${PKCS11_MODNAME+set}" != set; then PKCS11_MODNAME=opensc-pkcs11.so fi AC_MSG_NOTICE([Default PKCS11 module name: $PKCS11_MODNAME]) AC_DEFINE_UNQUOTED(PKCS11_MODNAME, ["$PKCS11_MODNAME"], [Default PKCS11 module name]) AC_CONFIG_FILES([build-tools/krb5-config], [chmod +x build-tools/krb5-config]) AC_CONFIG_FILES([build-tools/kadm-server.pc build-tools/kadm-client.pc build-tools/kdb.pc build-tools/krb5.pc build-tools/krb5-gssapi.pc build-tools/mit-krb5.pc build-tools/mit-krb5-gssapi.pc build-tools/gssrpc.pc ]) V5_AC_OUTPUT_MAKEFILE(. util util/support util/profile util/profile/testmod util/verto lib lib/kdb lib/crypto lib/crypto/krb lib/crypto/crypto_tests lib/crypto/builtin lib/crypto/builtin/des lib/crypto/builtin/aes lib/crypto/builtin/camellia lib/crypto/builtin/md4 lib/crypto/builtin/md5 lib/crypto/builtin/sha1 lib/crypto/builtin/sha2 lib/crypto/builtin/enc_provider lib/crypto/builtin/hash_provider lib/crypto/openssl lib/crypto/openssl/des lib/crypto/openssl/enc_provider lib/crypto/openssl/hash_provider lib/krb5 lib/krb5/error_tables lib/krb5/asn.1 lib/krb5/ccache lib/krb5/keytab lib/krb5/krb lib/krb5/rcache lib/krb5/os lib/krb5/unicode lib/gssapi lib/gssapi/generic lib/gssapi/krb5 lib/gssapi/spnego lib/gssapi/mechglue lib/rpc lib/rpc/unit-test lib/kadm5 lib/kadm5/clnt lib/kadm5/srv lib/krad lib/apputils kdc kprop config-files build-tools man doc include plugins/certauth/test plugins/gssapi/negoextest plugins/hostrealm/test plugins/localauth/test plugins/kadm5_hook/test plugins/kadm5_auth/test plugins/pwqual/test plugins/audit plugins/audit/test plugins/kdb/db2 plugins/kdb/db2/libdb2 plugins/kdb/db2/libdb2/hash plugins/kdb/db2/libdb2/btree plugins/kdb/db2/libdb2/db plugins/kdb/db2/libdb2/mpool plugins/kdb/db2/libdb2/recno plugins/kdb/db2/libdb2/test plugins/kdb/test plugins/kdcpolicy/test plugins/preauth/otp plugins/preauth/spake plugins/preauth/test plugins/authdata/greet_client plugins/authdata/greet_server plugins/tls/k5tls clients clients/klist clients/kinit clients/kvno clients/kdestroy clients/kpasswd clients/ksu clients/kswitch kadmin kadmin/cli kadmin/dbutil kadmin/ktutil kadmin/server appl appl/sample appl/sample/sclient appl/sample/sserver appl/simple appl/simple/client appl/simple/server appl/gss-sample appl/user_user tests tests/asn.1 tests/create tests/hammer tests/verify tests/gssapi tests/threads tests/shlib tests/gss-threads tests/misc ) krb5-1.22.1/src/wconfig.c0000664000175000017500000001257115051422640014736 0ustar ghudsonghudson/* wconfig.c */ /* * Copyright 1995,1996,1997,1998 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Program to take the place of the configure shell script under DOS. * The makefile.in files are constructed in such a way that all this * program needs to do is uncomment lines beginning ##DOS by removing the * first 5 characters of the line. This will allow lines like: * ##DOS!include win-pre.in to become: !include win-pre.in * * We also turn any line beginning with '@' into a blank line. * * If a config directory is specified, then the output will be start with * config\pre.in, then the filtered stdin text, and will end with * config\post.in. * * Syntax: wconfig [options] [config_directory] output_file * */ #include #include #include #include static int copy_file (char *path, char *fname); void add_ignore_list(char *str); int mit_specific = 0; char *win16_flag = "WIN16##"; char *win32_flag = "WIN32##"; int main(int argc, char *argv[]) { char *ignore_str = "--ignore="; int ignore_len; char *cp, *tmp; char *win_flag; char wflags[1024]; size_t wlen, alen; #ifdef _WIN32 win_flag = win32_flag; #else win_flag = "UNIX##"; #endif wlen = 0; ignore_len = strlen(ignore_str); argc--; argv++; while (*argv && *argv[0] == '-') { alen = strlen(*argv); if (wlen + 1 + alen > sizeof (wflags) - 1) { fprintf (stderr, "wconfig: argument list too long (internal limit %lu)", (unsigned long) sizeof (wflags)); exit (1); } if (wlen > 0) wflags[wlen++] = ' '; memcpy(&wflags[wlen], *argv, alen); wlen += alen; if (!strcmp(*argv, "--mit")) { mit_specific = 1; argc--; argv++; continue; } if (!strcmp(*argv, "--win16")) { win_flag = win16_flag; argc--; argv++; continue; } if (!strcmp(*argv, "--win32")) { win_flag = win32_flag; argc--; argv++; continue; } if (!strncmp(*argv, "--enable-", 9)) { tmp = malloc(alen - ignore_len + 3); if (!tmp) { fprintf(stderr, "wconfig: malloc failed!\n"); exit(1); } memcpy(tmp, *argv + ignore_len, alen - ignore_len); memcpy(tmp + alen - ignore_len, "##", 3); for (cp = tmp; *cp; cp++) { if (islower(*cp)) *cp = toupper(*cp); } add_ignore_list(tmp); argc--; argv++; continue; } if (!strncmp(*argv, ignore_str, ignore_len)) { add_ignore_list((*argv)+ignore_len); argc--; argv++; continue; } fprintf(stderr, "Invalid option: %s\n", *argv); exit(1); } wflags[wlen] = '\0'; if (win_flag) add_ignore_list(win_flag); if (mit_specific) add_ignore_list("MIT##"); if (wflags[0] && (argc > 0)) printf("WCONFIG_FLAGS=%s\n", wflags); if (argc > 0) copy_file (*argv, "win-pre.in"); copy_file("", "-"); if (argc > 0) copy_file (*argv, "win-post.in"); return 0; } char *ignore_list[64] = { "DOS##", "DOS", }; /* * Add a new item to the ignore list */ void add_ignore_list(char *str) { char **cpp; for (cpp = ignore_list; *cpp; cpp++) ; *cpp = str; } /* * * Copy_file * * Copies file 'path\fname' to stdout. * */ static int copy_file (char *path, char *fname) { FILE *fin; char buf[1024]; char **cpp, *ptr; size_t len, plen, flen; if (strcmp(fname, "-") == 0) { fin = stdin; } else { plen = strlen(path); flen = strlen(fname); if (plen + 1 + flen > sizeof(buf) - 1) { fprintf(stderr, "Name %s or %s too long", path, fname); return 1; } memcpy(buf, path, plen); #ifdef _WIN32 buf[plen] = '\\'; #else buf[plen] = '/'; #endif memcpy(buf + plen + 1, fname, flen); buf[plen + 1 + flen] = '\0'; fin = fopen (buf, "r"); /* File to read */ if (fin == NULL) { fprintf(stderr, "wconfig: Can't open file %s\n", buf); return 1; } } while (fgets (buf, sizeof(buf), fin) != NULL) { /* Copy file over */ if (buf[0] == '@') { fputs("\n", stdout); continue; } if (buf[0] != '#' || buf[1] != '#') { fputs(buf, stdout); continue; } ptr = buf; for (cpp = ignore_list; *cpp; cpp++) { len = strlen(*cpp); if (memcmp (*cpp, buf+2, len) == 0) { ptr += 2+len; break; } } fputs(ptr, stdout); } fclose (fin); return 0; } krb5-1.22.1/src/config/0000775000175000017500000000000015051422640014375 5ustar ghudsonghudsonkrb5-1.22.1/src/config/lib.in0000664000175000017500000001336515051422640015503 0ustar ghudsonghudson### config/lib.in # *** keep this in sync with libnover.in # # Makefile fragment that creates static, shared, and profiled libraries. # # The following variables must be set in the Makefile.in: # # LIBBASE library name without "lib" or extension # LIBMAJOR library major version # LIBMINOR library minor version # SHLIB_EXPDEPS list of libraries that this one has explicit # dependencies on, pref. in the form libfoo$(SHLIBEXT) # SHLIB_EXPLIBS list of libraries that this one has explicit # dependencies on, in "-lfoo" form. # RELDIR path to this directory relative to $(TOPLIBD) # # Makefile.in can also override the defaults for SHLIB_DIRS, # SHLIB_RDIRS, and STOBJLISTS from pre.in. LIBPREFIX=lib SHOBJLISTS=$(STOBJLISTS:.ST=.SH) PFOBJLISTS=$(STOBJLISTS:.ST=.PF) dummy-target-1 $(SUBDIROBJLISTS) $(SUBDIROBJLISTS:.ST=.SH) $(SUBDIROBJLISTS:.ST=.PF): all-recurse # Gets invoked as $(PARSE_OBJLISTS) list-of-OBJS.*-files PARSE_OBJLISTS= set -x && $(PERL) -p -e 'BEGIN { $$SIG{__WARN__} = sub {die @_} }; $$e=$$ARGV; $$e =~ s/OBJS\...$$//; s/^/ /; s/ $$//; s/ / $$e/g;' lib$(LIBBASE)$(STLIBEXT): $(STOBJLISTS) $(RM) $@ @echo "building static $(LIBBASE) library" set -x; objlist=`$(PARSE_OBJLISTS) $(STOBJLISTS)` && $(AR) cq $@ $$objlist $(RANLIB) $@ lib$(LIBBASE)$(SHLIBVEXT): $(SHOBJLISTS) $(SHLIB_EXPDEPS) $(SHLIB_EXPORT_FILE_DEP) $(RM) $@ @echo "building shared $(LIBBASE) library ($(LIBMAJOR).$(LIBMINOR))" set -x; objlist=`$(PARSE_OBJLISTS) $(SHOBJLISTS)` && $(MAKE_SHLIB_COMMAND) lib$(LIBBASE)$(SHLIBSEXT): lib$(LIBBASE)$(SHLIBVEXT) $(RM) $@ $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) $@ lib$(LIBBASE)$(SHLIBEXT): lib$(LIBBASE)$(SHLIBVEXT) $(RM) $@ $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) $@ binutils.versions: $(SHLIB_EXPORT_FILE) Makefile base=`echo "$(LIBBASE)" | sed -e 's/-/_/'`; \ echo > binutils.versions "$${base}_$(LIBMAJOR)_MIT {" sed >> binutils.versions < $(SHLIB_EXPORT_FILE) "s/$$/;/" echo >> binutils.versions "};" echo >> binutils.versions "HIDDEN { local: __*; _rest*; _save*; *; };" darwin.exports: $(SHLIB_EXPORT_FILE) Makefile sed > darwin-exports.tmp < $(SHLIB_EXPORT_FILE) "s/^/_/" $(MV) darwin-exports.tmp darwin.exports osf1.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) osf1.tmp osf1.exports sed "s/^/-exported_symbol /" < $(SHLIB_EXPORT_FILE) > osf1.tmp for f in . $(LIBINITFUNC); do \ if test "$$f" != "." ; then \ echo " -init $$f"__auxinit >> osf1.tmp; \ else :; fi; \ done a=""; \ for f in . $(LIBFINIFUNC); do \ if test "$$f" != "." ; then \ a="-fini $$f $$a"; \ else :; fi; \ done; echo " $$a" >> osf1.tmp mv -f osf1.tmp osf1.exports hpux.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) hpux.tmp hpux.exports sed "s/^/+e /" < $(SHLIB_EXPORT_FILE) > hpux.tmp a=""; \ for f in . $(LIBFINIFUNC); do \ if test "$$f" != .; then \ a="+I $${f}__auxfini $$a"; \ else :; fi; \ done; echo "$$a" >> hpux.tmp echo "+e errno" >> hpux.tmp base=`echo "$(LIBBASE)" | sed -e 's/-/_/'`; \ echo "+e _GLOBAL__FD_lib$${base}_$(LIBMAJOR)_$(LIBMINOR)" >> hpux.tmp; \ echo "+e _GLOBAL__FI_lib$${base}_$(LIBMAJOR)_$(LIBMINOR)" >> hpux.tmp mv -f hpux.tmp hpux.exports lib$(LIBBASE)$(PFLIBEXT): $(PFOBJLISTS) $(RM) $@ @echo "building profiled $(LIBBASE) library" set -x; objlist=`$(PARSE_OBJLISTS) $(PFOBJLISTS)` && $(AR) cq $@ $$objlist $(RANLIB) $@ $(TOPLIBD)/lib$(LIBBASE)$(STLIBEXT): lib$(LIBBASE)$(STLIBEXT) $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/lib$(LIBBASE)$(STLIBEXT) .) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBEXT): lib$(LIBBASE)$(SHLIBEXT) $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/lib$(LIBBASE)$(SHLIBEXT) .) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBSEXT): lib$(LIBBASE)$(SHLIBSEXT) $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/lib$(LIBBASE)$(SHLIBSEXT) .) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBVEXT): lib$(LIBBASE)$(SHLIBVEXT) $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/lib$(LIBBASE)$(SHLIBVEXT) .) $(TOPLIBD)/lib$(LIBBASE)$(PFLIBEXT): lib$(LIBBASE)$(PFLIBEXT) $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/lib$(LIBBASE)$(PFLIBEXT) .) all-libs: $(LIBLIST) all-liblinks: $(LIBLINKS) clean-libs: $(RM) lib$(LIBBASE)$(STLIBEXT) $(RM) lib$(LIBBASE)$(SHLIBVEXT) $(RM) lib$(LIBBASE)$(SHLIBSEXT) $(RM) lib$(LIBBASE)$(SHLIBEXT) $(RM) lib$(LIBBASE)$(PFLIBEXT) $(RM) binutils.versions osf1.exports darwin.exports hpux.exports clean-liblinks: $(RM) $(TOPLIBD)/lib$(LIBBASE)$(STLIBEXT) $(RM) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBVEXT) $(RM) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBSEXT) $(RM) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBEXT) $(RM) $(TOPLIBD)/lib$(LIBBASE)$(PFLIBEXT) install-libs: $(LIBINSTLIST) install-static: $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(STLIBEXT) $(INSTALL_DATA) lib$(LIBBASE)$(STLIBEXT) $(DESTDIR)$(KRB5_LIBDIR) $(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(STLIBEXT) install-shared: $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(SHLIBVEXT) $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(SHLIBEXT) $(INSTALL_SHLIB) lib$(LIBBASE)$(SHLIBVEXT) $(DESTDIR)$(KRB5_LIBDIR) (cd $(DESTDIR)$(KRB5_LIBDIR) && $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) \ lib$(LIBBASE)$(SHLIBEXT)) install-shlib-soname: install-shared $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(SHLIBSEXT) (cd $(DESTDIR)$(KRB5_LIBDIR) && $(LN_S) lib$(LIBBASE)$(SHLIBVEXT) \ lib$(LIBBASE)$(SHLIBSEXT)) install-profiled: $(RM) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(PFLIBEXT) $(INSTALL_DATA) lib$(LIBBASE)$(PFLIBEXT) $(DESTDIR)$(KRB5_LIBDIR) $(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/lib$(LIBBASE)$(PFLIBEXT) Makefile: $(top_srcdir)/config/lib.in $(BUILDTOP)/config.status: $(top_srcdir)/config/shlib.conf # Use the following if links need to be made to $(TOPLIBD): # all-unix: all-liblinks # install-unix: install-libs # clean-unix:: clean-liblinks clean-libs # Use the following if links need not be made: # all-unix: all-libs # install-unix: install-libs # clean-unix:: clean-libs ### ### end config/lib.in krb5-1.22.1/src/config/ac-archive/0000775000175000017500000000000015051422640016377 5ustar ghudsonghudsonkrb5-1.22.1/src/config/ac-archive/README0000664000175000017500000000050215051422640017254 0ustar ghudsonghudson-*- text -*- These macros are taken from the autoconf archive at https://www.gnu.org/software/autoconf-archive/ . They are licensed under a modified version of the GNU General Public License as noted in the comments near the top of each file. ax_pthread.m4 serial 31 2023-02-20 ax_recursive_eval.m4 serial 1 2017-01-05 krb5-1.22.1/src/config/ac-archive/ax_pthread.m40000664000175000017500000005403415051422640020766 0ustar ghudsonghudson# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is # needed for multi-threaded programs (defaults to the value of CC # respectively CXX otherwise). (This is necessary on e.g. AIX to use the # special cc_r/CC_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # CXX="$PTHREAD_CXX" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # Copyright (c) 2019 Marc Stevens # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 31 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items with a "," contain both # C compiler flags (before ",") and linker flags (after ","). Other items # starting with a "-" are C compiler flags, and remaining items are # library names, except for "none" which indicates that we try without # any flags at all, and "pthread-config" which is a program returning # the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], [ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif ], [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; esac # Are we compiling with Clang? AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif ], [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) # Note that for GCC and Clang -pthread generally implies -lpthread, # except when -nostdlib is passed. # This is problematic using libtool to build C++ shared libraries with pthread: # [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 # [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 # [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 # To solve this, first try -pthread together with -lpthread for GCC AS_IF([test "x$GCC" = "xyes"], [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) # Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first AS_IF([test "x$ax_pthread_clang" = "xyes"], [ax_pthread_flags="-pthread,-lpthread -pthread"]) # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; *,*) PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void *some_global = NULL; static void routine(void *a) { /* To avoid any unused-parameter or unused-but-set-parameter warning. */ some_global = a; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ac_link="$ax_pthread_save_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [ac_link="$ax_pthread_2step_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [break]) ]) done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" ]) case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_CACHE_CHECK([for joinable pthread attribute], [ax_cv_PTHREAD_JOINABLE_ATTR], [ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $ax_pthread_attr; return attr /* ; */])], [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], []) done ]) AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes"], [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$ax_cv_PTHREAD_JOINABLE_ATTR], [Define to necessary symbol if this constant uses a non-standard name on your system.]) ax_pthread_joinable_attr_defined=yes ]) AC_CACHE_CHECK([whether more special flags are required for pthreads], [ax_cv_PTHREAD_SPECIAL_FLAGS], [ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac ]) AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes"], [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT; return i;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) ax_pthread_prio_inherit_defined=yes ]) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [ AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) ], [ AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) ] ) ]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) AC_SUBST([PTHREAD_CXX]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD krb5-1.22.1/src/config/ac-archive/ax_recursive_eval.m40000664000175000017500000000455015051422640022353 0ustar ghudsonghudson# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_recursive_eval.html # =========================================================================== # # SYNOPSIS # # AX_RECURSIVE_EVAL(VALUE, RESULT) # # DESCRIPTION # # Interpolate the VALUE in loop until it doesn't change, and set the # result to $RESULT. WARNING: It's easy to get an infinite loop with some # unsane input. # # LICENSE # # Copyright (c) 2008 Alexandre Duret-Lutz # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 1 AC_DEFUN([AX_RECURSIVE_EVAL], [_lcl_receval="$1" $2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do _lcl_receval_old="[$]_lcl_receval" eval _lcl_receval="\"[$]_lcl_receval\"" done echo "[$]_lcl_receval")`]) krb5-1.22.1/src/config/post.in0000664000175000017500000002056215051422640015717 0ustar ghudsonghudson############################################################ ## config/post.in ## # in case there is no default target (very unlikely) all: check-windows: # In a few parts of "make check" we run shell scripts which run # programs linked against krb5 libraries. On macOS 10.11 and higher, # DYLD_LIBRARY_PATH is cleared by the shell unless System Integrity # Protection is turned off, so we need to set runtime linker # environment variables from within test scripts. A Makefile.in which # runs shell script tests should make its check rule depend on # runenv.sh and make each script begin with ". ./runenv.sh". runenv.sh: $(RUN_SETUP); for i in $(RUN_VARS); do \ eval echo "$$i=\\\"\$$$$i\\\""; \ echo "export $$i"; done > $@ ############################## # dependency generation # depend: depend-postrecurse depend-postrecurse: depend-recurse depend-recurse: depend-prerecurse depend-prerecurse: depend-postrecurse: depend-postrecurse: depend-update-makefile ALL_DEP_SRCS= $(SRCS) $(EXTRADEPSRCS) # be sure to check ALL_DEP_SRCS against *what it would be if SRCS and # EXTRADEPSRCS are both empty* $(BUILDTOP)/.depend-verify-srcdir: @if test "$(srcdir)" = "." ; then \ echo 1>&2 error: cannot build dependencies with srcdir=. ; \ echo 1>&2 "(can't distinguish generated files from source files)" ; \ echo 1>&2 "Run 'make distclean' and create a separate build dir" ; \ exit 1 ; \ elif test -f "$(top_srcdir)/include/autoconf.h"; then \ echo 1>&2 "error: generated headers found in source tree" ; \ echo 1>&2 "Run 'make distclean' in source tree first" ; \ exit 1 ; \ else \ if test -r $(BUILDTOP)/.depend-verify-srcdir; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-srcdir); fi \ fi $(BUILDTOP)/.depend-verify-et: depend-verify-et-$(COM_ERR_VERSION) depend-verify-et-k5: @if test -r $(BUILDTOP)/.depend-verify-et; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-et); fi depend-verify-et-sys depend-verify-et-intlsys: @echo 1>&2 error: cannot build dependencies using system et package @exit 1 $(BUILDTOP)/.depend-verify-ss: depend-verify-ss-$(SS_VERSION) depend-verify-ss-k5: @if test -r $(BUILDTOP)/.depend-verify-ss; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-ss); fi depend-verify-ss-sys: @echo 1>&2 error: cannot build dependencies using system ss package @exit 1 $(BUILDTOP)/.depend-verify-verto: depend-verify-verto-$(VERTO_VERSION) depend-verify-verto-k5: @if test -r $(BUILDTOP)/.depend-verify-verto; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-verto); fi depend-verify-verto-sys: @echo 1>&2 error: cannot build dependencies using system verto package @echo 1>&2 Please configure with --without-system-verto @exit 1 $(BUILDTOP)/.depend-verify-gcc: depend-verify-gcc-@HAVE_GCC@ depend-verify-gcc-yes: @if test -r $(BUILDTOP)/.depend-verify-gcc; then :; \ else (set -x; touch $(BUILDTOP)/.depend-verify-gcc); fi depend-verify-gcc-no: @echo 1>&2 error: The '"depend"' rules are written for gcc. @echo 1>&2 Please use gcc, or update the rules to handle your compiler. @exit 1 DEP_CFG_VERIFY = $(BUILDTOP)/.depend-verify-srcdir \ $(BUILDTOP)/.depend-verify-et $(BUILDTOP)/.depend-verify-ss \ $(BUILDTOP)/.depend-verify-verto DEP_VERIFY = $(DEP_CFG_VERIFY) $(BUILDTOP)/.depend-verify-gcc .d: $(ALL_DEP_SRCS) $(DEP_CFG_VERIFY) depend-dependencies if test "$(ALL_DEP_SRCS)" != " " ; then \ $(RM) .dtmp && $(MAKE) .dtmp && mv -f .dtmp .d ; \ else \ touch .d ; \ fi # These are dependencies of the depend target that do not get fed to # the compiler. Examples include generated header files. depend-dependencies: # .dtmp must *always* be out of date so that $? can be used to perform # VPATH searches on the sources. # # NOTE: This will fail when using Make programs whose VPATH support is # broken. .dtmp: $(ALL_DEP_SRCS) $(CC) -M -DDEPEND $(ALL_CFLAGS) $? > .dtmp # NOTE: This will also generate spurious $(OUTPRE) and $(OBJEXT) # references in rules for non-library objects in a directory where # library objects happen to be built. It's mostly harmless. .depend: .d $(top_srcdir)/util/depfix.pl perl $(top_srcdir)/util/depfix.pl '$(top_srcdir)' '$(mydir)' \ '$(srcdir)' '$(BUILDTOP)' '$(STLIBOBJS)' < .d > .depend # Temporarily keep the rule for removing the dependency line eater # until we're sure we've gotten everything converted and excised the # old stuff from Makefile.in files. depend-update-makefile: .depend depend-recurse if test "$(ALL_DEP_SRCS)" != " " ; then \ $(CP) .depend $(srcdir)/deps.new ; \ else \ echo "# No dependencies here." > $(srcdir)/deps.new ; \ fi $(top_srcdir)/config/move-if-changed $(srcdir)/deps.new $(srcdir)/deps sed -e '/^# +++ Dependency line eater +++/,$$d' \ < $(srcdir)/Makefile.in > $(srcdir)/Makefile.in.new $(top_srcdir)/config/move-if-changed $(srcdir)/Makefile.in.new \ $(srcdir)/Makefile.in DEPTARGETS = .depend .d .dtmp $(DEP_VERIFY) DEPTARGETS_CLEAN = .depend .d .dtmp $(DEPTARGETS_@srcdir@_@CONFIG_RELTOPDIR@) DEPTARGETS_@top_srcdir@_. = $(DEP_VERIFY) # Clear out dependencies. Should only be used temporarily, e.g., while # moving or renaming headers and then rebuilding dependencies. undepend: undepend-postrecurse undepend-recurse: undepend-postrecurse: undepend-recurse if test -n "$(SRCS)" ; then \ sed -e '/^# +++ Dependency line eater +++/,$$d' \ < $(srcdir)/Makefile.in \ > $(srcdir)/Makefile.in.new ;\ echo "# +++ Dependency line eater +++" >> $(srcdir)/Makefile.in.new ;\ echo "# (dependencies temporarily removed)" >> $(srcdir)/Makefile.in.new ;\ $(top_srcdir)/config/move-if-changed $(srcdir)/Makefile.in.new $(srcdir)/Makefile.in;\ else :; fi # # end dependency generation ############################## # Python tests check-unix: check-pytests-@HAVE_PYTHON@ # Makefile.in should add rules to check-pytests to execute Python tests. check-pytests-yes: check-pytests check-pytests-no: check-pytests: # cmocka tests check-unix: check-cmocka-@HAVE_CMOCKA@ check-cmocka-yes: check-cmocka check-cmocka-no: check-cmocka: clean: clean-$(WHAT) clean-unix:: $(RM) $(OBJS) $(DEPTARGETS_CLEAN) $(EXTRA_FILES) $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog testtrace runenv.sh -$(RM) -r testdir clean-windows:: $(RM) *.$(OBJEXT) $(RM) msvc.pdb *.err distclean: distclean-$(WHAT) distclean-normal-clean: $(MAKE) NORECURSE=true clean distclean-prerecurse: distclean-normal-clean distclean-nuke-configure-state: $(RM) config.log config.cache config.status Makefile distclean-postrecurse: distclean-nuke-configure-state Makefiles-prerecurse: Makefile # mydir = relative path from top to this Makefile Makefile: $(srcdir)/Makefile.in $(srcdir)/deps $(BUILDTOP)/config.status \ $(top_srcdir)/config/pre.in $(top_srcdir)/config/post.in (cd $(BUILDTOP) && $(SHELL) config.status $(mydir)/Makefile) $(BUILDTOP)/config.status: $(top_srcdir)/configure (cd $(BUILDTOP) && $(SHELL) config.status --recheck) $(top_srcdir)/configure: @MAINT@ \ $(top_srcdir)/configure.ac \ $(top_srcdir)/patchlevel.h \ $(top_srcdir)/aclocal.m4 (cd $(top_srcdir) && \ $(AUTOCONF) -f --include=$(CONFIG_RELTOPDIR) $(AUTOCONFFLAGS)) RECURSE_TARGETS=all-recurse clean-recurse distclean-recurse install-recurse \ generate-files-mac-recurse \ check-recurse depend-recurse undepend-recurse \ Makefiles-recurse install-headers-recurse # MY_SUBDIRS overrides any setting of SUBDIRS generated by the # configure script that generated this Makefile. This is needed when # the configure script that produced this Makefile creates multiple # Makefiles in different directories; the setting of SUBDIRS will be # the same in each. # # LOCAL_SUBDIRS seems to account for the case where the configure # script doesn't call any other subsidiary configure scripts, but # generates multiple Makefiles. $(RECURSE_TARGETS): @case "`echo 'x$(MFLAGS)'|sed -e 's/^x//' -e 's/ --.*$$//'`" \ in *[ik]*) e="status=1" ;; *) e="exit 1";; esac; \ do_subdirs="$(SUBDIRS)" ; \ status=0; \ if test -n "$$do_subdirs" && test -z "$(NORECURSE)"; then \ for i in $$do_subdirs ; do \ if test -d $$i && test -r $$i/Makefile ; then \ case $$i in .);; *) \ target=`echo $@|sed s/-recurse//`; \ echo "making $$target in $(CURRENT_DIR)$$i..."; \ if (cd $$i ; $(MAKE) \ CURRENT_DIR=$(CURRENT_DIR)$$i/ $$target) then :; \ else eval $$e; fi; \ ;; \ esac; \ else \ echo "Skipping missing directory $(CURRENT_DIR)$$i" ; \ fi; \ done; \ else :; \ fi;\ exit $$status ## ## end of post.in ############################################################ krb5-1.22.1/src/config/config.guess0000775000175000017500000014306715051422640016730 0ustar ghudsonghudson#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2024-07-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still # use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c17 c99 c89 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #if defined(__ANDROID__) LIBC=android #else #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #elif defined(__LLVM_LIBC__) LIBC=llvm #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-pc-managarm-mlibc" ;; *:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __ARM_EABI__ #ifdef __ARM_PCS_VFP ABI=eabihf #else ABI=eabi #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; esac fi GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:cos:*:*) GUESS=$UNAME_MACHINE-unknown-cos ;; kvx:mbr:*:*) GUESS=$UNAME_MACHINE-unknown-mbr ;; loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __i386__ ABI=x86 #else #ifdef __ILP32__ ABI=x32 #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in x86) CPU=i686 ;; x32) LIBCABI=${LIBC}x32 ;; esac fi GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; ppc:Haiku:*:*) # Haiku running on Apple PowerPC GUESS=powerpc-apple-haiku ;; *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) GUESS=$UNAME_MACHINE-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; *:Ironclad:*:*) GUESS=$UNAME_MACHINE-unknown-ironclad ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif int main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: krb5-1.22.1/src/config/mkinstalldirs0000775000175000017500000000123715051422640017206 0ustar ghudsonghudson#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id$ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here krb5-1.22.1/src/config/shlib.conf0000664000175000017500000003501215051422640016346 0ustar ghudsonghudson# This shell script fragment should set a bunch of variables: # # CC_LINK_STATIC: How to link a program if we're only building static # libraries for krb5 (but may use other shared libs, and there may # be a shared krb5 lib already installed that we shouldn't use). # CC_LINK_SHARED: How to link a program if we're building shared # libraries. # CXX_LINK_STATIC, CXX_LINK_SHARED: Variants for C++. # STLIBEXT: Static library extension. # SHLIBEXT: Shared library extension. # SHLIBVEXT: Shared library extension, with major version. # SHLIBSEXT: Shared library extension, with full version. # (... finish documenting these ...) # # Set up some defaults. # STLIBEXT=.a # Default to being unable to build shared libraries. SHLIBEXT=.so-nobuild SHLIBVEXT=.so.v-nobuild SHLIBSEXT=.so.s-nobuild # Most systems support profiled libraries. PFLIBEXT=_p.a # Install libraries executable. Some systems (e.g., RPM-based ones) require # this for package dependency generation, while others are ambivalent or will # strip it during packaging. INSTALL_SHLIB='$(INSTALL)' # Most systems use the same objects for shared libraries and dynamically # loadable objects. DYNOBJEXT='$(SHLIBEXT)' MAKE_DYNOBJ_COMMAND='$(MAKE_SHLIB_COMMAND)' DYNOBJ_EXPDEPS='$(SHLIB_EXPDEPS)' DYNOBJ_EXPFLAGS='$(SHLIB_EXPFLAGS)' # On some platforms we will instruct the linker to run named functions # (specified by LIBINITFUNC and LIBFINIFUNC in each library's Makefile.in) as # initializers or finalizers. use_linker_init_option=no use_linker_fini_option=no # Where possible we will prevent unloading of the libraries we build, in which # case we can skip running finalizers. Do not set use_linker_fini_option if # setting lib_unload_prevented. lib_unload_prevented=no STOBJEXT=.o SHOBJEXT=.so PFOBJEXT=.po # Default for systems w/o shared libraries CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' # SHLIB_EXPORT_FILE_DEP='$(SHLIB_EXPORT_FILE)' # This will do for most platforms, and we'll substitute for # LDCOMBINE, SHLIB_EXPFLAGS, and LDCOMBINE_TAIL below. MAKE_SHLIB_COMMAND=x INIT_FINI_PREP=: # Default to static or shared libraries? default_static=no default_shared=yes # Set up architecture-specific variables. case $krb5_cv_host in # Note: "-Wl,+s" when building executables enables the use of the # SHLIB_PATH environment variable for finding shared libraries # in non-standard directories. If a non-standard search-path for # shared libraries is compiled into the executable (using # -Wl,+b,$KRB5_SHLIBDIR), then the order of "-Wl,+b,..." and "-Wl,+s" # on the commandline of the linker will determine which path # (compiled-in or SHLIB_PATH) will be searched first. # # +I initproc routine gets called at load and unload time for # shl_load calls, but appears to never be called for link-time # specified libraries. # +e sym exports symbol and supposedly prevents other symbols # from being exported, according to the man page, but the # latter bit doesn't actually seem to work # -O +dpv should display any routines eliminated as unused, but -b # apparently turns that off *-*-hpux*) case $host_cpu in hppa*) SHLIBEXT=.sl ;; ia64*) SHLIBEXT=.so ;; esac SHLIBVEXT='.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.$(LIBMAJOR)' RPATH_FLAG='-Wl,+b,' if test "$ac_cv_c_compiler_gnu" = yes; then PICFLAGS=-fPIC SHLIB_RPATH_FLAGS='-Wl,+b,$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='-Wl,+s $(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' LDCOMBINE='gcc -fPIC -shared -Wl,+h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) -Wl,-c,hpux.exports' else PICFLAGS=+z SHLIB_RPATH_FLAGS='+b $(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' LDCOMBINE='ld -b +h $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) -c hpux.exports' fi MAKE_SHLIB_COMMAND="${LDCOMBINE} -o \$@ \$\$objlist \$(LDFLAGS) \$(SHLIB_EXPFLAGS) ${LDCOMBINE_TAIL}" PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='SHLIB_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='SHLIB_PATH' SHLIB_EXPORT_FILE_DEP=hpux.exports # Do *not* set use_linker_init_option=yes here, because in the # case where the library is specified at program link time, the # initialization function appears not to get called, only for # shl_load. But for finalization functions, the shl_load case # is the one we care about. # # Not setting use_linker_init_option here should cause compilation # failures if the user tries to disable delayed initialization. use_linker_fini_option=yes ;; mips-*-netbsd*) PICFLAGS=-fPIC SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so LDCOMBINE='ld -shared -soname $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) -z nodelete' SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' RPATH_FLAG='-Wl,-rpath -Wl,' PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg lib_unload_prevented=yes ;; *-*-netbsd*) PICFLAGS=-fPIC SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBEXT=.so LDCOMBINE='$(CC) -shared -Wl,-z,nodelete' SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' RPATH_FLAG=-R PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg lib_unload_prevented=yes ;; *-*-freebsd*) case $krb5_cv_host in sparc64-*) PICFLAGS=-fPIC ;; *) PICFLAGS=-fpic ;; esac SHLIBVEXT='.so.$(LIBMAJOR)' RPATH_FLAG='-Wl,--enable-new-dtags -Wl,-rpath -Wl,' PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' SHLIBEXT=.so LDCOMBINE='ld -Bshareable -z nodelete' SHLIB_RPATH_FLAGS='--enable-new-dtags -rpath $(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg lib_unload_prevented=yes ;; *-*-openbsd*) PICFLAGS=-fpic SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBEXT=.so LDCOMBINE='ld -Bshareable -z nodelete' SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' RPATH_FLAG=-R PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' PROFFLAGS=-pg lib_unload_prevented=yes ;; *-*-darwin* | *-*-rhapsody*) SHLIBVEXT='.$(LIBMAJOR).$(LIBMINOR).dylib' SHLIBSEXT='.$(LIBMAJOR).dylib' SHLIB_EXPFLAGS='$(SHLIB_DIRS) $(SHLIB_EXPLIBS)' SHLIBEXT=.dylib DYNOBJEXT=.so SHLIB_EXPORT_FILE_DEP=darwin.exports LDCOMBINE='$(CC) -undefined error -dead_strip -dynamiclib -compatibility_version $(LIBMAJOR) -current_version $(LIBMAJOR).$(LIBMINOR) -install_name "$(KRB5_LIBDIR)/$(LIBPREFIX)$(LIBBASE)$(SHLIBVEXT)" -exported_symbols_list darwin.exports $(CFLAGS)' # The -dylib_file option tells the linker where to find indirect dependent # libraries, without adding them to the dependency list. We need this because # the direct dependent libraries contain the pathname where the indirect # dependent libraries will be installed (but haven't been yet). LDCOMBINE_TAIL="" for lib in libkrb5support.1.1.dylib libkadm5srv.5.1.dylib libkdb5.4.0.dylib; do LDCOMBINE_TAIL="$LDCOMBINE_TAIL -dylib_file \"\$(KRB5_LIBDIR)/$lib\":\$(TOPLIBD)/$lib" done MAKE_DYNOBJ_COMMAND='$(CC) -bundle $(CFLAGS) $(LDFLAGS) -o $@ $$objlist $(DYNOBJ_EXPFLAGS) $(LDFLAGS) -exported_symbols_list darwin.exports'" ${LDCOMBINE_TAIL}" CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) -dynamic $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) -dynamic $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='DYLD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='DYLD_LIBRARY_PATH' ;; *-*-solaris*) if test "$ac_cv_c_compiler_gnu" = yes; then PICFLAGS=-fPIC LDCOMBINE='$(CC) $(CFLAGS) -shared -Wl,-z,nodelete -h $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT)' else PICFLAGS=-KPIC # Solaris cc doesn't default to stuffing the SONAME field... LDCOMBINE='$(CC) $(CFLAGS) -dy -G -z text -z nodelete -h $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $$initfini' # case $krb5_cv_host in *-*-solaris2.[1-7] | *-*-solaris2.[1-7].*) # Did Solaris 7 and earlier have a linker option for this? ;; *) INIT_FINI_PREP='initfini=; for f in . $(LIBINITFUNC); do if test $$f = .; then :; else initfini="$$initfini -Wl,-z,initarray=$${f}__auxinit"; fi; done;' use_linker_init_option=yes ;; esac fi SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so SHLIB_RPATH_FLAGS='-R$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg RPATH_FLAG=-R PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(PURE) $(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(PURE) $(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(PURE) $(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(PURE) $(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' lib_unload_prevented=yes ;; *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu) PICFLAGS=-fPIC SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so # Linux ld doesn't default to stuffing the SONAME field... # Use objdump -x to examine the fields of the library # UNDEF_CHECK is suppressed by --enable-asan LDCOMBINE='$(CC) -shared -fPIC -Wl,-z,nodelete -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)' UNDEF_CHECK='-Wl,--no-undefined' # $(EXPORT_CHECK) runs export-check.pl when in maintainer mode. LDCOMBINE_TAIL='-Wl,--version-script binutils.versions $(EXPORT_CHECK)' SHLIB_EXPORT_FILE_DEP=binutils.versions RPATH_FLAG='-Wl,--enable-new-dtags -Wl,-rpath -Wl,' # For cases where we do have dependencies on other libraries # built in this tree... SHLIB_RPATH_FLAGS='$(RPATH_FLAG)$(SHLIB_RDIRS)' SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`' RUN_VARS='LD_LIBRARY_PATH' lib_unload_prevented=yes ## old version: # Linux libc does weird stuff at shlib link time, must be # explicitly listed here. This also makes it get used even # for the libraries marked as not having any dependencies; while # that's not strictly correct, the resulting behavior -- not adding # extra -R directories -- is still what we want. #LDCOMBINE='ld -shared -h $(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT)' #LDCOMBINE_TAIL="-lc" #SHLIB_EXPFLAGS='-R$(SHLIB_RDIRS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' ;; *-*-aix*) SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBEXT=.so # AIX doesn't need separate PIC objects SHOBJEXT=.o SHLIB_EXPFLAGS=' $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg if test "$ac_cv_c_compiler_gnu" = "yes" ; then wl_prefix=-Wl, RPATH_FLAG='-Wl,-blibpath:' LDCOMBINE='$(CC) -shared -v -o $@ $$objlist -nostartfiles -Xlinker -bgcbypass:1 -Xlinker -bfilelist -Xlinker -bM:SRE -Xlinker -bE:$(SHLIB_EXPORT_FILE) -Xlinker -bernotok -Xlinker -brtl $(SHLIB_EXPFLAGS) $(LDFLAGS) -lc $$initfini' else wl_prefix= RPATH_FLAG=-blibpath: LDCOMBINE='/bin/ld -o $@ $$objlist -H512 -T512 -bnoentry -bgcbypass:1 -bnodelcsect -bfilelist -bM:SRE -bE:$(SHLIB_EXPORT_FILE) -bernotok -brtl $(SHLIB_EXPFLAGS) $(LDFLAGS) -lc $$initfini' fi # Assume initialization always delayed. INIT_FINI_PREP="wl=${wl_prefix}; "'i=1; initfini=; for f in . $(LIBFINIFUNC); do if test $$f != .; then initfini="$$initfini $${wl}-binitfini::$$f:$$i"; else :; fi; i=`expr $$i + 1`; done' use_linker_fini_option=yes MAKE_SHLIB_COMMAND="${INIT_FINI_PREP} && ${LDCOMBINE}" RPATH_TAIL=:/usr/lib:/lib PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH):'"$RPATH_TAIL" CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' # $(PROG_RPATH) is here to handle things like a shared tcl library RUN_ENV='LIBPATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`:$(PROG_RPATH):/usr/lib:/usr/local/lib' RUN_VARS='LIBPATH' ;; esac if test "${MAKE_SHLIB_COMMAND}" = "x" ; then if test "${INIT_FINI_PREP}" != ":"; then MAKE_SHLIB_COMMAND="${INIT_FINI_PREP} && ${LDCOMBINE} -o \$@ \$\$objlist \$(SHLIB_EXPFLAGS) \$(LDFLAGS) ${LDCOMBINE_TAIL}" else MAKE_SHLIB_COMMAND="${LDCOMBINE} -o \$@ \$\$objlist \$(SHLIB_EXPFLAGS) \$(LDFLAGS) ${LDCOMBINE_TAIL}" fi fi krb5-1.22.1/src/config/libpriv.in0000664000175000017500000000063715051422640016402 0ustar ghudsonghudson# Additional definitions for private libraries, which we build as archive # libraries (or equivalent) and do not install. # # The defaults (for installed shared libraries) are in pre.in. We # override them here, before lib.in uses them. LIBLIST=lib$(LIBBASE)$(STLIBEXT) LIBLINKS=$(TOPLIBD)/lib$(LIBBASE)$(STLIBEXT) OBJLISTS=OBJS.ST LIBINSTLIST= SHLIBEXT=.so-nobuild SHLIBVEXT=.so.v-nobuild SHLIBSEXT=.so.s-nobuild krb5-1.22.1/src/config/rm.bat0000664000175000017500000000225515051422640015507 0ustar ghudsonghudson@echo off :loop if exist %1 del %1 shift if not %1.==. goto loop exit Rem Rem rm.bat Rem Rem Copyright 1995 by the Massachusetts Institute of Technology. Rem All Rights Reserved. Rem Rem Export of this software from the United States of America may Rem require a specific license from the United States Government. Rem It is the responsibility of any person or organization contemplating Rem export to obtain such a license before exporting. Rem Rem WITHIN THAT CONSTRAINT, permission to use, copy, modify, and Rem distribute this software and its documentation for any purpose and Rem without fee is hereby granted, provided that the above copyright Rem notice appear in all copies and that both that copyright notice and Rem this permission notice appear in supporting documentation, and that Rem the name of M.I.T. not be used in advertising or publicity pertaining Rem to distribution of the software without specific, written prior Rem permission. M.I.T. makes no representations about the suitability of Rem this software for any purpose. It is provided "as is" without express Rem or implied warranty. Rem Rem Rem Batch file to mimic the functionality of the Unix rm command Rem krb5-1.22.1/src/config/pre.in0000664000175000017500000004326315051422640015523 0ustar ghudsonghudson############################################################ ## config/pre.in ## common prefix for all Makefile.in in the Kerberos V5 tree. ## # These are set per-directory by autoconf 2.52 and 2.53: # srcdir=@srcdir@ # top_srcdir=@top_srcdir@ # but these are only set by autoconf 2.53, and thus not useful to us on # macOS yet (as of 10.2): # abs_srcdir=@abs_srcdir@ # abs_top_srcdir=@abs_top_srcdir@ # builddir=@builddir@ # abs_builddir=@abs_builddir@ # top_builddir=@top_builddir@ # abs_top_builddir=@abs_top_builddir@ # The "top" variables refer to the directory with the configure (or # config.status) script. WHAT = unix SHELL=/bin/sh all: all-$(WHAT) clean: clean-$(WHAT) distclean: distclean-$(WHAT) install: install-$(WHAT) check: check-$(WHAT) install-headers: install-headers-$(WHAT) ############################## # Recursion rule support # # The commands for the recursion targets live in config/post.in. # # General form of recursion rules: # # Each recursive target foo-unix has related targets: foo-prerecurse, # foo-recurse, and foo-postrecurse # # The foo-recurse rule is in post.in. It is what actually recursively # calls make. # # foo-recurse depends on foo-prerecurse, so any targets that must be # built before descending into subdirectories must be dependencies of # foo-prerecurse. # # foo-postrecurse depends on foo-recurse, but targets that must be # built after descending into subdirectories should be have # foo-recurse as dependencies in addition to being listed under # foo-postrecurse, to avoid ordering issues. # # The foo-prerecurse, foo-recurse, and foo-postrecurse rules are all # single-colon rules, to avoid nasty ordering problems with # double-colon rules. # # e.g. # all: includes foo # foo: # echo foo # includes: # echo bar # includes: # echo baz # # will result in "bar", "foo", "baz" on AIX, and possibly others. all-unix: all-postrecurse all-postrecurse: all-recurse all-recurse: all-prerecurse all-prerecurse: all-postrecurse: clean-unix:: clean-postrecurse clean-postrecurse: clean-recurse clean-recurse: clean-prerecurse clean-prerecurse: clean-postrecurse: distclean-unix: distclean-postrecurse distclean-postrecurse: distclean-recurse distclean-recurse: distclean-prerecurse distclean-prerecurse: distclean-postrecurse: install-unix: install-postrecurse install-postrecurse: install-recurse install-recurse: install-prerecurse install-prerecurse: install-postrecurse: install-headers-unix: install-headers-postrecurse install-headers-postrecurse: install-headers-recurse install-headers-recurse: install-headers-prerecurse install-headers-prerecurse: install-headers-postrecurse: check-unix: check-postrecurse check-postrecurse: check-recurse check-recurse: check-prerecurse check-prerecurse: check-postrecurse: Makefiles: Makefiles-postrecurse Makefiles-postrecurse: Makefiles-recurse Makefiles-recurse: Makefiles-prerecurse Makefiles-prerecurse: Makefiles-postrecurse: generate-files-mac: generate-files-mac-postrecurse generate-files-mac-postrecurse: generate-files-mac-recurse generate-files-mac-recurse: generate-files-mac-prerecurse generate-files-mac-prerecurse: # # end recursion rule support ############################## # Directory syntax: # # begin relative path REL= # this is magic... should only be used for preceding a program invocation C=./ # "/" for UNIX, "\" for Windows; *sigh* S=/ # srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ CONFIG_RELTOPDIR = @CONFIG_RELTOPDIR@ # DEFS set by configure # DEFINES set by local Makefile.in # LOCALINCLUDES set by local Makefile.in # CPPFLAGS user override # CFLAGS user override but starts off set by configure # WARN_CFLAGS user override but starts off set by configure # PTHREAD_CFLAGS set by configure, not included in CFLAGS so that we # don't pull the pthreads library into shared libraries # ASAN_FLAGS set by configure when --enable-asan is used ALL_CFLAGS = $(DEFS) $(DEFINES) $(KRB_INCLUDES) $(LOCALINCLUDES) \ -DKRB5_DEPRECATED=1 \ -DKRB5_PRIVATE \ $(CPPFLAGS) $(CFLAGS) $(WARN_CFLAGS) $(PTHREAD_CFLAGS) $(ASAN_FLAGS) ALL_CXXFLAGS = $(DEFS) $(DEFINES) $(KRB_INCLUDES) $(LOCALINCLUDES) \ -DKRB5_DEPRECATED=1 \ -DKRB5_PRIVATE \ $(CPPFLAGS) $(CXXFLAGS) $(WARN_CXXFLAGS) $(PTHREAD_CFLAGS) \ $(ASAN_FLAGS) CFLAGS = @CFLAGS@ CXXFLAGS = @CXXFLAGS@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_CXXFLAGS = @WARN_CXXFLAGS@ ASAN_FLAGS = @ASAN_FLAGS@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ THREAD_LINKOPTS = $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) CPPFLAGS = @CPPFLAGS@ DEFS = @DEFS@ CC = @CC@ CXX = @CXX@ LD = $(PURE) @LD@ KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ FUZZ_LDFLAGS = @FUZZ_LDFLAGS@ INSTALL=@INSTALL@ INSTALL_STRIP= INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP) INSTALL_SCRIPT=@INSTALL_PROGRAM@ INSTALL_DATA=@INSTALL_DATA@ INSTALL_SHLIB=@INSTALL_SHLIB@ INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root ## This is needed because autoconf will sometimes define @exec_prefix@ to be ## ${prefix}. prefix=@prefix@ INSTALL_PREFIX=$(prefix) INSTALL_EXEC_PREFIX=@exec_prefix@ exec_prefix=@exec_prefix@ datarootdir=@datarootdir@ localstatedir=@localstatedir@ runstatedir=@runstatedir@ datadir = @datadir@ EXAMPLEDIR = $(datadir)/examples/krb5 KRB5MANROOT = @mandir@ ADMIN_BINDIR = @sbindir@ SERVER_BINDIR = @sbindir@ CLIENT_BINDIR =@bindir@ PKGCONFIG_DIR = @libdir@/pkgconfig ADMIN_MANDIR = $(KRB5MANROOT)/man8 SERVER_MANDIR = $(KRB5MANROOT)/man8 CLIENT_MANDIR = $(KRB5MANROOT)/man1 FILE_MANDIR = $(KRB5MANROOT)/man5 ADMIN_CATDIR = $(KRB5MANROOT)/cat8 SERVER_CATDIR = $(KRB5MANROOT)/cat8 CLIENT_CATDIR = $(KRB5MANROOT)/cat1 FILE_CATDIR = $(KRB5MANROOT)/cat5 OVERVIEW_MANDIR = $(KRB5MANROOT)/man7 OVERVIEW_CATDIR = $(KRB5MANROOT)/cat7 KRB5_LIBDIR = @libdir@ KRB5_INCDIR = @includedir@ MODULE_DIR = @libdir@/krb5/plugins KRB5_DB_MODULE_DIR = $(MODULE_DIR)/kdb KRB5_PA_MODULE_DIR = $(MODULE_DIR)/preauth KRB5_AD_MODULE_DIR = $(MODULE_DIR)/authdata KRB5_LIBKRB5_MODULE_DIR = $(MODULE_DIR)/libkrb5 KRB5_TLS_MODULE_DIR = $(MODULE_DIR)/tls KRB5_LOCALEDIR = @localedir@ GSS_MODULE_DIR = @libdir@/gss KRB5_INCSUBDIRS = \ $(KRB5_INCDIR)/kadm5 \ $(KRB5_INCDIR)/krb5 \ $(KRB5_INCDIR)/gssapi \ $(KRB5_INCDIR)/gssrpc SKIPTESTS = $(BUILDTOP)/skiptests RUNPYTEST = PYTHONPATH=$(top_srcdir)/util VALGRIND="$(VALGRIND)" \ $(PYTHON) transform = @program_transform_name@ RM = rm -f CP = cp MV = mv -f RANLIB = @RANLIB@ AWK = @AWK@ YACC = @YACC@ PERL = @PERL@ PYTHON = @PYTHON@ AUTOCONF = autoconf AUTOCONFFLAGS = AUTOHEADER = autoheader AUTOHEADERFLAGS = MOVEIFCHANGED = $(top_srcdir)/config/move-if-changed TOPLIBD = $(BUILDTOP)/lib OBJEXT = o EXEEXT = # # variables for libraries, for use in linking programs # -- this may want to get broken out into a separate frag later # # invocation is like: # prog: foo.o bar.o $(KRB5_BASE_DEPLIBS) # $(CC_LINK) -o $@ foo.o bar.o $(KRB5_BASE_LIBS) CC_LINK=@CC_LINK@ $(ASAN_FLAGS) CXX_LINK=@CXX_LINK@ $(ASAN_FLAGS) # Makefile.in files which build programs can override the list of # directories to look for dependent libraries in (in the form -Ldir1 # -Ldir2 ...) and also the list of rpath directories to search (in the # form dir1:dir2:...). PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) # Library Makefile.in files can override this list of directories to # look for dependent libraries in (in the form -Ldir1 -Ldir2 ...) and # also the list of rpath directories to search (in the form # dir1:dir2:...) SHLIB_DIRS=-L$(TOPLIBD) SHLIB_RDIRS=$(KRB5_LIBDIR) # Multi-directory library Makefile.in files should override this list # of object files with the full list. STOBJLISTS=OBJS.ST # prefix (with no spaces after) for rpath flag to cc RPATH_FLAG=@RPATH_FLAG@ # link flags to add PROG_RPATH to the rpath PROG_RPATH_FLAGS=@PROG_RPATH_FLAGS@ # this gets set by configure to either $(STLIBEXT) or $(SHLIBEXT), # depending on whether we're building with shared libraries. DEPLIBEXT=@DEPLIBEXT@ KDB5_PLUGIN_DEPLIBS = @KDB5_PLUGIN_DEPLIBS@ KDB5_PLUGIN_LIBS = @KDB5_PLUGIN_LIBS@ KADMCLNT_DEPLIB = $(TOPLIBD)/libkadm5clnt_mit$(DEPLIBEXT) KADMSRV_DEPLIB = $(TOPLIBD)/libkadm5srv_mit$(DEPLIBEXT) KDB5_DEPLIB = $(TOPLIBD)/libkdb5$(DEPLIBEXT) GSSRPC_DEPLIB = $(TOPLIBD)/libgssrpc$(DEPLIBEXT) GSS_DEPLIB = $(TOPLIBD)/libgssapi_krb5$(DEPLIBEXT) KRB5_DEPLIB = $(TOPLIBD)/libkrb5$(DEPLIBEXT) CRYPTO_DEPLIB = $(TOPLIBD)/libk5crypto$(DEPLIBEXT) COM_ERR_DEPLIB = $(COM_ERR_DEPLIB-@COM_ERR_VERSION@) COM_ERR_DEPLIB-sys = # empty COM_ERR_DEPLIB-intlsys = # empty COM_ERR_DEPLIB-k5 = $(TOPLIBD)/libcom_err$(DEPLIBEXT) COM_ERR_LIB = @COM_ERR_LIB@ SUPPORT_LIBNAME=krb5support SUPPORT_DEPLIB = $(TOPLIBD)/lib$(SUPPORT_LIBNAME)$(DEPLIBEXT) # These are forced to use ".a" as an extension because they're never # built shared. SS_DEPLIB = $(SS_DEPLIB-@SS_VERSION@) SS_DEPLIB-k5 = $(TOPLIBD)/libss.a SS_DEPLIB-sys = APPUTILS_DEPLIB = $(TOPLIBD)/libapputils.a KRB5_BASE_DEPLIBS = $(KRB5_DEPLIB) $(CRYPTO_DEPLIB) $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB) KDB5_DEPLIBS = $(KDB5_DEPLIB) $(KDB5_PLUGIN_DEPLIBS) GSS_DEPLIBS = $(GSS_DEPLIB) GSSRPC_DEPLIBS = $(GSSRPC_DEPLIB) $(GSS_DEPLIBS) KADM_COMM_DEPLIBS = $(GSSRPC_DEPLIBS) $(KDB5_DEPLIBS) $(GSSRPC_DEPLIBS) KADMSRV_DEPLIBS = $(KADMSRV_DEPLIB) $(KDB5_DEPLIBS) $(KADM_COMM_DEPLIBS) KADMCLNT_DEPLIBS = $(KADMCLNT_DEPLIB) $(KADM_COMM_DEPLIBS) # Header file dependencies we might override. # See util/depfix.sed. # Also see depend-verify-* in post.in, which wants to confirm that we're using # the in-tree versions. COM_ERR_VERSION = @COM_ERR_VERSION@ COM_ERR_DEPS = $(COM_ERR_DEPS-@COM_ERR_VERSION@) COM_ERR_DEPS-sys = COM_ERR_DEPS-intlsys = COM_ERR_DEPS-k5 = $(BUILDTOP)/include/com_err.h SS_VERSION = @SS_VERSION@ SS_DEPS = $(SS_DEPS-@SS_VERSION@) SS_DEPS-sys = SS_DEPS-k5 = $(BUILDTOP)/include/ss/ss.h $(BUILDTOP)/include/ss/ss_err.h VERTO_VERSION = @VERTO_VERSION@ VERTO_DEPS = $(VERTO_DEPS-@VERTO_VERSION@) VERTO_DEPS-sys = VERTO_DEPS-k5 = $(BUILDTOP)/include/verto.h # LIBS gets substituted in... e.g. -lnsl -lsocket # Editline or readline flags and libraries. RL_CFLAGS = @RL_CFLAGS@ RL_LIBS = @RL_LIBS@ SS_LIB = $(SS_LIB-@SS_VERSION@) SS_LIB-sys = @SS_LIB@ SS_LIB-k5 = $(TOPLIBD)/libss.a $(RL_LIBS) KDB5_LIB = -lkdb5 $(KDB5_PLUGIN_LIBS) VERTO_DEPLIB = $(VERTO_DEPLIB-@VERTO_VERSION@) VERTO_DEPLIB-sys = # empty VERTO_DEPLIB-k5 = $(TOPLIBD)/libverto$(DEPLIBEXT) VERTO_CFLAGS = @VERTO_CFLAGS@ VERTO_LIBS = @VERTO_LIBS@ DL_LIB = @DL_LIB@ CMOCKA_LIBS = @CMOCKA_LIBS@ LDAP_LIBS = @LDAP_LIBS@ LMDB_LIBS = @LMDB_LIBS@ KRB5_LIB = -lkrb5 K5CRYPTO_LIB = -lk5crypto GSS_KRB5_LIB = -lgssapi_krb5 SUPPORT_LIB = -l$(SUPPORT_LIBNAME) # HESIOD_LIBS is -lhesiod... HESIOD_LIBS = @HESIOD_LIBS@ KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(LIBS) $(DL_LIB) KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS) GSS_LIBS = $(GSS_KRB5_LIB) # needs fixing if ever used on macOS! GSSRPC_LIBS = -lgssrpc $(GSS_LIBS) KADM_COMM_LIBS = $(GSSRPC_LIBS) # need fixing if ever used on macOS! KADMSRV_LIBS = -lkadm5srv_mit $(HESIOD_LIBS) $(KDB5_LIBS) $(KADM_COMM_LIBS) KADMCLNT_LIBS = -lkadm5clnt_mit $(KADM_COMM_LIBS) # Misc stuff for linking server programs (and maybe some others, # eventually) but which we don't want to install. APPUTILS_LIB = -lapputils # So test programs can find their libraries without "make install", etc. RUN_SETUP=@KRB5_RUN_ENV@ RUN_VARS=@KRB5_RUN_VARS@ # Appropriate command prefix for most C test programs: use libraries # from the build tree, avoid referencing the installed krb5.conf and # message catalog, and use valgrind when asked. RUN_TEST=$(RUN_SETUP) KRB5_CONFIG=$(top_srcdir)/config-files/krb5.conf \ LC_ALL=C $(VALGRIND) # libk5crypto dependencies CRYPTO_IMPL_CFLAGS = @CRYPTO_IMPL_CFLAGS@ CRYPTO_IMPL_LIBS = @CRYPTO_IMPL_LIBS@ # TLS implementation selection TLS_IMPL = @TLS_IMPL@ TLS_IMPL_CFLAGS = @TLS_IMPL_CFLAGS@ TLS_IMPL_LIBS = @TLS_IMPL_LIBS@ # SPAKE preauth back-end libraries SPAKE_OPENSSL_LIBS = @SPAKE_OPENSSL_LIBS@ # Whether we have the SASL header file for the LDAP KDB module HAVE_SASL = @HAVE_SASL@ # Whether we are building support for NIST SPAKE groups using OpenSSL HAVE_SPAKE_OPENSSL = @HAVE_SPAKE_OPENSSL@ # Whether we are building the LMDB KDB module HAVE_LMDB = @HAVE_LMDB@ # Whether we have libresolv 1.1.5 for URI discovery tests HAVE_RESOLV_WRAPPER = @HAVE_RESOLV_WRAPPER@ SIZEOF_TIME_T = @SIZEOF_TIME_T@ # error table rules # ### /* these are invoked as $(...) foo.et, which works, but could be better */ COMPILE_ET= $(COMPILE_ET-@COM_ERR_VERSION@) COMPILE_ET-sys= compile_et COMPILE_ET-intlsys= compile_et --textdomain mit-krb5 COMPILE_ET-k5= $(BUILDTOP)/util/et/compile_et -d $(top_srcdir)/util/et \ --textdomain mit-krb5 .SUFFIXES: .h .c .et .ct # These versions cause both .c and .h files to be generated at once. # But GNU make doesn't understand this, and parallel builds can trigger # both of them at once, causing them to stomp on each other. The versions # below only update one of the files, so compile_et has to get run twice, # but it won't break parallel builds. #.et.h: ; $(COMPILE_ET) $< #.et.c: ; $(COMPILE_ET) $< .et.h: $(RM) et-h-$*.et et-h-$*.c et-h-$*.h $(CP) $< et-h-$*.et $(COMPILE_ET) et-h-$*.et $(MV) et-h-$*.h $*.h $(RM) et-h-$*.et et-h-$*.c .et.c: $(RM) et-c-$*.et et-c-$*.c et-c-$*.h $(CP) $< et-c-$*.et $(COMPILE_ET) et-c-$*.et $(MV) et-c-$*.c $*.c $(RM) et-c-$*.et et-c-$*.h # rule to make object files # .SUFFIXES: .cpp .c .o .c.o: $(CC) $(ALL_CFLAGS) -c $< # Use .cpp because that's what autoconf uses in its test. # If the compiler doesn't accept a .cpp suffix here, it wouldn't # have accepted it when autoconf tested it. .cpp.o: $(CXX) $(ALL_CXXFLAGS) -c $< # ss command table rules # MAKE_COMMANDS= $(MAKE_COMMANDS-@SS_VERSION@) MAKE_COMMANDS-sys= mk_cmds MAKE_COMMANDS-k5= $(BUILDTOP)/util/ss/mk_cmds .ct.c: $(MAKE_COMMANDS) $< ## Parameters to be set by configure for use in lib.in: ## # # These settings are for building shared libraries only. Including # libpriv.in will override with values appropriate for static # libraries that we don't install. Some values will depend on whether # the platform supports major and minor version number extensions on # shared libraries, hence the FOO_@@ settings. LN_S=@LN_S@ AR=@AR@ # Set to "lib$(LIBBASE)$(STLIBEXT) lib$(LIBBASE)$(SHLIBEXT)" or some # subset thereof by configure; determines which types of libs get # built. LIBLIST=@LIBLIST@ # Set by configure; list of library symlinks to make to $(TOPLIBD) LIBLINKS=@LIBLINKS@ # Set by configure; name of plugin module to build (libfoo.a or foo.so) PLUGIN=@PLUGIN@ # Set by configure; symlink for plugin module for static plugin linking PLUGINLINK=@PLUGINLINK@ # Set by configure; list of install targets for libraries LIBINSTLIST=@LIBINSTLIST@ # Set by configure; install target PLUGININST=@PLUGININST@ # Some of these should really move to pre.in, since programs will need # it too. (e.g. stuff that has dependencies on the libraries) # usually .a STLIBEXT=@STLIBEXT@ # usually .so.$(LIBMAJOR).$(LIBMINOR) SHLIBVEXT=@SHLIBVEXT@ # usually .so.$(LIBMAJOR) (to allow for major-version compat) SHLIBSEXT=@SHLIBSEXT@ # usually .so SHLIBEXT=@SHLIBEXT@ # usually _p.a PFLIBEXT=@PFLIBEXT@ # DYNOBJEXT=@DYNOBJEXT@ MAKE_DYNOBJ_COMMAND=@MAKE_DYNOBJ_COMMAND@ DYNOBJ_EXPDEPS=@DYNOBJ_EXPDEPS@ DYNOBJ_EXPFLAGS=@DYNOBJ_EXPFLAGS@ # For some platforms, a flag which causes shared library creation to # check for undefined symbols. Suppressed when using --enable-asan. UNDEF_CHECK=@UNDEF_CHECK@ # File with symbol names to be exported, both functions and data, # currently not distinguished. SHLIB_EXPORT_FILE=$(srcdir)/$(LIBPREFIX)$(LIBBASE).exports # File that needs to be current for building the shared library, # usually SHLIB_EXPORT_FILE, but not always, if we have to convert # it to another, intermediate form for the linker. SHLIB_EXPORT_FILE_DEP=@SHLIB_EXPORT_FILE_DEP@ # Export file checker to run when building in maintainer mode on # Linux. This gets included in LDCOMBINE_TAIL. EXPORT_CHECK_CMD = && $(PERL) -w $(top_srcdir)/util/export-check.pl \ $(SHLIB_EXPORT_FILE) $@ EXPORT_CHECK = @MAINT@ $(EXPORT_CHECK_CMD) # Command to run to build a shared library. # In systems that require multiple commands, like AIX, it may need # to change to rearrange where the various parameters fit in. MAKE_SHLIB_COMMAND=@MAKE_SHLIB_COMMAND@ # run path flags for explicit libraries depending on this one, # e.g. "-R$(SHLIB_RPATH)" SHLIB_RPATH_FLAGS=@SHLIB_RPATH_FLAGS@ # flags for explicit libraries depending on this one, # e.g. "$(SHLIB_RPATH_FLAGS) $(SHLIB_SHLIB_DIRFLAGS) $(SHLIB_EXPLIBS)" SHLIB_EXPFLAGS=@SHLIB_EXPFLAGS@ ## Parameters to be set by configure for use in libobj.in: # Set to "OBJS.ST OBJS.SH OBJS.PF" or some subset thereof by # configure; determines which types of object files get built. OBJLISTS=@OBJLISTS@ # Note that $(LIBSRCS) *cannot* contain any variable references, or # the suffix substitution will break on some platforms! SHLIBOBJS=$(STLIBOBJS:.o=@SHOBJEXT@) PFLIBOBJS=$(STLIBOBJS:.o=@PFOBJEXT@) # # rules to make various types of object files # PICFLAGS=@PICFLAGS@ PROFFLAGS=@PROFFLAGS@ # platform-dependent temporary files that should get cleaned up EXTRA_FILES=@EXTRA_FILES@ VALGRIND= # Need absolute paths here because under kshd or ftpd we may run programs # while in other directories. VALGRIND_LOGDIR = `cd $(BUILDTOP)&&pwd` VALGRIND1 = valgrind --tool=memcheck --log-file=$(VALGRIND_LOGDIR)/vg.%p --trace-children=yes --leak-check=yes --suppressions=`cd $(top_srcdir)&&pwd`/util/valgrind-suppressions # Set OFFLINE=yes to disable tests that assume network connectivity. # (Specifically, this concerns the ability to fetch DNS data for # mit.edu, to verify that SRV queries are working.) Note that other # tests still assume that the local hostname can be resolved into # something that looks like an FQDN, with an IPv4 address. OFFLINE=no # Used when running Python tests. PYTESTFLAGS= ## ## end of pre.in ############################################################ krb5-1.22.1/src/config/config.sub0000775000175000017500000011544115051422640016366 0ustar ghudsonghudson#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale timestamp='2024-05-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in cloudabi*-eabi* \ | kfreebsd*-gnu* \ | knetbsd*-gnu* \ | kopensolaris*-gnu* \ | linux-* \ | managarm-* \ | netbsd*-eabi* \ | netbsd*-gnu* \ | nto-qnx* \ | os2-emx* \ | rtmk-nova* \ | storm-chaos* \ | uclinux-gnu* \ | uclinux-uclibc* \ | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) case $field1-$field2 in # Shorthands that happen to contain a single dash convex-c[12] | convex-c3[248]) basic_machine=$field2-convex basic_os= ;; decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Do not treat sunos as a manufacturer sun*os*) basic_machine=$field1 basic_os=$field2 ;; # Manufacturers 3100* \ | 32* \ | 3300* \ | 3600* \ | 7300* \ | acorn \ | altos* \ | apollo \ | apple \ | atari \ | att* \ | axis \ | be \ | bull \ | cbm \ | ccur \ | cisco \ | commodore \ | convergent* \ | convex* \ | cray \ | crds \ | dec* \ | delta* \ | dg \ | digital \ | dolphin \ | encore* \ | gould \ | harris \ | highlevel \ | hitachi* \ | hp \ | ibm* \ | intergraph \ | isi* \ | knuth \ | masscomp \ | microblaze* \ | mips* \ | motorola* \ | ncr* \ | news \ | next \ | ns \ | oki \ | omron* \ | pc533* \ | rebel \ | rom68k \ | rombug \ | semi \ | sequent* \ | siemens \ | sgi* \ | siemens \ | sim \ | sni \ | sony* \ | stratus \ | sun \ | sun[234]* \ | tektronix \ | tti* \ | ultra \ | unicom* \ | wec \ | winbond \ | wrs) basic_machine=$field1-$field2 basic_os= ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300) cpu=m68k vendor=motorola ;; # This used to be dpx2*, but that gets the RS6000-based # DPX/20 and the x86-based DPX/2-100 wrong. See # https://oldskool.silicium.org/stations/bull_dpx20.htm # https://www.feb-patrimoine.com/english/bull_dpx2.htm # https://www.feb-patrimoine.com/english/unix_and_bull.htm dpx2 | dpx2[23]00 | dpx2[23]xx) cpu=m68k vendor=bull ;; dpx2100 | dpx21xx) cpu=i386 vendor=bull ;; dpx20) cpu=rs6000 vendor=bull ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. obj= case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) saved_IFS=$IFS IFS="-" read kernel os <&2 fi ;; *) echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 exit 1 ;; esac case $obj in aout* | coff* | elf* | pe*) ;; '') # empty is fine ;; *) echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 exit 1 ;; esac # Here we handle the constraint that a (synthetic) cpu and os are # valid only in combination with each other and nowhere else. case $cpu-$os in # The "javascript-unknown-ghcjs" triple is used by GHC; we # accept it here in order to tolerate that, but reject any # variations. javascript-ghcjs) ;; javascript-* | *-ghcjs) echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os-$obj in linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ | linux-mlibc*- | linux-musl*- | linux-newlib*- \ | linux-relibc*- | linux-uclibc*- | linux-ohos*- ) ;; uclinux-uclibc*- | uclinux-gnu*- ) ;; managarm-mlibc*- | managarm-kernel*- ) ;; windows*-msvc*-) ;; -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; -kernel*- ) echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 exit 1 ;; *-kernel*- ) echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 exit 1 ;; *-msvc*- ) echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 exit 1 ;; kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) ;; vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) ;; nto-qnx*-) ;; os2-emx-) ;; rtmk-nova-) ;; *-eabi*- | *-gnueabi*-) ;; none--*) # None (no kernel, i.e. freestanding / bare metal), # can be paired with an machine code file format ;; -*-) # Blank kernel with real OS is always fine. ;; --*) # Blank kernel and OS with real machine code file format is always fine. ;; *-*-*) echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos* | *-solaris*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: krb5-1.22.1/src/config/libnover.in0000664000175000017500000001041115051422640016542 0ustar ghudsonghudson### config/libnover.in # *** keep this in sync with lib.in # # Makefile fragment that creates shared libraries sans version # info (plugin modules). # # The following variables must be set in the Makefile.in: # # LIBBASE library name without "lib" or extension # SHLIB_EXPDEPS list of libraries that this one has explicit # dependencies on, pref. in the form libfoo$(SHLIBEXT) # SHLIB_EXPLIBS list of libraries that this one has explicit # dependencies on, in "-lfoo" form. # RELDIR path to this directory relative to $(TOPLIBD) # # Makefile.in can also override the defaults for SHLIB_DIRS, # SHLIB_RDIRS, and STOBJLISTS from pre.in. LIBPREFIX= SHOBJLISTS=$(STOBJLISTS:.ST=.SH) PFOBJLISTS=$(STOBJLISTS:.ST=.PF) dummy-target-1 $(SUBDIROBJLISTS) $(SUBDIROBJLISTS:.ST=.SH) $(SUBDIROBJLISTS:.ST=.PF): all-recurse # Gets invoked as $(PARSE_OBJLISTS) list-of-OBJS.*-files PARSE_OBJLISTS= set -x && $(PERL) -p -e 'BEGIN { $$SIG{__WARN__} = sub {die @_} }; $$e=$$ARGV; $$e =~ s/OBJS\...$$//; s/^/ /; s/ $$//; s/ / $$e/g;' LIBINSTLIST=install-shared libkrb5_$(LIBBASE)$(STLIBEXT): $(STOBJLISTS) $(RM) $@ @echo "building static $(LIBBASE) library" set -x; objlist=`$(PARSE_OBJLISTS) $(STOBJLISTS)` && $(AR) cq $@ $$objlist $(RANLIB) $@ $(LIBBASE)$(DYNOBJEXT): $(SHOBJLISTS) $(DYNOBJ_EXPDEPS) $(SHLIB_EXPORT_FILE_DEP) $(RM) $@ @echo "building dynamic $(LIBBASE) object" set -x; objlist=`$(PARSE_OBJLISTS) $(SHOBJLISTS)` && $(MAKE_DYNOBJ_COMMAND) binutils.versions: $(SHLIB_EXPORT_FILE) Makefile echo > binutils.versions "HIDDEN { local: __*; _rest*; _save*; *; };" echo >> binutils.versions "$(LIBBASE)_$(LIBMAJOR)_MIT {" sed >> binutils.versions < $(SHLIB_EXPORT_FILE) "s/$$/;/" echo >> binutils.versions "};" osf1.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) osf1.tmp osf1.exports sed "s/^/-exported_symbol /" < $(SHLIB_EXPORT_FILE) > osf1.tmp for f in . $(LIBINITFUNC); do \ if test "$$f" != "." ; then \ echo " -init $$f"__auxinit >> osf1.tmp; \ else :; fi; \ done a=""; \ for f in . $(LIBFINIFUNC); do \ if test "$$f" != "." ; then \ a="-fini $$f $$a"; \ else :; fi; \ done; echo " $$a" >> osf1.tmp; \ mv -f osf1.tmp osf1.exports hpux.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) hpux.tmp hpux.exports sed "s/^/+e /" < $(SHLIB_EXPORT_FILE) > hpux.tmp a=""; \ for f in . $(LIBFINIFUNC); do \ if test "$$f" != .; then \ a="+I $${f}__auxfini $$a"; \ else :; fi; \ done; echo "$$a" >> hpux.tmp echo "+e errno" >> hpux.tmp mv -f hpux.tmp hpux.exports darwin.exports: $(SHLIB_EXPORT_FILE) Makefile $(RM) darwin.exports sed "s/^/_/" < $(SHLIB_EXPORT_FILE) > darwin.exports libkrb5_$(LIBBASE)$(PFLIBEXT): $(PFOBJLISTS) $(RM) $@ @echo "building profiled $(LIBBASE) library" set -x; objlist=`$(PARSE_OBJLISTS) $(PFOBJLISTS)` && $(AR) cq $@ $$objlist $(RANLIB) $@ # For static builds, we make a symlink in the main library directory, # allowing the plugin library to be a dependency of the core libraries # which use it. $(TOPLIBD)/libkrb5_$(LIBBASE)$(STLIBEXT): $(RM) $@ (cd $(TOPLIBD) && $(LN_S) $(RELDIR)/libkrb5_$(LIBBASE)$(STLIBEXT) .) # For shared builds, we make a symlink in the parent directory, allowing # tests to point plugin_base_dir at $(BUILDTOP)/plugins. ../$(LIBBASE)$(DYNOBJEXT): $(RM) $@ (cd .. && $(LN_S) `basename $(mydir)`/$(LIBBASE)$(DYNOBJEXT) .) all-liblinks: all-libs $(PLUGINLINK) all-libs: $(PLUGIN) clean-libs: $(RM) $(LIBBASE)$(DYNOBJEXT) $(RM) binutils.versions osf1.exports darwin.exports hpux.exports clean-liblinks: $(RM) $(PLUGINLINK) install-libs: $(PLUGININST) install-static: $(RM) $(DESTDIR)$(KRB5_LIBDIR)/libkrb5_$(LIBBASE)$(STLIBEXT) $(INSTALL_DATA) libkrb5_$(LIBBASE)$(STLIBEXT) $(DESTDIR)$(KRB5_LIBDIR) $(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/libkrb5_$(LIBBASE)$(STLIBEXT) install-plugin: $(RM) $(DESTDIR)$(MODULE_INSTALL_DIR)/$(LIBBASE)$(DYNOBJEXT) $(INSTALL_SHLIB) $(LIBBASE)$(DYNOBJEXT) $(DESTDIR)$(MODULE_INSTALL_DIR) Makefile: $(top_srcdir)/config/libnover.in $(BUILDTOP)/config.status: $(top_srcdir)/config/shlib.conf # Use the following if links need to be made to $(TOPLIBD): # all-unix: all-liblinks # install-unix: install-libs # clean-unix:: clean-liblinks clean-libs # Use the following if links need not be made: # all-unix: all-libs # install-unix: install-libs # clean-unix:: clean-libs ### ### end config/libnovers.in krb5-1.22.1/src/config/install-sh0000775000175000017500000002017415051422640016405 0ustar ghudsonghudson#!/bin/sh # install - install a program, script, or datafile scriptversion=2003-09-24.23 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename= transform_arg= instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd= chgrpcmd= stripcmd= rmcmd="$rmprog -f" mvcmd="$mvprog" src= dst= dir_arg= usage="Usage: $0 [OPTION]... SRCFILE DSTFILE or: $0 -d DIR1 DIR2... In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default. In the second, create the directory path DIR. Options: -b=TRANSFORMBASENAME -c copy source (using $cpprog) instead of moving (using $mvprog). -d create directories instead of installing files. -g GROUP $chgrp installed files to GROUP. -m MODE $chmod installed files to MODE. -o USER $chown installed files to USER. -s strip installed files (using $stripprog). -t=TRANSFORM --help display this help and exit. --version display version info and exit. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test -n "$1"; do case $1 in -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; -c) instcmd=$cpprog shift continue;; -d) dir_arg=true shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; --help) echo "$usage"; exit 0;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -s) stripcmd=$stripprog shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; --version) echo "$0 $scriptversion"; exit 0;; *) if test -z "$src"; then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if test -z "$src"; then echo "$0: no input file specified." >&2 exit 1 fi # Protect names starting with `-'. case $src in -*) src=./$src ;; esac if test -n "$dir_arg"; then dst=$src src= if test -d "$dst"; then instcmd=: chmodcmd= else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst"; then echo "$0: no destination specified." >&2 exit 1 fi # Protect names starting with `-'. case $dst in -*) dst=./$dst ;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then dst=$dst/`basename "$src"` fi fi # This sed command emulates the dirname command. dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # Skip lots of stat calls in the usual case. if test ! -d "$dstdir"; then defaultIFS=' ' IFS="${IFS-$defaultIFS}" oIFS=$IFS # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` IFS=$oIFS pathcomp= while test $# -ne 0 ; do pathcomp=$pathcomp$1 shift test -d "$pathcomp" || $mkdirprog "$pathcomp" pathcomp=$pathcomp/ done fi if test -n "$dir_arg"; then $doit $instcmd "$dst" \ && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } else # If we're going to rename the final executable, determine the name now. if test -z "$transformarg"; then dstfile=`basename "$dst"` else dstfile=`basename "$dst" $transformbasename \ | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename. test -z "$dstfile" && dstfile=`basename "$dst"` # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 trap '(exit $?); exit' 1 2 13 15 # Move or copy the file name to the temp name $doit $instcmd "$src" "$dsttmp" && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && # Now remove or move aside any old file at destination location. We # try this two ways since rm can't unlink itself on some systems and # the destination file might be busy for other reasons. In this case, # the final cleanup might fail but the new file should still install # successfully. { if test -f "$dstdir/$dstfile"; then $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ || { echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 (exit 1); exit } else : fi } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" fi && # The final little trick to "correctly" pass the exit status to the exit trap. { (exit 0); exit } # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: krb5-1.22.1/src/config/win-pre.in0000664000175000017500000001354715051422640016320 0ustar ghudsonghudsonWHAT=windows all: setup-msg outpre-dir all: all-$(WHAT) clean: clean-$(WHAT) install: install-$(WHAT) check: check-$(WHAT) all-windows: clean-windows:: install-windows: check-windows: all-windows: Makefile clean-windows:: Makefile # # Figure out the CPU # !if !defined(CPU) || "$(CPU)" == "" CPU=$(PROCESSOR_ARCHITECTURE) !endif # CPU !if "$(CPU)" == "" CPU=i386 !endif # Change x86 or X86 to i386 !if ( "$(CPU)" == "X86" ) || ( "$(CPU)" == "x86" ) CPU=i386 !endif # CPU == X86 !if ( "$(CPU)" != "i386" ) && ( "$(CPU)" != "ALPHA" ) && ( "$(CPU)" != "ALPHA64" ) && ( "$(CPU)" != "IA64" ) && ( "$(CPU)" != "AMD64" ) && ( "$(CPU)" != "ARM64" ) !error Must specify CPU environment variable ( CPU=i386, CPU=ALPHA, CPU=ALPHA64,CPU=IA64, CPU=AMD64) !endif !if ("$(CPU)" == "IA64" ) || ("$(CPU)" == "AMD64" ) || ("$(CPU)" == "ALPHA64" ) || ("$(CPU)" == "ARM64" ) BITS=64 !else BITS=32 !endif # # End of figuring out CPU # !if "$(OS)" == "Windows_NT" DIRNUL= !else DIRNUL=\nul !endif # NOTE: ^ is an escape char for NMAKE. !ifdef NODEBUG OUTPRE_DBG=rel !else OUTPRE_DBG=dbg !endif OUTPRE1=obj OUTPRE2=$(OUTPRE1)\$(CPU) OUTPRE3=$(OUTPRE2)\$(OUTPRE_DBG) OUTPRE=$(OUTPRE3)^\ $(OUTPRE3)$(DIRNUL): -@if not exist $(OUTPRE1)$(DIRNUL) mkdir $(OUTPRE1) -@if not exist $(OUTPRE2)$(DIRNUL) mkdir $(OUTPRE2) -@if not exist $(OUTPRE3)$(DIRNUL) mkdir $(OUTPRE3) @if exist $(OUTPRE3)$(DIRNUL) echo Output going into $(OUTPRE3) @if not exist $(OUTPRE1)$(DIRNUL) echo The directory $(OUTPRE1) could not be created. @if exist $(OUTPRE1)$(DIRNUL) if not exist $(OUTPRE2)$(DIRNUL) echo The directory $(OUTPRE2) could not be created. @if exist $(OUTPRE2)$(DIRNUL) if not exist $(OUTPRE3)$(DIRNUL) echo The directory $(OUTPRE3) could not be created. clean-windows-dir: -@if exist $(OUTPRE3)$(DIRNUL) rmdir $(OUTPRE3) -@if exist $(OUTPRE2)$(DIRNUL) rmdir $(OUTPRE2) -@if exist $(OUTPRE1)$(DIRNUL) rmdir $(OUTPRE1) @if exist $(OUTPRE2)$(DIRNUL) echo The directory $(OUTPRE2) is not empty. @if not exist $(OUTPRE2)$(DIRNUL) if exist $(OUTPRE1)$(DIRNUL) echo The directory $(OUTPRE1) is not empty. # Directory syntax: # # begin absolute path ABS=^\ # begin relative path REL= # up-directory U=.. # path separator S=^\ # this is magic... should only be used for preceding a program invocation C=.^\ srcdir = . top_srcdir = $(srcdir)\$(BUILDTOP) DNSLIBS=dnsapi.lib DNSFLAGS=-DKRB5_DNS_LOOKUP=1 !if defined(KRB5_USE_DNS_REALMS) DNSFLAGS=$(DNSFLAGS) -DKRB5_DNS_LOOKUP_REALM=1 !endif !if ("$(CPU)" == "i386") TIME_T_FLAGS=-D_USE_32BIT_TIME_T !endif !if defined (NODEBUG) KFWFLAGS=-DUSE_LEASH=1 !else KFWFLAGS=-DUSE_LEASH=1 -DDEBUG -D_CRTDBG_MAP_ALLOC !endif # # The name of the C compiler for the target # CC=cl PDB_OPTS=-Fd$(OUTPRE)\ -FD CPPFLAGS=-I$(top_srcdir)\include -I$(top_srcdir)\include\krb5 $(DNSFLAGS) -DWIN32_LEAN_AND_MEAN -DKRB5_DEPRECATED=1 -DKRB5_PRIVATE -D_CRT_SECURE_NO_DEPRECATE $(KFWFLAGS) $(TIME_T_FLAGS) $(OSSLINCLUDE) # Treat the following warnings as errors: # 4020: too many actual parameters # 4024: different types for formal and actual parameter # 4047: different levels of indirection CCOPTS=-nologo /EHsc /W3 /we4020 /we4024 /we4047 $(PDB_OPTS) $(DLL_FILE_DEF) LOPTS=-nologo -incremental:no -manifest CCLINKOPTION= DEBUGOPT=/guard:cf /Zi #if the compiler is vstudio 8, generate manifest !if exists("$(VCINSTALLDIR)\..\..\MICROSOFT VISUAL STUDIO 8") CCLINKOPTION = $(CCLINKOPTION) /MANIFEST _VC_MANIFEST_EMBED_EXE = if exist $*.exe.manifest mt.exe -manifest $*.exe.manifest -outputresource:$*.exe;1 _VC_MANIFEST_EMBED_DLL = if exist $*.dll.manifest mt.exe -manifest $*.dll.manifest -outputresource:$*.dll;2 !endif # /ZI gives better debug info in each object file (MSVC 6.0 or higher). # /Zi gives debug info in each object file. # /Gs Avoid stack probes (they don't seem to work anyway) # /Os optimize for space. FIXME: Do not use /Ox; it miscompiles the DES lib! # /Od disable optimization (for debugging) # /MD (Win32) thread safe, ML would be single threaded, don't build with ML # # CCOPTS was for DLL compiles # CCOPTS2 was for non-DLL compiles (EXEs, for example) # !ifdef NODEBUG !ifdef DEBUG_SYMBOL CCOPTS=$(DEBUGOPT) $(CCOPTS) LOPTS=$(LOPTS) -debug !endif CCOPTS=/Os /MD $(CCOPTS) LOPTS=$(LOPTS) !ifdef DEBUG_SYMBOL INSTALLDBGSYMS=copy !else INSTALLDBGSYMS=rem !endif !else CCOPTS=/Od $(DEBUGOPT) /MDd $(CCOPTS) LOPTS=$(LOPTS) -debug INSTALLDBGSYMS=copy !endif DLL_LINKOPTS=$(LOPTS) -dll EXE_LINKOPTS=$(LOPTS) RM=$(BUILDTOP)\config\rm.bat LIBECHO=$(BUILDTOP)\util\windows\$(OUTPRE)libecho CP=copy/b nul:+ MV=ren LN=copy LIBCMD=lib AWK=rem RC = rc CVTRES = cvtres PERL=perl WCONFIG_EXE=$(BUILDTOP)\$(OUTPRE)wconfig.exe WCONFIG=$(WCONFIG_EXE:.exe=) $(WCONFIG_FLAGS) CLIB=$(BUILDTOP)\lib\$(OUTPRE)comerr$(BITS).lib PLIB=$(BUILDTOP)\lib\$(OUTPRE)xpprof$(BITS).lib KLIB=$(BUILDTOP)\lib\$(OUTPRE)krb5_$(BITS).lib SLIB=$(BUILDTOP)\lib\$(OUTPRE)k5sprt$(BITS).lib GLIB=$(BUILDTOP)\lib\$(OUTPRE)gssapi$(BITS).lib CCLIB=krbcc$(BITS) SPAKELIB=spake$(BITS) !ifdef OPENSSL_DIR OSSLLIB="$(OPENSSL_DIR)\lib\libcrypto.lib" OSSLINC="-I$(OPENSSL_DIR)\include" PKINITLIB=pkinit$(BITS) !else OSSLLIB= OSSLINC= PKINITLIB= !endif KRB4_INCLUDES=-I$(BUILDTOP)/include/kerberosIV COM_ERR_DEPS = $(BUILDTOP)/include/com_err.h RANLIB=rem OBJEXT=obj EXEEXT=.exe MFLAGS=$(MAKEFLAGS) !ifdef MIGNORE MAKE=-$(MAKE) !endif CFLAGS = $(CCOPTS) ALL_CFLAGS = $(DEFS) $(DEFINES) $(LOCALINCLUDES) $(CPPFLAGS) $(CFLAGS) C_RULE_STUFF=$(CC) $(ALL_CFLAGS) -Fo$(OUTPRE)\ -c C_RULE_PRINT=$(C_RULE_STUFF) C_RULE=$(C_RULE_STUFF) $< {}.rc{$(OUTPRE)}.res: $(RC) $(RCFLAGS) -fo $@ -r $< {}.c{$(OUTPRE)}.obj: @if "%DO_C_RULE_PRINT%"=="1" echo %C_RULE_PRINT% ... @set DO_C_RULE_PRINT= @$(C_RULE) {}.cxx{$(OUTPRE)}.obj: @if "%DO_C_RULE_PRINT%"=="1" echo %C_RULE_PRINT% ... @set DO_C_RULE_PRINT= @$(C_RULE) {}.cpp{$(OUTPRE)}.obj: @if "%DO_C_RULE_PRINT%"=="1" echo %C_RULE_PRINT% ... @set DO_C_RULE_PRINT= @$(C_RULE) # # End of Win32 pre-config lines (config/win-pre.in) # krb5-1.22.1/src/config/win-post.in0000664000175000017500000000600415051422640016505 0ustar ghudsonghudson# # Start of Win32 post-config lines (config/win-post.in) # setup-msg: @set C_RULE_PRINT= $(C_RULE_PRINT) @set DO_C_RULE_PRINT=1 !if defined(NO_OUTPRE) || defined(NO_OUTDIR) outpre-dir: !else outpre-dir: $(OUTPRE3)$(DIRNUL) !endif # # put all: first just in case no other rules occur here # all: # # Set the #define to indicate that we are compiling a DLL. We default to # compiling the Kerberos library # !if defined(DLL_EXP_TYPE) DLL_FILE_DEF=/D$(DLL_EXP_TYPE)_DLL_FILE !else DLL_FILE_DEF=/DKRB5_DLL_FILE !endif # Build the Makefile unless we are in the top-level #(where there is already an explicit rule). !if !defined(TOPLEVEL) Makefile: Makefile.in $(BUILDTOP)\config\win-pre.in $(BUILDTOP)\config\win-post.in $(WCONFIG) $(BUILDTOP)\config < Makefile.in > Makefile !endif # Recurse into subdirs if WINSUBDIRS or SUBDIRS is defined. Makefiles # can depend on all-recurse, clean-recurse, or check-recurse to perform # actions after recursion. !if defined(SUBDIRS) && !defined(WINSUBDIRS) WINSUBDIRS=$(SUBDIRS) !endif !ifdef WINSUBDIRS all-recurse: @for %d in ($(WINSUBDIRS)) do @(echo Making in $(mydir)\%d && \ pushd %d && $(MAKE) -$(MFLAGS) && popd) || exit 1 @echo Making in $(mydir) all-windows: all-recurse clean-recurse: @for %d in ($(WINSUBDIRS)) do @(echo Making clean in $(mydir)\%d && \ pushd %d && $(MAKE) -$(MFLAGS) clean && popd) || exit 1 @echo Making clean in $(mydir) clean-windows:: clean-recurse check-recurse: @for %d in ($(WINSUBDIRS)) do @(echo Making check in $(mydir)\%d && \ pushd %d && $(MAKE) -$(MFLAGS) check && popd) || exit 1 @echo Making check in $(mydir) check-windows: check-recurse !endif # WINSUBDIRS # Use 64-bit LIBNAME and OBJFILE on 64-bit platforms, if defined. !if ("$(CPU)" == "IA64") || ("$(CPU)" == "AMD64") || ("$(CPU)" == "ALPHA64") || ("$(CPU)" == "ARM64") !if defined(WIN64LIBNAME) LIBNAME=$(WIN64LIBNAME) !endif !if defined(WIN64OBJFILE) OBJFILE=$(WIN64OBJFILE) !endif !endif # Build a library if LIBNAME is defined. !if defined(LIBNAME) !if !defined(OBJFILELIST) OBJFILELIST=@$(OBJFILE) !endif !if !defined(OBJFILEDEP) OBJFILEDEP=$(OBJFILE) !endif all-windows: $(LIBNAME) $(LIBNAME): $(OBJFILEDEP) $(LIBCMD) /out:$(LIBNAME) /nologo $(OBJFILELIST) !endif # LIBNAME # Build an object file list if OBJFILE is defined. !if defined(OBJFILE) all-windows: $(OBJFILE) !if defined(LIBOBJS) $(OBJFILE): $(LIBOBJS) if exist $(OBJFILE) del $(OBJFILE) !if defined(PREFIXDIR) $(LIBECHO) -p $(PREFIXDIR)\ $** > $(OBJFILE) !else $(LIBECHO) $** > $(OBJFILE) !endif # !PREFIXDIR !endif # LIBOBJS !endif # OBJFILE check: check-windows: clean-windows:: clean-windows-files clean-windows-dir # This needs to be in the post because we need RM to be defined in terms # of BUILDTOP clean-windows-files: !if "$(OUTPRE3)" == "" !error ASSERTION FAILURE: OUTPRE3 must be defined!!! !endif !if "$(OS)" == "Windows_NT" @if exist $(OUTPRE3)$(DIRNUL) rd /s/q $(OUTPRE3) !else @if exist $(OUTPRE3)$(DIRNUL) deltree /y $(OUTPRE3) !endif # Dependencies !if exist($(srcdir)/deps) !include $(srcdir)/deps !endif krb5-1.22.1/src/config/move-if-changed0000775000175000017500000000057015051422640017256 0ustar ghudsonghudson#!/bin/sh # Move file 1 to file 2 if they don't already match. # Good for "make depend" for example, where it'd be nice to keep the # old datestamp. if [ $# != 2 ]; then echo 2>&1 usage: $0 newfile oldfilename exit 1 fi # if [ ! -r "$2" ]; then exec mv -f "$1" "$2" fi if cmp "$1" "$2" >/dev/null; then echo "$2 is unchanged" exec rm -f "$1" fi exec mv -f "$1" "$2" krb5-1.22.1/src/config/pkg.m40000664000175000017500000002403215051422640015421 0ustar ghudsonghudson# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR krb5-1.22.1/src/config/libobj.in0000664000175000017500000000166515051422640016176 0ustar ghudsonghudson### config/libobj.in # # Makefile fragment that builds object files for libraries. # # The following variables must be set in Makefile.in: # # STLIBOBJS list of .o objects; this must not contain variable # references. .SUFFIXES: .c .so .po .c.so: $(CC) $(PICFLAGS) -DSHARED $(ALL_CFLAGS) -c $< -o $*.so.o && $(MV) $*.so.o $*.so .c.po: $(CC) $(PROFFLAGS) $(ALL_CFLAGS) -c $< -o $*.po.o && $(MV) $*.po.o $*.po # rules to generate object file lists OBJS.ST: $(STLIBOBJS) Makefile @echo $(STLIBOBJS) > $@ : updated $@ OBJS.SH: $(SHLIBOBJS) Makefile @echo $(SHLIBOBJS) > $@ : updated $@ OBJS.PF: $(PFLIBOBJS) Makefile @echo $(PFLIBOBJS) > $@ : updated $@ all-libobjs: $(OBJLISTS) clean-libobjs: $(RM) OBJS.ST OBJS.SH OBJS.PF $(STLIBOBJS) $(SHLIBOBJS) $(PFLIBOBJS) Makefile: $(top_srcdir)/config/libobj.in config.status: $(top_srcdir)/config/shlib.conf # clean-unix:: clean-libobjs # all-unix: all-libobjs ### ### end config/libobj.in krb5-1.22.1/src/prototype/0000775000175000017500000000000015051422640015175 5ustar ghudsonghudsonkrb5-1.22.1/src/prototype/prototype.c0000664000175000017500000000306615051422640017413 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* prototype/prototype.c - <<< One-line description of file >>> */ /* * Copyright (C) 2025 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * <<< Longer description of file >>> */ krb5-1.22.1/src/prototype/prototype.h0000664000175000017500000000324215051422640017414 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* prototype/prototype.h - <<< One-line description of file >>> */ /* * Copyright (C) 2025 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * <<< Longer description of file >>> */ #ifndef <<< include blocker>>>__ #define <<< include blocker>>>__ #endif /* __<<< include blocker>>>__ */ krb5-1.22.1/src/Makefile.in0000664000175000017500000006416215051422640015206 0ustar ghudsonghudsondatadir=@datadir@ mydir=. # Don't build sample by default, and definitely don't install them # for production use: # plugins/locate/python # plugins/preauth/wpse # plugins/preauth/cksum_body SUBDIRS=util include lib \ @sam2_plugin@ \ plugins/audit \ plugins/audit/test \ @audit_plugin@ \ plugins/kadm5_hook/test \ plugins/kadm5_auth/test \ plugins/gssapi/negoextest \ plugins/hostrealm/test \ plugins/localauth/test \ plugins/pwqual/test \ plugins/authdata/greet_server \ plugins/authdata/greet_client \ plugins/certauth/test \ plugins/kdb/db2 \ @ldap_plugin_dir@ \ @lmdb_plugin_dir@ \ plugins/kdb/test \ plugins/kdcpolicy/test \ plugins/preauth/otp \ plugins/preauth/pkinit \ plugins/preauth/spake \ plugins/preauth/test \ plugins/tls/k5tls \ kdc kadmin kprop clients appl tests \ config-files build-tools man doc @po@ WINSUBDIRS=include util lib ccapi windows clients appl plugins\preauth\spake \ $(PKINIT_SUBDIR) BUILDTOP=$(REL). SRCS = HDRS = # Why aren't these flags showing up in Windows builds? ##DOS##CPPFLAGS=$(CPPFLAGS) -D_X86_=1 -DWIN32 -D_WIN32 -W3 -D_WINNT # Lots of things will start to depend on the thread support, which # needs autoconf.h, but building "all" in include requires that util/et # have been built first. Until we can untangle this, let's just check # that autoconf.h is up to date before going into any of the subdirectories. all-prerecurse generate-files-mac-prerecurse: update-autoconf-h update-autoconf-h: (cd include && $(MAKE) autoconf.h osconf.h) ##DOS##!if 0 # This makefile doesn't use lib.in, but we still need shlib.conf here. config.status: $(top_srcdir)/config/shlib.conf ##DOS##!endif all-windows: maybe-awk Makefile-windows world: date make $(MFLAGS) all date INSTALLMKDIRS = $(KRB5ROOT) $(KRB5MANROOT) $(KRB5OTHERMKDIRS) \ $(ADMIN_BINDIR) $(SERVER_BINDIR) $(CLIENT_BINDIR) \ $(ADMIN_MANDIR) $(SERVER_MANDIR) $(CLIENT_MANDIR) \ $(FILE_MANDIR) $(OVERVIEW_MANDIR) \ $(ADMIN_CATDIR) $(SERVER_CATDIR) $(CLIENT_CATDIR) \ $(FILE_CATDIR) $(OVERVIEW_CATDIR) \ $(KRB5_LIBDIR) $(KRB5_INCDIR) \ $(KRB5_DB_MODULE_DIR) $(KRB5_PA_MODULE_DIR) \ $(KRB5_AD_MODULE_DIR) \ $(KRB5_LIBKRB5_MODULE_DIR) $(KRB5_TLS_MODULE_DIR) \ $(localstatedir) $(localstatedir)/krb5kdc \ $(runstatedir) $(runstatedir)/krb5kdc \ $(KRB5_INCSUBDIRS) $(datadir) $(EXAMPLEDIR) \ $(PKGCONFIG_DIR) install-strip: $(MAKE) install INSTALL_STRIP=-s install-recurse: install-mkdirs install-mkdirs: @for i in $(INSTALLMKDIRS); do \ $(srcdir)/config/mkinstalldirs $(DESTDIR)$$i; \ done install-headers-mkdirs: $(srcdir)/config/mkinstalldirs $(DESTDIR)$(KRB5_INCDIR) $(srcdir)/config/mkinstalldirs $(DESTDIR)$(KRB5_INCDIR)/gssapi $(srcdir)/config/mkinstalldirs $(DESTDIR)$(KRB5_INCDIR)/gssrpc install-headers-prerecurse: install-headers-mkdirs clean-:: clean-windows clean-unix:: $(RM) *.o core skiptests # Microsoft Windows build process... # config-windows: Makefile-windows # @echo Making in include # cd include # $(MAKE) -$(MFLAGS) # cd .. # # Build the pkinit plugin if OpenSSL was configured # ##DOS##!ifdef OPENSSL_DIR ##DOS##PKINIT_SUBDIR=plugins\preauth\pkinit ##DOS##PKINIT_MAKEFILE=$(PKINIT_SUBDIR)\Makefile ##DOS##!else ##DOS##PKINIT_SUBDIR= ##DOS##PKINIT_MAKEFILE= ##DOS##!endif # # We need outpre-dir explicitly in here because we may # try to build wconfig on a config-windows. # ##DOS##$(WCONFIG_EXE): outpre-dir wconfig.c ##DOS## $(CC) -Fe$@ -Fo$*.obj wconfig.c $(CCLINKOPTION) ##DOS## $(_VC_MANIFEST_EMBED_EXE) ##DOS##MKFDEP=$(WCONFIG_EXE) config\win-pre.in config\win-post.in WINMAKEFILES=Makefile \ appl\Makefile appl\gss-sample\Makefile \ ccapi\Makefile \ ccapi\lib\win\Makefile \ ccapi\server\win\Makefile \ ccapi\test\Makefile \ clients\Makefile clients\kdestroy\Makefile \ clients\kinit\Makefile clients\klist\Makefile \ clients\kpasswd\Makefile clients\kvno\Makefile \ clients\kcpytkt\Makefile clients\kdeltkt\Makefile \ clients\kswitch\Makefile \ include\Makefile \ lib\Makefile lib\crypto\Makefile lib\crypto\krb\Makefile \ lib\crypto\builtin\Makefile lib\crypto\builtin\aes\Makefile \ lib\crypto\builtin\enc_provider\Makefile \ lib\crypto\builtin\des\Makefile lib\crypto\builtin\md5\Makefile \ lib\crypto\builtin\camellia\Makefile lib\crypto\builtin\md4\Makefile \ lib\crypto\builtin\hash_provider\Makefile \ lib\crypto\builtin\sha2\Makefile lib\crypto\builtin\sha1\Makefile \ lib\crypto\crypto_tests\Makefile \ lib\gssapi\Makefile lib\gssapi\generic\Makefile \ lib\gssapi\krb5\Makefile lib\gssapi\mechglue\Makefile \ lib\gssapi\spnego\Makefile \ lib\krb5\Makefile \ lib\krb5\asn.1\Makefile lib\krb5\ccache\Makefile \ lib\krb5\ccache\ccapi\Makefile \ lib\krb5\error_tables\Makefile \ lib\krb5\keytab\Makefile \ lib\krb5\krb\Makefile \ lib\krb5\os\Makefile \ lib\krb5\rcache\Makefile \ lib\krb5\unicode\Makefile \ util\Makefile \ util\et\Makefile util\profile\Makefile util\profile\testmod\Makefile \ util\support\Makefile \ util\windows\Makefile \ windows\Makefile windows\lib\Makefile windows\ms2mit\Makefile \ windows\kfwlogon\Makefile windows\leashdll\Makefile \ windows\leash\Makefile windows\leash\htmlhelp\Makefile \ plugins\preauth\spake\Makefile $(PKINIT_MAKEFILE) ##DOS##Makefile-windows: $(MKFDEP) $(WINMAKEFILES) ##DOS##Makefile: Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##appl\Makefile: appl\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##appl\gss-sample\Makefile: appl\gss-sample\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##ccapi\Makefile: ccapi\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##ccapi\lib\win\Makefile: ccapi\lib\win\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##ccapi\server\win\Makefile: ccapi\server\win\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##ccapi\test\Makefile: ccapi\test\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##clients\Makefile: clients\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##clients\kdestroy\Makefile: clients\kdestroy\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##clients\kinit\Makefile: clients\kinit\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##clients\klist\Makefile: clients\klist\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##clients\kpasswd\Makefile: clients\kpasswd\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##clients\kswitch\Makefile: clients\kswitch\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##clients\kvno\Makefile: clients\kvno\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##clients\kcpytkt\Makefile: clients\kcpytkt\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##clients\kdeltkt\Makefile: clients\kdeltkt\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##include\Makefile: include\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\Makefile: lib\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\Makefile: lib\crypto\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\krb\Makefile: lib\crypto\krb\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\aes\Makefile: lib\crypto\builtin\aes\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\enc_provider\Makefile: lib\crypto\builtin\enc_provider\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\des\Makefile: lib\crypto\builtin\des\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\md5\Makefile: lib\crypto\builtin\md5\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\camellia\Makefile: lib\crypto\builtin\camellia\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\md4\Makefile: lib\crypto\builtin\md4\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\hash_provider\Makefile: lib\crypto\builtin\hash_provider\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\sha2\Makefile: lib\crypto\builtin\sha2\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\sha1\Makefile: lib\crypto\builtin\sha1\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\builtin\Makefile: lib\crypto\builtin\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\crypto\crypto_tests\Makefile: lib\crypto\crypto_tests\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\gssapi\Makefile: lib\gssapi\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\gssapi\generic\Makefile: lib\gssapi\generic\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\gssapi\mechglue\Makefile: lib\gssapi\mechglue\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\gssapi\spnego\Makefile: lib\gssapi\spnego\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\gssapi\krb5\Makefile: lib\gssapi\krb5\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\Makefile: lib\krb5\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\asn.1\Makefile: lib\krb5\asn.1\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\ccache\Makefile: lib\krb5\ccache\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\ccache\ccapi\Makefile: lib\krb5\ccache\ccapi\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\error_tables\Makefile: lib\krb5\error_tables\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\keytab\Makefile: $$@.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\krb\Makefile: lib\krb5\krb\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\os\Makefile: lib\krb5\os\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\rcache\Makefile: lib\krb5\rcache\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##lib\krb5\unicode\Makefile: lib\krb5\unicode\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##util\Makefile: util\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##util\et\Makefile: util\et\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##util\profile\Makefile: util\profile\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##util\profile\testmod\Makefile: util\profile\testmod\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##util\support\Makefile: util\support\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##util\windows\Makefile: util\windows\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##windows\Makefile: windows\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##windows\lib\Makefile: windows\lib\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##windows\ms2mit\Makefile: windows\ms2mit\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##windows\kfwlogon\Makefile: windows\kfwlogon\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##windows\leashdll\Makefile: windows\leashdll\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##windows\leash\Makefile: windows\leash\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##windows\leash\htmlhelp\Makefile: windows\leash\htmlhelp\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##plugins\preauth\spake\Makefile: plugins\preauth\spake\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ ##DOS##plugins\preauth\pkinit\Makefile: plugins\preauth\pkinit\Makefile.in $(MKFDEP) ##DOS## $(WCONFIG) config < $@.in > $@ clean-windows:: Makefile-windows # # Renames DOS 8.3 filenames back to their proper, longer names. # ren2long: -sh config/ren2long # # Helper for the windows build # TOPLEVEL=dummy # # Building error tables requires awk. # AWK = awk AH = util/et/et_h.awk AC = util/et/et_c.awk INC = include/ ET = lib/krb5/error_tables/ GG = lib/gssapi/generic/ GK = lib/gssapi/krb5/ PR = util/profile/ CE = util/et/ CCL = ccapi/lib/ ETOUT = \ $(INC)asn1_err.h $(ET)asn1_err.c \ $(INC)kdb5_err.h $(ET)kdb5_err.c \ $(INC)krb5_err.h $(ET)krb5_err.c \ $(INC)k5e1_err.h $(ET)k5e1_err.c \ $(INC)kv5m_err.h $(ET)kv5m_err.c \ $(INC)krb524_err.h $(ET)krb524_err.c \ $(PR)prof_err.h $(PR)prof_err.c \ $(GG)gssapi_err_generic.h $(GG)gssapi_err_generic.c \ $(GK)gssapi_err_krb5.h $(GK)gssapi_err_krb5.c \ $(CCL)ccapi_err.h $(CCL)ccapi_err.c HOUT = $(INC)krb5/krb5.h $(GG)gssapi.h $(PR)profile.h CLEANUP= Makefile $(ETOUT) $(HOUT) \ include/profile.h include/osconf.h dos-Makefile: cat config/win-pre.in Makefile.in config/win-post.in | \ sed -e "s/^##DOS##//" -e "s/^##DOS//" > Makefile.tmp mv Makefile.tmp Makefile prep-windows: dos-Makefile awk-windows-mac $(INC)asn1_err.h: $(AH) $(ET)asn1_err.et $(AWK) -f $(AH) outfile=$@ $(ET)asn1_err.et $(INC)kdb5_err.h: $(AH) $(ET)kdb5_err.et $(AWK) -f $(AH) outfile=$@ $(ET)kdb5_err.et $(INC)krb5_err.h: $(AH) $(ET)krb5_err.et $(AWK) -f $(AH) outfile=$@ $(ET)krb5_err.et $(INC)k5e1_err.h: $(AH) $(ET)k5e1_err.et $(AWK) -f $(AH) outfile=$@ $(ET)k5e1_err.et $(INC)kv5m_err.h: $(AH) $(ET)kv5m_err.et $(AWK) -f $(AH) outfile=$@ $(ET)kv5m_err.et $(INC)krb524_err.h: $(AH) $(ET)krb524_err.et $(AWK) -f $(AH) outfile=$@ $(ET)krb524_err.et $(PR)prof_err.h: $(AH) $(PR)prof_err.et $(AWK) -f $(AH) outfile=$@ $(PR)prof_err.et $(GG)gssapi_err_generic.h: $(AH) $(GG)gssapi_err_generic.et $(AWK) -f $(AH) outfile=$@ $(GG)gssapi_err_generic.et $(GK)gssapi_err_krb5.h: $(AH) $(GK)gssapi_err_krb5.et $(AWK) -f $(AH) outfile=$@ $(GK)gssapi_err_krb5.et $(CCL)ccapi_err.h: $(AH) $(CCL)ccapi_err.et $(AWK) -f $(AH) outfile=$@ $(CCL)ccapi_err.et $(CE)test1.h: $(AH) $(CE)test1.et $(AWK) -f $(AH) outfile=$@ $(CE)test1.et $(CE)test2.h: $(AH) $(CE)test2.et $(AWK) -f $(AH) outfile=$@ $(CE)test2.et $(ET)asn1_err.c: $(AC) $(ET)asn1_err.et $(AWK) -f $(AC) outfile=$@ $(ET)asn1_err.et $(ET)kdb5_err.c: $(AC) $(ET)kdb5_err.et $(AWK) -f $(AC) outfile=$@ $(ET)kdb5_err.et $(ET)krb5_err.c: $(AC) $(ET)krb5_err.et $(AWK) -f $(AC) outfile=$@ $(ET)krb5_err.et $(ET)k5e1_err.c: $(AC) $(ET)k5e1_err.et $(AWK) -f $(AC) outfile=$@ $(ET)k5e1_err.et $(ET)kv5m_err.c: $(AC) $(ET)kv5m_err.et $(AWK) -f $(AC) outfile=$@ $(ET)kv5m_err.et $(ET)krb524_err.c: $(AC) $(ET)krb524_err.et $(AWK) -f $(AC) outfile=$@ $(ET)krb524_err.et $(PR)prof_err.c: $(AC) $(PR)prof_err.et $(AWK) -f $(AC) outfile=$@ $(PR)prof_err.et $(GG)gssapi_err_generic.c: $(AC) $(GG)gssapi_err_generic.et $(AWK) -f $(AC) outfile=$@ $(GG)gssapi_err_generic.et $(GK)gssapi_err_krb5.c: $(AC) $(GK)gssapi_err_krb5.et $(AWK) -f $(AC) outfile=$@ $(GK)gssapi_err_krb5.et $(CCL)ccapi_err.c: $(AC) $(CCL)ccapi_err.et $(AWK) -f $(AC) outfile=$@ $(CCL)ccapi_err.et $(CE)test1.c: $(AC) $(CE)test1.et $(AWK) -f $(AC) outfile=$@ $(CE)test1.et $(CE)test2.c: $(AC) $(CE)test2.et $(AWK) -f $(AC) outfile=$@ $(CE)test2.et KRBHDEP = $(INC)krb5/krb5.hin $(INC)krb5_err.h $(INC)k5e1_err.h \ $(INC)kdb5_err.h $(INC)kv5m_err.h $(INC)krb524_err.h $(INC)asn1_err.h $(INC)krb5/krb5.h: $(KRBHDEP) rm -f $@ cat $(KRBHDEP) > $@ $(PR)profile.h: $(PR)profile.hin $(PR)prof_err.h rm -f $@ cat $(PR)profile.hin $(PR)prof_err.h > $@ $(GG)gssapi.h: $(GG)gssapi.hin rm -f $@ cat $(GG)gssapi.hin > $@ awk-windows-mac: $(ETOUT) $(HOUT) # # The maybe-awk target needs to happen after AWK is defined. # ##DOS##maybe-awk: ##DOS##!ifdef WHICH_CMD ##DOS##!if ![ $(WHICH_CMD) $(AWK) ] ##DOS##maybe-awk: awk-windows-mac ##DOS##!endif ##DOS##!endif clean-windows-mac: rm -f $(CLEANUP) distclean-windows: config\rm.bat $(CLEANUP:^/=^\) config\rm.bat $(WINMAKEFILES) config\rm.bat $(KBINDIR)\*.dll $(KBINDIR)\*.exe @if exist $(KBINDIR)\nul rmdir $(KBINDIR) # Avoid using $(CP) here because the nul+ hack breaks implicit # destination filenames. install-windows: @if "$(KRB_INSTALL_DIR)"=="" @echo KRB_INSTALL_DIR is not defined! Please define it. @if "$(KRB_INSTALL_DIR)"=="" @dir /b \nul\nul @if not exist "$(KRB_INSTALL_DIR)\$(NULL)" @echo The directory $(KRB_INSTALL_DIR) does not exist. Please create it. @if not exist "$(KRB_INSTALL_DIR)\$(NULL)" @dir /b $(KRB_INSTALL_DIR)\nul @if not exist "$(KRB_INSTALL_DIR)\include\$(NULL)" @mkdir "$(KRB_INSTALL_DIR)\include" @if not exist "$(KRB_INSTALL_DIR)\include\krb5\$(NULL)" @mkdir "$(KRB_INSTALL_DIR)\include\krb5" @if not exist "$(KRB_INSTALL_DIR)\include\gssapi\$(NULL)" @mkdir "$(KRB_INSTALL_DIR)\include\gssapi" @if not exist "$(KRB_INSTALL_DIR)\lib\$(NULL)" @mkdir "$(KRB_INSTALL_DIR)\lib" @if not exist "$(KRB_INSTALL_DIR)\bin\$(NULL)" @mkdir "$(KRB_INSTALL_DIR)\bin" @if not exist "$(KRB_INSTALL_DIR)\bin\plugins\$(NULL)" @mkdir "$(KRB_INSTALL_DIR)\bin\plugins" @if not exist "$(KRB_INSTALL_DIR)\bin\plugins\preauth\$(NULL)" @mkdir "$(KRB_INSTALL_DIR)\bin\plugins\preauth" copy include\krb5.h "$(KRB_INSTALL_DIR)\include\." copy include\krb5\krb5.h "$(KRB_INSTALL_DIR)\include\krb5\." copy include\win-mac.h "$(KRB_INSTALL_DIR)\include\." copy include\profile.h "$(KRB_INSTALL_DIR)\include\." copy include\com_err.h "$(KRB_INSTALL_DIR)\include\." copy include\gssapi\gssapi.h "$(KRB_INSTALL_DIR)\include\gssapi\." copy include\gssapi\gssapi_alloc.h "$(KRB_INSTALL_DIR)\include\gssapi\." copy include\gssapi\gssapi_krb5.h "$(KRB_INSTALL_DIR)\include\gssapi\." copy include\gssapi\gssapi_ext.h "$(KRB_INSTALL_DIR)\include\gssapi\." copy lib\$(OUTPRE)*.lib "$(KRB_INSTALL_DIR)\lib\." copy lib\$(OUTPRE)*.dll "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) lib\$(OUTPRE)*.pdb "$(KRB_INSTALL_DIR)\bin\." copy appl\gss-sample\$(OUTPRE)gss-server.exe "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) appl\gss-sample\$(OUTPRE)gss-server.pdb "$(KRB_INSTALL_DIR)\bin\." copy appl\gss-sample\$(OUTPRE)gss-client.exe "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) appl\gss-sample\$(OUTPRE)gss-client.pdb "$(KRB_INSTALL_DIR)\bin\." copy windows\ms2mit\$(OUTPRE)*.exe "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) windows\ms2mit\$(OUTPRE)*.pdb "$(KRB_INSTALL_DIR)\bin\." copy windows\leashdll\$(OUTPRE)*.lib "$(KRB_INSTALL_DIR)\lib\." copy windows\leashdll\$(OUTPRE)*.dll "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) windows\leashdll\$(OUTPRE)*.pdb "$(KRB_INSTALL_DIR)\bin\." ##DOS##!ifndef NO_LEASH copy windows\leash\$(OUTPRE)*.exe "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) windows\leash\$(OUTPRE)*.pdb "$(KRB_INSTALL_DIR)\bin\." copy windows\leash\$(OUTPRE)*.chm "$(KRB_INSTALL_DIR)\bin\." copy windows\leash\htmlhelp\*.chm "$(KRB_INSTALL_DIR)\bin\." ##DOS##!endif copy windows\kfwlogon\$(OUTPRE)*.lib "$(KRB_INSTALL_DIR)\lib\." copy windows\kfwlogon\$(OUTPRE)*.exe "$(KRB_INSTALL_DIR)\bin\." copy windows\kfwlogon\$(OUTPRE)*.dll "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) windows\kfwlogon\$(OUTPRE)*.pdb "$(KRB_INSTALL_DIR)\bin\." copy ccapi\lib\win\srctmp\$(OUTPRE)$(CCLIB).dll "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) ccapi\lib\win\srctmp\$(OUTPRE)$(CCLIB).pdb "$(KRB_INSTALL_DIR)\bin\." copy ccapi\lib\win\srctmp\$(CCLIB).lib "$(KRB_INSTALL_DIR)\lib\." copy ccapi\server\win\srctmp\$(OUTPRE)ccapiserver.exe "$(KRB_INSTALL_DIR)\bin\." copy clients\kvno\$(OUTPRE)kvno.exe "$(KRB_INSTALL_DIR)\bin\." copy clients\klist\$(OUTPRE)klist.exe "$(KRB_INSTALL_DIR)\bin\." copy clients\kinit\$(OUTPRE)kinit.exe "$(KRB_INSTALL_DIR)\bin\." copy clients\kdestroy\$(OUTPRE)kdestroy.exe "$(KRB_INSTALL_DIR)\bin\." copy clients\kcpytkt\$(OUTPRE)kcpytkt.exe "$(KRB_INSTALL_DIR)\bin\." copy clients\kdeltkt\$(OUTPRE)kdeltkt.exe "$(KRB_INSTALL_DIR)\bin\." copy clients\kpasswd\$(OUTPRE)kpasswd.exe "$(KRB_INSTALL_DIR)\bin\." copy clients\kswitch\$(OUTPRE)kswitch.exe "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) ccapi\server\win\srctmp\$(OUTPRE)ccapiserver.pdb "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) clients\kvno\$(OUTPRE)kvno.pdb "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) clients\klist\$(OUTPRE)klist.pdb "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) clients\kinit\$(OUTPRE)kinit.pdb "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) clients\kdestroy\$(OUTPRE)kdestroy.pdb "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) clients\kcpytkt\$(OUTPRE)kcpytkt.pdb "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) clients\kdeltkt\$(OUTPRE)kdeltkt.pdb "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) clients\kpasswd\$(OUTPRE)kpasswd.pdb "$(KRB_INSTALL_DIR)\bin\." $(INSTALLDBGSYMS) clients\kswitch\$(OUTPRE)kswitch.pdb "$(KRB_INSTALL_DIR)\bin\." copy plugins\preauth\spake\$(OUTPRE)$(SPAKELIB).dll "$(KRB_INSTALL_DIR)\bin\plugins\preauth\." $(INSTALLDBGSYMS) plugins\preauth\spake\$(OUTPRE)$(SPAKELIB).pdb "$(KRB_INSTALL_DIR)\bin\plugins\preauth\." ##DOS##!ifdef OPENSSL_DIR copy plugins\preauth\pkinit\$(OUTPRE)$(PKINITLIB).dll "$(KRB_INSTALL_DIR)\bin\plugins\preauth\." $(INSTALLDBGSYMS) plugins\preauth\pkinit\$(OUTPRE)$(PKINITLIB).pdb "$(KRB_INSTALL_DIR)\bin\plugins\preauth\." ##DOS##!endif check-prerecurse: runenv.py $(RM) $(SKIPTESTS) touch $(SKIPTESTS) check-unix: check-lmdb-$(HAVE_LMDB) cat $(SKIPTESTS) MINPYTHON = @PYTHON_MINVERSION@ check-pytests-no: check-postrecurse @echo 'Skipped python test scripts: python $(MINPYTHON) required' >> \ $(SKIPTESTS) check-cmocka-no: check-postrecurse @echo 'Skipped cmocka tests: cmocka library or header not found' >> \ $(SKIPTESTS) check-lmdb-yes: check-lmdb-no: @echo 'Skipped LMDB tests: LMDB KDB module not built' >> $(SKIPTESTS) # Create a test realm and spawn a shell in an environment pointing to it. # If CROSSNUM is set, create that many fully connected test realms and # point the shell at the first one. testrealm: runenv.py PYTHONPATH=$(top_srcdir)/util $(PYTHON) $(srcdir)/util/testrealm.py \ $(CROSSNUM) # environment variable settings to propagate to Python-based tests ASAN = @ASAN@ pyrunenv.vals: Makefile $(RUN_SETUP); \ for i in $(RUN_VARS); do \ eval echo 'env['\\\'$$i\\\''] = '\\\'\$$$$i\\\'; \ done > $@ echo "asan = '$(ASAN)'" >> $@ echo "tls_impl = '$(TLS_IMPL)'" >> $@ echo "have_sasl = '$(HAVE_SASL)'" >> $@ echo "have_spake_openssl = '$(HAVE_SPAKE_OPENSSL)'" >> $@ echo "have_lmdb = '$(HAVE_LMDB)'" >> $@ echo "sizeof_time_t = $(SIZEOF_TIME_T)" >> $@ runenv.py: pyrunenv.vals echo 'env = {}' > $@ cat pyrunenv.vals >> $@ clean-unix:: $(RM) runenv.py runenv.pyc pyrunenv.vals $(RM) -r __pycache__ COV_BUILD= cov-build COV_ANALYZE= cov-analyze COV_COMMIT= cov-commit-defects --product "$(COV_PRODUCT)" --user "$(COV_USER)" --target "$(COV_TARGET)" --description "$(COV_DESC)" COV_MAKE_LIB= cov-make-library COV_PRODUCT= krb5 COV_USER= admin COV_DATADIR= COV_TARGET= $(host) COV_DESC= # Set to, e.g., "--all" or "--security". COV_ANALYSES= # Temporary directory, might as well put it in the build tree. COV_TEMPDIR= cov-temp # Sources modeling some functions or macros confusing Prevent. COV_MODELS=\ $(top_srcdir)/util/coverity-models/threads.c # Depend on Makefiles to ensure that (in maintainer mode) the configure # scripts won't get rerun under cov-build. coverity prevent cov: Makefiles $(COV_BUILD) --dir $(COV_TEMPDIR) $(MAKE) all $(COV_ANALYZE) $(COV_ANALYSES) --dir $(COV_TEMPDIR) if test "$(COV_DATADIR)" != ""; then \ $(COV_COMMIT) --dir $(COV_TEMPDIR) --datadir $(COV_DATADIR); \ else \ echo "** Coverity Prevent analysis results not commit to Defect Manager"; \ fi FIND = find XARGS = xargs EMACS = emacs INDENTDIRS = \ appl \ clients \ include \ kadmin \ kdc \ lib/apputils \ lib/crypto \ lib/gssapi \ lib/kadm5 \ lib/kdb \ lib/krb5 \ plugins \ prototype \ kprop \ tests \ util BSDFILES = \ kadmin/server/ipropd_svc.c \ kadmin/server/kadm_rpc_svc.c \ lib/apputils/daemon.c \ lib/kadm5/admin_xdr.h \ lib/kadm5/clnt/client_rpc.c \ lib/kadm5/kadm_rpc.h \ lib/kadm5/kadm_rpc_xdr.c \ lib/kadm5/srv/adb_xdr.c \ lib/krb5/krb/strptime.c \ kprop/kpropd_rpc.c \ util/support/getopt.c \ util/support/getopt_long.c \ util/support/mkstemp.c \ util/support/strlcpy.c OTHEREXCLUDES = \ include/iprop.h \ include/k5-platform.h \ include/gssrpc \ lib/apputils/dummy.c \ lib/crypto/crypto_tests/camellia-test.c \ lib/crypto/builtin/aes \ lib/crypto/builtin/camellia \ lib/crypto/builtin/sha2 \ lib/gssapi/generic/gssapiP_generic.h \ lib/gssapi/generic/gssapi_ext.h \ lib/gssapi/krb5/gssapiP_krb5.h \ lib/gssapi/mechglue \ lib/gssapi/spnego \ lib/krb5/krb/deltat.c \ lib/krb5/unicode \ plugins/kdb/db2/libdb2 \ plugins/kdb/db2/pol_xdr.c \ plugins/preauth/pkinit/pkcs11.h \ plugins/preauth/pkinit/pkinit_accessor.h \ plugins/preauth/pkinit/pkinit_crypto.h \ plugins/preauth/pkinit/pkinit.h \ plugins/preauth/pkinit/pkinit_crypto_openssl.h \ tests/asn.1/ktest.h \ tests/asn.1/ktest_equal.h \ tests/asn.1/utility.h \ tests/gss-threads/gss-misc.c \ tests/gss-threads/gss-misc.h \ tests/hammer/kdc5_hammer.c \ util/et/com_err.h \ util/profile/prof_int.h \ util/profile/profile.hin \ util/support/fnmatch.c \ util/verto \ util/k5ev EXCLUDES = `for i in $(BSDFILES) $(OTHEREXCLUDES); do echo $$i; done | $(AWK) '{ print "-path", $$1, "-o" }'` -path /dev/null FIND_REINDENT = cd $(top_srcdir) && \ $(FIND) $(INDENTDIRS) \( $(EXCLUDES) \) -prune -o \ \( -name '*.[ch]' -o -name '*.hin' -o -name '*.[ch].in' \) show-reindentfiles: ($(FIND_REINDENT) -print) reindent: ($(FIND_REINDENT) \ -print0 | $(XARGS) -0 $(EMACS) -q -batch \ -l util/krb5-c-style.el \ -l util/krb5-batch-reindent.el) mark-cstyle: mark-cstyle-krb5 mark-cstyle-bsd mark-cstyle-krb5: (cd $(top_srcdir) && \ $(FIND) $(INDENTDIRS) \( $(EXCLUDES) \) -prune -o \ -name '*.[ch]' \ -print0 | $(XARGS) -0 $(PYTHON) util/krb5-mark-cstyle.py \ --cstyle=krb5) mark-cstyle-bsd: (cd $(top_srcdir) && $(FIND) $(BSDFILES) -print0 | $(XARGS) -0 \ $(PYTHON) util/krb5-mark-cstyle.py --cstyle=bsd) check-copyright: (cd $(top_srcdir) && \ $(FIND) . \( -name '*.[ch]' -o -name '*.hin' \) -print0 | \ $(XARGS) -0 $(PYTHON) util/krb5-check-copyright.py) tags: FORCE (cd $(top_srcdir) && \ $(FIND) . \( -name '*.[ch]' -o -name '*.hin' \) -print | \ etags --lang=c - && \ $(FIND) . -name '*.cpp' -print | etags --lang=c++ --append - && \ $(FIND) . -name '*.y' -print | etags --lang=yacc --append -) FORCE: .PHONY: FORCE tags # Update versioned automatically-generated files. regen: $(MAKE) depend (cd man && $(MAKE) man) (cd po && $(MAKE) update-po) (cd lib/krb5/krb && $(RM) deltat.c && $(MAKE) deltat.c) distclean-unix: $(RM) $(top_srcdir)/TAGS krb5-1.22.1/src/appl/0000775000175000017500000000000015051422640014064 5ustar ghudsonghudsonkrb5-1.22.1/src/appl/Makefile.in0000664000175000017500000000014115051422640016125 0ustar ghudsonghudsonmydir=appl BUILDTOP=$(REL).. SUBDIRS= sample simple user_user gss-sample WINSUBDIRS= gss-sample krb5-1.22.1/src/appl/deps0000664000175000017500000000003015051422640014733 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/appl/gss-sample/0000775000175000017500000000000015051422640016137 5ustar ghudsonghudsonkrb5-1.22.1/src/appl/gss-sample/README0000664000175000017500000001466515051422640017033 0ustar ghudsonghudson# Copyright 1993 by OpenVision Technologies, Inc. # # Permission to use, copy, modify, distribute, and sell this software # and its documentation for any purpose is hereby granted without fee, # provided that the above copyright notice appears in all copies and # that both that copyright notice and this permission notice appear in # supporting documentation, and that the name of OpenVision not be used # in advertising or publicity pertaining to distribution of the software # without specific, written prior permission. OpenVision makes no # representations about the suitability of this software for any # purpose. It is provided "as is" without express or implied warranty. # # OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO # EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF # USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. This directory contains a sample GSS-API client and server application. In addition to serving as an example of GSS-API programming, this application is also intended to be a tool for testing the performance of GSS-API implementations. Each time the client is invoked, it performs one or more exchanges with the server. Each exchange with the server consists primarily of the following steps: 1. A TCP/IP connection is established. 2. (optional, on by default) The client and server establish a GSS-API context, and the server prints the identify of the client. / 3. The client sends a message to the server. The message may / be plaintext, cryptographically "signed" but not encrypted, | or encrypted (default). | 0 or | 4. The server decrypts the message (if necessary), verifies more | its signature (if there is one) and prints it. times| | 5. The server sends either a signature block (the default) or an | empty token back to the client to acknowledge the message. \ \ 6. If the server sent a signature block, the client verifies it and prints a message indicating that it was verified. 7. The client sends an empty block to the server to tell it that the exchange is finished. 8. The client and server close the TCP/IP connection and destroy the GSS-API context. The client also supports the -v1 flag which uses an older exchange format compatible with previous releases of Kerberos and with samples shipped in the Microsoft SDK. The server's command line usage is gss-server [-port port] [-verbose] [-once] [-inetd] [-export] [-logfile file] service_name where service_name is a GSS-API service name of the form "service@host" (or just "service", in which case the local host name is used). The command-line options have the following meanings: -port The TCP port on which to accept connections. Default is 4444. -once Tells the server to exit after a single exchange, rather than persisting. -inetd Tells the server that it is running out of inetd, so it should interact with the client on stdin rather than binding to a network port. Implies "-once". -export Tells the server to test the gss_export_sec_context function after establishing a context with a client. -logfile The file to which the server should append its output, rather than sending it to stdout. The client's command line usage is gss-client [-port port] [-mech mechanism] [-d] [-f] [-q] [-seq] [-noreplay] [-nomutual] [-dce] [-ccount count] [-mcount count] [-na] [-nw] [-nx] [-nm] host service_name msg where host is the host running the server, service_name is the service name that the server will establish connections as (if you don't specify the host name in the service name when running gss-server, and it's running on a different machine from gss-client, make sure to specify the server's host name in the service name you specify to gss-client!) and msg is the message. The command-line options have the following meanings: -port The TCP port to which to connect. Default is 4444. -mech The OID of the GSS-API mechanism to use. -d Tells the client to delegate credentials to the server. For the Kerberos GSS-API mechanism, this means that a forwardable TGT will be sent to the server, which will put it in its credential cache (you must have acquired your tickets with "kinit -f" for this to work). -seq Tells the client to enforce ordered message delivery via sequencing. -noreplay Tells the client to disable the use of replay detection. -dce Tells the client to request DCE-style authentication. -nomutual Tells the client to disable the use of mutual authentication. -f Tells the client that the "msg" argument is actually the name of a file whose contents should be used as the message. -q Tells the client to be quiet, i.e., to only print error messages. -ccount Specifies how many sessions the client should initiate with the server (the "connection count"). -mcount Specifies how many times the message should be sent to the server in each session (the "message count"). -na Tells the client not to do any authentication with the server. Implies "-nw", "-nx" and "-nm". -nw Tells the client not to "wrap" messages. Implies "-nx". -nx Tells the client not to encrypt messages. -nm Tells the client not to ask the server to send back a cryptographic checksum ("MIC"). To run the server on a host, you need to make sure that the principal corresponding to service_name is in the default keytab on the server host, and that the gss-server process can read the keytab. For example, the service name "host@server" corresponds to the Kerberos principal "host/server.domain.com@REALM". This sample application uses the following GSS-API functions: gss_accept_sec_context gss_inquire_names_for_mech gss_acquire_cred gss_oid_to_str gss_delete_sec_context gss_release_buffer gss_display_name gss_release_cred gss_display_status gss_release_name gss_export_sec_context gss_release_oid gss_get_mic gss_release_oid_set gss_import_name gss_str_to_oid gss_import_sec_context gss_unwrap gss_init_sec_context gss_verify_mic gss_inquire_context gss_wrap This application was originally written by Barry Jaspan of OpenVision Technologies, Inc. It was updated significantly by Jonathan Kamens of OpenVision Technologies, Inc. $Id$ krb5-1.22.1/src/appl/gss-sample/Makefile.in0000664000175000017500000000333315051422640020206 0ustar ghudsonghudsonmydir=appl$(S)gss-sample BUILDTOP=$(REL)..$(S).. DEFINES = -DUSE_AUTOCONF_H -DGSSAPI_V2 SRCS= $(srcdir)/gss-client.c $(srcdir)/gss-misc.c $(srcdir)/gss-server.c OBJS= gss-client.o gss-misc.o gss-server.o all-unix: gss-server gss-client ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##GSSCLIENT=$(OUTPRE)gss-client.exe ##WIN32##GSSSERVER=$(OUTPRE)gss-server.exe ##WIN32##CLIENTRES=$(GSSCLIENT:.exe=.res) ##WIN32##SERVERRES=$(GSSSERVER:.exe=.res) ##WIN32##$(CLIENTRES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DGSS_CLIENT_APP -fo $@ -r $** ##WIN32##$(SERVERRES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DGSS_SERVER_APP -fo $@ -r $** ##WIN32##all-windows: $(OUTPRE)gss-server.exe $(OUTPRE)gss-client.exe gss-server: gss-server.o gss-misc.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o gss-server gss-server.o gss-misc.o $(GSS_LIBS) $(KRB5_BASE_LIBS) gss-client: gss-client.o gss-misc.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o gss-client gss-client.o gss-misc.o $(GSS_LIBS) $(KRB5_BASE_LIBS) ##WIN32##$(GSSSERVER): $(OUTPRE)gss-server.obj $(OUTPRE)gss-misc.obj $(GLIB) $(KLIB) $(SERVERRES) ##WIN32## link $(EXE_LINKOPTS) -out:$@ $** ws2_32.lib ##WIN32## $(_VC_MANIFEST_EMBED_EXE) ##WIN32##$(GSSCLIENT): $(OUTPRE)gss-client.obj $(OUTPRE)gss-misc.obj $(GLIB) $(KLIB) $(CLIENTRES) ##WIN32## link $(EXE_LINKOPTS) -out:$@ $** ws2_32.lib ##WIN32## $(_VC_MANIFEST_EMBED_EXE) clean-unix:: $(RM) gss-server gss-client check-pytests: $(RUNPYTEST) $(srcdir)/t_gss_sample.py $(PYTESTFLAGS) install-unix: $(INSTALL_PROGRAM) gss-client $(DESTDIR)$(CLIENT_BINDIR)/gss-client $(INSTALL_PROGRAM) gss-server $(DESTDIR)$(SERVER_BINDIR)/gss-server krb5-1.22.1/src/appl/gss-sample/gss-misc.h0000664000175000017500000000373715051422640020047 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * $Id$ */ #ifndef _GSSMISC_H_ #define _GSSMISC_H_ #include #include extern FILE *display_file; int send_token(int s, int flags, gss_buffer_t tok); int recv_token(int s, int *flags, gss_buffer_t tok); void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat); void display_ctx_flags(OM_uint32 flags); void print_token(gss_buffer_t tok); /* Token types */ #define TOKEN_NOOP (1<<0) #define TOKEN_CONTEXT (1<<1) #define TOKEN_DATA (1<<2) #define TOKEN_MIC (1<<3) /* Token flags */ #define TOKEN_CONTEXT_NEXT (1<<4) #define TOKEN_WRAPPED (1<<5) #define TOKEN_ENCRYPTED (1<<6) #define TOKEN_SEND_MIC (1<<7) extern gss_buffer_t empty_token; #endif krb5-1.22.1/src/appl/gss-sample/gss-misc.c0000664000175000017500000002674515051422640020046 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2003, 2004 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #ifdef _WIN32 #include #include #else #include #include #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #include /* need struct timeval */ #ifdef HAVE_SYS_TIME_H #include #else #include #endif #include #include "gss-misc.h" #ifdef HAVE_STDLIB_H #include #else extern char *malloc(); #endif FILE *display_file; gss_buffer_desc empty_token_buf = { 0, (void *) "" }; gss_buffer_t empty_token = &empty_token_buf; static void display_status_1(char *m, OM_uint32 code, int type); static int write_all(int fildes, const void *data, unsigned int nbyte) { int ret; const char *ptr, *buf = data; for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { ret = send(fildes, ptr, nbyte, 0); if (ret < 0) { if (errno == EINTR) continue; return (ret); } else if (ret == 0) { return (ptr - buf); } } return (ptr - buf); } static int read_all(int fildes, void *data, unsigned int nbyte) { int ret; char *ptr, *buf = data; fd_set rfds; struct timeval tv; FD_ZERO(&rfds); FD_SET(fildes, &rfds); tv.tv_sec = 300; tv.tv_usec = 0; for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { if (select(FD_SETSIZE, &rfds, NULL, NULL, &tv) <= 0 || !FD_ISSET(fildes, &rfds)) return (ptr - buf); ret = recv(fildes, ptr, nbyte, 0); if (ret < 0) { if (errno == EINTR) continue; return (ret); } else if (ret == 0) { return (ptr - buf); } } return (ptr - buf); } /* * Function: send_token * * Purpose: Writes a token to a file descriptor. * * Arguments: * * s (r) an open file descriptor * flags (r) the flags to write * tok (r) the token to write * * Returns: 0 on success, -1 on failure * * Effects: * * If the flags are non-null, send_token writes the token flags (a * single byte, even though they're passed in in an integer). Next, * the token length (as a network long) and then the token data are * written to the file descriptor s. It returns 0 on success, and -1 * if an error occurs or if it could not write all the data. */ int send_token(int s, int flags, gss_buffer_t tok) { int ret; unsigned char char_flags = (unsigned char) flags; unsigned char lenbuf[4]; if (char_flags) { ret = write_all(s, (char *) &char_flags, 1); if (ret != 1) { perror("sending token flags"); return -1; } } if (tok->length > 0xffffffffUL) abort(); lenbuf[0] = (tok->length >> 24) & 0xff; lenbuf[1] = (tok->length >> 16) & 0xff; lenbuf[2] = (tok->length >> 8) & 0xff; lenbuf[3] = tok->length & 0xff; ret = write_all(s, lenbuf, 4); if (ret < 0) { perror("sending token length"); return -1; } else if (ret != 4) { if (display_file) fprintf(display_file, "sending token length: %d of %d bytes written\n", ret, 4); return -1; } ret = write_all(s, tok->value, tok->length); if (ret < 0) { perror("sending token data"); return -1; } else if ((size_t)ret != tok->length) { if (display_file) fprintf(display_file, "sending token data: %d of %d bytes written\n", ret, (int) tok->length); return -1; } return 0; } /* * Function: recv_token * * Purpose: Reads a token from a file descriptor. * * Arguments: * * s (r) an open file descriptor * flags (w) the read flags * tok (w) the read token * * Returns: 0 on success, -1 on failure * * Effects: * * recv_token reads the token flags (a single byte, even though * they're stored into an integer, then reads the token length (as a * network long), allocates memory to hold the data, and then reads * the token data from the file descriptor s. It blocks to read the * length and data, if necessary. On a successful return, the token * should be freed with gss_release_buffer. It returns 0 on success, * and -1 if an error occurs or if it could not read all the data. */ int recv_token(int s, int *flags, gss_buffer_t tok) { int ret; unsigned char char_flags; unsigned char lenbuf[4]; ret = read_all(s, (char *) &char_flags, 1); if (ret < 0) { perror("reading token flags"); return -1; } else if (!ret) { if (display_file) fputs("reading token flags: 0 bytes read\n", display_file); return -1; } else { *flags = (int) char_flags; } if (char_flags == 0) { lenbuf[0] = 0; ret = read_all(s, &lenbuf[1], 3); if (ret < 0) { perror("reading token length"); return -1; } else if (ret != 3) { if (display_file) fprintf(display_file, "reading token length: %d of %d bytes read\n", ret, 3); return -1; } } else { ret = read_all(s, lenbuf, 4); if (ret < 0) { perror("reading token length"); return -1; } else if (ret != 4) { if (display_file) fprintf(display_file, "reading token length: %d of %d bytes read\n", ret, 4); return -1; } } tok->length = ((lenbuf[0] << 24) | (lenbuf[1] << 16) | (lenbuf[2] << 8) | lenbuf[3]); tok->value = (char *) malloc(tok->length ? tok->length : 1); if (tok->length && tok->value == NULL) { if (display_file) fprintf(display_file, "Out of memory allocating token data\n"); return -1; } ret = read_all(s, (char *) tok->value, tok->length); if (ret < 0) { perror("reading token data"); free(tok->value); return -1; } else if ((size_t)ret != tok->length) { fprintf(stderr, "sending token data: %d of %d bytes written\n", ret, (int) tok->length); free(tok->value); return -1; } return 0; } static void display_status_1(char *m, OM_uint32 code, int type) { OM_uint32 min_stat; gss_buffer_desc msg; OM_uint32 msg_ctx; msg_ctx = 0; while (1) { (void) gss_display_status(&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg); if (display_file) fprintf(display_file, "GSS-API error %s: %s\n", m, (char *) msg.value); (void) gss_release_buffer(&min_stat, &msg); if (!msg_ctx) break; } } /* * Function: display_status * * Purpose: displays GSS-API messages * * Arguments: * * msg a string to be displayed with the message * maj_stat the GSS-API major status code * min_stat the GSS-API minor status code * * Effects: * * The GSS-API messages associated with maj_stat and min_stat are * displayed on stderr, each preceded by "GSS-API error : " and * followed by a newline. */ void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat) { display_status_1(msg, maj_stat, GSS_C_GSS_CODE); display_status_1(msg, min_stat, GSS_C_MECH_CODE); } /* * Function: display_ctx_flags * * Purpose: displays the flags returned by context initiation in * a human-readable form * * Arguments: * * int ret_flags * * Effects: * * Strings corresponding to the context flags are printed on * stdout, preceded by "context flag: " and followed by a newline */ void display_ctx_flags(OM_uint32 flags) { if (flags & GSS_C_DELEG_FLAG) fprintf(display_file, "context flag: GSS_C_DELEG_FLAG\n"); if (flags & GSS_C_MUTUAL_FLAG) fprintf(display_file, "context flag: GSS_C_MUTUAL_FLAG\n"); if (flags & GSS_C_REPLAY_FLAG) fprintf(display_file, "context flag: GSS_C_REPLAY_FLAG\n"); if (flags & GSS_C_SEQUENCE_FLAG) fprintf(display_file, "context flag: GSS_C_SEQUENCE_FLAG\n"); if (flags & GSS_C_CONF_FLAG) fprintf(display_file, "context flag: GSS_C_CONF_FLAG \n"); if (flags & GSS_C_INTEG_FLAG) fprintf(display_file, "context flag: GSS_C_INTEG_FLAG \n"); } void print_token(gss_buffer_t tok) { unsigned int i; unsigned char *p = tok->value; if (!display_file) return; for (i = 0; i < tok->length; i++, p++) { fprintf(display_file, "%02x ", *p); if ((i % 16) == 15) { fprintf(display_file, "\n"); } } fprintf(display_file, "\n"); fflush(display_file); } #ifdef _WIN32 #include #include int gettimeofday(struct timeval *tv, void *ignore_tz) { struct _timeb tb; _tzset(); _ftime(&tb); if (tv) { tv->tv_sec = tb.time; tv->tv_usec = tb.millitm * 1000; } return 0; } #endif /* _WIN32 */ krb5-1.22.1/src/appl/gss-sample/t_gss_sample.py0000775000175000017500000001336715051422640021206 0ustar ghudsonghudson# Copyright (C) 2010 by the Massachusetts Institute of Technology. # All rights reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * appdir = os.path.join(buildtop, 'appl', 'gss-sample') gss_client = os.path.join(appdir, 'gss-client') gss_server = os.path.join(appdir, 'gss-server') # Run a gss-server process and a gss-client process, with additional # gss-client flags given by options and additional gss-server flags # given by server_options. Return the output of gss-client. def run_client_server(realm, options, server_options, **kwargs): portstr = str(realm.server_port()) server_args = [gss_server, '-export', '-port', portstr] server_args += server_options + ['host'] server = realm.start_server(server_args, 'starting...') realm.run([gss_client, '-port', portstr] + options + [hostname, 'host', 'testmsg'], **kwargs) seen1 = seen2 = False while 'expected_code' not in kwargs and not (seen1 and seen2): line = server.stdout.readline() if line == '': fail('gss-server process exited unexpectedly') if line == 'Accepted connection: "user@KRBTEST.COM"\n': seen1 = True if line == 'Received message: "testmsg"\n': seen2 = True stop_daemon(server) # Run a gss-server and gss-client process, and verify that gss-client # displayed the expected output for a successful negotiation. def server_client_test(realm, options, server_options): run_client_server(realm, options, server_options, expected_msg='Signature verified.') # Make up a filename to hold user's initial credentials. def ccache_savefile(realm): return os.path.join(realm.testdir, 'ccache.copy') # Move user's initial credentials into the save file. def ccache_save(realm): os.rename(realm.ccache, ccache_savefile(realm)) # Copy user's initial credentials from the save file into the ccache. def ccache_restore(realm): shutil.copyfile(ccache_savefile(realm), realm.ccache) # Perform a regular (TGS path) test of the server and client. def tgs_test(realm, options, server_options=[]): ccache_restore(realm) server_client_test(realm, options, server_options) realm.klist(realm.user_princ, realm.host_princ) # Perform a test of the server and client with initial credentials # obtained through gss_acquire_cred_with_password(). def pw_test(realm, options, server_options=[]): if os.path.exists(realm.ccache): os.remove(realm.ccache) if '-iakerb' in options: # Use IAKERB realm discovery. user = realm.user_princ.split('@')[0] else: user = realm.user_princ options = options + ['-user', user, '-pass', password('user')] server_client_test(realm, options, server_options) if os.path.exists(realm.ccache): fail('gss_acquire_cred_with_password created ccache') # Perform a test using the wrong password, and make sure that failure # occurs during the expected operation (gss_init_sec_context() for # IAKERB, gss_aqcuire_cred_with_password() otherwise). def wrong_pw_test(realm, options, server_options=[], iakerb=False): options = options + ['-user', realm.user_princ, '-pass', 'wrongpw'] failed_op = 'initializing context' if iakerb else 'acquiring creds' msg = 'GSS-API error ' + failed_op run_client_server(realm, options, server_options, expected_code=1, expected_msg=msg) # Perform a test of the server and client with initial credentials # obtained with the client keytab def kt_test(realm, options, server_options=[]): if os.path.exists(realm.ccache): os.remove(realm.ccache) server_client_test(realm, options, server_options) realm.klist(realm.user_princ, realm.host_princ) for realm in multipass_realms(): ccache_save(realm) mark('TGS') tgs_test(realm, ['-krb5']) tgs_test(realm, ['-spnego']) tgs_test(realm, ['-iakerb'], ['-iakerb']) # test default (i.e., krb5) mechanism with GSS_C_DCE_STYLE tgs_test(realm, ['-dce']) mark('AP') ccache_save(realm) tgs_test(realm, ['-krb5']) tgs_test(realm, ['-spnego']) tgs_test(realm, ['-iakerb'], ['-iakerb']) tgs_test(realm, ['-dce']) mark('pw') pw_test(realm, ['-krb5']) pw_test(realm, ['-spnego']) pw_test(realm, ['-iakerb'], ['-iakerb']) pw_test(realm, ['-dce']) mark('wrong pw') wrong_pw_test(realm, ['-krb5']) wrong_pw_test(realm, ['-spnego']) wrong_pw_test(realm, ['-iakerb'], ['-iakerb'], True) wrong_pw_test(realm, ['-dce']) mark('client keytab') realm.extract_keytab(realm.user_princ, realm.client_keytab) kt_test(realm, ['-krb5']) kt_test(realm, ['-spnego']) kt_test(realm, ['-iakerb'], ['-iakerb']) kt_test(realm, ['-dce']) success('GSS sample application') krb5-1.22.1/src/appl/gss-sample/deps0000664000175000017500000000171215051422640017016 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)gss-client.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/port-sockets.h gss-client.c gss-misc.h $(OUTPRE)gss-misc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ gss-misc.c gss-misc.h $(OUTPRE)gss-server.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/port-sockets.h gss-misc.h gss-server.c krb5-1.22.1/src/appl/gss-sample/gss-server.c0000664000175000017500000006614515051422640020417 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2004,2005 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #ifdef _WIN32 #include #include #else #include "port-sockets.h" #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include "gss-misc.h" #ifdef HAVE_STRING_H #include #else #include #endif static OM_uint32 enumerateAttributes(OM_uint32 *minor, gss_name_t name, int noisy); static OM_uint32 showLocalIdentity(OM_uint32 *minor, gss_name_t name); static void usage(void) { fprintf(stderr, "Usage: gss-server [-port port] [-verbose] [-once]"); #ifdef _WIN32 fprintf(stderr, " [-threads num]"); #endif fprintf(stderr, "\n"); fprintf(stderr, " [-inetd] [-export] [-logfile file] [-keytab keytab]\n" " service_name\n"); exit(1); } static FILE *logfile; int verbose = 0; /* * Function: server_acquire_creds * * Purpose: imports a service name and acquires credentials for it * * Arguments: * * service_name (r) the ASCII service name * mech (r) the desired mechanism (or GSS_C_NO_OID) * server_creds (w) the GSS-API service credentials * * Returns: 0 on success, -1 on failure * * Effects: * * The service name is imported with gss_import_name, and service * credentials are acquired with gss_acquire_cred. If either operation * fails, an error message is displayed and -1 is returned; otherwise, * 0 is returned. If mech is given, credentials are acquired for the * specified mechanism. */ static int server_acquire_creds(char *service_name, gss_OID mech, gss_cred_id_t *server_creds) { gss_buffer_desc name_buf; gss_name_t server_name; OM_uint32 maj_stat, min_stat; gss_OID_set_desc mechlist; gss_OID_set mechs = GSS_C_NO_OID_SET; name_buf.value = service_name; name_buf.length = strlen(name_buf.value) + 1; maj_stat = gss_import_name(&min_stat, &name_buf, (gss_OID) gss_nt_service_name, &server_name); if (maj_stat != GSS_S_COMPLETE) { display_status("importing name", maj_stat, min_stat); return -1; } if (mech != GSS_C_NO_OID) { mechlist.count = 1; mechlist.elements = mech; mechs = &mechlist; } maj_stat = gss_acquire_cred(&min_stat, server_name, 0, mechs, GSS_C_ACCEPT, server_creds, NULL, NULL); (void) gss_release_name(&min_stat, &server_name); if (maj_stat != GSS_S_COMPLETE) { display_status("acquiring credentials", maj_stat, min_stat); return -1; } return 0; } /* * Function: server_establish_context * * Purpose: establishses a GSS-API context as a specified service with * an incoming client, and returns the context handle and associated * client name * * Arguments: * * s (r) an established TCP connection to the client * service_creds (r) server credentials, from gss_acquire_cred * context (w) the established GSS-API context * client_name (w) the client's ASCII name * * Returns: 0 on success, -1 on failure * * Effects: * * Any valid client request is accepted. If a context is established, * its handle is returned in context and the client name is returned * in client_name and 0 is returned. If unsuccessful, an error * message is displayed and -1 is returned. */ static int server_establish_context(int s, gss_cred_id_t server_creds, gss_ctx_id_t *context, gss_buffer_t client_name, OM_uint32 *ret_flags) { gss_buffer_desc send_tok, recv_tok; gss_name_t client; gss_OID doid; OM_uint32 maj_stat, min_stat, acc_sec_min_stat; gss_buffer_desc oid_name; int token_flags; if (recv_token(s, &token_flags, &recv_tok) < 0) return -1; if (recv_tok.value) { free(recv_tok.value); recv_tok.value = NULL; } if (!(token_flags & TOKEN_NOOP)) { if (logfile) fprintf(logfile, "Expected NOOP token, got %d token instead\n", token_flags); return -1; } *context = GSS_C_NO_CONTEXT; if (token_flags & TOKEN_CONTEXT_NEXT) { do { if (recv_token(s, &token_flags, &recv_tok) < 0) return -1; if (verbose && logfile) { fprintf(logfile, "Received token (size=%d): \n", (int) recv_tok.length); print_token(&recv_tok); } maj_stat = gss_accept_sec_context(&acc_sec_min_stat, context, server_creds, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &client, &doid, &send_tok, ret_flags, NULL, /* time_rec */ NULL); /* del_cred_handle */ if (recv_tok.value) { free(recv_tok.value); recv_tok.value = NULL; } if (send_tok.length != 0) { if (verbose && logfile) { fprintf(logfile, "Sending accept_sec_context token (size=%d):\n", (int) send_tok.length); print_token(&send_tok); } if (send_token(s, TOKEN_CONTEXT, &send_tok) < 0) { if (logfile) fprintf(logfile, "failure sending token\n"); return -1; } (void) gss_release_buffer(&min_stat, &send_tok); } if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { display_status("accepting context", maj_stat, acc_sec_min_stat); if (*context != GSS_C_NO_CONTEXT) gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); return -1; } if (verbose && logfile) { if (maj_stat == GSS_S_CONTINUE_NEEDED) fprintf(logfile, "continue needed...\n"); else fprintf(logfile, "\n"); fflush(logfile); } } while (maj_stat == GSS_S_CONTINUE_NEEDED); /* display the flags */ display_ctx_flags(*ret_flags); if (verbose && logfile) { maj_stat = gss_oid_to_str(&min_stat, doid, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } fprintf(logfile, "Accepted connection using mechanism OID %.*s.\n", (int) oid_name.length, (char *) oid_name.value); (void) gss_release_buffer(&min_stat, &oid_name); } maj_stat = gss_display_name(&min_stat, client, client_name, &doid); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying name", maj_stat, min_stat); return -1; } enumerateAttributes(&min_stat, client, TRUE); showLocalIdentity(&min_stat, client); maj_stat = gss_release_name(&min_stat, &client); if (maj_stat != GSS_S_COMPLETE) { display_status("releasing name", maj_stat, min_stat); return -1; } } else { client_name->length = *ret_flags = 0; if (logfile) fprintf(logfile, "Accepted unauthenticated connection.\n"); } return 0; } /* * Function: create_socket * * Purpose: Opens a listening TCP socket. * * Arguments: * * port (r) the port number on which to listen * * Returns: the listening socket file descriptor, or -1 on failure * * Effects: * * A listening socket on the specified port and created and returned. * On error, an error message is displayed and -1 is returned. */ static int create_socket(u_short port) { struct sockaddr_in saddr; int s; int on = 1; saddr.sin_family = AF_INET; saddr.sin_port = htons(port); saddr.sin_addr.s_addr = INADDR_ANY; if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("creating socket"); return -1; } /* Let the socket be reused right away */ (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)); if (bind(s, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { perror("binding socket"); (void) closesocket(s); return -1; } if (listen(s, 5) < 0) { perror("listening on socket"); (void) closesocket(s); return -1; } return s; } static float timeval_subtract(struct timeval *tv1, struct timeval *tv2) { return ((tv1->tv_sec - tv2->tv_sec) + ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000); } /* * Yes, yes, this isn't the best place for doing this test. * DO NOT REMOVE THIS UNTIL A BETTER TEST HAS BEEN WRITTEN, THOUGH. * -TYT */ static int test_import_export_context(gss_ctx_id_t *context) { OM_uint32 min_stat, maj_stat; gss_buffer_desc context_token, copied_token; struct timeval tm1, tm2; /* * Attempt to save and then restore the context. */ gettimeofday(&tm1, (struct timezone *) 0); maj_stat = gss_export_sec_context(&min_stat, context, &context_token); if (maj_stat != GSS_S_COMPLETE) { display_status("exporting context", maj_stat, min_stat); return 1; } gettimeofday(&tm2, (struct timezone *) 0); if (verbose && logfile) fprintf(logfile, "Exported context: %d bytes, %7.4f seconds\n", (int) context_token.length, timeval_subtract(&tm2, &tm1)); copied_token.length = context_token.length; copied_token.value = malloc(context_token.length); if (copied_token.value == 0) { if (logfile) fprintf(logfile, "Couldn't allocate memory to copy context token.\n"); return 1; } memcpy(copied_token.value, context_token.value, copied_token.length); maj_stat = gss_import_sec_context(&min_stat, &copied_token, context); if (maj_stat != GSS_S_COMPLETE) { display_status("importing context", maj_stat, min_stat); return 1; } free(copied_token.value); gettimeofday(&tm1, (struct timezone *) 0); if (verbose && logfile) fprintf(logfile, "Importing context: %7.4f seconds\n", timeval_subtract(&tm1, &tm2)); (void) gss_release_buffer(&min_stat, &context_token); return 0; } /* * Function: sign_server * * Purpose: Performs the "sign" service. * * Arguments: * * s (r) a TCP socket on which a connection has been * accept()ed * service_name (r) the ASCII name of the GSS-API service to * establish a context as * export (r) whether to test context exporting * * Returns: -1 on error * * Effects: * * sign_server establishes a context, and performs a single sign request. * * A sign request is a single GSS-API sealed token. The token is * unsealed and a signature block, produced with gss_sign, is returned * to the sender. The context is the destroyed and the connection * closed. * * If any error occurs, -1 is returned. */ static int sign_server(int s, gss_cred_id_t server_creds, int export) { gss_buffer_desc client_name, recv_buf, unwrap_buf, mic_buf, *msg_buf, *send_buf; gss_ctx_id_t context; OM_uint32 maj_stat, min_stat; int i, conf_state; OM_uint32 ret_flags; char *cp; int token_flags; int send_flags; /* Establish a context with the client */ if (server_establish_context(s, server_creds, &context, &client_name, &ret_flags) < 0) return (-1); if (context == GSS_C_NO_CONTEXT) { printf("Accepted unauthenticated connection.\n"); } else { printf("Accepted connection: \"%.*s\"\n", (int) client_name.length, (char *) client_name.value); (void) gss_release_buffer(&min_stat, &client_name); if (export) { for (i = 0; i < 3; i++) if (test_import_export_context(&context)) return -1; } } do { /* Receive the message token */ if (recv_token(s, &token_flags, &recv_buf) < 0) return (-1); if (token_flags & TOKEN_NOOP) { if (logfile) fprintf(logfile, "NOOP token\n"); if (recv_buf.value) { free(recv_buf.value); recv_buf.value = 0; } break; } if (verbose && logfile) { fprintf(logfile, "Message token (flags=%d):\n", token_flags); print_token(&recv_buf); } if ((context == GSS_C_NO_CONTEXT) && (token_flags & (TOKEN_WRAPPED | TOKEN_ENCRYPTED | TOKEN_SEND_MIC))) { if (logfile) fprintf(logfile, "Unauthenticated client requested authenticated services!\n"); if (recv_buf.value) { free(recv_buf.value); recv_buf.value = 0; } return (-1); } if (token_flags & TOKEN_WRAPPED) { maj_stat = gss_unwrap(&min_stat, context, &recv_buf, &unwrap_buf, &conf_state, (gss_qop_t *) NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("unsealing message", maj_stat, min_stat); if (recv_buf.value) { free(recv_buf.value); recv_buf.value = 0; } return (-1); } else if (!conf_state && (token_flags & TOKEN_ENCRYPTED)) { fprintf(stderr, "Warning! Message not encrypted.\n"); } if (recv_buf.value) { free(recv_buf.value); recv_buf.value = 0; } msg_buf = &unwrap_buf; } else { unwrap_buf.value = NULL; unwrap_buf.length = 0; msg_buf = &recv_buf; } if (logfile) { fprintf(logfile, "Received message: "); cp = msg_buf->value; if ((isprint((int) cp[0]) || isspace((int) cp[0])) && (isprint((int) cp[1]) || isspace((int) cp[1]))) { fprintf(logfile, "\"%.*s\"\n", (int) msg_buf->length, (char *) msg_buf->value); } else { fprintf(logfile, "\n"); print_token(msg_buf); } } if (token_flags & TOKEN_SEND_MIC) { /* Produce a signature block for the message */ maj_stat = gss_get_mic(&min_stat, context, GSS_C_QOP_DEFAULT, msg_buf, &mic_buf); if (maj_stat != GSS_S_COMPLETE) { display_status("signing message", maj_stat, min_stat); return (-1); } send_flags = TOKEN_MIC; send_buf = &mic_buf; } else { mic_buf.value = NULL; mic_buf.length = 0; send_flags = TOKEN_NOOP; send_buf = empty_token; } if (recv_buf.value) { free(recv_buf.value); recv_buf.value = NULL; } if (unwrap_buf.value) { gss_release_buffer(&min_stat, &unwrap_buf); } /* Send the signature block or NOOP to the client */ if (send_token(s, send_flags, send_buf) < 0) return (-1); if (mic_buf.value) { gss_release_buffer(&min_stat, &mic_buf); } } while (1 /* loop will break if NOOP received */ ); if (context != GSS_C_NO_CONTEXT) { /* Delete context */ maj_stat = gss_delete_sec_context(&min_stat, &context, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("deleting context", maj_stat, min_stat); return (-1); } } if (logfile) fflush(logfile); return (0); } static int max_threads = 1; #ifdef _WIN32 static thread_count = 0; static HANDLE hMutex = NULL; static HANDLE hEvent = NULL; void InitHandles(void) { hMutex = CreateMutex(NULL, FALSE, NULL); hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); } void CleanupHandles(void) { CloseHandle(hMutex); CloseHandle(hEvent); } BOOL WaitAndIncrementThreadCounter(void) { for (;;) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count < max_threads) { thread_count++; ReleaseMutex(hMutex); return TRUE; } else { ReleaseMutex(hMutex); if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) { continue; } else { return FALSE; } } } else { return FALSE; } } } BOOL DecrementAndSignalThreadCounter(void) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count == max_threads) ResetEvent(hEvent); thread_count--; ReleaseMutex(hMutex); return TRUE; } else { return FALSE; } } #endif struct _work_plan { int s; gss_cred_id_t server_creds; int export; }; static void worker_bee(void *param) { struct _work_plan *work = (struct _work_plan *) param; /* this return value is not checked, because there's * not really anything to do if it fails */ sign_server(work->s, work->server_creds, work->export); closesocket(work->s); free(work); #ifdef _WIN32 if (max_threads > 1) DecrementAndSignalThreadCounter(); #endif } int main(int argc, char **argv) { char *service_name; gss_cred_id_t server_creds; gss_OID mech = GSS_C_NO_OID; OM_uint32 min_stat; u_short port = 4444; int once = 0; int do_inetd = 0; int export = 0; logfile = stdout; display_file = stdout; argc--; argv++; while (argc) { if (strcmp(*argv, "-port") == 0) { argc--; argv++; if (!argc) usage(); port = atoi(*argv); } #ifdef _WIN32 else if (strcmp(*argv, "-threads") == 0) { argc--; argv++; if (!argc) usage(); max_threads = atoi(*argv); } #endif else if (strcmp(*argv, "-verbose") == 0) { verbose = 1; } else if (strcmp(*argv, "-once") == 0) { once = 1; } else if (strcmp(*argv, "-inetd") == 0) { do_inetd = 1; } else if (strcmp(*argv, "-export") == 0) { export = 1; } else if (strcmp(*argv, "-logfile") == 0) { argc--; argv++; if (!argc) usage(); /* Gross hack, but it makes it unnecessary to add an * extra argument to disable logging, and makes the code * more efficient because it doesn't actually write data * to /dev/null. */ if (!strcmp(*argv, "/dev/null")) { logfile = display_file = NULL; } else { logfile = fopen(*argv, "a"); display_file = logfile; if (!logfile) { perror(*argv); exit(1); } } } else if (strcmp(*argv, "-keytab") == 0) { argc--; argv++; if (!argc) usage(); if (krb5_gss_register_acceptor_identity(*argv)) { fprintf(stderr, "failed to register keytab\n"); exit(1); } } else if (strcmp(*argv, "-iakerb") == 0) { mech = (gss_OID)gss_mech_iakerb; } else break; argc--; argv++; } if (argc != 1) usage(); if ((*argv)[0] == '-') usage(); #ifdef _WIN32 if (max_threads < 1) { fprintf(stderr, "warning: there must be at least one thread\n"); max_threads = 1; } if (max_threads > 1 && do_inetd) fprintf(stderr, "warning: one thread may be used in conjunction with inetd\n"); InitHandles(); #endif service_name = *argv; if (server_acquire_creds(service_name, mech, &server_creds) < 0) return -1; if (do_inetd) { close(1); close(2); sign_server(0, server_creds, export); close(0); } else { int stmp; if ((stmp = create_socket(port)) >= 0) { fprintf(stderr, "starting...\n"); do { struct _work_plan *work = malloc(sizeof(struct _work_plan)); if (work == NULL) { fprintf(stderr, "fatal error: out of memory"); break; } /* Accept a TCP connection */ if ((work->s = accept(stmp, NULL, 0)) < 0) { perror("accepting connection"); free(work); continue; } work->server_creds = server_creds; work->export = export; if (max_threads == 1) { worker_bee((void *) work); } #ifdef _WIN32 else { if (WaitAndIncrementThreadCounter()) { uintptr_t handle = _beginthread(worker_bee, 0, (void *) work); if (handle == (uintptr_t) - 1) { closesocket(work->s); free(work); } } else { fprintf(stderr, "fatal error incrementing thread counter"); closesocket(work->s); free(work); break; } } #endif } while (!once); closesocket(stmp); } } (void) gss_release_cred(&min_stat, &server_creds); #ifdef _WIN32 CleanupHandles(); #endif return 0; } static void dumpAttribute(OM_uint32 *minor, gss_name_t name, gss_buffer_t attribute, int noisy) { OM_uint32 major, tmp; gss_buffer_desc value; gss_buffer_desc display_value; int authenticated = 0; int complete = 0; int more = -1; unsigned int i; while (more != 0) { value.value = NULL; display_value.value = NULL; major = gss_get_name_attribute(minor, name, attribute, &authenticated, &complete, &value, &display_value, &more); if (GSS_ERROR(major)) { display_status("gss_get_name_attribute", major, *minor); break; } printf("Attribute %.*s %s %s\n\n%.*s\n", (int)attribute->length, (char *)attribute->value, authenticated ? "Authenticated" : "", complete ? "Complete" : "", (int)display_value.length, (char *)display_value.value); if (noisy) { for (i = 0; i < value.length; i++) { if ((i % 32) == 0) printf("\n"); printf("%02x", ((char *)value.value)[i] & 0xFF); } printf("\n\n"); } gss_release_buffer(&tmp, &value); gss_release_buffer(&tmp, &display_value); } } static OM_uint32 enumerateAttributes(OM_uint32 *minor, gss_name_t name, int noisy) { OM_uint32 major, tmp; int name_is_MN; gss_OID mech = GSS_C_NO_OID; gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET; unsigned int i; major = gss_inquire_name(minor, name, &name_is_MN, &mech, &attrs); if (GSS_ERROR(major)) { display_status("gss_inquire_name", major, *minor); return major; } if (attrs != GSS_C_NO_BUFFER_SET) { for (i = 0; i < attrs->count; i++) dumpAttribute(minor, name, &attrs->elements[i], noisy); } gss_release_oid(&tmp, &mech); gss_release_buffer_set(&tmp, &attrs); return major; } static OM_uint32 showLocalIdentity(OM_uint32 *minor, gss_name_t name) { OM_uint32 major; gss_buffer_desc buf; major = gss_localname(minor, name, GSS_C_NO_OID, &buf); if (major == GSS_S_COMPLETE) printf("localname: %-*s\n", (int)buf.length, (char *)buf.value); else if (major != GSS_S_UNAVAILABLE) display_status("gss_localname", major, *minor); gss_release_buffer(minor, &buf); return major; } krb5-1.22.1/src/appl/gss-sample/gss-client.c0000664000175000017500000006604715051422640020370 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2003, 2004, 2005 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #ifdef _WIN32 #include #include #else #include #include #include #include #include #include #include #include #include #include #endif #include #include #include #include "gss-misc.h" #include "port-sockets.h" static int verbose = 1; static int spnego = 0; static gss_OID_desc gss_spnego_mechanism_oid_desc = {6, (void *)"\x2b\x06\x01\x05\x05\x02"}; static void usage(void) { fprintf(stderr, "Usage: gss-client [-port port] [-mech mechanism] " "[-spnego] [-d]\n"); fprintf(stderr, " [-seq] [-noreplay] [-nomutual] [-user user] " "[-pass pw]"); #ifdef _WIN32 fprintf(stderr, " [-threads num]"); #endif fprintf(stderr, "\n"); fprintf(stderr, " [-f] [-q] [-ccount count] [-mcount count]\n"); fprintf(stderr, " [-v1] [-na] [-nw] [-nx] [-nm] host service msg\n"); exit(1); } /* * Function: connect_to_server * * Purpose: Opens a TCP connection to the name host and port. * * Arguments: * * host (r) the target host name * port (r) the target port, in host byte order * * Returns: the established socket file descriptor, or -1 on failure * * Effects: * * The host name is resolved with gethostbyname(), and the socket is * opened and connected. If an error occurs, an error message is * displayed and -1 is returned. */ static int connect_to_server(char *host, u_short port) { struct sockaddr_in saddr; struct hostent *hp; int s; #ifdef _WIN32 WSADATA wsadata; int wsastartuperror = WSAStartup(0x202, &wsadata); if (wsastartuperror) { fprintf(stderr, "WSAStartup error: %x\n", wsastartuperror); return -1; } #endif if ((hp = gethostbyname(host)) == NULL) { fprintf(stderr, "Unknown host: %s\n", host); return -1; } saddr.sin_family = hp->h_addrtype; memcpy(&saddr.sin_addr, hp->h_addr, sizeof(saddr.sin_addr)); saddr.sin_port = htons(port); if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("creating socket"); return -1; } if (connect(s, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { perror("connecting to server"); (void) closesocket(s); return -1; } return s; } /* * Function: client_establish_context * * Purpose: establishes a GSS-API context with a specified service and * returns the context handle * * Arguments: * * s (r) an established TCP connection to the service * service_name(r) the ASCII service name of the service * gss_flags (r) GSS-API delegation flag (if any) * auth_flag (r) whether to actually do authentication * v1_format (r) whether the v1 sample protocol should be used * oid (r) OID of the mechanism to use * context (w) the established GSS-API context * ret_flags (w) the returned flags from init_sec_context * * Returns: 0 on success, -1 on failure * * Effects: * * service_name is imported as a GSS-API name and a GSS-API context is * established with the corresponding service; the service should be * listening on the TCP connection s. The default GSS-API mechanism * is used, and mutual authentication and replay detection are * requested. * * If successful, the context handle is returned in context. If * unsuccessful, the GSS-API error messages are displayed on stderr * and -1 is returned. */ static int client_establish_context(int s, char *service_name, OM_uint32 gss_flags, int auth_flag, int v1_format, gss_OID oid, char *username, char *password, gss_ctx_id_t *gss_context, OM_uint32 *ret_flags) { int result = -1, st; gss_buffer_desc send_tok, recv_tok, pwbuf, *token_ptr; gss_name_t target_name = GSS_C_NO_NAME, gss_username = GSS_C_NO_NAME; OM_uint32 maj_stat, min_stat, init_sec_min_stat; int token_flags; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; gss_OID_set_desc mechs, neg_mechs, *mechsp = GSS_C_NO_OID_SET; if (!auth_flag) return send_token(s, TOKEN_NOOP, empty_token); if (spnego) { mechs.elements = &gss_spnego_mechanism_oid_desc; mechs.count = 1; mechsp = &mechs; } else if (oid != GSS_C_NO_OID) { mechs.elements = oid; mechs.count = 1; mechsp = &mechs; } else { mechs.elements = NULL; mechs.count = 0; } if (username != NULL) { send_tok.value = username; send_tok.length = strlen(username); maj_stat = gss_import_name(&min_stat, &send_tok, (gss_OID) gss_nt_user_name, &gss_username); if (maj_stat != GSS_S_COMPLETE) { display_status("parsing client name", maj_stat, min_stat); goto cleanup; } } if (password != NULL) { pwbuf.value = password; pwbuf.length = strlen(password); maj_stat = gss_acquire_cred_with_password(&min_stat, gss_username, &pwbuf, 0, mechsp, GSS_C_INITIATE, &cred, NULL, NULL); } else if (gss_username != GSS_C_NO_NAME) { maj_stat = gss_acquire_cred(&min_stat, gss_username, 0, mechsp, GSS_C_INITIATE, &cred, NULL, NULL); } else { maj_stat = GSS_S_COMPLETE; } if (maj_stat != GSS_S_COMPLETE) { display_status("acquiring creds", maj_stat, min_stat); goto cleanup; } if (spnego && oid != GSS_C_NO_OID) { neg_mechs.elements = oid; neg_mechs.count = 1; maj_stat = gss_set_neg_mechs(&min_stat, cred, &neg_mechs); if (maj_stat != GSS_S_COMPLETE) { display_status("setting neg mechs", maj_stat, min_stat); goto cleanup; } } /* Import the name into target_name. Use send_tok to save local variable * space. */ send_tok.value = service_name; send_tok.length = strlen(service_name); maj_stat = gss_import_name(&min_stat, &send_tok, (gss_OID) gss_nt_service_name, &target_name); if (maj_stat != GSS_S_COMPLETE) { display_status("parsing name", maj_stat, min_stat); goto cleanup; } if (!v1_format) { if (send_token(s, TOKEN_NOOP | TOKEN_CONTEXT_NEXT, empty_token) < 0) goto cleanup; } /* * Perform the context-establishment loop. * * On each pass through the loop, token_ptr points to the token to send to * the server (or GSS_C_NO_BUFFER on the first pass). Every generated * token is stored in send_tok which is then transmitted to the server; * every received token is stored in recv_tok, which token_ptr is then set * to, to be processed by the next call to gss_init_sec_context. * * GSS-API guarantees that send_tok's length will be non-zero if and only * if the server is expecting another token from us, and that * gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if and only if the * server has another token to send us. */ token_ptr = GSS_C_NO_BUFFER; *gss_context = GSS_C_NO_CONTEXT; do { maj_stat = gss_init_sec_context(&init_sec_min_stat, cred, gss_context, target_name, mechs.elements, gss_flags, 0, NULL, token_ptr, NULL, &send_tok, ret_flags, NULL); if (token_ptr != GSS_C_NO_BUFFER) free(recv_tok.value); if (send_tok.length > 0) { if (verbose) { printf("Sending init_sec_context token (size=%d)...", (int) send_tok.length); } st = send_token(s, v1_format ? 0 : TOKEN_CONTEXT, &send_tok); (void) gss_release_buffer(&min_stat, &send_tok); if (st < 0) goto cleanup; } if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { display_status("initializing context", maj_stat, init_sec_min_stat); goto cleanup; } if (maj_stat == GSS_S_CONTINUE_NEEDED) { if (verbose) printf("continue needed..."); if (recv_token(s, &token_flags, &recv_tok) < 0) goto cleanup; token_ptr = &recv_tok; } if (verbose) printf("\n"); } while (maj_stat == GSS_S_CONTINUE_NEEDED); result = 0; cleanup: (void) gss_release_name(&min_stat, &gss_username); (void) gss_release_cred(&min_stat, &cred); (void) gss_release_name(&min_stat, &target_name); return result; } static void read_file(char *file_name, gss_buffer_t in_buf) { int fd, count; struct stat stat_buf; if ((fd = open(file_name, O_RDONLY, 0)) < 0) { perror("open"); fprintf(stderr, "Couldn't open file %s\n", file_name); exit(1); } if (fstat(fd, &stat_buf) < 0) { perror("fstat"); exit(1); } in_buf->length = stat_buf.st_size; if (in_buf->length == 0) { in_buf->value = NULL; return; } if ((in_buf->value = malloc(in_buf->length)) == 0) { fprintf(stderr, "Couldn't allocate %d byte buffer for reading file\n", (int) in_buf->length); exit(1); } /* this code used to check for incomplete reads, but you can't get * an incomplete read on any file for which fstat() is meaningful */ count = read(fd, in_buf->value, in_buf->length); if (count < 0) { perror("read"); exit(1); } if (count < (int)in_buf->length) fprintf(stderr, "Warning, only read in %d bytes, expected %d\n", count, (int) in_buf->length); } /* * Function: call_server * * Purpose: Call the "sign" service. * * Arguments: * * host (r) the host providing the service * port (r) the port to connect to on host * service_name (r) the GSS-API service name to authenticate to * gss_flags (r) GSS-API delegation flag (if any) * auth_flag (r) whether to do authentication * wrap_flag (r) whether to do message wrapping at all * encrypt_flag (r) whether to do encryption while wrapping * mic_flag (r) whether to request a MIC from the server * msg (r) the message to have "signed" * use_file (r) whether to treat msg as an input file name * mcount (r) the number of times to send the message * * Returns: 0 on success, -1 on failure * * Effects: * * call_server opens a TCP connection to and establishes a * GSS-API context with service_name over the connection. It then * seals msg in a GSS-API token with gss_wrap, sends it to the server, * reads back a GSS-API signature block for msg from the server, and * verifies it with gss_verify. -1 is returned if any step fails, * otherwise 0 is returned. */ static int call_server(char *host, u_short port, gss_OID oid, char *service_name, OM_uint32 gss_flags, int auth_flag, int wrap_flag, int encrypt_flag, int mic_flag, int v1_format, char *msg, int use_file, int mcount, char *username, char *password) { gss_ctx_id_t context = GSS_C_NO_CONTEXT; gss_buffer_desc in_buf, out_buf; int s = -1, result = -1, state; OM_uint32 ret_flags; OM_uint32 maj_stat, min_stat; gss_name_t src_name = GSS_C_NO_NAME, targ_name = GSS_C_NO_NAME; gss_buffer_desc sname = GSS_C_EMPTY_BUFFER, tname = GSS_C_EMPTY_BUFFER; OM_uint32 lifetime; gss_OID mechanism, name_type; int is_local; OM_uint32 context_flags; int is_open; gss_qop_t qop_state; gss_OID_set mech_names; gss_buffer_desc oid_name; size_t i; int token_flags; /* Open connection */ if ((s = connect_to_server(host, port)) < 0) goto cleanup; /* Establish context */ if (client_establish_context(s, service_name, gss_flags, auth_flag, v1_format, oid, username, password, &context, &ret_flags) < 0) { goto cleanup; } if (auth_flag && verbose) { /* display the flags */ display_ctx_flags(ret_flags); /* Get context information */ maj_stat = gss_inquire_context(&min_stat, context, &src_name, &targ_name, &lifetime, &mechanism, &context_flags, &is_local, &is_open); if (maj_stat != GSS_S_COMPLETE) { display_status("inquiring context", maj_stat, min_stat); goto cleanup; } maj_stat = gss_display_name(&min_stat, src_name, &sname, &name_type); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying source name", maj_stat, min_stat); goto cleanup; } maj_stat = gss_display_name(&min_stat, targ_name, &tname, (gss_OID *) NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying target name", maj_stat, min_stat); goto cleanup; } printf("\"%.*s\" to \"%.*s\", lifetime %d, flags %x, %s, %s\n", (int) sname.length, (char *) sname.value, (int) tname.length, (char *) tname.value, lifetime, context_flags, (is_local) ? "locally initiated" : "remotely initiated", (is_open) ? "open" : "closed"); maj_stat = gss_oid_to_str(&min_stat, name_type, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); goto cleanup; } printf("Name type of source name is %.*s.\n", (int) oid_name.length, (char *) oid_name.value); (void) gss_release_buffer(&min_stat, &oid_name); /* Now get the names supported by the mechanism */ maj_stat = gss_inquire_names_for_mech(&min_stat, mechanism, &mech_names); if (maj_stat != GSS_S_COMPLETE) { display_status("inquiring mech names", maj_stat, min_stat); goto cleanup; } maj_stat = gss_oid_to_str(&min_stat, mechanism, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); goto cleanup; } printf("Mechanism %.*s supports %d names\n", (int) oid_name.length, (char *) oid_name.value, (int) mech_names->count); (void) gss_release_buffer(&min_stat, &oid_name); for (i = 0; i < mech_names->count; i++) { maj_stat = gss_oid_to_str(&min_stat, &mech_names->elements[i], &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); goto cleanup; } printf(" %d: %.*s\n", (int) i, (int) oid_name.length, (char *) oid_name.value); (void) gss_release_buffer(&min_stat, &oid_name); } (void) gss_release_oid_set(&min_stat, &mech_names); } if (use_file) { read_file(msg, &in_buf); } else { /* Seal the message */ in_buf.value = msg; in_buf.length = strlen((char *)in_buf.value); } for (i = 0; i < (size_t)mcount; i++) { if (wrap_flag) { maj_stat = gss_wrap(&min_stat, context, encrypt_flag, GSS_C_QOP_DEFAULT, &in_buf, &state, &out_buf); if (maj_stat != GSS_S_COMPLETE) { display_status("wrapping message", maj_stat, min_stat); goto cleanup; } else if (encrypt_flag && !state) { fprintf(stderr, "Warning! Message not encrypted.\n"); } } else { out_buf = in_buf; } /* Send to server */ if (send_token(s, (v1_format ? 0 : (TOKEN_DATA | (wrap_flag ? TOKEN_WRAPPED : 0) | (encrypt_flag ? TOKEN_ENCRYPTED : 0) | (mic_flag ? TOKEN_SEND_MIC : 0))), &out_buf) < 0) goto cleanup; if (out_buf.value != in_buf.value) (void) gss_release_buffer(&min_stat, &out_buf); /* Read signature block into out_buf */ if (recv_token(s, &token_flags, &out_buf) < 0) goto cleanup; if (mic_flag) { /* Verify signature block */ maj_stat = gss_verify_mic(&min_stat, context, &in_buf, &out_buf, &qop_state); if (maj_stat != GSS_S_COMPLETE) { display_status("verifying signature", maj_stat, min_stat); goto cleanup; } if (verbose) printf("Signature verified.\n"); } else { if (verbose) printf("Response received.\n"); } free(out_buf.value); } if (use_file) free(in_buf.value); /* Send NOOP */ if (!v1_format) (void) send_token(s, TOKEN_NOOP, empty_token); result = 0; cleanup: (void) gss_release_name(&min_stat, &src_name); (void) gss_release_name(&min_stat, &targ_name); (void) gss_release_buffer(&min_stat, &sname); (void) gss_release_buffer(&min_stat, &tname); (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); if (s >= 0) (void) closesocket(s); return result; } static void parse_oid(char *mechanism, gss_OID * oid) { char *mechstr = 0; gss_buffer_desc tok; OM_uint32 maj_stat, min_stat; size_t i, mechlen = strlen(mechanism); if (isdigit((int) mechanism[0])) { mechstr = malloc(mechlen + 5); if (!mechstr) { fprintf(stderr, "Couldn't allocate mechanism scratch!\n"); return; } mechstr[0] = '{'; mechstr[1] = ' '; for (i = 0; i < mechlen; i++) mechstr[i + 2] = (mechanism[i] == '.') ? ' ' : mechanism[i]; mechstr[mechlen + 2] = ' '; mechstr[mechlen + 3] = ' '; mechstr[mechlen + 4] = '\0'; tok.value = mechstr; } else tok.value = mechanism; tok.length = strlen(tok.value); maj_stat = gss_str_to_oid(&min_stat, &tok, oid); if (maj_stat != GSS_S_COMPLETE) { display_status("str_to_oid", maj_stat, min_stat); return; } if (mechstr) free(mechstr); } static int max_threads = 1; #ifdef _WIN32 static thread_count = 0; static HANDLE hMutex = NULL; static HANDLE hEvent = NULL; void InitHandles(void) { hMutex = CreateMutex(NULL, FALSE, NULL); hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); } void CleanupHandles(void) { CloseHandle(hMutex); CloseHandle(hEvent); } BOOL WaitAndIncrementThreadCounter(void) { for (;;) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count < max_threads) { thread_count++; ReleaseMutex(hMutex); return TRUE; } else { ReleaseMutex(hMutex); if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) { continue; } else { return FALSE; } } } else { return FALSE; } } } BOOL DecrementAndSignalThreadCounter(void) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count == max_threads) ResetEvent(hEvent); thread_count--; ReleaseMutex(hMutex); return TRUE; } else { return FALSE; } } #endif static char *service_name, *server_host, *msg; static char *mechanism = 0; static u_short port = 4444; static int use_file = 0; static OM_uint32 gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; static OM_uint32 min_stat; static gss_OID oid = GSS_C_NULL_OID; static int mcount = 1, ccount = 1; static int auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format; static char *username = NULL; static char *password = NULL; static void worker_bee(void *unused) { if (call_server(server_host, port, oid, service_name, gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format, msg, use_file, mcount, username, password) < 0) exit(1); #ifdef _WIN32 if (max_threads > 1) DecrementAndSignalThreadCounter(); #endif } int main(int argc, char **argv) { int i; display_file = stdout; auth_flag = wrap_flag = encrypt_flag = mic_flag = 1; v1_format = 0; /* Parse arguments. */ argc--; argv++; while (argc) { if (strcmp(*argv, "-port") == 0) { argc--; argv++; if (!argc) usage(); port = atoi(*argv); } else if (strcmp(*argv, "-mech") == 0) { argc--; argv++; if (!argc) usage(); mechanism = *argv; } else if (strcmp(*argv, "-user") == 0) { argc--; argv++; if (!argc) usage(); username = *argv; } else if (strcmp(*argv, "-pass") == 0) { argc--; argv++; if (!argc) usage(); password = *argv; } else if (strcmp(*argv, "-iakerb") == 0) { mechanism = "{ 1 3 6 1 5 2 5 }"; } else if (strcmp(*argv, "-spnego") == 0) { spnego = 1; } else if (strcmp(*argv, "-krb5") == 0) { mechanism = "{ 1 2 840 113554 1 2 2 }"; #ifdef _WIN32 } else if (strcmp(*argv, "-threads") == 0) { argc--; argv++; if (!argc) usage(); max_threads = atoi(*argv); #endif } else if (strcmp(*argv, "-dce") == 0) { gss_flags |= GSS_C_DCE_STYLE; } else if (strcmp(*argv, "-d") == 0) { gss_flags |= GSS_C_DELEG_FLAG; } else if (strcmp(*argv, "-seq") == 0) { gss_flags |= GSS_C_SEQUENCE_FLAG; } else if (strcmp(*argv, "-noreplay") == 0) { gss_flags &= ~GSS_C_REPLAY_FLAG; } else if (strcmp(*argv, "-nomutual") == 0) { gss_flags &= ~GSS_C_MUTUAL_FLAG; } else if (strcmp(*argv, "-f") == 0) { use_file = 1; } else if (strcmp(*argv, "-q") == 0) { verbose = 0; } else if (strcmp(*argv, "-ccount") == 0) { argc--; argv++; if (!argc) usage(); ccount = atoi(*argv); if (ccount <= 0) usage(); } else if (strcmp(*argv, "-mcount") == 0) { argc--; argv++; if (!argc) usage(); mcount = atoi(*argv); if (mcount < 0) usage(); } else if (strcmp(*argv, "-na") == 0) { auth_flag = wrap_flag = encrypt_flag = mic_flag = 0; } else if (strcmp(*argv, "-nw") == 0) { wrap_flag = 0; } else if (strcmp(*argv, "-nx") == 0) { encrypt_flag = 0; } else if (strcmp(*argv, "-nm") == 0) { mic_flag = 0; } else if (strcmp(*argv, "-v1") == 0) { v1_format = 1; } else break; argc--; argv++; } if (argc != 3) usage(); #ifdef _WIN32 if (max_threads < 1) { fprintf(stderr, "warning: there must be at least one thread\n"); max_threads = 1; } #endif server_host = *argv++; service_name = *argv++; msg = *argv++; if (mechanism) parse_oid(mechanism, &oid); if (max_threads == 1) { for (i = 0; i < ccount; i++) { worker_bee(0); } } else { #ifdef _WIN32 for (i = 0; i < ccount; i++) { if (WaitAndIncrementThreadCounter()) { uintptr_t handle = _beginthread(worker_bee, 0, (void *) 0); if (handle == (uintptr_t) - 1) { exit(1); } } else { exit(1); } } #else /* boom */ assert(max_threads == 1); #endif } if (oid != GSS_C_NULL_OID) (void) gss_release_oid(&min_stat, &oid); #ifdef _WIN32 CleanupHandles(); #endif return 0; } krb5-1.22.1/src/appl/simple/0000775000175000017500000000000015051422640015355 5ustar ghudsonghudsonkrb5-1.22.1/src/appl/simple/Makefile.in0000664000175000017500000000021015051422640017413 0ustar ghudsonghudsonmydir=appl$(S)simple SUBDIRS = client server BUILDTOP=$(REL)..$(S).. check-pytests: $(RUNPYTEST) $(srcdir)/t_simple.py $(PYTESTFLAGS) krb5-1.22.1/src/appl/simple/client/0000775000175000017500000000000015051422640016633 5ustar ghudsonghudsonkrb5-1.22.1/src/appl/simple/client/Makefile.in0000664000175000017500000000051315051422640020677 0ustar ghudsonghudsonmydir=appl$(S)simple$(S)client BUILDTOP=$(REL)..$(S)..$(S).. all: sim_client LOCALINCLUDES= -I$(srcdir)/.. sim_client: sim_client.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o sim_client sim_client.o $(KRB5_BASE_LIBS) install: $(INSTALL_PROGRAM) sim_client $(DESTDIR)$(CLIENT_BINDIR)/sim_client clean: $(RM) sim_client.o sim_client krb5-1.22.1/src/appl/simple/client/deps0000664000175000017500000000003015051422640017502 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/appl/simple/client/sim_client.c0000664000175000017500000002100615051422640021124 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* appl/simple/client/sim_client.c */ /* * Copyright 1989,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Simple UDP-based sample client program. For demonstration. * This program performs no useful function. */ #include #include "com_err.h" #include #include #include #include #include #include #include #include #include "simple.h" /* for old Unixes and friends ... */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif #define MSG "hi there!" /* message text */ void usage (char *); void usage(char *name) { fprintf(stderr, "usage: %s [-p port] [-h host] [-m message] [-s service] [host]\n", name); } int main(int argc, char *argv[]) { int sock, i; socklen_t len; int flags = 0; /* flags for sendto() */ struct servent *serv; struct hostent *host; #ifdef BROKEN_STREAMS_SOCKETS char my_hostname[MAXHOSTNAMELEN]; #endif struct sockaddr_in s_sock; /* server address */ struct sockaddr_in c_sock; /* client address */ extern int opterr, optind; extern char * optarg; int ch; short port = 0; char *message = MSG; char *hostname = 0; char *service = SIMPLE_SERVICE; char *progname = 0; krb5_error_code retval; krb5_data packet, inbuf; krb5_ccache ccdef; krb5_address addr; krb5_context context; krb5_auth_context auth_context = NULL; retval = krb5_init_context(&context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } progname = argv[0]; /* * Parse command line arguments * */ opterr = 0; while ((ch = getopt(argc, argv, "p:m:h:s:")) != -1) switch (ch) { case 'p': port = atoi(optarg); break; case 'm': message = optarg; break; case 'h': hostname = optarg; break; case 's': service = optarg; break; case '?': default: usage(progname); exit(1); break; } argc -= optind; argv += optind; if (argc > 0) { if (hostname) usage(progname); hostname = argv[0]; } if (hostname == 0) { fprintf(stderr, "You must specify a hostname to contact.\n\n"); usage(progname); exit(1); } /* Look up server host */ if ((host = gethostbyname(hostname)) == (struct hostent *) 0) { fprintf(stderr, "%s: unknown host\n", hostname); exit(1); } /* Set server's address */ (void) memset(&s_sock, 0, sizeof(s_sock)); memcpy(&s_sock.sin_addr, host->h_addr, sizeof(s_sock.sin_addr)); #ifdef DEBUG printf("s_sock.sin_addr is %s\n", inet_ntoa(s_sock.sin_addr)); #endif s_sock.sin_family = AF_INET; if (port == 0) { /* Look up service */ if ((serv = getservbyname(SIMPLE_PORT, "udp")) == NULL) { fprintf(stderr, "service unknown: %s/udp\n", SIMPLE_PORT); exit(1); } s_sock.sin_port = serv->s_port; } else { s_sock.sin_port = htons(port); } /* Open a socket */ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { com_err(progname, errno, "opening datagram socket"); exit(1); } memset(&c_sock, 0, sizeof(c_sock)); c_sock.sin_family = AF_INET; #ifdef BROKEN_STREAMS_SOCKETS if (gethostname(my_hostname, sizeof(my_hostname)) < 0) { perror("gethostname"); exit(1); } if ((host = gethostbyname(my_hostname)) == (struct hostent *)0) { fprintf(stderr, "%s: unknown host\n", hostname); exit(1); } memcpy(&c_sock.sin_addr, host->h_addr, sizeof(c_sock.sin_addr)); #endif /* Bind it to set the address; kernel will fill in port # */ if (bind(sock, (struct sockaddr *)&c_sock, sizeof(c_sock)) < 0) { com_err(progname, errno, "while binding datagram socket"); exit(1); } /* PREPARE KRB_AP_REQ MESSAGE */ inbuf.data = hostname; inbuf.length = strlen(hostname); /* Get credentials for server */ if ((retval = krb5_cc_default(context, &ccdef))) { com_err(progname, retval, "while getting default ccache"); exit(1); } retval = krb5_mk_req(context, &auth_context, AP_OPTS_USE_SUBKEY, service, hostname, &inbuf, ccdef, &packet); if (retval) { com_err(progname, retval, "while preparing AP_REQ"); exit(1); } printf("Got credentials for %s.\n", service); /* "connect" the datagram socket; this is necessary to get a local address properly bound for getsockname() below. */ if (connect(sock, (struct sockaddr *)&s_sock, sizeof(s_sock)) == -1) { com_err(progname, errno, "while connecting to server"); exit(1); } /* Send authentication info to server */ if ((i = send(sock, (char *)packet.data, (unsigned) packet.length, flags)) < 0) com_err(progname, errno, "while sending KRB_AP_REQ message"); printf("Sent authentication data: %d bytes\n", i); krb5_free_data_contents(context, &packet); /* PREPARE KRB_SAFE MESSAGE */ /* Get my address */ memset(&c_sock, 0, sizeof(c_sock)); len = sizeof(c_sock); if (getsockname(sock, (struct sockaddr *)&c_sock, &len) < 0) { com_err(progname, errno, "while getting socket name"); exit(1); } addr.addrtype = ADDRTYPE_IPPORT; addr.length = sizeof(c_sock.sin_port); addr.contents = (krb5_octet *)&c_sock.sin_port; if ((retval = krb5_auth_con_setports(context, auth_context, &addr, NULL))) { com_err(progname, retval, "while setting local port\n"); exit(1); } addr.addrtype = ADDRTYPE_INET; addr.length = sizeof(c_sock.sin_addr); addr.contents = (krb5_octet *)&c_sock.sin_addr; if ((retval = krb5_auth_con_setaddrs(context, auth_context, &addr, NULL))) { com_err(progname, retval, "while setting local addr\n"); exit(1); } /* Make the safe message */ inbuf.data = message; inbuf.length = strlen(message); if ((retval = krb5_mk_safe(context, auth_context, &inbuf, &packet, NULL))){ com_err(progname, retval, "while making KRB_SAFE message"); exit(1); } /* Send it */ if ((i = send(sock, (char *)packet.data, (unsigned) packet.length, flags)) < 0) com_err(progname, errno, "while sending SAFE message"); printf("Sent checksummed message: %d bytes\n", i); krb5_free_data_contents(context, &packet); /* PREPARE KRB_PRIV MESSAGE */ /* Make the encrypted message */ if ((retval = krb5_mk_priv(context, auth_context, &inbuf, &packet, NULL))) { com_err(progname, retval, "while making KRB_PRIV message"); exit(1); } /* Send it */ if ((i = send(sock, (char *)packet.data, (unsigned) packet.length, flags)) < 0) com_err(progname, errno, "while sending PRIV message"); printf("Sent encrypted message: %d bytes\n", i); krb5_free_data_contents(context, &packet); krb5_auth_con_free(context, auth_context); krb5_free_context(context); exit(0); } krb5-1.22.1/src/appl/simple/t_simple.py0000664000175000017500000000237515051422640017552 0ustar ghudsonghudsonfrom k5test import * sim_client = os.path.join(buildtop, 'appl', 'simple', 'client', 'sim_client') sim_server = os.path.join(buildtop, 'appl', 'simple', 'server', 'sim_server') for realm in multipass_realms(create_host=False): server_princ = 'sample/%s@%s' % (hostname, realm.realm) realm.addprinc(server_princ) realm.extract_keytab(server_princ, realm.keytab) portstr = str(realm.server_port()) server = realm.start_server([sim_server, '-p', portstr], 'starting...') out = realm.run([sim_client, '-p', portstr, hostname]) if ('Sent checksummed message:' not in out or 'Sent encrypted message:' not in out): fail('Expected client messages not seen') # sim_server exits after one client execution, so we can read # until it closes stdout. seen1 = seen2 = seen3 = False for line in server.stdout: if line == 'Got authentication info from user@KRBTEST.COM\n': seen1 = True if line == "Safe message is: 'hi there!'\n": seen2 = True if line == "Decrypted message is: 'hi there!'\n": seen3 = True if not (seen1 and seen2 and seen3): fail('Expected server messages not seen') await_daemon_exit(server) success('sim_client/sim_server tests') krb5-1.22.1/src/appl/simple/deps0000664000175000017500000000003015051422640016224 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/appl/simple/server/0000775000175000017500000000000015051422640016663 5ustar ghudsonghudsonkrb5-1.22.1/src/appl/simple/server/Makefile.in0000664000175000017500000000051315051422640020727 0ustar ghudsonghudsonmydir=appl$(S)simple$(S)server BUILDTOP=$(REL)..$(S)..$(S).. LOCALINCLUDES= -I$(srcdir)/.. all: sim_server sim_server: sim_server.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o sim_server sim_server.o $(KRB5_BASE_LIBS) install: $(INSTALL_PROGRAM) sim_server $(DESTDIR)$(SERVER_BINDIR)/sim_server clean: $(RM) sim_server.o sim_server krb5-1.22.1/src/appl/simple/server/deps0000664000175000017500000000003015051422640017532 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/appl/simple/server/sim_server.c0000664000175000017500000001777515051422640021226 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* appl/simple/server/sim_server.c */ /* * Copyright 1989,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Usage: * sample_server servername * * Simple UDP-based server application. For demonstration. * This program performs no useful function. */ #include "krb5.h" #include "port-sockets.h" #include #include #include #include #include #include #include #include #include #include "com_err.h" #include "simple.h" /* for old Unixes and friends ... */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif #define PROGNAME argv[0] static void usage(char *name) { fprintf(stderr, "usage: %s [-p port] [-s service] [-S keytab]\n", name); } int main(int argc, char *argv[]) { int sock, i; socklen_t len; int flags = 0; /* for recvfrom() */ int on = 1; struct servent *serv; struct sockaddr_in s_sock; /* server's address */ struct sockaddr_in c_sock; /* client's address */ char *cp; extern char * optarg; int ch; short port = 0; /* If user specifies port */ krb5_keytab keytab = NULL; /* Allow specification on command line */ char *service = SIMPLE_SERVICE; krb5_error_code retval; krb5_data packet, message; unsigned char pktbuf[BUFSIZ]; krb5_principal sprinc; krb5_context context; krb5_auth_context auth_context = NULL; krb5_address addr; krb5_ticket *ticket = NULL; retval = krb5_init_context(&context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } /* * Parse command line arguments * */ while ((ch = getopt(argc, argv, "p:s:S:")) != -1) { switch (ch) { case 'p': port = atoi(optarg); break; case 's': service = optarg; break; case 'S': if ((retval = krb5_kt_resolve(context, optarg, &keytab))) { com_err(PROGNAME, retval, "while resolving keytab file %s", optarg); exit(2); } break; case '?': default: usage(PROGNAME); exit(1); break; } } if ((retval = krb5_sname_to_principal(context, NULL, service, KRB5_NT_SRV_HST, &sprinc))) { com_err(PROGNAME, retval, "while generating service name %s", service); exit(1); } /* Set up server address */ memset(&s_sock, 0, sizeof(s_sock)); s_sock.sin_family = AF_INET; s_sock.sin_addr.s_addr = INADDR_ANY; if (port == 0) { /* Look up service */ if ((serv = getservbyname(SIMPLE_PORT, "udp")) == NULL) { fprintf(stderr, "service unknown: %s/udp\n", SIMPLE_PORT); exit(1); } s_sock.sin_port = serv->s_port; } else { s_sock.sin_port = htons(port); } /* Open socket */ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("opening datagram socket"); exit(1); } /* Let the socket be reused right away */ (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); /* Bind the socket */ if (bind(sock, (struct sockaddr *)&s_sock, sizeof(s_sock))) { perror("binding datagram socket"); exit(1); } printf("starting...\n"); fflush(stdout); #ifdef DEBUG printf("socket has port # %d\n", ntohs(s_sock.sin_port)); #endif /* GET KRB_AP_REQ MESSAGE */ /* use "recvfrom" so we know client's address */ len = sizeof(struct sockaddr_in); if ((i = recvfrom(sock, (char *)pktbuf, sizeof(pktbuf), flags, (struct sockaddr *)&c_sock, &len)) < 0) { perror("receiving datagram"); exit(1); } printf("Received %d bytes\n", i); packet.length = i; packet.data = (krb5_pointer) pktbuf; /* Check authentication info */ if ((retval = krb5_rd_req(context, &auth_context, &packet, sprinc, keytab, NULL, &ticket))) { com_err(PROGNAME, retval, "while reading request"); exit(1); } if ((retval = krb5_unparse_name(context, ticket->enc_part2->client, &cp))) { com_err(PROGNAME, retval, "while unparsing client name"); exit(1); } printf("Got authentication info from %s\n", cp); free(cp); /* Set foreign_addr for rd_safe() and rd_priv() */ addr.addrtype = ADDRTYPE_INET; addr.length = sizeof(c_sock.sin_addr); addr.contents = (krb5_octet *)&c_sock.sin_addr; if ((retval = krb5_auth_con_setaddrs(context, auth_context, NULL, &addr))) { com_err(PROGNAME, retval, "while setting foreign addr"); exit(1); } addr.addrtype = ADDRTYPE_IPPORT; addr.length = sizeof(c_sock.sin_port); addr.contents = (krb5_octet *)&c_sock.sin_port; if ((retval = krb5_auth_con_setports(context, auth_context, NULL, &addr))) { com_err(PROGNAME, retval, "while setting foreign port"); exit(1); } /* GET KRB_MK_SAFE MESSAGE */ /* use "recvfrom" so we know client's address */ len = sizeof(struct sockaddr_in); if ((i = recvfrom(sock, (char *)pktbuf, sizeof(pktbuf), flags, (struct sockaddr *)&c_sock, &len)) < 0) { perror("receiving datagram"); exit(1); } #ifdef DEBUG printf("&c_sock.sin_addr is %s\n", inet_ntoa(c_sock.sin_addr)); #endif printf("Received %d bytes\n", i); packet.length = i; packet.data = (krb5_pointer) pktbuf; if ((retval = krb5_rd_safe(context, auth_context, &packet, &message, NULL))) { com_err(PROGNAME, retval, "while verifying SAFE message"); exit(1); } printf("Safe message is: '%.*s'\n", (int) message.length, message.data); krb5_free_data_contents(context, &message); /* NOW GET ENCRYPTED MESSAGE */ /* use "recvfrom" so we know client's address */ len = sizeof(struct sockaddr_in); if ((i = recvfrom(sock, (char *)pktbuf, sizeof(pktbuf), flags, (struct sockaddr *)&c_sock, &len)) < 0) { perror("receiving datagram"); exit(1); } printf("Received %d bytes\n", i); packet.length = i; packet.data = (krb5_pointer) pktbuf; if ((retval = krb5_rd_priv(context, auth_context, &packet, &message, NULL))) { com_err(PROGNAME, retval, "while verifying PRIV message"); exit(1); } printf("Decrypted message is: '%.*s'\n", (int) message.length, message.data); krb5_auth_con_free(context, auth_context); krb5_free_context(context); exit(0); } krb5-1.22.1/src/appl/simple/simple.h0000664000175000017500000000271615051422640017025 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* appl/simple/simple.h */ /* * Copyright 1988,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Common definitions for the simple UDP-based Kerberos-mediated * server & client applications. */ #define SIMPLE_SERVICE "sample" #define SIMPLE_PORT "sample" krb5-1.22.1/src/appl/sample/0000775000175000017500000000000015051422640015345 5ustar ghudsonghudsonkrb5-1.22.1/src/appl/sample/sample.h0000664000175000017500000000275515051422640017010 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* appl/sample/sample.h - Common declarations for sample client/server */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef KRB5_SAMPLE__ #define KRB5_SAMPLE__ #define SAMPLE_SERVICE "sample" #define SAMPLE_PORT "sample" #define SAMPLE_VERSION "KRB5_sample_protocol_v1.0" #endif /* KRB5_SAMPLE__ */ krb5-1.22.1/src/appl/sample/Makefile.in0000664000175000017500000000021215051422640017405 0ustar ghudsonghudsonmydir=appl$(S)sample SUBDIRS = sclient sserver BUILDTOP=$(REL)..$(S).. check-pytests: $(RUNPYTEST) $(srcdir)/t_sample.py $(PYTESTFLAGS) krb5-1.22.1/src/appl/sample/sserver/0000775000175000017500000000000015051422640017036 5ustar ghudsonghudsonkrb5-1.22.1/src/appl/sample/sserver/Makefile.in0000664000175000017500000000042215051422640021101 0ustar ghudsonghudsonmydir=appl$(S)sample$(S)sserver BUILDTOP=$(REL)..$(S)..$(S).. all: sserver sserver: sserver.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o sserver sserver.o $(KRB5_BASE_LIBS) clean: $(RM) sserver.o sserver install: $(INSTALL_PROGRAM) sserver ${DESTDIR}$(SERVER_BINDIR)/sserver krb5-1.22.1/src/appl/sample/sserver/deps0000664000175000017500000000003015051422640017705 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/appl/sample/sserver/sserver.c0000664000175000017500000001635415051422640020704 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* appl/sample/sserver/sserver.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Sample Kerberos v5 server. * * sample_server: * A sample Kerberos server, which reads an AP_REQ from a TCP socket, * decodes it, and writes back the results (in ASCII) to the client. * * Usage: * sample_server servername * * file descriptor 0 (zero) should be a socket connected to the requesting * client (this will be correct if this server is started by inetd). */ #include "k5-int.h" #include "com_err.h" #include #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "../sample.h" extern krb5_deltat krb5_clockskew; #ifndef GETPEERNAME_ARG3_TYPE #define GETPEERNAME_ARG3_TYPE int #endif static void usage(char *name) { fprintf(stderr, "usage: %s [-p port] [-s service] [-S keytab]\n", name); } int main(int argc, char *argv[]) { krb5_context context; krb5_auth_context auth_context = NULL; krb5_ticket * ticket; struct sockaddr_in peername; GETPEERNAME_ARG3_TYPE namelen = sizeof(peername); int sock = -1; /* incoming connection fd */ krb5_data recv_data; short xmitlen; krb5_error_code retval; krb5_principal server; char repbuf[BUFSIZ]; char *cname; char *service = SAMPLE_SERVICE; short port = 0; /* If user specifies port */ extern int opterr, optind; extern char * optarg; int ch; krb5_keytab keytab = NULL; /* Allow specification on command line */ char *progname; int on = 1; progname = *argv; retval = krb5_init_context(&context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } /* open a log connection */ openlog("sserver", 0, LOG_DAEMON); /* * Parse command line arguments * */ opterr = 0; while ((ch = getopt(argc, argv, "p:S:s:")) != -1) { switch (ch) { case 'p': port = atoi(optarg); break; case 's': service = optarg; break; case 'S': if ((retval = krb5_kt_resolve(context, optarg, &keytab))) { com_err(progname, retval, "while resolving keytab file %s", optarg); exit(2); } break; case '?': default: usage(progname); exit(1); break; } } argc -= optind; argv += optind; /* Backwards compatibility, allow port to be specified at end */ if (argc > 1) { port = atoi(argv[1]); } retval = krb5_sname_to_principal(context, NULL, service, KRB5_NT_SRV_HST, &server); if (retval) { syslog(LOG_ERR, "while generating service name (%s): %s", service, error_message(retval)); exit(1); } /* * If user specified a port, then listen on that port; otherwise, * assume we've been started out of inetd. */ if (port) { int acc; struct sockaddr_in sockin; if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { syslog(LOG_ERR, "socket: %m"); exit(3); } /* Let the socket be reused right away */ (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); sockin.sin_family = AF_INET; sockin.sin_addr.s_addr = 0; sockin.sin_port = htons(port); if (bind(sock, (struct sockaddr *) &sockin, sizeof(sockin))) { syslog(LOG_ERR, "bind: %m"); exit(3); } if (listen(sock, 1) == -1) { syslog(LOG_ERR, "listen: %m"); exit(3); } printf("starting...\n"); fflush(stdout); if ((acc = accept(sock, (struct sockaddr *)&peername, &namelen)) == -1){ syslog(LOG_ERR, "accept: %m"); exit(3); } dup2(acc, 0); close(sock); sock = 0; } else { /* * To verify authenticity, we need to know the address of the * client. */ if (getpeername(0, (struct sockaddr *)&peername, &namelen) < 0) { syslog(LOG_ERR, "getpeername: %m"); exit(1); } sock = 0; } retval = krb5_recvauth(context, &auth_context, (krb5_pointer)&sock, SAMPLE_VERSION, server, 0, /* no flags */ keytab, /* default keytab is NULL */ &ticket); if (retval) { syslog(LOG_ERR, "recvauth failed--%s", error_message(retval)); exit(1); } /* Get client name */ repbuf[sizeof(repbuf) - 1] = '\0'; retval = krb5_unparse_name(context, ticket->enc_part2->client, &cname); if (retval){ syslog(LOG_ERR, "unparse failed: %s", error_message(retval)); strncpy(repbuf, "You are \n", sizeof(repbuf) - 1); } else { strncpy(repbuf, "You are ", sizeof(repbuf) - 1); strncat(repbuf, cname, sizeof(repbuf) - 1 - strlen(repbuf)); strncat(repbuf, "\n", sizeof(repbuf) - 1 - strlen(repbuf)); free(cname); } xmitlen = htons(strlen(repbuf)); recv_data.length = strlen(repbuf); recv_data.data = repbuf; if ((retval = krb5_net_write(context, 0, (char *)&xmitlen, sizeof(xmitlen))) < 0) { syslog(LOG_ERR, "%m: while writing len to client"); exit(1); } if ((retval = krb5_net_write(context, 0, (char *)recv_data.data, recv_data.length)) < 0) { syslog(LOG_ERR, "%m: while writing data to client"); exit(1); } krb5_free_ticket(context, ticket); if(keytab) krb5_kt_close(context, keytab); krb5_free_principal(context, server); krb5_auth_con_free(context, auth_context); krb5_free_context(context); exit(0); } krb5-1.22.1/src/appl/sample/deps0000664000175000017500000000003015051422640016214 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/appl/sample/t_sample.py0000664000175000017500000000151615051422640017526 0ustar ghudsonghudsonfrom k5test import * sclient = os.path.join(buildtop, 'appl', 'sample', 'sclient', 'sclient') sserver = os.path.join(buildtop, 'appl', 'sample', 'sserver', 'sserver') for realm in multipass_realms(create_host=False): server_princ = 'sample/%s@%s' % (hostname, realm.realm) realm.addprinc(server_princ) realm.extract_keytab(server_princ, realm.keytab) portstr = str(realm.server_port()) server = realm.start_server([sserver, '-p', portstr], 'starting...') out = realm.run([sclient, hostname, portstr], expected_msg='You are user@KRBTEST.COM') await_daemon_exit(server) server = realm.start_in_inetd([sserver]) out = realm.run([sclient, hostname, portstr], expected_msg='You are user@KRBTEST.COM') await_daemon_exit(server) success('sim_client/sim_server tests') krb5-1.22.1/src/appl/sample/sclient/0000775000175000017500000000000015051422640017006 5ustar ghudsonghudsonkrb5-1.22.1/src/appl/sample/sclient/Makefile.in0000664000175000017500000000042215051422640021051 0ustar ghudsonghudsonmydir=appl$(S)sample$(S)sclient BUILDTOP=$(REL)..$(S)..$(S).. all: sclient sclient: sclient.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o sclient sclient.o $(KRB5_BASE_LIBS) clean: $(RM) sclient.o sclient install: $(INSTALL_PROGRAM) sclient ${DESTDIR}$(CLIENT_BINDIR)/sclient krb5-1.22.1/src/appl/sample/sclient/deps0000664000175000017500000000003015051422640017655 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/appl/sample/sclient/sclient.c0000664000175000017500000002026215051422640020615 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* appl/sample/sclient/sclient.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * Sample Kerberos v5 client. * * Usage: sample_client hostname */ #include "krb5.h" #include "com_err.h" #include #include #include #include #include #include #include #include #include "fake-addrinfo.h" /* not everyone implements getaddrinfo yet */ #include #ifdef HAVE_UNISTD_H #include #endif #include #include "../sample.h" #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE int #endif static int net_read(int fd, char *buf, int len) { int cc, len2 = 0; do { cc = SOCKET_READ((SOCKET)fd, buf, len); if (cc < 0) { if (SOCKET_ERRNO == SOCKET_EINTR) continue; /* XXX this interface sucks! */ errno = SOCKET_ERRNO; return(cc); /* errno is already set */ } else if (cc == 0) { return(len2); } else { buf += cc; len2 += cc; len -= cc; } } while (len > 0); return(len2); } int main(int argc, char *argv[]) { struct addrinfo *ap, aihints, *apstart; int aierr; int sock; krb5_context context; krb5_data recv_data; krb5_data cksum_data; krb5_error_code retval; krb5_ccache ccdef; krb5_principal client, server; krb5_error *err_ret; krb5_ap_rep_enc_part *rep_ret; krb5_auth_context auth_context = 0; short xmitlen; char *portstr; char *service = SAMPLE_SERVICE; if (argc != 2 && argc != 3 && argc != 4) { fprintf(stderr, "usage: %s [port] [service]\n",argv[0]); exit(1); } retval = krb5_init_context(&context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } (void) signal(SIGPIPE, SIG_IGN); if (argc > 2) portstr = argv[2]; else portstr = SAMPLE_PORT; memset(&aihints, 0, sizeof(aihints)); aihints.ai_socktype = SOCK_STREAM; aihints.ai_flags = AI_ADDRCONFIG; aierr = getaddrinfo(argv[1], portstr, &aihints, &ap); if (aierr) { fprintf(stderr, "%s: error looking up host '%s' port '%s'/tcp: %s\n", argv[0], argv[1], portstr, gai_strerror(aierr)); exit(1); } if (ap == 0) { /* Should never happen. */ fprintf(stderr, "%s: error looking up host '%s' port '%s'/tcp: no addresses returned?\n", argv[0], argv[1], portstr); exit(1); } if (argc > 3) { service = argv[3]; } retval = krb5_sname_to_principal(context, argv[1], service, KRB5_NT_SRV_HST, &server); if (retval) { com_err(argv[0], retval, "while creating server name for host %s service %s", argv[1], service); exit(1); } /* set up the address of the foreign socket for connect() */ apstart = ap; /* For freeing later */ for (sock = -1; ap && sock == -1; ap = ap->ai_next) { char abuf[NI_MAXHOST], pbuf[NI_MAXSERV]; char mbuf[NI_MAXHOST + NI_MAXSERV + 64]; if (getnameinfo(ap->ai_addr, ap->ai_addrlen, abuf, sizeof(abuf), pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { memset(abuf, 0, sizeof(abuf)); memset(pbuf, 0, sizeof(pbuf)); strncpy(abuf, "[error, cannot print address?]", sizeof(abuf)-1); strncpy(pbuf, "[?]", sizeof(pbuf)-1); } memset(mbuf, 0, sizeof(mbuf)); strncpy(mbuf, "error contacting ", sizeof(mbuf)-1); strncat(mbuf, abuf, sizeof(mbuf) - strlen(mbuf) - 1); strncat(mbuf, " port ", sizeof(mbuf) - strlen(mbuf) - 1); strncat(mbuf, pbuf, sizeof(mbuf) - strlen(mbuf) - 1); sock = socket(ap->ai_family, SOCK_STREAM, 0); if (sock < 0) { fprintf(stderr, "%s: socket: %s\n", mbuf, strerror(errno)); continue; } if (connect(sock, ap->ai_addr, ap->ai_addrlen) < 0) { fprintf(stderr, "%s: connect: %s\n", mbuf, strerror(errno)); close(sock); sock = -1; continue; } /* connected, yay! */ } if (sock == -1) /* Already printed error message above. */ exit(1); printf("connected\n"); cksum_data.data = argv[1]; cksum_data.length = strlen(argv[1]); retval = krb5_cc_default(context, &ccdef); if (retval) { com_err(argv[0], retval, "while getting default ccache"); exit(1); } retval = krb5_cc_get_principal(context, ccdef, &client); if (retval) { com_err(argv[0], retval, "while getting client principal name"); exit(1); } retval = krb5_sendauth(context, &auth_context, (krb5_pointer) &sock, SAMPLE_VERSION, client, server, AP_OPTS_MUTUAL_REQUIRED, &cksum_data, 0, /* no creds, use ccache instead */ ccdef, &err_ret, &rep_ret, NULL); krb5_free_principal(context, server); /* finished using it */ krb5_free_principal(context, client); krb5_cc_close(context, ccdef); if (auth_context) krb5_auth_con_free(context, auth_context); if (retval && retval != KRB5_SENDAUTH_REJECTED) { com_err(argv[0], retval, "while using sendauth"); exit(1); } if (retval == KRB5_SENDAUTH_REJECTED) { /* got an error */ printf("sendauth rejected, error reply is:\n\t\"%*s\"\n", err_ret->text.length, err_ret->text.data); } else if (rep_ret) { /* got a reply */ krb5_free_ap_rep_enc_part(context, rep_ret); printf("sendauth succeeded, reply is:\n"); if ((retval = net_read(sock, (char *)&xmitlen, sizeof(xmitlen))) <= 0) { if (retval == 0) errno = ECONNABORTED; com_err(argv[0], errno, "while reading data from server"); exit(1); } recv_data.length = ntohs(xmitlen); if (!(recv_data.data = (char *)malloc((size_t) recv_data.length + 1))) { com_err(argv[0], ENOMEM, "while allocating buffer to read from server"); exit(1); } if ((retval = net_read(sock, (char *)recv_data.data, recv_data.length)) <= 0) { if (retval == 0) errno = ECONNABORTED; com_err(argv[0], errno, "while reading data from server"); exit(1); } recv_data.data[recv_data.length] = '\0'; printf("reply len %d, contents:\n%s\n", recv_data.length,recv_data.data); free(recv_data.data); } else { com_err(argv[0], 0, "no error or reply from sendauth!"); exit(1); } freeaddrinfo(apstart); krb5_free_context(context); exit(0); } krb5-1.22.1/src/appl/user_user/0000775000175000017500000000000015051422640016100 5ustar ghudsonghudsonkrb5-1.22.1/src/appl/user_user/Makefile.in0000664000175000017500000000115415051422640020146 0ustar ghudsonghudsonmydir=appl$(S)user_user BUILDTOP=$(REL)..$(S).. # If you remove the -DDEBUG, the test program needs a line changed DEFINES = -DDEBUG all: uuclient uuserver check-pytests: uuclient uuserver $(RUNPYTEST) $(srcdir)/t_user2user.py $(PYTESTFLAGS) uuclient: client.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o uuclient client.o $(KRB5_BASE_LIBS) uuserver: server.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o uuserver server.o $(KRB5_BASE_LIBS) install: $(INSTALL_PROGRAM) uuclient $(DESTDIR)$(CLIENT_BINDIR)/uuclient $(INSTALL_PROGRAM) uuserver $(DESTDIR)$(SERVER_BINDIR)/uuserver clean: $(RM) client.o server.o uuclient uuserver krb5-1.22.1/src/appl/user_user/t_user2user.py0000775000175000017500000000104715051422640020741 0ustar ghudsonghudsonfrom k5test import * # If uuserver is not compiled under -DDEBUG, then set to 0 debug_compiled=1 for realm in multipass_realms(): if debug_compiled == 0: server = realm.start_in_inetd(['./uuserver'], port=9999) else: server = realm.start_server(['./uuserver', '9999'], 'Server started') msg = 'uu-client: server says "Hello, other end of connection."' realm.run(['./uuclient', hostname, 'testing message', '9999'], expected_msg=msg) await_daemon_exit(server) success('User-2-user test programs') krb5-1.22.1/src/appl/user_user/client.c0000664000175000017500000002216015051422640017523 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* appl/user_user/client.c - Other end of user-user client/server pair */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "com_err.h" #include #include #include #include #include int main (int argc, char *argv[]) { int s; int retval, i; char *hname; /* full name of server */ char **srealms; /* realm(s) of server */ char *princ; /* principal in credentials cache */ struct servent *serv; struct hostent *host; struct sockaddr_in serv_net_addr, cli_net_addr; krb5_ccache cc; krb5_creds creds, *new_creds; krb5_data reply, msg, princ_data; krb5_auth_context auth_context = NULL; krb5_ticket * ticket = NULL; krb5_context context; unsigned short port; if (argc < 2 || argc > 4) { fputs ("usage: uu-client [message [port]]\n", stderr); exit(1); } retval = krb5_init_context(&context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } if (argc == 4) { port = htons(atoi(argv[3])); } else if ((serv = getservbyname ("uu-sample", "tcp")) == NULL) { fputs ("uu-client: unknown service \"uu-sample/tcp\"\n", stderr); exit(2); } else { port = serv->s_port; } if ((host = gethostbyname (argv[1])) == NULL) { fprintf (stderr, "uu-client: can't get address of host \"%s\".\n", argv[1]); exit(3); } if (host->h_addrtype != AF_INET) { fprintf (stderr, "uu-client: bad address type %d for \"%s\".\n", host->h_addrtype, argv[1]); exit(3); } hname = strdup (host->h_name); #ifndef USE_STDOUT if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { com_err ("uu-client", errno, "creating socket"); exit(4); } else { cli_net_addr.sin_family = AF_INET; cli_net_addr.sin_port = 0; cli_net_addr.sin_addr.s_addr = 0; if (bind (s, (struct sockaddr *)&cli_net_addr, sizeof (cli_net_addr)) < 0) { com_err ("uu-client", errno, "binding socket"); exit(4); } } serv_net_addr.sin_family = AF_INET; serv_net_addr.sin_port = port; i = 0; while (1) { if (host->h_addr_list[i] == 0) { fprintf (stderr, "uu-client: unable to connect to \"%s\"\n", hname); exit(5); } memcpy (&serv_net_addr.sin_addr, host->h_addr_list[i++], sizeof(serv_net_addr.sin_addr)); if (connect(s, (struct sockaddr *)&serv_net_addr, sizeof (serv_net_addr)) == 0) break; com_err ("uu-client", errno, "connecting to \"%s\" (%s).", hname, inet_ntoa(serv_net_addr.sin_addr)); } #else s = 1; #endif retval = krb5_cc_default(context, &cc); if (retval) { com_err("uu-client", retval, "getting credentials cache"); exit(6); } memset (&creds, 0, sizeof(creds)); retval = krb5_cc_get_principal(context, cc, &creds.client); if (retval) { com_err("uu-client", retval, "getting principal name"); exit(6); } retval = krb5_unparse_name(context, creds.client, &princ); if (retval) { com_err("uu-client", retval, "printing principal name"); exit(7); } else fprintf(stderr, "uu-client: client principal is \"%s\".\n", princ); retval = krb5_get_host_realm(context, hname, &srealms); if (retval) { com_err("uu-client", retval, "getting realms for \"%s\"", hname); exit(7); } retval = krb5_build_principal_ext(context, &creds.server, krb5_princ_realm(context, creds.client)->length, krb5_princ_realm(context, creds.client)->data, 6, "krbtgt", krb5_princ_realm(context, creds.client)->length, krb5_princ_realm(context, creds.client)->data, 0); if (retval) { com_err("uu-client", retval, "setting up tgt server name"); exit(7); } /* Get TGT from credentials cache */ retval = krb5_get_credentials(context, KRB5_GC_CACHED, cc, &creds, &new_creds); if (retval) { com_err("uu-client", retval, "getting TGT"); exit(6); } i = strlen(princ) + 1; fprintf(stderr, "uu-client: sending %d bytes\n", new_creds->ticket.length + i); princ_data.data = princ; princ_data.length = i; /* include null terminator for server's convenience */ retval = krb5_write_message(context, (krb5_pointer) &s, &princ_data); if (retval) { com_err("uu-client", retval, "sending principal name to server"); exit(8); } free(princ); retval = krb5_write_message(context, (krb5_pointer) &s, &new_creds->ticket); if (retval) { com_err("uu-client", retval, "sending ticket to server"); exit(8); } retval = krb5_read_message(context, (krb5_pointer) &s, &reply); if (retval) { com_err("uu-client", retval, "reading reply from server"); exit(9); } retval = krb5_auth_con_init(context, &auth_context); if (retval) { com_err("uu-client", retval, "initializing the auth_context"); exit(9); } retval = krb5_auth_con_genaddrs(context, auth_context, s, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR | KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR); if (retval) { com_err("uu-client", retval, "generating addrs for auth_context"); exit(9); } retval = krb5_auth_con_setflags(context, auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); if (retval) { com_err("uu-client", retval, "initializing the auth_context flags"); exit(9); } retval = krb5_auth_con_setuseruserkey(context, auth_context, &new_creds->keyblock); if (retval) { com_err("uu-client", retval, "setting useruserkey for authcontext"); exit(9); } /* read the ap_req to get the session key */ retval = krb5_rd_req(context, &auth_context, &reply, creds.client, NULL, NULL, &ticket); krb5_free_data_contents(context, &reply); if (retval) { com_err("uu-client", retval, "reading AP_REQ from server"); exit(9); } retval = krb5_unparse_name(context, ticket->enc_part2->client, &princ); if (retval) com_err("uu-client", retval, "while unparsing client name"); else { printf("server is named \"%s\"\n", princ); free(princ); } retval = krb5_read_message(context, (krb5_pointer) &s, &reply); if (retval) { com_err("uu-client", retval, "reading reply from server"); exit(9); } retval = krb5_rd_safe(context, auth_context, &reply, &msg, NULL); if (retval) { com_err("uu-client", retval, "decoding reply from server"); exit(10); } printf ("uu-client: server says \"%s\".\n", msg.data); #ifndef USE_STDOUT close(s); #endif krb5_free_ticket(context, ticket); krb5_free_host_realm(context, srealms); free(hname); krb5_free_cred_contents(context, &creds); krb5_free_creds(context, new_creds); krb5_free_data_contents(context, &msg); krb5_free_data_contents(context, &reply); krb5_cc_close(context, cc); krb5_auth_con_free(context, auth_context); krb5_free_context(context); return 0; } krb5-1.22.1/src/appl/user_user/deps0000664000175000017500000000003015051422640016747 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/appl/user_user/server.c0000664000175000017500000001723415051422640017561 0ustar ghudsonghudson /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* appl/user_user/server.c - One end of user-user client-server pair */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "port-sockets.h" #include "com_err.h" #include #include #include #include #include #include #include /* fd 0 is a tcp socket used to talk to the client */ int main(int argc, char *argv[]) { krb5_data pname_data, tkt_data; int sock = 0; socklen_t l; int retval; struct sockaddr_in l_inaddr, f_inaddr; /* local, foreign address */ krb5_creds creds, *new_creds; krb5_ccache cc; krb5_data msgtext, msg; krb5_context context; krb5_auth_context auth_context = NULL; #ifndef DEBUG freopen("/tmp/uu-server.log", "w", stderr); #endif retval = krb5_init_context(&context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } #ifdef DEBUG { int one = 1; int acc; struct servent *sp; socklen_t namelen = sizeof(f_inaddr); if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { com_err("uu-server", errno, "creating socket"); exit(3); } l_inaddr.sin_family = AF_INET; l_inaddr.sin_addr.s_addr = 0; if (argc == 2) { l_inaddr.sin_port = htons(atoi(argv[1])); } else { if (!(sp = getservbyname("uu-sample", "tcp"))) { com_err("uu-server", 0, "can't find uu-sample/tcp service"); exit(3); } l_inaddr.sin_port = sp->s_port; } (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (one)); if (bind(sock, (struct sockaddr *)&l_inaddr, sizeof(l_inaddr))) { com_err("uu-server", errno, "binding socket"); exit(3); } if (listen(sock, 1) == -1) { com_err("uu-server", errno, "listening"); exit(3); } printf("Server started\n"); fflush(stdout); if ((acc = accept(sock, (struct sockaddr *)&f_inaddr, &namelen)) == -1) { com_err("uu-server", errno, "accepting"); exit(3); } dup2(acc, 0); close(sock); sock = 0; } #endif /* principal name must be sent null-terminated. */ retval = krb5_read_message(context, (krb5_pointer) &sock, &pname_data); if (retval || pname_data.length == 0 || pname_data.data[pname_data.length - 1] != '\0') { com_err ("uu-server", retval, "reading pname"); return 2; } retval = krb5_read_message(context, (krb5_pointer) &sock, &tkt_data); if (retval) { com_err ("uu-server", retval, "reading ticket data"); return 2; } retval = krb5_cc_default(context, &cc); if (retval) { com_err("uu-server", retval, "getting credentials cache"); return 4; } memset (&creds, 0, sizeof(creds)); retval = krb5_cc_get_principal(context, cc, &creds.client); if (retval) { com_err("uu-client", retval, "getting principal name"); return 6; } /* client sends it already null-terminated. */ printf ("uu-server: client principal is \"%s\".\n", pname_data.data); retval = krb5_parse_name(context, pname_data.data, &creds.server); if (retval) { com_err("uu-server", retval, "parsing client name"); return 3; } creds.second_ticket = tkt_data; printf ("uu-server: client ticket is %d bytes.\n", creds.second_ticket.length); retval = krb5_get_credentials(context, KRB5_GC_USER_USER, cc, &creds, &new_creds); if (retval) { com_err("uu-server", retval, "getting user-user ticket"); return 5; } #ifndef DEBUG l = sizeof(f_inaddr); if (getpeername(0, (struct sockaddr *)&f_inaddr, &l) == -1) { com_err("uu-server", errno, "getting client address"); return 6; } #endif l = sizeof(l_inaddr); if (getsockname(0, (struct sockaddr *)&l_inaddr, &l) == -1) { com_err("uu-server", errno, "getting local address"); return 6; } /* send a ticket/authenticator to the other side, so it can get the key we're using for the krb_safe below. */ retval = krb5_auth_con_init(context, &auth_context); if (retval) { com_err("uu-server", retval, "making auth_context"); return 8; } retval = krb5_auth_con_setflags(context, auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); if (retval) { com_err("uu-server", retval, "initializing the auth_context flags"); return 8; } retval = krb5_auth_con_genaddrs(context, auth_context, sock, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR | KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR); if (retval) { com_err("uu-server", retval, "generating addrs for auth_context"); return 9; } #if 1 retval = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SESSION_KEY, NULL, new_creds, &msg); if (retval) { com_err("uu-server", retval, "making AP_REQ"); return 8; } retval = krb5_write_message(context, (krb5_pointer) &sock, &msg); #else retval = krb5_sendauth(context, &auth_context, (krb5_pointer)&sock, "???", 0, 0, AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SESSION_KEY, NULL, &creds, cc, NULL, NULL, NULL); #endif if (retval) goto cl_short_wrt; free(msg.data); msgtext.length = 32; msgtext.data = "Hello, other end of connection."; retval = krb5_mk_safe(context, auth_context, &msgtext, &msg, NULL); if (retval) { com_err("uu-server", retval, "encoding message to client"); return 6; } retval = krb5_write_message(context, (krb5_pointer) &sock, &msg); if (retval) { cl_short_wrt: com_err("uu-server", retval, "writing message to client"); return 7; } krb5_free_data_contents(context, &msg); krb5_free_data_contents(context, &pname_data); /* tkt_data freed with creds */ krb5_free_cred_contents(context, &creds); krb5_free_creds(context, new_creds); krb5_cc_close(context, cc); krb5_auth_con_free(context, auth_context); krb5_free_context(context); return 0; } krb5-1.22.1/src/aclocal.m40000664000175000017500000013403115051422640014772 0ustar ghudsonghudsonAC_PREREQ(2.63) AC_COPYRIGHT([Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Massachusetts Institute of Technology. ]) dnl define([K5_TOPDIR],[.])dnl dnl AC_DEFUN(V5_SET_TOPDIR,[dnl ac_reltopdir="K5_TOPDIR" if test ! -r "$srcdir/K5_TOPDIR/aclocal.m4"; then AC_MSG_ERROR([Configure could not determine the relative topdir]) fi ac_topdir=$srcdir/$ac_reltopdir ac_config_fragdir=$ac_reltopdir/config # echo "Looking for $srcdir/$ac_config_fragdir" AC_CONFIG_AUX_DIR(K5_TOPDIR/config) ])dnl dnl dnl Version info. dnl pushdef([x],esyscmd([sed -n 's/#define \([A-Z0-9_]*\)[ \t]*\(.*\)/\1=\2/p' < ]K5_TOPDIR/patchlevel.h)) define([PL_KRB5_MAJOR_RELEASE],regexp(x,[KRB5_MAJOR_RELEASE=\(.*\)],[\1])) ifelse(PL_KRB5_MAJOR_RELEASE,,[errprint([Can't determine KRB5_MAJOR_RELEASE value from patchlevel.h. ]) m4exit(1) dnl sometimes that does not work? builtin(m4exit,1)]) define([PL_KRB5_MINOR_RELEASE],regexp(x,[KRB5_MINOR_RELEASE=\(.*\)],[\1])) ifelse(PL_KRB5_MINOR_RELEASE,,[errprint([Can't determine KRB5_MINOR_RELEASE value from patchlevel.h. ]) m4exit(1) dnl sometimes that does not work? builtin(m4exit,1)]) define([PL_KRB5_PATCHLEVEL],regexp(x,[KRB5_PATCHLEVEL=\(.*\)],[\1])) ifelse(PL_KRB5_PATCHLEVEL,,[errprint([Can't determine KRB5_PATCHLEVEL value from patchlevel.h. ]) m4exit(1) dnl sometimes that does not work? builtin(m4exit,1)]) define([PL_KRB5_RELTAIL],regexp(x,[KRB5_RELTAIL="\(.*\)"],[\1])) dnl RELTAIL is allowed to not be defined. popdef([x]) define([K5_VERSION],PL_KRB5_MAJOR_RELEASE.PL_KRB5_MINOR_RELEASE[]ifelse(PL_KRB5_PATCHLEVEL,0,,.PL_KRB5_PATCHLEVEL)ifelse(PL_KRB5_RELTAIL,,,-PL_KRB5_RELTAIL)) define([K5_BUGADDR],krb5-bugs@mit.edu) define([K5_AC_INIT],[AC_INIT(Kerberos 5, K5_VERSION, K5_BUGADDR, krb5) AC_CONFIG_SRCDIR($1) build_dynobj=no]) dnl dnl drop in standard rules for all configure files -- CONFIG_RULES dnl AC_DEFUN(CONFIG_RULES,[dnl AC_REQUIRE([V5_SET_TOPDIR]) dnl EXTRA_FILES="" AC_SUBST(EXTRA_FILES) dnl Consider using AC_USE_SYSTEM_EXTENSIONS when we require autoconf dnl 2.59c or later, but be sure to test on Solaris first. AC_DEFINE([_GNU_SOURCE], 1, [Define to enable extensions in glibc]) AC_DEFINE([__STDC_WANT_LIB_EXT1__], 1, [Define to enable C11 extensions]) WITH_CC dnl AC_REQUIRE_CPP if test -z "$LD" ; then LD=$CC; fi AC_ARG_VAR(LD,[linker command [CC]]) AC_SUBST(LDFLAGS) dnl KRB5_AC_CHOOSE_ET dnl KRB5_AC_CHOOSE_SS dnl KRB5_AC_CHOOSE_DB dnl dnl allow stuff in tree to access deprecated stuff for now dnl AC_DEFINE([KRB5_DEPRECATED], 1, [Define only if building in-tree]) AC_C_CONST dnl WITH_NETLIB dnl WITH_HESIOD dnl KRB5_AC_MAINTAINER_MODE dnl AC_ARG_PROGRAM dnl dnl dnl This identifies the top of the source tree relative to the directory dnl in which the configure file lives. dnl CONFIG_RELTOPDIR=$ac_reltopdir AC_SUBST(CONFIG_RELTOPDIR) lib_frag=$srcdir/$ac_config_fragdir/lib.in AC_SUBST_FILE(lib_frag) libobj_frag=$srcdir/$ac_config_fragdir/libobj.in AC_SUBST_FILE(libobj_frag) libnover_frag=$srcdir/$ac_config_fragdir/libnover.in AC_SUBST_FILE(libnover_frag) libpriv_frag=$srcdir/$ac_config_fragdir/libpriv.in AC_SUBST_FILE(libpriv_frag) libnodeps_frag=$srcdir/$ac_config_fragdir/libnodeps.in AC_SUBST_FILE(libnodeps_frag) dnl KRB5_AC_PRAGMA_WEAK_REF WITH_LDAP KRB5_LIB_PARAMS KRB5_AC_INITFINI KRB5_AC_ENABLE_THREADS KRB5_AC_FIND_DLOPEN ])dnl dnl Maintainer mode, akin to what automake provides, 'cept we don't dnl want to use automake right now. AC_DEFUN([KRB5_AC_MAINTAINER_MODE], [AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--enable-maintainer-mode], [enable rebuilding of source files, Makefiles, etc])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=no]) if test "$USE_MAINTAINER_MODE" = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' AC_MSG_NOTICE(enabling maintainer mode) else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE AC_SUBST(MAINTAINER_MODE_TRUE) AC_SUBST(MAINTAINER_MODE_FALSE) AC_SUBST(MAINT) ]) dnl AC_DEFUN([KRB5_AC_INITFINI],[ dnl Do we want initialization at load time? AC_ARG_ENABLE([delayed-initialization], [AS_HELP_STRING([--disable-delayed-initialization], [initialize library code when loaded @<:@delay until first use@:>@])], [], [enable_delayed_initialization=yes]) case "$enable_delayed_initialization" in yes) AC_DEFINE(DELAY_INITIALIZER,1,[Define if library initialization should be delayed until first use]) ;; no) ;; *) AC_MSG_ERROR(invalid option $enable_delayed_initialization for delayed-initialization) ;; esac dnl We always want finalization at unload time. dnl dnl Can we do things through gcc? KRB5_AC_GCC_ATTRS dnl How about with the linker? if test -z "$use_linker_init_option" ; then AC_MSG_ERROR(ran INITFINI before checking shlib.conf?) fi if test "$use_linker_init_option" = yes; then AC_DEFINE(USE_LINKER_INIT_OPTION,1,[Define if link-time options for library initialization will be used]) fi if test "$use_linker_fini_option" = yes; then AC_DEFINE(USE_LINKER_FINI_OPTION,1,[Define if link-time options for library finalization will be used]) fi if test "$lib_unload_prevented" = yes; then AC_DEFINE(LIB_UNLOAD_PREVENTED,1,[Define if library unloading is prevented]) fi ]) dnl find dlopen AC_DEFUN([KRB5_AC_FIND_DLOPEN],[ old_LIBS="$LIBS" DL_LIB= AC_SEARCH_LIBS(dlopen, dl, [ if test "$ac_cv_search_dlopen" != "none required"; then DL_LIB=$ac_cv_search_dlopen fi LIBS="$old_LIBS" AC_DEFINE(USE_DLOPEN,1,[Define if dlopen should be used])]) AC_SUBST(DL_LIB) ]) dnl Hack for now. AC_DEFUN([KRB5_AC_ENABLE_THREADS],[ AC_ARG_ENABLE([thread-support], [AS_HELP_STRING([--disable-thread-support], [don't enable thread support @<:@enabled@:>@])], [], [enable_thread_support=yes]) if test "$enable_thread_support" = yes ; then AC_MSG_NOTICE(enabling thread support) AC_DEFINE(ENABLE_THREADS,1,[Define if thread support enabled]) fi dnl Maybe this should be inside the conditional above? Doesn't cache.... if test "$enable_thread_support" = yes; then AX_PTHREAD(,[AC_MSG_ERROR([cannot determine options for enabling thread support; try --disable-thread-support])]) AC_MSG_NOTICE(PTHREAD_CC = $PTHREAD_CC) AC_MSG_NOTICE(PTHREAD_CFLAGS = $PTHREAD_CFLAGS) AC_MSG_NOTICE(PTHREAD_LIBS = $PTHREAD_LIBS) dnl Not really needed -- if pthread.h isn't found, ACX_PTHREAD will fail. dnl AC_CHECK_HEADERS(pthread.h) # AIX and Tru64 don't support weak references, and don't have # stub versions of the pthread code in libc. case "${host_os}" in aix* | osf*) # On these platforms, we'll always pull in the thread support. LIBS="$LIBS $PTHREAD_LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # We don't need to sometimes add the flags we've just folded in... PTHREAD_LIBS= PTHREAD_CFLAGS= ;; hpux*) # These are the flags that "gcc -pthread" adds. But we don't # want "-pthread" because that has link-time effects, and we # don't exclude CFLAGS when linking. *sigh* PTHREAD_CFLAGS="-D_REENTRANT -D_THREAD_SAFE -D_POSIX_C_SOURCE=199506L" ;; solaris2.[[1-9]]) # On Solaris 10 with gcc 3.4.3, the autoconf archive macro doesn't # get the right result. XXX What about Solaris 9 and earlier? if test "$GCC" = yes ; then PTHREAD_CFLAGS="-D_REENTRANT -pthreads" fi ;; solaris*) # On Solaris 10 with gcc 3.4.3, the autoconf archive macro doesn't # get the right result. if test "$GCC" = yes ; then PTHREAD_CFLAGS="-D_REENTRANT -pthreads" fi # On Solaris 10, the thread support is always available in libc. AC_DEFINE(NO_WEAK_PTHREADS,1,[Define if references to pthread routines should be non-weak.]) ;; esac THREAD_SUPPORT=1 else PTHREAD_CC="$CC" PTHREAD_CFLAGS="" PTHREAD_LIBS="" THREAD_SUPPORT=0 fi AC_SUBST(THREAD_SUPPORT) dnl We want to know where these routines live, so on systems with weak dnl reference support we can figure out whether or not the pthread library dnl has been linked in. dnl If we don't add any libraries for thread support, don't bother. AC_CHECK_FUNCS(pthread_once pthread_rwlock_init) old_CC="$CC" test "$PTHREAD_CC" != "" && test "$ac_cv_c_compiler_gnu" = no && CC=$PTHREAD_CC old_CFLAGS="$CFLAGS" # On Solaris, -pthreads is added to CFLAGS, no extra explicit libraries. CFLAGS="$CFLAGS $PTHREAD_CFLAGS" AC_SUBST(PTHREAD_CFLAGS) old_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_NOTICE(rechecking with PTHREAD_... options) AC_CHECK_LIB(c, pthread_rwlock_init, [AC_DEFINE(HAVE_PTHREAD_RWLOCK_INIT_IN_THREAD_LIB,1,[Define if pthread_rwlock_init is provided in the thread library.])]) LIBS="$old_LIBS" CC="$old_CC" CFLAGS="$old_CFLAGS" ]) dnl This is somewhat gross and should go away when the build system dnl is revamped. -- tlyu dnl DECLARE_SYS_ERRLIST - check for sys_errlist in libc dnl AC_DEFUN([DECLARE_SYS_ERRLIST], [AC_CACHE_CHECK([for sys_errlist declaration], krb5_cv_decl_sys_errlist, [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include #include ]], [[1+sys_nerr;]])], [krb5_cv_decl_sys_errlist=yes], [krb5_cv_decl_sys_errlist=no])]) # assume sys_nerr won't be declared w/o being in libc if test $krb5_cv_decl_sys_errlist = yes; then AC_DEFINE(SYS_ERRLIST_DECLARED,1,[Define if sys_errlist is defined in errno.h]) AC_DEFINE(HAVE_SYS_ERRLIST,1,[Define if sys_errlist in libc]) else # This means that sys_errlist is not declared in errno.h, but may still # be in libc. AC_CACHE_CHECK([for sys_errlist in libc], krb5_cv_var_sys_errlist, [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[extern int sys_nerr;]], [[if (1+sys_nerr < 0) return 1;]])], [krb5_cv_var_sys_errlist=yes], [krb5_cv_var_sys_errlist=no])]) if test $krb5_cv_var_sys_errlist = yes; then AC_DEFINE(HAVE_SYS_ERRLIST,1,[Define if sys_errlist in libc]) # Do this cruft for backwards compatibility for now. AC_DEFINE(NEED_SYS_ERRLIST,1,[Define if need to declare sys_errlist]) else AC_MSG_WARN([sys_errlist is neither in errno.h nor in libc]) fi fi]) dnl dnl check for sigmask/sigprocmask -- CHECK_SIGPROCMASK dnl AC_DEFUN(CHECK_SIGPROCMASK,[ AC_MSG_CHECKING([for use of sigprocmask]) AC_CACHE_VAL(krb5_cv_func_sigprocmask_use, [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[sigprocmask(SIG_SETMASK, 0, 0);]])], [krb5_cv_func_sigprocmask_use=yes], [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[sigmask(1);]])], [krb5_cv_func_sigprocmask_use=no], [krb5_cv_func_sigprocmask_use=yes])])]) AC_MSG_RESULT($krb5_cv_func_sigprocmask_use) if test $krb5_cv_func_sigprocmask_use = yes; then AC_DEFINE(USE_SIGPROCMASK,1,[Define if sigprocmask should be used]) fi ])dnl dnl dnl dnl check for -- CHECK_DIRENT dnl (may need to be more complex later) dnl AC_DEFUN(CHECK_DIRENT,[ AC_CHECK_HEADER(dirent.h,AC_DEFINE(USE_DIRENT_H,1,[Define if you have dirent.h functionality]))])dnl dnl dnl check if union wait is defined, or if WAIT_USES_INT -- CHECK_WAIT_TYPE dnl AC_DEFUN(CHECK_WAIT_TYPE,[ AC_MSG_CHECKING([if argument to wait is int *]) AC_CACHE_VAL(krb5_cv_struct_wait, dnl Test for prototype clash - if there is none - then assume int * works [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include #include extern pid_t wait(int *);]])], [krb5_cv_struct_wait=no], dnl Else fallback on old stuff [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[union wait i; #ifdef WEXITSTATUS WEXITSTATUS (i); #endif ]])], [krb5_cv_struct_wait=yes], [krb5_cv_struct_wait=no])])]) AC_MSG_RESULT($krb5_cv_struct_wait) if test $krb5_cv_struct_wait = no; then AC_DEFINE(WAIT_USES_INT,1,[Define if wait takes int as a argument]) fi ])dnl dnl dnl check for POSIX signal handling -- CHECK_SIGNALS dnl AC_DEFUN(CHECK_SIGNALS,[ AC_CHECK_FUNC(sigprocmask, AC_MSG_CHECKING(for sigset_t and POSIX_SIGNALS) AC_CACHE_VAL(krb5_cv_type_sigset_t, [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[sigset_t x]])], [krb5_cv_type_sigset_t=yes], [krb5_cv_type_sigset_t=no])]) AC_MSG_RESULT($krb5_cv_type_sigset_t) if test $krb5_cv_type_sigset_t = yes; then AC_DEFINE(POSIX_SIGNALS,1,[Define if POSIX signal handling is used]) fi )])dnl dnl dnl check for POSIX setjmp/longjmp -- CHECK_SETJMP dnl AC_DEFUN(CHECK_SETJMP,[ AC_CHECK_FUNC(sigsetjmp, AC_MSG_CHECKING(for sigjmp_buf) AC_CACHE_VAL(krb5_cv_struct_sigjmp_buf, [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[sigjmp_buf x]])], [krb5_cv_struct_sigjmp_buf=yes], [krb5_cv_struct_sigjmp_buf=no])]) AC_MSG_RESULT($krb5_cv_struct_sigjmp_buf) if test $krb5_cv_struct_sigjmp_buf = yes; then AC_DEFINE(POSIX_SETJMP,1,[Define if setjmp indicates POSIX interface]) fi )])dnl dnl dnl Check for IPv6 compile-time support. dnl AC_DEFUN(KRB5_AC_INET6,[ AC_CHECK_HEADERS(sys/types.h sys/socket.h netinet/in.h netdb.h) AC_CHECK_FUNCS(inet_ntop inet_pton getnameinfo) dnl getaddrinfo test needs netdb.h, for proper compilation on alpha dnl under OSF/1^H^H^H^H^HDigital^H^H^H^H^H^H^HTru64 UNIX, where it's dnl a macro AC_MSG_CHECKING(for getaddrinfo) AC_CACHE_VAL(ac_cv_func_getaddrinfo, [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#ifdef HAVE_NETDB_H #include #endif ]], [[struct addrinfo *ai; getaddrinfo("kerberos.mit.edu", "echo", 0, &ai);]])], [ac_cv_func_getaddrinfo=yes], [ac_cv_func_getaddrinfo=no])]) AC_MSG_RESULT($ac_cv_func_getaddrinfo) if test $ac_cv_func_getaddrinfo = yes; then AC_DEFINE(HAVE_GETADDRINFO,1,[Define if you have the getaddrinfo function]) fi dnl AC_REQUIRE([KRB5_SOCKADDR_SA_LEN])dnl AC_MSG_CHECKING(for IPv6 compile-time support without -DINET6) AC_CACHE_VAL(krb5_cv_inet6,[ if test "$ac_cv_func_inet_ntop" != "yes" ; then krb5_cv_inet6=no else AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#ifdef HAVE_SYS_TYPES_H #include #endif #include #include #include ]], [[struct sockaddr_in6 in; AF_INET6; IN6_IS_ADDR_LINKLOCAL(&in.sin6_addr);]])], [krb5_cv_inet6=yes], [krb5_cv_inet6=no]) fi]) AC_MSG_RESULT($krb5_cv_inet6) if test "$krb5_cv_inet6" = no && test "$ac_cv_func_inet_ntop" = yes; then AC_MSG_CHECKING(for IPv6 compile-time support with -DINET6) AC_CACHE_VAL(krb5_cv_inet6_with_dinet6,[ old_CC="$CC" CC="$CC -DINET6" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#ifdef HAVE_SYS_TYPES_H #include #endif #include #include #include ]], [[struct sockaddr_in6 in; AF_INET6; IN6_IS_ADDR_LINKLOCAL (&in.sin6_addr);]])], [krb5_cv_inet6_with_dinet6=yes], [krb5_cv_inet6_with_dinet6=no]) CC="$old_CC"]) AC_MSG_RESULT($krb5_cv_inet6_with_dinet6) fi if test $krb5_cv_inet6 = yes || test "$krb5_cv_inet6_with_dinet6" = yes; then if test "$krb5_cv_inet6_with_dinet6" = yes; then AC_DEFINE(INET6,1,[May need to be defined to enable IPv6 support, for example on IRIX]) fi fi ])dnl dnl AC_DEFUN(KRB5_AC_CHECK_FOR_CFLAGS,[ AC_BEFORE([$0],[AC_PROG_CC]) AC_BEFORE([$0],[AC_PROG_CXX]) krb5_ac_cflags_set=${CFLAGS+set} krb5_ac_cxxflags_set=${CXXFLAGS+set} krb5_ac_warn_cflags_set=${WARN_CFLAGS+set} krb5_ac_warn_cxxflags_set=${WARN_CXXFLAGS+set} ]) dnl AC_DEFUN(TRY_WARN_CC_FLAG_1,[dnl cachevar=`echo "krb5_cv_cc_flag_$1" | sed -e s/=/_eq_/g -e s/-/_dash_/g -e s/[[^a-zA-Z0-9_]]/_/g` AC_CACHE_CHECK([if C compiler supports $1], [$cachevar], [# first try without, then with AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([], [1;])], [old_cflags="$CFLAGS" CFLAGS="$CFLAGS $cflags_warning_test_flags $1" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([], [1;])], [eval $cachevar=yes], [eval $cachevar=no]) CFLAGS="$old_cflags"], [AC_MSG_ERROR(compiling simple test program with $CFLAGS failed)])]) if eval test '"${'$cachevar'}"' = yes; then WARN_CFLAGS="$WARN_CFLAGS $1" fi eval flag_supported='${'$cachevar'}' ])dnl dnl dnl Are additional flags needed to make unsupported warning options dnl get reported as errors? AC_DEFUN(CHECK_CC_WARNING_TEST_FLAGS,[dnl cflags_warning_test_flags= TRY_WARN_CC_FLAG_1(-Werror=unknown-warning-option) if test $flag_supported = yes; then cflags_warning_test_flags=-Werror=unknown-warning-option fi ])dnl dnl AC_DEFUN(TRY_WARN_CC_FLAG,[dnl AC_REQUIRE([CHECK_CC_WARNING_TEST_FLAGS])dnl TRY_WARN_CC_FLAG_1($1)dnl ])dnl dnl AC_DEFUN(WITH_CC,[dnl AC_REQUIRE([KRB5_AC_CHECK_FOR_CFLAGS])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_CXX])dnl if test $ac_cv_c_compiler_gnu = yes ; then HAVE_GCC=yes else HAVE_GCC= fi AC_SUBST(HAVE_GCC) AC_CACHE_CHECK([for GNU linker], krb5_cv_prog_gnu_ld, [krb5_cv_prog_gnu_ld=no if test "$GCC" = yes; then if AC_TRY_COMMAND([$CC -Wl,-v 2>&1 dnl | grep "GNU ld" > /dev/null]); then krb5_cv_prog_gnu_ld=yes fi fi]) AC_ARG_WITH([size-optimizations], [ --with-size-optimizations enable a few optimizations to reduce code size possibly at some run-time cost], , withval=no) if test "$withval" = yes; then AC_DEFINE(CONFIG_SMALL,1,[Define to reduce code size even if it means more cpu usage]) fi # -Wno-long-long, if needed, for k5-platform.h without inttypes.h etc. extra_gcc_warn_opts="-Wall -Wcast-align -Wshadow" # -Wmissing-prototypes if test "$GCC" = yes ; then # Putting this here means we get -Os after -O2, which works. if test "$with_size_optimizations" = yes && test "x$krb5_ac_cflags_set" != xset; then AC_MSG_NOTICE(adding -Os optimization option) case "$CFLAGS" in "-g -O2") CFLAGS="-g -Os" ;; "-O2") CFLAGS="-Os" ;; *) CFLAGS="$CFLAGS -Os" ;; esac fi if test "x$krb5_ac_warn_cflags_set" = xset ; then AC_MSG_NOTICE(not adding extra gcc warning flags because WARN_CFLAGS was set) else AC_MSG_NOTICE(adding extra warning flags for gcc) WARN_CFLAGS="$WARN_CFLAGS $extra_gcc_warn_opts -Wmissing-prototypes" if test "`uname -s`" = Darwin ; then AC_MSG_NOTICE(skipping pedantic warnings on Darwin) elif test "`uname -s`" = Linux ; then AC_MSG_NOTICE(skipping pedantic warnings on Linux) else WARN_CFLAGS="$WARN_CFLAGS -pedantic" fi if test "$ac_cv_cxx_compiler_gnu" = yes; then if test "x$krb5_ac_warn_cxxflags_set" = xset ; then AC_MSG_NOTICE(not adding extra g++ warnings because WARN_CXXFLAGS was set) else AC_MSG_NOTICE(adding extra warning flags for g++) WARN_CXXFLAGS="$WARN_CXXFLAGS $extra_gcc_warn_opts" fi fi # Currently, G++ does not support -Wno-format-zero-length. TRY_WARN_CC_FLAG(-Wno-format-zero-length) # Other flags here may not be supported on some versions of # gcc that people want to use. for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized no-maybe-uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers error=implicit-int error=strict-prototypes; do TRY_WARN_CC_FLAG(-W$flag) done # old-style-definition? generates many, many warnings # # Warnings that we'd like to turn into errors on versions of gcc # that support promoting only specific warnings to errors, but # we'll take as warnings on older compilers. (If such a warning # is added after the -Werror=foo feature, you can just put # error=foo in the above list, and skip the test for the # warning-only form.) At least in some versions, -Werror= doesn't # seem to make the conditions actual errors, but still issues # warnings; I guess we'll take what we can get. # # We're currently targeting C89+, not C99, so disallow some # constructs. for flag in declaration-after-statement ; do TRY_WARN_CC_FLAG(-Werror=$flag) if test "$flag_supported" = no; then TRY_WARN_CC_FLAG(-W$flag) fi done # We require function declarations now. # # In some compiler versions -- e.g., "gcc version 4.2.1 (Apple # Inc. build 5664)" -- the -Werror- option works, but the -Werror= # version doesn't cause implicitly declared functions to be # flagged as errors. If neither works, -Wall implies # -Wimplicit-function-declaration so don't bother. TRY_WARN_CC_FLAG(-Werror-implicit-function-declaration) if test "implicit-function-declaration_supported" = no; then TRY_WARN_CC_FLAG(-Werror=implicit-function-declaration) fi # fi if test "`uname -s`" = Darwin ; then # Someday this should be a feature test. # One current (Jaguar = OS 10.2) problem: # Archive library with foo.o undef sym X and bar.o common sym X, # if foo.o is pulled in at link time, bar.o may not be, causing # the linker to complain. # Dynamic library problems too? case "$CC $CFLAGS" in *-fcommon*) ;; # why someone would do this, I don't know *-fno-common*) ;; # okay, they're already doing the right thing *) AC_MSG_NOTICE(disabling the use of common storage on Darwin) CFLAGS="$CFLAGS -fno-common" ;; esac fi else if test "`uname -s`" = AIX ; then # Using AIX but not GCC, assume native compiler. # The native compiler appears not to give a nonzero exit # status for certain classes of errors, like missing arguments # in function calls. Let's try to fix that with -qhalt=e. case "$CC $CFLAGS" in *-qhalt=*) ;; *) CFLAGS="$CFLAGS -qhalt=e" AC_MSG_NOTICE(adding -qhalt=e for better error reporting) ;; esac # Also, the optimizer isn't turned on by default, which means # the static inline functions get left in random object files, # leading to references to pthread_mutex_lock from anything that # includes k5-int.h whether it uses threads or not. case "$CC $CFLAGS" in *-O*) ;; *) CFLAGS="$CFLAGS -O" AC_MSG_NOTICE(adding -O for inline thread-support function elimination) ;; esac fi if test "`uname -s`" = SunOS ; then # Using Solaris but not GCC, assume Sunsoft compiler. # We have some error-out-on-warning options available. # Sunsoft 12 compiler defaults to -xc99=all, it appears, so "inline" # works, but it also means that declaration-in-code warnings won't # be issued. # -v -fd -errwarn=E_DECLARATION_IN_CODE ... if test "x$krb5_ac_warn_cflags_set" = xset ; then AC_MSG_NOTICE(not adding extra warning flags because WARN_CFLAGS was set) else WARN_CFLAGS="-errtags=yes -errwarn=E_BAD_PTR_INT_COMBINATION,E_BAD_PTR_INT_COMB_ARG,E_PTR_TO_VOID_IN_ARITHMETIC,E_NO_IMPLICIT_DECL_ALLOWED,E_ATTRIBUTE_PARAM_UNDEFINED" fi if test "x$krb5_ac_warn_cxxflags_set" = xset ; then AC_MSG_NOTICE(not adding extra warning flags because WARN_CXXFLAGS was set) else WARN_CXXFLAGS="-errtags=yes +w +w2 -xport64" fi fi fi AC_SUBST(WARN_CFLAGS) AC_SUBST(WARN_CXXFLAGS) ])dnl dnl dnl K5_GEN_MAKEFILE([dir, [frags]]) dnl AC_DEFUN(K5_GEN_MAKEFILE,[dnl ifelse($1, ,[_K5_GEN_MAKEFILE(.,$2)],[_K5_GEN_MAKEFILE($1,$2)]) ]) dnl dnl _K5_GEN_MAKEFILE(dir, [frags]) dnl dir must be present in this case dnl Note: Be careful in quoting. dnl The m4_foreach_w generates the list of fragments to include dnl or "" if $2 is empty AC_DEFUN(_K5_GEN_MAKEFILE,[dnl AC_CONFIG_FILES([$1/Makefile:$srcdir/]K5_TOPDIR[/config/pre.in:$1/Makefile.in:$1/deps:$srcdir/]K5_TOPDIR[/config/post.in]) ]) dnl dnl K5_GEN_FILE( ) dnl AC_DEFUN(K5_GEN_FILE,[AC_CONFIG_FILES($1)])dnl dnl dnl K5_AC_OUTPUT dnl Note: Adds the variables to config.status for individual dnl Makefile generation from config.status AC_DEFUN(K5_AC_OUTPUT,[AC_OUTPUT])dnl dnl dnl V5_AC_OUTPUT_MAKEFILE dnl AC_DEFUN(V5_AC_OUTPUT_MAKEFILE, [ifelse($1, , [_V5_AC_OUTPUT_MAKEFILE(.,$2)],[_V5_AC_OUTPUT_MAKEFILE($1,$2)])]) dnl define(_V5_AC_OUTPUT_MAKEFILE, [ifelse($2, , ,AC_CONFIG_FILES($2)) m4_foreach_w([DIR], [$1],dnl [AC_CONFIG_FILES(DIR[/Makefile:$srcdir/]K5_TOPDIR[/config/pre.in:]DIR[/Makefile.in:]DIR[/deps:$srcdir/]K5_TOPDIR[/config/post.in])]) K5_AC_OUTPUT])dnl dnl dnl dnl KRB5_SOCKADDR_SA_LEN: define HAVE_SA_LEN if sockaddr contains the sa_len dnl component dnl AC_DEFUN([KRB5_SOCKADDR_SA_LEN],[ dnl AC_CHECK_MEMBER(struct sockaddr.sa_len, AC_DEFINE(HAVE_SA_LEN,1,[Define if struct sockaddr contains sa_len]) ,,[#include #include ])]) dnl dnl WITH_NETLIB dnl dnl AC_DEFUN(WITH_NETLIB,[ AC_ARG_WITH([netlib], [AS_HELP_STRING([--with-netlib=LIBS], [use user defined resolver library])], [ if test "$withval" = yes -o "$withval" = no ; then AC_MSG_RESULT("netlib will link with C library resolver only") else LIBS="$LIBS $withval" AC_MSG_RESULT("netlib will use \'$withval\'") fi ],dnl [AC_LIBRARY_NET] )])dnl dnl dnl AC_DEFUN(KRB5_AC_NEED_DAEMON, [ KRB5_NEED_PROTO([#ifdef HAVE_UNISTD_H #include #endif],daemon,1)])dnl dnl dnl WITH_HESIOD dnl AC_DEFUN(WITH_HESIOD, [AC_ARG_WITH(hesiod, [AS_HELP_STRING([--with-hesiod[=path]], [compile with hesiod support @<:@omitted@:>@])], [hesiod=$with_hesiod], [with_hesiod=no]) if test "$with_hesiod" != "no"; then HESIOD_DEFS=-DHESIOD AC_CHECK_LIB(resolv, res_send, res_lib=-lresolv) if test "$hesiod" != "yes"; then HESIOD_LIBS="-L${hesiod}/lib -lhesiod $res_lib" else HESIOD_LIBS="-lhesiod $res_lib" fi else HESIOD_DEFS= HESIOD_LIBS= fi AC_SUBST(HESIOD_DEFS) AC_SUBST(HESIOD_LIBS)]) dnl dnl KRB5_BUILD_LIBRARY dnl dnl Pull in the necessary stuff to create the libraries. AC_DEFUN(KRB5_BUILD_LIBRARY, [AC_REQUIRE([KRB5_LIB_AUX])dnl AC_REQUIRE([AC_PROG_LN_S])dnl AC_REQUIRE([AC_PROG_RANLIB])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_CHECK_TOOL(AR, ar, false) if test "$AR" = "false"; then AC_MSG_ERROR([ar not found in PATH]) fi AC_CHECK_PROG(PERL, perl, perl, false) if test "$ac_cv_prog_PERL" = "false"; then AC_MSG_ERROR(Perl is now required for Kerberos builds.) fi AC_SUBST(LIBLIST) AC_SUBST(LIBLINKS) AC_SUBST(PLUGIN) AC_SUBST(PLUGINLINK) AC_SUBST(PLUGININST) AC_SUBST(KDB5_PLUGIN_DEPLIBS) AC_SUBST(KDB5_PLUGIN_LIBS) AC_SUBST(MAKE_SHLIB_COMMAND) AC_SUBST(SHLIB_RPATH_FLAGS) AC_SUBST(SHLIB_EXPFLAGS) AC_SUBST(SHLIB_EXPORT_FILE_DEP) AC_SUBST(DYNOBJ_EXPDEPS) AC_SUBST(DYNOBJ_EXPFLAGS) AC_SUBST(INSTALL_SHLIB) AC_SUBST(STLIBEXT) AC_SUBST(SHLIBEXT) AC_SUBST(SHLIBVEXT) AC_SUBST(SHLIBSEXT) AC_SUBST(DEPLIBEXT) AC_SUBST(PFLIBEXT) AC_SUBST(LIBINSTLIST) AC_SUBST(DYNOBJEXT) AC_SUBST(MAKE_DYNOBJ_COMMAND) AC_SUBST(UNDEF_CHECK) ]) dnl dnl KRB5_BUILD_LIBOBJS dnl dnl Pull in the necessary stuff to build library objects. AC_DEFUN(KRB5_BUILD_LIBOBJS, [AC_REQUIRE([KRB5_LIB_AUX])dnl AC_SUBST(OBJLISTS) AC_SUBST(STOBJEXT) AC_SUBST(SHOBJEXT) AC_SUBST(PFOBJEXT) AC_SUBST(PICFLAGS) AC_SUBST(PROFFLAGS)]) dnl dnl KRB5_BUILD_PROGRAM dnl dnl Set variables to build a program. AC_DEFUN(KRB5_BUILD_PROGRAM, [AC_REQUIRE([KRB5_LIB_AUX])dnl AC_SUBST(CC_LINK) AC_SUBST(CXX_LINK) AC_SUBST(RPATH_FLAG) AC_SUBST(PROG_RPATH_FLAGS) AC_SUBST(DEPLIBEXT)]) dnl dnl KRB5_RUN_FLAGS dnl dnl Set up environment for running dynamic executables out of build tree AC_DEFUN(KRB5_RUN_FLAGS, [AC_REQUIRE([KRB5_LIB_AUX])dnl KRB5_RUN_ENV="$RUN_ENV" KRB5_RUN_VARS="$RUN_VARS" AC_SUBST(KRB5_RUN_ENV) AC_SUBST(KRB5_RUN_VARS)]) dnl dnl KRB5_LIB_AUX dnl dnl Parse configure options related to library building. AC_DEFUN(KRB5_LIB_AUX, [AC_REQUIRE([KRB5_LIB_PARAMS])dnl AC_ARG_ENABLE([static],,, [enable_static=no]) AC_ARG_ENABLE([shared],,, [enable_shared=yes]) if test "x$enable_static" = "x$enable_shared"; then AC_MSG_ERROR([--enable-static must be specified with --disable-shared]) fi AC_ARG_ENABLE([rpath], [AS_HELP_STRING([--disable-rpath],[suppress run path flags in link lines])], [], [enable_rpath=yes]) if test "x$enable_rpath" != xyes ; then # Unset the rpath flag values set by shlib.conf SHLIB_RPATH_FLAGS= RPATH_FLAG= PROG_RPATH_FLAGS= fi if test "$SHLIBEXT" = ".so-nobuild"; then AC_MSG_ERROR([Shared libraries are not yet supported on this platform.]) fi DEPLIBEXT=$SHLIBEXT if test "x$enable_static" = xyes; then AC_MSG_NOTICE([using static libraries]) LIBLIST='lib$(LIBBASE)$(STLIBEXT)' LIBLINKS='$(TOPLIBD)/lib$(LIBBASE)$(STLIBEXT)' PLUGIN='libkrb5_$(LIBBASE)$(STLIBEXT)' PLUGINLINK='$(TOPLIBD)/libkrb5_$(LIBBASE)$(STLIBEXT)' PLUGININST=install-static OBJLISTS=OBJS.ST LIBINSTLIST=install-static DEPLIBEXT=$STLIBEXT AC_DEFINE([STATIC_PLUGINS], 1, [Define for static plugin linkage]) KDB5_PLUGIN_DEPLIBS='$(TOPLIBD)/libkrb5_db2$(DEPLIBEXT)' KDB5_PLUGIN_LIBS='-lkrb5_db2' if test "x$OPENLDAP_PLUGIN" = xyes; then KDB5_PLUGIN_DEBLIBS=$KDB5_PLUGIN_DEPLIBS' $(TOPLIBD)/libkrb5_ldap$(DEPLIBEXT) $(TOPLIBD)/libkdb_ldap$(DEPLIBEXT)' KDB5_PLUGIN_LIBS=$KDB5_PLUGIN_LIBS' -lkrb5_kldap -lkdb_ldap $(LDAP_LIBS)' fi # kadm5srv_mit normally comes before kdb on the link line. Add it # again after the KDB plugins, since they depend on it for XDR stuff. KDB5_PLUGIN_DEPLIBS=$KDB5_PLUGIN_DEPLIBS' $(TOPLIBD)/libkadm5srv_mit$(DEPLIBEXT)' KDB5_PLUGIN_LIBS=$KDB5_PLUGIN_LIBS' -lkadm5srv_mit' # avoid duplicate rules generation for AIX and such SHLIBEXT=.so-nobuild SHLIBVEXT=.so.v-nobuild SHLIBSEXT=.so.s-nobuild else AC_MSG_NOTICE([using shared libraries]) # Clear some stuff in case of AIX, etc. if test "$STLIBEXT" = "$SHLIBEXT" ; then STLIBEXT=.a-nobuild fi case "$SHLIBSEXT" in .so.s-nobuild) LIBLIST='lib$(LIBBASE)$(SHLIBEXT)' LIBLINKS='$(TOPLIBD)/lib$(LIBBASE)$(SHLIBEXT) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBVEXT)' LIBINSTLIST="install-shared" ;; *) LIBLIST='lib$(LIBBASE)$(SHLIBEXT) lib$(LIBBASE)$(SHLIBSEXT)' LIBLINKS='$(TOPLIBD)/lib$(LIBBASE)$(SHLIBEXT) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBVEXT) $(TOPLIBD)/lib$(LIBBASE)$(SHLIBSEXT)' LIBINSTLIST="install-shlib-soname" ;; esac OBJLISTS="OBJS.SH" PLUGIN='$(LIBBASE)$(DYNOBJEXT)' PLUGINLINK='../$(PLUGIN)' PLUGININST=install-plugin KDB5_PLUGIN_DEPLIBS= KDB5_PLUGIN_LIBS= fi CC_LINK="$CC_LINK_SHARED" CXX_LINK="$CXX_LINK_SHARED" if test -z "$LIBLIST"; then AC_MSG_ERROR([must enable one of shared or static libraries]) fi # Check whether to build profiled libraries. AC_ARG_ENABLE([profiled], dnl [ --enable-profiled build profiled libraries @<:@disabled@:>@] , [if test "$enableval" = yes; then AC_MSG_ERROR([Sorry, profiled libraries do not work in this release.]) fi])]) dnl dnl KRB5_LIB_PARAMS dnl dnl Determine parameters related to libraries, e.g. various extensions. AC_DEFUN(KRB5_LIB_PARAMS, [AC_REQUIRE([AC_CANONICAL_HOST])dnl krb5_cv_host=$host AC_SUBST(krb5_cv_host) AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([V5_SET_TOPDIR])dnl . $ac_topdir/config/shlib.conf]) dnl dnl The following was written by jhawk@mit.edu dnl dnl AC_LIBRARY_NET: Id: net.m4,v 1.4 1997/10/25 20:49:53 jhawk Exp dnl dnl This test is for network applications that need socket() and dnl gethostbyname() -ish functions. Under Solaris, those applications need to dnl link with "-lsocket -lnsl". Under IRIX, they should *not* link with dnl "-lsocket" because libsocket.a breaks a number of things (for instance: dnl gethostbyname() under IRIX 5.2, and snoop sockets under most versions of dnl IRIX). dnl dnl Unfortunately, many application developers are not aware of this, and dnl mistakenly write tests that cause -lsocket to be used under IRIX. It is dnl also easy to write tests that cause -lnsl to be used under operating dnl systems where neither are necessary (or useful), such as SunOS 4.1.4, which dnl uses -lnsl for TLI. dnl dnl This test exists so that every application developer does not test this in dnl a different, and subtly broken fashion. dnl dnl It has been argued that this test should be broken up into two separate dnl tests, one for the resolver libraries, and one for the libraries necessary dnl for using Sockets API. Unfortunately, the two are carefully intertwined and dnl allowing the autoconf user to use them independantly potentially results in dnl unfortunate ordering dependencies -- as such, such component macros would dnl have to carefully use indirection and be aware if the other components were dnl executed. Since other autoconf macros do not go to this trouble, and almost dnl no applications use sockets without the resolver, this complexity has not dnl been implemented. dnl dnl The check for libresolv is in case you are attempting to link statically dnl and happen to have a libresolv.a lying around (and no libnsl.a). dnl AC_DEFUN(AC_LIBRARY_NET, [ # Most operating systems have gethostbyname() in the default searched # libraries (i.e. libc): AC_CHECK_FUNC(gethostbyname, , [ # Some OSes (eg. Solaris) place it in libnsl: AC_CHECK_LIB(nsl, gethostbyname, , [ # Some strange OSes (SINIX) have it in libsocket: AC_CHECK_LIB(socket, gethostbyname, , [ # Unfortunately libsocket sometimes depends on libnsl. # AC_CHECK_LIB's API is essentially broken so the following # ugliness is necessary: AC_CHECK_LIB(socket, gethostbyname, LIBS="-lsocket -lnsl $LIBS", [AC_CHECK_LIB(resolv, gethostbyname, LIBS="-lresolv $LIBS" )], -lnsl) ]) ]) ]) AC_CHECK_FUNC(socket, , AC_CHECK_LIB(socket, socket, , AC_CHECK_LIB(socket, socket, LIBS="-lsocket -lnsl $LIBS", , -lnsl))) KRB5_AC_ENABLE_DNS if test "$enable_dns" = yes ; then # We assume that if libresolv exists we can link against it. # This may get us a gethostby* that doesn't respect nsswitch. AC_CHECK_LIB(resolv, main) _KRB5_AC_CHECK_RES_FUNCS(res_ninit res_nclose res_ndestroy res_nsearch dnl ns_initparse ns_name_uncompress dn_skipname res_search) if test $krb5_cv_func_res_nsearch = no \ && test $krb5_cv_func_res_search = no; then # Attempt to link with res_search(), in case it's not prototyped. AC_CHECK_FUNC(res_search, [AC_DEFINE(HAVE_RES_SEARCH, 1, [Define to 1 if you have the `res_search' function])], [AC_MSG_ERROR([cannot find res_nsearch or res_search])]) fi fi ]) AC_DEFUN([_KRB5_AC_CHECK_RES_FUNCS], [m4_foreach_w([AC_Func], [$1], [AH_TEMPLATE(AS_TR_CPP(HAVE_[]AC_Func), [Define to 1 if you have the `]AC_Func[' function.])])dnl for krb5_func in $1; do _KRB5_AC_CHECK_RES_FUNC($krb5_func) done ]) AC_DEFUN([_KRB5_AC_CHECK_RES_FUNC], [ # Solaris 9 prototypes ns_name_uncompress() in arpa/nameser.h, but # doesn't export it from libresolv.so, so we use extreme paranoia here # and check both for the declaration and that we can link against the # function. AC_CACHE_CHECK([for $1], [krb5_cv_func_$1], [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include #include #include #include ]], [[/* * Use volatile, or else optimization can cause false positives. */ void (* volatile p)() = (void (*)())$1;]])], [AS_VAR_SET(krb5_cv_func_$1, yes)], [AS_VAR_SET(krb5_cv_func_$1, no)])]) AS_IF([test AS_VAR_GET(krb5_cv_func_$1) = yes], [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1]), 1, [Define to 1 if you have the `$1' function])])[]dnl ]) dnl dnl dnl KRB5_AC_ENABLE_DNS dnl AC_DEFUN(KRB5_AC_ENABLE_DNS, [ enable_dns=yes AC_ARG_ENABLE([dns-for-realm], [ --enable-dns-for-realm enable DNS lookups of Kerberos realm names], , [enable_dns_for_realm=no]) if test "$enable_dns_for_realm" = yes; then AC_DEFINE(KRB5_DNS_LOOKUP_REALM,1,[Define to enable DNS lookups of Kerberos realm names]) fi AC_DEFINE(KRB5_DNS_LOOKUP, 1,[Define for DNS support of locating realms and KDCs]) ]) dnl dnl dnl Check if we need the prototype for a function - we give it a bogus dnl prototype and if it complains - then a valid prototype exists on the dnl system. dnl dnl KRB5_NEED_PROTO(includes, function, [bypass]) dnl if $3 set, don't see if library defined. dnl Useful for case where we will define in libkrb5 the function if need be dnl but want to know if a prototype exists in either case on system. dnl AC_DEFUN([KRB5_NEED_PROTO], [ ifelse([$3], ,[if test "x$ac_cv_func_$2" = xyes; then]) AC_CACHE_CHECK([if $2 needs a prototype provided], krb5_cv_func_$2_noproto, [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[$1]], [[#undef $2 struct k5foo {int foo; } xx; extern int $2 (struct k5foo*); $2(&xx);]])], [krb5_cv_func_$2_noproto=yes], [krb5_cv_func_$2_noproto=no])]) if test $krb5_cv_func_$2_noproto = yes; then AC_DEFINE([NEED_]translit($2, [a-z], [A-Z])[_PROTO], 1, dnl [define if the system header files are missing prototype for $2()]) fi ifelse([$3], ,[fi]) ]) dnl dnl ============================================================= dnl Internal function for testing for getpeername prototype dnl AC_DEFUN([KRB5_GETPEERNAME_ARGS],[ AC_DEFINE([GETPEERNAME_ARG3_TYPE],GETSOCKNAME_ARG3_TYPE,[Type of getpeername second argument.]) ]) dnl dnl ============================================================= dnl Internal function for testing for getsockname arguments dnl AC_DEFUN([TRY_GETSOCK_INT],[ krb5_lib_var=`echo "$1 $2" | sed 'y% ./+-*%___p_p%'` AC_MSG_CHECKING([if getsockname() takes arguments $1 and $2]) AC_CACHE_VAL(krb5_cv_getsockname_proto_$krb5_lib_var, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [[#include #include extern int getsockname(int, $1, $2);]])], [eval "krb5_cv_getsockname_proto_$krb5_lib_var=yes"], [eval "krb5_cv_getsockname_proto_$krb5_lib_var=no"])]) if eval "test \"`echo '$krb5_cv_getsockname_proto_'$krb5_lib_var`\" = yes"; then AC_MSG_RESULT(yes) sock_set=yes; res1="$1"; res2="$2" else AC_MSG_RESULT(no) fi ]) dnl dnl Determines the types of the second and third arguments to getsockname(). dnl AC_DEFUN([KRB5_GETSOCKNAME_ARGS],[ sock_set=no for sock_arg1 in "struct sockaddr *" "void *" do for sock_arg2 in "size_t *" "int *" "socklen_t *" do if test $sock_set = no; then TRY_GETSOCK_INT($sock_arg1, $sock_arg2) fi done done if test "$sock_set" = no; then AC_MSG_NOTICE(assuming struct sockaddr and socklen_t for getsockname args) res1="struct sockaddr *" res2="socklen_t *" fi res1=`echo "$res1" | tr -d '*' | sed -e 's/ *$//'` res2=`echo "$res2" | tr -d '*' | sed -e 's/ *$//'` AC_DEFINE_UNQUOTED([GETSOCKNAME_ARG3_TYPE],$res2,[Type of pointer target for argument 3 to getsockname]) ]) dnl dnl AC_DEFUN([KRB5_AC_CHOOSE_ET],[ AC_ARG_WITH([system-et], [AS_HELP_STRING([--with-system-et], [use system compile_et and -lcom_err @<:@default: build and install a local version@:>@])]) AC_MSG_CHECKING(which version of com_err to use) if test "x$with_system_et" = xyes ; then # This will be changed to "intlsys" if textdomain support is present. COM_ERR_VERSION=sys AC_MSG_RESULT(system) else COM_ERR_VERSION=k5 AC_MSG_RESULT(krb5) fi OLDLIBS="$LIBS" COM_ERR_LIB=-lcom_err if test $COM_ERR_VERSION = sys; then PKG_CHECK_MODULES(COM_ERR, com_err, [have_com_err=yes], [have_com_err=no]) if test "x$have_com_err = xyes"; then COM_ERR_LIB="$COM_ERR_LIBS" fi LIBS="$LIBS $COM_ERR_LIB" # check for various functions we need AC_CHECK_LIB(com_err, add_error_table, :, AC_MSG_ERROR(cannot find add_error_table in com_err library)) AC_CHECK_LIB(com_err, remove_error_table, :, AC_MSG_ERROR(cannot find remove_error_table in com_err library)) # make sure compile_et provides "et_foo" name cat >> conf$$e.et </dev/null 2>&1 ; then true ; else AC_MSG_ERROR(execution failed) fi AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include "conf$$e.h" ]], [[&et_foo_error_table;]])], [], [AC_MSG_ERROR(cannot use et_foo_error_table)]) # Anything else we need to test for? rm -f conf$$e.c conf$$e.h krb5_cv_compile_et_useful=yes ]) AC_CACHE_CHECK(whether compile_et supports --textdomain, krb5_cv_compile_et_textdomain,[ krb5_cv_compile_et_textdomain=no if compile_et --textdomain=xyzw conf$$e.et >/dev/null 2>&1 ; then if grep -q xyzw conf$$e.c; then krb5_cv_compile_et_textdomain=yes fi fi rm -f conf$$e.c conf$$e.h ]) if test "$krb5_cv_compile_et_textdomain" = yes; then COM_ERR_VERSION=intlsys fi rm -f conf$$e.et fi AC_SUBST(COM_ERR_VERSION) AC_SUBST(COM_ERR_LIB) LIBS="$OLDLIBS" if test "$COM_ERR_VERSION" = k5 -o "$COM_ERR_VERSION" = intlsys; then AC_DEFINE(HAVE_COM_ERR_INTL,1, [Define if com_err has compatible gettext support]) fi ]) AC_DEFUN([KRB5_AC_CHOOSE_SS],[ AC_ARG_WITH(system-ss, [AS_HELP_STRING([--with-system-ss], [use system -lss and mk_cmds @<:@private version@:>@])]) AC_ARG_VAR(SS_LIB,[system libraries for 'ss' package [-lss]]) AC_MSG_CHECKING(which version of subsystem package to use) if test "x$with_system_ss" = xyes ; then SS_VERSION=sys AC_MSG_RESULT(system) # todo: check for various libraries we might need # in the meantime... test "x${SS_LIB+set}" = xset || SS_LIB=-lss old_LIBS="$LIBS" LIBS="$LIBS $SS_LIB" AC_CACHE_CHECK(whether system ss package works, krb5_cv_system_ss_okay, [AC_RUN_IFELSE( [AC_LANG_SOURCE( [[#include int main(int argc, char *argv[]) { if (argc == 42) { int i, err; i = ss_create_invocation("foo","foo","",0,&err); ss_listen(i); } return 0; }]])], [krb5_cv_system_ss_okay=yes], [AC_MSG_ERROR(cannot run test program)], [krb5_cv_system_ss_okay=assumed])]) LIBS="$old_LIBS" KRB5_NEED_PROTO([#include ],ss_execute_command,1) else SS_VERSION=k5 AC_MSG_RESULT(krb5) fi AC_SUBST(SS_LIB) AC_SUBST(SS_VERSION) ]) dnl AC_DEFUN([KRB5_AC_CHOOSE_DB],[ AC_ARG_WITH(system-db, [AS_HELP_STRING([--with-system-db], [use system Berkeley db @<:@private version@:>@])]) AC_ARG_VAR(DB_HEADER,[header file for system Berkeley db package [db.h]]) AC_ARG_VAR(DB_LIB,[library for system Berkeley db package [-ldb]]) if test "x$with_system_db" = xyes ; then DB_VERSION=sys # TODO: Do we have specific routines we should check for? # How about known, easily recognizable bugs? # We want to use bt_rseq in some cases, but no other version but # ours has it right now. # # Okay, check the variables. test "x${DB_HEADER+set}" = xset || DB_HEADER=db.h test "x${DB_LIB+set}" = xset || DB_LIB=-ldb # if test "x${DB_HEADER}" = xdb.h ; then DB_HEADER_VERSION=sys else DB_HEADER_VERSION=redirect fi KDB5_DB_LIB="$DB_LIB" else DB_VERSION=k5 AC_DEFINE(HAVE_BT_RSEQ,1,[Define if bt_rseq is available, for recursive btree traversal.]) DB_HEADER=db.h DB_HEADER_VERSION=k5 # libdb gets sucked into libkdb KDB5_DB_LIB= # needed for a couple of things that need libdb for its own sake DB_LIB=-ldb fi AC_SUBST(DB_VERSION) AC_SUBST(DB_HEADER) AC_SUBST(DB_HEADER_VERSION) AC_SUBST(DB_LIB) AC_SUBST(KDB5_DB_LIB) ]) dnl dnl KRB5_AC_PRIOCNTL_HACK dnl dnl AC_DEFUN([KRB5_AC_PRIOCNTL_HACK], [AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_LANG_COMPILER_REQUIRE])dnl AC_CACHE_CHECK([whether to use priocntl hack], [krb5_cv_priocntl_hack], [case $krb5_cv_host in *-*-solaris2.9*) if test "$cross_compiling" = yes; then krb5_cv_priocntl_hack=yes else # Solaris patch 117171-11 (sparc) or 117172-11 (x86) # fixes the Solaris 9 bug where final pty output # gets lost on close. if showrev -p | $AWK 'BEGIN { e = 1 } /Patch: 11717[[12]]/ { x = index[]([$]2, "-"); if (substr[]([$]2, x + 1, length([$]2) - x) >= 11) { e = 0 } else { e = 1 } } END { exit e; }'; then krb5_cv_priocntl_hack=no else krb5_cv_priocntl_hack=yes fi fi ;; *) krb5_cv_priocntl_hack=no ;; esac]) if test "$krb5_cv_priocntl_hack" = yes; then PRIOCNTL_HACK=1 else PRIOCNTL_HACK=0 fi AC_SUBST(PRIOCNTL_HACK)]) dnl dnl dnl KRB5_AC_GCC_ATTRS AC_DEFUN([KRB5_AC_GCC_ATTRS], [AC_CACHE_CHECK([for constructor/destructor attribute support],krb5_cv_attr_constructor_destructor, [rm -f conftest.1 conftest.2 if test -r conftest.1 || test -r conftest.2 ; then AC_MSG_ERROR(write error in local file system?) fi true > conftest.1 true > conftest.2 if test -r conftest.1 && test -r conftest.2 ; then true ; else AC_MSG_ERROR(write error in local file system?) fi a=no b=no # blindly assume we have 'unlink' and unistd.h. AC_RUN_IFELSE( [AC_LANG_SOURCE( [[#include void foo1() __attribute__((constructor)); void foo1() { unlink("conftest.1"); } void foo2() __attribute__((destructor)); void foo2() { unlink("conftest.2"); } int main () { return 0; }]])], [test -r conftest.1 || a=yes test -r conftest.2 || b=yes], [], [AC_MSG_ERROR(Cannot test for constructor/destructor support when cross compiling)]) case $krb5_cv_host in *-*-aix4.*) # Under AIX 4.3.3, at least, shared library destructor functions # appear to get executed in reverse link order (right to left), # so that a library's destructor function may run after that of # libraries it depends on, and may still have to access in the # destructor. # # That counts as "not working", for me, but it's a much more # complicated test case to set up. b=no ;; esac krb5_cv_attr_constructor_destructor="$a,$b" ]) # Okay, krb5_cv_... should be set now. case $krb5_cv_attr_constructor_destructor in yes,*) AC_DEFINE(CONSTRUCTOR_ATTR_WORKS,1,[Define if __attribute__((constructor)) works]) ;; esac case $krb5_cv_attr_constructor_destructor in *,yes) AC_DEFINE(DESTRUCTOR_ATTR_WORKS,1,[Define if __attribute__((destructor)) works]) ;; esac dnl End of attributes we care about right now. ]) dnl dnl dnl KRB5_AC_PRAGMA_WEAK_REF AC_DEFUN([KRB5_AC_PRAGMA_WEAK_REF], [AC_CACHE_CHECK([whether pragma weak references are supported], krb5_cv_pragma_weak_ref, [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#pragma weak flurbl extern int flurbl(void);]], [[if (&flurbl != 0) return flurbl();]])], [krb5_cv_pragma_weak_ref=yes], [krb5_cv_pragma_weak_ref=no])]) if test $krb5_cv_pragma_weak_ref = yes ; then AC_DEFINE(HAVE_PRAGMA_WEAK_REF,1,[Define if #pragma weak references work]) fi]) dnl dnl m4_include(config/ac-archive/ax_pthread.m4) m4_include(config/ac-archive/ax_recursive_eval.m4) m4_include(config/pkg.m4) dnl dnl dnl dnl --with-ldap=value dnl AC_DEFUN(WITH_LDAP,[ AC_ARG_WITH([ldap], [AS_HELP_STRING([--with-ldap], [compile OpenLDAP database backend module])], [case "$withval" in OPENLDAP) with_ldap=yes ;; yes | no) ;; *) AC_MSG_ERROR(Invalid option value --with-ldap="$withval") ;; esac], with_ldap=no)dnl if test "$with_ldap" = yes; then AC_MSG_NOTICE(enabling OpenLDAP database backend module support) OPENLDAP_PLUGIN=yes fi ])dnl krb5-1.22.1/src/kprop/0000775000175000017500000000000015051422640014263 5ustar ghudsonghudsonkrb5-1.22.1/src/kprop/replica_update0000664000175000017500000000134115051422640017166 0ustar ghudsonghudson#!/bin/sh # # Propagate if database (principal.db) has been modified since last dump # (dumpfile.dump_ok) or if database has been dumped since last successful # propagation (dumpfile..last_prop) KDB_DIR=/usr/local/var/krb5kdc KDB_FILE=$KDB_DIR/principal.db DUMPFILE=$KDB_DIR/replica_datatrans KDB5_UTIL=/usr/local/sbin/kdb5_util KPROP=/usr/local/sbin/kprop REPLICA=$1 if [ -z "${REPLICA}" ] then echo "Usage $0 replica_server" fi if [ "`ls -t $DUMPFILE.dump_ok $KDB_FILE | sed -n 1p`" = "$KDB_FILE" -o \ "`ls -t $DUMPFILE.${REPLICA}.last_prop $DUMPFILE.dump_ok | \ sed -n 1p`" = "$DUMPFILE.dump_ok" ] then date $KDB5_UTIL dump $DUMPFILE > /dev/null $KPROP -d -f $DUMPFILE ${REPLICA} rm $DUMPFILE fi krb5-1.22.1/src/kprop/Makefile.in0000664000175000017500000000174715051422640016341 0ustar ghudsonghudsonmydir=kprop BUILDTOP=$(REL).. all: kprop kpropd kproplog CLIENTSRCS= $(srcdir)/kprop.c $(srcdir)/kprop_util.c CLIENTOBJS= kprop.o kprop_util.o SERVERSRCS= $(srcdir)/kpropd.c $(srcdir)/kpropd_rpc.c $(srcdir)/kprop_util.c SERVEROBJS= kpropd.o kpropd_rpc.o kprop_util.o LOGSRCS= $(srcdir)/kproplog.c LOGOBJS= kproplog.o SRCS= $(CLIENTSRCS) $(SERVERSRCS) $(LOGSRCS) kprop: $(CLIENTOBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kprop $(CLIENTOBJS) $(KRB5_BASE_LIBS) @LIBUTIL@ kpropd: $(SERVEROBJS) $(KDB5_DEPLIB) $(KADMCLNT_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB) $(CC_LINK) -o kpropd $(SERVEROBJS) $(KDB5_LIB) $(KADMCLNT_LIBS) $(KRB5_BASE_LIBS) $(APPUTILS_LIB) @LIBUTIL@ kproplog: $(LOGOBJS) $(CC_LINK) -o kproplog $(LOGOBJS) $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) install: for f in kprop kpropd kproplog; do \ $(INSTALL_PROGRAM) $$f \ $(DESTDIR)$(SERVER_BINDIR)/`echo $$f|sed '$(transform)'`; \ done clean: $(RM) $(CLIENTOBJS) $(SERVEROBJS) $(LOGOBJS) $(RM) kprop kpropd kproplog krb5-1.22.1/src/kprop/kpropd.c0000664000175000017500000014462215051422640015737 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* kprop/kpropd.c */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* * Copyright 1990,1991,2007 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "com_err.h" #include "fake-addrinfo.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kprop.h" #include #include "iprop.h" #include #include #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE unsigned int #endif #ifndef GETPEERNAME_ARG3_TYPE #define GETPEERNAME_ARG3_TYPE unsigned int #endif #if defined(NEED_DAEMON_PROTO) extern int daemon(int, int); #endif #define SYSLOG_CLASS LOG_DAEMON int runonce = 0; /* * This struct simulates the use of _kadm5_server_handle_t * * This is a COPY of kadm5_server_handle_t from * lib/kadm5/clnt/client_internal.h! */ typedef struct _kadm5_iprop_handle_t { krb5_ui_4 magic_number; krb5_ui_4 struct_version; krb5_ui_4 api_version; char *cache_name; int destroy_cache; CLIENT *clnt; krb5_context context; kadm5_config_params params; struct _kadm5_iprop_handle_t *lhandle; } *kadm5_iprop_handle_t; static char *kprop_version = KPROP_PROT_VERSION; static kadm5_config_params params; static char *progname; static int debug = 0; static int nodaemon = 0; static char *keytab_path = NULL; static int standalone = 0; static const char *pid_file = NULL; static pid_t fullprop_child = (pid_t)-1; static krb5_principal server; /* This is our server principal name */ static krb5_principal client; /* This is who we're talking to */ static krb5_context kpropd_context; static krb5_auth_context auth_context; static char *realm = NULL; /* Our realm */ static char *def_realm = NULL; /* Ref pointer for default realm */ static char *file = KPROPD_DEFAULT_FILE; static char *temp_file_name; static char *kdb5_util = KPROPD_DEFAULT_KDB5_UTIL; static char *kerb_database = NULL; static char *acl_file_name = KPROPD_ACL_FILE; static krb5_address *receiver_addr; static const char *port = KPROP_SERVICE; static char **db_args = NULL; static size_t db_args_size = 0; static void parse_args(int argc, char **argv); static void do_standalone(void); static void doit(int fd); static krb5_error_code do_iprop(void); static void kerberos_authenticate(krb5_context context, int fd, krb5_principal *clientp, krb5_enctype *etype, struct sockaddr_storage *my_sin); static krb5_boolean authorized_principal(krb5_context context, krb5_principal p, krb5_enctype auth_etype); static void recv_database(krb5_context context, int fd, int database_fd, krb5_data *confmsg); static void load_database(krb5_context context, char *kdb_util, char *database_file_name); static void send_error(krb5_context context, int fd, krb5_error_code err_code, char *err_text); static void recv_error(krb5_context context, krb5_data *inbuf); static unsigned int backoff_from_primary(int *cnt); static kadm5_ret_t kadm5_get_kiprop_host_srv_name(krb5_context context, const char *realm_name, char **host_service_name); static void usage(void) { fprintf(stderr, _("\nUsage: %s [-r realm] [-s keytab] [-d] [-D] [-S]\n" "\t[-f replica_file] [-F kerberos_db_file ]\n" "\t[-p kdb5_util_pathname] [-x db_args]* [-P port]\n" "\t[-a acl_file] [-A admin_server] [--pid-file=pid_file]\n"), progname); exit(1); } static krb5_error_code write_pid_file(const char *path) { FILE *fp; unsigned long pid; int st1, st2; fp = fopen(path, "w"); if (fp == NULL) return errno; pid = (unsigned long)getpid(); st1 = (fprintf(fp, "%ld\n", pid) < 0) ? errno : 0; st2 = (fclose(fp) == EOF) ? errno : 0; return st1 ? st1 : st2; } typedef void (*sig_handler_fn)(int sig); static void signal_wrapper(int sig, sig_handler_fn handler) { #ifdef POSIX_SIGNALS struct sigaction s_action; memset(&s_action, 0, sizeof(s_action)); sigemptyset(&s_action.sa_mask); s_action.sa_handler = handler; sigaction(sig, &s_action, NULL); #else signal(sig, handler); #endif } static void alarm_handler(int sig) { static char *timeout_msg = "Full propagation timed out\n"; write(STDERR_FILENO, timeout_msg, strlen(timeout_msg)); exit(1); } static void usr1_handler(int sig) { /* Nothing to do, just let the signal interrupt sleep(). */ } static void kill_do_standalone(int sig) { if (fullprop_child > 0) { if (debug) { fprintf(stderr, _("Killing fullprop child (%d)\n"), (int)fullprop_child); } kill(fullprop_child, sig); } /* Make sure our exit status code reflects our having been signaled */ signal_wrapper(sig, SIG_DFL); kill(getpid(), sig); } static void atexit_kill_do_standalone(void) { if (fullprop_child > 0) kill(fullprop_child, SIGHUP); } int main(int argc, char **argv) { krb5_error_code retval; kdb_log_context *log_ctx; int devnull, sock; struct stat st; setlocale(LC_ALL, ""); parse_args(argc, argv); if (fstat(0, &st) == -1) { com_err(progname, errno, _("while checking if stdin is a socket")); exit(1); } /* * Detect whether we're running from inetd; if not then we're in * standalone mode. */ standalone = !S_ISSOCK(st.st_mode); log_ctx = kpropd_context->kdblog_context; signal_wrapper(SIGPIPE, SIG_IGN); if (standalone) { /* "ready" is a sentinel for the test framework. */ if (!debug && !nodaemon) { daemon(0, 0); } else { printf(_("ready\n")); fflush(stdout); } if (pid_file != NULL) { retval = write_pid_file(pid_file); if (retval) { syslog(LOG_ERR, _("Could not write pid file %s: %s"), pid_file, strerror(errno)); exit(1); } } } else { /* * We're an inetd nowait service. Let's not risk anything * read/write from/to the inetd socket unintentionally. */ devnull = open("/dev/null", O_RDWR); if (devnull == -1) { syslog(LOG_ERR, _("Could not open /dev/null: %s"), strerror(errno)); exit(1); } sock = dup(0); if (sock == -1) { syslog(LOG_ERR, _("Could not dup the inetd socket: %s"), strerror(errno)); exit(1); } dup2(devnull, STDIN_FILENO); dup2(devnull, STDOUT_FILENO); dup2(devnull, STDERR_FILENO); close(devnull); doit(sock); exit(0); } if (log_ctx == NULL || log_ctx->iproprole != IPROP_REPLICA) { do_standalone(); /* do_standalone() should never return */ assert(0); } /* * This is the iprop case. We'll fork a child to run do_standalone(). The * parent will run do_iprop(). We try to kill the child if we get killed. * Catch SIGUSR1, which can be used to interrupt the sleep timer and force * an iprop request. */ signal_wrapper(SIGHUP, kill_do_standalone); signal_wrapper(SIGINT, kill_do_standalone); signal_wrapper(SIGQUIT, kill_do_standalone); signal_wrapper(SIGTERM, kill_do_standalone); signal_wrapper(SIGSEGV, kill_do_standalone); signal_wrapper(SIGUSR1, usr1_handler); atexit(atexit_kill_do_standalone); fullprop_child = fork(); switch (fullprop_child) { case -1: com_err(progname, errno, _("do_iprop failed.\n")); break; case 0: do_standalone(); /* do_standalone() should never return */ /* NOTREACHED */ break; default: retval = do_iprop(); /* do_iprop() can return due to failures and runonce. */ kill(fullprop_child, SIGHUP); wait(NULL); if (retval) com_err(progname, retval, _("do_iprop failed.\n")); else exit(0); } exit(1); } /* Use getaddrinfo to determine a wildcard listener address, preferring * IPv6 if available. */ static int get_wildcard_addr(struct addrinfo **res) { struct addrinfo hints; int error; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; hints.ai_family = AF_INET6; error = getaddrinfo(NULL, port, &hints, res); if (error == 0) return 0; hints.ai_family = AF_INET; return getaddrinfo(NULL, port, &hints, res); } static void do_standalone(void) { struct sockaddr_in frominet; struct addrinfo *res; GETPEERNAME_ARG3_TYPE fromlen; int finet, s, ret, error, val, status; pid_t child_pid; pid_t wait_pid; error = get_wildcard_addr(&res); if (error != 0) { fprintf(stderr, _("getaddrinfo: %s\n"), gai_strerror(error)); exit(1); } finet = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (finet < 0) { com_err(progname, errno, _("while obtaining socket")); exit(1); } val = 1; if (setsockopt(finet, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0) com_err(progname, errno, _("while setting SO_REUSEADDR option")); #if defined(IPV6_V6ONLY) /* Make sure dual-stack support is enabled on IPv6 listener sockets if * possible. */ val = 0; if (res->ai_family == AF_INET6 && setsockopt(finet, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)) < 0) com_err(progname, errno, _("while unsetting IPV6_V6ONLY option")); #endif ret = bind(finet, res->ai_addr, res->ai_addrlen); if (ret < 0) { com_err(progname, errno, _("while binding listener socket")); exit(1); } if (listen(finet, 5) < 0) { com_err(progname, errno, "in listen call"); exit(1); } for (;;) { memset(&frominet, 0, sizeof(frominet)); fromlen = sizeof(frominet); if (debug) fprintf(stderr, _("waiting for a kprop connection\n")); s = accept(finet, (struct sockaddr *) &frominet, &fromlen); if (s < 0) { int e = errno; if (e != EINTR) { com_err(progname, e, _("while accepting connection")); } } child_pid = fork(); switch (child_pid) { case -1: com_err(progname, errno, _("while forking")); exit(1); case 0: close(finet); doit(s); close(s); _exit(0); default: do { wait_pid = waitpid(child_pid, &status, 0); } while (wait_pid == -1 && errno == EINTR); if (wait_pid == -1) { /* Something bad happened; panic. */ if (debug) { fprintf(stderr, _("waitpid() failed to wait for doit() " "(%d %s)\n"), errno, strerror(errno)); } com_err(progname, errno, _("while waiting to receive database")); exit(1); } if (debug) { fprintf(stderr, _("Database load process for full propagation " "completed.\n")); } close(s); /* If we are the fullprop child in iprop mode, notify the parent * process that it should poll for incremental updates. */ if (fullprop_child == 0) kill(getppid(), SIGUSR1); else if (runonce) exit(0); } } exit(0); } static void doit(int fd) { struct sockaddr_storage from; int on = 1; GETPEERNAME_ARG3_TYPE fromlen; krb5_error_code retval; krb5_data confmsg; int lock_fd; mode_t omask; krb5_enctype etype; int database_fd; char host[INET6_ADDRSTRLEN + 1]; signal_wrapper(SIGALRM, alarm_handler); alarm(params.iprop_resync_timeout); fromlen = sizeof(from); if (getpeername(fd, (struct sockaddr *)&from, &fromlen) < 0) { #ifdef ENOTSOCK if (errno == ENOTSOCK && fd == 0 && !standalone) { fprintf(stderr, _("%s: Standard input does not appear to be a network " "socket.\n" "\t(Not run from inetd, and missing the -S option?)\n"), progname); exit(1); } #endif fprintf(stderr, "%s: ", progname); perror("getpeername"); exit(1); } if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) { com_err(progname, errno, _("while attempting setsockopt (SO_KEEPALIVE)")); } if (getnameinfo((const struct sockaddr *) &from, fromlen, host, sizeof(host), NULL, 0, 0) == 0) { syslog(LOG_INFO, _("Connection from %s"), host); if (debug) fprintf(stderr, "Connection from %s\n", host); } /* * Now do the authentication */ kerberos_authenticate(kpropd_context, fd, &client, &etype, &from); if (!authorized_principal(kpropd_context, client, etype)) { char *name; retval = krb5_unparse_name(kpropd_context, client, &name); if (retval) { com_err(progname, retval, "While unparsing client name"); exit(1); } if (debug) { fprintf(stderr, _("Rejected connection from unauthorized principal %s\n"), name); } syslog(LOG_WARNING, _("Rejected connection from unauthorized principal %s"), name); free(name); exit(1); } omask = umask(077); lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600); (void)umask(omask); retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK); if (retval) { com_err(progname, retval, _("while trying to lock '%s'"), temp_file_name); exit(1); } database_fd = open(temp_file_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (database_fd < 0) { com_err(progname, errno, _("while opening database file, '%s'"), temp_file_name); exit(1); } recv_database(kpropd_context, fd, database_fd, &confmsg); if (rename(temp_file_name, file)) { com_err(progname, errno, _("while renaming %s to %s"), temp_file_name, file); exit(1); } retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_SHARED); if (retval) { com_err(progname, retval, _("while downgrading lock on '%s'"), temp_file_name); exit(1); } load_database(kpropd_context, kdb5_util, file); retval = krb5_lock_file(kpropd_context, lock_fd, KRB5_LOCKMODE_UNLOCK); if (retval) { com_err(progname, retval, _("while unlocking '%s'"), temp_file_name); exit(1); } close(lock_fd); /* * Send the acknowledgement message generated in * recv_database, then close the socket. */ retval = krb5_write_message(kpropd_context, &fd, &confmsg); if (retval) { krb5_free_data_contents(kpropd_context, &confmsg); com_err(progname, retval, _("while sending # of received bytes")); exit(1); } krb5_free_data_contents(kpropd_context, &confmsg); if (close(fd) < 0) { com_err(progname, errno, _("while trying to close database file")); exit(1); } exit(0); } /* Default timeout can be changed using clnt_control() */ static struct timeval full_resync_timeout = { 25, 0 }; static kdb_fullresync_result_t * full_resync(CLIENT *clnt) { static kdb_fullresync_result_t clnt_res; uint32_t vers = IPROPX_VERSION_1; /* max version we support */ enum clnt_stat status; memset(&clnt_res, 0, sizeof(clnt_res)); status = clnt_call(clnt, IPROP_FULL_RESYNC_EXT, (xdrproc_t)xdr_u_int32, &vers, (xdrproc_t)xdr_kdb_fullresync_result_t, &clnt_res, full_resync_timeout); if (status == RPC_PROCUNAVAIL) { status = clnt_call(clnt, IPROP_FULL_RESYNC, (xdrproc_t)xdr_void, &vers, (xdrproc_t)xdr_kdb_fullresync_result_t, &clnt_res, full_resync_timeout); } return (status == RPC_SUCCESS) ? &clnt_res : NULL; } /* * Beg for incrementals from the KDC. * * Returns 0 on success IFF runonce is true. * Returns non-zero on failure due to errors. */ krb5_error_code do_iprop(void) { kadm5_ret_t retval; krb5_principal iprop_svc_principal = NULL; void *server_handle = NULL; char *iprop_svc_princstr = NULL, *primary_svc_princstr = NULL; unsigned int pollin, backoff_time; int backoff_cnt = 0, reinit_cnt = 0; struct timeval iprop_start, iprop_end; unsigned long usec; time_t frrequested = 0, now; kdb_incr_result_t *incr_ret; kdb_last_t mylast; kdb_fullresync_result_t *full_ret; kadm5_iprop_handle_t handle; if (debug) fprintf(stderr, _("Incremental propagation enabled\n")); pollin = params.iprop_poll_time; if (pollin == 0) pollin = 10; retval = kadm5_get_kiprop_host_srv_name(kpropd_context, realm, &primary_svc_princstr); if (retval) { com_err(progname, retval, _("%s: unable to get kiprop host based " "service name for realm %s\n"), progname, realm); goto done; } retval = sn2princ_realm(kpropd_context, NULL, KIPROP_SVC_NAME, realm, &iprop_svc_principal); if (retval) { com_err(progname, retval, _("while trying to construct host service principal")); goto done; } retval = krb5_unparse_name(kpropd_context, iprop_svc_principal, &iprop_svc_princstr); if (retval) { com_err(progname, retval, _("while canonicalizing principal name")); goto done; } reinit: /* * Authentication, initialize rpcsec_gss handle etc. */ if (debug) { fprintf(stderr, _("Initializing kadm5 as client %s\n"), iprop_svc_princstr); } retval = kadm5_init_with_skey(kpropd_context, iprop_svc_princstr, keytab_path, primary_svc_princstr, ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, db_args, &server_handle); if (retval) { if (debug) fprintf(stderr, _("kadm5 initialization failed!\n")); if (retval == KADM5_RPC_ERROR) { reinit_cnt++; if (server_handle) kadm5_destroy(server_handle); server_handle = NULL; handle = NULL; com_err(progname, retval, _( "while attempting to connect" " to primary KDC ... retrying")); backoff_time = backoff_from_primary(&reinit_cnt); if (debug) { fprintf(stderr, _("Sleeping %d seconds to re-initialize " "kadm5 (RPC ERROR)\n"), backoff_time); } sleep(backoff_time); goto reinit; } else { if (retval == KADM5_BAD_CLIENT_PARAMS || retval == KADM5_BAD_SERVER_PARAMS) { com_err(progname, retval, _("while initializing %s interface"), progname); usage(); } reinit_cnt++; com_err(progname, retval, _("while initializing %s interface, retrying"), progname); backoff_time = backoff_from_primary(&reinit_cnt); if (debug) { fprintf(stderr, _("Sleeping %d seconds to re-initialize " "kadm5 (krb5kdc not running?)\n"), backoff_time); } sleep(backoff_time); goto reinit; } } if (debug) fprintf(stderr, _("kadm5 initialization succeeded\n")); /* * Reset re-initialization count to zero now. */ reinit_cnt = backoff_time = 0; /* * Reset the handle to the correct type for the RPC call */ handle = server_handle; for (;;) { incr_ret = NULL; full_ret = NULL; /* * Get the most recent ulog entry sno + ts, which * we package in the request to the primary KDC */ retval = ulog_get_last(kpropd_context, &mylast); if (retval) { com_err(progname, retval, _("reading update log header")); goto done; } /* * Loop continuously on an iprop_get_updates_1(), * so that we can keep probing the primary for updates * or (if needed) do a full resync of the krb5 db. */ if (debug) { fprintf(stderr, _("Calling iprop_get_updates_1 " "(sno=%u sec=%u usec=%u)\n"), (unsigned int)mylast.last_sno, (unsigned int)mylast.last_time.seconds, (unsigned int)mylast.last_time.useconds); } gettimeofday(&iprop_start, NULL); incr_ret = iprop_get_updates_1(&mylast, handle->clnt); if (incr_ret == (kdb_incr_result_t *)NULL) { clnt_perror(handle->clnt, _("iprop_get_updates call failed")); if (server_handle) kadm5_destroy(server_handle); server_handle = NULL; handle = (kadm5_iprop_handle_t)NULL; if (debug) { fprintf(stderr, _("Reinitializing iprop because get updates " "failed\n")); } goto reinit; } switch (incr_ret->ret) { case UPDATE_FULL_RESYNC_NEEDED: /* * If we're already asked for a full resync and we still * need one and the last one hasn't timed out then just keep * asking for updates as eventually the resync will finish * (or, if it times out we'll just try again). Note that * doit() also applies a timeout to the full resync, thus * it's OK for us to do the same here. */ now = time(NULL); if (frrequested && (now - frrequested) < params.iprop_resync_timeout) { if (debug) fprintf(stderr, _("Still waiting for full resync\n")); break; } else { frrequested = now; if (debug) fprintf(stderr, _("Full resync needed\n")); syslog(LOG_INFO, _("kpropd: Full resync needed.")); full_ret = full_resync(handle->clnt); if (full_ret == NULL) { clnt_perror(handle->clnt, _("iprop_full_resync call failed")); kadm5_destroy(server_handle); server_handle = NULL; handle = NULL; goto reinit; } } switch (full_ret->ret) { case UPDATE_OK: if (debug) fprintf(stderr, _("Full resync request granted\n")); syslog(LOG_INFO, _("Full resync request granted.")); backoff_cnt = 0; break; case UPDATE_BUSY: /* * Exponential backoff */ if (debug) fprintf(stderr, _("Exponential backoff\n")); backoff_cnt++; break; case UPDATE_PERM_DENIED: if (debug) fprintf(stderr, _("Full resync permission denied\n")); syslog(LOG_ERR, _("Full resync, permission denied.")); goto error; case UPDATE_ERROR: if (debug) fprintf(stderr, _("Full resync error from primary\n")); syslog(LOG_ERR, _(" Full resync, " "error returned from primary KDC.")); goto error; default: backoff_cnt = 0; if (debug) { fprintf(stderr, _("Full resync invalid result from primary\n")); } syslog(LOG_ERR, _("Full resync, " "invalid return from primary KDC.")); break; } break; case UPDATE_OK: backoff_cnt = 0; frrequested = 0; /* * ulog_replay() will convert the ulog updates to db * entries using the kdb conv api and will commit * the entries to the replica kdc database */ if (debug) { fprintf(stderr, _("Got incremental updates " "(sno=%u sec=%u usec=%u)\n"), (unsigned int)incr_ret->lastentry.last_sno, (unsigned int)incr_ret->lastentry.last_time.seconds, (unsigned int)incr_ret->lastentry.last_time.useconds); } retval = ulog_replay(kpropd_context, incr_ret, db_args); if (retval) { const char *msg = krb5_get_error_message(kpropd_context, retval); if (debug) { fprintf(stderr, _("ulog_replay failed (%s), updates not " "registered\n"), msg); } syslog(LOG_ERR, _("ulog_replay failed (%s), updates " "not registered."), msg); krb5_free_error_message(kpropd_context, msg); break; } gettimeofday(&iprop_end, NULL); usec = (iprop_end.tv_sec - iprop_start.tv_sec) * 1000000 + iprop_end.tv_usec - iprop_start.tv_usec; syslog(LOG_INFO, _("Incremental updates: %d updates / %lu us"), incr_ret->updates.kdb_ulog_t_len, usec); if (debug) { fprintf(stderr, _("Incremental updates: %d updates / " "%lu us\n"), incr_ret->updates.kdb_ulog_t_len, usec); } break; case UPDATE_PERM_DENIED: if (debug) fprintf(stderr, _("get_updates permission denied\n")); syslog(LOG_ERR, _("get_updates, permission denied.")); goto error; case UPDATE_ERROR: if (debug) fprintf(stderr, _("get_updates error from primary\n")); syslog(LOG_ERR, _("get_updates, error returned from primary KDC.")); goto error; case UPDATE_BUSY: /* * Exponential backoff */ if (debug) fprintf(stderr, _("get_updates primary busy; backoff\n")); backoff_cnt++; break; case UPDATE_NIL: /* * Primary-replica are in sync */ if (debug) fprintf(stderr, _("KDC is synchronized with primary.\n")); backoff_cnt = 0; frrequested = 0; break; default: backoff_cnt = 0; if (debug) { fprintf(stderr, _("get_updates invalid result from primary\n")); } syslog(LOG_ERR, _("get_updates, invalid return from primary KDC.")); break; } if (runonce == 1 && incr_ret->ret != UPDATE_FULL_RESYNC_NEEDED) goto done; /* * Sleep for the specified poll interval (Default is 2 mts), * or do a binary exponential backoff if we get an * UPDATE_BUSY signal */ if (backoff_cnt > 0) { backoff_time = backoff_from_primary(&backoff_cnt); if (debug) { fprintf(stderr, _("Busy signal received " "from primary, backoff for %d secs\n"), backoff_time); } sleep(backoff_time); } else { if (debug) { fprintf(stderr, _("Waiting for %d seconds before checking " "for updates again\n"), pollin); } sleep(pollin); } } error: if (debug) fprintf(stderr, _("ERROR returned by primary, bailing\n")); syslog(LOG_ERR, _("ERROR returned by primary KDC, bailing.\n")); done: free(iprop_svc_princstr); free(primary_svc_princstr); krb5_free_principal(kpropd_context, iprop_svc_principal); krb5_free_default_realm(kpropd_context, def_realm); kadm5_destroy(server_handle); krb5_db_fini(kpropd_context); ulog_fini(kpropd_context); krb5_free_context(kpropd_context); return (runonce == 1) ? 0 : 1; } /* Do exponential backoff, since primary KDC is BUSY or down. */ static unsigned int backoff_from_primary(int *cnt) { unsigned int btime; btime = (unsigned int)(2<<(*cnt)); if (btime > MAX_BACKOFF) { btime = MAX_BACKOFF; (*cnt)--; } return btime; } static void kpropd_com_err_proc(const char *whoami, long code, const char *fmt, va_list args) #if !defined(__cplusplus) && (__GNUC__ > 2) __attribute__((__format__(__printf__, 3, 0))) #endif ; static void kpropd_com_err_proc(const char *whoami, long code, const char *fmt, va_list args) { char error_buf[8096]; error_buf[0] = '\0'; if (fmt) vsnprintf(error_buf, sizeof(error_buf), fmt, args); syslog(LOG_ERR, "%s%s%s%s%s", whoami ? whoami : "", whoami ? ": " : "", code ? error_message(code) : "", code ? " " : "", error_buf); } static void parse_args(int argc, char **argv) { char **newargs; int c; krb5_error_code retval; enum { PID_FILE = 256 }; struct option long_options[] = { { "pid-file", 1, NULL, PID_FILE }, { NULL, 0, NULL, 0 }, }; memset(¶ms, 0, sizeof(params)); /* Since we may modify the KDB with ulog_replay(), we must read the KDC * profile. */ retval = krb5int_init_context_kdc(&kpropd_context); if (retval) { com_err(argv[0], retval, _("while initializing krb5")); exit(1); } progname = argv[0]; while ((c = getopt_long(argc, argv, "A:f:F:p:P:r:s:DdSa:tx:", long_options, NULL)) != -1) { switch (c) { case 'A': params.mask |= KADM5_CONFIG_ADMIN_SERVER; params.admin_server = optarg; break; case 'f': file = optarg; break; case 'F': kerb_database = optarg; break; case 'p': kdb5_util = optarg; break; case 'P': port = optarg; break; case 'r': realm = optarg; break; case 's': keytab_path = optarg; break; case 'D': nodaemon++; break; case 'd': debug++; break; case 'S': /* Standalone mode is now auto-detected; see main(). */ break; case 'a': acl_file_name = optarg; break; case 't': /* Undocumented option - for testing only. Run the kpropd * server exactly once. */ runonce = 1; break; case 'x': newargs = realloc(db_args, (db_args_size + 2) * sizeof(*db_args)); if (newargs == NULL) { com_err(argv[0], errno, _("copying db args")); exit(1); } db_args = newargs; db_args[db_args_size] = optarg; db_args[db_args_size + 1] = NULL; db_args_size++; break; case PID_FILE: pid_file = optarg; break; default: usage(); } } if (optind != argc) usage(); openlog("kpropd", LOG_PID | LOG_ODELAY, SYSLOG_CLASS); if (!debug) set_com_err_hook(kpropd_com_err_proc); if (realm == NULL) { retval = krb5_get_default_realm(kpropd_context, &def_realm); if (retval) { com_err(progname, retval, _("Unable to get default realm")); exit(1); } realm = def_realm; } else { retval = krb5_set_default_realm(kpropd_context, realm); if (retval) { com_err(progname, retval, _("Unable to set default realm")); exit(1); } } /* Construct service name from local hostname. */ retval = sn2princ_realm(kpropd_context, NULL, KPROP_SERVICE_NAME, realm, &server); if (retval) { com_err(progname, retval, _("while trying to construct my service name")); exit(1); } /* Construct the name of the temporary file. */ if (asprintf(&temp_file_name, "%s.temp", file) < 0) { com_err(progname, ENOMEM, _("while allocating filename for temp file")); exit(1); } params.realm = realm; params.mask |= KADM5_CONFIG_REALM; retval = kadm5_get_config_params(kpropd_context, 1, ¶ms, ¶ms); if (retval) { com_err(progname, retval, _("while initializing")); exit(1); } if (params.iprop_enabled == TRUE) { ulog_set_role(kpropd_context, IPROP_REPLICA); if (ulog_map(kpropd_context, params.iprop_logfile, params.iprop_ulogsize)) { com_err(progname, errno, _("Unable to map log!\n")); exit(1); } } } /* * Figure out who's calling on the other end of the connection.... */ static void kerberos_authenticate(krb5_context context, int fd, krb5_principal *clientp, krb5_enctype *etype, struct sockaddr_storage *my_sin) { krb5_error_code retval; krb5_address addr; krb5_ticket *ticket; struct sockaddr_storage r_sin; GETSOCKNAME_ARG3_TYPE sin_length; krb5_keytab keytab = NULL; char *name, etypebuf[100]; sin_length = sizeof(r_sin); if (getsockname(fd, (struct sockaddr *)&r_sin, &sin_length)) { com_err(progname, errno, _("while getting local socket address")); exit(1); } if (k5_sockaddr_to_address(ss2sa(my_sin), FALSE, &addr) != 0) addr = k5_addr_directional_accept; retval = krb5_copy_addr(context, &addr, &receiver_addr); if (retval) { com_err(progname, retval, _("while converting local address")); exit(1); } if (debug) { retval = krb5_unparse_name(context, server, &name); if (retval) { com_err(progname, retval, _("while unparsing client name")); exit(1); } fprintf(stderr, "krb5_recvauth(%d, %s, %s, ...)\n", fd, kprop_version, name); free(name); } retval = krb5_auth_con_init(context, &auth_context); if (retval) { syslog(LOG_ERR, _("Error in krb5_auth_con_ini: %s"), error_message(retval)); exit(1); } retval = krb5_auth_con_setflags(context, auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); if (retval) { syslog(LOG_ERR, _("Error in krb5_auth_con_setflags: %s"), error_message(retval)); exit(1); } /* * Do not set a remote address, to allow replication over a NAT that * changes the client address. A reflection attack against kpropd is * impossible because kpropd only sends one message at the end. */ retval = krb5_auth_con_setaddrs(context, auth_context, receiver_addr, NULL); if (retval) { syslog(LOG_ERR, _("Error in krb5_auth_con_setaddrs: %s"), error_message(retval)); exit(1); } if (keytab_path != NULL) { retval = krb5_kt_resolve(context, keytab_path, &keytab); if (retval) { syslog(LOG_ERR, _("Error in krb5_kt_resolve: %s"), error_message(retval)); exit(1); } } retval = krb5_recvauth(context, &auth_context, &fd, kprop_version, server, 0, keytab, &ticket); if (retval) { syslog(LOG_ERR, _("Error in krb5_recvauth: %s"), error_message(retval)); exit(1); } retval = krb5_copy_principal(context, ticket->enc_part2->client, clientp); if (retval) { syslog(LOG_ERR, _("Error in krb5_copy_prinicpal: %s"), error_message(retval)); exit(1); } *etype = ticket->enc_part.enctype; if (debug) { retval = krb5_unparse_name(context, *clientp, &name); if (retval) { com_err(progname, retval, _("while unparsing client name")); exit(1); } retval = krb5_enctype_to_name(*etype, FALSE, etypebuf, sizeof(etypebuf)); if (retval) { com_err(progname, retval, _("while unparsing ticket etype")); exit(1); } fprintf(stderr, _("authenticated client: %s (etype == %s)\n"), name, etypebuf); free(name); } krb5_free_ticket(context, ticket); } static krb5_boolean authorized_principal(krb5_context context, krb5_principal p, krb5_enctype auth_etype) { krb5_boolean ok = FALSE; char *name = NULL, *ptr, buf[1024]; krb5_error_code retval; FILE *acl_file = NULL; int end; krb5_enctype acl_etype; retval = krb5_unparse_name(context, p, &name); if (retval) goto cleanup; acl_file = fopen(acl_file_name, "r"); if (acl_file == NULL) goto cleanup; while (!feof(acl_file)) { if (!fgets(buf, sizeof(buf), acl_file)) break; end = strlen(buf) - 1; if (buf[end] == '\n') buf[end] = '\0'; if (!strncmp(name, buf, strlen(name))) { ptr = buf + strlen(name); /* If the next character is not whitespace or null, then the match * is only partial. Continue on to new lines. */ if (*ptr != '\0' && !isspace((int)*ptr)) continue; /* Otherwise, skip trailing whitespace. */ for (; *ptr != '\0' && isspace((int)*ptr); ptr++) ; /* * Now, look for an etype string. If there isn't one, return true. * If there is an invalid string, continue. If there is a valid * string, return true only if it matches the etype passed in, * otherwise continue. */ if (*ptr != '\0' && ((retval = krb5_string_to_enctype(ptr, &acl_etype)) || (acl_etype != auth_etype))) continue; ok = TRUE; goto cleanup; } } cleanup: free(name); if (acl_file != NULL) fclose(acl_file); return ok; } static void recv_database(krb5_context context, int fd, int database_fd, krb5_data *confmsg) { uint64_t database_size, received_size; int n; char buf[1024]; char dbsize_buf[KPROP_DBSIZE_MAX_BUFSIZ]; krb5_data inbuf, outbuf; krb5_error_code retval; /* Receive and decode size from client. */ retval = krb5_read_message(context, &fd, &inbuf); if (retval) { send_error(context, fd, retval, "while reading database size"); com_err(progname, retval, _("while reading size of database from client")); exit(1); } if (krb5_is_krb_error(&inbuf)) recv_error(context, &inbuf); retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL); if (retval) { send_error(context, fd, retval, "while decoding database size"); krb5_free_data_contents(context, &inbuf); com_err(progname, retval, _("while decoding database size from client")); exit(1); } retval = decode_database_size(&outbuf, &database_size); if (retval) { send_error(context, fd, retval, "malformed database size message"); com_err(progname, retval, _("malformed database size message from client")); exit(1); } krb5_free_data_contents(context, &inbuf); krb5_free_data_contents(context, &outbuf); /* Initialize the initial vector. */ retval = krb5_auth_con_initivector(context, auth_context); if (retval) { send_error(context, fd, retval, "failed while initializing i_vector"); com_err(progname, retval, _("while initializing i_vector")); exit(1); } if (debug) fprintf(stderr, _("Full propagation transfer started.\n")); /* Now start receiving the database from the net. */ received_size = 0; while (received_size < database_size) { retval = krb5_read_message(context, &fd, &inbuf); if (retval) { snprintf(buf, sizeof(buf), "while reading database block starting at offset %"PRIu64, received_size); com_err(progname, retval, "%s", buf); send_error(context, fd, retval, buf); exit(1); } if (krb5_is_krb_error(&inbuf)) recv_error(context, &inbuf); retval = krb5_rd_priv(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { snprintf(buf, sizeof(buf), "while decoding database block starting at offset %" PRIu64, received_size); com_err(progname, retval, "%s", buf); send_error(context, fd, retval, buf); krb5_free_data_contents(context, &inbuf); exit(1); } n = write(database_fd, outbuf.data, outbuf.length); krb5_free_data_contents(context, &inbuf); if (n < 0) { snprintf(buf, sizeof(buf), "while writing database block starting at offset %"PRIu64, received_size); send_error(context, fd, errno, buf); } else if ((unsigned int)n != outbuf.length) { snprintf(buf, sizeof(buf), "incomplete write while writing database block starting " "at \noffset %"PRIu64" (%d written, %d expected)", received_size, n, outbuf.length); send_error(context, fd, KRB5KRB_ERR_GENERIC, buf); } received_size += outbuf.length; krb5_free_data_contents(context, &outbuf); } /* OK, we've seen the entire file. Did we get too many bytes? */ if (received_size > database_size) { snprintf(buf, sizeof(buf), "Received %"PRIu64" bytes, expected %"PRIu64 " bytes for database file", received_size, database_size); send_error(context, fd, KRB5KRB_ERR_GENERIC, buf); } if (debug) fprintf(stderr, _("Full propagation transfer finished.\n")); /* Create message acknowledging number of bytes received, but * don't send it until kdb5_util returns successfully. */ inbuf = make_data(dbsize_buf, sizeof(dbsize_buf)); encode_database_size(database_size, &inbuf); retval = krb5_mk_safe(context,auth_context,&inbuf,confmsg,NULL); if (retval) { com_err(progname, retval, "while encoding # of received bytes"); send_error(context, fd, retval, "while encoding # of received bytes"); exit(1); } } static void send_error(krb5_context context, int fd, krb5_error_code err_code, char *err_text) { krb5_error error; const char *text; krb5_data outbuf; char buf[1024]; memset(&error, 0, sizeof(error)); krb5_us_timeofday(context, &error.stime, &error.susec); error.server = server; error.client = client; text = (err_text != NULL) ? err_text : error_message(err_code); error.error = err_code - ERROR_TABLE_BASE_krb5; if (error.error > 127) { error.error = KRB_ERR_GENERIC; if (err_text) { snprintf(buf, sizeof(buf), "%s %s", error_message(err_code), err_text); text = buf; } } error.text.length = strlen(text) + 1; error.text.data = strdup(text); if (error.text.data) { if (!krb5_mk_error(context, &error, &outbuf)) { (void)krb5_write_message(context, &fd, &outbuf); krb5_free_data_contents(context, &outbuf); } free(error.text.data); } } void recv_error(krb5_context context, krb5_data *inbuf) { krb5_error *error; krb5_error_code retval; retval = krb5_rd_error(context, inbuf, &error); if (retval) { com_err(progname, retval, _("while decoding error packet from client")); exit(1); } if (error->error == KRB_ERR_GENERIC) { if (error->text.data) fprintf(stderr, _("Generic remote error: %s\n"), error->text.data); } else if (error->error) { com_err(progname, (krb5_error_code)error->error + ERROR_TABLE_BASE_krb5, _("signaled from server")); if (error->text.data) { fprintf(stderr, _("Error text from client: %s\n"), error->text.data); } } krb5_free_error(context, error); exit(1); } static void load_database(krb5_context context, char *kdb_util, char *database_file_name) { static char *edit_av[10]; int error_ret, child_pid, count; /* has been included, so BSD will be defined on * BSD systems. */ #if BSD > 0 && BSD <= 43 #ifndef WEXITSTATUS #define WEXITSTATUS(w) (w).w_retcode #endif union wait waitb; #else int waitb; #endif kdb_log_context *log_ctx; if (debug) fprintf(stderr, "calling kdb5_util to load database\n"); log_ctx = context->kdblog_context; edit_av[0] = kdb_util; count = 1; if (realm) { edit_av[count++] = "-r"; edit_av[count++] = realm; } edit_av[count++] = "load"; if (kerb_database) { edit_av[count++] = "-d"; edit_av[count++] = kerb_database; } if (log_ctx && log_ctx->iproprole == IPROP_REPLICA) edit_av[count++] = "-i"; edit_av[count++] = database_file_name; edit_av[count++] = NULL; switch (child_pid = fork()) { case -1: com_err(progname, errno, _("while trying to fork %s"), kdb_util); exit(1); case 0: execv(kdb_util, edit_av); com_err(progname, errno, _("while trying to exec %s"), kdb_util); _exit(1); /*NOTREACHED*/ default: if (debug) fprintf(stderr, "Load PID is %d\n", child_pid); if (wait(&waitb) < 0) { com_err(progname, errno, _("while waiting for %s"), kdb_util); exit(1); } } if (!WIFEXITED(waitb)) { com_err(progname, 0, _("%s load terminated"), kdb_util); exit(1); } error_ret = WEXITSTATUS(waitb); if (error_ret) { com_err(progname, 0, _("%s returned a bad exit status (%d)"), kdb_util, error_ret); exit(1); } return; } /* * Get the host base service name for the kiprop principal. Returns * KADM5_OK on success. Caller must free the storage allocated * for host_service_name. */ static kadm5_ret_t kadm5_get_kiprop_host_srv_name(krb5_context context, const char *realm_name, char **host_service_name) { char *name, *host; host = params.admin_server; /* XXX */ if (asprintf(&name, "%s/%s", KADM5_KIPROP_HOST_SERVICE, host) < 0) { free(host); return ENOMEM; } *host_service_name = name; return KADM5_OK; } krb5-1.22.1/src/kprop/kprop_util.c0000664000175000017500000000640315051422640016622 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* kprop/kprop_util.c */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* sockaddr2krbaddr() utility function used by kprop and kpropd */ #include "k5-int.h" #include "kprop.h" /* Construct a host-based principal, similar to krb5_sname_to_principal() but * with a specified realm. */ krb5_error_code sn2princ_realm(krb5_context context, const char *hostname, const char *sname, const char *realm, krb5_principal *princ_out) { krb5_error_code ret; krb5_principal princ; *princ_out = NULL; assert(sname != NULL && realm != NULL); ret = krb5_sname_to_principal(context, hostname, sname, KRB5_NT_SRV_HST, &princ); if (ret) return ret; ret = krb5_set_principal_realm(context, princ, realm); if (ret) { krb5_free_principal(context, princ); return ret; } *princ_out = princ; return 0; } void encode_database_size(uint64_t size, krb5_data *buf) { assert(buf->length >= 12); if (size > 0 && size <= UINT32_MAX) { /* Encode in 32 bits for backward compatibility. */ store_32_be(size, buf->data); buf->length = 4; } else { /* Set the first 32 bits to 0 and encode in the following 64 bits. */ store_32_be(0, buf->data); store_64_be(size, buf->data + 4); buf->length = 12; } } krb5_error_code decode_database_size(const krb5_data *buf, uint64_t *size_out) { uint64_t size; if (buf->length == 12) { /* A 12-byte buffer must have the first four bytes zeroed. */ if (load_32_be(buf->data) != 0) return KRB5KRB_ERR_GENERIC; /* The size is stored in the next 64 bits. Values from 1..2^32-1 must * be encoded in four bytes. */ size = load_64_be(buf->data + 4); if (size > 0 && size <= UINT32_MAX) return KRB5KRB_ERR_GENERIC; } else if (buf->length == 4) { size = load_32_be(buf->data); } else { /* Invalid buffer size. */ return KRB5KRB_ERR_GENERIC; } *size_out = size; return 0; } krb5-1.22.1/src/kprop/kpropd_rpc.c0000664000175000017500000000266715051422640016605 0ustar ghudsonghudson/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include /* for memset */ #include "iprop.h" /* Default timeout can be changed using clnt_control() */ static struct timeval TIMEOUT = { 25, 0 }; void * iprop_null_1(void *argp, CLIENT *clnt) { static char clnt_res; memset(&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, IPROP_NULL, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return ((void *)&clnt_res); } kdb_incr_result_t * iprop_get_updates_1(kdb_last_t *argp, CLIENT *clnt) { static kdb_incr_result_t clnt_res; memset(&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, IPROP_GET_UPDATES, (xdrproc_t) xdr_kdb_last_t, (caddr_t) argp, (xdrproc_t) xdr_kdb_incr_result_t, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); } kdb_fullresync_result_t * iprop_full_resync_1(void *argp, CLIENT *clnt) { static kdb_fullresync_result_t clnt_res; memset(&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, IPROP_FULL_RESYNC, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_kdb_fullresync_result_t, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); } krb5-1.22.1/src/kprop/kprop.c0000664000175000017500000004552415051422640015574 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* kprop/kprop.c */ /* * Copyright 1990,1991,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "com_err.h" #include "fake-addrinfo.h" #include "kprop.h" #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE unsigned int #endif static char *kprop_version = KPROP_PROT_VERSION; static char *progname = NULL; static int debug = 0; static char *keytab_path = NULL; static char *replica_host; static char *realm = NULL; static char *def_realm = NULL; static char *file = KPROP_DEFAULT_FILE; /* The Kerberos principal we'll be sending as, initialized in get_tickets. */ static krb5_principal my_principal; static krb5_creds creds; static krb5_address *sender_addr; static const char *port = KPROP_SERVICE; static char *dbpathname; static void parse_args(krb5_context context, int argc, char **argv); static void get_tickets(krb5_context context); static void usage(void); static void open_connection(krb5_context context, char *host, int *fd_out); static void kerberos_authenticate(krb5_context context, krb5_auth_context *auth_context, int fd, krb5_principal me, krb5_creds **new_creds); static int open_database(krb5_context context, char *data_fn, off_t *size); static void close_database(krb5_context context, int fd); static void xmit_database(krb5_context context, krb5_auth_context auth_context, krb5_creds *my_creds, int fd, int database_fd, off_t in_database_size); static void send_error(krb5_context context, krb5_creds *my_creds, int fd, char *err_text, krb5_error_code err_code); static void update_last_prop_file(char *hostname, char *file_name); static void usage(void) { fprintf(stderr, _("\nUsage: %s [-r realm] [-f file] [-d] [-P port] " "[-s keytab] replica_host\n\n"), progname); exit(1); } int main(int argc, char **argv) { int fd, database_fd; off_t database_size; krb5_error_code retval; krb5_context context; krb5_creds *my_creds; krb5_auth_context auth_context; setlocale(LC_ALL, ""); retval = krb5_init_context(&context); if (retval) { com_err(argv[0], retval, _("while initializing krb5")); exit(1); } parse_args(context, argc, argv); get_tickets(context); database_fd = open_database(context, file, &database_size); open_connection(context, replica_host, &fd); kerberos_authenticate(context, &auth_context, fd, my_principal, &my_creds); xmit_database(context, auth_context, my_creds, fd, database_fd, database_size); update_last_prop_file(replica_host, file); printf(_("Database propagation to %s: SUCCEEDED\n"), replica_host); krb5_free_cred_contents(context, my_creds); close_database(context, database_fd); krb5_free_default_realm(context, def_realm); exit(0); } static void parse_args(krb5_context context, int argc, char **argv) { int c; krb5_error_code ret; progname = argv[0]; while ((c = getopt(argc, argv, "r:f:dP:s:")) != -1) { switch (c) { case 'r': realm = optarg; break; case 'f': file = optarg; break; case 'd': debug++; break; case 'P': port = optarg; break; case 's': keytab_path = optarg; break; default: usage(); } } if (argc - optind != 1) usage(); replica_host = argv[optind]; if (realm == NULL) { ret = krb5_get_default_realm(context, &def_realm); if (ret) { com_err(progname, errno, _("while getting default realm")); exit(1); } realm = def_realm; } } static void get_tickets(krb5_context context) { char *server; krb5_error_code retval; krb5_keytab keytab = NULL; krb5_principal server_princ = NULL; /* Figure out what tickets we'll be using to send. */ retval = sn2princ_realm(context, NULL, KPROP_SERVICE_NAME, realm, &my_principal); if (retval) { com_err(progname, errno, _("while setting client principal name")); exit(1); } /* Construct the principal name for the replica host. */ memset(&creds, 0, sizeof(creds)); retval = sn2princ_realm(context, replica_host, KPROP_SERVICE_NAME, realm, &server_princ); if (retval) { com_err(progname, errno, _("while setting server principal name")); exit(1); } retval = krb5_unparse_name_flags(context, server_princ, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &server); if (retval) { com_err(progname, retval, _("while unparsing server name")); exit(1); } if (keytab_path != NULL) { retval = krb5_kt_resolve(context, keytab_path, &keytab); if (retval) { com_err(progname, retval, _("while resolving keytab")); exit(1); } } retval = krb5_get_init_creds_keytab(context, &creds, my_principal, keytab, 0, server, NULL); if (retval) { com_err(progname, retval, _("while getting initial credentials\n")); exit(1); } if (keytab != NULL) krb5_kt_close(context, keytab); krb5_free_unparsed_name(context, server); krb5_free_principal(context, server_princ); } static void open_connection(krb5_context context, char *host, int *fd_out) { krb5_error_code retval; krb5_address addr; GETSOCKNAME_ARG3_TYPE socket_length; struct addrinfo hints, *res, *answers; struct sockaddr_storage my_sin; int s, error; *fd_out = -1; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG; error = getaddrinfo(host, port, &hints, &answers); if (error != 0) { com_err(progname, 0, "%s: %s", host, gai_strerror(error)); exit(1); } s = -1; retval = EINVAL; for (res = answers; res != NULL; res = res->ai_next) { s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (s < 0) { com_err(progname, errno, _("while creating socket")); exit(1); } if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { retval = errno; close(s); s = -1; continue; } /* We successfully connect()ed */ *fd_out = s; break; } freeaddrinfo(answers); if (s == -1) { com_err(progname, retval, _("while connecting to server")); exit(1); } /* Set sender_addr. */ socket_length = sizeof(my_sin); if (getsockname(s, (struct sockaddr *)&my_sin, &socket_length) < 0) { com_err(progname, errno, _("while getting local socket address")); exit(1); } if (k5_sockaddr_to_address(ss2sa(&my_sin), FALSE, &addr) != 0) addr = k5_addr_directional_init; retval = krb5_copy_addr(context, &addr, &sender_addr); if (retval) { com_err(progname, retval, _("while converting local address")); exit(1); } } static void kerberos_authenticate(krb5_context context, krb5_auth_context *auth_context, int fd, krb5_principal me, krb5_creds **new_creds) { krb5_error_code retval; krb5_error *error = NULL; krb5_ap_rep_enc_part *rep_result; retval = krb5_auth_con_init(context, auth_context); if (retval) exit(1); krb5_auth_con_setflags(context, *auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); retval = krb5_auth_con_setaddrs(context, *auth_context, sender_addr, NULL); if (retval) { com_err(progname, retval, _("in krb5_auth_con_setaddrs")); exit(1); } retval = krb5_sendauth(context, auth_context, &fd, kprop_version, me, creds.server, AP_OPTS_MUTUAL_REQUIRED, NULL, &creds, NULL, &error, &rep_result, new_creds); if (retval) { com_err(progname, retval, _("while authenticating to server")); if (error != NULL) { if (error->error == KRB_ERR_GENERIC) { if (error->text.data) { fprintf(stderr, _("Generic remote error: %s\n"), error->text.data); } } else if (error->error) { com_err(progname, (krb5_error_code)error->error + ERROR_TABLE_BASE_krb5, _("signalled from server")); if (error->text.data) { fprintf(stderr, _("Error text from server: %s\n"), error->text.data); } } krb5_free_error(context, error); } exit(1); } krb5_free_ap_rep_enc_part(context, rep_result); } /* * Open the Kerberos database dump file. Takes care of locking it * and making sure that the .ok file is more recent that the database * dump file itself. * * Returns the file descriptor of the database dump file. Also fills * in the size of the database file. */ static int open_database(krb5_context context, char *data_fn, off_t *size) { struct stat stbuf, stbuf_ok; char *data_ok_fn; int fd, err; dbpathname = strdup(data_fn); if (dbpathname == NULL) { com_err(progname, ENOMEM, _("allocating database file name '%s'"), data_fn); exit(1); } fd = open(dbpathname, O_RDONLY); if (fd < 0) { com_err(progname, errno, _("while trying to open %s"), dbpathname); exit(1); } err = krb5_lock_file(context, fd, KRB5_LOCKMODE_SHARED | KRB5_LOCKMODE_DONTBLOCK); if (err == EAGAIN || err == EWOULDBLOCK || errno == EACCES) { com_err(progname, 0, _("database locked")); exit(1); } else if (err) { com_err(progname, err, _("while trying to lock '%s'"), dbpathname); exit(1); } if (fstat(fd, &stbuf)) { com_err(progname, errno, _("while trying to stat %s"), data_fn); exit(1); } if (asprintf(&data_ok_fn, "%s.dump_ok", data_fn) < 0) { com_err(progname, ENOMEM, _("while trying to malloc data_ok_fn")); exit(1); } if (stat(data_ok_fn, &stbuf_ok)) { com_err(progname, errno, _("while trying to stat %s"), data_ok_fn); free(data_ok_fn); exit(1); } if (stbuf.st_mtime > stbuf_ok.st_mtime) { com_err(progname, 0, _("'%s' more recent than '%s'."), data_fn, data_ok_fn); exit(1); } free(data_ok_fn); *size = stbuf.st_size; return fd; } static void close_database(krb5_context context, int fd) { int err; err = krb5_lock_file(context, fd, KRB5_LOCKMODE_UNLOCK); if (err) com_err(progname, err, _("while unlocking database '%s'"), dbpathname); free(dbpathname); close(fd); } /* * Now we send over the database. We use the following protocol: * Send over a KRB_SAFE message with the size. Then we send over the * database in blocks of KPROP_BLKSIZE, encrypted using KRB_PRIV. * Then we expect to see a KRB_SAFE message with the size sent back. * * At any point in the protocol, we may send a KRB_ERROR message; this * will abort the entire operation. */ static void xmit_database(krb5_context context, krb5_auth_context auth_context, krb5_creds *my_creds, int fd, int database_fd, off_t in_database_size) { krb5_int32 n; krb5_data inbuf, outbuf; char buf[KPROP_BUFSIZ], dbsize_buf[KPROP_DBSIZE_MAX_BUFSIZ]; krb5_error_code retval; krb5_error *error; uint64_t database_size = in_database_size, send_size, sent_size; /* Send over the size. */ inbuf = make_data(dbsize_buf, sizeof(dbsize_buf)); encode_database_size(database_size, &inbuf); /* KPROP_CKSUMTYPE */ retval = krb5_mk_safe(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { com_err(progname, retval, _("while encoding database size")); send_error(context, my_creds, fd, _("while encoding database size"), retval); exit(1); } retval = krb5_write_message(context, &fd, &outbuf); if (retval) { krb5_free_data_contents(context, &outbuf); com_err(progname, retval, _("while sending database size")); exit(1); } krb5_free_data_contents(context, &outbuf); /* Initialize the initial vector. */ retval = krb5_auth_con_initivector(context, auth_context); if (retval) { send_error(context, my_creds, fd, "failed while initializing i_vector", retval); com_err(progname, retval, _("while allocating i_vector")); exit(1); } /* Send over the file, block by block. */ inbuf.data = buf; sent_size = 0; while ((n = read(database_fd, buf, sizeof(buf)))) { inbuf.length = n; retval = krb5_mk_priv(context, auth_context, &inbuf, &outbuf, NULL); if (retval) { snprintf(buf, sizeof(buf), "while encoding database block starting at %"PRIu64, sent_size); com_err(progname, retval, "%s", buf); send_error(context, my_creds, fd, buf, retval); exit(1); } retval = krb5_write_message(context, &fd, &outbuf); if (retval) { krb5_free_data_contents(context, &outbuf); com_err(progname, retval, _("while sending database block starting at %"PRIu64), sent_size); exit(1); } krb5_free_data_contents(context, &outbuf); sent_size += n; if (debug) printf("%"PRIu64" bytes sent.\n", sent_size); } if (sent_size != database_size) { com_err(progname, 0, _("Premature EOF found for database file!")); send_error(context, my_creds, fd, "Premature EOF found for database file!", KRB5KRB_ERR_GENERIC); exit(1); } /* * OK, we've sent the database; now let's wait for a success * indication from the remote end. */ retval = krb5_read_message(context, &fd, &inbuf); if (retval) { com_err(progname, retval, _("while reading response from server")); exit(1); } /* * If we got an error response back from the server, display * the error message */ if (krb5_is_krb_error(&inbuf)) { retval = krb5_rd_error(context, &inbuf, &error); if (retval) { com_err(progname, retval, _("while decoding error response from server")); exit(1); } if (error->error == KRB_ERR_GENERIC) { if (error->text.data) { fprintf(stderr, _("Generic remote error: %s\n"), error->text.data); } } else if (error->error) { com_err(progname, (krb5_error_code)error->error + ERROR_TABLE_BASE_krb5, _("signalled from server")); if (error->text.data) { fprintf(stderr, _("Error text from server: %s\n"), error->text.data); } } krb5_free_error(context, error); exit(1); } retval = krb5_rd_safe(context,auth_context,&inbuf,&outbuf,NULL); if (retval) { com_err(progname, retval, "while decoding final size packet from server"); exit(1); } retval = decode_database_size(&outbuf, &send_size); if (retval) { com_err(progname, retval, _("malformed sent database size message")); exit(1); } if (send_size != database_size) { com_err(progname, 0, _("Kpropd sent database size %"PRIu64 ", expecting %"PRIu64), send_size, database_size); exit(1); } free(inbuf.data); free(outbuf.data); } static void send_error(krb5_context context, krb5_creds *my_creds, int fd, char *err_text, krb5_error_code err_code) { krb5_error error; const char *text; krb5_data outbuf; memset(&error, 0, sizeof(error)); krb5_us_timeofday(context, &error.ctime, &error.cusec); error.server = my_creds->server; error.client = my_principal; error.error = err_code - ERROR_TABLE_BASE_krb5; if (error.error > 127) error.error = KRB_ERR_GENERIC; text = (err_text != NULL) ? err_text : error_message(err_code); error.text.length = strlen(text) + 1; error.text.data = strdup(text); if (error.text.data) { if (!krb5_mk_error(context, &error, &outbuf)) { (void)krb5_write_message(context, &fd, &outbuf); krb5_free_data_contents(context, &outbuf); } free(error.text.data); } } static void update_last_prop_file(char *hostname, char *file_name) { char *file_last_prop; int fd; static char last_prop[] = ".last_prop"; if (asprintf(&file_last_prop, "%s.%s%s", file_name, hostname, last_prop) < 0) { com_err(progname, ENOMEM, _("while allocating filename for update_last_prop_file")); return; } fd = THREEPARAMOPEN(file_last_prop, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd < 0) { com_err(progname, errno, _("while creating 'last_prop' file, '%s'"), file_last_prop); free(file_last_prop); return; } write(fd, "", 1); free(file_last_prop); close(fd); } krb5-1.22.1/src/kprop/deps0000664000175000017500000001165715051422640015153 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)kprop.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ kprop.c kprop.h $(OUTPRE)kprop_util.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kprop.h kprop_util.c $(OUTPRE)kpropd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/iprop.h $(top_srcdir)/include/iprop_hdr.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/kdb_log.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ kprop.h kpropd.c $(OUTPRE)kpropd_rpc.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/iprop.h \ kpropd_rpc.c $(OUTPRE)kproplog.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/adm_proto.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/iprop.h \ $(top_srcdir)/include/iprop_hdr.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-hex.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/kdb_log.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ kproplog.c krb5-1.22.1/src/kprop/kprop.h0000664000175000017500000000430715051422640015573 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* kprop/kprop.h */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #define KPROP_SERVICE_NAME "host" #define TGT_SERVICE_NAME "krbtgt" #define KPROP_SERVICE "krb5_prop" #define KPROP_PORT 754 #define KPROP_PROT_VERSION "kprop5_01" #define KPROP_BUFSIZ 32768 #define KPROP_DBSIZE_MAX_BUFSIZ 12 /* max length of an encoded DB size */ /* pathnames are in osconf.h, included via k5-int.h */ krb5_error_code sn2princ_realm(krb5_context context, const char *hostname, const char *sname, const char *realm, krb5_principal *princ_out); /* * Encode size in four bytes (for backward compatibility) if it fits; otherwise * use the larger encoding. buf must be allocated with at least * KPROP_DBSIZE_MAX_BUFSIZ bytes. */ void encode_database_size(uint64_t size, krb5_data *buf); /* Decode a database size. Return KRB5KRB_ERR_GENERIC if buf has an invalid * length or did not encode a 32-bit size compactly. */ krb5_error_code decode_database_size(const krb5_data *buf, uint64_t *size_out); krb5-1.22.1/src/kprop/kproplog.c0000664000175000017500000003471015051422640016271 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * This module will parse the update logs on the primary or replica servers. */ #include "k5-int.h" #include "k5-hex.h" #include #include #include #include #include #include #include #include #include #include static char *progname; static void usage(void) { fprintf(stderr, _("\nUsage: %s [-h] [-v] [-v] [-e num]\n\t%s -R\n\n"), progname, progname); exit(1); } /* * Print the attribute flags of principal in human readable form. */ static void print_flags(unsigned int flags) { char **attrstrs, **sp; if (krb5_flags_to_strings(flags, &attrstrs) != 0) { printf("\t\t\t(error)\n"); return; } for (sp = attrstrs; sp != NULL && *sp != NULL; sp++) { printf("\t\t\t%s\n", *sp); free(*sp); } free(attrstrs); } /* ctime() for uint32_t* */ static const char * ctime_uint32(uint32_t *time32) { time_t tmp; const char *r; tmp = *time32; r = ctime(&tmp); return (r == NULL) ? "(error)" : r; } /* Display time information. */ static void print_time(uint32_t *timep) { if (*timep == 0L) printf("\t\t\tNone\n"); else printf("\t\t\t%s", ctime_uint32(timep)); } static void print_deltat(uint32_t *deltat) { krb5_error_code ret; static char buf[30]; ret = krb5_deltat_to_string(*deltat, buf, sizeof(buf)); if (ret) printf("\t\t\t(error)\n"); else printf("\t\t\t%s\n", buf); } /* Display string in hex primitive. */ static void print_hex(const char *tag, utf8str_t *str) { unsigned int len; char *hex; len = str->utf8str_t_len; if (k5_hex_encode(str->utf8str_t_val, len, FALSE, &hex) != 0) abort(); printf("\t\t\t%s(%d): 0x%s\n", tag, len, hex); free(hex); } /* Display string primitive. */ static void print_str(const char *tag, utf8str_t *str) { krb5_error_code ret; char *s; s = k5memdup0(str->utf8str_t_val, str->utf8str_t_len, &ret); if (s == NULL) { fprintf(stderr, _("\nCouldn't allocate memory")); exit(1); } printf("\t\t\t%s(%d): %s\n", tag, str->utf8str_t_len, s); free(s); } /* Display data components. */ static void print_data(const char *tag, kdbe_data_t *data) { printf("\t\t\tmagic: 0x%x\n", data->k_magic); print_str(tag, &data->k_data); } /* Display the principal components. */ static void print_princ(kdbe_princ_t *princ) { int i, len; kdbe_data_t *data; print_str("realm", &princ->k_realm); len = princ->k_components.k_components_len; data = princ->k_components.k_components_val; for (i = 0; i < len; i++, data++) print_data("princ", data); } /* Display individual key. */ static void print_key(kdbe_key_t *k) { unsigned int i; utf8str_t *str; printf("\t\t\tver: %d\n", k->k_ver); printf("\t\t\tkvno: %d\n", k->k_kvno); for (i = 0; i < k->k_enctype.k_enctype_len; i++) printf("\t\t\tenc type: 0x%x\n", k->k_enctype.k_enctype_val[i]); str = k->k_contents.k_contents_val; for (i = 0; i < k->k_contents.k_contents_len; i++, str++) print_hex("key", str); } /* Display all key data. */ static void print_keydata(kdbe_key_t *keys, unsigned int len) { unsigned int i; for (i = 0; i < len; i++, keys++) print_key(keys); } /* Display TL item. */ static void print_tl(kdbe_tl_t *tl) { int i, len; printf("\t\t\ttype: 0x%x\n", tl->tl_type); len = tl->tl_data.tl_data_len; printf("\t\t\tvalue(%d): 0x", len); for (i = 0; i < len; i++) printf("%02x", (krb5_octet)tl->tl_data.tl_data_val[i]); printf("\n"); } /* Display TL data items. */ static void print_tldata(kdbe_tl_t *tldata, int len) { int i; printf("\t\t\titems: %d\n", len); for (i = 0; i < len; i++, tldata++) print_tl(tldata); } /* * Print the individual types if verbose mode was specified. * If verbose-verbose then print types along with respective values. */ static void print_attr(kdbe_val_t *val, int vverbose) { switch (val->av_type) { case AT_ATTRFLAGS: printf(_("\t\tAttribute flags\n")); if (vverbose) print_flags(val->kdbe_val_t_u.av_attrflags); break; case AT_MAX_LIFE: printf(_("\t\tMaximum ticket life\n")); if (vverbose) print_deltat(&val->kdbe_val_t_u.av_max_life); break; case AT_MAX_RENEW_LIFE: printf(_("\t\tMaximum renewable life\n")); if (vverbose) print_deltat(&val->kdbe_val_t_u.av_max_renew_life); break; case AT_EXP: printf(_("\t\tPrincipal expiration\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_exp); break; case AT_PW_EXP: printf(_("\t\tPassword expiration\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_pw_exp); break; case AT_LAST_SUCCESS: printf(_("\t\tLast successful auth\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_last_success); break; case AT_LAST_FAILED: printf(_("\t\tLast failed auth\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_last_failed); break; case AT_FAIL_AUTH_COUNT: printf(_("\t\tFailed passwd attempt\n")); if (vverbose) printf("\t\t\t%d\n", val->kdbe_val_t_u.av_fail_auth_count); break; case AT_PRINC: printf(_("\t\tPrincipal\n")); if (vverbose) print_princ(&val->kdbe_val_t_u.av_princ); break; case AT_KEYDATA: printf(_("\t\tKey data\n")); if (vverbose) { print_keydata(val->kdbe_val_t_u.av_keydata.av_keydata_val, val->kdbe_val_t_u.av_keydata.av_keydata_len); } break; case AT_TL_DATA: printf(_("\t\tTL data\n")); if (vverbose) { print_tldata(val->kdbe_val_t_u.av_tldata.av_tldata_val, val->kdbe_val_t_u.av_tldata.av_tldata_len); } break; case AT_LEN: printf(_("\t\tLength\n")); if (vverbose) printf("\t\t\t%d\n", val->kdbe_val_t_u.av_len); break; case AT_PW_LAST_CHANGE: printf(_("\t\tPassword last changed\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_pw_last_change); break; case AT_MOD_PRINC: printf(_("\t\tModifying principal\n")); if (vverbose) print_princ(&val->kdbe_val_t_u.av_mod_princ); break; case AT_MOD_TIME: printf(_("\t\tModification time\n")); if (vverbose) print_time(&val->kdbe_val_t_u.av_mod_time); break; case AT_MOD_WHERE: printf(_("\t\tModified where\n")); if (vverbose) print_str("where", &val->kdbe_val_t_u.av_mod_where); break; case AT_PW_POLICY: printf(_("\t\tPassword policy\n")); if (vverbose) print_str("policy", &val->kdbe_val_t_u.av_pw_policy); break; case AT_PW_POLICY_SWITCH: printf(_("\t\tPassword policy switch\n")); if (vverbose) printf("\t\t\t%d\n", val->kdbe_val_t_u.av_pw_policy_switch); break; case AT_PW_HIST_KVNO: printf(_("\t\tPassword history KVNO\n")); if (vverbose) printf("\t\t\t%d\n", val->kdbe_val_t_u.av_pw_hist_kvno); break; case AT_PW_HIST: printf(_("\t\tPassword history\n")); if (vverbose) printf("\t\t\tPW history elided\n"); break; } /* switch */ } /* * Print the update entry information */ static void print_update(kdb_hlog_t *ulog, uint32_t entry, uint32_t ulogentries, unsigned int verbose) { XDR xdrs; uint32_t start_sno, i, j, indx; char *dbprinc; kdb_ent_header_t *indx_log; kdb_incr_update_t upd; if (entry && (entry < ulog->kdb_num)) start_sno = ulog->kdb_last_sno - entry; else start_sno = ulog->kdb_first_sno - 1; for (i = start_sno; i < ulog->kdb_last_sno; i++) { indx = i % ulogentries; indx_log = ulog_index(ulog, indx); /* * Check for corrupt update entry */ if (indx_log->kdb_umagic != KDB_ULOG_MAGIC) { fprintf(stderr, _("Corrupt update entry\n\n")); exit(1); } printf("---\n"); printf(_("Update Entry\n")); printf(_("\tUpdate serial # : %u\n"), indx_log->kdb_entry_sno); /* The initial entry after a reset is a dummy entry; skip it. */ if (indx_log->kdb_entry_size == 0) { printf(_("\tDummy entry\n")); continue; } memset(&upd, 0, sizeof(kdb_incr_update_t)); xdrmem_create(&xdrs, (char *)indx_log->entry_data, indx_log->kdb_entry_size, XDR_DECODE); if (!xdr_kdb_incr_update_t(&xdrs, &upd)) { printf(_("Entry data decode failure\n\n")); exit(1); } printf(_("\tUpdate operation : ")); if (upd.kdb_deleted) printf(_("Delete\n")); else printf(_("Add\n")); dbprinc = malloc(upd.kdb_princ_name.utf8str_t_len + 1); if (dbprinc == NULL) { printf(_("Could not allocate principal name\n\n")); exit(1); } strncpy(dbprinc, upd.kdb_princ_name.utf8str_t_val, upd.kdb_princ_name.utf8str_t_len); dbprinc[upd.kdb_princ_name.utf8str_t_len] = 0; printf(_("\tUpdate principal : %s\n"), dbprinc); printf(_("\tUpdate size : %u\n"), indx_log->kdb_entry_size); printf(_("\tUpdate committed : %s\n"), indx_log->kdb_commit ? "True" : "False"); if (indx_log->kdb_time.seconds == 0L) { printf(_("\tUpdate time stamp : None\n")); } else{ printf(_("\tUpdate time stamp : %s"), ctime_uint32(&indx_log->kdb_time.seconds)); } printf(_("\tAttributes changed : %d\n"), upd.kdb_update.kdbe_t_len); if (verbose) { for (j = 0; j < upd.kdb_update.kdbe_t_len; j++) print_attr(&upd.kdb_update.kdbe_t_val[j], verbose > 1 ? 1 : 0); } xdr_free((xdrproc_t)xdr_kdb_incr_update_t, (char *)&upd); free(dbprinc); } } /* Return a read-only mmap of the ulog, or NULL on failure. */ static kdb_hlog_t * map_ulog(const char *filename, int *fd_out) { int fd; struct stat st; kdb_hlog_t *ulog = MAP_FAILED; *fd_out = -1; fd = open(filename, O_RDONLY); if (fd == -1) return NULL; if (fstat(fd, &st) < 0) { close(fd); return NULL; } ulog = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (ulog == MAP_FAILED) { close(fd); return NULL; } *fd_out = fd; return ulog; } int main(int argc, char **argv) { int c, ulog_fd = -1; unsigned int verbose = 0; bool_t headeronly = FALSE, reset = FALSE; uint32_t entry = 0; krb5_context context; kadm5_config_params params; kdb_hlog_t *ulog = NULL; setlocale(LC_ALL, ""); progname = argv[0]; while ((c = getopt(argc, argv, "Rvhe:")) != -1) { switch (c) { case 'h': headeronly = TRUE; break; case 'e': entry = atoi(optarg); break; case 'R': reset = TRUE; break; case 'v': verbose++; break; default: usage(); } } if (kadm5_init_krb5_context(&context)) { fprintf(stderr, _("Unable to initialize Kerberos\n\n")); exit(1); } memset(¶ms, 0, sizeof(params)); if (kadm5_get_config_params(context, 1, ¶ms, ¶ms)) { fprintf(stderr, _("Couldn't read database_name\n\n")); exit(1); } printf(_("\nKerberos update log (%s)\n"), params.iprop_logfile); if (reset) { if (ulog_map(context, params.iprop_logfile, params.iprop_ulogsize)) { fprintf(stderr, _("Unable to map log file %s\n\n"), params.iprop_logfile); exit(1); } if (ulog_init_header(context) != 0) { fprintf(stderr, _("Couldn't reinitialize ulog file %s\n\n"), params.iprop_logfile); exit(1); } printf(_("Reinitialized the ulog.\n")); ulog_fini(context); goto done; } ulog = map_ulog(params.iprop_logfile, &ulog_fd); if (ulog == NULL) { fprintf(stderr, _("Unable to map log file %s\n\n"), params.iprop_logfile); exit(1); } if (ulog->kdb_hmagic != KDB_ULOG_HDR_MAGIC) { fprintf(stderr, _("Corrupt header log, exiting\n\n")); exit(1); } printf(_("Update log dump :\n")); printf(_("\tLog version # : %u\n"), ulog->db_version_num); printf(_("\tLog state : ")); switch (ulog->kdb_state) { case KDB_STABLE: printf(_("Stable\n")); break; case KDB_UNSTABLE: printf(_("Unstable\n")); break; case KDB_CORRUPT: printf(_("Corrupt\n")); break; default: printf(_("Unknown state: %d\n"), ulog->kdb_state); break; } printf(_("\tEntry block size : %u\n"), ulog->kdb_block); printf(_("\tNumber of entries : %u\n"), ulog->kdb_num); if (ulog->kdb_last_sno == 0) { printf(_("\tLast serial # : None\n")); } else { if (ulog->kdb_first_sno == 0) { printf(_("\tFirst serial # : None\n")); } else { printf(_("\tFirst serial # : ")); printf("%u\n", ulog->kdb_first_sno); } printf(_("\tLast serial # : ")); printf("%u\n", ulog->kdb_last_sno); } if (ulog->kdb_last_time.seconds == 0L) { printf(_("\tLast time stamp : None\n")); } else { if (ulog->kdb_first_time.seconds == 0L) { printf(_("\tFirst time stamp : None\n")); } else { printf(_("\tFirst time stamp : %s"), ctime_uint32(&ulog->kdb_first_time.seconds)); } printf(_("\tLast time stamp : %s\n"), ctime_uint32(&ulog->kdb_last_time.seconds)); } if (!headeronly && ulog->kdb_num) print_update(ulog, entry, params.iprop_ulogsize, verbose); printf("\n"); done: close(ulog_fd); kadm5_free_config_params(context, ¶ms); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/0000775000175000017500000000000015051422640014272 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/replay.c0000664000175000017500000001535615051422640015744 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/replay.c - test replay cache using libkrb5 functions */ /* * Copyright (C) 2019 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" int main(int argc, char **argv) { krb5_error_code ret; krb5_context ctx; krb5_auth_context c_authcon, s_authcon, s_authcon2; krb5_rcache rc; krb5_ccache cc; krb5_principal client, server; krb5_creds mcred, *cred, **tmpcreds; krb5_data der_apreq, der_krbsafe, der_krbpriv, *der_krbcred, tmpdata; krb5_address addr; struct in_addr inaddr; const char *server_name; assert(argc == 2); server_name = argv[1]; /* Create client and server auth contexts. (They will use a replay cache * by default.) */ ret = krb5_init_context(&ctx); assert(ret == 0); ret = krb5_auth_con_init(ctx, &c_authcon); assert(ret == 0); ret = krb5_auth_con_init(ctx, &s_authcon); assert(ret == 0); /* Set dummy addresses for the auth contexts. */ memset(&inaddr, 0, sizeof(inaddr)); addr.addrtype = ADDRTYPE_INET; addr.length = sizeof(inaddr); addr.contents = (uint8_t *)&inaddr; ret = krb5_auth_con_setaddrs(ctx, c_authcon, &addr, &addr); assert(ret == 0); ret = krb5_auth_con_setaddrs(ctx, s_authcon, &addr, &addr); assert(ret == 0); /* Set up replay caches for the auth contexts. */ tmpdata = string2data("testclient"); ret = krb5_get_server_rcache(ctx, &tmpdata, &rc); assert(ret == 0); ret = krb5_auth_con_setrcache(ctx, c_authcon, rc); assert(ret == 0); tmpdata = string2data("testserver"); ret = krb5_get_server_rcache(ctx, &tmpdata, &rc); assert(ret == 0); ret = krb5_auth_con_setrcache(ctx, s_authcon, rc); assert(ret == 0); /* Construct the client and server principal names. */ ret = krb5_cc_default(ctx, &cc); assert(ret == 0); ret = krb5_cc_get_principal(ctx, cc, &client); assert(ret == 0); ret = krb5_parse_name(ctx, server_name, &server); assert(ret == 0); /* Get credentials for the client. */ memset(&mcred, 0, sizeof(mcred)); mcred.client = client; mcred.server = server; ret = krb5_get_credentials(ctx, 0, cc, &mcred, &cred); assert(ret == 0); /* Send an AP-REP to establish the sessions. */ ret = krb5_mk_req_extended(ctx, &c_authcon, 0, NULL, cred, &der_apreq); assert(ret == 0); ret = krb5_rd_req(ctx, &s_authcon, &der_apreq, NULL, NULL, NULL, NULL); assert(ret == 0); /* Set up another server auth context with the same rcache name and replay * the AP-REQ. */ ret = krb5_auth_con_init(ctx, &s_authcon2); assert(ret == 0); tmpdata = string2data("testserver"); ret = krb5_get_server_rcache(ctx, &tmpdata, &rc); assert(ret == 0); ret = krb5_auth_con_setrcache(ctx, s_authcon2, rc); assert(ret == 0); ret = krb5_rd_req(ctx, &s_authcon2, &der_apreq, NULL, NULL, NULL, NULL); assert(ret == KRB5KRB_AP_ERR_REPEAT); krb5_auth_con_free(ctx, s_authcon2); /* Make a KRB-SAFE message with the client auth context. */ tmpdata = string2data("safemsg"); ret = krb5_mk_safe(ctx, c_authcon, &tmpdata, &der_krbsafe, NULL); assert(ret == 0); /* Play it back to the client to detect a reflection. */ ret = krb5_rd_safe(ctx, c_authcon, &der_krbsafe, &tmpdata, NULL); assert(ret == KRB5KRB_AP_ERR_REPEAT); /* Send it to the server auth context twice, to detect a replay. */ ret = krb5_rd_safe(ctx, s_authcon, &der_krbsafe, &tmpdata, NULL); assert(ret == 0); krb5_free_data_contents(ctx, &tmpdata); ret = krb5_rd_safe(ctx, s_authcon, &der_krbsafe, &tmpdata, NULL); assert(ret == KRB5KRB_AP_ERR_REPEAT); /* Make a KRB-PRIV message with the client auth context. */ tmpdata = string2data("safemsg"); ret = krb5_mk_priv(ctx, c_authcon, &tmpdata, &der_krbpriv, NULL); assert(ret == 0); /* Play it back to the client to detect a reflection. */ ret = krb5_rd_priv(ctx, c_authcon, &der_krbpriv, &tmpdata, NULL); assert(ret == KRB5KRB_AP_ERR_REPEAT); /* Send it to the server auth context twice, to detect a replay. */ ret = krb5_rd_priv(ctx, s_authcon, &der_krbpriv, &tmpdata, NULL); assert(ret == 0); krb5_free_data_contents(ctx, &tmpdata); ret = krb5_rd_priv(ctx, s_authcon, &der_krbpriv, &tmpdata, NULL); assert(ret == KRB5KRB_AP_ERR_REPEAT); /* Make a KRB-CRED message with the client auth context. */ tmpdata = string2data("safemsg"); ret = krb5_mk_1cred(ctx, c_authcon, cred, &der_krbcred, NULL); assert(ret == 0); /* Play it back to the client to detect a reflection. */ ret = krb5_rd_cred(ctx, c_authcon, der_krbcred, &tmpcreds, NULL); assert(ret == KRB5KRB_AP_ERR_REPEAT); /* Send it to the server auth context twice, to detect a replay. */ ret = krb5_rd_cred(ctx, s_authcon, der_krbcred, &tmpcreds, NULL); assert(ret == 0); krb5_free_tgt_creds(ctx, tmpcreds); ret = krb5_rd_cred(ctx, s_authcon, der_krbcred, &tmpcreds, NULL); assert(ret == KRB5KRB_AP_ERR_REPEAT); krb5_free_data_contents(ctx, &der_apreq); krb5_free_data_contents(ctx, &der_krbsafe); krb5_free_data_contents(ctx, &der_krbpriv); krb5_free_data(ctx, der_krbcred); krb5_free_creds(ctx, cred); krb5_cc_close(ctx, cc); krb5_free_principal(ctx, client); krb5_free_principal(ctx, server); krb5_auth_con_free(ctx, c_authcon); krb5_auth_con_free(ctx, s_authcon); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/rdreq.c0000664000175000017500000001005015051422640015547 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/rdreq.c - Test harness for krb5_rd_req */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include int main(int argc, char **argv) { krb5_context context; krb5_principal client_princ, tkt_princ, server_princ; krb5_ccache ccache; krb5_creds *cred, mcred; krb5_auth_context auth_con; krb5_data apreq; krb5_error_code ret, code; const char *tkt_name, *server_name, *emsg; /* Parse arguments. */ if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: rdreq tktname [servername]\n"); exit(1); } tkt_name = argv[1]; server_name = argv[2]; if (krb5_init_context(&context) != 0) abort(); /* Parse the requested principal names. */ if (krb5_parse_name(context, tkt_name, &tkt_princ) != 0) abort(); if (server_name != NULL) { if (krb5_parse_name(context, server_name, &server_princ) != 0) abort(); server_princ->type = KRB5_NT_SRV_HST; } else { server_princ = NULL; } /* Produce an AP-REQ message. */ if (krb5_cc_default(context, &ccache) != 0) abort(); if (krb5_cc_get_principal(context, ccache, &client_princ) != 0) abort(); memset(&mcred, 0, sizeof(mcred)); mcred.client = client_princ; mcred.server = tkt_princ; if (krb5_get_credentials(context, 0, ccache, &mcred, &cred) != 0) abort(); auth_con = NULL; if (krb5_mk_req_extended(context, &auth_con, 0, NULL, cred, &apreq) != 0) abort(); /* Consume the AP-REQ message without using a replay cache. */ krb5_auth_con_free(context, auth_con); if (krb5_auth_con_init(context, &auth_con) != 0) abort(); if (krb5_auth_con_setflags(context, auth_con, 0) != 0) abort(); ret = krb5_rd_req(context, &auth_con, &apreq, server_princ, NULL, NULL, NULL); /* Display the result. */ if (ret) { code = ret - ERROR_TABLE_BASE_krb5; if (code < 0 || code > 127) code = 60; /* KRB_ERR_GENERIC */ emsg = krb5_get_error_message(context, ret); printf("%d %s\n", code, emsg); krb5_free_error_message(context, emsg); } else { printf("0 success\n"); } krb5_free_data_contents(context, &apreq); assert(apreq.length == 0); krb5_auth_con_free(context, auth_con); krb5_free_creds(context, cred); krb5_cc_close(context, ccache); krb5_free_principal(context, client_princ); krb5_free_principal(context, tkt_princ); krb5_free_principal(context, server_princ); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/unlockiter.c0000664000175000017500000001652215051422640016623 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/unlockiter.c - test program for unlocked iteration */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Test unlocked KDB iteration. */ #include #include #include #include #include #include #include #include #include #include /* Some platforms need memset() for FD_ZERO */ #include struct cb_arg { int inpipe; int outpipe; int timeout; int done; }; /* Helper function for cb(): read a sync byte (with possible timeout), then * write a sync byte. */ static int syncpair_rw(const char *name, struct cb_arg *arg, char *cp, int timeout) { struct timeval tv; fd_set rset; int nfds; FD_ZERO(&rset); FD_SET(arg->inpipe, &rset); tv.tv_sec = timeout; tv.tv_usec = 0; printf("cb: waiting for %s sync pair\n", name); nfds = select(arg->inpipe + 1, &rset, NULL, NULL, (timeout == 0) ? NULL : &tv); if (nfds < 0) return -1; if (nfds == 0) { errno = ETIMEDOUT; return -1; } if (read(arg->inpipe, cp, 1) < 0) return -1; printf("cb: writing %s sync pair\n", name); if (write(arg->outpipe, cp, 1) < 0) return -1; return 0; } /* On the first iteration only, receive and send sync bytes to the locking * child to drive its locking activities. */ static krb5_error_code cb(void *argin, krb5_db_entry *ent) { struct cb_arg *arg = argin; char c = '\0'; if (arg->done) return 0; if (syncpair_rw("first", arg, &c, 0) < 0) { com_err("cb", errno, "first sync pair"); return errno; } if (syncpair_rw("second", arg, &c, arg->timeout) < 0) { com_err("cb", errno, "second sync pair"); return errno; } printf("cb: waiting for final sync byte\n"); if (read(arg->inpipe, &c, 1) < 0) { com_err("cb", errno, "final sync byte"); return errno; } arg->done = 1; return 0; } /* Parent process: iterate over the KDB, using a callback that synchronizes * with the locking child. */ static int iterator(struct cb_arg *cb_arg, char **db_args, pid_t child) { krb5_error_code retval; krb5_context ctx; retval = krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_KDC, &ctx); if (retval) goto cleanup; retval = krb5_db_open(ctx, db_args, KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN); if (retval) goto cleanup; retval = krb5_db_iterate(ctx, NULL, cb, cb_arg, 0); if (retval) goto cleanup; retval = krb5_db_fini(ctx); cleanup: krb5_free_context(ctx); if (retval) { com_err("iterator", retval, ""); kill(child, SIGTERM); exit(1); } return retval; } /* Helper function for locker(): write, then receive a sync byte. */ static int syncpair_wr(const char *name, int inpipe, int outpipe, unsigned char *cp) { printf("locker: writing %s sync pair\n", name); if (write(outpipe, cp, 1) < 0) return -1; printf("locker: waiting for %s sync pair\n", name); if (read(inpipe, cp, 1) < 0) return -1; return 0; } /* Child process: acquire and release a write lock on the KDB, synchronized * with parent. */ static int locker(int inpipe, int outpipe, char **db_args) { krb5_error_code retval; unsigned char c = '\0'; krb5_context ctx; retval = krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_KDC, &ctx); if (retval) goto cleanup; retval = krb5_db_open(ctx, db_args, KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN); if (retval) goto cleanup; if (syncpair_wr("first", inpipe, outpipe, &c) < 0) { retval = errno; goto cleanup; } printf("locker: acquiring lock...\n"); retval = krb5_db_lock(ctx, KRB5_DB_LOCKMODE_EXCLUSIVE); if (retval) goto cleanup; printf("locker: acquired lock\n"); if (syncpair_wr("second", inpipe, outpipe, &c) < 0) { retval = errno; goto cleanup; } krb5_db_unlock(ctx); printf("locker: released lock\n"); printf("locker: writing final sync byte\n"); if (write(outpipe, &c, 1) < 0) { retval = errno; goto cleanup; } retval = krb5_db_fini(ctx); cleanup: if (retval) com_err("locker", retval, ""); krb5_free_context(ctx); exit(retval != 0); } static void usage(const char *prog) { fprintf(stderr, "usage: %s [-lu] [-t timeout]\n", prog); exit(1); } int main(int argc, char *argv[]) { struct cb_arg cb_arg; pid_t child; char *db_args[2] = { NULL, NULL }; int c; int cstatus; int pipe_to_locker[2], pipe_to_iterator[2]; cb_arg.timeout = 1; cb_arg.done = 0; while ((c = getopt(argc, argv, "lt:u")) != -1) { switch (c) { case 'l': db_args[0] = "lockiter"; break; case 't': cb_arg.timeout = atoi(optarg); break; case 'u': db_args[0] = "unlockiter"; break; default: usage(argv[0]); } } if (pipe(pipe_to_locker) < 0) { com_err(argv[0], errno, "pipe(p_il)"); exit(1); } if (pipe(pipe_to_iterator) < 0) { com_err(argv[0], errno, "pipe(p_li)"); exit(1); } cb_arg.inpipe = pipe_to_iterator[0]; cb_arg.outpipe = pipe_to_locker[1]; child = fork(); switch (child) { case -1: com_err(argv[0], errno, "fork"); exit(1); break; case 0: locker(pipe_to_locker[0], pipe_to_iterator[1], db_args); break; default: if (iterator(&cb_arg, db_args, child)) exit(1); if (wait(&cstatus) < 0) { com_err(argv[0], errno, "wait"); exit(1); } if (WIFSIGNALED(cstatus)) exit(1); if (WIFEXITED(cstatus) && WEXITSTATUS(cstatus) != 0) { exit(1); } } exit(0); } krb5-1.22.1/src/tests/hist.c0000664000175000017500000001043315051422640015406 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/hist.c - Perform unusual operations on history keys */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is invoked from t_policy.py to simulate some conditions * normally only seen in older databases. It expects one argument, which can * be: * * make: The kadmin/history entry is created with two keys. (Since krb5 1.3 * we ordinarily ensure that there's only one.) * * swap: The kadmin/history entry previously created with "make" is modified * to swap the order of its keys. We use this operation to simulate the case * where krb5 1.7 or earlier chose something other than the first history key * to create password history entries. * * des: The kadmin/history entry is modified to change its first key type to * des-cbc-crc. The key length and contents are not changed. (DES support * was removed in krb5 1.18.) */ #include #include static void check(krb5_error_code ret) { if (ret) { fprintf(stderr, "Unexpected failure, aborting\n"); abort(); } } int main(int argc, char **argv) { krb5_context ctx; krb5_db_entry *ent; krb5_principal hprinc; kadm5_principal_ent_rec kent; krb5_key_salt_tuple ks[2]; krb5_key_data kd; kadm5_config_params params = { 0 }; void *handle; char *realm; long mask = KADM5_PRINCIPAL | KADM5_MAX_LIFE | KADM5_ATTRIBUTES; check(kadm5_init_krb5_context(&ctx)); check(krb5_parse_name(ctx, "kadmin/history", &hprinc)); check(krb5_get_default_realm(ctx, &realm)); params.mask |= KADM5_CONFIG_REALM; params.realm = realm; check(kadm5_init(ctx, "user", "", "", ¶ms, KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL, &handle)); if (strcmp(argv[1], "make") == 0) { memset(&kent, 0, sizeof(kent)); kent.principal = hprinc; kent.max_life = KRB5_KDB_DISALLOW_ALL_TIX; kent.attributes = 0; ks[0].ks_enctype = ENCTYPE_AES256_CTS_HMAC_SHA1_96; ks[0].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL; ks[1].ks_enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; ks[1].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL; check(kadm5_create_principal_3(handle, &kent, mask, 2, ks, NULL)); } else if (strcmp(argv[1], "swap") == 0) { check(krb5_db_get_principal(ctx, hprinc, 0, &ent)); kd = ent->key_data[0]; ent->key_data[0] = ent->key_data[1]; ent->key_data[1] = kd; check(krb5_db_put_principal(ctx, ent)); krb5_db_free_principal(ctx, ent); } else if (strcmp(argv[1], "des") == 0) { check(krb5_db_get_principal(ctx, hprinc, 0, &ent)); assert(ent->n_key_data >= 1); ent->key_data[0].key_data_type[0] = ENCTYPE_DES_CBC_CRC; check(krb5_db_put_principal(ctx, ent)); krb5_db_free_principal(ctx, ent); } krb5_free_default_realm(ctx, realm); kadm5_destroy(handle); krb5_free_principal(ctx, hprinc); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/adata.c0000664000175000017500000002744415051422640015523 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/adata.c - Test harness for KDC authorization data */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Usage: ./adata [-c ccname] [-p clientprinc] serviceprinc * [ad-type ad-contents ...] * * This program acquires credentials for the specified service principal, using * the specified or default ccache, possibly including requested authdata. The * resulting ticket is decrypted using the default keytab, and the authdata in * the ticket are displayed to stdout. * * In the requested authdata types, the type may be prefixed with '?' for an * AD-IF-RELEVANT container, '!' for an AD-MANDATORY-FOR-KDC container, or '^' * for an AD-KDC-ISSUED container checksummed with a random AES256 key. * Multiple prefixes may be specified for nested container. * * In the output, authdata containers will be flattened and displayed with the * above prefixes or '+' for an AD-CAMMAC container. AD-KDC-ISSUED and * AD-CAMMAC containers will be verified with the appropriate key. Nested * containers only display the prefix for the innermost container. */ #include #include static krb5_context ctx; static void display_authdata_list(krb5_authdata **list, krb5_enc_tkt_part *enc_tkt, krb5_keyblock *tktkey, char prefix_byte, krb5_boolean pac_ok); static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static krb5_authdatatype get_type_for_prefix(int prefix_byte) { if (prefix_byte == '?') return KRB5_AUTHDATA_IF_RELEVANT; if (prefix_byte == '!') return KRB5_AUTHDATA_MANDATORY_FOR_KDC; if (prefix_byte == '^') return KRB5_AUTHDATA_KDC_ISSUED; if (prefix_byte == '+') return KRB5_AUTHDATA_CAMMAC; abort(); } static int get_prefix_byte(krb5_authdata *ad) { if (ad->ad_type == KRB5_AUTHDATA_IF_RELEVANT) return '?'; if (ad->ad_type == KRB5_AUTHDATA_MANDATORY_FOR_KDC) return '!'; if (ad->ad_type == KRB5_AUTHDATA_KDC_ISSUED) return '^'; if (ad->ad_type == KRB5_AUTHDATA_CAMMAC) return '+'; abort(); } /* Construct a container of type ad_type for the single authdata element * content. For KDC-ISSUED containers, use a random checksum key. */ static krb5_authdata * make_container(krb5_authdatatype ad_type, krb5_authdata *content) { krb5_authdata *list[2], **enclist, *ad; krb5_keyblock kb; list[0] = content; list[1] = NULL; if (ad_type == KRB5_AUTHDATA_KDC_ISSUED) { check(krb5_c_make_random_key(ctx, ENCTYPE_AES256_CTS_HMAC_SHA1_96, &kb)); check(krb5_make_authdata_kdc_issued(ctx, &kb, NULL, list, &enclist)); krb5_free_keyblock_contents(ctx, &kb); } else { check(krb5_encode_authdata_container(ctx, ad_type, list, &enclist)); } /* Grab the first element from the encoded list and free the array. */ ad = enclist[0]; free(enclist); return ad; } /* Parse typestr and contents into an authdata element. */ static krb5_authdata * make_authdata(const char *typestr, const char *contents) { krb5_authdata *inner_ad, *ad; if (*typestr == '?' || *typestr == '!' || *typestr == '^') { inner_ad = make_authdata(typestr + 1, contents); ad = make_container(get_type_for_prefix(*typestr), inner_ad); free(inner_ad->contents); free(inner_ad); return ad; } ad = malloc(sizeof(*ad)); assert(ad != NULL); ad->magic = KV5M_AUTHDATA; ad->ad_type = atoi(typestr); ad->length = strlen(contents); ad->contents = (unsigned char *)strdup(contents); assert(ad->contents != NULL); return ad; } static krb5_authdata ** get_container_contents(krb5_authdata *ad, krb5_keyblock *skey, krb5_keyblock *tktkey) { krb5_authdata **inner_ad; if (ad->ad_type == KRB5_AUTHDATA_KDC_ISSUED) check(krb5_verify_authdata_kdc_issued(ctx, skey, ad, NULL, &inner_ad)); else if (ad->ad_type == KRB5_AUTHDATA_CAMMAC) check(k5_unwrap_cammac_svc(ctx, ad, tktkey, &inner_ad)); else check(krb5_decode_authdata_container(ctx, ad->ad_type, ad, &inner_ad)); return inner_ad; } static int compare_uint32(const void *p1, const void *p2) { uint32_t t1 = *(uint32_t *)p1, t2 = *(uint32_t *)p2; return (t1 > t2) ? 1 : (t1 == t2) ? 0 : -1; } static void display_pac(krb5_authdata *ad, krb5_enc_tkt_part *enc_tkt, krb5_keyblock *tktkey) { krb5_pac pac; size_t tlen, i; uint32_t *types; assert(ad->ad_type == KRB5_AUTHDATA_WIN2K_PAC); check(krb5_pac_parse(ctx, ad->contents, ad->length, &pac)); check(krb5_pac_verify(ctx, pac, enc_tkt->times.authtime, enc_tkt->client, tktkey, NULL)); check(krb5_pac_get_types(ctx, pac, &tlen, &types)); qsort(types, tlen, sizeof(*types), compare_uint32); printf("["); for (i = 0; i < tlen; i++) { printf("%d", (int)types[i]); if (i + 1 < tlen) printf(", "); } printf("]"); free(types); krb5_pac_free(ctx, pac); } /* Decode and display authentication indicator authdata. */ static void display_auth_indicator(krb5_authdata *ad) { krb5_data **strs = NULL, **p; check(k5_authind_decode(ad, &strs)); assert(strs != NULL); printf("["); for (p = strs; *p != NULL; p++) { printf("%.*s", (int)(*p)->length, (*p)->data); if (*(p + 1) != NULL) printf(", "); } printf("]"); k5_free_data_ptr_list(strs); } /* Display ad as either a hex dump or ASCII text. */ static void display_binary_or_ascii(krb5_authdata *ad) { krb5_boolean binary = FALSE; unsigned char *p; for (p = ad->contents; p < ad->contents + ad->length; p++) { if (!isascii(*p) || !isprint(*p)) binary = TRUE; } if (binary) { for (p = ad->contents; p < ad->contents + ad->length; p++) printf("%02X", *p); } else { printf("%.*s", (int)ad->length, ad->contents); } } /* Display the contents of an authdata element, prefixed by prefix_byte. skey * must be the ticket session key. */ static void display_authdata(krb5_authdata *ad, krb5_enc_tkt_part *enc_tkt, krb5_keyblock *tktkey, int prefix_byte, krb5_boolean pac_ok) { krb5_authdata **inner_ad; if (ad->ad_type == KRB5_AUTHDATA_IF_RELEVANT || ad->ad_type == KRB5_AUTHDATA_MANDATORY_FOR_KDC || ad->ad_type == KRB5_AUTHDATA_KDC_ISSUED || ad->ad_type == KRB5_AUTHDATA_CAMMAC) { if (ad->ad_type != KRB5_AUTHDATA_IF_RELEVANT) pac_ok = FALSE; /* Decode and display the contents. */ inner_ad = get_container_contents(ad, enc_tkt->session, tktkey); display_authdata_list(inner_ad, enc_tkt, tktkey, get_prefix_byte(ad), pac_ok); krb5_free_authdata(ctx, inner_ad); return; } assert(pac_ok || ad->ad_type != KRB5_AUTHDATA_WIN2K_PAC); printf("%c", prefix_byte); printf("%d: ", (int)ad->ad_type); if (ad->ad_type == KRB5_AUTHDATA_WIN2K_PAC) display_pac(ad, enc_tkt, tktkey); else if (ad->ad_type == KRB5_AUTHDATA_AUTH_INDICATOR) display_auth_indicator(ad); else display_binary_or_ascii(ad); printf("\n"); } static void display_authdata_list(krb5_authdata **list, krb5_enc_tkt_part *tkt_enc, krb5_keyblock *tktkey, char prefix_byte, krb5_boolean pac_ok) { if (list == NULL) return; /* Only expect a PAC in the first element, if at all. */ for (; *list != NULL; list++) { display_authdata(*list, tkt_enc, tktkey, prefix_byte, pac_ok); pac_ok = FALSE; } } int main(int argc, char **argv) { const char *ccname = NULL, *clientname = NULL; krb5_principal client, server; krb5_ccache ccache; krb5_keytab keytab; krb5_creds in_creds, *creds; krb5_ticket *ticket; krb5_authdata **req_authdata = NULL, *ad; krb5_keytab_entry ktent; size_t count; int c; check(krb5_init_context(&ctx)); while ((c = getopt(argc, argv, "+c:p:")) != -1) { switch (c) { case 'c': ccname = optarg; break; case 'p': clientname = optarg; break; default: abort(); } } argv += optind; /* Parse arguments. */ assert(*argv != NULL); check(krb5_parse_name(ctx, *argv++, &server)); count = 0; for (; argv[0] != NULL && argv[1] != NULL; argv += 2) { ad = make_authdata(argv[0], argv[1]); req_authdata = realloc(req_authdata, (count + 2) * sizeof(*req_authdata)); assert(req_authdata != NULL); req_authdata[count++] = ad; req_authdata[count] = NULL; } assert(*argv == NULL); if (ccname != NULL) check(krb5_cc_resolve(ctx, ccname, &ccache)); else check(krb5_cc_default(ctx, &ccache)); if (clientname != NULL) check(krb5_parse_name(ctx, clientname, &client)); else check(krb5_cc_get_principal(ctx, ccache, &client)); memset(&in_creds, 0, sizeof(in_creds)); in_creds.client = client; in_creds.server = server; in_creds.authdata = req_authdata; check(krb5_get_credentials(ctx, KRB5_GC_NO_STORE, ccache, &in_creds, &creds)); assert(in_creds.authdata == NULL || creds->authdata != NULL); check(krb5_decode_ticket(&creds->ticket, &ticket)); check(krb5_kt_default(ctx, &keytab)); check(krb5_kt_get_entry(ctx, keytab, ticket->server, ticket->enc_part.kvno, ticket->enc_part.enctype, &ktent)); check(krb5_decrypt_tkt_part(ctx, &ktent.key, ticket)); display_authdata_list(ticket->enc_part2->authorization_data, ticket->enc_part2, &ktent.key, ' ', TRUE); while (count > 0) { free(req_authdata[--count]->contents); free(req_authdata[count]); } free(req_authdata); krb5_free_keytab_entry_contents(ctx, &ktent); krb5_free_creds(ctx, creds); krb5_free_ticket(ctx, ticket); krb5_free_principal(ctx, client); krb5_free_principal(ctx, server); krb5_cc_close(ctx, ccache); krb5_kt_close(ctx, keytab); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/hooks.c0000664000175000017500000002144715051422640015571 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/hooks.c - test harness for KDC send and recv hooks */ /* * Copyright (C) 2016 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" static krb5_context ctx; static void check_code(krb5_error_code code, const char *file, int line) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s:%d -- %s (code=%d)\n", file, line, errmsg, (int)code); krb5_free_error_message(ctx, errmsg); exit(1); } } #define check(code) check_code((code), __FILE__, __LINE__) /* Verify that the canonicalize bit is set in an AS-REQ and remove it. */ static krb5_error_code test_send_as_req(krb5_context context, void *data, const krb5_data *realm, const krb5_data *message, krb5_data **new_message_out, krb5_data **reply_out) { krb5_kdc_req *as_req; int cmp; assert(krb5_is_as_req(message)); check(decode_krb5_as_req(message, &as_req)); assert(as_req->msg_type == KRB5_AS_REQ); assert(as_req->kdc_options & KDC_OPT_CANONICALIZE); assert(as_req->client->realm.length == realm->length); cmp = memcmp(as_req->client->realm.data, realm->data, realm->length); assert(cmp == 0); /* Remove the canonicalize flag and create a new message. */ as_req->kdc_options &= ~KDC_OPT_CANONICALIZE; check(encode_krb5_as_req(as_req, new_message_out)); krb5_free_kdc_req(context, as_req); return 0; } /* Verify that reply is an AS-REP with kvno 1 and a valid enctype. */ static krb5_error_code test_recv_as_rep(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply) { krb5_kdc_rep *as_rep; assert(code == 0); assert(krb5_is_as_rep(reply)); check(decode_krb5_as_rep(reply, &as_rep)); assert(as_rep->msg_type == KRB5_AS_REP); assert(as_rep->ticket->enc_part.kvno == 1); assert(krb5_c_valid_enctype(as_rep->ticket->enc_part.enctype)); krb5_free_kdc_rep(context, as_rep); return 0; } /* Create a fake error reply. */ static krb5_error_code test_send_error(krb5_context context, void *data, const krb5_data *realm, const krb5_data *message, krb5_data **new_message_out, krb5_data **reply_out) { krb5_error_code ret; krb5_error err; krb5_principal client, server; char *realm_str, *princ_str; int r; realm_str = k5memdup0(realm->data, realm->length, &ret); check(ret); r = asprintf(&princ_str, "invalid@%s", realm_str); assert(r > 0); check(krb5_parse_name(ctx, princ_str, &client)); free(princ_str); r = asprintf(&princ_str, "krbtgt@%s", realm_str); assert(r > 0); check(krb5_parse_name(ctx, princ_str, &server)); free(princ_str); free(realm_str); err.magic = KV5M_ERROR; err.ctime = 1971196337; err.cusec = 0; err.susec = 97008; err.stime = 1458219390; err.error = 6; err.client = client; err.server = server; err.text = string2data("CLIENT_NOT_FOUND"); err.e_data = empty_data(); check(encode_krb5_error(&err, reply_out)); krb5_free_principal(ctx, client); krb5_free_principal(ctx, server); return 0; } static krb5_error_code test_recv_error(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply) { /* The send hook created a reply, so this hook should not be executed. */ abort(); } /* Modify an AS-REP reply, change the msg_type to KRB5_TGS_REP. */ static krb5_error_code test_recv_modify_reply(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply) { krb5_kdc_rep *as_rep; assert(code == 0); assert(krb5_is_as_rep(reply)); check(decode_krb5_as_rep(reply, &as_rep)); as_rep->msg_type = KRB5_TGS_REP; check(encode_krb5_as_rep(as_rep, new_reply)); krb5_free_kdc_rep(context, as_rep); return 0; } /* Return an error given by the callback data argument. */ static krb5_error_code test_send_return_value(krb5_context context, void *data, const krb5_data *realm, const krb5_data *message, krb5_data **new_message_out, krb5_data **reply_out) { assert(data != NULL); return *(krb5_error_code *)data; } /* Return an error given by the callback argument. */ static krb5_error_code test_recv_return_value(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply) { assert(data != NULL); return *(krb5_error_code *)data; } int main(int argc, char *argv[]) { const char *principal, *password; krb5_principal client; krb5_get_init_creds_opt *opts; krb5_creds creds; krb5_error_code ret, test_return_code; if (argc != 3) { fprintf(stderr, "Usage: %s princname password\n", argv[0]); exit(1); } principal = argv[1]; password = argv[2]; check(krb5_init_context(&ctx)); check(krb5_parse_name(ctx, principal, &client)); /* Use a send hook to modify an outgoing AS-REQ. The library will detect * the modification in the reply. */ check(krb5_get_init_creds_opt_alloc(ctx, &opts)); krb5_get_init_creds_opt_set_canonicalize(opts, 1); krb5_set_kdc_send_hook(ctx, test_send_as_req, NULL); krb5_set_kdc_recv_hook(ctx, test_recv_as_rep, NULL); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, opts); assert(ret == KRB5_KDCREP_MODIFIED); krb5_get_init_creds_opt_free(ctx, opts); /* Use a send hook to synthesize a KRB-ERROR reply. */ krb5_set_kdc_send_hook(ctx, test_send_error, NULL); krb5_set_kdc_recv_hook(ctx, test_recv_error, NULL); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, NULL); assert(ret == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN); /* Use a recv hook to modify a KDC reply. */ krb5_set_kdc_send_hook(ctx, NULL, NULL); krb5_set_kdc_recv_hook(ctx, test_recv_modify_reply, NULL); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, NULL); assert(ret == KRB5KRB_AP_ERR_MSG_TYPE); /* Verify that the user data pointer works in the send hook. */ test_return_code = KRB5KDC_ERR_PREAUTH_FAILED; krb5_set_kdc_send_hook(ctx, test_send_return_value, &test_return_code); krb5_set_kdc_recv_hook(ctx, NULL, NULL); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, NULL); assert(ret == KRB5KDC_ERR_PREAUTH_FAILED); /* Verify that the user data pointer works in the recv hook. */ test_return_code = KRB5KDC_ERR_NULL_KEY; krb5_set_kdc_send_hook(ctx, NULL, NULL); krb5_set_kdc_recv_hook(ctx, test_recv_return_value, &test_return_code); ret = krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, NULL); assert(ret == KRB5KDC_ERR_NULL_KEY); krb5_free_principal(ctx, client); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/t_tabdump.py0000775000175000017500000000472015051422640016631 0ustar ghudsonghudsonfrom k5test import * import csv from io import StringIO def tab_csv(s): io = StringIO(s) return list(csv.DictReader(io, dialect=csv.excel_tab)) def getrows(dumptype): out = realm.run([kdb5_util, 'tabdump', dumptype]) return tab_csv(out) def checkkeys(rows, dumptype, names): if sorted(rows[0].keys()) != sorted(names): fail('tabdump %s field names' % dumptype) realm = K5Realm(start_kdc=False, get_creds=False) realm.run([kadminl, 'alias', 'useralias', 'user']) rows = getrows('alias') checkkeys(rows, 'alias', ["aliasname", "targetname"]) if (rows[0]['aliasname'] != 'useralias@KRBTEST.COM' or rows[0]['targetname'] != 'user@KRBTEST.COM'): fail('tabdump alias principal names') rows = getrows('keyinfo') checkkeys(rows, 'keyinfo', ["name", "keyindex", "kvno", "enctype", "salttype", "salt"]) userrows = [x for x in rows if x['name'].startswith('user@')] userrows.sort(key=lambda x: x['keyindex']) if (userrows[0]['enctype'] != 'aes256-cts-hmac-sha1-96' or userrows[1]['enctype'] != 'aes128-cts-hmac-sha1-96'): fail('tabdump keyinfo enctypes') success('tabdump keyinfo') rows = getrows('keydata') checkkeys(rows, 'keydata', ["name", "keyindex", "kvno", "enctype", "key", "salttype", "salt"]) rows = getrows('princ_flags') checkkeys(rows, 'princ_flags', ["name", "flag", "value"]) rows = getrows('princ_lockout') checkkeys(rows, 'princ_lockout', ["name", "last_success", "last_failed", "fail_count"]) realm.run([kadminl, 'addpol', '-history', '3', 'testpol']) realm.run([kadminl, 'modprinc', '-policy', 'testpol', 'user']) rows = getrows('princ_meta') checkkeys(rows, 'princ_meta', ["name", "modby", "modtime", "lastpwd", "policy", "mkvno", "hist_kvno"]) userrows = [x for x in rows if x['name'].startswith('user@')] if userrows[0]['policy'] != 'testpol': fail('tabdump princ_meta policy name') realm.run([kadminl, 'set_string', 'user', 'foo', 'bar']) rows = getrows('princ_stringattrs') checkkeys(rows, 'princ_stringattrs', ["name", "key", "value"]) userrows = [x for x in rows if x['name'].startswith('user@')] if (len(userrows) != 1 or userrows[0]['key'] != 'foo' or userrows[0]['value'] != 'bar'): fail('tabdump princ_stringattrs key/value') rows = getrows('princ_tktpolicy') checkkeys(rows, 'princ_tktpolicy', ["name", "expiration", "pw_expiration", "max_life", "max_renew_life"]) success('tabdump') krb5-1.22.1/src/tests/t_kadmin_acl.py0000775000175000017500000005117615051422640017266 0ustar ghudsonghudsonfrom k5test import * import os realm = K5Realm(create_host=False, create_user=False) def make_client(name): global realm realm.addprinc(name, password(name)) ccache = os.path.join(realm.testdir, 'kadmin_ccache_' + name.replace('/', '_')) realm.kinit(name, password(name), flags=['-S', 'kadmin/admin', '-c', ccache]) return ccache def kadmin_as(client, query, **kwargs): global realm return realm.run([kadmin, '-c', client] + query, **kwargs) all_add = make_client('all_add') all_changepw = make_client('all_changepw') all_delete = make_client('all_delete') all_inquire = make_client('all_inquire') all_list = make_client('all_list') all_modify = make_client('all_modify') all_rename = make_client('all_rename') all_wildcard = make_client('all_wildcard') all_extract = make_client('all_extract') all_alias = make_client('all_alias') some_add = make_client('some_add') some_changepw = make_client('some_changepw') some_delete = make_client('some_delete') some_inquire = make_client('some_inquire') some_modify = make_client('some_modify') some_rename = make_client('some_rename') some_extract = make_client('some_extract') some_alias = make_client('some_alias') restricted_add = make_client('restricted_add') restricted_modify = make_client('restricted_modify') restricted_rename = make_client('restricted_rename') restricted_alias = make_client('restricted_alias') wctarget = make_client('wctarget') admin = make_client('user/admin') none = make_client('none') restrictions = make_client('restrictions') onetwothreefour = make_client('one/two/three/four') realm.run([kadminl, 'alias', 'aliastonone', 'none']) aliastonone = os.path.join(realm.testdir, 'kadmin_ccache_aliastonone') realm.kinit('aliastonone', password('none'), flags=['-S', 'kadmin/admin', '-c', aliastonone]) realm.run([kadminl, 'alias', 'aliastounselected', 'unselected']) realm.run([kadminl, 'alias', 'aliastoselected', 'selected']) realm.run([kadminl, 'addpol', '-minlife', '1 day', 'minlife']) f = open(os.path.join(realm.testdir, 'acl'), 'w') f.write(''' all_add a all_changepw c all_delete d all_inquire i all_list l all_modify im all_rename ad all_wildcard x all_extract ie all_alias am some_add a selected some_add a aliastounselected some_changepw c selected some_changepw c aliastounselected some_delete d selected some_delete d aliastounselected some_inquire i selected some_inquire i aliastounselected some_modify im selected some_modify im aliastounselected some_extract ie selected some_extract ie aliastounselected some_rename d from some_rename a to some_alias a aliasname some_alias m canon restricted_add a * +preauth restricted_modify im * +preauth restricted_rename ad * +preauth restricted_alias ai * +preauth */* d *2/*1 # The next line is a regression test for #8154; it is not used directly. one/*/*/five l */two/*/* d *3/*1/*2 */admin a wctarget a wild/* restrictions a type1 -policy minlife restrictions a type2 -clearpolicy restrictions a type3 -maxlife 1h -maxrenewlife 2h ''') f.close() realm.start_kadmind() # cpw can generate four different RPC calls depending on options. realm.addprinc('selected', 'oldpw') realm.addprinc('unselected', 'oldpw') for pw in (['-pw', 'newpw'], ['-randkey']): for ks in ([], ['-e', 'aes256-cts']): mark('cpw: %s %s' % (repr(pw), repr(ks))) args = pw + ks kadmin_as(all_changepw, ['cpw'] + args + ['unselected']) kadmin_as(some_changepw, ['cpw'] + args + ['selected']) msg = "Operation requires ``change-password'' privilege" kadmin_as(none, ['cpw'] + args + ['selected'], expected_code=1, expected_msg=msg) kadmin_as(some_changepw, ['cpw'] + args + ['unselected'], expected_code=1, expected_msg=msg) # Verify that the ACL check is canonicalized. kadmin_as(some_changepw, ['cpw'] + args + ['aliastounselected'], expected_code=1, expected_msg=msg) kadmin_as(some_changepw, ['cpw'] + args + ['aliastoselected']) kadmin_as(none, ['cpw'] + args + ['none']) kadmin_as(aliastonone, ['cpw'] + args + ['none'], expected_code=1, expected_msg=msg) realm.run([kadminl, 'modprinc', '-policy', 'minlife', 'none']) msg = "Current password's minimum life has not expired" kadmin_as(none, ['cpw'] + args + ['none'], expected_code=1, expected_msg=msg) realm.run([kadminl, 'modprinc', '-clearpolicy', 'none']) realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) mark('addpol') kadmin_as(all_add, ['addpol', 'policy']) realm.run([kadminl, 'delpol', 'policy']) kadmin_as(none, ['addpol', 'policy'], expected_code=1, expected_msg="Operation requires ``add'' privilege") # addprinc can generate two different RPC calls depending on options. for ks in ([], ['-e', 'aes256-cts']): mark('addprinc: %s' % repr(ks)) args = ['-pw', 'pw'] + ks kadmin_as(all_add, ['addprinc'] + args + ['unselected']) realm.run([kadminl, 'delprinc', 'unselected']) kadmin_as(some_add, ['addprinc'] + args + ['selected']) realm.run([kadminl, 'delprinc', 'selected']) kadmin_as(restricted_add, ['addprinc'] + args + ['unselected']) realm.run([kadminl, 'getprinc', 'unselected'], expected_msg='REQUIRES_PRE_AUTH') realm.run([kadminl, 'delprinc', 'unselected']) kadmin_as(none, ['addprinc'] + args + ['selected'], expected_code=1, expected_msg="Operation requires ``add'' privilege") kadmin_as(some_add, ['addprinc'] + args + ['unselected'], expected_code=1, expected_msg="Operation requires ``add'' privilege") # Verify that the ACL check isn't canonicalized. (We need the alias # to resolve or we will overwrite it, currently.) realm.addprinc('unselected') kadmin_as(some_add, ['addprinc'] + args + ['aliastounselected'], expected_code=1, expected_msg='already exists') realm.run([kadminl, 'delprinc', 'unselected']) mark('delprinc') realm.addprinc('unselected', 'pw') kadmin_as(all_delete, ['delprinc', 'unselected']) realm.addprinc('selected', 'pw') kadmin_as(some_delete, ['delprinc', 'selected']) realm.addprinc('unselected', 'pw') kadmin_as(none, ['delprinc', 'unselected'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") kadmin_as(some_delete, ['delprinc', 'unselected'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") # Verify that the ACL check isn't canonicalized. kadmin_as(some_delete, ['delprinc', 'aliastounselected']) realm.run([kadminl, 'alias', 'aliastounselected', 'unselected']) kadmin_as(some_delete, ['delprinc', 'aliastoselected'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") realm.run([kadminl, 'delprinc', 'unselected']) mark('getpol') kadmin_as(all_inquire, ['getpol', 'minlife'], expected_msg='Policy: minlife') kadmin_as(none, ['getpol', 'minlife'], expected_code=1, expected_msg="Operation requires ``get'' privilege") realm.run([kadminl, 'modprinc', '-policy', 'minlife', 'none']) kadmin_as(none, ['getpol', 'minlife'], expected_msg='Policy: minlife') realm.run([kadminl, 'modprinc', '-clearpolicy', 'none']) mark('getprinc') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_inquire, ['getprinc', 'unselected'], expected_msg='Principal: unselected@KRBTEST.COM') kadmin_as(some_inquire, ['getprinc', 'selected'], expected_msg='Principal: selected@KRBTEST.COM') kadmin_as(none, ['getprinc', 'selected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") kadmin_as(some_inquire, ['getprinc', 'unselected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") # Verify that the ACL check is canonicalized. kadmin_as(some_inquire, ['getprinc', 'aliastounselected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") kadmin_as(some_inquire, ['getprinc', 'aliastoselected'], expected_msg='Principal: selected@KRBTEST.COM') kadmin_as(none, ['getprinc', 'none'], expected_msg='Principal: none@KRBTEST.COM') realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) mark('listprincs') kadmin_as(all_list, ['listprincs'], expected_msg='K/M@KRBTEST.COM') kadmin_as(none, ['listprincs'], expected_code=1, expected_msg="Operation requires ``list'' privilege") mark('getstrs') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') realm.run([kadminl, 'setstr', 'selected', 'key', 'value']) realm.run([kadminl, 'setstr', 'unselected', 'key', 'value']) kadmin_as(all_inquire, ['getstrs', 'unselected'], expected_msg='key: value') kadmin_as(some_inquire, ['getstrs', 'selected'], expected_msg='key: value') kadmin_as(none, ['getstrs', 'selected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") kadmin_as(some_inquire, ['getstrs', 'unselected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") # Verify that the ACL check is canonicalized. kadmin_as(some_inquire, ['getstrs', 'aliastounselected'], expected_code=1, expected_msg="Operation requires ``get'' privilege") kadmin_as(some_inquire, ['getstrs', 'aliastoselected'], expected_msg='key: value') kadmin_as(none, ['getstrs', 'none'], expected_msg='(No string attributes.)') realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) mark('modpol') out = kadmin_as(all_modify, ['modpol', '-maxlife', '1 hour', 'policy'], expected_code=1) if 'Operation requires' in out: fail('modpol success (acl)') kadmin_as(none, ['modpol', '-maxlife', '1 hour', 'policy'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") mark('modprinc') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_modify, ['modprinc', '-maxlife', '1 hour', 'unselected']) kadmin_as(some_modify, ['modprinc', '-maxlife', '1 hour', 'selected']) kadmin_as(restricted_modify, ['modprinc', '-maxlife', '1 hour', 'unselected']) realm.run([kadminl, 'getprinc', 'unselected'], expected_msg='REQUIRES_PRE_AUTH') kadmin_as(all_inquire, ['modprinc', '-maxlife', '1 hour', 'selected'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") kadmin_as(some_modify, ['modprinc', '-maxlife', '1 hour', 'unselected'], expected_code=1, expected_msg='Operation requires') # Verify that the ACL check is canonicalized. kadmin_as(some_modify, ['modprinc', '-maxlife', '1 hour', 'aliastounselected'], expected_code=1, expected_msg='Operation requires') kadmin_as(some_modify, ['modprinc', '-maxlife', '2 hours', 'aliastoselected']) realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) mark('purgekeys') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_modify, ['purgekeys', 'unselected']) kadmin_as(some_modify, ['purgekeys', 'selected']) kadmin_as(none, ['purgekeys', 'selected'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") kadmin_as(some_modify, ['purgekeys', 'unselected'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") # Verify that the ACL check is canonicalized. kadmin_as(some_modify, ['purgekeys', 'aliastounselected'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") kadmin_as(some_modify, ['purgekeys', 'aliastoselected']) kadmin_as(none, ['purgekeys', 'none']) realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) mark('renprinc') realm.addprinc('from', 'pw') kadmin_as(all_rename, ['renprinc', 'from', 'to']) realm.run([kadminl, 'renprinc', 'to', 'from']) kadmin_as(some_rename, ['renprinc', 'from', 'to']) realm.run([kadminl, 'renprinc', 'to', 'from']) kadmin_as(all_add, ['renprinc', 'from', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(all_delete, ['renprinc', 'from', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(some_rename, ['renprinc', 'from', 'notto'], expected_code=1, expected_msg="Insufficient authorization for operation") realm.run([kadminl, 'renprinc', 'from', 'notfrom']) kadmin_as(some_rename, ['renprinc', 'notfrom', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") # Verify that the ACL check isn't canonicalized. realm.run([kadminl, 'alias', 'aliastofrom', 'from']) realm.run([kadminl, 'alias', 'aliastoto', 'to']) kadmin_as(some_rename, ['renprinc', 'aliastofrom', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(some_rename, ['renprinc', 'from', 'aliastoto'], expected_code=1, expected_msg="Insufficient authorization for operation") realm.run([kadminl, 'delprinc', 'aliastofrom']) realm.run([kadminl, 'delprinc', 'aliastoto']) kadmin_as(restricted_rename, ['renprinc', 'notfrom', 'to'], expected_code=1, expected_msg="Insufficient authorization for operation") realm.run([kadminl, 'delprinc', 'notfrom']) mark('setstr') realm.addprinc('selected', 'pw') realm.addprinc('unselected', 'pw') kadmin_as(all_modify, ['setstr', 'unselected', 'key', 'value']) kadmin_as(some_modify, ['setstr', 'selected', 'key', 'value']) kadmin_as(none, ['setstr', 'selected', 'key', 'value'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") kadmin_as(some_modify, ['setstr', 'unselected', 'key', 'value'], expected_code=1, expected_msg='Operation requires') # Verify that the ACL check is canonicalized. kadmin_as(some_modify, ['setstr', 'aliastounselected', 'key', 'value'], expected_code=1, expected_msg='Operation requires') kadmin_as(some_modify, ['setstr', 'aliastoselected', 'key', 'value']) realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) mark('addprinc/delprinc (wildcard)') kadmin_as(admin, ['addprinc', '-pw', 'pw', 'anytarget']) realm.run([kadminl, 'delprinc', 'anytarget']) kadmin_as(wctarget, ['addprinc', '-pw', 'pw', 'wild/card']) realm.run([kadminl, 'delprinc', 'wild/card']) kadmin_as(wctarget, ['addprinc', '-pw', 'pw', 'wild/card/extra'], expected_code=1, expected_msg='Operation requires') realm.addprinc('admin/user', 'pw') kadmin_as(admin, ['delprinc', 'admin/user']) kadmin_as(admin, ['delprinc', 'none'], expected_code=1, expected_msg='Operation requires') realm.addprinc('four/one/three', 'pw') kadmin_as(onetwothreefour, ['delprinc', 'four/one/three']) mark('addprinc (restrictions)') kadmin_as(restrictions, ['addprinc', '-pw', 'pw', 'type1']) realm.run([kadminl, 'getprinc', 'type1'], expected_msg='Policy: minlife') realm.run([kadminl, 'delprinc', 'type1']) kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-policy', 'minlife', 'type2']) realm.run([kadminl, 'getprinc', 'type2'], expected_msg='Policy: [none]') realm.run([kadminl, 'delprinc', 'type2']) kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-maxlife', '1 minute', 'type3']) out = realm.run([kadminl, 'getprinc', 'type3']) if ('Maximum ticket life: 0 days 00:01:00' not in out or 'Maximum renewable life: 0 days 02:00:00' not in out): fail('restriction (maxlife low, maxrenewlife unspec)') realm.run([kadminl, 'delprinc', 'type3']) kadmin_as(restrictions, ['addprinc', '-pw', 'pw', '-maxrenewlife', '1 day', 'type3']) realm.run([kadminl, 'getprinc', 'type3'], expected_msg='Maximum renewable life: 0 days 02:00:00') mark('extract') realm.addprinc('selected') realm.addprinc('unselected') realm.run([kadminl, 'addprinc', '-pw', 'pw', 'extractkeys']) msg = "Operation requires ``extract-keys'' privilege" kadmin_as(all_wildcard, ['ktadd', '-norandkey', 'extractkeys'], expected_code=1, expected_msg=msg) kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys']) realm.kinit('extractkeys', flags=['-k']) kadmin_as(some_extract, ['ktadd', '-norandkey', 'selected']) kadmin_as(some_extract, ['ktadd', '-norandkey', 'unselected'], expected_code=1, expected_msg=msg) # Verify that the ACL check is canonicalized. kadmin_as(some_extract, ['ktadd', '-norandkey', 'aliastounselected'], expected_code=1, expected_msg=msg) kadmin_as(some_extract, ['ktadd', '-norandkey', 'aliastoselected']) os.remove(realm.keytab) realm.run([kadminl, 'delprinc', 'selected']) realm.run([kadminl, 'delprinc', 'unselected']) mark('lockdown_keys') kadmin_as(all_modify, ['modprinc', '+lockdown_keys', 'extractkeys']) kadmin_as(all_changepw, ['cpw', '-pw', 'newpw', 'extractkeys'], expected_code=1, expected_msg="Operation requires ``change-password'' privilege") kadmin_as(all_changepw, ['cpw', '-randkey', 'extractkeys']) kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys'], expected_code=1, expected_msg="Operation requires ``extract-keys'' privilege") kadmin_as(all_delete, ['delprinc', 'extractkeys'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") kadmin_as(all_rename, ['renprinc', 'extractkeys', 'renamedprinc'], expected_code=1, expected_msg="Operation requires ``delete'' privilege") kadmin_as(all_modify, ['modprinc', '-lockdown_keys', 'extractkeys'], expected_code=1, expected_msg="Operation requires ``modify'' privilege") realm.run([kadminl, 'modprinc', '-lockdown_keys', 'extractkeys']) kadmin_as(all_extract, ['ktadd', '-norandkey', 'extractkeys']) realm.kinit('extractkeys', flags=['-k']) os.remove(realm.keytab) mark('alias') kadmin_as(all_alias, ['alias', 'aliasname', 'canon']) realm.run([kadminl, 'delprinc', 'aliasname']) kadmin_as(some_alias, ['alias', 'aliasname', 'canon']) realm.run([kadminl, 'delprinc', 'aliasname']) kadmin_as(all_add, ['alias', 'aliasname', 'canon'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(all_inquire, ['alias', 'aliasname', 'canon'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(some_alias, ['alias', 'aliasname', 'notcanon'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(some_alias, ['alias', 'notaliasname', 'canon'], expected_code=1, expected_msg="Insufficient authorization for operation") kadmin_as(restricted_alias, ['alias', 'aliasname', 'canon'], expected_code=1, expected_msg="Insufficient authorization for operation") # Verify that self-service key changes require an initial ticket. mark('self-service initial ticket') realm.run([kadminl, 'cpw', '-pw', password('none'), 'none']) realm.run([kadminl, 'modprinc', '+allow_tgs_req', 'kadmin/admin']) realm.kinit('none', password('none')) realm.run([kvno, 'kadmin/admin']) msg = 'Operation requires initial ticket' realm.run([kadmin, '-c', realm.ccache, 'cpw', '-pw', 'newpw', 'none'], expected_code=1, expected_msg=msg) realm.run([kadmin, '-c', realm.ccache, 'cpw', '-pw', 'newpw', '-e', 'aes256-cts', 'none'], expected_code=1, expected_msg=msg) realm.run([kadmin, '-c', realm.ccache, 'cpw', '-randkey', 'none'], expected_code=1, expected_msg=msg) realm.run([kadmin, '-c', realm.ccache, 'cpw', '-randkey', '-e', 'aes256-cts', 'none'], expected_code=1, expected_msg=msg) # Test authentication to kadmin/hostname. mark('authentication to kadmin/hostname') kadmin_hostname = 'kadmin/' + hostname realm.addprinc(kadmin_hostname) realm.run([kadminl, 'delprinc', 'kadmin/admin']) msgs = ('Getting initial credentials for user/admin@KRBTEST.COM', 'Setting initial creds service to kadmin/admin', '/Server not found in Kerberos database', 'Getting initial credentials for user/admin@KRBTEST.COM', 'Setting initial creds service to ' + kadmin_hostname, 'Decrypted AS reply') realm.run([kadmin, '-p', 'user/admin', 'listprincs'], expected_code=1, expected_msg="Operation requires ``list'' privilege", input=password('user/admin'), expected_trace=msgs) # Test operations disallowed at the libkadm5 layer. realm.run([kadminl, 'delprinc', 'K/M'], expected_code=1, expected_msg='Cannot change protected principal') realm.run([kadminl, 'cpw', '-pw', 'pw', 'kadmin/history'], expected_code=1, expected_msg='Cannot change protected principal') success('kadmin ACL enforcement') krb5-1.22.1/src/tests/t_kadm5_auth.py0000664000175000017500000000735715051422640017225 0ustar ghudsonghudsonfrom k5test import * # Create a realm with the welcomer and bouncer kadm5_auth test modules # in place of the builtin modules. modpath = os.path.join(buildtop, 'plugins', 'kadm5_auth', 'test', 'kadm5_auth_test.so') conf = {'plugins': {'kadm5_auth': {'module': ['welcomer:' + modpath, 'bouncer:' + modpath], 'enable_only': ['welcomer', 'bouncer']}}} realm = K5Realm(krb5_conf=conf, create_host=False) realm.start_kadmind() realm.prep_kadmin() # addprinc: welcomer accepts with policy VIP, bouncer denies maxlife. realm.run_kadmin(['addprinc', '-randkey', 'princ'], expected_code=1) realm.run_kadmin(['addprinc', '-randkey', '-policy', 'VIP', 'princ']) realm.run_kadmin(['addprinc', '-randkey', '-policy', 'VIP', '-maxlife', '3', 'princ'], expected_code=1) # modprinc: welcomer accepts with only maxrenewlife, bouncer denies # with even-component target principal. realm.run_kadmin(['modprinc', '-maxlife', '3', 'princ'], expected_code=1) realm.run_kadmin(['modprinc', '-maxrenewlife', '3', 'princ']) realm.run_kadmin(['modprinc', '-maxrenewlife', '3', 'user/admin'], expected_code=1) # setstr: welcomer accepts with key 'note', bouncer denies with value # length > 10. realm.run_kadmin(['setstr', 'princ', 'somekey', 'someval'], expected_code=1) realm.run_kadmin(['setstr', 'princ', 'note', 'abc']) realm.run_kadmin(['setstr', 'princ', 'note', 'abcdefghijkl'], expected_code=1) # delprinc: welcomer accepts with target principal beginning with 'd', # bouncer denies with "nodelete" string attribute. realm.run_kadmin(['delprinc', 'user'], expected_code=1) realm.run([kadminl, 'addprinc', '-randkey', 'deltest']) realm.run_kadmin(['delprinc', 'deltest']) realm.run([kadminl, 'addprinc', '-randkey', 'deltest']) realm.run([kadminl, 'setstr', 'deltest', 'nodelete', 'yes']) realm.run_kadmin(['delprinc', 'deltest'], expected_code=1) # renprinc: welcomer accepts with same-length first components, bouncer # refuses with source principal beginning with 'a'. realm.run_kadmin(['renprinc', 'princ', 'xyz'], expected_code=1) realm.run_kadmin(['renprinc', 'princ', 'abcde']) realm.run_kadmin(['renprinc', 'abcde', 'fghij'], expected_code=1) # addpol: welcomer accepts with minlength 3, bouncer denies with name # length <= 3. realm.run_kadmin(['addpol', 'testpol'], expected_code=1) realm.run_kadmin(['addpol', '-minlength', '3', 'testpol']) realm.run_kadmin(['addpol', '-minlength', '3', 'abc'], expected_code=1) # modpol: welcomer accepts changes to minlife, bouncer denies with # minlife > 10. realm.run_kadmin(['modpol', '-minlength', '4', 'testpol'], expected_code=1) realm.run_kadmin(['modpol', '-minlife', '8', 'testpol']) realm.run_kadmin(['modpol', '-minlife', '11', 'testpol'], expected_code=1) # getpol: welcomer accepts if policy and client policy have same length, # bouncer denies if policy name begins with 'x'. realm.run([kadminl, 'addpol', 'aaaa']) realm.run([kadminl, 'addpol', 'bbbb']) realm.run([kadminl, 'addpol', 'xxxx']) realm.run([kadminl, 'modprinc', '-policy', 'aaaa', 'user/admin']) realm.run_kadmin(['getpol', 'testpol'], expected_code=1) realm.run_kadmin(['getpol', 'bbbb']) realm.run_kadmin(['getpol', 'xxxx'], expected_code=1) # end: welcomer counts operations using "ends" string attribute on # "opcount" principal. kadmind is dumb and invokes the end method for # every RPC operation including init, so we expect four calls to the # end operation. realm.run([kadminl, 'addprinc', '-nokey', 'opcount']) realm.run([kadminl, 'setstr', 'opcount', 'ends', '0']) realm.run_kadmin(['getprinc', 'user']) realm.run_kadmin(['getpol', 'bbbb']) realm.run([kadminl, 'getstrs', 'opcount'], expected_msg='ends: 4') success('kadm5_auth pluggable interface tests') krb5-1.22.1/src/tests/t_cve-2021-36222.py0000664000175000017500000000361115051422640017003 0ustar ghudsonghudsonimport socket from k5test import * realm = K5Realm() # CVE-2021-36222 KDC null dereference on encrypted challenge preauth # without FAST s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) a = (hostname, realm.portbase) m = ('6A81A0' '30819D' # [APPLICATION 10] SEQUENCE 'A103' '0201' '05' # [1] pvno = 5 'A203' '0201' '0A' # [2] msg-type = 10 'A30E' '300C' # [3] padata = SEQUENCE OF '300A' # SEQUENCE 'A104' '0202' '008A' # [1] padata-type = PA-ENCRYPTED-CHALLENGE 'A202' '0400' # [2] padata-value = "" 'A48180' '307E' # [4] req-body = SEQUENCE 'A007' '0305' '0000000000' # [0] kdc-options = 0 'A120' '301E' # [1] cname = SEQUENCE 'A003' '0201' '01' # [0] name-type = NT-PRINCIPAL 'A117' '3015' # [1] name-string = SEQUENCE-OF '1B06' '6B7262746774' # krbtgt '1B0B' '4B5242544553542E434F4D' # KRBTEST.COM 'A20D' '1B0B' '4B5242544553542E434F4D' # [2] realm = KRBTEST.COM 'A320' '301E' # [3] sname = SEQUENCE 'A003' '0201' '01' # [0] name-type = NT-PRINCIPAL 'A117' '3015' # [1] name-string = SEQUENCE-OF '1B06' '6B7262746774' # krbtgt '1B0B' '4B5242544553542E434F4D' # KRBTEST.COM 'A511' '180F' '31393934303631303036303331375A' # [5] till = 19940610060317Z 'A703' '0201' '00' # [7] nonce = 0 'A808' '3006' # [8] etype = SEQUENCE OF '020112' '020111') # aes256-cts aes128-cts s.sendto(bytes.fromhex(m), a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) success('CVE-2021-36222 regression test') krb5-1.22.1/src/tests/kcmserver.py0000664000175000017500000002276015051422640016654 0ustar ghudsonghudson# This is a simple KCM test server, used to exercise the KCM ccache # client code. It will generally throw an uncaught exception if the # client sends anything unexpected, so is unsuitable for production. # (It also imposes no namespace or access constraints, and blocks # while reading requests and writing responses.) # This code knows nothing about how to marshal and unmarshal principal # names and credentials as is required in the KCM protocol; instead, # it just remembers the marshalled forms and replays them to the # client when asked. This works because marshalled creds and # principal names are always the last part of marshalled request # arguments, and because we don't need to implement remove_cred (which # would need to know how to match a cred tag against previously stored # credentials). # The following code is useful for debugging if anything appears to be # going wrong in the server, since daemon output is generally not # visible in Python test scripts. # # import sys, traceback # def ehook(etype, value, tb): # with open('/tmp/exception', 'w') as f: # traceback.print_exception(etype, value, tb, file=f) # sys.excepthook = ehook import optparse import select import socket import struct import sys caches = {} cache_uuidmap = {} defname = b'default' next_unique = 1 next_uuid = 1 class KCMOpcodes(object): GEN_NEW = 3 INITIALIZE = 4 DESTROY = 5 STORE = 6 RETRIEVE = 7 GET_PRINCIPAL = 8 GET_CRED_UUID_LIST = 9 GET_CRED_BY_UUID = 10 REMOVE_CRED = 11 GET_CACHE_UUID_LIST = 18 GET_CACHE_BY_UUID = 19 GET_DEFAULT_CACHE = 20 SET_DEFAULT_CACHE = 21 GET_KDC_OFFSET = 22 SET_KDC_OFFSET = 23 GET_CRED_LIST = 13001 REPLACE = 13002 class KRB5Errors(object): KRB5_CC_NOTFOUND = -1765328243 KRB5_CC_END = -1765328242 KRB5_CC_NOSUPP = -1765328137 KRB5_FCC_NOFILE = -1765328189 KRB5_FCC_INTERNAL = -1765328188 def make_uuid(): global next_uuid uuid = bytes(12) + struct.pack('>L', next_uuid) next_uuid = next_uuid + 1 return uuid class Cache(object): def __init__(self, name): self.name = name self.princ = None self.uuid = make_uuid() self.cred_uuids = [] self.creds = {} self.time_offset = 0 def get_cache(name): if name in caches: return caches[name] cache = Cache(name) caches[name] = cache cache_uuidmap[cache.uuid] = cache return cache def unmarshal_name(argbytes): offset = argbytes.find(b'\0') return argbytes[0:offset], argbytes[offset+1:] # Find the bounds of a marshalled principal, returning it and the # remainder of argbytes. def extract_princ(argbytes): ncomps, rlen = struct.unpack('>LL', argbytes[4:12]) pos = 12 + rlen for i in range(ncomps): clen, = struct.unpack('>L', argbytes[pos:pos+4]) pos += 4 + clen return argbytes[0:pos], argbytes[pos:] # Return true if the marshalled principals p1 and p2 name the same # principal. def princ_eq(p1, p2): # Ignore the name-types at bytes 0..3. The remaining bytes should # be identical if the principals are the same. return p1[4:] == p2[4:] def op_gen_new(argbytes): # Does not actually check for uniqueness. global next_unique name = b'unique' + str(next_unique).encode('ascii') next_unique += 1 return 0, name + b'\0' def op_initialize(argbytes): name, princ = unmarshal_name(argbytes) cache = get_cache(name) cache.princ = princ cache.cred_uuids = [] cache.creds = {} cache.time_offset = 0 return 0, b'' def op_destroy(argbytes): name, rest = unmarshal_name(argbytes) cache = get_cache(name) del cache_uuidmap[cache.uuid] del caches[name] return 0, b'' def op_store(argbytes): name, cred = unmarshal_name(argbytes) cache = get_cache(name) uuid = make_uuid() cache.creds[uuid] = cred cache.cred_uuids.append(uuid) return 0, b'' def op_retrieve(argbytes): name, rest = unmarshal_name(argbytes) # Ignore the flags at rest[0:4] and the header at rest[4:8]. # Assume there are client and server creds in the tag and match # only against them. cprinc, rest = extract_princ(rest[8:]) sprinc, rest = extract_princ(rest) cache = get_cache(name) for cred in (cache.creds[u] for u in cache.cred_uuids): cred_cprinc, rest = extract_princ(cred) cred_sprinc, rest = extract_princ(rest) if princ_eq(cred_cprinc, cprinc) and princ_eq(cred_sprinc, sprinc): return 0, cred return KRB5Errors.KRB5_CC_NOTFOUND, b'' def op_get_principal(argbytes): name, rest = unmarshal_name(argbytes) cache = get_cache(name) if cache.princ is None: return KRB5Errors.KRB5_FCC_NOFILE, b'' return 0, cache.princ + b'\0' def op_get_cred_uuid_list(argbytes): name, rest = unmarshal_name(argbytes) cache = get_cache(name) return 0, b''.join(cache.cred_uuids) def op_get_cred_by_uuid(argbytes): name, uuid = unmarshal_name(argbytes) cache = get_cache(name) if uuid not in cache.creds: return KRB5Errors.KRB5_CC_END, b'' return 0, cache.creds[uuid] def op_remove_cred(argbytes): return KRB5Errors.KRB5_CC_NOSUPP, b'' def op_get_cache_uuid_list(argbytes): return 0, b''.join(cache_uuidmap.keys()) def op_get_cache_by_uuid(argbytes): uuid = argbytes if uuid not in cache_uuidmap: return KRB5Errors.KRB5_CC_END, b'' return 0, cache_uuidmap[uuid].name + b'\0' def op_get_default_cache(argbytes): return 0, defname + b'\0' def op_set_default_cache(argbytes): global defname defname, rest = unmarshal_name(argbytes) return 0, b'' def op_get_kdc_offset(argbytes): name, rest = unmarshal_name(argbytes) cache = get_cache(name) return 0, struct.pack('>l', cache.time_offset) def op_set_kdc_offset(argbytes): name, obytes = unmarshal_name(argbytes) cache = get_cache(name) cache.time_offset, = struct.unpack('>l', obytes) return 0, b'' def op_get_cred_list(argbytes): name, rest = unmarshal_name(argbytes) cache = get_cache(name) creds = [cache.creds[u] for u in cache.cred_uuids] return 0, (struct.pack('>L', len(creds)) + b''.join(struct.pack('>L', len(c)) + c for c in creds)) def op_replace(argbytes): name, rest = unmarshal_name(argbytes) offset, = struct.unpack('>L', rest[0:4]) princ, rest = extract_princ(rest[4:]) ncreds, = struct.unpack('>L', rest[0:4]) rest = rest[4:] creds = [] for i in range(ncreds): len, = struct.unpack('>L', rest[0:4]) creds.append(rest[4:4+len]) rest = rest[4+len:] cache = get_cache(name) cache.princ = princ cache.cred_uuids = [] cache.creds = {} cache.time_offset = offset for i in range(ncreds): uuid = make_uuid() cache.creds[uuid] = creds[i] cache.cred_uuids.append(uuid) return 0, b'' ophandlers = { KCMOpcodes.GEN_NEW : op_gen_new, KCMOpcodes.INITIALIZE : op_initialize, KCMOpcodes.DESTROY : op_destroy, KCMOpcodes.STORE : op_store, KCMOpcodes.RETRIEVE : op_retrieve, KCMOpcodes.GET_PRINCIPAL : op_get_principal, KCMOpcodes.GET_CRED_UUID_LIST : op_get_cred_uuid_list, KCMOpcodes.GET_CRED_BY_UUID : op_get_cred_by_uuid, KCMOpcodes.REMOVE_CRED : op_remove_cred, KCMOpcodes.GET_CACHE_UUID_LIST : op_get_cache_uuid_list, KCMOpcodes.GET_CACHE_BY_UUID : op_get_cache_by_uuid, KCMOpcodes.GET_DEFAULT_CACHE : op_get_default_cache, KCMOpcodes.SET_DEFAULT_CACHE : op_set_default_cache, KCMOpcodes.GET_KDC_OFFSET : op_get_kdc_offset, KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset, KCMOpcodes.GET_CRED_LIST : op_get_cred_list, KCMOpcodes.REPLACE : op_replace } # Read and respond to a request from the socket s. def service_request(s): lenbytes = b'' while len(lenbytes) < 4: lenbytes += s.recv(4 - len(lenbytes)) if lenbytes == b'': return False reqlen, = struct.unpack('>L', lenbytes) req = b'' while len(req) < reqlen: req += s.recv(reqlen - len(req)) majver, minver, op = struct.unpack('>BBH', req[:4]) argbytes = req[4:] if op in ophandlers: code, payload = ophandlers[op](argbytes) else: code, payload = KRB5Errors.KRB5_FCC_INTERNAL, b'' # The KCM response is the code (4 bytes) and the response payload. # The Heimdal IPC response is the length of the KCM response (4 # bytes), a status code which is essentially always 0 (4 bytes), # and the KCM response. kcm_response = struct.pack('>l', code) + payload hipc_response = struct.pack('>LL', len(kcm_response), 0) + kcm_response s.sendall(hipc_response) return True parser = optparse.OptionParser() parser.add_option('-f', '--fallback', action='store_true', dest='fallback', default=False, help='Do not support RETRIEVE/GET_CRED_LIST/REPLACE') (options, args) = parser.parse_args() if options.fallback: del ophandlers[KCMOpcodes.RETRIEVE] del ophandlers[KCMOpcodes.GET_CRED_LIST] del ophandlers[KCMOpcodes.REPLACE] server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) server.bind(args[0]) server.listen(5) select_input = [server,] sys.stderr.write('starting...\n') sys.stderr.flush() while True: iready, oready, xready = select.select(select_input, [], []) for s in iready: if s == server: client, addr = server.accept() select_input.append(client) else: if not service_request(s): select_input.remove(s) s.close() krb5-1.22.1/src/tests/t_authdata.py0000664000175000017500000004041615051422640016767 0ustar ghudsonghudsonfrom k5test import * # Load the sample KDC authdata module. Allow renewable tickets. greet_path = os.path.join(buildtop, 'plugins', 'authdata', 'greet_server', 'greet_server.so') conf = {'realms': {'$realm': {'max_life': '20h', 'max_renewable_life': '20h'}}, 'plugins': {'kdcauthdata': {'module': 'greet:' + greet_path}}} realm = K5Realm(krb5_conf=conf) # With no requested authdata, we expect to see PAC (128) in an # if-relevant container and the greet authdata in a kdc-issued # container. mark('baseline authdata') out = realm.run(['./adata', realm.host_princ]) if '?128: [6, 7, 10, 16, 19]' not in out or '^-42: Hello' not in out: fail('expected authdata not seen for basic request') # Requested authdata is copied into the ticket, with KDC-only types # filtered out. (128 is win2k-pac, which should be filtered.) mark('request authdata') out = realm.run(['./adata', realm.host_princ, '-5', 'test1', '?-6', 'test2', '128', 'fakepac', '?128', 'ifrelfakepac', '^-8', 'fakekdcissued', '?^-8', 'ifrelfakekdcissued']) if ' -5: test1' not in out or '?-6: test2' not in out: fail('expected authdata not seen for request with authdata') if 'fake' in out: fail('KDC-only authdata not filtered for request with authdata') mark('AD-MANDATORY-FOR-KDC') realm.run(['./adata', realm.host_princ, '!-1', 'mandatoryforkdc'], expected_code=1, expected_msg='KDC policy rejects request') # The no_auth_data_required server flag should suppress the PAC, but # not module or request authdata. mark('no_auth_data_required server flag') realm.run([kadminl, 'ank', '-randkey', '+no_auth_data_required', 'noauth']) realm.extract_keytab('noauth', realm.keytab) out = realm.run(['./adata', 'noauth', '-2', 'test']) if '^-42: Hello' not in out or ' -2: test' not in out: fail('expected authdata not seen for no_auth_data_required request') if '128: ' in out: fail('PAC authdata seen for no_auth_data_required request') # Cross-realm TGT requests should not suppress PAC or request # authdata. mark('cross-realm') realm.addprinc('krbtgt/XREALM') realm.extract_keytab('krbtgt/XREALM', realm.keytab) out = realm.run(['./adata', 'krbtgt/XREALM', '-3', 'test']) if '128:' not in out or '^-42: Hello' not in out or ' -3: test' not in out: fail('expected authdata not seen for cross-realm TGT request') mark('pac_privsvr_enctype') # Change the privsvr enctype and make sure we can still verify the PAC # on a service ticket in a TGS request. realm.run([kadminl, 'setstr', realm.host_princ, 'pac_privsvr_enctype', 'aes128-sha1']) realm.kinit(realm.user_princ, password('user'), ['-S', realm.host_princ, '-r', '1h']) realm.kinit(realm.user_princ, None, ['-S', realm.host_princ, '-R']) # Remove the attribute and make sure the previously-issued service # ticket PAC no longer verifies. realm.run([kadminl, 'delstr', realm.host_princ, 'pac_privsvr_enctype']) realm.kinit(realm.user_princ, None, ['-S', realm.host_princ, '-R'], expected_code=1, expected_msg='Message stream modified') realm.stop() if not pkinit_enabled: skipped('anonymous ticket authdata tests', 'PKINIT not built') else: # Set up a realm with PKINIT support and get anonymous tickets. realm = K5Realm(krb5_conf=conf, get_creds=False, pkinit=True) realm.addprinc('WELLKNOWN/ANONYMOUS') realm.kinit('@%s' % realm.realm, flags=['-n']) # PAC and module authdata should be suppressed for anonymous # tickets, but not request authdata. mark('anonymous') out = realm.run(['./adata', realm.host_princ, '-4', 'test']) if ' -4: test' not in out: fail('expected authdata not seen for anonymous request') if '128: ' in out or '-42: ' in out: fail('PAC or greet authdata seen for anonymous request') realm.stop() # Test authentication indicators. Load the test preauth module so we # can control the indicators asserted. testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') krb5conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}}} realm, realm2 = cross_realms(2, args=({'realm': 'LOCAL'}, {'realm': 'FOREIGN'}), krb5_conf=krb5conf, get_creds=False) realm.run([kadminl, 'modprinc', '+requires_preauth', '-maxrenewlife', '2 days', realm.user_princ]) realm.run([kadminl, 'modprinc', '-maxrenewlife', '2 days', realm.host_princ]) realm.run([kadminl, 'modprinc', '-maxrenewlife', '2 days', realm.krbtgt_princ]) realm.extract_keytab(realm.krbtgt_princ, realm.keytab) realm.extract_keytab(realm.host_princ, realm.keytab) realm.extract_keytab('krbtgt/FOREIGN', realm.keytab) realm2.extract_keytab(realm2.krbtgt_princ, realm.keytab) realm2.extract_keytab(realm2.host_princ, realm.keytab) realm2.extract_keytab('krbtgt/LOCAL', realm.keytab) # AS request to local-realm service mark('AS-REQ to local service auth indicator') realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl', '-r', '2d', '-S', realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # Ticket modification request mark('ticket modification auth indicator') realm.kinit(realm.user_princ, None, ['-R', '-S', realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # AS request to cross TGT mark('AS-REQ to cross TGT auth indicator') realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl', '-S', 'krbtgt/FOREIGN']) realm.run(['./adata', 'krbtgt/FOREIGN'], expected_msg='+97: [indcl]') # Multiple indicators mark('AS multiple indicators') realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl indcl2 indcl3']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indcl, indcl2, indcl3]') # AS request to local TGT (resulting creds are used for TGS tests) mark('AS-REQ to local TGT auth indicator') realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=indcl']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indcl]') # Local TGS request for local realm service mark('TGS-REQ to local service auth indicator') realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # Local TGS request for cross TGT service mark('TGS-REQ to cross TGT auth indicator') realm.run(['./adata', 'krbtgt/FOREIGN'], expected_msg='+97: [indcl]') # We don't yet have support for passing auth indicators across realms, # so just verify that indicators don't survive cross-realm requests. mark('TGS-REQ to foreign service auth indicator') out = realm.run(['./adata', realm2.krbtgt_princ]) if '97:' in out: fail('auth-indicator seen in cross TGT request to local TGT') out = realm.run(['./adata', 'krbtgt/LOCAL@FOREIGN']) if '97:' in out: fail('auth-indicator seen in cross TGT request to cross TGT') out = realm.run(['./adata', realm2.host_princ]) if '97:' in out: fail('auth-indicator seen in cross TGT request to service') # Test that the CAMMAC signature still works during a krbtgt rollover. mark('CAMMAC signature across krbtgt rollover') realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.krbtgt_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indcl]') # Test indicator enforcement. mark('auth indicator enforcement') realm.addprinc('restricted') realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'superstrong']) realm.kinit(realm.user_princ, password('user'), ['-S', 'restricted'], expected_code=1, expected_msg='KDC policy rejects request') realm.run([kvno, 'restricted'], expected_code=1, expected_msg='KDC policy rejects request') realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'indcl']) realm.run([kvno, 'restricted']) realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=ind1 ind2']) realm.run([kvno, 'restricted'], expected_code=1) realm.run([kadminl, 'setstr', 'restricted', 'require_auth', 'a b c ind2']) realm.run([kvno, 'restricted']) # Regression test for one manifestation of #8139: ensure that # forwarded TGTs obtained across a TGT re-key still work when the # preferred krbtgt enctype changes. mark('#8139 regression test') realm.kinit(realm.user_princ, password('user'), ['-f']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'des3-cbc-sha1', realm.krbtgt_princ]) realm.run(['./forward']) realm.run([kvno, realm.host_princ]) # Repeat the above test using a renewed TGT. mark('#8139 regression test (renewed TGT)') realm.kinit(realm.user_princ, password('user'), ['-r', '2d']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes128-cts', realm.krbtgt_princ]) realm.kinit(realm.user_princ, None, ['-R']) realm.run([kvno, realm.host_princ]) realm.stop() realm2.stop() # Load the test KDB module to allow successful S4U2Proxy # auth-indicator requests and to detect whether replaced_reply_key is # set. testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, 'krbtgt/FOREIGN': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'user2': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'rservice': {'keys': 'aes128-cts', 'strings': 'require_auth:strong'}, 'service/1': {'keys': 'aes128-cts', 'flags': '+ok_to_auth_as_delegate'}, 'service/2': {'keys': 'aes128-cts'}, 'noauthdata': {'keys': 'aes128-cts', 'flags': '+no_auth_data_required'}} kdcconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': testprincs, 'delegation': {'service/1': 'service/2'}}}} realm = K5Realm(krb5_conf=krb5conf, kdc_conf=kdcconf, create_kdb=False, pkinit=True) usercache = 'FILE:' + os.path.join(realm.testdir, 'usercache') realm.extract_keytab(realm.krbtgt_princ, realm.keytab) realm.extract_keytab('krbtgt/FOREIGN', realm.keytab) realm.extract_keytab(realm.user_princ, realm.keytab) realm.extract_keytab('ruser', realm.keytab) realm.extract_keytab('service/1', realm.keytab) realm.extract_keytab('service/2', realm.keytab) realm.extract_keytab('noauthdata', realm.keytab) realm.start_kdc() if not pkinit_enabled: skipped('replaced_reply_key test', 'PKINIT not built') else: # Check that replaced_reply_key is set in issue_pac() when PKINIT # is used. The test KDB module will indicate this by including a # fake PAC_CREDENTIAL_INFO(2) buffer in the PAC. mark('PKINIT (replaced_reply_key set)') realm.pkinit(realm.user_princ) realm.run(['./adata', realm.krbtgt_princ], expected_msg='?128: [1, 2, 6, 7, 10]') # S4U2Self (should have no indicators since client did not authenticate) mark('S4U2Self (no auth indicators expected)') realm.kinit('service/1', None, ['-k', '-f', '-X', 'indicators=inds1']) realm.run([kvno, '-U', 'user', 'service/1']) out = realm.run(['./adata', '-p', realm.user_princ, 'service/1']) if '97:' in out: fail('auth-indicator present in S4U2Self response') # Get another S4U2Self ticket with requested authdata. realm.run(['./s4u2self', 'user', 'service/1', '-', '-2', 'self_ad']) realm.run(['./adata', '-p', realm.user_princ, 'service/1', '-2', 'self_ad'], expected_msg=' -2: self_ad') # S4U2Proxy (indicators should come from evidence ticket, not TGT) mark('S4U2Proxy (auth indicators from evidence ticket expected)') realm.kinit(realm.user_princ, None, ['-k', '-f', '-X', 'indicators=indcl', '-S', 'service/1', '-c', usercache]) realm.run(['./s4u2proxy', usercache, 'service/2']) out = realm.run(['./adata', '-p', realm.user_princ, 'service/2']) if '+97: [indcl]' not in out or '[inds1]' in out: fail('correct auth-indicator not seen for S4U2Proxy req') # Make sure a PAC with an S4U_DELEGATION_INFO(11) buffer is included. if '?128: [1, 6, 7, 10, 11, 16, 19]' not in out: fail('PAC with delegation info not seen for S4U2Proxy req') # Get another S4U2Proxy ticket including request-authdata. realm.run(['./s4u2proxy', usercache, 'service/2', '-2', 'proxy_ad']) realm.run(['./adata', '-p', realm.user_princ, 'service/2', '-2', 'proxy_ad'], expected_msg=' -2: proxy_ad') # Get an S4U2Proxy ticket using an evidence ticket obtained by S4U2Self, # with request authdata in both steps. realm.run(['./s4u2self', 'user2', 'service/1', usercache, '-2', 'self_ad']) realm.run(['./s4u2proxy', usercache, 'service/2', '-2', 'proxy_ad']) out = realm.run(['./adata', '-p', 'user2', 'service/2', '-2', 'proxy_ad']) if ' -2: self_ad' not in out or ' -2: proxy_ad' not in out: fail('expected authdata not seen in S4U2Proxy ticket') # Test alteration of auth indicators by KDB module (AS and TGS). realm.kinit(realm.user_princ, None, ['-k', '-X', 'indicators=dummy dbincr1']) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [dbincr2]') realm.run(['./adata', 'service/1'], expected_msg='+97: [dbincr3]') realm.kinit(realm.user_princ, None, ['-k', '-X', 'indicators=strong', '-S', 'rservice']) # Test enforcement of altered indicators during AS request. realm.kinit(realm.user_princ, None, ['-k', '-X', 'indicators=strong dbincr1', '-S', 'rservice'], expected_code=1) # Test that the PAC is suppressed in an AS request by a negative PAC # request. mark('AS-REQ PAC client supression') realm.kinit(realm.user_princ, None, ['-k', '--no-request-pac']) out = realm.run(['./adata', realm.krbtgt_princ]) if '128:' in out: fail('PAC not suppressed by --no-request-pac') mark('S4U2Proxy with a foreign client') a_princs = {'krbtgt/A': {'keys': 'aes128-cts'}, 'krbtgt/B': {'keys': 'aes128-cts'}, 'impersonator': {'keys': 'aes128-cts'}, 'impersonator2': {'keys': 'aes128-cts'}, 'resource': {'keys': 'aes128-cts'}} a_kconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'delegation': {'impersonator' : 'resource'}, 'princs': a_princs, 'alias': {'service/rb.b': '@B'}}}} b_princs = {'krbtgt/B': {'keys': 'aes128-cts'}, 'krbtgt/A': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'rb': {'keys': 'aes128-cts'}} b_kconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': b_princs, 'rbcd': {'rb@B': 'impersonator2@A'}, 'alias': {'service/rb.b': 'rb', 'impersonator2@A': '@A'}}}} ra, rb = cross_realms(2, xtgts=(), args=({'realm': 'A', 'kdc_conf': a_kconf}, {'realm': 'B', 'kdc_conf': b_kconf}), create_kdb=False) ra.start_kdc() rb.start_kdc() ra.extract_keytab('impersonator@A', ra.keytab) ra.extract_keytab('impersonator2@A', ra.keytab) rb.extract_keytab('user@B', rb.keytab) usercache = 'FILE:' + os.path.join(rb.testdir, 'usercache') rb.kinit(rb.user_princ, None, ['-k', '-f', '-c', usercache]) rb.run([kvno, '-C', 'impersonator@A', '-c', usercache]) ra.kinit('impersonator@A', None, ['-f', '-k', '-t', ra.keytab]) ra.run(['./s4u2proxy', usercache, 'resource@A']) mark('Cross realm S4U authdata tests') ra.kinit('impersonator2@A', None, ['-f', '-k', '-t', ra.keytab]) ra.run(['./s4u2self', rb.user_princ, 'impersonator2@A', usercache, '-2', 'cross_s4u_self_ad']) out = ra.run(['./adata', '-c', usercache, '-p', rb.user_princ, 'impersonator2@A', '-2', 'cross_s4u_self_ad']) if out.count(' -2: cross_s4u_self_ad') != 1: fail('expected one cross_s4u_self_ad, got: %s' % count) ra.run(['./s4u2proxy', usercache, 'service/rb.b', '-2', 'cross_s4u_proxy_ad']) rb.extract_keytab('service/rb.b', ra.keytab) out = ra.run(['./adata', '-p', rb.user_princ, 'service/rb.b', '-2', 'cross_s4u_proxy_ad']) if out.count(' -2: cross_s4u_self_ad') != 1: fail('expected one cross_s4u_self_ad, got: %s' % count) if out.count(' -2: cross_s4u_proxy_ad') != 1: fail('expected one cross_s4u_proxy_ad, got: %s' % count) ra.stop() rb.stop() success('Authorization data tests') krb5-1.22.1/src/tests/Makefile.in0000664000175000017500000001773315051422640016352 0ustar ghudsonghudsonmydir=tests BUILDTOP=$(REL).. SUBDIRS = asn.1 create hammer verify gssapi shlib gss-threads misc threads \ @fuzz_dir@ RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \ GSS_MECH_CONFIG=mech.conf LC_ALL=C $(VALGRIND) OBJS= adata.o conccache.o etinfo.o forward.o gcred.o hist.o hooks.o hrealm.o \ icinterleave.o icred.o kdbtest.o localauth.o plugorder.o rdreq.o \ replay.o responder.o s2p.o s4u2self.o s4u2proxy.o t_inetd.o \ unlockiter.o EXTRADEPSRCS= adata.c conccache.c etinfo.c forward.c gcred.c hist.c hooks.c \ hrealm.c icinterleave.c icred.c kdbtest.c localauth.c plugorder.c \ rdreq.c replay.c responder.c s2p.c s4u2self.c s4u2proxy.c t_inetd.c \ unlockiter.c TEST_DB = ./testdb TEST_REALM = FOO.TEST.REALM TEST_MKEY = footes TEST_NUM = 65 TEST_DEPTH = 5 TEST_PREFIX = "foo bar" KADMIN_OPTS= -d $(TEST_DB) -r $(TEST_REALM) -P $(TEST_MKEY) KTEST_OPTS= $(KADMIN_OPTS) -p $(TEST_PREFIX) -n $(TEST_NUM) -D $(TEST_DEPTH) adata: adata.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ adata.o $(KRB5_BASE_LIBS) conccache: conccache.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ conccache.o $(KRB5_BASE_LIBS) etinfo: etinfo.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ etinfo.o $(KRB5_BASE_LIBS) forward: forward.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ forward.o $(KRB5_BASE_LIBS) gcred: gcred.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ gcred.o $(KRB5_BASE_LIBS) hist: hist.o $(KDB5_DEPLIBS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ hist.o $(KDB5_LIBS) $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) hooks: hooks.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ hooks.o $(KRB5_BASE_LIBS) hrealm: hrealm.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ hrealm.o $(KRB5_BASE_LIBS) icinterleave: icinterleave.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ icinterleave.o $(KRB5_BASE_LIBS) icred: icred.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ icred.o $(KRB5_BASE_LIBS) kdbtest: kdbtest.o $(KDB5_DEPLIBS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ kdbtest.o $(KDB5_LIBS) $(KADMSRV_LIBS) \ $(KRB5_BASE_LIBS) localauth: localauth.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ localauth.o $(KRB5_BASE_LIBS) plugorder: plugorder.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ plugorder.o $(KRB5_BASE_LIBS) rdreq: rdreq.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ rdreq.o $(KRB5_BASE_LIBS) replay: replay.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ replay.o $(KRB5_BASE_LIBS) responder: responder.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ responder.o $(KRB5_BASE_LIBS) s2p: s2p.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ s2p.o $(KRB5_BASE_LIBS) s4u2self: s4u2self.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ s4u2self.o $(KRB5_BASE_LIBS) s4u2proxy: s4u2proxy.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ s4u2proxy.o $(KRB5_BASE_LIBS) t_inetd: t_inetd.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_inetd.o $(LIBS) $(KRB5_BASE_LIBS) unlockiter: unlockiter.o $(KDB5_DEPLIBS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ unlockiter.o $(KDB5_LIBS) $(KADMSRV_LIBS) \ $(KRB5_BASE_LIBS) all-unix: t_inetd check-unix: kdb_check kdc.conf: Makefile rm -rf kdc.conf @echo "[realms]" > kdc.conf @echo "$(TEST_REALM) = {" >> kdc.conf @echo " key_stash_file = `pwd`/stash_file" >> kdc.conf @echo "}" >> kdc.conf krb5.conf: Makefile cat $(top_srcdir)/config-files/krb5.conf > krb5.new echo "[dbmodules]" >> krb5.new echo " db_module_dir = `pwd`/../plugins/kdb" >> krb5.new mv krb5.new krb5.conf kdb_check: kdc.conf krb5.conf $(RM) $(TEST_DB)* $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) create -W $(RUN_DB_TEST) ../tests/create/kdb5_mkdums $(KTEST_OPTS) $(RUN_DB_TEST) ../tests/verify/kdb5_verify $(KTEST_OPTS) $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump $(TEST_DB).dump $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f @echo "====> NOTE!" @echo "The following 'create' command is needed due to a change" @echo "in functionality caused by DAL integration. See ticket 3973." @echo ==== $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) create -W $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) load $(TEST_DB).dump $(RUN_DB_TEST) ../tests/verify/kdb5_verify $(KTEST_OPTS) $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) dump $(TEST_DB).dump2 sort $(TEST_DB).dump > $(TEST_DB).sort sort $(TEST_DB).dump2 > $(TEST_DB).sort2 cmp $(TEST_DB).sort $(TEST_DB).sort2 $(RUN_DB_TEST) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f $(RM) $(TEST_DB)* stash_file check-pytests: adata conccache etinfo forward gcred hist hooks hrealm check-pytests: icinterleave icred kdbtest localauth plugorder rdreq replay check-pytests: responder s2p s4u2proxy unlockiter s4u2self $(RUNPYTEST) $(srcdir)/t_general.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_hooks.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_dump.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_iprop.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kprop.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_policy.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_changepw.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_pkinit.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_otp.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_spake.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_localauth.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kadm5_hook.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kadm5_auth.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_pwqual.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_hostrealm.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kdb_locking.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_keyrollover.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_renew.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_renprinc.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_ccache.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_stringattr.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_sesskeynego.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_crossrealm.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_referral.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_skew.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_keytab.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kadmin.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kadmin_acl.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kadmin_parsing.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kdb.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_keydata.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_mkey.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_rdreq.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_sn2princ.py $(PYTESTFLAGS) $(OFFLINE) $(RUNPYTEST) $(srcdir)/t_cve-2012-1014.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_cve-2012-1015.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_cve-2013-1416.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_cve-2013-1417.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_cve-2021-36222.py $(PYTESTFLAGS) $(RM) au.log $(RUNPYTEST) $(srcdir)/t_audit.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/jsonwalker.py -d $(srcdir)/au_dict.json \ -i au.log $(RUNPYTEST) $(srcdir)/t_salt.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_etype_info.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_bogus_kdc_req.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kdc_log.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_proxy.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_unlockiter.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_errmsg.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_authdata.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_preauth.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_princflags.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_y2038.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kdcpolicy.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_u2u.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_kdcoptions.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_replay.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_sendto_kdc.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_alias.py $(PYTESTFLAGS) clean: $(RM) adata conccache etinfo forward gcred hist hooks hrealm $(RM) icinterleave icred kdbtest localauth plugorder rdreq replay $(RM) responder s2p s4u2proxy s4u2self t_inetd unlockiter $(RM) krb5.conf kdc.conf $(RM) -rf kdc_realm/sandbox ldap $(RM) au.log krb5-1.22.1/src/tests/t_alias.py0000775000175000017500000001076515051422640016274 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(create_host=False) mark('getprinc') realm.addprinc('canon') realm.run([kadminl, 'alias', 'alias', 'canon@KRBTEST.COM']) realm.run([kadminl, 'getprinc', 'alias'], expected_msg='Principal: canon@KRBTEST.COM') mark('delprinc') realm.run([kadminl, 'delprinc', 'alias']) realm.run([kadminl, 'getprinc', 'alias'], expected_code=1, expected_msg='does not exist') realm.run([kadminl, 'getprinc', 'canon'], expected_msg=': canon@KRBTEST.COM') mark('no specified realm') realm.run([kadminl, 'alias', 'alias', 'canon']) realm.run([kadminl, 'getprinc', 'alias'], expected_msg=': canon@KRBTEST.COM') mark('cross-realm') realm.run([kadminl, 'alias', 'x', 'y@OTHER.REALM'], expected_code=1, expected_msg='Alias target must be within the same realm') mark('alias as service principal') realm.extract_keytab('alias', realm.keytab) realm.run([kvno, 'alias']) realm.klist('user@KRBTEST.COM', 'alias@KRBTEST.COM') mark('alias as client principal') realm.kinit('alias', flags=['-k']) realm.klist('alias@KRBTEST.COM') realm.kinit('alias', flags=['-k', '-C']) realm.klist('canon@KRBTEST.COM') mark('chain') realm.run([kadminl, 'alias', 'a1', 'canon']) realm.run([kadminl, 'alias', 'a2', 'a1']) realm.run([kadminl, 'alias', 'a3', 'a2']) realm.run([kadminl, 'alias', 'a4', 'a3']) realm.run([kadminl, 'alias', 'a5', 'a4']) realm.run([kadminl, 'alias', 'a6', 'a5']) realm.run([kadminl, 'alias', 'a7', 'a6']) realm.run([kadminl, 'alias', 'a8', 'a7']) realm.run([kadminl, 'alias', 'a9', 'a8']) realm.run([kadminl, 'alias', 'a10', 'a9']) realm.run([kadminl, 'alias', 'a11', 'a10']) realm.run([kvno, 'a1']) realm.run([kvno, 'a2']) realm.run([kvno, 'a3']) realm.run([kvno, 'a4']) realm.run([kvno, 'a5']) realm.run([kvno, 'a6']) realm.run([kvno, 'a7']) realm.run([kvno, 'a8']) realm.run([kvno, 'a9']) realm.run([kvno, 'a10']) realm.run([kvno, 'a11'], expected_code=1, expected_msg='Server a11@KRBTEST.COM not found in Kerberos database') mark('circular chain') realm.run([kadminl, 'alias', 'selfalias', 'selfalias']) realm.run([kvno, 'selfalias'], expected_code=1, expected_msg='Server selfalias@KRBTEST.COM not found') mark('blocking creations') realm.run([kadminl, 'addprinc', '-nokey', 'alias'], expected_code=1, expected_msg='already exists') realm.run([kadminl, 'alias', 'alias', 'canon'], expected_code=1, expected_msg='already exists') realm.run([kadminl, 'renprinc', 'user', 'alias'], expected_code=1, expected_msg='already exists') # Non-resolving aliases being overwritable is emergent behavior; # change the tests if the behavior changes. mark('not blocking creations') realm.run([kadminl, 'alias', 'xa1', 'x']) realm.run([kadminl, 'alias', 'xa2', 'x']) realm.run([kadminl, 'alias', 'xa3', 'x']) realm.addprinc('xa1') realm.run([kadminl, 'getprinc', 'xa1'], expected_msg=': xa1@KRBTEST.COM') realm.run([kadminl, 'alias', 'xa2', 'canon']) realm.run([kadminl, 'getprinc', 'xa2'], expected_msg=': canon@KRBTEST.COM') realm.run([kadminl, 'renprinc', 'xa1', 'xa3']) realm.run([kadminl, 'getprinc', 'xa3'], expected_msg=': xa3@KRBTEST.COM') mark('renprinc') realm.run([kadminl, 'renprinc', 'alias', 'nalias'], expected_code=1, expected_msg='Operation unsupported on alias principal name') mark('modprinc') realm.run([kadminl, 'modprinc', '+preauth', 'alias']) realm.run([kadminl, 'getprinc', 'canon'], expected_msg='REQUIRES_PRE_AUTH') mark('cpw') realm.run([kadminl, 'cpw', '-pw', 'pw', 'alias']) realm.run([kadminl, 'getprinc', 'canon'], expected_msg='vno 2,') realm.run([kadminl, 'cpw', '-e', 'aes256-cts', '-pw', 'pw', 'alias']) realm.run([kadminl, 'getprinc', 'canon'], expected_msg='vno 3,') realm.run([kadminl, 'cpw', '-randkey', 'alias']) realm.run([kadminl, 'getprinc', 'canon'], expected_msg='vno 4,') realm.run([kadminl, 'cpw', '-e', 'aes256-cts', '-randkey', 'alias']) realm.run([kadminl, 'getprinc', 'canon'], expected_msg='vno 5,') mark('listprincs') realm.run([kadminl, 'listprincs'], expected_msg='alias@KRBTEST.COM') mark('purgekeys') realm.run([kadminl, 'purgekeys', '-all', 'alias']) realm.run([kadminl, 'getprinc', 'canon'], expected_msg='Number of keys: 0') mark('setstr') realm.run([kadminl, 'setstr', 'alias', 'key', 'value']) realm.run([kadminl, 'getstrs', 'canon'], expected_msg='key: value') mark('getstrs') realm.run([kadminl, 'getstrs', 'alias'], expected_msg='key: value') mark('delstr') realm.run([kadminl, 'delstr', 'alias', 'key']) realm.run([kadminl, 'getstrs', 'canon'], expected_msg='(No string attributes.)') success('alias tests') krb5-1.22.1/src/tests/t_cve-2013-1417.py0000775000175000017500000000051715051422640016727 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(realm='TEST') # CVE-2013-1417 KDC dereferences null pointer realm.kinit(realm.user_princ, password('user')) realm.run([kvno, '-S', 'host', 'example.com'], expected_code=1) # Make sure KDC is still running. realm.kinit(realm.user_princ, password('user')) success('CVE-2013-1417 regression test') krb5-1.22.1/src/tests/t_sesskeynego.py0000775000175000017500000001044415051422640017534 0ustar ghudsonghudsonfrom k5test import * import re # Run "kvno server" with a fresh set of client tickets, then check that the # enctypes in the service ticket match the expected values. etypes_re = re.compile(r'server@[^\n]+\n\tEtype \(skey, tkt\): ' r'([^,]+), ([^\s]+)') def test_kvno(realm, expected_skey, expected_tkt): realm.kinit(realm.user_princ, password('user')) realm.run([kvno, 'server']) output = realm.run([klist, '-e']) m = etypes_re.search(output) if not m: fail('could not parse etypes from klist -e output') skey, tkt = m.groups() if skey != expected_skey: fail('got session key type %s, expected %s' % (skey, expected_skey)) if tkt != expected_tkt: fail('got ticket key type %s, expected %s' % (tkt, expected_tkt)) conf1 = {'libdefaults': {'default_tgs_enctypes': 'aes128-cts,aes256-cts'}} conf2 = {'libdefaults': {'default_tgs_enctypes': 'aes256-cts,aes128-cts'}} conf3 = {'libdefaults': { 'allow_weak_crypto': 'true', 'default_tkt_enctypes': 'aes128-cts', 'default_tgs_enctypes': 'rc4-hmac,aes128-cts'}} conf4 = {'libdefaults': {'permitted_enctypes': 'aes256-cts'}} conf5 = {'libdefaults': {'allow_rc4': 'true'}} conf6 = {'libdefaults': {'allow_des3': 'true'}} # Test with client request and session_enctypes preferring aes128, but # aes256 long-term key. realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'aes128-cts,aes256-cts']) test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96') realm.stop() # Second go, almost same as first, but resulting session key must be aes256 # because of the difference in default_tgs_enctypes order. This tests that # session_enctypes doesn't change the order in which we negotiate. realm = K5Realm(krb5_conf=conf2, create_host=False, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'aes128-cts,aes256-cts']) test_kvno(realm, 'aes256-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96') realm.stop() # Next we use conf3 and try various things. realm = K5Realm(krb5_conf=conf3, create_host=False, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts:normal', 'server']) # 3a: Negotiate aes128 session key when principal only has aes256 long-term. realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'aes128-cts,aes256-cts']) test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96') # 3b: Skip RC4 (as the KDC does not allow it for session keys by # default) and negotiate aes128-cts session key, with only an aes256 # long-term service key. realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac,aes128-cts,aes256-cts']) test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96') realm.stop() # 4: Check that permitted_enctypes is a default for session key enctypes. realm = K5Realm(krb5_conf=conf4, create_host=False, get_creds=False) realm.kinit(realm.user_princ, password('user')) realm.run([kvno, 'user'], expected_trace=('etypes requested in TGS request: aes256-cts',)) realm.stop() # 5: allow_rc4 permits negotiation of rc4-hmac session key. realm = K5Realm(krb5_conf=conf5, create_host=False, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'rc4-hmac']) test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96') realm.stop() # 6: allow_des3 permits negotiation of des3-cbc-sha1 session key. realm = K5Realm(krb5_conf=conf6, create_host=False, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) realm.run([kadminl, 'setstr', 'server', 'session_enctypes', 'des3-cbc-sha1']) test_kvno(realm, 'DEPRECATED:des3-cbc-sha1', 'aes256-cts-hmac-sha1-96') realm.stop() # 7: default config negotiates aes256-sha1 session key for RC4-only service. realm = K5Realm(create_host=False, get_creds=False) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'rc4-hmac', 'server']) test_kvno(realm, 'aes256-cts-hmac-sha1-96', 'DEPRECATED:arcfour-hmac') realm.stop() success('sesskeynego') krb5-1.22.1/src/tests/t_pwqual.py0000775000175000017500000000604215051422640016505 0ustar ghudsonghudsonfrom k5test import * plugin = os.path.join(buildtop, "plugins", "pwqual", "test", "pwqual_test.so") dictfile = os.path.join(os.getcwd(), 'testdir', 'dict') pconf = {'plugins': {'pwqual': {'module': 'combo:' + plugin}}} dconf = {'realms': {'$realm': {'dict_file': dictfile}}} realm = K5Realm(krb5_conf=pconf, kdc_conf=dconf, create_user=False, create_host=False) # Write a short dictionary file. f = open(dictfile, 'w') f.write('birds\nbees\napples\noranges\n') f.close() realm.run([kadminl, 'addpol', 'pol']) mark('pwqual modules') # The built-in "empty" module rejects empty passwords even without a policy. realm.run([kadminl, 'addprinc', '-pw', '', 'p1'], expected_code=1, expected_msg='Empty passwords are not allowed') # The built-in "dict" module rejects dictionary words, but only with a policy. realm.run([kadminl, 'addprinc', '-pw', 'birds', 'p2']) realm.run([kadminl, 'addprinc', '-pw', 'birds', '-policy', 'pol', 'p3'], expected_code=1, expected_msg='Password is in the password dictionary') # The built-in "princ" module rejects principal components, only with a policy. realm.run([kadminl, 'addprinc', '-pw', 'p4', 'p4']) realm.run([kadminl, 'addprinc', '-pw', 'p5', '-policy', 'pol', 'p5'], expected_code=1, expected_msg='Password may not match principal name') # The dynamic "combo" module rejects pairs of dictionary words. realm.run([kadminl, 'addprinc', '-pw', 'birdsoranges', 'p6'], expected_code=1, expected_msg='Password may not be a pair of dictionary words') # These plugin ordering tests aren't specifically related to the # password quality interface, but are convenient to put here. mark('plugin module order') def test_order(realm, testname, conf, expected): conf = {'plugins': {'pwqual': conf}} env = realm.special_env(testname, False, krb5_conf=conf) out = realm.run(['./plugorder'], env=env) if out.split() != expected: fail('order test: ' + testname) realm.stop() realm = K5Realm(create_kdb=False) # Check the test harness with no special configuration. test_order(realm, 'noconf', {}, ['blt1', 'blt2', 'blt3']) # Test the basic order: dynamic modules, then built-in modules, each # in registration order. conf = {'module': ['dyn3:' + plugin, 'dyn1:' + plugin, 'dyn2:' + plugin]} test_order(realm, 'basic', conf, ['dyn3', 'dyn1', 'dyn2', 'blt1', 'blt2', 'blt3']) # Disabling modules should not affect the order of other modules. conf['disable'] = ['dyn1', 'blt3'] test_order(realm, 'disable', conf, ['dyn3', 'dyn2', 'blt1', 'blt2']) # enable_only should reorder the modules, but can't resurrect disabled # modules or create ones from thin air. conf['enable_only'] = ['dyn2', 'blt3', 'blt2', 'dyn1', 'dyn3', 'xxx'] test_order(realm, 'enable_only', conf, ['dyn2', 'blt2', 'dyn3']) # Duplicate modules should be pruned by preferring earlier entries. conf = {'module': ['dyn3:' + plugin, 'dyn1:' + plugin, 'dyn3:' + plugin]} test_order(realm, 'duplicate', conf, ['dyn3', 'dyn1', 'blt1', 'blt2', 'blt3']) success('Password quality interface tests') krb5-1.22.1/src/tests/t_localauth.py0000775000175000017500000001565715051422640017164 0ustar ghudsonghudsonfrom k5test import * # Unfortunately, we can't reliably test the k5login module. We can control # the directory where k5login files are read, but we can't suppress the UID # validity check, which might fail in some filesystems for a .k5login file # we create. conf = {'plugins': {'localauth': { 'disable': 'k5login'}}} realm = K5Realm(create_kdb=False, krb5_conf=conf) def test_an2ln(env, aname, result, msg): out = realm.run(['./localauth', aname], env=env) if out != result + '\n': fail(msg) def test_an2ln_err(env, aname, err, msg): realm.run(['./localauth', aname], env=env, expected_code=1, expected_msg=err) def test_userok(env, aname, lname, ok, msg): out = realm.run(['./localauth', aname, lname], env=env) if ((ok and out != 'yes\n') or (not ok and out != 'no\n')): fail(msg) # The default an2ln method works only in the default realm, and works # for a single-component principal or a two-component principal where # the second component is the default realm. mark('default') test_an2ln(None, 'user@KRBTEST.COM', 'user', 'default rule 1') test_an2ln(None, 'user/KRBTEST.COM@KRBTEST.COM', 'user', 'default rule 2') test_an2ln_err(None, 'user/KRBTEST.COM/x@KRBTEST.COM', 'No translation', 'default rule (3)') test_an2ln_err(None, 'user/X@KRBTEST.COM', 'No translation', 'default rule comp mismatch') test_an2ln_err(None, 'user@X', 'No translation', 'default rule realm mismatch') # auth_to_local_names matches ignore the realm but are case-sensitive. mark('auth_to_local_names') conf_names1 = {'realms': {'$realm': {'auth_to_local_names': {'user': 'abcd'}}}} names1 = realm.special_env('names1', False, conf_names1) test_an2ln(names1, 'user@KRBTEST.COM', 'abcd', 'auth_to_local_names match') test_an2ln(names1, 'user@X', 'abcd', 'auth_to_local_names out-of-realm match') test_an2ln(names1, 'x@KRBTEST.COM', 'x', 'auth_to_local_names mismatch') test_an2ln(names1, 'User@KRBTEST.COM', 'User', 'auth_to_local_names case') # auth_to_local_names values must be in the default realm's section. conf_names2 = {'realms': {'X': {'auth_to_local_names': {'user': 'abcd'}}}} names2 = realm.special_env('names2', False, conf_names2) test_an2ln_err(names2, 'user@X', 'No translation', 'auth_to_local_names section mismatch') # Return a realm environment containing an auth_to_local value (or list). def a2l_realm(name, values): conf = {'realms': {'$realm': {'auth_to_local': values}}} return realm.special_env(name, False, conf) # Test explicit use of default method. mark('explicit default') auth1 = a2l_realm('auth1', 'DEFAULT') test_an2ln(auth1, 'user@KRBTEST.COM', 'user', 'default rule') # Test some invalid auth_to_local values. mark('auth_to_local invalid') auth2 = a2l_realm('auth2', 'RULE') test_an2ln_err(auth2, 'user@X', 'Improper format', 'null rule') auth3 = a2l_realm('auth3', 'UNRECOGNIZED:stuff') test_an2ln_err(auth3, 'user@X', 'Improper format', 'null rule') # An empty rule has the default selection string (unparsed principal # without realm) and no match or substitutions. mark('rule (empty)') rule1 = a2l_realm('rule1', 'RULE:') test_an2ln(rule1, 'user@KRBTEST.COM', 'user', 'empty rule') test_an2ln(rule1, 'user@X', 'user', 'empty rule (foreign realm)') test_an2ln(rule1, 'a/b/c@X', 'a/b/c', 'empty rule (multi-component)') # Test explicit selection string. Also test that the default method # is suppressed when auth_to_local values are present. mark('rule (selection string)') rule2 = a2l_realm('rule2', 'RULE:[2:$$0.$$2.$$1]') test_an2ln(rule2, 'aaron/burr@REALM', 'REALM.burr.aaron', 'selection string') test_an2ln_err(rule2, 'user@KRBTEST.COM', 'No translation', 'suppress default') # Test match string. mark('rule (match string)') rule3 = a2l_realm('rule3', 'RULE:(.*tail)') test_an2ln(rule3, 'withtail@X', 'withtail', 'rule match 1') test_an2ln(rule3, 'x/withtail@X', 'x/withtail', 'rule match 2') test_an2ln_err(rule3, 'tails@X', 'No translation', 'rule anchor mismatch') # Test substitutions. mark('rule (substitutions)') rule4 = a2l_realm('rule4', 'RULE:s/birds/bees/') test_an2ln(rule4, 'thebirdsbirdsbirds@X', 'thebeesbirdsbirds', 'subst 1') rule5 = a2l_realm('rule4', 'RULE:s/birds/bees/g s/bees/birds/') test_an2ln(rule4, 'the/birdsbirdsbirds@x', 'the/birdsbeesbees', 'subst 2') # Test a bunch of auth_to_local values and rule features in combination. mark('rule (combo)') combo = a2l_realm('combo', ['RULE:[1:$$1-$$0](fred.*)s/-/ /g', 'DEFAULT', 'RULE:[3:$$1](z.*z)']) test_an2ln(combo, 'fred@X', 'fred X', 'combo 1') test_an2ln(combo, 'fred-too@X', 'fred too X', 'combo 2') test_an2ln(combo, 'fred@KRBTEST.COM', 'fred KRBTEST.COM', 'combo 3') test_an2ln(combo, 'user@KRBTEST.COM', 'user', 'combo 4') test_an2ln(combo, 'zazz/b/c@X', 'zazz', 'combo 5') test_an2ln_err(combo, 'a/b@KRBTEST.COM', 'No translation', 'combo 6') # Test the an2ln userok method with the combo environment. mark('userok (an2ln)') test_userok(combo, 'fred@X', 'fred X', True, 'combo userok 1') test_userok(combo, 'user@KRBTEST.COM', 'user', True, 'combo userok 2') test_userok(combo, 'user@KRBTEST.COM', 'X', False, 'combo userok 3') test_userok(combo, 'a/b@KRBTEST.COM', 'a/b', False, 'combo userok 4') mark('test modules') # Register the two test modules and set up some auth_to_local and # auth_to_local_names entries. modpath = os.path.join(buildtop, 'plugins', 'localauth', 'test', 'localauth_test.so') conf = {'plugins': {'localauth': { 'module': [ 'test1:' + modpath, 'test2:' + modpath]}}, 'realms': {'$realm': {'auth_to_local': [ 'RULE:(test/rulefirst)s/.*/rule/', 'TYPEA', 'DEFAULT', 'TYPEB:resid']}, 'auth_to_local_names': {'test/a/b': 'name'}}} mod = realm.special_env('mod', False, conf) # test1's untyped an2ln method should come before the names method, mapping # test/a/b@X to its realm name (superseding auth_to_local_names). test_an2ln(mod, 'test/a/b@X', 'X', 'mod untyped an2ln') # Match the auth_to_local values in order. test2's TYPEA should map # test/notrule to its second component, and its TYPEB should map # anything which gets there to the residual string. test_an2ln(mod, 'test/rulefirst@X', 'rule', 'mod auth_to_local 1') test_an2ln(mod, 'test/notrule', 'notrule', 'mod auth_to_local 2') test_an2ln(mod, 'user@KRBTEST.COM', 'user', 'mod auth_to_local 3') test_an2ln(mod, 'xyz@X', 'resid', 'mod auth_to_local 4') # test2's userok module should succeed when the number of components # is equal to the length of the local name, should pass if the first # component is 'pass', and should reject otherwise. test_userok(mod, 'a/b/c/d@X', 'four', True, 'mod userok 1') test_userok(mod, 'x/y/z@X', 'four', False, 'mod userok 2') test_userok(mod, 'pass@KRBTEST.COM', 'pass', True, 'mod userok 3') test_userok(mod, 'user@KRBTEST.COM', 'user', False, 'mod userok 4') success('krb5_kuserok and krb5_aname_to_localname tests') krb5-1.22.1/src/tests/t_sendto_kdc.py0000664000175000017500000000336415051422640017312 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(create_host=False) mark('Fallback to primary KDC') # Create a replica database and start a KDC. conf_rep = {'dbmodules': {'db': {'database_name': '$testdir/db.replica2'}}, 'realms': {'$realm': {'kdc_listen': '$port9', 'kdc_tcp_listen': '$port9'}}} replica = realm.special_env('replica', True, kdc_conf=conf_rep) dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile], env=replica) replica_kdc = realm.start_server([krb5kdc, '-n'], 'starting...', env=replica) # Change the password on the primary. realm.run([kadminl, 'cpw', '-pw', 'new', realm.user_princ]) conf_fallback = {'realms': {'$realm': {'kdc': '$hostname:$port9', 'primary_kdc': '$hostname:$port0'}}} fallback = realm.special_env('fallback', False, krb5_conf=conf_fallback) msgs = ('Retrying AS request with primary KDC',) realm.kinit(realm.user_princ, 'new', env=fallback, expected_trace=msgs) stop_daemon(replica_kdc) mark('UNIX domain socket') conf_unix = {'realms': {'$realm': {'kdc_listen': '$testdir/krb5.sock', 'kdc_tcp_listen': ''}}} unix = realm.special_env('unix', True, kdc_conf=conf_unix) realm.run([kdb5_util, 'load', dumpfile], env=unix) realm.stop_kdc() realm.start_kdc(env=unix) conf_unix_cli = {'realms': {'$realm': {'kdc': '$testdir/krb5.sock'}}} unix_cli = realm.special_env('unix_cli', False, krb5_conf=conf_unix_cli) # Do a kinit and check if we send the packet via a UNIX domain socket. msgs = ('Sending TCP request to UNIX domain socket',) realm.kinit(realm.user_princ, password('user'), env=unix_cli, expected_trace=msgs) success('sendto_kdc') krb5-1.22.1/src/tests/plugorder.c0000664000175000017500000000640315051422640016444 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/plugorder.c - Test harness to display the order of loaded plugins */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file registers a few dummy built-in pwqual modules, then prints out the * order of pwqual modules returned by k5_plugin_load_all. The choice of the * pwqual interface is mostly arbitrary; it is an interface which libkrb5 * itself doesn't use, for which we have a test module. */ #include "k5-int.h" #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static krb5_error_code blt1(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { ((krb5_pwqual_vtable)vtable)->name = "blt1"; return 0; } static krb5_error_code blt2(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { ((krb5_pwqual_vtable)vtable)->name = "blt2"; return 0; } static krb5_error_code blt3(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { ((krb5_pwqual_vtable)vtable)->name = "blt3"; return 0; } int main(void) { krb5_plugin_initvt_fn *modules = NULL, *mod; struct krb5_pwqual_vtable_st vt; check(krb5_init_context(&ctx)); check(k5_plugin_register(ctx, PLUGIN_INTERFACE_PWQUAL, "blt1", blt1)); check(k5_plugin_register(ctx, PLUGIN_INTERFACE_PWQUAL, "blt2", blt2)); check(k5_plugin_register(ctx, PLUGIN_INTERFACE_PWQUAL, "blt3", blt3)); check(k5_plugin_load_all(ctx, PLUGIN_INTERFACE_PWQUAL, &modules)); for (mod = modules; *mod != NULL; mod++) { check((*mod)(ctx, 1, 1, (krb5_plugin_vtable)&vt)); printf("%s\n", vt.name); } k5_plugin_free_modules(ctx, modules); return 0; } krb5-1.22.1/src/tests/gss-threads/0000775000175000017500000000000015051422640016516 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/gss-threads/README0000664000175000017500000001470515051422640017405 0ustar ghudsonghudson[Out of date; needs updating for thread safety test support. -- KR 2005-02-09] # Copyright 1993 by OpenVision Technologies, Inc. # # Permission to use, copy, modify, distribute, and sell this software # and its documentation for any purpose is hereby granted without fee, # provided that the above copyright notice appears in all copies and # that both that copyright notice and this permission notice appear in # supporting documentation, and that the name of OpenVision not be used # in advertising or publicity pertaining to distribution of the software # without specific, written prior permission. OpenVision makes no # representations about the suitability of this software for any # purpose. It is provided "as is" without express or implied warranty. # # OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO # EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF # USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. This directory contains a sample GSS-API client and server application. In addition to serving as an example of GSS-API programming, this application is also intended to be a tool for testing the performance of GSS-API implementations. Each time the client is invoked, it performs one or more exchanges with the server. Each exchange with the server consists primarily of the following steps: 1. A TCP/IP connection is established. 2. (optional, on by default) The client and server establish a GSS-API context, and the server prints the identify of the client. / 3. The client sends a message to the server. The message may / be plaintext, cryptographically "signed" but not encrypted, | or encrypted (default). | 0 or | 4. The server decrypts the message (if necessary), verifies more | its signature (if there is one) and prints it. times| | 5. The server sends either a signature block (the default) or an | empty token back to the client to acknowledge the message. \ \ 6. If the server sent a signature block, the client verifies it and prints a message indicating that it was verified. 7. The client sends an empty block to the server to tell it that the exchange is finished. 8. The client and server close the TCP/IP connection and destroy the GSS-API context. The client also supports the -v1 flag which uses an older exchange format compatible with previous releases of Kerberos and with samples shipped in the Microsoft SDK. The server's command line usage is gss-server [-port port] [-verbose] [-once] [-inetd] [-export] [-logfile file] service_name where service_name is a GSS-API service name of the form "service@host" (or just "service", in which case the local host name is used). The command-line options have the following meanings: -port The TCP port on which to accept connections. Default is 4444. -once Tells the server to exit after a single exchange, rather than persisting. -inetd Tells the server that it is running out of inetd, so it should interact with the client on stdin rather than binding to a network port. Implies "-once". -export Tells the server to test the gss_export_sec_context function after establishing a context with a client. -logfile The file to which the server should append its output, rather than sending it to stdout. The client's command line usage is gss-client [-port port] [-mech mechanism] [-d] [-f] [-q] [-seq] [-noreplay] [-nomutual] [-ccount count] [-mcount count] [-na] [-nw] [-nx] [-nm] host service_name msg where host is the host running the server, service_name is the service name that the server will establish connections as (if you don't specify the host name in the service name when running gss-server, and it's running on a different machine from gss-client, make sure to specify the server's host name in the service name you specify to gss-client!) and msg is the message. The command-line options have the following meanings: -port The TCP port to which to connect. Default is 4444. -mech The OID of the GSS-API mechanism to use. -d Tells the client to delegate credentials to the server. For the Kerberos GSS-API mechanism, this means that a forwardable TGT will be sent to the server, which will put it in its credential cache (you must have acquired your tickets with "kinit -f" for this to work). -seq Tells the client to enforce ordered message delivery via sequencing. -noreplay Tells the client to disable the use of replay detection. -nomutual Tells the client to disable the use of mutual authentication. -f Tells the client that the "msg" argument is actually the name of a file whose contents should be used as the message. -q Tells the client to be quiet, i.e., to only print error messages. -ccount Specifies how many sessions the client should initiate with the server (the "connection count"). -mcount Specifies how many times the message should be sent to the server in each session (the "message count"). -na Tells the client not to do any authentication with the server. Implies "-nw", "-nx" and "-nm". -nw Tells the client not to "wrap" messages. Implies "-nx". -nx Tells the client not to encrypt messages. -nm Tells the client not to ask the server to send back a cryptographic checksum ("MIC"). To run the server on a host, you need to make sure that the principal corresponding to service_name is in the default keytab on the server host, and that the gss-server process can read the keytab. For example, the service name "host@server" corresponds to the Kerberos principal "host/server.domain.com@REALM". This sample application uses the following GSS-API functions: gss_accept_sec_context gss_inquire_names_for_mech gss_acquire_cred gss_oid_to_str gss_delete_sec_context gss_release_buffer gss_display_name gss_release_cred gss_display_status gss_release_name gss_export_sec_context gss_release_oid gss_get_mic gss_release_oid_set gss_import_name gss_str_to_oid gss_import_sec_context gss_unwrap gss_init_sec_context gss_verify_mic gss_inquire_context gss_wrap This application was originally written by Barry Jaspan of OpenVision Technologies, Inc. It was updated significantly by Jonathan Kamens of OpenVision Technologies, Inc. $Id$ krb5-1.22.1/src/tests/gss-threads/Makefile.in0000664000175000017500000000237115051422640020566 0ustar ghudsonghudson# Derived from appl/gss-sample, January 2005. mydir=tests$(S)gss-threads BUILDTOP=$(REL)..$(S).. DEFINES = -DUSE_AUTOCONF_H -DGSSAPI_V2 PTHREAD_LIBS=@PTHREAD_LIBS@ SRCS= $(srcdir)/gss-client.c $(srcdir)/gss-misc.c $(srcdir)/gss-server.c OBJS= gss-client.o gss-misc.o gss-server.o all-unix: all-unix-@THREAD_SUPPORT@ all-unix-1: gss-server gss-client all-unix-0: all-windows: $(OUTPRE)gss-server.exe $(OUTPRE)gss-client.exe gss-server: gss-server.o gss-misc.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o gss-server gss-server.o gss-misc.o $(GSS_LIBS) $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) gss-client: gss-client.o gss-misc.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o gss-client gss-client.o gss-misc.o $(GSS_LIBS) $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) $(OUTPRE)gss-server.exe: $(OUTPRE)gss-server.obj $(OUTPRE)gss-misc.obj $(GLIB) $(KLIB) link $(EXE_LINKOPTS) -out:$@ $** ws2_32.lib $(OUTPRE)gss-client.exe: $(OUTPRE)gss-client.obj $(OUTPRE)gss-misc.obj $(GLIB) $(KLIB) link $(EXE_LINKOPTS) -out:$@ $** ws2_32.lib clean-unix:: $(RM) gss-server gss-client install-unix: # $(INSTALL_PROGRAM) gss-client $(DESTDIR)$(CLIENT_BINDIR)/gss-tclient # $(INSTALL_PROGRAM) gss-server $(DESTDIR)$(SERVER_BINDIR)/gss-tserver krb5-1.22.1/src/tests/gss-threads/gss-misc.h0000664000175000017500000000350415051422640020416 0ustar ghudsonghudson/* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifndef _GSSMISC_H_ #define _GSSMISC_H_ #include #include extern FILE *display_file; int send_token(int s, int flags, gss_buffer_t tok); int recv_token(int s, int *flags, gss_buffer_t tok); void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat); void display_ctx_flags(OM_uint32 flags); void print_token(gss_buffer_t tok); /* Token types */ #define TOKEN_NOOP (1<<0) #define TOKEN_CONTEXT (1<<1) #define TOKEN_DATA (1<<2) #define TOKEN_MIC (1<<3) /* Token flags */ #define TOKEN_CONTEXT_NEXT (1<<4) #define TOKEN_WRAPPED (1<<5) #define TOKEN_ENCRYPTED (1<<6) #define TOKEN_SEND_MIC (1<<7) extern gss_buffer_t empty_token; #endif krb5-1.22.1/src/tests/gss-threads/gss-misc.c0000664000175000017500000002641415051422640020416 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2003, 2004 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #include #ifdef _WIN32 #include #include #else #include #include #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #include /* need struct timeval */ #include #if HAVE_SYS_TIME_H #include #endif #include #include "gss-misc.h" /* for store_32_be */ #include "k5-platform.h" #ifdef HAVE_STDLIB_H #include #else extern char *malloc(); #endif FILE *display_file; gss_buffer_desc empty_token_buf = { 0, (void *)"" }; gss_buffer_t empty_token = &empty_token_buf; static void display_status_1(char *m, OM_uint32 code, int type); static int write_all(int fildes, char *buf, unsigned int nbyte) { int ret; char *ptr; for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { ret = send(fildes, ptr, nbyte, 0); if (ret < 0) { if (errno == EINTR) continue; return ret; } else if (ret == 0) { return ptr - buf; } } return ptr - buf; } static int read_all(int fildes, char *buf, unsigned int nbyte) { int ret; char *ptr; fd_set rfds; struct timeval tv; FD_ZERO(&rfds); FD_SET(fildes, &rfds); tv.tv_sec = 10; tv.tv_usec = 0; for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { if (select(FD_SETSIZE, &rfds, NULL, NULL, &tv) <= 0 || !FD_ISSET(fildes, &rfds)) return ptr - buf; ret = recv(fildes, ptr, nbyte, 0); if (ret < 0) { if (errno == EINTR) continue; return ret; } else if (ret == 0) { return ptr - buf; } } return ptr - buf; } /* * Function: send_token * * Purpose: Writes a token to a file descriptor. * * Arguments: * * s (r) an open file descriptor * flags (r) the flags to write * tok (r) the token to write * * Returns: 0 on success, -1 on failure * * Effects: * * If the flags are non-null, send_token writes the token flags (a * single byte, even though they're passed in in an integer). Next, * the token length (as a network long) and then the token data are * written to the file descriptor s. It returns 0 on success, and -1 * if an error occurs or if it could not write all the data. */ int send_token(int s, int flags, gss_buffer_t tok) { int ret; unsigned char char_flags = (unsigned char)flags; unsigned char lenbuf[4]; if (char_flags) { ret = write_all(s, (char *)&char_flags, 1); if (ret != 1) { perror("sending token flags"); return -1; } } if (tok->length > 0xffffffffUL) abort(); store_32_be(tok->length, lenbuf); ret = write_all(s, (char *)lenbuf, 4); if (ret < 0) { perror("sending token length"); return -1; } else if (ret != 4) { if (display_file) { fprintf(display_file, "sending token length: %d of %d bytes written\n", ret, 4); } return -1; } ret = write_all(s, tok->value, tok->length); if (ret < 0) { perror("sending token data"); return -1; } else if ((size_t)ret != tok->length) { if (display_file) { fprintf(display_file, "sending token data: %d of %d bytes written\n", ret, (int)tok->length); } return -1; } return 0; } /* * Function: recv_token * * Purpose: Reads a token from a file descriptor. * * Arguments: * * s (r) an open file descriptor * flags (w) the read flags * tok (w) the read token * * Returns: 0 on success, -1 on failure * * Effects: * * recv_token reads the token flags (a single byte, even though * they're stored into an integer, then reads the token length (as a * network long), allocates memory to hold the data, and then reads * the token data from the file descriptor s. It blocks to read the * length and data, if necessary. On a successful return, the token * should be freed with gss_release_buffer. It returns 0 on success, * and -1 if an error occurs or if it could not read all the data. */ int recv_token(int s, int *flags, gss_buffer_t tok) { int ret; unsigned char char_flags; unsigned char lenbuf[4]; ret = read_all(s, (char *)&char_flags, 1); if (ret < 0) { perror("reading token flags"); return -1; } else if (!ret) { if (display_file) fputs("reading token flags: 0 bytes read\n", display_file); return -1; } else { *flags = char_flags; } if (char_flags == 0) { lenbuf[0] = 0; ret = read_all(s, (char *)&lenbuf[1], 3); if (ret < 0) { perror("reading token length"); return -1; } else if (ret != 3) { if (display_file) { fprintf(display_file, "reading token length: %d of %d bytes read\n", ret, 3); } return -1; } } else { ret = read_all(s, (char *)lenbuf, 4); if (ret < 0) { perror("reading token length"); return -1; } else if (ret != 4) { if (display_file) { fprintf(display_file, "reading token length: %d of %d bytes read\n", ret, 4); } return -1; } } tok->length = load_32_be(lenbuf); tok->value = malloc(tok->length ? tok->length : 1); if (tok->length && tok->value == NULL) { if (display_file) fprintf(display_file, "Out of memory allocating token data\n"); return -1; } ret = read_all(s, (char *)tok->value, tok->length); if (ret < 0) { perror("reading token data"); free(tok->value); return -1; } else if ((size_t)ret != tok->length) { fprintf(stderr, "sending token data: %d of %d bytes written\n", ret, (int)tok->length); free(tok->value); return -1; } return 0; } static void display_status_1(char *m, OM_uint32 code, int type) { OM_uint32 min_stat; gss_buffer_desc msg; OM_uint32 msg_ctx; msg_ctx = 0; while (1) { (void)gss_display_status(&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg); if (display_file) { fprintf(display_file, "GSS-API error %s: %s\n", m, (char *)msg.value); } (void)gss_release_buffer(&min_stat, &msg); if (!msg_ctx) break; } } /* * Function: display_status * * Purpose: displays GSS-API messages * * Arguments: * * msg a string to be displayed with the message * maj_stat the GSS-API major status code * min_stat the GSS-API minor status code * * Effects: * * The GSS-API messages associated with maj_stat and min_stat are * displayed on stderr, each preceded by "GSS-API error : " and * followed by a newline. */ void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat) { display_status_1(msg, maj_stat, GSS_C_GSS_CODE); display_status_1(msg, min_stat, GSS_C_MECH_CODE); } /* * Function: display_ctx_flags * * Purpose: displays the flags returned by context initiation in * a human-readable form * * Arguments: * * int ret_flags * * Effects: * * Strings corresponding to the context flags are printed on * stdout, preceded by "context flag: " and followed by a newline */ void display_ctx_flags(OM_uint32 flags) { if (flags & GSS_C_DELEG_FLAG) fprintf(display_file, "context flag: GSS_C_DELEG_FLAG\n"); if (flags & GSS_C_MUTUAL_FLAG) fprintf(display_file, "context flag: GSS_C_MUTUAL_FLAG\n"); if (flags & GSS_C_REPLAY_FLAG) fprintf(display_file, "context flag: GSS_C_REPLAY_FLAG\n"); if (flags & GSS_C_SEQUENCE_FLAG) fprintf(display_file, "context flag: GSS_C_SEQUENCE_FLAG\n"); if (flags & GSS_C_CONF_FLAG) fprintf(display_file, "context flag: GSS_C_CONF_FLAG \n"); if (flags & GSS_C_INTEG_FLAG) fprintf(display_file, "context flag: GSS_C_INTEG_FLAG \n"); } void print_token(gss_buffer_t tok) { size_t i; unsigned char *p = tok->value; if (!display_file) return; for (i = 0; i < tok->length; i++, p++) { fprintf(display_file, "%02x ", *p); if (i % 16 == 15) { fprintf(display_file, "\n"); } } fprintf(display_file, "\n"); fflush(display_file); } #ifdef _WIN32 #include #include int gettimeofday(struct timeval *tv, void *ignore_tz) { struct _timeb tb; _tzset(); _ftime(&tb); if (tv) { tv->tv_sec = tb.time; tv->tv_usec = tb.millitm * 1000; } return 0; } #endif /* _WIN32 */ krb5-1.22.1/src/tests/gss-threads/deps0000664000175000017500000000154115051422640017375 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)gss-client.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(top_srcdir)/include/fake-addrinfo.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h gss-client.c gss-misc.h $(OUTPRE)gss-misc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ gss-misc.c gss-misc.h $(OUTPRE)gss-server.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(top_srcdir)/include/port-sockets.h gss-misc.h gss-server.c krb5-1.22.1/src/tests/gss-threads/gss-server.c0000664000175000017500000006115715051422640020774 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2004,2008 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #include #ifdef _WIN32 #include #include #else #include #include #include #include #include #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include "gss-misc.h" #include "port-sockets.h" #ifdef HAVE_STRING_H #include #else #include #endif static void usage(void) { fprintf(stderr, "Usage: gss-server [-port port] [-verbose] [-once]"); #ifdef _WIN32 fprintf(stderr, " [-threads num]"); #endif fprintf(stderr, "\n"); fprintf(stderr, " [-inetd] [-export] [-logfile file] " "service_name\n"); exit(1); } FILE *logfile; int verbose = 0; /* * Function: server_acquire_creds * * Purpose: imports a service name and acquires credentials for it * * Arguments: * * service_name (r) the ASCII service name * server_creds (w) the GSS-API service credentials * * Returns: 0 on success, -1 on failure * * Effects: * * The service name is imported with gss_import_name, and service * credentials are acquired with gss_acquire_cred. If either operation * fails, an error message is displayed and -1 is returned; otherwise, * 0 is returned. */ static int server_acquire_creds(char *service_name, gss_cred_id_t *server_creds) { gss_buffer_desc name_buf; gss_name_t server_name; OM_uint32 maj_stat, min_stat; name_buf.value = service_name; name_buf.length = strlen(name_buf.value) + 1; maj_stat = gss_import_name(&min_stat, &name_buf, (gss_OID)gss_nt_service_name, &server_name); if (maj_stat != GSS_S_COMPLETE) { display_status("importing name", maj_stat, min_stat); return -1; } maj_stat = gss_acquire_cred(&min_stat, server_name, 0, GSS_C_NULL_OID_SET, GSS_C_ACCEPT, server_creds, NULL, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("acquiring credentials", maj_stat, min_stat); return -1; } (void)gss_release_name(&min_stat, &server_name); return 0; } /* * Function: server_establish_context * * Purpose: establishses a GSS-API context as a specified service with * an incoming client, and returns the context handle and associated * client name * * Arguments: * * s (r) an established TCP connection to the client * service_creds (r) server credentials, from gss_acquire_cred * context (w) the established GSS-API context * client_name (w) the client's ASCII name * * Returns: 0 on success, -1 on failure * * Effects: * * Any valid client request is accepted. If a context is established, * its handle is returned in context and the client name is returned * in client_name and 0 is returned. If unsuccessful, an error * message is displayed and -1 is returned. */ static int server_establish_context(int s, gss_cred_id_t server_creds, gss_ctx_id_t *context, gss_buffer_t client_name, OM_uint32 *ret_flags) { gss_buffer_desc send_tok, recv_tok, oid_name; gss_name_t client; gss_OID doid; OM_uint32 maj_stat, min_stat, acc_sec_min_stat; int token_flags; if (recv_token(s, &token_flags, &recv_tok) < 0) return -1; if (recv_tok.value) { free(recv_tok.value); recv_tok.value = NULL; } if (!(token_flags & TOKEN_NOOP)) { if (logfile) { fprintf(logfile, "Expected NOOP token, got %d token instead\n", token_flags); } return -1; } *context = GSS_C_NO_CONTEXT; if (token_flags & TOKEN_CONTEXT_NEXT) { do { if (recv_token(s, &token_flags, &recv_tok) < 0) return -1; if (verbose && logfile) { fprintf(logfile, "Received token (size=%d): \n", (int)recv_tok.length); print_token(&recv_tok); } maj_stat = gss_accept_sec_context(&acc_sec_min_stat, context, server_creds, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &client, &doid, &send_tok, ret_flags, NULL, NULL); if (recv_tok.value) { free(recv_tok.value); recv_tok.value = NULL; } if (send_tok.length != 0) { if (verbose && logfile) { fprintf(logfile, "Sending accept_sec_context token (size=%d):\n", (int)send_tok.length); print_token(&send_tok); } if (send_token(s, TOKEN_CONTEXT, &send_tok) < 0) { if (logfile) fprintf(logfile, "failure sending token\n"); return -1; } (void)gss_release_buffer(&min_stat, &send_tok); } if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { display_status("accepting context", maj_stat, acc_sec_min_stat); if (*context != GSS_C_NO_CONTEXT) { gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER); } return -1; } if (verbose && logfile) { if (maj_stat == GSS_S_CONTINUE_NEEDED) fprintf(logfile, "continue needed...\n"); else fprintf(logfile, "\n"); fflush(logfile); } } while (maj_stat == GSS_S_CONTINUE_NEEDED); /* display the flags */ display_ctx_flags(*ret_flags); if (verbose && logfile) { maj_stat = gss_oid_to_str(&min_stat, doid, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } fprintf(logfile, "Accepted connection using mechanism OID %.*s.\n", (int)oid_name.length, (char *)oid_name.value); (void)gss_release_buffer(&min_stat, &oid_name); } maj_stat = gss_display_name(&min_stat, client, client_name, &doid); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying name", maj_stat, min_stat); return -1; } maj_stat = gss_release_name(&min_stat, &client); if (maj_stat != GSS_S_COMPLETE) { display_status("releasing name", maj_stat, min_stat); return -1; } } else { client_name->length = *ret_flags = 0; if (logfile) fprintf(logfile, "Accepted unauthenticated connection.\n"); } return 0; } /* * Function: create_socket * * Purpose: Opens a listening TCP socket. * * Arguments: * * port (r) the port number on which to listen * * Returns: the listening socket file descriptor, or -1 on failure * * Effects: * * A listening socket on the specified port and created and returned. * On error, an error message is displayed and -1 is returned. */ static int create_socket(u_short port) { struct sockaddr_in saddr; int s, on = 1; saddr.sin_family = AF_INET; saddr.sin_port = htons(port); saddr.sin_addr.s_addr = INADDR_ANY; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { perror("creating socket"); return -1; } /* Let the socket be reused right away. */ (void)setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if (bind(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("binding socket"); (void)close(s); return -1; } if (listen(s, 5) < 0) { perror("listening on socket"); (void)close(s); return -1; } return s; } static float timeval_subtract(struct timeval *tv1, struct timeval *tv2) { return ((tv1->tv_sec - tv2->tv_sec) + ((float)(tv1->tv_usec - tv2->tv_usec)) / 1000000); } /* * Yes, yes, this isn't the best place for doing this test. * DO NOT REMOVE THIS UNTIL A BETTER TEST HAS BEEN WRITTEN, THOUGH. * -TYT */ static int test_import_export_context(gss_ctx_id_t *context) { OM_uint32 min_stat, maj_stat; gss_buffer_desc context_token, copied_token; struct timeval tm1, tm2; /* Attempt to save and then restore the context. */ gettimeofday(&tm1, (struct timezone *)0); maj_stat = gss_export_sec_context(&min_stat, context, &context_token); if (maj_stat != GSS_S_COMPLETE) { display_status("exporting context", maj_stat, min_stat); return 1; } gettimeofday(&tm2, NULL); if (verbose && logfile) { fprintf(logfile, "Exported context: %d bytes, %7.4f seconds\n", (int)context_token.length, timeval_subtract(&tm2, &tm1)); } copied_token.length = context_token.length; copied_token.value = malloc(context_token.length); if (copied_token.value == 0) { if (logfile) { fprintf(logfile, "Couldn't allocate memory to copy context " "token.\n"); } return 1; } memcpy(copied_token.value, context_token.value, copied_token.length); maj_stat = gss_import_sec_context(&min_stat, &copied_token, context); if (maj_stat != GSS_S_COMPLETE) { display_status("importing context", maj_stat, min_stat); return 1; } free(copied_token.value); gettimeofday(&tm1, NULL); if (verbose && logfile) { fprintf(logfile, "Importing context: %7.4f seconds\n", timeval_subtract(&tm1, &tm2)); } (void)gss_release_buffer(&min_stat, &context_token); return 0; } /* * Function: sign_server * * Purpose: Performs the "sign" service. * * Arguments: * * s (r) a TCP socket on which a connection has been * accept()ed * service_name (r) the ASCII name of the GSS-API service to * establish a context as * export (r) whether to test context exporting * * Returns: -1 on error * * Effects: * * sign_server establishes a context, and performs a single sign request. * * A sign request is a single GSS-API sealed token. The token is * unsealed and a signature block, produced with gss_sign, is returned * to the sender. The context is the destroyed and the connection * closed. * * If any error occurs, -1 is returned. */ static int sign_server(int s, gss_cred_id_t server_creds, int export) { gss_buffer_desc client_name, xmit_buf, msg_buf; gss_ctx_id_t context; OM_uint32 maj_stat, min_stat, ret_flags; int i, conf_state, token_flags; char *cp; /* Establish a context with the client */ if (server_establish_context(s, server_creds, &context, &client_name, &ret_flags) < 0) return -1; if (context == GSS_C_NO_CONTEXT) { printf("Accepted unauthenticated connection.\n"); } else { printf("Accepted connection: \"%.*s\"\n", (int)client_name.length, (char *)client_name.value); (void)gss_release_buffer(&min_stat, &client_name); if (export) { for (i = 0; i < 3; i++) { if (test_import_export_context(&context)) return -1; } } } do { /* Receive the message token */ if (recv_token(s, &token_flags, &xmit_buf) < 0) return -1; if (token_flags & TOKEN_NOOP) { if (logfile) fprintf(logfile, "NOOP token\n"); if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } break; } if (verbose && logfile) { fprintf(logfile, "Message token (flags=%d):\n", token_flags); print_token(&xmit_buf); } if (context == GSS_C_NO_CONTEXT && (token_flags & (TOKEN_WRAPPED | TOKEN_ENCRYPTED | TOKEN_SEND_MIC))) { if (logfile) { fprintf(logfile, "Unauthenticated client requested " "authenticated services!\n"); } if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } return -1; } if (token_flags & TOKEN_WRAPPED) { maj_stat = gss_unwrap(&min_stat, context, &xmit_buf, &msg_buf, &conf_state, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("unsealing message", maj_stat, min_stat); if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } return -1; } else if (!conf_state && (token_flags & TOKEN_ENCRYPTED)) { fprintf(stderr, "Warning! Message not encrypted.\n"); } if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } } else { msg_buf = xmit_buf; } if (logfile) { fprintf(logfile, "Received message: "); cp = msg_buf.value; if (isprint((unsigned char)cp[0]) && isprint((unsigned char)cp[1])) { fprintf(logfile, "\"%.*s\"\n", (int)msg_buf.length, (char *)msg_buf.value); } else { fprintf(logfile, "\n"); print_token(&msg_buf); } } if (token_flags & TOKEN_SEND_MIC) { /* Produce a signature block for the message. */ maj_stat = gss_get_mic(&min_stat, context, GSS_C_QOP_DEFAULT, &msg_buf, &xmit_buf); if (maj_stat != GSS_S_COMPLETE) { display_status("signing message", maj_stat, min_stat); return -1; } if (msg_buf.value) { free(msg_buf.value); msg_buf.value = 0; } /* Send the signature block to the client. */ if (send_token(s, TOKEN_MIC, &xmit_buf) < 0) return -1; if (xmit_buf.value) { free(xmit_buf.value); xmit_buf.value = 0; } } else { if (msg_buf.value) { free(msg_buf.value); msg_buf.value = 0; } if (send_token(s, TOKEN_NOOP, empty_token) < 0) return -1; } } while (1 /* loop will break if NOOP received */); if (context != GSS_C_NO_CONTEXT) { /* Delete context. */ maj_stat = gss_delete_sec_context(&min_stat, &context, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("deleting context", maj_stat, min_stat); return -1; } } if (logfile) fflush(logfile); return 0; } static int max_threads = 1; #ifdef _WIN32 static thread_count = 0; static HANDLE hMutex = NULL; static HANDLE hEvent = NULL; void init_handles(void) { hMutex = CreateMutex(NULL, FALSE, NULL); hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); } void cleanup_handles(void) { CloseHandle(hMutex); CloseHandle(hEvent); } BOOL wait_and_increment_thread_counter(void) { for (;;) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count < max_threads) { thread_count++; ReleaseMutex(hMutex); return TRUE; } else { ReleaseMutex(hMutex); if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) continue; else return FALSE; } } else { return FALSE; } } } BOOL decrement_and_signal_thread_counter(void) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count == max_threads) SetEvent(hEvent); thread_count--; ReleaseMutex(hMutex); return TRUE; } else { return FALSE; } } #else /* assume pthread */ static pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t counter_cond = PTHREAD_COND_INITIALIZER; int counter = 0; static int wait_and_increment_thread_counter(void) { int err; err = pthread_mutex_lock(&counter_mutex); if (err) { perror("pthread_mutex_lock"); return 0; } if (counter == max_threads) { err = pthread_cond_wait(&counter_cond, &counter_mutex); if (err) { pthread_mutex_unlock(&counter_mutex); perror("pthread_cond_wait"); return 0; } } counter++; pthread_mutex_unlock(&counter_mutex); return 1; } static void decrement_and_signal_thread_counter(void) { int err; err = pthread_mutex_lock(&counter_mutex); if (err) { perror("pthread_mutex_lock"); return; } if (counter == max_threads) pthread_cond_broadcast(&counter_cond); counter--; pthread_mutex_unlock(&counter_mutex); } #endif struct _work_plan { int s; gss_cred_id_t server_creds; int export; }; static void * worker_bee(void *param) { struct _work_plan *work = param; /* This return value is not checked, because there's not really anything to * do if it fails. */ sign_server(work->s, work->server_creds, work->export); closesocket(work->s); free(work); #if defined _WIN32 || 1 if (max_threads > 1) decrement_and_signal_thread_counter(); #endif return NULL; } int main(int argc, char **argv) { char *service_name; gss_cred_id_t server_creds; OM_uint32 min_stat; u_short port = 4444; int once = 0; int do_inetd = 0; int export = 0; signal(SIGPIPE, SIG_IGN); logfile = stdout; display_file = stdout; argc--; argv++; while (argc) { if (strcmp(*argv, "-port") == 0) { argc--; argv++; if (!argc) usage(); port = atoi(*argv); } else if (strcmp(*argv, "-threads") == 0) { argc--; argv++; if (!argc) usage(); max_threads = atoi(*argv); } else if (strcmp(*argv, "-verbose") == 0) { verbose = 1; } else if (strcmp(*argv, "-once") == 0) { once = 1; } else if (strcmp(*argv, "-inetd") == 0) { do_inetd = 1; } else if (strcmp(*argv, "-export") == 0) { export = 1; } else if (strcmp(*argv, "-logfile") == 0) { argc--; argv++; if (!argc) usage(); /* * Gross hack, but it makes it unnecessary to add an extra argument * to disable logging, and makes the code more efficient because it * doesn't actually write data to /dev/null. */ if (!strcmp(*argv, "/dev/null")) { logfile = display_file = NULL; } else { logfile = fopen(*argv, "a"); display_file = logfile; if (!logfile) { perror(*argv); exit(1); } } } else { break; } argc--; argv++; } if (argc != 1) usage(); if ((*argv)[0] == '-') usage(); #ifdef _WIN32 if (max_threads < 1) { fprintf(stderr, "warning: there must be at least one thread\n"); max_threads = 1; } if (max_threads > 1 && do_inetd) { fprintf(stderr, "warning: one thread may be used in conjunction " "with inetd\n"); } init_handles(); #endif service_name = *argv; if (server_acquire_creds(service_name, &server_creds) < 0) return -1; if (do_inetd) { close(1); close(2); sign_server(0, server_creds, export); close(0); } else { int stmp; stmp = create_socket(port); if (stmp >= 0) { do { struct _work_plan * work = malloc(sizeof(struct _work_plan)); if (work == NULL) { fprintf(stderr, "fatal error: out of memory"); break; } /* Accept a TCP connection */ work->s = accept(stmp, NULL, 0); if (work->s < 0) { perror("accepting connection"); continue; } work->server_creds = server_creds; work->export = export; if (max_threads == 1) { worker_bee(work); } else { if (wait_and_increment_thread_counter()) { #ifdef _WIN32 uintptr_t handle = _beginthread(worker_bee, 0, work); if (handle == (uintptr_t)-1) { closesocket(work->s); free(work); } #else int err; pthread_t thr; err = pthread_create(&thr, 0, worker_bee, work); if (err) { perror("pthread_create"); closesocket(work->s); free(work); } (void)pthread_detach(thr); #endif } else { fprintf(stderr, "fatal error incrementing thread " "counter"); closesocket(work->s); free(work); break; } } } while (!once); closesocket(stmp); } } (void)gss_release_cred(&min_stat, &server_creds); #ifdef _WIN32 cleanup_handles(); #else if (max_threads > 1) { while (1) sleep(999999); } #endif return 0; } krb5-1.22.1/src/tests/gss-threads/gss-client.c0000664000175000017500000006613315051422640020743 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright (C) 2003, 2004, 2008 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-platform.h" #ifdef _WIN32 #include #include #else #include #include #include #include #include #include #include #include #include #endif #include #include "gss-misc.h" #include "port-sockets.h" #include "fake-addrinfo.h" static int verbose = 1; static void usage(void) { fprintf(stderr, "Usage: gss-client [-port port] [-mech mechanism] [-d]\n"); fprintf(stderr, " [-seq] [-noreplay] [-nomutual]"); fprintf(stderr, " [-threads num]"); fprintf(stderr, "\n"); fprintf(stderr, " [-f] [-q] [-ccount count] [-mcount count]\n"); fprintf(stderr, " [-v1] [-na] [-nw] [-nx] [-nm] host service msg\n"); exit(1); } /* * Function: get_server_info * * Purpose: Sets up a socket address for the named host and port. * * Arguments: * * host (r) the target host name * port (r) the target port, in host byte order * * Returns: 0 on success, or -1 on failure * * Effects: * * The host name is resolved with gethostbyname(), and "saddr" is set * to the desired socket address. If an error occurs, an error * message is displayed and -1 is returned. */ struct sockaddr_in saddr; static int get_server_info(char *host, u_short port) { struct hostent *hp; hp = gethostbyname(host); if (hp == NULL) { fprintf(stderr, "Unknown host: %s\n", host); return -1; } saddr.sin_family = hp->h_addrtype; memcpy(&saddr.sin_addr, hp->h_addr, sizeof(saddr.sin_addr)); saddr.sin_port = htons(port); return 0; } /* * Function: connect_to_server * * Purpose: Opens a TCP connection to the name host and port. * * Arguments: * * host (r) the target host name * port (r) the target port, in host byte order * * Returns: the established socket file descriptor, or -1 on failure * * Effects: * * The host name is resolved with gethostbyname(), and the socket is * opened and connected. If an error occurs, an error message is * displayed and -1 is returned. */ static int connect_to_server(void) { int s; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { perror("creating socket"); return -1; } if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("connecting to server"); (void)closesocket(s); return -1; } return s; } /* * Function: client_establish_context * * Purpose: establishes a GSS-API context with a specified service and * returns the context handle * * Arguments: * * s (r) an established TCP connection to the service * service_name (r) the ASCII service name of the service * gss_flags (r) GSS-API delegation flag (if any) * auth_flag (r) whether to actually do authentication * v1_format (r) whether the v1 sample protocol should be used * oid (r) OID of the mechanism to use * context (w) the established GSS-API context * ret_flags (w) the returned flags from init_sec_context * * Returns: 0 on success, -1 on failure * * Effects: * * service_name is imported as a GSS-API name and a GSS-API context is * established with the corresponding service; the service should be * listening on the TCP connection s. The default GSS-API mechanism * is used, and mutual authentication and replay detection are * requested. * * If successful, the context handle is returned in context. If * unsuccessful, the GSS-API error messages are displayed on stderr * and -1 is returned. */ static int client_establish_context(int s, char *service_name, OM_uint32 gss_flags, int auth_flag, int v1_format, gss_OID oid, gss_ctx_id_t *gss_context, OM_uint32 *ret_flags) { if (auth_flag) { gss_buffer_desc send_tok, recv_tok, *token_ptr; gss_name_t target_name; OM_uint32 maj_stat, min_stat, init_sec_min_stat; int token_flags; /* * Import the name into target_name. Use send_tok to save * local variable space. */ send_tok.value = service_name; send_tok.length = strlen(service_name); maj_stat = gss_import_name(&min_stat, &send_tok, (gss_OID)gss_nt_service_name, &target_name); if (maj_stat != GSS_S_COMPLETE) { display_status("parsing name", maj_stat, min_stat); return -1; } if (!v1_format) { if (send_token(s, TOKEN_NOOP | TOKEN_CONTEXT_NEXT, empty_token) < 0) { (void)gss_release_name(&min_stat, &target_name); return -1; } } /* * Perform the context-establishement loop. * * On each pass through the loop, token_ptr points to the token * to send to the server (or GSS_C_NO_BUFFER on the first pass). * Every generated token is stored in send_tok which is then * transmitted to the server; every received token is stored in * recv_tok, which token_ptr is then set to, to be processed by * the next call to gss_init_sec_context. * * GSS-API guarantees that send_tok's length will be non-zero * if and only if the server is expecting another token from us, * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if * and only if the server has another token to send us. */ token_ptr = GSS_C_NO_BUFFER; *gss_context = GSS_C_NO_CONTEXT; do { maj_stat = gss_init_sec_context(&init_sec_min_stat, GSS_C_NO_CREDENTIAL, gss_context, target_name, oid, gss_flags, 0, NULL, token_ptr, NULL, &send_tok, ret_flags, NULL); if (token_ptr != GSS_C_NO_BUFFER) free(recv_tok.value); if (send_tok.length != 0) { if (verbose) { printf("Sending init_sec_context token (size=%d)...", (int)send_tok.length); } if (send_token(s, v1_format ? 0 : TOKEN_CONTEXT, &send_tok) < 0) { (void)gss_release_buffer(&min_stat, &send_tok); (void)gss_release_name(&min_stat, &target_name); if (*gss_context != GSS_C_NO_CONTEXT) { gss_delete_sec_context(&min_stat, gss_context, GSS_C_NO_BUFFER); *gss_context = GSS_C_NO_CONTEXT; } return -1; } } (void)gss_release_buffer(&min_stat, &send_tok); if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { display_status("initializing context", maj_stat, init_sec_min_stat); (void)gss_release_name(&min_stat, &target_name); if (*gss_context != GSS_C_NO_CONTEXT) { gss_delete_sec_context(&min_stat, gss_context, GSS_C_NO_BUFFER); } return -1; } if (maj_stat == GSS_S_CONTINUE_NEEDED) { if (verbose) printf("continue needed..."); if (recv_token(s, &token_flags, &recv_tok) < 0) { (void)gss_release_name(&min_stat, &target_name); return -1; } token_ptr = &recv_tok; } if (verbose) printf("\n"); } while (maj_stat == GSS_S_CONTINUE_NEEDED); (void)gss_release_name(&min_stat, &target_name); } else if (send_token(s, TOKEN_NOOP, empty_token) < 0) { return -1; } return 0; } static void read_file(char *file_name, gss_buffer_t in_buf) { int fd, count; struct stat stat_buf; fd = open(file_name, O_RDONLY, 0); if (fd < 0) { perror("open"); fprintf(stderr, "Couldn't open file %s\n", file_name); exit(2); } if (fstat(fd, &stat_buf) < 0) { perror("fstat"); exit(3); } in_buf->length = stat_buf.st_size; if (in_buf->length == 0) { in_buf->value = NULL; return; } in_buf->value = malloc(in_buf->length); if (in_buf->value == NULL) { fprintf(stderr, "Couldn't allocate %d byte buffer for reading file\n", (int)in_buf->length); exit(4); } /* This code used to check for incomplete reads, but you can't get * an incomplete read on any file for which fstat() is meaningful. */ count = read(fd, in_buf->value, in_buf->length); if (count < 0) { perror("read"); exit(5); } if ((size_t)count < in_buf->length) { fprintf(stderr, "Warning, only read in %d bytes, expected %d\n", count, (int)in_buf->length); } } /* * Function: call_server * * Purpose: Call the "sign" service. * * Arguments: * * host (r) the host providing the service * port (r) the port to connect to on host * service_name (r) the GSS-API service name to authenticate to * gss_flags (r) GSS-API delegation flag (if any) * auth_flag (r) whether to do authentication * wrap_flag (r) whether to do message wrapping at all * encrypt_flag (r) whether to do encryption while wrapping * mic_flag (r) whether to request a MIC from the server * msg (r) the message to have "signed" * use_file (r) whether to treat msg as an input file name * mcount (r) the number of times to send the message * * Returns: 0 on success, -1 on failure * * Effects: * * call_server opens a TCP connection to and establishes a * GSS-API context with service_name over the connection. It then * seals msg in a GSS-API token with gss_wrap, sends it to the server, * reads back a GSS-API signature block for msg from the server, and * verifies it with gss_verify. -1 is returned if any step fails, * otherwise 0 is returned. */ static int call_server(char *host, u_short port, gss_OID oid, char *service_name, OM_uint32 gss_flags, int auth_flag, int wrap_flag, int encrypt_flag, int mic_flag, int v1_format, char *msg, int use_file, size_t mcount) { gss_ctx_id_t context; gss_buffer_desc in_buf, out_buf, sname, tname, oid_name; int s, state, is_local, is_open, flags, token_flags; OM_uint32 ret_flags, maj_stat, min_stat, lifetime, context_flags; gss_name_t src_name, targ_name; gss_OID mechanism, name_type; gss_qop_t qop_state; gss_OID_set mech_names; size_t i; /* Open connection. */ s = connect_to_server(); if (s < 0) return -1; /* Establish context. */ if (client_establish_context(s, service_name, gss_flags, auth_flag, v1_format, oid, &context, &ret_flags) < 0) { (void)closesocket(s); return -1; } if (auth_flag && verbose) { /* Display the flags. */ display_ctx_flags(ret_flags); /* Get context information. */ maj_stat = gss_inquire_context(&min_stat, context, &src_name, &targ_name, &lifetime, &mechanism, &context_flags, &is_local, &is_open); if (maj_stat != GSS_S_COMPLETE) { display_status("inquiring context", maj_stat, min_stat); return -1; } maj_stat = gss_display_name(&min_stat, src_name, &sname, &name_type); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying source name", maj_stat, min_stat); return -1; } maj_stat = gss_display_name(&min_stat, targ_name, &tname, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("displaying target name", maj_stat, min_stat); return -1; } printf("\"%.*s\" to \"%.*s\", lifetime %d, flags %x, %s, %s\n", (int)sname.length, (char *)sname.value, (int)tname.length, (char *)tname.value, lifetime, context_flags, is_local ? "locally initiated" : "remotely initiated", is_open ? "open" : "closed"); (void)gss_release_name(&min_stat, &src_name); (void)gss_release_name(&min_stat, &targ_name); (void)gss_release_buffer(&min_stat, &sname); (void)gss_release_buffer(&min_stat, &tname); maj_stat = gss_oid_to_str(&min_stat, name_type, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } printf("Name type of source name is %.*s.\n", (int)oid_name.length, (char *)oid_name.value); (void)gss_release_buffer(&min_stat, &oid_name); /* Now get the names supported by the mechanism. */ maj_stat = gss_inquire_names_for_mech(&min_stat, mechanism, &mech_names); if (maj_stat != GSS_S_COMPLETE) { display_status("inquiring mech names", maj_stat, min_stat); return -1; } maj_stat = gss_oid_to_str(&min_stat, mechanism, &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } printf("Mechanism %.*s supports %d names\n", (int)oid_name.length, (char *)oid_name.value, (int)mech_names->count); (void)gss_release_buffer(&min_stat, &oid_name); for (i = 0; i < mech_names->count; i++) { maj_stat = gss_oid_to_str(&min_stat, &mech_names->elements[i], &oid_name); if (maj_stat != GSS_S_COMPLETE) { display_status("converting oid->string", maj_stat, min_stat); return -1; } printf(" %d: %.*s\n", (int)i, (int)oid_name.length, (char *)oid_name.value); (void)gss_release_buffer(&min_stat, &oid_name); } (void)gss_release_oid_set(&min_stat, &mech_names); } if (use_file) { read_file(msg, &in_buf); } else { /* Seal the message. */ in_buf.value = msg; in_buf.length = strlen(msg); } for (i = 0; i < mcount; i++) { if (wrap_flag) { maj_stat = gss_wrap(&min_stat, context, encrypt_flag, GSS_C_QOP_DEFAULT, &in_buf, &state, &out_buf); if (maj_stat != GSS_S_COMPLETE) { display_status("wrapping message", maj_stat, min_stat); (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } else if (encrypt_flag && !state) { fprintf(stderr, "Warning! Message not encrypted.\n"); } } else { out_buf = in_buf; } /* Send to server. */ flags = 0; if (!v1_format) { flags = TOKEN_DATA | (wrap_flag ? TOKEN_WRAPPED : 0) | (encrypt_flag ? TOKEN_ENCRYPTED : 0) | (mic_flag ? TOKEN_SEND_MIC : 0); } if (send_token(s, flags, &out_buf) < 0) { (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } if (out_buf.value != in_buf.value) (void)gss_release_buffer(&min_stat, &out_buf); /* Read signature block into out_buf. */ if (recv_token(s, &token_flags, &out_buf) < 0) { (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } if (mic_flag) { /* Verify signature block. */ maj_stat = gss_verify_mic(&min_stat, context, &in_buf, &out_buf, &qop_state); if (maj_stat != GSS_S_COMPLETE) { display_status("verifying signature", maj_stat, min_stat); (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } if (verbose) printf("Signature verified.\n"); } else if (verbose) { printf("Response received.\n"); } free(out_buf.value); } if (use_file) free(in_buf.value); /* Send NOOP. */ if (!v1_format) (void)send_token(s, TOKEN_NOOP, empty_token); if (auth_flag) { /* Delete context. */ maj_stat = gss_delete_sec_context(&min_stat, &context, &out_buf); if (maj_stat != GSS_S_COMPLETE) { display_status("deleting context", maj_stat, min_stat); (void)closesocket(s); (void)gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER); return -1; } (void)gss_release_buffer(&min_stat, &out_buf); } (void)closesocket(s); return 0; } static void parse_oid(char *mechanism, gss_OID *oid) { char *mechstr = 0, *cp; gss_buffer_desc tok; OM_uint32 maj_stat, min_stat; if (isdigit((unsigned char)mechanism[0])) { if (asprintf(&mechstr, "{ %s }", mechanism) < 0) { fprintf(stderr, "Couldn't allocate mechanism scratch!\n"); return; } for (cp = mechstr; *cp; cp++) { if (*cp == '.') *cp = ' '; } tok.value = mechstr; } else { tok.value = mechanism; } tok.length = strlen(tok.value); maj_stat = gss_str_to_oid(&min_stat, &tok, oid); if (maj_stat != GSS_S_COMPLETE) { display_status("str_to_oid", maj_stat, min_stat); return; } if (mechstr) free(mechstr); } static int max_threads = 1; #ifdef _WIN32 static thread_count = 0; static HANDLE hMutex = NULL; static HANDLE hEvent = NULL; void init_handles(void) { hMutex = CreateMutex(NULL, FALSE, NULL); hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); } void cleanup_handles(void) { CloseHandle(hMutex); CloseHandle(hEvent); } BOOL wait_and_increment_thread_counter(void) { for (;;) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count < max_threads) { thread_count++; ReleaseMutex(hMutex); return TRUE; } else { ReleaseMutex(hMutex); if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) continue; else return FALSE; } } else { return FALSE; } } } BOOL decrement_and_signal_thread_counter(void) { if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { if (thread_count == max_threads) SetEvent(hEvent); thread_count--; ReleaseMutex(hMutex); return TRUE; } else { return FALSE; } } #else /* assume pthread */ static pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t counter_cond = PTHREAD_COND_INITIALIZER; int counter = 0; static int wait_and_increment_thread_counter(void) { int err; err = pthread_mutex_lock(&counter_mutex); if (err) { perror("pthread_mutex_lock"); return 0; } if (counter == max_threads) { err = pthread_cond_wait(&counter_cond, &counter_mutex); if (err) { pthread_mutex_unlock(&counter_mutex); perror("pthread_cond_wait"); return 0; } } counter++; pthread_mutex_unlock(&counter_mutex); return 1; } static void decrement_and_signal_thread_counter(void) { int err; sleep(1); err = pthread_mutex_lock(&counter_mutex); if (err) { perror("pthread_mutex_lock"); return; } if (counter == max_threads) pthread_cond_broadcast(&counter_cond); counter--; pthread_mutex_unlock(&counter_mutex); } #endif static char *service_name, *server_host, *msg; static char *mechanism = 0; static u_short port = 4444; static int use_file = 0; static OM_uint32 gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; static OM_uint32 min_stat; static gss_OID oid = GSS_C_NULL_OID; static int mcount = 1, ccount = 1; static int auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format; static void * worker_bee(void *unused) { printf("worker bee!\n"); if (call_server(server_host, port, oid, service_name, gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format, msg, use_file, mcount) < 0) { if (max_threads == 1) exit(6); } if (max_threads > 1) decrement_and_signal_thread_counter(); free(unused); return NULL; } int main(int argc, char **argv) { int i; display_file = stdout; auth_flag = wrap_flag = encrypt_flag = mic_flag = 1; v1_format = 0; /* Parse arguments. */ argc--; argv++; while (argc) { if (strcmp(*argv, "-port") == 0) { argc--; argv++; if (!argc) usage(); port = atoi(*argv); } else if (strcmp(*argv, "-mech") == 0) { argc--; argv++; if (!argc) usage(); mechanism = *argv; } else if (strcmp(*argv, "-threads") == 0) { argc--; argv++; if (!argc) usage(); max_threads = atoi(*argv); } else if (strcmp(*argv, "-d") == 0) { gss_flags |= GSS_C_DELEG_FLAG; } else if (strcmp(*argv, "-seq") == 0) { gss_flags |= GSS_C_SEQUENCE_FLAG; } else if (strcmp(*argv, "-noreplay") == 0) { gss_flags &= ~GSS_C_REPLAY_FLAG; } else if (strcmp(*argv, "-nomutual") == 0) { gss_flags &= ~GSS_C_MUTUAL_FLAG; } else if (strcmp(*argv, "-f") == 0) { use_file = 1; } else if (strcmp(*argv, "-q") == 0) { verbose = 0; } else if (strcmp(*argv, "-ccount") == 0) { argc--; argv++; if (!argc) usage(); ccount = atoi(*argv); if (ccount <= 0) usage(); } else if (strcmp(*argv, "-mcount") == 0) { argc--; argv++; if (!argc) usage(); mcount = atoi(*argv); if (mcount < 0) usage(); } else if (strcmp(*argv, "-na") == 0) { auth_flag = wrap_flag = encrypt_flag = mic_flag = 0; } else if (strcmp(*argv, "-nw") == 0) { wrap_flag = 0; } else if (strcmp(*argv, "-nx") == 0) { encrypt_flag = 0; } else if (strcmp(*argv, "-nm") == 0) { mic_flag = 0; } else if (strcmp(*argv, "-v1") == 0) { v1_format = 1; } else { break; } argc--; argv++; } if (argc != 3) usage(); #ifdef _WIN32 if (max_threads < 1) { fprintf(stderr, "warning: there must be at least one thread\n"); max_threads = 1; } init_handles(); SetEnvironmentVariable("KERBEROSLOGIN_NEVER_PROMPT", "1"); #endif server_host = *argv++; service_name = *argv++; msg = *argv++; if (mechanism) parse_oid(mechanism, &oid); if (get_server_info(server_host, port) < 0) exit(1); if (max_threads == 1) { for (i = 0; i < ccount; i++) worker_bee(0); } else { for (i = 0; i < ccount; i++) { if (wait_and_increment_thread_counter()) { #ifdef _WIN32 uintptr_t handle = _beginthread(worker_bee, 0, (void *)NULL); if (handle == (uintptr_t)-1) exit(7); #else int err; pthread_t thr; err = pthread_create(&thr, 0, worker_bee, malloc(12)); if (err) { perror("pthread_create"); exit(7); } (void)pthread_detach(thr); #endif } else { exit(8); } } } if (oid != GSS_C_NULL_OID) (void)gss_release_oid(&min_stat, &oid); #ifdef _WIN32 cleanup_handles(); #else if (max_threads > 1) sleep(10); #endif return 0; } krb5-1.22.1/src/tests/icinterleave.c0000664000175000017500000001020515051422640017106 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/icinterleave.c - interleaved init_creds_step test harness */ /* * Copyright (C) 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This test harness performs multiple initial creds operations using * krb5_init_creds_step(), interleaving the operations to test the scoping of * the preauth state. All principals must have the same password (or not * require a password). */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { const char *password; char **princstrs; krb5_principal client; krb5_init_creds_context *iccs; krb5_data req, *reps, realm; krb5_boolean any_left; int i, nclients, primary; unsigned int flags; if (argc < 3) { fprintf(stderr, "Usage: icinterleave password princ1 princ2 ...\n"); exit(1); } password = argv[1]; princstrs = argv + 2; nclients = argc - 2; check(krb5_init_context(&ctx)); /* Create an initial creds context for each client principal. */ iccs = calloc(nclients, sizeof(*iccs)); assert(iccs != NULL); for (i = 0; i < nclients; i++) { check(krb5_parse_name(ctx, princstrs[i], &client)); check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, &iccs[i])); check(krb5_init_creds_set_password(ctx, iccs[i], password)); krb5_free_principal(ctx, client); } reps = calloc(nclients, sizeof(*reps)); assert(reps != NULL); any_left = TRUE; while (any_left) { any_left = FALSE; for (i = 0; i < nclients; i++) { if (iccs[i] == NULL) continue; any_left = TRUE; printf("step %d\n", i + 1); req = empty_data(); realm = empty_data(); check(krb5_init_creds_step(ctx, iccs[i], &reps[i], &req, &realm, &flags)); if (!(flags & KRB5_INIT_CREDS_STEP_FLAG_CONTINUE)) { printf("finish %d\n", i + 1); krb5_init_creds_free(ctx, iccs[i]); iccs[i] = NULL; continue; } primary = 0; krb5_free_data_contents(ctx, &reps[i]); check(krb5_sendto_kdc(ctx, &req, &realm, &reps[i], &primary, 0)); krb5_free_data_contents(ctx, &req); krb5_free_data_contents(ctx, &realm); } } for (i = 0; i < nclients; i++) krb5_free_data_contents(ctx, &reps[i]); free(reps); free(iccs); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/t_kprop.py0000775000175000017500000001220015051422640016320 0ustar ghudsonghudsonfrom k5test import * conf_replica = {'dbmodules': {'db': {'database_name': '$testdir/db.replica'}}} def setup_acl(realm): acl_file = os.path.join(realm.testdir, 'kpropd-acl') acl = open(acl_file, 'w') acl.write(realm.host_princ + '\n') acl.close() def check_output(kpropd): output('*** kpropd output follows\n') while True: line = kpropd.stdout.readline() if 'Database load process for full propagation completed' in line: break output('kpropd: ' + line) if 'Rejected connection' in line: fail('kpropd rejected connection from kprop') # kprop/kpropd are the only users of krb5_auth_con_initivector, so run # this test over all enctypes to exercise mkpriv cipher state. for realm in multipass_realms(create_user=False): replica = realm.special_env('replica', True, kdc_conf=conf_replica) # Set up the kpropd acl file. setup_acl(realm) # Create the replica db. dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile], replica) realm.run([kdb5_util, 'stash', '-P', 'master'], replica) # Make some changes to the primary db. realm.addprinc('wakawaka') # Start kpropd. kpropd = realm.start_kpropd(replica, ['-d']) realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) check_output(kpropd) realm.run([kadminl, 'listprincs'], replica, expected_msg='wakawaka') # default_realm tests follow. # default_realm and domain_realm different than realm.realm (test -r argument). conf_rep2 = {'dbmodules': {'db': {'database_name': '$testdir/db.replica2'}}} krb5_conf_rep2 = {'libdefaults': {'default_realm': 'FOO'}, 'domain_realm': {hostname: 'FOO'}} # default_realm and domain_realm map differ. conf_rep3 = {'dbmodules': {'db': {'database_name': '$testdir/db.replica3'}}} krb5_conf_rep3 = {'domain_realm': {hostname: 'BAR'}} realm = K5Realm(create_user=False) replica2 = realm.special_env('replica2', True, kdc_conf=conf_rep2, krb5_conf=krb5_conf_rep2) replica3 = realm.special_env('replica3', True, kdc_conf=conf_rep3, krb5_conf=krb5_conf_rep3) setup_acl(realm) # Create the replica db. dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, '-r', realm.realm, 'load', dumpfile], replica2) realm.run([kdb5_util, 'load', dumpfile], replica3) # Make some changes to the primary db. realm.addprinc('wakawaka') # Test override of default_realm with -r realm argument. kpropd = realm.start_kpropd(replica2, ['-r', realm.realm, '-d']) realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kprop, '-r', realm.realm, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) check_output(kpropd) realm.run([kadminl, '-r', realm.realm, 'listprincs'], replica2, expected_msg='wakawaka') stop_daemon(kpropd) # Test default_realm and domain_realm mismatch. kpropd = realm.start_kpropd(replica3, ['-d']) realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) check_output(kpropd) realm.run([kadminl, 'listprincs'], replica3, expected_msg='wakawaka') stop_daemon(kpropd) # This test is too resource-intensive to be included in "make check" # by default, but it can be enabled in the environment to test the # propagation of databases large enough to require a 12-byte encoding # of the database size. if 'KPROP_LARGE_DB_TEST' in os.environ: output('Generating >4GB dumpfile\n') with open(dumpfile, 'w') as f: f.write('kdb5_util load_dump version 6\n') f.write('princ\t38\t15\t3\t1\t0\tK/M@KRBTEST.COM\t64\t86400\t0\t0\t0' '\t0\t0\t0\t8\t2\t0100\t9\t8\t0100010000000000\t2\t28' '\tb93e105164625f6372656174696f6e404b5242544553542e434f4d00' '\t1\t1\t18\t62\t2000408c027c250e8cc3b81476414f2214d57c1ce' '38891e29792e87258247c73547df4d5756266931dd6686b62270e6568' '95a31ec66bfe913b4f15226227\t-1;\n') for i in range(1, 20000000): f.write('princ\t38\t21\t1\t1\t0\tp%08d@KRBTEST.COM' % i) f.write('\t0\t86400\t0\t0\t0\t0\t0\t0\t2\t27' '\td73e1051757365722f61646d696e404b5242544553542e434f4d00' '\t1\t1\t17\t46' '\t10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c49' '5605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf\t-1;\n') assert os.path.getsize(dumpfile) > 4 * 1024 * 1024 * 1024 with open(dumpfile + '.dump_ok', 'w') as f: f.write('\0') conf_large = {'dbmodules': {'db': {'database_name': '$testdir/db.large'}}, 'realms': {'$realm': {'iprop_resync_timeout': '3600'}}} large = realm.special_env('large', True, kdc_conf=conf_large) kpropd = realm.start_kpropd(large, ['-d']) realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) check_output(kpropd) realm.run([kadminl, 'getprinc', 'p19999999'], env=large, expected_msg='Principal: p19999999') success('kprop tests') krb5-1.22.1/src/tests/t_rdreq.py0000775000175000017500000001174515051422640016317 0ustar ghudsonghudsonfrom k5test import * conf = {'realms': {'$realm': {'supported_enctypes': 'aes256-cts aes128-cts'}}} realm = K5Realm(create_host=False, kdc_conf=conf) # Define some server principal names. princ1 = 'host/1@%s' % realm.realm princ2 = 'host/2@%s' % realm.realm princ3 = 'HTTP/3@%s' % realm.realm princ4 = 'HTTP/4@%s' % realm.realm matchprinc = 'host/@' nomatchprinc = 'x/@' realm.addprinc(princ1) realm.addprinc(princ2) realm.addprinc(princ3) def test(tserver, server, expected): args = ['./rdreq', tserver] if server is not None: args += [server] out = realm.run(args) if out.strip() != expected: fail('unexpected rdreq output') # No keytab present. mark('no keytab') nokeytab_err = "45 Key table file '%s' not found" % realm.keytab test(princ1, None, nokeytab_err) test(princ1, princ1, nokeytab_err) test(princ1, matchprinc, nokeytab_err) # Keytab present, successful decryption. mark('success') realm.extract_keytab(princ1, realm.keytab) test(princ1, None, '0 success') test(princ1, princ1, '0 success') test(princ1, matchprinc, '0 success') # Explicit server principal not found in keytab. mark('explicit server not found') test(princ2, princ2, '45 No key table entry found for host/2@KRBTEST.COM') # Matching server principal does not match any entries in keytab (with # and without ticket server present in keytab). mark('matching server') nomatch_err = '45 Server principal x/@ does not match any keys in keytab' test(princ1, nomatchprinc, nomatch_err) test(princ2, nomatchprinc, nomatch_err) # Ticket server does not match explicit server principal (with and # without ticket server present in keytab). mark('ticket server mismatch') test(princ1, princ2, '45 No key table entry found for host/2@KRBTEST.COM') test(princ2, princ1, '35 Cannot decrypt ticket for host/2@KRBTEST.COM using keytab key for ' 'host/1@KRBTEST.COM') # Ticket server not found in keytab during iteration. mark('ticket server not found') test(princ2, None, '35 Request ticket server host/2@KRBTEST.COM not found in keytab ' '(ticket kvno 1)') # Ticket server found in keytab but is not matched by server principal # (but other principals in keytab do match). mark('ticket server mismatch (matching)') realm.extract_keytab(princ3, realm.keytab) test(princ3, matchprinc, '35 Request ticket server HTTP/3@KRBTEST.COM found in keytab but does ' 'not match server principal host/@') # Service ticket is out of date. mark('outdated service ticket') os.remove(realm.keytab) realm.run([kadminl, 'ktadd', princ1]) test(princ1, None, '44 Request ticket server host/1@KRBTEST.COM kvno 1 not found in keytab; ' 'ticket is likely out of date') test(princ1, princ1, '44 Cannot find key for host/1@KRBTEST.COM kvno 1 in keytab') # kvno mismatch due to ticket principal mismatch with explicit server. mark('ticket server mismatch (kvno)') test(princ2, princ1, '35 Cannot find key for host/1@KRBTEST.COM kvno 1 in keytab (request ' 'ticket server host/2@KRBTEST.COM)') # Keytab is out of date. mark('outdated keytab') realm.run([kadminl, 'cpw', '-randkey', princ1]) realm.kinit(realm.user_princ, password('user')) test(princ1, None, '44 Request ticket server host/1@KRBTEST.COM kvno 3 not found in keytab; ' 'keytab is likely out of date') test(princ1, princ1, '44 Cannot find key for host/1@KRBTEST.COM kvno 3 in keytab') # Ticket server and kvno found but not with ticket enctype. mark('missing enctype') os.remove(realm.keytab) realm.extract_keytab(princ1, realm.keytab) pkeytab = realm.keytab + '.partial' realm.run([ktutil], input=('rkt %s\ndelent 1\nwkt %s\n' % (realm.keytab, pkeytab))) os.rename(pkeytab, realm.keytab) realm.run([klist, '-ke']) test(princ1, None, '44 Request ticket server host/1@KRBTEST.COM kvno 3 found in keytab but ' 'not with enctype aes256-cts') # This is a bad code (KRB_AP_ERR_NOKEY) and message, because # krb5_kt_get_entry returns the same result for this and not finding # the principal at all. But it's an uncommon case; GSSAPI apps # usually use a matching principal and missing key enctypes are rare. test(princ1, princ1, '45 No key table entry found for host/1@KRBTEST.COM') # Ticket server, kvno, and enctype matched, but key does not work. mark('wrong key') realm.run([kadminl, 'cpw', '-randkey', princ1]) realm.run([kadminl, 'modprinc', '-kvno', '3', princ1]) os.remove(realm.keytab) realm.extract_keytab(princ1, realm.keytab) test(princ1, None, '31 Request ticket server host/1@KRBTEST.COM kvno 3 enctype aes256-cts ' 'found in keytab but cannot decrypt ticket') test(princ1, princ1, '31 Cannot decrypt ticket for host/1@KRBTEST.COM using keytab key for ' 'host/1@KRBTEST.COM') # Test that aliases work. The ticket server (princ4) isn't present in # keytab, but there is a usable princ1 entry with the same key. mark('aliases') realm.run([kadminl, 'renprinc', princ1, princ4]) test(princ4, None, '0 success') test(princ4, princ1, '0 success') test(princ4, matchprinc, '0 success') success('krb5_rd_req tests') krb5-1.22.1/src/tests/dumpfiles/0000775000175000017500000000000015051422640016262 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/dumpfiles/dump.160000664000175000017500000000415715051422640017406 0ustar ghudsonghudsonkdb5_util load_dump version 5 princ 38 15 1 1 0 K/M@KRBTEST.COM 64 36000 604800 0 0 0 0 0 2 28 18de675264625f6372656174696f6e404b5242544553542e434f4d00 1 1 16 54 180001361a6c58b3a273e484574c6c5739fb114ffe7d2298e767b545f332e3bda573021c97728028e7ec4942708f23f4445d4419f4ad -1; princ 38 24 3 2 0 kadmin/admin@KRBTEST.COM 4 10800 604800 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 18de67526b6462355f7574696c404b5242544553542e434f4d00 1 4 18de6752 1 2 16 54 1800555ff1892cdb7dd7c62b659f9659981205ebb4f9fd4446e5243f58dfc0b99a4f096080d435702e052793a90c66aea062c8b8964e 1 2 1 38 0800ca62598d281381a22fc6d5bdf25653002b6afeb8f24af6ea01c9301359527304a08bb8f5 -1; princ 38 27 3 2 0 kadmin/changepw@KRBTEST.COM 8196 300 604800 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 18de67526b6462355f7574696c404b5242544553542e434f4d00 1 4 18de6752 1 2 16 54 1800237a5df1fc3295e08ba18986f51f553c2d0dfff3fb8e17d19ac7777a1cd516713e5496521ba362261ab61c063090705ecf7bca01 1 2 1 38 0800685d1f82188b712b2947b63a259269b1fe53bf383bb05cdc802e2cb9d680631e512af4d4 -1; princ 38 38 3 2 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 604800 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 18de67526b6462355f7574696c404b5242544553542e434f4d00 1 4 18de6752 1 2 16 54 1800ed9ad2e91940a41abc9b05d7dfb736c353e3ff18272b1d3bc31e5ebc3204e15d5fd9c3caa0c57be4736831b6f03c1741d5423ff1 1 2 1 38 0800eb82c30aa8e1f5a10f0f099372e2ff3385cb5437b41abee02491673cf45c79b2c4466364 -1; princ 38 26 3 1 0 kadmin/history@KRBTEST.COM 0 64 604800 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 18de67526b6462355f7574696c404b5242544553542e434f4d00 1 4 18de6752 1 2 16 54 180070b4f132c63aa7d8b91f1323daa8d59bf2e04663b9b8931bcbe9a953c4fab6dda7c820db0cf9922af5ebfb7bd09101849e81f054 -1; princ 38 30 1 2 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 36000 604800 0 0 0 0 0 2 28 18de675264625f6372656174696f6e404b5242544553542e434f4d00 1 1 16 54 1800010572e45515fc5ee028a59a48bc86896ab5014c265304b2340d37a46c0185312e475e9245e70df0f6874c9348a2ca4389c7168f 1 1 1 38 0800d8b88190a5e7f49cdca68c0e018bafd971f1606f9af2f2e3d9e31c69071556896443ade2 -1; krb5-1.22.1/src/tests/dumpfiles/dump.b70000664000175000017500000001123115051422640017457 0ustar ghudsonghudsonkdb5_util load_dump version 4 princ 38 15 3 1 0 K/M@KRBTEST.COM 64 86400 0 0 0 0 0 0 8 2 0100 9 8 0100010000000000 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000408c027c250e8cc3b81476414f2214d57c1ce38891e29792e87258247c73547df4d5756266931dd6686b62270e656895a31ec66bfe913b4f15226227 -1; princ 38 36 3 4 0 host/equal-rites.mit.edu@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20009b7f9e9edd44559c5ffb2b52beb92e57586f9bdf59ae0be7010ffa8b628928bebc7d6015211977bc34325be853e5f1eb5826ce75575414bc2696bc16 1 1 17 46 10001bfaf4d8ddd6e8767194a190e9dec2617dbc90883db767fa464325b76b97ea98f3b61c4d4234ff9aee6314a4 1 1 16 54 18008291ce8c2ccde958c2739e93ce499b088b1b8c304bce95097bd6c1bd92c3c9f64e92950767f7806d890b386ba586fdb7f8433f1c 1 1 23 46 1000a460520a9e39b1539e703a51793967247999a9a0bb7c59a61ca2b5e64a58c3b9cf8217daeddd71caae9d7fbb -1; princ 38 24 3 4 0 kadmin/admin@KRBTEST.COM 4 10800 0 0 0 0 0 0 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20005ea70b11f3337975c5463baedc68b234cadf72f89828d98e3c16cb8640bba7c5ed48a4bcf7649a73a9a410e96234924bfacd4bb38f08982db02c5c5b 1 1 17 46 10001b678f8b9bb6913397202c259702c1941fd5d2892f42349a92ca908de248cd041465bb3d16d27efce1f63e30 1 1 16 54 18009ed81fe14b19549918acad7b1158b86f5971ab3bd77b2359c29147af35730167210157e510dda65f691c312ac398850d7e228c40 1 1 23 46 10001d15a249bbea104208ae0b3d83337d4c06f6edef6a6ac60ec3df7b52aeeeb388c7233a9b1e3de646949ed540 -1; princ 38 27 3 4 0 kadmin/changepw@KRBTEST.COM 8196 300 0 0 0 0 0 0 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200015daf7bc8073eae166b03231330b81b78cfd6021d3dcf3700862dc98725c5bb549a72aa2ae8eef37dc2db5acc59cc62600f72052c6238ef216dd24a5 1 1 17 46 1000c1e176f253d6292fe4e34b2edfbdd5ff81ff3e17b38c2a674bd738d20fc40a4ed38a02351f4a9872123fb865 1 1 16 54 18008bf3418871e7d117af489798fbbcc031c534e095b4e4ed6cb110c7d87a91e5fb6c080c77616618db80ed37589fcc0ca8328406ef 1 1 23 46 10007a522025d2e7126dc48d76218e9efb3ff4326a3b5969be0deac108657a9d23c7827ec39b828fd43e51ea114b -1; princ 38 38 3 4 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 0 0 0 0 0 0 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200045a2e5b79c5787bfc68700d3abc0034cc91d48f10636c35e1a571c41c4e6892caceeda8808bfa46aa4050a6d33d99cb64d237f645af6741e90c723ff 1 1 17 46 100073b99fecd81b4fe113b10852065c15e75ed7d256d2d242b3cca57317c28c7fece4bda797f116309ea5bc2eb1 1 1 16 54 1800bd05672170b5d04cb62394498988f3844b744a0793ac435d044e67ed0ee50d20c408b30cec599c169378b0ad2a4967f42aef38e5 1 1 23 46 1000a1a515e0fe322980f319752bf85dd405ca2bdda148009654584b70f50d38c532df1c2d0a3c56f9758775b007 -1; princ 38 30 1 4 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000582c9aaf26c4a0abf13600baf37718c91e15dca02385e346cf5d2730d28b2302677f23d02791299548b45e1ced0b05cd30062617bff7532885d7889c 1 1 17 46 1000122eb47263d7837771ebbf7ad82163cc2ea7674a417944c0cbf186522fc0e74a73affd4a42fb9fda287be4f8 1 1 16 54 18008cd8064aea468f13f36ae13ecd4f993d87ef6bafcb2dc5101ad903200ffe3d5c265b2f0c71a6c07ec60d259b6862825cc77a70b2 1 1 23 46 10001699ad0304644456106328fbd733bd5c524f20d4b5d8b8e370eff196803b5990ee7e9eb4b6c2214cf327f59b -1; princ 38 18 3 0 0 nokeys@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 27 d931dc51757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 d931dc51 -1; princ 38 22 3 4 0 user/admin@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20002db4cd2b0824c44a17cdbb2d180a1ec9956db35d74741826ed0d77eaef9abdb20c481d5ab9f511d5a3e6b8def443382f03d247568d81529e5dd17fae 1 1 17 46 100011d7cc3627468d565d398cffd735a3cc9d3705cd9846cede198c7d07f4e8209cd9192bc6c5f127169c00f373 1 1 16 54 18002bd9dc3388c90055844b3b4c5c2a814d73758f226d44d7dc5e35ef3b65e7d80cd604a4ef2a5769106818c3d813956bbad1813cb2 1 1 23 46 1000409681c3ff356fb7d28a9f71957c3465ea42ec4eee5019a662f7d367042527b76ae783cfbd0dccbd7529d090 -1; princ 38 16 3 4 0 user@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 27 d73e1051757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 2000aec451aae295389f92d177e61b5154941386c70d75d382393e556dfa61bd77d112a777420a99030b56649d366bba83a5c40aa17fa4522222d2e78e10 1 1 17 46 10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c495605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf 1 1 16 54 18002b87a46d6c4de954a316b5ce28a99886f2abb6b0307190e577b81171dfb7a067139835be8625bc36b0edaaed357609107d85d335 1 1 23 46 1000c01fcdb3050a2270f82dbafbe4c1adc868377bf7133ee7a1bcaf85817abe541beb8008b91c54b99e93d2e0f5 -1; policy testpol 0 0 1 3 1 0 krb5-1.22.1/src/tests/dumpfiles/dump0000664000175000017500000001206315051422640017154 0ustar ghudsonghudsonkdb5_util load_dump version 7 princ 38 15 3 1 0 K/M@KRBTEST.COM 64 86400 0 0 0 0 0 0 8 2 0100 9 8 0100010000000000 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000408c027c250e8cc3b81476414f2214d57c1ce38891e29792e87258247c73547df4d5756266931dd6686b62270e656895a31ec66bfe913b4f15226227 -1; princ 38 36 4 4 0 host/equal-rites.mit.edu@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20009b7f9e9edd44559c5ffb2b52beb92e57586f9bdf59ae0be7010ffa8b628928bebc7d6015211977bc34325be853e5f1eb5826ce75575414bc2696bc16 1 1 17 46 10001bfaf4d8ddd6e8767194a190e9dec2617dbc90883db767fa464325b76b97ea98f3b61c4d4234ff9aee6314a4 1 1 16 54 18008291ce8c2ccde958c2739e93ce499b088b1b8c304bce95097bd6c1bd92c3c9f64e92950767f7806d890b386ba586fdb7f8433f1c 1 1 23 46 1000a460520a9e39b1539e703a51793967247999a9a0bb7c59a61ca2b5e64a58c3b9cf8217daeddd71caae9d7fbb -1; princ 38 24 4 4 0 kadmin/admin@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20005ea70b11f3337975c5463baedc68b234cadf72f89828d98e3c16cb8640bba7c5ed48a4bcf7649a73a9a410e96234924bfacd4bb38f08982db02c5c5b 1 1 17 46 10001b678f8b9bb6913397202c259702c1941fd5d2892f42349a92ca908de248cd041465bb3d16d27efce1f63e30 1 1 16 54 18009ed81fe14b19549918acad7b1158b86f5971ab3bd77b2359c29147af35730167210157e510dda65f691c312ac398850d7e228c40 1 1 23 46 10001d15a249bbea104208ae0b3d83337d4c06f6edef6a6ac60ec3df7b52aeeeb388c7233a9b1e3de646949ed540 -1; princ 38 27 4 4 0 kadmin/changepw@KRBTEST.COM 8196 300 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200015daf7bc8073eae166b03231330b81b78cfd6021d3dcf3700862dc98725c5bb549a72aa2ae8eef37dc2db5acc59cc62600f72052c6238ef216dd24a5 1 1 17 46 1000c1e176f253d6292fe4e34b2edfbdd5ff81ff3e17b38c2a674bd738d20fc40a4ed38a02351f4a9872123fb865 1 1 16 54 18008bf3418871e7d117af489798fbbcc031c534e095b4e4ed6cb110c7d87a91e5fb6c080c77616618db80ed37589fcc0ca8328406ef 1 1 23 46 10007a522025d2e7126dc48d76218e9efb3ff4326a3b5969be0deac108657a9d23c7827ec39b828fd43e51ea114b -1; princ 38 38 4 4 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200045a2e5b79c5787bfc68700d3abc0034cc91d48f10636c35e1a571c41c4e6892caceeda8808bfa46aa4050a6d33d99cb64d237f645af6741e90c723ff 1 1 17 46 100073b99fecd81b4fe113b10852065c15e75ed7d256d2d242b3cca57317c28c7fece4bda797f116309ea5bc2eb1 1 1 16 54 1800bd05672170b5d04cb62394498988f3844b744a0793ac435d044e67ed0ee50d20c408b30cec599c169378b0ad2a4967f42aef38e5 1 1 23 46 1000a1a515e0fe322980f319752bf85dd405ca2bdda148009654584b70f50d38c532df1c2d0a3c56f9758775b007 -1; princ 38 30 1 4 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000582c9aaf26c4a0abf13600baf37718c91e15dca02385e346cf5d2730d28b2302677f23d02791299548b45e1ced0b05cd30062617bff7532885d7889c 1 1 17 46 1000122eb47263d7837771ebbf7ad82163cc2ea7674a417944c0cbf186522fc0e74a73affd4a42fb9fda287be4f8 1 1 16 54 18008cd8064aea468f13f36ae13ecd4f993d87ef6bafcb2dc5101ad903200ffe3d5c265b2f0c71a6c07ec60d259b6862825cc77a70b2 1 1 23 46 10001699ad0304644456106328fbd733bd5c524f20d4b5d8b8e370eff196803b5990ee7e9eb4b6c2214cf327f59b -1; princ 38 18 4 0 0 nokeys@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 27 d931dc51757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 d931dc51 -1; princ 38 22 4 4 0 user/admin@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20002db4cd2b0824c44a17cdbb2d180a1ec9956db35d74741826ed0d77eaef9abdb20c481d5ab9f511d5a3e6b8def443382f03d247568d81529e5dd17fae 1 1 17 46 100011d7cc3627468d565d398cffd735a3cc9d3705cd9846cede198c7d07f4e8209cd9192bc6c5f127169c00f373 1 1 16 54 18002bd9dc3388c90055844b3b4c5c2a814d73758f226d44d7dc5e35ef3b65e7d80cd604a4ef2a5769106818c3d813956bbad1813cb2 1 1 23 46 1000409681c3ff356fb7d28a9f71957c3465ea42ec4eee5019a662f7d367042527b76ae783cfbd0dccbd7529d090 -1; princ 38 16 4 4 0 user@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 32 12345c010000000874657374706f6c0000000800000000000000000200000000 2 27 d73e1051757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 2000aec451aae295389f92d177e61b5154941386c70d75d382393e556dfa61bd77d112a777420a99030b56649d366bba83a5c40aa17fa4522222d2e78e10 1 1 17 46 10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c495605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf 1 1 16 54 18002b87a46d6c4de954a316b5ce28a99886f2abb6b0307190e577b81171dfb7a067139835be8625bc36b0edaaed357609107d85d335 1 1 23 46 1000c01fcdb3050a2270f82dbafbe4c1adc868377bf7133ee7a1bcaf85817abe541beb8008b91c54b99e93d2e0f5 -1; policy testpol 0 0 1 3 1 0 0 0 0 0 0 0 - 0 krb5-1.22.1/src/tests/dumpfiles/dump.r180000664000175000017500000001205115051422640017562 0ustar ghudsonghudsonkdb5_util load_dump version 6 princ 38 15 3 1 0 K/M@KRBTEST.COM 64 86400 0 0 0 0 0 0 8 2 0100 9 8 0100010000000000 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000408c027c250e8cc3b81476414f2214d57c1ce38891e29792e87258247c73547df4d5756266931dd6686b62270e656895a31ec66bfe913b4f15226227 -1; princ 38 36 4 4 0 host/equal-rites.mit.edu@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20009b7f9e9edd44559c5ffb2b52beb92e57586f9bdf59ae0be7010ffa8b628928bebc7d6015211977bc34325be853e5f1eb5826ce75575414bc2696bc16 1 1 17 46 10001bfaf4d8ddd6e8767194a190e9dec2617dbc90883db767fa464325b76b97ea98f3b61c4d4234ff9aee6314a4 1 1 16 54 18008291ce8c2ccde958c2739e93ce499b088b1b8c304bce95097bd6c1bd92c3c9f64e92950767f7806d890b386ba586fdb7f8433f1c 1 1 23 46 1000a460520a9e39b1539e703a51793967247999a9a0bb7c59a61ca2b5e64a58c3b9cf8217daeddd71caae9d7fbb -1; princ 38 24 4 4 0 kadmin/admin@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20005ea70b11f3337975c5463baedc68b234cadf72f89828d98e3c16cb8640bba7c5ed48a4bcf7649a73a9a410e96234924bfacd4bb38f08982db02c5c5b 1 1 17 46 10001b678f8b9bb6913397202c259702c1941fd5d2892f42349a92ca908de248cd041465bb3d16d27efce1f63e30 1 1 16 54 18009ed81fe14b19549918acad7b1158b86f5971ab3bd77b2359c29147af35730167210157e510dda65f691c312ac398850d7e228c40 1 1 23 46 10001d15a249bbea104208ae0b3d83337d4c06f6edef6a6ac60ec3df7b52aeeeb388c7233a9b1e3de646949ed540 -1; princ 38 27 4 4 0 kadmin/changepw@KRBTEST.COM 8196 300 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200015daf7bc8073eae166b03231330b81b78cfd6021d3dcf3700862dc98725c5bb549a72aa2ae8eef37dc2db5acc59cc62600f72052c6238ef216dd24a5 1 1 17 46 1000c1e176f253d6292fe4e34b2edfbdd5ff81ff3e17b38c2a674bd738d20fc40a4ed38a02351f4a9872123fb865 1 1 16 54 18008bf3418871e7d117af489798fbbcc031c534e095b4e4ed6cb110c7d87a91e5fb6c080c77616618db80ed37589fcc0ca8328406ef 1 1 23 46 10007a522025d2e7126dc48d76218e9efb3ff4326a3b5969be0deac108657a9d23c7827ec39b828fd43e51ea114b -1; princ 38 38 4 4 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200045a2e5b79c5787bfc68700d3abc0034cc91d48f10636c35e1a571c41c4e6892caceeda8808bfa46aa4050a6d33d99cb64d237f645af6741e90c723ff 1 1 17 46 100073b99fecd81b4fe113b10852065c15e75ed7d256d2d242b3cca57317c28c7fece4bda797f116309ea5bc2eb1 1 1 16 54 1800bd05672170b5d04cb62394498988f3844b744a0793ac435d044e67ed0ee50d20c408b30cec599c169378b0ad2a4967f42aef38e5 1 1 23 46 1000a1a515e0fe322980f319752bf85dd405ca2bdda148009654584b70f50d38c532df1c2d0a3c56f9758775b007 -1; princ 38 30 1 4 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000582c9aaf26c4a0abf13600baf37718c91e15dca02385e346cf5d2730d28b2302677f23d02791299548b45e1ced0b05cd30062617bff7532885d7889c 1 1 17 46 1000122eb47263d7837771ebbf7ad82163cc2ea7674a417944c0cbf186522fc0e74a73affd4a42fb9fda287be4f8 1 1 16 54 18008cd8064aea468f13f36ae13ecd4f993d87ef6bafcb2dc5101ad903200ffe3d5c265b2f0c71a6c07ec60d259b6862825cc77a70b2 1 1 23 46 10001699ad0304644456106328fbd733bd5c524f20d4b5d8b8e370eff196803b5990ee7e9eb4b6c2214cf327f59b -1; princ 38 18 4 0 0 nokeys@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 27 d931dc51757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 d931dc51 -1; princ 38 22 4 4 0 user/admin@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20002db4cd2b0824c44a17cdbb2d180a1ec9956db35d74741826ed0d77eaef9abdb20c481d5ab9f511d5a3e6b8def443382f03d247568d81529e5dd17fae 1 1 17 46 100011d7cc3627468d565d398cffd735a3cc9d3705cd9846cede198c7d07f4e8209cd9192bc6c5f127169c00f373 1 1 16 54 18002bd9dc3388c90055844b3b4c5c2a814d73758f226d44d7dc5e35ef3b65e7d80cd604a4ef2a5769106818c3d813956bbad1813cb2 1 1 23 46 1000409681c3ff356fb7d28a9f71957c3465ea42ec4eee5019a662f7d367042527b76ae783cfbd0dccbd7529d090 -1; princ 38 16 4 4 0 user@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 32 12345c010000000874657374706f6c0000000800000000000000000200000000 2 27 d73e1051757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 2000aec451aae295389f92d177e61b5154941386c70d75d382393e556dfa61bd77d112a777420a99030b56649d366bba83a5c40aa17fa4522222d2e78e10 1 1 17 46 10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c495605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf 1 1 16 54 18002b87a46d6c4de954a316b5ce28a99886f2abb6b0307190e577b81171dfb7a067139835be8625bc36b0edaaed357609107d85d335 1 1 23 46 1000c01fcdb3050a2270f82dbafbe4c1adc868377bf7133ee7a1bcaf85817abe541beb8008b91c54b99e93d2e0f5 -1; policy testpol 0 0 1 3 1 0 0 0 0 krb5-1.22.1/src/tests/dumpfiles/dump.r130000664000175000017500000001204315051422640017556 0ustar ghudsonghudsonkdb5_util load_dump version 5 princ 38 15 3 1 0 K/M@KRBTEST.COM 64 86400 0 0 0 0 0 0 8 2 0100 9 8 0100010000000000 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000408c027c250e8cc3b81476414f2214d57c1ce38891e29792e87258247c73547df4d5756266931dd6686b62270e656895a31ec66bfe913b4f15226227 -1; princ 38 36 4 4 0 host/equal-rites.mit.edu@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20009b7f9e9edd44559c5ffb2b52beb92e57586f9bdf59ae0be7010ffa8b628928bebc7d6015211977bc34325be853e5f1eb5826ce75575414bc2696bc16 1 1 17 46 10001bfaf4d8ddd6e8767194a190e9dec2617dbc90883db767fa464325b76b97ea98f3b61c4d4234ff9aee6314a4 1 1 16 54 18008291ce8c2ccde958c2739e93ce499b088b1b8c304bce95097bd6c1bd92c3c9f64e92950767f7806d890b386ba586fdb7f8433f1c 1 1 23 46 1000a460520a9e39b1539e703a51793967247999a9a0bb7c59a61ca2b5e64a58c3b9cf8217daeddd71caae9d7fbb -1; princ 38 24 4 4 0 kadmin/admin@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20005ea70b11f3337975c5463baedc68b234cadf72f89828d98e3c16cb8640bba7c5ed48a4bcf7649a73a9a410e96234924bfacd4bb38f08982db02c5c5b 1 1 17 46 10001b678f8b9bb6913397202c259702c1941fd5d2892f42349a92ca908de248cd041465bb3d16d27efce1f63e30 1 1 16 54 18009ed81fe14b19549918acad7b1158b86f5971ab3bd77b2359c29147af35730167210157e510dda65f691c312ac398850d7e228c40 1 1 23 46 10001d15a249bbea104208ae0b3d83337d4c06f6edef6a6ac60ec3df7b52aeeeb388c7233a9b1e3de646949ed540 -1; princ 38 27 4 4 0 kadmin/changepw@KRBTEST.COM 8196 300 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200015daf7bc8073eae166b03231330b81b78cfd6021d3dcf3700862dc98725c5bb549a72aa2ae8eef37dc2db5acc59cc62600f72052c6238ef216dd24a5 1 1 17 46 1000c1e176f253d6292fe4e34b2edfbdd5ff81ff3e17b38c2a674bd738d20fc40a4ed38a02351f4a9872123fb865 1 1 16 54 18008bf3418871e7d117af489798fbbcc031c534e095b4e4ed6cb110c7d87a91e5fb6c080c77616618db80ed37589fcc0ca8328406ef 1 1 23 46 10007a522025d2e7126dc48d76218e9efb3ff4326a3b5969be0deac108657a9d23c7827ec39b828fd43e51ea114b -1; princ 38 38 4 4 0 kadmin/equal-rites.mit.edu@KRBTEST.COM 4 10800 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 26 b93e10516b6462355f7574696c404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 200045a2e5b79c5787bfc68700d3abc0034cc91d48f10636c35e1a571c41c4e6892caceeda8808bfa46aa4050a6d33d99cb64d237f645af6741e90c723ff 1 1 17 46 100073b99fecd81b4fe113b10852065c15e75ed7d256d2d242b3cca57317c28c7fece4bda797f116309ea5bc2eb1 1 1 16 54 1800bd05672170b5d04cb62394498988f3844b744a0793ac435d044e67ed0ee50d20c408b30cec599c169378b0ad2a4967f42aef38e5 1 1 23 46 1000a1a515e0fe322980f319752bf85dd405ca2bdda148009654584b70f50d38c532df1c2d0a3c56f9758775b007 -1; princ 38 30 1 4 0 krbtgt/KRBTEST.COM@KRBTEST.COM 0 86400 0 0 0 0 0 0 2 28 b93e105164625f6372656174696f6e404b5242544553542e434f4d00 1 1 18 62 2000582c9aaf26c4a0abf13600baf37718c91e15dca02385e346cf5d2730d28b2302677f23d02791299548b45e1ced0b05cd30062617bff7532885d7889c 1 1 17 46 1000122eb47263d7837771ebbf7ad82163cc2ea7674a417944c0cbf186522fc0e74a73affd4a42fb9fda287be4f8 1 1 16 54 18008cd8064aea468f13f36ae13ecd4f993d87ef6bafcb2dc5101ad903200ffe3d5c265b2f0c71a6c07ec60d259b6862825cc77a70b2 1 1 23 46 10001699ad0304644456106328fbd733bd5c524f20d4b5d8b8e370eff196803b5990ee7e9eb4b6c2214cf327f59b -1; princ 38 18 4 0 0 nokeys@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 27 d931dc51757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 d931dc51 -1; princ 38 22 4 4 0 user/admin@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 24 12345c010000000000000000000000000000000200000000 2 30 b93e105167687564736f6e2f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 20002db4cd2b0824c44a17cdbb2d180a1ec9956db35d74741826ed0d77eaef9abdb20c481d5ab9f511d5a3e6b8def443382f03d247568d81529e5dd17fae 1 1 17 46 100011d7cc3627468d565d398cffd735a3cc9d3705cd9846cede198c7d07f4e8209cd9192bc6c5f127169c00f373 1 1 16 54 18002bd9dc3388c90055844b3b4c5c2a814d73758f226d44d7dc5e35ef3b65e7d80cd604a4ef2a5769106818c3d813956bbad1813cb2 1 1 23 46 1000409681c3ff356fb7d28a9f71957c3465ea42ec4eee5019a662f7d367042527b76ae783cfbd0dccbd7529d090 -1; princ 38 16 4 4 0 user@KRBTEST.COM 0 86400 0 0 0 0 0 0 3 32 12345c010000000874657374706f6c0000000800000000000000000200000000 2 27 d73e1051757365722f61646d696e404b5242544553542e434f4d00 8 2 0100 1 4 b93e1051 1 1 18 62 2000aec451aae295389f92d177e61b5154941386c70d75d382393e556dfa61bd77d112a777420a99030b56649d366bba83a5c40aa17fa4522222d2e78e10 1 1 17 46 10009c8ab7b3f89ccf3ca3ad98352a461b7f4f1b0c495605117591d9ad52ba4da0adef7a902126973ed2bdc3ffbf 1 1 16 54 18002b87a46d6c4de954a316b5ce28a99886f2abb6b0307190e577b81171dfb7a067139835be8625bc36b0edaaed357609107d85d335 1 1 23 46 1000c01fcdb3050a2270f82dbafbe4c1adc868377bf7133ee7a1bcaf85817abe541beb8008b91c54b99e93d2e0f5 -1; policy testpol 0 0 1 3 1 0 krb5-1.22.1/src/tests/dumpfiles/dump.ov0000664000175000017500000000053415051422640017577 0ustar ghudsonghudsonOpenV*Secure V1.0 princ host/equal-rites.mit.edu@KRBTEST.COM 0 0 0 2 princ kadmin/admin@KRBTEST.COM 0 0 0 2 princ kadmin/changepw@KRBTEST.COM 0 0 0 2 princ kadmin/equal-rites.mit.edu@KRBTEST.COM 0 0 0 2 princ nokeys@KRBTEST.COM 0 0 0 2 princ user/admin@KRBTEST.COM 0 0 0 2 princ user@KRBTEST.COM testpol 800 0 0 2 policy testpol 0 0 1 3 1 0 krb5-1.22.1/src/tests/t_kdcpolicy.py0000664000175000017500000000475715051422640017165 0ustar ghudsonghudsonfrom k5test import * from datetime import datetime import re testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') testpolicy = os.path.join(buildtop, 'plugins', 'kdcpolicy', 'test', 'kdcpolicy_test.so') krb5_conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}, 'kdcpolicy': {'module': 'test:' + testpolicy}}} kdc_conf = {'realms': {'$realm': {'default_principal_flags': '+preauth', 'max_renewable_life': '1d'}}} realm = K5Realm(krb5_conf=krb5_conf, kdc_conf=kdc_conf) # We will be scraping timestamps from klist to compute lifetimes, so # use a time zone with no daylight savings time. realm.env['TZ'] = 'UTC' realm.run([kadminl, 'addprinc', '-pw', password('fail'), 'fail']) def verify_time(out, target_time): times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out) times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times] divisor = 1 while len(times) > 0: starttime = times.pop(0) endtime = times.pop(0) renewtime = times.pop(0) if str((endtime - starttime) * divisor) != target_time: fail('unexpected lifetime value') if str((renewtime - endtime) * divisor) != target_time: fail('unexpected renewable value') # Service tickets should have half the lifetime of initial # tickets. divisor = 2 rflags = ['-r', '1d', '-l', '12h'] # Test AS+TGS success path. realm.kinit(realm.user_princ, password('user'), rflags + ['-X', 'indicators=SEVEN_HOURS']) realm.run([kvno, realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [SEVEN_HOURS]') out = realm.run([klist, '-e', realm.ccache]) verify_time(out, '7:00:00') # Test AS+TGS success path with different values. realm.kinit(realm.user_princ, password('user'), rflags + ['-X', 'indicators=ONE_HOUR']) realm.run([kvno, realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [ONE_HOUR]') out = realm.run([klist, '-e', realm.ccache]) verify_time(out, '1:00:00') # Test TGS failure path (using previous creds). realm.run([kvno, 'fail@%s' % realm.realm], expected_code=1, expected_msg='KDC policy rejects request') # Test AS failure path. realm.kinit('fail@%s' % realm.realm, password('fail'), expected_code=1, expected_msg='KDC policy rejects request') success('kdcpolicy tests') krb5-1.22.1/src/tests/s4u2proxy.c0000664000175000017500000001211615051422640016336 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/s4u2proxy.c - S4U2Proxy test harness */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Usage: s4u2proxy evccname targetname [ad-type ad-contents] * * evccname contains an evidence ticket. The default ccache contains a TGT for * the intermediate service. The default keytab contains a key for the * intermediate service. An S4U2Proxy request is made to get a ticket from * evccname's default principal to the target service. The resulting cred is * stored in the default ccache. */ #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static krb5_authdata ** make_request_authdata(int type, const char *contents) { krb5_authdata *ad; krb5_authdata **req_authdata; ad = malloc(sizeof(*ad)); assert(ad != NULL); ad->magic = KV5M_AUTHDATA; ad->ad_type = type; ad->length = strlen(contents); ad->contents = (unsigned char *)strdup(contents); assert(ad->contents != NULL); req_authdata = malloc(2 * sizeof(*req_authdata)); assert(req_authdata != NULL); req_authdata[0] = ad; req_authdata[1] = NULL; return req_authdata; } int main(int argc, char **argv) { krb5_context context; krb5_ccache defcc, evcc; krb5_principal client_name, int_name, target_name; krb5_keytab defkt; krb5_creds mcred, ev_cred, *new_cred; krb5_ticket *ev_ticket; krb5_authdata **req_authdata = NULL; if (argc == 5) { req_authdata = make_request_authdata(atoi(argv[3]), argv[4]); argc -= 2; } assert(argc == 3); check(krb5_init_context(&context)); /* Open the default ccache, evidence ticket ccache, and default keytab. */ check(krb5_cc_default(context, &defcc)); check(krb5_cc_resolve(context, argv[1], &evcc)); check(krb5_kt_default(context, &defkt)); /* Determine the client name, intermediate name, and target name. */ check(krb5_cc_get_principal(context, evcc, &client_name)); check(krb5_cc_get_principal(context, defcc, &int_name)); check(krb5_parse_name(context, argv[2], &target_name)); /* Retrieve and decrypt the evidence ticket. */ memset(&mcred, 0, sizeof(mcred)); mcred.client = client_name; mcred.server = int_name; check(krb5_cc_retrieve_cred(context, evcc, 0, &mcred, &ev_cred)); check(krb5_decode_ticket(&ev_cred.ticket, &ev_ticket)); check(krb5_server_decrypt_ticket_keytab(context, defkt, ev_ticket)); /* Make an S4U2Proxy request for the target service. */ mcred.client = client_name; mcred.server = target_name; mcred.authdata = req_authdata; check(krb5_get_credentials_for_proxy(context, KRB5_GC_NO_STORE | KRB5_GC_CANONICALIZE, defcc, &mcred, ev_ticket, &new_cred)); assert(data_eq(new_cred->second_ticket, ev_cred.ticket)); assert(new_cred->second_ticket.length != 0); /* Store the new cred in the default ccache. */ check(krb5_cc_store_cred(context, defcc, new_cred)); assert(req_authdata == NULL || new_cred->authdata != NULL); krb5_cc_close(context, defcc); krb5_cc_close(context, evcc); krb5_kt_close(context, defkt); krb5_free_principal(context, client_name); krb5_free_principal(context, int_name); krb5_free_principal(context, target_name); krb5_free_cred_contents(context, &ev_cred); krb5_free_ticket(context, ev_ticket); krb5_free_creds(context, new_cred); krb5_free_authdata(context, req_authdata); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/t_general.py0000775000175000017500000000565615051422640016623 0ustar ghudsonghudsonfrom k5test import * for realm in multipass_realms(create_host=False): # Check that kinit fails appropriately with the wrong password. mark('kinit wrong password failure') msg = 'Password incorrect while getting initial credentials' realm.run([kinit, realm.user_princ], input='wrong\n', expected_code=1, expected_msg=msg) # Check that we can kinit as a different principal. mark('kinit with specified principal') realm.kinit(realm.admin_princ, password('admin')) realm.klist(realm.admin_princ) # Test FAST kinit. mark('FAST kinit') fastpw = password('fast') realm.run([kadminl, 'ank', '-pw', fastpw, '+requires_preauth', 'user/fast']) realm.kinit('user/fast', fastpw) realm.kinit('user/fast', fastpw, flags=['-T', realm.ccache]) realm.klist('user/fast@%s' % realm.realm) # Test kinit against kdb keytab realm.run([kinit, "-k", "-t", "KDB:", realm.user_princ]) # Test that we can get initial creds with an empty password via the # API. We have to disable the "empty" pwqual module to create a # principal with an empty password. (Regression test for #7642.) mark('initial creds with empty password') conf={'plugins': {'pwqual': {'disable': 'empty'}}} realm = K5Realm(create_user=False, create_host=False, krb5_conf=conf) realm.run([kadminl, 'addprinc', '-pw', '', 'user']) realm.run(['./icred', 'user', '']) realm.run(['./icred', '-s', 'user', '']) realm.stop() realm = K5Realm(create_host=False) # Regression test for #6428 (KDC should prefer account expiration # error to password expiration error). mark('#6428 regression test') realm.run([kadminl, 'addprinc', '-randkey', '-pwexpire', 'yesterday', 'xpr']) realm.run(['./icred', 'xpr'], expected_code=1, expected_msg='Password has expired') realm.run([kadminl, 'modprinc', '-expire', 'yesterday', 'xpr']) realm.run(['./icred', 'xpr'], expected_code=1, expected_msg="Client's entry in database has expired") # Regression test for #8454 (responder callback isn't used when # preauth is not required). mark('#8454 regression test') realm.run(['./responder', '-r', 'password=%s' % password('user'), realm.user_princ]) # Test that WRONG_REALM responses aren't treated as referrals unless # they contain a crealm field pointing to a different realm. # (Regression test for #8060.) mark('#8060 regression test') realm.run([kinit, '-C', 'notfoundprinc'], expected_code=1, expected_msg='not found in Kerberos database') # Spot-check KRB5_TRACE output mark('KRB5_TRACE spot check') expected_trace = ('Sending initial UDP request', 'Received answer', 'Selected etype info', 'AS key obtained', 'Decrypted AS reply', 'FAST negotiation: available', 'Storing user@KRBTEST.COM') realm.kinit(realm.user_princ, password('user'), expected_trace=expected_trace) success('FAST kinit, trace logging') krb5-1.22.1/src/tests/t_kdcoptions.py0000664000175000017500000000763515051422640017357 0ustar ghudsonghudsonfrom k5test import * import re # KDC option test coverage notes: # # FORWARDABLE here # FORWARDED no test # PROXIABLE here # PROXY no test # ALLOW_POSTDATE no test # POSTDATED no test # RENEWABLE t_renew.py # CNAME_IN_ADDL_TKT gssapi/t_s4u.py # CANONICALIZE t_kdb.py and various other tests # REQUEST_ANONYMOUS t_pkinit.py # DISABLE_TRANSITED_CHECK no test # RENEWABLE_OK t_renew.py # ENC_TKT_IN_SKEY t_u2u.py # RENEW t_renew.py # VALIDATE no test # Run klist -f and return the flags on the ticket for svcprinc. def get_flags(realm, svcprinc): grab_flags = False for line in realm.run([klist, '-f']).splitlines(): if grab_flags: return re.findall(r'Flags: ([a-zA-Z]*)', line)[0] grab_flags = line.endswith(svcprinc) # Get the flags on the ticket for svcprinc, and check for an expected # element and an expected-absent element, either of which can be None. def check_flags(realm, svcprinc, expected_flag, expected_noflag): flags = get_flags(realm, svcprinc) if expected_flag is not None and not expected_flag in flags: fail('expected flag ' + expected_flag) if expected_noflag is not None and expected_noflag in flags: fail('did not expect flag ' + expected_noflag) # Run kinit with the given flags, and check the flags on the resulting # TGT. def kinit_check_flags(realm, flags, expected_flag, expected_noflag): realm.kinit(realm.user_princ, password('user'), flags) check_flags(realm, realm.krbtgt_princ, expected_flag, expected_noflag) # Run kinit with kflags. Then get credentials for the host principal # with gflags, and check the flags on the resulting ticket. def gcred_check_flags(realm, kflags, gflags, expected_flag, expected_noflag): realm.kinit(realm.user_princ, password('user'), kflags) realm.run(['./gcred'] + gflags + ['unknown', realm.host_princ]) check_flags(realm, realm.host_princ, expected_flag, expected_noflag) realm = K5Realm() mark('proxiable (AS)') kinit_check_flags(realm, [], None, 'P') kinit_check_flags(realm, ['-p'], 'P', None) realm.run([kadminl, 'modprinc', '-allow_proxiable', realm.user_princ]) kinit_check_flags(realm, ['-p'], None, 'P') realm.run([kadminl, 'modprinc', '+allow_proxiable', realm.user_princ]) realm.run([kadminl, 'modprinc', '-allow_proxiable', realm.krbtgt_princ]) kinit_check_flags(realm, ['-p'], None, 'P') realm.run([kadminl, 'modprinc', '+allow_proxiable', realm.krbtgt_princ]) mark('proxiable (TGS)') gcred_check_flags(realm, [], [], None, 'P') gcred_check_flags(realm, ['-p'], [], 'P', None) # Not tested: PROXIABLE option set with a non-proxiable TGT (because # there is no krb5_get_credentials() flag to request this; would # expect a non-proxiable ticket). # Not tested: proxiable TGT but PROXIABLE flag not set (because we # internally set the PROXIABLE option when using a proxiable TGT; # would expect a non-proxiable ticket). mark('forwardable (AS)') kinit_check_flags(realm, [], None, 'F') kinit_check_flags(realm, ['-f'], 'F', None) realm.run([kadminl, 'modprinc', '-allow_forwardable', realm.user_princ]) kinit_check_flags(realm, ['-f'], None, 'F') realm.run([kadminl, 'modprinc', '+allow_forwardable', realm.user_princ]) realm.run([kadminl, 'modprinc', '-allow_forwardable', realm.krbtgt_princ]) kinit_check_flags(realm, ['-f'], None, 'F') realm.run([kadminl, 'modprinc', '+allow_forwardable', realm.krbtgt_princ]) mark('forwardable (TGS)') realm.kinit(realm.user_princ, password('user')) gcred_check_flags(realm, [], [], None, 'F') gcred_check_flags(realm, [], ['-f'], None, 'F') gcred_check_flags(realm, ['-f'], [], 'F', None) # Not tested: forwardable TGT but FORWARDABLE flag not set (because we # internally set the FORWARDABLE option when using a forwardable TGT; # would expect a non-proxiable ticket). success('KDC option tests') krb5-1.22.1/src/tests/t_changepw.py0000775000175000017500000000553115051422640016772 0ustar ghudsonghudsonfrom k5test import * # Also listen on a UNIX domain sockets for kpasswd. unix_conf = {'realms': {'$realm': { 'kdc_listen': '$port0, $testdir/krb5.sock', 'kadmind_listen': '$port1, $testdir/kadmin.sock', 'kpasswd_listen': '$port2, $testdir/kpasswd.sock'}}} realm = K5Realm(create_host=False,get_creds=False, kdc_conf=unix_conf) realm.start_kadmind() realm.prep_kadmin() # Mark a principal as expired and change its password through kinit. mark('password change via kinit') realm.run([kadminl, 'modprinc', '-pwexpire', '1 day ago', 'user']) pwinput = password('user') + '\nabcd\nabcd\n' realm.run([kinit, realm.user_princ], input=pwinput) # Regression test for #7868 (preauth options ignored when # krb5_get_init_creds_password() initiates a password change). This # time use the REQUIRES_PWCHANGE bit instead of the password # expiration time. mark('password change via kinit with FAST') realm.run([kadminl, 'modprinc', '+needchange', 'user']) pwinput = 'abcd\nefgh\nefgh\n' out, trace = realm.run([kinit, '-T', realm.ccache, realm.user_princ], input=pwinput, return_trace=True) # Check that FAST was used when getting the kadmin/changepw ticket. getting_changepw = fast_used_for_changepw = False for line in trace.splitlines(): if 'Getting initial credentials for user@' in line: getting_changepw_ticket = False if 'Setting initial creds service to kadmin/changepw' in line: getting_changepw_ticket = True if getting_changepw_ticket and 'Using FAST' in line: fast_used_for_changepw = True if not fast_used_for_changepw: fail('FAST was not used to get kadmin/changepw ticket') # Test that passwords specified via kadmin and kpasswd are usable with # kinit. mark('password change usability by kinit') realm.run([kadminl, 'addprinc', '-pw', 'pw1', 'testprinc']) # Run kpasswd with an active cache to exercise automatic FAST use. realm.kinit('testprinc', 'pw1') realm.run([kpasswd, 'testprinc'], input='pw1\npw2\npw2\n') realm.kinit('testprinc', 'pw2') realm.run([kdestroy]) realm.run([kpasswd, 'testprinc'], input='pw2\npw3\npw3\n') realm.kinit('testprinc', 'pw3') realm.run([kdestroy]) realm.run_kadmin(['cpw', '-pw', 'pw4', 'testprinc']) realm.kinit('testprinc', 'pw4') realm.run([kdestroy]) realm.run([kadminl, 'delprinc', 'testprinc']) mark('password change over UNIX domain socket') unix_cli_conf = {'realms': {'$realm': { 'kdc': '$testdir/krb5.sock', 'admin_server': '$testdir/kadmin.sock', 'kpasswd_server': '$testdir/kpasswd.sock'}}} unix_cli = realm.special_env('unix_cli', False, krb5_conf=unix_cli_conf) realm.run([kadminl, 'addprinc', '-pw', 'pw1', 'testprinc']) msgs = ('Sending TCP request to UNIX domain socket',) realm.run([kpasswd, 'testprinc'], input='pw1\npw2\npw2\n', env=unix_cli, expected_trace=msgs) realm.run([kadminl, 'delprinc', 'testprinc']) success('Password change tests') krb5-1.22.1/src/tests/t_salt.py0000775000175000017500000000440115051422640016134 0ustar ghudsonghudsonfrom k5test import * import re realm = K5Realm(create_user=False) # Check that a non-default salt type applies only to the key it is # matched with and not to subsequent keys. e1 and e2 are enctypes, # and salt is a non-default salt type. def test_salt(realm, e1, salt, e2): keysalts = e1 + ':' + salt + ',' + e2 realm.run([kadminl, 'ank', '-e', keysalts, '-pw', 'password', 'user']) out = realm.run([kadminl, 'getprinc', 'user']) if len(re.findall(':' + salt, out)) != 1: fail(salt + ' present in second enctype or not present') realm.run([kadminl, 'delprinc', 'user']) # Enctype/salt pairs chosen with non-default salt types. # The enctypes are mostly arbitrary. salts = [('des3-cbc-sha1', 'norealm'), ('arcfour-hmac', 'onlyrealm'), ('aes128-cts-hmac-sha1-96', 'special')] # These enctypes are chosen to cover the different string-to-key routines. # Omit ":normal" from aes256 to check that salttype defaulting works. second_kstypes = ['aes256-cts-hmac-sha1-96', 'arcfour-hmac:normal', 'des3-cbc-sha1:normal'] # Test using different salt types in a principal's key list. # Parameters from one key in the list must not leak over to later ones. for e1, string in salts: for e2 in second_kstypes: test_salt(realm, e1, string, e2) def test_dup(realm, ks): realm.run([kadminl, 'ank', '-e', ks, '-pw', 'password', 'ks_princ']) out = realm.run([kadminl, 'getprinc', 'ks_princ']) lines = out.split('\n') keys = [l for l in lines if 'Key: ' in l] uniq = set(keys) # 'Key:' matches 'MKey:' as well so len(keys) has one extra if (len(uniq) != len(keys)) or len(keys) > len(ks.split(',')): fail('Duplicate keysalt detection failed for keysalt ' + ks) realm.run([kadminl, 'delprinc', 'ks_princ']) # All in-tree callers request duplicate suppression from # krb5_string_to_keysalts(); we should check that it works, respects # aliases, and doesn't result in an infinite loop. dup_kstypes = ['arcfour-hmac-md5:normal,rc4-hmac:normal', 'aes256-cts-hmac-sha1-96:normal,aes128-cts,aes256-cts', 'aes256-cts-hmac-sha1-96:normal,aes256-cts:special,' + 'aes256-cts-hmac-sha1-96:normal'] for ks in dup_kstypes: test_dup(realm, ks) success("Salt types") krb5-1.22.1/src/tests/t_replay.py0000664000175000017500000000015315051422640016462 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm() realm.run(['./replay', realm.host_princ]) success('Replay tests') krb5-1.22.1/src/tests/t_unlockiter.py0000775000175000017500000000145415051422640017355 0ustar ghudsonghudsonfrom k5test import * # Default KDB iteration is locked. Expect write lock failure unless # unlocked iteration is explicitly requested. realm = K5Realm(create_user=False, create_host=False, start_kdc=False, bdb_only=True) realm.run(['./unlockiter'], expected_code=1) realm.run(['./unlockiter', '-u']) realm.run(['./unlockiter', '-l'], expected_code=1) # Set default to unlocked iteration. Only explicitly requested locked # iteration should block the write lock. realm = K5Realm(create_user=False, create_host=False, start_kdc=False, bdb_only=True, krb5_conf={'dbmodules': {'db': {'unlockiter': 'true'}}}) realm.run(['./unlockiter']) realm.run(['./unlockiter', '-u']) realm.run(['./unlockiter', '-l'], expected_code=1) success('Unlocked iteration unit tests') krb5-1.22.1/src/tests/kdbtest.c0000664000175000017500000003735215051422640016110 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/kdbtest.c - test program to exercise KDB modules */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This test program uses libkdb5 APIs to exercise as much of the LDAP and DB2 * back ends. */ #include #include #include static krb5_context ctx; #define CHECK(code) check(code, __LINE__) #define CHECK_COND(val) check_cond(val, __LINE__) static void check(krb5_error_code code, int lineno) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "Unexpected error at line %d: %s\n", lineno, errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static void check_cond(int value, int lineno) { if (!value) { fprintf(stderr, "Unexpected result at line %d\n", lineno); exit(1); } } static krb5_data princ_data[2] = { { KV5M_DATA, 6, "xy*(z)" }, { KV5M_DATA, 12, "+<> *()\\#\",;" } }; static krb5_principal_data sample_princ = { KV5M_PRINCIPAL, { KV5M_DATA, 11, "KRBTEST.COM" }, princ_data, 2, KRB5_NT_UNKNOWN }; static krb5_principal_data xrealm_princ = { KV5M_PRINCIPAL, { KV5M_DATA, 12, "KRBTEST2.COM" }, princ_data, 2, KRB5_NT_UNKNOWN }; #define U(x) (unsigned char *)x /* * tl1 through tl4 are normalized to attributes in the LDAP back end. tl5 is * stored as untranslated tl-data. tl3 contains an encoded osa_princ_ent with * a policy reference to "". */ static krb5_tl_data tl5 = { NULL, KRB5_TL_MKVNO, 2, U("\0\1") }; static krb5_tl_data tl4 = { &tl5, KRB5_TL_LAST_ADMIN_UNLOCK, 4, U("\6\0\0\0") }; static krb5_tl_data tl3 = { &tl4, KRB5_TL_KADM_DATA, 32, U("\x12\x34\x5C\x01\x00\x00\x00\x08" "\x3C\x74\x65\x73\x74\x2A\x3E\x00" "\x00\x00\x08\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00") }; static krb5_tl_data tl2 = { &tl3, KRB5_TL_MOD_PRINC, 8, U("\5\6\7\0x@Y\0") }; static krb5_tl_data tl1 = { &tl2, KRB5_TL_LAST_PWD_CHANGE, 4, U("\1\2\3\4") }; /* An encoded osa_print_enc with no policy reference. */ static krb5_tl_data tl_no_policy = { NULL, KRB5_TL_KADM_DATA, 24, U("\x12\x34\x5C\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x02\x00\x00\x00\x00") }; static krb5_key_data keys[] = { { 2, /* key_data_ver */ 2, /* key_data_kvno */ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, KRB5_KDB_SALTTYPE_SPECIAL }, { 32, 7 }, { U("\x17\xF2\x75\xF2\x95\x4F\x2E\xD1" "\xF9\x0C\x37\x7B\xA7\xF4\xD6\xA3" "\x69\xAA\x01\x36\xE0\xBF\x0C\x92" "\x7A\xD6\x13\x3C\x69\x37\x59\xA9"), U("expsalt") } }, { 2, /* key_data_ver */ 2, /* key_data_kvno */ { ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0 }, { 16, 0 }, { U("\xDC\xEE\xB7\x0B\x3D\xE7\x65\x62" "\xE6\x89\x22\x6C\x76\x42\x91\x48"), NULL } } }; #undef U static char polname[] = ""; static krb5_db_entry sample_entry = { 0, KRB5_KDB_V1_BASE_LENGTH, /* mask */ KADM5_PRINCIPAL | KADM5_PRINC_EXPIRE_TIME | KADM5_PW_EXPIRATION | KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_POLICY | KADM5_MAX_RLIFE | KADM5_LAST_SUCCESS | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT | KADM5_KEY_DATA | KADM5_TL_DATA, /* attributes */ KRB5_KDB_REQUIRES_PRE_AUTH | KRB5_KDB_REQUIRES_HW_AUTH | KRB5_KDB_DISALLOW_SVR, 1234, /* max_life */ 5678, /* max_renewable_life */ 9012, /* expiration */ 3456, /* pw_expiration */ 1, /* last_success */ 5, /* last_failed */ 2, /* fail_auth_count */ 5, /* n_tl_data */ 2, /* n_key_data */ 0, NULL, /* e_length, e_data */ &sample_princ, &tl1, keys }; static osa_policy_ent_rec sample_policy = { 0, /* version */ polname, /* name */ 1357, /* pw_min_life */ 100, /* pw_max_life */ 6, /* pw_min_length */ 2, /* pw_min_classes */ 3, /* pw_history_num */ 0, /* policy_refcnt */ 2, /* pw_max_fail */ 60, /* pw_failcnt_interval */ 120, /* pw_lockout_duration */ 0, /* attributes */ 2468, /* max_life */ 3579, /* max_renewable_life */ "aes", /* allowed_keysalts */ 0, NULL /* n_tl_data, tl_data */ }; /* Compare pol against sample_policy. */ static void check_policy(osa_policy_ent_t pol) { CHECK_COND(strcmp(pol->name, sample_policy.name) == 0); CHECK_COND(pol->pw_min_life == sample_policy.pw_min_life); CHECK_COND(pol->pw_max_life == sample_policy.pw_max_life); CHECK_COND(pol->pw_min_length == sample_policy.pw_min_length); CHECK_COND(pol->pw_min_classes == sample_policy.pw_min_classes); CHECK_COND(pol->pw_history_num == sample_policy.pw_history_num); CHECK_COND(pol->pw_max_life == sample_policy.pw_max_life); CHECK_COND(pol->pw_failcnt_interval == sample_policy.pw_failcnt_interval); CHECK_COND(pol->pw_lockout_duration == sample_policy.pw_lockout_duration); CHECK_COND(pol->attributes == sample_policy.attributes); CHECK_COND(pol->max_life == sample_policy.max_life); CHECK_COND(pol->max_renewable_life == sample_policy.max_renewable_life); CHECK_COND(strcmp(pol->allowed_keysalts, sample_policy.allowed_keysalts) == 0); } /* Compare ent against sample_entry. */ static void check_entry(krb5_db_entry *ent) { krb5_int16 i, j; krb5_key_data *k1, *k2; krb5_tl_data *tl, etl; CHECK_COND(ent->attributes == sample_entry.attributes); CHECK_COND(ent->max_life == sample_entry.max_life); CHECK_COND(ent->max_renewable_life == sample_entry.max_renewable_life); CHECK_COND(ent->expiration == sample_entry.expiration); CHECK_COND(ent->pw_expiration == sample_entry.pw_expiration); CHECK_COND(ent->last_success == sample_entry.last_success); CHECK_COND(ent->last_failed == sample_entry.last_failed); CHECK_COND(ent->fail_auth_count == sample_entry.fail_auth_count); CHECK_COND(krb5_principal_compare(ctx, ent->princ, sample_entry.princ)); CHECK_COND(ent->n_key_data == sample_entry.n_key_data); for (i = 0; i < ent->n_key_data; i++) { k1 = &ent->key_data[i]; k2 = &sample_entry.key_data[i]; CHECK_COND(k1->key_data_ver == k2->key_data_ver); CHECK_COND(k1->key_data_kvno == k2->key_data_kvno); for (j = 0; j < k1->key_data_ver; j++) { CHECK_COND(k1->key_data_type[j] == k2->key_data_type[j]); CHECK_COND(k1->key_data_length[j] == k2->key_data_length[j]); CHECK_COND(memcmp(k1->key_data_contents[j], k2->key_data_contents[j], k1->key_data_length[j]) == 0); } } for (tl = sample_entry.tl_data; tl != NULL; tl = tl->tl_data_next) { etl.tl_data_type = tl->tl_data_type; CHECK(krb5_dbe_lookup_tl_data(ctx, ent, &etl)); CHECK_COND(tl->tl_data_length == etl.tl_data_length); CHECK_COND(memcmp(tl->tl_data_contents, etl.tl_data_contents, tl->tl_data_length) == 0); } } /* Audit a successful or failed preauth attempt for *entp. Then reload *entp * (by fetching sample_princ) so we can see the effect. */ static void sim_preauth(krb5_timestamp authtime, krb5_boolean ok, krb5_db_entry **entp) { /* Both back ends ignore the request, local_addr, and remote_addr * parameters for now. */ krb5_db_audit_as_req(ctx, NULL, NULL, NULL, *entp, *entp, authtime, ok ? 0 : KRB5KDC_ERR_PREAUTH_FAILED); krb5_db_free_principal(ctx, *entp); CHECK(krb5_db_get_principal(ctx, &sample_princ, 0, entp)); } static krb5_error_code iter_princ_handler(void *data, krb5_db_entry *ent) { int *count = data; CHECK_COND(krb5_principal_compare(ctx, ent->princ, sample_entry.princ)); (*count)++; return 0; } static void iter_pol_handler(void *data, osa_policy_ent_t pol) { int *count = data; CHECK_COND(strcmp(pol->name, sample_policy.name) == 0); (*count)++; } int main(void) { krb5_db_entry *ent; osa_policy_ent_t pol; krb5_pa_data **e_data; const char *status; int count; CHECK(krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_KDC, &ctx)); /* If we can, revert to requiring all entries match sample_princ in * iter_princ_handler */ CHECK_COND(krb5_db_inited(ctx) != 0); CHECK(krb5_db_create(ctx, NULL)); CHECK(krb5_db_inited(ctx)); CHECK(krb5_db_fini(ctx)); CHECK_COND(krb5_db_inited(ctx) != 0); CHECK_COND(krb5_db_inited(ctx) != 0); CHECK(krb5_db_open(ctx, NULL, KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN)); CHECK(krb5_db_inited(ctx)); /* Manipulate a policy, leaving it in place at the end. */ CHECK_COND(krb5_db_put_policy(ctx, &sample_policy) != 0); CHECK_COND(krb5_db_delete_policy(ctx, polname) != 0); CHECK_COND(krb5_db_get_policy(ctx, polname, &pol) == KRB5_KDB_NOENTRY); CHECK(krb5_db_create_policy(ctx, &sample_policy)); CHECK_COND(krb5_db_create_policy(ctx, &sample_policy) != 0); CHECK(krb5_db_get_policy(ctx, polname, &pol)); check_policy(pol); pol->pw_min_length--; CHECK(krb5_db_put_policy(ctx, pol)); krb5_db_free_policy(ctx, pol); CHECK(krb5_db_get_policy(ctx, polname, &pol)); CHECK_COND(pol->pw_min_length == sample_policy.pw_min_length - 1); krb5_db_free_policy(ctx, pol); CHECK(krb5_db_delete_policy(ctx, polname)); CHECK_COND(krb5_db_put_policy(ctx, &sample_policy) != 0); CHECK_COND(krb5_db_delete_policy(ctx, polname) != 0); CHECK_COND(krb5_db_get_policy(ctx, polname, &pol) == KRB5_KDB_NOENTRY); CHECK(krb5_db_create_policy(ctx, &sample_policy)); count = 0; CHECK(krb5_db_iter_policy(ctx, NULL, iter_pol_handler, &count)); CHECK_COND(count == 1); /* Create a principal. */ CHECK_COND(krb5_db_delete_principal(ctx, &sample_princ) == KRB5_KDB_NOENTRY); CHECK_COND(krb5_db_get_principal(ctx, &xrealm_princ, 0, &ent) == KRB5_KDB_NOENTRY); CHECK(krb5_db_put_principal(ctx, &sample_entry)); /* Putting again will fail with LDAP (due to KADM5_PRINCIPAL in mask) * but succeed with DB2, so don't check the result. */ (void)krb5_db_put_principal(ctx, &sample_entry); /* But it should succeed in both back ends with KADM5_LOAD in mask. */ sample_entry.mask |= KADM5_LOAD; CHECK(krb5_db_put_principal(ctx, &sample_entry)); sample_entry.mask &= ~KADM5_LOAD; /* Fetch and compare the added principal. */ CHECK(krb5_db_get_principal(ctx, &sample_princ, 0, &ent)); check_entry(ent); /* We can't set up a successful allowed-to-delegate check through existing * APIs yet, but we can make a failed check. */ CHECK_COND(krb5_db_check_allowed_to_delegate(ctx, &sample_princ, ent, &sample_princ) != 0); /* Exercise lockout code. */ /* Policy params: max_fail 2, failcnt_interval 60, lockout_duration 120 */ /* Initial state: last_success 1, last_failed 5, fail_auth_count 2, * last admin unlock 6 */ /* Check succeeds due to last admin unlock. */ CHECK(krb5_db_check_policy_as(ctx, NULL, ent, ent, 7, &status, &e_data)); /* Failure count resets to 1 due to last admin unlock. */ sim_preauth(8, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 8); /* Failure count resets to 1 due to failcnt_interval */ sim_preauth(70, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 70); /* Failure count resets to 0 due to successful preauth. */ sim_preauth(75, TRUE, &ent); CHECK_COND(ent->fail_auth_count == 0 && ent->last_success == 75); /* Failure count increments to 2 and stops incrementing. */ sim_preauth(80, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 80); sim_preauth(100, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 2 && ent->last_failed == 100); sim_preauth(110, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 2 && ent->last_failed == 100); /* Check fails due to reaching maximum failure count. */ CHECK_COND(krb5_db_check_policy_as(ctx, NULL, ent, ent, 170, &status, &e_data) == KRB5KDC_ERR_CLIENT_REVOKED); /* Check succeeds after lockout_duration has passed. */ CHECK(krb5_db_check_policy_as(ctx, NULL, ent, ent, 230, &status, &e_data)); /* Failure count resets to 1 on next failure. */ sim_preauth(240, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 240); /* Exercise LDAP code to clear a policy reference and to set the key * data on an existing principal. */ CHECK(krb5_dbe_update_tl_data(ctx, ent, &tl_no_policy)); ent->mask = KADM5_POLICY_CLR | KADM5_KEY_DATA; CHECK(krb5_db_put_principal(ctx, ent)); CHECK(krb5_db_delete_policy(ctx, polname)); /* Put the modified entry again (with KDB_TL_USER_INFO tl-data for LDAP) as * from a load operation. */ ent->mask = (sample_entry.mask & ~KADM5_POLICY) | KADM5_LOAD; CHECK(krb5_db_put_principal(ctx, ent)); /* Exercise LDAP code to create a new principal at a DN from * KDB_TL_USER_INFO tl-data. */ CHECK(krb5_db_delete_principal(ctx, &sample_princ)); CHECK(krb5_db_put_principal(ctx, ent)); krb5_db_free_principal(ctx, ent); /* Exercise principal iteration code. */ count = 0; CHECK(krb5_db_iterate(ctx, "xy*", iter_princ_handler, &count, 0)); CHECK_COND(count == 1); CHECK(krb5_db_fini(ctx)); CHECK_COND(krb5_db_inited(ctx) != 0); /* It might be nice to exercise krb5_db_destroy here, but the LDAP module * doesn't support it. */ krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/t_renew.py0000775000175000017500000001176315051422640016322 0ustar ghudsonghudsonfrom k5test import * from datetime import datetime import re conf = {'realms': {'$realm': {'max_life': '20h', 'max_renewable_life': '20h'}}} realm = K5Realm(create_host=False, get_creds=False, kdc_conf=conf) # We will be scraping timestamps from klist to compute lifetimes, so # use a time zone with no daylight savings time. realm.env['TZ'] = 'UTC' def test(testname, life, rlife, exp_life, exp_rlife, env=None): global realm flags = ['-l', life] if rlife is not None: flags += ['-r', rlife] realm.kinit(realm.user_princ, password('user'), flags=flags, env=env) out = realm.run([klist, '-f']) if ('Default principal: %s\n' % realm.user_princ) not in out: fail('%s: did not get tickets' % testname) # Extract flags and check the renewable flag against expectations. flags = re.findall(r'Flags: ([a-zA-Z]*)', out)[0] if exp_rlife is None and 'R' in flags: fail('%s: ticket unexpectedly renewable' % testname) if exp_rlife is not None and 'R' not in flags: fail('%s: ticket unexpectedly non-renewable' % testname) # Extract the start time, end time, and renewable end time if present. times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out) times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times] starttime = times[0] endtime = times[1] rtime = times[2] if len(times) >= 3 else None # Check the ticket lifetime against expectations. If the lifetime # was determined by the request, there may be a small error # because KDC requests contain an end time rather than a lifetime. life = (endtime - starttime).seconds if abs(life - exp_life) > 5: fail('%s: expected life %d, got %d' % (testname, exp_life, life)) # Check the ticket renewable lifetime against expectations. if exp_rlife is None and rtime is not None: fail('%s: ticket has unexpected renew_till' % testname) if exp_rlife is not None and rtime is None: fail('%s: ticket is renewable but has no renew_till' % testname) if rtime is not None: rlife = (rtime - starttime).seconds if abs(rlife - exp_rlife) > 5: fail('%s: expected rlife %d, got %d' % (testname, exp_rlife, rlife)) # Get renewable tickets. test('simple', '1h', '2h', 3600, 7200) # Renew twice, to test that renewed tickets are renewable. mark('renew twice') realm.kinit(realm.user_princ, flags=['-R']) realm.kinit(realm.user_princ, flags=['-R']) realm.klist(realm.user_princ) # Make sure we can use a renewed ticket. realm.run([kvno, realm.user_princ]) # Make sure we can't renew non-renewable tickets. mark('non-renewable') test('non-renewable', '1h', None, 3600, None) realm.kinit(realm.user_princ, flags=['-R'], expected_code=1, expected_msg="KDC can't fulfill requested option") # Test that -allow_renewable on the client principal works. mark('allow_renewable (client)') realm.run([kadminl, 'modprinc', '-allow_renewable', 'user']) test('disallowed client', '1h', '2h', 3600, None) realm.run([kadminl, 'modprinc', '+allow_renewable', 'user']) # Test that -allow_renewable on the server principal works. mark('allow_renewable (server)') realm.run([kadminl, 'modprinc', '-allow_renewable', realm.krbtgt_princ]) test('disallowed server', '1h', '2h', 3600, None) realm.run([kadminl, 'modprinc', '+allow_renewable', realm.krbtgt_princ]) # Test that trivially renewable tickets are issued if renew_till <= # till. (Our client code bumps up the requested renewable life to the # requested life.) mark('trivially renewable') test('short', '2h', '1h', 7200, 7200) # Test that renewable tickets are issued if till > max life by # default, but not if we configure away the RENEWABLE-OK option. mark('renewable-ok') no_opts_conf = {'libdefaults': {'kdc_default_options': '0'}} no_opts = realm.special_env('no_opts', False, krb5_conf=no_opts_conf) realm.run([kadminl, 'modprinc', '-maxlife', '10 hours', 'user']) test('long', '15h', None, 10 * 3600, 15 * 3600) test('long noopts', '15h', None, 10 * 3600, None, env=no_opts) realm.run([kadminl, 'modprinc', '-maxlife', '20 hours', 'user']) # Test maximum renewable life on the client principal. mark('maxrenewlife (client)') realm.run([kadminl, 'modprinc', '-maxrenewlife', '5 hours', 'user']) test('maxrenewlife client 1', '4h', '5h', 4 * 3600, 5 * 3600) test('maxrenewlife client 2', '6h', '10h', 6 * 3600, 5 * 3600) # Test maximum renewable life on the server principal. mark('maxrenewlife (server)') realm.run([kadminl, 'modprinc', '-maxrenewlife', '3 hours', realm.krbtgt_princ]) test('maxrenewlife server 1', '2h', '3h', 2 * 3600, 3 * 3600) test('maxrenewlife server 2', '4h', '8h', 4 * 3600, 3 * 3600) # Test realm maximum life. mark('realm maximum life') realm.run([kadminl, 'modprinc', '-maxrenewlife', '40 hours', 'user']) realm.run([kadminl, 'modprinc', '-maxrenewlife', '40 hours', realm.krbtgt_princ]) test('maxrenewlife realm 1', '10h', '20h', 10 * 3600, 20 * 3600) test('maxrenewlife realm 2', '21h', '40h', 20 * 3600, 20 * 3600) success('Renewing credentials') krb5-1.22.1/src/tests/pkinit-certs/0000775000175000017500000000000015051422640016706 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/pkinit-certs/make-certs.sh0000775000175000017500000001230515051422640021301 0ustar ghudsonghudson#!/bin/sh -e NAMETYPE=1 KRBTGT_NAMETYPE=2 KEYSIZE=2048 DAYS=4000 REALM=KRBTEST.COM LOWREALM=krbtest.com KRB5_PRINCIPAL_SAN=1.3.6.1.5.2.2 KRB5_UPN_SAN=1.3.6.1.4.1.311.20.2.3 PKINIT_KDC_EKU=1.3.6.1.5.2.3.5 PKINIT_CLIENT_EKU=1.3.6.1.5.2.3.4 TLS_SERVER_EKU=1.3.6.1.5.5.7.3.1 TLS_CLIENT_EKU=1.3.6.1.5.5.7.3.2 EMAIL_PROTECTION_EKU=1.3.6.1.5.5.7.3.4 # Add TLS EKUs to these if we're testing with NSS and we still have to # piggy-back on the TLS trust settings. KDC_EKU_LIST=$PKINIT_KDC_EKU CLIENT_EKU_LIST=$PKINIT_CLIENT_EKU cat > openssl.cnf << EOF [req] prompt = no distinguished_name = \$ENV::SUBJECT [ca] CN = test CA certificate C = US ST = Massachusetts L = Cambridge O = MIT OU = Insecure PKINIT Kerberos test CA CN = pkinit test suite CA; do not use otherwise [kdc] C = US ST = Massachusetts O = KRBTEST.COM CN = KDC [user] C = US ST = Massachusetts O = KRBTEST.COM CN = user [exts_ca] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign basicConstraints = critical,CA:TRUE [components_kdc] 0.component=GeneralString:krbtgt 1.component=GeneralString:$REALM [princ_kdc] nametype=EXPLICIT:0,INTEGER:$KRBTGT_NAMETYPE components=EXPLICIT:1,SEQUENCE:components_kdc [krb5princ_kdc] realm=EXPLICIT:0,GeneralString:$REALM princ=EXPLICIT:1,SEQUENCE:princ_kdc [exts_kdc] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_PRINCIPAL_SAN;SEQUENCE:krb5princ_kdc extendedKeyUsage = $KDC_EKU_LIST [components_client] component=GeneralString:user [princ_client] nametype=EXPLICIT:0,INTEGER:$NAMETYPE components=EXPLICIT:1,SEQUENCE:components_client [krb5princ_client] realm=EXPLICIT:0,GeneralString:$REALM princ=EXPLICIT:1,SEQUENCE:princ_client [exts_client] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_PRINCIPAL_SAN;SEQUENCE:krb5princ_client extendedKeyUsage = $CLIENT_EKU_LIST [exts_upn_client] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$LOWREALM extendedKeyUsage = $CLIENT_EKU_LIST [exts_upn2_client] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user extendedKeyUsage = $CLIENT_EKU_LIST [exts_upn3_client] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$REALM extendedKeyUsage = $CLIENT_EKU_LIST [exts_none] EOF # Generate an RSA private key and a password-protected PEM file for it.. openssl genrsa $KEYSIZE > privkey.pem openssl rsa -in privkey.pem -out privkey-enc.pem -des3 -passout pass:encrypted # Generate an EC private key. openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 > eckey.pem # Generate a "CA" certificate. SUBJECT=ca openssl req -config openssl.cnf -new -x509 -extensions exts_ca \ -set_serial 1 -days $DAYS -key privkey.pem -out ca.pem serial=2 gen_cert() { keyfile=${4-privkey.pem} SUBJECT=$1 openssl req -config openssl.cnf -new -key $keyfile -out csr SUBJECT=$1 openssl x509 -extfile openssl.cnf -extensions $2 \ -set_serial $serial -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ -in csr -out $3 serial=$((serial + 1)) rm -f csr } gen_pkcs12() { # Use -descert to make OpenSSL 1.1 generate files OpenSSL 3.0 can # read (the default uses RC2, which is only available in the # legacy provider in OpenSSL 3). This option causes an algorithm # downgrade with OpenSSL 3.0 (AES to DES3), but that isn't # important for test certs. openssl pkcs12 -export -descert -in "$1" -inkey privkey.pem -out "$2" \ -passout pass:"$3" } # Generate a KDC certificate. gen_cert kdc exts_kdc kdc.pem # Generate a client certificate and PKCS#12 bundles. gen_cert user exts_client user.pem gen_pkcs12 user.pem user.p12 gen_pkcs12 user.pem user-enc.p12 encrypted # Generate an EC client certificate. gen_cert user exts_client ecuser.pem eckey.pem # Generate a client certificate and PKCS#12 bundle with a UPN SAN. gen_cert user exts_upn_client user-upn.pem gen_pkcs12 user-upn.pem user-upn.p12 # Same, but with no realm in the UPN SAN. gen_cert user exts_upn2_client user-upn2.pem gen_pkcs12 user-upn2.pem user-upn2.p12 # Same, but with an uppercase realm in the UPN SAN. gen_cert user exts_upn3_client user-upn3.pem gen_pkcs12 user-upn3.pem user-upn3.p12 # Generate a client certificate and PKCS#12 bundle with no PKINIT extensions. gen_cert user exts_none generic.pem gen_pkcs12 generic.pem generic.p12 # Clean up. rm -f openssl.cnf krb5-1.22.1/src/tests/pkinit-certs/user-enc.p120000664000175000017500000000555015051422640020760 0ustar ghudsonghudson0‚ d0‚  *†H†÷  ‚ ‚ 0‚ 0‚w *†H†÷  ‚h0‚d0‚] *†H†÷ 0 *†H†÷  0TX{uû†£€‚0•¨^þ|w”¾üÅ$õs–2Máð‡âmnLEߊa)É•.±¸'|žˆµvŒôÂe^ÎEýþŒ~zLAœìbÇåõ$å$/©“tïU©0ïê(Böд w¶tÉ¥ŸHÿ²?¶BÕ¿ÖÞ%„4 ZÌÒ$Ï4?×,kš$vP·Õ„Ž®­8tT¦fâ=ùzt9‚;8{}¥¸[PXÑmé–|·5mâG€r:«š?¾3áiŠHĺÇô—˜ê-· AÍ­›Û†#Éwà05CÝEí6€RL³0é|×”æí¶§¦n6Ÿ›áKÃy­tr¥A IÒ òóåÿl-QKôÝ|Z•㥜d.¼ðÜ)¿ÌwçCxdÑ–Z÷nž®Ëû€íPMzBxšìh…O½O“~ ÓæERa;tVH®~­ðyÛc ~¶B‚}³d¦Oê²ðŽ&cégñOëp ö0Ýå¡#)æ5~ƒžúb £‹ê­äÍ®űÚ4FwVQüê Ø`µÃji*Á§kô¹ùÐÑ·êÃ¥oÜ_eˆ×å™@(àe‹v÷BP#ïFOggå{‰[)‡`jø²_dÆÙéB~8•’ÿ~ÂûýÒjFЬÃtà)Þ:S•®%êP,u8ûÃrC‘%¯0Ó·MY ÂPÅéÑÈã×÷ÕöŸòÊ÷:I¡U†ùÔ9l‹ùz˜ü«.¾€Ü)ûè”Ô-@Q•Ñ{ãšÇ?·|†*"  âzMþÀ¡Žàl~¹D©d¦ÌäÝ•8£·¨®öÜ óþºÎh»—Ä+}䢞µBb>j³á\“¡¼e Ä\¹éÇÃ_5Ï›¿3Mªôê¿ãþ!€òº¿:8¤ÌâíTö*®dMÏF7ýëÂÁròLdÑ ›Û*ˆj¾t«íÃíK#nåJNKD•fmBf¸#ÌÇsC’/Öì¤óèúr†E×õo»•ÅÉgüÂ+Î&CŠWSF¼°íH¶ _-§GëJW×­”Å:éþ™s9]CïwÍ]ÉC ö1Ïúq»¿|PS¼ S;yÅŽÛåxTéÍ~3= žò¼ê™ä¬gœÂ´Øþ»›2[*RÁKnƒ¥ÌþÈRz†L% j92îÀÚ62[»ÎÔ[4•cjr‚,ÝßÈ2-Í!C>%>÷Œ5·Ž˜˜„Ä­ÿ{ÁZúïÑf%y6ì[ˆt®ŠßˆDéšî@°}Ãuß0‚„ *†H†÷  ‚u‚q0‚m0‚i *†H†÷   ‚10‚-0W *†H†÷  0J0) *†H†÷  0•íŸi¤Ï0 *†H†÷  0 `†He*öj†îCGŽÂCÂùõR-¨•‚Ð,VS+º½æX¨ÿ:¢fÛÔ0ÄöÌ"†fAdw/­<’(Í¢t¼¦»ô .&ÔŸ©ÖB"‹ÆÉU.âBŸbæHÖuË_7Wa`_Ñ–61÷ýhÈÿ­XcÁO¬ú?`à.wÏɧ®úÖLþ¡«x…Xà«Úæš&¥kÉvb5ð.( ?Ëò™îßy0&0Êàù™’¿Alá?£Y°· ÷†¥³µ²uŸáÌ ïcFgBÌG?ß]ÙÀ0ktòœhèvr6^HO\»ÎÉê1²x‹}±ðx¤¸ Æ¿½E~ñCD¡½rx I¯v¾ÉsÒ_ï…^ä›®ÑJi¨¯ð•;[Ó”Ô>Ï÷Ë,OEð««6£X¦*^Nïì_«²Ìõ^³Š…0(= œdl¾Í1*ÙŸ’æd[š!]e‚øˆ½L“:ïžuO9øó±Öâ±ÞÖVd²ëQ§­'m79I~¯5í p{Óԡ؆¿„Î!àLQh훜âü{r¨2 S]€_øÊ˜‘BõÕIcä¦4T=t¥ÞSI‰ñ»ón¶«N~I}‘Nƒú6ùè€8D—>jñìm8dϽхX)#ö²Y0½ÍCA!@£õ¼í¨Ç8î`kŸ–FÙùŒIP]mšá‡×hù_²XîD„S]íUeo¦*µ‚TLaöt”û-Mˆü¦Üu›¦ÑùReµF€ßÒÂ9–VÈÊHHÊV8ƒx0°¹#Þ j¨/¸2<—»Ûãý¦95À-ÛTäŸËî·º)Rß%, ADÞ`:̆º!‚_e'•ÓÍR–šií±õ…cÍIH‚$£3dŒY;ü•êwȤŽlËç'¨„ìµRˣʌ]Ƈ=ô­à^ÕIÕxÈa³®W¬cÞW3B:Õ&W·ìÉõ¾Ï»öKCÔ¥¸g]V [:ZT…ðtoaú·yyÐo¥T1c Š„n[DkUÆÝî‹tü¿õÖ@¦Â¶.`DìpžL*Í-Èò `šÆ›EÎä"9jFÑ3Pf…\ÏÚ¾Ó»(×lC)ñ¢xb*žœ’^ : ¹1ú6*–Þ,Ö­àið½rârÅ¡¼âHÜbÒM ˆ Nu½ÃWyd­Hl@U0u#YrT4TçÌ ‘é“K.Žçoaž¿à†k^­ÒkFîðË'ñEékNQéž„Çí„G¹à`Qe‘L¡+o°Ž~~Cvt(ø×há÷ÄÀм+,êâíûdâÿ@öÊ  j‚2´¡¦‰æÌ4ùwüab %dñ—};GÌé…z Œç©Ø›–+xŽ“–6qFˆé`”@(.\ˆç†o\ à`aMµñlA²Z'´0ß9rŒÇ³AœÜù1l|¦¿#ÈTâ·$MwKƒ#½Ï•äy]ekNâuö ¨Â‡ýe ¸õ¿ªŒF¶½ûã¨#[ËKe©4`B„È0—¸Ì°ÞpûQÉo ‹¯ã#8à¶LrÔâKå즖ËÊ帒ÿóú[Cï¾PcLì Pûjôñ‰e†ñG|GT­ÑáfCPŒä§7%ÉÃÇ®!VÕåi´]˜7‚ÞÖV 1%0# *†H†÷  1<Ë/lѪÖ¨˜=&úAÆ0A010  `†He ÈÆ~kz±ÊÓ8Ü"{ŒÑäñq§.”êÉe—Ô×7úQmá~­‚?krb5-1.22.1/src/tests/pkinit-certs/user-upn.pem0000664000175000017500000000326415051422640021174 0ustar ghudsonghudson-----BEGIN CERTIFICATE----- MIIExTCCA62gAwIBAgIBBTANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTI0MDIxNTA0NTkwN1oXDTM1MDEyODA0NTkwN1owSjELMAkG A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAm/1JtzZBJsdadmOTnkl94508ZSyYo5xP83sLT/SY5Cri1QKaFrue2kGg gl1QEOExBrIbdAeu5BftqiC07HyGgugtRo0qDHMRnQ4tsNExzYz69MOkFE4hMYjU o+9C22GVLihyoq+oELN7ro30u5/MCO7rULIp0HekLKQ+uANVVJx+xnW3bMJsrRIX Zx9kB0jIIugYt5D3n80vdIjHQJf2BTjsBWYGRJD4sTElGFtRIiD6m4puonRdUgtH UHZ7OCKTY5sU0PSGxFRLi/ykqcgPPQddHYCd5MRJj5q2NvPN6UYDbMfzqni0uDQ9 qdDjHj6CmRCHNKvkKaLdBfhdqFKuZQIDAQABo4IBVjCCAVIwHQYDVR0OBBYEFJI/ +nOV5fnNVxn2GkjkYbZ5D6mqMIHUBgNVHSMEgcwwgcmAFJI/+nOV5fnNVxn2Gkjk YbZ5D6mqoYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P BAQDAgPoMAwGA1UdEwEB/wQCMAAwKwYDVR0RBCQwIqAgBgorBgEEAYI3FAIDoBIM EHVzZXJAa3JidGVzdC5jb20wEgYDVR0lBAswCQYHKwYBBQIDBDANBgkqhkiG9w0B AQsFAAOCAQEAbe5/xDlFplE/h6BSqXSftjyiPgRlmPPkuTwiKHfmHYHv+KXHBDFY wuGDu4Tdh/qisskXJGoKYfRsOox6AW3ZTcklkjvVw0V73nPo+98USWYTzKq7NriF rJ9skYALu/Yv6q8iEoziOyDG55LppWne5KH0Of5ctikZVthxDnjm/saSR1lNa+8A gB6x9uid73qw+seg1/DoOdb+uHGnKBeSUrJC9vtdfodYdeatNFDDNoxqjGPajDNT TGI2ace2yZAgD/ic1MzI/s2eTHfzzO+puJIPzLScdy80RYMeILQs9g+x5NhOUuMz YMVFE0PAQLshVggtJ9l8fmHmrrJXP9BAWw== -----END CERTIFICATE----- krb5-1.22.1/src/tests/pkinit-certs/user.p120000664000175000017500000000555015051422640020215 0ustar ghudsonghudson0‚ d0‚  *†H†÷  ‚ ‚ 0‚ 0‚w *†H†÷  ‚h0‚d0‚] *†H†÷ 0 *†H†÷  0[¶µ=€‚0,œã ¦Â4ñTëî«\Ï^È‹‡ÿ âV&¼,ÄwxôÔU‚ŠÛÑg>U Nù-èŠö“w|ì…–8}4v\œ+¼íª…Y08ã;r,ªýeH´îv£F0Á3ÿÊ[µ^­²ºÉà°¢”̺‡+Aý»•ªÞÞá&Ü/z“´OÅyΞ;‚ØÂYb1†¶ù5ZíØíxû¾|“¶%‰+ÓïdNkIä¯[|@WÆæ?X4ÂÌ9~ÈR3f÷V½„‹ZDFÛ§³‡a6œRü6SJÑeÀL±ìÚ÷Œ¾ž!ß¿Dû $é¿"Ã%:L™EϹMãTY†H$¸ñ–äN›âõoùpº(_ Bn:¬BØÐVßV2ŒÃÐ+vÈV …§¾ïq e\`€Sã“Ù.ÞÏT¡r~ÑÓE5]^yFG¹ÿ©]š¢%JˆM"É9 «f9¹‡"ôza›wbå¶Åq0³âX¬z*üˆÕ§;’¹ÅÊS;L„˜ˆ¸¸gD.©Veé~­µGå{ý™çL²ä†ÑÍõ¸÷8V&×v¬Ž«${‹€í Éy„º‰µôÒž±÷Þ× ž~ÐÔ àöyMøaµ2wkýóô3›°OQ×Ü?OS1Kµ=z¶@E/>N m[9*Y«"4ó¨`§”××Õ›/Ÿµ¦ÙÄIAƤ……Ö‹,ô}Úœ%>°-Dß5|´vB„è\—ɤ£/xÛ>#í£Õ'[åÃ7ñbýVjjý0O¢V¸›4¸‹’þ´ÛOŸ¡’‡$Ì#¢1—í–ª–€ gn*Ðôº½hióEü²€€‚3FÛ¨­(¾¨ëþ-kl+Ûá³¾7§•çfÜ~z×sØ™o<Ò¯mjö§WäeSüìøSÂßåBÅ„Î&…3ÿ!f.$îEoM¡b=KçËß6s¦>fD¨ßà0îåé©x*úÂîðLÀËîbÈ=0ÎBYÄ…g‘’Oe¦¾Òcv¾gM±èï%v ¼’'!ÕlYÐ1¼É‹oà$ÓÌųØü~ðñì0»8²Ùžs2ì‹õÑ‹PÏEÈ¥Ç4ßZÂîgÊe)6¡‚® °2©ìÿ®‡Ä%+¸ƒyÄÊ£&•ÇiÌvT”RÙˆö–ĤŒUˆW©Í¤|ª»žS¸•lJ±äûÄ@µäãK*Ñ-?Ý1߉”k$ì4U¿zîÆÎRýÁ@!IÓĹP,ôãìç0jþŒË¤ §˜6Ö´ˆÄ°· ×XŸa©t; }h¯º#ö/§‡ßÍò£Ö>žk‹ÞÁ…ñú—`ƒ‘Ä#òO´¯Dx Nö0‚„ *†H†÷  ‚u‚q0‚m0‚i *†H†÷   ‚10‚-0W *†H†÷  0J0) *†H†÷  0OŒü9‡0 *†H†÷  0 `†He*/Û¼³°7ÁP¿ ˜}î‚Ð u„¯ÍM‡g¶UeF-7HöÅÍÅù6Ž`ÀåÛ`@þ“mU=¶»;¹Î ôD\Ù’N?^ î„Tok‘Íýýbëšüä¾f"‘¤fð,–´ˆÞ2×oùð¬{kPÔa´…Œ ¬xwÙxW°Uj¨ã½ìsPïñË{S"á ã?SHÃ]ýÃÃë—*l8£·0u¿¡› ˆ #lÕÀ,«Í=Ç.u­d9Õ>«É‘6ٳɕzoŽvx©ómå"÷A­Ømø>ZȤ}…xx¹˜G“™¹ÊŽ>–8x¶k.Ña8Ý4†/e„ Âjî~óàsb©¥¶² XÞÕ ¶KôÐŒlÃðM“CG­%Vçï,œeM[oÔ_KJ»Ó9-NrÕK1Rê^²ÑX—Qe?6udª¦Nj÷P^ïû÷£O¦Ù y‰‰´‹Ú†˜É–d4ð´r¹E”k ÍØÆôÓÄ}Ž7ƒ@˜"‰«?Û'æÈöàáA.^£BAß½¾e†<ô†q×ì·B‰«¢ã… ÁöV›{N~.l\sÎ%0XÇ,åað"ëN%«¤Wø‹Áö÷|‘ÿò ÞÈ.E›ÄÔÓó'£˜ä-Y";š^ÒÑ#•Ö³ÓØÆÂ@¡ÉÛÛ-"Û£í„?£EºOEb°ïü¿VÂwçjÖ¶’’!¼ ¢"Ï÷.ˆÙ_¨<µuàfkªÿ¿× @ͨçìèS#§%ï"ȸiRiÕÀa­œ/ÖU©Ÿ…Ó*ò1bú‹ä·ôÆÌÒ])‡h€ÈÖ8¥‘åÜÔÀ²˜g+m xr ¡õ v‡,M¨o›Õs>ž1»ý„b#\ÿ˜™o4.zÈ,eÆ&›£]Ѐ/a'½@ÀǽüNÚ' ¦n/T:NäÕ1½#fêÌIšÈ C ÌÑ›š“‚Y.Õ”óÕÜß©ýAARÒkãÐ$ÿîú‹Û ËÀ6êPSд=½à¯ßÄ£'þ,¢ÓBýp(ø0y®{üB#ìÀg¬@ús"„ÿúØÉí[A¹øvk1Ež›Û ÁkëÍÜäêµxôf?9(ãQΗ’²Ê-"õN•ùÊÄ{‚ÍS0Déã6=–/8¹Ç¾Yôš=Ê".’€°c‚%‚S›;ȪÀÈ6©‡Q¤M™½lF¥ŽmÁü‰b/{ë—äýõ+·e i€R-˜^x5R¨ecí[VyƒRF6¹Lhù®'IÎ@–öQî~¯¸:eÐ&Ï~¯Œ;`‹=´û¦¸0IûdŠ®ÈôW×âKb²·…bï=ðnËLÀ{]ÝgdÑ4ä]­ä‡Þ0‹¿¿+ø #?… ¬yo'~ï»}Ÿ¼Ë)OÎû9Ë7ÄHÙb;eJ~þù¼Tu¿Íì’ÃÐÜ[Æ)ÿ!œ:E…–|ɉM‡êf£ÈÈHSkuxÝFÍòßKÿ3°rPjmºæpjº$‰S!V£åš5Ý®ŸW_`¼oKv±¯JR%îPŽŠçõñDêQqiÔïUŒƒ»]ï„Ì1%0# *†H†÷  1<Ë/lѪÖ¨˜=&úAÆ0A010  `†He G¶µgeÇ™/¼XÕ?G_`<*~’lÊŸ­ƒ6·LyV¢D1DoH ½muxî_,QÛ—Z«*X:&ˆn±ßúç²I6IÒ~œ­ž)Ö/ÿ!Ïðú]K›=¢60>l‚¡‚Îmä6M´®!Ûͤ½©&Gßó·Ôt „ðº_ÅÔ׫r|)rn ¬µí±OfÎ˲Êè 2ÍnqÃÖd^ i.ýÓ-A=ßéÔ9ãÕRK)åYÒæBß8Dô¦ŸkÍV$yííX7 ¹ô΀°©JƒF4sAë tc6YCsî º¶‘÷ñcX½,8æŸ'«`1„Þ™"1÷ùĵËóùÖä|îUCHã{-½T\ÙÜfê÷t…Ο¾ðæ¶ú<`Û éÍ)KD,Ò-t»Ähæ$Nž…T©r…å<™’æm% K<Èé+|u¿Òhh„xX/{ýFZº oˆ;4oT”aR~\!¸kòˆOth@ú‘¨«ÃÛ.ö}(Vß:i,üª)h¹³K5ÜûXûŒ©xâDØ¿±Cü±§’ÁÇ€d‚ =ŽÙA‹1í³+¤ÂVõižxÇ&ÊBâî38+Û^\ö }\‹ÓŽÝœò%­ˆg•d]!-!JÁâÁ5`þPüõ²U]—©R‡rBá ¨6ŠKÄUÜ‚1aGÝxØpÞ½ SHß§æ+ŽsC’ž6¤GŽKîB<ç•ì·ôþgï¸_÷CÌ@Û°5ƒAT嬃÷ÑÆ—:çz%ðF°Î"™²káß%»Ç`v]‰X®jþ‹fÂ^§|¤O?Õ4œ]Žž”ÔlÂwÂÿ$Y¡Ü€*Q !é‡â;‡EŒŸÉz»ÛøË<ùšûÀn}á‰Kšž‡±é¨pdu>Íü¼I°†4Uî .ï)pϼ@›ž˜Kù"êŸÒôyPØU§Ã¦Vá‘ít¯Mg€h§vù”L[ŸÏ˱uÊ€€üCÊ2-!c±kÞ*²gS^’¥ôGEù[xoº‹!5Ç.Œ…ÚL$ {°lôtŒXô e¤[EËp’ü+c¨Óœ¬²šy!6 ¡oYmaßµ¸´RMk›å¹Ó Ä¢D¯¥Ðxîe4N]‰ÉçžnÏ…%Vô Å>ÊÂ/GßMHy=eå|X€†4W2vĺ<ó ï®/t\h_c o6À¸wê yÇ Òµ±š/ÐKá5Àù°¨òv›¢Ÿ:™Í-ãQÁÍq¢@»ù531²¡¹ïãØÎtèú¹ÕVÐgŦ2ƒt Âü¡‘ìÝÏœÌisx484ä{ü5ÚáÿqÅZ´±¬´¢%* Ž-&':¥¢#ÑcªSCkæ`ý"½µËC>¢ÇPêÊVeýO?]q¥éÚÄ€Sô¶|§ÔV9?× ú¤® •OÝ«#þj“™ß«v¤…âét¿H{£Ÿ?’%="d(ˆ¬²|<‰äbë]ð¤¿*u¼ùn¸CáˆO©F“\Ò3âhÛX•N˜ÀWR1?¤K—ŒÊ½Æ Ý¡u>f{VlÖú0‚„ *†H†÷  ‚u‚q0‚m0‚i *†H†÷   ‚10‚-0W *†H†÷  0J0) *†H†÷  0õÏàÔ _‹g0 *†H†÷  0 `†He*æ¦_‚–av;S,ïóý!v‚Пë³]@ð 8/a†òзâÜ–´±³Ãxž|ÌÛ–Ù˜hßdÃ$"®),þÍ5%Íë¼3Ò…Ñ©ïÂÈÂ+èºí Ê— ¤fmHÿ&²©Áß…§†û hç½NwÇ‘<¨ë<öNÖ­O!̦¹Æºê¤ÕE~Ú="^!@1¬`QÀ_pDšë0˜«(û´áKHúÚÂ6³ã©@7jðUä:pᑎÚhžÙ[‰L>1¿“,áýöǸD¤1¦…ÆšÆKæÜÜOoÒ(Ô!^Ë*ÖÂ\Vræ»>yÇ^ ½ /ç]Χ58µŽ¢iÎõÑÜJ©u–Õ3§wœÅØeƒÉr¯7:xªˆÒ/yÉ¥ ¸4w«ÀžR£Ì‡ïÿtáʃ²¸ùÛ?Uª“nѧ FÇBssDËu×<ÎU\rk5–ÑÑ·hÂ:WÃÖ¥Íh£,ðh|±#üãáߣëëhœTÝS“9ýþÀ4ãï–þžþ’ÛúžôœN©ŒpªYT{îMÇûFôhVö¦ì‰'÷¹Ð!ù³àYÀ€b–_'ãPÀ‘]”˜|ñ¡÷Bo£3‰iY÷F¥/Ÿ/Øèéù |}‡ËQÔJ6_ éå ò½a`ÑŽ›A¦‡‹ª‰œ{õ³ÂYÔLVã–=ln$´{ìï5Å“¡9ÚYøT·WUNW¸‚~GêÝ`Cðc¹9y[®©ËùNXšä=—ô€è@øFåŽ*tK›e*D«šH6ŸŸ[6ž*Ô“zÐF(}99A—÷zï#ª¹oêbІ¸bã®lE[›k^:KÄF|UÃü;ÅîDoZ‚ª“žY§êÀƒ6] ïÐ4ùl Â_•¢P-Ç÷“î ÜOûæ}%ÉO&âèÕ'Ò •'yútmn=ß¿Ñ&r§Â9ŽøæúÐTQ$‚ê¿2Ux¯Ã4öµŒ–@d6) /yÞ0Ã>õh÷Ñ!õ¯ÈÓ;ÃC](ªÁÊL"é Çx —þB„îS WÎ4 Ë„¬Í”°Áœ@ÇfdçÌPÓ ûsYd¯´oÉ#&cuXU¤ÛÈZ ±#«´F÷Jñ´‘mGa´™ý¶Ô$Þ|Ýföù'm'=±%œ ¹Å˜¹ž_Cï?RÛ Àå‰LRg¡ë(Éñ ºð8Zä–ôH7@‰SÃäUž9ǯ1X2n@?ÓÔ’E03hÇ_&áÚXËeŸ^ßá'[\/TQ$½äÿQ}ÍQ½™*P½Ä?Z«¶I €†ALÕ°—rÈQ2G ñ³é!‚t†q&µd6A!€‚ÈpŠ 7+‘U–ùjh|î+´ø‚WwœÁ LÜ » ±€ª¸ÈáàwACÂÑ•”I»U˜D¼('‡©¿Ì•›ûh¾À3bD‹dÔ‚â÷y SuyÌ}¢Þ†\d{sYz[{Í'î&7Ï‘j£w\0ÜQ‰;éˆE½p_L쵂ö@›e™Û2Ñå¸P‹ú;øzx•šyVÛvmufC¸cì­ˆUM#„FÌÄMñÖÐl~‡¸ÇNÎß‘þ¶c©7äs˜,Ò;QhJ¾®I¶Ð¬lâÏCl4Ý(2Áë»Õ΀¿6\nDÞh Å ´ÄM‡G×Þ|#TÒ R=5¶òtJT£s4ì[ÊÁ¬¥oo2æ8*DXc.úò4§ƒÓJ¼:‰jgСTWl*+ËpÒ;Àá .ÂPÔ±Ôþsîʸ?ÙÀO«v"Ÿ˜z¡g1 b—|À9aw…\N\E}UÇD¸ˆ QÝ9"¦‘K¾|cK=€]_HÀ.$z“ïÈ”;íý²áÔžT1 lÝ‹d¥ï|[žDkRx^+]=YS¼”`ôÅz6¨Fóñ¬:Q§“LÓÇ «¯’{ƒò·¯-Ž&XÕòÓS¼èpoñ x*òiÛzG\@þi›±Þ¢Ý^3Ó9\„äûS sÜñAÞ}Cï1$oF÷B\±²ÌìõGo\á¬ø½)®Á $&ÐzÖ–ËßÙ ‚GVq4/Š…O·t§ñ‚Á¨CÞnMÕìú‰.gYÆé‰|‰ßЇžqPÛð‚*ƒgàÒÏ´GoPÇ“y’vHU½cÖ åøÊ.¡¬—Q$3je(ò)Ðɇ¥zC‡Â4ÚZ§sÒ9äêTZ¯‡é±î††ïä/¤Fá÷ð =l— ̦ž¨¶¡ÑÁ0õâ(ëhù¦ÁV1çÍ’P"GTHòpÓmÌåΓwÛËñ$²Ñ¡†aå3U@¿sE[_ªKÿ#hóz…µÎBè\¹»a~1‘6<+ñ¶”–4pSàÒôf™Bž¿‡. —hªéú„tÖZÖØi0á¹±!5¬§ŒS‹1æ6ªðàñJ >†ÃŸïj>†2…«â•ÝÞĺ#­Tëâ¡^ YÇúVõO@=úä_ÔdÀŠ2Nƒ~ë¹6@­)Á»eS‚BÑSr†,3Ç—Þ½m Ze1ñ#ð2\.êβÔ,øá¡ˆɯKzÂx)ÚDux?»¾‘ú{ÈD Õn_}þ§E÷o2ÜÝ"Í÷ö ˜$ë\ûsY àTúôÜØ;c®qÑžñú=ûz¨Š›¨(Ç LqLÆ—P–o@2Î> 6’—r?ø®ÞØÙv©3~‘]µ$ƒ*³: ÀS–Co†æXÂXKê ;#kŽào¶6ÑÈ|m<¯1Sg¥¼429²¼µ¥ï„²ƒªÑ@“¼Aù [·õª¶N TØ,¾C¹F; õeUˆ*h˜íuÇWÛÙ!Ñ6ÏÌ `õ„»#ïyó*x S6Ô…>Œ`R¢¾<¼¦m÷µO·ý;}ƒf¶¨ À*s;]pÄȽfg© WŸ§ƒ»®ˆ{|_gýâ6y×° àC”•@iÒ†K_ïë 5|Ö•#ºæ,9½ž&©v¡aǼ åŠÓ ¢ÔìûQˆÂç¯iZ……|âŠ]!¹3¡ôÈl*w7VËòß@CDcì¦àx‡s¶o3çvÀ ªÓÙGL¢:\¾+ í:¼šaŒ± 6ßžãØû nó<`/ø¼ƒ§6eÀÈ’yŽÁçÈ–Þ}G{ÔeŧÓY°T,Á){fsÆcⰠØ7ºSœò2éæü“ZÓš xIÚ«õ5€¶Tyñ\Ñg v¶<è§+F–Úk…ã列.ÝðyHª"—ØÝ—8' ]Ò£â\sž³ý}¹Ëä%’ ¼ ^È*}µkˆär ÝvcÄøV‚1YǶDÌÍ`/˜êF :4 äZbs¢ ¨±©±XlpS›ÊÑg Ÿ–¤°²÷Oß«Ÿ'IúÅ÷z…šp¹lVȧÓÙKÁ}„qMЩ:ûÄãExû¹µR‰´-½ú aÙð‡Í1%0# *†H†÷  1ÂìŒUQ¨Æd:<:N ”Ϻ0A010  `†He 8l§–0Ê^ñðj"©é]„Æ™lN9Lß÷¦ïMZ—‰ëˆvã¶é7krb5-1.22.1/src/tests/pkinit-certs/generic.pem0000664000175000017500000000233115051422640021024 0ustar ghudsonghudson-----BEGIN CERTIFICATE----- MIIDZjCCAk4CAQgwDQYJKoZIhvcNAQELBQAwgacxCzAJBgNVBAYTAlVTMRYwFAYD VQQIDA1NYXNzYWNodXNldHRzMRIwEAYDVQQHDAlDYW1icmlkZ2UxDDAKBgNVBAoM A01JVDEpMCcGA1UECwwgSW5zZWN1cmUgUEtJTklUIEtlcmJlcm9zIHRlc3QgQ0Ex MzAxBgNVBAMMKnBraW5pdCB0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVy d2lzZTAeFw0yNDAyMTUwNDU5MDdaFw0zNTAxMjgwNDU5MDdaMEoxCzAJBgNVBAYT AlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMRQwEgYDVQQKDAtLUkJURVNULkNP TTENMAsGA1UEAwwEdXNlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB AJv9Sbc2QSbHWnZjk55JfeOdPGUsmKOcT/N7C0/0mOQq4tUCmha7ntpBoIJdUBDh MQayG3QHruQX7aogtOx8hoLoLUaNKgxzEZ0OLbDRMc2M+vTDpBROITGI1KPvQtth lS4ocqKvqBCze66N9LufzAju61CyKdB3pCykPrgDVVScfsZ1t2zCbK0SF2cfZAdI yCLoGLeQ95/NL3SIx0CX9gU47AVmBkSQ+LExJRhbUSIg+puKbqJ0XVILR1B2ezgi k2ObFND0hsRUS4v8pKnIDz0HXR2AneTESY+atjbzzelGA2zH86p4tLg0PanQ4x4+ gpkQhzSr5Cmi3QX4XahSrmUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAau8fw4h1 hp4/gp7l+AXvq+9E/a2y2Np+H8BmlRIg8ZLyKjRR6iPjcUwFWUteSSBsFzcc+/5V /Qs9gAW4nRIb9zY/sPO3KMAjJGKaP3u8xWkrfVZzaqPkfOWa5RDkh9AtvpN/fVLH dC+hC1xlXtjJ/YugJD6OA66sxdyTjR/v++0mqaTQyTI29HqtTc9LUcpbC1OYzxS3 8vlZZgieRU0UlBvpsR0AqCaTZPgcrIvJ0EVIk6XzgOWJAptAe3tFEVrHtZJAQG04 TI7NN/zw17O9Sn8NVEB4RSw6CFZeEVBBfCZL99HveEd8WPU0zgYceuVl/UCpQFNi Av6/+n+/6KwHXg== -----END CERTIFICATE----- krb5-1.22.1/src/tests/pkinit-certs/user-upn.p120000664000175000017500000000554015051422640021014 0ustar ghudsonghudson0‚ \0‚  *†H†÷  ‚ ‚ ÿ0‚ û0‚o *†H†÷  ‚`0‚\0‚U *†H†÷ 0 *†H†÷  0;HÙˆû…Ù€‚(†™h°„&žaXµ|oeÒbæ‰+Ti™^â³Îc@§ÍœªnprOÖ»iB¢D3I®ç:SÄIpü Î:V3F_ªð/ýD£sHNÚàž™&W› w ‰¸ò•Ý*ôby¼òC¾üâ¶N L;|zñék%ø‰¢%Ò:”Ôã1ú›7SDÇ„?B€lŠ¡ú&Þ¼$F=.¹ã¦ïd^á±ÀÀ©®v«%þ<-xŒ™ÿ3wÖ,<ñ§Ù²Œ÷wçô“ßã—›µKÅVqç?&ZØ«‡@1zˆ m‚µ¡¦^FQ:;rP0 É_/³,0ãH¢Ç+Âøs:Í­é²üÿóß2\ê½W8zU­ŽŒ^—kš‹„ûü€\&í߻ɪì4;”»tÄþÀ´ ?óÏk->8ø¤o—мp£öx¤xôü7Ê8ؾ±¢]V“\{ØÕp7¤¦Oaȼ‚Õ(ýJ. Å‹?\€h>©­õÇ®ØÃôbãЯRjki9ľÿïŽ#P´•;UAÑ8RÍů??#Õ‡s¼vòà¢èÜh_²»¦»q„²ößøÅÞž®›Ù§³Jç¢aÇ»Ò!J|§ =ºÿ}?F78¥Ú££¨F¿ÈÝ]öââ™eùÔÈ3£z¨ÉÜ.ÔöƒÞA»__ĘÞÕF·wZCtéí°Ì˜hyŽ,=«ðvŽ£eÜ*.Ím³Ä{¨´ZO`Œz/UëÔ ¶Ob’ƒöiorg§M=ÒäŲGRunN2¤é®Hö‡«ü%5CBdØrn¬²÷1já½nÒx =},ÞU;{à0 ˆz 6²–q÷ÆÐ~uôI v8œ²i¸J dÝi>™Û²÷JÁêî€IÌÖ–Õv7»V´Ê‚Õ2ÿ´'éRF})_Û½§…·™^¿\ºO‡'ŽÉ Æš/6,?™fu ÚU„·¥çÚ’8Ý“’ü l܇ÏÜ—heöÚ´ª¬©‰y›ŽÍ¤VÕö‡u븳Â)@HM“hG½]¹Xb{d¹°=4üOе!DšÚ@L„Ñ¡ :ê–<à7媢Oͯ:†]‚Ò¨«½w°_Ëy•PÐØ’ÃIh¥nPx—ÇÉ).BÀqüÚœÜ^º³|Ïrb3 5†œJ!ͶNôÍh%º^™ˆlk€é¢ñÂàªEVV`ç fÛ¤Öûa ®™2DZðŸÃepƒ(§áÌvºnÂÚb‚ÐãY¶>4dØ©"÷n›s²äö§ÐA8K¬}z &”9!8¥=°í¶÷…õß^Ák“(DÃnˆ©–ûhîY©í¦:ó‡jaVðFíC‰zdPox2ÿn €96`Ìs õ!Y¡sA=½ª³·û,Ó }º¡#RŠ$‹å`MÅgÃׯÖtÌW9Õî0 yfÏÅòšà•ïìOËû«fÁ-µ®Ÿ±ï…ážSqXû-þ3,RêÓŸÝôceMoò¤"Š˜ ²­ƒÚ­È˜ÆCü¯—Ò4ã¨vŦ ¦6é¤ÿ~ƃ“Hî( k®=u±Û¢Î*;*Ïòö½e/ ©–¡ÙÚÙ¡¢¸šÎ% å„]Ë™L” væÌjBl­žÈ„ˆ=¦.2mûü½ƒÎ[R"Ô²CâŰñ„«¤l‹ÛqÀ͇ ¨ñ¢›ÔZ1¸ õFÚU´IŠ¢0‚„ *†H†÷  ‚u‚q0‚m0‚i *†H†÷   ‚10‚-0W *†H†÷  0J0) *†H†÷  0Ø©Ñ ÂÈ—c0 *†H†÷  0 `†He*À4±ƒI0e{®}3»‚ÐÅ÷ÂÏÚäÅ:wû¼Œå:~ÍoÏ–Ä $ lb#ì2®†SÜX·ÿ{½(f DZwá”÷ëàÝȺ…Á¯g‘àÛÂÅÜ·)o€ñ2í¨¹æ X/@컊)¼Õaoç8žÞîc]z–©»³D¤Í í@{¼Õ·R DÈI˜¯F`ìÞTõO8‰Ã4íhD@âAì A,’Ò\çón€ðÑå™í4½úA56Y-›¸•Ñ D!`Ãú…&í\OÑf c³s,õ µãÅ”!BË]Ääû?=:«¤lnb¢6¨iián#©Ë»UJ™S”™×m8=iÿÁË büÔì}*Ô»Vk'É'"55%« )v´€z9à¡Oa¿\ÿM¦¼¢ßæã5cì*øpyLn19\ ”—¶ZÁ¸³Ô¸†*r/>Ôt&x~nƒ¶÷u«‘Û,ÞüI*¼@•ìkïêjì8Ê=ÝÆòŽõG½ƒŽÌðÞImÃr¦ÎØlóU”’pñÀ‡ƒÞjƒ&_[•Mlz±>1TRÄÙù˜·9 P¦gÈgÍj‹3VggS/¨ýÁHF ÆÃÞß8²Áø‚àN¥`ýÆg‰ŸØ…Ta »5=­<#ÌmÔá¿c1ú¦eMÉï m g>ßïF»Ž½+‡6Ùd&Bô2ÁVi!ï3î Ù§À“ÒX2ê·»=H#nëqMœšys³f³£È–ò¡Vú޾Êh°ø^>dÁñ4çÈït4{\èÙbV‘¶Ó$°]‰•­¶ÖƒilϘ Ëy‹‹¶/IU‰3¡ÏtQd¨K…£LÝËÞÕtoülÒ|ò—˜iDnmÐA«+­#a 0uÔTA¿ µŸN~n¡j¬RjG@VJd®GGO½%Âü¥Þ*¼KjœÕv‹ð˜G“¢(÷š`¼(ÁW‘íÙŽZòÅp-“Wáø`RkݧžPžÿ^} Èݸ{#äÀ«M€Î¹„4e u>…yçp)?(ÀÝ×ì8F笻äÄ |‰-¥úù›¦Ï–Þ4KÁ®Š‹Û2§ò|ìÙšçà—¸L¢Xôg¢e‰,&A*±…Ù¯Î-ÓJddyäüVþ ˜åÐË‹yJŠ|Ôqïý¿ÒKVÞ<ƒc) ¥ZYR|_EÍìk’ï}‰CŸ!ë¼Ä‰Þ³ÏJv ú?FŒêôŸÃq¹L123ÿMÚ´Í]4KÔfŒº…‡pŠ›ØŸÙÀãdÇ ·mof\N‡.9c‰ÈHŠ¿ 2;ììvx Àï¿Fn•¦ ¢0ñÇr·{­Àk 3è.«©uR* ìËA Ö0-‡ðžý)/oF{MÕcmÿ’r™\Ö„.¦Š¤g€PÚ^ W7*SÅónFj”Õ1Bå¢ÙWd÷ÕÁ¬aüºožÛŠž¥.3~^†4{5ÂýQ¨Ué(ùf[Àïr“ñ½)¿4˜ý(qœCûGä'|±”vÇxµè+15Ý*Øv†3\®Ë÷K:Ê*íÛ¨£{4D╵º1%0# *†H†÷  1sG-Ž6Œº’#’Ù7%1­Û2è¬0A010  `†He Ù&Ü À ˆ¯gÝ“wºÀ…3)Æ‘i8(O¦ô¤eŠ$KO YMkrb5-1.22.1/src/tests/pkinit-certs/kdc.pem0000664000175000017500000000333115051422640020152 0ustar ghudsonghudson-----BEGIN CERTIFICATE----- MIIE4TCCA8mgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTI0MDIxNTA0NTkwN1oXDTM1MDEyODA0NTkwN1owSTELMAkG A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF U1QuQ09NMQwwCgYDVQQDDANLREMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQCb/Um3NkEmx1p2Y5OeSX3jnTxlLJijnE/zewtP9JjkKuLVApoWu57aQaCC XVAQ4TEGsht0B67kF+2qILTsfIaC6C1GjSoMcxGdDi2w0THNjPr0w6QUTiExiNSj 70LbYZUuKHKir6gQs3uujfS7n8wI7utQsinQd6QspD64A1VUnH7GdbdswmytEhdn H2QHSMgi6Bi3kPefzS90iMdAl/YFOOwFZgZEkPixMSUYW1EiIPqbim6idF1SC0dQ dns4IpNjmxTQ9IbEVEuL/KSpyA89B10dgJ3kxEmPmrY2883pRgNsx/OqeLS4ND2p 0OMePoKZEIc0q+Qpot0F+F2oUq5lAgMBAAGjggFzMIIBbzAdBgNVHQ4EFgQUkj/6 c5Xl+c1XGfYaSORhtnkPqaowgdQGA1UdIwSBzDCByYAUkj/6c5Xl+c1XGfYaSORh tnkPqaqhga2kgaowgacxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNl dHRzMRIwEAYDVQQHDAlDYW1icmlkZ2UxDDAKBgNVBAoMA01JVDEpMCcGA1UECwwg SW5zZWN1cmUgUEtJTklUIEtlcmJlcm9zIHRlc3QgQ0ExMzAxBgNVBAMMKnBraW5p dCB0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZYIBATALBgNVHQ8E BAMCA+gwDAYDVR0TAQH/BAIwADBIBgNVHREEQTA/oD0GBisGAQUCAqAzMDGgDRsL S1JCVEVTVC5DT02hIDAeoAMCAQKhFzAVGwZrcmJ0Z3QbC0tSQlRFU1QuQ09NMBIG A1UdJQQLMAkGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggEBAHGR7TUjyGt7IbqD MW/MfOkLtvpv1f3MhbRSmYDweGKejh2xQIONC/BlaBA2RWmhJIYTdc8wPRlcC76D 2HLhBmGyOSy+ZTX/txGhtXm+xzNuhLF95VKDd2Z+06CMe1CptH1fvnf5YaZsUgv4 nXmRN2i4WWrVHoWsAFCcEM6PqT9j/2485DbjtmoS7nVNvO0UKJs2vGgZYuxgYQsl S387YJnSbC3/VjTHGBh+R7oRZ0cBvpviWyp5Xak0kNcWAUSu3Oa1FRYDz6Cw/r7/ wrTWxMA9W3Ygzeh+JFpYZkj5BNrwFem8UxrM/g2ZvXVS81dKGfA5spEZ/cEsAkU1 8mWgcJY= -----END CERTIFICATE----- krb5-1.22.1/src/tests/pkinit-certs/user.pem0000664000175000017500000000330415051422640020367 0ustar ghudsonghudson-----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTI0MDIxNTA0NTkwN1oXDTM1MDEyODA0NTkwN1owSjELMAkG A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAm/1JtzZBJsdadmOTnkl94508ZSyYo5xP83sLT/SY5Cri1QKaFrue2kGg gl1QEOExBrIbdAeu5BftqiC07HyGgugtRo0qDHMRnQ4tsNExzYz69MOkFE4hMYjU o+9C22GVLihyoq+oELN7ro30u5/MCO7rULIp0HekLKQ+uANVVJx+xnW3bMJsrRIX Zx9kB0jIIugYt5D3n80vdIjHQJf2BTjsBWYGRJD4sTElGFtRIiD6m4puonRdUgtH UHZ7OCKTY5sU0PSGxFRLi/ykqcgPPQddHYCd5MRJj5q2NvPN6UYDbMfzqni0uDQ9 qdDjHj6CmRCHNKvkKaLdBfhdqFKuZQIDAQABo4IBZDCCAWAwHQYDVR0OBBYEFJI/ +nOV5fnNVxn2GkjkYbZ5D6mqMIHUBgNVHSMEgcwwgcmAFJI/+nOV5fnNVxn2Gkjk YbZ5D6mqoYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P BAQDAgPoMAwGA1UdEwEB/wQCMAAwOQYDVR0RBDIwMKAuBgYrBgEFAgKgJDAioA0b C0tSQlRFU1QuQ09NoREwD6ADAgEBoQgwBhsEdXNlcjASBgNVHSUECzAJBgcrBgEF AgMEMA0GCSqGSIb3DQEBCwUAA4IBAQBRWsxPb9miF9xf8rEIfVko0qBy8doEJsPE IVD9Jz/Ml/TBZRLbi1b94l15Fto/Z6XKf8jrnBs4krf6tU2D5PUZXZYZ6tr/2kkY IpmoOkEoQX8gtcZfaq2OJzsKHnAJT159EVydyYahHU66i4aNvho74oAafrVTyk8B PHCHFs0MUct8DoNwrbnfH0cjqEdVOmjjvBN0yA+RxOa543XnQqkSmCuIJKoD6pUa 07rE372iERgIjDnzCogiEo9cCBBqDfgsbr0ah1QbWJTJvnsFuxT43tBNurRjNPoX Jj6xAzhQLCuvqtKtWlAUOHut18YbVGXVT+3tm7+C6iA44JvMl9m1 -----END CERTIFICATE----- krb5-1.22.1/src/tests/pkinit-certs/ecuser.pem0000664000175000017500000000266415051422640020707 0ustar ghudsonghudson-----BEGIN CERTIFICATE----- MIIECDCCAvCgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTI0MDIxNTA0NTkwN1oXDTM1MDEyODA0NTkwN1owSjELMAkG A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE MtBPPHtQl9ev9sC9k/pxNKZpW+8ATNIToept5trg21bACESX4RIx1rE9jgwqAbxg 1erwXiDlIxP0aPRMJ2AVuaOCAWQwggFgMB0GA1UdDgQWBBR5MaRx7ub5YBwsS0CF Li18nsl49zCB1AYDVR0jBIHMMIHJgBSSP/pzleX5zVcZ9hpI5GG2eQ+pqqGBraSB qjCBpzELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNV BAcMCUNhbWJyaWRnZTEMMAoGA1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQ S0lOSVQgS2VyYmVyb3MgdGVzdCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3Vp dGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNV HRMBAf8EAjAAMDkGA1UdEQQyMDCgLgYGKwYBBQICoCQwIqANGwtLUkJURVNULkNP TaERMA+gAwIBAaEIMAYbBHVzZXIwEgYDVR0lBAswCQYHKwYBBQIDBDANBgkqhkiG 9w0BAQsFAAOCAQEAfwlONLYPo0BNN2NyQZM3wkoldvFqidcoZiYALOcBcmllMP7H XQ/+en4TmbKR0RUJN6AjR9yEo92fHAYOB2L7AzR8AkOiRLjp/Pdg5kUHFTdKenTK DvpeiJELz9chk/vaMv1T9qvOwH2bVAyS8GrUc5n0ui5F61PrquLAmm+dpKyHDY60 DdFaebS2gYsmy4bBv0mgcMZ+ZXnzXYmLNtdVQ3SgVGO7M8eyCqPbe/o0Lw4Gz+l0 xgpFkptdlEogsOaJBzjrgWyBnWw6MkyyLiSY+iOxFpBGkwCxi1gtQwbcp4gMwaxc p5+JPM/JBfglBX1lpRhhxL8EGQvpryN9MT530w== -----END CERTIFICATE----- krb5-1.22.1/src/tests/pkinit-certs/user-upn2.pem0000664000175000017500000000324415051422640021254 0ustar ghudsonghudson-----BEGIN CERTIFICATE----- MIIEuTCCA6GgAwIBAgIBBjANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug b3RoZXJ3aXNlMB4XDTI0MDIxNTA0NTkwN1oXDTM1MDEyODA0NTkwN1owSjELMAkG A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAm/1JtzZBJsdadmOTnkl94508ZSyYo5xP83sLT/SY5Cri1QKaFrue2kGg gl1QEOExBrIbdAeu5BftqiC07HyGgugtRo0qDHMRnQ4tsNExzYz69MOkFE4hMYjU o+9C22GVLihyoq+oELN7ro30u5/MCO7rULIp0HekLKQ+uANVVJx+xnW3bMJsrRIX Zx9kB0jIIugYt5D3n80vdIjHQJf2BTjsBWYGRJD4sTElGFtRIiD6m4puonRdUgtH UHZ7OCKTY5sU0PSGxFRLi/ykqcgPPQddHYCd5MRJj5q2NvPN6UYDbMfzqni0uDQ9 qdDjHj6CmRCHNKvkKaLdBfhdqFKuZQIDAQABo4IBSjCCAUYwHQYDVR0OBBYEFJI/ +nOV5fnNVxn2GkjkYbZ5D6mqMIHUBgNVHSMEgcwwgcmAFJI/+nOV5fnNVxn2Gkjk YbZ5D6mqoYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P BAQDAgPoMAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFqAUBgorBgEEAYI3FAIDoAYM BHVzZXIwEgYDVR0lBAswCQYHKwYBBQIDBDANBgkqhkiG9w0BAQsFAAOCAQEAFN2R gVMM5HNoXuwBPcpNsP5AVSoQRTAv6UUxAjTPLGH5mE6LGW8/JxM0R5x0PdVyU3u7 zq4qa10XdGJpSt94cD6m7R61Sw6ru9PBtHmB0oUfkWRa2+SJpjmcwyc86W0XRBhr OhD0QGOnF1hGyTYzPViGxRZFVMiqXsWuAJ4i6uTyyPeeN+UuehQ3SsVEA1csrKMy dNT7FKQBvUTBnSZ9rxphGBrw/NZQyG74KxG5W3Nsnq89VK6+ESJcsUOT55WrHRwE CwKoeX+otyj8ptOwKaaje0DZnSXTXqEag4G4PgH4ovd+ehad0JaE4jtQTm+Vy15W cwHSMGSA+Kq1Hsqhhw== -----END CERTIFICATE----- krb5-1.22.1/src/tests/pkinit-certs/user-upn3.p120000664000175000017500000000554015051422640021077 0ustar ghudsonghudson0‚ \0‚  *†H†÷  ‚ ‚ ÿ0‚ û0‚o *†H†÷  ‚`0‚\0‚U *†H†÷ 0 *†H†÷  0í¶*C³fªü€‚(ܾEW!Ñ´¥Ý¹Xu—m; œˆ¨^à@´…x W Ø—4ÂÛm©¦M ‡JÁ½†HŒ“0û,Iè0ñ:×MüÜ?eÓ«øÐ(½ÀÒÆ\-º-ªÒôÙ¸÷ïx«R–S…jiŒäUtø³ï…;xO Eârú õÚÄX¢â+Tz}ilËî‘Y÷Þ3 ö#ppÁ#bYœ… É|QrÝSdQ,ü†ûû: Íó«m/ã·ªG¸/jâ¿ÖâÇÜÚfADm)sêØúênKEPÊKaãFº(|Ã7ÊòÛ£”V¥¦¹T’kI×fë«®ÕÊópB3ÀôbÍâ µÔîo·ï7Ùth¢G…ç\Æ5ZZcŒçUføñ–`+e¸Ä XÛÔš2éÉ™ÜXt$<â6\öQPõ’s¯-á麲Ò ‹AÐx‡ø-s%øUWs¨Ï'𦂭b»”*‘%äÃó0ÎR„ÇñÞvÛ$QI{u:™Y¨üýΟ°WCNÄ+ïžæJƒÖa ãkÓOGü‰öFðÔ.ôE,~-‡¸@ì“d ¬->îÏ™ÊĬÌU'3}ß^ûþ©Á*y¦3Ô–ßÜÂ…?¢Ïåö¯{ s0¤Ï@L°¾ÔË?m@w*¼xyÁ'V¬ß-Žàík—+tº_Ô¨Ud¦7ù˜$ƒ_žkè½Wkà `n릌ˆué;6¬  'ªYKÍܤÚÊWïuü:þOFÙ¶Êò‘'¼ÖþÙè§ ~ÈÚÓM¶ªµåü°ö$I™©Ù^Æ#á‚AWÔÏsuµ0½ô­Fò ÉîE¶ÅeðrIì£WEÉÙBfâf±·Ó¯ëJ± Ô}*™jŽ÷ +YøÐ9ðÚ‰âø0n,³C»yÉÝŸ!kb»-MBfb›Zt)­¹Ycu',n£E˜Ÿg8´Ÿ“8¦±2‰mÿV±ØhÙ´çt©=°4‰ äÇ•rÂCzê4zÇ:¢”ð&'áˬdÇØåÿ°øUµàdôBøˆt;UÕ(O 5 ¼_åýëÃû¹Çfñ‚E;(Ø%½)ÿ’£ÐˆlÑÿühÚùÆ_ŒÞu?k‡”ÝjˆƒLÂ(°Íuú±¨¶ÄQ定eRÒ{R*Ž%ÜWå/a­8î®üiqë½ ú5Îiï~«1³ÎiÌÑ–AoLÀÃ<ä"Úp®5Ühø\ÊPAPPTW‘ƒÞtžþPï®±*ÉŽq0RÄB¿²¸V±:™·„Øžûp¿¼vâíH!uÑ­­æ=çŸc©D#›Ÿ[“W<®%€Ç“Èú! KØm‹ÁŸžLŠrð®ÝwAy `a#`„Ÿ}ÀLï=hvÕTȶT„–“B…iþ¾ÐÆžÛŽ‰ÏDóØçT×U`¬A¾Œƒ–mk¾xü!lÝ¥ŽÚ·-µ¥wBѮ˶=sˆPrrác  dl…²7p¶<-+ÅîNƒ•°òEŒ{õ¥<û—ÐüÄ%ÕCo{gþ¿¶a„-ERêùfFS/`³Q~wWLe–JJ'ÓöbÔõà  v‹"ìª5ÛªhÐçiä³ß`ŸÞA“ùi¶wtoGêõŠÎJL} ¶tΑ µ—âÑöò=€’OS¿d/Åõ‚K¢¥ÎqÁ(¸U EˆX¶A}˜;ÒliÅ>¥äpn×}ù3%?o`<Àc!y¦œ1‹¬æp(@Œ"8i•Sö>Ö]ÎÉ{®ÁkÉ–+Hô<˜ýL6:XTŠ^wAÏ–ú&åšÉî™›Ÿ¡N;ÅeÀ{¨Lq­}H1zÝE2¥hY…Ç*Ž#Ûs3H{“Mƒ™Gèo2ÿkzB M¬w+ÍÐþeG¿>ú3«í(¦¦Å~éóÜ'LóÞ`‹Ö{´½ôü¿{2Mg‹Ψä]ÝCêvxšªA$˜&Á“ÿ)çnº²­´ûgŸëx%éñ>L…Žßß›¹À• ¹¨z\ÐNû™ºþS¢í $dJ—¼ se¿ëšDÆŠèïjW:Ã_ G!Ð^‡”µÏœbìÅë$!’2',à ¦ÆüBnˆÖÎ9\Â=ñVÀ,Ì—Ôøðð±qžj—C|+n*b{Ãä`äÞ`–(ÐV}ËŒân}·p"¦ëÌðùÁ7Ÿ Žë¥Kâêo©%<Óµ‚d^“b”S©mÀ&%Ùz[‘¶×ñŽÎŸ¹óØe r~ç%…Z)OÃéË!•lÒ©¼X>­6ãßD•lì‹õd¤"¥0Ö”ª$=„Ó2¶¤éFX˜ª¨v$/a«ô5bJvÀ½ÝeÔ˜c’ÅåÄ?>›ß·˜ä+]“(zÂ=¦tŽ(~ahÔ’‘ñYôÂä^¶¥zÎÞG,St•äô•’jéS}@1â}™‡’™3–ÍsæÑz0ÖâP³5jñVŠ~K “Û/Cjƒà>—êudÅPq˰¥-ÊU€œ8¿Ñ8yÚ"ÜÁ#/Â#DL!Œƒq‰îƒÖò&7êqÇwõÿÓb¹®(8ùý}yÏGAñßëŠáUˆÁ²‡Óº‘õìÕK!T©$º±ÆÞaóÌÎã·F-{B6éºöo¸d&ˆ¾ŽÍŒŸTc{ö‡VM’@oÈrÚ½ßf÷Áœ¡ÃÅ色 Îðñ‡ËÎj§ï0Þ¾OÎjë,VÀбéI¡³Q#þuŒï8Ïçsa© ìLòµ@ÀÑ›ZUI͆<¤££Œät׺ý¹ëÒY5ïiY~Ñ âÛMp?„}4# #include #include int main(int argc, char *argv[]) { int inlen, outlen, i; unsigned char *instr, *outstr; if (argc != 3) { fprintf(stderr, "%s: instr outlen\n", argv[0]); exit(1); } instr = (unsigned char *) argv[1]; inlen = strlen(instr)*8; outlen = atoi(argv[2]); if (outlen%8) { fprintf(stderr, "outlen must be a multiple of 8\n"); exit(1); } if ((outstr = (unsigned char *) malloc(outlen/8)) == NULL) { fprintf(stderr, "ENOMEM\n"); exit(1); } krb5int_nfold(inlen,instr,outlen,outstr); printf("%d-fold(",outlen); for (i=0; i<(inlen/8); i++) printf("%02x",instr[i]); printf(") = "); for (i=0; i<(outlen/8); i++) printf("%02x",outstr[i]); printf("\n"); exit(0); } krb5-1.22.1/src/tests/misc/Makefile.in0000664000175000017500000000440715051422640017277 0ustar ghudsonghudsonmydir=tests$(S)misc BUILDTOP=$(REL)..$(S).. OBJS=\ test_getpw.o \ test_chpw_message.o SRCS=\ $(srcdir)/test_getpw.c \ $(srcdir)/test_chpw_message.c \ $(srcdir)/test_getsockname.c \ $(srcdir)/test_cxx_krb5.cpp \ $(srcdir)/test_cxx_k5int.cpp \ $(srcdir)/test_cxx_gss.cpp \ $(srcdir)/test_cxx_rpc.cpp \ $(srcdir)/test_cxx_kadm5.cpp all: test_getpw test_chpw_message check: test_getpw test_chpw_message test_cxx_krb5 test_cxx_gss test_cxx_rpc test_cxx_k5int test_cxx_kadm5 $(RUN_TEST) ./test_getpw $(RUN_TEST) ./test_chpw_message $(RUN_TEST) ./test_cxx_krb5 $(RUN_TEST) ./test_cxx_k5int $(RUN_TEST) ./test_cxx_gss $(RUN_TEST) ./test_cxx_rpc $(RUN_TEST) ./test_cxx_kadm5 test_getpw: $(OUTPRE)test_getpw.$(OBJEXT) $(SUPPORT_DEPLIB) $(CC_LINK) $(ALL_CFLAGS) -o test_getpw $(OUTPRE)test_getpw.$(OBJEXT) $(SUPPORT_LIB) test_chpw_message: $(OUTPRE)test_chpw_message.$(OBJEXT) $(SUPPORT_DEPLIB) $(CC_LINK) $(ALL_CFLAGS) -o test_chpw_message $(OUTPRE)test_chpw_message.$(OBJEXT) $(KRB5_BASE_LIBS) $(LIBS) test_getsockname: $(OUTPRE)test_getsockname.$(OBJEXT) $(CC_LINK) $(ALL_CFLAGS) -o test_getsockname $(OUTPRE)test_getsockname.$(OBJEXT) $(LIBS) test_cxx_krb5: $(OUTPRE)test_cxx_krb5.$(OBJEXT) $(KRB5_DEPLIB) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_krb5 $(OUTPRE)test_cxx_krb5.$(OBJEXT) $(KRB5_BASE_LIBS) $(LIBS) test_cxx_k5int: $(OUTPRE)test_cxx_k5int.$(OBJEXT) $(KRB5_DEPLIB) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_k5int $(OUTPRE)test_cxx_k5int.$(OBJEXT) $(KRB5_BASE_LIBS) $(LIBS) test_cxx_gss: $(OUTPRE)test_cxx_gss.$(OBJEXT) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_gss $(OUTPRE)test_cxx_gss.$(OBJEXT) $(LIBS) test_cxx_rpc: $(OUTPRE)test_cxx_rpc.$(OBJEXT) $(GSSRPC_DEPLIBS) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_rpc $(OUTPRE)test_cxx_rpc.$(OBJEXT) $(GSSRPC_LIBS) $(KRB5_BASE_LIBS) $(LIBS) test_cxx_kadm5: $(OUTPRE)test_cxx_kadm5.$(OBJEXT) $(KADMCLNT_DEPLIBS) $(CXX_LINK) $(ALL_CXXFLAGS) -o test_cxx_kadm5 $(OUTPRE)test_cxx_kadm5.$(OBJEXT) $(KADMCLNT_LIBS) $(KRB5_BASE_LIBS) $(LIBS) test_cxx_krb5.$(OBJEXT): test_cxx_krb5.cpp test_cxx_gss.$(OBJEXT): test_cxx_gss.cpp test_cxx_rpc.$(OBJEXT): test_cxx_rpc.cpp test_cxx_kadm5.$(OBJEXT): test_cxx_kadm5.cpp install: clean: $(RM) test_getpw test_chpw_message test_cxx_krb5 test_cxx_gss test_cxx_k5int test_cxx_rpc test_cxx_kadm5 *.o krb5-1.22.1/src/tests/misc/test_cxx_gss.cpp0000664000175000017500000000026615051422640020452 0ustar ghudsonghudson// Test that the gssapi.h header is compatible with C++ application code. #include #include "gssapi/gssapi.h" int main () { printf("hello, world\n"); return 0; } krb5-1.22.1/src/tests/misc/deps0000664000175000017500000000542415051422640016110 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)test_getpw.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ test_getpw.c $(OUTPRE)test_chpw_message.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ test_chpw_message.c $(OUTPRE)test_getsockname.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ test_getsockname.c $(OUTPRE)test_cxx_krb5.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/locate_plugin.h test_cxx_krb5.cpp $(OUTPRE)test_cxx_k5int.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-ipc_stream.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h test_cxx_k5int.cpp $(OUTPRE)test_cxx_gss.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ test_cxx_gss.cpp $(OUTPRE)test_cxx_rpc.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h test_cxx_rpc.cpp $(OUTPRE)test_cxx_kadm5.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/kadm5/admin.h \ $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h test_cxx_kadm5.cpp krb5-1.22.1/src/tests/misc/test_cxx_kadm5.cpp0000664000175000017500000000052415051422640020654 0ustar ghudsonghudson// Test that the kadm5 header is compatible with C++ application code. #include "kadm5/admin.h" krb5_context ctx; kadm5_config_params p_in, p_out; int main (int argc, char *argv[]) { if (argc == 47 && kadm5_get_config_params(ctx, 1, &p_in, &p_out)) { printf("error\n"); return 1; } printf("hello, world\n"); return 0; } krb5-1.22.1/src/tests/misc/test_cxx_rpc.cpp0000664000175000017500000000044015051422640020434 0ustar ghudsonghudson// Test that the rpc.h header is compatible with C++ application code. #include "gssrpc/rpc.h" struct sockaddr_in s_in; int main (int argc, char *argv[]) { if (argc == 47 && get_myaddress (&s_in)) { printf("error\n"); return 1; } printf("hello, world\n"); return 0; } krb5-1.22.1/src/tests/misc/test_getpw.c0000664000175000017500000000346115051422640017562 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/misc/test_getpw.c */ /* * Copyright (C) 2005 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #include "k5-platform.h" #include #include #include #include #include int main(void) { uid_t my_uid; struct passwd *pwd, pwx; char pwbuf[BUFSIZ]; int x; my_uid = getuid(); printf("my uid: %ld\n", (long) my_uid); x = k5_getpwuid_r(my_uid, &pwx, pwbuf, sizeof(pwbuf), &pwd); printf("k5_getpwuid_r returns %d\n", x); if (x != 0) exit(1); printf(" username is '%s'\n", pwd->pw_name); exit(0); } krb5-1.22.1/src/tests/misc/test_chpw_message.c0000664000175000017500000001322015051422640021073 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/misc/test_getpw.c */ /* * Copyright (C) 2012 by the Red Hat Inc. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #include "krb5.h" #include #include #include #include #include #include static krb5_data result_utf8 = { 0, 23, "This is a valid string.", }; static krb5_data result_invalid_utf8 = { 0, 19, "\0This is not valid.", }; static krb5_data result_ad_complex = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\0" /* min length */ "\0\0\0\0" /* history */ "\0\0\0\1" /* properties, complex */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\0\0\0\0\0\0" /* min age */ }; static krb5_data result_ad_length = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\x0d" /* min length, 13 characters */ "\0\0\0\0" /* history */ "\0\0\0\0" /* properties */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\0\0\0\0\0\0" /* min age */ }; static krb5_data result_ad_history = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\0" /* min length */ "\0\0\0\x09" /* history, 9 passwords */ "\0\0\0\0" /* properties */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\0\0\0\0\0\0" /* min age */ }; static krb5_data result_ad_age = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\0" /* min length */ "\0\0\0\0" /* history, 9 passwords */ "\0\0\0\0" /* properties */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\x01\x92\x54\xd3\x80\0" /* min age, 2 days */ }; static krb5_data result_ad_all = { 0, 30, "\0\0" /* zero bytes */ "\0\0\0\x05" /* min length, 5 characters */ "\0\0\0\x0D" /* history, 13 passwords */ "\0\0\0\x01" /* properties, complex */ "\0\0\0\0\0\0\0\0" /* expire */ "\0\0\0\xc9\x2a\x69\xc0\0" /* min age, 1 day */ }; static void check(krb5_error_code code) { if (code != 0) { com_err("t_vfy_increds", code, ""); abort(); } } static void check_msg(const char *real, const char *expected) { if (strstr(real, expected) == NULL) { fprintf(stderr, "Expected to see: %s\n", expected); abort(); } } int main(void) { krb5_context context; char *msg; setlocale(LC_ALL, "C"); check(krb5_init_context(&context)); /* Valid utf-8 data in the result should be returned as is */ check(krb5_chpw_message(context, &result_utf8, &msg)); printf(" UTF8 valid: %s\n", msg); check_msg(msg, "This is a valid string."); free(msg); /* Invalid data should have a generic message. */ check(krb5_chpw_message(context, &result_invalid_utf8, &msg)); printf(" UTF8 invalid: %s\n", msg); check_msg(msg, "contact your administrator"); free(msg); /* AD data with complex data requirement */ check(krb5_chpw_message(context, &result_ad_complex, &msg)); printf(" AD complex: %s\n", msg); check_msg(msg, "The password must include numbers or symbols."); check_msg(msg, "Don't include any part of your name in the password."); free(msg); /* AD data with min password length */ check(krb5_chpw_message(context, &result_ad_length, &msg)); printf(" AD length: %s\n", msg); check_msg(msg, "The password must contain at least 13 characters."); free(msg); /* AD data with history requirements */ check(krb5_chpw_message(context, &result_ad_history, &msg)); printf(" AD history: %s\n", msg); check_msg(msg, "The password must be different from the previous 9 " "passwords."); free(msg); /* AD data with minimum age */ check(krb5_chpw_message(context, &result_ad_age, &msg)); printf(" AD min age: %s\n", msg); check_msg(msg, "The password can only be changed every 2 days."); free(msg); /* AD data with all */ check(krb5_chpw_message(context, &result_ad_all, &msg)); printf(" AD all: %s\n", msg); check_msg(msg, "The password can only be changed once a day."); check_msg(msg, "The password must be different from the previous 13 " "passwords."); check_msg(msg, "The password must contain at least 5 characters."); check_msg(msg, "The password must include numbers or symbols."); check_msg(msg, "Don't include any part of your name in the password."); free(msg); krb5_free_context(context); exit(0); } krb5-1.22.1/src/tests/misc/test_cxx_krb5.cpp0000664000175000017500000000062415051422640020517 0ustar ghudsonghudson// Test that the krb5.h header is compatible with C++ application code. #include #include "krb5.h" #include "krb5/locate_plugin.h" #include "profile.h" int main (int argc, char *argv[]) { krb5_context ctx; if (krb5_init_context(&ctx) != 0) { printf("krb5_init_context returned an error\n"); return 1; } printf("hello, world\n"); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/misc/test_cxx_k5int.cpp0000664000175000017500000000071515051422640020707 0ustar ghudsonghudson// Test that the krb5 internal headers are compatible with C++ code. // (Some Windows-specific code is in C++ in this source tree.) #include #include "k5-int.h" #include "k5-ipc_stream.h" #include "k5-utf8.h" int main (int argc, char *argv[]) { krb5_context ctx; if (krb5_init_context(&ctx) != 0) { printf("krb5_init_context returned an error\n"); return 1; } printf("hello, world\n"); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/misc/test_getsockname.c0000664000175000017500000000717315051422640020740 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/misc/test_getsockname.c */ /* * Copyright (C) 1995 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * test_getsockname.c * * This routine demonstrates a bug in the socket emulation library of * Solaris and other monstrosities that uses STREAMS. On other * machines with a real networking layer, it prints the local * interface address that is used to send a message to a specific * host. On Solaris, it prints out 0.0.0.0. */ #include "autoconf.h" #include #include #include #include #include #include #include #include #include int main(argc, argv) int argc; char *argv[]; { int sock; GETSOCKNAME_ARG3_TYPE i; struct hostent *host; struct sockaddr_in s_sock; /* server address */ struct sockaddr_in c_sock; /* client address */ char *hostname; if (argc == 2) { hostname = argv[1]; } else { fprintf(stderr, "Usage: %s hostname\n", argv[0]); exit(1); } /* Look up server host */ if ((host = gethostbyname(hostname)) == (struct hostent *) 0) { fprintf(stderr, "%s: unknown host\n", hostname); exit(1); } /* Set server's address */ (void) memset(&s_sock, 0, sizeof(s_sock)); memcpy(&s_sock.sin_addr, host->h_addr, sizeof(s_sock.sin_addr)); #ifdef DEBUG printf("s_sock.sin_addr is %s\n", inet_ntoa(s_sock.sin_addr)); #endif s_sock.sin_family = AF_INET; s_sock.sin_port = htons(5555); /* Open a socket */ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } memset(&c_sock, 0, sizeof(c_sock)); c_sock.sin_family = AF_INET; /* Bind it to set the address; kernel will fill in port # */ if (bind(sock, (struct sockaddr *)&c_sock, sizeof(c_sock)) < 0) { perror("bind"); exit(1); } /* "connect" the datagram socket; this is necessary to get a local address properly bound for getsockname() below. */ if (connect(sock, (struct sockaddr *)&s_sock, sizeof(s_sock)) == -1) { perror("connect"); exit(1); } /* Get my address */ memset(&c_sock, 0, sizeof(c_sock)); i = sizeof(c_sock); if (getsockname(sock, (struct sockaddr *)&c_sock, &i) < 0) { perror("getsockname"); exit(1); } printf("My interface address is: %s\n", inet_ntoa(c_sock.sin_addr)); exit(0); } krb5-1.22.1/src/tests/t_renprinc.py0000775000175000017500000000372515051422640017021 0ustar ghudsonghudson# Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * enctype = "aes128-cts" realm = K5Realm(create_host=False, create_user=False) salttypes = ('normal', 'norealm', 'onlyrealm') # For a variety of salt types, test that we can rename a principal and # still get tickets with the same password. for st in salttypes: realm.run([kadminl, 'addprinc', '-e', enctype + ':' + st, '-pw', password(st), st]) realm.kinit(st, password(st)) newprinc = 'new' + st realm.run([kadminl, 'renprinc', st, newprinc]) realm.kinit(newprinc, password(st)) # Rename the normal salt again to test renaming a principal with # special salt type (which it will have after the first rename). realm.run([kadminl, 'renprinc', 'newnormal', 'newnormal2']) realm.kinit('newnormal2', password('normal')) success('Principal renaming tests') krb5-1.22.1/src/tests/t_u2u.py0000664000175000017500000000446515051422640015713 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(create_host=False) # Create a second user principal and get tickets for it. u2u_ccache = 'FILE:' + os.path.join(realm.testdir, 'ccu2u') realm.addprinc('alice', password('alice')) realm.kinit('alice', password('alice'), ['-c', u2u_ccache]) # Verify that -allow_dup_skey denies u2u requests. realm.run([kadminl, 'modprinc', '-allow_dup_skey', 'alice']) realm.run([kvno, '--u2u', u2u_ccache, 'alice'], expected_code=1, expected_msg='KDC policy rejects request') realm.run([kadminl, 'modprinc', '+allow_dup_skey', 'alice']) # Verify that -allow_svr denies regular TGS requests, but allows # user-to-user TGS requests. realm.run([kadminl, 'modprinc', '-allow_svr', 'alice']) realm.run([kvno, 'alice'], expected_code=1, expected_msg='Server principal valid for user2user only') realm.run([kvno, '--u2u', u2u_ccache, 'alice'], expected_msg='kvno = 0') realm.run([kadminl, 'modprinc', '+allow_svr', 'alice']) # Verify that normal lookups ignore the user-to-user ticket. realm.run([kvno, 'alice'], expected_msg='kvno = 1') out = realm.run([klist]) if out.count('alice@KRBTEST.COM') != 2: fail('expected two alice tickets after regular kvno') # Try u2u against the client user. realm.run([kvno, '--u2u', realm.ccache, realm.user_princ]) realm.run([klist]) realm.stop() # Load the test KDB module to test aliases testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'WIN10': {'keys': 'aes128-cts'}} kdcconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': testprincs, 'alias': {'HOST/win10': 'WIN10'}}}} realm = K5Realm(kdc_conf=kdcconf, create_kdb=False) realm.start_kdc() # Create a second user principal and get tickets for it. u2u_ccache = 'FILE:' + os.path.join(realm.testdir, 'ccu2u') realm.extract_keytab('WIN10', realm.keytab) realm.kinit('WIN10', None, ['-k', '-c', u2u_ccache]) realm.extract_keytab(realm.user_princ, realm.keytab) realm.kinit(realm.user_princ, None, ['-k']) realm.run([kvno, '--u2u', u2u_ccache, 'HOST/win10'], expected_msg='kvno = 0') realm.run([kvno, '--u2u', u2u_ccache, 'WIN10'], expected_msg='kvno = 0') success('user-to-user tests') krb5-1.22.1/src/tests/t_bogus_kdc_req.py0000775000175000017500000000151615051422640020004 0ustar ghudsonghudsonimport base64 import socket from k5test import * realm = K5Realm() # Send encodings that are invalid KDC-REQs, but pass krb5_is_as_req() # and krb5_is_tgs_req(), to make sure that the KDC recovers correctly # from failures in decode_krb5_as_req() and decode_krb5_tgs_req(). s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) a = (hostname, realm.portbase) # Bogus AS-REQ x1 = base64.b16decode('6AFF') s.sendto(x1, a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) # Bogus TGS-REQ x2 = base64.b16decode('6CFF') s.sendto(x2, a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) # Not a KDC-REQ, even a little bit x3 = base64.b16decode('FFFF') s.sendto(x3, a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) success('Bogus KDC-REQ test') krb5-1.22.1/src/tests/localauth.c0000664000175000017500000000461615051422640016421 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/localauth.c - test harness for kuserok and aname_to_lname */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { krb5_principal princ; char buf[1024]; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: localauth principal [localuser]\n"); return 1; } check(krb5_init_context(&ctx)); check(krb5_parse_name(ctx, argv[1], &princ)); if (argc == 3) { printf("%s\n", krb5_kuserok(ctx, princ, argv[2]) ? "yes" : "no"); } else { check(krb5_aname_to_localname(ctx, princ, sizeof(buf), buf)); printf("%s\n", buf); } krb5_free_principal(ctx, princ); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/t_kadmin_parsing.py0000664000175000017500000000731615051422640020164 0ustar ghudsonghudsonfrom k5test import * # This file contains tests for kadmin command parsing. Principal # flags (which can also be used in kadm5.acl or krb5.conf) are tested # in t_princflags.py. # kadmin recognizes time intervals using either the # krb5_string_to_deltat() formats or the relative getdate.y formats. # (Absolute getdate.y formats also work with the current time # subtracted; this isn't very useful and we won't test it here.) intervals = ( # krb5_string_to_deltat() formats. Whitespace ( \t\n) is allowed # before or between most elements or at the end, but not after # 's'. Negative or oversized numbers are allowed in most places, # but not after the first number in an HH:MM:SS form. ('28s', '0 days 00:00:28'), ('7m ', '0 days 00:07:00'), ('6m 9s', '0 days 00:06:09'), ('2h', '0 days 02:00:00'), ('2h-5s', '0 days 01:59:55'), ('2h3m', '0 days 02:03:00'), ('2h3m5s', '0 days 02:03:05'), ('5d ', '5 days 00:00:00'), ('5d-48s', '4 days 23:59:12'), ('5d18m', '5 days 00:18:00'), ('5d -6m56s', '4 days 23:54:56'), ('5d4h', '5 days 04:00:00'), ('5d4h 1s', '5 days 04:00:01'), ('5d4h3m', '5 days 04:03:00'), (' \t 15d \n 4h 3m 2s', '15 days 04:03:02'), ('10-8:45:0', '10 days 08:45:00'), ('1000:67:99', '41 days 17:08:39'), ('999:11', '41 days 15:11:00'), ('382512', '4 days 10:15:12'), # getdate.y relative formats (and "never", which is handled # specially as a zero interval). Any number of relative forms can # be specified in any order. Whitespace is ignored before or # after any token. "month" and "year" are allowed as units but # depend on the current time, so we won't test them. Plural unit # names are treated identically to singular unit names. Numbers # before unit names are optional and may be signed; there are also # aliases for some numbers. "ago" inverts the interval up to the # point where it appears. ('never', '0 days 00:00:00'), ('fortnight', '14 days 00:00:00'), ('3 day ago 4 weeks 8 hours', '25 days 08:00:00'), ('8 second -3 secs 5 minute ago 63 min', '0 days 00:57:55'), ('min mins min mins min', '0 days 00:05:00'), ('tomorrow tomorrow today yesterday now last minute', '0 days 23:59:00'), ('this second next minute first hour third fortnight fourth day ' 'fifth weeks sixth sec seventh secs eighth second ninth mins tenth ' 'day eleventh min twelfth sec', '91 days 01:22:34')) realm = K5Realm(create_host=False, get_creds=False) realm.run([kadminl, 'addpol', 'pol']) for instr, outstr in intervals: realm.run([kadminl, 'modprinc', '-maxlife', instr, realm.user_princ]) msg = 'Maximum ticket life: ' + outstr + '\n' realm.run([kadminl, 'getprinc', realm.user_princ], expected_msg=msg) realm.run([kadminl, 'modprinc', '-maxrenewlife', instr, realm.user_princ]) msg = 'Maximum renewable life: ' + outstr + '\n' realm.run([kadminl, 'getprinc', realm.user_princ], expected_msg=msg) realm.run([kadminl, 'modpol', '-maxlife', instr, 'pol']) msg = 'Maximum password life: ' + outstr + '\n' realm.run([kadminl, 'getpol', 'pol'], expected_msg=msg) realm.run([kadminl, 'modpol', '-minlife', instr, 'pol']) msg = 'Minimum password life: ' + outstr + '\n' realm.run([kadminl, 'getpol', 'pol'], expected_msg=msg) realm.run([kadminl, 'modpol', '-failurecountinterval', instr, 'pol']) msg = 'Password failure count reset interval: ' + outstr + '\n' realm.run([kadminl, 'getpol', 'pol'], expected_msg=msg) realm.run([kadminl, 'modpol', '-lockoutduration', instr, 'pol']) msg = 'Password lockout duration: ' + outstr + '\n' realm.run([kadminl, 'getpol', 'pol'], expected_msg=msg) success('kadmin command parsing tests') krb5-1.22.1/src/tests/deps0000664000175000017500000003020315051422640015146 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)adata.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h adata.c $(OUTPRE)conccache.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ conccache.c $(OUTPRE)etinfo.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h etinfo.c $(OUTPRE)forward.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h forward.c $(OUTPRE)gcred.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h gcred.c $(OUTPRE)hist.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hist.c $(OUTPRE)hooks.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h hooks.c $(OUTPRE)hrealm.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h hrealm.c $(OUTPRE)icinterleave.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h icinterleave.c $(OUTPRE)icred.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ icred.c $(OUTPRE)kdbtest.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/kadm5/admin.h \ $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h kdbtest.c $(OUTPRE)localauth.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h localauth.c $(OUTPRE)plugorder.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/krb5/pwqual_plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h plugorder.c $(OUTPRE)rdreq.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h rdreq.c $(OUTPRE)replay.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h replay.c $(OUTPRE)responder.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-json.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/krb5.h responder.c $(OUTPRE)s2p.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h s2p.c $(OUTPRE)s4u2self.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h s4u2self.c $(OUTPRE)s4u2proxy.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h s4u2proxy.c $(OUTPRE)t_inetd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(COM_ERR_DEPS) t_inetd.c $(OUTPRE)unlockiter.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/kadm5/admin.h \ $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h unlockiter.c krb5-1.22.1/src/tests/t_pkinit.py0000775000175000017500000005063615051422640016502 0ustar ghudsonghudsonfrom k5test import * import re # Skip this test if pkinit wasn't built. if not pkinit_enabled: skip_rest('PKINIT tests', 'PKINIT module not built') # Construct a krb5.conf fragment configuring pkinit. user_pem = os.path.join(pkinit_certs, 'user.pem') ecuser_pem = os.path.join(pkinit_certs, 'ecuser.pem') privkey_pem = os.path.join(pkinit_certs, 'privkey.pem') privkey_enc_pem = os.path.join(pkinit_certs, 'privkey-enc.pem') privkey_ec_pem = os.path.join(pkinit_certs, 'eckey.pem') user_p12 = os.path.join(pkinit_certs, 'user.p12') user_enc_p12 = os.path.join(pkinit_certs, 'user-enc.p12') user_upn_p12 = os.path.join(pkinit_certs, 'user-upn.p12') user_upn2_p12 = os.path.join(pkinit_certs, 'user-upn2.p12') user_upn3_p12 = os.path.join(pkinit_certs, 'user-upn3.p12') generic_p12 = os.path.join(pkinit_certs, 'generic.p12') path = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs') path_enc = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs-enc') pkinit_kdc_conf = {'realms': {'$realm': { 'default_principal_flags': '+preauth', 'pkinit_eku_checking': 'none', 'pkinit_indicator': ['indpkinit1', 'indpkinit2']}}} restrictive_kdc_conf = {'realms': {'$realm': { 'restrict_anonymous_to_tgt': 'true' }}} freshness_kdc_conf = {'realms': {'$realm': { 'pkinit_require_freshness': 'true'}}} testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'user2': {'keys': 'aes128-cts', 'flags': '+preauth'}} alias_kdc_conf = {'realms': {'$realm': { 'default_principal_flags': '+preauth', 'pkinit_eku_checking': 'none', 'pkinit_allow_upn': 'true', 'database_module': 'test'}}, 'dbmodules': {'test': { 'db_library': 'test', 'alias': {'user@krbtest.com': 'user'}, 'princs': testprincs}}} file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem) file_enc_identity = 'FILE:%s,%s' % (user_pem, privkey_enc_pem) ec_identity = 'FILE:%s,%s' % (ecuser_pem, privkey_ec_pem) dir_identity = 'DIR:%s' % path dir_enc_identity = 'DIR:%s' % path_enc dir_file_identity = 'FILE:%s,%s' % (os.path.join(path, 'user.crt'), os.path.join(path, 'user.key')) dir_file_enc_identity = 'FILE:%s,%s' % (os.path.join(path_enc, 'user.crt'), os.path.join(path_enc, 'user.key')) p12_identity = 'PKCS12:%s' % user_p12 p12_upn_identity = 'PKCS12:%s' % user_upn_p12 p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12 p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12 p12_generic_identity = 'PKCS12:%s' % generic_p12 p12_enc_identity = 'PKCS12:%s' % user_enc_p12 # Start a realm with the test kdb module for the following UPN SAN tests. realm = K5Realm(kdc_conf=alias_kdc_conf, create_kdb=False, pkinit=True) realm.start_kdc() mark('UPN SANs') # Compatibility check: cert contains UPN "user", which matches the # request principal user@KRBTEST.COM if parsed as a normal principal. realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_upn2_identity]) # Compatibility check: cert contains UPN "user@KRBTEST.COM", which matches # the request principal user@KRBTEST.COM if parsed as a normal principal. realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_upn3_identity]) # Cert contains UPN "user@krbtest.com" which is aliased to the request # principal. realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_upn_identity]) # Test an id-pkinit-san match to a post-canonical principal. realm.kinit('user@krbtest.com', flags=['-E', '-X', 'X509_user_identity=%s' % p12_identity]) # Test a UPN match to a post-canonical principal. (This only works # for the cert with the UPN containing just "user", as we don't allow # UPN reparsing when comparing to the canonicalized client principal.) realm.kinit('user@krbtest.com', flags=['-E', '-X', 'X509_user_identity=%s' % p12_upn2_identity]) # Test a mismatch. msg = 'kinit: Client name mismatch while getting initial credentials' realm.run([kinit, '-X', 'X509_user_identity=%s' % p12_upn2_identity, 'user2'], expected_code=1, expected_msg=msg) realm.stop() realm = K5Realm(kdc_conf=pkinit_kdc_conf, get_creds=False, pkinit=True) # Sanity check - password-based preauth should still work. mark('password preauth sanity check') realm.run(['./responder', '-r', 'password=%s' % password('user'), realm.user_princ]) realm.kinit(realm.user_princ, password=password('user')) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # Having tested password preauth, remove the keys for better error # reporting. realm.run([kadminl, 'purgekeys', '-all', realm.user_princ]) # Test anonymous PKINIT. mark('anonymous') realm.kinit('@%s' % realm.realm, flags=['-n'], expected_code=1, expected_msg='not found in Kerberos database') realm.addprinc('WELLKNOWN/ANONYMOUS') realm.kinit('@%s' % realm.realm, flags=['-n']) realm.klist('WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS') realm.run([kvno, realm.host_princ]) out = realm.run(['./adata', realm.host_princ]) if '97:' in out: fail('auth indicators seen in anonymous PKINIT ticket') # Verify start_realm setting and test referrals TGS request. realm.run([klist, '-C'], expected_msg='start_realm = KRBTEST.COM') realm.run([kvno, '-S', 'host', hostname]) # Test anonymous kadmin. mark('anonymous kadmin') f = open(os.path.join(realm.testdir, 'acl'), 'a') f.write('WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS a *') f.close() realm.start_kadmind() realm.run([kadmin, '-n', 'addprinc', '-pw', 'test', 'testadd']) realm.run([kadmin, '-n', 'getprinc', 'testadd'], expected_code=1, expected_msg="Operation requires ``get'' privilege") realm.stop_kadmind() # Test with anonymous restricted; FAST should work but kvno should fail. mark('anonymous restricted') r_env = realm.special_env('restrict', True, kdc_conf=restrictive_kdc_conf) realm.stop_kdc() realm.start_kdc(env=r_env) realm.kinit('@%s' % realm.realm, flags=['-n']) realm.kinit('@%s' % realm.realm, flags=['-n', '-T', realm.ccache]) realm.run([kvno, realm.host_princ], expected_code=1, expected_msg='KDC policy rejects request') # Regression test for #8458: S4U2Self requests crash the KDC if # anonymous is restricted. mark('#8458 regression test') realm.kinit(realm.host_princ, flags=['-k']) realm.run([kvno, '-U', 'user', realm.host_princ]) # Go back to the normal KDC environment. realm.stop_kdc() realm.start_kdc() # Run the basic test - PKINIT with FILE: identity, with no password on the key. mark('FILE identity, no password') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'PKINIT client received freshness token from KDC', 'PKINIT loading CA certs and CRLs from FILE', 'PKINIT client making DH request', ' preauth for next request: PA-FX-COOKIE (133), PA-PK-AS-REQ (16)', 'PKINIT client verified DH reply', 'PKINIT client found id-pkinit-san in KDC cert', 'PKINIT client matched KDC principal krbtgt/') realm.pkinit(realm.user_princ, expected_trace=msgs) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # Test each Diffie-Hellman group except 1024-bit (which doesn't work # in OpenSSL 3.0) and the default 2048-bit group. for g in ('4096', 'P-256', 'P-384', 'P-521'): mark('Diffie-Hellman group ' + g) group_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': g}}} group_env = realm.special_env(g, True, krb5_conf=group_conf) realm.pkinit(realm.user_princ, expected_trace=('PKINIT using ' + g,), env=group_env) # Test with an EC client cert. mark('EC client cert') realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % ec_identity]) # Try using multiple configured pkinit_identities, to make sure we # fall back to the second one when the first one cannot be read. id_conf = {'realms': {'$realm': {'pkinit_identities': [file_identity + 'X', file_identity]}}} id_env = realm.special_env('idconf', False, krb5_conf=id_conf) realm.kinit(realm.user_princ, expected_trace=msgs, env=id_env) # Test a DH parameter renegotiation by temporarily setting a 4096-bit # minimum on the KDC. (Preauth type 16 is PKINIT PA_PK_AS_REQ; # 109 is PKINIT TD_DH_PARAMETERS; 133 is FAST PA-FX-COOKIE.) mark('DH parameter renegotiation') minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}} minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf) realm.stop_kdc() realm.start_kdc(env=minbits_env) msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'PKINIT using 2048-bit DH key exchange group', 'Preauth module pkinit (16) (real) returned: 0/Success', ' preauth for next request: PA-FX-COOKIE (133), PA-PK-AS-REQ (16)', '/Key parameters not accepted', 'Preauth tryagain input types (16): 109, PA-FX-COOKIE (133)', 'PKINIT accepting KDC key exchange group preference P-384', 'trying again with KDC-provided parameters', 'PKINIT using P-384 key exchange group', 'Preauth module pkinit (16) tryagain returned: 0/Success', ' preauth for next request: PA-PK-AS-REQ (16), PA-FX-COOKIE (133)') realm.pkinit(realm.user_princ, expected_trace=msgs) # Test enforcement of required freshness tokens. (We can leave # freshness tokens required after this test.) mark('freshness token enforcement') realm.pkinit(realm.user_princ, flags=['-X', 'disable_freshness=yes']) f_env = realm.special_env('freshness', True, kdc_conf=freshness_kdc_conf) realm.stop_kdc() realm.start_kdc(env=f_env) realm.pkinit(realm.user_princ) realm.pkinit(realm.user_princ, flags=['-X', 'disable_freshness=yes'], expected_code=1, expected_msg='Preauthentication failed') # Anonymous should never require a freshness token. realm.kinit('@%s' % realm.realm, flags=['-n', '-X', 'disable_freshness=yes']) # Run the basic test - PKINIT with FILE: identity, with a password on the key, # supplied by the prompter. # Expect failure if the responder does nothing, and we have no prompter. mark('FILE identity, password on key (prompter)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity, '-X', 'X509_user_identity=%s' % file_enc_identity, realm.user_princ], expected_code=2) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % file_enc_identity], password='encrypted') realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indpkinit1, indpkinit2]') # Run the basic test - PKINIT with FILE: identity, with a password on the key, # supplied by the responder. # Supply the response in raw form. mark('FILE identity, password on key (responder)') out = realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % file_enc_identity, '-r', 'pkinit={"%s": "encrypted"}' % file_enc_identity, '-X', 'X509_user_identity=%s' % file_enc_identity, realm.user_princ]) # Regression test for #8885 (password question asked twice). if out.count('OK: ') != 1: fail('Wrong number of responder calls') # Supply the response through the convenience API. realm.run(['./responder', '-X', 'X509_user_identity=%s' % file_enc_identity, '-p', '%s=%s' % (file_enc_identity, 'encrypted'), realm.user_princ]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with DIR: identity, with no password on the key. mark('DIR identity, no password') os.mkdir(path) os.mkdir(path_enc) shutil.copy(privkey_pem, os.path.join(path, 'user.key')) shutil.copy(privkey_enc_pem, os.path.join(path_enc, 'user.key')) shutil.copy(user_pem, os.path.join(path, 'user.crt')) shutil.copy(user_pem, os.path.join(path_enc, 'user.crt')) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % dir_identity]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with DIR: identity, with a password on the key, supplied by the # prompter. # Expect failure if the responder does nothing, and we have no prompter. mark('DIR identity, password on key (prompter)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % dir_file_enc_identity, '-X', 'X509_user_identity=%s' % dir_enc_identity, realm.user_princ], expected_code=2) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % dir_enc_identity], password='encrypted') realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with DIR: identity, with a password on the key, supplied by the # responder. # Supply the response in raw form. mark('DIR identity, password on key (responder)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % dir_file_enc_identity, '-r', 'pkinit={"%s": "encrypted"}' % dir_file_enc_identity, '-X', 'X509_user_identity=%s' % dir_enc_identity, realm.user_princ]) # Supply the response through the convenience API. realm.run(['./responder', '-X', 'X509_user_identity=%s' % dir_enc_identity, '-p', '%s=%s' % (dir_file_enc_identity, 'encrypted'), realm.user_princ]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with PKCS12: identity, with no password on the bundle. mark('PKCS12 identity, no password') realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with PKCS12: identity, with a password on the bundle, supplied by the # prompter. # Expect failure if the responder does nothing, and we have no prompter. mark('PKCS12 identity, password on bundle (prompter)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p12_enc_identity, '-X', 'X509_user_identity=%s' % p12_enc_identity, realm.user_princ], expected_code=2) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_enc_identity], password='encrypted') realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) # PKINIT with PKCS12: identity, with a password on the bundle, supplied by the # responder. # Supply the response in raw form. mark('PKCS12 identity, password on bundle (responder)') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p12_enc_identity, '-r', 'pkinit={"%s": "encrypted"}' % p12_enc_identity, '-X', 'X509_user_identity=%s' % p12_enc_identity, realm.user_princ]) # Supply the response through the convenience API. realm.run(['./responder', '-X', 'X509_user_identity=%s' % p12_enc_identity, '-p', '%s=%s' % (p12_enc_identity, 'encrypted'), realm.user_princ]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) mark('pkinit_cert_match rules') # Match a single rule. rule = '^user@KRBTEST.COM$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity]) realm.klist(realm.user_princ) # Regression test for #8670: match a UPN SAN with a single rule. rule = '^user@krbtest.com$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_upn_identity]) realm.klist(realm.user_princ) # Match a combined rule (default prefix is &&). rule = 'CN=user$digitalSignature,keyEncipherment' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity]) realm.klist(realm.user_princ) # Fail an && rule. rule = '&&O=OTHER.COM^user@KRBTEST.COM$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) msg = 'kinit: Certificate mismatch while getting initial credentials' realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity], expected_code=1, expected_msg=msg) # Pass an || rule. rule = '||O=KRBTEST.COM^otheruser@KRBTEST.COM$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity]) realm.klist(realm.user_princ) # Fail an || rule. rule = '||O=OTHER.COM^otheruser@KRBTEST.COM$' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) msg = 'kinit: Certificate mismatch while getting initial credentials' realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_identity], expected_code=1, expected_msg=msg) # Authorize a client cert with no PKINIT extensions using subject and # issuer. (Relies on EKU checking being turned off.) rule = '&&CN=user$O=MIT,' realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule]) realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=%s' % p12_generic_identity]) realm.klist(realm.user_princ) # Regression test for #8726: null deref when parsing a FILE residual # beginning with a comma. realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=,'], expected_code=1, expected_msg='Preauthentication failed while') softhsm2 = '/usr/lib/softhsm/libsofthsm2.so' if not os.path.exists(softhsm2): skip_rest('PKCS11 tests', 'SoftHSMv2 required') pkcs11_tool = which('pkcs11-tool') if not pkcs11_tool: skip_rest('PKCS11 tests', 'pkcs11-tool from OpenSC required') tool_cmd = [pkcs11_tool, '--module', softhsm2] # Prepare a SoftHSM token. softhsm2_conf = os.path.join(realm.testdir, 'softhsm2.conf') softhsm2_tokens = os.path.join(realm.testdir, 'tokens') os.mkdir(softhsm2_tokens) realm.env['SOFTHSM2_CONF'] = softhsm2_conf with open(softhsm2_conf, 'w') as f: f.write('directories.tokendir = %s\n' % softhsm2_tokens) realm.run(tool_cmd + ['--init-token', '--label', 'user', '--so-pin', 'sopin', '--init-pin', '--pin', 'userpin']) realm.run(tool_cmd + ['-w', user_pem, '-y', 'cert']) realm.run(tool_cmd + ['-w', privkey_pem, '-y', 'privkey', '-l', '--pin', 'userpin']) # Extract the slot ID generated by SoftHSM. out = realm.run(tool_cmd + ['-L']) m = re.search(r'slot ID 0x([0-9a-f]+)\n', out) if not m: fail('could not extract slot ID from SoftHSM token') slot_id = int(m.group(1), 16) p11_attr = 'X509_user_identity=PKCS11:' + softhsm2 p11_token_identity = ('PKCS11:module_name=%s:slotid=%d:token=user' % (softhsm2, slot_id)) mark('PKCS11 identity, with PIN (prompter)') realm.kinit(realm.user_princ, flags=['-X', p11_attr], password='userpin') realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) mark('PKCS11 identity, unavailable PIN') realm.run(['./responder', '-x', 'pkinit={"%s": 0}' % p11_token_identity, '-X', p11_attr, realm.user_princ], expected_code=2) mark('PKCS11 identity, wrong PIN') expected_trace = ('PKINIT client has no configured identity; giving up',) realm.kinit(realm.user_princ, flags=['-X', p11_attr], password='wrong', expected_code=1, expected_trace=expected_trace) # PKINIT with PKCS11: identity, with a PIN supplied by the responder. # Supply the response in raw form. Expect the PIN_COUNT_LOW flag (1) # to be set due to the previous test. mark('PKCS11 identity, with PIN (responder)') realm.run(['./responder', '-x', 'pkinit={"%s": 1}' % p11_token_identity, '-r', 'pkinit={"%s": "userpin"}' % p11_token_identity, '-X', p11_attr, realm.user_princ]) # Supply the response through the convenience API. realm.run(['./responder', '-X', p11_attr, '-p', '%s=%s' % (p11_token_identity, 'userpin'), realm.user_princ]) realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) mark('PKCS11 identity, EC client cert') shutil.rmtree(softhsm2_tokens) os.mkdir(softhsm2_tokens) realm.run(tool_cmd + ['--init-token', '--label', 'user', '--so-pin', 'sopin', '--init-pin', '--pin', 'userpin']) realm.run(tool_cmd + ['-w', ecuser_pem, '-y', 'cert']) realm.run(tool_cmd + ['-w', privkey_ec_pem, '-y', 'privkey', '-l', '--pin', 'userpin']) realm.kinit(realm.user_princ, flags=['-X', p11_attr], password='userpin') realm.klist(realm.user_princ) realm.run([kvno, realm.host_princ]) success('PKINIT tests') krb5-1.22.1/src/tests/t_y2038.py0000664000175000017500000000646215051422640015764 0ustar ghudsonghudsonfrom k5test import * # These tests will become much less important after the y2038 boundary # has elapsed, and may start exhibiting problems around the year 2075. if runenv.sizeof_time_t <= 4: skip_rest('y2038 timestamp tests', 'platform has 32-bit time_t') # Start a KDC running roughly 21 years in the future, after the y2038 # boundary. Set long maximum lifetimes for later tests. conf = {'realms': {'$realm': {'max_life': '9000d', 'max_renewable_life': '9000d'}}} realm = K5Realm(start_kdc=False, kdc_conf=conf) realm.start_kdc(['-T', '662256000']) # kinit without preauth should succeed with clock skew correction, but # will result in an expired ticket, because we sent an absolute end # time and didn't get a chance to correct it.. mark('kinit, no preauth') realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ], expected_code=1, expected_msg='Ticket expired') # kinit with preauth should succeed and result in a valid ticket, as # we get a chance to correct the end time based on the KDC time. Try # with encrypted timestamp and encrypted challenge. mark('kinit, with preauth') realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache]) realm.run([kvno, realm.host_princ]) # Test that expiration warning works after y2038, by setting a # password expiration time ten minutes after the KDC time. mark('expiration warning') realm.run([kadminl, 'modprinc', '-pwexpire', '662256600 seconds', 'user']) out = realm.kinit(realm.user_princ, password('user')) if 'will expire in less than one hour' not in out: fail('password expiration message') year = int(out.split()[-1]) if year < 2038 or year > 9999: fail('password expiration year') realm.stop_kdc() realm.start_kdc() realm.start_kadmind() realm.prep_kadmin() # Test getdate parsing of absolute timestamps after 2038 and # marshalling over the kadmin protocol. The local time zone will # affect the display time by a little bit, so just look for the year. mark('kadmin marshalling') realm.run_kadmin(['modprinc', '-pwexpire', '2040-02-03', realm.host_princ]) realm.run_kadmin(['getprinc', realm.host_princ], expected_msg=' 2040\n') # Get a ticket whose lifetime crosses the y2038 boundary and # range-check the expiration year as reported by klist. mark('ticket lifetime across y2038') realm.kinit(realm.user_princ, password('user'), flags=['-l', '8000d', '-r', '8500d']) realm.run([kvno, realm.host_princ]) out = realm.run([klist]) if int(out.split('\n')[4].split()[2].split('/')[2]) < 39: fail('unexpected tgt expiration year') if int(out.split('\n')[5].split()[2].split('/')[2]) < 40: fail('unexpected tgt rtill year') if int(out.split('\n')[6].split()[2].split('/')[2]) < 39: fail('unexpected service ticket expiration year') if int(out.split('\n')[7].split()[2].split('/')[2]) < 40: fail('unexpected service ticket rtill year') realm.kinit(realm.user_princ, None, ['-R']) out = realm.run([klist]) if int(out.split('\n')[4].split()[2].split('/')[2]) < 39: fail('unexpected renewed tgt expiration year') if int(out.split('\n')[5].split()[2].split('/')[2]) < 40: fail('unexpected renewed tgt rtill year') success('y2038 tests') krb5-1.22.1/src/tests/shlib/0000775000175000017500000000000015051422640015373 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/shlib/Makefile.in0000664000175000017500000000052515051422640017442 0ustar ghudsonghudsonmydir=tests$(S)shlib BUILDTOP=$(REL)..$(S).. #VALGRIND=valgrind #VALGRINDFLAGS=--tool=memcheck --leak-check=yes --show-reachable=yes SRCS=$(srcdir)/t_loader.c all: run-t_loader: t_loader $(RUN_TEST) ./t_loader t_loader: t_loader.o $(CC_LINK) -o t_loader t_loader.o $(DL_LIB) check-unix: install: clean: $(RM) t_loader.o t_loader krb5-1.22.1/src/tests/shlib/deps0000664000175000017500000000047415051422640016256 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)t_loader.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ t_loader.c krb5-1.22.1/src/tests/shlib/t_loader.c0000664000175000017500000003131715051422640017335 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/shlib/t_loader.c */ /* * Copyright (C) 2005 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-platform.h" #include "krb5.h" #include "gssapi/gssapi.h" #define HAVE_DLOPEN 1 static int verbose = 1; #ifdef HAVE_DLFCN_H # include #endif /* Solaris man page recommends link.h too */ /* lazy = 1 means resolve symbols later, 0 means now; any other flags we should be testing? On Windows, maybe? Return value is the library handle. On error, print a message and exit. */ #define do_open(LIB,REV,FLAGS) do_open_1(LIB,REV,FLAGS,__LINE__) static void *do_open_1(const char *libname, const char *rev, int lazy, int line); /* Look up a function symbol in the library and return a pointer. The return value may need casting to the correct type. On error, print a message and exit. */ static void *get_sym_1(void *libhandle, const char *sym, int line); #define get_sym(LIB, NAME) get_sym_1(LIB, NAME, __LINE__) #define GET_FSYM(TYPE, LIB, NAME) ((TYPE) get_sym(LIB, NAME)) #define get_gfun(LIB, NAME) ((OM_uint32 KRB5_CALLCONV(*)()) get_sym(LIB, NAME)) /* Close dynamically-opened library. If the OS reports an error in doing so, print a message and exit. */ #define do_close(X) do_close_1(X, __LINE__) static void do_close_1(void *libhandle, int line); #ifdef HAVE_DLOPEN #ifdef _AIX # define SHLIB_SUFFIX ".a" #else # define SHLIB_SUFFIX ".so" #endif #define HORIZ 25 static void *do_open_1(const char *libname, const char *rev, int lazy, int line) { void *p; char *namebuf; int r; if (verbose) printf("from line %d: do_open(%s)...%*s", line, libname, HORIZ-strlen(libname), ""); #ifdef _AIX r = asprintf(&namebuf, "lib%s%s", libname, SHLIB_SUFFIX); #else r = asprintf(&namebuf, "lib%s%s(shr.o.%s)", libname, SHLIB_SUFFIX, rev); #endif if (r < 0) { perror("asprintf"); exit(1); } #ifndef RTLD_MEMBER #define RTLD_MEMBER 0 #endif p = dlopen(namebuf, (lazy ? RTLD_LAZY : RTLD_NOW) | RTLD_MEMBER); if (p == 0) { fprintf(stderr, "dlopen of %s failed: %s\n", namebuf, dlerror()); exit(1); } free(namebuf); if (verbose) printf("done: %p\n", p); return p; } #define SYM_PREFIX "" static void *get_sym_1(void *libhandle, const char *symname, int line) { void *s; /* Bah. Fix this later, if we care. */ assert(strlen(SYM_PREFIX) == 0); if (verbose) printf("from line %d: get_sym(%s)...%*s", line, symname, HORIZ-strlen(symname), ""); s = dlsym(libhandle, symname); if (s == 0) { fprintf(stderr, "symbol %s not found\n", symname); exit(1); } if (verbose) printf("done: %p\n", s); return s; } static void do_close_1(void *libhandle, int line) { if (verbose) { char pbuf[3*sizeof(libhandle)+4]; snprintf(pbuf, sizeof(pbuf), "%p", libhandle); printf("from line %d: do_close(%s)...%*s", line, pbuf, HORIZ-1-strlen(pbuf), ""); } if (dlclose(libhandle) != 0) { fprintf(stderr, "dlclose failed: %s\n", dlerror()); exit(1); } if (verbose) printf("done\n"); } #elif defined _WIN32 static void *do_open(const char *libname, int lazy) { /* To be written? */ abort(); } static void *get_sym(void *libhandle, const char *symname) { abort(); } static void do_close(void *libhandle) { abort(); } #else static void *do_open(const char *libname, int lazy) { printf("don't know how to do dynamic loading here, punting\n"); exit(0); } static void *get_sym(void *libhandle, const char *symname) { abort(); } static void do_close(void *libhandle) { abort(); } #endif int main(void) { void *celib, *k5lib, *gsslib, *celib2; (void) setvbuf(stdout, 0, _IONBF, 0); celib = do_open("com_err", "3.0", 0); k5lib = do_open("krb5", "3.2", 0); gsslib = do_open("gssapi_krb5", "2.2", 0); celib2 = do_open("com_err", "3.0", 0); do_close(celib2); { typedef krb5_error_code KRB5_CALLCONV (*ict)(krb5_context *); typedef void KRB5_CALLCONV (*fct)(krb5_context); ict init_context = (ict) get_sym(k5lib, "krb5_init_context"); fct free_context = (fct) get_sym(k5lib, "krb5_free_context"); krb5_context ctx; krb5_error_code err; #define CALLING(S) (verbose ? printf("at line %d: calling %s...%*s", __LINE__, #S, (int)(HORIZ+1-strlen(#S)), "") : 0) #define DONE() (verbose ? printf("done\n") : 0) CALLING(krb5_init_context); err = init_context(&ctx); DONE(); if (err) { fprintf(stderr, "error 0x%lx initializing context\n", (unsigned long) err); exit(1); } CALLING(krb5_free_context); free_context(ctx); DONE(); } celib2 = do_open("com_err", "3.0", 0); do_close(celib); do_close(k5lib); do_close(celib2); do_close(gsslib); /* Test gssapi_krb5 without having loaded anything else. */ gsslib = do_open("gssapi_krb5", "2.2", 1); { OM_uint32 KRB5_CALLCONV (*init_sec_context)(OM_uint32 *, gss_cred_id_t, gss_ctx_id_t *, gss_name_t, gss_OID, OM_uint32, OM_uint32, gss_channel_bindings_t, gss_buffer_t, gss_OID *, gss_buffer_t, OM_uint32 *, OM_uint32 *) = get_gfun(gsslib, "gss_init_sec_context"); OM_uint32 KRB5_CALLCONV (*import_name)(OM_uint32 *, gss_buffer_t, gss_OID, gss_name_t *) = get_gfun(gsslib, "gss_import_name"); OM_uint32 KRB5_CALLCONV (*release_buffer)(OM_uint32 *, gss_buffer_t) = get_gfun(gsslib, "gss_release_buffer"); OM_uint32 KRB5_CALLCONV (*release_name)(OM_uint32 *, gss_name_t *) = get_gfun(gsslib, "gss_release_name"); OM_uint32 KRB5_CALLCONV (*delete_sec_context)(OM_uint32 *, gss_ctx_id_t *, gss_buffer_t) = get_gfun(gsslib, "gss_delete_sec_context"); OM_uint32 gmaj, gmin; OM_uint32 retflags; gss_ctx_id_t gctx = GSS_C_NO_CONTEXT; gss_buffer_desc token; gss_name_t target; static gss_buffer_desc target_name_buf = { 9, "x@mit.edu" }; static gss_OID_desc service_name = { 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04" }; CALLING(gss_import_name); gmaj = import_name(&gmin, &target_name_buf, &service_name, &target); DONE(); if (gmaj != GSS_S_COMPLETE) { fprintf(stderr, "import_name reports error major 0x%lx minor 0x%lx(%ld)\n", (unsigned long) gmaj, (unsigned long) gmin, (signed long) gmin); exit(1); } /* This will probably get different errors, depending on whether we have tickets at the time. Doesn't matter much, we're ignoring the error and testing whether we're doing cleanup properly. (Though the internal cleanup needed in the two cases might be different.) */ CALLING(gss_init_sec_context); gmaj = init_sec_context(&gmin, GSS_C_NO_CREDENTIAL, &gctx, target, GSS_C_NULL_OID, 0, 0, NULL, GSS_C_NO_BUFFER, NULL, &token, &retflags, NULL); DONE(); /* Ignore success/failure indication. */ if (token.length) { CALLING(gss_release_buffer); release_buffer(&gmin, &token); DONE(); } CALLING(gss_release_name); release_name(&gmin, &target); DONE(); if (gctx != GSS_C_NO_CONTEXT) { CALLING(gss_delete_sec_context); delete_sec_context(&gmin, gctx, GSS_C_NO_BUFFER); DONE(); } } do_close(gsslib); /* Test gssapi_krb5 with com_err already loaded, then unload com_err first. */ celib = do_open("com_err", "3.0", 1); gsslib = do_open("gssapi_krb5", "2.2", 1); { OM_uint32 KRB5_CALLCONV (*init_sec_context)(OM_uint32 *, gss_cred_id_t, gss_ctx_id_t *, gss_name_t, gss_OID, OM_uint32, OM_uint32, gss_channel_bindings_t, gss_buffer_t, gss_OID *, gss_buffer_t, OM_uint32 *, OM_uint32 *) = get_gfun(gsslib, "gss_init_sec_context"); OM_uint32 KRB5_CALLCONV (*import_name)(OM_uint32 *, gss_buffer_t, gss_OID, gss_name_t *) = get_gfun(gsslib, "gss_import_name"); OM_uint32 KRB5_CALLCONV (*release_buffer)(OM_uint32 *, gss_buffer_t) = get_gfun(gsslib, "gss_release_buffer"); OM_uint32 KRB5_CALLCONV (*release_name)(OM_uint32 *, gss_name_t *) = get_gfun(gsslib, "gss_release_name"); OM_uint32 KRB5_CALLCONV (*delete_sec_context)(OM_uint32 *, gss_ctx_id_t *, gss_buffer_t) = get_gfun(gsslib, "gss_delete_sec_context"); OM_uint32 gmaj, gmin; OM_uint32 retflags; gss_ctx_id_t gctx = GSS_C_NO_CONTEXT; gss_buffer_desc token; gss_name_t target; static gss_buffer_desc target_name_buf = { 9, "x@mit.edu" }; static gss_OID_desc service_name = { 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04" }; CALLING(gss_import_name); gmaj = import_name(&gmin, &target_name_buf, &service_name, &target); DONE(); if (gmaj != GSS_S_COMPLETE) { fprintf(stderr, "import_name reports error major 0x%lx minor 0x%lx(%ld)\n", (unsigned long) gmaj, (unsigned long) gmin, (signed long) gmin); exit(1); } /* This will probably get different errors, depending on whether we have tickets at the time. Doesn't matter much, we're ignoring the error and testing whether we're doing cleanup properly. (Though the internal cleanup needed in the two cases might be different.) */ CALLING(gss_init_sec_context); gmaj = init_sec_context(&gmin, GSS_C_NO_CREDENTIAL, &gctx, target, GSS_C_NULL_OID, 0, 0, NULL, GSS_C_NO_BUFFER, NULL, &token, &retflags, NULL); DONE(); /* Ignore success/failure indication. */ if (token.length) { CALLING(gss_release_buffer); release_buffer(&gmin, &token); DONE(); } CALLING(gss_release_name); release_name(&gmin, &target); DONE(); if (gctx != GSS_C_NO_CONTEXT) { CALLING(gss_delete_sec_context); delete_sec_context(&gmin, gctx, GSS_C_NO_BUFFER); DONE(); } } do_close(celib); do_close(gsslib); return 0; } krb5-1.22.1/src/tests/t_audit.py0000775000175000017500000000204515051422640016301 0ustar ghudsonghudsonfrom k5test import * conf = {'plugins': {'audit': { 'module': 'test:$plugins/audit/test/k5audit_test.so'}}} realm = K5Realm(krb5_conf=conf, get_creds=False) realm.addprinc('target') realm.run([kadminl, 'modprinc', '+ok_to_auth_as_delegate', realm.host_princ]) # Make normal AS and TGS requests so they will be audited. realm.kinit(realm.host_princ, flags=['-k', '-f']) realm.run([kvno, 'target']) # Make S4U2Self and S4U2Proxy requests so they will be audited. The # S4U2Proxy request is expected to fail. realm.run([kvno, '-k', realm.keytab, '-U', 'user', '-P', 'target'], expected_code=1, expected_msg='KDC can\'t fulfill requested option') # Make a U2U request so it will be audited. uuserver = os.path.join(buildtop, 'appl', 'user_user', 'uuserver') uuclient = os.path.join(buildtop, 'appl', 'user_user', 'uuclient') port_arg = str(realm.server_port()) realm.start_server([uuserver, port_arg], 'Server started') realm.run([uuclient, hostname, 'testing message', port_arg], expected_msg='Hello') success('Audit tests') krb5-1.22.1/src/tests/t_cve-2012-1015.py0000775000175000017500000000223515051422640016717 0ustar ghudsonghudsonimport base64 import socket from k5test import * realm = K5Realm() # CVE-2012-1015 KDC frees uninitialized pointer # Force a failure in krb5_c_make_checksum(), which causes the cleanup # code in kdc_handle_protected_negotiation() to free an uninitialized # pointer in an unpatched KDC. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) a = (hostname, realm.portbase) x1 = base64.b16decode('6A81A030819DA103020105A20302010A' + 'A30E300C300AA10402020095A2020400' + 'A48180307EA00703050000000000A120' + '301EA003020101A11730151B066B7262' + '7467741B0B4B5242544553542E434F4D' + 'A20D1B0B4B5242544553542E434F4DA3' + '20301EA003020101A11730151B066B72' + '627467741B0B4B5242544553542E434F' + '4DA511180F3139393430363130303630' + '3331375AA7030201') x2 = base64.b16decode('A8083006020106020112') for x in range(0, 128): s.sendto(x1 + bytes([x]) + x2, a) # Make sure kinit still works. realm.kinit(realm.user_princ, password('user')) success('CVE-2012-1015 regression test') krb5-1.22.1/src/tests/au_dict.json0000664000175000017500000000164215051422640016600 0ustar ghudsonghudson{ "event_name":"", "event_success":0, "evidence_tkt_id":"", "fromport":0, "fromaddr":{ "type":0, "length":0, "ip":[]}, "kdc_status":"", "rep_etype":0, "rep.ticket":{ "authtime":0, "cname":{ "components":[], "realm":"", "length":0, "type":0}, "end":0, "flags":0, "sess_etype":0, "srv_etype":0, "sname":{ "components":[], "realm":"", "length":0, "type":0}}, "req.avail_etypes":[], "req.client":{ "components":[], "realm":"", "length":0, "type":0}, "req_id":"", "req.kdc_options":0, "req.pa_type":[], "req.server":{ "components":[], "realm":"", "length":0, "type":0}, "req.tkt_end":0, "s4u2proxy_user":{ "components":[], "realm":"", "length":0, "type":0}, "s4u2self_user":{ "components":[], "realm":"", "length":0, "type":0}, "stage":1, "tkt_in_id":"", "tkt_renewed":0, "tkt_out_id":"", "tkt_validated":0, "u2u_user":{ "components":[], "realm":"", "length":0, "type":0}, "violation":0 } krb5-1.22.1/src/tests/icred.c0000664000175000017500000001112515051422640015524 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/icred.c - test harness for getting initial creds */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This program exercises the init_creds APIs in ways kinit doesn't. */ #include "k5-platform.h" #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { const char *ktname = NULL, *sname = NULL, *princstr, *password; krb5_principal client; krb5_init_creds_context icc; krb5_get_init_creds_opt *opt; krb5_keytab keytab = NULL; krb5_creds creds; krb5_boolean stepwise = FALSE; krb5_preauthtype ptypes[64]; int c, nptypes = 0; char *val; check(krb5_init_context(&ctx)); check(krb5_get_init_creds_opt_alloc(ctx, &opt)); while ((c = getopt(argc, argv, "k:so:S:X:")) != -1) { switch (c) { case 'k': ktname = optarg; break; case 's': stepwise = TRUE; break; case 'o': assert(nptypes < 64); ptypes[nptypes++] = atoi(optarg); break; case 'S': sname = optarg; break; case 'X': val = strchr(optarg, '='); if (val != NULL) *val++ = '\0'; else val = "yes"; check(krb5_get_init_creds_opt_set_pa(ctx, opt, optarg, val)); break; default: abort(); } } argc -= optind; argv += optind; if (argc != 1 && argc != 2) abort(); princstr = argv[0]; password = argv[1]; if (sname != NULL) { check(krb5_sname_to_principal(ctx, princstr, sname, KRB5_NT_SRV_HST, &client)); } else { check(krb5_parse_name(ctx, princstr, &client)); } if (ktname != NULL) check(krb5_kt_resolve(ctx, ktname, &keytab)); if (nptypes > 0) krb5_get_init_creds_opt_set_preauth_list(opt, ptypes, nptypes); if (stepwise) { /* Use the stepwise interface. */ check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, &icc)); if (keytab != NULL) check(krb5_init_creds_set_keytab(ctx, icc, keytab)); if (password != NULL) check(krb5_init_creds_set_password(ctx, icc, password)); check(krb5_init_creds_get(ctx, icc)); krb5_init_creds_free(ctx, icc); } else if (keytab != NULL) { check(krb5_get_init_creds_keytab(ctx, &creds, client, keytab, 0, NULL, opt)); krb5_free_cred_contents(ctx, &creds); } else { /* Use the traditional one-shot interface. */ check(krb5_get_init_creds_password(ctx, &creds, client, password, NULL, NULL, 0, NULL, opt)); krb5_free_cred_contents(ctx, &creds); } if (keytab != NULL) krb5_kt_close(ctx, keytab); krb5_get_init_creds_opt_free(ctx, opt); krb5_free_principal(ctx, client); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/hrealm.c0000664000175000017500000000611415051422640015710 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/hrealm.c - Test harness for host-realm interfaces */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is intended to be run from a python script as: * * hrealm -h|-f|-d [hostname] * * Calls krb5_get_host_realm, krb5_get_fallback_host_realm, or * krb5_default_realm depending on the option given. For the first two * choices, hostname or NULL is passed as the argument. The results are * displayed one per line. */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static void display(char **realms) { while (realms != NULL && *realms != NULL) printf("%s\n", *realms++); } int main(int argc, char **argv) { krb5_data d; char **realms, *realm; check(krb5_init_context(&ctx)); /* Parse arguments. */ if (argc < 2 || argc > 3) abort(); if (strcmp(argv[1], "-d") == 0) { check(krb5_get_default_realm(ctx, &realm)); printf("%s\n", realm); krb5_free_default_realm(ctx, realm); } else if (strcmp(argv[1], "-h") == 0) { check(krb5_get_host_realm(ctx, argv[2], &realms)); display(realms); krb5_free_host_realm(ctx, realms); } else if (strcmp(argv[1], "-f") == 0) { assert(argc == 3); d = string2data(argv[2]); check(krb5_get_fallback_host_realm(ctx, &d, &realms)); display(realms); krb5_free_host_realm(ctx, realms); } else { abort(); } krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/t_keyrollover.py0000775000175000017500000001026215051422640017550 0ustar ghudsonghudsonfrom k5test import * import re rollover_krb5_conf = {'libdefaults': {'allow_weak_crypto': 'true'}} realm = K5Realm(krbtgt_keysalt='aes128-cts-hmac-sha256-128:normal', krb5_conf=rollover_krb5_conf) princ1 = 'host/test1@%s' % (realm.realm,) princ2 = 'host/test2@%s' % (realm.realm,) realm.addprinc(princ1) realm.addprinc(princ2) realm.run([kvno, realm.host_princ]) # Change key for TGS, keeping old key. realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts', '-keepold', realm.krbtgt_princ]) # Ensure that kvno still works with an old TGT. realm.run([kvno, princ1]) realm.run([kadminl, 'purgekeys', realm.krbtgt_princ]) # Make sure an old TGT fails after purging old TGS key. realm.run([kvno, princ2], expected_code=1) msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): ' \ 'aes256-cts-hmac-sha1-96, aes128-cts-hmac-sha256-128' % \ (realm.realm, realm.realm) realm.run([klist, '-e'], expected_msg=msg) # Check that new key actually works. realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): ' \ 'aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96' % \ (realm.realm, realm.realm) realm.run([klist, '-e'], expected_msg=msg) # Test that the KDC only accepts the first enctype for a kvno, for a # local-realm TGS request. To set this up, we abuse an edge-case # behavior of modprinc -kvno. First, set up a DES3 krbtgt entry at # kvno 1 and cache a krbtgt ticket. realm.run([kadminl, 'cpw', '-randkey', '-e', 'des3-cbc-sha1', realm.krbtgt_princ]) realm.run([kadminl, 'modprinc', '-kvno', '1', realm.krbtgt_princ]) realm.kinit(realm.user_princ, password('user')) # Add an AES krbtgt entry at kvno 2, and then reset it to kvno 1 # (modprinc -kvno sets the kvno on all entries without deleting any). realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts', realm.krbtgt_princ]) realm.run([kadminl, 'modprinc', '-kvno', '1', realm.krbtgt_princ]) out = realm.run([kadminl, 'getprinc', realm.krbtgt_princ]) if 'vno 1, aes256-cts' not in out or \ 'vno 1, DEPRECATED:des3-cbc-sha1' not in out: fail('keyrollover: setup for TGS enctype test failed') # Now present the DES3 ticket to the KDC and make sure it's rejected. realm.run([kvno, realm.host_princ], expected_code=1) # Test -keepold limit for self-service requests through kadmind. def count_kvnos(princ, expected_count): out = realm.run_kadmin(['getprinc', princ]) vnos = re.findall(r' vno \d+,', out) if len(set(vnos)) != expected_count: fail('expected %d key versions' % expected_count) realm.start_kadmind() realm.prep_kadmin(realm.user_princ, password('user')) realm.run_kadmin(['cpw', '-randkey', '-keepold', realm.user_princ]) realm.run_kadmin(['cpw', '-randkey', '-keepold', realm.user_princ]) realm.run_kadmin(['cpw', '-randkey', '-keepold', realm.user_princ]) realm.run_kadmin(['cpw', '-randkey', '-keepold', realm.user_princ]) count_kvnos(realm.user_princ, 5) realm.run_kadmin(['cpw', '-randkey', '-keepold', realm.user_princ]) count_kvnos(realm.user_princ, 5) realm.run_kadmin(['cpw', '-pw', 'pw', '-keepold', realm.user_princ]) count_kvnos(realm.user_princ, 5) # Test that the limit doesn't apply when modifying another principal. realm.prep_kadmin() realm.run_kadmin(['cpw', '-randkey', '-keepold', realm.user_princ]) count_kvnos(realm.user_princ, 6) realm.run_kadmin(['cpw', '-pw', 'pw', '-keepold', realm.user_princ]) count_kvnos(realm.user_princ, 7) realm.stop() # Test a cross-realm TGT key rollover scenario where realm 1 mimics # the Active Directory behavior of always using kvno 0 when issuing # cross-realm TGTs. The first kvno invocation caches a cross-realm # TGT with the old key, and the second kvno invocation sends it to # r2's KDC with no kvno to identify it, forcing the KDC to try # multiple keys. r1, r2 = cross_realms(2) crosstgt_princ = 'krbtgt/%s@%s' % (r2.realm, r1.realm) r1.run([kadminl, 'modprinc', '-kvno', '0', crosstgt_princ]) r1.run([kvno, r2.host_princ]) r2.run([kadminl, 'cpw', '-pw', 'newcross', '-keepold', crosstgt_princ]) r1.run([kadminl, 'cpw', '-pw', 'newcross', crosstgt_princ]) r1.run([kadminl, 'modprinc', '-kvno', '0', crosstgt_princ]) r1.run([kvno, r2.user_princ]) success('keyrollover') krb5-1.22.1/src/tests/proxy-certs/0000775000175000017500000000000015051422640016571 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/proxy-certs/make-certs.sh0000775000175000017500000000715015051422640021166 0ustar ghudsonghudson#!/bin/sh -e PWD=`pwd` NAMETYPE=1 KEYSIZE=2048 DAYS=4000 REALM=KRBTEST.COM TLS_SERVER_EKU=1.3.6.1.5.5.7.3.1 PROXY_EKU_LIST=$TLS_SERVER_EKU cat > openssl.cnf << EOF [req] prompt = no distinguished_name = \$ENV::SUBJECT [ca] default_ca = test_ca [test_ca] new_certs_dir = $PWD serial = $PWD/ca.srl database = $PWD/ca.db certificate = $PWD/ca.pem private_key = $PWD/privkey.pem default_days = $DAYS x509_extensions = exts_proxy policy = proxyname default_md = sha256 unique_subject = no email_in_dn = no [signer] CN = test CA certificate C = US ST = Massachusetts L = Cambridge O = MIT OU = Insecure Kerberos test CA CN = test suite CA; do not use otherwise [proxy] C = US ST = Massachusetts O = KRBTEST.COM CN = PROXYinSubject [localhost] C = US ST = Massachusetts O = KRBTEST.COM CN = localhost [proxyname] C = supplied ST = supplied O = supplied CN = supplied [exts_ca] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign basicConstraints = critical,CA:TRUE [exts_proxy] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE subjectAltName = DNS:proxyÅ ubjectÄltÑame,DNS:proxySubjectAltName,IP:127.0.0.1,IP:::1,DNS:localhost extendedKeyUsage = $PROXY_EKU_LIST [exts_proxy_no_san] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement basicConstraints = critical,CA:FALSE extendedKeyUsage = $PROXY_EKU_LIST EOF # Generate a private key. openssl genrsa $KEYSIZE > privkey.pem # Generate a "CA" certificate. SUBJECT=signer openssl req -config openssl.cnf -new -x509 -extensions exts_ca \ -set_serial 1 -days $DAYS -key privkey.pem -out ca.pem # Generate proxy certificate signing requests. SUBJECT=proxy openssl req -config openssl.cnf -new -key privkey.pem \ -out proxy.csr SUBJECT=localhost openssl req -config openssl.cnf -new -key privkey.pem \ -out localhost.csr # Issue the certificate with the right name in a subjectAltName. echo 02 > ca.srl cat /dev/null > ca.db SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy \ -batch -days $DAYS -notext -out tmp.pem -in proxy.csr cat privkey.pem tmp.pem > proxy-san.pem # Issue a certificate that only has the name in the subject field SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy_no_san \ -batch -days $DAYS -notext -out tmp.pem -in localhost.csr cat privkey.pem tmp.pem > proxy-subject.pem # Issue a certificate that doesn't include any matching name values. SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy_no_san \ -batch -days $DAYS -notext -out tmp.pem -in proxy.csr cat privkey.pem tmp.pem > proxy-no-match.pem # Issue a certificate that contains all matching name values. SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy \ -batch -days $DAYS -notext -out tmp.pem -in localhost.csr cat privkey.pem tmp.pem > proxy-ideal.pem # Corrupt the signature on the certificate. SUBJECT=proxy openssl x509 -outform der -in proxy-ideal.pem -out bad.der length=`od -Ad bad.der | tail -n 1 | awk '{print $1}'` dd if=/dev/zero bs=1 of=bad.der count=16 seek=`expr $length - 16` SUBJECT=proxy openssl x509 -inform der -in bad.der -out tmp.pem cat privkey.pem tmp.pem > proxy-badsig.pem # Clean up. rm -f openssl.cnf proxy.csr localhost.csr privkey.pem ca.db ca.db.old ca.srl ca.srl.old ca.db.attr ca.db.attr.old 02.pem 03.pem 04.pem 05.pem tmp.pem bad.der krb5-1.22.1/src/tests/proxy-certs/ca.pem0000664000175000017500000000324415051422640017662 0ustar ghudsonghudson-----BEGIN CERTIFICATE----- MIIEuzCCA6OgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSIwIAYDVQQLDBlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDDCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x OTExMTIxODMwMzRaFw0zMDEwMjUxODMwMzRaMIGZMQswCQYDVQQGEwJVUzEWMBQG A1UECAwNTWFzc2FjaHVzZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQK DANNSVQxIjAgBgNVBAsMGUluc2VjdXJlIEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNV BAMMI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA54HCeTTUe127pqjK8r28NGMw2r2x+hWK KayH5NmqOqnwnzRHkZE5UjkazQ/h97S6LZ6Yb8w3mJEyX1PdcNARDw2mbOPFk5N9 uXnBb6AZog7hh9wMe//g9a7PpKanfw69fSVgAr49TFFiLoKuyTgHiJOB7YgP0bTH EO4lLqusPQM16lRDSdoXg42udAh3uBY+QDs23snLSiB+9vt8gt6gXiaYb3BBOWs9 B3PKs374N9kOPsgcj+8kyR/M+q+RfK5biqS3ce/sxvPV0Kseh//1uJxlbQCwOiBd 3TLWHLhW9F7rzEcvzn1Mfck35s0XDDRlGxRGGDy+ZCKmxf8Zu/8SwwIDAQABo4IB CjCCAQYwHQYDVR0OBBYEFPf/vJvFMCwrABeCC0sq7RGfYeIiMIHGBgNVHSMEgb4w gbuAFPf/vJvFMCwrABeCC0sq7RGfYeIioYGfpIGcMIGZMQswCQYDVQQGEwJVUzEW MBQGA1UECAwNTWFzc2FjaHVzZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYD VQQKDANNSVQxIjAgBgNVBAsMGUluc2VjdXJlIEtlcmJlcm9zIHRlc3QgQ0ExLDAq BgNVBAMMI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlggEBMAsG A1UdDwQEAwIB/jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBz q/t9amz4ahTFNc0v69NZrfCBgo7DWBHxXuE0Gov2/RBPwP/+Efrd4+1Tl5fSv6We N/cttEUTTM3Z7wtof3mkSQwkozwWpaHXm31St+0FbTuHNpN4i0Uae5lsO8/pTz/L VqsVLjGGpkZKP831BO9oJJbwUASNc2dpLs94pojlSlSZzf/u/T+k0wltgZexnQpU 5IrdPIqteB32ym2XjZWSCS29jL3zoZ/y8UAPIOR/Zi77wNCehOuBx2bzc/P6RNLa CuuPMhDu8PPYVB3rfJInmF5wT5jQ9YX4UUb0qYXDRff5/l26fEjLHQSrA/iMqdIW dsDwkqTcy1lOjcP3xOMq -----END CERTIFICATE----- krb5-1.22.1/src/tests/proxy-certs/proxy-no-match.pem0000664000175000017500000000635615051422640022173 0ustar ghudsonghudson-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA54HCeTTUe127pqjK8r28NGMw2r2x+hWKKayH5NmqOqnwnzRH kZE5UjkazQ/h97S6LZ6Yb8w3mJEyX1PdcNARDw2mbOPFk5N9uXnBb6AZog7hh9wM e//g9a7PpKanfw69fSVgAr49TFFiLoKuyTgHiJOB7YgP0bTHEO4lLqusPQM16lRD SdoXg42udAh3uBY+QDs23snLSiB+9vt8gt6gXiaYb3BBOWs9B3PKs374N9kOPsgc j+8kyR/M+q+RfK5biqS3ce/sxvPV0Kseh//1uJxlbQCwOiBd3TLWHLhW9F7rzEcv zn1Mfck35s0XDDRlGxRGGDy+ZCKmxf8Zu/8SwwIDAQABAoIBAGxzOBQpsIReQ6Lu HaybP4hXEzLVfIOIBaJCJaMKaJl0tLkP95r0qiKfh7OahiPRMQpf6k8tHrpFApDv q6PGhMdFgLov9YWNqW7y37AYEwn86KAJcHvCQbM2AiXCwGJgGFqA4LpIPlT7JwBc zd6LddQALfSFMcvuYPbIaPi1CUnGy/AAyxGjUrc60KO57NbI+dHSTOwTHO1QjOz9 ESk4fb34beUuZQzR6s/s1N0k09GJyklLpAAblRs5M6w9IlAn781eRLUAHTafLm4b 21J9k2Q2UaOofn0Cvh8ggyJMiYqAJ0CsRy5pJroEyboA51WU+8THNFkNtRX5SxY5 YY3xE7ECgYEA/qkq7BPMkr/SnBPm32G1Eux5eLVd65qbox0oTLodZbusuxutqXTp 1MseDPQtHlrq6CQBizwElx//pdKnIiU9iBS/QkMR9CviitMTt+WrWRrM54/A4CJP AU2Jg7b2DmhW1ombHHiBZ1tWzyiv9zxrtwR8kmKqv9aTOuPn4l7jY5kCgYEA6Llr 47pQjp/YhkBBvlriRwM9RXek++ythgsWvEswORaUalnaZ9gxZOKKas35GLDDuVyT RnEhIqVlTg9iz6x5fXRtm6VzQvy9yFLzPMnlwsiSnRNOfMVIETUTOhNgm45tYY8f lN5bcdY6k6VZ/g/N3zqddnxkjocrd6lAayjjIrsCgYEAyZLYAcPuQx6JM7fhIGIz tQXvZKeS7yITHbq/onQTPuqd4AEZpi9/w0r/v1srt4JZvGR7wF1CeOkAL56dYr69 hNB/T5DNTkvKZv6K9h5aUg6PsJ8uGXuus6ZPOi4BeAgI7IpBd/i+3TQEc7eOCZIO 5PAtNqXY6D6NjajGbH2VWckCgYA2KRDmyrF8v86QT9v9BQGsLSDRTerjhk1L6MC9 yXHLl2mq5oZhrHqyU9aKzKywBlNGjDjqJ+HiQkO1SvdgBW+wtqvbkUGl0VQJjuR0 vTfvgOY+EAQwHWmMN6Hl3iSZjyf9kGV1K9p0P7saKV0sN1leHjIPJRvx35tKGeWY CsfxiQKBgQCVUvsX/HeWyc4bxxMuzw8JniUG2JftZqIC1haHEFNElASjt4hARM7Y X/dkpYPXOZaN+qfvP949rS1WPXRtwMjt7bYzm7MGbXW7OiGGY3LV2CuVmbXJupvr Usvi+YnpqKDY/miOYd+541NJm76AQTSgQ8K7XitX7Beddh1U9e17mg== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIEhzCCA2+gAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSIwIAYDVQQLDBlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDDCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x OTExMTIxODMwMzRaFw0zMDEwMjUxODMwMzRaMFQxCzAJBgNVBAYTAlVTMRYwFAYD VQQIDA1NYXNzYWNodXNldHRzMRQwEgYDVQQKDAtLUkJURVNULkNPTTEXMBUGA1UE AwwOUFJPWFlpblN1YmplY3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQDngcJ5NNR7XbumqMryvbw0YzDavbH6FYoprIfk2ao6qfCfNEeRkTlSORrND+H3 tLotnphvzDeYkTJfU91w0BEPDaZs48WTk325ecFvoBmiDuGH3Ax7/+D1rs+kpqd/ Dr19JWACvj1MUWIugq7JOAeIk4HtiA/RtMcQ7iUuq6w9AzXqVENJ2heDja50CHe4 Fj5AOzbeyctKIH72+3yC3qBeJphvcEE5az0Hc8qzfvg32Q4+yByP7yTJH8z6r5F8 rluKpLdx7+zG89XQqx6H//W4nGVtALA6IF3dMtYcuFb0XuvMRy/OfUx9yTfmzRcM NGUbFEYYPL5kIqbF/xm7/xLDAgMBAAGjggEcMIIBGDAdBgNVHQ4EFgQU9/+8m8Uw LCsAF4ILSyrtEZ9h4iIwgcYGA1UdIwSBvjCBu4AU9/+8m8UwLCsAF4ILSyrtEZ9h 4iKhgZ+kgZwwgZkxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRz MRIwEAYDVQQHDAlDYW1icmlkZ2UxDDAKBgNVBAoMA01JVDEiMCAGA1UECwwZSW5z ZWN1cmUgS2VyYmVyb3MgdGVzdCBDQTEsMCoGA1UEAwwjdGVzdCBzdWl0ZSBDQTsg ZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0PBAQDAgPoMAwGA1UdEwEB/wQC MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAI0Ons8g 6aXdZsKSmp1hbwNUvsY5GNl/QHVJIMQbe9zNVkW9Hp286fzkMar6peTB9MEnhzJ5 5mbJM9DkugzgJeG0+HwsSdjAQCOcG4jSQ3SaASETOo58LsaG/yssIaZiZdJBrzNb 1D5fJVVpopZMZ/mKUNB/2ofUVGVBZCdfyOoIbVSkkm1UHJ9liLFK1ZNPDTX60613 YNl4BydTiXtEg+IOYgmFXuZj310dDZUMHuYdzAM5j+6i2JaIcK4PgDE+yG9Oj9N+ uKjj0iHWyoZW49y9Hq/oiMegi2X4XZBtbZlEUu4OkpBJ1QG0MTaz/vN94sHiLOzS 81b7+2BMgHd51+E= -----END CERTIFICATE----- krb5-1.22.1/src/tests/proxy-certs/proxy-san.pem0000664000175000017500000000655015051422640021242 0ustar ghudsonghudson-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA54HCeTTUe127pqjK8r28NGMw2r2x+hWKKayH5NmqOqnwnzRH kZE5UjkazQ/h97S6LZ6Yb8w3mJEyX1PdcNARDw2mbOPFk5N9uXnBb6AZog7hh9wM e//g9a7PpKanfw69fSVgAr49TFFiLoKuyTgHiJOB7YgP0bTHEO4lLqusPQM16lRD SdoXg42udAh3uBY+QDs23snLSiB+9vt8gt6gXiaYb3BBOWs9B3PKs374N9kOPsgc j+8kyR/M+q+RfK5biqS3ce/sxvPV0Kseh//1uJxlbQCwOiBd3TLWHLhW9F7rzEcv zn1Mfck35s0XDDRlGxRGGDy+ZCKmxf8Zu/8SwwIDAQABAoIBAGxzOBQpsIReQ6Lu HaybP4hXEzLVfIOIBaJCJaMKaJl0tLkP95r0qiKfh7OahiPRMQpf6k8tHrpFApDv q6PGhMdFgLov9YWNqW7y37AYEwn86KAJcHvCQbM2AiXCwGJgGFqA4LpIPlT7JwBc zd6LddQALfSFMcvuYPbIaPi1CUnGy/AAyxGjUrc60KO57NbI+dHSTOwTHO1QjOz9 ESk4fb34beUuZQzR6s/s1N0k09GJyklLpAAblRs5M6w9IlAn781eRLUAHTafLm4b 21J9k2Q2UaOofn0Cvh8ggyJMiYqAJ0CsRy5pJroEyboA51WU+8THNFkNtRX5SxY5 YY3xE7ECgYEA/qkq7BPMkr/SnBPm32G1Eux5eLVd65qbox0oTLodZbusuxutqXTp 1MseDPQtHlrq6CQBizwElx//pdKnIiU9iBS/QkMR9CviitMTt+WrWRrM54/A4CJP AU2Jg7b2DmhW1ombHHiBZ1tWzyiv9zxrtwR8kmKqv9aTOuPn4l7jY5kCgYEA6Llr 47pQjp/YhkBBvlriRwM9RXek++ythgsWvEswORaUalnaZ9gxZOKKas35GLDDuVyT RnEhIqVlTg9iz6x5fXRtm6VzQvy9yFLzPMnlwsiSnRNOfMVIETUTOhNgm45tYY8f lN5bcdY6k6VZ/g/N3zqddnxkjocrd6lAayjjIrsCgYEAyZLYAcPuQx6JM7fhIGIz tQXvZKeS7yITHbq/onQTPuqd4AEZpi9/w0r/v1srt4JZvGR7wF1CeOkAL56dYr69 hNB/T5DNTkvKZv6K9h5aUg6PsJ8uGXuus6ZPOi4BeAgI7IpBd/i+3TQEc7eOCZIO 5PAtNqXY6D6NjajGbH2VWckCgYA2KRDmyrF8v86QT9v9BQGsLSDRTerjhk1L6MC9 yXHLl2mq5oZhrHqyU9aKzKywBlNGjDjqJ+HiQkO1SvdgBW+wtqvbkUGl0VQJjuR0 vTfvgOY+EAQwHWmMN6Hl3iSZjyf9kGV1K9p0P7saKV0sN1leHjIPJRvx35tKGeWY CsfxiQKBgQCVUvsX/HeWyc4bxxMuzw8JniUG2JftZqIC1haHEFNElASjt4hARM7Y X/dkpYPXOZaN+qfvP949rS1WPXRtwMjt7bYzm7MGbXW7OiGGY3LV2CuVmbXJupvr Usvi+YnpqKDY/miOYd+541NJm76AQTSgQ8K7XitX7Beddh1U9e17mg== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIE4jCCA8qgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSIwIAYDVQQLDBlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDDCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x OTExMTIxODMwMzRaFw0zMDEwMjUxODMwMzRaMFQxCzAJBgNVBAYTAlVTMRYwFAYD VQQIDA1NYXNzYWNodXNldHRzMRQwEgYDVQQKDAtLUkJURVNULkNPTTEXMBUGA1UE AwwOUFJPWFlpblN1YmplY3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQDngcJ5NNR7XbumqMryvbw0YzDavbH6FYoprIfk2ao6qfCfNEeRkTlSORrND+H3 tLotnphvzDeYkTJfU91w0BEPDaZs48WTk325ecFvoBmiDuGH3Ax7/+D1rs+kpqd/ Dr19JWACvj1MUWIugq7JOAeIk4HtiA/RtMcQ7iUuq6w9AzXqVENJ2heDja50CHe4 Fj5AOzbeyctKIH72+3yC3qBeJphvcEE5az0Hc8qzfvg32Q4+yByP7yTJH8z6r5F8 rluKpLdx7+zG89XQqx6H//W4nGVtALA6IF3dMtYcuFb0XuvMRy/OfUx9yTfmzRcM NGUbFEYYPL5kIqbF/xm7/xLDAgMBAAGjggF3MIIBczAdBgNVHQ4EFgQU9/+8m8Uw LCsAF4ILSyrtEZ9h4iIwgcYGA1UdIwSBvjCBu4AU9/+8m8UwLCsAF4ILSyrtEZ9h 4iKhgZ+kgZwwgZkxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRz MRIwEAYDVQQHDAlDYW1icmlkZ2UxDDAKBgNVBAoMA01JVDEiMCAGA1UECwwZSW5z ZWN1cmUgS2VyYmVyb3MgdGVzdCBDQTEsMCoGA1UEAwwjdGVzdCBzdWl0ZSBDQTsg ZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0PBAQDAgPoMAwGA1UdEwEB/wQC MAAwWQYDVR0RBFIwUIIWcHJveHnFoHViamVjdMOEbHTDkWFtZYITcHJveHlTdWJq ZWN0QWx0TmFtZYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAAYIJbG9jYWxob3N0MBMG A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQDQI1/zeNAWvXAG CTJk+hFLNx7xzd28/vWGkumK60rSmLVLZNDlvfmNJZ/kd7d0YZFvZDvbzhugXigI 5N54664XreRwXA7QkgD2laFd/Rzq+6NdhyMCno7V6j1VZUm6/FWgfYjfGEBvbGNv Ue50fyRSQBmFv3p87Av/Zc0OMjted0zOYUxUPH0OL+2e4BL/suo05Q5DZq+J8Dni 7SJbDC0fp5mKVLQ500zIRwUF2y5TE4olBsYBoaMDxQl+HoG6XpzaVslTKXAvzFMk 8beI2BmqUId1OSLa3TOKnbsK8K/MPnSnB5StINt1+ZtTjjV+dY3xB6ZC+G1Pl6Ta 00C7EWul -----END CERTIFICATE----- krb5-1.22.1/src/tests/proxy-certs/proxy-subject.pem0000664000175000017500000000634615051422640022123 0ustar ghudsonghudson-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA54HCeTTUe127pqjK8r28NGMw2r2x+hWKKayH5NmqOqnwnzRH kZE5UjkazQ/h97S6LZ6Yb8w3mJEyX1PdcNARDw2mbOPFk5N9uXnBb6AZog7hh9wM e//g9a7PpKanfw69fSVgAr49TFFiLoKuyTgHiJOB7YgP0bTHEO4lLqusPQM16lRD SdoXg42udAh3uBY+QDs23snLSiB+9vt8gt6gXiaYb3BBOWs9B3PKs374N9kOPsgc j+8kyR/M+q+RfK5biqS3ce/sxvPV0Kseh//1uJxlbQCwOiBd3TLWHLhW9F7rzEcv zn1Mfck35s0XDDRlGxRGGDy+ZCKmxf8Zu/8SwwIDAQABAoIBAGxzOBQpsIReQ6Lu HaybP4hXEzLVfIOIBaJCJaMKaJl0tLkP95r0qiKfh7OahiPRMQpf6k8tHrpFApDv q6PGhMdFgLov9YWNqW7y37AYEwn86KAJcHvCQbM2AiXCwGJgGFqA4LpIPlT7JwBc zd6LddQALfSFMcvuYPbIaPi1CUnGy/AAyxGjUrc60KO57NbI+dHSTOwTHO1QjOz9 ESk4fb34beUuZQzR6s/s1N0k09GJyklLpAAblRs5M6w9IlAn781eRLUAHTafLm4b 21J9k2Q2UaOofn0Cvh8ggyJMiYqAJ0CsRy5pJroEyboA51WU+8THNFkNtRX5SxY5 YY3xE7ECgYEA/qkq7BPMkr/SnBPm32G1Eux5eLVd65qbox0oTLodZbusuxutqXTp 1MseDPQtHlrq6CQBizwElx//pdKnIiU9iBS/QkMR9CviitMTt+WrWRrM54/A4CJP AU2Jg7b2DmhW1ombHHiBZ1tWzyiv9zxrtwR8kmKqv9aTOuPn4l7jY5kCgYEA6Llr 47pQjp/YhkBBvlriRwM9RXek++ythgsWvEswORaUalnaZ9gxZOKKas35GLDDuVyT RnEhIqVlTg9iz6x5fXRtm6VzQvy9yFLzPMnlwsiSnRNOfMVIETUTOhNgm45tYY8f lN5bcdY6k6VZ/g/N3zqddnxkjocrd6lAayjjIrsCgYEAyZLYAcPuQx6JM7fhIGIz tQXvZKeS7yITHbq/onQTPuqd4AEZpi9/w0r/v1srt4JZvGR7wF1CeOkAL56dYr69 hNB/T5DNTkvKZv6K9h5aUg6PsJ8uGXuus6ZPOi4BeAgI7IpBd/i+3TQEc7eOCZIO 5PAtNqXY6D6NjajGbH2VWckCgYA2KRDmyrF8v86QT9v9BQGsLSDRTerjhk1L6MC9 yXHLl2mq5oZhrHqyU9aKzKywBlNGjDjqJ+HiQkO1SvdgBW+wtqvbkUGl0VQJjuR0 vTfvgOY+EAQwHWmMN6Hl3iSZjyf9kGV1K9p0P7saKV0sN1leHjIPJRvx35tKGeWY CsfxiQKBgQCVUvsX/HeWyc4bxxMuzw8JniUG2JftZqIC1haHEFNElASjt4hARM7Y X/dkpYPXOZaN+qfvP949rS1WPXRtwMjt7bYzm7MGbXW7OiGGY3LV2CuVmbXJupvr Usvi+YnpqKDY/miOYd+541NJm76AQTSgQ8K7XitX7Beddh1U9e17mg== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIEgjCCA2qgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSIwIAYDVQQLDBlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDDCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x OTExMTIxODMwMzRaFw0zMDEwMjUxODMwMzRaME8xCzAJBgNVBAYTAlVTMRYwFAYD VQQIDA1NYXNzYWNodXNldHRzMRQwEgYDVQQKDAtLUkJURVNULkNPTTESMBAGA1UE AwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA54HC eTTUe127pqjK8r28NGMw2r2x+hWKKayH5NmqOqnwnzRHkZE5UjkazQ/h97S6LZ6Y b8w3mJEyX1PdcNARDw2mbOPFk5N9uXnBb6AZog7hh9wMe//g9a7PpKanfw69fSVg Ar49TFFiLoKuyTgHiJOB7YgP0bTHEO4lLqusPQM16lRDSdoXg42udAh3uBY+QDs2 3snLSiB+9vt8gt6gXiaYb3BBOWs9B3PKs374N9kOPsgcj+8kyR/M+q+RfK5biqS3 ce/sxvPV0Kseh//1uJxlbQCwOiBd3TLWHLhW9F7rzEcvzn1Mfck35s0XDDRlGxRG GDy+ZCKmxf8Zu/8SwwIDAQABo4IBHDCCARgwHQYDVR0OBBYEFPf/vJvFMCwrABeC C0sq7RGfYeIiMIHGBgNVHSMEgb4wgbuAFPf/vJvFMCwrABeCC0sq7RGfYeIioYGf pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVzZXR0czESMBAG A1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxIjAgBgNVBAsMGUluc2VjdXJl IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMMI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMBMG A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQBdg7Gk/RqQpTfD vyFB1GPWRcLYpYW4GQh3e/dcesmwjwT8Nsd4Mzq9mA9TzJIXwffUQ8de85L5+9Oh k4yiwRS3vDCP0fr+GZMpBqkBVunJIHQnm+RWxT42+0kBxxmO/fqp5ztND8gGBLiW QPHb+mSCFgmgwnRuW+UI3TZ965oZfd2oRjjHjr51cgxcXndqnNws/kakMpxSM+KT +ICHNz5og79nC7zpVqu0Cd56stPXbrFeU+bnN5UT9sOZNOYstWZmS8u+ddDuJwhS ijJZgtQNOIuBfD2TLfDmg/QfLeh5hhgBVyXC5o8g6KEtjPgm+44OF3vNZeuwVPaf L58YyPcO -----END CERTIFICATE----- krb5-1.22.1/src/tests/proxy-certs/proxy-ideal.pem0000664000175000017500000000654415051422640021542 0ustar ghudsonghudson-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA54HCeTTUe127pqjK8r28NGMw2r2x+hWKKayH5NmqOqnwnzRH kZE5UjkazQ/h97S6LZ6Yb8w3mJEyX1PdcNARDw2mbOPFk5N9uXnBb6AZog7hh9wM e//g9a7PpKanfw69fSVgAr49TFFiLoKuyTgHiJOB7YgP0bTHEO4lLqusPQM16lRD SdoXg42udAh3uBY+QDs23snLSiB+9vt8gt6gXiaYb3BBOWs9B3PKs374N9kOPsgc j+8kyR/M+q+RfK5biqS3ce/sxvPV0Kseh//1uJxlbQCwOiBd3TLWHLhW9F7rzEcv zn1Mfck35s0XDDRlGxRGGDy+ZCKmxf8Zu/8SwwIDAQABAoIBAGxzOBQpsIReQ6Lu HaybP4hXEzLVfIOIBaJCJaMKaJl0tLkP95r0qiKfh7OahiPRMQpf6k8tHrpFApDv q6PGhMdFgLov9YWNqW7y37AYEwn86KAJcHvCQbM2AiXCwGJgGFqA4LpIPlT7JwBc zd6LddQALfSFMcvuYPbIaPi1CUnGy/AAyxGjUrc60KO57NbI+dHSTOwTHO1QjOz9 ESk4fb34beUuZQzR6s/s1N0k09GJyklLpAAblRs5M6w9IlAn781eRLUAHTafLm4b 21J9k2Q2UaOofn0Cvh8ggyJMiYqAJ0CsRy5pJroEyboA51WU+8THNFkNtRX5SxY5 YY3xE7ECgYEA/qkq7BPMkr/SnBPm32G1Eux5eLVd65qbox0oTLodZbusuxutqXTp 1MseDPQtHlrq6CQBizwElx//pdKnIiU9iBS/QkMR9CviitMTt+WrWRrM54/A4CJP AU2Jg7b2DmhW1ombHHiBZ1tWzyiv9zxrtwR8kmKqv9aTOuPn4l7jY5kCgYEA6Llr 47pQjp/YhkBBvlriRwM9RXek++ythgsWvEswORaUalnaZ9gxZOKKas35GLDDuVyT RnEhIqVlTg9iz6x5fXRtm6VzQvy9yFLzPMnlwsiSnRNOfMVIETUTOhNgm45tYY8f lN5bcdY6k6VZ/g/N3zqddnxkjocrd6lAayjjIrsCgYEAyZLYAcPuQx6JM7fhIGIz tQXvZKeS7yITHbq/onQTPuqd4AEZpi9/w0r/v1srt4JZvGR7wF1CeOkAL56dYr69 hNB/T5DNTkvKZv6K9h5aUg6PsJ8uGXuus6ZPOi4BeAgI7IpBd/i+3TQEc7eOCZIO 5PAtNqXY6D6NjajGbH2VWckCgYA2KRDmyrF8v86QT9v9BQGsLSDRTerjhk1L6MC9 yXHLl2mq5oZhrHqyU9aKzKywBlNGjDjqJ+HiQkO1SvdgBW+wtqvbkUGl0VQJjuR0 vTfvgOY+EAQwHWmMN6Hl3iSZjyf9kGV1K9p0P7saKV0sN1leHjIPJRvx35tKGeWY CsfxiQKBgQCVUvsX/HeWyc4bxxMuzw8JniUG2JftZqIC1haHEFNElASjt4hARM7Y X/dkpYPXOZaN+qfvP949rS1WPXRtwMjt7bYzm7MGbXW7OiGGY3LV2CuVmbXJupvr Usvi+YnpqKDY/miOYd+541NJm76AQTSgQ8K7XitX7Beddh1U9e17mg== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIE3TCCA8WgAwIBAgIBBTANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSIwIAYDVQQLDBlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDDCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x OTExMTIxODMwMzRaFw0zMDEwMjUxODMwMzRaME8xCzAJBgNVBAYTAlVTMRYwFAYD VQQIDA1NYXNzYWNodXNldHRzMRQwEgYDVQQKDAtLUkJURVNULkNPTTESMBAGA1UE AwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA54HC eTTUe127pqjK8r28NGMw2r2x+hWKKayH5NmqOqnwnzRHkZE5UjkazQ/h97S6LZ6Y b8w3mJEyX1PdcNARDw2mbOPFk5N9uXnBb6AZog7hh9wMe//g9a7PpKanfw69fSVg Ar49TFFiLoKuyTgHiJOB7YgP0bTHEO4lLqusPQM16lRDSdoXg42udAh3uBY+QDs2 3snLSiB+9vt8gt6gXiaYb3BBOWs9B3PKs374N9kOPsgcj+8kyR/M+q+RfK5biqS3 ce/sxvPV0Kseh//1uJxlbQCwOiBd3TLWHLhW9F7rzEcvzn1Mfck35s0XDDRlGxRG GDy+ZCKmxf8Zu/8SwwIDAQABo4IBdzCCAXMwHQYDVR0OBBYEFPf/vJvFMCwrABeC C0sq7RGfYeIiMIHGBgNVHSMEgb4wgbuAFPf/vJvFMCwrABeCC0sq7RGfYeIioYGf pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVzZXR0czESMBAG A1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxIjAgBgNVBAsMGUluc2VjdXJl IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMMI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMFkG A1UdEQRSMFCCFnByb3h5xaB1YmplY3TDhGx0w5FhbWWCE3Byb3h5U3ViamVjdEFs dE5hbWWHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9zdDATBgNVHSUE DDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAsMRJnxdbnpm5VlCFwNyU 8ra1wCjj+ZH0POVCM4iXQ77bV6UBpcqlaQUvR7R/H1Bt5t3Cp0ycN/dy+RcXtj+5 FA84bRM767rsakxTEwjOjWw6GiK6bGjBfQ4F6Q97ELmiM0OZgmW8D56UHZxrI+o7 QrKWBpFf1UA8n/BmupHBtyW3gudtJS9a71u6lBRydPFqJ4l8YxHckbgPFceSRbRj x7E2pQVQ0p2nvG/NVyuC+2L29p81KAsG3vPzwOOfr1Tnpl1/B4R0+XEIy33KHpbz Ceyitz6k16fOVNxMI59W2OACPTQ/s99kygh+cARRPfEUPjDcJpS1gRZ6kDKRh6Np ig== -----END CERTIFICATE----- krb5-1.22.1/src/tests/proxy-certs/proxy-badsig.pem0000664000175000017500000000654415051422640021715 0ustar ghudsonghudson-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA54HCeTTUe127pqjK8r28NGMw2r2x+hWKKayH5NmqOqnwnzRH kZE5UjkazQ/h97S6LZ6Yb8w3mJEyX1PdcNARDw2mbOPFk5N9uXnBb6AZog7hh9wM e//g9a7PpKanfw69fSVgAr49TFFiLoKuyTgHiJOB7YgP0bTHEO4lLqusPQM16lRD SdoXg42udAh3uBY+QDs23snLSiB+9vt8gt6gXiaYb3BBOWs9B3PKs374N9kOPsgc j+8kyR/M+q+RfK5biqS3ce/sxvPV0Kseh//1uJxlbQCwOiBd3TLWHLhW9F7rzEcv zn1Mfck35s0XDDRlGxRGGDy+ZCKmxf8Zu/8SwwIDAQABAoIBAGxzOBQpsIReQ6Lu HaybP4hXEzLVfIOIBaJCJaMKaJl0tLkP95r0qiKfh7OahiPRMQpf6k8tHrpFApDv q6PGhMdFgLov9YWNqW7y37AYEwn86KAJcHvCQbM2AiXCwGJgGFqA4LpIPlT7JwBc zd6LddQALfSFMcvuYPbIaPi1CUnGy/AAyxGjUrc60KO57NbI+dHSTOwTHO1QjOz9 ESk4fb34beUuZQzR6s/s1N0k09GJyklLpAAblRs5M6w9IlAn781eRLUAHTafLm4b 21J9k2Q2UaOofn0Cvh8ggyJMiYqAJ0CsRy5pJroEyboA51WU+8THNFkNtRX5SxY5 YY3xE7ECgYEA/qkq7BPMkr/SnBPm32G1Eux5eLVd65qbox0oTLodZbusuxutqXTp 1MseDPQtHlrq6CQBizwElx//pdKnIiU9iBS/QkMR9CviitMTt+WrWRrM54/A4CJP AU2Jg7b2DmhW1ombHHiBZ1tWzyiv9zxrtwR8kmKqv9aTOuPn4l7jY5kCgYEA6Llr 47pQjp/YhkBBvlriRwM9RXek++ythgsWvEswORaUalnaZ9gxZOKKas35GLDDuVyT RnEhIqVlTg9iz6x5fXRtm6VzQvy9yFLzPMnlwsiSnRNOfMVIETUTOhNgm45tYY8f lN5bcdY6k6VZ/g/N3zqddnxkjocrd6lAayjjIrsCgYEAyZLYAcPuQx6JM7fhIGIz tQXvZKeS7yITHbq/onQTPuqd4AEZpi9/w0r/v1srt4JZvGR7wF1CeOkAL56dYr69 hNB/T5DNTkvKZv6K9h5aUg6PsJ8uGXuus6ZPOi4BeAgI7IpBd/i+3TQEc7eOCZIO 5PAtNqXY6D6NjajGbH2VWckCgYA2KRDmyrF8v86QT9v9BQGsLSDRTerjhk1L6MC9 yXHLl2mq5oZhrHqyU9aKzKywBlNGjDjqJ+HiQkO1SvdgBW+wtqvbkUGl0VQJjuR0 vTfvgOY+EAQwHWmMN6Hl3iSZjyf9kGV1K9p0P7saKV0sN1leHjIPJRvx35tKGeWY CsfxiQKBgQCVUvsX/HeWyc4bxxMuzw8JniUG2JftZqIC1haHEFNElASjt4hARM7Y X/dkpYPXOZaN+qfvP949rS1WPXRtwMjt7bYzm7MGbXW7OiGGY3LV2CuVmbXJupvr Usvi+YnpqKDY/miOYd+541NJm76AQTSgQ8K7XitX7Beddh1U9e17mg== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIE3TCCA8WgAwIBAgIBBTANBgkqhkiG9w0BAQsFADCBmTELMAkGA1UEBhMCVVMx FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG A1UECgwDTUlUMSIwIAYDVQQLDBlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww KgYDVQQDDCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x OTExMTIxODMwMzRaFw0zMDEwMjUxODMwMzRaME8xCzAJBgNVBAYTAlVTMRYwFAYD VQQIDA1NYXNzYWNodXNldHRzMRQwEgYDVQQKDAtLUkJURVNULkNPTTESMBAGA1UE AwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA54HC eTTUe127pqjK8r28NGMw2r2x+hWKKayH5NmqOqnwnzRHkZE5UjkazQ/h97S6LZ6Y b8w3mJEyX1PdcNARDw2mbOPFk5N9uXnBb6AZog7hh9wMe//g9a7PpKanfw69fSVg Ar49TFFiLoKuyTgHiJOB7YgP0bTHEO4lLqusPQM16lRDSdoXg42udAh3uBY+QDs2 3snLSiB+9vt8gt6gXiaYb3BBOWs9B3PKs374N9kOPsgcj+8kyR/M+q+RfK5biqS3 ce/sxvPV0Kseh//1uJxlbQCwOiBd3TLWHLhW9F7rzEcvzn1Mfck35s0XDDRlGxRG GDy+ZCKmxf8Zu/8SwwIDAQABo4IBdzCCAXMwHQYDVR0OBBYEFPf/vJvFMCwrABeC C0sq7RGfYeIiMIHGBgNVHSMEgb4wgbuAFPf/vJvFMCwrABeCC0sq7RGfYeIioYGf pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVzZXR0czESMBAG A1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxIjAgBgNVBAsMGUluc2VjdXJl IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMMI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMFkG A1UdEQRSMFCCFnByb3h5xaB1YmplY3TDhGx0w5FhbWWCE3Byb3h5U3ViamVjdEFs dE5hbWWHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9zdDATBgNVHSUE DDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAsMRJnxdbnpm5VlCFwNyU 8ra1wCjj+ZH0POVCM4iXQ77bV6UBpcqlaQUvR7R/H1Bt5t3Cp0ycN/dy+RcXtj+5 FA84bRM767rsakxTEwjOjWw6GiK6bGjBfQ4F6Q97ELmiM0OZgmW8D56UHZxrI+o7 QrKWBpFf1UA8n/BmupHBtyW3gudtJS9a71u6lBRydPFqJ4l8YxHckbgPFceSRbRj x7E2pQVQ0p2nvG/NVyuC+2L29p81KAsG3vPzwOOfr1Tnpl1/B4R0+XEIy33KHpbz Ceyitz6k16fOVNxMI59W2OACPTQ/s99kygh+cARRPfEUAAAAAAAAAAAAAAAAAAAA AA== -----END CERTIFICATE----- krb5-1.22.1/src/tests/t_kadm5_hook.py0000775000175000017500000000100415051422640017206 0ustar ghudsonghudsonfrom k5test import * plugin = os.path.join(buildtop, "plugins", "kadm5_hook", "test", "kadm5_hook_test.so") hook_krb5_conf = {'plugins': {'kadm5_hook': { 'module': 'test:' + plugin}}} realm = K5Realm(krb5_conf=hook_krb5_conf, create_user=False, create_host=False) realm.run([kadminl, 'addprinc', '-randkey', 'test'], expected_msg='create: stage precommit') realm.run([kadminl, 'renprinc', 'test', 'test2'], expected_msg='rename: stage precommit') success('kadm5_hook') krb5-1.22.1/src/tests/t_policy.py0000775000175000017500000002430415051422640016474 0ustar ghudsonghudsonfrom k5test import * import re realm = K5Realm(create_host=False, start_kadmind=True) # Test password quality enforcement. mark('password quality') realm.run([kadminl, 'addpol', '-minlength', '6', '-minclasses', '2', 'pwpol']) realm.run([kadminl, 'addprinc', '-randkey', '-policy', 'pwpol', 'pwuser']) realm.run([kadminl, 'cpw', '-pw', 'sh0rt', 'pwuser'], expected_code=1, expected_msg='Password is too short') realm.run([kadminl, 'cpw', '-pw', 'longenough', 'pwuser'], expected_code=1, expected_msg='Password does not contain enough character classes') realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser']) # Test some password history enforcement. Even with no history value, # the current password should be denied. mark('password history') realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'modpol', '-history', '2', 'pwpol']) realm.run([kadminl, 'cpw', '-pw', 'an0therpw', 'pwuser']) realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser']) realm.run([kadminl, 'cpw', '-pw', 'l0ngenough', 'pwuser']) # Regression test for #929 (kadmind crash with more historical # passwords in a principal entry than current policy history setting). mark('password history (policy value reduced below current array size)') realm.run([kadminl, 'addpol', '-history', '5', 'histpol']) realm.addprinc('histprinc', 'first') realm.run([kadminl, 'modprinc', '-policy', 'histpol', 'histprinc']) realm.run([kadminl, 'cpw', '-pw', 'second', 'histprinc']) realm.run([kadminl, 'cpw', '-pw', 'third', 'histprinc']) realm.run([kadminl, 'cpw', '-pw', 'fourth', 'histprinc']) realm.run([kadminl, 'modpol', '-history', '3', 'histpol']) realm.run([kadminl, 'cpw', '-pw', 'fifth', 'histprinc']) realm.run([kadminl, 'delprinc', 'histprinc']) # Regression test for #2841 (heap buffer overflow when policy history # value is reduced to match the number of historical passwords for a # principal). mark('password history (policy value reduced to current array size)') def histfail(*pwlist): for pw in pwlist: realm.run([kadminl, 'cpw', '-pw', pw, 'histprinc'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'modpol', '-history', '3', 'histpol']) realm.addprinc('histprinc', '1111') realm.run([kadminl, 'modprinc', '-policy', 'histpol', 'histprinc']) realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc']) histfail('2222', '1111') realm.run([kadminl, 'modpol', '-history', '2', 'histpol']) realm.run([kadminl, 'cpw', '-pw', '3333', 'histprinc']) # Test that the history array is properly resized if the policy # history value is increased after the array is filled. mark('password history (policy value increase)') realm.run([kadminl, 'delprinc', 'histprinc']) realm.addprinc('histprinc', '1111') realm.run([kadminl, 'modprinc', '-policy', 'histpol', 'histprinc']) realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc']) histfail('2222', '1111') realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'cpw', '-pw', '1111', 'histprinc'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'modpol', '-history', '3', 'histpol']) realm.run([kadminl, 'cpw', '-pw', '3333', 'histprinc']) histfail('3333', '2222', '1111') realm.run([kadminl, 'modpol', '-history', '4', 'histpol']) histfail('3333', '2222', '1111') realm.run([kadminl, 'cpw', '-pw', '4444', 'histprinc']) histfail('4444', '3333', '2222', '1111') # Test that when the policy history value is reduced, all currently # known old passwords still fail until the next password change, after # which the new number of old passwords fails (but no more). mark('password history (policy value reduction)') realm.run([kadminl, 'modpol', '-history', '3', 'histpol']) histfail('4444', '3333', '2222', '1111') realm.run([kadminl, 'cpw', '-pw', '5555', 'histprinc']) histfail('5555', '3333', '3333') realm.run([kadminl, 'cpw', '-pw', '2222', 'histprinc']) realm.run([kadminl, 'modpol', '-history', '2', 'histpol']) histfail('2222', '5555', '4444') realm.run([kadminl, 'cpw', '-pw', '3333', 'histprinc']) # Test references to nonexistent policies. mark('nonexistent policy references') realm.run([kadminl, 'addprinc', '-randkey', '-policy', 'newpol', 'newuser']) realm.run([kadminl, 'getprinc', 'newuser'], expected_msg='Policy: newpol [does not exist]\n') realm.run([kadminl, 'modprinc', '-policy', 'newpol', 'pwuser']) # pwuser should allow reuse of the current password since newpol doesn't exist. realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser']) # Regression test for #8427 (min_life check with nonexistent policy). realm.run([kadmin, '-p', 'pwuser', '-w', '3rdpassword', 'cpw', '-pw', '3rdpassword', 'pwuser']) # Create newpol and verify that it is enforced. mark('create referenced policy') realm.run([kadminl, 'addpol', '-minlength', '3', 'newpol']) realm.run([kadminl, 'getprinc', 'pwuser'], expected_msg='Policy: newpol\n') realm.run([kadminl, 'cpw', '-pw', 'aa', 'pwuser'], expected_code=1, expected_msg='Password is too short') realm.run([kadminl, 'cpw', '-pw', '3rdpassword', 'pwuser'], expected_code=1, expected_msg='Cannot reuse password') realm.run([kadminl, 'getprinc', 'newuser'], expected_msg='Policy: newpol\n') realm.run([kadminl, 'cpw', '-pw', 'aa', 'newuser'], expected_code=1, expected_msg='Password is too short') # Delete the policy and verify that it is no longer enforced. mark('delete referenced policy') realm.run([kadminl, 'delpol', 'newpol']) realm.run([kadminl, 'getpol', 'newpol'], expected_code=1, expected_msg='Policy does not exist') realm.run([kadminl, 'cpw', '-pw', 'aa', 'pwuser']) # Test basic password lockout support. mark('password lockout') realm.stop() for realm in multidb_realms(create_host=False): realm.run([kadminl, 'addpol', '-maxfailure', '2', '-failurecountinterval', '5m', 'lockout']) realm.run([kadminl, 'modprinc', '+requires_preauth', '-policy', 'lockout', 'user']) # kinit twice with the wrong password. msg = 'Password incorrect while getting initial credentials' realm.run([kinit, realm.user_princ], input='wrong\n', expected_code=1, expected_msg=msg) realm.run([kinit, realm.user_princ], input='wrong\n', expected_code=1, expected_msg=msg) # Now the account should be locked out. msg = 'credentials have been revoked while getting initial credentials' realm.run([kinit, realm.user_princ], expected_code=1, expected_msg=msg) # Check that modprinc -unlock allows a further attempt. realm.run([kadminl, 'modprinc', '-unlock', 'user']) realm.kinit(realm.user_princ, password('user')) # Make sure a nonexistent policy reference doesn't prevent authentication. realm.run([kadminl, 'delpol', 'lockout']) realm.kinit(realm.user_princ, password('user')) # Regression test for issue #7099: databases created prior to krb5 1.3 have # multiple history keys, and kadmin prior to 1.7 didn't necessarily use the # first one to create history entries. mark('#7099 regression test') realm = K5Realm(start_kdc=False) # Create a history principal with two keys. realm.run(['./hist', 'make']) realm.run([kadminl, 'addpol', '-history', '2', 'pol']) realm.run([kadminl, 'modprinc', '-policy', 'pol', 'user']) realm.run([kadminl, 'cpw', '-pw', 'pw2', 'user']) # Swap the keys, simulating older kadmin having chosen the second entry. realm.run(['./hist', 'swap']) # Make sure we can read the history entry. realm.run([kadminl, 'cpw', '-pw', password('user'), 'user'], expected_code=1, expected_msg='Cannot reuse password') mark('Error message for unsupported kadmin/history key type') realm.run(['./hist', 'des']) realm.run([kadminl, 'cpw', '-pw', 'pw', 'user'], expected_code=1, expected_msg='(kadmin/history) contains unsupported key type') # Test key/salt constraints. mark('allowedkeysalts') realm.stop() krb5_conf1 = {'libdefaults': {'supported_enctypes': 'aes256-cts'}} realm = K5Realm(krb5_conf=krb5_conf1, create_host=False, get_creds=False) # Add policy. realm.run([kadminl, 'addpol', '-allowedkeysalts', 'aes256-cts', 'ak']) realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts', 'server']) # Test with one-enctype allowed_keysalts. realm.run([kadminl, 'modprinc', '-policy', 'ak', 'server']) out = realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes128-cts', 'server'], expected_code=1) if not 'Invalid key/salt tuples' in out: fail('allowed_keysalts policy not applied properly') realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts', 'server']) # Now test a multi-enctype allowed_keysalts. Test that subsets are allowed, # the the complete set is allowed, that order doesn't matter, and that # enctypes outside the set are not allowed. # Test modpol. realm.run([kadminl, 'modpol', '-allowedkeysalts', 'aes256-cts,rc4-hmac', 'ak']) realm.run([kadminl, 'getpol', 'ak'], expected_msg='Allowed key/salt types: aes256-cts,rc4-hmac') # Test subsets and full set. realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac', 'server']) realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts', 'server']) realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts,rc4-hmac', 'server']) realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac,aes256-cts', 'server']) # Check that the order we got is the one from the policy. realm.run([kadminl, 'getprinc', '-terse', 'server'], expected_msg='2\t1\t6\t18\t0\t1\t6\t23\t0') # Test partially intersecting sets. realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac,aes128-cts', 'server'], expected_code=1, expected_msg='Invalid key/salt tuples') realm.run([kadminl, 'cpw', '-randkey', '-e', 'rc4-hmac,aes256-cts,aes128-cts', 'server'], expected_code=1, expected_msg='Invalid key/salt tuples') # Test reset of allowedkeysalts. realm.run([kadminl, 'modpol', '-allowedkeysalts', '-', 'ak']) out = realm.run([kadminl, 'getpol', 'ak']) if 'Allowed key/salt types' in out: fail('failed to clear allowedkeysalts') realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes128-cts', 'server']) success('Policy tests') krb5-1.22.1/src/tests/t_cve-2013-1416.py0000775000175000017500000000060315051422640016722 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm() # CVE-2013-1416 KDC dereferences null pointer realm.kinit(realm.user_princ, password('user')) realm.run([kvno, '/test'], expected_code=1) realm.run([kvno, 'test/'], expected_code=1) realm.run([kvno, '/'], expected_code=1) # Make sure KDC is still running. realm.kinit(realm.user_princ, password('user')) success('CVE-2013-1416 regression test') krb5-1.22.1/src/tests/t_preauth.py0000664000175000017500000003150715051422640016645 0ustar ghudsonghudsonfrom k5test import * # Test that the kdcpreauth client_keyblock() callback matches the key # indicated by the etype info, and returns NULL if no key was selected. testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}}} realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf) realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ]) realm.run([kadminl, 'setstr', realm.user_princ, 'teststring', 'testval']) realm.run([kadminl, 'addprinc', '-nokey', '+requires_preauth', 'nokeyuser']) realm.kinit(realm.user_princ, password('user'), expected_msg='testval') realm.kinit('nokeyuser', password('user'), expected_code=1, expected_msg='no key') # Preauth type -123 is the test preauth module type; 133 is FAST # PA-FX-COOKIE; 2 is encrypted timestamp. # Test normal preauth flow. mark('normal') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 'Decrypted AS reply') realm.run(['./icred', realm.user_princ, password('user')], expected_msg='testval', expected_trace=msgs) # Test successful optimistic preauth. mark('optimistic') expected_trace = ('Attempting optimistic preauth', 'Processing preauth types: -123', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: -123', 'Decrypted AS reply') realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], expected_trace=expected_trace) # Test optimistic preauth failing on client, falling back to encrypted # timestamp. mark('optimistic (client failure)') msgs = ('Attempting optimistic preauth', 'Processing preauth types: -123', '/induced optimistic fail', 'Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Encrypted timestamp (for ', 'module encrypted_timestamp (2) (real) returned: 0/Success', 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 'Decrypted AS reply') realm.run(['./icred', '-o', '-123', '-X', 'fail_optimistic', realm.user_princ, password('user')], expected_trace=msgs) # Test optimistic preauth failing on KDC, falling back to encrypted # timestamp. mark('optimistic (KDC failure)') realm.run([kadminl, 'setstr', realm.user_princ, 'failopt', 'yes']) msgs = ('Attempting optimistic preauth', 'Processing preauth types: -123', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: -123', '/Preauthentication failed', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Encrypted timestamp (for ', 'module encrypted_timestamp (2) (real) returned: 0/Success', 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 'Decrypted AS reply') realm.run(['./icred', '-o', '-123', realm.user_princ, password('user')], expected_trace=msgs) # Leave failopt set for the next test. # Test optimistic preauth failing on KDC, stopping because the test # module disabled fallback. mark('optimistic (KDC failure, no fallback)') msgs = ('Attempting optimistic preauth', 'Processing preauth types: -123', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: -123', '/Preauthentication failed') realm.run(['./icred', '-X', 'disable_fallback', '-o', '-123', realm.user_princ, password('user')], expected_code=1, expected_msg='Preauthentication failed', expected_trace=msgs) realm.run([kadminl, 'delstr', realm.user_princ, 'failopt']) # Test KDC_ERR_MORE_PREAUTH_DATA_REQUIRED and secure cookies. mark('second round-trip') realm.run([kadminl, 'setstr', realm.user_princ, '2rt', 'secondtrip']) msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/More preauthentication data is required', 'Continuing preauth mech -123', 'Processing preauth types: -123, PA-FX-COOKIE (133)', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', 'Decrypted AS reply') realm.run(['./icred', realm.user_princ, password('user')], expected_msg='2rt: secondtrip', expected_trace=msgs) # Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # falling back to encrypted timestamp. mark('second round-trip (client failure)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/More preauthentication data is required', 'Continuing preauth mech -123', 'Processing preauth types: -123, PA-FX-COOKIE (133)', '/induced 2rt fail', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Encrypted timestamp (for ', 'module encrypted_timestamp (2) (real) returned: 0/Success', 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 'Decrypted AS reply') realm.run(['./icred', '-X', 'fail_2rt', realm.user_princ, password('user')], expected_msg='2rt: secondtrip', expected_trace=msgs) # Test client-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # stopping because the test module disabled fallback. mark('second round-trip (client failure, no fallback)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/More preauthentication data is required', 'Continuing preauth mech -123', 'Processing preauth types: -123, PA-FX-COOKIE (133)', '/induced 2rt fail') realm.run(['./icred', '-X', 'fail_2rt', '-X', 'disable_fallback', realm.user_princ, password('user')], expected_code=1, expected_msg='Pre-authentication failed: induced 2rt fail', expected_trace=msgs) # Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # falling back to encrypted timestamp. mark('second round-trip (KDC failure)') realm.run([kadminl, 'setstr', realm.user_princ, 'fail2rt', 'yes']) msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/More preauthentication data is required', 'Continuing preauth mech -123', 'Processing preauth types: -123, PA-FX-COOKIE (133)', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/Preauthentication failed', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Encrypted timestamp (for ', 'module encrypted_timestamp (2) (real) returned: 0/Success', 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 'Decrypted AS reply') realm.run(['./icred', realm.user_princ, password('user')], expected_msg='2rt: secondtrip', expected_trace=msgs) # Leave fail2rt set for the next test. # Test KDC-side failure after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, # stopping because the test module disabled fallback. mark('second round-trip (KDC failure, no fallback)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/More preauthentication data is required', 'Continuing preauth mech -123', 'Processing preauth types: -123, PA-FX-COOKIE (133)', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/Preauthentication failed') realm.run(['./icred', '-X', 'disable_fallback', realm.user_princ, password('user')], expected_code=1, expected_msg='Preauthentication failed', expected_trace=msgs) realm.run([kadminl, 'delstr', realm.user_princ, 'fail2rt']) # Test tryagain flow by inducing a KDC_ERR_ENCTYPE_NOSUPP error on the KDC. mark('tryagain') realm.run([kadminl, 'setstr', realm.user_princ, 'err', 'testagain']) msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/KDC has no support for encryption type', 'Recovering from KDC error 14 using preauth mech -123', 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)', 'Preauth module test (-123) tryagain returned: 0/Success', 'Followup preauth for next request: -123, PA-FX-COOKIE (133)', 'Decrypted AS reply') realm.run(['./icred', realm.user_princ, password('user')], expected_msg='tryagain: testagain', expected_trace=msgs) # Test a client-side tryagain failure, falling back to encrypted # timestamp. mark('tryagain (client failure)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/KDC has no support for encryption type', 'Recovering from KDC error 14 using preauth mech -123', 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)', '/induced tryagain fail', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Encrypted timestamp (for ', 'module encrypted_timestamp (2) (real) returned: 0/Success', 'preauth for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 'Decrypted AS reply') realm.run(['./icred', '-X', 'fail_tryagain', realm.user_princ, password('user')], expected_trace=msgs) # Test a client-side tryagain failure, stopping because the test # module disabled fallback. mark('tryagain (client failure, no fallback)') msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Preauthenticating using KDC method data', 'Processing preauth types:', 'Preauth module test (-123) (real) returned: 0/Success', 'Produced preauth for next request: PA-FX-COOKIE (133), -123', '/KDC has no support for encryption type', 'Recovering from KDC error 14 using preauth mech -123', 'Preauth tryagain input types (-123): -123, PA-FX-COOKIE (133)', '/induced tryagain fail') realm.run(['./icred', '-X', 'fail_tryagain', '-X', 'disable_fallback', realm.user_princ, password('user')], expected_code=1, expected_msg='KDC has no support for encryption type', expected_trace=msgs) # Test that multiple stepwise initial creds operations can be # performed with the same krb5_context, with proper tracking of # clpreauth module request handles. mark('interleaved') realm.run([kadminl, 'addprinc', '-pw', 'pw', 'u1']) realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u2']) realm.run([kadminl, 'addprinc', '+requires_preauth', '-pw', 'pw', 'u3']) realm.run([kadminl, 'setstr', 'u2', '2rt', 'extra']) out = realm.run(['./icinterleave', 'pw', 'u1', 'u2', 'u3']) if out != ('step 1\nstep 2\nstep 3\nstep 1\nfinish 1\nstep 2\nno attr\n' 'step 3\nno attr\nstep 2\n2rt: extra\nstep 3\nfinish 3\nstep 2\n' 'finish 2\n'): fail('unexpected output from icinterleave') success('Pre-authentication framework tests') krb5-1.22.1/src/tests/t_keytab.py0000775000175000017500000001760515051422640016462 0ustar ghudsonghudsonfrom k5test import * for realm in multipass_realms(create_user=False): # Test kinit with a keytab. realm.kinit(realm.host_princ, flags=['-k']) realm = K5Realm(get_creds=False, start_kadmind=True) # Test kinit with a partial keytab. mark('partial keytab') pkeytab = realm.keytab + '.partial' realm.run([ktutil], input=('rkt %s\ndelent 1\nwkt %s\n' % (realm.keytab, pkeytab))) realm.kinit(realm.host_princ, flags=['-k', '-t', pkeytab]) # Test kinit with no keys for client in keytab. mark('no keys for client') realm.kinit(realm.user_princ, flags=['-k'], expected_code=1, expected_msg='no suitable keys') # Test kinit and klist with client keytab defaults. mark('client keytab') realm.extract_keytab(realm.user_princ, realm.client_keytab); realm.run([kinit, '-k', '-i']) realm.klist(realm.user_princ) realm.run([kdestroy]) realm.kinit(realm.user_princ, flags=['-k', '-i']) realm.klist(realm.user_princ) out = realm.run([klist, '-k', '-i']) if realm.client_keytab not in out or realm.user_princ not in out: fail('Expected output not seen from klist -k -i') # Test implicit request for keytab (-i or -t without -k) mark('implicit -k') realm.run([kdestroy]) realm.kinit(realm.host_princ, flags=['-t', realm.keytab], expected_msg='keytab specified, forcing -k') realm.klist(realm.host_princ) realm.run([kdestroy]) realm.kinit(realm.user_princ, flags=['-i'], expected_msg='keytab specified, forcing -k') realm.klist(realm.user_princ) # Test default principal for -k. This operation requires # canonicalization against the keytab in krb5_get_init_creds_keytab() # as the krb5_sname_to_principal() result won't have a realm. Try # with and without without fallback processing since the code paths # are different. mark('default principal for -k') realm.run([kinit, '-k']) realm.klist(realm.host_princ) no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}} no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf) realm.run([kinit, '-k'], env=no_canon) realm.klist(realm.host_princ) # Test extracting keys with multiple key versions present. mark('multi-kvno extract') os.remove(realm.keytab) realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.host_princ]) out = realm.run([kadminl, 'ktadd', '-norandkey', realm.host_princ]) if 'with kvno 1,' not in out or 'with kvno 2,' not in out: fail('Expected output not seen from kadmin.local ktadd -norandkey') out = realm.run([klist, '-k', '-e']) if ' 1 host/' not in out or ' 2 host/' not in out: fail('Expected output not seen from klist -k -e') # Test again using kadmin over the network. mark('multi-kvno extract (via kadmin)') realm.prep_kadmin() os.remove(realm.keytab) out = realm.run_kadmin(['ktadd', '-norandkey', realm.host_princ]) if 'with kvno 1,' not in out or 'with kvno 2,' not in out: fail('Expected output not seen from kadmin.local ktadd -norandkey') out = realm.run([klist, '-k', '-e']) if ' 1 host/' not in out or ' 2 host/' not in out: fail('Expected output not seen from klist -k -e') # Test handling of kvno values beyond 255. Use kadmin over the # network since we used to have an 8-bit limit on kvno marshalling. # Test one key rotation, verifying that the expected new kvno appears # in the keytab and in the principal entry. def test_key_rotate(realm, princ, expected_kvno): realm.run_kadmin(['ktadd', '-k', realm.keytab, princ]) realm.run([kadminl, 'ktrem', princ, 'old']) realm.kinit(princ, flags=['-k']) msg = '%d %s' % (expected_kvno, princ) out = realm.run([klist, '-k'], expected_msg=msg) msg = 'Key: vno %d,' % expected_kvno out = realm.run_kadmin(['getprinc', princ], expected_msg=msg) mark('key rotation across boundaries') princ = 'foo/bar@%s' % realm.realm realm.addprinc(princ) os.remove(realm.keytab) realm.run([kadminl, 'modprinc', '-kvno', '253', princ]) test_key_rotate(realm, princ, 254) test_key_rotate(realm, princ, 255) test_key_rotate(realm, princ, 256) test_key_rotate(realm, princ, 257) realm.run([kadminl, 'modprinc', '-kvno', '32766', princ]) test_key_rotate(realm, princ, 32767) test_key_rotate(realm, princ, 32768) test_key_rotate(realm, princ, 32769) realm.run([kadminl, 'modprinc', '-kvno', '65534', princ]) test_key_rotate(realm, princ, 65535) test_key_rotate(realm, princ, 1) test_key_rotate(realm, princ, 2) mark('32-bit kvno') # Test that klist -k can read a keytab entry without a 32-bit kvno and # reports the 8-bit key version. record = b'\x00\x01' # principal component count record += b'\x00\x0bKRBTEST.COM' # realm record += b'\x00\x04user' # principal component record += b'\x00\x00\x00\x01' # name type (NT-PRINCIPAL) record += b'\x54\xf7\x4d\x35' # timestamp record += b'\x02' # key version record += b'\x00\x12' # enctype record += b'\x00\x20' # key length record += b'\x00' * 32 # key bytes f = open(realm.keytab, 'wb') f.write(b'\x05\x02\x00\x00\x00' + bytes([len(record)])) f.write(record) f.close() msg = ' 2 %s' % realm.user_princ out = realm.run([klist, '-k'], expected_msg=msg) # Make sure zero-fill isn't treated as a 32-bit kvno. f = open(realm.keytab, 'wb') f.write(b'\x05\x02\x00\x00\x00' + bytes([len(record) + 4])) f.write(record) f.write(b'\x00\x00\x00\x00') f.close() msg = ' 2 %s' % realm.user_princ out = realm.run([klist, '-k'], expected_msg=msg) # Make sure a hand-crafted 32-bit kvno is recognized. f = open(realm.keytab, 'wb') f.write(b'\x05\x02\x00\x00\x00' + bytes([len(record) + 4])) f.write(record) f.write(b'\x00\x00\x00\x03') f.close() msg = ' 3 %s' % realm.user_princ out = realm.run([klist, '-k'], expected_msg=msg) # Test parameter expansion in profile variables mark('parameter expansion') realm.stop() conf = {'libdefaults': { 'default_keytab_name': 'testdir/%{null}abc%{uid}', 'default_client_keytab_name': 'testdir/%{null}xyz%{uid}'}} realm = K5Realm(krb5_conf=conf, create_kdb=False) del realm.env['KRB5_KTNAME'] del realm.env['KRB5_CLIENT_KTNAME'] uidstr = str(os.getuid()) msg = 'FILE:testdir/abc%s' % uidstr out = realm.run([klist, '-k'], expected_code=1, expected_msg=msg) msg = 'FILE:testdir/xyz%s' % uidstr out = realm.run([klist, '-ki'], expected_code=1, expected_msg=msg) conf = {'libdefaults': {'allow_weak_crypto': 'true'}} realm = K5Realm(create_user=False, create_host=False, krb5_conf=conf) realm.run([kadminl, 'ank', '-pw', 'pw', 'default']) realm.run([kadminl, 'ank', '-e', 'aes256-cts:special', '-pw', 'pw', 'exp']) realm.run([kadminl, 'ank', '-e', 'aes256-cts:special', '-pw', 'pw', '+preauth', 'pexp']) # Extract one of the explicit salt values from the database. out = realm.run([kdb5_util, 'tabdump', 'keyinfo']) salt_dict = {f[0]: f[5] for f in [l.split('\t') for l in out.splitlines()]} exp_salt = bytes.fromhex(salt_dict['exp@KRBTEST.COM']).decode('ascii') # Create a keytab using ktutil addent with the specified options and # password "pw". Test that we can use it to get initial tickets. # Remove the keytab afterwards. def test_addent(realm, princ, opts): realm.run([ktutil], input=('addent -password -p %s -k 1 %s\npw\nwkt %s\n' % (princ, opts, realm.keytab))) realm.kinit(princ, flags=['-k']) os.remove(realm.keytab) mark('ktutil addent') # Test with default salt. test_addent(realm, 'default', '-e aes128-cts') test_addent(realm, 'default', '-e aes256-cts') # Test with a salt specified to ktutil addent. test_addent(realm, 'exp', '-e aes256-cts -s %s' % exp_salt) # Test etype-info fetching. test_addent(realm, 'default', '-f') test_addent(realm, 'default', '-f -e aes128-cts') test_addent(realm, 'exp', '-f') test_addent(realm, 'pexp', '-f') # Regression test for #8914: INT32_MIN length can cause backwards seek mark('invalid record length') f = open(realm.keytab, 'wb') f.write(b'\x05\x02\x80\x00\x00\x00') f.close() msg = 'Bad format in keytab while scanning keytab' realm.run([klist, '-k'], expected_code=1, expected_msg=msg) success('Keytab-related tests') krb5-1.22.1/src/tests/t_certauth.py0000664000175000017500000000551715051422640017016 0ustar ghudsonghudsonfrom k5test import * # Skip this test if pkinit wasn't built. if not pkinit_enabled: skip_rest('certauth tests', 'PKINIT module not built') modpath = os.path.join(buildtop, 'plugins', 'certauth', 'test', 'certauth_test.so') krb5_conf = {'plugins': {'certauth': { 'module': ['test1:' + modpath, 'test2:' + modpath, 'test3:' + modpath], 'enable_only': ['test1', 'test2', 'test3']}}} kdc_conf = {'realms': {'$realm': { 'default_principal_flags': '+preauth', 'pkinit_indicator': ['indpkinit1', 'indpkinit2']}}} realm = K5Realm(krb5_conf=krb5_conf, kdc_conf=kdc_conf, get_creds=False, pkinit=True) realm.addprinc('nocert') def check_indicators(inds): msg = '+97: [%s]' % inds realm.run(['./adata', realm.host_princ], expected_msg=msg) # Test that authentication fails if no module accepts. realm.pkinit('nocert', expected_code=1, expected_msg='Client name mismatch') # Let the test2 module match user to CN=user, with indicators. realm.pkinit(realm.user_princ) realm.klist(realm.user_princ) check_indicators('test1, test2, user, indpkinit1, indpkinit2') # Let the test2 module mismatch with user2 to CN=user. realm.addprinc('user2@KRBTEST.COM') realm.pkinit('user2', expected_code=1, expected_msg='Certificate mismatch') # Test the KRB5_CERTAUTH_HWAUTH return code. mark('hw-authent flag tests') # First test +requires_hwauth without causing the hw-authent ticket # flag to be set. This currently results in a preauth loop. realm.run([kadminl, 'modprinc', '+requires_hwauth', realm.user_princ]) realm.pkinit(realm.user_princ, expected_code=1, expected_msg='Looping detected') # Cause the test3 module to return KRB5_CERTAUTH_HWAUTH and try again. # Authentication should succeed whether or not another module accepts, # but not if another module rejects. realm.run([kadminl, 'setstr', realm.user_princ, 'hwauth', 'ok']) realm.run([kadminl, 'setstr', 'user2', 'hwauth', 'ok']) realm.run([kadminl, 'setstr', 'nocert', 'hwauth', 'ok']) realm.pkinit(realm.user_princ) check_indicators('test1, test2, user, hwauth:ok, indpkinit1, indpkinit2') realm.pkinit('user2', expected_code=1, expected_msg='Certificate mismatch') realm.pkinit('nocert') check_indicators('test1, hwauth:ok, indpkinit1, indpkinit2') # Cause the test3 module to return KRB5_CERTAUTH_HWAUTH_PASS and try # again. Authentication should succeed only if another module accepts. realm.run([kadminl, 'setstr', realm.user_princ, 'hwauth', 'pass']) realm.run([kadminl, 'setstr', 'user2', 'hwauth', 'pass']) realm.run([kadminl, 'setstr', 'nocert', 'hwauth', 'pass']) realm.pkinit(realm.user_princ) check_indicators('test1, test2, user, hwauth:pass, indpkinit1, indpkinit2') realm.pkinit('user2', expected_code=1, expected_msg='Certificate mismatch') realm.pkinit('nocert', expected_code=1, expected_msg='Client name mismatch') success("certauth tests") krb5-1.22.1/src/tests/t_referral.py0000775000175000017500000001421315051422640016775 0ustar ghudsonghudsonfrom k5test import * # Create a pair of realms, where KRBTEST1.COM can authenticate to # REFREALM and has a domain-realm mapping for 'd' pointing to it. drealm = {'domain_realm': {'d': 'REFREALM'}} realm, refrealm = cross_realms(2, xtgts=((0,1),), args=({'kdc_conf': drealm}, {'realm': 'REFREALM', 'create_user': False}), create_host=False) refrealm.addprinc('a/x.d') savefile = os.path.join(realm.testdir, 'ccache.copy') os.rename(realm.ccache, savefile) # Get credentials and check that we got a referral to REFREALM. def testref(realm, nametype): shutil.copyfile(savefile, realm.ccache) realm.run(['./gcred', nametype, 'a/x.d@']) out = realm.run([klist]).split('\n') if len(out) != 8: fail('unexpected number of lines in klist output') if out[5].split()[4] != 'a/x.d@' or out[6].split()[2] != 'a/x.d@REFREALM': fail('unexpected service principals in klist output') # Get credentials and check that we get an error, not a referral. def testfail(realm, nametype): shutil.copyfile(savefile, realm.ccache) realm.run(['./gcred', nametype, 'a/x.d@'], expected_code=1, expected_msg='not found in Kerberos database') # Create a modified KDC environment and restart the KDC. def restart_kdc(realm, kdc_conf): env = realm.special_env('extravars', True, kdc_conf=kdc_conf) realm.stop_kdc() realm.start_kdc(env=env) # With no KDC configuration besides [domain_realm], we should get a # referral for a NT-SRV-HST or NT-SRV-INST server name, but not an # NT-UNKNOWN or NT-PRINCIPAL server name. mark('[domain-realm] only') testref(realm, 'srv-hst') testref(realm, 'srv-inst') testfail(realm, 'principal') testfail(realm, 'unknown') # With host_based_services matching the first server name component # ("a"), we should get a referral for an NT-UNKNOWN server name. # host_based_services can appear in either [kdcdefaults] or the realm # section, with the realm values supplementing the kdcdefaults values. # NT-SRV-HST server names should be unaffected by host_based_services, # and NT-PRINCIPAL server names shouldn't get a referral regardless. mark('host_based_services') restart_kdc(realm, {'kdcdefaults': {'host_based_services': '*'}}) testref(realm, 'unknown') testfail(realm, 'principal') restart_kdc(realm, {'kdcdefaults': {'host_based_services': ['b', 'a,c']}}) testref(realm, 'unknown') restart_kdc(realm, {'realms': {'$realm': {'host_based_services': 'a b c'}}}) testref(realm, 'unknown') restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'a'}, 'realms': {'$realm': {'host_based_services': 'b c'}}}) testref(realm, 'unknown') restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'b,c'}, 'realms': {'$realm': {'host_based_services': 'a,b'}}}) testref(realm, 'unknown') restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'b,c'}}) testfail(realm, 'unknown') testref(realm, 'srv-hst') # With no_host_referrals matching the first server name component, we # should not get a referral even for NT-SRV-HOST server names mark('no_host_referral') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': '*'}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': ['b', 'a,c']}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'realms': {'$realm': {'no_host_referral': 'a b c'}}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'a'}, 'realms': {'$realm': {'no_host_referral': 'b c'}}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'b,c'}, 'realms': {'$realm': {'no_host_referral': 'a,b'}}}) testfail(realm, 'srv-hst') restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'b,c'}}) testref(realm, 'srv-hst') # no_host_referrals should override host_based_services for NT-UNKNWON # server names. restart_kdc(realm, {'kdcdefaults': {'no_host_referral': '*', 'host_based_services': '*'}}) testfail(realm, 'unknown') realm.stop() refrealm.stop() # Regression test for #7483: a KDC should not return a host referral # to its own realm. mark('#7483 regression test') drealm = {'domain_realm': {'d': 'KRBTEST.COM'}} realm = K5Realm(kdc_conf=drealm, create_host=False) out, trace = realm.run(['./gcred', 'srv-hst', 'a/x.d@'], expected_code=1, return_trace=True) if 'back to same realm' in trace: fail('KDC returned referral to service realm') realm.stop() # Test client referrals. Use the test KDB module for KRBTEST1.COM to # simulate referrals since our built-in modules do not support them. # No cross-realm TGTs are necessary. mark('client referrals') kdcconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'alias': {'user': '@KRBTEST2.COM', 'abc@XYZ': '@KRBTEST2.COM'}}}} r1, r2 = cross_realms(2, xtgts=(), args=({'kdc_conf': kdcconf, 'create_kdb': False}, None), create_host=False) r2.addprinc('abc\\@XYZ', 'pw') r1.start_kdc() r1.kinit('user', expected_code=1, expected_msg='not found in Kerberos database') r1.kinit('user', password('user'), ['-C']) r1.klist('user@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM') r1.kinit('abc@XYZ', 'pw', ['-E']) r1.klist('abc\\@XYZ@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM') # Test that disable_encrypted_timestamp persists across client # referrals. (This test relies on SPAKE not being enabled by default # on the KDC.) r2.run([kadminl, 'modprinc', '+preauth', 'user']) msgs = ('Encrypted timestamp (for ') r1.kinit('user', password('user'), ['-C'], expected_trace=msgs) dconf = {'realms': {'$realm': {'disable_encrypted_timestamp': 'true'}}} denv = r1.special_env('disable_encts', False, krb5_conf=dconf) msgs = ('Ignoring encrypted timestamp because it is disabled', '/Encrypted timestamp is disabled') r1.kinit('user', None, ['-C'], env=denv, expected_code=1, expected_trace=msgs, expected_msg='Encrypted timestamp is disabled') success('KDC host referral tests') krb5-1.22.1/src/tests/jsonwalker.py0000664000175000017500000000623015051422640017024 0ustar ghudsonghudsonimport sys import json from collections import defaultdict from optparse import OptionParser class Parser(object): DEFAULTS = {int:0, str:'', list:[]} def __init__(self, defconf=None): self.defaults = None if defconf is not None: self.defaults = self.flatten(defconf) def run(self, logs, verbose=None): result = self.parse(logs) if len(result) != len(self.defaults): diff = set(self.defaults.keys()).difference(result.keys()) print('Test failed.') print('The following attributes were not set:') for it in diff: print(it) sys.exit(1) def flatten(self, defaults): """ Flattens paths to attributes. Parameters ---------- defaults : a dictionaries populated with default values Returns : dict : with flattened attributes """ result = dict() for path,value in self._walk(defaults): if path in result: print('Warning: attribute path %s already exists' % path) result[path] = value return result def parse(self, logs): result = defaultdict(list) for msg in logs: # each message is treated as a dictionary of dictionaries for a,v in self._walk(msg): # see if path is registered in defaults if a in self.defaults: dv = self.defaults.get(a) if dv is None: # determine default value by type if v is not None: dv = self.DEFAULTS[type(v)] else: print('Warning: attribute %s is set to None' % a) continue # by now we have default value if v != dv: # test passed result[a].append(v) return result def _walk(self, adict): """ Generator that works through dictionary. """ for a,v in adict.items(): if isinstance(v,dict): for (attrpath,u) in self._walk(v): yield (a+'.'+attrpath,u) else: yield (a,v) if __name__ == '__main__': parser = OptionParser() parser.add_option("-i", "--logfile", dest="filename", help="input log file in json fmt", metavar="FILE") parser.add_option("-d", "--defaults", dest="defaults", help="dictionary with defaults", metavar="FILE") (options, args) = parser.parse_args() if options.filename is not None: with open(options.filename, 'r') as f: content = list() for l in f: content.append(json.loads(l.rstrip())) f.close() else: print('Input file in JSON format is required') exit() defaults = None if options.defaults is not None: with open(options.defaults, 'r') as f: defaults = json.load(f) # run test p = Parser(defaults) p.run(content) exit() krb5-1.22.1/src/tests/t_ccache.py0000775000175000017500000002144315051422640016404 0ustar ghudsonghudson# Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * import tempfile socketdir = tempfile.TemporaryDirectory() kcm_socket_path = os.path.join(socketdir.name, 'kcm') conf = {'libdefaults': {'kcm_socket': kcm_socket_path, 'kcm_mach_service': '-'}} realm = K5Realm(krb5_conf=conf) realm.addprinc('contest') realm.extract_keytab('contest', realm.keytab) realm.run(['./conccache', realm.ccache + '.contest', 'contest', realm.host_princ]) keyctl = which('keyctl') out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1) test_keyring = (keyctl is not None and 'Unknown credential cache type' not in out) if not test_keyring: skipped('keyring ccache tests', 'keyring support not built') # Test kdestroy and klist of a non-existent ccache. mark('no ccache') realm.run([kdestroy]) realm.run([klist], expected_code=1, expected_msg='No credentials cache found') # Test kinit with an inaccessible ccache. mark('inaccessible ccache') realm.kinit(realm.user_princ, password('user'), flags=['-c', 'testdir/xx/yy'], expected_code=1, expected_msg='Failed to store credentials') # Test klist -s with a single ccache. mark('klist -s single ccache') realm.run([klist, '-s'], expected_code=1) realm.kinit(realm.user_princ, password('user')) realm.run([klist, '-s']) realm.kinit(realm.user_princ, password('user'), ['-l', '-10s']) realm.run([klist, '-s'], expected_code=1) realm.kinit(realm.user_princ, password('user'), ['-S', 'kadmin/admin']) realm.run([klist, '-s']) realm.run([kdestroy]) realm.run([klist, '-s'], expected_code=1) realm.addprinc('alice', password('alice')) realm.addprinc('bob', password('bob')) realm.addprinc('carol', password('carol')) realm.addprinc('doug', password('doug')) def collection_test(realm, ccname): cctype = ccname.partition(':')[0] oldccname = realm.env['KRB5CCNAME'] realm.env['KRB5CCNAME'] = ccname mark('%s collection, single cache' % cctype) realm.run([klist, '-A', '-s'], expected_code=1) realm.kinit('alice', password('alice')) realm.run([klist], expected_msg='Default principal: alice@') realm.run([klist, '-A', '-s']) realm.run([kvno, realm.host_princ], expected_msg = 'kvno = 1') realm.run([kvno, realm.host_princ], expected_msg = 'kvno = 1') out = realm.run([klist]) if out.count(realm.host_princ) != 1: fail('Wrong number of service tickets in cache') realm.run([kdestroy]) output = realm.run([klist], expected_code=1) if 'No credentials cache' not in output and 'not found' not in output: fail('Initial kdestroy failed to destroy primary cache.') output = realm.run([klist, '-l'], expected_code=1) if not output.endswith('---\n') or output.count('\n') != 2: fail('Initial kdestroy failed to empty cache collection.') realm.run([klist, '-A', '-s'], expected_code=1) mark('%s collection, multiple caches' % cctype) realm.kinit('alice', password('alice')) realm.kinit('carol', password('carol')) output = realm.run([klist, '-l']) if '---\ncarol@' not in output or '\nalice@' not in output: fail('klist -l did not show expected output after two kinits.') realm.kinit('alice', password('alice')) output = realm.run([klist, '-l']) if '---\nalice@' not in output or output.count('\n') != 4: fail('klist -l did not show expected output after re-kinit for alice.') realm.kinit('doug', password('doug')) realm.kinit('bob', password('bob')) output = realm.run([klist, '-A', ccname]) if 'bob@' not in output.splitlines()[1] or 'alice@' not in output or \ 'carol@' not in output or 'doug@' not in output or \ output.count('Default principal:') != 4: fail('klist -A did not show expected output after kinit doug+bob.') realm.run([kswitch, '-p', 'carol']) output = realm.run([klist, '-l']) if '---\ncarol@' not in output or output.count('\n') != 6: fail('klist -l did not show expected output after kswitch to carol.') # Switch to specifying the collection name on the command line # (only works with klist/kdestroy for now, not kinit/kswitch). realm.env['KRB5CCNAME'] = oldccname mark('%s collection, command-line specifier' % cctype) realm.run([kdestroy, '-c', ccname]) output = realm.run([klist, '-l', ccname]) if 'carol@' in output or 'bob@' not in output or output.count('\n') != 5: fail('kdestroy failed to remove only primary ccache.') realm.run([klist, '-s', ccname], expected_code=1) realm.run([klist, '-A', '-s', ccname]) realm.run([kdestroy, '-p', 'alice', '-c', ccname]) output = realm.run([klist, '-l', ccname]) if 'alice@' in output or 'bob@' not in output or output.count('\n') != 4: fail('kdestroy -p failed to remove alice') realm.run([kdestroy, '-A', '-c', ccname]) output = realm.run([klist, '-l', ccname], expected_code=1) if not output.endswith('---\n') or output.count('\n') != 2: fail('kdestroy -a failed to empty cache collection.') realm.run([klist, '-A', '-s', ccname], expected_code=1) collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc')) # Test KCM with and without RETRIEVE and GET_CRED_LIST support. kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py') kcmd = realm.start_server([sys.executable, kcmserver_path, kcm_socket_path], 'starting...') collection_test(realm, 'KCM:') stop_daemon(kcmd) os.remove(kcm_socket_path) realm.start_server([sys.executable, kcmserver_path, '-f', kcm_socket_path], 'starting...') collection_test(realm, 'KCM:') if test_keyring: def cleanup_keyring(anchor, name): out = realm.run(['keyctl', 'list', anchor]) if ('keyring: ' + name + '\n') in out: keyid = realm.run(['keyctl', 'search', anchor, 'keyring', name]) realm.run(['keyctl', 'unlink', keyid.strip(), anchor]) # Use realm.testdir as the collection name to avoid conflicts with # other build trees. cname = realm.testdir col_ringname = '_krb_' + cname cleanup_keyring('@s', col_ringname) collection_test(realm, 'KEYRING:session:' + cname) cleanup_keyring('@s', col_ringname) # Test legacy keyring cache linkage. mark('legacy keyring cache linkage') realm.env['KRB5CCNAME'] = 'KEYRING:' + cname realm.run([kdestroy, '-A']) realm.kinit(realm.user_princ, password('user')) msg = 'KEYRING:legacy:' + cname + ':' + cname realm.run([klist, '-l'], expected_msg=msg) # Make sure this cache is linked to the session keyring. id = realm.run([keyctl, 'search', '@s', 'keyring', cname]) realm.run([keyctl, 'list', id.strip()], expected_msg='user: __krb5_princ__') # Remove the collection keyring. When the collection is # reinitialized, the legacy cache should reappear inside it # automatically as the primary cache. cleanup_keyring('@s', col_ringname) realm.run([klist], expected_msg=realm.user_princ) coll_id = realm.run([keyctl, 'search', '@s', 'keyring', '_krb_' + cname]) msg = id.strip() + ':' realm.run([keyctl, 'list', coll_id.strip()], expected_msg=msg) # Destroy the cache and check that it is unlinked from the session keyring. realm.run([kdestroy]) realm.run([keyctl, 'search', '@s', 'keyring', cname], expected_code=1) cleanup_keyring('@s', col_ringname) # Test parameter expansion in default_ccache_name mark('default_ccache_name parameter expansion') realm.stop() conf = {'libdefaults': {'default_ccache_name': 'testdir/%{null}abc%{uid}'}} realm = K5Realm(krb5_conf=conf, create_kdb=False) del realm.env['KRB5CCNAME'] uidstr = str(os.getuid()) msg = 'testdir/abc%s' % uidstr realm.run([klist], expected_code=1, expected_msg=msg) success('Credential cache tests') krb5-1.22.1/src/tests/etinfo.c0000664000175000017500000001377215051422640015734 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/etinfo.c - Test harness for KDC etype-info behavior */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Send an AS-REQ to the KDC for a specified principal, with an optionally * specified request enctype list. Decode the output as either an AS-REP or a * KRB-ERROR and display the PA-ETYPE-INFO2, PA-ETYPE-INFO, and PA-PW-SALT * padata in the following format: * * error/asrep etype-info2/etype-info/pw-salt enctype salt [s2kparams] * * enctype is omitted for PA-PW-SALT entries. salt is displayed directly; * s2kparams is displayed in uppercase hex. */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static void display_etinfo(krb5_etype_info_entry **list, const char *l1, const char *l2) { krb5_etype_info_entry *info; char etname[256]; unsigned int i; for (; *list != NULL; list++) { info = *list; check(krb5_enctype_to_name(info->etype, TRUE, etname, sizeof(etname))); printf("%s %s %s ", l1, l2, etname); if (info->length != KRB5_ETYPE_NO_SALT) printf("%.*s", info->length, info->salt); else printf("(default)"); if (info->s2kparams.length > 0) { printf(" "); for (i = 0; i < info->s2kparams.length; i++) printf("%02X", (unsigned char)info->s2kparams.data[i]); } printf("\n"); } } static void display_padata(krb5_pa_data **pa_list, const char *label) { krb5_pa_data *pa; krb5_data d; krb5_etype_info_entry **etinfo_list; for (; pa_list != NULL && *pa_list != NULL; pa_list++) { pa = *pa_list; d = make_data(pa->contents, pa->length); if (pa->pa_type == KRB5_PADATA_ETYPE_INFO2) { check(decode_krb5_etype_info2(&d, &etinfo_list)); display_etinfo(etinfo_list, label, "etype_info2"); krb5_free_etype_info(ctx, etinfo_list); } else if (pa->pa_type == KRB5_PADATA_ETYPE_INFO) { check(decode_krb5_etype_info(&d, &etinfo_list)); display_etinfo(etinfo_list, label, "etype_info"); krb5_free_etype_info(ctx, etinfo_list); } else if (pa->pa_type == KRB5_PADATA_PW_SALT) { printf("%s pw_salt %.*s\n", label, (int)d.length, d.data); } else if (pa->pa_type == KRB5_PADATA_AFS3_SALT) { printf("%s afs3_salt %.*s\n", label, (int)d.length, d.data); } } } int main(int argc, char **argv) { krb5_principal client; krb5_get_init_creds_opt *opt; krb5_init_creds_context icc; krb5_data reply, request, realm; krb5_error *error; krb5_kdc_rep *asrep; krb5_pa_data **padata; krb5_preauthtype pa_type = KRB5_PADATA_NONE; unsigned int flags; int primary = 0; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s princname [patype]\n", argv[0]); exit(1); } check(krb5_init_context(&ctx)); check(krb5_parse_name(ctx, argv[1], &client)); if (argc >= 3) pa_type = atoi(argv[2]); check(krb5_get_init_creds_opt_alloc(ctx, &opt)); if (pa_type != KRB5_PADATA_NONE) krb5_get_init_creds_opt_set_preauth_list(opt, &pa_type, 1); check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, opt, &icc)); reply = empty_data(); check(krb5_init_creds_step(ctx, icc, &reply, &request, &realm, &flags)); assert(flags == KRB5_INIT_CREDS_STEP_FLAG_CONTINUE); check(krb5_sendto_kdc(ctx, &request, &realm, &reply, &primary, 0)); if (decode_krb5_error(&reply, &error) == 0) { decode_krb5_padata_sequence(&error->e_data, &padata); if (error->error == KDC_ERR_PREAUTH_REQUIRED) { display_padata(padata, "error"); } else if (error->error == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED) { display_padata(padata, "more"); } else { fprintf(stderr, "Unexpected error %d\n", (int)error->error); return 1; } krb5_free_pa_data(ctx, padata); krb5_free_error(ctx, error); } else if (decode_krb5_as_rep(&reply, &asrep) == 0) { display_padata(asrep->padata, "asrep"); krb5_free_kdc_rep(ctx, asrep); } else { abort(); } krb5_free_data_contents(ctx, &request); krb5_free_data_contents(ctx, &reply); krb5_free_data_contents(ctx, &realm); krb5_get_init_creds_opt_free(ctx, opt); krb5_init_creds_free(ctx, icc); krb5_free_principal(ctx, client); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/t_kadmin.py0000664000175000017500000000527115051422640016437 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(start_kadmind=True) # Create a principal. Test -q option and keyboard entry of the admin # password and principal password. Verify creation with kadmin.local. realm.run([kadmin, '-q', 'addprinc princ/pw'], input=password('admin') + '\npw1\npw1\n') realm.run([kadminl, 'getprinc', 'princ/pw'], expected_msg='Principal: princ/pw@KRBTEST.COM') # Run the remaining tests with a cache for efficiency. realm.prep_kadmin() realm.run_kadmin(['addpol', 'standardpol']) realm.run_kadmin(['listpols'], expected_msg='standardpol') realm.run_kadmin(['modpol', '-minlength', '5', 'standardpol']) realm.run_kadmin(['getpol', 'standardpol'], expected_msg='Minimum password length: 5') realm.run_kadmin(['addprinc', '-randkey', 'princ/random']) realm.run([kadminl, 'getprinc', 'princ/random'], expected_msg='Principal: princ/random@KRBTEST.COM') realm.run_kadmin(['cpw', 'princ/pw'], input='newpw\nnewpw\n') realm.run_kadmin(['cpw', '-randkey', 'princ/random']) realm.run_kadmin(['modprinc', '-allow_tix', 'princ/random']) realm.run_kadmin(['modprinc', '+allow_tix', 'princ/random']) realm.run_kadmin(['modprinc', '-policy', 'standardpol', 'princ/random']) realm.run_kadmin(['listprincs'], expected_msg='princ/random@KRBTEST.COM') realm.run_kadmin(['ktadd', 'princ/pw']) realm.run_kadmin(['delprinc', 'princ/random']) realm.run([kadminl, 'getprinc', 'princ/random'], expected_code=1, expected_msg='Principal does not exist') realm.run_kadmin(['delprinc', 'princ/pw']) realm.run([kadminl, 'getprinc', 'princ/pw'], expected_code=1, expected_msg='Principal does not exist') realm.run_kadmin(['delpol', 'standardpol']) realm.run([kadminl, 'getpol', 'standardpol'], expected_code=1, expected_msg='Policy does not exist') # Regression test for #2877 (fixed-sized GSSRPC buffers can't # accomodate large listprinc results). mark('large listprincs result') for i in range(200): realm.run_kadmin(['addprinc', '-randkey', 'foo%d' % i]) realm.run_kadmin(['listprincs'], expected_msg='foo199') # Test kadmin -k with the default principal, with and without # fallback. This operation requires canonicalization against the # keytab in krb5_get_init_creds_keytab() as the # krb5_sname_to_principal() result won't have a realm. Try with and # without without fallback processing since the code paths are # different. mark('kadmin -k') realm.run([kadmin, '-k', 'getprinc', realm.host_princ]) no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}} no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf) realm.run([kadmin, '-k', 'getprinc', realm.host_princ], env=no_canon) success('kadmin and kpasswd tests') krb5-1.22.1/src/tests/fuzzing/0000775000175000017500000000000015051422640015766 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_cred.c0000664000175000017500000000440315051422640021635 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_marshal_cred.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for k5_unmarshal_cred. */ #include "autoconf.h" #include #define FIRST_VERSION 1 #define kMinInputLength 2 #define kMaxInputLength 1024 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; krb5_creds cred; int version; struct k5buf buf; if (size < kMinInputLength || size > kMaxInputLength) return 0; for (version = FIRST_VERSION; version <= 4; version++) { ret = k5_unmarshal_cred(data, size, version, &cred); if (!ret) { k5_buf_init_dynamic(&buf); k5_marshal_cred(&buf, version, &cred); k5_buf_free(&buf); } krb5_free_cred_contents(NULL, &cred); } return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_marshal_princ_seed_corpus/0000775000175000017500000000000015051422640024261 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_princ_seed_corpus/princ_input_4.bin0000664000175000017500000000004515051422640027527 0ustar ghudsonghudson KRBTEST.COM testclientkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_princ_seed_corpus/princ_input_1.bin0000664000175000017500000000004115051422640027520 0ustar ghudsonghudson KRBTEST.COM testclientkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_princ_seed_corpus/princ_input_2.bin0000664000175000017500000000004515051422640027525 0ustar ghudsonghudson KRBTEST.COM testclientkrb5-1.22.1/src/tests/fuzzing/README0000664000175000017500000000154515051422640016653 0ustar ghudsonghudsonThis directory builds fuzzing targets for oss-fuzz compatibility. If you wish to build it locally, you can do so by using the given guide below. Note that it only works on GNU/Linux. Export flags required for building fuzzing targets. ```bash export CC=clang export CXX=clang++ export CFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link" export CXXFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link" export LIB_FUZZING_ENGINE="-fsanitize=fuzzer" ``` Compilation of the fuzzing targets. ```bash autoreconf ./configure CFLAGS="-fcommon $CFLAGS" CXXFLAGS="-fcommon $CXXFLAGS" \ --enable-static --disable-shared --enable-ossfuzz make ``` Running fuzzing targets. ```bash mkdir fuzz_${TARGET}_corpus ./fuzz_${TARGET} fuzz_${TARGET}_corpus/ fuzz_${TARGET}_seed_corpus ``` krb5-1.22.1/src/tests/fuzzing/fuzz_kdc.c0000664000175000017500000000442515051422640017756 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_kdc.c - fuzzing harness for KDC replay cache */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "autoconf.h" #include #define kMinInputLength 2 #define kMaxInputLength 256 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; krb5_context context = NULL; krb5_data req, rep; struct entry *e; if (size < kMinInputLength || size > kMaxInputLength) return 0; ret = krb5_init_context(&context); if (ret) return 0; ret = kdc_init_lookaside(context); if (ret) goto cleanup; req = make_data((void *)data, size); rep = make_data((void *)data, size - 1); e = insert_entry(context, &req, &rep, 0); discard_entry(context, e); kdc_free_lookaside(context); cleanup: krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_krb5_ticket.c0000664000175000017500000000514215051422640021420 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_krb5_ticket.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for krb5_decode_ticket. */ #include "autoconf.h" #include #include #include #define kMinInputLength 2 #define kMaxInputLength 2048 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; krb5_context context = NULL; krb5_keytab defkt = NULL; krb5_data data_in, *data_out; krb5_ticket *ticket = NULL; if (size < kMinInputLength || size > kMaxInputLength) return 0; data_in = make_data((void *)data, size); ret = krb5_init_context(&context); if (ret) return 0; ret = krb5_kt_default(context, &defkt); if (ret) goto cleanup; ret = krb5_decode_ticket(&data_in, &ticket); if (ret) goto cleanup; ret = encode_krb5_ticket(ticket, &data_out); if (!ret) krb5_free_data(context, data_out); krb5_server_decrypt_ticket_keytab(context, defkt, ticket); cleanup: krb5_free_ticket(context, ticket); if (defkt != NULL) krb5_kt_close(context, defkt); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/fuzzing/Makefile.in0000664000175000017500000000731615051422640020042 0ustar ghudsonghudsonmydir=tests$(S)fuzzing BUILDTOP=$(REL)..$(S).. LOCALINCLUDES= \ -I$(srcdir)/../../lib/crypto/krb -I$(srcdir)/../../lib/krad \ -I$(srcdir)/../../lib/crypto/builtin/des -I$(srcdir)/../../kdc \ -I$(srcdir)/../../lib/krb5/ccache -I$(srcdir)/../../util/profile \ -I$(srcdir)/../../util/support OBJS= \ fuzz_aes.o \ fuzz_asn.o \ fuzz_attrset.o \ fuzz_chpw.o \ fuzz_crypto.o \ fuzz_des.o \ fuzz_gss.o \ fuzz_json.o \ fuzz_kdc.o \ fuzz_krad.o \ fuzz_krb.o \ fuzz_krb5_ticket.o \ fuzz_marshal_cred.o \ fuzz_marshal_princ.o \ fuzz_ndr.o \ fuzz_oid.o \ fuzz_pac.o \ fuzz_profile.o \ fuzz_util.o SRCS= \ $(srcdir)/fuzz_aes.c \ $(srcdir)/fuzz_asn.c \ $(srcdir)/fuzz_attrset.c \ $(srcdir)/fuzz_chpw.c \ $(srcdir)/fuzz_crypto.c \ $(srcdir)/fuzz_des.c \ $(srcdir)/fuzz_gss.c \ $(srcdir)/fuzz_json.c \ $(srcdir)/fuzz_kdc.c \ $(srcdir)/fuzz_krad.c \ $(srcdir)/fuzz_krb.c \ $(srcdir)/fuzz_krb5_ticket.c \ $(srcdir)/fuzz_marshal_cred.c \ $(srcdir)/fuzz_marshal_princ.c \ $(srcdir)/fuzz_ndr.c \ $(srcdir)/fuzz_oid.c \ $(srcdir)/fuzz_pac.c \ $(srcdir)/fuzz_profile.c \ $(srcdir)/fuzz_util.c FUZZ_TARGETS= \ fuzz_aes \ fuzz_asn \ fuzz_attrset \ fuzz_chpw \ fuzz_crypto \ fuzz_des \ fuzz_gss \ fuzz_json \ fuzz_kdc \ fuzz_krad \ fuzz_krb \ fuzz_krb5_ticket \ fuzz_marshal_cred \ fuzz_marshal_princ \ fuzz_ndr \ fuzz_oid \ fuzz_pac \ fuzz_profile \ fuzz_util all: $(FUZZ_TARGETS) # OSS-Fuzz requires fuzz targets to be linked with the C++ linker, # even if they are written in C. fuzz_aes: fuzz_aes.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_aes.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_asn: fuzz_asn.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_asn.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_attrset: fuzz_attrset.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_attrset.o -lkrad $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_chpw: fuzz_chpw.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_chpw.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_crypto: fuzz_crypto.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_crypto.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_des: fuzz_des.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_des.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_gss: fuzz_gss.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_gss.o $(GSS_LIBS) $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_json: fuzz_json.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_json.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_kdc: fuzz_kdc.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_kdc.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_krad: fuzz_krad.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_krad.o -lkrad $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_krb: fuzz_krb.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_krb.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_krb5_ticket: fuzz_krb5_ticket.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_krb5_ticket.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_marshal_cred: fuzz_marshal_cred.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_marshal_cred.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_marshal_princ: fuzz_marshal_princ.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_marshal_princ.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_ndr: fuzz_ndr.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_ndr.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_oid: fuzz_oid.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_oid.o $(GSS_LIBS) $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_pac: fuzz_pac.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_pac.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_profile: fuzz_profile.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_profile.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) fuzz_util: fuzz_util.o $(KRB5_BASE_DEPLIBS) $(CXX_LINK) -o $@ fuzz_util.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS) install: clean: $(RM) $(FUZZ_TARGETS) krb5-1.22.1/src/tests/fuzzing/fuzz_pac.c0000664000175000017500000000570515051422640017762 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_pac.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for krb5_pac_parse. */ #include "autoconf.h" #include #define U(x) (uint8_t *)x #define kMinInputLength 2 #define kMaxInputLength 1024 static const krb5_keyblock kdc_keyblock = { 0, ENCTYPE_ARCFOUR_HMAC, 16, U("\xB2\x86\x75\x71\x48\xAF\x7F\xD2\x52\xC5\x36\x03\xA1\x50\xB7\xE7") }; static const krb5_keyblock member_keyblock = { 0, ENCTYPE_ARCFOUR_HMAC, 16, U("\xD2\x17\xFA\xEA\xE5\xE6\xB5\xF9\x5C\xCC\x94\x07\x7A\xB8\xA5\xFC") }; static time_t authtime = 1120440609; static const char *user = "w2003final$@WIN2K3.THINKER.LOCAL"; extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; krb5_context context = NULL; krb5_pac pac; krb5_principal princ = NULL; if (size < kMinInputLength || size > kMaxInputLength) return 0; ret = krb5_init_context(&context); if (ret) return 0; ret = krb5_parse_name(context, user, &princ); if (ret) goto cleanup; ret = krb5_pac_parse(context, data, size, &pac); if (ret) goto cleanup; krb5_pac_verify(context, pac, authtime, princ, NULL, NULL); krb5_pac_verify_ext(context, pac, authtime, princ, NULL, NULL, TRUE); krb5_pac_verify(context, pac, authtime, princ, &member_keyblock, &kdc_keyblock); krb5_pac_free(context, pac); cleanup: krb5_free_principal(context, princ); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_json_seed_corpus/0000775000175000017500000000000015051422640022410 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_json_seed_corpus/seed_3.json0000664000175000017500000000000715051422640024442 0ustar ghudsonghudson [ -1 ]krb5-1.22.1/src/tests/fuzzing/fuzz_json_seed_corpus/seed_2.json0000664000175000017500000000006415051422640024444 0ustar ghudsonghudson{ "k1" : { "k2" : "s2", "k3" : "s3" }, "k4" : "s4" }krb5-1.22.1/src/tests/fuzzing/fuzz_json_seed_corpus/seed_1.json0000664000175000017500000000001515051422640024437 0ustar ghudsonghudson "foo\"bar" krb5-1.22.1/src/tests/fuzzing/fuzz_krad.c0000664000175000017500000000537715051422640020145 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_krad.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for krad_packet_decode_response, * krad_packet_decode_request. */ #include "autoconf.h" #include #include #define kMinInputLength 2 #define kMaxInputLength 1024 static krad_packet *packets[3]; static const krad_packet * iterator(void *data, krb5_boolean cancel) { krad_packet *tmp; int *i = data; if (cancel || packets[*i] == NULL) return NULL; tmp = packets[*i]; *i += 1; return tmp; } extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { int i; krb5_context ctx; krb5_data data_in; const char *secret = "f"; const krad_packet *req_1 = NULL, *req_2 = NULL; krad_packet *rsp_1 = NULL, *rsp_2 = NULL; if (size < kMinInputLength || size > kMaxInputLength) return 0; if (krb5_init_context(&ctx) != 0) return 0; data_in = make_data((void *)data, size); i = 0; krad_packet_decode_response(ctx, secret, &data_in, iterator, &i, &req_1, &rsp_1); i = 0; krad_packet_decode_request(ctx, secret, &data_in, iterator, &i, &req_2, &rsp_2); krad_packet_free(rsp_1); krad_packet_free(rsp_2); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_marshal_cred_seed_corpus/0000775000175000017500000000000015051422640024063 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_cred_seed_corpus/cred_1_input_4.bin0000664000175000017500000000025515051422640027356 0ustar ghudsonghudson KRBTEST.COM testclient EXAMPLE.COMtesthost  Þ ;šÊ@€  signticketÿœticketkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_cred_seed_corpus/cred_1_input_1.bin0000664000175000017500000000024515051422640027352 0ustar ghudsonghudson KRBTEST.COM testclient EXAMPLE.COMtesthost  Þ Êš;€@  signticketœÿticketkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_cred_seed_corpus/cred_2_input_1.bin0000664000175000017500000000016115051422640027350 0ustar ghudsonghudson KRBTEST.COM testclient ticket2ticketkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_cred_seed_corpus/cred_1_input_2.bin0000664000175000017500000000025515051422640027354 0ustar ghudsonghudson KRBTEST.COM testclient EXAMPLE.COMtesthost  Þ Êš;€@  signticketœÿticketkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_cred_seed_corpus/cred_2_input_2.bin0000664000175000017500000000017115051422640027352 0ustar ghudsonghudson KRBTEST.COM testclient ticket2ticketkrb5-1.22.1/src/tests/fuzzing/fuzz_marshal_cred_seed_corpus/cred_2_input_4.bin0000664000175000017500000000017115051422640027354 0ustar ghudsonghudson KRBTEST.COM testclient ticket2ticketkrb5-1.22.1/src/tests/fuzzing/fuzz_aes.c0000664000175000017500000000663015051422640017765 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_aes.c - fuzzing harness for AES encryption/decryption */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "autoconf.h" #include #include #define kMinInputLength 48 #define kMaxInputLength 512 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); static void fuzz_aes(const uint8_t *data, size_t size, size_t key_size, krb5_enctype etype) { krb5_error_code ret; krb5_keyblock keyblock; krb5_crypto_iov iov; krb5_key key = NULL; char *aeskey = NULL, *data_in = NULL; char encivbuf[16] = { 0 }, decivbuf[16] = { 0 }; krb5_data enciv = make_data(encivbuf, 16), deciv = make_data(decivbuf, 16); aeskey = k5memdup(data, key_size, &ret); if (ret) return; data_in = k5memdup(data + key_size, size - key_size, &ret); if (ret) goto cleanup; keyblock.contents = (krb5_octet *)aeskey; keyblock.length = key_size; keyblock.enctype = etype; ret = krb5_k_create_key(NULL, &keyblock, &key); if (ret) goto cleanup; iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(data_in, size - key_size); /* iov.data.data is input and output buffer */ ret = krb5int_aes_encrypt(key, &enciv, &iov, 1); if (ret) goto cleanup; ret = krb5int_aes_decrypt(key, &deciv, &iov, 1); if (ret) goto cleanup; /* Check that decryption result matches original plaintext. */ ret = memcmp(data_in, data + key_size, size - key_size); if (ret) abort(); (void)krb5int_aes_decrypt(key, &deciv, &iov, 1); cleanup: free(aeskey); free(data_in); krb5_k_free_key(NULL, key); } int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (size < kMinInputLength || size > kMaxInputLength) return 0; fuzz_aes(data, size, 16, ENCTYPE_AES128_CTS_HMAC_SHA1_96); fuzz_aes(data, size, 16, ENCTYPE_AES256_CTS_HMAC_SHA1_96); fuzz_aes(data, size, 32, ENCTYPE_AES128_CTS_HMAC_SHA1_96); fuzz_aes(data, size, 32, ENCTYPE_AES256_CTS_HMAC_SHA1_96); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_marshal_princ.c0000664000175000017500000000441115051422640022032 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_marshal_princ.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for k5_unmarshal_princ. */ #include "autoconf.h" #include #define FIRST_VERSION 1 #define kMinInputLength 2 #define kMaxInputLength 1024 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; krb5_principal princ; int version; struct k5buf buf; if (size < kMinInputLength || size > kMaxInputLength) return 0; for (version = FIRST_VERSION; version <= 4; version++) { ret = k5_unmarshal_princ(data, size, version, &princ); if (!ret) { k5_buf_init_dynamic(&buf); k5_marshal_princ(&buf, version, princ); k5_buf_free(&buf); } krb5_free_principal(NULL, princ); } return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_attrset.c0000664000175000017500000000452315051422640020702 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_attrset.c - fuzzing harness for kr_attrset functions */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "autoconf.h" #include #include #define kMinInputLength 2 #define kMaxInputLength 1024 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; krb5_context context; krad_attrset *set; krb5_data data_in; uint8_t buffer[KRAD_PACKET_SIZE_MAX], auth[MD5_DIGEST_SIZE] = { 0 }; size_t encode_len; if (size < kMinInputLength || size > kMaxInputLength) return 0; data_in = make_data((void *)data, size); ret = krb5_init_context(&context); if (ret) return 0; ret = kr_attrset_decode(context, &data_in, "f", auth, &set); if (!ret) kr_attrset_encode(set, "f", auth, FALSE, buffer, &encode_len); krad_attrset_free(set); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_oid.c0000664000175000017500000000430115051422640017761 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_oid.c - fuzzing harness for GSS OID conversions */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "autoconf.h" #include #include #define kMinInputLength 2 #define kMaxInputLength 1024 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { OM_uint32 minor; gss_buffer_desc buf; gss_OID oid; gss_OID_desc oid_desc; if (size < kMinInputLength || size > kMaxInputLength) return 0; oid_desc.elements = (void *)data; oid_desc.length = size; gss_oid_to_str(&minor, &oid_desc, &buf); gss_release_buffer(&minor, &buf); buf.value = (void *)data; buf.length = size; gss_str_to_oid(&minor, &buf, &oid); gss_release_oid(&minor, &oid); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_profile.c0000664000175000017500000000522015051422640020647 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_profile.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for profile_parse_file. */ #include "autoconf.h" #include void dump_profile(struct profile_node *root, int level); #define kMinInputLength 2 #define kMaxInputLength 1024 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { errcode_t ret; FILE *fp_w, *fp_r; char file_name[256], *output; struct profile_node *root; if (size < kMinInputLength || size > kMaxInputLength) return 0; snprintf(file_name, sizeof(file_name), "/tmp/libfuzzer.%d", getpid()); /* Write data into the file. */ fp_w = fopen(file_name, "w"); if (!fp_w) return 1; fwrite(data, 1, size, fp_w); fclose(fp_w); /* Provide the file pointer to the parser. */ fp_r = fopen(file_name, "r"); if (!fp_r) return 1; initialize_prof_error_table(); ret = profile_parse_file(fp_r, &root, NULL); if (!ret) { ret = profile_write_tree_to_buffer(root, &output); if (!ret) free(output); profile_verify_node(root); profile_free_node(root); } fclose(fp_r); unlink(file_name); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_krad_seed_corpus/0000775000175000017500000000000015051422640022360 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_krad_seed_corpus/do_auth_1.bin0000664000175000017500000000002415051422640024711 0ustar ghudsonghudson@ÑŸnj${<‘8Æ'¢V/"krb5-1.22.1/src/tests/fuzzing/fuzz_crypto_seed_corpus/0000775000175000017500000000000015051422640022757 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_crypto_seed_corpus/input.bin0000664000175000017500000000000415051422640024602 0ustar ghudsonghudsonbrrrkrb5-1.22.1/src/tests/fuzzing/fuzz_oid_seed_corpus/0000775000175000017500000000000015051422640022212 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_oid_seed_corpus/oid_21.bin0000664000175000017500000000000315051422640023752 0ustar ghudsonghudson€krb5-1.22.1/src/tests/fuzzing/fuzz_oid_seed_corpus/oid_8.bin0000664000175000017500000000001115051422640023676 0ustar ghudsonghudson*†H†÷krb5-1.22.1/src/tests/fuzzing/fuzz_oid_seed_corpus/oid_22.bin0000664000175000017500000000000215051422640023752 0ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_oid_seed_corpus/oid_20.bin0000664000175000017500000000000215051422640023750 0ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_oid_seed_corpus/oid_19.bin0000664000175000017500000000000115051422640023757 0ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_oid_seed_corpus/oid_24.bin0000664000175000017500000000000415051422640023756 0ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/deps0000664000175000017500000003557515051422640016663 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)fuzz_aes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/crypto/krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_aes.c $(OUTPRE)fuzz_asn.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-spake.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_asn.c $(OUTPRE)fuzz_attrset.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(VERTO_DEPS) \ $(srcdir)/../../lib/krad/internal.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krad.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_attrset.c $(OUTPRE)fuzz_chpw.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h fuzz_chpw.c $(OUTPRE)fuzz_crypto.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/crypto/krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_crypto.c $(OUTPRE)fuzz_des.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/crypto/builtin/des/des_int.h \ $(srcdir)/../../lib/crypto/builtin/des/f_cbc.c $(srcdir)/../../lib/crypto/builtin/des/f_tables.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_des.c $(OUTPRE)fuzz_gss.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/gssapi.h $(top_srcdir)/include/krb5.h \ fuzz_gss.c $(OUTPRE)fuzz_json.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-json.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_json.c $(OUTPRE)fuzz_kdc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(VERTO_DEPS) \ $(srcdir)/../../kdc/extern.h $(srcdir)/../../kdc/kdc_util.h \ $(srcdir)/../../kdc/realm_data.h $(srcdir)/../../kdc/replay.c \ $(srcdir)/../../kdc/reqstate.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-hashtab.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-queue.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/kdcpreauth_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/net-server.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_kdc.c $(OUTPRE)fuzz_krad.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(VERTO_DEPS) \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krad.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h fuzz_krad.c $(OUTPRE)fuzz_krb.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-base64.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hex.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h fuzz_krb.c $(OUTPRE)fuzz_krb5_ticket.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h fuzz_krb5_ticket.c $(OUTPRE)fuzz_marshal_cred.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/krb5/ccache/cc-int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_marshal_cred.c $(OUTPRE)fuzz_marshal_princ.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../lib/krb5/ccache/cc-int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_marshal_princ.c $(OUTPRE)fuzz_ndr.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(VERTO_DEPS) \ $(srcdir)/../../kdc/kdc_util.h $(srcdir)/../../kdc/ndr.c \ $(srcdir)/../../kdc/realm_data.h $(srcdir)/../../kdc/reqstate.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-input.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/k5-utf8.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/kdcpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/net-server.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h fuzz_ndr.c $(OUTPRE)fuzz_oid.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ fuzz_oid.c $(OUTPRE)fuzz_pac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h fuzz_pac.c $(OUTPRE)fuzz_profile.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../util/profile/prof_int.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ fuzz_profile.c $(OUTPRE)fuzz_util.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../util/support/hashtab.c \ $(top_srcdir)/include/k5-base64.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-hashtab.h $(top_srcdir)/include/k5-hex.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-queue.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h fuzz_util.c krb5-1.22.1/src/tests/fuzzing/fuzz_des.c0000664000175000017500000000642215051422640017767 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_des.c - fuzzing harness for DES functions */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "autoconf.h" #include #include #include #define kMinInputLength 32 #define kMaxInputLength 128 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); uint8_t default_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; static void fuzz_des(uint8_t *input, mit_des_key_schedule sched) { uint8_t encrypt[8], decrypt[8]; mit_des_cbc_encrypt((const mit_des_cblock *)input, (mit_des_cblock *)encrypt, 8, sched, default_ivec, MIT_DES_ENCRYPT); mit_des_cbc_encrypt((const mit_des_cblock *)encrypt, (mit_des_cblock *)decrypt, 8, sched, default_ivec, MIT_DES_DECRYPT); if (memcmp(input, decrypt, 8) != 0) abort(); } static void fuzz_decrypt(uint8_t *input, mit_des_key_schedule sched) { uint8_t output[8]; mit_des_cbc_encrypt((const mit_des_cblock *)input, (mit_des_cblock *)output, 8, sched, default_ivec, MIT_DES_DECRYPT); } static void fuzz_cksum(uint8_t *input, mit_des_key_schedule sched) { uint8_t output[8]; mit_des_cbc_cksum(input, output, 8, sched, default_ivec); } int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; mit_des_key_schedule sched; uint8_t *data_in, input[8]; if (size < kMinInputLength || size > kMaxInputLength) return 0; memcpy(input, data, 8); ret = mit_des_key_sched(input, sched); if (ret) return 0; memcpy(input, data + 8, 8); fuzz_des(input, sched); memcpy(input, data + 16, 8); fuzz_decrypt(input, sched); data_in = k5memdup(data + 24, size - 24, &ret); if (ret) return 0; fuzz_cksum(data_in, sched); free(data_in); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_profile_seed_corpus/0000775000175000017500000000000015051422640023077 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_profile_seed_corpus/final2.ini0000664000175000017500000000013515051422640024752 0ustar ghudsonghudson# In this variant the relation is marked final. [section] subsection = { key* = value2 } krb5-1.22.1/src/tests/fuzzing/fuzz_profile_seed_corpus/final4.ini0000664000175000017500000000020315051422640024750 0ustar ghudsonghudson# In this variant the subsection is marked final via a '*' after the # closing brace. [section] subsection = { key = value4 }* krb5-1.22.1/src/tests/fuzzing/fuzz_profile_seed_corpus/test3.ini0000664000175000017500000000003015051422640024633 0ustar ghudsonghudson[section] var = value krb5-1.22.1/src/tests/fuzzing/fuzz_profile_seed_corpus/final5.ini0000664000175000017500000000014615051422640024757 0ustar ghudsonghudson# In this variant the top-level section is marked final. [section]* subsection = { key = value5 } krb5-1.22.1/src/tests/fuzzing/fuzz_profile_seed_corpus/modtest.conf0000664000175000017500000000012715051422640025425 0ustar ghudsonghudsonmodule /home/dark/Desktop/krb5/src/util/profile/testmod/proftest.so-nobuild:teststring krb5-1.22.1/src/tests/fuzzing/fuzz_profile_seed_corpus/testinc2.ini0000664000175000017500000000001515051422640025327 0ustar ghudsonghudson[sec2] b = 2 krb5-1.22.1/src/tests/fuzzing/fuzz_profile_seed_corpus/testinc.ini0000664000175000017500000000006215051422640025247 0ustar ghudsonghudson[sec1] var = { a = 1 include testinc2.ini c = 3 } krb5-1.22.1/src/tests/fuzzing/fuzz_profile_seed_corpus/final3.ini0000664000175000017500000000020615051422640024752 0ustar ghudsonghudson# In this variant the subsection is marked final via a '*' at the end # of the tag name. [section] subsection* = { key = value3 } krb5-1.22.1/src/tests/fuzzing/fuzz_ndr_seed_corpus/0000775000175000017500000000000015051422640022222 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_ndr_seed_corpus/s4u_di_long.bin0000664000175000017500000000027015051422640025121 0ustar ghudsonghudsonÌÌĮ̀02longsvc/adserver.ad.test:< svc1/adserver.ad.test@AD.TESTkrb5-1.22.1/src/tests/fuzzing/fuzz_ndr_seed_corpus/s4u_di_double.bin0000664000175000017500000000041015051422640025430 0ustar ghudsonghudsonÌÌÌÌø02longsvc/adserver.ad.test:< :<svc1/adserver.ad.test@AD.TESTsvc2/adserver.ad.test@AD.TESTkrb5-1.22.1/src/tests/fuzzing/fuzz_des_seed_corpus/0000775000175000017500000000000015051422640022212 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_des_seed_corpus/input.bin0000664000175000017500000000003715051422640024043 0ustar ghudsonghudsonbrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrkrb5-1.22.1/src/tests/fuzzing/fuzz_util.c0000664000175000017500000000765115051422640020176 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_util.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for k5_base64_decode, k5_hex_decode * krb5_parse_name and k5_parse_host_string. */ #include "autoconf.h" #include #include #include #include #include #include #define kMinInputLength 2 #define kMaxInputLength 256 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); static void fuzz_base64(const char *data_in, size_t size) { size_t len; free(k5_base64_encode(data_in, size)); free(k5_base64_decode(data_in, &len)); } static void fuzz_hashtab(const char *data_in, size_t size) { int st; struct k5_hashtab *ht; k5_hashtab_create(NULL, 4, &ht); if (ht == NULL) return; k5_hashtab_add(ht, data_in, size, &st); k5_hashtab_free(ht); } static void fuzz_hex(const char *data_in, size_t size) { char *hex; uint8_t *bytes; size_t len; if (k5_hex_encode(data_in, size, 0, &hex) == 0) free(hex); if (k5_hex_encode(data_in, size, 1, &hex) == 0) free(hex); if (k5_hex_decode(data_in, &bytes, &len) == 0) free(bytes); } static void fuzz_name(const char *data_in, size_t size) { krb5_context context; krb5_principal fuzzing; if (krb5_init_context(&context) != 0) return; krb5_parse_name(context, data_in, &fuzzing); krb5_free_principal(context, fuzzing); krb5_free_context(context); } static void fuzz_parse_host(const char *data_in, size_t size) { char *host_out = NULL; int port_out = -1; if (k5_parse_host_string(data_in, 1, &host_out, &port_out) == 0) free(host_out); } static void fuzz_utf8(const char *data_in, size_t size) { krb5_ucs4 u = 0; char *utf8; uint8_t *utf16; size_t utf16len; krb5int_utf8_to_ucs4(data_in, &u); k5_utf8_to_utf16le(data_in, &utf16, &utf16len); if (utf16 != NULL) free(utf16); k5_utf16le_to_utf8((const uint8_t *)data_in, size, &utf8); if (utf8 != NULL) free(utf8); } extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; char *data_in; if (size < kMinInputLength || size > kMaxInputLength) return 0; data_in = k5memdup0(data, size, &ret); if (data_in == NULL) return 0; fuzz_base64(data_in, size); fuzz_hashtab(data_in, size); fuzz_hex(data_in, size); fuzz_name(data_in, size); fuzz_parse_host(data_in, size); fuzz_utf8(data_in, size); free(data_in); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_crypto.c0000664000175000017500000001246715051422640020542 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_crypto.c - fuzzing harness for general crypto */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "autoconf.h" #include #include #define kMinInputLength 2 #define kMaxInputLength 512 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); static void fuzz_checksum(krb5_cksumtype sumtype, krb5_keyblock keyblock, krb5_keyusage usage, krb5_data data) { krb5_error_code ret; krb5_checksum cksum; krb5_boolean valid; ret = krb5_c_make_checksum(NULL, sumtype, &keyblock, usage, &data, &cksum); if (ret) return; ret = krb5_c_verify_checksum(NULL, &keyblock, usage, &data, &cksum, &valid); if (ret || !valid) abort(); krb5_free_checksum_contents(NULL, &cksum); } static void fuzz_crypt(krb5_keyblock keyblock, krb5_enctype enctype, krb5_keyusage usage, krb5_data data) { krb5_error_code ret; krb5_enc_data encoded = { 0 }; krb5_data decoded = empty_data(); size_t enclen; ret = krb5_c_encrypt_length(NULL, enctype, data.length, &enclen); if (ret) return; encoded.magic = KV5M_ENC_DATA; encoded.enctype = enctype; ret = alloc_data(&encoded.ciphertext, enclen); if (ret) return; ret = alloc_data(&decoded, data.length); if (ret) { krb5_free_data_contents(NULL, &encoded.ciphertext); return; } ret = krb5_c_encrypt(NULL, &keyblock, usage, NULL, &data, &encoded); if (ret) goto cleanup; ret = krb5_c_decrypt(NULL, &keyblock, usage, NULL, &encoded, &decoded); if (ret) goto cleanup; if (memcmp(data.data, decoded.data, data.length) != 0) abort(); cleanup: krb5_free_data_contents(NULL, &encoded.ciphertext); krb5_free_data_contents(NULL, &decoded); } static void fuzz_prf(krb5_keyblock keyblock, krb5_enctype enctype, krb5_data data) { krb5_error_code ret; krb5_data output; size_t prfsz; ret = krb5_c_prf_length(NULL, enctype, &prfsz); if (ret) return; ret = alloc_data(&output, prfsz); if (ret) return; krb5_c_prf(NULL, &keyblock, &data, &output); krb5_free_data_contents(NULL, &output); } static void fuzz_setup(krb5_enctype enctype, krb5_cksumtype sumtype, krb5_keyusage usage, krb5_data data) { krb5_error_code ret; krb5_keyblock keyblock; ret = krb5_c_make_random_key(NULL, enctype, &keyblock); if (ret) return; fuzz_checksum(sumtype, keyblock, usage, data); fuzz_crypt(keyblock, enctype, usage, data); fuzz_prf(keyblock, enctype, data); krb5_free_keyblock_contents(NULL, &keyblock); } int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_data data_in; if (size < kMinInputLength || size > kMaxInputLength) return 0; data_in = make_data((void *)data, size); fuzz_setup(ENCTYPE_DES3_CBC_SHA1, CKSUMTYPE_HMAC_SHA1_DES3, 0, data_in); fuzz_setup(ENCTYPE_ARCFOUR_HMAC, CKSUMTYPE_MD5_HMAC_ARCFOUR, 1, data_in); fuzz_setup(ENCTYPE_ARCFOUR_HMAC, CKSUMTYPE_HMAC_MD5_ARCFOUR, 2, data_in); fuzz_setup(ENCTYPE_ARCFOUR_HMAC_EXP, CKSUMTYPE_RSA_MD4, 3, data_in); fuzz_setup(ENCTYPE_ARCFOUR_HMAC_EXP, CKSUMTYPE_RSA_MD5, 4, data_in); fuzz_setup(ENCTYPE_ARCFOUR_HMAC_EXP, CKSUMTYPE_SHA1, 5, data_in); fuzz_setup(ENCTYPE_AES128_CTS_HMAC_SHA1_96, CKSUMTYPE_HMAC_SHA1_96_AES128, 6, data_in); fuzz_setup(ENCTYPE_AES256_CTS_HMAC_SHA1_96, CKSUMTYPE_HMAC_SHA1_96_AES256, 7, data_in); fuzz_setup(ENCTYPE_CAMELLIA128_CTS_CMAC, CKSUMTYPE_CMAC_CAMELLIA128, 8, data_in); fuzz_setup(ENCTYPE_CAMELLIA256_CTS_CMAC, CKSUMTYPE_CMAC_CAMELLIA256, 9, data_in); fuzz_setup(ENCTYPE_AES128_CTS_HMAC_SHA256_128, CKSUMTYPE_HMAC_SHA256_128_AES128, 10, data_in); fuzz_setup(ENCTYPE_AES256_CTS_HMAC_SHA384_192, CKSUMTYPE_HMAC_SHA384_192_AES256, 11, data_in); return 0; } krb5-1.22.1/src/tests/fuzzing/oss-fuzz.sh0000664000175000017500000000162315051422640020124 0ustar ghudsonghudson#!/bin/bash -eu # This script plays the role of build.sh in OSS-Fuzz. If only minor # changes are required such as changing the fuzzing targets, a PR in # the OSS-Fuzz repository is not needed and they can be done here. # Compile krb5 for oss-fuzz. pushd src/ autoreconf ./configure CFLAGS="-fcommon $CFLAGS" CXXFLAGS="-fcommon $CXXFLAGS" \ --enable-static --disable-shared --enable-ossfuzz make popd # Copy fuzz targets and seed corpus to $OUT. pushd src/tests/fuzzing fuzzers=("fuzz_aes" "fuzz_asn" "fuzz_attrset" "fuzz_chpw" "fuzz_crypto" "fuzz_des" "fuzz_gss" "fuzz_json" "fuzz_kdc" "fuzz_krad" "fuzz_krb" "fuzz_krb5_ticket" "fuzz_marshal_cred" "fuzz_marshal_princ" "fuzz_ndr" "fuzz_oid" "fuzz_pac" "fuzz_profile" "fuzz_util") for fuzzer in "${fuzzers[@]}"; do cp "$fuzzer" "$OUT/$fuzzer" zip -r "${OUT}/${fuzzer}_seed_corpus.zip" "${fuzzer}_seed_corpus" done popd krb5-1.22.1/src/tests/fuzzing/fuzz_util_seed_corpus/0000775000175000017500000000000015051422640022414 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_util_seed_corpus/name.txt0000664000175000017500000000000515051422640024070 0ustar ghudsonghudson/b@R krb5-1.22.1/src/tests/fuzzing/fuzz_util_seed_corpus/host.txt0000664000175000017500000000002015051422640024122 0ustar ghudsonghudsontest.example:75 krb5-1.22.1/src/tests/fuzzing/fuzz_util_seed_corpus/base64.txt0000664000175000017500000000001515051422640024235 0ustar ghudsonghudsonYWJjOmRlZg== krb5-1.22.1/src/tests/fuzzing/fuzz_util_seed_corpus/hax.txt0000664000175000017500000000002115051422640023726 0ustar ghudsonghudson3031323334353637 krb5-1.22.1/src/tests/fuzzing/fuzz_krb.c0000664000175000017500000001037615051422640017775 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/krb.c - fuzzing harness for miscellaneous libkrb5 functions */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "autoconf.h" #include #define kMinInputLength 2 #define kMaxInputLength 512 #define ANAME_SZ 40 #define INST_SZ 40 #define REALM_SZ 40 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); static void fuzz_deltat(char *data_in) { krb5_deltat result; krb5_string_to_deltat(data_in, &result); } static void fuzz_host_string(char *data_in) { krb5_error_code ret; char *host; int port = -1; ret = k5_parse_host_string(data_in, 0, &host, &port); if (!ret) free(host); } static void fuzz_princ(krb5_context context, char *data_in) { krb5_error_code ret; krb5_principal p; char *princ; ret = krb5_parse_name(context, data_in, &p); if (ret) return; ret = krb5_unparse_name(context, p, &princ); if (!ret) free(princ); krb5_free_principal(context, p); } static void fuzz_principal_425(krb5_context context, char *data_in) { krb5_principal princ; krb5_425_conv_principal(context, data_in, data_in, data_in, &princ); krb5_free_principal(context, princ); } static void fuzz_principal_524(krb5_context context, char *data_in) { krb5_error_code ret; krb5_principal princ = 0; char aname[ANAME_SZ + 1], inst[INST_SZ + 1], realm[REALM_SZ + 1]; aname[ANAME_SZ] = inst[INST_SZ] = realm[REALM_SZ] = 0; ret = krb5_parse_name(context, data_in, &princ); if (ret) return; krb5_524_conv_principal(context, princ, aname, inst, realm); krb5_free_principal(context, princ); } static void fuzz_timestamp(char *data_in) { krb5_error_code ret; krb5_timestamp timestamp; ret = krb5_string_to_timestamp(data_in, ×tamp); if (!ret) ts2tt(timestamp); } /* * data_in is going to be modified during parsing. */ static void fuzz_enctype_list(char *data_in) { krb5_error_code ret; krb5_context context; krb5_enctype *ienc, zero = 0; ret = krb5_init_context(&context); if (ret) return; ret = krb5int_parse_enctype_list(context, "", data_in, &zero, &ienc); if (!ret) free(ienc); krb5_free_context(context); } extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; krb5_context context = NULL; char *data_in; if (size < kMinInputLength || size > kMaxInputLength) return 0; ret = krb5_init_context(&context); if (ret) return 0; data_in = k5memdup0(data, size, &ret); if (ret) goto cleanup; fuzz_deltat(data_in); fuzz_host_string(data_in); fuzz_princ(context, data_in); fuzz_principal_425(context, data_in); fuzz_principal_524(context, data_in); fuzz_timestamp(data_in); fuzz_enctype_list(data_in); free(data_in); cleanup: krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_ndr.c0000664000175000017500000000433215051422640017775 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_ndr.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for ndr_dec_delegation_info. */ #include "autoconf.h" #include #include #include #define kMinInputLength 2 #define kMaxInputLength 1024 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; krb5_data data_in, data_out = empty_data(); struct pac_s4u_delegation_info *di; if (size < kMinInputLength || size > kMaxInputLength) return 0; data_in = make_data((void *)data, size); ret = ndr_dec_delegation_info(&data_in, &di); if (!ret) (void)ndr_enc_delegation_info(di, &data_out); ndr_free_delegation_info(di); krb5_free_data_contents(NULL, &data_out); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/0000775000175000017500000000000015051422640022215 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/host_string_5.bin0000664000175000017500000000005515051422640025476 0ustar ghudsonghudson[BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE]:250krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/host_string_4.bin0000664000175000017500000000005115051422640025471 0ustar ghudsonghudson[BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE]krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/enctype_6.bin0000664000175000017500000000001515051422640024577 0ustar ghudsonghudsondes3 +DEFAULTkrb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/enctype_2.bin0000664000175000017500000000002415051422640024573 0ustar ghudsonghudsonaes des3-cbc-sha1-kdkrb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/host_string_2.bin0000664000175000017500000000001315051422640025465 0ustar ghudsonghudson192.168.1.1krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/enctype_4.bin0000664000175000017500000000003615051422640024600 0ustar ghudsonghudsonDEFAULT +aes -arcfour-hmac-md5krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/host_string_8.bin0000664000175000017500000000000415051422640025473 0ustar ghudsonghudson:300krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/enctype_5.bin0000664000175000017500000000004315051422640024577 0ustar ghudsonghudsonDEFAULT -des3 rc4-hmac rc4-hmac-expkrb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/enctype_3.bin0000664000175000017500000000003615051422640024577 0ustar ghudsonghudsoncamellia -camellia256-cts-cmackrb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/deltat.bin0000664000175000017500000000001515051422640024160 0ustar ghudsonghudson-35791394m-9skrb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/enctype_7.bin0000664000175000017500000000004015051422640024576 0ustar ghudsonghudsonaes +rc4 -DEFaulT des3-hmac-sha1krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/host_string_9.bin0000664000175000017500000000000315051422640025473 0ustar ghudsonghudson350krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/principal_425_name.bin0000664000175000017500000000000615051422640026256 0ustar ghudsonghudsonkadminkrb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/host_string_12.bin0000664000175000017500000000002115051422640025545 0ustar ghudsonghudsontest.example:F101krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/host_string_11.bin0000664000175000017500000000000515051422640025546 0ustar ghudsonghudson70000krb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/parse_name.bin0000664000175000017500000000001115051422640025011 0ustar ghudsonghudsonlha@SU.SEkrb5-1.22.1/src/tests/fuzzing/fuzz_krb_seed_corpus/enctype_1.bin0000664000175000017500000000004215051422640024572 0ustar ghudsonghudsondefault -aes128-cts -des-hmac-sha1krb5-1.22.1/src/tests/fuzzing/fuzz_asn.c0000664000175000017500000002101115051422640017764 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_asn.c - fuzzing harness for ASN.1 encoding/decoding */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "autoconf.h" #include #define kMinInputLength 2 #define kMaxInputLength 2048 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); static void free_cred_enc_part_whole(krb5_context ctx, krb5_cred_enc_part *val) { krb5_free_cred_enc_part(ctx, val); free(val); } static void free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val) { if (val == NULL) return; free(val->kerb_message.data); free(val->target_domain.data); free(val); } #define FUZZ_ASAN(type, encoder, decoder, freefn) do { \ type *v; \ krb5_data *data_out = NULL; \ \ if ((*decoder)(&data_in, &v) != 0) \ break; \ \ (*encoder)(v, &data_out); \ krb5_free_data(context, data_out); \ (*freefn)(context, v); \ } while (0) int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_context context; krb5_data data_in; if (size < kMinInputLength || size > kMaxInputLength) return 0; if (krb5_init_context(&context)) return 0; data_in = make_data((void *)data, size); /* Adapted from krb5_decode_leak.c */ FUZZ_ASAN(krb5_authenticator, encode_krb5_authenticator, decode_krb5_authenticator, krb5_free_authenticator); FUZZ_ASAN(krb5_ticket, encode_krb5_ticket, decode_krb5_ticket, krb5_free_ticket); FUZZ_ASAN(krb5_keyblock, encode_krb5_encryption_key, decode_krb5_encryption_key, krb5_free_keyblock); FUZZ_ASAN(krb5_enc_tkt_part, encode_krb5_enc_tkt_part, decode_krb5_enc_tkt_part, krb5_free_enc_tkt_part); FUZZ_ASAN(krb5_enc_kdc_rep_part, encode_krb5_enc_kdc_rep_part, decode_krb5_enc_kdc_rep_part, krb5_free_enc_kdc_rep_part); FUZZ_ASAN(krb5_kdc_rep, encode_krb5_as_rep, decode_krb5_as_rep, krb5_free_kdc_rep); FUZZ_ASAN(krb5_kdc_rep, encode_krb5_tgs_rep, decode_krb5_tgs_rep, krb5_free_kdc_rep); FUZZ_ASAN(krb5_ap_req, encode_krb5_ap_req, decode_krb5_ap_req, krb5_free_ap_req); FUZZ_ASAN(krb5_ap_rep, encode_krb5_ap_rep, decode_krb5_ap_rep, krb5_free_ap_rep); FUZZ_ASAN(krb5_ap_rep_enc_part, encode_krb5_ap_rep_enc_part, decode_krb5_ap_rep_enc_part, krb5_free_ap_rep_enc_part); FUZZ_ASAN(krb5_kdc_req, encode_krb5_as_req, decode_krb5_as_req, krb5_free_kdc_req); FUZZ_ASAN(krb5_kdc_req, encode_krb5_tgs_req, decode_krb5_tgs_req, krb5_free_kdc_req); FUZZ_ASAN(krb5_kdc_req, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body, krb5_free_kdc_req); FUZZ_ASAN(krb5_safe, encode_krb5_safe, decode_krb5_safe, krb5_free_safe); FUZZ_ASAN(krb5_priv, encode_krb5_priv, decode_krb5_priv, krb5_free_priv); FUZZ_ASAN(krb5_priv_enc_part, encode_krb5_enc_priv_part, decode_krb5_enc_priv_part, krb5_free_priv_enc_part); FUZZ_ASAN(krb5_cred, encode_krb5_cred, decode_krb5_cred, krb5_free_cred); FUZZ_ASAN(krb5_cred_enc_part, encode_krb5_enc_cred_part, decode_krb5_enc_cred_part, free_cred_enc_part_whole); FUZZ_ASAN(krb5_error, encode_krb5_error, decode_krb5_error, krb5_free_error); FUZZ_ASAN(krb5_authdata *, encode_krb5_authdata, decode_krb5_authdata, krb5_free_authdata); FUZZ_ASAN(krb5_pa_data *, encode_krb5_padata_sequence, decode_krb5_padata_sequence, krb5_free_pa_data); FUZZ_ASAN(krb5_pa_data *, encode_krb5_typed_data, decode_krb5_typed_data, krb5_free_pa_data); FUZZ_ASAN(krb5_etype_info_entry *, encode_krb5_etype_info, decode_krb5_etype_info, krb5_free_etype_info); FUZZ_ASAN(krb5_etype_info_entry *, encode_krb5_etype_info2, decode_krb5_etype_info2, krb5_free_etype_info); FUZZ_ASAN(krb5_pa_enc_ts, encode_krb5_pa_enc_ts, decode_krb5_pa_enc_ts, krb5_free_pa_enc_ts); FUZZ_ASAN(krb5_enc_data, encode_krb5_enc_data, decode_krb5_enc_data, krb5_free_enc_data); FUZZ_ASAN(krb5_sam_challenge_2, encode_krb5_sam_challenge_2, decode_krb5_sam_challenge_2, krb5_free_sam_challenge_2); FUZZ_ASAN(krb5_sam_challenge_2_body, encode_krb5_sam_challenge_2_body, decode_krb5_sam_challenge_2_body, krb5_free_sam_challenge_2_body); FUZZ_ASAN(krb5_sam_response_2, encode_krb5_sam_response_2, decode_krb5_sam_response_2, krb5_free_sam_response_2); FUZZ_ASAN(krb5_enc_sam_response_enc_2, encode_krb5_enc_sam_response_enc_2, decode_krb5_enc_sam_response_enc_2, krb5_free_enc_sam_response_enc_2); FUZZ_ASAN(krb5_pa_for_user, encode_krb5_pa_for_user, decode_krb5_pa_for_user, krb5_free_pa_for_user); FUZZ_ASAN(krb5_pa_s4u_x509_user, encode_krb5_pa_s4u_x509_user, decode_krb5_pa_s4u_x509_user, krb5_free_pa_s4u_x509_user); FUZZ_ASAN(krb5_ad_kdcissued, encode_krb5_ad_kdcissued, decode_krb5_ad_kdcissued, krb5_free_ad_kdcissued); FUZZ_ASAN(krb5_iakerb_header, encode_krb5_iakerb_header, decode_krb5_iakerb_header, krb5_free_iakerb_header); FUZZ_ASAN(krb5_iakerb_finished, encode_krb5_iakerb_finished, decode_krb5_iakerb_finished, krb5_free_iakerb_finished); FUZZ_ASAN(krb5_fast_response, encode_krb5_fast_response, decode_krb5_fast_response, krb5_free_fast_response); FUZZ_ASAN(krb5_enc_data, encode_krb5_pa_fx_fast_reply, decode_krb5_pa_fx_fast_reply, krb5_free_enc_data); /* Adapted from krb5_encode_test.c */ FUZZ_ASAN(krb5_otp_tokeninfo, encode_krb5_otp_tokeninfo, decode_krb5_otp_tokeninfo, k5_free_otp_tokeninfo); FUZZ_ASAN(krb5_pa_otp_challenge, encode_krb5_pa_otp_challenge, decode_krb5_pa_otp_challenge, k5_free_pa_otp_challenge); FUZZ_ASAN(krb5_pa_otp_req, encode_krb5_pa_otp_req, decode_krb5_pa_otp_req, k5_free_pa_otp_req); FUZZ_ASAN(krb5_data, encode_krb5_pa_otp_enc_req, decode_krb5_pa_otp_enc_req, krb5_free_data); FUZZ_ASAN(krb5_kkdcp_message, encode_krb5_kkdcp_message, decode_krb5_kkdcp_message, free_kkdcp_message); FUZZ_ASAN(krb5_cammac, encode_krb5_cammac, decode_krb5_cammac, k5_free_cammac); FUZZ_ASAN(krb5_secure_cookie, encode_krb5_secure_cookie, decode_krb5_secure_cookie, k5_free_secure_cookie); FUZZ_ASAN(krb5_spake_factor, encode_krb5_spake_factor, decode_krb5_spake_factor, k5_free_spake_factor); FUZZ_ASAN(krb5_pa_spake, encode_krb5_pa_spake, decode_krb5_pa_spake, k5_free_pa_spake); /* Adapted from krb5_decode_test.c */ { krb5_pa_pac_req *pa_pac_req = NULL; if (decode_krb5_pa_pac_req(&data_in, &pa_pac_req) == 0) free(pa_pac_req); } krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_json.c0000664000175000017500000000442615051422640020167 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_json.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for k5_json_decode. */ #include "autoconf.h" #include #include #include #include #define kMinInputLength 2 #define kMaxInputLength 1024 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { krb5_error_code ret; k5_json_value decoded = NULL; char *data_in = NULL, *data_out; if (size < kMinInputLength || size > kMaxInputLength) return 0; data_in = k5memdup0(data, size, &ret); if (data_in == NULL) return 0; ret = k5_json_decode(data_in, &decoded); if (ret) goto cleanup; ret = k5_json_encode(decoded, &data_out); if (!ret) free(data_out); cleanup: free(data_in); k5_json_release(decoded); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_krb5_ticket_seed_corpus/0000775000175000017500000000000015051422640023645 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_krb5_ticket_seed_corpus/gcred.bin0000664000175000017500000000072615051422640025430 0ustar ghudsonghudsona‚Ò0‚Π¡  KRBTEST.COM¢0 ¡0hostfedora£‚›0‚— ¡¢‚‰‚…žîè¸[V uÈiî$"ˆ)$±¯ÉßìQÐD3ñ¸’[ç…Ù‘¢1ÔˆQ>Iä…žé>€k¶±¿Žú1Š}–W‹'|š=Z ©J<Â.‹úï K9”ô¤P7¹P.öJõ'éù³vÍKyÈjêÛè—ËÄŸ)&t|\–…hl¿ ÛùPɪ\Cè•uoÊjÿŽŒO×Ðqx¯ÿ ¸°àâB²^—ÀEŒrÕ…¡rTPýç-!J+¤žÚÚJË.žÃŸ'{:»ŽŒA•ìÞ µJ€&UEú*G¸Sw€Z«úJ…œdî%^~Þ¾tŠUÙ{ü³,VꓟÈR»rc*†éA4H‹ÞAõßY³f[¸7üJlÚþÌS»ª”å×ã­ÔÌÂØGn&ª7˜KÎ|E;˜ó0Å ¥¼Wv‘äÁ‚Wjåzy$ïà~òi¥bßk€1@¶¬²˜#XRþi(Ãn‹Œwx7 òR¢Ï.Ã)OµÅ€F"-±*àFðH‘ËjPýkrb5-1.22.1/src/tests/fuzzing/fuzz_krb5_ticket_seed_corpus/s4u2proxy.bin0000664000175000017500000000077115051422640026243 0ustar ghudsonghudsona‚õ0‚ñ ¡A¢0 ¡0 impersonator2£‚Ç0‚à¡¢‚µ‚±¨Œô‹>?íèÿ×ügÔj¼<¼ò¦ 0ƒ¿Yr@5ìD ‚*£•Æ´ g˜Dƒ‘®Ó0!ÎḴÏG<”lØÆÔ[Fb ûáoXEڦݦk>Cª Ó,NÇä ·hÛÞóÕ8gÞfVÿLçA8óÆ‘m§U°˜äÿΊQ싱› ùKvŒ{ïðøØ ›üQñŸéä×ÀÊõëÝÇ®§Êöæ¥k¬7õ ”x!z¤fàŸ‘“=y倿0­ ²JÑ#¥†PzC°Ëg€)ì_˜Ž´o4É﮾AW|²¿ÓõB=ÈÓÈéÄeIùAúŒH:ðø ’‰ñý2ë«Å÷Z 5x°p6`©`óõ|(ŽíJD̺¿Ô´n²ÿr2¢ 0f×ûùd?ï­xßú)aüäøÝ,v»‡ž14,ó<‚i‡¨hDkœKK Sà© B âæØ{IA&˜¥L°hÈjshè fåE{ÂÝuã·‰|MW²40à!™OˆÎ:´)³êf§úrŠÞ‘áÃê˜XÉíœ×s\oL^ÕÁkrb5-1.22.1/src/tests/fuzzing/fuzz_attrset_seed_corpus/0000775000175000017500000000000015051422640023125 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_attrset_seed_corpus/t_attrset.bin0000664000175000017500000000003415051422640025625 0ustar ghudsonghudson testUserXÿÚ7ùäÊ®I·mX'krb5-1.22.1/src/tests/fuzzing/fuzz_kdc_seed_corpus/0000775000175000017500000000000015051422640022200 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_kdc_seed_corpus/input.bin0000664000175000017500000000004015051422640024023 0ustar ghudsonghudsonI Had Strings, But now i'm free.krb5-1.22.1/src/tests/fuzzing/fuzz_pac_seed_corpus/0000775000175000017500000000000015051422640022202 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_pac_seed_corpus/s4u_pac_regular.bin0000664000175000017500000000116015051422640025751 0ustar ghudsonghudson X ø 8HXÌÌÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ6ýW[YÔÉ6ýW[YÔÿÿÿÿÿÿÿ   v   $(w2k8uw2k8uWDCACMEt ?¥Âé`‘á"‰¡%ÐYÔ w2k8u(w2k8u@abcACME.COMˆ@„z|€tãjkvÿÿÿ—Ò9ô¸²S®wÛlÔ=krb5-1.22.1/src/tests/fuzzing/fuzz_pac_seed_corpus/saved_pac.bin0000664000175000017500000000116015051422640024617 0ustar ghudsonghudsonØH @XÌÌÌÌÈ0ߦËO}ÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ #include #include #define kMinInputLength 2 #define kMaxInputLength 1024 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { gss_OID doid; OM_uint32 minor, ret_flags, time_rec; gss_name_t client = GSS_C_NO_NAME; gss_ctx_id_t context = GSS_C_NO_CONTEXT; gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL; gss_buffer_desc data_in, data_out = GSS_C_EMPTY_BUFFER; if (size < kMinInputLength || size > kMaxInputLength) return 0; data_in.length = size; data_in.value = (void *)data; gss_accept_sec_context(&minor, &context, GSS_C_NO_CREDENTIAL, &data_in, GSS_C_NO_CHANNEL_BINDINGS, &client, &doid, &data_out, &ret_flags, &time_rec, &deleg_cred); gss_release_buffer(&minor, &data_out); if (context != GSS_C_NO_CONTEXT) gss_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_chpw.c0000664000175000017500000000413615051422640020155 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/fuzzing/fuzz_chpw.c */ /* * Copyright (C) 2024 by Arjun. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Fuzzing harness implementation for krb5_chpw_message. */ #include "autoconf.h" #include #define kMinInputLength 2 #define kMaxInputLength 512 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { char *msg; krb5_data data_in; krb5_context context; if (size < kMinInputLength || size > kMaxInputLength) return 0; data_in = make_data((void *)data, size); if (krb5_init_context(&context) != 0) return 0; if (krb5_chpw_message(context, &data_in, &msg) == 0) free(msg); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/0000775000175000017500000000000015051422640022220 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_kdc_dh_key_info_81.bin0000664000175000017500000000004715051422640027637 0ustar ghudsonghudson0%   krb5data¡*¢19940610060317Zkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_iakerb_finished_56.bin0000664000175000017500000000002315051422640030565 0ustar ghudsonghudson0¡0  ¡1234krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_ad_kdcissued_54.bin0000664000175000017500000000014715051422640030106 0ustar ghudsonghudson0e 0  ¡1234¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£$0"0 ¡foobar0 ¡foobarkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_tgs_req_21.bin0000664000175000017500000000043015051422640026172 0ustar ghudsonghudsonl‚0‚¡¢ ¤‚0ÿ þܺ˜¢ATHENA.MIT.EDU¥19940610060317Z§*¨0«¿0¼a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagea\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_fx_fast_reply_59.bin0000664000175000017500000000005315051422640030067 0ustar ghudsonghudson )0' %0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_error_34.bin0000664000175000017500000000027515051422640026615 0ustar ghudsonghudson~º0· ¡¢19940610060317Z£â@¤19940610060317Z¥â@¦<§ATHENA.MIT.EDU¨0 ¡0hftsaiextra©ATHENA.MIT.EDUª0 ¡0hftsaiextra« krb5data¬ krb5datakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_tgs_rep_12.bin0000664000175000017500000000030515051422640026172 0ustar ghudsonghudsonmÂ0¿ ¡ £ATHENA.MIT.EDU¤0 ¡0hftsaiextra¥^a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test message¦%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_kkdcp_message_67.bin0000664000175000017500000000100015051422640027332 0ustar ghudsonghudson0‚ü ‚ì‚èj‚ä0‚à¡¢ £&0$0¡ ¢ pa-data0¡ ¢ pa-data¤‚ª0‚¦ þܺ˜¡0 ¡0hftsaiextra¢ATHENA.MIT.EDU£0 ¡0hftsaiextra¤19940610060317Z¥19940610060317Z¦19940610060317Z§*¨0© 00  ¡Ð#0  ¡Ð#ª%0# ¡¢krbASN.1 test message«¿0¼a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagea\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test message¡ krb5datakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_tgs_rep_11.bin0000664000175000017500000000035515051422640026176 0ustar ghudsonghudsonmê0ç ¡ ¢&0$0¡ ¢ pa-data0¡ ¢ pa-data£ATHENA.MIT.EDU¤0 ¡0hftsaiextra¥^a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test message¦%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_spake_73.bin0000664000175000017500000000001615051422640026320 0ustar ghudsonghudson  0  0krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_spake_74.bin0000664000175000017500000000005715051422640026326 0ustar ghudsonghudson¡-0+ ¡ T value¢00 0 ¡fdatakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_etype_info_40.bin0000664000175000017500000000006515051422640027617 0ustar ghudsonghudson030 ¡  Morton's #00 0 ¡  Morton's #2krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_safe_27.bin0000664000175000017500000000010015051422640025444 0ustar ghudsonghudsont>0< ¡¢0  krb5data¤0  ¡Ð#£0  ¡1234krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_enc_data_47.bin0000664000175000017500000000005015051422640026272 0ustar ghudsonghudson0& ¡ÿ¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_pk_as_rep_78.bin0000664000175000017500000000005215051422640027165 0ustar ghudsonghudson (0&€krb5data¡ krb5data¢0   krb5datakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_priv_28.bin0000664000175000017500000000006515051422640025521 0ustar ghudsonghudsonu301 ¡£%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_kdc_req_body_24.bin0000664000175000017500000000040215051422640030100 0ustar ghudsonghudson0ÿ þܺ˜¢ATHENA.MIT.EDU¥19940610060317Z§*¨0«¿0¼a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagea\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_s4u_x509_user_54.bin0000664000175000017500000000015215051422640027553 0ustar ghudsonghudson0h U0S Êš¡0 ¡0hftsaiextra¢ATHENA.MIT.EDU£pa_s4u_x509_user¤€¡0  ¡1234krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_ap_rep_enc_part_16.bin0000664000175000017500000000003615051422640030600 0ustar ghudsonghudson{0 19940610060317Z¡â@krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_etype_info2_44.bin0000664000175000017500000000004215051422640027700 0ustar ghudsonghudson0 0 ¡  Morton's #0¢s2k: 0krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_pk_as_rep_79.bin0000664000175000017500000000001215051422640027162 0ustar ghudsonghudsonkrb5datakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_enc_ts (no usec)_45.bin0000664000175000017500000000002515051422640030125 0ustar ghudsonghudson0 19940610060317Zkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_as_rep_10.bin0000664000175000017500000000030515051422640026721 0ustar ghudsonghudsonkÂ0¿ ¡ £ATHENA.MIT.EDU¤0 ¡0hftsaiextra¥^a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test message¦%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_otp_req_64.bin0000664000175000017500000000005615051422640026672 0ustar ghudsonghudson0,€¢# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_sam_challenge_2_body_50.bin0000664000175000017500000000014615051422640030554 0ustar ghudsonghudson0d *¡€¢  type name¤challenge label¥challenge ipse¦response_prompt ipse¨T2©krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_fast_response_57.bin0000664000175000017500000000024215051422640030336 0ustar ghudsonghudson0Ÿ &0$0¡ ¢ pa-data0¡ ¢ pa-data¡0 ¡ 12345678¢[0Y 19940610060317Z¡â@¢ATHENA.MIT.EDU£0 ¡0hftsaiextra¤0  ¡1234£*krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_sp80056a_other_info_83.bin0000664000175000017500000000020415051422640030137 0ustar ghudsonghudson00  *†H†÷ 200. ATHENA.MIT.EDU¡0 ¡0hftsaiextra¡200. ATHENA.MIT.EDU¡0 ¡0hftsaiextra¢ krb5datakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_for_user_53.bin0000664000175000017500000000011515051422640027037 0ustar ghudsonghudson0K 0 ¡0hftsaiextra¡ATHENA.MIT.EDU¢0  ¡1234£ krb5datakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_reply_key_pack_82.bin0000664000175000017500000000005015051422640027534 0ustar ghudsonghudson0& 0 ¡ 12345678¡0  ¡1234krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_cammac_69.bin0000664000175000017500000000036515051422640025772 0ustar ghudsonghudson0ò 00  ¡ad10  ¡ad2¡=0; 0 ¡0hftsaiextra¡¢£0 ¡ cksumkdc¢=0; 0 ¡0hftsaiextra¡¢£0 ¡ cksumsvc£R0P0£0 ¡cksum109 0 ¡0hftsaiextra¡¢£0 ¡cksum2krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_auth_pack_80.bin0000664000175000017500000000021015051422640026466 0ustar ghudsonghudson0… 503 â@¡19940610060317Z¢*£1234¤ krb5data¡pvalue¢$0"0 *†H†÷params0  *†H†÷£ krb5data¤00   krb5datakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_spake_75.bin0000664000175000017500000000006615051422640026327 0ustar ghudsonghudson¢402  S value¡%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_authenticator_2.bin0000664000175000017500000000012115051422640030237 0ustar ghudsonghudsonbO0M ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra¤â@¥19940610060317Zkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/decode_enc_tkt_part_30.bin0000664000175000017500000000024715051422640027177 0ustar ghudsonghudsonc¤0¡ þܺ¡0 ¡ 12345678¢ATHENA.MIT.EDU£0 ¡0hftsaiextra¤.0, ¡%#EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS.¥19940610060317Z§19940610060317Zkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/decode_encryption_key_15.bin0000664000175000017500000000003415051422640027561 0ustar ghudsonghudson0 ¡ 12345678¢0 krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/decode_encryption_key_22.bin0000664000175000017500000000002415051422640027556 0ustar ghudsonghudson0 ÿ¡ 12345678krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_cred_31.bin0000664000175000017500000000037115051422640026373 0ustar ghudsonghudsonvö0ó ¡¢¿0¼a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagea\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test message£%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_enc_cred_part_32.bin0000664000175000017500000000104715051422640030250 0ustar ghudsonghudson}‚#0‚ ‚Ú0‚Ö0è 0 ¡ 12345678¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£þܺ˜¤19940610060317Z¥19940610060317Z¦19940610060317Z§19940610060317Z¨ATHENA.MIT.EDU©0 ¡0hftsaiextraª 00  ¡Ð#0  ¡Ð#0è 0 ¡ 12345678¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£þܺ˜¤19940610060317Z¥19940610060317Z¦19940610060317Z§19940610060317Z¨ATHENA.MIT.EDU©0 ¡0hftsaiextraª 00  ¡Ð#0  ¡Ð#¡*¢19940610060317Z£â@¤0  ¡Ð#¥0  ¡Ð#krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_enc_kdc_rep_part_8.bin0000664000175000017500000000026515051422640030666 0ustar ghudsonghudsonz²0¯ 0 ¡ 12345678¡6040 û¡19940610060317Z0 û¡19940610060317Z¢*¤þ\º˜¥19940610060317Z§19940610060317Z©ATHENA.MIT.EDUª0 ¡0hftsaiextrakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_safe_26.bin0000664000175000017500000000016015051422640025451 0ustar ghudsonghudsontn0l ¡¢O0M  krb5data¡19940610060317Z¢â@£¤0  ¡Ð#¥0  ¡Ð#£0  ¡1234krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/decode_authenticator_3.bin0000664000175000017500000000024515051422640027312 0ustar ghudsonghudsonb¢0Ÿ ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£0  ¡1234¤â@¥19940610060317Z¦0 ¡ 12345678§ÿ¨$0"0 ¡foobar0 ¡foobarkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_otp_challenge_63.bin0000664000175000017500000000025015051422640030020 0ustar ghudsonghudson0¥€maxnonce testservice¢}0€0r€w Examplecorp‚hark!ƒ „… yourtoken†(urn:ietf:params:xml:ns:keyprov:pskc:hotp§0  `†He0+ˆèƒkeysalt„1234krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_enc_priv_part_30.bin0000664000175000017500000000004115051422640030302 0ustar ghudsonghudson|0  krb5data¤0  ¡Ð#krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_spake_76.bin0000664000175000017500000000004715051422640026327 0ustar ghudsonghudson£%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_etype_info_41.bin0000664000175000017500000000003015051422640027610 0ustar ghudsonghudson00 ¡  Morton's #0krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_otp_tokeninfo_61.bin0000664000175000017500000000016415051422640027414 0ustar ghudsonghudson0r€w Examplecorp‚hark!ƒ „… yourtoken†(urn:ietf:params:xml:ns:keyprov:pskc:hotp§0  `†He0+ˆèkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_tgs_rep_13.bin0000664000175000017500000000024015051422640027114 0ustar ghudsonghudsonn0š ¡¢þܺ˜£^a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test message¤%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_sam_response_2_51.bin0000664000175000017500000000010415051422640027446 0ustar ghudsonghudson0B +¡€¢  track data£0 ¡ 6¢ nonce or sad¤T2krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_tgs_req_23.bin0000664000175000017500000000065215051422640027125 0ustar ghudsonghudson0‚¦ þܺ¡0 ¡0hftsaiextra¢ATHENA.MIT.EDU£0 ¡0hftsaiextra¤19940610060317Z¥19940610060317Z¦19940610060317Z§*¨0© 00  ¡Ð#0  ¡Ð#ª%0# ¡¢krbASN.1 test message«¿0¼a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagea\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_enc_cred_part_33.bin0000664000175000017500000000042215051422640030245 0ustar ghudsonghudson}‚0‚  ‚0‚0 0 ¡ 123456780è 0 ¡ 12345678¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£þܺ˜¤19940610060317Z¥19940610060317Z¦19940610060317Z§19940610060317Z¨ATHENA.MIT.EDU©0 ¡0hftsaiextraª 00  ¡Ð#0  ¡Ð#krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_spake_factor_71.bin0000664000175000017500000000000715051422640027174 0ustar ghudsonghudson0 krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_pa_otp_req_65.bin0000664000175000017500000000027415051422640026675 0ustar ghudsonghudson0¹€`nonce¢# ¡¢krbASN.1 test message£  `†He„è…frogs† myfirstpin‡hark!ˆ19940610060317Z‰346Š‹ yourtokenŒ(urn:ietf:params:xml:ns:keyprov:pskc:hotp Examplecorpkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_enc_tkt_part_5.bin0000664000175000017500000000043015051422640030050 0ustar ghudsonghudsonc‚0‚ þܺ˜¡0 ¡ 12345678¢ATHENA.MIT.EDU£0 ¡0hftsaiextra¤.0, ¡%#EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS.¥19940610060317Z¦19940610060317Z§19940610060317Z¨19940610060317Z© 00  ¡Ð#0  ¡Ð#ª$0"0 ¡foobar0 ¡foobarkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_ticket_3.bin0000664000175000017500000000013615051422640025734 0ustar ghudsonghudsona\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_secure_cookie_70.bin0000664000175000017500000000005615051422640027355 0ustar ghudsonghudson0,-ø%0$0¡ ¢ pa-data0¡ ¢ pa-datakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_cammac_68.bin0000664000175000017500000000002415051422640025761 0ustar ghudsonghudson0 00  ¡ad1krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/decode_authenticator_4.bin0000664000175000017500000000025015051422640027307 0ustar ghudsonghudsonb¥0¢ ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£0  ¡1234¤â@¥19940610060317Z¦0 ¡ 12345678§ÿÿÿÿ¨$0"0 ¡foobar0 ¡foobarkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_iakerb_header_55.bin0000664000175000017500000000003215051422640030223 0ustar ghudsonghudson0¡ krb5data¢ krb5datakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/decode_authenticator_6.bin0000664000175000017500000000024715051422640027317 0ustar ghudsonghudsonb¤0¡ ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£0  ¡1234¤â@¥19940610060317Z¦0 ¡ 12345678§ÿÿÿÿ¨$0"0 ¡foobar0 ¡foobarkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_authdata_36.bin0000664000175000017500000000004415051422640027253 0ustar ghudsonghudson0"0 ¡foobar0 ¡foobarkrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_tgs_req_20.bin0000664000175000017500000000075015051422640026176 0ustar ghudsonghudsonl‚ä0‚à¡¢ £&0$0¡ ¢ pa-data0¡ ¢ pa-data¤‚ª0‚¦ þܺ¡0 ¡0hftsaiextra¢ATHENA.MIT.EDU£0 ¡0hftsaiextra¤19940610060317Z¥19940610060317Z¦19940610060317Z§*¨0© 00  ¡Ð#0  ¡Ð#ª%0# ¡¢krbASN.1 test message«¿0¼a\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagea\0Z ¡ATHENA.MIT.EDU¢0 ¡0hftsaiextra£%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_enc_priv_part_29.bin0000664000175000017500000000012115051422640030311 0ustar ghudsonghudson|O0M  krb5data¡19940610060317Z¢â@£¤0  ¡Ð#¥0  ¡Ð#krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/decode_encryption_key_21.bin0000664000175000017500000000002415051422640027555 0ustar ghudsonghudson0 ÿ¡ 12345678krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_error_35.bin0000664000175000017500000000014215051422640026607 0ustar ghudsonghudson~`0^ ¡£â@¤19940610060317Z¥â@¦<©ATHENA.MIT.EDUª0 ¡0hftsaiextrakrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_etype_info2_43.bin0000664000175000017500000000012315051422640027677 0ustar ghudsonghudson0Q0 ¡  Morton's #0¢s2k: 00 ¢s2k: 10 ¡  Morton's #2¢s2k: 2krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_sam_challenge_2_49.bin0000664000175000017500000000004415051422640027544 0ustar ghudsonghudson0"  0  challenge¡00  ¡1234krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_padata_sequence_38.bin0000664000175000017500000000000215051422640027653 0ustar ghudsonghudson0krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_ap_req_14.bin0000664000175000017500000000006515051422640026726 0ustar ghudsonghudsono301 ¡¢%0# ¡¢krbASN.1 test messagekrb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/decode_encryption_key_24.bin0000664000175000017500000000002615051422640027562 0ustar ghudsonghudson0 ÿÿÿ¡ 12345678krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/decode_fail_encryption_key_16.bin0000664000175000017500000000002515051422640030555 0ustar ghudsonghudson0€ ¡ 12345678krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_as_req_19.bin0000664000175000017500000000015315051422640026734 0ustar ghudsonghudsonji0g¡¢ ¤[0Y þܺ¢ATHENA.MIT.EDU£0 ¡0hftsaiextra¥19940610060317Z§*¨0krb5-1.22.1/src/tests/fuzzing/fuzz_asn_seed_corpus/encode_krb5_enc_tkt_part_7.bin0000664000175000017500000000042215051422640030053 0ustar ghudsonghudsonz‚0‚  0 ¡ 12345678¡6040 û¡19940610060317Z0 û¡19940610060317Z¢*£19940610060317Z¤þܺ˜¥19940610060317Z¦19940610060317Z§19940610060317Z¨19940610060317Z©ATHENA.MIT.EDUª0 ¡0hftsaiextra« 00  ¡Ð#0  ¡Ð#krb5-1.22.1/src/tests/fuzzing/fuzz_chpw_seed_corpus/0000775000175000017500000000000015051422640022400 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_chpw_seed_corpus/result_ad_all.bin0000664000175000017500000000003615051422640025703 0ustar ghudsonghudson É*iÀkrb5-1.22.1/src/tests/fuzzing/fuzz_chpw_seed_corpus/result_ad_history.bin0000664000175000017500000000003615051422640026634 0ustar ghudsonghudson krb5-1.22.1/src/tests/fuzzing/fuzz_chpw_seed_corpus/result_utf8.bin0000664000175000017500000000002715051422640025355 0ustar ghudsonghudsonThis is a valid string.krb5-1.22.1/src/tests/fuzzing/fuzz_chpw_seed_corpus/result_ad_age.bin0000664000175000017500000000003615051422640025667 0ustar ghudsonghudson’TÓ€krb5-1.22.1/src/tests/fuzzing/fuzz_chpw_seed_corpus/result_ad_complex.bin0000664000175000017500000000003615051422640026602 0ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_chpw_seed_corpus/result_invalid_utf8.bin0000664000175000017500000000002315051422640027057 0ustar ghudsonghudsonThis is not valid.krb5-1.22.1/src/tests/fuzzing/fuzz_chpw_seed_corpus/result_ad_length.bin0000664000175000017500000000003615051422640026414 0ustar ghudsonghudson krb5-1.22.1/src/tests/fuzzing/fuzz_gss_seed_corpus/0000775000175000017500000000000015051422640022233 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_gss_seed_corpus/realm_query.bin0000664000175000017500000000002215051422640025244 0ustar ghudsonghudson`+0¡ krb5-1.22.1/src/tests/fuzzing/fuzz_gss_seed_corpus/gss_accept_sec_context_spnego.bin0000664000175000017500000000123015051422640031005 0ustar ghudsonghudson`‚”+ ‚ˆ0‚„ #0! *†H†÷ + +¢‚[‚W`‚S *†H†÷n‚B0‚> ¡¢ £‚^a‚Z0‚V ¡VIRT¢$0" ¡0hostkrb.research.virt£‚0‚ ¡¢‚ ‚ ÕÌÈ)ë ™©,r|yÖ fž#¾oâšÊßzu8ôäøã&:£¤l<¦‘QŽB²Á[Wœ{…HÜ} $¡w@wh„[ :× “qªÂKfÒ…{71Èq@üTòg3 h·ŠdIV{ &5®+ìcÒqËÔÊÈ¢ÑAúYˆÚ›5².à(¤¸.æl¡ç¾O]ŽÖ‘ïòÌAoŒú>ÔH¯afdûr¥‘£Ø^ ¢¥ˆJ²h\‹ZâI«ãןà$Ûúí£Ìáî)5LÊ“[êËêý¨šÄ}næXa‘KÝ …D“gôd¤ÔÝ”öU‘[Þ€b³ãyP¾|Cá!/\\·BgâåÜ‹gÐ9]¤Æ0ࢻ¸ÿ7<¹3ôØ£,¦ŠZ<2ÉìF·8Ø'«øŸî6F…yâ ¤¤“Z/œüÏBÔÇ›H¦Äƒ¡YvõÔz¥Ü`d|8¤Ê[6/ÍÞt3ESñ“çÌùÛ&Ù!'¾3€95Ò­‹šnXÓßÀ¾:ý» Ÿú™ò¼`O“ΞÏ]šÎè4ßKñÑŒÈVlV #`Qmc‚'Rr1V ³eHNš½I÷{u:?Æéùw×6žkrb5-1.22.1/src/tests/fuzzing/fuzz_gss_seed_corpus/establish_contexts_ex.bin0000664000175000017500000000072515051422640027332 0ustar ghudsonghudson`‚Ñ+ ‚Å0‚Á 0  +‚7¢‚­‚©NEGOEXTS`€pHÜ6‡ø™:ùÎCT¤nšaЄ‰uÖ~rV_CÃ.>wzþo.ùp‘'…ç÷Íâ``i…¢À¬fi„°Ñ¨,NEGOEXTS@ApHÜ6‡ø™:ùÎCT¤ni…¢À¬f@XNEGOEXTS@ApHÜ6‡ø™:ùÎCT¤ni„°Ñ¨,@XNEGOEXTS@KpHÜ6‡ø™:ùÎCT¤ni…¢À¬f@ ` i…¢À¬fNEGOEXTSP\pHÜ6‡ø™:ùÎCT¤ni…¢À¬fP ({ñ:DST‡Ø0krb5-1.22.1/src/tests/fuzzing/fuzz_gss_seed_corpus/gss_accept_sec_context_kerberos.bin0000664000175000017500000000112715051422640031333 0ustar ghudsonghudson`‚S *†H†÷n‚B0‚> ¡¢ £‚^a‚Z0‚V ¡VIRT¢$0" ¡0hostkrb.research.virt£‚0‚ ¡¢‚ ‚ 7zsÑtžÉÛ4¿Ê1Ùç¸q§ø(íáf¼§Æ=Œ¶y³”_ï;5bw…à7’†áØF1LgæõŒì<@½~q&Ej‡}ØØzê~ ùÄ"w¢ ´F.eDé‚5Äî)ŽEëLv_*ˆÿ½îP᢯TVb‹HÔצžLÙºs ÷¼ #7¨Ûª+_#»Âá3{!“ÿ12ù0—SF¤.åOªnÀ>wHPö˜F”6“^G§h\ø¬H+#°©?™öB pfõ¶µ‡T>°ëL”øé½¬…lŽfÖP—rŠ”!垘›ûnesåuE¬–BSbô 6þí*JýU6Ûò¤Æ0ࢻ¸ \Pã†oyÑæüú«²¿knkÃË‚†rØ_×°’-$‚= bÝEüÒ¶¶…ªˆÉhŠÀÁ ¶%¼T—hñWNWH@ÅcM%ô©ÑÛn¡aŠÅ¥ZÏt–Êåž©üf››q)ÉäNØÛ{–ÝàMë䦮ÜDKJ‡£_y´D³@?tph$âà¾i™!h0¾ê.<ŒqÿçÜa†XÛ8_c²‡üæ=—'^͉%.f®p2Dkrb5-1.22.1/src/tests/fuzzing/fuzz_gss_seed_corpus/start_accept_context.bin0000664000175000017500000000032415051422640027144 0ustar ghudsonghudson`Ñ+0¡  KRBTEST.COMj³0°¡¢ £00 ¡–¢0 ¡•¢¤‡0„ ¡0 ¡0user¢  KRBTEST.COM£ 0 ¡0krbtgt KRBTEST.COM¥20240509062805Z§+¹m£¨0krb5-1.22.1/src/tests/fuzzing/fuzz_aes_seed_corpus/0000775000175000017500000000000015051422640022207 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/fuzzing/fuzz_aes_seed_corpus/input.bin0000664000175000017500000000010015051422640024027 0ustar ghudsonghudsonI would like the General Gau's Chicken, please, and wonton soup.krb5-1.22.1/src/tests/t_errmsg.py0000775000175000017500000000233315051422640016472 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(create_kdb=False) # Test err_fmt, using klist -c to induce errors. fmt1 = 'FOO Error: %M (see http://localhost:1234/%C for more information)' conf1 = {'libdefaults': {'err_fmt': fmt1}} e1 = realm.special_env('fmt1', False, krb5_conf=conf1) out = realm.run([klist, '-c', 'testdir/xx/yy'], env=e1, expected_code=1) if out != ('klist: FOO Error: No credentials cache found (filename: ' 'testdir/xx/yy) (see http://localhost:1234/-1765328189 for more ' 'information)\n'): fail('err_fmt expansion failed') conf2 = {'libdefaults': {'err_fmt': '%M - %C'}} e2 = realm.special_env('fmt2', False, krb5_conf=conf2) out = realm.run([klist, '-c', 'testdir/xx/yy'], env=e2, expected_code=1) if out != ('klist: No credentials cache found (filename: testdir/xx/yy) - ' '-1765328189\n'): fail('err_fmt expansion failed') conf3 = {'libdefaults': {'err_fmt': '%%%M %-% %C%'}} e3 = realm.special_env('fmt3', False, krb5_conf=conf3) out = realm.run([klist, '-c', 'testdir/xx/yy'], env=e3, expected_code=1) if out != ('klist: %No credentials cache found (filename: testdir/xx/yy) %-% ' '-1765328189%\n'): fail('err_fmt expansion failed') success('error message tests') krb5-1.22.1/src/tests/t_keydata.py0000775000175000017500000000352015051422640016614 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(create_user=False, create_host=False) # Create a principal with no keys. realm.run([kadminl, 'addprinc', '-nokey', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg='Number of keys: 0') # Change its password and check the resulting kvno. realm.run([kadminl, 'cpw', '-pw', 'password', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg='vno 1') # Delete all of its keys. realm.run([kadminl, 'purgekeys', '-all', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg='Number of keys: 0') # Randomize its keys and check the resulting kvno. realm.run([kadminl, 'cpw', '-randkey', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg='vno 1') # Return true if patype appears to have been received in a hint list # from a KDC error message, based on the trace file fname. def preauth_type_received(trace, patype): found = False for line in trace.splitlines(): if 'Processing preauth types:' in line: ind = line.find('types:') patypes = line[ind + 6:].split(', ') if str(patype) in patypes: found = True return found # Make sure the KDC doesn't offer encrypted timestamp for a principal # with no keys. realm.run([kadminl, 'purgekeys', '-all', 'user']) realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) out, trace = realm.run([kinit, 'user'], expected_code=1, return_trace=True) if preauth_type_received(trace, 2): fail('encrypted timestamp') # Make sure it doesn't offer encrypted challenge either. realm.run([kadminl, 'addprinc', '-pw', 'fast', 'armor']) realm.kinit('armor', 'fast') out, trace = realm.run([kinit, '-T', realm.ccache, 'user'], expected_code=1, return_trace=True) if preauth_type_received(trace, 138): fail('encrypted challenge') success('Key data tests') krb5-1.22.1/src/tests/forward.c0000664000175000017500000000652515051422640016112 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/forward.c - test harness for getting forwarded creds */ /* * Copyright (C) 2016 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This test program overwrites the default credential cache with a forwarded * TGT obtained using the TGT presently in the cache. */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(void) { krb5_ccache cc; krb5_creds mcred, tgt, *fcred; krb5_principal client, tgtprinc; krb5_flags options; /* Open the default ccache and get the client and TGT principal names. */ check(krb5_init_context(&ctx)); check(krb5_cc_default(ctx, &cc)); check(krb5_cc_get_principal(ctx, cc, &client)); check(krb5_build_principal_ext(ctx, &tgtprinc, client->realm.length, client->realm.data, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, client->realm.length, client->realm.data, 0)); /* Fetch the TGT credential. */ memset(&mcred, 0, sizeof(mcred)); mcred.client = client; mcred.server = tgtprinc; check(krb5_cc_retrieve_cred(ctx, cc, 0, &mcred, &tgt)); /* Get a forwarded TGT. */ mcred.times = tgt.times; mcred.times.starttime = 0; options = (tgt.ticket_flags & KDC_TKT_COMMON_MASK) | KDC_OPT_FORWARDED; check(krb5_get_cred_via_tkt(ctx, &tgt, options, NULL, &mcred, &fcred)); /* Reinitialize the default ccache with the forwarded TGT. */ check(krb5_cc_initialize(ctx, cc, client)); check(krb5_cc_store_cred(ctx, cc, fcred)); krb5_free_creds(ctx, fcred); krb5_free_cred_contents(ctx, &tgt); krb5_free_principal(ctx, tgtprinc); krb5_free_principal(ctx, client); krb5_cc_close(ctx, cc); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/t_crossrealm.py0000775000175000017500000002070515051422640017350 0ustar ghudsonghudson# Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * def test_kvno(r, princ, test, env=None): r.run([kvno, princ], env=env, expected_msg=princ) def stop(*realms): for r in realms: r.stop() # Verify that the princs appear as the service principals in the klist # output for the realm r, in order. def check_klist(r, princs): out = r.run([klist]) count = 0 seen_header = False for l in out.split('\n'): if l.startswith('Valid starting'): seen_header = True continue if not seen_header or l == '': continue if count >= len(princs): fail('too many entries in klist output') svcprinc = l.split()[4] if svcprinc != princs[count]: fail('saw service princ %s in klist output, expected %s' % (svcprinc, princs[count])) count += 1 if count != len(princs): fail('not enough entries in klist output') def tgt(r1, r2): return 'krbtgt/%s@%s' % (r1.realm, r2.realm) # Basic two-realm test with cross TGTs in both directions. mark('two realms') r1, r2 = cross_realms(2) test_kvno(r1, r2.host_princ, 'basic r1->r2') check_klist(r1, (tgt(r1, r1), tgt(r2, r1), r2.host_princ)) test_kvno(r2, r1.host_princ, 'basic r2->r1') check_klist(r2, (tgt(r2, r2), tgt(r1, r2), r1.host_princ)) stop(r1, r2) # Test the KDC domain walk for hierarchically arranged realms. The # client in A.X will ask for a cross TGT to B.X, but A.X's KDC only # has a TGT for the intermediate realm X, so it will return that # instead. The client will use that to get a TGT for B.X. mark('hierarchical realms') r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), args=({'realm': 'A.X'}, {'realm': 'X'}, {'realm': 'B.X'})) test_kvno(r1, r3.host_princ, 'KDC domain walk') check_klist(r1, (tgt(r1, r1), r3.host_princ)) # Test start_realm in this setup. r1.run([kvno, '--out-cache', r1.ccache, r2.krbtgt_princ]) r1.run([klist, '-C'], expected_msg='config: start_realm = X') msgs = ('Requesting TGT krbtgt/B.X@X using TGT krbtgt/X@X', 'Received TGT for service realm: krbtgt/B.X@X') r1.run([kvno, r3.host_princ], expected_trace=msgs) stop(r1, r2, r3) # Test client capaths. The client in A will ask for a cross TGT to D, # but A's KDC won't have it and won't know an intermediate to return. # The client will walk its A->D capaths to get TGTs for B, then C, # then D. The KDCs for C and D need capaths settings to avoid failing # transited checks, including a capaths for A->C. mark('client capaths') capaths = {'capaths': {'A': {'D': ['B', 'C'], 'C': 'B'}}} r1, r2, r3, r4 = cross_realms(4, xtgts=((0,1), (1,2), (2,3)), args=({'realm': 'A'}, {'realm': 'B'}, {'realm': 'C', 'krb5_conf': capaths}, {'realm': 'D', 'krb5_conf': capaths})) r1client = r1.special_env('client', False, krb5_conf=capaths) test_kvno(r1, r4.host_princ, 'client capaths', r1client) check_klist(r1, (tgt(r1, r1), tgt(r2, r1), tgt(r3, r2), tgt(r4, r3), r4.host_princ)) stop(r1, r2, r3, r4) # Test KDC capaths. The KDCs for A and B have appropriate capaths # settings to determine intermediate TGTs to return, but the client # has no idea. mark('kdc capaths') capaths = {'capaths': {'A': {'D': ['B', 'C'], 'C': 'B'}, 'B': {'D': 'C'}}} r1, r2, r3, r4 = cross_realms(4, xtgts=((0,1), (1,2), (2,3)), args=({'realm': 'A', 'krb5_conf': capaths}, {'realm': 'B', 'krb5_conf': capaths}, {'realm': 'C', 'krb5_conf': capaths}, {'realm': 'D', 'krb5_conf': capaths})) r1client = r1.special_env('client', False, krb5_conf={'capaths': None}) test_kvno(r1, r4.host_princ, 'KDC capaths', r1client) check_klist(r1, (tgt(r1, r1), r4.host_princ)) stop(r1, r2, r3, r4) # A capaths value of '.' should enforce direct cross-realm, with no # intermediate. mark('direct cross-realm enforcement') capaths = {'capaths': {'A.X': {'B.X': '.'}}} r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), args=({'realm': 'A.X', 'krb5_conf': capaths}, {'realm': 'X'}, {'realm': 'B.X'})) r1.run([kvno, r3.host_princ], expected_code=1, expected_msg='Server krbtgt/B.X@A.X not found in Kerberos database') stop(r1, r2, r3) # Test transited error. The KDC for C does not recognize B as an # intermediate realm for A->C, so it refuses to issue a service # ticket. mark('transited error (three realms)') capaths = {'capaths': {'A': {'C': 'B'}}} r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), args=({'realm': 'A', 'krb5_conf': capaths}, {'realm': 'B'}, {'realm': 'C'})) r1.run([kvno, r3.host_princ], expected_code=1, expected_msg='KDC policy rejects request') check_klist(r1, (tgt(r1, r1), tgt(r3, r2))) stop(r1, r2, r3) # Test server transited checking. The KDC for C recognizes B as an # intermediate realm for A->C, but the server environment does not. # The server should honor the ticket if the transited-policy-checked # flag is set, but not if it isn't. (It is only possible for our KDC # to issue a ticket without the transited-policy-checked flag with # reject_bad_transit=false.) mark('server transited checking') capaths = {'capaths': {'A': {'C': 'B'}}} noreject = {'realms': {'$realm': {'reject_bad_transit': 'false'}}} r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), args=({'realm': 'A', 'krb5_conf': capaths}, {'realm': 'B'}, {'realm': 'C', 'krb5_conf': capaths, 'kdc_conf': noreject})) r3server = r3.special_env('server', False, krb5_conf={'capaths': None}) # Process a ticket with the transited-policy-checked flag set. shutil.copy(r1.ccache, r1.ccache + '.copy') r1.run(['./gcred', 'principal', r3.host_princ]) os.rename(r1.ccache, r3.ccache) r3.run(['./rdreq', r3.host_princ], env=r3server, expected_msg='0 success') # Try again with the transited-policy-checked flag unset. os.rename(r1.ccache + '.copy', r1.ccache) r1.run(['./gcred', '-t', 'principal', r3.host_princ]) os.rename(r1.ccache, r3.ccache) r3.run(['./rdreq', r3.host_princ], env=r3server, expected_msg='43 Illegal cross-realm ticket') stop(r1, r2, r3) # Test a four-realm scenario. This test used to result in an "Illegal # cross-realm ticket" error as the KDC for D would refuse to process # the cross-realm ticket from C. Now that we honor the # transited-policy-checked flag in krb5_rd_req(), it instead issues a # policy error as in the three-realm scenario. mark('transited error (four realms)') capaths = {'capaths': {'A': {'D': ['B', 'C'], 'C': 'B'}, 'B': {'D': 'C'}}} r1, r2, r3, r4 = cross_realms(4, xtgts=((0,1), (1,2), (2,3)), args=({'realm': 'A', 'krb5_conf': capaths}, {'realm': 'B', 'krb5_conf': capaths}, {'realm': 'C', 'krb5_conf': capaths}, {'realm': 'D'})) r1.run([kvno, r4.host_princ], expected_code=1, expected_msg='KDC policy rejects request') check_klist(r1, (tgt(r1, r1), tgt(r4, r3))) stop(r1, r2, r3, r4) success('Cross-realm tests') krb5-1.22.1/src/tests/t_mkey.py0000775000175000017500000003605115051422640016144 0ustar ghudsonghudsonfrom k5test import * import random import re import struct # Convenience constants for use as expected enctypes. defetype is the # default enctype for master keys. aes256 = 'aes256-cts-hmac-sha1-96' aes128 = 'aes128-cts-hmac-sha1-96' des3 = 'des3-cbc-sha1' defetype = aes256 realm = K5Realm(create_host=False, start_kadmind=True) realm.prep_kadmin() stash_file = os.path.join(realm.testdir, 'stash') # Count the number of principals in the realm. nprincs = len(realm.run([kadminl, 'listprincs']).splitlines()) # List the currently active mkeys and compare against expected # results. Each argument must be a sequence of four elements: an # expected kvno, an expected enctype, whether the key is expected to # have an activation time, and whether the key is expected to be # currently active. list_mkeys_re = re.compile(r'^KVNO: (\d+), Enctype: (\S+), ' r'(Active on: [^\*]+|No activate time set)( \*)?$') def check_mkey_list(*expected): # Split the output of kdb5_util list_mkeys into lines and ignore the first. outlines = realm.run([kdb5_util, 'list_mkeys']).splitlines()[1:] if len(outlines) != len(expected): fail('Unexpected number of list_mkeys output lines') for line, ex in zip(outlines, expected): m = list_mkeys_re.match(line) if not m: fail('Unrecognized list_mkeys output line') kvno, enctype, act_time, active = m.groups() exp_kvno, exp_enctype, exp_act_time_present, exp_active = ex if kvno != str(exp_kvno): fail('Unexpected master key version') if enctype != exp_enctype: fail('Unexpected master key enctype') if act_time.startswith('Active on: ') != exp_act_time_present: fail('Unexpected presence or absence of mkey activation time') if (active == ' *') != exp_active: fail('Master key unexpectedly active or inactive') # Get the K/M principal. Verify that it has the expected mkvno. Each # remaining argument must be a sequence of two elements: an expected # key version and an expected enctype. keyline_re = re.compile(r'^Key: vno (\d+), (\S+)$') def check_master_dbent(expected_mkvno, *expected_keys): outlines = realm.run([kadminl, 'getprinc', 'K/M']).splitlines() mkeyline = [l for l in outlines if l.startswith('MKey: vno ')] if len(mkeyline) != 1 or mkeyline[0] != ('MKey: vno %d' % expected_mkvno): fail('Unexpected mkvno in K/M DB entry') keylines = [l for l in outlines if l.startswith('Key: vno ')] if len(keylines) != len(expected_keys): fail('Unexpected number of key lines in K/M DB entry') for line, ex in zip(keylines, expected_keys): m = keyline_re.match(line) if not m: fail('Unrecognized key line in K/M DB entry') kvno, enctype = m.groups() exp_kvno, exp_enctype = ex if kvno != str(exp_kvno): fail('Unexpected key version in K/M DB entry') if enctype != exp_enctype: fail('Unexpected enctype in K/M DB entry') # Check the stash file. Each argument must be a sequence of two # elements: an expected key version and an expected enctype. klist_re = re.compile(r'^\s*(\d+) K/M@KRBTEST.COM \((\S+)\)') def check_stash(*expected): # Split the output of klist -e -k into lines and ignore the first three. outlines = realm.run([klist, '-e', '-k', stash_file]).splitlines()[3:] if len(outlines) != len(expected): fail('Unexpected number of lines in stash file klist') for line, ex in zip(outlines, expected): m = klist_re.match(line) if not m: fail('Unrecognized stash file klist line') kvno, enctype = m.groups() exp_kvno, exp_enctype = ex if kvno != str(exp_kvno): fail('Unexpected stash file klist kvno') if enctype != exp_enctype: fail('Unexpected stash file klist enctype') # Verify that the user principal has the expected mkvno. def check_mkvno(princ, expected_mkvno): msg = 'MKey: vno %d\n' % expected_mkvno realm.run([kadminl, 'getprinc', princ], expected_msg=msg) # Change the password using either kadmin.local or kadmin, then check # the mkvno of the principal against expected_mkvno and verify that # the running KDC can access the new key. def change_password_check_mkvno(local, princ, password, expected_mkvno): cmd = ['cpw', '-pw', password, princ] if local: realm.run([kadminl] + cmd) else: realm.run_kadmin(cmd) check_mkvno(princ, expected_mkvno) realm.kinit(princ, password) # Add a master key with the specified options and a random password. def add_mkey(options): pw = ''.join(random.choice(string.ascii_uppercase) for x in range(5)) realm.run([kdb5_util, 'add_mkey'] + options, input=(pw + '\n' + pw + '\n')) # Run kdb5_util update_princ_encryption (with the dry-run option if # specified) and verify the output against the expected mkvno, number # of updated principals, and number of already-current principals. mkvno_re = {False: re.compile(r'^Principals whose keys are being re-encrypted ' r'to master key vno (\d+) if necessary:$'), True: re.compile(r'^Principals whose keys WOULD BE re-encrypted ' r'to master key vno (\d+):$')} count_re = {False: re.compile(r'^(\d+) principals processed: (\d+) updated, ' r'(\d+) already current$'), True: re.compile(r'^(\d+) principals processed: (\d+) would be ' r'updated, (\d+) already current$')} def update_princ_encryption(dry_run, expected_mkvno, expected_updated, expected_current): opts = ['-f', '-v'] if dry_run: opts += ['-n'] out = realm.run([kdb5_util, 'update_princ_encryption'] + opts) lines = out.splitlines() # Parse the first line to get the target mkvno. m = mkvno_re[dry_run].match(lines[0]) if not m: fail('Unexpected first line of update_princ_encryption output') if m.group(1) != str(expected_mkvno): fail('Unexpected master key version in update_princ_encryption output') # Parse the last line to get the principal counts. m = count_re[dry_run].match(lines[-1]) if not m: fail('Unexpected last line of update_princ_encryption output') total, updated, current = m.groups() if (total != str(expected_updated + expected_current) or updated != str(expected_updated) or current != str(expected_current)): fail('Unexpected counts from update_princ_encryption') # Check the initial state of the realm. mark('initial state') check_mkey_list((1, defetype, True, True)) check_master_dbent(1, (1, defetype)) check_stash((1, defetype)) check_mkvno(realm.user_princ, 1) # Check that stash will fail if a temp stash file is already present. mark('temp stash collision') collisionfile = os.path.join(realm.testdir, 'stash_tmp') f = open(collisionfile, 'w') f.close() realm.run([kdb5_util, 'stash'], expected_code=1, expected_msg='Temporary stash file already exists') os.unlink(collisionfile) # Add a new master key with no options. Verify that: # 1. The new key appears in list_mkeys but has no activation time and # is not active. # 2. The new key appears in the K/M DB entry and is the current key to # encrypt that entry. # 3. The stash file is not modified (since we did not pass -s). # 4. The old key is used for password changes. mark('add_mkey (second master key)') add_mkey([]) check_mkey_list((2, defetype, False, False), (1, defetype, True, True)) check_master_dbent(2, (2, defetype), (1, defetype)) change_password_check_mkvno(True, realm.user_princ, 'abcd', 1) change_password_check_mkvno(False, realm.user_princ, 'user', 1) # Verify that use_mkey won't make all master keys inactive. mark('use_mkey (no active keys)') realm.run([kdb5_util, 'use_mkey', '1', 'now+1day'], expected_code=1, expected_msg='there must be one master key currently active') check_mkey_list((2, defetype, False, False), (1, defetype, True, True)) # Make the new master key active. Verify that: # 1. The new key has an activation time in list_mkeys and is active. # 2. The new key is used for password changes. # 3. The running KDC can access the new key. mark('use_mkey') realm.run([kdb5_util, 'use_mkey', '2', 'now-1day']) check_mkey_list((2, defetype, True, True), (1, defetype, True, False)) change_password_check_mkvno(True, realm.user_princ, 'abcd', 2) change_password_check_mkvno(False, realm.user_princ, 'user', 2) # Check purge_mkeys behavior with both master keys still in use. mark('purge_mkeys (nothing to purge)') realm.run([kdb5_util, 'purge_mkeys', '-f', '-v'], expected_msg='All keys in use, nothing purged.') # Do an update_princ_encryption dry run and for real. Verify that: # 1. The target master key is 2 (the active mkvno). # 2. nprincs - 2 principals were updated and one principal was # skipped (K/M is not included in the output and user was updated # above). # 3. The dry run doesn't change user/admin's mkvno but the real update # does. # 4. The old stashed master key is sufficient to access the DB (via # MKEY_AUX tl-data which keeps the current master key encrypted in # each of the old master keys). mark('update_princ_encryption') update_princ_encryption(True, 2, nprincs - 2, 1) check_mkvno(realm.admin_princ, 1) update_princ_encryption(False, 2, nprincs - 2, 1) check_mkvno(realm.admin_princ, 2) realm.stop_kdc() realm.start_kdc() realm.kinit(realm.user_princ, 'user') # Update all principals back to mkvno 1 and to mkvno 2 again, to # verify that update_princ_encryption targets the active master key. mark('update_princ_encryption (back and forth)') realm.run([kdb5_util, 'use_mkey', '2', 'now+1day']) update_princ_encryption(False, 1, nprincs - 1, 0) check_mkvno(realm.user_princ, 1) realm.run([kdb5_util, 'use_mkey', '2', 'now-1day']) update_princ_encryption(False, 2, nprincs - 1, 0) check_mkvno(realm.user_princ, 2) # Test the safety check for purging with an outdated stash file. mark('purge_mkeys (outdated stash file)') realm.run([kdb5_util, 'purge_mkeys', '-f'], expected_code=1, expected_msg='stash file needs updating') # Update the master stash file and check it. Save a copy of the old # one for a later test. mark('update stash file') shutil.copy(stash_file, stash_file + '.old') realm.run([kdb5_util, 'stash']) check_stash((2, defetype), (1, defetype)) # Do a purge_mkeys dry run and for real. Verify that: # 1. Master key 1 is purged. # 2. The dry run doesn't remove mkvno 1 but the real one does. # 3. The old stash file is no longer sufficient to access the DB. # 4. If the stash file is updated, it no longer contains mkvno 1. # 5. use_mkey now gives an error if we refer to mkvno 1. # 6. A second purge_mkeys gives the right message. mark('purge_mkeys') out = realm.run([kdb5_util, 'purge_mkeys', '-v', '-n', '-f']) if 'KVNO: 1' not in out or '1 key(s) would be purged' not in out: fail('Unexpected output from purge_mkeys dry-run') check_mkey_list((2, defetype, True, True), (1, defetype, True, False)) check_master_dbent(2, (2, defetype), (1, defetype)) out = realm.run([kdb5_util, 'purge_mkeys', '-v', '-f']) check_mkey_list((2, defetype, True, True)) check_master_dbent(2, (2, defetype)) os.rename(stash_file, stash_file + '.save') os.rename(stash_file + '.old', stash_file) realm.run([kadminl, 'getprinc', 'user'], expected_code=1, expected_msg='Unable to decrypt latest master key') os.rename(stash_file + '.save', stash_file) realm.run([kdb5_util, 'stash']) check_stash((2, defetype)) realm.run([kdb5_util, 'use_mkey', '1'], expected_code=1, expected_msg='1 is an invalid KVNO value') realm.run([kdb5_util, 'purge_mkeys', '-f', '-v'], expected_msg='There is only one master key which can not be purged.') # Add a third master key with a specified enctype. Verify that: # 1. The new master key receives the correct number. # 2. The enctype argument is respected. # 3. The new master key is stashed (by itself, at the moment). # 4. We can roll over to the new master key and use it. mark('add_mkey and update_princ_encryption (third master key)') add_mkey(['-s', '-e', aes128]) check_mkey_list((3, aes128, False, False), (2, defetype, True, True)) check_master_dbent(3, (3, aes128), (2, defetype)) check_stash((3, aes128)) realm.run([kdb5_util, 'use_mkey', '3', 'now-1day']) update_princ_encryption(False, 3, nprincs - 1, 0) check_mkey_list((3, aes128, True, True), (2, defetype, True, False)) check_mkvno(realm.user_princ, 3) # Regression test for #7994 (randkey does not update principal mkvno) # and #7995 (-keepold does not re-encrypt old keys). mark('#7994 and #7995 regression test') add_mkey(['-s']) realm.run([kdb5_util, 'use_mkey', '4', 'now-1day']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', realm.user_princ]) # With #7994 unfixed, mkvno of user will still be 3. check_mkvno(realm.user_princ, 4) # With #7995 unfixed, old keys are still encrypted with mkvno 3. update_princ_encryption(False, 4, nprincs - 2, 1) realm.run([kdb5_util, 'purge_mkeys', '-f']) out = realm.run([kadminl, 'xst', '-norandkey', realm.user_princ]) if 'Decrypt integrity check failed' in out or 'added to keytab' not in out: fail('Preserved old key data not updated to new master key') realm.stop() # Load a dump file created with krb5 1.6, before the master key # rollover changes were introduced. Write out an old-format stash # file consistent with the dump's master password ("footes"). The K/M # entry in this database will not have actkvno tl-data because it was # created prior to master key rollover support. Verify that: # 1. We can access the database using the old-format stash file. # 2. list_mkeys displays the same list as for a post-1.7 KDB. mark('pre-1.7 stash file') dumpfile = os.path.join(srctop, 'tests', 'dumpfiles', 'dump.16') os.remove(stash_file) f = open(stash_file, 'wb') f.write(struct.pack('=HL24s', 16, 24, b'\xF8\x3E\xFB\xBA\x6D\x80\xD9\x54\xE5\x5D\xF2\xE0' b'\x94\xAD\x6D\x86\xB5\x16\x37\xEC\x7C\x8A\xBC\x86')) f.close() realm.run([kdb5_util, 'load', dumpfile]) nprincs = len(realm.run([kadminl, 'listprincs']).splitlines()) check_mkvno('K/M', 1) check_mkey_list((1, des3, True, True)) # Create a new master key and verify that, without actkvkno tl-data: # 1. list_mkeys displays the same as for a post-1.7 KDB. # 2. update_princ_encryption still targets mkvno 1. # 3. libkadm5 still uses mkvno 1 for key changes. # 4. use_mkey creates the same list as for a post-1.7 KDB. mark('rollover from pre-1.7 KDB') add_mkey([]) check_mkey_list((2, defetype, False, False), (1, des3, True, True)) update_princ_encryption(False, 1, 0, nprincs - 1) realm.run([kadminl, 'addprinc', '-randkey', realm.user_princ]) check_mkvno(realm.user_princ, 1) realm.run([kdb5_util, 'use_mkey', '2', 'now-1day']) check_mkey_list((2, defetype, True, True), (1, des3, True, False)) # Regression test for #8395. Purge the master key and verify that a # master key fetch does not segfault. mark('#8395 regression test') realm.run([kadminl, 'purgekeys', '-all', 'K/M']) realm.run([kadminl, 'getprinc', realm.user_princ], expected_code=1, expected_msg='Cannot find master key record in database') success('Master key rollover tests') krb5-1.22.1/src/tests/t_hostrealm.py0000775000175000017500000001364215051422640017176 0ustar ghudsonghudsonfrom k5test import * plugin = os.path.join(buildtop, "plugins", "hostrealm", "test", "hostrealm_test.so") # Disable the "dns" module (we can't easily test TXT lookups) and # arrange the remaining modules in an order which makes sense for most # tests. conf = {'plugins': {'hostrealm': {'module': ['test1:' + plugin, 'test2:' + plugin], 'enable_only': ['test2', 'profile', 'domain', 'test1']}}, 'domain_realm': {'.x': 'DOTMATCH', 'x': 'MATCH', '.1': 'NUMMATCH'}} realm = K5Realm(krb5_conf=conf, create_kdb=False) def test(realm, args, expected_realms, msg, env=None): out = realm.run(['./hrealm'] + args, env=env) if out.split('\n') != expected_realms + ['']: fail(msg) def test_error(realm, args, expected_error, msg, env=None): realm.run(['./hrealm'] + args, env=env, expected_code=1, expected_msg=expected_error) def testh(realm, host, expected_realms, msg, env=None): test(realm, ['-h', host], expected_realms, msg, env=env) def testf(realm, host, expected_realms, msg, env=None): test(realm, ['-f', host], expected_realms, msg, env=env) def testd(realm, expected_realm, msg, env=None): test(realm, ['-d'], [expected_realm], msg, env=env) def testh_error(realm, host, expected_error, msg, env=None): test_error(realm, ['-h', host], expected_error, msg, env=env) def testf_error(realm, host, expected_error, msg, env=None): test_error(realm, ['-f', host], expected_error, msg, env=env) def testd_error(realm, expected_error, msg, env=None): test_error(realm, ['-d'], expected_error, msg, env=env) ### ### krb5_get_host_realm tests ### # The test2 module returns a fatal error on hosts beginning with 'z', # and an answer on hosts beginning with 'a'. mark('test2 module') testh_error(realm, 'zoo', 'service not available', 'host_realm test2 z') testh(realm, 'abacus', ['a'], 'host_realm test2 a') # The profile module gives answers for hostnames equal to or ending in # 'X', due to [domain_realms]. There is also an entry for hostnames # ending in '1', but hostnames which appear to be IP or IPv6 addresses # should instead fall through to test1. mark('profile module') testh(realm, 'x', ['MATCH'], 'host_realm profile x') testh(realm, '.x', ['DOTMATCH'], 'host_realm profile .x') testh(realm, 'b.x', ['DOTMATCH'], 'host_realm profile b.x') testh(realm, '.b.c.x', ['DOTMATCH'], 'host_realm profile .b.c.x') testh(realm, 'b.1', ['NUMMATCH'], 'host_realm profile b.1') testh(realm, '4.3.2.1', ['4', '3', '2', '1'], 'host_realm profile 4.3.2.1') testh(realm, 'b:c.x', ['b:c', 'x'], 'host_realm profile b:c.x') # hostname cleaning should convert "X." to "x" before matching. testh(realm, 'X.', ['MATCH'], 'host_realm profile X.') # The test1 module returns a list of the hostname components. mark('test1 module') testh(realm, 'b.c.d', ['b', 'c', 'd'], 'host_realm test1') # If no module returns a result, we should get the referral realm. mark('no result') testh(realm, '', [''], 'host_realm referral realm') ### ### krb5_get_fallback_host_realm tests ### # Return a special environment with realm_try_domains set to n. def try_env(realm, testname, n): conf = {'libdefaults': {'realm_try_domains': str(n)}} return realm.special_env(testname, False, krb5_conf=conf) # The domain module will answer with the uppercased parent domain, # with no special configuration. mark('fallback: domain module') testf(realm, 'a.b.c', ['B.C'], 'fallback_realm domain a.b.c') # With realm_try_domains = 0, the hostname itself will be looked up as # a realm and returned if found. mark('fallback: realm_try_domains = 0') try0 = try_env(realm, 'try0', 0) testf(realm, 'krbtest.com', ['KRBTEST.COM'], 'fallback_realm try0', env=try0) testf(realm, 'a.b.krbtest.com', ['B.KRBTEST.COM'], 'fallback_realm try0 grandparent', env=try0) testf(realm, 'a.b.c', ['B.C'], 'fallback_realm try0 nomatch', env=try0) # With realm_try_domains = 2, the parent and grandparent will be # checked as well, but it stops there. mark('fallback: realm_try_domains = 2') try2 = try_env(realm, 'try2', 2) testf(realm, 'krbtest.com', ['KRBTEST.COM'], 'fallback_realm try2', env=try2) testf(realm, 'a.b.krbtest.com', ['KRBTEST.COM'], 'fallback_realm try2 grandparent', env=try2) testf(realm, 'a.b.c.krbtest.com', ['B.C.KRBTEST.COM'], 'fallback_realm try2 great-grandparent', env=try2) # The test1 module answers with a list of components. Use an IPv4 # address to bypass the domain module. mark('fallback: test1 module') testf(realm, '1.2.3.4', ['1', '2', '3', '4'], 'fallback_realm test1') # If no module answers, the default realm is returned. The test2 # module returns an error when we try to look that up. mark('fallback: default realm') testf_error(realm, '', 'service not available', 'fallback_realm default') ### ### krb5_get_default_realm tests ### # The test2 module returns an error. mark('default_realm: test2 module') testd_error(realm, 'service not available', 'default_realm test2') # The profile module returns the default realm from the profile. # Disable test2 to expose this behavior. mark('default_realm: profile module') disable_conf = {'plugins': {'hostrealm': {'disable': 'test2'}}} notest2 = realm.special_env('notest2', False, krb5_conf=disable_conf) testd(realm, 'KRBTEST.COM', 'default_realm profile', env=notest2) # The test1 module returns a list of two realms, of which we can only # see the first. Remove the profile default_realm setting to expose # this behavior. mark('default_realm: test1 module') remove_default = {'libdefaults': {'default_realm': None}} # Python 3.5+: nodefault_conf = {**disable_conf, **remove_default} nodefault_conf = dict(list(disable_conf.items()) + list(remove_default.items())) nodefault = realm.special_env('nodefault', False, krb5_conf=nodefault_conf) testd(realm, 'one', 'default_realm test1', env=nodefault) success('hostrealm interface tests') krb5-1.22.1/src/tests/responder.c0000664000175000017500000003735115051422640016450 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/responder.c - Test harness for responder callbacks and the like. */ /* * Copyright 2013 Red Hat, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * A helper for testing PKINIT and responder callbacks. * * This test helper takes multiple options and one argument. * * responder [options] principal * -X preauth_option -> preauth options, as for kinit * -x challenge -> expected responder challenge, of the form * "question=challenge" * -r response -> provide a reponder answer, in the form * "question=answer" * -c -> print the pkinit challenge * -p identity=pin -> provide a pkinit answer, in the form "identity=pin" * -o index=value:pin -> provide an OTP answer, in the form "index=value:pin" * principal -> client principal name * * If the responder callback isn't called, that's treated as an error. * * If an expected responder challenge is specified, when the responder * callback is called, the challenge associated with the specified question is * compared against the specified value. If the value provided to the * callback doesn't parse as JSON, a literal string compare is performed, * otherwise both values are parsed as JSON and then re-encoded before * comparison. In either case, the comparison must succeed. * * Any missing data or mismatches are treated as errors. */ #include #include #include #include #include struct responder_data { krb5_boolean called; krb5_boolean print_pkinit_challenge; const char *challenge; const char *response; const char *pkinit_answer; const char *otp_answer; }; static krb5_error_code responder(krb5_context ctx, void *rawdata, krb5_responder_context rctx) { krb5_error_code err; char *key, *value, *pin, *encoded1, *encoded2; const char *challenge; k5_json_value decoded1, decoded2; k5_json_object ids; k5_json_number val; krb5_int32 token_flags; struct responder_data *data = rawdata; krb5_responder_pkinit_challenge *chl; krb5_responder_otp_challenge *ochl; unsigned int i, n; data->called = TRUE; /* Check that a particular challenge has the specified expected value. */ if (data->challenge != NULL) { /* Separate the challenge name and its expected value. */ key = strdup(data->challenge); if (key == NULL) exit(ENOMEM); value = key + strcspn(key, "="); if (*value != '\0') *value++ = '\0'; /* Read the challenge. */ challenge = krb5_responder_get_challenge(ctx, rctx, key); err = k5_json_decode(value, &decoded1); /* Check for "no challenge". */ if (challenge == NULL && *value == '\0') { fprintf(stderr, "OK: (no challenge) == (no challenge)\n"); } else if (err != 0) { /* It's not JSON, so assume we're just after a string compare. */ if (strcmp(challenge, value) == 0) { fprintf(stderr, "OK: \"%s\" == \"%s\"\n", challenge, value); } else { fprintf(stderr, "ERROR: \"%s\" != \"%s\"\n", challenge, value); exit(1); } } else { /* Assume we're after a JSON compare - decode the actual value. */ err = k5_json_decode(challenge, &decoded2); if (err != 0) { fprintf(stderr, "error decoding \"%s\"\n", challenge); exit(1); } /* Re-encode the expected challenge and the actual challenge... */ err = k5_json_encode(decoded1, &encoded1); if (err != 0) { fprintf(stderr, "error encoding json data\n"); exit(1); } err = k5_json_encode(decoded2, &encoded2); if (err != 0) { fprintf(stderr, "error encoding json data\n"); exit(1); } k5_json_release(decoded1); k5_json_release(decoded2); /* ... and see if they look the same. */ if (strcmp(encoded1, encoded2) == 0) { fprintf(stderr, "OK: \"%s\" == \"%s\"\n", encoded1, encoded2); } else { fprintf(stderr, "ERROR: \"%s\" != \"%s\"\n", encoded1, encoded2); exit(1); } free(encoded1); free(encoded2); } free(key); } /* Provide a particular response for a challenge. */ if (data->response != NULL) { /* Separate the challenge and its data content... */ key = strdup(data->response); if (key == NULL) exit(ENOMEM); value = key + strcspn(key, "="); if (*value != '\0') *value++ = '\0'; /* ... and pass it in. */ err = krb5_responder_set_answer(ctx, rctx, key, value); if (err != 0) { fprintf(stderr, "error setting response\n"); exit(1); } free(key); } if (data->print_pkinit_challenge) { /* Read the PKINIT challenge, formatted as a structure. */ err = krb5_responder_pkinit_get_challenge(ctx, rctx, &chl); if (err != 0) { fprintf(stderr, "error getting pkinit challenge\n"); exit(1); } if (chl != NULL) { for (n = 0; chl->identities[n] != NULL; n++) continue; for (i = 0; chl->identities[i] != NULL; i++) { if (chl->identities[i]->token_flags != -1) { printf("identity %u/%u: %s (flags=0x%lx)\n", i + 1, n, chl->identities[i]->identity, (long)chl->identities[i]->token_flags); } else { printf("identity %u/%u: %s\n", i + 1, n, chl->identities[i]->identity); } } } krb5_responder_pkinit_challenge_free(ctx, rctx, chl); } /* Provide a particular response for the PKINIT challenge. */ if (data->pkinit_answer != NULL) { /* Read the PKINIT challenge, formatted as a structure. */ err = krb5_responder_pkinit_get_challenge(ctx, rctx, &chl); if (err != 0) { fprintf(stderr, "error getting pkinit challenge\n"); exit(1); } /* * In case order matters, if the identity starts with "FILE:", exercise * the set_answer function, with the real answer second. */ if (chl != NULL && chl->identities != NULL && chl->identities[0] != NULL) { if (strncmp(chl->identities[0]->identity, "FILE:", 5) == 0) krb5_responder_pkinit_set_answer(ctx, rctx, "foo", "bar"); } /* Provide the real answer. */ key = strdup(data->pkinit_answer); if (key == NULL) exit(ENOMEM); value = strrchr(key, '='); if (value != NULL) *value++ = '\0'; else value = ""; err = krb5_responder_pkinit_set_answer(ctx, rctx, key, value); if (err != 0) { fprintf(stderr, "error setting response\n"); exit(1); } free(key); /* * In case order matters, if the identity starts with "PKCS12:", * exercise the set_answer function, with the real answer first. */ if (chl != NULL && chl->identities != NULL && chl->identities[0] != NULL) { if (strncmp(chl->identities[0]->identity, "PKCS12:", 7) == 0) krb5_responder_pkinit_set_answer(ctx, rctx, "foo", "bar"); } krb5_responder_pkinit_challenge_free(ctx, rctx, chl); } /* * Something we always check: read the PKINIT challenge, both as a * structure and in JSON form, reconstruct the JSON form from the * structure's contents, and check that they're the same. */ challenge = krb5_responder_get_challenge(ctx, rctx, KRB5_RESPONDER_QUESTION_PKINIT); if (challenge != NULL) { krb5_responder_pkinit_get_challenge(ctx, rctx, &chl); if (chl == NULL) { fprintf(stderr, "pkinit raw challenge set, " "but structure is NULL\n"); exit(1); } if (k5_json_object_create(&ids) != 0) { fprintf(stderr, "error creating json objects\n"); exit(1); } for (i = 0; chl->identities[i] != NULL; i++) { token_flags = chl->identities[i]->token_flags; if (k5_json_number_create(token_flags, &val) != 0) { fprintf(stderr, "error creating json number\n"); exit(1); } if (k5_json_object_set(ids, chl->identities[i]->identity, val) != 0) { fprintf(stderr, "error adding json number to object\n"); exit(1); } k5_json_release(val); } /* Encode the structure... */ err = k5_json_encode(ids, &encoded1); if (err != 0) { fprintf(stderr, "error encoding json data\n"); exit(1); } k5_json_release(ids); /* ... and see if they look the same. */ if (strcmp(encoded1, challenge) != 0) { fprintf(stderr, "\"%s\" != \"%s\"\n", encoded1, challenge); exit(1); } krb5_responder_pkinit_challenge_free(ctx, rctx, chl); free(encoded1); } /* Provide a particular response for an OTP challenge. */ if (data->otp_answer != NULL) { if (krb5_responder_otp_get_challenge(ctx, rctx, &ochl) == 0) { key = strchr(data->otp_answer, '='); if (key != NULL) { /* Make a copy of the answer that we can chop up. */ key = strdup(data->otp_answer); if (key == NULL) return ENOMEM; /* Isolate the ti value. */ value = strchr(key, '='); *value++ = '\0'; n = atoi(key); /* Break the value and PIN apart. */ pin = strchr(value, ':'); if (pin != NULL) *pin++ = '\0'; err = krb5_responder_otp_set_answer(ctx, rctx, n, value, pin); if (err != 0) { fprintf(stderr, "error setting response\n"); exit(1); } free(key); } krb5_responder_otp_challenge_free(ctx, rctx, ochl); } } return 0; } int main(int argc, char **argv) { krb5_context context; krb5_ccache ccache; krb5_get_init_creds_opt *opts; krb5_principal principal; krb5_creds creds; krb5_error_code err; const char *errmsg; char *opt, *val; struct responder_data response; int c; err = krb5_init_context(&context); if (err != 0) { fprintf(stderr, "error starting Kerberos: %s\n", error_message(err)); return err; } err = krb5_get_init_creds_opt_alloc(context, &opts); if (err != 0) { fprintf(stderr, "error initializing options: %s\n", error_message(err)); return err; } err = krb5_cc_default(context, &ccache); if (err != 0) { fprintf(stderr, "error resolving default ccache: %s\n", error_message(err)); return err; } err = krb5_get_init_creds_opt_set_out_ccache(context, opts, ccache); if (err != 0) { fprintf(stderr, "error setting output ccache: %s\n", error_message(err)); return err; } memset(&response, 0, sizeof(response)); while ((c = getopt(argc, argv, "X:x:cr:p:")) != -1) { switch (c) { case 'X': /* Like kinit, set a generic preauth option. */ opt = strdup(optarg); val = opt + strcspn(opt, "="); if (*val != '\0') { *val++ = '\0'; } err = krb5_get_init_creds_opt_set_pa(context, opts, opt, val); if (err != 0) { fprintf(stderr, "error setting option \"%s\": %s\n", opt, error_message(err)); return err; } free(opt); break; case 'x': /* Check that a particular question has a specific challenge. */ response.challenge = optarg; break; case 'c': /* Note that we want a dump of the PKINIT challenge structure. */ response.print_pkinit_challenge = TRUE; break; case 'r': /* Set a verbatim response for a verbatim challenge. */ response.response = optarg; break; case 'p': /* Set a PKINIT answer for a specific PKINIT identity. */ response.pkinit_answer = optarg; break; case 'o': /* Set an OTP answer for a specific OTP tokeninfo. */ response.otp_answer = optarg; break; } } if (argc > optind) { err = krb5_parse_name(context, argv[optind], &principal); if (err != 0) { fprintf(stderr, "error parsing name \"%s\": %s", argv[optind], error_message(err)); return err; } } else { fprintf(stderr, "error: no principal name provided\n"); return -1; } err = krb5_get_init_creds_opt_set_responder(context, opts, responder, &response); if (err != 0) { fprintf(stderr, "error setting responder: %s\n", error_message(err)); return err; } memset(&creds, 0, sizeof(creds)); err = krb5_get_init_creds_password(context, &creds, principal, NULL, NULL, NULL, 0, NULL, opts); if (err == 0) krb5_free_cred_contents(context, &creds); krb5_free_principal(context, principal); krb5_get_init_creds_opt_free(context, opts); krb5_cc_close(context, ccache); if (!response.called) { fprintf(stderr, "error: responder callback wasn't called\n"); err = 1; } else if (err) { errmsg = krb5_get_error_message(context, err); fprintf(stderr, "error: krb5_get_init_creds_password failed: %s\n", errmsg); krb5_free_error_message(context, errmsg); err = 2; } krb5_free_context(context); return err; } krb5-1.22.1/src/tests/t_princflags.py0000775000175000017500000001033715051422640017326 0ustar ghudsonghudsonfrom k5test import * from princflags import * import re realm = K5Realm(create_host=False, get_creds=False) # Regex pattern to match an empty attribute line from kadmin getprinc emptyattr = re.compile('^Attributes:$', re.MULTILINE) # Regex pattern to match a kadmin getprinc output for a flag tuple def attr_pat(ftuple): return re.compile('^Attributes: ' + ftuple.flagname() + '$', re.MULTILINE) # Test one flag tuple for kadmin ank. def one_kadmin_flag(ftuple): pat = attr_pat(ftuple) realm.run([kadminl, 'ank', ftuple.setspec(), '-pw', 'password', 'test']) out = realm.run([kadminl, 'getprinc', 'test']) if not pat.search(out): fail('Failed to set flag ' + ftuple.flagname()) realm.run([kadminl, 'modprinc', ftuple.clearspec(), 'test']) out = realm.run([kadminl, 'getprinc', 'test']) if not emptyattr.search(out): fail('Failed to clear flag ' + ftuple.flagname()) realm.run([kadminl, 'delprinc', 'test']) # Generate a custom kdc.conf with default_principal_flags set # according to ftuple. def genkdcconf(ftuple): d = { 'realms': { '$realm': { 'default_principal_flags': ftuple.setspec() }}} return realm.special_env('tmp', True, kdc_conf=d) # Test one ftuple for kdc.conf default_principal_flags. def one_kdcconf(ftuple): e = genkdcconf(ftuple) pat = attr_pat(ftuple) realm.run([kadminl, 'ank', '-pw', 'password', 'test'], env=e) out = realm.run([kadminl, 'getprinc', 'test']) if not pat.search(out): fail('Failed to set flag ' + ftuple.flagname() + ' via kdc.conf') realm.run([kadminl, 'delprinc', 'test']) # Principal name for kadm5.acl line def ftuple2pname(ftuple, doset): pname = 'set_' if doset else 'clear_' return pname + ftuple.flagname() # Translate a strconv ftuple to a spec string for kadmin. def ftuple2kadm_spec(ftuple, doset): ktuple = kadmin_itable[ftuple.flag] if ktuple.invert != ftuple.invert: # Could do: # doset = not doset # but this shouldn't happen. raise ValueError return ktuple.spec(doset) # Generate a line for kadm5.acl. def acl_line(ftuple, doset): pname = ftuple2pname(ftuple, doset) spec = ftuple.spec(doset) return "%s * %s %s\n" % (realm.admin_princ, pname, spec) # Test one kadm5.acl line for a ftuple. def one_aclcheck(ftuple, doset): pname = ftuple2pname(ftuple, doset) pat = attr_pat(ftuple) outname = ftuple.flagname() # Create the principal and check that the flag is correctly set or # cleared. realm.run_kadmin(['ank', '-pw', 'password', pname]) out = realm.run([kadminl, 'getprinc', pname]) if doset: if not pat.search(out): fail('Failed to set flag ' + outname + ' via kadm5.acl') else: if not emptyattr.search(out): fail('Failed to clear flag ' + outname + ' via kadm5.acl') # If acl forces flag to be set, try to clear it, and vice versa. spec = ftuple2kadm_spec(ftuple, not doset) realm.run_kadmin(['modprinc', spec, pname]) out = realm.run([kadminl, 'getprinc', pname]) if doset: if not pat.search(out): fail('Failed to keep flag ' + outname + ' set') else: if not emptyattr.search(out): fail('Failed to keep flag ' + outname + ' clear') # Set all flags simultaneously, even the ones that aren't defined yet. def lamptest(): pat = re.compile('^Attributes: ' + ' '.join(flags2namelist(0xffffffff)) + '$', re.MULTILINE) realm.run([kadminl, 'ank', '-pw', 'password', '+0xffffffff', 'test']) out = realm.run([kadminl, 'getprinc', 'test']) if not pat.search(out): fail('Failed to simultaenously set all flags') realm.run([kadminl, 'delprinc', 'test']) for ftuple in kadmin_ftuples: one_kadmin_flag(ftuple) for ftuple in strconv_ftuples: one_kdcconf(ftuple) f = open(os.path.join(realm.testdir, 'acl'), 'w') for ftuple in strconv_ftuples: f.write(acl_line(ftuple, True)) f.write(acl_line(ftuple, False)) f.close() realm.start_kadmind() realm.prep_kadmin() for ftuple in strconv_ftuples: one_aclcheck(ftuple, True) one_aclcheck(ftuple, False) lamptest() success('KDB principal flags') krb5-1.22.1/src/tests/t_stringattr.py0000775000175000017500000000341115051422640017372 0ustar ghudsonghudson# Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * realm = K5Realm(start_kadmind=True, create_host=False, get_creds=False) realm.prep_kadmin() realm.run_kadmin(['getstrs', 'user'], expected_msg='(No string attributes.)') realm.run_kadmin(['setstr', 'user', 'attr1', 'value1']) realm.run_kadmin(['setstr', 'user', 'attr2', 'value2']) realm.run_kadmin(['delstr', 'user', 'attr1']) realm.run_kadmin(['setstr', 'user', 'attr3', 'value3']) out = realm.run_kadmin(['getstrs', 'user']) if ('attr2: value2' not in out or 'attr3: value3' not in out or 'attr1:' in out): fail('Final attribute query') success('KDB string attributes') krb5-1.22.1/src/tests/gcred.c0000664000175000017500000001012615051422640015522 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gcred.c - Test harness for referrals */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is intended to be run from a python script as: * * gcred [-f] [-t] nametype princname * * where nametype is one of "unknown", "principal", "srv-inst", and "srv-hst", * and princname is the name of the service principal. gcred acquires * credentials for the specified server principal. On success, gcred displays * the server principal name of the obtained credentials to stdout and exits * with status 0. On failure, gcred displays the error message for the failed * operation to stderr and exits with status 1. * * The -f and -t flags set the KRB5_GC_FORWARDABLE and KRB5_GC_NO_TRANSIT_CHECK * options respectively. */ #include "k5-int.h" static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { krb5_principal client, server; krb5_ccache ccache; krb5_creds in_creds, *creds; krb5_ticket *ticket; krb5_flags options = 0; char *name; int c; check(krb5_init_context(&ctx)); while ((c = getopt(argc, argv, "ft")) != -1) { switch (c) { case 'f': options |= KRB5_GC_FORWARDABLE; break; case 't': options |= KRB5_GC_NO_TRANSIT_CHECK; break; default: abort(); } } argc -= optind; argv += optind; assert(argc == 2); check(krb5_parse_name(ctx, argv[1], &server)); if (strcmp(argv[0], "unknown") == 0) server->type = KRB5_NT_UNKNOWN; else if (strcmp(argv[0], "principal") == 0) server->type = KRB5_NT_PRINCIPAL; else if (strcmp(argv[0], "srv-inst") == 0) server->type = KRB5_NT_SRV_INST; else if (strcmp(argv[0], "srv-hst") == 0) server->type = KRB5_NT_SRV_HST; else abort(); check(krb5_cc_default(ctx, &ccache)); check(krb5_cc_get_principal(ctx, ccache, &client)); memset(&in_creds, 0, sizeof(in_creds)); in_creds.client = client; in_creds.server = server; check(krb5_get_credentials(ctx, options, ccache, &in_creds, &creds)); check(krb5_decode_ticket(&creds->ticket, &ticket)); check(krb5_unparse_name(ctx, ticket->server, &name)); printf("%s\n", name); krb5_free_ticket(ctx, ticket); krb5_free_unparsed_name(ctx, name); krb5_free_creds(ctx, creds); krb5_free_principal(ctx, client); krb5_free_principal(ctx, server); krb5_cc_close(ctx, ccache); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/hammer/0000775000175000017500000000000015051422640015543 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/hammer/Makefile.in0000664000175000017500000000037615051422640017616 0ustar ghudsonghudsonmydir=tests$(S)hammer BUILDTOP=$(REL)..$(S).. SRCS=$(srcdir)/kdc5_hammer.c all: kdc5_hammer kdc5_hammer: kdc5_hammer.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kdc5_hammer kdc5_hammer.o $(KRB5_BASE_LIBS) install: clean: $(RM) kdc5_hammer.o kdc5_hammer krb5-1.22.1/src/tests/hammer/deps0000664000175000017500000000136415051422640016425 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)kdc5_hammer.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kdc5_hammer.c krb5-1.22.1/src/tests/hammer/pp.c0000664000175000017500000000112115051422640016321 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/hammer/pp.c */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * For copying and distribution information, please see the file * . */ #include "krb5.h" void print_principal(p) krb5_principal p; { char *buf; krb5_error_code retval; if (retval = krb5_unparse_name(p, &buf)) { com_err("DEBUG: Print_principal", retval, "while unparsing name"); exit(1); } printf("%s\n", buf); free(buf); } krb5-1.22.1/src/tests/hammer/kdc5_hammer.c0000664000175000017500000003240715051422640020074 0ustar ghudsonghudson/* tests/hammer/kdc5_hammer.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "com_err.h" #include #define KRB5_DEFAULT_OPTIONS 0 #define KRB5_DEFAULT_LIFE 60*60*8 /* 8 hours */ #define KRB5_RENEWABLE_LIFE 60*60*2 /* 2 hours */ struct h_timer { float ht_cumulative; float ht_min; float ht_max; krb5_int32 ht_observations; }; extern int optind; extern char *optarg; char *prog; static int brief; static char *cur_realm = 0; static int do_timer = 0; krb5_data tgtname = { 0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME }; int verify_cs_pair (krb5_context, char *, krb5_principal, char *, char *, int, int, int, krb5_ccache); int get_tgt (krb5_context, char *, krb5_principal *, krb5_ccache); static void usage(char *who, int status) { fprintf(stderr, "usage: %s -p prefix -n num_to_check [-c cachename] [-r realmname]\n", who); fprintf(stderr, "\t [-D depth]\n"); fprintf(stderr, "\t [-P preauth type] [-R repeat_count] [-t] [-b] [-v] \n"); exit(status); } static krb5_preauthtype * patype = NULL, patypedata[2] = { 0, -1 }; static krb5_context test_context; struct timeval tstart_time, tend_time; struct timezone dontcare; struct h_timer in_tkt_times = { 0.0, 1000000.0, -1.0, 0 }; struct h_timer tgs_req_times = { 0.0, 1000000.0, -1.0, 0 }; /* * Timer macros. */ #define swatch_on() ((void) gettimeofday(&tstart_time, &dontcare)) #define swatch_eltime() ((gettimeofday(&tend_time, &dontcare)) ? -1.0 : \ (((float) (tend_time.tv_sec - \ tstart_time.tv_sec)) + \ (((float) (tend_time.tv_usec - \ tstart_time.tv_usec))/1000000.0))) int main(int argc, char **argv) { krb5_ccache ccache = NULL; char *cache_name = NULL; /* -f option */ int option; int errflg = 0; krb5_error_code code; int num_to_check, n, i, j, repeat_count, counter; int n_tried, errors; char prefix[BUFSIZ], client[4096], server[4096]; int depth; char ctmp[4096], ctmp2[BUFSIZ], stmp[4096], stmp2[BUFSIZ]; krb5_principal client_princ; krb5_error_code retval; krb5_init_context(&test_context); if (strrchr(argv[0], '/')) prog = strrchr(argv[0], '/')+1; else prog = argv[0]; num_to_check = 0; depth = 1; repeat_count = 1; brief = 0; n_tried = 0; errors = 0; while ((option = getopt(argc, argv, "D:p:n:c:R:P:e:bvr:t")) != -1) { switch (option) { case 't': do_timer = 1; break; case 'b': brief = 1; break; case 'v': brief = 0; break; case 'R': repeat_count = atoi(optarg); /* how many times? */ break; case 'r': cur_realm = optarg; break; case 'D': depth = atoi(optarg); /* how deep to go */ break; case 'p': /* prefix name to check */ strncpy(prefix, optarg, sizeof(prefix) - 1); prefix[sizeof(prefix) - 1] = '\0'; break; case 'n': /* how many to check */ num_to_check = atoi(optarg); break; case 'P': patypedata[0] = atoi(optarg); patype = patypedata; break; case 'c': if (ccache == NULL) { cache_name = optarg; code = krb5_cc_resolve (test_context, cache_name, &ccache); if (code != 0) { com_err (prog, code, "resolving %s", cache_name); errflg++; } } else { fprintf(stderr, "Only one -c option allowed\n"); errflg++; } break; case '?': default: errflg++; break; } } if (!(num_to_check && prefix[0]) || errflg) usage(prog, 1); if (!cur_realm) { if ((retval = krb5_get_default_realm(test_context, &cur_realm))) { com_err(prog, retval, "while retrieving default realm name"); exit(1); } } if (ccache == NULL) { if ((code = krb5_cc_default(test_context, &ccache))) { com_err(prog, code, "while getting default ccache"); exit(1); } } memset(ctmp, 0, sizeof(ctmp)); memset(stmp, 0, sizeof(stmp)); for (counter = 0; counter < repeat_count; counter++) { fprintf(stderr, "\nRound %d\n", counter); for (n = 1; n <= num_to_check; n++) { /* build the new principal name */ /* we can't pick random names because we need to generate all the names again given a prefix and count to test the db lib and kdb */ ctmp[0] = '\0'; for (i = 1; i <= depth; i++) { (void) snprintf(ctmp2, sizeof(ctmp2), "%s%s%d-DEPTH-%d", (i != 1) ? "/" : "", prefix, n, i); ctmp2[sizeof(ctmp2) - 1] = '\0'; strncat(ctmp, ctmp2, sizeof(ctmp) - 1 - strlen(ctmp)); ctmp[sizeof(ctmp) - 1] = '\0'; snprintf(client, sizeof(client), "%s@%s", ctmp, cur_realm); if (get_tgt (test_context, client, &client_princ, ccache)) { errors++; n_tried++; continue; } n_tried++; stmp[0] = '\0'; for (j = 1; j <= depth; j++) { (void) snprintf(stmp2, sizeof(stmp2), "%s%s%d-DEPTH-%d", (j != 1) ? "/" : "", prefix, n, j); stmp2[sizeof (stmp2) - 1] = '\0'; strncat(stmp, stmp2, sizeof(stmp) - 1 - strlen(stmp)); stmp[sizeof(stmp) - 1] = '\0'; snprintf(server, sizeof(server), "%s@%s", stmp, cur_realm); if (verify_cs_pair(test_context, client, client_princ, stmp, cur_realm, n, i, j, ccache)) errors++; n_tried++; } krb5_free_principal(test_context, client_princ); } } } fprintf (stderr, "\nTried %d. Got %d errors.\n", n_tried, errors); if (do_timer) { if (in_tkt_times.ht_observations) fprintf(stderr, "%8d AS_REQ requests: %9.6f average (min: %9.6f, max:%9.6f)\n", in_tkt_times.ht_observations, in_tkt_times.ht_cumulative / (float) in_tkt_times.ht_observations, in_tkt_times.ht_min, in_tkt_times.ht_max); if (tgs_req_times.ht_observations) fprintf(stderr, "%8d TGS_REQ requests: %9.6f average (min: %9.6f, max:%9.6f)\n", tgs_req_times.ht_observations, tgs_req_times.ht_cumulative / (float) tgs_req_times.ht_observations, tgs_req_times.ht_min, tgs_req_times.ht_max); } (void) krb5_cc_close(test_context, ccache); krb5_free_context(test_context); exit(errors); } static krb5_error_code get_server_key(krb5_context context, krb5_principal server, krb5_enctype enctype, krb5_keyblock **key) { krb5_error_code retval; krb5_encrypt_block eblock; char * string; krb5_data salt; krb5_data pwd; *key = NULL; if ((retval = krb5_principal2salt(context, server, &salt))) return retval; if ((retval = krb5_unparse_name(context, server, &string))) goto cleanup_salt; pwd.data = string; pwd.length = strlen(string); if ((*key = (krb5_keyblock *)malloc(sizeof(krb5_keyblock)))) { krb5_use_enctype(context, &eblock, enctype); retval = krb5_string_to_key(context, &eblock, *key, &pwd, &salt); if (retval) { free(*key); *key = NULL; } } else retval = ENOMEM; free(string); cleanup_salt: free(salt.data); return retval; } int verify_cs_pair(krb5_context context, char *p_client_str, krb5_principal p_client, char *service, char *hostname, int p_num, int c_depth, int s_depth, krb5_ccache ccache) { krb5_error_code retval; krb5_creds creds; krb5_creds * credsp = NULL; krb5_ticket * ticket = NULL; krb5_keyblock * keyblock = NULL; krb5_auth_context auth_context = NULL; krb5_data request_data = empty_data(); char * sname; float dt; if (brief) fprintf(stderr, "\tprinc (%d) client (%d) for server (%d)\n", p_num, c_depth, s_depth); else fprintf(stderr, "\tclient %s for server %s\n", p_client_str, service); /* Initialize variables */ memset(&creds, 0, sizeof(creds)); /* Do client side */ if (asprintf(&sname, "%s@%s", service, hostname) >= 0) { retval = krb5_parse_name(context, sname, &creds.server); free(sname); } else retval = ENOMEM; if (retval) return(retval); /* obtain ticket & session key */ if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { com_err(prog, retval, "while getting client princ for %s", hostname); return retval; } if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { com_err(prog, retval, "while getting creds for %s", hostname); return retval; } if (do_timer) swatch_on(); if ((retval = krb5_mk_req_extended(context, &auth_context, 0, NULL, credsp, &request_data))) { com_err(prog, retval, "while preparing AP_REQ for %s", hostname); goto cleanup; } krb5_auth_con_free(context, auth_context); auth_context = NULL; /* Do server side now */ if ((retval = get_server_key(context, credsp->server, credsp->keyblock.enctype, &keyblock))) { com_err(prog, retval, "while getting server key for %s", hostname); goto cleanup; } if (krb5_auth_con_init(context, &auth_context)) { com_err(prog, retval, "while creating auth_context for %s", hostname); goto cleanup; } if (krb5_auth_con_setuseruserkey(context, auth_context, keyblock)) { com_err(prog, retval, "while setting auth_context key %s", hostname); goto cleanup; } if ((retval = krb5_rd_req(context, &auth_context, &request_data, NULL /* server */, 0, NULL, &ticket))) { com_err(prog, retval, "while decoding AP_REQ for %s", hostname); goto cleanup; } if (do_timer) { dt = swatch_eltime(); tgs_req_times.ht_cumulative += dt; tgs_req_times.ht_observations++; if (dt > tgs_req_times.ht_max) tgs_req_times.ht_max = dt; if (dt < tgs_req_times.ht_min) tgs_req_times.ht_min = dt; } if (!(krb5_principal_compare(context,ticket->enc_part2->client,p_client))){ char *returned_client; if ((retval = krb5_unparse_name(context, ticket->enc_part2->client, &returned_client))) com_err (prog, retval, "Client not as expected, but cannot unparse client name"); else com_err (prog, 0, "Client not as expected (%s).", returned_client); retval = KRB5_PRINC_NOMATCH; free(returned_client); } else { retval = 0; } cleanup: krb5_free_cred_contents(context, &creds); krb5_free_ticket(context, ticket); krb5_auth_con_free(context, auth_context); krb5_free_keyblock(context, keyblock); krb5_free_data_contents(context, &request_data); krb5_free_creds(context, credsp); return retval; } int get_tgt(krb5_context context, char *p_client_str, krb5_principal *p_client, krb5_ccache ccache) { long lifetime = KRB5_DEFAULT_LIFE; /* -l option */ krb5_error_code code; krb5_creds my_creds; krb5_timestamp start; float dt; krb5_get_init_creds_opt *options; if (!brief) fprintf(stderr, "\tgetting TGT for %s\n", p_client_str); if ((code = krb5_timeofday(context, &start))) { com_err(prog, code, "while getting time of day"); return(-1); } memset(&my_creds, 0, sizeof(my_creds)); if ((code = krb5_parse_name (context, p_client_str, p_client))) { com_err (prog, code, "when parsing name %s", p_client_str); return(-1); } code = krb5_cc_initialize (context, ccache, *p_client); if (code != 0) { com_err (prog, code, "when initializing cache"); return(-1); } if (do_timer) swatch_on(); code = krb5_get_init_creds_opt_alloc(context, &options); if (code != 0) { com_err(prog, code, "when allocating init cred options"); return(-1); } krb5_get_init_creds_opt_set_tkt_life(options, lifetime); code = krb5_get_init_creds_opt_set_out_ccache(context, options, ccache); if (code != 0) { com_err(prog, code, "when setting init cred output ccache"); return(-1); } code = krb5_get_init_creds_password(context, &my_creds, *p_client, p_client_str, NULL, NULL, 0, NULL, options); if (do_timer) { dt = swatch_eltime(); in_tkt_times.ht_cumulative += dt; in_tkt_times.ht_observations++; if (dt > in_tkt_times.ht_max) in_tkt_times.ht_max = dt; if (dt < in_tkt_times.ht_min) in_tkt_times.ht_min = dt; } krb5_get_init_creds_opt_free(context, options); krb5_free_cred_contents(context, &my_creds); if (code != 0) { com_err (prog, code, "while getting initial credentials"); return(-1); } return(0); } krb5-1.22.1/src/tests/t_kdc_log.py0000775000175000017500000000114215051422640016572 0ustar ghudsonghudsonfrom k5test import * # Make a TGS request with an expired ticket. realm = K5Realm() realm.stop() realm.start_kdc(['-T', '3600']) realm.run([kvno, realm.host_princ], expected_code=1) kdc_logfile = os.path.join(realm.testdir, 'kdc.log') f = open(kdc_logfile, 'r') found_skew = False for line in f: if 'Clock skew too great' in line: found_skew = True if realm.user_princ not in line: fail('Client principal not logged in expired-ticket TGS request') f.close() if not found_skew: fail('Did not find KDC log line for expired-ticket TGS request') success('KDC logging tests') krb5-1.22.1/src/tests/asn.1/0000775000175000017500000000000015051422640015212 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/asn.1/ktest.h0000664000175000017500000002323315051422640016520 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/ktest.h */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __KTEST_H__ #define __KTEST_H__ #include "k5-int.h" #include "k5-spake.h" #include "kdb.h" #define SAMPLE_USEC 123456 #define SAMPLE_TIME 771228197 /* Fri Jun 10 6:03:17 GMT 1994 */ #define SAMPLE_SEQ_NUMBER 17 #define SAMPLE_NONCE 42 #define SAMPLE_FLAGS 0xFEDCBA98 #define SAMPLE_ERROR 0x3C; void ktest_make_sample_data(krb5_data *d); void ktest_make_sample_authenticator(krb5_authenticator *a); void ktest_make_sample_principal(krb5_principal *p); void ktest_make_sample_checksum(krb5_checksum *cs); void ktest_make_sample_keyblock(krb5_keyblock *kb); void ktest_make_sample_ticket(krb5_ticket *tkt); void ktest_make_sample_enc_data(krb5_enc_data *ed); void ktest_make_sample_enc_tkt_part(krb5_enc_tkt_part *etp); void ktest_make_sample_transited(krb5_transited *t); void ktest_make_sample_ticket_times(krb5_ticket_times *tt); void ktest_make_sample_addresses(krb5_address ***caddrs); void ktest_make_sample_address(krb5_address *a); void ktest_make_sample_authorization_data(krb5_authdata ***ad); void ktest_make_sample_authdata(krb5_authdata *ad); void ktest_make_sample_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ekr); void ktest_make_sample_kdc_req(krb5_kdc_req *kr); void ktest_make_sample_last_req(krb5_last_req_entry ***lr); void ktest_make_sample_last_req_entry(krb5_last_req_entry **lre); void ktest_make_sample_kdc_rep(krb5_kdc_rep *kdcr); void ktest_make_sample_pa_data_array(krb5_pa_data ***pad); void ktest_make_sample_empty_pa_data_array(krb5_pa_data ***pad); void ktest_make_sample_pa_data(krb5_pa_data *pad); void ktest_make_sample_ap_req(krb5_ap_req *ar); void ktest_make_sample_ap_rep(krb5_ap_rep *ar); void ktest_make_sample_ap_rep_enc_part(krb5_ap_rep_enc_part *arep); void ktest_make_sample_kdc_req_body(krb5_kdc_req *krb); void ktest_make_sample_safe(krb5_safe *s); void ktest_make_sample_priv(krb5_priv *p); void ktest_make_sample_priv_enc_part(krb5_priv_enc_part *pep); void ktest_make_sample_cred(krb5_cred *c); void ktest_make_sample_cred_enc_part(krb5_cred_enc_part *cep); void ktest_make_sample_sequence_of_ticket(krb5_ticket ***sot); void ktest_make_sample_error(krb5_error *kerr); void ktest_make_sequence_of_cred_info(krb5_cred_info ***soci); void ktest_make_sample_cred_info(krb5_cred_info *ci); void ktest_make_sample_etype_info(krb5_etype_info_entry ***p); void ktest_make_sample_etype_info2(krb5_etype_info_entry ***p); void ktest_make_sample_pa_enc_ts(krb5_pa_enc_ts *am); void ktest_make_sample_sam_challenge_2(krb5_sam_challenge_2 *p); void ktest_make_sample_sam_challenge_2_body(krb5_sam_challenge_2_body *p); void ktest_make_sample_sam_response_2(krb5_sam_response_2 *p); void ktest_make_sample_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p); void ktest_make_sample_pa_for_user(krb5_pa_for_user *p); void ktest_make_sample_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p); void ktest_make_sample_ad_kdcissued(krb5_ad_kdcissued *p); void ktest_make_sample_iakerb_header(krb5_iakerb_header *p); void ktest_make_sample_iakerb_finished(krb5_iakerb_finished *p); void ktest_make_sample_fast_response(krb5_fast_response *p); void ktest_make_sha256_alg(krb5_algorithm_identifier *p); void ktest_make_sha1_alg(krb5_algorithm_identifier *p); void ktest_make_minimal_otp_tokeninfo(krb5_otp_tokeninfo *p); void ktest_make_maximal_otp_tokeninfo(krb5_otp_tokeninfo *p); void ktest_make_minimal_pa_otp_challenge(krb5_pa_otp_challenge *p); void ktest_make_maximal_pa_otp_challenge(krb5_pa_otp_challenge *p); void ktest_make_minimal_pa_otp_req(krb5_pa_otp_req *p); void ktest_make_maximal_pa_otp_req(krb5_pa_otp_req *p); #ifndef DISABLE_PKINIT void ktest_make_sample_pa_pk_as_req(krb5_pa_pk_as_req *p); void ktest_make_sample_pa_pk_as_rep_dhInfo(krb5_pa_pk_as_rep *p); void ktest_make_sample_pa_pk_as_rep_encKeyPack(krb5_pa_pk_as_rep *p); void ktest_make_sample_auth_pack(krb5_auth_pack *p); void ktest_make_sample_kdc_dh_key_info(krb5_kdc_dh_key_info *p); void ktest_make_sample_reply_key_pack(krb5_reply_key_pack *p); void ktest_make_sample_sp80056a_other_info(krb5_sp80056a_other_info *p); void ktest_make_sample_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p); #endif #ifdef ENABLE_LDAP void ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data *p); #endif void ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p); void ktest_make_minimal_cammac(krb5_cammac *p); void ktest_make_maximal_cammac(krb5_cammac *p); void ktest_make_sample_secure_cookie(krb5_secure_cookie *p); void ktest_make_minimal_spake_factor(krb5_spake_factor *p); void ktest_make_maximal_spake_factor(krb5_spake_factor *p); void ktest_make_support_pa_spake(krb5_pa_spake *p); void ktest_make_challenge_pa_spake(krb5_pa_spake *p); void ktest_make_response_pa_spake(krb5_pa_spake *p); void ktest_make_encdata_pa_spake(krb5_pa_spake *p); /*----------------------------------------------------------------------*/ void ktest_empty_authorization_data(krb5_authdata **ad); void ktest_destroy_authorization_data(krb5_authdata ***ad); void ktest_destroy_authorization_data(krb5_authdata ***ad); void ktest_empty_addresses(krb5_address **a); void ktest_destroy_addresses(krb5_address ***a); void ktest_destroy_address(krb5_address **a); void ktest_empty_pa_data_array(krb5_pa_data **pad); void ktest_destroy_pa_data_array(krb5_pa_data ***pad); void ktest_destroy_pa_data(krb5_pa_data **pad); void ktest_destroy_data(krb5_data **d); void ktest_empty_data(krb5_data *d); void ktest_destroy_principal(krb5_principal *p); void ktest_destroy_checksum(krb5_checksum **cs); void ktest_empty_keyblock(krb5_keyblock *kb); void ktest_destroy_keyblock(krb5_keyblock **kb); void ktest_destroy_authdata(krb5_authdata **ad); void ktest_destroy_sequence_of_integer(long **soi); void ktest_destroy_sequence_of_ticket(krb5_ticket ***sot); void ktest_destroy_ticket(krb5_ticket **tkt); void ktest_empty_ticket(krb5_ticket *tkt); void ktest_destroy_enc_data(krb5_enc_data *ed); void ktest_empty_error(krb5_error *kerr); void ktest_destroy_etype_info_entry(krb5_etype_info_entry *i); void ktest_destroy_etype_info(krb5_etype_info_entry **info); void ktest_empty_kdc_req(krb5_kdc_req *kr); void ktest_empty_kdc_rep(krb5_kdc_rep *kr); void ktest_empty_authenticator(krb5_authenticator *a); void ktest_empty_enc_tkt_part(krb5_enc_tkt_part *etp); void ktest_destroy_enc_tkt_part(krb5_enc_tkt_part **etp); void ktest_empty_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ekr); void ktest_destroy_transited(krb5_transited *t); void ktest_empty_ap_rep(krb5_ap_rep *ar); void ktest_empty_ap_req(krb5_ap_req *ar); void ktest_empty_cred_enc_part(krb5_cred_enc_part *cep); void ktest_destroy_cred_info(krb5_cred_info **ci); void ktest_destroy_sequence_of_cred_info(krb5_cred_info ***soci); void ktest_empty_safe(krb5_safe *s); void ktest_empty_priv(krb5_priv *p); void ktest_empty_priv_enc_part(krb5_priv_enc_part *pep); void ktest_empty_cred(krb5_cred *c); void ktest_destroy_last_req(krb5_last_req_entry ***lr); void ktest_empty_ap_rep_enc_part(krb5_ap_rep_enc_part *arep); void ktest_empty_sam_challenge_2(krb5_sam_challenge_2 *p); void ktest_empty_sam_challenge_2_body(krb5_sam_challenge_2_body *p); void ktest_empty_sam_response_2(krb5_sam_response_2 *p); void ktest_empty_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p); void ktest_empty_pa_for_user(krb5_pa_for_user *p); void ktest_empty_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p); void ktest_empty_ad_kdcissued(krb5_ad_kdcissued *p); void ktest_empty_iakerb_header(krb5_iakerb_header *p); void ktest_empty_iakerb_finished(krb5_iakerb_finished *p); void ktest_empty_fast_response(krb5_fast_response *p); void ktest_empty_otp_tokeninfo(krb5_otp_tokeninfo *p); void ktest_empty_pa_otp_challenge(krb5_pa_otp_challenge *p); void ktest_empty_pa_otp_req(krb5_pa_otp_req *p); #ifndef DISABLE_PKINIT void ktest_empty_pa_pk_as_req(krb5_pa_pk_as_req *p); void ktest_empty_pa_pk_as_rep(krb5_pa_pk_as_rep *p); void ktest_empty_auth_pack(krb5_auth_pack *p); void ktest_empty_kdc_dh_key_info(krb5_kdc_dh_key_info *p); void ktest_empty_reply_key_pack(krb5_reply_key_pack *p); void ktest_empty_sp80056a_other_info(krb5_sp80056a_other_info *p); void ktest_empty_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p); #endif #ifdef ENABLE_LDAP void ktest_empty_ldap_seqof_key_data(ldap_seqof_key_data *p); #endif void ktest_empty_kkdcp_message(krb5_kkdcp_message *p); void ktest_empty_cammac(krb5_cammac *p); void ktest_empty_secure_cookie(krb5_secure_cookie *p); void ktest_empty_spake_factor(krb5_spake_factor *p); void ktest_empty_pa_spake(krb5_pa_spake *p); extern krb5_context test_context; extern char *sample_principal_name; #endif krb5-1.22.1/src/tests/asn.1/README0000664000175000017500000000243615051422640016077 0ustar ghudsonghudsonkrb5_encode_test runs through all the functions declared in src/include/krb5/asn.1/krb5_encode.h. It passes various sample inputs to each function and prints the result to standard output. This output should match the contents of the file "reference_encode.out". Each function is first run with a relatively simple, contrived sample structure. Then if the structure has any optional parts, these parts are cleared and another run is made. Some structures (namely, those containing a krb5_kdc_req_body) have a third run, due to the fact that two of the kdc_req_body's optional fields have mutually exclusive conditions under which they may be omitted. krb5_decode_test runs through all the functions declared in src/include/krb5/asn.1/krb5_decode.h. It has the encodings in reference_encode.out hard-coded into itself. It sets up the krb5 structures the same way krb5_encode_test does, then passes its hard-coded encoding strings through the krb5 decoders. The outputs of these functions are compared to the previously set-up structures in memory, and the results are reported to standard output. If every line comes out prefixed by "OK: ", then the decoders are working properly. If any decoder produces an anomalous output, then its output line will be prefixed by "ERROR: " krb5-1.22.1/src/tests/asn.1/pkinit-agility.asn10000664000175000017500000000711515051422640020740 0ustar ghudsonghudsonKerberosV5-PK-INIT-Agility-SPEC { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) pkinit(5) agility (1) } DEFINITIONS EXPLICIT TAGS ::= BEGIN IMPORTS AlgorithmIdentifier, SubjectPublicKeyInfo FROM PKIX1Explicit88 { iso (1) identified-organization (3) dod (6) internet (1) security (5) mechanisms (5) pkix (7) id-mod (0) id-pkix1-explicit (18) } -- As defined in RFC 3280. Ticket, Int32, Realm, EncryptionKey, Checksum FROM KerberosV5Spec2 { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2) } -- as defined in RFC 4120. PKAuthenticator, DHNonce FROM KerberosV5-PK-INIT-SPEC { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) pkinit(5) }; -- as defined in RFC 4556. TD-CMS-DIGEST-ALGORITHMS-DATA ::= SEQUENCE OF AlgorithmIdentifier -- Contains the list of CMS algorithm [RFC3852] -- identifiers that identify the digest algorithms -- acceptable by the KDC for signing CMS data in -- the order of decreasing preference. TD-CERT-DIGEST-ALGORITHMS-DATA ::= SEQUENCE { allowedAlgorithms [0] SEQUENCE OF AlgorithmIdentifier, -- Contains the list of CMS algorithm [RFC3852] -- identifiers that identify the digest algorithms -- that are used by the CA to sign the client's -- X.509 certificate and acceptable by the KDC in -- the process of validating the client's X.509 -- certificate, in the order of decreasing -- preference. rejectedAlgorithm [1] AlgorithmIdentifier OPTIONAL, -- This identifies the digest algorithm that was -- used to sign the client's X.509 certificate and -- has been rejected by the KDC in the process of -- validating the client's X.509 certificate -- [RFC3280]. ... } OtherInfo ::= SEQUENCE { algorithmID AlgorithmIdentifier, partyUInfo [0] OCTET STRING, partyVInfo [1] OCTET STRING, suppPubInfo [2] OCTET STRING OPTIONAL, suppPrivInfo [3] OCTET STRING OPTIONAL } PkinitSuppPubInfo ::= SEQUENCE { enctype [0] Int32, -- The enctype of the AS reply key. as-REQ [1] OCTET STRING, -- This contains the AS-REQ in the request. pk-as-rep [2] OCTET STRING, -- Contains the DER encoding of the type -- PA-PK-AS-REP [RFC4556] in the KDC reply. ... } -- Renamed from AuthPack to allow asn1c to process this and pkinit.asn1 AuthPack2 ::= SEQUENCE { pkAuthenticator [0] PKAuthenticator, clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL, supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL, clientDHNonce [3] DHNonce OPTIONAL, ..., supportedKDFs [4] SEQUENCE OF KDFAlgorithmId OPTIONAL, -- Contains an unordered set of KDFs supported by the -- client. ... } KDFAlgorithmId ::= SEQUENCE { kdf-id [0] OBJECT IDENTIFIER, -- The object identifier of the KDF ... } -- Renamed from DHRepInfo to allow asn1c to process this and pkinit.asn1 DHRepInfo2 ::= SEQUENCE { dhSignedData [0] IMPLICIT OCTET STRING, serverDHNonce [1] DHNonce OPTIONAL, ..., kdf [2] KDFAlgorithmId OPTIONAL, -- The KDF picked by the KDC. ... } END krb5-1.22.1/src/tests/asn.1/trval.c0000664000175000017500000004755215051422640016523 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1992,1993 Trusted Information Systems, Inc. * * Permission to include this software in the Kerberos V5 distribution * was graciously provided by Trusted Information Systems. * * Trusted Information Systems makes no representation about the * suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. */ /* * Copyright (C) 1994 Massachusetts Institute of Technology * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /***************************************************************************** * trval.c.c *****************************************************************************/ #include #include #include #include #include #define OK 0 #define NOTOK (-1) /* IDENTIFIER OCTET = TAG CLASS | FORM OF ENCODING | TAG NUMBER */ /* TAG CLASSES */ #define ID_CLASS 0xc0 /* bits 8 and 7 */ #define CLASS_UNIV 0x00 /* 0 = universal */ #define CLASS_APPL 0x40 /* 1 = application */ #define CLASS_CONT 0x80 /* 2 = context-specific */ #define CLASS_PRIV 0xc0 /* 3 = private */ /* FORM OF ENCODING */ #define ID_FORM 0x20 /* bit 6 */ #define FORM_PRIM 0x00 /* 0 = primitive */ #define FORM_CONS 0x20 /* 1 = constructed */ /* TAG NUMBERS */ #define ID_TAG 0x1f /* bits 5-1 */ #define PRIM_BOOL 0x01 /* Boolean */ #define PRIM_INT 0x02 /* Integer */ #define PRIM_BITS 0x03 /* Bit String */ #define PRIM_OCTS 0x04 /* Octet String */ #define PRIM_NULL 0x05 /* Null */ #define PRIM_OID 0x06 /* Object Identifier */ #define PRIM_ODE 0x07 /* Object Descriptor */ #define CONS_EXTN 0x08 /* External */ #define PRIM_REAL 0x09 /* Real */ #define PRIM_ENUM 0x0a /* Enumerated type */ #define PRIM_ENCR 0x0b /* Encrypted */ #define PRIM_UTF8 0x0c /* UTF8String */ #define CONS_SEQ 0x10 /* SEQUENCE/SEQUENCE OF */ #define CONS_SET 0x11 /* SET/SET OF */ #define DEFN_NUMS 0x12 /* Numeric String */ #define DEFN_PRTS 0x13 /* Printable String */ #define DEFN_T61S 0x14 /* T.61 String */ #define DEFN_VTXS 0x15 /* Videotex String */ #define DEFN_IA5S 0x16 /* IA5 String */ #define DEFN_UTCT 0x17 /* UTCTime */ #define DEFN_GENT 0x18 /* Generalized Time */ #define DEFN_GFXS 0x19 /* Graphics string (ISO2375) */ #define DEFN_VISS 0x1a /* Visible string */ #define DEFN_GENS 0x1b /* General string */ #define DEFN_CHRS 0x1c /* Character string */ #define LEN_XTND 0x80 /* long or indefinite form */ #define LEN_SMAX 127 /* largest short form */ #define LEN_MASK 0x7f /* mask to get number of bytes in length */ #define LEN_INDF (-1) /* indefinite length */ #define KRB5 /* Do krb5 application types */ int print_types = 0; int print_id_and_len = 1; int print_constructed_length = 1; int print_primitive_length = 1; int print_skip_context = 0; int print_skip_tagnum = 1; int print_context_shortcut = 0; int do_hex = 0; #ifdef KRB5 int print_krb5_types = 0; #endif int current_appl_type = -1; int decode_len (FILE *, unsigned char *, int); int do_prim (FILE *, int, unsigned char *, int, int); int do_cons (FILE *, unsigned char *, int, int, int *); int do_prim_bitstring (FILE *, int, unsigned char *, int, int); int do_prim_int (FILE *, int, unsigned char *, int, int); int do_prim_string (FILE *, int, unsigned char *, int, int); void print_tag_type (FILE *, int, int); int trval (FILE *, FILE *); int trval2 (FILE *, unsigned char *, int, int, int *); /****************************************************************************/ static int convert_nibble(int ch) { if (isdigit(ch)) return (ch - '0'); if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 10); if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 10); return -1; } int trval(FILE *fin, FILE *fout) { unsigned char *p; unsigned int maxlen; int len; int cc, cc2, n1, n2; int r; int rlen; maxlen = BUFSIZ; p = (unsigned char *)malloc(maxlen); len = 0; while ((cc = fgetc(fin)) != EOF) { if ((unsigned int) len == maxlen) { maxlen += BUFSIZ; p = (unsigned char *)realloc(p, maxlen); } if (do_hex) { if (cc == ' ' || cc == '\n' || cc == '\t') continue; cc2 = fgetc(fin); if (cc2 == EOF) break; n1 = convert_nibble(cc); n2 = convert_nibble(cc2); cc = (n1 << 4) + n2; } p[len++] = cc; } fprintf(fout, "<%d>", len); r = trval2(fout, p, len, 0, &rlen); fprintf(fout, "\n"); (void) free(p); return(r); } int trval2(FILE *fp, unsigned char *enc, int len, int lev, int *rlen) { int l, eid, elen, xlen, r, rlen2 = 0; int rlen_ext = 0; r = OK; *rlen = -1; if (len < 2) { fprintf(fp, "missing id and length octets (%d)\n", len); return(NOTOK); } fprintf(fp, "\n"); for (l=0; l len - 2) { fprintf(fp, "extended length too long (%d > %d - 2)\n", xlen, len); return(NOTOK); } elen = decode_len(fp, enc+2, xlen); } if (elen > len - 2 - xlen) { fprintf(fp, "length too long (%d > %d - 2 - %d)\n", elen, len, xlen); return(NOTOK); } print_tag_type(fp, eid, lev); if (print_context_shortcut && (eid & ID_CLASS) == CLASS_CONT && (eid & ID_FORM) == FORM_CONS && lev > 0) { rlen_ext += 2 + xlen; enc += 2 + xlen; fprintf(fp, " "); goto context_restart; } switch(eid & ID_FORM) { case FORM_PRIM: r = do_prim(fp, eid & ID_TAG, enc+2+xlen, elen, lev+1); *rlen = 2 + xlen + elen + rlen_ext; break; case FORM_CONS: if (print_constructed_length) { fprintf(fp, " constr"); fprintf(fp, " <%d>", elen); } r = do_cons(fp, enc+2+xlen, elen, lev+1, &rlen2); *rlen = 2 + xlen + rlen2 + rlen_ext; break; } return(r); } int decode_len(FILE *fp, unsigned char *enc, int len) { int rlen; int i; if (print_id_and_len) fprintf(fp, "%02x ", enc[0]); rlen = enc[0]; for (i=1; i 5) return 0; for (i=1; i < len; i++) { num = num << 8; num += enc[i]; } fprintf(fp, " 0x%lx", num); if (enc[0]) fprintf(fp, " (%d unused bits)", enc[0]); return 1; } /* * This is the printing function for integers */ int do_prim_int(FILE *fp, int tag, unsigned char *enc, int len, int lev) { int i; long num = 0; if (tag != PRIM_INT || len > 4) return 0; if (enc[0] & 0x80) num = -1; for (i=0; i < len; i++) { num = num << 8; num += enc[i]; } fprintf(fp, " %ld", num); return 1; } /* * This is the printing function which we use if it's a string or * other other type which is best printed as a string */ int do_prim_string(FILE *fp, int tag, unsigned char *enc, int len, int lev) { int i; /* * Only try this printing function with "reasonable" types */ if ((tag < DEFN_NUMS) && (tag != PRIM_OCTS) && (tag != PRIM_UTF8)) return 0; for (i=0; i < len; i++) if (!isprint(enc[i])) return 0; fprintf(fp, " \"%.*s\"", len, enc); return 1; } int do_prim(FILE *fp, int tag, unsigned char *enc, int len, int lev) { int n; int i; int j; int width; if (do_prim_string(fp, tag, enc, len, lev)) return OK; if (do_prim_int(fp, tag, enc, len, lev)) return OK; if (do_prim_bitstring(fp, tag, enc, len, lev)) return OK; if (print_primitive_length) fprintf(fp, " <%d>", len); width = (80 - (lev * 3) - 8) / 4; for (n = 0; n < len; n++) { if ((n % width) == 0) { fprintf(fp, "\n"); for (i=0; ik1 > 0; ent++) { if ((ent->k1 == key1) && (ent->k2 == key2)) { if (ent->new_appl) current_appl_type = ent->new_appl; return ent->str; } } return 0; } struct typestring_table univ_types[] = { { PRIM_BOOL, -1, "Boolean"}, { PRIM_INT, -1, "Integer"}, { PRIM_BITS, -1, "Bit String"}, { PRIM_OCTS, -1, "Octet String"}, { PRIM_NULL, -1, "Null"}, { PRIM_OID, -1, "Object Identifier"}, { PRIM_ODE, -1, "Object Descriptor"}, { CONS_EXTN, -1, "External"}, { PRIM_REAL, -1, "Real"}, { PRIM_ENUM, -1, "Enumerated type"}, { PRIM_ENCR, -1, "Encrypted"}, { PRIM_UTF8, -1, "UTF8String"}, { CONS_SEQ, -1, "Sequence/Sequence Of"}, { CONS_SET, -1, "Set/Set Of"}, { DEFN_NUMS, -1, "Numeric String"}, { DEFN_PRTS, -1, "Printable String"}, { DEFN_T61S, -1, "T.61 String"}, { DEFN_VTXS, -1, "Videotex String"}, { DEFN_IA5S, -1, "IA5 String"}, { DEFN_UTCT, -1, "UTCTime"}, { DEFN_GENT, -1, "Generalized Time"}, { DEFN_GFXS, -1, "Graphics string (ISO2375)"}, { DEFN_VISS, -1, "Visible string"}, { DEFN_GENS, -1, "General string"}, { DEFN_CHRS, -1, "Character string"}, { -1, -1, 0} }; #ifdef KRB5 struct typestring_table krb5_types[] = { { 1, -1, "Krb5 Ticket"}, { 2, -1, "Krb5 Authenticator"}, { 3, -1, "Krb5 Encrypted ticket part"}, { 10, -1, "Krb5 AS-REQ packet"}, { 11, -1, "Krb5 AS-REP packet"}, { 12, -1, "Krb5 TGS-REQ packet"}, { 13, -1, "Krb5 TGS-REP packet"}, { 14, -1, "Krb5 AP-REQ packet"}, { 15, -1, "Krb5 AP-REP packet"}, { 20, -1, "Krb5 SAFE packet"}, { 21, -1, "Krb5 PRIV packet"}, { 22, -1, "Krb5 CRED packet"}, { 30, -1, "Krb5 ERROR packet"}, { 25, -1, "Krb5 Encrypted AS-REP part"}, { 26, -1, "Krb5 Encrypted TGS-REP part"}, { 27, -1, "Krb5 Encrypted AP-REP part"}, { 28, -1, "Krb5 Encrypted PRIV part"}, { 29, -1, "Krb5 Encrypted CRED part"}, { -1, -1, 0} }; struct typestring_table krb5_fields[] = { { 1000, 0, "name-type"}, /* PrincipalName */ { 1000, 1, "name-string"}, { 1001, 0, "etype"}, /* Encrypted data */ { 1001, 1, "kvno"}, { 1001, 2, "cipher"}, { 1002, 0, "addr-type"}, /* HostAddress */ { 1002, 1, "address"}, { 1003, 0, "addr-type"}, /* HostAddresses */ { 1003, 1, "address"}, { 1004, 0, "ad-type"}, /* AuthorizationData */ { 1004, 1, "ad-data"}, { 1005, 0, "keytype"}, /* EncryptionKey */ { 1005, 1, "keyvalue"}, { 1006, 0, "cksumtype"}, /* Checksum */ { 1006, 1, "checksum"}, { 1007, 0, "kdc-options"}, /* KDC-REQ-BODY */ { 1007, 1, "cname", 1000}, { 1007, 2, "realm"}, { 1007, 3, "sname", 1000}, { 1007, 4, "from"}, { 1007, 5, "till"}, { 1007, 6, "rtime"}, { 1007, 7, "nonce"}, { 1007, 8, "etype"}, { 1007, 9, "addresses", 1003}, { 1007, 10, "enc-authorization-data", 1001}, { 1007, 11, "additional-tickets"}, { 1008, 1, "padata-type"}, /* PA-DATA */ { 1008, 2, "pa-data"}, { 1009, 0, "user-data"}, /* KRB-SAFE-BODY */ { 1009, 1, "timestamp"}, { 1009, 2, "usec"}, { 1009, 3, "seq-number"}, { 1009, 4, "s-address", 1002}, { 1009, 5, "r-address", 1002}, { 1010, 0, "lr-type"}, /* LastReq */ { 1010, 1, "lr-value"}, { 1011, 0, "key", 1005}, /* KRB-CRED-INFO */ { 1011, 1, "prealm"}, { 1011, 2, "pname", 1000}, { 1011, 3, "flags"}, { 1011, 4, "authtime"}, { 1011, 5, "startime"}, { 1011, 6, "endtime"}, { 1011, 7, "renew-till"}, { 1011, 8, "srealm"}, { 1011, 9, "sname", 1000}, { 1011, 10, "caddr", 1002}, { 1, 0, "tkt-vno"}, /* Ticket */ { 1, 1, "realm"}, { 1, 2, "sname", 1000}, { 1, 3, "tkt-enc-part", 1001}, { 2, 0, "authenticator-vno"}, /* Authenticator */ { 2, 1, "crealm"}, { 2, 2, "cname", 1000}, { 2, 3, "cksum", 1006}, { 2, 4, "cusec"}, { 2, 5, "ctime"}, { 2, 6, "subkey", 1005}, { 2, 7, "seq-number"}, { 2, 8, "authorization-data", 1004}, { 3, 0, "flags"}, /* EncTicketPart */ { 3, 1, "key", 1005}, { 3, 2, "crealm"}, { 3, 3, "cname", 1000}, { 3, 4, "transited"}, { 3, 5, "authtime"}, { 3, 6, "starttime"}, { 3, 7, "endtime"}, { 3, 8, "renew-till"}, { 3, 9, "caddr", 1003}, { 3, 10, "authorization-data", 1004}, { 10, 1, "pvno"}, /* AS-REQ */ { 10, 2, "msg-type"}, { 10, 3, "padata", 1008}, { 10, 4, "req-body", 1007}, { 11, 0, "pvno"}, /* AS-REP */ { 11, 1, "msg-type"}, { 11, 2, "padata", 1008}, { 11, 3, "crealm"}, { 11, 4, "cname", 1000}, { 11, 5, "ticket"}, { 11, 6, "enc-part", 1001}, { 12, 1, "pvno"}, /* TGS-REQ */ { 12, 2, "msg-type"}, { 12, 3, "padata", 1008}, { 12, 4, "req-body", 1007}, { 13, 0, "pvno"}, /* TGS-REP */ { 13, 1, "msg-type"}, { 13, 2, "padata", 1008}, { 13, 3, "crealm"}, { 13, 4, "cname", 1000}, { 13, 5, "ticket"}, { 13, 6, "enc-part", 1001}, { 14, 0, "pvno"}, /* AP-REQ */ { 14, 1, "msg-type"}, { 14, 2, "ap-options"}, { 14, 3, "ticket"}, { 14, 4, "authenticator", 1001}, { 15, 0, "pvno"}, /* AP-REP */ { 15, 1, "msg-type"}, { 15, 2, "enc-part", 1001}, { 20, 0, "pvno"}, /* KRB-SAFE */ { 20, 1, "msg-type"}, { 20, 2, "safe-body", 1009}, { 20, 3, "cksum", 1006}, { 21, 0, "pvno"}, /* KRB-PRIV */ { 21, 1, "msg-type"}, { 21, 2, "enc-part", 1001}, { 22, 0, "pvno"}, /* KRB-CRED */ { 22, 1, "msg-type"}, { 22, 2, "tickets"}, { 22, 3, "enc-part", 1001}, { 25, 0, "key", 1005}, /* EncASRepPart */ { 25, 1, "last-req", 1010}, { 25, 2, "nonce"}, { 25, 3, "key-expiration"}, { 25, 4, "flags"}, { 25, 5, "authtime"}, { 25, 6, "starttime"}, { 25, 7, "enddtime"}, { 25, 8, "renew-till"}, { 25, 9, "srealm"}, { 25, 10, "sname", 1000}, { 25, 11, "caddr", 1003}, { 26, 0, "key", 1005}, /* EncTGSRepPart */ { 26, 1, "last-req", 1010}, { 26, 2, "nonce"}, { 26, 3, "key-expiration"}, { 26, 4, "flags"}, { 26, 5, "authtime"}, { 26, 6, "starttime"}, { 26, 7, "enddtime"}, { 26, 8, "renew-till"}, { 26, 9, "srealm"}, { 26, 10, "sname", 1000}, { 26, 11, "caddr", 1003}, { 27, 0, "ctime"}, /* EncApRepPart */ { 27, 1, "cusec"}, { 27, 2, "subkey", 1005}, { 27, 3, "seq-number"}, { 28, 0, "user-data"}, /* EncKrbPrivPart */ { 28, 1, "timestamp"}, { 28, 2, "usec"}, { 28, 3, "seq-number"}, { 28, 4, "s-address", 1002}, { 28, 5, "r-address", 1002}, { 29, 0, "ticket-info", 1011}, /* EncKrbCredPart */ { 29, 1, "nonce"}, { 29, 2, "timestamp"}, { 29, 3, "usec"}, { 29, 4, "s-address", 1002}, { 29, 5, "r-address", 1002}, { 30, 0, "pvno"}, /* KRB-ERROR */ { 30, 1, "msg-type"}, { 30, 2, "ctime"}, { 30, 3, "cusec"}, { 30, 4, "stime"}, { 30, 5, "susec"}, { 30, 6, "error-code"}, { 30, 7, "crealm"}, { 30, 8, "cname", 1000}, { 30, 9, "realm"}, { 30, 10, "sname", 1000}, { 30, 11, "e-text"}, { 30, 12, "e-data"}, { -1, -1, 0} }; #endif void print_tag_type(FILE *fp, int eid, int lev) { int tag = eid & ID_TAG; int do_space = 1; char *str; fprintf(fp, "["); switch(eid & ID_CLASS) { case CLASS_UNIV: if (print_types && print_skip_tagnum) do_space = 0; else fprintf(fp, "UNIV %d", tag); break; case CLASS_APPL: current_appl_type = tag; #ifdef KRB5 if (print_krb5_types) { str = lookup_typestring(krb5_types, tag, -1); if (str) { fputs(str, fp); break; } } #endif fprintf(fp, "APPL %d", tag); break; case CLASS_CONT: #ifdef KRB5 if (print_krb5_types && current_appl_type) { str = lookup_typestring(krb5_fields, current_appl_type, tag); if (str) { fputs(str, fp); break; } } #endif if (print_skip_context && lev) fprintf(fp, "%d", tag); else fprintf(fp, "CONT %d", tag); break; case CLASS_PRIV: fprintf(fp, "PRIV %d", tag); break; } if (print_types && ((eid & ID_CLASS) == CLASS_UNIV)) { if (do_space) fputs(" ", fp); str = lookup_typestring(univ_types, eid & ID_TAG, -1); if (str) fputs(str, fp); else fprintf(fp, "UNIV %d???", eid & ID_TAG); } fprintf(fp, "]"); } /*****************************************************************************/ krb5-1.22.1/src/tests/asn.1/Makefile.in0000664000175000017500000000635515051422640017270 0ustar ghudsonghudsonmydir=tests$(S)asn.1 BUILDTOP=$(REL)..$(S).. LDAP=@LDAP@ SRCS= $(srcdir)/krb5_encode_test.c $(srcdir)/krb5_decode_test.c \ $(srcdir)/krb5_decode_leak.c $(srcdir)/ktest.c \ $(srcdir)/ktest_equal.c $(srcdir)/utility.c \ $(srcdir)/trval.c $(srcdir)/t_trval.c ASN1SRCS= $(srcdir)/krb5.asn1 $(srcdir)/pkix.asn1 $(srcdir)/otp.asn1 \ $(srcdir)/pkinit.asn1 $(srcdir)/pkinit-agility.asn1 \ $(srcdir)/cammac.asn1 $(srcdir)/spake.asn1 all: krb5_encode_test krb5_decode_test krb5_decode_leak t_trval ENCOBJS = krb5_encode_test.o ktest.o ktest_equal.o utility.o trval.o krb5_encode_test: $(ENCOBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o krb5_encode_test $(ENCOBJS) $(KRB5_BASE_LIBS) DECOBJS = krb5_decode_test.o ktest.o ktest_equal.o utility.o krb5_decode_test: $(DECOBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o krb5_decode_test $(DECOBJS) $(KRB5_BASE_LIBS) LEAKOBJS = krb5_decode_leak.o ktest.o ktest_equal.o utility.o krb5_decode_leak: $(LEAKOBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o krb5_decode_leak $(LEAKOBJS) $(KRB5_BASE_LIBS) t_trval: t_trval.o $(CC) -o t_trval $(ALL_CFLAGS) t_trval.o check: check-encode check-encode-trval check-decode check-leak # Does not actually test for leaks unless using valgrind or a similar # tool, but does exercise a bunch of code. check-leak: krb5_decode_leak $(RUN_TEST) ./krb5_decode_leak check-decode: krb5_decode_test $(RUN_TEST) ./krb5_decode_test PKINIT_ENCODE_OUT=$(PKINIT_ENCODE_OUT-@PKINIT@) PKINIT_ENCODE_OUT-yes=$(srcdir)/pkinit_encode.out PKINIT_ENCODE_OUT-no= LDAP_ENCODE_OUT=$(LDAP_ENCODE_OUT-@LDAP@) LDAP_ENCODE_OUT-yes=$(srcdir)/ldap_encode.out LDAP_ENCODE_OUT-no= expected_encode.out: reference_encode.out pkinit_encode.out ldap_encode.out cat $(srcdir)/reference_encode.out $(PKINIT_ENCODE_OUT) \ $(LDAP_ENCODE_OUT) > $@ PKINIT_TRVAL_OUT=$(PKINIT_TRVAL_OUT-@PKINIT@) PKINIT_TRVAL_OUT-yes=$(srcdir)/pkinit_trval.out PKINIT_TRVAL_OUT-no= LDAP_TRVAL_OUT=$(LDAP_TRVAL_OUT-@LDAP@) LDAP_TRVAL_OUT-yes=$(srcdir)/ldap_trval.out LDAP_TRVAL_OUT-no= expected_trval.out: trval_reference.out pkinit_trval.out ldap_trval.out cat $(srcdir)/trval_reference.out $(PKINIT_TRVAL_OUT) \ $(LDAP_TRVAL_OUT) > $@ check-encode: krb5_encode_test expected_encode.out $(RUN_TEST) ./krb5_encode_test > test.out cmp test.out expected_encode.out check-encode-trval: krb5_encode_test expected_trval.out $(RUN_TEST) ./krb5_encode_test -t > trval.out cmp trval.out expected_trval.out # This target uses asn1c to generate encodings of sample objects, to # help ensure that our implementation is correct. asn1c must be in the # path for this to work. test-vectors: $(RM) -r vectors mkdir vectors cp $(ASN1SRCS) $(srcdir)/make-vectors.c vectors (cd vectors && asn1c *.asn1 && rm converter-sample.c) (cd vectors && $(CC) -I. -w *.c -o make-vectors) (cd vectors && ./make-vectors) install: clean: rm -f *~ *.o krb5_encode_test krb5_decode_test krb5_decode_leak test.out trval t_trval expected_encode.out expected_trval.out trval.out ################ Dependencies ################ krb5_decode_test.o: ktest.h utility.h ktest_equal.h debug.h krb5_encode_test.o: utility.h ktest.h debug.h trval.o: trval.c ktest.o: ktest.h utility.h ktest_equal.o: ktest_equal.h #utility.o: utility.h #utility.h: krbasn1.h asn1buf.h ############################################## krb5-1.22.1/src/tests/asn.1/ldap_trval.out0000664000175000017500000000154415051422640020077 0ustar ghudsonghudson encode_krb5_ldap_seqof_key_data: [Sequence/Sequence Of] . [0] [Integer] 1 . [1] [Integer] 1 . [2] [Integer] 42 . [3] [Integer] 14 . [4] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Sequence/Sequence Of] . . . . [0] [Integer] 0 . . . . [1] [Octet String] "salt0" . . . [1] [Sequence/Sequence Of] . . . . [0] [Integer] 2 . . . . [1] [Octet String] "key0" . . [Sequence/Sequence Of] . . . [0] [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . . [1] [Octet String] "salt1" . . . [1] [Sequence/Sequence Of] . . . . [0] [Integer] 2 . . . . [1] [Octet String] "key1" . . [Sequence/Sequence Of] . . . [0] [Sequence/Sequence Of] . . . . [0] [Integer] 2 . . . . [1] [Octet String] "salt2" . . . [1] [Sequence/Sequence Of] . . . . [0] [Integer] 2 . . . . [1] [Octet String] "key2" krb5-1.22.1/src/tests/asn.1/t_trval.c0000664000175000017500000000700615051422640017034 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1992,1993 Trusted Information Systems, Inc. * * Permission to include this software in the Kerberos V5 distribution * was graciously provided by Trusted Information Systems. * * Trusted Information Systems makes no representation about the * suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * Copyright (C) 1994 Massachusetts Institute of Technology * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* Split out from "#ifdef STANDALONE" code previously in trval.c, so that trval.o could be linked into other tests too without the -DSTANDALONE code. */ #include "trval.c" static void usage(void) { fprintf(stderr, "Usage: trval [--types] [--krb5] [--krb5decode] [--hex] [-notypebytes] [file]\n"); exit(1); } /* * Returns true if the option was selected. Allow "-option" and * "--option" syntax, since we used to accept only "-option" */ static int check_option(char *word, char *option) { if (word[0] != '-') return 0; if (word[1] == '-') word++; if (strcmp(word+1, option)) return 0; return 1; } int main(int argc, char **argv) { int optflg = 1; FILE *fp; int r = 0; while (--argc > 0) { argv++; if (optflg && *(argv)[0] == '-') { if (check_option(*argv, "help")) usage(); else if (check_option(*argv, "types")) print_types = 1; else if (check_option(*argv, "notypes")) print_types = 0; else if (check_option(*argv, "krb5")) print_krb5_types = 1; else if (check_option(*argv, "hex")) do_hex = 1; else if (check_option(*argv, "notypebytes")) print_id_and_len = 0; else if (check_option(*argv, "krb5decode")) { print_id_and_len = 0; print_krb5_types = 1; print_types = 1; } else { fprintf(stderr,"trval: unknown option: %s\n", *argv); usage(); } } else { optflg = 0; if ((fp = fopen(*argv,"r")) == NULL) { fprintf(stderr,"trval: unable to open %s\n", *argv); continue; } r = trval(fp, stdout); fclose(fp); } } if (optflg) r = trval(stdin, stdout); exit(r); } krb5-1.22.1/src/tests/asn.1/reference_encode.out0000664000175000017500000007463515051422640021235 0ustar ghudsonghudsonencode_krb5_authenticator: 62 81 A1 30 81 9E A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A7 03 02 01 11 A8 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 encode_krb5_authenticator(optionals empty): 62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_authenticator(optionals NULL): 62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_ticket: 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_keyblock: 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 encode_krb5_enc_tkt_part: 63 82 01 14 30 82 01 10 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 encode_krb5_enc_tkt_part(optionals NULL): 63 81 A5 30 81 A2 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_enc_kdc_rep_part: 7A 82 01 0E 30 82 01 0A A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_enc_kdc_rep_part(optionals NULL): 7A 81 B2 30 81 AF A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 encode_krb5_as_rep: 6B 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0B A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_as_rep(optionals NULL): 6B 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0B A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_tgs_rep: 6D 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0D A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_tgs_rep(optionals NULL): 6D 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0D A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_ap_req: 6E 81 9D 30 81 9A A0 03 02 01 05 A1 03 02 01 0E A2 07 03 05 00 FE DC BA 98 A3 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_ap_rep: 6F 33 30 31 A0 03 02 01 05 A1 03 02 01 0F A2 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_ap_rep_enc_part: 7B 36 30 34 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A3 03 02 01 11 encode_krb5_ap_rep_enc_part(optionals NULL): 7B 1C 30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 encode_krb5_as_req: 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_as_req(optionals NULL except second_ticket): 6A 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0A A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_as_req(optionals NULL except server): 6A 69 30 67 A1 03 02 01 05 A2 03 02 01 0A A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 encode_krb5_tgs_req: 6C 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0C A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_tgs_req(optionals NULL except second_ticket): 6C 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0C A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_tgs_req(optionals NULL except server): 6C 69 30 67 A1 03 02 01 05 A2 03 02 01 0C A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 encode_krb5_kdc_req_body: 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_kdc_req_body(optionals NULL except second_ticket): 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_kdc_req_body(optionals NULL except server): 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 encode_krb5_safe: 74 6E 30 6C A0 03 02 01 05 A1 03 02 01 14 A2 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_safe(optionals NULL): 74 3E 30 3C A0 03 02 01 05 A1 03 02 01 14 A2 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_priv: 75 33 30 31 A0 03 02 01 05 A1 03 02 01 15 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_enc_priv_part: 7C 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_enc_priv_part(optionals NULL): 7C 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_cred: 76 81 F6 30 81 F3 A0 03 02 01 05 A1 03 02 01 16 A2 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_enc_cred_part: 7D 82 02 23 30 82 02 1F A0 82 01 DA 30 82 01 D6 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_enc_cred_part(optionals NULL): 7D 82 01 0E 30 82 01 0A A0 82 01 06 30 82 01 02 30 15 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 encode_krb5_error: 7E 81 BA 30 81 B7 A0 03 02 01 05 A1 03 02 01 1E A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A7 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A8 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 0A 1B 08 6B 72 62 35 64 61 74 61 AC 0A 04 08 6B 72 62 35 64 61 74 61 encode_krb5_error(optionals NULL): 7E 60 30 5E A0 03 02 01 05 A1 03 02 01 1E A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 encode_krb5_authorization_data: 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 encode_krb5_padata_sequence: 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 encode_krb5_typed_data: 30 24 30 10 A0 03 02 01 0D A1 09 04 07 70 61 2D 64 61 74 61 30 10 A0 03 02 01 0D A1 09 04 07 70 61 2D 64 61 74 61 encode_krb5_padata_sequence(empty): 30 00 encode_krb5_etype_info: 30 33 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 30 05 A0 03 02 01 01 30 14 A0 03 02 01 02 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 32 encode_krb5_etype_info(only 1): 30 16 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 encode_krb5_etype_info(no info): 30 00 encode_krb5_etype_info2: 30 51 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30 30 0F A0 03 02 01 01 A2 08 04 06 73 32 6B 3A 20 31 30 1E A0 03 02 01 02 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 32 A2 08 04 06 73 32 6B 3A 20 32 encode_krb5_etype_info2(only 1): 30 20 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30 encode_krb5_pa_enc_ts: 30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 encode_krb5_pa_enc_ts (no usec): 30 13 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_enc_data: 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_enc_data(MSB-set kvno): 30 26 A0 03 02 01 00 A1 06 02 04 FF 00 00 00 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_enc_data(kvno=-1): 30 23 A0 03 02 01 00 A1 03 02 01 FF A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_sam_challenge_2: 30 22 A0 0D 30 0B 04 09 63 68 61 6C 6C 65 6E 67 65 A1 11 30 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_sam_challenge_2_body: 30 64 A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0B 04 09 74 79 70 65 20 6E 61 6D 65 A4 11 04 0F 63 68 61 6C 6C 65 6E 67 65 20 6C 61 62 65 6C A5 10 04 0E 63 68 61 6C 6C 65 6E 67 65 20 69 70 73 65 A6 16 04 14 72 65 73 70 6F 6E 73 65 5F 70 72 6F 6D 70 74 20 69 70 73 65 A8 05 02 03 54 32 10 A9 03 02 01 14 encode_krb5_sam_response_2: 30 42 A0 03 02 01 2B A1 07 03 05 00 80 00 00 00 A2 0C 04 0A 74 72 61 63 6B 20 64 61 74 61 A3 1D 30 1B A0 03 02 01 14 A1 04 02 02 0D 36 A2 0E 04 0C 6E 6F 6E 63 65 20 6F 72 20 73 61 64 A4 05 02 03 54 32 10 encode_krb5_enc_sam_response_enc_2: 30 1F A0 03 02 01 58 A1 18 04 16 65 6E 63 5F 73 61 6D 5F 72 65 73 70 6F 6E 73 65 5F 65 6E 63 5F 32 encode_krb5_pa_for_user: 30 4B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 0A 1B 08 6B 72 62 35 64 61 74 61 encode_krb5_pa_s4u_x509_user: 30 68 A0 55 30 53 A0 06 02 04 00 CA 14 9A A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 12 04 10 70 61 5F 73 34 75 5F 78 35 30 39 5F 75 73 65 72 A4 07 03 05 00 80 00 00 00 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_ad_kdcissued: 30 65 A0 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 encode_krb5_iakerb_header: 30 18 A1 0A 0C 08 6B 72 62 35 64 61 74 61 A2 0A 04 08 6B 72 62 35 64 61 74 61 encode_krb5_iakerb_finished: 30 11 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_fast_response: 30 81 9F A0 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 5B 30 59 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 03 02 01 2A encode_krb5_pa_fx_fast_reply: A0 29 30 27 A0 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_otp_tokeninfo(optionals NULL): 30 07 80 05 00 00 00 00 00 encode_krb5_otp_tokeninfo: 30 72 80 05 00 77 00 00 00 81 0B 45 78 61 6D 70 6C 65 63 6F 72 70 82 05 68 61 72 6B 21 83 01 0A 84 01 02 85 09 79 6F 75 72 74 6F 6B 65 6E 86 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 A7 16 30 0B 06 09 60 86 48 01 65 03 04 02 01 30 07 06 05 2B 0E 03 02 1A 88 02 03 E8 encode_krb5_pa_otp_challenge(optionals NULL): 30 15 80 08 6D 69 6E 6E 6F 6E 63 65 A2 09 30 07 80 05 00 00 00 00 00 encode_krb5_pa_otp_challenge: 30 81 A5 80 08 6D 61 78 6E 6F 6E 63 65 81 0B 74 65 73 74 73 65 72 76 69 63 65 A2 7D 30 07 80 05 00 00 00 00 00 30 72 80 05 00 77 00 00 00 81 0B 45 78 61 6D 70 6C 65 63 6F 72 70 82 05 68 61 72 6B 21 83 01 0A 84 01 02 85 09 79 6F 75 72 74 6F 6B 65 6E 86 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 A7 16 30 0B 06 09 60 86 48 01 65 03 04 02 01 30 07 06 05 2B 0E 03 02 1A 88 02 03 E8 83 07 6B 65 79 73 61 6C 74 84 04 31 32 33 34 encode_krb5_pa_otp_req(optionals NULL): 30 2C 80 05 00 00 00 00 00 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_pa_otp_req: 30 81 B9 80 05 00 60 00 00 00 81 05 6E 6F 6E 63 65 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 0B 06 09 60 86 48 01 65 03 04 02 01 84 02 03 E8 85 05 66 72 6F 67 73 86 0A 6D 79 66 69 72 73 74 70 69 6E 87 05 68 61 72 6B 21 88 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 89 03 33 34 36 8A 01 02 8B 09 79 6F 75 72 74 6F 6B 65 6E 8C 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 8D 0B 45 78 61 6D 70 6C 65 63 6F 72 70 encode_krb5_pa_otp_enc_req: 30 0A 80 08 6B 72 62 35 64 61 74 61 encode_krb5_kkdcp_message: 30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61 encode_krb5_cammac(optionals NULL): 30 12 A0 10 30 0E 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31 encode_krb5_cammac: 30 81 F2 A0 1E 30 1C 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31 30 0C A0 03 02 01 02 A1 05 04 03 61 64 32 A1 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 6B 64 63 A2 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 73 76 63 A3 52 30 50 30 13 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 31 30 39 A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 32 encode_krb5_secure_cookie: 30 2C 02 04 2D F8 02 25 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 encode_krb5_spake_factor(optionals NULL): 30 05 A0 03 02 01 01 encode_krb5_spake_factor: 30 0E A0 03 02 01 02 A1 07 04 05 66 64 61 74 61 encode_krb5_pa_spake(support): A0 0C 30 0A A0 08 30 06 02 01 01 02 01 02 encode_krb5_pa_spake(challenge): A1 2D 30 2B A0 03 02 01 01 A1 09 04 07 54 20 76 61 6C 75 65 A2 19 30 17 30 05 A0 03 02 01 01 30 0E A0 03 02 01 02 A1 07 04 05 66 64 61 74 61 encode_krb5_pa_spake(response): A2 34 30 32 A0 09 04 07 53 20 76 61 6C 75 65 A1 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 encode_krb5_pa_spake(encdata): A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 krb5-1.22.1/src/tests/asn.1/debug.h0000664000175000017500000000333515051422640016455 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/debug.h */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __DEBUG_H__ #define __DEBUG_H__ /* assert utility macro for test programs: If the predicate (pred) is true, then OK: is printed. Otherwise, ERROR: is printed. message should be a printf format string. */ #include #define test(pred,message) \ if(pred) printf("OK: "); \ else { printf("ERROR: "); error_count++; } \ printf(message); #endif krb5-1.22.1/src/tests/asn.1/pkix.asn10000664000175000017500000005536415051422640016766 0ustar ghudsonghudsonPKIX1Explicit88 { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit(18) } DEFINITIONS EXPLICIT TAGS ::= BEGIN -- EXPORTS ALL -- -- IMPORTS NONE -- -- UNIVERSAL Types defined in 1993 and 1998 ASN.1 -- and required by this specification -- (Commented out for krb5 source tree) -- UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING -- UniversalString is defined in ASN.1:1993 -- BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING -- BMPString is the subtype of UniversalString and models -- the Basic Multilingual Plane of ISO/IEC 10646 --UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING -- The content of this type conforms to RFC 3629. -- PKIX specific OIDs id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) } -- PKIX arcs id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } -- arc for private certificate extensions id-qt OBJECT IDENTIFIER ::= { id-pkix 2 } -- arc for policy qualifier types id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } -- arc for extended key purpose OIDS id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } -- arc for access descriptors -- policyQualifierIds for Internet policy qualifiers id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 } -- OID for CPS qualifier id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 } -- OID for user notice qualifier -- access descriptor definitions id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 } id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 } -- attribute data types Attribute ::= SEQUENCE { type AttributeType, values SET OF AttributeValue } -- at least one value is required AttributeType ::= OBJECT IDENTIFIER AttributeValue ::= ANY -- DEFINED BY AttributeType AttributeTypeAndValue ::= SEQUENCE { type AttributeType, value AttributeValue } -- suggested naming attributes: Definition of the following -- information object set may be augmented to meet local -- requirements. Note that deleting members of the set may -- prevent interoperability with conforming implementations. -- presented in pairs: the AttributeType followed by the -- type definition for the corresponding AttributeValue -- Arc for standard naming attributes id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 } -- Naming attributes of type X520name id-at-name AttributeType ::= { id-at 41 } id-at-surname AttributeType ::= { id-at 4 } id-at-givenName AttributeType ::= { id-at 42 } id-at-initials AttributeType ::= { id-at 43 } id-at-generationQualifier AttributeType ::= { id-at 44 } -- Naming attributes of type X520Name: -- X520name ::= DirectoryString (SIZE (1..ub-name)) -- -- Expanded to avoid parameterized type: X520name ::= CHOICE { teletexString TeletexString (SIZE (1..ub-name)), printableString PrintableString (SIZE (1..ub-name)), universalString UniversalString (SIZE (1..ub-name)), utf8String UTF8String (SIZE (1..ub-name)), bmpString BMPString (SIZE (1..ub-name)) } -- Naming attributes of type X520CommonName id-at-commonName AttributeType ::= { id-at 3 } -- Naming attributes of type X520CommonName: -- X520CommonName ::= DirectoryName (SIZE (1..ub-common-name)) -- -- Expanded to avoid parameterized type: X520CommonName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-common-name)), printableString PrintableString (SIZE (1..ub-common-name)), universalString UniversalString (SIZE (1..ub-common-name)), utf8String UTF8String (SIZE (1..ub-common-name)), bmpString BMPString (SIZE (1..ub-common-name)) } -- Naming attributes of type X520LocalityName id-at-localityName AttributeType ::= { id-at 7 } -- Naming attributes of type X520LocalityName: -- X520LocalityName ::= DirectoryName (SIZE (1..ub-locality-name)) -- -- Expanded to avoid parameterized type: X520LocalityName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-locality-name)), printableString PrintableString (SIZE (1..ub-locality-name)), universalString UniversalString (SIZE (1..ub-locality-name)), utf8String UTF8String (SIZE (1..ub-locality-name)), bmpString BMPString (SIZE (1..ub-locality-name)) } -- Naming attributes of type X520StateOrProvinceName id-at-stateOrProvinceName AttributeType ::= { id-at 8 } -- Naming attributes of type X520StateOrProvinceName: -- X520StateOrProvinceName ::= DirectoryName (SIZE (1..ub-state-name)) -- -- Expanded to avoid parameterized type: X520StateOrProvinceName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-state-name)), printableString PrintableString (SIZE (1..ub-state-name)), universalString UniversalString (SIZE (1..ub-state-name)), utf8String UTF8String (SIZE (1..ub-state-name)), bmpString BMPString (SIZE (1..ub-state-name)) } -- Naming attributes of type X520OrganizationName id-at-organizationName AttributeType ::= { id-at 10 } -- Naming attributes of type X520OrganizationName: -- X520OrganizationName ::= -- DirectoryName (SIZE (1..ub-organization-name)) -- -- Expanded to avoid parameterized type: X520OrganizationName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-organization-name)), printableString PrintableString (SIZE (1..ub-organization-name)), universalString UniversalString (SIZE (1..ub-organization-name)), utf8String UTF8String (SIZE (1..ub-organization-name)), bmpString BMPString (SIZE (1..ub-organization-name)) } -- Naming attributes of type X520OrganizationalUnitName id-at-organizationalUnitName AttributeType ::= { id-at 11 } -- Naming attributes of type X520OrganizationalUnitName: -- X520OrganizationalUnitName ::= -- DirectoryName (SIZE (1..ub-organizational-unit-name)) -- -- Expanded to avoid parameterized type: X520OrganizationalUnitName ::= CHOICE { teletexString TeletexString (SIZE (1..ub-organizational-unit-name)), printableString PrintableString (SIZE (1..ub-organizational-unit-name)), universalString UniversalString (SIZE (1..ub-organizational-unit-name)), utf8String UTF8String (SIZE (1..ub-organizational-unit-name)), bmpString BMPString (SIZE (1..ub-organizational-unit-name)) } -- Naming attributes of type X520Title id-at-title AttributeType ::= { id-at 12 } -- Naming attributes of type X520Title: -- X520Title ::= DirectoryName (SIZE (1..ub-title)) -- -- Expanded to avoid parameterized type: X520Title ::= CHOICE { teletexString TeletexString (SIZE (1..ub-title)), printableString PrintableString (SIZE (1..ub-title)), universalString UniversalString (SIZE (1..ub-title)), utf8String UTF8String (SIZE (1..ub-title)), bmpString BMPString (SIZE (1..ub-title)) } -- Naming attributes of type X520dnQualifier id-at-dnQualifier AttributeType ::= { id-at 46 } X520dnQualifier ::= PrintableString -- Naming attributes of type X520countryName (digraph from IS 3166) id-at-countryName AttributeType ::= { id-at 6 } X520countryName ::= PrintableString (SIZE (2)) -- Naming attributes of type X520SerialNumber id-at-serialNumber AttributeType ::= { id-at 5 } X520SerialNumber ::= PrintableString (SIZE (1..ub-serial-number)) -- Naming attributes of type X520Pseudonym id-at-pseudonym AttributeType ::= { id-at 65 } -- Naming attributes of type X520Pseudonym: -- X520Pseudonym ::= DirectoryName (SIZE (1..ub-pseudonym)) -- -- Expanded to avoid parameterized type: X520Pseudonym ::= CHOICE { teletexString TeletexString (SIZE (1..ub-pseudonym)), printableString PrintableString (SIZE (1..ub-pseudonym)), universalString UniversalString (SIZE (1..ub-pseudonym)), utf8String UTF8String (SIZE (1..ub-pseudonym)), bmpString BMPString (SIZE (1..ub-pseudonym)) } -- Naming attributes of type DomainComponent (from RFC 4519) id-domainComponent AttributeType ::= { 0 9 2342 19200300 100 1 25 } DomainComponent ::= IA5String -- Legacy attributes pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } id-emailAddress AttributeType ::= { pkcs-9 1 } EmailAddress ::= IA5String (SIZE (1..ub-emailaddress-length)) -- naming data types -- Name ::= CHOICE { -- only one possibility for now -- rdnSequence RDNSequence } RDNSequence ::= SEQUENCE OF RelativeDistinguishedName DistinguishedName ::= RDNSequence RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue -- Directory string type -- DirectoryString ::= CHOICE { teletexString TeletexString (SIZE (1..MAX)), printableString PrintableString (SIZE (1..MAX)), universalString UniversalString (SIZE (1..MAX)), utf8String UTF8String (SIZE (1..MAX)), bmpString BMPString (SIZE (1..MAX)) } -- certificate and CRL specific structures begin here Certificate ::= SEQUENCE { tbsCertificate TBSCertificate, signatureAlgorithm AlgorithmIdentifier, signature BIT STRING } TBSCertificate ::= SEQUENCE { version [0] Version DEFAULT v1, serialNumber CertificateSerialNumber, signature AlgorithmIdentifier, issuer Name, validity Validity, subject Name, subjectPublicKeyInfo SubjectPublicKeyInfo, issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, -- If present, version MUST be v2 or v3 subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, -- If present, version MUST be v2 or v3 extensions [3] Extensions OPTIONAL -- If present, version MUST be v3 -- } Version ::= INTEGER { v1(0), v2(1), v3(2) } CertificateSerialNumber ::= INTEGER Validity ::= SEQUENCE { notBefore Time, notAfter Time } Time ::= CHOICE { utcTime UTCTime, generalTime GeneralizedTime } UniqueIdentifier ::= BIT STRING SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING } Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension Extension ::= SEQUENCE { extnID OBJECT IDENTIFIER, critical BOOLEAN DEFAULT FALSE, extnValue OCTET STRING -- contains the DER encoding of an ASN.1 value -- corresponding to the extension type identified -- by extnID } -- CRL structures CertificateList ::= SEQUENCE { tbsCertList TBSCertList, signatureAlgorithm AlgorithmIdentifier, signature BIT STRING } TBSCertList ::= SEQUENCE { version Version OPTIONAL, -- if present, MUST be v2 signature AlgorithmIdentifier, issuer Name, thisUpdate Time, nextUpdate Time OPTIONAL, revokedCertificates SEQUENCE OF SEQUENCE { userCertificate CertificateSerialNumber, revocationDate Time, crlEntryExtensions Extensions OPTIONAL -- if present, version MUST be v2 } OPTIONAL, crlExtensions [0] Extensions OPTIONAL } -- if present, version MUST be v2 -- Version, Time, CertificateSerialNumber, and Extensions were -- defined earlier for use in the certificate structure AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } -- contains a value of the type -- registered for use with the -- algorithm object identifier value -- X.400 address syntax starts here ORAddress ::= SEQUENCE { built-in-standard-attributes BuiltInStandardAttributes, built-in-domain-defined-attributes BuiltInDomainDefinedAttributes OPTIONAL, -- see also teletex-domain-defined-attributes extension-attributes ExtensionAttributes OPTIONAL } -- Built-in Standard Attributes BuiltInStandardAttributes ::= SEQUENCE { country-name CountryName OPTIONAL, administration-domain-name AdministrationDomainName OPTIONAL, network-address [0] IMPLICIT NetworkAddress OPTIONAL, -- see also extended-network-address terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL, private-domain-name [2] PrivateDomainName OPTIONAL, organization-name [3] IMPLICIT OrganizationName OPTIONAL, -- see also teletex-organization-name numeric-user-identifier [4] IMPLICIT NumericUserIdentifier OPTIONAL, personal-name [5] IMPLICIT PersonalName OPTIONAL, -- see also teletex-personal-name organizational-unit-names [6] IMPLICIT OrganizationalUnitNames OPTIONAL } -- see also teletex-organizational-unit-names CountryName ::= [APPLICATION 1] CHOICE { x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)), iso-3166-alpha2-code PrintableString (SIZE (ub-country-name-alpha-length)) } AdministrationDomainName ::= [APPLICATION 2] CHOICE { numeric NumericString (SIZE (0..ub-domain-name-length)), printable PrintableString (SIZE (0..ub-domain-name-length)) } NetworkAddress ::= X121Address -- see also extended-network-address X121Address ::= NumericString (SIZE (1..ub-x121-address-length)) TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length)) PrivateDomainName ::= CHOICE { numeric NumericString (SIZE (1..ub-domain-name-length)), printable PrintableString (SIZE (1..ub-domain-name-length)) } OrganizationName ::= PrintableString (SIZE (1..ub-organization-name-length)) -- see also teletex-organization-name NumericUserIdentifier ::= NumericString (SIZE (1..ub-numeric-user-id-length)) PersonalName ::= SET { surname [0] IMPLICIT PrintableString (SIZE (1..ub-surname-length)), given-name [1] IMPLICIT PrintableString (SIZE (1..ub-given-name-length)) OPTIONAL, initials [2] IMPLICIT PrintableString (SIZE (1..ub-initials-length)) OPTIONAL, generation-qualifier [3] IMPLICIT PrintableString (SIZE (1..ub-generation-qualifier-length)) OPTIONAL } -- see also teletex-personal-name OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) OF OrganizationalUnitName -- see also teletex-organizational-unit-names OrganizationalUnitName ::= PrintableString (SIZE (1..ub-organizational-unit-name-length)) -- Built-in Domain-defined Attributes BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE (1..ub-domain-defined-attributes) OF BuiltInDomainDefinedAttribute BuiltInDomainDefinedAttribute ::= SEQUENCE { type PrintableString (SIZE (1..ub-domain-defined-attribute-type-length)), value PrintableString (SIZE (1..ub-domain-defined-attribute-value-length)) } -- Extension Attributes ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF ExtensionAttribute ExtensionAttribute ::= SEQUENCE { extension-attribute-type [0] IMPLICIT INTEGER (0..ub-extension-attributes), extension-attribute-value [1] ANY DEFINED BY extension-attribute-type } -- Extension types and attribute values common-name INTEGER ::= 1 CommonName ::= PrintableString (SIZE (1..ub-common-name-length)) teletex-common-name INTEGER ::= 2 TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length)) teletex-organization-name INTEGER ::= 3 TeletexOrganizationName ::= TeletexString (SIZE (1..ub-organization-name-length)) teletex-personal-name INTEGER ::= 4 TeletexPersonalName ::= SET { surname [0] IMPLICIT TeletexString (SIZE (1..ub-surname-length)), given-name [1] IMPLICIT TeletexString (SIZE (1..ub-given-name-length)) OPTIONAL, initials [2] IMPLICIT TeletexString (SIZE (1..ub-initials-length)) OPTIONAL, generation-qualifier [3] IMPLICIT TeletexString (SIZE (1..ub-generation-qualifier-length)) OPTIONAL } teletex-organizational-unit-names INTEGER ::= 5 TeletexOrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) OF TeletexOrganizationalUnitName TeletexOrganizationalUnitName ::= TeletexString (SIZE (1..ub-organizational-unit-name-length)) pds-name INTEGER ::= 7 PDSName ::= PrintableString (SIZE (1..ub-pds-name-length)) physical-delivery-country-name INTEGER ::= 8 PhysicalDeliveryCountryName ::= CHOICE { x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)), iso-3166-alpha2-code PrintableString (SIZE (ub-country-name-alpha-length)) } postal-code INTEGER ::= 9 PostalCode ::= CHOICE { numeric-code NumericString (SIZE (1..ub-postal-code-length)), printable-code PrintableString (SIZE (1..ub-postal-code-length)) } physical-delivery-office-name INTEGER ::= 10 PhysicalDeliveryOfficeName ::= PDSParameter physical-delivery-office-number INTEGER ::= 11 PhysicalDeliveryOfficeNumber ::= PDSParameter extension-OR-address-components INTEGER ::= 12 ExtensionORAddressComponents ::= PDSParameter physical-delivery-personal-name INTEGER ::= 13 PhysicalDeliveryPersonalName ::= PDSParameter physical-delivery-organization-name INTEGER ::= 14 PhysicalDeliveryOrganizationName ::= PDSParameter extension-physical-delivery-address-components INTEGER ::= 15 ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter unformatted-postal-address INTEGER ::= 16 UnformattedPostalAddress ::= SET { printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) OF PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL, teletex-string TeletexString (SIZE (1..ub-unformatted-address-length)) OPTIONAL } street-address INTEGER ::= 17 StreetAddress ::= PDSParameter post-office-box-address INTEGER ::= 18 PostOfficeBoxAddress ::= PDSParameter poste-restante-address INTEGER ::= 19 PosteRestanteAddress ::= PDSParameter unique-postal-name INTEGER ::= 20 UniquePostalName ::= PDSParameter local-postal-attributes INTEGER ::= 21 LocalPostalAttributes ::= PDSParameter PDSParameter ::= SET { printable-string PrintableString (SIZE(1..ub-pds-parameter-length)) OPTIONAL, teletex-string TeletexString (SIZE(1..ub-pds-parameter-length)) OPTIONAL } extended-network-address INTEGER ::= 22 ExtendedNetworkAddress ::= CHOICE { e163-4-address SEQUENCE { number [0] IMPLICIT NumericString (SIZE (1..ub-e163-4-number-length)), sub-address [1] IMPLICIT NumericString (SIZE (1..ub-e163-4-sub-address-length)) OPTIONAL }, psap-address [0] IMPLICIT PresentationAddress } PresentationAddress ::= SEQUENCE { pSelector [0] EXPLICIT OCTET STRING OPTIONAL, sSelector [1] EXPLICIT OCTET STRING OPTIONAL, tSelector [2] EXPLICIT OCTET STRING OPTIONAL, nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING } terminal-type INTEGER ::= 23 TerminalType ::= INTEGER { telex (3), teletex (4), g3-facsimile (5), g4-facsimile (6), ia5-terminal (7), videotex (8) } (0..ub-integer-options) -- Extension Domain-defined Attributes teletex-domain-defined-attributes INTEGER ::= 6 TeletexDomainDefinedAttributes ::= SEQUENCE SIZE (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute TeletexDomainDefinedAttribute ::= SEQUENCE { type TeletexString (SIZE (1..ub-domain-defined-attribute-type-length)), value TeletexString (SIZE (1..ub-domain-defined-attribute-value-length)) } -- specifications of Upper Bounds MUST be regarded as mandatory -- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter -- Upper Bounds -- Upper Bounds ub-name INTEGER ::= 32768 ub-common-name INTEGER ::= 64 ub-locality-name INTEGER ::= 128 ub-state-name INTEGER ::= 128 ub-organization-name INTEGER ::= 64 ub-organizational-unit-name INTEGER ::= 64 ub-title INTEGER ::= 64 ub-serial-number INTEGER ::= 64 ub-match INTEGER ::= 128 ub-emailaddress-length INTEGER ::= 255 ub-common-name-length INTEGER ::= 64 ub-country-name-alpha-length INTEGER ::= 2 ub-country-name-numeric-length INTEGER ::= 3 ub-domain-defined-attributes INTEGER ::= 4 ub-domain-defined-attribute-type-length INTEGER ::= 8 ub-domain-defined-attribute-value-length INTEGER ::= 128 ub-domain-name-length INTEGER ::= 16 ub-extension-attributes INTEGER ::= 256 ub-e163-4-number-length INTEGER ::= 15 ub-e163-4-sub-address-length INTEGER ::= 40 ub-generation-qualifier-length INTEGER ::= 3 ub-given-name-length INTEGER ::= 16 ub-initials-length INTEGER ::= 5 ub-integer-options INTEGER ::= 256 ub-numeric-user-id-length INTEGER ::= 32 ub-organization-name-length INTEGER ::= 64 ub-organizational-unit-name-length INTEGER ::= 32 ub-organizational-units INTEGER ::= 4 ub-pds-name-length INTEGER ::= 16 ub-pds-parameter-length INTEGER ::= 30 ub-pds-physical-address-lines INTEGER ::= 6 ub-postal-code-length INTEGER ::= 16 ub-pseudonym INTEGER ::= 128 ub-surname-length INTEGER ::= 40 ub-terminal-id-length INTEGER ::= 24 ub-unformatted-address-length INTEGER ::= 180 ub-x121-address-length INTEGER ::= 16 -- Note - upper bounds on string types, such as TeletexString, are -- measured in characters. Excepting PrintableString or IA5String, a -- significantly greater number of octets will be required to hold -- such a value. As a minimum, 16 octets, or twice the specified -- upper bound, whichever is the larger, should be allowed for -- TeletexString. For UTF8String or UniversalString at least four -- times the upper bound should be allowed. END krb5-1.22.1/src/tests/asn.1/spake.asn10000664000175000017500000000205115051422640017077 0ustar ghudsonghudsonKerberosV5SPAKE { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) spake(8) } DEFINITIONS EXPLICIT TAGS ::= BEGIN IMPORTS EncryptedData, Int32 FROM KerberosV5Spec2 { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2) }; -- as defined in RFC 4120. SPAKESupport ::= SEQUENCE { groups [0] SEQUENCE (SIZE(1..MAX)) OF Int32, ... } SPAKEChallenge ::= SEQUENCE { group [0] Int32, pubkey [1] OCTET STRING, factors [2] SEQUENCE (SIZE(1..MAX)) OF SPAKESecondFactor, ... } SPAKESecondFactor ::= SEQUENCE { type [0] Int32, data [1] OCTET STRING OPTIONAL } SPAKEResponse ::= SEQUENCE { pubkey [0] OCTET STRING, factor [1] EncryptedData, -- SPAKESecondFactor ... } PA-SPAKE ::= CHOICE { support [0] SPAKESupport, challenge [1] SPAKEChallenge, response [2] SPAKEResponse, encdata [3] EncryptedData, ... } END krb5-1.22.1/src/tests/asn.1/deps0000664000175000017500000001141315051422640016070 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)krb5_encode_test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-spake.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h debug.h krb5_encode_test.c \ ktest.h utility.h $(OUTPRE)krb5_decode_test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-spake.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h debug.h krb5_decode_test.c \ ktest.h ktest_equal.h utility.h $(OUTPRE)krb5_decode_leak.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-spake.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h debug.h krb5_decode_leak.c \ ktest.h utility.h $(OUTPRE)ktest.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-spake.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ktest.c ktest.h \ utility.h $(OUTPRE)ktest_equal.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-spake.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ktest_equal.c \ ktest_equal.h $(OUTPRE)utility.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h utility.c utility.h $(OUTPRE)trval.$(OBJEXT): trval.c $(OUTPRE)t_trval.$(OBJEXT): t_trval.c trval.c krb5-1.22.1/src/tests/asn.1/ktest.c0000664000175000017500000013050515051422640016514 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/ktest.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "ktest.h" #include "utility.h" #include char *sample_principal_name = "hftsai/extra@ATHENA.MIT.EDU"; void ktest_make_sample_authenticator(krb5_authenticator *a) { ktest_make_sample_principal(&a->client); a->checksum = ealloc(sizeof(krb5_checksum)); ktest_make_sample_checksum(a->checksum); a->cusec = SAMPLE_USEC; a->ctime = SAMPLE_TIME; a->subkey = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(a->subkey); a->seq_number = SAMPLE_SEQ_NUMBER; ktest_make_sample_authorization_data(&a->authorization_data); } void ktest_make_sample_principal(krb5_principal *p) { if (krb5_parse_name(test_context, sample_principal_name, p)) abort(); } void ktest_make_sample_checksum(krb5_checksum *cs) { cs->checksum_type = 1; cs->length = 4; cs->contents = ealloc(4); memcpy(cs->contents,"1234",4); } void ktest_make_sample_keyblock(krb5_keyblock *kb) { kb->magic = KV5M_KEYBLOCK; kb->enctype = 1; kb->length = 8; kb->contents = ealloc(8); memcpy(kb->contents,"12345678",8); } void ktest_make_sample_ticket(krb5_ticket *tkt) { ktest_make_sample_principal(&tkt->server); ktest_make_sample_enc_data(&tkt->enc_part); tkt->enc_part2 = NULL; } void ktest_make_sample_enc_data(krb5_enc_data *ed) { ed->kvno = 5; ed->enctype = 0; krb5_data_parse(&ed->ciphertext, "krbASN.1 test message"); } void ktest_make_sample_enc_tkt_part(krb5_enc_tkt_part *etp) { etp->flags = SAMPLE_FLAGS; etp->session = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(etp->session); ktest_make_sample_principal(&etp->client); ktest_make_sample_transited(&etp->transited); ktest_make_sample_ticket_times(&etp->times); ktest_make_sample_addresses(&etp->caddrs); ktest_make_sample_authorization_data(&etp->authorization_data); } void ktest_make_sample_addresses(krb5_address ***caddrs) { int i; *caddrs = ealloc(3 * sizeof(krb5_address *)); for (i = 0; i < 2; i++) { (*caddrs)[i] = ealloc(sizeof(krb5_address)); ktest_make_sample_address((*caddrs)[i]); } (*caddrs)[2] = NULL; } void ktest_make_sample_authorization_data(krb5_authdata ***ad) { int i; *ad = ealloc(3 * sizeof(krb5_authdata *)); for (i = 0; i <= 1; i++) { (*ad)[i] = ealloc(sizeof(krb5_authdata)); ktest_make_sample_authdata((*ad)[i]); } (*ad)[2] = NULL; } void ktest_make_sample_transited(krb5_transited *t) { t->tr_type = 1; krb5_data_parse(&t->tr_contents, "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS."); } void ktest_make_sample_ticket_times(krb5_ticket_times *tt) { tt->authtime = SAMPLE_TIME; tt->starttime = SAMPLE_TIME; tt->endtime = SAMPLE_TIME; tt->renew_till = SAMPLE_TIME; } void ktest_make_sample_address(krb5_address *a) { a->addrtype = ADDRTYPE_INET; a->length = 4; a->contents = ealloc(4 * sizeof(krb5_octet)); a->contents[0] = 18; a->contents[1] = 208; a->contents[2] = 0; a->contents[3] = 35; } void ktest_make_sample_authdata(krb5_authdata *ad) { ad->ad_type = 1; ad->length = 6; ad->contents = ealloc(6 * sizeof(krb5_octet)); memcpy(ad->contents, "foobar", 6); } void ktest_make_sample_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ekr) { ekr->session = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(ekr->session); ktest_make_sample_last_req(&ekr->last_req); ekr->nonce = SAMPLE_NONCE; ekr->key_exp = SAMPLE_TIME; ekr->flags = SAMPLE_FLAGS; ekr->times.authtime = SAMPLE_TIME; ekr->times.starttime = SAMPLE_TIME; ekr->times.endtime = SAMPLE_TIME; ekr->times.renew_till = SAMPLE_TIME; ktest_make_sample_principal(&ekr->server); ktest_make_sample_addresses(&ekr->caddrs); } void ktest_make_sample_last_req(krb5_last_req_entry ***lr) { int i; *lr = ealloc(3 * sizeof(krb5_last_req_entry *)); for (i = 0; i <= 1; i++) ktest_make_sample_last_req_entry(&(*lr)[i]); (*lr)[2] = NULL; } void ktest_make_sample_last_req_entry(krb5_last_req_entry **lre) { *lre = ealloc(sizeof(krb5_last_req_entry)); (*lre)->lr_type = -5; (*lre)->value = SAMPLE_TIME; } void ktest_make_sample_kdc_rep(krb5_kdc_rep *kdcr) { ktest_make_sample_pa_data_array(&kdcr->padata); ktest_make_sample_principal(&kdcr->client); kdcr->ticket = ealloc(sizeof(krb5_ticket)); ktest_make_sample_ticket(kdcr->ticket); ktest_make_sample_enc_data(&kdcr->enc_part); kdcr->enc_part2 = NULL; } void ktest_make_sample_pa_data_array(krb5_pa_data ***pad) { int i; *pad = ealloc(3 * sizeof(krb5_pa_data *)); for (i = 0; i <= 1; i++) { (*pad)[i] = ealloc(sizeof(krb5_pa_data)); ktest_make_sample_pa_data((*pad)[i]); } (*pad)[2] = NULL; } void ktest_make_sample_empty_pa_data_array(krb5_pa_data ***pad) { *pad = ealloc(sizeof(krb5_pa_data *)); (*pad)[0] = NULL; } void ktest_make_sample_pa_data(krb5_pa_data *pad) { pad->pa_type = 13; pad->length = 7; pad->contents = ealloc(7); memcpy(pad->contents, "pa-data", 7); } void ktest_make_sample_ap_req(krb5_ap_req *ar) { ar->ap_options = SAMPLE_FLAGS; ar->ticket = ealloc(sizeof(krb5_ticket)); ktest_make_sample_ticket(ar->ticket); ktest_make_sample_enc_data(&(ar->authenticator)); } void ktest_make_sample_ap_rep(krb5_ap_rep *ar) { ktest_make_sample_enc_data(&ar->enc_part); } void ktest_make_sample_ap_rep_enc_part(krb5_ap_rep_enc_part *arep) { arep->ctime = SAMPLE_TIME; arep->cusec = SAMPLE_USEC; arep->subkey = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(arep->subkey); arep->seq_number = SAMPLE_SEQ_NUMBER; } void ktest_make_sample_kdc_req(krb5_kdc_req *kr) { /* msg_type is left up to the calling procedure */ ktest_make_sample_pa_data_array(&kr->padata); kr->kdc_options = SAMPLE_FLAGS; ktest_make_sample_principal(&(kr->client)); ktest_make_sample_principal(&(kr->server)); kr->from = SAMPLE_TIME; kr->till = SAMPLE_TIME; kr->rtime = SAMPLE_TIME; kr->nonce = SAMPLE_NONCE; kr->nktypes = 2; kr->ktype = ealloc(2 * sizeof(krb5_enctype)); kr->ktype[0] = 0; kr->ktype[1] = 1; ktest_make_sample_addresses(&kr->addresses); ktest_make_sample_enc_data(&kr->authorization_data); ktest_make_sample_authorization_data(&kr->unenc_authdata); ktest_make_sample_sequence_of_ticket(&kr->second_ticket); } void ktest_make_sample_kdc_req_body(krb5_kdc_req *krb) { krb->kdc_options = SAMPLE_FLAGS; ktest_make_sample_principal(&krb->client); ktest_make_sample_principal(&krb->server); krb->from = SAMPLE_TIME; krb->till = SAMPLE_TIME; krb->rtime = SAMPLE_TIME; krb->nonce = SAMPLE_NONCE; krb->nktypes = 2; krb->ktype = (krb5_enctype*)calloc(2,sizeof(krb5_enctype)); krb->ktype[0] = 0; krb->ktype[1] = 1; ktest_make_sample_addresses(&krb->addresses); ktest_make_sample_enc_data(&krb->authorization_data); ktest_make_sample_authorization_data(&krb->unenc_authdata); ktest_make_sample_sequence_of_ticket(&krb->second_ticket); } void ktest_make_sample_safe(krb5_safe *s) { ktest_make_sample_data(&s->user_data); s->timestamp = SAMPLE_TIME; s->usec = SAMPLE_USEC; s->seq_number = SAMPLE_SEQ_NUMBER; s->s_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(s->s_address); s->r_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(s->r_address); s->checksum = ealloc(sizeof(krb5_checksum)); ktest_make_sample_checksum(s->checksum); } void ktest_make_sample_priv(krb5_priv *p) { ktest_make_sample_enc_data(&p->enc_part); } void ktest_make_sample_priv_enc_part(krb5_priv_enc_part *pep) { ktest_make_sample_data(&(pep->user_data)); pep->timestamp = SAMPLE_TIME; pep->usec = SAMPLE_USEC; pep->seq_number = SAMPLE_SEQ_NUMBER; pep->s_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(pep->s_address); pep->r_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(pep->r_address); } void ktest_make_sample_cred(krb5_cred *c) { ktest_make_sample_sequence_of_ticket(&c->tickets); ktest_make_sample_enc_data(&c->enc_part); } void ktest_make_sample_sequence_of_ticket(krb5_ticket ***sot) { int i; *sot = ealloc(3 * sizeof(krb5_ticket *)); for (i = 0; i < 2; i++) { (*sot)[i] = ealloc(sizeof(krb5_ticket)); ktest_make_sample_ticket((*sot)[i]); } (*sot)[2] = NULL; } void ktest_make_sample_cred_enc_part(krb5_cred_enc_part *cep) { cep->nonce = SAMPLE_NONCE; cep->timestamp = SAMPLE_TIME; cep->usec = SAMPLE_USEC; cep->s_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(cep->s_address); cep->r_address = ealloc(sizeof(krb5_address)); ktest_make_sample_address(cep->r_address); ktest_make_sequence_of_cred_info(&cep->ticket_info); } void ktest_make_sequence_of_cred_info(krb5_cred_info ***soci) { int i; *soci = ealloc(3 * sizeof(krb5_cred_info *)); for (i = 0; i < 2; i++) { (*soci)[i] = ealloc(sizeof(krb5_cred_info)); ktest_make_sample_cred_info((*soci)[i]); } (*soci)[2] = NULL; } void ktest_make_sample_cred_info(krb5_cred_info *ci) { ci->session = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(ci->session); ktest_make_sample_principal(&ci->client); ktest_make_sample_principal(&ci->server); ci->flags = SAMPLE_FLAGS; ci->times.authtime = SAMPLE_TIME; ci->times.starttime = SAMPLE_TIME; ci->times.endtime = SAMPLE_TIME; ci->times.renew_till = SAMPLE_TIME; ktest_make_sample_addresses(&ci->caddrs); } void ktest_make_sample_error(krb5_error *kerr) { kerr->ctime = SAMPLE_TIME; kerr->cusec = SAMPLE_USEC; kerr->susec = SAMPLE_USEC; kerr->stime = SAMPLE_TIME; kerr->error = SAMPLE_ERROR; ktest_make_sample_principal(&kerr->client); ktest_make_sample_principal(&kerr->server); ktest_make_sample_data(&kerr->text); ktest_make_sample_data(&kerr->e_data); } void ktest_make_sample_data(krb5_data *d) { krb5_data_parse(d, "krb5data"); } void ktest_make_sample_etype_info(krb5_etype_info_entry ***p) { krb5_etype_info_entry **info; int i, len; char *str; info = ealloc(4 * sizeof(krb5_etype_info_entry *)); for (i = 0; i < 3; i++) { info[i] = ealloc(sizeof(krb5_etype_info_entry)); info[i]->etype = i; len = asprintf(&str, "Morton's #%d", i); if (len < 0) abort(); info[i]->salt = (krb5_octet *)str; info[i]->length = len; info[i]->s2kparams.data = NULL; info[i]->s2kparams.length = 0; info[i]->magic = KV5M_ETYPE_INFO_ENTRY; } free(info[1]->salt); info[1]->length = KRB5_ETYPE_NO_SALT; info[1]->salt = 0; *p = info; } void ktest_make_sample_etype_info2(krb5_etype_info_entry ***p) { krb5_etype_info_entry **info; int i, len; char *str; info = ealloc(4 * sizeof(krb5_etype_info_entry *)); for (i = 0; i < 3; i++) { info[i] = ealloc(sizeof(krb5_etype_info_entry)); info[i]->etype = i; len = asprintf(&str, "Morton's #%d", i); if (len < 0) abort(); info[i]->salt = (krb5_octet *)str; info[i]->length = (unsigned int)len; len = asprintf(&info[i]->s2kparams.data, "s2k: %d", i); if (len < 0) abort(); info[i]->s2kparams.length = (unsigned int) len; info[i]->magic = KV5M_ETYPE_INFO_ENTRY; } free(info[1]->salt); info[1]->length = KRB5_ETYPE_NO_SALT; info[1]->salt = 0; *p = info; } void ktest_make_sample_pa_enc_ts(krb5_pa_enc_ts *pa_enc) { pa_enc->patimestamp = SAMPLE_TIME; pa_enc->pausec = SAMPLE_USEC; } void ktest_make_sample_sam_challenge_2(krb5_sam_challenge_2 *p) { /* Need a valid DER sequence encoding here; this one contains the OCTET * STRING "challenge". */ krb5_data_parse(&p->sam_challenge_2_body, "\x30\x0B\x04\x09" "challenge"); p->sam_cksum = ealloc(2 * sizeof(krb5_checksum *)); p->sam_cksum[0] = ealloc(sizeof(krb5_checksum)); ktest_make_sample_checksum(p->sam_cksum[0]); p->sam_cksum[1] = NULL; } void ktest_make_sample_sam_challenge_2_body(krb5_sam_challenge_2_body *p) { p->sam_type = 42; p->sam_flags = KRB5_SAM_USE_SAD_AS_KEY; krb5_data_parse(&p->sam_type_name, "type name"); p->sam_track_id = empty_data(); krb5_data_parse(&p->sam_challenge_label, "challenge label"); krb5_data_parse(&p->sam_challenge, "challenge ipse"); krb5_data_parse(&p->sam_response_prompt, "response_prompt ipse"); p->sam_pk_for_sad = empty_data(); p->sam_nonce = 0x543210; p->sam_etype = ENCTYPE_AES256_CTS_HMAC_SHA384_192; } void ktest_make_sample_sam_response_2(krb5_sam_response_2 *p) { p->magic = KV5M_SAM_RESPONSE; p->sam_type = 43; /* information */ p->sam_flags = KRB5_SAM_USE_SAD_AS_KEY; /* KRB5_SAM_* values */ krb5_data_parse(&p->sam_track_id, "track data"); krb5_data_parse(&p->sam_enc_nonce_or_sad.ciphertext, "nonce or sad"); p->sam_enc_nonce_or_sad.enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192; p->sam_enc_nonce_or_sad.kvno = 3382; p->sam_nonce = 0x543210; } void ktest_make_sample_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p) { p->magic = 83; p->sam_nonce = 88; krb5_data_parse(&p->sam_sad, "enc_sam_response_enc_2"); } void ktest_make_sample_pa_for_user(krb5_pa_for_user *p) { ktest_make_sample_principal(&p->user); ktest_make_sample_checksum(&p->cksum); ktest_make_sample_data(&p->auth_package); } void ktest_make_sample_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p) { krb5_s4u_userid *u = &p->user_id; u->nonce = 13243546; ktest_make_sample_principal(&u->user); krb5_data_parse(&u->subject_cert, "pa_s4u_x509_user"); u->options = 0x80000000; ktest_make_sample_checksum(&p->cksum); } void ktest_make_sample_ad_kdcissued(krb5_ad_kdcissued *p) { ktest_make_sample_checksum(&p->ad_checksum); ktest_make_sample_principal(&p->i_principal); ktest_make_sample_authorization_data(&p->elements); } void ktest_make_sample_iakerb_header(krb5_iakerb_header *ih) { ktest_make_sample_data(&(ih->target_realm)); ih->cookie = ealloc(sizeof(krb5_data)); ktest_make_sample_data(ih->cookie); } void ktest_make_sample_iakerb_finished(krb5_iakerb_finished *ih) { ktest_make_sample_checksum(&ih->checksum); } static void ktest_make_sample_fast_finished(krb5_fast_finished *p) { p->timestamp = SAMPLE_TIME; p->usec = SAMPLE_USEC; ktest_make_sample_principal(&p->client); ktest_make_sample_checksum(&p->ticket_checksum); } void ktest_make_sample_fast_response(krb5_fast_response *p) { ktest_make_sample_pa_data_array(&p->padata); p->strengthen_key = ealloc(sizeof(krb5_keyblock)); ktest_make_sample_keyblock(p->strengthen_key); p->finished = ealloc(sizeof(krb5_fast_finished)); ktest_make_sample_fast_finished(p->finished); p->nonce = SAMPLE_NONCE; } void ktest_make_sha256_alg(krb5_algorithm_identifier *p) { /* { 2 16 840 1 101 3 4 2 1 } */ krb5_data_parse(&p->algorithm, "\x60\x86\x48\x01\x65\x03\x04\x02\x01"); p->parameters = empty_data(); } void ktest_make_sha1_alg(krb5_algorithm_identifier *p) { /* { 1 3 14 3 2 26 } */ krb5_data_parse(&p->algorithm, "\x2b\x0e\x03\x02\x1a"); p->parameters = empty_data(); } void ktest_make_minimal_otp_tokeninfo(krb5_otp_tokeninfo *p) { memset(p, 0, sizeof(*p)); p->length = p->format = p->iteration_count = -1; } void ktest_make_maximal_otp_tokeninfo(krb5_otp_tokeninfo *p) { p->flags = KRB5_OTP_FLAG_NEXTOTP | KRB5_OTP_FLAG_COMBINE | KRB5_OTP_FLAG_COLLECT_PIN | KRB5_OTP_FLAG_ENCRYPT_NONCE | KRB5_OTP_FLAG_SEPARATE_PIN | KRB5_OTP_FLAG_CHECK_DIGIT; krb5_data_parse(&p->vendor, "Examplecorp"); krb5_data_parse(&p->challenge, "hark!"); p->length = 10; p->format = 2; krb5_data_parse(&p->token_id, "yourtoken"); krb5_data_parse(&p->alg_id, "urn:ietf:params:xml:ns:keyprov:pskc:hotp"); p->supported_hash_alg = ealloc(3 * sizeof(*p->supported_hash_alg)); p->supported_hash_alg[0] = ealloc(sizeof(*p->supported_hash_alg[0])); ktest_make_sha256_alg(p->supported_hash_alg[0]); p->supported_hash_alg[1] = ealloc(sizeof(*p->supported_hash_alg[1])); ktest_make_sha1_alg(p->supported_hash_alg[1]); p->supported_hash_alg[2] = NULL; p->iteration_count = 1000; } void ktest_make_minimal_pa_otp_challenge(krb5_pa_otp_challenge *p) { memset(p, 0, sizeof(*p)); krb5_data_parse(&p->nonce, "minnonce"); p->tokeninfo = ealloc(2 * sizeof(*p->tokeninfo)); p->tokeninfo[0] = ealloc(sizeof(*p->tokeninfo[0])); ktest_make_minimal_otp_tokeninfo(p->tokeninfo[0]); p->tokeninfo[1] = NULL; } void ktest_make_maximal_pa_otp_challenge(krb5_pa_otp_challenge *p) { krb5_data_parse(&p->nonce, "maxnonce"); krb5_data_parse(&p->service, "testservice"); p->tokeninfo = ealloc(3 * sizeof(*p->tokeninfo)); p->tokeninfo[0] = ealloc(sizeof(*p->tokeninfo[0])); ktest_make_minimal_otp_tokeninfo(p->tokeninfo[0]); p->tokeninfo[1] = ealloc(sizeof(*p->tokeninfo[1])); ktest_make_maximal_otp_tokeninfo(p->tokeninfo[1]); p->tokeninfo[2] = NULL; krb5_data_parse(&p->salt, "keysalt"); krb5_data_parse(&p->s2kparams, "1234"); } void ktest_make_minimal_pa_otp_req(krb5_pa_otp_req *p) { memset(p, 0, sizeof(*p)); p->iteration_count = -1; p->format = -1; ktest_make_sample_enc_data(&p->enc_data); } void ktest_make_maximal_pa_otp_req(krb5_pa_otp_req *p) { p->flags = KRB5_OTP_FLAG_NEXTOTP | KRB5_OTP_FLAG_COMBINE; krb5_data_parse(&p->nonce, "nonce"); ktest_make_sample_enc_data(&p->enc_data); p->hash_alg = ealloc(sizeof(*p->hash_alg)); ktest_make_sha256_alg(p->hash_alg); p->iteration_count = 1000; krb5_data_parse(&p->otp_value, "frogs"); krb5_data_parse(&p->pin, "myfirstpin"); krb5_data_parse(&p->challenge, "hark!"); p->time = SAMPLE_TIME; krb5_data_parse(&p->counter, "346"); p->format = 2; krb5_data_parse(&p->token_id, "yourtoken"); krb5_data_parse(&p->alg_id, "urn:ietf:params:xml:ns:keyprov:pskc:hotp"); krb5_data_parse(&p->vendor, "Examplecorp"); } #ifndef DISABLE_PKINIT static void ktest_make_sample_pk_authenticator(krb5_pk_authenticator *p) { p->cusec = SAMPLE_USEC; p->ctime = SAMPLE_TIME; p->nonce = SAMPLE_NONCE; ktest_make_sample_data(&p->paChecksum); p->freshnessToken = ealloc(sizeof(krb5_data)); ktest_make_sample_data(p->freshnessToken); } static void ktest_make_sample_oid(krb5_data *p) { krb5_data_parse(p, "\052\206\110\206\367\022\001\002\002"); } static void ktest_make_sample_algorithm_identifier(krb5_algorithm_identifier *p) { ktest_make_sample_oid(&p->algorithm); /* Need a valid DER encoding here; this is the OCTET STRING "params". */ krb5_data_parse(&p->parameters, "\x04\x06" "params"); } static void ktest_make_sample_algorithm_identifier_no_params(krb5_algorithm_identifier *p) { ktest_make_sample_oid(&p->algorithm); p->parameters = empty_data(); } static void ktest_make_sample_external_principal_identifier( krb5_external_principal_identifier *p) { ktest_make_sample_data(&p->subjectName); ktest_make_sample_data(&p->issuerAndSerialNumber); ktest_make_sample_data(&p->subjectKeyIdentifier); } void ktest_make_sample_pa_pk_as_req(krb5_pa_pk_as_req *p) { ktest_make_sample_data(&p->signedAuthPack); p->trustedCertifiers = ealloc(2 * sizeof(krb5_external_principal_identifier *)); p->trustedCertifiers[0] = ealloc(sizeof(krb5_external_principal_identifier)); ktest_make_sample_external_principal_identifier(p->trustedCertifiers[0]); p->trustedCertifiers[1] = NULL; ktest_make_sample_data(&p->kdcPkId); } static void ktest_make_sample_dh_rep_info(krb5_dh_rep_info *p) { ktest_make_sample_data(&p->dhSignedData); ktest_make_sample_data(&p->serverDHNonce); p->kdfID = ealloc(sizeof(krb5_data)); ktest_make_sample_data(p->kdfID); } void ktest_make_sample_pa_pk_as_rep_dhInfo(krb5_pa_pk_as_rep *p) { p->choice = choice_pa_pk_as_rep_dhInfo; ktest_make_sample_dh_rep_info(&p->u.dh_Info); } void ktest_make_sample_pa_pk_as_rep_encKeyPack(krb5_pa_pk_as_rep *p) { p->choice = choice_pa_pk_as_rep_encKeyPack; ktest_make_sample_data(&p->u.encKeyPack); } void ktest_make_sample_auth_pack(krb5_auth_pack *p) { ktest_make_sample_pk_authenticator(&p->pkAuthenticator); /* Need a valid DER encoding here; this is the OCTET STRING "pvalue". */ krb5_data_parse(&p->clientPublicValue, "\x04\x06" "pvalue"); p->supportedCMSTypes = ealloc(3 * sizeof(krb5_algorithm_identifier *)); p->supportedCMSTypes[0] = ealloc(sizeof(krb5_algorithm_identifier)); ktest_make_sample_algorithm_identifier(p->supportedCMSTypes[0]); p->supportedCMSTypes[1] = ealloc(sizeof(krb5_algorithm_identifier)); ktest_make_sample_algorithm_identifier_no_params(p->supportedCMSTypes[1]); p->supportedCMSTypes[2] = NULL; ktest_make_sample_data(&p->clientDHNonce); p->supportedKDFs = ealloc(2 * sizeof(krb5_data *)); p->supportedKDFs[0] = ealloc(sizeof(krb5_data)); ktest_make_sample_data(p->supportedKDFs[0]); p->supportedKDFs[1] = NULL; } void ktest_make_sample_kdc_dh_key_info(krb5_kdc_dh_key_info *p) { ktest_make_sample_data(&p->subjectPublicKey); p->nonce = SAMPLE_NONCE; p->dhKeyExpiration = SAMPLE_TIME; } void ktest_make_sample_reply_key_pack(krb5_reply_key_pack *p) { ktest_make_sample_keyblock(&p->replyKey); ktest_make_sample_checksum(&p->asChecksum); } void ktest_make_sample_sp80056a_other_info(krb5_sp80056a_other_info *p) { ktest_make_sample_algorithm_identifier_no_params(&p->algorithm_identifier); ktest_make_sample_principal(&p->party_u_info); ktest_make_sample_principal(&p->party_v_info); ktest_make_sample_data(&p->supp_pub_info); } void ktest_make_sample_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p) { p->enctype = ENCTYPE_AES256_CTS_HMAC_SHA384_192; ktest_make_sample_data(&p->as_req); ktest_make_sample_data(&p->pk_as_rep); } #endif /* not DISABLE_PKINIT */ #ifdef ENABLE_LDAP static void ktest_make_sample_key_data(krb5_key_data *p, int i) { char *str; int len; len = asprintf(&str, "key%d", i); if (len < 0) abort(); p->key_data_ver = 2; p->key_data_type[0] = 2; p->key_data_length[0] = (unsigned int) len; p->key_data_contents[0] = (krb5_octet *)str; len = asprintf(&str, "salt%d", i); if (len < 0) abort(); p->key_data_type[1] = i; p->key_data_length[1] = (unsigned int) len; p->key_data_contents[1] = (krb5_octet *)str; } void ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data *p) { int i; p->mkvno = 14; p->n_key_data = 3; p->key_data = calloc(3,sizeof(krb5_key_data)); p->kvno = 42; for (i = 0; i < 3; i++) ktest_make_sample_key_data(&p->key_data[i], i); } #endif void ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p) { krb5_kdc_req req; krb5_data *message; ktest_make_sample_kdc_req(&req); req.msg_type = KRB5_AS_REQ; encode_krb5_as_req(&req, &message); p->kerb_message = *message; free(message); ktest_empty_kdc_req(&req); ktest_make_sample_data(&(p->target_domain)); p->dclocator_hint = 0; } static krb5_authdata * make_ad_element(krb5_authdatatype ad_type, const char *str) { krb5_authdata *ad; ad = ealloc(sizeof(*ad)); ad->ad_type = ad_type; ad->length = strlen(str); ad->contents = ealloc(ad->length); memcpy(ad->contents, str, ad->length); return ad; } static krb5_verifier_mac * make_vmac(krb5_boolean include_princ, krb5_kvno kvno, krb5_enctype enctype, const char *cksumstr) { krb5_verifier_mac *vmac; vmac = ealloc(sizeof(*vmac)); if (include_princ) { ktest_make_sample_principal(&vmac->princ); (void)krb5_set_principal_realm(NULL, vmac->princ, ""); } else { vmac->princ = NULL; } vmac->kvno = kvno; vmac->enctype = enctype; vmac->checksum.checksum_type = 1; vmac->checksum.length = strlen(cksumstr); vmac->checksum.contents = ealloc(vmac->checksum.length); memcpy(vmac->checksum.contents, cksumstr, vmac->checksum.length); return vmac; } void ktest_make_minimal_cammac(krb5_cammac *p) { memset(p, 0, sizeof(*p)); p->elements = ealloc(2 * sizeof(*p->elements)); p->elements[0] = make_ad_element(1, "ad1"); p->elements[1] = NULL; } void ktest_make_maximal_cammac(krb5_cammac *p) { p->elements = ealloc(3 * sizeof(*p->elements)); p->elements[0] = make_ad_element(1, "ad1"); p->elements[1] = make_ad_element(2, "ad2"); p->elements[2] = NULL; p->kdc_verifier = make_vmac(TRUE, 5, 16, "cksumkdc"); p->svc_verifier = make_vmac(TRUE, 5, 16, "cksumsvc"); p->other_verifiers = ealloc(3 * sizeof(*p->other_verifiers)); p->other_verifiers[0] = make_vmac(FALSE, 0, 0, "cksum1"); p->other_verifiers[1] = make_vmac(TRUE, 5, 16, "cksum2"); p->other_verifiers[2] = NULL; } void ktest_make_sample_secure_cookie(krb5_secure_cookie *p) { ktest_make_sample_pa_data_array(&p->data); p->time = SAMPLE_TIME; } void ktest_make_minimal_spake_factor(krb5_spake_factor *p) { p->type = 1; p->data = NULL; } void ktest_make_maximal_spake_factor(krb5_spake_factor *p) { p->type = 2; p->data = ealloc(sizeof(*p->data)); krb5_data_parse(p->data, "fdata"); } void ktest_make_support_pa_spake(krb5_pa_spake *p) { krb5_spake_support *s = &p->u.support; s->ngroups = 2; s->groups = ealloc(s->ngroups * sizeof(*s->groups)); s->groups[0] = 1; s->groups[1] = 2; p->choice = SPAKE_MSGTYPE_SUPPORT; } void ktest_make_challenge_pa_spake(krb5_pa_spake *p) { krb5_spake_challenge *c = &p->u.challenge; c->group = 1; krb5_data_parse(&c->pubkey, "T value"); c->factors = ealloc(3 * sizeof(*c->factors)); c->factors[0] = ealloc(sizeof(*c->factors[0])); ktest_make_minimal_spake_factor(c->factors[0]); c->factors[1] = ealloc(sizeof(*c->factors[1])); ktest_make_maximal_spake_factor(c->factors[1]); c->factors[2] = NULL; p->choice = SPAKE_MSGTYPE_CHALLENGE; } void ktest_make_response_pa_spake(krb5_pa_spake *p) { krb5_spake_response *r = &p->u.response; krb5_data_parse(&r->pubkey, "S value"); ktest_make_sample_enc_data(&r->factor); p->choice = SPAKE_MSGTYPE_RESPONSE; } void ktest_make_encdata_pa_spake(krb5_pa_spake *p) { ktest_make_sample_enc_data(&p->u.encdata); p->choice = SPAKE_MSGTYPE_ENCDATA; } /****************************************************************/ /* destructors */ void ktest_destroy_data(krb5_data **d) { if (*d != NULL) { free((*d)->data); free(*d); *d = NULL; } } void ktest_empty_data(krb5_data *d) { if (d->data != NULL) { free(d->data); d->data = NULL; d->length = 0; } } static void ktest_empty_checksum(krb5_checksum *cs) { free(cs->contents); cs->contents = NULL; } void ktest_destroy_checksum(krb5_checksum **cs) { if (*cs != NULL) { free((*cs)->contents); free(*cs); *cs = NULL; } } void ktest_empty_keyblock(krb5_keyblock *kb) { if (kb != NULL) { if (kb->contents) { free(kb->contents); kb->contents = NULL; } } } void ktest_destroy_keyblock(krb5_keyblock **kb) { if (*kb != NULL) { free((*kb)->contents); free(*kb); *kb = NULL; } } void ktest_empty_authorization_data(krb5_authdata **ad) { size_t i; if (*ad != NULL) { for (i=0; ad[i] != NULL; i++) ktest_destroy_authdata(&ad[i]); } } void ktest_destroy_authorization_data(krb5_authdata ***ad) { ktest_empty_authorization_data(*ad); free(*ad); *ad = NULL; } void ktest_destroy_authdata(krb5_authdata **ad) { if (*ad != NULL) { free((*ad)->contents); free(*ad); *ad = NULL; } } void ktest_empty_pa_data_array(krb5_pa_data **pad) { size_t i; for (i=0; pad[i] != NULL; i++) ktest_destroy_pa_data(&pad[i]); } void ktest_destroy_pa_data_array(krb5_pa_data ***pad) { ktest_empty_pa_data_array(*pad); free(*pad); *pad = NULL; } void ktest_destroy_pa_data(krb5_pa_data **pad) { if (*pad != NULL) { free((*pad)->contents); free(*pad); *pad = NULL; } } void ktest_destroy_address(krb5_address **a) { if (*a != NULL) { free((*a)->contents); free(*a); *a = NULL; } } void ktest_empty_addresses(krb5_address **a) { size_t i; for (i=0; a[i] != NULL; i++) ktest_destroy_address(&a[i]); } void ktest_destroy_addresses(krb5_address ***a) { ktest_empty_addresses(*a); free(*a); *a = NULL; } void ktest_destroy_principal(krb5_principal *p) { int i; if (*p == NULL) return; for (i=0; i<(*p)->length; i++) ktest_empty_data(&(*p)->data[i]); ktest_empty_data(&(*p)->realm); free((*p)->data); free(*p); *p = NULL; } void ktest_destroy_sequence_of_integer(long **soi) { free(*soi); *soi = NULL; } void ktest_destroy_sequence_of_ticket(krb5_ticket ***sot) { size_t i; for (i=0; (*sot)[i] != NULL; i++) ktest_destroy_ticket(&(*sot)[i]); free(*sot); *sot = NULL; } void ktest_destroy_ticket(krb5_ticket **tkt) { ktest_destroy_principal(&(*tkt)->server); ktest_destroy_enc_data(&(*tkt)->enc_part); /* ktest_empty_enc_tkt_part(((*tkt)->enc_part2));*/ free(*tkt); *tkt = NULL; } void ktest_empty_ticket(krb5_ticket *tkt) { if (tkt->server) ktest_destroy_principal(&tkt->server); ktest_destroy_enc_data(&tkt->enc_part); if (tkt->enc_part2) ktest_destroy_enc_tkt_part(&tkt->enc_part2); } void ktest_destroy_enc_data(krb5_enc_data *ed) { ktest_empty_data(&ed->ciphertext); ed->kvno = 0; } void ktest_destroy_etype_info_entry(krb5_etype_info_entry *i) { if (i->salt) free(i->salt); ktest_empty_data(&i->s2kparams); free(i); } void ktest_destroy_etype_info(krb5_etype_info_entry **info) { size_t i; for (i = 0; info[i] != NULL; i++) ktest_destroy_etype_info_entry(info[i]); free(info); } void ktest_empty_kdc_req(krb5_kdc_req *kr) { if (kr->padata) ktest_destroy_pa_data_array(&kr->padata); if (kr->client) ktest_destroy_principal(&kr->client); if (kr->server) ktest_destroy_principal(&kr->server); free(kr->ktype); if (kr->addresses) ktest_destroy_addresses(&kr->addresses); ktest_destroy_enc_data(&kr->authorization_data); if (kr->unenc_authdata) ktest_destroy_authorization_data(&kr->unenc_authdata); if (kr->second_ticket) ktest_destroy_sequence_of_ticket(&kr->second_ticket); } void ktest_empty_kdc_rep(krb5_kdc_rep *kr) { if (kr->padata) ktest_destroy_pa_data_array(&kr->padata); if (kr->client) ktest_destroy_principal(&kr->client); if (kr->ticket) ktest_destroy_ticket(&kr->ticket); ktest_destroy_enc_data(&kr->enc_part); if (kr->enc_part2) { ktest_empty_enc_kdc_rep_part(kr->enc_part2); free(kr->enc_part2); kr->enc_part2 = NULL; } } void ktest_empty_authenticator(krb5_authenticator *a) { if (a->client) ktest_destroy_principal(&a->client); if (a->checksum) ktest_destroy_checksum(&a->checksum); if (a->subkey) ktest_destroy_keyblock(&a->subkey); if (a->authorization_data) ktest_destroy_authorization_data(&a->authorization_data); } void ktest_empty_enc_tkt_part(krb5_enc_tkt_part *etp) { if (etp->session) ktest_destroy_keyblock(&etp->session); if (etp->client) ktest_destroy_principal(&etp->client); if (etp->caddrs) ktest_destroy_addresses(&etp->caddrs); if (etp->authorization_data) ktest_destroy_authorization_data(&etp->authorization_data); ktest_destroy_transited(&etp->transited); } void ktest_destroy_enc_tkt_part(krb5_enc_tkt_part **etp) { if (*etp) { ktest_empty_enc_tkt_part(*etp); free(*etp); *etp = NULL; } } void ktest_empty_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ekr) { if (ekr->session) ktest_destroy_keyblock(&ekr->session); if (ekr->server) ktest_destroy_principal(&ekr->server); if (ekr->caddrs) ktest_destroy_addresses(&ekr->caddrs); ktest_destroy_last_req(&ekr->last_req); } void ktest_destroy_transited(krb5_transited *t) { if (t->tr_contents.data) ktest_empty_data(&t->tr_contents); } void ktest_empty_ap_rep(krb5_ap_rep *ar) { ktest_destroy_enc_data(&ar->enc_part); } void ktest_empty_ap_req(krb5_ap_req *ar) { if (ar->ticket) ktest_destroy_ticket(&ar->ticket); ktest_destroy_enc_data(&ar->authenticator); } void ktest_empty_cred_enc_part(krb5_cred_enc_part *cep) { if (cep->s_address) ktest_destroy_address(&cep->s_address); if (cep->r_address) ktest_destroy_address(&cep->r_address); if (cep->ticket_info) ktest_destroy_sequence_of_cred_info(&cep->ticket_info); } void ktest_destroy_cred_info(krb5_cred_info **ci) { if ((*ci)->session) ktest_destroy_keyblock(&(*ci)->session); if ((*ci)->client) ktest_destroy_principal(&(*ci)->client); if ((*ci)->server) ktest_destroy_principal(&(*ci)->server); if ((*ci)->caddrs) ktest_destroy_addresses(&(*ci)->caddrs); free(*ci); *ci = NULL; } void ktest_destroy_sequence_of_cred_info(krb5_cred_info ***soci) { size_t i; for (i = 0; (*soci)[i] != NULL; i++) ktest_destroy_cred_info(&(*soci)[i]); free(*soci); *soci = NULL; } void ktest_empty_safe(krb5_safe *s) { ktest_empty_data(&s->user_data); ktest_destroy_address(&s->s_address); ktest_destroy_address(&s->r_address); ktest_destroy_checksum(&s->checksum); } void ktest_empty_priv_enc_part(krb5_priv_enc_part *pep) { ktest_empty_data(&pep->user_data); ktest_destroy_address(&pep->s_address); ktest_destroy_address(&pep->r_address); } void ktest_empty_priv(krb5_priv *p) { ktest_destroy_enc_data(&p->enc_part); } void ktest_empty_cred(krb5_cred *c) { ktest_destroy_sequence_of_ticket(&c->tickets); ktest_destroy_enc_data(&c->enc_part); /* enc_part2 */ } void ktest_destroy_last_req(krb5_last_req_entry ***lr) { size_t i; if (*lr) { for (i=0; (*lr)[i] != NULL; i++) free((*lr)[i]); free(*lr); } } void ktest_empty_error(krb5_error *kerr) { if (kerr->client) ktest_destroy_principal(&kerr->client); if (kerr->server) ktest_destroy_principal(&kerr->server); ktest_empty_data(&kerr->text); ktest_empty_data(&kerr->e_data); } void ktest_empty_ap_rep_enc_part(krb5_ap_rep_enc_part *arep) { ktest_destroy_keyblock(&(arep)->subkey); } void ktest_empty_sam_challenge_2(krb5_sam_challenge_2 *p) { krb5_checksum **ck; ktest_empty_data(&p->sam_challenge_2_body); if (p->sam_cksum != NULL) { for (ck = p->sam_cksum; *ck != NULL; ck++) ktest_destroy_checksum(ck); free(p->sam_cksum); p->sam_cksum = NULL; } } void ktest_empty_sam_challenge_2_body(krb5_sam_challenge_2_body *p) { ktest_empty_data(&p->sam_type_name); ktest_empty_data(&p->sam_track_id); ktest_empty_data(&p->sam_challenge_label); ktest_empty_data(&p->sam_challenge); ktest_empty_data(&p->sam_response_prompt); ktest_empty_data(&p->sam_pk_for_sad); } void ktest_empty_sam_response_2(krb5_sam_response_2 *p) { ktest_empty_data(&p->sam_track_id); ktest_empty_data(&p->sam_enc_nonce_or_sad.ciphertext); } void ktest_empty_enc_sam_response_enc_2(krb5_enc_sam_response_enc_2 *p) { ktest_empty_data(&p->sam_sad); } void ktest_empty_pa_for_user(krb5_pa_for_user *p) { ktest_destroy_principal(&p->user); ktest_empty_checksum(&p->cksum); ktest_empty_data(&p->auth_package); } void ktest_empty_pa_s4u_x509_user(krb5_pa_s4u_x509_user *p) { ktest_destroy_principal(&p->user_id.user); ktest_empty_data(&p->user_id.subject_cert); free(p->cksum.contents); } void ktest_empty_ad_kdcissued(krb5_ad_kdcissued *p) { free(p->ad_checksum.contents); ktest_destroy_principal(&p->i_principal); ktest_destroy_authorization_data(&p->elements); } void ktest_empty_iakerb_header(krb5_iakerb_header *p) { krb5_free_data_contents(NULL, &p->target_realm); krb5_free_data(NULL, p->cookie); } void ktest_empty_iakerb_finished(krb5_iakerb_finished *p) { krb5_free_checksum_contents(NULL, &p->checksum); } static void ktest_empty_fast_finished(krb5_fast_finished *p) { ktest_destroy_principal(&p->client); ktest_empty_checksum(&p->ticket_checksum); } void ktest_empty_fast_response(krb5_fast_response *p) { ktest_destroy_pa_data_array(&p->padata); ktest_destroy_keyblock(&p->strengthen_key); if (p->finished != NULL) { ktest_empty_fast_finished(p->finished); free(p->finished); p->finished = NULL; } } static void ktest_empty_algorithm_identifier(krb5_algorithm_identifier *p) { ktest_empty_data(&p->algorithm); ktest_empty_data(&p->parameters); } void ktest_empty_otp_tokeninfo(krb5_otp_tokeninfo *p) { krb5_algorithm_identifier **alg; p->flags = 0; krb5_free_data_contents(NULL, &p->vendor); krb5_free_data_contents(NULL, &p->challenge); krb5_free_data_contents(NULL, &p->token_id); krb5_free_data_contents(NULL, &p->alg_id); for (alg = p->supported_hash_alg; alg != NULL && *alg != NULL; alg++) { ktest_empty_algorithm_identifier(*alg); free(*alg); } free(p->supported_hash_alg); p->supported_hash_alg = NULL; p->length = p->format = p->iteration_count = -1; } void ktest_empty_pa_otp_challenge(krb5_pa_otp_challenge *p) { krb5_otp_tokeninfo **ti; krb5_free_data_contents(NULL, &p->nonce); krb5_free_data_contents(NULL, &p->service); for (ti = p->tokeninfo; *ti != NULL; ti++) { ktest_empty_otp_tokeninfo(*ti); free(*ti); } free(p->tokeninfo); p->tokeninfo = NULL; krb5_free_data_contents(NULL, &p->salt); krb5_free_data_contents(NULL, &p->s2kparams); } void ktest_empty_pa_otp_req(krb5_pa_otp_req *p) { p->flags = 0; krb5_free_data_contents(NULL, &p->nonce); ktest_destroy_enc_data(&p->enc_data); if (p->hash_alg != NULL) ktest_empty_algorithm_identifier(p->hash_alg); free(p->hash_alg); p->hash_alg = NULL; p->iteration_count = -1; krb5_free_data_contents(NULL, &p->otp_value); krb5_free_data_contents(NULL, &p->pin); krb5_free_data_contents(NULL, &p->challenge); p->time = 0; krb5_free_data_contents(NULL, &p->counter); p->format = -1; krb5_free_data_contents(NULL, &p->token_id); krb5_free_data_contents(NULL, &p->alg_id); krb5_free_data_contents(NULL, &p->vendor); } #ifndef DISABLE_PKINIT static void ktest_empty_pk_authenticator(krb5_pk_authenticator *p) { ktest_empty_data(&p->paChecksum); krb5_free_data(NULL, p->freshnessToken); p->freshnessToken = NULL; } static void ktest_empty_external_principal_identifier( krb5_external_principal_identifier *p) { ktest_empty_data(&p->subjectName); ktest_empty_data(&p->issuerAndSerialNumber); ktest_empty_data(&p->subjectKeyIdentifier); } void ktest_empty_pa_pk_as_req(krb5_pa_pk_as_req *p) { krb5_external_principal_identifier **pi; ktest_empty_data(&p->signedAuthPack); for (pi = p->trustedCertifiers; *pi != NULL; pi++) { ktest_empty_external_principal_identifier(*pi); free(*pi); } free(p->trustedCertifiers); p->trustedCertifiers = NULL; ktest_empty_data(&p->kdcPkId); } static void ktest_empty_dh_rep_info(krb5_dh_rep_info *p) { ktest_empty_data(&p->dhSignedData); ktest_empty_data(&p->serverDHNonce); ktest_destroy_data(&p->kdfID); } void ktest_empty_pa_pk_as_rep(krb5_pa_pk_as_rep *p) { if (p->choice == choice_pa_pk_as_rep_dhInfo) ktest_empty_dh_rep_info(&p->u.dh_Info); else if (p->choice == choice_pa_pk_as_rep_encKeyPack) ktest_empty_data(&p->u.encKeyPack); p->choice = choice_pa_pk_as_rep_UNKNOWN; } void ktest_empty_auth_pack(krb5_auth_pack *p) { krb5_algorithm_identifier **ai; krb5_data **d; ktest_empty_pk_authenticator(&p->pkAuthenticator); ktest_empty_data(&p->clientPublicValue); if (p->supportedCMSTypes != NULL) { for (ai = p->supportedCMSTypes; *ai != NULL; ai++) { ktest_empty_algorithm_identifier(*ai); free(*ai); } free(p->supportedCMSTypes); p->supportedCMSTypes = NULL; } ktest_empty_data(&p->clientDHNonce); if (p->supportedKDFs != NULL) { for (d = p->supportedKDFs; *d != NULL; d++) { ktest_empty_data(*d); free(*d); } free(p->supportedKDFs); p->supportedKDFs = NULL; } } void ktest_empty_kdc_dh_key_info(krb5_kdc_dh_key_info *p) { ktest_empty_data(&p->subjectPublicKey); } void ktest_empty_reply_key_pack(krb5_reply_key_pack *p) { ktest_empty_keyblock(&p->replyKey); ktest_empty_checksum(&p->asChecksum); } void ktest_empty_sp80056a_other_info(krb5_sp80056a_other_info *p) { ktest_empty_algorithm_identifier(&p->algorithm_identifier); ktest_destroy_principal(&p->party_u_info); ktest_destroy_principal(&p->party_v_info); ktest_empty_data(&p->supp_pub_info); } void ktest_empty_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p) { ktest_empty_data(&p->as_req); ktest_empty_data(&p->pk_as_rep); } #endif /* not DISABLE_PKINIT */ #ifdef ENABLE_LDAP void ktest_empty_ldap_seqof_key_data(ldap_seqof_key_data *p) { int i; for (i = 0; i < p->n_key_data; i++) { free(p->key_data[i].key_data_contents[0]); free(p->key_data[i].key_data_contents[1]); } free(p->key_data); } #endif void ktest_empty_kkdcp_message(krb5_kkdcp_message *p) { ktest_empty_data(&p->kerb_message); ktest_empty_data(&p->target_domain); p->dclocator_hint = -1; } static void destroy_verifier_mac(krb5_verifier_mac **vmac) { if (*vmac == NULL) return; ktest_destroy_principal(&(*vmac)->princ); ktest_empty_checksum(&(*vmac)->checksum); free(*vmac); *vmac = NULL; } void ktest_empty_cammac(krb5_cammac *p) { krb5_verifier_mac **vmacp; ktest_destroy_authorization_data(&p->elements); destroy_verifier_mac(&p->kdc_verifier); destroy_verifier_mac(&p->svc_verifier); for (vmacp = p->other_verifiers; vmacp != NULL && *vmacp != NULL; vmacp++) destroy_verifier_mac(vmacp); free(p->other_verifiers); p->other_verifiers = NULL; } void ktest_empty_secure_cookie(krb5_secure_cookie *p) { ktest_destroy_pa_data_array(&p->data); } void ktest_empty_spake_factor(krb5_spake_factor *p) { krb5_free_data(NULL, p->data); p->data = NULL; } void ktest_empty_pa_spake(krb5_pa_spake *p) { krb5_spake_factor **f; switch (p->choice) { case SPAKE_MSGTYPE_SUPPORT: free(p->u.support.groups); break; case SPAKE_MSGTYPE_CHALLENGE: ktest_empty_data(&p->u.challenge.pubkey); for (f = p->u.challenge.factors; *f != NULL; f++) { ktest_empty_spake_factor(*f); free(*f); } free(p->u.challenge.factors); break; case SPAKE_MSGTYPE_RESPONSE: ktest_empty_data(&p->u.response.pubkey); ktest_destroy_enc_data(&p->u.response.factor); break; case SPAKE_MSGTYPE_ENCDATA: ktest_destroy_enc_data(&p->u.encdata); break; default: break; } p->choice = SPAKE_MSGTYPE_UNKNOWN; } krb5-1.22.1/src/tests/asn.1/krb5.asn10000664000175000017500000003156615051422640016654 0ustar ghudsonghudsonKerberosV5Spec2 { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2) } DEFINITIONS EXPLICIT TAGS ::= BEGIN -- OID arc for KerberosV5 -- -- This OID may be used to identify Kerberos protocol messages -- encapsulated in other protocols. -- -- This OID also designates the OID arc for KerberosV5-related OIDs. -- -- NOTE: RFC 1510 had an incorrect value (5) for "dod" in its OID. id-krb5 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) } Int32 ::= INTEGER (-2147483648..2147483647) -- signed values representable in 32 bits UInt32 ::= INTEGER (0..4294967295) -- unsigned 32 bit values Microseconds ::= INTEGER (0..999999) -- microseconds KerberosString ::= GeneralString -- (IA5String) Realm ::= KerberosString PrincipalName ::= SEQUENCE { name-type [0] Int32, name-string [1] SEQUENCE OF KerberosString } KerberosTime ::= GeneralizedTime -- with no fractional seconds HostAddress ::= SEQUENCE { addr-type [0] Int32, address [1] OCTET STRING } -- NOTE: HostAddresses is always used as an OPTIONAL field and -- should not be empty. HostAddresses -- NOTE: subtly different from rfc1510, -- but has a value mapping and encodes the same ::= SEQUENCE OF HostAddress -- NOTE: AuthorizationData is always used as an OPTIONAL field and -- should not be empty. AuthorizationData ::= SEQUENCE OF SEQUENCE { ad-type [0] Int32, ad-data [1] OCTET STRING } PA-DATA ::= SEQUENCE { -- NOTE: first tag is [1], not [0] padata-type [1] Int32, padata-value [2] OCTET STRING -- might be encoded AP-REQ } KerberosFlags ::= BIT STRING (SIZE (32..MAX)) -- minimum number of bits shall be sent, -- but no fewer than 32 EncryptedData ::= SEQUENCE { etype [0] Int32 -- EncryptionType --, kvno [1] UInt32 OPTIONAL, cipher [2] OCTET STRING -- ciphertext } EncryptionKey ::= SEQUENCE { keytype [0] Int32 -- actually encryption type --, keyvalue [1] OCTET STRING } Checksum ::= SEQUENCE { cksumtype [0] Int32, checksum [1] OCTET STRING } Ticket ::= [APPLICATION 1] SEQUENCE { tkt-vno [0] INTEGER (5), realm [1] Realm, sname [2] PrincipalName, enc-part [3] EncryptedData -- EncTicketPart } -- Encrypted part of ticket EncTicketPart ::= [APPLICATION 3] SEQUENCE { flags [0] TicketFlags, key [1] EncryptionKey, crealm [2] Realm, cname [3] PrincipalName, transited [4] TransitedEncoding, authtime [5] KerberosTime, starttime [6] KerberosTime OPTIONAL, endtime [7] KerberosTime, renew-till [8] KerberosTime OPTIONAL, caddr [9] HostAddresses OPTIONAL, authorization-data [10] AuthorizationData OPTIONAL } -- encoded Transited field TransitedEncoding ::= SEQUENCE { tr-type [0] Int32 -- must be registered --, contents [1] OCTET STRING } TicketFlags ::= KerberosFlags -- reserved(0), -- forwardable(1), -- forwarded(2), -- proxiable(3), -- proxy(4), -- may-postdate(5), -- postdated(6), -- invalid(7), -- renewable(8), -- initial(9), -- pre-authent(10), -- hw-authent(11), -- the following are new since 1510 -- transited-policy-checked(12), -- ok-as-delegate(13) AS-REQ ::= [APPLICATION 10] KDC-REQ TGS-REQ ::= [APPLICATION 12] KDC-REQ KDC-REQ ::= SEQUENCE { -- NOTE: first tag is [1], not [0] pvno [1] INTEGER (5) , msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), padata [3] SEQUENCE OF PA-DATA OPTIONAL -- NOTE: not empty --, req-body [4] KDC-REQ-BODY } KDC-REQ-BODY ::= SEQUENCE { kdc-options [0] KDCOptions, cname [1] PrincipalName OPTIONAL -- Used only in AS-REQ --, realm [2] Realm -- Server's realm -- Also client's in AS-REQ --, sname [3] PrincipalName OPTIONAL, from [4] KerberosTime OPTIONAL, till [5] KerberosTime, rtime [6] KerberosTime OPTIONAL, nonce [7] UInt32, etype [8] SEQUENCE OF Int32 -- EncryptionType -- in preference order --, addresses [9] HostAddresses OPTIONAL, enc-authorization-data [10] EncryptedData OPTIONAL -- AuthorizationData --, additional-tickets [11] SEQUENCE OF Ticket OPTIONAL -- NOTE: not empty } KDCOptions ::= KerberosFlags -- reserved(0), -- forwardable(1), -- forwarded(2), -- proxiable(3), -- proxy(4), -- allow-postdate(5), -- postdated(6), -- unused7(7), -- renewable(8), -- unused9(9), -- unused10(10), -- opt-hardware-auth(11), -- unused12(12), -- unused13(13), -- 15 is reserved for canonicalize -- unused15(15), -- 26 was unused in 1510 -- disable-transited-check(26), -- -- renewable-ok(27), -- enc-tkt-in-skey(28), -- renew(30), -- validate(31) AS-REP ::= [APPLICATION 11] KDC-REP TGS-REP ::= [APPLICATION 13] KDC-REP KDC-REP ::= SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (11 -- AS -- | 13 -- TGS --), padata [2] SEQUENCE OF PA-DATA OPTIONAL -- NOTE: not empty --, crealm [3] Realm, cname [4] PrincipalName, ticket [5] Ticket, enc-part [6] EncryptedData -- EncASRepPart or EncTGSRepPart, -- as appropriate } EncASRepPart ::= [APPLICATION 25] EncKDCRepPart EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart EncKDCRepPart ::= SEQUENCE { key [0] EncryptionKey, last-req [1] LastReq, nonce [2] UInt32, key-expiration [3] KerberosTime OPTIONAL, flags [4] TicketFlags, authtime [5] KerberosTime, starttime [6] KerberosTime OPTIONAL, endtime [7] KerberosTime, renew-till [8] KerberosTime OPTIONAL, srealm [9] Realm, sname [10] PrincipalName, caddr [11] HostAddresses OPTIONAL } LastReq ::= SEQUENCE OF SEQUENCE { lr-type [0] Int32, lr-value [1] KerberosTime } AP-REQ ::= [APPLICATION 14] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (14), ap-options [2] APOptions, ticket [3] Ticket, authenticator [4] EncryptedData -- Authenticator } APOptions ::= KerberosFlags -- reserved(0), -- use-session-key(1), -- mutual-required(2) -- Unencrypted authenticator Authenticator ::= [APPLICATION 2] SEQUENCE { authenticator-vno [0] INTEGER (5), crealm [1] Realm, cname [2] PrincipalName, cksum [3] Checksum OPTIONAL, cusec [4] Microseconds, ctime [5] KerberosTime, subkey [6] EncryptionKey OPTIONAL, seq-number [7] UInt32 OPTIONAL, authorization-data [8] AuthorizationData OPTIONAL } AP-REP ::= [APPLICATION 15] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (15), enc-part [2] EncryptedData -- EncAPRepPart } EncAPRepPart ::= [APPLICATION 27] SEQUENCE { ctime [0] KerberosTime, cusec [1] Microseconds, subkey [2] EncryptionKey OPTIONAL, seq-number [3] UInt32 OPTIONAL } KRB-SAFE ::= [APPLICATION 20] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (20), safe-body [2] KRB-SAFE-BODY, cksum [3] Checksum } KRB-SAFE-BODY ::= SEQUENCE { user-data [0] OCTET STRING, timestamp [1] KerberosTime OPTIONAL, usec [2] Microseconds OPTIONAL, seq-number [3] UInt32 OPTIONAL, s-address [4] HostAddress, r-address [5] HostAddress OPTIONAL } KRB-PRIV ::= [APPLICATION 21] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (21), -- NOTE: there is no [2] tag enc-part [3] EncryptedData -- EncKrbPrivPart } EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE { user-data [0] OCTET STRING, timestamp [1] KerberosTime OPTIONAL, usec [2] Microseconds OPTIONAL, seq-number [3] UInt32 OPTIONAL, s-address [4] HostAddress -- sender's addr --, r-address [5] HostAddress OPTIONAL -- recip's addr } KRB-CRED ::= [APPLICATION 22] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (22), tickets [2] SEQUENCE OF Ticket, enc-part [3] EncryptedData -- EncKrbCredPart } EncKrbCredPart ::= [APPLICATION 29] SEQUENCE { ticket-info [0] SEQUENCE OF KrbCredInfo, nonce [1] UInt32 OPTIONAL, timestamp [2] KerberosTime OPTIONAL, usec [3] Microseconds OPTIONAL, s-address [4] HostAddress OPTIONAL, r-address [5] HostAddress OPTIONAL } KrbCredInfo ::= SEQUENCE { key [0] EncryptionKey, prealm [1] Realm OPTIONAL, pname [2] PrincipalName OPTIONAL, flags [3] TicketFlags OPTIONAL, authtime [4] KerberosTime OPTIONAL, starttime [5] KerberosTime OPTIONAL, endtime [6] KerberosTime OPTIONAL, renew-till [7] KerberosTime OPTIONAL, srealm [8] Realm OPTIONAL, sname [9] PrincipalName OPTIONAL, caddr [10] HostAddresses OPTIONAL } KRB-ERROR ::= [APPLICATION 30] SEQUENCE { pvno [0] INTEGER (5), msg-type [1] INTEGER (30), ctime [2] KerberosTime OPTIONAL, cusec [3] Microseconds OPTIONAL, stime [4] KerberosTime, susec [5] Microseconds, error-code [6] Int32, crealm [7] Realm OPTIONAL, cname [8] PrincipalName OPTIONAL, realm [9] Realm -- service realm --, sname [10] PrincipalName -- service name --, e-text [11] KerberosString OPTIONAL, e-data [12] OCTET STRING OPTIONAL } METHOD-DATA ::= SEQUENCE OF PA-DATA TYPED-DATA ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { data-type [0] Int32, data-value [1] OCTET STRING OPTIONAL } -- preauth stuff follows PA-ENC-TIMESTAMP ::= EncryptedData -- PA-ENC-TS-ENC PA-ENC-TS-ENC ::= SEQUENCE { patimestamp [0] KerberosTime -- client's time --, pausec [1] Microseconds OPTIONAL } ETYPE-INFO-ENTRY ::= SEQUENCE { etype [0] Int32, salt [1] OCTET STRING OPTIONAL } ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY ETYPE-INFO2-ENTRY ::= SEQUENCE { etype [0] Int32, salt [1] KerberosString OPTIONAL, s2kparams [2] OCTET STRING OPTIONAL } ETYPE-INFO2 ::= SEQUENCE SIZE (1..MAX) OF ETYPE-INFO2-ENTRY AD-IF-RELEVANT ::= AuthorizationData AD-KDCIssued ::= SEQUENCE { ad-checksum [0] Checksum, i-realm [1] Realm OPTIONAL, i-sname [2] PrincipalName OPTIONAL, elements [3] AuthorizationData } AD-AND-OR ::= SEQUENCE { condition-count [0] Int32, elements [1] AuthorizationData } AD-MANDATORY-FOR-KDC ::= AuthorizationData END krb5-1.22.1/src/tests/asn.1/pkinit_trval.out0000664000175000017500000000601015051422640020446 0ustar ghudsonghudson encode_krb5_pa_pk_as_req: [Sequence/Sequence Of] . [0] <8> 6b 72 62 35 64 61 74 61 krb5data . [1] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] <8> 6b 72 62 35 64 61 74 61 krb5data . . . [1] <8> 6b 72 62 35 64 61 74 61 krb5data . . . [2] <8> 6b 72 62 35 64 61 74 61 krb5data . [2] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_pa_pk_as_rep(dhInfo): [CONT 0] . [Sequence/Sequence Of] . . [0] <8> 6b 72 62 35 64 61 74 61 krb5data . . [1] [Octet String] "krb5data" . . [2] [Sequence/Sequence Of] . . . [0] [Object Identifier] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_pa_pk_as_rep(encKeyPack): [CONT 1] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_auth_pack: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 123456 . . [1] [Generalized Time] "19940610060317Z" . . [2] [Integer] 42 . . [3] [Octet String] "krb5data" . . [4] [Octet String] "krb5data" . [1] [Octet String] "pvalue" . [2] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [Object Identifier] <9> 2a 86 48 86 f7 12 01 02 02 *.H...... . . . [Octet String] "params" . . [Sequence/Sequence Of] . . . [Object Identifier] <9> 2a 86 48 86 f7 12 01 02 02 *.H...... . [3] [Octet String] "krb5data" . [4] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Object Identifier] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_kdc_dh_key_info: [Sequence/Sequence Of] . [0] [Bit String] <9> 00 6b 72 62 35 64 61 74 61 .krb5data . [1] [Integer] 42 . [2] [Generalized Time] "19940610060317Z" encode_krb5_reply_key_pack: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "12345678" . [1] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" encode_krb5_sp80056a_other_info: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [Object Identifier] <9> 2a 86 48 86 f7 12 01 02 02 *.H...... . [0] [Octet String] <48> 30 2e a0 10 1b 0e 41 54 48 45 4e 41 2e 4d 49 54 0.....ATHENA.MIT 2e 45 44 55 a1 1a 30 18 a0 03 02 01 01 a1 11 30 .EDU..0........0 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 74 72 61 ...hftsai..extra . [1] [Octet String] <48> 30 2e a0 10 1b 0e 41 54 48 45 4e 41 2e 4d 49 54 0.....ATHENA.MIT 2e 45 44 55 a1 1a 30 18 a0 03 02 01 01 a1 11 30 .EDU..0........0 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 74 72 61 ...hftsai..extra . [2] [Octet String] "krb5data" encode_krb5_pkinit_supp_pub_info: [Sequence/Sequence Of] . [0] [Integer] 20 . [1] [Octet String] "krb5data" . [2] [Octet String] "krb5data" krb5-1.22.1/src/tests/asn.1/cammac.asn10000664000175000017500000000164115051422640017221 0ustar ghudsonghudsonKerberosV5CAMMAC DEFINITIONS EXPLICIT TAGS ::= BEGIN IMPORTS AuthorizationData, PrincipalName, Checksum, UInt32, Int32 FROM KerberosV5Spec2 { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2) }; -- as defined in RFC 4120. AD-CAMMAC ::= SEQUENCE { elements [0] AuthorizationData, kdc-verifier [1] Verifier-MAC OPTIONAL, svc-verifier [2] Verifier-MAC OPTIONAL, other-verifiers [3] SEQUENCE (SIZE (1..MAX)) OF Verifier OPTIONAL } Verifier ::= CHOICE { mac Verifier-MAC, ... } Verifier-MAC ::= SEQUENCE { identifier [0] PrincipalName OPTIONAL, kvno [1] UInt32 OPTIONAL, enctype [2] Int32 OPTIONAL, mac [3] Checksum } END krb5-1.22.1/src/tests/asn.1/otp.asn10000664000175000017500000000775715051422640016620 0ustar ghudsonghudson OTPKerberos DEFINITIONS IMPLICIT TAGS ::= BEGIN IMPORTS KerberosTime, KerberosFlags, EncryptionKey, Int32, EncryptedData, LastReq, KerberosString FROM KerberosV5Spec2 {iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2)} -- as defined in RFC 4120. AlgorithmIdentifier FROM PKIX1Explicit88 { iso (1) identified-organization (3) dod (6) internet (1) security (5) mechanisms (5) pkix (7) id-mod (0) id-pkix1-explicit (18) }; -- As defined in RFC 5280. PA-OTP-CHALLENGE ::= SEQUENCE { nonce [0] OCTET STRING, otp-service [1] UTF8String OPTIONAL, otp-tokenInfo [2] SEQUENCE (SIZE(1..MAX)) OF OTP-TOKENINFO, salt [3] KerberosString OPTIONAL, s2kparams [4] OCTET STRING OPTIONAL, ... } OTP-TOKENINFO ::= SEQUENCE { flags [0] OTPFlags, otp-vendor [1] UTF8String OPTIONAL, otp-challenge [2] OCTET STRING (SIZE(1..MAX)) OPTIONAL, otp-length [3] Int32 OPTIONAL, otp-format [4] OTPFormat OPTIONAL, otp-tokenID [5] OCTET STRING OPTIONAL, otp-algID [6] AnyURI OPTIONAL, supportedHashAlg [7] SEQUENCE OF AlgorithmIdentifier OPTIONAL, iterationCount [8] Int32 OPTIONAL, ... } OTPFormat ::= INTEGER { decimal(0), hexadecimal(1), alphanumeric(2), binary(3), base64(4) } OTPFlags ::= KerberosFlags -- reserved(0), -- nextOTP(1), -- combine(2), -- collect-pin(3), -- do-not-collect-pin(4), -- must-encrypt-nonce (5), -- separate-pin-required (6), -- check-digit (7) PA-OTP-REQUEST ::= SEQUENCE { flags [0] OTPFlags, nonce [1] OCTET STRING OPTIONAL, encData [2] EncryptedData, -- PA-OTP-ENC-REQUEST or PA-ENC-TS-ENC -- Key usage of KEY_USAGE_OTP_REQUEST hashAlg [3] AlgorithmIdentifier OPTIONAL, iterationCount [4] Int32 OPTIONAL, otp-value [5] OCTET STRING OPTIONAL, otp-pin [6] UTF8String OPTIONAL, otp-challenge [7] OCTET STRING (SIZE(1..MAX)) OPTIONAL, otp-time [8] KerberosTime OPTIONAL, otp-counter [9] OCTET STRING OPTIONAL, otp-format [10] OTPFormat OPTIONAL, otp-tokenID [11] OCTET STRING OPTIONAL, otp-algID [12] AnyURI OPTIONAL, otp-vendor [13] UTF8String OPTIONAL, ... } PA-OTP-ENC-REQUEST ::= SEQUENCE { nonce [0] OCTET STRING, ... } PA-OTP-PIN-CHANGE ::= SEQUENCE { flags [0] PinFlags, pin [1] UTF8String OPTIONAL, minLength [2] INTEGER OPTIONAL, maxLength [3] INTEGER OPTIONAL, last-req [4] LastReq OPTIONAL, format [5] OTPFormat OPTIONAL, ... } PinFlags ::= KerberosFlags -- reserved(0), -- systemSetPin(1), -- mandatory(2) AnyURI ::= UTF8String (CONSTRAINED BY { -- MUST be a valid URI in accordance with IETF RFC 2396 }) END krb5-1.22.1/src/tests/asn.1/krb5_decode_leak.c0000664000175000017500000006024715051422640020531 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/krb5_decode_leak.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This program is intended to help detect memory leaks in the ASN.1 * decoder functions by exercising their failure paths. The setup * code for the test cases is copied from krb5_encode_test.c. * * This code does not actually detect leaks by itself; it must be run * through a leak-detection tool such as valgrind to do so. Simply * running the program will exercise a bunch of ASN.1 encoder and * decoder code paths but won't validate the results. */ #include "k5-int.h" #include "com_err.h" #include "utility.h" #include "ktest.h" #include "debug.h" krb5_context test_context; /* * Contrary to our usual convention, krb5_free_cred_enc_part is a * contents-only free function (and is assumed to be by mk_cred and * rd_cred) and we have no whole-structure free function for that data * type. So create one here. */ static void free_cred_enc_part_whole(krb5_context ctx, krb5_cred_enc_part *val) { krb5_free_cred_enc_part(ctx, val); free(val); } int main(int argc, char **argv) { krb5_data *code; krb5_error_code retval; unsigned int i; retval = krb5_init_context(&test_context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } init_access(argv[0]); #define encode_run(value,type,typestring,description,encoder) /* * Encode a value. Then attempt to trigger most failure paths of * the decoder function by passing in corrupt encodings, which we * generate by perturbing each byte of the encoding in turn. Some * of the perturbed encodings are expected to decode successfully, * so we need a free function to discard successful results. Make * sure to define a pointer named "tmp" of the correct type in the * enclosing block. */ #define leak_test(value, encoder, decoder, freefn) \ retval = encoder(&(value),&(code)); \ if (retval) { \ com_err("krb5_decode_leak", retval, "while encoding"); \ exit(1); \ } \ for (i = 0; i < code->length; i++) { \ code->data[i] = (char)~((unsigned char)code->data[i]); \ retval = decoder(code, &tmp); \ code->data[i] = (char)~((unsigned char)code->data[i]); \ if (retval == 0) \ freefn(test_context, tmp); \ } \ krb5_free_data(test_context, code); /****************************************************************/ /* encode_krb5_authenticator */ { krb5_authenticator authent, *tmp; ktest_make_sample_authenticator(&authent); leak_test(authent, encode_krb5_authenticator, decode_krb5_authenticator, krb5_free_authenticator); ktest_destroy_checksum(&(authent.checksum)); ktest_destroy_keyblock(&(authent.subkey)); authent.seq_number = 0; ktest_empty_authorization_data(authent.authorization_data); leak_test(authent, encode_krb5_authenticator, decode_krb5_authenticator, krb5_free_authenticator); ktest_destroy_authorization_data(&(authent.authorization_data)); leak_test(authent, encode_krb5_authenticator, decode_krb5_authenticator, krb5_free_authenticator); ktest_empty_authenticator(&authent); } /****************************************************************/ /* encode_krb5_ticket */ { krb5_ticket tkt, *tmp; ktest_make_sample_ticket(&tkt); leak_test(tkt, encode_krb5_ticket, decode_krb5_ticket, krb5_free_ticket); ktest_empty_ticket(&tkt); } /****************************************************************/ /* encode_krb5_encryption_key */ { krb5_keyblock keyblk, *tmp; ktest_make_sample_keyblock(&keyblk); leak_test(keyblk, encode_krb5_encryption_key, decode_krb5_encryption_key, krb5_free_keyblock); ktest_empty_keyblock(&keyblk); } /****************************************************************/ /* encode_krb5_enc_tkt_part */ { krb5_ticket tkt; krb5_enc_tkt_part *tmp; memset(&tkt, 0, sizeof(krb5_ticket)); tkt.enc_part2 = ealloc(sizeof(krb5_enc_tkt_part)); ktest_make_sample_enc_tkt_part(tkt.enc_part2); leak_test(*(tkt.enc_part2), encode_krb5_enc_tkt_part, decode_krb5_enc_tkt_part, krb5_free_enc_tkt_part); tkt.enc_part2->times.starttime = 0; tkt.enc_part2->times.renew_till = 0; ktest_destroy_address(&(tkt.enc_part2->caddrs[1])); ktest_destroy_address(&(tkt.enc_part2->caddrs[0])); ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[1])); ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[0])); /* ISODE version fails on the empty caddrs field */ ktest_destroy_addresses(&(tkt.enc_part2->caddrs)); ktest_destroy_authorization_data(&(tkt.enc_part2->authorization_data)); leak_test(*(tkt.enc_part2), encode_krb5_enc_tkt_part, decode_krb5_enc_tkt_part, krb5_free_enc_tkt_part); ktest_empty_ticket(&tkt); } /****************************************************************/ /* encode_krb5_enc_kdc_rep_part */ { krb5_kdc_rep kdcr; krb5_enc_kdc_rep_part *tmp; memset(&kdcr, 0, sizeof(kdcr)); kdcr.enc_part2 = ealloc(sizeof(krb5_enc_kdc_rep_part)); ktest_make_sample_enc_kdc_rep_part(kdcr.enc_part2); leak_test(*(kdcr.enc_part2), encode_krb5_enc_kdc_rep_part, decode_krb5_enc_kdc_rep_part, krb5_free_enc_kdc_rep_part); kdcr.enc_part2->key_exp = 0; kdcr.enc_part2->times.starttime = 0; kdcr.enc_part2->flags &= ~TKT_FLG_RENEWABLE; ktest_destroy_addresses(&(kdcr.enc_part2->caddrs)); leak_test(*(kdcr.enc_part2), encode_krb5_enc_kdc_rep_part, decode_krb5_enc_kdc_rep_part, krb5_free_enc_kdc_rep_part); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_as_rep */ { krb5_kdc_rep kdcr, *tmp; ktest_make_sample_kdc_rep(&kdcr); kdcr.msg_type = KRB5_AS_REP; leak_test(kdcr, encode_krb5_as_rep, decode_krb5_as_rep, krb5_free_kdc_rep); ktest_destroy_pa_data_array(&(kdcr.padata)); leak_test(kdcr, encode_krb5_as_rep, decode_krb5_as_rep, krb5_free_kdc_rep); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_tgs_rep */ { krb5_kdc_rep kdcr, *tmp; ktest_make_sample_kdc_rep(&kdcr); kdcr.msg_type = KRB5_TGS_REP; leak_test(kdcr, encode_krb5_tgs_rep, decode_krb5_tgs_rep, krb5_free_kdc_rep); ktest_destroy_pa_data_array(&(kdcr.padata)); leak_test(kdcr, encode_krb5_tgs_rep, decode_krb5_tgs_rep, krb5_free_kdc_rep); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_ap_req */ { krb5_ap_req apreq, *tmp; ktest_make_sample_ap_req(&apreq); leak_test(apreq, encode_krb5_ap_req, decode_krb5_ap_req, krb5_free_ap_req); ktest_empty_ap_req(&apreq); } /****************************************************************/ /* encode_krb5_ap_rep */ { krb5_ap_rep aprep, *tmp; ktest_make_sample_ap_rep(&aprep); leak_test(aprep, encode_krb5_ap_rep, decode_krb5_ap_rep, krb5_free_ap_rep); ktest_empty_ap_rep(&aprep); } /****************************************************************/ /* encode_krb5_ap_rep_enc_part */ { krb5_ap_rep_enc_part apenc, *tmp; ktest_make_sample_ap_rep_enc_part(&apenc); leak_test(apenc, encode_krb5_ap_rep_enc_part, decode_krb5_ap_rep_enc_part, krb5_free_ap_rep_enc_part); ktest_destroy_keyblock(&(apenc.subkey)); apenc.seq_number = 0; leak_test(apenc, encode_krb5_ap_rep_enc_part, decode_krb5_ap_rep_enc_part, krb5_free_ap_rep_enc_part); ktest_empty_ap_rep_enc_part(&apenc); } /****************************************************************/ /* encode_krb5_as_req */ { krb5_kdc_req asreq, *tmp; ktest_make_sample_kdc_req(&asreq); asreq.msg_type = KRB5_AS_REQ; asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(asreq, encode_krb5_as_req, decode_krb5_as_req, krb5_free_kdc_req); ktest_destroy_pa_data_array(&(asreq.padata)); ktest_destroy_principal(&(asreq.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(asreq.server)); #endif asreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; asreq.from = 0; asreq.rtime = 0; ktest_destroy_addresses(&(asreq.addresses)); ktest_destroy_enc_data(&(asreq.authorization_data)); leak_test(asreq, encode_krb5_as_req, decode_krb5_as_req, krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(asreq.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(asreq.server)); #endif asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(asreq, encode_krb5_as_req, decode_krb5_as_req, krb5_free_kdc_req); ktest_empty_kdc_req(&asreq); } /****************************************************************/ /* encode_krb5_tgs_req */ { krb5_kdc_req tgsreq, *tmp; ktest_make_sample_kdc_req(&tgsreq); tgsreq.msg_type = KRB5_TGS_REQ; tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(tgsreq, encode_krb5_tgs_req, decode_krb5_tgs_req, krb5_free_kdc_req); ktest_destroy_pa_data_array(&(tgsreq.padata)); ktest_destroy_principal(&(tgsreq.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(tgsreq.server)); #endif tgsreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; tgsreq.from = 0; tgsreq.rtime = 0; ktest_destroy_addresses(&(tgsreq.addresses)); ktest_destroy_enc_data(&(tgsreq.authorization_data)); leak_test(tgsreq, encode_krb5_tgs_req, decode_krb5_tgs_req, krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(tgsreq.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(tgsreq.server)); #endif tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(tgsreq, encode_krb5_tgs_req, decode_krb5_tgs_req, krb5_free_kdc_req); ktest_empty_kdc_req(&tgsreq); } /****************************************************************/ /* encode_krb5_kdc_req_body */ { krb5_kdc_req kdcrb, *tmp; memset(&kdcrb, 0, sizeof(kdcrb)); ktest_make_sample_kdc_req_body(&kdcrb); kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(kdcrb, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body, krb5_free_kdc_req); ktest_destroy_principal(&(kdcrb.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(kdcrb.server)); #endif kdcrb.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; kdcrb.from = 0; kdcrb.rtime = 0; ktest_destroy_addresses(&(kdcrb.addresses)); ktest_destroy_enc_data(&(kdcrb.authorization_data)); leak_test(kdcrb, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body, krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(kdcrb.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(kdcrb.server)); #endif kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; leak_test(kdcrb, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body, krb5_free_kdc_req); ktest_empty_kdc_req(&kdcrb); } /****************************************************************/ /* encode_krb5_safe */ { krb5_safe s, *tmp; ktest_make_sample_safe(&s); leak_test(s, encode_krb5_safe, decode_krb5_safe, krb5_free_safe); s.timestamp = 0; /* s.usec should be opted out by the timestamp */ s.seq_number = 0; ktest_destroy_address(&(s.r_address)); leak_test(s, encode_krb5_safe, decode_krb5_safe, krb5_free_safe); ktest_empty_safe(&s); } /****************************************************************/ /* encode_krb5_priv */ { krb5_priv p, *tmp; ktest_make_sample_priv(&p); leak_test(p, encode_krb5_priv, decode_krb5_priv, krb5_free_priv); ktest_empty_priv(&p); } /****************************************************************/ /* encode_krb5_enc_priv_part */ { krb5_priv_enc_part ep, *tmp; ktest_make_sample_priv_enc_part(&ep); leak_test(ep, encode_krb5_enc_priv_part, decode_krb5_enc_priv_part, krb5_free_priv_enc_part); ep.timestamp = 0; /* ep.usec should be opted out along with timestamp */ ep.seq_number = 0; ktest_destroy_address(&(ep.r_address)); leak_test(ep, encode_krb5_enc_priv_part, decode_krb5_enc_priv_part, krb5_free_priv_enc_part); ktest_empty_priv_enc_part(&ep); } /****************************************************************/ /* encode_krb5_cred */ { krb5_cred c, *tmp; ktest_make_sample_cred(&c); leak_test(c, encode_krb5_cred, decode_krb5_cred, krb5_free_cred); ktest_empty_cred(&c); } /****************************************************************/ /* encode_krb5_enc_cred_part */ { krb5_cred_enc_part cep, *tmp; ktest_make_sample_cred_enc_part(&cep); leak_test(cep, encode_krb5_enc_cred_part, decode_krb5_enc_cred_part, free_cred_enc_part_whole); ktest_destroy_principal(&(cep.ticket_info[0]->client)); ktest_destroy_principal(&(cep.ticket_info[0]->server)); cep.ticket_info[0]->flags = 0; cep.ticket_info[0]->times.authtime = 0; cep.ticket_info[0]->times.starttime = 0; cep.ticket_info[0]->times.endtime = 0; cep.ticket_info[0]->times.renew_till = 0; ktest_destroy_addresses(&(cep.ticket_info[0]->caddrs)); cep.nonce = 0; cep.timestamp = 0; ktest_destroy_address(&(cep.s_address)); ktest_destroy_address(&(cep.r_address)); leak_test(cep, encode_krb5_enc_cred_part, decode_krb5_enc_cred_part, free_cred_enc_part_whole); ktest_empty_cred_enc_part(&cep); } /****************************************************************/ /* encode_krb5_error */ { krb5_error kerr, *tmp; ktest_make_sample_error(&kerr); leak_test(kerr, encode_krb5_error, decode_krb5_error, krb5_free_error); kerr.ctime = 0; ktest_destroy_principal(&(kerr.client)); ktest_empty_data(&(kerr.text)); ktest_empty_data(&(kerr.e_data)); leak_test(kerr, encode_krb5_error, decode_krb5_error, krb5_free_error); ktest_empty_error(&kerr); } /****************************************************************/ /* encode_krb5_authdata */ { krb5_authdata **ad, **tmp; ktest_make_sample_authorization_data(&ad); leak_test(*ad, encode_krb5_authdata, decode_krb5_authdata, krb5_free_authdata); ktest_destroy_authorization_data(&ad); } /****************************************************************/ /* encode_padata_sequence and encode_typed_data */ { krb5_pa_data **pa, **tmp; ktest_make_sample_pa_data_array(&pa); leak_test(*pa, encode_krb5_padata_sequence, decode_krb5_padata_sequence, krb5_free_pa_data); leak_test(*pa, encode_krb5_typed_data, decode_krb5_typed_data, krb5_free_pa_data); ktest_destroy_pa_data_array(&pa); } /****************************************************************/ /* encode_padata_sequence (empty) */ { krb5_pa_data **pa, **tmp; ktest_make_sample_empty_pa_data_array(&pa); leak_test(*pa, encode_krb5_padata_sequence, decode_krb5_padata_sequence, krb5_free_pa_data); ktest_destroy_pa_data_array(&pa); } /****************************************************************/ /* encode_etype_info */ { krb5_etype_info_entry **info, **tmp; ktest_make_sample_etype_info(&info); leak_test(*info, encode_krb5_etype_info, decode_krb5_etype_info, krb5_free_etype_info); ktest_destroy_etype_info_entry(info[2]); info[2] = 0; ktest_destroy_etype_info_entry(info[1]); info[1] = 0; leak_test(*info, encode_krb5_etype_info, decode_krb5_etype_info, krb5_free_etype_info); ktest_destroy_etype_info_entry(info[0]); info[0] = 0; leak_test(*info, encode_krb5_etype_info, decode_krb5_etype_info, krb5_free_etype_info); ktest_destroy_etype_info(info); } /* encode_etype_info 2*/ { krb5_etype_info_entry **info, **tmp; ktest_make_sample_etype_info2(&info); leak_test(*info, encode_krb5_etype_info2, decode_krb5_etype_info2, krb5_free_etype_info); ktest_destroy_etype_info_entry(info[2]); info[2] = 0; ktest_destroy_etype_info_entry(info[1]); info[1] = 0; leak_test(*info, encode_krb5_etype_info2, decode_krb5_etype_info2, krb5_free_etype_info); ktest_destroy_etype_info(info); } /****************************************************************/ /* encode_pa_enc_ts */ { krb5_pa_enc_ts pa_enc, *tmp; ktest_make_sample_pa_enc_ts(&pa_enc); leak_test(pa_enc, encode_krb5_pa_enc_ts, decode_krb5_pa_enc_ts, krb5_free_pa_enc_ts); pa_enc.pausec = 0; leak_test(pa_enc, encode_krb5_pa_enc_ts, decode_krb5_pa_enc_ts, krb5_free_pa_enc_ts); } /****************************************************************/ /* encode_enc_data */ { krb5_enc_data enc_data, *tmp; ktest_make_sample_enc_data(&enc_data); leak_test(enc_data, encode_krb5_enc_data, decode_krb5_enc_data, krb5_free_enc_data); ktest_destroy_enc_data(&enc_data); } /****************************************************************/ /* encode_krb5_sam_challenge_2 */ { krb5_sam_challenge_2 sam_ch2, *tmp; ktest_make_sample_sam_challenge_2(&sam_ch2); leak_test(sam_ch2, encode_krb5_sam_challenge_2, decode_krb5_sam_challenge_2, krb5_free_sam_challenge_2); ktest_empty_sam_challenge_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_sam_challenge_2 */ { krb5_sam_challenge_2_body body, *tmp; ktest_make_sample_sam_challenge_2_body(&body); leak_test(body, encode_krb5_sam_challenge_2_body, decode_krb5_sam_challenge_2_body, krb5_free_sam_challenge_2_body); ktest_empty_sam_challenge_2_body(&body); } /****************************************************************/ /* encode_krb5_sam_response_2 */ { krb5_sam_response_2 sam_ch2, *tmp; ktest_make_sample_sam_response_2(&sam_ch2); leak_test(sam_ch2, encode_krb5_sam_response_2, decode_krb5_sam_response_2, krb5_free_sam_response_2); ktest_empty_sam_response_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_sam_response_enc_2 */ { krb5_enc_sam_response_enc_2 sam_ch2, *tmp; ktest_make_sample_enc_sam_response_enc_2(&sam_ch2); leak_test(sam_ch2, encode_krb5_enc_sam_response_enc_2, decode_krb5_enc_sam_response_enc_2, krb5_free_enc_sam_response_enc_2); ktest_empty_enc_sam_response_enc_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_pa_for_user */ { krb5_pa_for_user foru, *tmp; ktest_make_sample_pa_for_user(&foru); leak_test(foru, encode_krb5_pa_for_user, decode_krb5_pa_for_user, krb5_free_pa_for_user); ktest_empty_pa_for_user(&foru); } /****************************************************************/ /* encode_krb5_pa_s4u_x509_user */ { krb5_pa_s4u_x509_user s4u, *tmp; ktest_make_sample_pa_s4u_x509_user(&s4u); leak_test(s4u, encode_krb5_pa_s4u_x509_user, decode_krb5_pa_s4u_x509_user, krb5_free_pa_s4u_x509_user); ktest_empty_pa_s4u_x509_user(&s4u); } /****************************************************************/ /* encode_krb5_ad_kdcissued */ { krb5_ad_kdcissued kdci, *tmp; ktest_make_sample_ad_kdcissued(&kdci); leak_test(kdci, encode_krb5_ad_kdcissued, decode_krb5_ad_kdcissued, krb5_free_ad_kdcissued); ktest_empty_ad_kdcissued(&kdci); } /****************************************************************/ /* encode_krb5_iakerb_header */ { krb5_iakerb_header ih, *tmp; ktest_make_sample_iakerb_header(&ih); leak_test(ih, encode_krb5_iakerb_header, decode_krb5_iakerb_header, krb5_free_iakerb_header); ktest_empty_iakerb_header(&ih); } /****************************************************************/ /* encode_krb5_iakerb_finished */ { krb5_iakerb_finished ih, *tmp; ktest_make_sample_iakerb_finished(&ih); leak_test(ih, encode_krb5_iakerb_finished, decode_krb5_iakerb_finished, krb5_free_iakerb_finished); ktest_empty_iakerb_finished(&ih); } /****************************************************************/ /* encode_krb5_fast_response */ { krb5_fast_response fr, *tmp; ktest_make_sample_fast_response(&fr); leak_test(fr, encode_krb5_fast_response, decode_krb5_fast_response, krb5_free_fast_response); ktest_empty_fast_response(&fr); } /****************************************************************/ /* encode_krb5_pa_fx_fast_reply */ { krb5_enc_data enc, *tmp; ktest_make_sample_enc_data(&enc); leak_test(enc, encode_krb5_pa_fx_fast_reply, decode_krb5_pa_fx_fast_reply, krb5_free_enc_data); ktest_destroy_enc_data(&enc); } krb5_free_context(test_context); return 0; } krb5-1.22.1/src/tests/asn.1/pkinit_encode.out0000664000175000017500000000327115051422640020561 0ustar ghudsonghudsonencode_krb5_pa_pk_as_req: 30 38 80 08 6B 72 62 35 64 61 74 61 A1 22 30 20 30 1E 80 08 6B 72 62 35 64 61 74 61 81 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61 encode_krb5_pa_pk_as_rep(dhInfo): A0 28 30 26 80 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61 encode_krb5_pa_pk_as_rep(encKeyPack): 81 08 6B 72 62 35 64 61 74 61 encode_krb5_auth_pack: 30 81 89 A0 39 30 37 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61 encode_krb5_kdc_dh_key_info: 30 25 A0 0B 03 09 00 6B 72 62 35 64 61 74 61 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A encode_krb5_reply_key_pack: 30 26 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 encode_krb5_sp80056a_other_info: 30 81 81 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A0 32 04 30 30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 32 04 30 30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 0A 04 08 6B 72 62 35 64 61 74 61 encode_krb5_pkinit_supp_pub_info: 30 1D A0 03 02 01 14 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0A 04 08 6B 72 62 35 64 61 74 61 krb5-1.22.1/src/tests/asn.1/utility.h0000664000175000017500000000467015051422640017075 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/utility.h */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __UTILITY_H__ #define __UTILITY_H__ #include "k5-int.h" /* Aborts on failure. ealloc returns zero-filled memory. */ void *ealloc(size_t size); char *estrdup(const char *str); void asn1_krb5_data_unparse(const krb5_data *code, char **s); /* modifies *s; effects Instantiates *s with a string representation of the series of hex octets in *code. (e.g. "02 02 00 7F") If code==NULL, the string rep is "". If code is empty (it contains no data or has length <= 0), the string rep is "". If *s is non-NULL, then its currently-allocated storage will be freed prior to the instantiation. Returns ENOMEM or the string rep cannot be created. */ void krb5_data_parse(krb5_data *d, const char *s); /* effects Parses character string *s into krb5_data *d. */ krb5_error_code krb5_data_hex_parse(krb5_data *d, const char *s); /* requires *s is the string representation of a sequence of hexadecimal octets. (e.g. "02 01 00") effects Parses *s into krb5_data *d. */ extern krb5int_access acc; extern void init_access(const char *progname); #endif krb5-1.22.1/src/tests/asn.1/krb5_encode_test.c0000664000175000017500000007442115051422640020605 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/krb5_encode_test.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "com_err.h" #include "utility.h" #include "ktest.h" #include "debug.h" extern int current_appl_type; krb5_context test_context; int error_count = 0; int do_trval = 0; int first_trval = 1; int trval2(FILE *, unsigned char *, int, int, int *); static void encoder_print_results(krb5_data *code, char *typestring, char *description) { char *code_string = NULL; int r, rlen; if (do_trval) { if (first_trval) first_trval = 0; else printf("\n"); printf("encode_krb5_%s%s:\n", typestring, description); r = trval2(stdout, (uint8_t *)code->data, code->length, 0, &rlen); printf("\n"); if (rlen < 0 || (unsigned int) rlen != code->length) { printf("Error: length mismatch: was %d, parsed %d\n", code->length, rlen); exit(1); } if (r != 0) { printf("Error: Return from trval2 is %d.\n", r); exit(1); } current_appl_type = -1; /* Reset type */ } else { asn1_krb5_data_unparse(code,&(code_string)); printf("encode_krb5_%s%s: %s\n", typestring, description, code_string); free(code_string); } ktest_destroy_data(&code); } static void PRS(int argc, char **argv) { extern char *optarg; int optchar; extern int print_types, print_krb5_types, print_id_and_len, print_constructed_length, print_skip_context, print_skip_tagnum, print_context_shortcut; while ((optchar = getopt(argc, argv, "tp:")) != -1) { switch(optchar) { case 't': do_trval = 1; break; case 'p': sample_principal_name = optarg; break; case '?': default: fprintf(stderr, "Usage: %s [-t] [-p principal]\n", argv[0]); exit(1); } } print_types = 1; print_krb5_types = 1; print_id_and_len = 0; print_constructed_length = 0; print_skip_context = 1; print_skip_tagnum = 1; print_context_shortcut = 1; } int main(int argc, char **argv) { krb5_data *code; krb5_error_code retval; PRS(argc, argv); retval = krb5_init_context(&test_context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } init_access(argv[0]); #define encode_run(value,typestring,description,encoder) \ retval = encoder(&(value),&(code)); \ if (retval) { \ com_err("krb5_encode_test", retval,"while encoding %s", typestring); \ exit(1); \ } \ encoder_print_results(code, typestring, description); /****************************************************************/ /* encode_krb5_authenticator */ { krb5_authenticator authent; ktest_make_sample_authenticator(&authent); encode_run(authent, "authenticator", "", encode_krb5_authenticator); ktest_destroy_checksum(&(authent.checksum)); ktest_destroy_keyblock(&(authent.subkey)); authent.seq_number = 0; ktest_empty_authorization_data(authent.authorization_data); encode_run(authent, "authenticator", "(optionals empty)", encode_krb5_authenticator); ktest_destroy_authorization_data(&(authent.authorization_data)); encode_run(authent, "authenticator", "(optionals NULL)", encode_krb5_authenticator); ktest_empty_authenticator(&authent); } /****************************************************************/ /* encode_krb5_ticket */ { krb5_ticket tkt; ktest_make_sample_ticket(&tkt); encode_run(tkt, "ticket", "", encode_krb5_ticket); ktest_empty_ticket(&tkt); } /****************************************************************/ /* encode_krb5_encryption_key */ { krb5_keyblock keyblk; ktest_make_sample_keyblock(&keyblk); current_appl_type = 1005; encode_run(keyblk, "keyblock", "", encode_krb5_encryption_key); ktest_empty_keyblock(&keyblk); } /****************************************************************/ /* encode_krb5_enc_tkt_part */ { krb5_ticket tkt; memset(&tkt, 0, sizeof(krb5_ticket)); tkt.enc_part2 = ealloc(sizeof(krb5_enc_tkt_part)); ktest_make_sample_enc_tkt_part(tkt.enc_part2); encode_run(*tkt.enc_part2, "enc_tkt_part", "", encode_krb5_enc_tkt_part); tkt.enc_part2->times.starttime = 0; tkt.enc_part2->times.renew_till = 0; ktest_destroy_address(&(tkt.enc_part2->caddrs[1])); ktest_destroy_address(&(tkt.enc_part2->caddrs[0])); ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[1])); ktest_destroy_authdata(&(tkt.enc_part2->authorization_data[0])); /* ISODE version fails on the empty caddrs field */ ktest_destroy_addresses(&(tkt.enc_part2->caddrs)); ktest_destroy_authorization_data(&(tkt.enc_part2->authorization_data)); encode_run(*tkt.enc_part2, "enc_tkt_part", "(optionals NULL)", encode_krb5_enc_tkt_part); ktest_empty_ticket(&tkt); } /****************************************************************/ /* encode_krb5_enc_kdc_rep_part */ { krb5_kdc_rep kdcr; memset(&kdcr, 0, sizeof(kdcr)); kdcr.enc_part2 = ealloc(sizeof(krb5_enc_kdc_rep_part)); ktest_make_sample_enc_kdc_rep_part(kdcr.enc_part2); encode_run(*kdcr.enc_part2, "enc_kdc_rep_part", "", encode_krb5_enc_kdc_rep_part); kdcr.enc_part2->key_exp = 0; kdcr.enc_part2->times.starttime = 0; kdcr.enc_part2->flags &= ~TKT_FLG_RENEWABLE; ktest_destroy_addresses(&(kdcr.enc_part2->caddrs)); encode_run(*kdcr.enc_part2, "enc_kdc_rep_part", "(optionals NULL)", encode_krb5_enc_kdc_rep_part); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_as_rep */ { krb5_kdc_rep kdcr; ktest_make_sample_kdc_rep(&kdcr); /* kdcr.msg_type = KRB5_TGS_REP; test(encode_krb5_as_rep(&kdcr,&code) == KRB5_BADMSGTYPE, "encode_krb5_as_rep type check\n"); ktest_destroy_data(&code);*/ kdcr.msg_type = KRB5_AS_REP; encode_run(kdcr, "as_rep", "", encode_krb5_as_rep); ktest_destroy_pa_data_array(&(kdcr.padata)); encode_run(kdcr, "as_rep", "(optionals NULL)", encode_krb5_as_rep); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_tgs_rep */ { krb5_kdc_rep kdcr; ktest_make_sample_kdc_rep(&kdcr); /* kdcr.msg_type = KRB5_AS_REP; test(encode_krb5_tgs_rep(&kdcr,&code) == KRB5_BADMSGTYPE, "encode_krb5_tgs_rep type check\n");*/ kdcr.msg_type = KRB5_TGS_REP; encode_run(kdcr, "tgs_rep", "", encode_krb5_tgs_rep); ktest_destroy_pa_data_array(&(kdcr.padata)); encode_run(kdcr, "tgs_rep", "(optionals NULL)", encode_krb5_tgs_rep); ktest_empty_kdc_rep(&kdcr); } /****************************************************************/ /* encode_krb5_ap_req */ { krb5_ap_req apreq; ktest_make_sample_ap_req(&apreq); encode_run(apreq, "ap_req", "", encode_krb5_ap_req); ktest_empty_ap_req(&apreq); } /****************************************************************/ /* encode_krb5_ap_rep */ { krb5_ap_rep aprep; ktest_make_sample_ap_rep(&aprep); encode_run(aprep, "ap_rep", "", encode_krb5_ap_rep); ktest_empty_ap_rep(&aprep); } /****************************************************************/ /* encode_krb5_ap_rep_enc_part */ { krb5_ap_rep_enc_part apenc; ktest_make_sample_ap_rep_enc_part(&apenc); encode_run(apenc, "ap_rep_enc_part", "", encode_krb5_ap_rep_enc_part); ktest_destroy_keyblock(&(apenc.subkey)); apenc.seq_number = 0; encode_run(apenc, "ap_rep_enc_part", "(optionals NULL)", encode_krb5_ap_rep_enc_part); ktest_empty_ap_rep_enc_part(&apenc); } /****************************************************************/ /* encode_krb5_as_req */ { krb5_kdc_req asreq; ktest_make_sample_kdc_req(&asreq); asreq.msg_type = KRB5_AS_REQ; asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; encode_run(asreq, "as_req", "", encode_krb5_as_req); ktest_destroy_pa_data_array(&(asreq.padata)); ktest_destroy_principal(&(asreq.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(asreq.server)); #endif asreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; asreq.from = 0; asreq.rtime = 0; ktest_destroy_addresses(&(asreq.addresses)); ktest_destroy_enc_data(&(asreq.authorization_data)); encode_run(asreq, "as_req", "(optionals NULL except second_ticket)", encode_krb5_as_req); ktest_destroy_sequence_of_ticket(&(asreq.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(asreq.server)); #endif asreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; encode_run(asreq, "as_req", "(optionals NULL except server)", encode_krb5_as_req); ktest_empty_kdc_req(&asreq); } /****************************************************************/ /* encode_krb5_tgs_req */ { krb5_kdc_req tgsreq; ktest_make_sample_kdc_req(&tgsreq); tgsreq.msg_type = KRB5_TGS_REQ; tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; encode_run(tgsreq, "tgs_req", "", encode_krb5_tgs_req); ktest_destroy_pa_data_array(&(tgsreq.padata)); ktest_destroy_principal(&(tgsreq.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(tgsreq.server)); #endif tgsreq.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; tgsreq.from = 0; tgsreq.rtime = 0; ktest_destroy_addresses(&(tgsreq.addresses)); ktest_destroy_enc_data(&(tgsreq.authorization_data)); encode_run(tgsreq, "tgs_req", "(optionals NULL except second_ticket)", encode_krb5_tgs_req); ktest_destroy_sequence_of_ticket(&(tgsreq.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(tgsreq.server)); #endif tgsreq.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; encode_run(tgsreq, "tgs_req", "(optionals NULL except server)", encode_krb5_tgs_req); ktest_empty_kdc_req(&tgsreq); } /****************************************************************/ /* encode_krb5_kdc_req_body */ { krb5_kdc_req kdcrb; memset(&kdcrb, 0, sizeof(kdcrb)); ktest_make_sample_kdc_req_body(&kdcrb); kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; current_appl_type = 1007; /* Force interpretation as kdc-req-body */ encode_run(kdcrb, "kdc_req_body", "", encode_krb5_kdc_req_body); ktest_destroy_principal(&(kdcrb.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(kdcrb.server)); #endif kdcrb.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; kdcrb.from = 0; kdcrb.rtime = 0; ktest_destroy_addresses(&(kdcrb.addresses)); ktest_destroy_enc_data(&(kdcrb.authorization_data)); current_appl_type = 1007; /* Force interpretation as kdc-req-body */ encode_run(kdcrb, "kdc_req_body", "(optionals NULL except second_ticket)", encode_krb5_kdc_req_body); ktest_destroy_sequence_of_ticket(&(kdcrb.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(kdcrb.server)); #endif kdcrb.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; current_appl_type = 1007; /* Force interpretation as kdc-req-body */ encode_run(kdcrb, "kdc_req_body", "(optionals NULL except server)", encode_krb5_kdc_req_body); ktest_empty_kdc_req(&kdcrb); } /****************************************************************/ /* encode_krb5_safe */ { krb5_safe s; ktest_make_sample_safe(&s); encode_run(s, "safe", "", encode_krb5_safe); s.timestamp = 0; /* s.usec should be opted out by the timestamp */ s.seq_number = 0; ktest_destroy_address(&(s.r_address)); encode_run(s, "safe", "(optionals NULL)", encode_krb5_safe); ktest_empty_safe(&s); } /****************************************************************/ /* encode_krb5_priv */ { krb5_priv p; ktest_make_sample_priv(&p); encode_run(p, "priv", "", encode_krb5_priv); ktest_empty_priv(&p); } /****************************************************************/ /* encode_krb5_enc_priv_part */ { krb5_priv_enc_part ep; ktest_make_sample_priv_enc_part(&ep); encode_run(ep, "enc_priv_part", "", encode_krb5_enc_priv_part); ep.timestamp = 0; /* ep.usec should be opted out along with timestamp */ ep.seq_number = 0; ktest_destroy_address(&(ep.r_address)); encode_run(ep, "enc_priv_part", "(optionals NULL)", encode_krb5_enc_priv_part); ktest_empty_priv_enc_part(&ep); } /****************************************************************/ /* encode_krb5_cred */ { krb5_cred c; ktest_make_sample_cred(&c); encode_run(c, "cred", "", encode_krb5_cred); ktest_empty_cred(&c); } /****************************************************************/ /* encode_krb5_enc_cred_part */ { krb5_cred_enc_part cep; ktest_make_sample_cred_enc_part(&cep); encode_run(cep, "enc_cred_part", "", encode_krb5_enc_cred_part); ktest_destroy_principal(&(cep.ticket_info[0]->client)); ktest_destroy_principal(&(cep.ticket_info[0]->server)); cep.ticket_info[0]->flags = 0; cep.ticket_info[0]->times.authtime = 0; cep.ticket_info[0]->times.starttime = 0; cep.ticket_info[0]->times.endtime = 0; cep.ticket_info[0]->times.renew_till = 0; ktest_destroy_addresses(&(cep.ticket_info[0]->caddrs)); cep.nonce = 0; cep.timestamp = 0; ktest_destroy_address(&(cep.s_address)); ktest_destroy_address(&(cep.r_address)); encode_run(cep, "enc_cred_part", "(optionals NULL)", encode_krb5_enc_cred_part); ktest_empty_cred_enc_part(&cep); } /****************************************************************/ /* encode_krb5_error */ { krb5_error kerr; ktest_make_sample_error(&kerr); encode_run(kerr, "error", "", encode_krb5_error); kerr.ctime = 0; ktest_destroy_principal(&(kerr.client)); ktest_empty_data(&(kerr.text)); ktest_empty_data(&(kerr.e_data)); encode_run(kerr, "error", "(optionals NULL)", encode_krb5_error); ktest_empty_error(&kerr); } /****************************************************************/ /* encode_krb5_authdata */ { krb5_authdata **ad; ktest_make_sample_authorization_data(&ad); retval = encode_krb5_authdata(ad,&(code)); if (retval) { com_err("encoding authorization_data",retval,""); exit(1); } current_appl_type = 1004; /* Force type to be authdata */ encoder_print_results(code, "authorization_data", ""); ktest_destroy_authorization_data(&ad); } /****************************************************************/ /* encode_padata_sequence and encode_krb5_typed_data */ { krb5_pa_data **pa; ktest_make_sample_pa_data_array(&pa); encode_run(*pa, "padata_sequence", "", encode_krb5_padata_sequence); encode_run(*pa, "typed_data", "", encode_krb5_typed_data); ktest_destroy_pa_data_array(&pa); ktest_make_sample_empty_pa_data_array(&pa); encode_run(*pa, "padata_sequence", "(empty)", encode_krb5_padata_sequence); ktest_destroy_pa_data_array(&pa); } /****************************************************************/ /* encode_etype_info */ { krb5_etype_info_entry **info; ktest_make_sample_etype_info(&info); encode_run(*info, "etype_info", "", encode_krb5_etype_info); ktest_destroy_etype_info_entry(info[2]); info[2] = 0; ktest_destroy_etype_info_entry(info[1]); info[1] = 0; encode_run(*info, "etype_info", "(only 1)", encode_krb5_etype_info); ktest_destroy_etype_info_entry(info[0]); info[0] = 0; encode_run(*info, "etype_info", "(no info)", encode_krb5_etype_info); ktest_destroy_etype_info(info); } /* encode_etype_info2 */ { krb5_etype_info_entry **info; ktest_make_sample_etype_info2(&info); encode_run(*info, "etype_info2", "", encode_krb5_etype_info2); ktest_destroy_etype_info_entry(info[2]); info[2] = 0; ktest_destroy_etype_info_entry(info[1]); info[1] = 0; encode_run(*info, "etype_info2", "(only 1)", encode_krb5_etype_info2); /* etype_info2 sequences aren't allowed to be empty. */ ktest_destroy_etype_info(info); } /****************************************************************/ /* encode_pa_enc_ts */ { krb5_pa_enc_ts pa_enc; ktest_make_sample_pa_enc_ts(&pa_enc); encode_run(pa_enc, "pa_enc_ts", "", encode_krb5_pa_enc_ts); pa_enc.pausec = 0; encode_run(pa_enc, "pa_enc_ts (no usec)", "", encode_krb5_pa_enc_ts); } /****************************************************************/ /* encode_enc_data */ { krb5_enc_data enc_data; ktest_make_sample_enc_data(&enc_data); current_appl_type = 1001; encode_run(enc_data, "enc_data", "", encode_krb5_enc_data); enc_data.kvno = 0xFF000000; current_appl_type = 1001; encode_run(enc_data, "enc_data", "(MSB-set kvno)", encode_krb5_enc_data); enc_data.kvno = 0xFFFFFFFF; current_appl_type = 1001; encode_run(enc_data, "enc_data", "(kvno=-1)", encode_krb5_enc_data); ktest_destroy_enc_data(&enc_data); } /****************************************************************/ /* encode_krb5_sam_challenge_2 */ { krb5_sam_challenge_2 sam_ch2; ktest_make_sample_sam_challenge_2(&sam_ch2); encode_run(sam_ch2, "sam_challenge_2", "", encode_krb5_sam_challenge_2); ktest_empty_sam_challenge_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_sam_challenge_2_body */ { krb5_sam_challenge_2_body body; ktest_make_sample_sam_challenge_2_body(&body); encode_run(body, "sam_challenge_2_body", "", encode_krb5_sam_challenge_2_body); ktest_empty_sam_challenge_2_body(&body); } /****************************************************************/ /* encode_krb5_sam_response_2 */ { krb5_sam_response_2 sam_ch2; ktest_make_sample_sam_response_2(&sam_ch2); encode_run(sam_ch2, "sam_response_2", "", encode_krb5_sam_response_2); ktest_empty_sam_response_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_sam_response_enc_2 */ { krb5_enc_sam_response_enc_2 sam_ch2; ktest_make_sample_enc_sam_response_enc_2(&sam_ch2); encode_run(sam_ch2, "enc_sam_response_enc_2", "", encode_krb5_enc_sam_response_enc_2); ktest_empty_enc_sam_response_enc_2(&sam_ch2); } /****************************************************************/ /* encode_krb5_pa_for_user */ { krb5_pa_for_user s4u; ktest_make_sample_pa_for_user(&s4u); encode_run(s4u, "pa_for_user", "", encode_krb5_pa_for_user); ktest_empty_pa_for_user(&s4u); } /****************************************************************/ /* encode_krb5_pa_s4u_x509_user */ { krb5_pa_s4u_x509_user s4u; ktest_make_sample_pa_s4u_x509_user(&s4u); encode_run(s4u, "pa_s4u_x509_user", "", encode_krb5_pa_s4u_x509_user); ktest_empty_pa_s4u_x509_user(&s4u); } /****************************************************************/ /* encode_krb5_ad_kdcissued */ { krb5_ad_kdcissued kdci; ktest_make_sample_ad_kdcissued(&kdci); encode_run(kdci, "ad_kdcissued", "", encode_krb5_ad_kdcissued); ktest_empty_ad_kdcissued(&kdci); } /****************************************************************/ /* encode_krb5_iakerb_header */ { krb5_iakerb_header ih; ktest_make_sample_iakerb_header(&ih); encode_run(ih, "iakerb_header", "", encode_krb5_iakerb_header); ktest_empty_iakerb_header(&ih); } /****************************************************************/ /* encode_krb5_iakerb_finished */ { krb5_iakerb_finished ih; ktest_make_sample_iakerb_finished(&ih); encode_run(ih, "iakerb_finished", "", encode_krb5_iakerb_finished); ktest_empty_iakerb_finished(&ih); } /****************************************************************/ /* encode_krb5_fast_response */ { krb5_fast_response fr; ktest_make_sample_fast_response(&fr); encode_run(fr, "fast_response", "", encode_krb5_fast_response); ktest_empty_fast_response(&fr); } /****************************************************************/ /* encode_krb5_pa_fx_fast_reply */ { krb5_enc_data enc_data; ktest_make_sample_enc_data(&enc_data); encode_run(enc_data, "pa_fx_fast_reply", "", encode_krb5_pa_fx_fast_reply); ktest_destroy_enc_data(&enc_data); } /****************************************************************/ /* encode_krb5_otp_tokeninfo */ { krb5_otp_tokeninfo ti; ktest_make_minimal_otp_tokeninfo(&ti); encode_run(ti, "otp_tokeninfo", "(optionals NULL)", encode_krb5_otp_tokeninfo); ktest_empty_otp_tokeninfo(&ti); ktest_make_maximal_otp_tokeninfo(&ti); encode_run(ti, "otp_tokeninfo", "", encode_krb5_otp_tokeninfo); ktest_empty_otp_tokeninfo(&ti); } /****************************************************************/ /* encode_krb5_pa_otp_challenge */ { krb5_pa_otp_challenge ch; ktest_make_minimal_pa_otp_challenge(&ch); encode_run(ch, "pa_otp_challenge", "(optionals NULL)", encode_krb5_pa_otp_challenge); ktest_empty_pa_otp_challenge(&ch); ktest_make_maximal_pa_otp_challenge(&ch); encode_run(ch, "pa_otp_challenge", "", encode_krb5_pa_otp_challenge); ktest_empty_pa_otp_challenge(&ch); } /****************************************************************/ /* encode_krb5_pa_otp_req */ { krb5_pa_otp_req req; ktest_make_minimal_pa_otp_req(&req); encode_run(req, "pa_otp_req", "(optionals NULL)", encode_krb5_pa_otp_req); ktest_empty_pa_otp_req(&req); ktest_make_maximal_pa_otp_req(&req); encode_run(req, "pa_otp_req", "", encode_krb5_pa_otp_req); ktest_empty_pa_otp_req(&req); } /****************************************************************/ /* encode_krb5_pa_otp_enc_request */ { krb5_data d; ktest_make_sample_data(&d); encode_run(d, "pa_otp_enc_req", "", encode_krb5_pa_otp_enc_req); ktest_empty_data(&d); } /****************************************************************/ /* encode_krb5_kkdcp_message */ { krb5_kkdcp_message info; ktest_make_sample_kkdcp_message(&info); encode_run(info, "kkdcp_message", "", encode_krb5_kkdcp_message); ktest_empty_kkdcp_message(&info); } /* encode_krb5_cammac */ { krb5_cammac req; ktest_make_minimal_cammac(&req); encode_run(req, "cammac", "(optionals NULL)", encode_krb5_cammac); ktest_empty_cammac(&req); ktest_make_maximal_cammac(&req); encode_run(req, "cammac", "", encode_krb5_cammac); ktest_empty_cammac(&req); } /****************************************************************/ /* encode_krb5_secure_cookie */ { krb5_secure_cookie cookie; ktest_make_sample_secure_cookie(&cookie); encode_run(cookie, "secure_cookie", "", encode_krb5_secure_cookie); ktest_empty_secure_cookie(&cookie); } /****************************************************************/ /* encode_krb5_spake_factor */ { krb5_spake_factor factor; ktest_make_minimal_spake_factor(&factor); encode_run(factor, "spake_factor", "(optionals NULL)", encode_krb5_spake_factor); ktest_empty_spake_factor(&factor); ktest_make_maximal_spake_factor(&factor); encode_run(factor, "spake_factor", "", encode_krb5_spake_factor); ktest_empty_spake_factor(&factor); } /****************************************************************/ /* encode_krb5_pa_spake */ { krb5_pa_spake pa_spake; ktest_make_support_pa_spake(&pa_spake); encode_run(pa_spake, "pa_spake", "(support)", encode_krb5_pa_spake); ktest_empty_pa_spake(&pa_spake); ktest_make_challenge_pa_spake(&pa_spake); encode_run(pa_spake, "pa_spake", "(challenge)", encode_krb5_pa_spake); ktest_empty_pa_spake(&pa_spake); ktest_make_response_pa_spake(&pa_spake); encode_run(pa_spake, "pa_spake", "(response)", encode_krb5_pa_spake); ktest_empty_pa_spake(&pa_spake); ktest_make_encdata_pa_spake(&pa_spake); encode_run(pa_spake, "pa_spake", "(encdata)", encode_krb5_pa_spake); ktest_empty_pa_spake(&pa_spake); } #ifndef DISABLE_PKINIT /****************************************************************/ /* encode_krb5_pa_pk_as_req */ { krb5_pa_pk_as_req req; ktest_make_sample_pa_pk_as_req(&req); encode_run(req, "pa_pk_as_req", "", acc.encode_krb5_pa_pk_as_req); ktest_empty_pa_pk_as_req(&req); } /****************************************************************/ /* encode_krb5_pa_pk_as_rep */ { krb5_pa_pk_as_rep rep; ktest_make_sample_pa_pk_as_rep_dhInfo(&rep); encode_run(rep, "pa_pk_as_rep", "(dhInfo)", acc.encode_krb5_pa_pk_as_rep); ktest_empty_pa_pk_as_rep(&rep); ktest_make_sample_pa_pk_as_rep_encKeyPack(&rep); encode_run(rep, "pa_pk_as_rep", "(encKeyPack)", acc.encode_krb5_pa_pk_as_rep); ktest_empty_pa_pk_as_rep(&rep); } /****************************************************************/ /* encode_krb5_auth_pack */ { krb5_auth_pack pack; ktest_make_sample_auth_pack(&pack); encode_run(pack, "auth_pack", "", acc.encode_krb5_auth_pack); ktest_empty_auth_pack(&pack); } /****************************************************************/ /* encode_krb5_kdc_dh_key_info */ { krb5_kdc_dh_key_info ki; ktest_make_sample_kdc_dh_key_info(&ki); encode_run(ki, "kdc_dh_key_info", "", acc.encode_krb5_kdc_dh_key_info); ktest_empty_kdc_dh_key_info(&ki); } /****************************************************************/ /* encode_krb5_reply_key_pack */ { krb5_reply_key_pack pack; ktest_make_sample_reply_key_pack(&pack); encode_run(pack, "reply_key_pack", "", acc.encode_krb5_reply_key_pack); ktest_empty_reply_key_pack(&pack); } /****************************************************************/ /* encode_krb5_sp80056a_other_info */ { krb5_sp80056a_other_info info; ktest_make_sample_sp80056a_other_info(&info); encode_run(info, "sp80056a_other_info", "", encode_krb5_sp80056a_other_info); ktest_empty_sp80056a_other_info(&info); } /****************************************************************/ /* encode_krb5_pkinit_supp_pub_info */ { krb5_pkinit_supp_pub_info info; ktest_make_sample_pkinit_supp_pub_info(&info); encode_run(info, "pkinit_supp_pub_info", "", encode_krb5_pkinit_supp_pub_info); ktest_empty_pkinit_supp_pub_info(&info); } #endif /* not DISABLE_PKINIT */ #ifdef ENABLE_LDAP { ldap_seqof_key_data skd; ktest_make_sample_ldap_seqof_key_data(&skd); encode_run(skd, "ldap_seqof_key_data", "", acc.asn1_ldap_encode_sequence_of_keys); ktest_empty_ldap_seqof_key_data(&skd); } #endif krb5_free_context(test_context); exit(error_count); return(error_count); } krb5-1.22.1/src/tests/asn.1/ktest_equal.c0000664000175000017500000007576415051422640017722 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/ktest_equal.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include "ktest_equal.h" #define FALSE 0 #define TRUE 1 #define struct_equal(field,comparator) \ comparator(&(ref->field),&(var->field)) #define ptr_equal(field,comparator) \ comparator(ref->field,var->field) #define scalar_equal(field) \ ((ref->field) == (var->field)) #define len_equal(length,field,comparator) \ ((ref->length == var->length) && \ comparator(ref->length,ref->field,var->field)) int ktest_equal_authenticator(krb5_authenticator *ref, krb5_authenticator *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(checksum,ktest_equal_checksum); p = p && scalar_equal(cusec); p = p && scalar_equal(ctime); p = p && ptr_equal(subkey,ktest_equal_keyblock); p = p && scalar_equal(seq_number); p = p && ptr_equal(authorization_data,ktest_equal_authorization_data); return p; } int ktest_equal_principal_data(krb5_principal_data *ref, krb5_principal_data *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(struct_equal(realm,ktest_equal_data) && len_equal(length,data,ktest_equal_array_of_data) && scalar_equal(type)); } int ktest_equal_authdata(krb5_authdata *ref, krb5_authdata *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(scalar_equal(ad_type) && len_equal(length,contents,ktest_equal_array_of_octet)); } int ktest_equal_checksum(krb5_checksum *ref, krb5_checksum *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(scalar_equal(checksum_type) && len_equal(length,contents,ktest_equal_array_of_octet)); } int ktest_equal_keyblock(krb5_keyblock *ref, krb5_keyblock *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(scalar_equal(enctype) && len_equal(length,contents,ktest_equal_array_of_octet)); } int ktest_equal_data(krb5_data *ref, krb5_data *var) { if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; return(len_equal(length,data,ktest_equal_array_of_char)); } int ktest_equal_ticket(krb5_ticket *ref, krb5_ticket *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(server,ktest_equal_principal_data); p = p && struct_equal(enc_part,ktest_equal_enc_data); /* enc_part2 is irrelevant, as far as the ASN.1 code is concerned */ return p; } int ktest_equal_enc_data(krb5_enc_data *ref, krb5_enc_data *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(enctype); p = p && scalar_equal(kvno); p = p && struct_equal(ciphertext,ktest_equal_data); return p; } int ktest_equal_encryption_key(krb5_keyblock *ref, krb5_keyblock *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(enctype); p = p && len_equal(length,contents,ktest_equal_array_of_octet); return p; } int ktest_equal_enc_tkt_part(krb5_enc_tkt_part *ref, krb5_enc_tkt_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(flags); p = p && ptr_equal(session,ktest_equal_encryption_key); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && struct_equal(transited,ktest_equal_transited); p = p && struct_equal(times,ktest_equal_ticket_times); p = p && ptr_equal(caddrs,ktest_equal_addresses); p = p && ptr_equal(authorization_data,ktest_equal_authorization_data); return p; } int ktest_equal_transited(krb5_transited *ref, krb5_transited *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(tr_type); p = p && struct_equal(tr_contents,ktest_equal_data); return p; } int ktest_equal_ticket_times(krb5_ticket_times *ref, krb5_ticket_times *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(authtime); p = p && scalar_equal(starttime); p = p && scalar_equal(endtime); p = p && scalar_equal(renew_till); return p; } int ktest_equal_address(krb5_address *ref, krb5_address *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(addrtype); p = p && len_equal(length,contents,ktest_equal_array_of_octet); return p; } int ktest_equal_enc_kdc_rep_part(krb5_enc_kdc_rep_part *ref, krb5_enc_kdc_rep_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(session,ktest_equal_keyblock); p = p && ptr_equal(last_req,ktest_equal_last_req); p = p && scalar_equal(nonce); p = p && scalar_equal(key_exp); p = p && scalar_equal(flags); p = p && struct_equal(times,ktest_equal_ticket_times); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && ptr_equal(caddrs,ktest_equal_addresses); return p; } int ktest_equal_priv(krb5_priv *ref, krb5_priv *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(enc_part,ktest_equal_enc_data); return p; } int ktest_equal_cred(krb5_cred *ref, krb5_cred *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(tickets,ktest_equal_sequence_of_ticket); p = p && struct_equal(enc_part,ktest_equal_enc_data); return p; } int ktest_equal_error(krb5_error *ref, krb5_error *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(ctime); p = p && scalar_equal(cusec); p = p && scalar_equal(susec); p = p && scalar_equal(stime); p = p && scalar_equal(error); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && struct_equal(text,ktest_equal_data); p = p && struct_equal(e_data,ktest_equal_data); return p; } int ktest_equal_ap_req(krb5_ap_req *ref, krb5_ap_req *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(ap_options); p = p && ptr_equal(ticket,ktest_equal_ticket); p = p && struct_equal(authenticator,ktest_equal_enc_data); return p; } int ktest_equal_ap_rep(krb5_ap_rep *ref, krb5_ap_rep *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(enc_part,ktest_equal_enc_data); return p; } int ktest_equal_ap_rep_enc_part(krb5_ap_rep_enc_part *ref, krb5_ap_rep_enc_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(ctime); p = p && scalar_equal(cusec); p = p && ptr_equal(subkey,ktest_equal_encryption_key); p = p && scalar_equal(seq_number); return p; } int ktest_equal_safe(krb5_safe *ref, krb5_safe *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(user_data,ktest_equal_data); p = p && scalar_equal(timestamp); p = p && scalar_equal(usec); p = p && scalar_equal(seq_number); p = p && ptr_equal(s_address,ktest_equal_address); p = p && ptr_equal(r_address,ktest_equal_address); p = p && ptr_equal(checksum,ktest_equal_checksum); return p; } int ktest_equal_enc_cred_part(krb5_cred_enc_part *ref, krb5_cred_enc_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(nonce); p = p && scalar_equal(timestamp); p = p && scalar_equal(usec); p = p && ptr_equal(s_address,ktest_equal_address); p = p && ptr_equal(r_address,ktest_equal_address); p = p && ptr_equal(ticket_info,ktest_equal_sequence_of_cred_info); return p; } int ktest_equal_enc_priv_part(krb5_priv_enc_part *ref, krb5_priv_enc_part *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(user_data,ktest_equal_data); p = p && scalar_equal(timestamp); p = p && scalar_equal(usec); p = p && scalar_equal(seq_number); p = p && ptr_equal(s_address,ktest_equal_address); p = p && ptr_equal(r_address,ktest_equal_address); return p; } int ktest_equal_as_rep(krb5_kdc_rep *ref, krb5_kdc_rep *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(msg_type); p = p && ptr_equal(padata,ktest_equal_sequence_of_pa_data); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(ticket,ktest_equal_ticket); p = p && struct_equal(enc_part,ktest_equal_enc_data); p = p && ptr_equal(enc_part2,ktest_equal_enc_kdc_rep_part); return p; } int ktest_equal_tgs_rep(krb5_kdc_rep *ref, krb5_kdc_rep *var) { return ktest_equal_as_rep(ref,var); } int ktest_equal_as_req(krb5_kdc_req *ref, krb5_kdc_req *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(msg_type); p = p && ptr_equal(padata,ktest_equal_sequence_of_pa_data); p = p && scalar_equal(kdc_options); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && scalar_equal(from); p = p && scalar_equal(till); p = p && scalar_equal(rtime); p = p && scalar_equal(nonce); p = p && len_equal(nktypes,ktype,ktest_equal_array_of_enctype); p = p && ptr_equal(addresses,ktest_equal_addresses); p = p && struct_equal(authorization_data,ktest_equal_enc_data); /* This field isn't actually in the ASN.1 encoding. */ /* p = p && ptr_equal(unenc_authdata,ktest_equal_authorization_data); */ return p; } int ktest_equal_tgs_req(krb5_kdc_req *ref, krb5_kdc_req *var) { return ktest_equal_as_req(ref,var); } int ktest_equal_kdc_req_body(krb5_kdc_req *ref, krb5_kdc_req *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(kdc_options); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && scalar_equal(from); p = p && scalar_equal(till); p = p && scalar_equal(rtime); p = p && scalar_equal(nonce); p = p && len_equal(nktypes,ktype,ktest_equal_array_of_enctype); p = p && ptr_equal(addresses,ktest_equal_addresses); p = p && struct_equal(authorization_data,ktest_equal_enc_data); /* This isn't part of the ASN.1 encoding. */ /* p = p && ptr_equal(unenc_authdata,ktest_equal_authorization_data); */ return p; } int ktest_equal_last_req_entry(krb5_last_req_entry *ref, krb5_last_req_entry *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(lr_type); p = p && scalar_equal(value); return p; } int ktest_equal_pa_data(krb5_pa_data *ref, krb5_pa_data *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(pa_type); p = p && len_equal(length,contents,ktest_equal_array_of_octet); return p; } int ktest_equal_cred_info(krb5_cred_info *ref, krb5_cred_info *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(session,ktest_equal_keyblock); p = p && ptr_equal(client,ktest_equal_principal_data); p = p && ptr_equal(server,ktest_equal_principal_data); p = p && scalar_equal(flags); p = p && struct_equal(times,ktest_equal_ticket_times); p = p && ptr_equal(caddrs,ktest_equal_addresses); return p; } int ktest_equal_krb5_etype_info_entry(krb5_etype_info_entry *ref, krb5_etype_info_entry *var) { if (ref->etype != var->etype) return FALSE; if (ref->length != var->length) return FALSE; if (ref->length > 0 && ref->length != KRB5_ETYPE_NO_SALT) if (memcmp(ref->salt, var->salt, ref->length) != 0) return FALSE; return TRUE; } int ktest_equal_krb5_pa_enc_ts(krb5_pa_enc_ts *ref, krb5_pa_enc_ts *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(patimestamp); p = p && scalar_equal(pausec); return p; } #define equal_str(f) struct_equal(f,ktest_equal_data) int ktest_equal_sam_challenge_2_body(krb5_sam_challenge_2_body *ref, krb5_sam_challenge_2_body *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(sam_type); p = p && scalar_equal(sam_flags); p = p && equal_str(sam_type_name); p = p && equal_str(sam_track_id); p = p && equal_str(sam_challenge_label); p = p && equal_str(sam_challenge); p = p && equal_str(sam_response_prompt); p = p && equal_str(sam_pk_for_sad); p = p && scalar_equal(sam_nonce); p = p && scalar_equal(sam_etype); return p; } int ktest_equal_sam_challenge_2(krb5_sam_challenge_2 *ref, krb5_sam_challenge_2 *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(sam_challenge_2_body); p = p && ptr_equal(sam_cksum,ktest_equal_sequence_of_checksum); return p; } int ktest_equal_pa_for_user(krb5_pa_for_user *ref, krb5_pa_for_user *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(user, ktest_equal_principal_data); p = p && struct_equal(cksum, ktest_equal_checksum); p = p && equal_str(auth_package); return p; } int ktest_equal_pa_s4u_x509_user(krb5_pa_s4u_x509_user *ref, krb5_pa_s4u_x509_user *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(user_id.nonce); p = p && ptr_equal(user_id.user,ktest_equal_principal_data); p = p && struct_equal(user_id.subject_cert,ktest_equal_data); p = p && scalar_equal(user_id.options); p = p && struct_equal(cksum,ktest_equal_checksum); return p; } int ktest_equal_ad_kdcissued(krb5_ad_kdcissued *ref, krb5_ad_kdcissued *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(ad_checksum,ktest_equal_checksum); p = p && ptr_equal(i_principal,ktest_equal_principal_data); p = p && ptr_equal(elements,ktest_equal_authorization_data); return p; } int ktest_equal_iakerb_header(krb5_iakerb_header *ref, krb5_iakerb_header *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(target_realm,ktest_equal_data); p = p && ptr_equal(cookie,ktest_equal_data); return p; } int ktest_equal_iakerb_finished(krb5_iakerb_finished *ref, krb5_iakerb_finished *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(checksum,ktest_equal_checksum); return p; } static int ktest_equal_fast_finished(krb5_fast_finished *ref, krb5_fast_finished *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(timestamp); p = p && scalar_equal(usec); p = p && ptr_equal(client, ktest_equal_principal_data); p = p && struct_equal(ticket_checksum, ktest_equal_checksum); return p; } int ktest_equal_fast_response(krb5_fast_response *ref, krb5_fast_response *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(padata, ktest_equal_sequence_of_pa_data); p = p && ptr_equal(strengthen_key, ktest_equal_keyblock); p = p && ptr_equal(finished, ktest_equal_fast_finished); p = p && scalar_equal(nonce); return p; } static int ktest_equal_algorithm_identifier(krb5_algorithm_identifier *ref, krb5_algorithm_identifier *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(algorithm); p = p && equal_str(parameters); return p; } int ktest_equal_otp_tokeninfo(krb5_otp_tokeninfo *ref, krb5_otp_tokeninfo *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(flags); p = p && equal_str(vendor); p = p && equal_str(challenge); p = p && scalar_equal(length); p = p && scalar_equal(format); p = p && equal_str(token_id); p = p && equal_str(alg_id); p = p && ptr_equal(supported_hash_alg, ktest_equal_sequence_of_algorithm_identifier); p = p && scalar_equal(iteration_count); return p; } int ktest_equal_pa_otp_challenge(krb5_pa_otp_challenge *ref, krb5_pa_otp_challenge *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(nonce); p = p && equal_str(service); p = p && ptr_equal(tokeninfo, ktest_equal_sequence_of_otp_tokeninfo); p = p && equal_str(salt); p = p && equal_str(s2kparams); return p; } int ktest_equal_pa_otp_req(krb5_pa_otp_req *ref, krb5_pa_otp_req *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(flags); p = p && equal_str(nonce); p = p && struct_equal(enc_data, ktest_equal_enc_data); p = p && ptr_equal(hash_alg, ktest_equal_algorithm_identifier); p = p && scalar_equal(iteration_count); p = p && equal_str(otp_value); p = p && equal_str(pin); p = p && equal_str(challenge); p = p && scalar_equal(time); p = p && equal_str(counter); p = p && scalar_equal(format); p = p && equal_str(token_id); p = p && equal_str(alg_id); p = p && equal_str(vendor); return p; } #ifdef ENABLE_LDAP static int equal_key_data(krb5_key_data *ref, krb5_key_data *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(key_data_type[0]); p = p && scalar_equal(key_data_type[1]); p = p && len_equal(key_data_length[0],key_data_contents[0], ktest_equal_array_of_octet); p = p && len_equal(key_data_length[1],key_data_contents[1], ktest_equal_array_of_octet); return p; } static int equal_key_data_array(int n, krb5_key_data *ref, krb5_key_data *val) { int i, p = TRUE; for (i = 0; i < n; i++) { p = p && equal_key_data(ref+i, val+i); } return p; } int ktest_equal_ldap_sequence_of_keys(ldap_seqof_key_data *ref, ldap_seqof_key_data *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(mkvno); p = p && scalar_equal(kvno); p = p && len_equal(n_key_data,key_data,equal_key_data_array); return p; } #endif /**** arrays ****************************************************************/ int ktest_equal_array_of_data(int length, krb5_data *ref, krb5_data *var) { int i,p = TRUE; if (length == 0 || ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; for (i=0; i<(length); i++) { p = p && ktest_equal_data(&(ref[i]),&(var[i])); } return p; } int ktest_equal_array_of_octet(unsigned int length, krb5_octet *ref, krb5_octet *var) { unsigned int i, p = TRUE; if (length == 0 || ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; for (i=0; ipaChecksum, var->paChecksum); return p; } static int ktest_equal_external_principal_identifier( krb5_external_principal_identifier *ref, krb5_external_principal_identifier *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(subjectName); p = p && equal_str(issuerAndSerialNumber); p = p && equal_str(subjectKeyIdentifier); return p; } static int ktest_equal_sequence_of_external_principal_identifier( krb5_external_principal_identifier **ref, krb5_external_principal_identifier **var) { array_compare(ktest_equal_external_principal_identifier); } int ktest_equal_pa_pk_as_req(krb5_pa_pk_as_req *ref, krb5_pa_pk_as_req *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(signedAuthPack); p = p && ptr_equal(trustedCertifiers, ktest_equal_sequence_of_external_principal_identifier); p = p && equal_str(kdcPkId); return p; } static int ktest_equal_dh_rep_info(krb5_dh_rep_info *ref, krb5_dh_rep_info *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(dhSignedData); p = p && equal_str(serverDHNonce); p = p && ptr_equal(kdfID, ktest_equal_data); return p; } int ktest_equal_pa_pk_as_rep(krb5_pa_pk_as_rep *ref, krb5_pa_pk_as_rep *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; if (ref->choice != var->choice) return FALSE; if (ref->choice == choice_pa_pk_as_rep_dhInfo) p = p && struct_equal(u.dh_Info, ktest_equal_dh_rep_info); else if (ref->choice == choice_pa_pk_as_rep_encKeyPack) p = p && equal_str(u.encKeyPack); return p; } static int ktest_equal_sequence_of_data(krb5_data **ref, krb5_data **var) { array_compare(ktest_equal_data); } int ktest_equal_auth_pack(krb5_auth_pack *ref, krb5_auth_pack *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(pkAuthenticator, ktest_equal_pk_authenticator); p = p && equal_str(clientPublicValue); p = p && ptr_equal(supportedCMSTypes, ktest_equal_sequence_of_algorithm_identifier); p = p && equal_str(clientDHNonce); p = p && ptr_equal(supportedKDFs, ktest_equal_sequence_of_data); return p; } int ktest_equal_kdc_dh_key_info(krb5_kdc_dh_key_info *ref, krb5_kdc_dh_key_info *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && equal_str(subjectPublicKey); p = p && scalar_equal(nonce); p = p && scalar_equal(dhKeyExpiration); return p; } int ktest_equal_reply_key_pack(krb5_reply_key_pack *ref, krb5_reply_key_pack *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && struct_equal(replyKey, ktest_equal_keyblock); p = p && struct_equal(asChecksum, ktest_equal_checksum); return p; } #endif /* not DISABLE_PKINIT */ int ktest_equal_kkdcp_message(krb5_kkdcp_message *ref, krb5_kkdcp_message *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && data_eq(ref->kerb_message, var->kerb_message); p = p && data_eq(ref->target_domain, var->target_domain); p = p && scalar_equal(dclocator_hint); return p; } static int vmac_eq(krb5_verifier_mac *ref, krb5_verifier_mac *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(princ, ktest_equal_principal_data); p = p && scalar_equal(kvno); p = p && scalar_equal(enctype); p = p && struct_equal(checksum, ktest_equal_checksum); return p; } static int vmac_list_eq(krb5_verifier_mac **ref, krb5_verifier_mac **var) { array_compare(vmac_eq); } int ktest_equal_cammac(krb5_cammac *ref, krb5_cammac *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ptr_equal(elements, ktest_equal_authorization_data); p = p && ptr_equal(kdc_verifier, vmac_eq); p = p && ptr_equal(svc_verifier, vmac_eq); p = p && ptr_equal(other_verifiers, vmac_list_eq); return p; } int ktest_equal_secure_cookie(krb5_secure_cookie *ref, krb5_secure_cookie *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && ktest_equal_sequence_of_pa_data(ref->data, var->data); p = p && scalar_equal(time); return p; } int ktest_equal_spake_factor(krb5_spake_factor *ref, krb5_spake_factor *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; p = p && scalar_equal(type); p = p && ptr_equal(data,ktest_equal_data); return p; } int ktest_equal_pa_spake(krb5_pa_spake *ref, krb5_pa_spake *var) { int p = TRUE; if (ref == var) return TRUE; else if (ref == NULL || var == NULL) return FALSE; else if (ref->choice != var->choice) return FALSE; switch (ref->choice) { case SPAKE_MSGTYPE_SUPPORT: p = p && scalar_equal(u.support.ngroups); p = p && (memcmp(ref->u.support.groups,var->u.support.groups, ref->u.support.ngroups * sizeof(int32_t)) == 0); break; case SPAKE_MSGTYPE_CHALLENGE: p = p && struct_equal(u.challenge.pubkey,ktest_equal_data); p = p && ptr_equal(u.challenge.factors, ktest_equal_sequence_of_spake_factor); break; case SPAKE_MSGTYPE_RESPONSE: p = p && struct_equal(u.response.pubkey,ktest_equal_data); p = p && struct_equal(u.response.factor,ktest_equal_enc_data); break; case SPAKE_MSGTYPE_ENCDATA: p = p && struct_equal(u.encdata,ktest_equal_enc_data); break; default: break; } return p; } krb5-1.22.1/src/tests/asn.1/pkinit.asn10000664000175000017500000002510215051422640017274 0ustar ghudsonghudsonKerberosV5-PK-INIT-SPEC { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) pkinit(5) } DEFINITIONS EXPLICIT TAGS ::= BEGIN IMPORTS SubjectPublicKeyInfo, AlgorithmIdentifier FROM PKIX1Explicit88 { iso (1) identified-organization (3) dod (6) internet (1) security (5) mechanisms (5) pkix (7) id-mod (0) id-pkix1-explicit (18) } -- As defined in RFC 3280. KerberosTime, PrincipalName, Realm, EncryptionKey, Checksum FROM KerberosV5Spec2 { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosV5(2) modules(4) krb5spec2(2) }; -- as defined in RFC 4120. id-pkinit OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) kerberosv5(2) pkinit (3) } id-pkinit-authData OBJECT IDENTIFIER ::= { id-pkinit 1 } id-pkinit-DHKeyData OBJECT IDENTIFIER ::= { id-pkinit 2 } id-pkinit-rkeyData OBJECT IDENTIFIER ::= { id-pkinit 3 } id-pkinit-KPClientAuth OBJECT IDENTIFIER ::= { id-pkinit 4 } id-pkinit-KPKdc OBJECT IDENTIFIER ::= { id-pkinit 5 } id-pkinit-san OBJECT IDENTIFIER ::= { iso(1) org(3) dod(6) internet(1) security(5) kerberosv5(2) x509SanAN (2) } pa-pk-as-req INTEGER ::= 16 pa-pk-as-rep INTEGER ::= 17 ad-initial-verified-cas INTEGER ::= 9 td-trusted-certifiers INTEGER ::= 104 td-invalid-certificates INTEGER ::= 105 td-dh-parameters INTEGER ::= 109 PA-PK-AS-REQ ::= SEQUENCE { signedAuthPack [0] IMPLICIT OCTET STRING, -- Contains a CMS type ContentInfo encoded -- according to [RFC3852]. -- The contentType field of the type ContentInfo -- is id-signedData (1.2.840.113549.1.7.2), -- and the content field is a SignedData. -- The eContentType field for the type SignedData is -- id-pkinit-authData (1.3.6.1.5.2.3.1), and the -- eContent field contains the DER encoding of the -- type AuthPack. -- AuthPack is defined below. trustedCertifiers [1] SEQUENCE OF ExternalPrincipalIdentifier OPTIONAL, -- Contains a list of CAs, trusted by the client, -- that can be used to certify the KDC. -- Each ExternalPrincipalIdentifier identifies a CA -- or a CA certificate (thereby its public key). -- The information contained in the -- trustedCertifiers SHOULD be used by the KDC as -- hints to guide its selection of an appropriate -- certificate chain to return to the client. kdcPkId [2] IMPLICIT OCTET STRING OPTIONAL, -- Contains a CMS type SignerIdentifier encoded -- according to [RFC3852]. -- Identifies, if present, a particular KDC -- public key that the client already has. ... } DHNonce ::= OCTET STRING ExternalPrincipalIdentifier ::= SEQUENCE { subjectName [0] IMPLICIT OCTET STRING OPTIONAL, -- Contains a PKIX type Name encoded according to -- [RFC3280]. -- Identifies the certificate subject by the -- distinguished subject name. -- REQUIRED when there is a distinguished subject -- name present in the certificate. issuerAndSerialNumber [1] IMPLICIT OCTET STRING OPTIONAL, -- Contains a CMS type IssuerAndSerialNumber encoded -- according to [RFC3852]. -- Identifies a certificate of the subject. -- REQUIRED for TD-INVALID-CERTIFICATES and -- TD-TRUSTED-CERTIFIERS. subjectKeyIdentifier [2] IMPLICIT OCTET STRING OPTIONAL, -- Identifies the subject's public key by a key -- identifier. When an X.509 certificate is -- referenced, this key identifier matches the X.509 -- subjectKeyIdentifier extension value. When other -- certificate formats are referenced, the documents -- that specify the certificate format and their use -- with the CMS must include details on matching the -- key identifier to the appropriate certificate -- field. -- RECOMMENDED for TD-TRUSTED-CERTIFIERS. ... } AuthPack ::= SEQUENCE { pkAuthenticator [0] PKAuthenticator, clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL, -- Type SubjectPublicKeyInfo is defined in -- [RFC3280]. -- Specifies Diffie-Hellman domain parameters -- and the client's public key value [IEEE1363]. -- The DH public key value is encoded as a BIT -- STRING according to [RFC3279]. -- This field is present only if the client wishes -- to use the Diffie-Hellman key agreement method. supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL, -- Type AlgorithmIdentifier is defined in -- [RFC3280]. -- List of CMS algorithm [RFC3370] identifiers -- that identify key transport algorithms, or -- content encryption algorithms, or signature -- algorithms supported by the client in order of -- (decreasing) preference. clientDHNonce [3] DHNonce OPTIONAL, -- Present only if the client indicates that it -- wishes to reuse DH keys or to allow the KDC to -- do so. ... } PKAuthenticator ::= SEQUENCE { cusec [0] INTEGER (0..999999), ctime [1] KerberosTime, -- cusec and ctime are used as in [RFC4120], for -- replay prevention. nonce [2] INTEGER (0..4294967295), -- Chosen randomly; this nonce does not need to -- match with the nonce in the KDC-REQ-BODY. paChecksum [3] OCTET STRING OPTIONAL, -- MUST be present. -- Contains the SHA1 checksum, performed over -- KDC-REQ-BODY. ... } TD-TRUSTED-CERTIFIERS ::= SEQUENCE OF ExternalPrincipalIdentifier -- Identifies a list of CAs trusted by the KDC. -- Each ExternalPrincipalIdentifier identifies a CA -- or a CA certificate (thereby its public key). TD-INVALID-CERTIFICATES ::= SEQUENCE OF ExternalPrincipalIdentifier -- Each ExternalPrincipalIdentifier identifies a -- certificate (sent by the client) with an invalid -- signature. KRB5PrincipalName ::= SEQUENCE { realm [0] Realm, principalName [1] PrincipalName } AD-INITIAL-VERIFIED-CAS ::= SEQUENCE OF ExternalPrincipalIdentifier -- Identifies the certification path based on which -- the client certificate was validated. -- Each ExternalPrincipalIdentifier identifies a CA -- or a CA certificate (thereby its public key). PA-PK-AS-REP ::= CHOICE { dhInfo [0] DHRepInfo, -- Selected when Diffie-Hellman key exchange is -- used. encKeyPack [1] IMPLICIT OCTET STRING, -- Selected when public key encryption is used. -- Contains a CMS type ContentInfo encoded -- according to [RFC3852]. -- The contentType field of the type ContentInfo is -- id-envelopedData (1.2.840.113549.1.7.3). -- The content field is an EnvelopedData. -- The contentType field for the type EnvelopedData -- is id-signedData (1.2.840.113549.1.7.2). -- The eContentType field for the inner type -- SignedData (when unencrypted) is -- id-pkinit-rkeyData (1.3.6.1.5.2.3.3) and the -- eContent field contains the DER encoding of the -- type ReplyKeyPack. -- ReplyKeyPack is defined below. ... } DHRepInfo ::= SEQUENCE { dhSignedData [0] IMPLICIT OCTET STRING, -- Contains a CMS type ContentInfo encoded according -- to [RFC3852]. -- The contentType field of the type ContentInfo is -- id-signedData (1.2.840.113549.1.7.2), and the -- content field is a SignedData. -- The eContentType field for the type SignedData is -- id-pkinit-DHKeyData (1.3.6.1.5.2.3.2), and the -- eContent field contains the DER encoding of the -- type KDCDHKeyInfo. -- KDCDHKeyInfo is defined below. serverDHNonce [1] DHNonce OPTIONAL, -- Present if and only if dhKeyExpiration is -- present. ... } KDCDHKeyInfo ::= SEQUENCE { subjectPublicKey [0] BIT STRING, -- The KDC's DH public key. -- The DH public key value is encoded as a BIT -- STRING according to [RFC3279]. nonce [1] INTEGER (0..4294967295), -- Contains the nonce in the pkAuthenticator field -- in the request if the DH keys are NOT reused, -- 0 otherwise. dhKeyExpiration [2] KerberosTime OPTIONAL, -- Expiration time for KDC's key pair, -- present if and only if the DH keys are reused. -- If present, the KDC's DH public key MUST not be -- used past the point of this expiration time. -- If this field is omitted then the serverDHNonce -- field MUST also be omitted. ... } ReplyKeyPack ::= SEQUENCE { replyKey [0] EncryptionKey, -- Contains the session key used to encrypt the -- enc-part field in the AS-REP, i.e., the -- AS reply key. asChecksum [1] Checksum, -- Contains the checksum of the AS-REQ -- corresponding to the containing AS-REP. -- The checksum is performed over the type AS-REQ. -- The protocol key [RFC3961] of the checksum is the -- replyKey and the key usage number is 6. -- If the replyKey's enctype is "newer" [RFC4120] -- [RFC4121], the checksum is the required -- checksum operation [RFC3961] for that enctype. -- The client MUST verify this checksum upon receipt -- of the AS-REP. ... } TD-DH-PARAMETERS ::= SEQUENCE OF AlgorithmIdentifier -- Each AlgorithmIdentifier specifies a set of -- Diffie-Hellman domain parameters [IEEE1363]. -- This list is in decreasing preference order. END krb5-1.22.1/src/tests/asn.1/krb5_decode_test.c0000664000175000017500000025276515051422640020604 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/krb5_decode_test.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "k5-spake.h" #include "ktest.h" #include "com_err.h" #include "utility.h" #include "ktest_equal.h" #include "debug.h" #include krb5_context test_context; int error_count = 0; void krb5_ktest_free_enc_data(krb5_context context, krb5_enc_data *val); #ifndef DISABLE_PKINIT static int equal_principal(krb5_principal *ref, krb5_principal var); static void ktest_free_auth_pack(krb5_context context, krb5_auth_pack *val); static void ktest_free_kdc_dh_key_info(krb5_context context, krb5_kdc_dh_key_info *val); static void ktest_free_pa_pk_as_req(krb5_context context, krb5_pa_pk_as_req *val); static void ktest_free_pa_pk_as_rep(krb5_context context, krb5_pa_pk_as_rep *val); static void ktest_free_reply_key_pack(krb5_context context, krb5_reply_key_pack *val); #endif #ifdef ENABLE_LDAP static void ktest_free_ldap_seqof_key_data(krb5_context context, ldap_seqof_key_data *val); #endif static void ktest_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val); int main(int argc, char **argv) { krb5_data code; krb5_error_code retval; retval = krb5_init_context(&test_context); if (retval) { com_err(argv[0], retval, "while initializing krb5"); exit(1); } init_access(argv[0]); #define setup(type,constructor) \ type ref, *var; \ constructor(&ref); \ do {} while (0) #define decode_run(typestring,description,encoding,decoder,comparator,cleanup) do { \ retval = krb5_data_hex_parse(&code,encoding); \ if (retval) { \ com_err("krb5_decode_test", retval, "while parsing %s", typestring); \ exit(1); \ } \ retval = decoder(&code,&var); \ if (retval) { \ com_err("krb5_decode_test", retval, "while decoding %s", typestring); \ error_count++; \ } \ test(comparator(&ref,var),typestring); \ printf("%s\n",description); \ krb5_free_data_contents(test_context, &code); \ cleanup(test_context, var); \ } while (0) #define decode_fail(err,typestring,description,encoding,decoder) do { \ retval = krb5_data_hex_parse(&code,encoding); \ if (retval) { \ com_err("krb5_decode_test", retval, "while parsing %s", typestring); \ exit(1); \ } \ retval = decoder(&code,&var); \ if (retval != (err)) { \ com_err("krb5_decode_test", retval, "while decoding %s", typestring); \ error_count++; \ } \ test(1,typestring); \ printf("%s\n",description); \ krb5_free_data_contents(test_context, &code); \ } while (0) /****************************************************************/ /* decode_krb5_authenticator */ { setup(krb5_authenticator,ktest_make_sample_authenticator); decode_run("authenticator","","62 81 A1 30 81 9E A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A7 03 02 01 11 A8 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xffffff80; decode_run("authenticator","(80 -> seq-number 0xffffff80)", "62 81 A1 30 81 9E" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 03 02 01 80" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xffffffff; decode_run("authenticator","(FF -> seq-number 0xffffffff)", "62 81 A1 30 81 9E" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 03 02 01 FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xff; decode_run("authenticator","(00FF -> seq-number 0xff)", "62 81 A2 30 81 9F" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 04 02 02 00 FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xffffffff; decode_run("authenticator","(00FFFFFFFF -> seq-number 0xffffffff)", "62 81 A5 30 81 A2" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 07 02 05 00 FF FF FF FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0x7fffffff; decode_run("authenticator","(7FFFFFFF -> seq-number 0x7fffffff)", "62 81 A4 30 81 A1" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 06 02 04 7F FF FF FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ref.seq_number = 0xffffffff; decode_run("authenticator","(FFFFFFFF -> seq-number 0xffffffff)", "62 81 A4 30 81 A1" " A0 03 02 01 05" " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55" " A2 1A 30 18" " A0 03 02 01 01" " A1 11 30 0F" " 1B 06 68 66 74 73 61 69" " 1B 05 65 78 74 72 61" " A3 0F 30 0D" " A0 03 02 01 01" " A1 06 04 04 31 32 33 34" " A4 05 02 03 01 E2 40" " A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A" " A6 13 30 11" " A0 03 02 01 01" " A1 0A 04 08 31 32 33 34 35 36 37 38" " A7 06 02 04 FF FF FF FF" " A8 24 30 22" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" " 30 0F" " A0 03 02 01 01" " A1 08 04 06 66 6F 6F 62 61 72" ,decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ktest_destroy_checksum(&(ref.checksum)); ktest_destroy_keyblock(&(ref.subkey)); ref.seq_number = 0; ktest_empty_authorization_data(ref.authorization_data); decode_run("authenticator","(optionals empty)","62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ktest_destroy_authorization_data(&(ref.authorization_data)); decode_run("authenticator","(optionals NULL)","62 4F 30 4D A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 05 02 03 01 E2 40 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_authenticator,ktest_equal_authenticator,krb5_free_authenticator); ktest_empty_authenticator(&ref); } /****************************************************************/ /* decode_krb5_ticket */ { setup(krb5_ticket,ktest_make_sample_ticket); decode_run("ticket","","61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket); decode_run("ticket","(+ trailing [4] INTEGER","61 61 30 5F A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 03 02 01 01",decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket); /* "61 80 30 80 " " A0 03 02 01 05 " " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 " " A2 80 30 80 " " A0 03 02 01 01 " " A1 80 30 80 " " 1B 06 68 66 74 73 61 69 " " 1B 05 65 78 74 72 61 " " 00 00 00 00 " " 00 00 00 00 " " A3 80 30 80 " " A0 03 02 01 00 " " A1 03 02 01 05 " " A2 17 04 15 6B 72 62 41 53 4E 2E 31 " " 20 74 65 73 74 20 6D 65 73 73 61 67 65 " " 00 00 00 00" "00 00 00 00" */ decode_fail(ASN1_INDEF,"ticket","(indefinite lengths)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00" ,decode_krb5_ticket); /* "61 80 30 80 " " A0 03 02 01 05 " " A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 " " A2 80 30 80 " " A0 03 02 01 01 " " A1 80 30 80 " " 1B 06 68 66 74 73 61 69 " " 1B 05 65 78 74 72 61 " " 00 00 00 00 " " 00 00 00 00 " " A3 80 30 80 " " A0 03 02 01 00 " " A1 03 02 01 05 " " A2 17 04 15 6B 72 62 41 53 4E 2E 31 " " 20 74 65 73 74 20 6D 65 73 73 61 67 65 " " 00 00 00 00" " A4 03 02 01 01 " "00 00 00 00" */ decode_fail(ASN1_INDEF,"ticket","(indefinite lengths + trailing [4] INTEGER)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 A4 03 02 01 01 00 00 00 00",decode_krb5_ticket); ktest_empty_ticket(&ref); } /****************************************************************/ /* decode_krb5_encryption_key */ { setup(krb5_keyblock,ktest_make_sample_keyblock); decode_run("encryption_key","","30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); decode_run("encryption_key","(+ trailing [2] INTEGER)","30 16 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); decode_run("encryption_key","(+ trailing [2] SEQUENCE {[0] INTEGER})","30 1A A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 07 30 05 A0 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); decode_fail(ASN1_INDEF,"encryption_key","(indefinite lengths)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 00 00",decode_krb5_encryption_key); decode_fail(ASN1_INDEF,"encryption_key","(indefinite lengths + trailing [2] INTEGER)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01 00 00",decode_krb5_encryption_key); decode_fail(ASN1_INDEF,"encryption_key","(indefinite lengths + trailing [2] SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 80 30 80 A0 03 02 01 01 00 00 00 00 00 00",decode_krb5_encryption_key); decode_fail(ASN1_INDEF,"encryption_key","(indefinite lengths + trailing SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 80 A0 03 02 01 01 00 00 00 00",decode_krb5_encryption_key); ref.enctype = -1; decode_run("encryption_key","(enctype = -1)","30 11 A0 03 02 01 FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ref.enctype = -255; decode_run("encryption_key","(enctype = -255)","30 12 A0 04 02 02 FF 01 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ref.enctype = 255; decode_run("encryption_key","(enctype = 255)","30 12 A0 04 02 02 00 FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ref.enctype = -2147483648U; decode_run("encryption_key","(enctype = -2147483648)","30 14 A0 06 02 04 80 00 00 00 A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ref.enctype = 2147483647; decode_run("encryption_key","(enctype = 2147483647)","30 14 A0 06 02 04 7F FF FF FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock); ktest_empty_keyblock(&ref); } /****************************************************************/ /* decode_krb5_enc_tkt_part */ { setup(krb5_enc_tkt_part,ktest_make_sample_enc_tkt_part); decode_run("enc_tkt_part","","63 82 01 14 30 82 01 10 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); ref.times.starttime = 0; ref.times.renew_till = 0; ktest_destroy_address(&(ref.caddrs[1])); ktest_destroy_address(&(ref.caddrs[0])); ktest_destroy_authdata(&(ref.authorization_data[1])); ktest_destroy_authdata(&(ref.authorization_data[0])); /* ISODE version fails on the empty caddrs field */ ktest_destroy_addresses(&(ref.caddrs)); ktest_destroy_authorization_data(&(ref.authorization_data)); decode_run("enc_tkt_part","(optionals NULL)","63 81 A5 30 81 A2 A0 07 03 05 00 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part, krb5_free_enc_tkt_part); decode_run("enc_tkt_part","(optionals NULL + bitstring enlarged to 38 bits)","63 81 A6 30 81 A3 A0 08 03 06 02 FE DC BA 98 DC A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); decode_run("enc_tkt_part","(optionals NULL + bitstring enlarged to 40 bits)","63 81 A6 30 81 A3 A0 08 03 06 00 FE DC BA 98 DE A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); decode_run("enc_tkt_part","(optionals NULL + bitstring reduced to 29 bits)","63 81 A5 30 81 A2 A0 07 03 05 03 FE DC BA 98 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); ref.flags &= 0xFFFFFF00; decode_run("enc_tkt_part","(optionals NULL + bitstring reduced to 24 bits)","63 81 A4 30 81 A1 A0 06 03 04 00 FE DC BA A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 2E 30 2C A0 03 02 01 01 A1 25 04 23 45 44 55 2C 4D 49 54 2E 2C 41 54 48 45 4E 41 2E 2C 57 41 53 48 49 4E 47 54 4F 4E 2E 45 44 55 2C 43 53 2E A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_enc_tkt_part,ktest_equal_enc_tkt_part,krb5_free_enc_tkt_part); ktest_empty_enc_tkt_part(&ref); } /****************************************************************/ /* decode_krb5_enc_kdc_rep_part */ { setup(krb5_enc_kdc_rep_part,ktest_make_sample_enc_kdc_rep_part); decode_run("enc_kdc_rep_part","","7A 82 01 0E 30 82 01 0A A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part); ref.key_exp = 0; /* ref.times.starttime = 0;*/ ref.times.starttime = ref.times.authtime; ref.times.renew_till = 0; ref.flags &= ~TKT_FLG_RENEWABLE; ktest_destroy_addresses(&(ref.caddrs)); decode_run("enc_kdc_rep_part","(optionals NULL)","7A 81 B2 30 81 AF A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part); ktest_empty_enc_kdc_rep_part(&ref); } /****************************************************************/ /* decode_krb5_as_rep */ { setup(krb5_kdc_rep,ktest_make_sample_kdc_rep); ref.msg_type = KRB5_AS_REP; decode_run("as_rep","","6B 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0B A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep); /* 6B 80 30 80 A0 03 02 01 05 A1 03 02 01 0B A2 80 30 80 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 00 00 00 00 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A5 80 61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 00 00 A6 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 */ decode_fail(ASN1_INDEF,"as_rep","(indefinite lengths)","6B 80 30 80 A0 03 02 01 05 A1 03 02 01 0B A2 80 30 80 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 00 00 00 00 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A5 80 61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 00 00 A6 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00",decode_krb5_as_rep); ktest_destroy_pa_data_array(&(ref.padata)); decode_run("as_rep","(optionals NULL)","6B 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0B A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep); ktest_empty_kdc_rep(&ref); } /****************************************************************/ /* decode_krb5_tgs_rep */ { setup(krb5_kdc_rep,ktest_make_sample_kdc_rep); ref.msg_type = KRB5_TGS_REP; decode_run("tgs_rep","","6D 81 EA 30 81 E7 A0 03 02 01 05 A1 03 02 01 0D A2 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_rep,ktest_equal_tgs_rep,krb5_free_kdc_rep); ktest_destroy_pa_data_array(&(ref.padata)); decode_run("tgs_rep","(optionals NULL)","6D 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0D A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_rep,ktest_equal_tgs_rep,krb5_free_kdc_rep); ktest_empty_kdc_rep(&ref); } /****************************************************************/ /* decode_krb5_ap_req */ { setup(krb5_ap_req,ktest_make_sample_ap_req); decode_run("ap_req","","6E 81 9D 30 81 9A A0 03 02 01 05 A1 03 02 01 0E A2 07 03 05 00 FE DC BA 98 A3 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A4 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ap_req,ktest_equal_ap_req,krb5_free_ap_req); ktest_empty_ap_req(&ref); } /****************************************************************/ /* decode_krb5_ap_rep */ { setup(krb5_ap_rep,ktest_make_sample_ap_rep); decode_run("ap_rep","","6F 33 30 31 A0 03 02 01 05 A1 03 02 01 0F A2 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_ap_rep,ktest_equal_ap_rep,krb5_free_ap_rep); ktest_empty_ap_rep(&ref); } /****************************************************************/ /* decode_krb5_ap_rep_enc_part */ { setup(krb5_ap_rep_enc_part,ktest_make_sample_ap_rep_enc_part); decode_run("ap_rep_enc_part","","7B 36 30 34 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A3 03 02 01 11",decode_krb5_ap_rep_enc_part,ktest_equal_ap_rep_enc_part,krb5_free_ap_rep_enc_part); ktest_destroy_keyblock(&(ref.subkey)); ref.seq_number = 0; decode_run("ap_rep_enc_part","(optionals NULL)","7B 1C 30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40",decode_krb5_ap_rep_enc_part,ktest_equal_ap_rep_enc_part,krb5_free_ap_rep_enc_part); retval = krb5_data_hex_parse(&code, "7B 06 30 04 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40"); if (retval) { com_err("krb5_decode_test", retval, "while parsing"); exit(1); } retval = decode_krb5_ap_rep_enc_part(&code, &var); if (retval != ASN1_OVERRUN) { printf("ERROR: "); error_count++; } else { printf("OK: "); } printf("ap_rep_enc_part(optionals NULL + expect ASN1_OVERRUN for inconsistent length of timestamp)\n"); krb5_free_data_contents(test_context, &code); krb5_free_ap_rep_enc_part(test_context, var); ktest_empty_ap_rep_enc_part(&ref); } /****************************************************************/ /* decode_krb5_as_req */ { setup(krb5_kdc_req,ktest_make_sample_kdc_req); ref.msg_type = KRB5_AS_REQ; ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("as_req","","6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_req,ktest_equal_as_req,krb5_free_kdc_req); ktest_destroy_pa_data_array(&(ref.padata)); ktest_destroy_principal(&(ref.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(ref.server)); #endif ref.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; ref.from = 0; ref.rtime = 0; ktest_destroy_addresses(&(ref.addresses)); ktest_destroy_enc_data(&(ref.authorization_data)); decode_run("as_req","(optionals NULL except second_ticket)","6A 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0A A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_req,ktest_equal_as_req,krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(ref.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(ref.server)); #endif ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("as_req","(optionals NULL except server)","6A 69 30 67 A1 03 02 01 05 A2 03 02 01 0A A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_as_req,ktest_equal_as_req,krb5_free_kdc_req); ktest_empty_kdc_req(&ref); } /****************************************************************/ /* decode_krb5_tgs_req */ { setup(krb5_kdc_req,ktest_make_sample_kdc_req); ref.msg_type = KRB5_TGS_REQ; ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("tgs_req","","6C 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0C A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_req,ktest_equal_tgs_req,krb5_free_kdc_req); ktest_destroy_pa_data_array(&(ref.padata)); ktest_destroy_principal(&(ref.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(ref.server)); #endif ref.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; ref.from = 0; ref.rtime = 0; ktest_destroy_addresses(&(ref.addresses)); ktest_destroy_enc_data(&(ref.authorization_data)); decode_run("tgs_req","(optionals NULL except second_ticket)","6C 82 01 14 30 82 01 10 A1 03 02 01 05 A2 03 02 01 0C A4 82 01 02 30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_tgs_req,ktest_equal_tgs_req,krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(ref.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(ref.server)); #endif ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("tgs_req","(optionals NULL except server)","6C 69 30 67 A1 03 02 01 05 A2 03 02 01 0C A4 5B 30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_tgs_req,ktest_equal_tgs_req,krb5_free_kdc_req); ktest_empty_kdc_req(&ref); } /****************************************************************/ /* decode_krb5_kdc_req_body */ { krb5_kdc_req ref, *var; memset(&ref, 0, sizeof(krb5_kdc_req)); ktest_make_sample_kdc_req_body(&ref); ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("kdc_req_body","","30 82 01 A6 A0 07 03 05 00 FE DC BA 90 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req); ktest_destroy_principal(&(ref.client)); #ifndef ISODE_SUCKS ktest_destroy_principal(&(ref.server)); #endif ref.kdc_options |= KDC_OPT_ENC_TKT_IN_SKEY; ref.from = 0; ref.rtime = 0; ktest_destroy_addresses(&(ref.addresses)); ktest_destroy_enc_data(&(ref.authorization_data)); decode_run("kdc_req_body","(optionals NULL except second_ticket)","30 81 FF A0 07 03 05 00 FE DC BA 98 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req); ktest_destroy_sequence_of_ticket(&(ref.second_ticket)); #ifndef ISODE_SUCKS ktest_make_sample_principal(&(ref.server)); #endif ref.kdc_options &= ~KDC_OPT_ENC_TKT_IN_SKEY; decode_run("kdc_req_body","(optionals NULL except server)","30 59 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req); ref.nktypes = 0; free(ref.ktype); ref.ktype = NULL; decode_run("kdc_req_body","(optionals NULL except server; zero-length etypes)","30 53 A0 07 03 05 00 FE DC BA 90 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 02 30 00",decode_krb5_kdc_req_body,ktest_equal_kdc_req_body,krb5_free_kdc_req); ktest_empty_kdc_req(&ref); } /****************************************************************/ /* decode_krb5_safe */ { setup(krb5_safe,ktest_make_sample_safe); decode_run("safe","","74 6E 30 6C A0 03 02 01 05 A1 03 02 01 14 A2 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_safe,ktest_equal_safe,krb5_free_safe); ref.timestamp = 0; ref.usec = 0; ref.seq_number = 0; ktest_destroy_address(&(ref.r_address)); decode_run("safe","(optionals NULL)","74 3E 30 3C A0 03 02 01 05 A1 03 02 01 14 A2 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A3 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_safe,ktest_equal_safe,krb5_free_safe); ktest_empty_safe(&ref); } /****************************************************************/ /* decode_krb5_priv */ { setup(krb5_priv,ktest_make_sample_priv); decode_run("priv","","75 33 30 31 A0 03 02 01 05 A1 03 02 01 15 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_priv,ktest_equal_priv,krb5_free_priv); ktest_empty_priv(&ref); } /****************************************************************/ /* decode_krb5_enc_priv_part */ { setup(krb5_priv_enc_part,ktest_make_sample_priv_enc_part); decode_run("enc_priv_part","","7C 4F 30 4D A0 0A 04 08 6B 72 62 35 64 61 74 61 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 05 02 03 01 E2 40 A3 03 02 01 11 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_priv_part,ktest_equal_enc_priv_part,krb5_free_priv_enc_part); ref.timestamp = 0; ref.usec = 0; ref.seq_number = 0; ktest_destroy_address(&(ref.r_address)); decode_run("enc_priv_part","(optionals NULL)","7C 1F 30 1D A0 0A 04 08 6B 72 62 35 64 61 74 61 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_priv_part,ktest_equal_enc_priv_part,krb5_free_priv_enc_part); ktest_empty_priv_enc_part(&ref); } /****************************************************************/ /* decode_krb5_cred */ { setup(krb5_cred,ktest_make_sample_cred); decode_run("cred","","76 81 F6 30 81 F3 A0 03 02 01 05 A1 03 02 01 16 A2 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_cred,ktest_equal_cred,krb5_free_cred); ktest_empty_cred(&ref); } /****************************************************************/ /* decode_krb5_enc_cred_part */ { setup(krb5_cred_enc_part,ktest_make_sample_cred_enc_part); decode_run("enc_cred_part","","7D 82 02 23 30 82 02 1F A0 82 01 DA 30 82 01 D6 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 A5 0F 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_cred_part,ktest_equal_enc_cred_part,krb5_free_cred_enc_part); /* free_cred_enc_part does not free the pointer */ free(var); ktest_destroy_principal(&(ref.ticket_info[0]->client)); ktest_destroy_principal(&(ref.ticket_info[0]->server)); ref.ticket_info[0]->flags = 0; ref.ticket_info[0]->times.authtime = 0; ref.ticket_info[0]->times.starttime = 0; ref.ticket_info[0]->times.endtime = 0; ref.ticket_info[0]->times.renew_till = 0; ktest_destroy_addresses(&(ref.ticket_info[0]->caddrs)); ref.nonce = 0; ref.timestamp = 0; ref.usec = 0; ktest_destroy_address(&(ref.s_address)); ktest_destroy_address(&(ref.r_address)); decode_run("enc_cred_part","(optionals NULL)","7D 82 01 0E 30 82 01 0A A0 82 01 06 30 82 01 02 30 15 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 81 E8 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 07 03 05 00 FE DC BA 98 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A9 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AA 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_cred_part,ktest_equal_enc_cred_part,krb5_free_cred_enc_part); /* free_cred_enc_part does not free the pointer */ free(var); ktest_empty_cred_enc_part(&ref); } /****************************************************************/ /* decode_krb5_error */ { setup(krb5_error,ktest_make_sample_error); decode_run("error","","7E 81 BA 30 81 B7 A0 03 02 01 05 A1 03 02 01 1E A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A7 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A8 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 0A 1B 08 6B 72 62 35 64 61 74 61 AC 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_error,ktest_equal_error,krb5_free_error); ref.ctime = 0; ktest_destroy_principal(&(ref.client)); ktest_empty_data(&(ref.text)); ktest_empty_data(&(ref.e_data)); decode_run("error","(optionals NULL)","7E 60 30 5E A0 03 02 01 05 A1 03 02 01 1E A3 05 02 03 01 E2 40 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 05 02 03 01 E2 40 A6 03 02 01 3C A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_error,ktest_equal_error,krb5_free_error); ktest_empty_error(&ref); } /****************************************************************/ /* decode_krb5_authdata and krb5int_get_authdata_containee_types */ { krb5_authdata **ref, **var, tmp; unsigned int count; krb5_authdatatype *types = NULL; ktest_make_sample_authorization_data(&ref); retval = krb5_data_hex_parse(&code,"30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72"); if (retval) { com_err("parsing authorization_data",retval,""); exit(1); } retval = decode_krb5_authdata(&code,&var); if (retval) com_err("decoding authorization_data",retval,""); test(ktest_equal_authorization_data(ref,var),"authorization_data\n"); tmp.length = code.length; tmp.contents = (krb5_octet *)code.data; retval = krb5int_get_authdata_containee_types(test_context, &tmp, &count, &types); if (retval) com_err("reading authdata types",retval,""); test(count == 2 && types[0] == 1 && types[1] == 1, "authorization_data(types only)\n"); free(types); krb5_free_data_contents(test_context, &code); krb5_free_authdata(test_context, var); ktest_destroy_authorization_data(&ref); } /****************************************************************/ /* decode_krb5_padata_sequence and decode_krb5_typed_data */ { krb5_pa_data **ref, **var; ktest_make_sample_pa_data_array(&ref); retval = krb5_data_hex_parse(&code,"30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61"); if (retval) { com_err("parsing padata_sequence",retval,""); exit(1); } retval = decode_krb5_padata_sequence(&code,&var); if (retval) com_err("decoding padata_sequence",retval,""); test(ktest_equal_sequence_of_pa_data(ref,var),"pa_data\n"); krb5_free_pa_data(test_context, var); krb5_free_data_contents(test_context, &code); retval = krb5_data_hex_parse(&code,"30 24 30 10 A0 03 02 01 0D A1 09 04 07 70 61 2D 64 61 74 61 30 10 A0 03 02 01 0D A1 09 04 07 70 61 2D 64 61 74 61"); if (retval) { com_err("parsing padata_sequence",retval,""); exit(1); } retval = decode_krb5_typed_data(&code,&var); if (retval) com_err("decoding typed_data",retval,""); test(ktest_equal_sequence_of_pa_data(ref,var),"typed_data\n"); krb5_free_pa_data(test_context, var); krb5_free_data_contents(test_context, &code); ktest_destroy_pa_data_array(&ref); } /****************************************************************/ /* decode_krb5_padata_sequence (empty) */ { krb5_pa_data **ref, **var; ktest_make_sample_empty_pa_data_array(&ref); retval = krb5_data_hex_parse(&code,"30 00"); if (retval) { com_err("parsing padata_sequence (empty)",retval,""); exit(1); } retval = decode_krb5_padata_sequence(&code,&var); if (retval) com_err("decoding padata_sequence (empty)",retval,""); test(ktest_equal_sequence_of_pa_data(ref,var),"pa_data (empty)\n"); krb5_free_pa_data(test_context, var); krb5_free_data_contents(test_context, &code); ktest_destroy_pa_data_array(&ref); } /****************************************************************/ /* decode_etype_info */ { krb5_etype_info ref, var; ktest_make_sample_etype_info(&ref); retval = krb5_data_hex_parse(&code,"30 33 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 30 05 A0 03 02 01 01 30 14 A0 03 02 01 02 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 32"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info"); exit(1); } retval = decode_krb5_etype_info(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info"); } test(ktest_equal_etype_info(ref,var),"etype_info\n"); ktest_destroy_etype_info(var); ktest_destroy_etype_info_entry(ref[2]); ref[2] = 0; ktest_destroy_etype_info_entry(ref[1]); ref[1] = 0; krb5_free_data_contents(test_context, &code); retval = krb5_data_hex_parse(&code,"30 16 30 14 A0 03 02 01 00 A1 0D 04 0B 4D 6F 72 74 6F 6E 27 73 20 23 30"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info (only one)"); exit(1); } retval = decode_krb5_etype_info(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info (only one)"); } test(ktest_equal_etype_info(ref,var),"etype_info (only one)\n"); ktest_destroy_etype_info(var); ktest_destroy_etype_info_entry(ref[0]); ref[0] = 0; krb5_free_data_contents(test_context, &code); retval = krb5_data_hex_parse(&code,"30 00"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info (no info)"); exit(1); } retval = decode_krb5_etype_info(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info (no info)"); } test(ktest_equal_etype_info(ref,var),"etype_info (no info)\n"); krb5_free_data_contents(test_context, &code); ktest_destroy_etype_info(var); ktest_destroy_etype_info(ref); } /****************************************************************/ /* decode_etype_info2 */ { krb5_etype_info ref, var; ktest_make_sample_etype_info2(&ref); retval = krb5_data_hex_parse(&code,"30 51 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30 30 0F A0 03 02 01 01 A2 08 04 06 73 32 6B 3A 20 31 30 1E A0 03 02 01 02 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 32 A2 08 04 06 73 32 6B 3A 20 32"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info2"); exit(1); } retval = decode_krb5_etype_info2(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info2"); } test(ktest_equal_etype_info(ref,var),"etype_info2\n"); ktest_destroy_etype_info(var); ktest_destroy_etype_info_entry(ref[2]); ref[2] = 0; ktest_destroy_etype_info_entry(ref[1]); ref[1] = 0; krb5_free_data_contents(test_context, &code); retval = krb5_data_hex_parse(&code,"30 20 30 1E A0 03 02 01 00 A1 0D 1B 0B 4D 6F 72 74 6F 6E 27 73 20 23 30 A2 08 04 06 73 32 6B 3A 20 30"); if (retval) { com_err("krb5_decode_test", retval, "while parsing etype_info2 (only one)"); exit(1); } retval = decode_krb5_etype_info2(&code,&var); if (retval) { com_err("krb5_decode_test", retval, "while decoding etype_info2 (only one)"); } test(ktest_equal_etype_info(ref,var),"etype_info2 (only one)\n"); krb5_free_data_contents(test_context, &code); ktest_destroy_etype_info(var); ktest_destroy_etype_info(ref); } /****************************************************************/ /* decode_pa_enc_ts */ { setup(krb5_pa_enc_ts,ktest_make_sample_pa_enc_ts); decode_run("pa_enc_ts","","30 1A A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40",decode_krb5_pa_enc_ts,ktest_equal_krb5_pa_enc_ts,krb5_free_pa_enc_ts); ref.pausec = 0; decode_run("pa_enc_ts (no usec)","","30 13 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A",decode_krb5_pa_enc_ts,ktest_equal_krb5_pa_enc_ts,krb5_free_pa_enc_ts); } /****************************************************************/ /* decode_enc_data */ { setup(krb5_enc_data,ktest_make_sample_enc_data); decode_run("enc_data","","30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_enc_data,ktest_equal_enc_data,krb5_ktest_free_enc_data); ref.kvno = 0xFF000000; decode_run("enc_data","(MSB-set kvno)","30 26 A0 03 02 01 00 A1 06 02 04 FF 00 00 00 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_enc_data,ktest_equal_enc_data,krb5_ktest_free_enc_data); ref.kvno = 0xFFFFFFFF; decode_run("enc_data","(kvno=-1)","30 23 A0 03 02 01 00 A1 03 02 01 FF A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_enc_data,ktest_equal_enc_data,krb5_ktest_free_enc_data); ktest_destroy_enc_data(&ref); } /****************************************************************/ /* decode_sam_challenge_2 */ { setup(krb5_sam_challenge_2,ktest_make_sample_sam_challenge_2); decode_run("sam_challenge_2","","30 22 A0 0D 30 0B 04 09 63 68 61 6C 6C 65 6E 67 65 A1 11 30 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_sam_challenge_2,ktest_equal_sam_challenge_2,krb5_free_sam_challenge_2); ktest_empty_sam_challenge_2(&ref); } /****************************************************************/ /* decode_sam_challenge_2_body */ { setup(krb5_sam_challenge_2_body,ktest_make_sample_sam_challenge_2_body); decode_run("sam_challenge_2_body","","30 64 A0 03 02 01 2A A1 07 03 05 00 80 00 00 00 A2 0B 04 09 74 79 70 65 20 6E 61 6D 65 A4 11 04 0F 63 68 61 6C 6C 65 6E 67 65 20 6C 61 62 65 6C A5 10 04 0E 63 68 61 6C 6C 65 6E 67 65 20 69 70 73 65 A6 16 04 14 72 65 73 70 6F 6E 73 65 5F 70 72 6F 6D 70 74 20 69 70 73 65 A8 05 02 03 54 32 10 A9 03 02 01 14",decode_krb5_sam_challenge_2_body,ktest_equal_sam_challenge_2_body,krb5_free_sam_challenge_2_body); ktest_empty_sam_challenge_2_body(&ref); } /****************************************************************/ /* decode_pa_for_user */ { setup(krb5_pa_for_user,ktest_make_sample_pa_for_user); decode_run("pa_for_user","","30 4B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 0A 1B 08 6B 72 62 35 64 61 74 61",decode_krb5_pa_for_user,ktest_equal_pa_for_user,krb5_free_pa_for_user); ktest_empty_pa_for_user(&ref); } /****************************************************************/ /* decode_pa_s4u_x509_user */ { setup(krb5_pa_s4u_x509_user,ktest_make_sample_pa_s4u_x509_user); decode_run("pa_s4u_x509_user","","30 68 A0 55 30 53 A0 06 02 04 00 CA 14 9A A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 12 04 10 70 61 5F 73 34 75 5F 78 35 30 39 5F 75 73 65 72 A4 07 03 05 00 80 00 00 00 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_pa_s4u_x509_user,ktest_equal_pa_s4u_x509_user,krb5_free_pa_s4u_x509_user); ktest_empty_pa_s4u_x509_user(&ref); } /****************************************************************/ /* decode_pa_pac_req */ { /* This type has no encoder and is very simple. Test two * hand-generated encodings. */ krb5_pa_pac_req *req1 = NULL, *req2 = NULL; code = make_data("\x30\x05\xA0\x03\x01\x01\x00", 7); retval = decode_krb5_pa_pac_req(&code, &req1); if (retval) { com_err(argv[0], retval, "while decoding PA-PAC-REQ"); exit(1); } code = make_data("\x30\x05\xA0\x03\x01\x01\xFF", 7); retval = decode_krb5_pa_pac_req(&code, &req2); if (retval) { com_err(argv[0], retval, "while decoding PA-PAC-REQ"); exit(1); } if (req1->include_pac != 0 || req2->include_pac != 1) { printf("ERROR: "); error_count++; } else { printf("OK: "); } printf("pa_pac_rec\n"); free(req1); free(req2); } /****************************************************************/ /* decode_ad_kdcissued */ { setup(krb5_ad_kdcissued,ktest_make_sample_ad_kdcissued); decode_run("ad_kdcissued","","30 65 A0 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 24 30 22 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72 30 0F A0 03 02 01 01 A1 08 04 06 66 6F 6F 62 61 72",decode_krb5_ad_kdcissued,ktest_equal_ad_kdcissued,krb5_free_ad_kdcissued); ktest_empty_ad_kdcissued(&ref); } /****************************************************************/ /* decode_iakerb_header */ { setup(krb5_iakerb_header,ktest_make_sample_iakerb_header); decode_run("iakerb_header","","30 18 A1 0A 0C 08 6B 72 62 35 64 61 74 61 A2 0A 04 08 6B 72 62 35 64 61 74 61",decode_krb5_iakerb_header,ktest_equal_iakerb_header,krb5_free_iakerb_header); ktest_empty_iakerb_header(&ref); } /****************************************************************/ /* decode_iakerb_finished */ { setup(krb5_iakerb_finished,ktest_make_sample_iakerb_finished); decode_run("iakerb_finished","","30 11 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34",decode_krb5_iakerb_finished,ktest_equal_iakerb_finished,krb5_free_iakerb_finished); ktest_empty_iakerb_finished(&ref); } /****************************************************************/ /* decode_fast_response */ { setup(krb5_fast_response,ktest_make_sample_fast_response); decode_run("fast_response","","30 81 9F A0 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A1 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 5B 30 59 A0 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A1 05 02 03 01 E2 40 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34 A3 03 02 01 2A",decode_krb5_fast_response,ktest_equal_fast_response,krb5_free_fast_response); ktest_empty_fast_response(&ref); } /****************************************************************/ /* decode_pa_fx_fast_reply */ { setup(krb5_enc_data,ktest_make_sample_enc_data); decode_run("pa_fx_fast_reply","","A0 29 30 27 A0 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_pa_fx_fast_reply,ktest_equal_enc_data,krb5_free_enc_data); ktest_destroy_enc_data(&ref); } /****************************************************************/ /* decode_krb5_otp_tokeninfo */ { setup(krb5_otp_tokeninfo,ktest_make_minimal_otp_tokeninfo); decode_run("otp_tokeninfo","(optionals NULL)","30 07 80 05 00 00 00 00 00",decode_krb5_otp_tokeninfo,ktest_equal_otp_tokeninfo,k5_free_otp_tokeninfo); ktest_empty_otp_tokeninfo(&ref); } { setup(krb5_otp_tokeninfo,ktest_make_maximal_otp_tokeninfo); decode_run("otp_tokeninfo","","30 72 80 05 00 77 00 00 00 81 0B 45 78 61 6D 70 6C 65 63 6F 72 70 82 05 68 61 72 6B 21 83 01 0A 84 01 02 85 09 79 6F 75 72 74 6F 6B 65 6E 86 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 A7 16 30 0B 06 09 60 86 48 01 65 03 04 02 01 30 07 06 05 2B 0E 03 02 1A 88 02 03 E8",decode_krb5_otp_tokeninfo,ktest_equal_otp_tokeninfo,k5_free_otp_tokeninfo); ktest_empty_otp_tokeninfo(&ref); } /****************************************************************/ /* decode_krb5_pa_otp_challenge */ { setup(krb5_pa_otp_challenge,ktest_make_minimal_pa_otp_challenge); decode_run("pa_otp_challenge","(optionals NULL)","30 15 80 08 6D 69 6E 6E 6F 6E 63 65 A2 09 30 07 80 05 00 00 00 00 00",decode_krb5_pa_otp_challenge,ktest_equal_pa_otp_challenge,k5_free_pa_otp_challenge); ktest_empty_pa_otp_challenge(&ref); } { setup(krb5_pa_otp_challenge,ktest_make_maximal_pa_otp_challenge); decode_run("pa_otp_challenge","","30 81 A5 80 08 6D 61 78 6E 6F 6E 63 65 81 0B 74 65 73 74 73 65 72 76 69 63 65 A2 7D 30 07 80 05 00 00 00 00 00 30 72 80 05 00 77 00 00 00 81 0B 45 78 61 6D 70 6C 65 63 6F 72 70 82 05 68 61 72 6B 21 83 01 0A 84 01 02 85 09 79 6F 75 72 74 6F 6B 65 6E 86 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 A7 16 30 0B 06 09 60 86 48 01 65 03 04 02 01 30 07 06 05 2B 0E 03 02 1A 88 02 03 E8 83 07 6B 65 79 73 61 6C 74 84 04 31 32 33 34",decode_krb5_pa_otp_challenge,ktest_equal_pa_otp_challenge,k5_free_pa_otp_challenge); ktest_empty_pa_otp_challenge(&ref); } /****************************************************************/ /* decode_krb5_pa_otp_req */ { setup(krb5_pa_otp_req,ktest_make_minimal_pa_otp_req); decode_run("pa_otp_req","(optionals NULL)","30 2C 80 05 00 00 00 00 00 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_pa_otp_req,ktest_equal_pa_otp_req,k5_free_pa_otp_req); ktest_empty_pa_otp_req(&ref); } { setup(krb5_pa_otp_req,ktest_make_maximal_pa_otp_req); decode_run("pa_otp_req","","30 81 B9 80 05 00 60 00 00 00 81 05 6E 6F 6E 63 65 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 0B 06 09 60 86 48 01 65 03 04 02 01 84 02 03 E8 85 05 66 72 6F 67 73 86 0A 6D 79 66 69 72 73 74 70 69 6E 87 05 68 61 72 6B 21 88 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 89 03 33 34 36 8A 01 02 8B 09 79 6F 75 72 74 6F 6B 65 6E 8C 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 8D 0B 45 78 61 6D 70 6C 65 63 6F 72 70",decode_krb5_pa_otp_req,ktest_equal_pa_otp_req,k5_free_pa_otp_req); ktest_empty_pa_otp_req(&ref); } /****************************************************************/ /* decode_krb5_pa_otp_enc_req */ { setup(krb5_data,ktest_make_sample_data); decode_run("pa_otp_enc_req","","30 0A 80 08 6B 72 62 35 64 61 74 61",decode_krb5_pa_otp_enc_req,ktest_equal_data,krb5_free_data); ktest_empty_data(&ref); } /****************************************************************/ /* decode_krb5_kkdcp_message */ { setup(krb5_kkdcp_message,ktest_make_sample_kkdcp_message); decode_run("kkdcp_message","","30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61",decode_krb5_kkdcp_message,ktest_equal_kkdcp_message,ktest_free_kkdcp_message); ktest_empty_kkdcp_message(&ref); } /****************************************************************/ /* decode_krb5_cammac */ { setup(krb5_cammac,ktest_make_minimal_cammac); decode_run("cammac","(optionals NULL)","30 12 A0 10 30 0E 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31",decode_krb5_cammac,ktest_equal_cammac,k5_free_cammac); ktest_empty_cammac(&ref); } { setup(krb5_cammac,ktest_make_maximal_cammac); decode_run("cammac","","30 81 F2 A0 1E 30 1C 30 0C A0 03 02 01 01 A1 05 04 03 61 64 31 30 0C A0 03 02 01 02 A1 05 04 03 61 64 32 A1 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 6B 64 63 A2 3D 30 3B A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 13 30 11 A0 03 02 01 01 A1 0A 04 08 63 6B 73 75 6D 73 76 63 A3 52 30 50 30 13 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 31 30 39 A0 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A1 03 02 01 05 A2 03 02 01 10 A3 11 30 0F A0 03 02 01 01 A1 08 04 06 63 6B 73 75 6D 32",decode_krb5_cammac,ktest_equal_cammac,k5_free_cammac); ktest_empty_cammac(&ref); } /****************************************************************/ /* decode_krb5_secure_cookie */ { setup(krb5_secure_cookie,ktest_make_sample_secure_cookie); decode_run("secure_cookie","","30 2C 02 04 2D F8 02 25 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61",decode_krb5_secure_cookie,ktest_equal_secure_cookie,k5_free_secure_cookie); ktest_empty_secure_cookie(&ref); } /****************************************************************/ /* decode_krb5_spake_factor */ { setup(krb5_spake_factor,ktest_make_minimal_spake_factor); decode_run("spake_factor","(optionals NULL)","30 05 A0 03 02 01 01",decode_krb5_spake_factor,ktest_equal_spake_factor,k5_free_spake_factor); ktest_empty_spake_factor(&ref); } { setup(krb5_spake_factor,ktest_make_maximal_spake_factor); decode_run("spake_factor","","30 0E A0 03 02 01 02 A1 07 04 05 66 64 61 74 61",decode_krb5_spake_factor,ktest_equal_spake_factor,k5_free_spake_factor); ktest_empty_spake_factor(&ref); } /****************************************************************/ /* decode_krb5_pa_spake */ { setup(krb5_pa_spake,ktest_make_support_pa_spake); decode_run("pa_spake","(support)","A0 0C 30 0A A0 08 30 06 02 01 01 02 01 02",decode_krb5_pa_spake,ktest_equal_pa_spake,k5_free_pa_spake); ktest_empty_pa_spake(&ref); } { setup(krb5_pa_spake,ktest_make_challenge_pa_spake); decode_run("pa_spake","(challenge)","A1 2D 30 2B A0 03 02 01 01 A1 09 04 07 54 20 76 61 6C 75 65 A2 19 30 17 30 05 A0 03 02 01 01 30 0E A0 03 02 01 02 A1 07 04 05 66 64 61 74 61",decode_krb5_pa_spake,ktest_equal_pa_spake,k5_free_pa_spake); ktest_empty_pa_spake(&ref); } { setup(krb5_pa_spake,ktest_make_response_pa_spake); decode_run("pa_spake","(response)","A2 34 30 32 A0 09 04 07 53 20 76 61 6C 75 65 A1 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_pa_spake,ktest_equal_pa_spake,k5_free_pa_spake); ktest_empty_pa_spake(&ref); } { setup(krb5_pa_spake,ktest_make_encdata_pa_spake); decode_run("pa_spake","(encdata)","A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_pa_spake,ktest_equal_pa_spake,k5_free_pa_spake); ktest_empty_pa_spake(&ref); } #ifndef DISABLE_PKINIT /****************************************************************/ /* decode_krb5_pa_pk_as_req */ { setup(krb5_pa_pk_as_req,ktest_make_sample_pa_pk_as_req); decode_run("krb5_pa_pk_as_req","","30 38 80 08 6B 72 62 35 64 61 74 61 A1 22 30 20 30 1E 80 08 6B 72 62 35 64 61 74 61 81 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61 82 08 6B 72 62 35 64 61 74 61", acc.decode_krb5_pa_pk_as_req, ktest_equal_pa_pk_as_req,ktest_free_pa_pk_as_req); ktest_empty_pa_pk_as_req(&ref); } /****************************************************************/ /* decode_krb5_pa_pk_as_rep */ { setup(krb5_pa_pk_as_rep,ktest_make_sample_pa_pk_as_rep_dhInfo); decode_run("krb5_pa_pk_as_rep","(dhInfo)","A0 28 30 26 80 08 6B 72 62 35 64 61 74 61 A1 0A 04 08 6B 72 62 35 64 61 74 61 A2 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61", acc.decode_krb5_pa_pk_as_rep, ktest_equal_pa_pk_as_rep,ktest_free_pa_pk_as_rep); ktest_empty_pa_pk_as_rep(&ref); } { setup(krb5_pa_pk_as_rep,ktest_make_sample_pa_pk_as_rep_encKeyPack); decode_run("krb5_pa_pk_as_rep","(encKeyPack)","81 08 6B 72 62 35 64 61 74 61", acc.decode_krb5_pa_pk_as_rep, ktest_equal_pa_pk_as_rep,ktest_free_pa_pk_as_rep); ktest_empty_pa_pk_as_rep(&ref); } /****************************************************************/ /* decode_krb5_auth_pack */ { setup(krb5_auth_pack,ktest_make_sample_auth_pack); decode_run("krb5_auth_pack","","30 81 89 A0 39 30 37 A0 05 02 03 01 E2 40 A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 0A 04 08 6B 72 62 35 64 61 74 61 A1 08 04 06 70 76 61 6C 75 65 A2 24 30 22 30 13 06 09 2A 86 48 86 F7 12 01 02 02 04 06 70 61 72 61 6D 73 30 0B 06 09 2A 86 48 86 F7 12 01 02 02 A3 0A 04 08 6B 72 62 35 64 61 74 61 A4 10 30 0E 30 0C A0 0A 06 08 6B 72 62 35 64 61 74 61", acc.decode_krb5_auth_pack, ktest_equal_auth_pack,ktest_free_auth_pack); ktest_empty_auth_pack(&ref); } /****************************************************************/ /* decode_krb5_kdc_dh_key_info */ { setup(krb5_kdc_dh_key_info,ktest_make_sample_kdc_dh_key_info); decode_run("krb5_kdc_dh_key_info","","30 25 A0 0B 03 09 00 6B 72 62 35 64 61 74 61 A1 03 02 01 2A A2 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A", acc.decode_krb5_kdc_dh_key_info, ktest_equal_kdc_dh_key_info,ktest_free_kdc_dh_key_info); ktest_empty_kdc_dh_key_info(&ref); } /****************************************************************/ /* decode_krb5_reply_key_pack */ { setup(krb5_reply_key_pack,ktest_make_sample_reply_key_pack); decode_run("krb5_reply_key_pack","","30 26 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 0F 30 0D A0 03 02 01 01 A1 06 04 04 31 32 33 34", acc.decode_krb5_reply_key_pack, ktest_equal_reply_key_pack,ktest_free_reply_key_pack); ktest_empty_reply_key_pack(&ref); } /****************************************************************/ /* decode_krb5_principal_name */ /* We have no encoder for this type (KerberosName from RFC 4556); the * encoding is hand-generated. */ { krb5_principal ref, var; ktest_make_sample_principal(&ref); decode_run("krb5_principal_name","","30 2E A0 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61", acc.decode_krb5_principal_name,equal_principal,krb5_free_principal); ktest_destroy_principal(&ref); } #endif /* not DISABLE_PKINIT */ #ifdef ENABLE_LDAP /* ldap sequence_of_keys */ { setup(ldap_seqof_key_data,ktest_make_sample_ldap_seqof_key_data); decode_run("ldap_seqof_key_data","","30 81 87 A0 03 02 01 01 A1 03 02 01 01 A2 03 02 01 2A A3 03 02 01 0E A4 71 30 6F 30 23 A0 10 30 0E A0 03 02 01 00 A1 07 04 05 73 61 6C 74 30 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 30 30 23 A0 10 30 0E A0 03 02 01 01 A1 07 04 05 73 61 6C 74 31 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 31 30 23 A0 10 30 0E A0 03 02 01 02 A1 07 04 05 73 61 6C 74 32 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 32",acc.asn1_ldap_decode_sequence_of_keys,ktest_equal_ldap_sequence_of_keys,ktest_free_ldap_seqof_key_data); ktest_empty_ldap_seqof_key_data(&ref); } #endif krb5_free_context(test_context); exit(error_count); return(error_count); } void krb5_ktest_free_enc_data(krb5_context context, krb5_enc_data *val) { if (val) { krb5_free_data_contents(context, &(val->ciphertext)); free(val); } } #ifndef DISABLE_PKINIT /* Glue function to make ktest_equal_principal_data look like what decode_run * expects. */ static int equal_principal(krb5_principal *ref, krb5_principal var) { return ktest_equal_principal_data(*ref, var); } static void ktest_free_auth_pack(krb5_context context, krb5_auth_pack *val) { if (val) ktest_empty_auth_pack(val); free(val); } static void ktest_free_kdc_dh_key_info(krb5_context context, krb5_kdc_dh_key_info *val) { if (val) ktest_empty_kdc_dh_key_info(val); free(val); } static void ktest_free_pa_pk_as_req(krb5_context context, krb5_pa_pk_as_req *val) { if (val) ktest_empty_pa_pk_as_req(val); free(val); } static void ktest_free_pa_pk_as_rep(krb5_context context, krb5_pa_pk_as_rep *val) { if (val) ktest_empty_pa_pk_as_rep(val); free(val); } static void ktest_free_reply_key_pack(krb5_context context, krb5_reply_key_pack *val) { if (val) ktest_empty_reply_key_pack(val); free(val); } #endif /* not DISABLE_PKINIT */ #ifdef ENABLE_LDAP static void ktest_free_ldap_seqof_key_data(krb5_context context, ldap_seqof_key_data *val) { if (val) ktest_empty_ldap_seqof_key_data(val); free(val); } #endif /* ENABLE_LDAP */ static void ktest_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val) { if (val) ktest_empty_kkdcp_message(val); free(val); } krb5-1.22.1/src/tests/asn.1/ldap_encode.out0000664000175000017500000000067715051422640020212 0ustar ghudsonghudsonencode_krb5_ldap_seqof_key_data: 30 81 87 A0 03 02 01 01 A1 03 02 01 01 A2 03 02 01 2A A3 03 02 01 0E A4 71 30 6F 30 23 A0 10 30 0E A0 03 02 01 00 A1 07 04 05 73 61 6C 74 30 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 30 30 23 A0 10 30 0E A0 03 02 01 01 A1 07 04 05 73 61 6C 74 31 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 31 30 23 A0 10 30 0E A0 03 02 01 02 A1 07 04 05 73 61 6C 74 32 A1 0F 30 0D A0 03 02 01 02 A1 06 04 04 6B 65 79 32 krb5-1.22.1/src/tests/asn.1/make-vectors.c0000664000175000017500000003136615051422640017767 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/make-vectors.c - Generate ASN.1 test vectors using asn1c */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This program generates test vectors using asn1c, to be included in other * test programs which exercise the krb5 ASN.1 encoder and decoder functions. * It is intended to be used via "make test-vectors". Currently, test vectors * are only generated for a subset of newer ASN.1 objects. */ #include #include #include #include #include #include #include #include #include #include #include static unsigned char buf[8192]; static size_t buf_pos; /* PrincipalName and KRB5PrincipalName */ static KerberosString_t comp_1 = { "hftsai", 6 }; static KerberosString_t comp_2 = { "extra", 5 }; static KerberosString_t *comps[] = { &comp_1, &comp_2 }; static PrincipalName_t princ = { 1, { comps, 2, 2 } }; static KRB5PrincipalName_t krb5princ = { { "ATHENA.MIT.EDU", 14 }, { 1, { comps, 2, 2 } } }; /* OtherInfo */ static unsigned int krb5_arcs[] = { 1, 2, 840, 113554, 1, 2, 2 }; static OCTET_STRING_t krb5data_ostring = { "krb5data", 8 }; static OtherInfo_t other_info = { { 0 }, { 0 }, { 0 }, /* Initialized in main() */ &krb5data_ostring, NULL }; /* PkinitSuppPubInfo */ static PkinitSuppPubInfo_t supp_pub_info = { 1, { "krb5data", 8 }, { "krb5data", 8 } }; /* Minimal OTP-TOKENINFO */ static OTP_TOKENINFO_t token_info_1 = { { "\0\0\0\0", 4, 0 } }; /* Maximal OTP-TOKENINFO */ static UTF8String_t vendor = { "Examplecorp", 11 }; static OCTET_STRING_t challenge = { "hark!", 5 }; static Int32_t otp_length = 10; static OTPFormat_t otp_format; /* Initialized to 2 in main(). */ static OCTET_STRING_t token_id = { "yourtoken", 9 }; static AnyURI_t otp_alg = { "urn:ietf:params:xml:ns:keyprov:pskc:hotp", 40 }; static unsigned int sha256_arcs[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 }; static unsigned int sha1_arcs[] = { 1, 3, 14, 3, 2, 26 }; static AlgorithmIdentifier_t alg_sha256, alg_sha1; /* Initialized in main(). */ static AlgorithmIdentifier_t *algs[] = { &alg_sha256, &alg_sha1 }; static struct supportedHashAlg hash_algs = { algs, 2, 2 }; static Int32_t iter_count = 1000; /* Flags are nextOTP | combine | collect-pin | must-encrypt-nonce | * separate-pin-required | check-digit */ static OTP_TOKENINFO_t token_info_2 = { { "\x77\0\0\0", 4, 0 }, &vendor, &challenge, &otp_length, &otp_format, &token_id, &otp_alg, &hash_algs, &iter_count }; /* Minimal PA-OTP-CHALLENGE */ static OTP_TOKENINFO_t *tinfo_1[] = { &token_info_1 }; static PA_OTP_CHALLENGE_t challenge_1 = { { "minnonce", 8 }, NULL, { { tinfo_1, 1, 1 } } }; /* Maximal PA-OTP-CHALLENGE */ static OTP_TOKENINFO_t *tinfo_2[] = { &token_info_1, &token_info_2 }; static UTF8String_t service = { "testservice", 11 }; static KerberosString_t salt = { "keysalt", 7 }; static OCTET_STRING_t s2kparams = { "1234", 4 }; static PA_OTP_CHALLENGE_t challenge_2 = { { "maxnonce", 8 }, &service, { { tinfo_2, 2, 2 } }, &salt, &s2kparams }; /* Minimal PA-OTP-REQUEST */ static UInt32_t kvno = 5; static PA_OTP_REQUEST_t request_1 = { { "\0\0\0\0", 4, 0 }, NULL, { 0, &kvno, { "krbASN.1 test message", 21 } } }; /* Maximal PA-OTP-REQUEST */ /* Flags are nextOTP | combine */ static OCTET_STRING_t nonce = { "nonce", 5 }; static OCTET_STRING_t otp_value = { "frogs", 5 }; static UTF8String_t otp_pin = { "myfirstpin", 10 }; /* Corresponds to Unix time 771228197 */ static KerberosTime_t otp_time = { "19940610060317Z", 15 }; static OCTET_STRING_t counter = { "346", 3 }; static PA_OTP_REQUEST_t request_2 = { { "\x60\0\0\0", 4, 0 }, &nonce, { 0, &kvno, { "krbASN.1 test message", 21 } }, &alg_sha256, &iter_count, &otp_value, &otp_pin, &challenge, &otp_time, &counter, &otp_format, &token_id, &otp_alg, &vendor }; /* PA-OTP-ENC-REQUEST */ static PA_OTP_ENC_REQUEST_t enc_request = { { "krb5data", 8 } }; /* * There is no ASN.1 name for a single authorization data element, so asn1c * declares it as "struct Member" in an inner scope. This structure must be * laid out identically to that one. */ struct ad_element { Int32_t ad_type; OCTET_STRING_t ad_data; asn_struct_ctx_t _asn_ctx; }; /* Authorization data elements and lists, for use in CAMMAC */ static struct ad_element ad_1 = { 1, { "ad1", 3 } }; static struct ad_element ad_2 = { 2, { "ad2", 3 } }; static struct ad_element *adlist_1[] = { &ad_1 }; static struct ad_element *adlist_2[] = { &ad_1, &ad_2 }; /* Minimal Verifier */ static Verifier_t verifier_1 = { Verifier_PR_mac, { { NULL, NULL, NULL, { 1, { "cksum1", 6 } } } } }; /* Maximal Verifier */ static Int32_t enctype = 16; static Verifier_t verifier_2 = { Verifier_PR_mac, { { &princ, &kvno, &enctype, { 1, { "cksum2", 6 } } } } }; /* Minimal CAMMAC */ static AD_CAMMAC_t cammac_1 = { { { (void *)adlist_1, 1, 1 } }, NULL, NULL, NULL }; /* Maximal CAMMAC */ static Verifier_MAC_t vmac_1 = { &princ, &kvno, &enctype, { 1, { "cksumkdc", 8 } } }; static Verifier_MAC_t vmac_2 = { &princ, &kvno, &enctype, { 1, { "cksumsvc", 8 } } }; static Verifier_t *verifiers[] = { &verifier_1, &verifier_2 }; static struct other_verifiers overfs = { { verifiers, 2, 2 } }; static AD_CAMMAC_t cammac_2 = { { { (void *)adlist_2, 2, 2 } }, &vmac_1, &vmac_2, &overfs }; /* SPAKESecondFactor */ static SPAKESecondFactor_t factor_1 = { 1, NULL }; static OCTET_STRING_t factor_data = { "fdata", 5 }; static SPAKESecondFactor_t factor_2 = { 2, &factor_data }; /* PA-SPAKE (support) */ static Int32_t group_1 = 1, group_2 = 2, *groups[] = { &group_1, &group_2 }; static PA_SPAKE_t pa_spake_1 = { PA_SPAKE_PR_support, { .support = { { groups, 2, 2 } } } }; /* PA-SPAKE (challenge) */ static SPAKESecondFactor_t *factors[2] = { &factor_1, &factor_2 }; static PA_SPAKE_t pa_spake_2 = { PA_SPAKE_PR_challenge, { .challenge = { 1, { "T value", 7 }, { factors, 2, 2 } } } }; /* PA-SPAKE (response) */ UInt32_t enctype_5 = 5; static PA_SPAKE_t pa_spake_3 = { PA_SPAKE_PR_response, { .response = { { "S value", 7 }, { 0, &enctype_5, { "krbASN.1 test message", 21 } } } } }; /* PA-SPAKE (encdata) */ static PA_SPAKE_t pa_spake_4 = { PA_SPAKE_PR_encdata, { .encdata = { 0, &enctype_5, { "krbASN.1 test message", 21 } } } }; static int consume(const void *data, size_t size, void *dummy) { memcpy(buf + buf_pos, data, size); buf_pos += size; return 0; } /* Display a C string literal representing the contents of buf, and * reinitialize buf_pos for the next encoding operation. */ static void printbuf(void) { size_t i; for (i = 0; i < buf_pos; i++) { printf("%02X", buf[i]); if (i + 1 < buf_pos) printf(" "); } buf_pos = 0; } int main(void) { /* Initialize values which can't use static initializers. */ asn_long2INTEGER(&otp_format, 2); /* Alphanumeric */ OBJECT_IDENTIFIER_set_arcs(&alg_sha256.algorithm, sha256_arcs, sizeof(*sha256_arcs), sizeof(sha256_arcs) / sizeof(*sha256_arcs)); OBJECT_IDENTIFIER_set_arcs(&alg_sha1.algorithm, sha1_arcs, sizeof(*sha1_arcs), sizeof(sha1_arcs) / sizeof(*sha1_arcs)); OBJECT_IDENTIFIER_set_arcs(&other_info.algorithmID.algorithm, krb5_arcs, sizeof(*krb5_arcs), sizeof(krb5_arcs) / sizeof(*krb5_arcs)); printf("PrincipalName:\n"); der_encode(&asn_DEF_PrincipalName, &princ, consume, NULL); printbuf(); /* Print this encoding and also use it to initialize two fields of * other_info. */ printf("\nKRB5PrincipalName:\n"); der_encode(&asn_DEF_KRB5PrincipalName, &krb5princ, consume, NULL); OCTET_STRING_fromBuf(&other_info.partyUInfo, buf, buf_pos); OCTET_STRING_fromBuf(&other_info.partyVInfo, buf, buf_pos); printbuf(); printf("\nOtherInfo:\n"); der_encode(&asn_DEF_OtherInfo, &other_info, consume, NULL); printbuf(); free(other_info.partyUInfo.buf); free(other_info.partyVInfo.buf); printf("\nPkinitSuppPubInfo:\n"); der_encode(&asn_DEF_PkinitSuppPubInfo, &supp_pub_info, consume, NULL); printbuf(); printf("\nMinimal OTP-TOKEN-INFO:\n"); der_encode(&asn_DEF_OTP_TOKENINFO, &token_info_1, consume, NULL); printbuf(); printf("\nMaximal OTP-TOKEN-INFO:\n"); der_encode(&asn_DEF_OTP_TOKENINFO, &token_info_2, consume, NULL); printbuf(); printf("\nMinimal PA-OTP-CHALLENGE:\n"); der_encode(&asn_DEF_PA_OTP_CHALLENGE, &challenge_1, consume, NULL); printbuf(); printf("\nMaximal PA-OTP-CHALLENGE:\n"); der_encode(&asn_DEF_PA_OTP_CHALLENGE, &challenge_2, consume, NULL); printbuf(); printf("\nMinimal PA-OTP-REQUEST:\n"); der_encode(&asn_DEF_PA_OTP_REQUEST, &request_1, consume, NULL); printbuf(); printf("\nMaximal PA-OTP-REQUEST:\n"); der_encode(&asn_DEF_PA_OTP_REQUEST, &request_2, consume, NULL); printbuf(); printf("\nPA-OTP-ENC-REQUEST:\n"); der_encode(&asn_DEF_PA_OTP_ENC_REQUEST, &enc_request, consume, NULL); printbuf(); printf("\nMinimal Verifier:\n"); der_encode(&asn_DEF_Verifier, &verifier_1, consume, NULL); printbuf(); printf("\nMaximal Verifier:\n"); der_encode(&asn_DEF_Verifier, &verifier_2, consume, NULL); printbuf(); printf("\nMinimal AD-CAMMAC:\n"); der_encode(&asn_DEF_AD_CAMMAC, &cammac_1, consume, NULL); printbuf(); printf("\nMaximal AD-CAMMAC:\n"); der_encode(&asn_DEF_AD_CAMMAC, &cammac_2, consume, NULL); printbuf(); printf("\nMinimal SPAKESecondFactor:\n"); der_encode(&asn_DEF_SPAKESecondFactor, &factor_1, consume, NULL); printbuf(); printf("\nMaximal SPAKESecondFactor:\n"); der_encode(&asn_DEF_SPAKESecondFactor, &factor_2, consume, NULL); printbuf(); printf("\nPA-SPAKE (support):\n"); der_encode(&asn_DEF_PA_SPAKE, &pa_spake_1, consume, NULL); printbuf(); printf("\nPA-SPAKE (challenge):\n"); der_encode(&asn_DEF_PA_SPAKE, &pa_spake_2, consume, NULL); printbuf(); printf("\nPA-SPAKE (response):\n"); der_encode(&asn_DEF_PA_SPAKE, &pa_spake_3, consume, NULL); printbuf(); printf("\nPA-SPAKE (encdata):\n"); der_encode(&asn_DEF_PA_SPAKE, &pa_spake_4, consume, NULL); printbuf(); printf("\n"); return 0; } krb5-1.22.1/src/tests/asn.1/ktest_equal.h0000664000175000017500000001553015051422640017710 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/ktest_equal.h */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __KTEST_EQUAL_H__ #define __KTEST_EQUAL_H__ #include "k5-int.h" #include "k5-spake.h" #include "kdb.h" /* int ktest_equal_structure(krb5_structure *ref, *var) */ /* effects Returns true (non-zero) if ref and var are semantically equivalent (i.e. have the same values, but aren't necessarily the same object). Returns false (zero) if ref and var differ. */ #define generic(funcname,type)\ int funcname (type *ref, type *var) #define len_array(funcname,type)\ int funcname (int length, type *ref, type *var) #define len_unsigned_array(funcname,type)\ int funcname (unsigned int length, type *ref, type *var) generic(ktest_equal_authenticator,krb5_authenticator); generic(ktest_equal_principal_data,krb5_principal_data); generic(ktest_equal_checksum,krb5_checksum); generic(ktest_equal_keyblock,krb5_keyblock); generic(ktest_equal_data,krb5_data); generic(ktest_equal_authdata,krb5_authdata); generic(ktest_equal_ticket,krb5_ticket); generic(ktest_equal_enc_tkt_part,krb5_enc_tkt_part); generic(ktest_equal_transited,krb5_transited); generic(ktest_equal_ticket_times,krb5_ticket_times); generic(ktest_equal_address,krb5_address); generic(ktest_equal_enc_data,krb5_enc_data); generic(ktest_equal_enc_kdc_rep_part,krb5_enc_kdc_rep_part); generic(ktest_equal_priv,krb5_priv); generic(ktest_equal_cred,krb5_cred); generic(ktest_equal_error,krb5_error); generic(ktest_equal_ap_req,krb5_ap_req); generic(ktest_equal_ap_rep,krb5_ap_rep); generic(ktest_equal_ap_rep_enc_part,krb5_ap_rep_enc_part); generic(ktest_equal_safe,krb5_safe); generic(ktest_equal_last_req_entry,krb5_last_req_entry); generic(ktest_equal_pa_data,krb5_pa_data); generic(ktest_equal_cred_info,krb5_cred_info); generic(ktest_equal_enc_cred_part,krb5_cred_enc_part); generic(ktest_equal_enc_priv_part,krb5_priv_enc_part); generic(ktest_equal_as_rep,krb5_kdc_rep); generic(ktest_equal_tgs_rep,krb5_kdc_rep); generic(ktest_equal_as_req,krb5_kdc_req); generic(ktest_equal_tgs_req,krb5_kdc_req); generic(ktest_equal_kdc_req_body,krb5_kdc_req); generic(ktest_equal_encryption_key,krb5_keyblock); generic(ktest_equal_krb5_pa_enc_ts,krb5_pa_enc_ts); generic(ktest_equal_sam_challenge_2,krb5_sam_challenge_2); generic(ktest_equal_sam_challenge_2_body,krb5_sam_challenge_2_body); int ktest_equal_last_req(krb5_last_req_entry **ref, krb5_last_req_entry **var); int ktest_equal_sequence_of_ticket(krb5_ticket **ref, krb5_ticket **var); int ktest_equal_sequence_of_pa_data(krb5_pa_data **ref, krb5_pa_data **var); int ktest_equal_sequence_of_cred_info(krb5_cred_info **ref, krb5_cred_info **var); int ktest_equal_sequence_of_principal(krb5_principal *ref, krb5_principal *var); int ktest_equal_sequence_of_checksum(krb5_checksum **ref, krb5_checksum **var); int ktest_equal_sequence_of_algorithm_identifier(krb5_algorithm_identifier **ref, krb5_algorithm_identifier **var); int ktest_equal_sequence_of_otp_tokeninfo(krb5_otp_tokeninfo **ref, krb5_otp_tokeninfo **var); int ktest_equal_sequence_of_spake_factor(krb5_spake_factor **ref, krb5_spake_factor **var); len_array(ktest_equal_array_of_enctype,krb5_enctype); len_array(ktest_equal_array_of_data,krb5_data); len_unsigned_array(ktest_equal_array_of_octet,krb5_octet); int ktest_equal_authorization_data(krb5_authdata **ref, krb5_authdata **var); int ktest_equal_addresses(krb5_address **ref, krb5_address **var); int ktest_equal_array_of_char(const unsigned int length, char *ref, char *var); int ktest_equal_etype_info(krb5_etype_info_entry **ref, krb5_etype_info_entry **var); int ktest_equal_krb5_etype_info_entry(krb5_etype_info_entry *ref, krb5_etype_info_entry *var); int ktest_equal_pa_for_user(krb5_pa_for_user *ref, krb5_pa_for_user *var); int ktest_equal_pa_s4u_x509_user(krb5_pa_s4u_x509_user *ref, krb5_pa_s4u_x509_user *var); int ktest_equal_ad_kdcissued(krb5_ad_kdcissued *ref, krb5_ad_kdcissued *var); int ktest_equal_iakerb_header(krb5_iakerb_header *ref, krb5_iakerb_header *var); int ktest_equal_iakerb_finished(krb5_iakerb_finished *ref, krb5_iakerb_finished *var); int ktest_equal_fast_response(krb5_fast_response *ref, krb5_fast_response *var); int ktest_equal_otp_tokeninfo(krb5_otp_tokeninfo *ref, krb5_otp_tokeninfo *var); int ktest_equal_pa_otp_challenge(krb5_pa_otp_challenge *ref, krb5_pa_otp_challenge *var); int ktest_equal_pa_otp_req(krb5_pa_otp_req *ref, krb5_pa_otp_req *var); int ktest_equal_ldap_sequence_of_keys(ldap_seqof_key_data *ref, ldap_seqof_key_data *var); #ifndef DISABLE_PKINIT generic(ktest_equal_pa_pk_as_req, krb5_pa_pk_as_req); generic(ktest_equal_pa_pk_as_rep, krb5_pa_pk_as_rep); generic(ktest_equal_auth_pack, krb5_auth_pack); generic(ktest_equal_kdc_dh_key_info, krb5_kdc_dh_key_info); generic(ktest_equal_reply_key_pack, krb5_reply_key_pack); #endif /* not DISABLE_PKINIT */ int ktest_equal_kkdcp_message(krb5_kkdcp_message *ref, krb5_kkdcp_message *var); int ktest_equal_cammac(krb5_cammac *ref, krb5_cammac *var); int ktest_equal_secure_cookie(krb5_secure_cookie *ref, krb5_secure_cookie *var); generic(ktest_equal_spake_factor, krb5_spake_factor); generic(ktest_equal_pa_spake, krb5_pa_spake); #endif krb5-1.22.1/src/tests/asn.1/utility.c0000664000175000017500000000707215051422640017067 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/asn.1/utility.c */ /* * Copyright (C) 1994 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "utility.h" #include "krb5.h" #include #include #include krb5int_access acc; char hexchar (const unsigned int digit); void * ealloc(size_t size) { void *ptr = calloc(1, size); if (ptr == NULL) abort(); return ptr; } char * estrdup(const char *str) { char *newstr = strdup(str); if (newstr == NULL) abort(); return newstr; } void asn1_krb5_data_unparse(const krb5_data *code, char **s) { if (*s != NULL) free(*s); if (code==NULL) { *s = estrdup(""); } else if (code->data == NULL || ((int) code->length) <= 0) { *s = estrdup(""); } else { unsigned int i; *s = ealloc(3 * code->length); for (i = 0; i < code->length; i++) { (*s)[3*i] = hexchar((unsigned char) (((code->data)[i]&0xF0)>>4)); (*s)[3*i+1] = hexchar((unsigned char) ((code->data)[i]&0x0F)); (*s)[3*i+2] = ' '; } (*s)[3*(code->length)-1] = '\0'; } } char hexchar(const unsigned int digit) { if (digit<=9) return '0'+digit; else if (digit<=15) return 'A'+digit-10; else return 'X'; } void krb5_data_parse(krb5_data *d, const char *s) { d->length = strlen(s); d->data = ealloc(d->length); memcpy(d->data, s, d->length); } krb5_error_code krb5_data_hex_parse(krb5_data *d, const char *s) { int lo; long v; const char *cp; char *dp; char buf[2]; d->data = ealloc(strlen(s) / 2 + 1); d->length = 0; buf[1] = '\0'; for (lo = 0, dp = d->data, cp = s; *cp; cp++) { if (*cp < 0) return ASN1_PARSE_ERROR; else if (isspace((unsigned char) *cp)) continue; else if (isxdigit((unsigned char) *cp)) { buf[0] = *cp; v = strtol(buf, NULL, 16); } else return ASN1_PARSE_ERROR; if (lo) { *dp++ |= v; lo = 0; } else { *dp = v << 4; lo = 1; } } d->length = dp - d->data; return 0; } void init_access(const char *progname) { krb5_error_code ret; ret = krb5int_accessor(&acc, KRB5INT_ACCESS_VERSION); if (ret) { com_err(progname, ret, "while initializing accessor"); exit(1); } } krb5-1.22.1/src/tests/asn.1/trval_reference.out0000664000175000017500000015417415051422640021125 0ustar ghudsonghudsonencode_krb5_authenticator: [Krb5 Authenticator] . [Sequence/Sequence Of] . . [authenticator-vno] [Integer] 5 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [cksum] [Sequence/Sequence Of] . . . [cksumtype] [Integer] 1 . . . [checksum] [Octet String] "1234" . . [cusec] [Integer] 123456 . . [ctime] [Generalized Time] "19940610060317Z" . . [subkey] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [seq-number] [Integer] 17 . . [authorization-data] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [ad-type] [Integer] 1 . . . . [ad-data] [Octet String] "foobar" . . . [Sequence/Sequence Of] . . . . [ad-type] [Integer] 1 . . . . [ad-data] [Octet String] "foobar" encode_krb5_authenticator(optionals empty): [Krb5 Authenticator] . [Sequence/Sequence Of] . . [authenticator-vno] [Integer] 5 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [cusec] [Integer] 123456 . . [ctime] [Generalized Time] "19940610060317Z" encode_krb5_authenticator(optionals NULL): [Krb5 Authenticator] . [Sequence/Sequence Of] . . [authenticator-vno] [Integer] 5 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [cusec] [Integer] 123456 . . [ctime] [Generalized Time] "19940610060317Z" encode_krb5_ticket: [Krb5 Ticket] . [Sequence/Sequence Of] . . [tkt-vno] [Integer] 5 . . [realm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [tkt-enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_keyblock: [Sequence/Sequence Of] . [keytype] [Integer] 1 . [keyvalue] [Octet String] "12345678" encode_krb5_enc_tkt_part: [Krb5 Encrypted ticket part] . [Sequence/Sequence Of] . . [flags] [Bit String] 0xfedcba98 . . [key] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [transited] [Sequence/Sequence Of] . . . [flags] [Integer] 1 . . . [key] [Octet String] "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS." . . [authtime] [Generalized Time] "19940610060317Z" . . [starttime] [Generalized Time] "19940610060317Z" . . [endtime] [Generalized Time] "19940610060317Z" . . [renew-till] [Generalized Time] "19940610060317Z" . . [caddr] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [authorization-data] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [ad-type] [Integer] 1 . . . . [ad-data] [Octet String] "foobar" . . . [Sequence/Sequence Of] . . . . [ad-type] [Integer] 1 . . . . [ad-data] [Octet String] "foobar" encode_krb5_enc_tkt_part(optionals NULL): [Krb5 Encrypted ticket part] . [Sequence/Sequence Of] . . [flags] [Bit String] 0xfedcba98 . . [key] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [transited] [Sequence/Sequence Of] . . . [flags] [Integer] 1 . . . [key] [Octet String] "EDU,MIT.,ATHENA.,WASHINGTON.EDU,CS." . . [authtime] [Generalized Time] "19940610060317Z" . . [endtime] [Generalized Time] "19940610060317Z" encode_krb5_enc_kdc_rep_part: [Krb5 Encrypted TGS-REP part] . [Sequence/Sequence Of] . . [key] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [last-req] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [lr-type] [Integer] -5 . . . . [lr-value] [Generalized Time] "19940610060317Z" . . . [Sequence/Sequence Of] . . . . [lr-type] [Integer] -5 . . . . [lr-value] [Generalized Time] "19940610060317Z" . . [nonce] [Integer] 42 . . [key-expiration] [Generalized Time] "19940610060317Z" . . [flags] [Bit String] 0xfedcba98 . . [authtime] [Generalized Time] "19940610060317Z" . . [starttime] [Generalized Time] "19940610060317Z" . . [enddtime] [Generalized Time] "19940610060317Z" . . [renew-till] [Generalized Time] "19940610060317Z" . . [srealm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [caddr] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_enc_kdc_rep_part(optionals NULL): [Krb5 Encrypted TGS-REP part] . [Sequence/Sequence Of] . . [key] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [last-req] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [lr-type] [Integer] -5 . . . . [lr-value] [Generalized Time] "19940610060317Z" . . . [Sequence/Sequence Of] . . . . [lr-type] [Integer] -5 . . . . [lr-value] [Generalized Time] "19940610060317Z" . . [nonce] [Integer] 42 . . [flags] [Bit String] 0xfe5cba98 . . [authtime] [Generalized Time] "19940610060317Z" . . [enddtime] [Generalized Time] "19940610060317Z" . . [srealm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" encode_krb5_as_rep: [Krb5 AS-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 11 . . [padata] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_as_rep(optionals NULL): [Krb5 AS-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 11 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_tgs_rep: [Krb5 TGS-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 13 . . [padata] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_tgs_rep(optionals NULL): [Krb5 TGS-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 13 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_ap_req: [Krb5 AP-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 14 . . [ap-options] [Bit String] 0xfedcba98 . . [ticket] [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [authenticator] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_ap_rep: [Krb5 AP-REP packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 15 . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_ap_rep_enc_part: [Krb5 Encrypted AP-REP part] . [Sequence/Sequence Of] . . [ctime] [Generalized Time] "19940610060317Z" . . [cusec] [Integer] 123456 . . [subkey] [Sequence/Sequence Of] . . . [keytype] [Integer] 1 . . . [keyvalue] [Octet String] "12345678" . . [seq-number] [Integer] 17 encode_krb5_ap_rep_enc_part(optionals NULL): [Krb5 Encrypted AP-REP part] . [Sequence/Sequence Of] . . [ctime] [Generalized Time] "19940610060317Z" . . [cusec] [Integer] 123456 encode_krb5_as_req: [Krb5 AS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 10 . . [padata] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba90 . . . [cname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [sname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [from] [Generalized Time] "19940610060317Z" . . . [till] [Generalized Time] "19940610060317Z" . . . [rtime] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 . . . [addresses] [Sequence/Sequence Of] . . . . [Sequence/Sequence Of] . . . . . [addr-type] [Integer] 2 . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . [Sequence/Sequence Of] . . . . . [addr-type] [Integer] 2 . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [enc-authorization-data] [Sequence/Sequence Of] . . . . [etype] [Integer] 0 . . . . [kvno] [Integer] 5 . . . . [cipher] [Octet String] "krbASN.1 test message" . . . [additional-tickets] [Sequence/Sequence Of] . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_as_req(optionals NULL except second_ticket): [Krb5 AS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 10 . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba98 . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [till] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 . . . [additional-tickets] [Sequence/Sequence Of] . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_as_req(optionals NULL except server): [Krb5 AS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 10 . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba90 . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [sname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [till] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 encode_krb5_tgs_req: [Krb5 TGS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 12 . . [padata] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . . [Sequence/Sequence Of] . . . . [padata-type] [Integer] 13 . . . . [pa-data] [Octet String] "pa-data" . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba90 . . . [cname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [sname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [from] [Generalized Time] "19940610060317Z" . . . [till] [Generalized Time] "19940610060317Z" . . . [rtime] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 . . . [addresses] [Sequence/Sequence Of] . . . . [Sequence/Sequence Of] . . . . . [addr-type] [Integer] 2 . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . [Sequence/Sequence Of] . . . . . [addr-type] [Integer] 2 . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [enc-authorization-data] [Sequence/Sequence Of] . . . . [etype] [Integer] 0 . . . . [kvno] [Integer] 5 . . . . [cipher] [Octet String] "krbASN.1 test message" . . . [additional-tickets] [Sequence/Sequence Of] . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_tgs_req(optionals NULL except second_ticket): [Krb5 TGS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 12 . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba98 . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [till] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 . . . [additional-tickets] [Sequence/Sequence Of] . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . . [Krb5 Ticket] . . . . . [Sequence/Sequence Of] . . . . . . [tkt-vno] [Integer] 5 . . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . . [sname] [Sequence/Sequence Of] . . . . . . . [name-type] [Integer] 1 . . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . . [General string] "hftsai" . . . . . . . . [General string] "extra" . . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . . [etype] [Integer] 0 . . . . . . . [kvno] [Integer] 5 . . . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_tgs_req(optionals NULL except server): [Krb5 TGS-REQ packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 12 . . [req-body] [Sequence/Sequence Of] . . . [kdc-options] [Bit String] 0xfedcba90 . . . [realm] [General string] "ATHENA.MIT.EDU" . . . [sname] [Sequence/Sequence Of] . . . . [name-type] [Integer] 1 . . . . [name-string] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [till] [Generalized Time] "19940610060317Z" . . . [nonce] [Integer] 42 . . . [etype] [Sequence/Sequence Of] . . . . [Integer] 0 . . . . [Integer] 1 encode_krb5_kdc_req_body: [Sequence/Sequence Of] . [kdc-options] [Bit String] 0xfedcba90 . [cname] [Sequence/Sequence Of] . . [name-type] [Integer] 1 . . [name-string] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [realm] [General string] "ATHENA.MIT.EDU" . [sname] [Sequence/Sequence Of] . . [name-type] [Integer] 1 . . [name-string] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [from] [Generalized Time] "19940610060317Z" . [till] [Generalized Time] "19940610060317Z" . [rtime] [Generalized Time] "19940610060317Z" . [nonce] [Integer] 42 . [etype] [Sequence/Sequence Of] . . [Integer] 0 . . [Integer] 1 . [addresses] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# . [enc-authorization-data] [Sequence/Sequence Of] . . [etype] [Integer] 0 . . [kvno] [Integer] 5 . . [cipher] [Octet String] "krbASN.1 test message" . [additional-tickets] [Sequence/Sequence Of] . . [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_kdc_req_body(optionals NULL except second_ticket): [Sequence/Sequence Of] . [kdc-options] [Bit String] 0xfedcba98 . [realm] [General string] "ATHENA.MIT.EDU" . [till] [Generalized Time] "19940610060317Z" . [nonce] [Integer] 42 . [etype] [Sequence/Sequence Of] . . [Integer] 0 . . [Integer] 1 . [additional-tickets] [Sequence/Sequence Of] . . [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [Krb5 Ticket] . . . [Sequence/Sequence Of] . . . . [tkt-vno] [Integer] 5 . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . [etype] [Integer] 0 . . . . . [kvno] [Integer] 5 . . . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_kdc_req_body(optionals NULL except server): [Sequence/Sequence Of] . [kdc-options] [Bit String] 0xfedcba90 . [realm] [General string] "ATHENA.MIT.EDU" . [sname] [Sequence/Sequence Of] . . [name-type] [Integer] 1 . . [name-string] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [till] [Generalized Time] "19940610060317Z" . [nonce] [Integer] 42 . [etype] [Sequence/Sequence Of] . . [Integer] 0 . . [Integer] 1 encode_krb5_safe: [Krb5 SAFE packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 20 . . [safe-body] [Sequence/Sequence Of] . . . [user-data] [Octet String] "krb5data" . . . [timestamp] [Generalized Time] "19940610060317Z" . . . [usec] [Integer] 123456 . . . [seq-number] [Integer] 17 . . . [s-address] [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [r-address] [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [cksum] [Sequence/Sequence Of] . . . [cksumtype] [Integer] 1 . . . [checksum] [Octet String] "1234" encode_krb5_safe(optionals NULL): [Krb5 SAFE packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 20 . . [safe-body] [Sequence/Sequence Of] . . . [user-data] [Octet String] "krb5data" . . . [s-address] [Sequence/Sequence Of] . . . . [addr-type] [Integer] 2 . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [cksum] [Sequence/Sequence Of] . . . [cksumtype] [Integer] 1 . . . [checksum] [Octet String] "1234" encode_krb5_priv: [Krb5 PRIV packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 21 . . [3] [Sequence/Sequence Of] . . . [pvno] [Integer] 0 . . . [msg-type] [Integer] 5 . . . [enc-part] [Octet String] "krbASN.1 test message" encode_krb5_enc_priv_part: [Krb5 Encrypted PRIV part] . [Sequence/Sequence Of] . . [user-data] [Octet String] "krb5data" . . [timestamp] [Generalized Time] "19940610060317Z" . . [usec] [Integer] 123456 . . [seq-number] [Integer] 17 . . [s-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [r-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_enc_priv_part(optionals NULL): [Krb5 Encrypted PRIV part] . [Sequence/Sequence Of] . . [user-data] [Octet String] "krb5data" . . [s-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_cred: [Krb5 CRED packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 22 . . [tickets] [Sequence/Sequence Of] . . . [Krb5 Ticket] . . . . [Sequence/Sequence Of] . . . . . [tkt-vno] [Integer] 5 . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . [sname] [Sequence/Sequence Of] . . . . . . [name-type] [Integer] 1 . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . [General string] "hftsai" . . . . . . . [General string] "extra" . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . [etype] [Integer] 0 . . . . . . [kvno] [Integer] 5 . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . . [Krb5 Ticket] . . . . [Sequence/Sequence Of] . . . . . [tkt-vno] [Integer] 5 . . . . . [realm] [General string] "ATHENA.MIT.EDU" . . . . . [sname] [Sequence/Sequence Of] . . . . . . [name-type] [Integer] 1 . . . . . . [name-string] [Sequence/Sequence Of] . . . . . . . [General string] "hftsai" . . . . . . . [General string] "extra" . . . . . [tkt-enc-part] [Sequence/Sequence Of] . . . . . . [etype] [Integer] 0 . . . . . . [kvno] [Integer] 5 . . . . . . [cipher] [Octet String] "krbASN.1 test message" . . [enc-part] [Sequence/Sequence Of] . . . [etype] [Integer] 0 . . . [kvno] [Integer] 5 . . . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_enc_cred_part: [Krb5 Encrypted CRED part] . [Sequence/Sequence Of] . . [ticket-info] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [key] [Sequence/Sequence Of] . . . . . [keytype] [Integer] 1 . . . . . [keyvalue] [Octet String] "12345678" . . . . [prealm] [General string] "ATHENA.MIT.EDU" . . . . [pname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [flags] [Bit String] 0xfedcba98 . . . . [authtime] [Generalized Time] "19940610060317Z" . . . . [startime] [Generalized Time] "19940610060317Z" . . . . [endtime] [Generalized Time] "19940610060317Z" . . . . [renew-till] [Generalized Time] "19940610060317Z" . . . . [srealm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [caddr] [Sequence/Sequence Of] . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . [Sequence/Sequence Of] . . . . [key] [Sequence/Sequence Of] . . . . . [keytype] [Integer] 1 . . . . . [keyvalue] [Octet String] "12345678" . . . . [prealm] [General string] "ATHENA.MIT.EDU" . . . . [pname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [flags] [Bit String] 0xfedcba98 . . . . [authtime] [Generalized Time] "19940610060317Z" . . . . [startime] [Generalized Time] "19940610060317Z" . . . . [endtime] [Generalized Time] "19940610060317Z" . . . . [renew-till] [Generalized Time] "19940610060317Z" . . . . [srealm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [caddr] [Sequence/Sequence Of] . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [nonce] [Integer] 42 . . [timestamp] [Generalized Time] "19940610060317Z" . . [usec] [Integer] 123456 . . [s-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . [r-address] [Sequence/Sequence Of] . . . [addr-type] [Integer] 2 . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_enc_cred_part(optionals NULL): [Krb5 Encrypted CRED part] . [Sequence/Sequence Of] . . [ticket-info] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [key] [Sequence/Sequence Of] . . . . . [keytype] [Integer] 1 . . . . . [keyvalue] [Octet String] "12345678" . . . [Sequence/Sequence Of] . . . . [key] [Sequence/Sequence Of] . . . . . [keytype] [Integer] 1 . . . . . [keyvalue] [Octet String] "12345678" . . . . [prealm] [General string] "ATHENA.MIT.EDU" . . . . [pname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [flags] [Bit String] 0xfedcba98 . . . . [authtime] [Generalized Time] "19940610060317Z" . . . . [startime] [Generalized Time] "19940610060317Z" . . . . [endtime] [Generalized Time] "19940610060317Z" . . . . [renew-till] [Generalized Time] "19940610060317Z" . . . . [srealm] [General string] "ATHENA.MIT.EDU" . . . . [sname] [Sequence/Sequence Of] . . . . . [name-type] [Integer] 1 . . . . . [name-string] [Sequence/Sequence Of] . . . . . . [General string] "hftsai" . . . . . . [General string] "extra" . . . . [caddr] [Sequence/Sequence Of] . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# . . . . . [Sequence/Sequence Of] . . . . . . [addr-type] [Integer] 2 . . . . . . [address] [Octet String] <4> 12 d0 00 23 ...# encode_krb5_error: [Krb5 ERROR packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 30 . . [ctime] [Generalized Time] "19940610060317Z" . . [cusec] [Integer] 123456 . . [stime] [Generalized Time] "19940610060317Z" . . [susec] [Integer] 123456 . . [error-code] [Integer] 60 . . [crealm] [General string] "ATHENA.MIT.EDU" . . [cname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [realm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [e-text] [General string] "krb5data" . . [e-data] [Octet String] "krb5data" encode_krb5_error(optionals NULL): [Krb5 ERROR packet] . [Sequence/Sequence Of] . . [pvno] [Integer] 5 . . [msg-type] [Integer] 30 . . [cusec] [Integer] 123456 . . [stime] [Generalized Time] "19940610060317Z" . . [susec] [Integer] 123456 . . [error-code] [Integer] 60 . . [realm] [General string] "ATHENA.MIT.EDU" . . [sname] [Sequence/Sequence Of] . . . [name-type] [Integer] 1 . . . [name-string] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" encode_krb5_authorization_data: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [ad-type] [Integer] 1 . . [ad-data] [Octet String] "foobar" . [Sequence/Sequence Of] . . [ad-type] [Integer] 1 . . [ad-data] [Octet String] "foobar" encode_krb5_padata_sequence: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [1] [Integer] 13 . . [2] [Octet String] "pa-data" . [Sequence/Sequence Of] . . [1] [Integer] 13 . . [2] [Octet String] "pa-data" encode_krb5_typed_data: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 13 . . [1] [Octet String] "pa-data" . [Sequence/Sequence Of] . . [0] [Integer] 13 . . [1] [Octet String] "pa-data" encode_krb5_padata_sequence(empty): [Sequence/Sequence Of] encode_krb5_etype_info: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 0 . . [1] [Octet String] "Morton's #0" . [Sequence/Sequence Of] . . [0] [Integer] 1 . [Sequence/Sequence Of] . . [0] [Integer] 2 . . [1] [Octet String] "Morton's #2" encode_krb5_etype_info(only 1): [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 0 . . [1] [Octet String] "Morton's #0" encode_krb5_etype_info(no info): [Sequence/Sequence Of] encode_krb5_etype_info2: [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 0 . . [1] [General string] "Morton's #0" . . [2] [Octet String] "s2k: 0" . [Sequence/Sequence Of] . . [0] [Integer] 1 . . [2] [Octet String] "s2k: 1" . [Sequence/Sequence Of] . . [0] [Integer] 2 . . [1] [General string] "Morton's #2" . . [2] [Octet String] "s2k: 2" encode_krb5_etype_info2(only 1): [Sequence/Sequence Of] . [Sequence/Sequence Of] . . [0] [Integer] 0 . . [1] [General string] "Morton's #0" . . [2] [Octet String] "s2k: 0" encode_krb5_pa_enc_ts: [Sequence/Sequence Of] . [0] [Generalized Time] "19940610060317Z" . [1] [Integer] 123456 encode_krb5_pa_enc_ts (no usec): [Sequence/Sequence Of] . [0] [Generalized Time] "19940610060317Z" encode_krb5_enc_data: [Sequence/Sequence Of] . [etype] [Integer] 0 . [kvno] [Integer] 5 . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_enc_data(MSB-set kvno): [Sequence/Sequence Of] . [etype] [Integer] 0 . [kvno] [Integer] -16777216 . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_enc_data(kvno=-1): [Sequence/Sequence Of] . [etype] [Integer] 0 . [kvno] [Integer] -1 . [cipher] [Octet String] "krbASN.1 test message" encode_krb5_sam_challenge_2: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [Octet String] "challenge" . [1] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "1234" encode_krb5_sam_challenge_2_body: [Sequence/Sequence Of] . [0] [Integer] 42 . [1] [Bit String] 0x80000000 . [2] [Octet String] "type name" . [4] [Octet String] "challenge label" . [5] [Octet String] "challenge ipse" . [6] [Octet String] "response_prompt ipse" . [8] [Integer] 5517840 . [9] [Integer] 20 encode_krb5_sam_response_2: [Sequence/Sequence Of] . [0] [Integer] 43 . [1] [Bit String] 0x80000000 . [2] [Octet String] "track data" . [3] [Sequence/Sequence Of] . . [0] [Integer] 20 . . [1] [Integer] 3382 . . [2] [Octet String] "nonce or sad" . [4] [Integer] 5517840 encode_krb5_enc_sam_response_enc_2: [Sequence/Sequence Of] . [0] [Integer] 88 . [1] [Octet String] "enc_sam_response_enc_2" encode_krb5_pa_for_user: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [1] [General string] "ATHENA.MIT.EDU" . [2] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" . [3] [General string] "krb5data" encode_krb5_pa_s4u_x509_user: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 13243546 . . [1] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [2] [General string] "ATHENA.MIT.EDU" . . [3] [Octet String] "pa_s4u_x509_user" . . [4] [Bit String] 0x80000000 . [1] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" encode_krb5_ad_kdcissued: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" . [1] [General string] "ATHENA.MIT.EDU" . [2] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Sequence/Sequence Of] . . . [General string] "hftsai" . . . [General string] "extra" . [3] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "foobar" . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "foobar" encode_krb5_iakerb_header: [Sequence/Sequence Of] . [1] [UTF8String] "krb5data" . [2] [Octet String] "krb5data" encode_krb5_iakerb_finished: [Sequence/Sequence Of] . [1] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "1234" encode_krb5_fast_response: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" . [1] [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "12345678" . [2] [Sequence/Sequence Of] . . [0] [Generalized Time] "19940610060317Z" . . [1] [Integer] 123456 . . [2] [General string] "ATHENA.MIT.EDU" . . [3] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [4] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "1234" . [3] [Integer] 42 encode_krb5_pa_fx_fast_reply: [CONT 0] . [Sequence/Sequence Of] . . [0] [Sequence/Sequence Of] . . . [0] [Integer] 0 . . . [1] [Integer] 5 . . . [2] [Octet String] "krbASN.1 test message" encode_krb5_otp_tokeninfo(optionals NULL): [Sequence/Sequence Of] . [0] <5> 00 00 00 00 00 ..... encode_krb5_otp_tokeninfo: [Sequence/Sequence Of] . [0] <5> 00 77 00 00 00 .w... . [1] <11> 45 78 61 6d 70 6c 65 63 6f 72 70 Examplecorp . [2] <5> 68 61 72 6b 21 hark! . [3] 0x0 (10 unused bits) . [4] <1> 02 . . [5] <9> 79 6f 75 72 74 6f 6b 65 6e yourtoken . [6] <40> 75 72 6e 3a 69 65 74 66 3a 70 61 72 61 6d 73 3a urn:ietf:params: 78 6d 6c 3a 6e 73 3a 6b 65 79 70 72 6f 76 3a 70 xml:ns:keyprov:p 73 6b 63 3a 68 6f 74 70 skc:hotp . [7] [Sequence/Sequence Of] . . [Object Identifier] <9> 60 86 48 01 65 03 04 02 01 `.H.e.... . [Sequence/Sequence Of] . . [Object Identifier] <5> 2b 0e 03 02 1a +.... . [8] <2> 03 e8 .. encode_krb5_pa_otp_challenge(optionals NULL): [Sequence/Sequence Of] . [0] <8> 6d 69 6e 6e 6f 6e 63 65 minnonce . [2] [Sequence/Sequence Of] . . [0] <5> 00 00 00 00 00 ..... encode_krb5_pa_otp_challenge: [Sequence/Sequence Of] . [0] <8> 6d 61 78 6e 6f 6e 63 65 maxnonce . [1] <11> 74 65 73 74 73 65 72 76 69 63 65 testservice . [2] [Sequence/Sequence Of] . . [0] <5> 00 00 00 00 00 ..... . [Sequence/Sequence Of] . . [0] <5> 00 77 00 00 00 .w... . . [1] <11> 45 78 61 6d 70 6c 65 63 6f 72 70 Examplecorp . . [2] <5> 68 61 72 6b 21 hark! . . [3] 0x0 (10 unused bits) . . [4] <1> 02 . . . [5] <9> 79 6f 75 72 74 6f 6b 65 6e yourtoken . . [6] <40> 75 72 6e 3a 69 65 74 66 3a 70 61 72 61 6d 73 urn:ietf:params 3a 78 6d 6c 3a 6e 73 3a 6b 65 79 70 72 6f 76 :xml:ns:keyprov 3a 70 73 6b 63 3a 68 6f 74 70 :pskc:hotp . . [7] [Sequence/Sequence Of] . . . [Object Identifier] <9> 60 86 48 01 65 03 04 02 01 `.H.e.... . . [Sequence/Sequence Of] . . . [Object Identifier] <5> 2b 0e 03 02 1a +.... . . [8] <2> 03 e8 .. . [3] <7> 6b 65 79 73 61 6c 74 keysalt . [4] "1234" encode_krb5_pa_otp_req(optionals NULL): [Sequence/Sequence Of] . [0] <5> 00 00 00 00 00 ..... . [2] [0] [Integer] 0 . [1] [Integer] 5 . [2] [Octet String] "krbASN.1 test message" encode_krb5_pa_otp_req: [Sequence/Sequence Of] . [0] <5> 00 60 00 00 00 .`... . [1] <5> 6e 6f 6e 63 65 nonce . [2] [0] [Integer] 0 . [1] [Integer] 5 . [2] [Octet String] "krbASN.1 test message" . [3] [Object Identifier] <9> 60 86 48 01 65 03 04 02 01 `.H.e.... . [4] <2> 03 e8 .. . [5] <5> 66 72 6f 67 73 frogs . [6] <10> 6d 79 66 69 72 73 74 70 69 6e myfirstpin . [7] <5> 68 61 72 6b 21 hark! . [8] <15> 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5a 19940610060317Z . [9] <3> 33 34 36 346 . [10] <1> 02 . . [11] <9> 79 6f 75 72 74 6f 6b 65 6e yourtoken . [12] "urn:ietf:params:xml:ns:keyprov:pskc:hotp" . [13] <11> 45 78 61 6d 70 6c 65 63 6f 72 70 Examplecorp encode_krb5_pa_otp_enc_req: [Sequence/Sequence Of] . [0] <8> 6b 72 62 35 64 61 74 61 krb5data encode_krb5_kkdcp_message: [Sequence/Sequence Of] . [0] [Octet String] <488> 6a 82 01 e4 30 82 01 e0 a1 03 02 01 05 a2 03 02 j...0........... 01 0a a3 26 30 24 30 10 a1 03 02 01 0d a2 09 04 ...&0$0......... 07 70 61 2d 64 61 74 61 30 10 a1 03 02 01 0d a2 .pa-data0....... 09 04 07 70 61 2d 64 61 74 61 a4 82 01 aa 30 82 ...pa-data....0. 01 a6 a0 07 03 05 00 fe dc ba 98 a1 1a 30 18 a0 .............0.. 03 02 01 01 a1 11 30 0f 1b 06 68 66 74 73 61 69 ......0...hftsai 1b 05 65 78 74 72 61 a2 10 1b 0e 41 54 48 45 4e ..extra....ATHEN 41 2e 4d 49 54 2e 45 44 55 a3 1a 30 18 a0 03 02 A.MIT.EDU..0.... 01 01 a1 11 30 0f 1b 06 68 66 74 73 61 69 1b 05 ....0...hftsai.. 65 78 74 72 61 a4 11 18 0f 31 39 39 34 30 36 31 extra....1994061 30 30 36 30 33 31 37 5a a5 11 18 0f 31 39 39 34 0060317Z....1994 30 36 31 30 30 36 30 33 31 37 5a a6 11 18 0f 31 0610060317Z....1 39 39 34 30 36 31 30 30 36 30 33 31 37 5a a7 03 9940610060317Z.. 02 01 2a a8 08 30 06 02 01 00 02 01 01 a9 20 30 ..*..0........ 0 1e 30 0d a0 03 02 01 02 a1 06 04 04 12 d0 00 23 .0.............# 30 0d a0 03 02 01 02 a1 06 04 04 12 d0 00 23 aa 0.............#. 25 30 23 a0 03 02 01 00 a1 03 02 01 05 a2 17 04 %0#............. 15 6b 72 62 41 53 4e 2e 31 20 74 65 73 74 20 6d .krbASN.1 test m 65 73 73 61 67 65 ab 81 bf 30 81 bc 61 5c 30 5a essage...0..a\0Z a0 03 02 01 05 a1 10 1b 0e 41 54 48 45 4e 41 2e .........ATHENA. 4d 49 54 2e 45 44 55 a2 1a 30 18 a0 03 02 01 01 MIT.EDU..0...... a1 11 30 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 ..0...hftsai..ex 74 72 61 a3 25 30 23 a0 03 02 01 00 a1 03 02 01 tra.%0#......... 05 a2 17 04 15 6b 72 62 41 53 4e 2e 31 20 74 65 .....krbASN.1 te 73 74 20 6d 65 73 73 61 67 65 61 5c 30 5a a0 03 st messagea\0Z.. 02 01 05 a1 10 1b 0e 41 54 48 45 4e 41 2e 4d 49 .......ATHENA.MI 54 2e 45 44 55 a2 1a 30 18 a0 03 02 01 01 a1 11 T.EDU..0........ 30 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 74 72 0...hftsai..extr 61 a3 25 30 23 a0 03 02 01 00 a1 03 02 01 05 a2 a.%0#........... 17 04 15 6b 72 62 41 53 4e 2e 31 20 74 65 73 74 ...krbASN.1 test 20 6d 65 73 73 61 67 65 message . [1] [General string] "krb5data" encode_krb5_cammac(optionals NULL): [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "ad1" encode_krb5_cammac: [Sequence/Sequence Of] . [0] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "ad1" . . [Sequence/Sequence Of] . . . [0] [Integer] 2 . . . [1] [Octet String] "ad2" . [1] [Sequence/Sequence Of] . . [0] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [1] [Integer] 5 . . [2] [Integer] 16 . . [3] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "cksumkdc" . [2] [Sequence/Sequence Of] . . [0] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Sequence/Sequence Of] . . . . [General string] "hftsai" . . . . [General string] "extra" . . [1] [Integer] 5 . . [2] [Integer] 16 . . [3] [Sequence/Sequence Of] . . . [0] [Integer] 1 . . . [1] [Octet String] "cksumsvc" . [3] [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [3] [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . . [1] [Octet String] "cksum1" . . [Sequence/Sequence Of] . . . [0] [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . . [1] [Sequence/Sequence Of] . . . . . [General string] "hftsai" . . . . . [General string] "extra" . . . [1] [Integer] 5 . . . [2] [Integer] 16 . . . [3] [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . . [1] [Octet String] "cksum2" encode_krb5_secure_cookie: [Sequence/Sequence Of] . [Integer] 771228197 . [Sequence/Sequence Of] . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" . . [Sequence/Sequence Of] . . . [1] [Integer] 13 . . . [2] [Octet String] "pa-data" encode_krb5_spake_factor(optionals NULL): [Sequence/Sequence Of] . [0] [Integer] 1 encode_krb5_spake_factor: [Sequence/Sequence Of] . [0] [Integer] 2 . [1] [Octet String] "fdata" encode_krb5_pa_spake(support): [CONT 0] . [Sequence/Sequence Of] . . [0] [Sequence/Sequence Of] . . . [Integer] 1 . . . [Integer] 2 encode_krb5_pa_spake(challenge): [CONT 1] . [Sequence/Sequence Of] . . [0] [Integer] 1 . . [1] [Octet String] "T value" . . [2] [Sequence/Sequence Of] . . . [Sequence/Sequence Of] . . . . [0] [Integer] 1 . . . [Sequence/Sequence Of] . . . . [0] [Integer] 2 . . . . [1] [Octet String] "fdata" encode_krb5_pa_spake(response): [CONT 2] . [Sequence/Sequence Of] . . [0] [Octet String] "S value" . . [1] [Sequence/Sequence Of] . . . [0] [Integer] 0 . . . [1] [Integer] 5 . . . [2] [Octet String] "krbASN.1 test message" encode_krb5_pa_spake(encdata): [CONT 3] . [Sequence/Sequence Of] . . [0] [Integer] 0 . . [1] [Integer] 5 . . [2] [Octet String] "krbASN.1 test message" krb5-1.22.1/src/tests/threads/0000775000175000017500000000000015051422640015724 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/threads/Makefile.in0000664000175000017500000000225415051422640017774 0ustar ghudsonghudson# The test programs here are not built or run by default. You can # build a specific test program with "make gss-perf" or similar. # "make run-t_rcache" will run the replay cache test program in the # proper environment. mydir=tests$(S)threads BUILDTOP=$(REL)..$(S).. SRCS=$(srcdir)/t_rcache.c \ $(srcdir)/gss-perf.c \ $(srcdir)/init_ctx.c \ $(srcdir)/profread.c \ $(srcdir)/prof1.c all: run-t_rcache: t_rcache $(RUN_TEST) ./t_rcache file2:test.rcache2 t_rcache: t_rcache.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_rcache t_rcache.o $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) prof1: prof1.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o prof1 prof1.o $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) prof1.o: prof1.c gss-perf: gss-perf.o $(KRB5_BASE_DEPLIBS) $(GSS_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o gss-perf gss-perf.o $(GSS_LIBS) $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) init_ctx: init_ctx.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o init_ctx init_ctx.o $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) profread: profread.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) $(PTHREAD_CFLAGS) -o profread profread.o $(KRB5_BASE_LIBS) $(THREAD_LINKOPTS) install: clean: $(RM) *.o t_rcache syms prof1 gss-perf test.rcache2 krb5-1.22.1/src/tests/threads/gss-perf.c0000664000175000017500000003373615051422640017632 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/gss-perf.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * GSSAPI performance testing * initially contributed by Ken Raeburn */ /* * Possible to-do items: * - init-mutual testing (process msg back from accept) * - wrap/unwrap testing (one init/accept per thread, loop on wrap/unwrap) * - wrap/unwrap MT testing (one init/accept for process) ? * - init+accept with replay cache * - default to target "host@localhostname" * - input ccache option? * * Also, perhaps try to simulate certain application patterns, like * init/accept, exchange N messages with wrap/unwrap, destroy context, * all in a loop in M parallel threads. */ #include #include #include #include #include #include #include #include #include #include #include #define N_THREADS 2 #define ITER_COUNT 10000 static int init_krb5_first = 0; struct resource_info { struct timeval start_time, end_time; }; struct thread_info { pthread_t tid; struct resource_info r; }; static gss_name_t target; static char *prog, *target_name; static unsigned int n_threads = N_THREADS; static int iter_count = ITER_COUNT; static int do_pause, do_mutual; static int test_init, test_accept; static void usage (void) __attribute__((noreturn)); static void set_target (char *); static void usage (void) { fprintf (stderr, "usage: %s [ options ] service-name\n", prog); fprintf (stderr, " service-name\tGSSAPI host-based service name (e.g., 'host@FQDN')\n"); fprintf (stderr, "options:\n"); fprintf (stderr, "\t-I\ttest gss_init_sec_context\n"); fprintf (stderr, "\t-A\ttest gss_accept_sec_context\n"); fprintf (stderr, "\t-k K\tspecify keytab (remember FILE: or other prefix!)\n"); fprintf (stderr, "\t-t N\tspecify number of threads (default %d)\n", N_THREADS); fprintf (stderr, "\t-i N\tset iteration count (default %d)\n", ITER_COUNT); fprintf (stderr, "\t-m\tenable mutual authentication flag (but don't do the additional calls)\n"); fprintf (stderr, "\t-K\tinitialize a krb5_context for the duration\n"); fprintf (stderr, "\t-P\tpause briefly after starting, to allow attaching dtrace/strace/etc\n"); exit (1); } static int numarg (char *arg) { char *end; long val; val = strtol (arg, &end, 10); if (*arg == 0 || *end != 0) { fprintf (stderr, "invalid numeric argument '%s'\n", arg); usage (); } if (val >= 1 && val <= INT_MAX) return val; fprintf (stderr, "out of range numeric value %ld (1..%d)\n", val, INT_MAX); usage (); } static char optstring[] = "k:t:i:KPmIA"; static void process_options (int argc, char *argv[]) { int c; prog = strrchr (argv[0], '/'); if (prog) prog++; else prog = argv[0]; while ((c = getopt (argc, argv, optstring)) != -1) { switch (c) { case '?': case ':': usage (); break; case 'k': setenv ("KRB5_KTNAME", optarg, 1); break; case 't': n_threads = numarg (optarg); if (n_threads >= SIZE_MAX / sizeof (struct thread_info)) { n_threads = SIZE_MAX / sizeof (struct thread_info); fprintf (stderr, "limiting n_threads to %u\n", n_threads); } break; case 'i': iter_count = numarg (optarg); break; case 'K': init_krb5_first = 1; break; case 'P': do_pause = 1; break; case 'I': test_init = 1; break; case 'A': test_accept = 1; break; } } if (argc == optind + 1) set_target (argv[optind]); else usage (); if (test_init && test_accept) { fprintf (stderr, "-I and -A are mutually exclusive\n"); usage (); } if (test_init == 0 && test_accept == 0) test_init = 1; } static void display_a_status (const char *s_type, OM_uint32 type, OM_uint32 val) { OM_uint32 mctx = 0; OM_uint32 maj_stat, min_stat; gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; do { maj_stat = gss_display_status (&min_stat, val, type, GSS_C_NO_OID, &mctx, &msg); if (maj_stat != GSS_S_COMPLETE) { fprintf (stderr, "error getting display form of %s status code %#lx\n", s_type, (unsigned long) val); exit (1); } fprintf (stderr, " %s: %.*s\n", s_type, (int) msg.length, (char *) msg.value); gss_release_buffer (&min_stat, &msg); } while (mctx != 0); } static void gss_error(const char *where, OM_uint32 maj_stat, OM_uint32 min_stat) { fprintf (stderr, "%s: %s:\n", prog, where); display_a_status ("major", GSS_C_GSS_CODE, maj_stat); display_a_status ("minor", GSS_C_MECH_CODE, min_stat); exit (1); } static void do_accept (gss_buffer_desc *msg, int iter) { OM_uint32 maj_stat, min_stat; gss_name_t client = GSS_C_NO_NAME; gss_buffer_desc reply = GSS_C_EMPTY_BUFFER; gss_OID oid = GSS_C_NO_OID; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; OM_uint32 flags = do_mutual ? GSS_C_MUTUAL_FLAG : 0; reply.value = NULL; reply.length = 0; maj_stat = gss_accept_sec_context (&min_stat, &ctx, GSS_C_NO_CREDENTIAL, msg, GSS_C_NO_CHANNEL_BINDINGS, &client, &oid, &reply, &flags, NULL, /* time_rec */ NULL); /* del_cred_handle */ if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { fprintf (stderr, "pid %lu thread %#lx failing in iteration %d\n", (unsigned long) getpid (), (unsigned long) pthread_self (), iter); gss_error ("accepting context", maj_stat, min_stat); } gss_release_buffer (&min_stat, &reply); if (ctx != GSS_C_NO_CONTEXT) gss_delete_sec_context (&min_stat, &ctx, GSS_C_NO_BUFFER); gss_release_name (&min_stat, &client); } static gss_buffer_desc do_init (void) { OM_uint32 maj_stat, min_stat; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; OM_uint32 flags = 0, ret_flags = 0; gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; if (do_mutual) flags |= GSS_C_MUTUAL_FLAG; msg.value = NULL; msg.length = 0; maj_stat = gss_init_sec_context (&min_stat, GSS_C_NO_CREDENTIAL, &ctx, target, GSS_C_NO_OID, flags, 0, NULL, /* no channel bindings */ NULL, /* no previous token */ NULL, /* ignore mech type */ &msg, &ret_flags, NULL); /* time_rec */ if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { gss_error ("initiating", maj_stat, min_stat); } if (ctx != GSS_C_NO_CONTEXT) gss_delete_sec_context (&min_stat, &ctx, GSS_C_NO_BUFFER); return msg; } static void set_target (char *name) { OM_uint32 maj_stat, min_stat; gss_buffer_desc namebuf; target_name = name; namebuf.value = name; namebuf.length = strlen (name); maj_stat = gss_import_name (&min_stat, &namebuf, GSS_C_NT_HOSTBASED_SERVICE, &target); if (maj_stat != GSS_S_COMPLETE) gss_error ("importing target name", maj_stat, min_stat); } static long double tvsub (struct timeval t1, struct timeval t2) { /* POSIX says .tv_usec is signed. */ return (t1.tv_sec - t2.tv_sec + (long double) 1.0e-6 * (t1.tv_usec - t2.tv_usec)); } static struct timeval now (void) { struct timeval tv; if (gettimeofday (&tv, NULL) < 0) { perror ("gettimeofday"); exit (1); } return tv; } static gss_buffer_desc init_msg; static void run_iterations (struct resource_info *r) { int i; OM_uint32 min_stat; r->start_time = now (); for (i = 0; i < iter_count; i++) { if (test_init) { gss_buffer_desc msg = do_init (); gss_release_buffer (&min_stat, &msg); } else if (test_accept) { do_accept (&init_msg, i); } else assert (test_init || test_accept); } r->end_time = now (); } static void * thread_proc (void *p) { run_iterations (p); return 0; } static struct thread_info *tinfo; static krb5_context kctx; static struct rusage start, finish; static struct timeval start_time, finish_time; int main (int argc, char *argv[]) { long double user, sys, wallclock, total; unsigned int i; /* Probably should have a command-line option controlling this, but if a replay cache is used, we can't do just one init_sec_context and easily time just the accept_sec_context side. */ setenv ("KRB5RCACHETYPE", "none", 1); process_options (argc, argv); /* * Some places in the krb5 library cache data globally. * This option allows you to test the effect of that. */ if (init_krb5_first && krb5_init_context (&kctx) != 0) { fprintf (stderr, "krb5_init_context error\n"); exit (1); } tinfo = calloc (n_threads, sizeof (*tinfo)); if (tinfo == NULL) { perror ("calloc"); exit (1); } printf ("Test: %s threads: %d iterations: %d target: %s\n", test_init ? "init" : "accept", n_threads, iter_count, target_name ? target_name : "(NONE)"); if (do_pause) { printf ("pid %lu napping...\n", (unsigned long) getpid ()); sleep (10); } /* * Some tests use one message and process it over and over. Even * if not, this sort of "primes" things by fetching any needed * tickets just once. */ init_msg = do_init (); printf ("starting...\n"); /* And *now* we start measuring the performance. */ if (getrusage (RUSAGE_SELF, &start) < 0) { perror ("getrusage"); exit (1); } start_time = now (); #define foreach_thread(IDXVAR) for (IDXVAR = 0; IDXVAR < n_threads; IDXVAR++) foreach_thread (i) { int err; err = pthread_create (&tinfo[i].tid, NULL, thread_proc, &tinfo[i].r); if (err) { fprintf (stderr, "pthread_create: %s\n", strerror (err)); exit (1); } } foreach_thread (i) { int err; void *val; err = pthread_join (tinfo[i].tid, &val); if (err) { fprintf (stderr, "pthread_join: %s\n", strerror (err)); exit (1); } } finish_time = now (); if (getrusage (RUSAGE_SELF, &finish) < 0) { perror ("getrusage"); exit (1); } if (init_krb5_first) krb5_free_context (kctx); foreach_thread (i) { printf ("Thread %2d: elapsed time %Lfs\n", i, tvsub (tinfo[i].r.end_time, tinfo[i].r.start_time)); } wallclock = tvsub (finish_time, start_time); /* * Report on elapsed time and CPU usage. Depending what * performance issue you're chasing down, different values may be * of particular interest, so report all the info we've got. */ printf ("Overall run time with %d threads = %Lfs, %Lfms per iteration.\n", n_threads, wallclock, 1000 * wallclock / iter_count); user = tvsub (finish.ru_utime, start.ru_utime); sys = tvsub (finish.ru_stime, start.ru_stime); total = user + sys; printf ("CPU usage: user=%Lfs sys=%Lfs total=%Lfs.\n", user, sys, total); printf ("Utilization: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock, 100 * sys / wallclock, 100 * total / wallclock); printf ("Util/thread: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock / n_threads, 100 * sys / wallclock / n_threads, 100 * total / wallclock / n_threads); printf ("Total CPU use per iteration per thread: %Lfms\n", 1000 * total / n_threads / iter_count); return 0; } krb5-1.22.1/src/tests/threads/deps0000664000175000017500000000272115051422640016604 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)t_rcache.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_rcache.c $(OUTPRE)gss-perf.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ gss-perf.c $(OUTPRE)init_ctx.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ init_ctx.c $(OUTPRE)profread.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ profread.c $(OUTPRE)prof1.$(OBJEXT): $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) prof1.c krb5-1.22.1/src/tests/threads/profread.c0000664000175000017500000001776115051422640017706 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/profread.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * krb5 profile data retrieval performance testing * initially contributed by Ken Raeburn */ #include "k5-platform.h" #include #include #include #include #include #include #define N_THREADS 4 #define ITER_COUNT 40000 static int init_krb5_first = 0; struct resource_info { struct timeval start_time, end_time; }; struct thread_info { pthread_t tid; struct resource_info r; krb5_context ctx; }; static char *prog; static unsigned int n_threads = N_THREADS; static int iter_count = ITER_COUNT; static int do_pause; static void usage (void) __attribute__((noreturn)); static void usage (void) { fprintf (stderr, "usage: %s [ options ]\n", prog); fprintf (stderr, "options:\n"); fprintf (stderr, "\t-t N\tspecify number of threads (default %d)\n", N_THREADS); fprintf (stderr, "\t-i N\tset iteration count (default %d)\n", ITER_COUNT); fprintf (stderr, "\t-K\tinitialize a krb5_context for the duration\n"); fprintf (stderr, "\t-P\tpause briefly after starting, to allow attaching dtrace/strace/etc\n"); exit (1); } static int numarg (char *arg) { char *end; long val; val = strtol (arg, &end, 10); if (*arg == 0 || *end != 0) { fprintf (stderr, "invalid numeric argument '%s'\n", arg); usage (); } if (val >= 1 && val <= INT_MAX) return val; fprintf (stderr, "out of range numeric value %ld (1..%d)\n", val, INT_MAX); usage (); } static char optstring[] = "t:i:KP"; static void process_options (int argc, char *argv[]) { int c; prog = strrchr (argv[0], '/'); if (prog) prog++; else prog = argv[0]; while ((c = getopt (argc, argv, optstring)) != -1) { switch (c) { case '?': case ':': usage (); break; case 't': n_threads = numarg (optarg); if (n_threads >= SIZE_MAX / sizeof (struct thread_info)) { n_threads = SIZE_MAX / sizeof (struct thread_info); fprintf (stderr, "limiting n_threads to %u\n", n_threads); } break; case 'i': iter_count = numarg (optarg); break; case 'K': init_krb5_first = 1; break; case 'P': do_pause = 1; break; } } if (argc != optind) usage (); } static long double tvsub (struct timeval t1, struct timeval t2) { /* POSIX says .tv_usec is signed. */ return (t1.tv_sec - t2.tv_sec + (long double) 1.0e-6 * (t1.tv_usec - t2.tv_usec)); } static struct timeval now (void) { struct timeval tv; if (gettimeofday (&tv, NULL) < 0) { perror ("gettimeofday"); exit (1); } return tv; } static void run_iterations (struct resource_info *r) { int i; krb5_error_code err; krb5_context ctx; profile_t prof = NULL; err = krb5_init_context(&ctx); if (err) { com_err(prog, err, "initializing krb5 context"); exit(1); } err = krb5_get_profile(ctx, &prof); if (err) { com_err(prog, err, "fetching profile from context"); exit(1); } r->start_time = now (); for (i = 0; i < iter_count; i++) { int ival; err = profile_get_integer(prof, "one", "two", "three", 42, &ival); if (err) { com_err(prog, err, "fetching value from profile"); exit(1); } } r->end_time = now (); profile_release (prof); krb5_free_context(ctx); } static void * thread_proc (void *p) { run_iterations (p); return 0; } static struct thread_info *tinfo; static krb5_context kctx; static struct rusage start, finish; static struct timeval start_time, finish_time; int main (int argc, char *argv[]) { long double user, sys, wallclock, total; unsigned int i; process_options (argc, argv); /* * Some places in the krb5 library cache data globally. * This option allows you to test the effect of that. */ if (init_krb5_first && krb5_init_context (&kctx) != 0) { fprintf (stderr, "krb5_init_context error\n"); exit (1); } tinfo = calloc (n_threads, sizeof (*tinfo)); if (tinfo == NULL) { perror ("calloc"); exit (1); } printf ("Threads: %d iterations: %d\n", n_threads, iter_count); if (do_pause) { printf ("pid %lu napping...\n", (unsigned long) getpid ()); sleep (10); } printf ("starting...\n"); /* And *now* we start measuring the performance. */ if (getrusage (RUSAGE_SELF, &start) < 0) { perror ("getrusage"); exit (1); } start_time = now (); #define foreach_thread(IDXVAR) for (IDXVAR = 0; IDXVAR < n_threads; IDXVAR++) foreach_thread (i) { int err; err = pthread_create (&tinfo[i].tid, NULL, thread_proc, &tinfo[i].r); if (err) { fprintf (stderr, "pthread_create: %s\n", strerror (err)); exit (1); } } foreach_thread (i) { int err; void *val; err = pthread_join (tinfo[i].tid, &val); if (err) { fprintf (stderr, "pthread_join: %s\n", strerror (err)); exit (1); } } finish_time = now (); if (getrusage (RUSAGE_SELF, &finish) < 0) { perror ("getrusage"); exit (1); } if (init_krb5_first) krb5_free_context (kctx); foreach_thread (i) { printf ("Thread %2d: elapsed time %Lfs\n", i, tvsub (tinfo[i].r.end_time, tinfo[i].r.start_time)); } wallclock = tvsub (finish_time, start_time); /* * Report on elapsed time and CPU usage. Depending what * performance issue you're chasing down, different values may be * of particular interest, so report all the info we've got. */ printf ("Overall run time with %d threads = %Lfs, %.2Lfus per iteration.\n", n_threads, wallclock, 1000000 * wallclock / iter_count); user = tvsub (finish.ru_utime, start.ru_utime); sys = tvsub (finish.ru_stime, start.ru_stime); total = user + sys; printf ("CPU usage: user=%Lfs sys=%Lfs total=%Lfs.\n", user, sys, total); printf ("Utilization: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock, 100 * sys / wallclock, 100 * total / wallclock); printf ("Util/thread: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock / n_threads, 100 * sys / wallclock / n_threads, 100 * total / wallclock / n_threads); printf ("Total CPU use per iteration per thread: %.2Lfus\n", 1000000 * total / n_threads / iter_count); return 0; } krb5-1.22.1/src/tests/threads/t_rcache.c0000664000175000017500000001603315051422640017643 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/t_rcache.c */ /* * Copyright (C) 2006 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include #include #include krb5_context ctx; krb5_rcache rcache; const char *rcname; time_t end_time; const char *prog; struct tinfo { time_t now; unsigned long my_ctime; unsigned int my_cusec; unsigned int total; int idx; }; #define DEFAULT_N_THREADS 2 #define DEFAULT_INTERVAL 20 /* 5 * 60 */ int init_once = 0; int n_threads = DEFAULT_N_THREADS; int interval = DEFAULT_INTERVAL; int *ip; static void wait_for_tick (void) { time_t now, next; now = time(0); do { next = time(0); } while (now == next); } /* Encrypt data into out (preallocated by the caller) with a random key. */ static krb5_error_code encrypt_data (krb5_data *data, krb5_enc_data *out) { krb5_keyblock kb; krb5_error_code err; err = krb5_c_make_random_key(ctx, ENCTYPE_AES256_CTS_HMAC_SHA1_96, &kb); if (err) return err; err = krb5_c_encrypt(ctx, &kb, KRB5_KEYUSAGE_TGS_REQ_AUTH, NULL, data, out); krb5_free_keyblock_contents(ctx, &kb); return err; } static void try_one (struct tinfo *t) { krb5_error_code err; char buf[256], buf2[512]; krb5_rcache my_rcache; krb5_data d; krb5_enc_data enc; snprintf(buf, sizeof(buf), "host/all-in-one.mit.edu/%p@ATHENA.MIT.EDU", buf); /* k5_rc_store() requires a ciphertext. Create one by encrypting a dummy * value in a random key. */ d = string2data(buf); enc.ciphertext = make_data(buf2, sizeof(buf2)); err = encrypt_data(&d, &enc); if (err != 0) { const char *msg = krb5_get_error_message(ctx, err); fprintf(stderr, "%s: encrypting authenticator: %s\n", prog, msg); krb5_free_error_message(ctx, msg); exit(1); } if (t->now != t->my_ctime) { if (t->my_ctime != 0) { snprintf(buf2, sizeof(buf2), "%3d: %ld %5d\n", t->idx, t->my_ctime, t->my_cusec); printf("%s", buf2); } t->my_ctime = t->now; t->my_cusec = 1; } else t->my_cusec++; if (!init_once) { err = k5_rc_resolve(ctx, rcname, &my_rcache); if (err) { const char *msg = krb5_get_error_message(ctx, err); fprintf(stderr, "%s: %s while initializing replay cache\n", prog, msg); krb5_free_error_message(ctx, msg); exit(1); } } else my_rcache = rcache; err = k5_rc_store(ctx, my_rcache, &enc); if (err) { com_err(prog, err, "storing in replay cache"); exit(1); } if (!init_once) k5_rc_close(ctx, my_rcache); } static void *run_a_loop (void *x) { struct tinfo t = { 0 }; t.now = time(0); t.idx = *(int *)x; while (t.now != time(0)) ; t.now = time(0); while (t.now < end_time) { t.now = time(0); try_one(&t); t.total++; } *(int*)x = t.total; return 0; } static void usage(void) { fprintf (stderr, "usage: %s [ options ] rcname\n", prog); fprintf (stderr, "options:\n"); fprintf (stderr, "\t-1\tcreate one rcache handle for process\n"); fprintf (stderr, "\t-t N\tnumber of threads to create (default: %d)\n", DEFAULT_N_THREADS); fprintf (stderr, "\t-i N\tinterval to run test over, in seconds (default: %d)\n", DEFAULT_INTERVAL); exit(1); } static const char optstring[] = "1t:i:"; static void process_options (int argc, char *argv[]) { int c; prog = argv[0]; while ((c = getopt(argc, argv, optstring)) != -1) { switch (c) { case '?': case ':': default: usage (); case '1': init_once = 1; break; case 't': n_threads = atoi (optarg); if (n_threads < 1 || n_threads > 10000) usage (); break; case 'i': interval = atoi (optarg); if (interval < 2 || n_threads > 100000) usage (); break; } } argc -= optind; argv += optind; if (argc != 1) usage (); rcname = argv[0]; } int main (int argc, char *argv[]) { krb5_error_code err; int i; unsigned long sum; process_options (argc, argv); err = krb5_init_context(&ctx); if (err) { com_err(prog, err, "initializing context"); return 1; } if (init_once) { err = k5_rc_resolve(ctx, rcname, &rcache); if (err) { const char *msg = krb5_get_error_message(ctx, err); fprintf(stderr, "%s: %s while initializing new replay cache\n", prog, msg); krb5_free_error_message(ctx, msg); return 1; } } ip = malloc(sizeof(int) * n_threads); if (ip == 0 && n_threads > 0) { perror("malloc"); exit(1); } for (i = 0; i < n_threads; i++) ip[i] = i; wait_for_tick (); end_time = time(0) + interval; for (i = 0; i < n_threads; i++) { pthread_t new_thread; int perr; perr = pthread_create(&new_thread, 0, run_a_loop, &ip[i]); if (perr) { errno = perr; perror("pthread_create"); exit(1); } } while (time(0) < end_time + 1) sleep(1); sum = 0; for (i = 0; i < n_threads; i++) { sum += ip[i]; printf("thread %d total %5d, about %.1f per second\n", i, ip[i], ((double) ip[i])/interval); } printf("total %lu in %d seconds, avg ~%.1f/sec, ~%.1f/sec/thread\n", sum, interval, ((double)sum)/interval, ((double)sum)/interval/n_threads); free(ip); if (init_once) k5_rc_close(ctx, rcache); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/threads/init_ctx.c0000664000175000017500000001711715051422640017720 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/init_ctx.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * krb5 context creation performance testing * initially contributed by Ken Raeburn */ #include "k5-platform.h" #include #include #include #include #include #define N_THREADS 4 #define ITER_COUNT 40000 static int init_krb5_first = 0; struct resource_info { struct timeval start_time, end_time; }; struct thread_info { pthread_t tid; struct resource_info r; }; static char *prog; static unsigned int n_threads = N_THREADS; static int iter_count = ITER_COUNT; static int do_pause; static void usage (void) __attribute__((noreturn)); static void usage (void) { fprintf (stderr, "usage: %s [ options ]\n", prog); fprintf (stderr, "options:\n"); fprintf (stderr, "\t-t N\tspecify number of threads (default %d)\n", N_THREADS); fprintf (stderr, "\t-i N\tset iteration count (default %d)\n", ITER_COUNT); fprintf (stderr, "\t-K\tinitialize a krb5_context for the duration\n"); fprintf (stderr, "\t-P\tpause briefly after starting, to allow attaching dtrace/strace/etc\n"); exit (1); } static int numarg (char *arg) { char *end; long val; val = strtol (arg, &end, 10); if (*arg == 0 || *end != 0) { fprintf (stderr, "invalid numeric argument '%s'\n", arg); usage (); } if (val >= 1 && val <= INT_MAX) return val; fprintf (stderr, "out of range numeric value %ld (1..%d)\n", val, INT_MAX); usage (); } static char optstring[] = "t:i:KP"; static void process_options (int argc, char *argv[]) { int c; prog = strrchr (argv[0], '/'); if (prog) prog++; else prog = argv[0]; while ((c = getopt (argc, argv, optstring)) != -1) { switch (c) { case '?': case ':': usage (); break; case 't': n_threads = numarg (optarg); if (n_threads >= SIZE_MAX / sizeof (struct thread_info)) { n_threads = SIZE_MAX / sizeof (struct thread_info); fprintf (stderr, "limiting n_threads to %u\n", n_threads); } break; case 'i': iter_count = numarg (optarg); break; case 'K': init_krb5_first = 1; break; case 'P': do_pause = 1; break; } } if (argc != optind) usage (); } static long double tvsub (struct timeval t1, struct timeval t2) { /* POSIX says .tv_usec is signed. */ return (t1.tv_sec - t2.tv_sec + (long double) 1.0e-6 * (t1.tv_usec - t2.tv_usec)); } static struct timeval now (void) { struct timeval tv; if (gettimeofday (&tv, NULL) < 0) { perror ("gettimeofday"); exit (1); } return tv; } static void run_iterations (struct resource_info *r) { int i; krb5_error_code err; krb5_context ctx; r->start_time = now (); for (i = 0; i < iter_count; i++) { err = krb5_init_context(&ctx); if (err) { com_err(prog, err, "initializing krb5 context"); exit(1); } krb5_free_context(ctx); } r->end_time = now (); } static void * thread_proc (void *p) { run_iterations (p); return 0; } static struct thread_info *tinfo; static krb5_context kctx; static struct rusage start, finish; static struct timeval start_time, finish_time; int main (int argc, char *argv[]) { long double user, sys, wallclock, total; unsigned int i; process_options (argc, argv); /* * Some places in the krb5 library cache data globally. * This option allows you to test the effect of that. */ if (init_krb5_first && krb5_init_context (&kctx) != 0) { fprintf (stderr, "krb5_init_context error\n"); exit (1); } tinfo = calloc (n_threads, sizeof (*tinfo)); if (tinfo == NULL) { perror ("calloc"); exit (1); } printf ("Threads: %d iterations: %d\n", n_threads, iter_count); if (do_pause) { printf ("pid %lu napping...\n", (unsigned long) getpid ()); sleep (10); } printf ("starting...\n"); /* And *now* we start measuring the performance. */ if (getrusage (RUSAGE_SELF, &start) < 0) { perror ("getrusage"); exit (1); } start_time = now (); #define foreach_thread(IDXVAR) for (IDXVAR = 0; IDXVAR < n_threads; IDXVAR++) foreach_thread (i) { int err; err = pthread_create (&tinfo[i].tid, NULL, thread_proc, &tinfo[i].r); if (err) { fprintf (stderr, "pthread_create: %s\n", strerror (err)); exit (1); } } foreach_thread (i) { int err; void *val; err = pthread_join (tinfo[i].tid, &val); if (err) { fprintf (stderr, "pthread_join: %s\n", strerror (err)); exit (1); } } finish_time = now (); if (getrusage (RUSAGE_SELF, &finish) < 0) { perror ("getrusage"); exit (1); } if (init_krb5_first) krb5_free_context (kctx); foreach_thread (i) { printf ("Thread %2d: elapsed time %Lfs\n", i, tvsub (tinfo[i].r.end_time, tinfo[i].r.start_time)); } wallclock = tvsub (finish_time, start_time); /* * Report on elapsed time and CPU usage. Depending what * performance issue you're chasing down, different values may be * of particular interest, so report all the info we've got. */ printf ("Overall run time with %d threads = %Lfs, %Lfms per iteration.\n", n_threads, wallclock, 1000 * wallclock / iter_count); user = tvsub (finish.ru_utime, start.ru_utime); sys = tvsub (finish.ru_stime, start.ru_stime); total = user + sys; printf ("CPU usage: user=%Lfs sys=%Lfs total=%Lfs.\n", user, sys, total); printf ("Utilization: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock, 100 * sys / wallclock, 100 * total / wallclock); printf ("Util/thread: user=%5.1Lf%% sys=%5.1Lf%% total=%5.1Lf%%\n", 100 * user / wallclock / n_threads, 100 * sys / wallclock / n_threads, 100 * total / wallclock / n_threads); printf ("Total CPU use per iteration per thread: %Lfms\n", 1000 * total / n_threads / iter_count); free(tinfo); return 0; } krb5-1.22.1/src/tests/threads/prof1.c0000664000175000017500000000564715051422640017133 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/threads/prof1.c */ /* * Copyright (C) 2004 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include #include #include #include #include #include #include #include int nthreads = 10; unsigned int delay = 3600; volatile int done = 0; /* XXX hack */ const char *path = "/tmp/foo1.conf:/tmp/foo.conf"; const char *filename = "/tmp/foo.conf"; const char *prog; static void *worker(void *arg) { profile_t p; long err; int i; const char *const names[] = { "one", "two", "three", 0 }; char **values; const char *mypath = (random() & 1) ? path : filename; while (!done) { err = profile_init_path(mypath, &p); if (err) { com_err(prog, err, "calling profile_init(\"%s\")", mypath); exit(1); } for (i = 0; i < 10; i++) { values = 0; err = profile_get_values(p, names, &values); if (err == 0 && values != 0) profile_free_list(values); } profile_release(p); } return 0; } static void *modifier(void *arg) { struct timespec req; while (!done) { req.tv_sec = 0; req.tv_nsec = random() & 499999999; nanosleep(&req, 0); utime(filename, 0); /* printf("."), fflush(stdout); */ } return 0; } int main(int argc, char *argv[]) { int i; pthread_t thr; prog = argv[0]; for (i = 0; i < nthreads; i++) { assert(0 == pthread_create(&thr, 0, worker, 0)); } sleep(1); pthread_create(&thr, 0, modifier, 0); sleep(delay); done = 1; sleep(2); return 0; } krb5-1.22.1/src/tests/t_proxy.py0000775000175000017500000002241715051422640016361 0ustar ghudsonghudsonfrom k5test import * # Skip this test if we're missing proxy functionality or parts of the proxy. if runenv.tls_impl == 'no': skip_rest('HTTP proxy tests', 'TLS build support not enabled') try: import kdcproxy except: skip_rest('HTTP proxy tests', 'Python kdcproxy module not found') # Construct a krb5.conf fragment configuring the client to use a local proxy # server. proxycerts = os.path.join(srctop, 'tests', 'proxy-certs') proxysubjectpem = os.path.join(proxycerts, 'proxy-subject.pem') proxysanpem = os.path.join(proxycerts, 'proxy-san.pem') proxyidealpem = os.path.join(proxycerts, 'proxy-ideal.pem') proxywrongpem = os.path.join(proxycerts, 'proxy-no-match.pem') proxybadpem = os.path.join(proxycerts, 'proxy-badsig.pem') proxyca = os.path.join(proxycerts, 'ca.pem') proxyurl = 'https://localhost:$port5/KdcProxy' proxyurlupcase = 'https://LocalHost:$port5/KdcProxy' proxyurl4 = 'https://127.0.0.1:$port5/KdcProxy' proxyurl6 = 'https://[::1]:$port5/KdcProxy' unanchored_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurl, 'kpasswd_server': proxyurl}}} anchored_name_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurl, 'kpasswd_server': proxyurl, 'http_anchors': 'FILE:%s' % proxyca}}} anchored_upcasename_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurlupcase, 'kpasswd_server': proxyurlupcase, 'http_anchors': 'FILE:%s' % proxyca}}} anchored_kadmin_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurl, 'admin_server': proxyurl, 'http_anchors': 'FILE:%s' % proxyca}}} anchored_ipv4_krb5_conf = {'realms': {'$realm': { 'kdc': proxyurl4, 'kpasswd_server': proxyurl4, 'http_anchors': 'FILE:%s' % proxyca}}} kpasswd_input = (password('user') + '\n' + password('user') + '\n' + password('user') + '\n') def start_proxy(realm, keycertpem): proxy_conf_path = os.path.join(realm.testdir, 'kdcproxy.conf') proxy_exec_path = os.path.join(srctop, 'util', 'wsgiref-kdcproxy.py') conf = open(proxy_conf_path, 'w') conf.write('[%s]\n' % realm.realm) conf.write('kerberos = kerberos://localhost:%d\n' % realm.portbase) conf.write('kpasswd = kpasswd://localhost:%d\n' % (realm.portbase + 2)) conf.close() realm.env['KDCPROXY_CONFIG'] = proxy_conf_path cmd = [sys.executable, proxy_exec_path, str(realm.server_port()), keycertpem] return realm.start_server(cmd, sentinel='proxy server ready') # Fail: untrusted issuer and hostname doesn't match. mark('untrusted issuer, hostname mismatch') output("running pass 1: issuer not trusted and hostname doesn't match\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxywrongpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: untrusted issuer, host name matches subject. mark('untrusted issuer, hostname subject match') output("running pass 2: subject matches, issuer not trusted\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysubjectpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: untrusted issuer, host name matches subjectAltName. mark('untrusted issuer, hostname SAN match') output("running pass 3: subjectAltName matches, issuer not trusted\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysanpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: untrusted issuer, certificate signature is bad. mark('untrusted issuer, bad signature') output("running pass 4: subject matches, issuer not trusted\n") realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxybadpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: trusted issuer but hostname doesn't match. mark('trusted issuer, hostname mismatch') output("running pass 5: issuer trusted but hostname doesn't match\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxywrongpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subject. mark('trusted issuer, hostname subject match') output("running pass 6: issuer trusted, subject matches\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True, get_creds=False) proxy = start_proxy(realm, proxysubjectpem) realm.kinit(realm.user_princ, password=password('user')) realm.run([kvno, realm.host_princ]) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName. mark('trusted issuer, hostname SAN match') output("running pass 7: issuer trusted, subjectAltName matches\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True, get_creds=False) proxy = start_proxy(realm, proxysanpem) realm.kinit(realm.user_princ, password=password('user')) realm.run([kvno, realm.host_princ]) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Fail: certificate signature is bad. mark('bad signature') output("running pass 8: issuer trusted and subjectAltName matches, sig bad\n") realm = K5Realm(krb5_conf=anchored_name_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxybadpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: trusted issuer but IP doesn't match. mark('trusted issuer, IP mismatch') output("running pass 9: issuer trusted but no name matches IP\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxywrongpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Fail: trusted issuer, but subject does not match. mark('trusted issuer, IP mismatch (hostname in subject)') output("running pass 10: issuer trusted, but subject does not match IP\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysubjectpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName. mark('trusted issuer, IP SAN match') output("running pass 11: issuer trusted, subjectAltName matches IP\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, start_kadmind=True, get_creds=False) proxy = start_proxy(realm, proxysanpem) realm.kinit(realm.user_princ, password=password('user')) realm.run([kvno, realm.host_princ]) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Fail: certificate signature is bad. mark('bad signature (IP hostname)') output("running pass 12: issuer trusted, names don't match, signature bad\n") realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, create_host=False) proxy = start_proxy(realm, proxybadpem) realm.kinit(realm.user_princ, password=password('user'), expected_code=1) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subject, using kadmin # configuration to find kpasswdd. mark('trusted issuer, hostname subject match (kadmin)') output("running pass 13: issuer trusted, subject matches\n") realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysubjectpem) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName, using # kadmin configuration to find kpasswdd. mark('trusted issuer, hostname SAN match (kadmin)') output("running pass 14: issuer trusted, subjectAltName matches\n") realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysanpem) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() # Succeed: trusted issuer and host name matches subjectAltName (give or take # case). mark('trusted issuer, hostname SAN case-insensitive match') output("running pass 15: issuer trusted, subjectAltName case-insensitive\n") realm = K5Realm(krb5_conf=anchored_upcasename_krb5_conf, start_kadmind=True, get_creds=False, create_host=False) proxy = start_proxy(realm, proxysanpem) realm.run([kpasswd, realm.user_princ], input=kpasswd_input) stop_daemon(proxy) realm.stop() success('MS-KKDCP proxy') krb5-1.22.1/src/tests/t_hooks.py0000775000175000017500000000035315051422640016316 0ustar ghudsonghudsonfrom k5test import * # Test that KDC send and recv hooks work correctly. realm = K5Realm(create_host=False, get_creds=False) realm.run(['./hooks', realm.user_princ, password('user')]) realm.stop() success('send and recv hook tests') krb5-1.22.1/src/tests/s2p.c0000664000175000017500000000505215051422640015144 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/s2p.c - krb5_name_to_principal test harness */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } int main(int argc, char **argv) { krb5_principal princ; krb5_int32 type; const char *service, *hostname; char *name; /* Parse arguments. */ assert(argc == 4); hostname = argv[1]; service = argv[2]; if (strcmp(argv[3], "unknown") == 0) type = KRB5_NT_UNKNOWN; else if (strcmp(argv[3], "srv-hst") == 0) type = KRB5_NT_SRV_HST; else abort(); check(krb5_init_context(&ctx)); check(krb5_sname_to_principal(ctx, hostname, service, type, &princ)); check(krb5_unparse_name(ctx, princ, &name)); printf("%s\n", name); krb5_free_unparsed_name(ctx, name); krb5_free_principal(ctx, princ); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/tests/t_iprop.py0000775000175000017500000005664615051422640016344 0ustar ghudsonghudsonimport os import re from k5test import * # On macOS with System Integrity Protection enabled, this script hangs # in the wait_for_prop() call after starting the first kpropd process, # most likely due to signal restrictions preventing the listening # child from informing the parent that a full resync was processed. if which('csrutil'): out = subprocess.check_output(['csrutil', 'status'], universal_newlines=True) if 'status: enabled' in out: skip_rest('iprop tests', 'System Integrity Protection is enabled') # Read lines from kpropd output until we are synchronized. Error if # full_expected is true and we didn't see a full propagation or vice # versa. def wait_for_prop(kpropd, full_expected, expected_old, expected_new): output('*** Waiting for sync from kpropd\n') full_seen = sleep_seen = False old_sno = new_sno = -1 while True: line = kpropd.stdout.readline() if line == '': fail('kpropd process exited unexpectedly') output('kpropd: ' + line) m = re.match(r'Calling iprop_get_updates_1 \(sno=(\d+) ', line) if m: if not full_seen: old_sno = int(m.group(1)) # Also record this as the new sno, in case we get back # UPDATE_NIL. new_sno = int(m.group(1)) m = re.match(r'Got incremental updates \(sno=(\d+) ', line) if m: new_sno = int(m.group(1)) if 'KDC is synchronized' in line or 'Incremental updates:' in line: break # After a full resync request, these lines could appear in # either order. if 'Waiting for' in line: sleep_seen = True if 'load process for full propagation completed' in line: full_seen = True # Detect some failure conditions. if 'Still waiting for full resync' in line: fail('kadmind gave consecutive full resyncs') if 'Rejected connection' in line: fail('kpropd rejected kprop connection') if 'get updates failed' in line: fail('iprop_get_updates failed') if 'permission denied' in line: fail('kadmind denied update') if ('error from primary' in line or 'error returned from primary' in line): fail('kadmind reported error') if 'invalid return' in line: fail('kadmind returned invalid result') if full_expected and not full_seen: fail('Expected full dump but saw only incremental') if full_seen and not full_expected: fail('Expected incremental prop but saw full dump') if old_sno != expected_old: fail('Expected old serial %d from kpropd sync' % expected_old) if new_sno != expected_new: fail('Expected new serial %d from kpropd sync' % expected_new) # Wait until kpropd is sleeping before continuing, to avoid races. # (This is imperfect since there's there is a short window between # the fprintf and the sleep; kpropd will need design changes to # fix that.) while True: line = kpropd.stdout.readline() output('kpropd: ' + line) if 'Waiting for' in line: break output('*** Sync complete\n') # Verify the output of kproplog against the expected number of # entries, first and last serial number, and a list of principal names # for the update entrires. def check_ulog(num, first, last, entries, env=None, bsize=2048): out = realm.run([kproplog], env=env) if 'Entry block size : ' + str(bsize) + '\n' not in out: fail('Expected block size %d' % bsize) if 'Number of entries : ' + str(num) + '\n' not in out: fail('Expected %d entries' % num) if last: firststr = first and str(first) or 'None' if 'First serial # : ' + firststr + '\n' not in out: fail('Expected first serial number %d' % first) laststr = last and str(last) or 'None' if 'Last serial # : ' + laststr + '\n' not in out: fail('Expected last serial number %d' % last) assert(len(entries) == num) ser = first - 1 entindex = 0 for line in out.splitlines(): m = re.match(r'\tUpdate serial # : (\d+)$', line) if m: ser = ser + 1 if m.group(1) != str(ser): fail('Expected serial number %d in update entry' % ser) m = re.match(r'\tUpdate principal : (.*)$', line) if m: eprinc = entries[ser - first] if eprinc == None: fail('Expected dummy update entry %d' % ser) elif m.group(1) != eprinc: fail('Expected princ %s in update entry %d' % (eprinc, ser)) if line == '\tDummy entry': eprinc = entries[ser - first] if eprinc != None: fail('Expected princ %s in update entry %d' % (eprinc, ser)) # replica1 will receive updates from primary, and replica2 will # receive updates from replica1. Because of the awkward way iprop and # kprop port configuration currently works, we need separate config # files for the replica and primary sides of replica1, but they use # the same DB and ulog file. conf = {'realms': {'$realm': {'iprop_enable': 'true', 'iprop_logfile': '$testdir/db.ulog'}}} conf_rep1 = {'realms': {'$realm': {'iprop_replica_poll': '600', 'iprop_logfile': '$testdir/ulog.replica1'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.replica1'}}} conf_rep1m = {'realms': {'$realm': {'iprop_logfile': '$testdir/ulog.replica1', 'iprop_port': '$port8'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.replica1'}}} conf_rep2 = {'realms': {'$realm': {'iprop_replica_poll': '600', 'iprop_logfile': '$testdir/ulog.replica2', 'iprop_port': '$port8'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.replica2'}}} conf_foo = {'libdefaults': {'default_realm': 'FOO'}, 'domain_realm': {hostname: 'FOO'}} conf_rep3 = {'realms': {'$realm': {'iprop_replica_poll': '600', 'iprop_logfile': '$testdir/ulog.replica3', 'iprop_port': '$port8'}, 'FOO': {'iprop_logfile': '$testdir/ulog.replica3'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.replica3'}}} krb5_conf_rep4 = {'domain_realm': {hostname: 'FOO'}} conf_rep4 = {'realms': {'$realm': {'iprop_replica_poll': '600', 'iprop_logfile': '$testdir/ulog.replica4', 'iprop_port': '$port8'}}, 'dbmodules': {'db': {'database_name': '$testdir/db.replica4'}}} for realm in multidb_realms(kdc_conf=conf, create_user=False, start_kadmind=True): replica1 = realm.special_env('replica1', True, kdc_conf=conf_rep1) replica1m = realm.special_env('replica1m', True, krb5_conf=conf_foo, kdc_conf=conf_rep1m) replica2 = realm.special_env('replica2', True, kdc_conf=conf_rep2) # A default_realm and domain_realm that do not match the KDC's # realm. The FOO realm iprop_logfile setting is needed to run # kproplog during a replica3 test, since kproplog has no realm # option. replica3 = realm.special_env('replica3', True, krb5_conf=conf_foo, kdc_conf=conf_rep3) # A default realm and a domain realm map that differ. replica4 = realm.special_env('replica4', True, krb5_conf=krb5_conf_rep4, kdc_conf=conf_rep4) # Define some principal names. pr3 is long enough to cause internal # reallocs, but not long enough to grow the basic ulog entry size. pr1 = 'wakawaka@' + realm.realm pr2 = 'w@' + realm.realm c = 'chocolate-flavored-school-bus' cs = c + '/' pr3 = (cs + cs + cs + cs + cs + cs + cs + cs + cs + cs + cs + cs + c + '@' + realm.realm) # Create the kpropd ACL file. acl_file = os.path.join(realm.testdir, 'kpropd-acl') acl = open(acl_file, 'w') acl.write(realm.host_princ + '\n') acl.close() ulog = os.path.join(realm.testdir, 'db.ulog') if not os.path.exists(ulog): fail('update log not created: ' + ulog) # Create the principal used to authenticate kpropd to kadmind. kiprop_princ = 'kiprop/' + hostname realm.addprinc(kiprop_princ) realm.extract_keytab(kiprop_princ, realm.keytab) # Create the initial replica databases. dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile], replica1) realm.run([kdb5_util, 'load', dumpfile], replica2) realm.run([kdb5_util, '-r', realm.realm, 'load', dumpfile], replica3) realm.run([kdb5_util, 'load', dumpfile], replica4) # Reinitialize the primary ulog so we know exactly what to expect # in it. realm.run([kproplog, '-R']) check_ulog(1, 1, 1, [None]) # Make some changes to the primary DB. realm.addprinc(pr1) realm.addprinc(pr3) realm.addprinc(pr2) realm.run([kadminl, 'modprinc', '-allow_tix', pr2]) realm.run([kadminl, 'modprinc', '+allow_tix', pr2]) check_ulog(6, 1, 6, [None, pr1, pr3, pr2, pr2, pr2]) # Start kpropd for replica1 and get a full dump from primary. mark('propagate M->1 full') kpropd1 = realm.start_kpropd(replica1, ['-d']) wait_for_prop(kpropd1, True, 1, 6) out = realm.run([kadminl, 'listprincs'], env=replica1) if pr1 not in out or pr2 not in out or pr3 not in out: fail('replica1 does not have all principals from primary') check_ulog(1, 6, 6, [None], replica1) # Make a change and check that it propagates incrementally. mark('propagate M->1 incremental') realm.run([kadminl, 'modprinc', '-allow_tix', pr2]) check_ulog(7, 1, 7, [None, pr1, pr3, pr2, pr2, pr2, pr2]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 6, 7) check_ulog(2, 6, 7, [None, pr2], replica1) realm.run([kadminl, 'getprinc', pr2], env=replica1, expected_msg='Attributes: DISALLOW_ALL_TIX') # Start kadmind -proponly for replica1. (Use the replica1m # environment which defines iprop_port to $port8.) replica1_out_dump_path = os.path.join(realm.testdir, 'dump.replica1.out') replica2_in_dump_path = os.path.join(realm.testdir, 'dump.replica2.in') replica2_kprop_port = str(realm.portbase + 9) kadmind_proponly = realm.start_server([kadmind, '-r', realm.realm, '-nofork', '-proponly', '-p', kdb5_util, '-K', kprop, '-k', replica2_kprop_port, '-F', replica1_out_dump_path], 'starting...', replica1m) # Test similar default_realm and domain_realm map settings with -r realm. mark('propagate 1->3 full') replica3_in_dump_path = os.path.join(realm.testdir, 'dump.replica3.in') kpropd3 = realm.start_server([kpropd, '-d', '-D', '-r', realm.realm, '-P', replica2_kprop_port, '-f', replica3_in_dump_path, '-p', kdb5_util, '-a', acl_file, '-A', hostname], 'ready', replica3) wait_for_prop(kpropd3, True, 1, 7) out = realm.run([kadminl, '-r', realm.realm, 'listprincs'], env=replica3) if pr1 not in out or pr2 not in out or pr3 not in out: fail('replica3 does not have all principals from replica1') check_ulog(1, 7, 7, [None], env=replica3) # Test an incremental propagation for the kpropd -r case. mark('propagate M->1->3 incremental') realm.run([kadminl, 'modprinc', '-maxlife', '20 minutes', pr1]) check_ulog(8, 1, 8, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 7, 8) check_ulog(3, 6, 8, [None, pr2, pr1], replica1) realm.run([kadminl, 'getprinc', pr1], env=replica1, expected_msg='Maximum ticket life: 0 days 00:20:00') kpropd3.send_signal(signal.SIGUSR1) wait_for_prop(kpropd3, False, 7, 8) check_ulog(2, 7, 8, [None, pr1], replica3) realm.run([kadminl, '-r', realm.realm, 'getprinc', pr1], env=replica3, expected_msg='Maximum ticket life: 0 days 00:20:00') stop_daemon(kpropd3) # Test dissimilar default_realm and domain_realm map settings (no # -r realm). mark('propagate 1->4 full') replica4_in_dump_path = os.path.join(realm.testdir, 'dump.replica4.in') kpropd4 = realm.start_server([kpropd, '-d', '-D', '-P', replica2_kprop_port, '-f', replica4_in_dump_path, '-p', kdb5_util, '-a', acl_file, '-A', hostname], 'ready', replica4) wait_for_prop(kpropd4, True, 1, 8) out = realm.run([kadminl, 'listprincs'], env=replica4) if pr1 not in out or pr2 not in out or pr3 not in out: fail('replica4 does not have all principals from replica1') stop_daemon(kpropd4) # Start kpropd for replica2. The -A option isn't needed since # we're talking to the same host as primary (we specify it anyway # to exercise the code), but replica2 defines iprop_port to $port8 # so it will talk to replica1. Get a full dump from replica1. mark('propagate 1->2 full') kpropd2 = realm.start_server([kpropd, '-d', '-D', '-P', replica2_kprop_port, '-f', replica2_in_dump_path, '-p', kdb5_util, '-a', acl_file, '-A', hostname], 'ready', replica2) wait_for_prop(kpropd2, True, 1, 8) check_ulog(2, 7, 8, [None, pr1], replica2) out = realm.run([kadminl, 'listprincs'], env=replica1) if pr1 not in out or pr2 not in out or pr3 not in out: fail('replica2 does not have all principals from replica1') # Make another change and check that it propagates incrementally # to both replicas. mark('propagate M->1->2 incremental') realm.run([kadminl, 'modprinc', '-maxrenewlife', '22 hours', pr1]) check_ulog(9, 1, 9, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr1]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 8, 9) check_ulog(4, 6, 9, [None, pr2, pr1, pr1], replica1) realm.run([kadminl, 'getprinc', pr1], env=replica1, expected_msg='Maximum renewable life: 0 days 22:00:00\n') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 8, 9) check_ulog(3, 7, 9, [None, pr1, pr1], replica2) realm.run([kadminl, 'getprinc', pr1], env=replica2, expected_msg='Maximum renewable life: 0 days 22:00:00\n') # Reset the ulog on replica1 to force a full resync from primary. # The resync will use the old dump file and then propagate # changes. replica2 should still be in sync with replica1 after # the resync, so make sure it doesn't take a full resync. mark('propagate M->1->2 full') realm.run([kproplog, '-R'], replica1) check_ulog(1, 1, 1, [None], replica1) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 1, 9) check_ulog(4, 6, 9, [None, pr2, pr1, pr1], replica1) kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 9, 9) check_ulog(3, 7, 9, [None, pr1, pr1], replica2) # Make another change and check that it propagates incrementally to # both replicas. mark('propagate M->1->2 incremental (after reset)') realm.run([kadminl, 'modprinc', '+allow_tix', pr2]) check_ulog(10, 1, 10, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr1, pr2]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 9, 10) check_ulog(5, 6, 10, [None, pr2, pr1, pr1, pr2], replica1) realm.run([kadminl, 'getprinc', pr2], env=replica1, expected_msg='Attributes:\n') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 9, 10) check_ulog(4, 7, 10, [None, pr1, pr1, pr2], replica2) realm.run([kadminl, 'getprinc', pr2], env=replica2, expected_msg='Attributes:\n') # Create a policy and check that it propagates via full resync. mark('propagate M->1->2 full (new policy)') realm.run([kadminl, 'addpol', '-minclasses', '2', 'testpol']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 10, 1) check_ulog(1, 1, 1, [None], replica1) realm.run([kadminl, 'getpol', 'testpol'], env=replica1, expected_msg='Minimum number of password character classes: 2') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, True, 10, 1) check_ulog(1, 1, 1, [None], replica2) realm.run([kadminl, 'getpol', 'testpol'], env=replica2, expected_msg='Minimum number of password character classes: 2') # Modify the policy and test that it also propagates via full resync. mark('propagate M->1->2 full (policy change)') realm.run([kadminl, 'modpol', '-minlength', '17', 'testpol']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 1, 1) check_ulog(1, 1, 1, [None], replica1) realm.run([kadminl, 'getpol', 'testpol'], env=replica1, expected_msg='Minimum password length: 17') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, True, 1, 1) check_ulog(1, 1, 1, [None], replica2) realm.run([kadminl, 'getpol', 'testpol'], env=replica2, expected_msg='Minimum password length: 17') # Delete the policy and test that it propagates via full resync. mark('propgate M->1->2 full (policy delete)') realm.run([kadminl, 'delpol', 'testpol']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 1, 1) check_ulog(1, 1, 1, [None], replica1) realm.run([kadminl, 'getpol', 'testpol'], env=replica1, expected_code=1, expected_msg='Policy does not exist') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, True, 1, 1) check_ulog(1, 1, 1, [None], replica2) realm.run([kadminl, 'getpol', 'testpol'], env=replica2, expected_code=1, expected_msg='Policy does not exist') # Modify a principal on the primary and test that it propagates # incrementally. mark('propagate M->1->2 incremental (after policy changes)') realm.run([kadminl, 'modprinc', '-maxlife', '10 minutes', pr1]) check_ulog(2, 1, 2, [None, pr1]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 1, 2) check_ulog(2, 1, 2, [None, pr1], replica1) realm.run([kadminl, 'getprinc', pr1], env=replica1, expected_msg='Maximum ticket life: 0 days 00:10:00') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 1, 2) check_ulog(2, 1, 2, [None, pr1], replica2) realm.run([kadminl, 'getprinc', pr1], env=replica2, expected_msg='Maximum ticket life: 0 days 00:10:00') # Delete a principal and test that it propagates incrementally. mark('propagate M->1->2 incremental (princ delete)') realm.run([kadminl, 'delprinc', pr3]) check_ulog(3, 1, 3, [None, pr1, pr3]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 2, 3) check_ulog(3, 1, 3, [None, pr1, pr3], replica1) realm.run([kadminl, 'getprinc', pr3], env=replica1, expected_code=1, expected_msg='Principal does not exist') kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 2, 3) check_ulog(3, 1, 3, [None, pr1, pr3], replica2) realm.run([kadminl, 'getprinc', pr3], env=replica2, expected_code=1, expected_msg='Principal does not exist') # Rename a principal and test that it propagates incrementally. mark('propagate M->1->2 incremental (princ rename)') renpr = "quacked@" + realm.realm realm.run([kadminl, 'renprinc', pr1, renpr]) check_ulog(6, 1, 6, [None, pr1, pr3, renpr, pr1, renpr]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 3, 6) check_ulog(6, 1, 6, [None, pr1, pr3, renpr, pr1, renpr], replica1) realm.run([kadminl, 'getprinc', pr1], env=replica1, expected_code=1, expected_msg='Principal does not exist') realm.run([kadminl, 'getprinc', renpr], env=replica1) kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 3, 6) check_ulog(6, 1, 6, [None, pr1, pr3, renpr, pr1, renpr], replica2) realm.run([kadminl, 'getprinc', pr1], env=replica2, expected_code=1, expected_msg='Principal does not exist') realm.run([kadminl, 'getprinc', renpr], env=replica2) pr1 = renpr # Reset the ulog on the primary to force a full resync. mark('propagate M->1->2 full (ulog reset)') realm.run([kproplog, '-R']) check_ulog(1, 1, 1, [None]) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 6, 1) check_ulog(1, 1, 1, [None], replica1) kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, True, 6, 1) check_ulog(1, 1, 1, [None], replica2) # Create an update large enough to cause a block resize, and make # sure that it propagates incrementally. mark('block resize') cmd = [kadminl, 'cpw', '-e', 'aes128-sha1,aes256-sha1,aes128-sha2,aes256-sha2', '-randkey', '-keepold', pr2] n = 6 for i in range(n): realm.run(cmd) check_ulog(n + 1, 1, n + 1, [None] + n * [pr2], bsize=4096) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, False, 1, n + 1) check_ulog(n + 1, 1, n + 1, [None] + n * [pr2], replica1, bsize=4096) kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, False, 1, n + 1) check_ulog(n + 1, 1, n + 1, [None] + n * [pr2], replica2, bsize=4096) # Reset the ulog again. realm.run([kproplog, '-R']) kpropd1.send_signal(signal.SIGUSR1) wait_for_prop(kpropd1, True, 7, 1) kpropd2.send_signal(signal.SIGUSR1) wait_for_prop(kpropd2, True, 7, 1) realm.stop_kpropd(kpropd1) # Stop the kprop daemons so we can test kpropd -t. stop_daemon(kpropd2) stop_daemon(kadmind_proponly) mark('kpropd -t') # Test the case where no updates are needed. out = realm.run_kpropd_once(replica1, ['-d']) if 'KDC is synchronized' not in out: fail('Expected synchronized from kpropd -t') check_ulog(1, 1, 1, [None], replica1) # Make a change on the primary and fetch it incrementally. realm.run([kadminl, 'modprinc', '-maxlife', '5 minutes', pr1]) check_ulog(2, 1, 2, [None, pr1]) out = realm.run_kpropd_once(replica1, ['-d']) if 'Got incremental updates (sno=2 ' not in out: fail('Expected full dump and synchronized from kpropd -t') check_ulog(2, 1, 2, [None, pr1], replica1) realm.run([kadminl, 'getprinc', pr1], env=replica1, expected_msg='Maximum ticket life: 0 days 00:05:00') # Propagate a policy change via full resync. realm.run([kadminl, 'addpol', '-minclasses', '3', 'testpol']) check_ulog(1, 1, 1, [None]) out = realm.run_kpropd_once(replica1, ['-d']) if ('Full propagation transfer finished' not in out or 'KDC is synchronized' not in out): fail('Expected full dump and synchronized from kpropd -t') check_ulog(1, 1, 1, [None], replica1) realm.run([kadminl, 'getpol', 'testpol'], env=replica1, expected_msg='Minimum number of password character classes: 3') success('iprop tests') krb5-1.22.1/src/tests/create/0000775000175000017500000000000015051422640015535 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/create/Makefile.in0000664000175000017500000000055015051422640017602 0ustar ghudsonghudsonmydir=tests$(S)create BUILDTOP=$(REL)..$(S).. SRCS=$(srcdir)/kdb5_mkdums.c KDB5_DEP_LIBS=$(THREAD_LINKOPTS) $(DL_LIB) all: kdb5_mkdums kdb5_mkdums: kdb5_mkdums.o $(KDB5_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kdb5_mkdums kdb5_mkdums.o $(KDB5_DEP_LIBS) $(KDB5_LIBS) $(KRB5_BASE_LIBS) all: kdb5_mkdums install: clean: $(RM) kdb5_mkdums.o kdb5_mkdums krb5-1.22.1/src/tests/create/deps0000664000175000017500000000143715051422640016420 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)kdb5_mkdums.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SS_DEPS) \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kdb5_mkdums.c krb5-1.22.1/src/tests/create/kdb5_mkdums.c0000664000175000017500000003162115051422640020111 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/create/kdb5_mkdums.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * Edit a KDC database. */ #include "k5-int.h" #include "kdb.h" #include "com_err.h" #include #include #define REALM_SEP '@' #define REALM_SEP_STR "@" struct mblock { krb5_deltat max_life; krb5_deltat max_rlife; krb5_timestamp expiration; krb5_flags flags; krb5_kvno mkvno; } mblock = { /* XXX */ KRB5_KDB_MAX_LIFE, KRB5_KDB_MAX_RLIFE, KRB5_KDB_EXPIRATION, KRB5_KDB_DEF_FLAGS, 1 }; int set_dbname_help (char *, char *); static void usage(char *who, int status) { fprintf(stderr, "usage: %s -p prefix -n num_to_create [-d dbpathname] [-r realmname]\n", who); fprintf(stderr, "\t [-D depth] [-k enctype] [-M mkeyname]\n"); exit(status); } int master_princ_set = 0; krb5_keyblock master_keyblock; krb5_principal master_princ; krb5_pointer master_random; krb5_context test_context; static char *progname; static char *cur_realm = 0; static char *mkey_name = 0; static char *mkey_password = 0; static krb5_boolean manual_mkey = FALSE; void add_princ (krb5_context, char *); int main(int argc, char *argv[]) { extern char *optarg; int optchar, i, n; char tmp[4096], tmp2[BUFSIZ], *str_newprinc; krb5_error_code retval; char *dbname = 0; int enctypedone = 0; int num_to_create; char principal_string[BUFSIZ]; char *suffix = 0; size_t suffix_size = 0; int depth; krb5_init_context(&test_context); if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; progname = argv[0]; memset(principal_string, 0, sizeof(principal_string)); num_to_create = 0; depth = 1; while ((optchar = getopt(argc, argv, "D:P:p:n:d:r:k:M:e:m")) != -1) { switch(optchar) { case 'D': depth = atoi(optarg); /* how deep to go */ break; case 'P': /* Only used for testing!!! */ mkey_password = optarg; break; case 'p': /* prefix name to create */ strncpy(principal_string, optarg, sizeof(principal_string) - 1); principal_string[sizeof(principal_string) - 1] = '\0'; suffix = principal_string + strlen(principal_string); suffix_size = sizeof(principal_string) - (suffix - principal_string); break; case 'n': /* how many to create */ num_to_create = atoi(optarg); break; case 'd': /* set db name */ dbname = optarg; break; case 'r': cur_realm = optarg; break; case 'k': master_keyblock.enctype = atoi(optarg); enctypedone++; break; case 'M': /* master key name in DB */ mkey_name = optarg; break; case 'm': manual_mkey = TRUE; break; case '?': default: usage(progname, 1); /*NOTREACHED*/ } } if (!(num_to_create && suffix)) usage(progname, 1); if (!enctypedone) master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; if (!krb5_c_valid_enctype(master_keyblock.enctype)) { com_err(progname, KRB5_PROG_ETYPE_NOSUPP, "while setting up enctype %d", master_keyblock.enctype); exit(1); } if (!dbname) dbname = DEFAULT_KDB_FILE; /* XXX? */ if (!cur_realm) { if ((retval = krb5_get_default_realm(test_context, &cur_realm))) { com_err(progname, retval, "while retrieving default realm name"); exit(1); } } if ((retval = set_dbname_help(progname, dbname))) exit(retval); for (n = 1; n <= num_to_create; n++) { /* build the new principal name */ /* we can't pick random names because we need to generate all the names again given a prefix and count to test the db lib and kdb */ (void) snprintf(suffix, suffix_size, "%d", n); (void) snprintf(tmp, sizeof(tmp), "%s-DEPTH-1", principal_string); tmp[sizeof(tmp) - 1] = '\0'; str_newprinc = tmp; add_princ(test_context, str_newprinc); for (i = 2; i <= depth; i++) { (void) snprintf(tmp2, sizeof(tmp2), "/%s-DEPTH-%d", principal_string, i); tmp2[sizeof(tmp2) - 1] = '\0'; strncat(tmp, tmp2, sizeof(tmp) - 1 - strlen(tmp)); str_newprinc = tmp; add_princ(test_context, str_newprinc); } } retval = krb5_db_fini(test_context); memset(master_keyblock.contents, 0, (size_t) master_keyblock.length); if (retval && retval != KRB5_KDB_DBNOTINITED) { com_err(progname, retval, "while closing database"); exit(1); } if (master_princ_set) krb5_free_principal(test_context, master_princ); krb5_free_context(test_context); exit(0); } void add_princ(krb5_context context, char *str_newprinc) { krb5_error_code retval; krb5_principal newprinc; krb5_db_entry *newentry; char princ_name[4096]; newentry = calloc(1, sizeof(*newentry)); if (newentry == NULL) { com_err(progname, ENOMEM, "while allocating DB entry"); return; } snprintf(princ_name, sizeof(princ_name), "%s@%s", str_newprinc, cur_realm); if ((retval = krb5_parse_name(context, princ_name, &newprinc))) { com_err(progname, retval, "while parsing '%s'", princ_name); return; } /* Add basic data */ newentry->len = KRB5_KDB_V1_BASE_LENGTH; newentry->attributes = mblock.flags; newentry->max_life = mblock.max_life; newentry->max_renewable_life = mblock.max_rlife; newentry->expiration = mblock.expiration; newentry->pw_expiration = mblock.expiration; /* Add princ to db entry */ if ((retval = krb5_copy_principal(context, newprinc, &newentry->princ))) { com_err(progname, retval, "while encoding princ to db entry for '%s'", princ_name); krb5_free_principal(context, newprinc); goto error; } { /* Add mod princ to db entry */ krb5_timestamp now; retval = krb5_timeofday(context, &now); if (retval) { com_err(progname, retval, "while fetching date"); krb5_free_principal(context, newprinc); goto error; } retval = krb5_dbe_update_mod_princ_data(context, newentry, now, master_princ); if (retval) { com_err(progname, retval, "while encoding mod_princ data"); krb5_free_principal(context, newprinc); goto error; } } { /* Add key and salt data to db entry */ krb5_data pwd, salt; krb5_keyblock key; if ((retval = krb5_principal2salt(context, newprinc, &salt))) { com_err(progname, retval, "while converting princ to salt for '%s'", princ_name); krb5_free_principal(context, newprinc); goto error; } krb5_free_principal(context, newprinc); pwd.length = strlen(princ_name); pwd.data = princ_name; /* must be able to regenerate */ if ((retval = krb5_c_string_to_key(context, master_keyblock.enctype, &pwd, &salt, &key))) { com_err(progname,retval,"while converting password to key for '%s'", princ_name); krb5_free_data_contents(context, &salt); goto error; } krb5_free_data_contents(context, &salt); if ((retval = krb5_dbe_create_key_data(context, newentry))) { com_err(progname, retval, "while creating key_data for '%s'", princ_name); free(key.contents); goto error; } if ((retval = krb5_dbe_encrypt_key_data(context, &master_keyblock, &key, NULL, 1, newentry->key_data))) { com_err(progname, retval, "while encrypting key for '%s'", princ_name); free(key.contents); goto error; } free(key.contents); } if ((retval = krb5_db_put_principal(context, newentry))) { com_err(progname, retval, "while storing principal date"); goto error; } error: /* Do cleanup of newentry regardless of error */ krb5_db_free_principal(context, newentry); return; } int set_dbname_help(char *pname, char *dbname) { krb5_error_code retval; krb5_data pwd, scratch; char *args[2]; krb5_db_entry *master_entry; /* assemble & parse the master key name */ if ((retval = krb5_db_setup_mkey_name(test_context, mkey_name, cur_realm, 0, &master_princ))) { com_err(pname, retval, "while setting up master key name"); return(1); } master_princ_set = 1; if (mkey_password) { pwd.data = mkey_password; pwd.length = strlen(mkey_password); retval = krb5_principal2salt(test_context, master_princ, &scratch); if (retval) { com_err(pname, retval, "while calculated master key salt"); return(1); } if ((retval = krb5_c_string_to_key(test_context, master_keyblock.enctype, &pwd, &scratch, &master_keyblock))) { com_err(pname, retval, "while transforming master key from password"); return(1); } free(scratch.data); } else { if ((retval = krb5_db_fetch_mkey(test_context, master_princ, master_keyblock.enctype, manual_mkey, FALSE, 0, NULL, NULL, &master_keyblock))) { com_err(pname, retval, "while reading master key"); return(1); } } /* Ick! Current DAL interface requires that the default_realm field be set in the krb5_context. */ if ((retval = krb5_set_default_realm(test_context, cur_realm))) { com_err(pname, retval, "setting default realm"); return 1; } /* Pathname is passed to db2 via 'args' parameter. */ args[1] = NULL; if (asprintf(&args[0], "dbname=%s", dbname) < 0) { com_err(pname, errno, "while setting up db parameters"); return 1; } if ((retval = krb5_db_open(test_context, args, KRB5_KDB_OPEN_RO))) { com_err(pname, retval, "while initializing database"); return(1); } /* Done with args */ free(args[0]); if ((retval = krb5_db_fetch_mkey_list(test_context, master_princ, &master_keyblock))){ com_err(pname, retval, "while verifying master key"); (void) krb5_db_fini(test_context); return(1); } if ((retval = krb5_db_get_principal(test_context, master_princ, 0, &master_entry))) { com_err(pname, retval, "while retrieving master entry"); (void) krb5_db_fini(test_context); return(1); } mblock.max_life = master_entry->max_life; mblock.max_rlife = master_entry->max_renewable_life; mblock.expiration = master_entry->expiration; /* don't set flags, master has some extra restrictions */ mblock.mkvno = master_entry->key_data[0].key_data_kvno; krb5_db_free_principal(test_context, master_entry); return 0; } krb5-1.22.1/src/tests/t_skew.py0000775000175000017500000000444115051422640016146 0ustar ghudsonghudsonfrom k5test import * # Create a realm with the KDC one hour in the past. realm = K5Realm(start_kdc=False) realm.start_kdc(['-T', '-3600']) # kinit (no preauth) should work, and should set a clock skew allowing # kvno to work, with or without FAST. mark('kdc_timesync enabled, no preauth') realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache]) realm.run([kvno, realm.host_princ]) realm.run([kdestroy]) # kinit (with preauth) should work, with or without FAST. mark('kdc_timesync enabled, with preauth') realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache]) realm.run([kvno, realm.host_princ]) realm.run([kdestroy]) realm.stop() # Repeat the above tests with kdc_timesync disabled. conf = {'libdefaults': {'kdc_timesync': '0'}} realm = K5Realm(start_kdc=False, krb5_conf=conf) realm.start_kdc(['-T', '-3600']) # Get tickets to use for FAST kinit tests. The start time offset is # ignored by the KDC since we aren't getting postdatable tickets, but # serves to suppress the client clock skew check on the KDC reply. fast_cache = realm.ccache + '.fast' realm.kinit(realm.user_princ, password('user'), flags=['-s', '-3600s', '-c', fast_cache]) # kinit should detect too much skew in the KDC response. kinit with # FAST should fail from the KDC since the armor AP-REQ won't be valid. mark('KDC timesync disabled, no preauth') realm.kinit(realm.user_princ, password('user'), expected_code=1, expected_msg='Clock skew too great in KDC reply') realm.kinit(realm.user_princ, None, flags=['-T', fast_cache], expected_code=1, expected_msg='Clock skew too great while') # kinit (with preauth) should fail from the KDC, with or without FAST. mark('KDC timesync disabled, with preauth') realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) realm.kinit(realm.user_princ, password('user'), expected_code=1, expected_msg='Clock skew too great while') realm.kinit(realm.user_princ, None, flags=['-T', fast_cache], expected_code=1, expected_msg='Clock skew too great while') success('Clock skew tests') krb5-1.22.1/src/tests/t_otp.py0000775000175000017500000002333515051422640016002 0ustar ghudsonghudson# Author: Nathaniel McCallum # # Copyright (c) 2013 Red Hat, Inc. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # This script tests OTP, both UDP and Unix Sockets, with a variety of # configuration. It requires pyrad to run, but exits gracefully if not found. # It also deliberately shuts down the test daemons between tests in order to # test how OTP handles the case of short daemon restarts. # from k5test import * from queue import Empty import io import struct try: from pyrad import packet, dictionary except ImportError: skip_rest('OTP tests', 'Python pyrad module not found') try: from multiprocessing import Process, Queue except ImportError: skip_rest('OTP tests', 'Python version 2.6 required') # We could use a dictionary file, but since we need so few attributes, # we'll just include them here. radius_attributes = ''' ATTRIBUTE User-Name 1 string ATTRIBUTE User-Password 2 octets ATTRIBUTE Service-Type 6 integer ATTRIBUTE NAS-Identifier 32 string ATTRIBUTE Message-Authenticator 80 octets ''' class RadiusDaemon(Process): MAX_PACKET_SIZE = 4096 DICTIONARY = dictionary.Dictionary(io.StringIO(radius_attributes)) def listen(self, addr): raise NotImplementedError() def recvRequest(self, data): raise NotImplementedError() def run(self): addr = self._args[0] secrfile = self._args[1] pswd = self._args[2] outq = self._args[3] if secrfile: with open(secrfile, 'rb') as file: secr = file.read().strip() else: secr = b'' data = self.listen(addr) outq.put("started") (buf, sock, addr) = self.recvRequest(data) pkt = packet.AuthPacket(secret=secr, dict=RadiusDaemon.DICTIONARY, packet=buf) usernm = [] passwd = [] for key in pkt.keys(): if key == 'User-Password': passwd = list(map(pkt.PwDecrypt, pkt[key])) elif key == 'User-Name': usernm = pkt[key] reply = pkt.CreateReply() replyq = {'user': usernm, 'pass': passwd} if passwd == [pswd]: reply.code = packet.AccessAccept replyq['reply'] = True else: reply.code = packet.AccessReject replyq['reply'] = False reply.add_message_authenticator() outq.put(replyq) if addr is None: sock.send(reply.ReplyPacket()) else: sock.sendto(reply.ReplyPacket(), addr) sock.close() class UDPRadiusDaemon(RadiusDaemon): def listen(self, addr): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((addr.split(':')[0], int(addr.split(':')[1]))) return sock def recvRequest(self, sock): (buf, addr) = sock.recvfrom(RadiusDaemon.MAX_PACKET_SIZE) return (buf, sock, addr) class UnixRadiusDaemon(RadiusDaemon): def listen(self, addr): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) if os.path.exists(addr): os.remove(addr) sock.bind(addr) sock.listen(1) return (sock, addr) def recvRequest(self, sock_and_addr): sock, addr = sock_and_addr conn = sock.accept()[0] sock.close() os.remove(addr) buf = b'' remain = RadiusDaemon.MAX_PACKET_SIZE while True: buf += conn.recv(remain) remain = RadiusDaemon.MAX_PACKET_SIZE - len(buf) if (len(buf) >= 4): remain = struct.unpack("!BBH", buf[0:4])[2] - len(buf) if (remain <= 0): return (buf, conn, None) def verify(daemon, queue, reply, usernm, passwd): try: data = queue.get(timeout=1) except Empty: sys.stderr.write("ERROR: Packet not received by daemon!\n") daemon.terminate() sys.exit(1) assert data['reply'] is reply assert data['user'] == [usernm] assert data['pass'] == [passwd] daemon.join() # Compose a single token configuration. def otpconfig_1(toktype, username=None, indicators=None): val = '{"type": "%s"' % toktype if username is not None: val += ', "username": "%s"' % username if indicators is not None: qind = ['"%s"' % s for s in indicators] jsonlist = '[' + ', '.join(qind) + ']' val += ', "indicators":' + jsonlist val += '}' return val # Compose a token configuration list suitable for the "otp" string # attribute. def otpconfig(toktype, username=None, indicators=None): return '[' + otpconfig_1(toktype, username, indicators) + ']' prefix = "/tmp/%d" % os.getpid() secret_file = prefix + ".secret" socket_file = prefix + ".socket" with open(secret_file, "w") as file: file.write("otptest") atexit.register(lambda: os.remove(secret_file)) conf = {'plugins': {'kdcpreauth': {'enable_only': 'otp'}}, 'otp': {'udp': {'server': '127.0.0.1:$port9', 'secret': secret_file, 'strip_realm': 'true', 'indicator': ['indotp1', 'indotp2']}, 'unix': {'server': socket_file, 'strip_realm': 'false'}}} queue = Queue() realm = K5Realm(kdc_conf=conf) realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ]) flags = ['-T', realm.ccache] server_addr = '127.0.0.1:' + str(realm.portbase + 9) ## Test UDP fail / custom username mark('UDP fail / custom username') daemon = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept', queue)) daemon.start() queue.get() realm.run([kadminl, 'setstr', realm.user_princ, 'otp', otpconfig('udp', 'custom')]) realm.kinit(realm.user_princ, 'reject', flags=flags, expected_code=1) verify(daemon, queue, False, 'custom', 'reject') ## Test UDP success / standard username mark('UDP success / standard username') daemon = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept', queue)) daemon.start() queue.get() realm.run([kadminl, 'setstr', realm.user_princ, 'otp', otpconfig('udp')]) realm.kinit(realm.user_princ, 'accept', flags=flags) verify(daemon, queue, True, realm.user_princ.split('@')[0], 'accept') realm.extract_keytab(realm.krbtgt_princ, realm.keytab) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indotp1, indotp2]') # Repeat with an indicators override in the string attribute. mark('auth indicator override') daemon = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept', queue)) daemon.start() queue.get() oconf = otpconfig('udp', indicators=['indtok1', 'indtok2']) realm.run([kadminl, 'setstr', realm.user_princ, 'otp', oconf]) realm.kinit(realm.user_princ, 'accept', flags=flags) verify(daemon, queue, True, realm.user_princ.split('@')[0], 'accept') realm.extract_keytab(realm.krbtgt_princ, realm.keytab) realm.run(['./adata', realm.krbtgt_princ], expected_msg='+97: [indtok1, indtok2]') # Detect upstream pyrad bug # https://github.com/wichert/pyrad/pull/18 try: auth = packet.Packet.CreateAuthenticator() packet.Packet(authenticator=auth, secret=b'').ReplyPacket() except AssertionError: skip_rest('OTP UNIX domain socket tests', 'pyrad assertion bug detected') ## Test Unix fail / custom username mark('Unix socket fail / custom username') daemon = UnixRadiusDaemon(args=(socket_file, None, 'accept', queue)) daemon.start() queue.get() realm.run([kadminl, 'setstr', realm.user_princ, 'otp', otpconfig('unix', 'custom')]) realm.kinit(realm.user_princ, 'reject', flags=flags, expected_code=1) verify(daemon, queue, False, 'custom', 'reject') ## Test Unix success / standard username mark('Unix socket success / standard username') daemon = UnixRadiusDaemon(args=(socket_file, None, 'accept', queue)) daemon.start() queue.get() realm.run([kadminl, 'setstr', realm.user_princ, 'otp', otpconfig('unix')]) realm.kinit(realm.user_princ, 'accept', flags=flags) verify(daemon, queue, True, realm.user_princ, 'accept') ## Regression test for #8708: test with the standard username and two ## tokens configured, with the first rejecting and the second ## accepting. With the bug, the KDC incorrectly rejects the request ## and then performs invalid memory accesses, most likely crashing. queue2 = Queue() daemon1 = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept1', queue)) daemon2 = UnixRadiusDaemon(args=(socket_file, None, 'accept2', queue2)) daemon1.start() queue.get() daemon2.start() queue2.get() oconf = '[' + otpconfig_1('udp') + ', ' + otpconfig_1('unix') + ']' realm.run([kadminl, 'setstr', realm.user_princ, 'otp', oconf]) realm.kinit(realm.user_princ, 'accept2', flags=flags) verify(daemon1, queue, False, realm.user_princ.split('@')[0], 'accept2') verify(daemon2, queue2, True, realm.user_princ, 'accept2') success('OTP tests') krb5-1.22.1/src/tests/t_sn2princ.py0000775000175000017500000001604615051422640016737 0ustar ghudsonghudsonfrom k5test import * offline = (len(args) > 0 and args[0] != "no") conf = {'libdefaults': {'dns_canonicalize_hostname': 'true'}, 'domain_realm': {'kerberos.org': 'R1', 'example.com': 'R2', 'mit.edu': 'R3'}} no_rdns_conf = {'libdefaults': {'rdns': 'false'}} no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false', 'qualify_shortname': 'example.com'}} fallback_canon_conf = {'libdefaults': {'rdns': 'false', 'dns_canonicalize_hostname': 'fallback'}} realm = K5Realm(realm='R1', create_host=False, krb5_conf=conf) no_rdns = realm.special_env('no_rdns', False, krb5_conf=no_rdns_conf) no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf) fallback_canon = realm.special_env('fallback_canon', False, krb5_conf=fallback_canon_conf) def testbase(host, nametype, princhost, princrealm, env=None): # Run the sn2princ harness with a specified host and name type and # the fixed service string 'svc', and compare the result to the # expected hostname and realm part. out = realm.run(['./s2p', host, 'SVC', nametype], env=env).rstrip() expected = 'SVC/%s@%s' % (princhost, princrealm) if out != expected: fail('Expected %s, got %s' % (expected, out)) def test(host, princhost, princrealm): # Test with the host-based name type with canonicalization enabled. testbase(host, 'srv-hst', princhost, princrealm) def testnc(host, princhost, princrealm): # Test with the host-based name type with canonicalization disabled. testbase(host, 'srv-hst', princhost, princrealm, env=no_canon) def testnr(host, princhost, princrealm): # Test with the host-based name type with reverse lookup disabled. testbase(host, 'srv-hst', princhost, princrealm, env=no_rdns) def testu(host, princhost, princrealm): # Test with the unknown name type. testbase(host, 'unknown', princhost, princrealm) def testfc(host, princhost, princrealm): # Test with the host-based name type with canonicalization fallback. testbase(host, 'srv-hst', princhost, princrealm, env=fallback_canon) # With the unknown principal type, we do not canonicalize or downcase, # but we do remove a trailing period and look up the realm. mark('unknown type') testu('ptr-mismatch.kerberos.org', 'ptr-mismatch.kerberos.org', 'R1') testu('Example.COM', 'Example.COM', 'R2') testu('abcde', 'abcde', '') # A ':port' or ':instance' trailer should be ignored for realm lookup. # If there is more than one colon in the name, we assume it's an IPv6 # address and don't treat it as having a trailer. mark('port trailer') testu('example.com.:123', 'example.com.:123', 'R2') testu('Example.COM:xyZ', 'Example.COM:xyZ', 'R2') testu('example.com.::123', 'example.com.::123', '') # With dns_canonicalize_hostname=false, we downcase and remove # trailing dots but do not canonicalize the hostname. # Single-component names are qualified with the configured suffix # (defaulting to the first OS search domain, but Python cannot easily # retrieve that value so we don't test it). Trailers do not get # downcased. mark('dns_canonicalize_host=false') testnc('ptr-mismatch.kerberos.org', 'ptr-mismatch.kerberos.org', 'R1') testnc('Example.COM', 'example.com', 'R2') testnc('abcde', 'abcde.example.com', 'R2') testnc('example.com.:123', 'example.com:123', 'R2') testnc('Example.COM:xyZ', 'example.com:xyZ', 'R2') testnc('example.com.::123', 'example.com.::123', '') if offline: skip_rest('sn2princ tests', 'offline mode requested') # For the online tests, we rely on ptr-mismatch.kerberos.org forward # and reverse resolving to these names. oname = 'ptr-mismatch.kerberos.org' fname = 'www.kerberos.org' # Test fallback canonicalization krb5_sname_to_principal() results. mark('dns_canonicalize_host=fallback') testfc(oname, oname, '') # Verify forward resolution before testing for it. try: ai = socket.getaddrinfo(oname, None, 0, 0, 0, socket.AI_CANONNAME) except socket.gaierror: skip_rest('sn2princ tests', 'cannot forward resolve %s' % oname) (family, socktype, proto, canonname, sockaddr) = ai[0] if canonname.lower() != fname: skip_rest('sn2princ tests', '%s forward resolves to %s, not %s' % (oname, canonname, fname)) # Test fallback canonicalization in krb5_get_credentials(). oprinc = 'host/' + oname fprinc = 'host/' + fname shutil.copy(realm.ccache, realm.ccache + '.save') # Test that we only try fprinc once if we enter it as input. out, trace = realm.run(['./gcred', 'srv-hst', fprinc + '@'], env=fallback_canon, expected_code=1, return_trace=True) msg = 'Requesting tickets for %s@R1, referrals on' % fprinc if trace.count(msg) != 1: fail('Expected one try for %s' % fprinc) # Create fprinc, and verify that we get it as the canonicalized # fallback for oprinc. realm.addprinc(fprinc) msgs = ('Getting credentials user@R1 -> %s@ using' % oprinc, 'Requesting tickets for %s@R1' % oprinc, 'Requesting tickets for %s@R1' % fprinc, 'Received creds for desired service %s@R1' % fprinc) realm.run(['./gcred', 'srv-hst', oprinc + '@'], env=fallback_canon, expected_msg=fprinc, expected_trace=msgs) realm.addprinc(oprinc) # oprinc now exists, but we still get the fprinc ticket from the cache. realm.run(['./gcred', 'srv-hst', oprinc + '@'], env=fallback_canon, expected_msg=fprinc) # Without the cached result, we should get oprinc in preference to fprinc. os.rename(realm.ccache + '.save', realm.ccache) realm.run(['./gcred', 'srv-hst', oprinc], env=fallback_canon, expected_msg=oprinc) # Test fallback canonicalization for krb5_rd_req(). realm.run([kadminl, 'ktadd', fprinc]) msgs = ('Decrypted AP-REQ with server principal %s@R1' % fprinc, 'AP-REQ ticket: user@R1 -> %s@R1' % fprinc) realm.run(['./rdreq', fprinc, oprinc + '@'], env=fallback_canon, expected_trace=msgs) # Test fallback canonicalization for getting initial creds with a keytab. msgs = ('Getting initial credentials for %s@' % oprinc, 'Found entries for %s@R1 in keytab' % fprinc, 'Retrieving %s@R1 from ' % fprinc) realm.run(['./icred', '-k', realm.keytab, '-S', 'host', oname], env=fallback_canon, expected_trace=msgs) # Test forward-only canonicalization (rdns=false). mark('rdns=false') testnr(oname, fname, 'R1') testnr(oname + ':123', fname + ':123', 'R1') testnr(oname + ':xyZ', fname + ':xyZ', 'R1') # Verify reverse resolution before testing for it. try: names = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD) except socket.gaierror: skip_rest('reverse sn2princ tests', 'cannot reverse resolve %s' % oname) rname = names[0].lower() if rname == fname: skip_rest('reverse sn2princ tests', '%s reverse resolves to %s ' 'which should be different from %s' % (oname, rname, fname)) # Test default canonicalization (forward and reverse lookup). mark('default') test(oname, rname, 'R3') test(oname + ':123', rname + ':123', 'R3') test(oname + ':xyZ', rname + ':xyZ', 'R3') success('krb5_sname_to_principal tests') krb5-1.22.1/src/tests/t_spake.py0000664000175000017500000001455515051422640016304 0ustar ghudsonghudsonfrom k5test import * # The name and number of each supported SPAKE group. builtin_groups = ((1, 'edwards25519'),) openssl_groups = ((2, 'P-256'), (3, 'P-384'), (4, 'P-521')) if runenv.have_spake_openssl == 'yes': groups = builtin_groups + openssl_groups else: groups = builtin_groups for gnum, gname in groups: mark('group %s' % gname) conf = {'libdefaults': {'spake_preauth_groups': gname}} for realm in multipass_realms(create_user=False, create_host=False, krb5_conf=conf): realm.run([kadminl, 'addprinc', '+preauth', '-pw', 'pw', 'user']) # Test a basic SPAKE preauth scenario with no optimizations. msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Selected etype info:', 'Sending SPAKE support message', 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', '/More preauthentication data is required', 'Continuing preauth mech PA-SPAKE (151)', 'SPAKE challenge received with group ' + str(gnum), 'Sending SPAKE response', 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 'AS key determined by preauth:', 'Decrypted AS reply') realm.kinit('user', 'pw', expected_trace=msgs) # Test an unsuccessful authentication. msgs = ('/Additional pre-authentication required', 'Selected etype info:', 'Sending SPAKE support message', 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', '/More preauthentication data is required', 'Continuing preauth mech PA-SPAKE (151)', 'SPAKE challenge received with group ' + str(gnum), 'Sending SPAKE response', '/Preauthentication failed') realm.kinit('user', 'wrongpw', expected_code=1, expected_trace=msgs) conf = {'libdefaults': {'spake_preauth_groups': 'edwards25519'}} kdcconf = {'realms': {'$realm': {'spake_preauth_indicator': 'indspake'}}} realm = K5Realm(create_user=False, krb5_conf=conf, kdc_conf=kdcconf) realm.run([kadminl, 'addprinc', '+preauth', '-pw', 'pw', 'user']) # Test with FAST. mark('FAST') msgs = ('Using FAST due to armor ccache negotiation', 'FAST armor key:', 'Sending unauthenticated request', '/Additional pre-authentication required', 'Decoding FAST response', 'Selected etype info:', 'Sending SPAKE support message', 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', '/More preauthentication data is required', 'Continuing preauth mech PA-SPAKE (151)', 'SPAKE challenge received with group 1', 'Sending SPAKE response', 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 'AS key determined by preauth:', 'FAST reply key:') realm.kinit(realm.host_princ, flags=['-k']) realm.kinit('user', 'pw', flags=['-T', realm.ccache], expected_trace=msgs) # Test optimistic client preauth (151 is PA-SPAKE). mark('client optimistic') msgs = ('Attempting optimistic preauth', 'Processing preauth types: PA-SPAKE (151)', 'Sending SPAKE support message', 'for next request: PA-SPAKE (151)', '/More preauthentication data is required', 'Selected etype info:', 'SPAKE challenge received with group 1', 'Sending SPAKE response', 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 'AS key determined by preauth:', 'Decrypted AS reply') realm.run(['./icred', '-o', '151', 'user', 'pw'], expected_trace=msgs) # Test KDC optimistic challenge (accepted by client). mark('KDC optimistic') oconf = {'kdcdefaults': {'spake_preauth_kdc_challenge': 'edwards25519'}} oenv = realm.special_env('ochal', True, krb5_conf=oconf) realm.stop_kdc() realm.start_kdc(env=oenv) msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Selected etype info:', 'SPAKE challenge received with group 1', 'Sending SPAKE response', 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 'AS key determined by preauth:', 'Decrypted AS reply') realm.kinit('user', 'pw', expected_trace=msgs) if runenv.have_spake_openssl != 'yes': skip_rest('SPAKE fallback tests', 'SPAKE not built using OpenSSL') # Test optimistic client preauth falling back to encrypted timestamp # because the KDC doesn't support any of the client groups. mark('client optimistic (fallback)') p256conf={'libdefaults': {'spake_preauth_groups': 'P-256'}} p256env = realm.special_env('p256', False, krb5_conf=p256conf) msgs = ('Attempting optimistic preauth', 'Processing preauth types: PA-SPAKE (151)', 'Sending SPAKE support message', 'for next request: PA-SPAKE (151)', '/Preauthentication failed', 'Selected etype info:', 'Encrypted timestamp ', 'for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 'AS key determined by preauth:', 'Decrypted AS reply') realm.run(['./icred', '-o', '151', 'user', 'pw'], env=p256env, expected_trace=msgs) # Test KDC optimistic challenge (rejected by client). mark('KDC optimistic (rejected)') rconf = {'libdefaults': {'spake_preauth_groups': 'P-384,edwards25519'}, 'kdcdefaults': {'spake_preauth_kdc_challenge': 'P-384'}} renv = realm.special_env('ochal', True, krb5_conf=rconf) realm.stop_kdc() realm.start_kdc(env=renv) msgs = ('Sending unauthenticated request', '/Additional pre-authentication required', 'Selected etype info:', 'SPAKE challenge with group 3 rejected', 'Sending SPAKE support message', 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', '/More preauthentication data is required', 'Continuing preauth mech PA-SPAKE (151)', 'SPAKE challenge received with group 1', 'Sending SPAKE response', 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 'AS key determined by preauth:', 'Decrypted AS reply') realm.kinit('user', 'pw', expected_trace=msgs) # Check that the auth indicator for SPAKE is properly included by the KDC. mark('auth indicator') realm.run([kvno, realm.host_princ]) realm.run(['./adata', realm.host_princ], expected_msg='+97: [indspake]') success('SPAKE pre-authentication tests') krb5-1.22.1/src/tests/verify/0000775000175000017500000000000015051422640015576 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/verify/Makefile.in0000664000175000017500000000052515051422640017645 0ustar ghudsonghudsonmydir=tests$(S)verify BUILDTOP=$(REL)..$(S).. KDB5_DEP_LIB=$(THREAD_LINKOPTS) $(DL_LIB) SRCS=$(srcdir)/kdb5_verify.c all: kdb5_verify kdb5_verify: kdb5_verify.o $(KDB5_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o kdb5_verify kdb5_verify.o $(KDB5_LIBS) $(KDB5_DEP_LIB) $(KRB5_BASE_LIBS) install: clean: $(RM) kdb5_verify.o kdb5_verify krb5-1.22.1/src/tests/verify/kdb5_verify.c0000664000175000017500000003420115051422640020153 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/verify/kdb5_verify.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "kdb.h" #include "com_err.h" #include #include #define REALM_SEP '@' #define REALM_SEP_STR "@" struct mblock { krb5_deltat max_life; krb5_deltat max_rlife; krb5_timestamp expiration; krb5_flags flags; krb5_kvno mkvno; } mblock = { /* XXX */ KRB5_KDB_MAX_LIFE, KRB5_KDB_MAX_RLIFE, KRB5_KDB_EXPIRATION, KRB5_KDB_DEF_FLAGS, 0 }; int set_dbname_help (krb5_context, char *, char *); static void usage(char *who, int status) { fprintf(stderr, "usage: %s -p prefix -n num_to_check [-d dbpathname] [-r realmname]\n", who); fprintf(stderr, "\t [-D depth] [-k enctype] [-M mkeyname]\n"); exit(status); } krb5_keyblock master_keyblock; krb5_principal master_princ; krb5_encrypt_block master_encblock; krb5_pointer master_random; char *str_master_princ; static char *progname; static char *cur_realm = 0; static char *mkey_name = 0; static char *mkey_password = 0; static krb5_boolean manual_mkey = FALSE; int check_princ (krb5_context, char *); int main(int argc, char *argv[]) { extern char *optarg; int optchar, i, n; char tmp[4096], tmp2[BUFSIZ], *str_princ; krb5_context context; krb5_error_code retval; char *dbname = 0; int enctypedone = 0; int num_to_check; char principal_string[BUFSIZ]; char *suffix = 0; size_t suffix_size = 0; int depth, errors; krb5_init_context(&context); if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; progname = argv[0]; memset(principal_string, 0, sizeof(principal_string)); num_to_check = 0; depth = 1; while ((optchar = getopt(argc, argv, "D:P:p:n:d:r:R:k:M:e:m")) != -1) { switch(optchar) { case 'D': depth = atoi(optarg); /* how deep to go */ break; case 'P': /* Only used for testing!!! */ mkey_password = optarg; break; case 'p': /* prefix name to check */ strncpy(principal_string, optarg, sizeof(principal_string) - 1); principal_string[sizeof(principal_string) - 1] = '\0'; suffix = principal_string + strlen(principal_string); suffix_size = sizeof(principal_string) - (suffix - principal_string); break; case 'n': /* how many to check */ num_to_check = atoi(optarg); break; case 'd': /* set db name */ dbname = optarg; break; case 'r': cur_realm = optarg; break; case 'k': master_keyblock.enctype = atoi(optarg); enctypedone++; break; case 'M': /* master key name in DB */ mkey_name = optarg; break; case 'm': manual_mkey = TRUE; break; case '?': default: usage(progname, 1); /*NOTREACHED*/ } } if (!(num_to_check && suffix)) usage(progname, 1); if (!enctypedone) master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; if (!krb5_c_valid_enctype(master_keyblock.enctype)) { com_err(progname, KRB5_PROG_ETYPE_NOSUPP, "while setting up enctype %d", master_keyblock.enctype); exit(1); } krb5_use_enctype(context, &master_encblock, master_keyblock.enctype); if (!dbname) dbname = DEFAULT_KDB_FILE; /* XXX? */ if (!cur_realm) { if ((retval = krb5_get_default_realm(context, &cur_realm))) { com_err(progname, retval, "while retrieving default realm name"); exit(1); } } if ((retval = set_dbname_help(context, progname, dbname))) exit(retval); errors = 0; fprintf(stdout, "\nChecking "); for (n = 1; n <= num_to_check; n++) { /* build the new principal name */ /* we can't pick random names because we need to generate all the names again given a prefix and count to test the db lib and kdb */ (void) snprintf(suffix, suffix_size, "%d", n); (void) snprintf(tmp, sizeof(tmp), "%s-DEPTH-1", principal_string); str_princ = tmp; if (check_princ(context, str_princ)) errors++; for (i = 2; i <= depth; i++) { (void) snprintf(tmp2, sizeof(tmp2), "/%s-DEPTH-%d", principal_string, i); tmp2[sizeof(tmp2) - 1] = '\0'; strncat(tmp, tmp2, sizeof(tmp) - 1 - strlen(tmp)); str_princ = tmp; if (check_princ(context, str_princ)) errors++; } } if (errors) fprintf(stdout, "\n%d errors/principals failed.\n", errors); else fprintf(stdout, "\nNo errors.\n"); krb5_finish_random_key(context, &master_encblock, &master_random); krb5_finish_key(context, &master_encblock); retval = krb5_db_fini(context); memset(master_keyblock.contents, 0, (size_t) master_keyblock.length); if (retval && retval != KRB5_KDB_DBNOTINITED) { com_err(progname, retval, "while closing database"); exit(1); } krb5_free_keyblock_contents(context, &master_keyblock); if (str_master_princ) { krb5_free_unparsed_name(context, str_master_princ); } krb5_free_principal(context, master_princ); krb5_free_context(context); exit(0); } int check_princ(krb5_context context, char *str_princ) { krb5_error_code retval; krb5_db_entry *kdbe = NULL; krb5_keyblock pwd_key, db_key; krb5_data pwd, salt; krb5_principal princ; /* char *str_mod_name; */ char princ_name[4096]; snprintf(princ_name, sizeof(princ_name), "%s@%s", str_princ, cur_realm); if ((retval = krb5_parse_name(context, princ_name, &princ))) { com_err(progname, retval, "while parsing '%s'", princ_name); goto out; } pwd.data = princ_name; /* must be able to regenerate */ pwd.length = strlen(princ_name); if ((retval = krb5_principal2salt(context, princ, &salt))) { com_err(progname, retval, "while converting principal to salt for '%s'", princ_name); krb5_free_principal(context, princ); goto out; } if ((retval = krb5_string_to_key(context, &master_encblock, &pwd_key, &pwd, &salt))) { com_err(progname, retval, "while converting password to key for '%s'", princ_name); krb5_free_data_contents(context, &salt); krb5_free_principal(context, princ); goto out; } krb5_free_data_contents(context, &salt); if ((retval = krb5_db_get_principal(context, princ, 0, &kdbe))) { com_err(progname, retval, "while attempting to verify principal's existence"); krb5_free_principal(context, princ); goto out; } krb5_free_principal(context, princ); if ((retval = krb5_dbe_decrypt_key_data(context, NULL, kdbe->key_data, &db_key, NULL))) { com_err(progname, retval, "while decrypting key for '%s'", princ_name); goto errout; } if ((pwd_key.enctype != db_key.enctype) || (pwd_key.length != db_key.length)) { fprintf (stderr, "\tKey types do not agree (%d expected, %d from db)\n", pwd_key.enctype, db_key.enctype); errout: krb5_db_free_principal(context, kdbe); return(-1); } else { if (memcmp((char *)pwd_key.contents, (char *) db_key.contents, (size_t) pwd_key.length)) { fprintf(stderr, "\t key did not match stored value for %s\n", princ_name); goto errout; } } free(pwd_key.contents); free(db_key.contents); if (kdbe->key_data[0].key_data_kvno != 1) { fprintf(stderr,"\tkvno did not match stored value for %s.\n", princ_name); goto errout; } if (kdbe->max_life != mblock.max_life) { fprintf(stderr, "\tmax life did not match stored value for %s.\n", princ_name); goto errout; } if (kdbe->max_renewable_life != mblock.max_rlife) { fprintf(stderr, "\tmax renewable life did not match stored value for %s.\n", princ_name); goto errout; } if (kdbe->expiration != mblock.expiration) { fprintf(stderr, "\texpiration time did not match stored value for %s.\n", princ_name); goto errout; } /* if ((retval = krb5_unparse_name(context, kdbe.mod_name, &str_mod_name))) com_err(progname, retval, "while unparsing mode name"); else { if (strcmp(str_mod_name, str_master_princ) != 0) { fprintf(stderr, "\tmod name isn't the master princ (%s not %s).\n", str_mod_name, str_master_princ); free(str_mod_name); goto errout; } else free(str_mod_name); } */ if (kdbe->attributes != mblock.flags) { fprintf(stderr, "\tAttributes did not match stored value for %s.\n", princ_name); goto errout; } out: krb5_db_free_principal(context, kdbe); return(0); } int set_dbname_help(krb5_context context, char *pname, char *dbname) { krb5_error_code retval; krb5_data pwd, scratch; char *args[2]; krb5_db_entry *master_entry; /* assemble & parse the master key name */ if ((retval = krb5_db_setup_mkey_name(context, mkey_name, cur_realm, 0, &master_princ))) { com_err(pname, retval, "while setting up master key name"); return(1); } if (mkey_password) { pwd.data = mkey_password; pwd.length = strlen(mkey_password); retval = krb5_principal2salt(context, master_princ, &scratch); if (retval) { com_err(pname, retval, "while calculated master key salt"); return(1); } if ((retval = krb5_string_to_key(context, &master_encblock, &master_keyblock, &pwd, &scratch))) { com_err(pname, retval, "while transforming master key from password"); return(1); } free(scratch.data); } else { if ((retval = krb5_db_fetch_mkey(context, master_princ, master_keyblock.enctype, manual_mkey, FALSE, (char *) NULL, NULL, NULL, &master_keyblock))) { com_err(pname, retval, "while reading master key"); return(1); } } /* Ick! Current DAL interface requires that the default_realm field be set in the krb5_context. */ if ((retval = krb5_set_default_realm(context, cur_realm))) { com_err(pname, retval, "setting default realm"); return 1; } /* Pathname is passed to db2 via 'args' parameter. */ args[1] = NULL; if (asprintf(&args[0], "dbname=%s", dbname) < 0) { com_err(pname, errno, "while setting up db parameters"); return 1; } if ((retval = krb5_db_open(context, args, KRB5_KDB_OPEN_RO))) { com_err(pname, retval, "while initializing database"); return(1); } if ((retval = krb5_db_fetch_mkey_list(context, master_princ, &master_keyblock))) { com_err(pname, retval, "while verifying master key"); (void) krb5_db_fini(context); return(1); } if ((retval = krb5_db_get_principal(context, master_princ, 0, &master_entry))) { com_err(pname, retval, "while retrieving master entry"); (void) krb5_db_fini(context); return(1); } if ((retval = krb5_unparse_name(context, master_princ, &str_master_princ))) { com_err(pname, retval, "while unparsing master principal"); krb5_db_fini(context); return(1); } if ((retval = krb5_process_key(context, &master_encblock, &master_keyblock))) { com_err(pname, retval, "while processing master key"); (void) krb5_db_fini(context); return(1); } if ((retval = krb5_init_random_key(context, &master_encblock, &master_keyblock, &master_random))) { com_err(pname, retval, "while initializing random key generator"); krb5_finish_key(context, &master_encblock); (void) krb5_db_fini(context); return(1); } mblock.max_life = master_entry->max_life; mblock.max_rlife = master_entry->max_renewable_life; mblock.expiration = master_entry->expiration; /* don't set flags, master has some extra restrictions */ mblock.mkvno = master_entry->key_data[0].key_data_kvno; krb5_db_free_principal(context, master_entry); free(args[0]); return 0; } krb5-1.22.1/src/tests/verify/deps0000664000175000017500000000143715051422640016461 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)kdb5_verify.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SS_DEPS) \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kdb5_verify.c krb5-1.22.1/src/tests/verify/pkey.c0000664000175000017500000000072415051422640016715 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/verify/pkey.c */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * For copying and distribution information, please see the file * . * */ #include void pkey(k) unsigned char *k; { int i; unsigned int foo; for (i = 0 ; i < 8 ; i++) { foo = *k++; fprintf(stderr, "%x ", foo); } } krb5-1.22.1/src/tests/gssapi/0000775000175000017500000000000015051422640015560 5ustar ghudsonghudsonkrb5-1.22.1/src/tests/gssapi/t_accname.c0000664000175000017500000000743615051422640017650 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include "common.h" /* * Test program for acceptor names, intended to be run from a Python test * script. Establishes contexts with the default initiator name, a specified * principal name as target name, and a specified host-based name as acceptor * name (or GSS_C_NO_NAME if no acceptor name is given). If the exchange is * successful, queries the context for the acceptor name and prints it. If any * call is unsuccessful, displays an error message. Exits with status 0 if all * operations are successful, or 1 if not. * * Usage: ./t_accname targetname [acceptorname] */ int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_cred_id_t acceptor_cred; gss_name_t target_name, acceptor_name = GSS_C_NO_NAME, real_acceptor_name; gss_buffer_desc namebuf; gss_ctx_id_t initiator_context, acceptor_context; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s targetname [acceptorname]\n", argv[0]); return 1; } /* Import target and acceptor names. */ target_name = import_name(argv[1]); if (argc >= 3) acceptor_name = import_name(argv[2]); /* Get acceptor cred. */ major = gss_acquire_cred(&minor, acceptor_name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_ACCEPT, &acceptor_cred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, acceptor_cred, target_name, flags, &initiator_context, &acceptor_context, NULL, NULL, NULL); major = gss_inquire_context(&minor, acceptor_context, NULL, &real_acceptor_name, NULL, NULL, NULL, NULL, NULL); check_gsserr("gss_inquire_context", major, minor); namebuf.value = NULL; namebuf.length = 0; major = gss_display_name(&minor, real_acceptor_name, &namebuf, NULL); check_gsserr("gss_display_name", major, minor); printf("%.*s\n", (int)namebuf.length, (char *)namebuf.value); (void)gss_release_name(&minor, &target_name); (void)gss_release_name(&minor, &acceptor_name); (void)gss_release_name(&minor, &real_acceptor_name); (void)gss_release_cred(&minor, &acceptor_cred); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); (void)gss_release_buffer(&minor, &namebuf); return 0; } krb5-1.22.1/src/tests/gssapi/t_gssexts.c0000664000175000017500000002203715051422640017753 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" /* * Test program for protocol transition (S4U2Self) and constrained delegation * (S4U2Proxy) * * Note: because of name canonicalization, the following tips may help * when configuring with Active Directory: * * - Create a computer account FOO$ * - Set the UPN to host/foo.domain (no suffix); this is necessary to * be able to send an AS-REQ as this principal, otherwise you would * need to use the canonical name (FOO$), which will cause principal * comparison errors in gss_accept_sec_context(). * - Add a SPN of host/foo.domain * - Configure the computer account to support constrained delegation with * protocol transition (Trust this computer for delegation to specified * services only / Use any authentication protocol) * - Add host/foo.domain to the keytab (possibly easiest to do this * with ktadd) * * For S4U2Proxy to work the TGT must be forwardable too. * * Usage eg: * * kinit -k -t test.keytab -f 'host/test.win.mit.edu@WIN.MIT.EDU' * ./t_s4u p:delegtest@WIN.MIT.EDU p:HOST/WIN-EQ7E4AA2WR8.win.mit.edu@WIN.MIT.EDU test.keytab */ static int use_spnego = 0; static void test_prf(gss_ctx_id_t initiatorContext, gss_ctx_id_t acceptorContext, int flags) { gss_buffer_desc constant; OM_uint32 major, minor; unsigned int i; gss_buffer_desc initiatorPrf; gss_buffer_desc acceptorPrf; constant.value = "gss prf test"; constant.length = strlen((char *)constant.value); initiatorPrf.value = NULL; acceptorPrf.value = NULL; major = gss_pseudo_random(&minor, initiatorContext, flags, &constant, 19, &initiatorPrf); check_gsserr("gss_pseudo_random", major, minor); printf("%s\n", flags == GSS_C_PRF_KEY_FULL ? "PRF_KEY_FULL" : "PRF_KEY_PARTIAL"); printf("Initiator PRF: "); for (i = 0; i < initiatorPrf.length; i++) printf("%02x ", ((char *)initiatorPrf.value)[i] & 0xFF); printf("\n"); major = gss_pseudo_random(&minor, acceptorContext, flags, &constant, 19, &acceptorPrf); check_gsserr("gss_pseudo_random", major, minor); printf("Acceptor PRF: "); for (i = 0; i < acceptorPrf.length; i++) printf("%02x ", ((char *)acceptorPrf.value)[i] & 0xFF); printf("\n"); if (acceptorPrf.length != initiatorPrf.length || memcmp(acceptorPrf.value, initiatorPrf.value, initiatorPrf.length)) { fprintf(stderr, "Initiator and acceptor PRF output does not match\n"); exit(1); } (void)gss_release_buffer(&minor, &initiatorPrf); (void)gss_release_buffer(&minor, &acceptorPrf); } static void init_accept_sec_context(gss_cred_id_t claimant_cred_handle, gss_cred_id_t verifier_cred_handle, gss_cred_id_t *deleg_cred_handle) { OM_uint32 major, minor, flags; gss_name_t source_name = GSS_C_NO_NAME, target_name = GSS_C_NO_NAME; gss_ctx_id_t initiator_context, acceptor_context; gss_OID mech; *deleg_cred_handle = GSS_C_NO_CREDENTIAL; major = gss_inquire_cred(&minor, verifier_cred_handle, &target_name, NULL, NULL, NULL); check_gsserr("gss_inquire_cred", major, minor); display_canon_name("Target name", target_name, &mech_krb5); mech = use_spnego ? &mech_spnego : &mech_krb5; display_oid("Target mech", mech); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(mech, claimant_cred_handle, verifier_cred_handle, target_name, flags, &initiator_context, &acceptor_context, &source_name, NULL, deleg_cred_handle); test_prf(initiator_context, acceptor_context, GSS_C_PRF_KEY_FULL); test_prf(initiator_context, acceptor_context, GSS_C_PRF_KEY_PARTIAL); (void)gss_release_name(&minor, &source_name); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); } static void get_default_cred(const char *keytab_name, gss_OID_set mechs, gss_cred_id_t *impersonator_cred_handle) { OM_uint32 major = GSS_S_FAILURE, minor; krb5_error_code ret; krb5_context context = NULL; krb5_keytab keytab = NULL; krb5_principal keytab_principal = NULL; krb5_ccache ccache = NULL; if (keytab_name != NULL) { ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); ret = krb5_kt_resolve(context, keytab_name, &keytab); check_k5err(context, "krb5_kt_resolve", ret); ret = krb5_cc_default(context, &ccache); check_k5err(context, "krb5_cc_default", ret); ret = krb5_cc_get_principal(context, ccache, &keytab_principal); check_k5err(context, "krb5_cc_get_principal", ret); major = gss_krb5_import_cred(&minor, ccache, keytab_principal, keytab, impersonator_cred_handle); check_gsserr("gss_krb5_import_cred", major, minor); krb5_free_principal(context, keytab_principal); krb5_cc_close(context, ccache); krb5_kt_close(context, keytab); krb5_free_context(context); } else { major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, impersonator_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); } } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t impersonator_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t user_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL; gss_name_t user = GSS_C_NO_NAME, target = GSS_C_NO_NAME; gss_OID_set mechs, actual_mechs = GSS_C_NO_OID_SET; uid_t uid; if (argc < 2 || argc > 5) { fprintf(stderr, "Usage: %s [--spnego] [user] " "[proxy-target] [keytab]\n", argv[0]); fprintf(stderr, " proxy-target and keytab are optional\n"); exit(1); } if (strcmp(argv[1], "--spnego") == 0) { use_spnego++; argc--; argv++; } user = import_name(argv[1]); major = gss_pname_to_uid(&minor, user, NULL, &uid); check_gsserr("gss_pname_to_uid(user)", major, minor); if (argc > 2 && strcmp(argv[2], "-") != 0) target = import_name(argv[2]); mechs = use_spnego ? &mechset_spnego : &mechset_krb5; get_default_cred((argc > 3) ? argv[3] : NULL, mechs, &impersonator_cred_handle); printf("Protocol transition tests follow\n"); printf("-----------------------------------\n\n"); /* get S4U2Self cred */ major = gss_acquire_cred_impersonate_name(&minor, impersonator_cred_handle, user, GSS_C_INDEFINITE, mechs, GSS_C_INITIATE, &user_cred_handle, &actual_mechs, NULL); check_gsserr("gss_acquire_cred_impersonate_name", major, minor); /* Try to store it in default ccache */ major = gss_store_cred(&minor, user_cred_handle, GSS_C_INITIATE, &mechs->elements[0], 1, 1, NULL, NULL); check_gsserr("gss_store_cred", major, minor); init_accept_sec_context(user_cred_handle, impersonator_cred_handle, &delegated_cred_handle); printf("\n"); (void)gss_release_name(&minor, &user); (void)gss_release_name(&minor, &target); (void)gss_release_cred(&minor, &delegated_cred_handle); (void)gss_release_cred(&minor, &impersonator_cred_handle); (void)gss_release_cred(&minor, &user_cred_handle); (void)gss_release_oid_set(&minor, &actual_mechs); return 0; } krb5-1.22.1/src/tests/gssapi/t_enctypes.py0000775000175000017500000001444015051422640020315 0ustar ghudsonghudsonfrom k5test import * # Define some convenience abbreviations for enctypes we will see in # test program output. For background, aes256 and aes128 are "CFX # enctypes", meaning that they imply support for RFC 4121, while des3 # and rc4 are not. DES3 keys will appear as 'des3-cbc-raw' in # t_enctypes output because that's how GSSAPI does raw triple-DES # encryption without the RFC3961 framing. aes256 = 'aes256-cts-hmac-sha1-96' aes128 = 'aes128-cts-hmac-sha1-96' des3 = 'des3-cbc-sha1' d_des3 = 'DEPRECATED:des3-cbc-sha1' des3raw = 'des3-cbc-raw' d_des3raw = 'DEPRECATED:des3-cbc-raw' rc4 = 'arcfour-hmac' d_rc4 = 'DEPRECATED:arcfour-hmac' # These tests make assumptions about the default enctype lists, so set # them explicitly rather than relying on the library defaults. supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal' conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4', 'allow_des3': 'true', 'allow_rc4': 'true'}, 'realms': {'$realm': {'supported_enctypes': supp}}} realm = K5Realm(krb5_conf=conf) shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save')) # Return an argument list for running t_enctypes with optional initiator # and acceptor enctype lists. def cmdline(ienc, aenc): iflags = ienc and ['-i', ienc] or [] aflags = aenc and ['-a', aenc] or [] return ['./t_enctypes'] + iflags + aflags + ['p:' + realm.host_princ] # Run t_enctypes with optional initiator and acceptor enctype lists, # and check that it succeeds with the expected output. Also check # that the ticket we got has the expected encryption key and session # key. def test(msg, ienc, aenc, tktenc='', tktsession='', proto='', isubkey='', asubkey=None): shutil.copyfile(os.path.join(realm.testdir, 'save'), realm.ccache) # Run the test program and check its output. out = realm.run(cmdline(ienc, aenc)).split() if out[0] != proto or out[1] != isubkey: fail(msg) if asubkey is not None and (len(out) < 3 or out[2] != asubkey): fail(msg) lines = realm.run([klist, '-e']).splitlines() for ind, line in enumerate(lines): if realm.host_princ in line: if lines[ind + 1].strip() != ('Etype (skey, tkt): %s, %s' % (tktsession, tktenc)): fail(msg) break # Run t_enctypes with optional initiator and acceptor enctype lists, # and check that it fails with the expected error message. def test_err(msg, ienc, aenc, expected_err): shutil.copyfile(os.path.join(realm.testdir, 'save'), realm.ccache) realm.run(cmdline(ienc, aenc), expected_code=1, expected_msg=expected_err) # By default, all of the key enctypes should be aes256. test('noargs', None, None, tktenc=aes256, tktsession=aes256, proto='cfx', isubkey=aes256, asubkey=aes256) # When the initiator constrains the permitted session enctypes to # aes128, the ticket encryption key should remain aes256. The client # initiator will not send an RFC 4537 upgrade list because it sees no # other permitted enctypes, so the acceptor subkey will not be # upgraded from aes128. test('init aes128', 'aes128-cts', None, tktenc=aes256, tktsession=aes128, proto='cfx', isubkey=aes128, asubkey=aes128) # If the initiator and acceptor both constrain the permitted session # enctypes to aes128, we should see the same keys as above. This # tests that the acceptor does not mistakenly contrain the ticket # encryption key. test('both aes128', 'aes128-cts', 'aes128-cts', tktenc=aes256, tktsession=aes128, proto='cfx', isubkey=aes128, asubkey=aes128) # If only the acceptor constrains the permitted session enctypes to # aes128, subkey negotiation fails because the acceptor considers the # aes256 session key to be non-permitted. test_err('acc aes128', None, 'aes128-cts', 'Encryption type aes256-cts-hmac-sha1-96 not permitted') # If the initiator constrains the permitted session enctypes to des3, # no acceptor subkey will be generated because we can't upgrade to a # CFX enctype. test('init des3', 'des3', None, tktenc=aes256, tktsession=d_des3, proto='rfc1964', isubkey=des3raw, asubkey=None) # Force the ticket session key to be rc4, so we can test some subkey # upgrade cases. The ticket encryption key remains aes256. realm.run([kadminl, 'setstr', realm.host_princ, 'session_enctypes', 'rc4']) # With no arguments, the initiator should send an upgrade list of # [aes256 aes128 des3] and the acceptor should upgrade to an aes256 # subkey. test('upgrade noargs', None, None, tktenc=aes256, tktsession=d_rc4, proto='cfx', isubkey=rc4, asubkey=aes256) # If the initiator won't permit rc4 as a session key, it won't be able # to get a ticket. test_err('upgrade init aes', 'aes', None, 'no support for encryption type') # If the initiator permits rc4 but prefers aes128, it will send an # upgrade list of [aes128] and the acceptor will upgrade to aes128. test('upgrade init aes128+rc4', 'aes128-cts rc4', None, tktenc=aes256, tktsession=d_rc4, proto='cfx', isubkey=rc4, asubkey=aes128) # If the initiator permits rc4 but prefers des3, it will send an # upgrade list of [des3], but the acceptor won't generate a subkey # because des3 isn't a CFX enctype. test('upgrade init des3+rc4', 'des3 rc4', None, tktenc=aes256, tktsession=d_rc4, proto='rfc1964', isubkey=rc4, asubkey=None) # If the acceptor permits only aes128, subkey negotiation will fail # because the ticket session key and initiator subkey are # non-permitted. (This is unfortunate if the acceptor's restriction # is only for the sake of the kernel, since we could upgrade to an # aes128 subkey, but it's the current semantics.) test_err('upgrade acc aes128', None, 'aes128-cts', 'Encryption type arcfour-hmac not permitted') # If the acceptor permits rc4 but prefers aes128, it will negotiate an # upgrade to aes128. test('upgrade acc aes128 rc4', None, 'aes128-cts rc4', tktenc=aes256, tktsession=d_rc4, proto='cfx', isubkey=rc4, asubkey=aes128) # In this test, the initiator and acceptor each prefer an AES enctype # to rc4, but they can't agree on which one, so no subkey is # generated. test('upgrade mismatch', 'aes128-cts rc4', 'aes256-cts rc4', tktenc=aes256, tktsession=d_rc4, proto='rfc1964', isubkey=rc4, asubkey=None) success('gss_krb5_set_allowable_enctypes tests') krb5-1.22.1/src/tests/gssapi/t_enctypes.c0000664000175000017500000001745315051422640020113 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_enctypes.c - gss_krb5_set_allowable_enctypes test */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "common.h" #include "gssapi_ext.h" /* * This test program establishes contexts with the krb5 mech, the default * initiator name, a specified target name, and the default acceptor name. * Before the exchange, gss_set_allowable_enctypes is called for the initiator * and the acceptor cred if requested. If the exchange is successful, the * resulting contexts are exported with gss_krb5_export_lucid_sec_context, * checked for mismatches, and the GSS protocol and keys are displayed. Exits * with status 0 if all operations are successful, or 1 if not. * * Usage: ./t_enctypes [-i initenctypes] [-a accenctypes] targetname */ static void usage(void) { errout("Usage: t_enctypes [-i initenctypes] [-a accenctypes] " "targetname"); } /* Error out if ikey is not the same as akey. */ static void check_key_match(gss_krb5_lucid_key_t *ikey, gss_krb5_lucid_key_t *akey) { if (ikey->type != akey->type || ikey->length != akey->length || memcmp(ikey->data, akey->data, ikey->length) != 0) errout("Initiator and acceptor keys do not match"); } /* Display the name of enctype. */ static void display_enctype(krb5_enctype enctype) { char ename[128]; if (krb5_enctype_to_name(enctype, FALSE, ename, sizeof(ename)) == 0) fputs(ename, stdout); else fputs("(unknown)", stdout); } int main(int argc, char *argv[]) { krb5_error_code ret; krb5_context kctx = NULL; krb5_enctype *ienc = NULL, *aenc = NULL, zero = 0; OM_uint32 minor, major, flags; gss_name_t tname; gss_cred_id_t icred = GSS_C_NO_CREDENTIAL, acred = GSS_C_NO_CREDENTIAL; gss_ctx_id_t ictx, actx; gss_krb5_lucid_context_v1_t *ilucid, *alucid; gss_krb5_rfc1964_keydata_t *i1964, *a1964; gss_krb5_cfx_keydata_t *icfx, *acfx; gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET; gss_OID ssf_oid = GSS_C_SEC_CONTEXT_SASL_SSF; unsigned int ssf; size_t count; void *lptr; int c; ret = krb5_init_context(&kctx); check_k5err(kctx, "krb5_init_context", ret); /* Parse arguments. */ while ((c = getopt(argc, argv, "i:a:")) != -1) { switch (c) { case 'i': ret = krb5int_parse_enctype_list(kctx, "", optarg, &zero, &ienc); check_k5err(kctx, "krb5_parse_enctype_list(initiator)", ret); break; case 'a': ret = krb5int_parse_enctype_list(kctx, "", optarg, &zero, &aenc); check_k5err(kctx, "krb5_parse_enctype_list(acceptor)", ret); break; default: usage(); } } argc -= optind; argv += optind; if (argc != 1) usage(); tname = import_name(*argv); if (ienc != NULL) { major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechset_krb5, GSS_C_INITIATE, &icred, NULL, NULL); check_gsserr("gss_acquire_cred(initiator)", major, minor); for (count = 0; ienc[count]; count++); major = gss_krb5_set_allowable_enctypes(&minor, icred, count, ienc); check_gsserr("gss_krb5_set_allowable_enctypes(init)", major, minor); } if (aenc != NULL) { major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechset_krb5, GSS_C_ACCEPT, &acred, NULL, NULL); check_gsserr("gss_acquire_cred(acceptor)", major, minor); for (count = 0; aenc[count]; count++); major = gss_krb5_set_allowable_enctypes(&minor, acred, count, aenc); check_gsserr("gss_krb5_set_allowable_enctypes(acc)", major, minor); } flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG; establish_contexts(&mech_krb5, icred, acred, tname, flags, &ictx, &actx, NULL, NULL, NULL); /* Query the SSF value and range-check the result. */ major = gss_inquire_sec_context_by_oid(&minor, ictx, ssf_oid, &bufset); check_gsserr("gss_inquire_sec_context_by_oid(ssf)", major, minor); if (bufset->elements[0].length != 4) errout("SSF buffer has unexpected length"); ssf = load_32_be(bufset->elements[0].value); if (ssf < 56 || ssf > 256) errout("SSF value not within acceptable range (56-256)"); (void)gss_release_buffer_set(&minor, &bufset); /* Export to lucid contexts. */ major = gss_krb5_export_lucid_sec_context(&minor, &ictx, 1, &lptr); check_gsserr("gss_export_lucid_sec_context(initiator)", major, minor); ilucid = lptr; major = gss_krb5_export_lucid_sec_context(&minor, &actx, 1, &lptr); check_gsserr("gss_export_lucid_sec_context(acceptor)", major, minor); alucid = lptr; /* Grab the session keys and make sure they match. */ if (ilucid->protocol != alucid->protocol) errout("Initiator/acceptor protocol mismatch"); if (ilucid->protocol) { icfx = &ilucid->cfx_kd; acfx = &alucid->cfx_kd; if (icfx->have_acceptor_subkey != acfx->have_acceptor_subkey) errout("Initiator/acceptor have_acceptor_subkey mismatch"); check_key_match(&icfx->ctx_key, &acfx->ctx_key); if (icfx->have_acceptor_subkey) check_key_match(&icfx->acceptor_subkey, &acfx->acceptor_subkey); fputs("cfx ", stdout); display_enctype(icfx->ctx_key.type); if (icfx->have_acceptor_subkey) { fputs(" ", stdout); display_enctype(icfx->acceptor_subkey.type); } fputs("\n", stdout); } else { i1964 = &ilucid->rfc1964_kd; a1964 = &alucid->rfc1964_kd; if (i1964->sign_alg != a1964->sign_alg || i1964->seal_alg != a1964->seal_alg) errout("Initiator/acceptor sign or seal alg mismatch"); check_key_match(&i1964->ctx_key, &a1964->ctx_key); fputs("rfc1964 ", stdout); display_enctype(i1964->ctx_key.type); fputs("\n", stdout); } krb5_free_context(kctx); free(ienc); free(aenc); (void)gss_release_name(&minor, &tname); (void)gss_release_cred(&minor, &icred); (void)gss_release_cred(&minor, &acred); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); (void)gss_krb5_free_lucid_sec_context(&minor, ilucid); (void)gss_krb5_free_lucid_sec_context(&minor, alucid); return 0; } krb5-1.22.1/src/tests/gssapi/Makefile.in0000664000175000017500000001442115051422640017627 0ustar ghudsonghudsonmydir=tests$(S)gssapi BUILDTOP=$(REL)..$(S).. DEFINES = -DUSE_AUTOCONF_H # For t_prf.c LOCALINCLUDES = -I$(srcdir)/../../lib/gssapi/mechglue \ -I$(srcdir)/../../lib/gssapi/krb5 \ -I$(srcdir)/../../lib/gssapi/generic -I../../lib/gssapi/krb5 \ -I../../lib/gssapi/generic SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \ $(srcdir)/reload.c $(srcdir)/t_accname.c $(srcdir)/t_add_cred.c \ $(srcdir)/t_bindings.c $(srcdir)/t_ccselect.c $(srcdir)/t_ciflags.c \ $(srcdir)/t_context.c $(srcdir)/t_credstore.c $(srcdir)/t_enctypes.c \ $(srcdir)/t_err.c $(srcdir)/t_export_cred.c $(srcdir)/t_export_name.c \ $(srcdir)/t_gssexts.c $(srcdir)/t_iakerb.c $(srcdir)/t_imp_cred.c \ $(srcdir)/t_imp_name.c $(srcdir)/t_invalid.c $(srcdir)/t_inq_cred.c \ $(srcdir)/t_inq_ctx.c $(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \ $(srcdir)/t_lifetime.c $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c \ $(srcdir)/t_pcontok.c $(srcdir)/t_prf.c $(srcdir)/t_s4u.c \ $(srcdir)/t_s4u2proxy_krb5.c $(srcdir)/t_saslname.c \ $(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c $(srcdir)/t_store_cred.c OBJS= ccinit.o ccrefresh.o common.o reload.o t_accname.o t_add_cred.o \ t_bindings.o t_ccselect.o t_ciflags.o t_context.o t_credstore.o \ t_enctypes.o t_err.o t_export_cred.o t_export_name.o t_gssexts.o \ t_iakerb.o t_imp_cred.o t_imp_name.o t_invalid.o t_inq_cred.o \ t_inq_ctx.o t_inq_mechs_name.o t_iov.o t_lifetime.o t_namingexts.o \ t_oid.o t_pcontok.o t_prf.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \ t_spnego.o t_srcattrs.o t_store_cred.o t_iakerb.o COMMON_DEPS= common.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS) all: ccinit ccrefresh reload t_accname t_add_cred t_bindings t_ccselect \ t_ciflags t_context t_credstore t_enctypes t_err t_export_cred \ t_export_name t_gssexts t_iakerb t_imp_cred t_imp_name t_invalid \ t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime t_namingexts \ t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname t_spnego \ t_srcattrs t_store_cred check-unix: t_invalid t_oid t_prf t_imp_name reload $(RUN_TEST) ./t_invalid $(RUN_TEST) ./t_oid $(RUN_TEST) ./t_prf $(RUN_TEST) ./t_imp_name if [ -r $(TOPLIBD)/libgssapi_krb5.so ]; then $(RUN_TEST) ./reload; fi check-pytests: ccinit ccrefresh t_accname t_add_cred t_bindings t_ccselect \ t_ciflags t_context t_credstore t_enctypes t_err t_export_cred \ t_export_name t_imp_cred t_inq_cred t_inq_ctx t_inq_mechs_name t_iov \ t_lifetime t_pcontok t_s4u t_s4u2proxy_krb5 t_spnego t_srcattrs \ t_store_cred $(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_store_cred.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_credstore.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_bindings.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_enctypes.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_export_cred.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_s4u.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_authind.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_negoex.py $(PYTESTFLAGS) ccinit: ccinit.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o ccinit ccinit.o $(KRB5_BASE_LIBS) ccrefresh: ccrefresh.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o ccrefresh ccrefresh.o $(KRB5_BASE_LIBS) reload: reload.o $(CC_LINK) -o $@ reload.o $(LIBS) $(DL_LIB) t_accname: t_accname.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_accname.o $(COMMON_LIBS) t_add_cred: t_add_cred.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_add_cred.o $(COMMON_LIBS) t_bindings: t_bindings.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_bindings.o $(COMMON_LIBS) t_ccselect: t_ccselect.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_ccselect.o $(COMMON_LIBS) t_ciflags: t_ciflags.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_ciflags.o $(COMMON_LIBS) t_context: t_context.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_context.o $(COMMON_LIBS) t_credstore: t_credstore.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_credstore.o $(COMMON_LIBS) t_enctypes: t_enctypes.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_enctypes.o $(COMMON_LIBS) t_err: t_err.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_err.o $(COMMON_LIBS) t_export_cred: t_export_cred.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_export_cred.o $(COMMON_LIBS) t_export_name: t_export_name.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_export_name.o $(COMMON_LIBS) t_gssexts: t_gssexts.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_gssexts.o $(COMMON_LIBS) t_iakerb: t_iakerb.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_iakerb.o $(COMMON_LIBS) t_imp_cred: t_imp_cred.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_imp_cred.o $(COMMON_LIBS) t_imp_name: t_imp_name.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_imp_name.o $(COMMON_LIBS) t_invalid: t_invalid.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_invalid.o $(COMMON_LIBS) t_inq_cred: t_inq_cred.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_inq_cred.o $(COMMON_LIBS) t_inq_ctx: t_inq_ctx.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_inq_ctx.o $(COMMON_LIBS) t_inq_mechs_name: t_inq_mechs_name.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_inq_mechs_name.o $(COMMON_LIBS) t_iov: t_iov.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_iov.o $(COMMON_LIBS) t_lifetime: t_lifetime.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_lifetime.o $(COMMON_LIBS) t_namingexts: t_namingexts.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_namingexts.o $(COMMON_LIBS) t_pcontok: t_pcontok.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_pcontok.o $(COMMON_LIBS) t_oid: t_oid.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_oid.o $(COMMON_LIBS) t_prf: t_prf.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_prf.o $(COMMON_LIBS) t_s4u: t_s4u.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_s4u.o $(COMMON_LIBS) t_s4u2proxy_krb5: t_s4u2proxy_krb5.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_s4u2proxy_krb5.o $(COMMON_LIBS) t_saslname: t_saslname.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_saslname.o $(COMMON_LIBS) t_spnego: t_spnego.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_spnego.o $(COMMON_LIBS) t_srcattrs: t_srcattrs.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_srcattrs.o $(COMMON_LIBS) t_store_cred: t_store_cred.o $(COMMON_DEPS) $(CC_LINK) -o $@ t_store_cred.o $(COMMON_LIBS) clean: $(RM) ccinit ccrefresh reload t_accname t_add_cred t_bindings $(RM) t_ccselect t_ciflags t_context t_credstore t_enctypes t_err $(RM) t_export_cred t_export_name t_gssexts t_iakerb t_imp_cred $(RM) t_imp_name t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov $(RM) t_lifetime t_namingexts t_oid t_pcontok t_prf t_s4u $(RM) t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs t_store_cred krb5-1.22.1/src/tests/gssapi/t_inq_mechs_name.c0000664000175000017500000000450615051422640021222 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_inq_mechs_name.c - Exercise gss_inquire_mechs_for_name */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Test program to exercise gss_inquire_mechs_for_name by importing a name and * reporting the mech OIDs which are reported as being able to process it. * * Usage: ./t_inq_mechs_name name */ #include #include "common.h" int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_name_t name; gss_OID_set mechs; size_t i; if (argc != 2) { fprintf(stderr, "Usage: t_inq_mechs_for_name name\n"); return 1; } name = import_name(argv[1]); major = gss_inquire_mechs_for_name(&minor, name, &mechs); check_gsserr("gss_inquire_mechs_for_name", major, minor); for (i = 0; i < mechs->count; i++) display_oid(NULL, &mechs->elements[i]); (void)gss_release_oid_set(&minor, &mechs); (void)gss_release_name(&minor, &name); return 0; } krb5-1.22.1/src/tests/gssapi/t_credstore.py0000664000175000017500000001147015051422640020452 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm() mark('gss_store_cred_into() and ccache/keytab') storagecache = 'FILE:' + os.path.join(realm.testdir, 'user_store') servicekeytab = os.path.join(realm.testdir, 'kt') service_cs = 'service/cs@%s' % realm.realm realm.addprinc(service_cs) realm.extract_keytab(service_cs, servicekeytab) realm.kinit(service_cs, None, ['-k', '-t', servicekeytab]) msgs = ('Storing %s -> %s in MEMORY:' % (service_cs, realm.krbtgt_princ), 'Moving ccache MEMORY:', 'Retrieving %s from FILE:%s' % (service_cs, servicekeytab)) realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache, 'keytab', servicekeytab], expected_trace=msgs) mark('matching') scc = 'FILE:' + os.path.join(realm.testdir, 'service_cache') realm.kinit(realm.host_princ, flags=['-k', '-c', scc]) realm.run(['./t_credstore', '-i', 'p:' + realm.host_princ, 'ccache', scc]) realm.run(['./t_credstore', '-i', 'h:host', 'ccache', scc]) realm.run(['./t_credstore', '-i', 'h:host@' + hostname, 'ccache', scc]) realm.run(['./t_credstore', '-i', 'p:wrong', 'ccache', scc], expected_code=1, expected_msg='does not match desired name') realm.run(['./t_credstore', '-i', 'h:host@-nomatch-', 'ccache', scc], expected_code=1, expected_msg='does not match desired name') realm.run(['./t_credstore', '-i', 'h:svc', 'ccache', scc], expected_code=1, expected_msg='does not match desired name') mark('matching (fallback)') canonname = canonicalize_hostname(hostname) if canonname != hostname: canonprinc = 'host/%s@%s' % (canonname, realm.realm) realm.addprinc(canonprinc) realm.extract_keytab(canonprinc, realm.keytab) realm.kinit(canonprinc, flags=['-k', '-c', scc]) realm.run(['./t_credstore', '-i', 'h:host', 'ccache', scc]) realm.run(['./t_credstore', '-i', 'h:host@' + hostname, 'ccache', scc]) realm.run(['./t_credstore', '-i', 'h:host@' + canonname, 'ccache', scc]) realm.run(['./t_credstore', '-i', 'p:' + canonprinc, 'ccache', scc]) realm.run(['./t_credstore', '-i', 'p:' + realm.host_princ, 'ccache', scc], expected_code=1, expected_msg='does not match desired name') realm.run(['./t_credstore', '-i', 'h:host@-nomatch-', 'ccache', scc], expected_code=1, expected_msg='does not match desired name') else: skipped('fallback matching test', '%s does not canonicalize to a different name' % hostname) mark('rcache') # t_credstore -r should produce a replay error normally, but not with # rcache set to "none:". realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ], expected_code=1, expected_msg='gss_accept_sec_context(2): Request is a replay') realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ, 'rcache', 'none:']) # Test password feature. mark('password') # Must be used with a desired name. realm.run(['./t_credstore', '-i', '', 'password', 'pw'], expected_code=1, expected_msg='An invalid name was supplied') # Must not be used with a client keytab. realm.run(['./t_credstore', '-i', 'u:' + realm.user_princ, 'password', 'pw', 'client_keytab', servicekeytab], expected_code=1, expected_msg='Credential usage type is unknown') # Must not be used with a ccache. realm.run(['./t_credstore', '-i', 'u:' + realm.user_princ, 'password', 'pw', 'ccache', storagecache], expected_code=1, expected_msg='Credential usage type is unknown') # Must be acquiring initiator credentials. realm.run(['./t_credstore', '-a', 'u:' + realm.user_princ, 'password', 'pw'], expected_code=1, expected_msg='Credential usage type is unknown') msgs = ('Getting initial credentials for %s' % realm.user_princ, 'Storing %s -> %s in MEMORY:' % (realm.user_princ, realm.krbtgt_princ), 'Destroying ccache MEMORY:') realm.run(['./t_credstore', '-i', 'u:' + realm.user_princ, 'password', password('user')], expected_trace=msgs) mark('verify') msgs = ('Getting initial credentials for %s' % realm.user_princ, 'Storing %s -> %s in MEMORY:' % (realm.user_princ, realm.krbtgt_princ), 'Getting credentials %s -> %s' % (realm.user_princ, service_cs), 'Storing %s -> %s in MEMORY:' % (realm.user_princ, service_cs)) realm.run(['./t_credstore', '-i', 'u:' + realm.user_princ, 'password', password('user'), 'keytab', servicekeytab, 'verify', service_cs], expected_trace=msgs) # Try again with verification failing due to key mismatch. realm.run([kadminl, 'cpw', '-randkey', service_cs]) realm.run([kadminl, 'modprinc', '-kvno', '1', service_cs]) errmsg = 'Cannot decrypt ticket for %s' % service_cs realm.run(['./t_credstore', '-i', 'u:' + realm.user_princ, 'password', password('user'), 'keytab', servicekeytab, 'verify', service_cs], expected_code=1, expected_msg=errmsg) success('Credential store tests') krb5-1.22.1/src/tests/gssapi/t_s4u.py0000775000175000017500000004330115051422640017174 0ustar ghudsonghudsonfrom k5test import * from base64 import b64encode import shutil realm = K5Realm(create_host=False, get_creds=False) usercache = 'FILE:' + os.path.join(realm.testdir, 'usercache') storagecache = 'FILE:' + os.path.join(realm.testdir, 'save') # Create two service principals with keys in the default keytab. service1 = 'service/1@%s' % realm.realm realm.addprinc(service1) realm.extract_keytab(service1, realm.keytab) service2 = 'service/2@%s' % realm.realm realm.addprinc(service2) realm.extract_keytab(service2, realm.keytab) puser = 'p:' + realm.user_princ pservice1 = 'p:' + service1 pservice2 = 'p:' + service2 # Get forwardable creds for service1 in the default cache. realm.kinit(service1, None, ['-f', '-k']) # Try S4U2Self for user with a restricted password. realm.run([kadminl, 'modprinc', '+needchange', realm.user_princ]) realm.run(['./t_s4u', 'e:user', '-']) realm.run([kadminl, 'modprinc', '-needchange', '-pwexpire', '1/1/2000', realm.user_princ]) realm.run(['./t_s4u', 'e:user', '-']) realm.run([kadminl, 'modprinc', '-pwexpire', 'never', realm.user_princ]) # Try krb5 -> S4U2Proxy with forwardable user creds. This should fail # at the S4U2Proxy step since the DB2 back end currently has no # support for allowing it. realm.kinit(realm.user_princ, password('user'), ['-f', '-c', usercache]) output = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2], expected_code=1) if ('auth1: ' + realm.user_princ not in output or 'KDC can\'t fulfill requested option' not in output): fail('krb5 -> s4u2proxy') # Again with SPNEGO. output = realm.run(['./t_s4u2proxy_krb5', '--spnego', usercache, storagecache, '-', pservice1, pservice2], expected_code=1) if ('auth1: ' + realm.user_princ not in output or 'KDC can\'t fulfill requested option' not in output): fail('krb5 -> s4u2proxy (SPNEGO)') # Try krb5 -> S4U2Proxy without forwardable user creds. realm.kinit(realm.user_princ, password('user'), ['-c', usercache]) output = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, pservice1, pservice1, pservice2], expected_code=1) if ('auth1: ' + realm.user_princ not in output or 'KDC can\'t fulfill requested option' not in output): fail('krb5 -> s4u2proxy not-forwardable') # Try S4U2Self. Ask for an S4U2Proxy step; this won't succeed because # service/1 isn't allowed to get a forwardable S4U2Self ticket. realm.run(['./t_s4u', puser, pservice2], expected_code=1, expected_msg='KDC can\'t fulfill requested option') realm.run(['./t_s4u', '--spnego', puser, pservice2], expected_code=1, expected_msg='KDC can\'t fulfill requested option') # Correct that problem and try again. As above, the S4U2Proxy step # won't actually succeed since we don't support that in DB2. realm.run([kadminl, 'modprinc', '+ok_to_auth_as_delegate', service1]) realm.run(['./t_s4u', puser, pservice2], expected_code=1, expected_msg='KDC can\'t fulfill requested option') # Again with SPNEGO. This uses SPNEGO for the initial authentication, # but still uses krb5 for S4U2Proxy--the delegated cred is returned as # a krb5 cred, not a SPNEGO cred, and t_s4u uses the delegated cred # directly rather than saving and reacquiring it. realm.run(['./t_s4u', '--spnego', puser, pservice2], expected_code=1, expected_msg='KDC can\'t fulfill requested option') realm.stop() # Set up a realm using the test KDB module so that we can do # successful S4U2Proxy delegations. testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts'}, 'service/1': {'flags': '+ok-to-auth-as-delegate', 'keys': 'aes128-cts'}, 'service/2': {'keys': 'aes128-cts'}} conf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': testprincs, 'delegation': {'service/1': 'service/2'}}}} realm = K5Realm(create_kdb=False, kdc_conf=conf) userkeytab = 'FILE:' + os.path.join(realm.testdir, 'userkeytab') realm.extract_keytab(realm.user_princ, userkeytab) realm.extract_keytab(service1, realm.keytab) realm.extract_keytab(service2, realm.keytab) realm.start_kdc() # Get forwardable creds for service1 in the default cache. realm.kinit(service1, None, ['-f', '-k']) # Successful krb5 -> S4U2Proxy, with krb5 and SPNEGO mechs. realm.kinit(realm.user_princ, None, ['-f', '-k', '-c', usercache, '-t', userkeytab]) out = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') out = realm.run(['./t_s4u2proxy_krb5', '--spnego', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') # Successful S4U2Self -> S4U2Proxy. out = realm.run(['./t_s4u', puser, pservice2]) # Regression test for #8139: get a user ticket directly for service1 and # try krb5 -> S4U2Proxy. realm.kinit(realm.user_princ, None, ['-f', '-k', '-c', usercache, '-t', userkeytab, '-S', service1]) out = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') # Simulate a krbtgt rollover and verify that the user ticket can still # be validated. realm.stop_kdc() newtgt_keys = ['2 aes128-cts', '1 aes128-cts'] newtgt_princs = {'krbtgt/KRBTEST.COM': {'keys': newtgt_keys}} newtgt_conf = {'dbmodules': {'test': {'princs': newtgt_princs}}} newtgt_env = realm.special_env('newtgt', True, kdc_conf=newtgt_conf) realm.start_kdc(env=newtgt_env) out = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') # Get a user ticket after the krbtgt rollover and verify that # S4U2Proxy delegation works (also a #8139 regression test). realm.kinit(realm.user_princ, None, ['-f', '-k', '-c', usercache, '-t', userkeytab]) out = realm.run(['./t_s4u2proxy_krb5', usercache, storagecache, '-', pservice1, pservice2]) if 'auth1: user@' not in out or 'auth2: user@' not in out: fail('krb5 -> s4u2proxy') realm.stop() mark('S4U2Self with various enctypes') for realm in multipass_realms(create_host=False, get_creds=False): service1 = 'service/1@%s' % realm.realm realm.addprinc(service1) realm.extract_keytab(service1, realm.keytab) realm.kinit(service1, None, ['-k']) realm.run(['./t_s4u', 'e:user', '-']) # Test cross realm S4U2Self using server referrals. mark('cross-realm S4U2Self') testprincs = {'krbtgt/SREALM': {'keys': 'aes128-cts'}, 'krbtgt/UREALM': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'other': {'keys': 'aes128-cts'}} kdcconf1 = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': testprincs, 'alias': {'enterprise@abc': '@UREALM', 'user@UREALM': '@UREALM'}}}} kdcconf2 = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': testprincs, 'alias': {'user@SREALM': '@SREALM', 'user@UREALM': 'user', 'enterprise@abc': 'user'}}}} r1, r2 = cross_realms(2, xtgts=(), args=({'realm': 'SREALM', 'kdc_conf': kdcconf1}, {'realm': 'UREALM', 'kdc_conf': kdcconf2}), create_kdb=False) r1.start_kdc() r2.start_kdc() r1.extract_keytab(r1.user_princ, r1.keytab) r1.kinit(r1.user_princ, None, ['-k', '-t', r1.keytab]) savefile = r1.ccache + '.save' shutil.copyfile(r1.ccache, savefile) # Include a regression test for #8741 by unsetting the default realm. remove_default = {'libdefaults': {'default_realm': None}} no_default = r1.special_env('no_default', False, krb5_conf=remove_default) msgs = ('Getting credentials user@UREALM -> user@SREALM', '/Matching credential not found', 'Getting credentials user@SREALM -> krbtgt/UREALM@SREALM', 'Received creds for desired service krbtgt/UREALM@SREALM', 'via TGT krbtgt/UREALM@SREALM after requesting user\\@SREALM@UREALM', 'krbtgt/SREALM@UREALM differs from requested user\\@SREALM@UREALM', 'via TGT krbtgt/SREALM@UREALM after requesting user@SREALM', 'TGS reply is for user@UREALM -> user@SREALM') r1.run(['./t_s4u', 'p:' + r2.user_princ, '-', r1.keytab], env=no_default, expected_trace=msgs) # Test realm identification of enterprise principal names ([MS-SFU] # 3.1.5.1.1.1). Attach a bogus realm to the enterprise name to verify # that we start at the server realm. mark('cross-realm S4U2Self with enterprise name') msgs = ('Getting initial credentials for enterprise\\@abc@SREALM', 'Sending unauthenticated request', '/Realm not local to KDC', 'Following referral to realm UREALM', 'Sending unauthenticated request', '/Additional pre-authentication required', 'Identified realm of client principal as UREALM', 'Getting credentials enterprise\\@abc@UREALM -> user@SREALM', 'TGS reply is for enterprise\\@abc@UREALM -> user@SREALM') r1.run(['./t_s4u', 'e:enterprise@abc@NOREALM', '-', r1.keytab], expected_trace=msgs) mark('S4U2Self using X509 certificate') # Encode name as a PEM certificate file (sort of) for use by kvno. def princ_cert(name): enc = b64encode(name.encode('ascii')).decode('ascii') return '-----BEGIN CERTIFICATE-----\n%s\n-----END y\n' % enc cert_path = os.path.join(r1.testdir, 'fake_cert') with open(cert_path, "w") as cert_file: cert_file.write(princ_cert('other')) shutil.copyfile(savefile, r1.ccache) msgs = ('Getting initial credentials for @SREALM', 'Identified realm of client principal as SREALM', 'TGS reply is for other@SREALM', 'Getting credentials other@SREALM', 'Storing other@SREALM') r1.run([kvno, '-F', cert_path, r1.user_princ], expected_trace=msgs) shutil.copyfile(savefile, r1.ccache) msgs = ('Getting credentials other@SREALM', 'TGS reply is for other@SREALM', 'Storing other@SREALM') r1.run([kvno, '-I', 'other', '-F', cert_path, r1.user_princ], expected_trace=msgs) shutil.copyfile(savefile, r1.ccache) msgs = ('Getting initial credentials for other@SREALM', 'Identified realm of client principal as SREALM', 'Getting credentials other@SREALM', 'TGS reply is for other@SREALM', 'Storing other@SREALM') r1.run([kvno, '-U', 'other', '-F', cert_path, r1.user_princ], expected_trace=msgs) mark('cross-realm S4U2Self using X509 certificate') with open(cert_path, "w") as cert_file: cert_file.write(princ_cert('user@UREALM')) shutil.copyfile(savefile, r1.ccache) msgs = ('Getting initial credentials for @SREALM', 'Identified realm of client principal as UREALM', 'TGS reply is for user@UREALM', 'Getting credentials user@UREALM', 'Storing user@UREALM') r1.run([kvno, '-F', cert_path, r1.user_princ], expected_trace=msgs) shutil.copyfile(savefile, r1.ccache) msgs = ('Getting credentials user@UREALM', 'TGS reply is for user@UREALM', 'Storing user@UREALM') r1.run([kvno, '-I', 'user@UREALM', '-F', cert_path, r1.user_princ], expected_trace=msgs) shutil.copyfile(savefile, r1.ccache) msgs = ('Getting initial credentials for enterprise\\@abc@SREALM', 'Identified realm of client principal as UREALM', 'Getting credentials enterprise\\@abc@UREALM', 'TGS reply is for enterprise\\@abc@UREALM', 'Storing enterprise\\@abc@UREALM') r1.run([kvno, '-U', 'enterprise@abc', '-F', cert_path, r1.user_princ], expected_trace=msgs) shutil.copyfile(savefile, r1.ccache) mark('S4U2Self using X509 certificate (GSSAPI)') r1.run(['./t_s4u', 'c:other', '-', r1.keytab]) r1.run(['./t_s4u', 'c:user@UREALM', '-', r1.keytab]) r1.run(['./t_s4u', '--spnego', 'c:other', '-', r1.keytab]) r1.run(['./t_s4u', '--spnego', 'c:user@UREALM', '-', r1.keytab]) r1.stop() r2.stop() mark('Resource-based constrained delegation') a_princs = {'krbtgt/A': {'keys': 'aes128-cts'}, 'krbtgt/B': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'sensitive': {'keys': 'aes128-cts', 'flags': '+disallow_forwardable'}, 'impersonator': {'keys': 'aes128-cts'}, 'service1': {'keys': 'aes128-cts'}, 'rb2': {'keys': 'aes128-cts'}, 'rb': {'keys': 'aes128-cts'}} a_kconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': a_princs, 'rbcd': {'rb@A': 'impersonator@A', 'rb2@A': 'service1@A'}, 'delegation': {'service1': 'rb2'}, 'alias': {'rb@A': 'rb', 'rb@B': '@B', 'rb@C': '@B', 'service/rb.a': 'rb', 'service/rb.b': '@B', 'service/rb.c': '@B' }}}} b_princs = {'krbtgt/B': {'keys': 'aes128-cts'}, 'krbtgt/A': {'keys': 'aes128-cts'}, 'krbtgt/C': {'keys': 'aes128-cts'}, 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, 'rb': {'keys': 'aes128-cts'}} b_kconf = {'realms': {'$realm': {'database_module': 'test'}}, 'dbmodules': {'test': {'db_library': 'test', 'princs': b_princs, 'rbcd': {'rb@B': 'impersonator@A'}, 'alias': {'rb@B': 'rb', 'service/rb.b': 'rb', 'rb@C': '@C', 'impersonator@A': '@A', 'service/rb.c': '@C'}}}} c_princs = {'krbtgt/C': {'keys': 'aes128-cts'}, 'krbtgt/B': {'keys': 'aes128-cts'}, 'rb': {'keys': 'aes128-cts'}} c_kconf = {'realms': {'$realm': {'database_module': 'test'}}, 'capaths': { 'A' : { 'C' : 'B' }}, 'dbmodules': {'test': {'db_library': 'test', 'princs': c_princs, 'rbcd': {'rb@C': ['impersonator@A', 'service1@A']}, 'alias': {'rb@C': 'rb', 'service/rb.c': 'rb' }}}} ra, rb, rc = cross_realms(3, xtgts=(), args=({'realm': 'A', 'kdc_conf': a_kconf}, {'realm': 'B', 'kdc_conf': b_kconf}, {'realm': 'C', 'kdc_conf': c_kconf}), create_kdb=False) ra.start_kdc() rb.start_kdc() rc.start_kdc() domain_realm = {'domain_realm': {'.a':'A', '.b':'B', '.c':'C'}} domain_conf = ra.special_env('domain_conf', False, krb5_conf=domain_realm) ra.extract_keytab('impersonator@A', ra.keytab) ra.kinit('impersonator@A', None, ['-f', '-k', '-t', ra.keytab]) mark('Local-realm RBCD') ra.run(['./t_s4u', 'p:' + ra.user_princ, 'p:rb']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'p:rb@A']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@A']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@A@']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@A@A']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.a']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.a'], env=domain_conf) ra.run(['./t_s4u', 'p:' + 'sensitive@A', 'h:service@rb.a'], expected_code=1) ra.run(['./t_s4u', 'p:' + rb.user_princ, 'h:service@rb.a']) mark('Cross-realm RBCD') ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@B']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@B@']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@B@A']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.b']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.b'], env=domain_conf) ra.run(['./t_s4u', 'p:' + 'sensitive@A', 'h:service@rb.b'], expected_code=1) ra.run(['./t_s4u', 'p:' + rb.user_princ, 'h:service@rb.b']) mark('RBCD transitive trust') ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@C']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@C@']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb@C@A']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.c']) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'h:service@rb.c'], env=domain_conf) ra.run(['./t_s4u', 'p:' + 'sensitive@A', 'h:service@rb.c'], expected_code=1) ra.run(['./t_s4u', 'p:' + rb.user_princ, 'h:service@rb.c']) # Although service1 has RBCD delegation privileges to rb2@A, it does # not have ok-to-auth-as-delegate and does have traditional delegation # privileges, so it cannot get a forwardable S4U2Self ticket. mark('RBCD forwardable blocked by forward delegation privileges') ra.extract_keytab('service1@A', ra.keytab) ra.kinit('service1@A', None, ['-f', '-k', '-t', ra.keytab]) ra.run(['./t_s4u', 'p:' + ra.user_princ, 'e:rb2@A'], expected_code=1, expected_msg='KDC can\'t fulfill requested option') ra.stop() rb.stop() rc.stop() success('S4U test cases') krb5-1.22.1/src/tests/gssapi/t_saslname.c0000664000175000017500000001472015051422640020056 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" static void dump_known_mech_attrs(gss_OID mech) { OM_uint32 major, minor; gss_OID_set mech_attrs = GSS_C_NO_OID_SET; gss_OID_set known_attrs = GSS_C_NO_OID_SET; size_t i; major = gss_inquire_attrs_for_mech(&minor, mech, &mech_attrs, &known_attrs); check_gsserr("gss_inquire_attrs_for_mech", major, minor); printf("Known attributes\n"); printf("----------------\n"); for (i = 0; i < known_attrs->count; i++) { gss_buffer_desc name = GSS_C_EMPTY_BUFFER; gss_buffer_desc short_desc = GSS_C_EMPTY_BUFFER; gss_buffer_desc long_desc = GSS_C_EMPTY_BUFFER; major = gss_display_mech_attr(&minor, &known_attrs->elements[i], &name, &short_desc, &long_desc); check_gsserr("gss_display_mech_attr", major, minor); printf("%.*s (%.*s): %.*s\n", (int)short_desc.length, (char *)short_desc.value, (int)name.length, (char *)name.value, (int)long_desc.length, (char *)long_desc.value); (void)gss_release_buffer(&minor, &name); (void)gss_release_buffer(&minor, &short_desc); (void)gss_release_buffer(&minor, &long_desc); } printf("\n"); (void)gss_release_oid_set(&minor, &mech_attrs); (void)gss_release_oid_set(&minor, &known_attrs); } static void dump_mech_attrs(gss_OID mech) { OM_uint32 major, minor; gss_OID_set mech_attrs = GSS_C_NO_OID_SET; gss_OID_set known_attrs = GSS_C_NO_OID_SET; size_t i; major = gss_inquire_attrs_for_mech(&minor, mech, &mech_attrs, &known_attrs); check_gsserr("gss_inquire_attrs_for_mech", major, minor); printf("Mech attrs: "); for (i = 0; i < mech_attrs->count; i++) { gss_buffer_desc name = GSS_C_EMPTY_BUFFER; gss_buffer_desc short_desc = GSS_C_EMPTY_BUFFER; gss_buffer_desc long_desc = GSS_C_EMPTY_BUFFER; major = gss_display_mech_attr(&minor, &mech_attrs->elements[i], &name, &short_desc, &long_desc); check_gsserr("gss_display_mech_attr", major, minor); printf("%.*s ", (int)name.length, (char *)name.value); (void)gss_release_buffer(&minor, &name); (void)gss_release_buffer(&minor, &short_desc); (void)gss_release_buffer(&minor, &long_desc); } printf("\n"); (void)gss_release_oid_set(&minor, &mech_attrs); (void)gss_release_oid_set(&minor, &known_attrs); } int main(int argc, char *argv[]) { gss_OID_set mechs; OM_uint32 major, minor; size_t i; major = gss_indicate_mechs(&minor, &mechs); check_gsserr("gss_indicate_mechs", major, minor); if (mechs->count > 0) dump_known_mech_attrs(mechs->elements); for (i = 0; i < mechs->count; i++) { gss_buffer_desc oidstr = GSS_C_EMPTY_BUFFER; gss_buffer_desc sasl_mech_name = GSS_C_EMPTY_BUFFER; gss_buffer_desc mech_name = GSS_C_EMPTY_BUFFER; gss_buffer_desc mech_description = GSS_C_EMPTY_BUFFER; gss_OID oid = GSS_C_NO_OID; major = gss_oid_to_str(&minor, &mechs->elements[i], &oidstr); if (GSS_ERROR(major)) continue; major = gss_inquire_saslname_for_mech(&minor, &mechs->elements[i], &sasl_mech_name, &mech_name, &mech_description); if (GSS_ERROR(major)) { gss_release_buffer(&minor, &oidstr); continue; } printf("-------------------------------------------------------------" "-----------------\n"); printf("OID : %.*s\n", (int)oidstr.length, (char *)oidstr.value); printf("SASL mech : %.*s\n", (int)sasl_mech_name.length, (char *)sasl_mech_name.value); printf("Mech name : %.*s\n", (int)mech_name.length, (char *)mech_name.value); printf("Mech desc : %.*s\n", (int)mech_description.length, (char *)mech_description.value); dump_mech_attrs(&mechs->elements[i]); printf("-------------------------------------------------------------" "-----------------\n"); major = gss_inquire_mech_for_saslname(&minor, &sasl_mech_name, &oid); check_gsserr("gss_inquire_mech_for_saslname", major, minor); if (oid == GSS_C_NO_OID || (oid->length != mechs->elements[i].length && memcmp(oid->elements, mechs->elements[i].elements, oid->length) != 0)) { (void)gss_release_buffer(&minor, &oidstr); (void)gss_oid_to_str(&minor, oid, &oidstr); fprintf(stderr, "Got different OID %.*s for mechanism %.*s\n", (int)oidstr.length, (char *)oidstr.value, (int)sasl_mech_name.length, (char *)sasl_mech_name.value); } (void)gss_release_buffer(&minor, &oidstr); (void)gss_release_buffer(&minor, &sasl_mech_name); (void)gss_release_buffer(&minor, &mech_name); (void)gss_release_buffer(&minor, &mech_description); } (void)gss_release_oid_set(&minor, &mechs); return 0; } krb5-1.22.1/src/tests/gssapi/t_store_cred.py0000664000175000017500000000637615051422640020622 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(create_user=False) alice = 'alice@' + realm.realm bob = 'bob@' + realm.realm cc_alice = realm.ccache + '.alice' cc_bob = realm.ccache + '.bob' realm.addprinc(alice) realm.addprinc(bob) realm.extract_keytab(alice, realm.keytab) realm.extract_keytab(bob, realm.keytab) realm.kinit(alice, flags=['-k', '-c', cc_alice]) realm.kinit(bob, flags=['-k', '-c', cc_bob]) mark('FILE, default output ccache') realm.run(['./t_store_cred', cc_alice]) realm.klist(alice) # Overwriting should fail by default, whether or not the principal matches. realm.run(['./t_store_cred', cc_alice], expected_code=1, expected_msg='The requested credential element already exists') realm.run(['./t_store_cred', cc_bob], expected_code=1, expected_msg='The requested credential element already exists') # Overwriting should succeed with overwrite_cred set. realm.run(['./t_store_cred', '-o', cc_bob]) realm.klist(bob) # default_cred has no effect without a collection. realm.run(['./t_store_cred', '-d', '-o', cc_alice]) realm.klist(alice) mark('FILE, gss_krb5_ccache_name()') cc_alternate = realm.ccache + '.alternate' realm.run(['./t_store_cred', cc_alice, cc_alternate]) realm.klist(alice, ccache=cc_alternate) realm.run(['./t_store_cred', cc_bob, cc_alternate], expected_code=1, expected_msg='The requested credential element already exists') mark('FILE, gss_store_cred_into()') os.remove(cc_alternate) realm.run(['./t_store_cred', '-i', cc_alice, cc_alternate]) realm.klist(alice, ccache=cc_alternate) realm.run(['./t_store_cred', '-i', cc_bob, cc_alternate], expected_code=1, expected_msg='The requested credential element already exists') mark('DIR, gss_krb5_ccache_name()') cc_dir = 'DIR:' + os.path.join(realm.testdir, 'cc') realm.run(['./t_store_cred', cc_alice, cc_dir]) realm.run([klist, '-c', cc_dir], expected_code=1, expected_msg='No credentials cache found') realm.run([klist, '-l', '-c', cc_dir], expected_msg=alice) realm.run(['./t_store_cred', cc_alice, cc_dir], expected_code=1, expected_msg='The requested credential element already exists') realm.run(['./t_store_cred', '-o', cc_alice, cc_dir]) realm.run([klist, '-c', cc_dir], expected_code=1, expected_msg='No credentials cache found') realm.run([klist, '-l', cc_dir], expected_msg=alice) realm.run(['./t_store_cred', '-d', cc_bob, cc_dir]) # The k5test klist method does not currently work with a collection name. realm.run([klist, cc_dir], expected_msg=bob) realm.run([klist, '-l', cc_dir], expected_msg=alice) realm.run(['./t_store_cred', '-o', '-d', cc_alice, cc_dir]) realm.run([klist, cc_dir], expected_msg=alice) realm.run([kdestroy, '-A', '-c', cc_dir]) mark('DIR, gss_store_cred_into()') realm.run(['./t_store_cred', '-i', cc_alice, cc_dir]) realm.run(['./t_store_cred', '-i', '-d', cc_bob, cc_dir]) realm.run([klist, cc_dir], expected_msg=bob) realm.run([klist, '-l', cc_dir], expected_msg=alice) realm.run([kdestroy, '-A', '-c', cc_dir]) mark('DIR, default output ccache') realm.ccache = cc_dir realm.env['KRB5CCNAME'] = cc_dir realm.run(['./t_store_cred', '-i', cc_alice, cc_dir]) realm.run(['./t_store_cred', '-i', '-d', cc_bob, cc_dir]) realm.run([klist], expected_msg=bob) realm.run([klist, '-l'], expected_msg=alice) success('gss_store_cred() tests') krb5-1.22.1/src/tests/gssapi/t_ccselect.c0000664000175000017500000000727115051422640020043 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_ccselect.c - Test program for GSSAPI cred selection */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" /* * Test program for client credential selection, intended to be run from a * Python test script. Establishes contexts with an optionally specified * initiator name, a specified target name, and the default acceptor cred. If * the exchange is successful, prints the initiator name as seen by the * acceptor. If any call is unsuccessful, displays an error message. Exits * with status 0 if all operations are successful, or 1 if not. * * Usage: ./t_ccselect targetname [initiatorname|-] */ int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_cred_id_t initiator_cred = GSS_C_NO_CREDENTIAL; gss_name_t target_name, initiator_name = GSS_C_NO_NAME; gss_name_t real_initiator_name; gss_buffer_desc namebuf; gss_ctx_id_t initiator_context, acceptor_context; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s targetname [initiatorname|-]\n", argv[0]); return 1; } target_name = import_name(argv[1]); if (argc >= 3) { /* Get initiator cred. */ if (strcmp(argv[2], "-") != 0) initiator_name = import_name(argv[2]); major = gss_acquire_cred(&minor, initiator_name, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &initiator_cred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); } flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, initiator_cred, GSS_C_NO_CREDENTIAL, target_name, flags, &initiator_context, &acceptor_context, &real_initiator_name, NULL, NULL); namebuf.value = NULL; namebuf.length = 0; major = gss_display_name(&minor, real_initiator_name, &namebuf, NULL); check_gsserr("gss_display_name(initiator)", major, minor); printf("%.*s\n", (int)namebuf.length, (char *)namebuf.value); (void)gss_release_name(&minor, &target_name); (void)gss_release_name(&minor, &initiator_name); (void)gss_release_name(&minor, &real_initiator_name); (void)gss_release_cred(&minor, &initiator_cred); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); (void)gss_release_buffer(&minor, &namebuf); return 0; } krb5-1.22.1/src/tests/gssapi/t_authind.py0000664000175000017500000000441315051422640020113 0ustar ghudsonghudsonfrom k5test import * # Test authentication indicators. Load the test preauth module so we # can control the indicators asserted. testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}}} realm = K5Realm(krb5_conf=conf) realm.run([kadminl, 'addprinc', '-randkey', 'service/1']) realm.run([kadminl, 'addprinc', '-randkey', 'service/2']) realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ]) realm.run([kadminl, 'setstr', 'service/1', 'require_auth', 'superstrong']) realm.run([kadminl, 'setstr', 'service/2', 'require_auth', 'one two']) realm.run([kadminl, 'xst', 'service/1']) realm.run([kadminl, 'xst', 'service/2']) realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=superstrong']) out = realm.run(['./t_srcattrs', 'p:service/1']) if ('Attribute auth-indicators Authenticated Complete') not in out: fail('Expected attribute type data not seen') # UTF8 "superstrong" if '73757065727374726f6e67' not in out: fail('Expected auth indicator not seen in name attributes') msg = 'gss_init_sec_context: KDC policy rejects request' realm.run(['./t_srcattrs', 'p:service/2'], expected_code=1, expected_msg=msg) realm.kinit(realm.user_princ, password('user'), ['-X', 'indicators=one two']) out = realm.run(['./t_srcattrs', 'p:service/2']) # Hexadecimal "one" and "two" if '6f6e65' not in out or '74776f' not in out: fail('Expected auth indicator not seen in name attributes') realm.stop() # Test the FAST encrypted challenge auth indicator. kdcconf = {'realms': {'$realm': {'encrypted_challenge_indicator': 'fast'}}} realm = K5Realm(kdc_conf=kdcconf) realm.run([kadminl, 'modprinc', '+requires_preauth', realm.user_princ]) realm.run([kadminl, 'xst', realm.host_princ]) realm.kinit(realm.user_princ, password('user')) realm.kinit(realm.user_princ, password('user'), ['-T', realm.ccache]) out = realm.run(['./t_srcattrs', 'p:' + realm.host_princ]) if ('Attribute auth-indicators Authenticated Complete') not in out: fail('Expected attribute type not seen') if '66617374' not in out: fail('Expected auth indicator not seen in name attributes') realm.stop() success('GSSAPI auth indicator tests') krb5-1.22.1/src/tests/gssapi/t_pcontok.c0000664000175000017500000001540215051422640017726 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_pcontok.c - gss_process_context_token tests */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This test program exercises krb5 gss_process_context_token. It first * establishes a context to a named target. Then, if the resulting context * uses RFC 1964, it creates a context deletion token from the acceptor to the * initiator and passes it to the initiator using gss_process_context_token. * If the established context uses RFC 4121, this program feeds a made-up * context token to gss_process_context_token and checks for the expected * error. */ #include "k5-int.h" #include "common.h" #define SGN_ALG_HMAC_SHA1_DES3_KD 0x04 #define SGN_ALG_HMAC_MD5 0x11 /* * Create a valid RFC 1964 context deletion token using the information in * * lctx. We must do this by hand since we no longer create context deletion * tokens from gss_delete_sec_context. */ static void make_delete_token(gss_krb5_lucid_context_v1_t *lctx, gss_buffer_desc *out) { krb5_error_code ret; krb5_context context; krb5_keyblock seqkb; krb5_key seq; krb5_checksum cksum; krb5_cksumtype cktype; krb5_keyusage ckusage; krb5_crypto_iov iov; krb5_data d; size_t cksize, tlen; unsigned char *token, *ptr, iv[8]; gss_krb5_lucid_key_t *lkey = &lctx->rfc1964_kd.ctx_key; int signalg = lctx->rfc1964_kd.sign_alg; ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); seqkb.enctype = lkey->type; seqkb.length = lkey->length; seqkb.contents = lkey->data; ret = krb5_k_create_key(context, &seqkb, &seq); check_k5err(context, "krb5_k_create_key", ret); if (signalg == SGN_ALG_HMAC_SHA1_DES3_KD) { cktype = CKSUMTYPE_HMAC_SHA1_DES3; cksize = 20; ckusage = 23; } else if (signalg == SGN_ALG_HMAC_MD5) { cktype = CKSUMTYPE_HMAC_MD5_ARCFOUR; cksize = 8; ckusage = 15; } else { abort(); } tlen = 20 + mech_krb5.length + cksize; token = malloc(tlen); assert(token != NULL); /* Create the ASN.1 wrapper (4 + mech_krb5.length bytes). Assume the ASN.1 * lengths fit in one byte since deletion tokens are short. */ ptr = token; *ptr++ = 0x60; *ptr++ = tlen - 2; *ptr++ = 0x06; *ptr++ = mech_krb5.length; memcpy(ptr, mech_krb5.elements, mech_krb5.length); ptr += mech_krb5.length; /* Create the RFC 1964 token header (8 bytes). */ *ptr++ = 0x01; *ptr++ = 0x02; store_16_le(signalg, ptr); ptr += 2; *ptr++ = 0xFF; *ptr++ = 0xFF; *ptr++ = 0xFF; *ptr++ = 0xFF; /* Create the checksum (cksize bytes at offset 8 from the header). */ d = make_data(ptr - 8, 8); ret = krb5_k_make_checksum(context, cktype, seq, ckusage, &d, &cksum); check_k5err(context, "krb5_k_make_checksum", ret); memcpy(ptr + 8, cksum.contents, cksize); /* Create the sequence number (8 bytes). */ iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(ptr, 8); ptr[4] = ptr[5] = ptr[6] = ptr[7] = lctx->initiate ? 0 : 0xFF; memcpy(iv, ptr + 8, 8); d = make_data(iv, 8); if (signalg == SGN_ALG_HMAC_MD5) { store_32_be(lctx->send_seq, ptr); ret = krb5int_arcfour_gsscrypt(&seq->keyblock, 0, &d, &iov, 1); check_k5err(context, "krb5int_arcfour_gsscrypt(seq)", ret); } else { store_32_le(lctx->send_seq, ptr); ret = krb5_k_encrypt_iov(context, seq, 24, &d, &iov, 1); check_k5err(context, "krb5_k_encrypt_iov(seq)", ret); } krb5_free_checksum_contents(context, &cksum); krb5_k_free_key(context, seq); krb5_free_context(context); out->length = tlen; out->value = token; } int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_name_t tname; gss_buffer_desc token, in = GSS_C_EMPTY_BUFFER, out; gss_ctx_id_t ictx, actx; gss_krb5_lucid_context_v1_t *lctx; void *lptr; assert(argc == 2); tname = import_name(argv[1]); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, NULL, NULL, NULL); /* Export the acceptor context to a lucid context so we can look inside. */ major = gss_krb5_export_lucid_sec_context(&minor, &actx, 1, &lptr); check_gsserr("gss_export_lucid_sec_context", major, minor); lctx = lptr; if (!lctx->protocol) { /* Make an RFC 1964 context deletion token and pass it to * gss_process_context_token. */ make_delete_token(lctx, &token); major = gss_process_context_token(&minor, ictx, &token); free(token.value); check_gsserr("gss_process_context_token", major, minor); /* Check for the appropriate major code from gss_wrap. */ major = gss_wrap(&minor, ictx, 1, GSS_C_QOP_DEFAULT, &in, NULL, &out); assert(major == GSS_S_NO_CONTEXT); } else { /* RFC 4121 defines no context deletion token, so try passing something * arbitrary and check for the appropriate major code. */ token.value = "abcd"; token.length = 4; major = gss_process_context_token(&minor, ictx, &token); assert(major == GSS_S_DEFECTIVE_TOKEN); } (void)gss_release_name(&minor, &tname); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_krb5_free_lucid_sec_context(&minor, lptr); return 0; } krb5-1.22.1/src/tests/gssapi/t_iov.c0000664000175000017500000005355615051422640017062 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_iov.c - Test program for IOV functions */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "common.h" /* Concatenate iov (except for sign-only buffers) into a contiguous token. */ static void concat_iov(gss_iov_buffer_desc *iov, size_t iovlen, char **buf_out, size_t *len_out) { size_t len, i; char *buf; /* Concatenate the result into a contiguous buffer. */ len = 0; for (i = 0; i < iovlen; i++) { if (GSS_IOV_BUFFER_TYPE(iov[i].type) != GSS_IOV_BUFFER_TYPE_SIGN_ONLY) len += iov[i].buffer.length; } buf = malloc(len); if (buf == NULL) errout("malloc failed"); len = 0; for (i = 0; i < iovlen; i++) { if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_SIGN_ONLY) continue; memcpy(buf + len, iov[i].buffer.value, iov[i].buffer.length); len += iov[i].buffer.length; } *buf_out = buf; *len_out = len; } static void check_encrypted(const char *msg, int conf, const char *buf, const char *plain) { int same = memcmp(buf, plain, strlen(plain)) == 0; if ((conf && same) || (!conf && !same)) errout(msg); } /* * Wrap str in standard form (HEADER | DATA | PADDING | TRAILER) using the * caller-provided array iov, which must have space for four elements. Library * allocation will be used for the header/padding/trailer buffers, so the * caller must check and free them. */ static void wrap_std(gss_ctx_id_t ctx, char *str, gss_iov_buffer_desc *iov, int conf) { OM_uint32 minor, major; int oconf; /* Lay out iov array. */ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = str; iov[1].buffer.length = strlen(str); iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_FLAG_ALLOCATE; iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_FLAG_ALLOCATE; /* Wrap. This will allocate header/padding/trailer buffers as necessary * and encrypt str in place. */ major = gss_wrap_iov(&minor, ctx, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 4); check_gsserr("gss_wrap_iov(std)", major, minor); if (oconf != conf) errout("gss_wrap_iov(std) conf"); } /* Create standard tokens using gss_wrap_iov and ctx1, and make sure we can * unwrap them using ctx2 in all of the supported ways. */ static void test_standard_wrap(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2, int conf) { OM_uint32 major, minor; gss_iov_buffer_desc iov[4], stiov[2]; gss_qop_t qop; gss_buffer_desc input, output; const char *string1 = "The swift brown fox jumped over the lazy dog."; const char *string2 = "Now is the time!"; const char *string3 = "x"; const char *string4 = "!@#"; char data[1024], *fulltoken; size_t len; int oconf; ptrdiff_t offset; /* Wrap a standard token and unwrap it using the iov array. */ memcpy(data, string1, strlen(string1) + 1); wrap_std(ctx1, data, iov, conf); check_encrypted("gss_wrap_iov(std1) encryption", conf, data, string1); major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, iov, 4); check_gsserr("gss_unwrap_iov(std1)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(std1) conf/qop"); if (iov[1].buffer.value != data || iov[1].buffer.length != strlen(string1)) errout("gss_unwrap_iov(std1) data buffer"); if (memcmp(data, string1, iov[1].buffer.length) != 0) errout("gss_unwrap_iov(std1) decryption"); (void)gss_release_iov_buffer(&minor, iov, 4); /* Wrap a standard token and unwrap it using gss_unwrap(). */ memcpy(data, string2, strlen(string2) + 1); wrap_std(ctx1, data, iov, conf); concat_iov(iov, 4, &fulltoken, &len); input.value = fulltoken; input.length = len; major = gss_unwrap(&minor, ctx2, &input, &output, &oconf, &qop); check_gsserr("gss_unwrap(std2)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap(std2) conf/qop"); if (output.length != strlen(string2) || memcmp(output.value, string2, output.length) != 0) errout("gss_unwrap(std2) decryption"); (void)gss_release_buffer(&minor, &output); (void)gss_release_iov_buffer(&minor, iov, 4); free(fulltoken); /* Wrap a standard token and unwrap it using a stream buffer. */ memcpy(data, string3, strlen(string3) + 1); wrap_std(ctx1, data, iov, conf); concat_iov(iov, 4, &fulltoken, &len); stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; stiov[0].buffer.value = fulltoken; stiov[0].buffer.length = len; stiov[1].type = GSS_IOV_BUFFER_TYPE_DATA; major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 2); check_gsserr("gss_unwrap_iov(std3)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(std3) conf/qop"); if (stiov[1].buffer.length != strlen(string3) || memcmp(stiov[1].buffer.value, string3, strlen(string3)) != 0) errout("gss_unwrap_iov(std3) decryption"); offset = (char *)stiov[1].buffer.value - fulltoken; if (offset < 0 || (size_t)offset > len) errout("gss_unwrap_iov(std3) offset"); (void)gss_release_iov_buffer(&minor, iov, 4); free(fulltoken); /* Wrap a token using gss_wrap and unwrap it using a stream buffer with * allocation and copying. */ input.value = (char *)string4; input.length = strlen(string4); major = gss_wrap(&minor, ctx1, conf, GSS_C_QOP_DEFAULT, &input, &oconf, &output); check_gsserr("gss_wrap(std4)", major, minor); if (oconf != conf) errout("gss_wrap(std4) conf"); stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; stiov[0].buffer = output; stiov[1].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 2); check_gsserr("gss_unwrap_iov(std4)", major, minor); if (!(GSS_IOV_BUFFER_FLAGS(stiov[1].type) & GSS_IOV_BUFFER_FLAG_ALLOCATED)) errout("gss_unwrap_iov(std4) allocated"); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(std4) conf/qop"); if (stiov[1].buffer.length != strlen(string4) || memcmp(stiov[1].buffer.value, string4, strlen(string4)) != 0) errout("gss_unwrap_iov(std4) decryption"); (void)gss_release_buffer(&minor, &output); (void)gss_release_iov_buffer(&minor, stiov, 2); } /* * Wrap an AEAD token (HEADER | SIGN_ONLY | DATA | PADDING | TRAILER) using the * caller-provided array iov, which must have space for five elements, and the * caller-provided buffer data, which must be big enough to handle the test * inputs. Library allocation will not be used. */ static void wrap_aead(gss_ctx_id_t ctx, const char *sign, const char *wrap, gss_iov_buffer_desc *iov, char *data, int conf) { OM_uint32 major, minor; int oconf; char *ptr; /* Lay out iov array. */ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[1].buffer.value = (char *)sign; iov[1].buffer.length = strlen(sign); iov[2].type = GSS_IOV_BUFFER_TYPE_DATA; iov[2].buffer.value = (char *)wrap; iov[2].buffer.length = strlen(wrap); iov[3].type = GSS_IOV_BUFFER_TYPE_PADDING; iov[4].type = GSS_IOV_BUFFER_TYPE_TRAILER; /* Get header/padding/trailer lengths. */ major = gss_wrap_iov_length(&minor, ctx, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 5); check_gsserr("gss_wrap_iov_length(aead)", major, minor); if (oconf != conf) errout("gss_wrap_iov_length(aead) conf"); if (iov[1].buffer.value != sign || iov[1].buffer.length != strlen(sign)) errout("gss_wrap_iov_length(aead) sign-only buffer"); if (iov[2].buffer.value != wrap || iov[2].buffer.length != strlen(wrap)) errout("gss_wrap_iov_length(aead) data buffer"); /* Set iov buffer pointers using returned lengths. */ iov[0].buffer.value = data; ptr = data + iov[0].buffer.length; memcpy(ptr, wrap, strlen(wrap)); iov[2].buffer.value = ptr; ptr += iov[2].buffer.length; iov[3].buffer.value = ptr; ptr += iov[3].buffer.length; iov[4].buffer.value = ptr; /* Wrap the AEAD token. */ major = gss_wrap_iov(&minor, ctx, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 5); check_gsserr("gss_wrap_iov(aead)", major, minor); if (oconf != conf) errout("gss_wrap_iov(aead) conf"); if (iov[1].buffer.value != sign || iov[1].buffer.length != strlen(sign)) errout("gss_wrap_iov(aead) sign-only buffer"); if (iov[2].buffer.length != strlen(wrap)) errout("gss_wrap_iov(aead) data buffer"); check_encrypted("gss_wrap_iov(aead) encryption", conf, iov[2].buffer.value, wrap); } /* Create AEAD tokens using gss_wrap_iov and ctx1, and make sure we can unwrap * them using ctx2 in all of the supported ways. */ static void test_aead(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2, int conf) { OM_uint32 major, minor; gss_iov_buffer_desc iov[5], stiov[3]; gss_qop_t qop; gss_buffer_desc input, assoc, output; const char *sign = "This data is only signed."; const char *wrap = "This data is wrapped in-place."; char data[1024], *fulltoken; size_t len; int oconf; ptrdiff_t offset; /* Wrap an AEAD token and unwrap it using the IOV array. */ wrap_aead(ctx1, sign, wrap, iov, data, conf); major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, iov, 5); check_gsserr("gss_unwrap_iov(aead1)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(aead1) conf/qop"); if (iov[1].buffer.value != sign || iov[1].buffer.length != strlen(sign)) errout("gss_unwrap_iov(aead1) sign-only buffer"); if (iov[2].buffer.length != strlen(wrap) || memcmp(iov[2].buffer.value, wrap, iov[2].buffer.length) != 0) errout("gss_unwrap_iov(aead1) decryption"); /* Wrap an AEAD token and unwrap it using gss_unwrap_aead. */ wrap_aead(ctx1, sign, wrap, iov, data, conf); concat_iov(iov, 5, &fulltoken, &len); input.value = fulltoken; input.length = len; assoc.value = (char *)sign; assoc.length = strlen(sign); major = gss_unwrap_aead(&minor, ctx2, &input, &assoc, &output, &oconf, &qop); check_gsserr("gss_unwrap_aead(aead2)", major, minor); if (output.length != strlen(wrap) || memcmp(output.value, wrap, output.length) != 0) errout("gss_unwrap_aead(aead2) decryption"); free(fulltoken); (void)gss_release_buffer(&minor, &output); /* Wrap an AEAD token and unwrap it using a stream buffer. */ wrap_aead(ctx1, sign, wrap, iov, data, conf); concat_iov(iov, 5, &fulltoken, &len); stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; stiov[0].buffer.value = fulltoken; stiov[0].buffer.length = len; stiov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; stiov[1].buffer.value = (char *)sign; stiov[1].buffer.length = strlen(sign); stiov[2].type = GSS_IOV_BUFFER_TYPE_DATA; major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 3); check_gsserr("gss_unwrap_iov(aead3)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(aead3) conf/qop"); if (stiov[2].buffer.length != strlen(wrap) || memcmp(stiov[2].buffer.value, wrap, strlen(wrap)) != 0) errout("gss_unwrap_iov(aead3) decryption"); offset = (char *)stiov[2].buffer.value - fulltoken; if (offset < 0 || (size_t)offset > len) errout("gss_unwrap_iov(aead3) offset"); free(fulltoken); (void)gss_release_iov_buffer(&minor, iov, 4); /* Wrap a token using gss_wrap_aead and unwrap it using a stream buffer * with allocation and copying. */ input.value = (char *)wrap; input.length = strlen(wrap); assoc.value = (char *)sign; assoc.length = strlen(sign); major = gss_wrap_aead(&minor, ctx1, conf, GSS_C_QOP_DEFAULT, &assoc, &input, &oconf, &output); check_gsserr("gss_wrap_aead(aead4)", major, minor); if (oconf != conf) errout("gss_wrap(aead4) conf"); stiov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; stiov[0].buffer = output; stiov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; stiov[1].buffer = assoc; stiov[2].type = GSS_IOV_BUFFER_TYPE_DATA | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, stiov, 3); check_gsserr("gss_unwrap_iov(aead4)", major, minor); if (!(GSS_IOV_BUFFER_FLAGS(stiov[2].type) & GSS_IOV_BUFFER_FLAG_ALLOCATED)) errout("gss_unwrap_iov(aead4) allocated"); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(aead4) conf/qop"); if (stiov[2].buffer.length != strlen(wrap) || memcmp(stiov[2].buffer.value, wrap, strlen(wrap)) != 0) errout("gss_unwrap_iov(aead4) decryption"); (void)gss_release_buffer(&minor, &output); (void)gss_release_iov_buffer(&minor, stiov, 3); } /* * Get a MIC for sign1, sign2, and sign3 using the caller-provided array iov, * which must have space for four elements, and the caller-provided buffer * data, which must be big enough for the MIC. If data is NULL, the library * will be asked to allocate the MIC buffer. The MIC will be located in * iov[3].buffer. */ static void mic(gss_ctx_id_t ctx, const char *sign1, const char *sign2, const char *sign3, gss_iov_buffer_desc *iov, char *data) { OM_uint32 minor, major; krb5_boolean allocated; /* Lay out iov array. */ iov[0].type = GSS_IOV_BUFFER_TYPE_DATA; iov[0].buffer.value = (char *)sign1; iov[0].buffer.length = strlen(sign1); iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[1].buffer.value = (char *)sign2; iov[1].buffer.length = strlen(sign2); iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[2].buffer.value = (char *)sign3; iov[2].buffer.length = strlen(sign3); iov[3].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN; if (data == NULL) { /* Ask the library to allocate the MIC buffer. */ iov[3].type |= GSS_IOV_BUFFER_FLAG_ALLOCATE; } else { /* Get the MIC length and use the caller-provided buffer. */ major = gss_get_mic_iov_length(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 4); check_gsserr("gss_get_mic_iov_length", major, minor); iov[3].buffer.value = data; } major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 4); check_gsserr("gss_get_mic_iov", major, minor); allocated = (GSS_IOV_BUFFER_FLAGS(iov[3].type) & GSS_IOV_BUFFER_FLAG_ALLOCATED) != 0; if (allocated != (data == NULL)) errout("gss_get_mic_iov allocated"); } static void test_mic(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2) { OM_uint32 major, minor; gss_iov_buffer_desc iov[4]; gss_qop_t qop; gss_buffer_desc concatbuf, micbuf; const char *sign1 = "Data and sign-only "; const char *sign2 = "buffers are treated "; const char *sign3 = "equally by gss_get_mic_iov"; char concat[1024], data[1024]; (void)snprintf(concat, sizeof(concat), "%s%s%s", sign1, sign2, sign3); concatbuf.value = concat; concatbuf.length = strlen(concat); /* MIC with a caller-provided buffer and verify with the IOV array. */ mic(ctx1, sign1, sign2, sign3, iov, data); major = gss_verify_mic_iov(&minor, ctx2, &qop, iov, 4); check_gsserr("gss_verify_mic_iov(mic1)", major, minor); if (qop != GSS_C_QOP_DEFAULT) errout("gss_verify_mic_iov(mic1) qop"); /* MIC with an allocated buffer and verify with gss_verify_mic. */ mic(ctx1, sign1, sign2, sign3, iov, NULL); major = gss_verify_mic(&minor, ctx2, &concatbuf, &iov[3].buffer, &qop); check_gsserr("gss_verify_mic(mic2)", major, minor); if (qop != GSS_C_QOP_DEFAULT) errout("gss_verify_mic(mic2) qop"); (void)gss_release_iov_buffer(&minor, iov, 4); /* MIC with gss_c_get_mic and verify using the IOV array (which is still * mostly set up from the last call to mic(). */ major = gss_get_mic(&minor, ctx1, GSS_C_QOP_DEFAULT, &concatbuf, &micbuf); check_gsserr("gss_get_mic(mic3)", major, minor); iov[3].buffer = micbuf; major = gss_verify_mic_iov(&minor, ctx2, &qop, iov, 4); check_gsserr("gss_verify_mic_iov(mic3)", major, minor); if (qop != GSS_C_QOP_DEFAULT) errout("gss_verify_mic_iov(mic3) qop"); (void)gss_release_buffer(&minor, &micbuf); } /* Create a DCE-style token and make sure we can unwrap it. */ static void test_dce(gss_ctx_id_t ctx1, gss_ctx_id_t ctx2, int conf) { OM_uint32 major, minor; gss_iov_buffer_desc iov[4]; gss_qop_t qop; const char *sign1 = "First data to be signed"; const char *sign2 = "Second data to be signed"; const char *wrap = "This data must align to 16 bytes"; int oconf; char data[1024]; /* Wrap a SIGN_ONLY_1 | DATA | SIGN_ONLY_2 | HEADER token. */ memcpy(data, wrap, strlen(wrap) + 1); iov[0].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[0].buffer.value = (char *)sign1; iov[0].buffer.length = strlen(sign1); iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = data; iov[1].buffer.length = strlen(wrap); iov[2].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY; iov[2].buffer.value = (char *)sign2; iov[2].buffer.length = strlen(sign2); iov[3].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE; major = gss_wrap_iov(&minor, ctx1, conf, GSS_C_QOP_DEFAULT, &oconf, iov, 4); check_gsserr("gss_wrap_iov(dce)", major, minor); if (oconf != conf) errout("gss_wrap_iov(dce) conf"); if (iov[0].buffer.value != sign1 || iov[0].buffer.length != strlen(sign1)) errout("gss_wrap_iov(dce) sign1 buffer"); if (iov[1].buffer.value != data || iov[1].buffer.length != strlen(wrap)) errout("gss_wrap_iov(dce) data buffer"); if (iov[2].buffer.value != sign2 || iov[2].buffer.length != strlen(sign2)) errout("gss_wrap_iov(dce) sign2 buffer"); check_encrypted("gss_wrap_iov(dce) encryption", conf, data, wrap); /* Make sure we can unwrap it. */ major = gss_unwrap_iov(&minor, ctx2, &oconf, &qop, iov, 4); check_gsserr("gss_unwrap_iov(std1)", major, minor); if (oconf != conf || qop != GSS_C_QOP_DEFAULT) errout("gss_unwrap_iov(std1) conf/qop"); if (iov[0].buffer.value != sign1 || iov[0].buffer.length != strlen(sign1)) errout("gss_unwrap_iov(dce) sign1 buffer"); if (iov[1].buffer.value != data || iov[1].buffer.length != strlen(wrap)) errout("gss_unwrap_iov(dce) data buffer"); if (iov[2].buffer.value != sign2 || iov[2].buffer.length != strlen(sign2)) errout("gss_unwrap_iov(dce) sign2 buffer"); if (memcmp(data, wrap, iov[1].buffer.length) != 0) errout("gss_unwrap_iov(dce) decryption"); (void)gss_release_iov_buffer(&minor, iov, 4); } int main(int argc, char *argv[]) { OM_uint32 minor, flags; gss_OID mech = &mech_krb5; gss_name_t tname; gss_ctx_id_t ictx, actx; /* Parse arguments. */ argv++; if (*argv != NULL && strcmp(*argv, "-s") == 0) { mech = &mech_spnego; argv++; } if (*argv == NULL || *(argv + 1) != NULL) errout("Usage: t_iov [-s] targetname"); tname = import_name(*argv); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG; establish_contexts(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, NULL, NULL, NULL); /* Test standard token wrapping and unwrapping in both directions, with and * without confidentiality. */ test_standard_wrap(ictx, actx, 0); test_standard_wrap(ictx, actx, 1); test_standard_wrap(actx, ictx, 0); test_standard_wrap(actx, ictx, 1); /* Test AEAD wrapping. */ test_aead(ictx, actx, 0); test_aead(ictx, actx, 1); test_aead(actx, ictx, 0); test_aead(actx, ictx, 1); /* Test MIC tokens. */ test_mic(ictx, actx); test_mic(actx, ictx); /* Test DCE wrapping with DCE-style contexts. */ (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_DCE_STYLE; establish_contexts(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, NULL, NULL, NULL); test_dce(ictx, actx, 0); test_dce(ictx, actx, 1); test_dce(actx, ictx, 0); test_dce(actx, ictx, 1); (void)gss_release_name(&minor, &tname); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.22.1/src/tests/gssapi/t_export_name.c0000664000175000017500000001010115051422640020561 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_export_name.c - Test program for gss_export_name behavior */ /* * Copyright 2012 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test program for gss_export_name, intended to be run from a Python test * script. Imports a name, canonicalizes it to a mech, exports it, * re-imports/exports it to compare results, and then prints the hex form of * the exported name followed by a newline. * * Usage: ./t_export_name [-k|-s] user:username|krb5:princ|host:service@host * * The name is imported as a username, krb5 principal, or hostbased name. * By default or with -k, the name is canonicalized to the krb5 mech; -s * indicates SPNEGO instead. */ #include #include #include #include "common.h" static void usage(void) { fprintf(stderr, "Usage: t_export_name [-k|-s] name\n"); exit(1); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_OID mech = (gss_OID)gss_mech_krb5; gss_name_t name, mechname, impname; gss_buffer_desc buf, buf2; krb5_boolean use_composite = FALSE; gss_OID ntype; const char *name_arg; char opt; /* Parse arguments. */ while (argc > 1 && argv[1][0] == '-') { opt = argv[1][1]; argc--, argv++; if (opt == 'k') mech = &mech_krb5; else if (opt == 's') mech = &mech_spnego; else if (opt == 'c') use_composite = TRUE; else usage(); } if (argc != 2) usage(); name_arg = argv[1]; /* Import the name. */ name = import_name(name_arg); /* Canonicalize and export the name. */ major = gss_canonicalize_name(&minor, name, mech, &mechname); check_gsserr("gss_canonicalize_name", major, minor); if (use_composite) major = gss_export_name_composite(&minor, mechname, &buf); else major = gss_export_name(&minor, mechname, &buf); check_gsserr("gss_export_name", major, minor); /* Import and re-export the name, and compare the results. */ ntype = use_composite ? GSS_C_NT_COMPOSITE_EXPORT : GSS_C_NT_EXPORT_NAME; major = gss_import_name(&minor, &buf, ntype, &impname); check_gsserr("gss_import_name", major, minor); if (use_composite) major = gss_export_name_composite(&minor, impname, &buf2); else major = gss_export_name(&minor, impname, &buf2); check_gsserr("gss_export_name", major, minor); if (buf.length != buf2.length || memcmp(buf.value, buf2.value, buf.length) != 0) { fprintf(stderr, "Mismatched results:\n"); print_hex(stderr, &buf); print_hex(stderr, &buf2); return 1; } print_hex(stdout, &buf); (void)gss_release_name(&minor, &name); (void)gss_release_name(&minor, &mechname); (void)gss_release_name(&minor, &impname); (void)gss_release_buffer(&minor, &buf); (void)gss_release_buffer(&minor, &buf2); return 0; } krb5-1.22.1/src/tests/gssapi/t_s4u.c0000664000175000017500000003107515051422640016770 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test program for protocol transition (S4U2Self) and constrained delegation * (S4U2Proxy) * * Note: because of name canonicalization, the following tips may help * when configuring with Active Directory: * * - Create a computer account FOO$ * - Set the UPN to host/foo.domain (no suffix); this is necessary to * be able to send an AS-REQ as this principal, otherwise you would * need to use the canonical name (FOO$), which will cause principal * comparison errors in gss_accept_sec_context(). * - Add a SPN of host/foo.domain * - Configure the computer account to support constrained delegation with * protocol transition (Trust this computer for delegation to specified * services only / Use any authentication protocol) * - Add host/foo.domain to the keytab (possibly easiest to do this * with ktadd) * * For S4U2Proxy to work the TGT must be forwardable too. * * Usage eg: * * kinit -k -t test.keytab -f 'host/test.win.mit.edu@WIN.MIT.EDU' * ./t_s4u p:delegtest@WIN.MIT.EDU p:HOST/WIN-EQ7E4AA2WR8.win.mit.edu@WIN.MIT.EDU test.keytab */ #include #include #include #include "common.h" static int use_spnego = 0; static void test_greet_authz_data(gss_name_t *name) { OM_uint32 major, minor; gss_buffer_desc attr; gss_buffer_desc value; gss_name_t canon; major = gss_canonicalize_name(&minor, *name, &mech_krb5, &canon); check_gsserr("gss_canonicalize_name", major, minor); attr.value = "greet:greeting"; attr.length = strlen((char *)attr.value); value.value = "Hello, acceptor world!"; value.length = strlen((char *)value.value); major = gss_set_name_attribute(&minor, canon, 1, &attr, &value); if (major == GSS_S_UNAVAILABLE) { (void)gss_release_name(&minor, &canon); return; } check_gsserr("gss_set_name_attribute", major, minor); gss_release_name(&minor, name); *name = canon; } static void init_accept_sec_context(gss_cred_id_t claimant_cred_handle, gss_cred_id_t verifier_cred_handle, gss_cred_id_t *deleg_cred_handle) { OM_uint32 major, minor, flags; gss_name_t source_name = GSS_C_NO_NAME, target_name = GSS_C_NO_NAME; gss_ctx_id_t initiator_context, acceptor_context; gss_OID mech = GSS_C_NO_OID; *deleg_cred_handle = GSS_C_NO_CREDENTIAL; major = gss_inquire_cred(&minor, verifier_cred_handle, &target_name, NULL, NULL, NULL); check_gsserr("gss_inquire_cred", major, minor); display_canon_name("Target name", target_name, &mech_krb5); mech = use_spnego ? &mech_spnego : &mech_krb5; display_oid("Target mech", mech); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(mech, claimant_cred_handle, verifier_cred_handle, target_name, flags, &initiator_context, &acceptor_context, &source_name, &mech, deleg_cred_handle); display_canon_name("Source name", source_name, &mech_krb5); display_oid("Source mech", mech); enumerate_attributes(source_name, 1); (void)gss_release_name(&minor, &source_name); (void)gss_release_name(&minor, &target_name); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); } static void check_ticket_count(gss_cred_id_t cred, int expected) { krb5_error_code ret; krb5_context context = NULL; krb5_creds kcred; krb5_cc_cursor cur; krb5_ccache ccache; int count = 0; gss_key_value_set_desc store; gss_key_value_element_desc elem; OM_uint32 major, minor; const char *ccname = "MEMORY:count"; store.count = 1; store.elements = &elem; elem.key = "ccache"; elem.value = ccname; major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE, &mech_krb5, 1, 0, &store, NULL, NULL); check_gsserr("gss_store_cred_into", major, minor); ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); ret = krb5_cc_resolve(context, ccname, &ccache); check_k5err(context, "krb5_cc_resolve", ret); ret = krb5_cc_start_seq_get(context, ccache, &cur); check_k5err(context, "krb5_cc_start_seq_get", ret); while (!krb5_cc_next_cred(context, ccache, &cur, &kcred)) { if (!krb5_is_config_principal(context, kcred.server)) count++; krb5_free_cred_contents(context, &kcred); } ret = krb5_cc_end_seq_get(context, ccache, &cur); check_k5err(context, "krb5_cc_end_seq_get", ret); if (expected != count) { printf("Expected %d tickets but got %d\n", expected, count); exit(1); } krb5_cc_destroy(context, ccache); krb5_free_context(context); } static void constrained_delegate(gss_OID_set desired_mechs, gss_name_t target, gss_cred_id_t delegated_cred_handle, gss_cred_id_t verifier_cred_handle) { OM_uint32 major, minor; gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT; gss_name_t cred_name = GSS_C_NO_NAME; OM_uint32 time_rec, lifetime; gss_cred_usage_t usage; gss_buffer_desc token; gss_OID_set mechs; printf("Constrained delegation tests follow\n"); printf("-----------------------------------\n\n"); if (gss_inquire_cred(&minor, verifier_cred_handle, &cred_name, &lifetime, &usage, NULL) == GSS_S_COMPLETE) { display_canon_name("Proxy name", cred_name, &mech_krb5); (void)gss_release_name(&minor, &cred_name); } display_canon_name("Target name", target, &mech_krb5); if (gss_inquire_cred(&minor, delegated_cred_handle, &cred_name, &lifetime, &usage, &mechs) == GSS_S_COMPLETE) { display_canon_name("Delegated name", cred_name, &mech_krb5); display_oid("Delegated mech", &mechs->elements[0]); (void)gss_release_name(&minor, &cred_name); } printf("\n"); major = gss_init_sec_context(&minor, delegated_cred_handle, &initiator_context, target, mechs ? &mechs->elements[0] : &mech_krb5, GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, NULL, &token, NULL, &time_rec); check_gsserr("gss_init_sec_context", major, minor); (void)gss_release_buffer(&minor, &token); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); /* Ensure a second call does not acquire new ticket. */ major = gss_init_sec_context(&minor, delegated_cred_handle, &initiator_context, target, mechs ? &mechs->elements[0] : &mech_krb5, GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, NULL, &token, NULL, &time_rec); check_gsserr("gss_init_sec_context", major, minor); (void)gss_release_buffer(&minor, &token); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_release_oid_set(&minor, &mechs); /* We expect three tickets: our TGT, the evidence ticket, and the ticket to * the target service. */ check_ticket_count(delegated_cred_handle, 3); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t impersonator_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t user_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t delegated_cred_handle = GSS_C_NO_CREDENTIAL; gss_name_t user = GSS_C_NO_NAME, target = GSS_C_NO_NAME; gss_OID_set mechs; gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET; if (argc < 2 || argc > 5) { fprintf(stderr, "Usage: %s [--spnego] [user] " "[proxy-target] [keytab]\n", argv[0]); fprintf(stderr, " proxy-target and keytab are optional\n"); exit(1); } if (strcmp(argv[1], "--spnego") == 0) { use_spnego++; argc--; argv++; } user = import_name(argv[1]); if (argc > 2 && strcmp(argv[2], "-")) target = import_name(argv[2]); if (argc > 3) { major = krb5_gss_register_acceptor_identity(argv[3]); check_gsserr("krb5_gss_register_acceptor_identity", major, 0); } /* Get default cred. */ mechs = use_spnego ? &mechset_spnego : &mechset_krb5; major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, &impersonator_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); printf("Protocol transition tests follow\n"); printf("-----------------------------------\n\n"); test_greet_authz_data(&user); /* Get S4U2Self cred. */ major = gss_acquire_cred_impersonate_name(&minor, impersonator_cred_handle, user, GSS_C_INDEFINITE, mechs, GSS_C_INITIATE, &user_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred_impersonate_name", major, minor); init_accept_sec_context(user_cred_handle, impersonator_cred_handle, &delegated_cred_handle); printf("\n"); if (target != GSS_C_NO_NAME && delegated_cred_handle != GSS_C_NO_CREDENTIAL) { constrained_delegate(mechs, target, delegated_cred_handle, impersonator_cred_handle); } else if (target != GSS_C_NO_NAME) { fprintf(stderr, "Warning: no delegated cred handle returned\n\n"); fprintf(stderr, "Verify:\n\n"); fprintf(stderr, " - The TGT for the impersonating service is " "forwardable\n"); fprintf(stderr, " - The T2A4D flag set on the impersonating service's " "UAC\n"); fprintf(stderr, " - The user is not marked sensitive and cannot be " "delegated\n"); fprintf(stderr, "\n"); } if (delegated_cred_handle != GSS_C_NO_CREDENTIAL) { /* Inquire impersonator status. */ major = gss_inquire_cred_by_oid(&minor, user_cred_handle, GSS_KRB5_GET_CRED_IMPERSONATOR, &bufset); check_gsserr("gss_inquire_cred_by_oid", major, minor); if (bufset->count == 0) errout("gss_inquire_cred_by_oid(user) returned NO impersonator"); (void)gss_release_buffer_set(&minor, &bufset); major = gss_inquire_cred_by_oid(&minor, impersonator_cred_handle, GSS_KRB5_GET_CRED_IMPERSONATOR, &bufset); check_gsserr("gss_inquire_cred_by_oid", major, minor); if (bufset->count != 0) errout("gss_inquire_cred_by_oid(svc) returned an impersonator"); (void)gss_release_buffer_set(&minor, &bufset); } (void)gss_release_name(&minor, &user); (void)gss_release_name(&minor, &target); (void)gss_release_cred(&minor, &delegated_cred_handle); (void)gss_release_cred(&minor, &impersonator_cred_handle); (void)gss_release_cred(&minor, &user_cred_handle); return 0; } krb5-1.22.1/src/tests/gssapi/deps0000664000175000017500000003226115051422640016442 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)ccinit.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ccinit.c $(OUTPRE)ccrefresh.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ccrefresh.c $(OUTPRE)common.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.c common.h $(OUTPRE)reload.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ reload.c $(OUTPRE)t_accname.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_accname.c $(OUTPRE)t_add_cred.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_add_cred.c $(OUTPRE)t_bindings.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_bindings.c $(OUTPRE)t_ccselect.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_ccselect.c $(OUTPRE)t_ciflags.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_ciflags.c $(OUTPRE)t_context.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_context.c $(OUTPRE)t_credstore.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_credstore.c $(OUTPRE)t_enctypes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../lib/gssapi/generic/gssapi_ext.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ common.h t_enctypes.c $(OUTPRE)t_err.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_err.c $(OUTPRE)t_export_cred.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_export_cred.c $(OUTPRE)t_export_name.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_export_name.c $(OUTPRE)t_gssexts.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_gssexts.c $(OUTPRE)t_iakerb.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_iakerb.c $(OUTPRE)t_imp_cred.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ common.h t_imp_cred.c $(OUTPRE)t_imp_name.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_imp_name.c $(OUTPRE)t_invalid.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.h \ $(BUILDTOP)/lib/gssapi/krb5/gssapi_err_krb5.h $(COM_ERR_DEPS) \ $(srcdir)/../../lib/gssapi/generic/gssapiP_generic.h \ $(srcdir)/../../lib/gssapi/generic/gssapi_ext.h $(srcdir)/../../lib/gssapi/generic/gssapi_generic.h \ $(srcdir)/../../lib/gssapi/krb5/gssapiP_krb5.h $(srcdir)/../../lib/gssapi/krb5/gssapi_krb5.h \ $(srcdir)/../../lib/gssapi/mechglue/mechglue.h $(srcdir)/../../lib/gssapi/mechglue/mglueP.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-input.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h common.h t_invalid.c $(OUTPRE)t_inq_cred.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_inq_cred.c $(OUTPRE)t_inq_ctx.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_inq_ctx.c $(OUTPRE)t_inq_mechs_name.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_inq_mechs_name.c $(OUTPRE)t_iov.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_iov.c $(OUTPRE)t_lifetime.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_lifetime.c $(OUTPRE)t_namingexts.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_namingexts.c $(OUTPRE)t_oid.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_oid.c $(OUTPRE)t_pcontok.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ common.h t_pcontok.c $(OUTPRE)t_prf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_alloc.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(BUILDTOP)/lib/gssapi/generic/gssapi_err_generic.h \ $(BUILDTOP)/lib/gssapi/krb5/gssapi_err_krb5.h $(COM_ERR_DEPS) \ $(srcdir)/../../lib/gssapi/generic/gssapiP_generic.h \ $(srcdir)/../../lib/gssapi/generic/gssapi_ext.h $(srcdir)/../../lib/gssapi/generic/gssapi_generic.h \ $(srcdir)/../../lib/gssapi/krb5/gssapiP_krb5.h $(srcdir)/../../lib/gssapi/krb5/gssapi_krb5.h \ $(srcdir)/../../lib/gssapi/mechglue/mechglue.h $(srcdir)/../../lib/gssapi/mechglue/mglueP.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hex.h \ $(top_srcdir)/include/k5-input.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ common.h t_prf.c $(OUTPRE)t_s4u.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_s4u.c $(OUTPRE)t_s4u2proxy_krb5.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_s4u2proxy_krb5.c $(OUTPRE)t_saslname.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_saslname.c $(OUTPRE)t_spnego.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_spnego.c $(OUTPRE)t_srcattrs.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \ common.h t_srcattrs.c $(OUTPRE)t_store_cred.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/krb5.h \ common.h t_store_cred.c krb5-1.22.1/src/tests/gssapi/t_gssapi.py0000775000175000017500000002665515051422640017764 0ustar ghudsonghudsonfrom k5test import * # Test krb5 negotiation under SPNEGO for all enctype configurations. Also # test IOV wrap/unwrap with and without SPNEGO. for realm in multipass_realms(): realm.run(['./t_spnego','p:' + realm.host_princ, realm.keytab]) realm.run(['./t_iov', 'p:' + realm.host_princ]) realm.run(['./t_iov', '-s', 'p:' + realm.host_princ]) realm.run(['./t_pcontok', 'p:' + realm.host_princ]) realm = K5Realm() realm.run([kadminl, 'modprinc', '+preauth', realm.user_princ]) remove_default = {'libdefaults': {'default_realm': None}} change_default = {'libdefaults': {'default_realm': 'WRONG.REALM'}} no_default = realm.special_env('no_default', False, krb5_conf=remove_default) wrong_default = realm.special_env('wrong_default', False, krb5_conf=change_default) # Test IAKERB with credentials. realm.run(['./t_iakerb', 'p:' + realm.user_princ, '-', 'h:host@' + hostname, 'h:host']) # Test IAKERB getting initial credentials. realm.run(['./t_iakerb', 'p:' + realm.user_princ, password('user'), 'h:host@' + hostname, 'h:host']) # Test IAKERB realm discovery. realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname, 'h:host']) # Test IAKERB realm discovery without default_realm set. We get an # error because the acceptor does not know the realm. realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname, 'h:host'], env=no_default, expected_code=1, expected_msg='The IAKERB proxy could not determine its realm') # Test again, using a GSS_KRB5_NT_PRINCIPAL_NAME acceptor name so that # gss_accept_sec_context() knows the realm. realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname, 'p:' + realm.host_princ], env=no_default) # Test IAKERB realm discovery with a non-useful default_realm set. realm.run(['./t_iakerb', 'e:user', password('user'), 'h:host@' + hostname, 'p:' + realm.host_princ], env=wrong_default) # Test gss_add_cred(). realm.run(['./t_add_cred']) ### Test acceptor name behavior. # Create some host-based principals and put most of them into the # keytab. Rename one principal so that the keytab name matches the # key but not the client name. realm.run([kadminl, 'addprinc', '-randkey', 'service1/abraham']) realm.run([kadminl, 'addprinc', '-randkey', 'service1/barack']) realm.run([kadminl, 'addprinc', '-randkey', 'service2/calvin']) realm.run([kadminl, 'addprinc', '-randkey', 'service2/dwight']) realm.run([kadminl, 'addprinc', '-randkey', 'host/-nomatch-']) realm.run([kadminl, 'addprinc', '-randkey', 'http/localhost']) realm.run([kadminl, 'xst', 'service1/abraham']) realm.run([kadminl, 'xst', 'service1/barack']) realm.run([kadminl, 'xst', 'service2/calvin']) realm.run([kadminl, 'xst', 'http/localhost']) realm.run([kadminl, 'renprinc', 'service1/abraham', 'service1/andrew']) # Test with no default realm and no dots in the server name. realm.run(['./t_accname', 'h:http@localhost'], expected_msg='http/localhost') realm.run(['./t_accname', 'h:http@localhost'], expected_msg='http/localhost', env=no_default) # Test with no acceptor name, including client/keytab principal # mismatch (non-fatal) and missing keytab entry (fatal). realm.run(['./t_accname', 'p:service1/andrew'], expected_msg='service1/abraham') realm.run(['./t_accname', 'p:service1/barack'], expected_msg='service1/barack') realm.run(['./t_accname', 'p:service2/calvin'], expected_msg='service2/calvin') realm.run(['./t_accname', 'p:service2/dwight'], expected_code=1, expected_msg=' not found in keytab') # Test with acceptor name containing service only, including # client/keytab hostname mismatch (non-fatal) and service name # mismatch (fatal). realm.run(['./t_accname', 'p:service1/andrew', 'h:service1'], expected_msg='service1/abraham') realm.run(['./t_accname', 'p:service1/andrew', 'h:service2'], expected_code=1, expected_msg=' not found in keytab') realm.run(['./t_accname', 'p:service2/calvin', 'h:service2'], expected_msg='service2/calvin') realm.run(['./t_accname', 'p:service2/calvin', 'h:service1'], expected_code=1, expected_msg=' found in keytab but does not match server principal') # Regression test for #8892 (trailing @ in name). realm.run(['./t_accname', 'p:service1/andrew', 'h:service1@'], expected_msg='service1/abraham') # Test with acceptor name containing service and host. Use the # client's un-canonicalized hostname as acceptor input to mirror what # many servers do. realm.run(['./t_accname', 'p:' + realm.host_princ, 'h:host@%s' % socket.gethostname()], expected_msg=realm.host_princ) realm.run(['./t_accname', 'p:host/-nomatch-', 'h:host@%s' % socket.gethostname()], expected_code=1, expected_msg=' not found in keytab') # If possible, test with an acceptor name requiring fallback to match # against a keytab entry. canonname = canonicalize_hostname(hostname) if canonname != hostname: os.rename(realm.keytab, realm.keytab + '.save') canonprinc = 'host/' + canonname realm.run([kadminl, 'addprinc', '-randkey', canonprinc]) realm.extract_keytab(canonprinc, realm.keytab) # Use the canonical name for the initiator's target name, since # host/hostname exists in the KDB (but not the keytab). realm.run(['./t_accname', 'h:host@' + canonname, 'h:host@' + hostname]) os.rename(realm.keytab + '.save', realm.keytab) else: skipped('GSS acceptor name fallback test', '%s does not canonicalize to a different name' % hostname) # Test krb5_gss_import_cred. realm.run(['./t_imp_cred', 'p:service1/barack']) realm.run(['./t_imp_cred', 'p:service1/barack', 'service1/barack']) realm.run(['./t_imp_cred', 'p:service1/andrew', 'service1/abraham']) realm.run(['./t_imp_cred', 'p:service2/dwight'], expected_code=1, expected_msg=' not found in keytab') # Verify that we can't acquire acceptor creds without a keytab. os.remove(realm.keytab) out = realm.run(['./t_accname', 'p:abc'], expected_code=1) if ('gss_acquire_cred: Keytab' not in out or 'nonexistent or empty' not in out): fail('Expected error message not seen for nonexistent keytab') realm.stop() # Re-run the last acceptor name test with ignore_acceptor_hostname set # and the principal for the mismatching hostname in the keytab. ignore_conf = {'libdefaults': {'ignore_acceptor_hostname': 'true'}} realm = K5Realm(krb5_conf=ignore_conf) realm.run([kadminl, 'addprinc', '-randkey', 'host/-nomatch-']) realm.run([kadminl, 'xst', 'host/-nomatch-']) realm.run(['./t_accname', 'p:host/-nomatch-', 'h:host@%s' % socket.gethostname()], expected_msg='host/-nomatch-') realm.stop() # Make sure a GSSAPI acceptor can handle cross-realm tickets with a # transited field. (Regression test for #7639.) r1, r2, r3 = cross_realms(3, xtgts=((0,1), (1,2)), create_user=False, create_host=False, args=[{'realm': 'A.X', 'create_user': True}, {'realm': 'X'}, {'realm': 'B.X', 'create_host': True}]) os.rename(r3.keytab, r1.keytab) r1.run(['./t_accname', 'p:' + r3.host_princ, 'h:host']) r1.stop() r2.stop() r3.stop() ### Test gss_inquire_cred behavior. realm = K5Realm() # Test deferred resolution of the default ccache for initiator creds. realm.run(['./t_inq_cred'], expected_msg=realm.user_princ) realm.run(['./t_inq_cred', '-k'], expected_msg=realm.user_princ) realm.run(['./t_inq_cred', '-s'], expected_msg=realm.user_princ) # Test picking a name from the keytab for acceptor creds. realm.run(['./t_inq_cred', '-a'], expected_msg=realm.host_princ) realm.run(['./t_inq_cred', '-k', '-a'], expected_msg=realm.host_princ) realm.run(['./t_inq_cred', '-s', '-a'], expected_msg=realm.host_princ) # Test client keytab initiation (non-deferred) with a specified name. realm.extract_keytab(realm.user_princ, realm.client_keytab) os.remove(realm.ccache) realm.run(['./t_inq_cred', '-k'], expected_msg=realm.user_princ) # Test deferred client keytab initiation and GSS_C_BOTH cred usage. os.remove(realm.client_keytab) os.remove(realm.ccache) shutil.copyfile(realm.keytab, realm.client_keytab) realm.run(['./t_inq_cred', '-k', '-b'], expected_msg=realm.host_princ) # Test gss_export_name behavior. realm.run(['./t_export_name', 'u:x'], expected_msg=\ '0401000B06092A864886F7120102020000000D78404B5242544553542E434F4D\n') realm.run(['./t_export_name', '-s', 'u:xyz'], expected_msg='0401000806062B06010505020000000378797A\n') realm.run(['./t_export_name', 'p:a@b'], expected_msg='0401000B06092A864886F71201020200000003614062\n') realm.run(['./t_export_name', '-s', 'p:a@b'], expected_msg='0401000806062B060105050200000003614062\n') # Test that composite-export tokens can be imported. realm.run(['./t_export_name', '-c', 'p:a@b'], expected_msg= '0402000B06092A864886F7120102020000000361406200000000\n') # Test gss_inquire_mechs_for_name behavior. krb5_mech = '{ 1 2 840 113554 1 2 2 }' spnego_mech = '{ 1 3 6 1 5 5 2 }' out = realm.run(['./t_inq_mechs_name', 'p:a@b']) if krb5_mech not in out: fail('t_inq_mechs_name (principal)') out = realm.run(['./t_inq_mechs_name', 'u:x']) if krb5_mech not in out or spnego_mech not in out: fail('t_inq_mecs_name (user)') out = realm.run(['./t_inq_mechs_name', 'h:host']) if krb5_mech not in out or spnego_mech not in out: fail('t_inq_mecs_name (hostbased)') # Test that accept_sec_context can produce an error token and # init_sec_context can interpret it. realm.run(['./t_err', 'p:' + realm.host_princ]) realm.run(['./t_err', '--spnego', 'p:' + realm.host_princ]) # Test the GSS_KRB5_CRED_NO_CI_FLAGS_X cred option. realm.run(['./t_ciflags', 'p:' + realm.host_princ]) # Test that inquire_context works properly, even on incomplete # contexts. realm.run(['./t_inq_ctx', 'user', password('user'), 'p:%s' % realm.host_princ]) if runenv.sizeof_time_t <= 4: skip_rest('y2038 GSSAPI tests', 'platform has 32-bit time_t') # Test lifetime results, using a realm with a large maximum lifetime # so that we can test ticket end dates after y2038. realm.stop() conf = {'realms': {'$realm': {'max_life': '9000d'}}} realm = K5Realm(kdc_conf=conf, get_creds=False) # Check a lifetime string result against an expected number value (or None). # Allow some variance due to time elapsed during the tests. def check_lifetime(msg, val, expected): if expected is None and val != 'indefinite': fail('%s: expected indefinite, got %s' % (msg, val)) if expected is not None and val == 'indefinite': fail('%s: expected %d, got indefinite' % (msg, expected)) if expected is not None and abs(int(val) - expected) > 100: fail('%s: expected %d, got %s' % (msg, expected, val)) realm.kinit(realm.user_princ, password('user'), flags=['-l', '8500d']) out = realm.run(['./t_lifetime', 'p:' + realm.host_princ, str(8000 * 86400)]) ln = out.split('\n') check_lifetime('icred gss_acquire_cred', ln[0], 8500 * 86400) check_lifetime('icred gss_inquire_cred', ln[1], 8500 * 86400) check_lifetime('acred gss_acquire_cred', ln[2], None) check_lifetime('acred gss_inquire_cred', ln[3], None) check_lifetime('ictx gss_init_sec_context', ln[4], 8000 * 86400) check_lifetime('ictx gss_inquire_context', ln[5], 8000 * 86400) check_lifetime('ictx gss_context_time', ln[6], 8000 * 86400) check_lifetime('actx gss_accept_sec_context', ln[7], 8000 * 86400 + 300) check_lifetime('actx gss_inquire_context', ln[8], 8000 * 86400 + 300) check_lifetime('actx gss_context_time', ln[9], 8000 * 86400 + 300) success('GSSAPI tests') krb5-1.22.1/src/tests/gssapi/t_inq_ctx.c0000664000175000017500000002223015051422640017713 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2015 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include #include "common.h" /* * Test program for inquiring about a security context, intended to be run from * a Python test script. Partially establishes a context to test inquiring * about an incomplete context, and then establishes full contexts and inquires * them. Exits with status 0 if all operations are successful, or 1 if not. * * Usage: ./t_inq_ctx target_name */ static void check_inq_context(gss_ctx_id_t context, int incomplete, gss_OID expected_mech, OM_uint32 expected_flags, int expected_locally_init) { OM_uint32 major, minor; gss_name_t out_init_name, out_accept_name; OM_uint32 out_lifetime; gss_OID out_mech_type; OM_uint32 out_flags; int out_locally_init; int out_open; major = gss_inquire_context(&minor, context, &out_init_name, &out_accept_name, &out_lifetime, &out_mech_type, &out_flags, &out_locally_init, &out_open); check_gsserr("gss_inquire_context", major, minor); assert(gss_oid_equal(out_mech_type, expected_mech)); assert(out_flags == expected_flags); assert(out_locally_init == expected_locally_init); if (incomplete) { assert(!out_open); assert(out_lifetime == 0); assert(out_init_name == GSS_C_NO_NAME); assert(out_accept_name == GSS_C_NO_NAME); } else { assert(out_open); assert(out_lifetime > 0); assert(out_init_name != GSS_C_NO_NAME); assert(out_accept_name != GSS_C_NO_NAME); } (void)gss_release_name(&minor, &out_accept_name); (void)gss_release_name(&minor, &out_init_name); } /* Call gss_init_sec_context() once to create an initiator context (which will * be partial if flags includes GSS_C_MUTUAL_FLAG and the mech is krb5). */ static void start_init_context(gss_OID mech, gss_cred_id_t cred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ctx) { OM_uint32 major, minor; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER; *ctx = GSS_C_NO_CONTEXT; major = gss_init_sec_context(&minor, cred, ctx, tname, mech, flags, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context", major, minor); (void)gss_release_buffer(&minor, &itok); } /* Call gss_init_sec_context() and gss_accept_sec_context() once to create an * acceptor context. */ static void start_accept_context(gss_OID mech, gss_cred_id_t icred, gss_cred_id_t acred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ctx) { OM_uint32 major, minor; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER; major = gss_init_sec_context(&minor, icred, &ictx, tname, mech, flags, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context", major, minor); *ctx = GSS_C_NO_CONTEXT; major = gss_accept_sec_context(&minor, ctx, acred, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context", major, minor); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &ictx, NULL); } static void partial_iakerb_acceptor(const char *username, const char *password, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ctx) { OM_uint32 major, minor; gss_name_t name; gss_buffer_desc ubuf, pwbuf; gss_OID_set_desc mechlist; gss_cred_id_t icred, acred; mechlist.count = 1; mechlist.elements = &mech_iakerb; /* Import the username. */ ubuf.value = (void *)username; ubuf.length = strlen(username); major = gss_import_name(&minor, &ubuf, GSS_C_NT_USER_NAME, &name); check_gsserr("gss_import_name", major, minor); /* Create an IAKERB initiator cred with the username and password. */ pwbuf.value = (void *)password; pwbuf.length = strlen(password); major = gss_acquire_cred_with_password(&minor, name, &pwbuf, 0, &mechlist, GSS_C_INITIATE, &icred, NULL, NULL); check_gsserr("gss_acquire_cred_with_password", major, minor); /* Create an acceptor cred with support for IAKERB. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechlist, GSS_C_ACCEPT, &acred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); /* Begin context establishment to get a partial acceptor context. */ start_accept_context(&mech_iakerb, icred, acred, tname, flags, ctx); (void)gss_release_name(&minor, &name); (void)gss_release_cred(&minor, &icred); (void)gss_release_cred(&minor, &acred); } /* Create a partially established SPNEGO acceptor. */ static void partial_spnego_acceptor(gss_name_t tname, gss_ctx_id_t *ctx) { OM_uint32 major, minor; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok; /* * We could construct a fixed SPNEGO initiator token which forces a * renegotiation, but a simpler approach is to pass an empty token to * gss_accept_sec_context(), taking advantage of our compatibility support * for SPNEGO NegHints. */ *ctx = GSS_C_NO_CONTEXT; major = gss_accept_sec_context(&minor, ctx, GSS_C_NO_CREDENTIAL, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(neghints)", major, minor); (void)gss_release_buffer(&minor, &atok); } int main(int argc, char *argv[]) { OM_uint32 minor, flags, dce_flags; gss_name_t tname; gss_ctx_id_t ictx, actx; const char *username, *password; if (argc != 4) { fprintf(stderr, "Usage: %s username password targetname\n", argv[0]); return 1; } username = argv[1]; password = argv[2]; tname = import_name(argv[3]); flags = GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG; start_init_context(&mech_krb5, GSS_C_NO_CREDENTIAL, tname, flags, &ictx); check_inq_context(ictx, 1, &mech_krb5, flags | GSS_C_TRANS_FLAG, 1); (void)gss_delete_sec_context(&minor, &ictx, NULL); start_init_context(&mech_iakerb, GSS_C_NO_CREDENTIAL, tname, flags, &ictx); check_inq_context(ictx, 1, &mech_iakerb, flags, 1); (void)gss_delete_sec_context(&minor, &ictx, NULL); start_init_context(&mech_spnego, GSS_C_NO_CREDENTIAL, tname, flags, &ictx); check_inq_context(ictx, 1, &mech_spnego, flags, 1); (void)gss_delete_sec_context(&minor, &ictx, NULL); dce_flags = flags | GSS_C_DCE_STYLE; start_accept_context(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, dce_flags, &actx); check_inq_context(actx, 1, &mech_krb5, dce_flags | GSS_C_TRANS_FLAG, 0); (void)gss_delete_sec_context(&minor, &actx, NULL); partial_iakerb_acceptor(username, password, tname, flags, &actx); check_inq_context(actx, 1, &mech_iakerb, 0, 0); (void)gss_delete_sec_context(&minor, &actx, NULL); partial_spnego_acceptor(tname, &actx); check_inq_context(actx, 1, &mech_spnego, 0, 0); (void)gss_delete_sec_context(&minor, &actx, NULL); establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, NULL, NULL, NULL); check_inq_context(ictx, 0, &mech_krb5, flags | GSS_C_TRANS_FLAG, 1); check_inq_context(actx, 0, &mech_krb5, flags | GSS_C_TRANS_FLAG | GSS_C_PROT_READY_FLAG, 0); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); (void)gss_release_name(&minor, &tname); return 0; } krb5-1.22.1/src/tests/gssapi/t_s4u2proxy_krb5.c0000664000175000017500000001571715051422640021104 0ustar ghudsonghudson/* -*- mode: c; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_s4u2proxy_deleg.c - Test S4U2Proxy after krb5 auth */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" /* * Usage: ./t_s4u2proxy_krb5 [--spnego] client_cache storage_cache * [accname|-] service1 service2 * * This program performs a regular Kerberos or SPNEGO authentication from the * default principal of client_cache to service1. If that authentication * yields delegated credentials, the program stores those credentials in * sorage_ccache and uses that cache to perform a second authentication to * service2 using S4U2Proxy. * * The default keytab must contain keys for service1 and service2. The default * ccache must contain a TGT for service1. This program assumes that krb5 or * SPNEGO authentication requires only one token exchange. */ int main(int argc, char *argv[]) { const char *client_ccname, *storage_ccname, *accname, *service1, *service2; krb5_context context = NULL; krb5_error_code ret; krb5_boolean use_spnego = FALSE; krb5_ccache storage_ccache = NULL; krb5_principal client_princ = NULL; OM_uint32 minor, major, flags; gss_buffer_desc buf = GSS_C_EMPTY_BUFFER; gss_OID mech; gss_OID_set mechs; gss_name_t acceptor_name = GSS_C_NO_NAME, client_name = GSS_C_NO_NAME; gss_name_t service1_name = GSS_C_NO_NAME, service2_name = GSS_C_NO_NAME; gss_cred_id_t service1_cred = GSS_C_NO_CREDENTIAL; gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL; gss_ctx_id_t initiator_context, acceptor_context; /* Parse arguments. */ if (argc >= 2 && strcmp(argv[1], "--spnego") == 0) { use_spnego = TRUE; argc--; argv++; } if (argc != 6) { fprintf(stderr, "./t_s4u2proxy_krb5 [--spnego] client_ccache " "storage_ccache [accname|-] service1 service2\n"); return 1; } client_ccname = argv[1]; storage_ccname = argv[2]; accname = argv[3]; service1 = argv[4]; service2 = argv[5]; mech = use_spnego ? &mech_spnego : &mech_krb5; mechs = use_spnego ? &mechset_spnego : &mechset_krb5; ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); /* Get GSS_C_BOTH acceptor credentials, using the default ccache. */ acceptor_name = GSS_C_NO_NAME; if (strcmp(accname, "-") != 0) acceptor_name = import_name(service1); major = gss_acquire_cred(&minor, acceptor_name, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, &service1_cred, NULL, NULL); check_gsserr("gss_acquire_cred(service1)", major, minor); /* Establish contexts using the client ccache. */ service1_name = import_name(service1); major = gss_krb5_ccache_name(&minor, client_ccname, NULL); check_gsserr("gss_krb5_ccache_name(1)", major, minor); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(mech, GSS_C_NO_CREDENTIAL, service1_cred, service1_name, flags, &initiator_context, &acceptor_context, &client_name, NULL, &deleg_cred); /* Display and remember the client principal. */ major = gss_display_name(&minor, client_name, &buf, NULL); check_gsserr("gss_display_name(1)", major, minor); printf("auth1: %.*s\n", (int)buf.length, (char *)buf.value); /* Assumes buffer is null-terminated, which in our implementation it is. */ ret = krb5_parse_name(context, buf.value, &client_princ); check_k5err(context, "krb5_parse_name", ret); (void)gss_release_buffer(&minor, &buf); if (deleg_cred == GSS_C_NO_CREDENTIAL) { printf("no credential delegated.\n"); goto cleanup; } /* Take the opportunity to test cred export/import on the synthesized * S4U2Proxy delegated cred. */ export_import_cred(&deleg_cred); /* Store the delegated credentials. */ ret = krb5_cc_resolve(context, storage_ccname, &storage_ccache); check_k5err(context, "krb5_cc_resolve", ret); ret = krb5_cc_initialize(context, storage_ccache, client_princ); check_k5err(context, "krb5_cc_initialize", ret); major = gss_krb5_copy_ccache(&minor, deleg_cred, storage_ccache); check_gsserr("gss_krb5_copy_ccache", major, minor); ret = krb5_cc_close(context, storage_ccache); check_k5err(context, "krb5_cc_close", ret); (void)gss_delete_sec_context(&minor, &initiator_context, GSS_C_NO_BUFFER); (void)gss_delete_sec_context(&minor, &acceptor_context, GSS_C_NO_BUFFER); (void)gss_release_name(&minor, &client_name); (void)gss_release_cred(&minor, &deleg_cred); /* Establish contexts using the storage ccache. */ service2_name = import_name(service2); major = gss_krb5_ccache_name(&minor, storage_ccname, NULL); check_gsserr("gss_krb5_ccache_name(2)", major, minor); establish_contexts(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, service2_name, flags, &initiator_context, &acceptor_context, &client_name, NULL, &deleg_cred); major = gss_display_name(&minor, client_name, &buf, NULL); check_gsserr("gss_display_name(2)", major, minor); printf("auth2: %.*s\n", (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&minor, &buf); cleanup: (void)gss_release_name(&minor, &acceptor_name); (void)gss_release_name(&minor, &client_name); (void)gss_release_name(&minor, &service1_name); (void)gss_release_name(&minor, &service2_name); (void)gss_release_cred(&minor, &service1_cred); (void)gss_release_cred(&minor, &deleg_cred); (void)gss_delete_sec_context(&minor, &initiator_context, GSS_C_NO_BUFFER); (void)gss_delete_sec_context(&minor, &acceptor_context, GSS_C_NO_BUFFER); krb5_free_principal(context, client_princ); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/gssapi/t_srcattrs.c0000664000175000017500000000454615051422640020125 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* src/tests/gssapi/t_accname_authind.c - test harness for auth indicators */ /* * Copyright (C) 2016 by Red Hat, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "common.h" /* Establish a context to the given target name and enumerate the attributes of * the source name. */ int main(int argc, char *argv[]) { OM_uint32 minor, flags; gss_name_t tname, sname; gss_ctx_id_t ictx, actx; if (argc != 2) { fprintf(stderr, "Usage: %s targetname\n", argv[0]); return 1; } tname = import_name(argv[1]); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, &sname, NULL, NULL); enumerate_attributes(sname, 1); (void)gss_release_name(&minor, &tname); (void)gss_release_name(&minor, &sname); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.22.1/src/tests/gssapi/t_ccselect.py0000775000175000017500000001541415051422640020252 0ustar ghudsonghudson# Copyright (C) 2011 by the Massachusetts Institute of Technology. # All rights reserved. # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * # Create two independent realms (no cross-realm TGTs). For the # fallback realm tests we need to control the precise server hostname, # so turn off DNS canonicalization and shortname qualification. conf = {'libdefaults': {'dns_canonicalize_hostname': 'false', 'qualify_shortname': ''}} r1 = K5Realm(create_user=False, krb5_conf=conf) r2 = K5Realm(create_user=False, krb5_conf=conf, realm='KRBTEST2.COM', portbase=62000, testdir=os.path.join(r1.testdir, 'r2')) host1 = 'p:' + r1.host_princ host2 = 'p:' + r2.host_princ foo = 'foo.krbtest.com' foo2 = 'foo.krbtest2.com' foobar = "foo.bar.krbtest.com" # These strings specify the target as a GSS name. The resulting # principal will have the host-based type, with the referral realm # (since k5test realms have no domain-realm mapping by default). # krb5_cc_select() will use the fallback realm, which is either the # uppercased parent domain, or the default realm if the hostname is a # single component. gssserver = 'h:host@' + foo gssserver2 = 'h:host@' + foo2 gssserver_bar = 'h:host@' + foobar gsslocal = 'h:host@localhost' # refserver specifies the target as a principal in the referral realm. # The principal won't be treated as a host principal by the # .k5identity rules since it has unknown type. refserver = 'p:host/' + hostname + '@' # Verify that we can't get initiator creds with no credentials in the # collection. r1.run(['./t_ccselect', host1, '-'], expected_code=1, expected_msg='No Kerberos credentials available') # Make a directory collection and use it for client commands in both realms. ccdir = os.path.join(r1.testdir, 'cc') ccname = 'DIR:' + ccdir r1.env['KRB5CCNAME'] = ccname r2.env['KRB5CCNAME'] = ccname # Use .k5identity from testdir and not from the tester's homedir. r1.env['HOME'] = r1.testdir r2.env['HOME'] = r1.testdir # Create two users in r1 and one in r2. alice='alice@KRBTEST.COM' bob='bob@KRBTEST.COM' zaphod='zaphod@KRBTEST2.COM' r1.addprinc(alice, password('alice')) r1.addprinc(bob, password('bob')) r2.addprinc(zaphod, password('zaphod')) # Create host principals and keytabs for fallback realm tests. if hostname != 'localhost': r1.addprinc('host/localhost') r2.addprinc('host/localhost') r1.addprinc('host/' + foo) r2.addprinc('host/' + foo2) r1.addprinc('host/' + foobar) r1.extract_keytab('host/localhost', r1.keytab) r2.extract_keytab('host/localhost', r2.keytab) r1.extract_keytab('host/' + foo, r1.keytab) r2.extract_keytab('host/' + foo2, r2.keytab) r1.extract_keytab('host/' + foobar, r1.keytab) # Get tickets for one user in each realm (zaphod will be primary). r1.kinit(alice, password('alice')) r2.kinit(zaphod, password('zaphod')) # Check that we can find a cache for a specified client principal. output = r1.run(['./t_ccselect', host1, 'p:' + alice]) if output != (alice + '\n'): fail('alice not chosen when specified') output = r2.run(['./t_ccselect', host2, 'p:' + zaphod]) if output != (zaphod + '\n'): fail('zaphod not chosen when specified') # Check that we can guess a cache based on the service realm. output = r1.run(['./t_ccselect', host1]) if output != (alice + '\n'): fail('alice not chosen as default initiator cred for server in r1') output = r1.run(['./t_ccselect', host1, '-']) if output != (alice + '\n'): fail('alice not chosen as default initiator name for server in r1') output = r2.run(['./t_ccselect', host2]) if output != (zaphod + '\n'): fail('zaphod not chosen as default initiator cred for server in r1') output = r2.run(['./t_ccselect', host2, '-']) if output != (zaphod + '\n'): fail('zaphod not chosen as default initiator name for server in r1') # Check that primary cache is used if server realm is unknown. output = r2.run(['./t_ccselect', refserver]) if output != (zaphod + '\n'): fail('zaphod not chosen via primary cache for unknown server realm') r1.run(['./t_ccselect', gssserver2], expected_code=1) # Check ccache selection using a fallback realm. output = r1.run(['./t_ccselect', gssserver]) if output != (alice + '\n'): fail('alice not chosen via parent domain fallback') output = r2.run(['./t_ccselect', gssserver2]) if output != (zaphod + '\n'): fail('zaphod not chosen via parent domain fallback') # Check ccache selection using a fallback realm (default realm). output = r1.run(['./t_ccselect', gsslocal]) if output != (alice + '\n'): fail('alice not chosen via default realm fallback') output = r2.run(['./t_ccselect', gsslocal]) if output != (zaphod + '\n'): fail('zaphod not chosen via default realm fallback') # Check that realm ccselect fallback works correctly r1.run(['./t_ccselect', gssserver_bar], expected_msg=alice) r2.kinit(zaphod, password('zaphod')) r1.run(['./t_ccselect', gssserver_bar], expected_msg=alice) # Get a second cred in r1 (bob will be primary). r1.kinit(bob, password('bob')) # Try some cache selections using .k5identity. k5id = open(os.path.join(r1.testdir, '.k5identity'), 'w') k5id.write('%s realm=%s\n' % (alice, r1.realm)) k5id.write('%s service=ho*t host=localhost\n' % zaphod) k5id.write('noprinc service=bogus') k5id.close() output = r1.run(['./t_ccselect', host1]) if output != (alice + '\n'): fail('alice not chosen via .k5identity realm line.') output = r2.run(['./t_ccselect', gsslocal]) if output != (zaphod + '\n'): fail('zaphod not chosen via .k5identity service/host line.') output = r1.run(['./t_ccselect', refserver]) if output != (bob + '\n'): fail('bob not chosen via primary cache when no .k5identity line matches.') r1.run(['./t_ccselect', 'h:bogus@' + foo2], expected_code=1, expected_msg="Can't find client principal noprinc") success('GSSAPI credential selection tests') krb5-1.22.1/src/tests/gssapi/t_store_cred.c0000664000175000017500000001002315051422640020374 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_store_cred.c - gss_store_cred() test harness */ /* * Copyright (C) 2021 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Usage: t_store_cred [-d] [-i] [-o] src_ccname [dest_ccname] * * Acquires creds from src_ccname using gss_acquire_cred_from() and then stores * them, using gss_store_cred_into() if -i is specified or gss_store_cred() * otherwise. If dest_ccname is specified with -i, it is included in the cred * store for the store operation; if it is specified without -i, it is set with * gss_krb5_ccache_name() before the store operation. If -d and/or -o are * specified they set the default_cred and overwrite_cred flags to true * respectively. */ #include "k5-platform.h" #include #include "common.h" int main(int argc, char *argv[]) { OM_uint32 major, minor; gss_key_value_set_desc store; gss_key_value_element_desc elem; gss_cred_id_t cred; krb5_boolean def = FALSE, into = FALSE, overwrite = FALSE; const char *src_ccname, *dest_ccname; int c; /* Parse arguments. */ while ((c = getopt(argc, argv, "dio")) != -1) { switch (c) { case 'd': def = TRUE; break; case 'i': into = TRUE; break; case 'o': overwrite = TRUE; break; default: abort(); } } argc -= optind; argv += optind; assert(argc == 1 || argc == 2); src_ccname = argv[0]; dest_ccname = argv[1]; elem.key = "ccache"; elem.value = src_ccname; store.count = 1; store.elements = &elem; major = gss_acquire_cred_from(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechset_krb5, GSS_C_INITIATE, &store, &cred, NULL, NULL); check_gsserr("acquire_cred", major, minor); if (into) { if (dest_ccname != NULL) { elem.key = "ccache"; elem.value = dest_ccname; store.count = 1; } else { store.count = 0; } major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE, &mech_krb5, overwrite, def, &store, NULL, NULL); check_gsserr("store_cred_into", major, minor); } else { if (dest_ccname != NULL) { major = gss_krb5_ccache_name(&minor, dest_ccname, NULL); check_gsserr("ccache_name", major, minor); } major = gss_store_cred(&minor, cred, GSS_C_INITIATE, &mech_krb5, overwrite, def, NULL, NULL); check_gsserr("store_cred", major, minor); } gss_release_cred(&minor, &cred); return 0; } krb5-1.22.1/src/tests/gssapi/t_export_cred.py0000775000175000017500000000325215051422640021000 0ustar ghudsonghudsonfrom k5test import * # Test gss_export_cred and gss_import_cred for initiator creds, # acceptor creds, and traditional delegated creds. t_s4u.py tests # exporting and importing a synthesized S4U2Proxy delegated # credential. # Make up a filename to hold user's initial credentials. def ccache_savefile(realm): return os.path.join(realm.testdir, 'ccache.copy') # Move user's initial credentials into the save file. def ccache_save(realm): os.rename(realm.ccache, ccache_savefile(realm)) # Copy user's initial credentials from the save file into the ccache. def ccache_restore(realm): shutil.copyfile(ccache_savefile(realm), realm.ccache) # Run t_export_cred with the saved ccache and verify that it stores a # forwarded cred into the default ccache. def check(realm, args): ccache_restore(realm) realm.run(['./t_export_cred'] + args) realm.run([klist, '-f'], expected_msg='Flags: Ff') # Check a given set of arguments with no specified mech and with krb5 # and SPNEGO as the specified mech. def check_mechs(realm, args): check(realm, args) check(realm, ['-k'] + args) check(realm, ['-s'] + args) # Make a realm, get forwardable tickets, and save a copy for each test. realm = K5Realm(get_creds=False) realm.kinit(realm.user_princ, password('user'), ['-f']) ccache_save(realm) # Test with default initiator and acceptor cred. tname = 'p:' + realm.host_princ check_mechs(realm, [tname]) # Test with principal-named initiator and acceptor cred. iname = 'p:' + realm.user_princ check_mechs(realm, ['-i', iname, '-a', tname, tname]) # Test with host-based acceptor cred. check_mechs(realm, ['-a', 'h:host', tname]) success('gss_export_cred/gss_import_cred tests') krb5-1.22.1/src/tests/gssapi/t_inq_cred.c0000664000175000017500000000777115051422640020047 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_inq_cred.c - Test program for gss_inquire_cred behavior */ /* * Copyright 2012 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test program for gss_inquire_cred, intended to be run from a Python test * script. Acquires credentials, inquires them, and prints the resulting name * and lifetime. * * Usage: ./t_inq_cred [-k|-s] [-a|-b|-i] [initiatorname] * * By default no mechanism is specified when acquiring credentials; -k * indicates the krb5 mech and -s indicates SPNEGO. By default or with -i, * initiator credentials are acquired; -a indicates acceptor credentials and -b * indicates credentials of both types. The credential is acquired with no * name by default; a krb5 principal name or host-based name (prefixed with * "gss:") may be supplied as an argument. */ #include #include #include #include "common.h" static void usage(void) { fprintf(stderr, "Usage: t_inq_cred [-k|-s] [-a|-b|-i] [princ|gss:service@host]\n"); exit(1); } int main(int argc, char *argv[]) { OM_uint32 minor, major, lifetime; gss_cred_usage_t cred_usage = GSS_C_INITIATE; gss_OID_set mechs = GSS_C_NO_OID_SET; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; gss_name_t name = GSS_C_NO_NAME; gss_buffer_desc buf; const char *name_arg = NULL; char opt; while (argc > 1 && argv[1][0] == '-') { opt = argv[1][1]; argc--, argv++; if (opt == 'a') cred_usage = GSS_C_ACCEPT; else if (opt == 'b') cred_usage = GSS_C_BOTH; else if (opt == 'i') cred_usage = GSS_C_INITIATE; else if (opt == 'k') mechs = &mechset_krb5; else if (opt == 's') mechs = &mechset_spnego; else usage(); } if (argc > 2) usage(); if (argc > 1) name_arg = argv[1]; /* Import the name, if given. */ if (name_arg != NULL) name = import_name(name_arg); /* Acquire a credential. */ major = gss_acquire_cred(&minor, name, GSS_C_INDEFINITE, mechs, cred_usage, &cred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); /* Inquire about the credential. */ (void)gss_release_name(&minor, &name); major = gss_inquire_cred(&minor, cred, &name, &lifetime, NULL, NULL); check_gsserr("gss_inquire_cred", major, minor); /* Get a display form of the name. */ buf.value = NULL; buf.length = 0; major = gss_display_name(&minor, name, &buf, NULL); check_gsserr("gss_display_name", major, minor); printf("name: %.*s\n", (int)buf.length, (char *)buf.value); printf("lifetime: %d\n", (int)lifetime); (void)gss_release_cred(&minor, &cred); (void)gss_release_name(&minor, &name); (void)gss_release_buffer(&minor, &buf); return 0; } krb5-1.22.1/src/tests/gssapi/t_export_cred.c0000664000175000017500000001070415051422640020567 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include "common.h" /* Display a usage error message and exit. */ static void usage(void) { fprintf(stderr, "Usage: t_export_cred [-k|-s] [-i initiatorname] " "[-a acceptorname] targetname\n"); exit(1); } int main(int argc, char *argv[]) { OM_uint32 major, minor, flags; gss_name_t initiator_name = GSS_C_NO_NAME, acceptor_name = GSS_C_NO_NAME; gss_name_t target_name; gss_cred_id_t initiator_cred, acceptor_cred, delegated_cred; gss_ctx_id_t initiator_context = GSS_C_NO_CONTEXT; gss_ctx_id_t acceptor_context = GSS_C_NO_CONTEXT; gss_OID mech = GSS_C_NO_OID; gss_OID_set mechs = GSS_C_NO_OID_SET; char optchar; /* Parse arguments. */ argv++; while (*argv != NULL && **argv == '-') { optchar = (*argv)[1]; argv++; if (optchar == 'i') { if (*argv == NULL) usage(); initiator_name = import_name(*argv++); } else if (optchar == 'a') { if (*argv == NULL) usage(); acceptor_name = import_name(*argv++); } else if (optchar == 'k') { mech = &mech_krb5; mechs = &mechset_krb5; } else if (optchar == 's') { mech = &mech_spnego; mechs = &mechset_spnego; } else { usage(); } } if (*argv == NULL || *(argv + 1) != NULL) usage(); target_name = import_name(argv[0]); /* Get initiator cred and export/import it. */ major = gss_acquire_cred(&minor, initiator_name, GSS_C_INDEFINITE, mechs, GSS_C_INITIATE, &initiator_cred, NULL, NULL); check_gsserr("gss_acquire_cred(initiator)", major, minor); export_import_cred(&initiator_cred); /* Get acceptor cred and export/import it. */ major = gss_acquire_cred(&minor, acceptor_name, GSS_C_INDEFINITE, mechs, GSS_C_ACCEPT, &acceptor_cred, NULL, NULL); check_gsserr("gss_acquire_cred(acceptor)", major, minor); export_import_cred(&acceptor_cred); /* Initiate and accept a security context (one-token exchange only), * delegating credentials. */ flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_DELEG_FLAG; establish_contexts(mech, initiator_cred, acceptor_cred, target_name, flags, &initiator_context, &acceptor_context, NULL, NULL, &delegated_cred); /* Import, release, export, and store delegated creds */ export_import_cred(&delegated_cred); major = gss_store_cred(&minor, delegated_cred, GSS_C_INITIATE, GSS_C_NULL_OID, 1, 1, NULL, NULL); check_gsserr("gss_store_cred", major, minor); (void)gss_release_name(&minor, &initiator_name); (void)gss_release_name(&minor, &acceptor_name); (void)gss_release_name(&minor, &target_name); (void)gss_release_cred(&minor, &initiator_cred); (void)gss_release_cred(&minor, &acceptor_cred); (void)gss_release_cred(&minor, &delegated_cred); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); return 0; } krb5-1.22.1/src/tests/gssapi/t_iakerb.c0000664000175000017500000000655615051422640017520 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_iakerb.c - IAKERB tests */ /* * Copyright (C) 2024, 2025 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "common.h" int main(int argc, char **argv) { OM_uint32 major, minor; const char *password; gss_name_t iname, tname, aname; gss_cred_id_t icred, acred; gss_ctx_id_t ictx, actx; gss_buffer_desc pwbuf; if (argc != 5) { fprintf(stderr, "Usage: %s initiatorname password|- targetname " "acceptorname\n", argv[0]); return 1; } iname = import_name(argv[1]); password = argv[2]; tname = import_name(argv[3]); aname = import_name(argv[4]); if (strcmp(password, "-") != 0) { pwbuf.value = (void *)password; pwbuf.length = strlen(password); major = gss_acquire_cred_with_password(&minor, iname, &pwbuf, 0, &mechset_iakerb, GSS_C_INITIATE, &icred, NULL, NULL); check_gsserr("gss_acquire_cred_with_password", major, minor); } else { major = gss_acquire_cred(&minor, iname, GSS_C_INDEFINITE, &mechset_iakerb, GSS_C_INITIATE, &icred, NULL, NULL); check_gsserr("gss_acquire_cred(iname)", major, minor); } major = gss_acquire_cred(&minor, aname, GSS_C_INDEFINITE, &mechset_iakerb, GSS_C_ACCEPT, &acred, NULL, NULL); check_gsserr("gss_acquire_cred(aname)", major, minor); establish_contexts(&mech_iakerb, icred, acred, tname, 0, &ictx, &actx, NULL, NULL, NULL); (void)gss_release_name(&minor, &iname); (void)gss_release_name(&minor, &tname); (void)gss_release_name(&minor, &aname); (void)gss_release_cred(&minor, &icred); (void)gss_release_cred(&minor, &acred); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.22.1/src/tests/gssapi/t_spnego.c0000664000175000017500000002720015051422640017543 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2010 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * */ #include #include #include #include #include "common.h" static gss_OID_desc mech_krb5_wrong = { 9, "\052\206\110\202\367\022\001\002\002" }; gss_OID_set_desc mechset_krb5_wrong = { 1, &mech_krb5_wrong }; /* * Test program for SPNEGO and gss_set_neg_mechs * * Example usage: * * kinit testuser * ./t_spnego host/test.host@REALM testhost.keytab */ /* Replace *tok and *len with the concatenation of prefix and *tok. */ static void prepend(const void *prefix, size_t plen, uint8_t **tok, size_t *len) { uint8_t *newtok; newtok = malloc(plen + *len); assert(newtok != NULL); memcpy(newtok, prefix, plen); memcpy(newtok + plen, *tok, *len); free(*tok); *tok = newtok; *len = plen + *len; } /* Replace *tok and *len with *tok wrapped in a DER tag with the given tag * byte. *len must be less than 2^16. */ static void der_wrap(uint8_t tag, uint8_t **tok, size_t *len) { char lenbuf[3]; uint8_t *wrapped; size_t llen; if (*len < 128) { lenbuf[0] = *len; llen = 1; } else if (*len < 256) { lenbuf[0] = 0x81; lenbuf[1] = *len; llen = 2; } else { assert(*len >> 16 == 0); lenbuf[0] = 0x82; lenbuf[1] = *len >> 8; lenbuf[2] = *len & 0xFF; llen = 3; } wrapped = malloc(1 + llen + *len); assert(wrapped != NULL); *wrapped = tag; memcpy(wrapped + 1, lenbuf, llen); memcpy(wrapped + 1 + llen, *tok, *len); free(*tok); *tok = wrapped; *len = 1 + llen + *len; } /* * Create a SPNEGO initiator token for the erroneous Microsoft krb5 mech OID, * wrapping a krb5 token ktok. The token should look like: * * 60 (GSS framing sequence) * 06 06 2B 06 01 05 05 02 (SPNEGO OID) * A0 (NegotiationToken choice 0, negTokenInit) * 30 (sequence) * A0 0D (context tag 0, mechTypes) * 30 0B (sequence of) * 06 09 2A 86 48 82 F7 12 01 02 02 (wrong krb5 OID) * A2 (context tag 2, mechToken) * 04 (octet string) * */ static void create_mskrb5_spnego_token(gss_buffer_t ktok, gss_buffer_desc *tok_out) { uint8_t *tok; size_t len; len = ktok->length; tok = malloc(len); assert(tok != NULL); memcpy(tok, ktok->value, len); /* Wrap the krb5 token in OCTET STRING and [2] tags. */ der_wrap(0x04, &tok, &len); der_wrap(0xA2, &tok, &len); /* Prepend the wrong krb5 OID inside OBJECT IDENTIFIER and [0] tags. */ prepend("\xA0\x0D\x30\x0B\x06\x09\x2A\x86\x48\x82\xF7\x12\x01\x02\x02", 15, &tok, &len); /* Wrap the previous two things in SEQUENCE and [0] tags. */ der_wrap(0x30, &tok, &len); der_wrap(0xA0, &tok, &len); /* Prepend the SPNEGO OID in an OBJECT IDENTIFIER tag. */ prepend("\x06\x06\x2B\x06\x01\x05\x05\x02", 8, &tok, &len); /* Wrap the whole thing in an [APPLICATION 0] tag. */ der_wrap(0x60, &tok, &len); tok_out->value = tok; tok_out->length = len; } /* * Test that the SPNEGO acceptor code accepts and properly reflects back the * erroneous Microsoft mech OID in the supportedMech field of the NegTokenResp * message. Use acred as the verifier cred handle. */ static void test_mskrb_oid(gss_name_t tname, gss_cred_id_t acred) { OM_uint32 major, minor; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; gss_buffer_desc atok = GSS_C_EMPTY_BUFFER, ktok = GSS_C_EMPTY_BUFFER, stok; const unsigned char *atok_oid; /* * Our SPNEGO mech no longer acquires creds for the wrong mech OID, so we * have to construct a SPNEGO token ourselves. */ major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, tname, &mech_krb5, 0, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &ktok, NULL, NULL); check_gsserr("gss_init_sec_context(mskrb)", major, minor); assert(major == GSS_S_COMPLETE); create_mskrb5_spnego_token(&ktok, &stok); /* * Look directly at the DER encoding of the response token. Since we * didn't request mutual authentication, the SPNEGO reply will contain no * underlying mech token; therefore, the encoding of the correct * NegotiationToken response is completely predictable: * * A1 14 (choice 1, length 20, meaning negTokenResp) * 30 12 (sequence, length 18) * A0 03 (context tag 0, length 3) * 0A 01 00 (enumerated value 0, meaning accept-completed) * A1 0B (context tag 1, length 11) * 06 09 (object identifier, length 9) * 2A 86 48 82 F7 12 01 02 02 (the erroneous krb5 OID) * * So we can just compare the length to 22 and the nine bytes at offset 13 * to the expected OID. */ major = gss_accept_sec_context(&minor, &actx, acred, &stok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(mskrb)", major, minor); assert(atok.length == 22); atok_oid = (unsigned char *)atok.value + 13; assert(memcmp(atok_oid, mech_krb5_wrong.elements, 9) == 0); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); (void)gss_release_buffer(&minor, &ktok); (void)gss_release_buffer(&minor, &atok); free(stok.value); } /* Check that we return a compatibility NegTokenInit2 message containing * NegHints for an empty initiator token. */ static void test_neghints(void) { OM_uint32 major, minor; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok; gss_ctx_id_t actx = GSS_C_NO_CONTEXT; const char *expected = /* RFC 2743 token framing: [APPLICATION 0] IMPLICIT SEQUENCE followed * by OBJECT IDENTIFIER and the SPNEGO OID */ "\x60\x47\x06\x06" "\x2B\x06\x01\x05\x05\x02" /* [0] SEQUENCE for the NegotiationToken negtokenInit choice */ "\xA0\x3D\x30\x3B" /* [0] MechTypeList containing the krb5 OID */ "\xA0\x0D\x30\x0B\x06\x09" "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02" /* [3] NegHints containing [0] GeneralString containing the dummy * hintName string defined in [MS-SPNG] */ "\xA3\x2A\x30\x28\xA0\x26\x1B\x24" "not_defined_in_RFC4178@please_ignore"; /* Produce a hint token. */ major = gss_accept_sec_context(&minor, &actx, GSS_C_NO_CREDENTIAL, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(neghints)", major, minor); /* Verify it against the expected contents, which are fixed as long as we * only list the krb5 mech in the token. */ assert(atok.length == strlen(expected)); assert(memcmp(atok.value, expected, atok.length) == 0); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &actx, NULL); } int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_cred_id_t verifier_cred_handle = GSS_C_NO_CREDENTIAL; gss_cred_id_t initiator_cred_handle = GSS_C_NO_CREDENTIAL; gss_OID_set actual_mechs = GSS_C_NO_OID_SET; gss_ctx_id_t initiator_context, acceptor_context; gss_name_t target_name, source_name = GSS_C_NO_NAME; gss_OID mech = GSS_C_NO_OID; gss_OID_desc pref_oids[2]; gss_OID_set_desc pref_mechs; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s target_name [keytab]\n", argv[0]); exit(1); } target_name = import_name(argv[1]); if (argc >= 3) { major = krb5_gss_register_acceptor_identity(argv[2]); check_gsserr("krb5_gss_register_acceptor_identity", major, 0); } /* Get default initiator cred. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechset_spnego, GSS_C_INITIATE, &initiator_cred_handle, NULL, NULL); check_gsserr("gss_acquire_cred(initiator)", major, minor); /* * The following test is designed to exercise SPNEGO reselection on the * client and server. Unfortunately, it no longer does so after tickets * #8217 and #8021, since SPNEGO now only acquires a single krb5 cred and * there is no way to expand the underlying creds with gss_set_neg_mechs(). * To fix this we need gss_acquire_cred_with_cred() or some other way to * turn a cred with a specifically requested mech set into a SPNEGO cred. */ /* Make the initiator prefer IAKERB and offer krb5 as an alternative. */ pref_oids[0] = mech_iakerb; pref_oids[1] = mech_krb5; pref_mechs.count = 2; pref_mechs.elements = pref_oids; major = gss_set_neg_mechs(&minor, initiator_cred_handle, &pref_mechs); check_gsserr("gss_set_neg_mechs(initiator)", major, minor); /* Get default acceptor cred. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, &mechset_spnego, GSS_C_ACCEPT, &verifier_cred_handle, &actual_mechs, NULL); check_gsserr("gss_acquire_cred(acceptor)", major, minor); /* Restrict the acceptor to krb5 (which will force a reselection). */ major = gss_set_neg_mechs(&minor, verifier_cred_handle, &mechset_krb5); check_gsserr("gss_set_neg_mechs(acceptor)", major, minor); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_spnego, initiator_cred_handle, verifier_cred_handle, target_name, flags, &initiator_context, &acceptor_context, &source_name, &mech, NULL); display_canon_name("Source name", source_name, &mech_krb5); display_oid("Source mech", mech); /* Test acceptance of the erroneous Microsoft krb5 OID, with and without an * acceptor cred. */ test_mskrb_oid(target_name, verifier_cred_handle); test_mskrb_oid(target_name, GSS_C_NO_CREDENTIAL); test_neghints(); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); (void)gss_release_name(&minor, &source_name); (void)gss_release_name(&minor, &target_name); (void)gss_release_cred(&minor, &initiator_cred_handle); (void)gss_release_cred(&minor, &verifier_cred_handle); (void)gss_release_oid_set(&minor, &actual_mechs); return 0; } krb5-1.22.1/src/tests/gssapi/ccrefresh.c0000664000175000017500000000524615051422640017677 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/ccrefresh.c - Get or set refresh time on a ccache */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program sets the refresh time of an existing ccache to 1, forcing a * refresh. */ #include "k5-int.h" static void check(krb5_error_code code) { if (code != 0) { com_err("ccrefresh", code, NULL); abort(); } } int main(int argc, char **argv) { const char *ccname, *value = NULL; krb5_context context; krb5_ccache ccache; krb5_data d; if (argc != 2 && argc != 3) { fprintf(stderr, "Usage: %s ccname [value]\n", argv[0]); return 1; } ccname = argv[1]; if (argc == 3) value = argv[2]; check(krb5_init_context(&context)); check(krb5_cc_resolve(context, ccname, &ccache)); if (value != NULL) { d = string2data((char *)value); check(krb5_cc_set_config(context, ccache, NULL, KRB5_CC_CONF_REFRESH_TIME, &d)); } else { check(krb5_cc_get_config(context, ccache, NULL, KRB5_CC_CONF_REFRESH_TIME, &d)); printf("%.*s\n", (int)d.length, d.data); krb5_free_data_contents(context, &d); } krb5_cc_close(context, ccache); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/gssapi/common.h0000664000175000017500000000762315051422640017231 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/common.h - Declarations for GSSAPI test utility functions */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef COMMON_H #define COMMON_H #include extern gss_OID_desc mech_krb5; extern gss_OID_desc mech_spnego; extern gss_OID_desc mech_iakerb; extern gss_OID_set_desc mechset_krb5; extern gss_OID_set_desc mechset_spnego; extern gss_OID_set_desc mechset_iakerb; /* Display an error message (containing msg) and exit if major is an error. */ void check_gsserr(const char *msg, OM_uint32 major, OM_uint32 minor); /* Display an error message (containing msg) and exit if code is an error. */ void check_k5err(krb5_context context, const char *msg, krb5_error_code code); /* Display an error message containing msg and exit. */ void errout(const char *msg); /* Import a GSSAPI name based on a string of the form 'u:username', * 'p:principalname', or 'h:host@service' (or just 'h:service'). */ gss_name_t import_name(const char *str); /* Establish contexts using gss_init_sec_context and gss_accept_sec_context. */ void establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx, gss_ctx_id_t *actx, gss_name_t *src_name, gss_OID *amech, gss_cred_id_t *deleg_cred); /* Establish contexts with channel bindings. */ void establish_contexts_ex(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx, gss_ctx_id_t *actx, gss_channel_bindings_t icb, gss_channel_bindings_t acb, OM_uint32 *aret_flags, gss_name_t *src_name, gss_OID *amech, gss_cred_id_t *deleg_cred); /* Export *cred to a token, then release *cred and replace it by re-importing * the token. */ void export_import_cred(gss_cred_id_t *cred); /* Display name as canonicalized to mech, preceded by tag. */ void display_canon_name(const char *tag, gss_name_t name, gss_OID mech); /* Display oid in printable form, preceded by tag (if not NULL). */ void display_oid(const char *tag, gss_OID oid); /* Display attributes of name, including hex value if noisy is true. */ void enumerate_attributes(gss_name_t name, int noisy); /* Display the contents of buf to fp in hex, followed by a newline. */ void print_hex(FILE *fp, gss_buffer_t buf); #endif /* COMMON_H */ krb5-1.22.1/src/tests/gssapi/t_negoex.py0000664000175000017500000001504715051422640017751 0ustar ghudsonghudsonfrom k5test import * # The next arc after 2.25 is supposed to be a single-integer UUID, but # since our gss_str_to_oid() can't handle arc values that don't fit in # an unsigned long, we use random unsigned 32-bit integers instead. # The final octet if the OID encoding will be used to identify the # mechanism when changing the behavior of just one mech. nxtest_oid1 = '2.25.1414534758' # final octet is 102 (0x66) nxtest_oid2 = '2.25.1175737388' # final octet is 44 (0x2C) nxtest_path = os.path.join(buildtop, 'plugins', 'gssapi', 'negoextest', 'gss_negoextest.so') # Test gss_add_cred(). realm = K5Realm(create_kdb=False) with open(realm.gss_mech_config, 'w') as f: f.write('negoextest %s %s\n' % (nxtest_oid1, nxtest_path)) f.write('negoextest %s %s\n' % (nxtest_oid2, nxtest_path)) def test(envvars, **kw): # Python 3.5: e = {**realm.env, **vars} e = realm.env.copy() e.update(envvars) realm.run(['./t_context', 'h:host'], env=e, **kw) # Test varying numbers of hops, and spot-check that messages are sent # in the appropriate sequence. mark('One hop') msgs = ('sending [0]INITIATOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 'd1b08469-2ca8-0000-0000-000000000000', 'sending [1]INITIATOR_META_DATA: c0a28569-66ac', 'sending [2]INITIATOR_META_DATA: d1b08469-2ca8', 'sending [3]AP_REQUEST: c0a28569-66ac', 'sending [4]VERIFY: c0a28569-66ac', 'received [0]INITIATOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 'd1b08469-2ca8-0000-0000-000000000000', 'received [1]INITIATOR_META_DATA: c0a28569-66ac', 'received [2]INITIATOR_META_DATA: d1b08469-2ca8', 'received [3]AP_REQUEST: c0a28569-66ac', 'received [4]VERIFY: c0a28569-66ac', 'sending [5]ACCEPTOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 'd1b08469-2ca8-0000-0000-000000000000', 'sending [6]ACCEPTOR_META_DATA: c0a28569-66ac', 'sending [7]ACCEPTOR_META_DATA: d1b08469-2ca8', 'sending [8]VERIFY: c0a28569-66ac', 'received [5]ACCEPTOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 'd1b08469-2ca8-0000-0000-000000000000', 'received [6]ACCEPTOR_META_DATA: c0a28569-66ac', 'received [7]ACCEPTOR_META_DATA: d1b08469-2ca8', 'received [8]VERIFY: c0a28569-66ac') test({'HOPS': '1'}, expected_trace=msgs) mark('Two hops') msgs = ('sending [7]CHALLENGE', 'sending [8]VERIFY', 'received [8]VERIFY', 'sending [9]VERIFY') test({'HOPS': '2'}, expected_trace=msgs) mark('Three hops') msgs = ('sending [8]AP_REQUEST', 'sending [9]VERIFY', 'received [8]AP_REQUEST', 'sending [10]VERIFY') test({'HOPS': '3'}, expected_trace=msgs) mark('Four hops') msgs = ('sending [9]CHALLENGE', 'sending [10]VERIFY', 'received [9]CHALLENGE', 'sending [11]VERIFY') test({'HOPS': '4'}, expected_trace=msgs) mark('Early keys, three hops') msgs = ('sending [4]VERIFY', 'sending [9]VERIFY', 'sending [10]AP_REQUEST') test({'HOPS': '3', 'KEY': 'always'}, expected_trace=msgs) mark('Early keys, four hops') msgs = ('sending [4]VERIFY', 'sending [9]VERIFY', 'sending [10]AP_REQUEST', 'sending [11]CHALLENGE') test({'HOPS': '4', 'KEY': 'always'}, expected_trace=msgs) mark('No keys') test({'KEY': 'never'}, expected_code=1, expected_msg='No NegoEx verify key') mark('No optimistic token') msgs = ('sending [3]ACCEPTOR_NEGO', 'sending [6]AP_REQUEST', 'sending [7]VERIFY', 'sending [8]VERIFY') test({'NEGOEX_NO_OPTIMISTIC_TOKEN': ''}, expected_trace=msgs) mark('First mech initiator query fail') msgs = ('sending [0]INITIATOR_NEGO: d1b08469-2ca8-0000-0000-000000000000', 'sending [2]AP_REQUEST', 'sending [3]VERIFY', 'sending [4]ACCEPTOR_NEGO: d1b08469-2ca8-0000-0000-000000000000', 'sending [6]VERIFY') test({'INIT_QUERY_FAIL': '102'}, expected_trace=msgs) mark('First mech acceptor query fail') msgs = ('sending [0]INITIATOR_NEGO: c0a28569-66ac-0000-0000-000000000000 ' 'd1b08469-2ca8-0000-0000-000000000000', 'sending [3]AP_REQUEST: c0a28569-66ac', 'sending [4]VERIFY: c0a28569-66ac', 'sending [5]ACCEPTOR_NEGO: d1b08469-2ca8-0000-0000-000000000000', 'sending [7]AP_REQUEST: d1b08469-2ca8', 'sending [8]VERIFY: d1b08469-2ca8', 'sending [9]VERIFY: d1b08469-2ca8') test({'ACCEPT_QUERY_FAIL': '102'}, expected_trace=msgs) # Same messages as previous test. mark('First mech acceptor exchange fail') test({'ACCEPT_EXCHANGE_FAIL': '102'}, expected_trace=msgs) # Fail the optimistic mech's gss_exchange_meta_data() in the # initiator. Since the acceptor has effectively selected the # optimistic mech, this causes the authentication to fail. mark('First mech initiator exchange fail, one hop') test({'HOPS': '1', 'INIT_EXCHANGE_FAIL': '102'}, expected_code=1, expected_msg='No mutually supported NegoEx authentication schemes') mark('First mech initiator exchange fail, two hops, early keys') test({'HOPS': '2', 'INIT_EXCHANGE_FAIL': '102', 'KEY': 'always'}, expected_code=1, expected_msg='No mutually supported NegoEx authentication schemes') mark('First mech initiator exchange fail, two hops') test({'HOPS': '2', 'INIT_EXCHANGE_FAIL': '102'}, expected_code=1, expected_msg='No mutually supported NegoEx authentication schemes') mark('First mech init_sec_context fail') msgs = ('sending [0]INITIATOR_NEGO: d1b08469-2ca8-0000-0000-000000000000', 'sending [2]AP_REQUEST', 'sending [3]VERIFY', 'sending [6]VERIFY') test({'INIT_FAIL': '102'}, expected_trace=msgs) mark('First mech accept_sec_context fail') test({'HOPS': '2', 'ACCEPT_FAIL': '102'}, expected_code=1, expected_msg='failure from acceptor') mark('ALERT from acceptor to initiator') msgs = ('sending [3]AP_REQUEST', 'sending [4]VERIFY', 'sending [8]CHALLENGE', 'sending [9]ALERT', 'received [9]ALERT', 'sending [10]AP_REQUEST', 'sending [11]VERIFY', 'sending [12]VERIFY') test({'HOPS': '3', 'KEY': 'init-always'}, expected_trace=msgs) mark('ALERT from initiator to acceptor') msgs = ('sending [3]AP_REQUEST', 'sending [7]CHALLENGE', 'sending [8]VERIFY', 'sending [9]AP_REQUEST', 'sending [10]ALERT', 'received [10]ALERT', 'sending [11]CHALLENGE', 'sending [12]VERIFY', 'sending [13]VERIFY') test({'HOPS': '4', 'KEY': 'accept-always'}, expected_trace=()) mark('channel bindings') e = realm.env.copy() e.update({'HOPS': '1', 'GSS_INIT_BINDING': 'a', 'GSS_ACCEPT_BINDING': 'b'}) # The test mech will verify that the bindings are communicated to the # mech, but does not set the channel-bound flag. realm.run(['./t_bindings', '-s', 'h:host', 'a', 'b'], env=e, expected_msg='no') success('NegoEx tests') krb5-1.22.1/src/tests/gssapi/t_oid.c0000664000175000017500000002041015051422640017017 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_oid.c - Test OID manipulation functions */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "common.h" static struct { char *canonical; char *variant; gss_OID_desc oid; } tests[] = { /* GSS_C_NT_USER_NAME */ { "{ 1 2 840 113554 1 2 1 1 }", "1.2.840.113554.1.2.1.1", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x01\x01" } }, /* GSS_C_NT_MACHINE_UID_NAME */ { "{ 1 2 840 113554 1 2 1 2 }", "1 2 840 113554 1 2 1 2", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x01\x02" } }, /* GSS_C_NT_STRING_UID_NAME */ { "{ 1 2 840 113554 1 2 1 3 }", "{1 2 840 113554 1 2 1 3}", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x01\x03" } }, /* GSS_C_NT_HOSTBASED_SERVICE_X */ { "{ 1 3 6 1 5 6 2 }", "{ 1 3 6 1 5 6 2 }", { 6, "\x2B\x06\x01\x05\x06\x02" } }, /* GSS_C_NT_ANONYMOUS */ { "{ 1 3 6 1 5 6 3 }", "{ 01 03 06 01 05 06 03 }", { 6, "\x2B\x06\x01\x05\x06\x03" } }, /* GSS_KRB5_NT_PRINCIPAL_NAME */ { "{ 1 2 840 113554 1 2 2 1 }", " {01 2 840 113554 1 2 2 1 } ", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x01" } }, /* GSS_KRB5_NT_ENTERPRISE_NAME */ { "{ 1 2 840 113554 1 2 2 6 }", " {1.2.840.113554.1.2.2.6} ", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x06" } }, /* gss_krb5_nt_principal */ { "{ 1 2 840 113554 1 2 2 2 }", "{1.2.840.113554.1.2.2.2}", { 10, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02" } }, /* gss_mech_krb5 */ { "{ 1 2 840 113554 1 2 2 }", "{ 1.2.840.113554.1.2.2 }", { 9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02" } }, /* gss_mech_krb5_old */ { "{ 1 3 5 1 5 2 }", "001 . 003 . 005 . 001 . 005 . 002", { 5, "\x2B\x05\x01\x05\x02" } }, /* gss_mech_krb5_wrong */ { "{ 1 2 840 48018 1 2 2 }", "1.2.840.48018.1.2.2 trailing garbage", { 9, "\x2A\x86\x48\x82\xF7\x12\x01\x02\x02" } }, /* gss_mech_iakerb */ { "{ 1 3 6 1 5 2 5 }", "{ 1 3 6 1 5 2 5 } trailing garbage", { 6, "\x2B\x06\x01\x05\x02\x05" } }, /* SPNEGO */ { "{ 1 3 6 1 5 5 2 }", "{1 3 6 1 5 5 2} trailing garbage", { 6, "\x2B\x06\x01\x05\x05\x02" } }, /* Edge cases for the first two arcs */ { "{ 0 0 }", NULL, { 1, "\x00" } }, { "{ 0 39 }", NULL, { 1, "\x27" } }, { "{ 1 0 }", NULL, { 1, "\x28" } }, { "{ 1 39 }", NULL, { 1, "\x4F" } }, { "{ 2 0 }", NULL, { 1, "\x50" } }, { "{ 2 40 }", NULL, { 1, "\x78" } }, { "{ 2 47 }", NULL, { 1, "\x7F" } }, { "{ 2 48 }", NULL, { 2, "\x81\x00" } }, { "{ 2 16304 }", NULL, { 3, "\x81\x80\x00" } }, /* Zero-valued arcs */ { "{ 0 0 0 }", NULL, { 2, "\x00\x00" } }, { "{ 0 0 1 0 }", NULL, { 3, "\x00\x01\x00" } }, { "{ 0 0 128 0 }", NULL, { 4, "\x00\x81\x00\x00 " } }, { "{ 0 0 0 1 }", NULL, { 3, "\x00\x00\x01" } }, { "{ 0 0 128 0 1 0 128 }", NULL, { 8, "\x00\x81\x00\x00\x01\x00\x81\x00 " } } }; static char *invalid_strings[] = { "", "{}", "{", "}", " ", " { } ", "x", "+1 1", "-1.1", "1.+0", "+0.1", "{ 1 garbage }", "{ 1 }", "{ 0 40 }", "{ 1 40 }", "{ 1 128 }", "{ 1 1", "{ 1 2 3 4 +5 }", "{ 1.2.-3.4.5 }" }; static int oid_equal(gss_OID o1, gss_OID o2) { return o1->length == o2->length && memcmp(o1->elements, o2->elements, o1->length) == 0; } int main(void) { size_t i; OM_uint32 major, minor; gss_buffer_desc buf; gss_OID oid; gss_OID_set set; int status = 0, present; for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { /* Check that this test's OID converts to its canonical string form. */ major = gss_oid_to_str(&minor, &tests[i].oid, &buf); check_gsserr("gss_oid_to_str", major, minor); if (buf.length != strlen(tests[i].canonical) + 1 || memcmp(buf.value, tests[i].canonical, buf.length) != 0) { status = 1; printf("test %d: OID converts to %.*s, wanted %s\n", (int)i, (int)buf.length, (char *)buf.value, tests[i].canonical); } (void)gss_release_buffer(&minor, &buf); /* Check that this test's canonical string form converts to its OID. */ buf.value = tests[i].canonical; buf.length = strlen(tests[i].canonical); major = gss_str_to_oid(&minor, &buf, &oid); check_gsserr("gss_str_to_oid", major, minor); if (!oid_equal(oid, &tests[i].oid)) { status = 1; printf("test %d: %s converts to wrong OID\n", (int)i, tests[i].canonical); display_oid("wanted", &tests[i].oid); display_oid("actual", oid); } (void)gss_release_oid(&minor, &oid); /* Check that this test's variant string form converts to its OID. */ if (tests[i].variant == NULL) continue; buf.value = tests[i].variant; buf.length = strlen(tests[i].variant); major = gss_str_to_oid(&minor, &buf, &oid); check_gsserr("gss_str_to_oid", major, minor); if (!oid_equal(oid, &tests[i].oid)) { status = 1; printf("test %d: %s converts to wrong OID\n", (int)i, tests[i].variant); display_oid("wanted", &tests[i].oid); display_oid("actual", oid); } (void)gss_release_oid(&minor, &oid); } for (i = 0; i < sizeof(invalid_strings) / sizeof(*invalid_strings); i++) { buf.value = invalid_strings[i]; buf.length = strlen(invalid_strings[i]); major = gss_str_to_oid(&minor, &buf, &oid); if (major == GSS_S_COMPLETE) { status = 1; printf("invalid %d: %s converted when it should not have\n", (int)i, invalid_strings[i]); (void)gss_release_oid(&minor, &oid); } } major = gss_create_empty_oid_set(&minor, &set); check_gsserr("gss_create_empty_oid_set", major, minor); for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { major = gss_add_oid_set_member(&minor, &tests[i].oid, &set); check_gsserr("gss_add_oid_set_member", major, minor); } if (set->count != i) { status = 1; printf("oid set has wrong size: wanted %d, actual %d\n", (int)i, (int)set->count); } for (i = 0; i < set->count; i++) { if (!oid_equal(&set->elements[i], &tests[i].oid)) { status = 1; printf("oid set has wrong element %d\n", (int)i); display_oid("wanted", &tests[i].oid); display_oid("actual", &set->elements[i]); } major = gss_test_oid_set_member(&minor, &tests[i].oid, set, &present); check_gsserr("gss_test_oid_set_member", major, minor); if (!present) { status = 1; printf("oid set does not contain OID %d\n", (int)i); display_oid("wanted", &tests[i].oid); } } (void)gss_release_oid_set(&minor, &set); return status; } krb5-1.22.1/src/tests/gssapi/t_client_keytab.py0000775000175000017500000001745315051422640021307 0ustar ghudsonghudsonfrom k5test import * # Set up a basic realm and a client keytab containing two user principals. # Point HOME at realm.testdir for tests using .k5identity. realm = K5Realm(get_creds=False) bob = 'bob@' + realm.realm phost = 'p:' + realm.host_princ puser = 'p:' + realm.user_princ pbob = 'p:' + bob gssserver = 'h:host@' + hostname realm.env['HOME'] = realm.testdir realm.addprinc(bob, password('bob')) realm.extract_keytab(realm.user_princ, realm.client_keytab) realm.extract_keytab(bob, realm.client_keytab) # Test 1: no name/cache specified, pick first principal from client keytab realm.run(['./t_ccselect', phost], expected_msg=realm.user_princ) realm.run([kdestroy]) # Test 2: no name/cache specified, pick principal from k5identity k5idname = os.path.join(realm.testdir, '.k5identity') k5id = open(k5idname, 'w') k5id.write('%s service=host host=%s\n' % (bob, hostname)) k5id.close() realm.run(['./t_ccselect', gssserver], expected_msg=bob) os.remove(k5idname) realm.run([kdestroy]) # Test 3: no name/cache specified, default ccache has name but no creds realm.run(['./ccinit', realm.ccache, bob]) realm.run(['./t_ccselect', phost], expected_msg=bob) # Leave tickets for next test. # Test 4: name specified, non-collectable default cache doesn't match msg = 'Principal in credential cache does not match desired name' realm.run(['./t_ccselect', phost, puser], expected_code=1, expected_msg=msg) realm.run([kdestroy]) # Test 5: name specified, nonexistent default cache realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) # Leave tickets for next test. # Test 6: name specified, matches default cache, time to refresh realm.run(['./ccrefresh', realm.ccache, '1']) realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) out = realm.run(['./ccrefresh', realm.ccache]) if int(out) < 1000: fail('Credentials apparently not refreshed') realm.run([kdestroy]) # Test 7: empty ccache specified, pick first principal from client keytab realm.run(['./t_imp_cred', phost]) realm.klist(realm.user_princ) realm.run([kdestroy]) # Test 8: ccache specified with name but no creds; name not in client keytab realm.run(['./ccinit', realm.ccache, realm.host_princ]) realm.run(['./t_imp_cred', phost], expected_code=1, expected_msg='Credential cache is empty') realm.run([kdestroy]) # Test 9: ccache specified with name but no creds; name in client keytab realm.run(['./ccinit', realm.ccache, bob]) realm.run(['./t_imp_cred', phost]) realm.klist(bob) # Leave tickets for next test. # Test 10: ccache specified with creds, time to refresh realm.run(['./ccrefresh', realm.ccache, '1']) realm.run(['./t_imp_cred', phost]) realm.klist(bob) out = realm.run(['./ccrefresh', realm.ccache]) if int(out) < 1000: fail('Credentials apparently not refreshed') realm.run([kdestroy]) # Test 11: gss_import_cred_from with client_keytab value store_keytab = os.path.join(realm.testdir, 'store_keytab') os.rename(realm.client_keytab, store_keytab) realm.run(['./t_credstore', '-i', 'p:' + realm.user_princ, 'client_keytab', store_keytab]) realm.klist(realm.user_princ) os.rename(store_keytab, realm.client_keytab) # Use a cache collection for the remaining tests. ccdir = os.path.join(realm.testdir, 'cc') ccname = 'DIR:' + ccdir os.mkdir(ccdir) realm.env['KRB5CCNAME'] = ccname # Test 12: name specified, matching cache in collection with no creds bobcache = os.path.join(ccdir, 'tktbob') realm.run(['./ccinit', bobcache, bob]) realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) # Leave tickets for next test. # Test 13: name specified, matching cache in collection, time to refresh realm.run(['./ccrefresh', bobcache, '1']) realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) out = realm.run(['./ccrefresh', bobcache]) if int(out) < 1000: fail('Credentials apparently not refreshed') realm.run([kdestroy, '-A']) # Test 14: name specified, collection has default for different principal realm.kinit(realm.user_princ, password('user')) realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) msg = 'Default principal: %s\n' % realm.user_princ realm.run([klist], expected_msg=msg) realm.run([kdestroy, '-A']) # Test 15: name specified, collection has no default cache realm.run(['./t_ccselect', phost, pbob], expected_msg=bob) # Make sure the tickets we acquired didn't become the default realm.run([klist], expected_code=1, expected_msg='No credentials cache found') realm.run([kdestroy, '-A']) # Test 16: default client keytab cannot be resolved, but valid # credentials exist in ccache. conf = {'libdefaults': {'default_client_keytab_name': '%{'}} bad_cktname = realm.special_env('bad_cktname', False, krb5_conf=conf) del bad_cktname['KRB5_CLIENT_KTNAME'] realm.kinit(realm.user_princ, password('user')) realm.run(['./t_ccselect', phost], env=bad_cktname, expected_msg=realm.user_princ) mark('refresh of manually acquired creds') # Test 17: no name/ccache specified, manually acquired creds which # will expire soon. Verify that creds are refreshed using the current # client name, with refresh_time set in the refreshed ccache. realm.kinit('bob', password('bob'), ['-l', '15s']) realm.run(['./t_ccselect', phost], expected_msg='bob') realm.run([klist, '-C'], expected_msg='refresh_time = ') # Test 18: no name/ccache specified, manually acquired creds with a # client principal not present in the client keytab. A refresh is # attempted but fails, and an expired ticket error results. realm.kinit(realm.admin_princ, password('admin'), ['-l', '-10s']) msgs = ('Getting initial credentials for user/admin@KRBTEST.COM', '/Matching credential not found') realm.run(['./t_ccselect', phost], expected_code=1, expected_msg='Ticket expired', expected_trace=msgs) realm.run([kdestroy, '-A']) # Test 19: host-based initiator name mark('host-based initiator name') hsvc = 'h:svc@' + hostname svcprinc = 'svc/%s@%s' % (hostname, realm.realm) realm.addprinc(svcprinc) realm.extract_keytab(svcprinc, realm.client_keytab) # On the first run we match against the keytab while getting tickets, # substituting the default realm. msgs = ('/Can\'t find client principal svc/%s@ in' % hostname, 'Getting initial credentials for svc/%s@' % hostname, 'Found entries for %s in keytab' % svcprinc, 'Retrieving %s from FILE:%s' % (svcprinc, realm.client_keytab), 'Storing %s -> %s in' % (svcprinc, realm.krbtgt_princ), 'Retrieving %s -> %s from' % (svcprinc, realm.krbtgt_princ), 'authenticator for %s -> %s' % (svcprinc, realm.host_princ)) realm.run(['./t_ccselect', phost, hsvc], expected_trace=msgs) # On the second run we match against the collection. msgs = ('Matching svc/%s@ in collection with result: 0' % hostname, 'Getting credentials %s -> %s' % (svcprinc, realm.host_princ), 'authenticator for %s -> %s' % (svcprinc, realm.host_princ)) realm.run(['./t_ccselect', phost, hsvc], expected_trace=msgs) realm.run([kdestroy, '-A']) # Test 20: host-based initiator name with fallback mark('host-based fallback initiator name') canonname = canonicalize_hostname(hostname) if canonname != hostname: hfsvc = 'h:fsvc@' + hostname canonprinc = 'fsvc/%s@%s' % (canonname, realm.realm) realm.addprinc(canonprinc) realm.extract_keytab(canonprinc, realm.client_keytab) msgs = ('/Can\'t find client principal fsvc/%s@ in' % hostname, 'Found entries for %s in keytab' % canonprinc, 'authenticator for %s -> %s' % (canonprinc, realm.host_princ)) realm.run(['./t_ccselect', phost, hfsvc], expected_trace=msgs) msgs = ('Matching fsvc/%s@ in collection with result: 0' % hostname, 'Getting credentials %s -> %s' % (canonprinc, realm.host_princ)) realm.run(['./t_ccselect', phost, hfsvc], expected_trace=msgs) realm.run([kdestroy, '-A']) else: skipped('GSS initiator name fallback test', '%s does not canonicalize to a different name' % hostname) success('Client keytab tests') krb5-1.22.1/src/tests/gssapi/t_imp_name.c0000664000175000017500000000612415051422640020037 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1996, Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Simple test program for testing how GSSAPI import name works. (May * be made into a more full-fledged test program later.) */ #include #include #include "common.h" static const char * oid_str(char type) { switch (type) { case 'p': /* GSS_KRB5_NT_PRINCIPAL_NAME */ return "{ 1 2 840 113554 1 2 2 1 }"; case 'e': /* GSS_KRB5_NT_ENTERPRISE_NAME */ return "{ 1 2 840 113554 1 2 2 6 }"; case 'c': /* GSS_KRB5_NT_X509_CERT */ return "{ 1 2 840 113554 1 2 2 7 }"; case 'h': /* GSS_C_NT_HOSTBASED_SERVICE */ return "{ 1 2 840 113554 1 2 1 4 }"; } return "no_oid"; } /* Return true if buf has the same contents as str, plus a zero byte if * indicated by buf_includes_nullterm. */ static int buf_eq_str(gss_buffer_t buf, const char *str, int buf_includes_nullterm) { size_t len = strlen(str) + (buf_includes_nullterm ? 1 : 0); return (buf->length == len && memcmp(buf->value, str, len) == 0); } static void test_import_name(const char *name) { OM_uint32 major, minor; gss_name_t gss_name; gss_buffer_desc buf; gss_OID name_oid; gss_name = import_name(name); major = gss_display_name(&minor, gss_name, &buf, &name_oid); check_gsserr("gss_display_name", major, minor); if (!buf_eq_str(&buf, name + 2, 0)) errout("wrong name string"); (void)gss_release_buffer(&minor, &buf); major = gss_oid_to_str(&minor, name_oid, &buf); check_gsserr("gss_oid_to_str", major, minor); if (!buf_eq_str(&buf, oid_str(*name), 1)) errout("wrong name type"); (void)gss_release_buffer(&minor, &buf); (void)gss_release_name(&minor, &gss_name); } int main(int argc, char **argv) { test_import_name("p:user@MIT.EDU"); test_import_name("e:enterprise@mit.edu@MIT.EDU"); test_import_name("h:HOST@dc1.mit.edu"); return 0; } krb5-1.22.1/src/tests/gssapi/t_invalid.c0000664000175000017500000006455515051422640017714 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_invalid.c - Invalid message token regression tests */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file contains regression tests for some GSSAPI invalid token * vulnerabilities. * * 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a * null pointer dereference. (The token must use SEAL_ALG_NONE or it will * be rejected.) This vulnerability also applies to IOV unwrap. * * 2. A CFX wrap token with a different value of EC between the plaintext and * encrypted copies will be erroneously accepted, which allows a message * truncation attack. This vulnerability also applies to IOV unwrap. * * 3. A CFX wrap token with a plaintext length fewer than 16 bytes causes an * access before the beginning of the input buffer, possibly leading to a * crash. * * 4. A CFX wrap token with a plaintext EC value greater than the plaintext * length - 16 causes an integer underflow when computing the result length, * likely causing a crash. * * 5. An IOV unwrap operation will overrun the header buffer if an ASN.1 * wrapper longer than the header buffer is present. * * 6. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1 * header causes an input buffer overrun, usually leading to either a segv * or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or * sequence number values. This vulnerability also applies to IOV unwrap. * * 7. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1 * header causes an integer underflow when computing the ciphertext length, * leading to an allocation error on 32-bit platforms or a segv on 64-bit * platforms. A pre-CFX MIC token of this size causes an input buffer * overrun when comparing the checksum, perhaps leading to a segv. * * 8. A pre-CFX wrap token with fewer than conflen + padlen bytes in the * ciphertext (where padlen is the last byte of the decrypted ciphertext) * causes an integer underflow when computing the original message length, * leading to an allocation error. * * 9. In the mechglue, truncated encapsulation in the initial context token can * cause input buffer overruns in gss_accept_sec_context(). */ #include "k5-int.h" #include "common.h" #include "mglueP.h" #include "gssapiP_krb5.h" /* * The following samples contain: * - context parameters * - otherwise valid seal tokens where the plain text is padded with byte value * 100 instead of the proper value 1. * - valid MIC tokens for the message "message" * - two valid wrap tokens for the message "message", one without * confidentiality and one with */ struct test { krb5_enctype enctype; krb5_enctype encseq_enctype; int sealalg; int signalg; size_t cksum_size; size_t keylen; const char *keydata; size_t toklen; const char *token; size_t miclen; const char *mic; size_t wrap1len; const char *wrap1; size_t wrap2len; const char *wrap2; } tests[] = { { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_DES3_CBC_RAW, SEAL_ALG_DES3KD, SGN_ALG_HMAC_SHA1_DES3_KD, 20, 24, "\x4F\xEA\x19\x19\x5E\x0E\x10\xDF\x3D\x29\xB5\x13\x8F\x01\xC7\xA7" "\x92\x3D\x38\xF7\x26\x73\x0D\x6D", 65, "\x60\x3F\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x04" "\x00\x02\x00\xFF\xFF\xEB\xF3\x9A\x89\x24\x57\xB8\x63\x95\x25\xE8" "\x6E\x8E\x79\xE6\x2E\xCA\xD3\xFF\x57\x9F\x8C\xAB\xEF\xDD\x28\x10" "\x2F\x93\x21\x2E\xF2\x52\xB6\x6F\xA8\xBB\x8A\x6D\xAA\x6F\xB7\xF4\xD4", 49, "\x60\x2F\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x01\x01\x04" "\x00\xFF\xFF\xFF\xFF\x57\xF5\x77\xC6\xC0\x72\x26\x97\x00\x89\xB2" "\xEE\xD9\xD1\x90\xE7\x11\x50\x4F\xE9\x59\x18\xB1\x8F\x82\x8E\x8F\x5E", 65, "\x60\x3F\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x04" "\x00\xFF\xFF\xFF\xFF\x0B\x81\x56\x4A\x02\x1B\xBE\x83\x2B\x35\x08" "\x7B\x49\x15\x07\x97\x6A\x64\xEF\xDD\x32\x52\xF0\xA2\xE2\x62\x9B" "\xA7\x72\xF7\x3D\x6B\x2D\xAC\x21\xE9\x6D\x65\x73\x73\x61\x67\x65\x01", 65, "\x60\x3F\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x04" "\x00\x02\x00\xFF\xFF\x66\x5A\xE1\xC8\x4F\x69\x33\x97\x5D\x05\xE2" "\x86\x40\x14\x15\x14\x27\x01\x9F\x32\x9D\x82\xF4\xE1\xC5\x3E\xFA" "\x6D\x7D\x05\x39\xAE\x21\x44\xA0\x87\xA6\x24\xED\xFC\xA3\x53\xF1\x30" }, { ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC, SEAL_ALG_MICROSOFT_RC4, SGN_ALG_HMAC_MD5, 8, 16, "\x66\x64\x41\x64\x55\x78\x21\xD0\xD0\xFD\x05\x6A\xFF\x6F\xE8\x09", 53, "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x11" "\x00\x10\x00\xFF\xFF\x35\xD4\x79\xF3\x8C\x47\x8F\x6E\x23\x6F\x3E" "\xCC\x5E\x57\x5C\x6A\x89\xF0\xA2\x03\x4F\x0B\x51\x11\xEE\x89\x7E" "\xD6\xF6\xB5\xD6\x51", 37, "\x60\x23\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x01\x01\x11" "\x00\xFF\xFF\xFF\xFF\x5D\xE7\x51\xF6\xFB\x6C\x25\x5B\x23\x93\x5A" "\x30\x20\x57\xDC\xB5", 53, "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x11" "\x00\xFF\xFF\xFF\xFF\xAD\xB5\x1D\x01\x39\x7B\xA2\x16\x4C\x1B\x68" "\x18\xEC\xAC\xD9\xE5\x9E\xD1\x41\x7A\x89\xE8\xCB\x24\x6D\x65\x73" "\x73\x61\x67\x65\x01", 53, "\x60\x33\x06\x09\x2A\x86\x48\x86\xF7\x12\x01\x02\x02\x02\x01\x11" "\x00\x10\x00\xFF\xFF\xDD\x6D\x04\xEA\x64\x5C\xE7\x31\x50\xD0\x09" "\x44\x9E\x67\xA4\x30\xEC\xFB\xFF\xC0\xF7\x16\x1E\x14\x1A\x82\x42" "\xDD\x26\x23\x2B\x02" } }; static void * ealloc(size_t len) { void *ptr = calloc(len, 1); if (ptr == NULL) abort(); return ptr; } /* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. * The context takes ownership of subkey. */ static gss_ctx_id_t make_fake_cfx_context(krb5_key subkey) { gss_union_ctx_id_t uctx; krb5_gss_ctx_id_t kgctx; kgctx = ealloc(sizeof(*kgctx)); kgctx->established = 1; kgctx->proto = 1; if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0) abort(); kgctx->mech_used = &mech_krb5; kgctx->sealalg = -1; kgctx->signalg = -1; kgctx->subkey = subkey; kgctx->cksumtype = CKSUMTYPE_HMAC_SHA1_96_AES128; uctx = ealloc(sizeof(*uctx)); uctx->mech_type = &mech_krb5; uctx->internal_ctx_id = (gss_ctx_id_t)kgctx; return (gss_ctx_id_t)uctx; } /* Fake up enough of a GSS context for gss_unwrap, using keys from test. */ static gss_ctx_id_t make_fake_context(const struct test *test) { gss_union_ctx_id_t uctx; krb5_gss_ctx_id_t kgctx; krb5_keyblock kb; kgctx = ealloc(sizeof(*kgctx)); kgctx->established = 1; if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0) abort(); kgctx->mech_used = &mech_krb5; kgctx->sealalg = test->sealalg; kgctx->signalg = test->signalg; kgctx->cksum_size = test->cksum_size; kb.enctype = test->enctype; kb.length = test->keylen; kb.contents = (unsigned char *)test->keydata; if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0) abort(); kb.enctype = test->encseq_enctype; if (krb5_k_create_key(NULL, &kb, &kgctx->seq) != 0) abort(); if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0) abort(); uctx = ealloc(sizeof(*uctx)); uctx->mech_type = &mech_krb5; uctx->internal_ctx_id = (gss_ctx_id_t)kgctx; return (gss_ctx_id_t)uctx; } /* Free a context created by make_fake_context. */ static void free_fake_context(gss_ctx_id_t ctx) { gss_union_ctx_id_t uctx = (gss_union_ctx_id_t)ctx; krb5_gss_ctx_id_t kgctx = (krb5_gss_ctx_id_t)uctx->internal_ctx_id; free(kgctx->seqstate); krb5_k_free_key(NULL, kgctx->subkey); krb5_k_free_key(NULL, kgctx->seq); krb5_k_free_key(NULL, kgctx->enc); free(kgctx); free(uctx); } /* Prefix a token (starting at the two-byte ID) with an ASN.1 header and return * it in an allocated block to facilitate checking by valgrind or similar. */ static void make_token(unsigned char *token, size_t len, gss_buffer_t out) { char *wrapped; assert(mech_krb5.length == 9); assert(len + 11 < 128); wrapped = ealloc(len + 13); wrapped[0] = 0x60; wrapped[1] = len + 11; wrapped[2] = 0x06; wrapped[3] = 9; memcpy(wrapped + 4, mech_krb5.elements, 9); memcpy(wrapped + 13, token, len); out->length = len + 13; out->value = wrapped; } /* Create a 16-byte header for a CFX confidential wrap token to be processed by * the fake CFX context. */ static void write_cfx_header(uint16_t ec, uint8_t *out) { memset(out, 0, 16); store_16_be(KG2_TOK_WRAP_MSG, out); out[2] = FLAG_WRAP_CONFIDENTIAL; out[3] = 0xFF; store_16_be(ec, out + 4); } /* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with * regular and IOV unwrap. */ static void test_bogus_1964_token(gss_ctx_id_t ctx) { OM_uint32 minor, major; unsigned char tokbuf[128]; gss_buffer_desc in, out; gss_iov_buffer_desc iov; store_16_be(KG_TOK_SIGN_MSG, tokbuf); store_16_le(SGN_ALG_HMAC_MD5, tokbuf + 2); store_16_le(SEAL_ALG_NONE, tokbuf + 4); store_16_le(0xFFFF, tokbuf + 6); memset(tokbuf + 8, 0, 16); make_token(tokbuf, 24, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); (void)gss_release_buffer(&minor, &out); iov.type = GSS_IOV_BUFFER_TYPE_HEADER; iov.buffer = in; major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); } static void test_cfx_altered_ec(gss_ctx_id_t ctx, krb5_key subkey) { OM_uint32 major, minor; uint8_t tokbuf[128], plainbuf[24]; krb5_data plain; krb5_enc_data cipher; gss_buffer_desc in, out; gss_iov_buffer_desc iov[2]; /* Construct a header with a plaintext EC value of 3. */ write_cfx_header(3, tokbuf); /* Encrypt a plaintext and a copy of the header with the EC value 0. */ memcpy(plainbuf, "truncate", 8); memcpy(plainbuf + 8, tokbuf, 16); store_16_be(0, plainbuf + 12); plain = make_data(plainbuf, 24); cipher.ciphertext.data = (char *)tokbuf + 16; cipher.ciphertext.length = sizeof(tokbuf) - 16; cipher.enctype = subkey->keyblock.enctype; if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL, &plain, &cipher) != 0) abort(); /* Verify that the token is rejected by gss_unwrap(). */ in.value = tokbuf; in.length = 16 + cipher.ciphertext.length; major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); (void)gss_release_buffer(&minor, &out); /* Verify that the token is rejected by gss_unwrap_iov(). */ iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM; iov[0].buffer = in; iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); } static void test_cfx_short_plaintext(gss_ctx_id_t ctx, krb5_key subkey) { OM_uint32 major, minor; uint8_t tokbuf[128], zerobyte = 0; krb5_data plain; krb5_enc_data cipher; gss_buffer_desc in, out; write_cfx_header(0, tokbuf); /* Encrypt a single byte, with no copy of the header. */ plain = make_data(&zerobyte, 1); cipher.ciphertext.data = (char *)tokbuf + 16; cipher.ciphertext.length = sizeof(tokbuf) - 16; cipher.enctype = subkey->keyblock.enctype; if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL, &plain, &cipher) != 0) abort(); /* Verify that the token is rejected by gss_unwrap(). */ in.value = tokbuf; in.length = 16 + cipher.ciphertext.length; major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); (void)gss_release_buffer(&minor, &out); } static void test_cfx_large_ec(gss_ctx_id_t ctx, krb5_key subkey) { OM_uint32 major, minor; uint8_t tokbuf[128] = { 0 }, plainbuf[20]; krb5_data plain; krb5_enc_data cipher; gss_buffer_desc in, out; /* Construct a header with an EC value of 5. */ write_cfx_header(5, tokbuf); /* Encrypt a 4-byte plaintext plus the header. */ memcpy(plainbuf, "abcd", 4); memcpy(plainbuf + 4, tokbuf, 16); plain = make_data(plainbuf, 20); cipher.ciphertext.data = (char *)tokbuf + 16; cipher.ciphertext.length = sizeof(tokbuf) - 16; cipher.enctype = subkey->keyblock.enctype; if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL, &plain, &cipher) != 0) abort(); /* Verify that the token is rejected by gss_unwrap(). */ in.value = tokbuf; in.length = 16 + cipher.ciphertext.length; major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); (void)gss_release_buffer(&minor, &out); } static void test_iov_large_asn1_wrapper(gss_ctx_id_t ctx) { OM_uint32 minor, major; uint8_t databuf[10] = { 0 }; gss_iov_buffer_desc iov[2]; /* * In this IOV array, the header contains a DER tag with a dangling eight * bytes of length field. The data IOV indicates a total token length * sufficient to contain the length bytes. */ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER; iov[0].buffer.value = ealloc(2); iov[0].buffer.length = 2; memcpy(iov[0].buffer.value, "\x60\x88", 2); iov[1].type = GSS_IOV_BUFFER_TYPE_DATA; iov[1].buffer.value = databuf; iov[1].buffer.length = 10; major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(iov[0].buffer.value); } /* Verify that token is a valid MIC token for ctx and message, and that * changing any of the input bytes yields one of the expected errors. */ static void mictest(gss_ctx_id_t ctx, gss_buffer_t message, gss_buffer_t token) { OM_uint32 major, minor; size_t i; uint8_t *p; major = gss_verify_mic(&minor, ctx, message, token, NULL); check_gsserr("gss_verify_mic", major, minor); p = token->value; for (i = 0; i < token->length; i++) { /* Skip sequence number bytes for RC4. */ if (load_16_le(p + 15) == SGN_ALG_HMAC_MD5 && i >= 21 && i <= 24) continue; p[i]++; major = gss_verify_mic(&minor, ctx, message, token, NULL); if (major != GSS_S_DEFECTIVE_TOKEN && major != GSS_S_BAD_SIG) abort(); p[i]--; } p = message->value; for (i = 0; i < message->length; i++) { p[i]++; major = gss_verify_mic(&minor, ctx, message, token, NULL); if (major != GSS_S_DEFECTIVE_TOKEN && major != GSS_S_BAD_SIG) abort(); p[i]--; } } static void test_cfx_verify_mic(gss_ctx_id_t ctx) { gss_buffer_desc message, token; uint8_t msg[] = "message"; uint8_t mic[] = "\x04\x04\x00\xFF\xFF\xFF\xFF\xFF" "\x00\x00\x00\x00\x00\x00\x00\x00\x97\xE9\x63\x3F\x9D\x82\x2B\x74" "\x67\x94\x8A\xD0"; message.value = msg; message.length = sizeof(msg) - 1; token.value = mic; token.length = sizeof(mic) - 1; mictest(ctx, &message, &token); } static void test_verify_mic(gss_ctx_id_t ctx, const struct test *test) { gss_buffer_desc message, token; uint8_t msg[] = "message", buf[128]; assert(test->miclen <= sizeof(buf)); memcpy(buf, test->mic, test->miclen); message.value = msg; message.length = sizeof(msg) - 1; token.value = buf; token.length = test->miclen; mictest(ctx, &message, &token); } /* Verify that token is a valid wrap token for ctx unwrapping to message, and * that changing any of the token bytes yields one of the expected errors. */ static void unwraptest(gss_ctx_id_t ctx, gss_buffer_t message, gss_buffer_t token) { OM_uint32 major, minor; gss_buffer_desc unwrapped; size_t i; uint8_t *p; major = gss_unwrap(&minor, ctx, token, &unwrapped, NULL, NULL); check_gsserr("gss_unwrap", major, minor); if (unwrapped.length != message->length || memcmp(unwrapped.value, message->value, unwrapped.length) != 0) abort(); gss_release_buffer(&minor, &unwrapped); p = token->value; for (i = 0; i < token->length; i++) { /* Skip sequence number bytes for RC4. */ if (load_16_le(p + 15) == SGN_ALG_HMAC_MD5 && i >= 21 && i <= 24) continue; p[i]++; major = gss_unwrap(&minor, ctx, token, &unwrapped, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN && major != GSS_S_BAD_SIG) abort(); p[i]--; } } static void test_cfx_unwrap(gss_ctx_id_t ctx) { gss_buffer_desc message, token; uint8_t msg[] = "message"; uint8_t token1[] = "\x05\x04\x00\xFF\x00\x0C\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x6D\x65\x73\x73\x61\x67\x65\xDF" "\x57\xB9\x5E\xA2\xB1\x73\x31\xDB\xCE\x61\x62"; uint8_t token2[] = "\x05\x04\x02\xFF\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x72\xBB\xD7\xCF\xDE\xB0\xF9\x20" "\xE2\x9A\x98\xA7\xA4\xE7\xC9\x9B\x30\xD3\xFE\x61\x51\x2E\x1B\x56" "\x88\xB7\x8A\xF5\xA9\xBF\x8F\x82\xB1\xEB\xCC\x88\xE6\x33\x13\xBF" "\x52\x4B\xC0\x3B\x24\x3F\x3E\xF5\xF1\xE0\x64"; message.value = msg; message.length = sizeof(msg) - 1; token.value = token1; token.length = sizeof(token1) - 1; unwraptest(ctx, &message, &token); token.value = token2; token.length = sizeof(token2) - 1; unwraptest(ctx, &message, &token); } static void test_unwrap(gss_ctx_id_t ctx, const struct test *test) { gss_buffer_desc message, token; uint8_t msg[] = "message", buf[128]; assert(test->wrap1len <= sizeof(buf) && test->wrap2len <= sizeof(buf)); token.value = buf; message.value = msg; message.length = sizeof(msg) - 1; memcpy(buf, test->wrap1, test->wrap1len); token.length = test->wrap1len; unwraptest(ctx, &message, &token); memcpy(buf, test->wrap2, test->wrap2len); token.length = test->wrap2len; unwraptest(ctx, &message, &token); } /* Process wrap and MIC tokens with incomplete headers. */ static void test_short_header(gss_ctx_id_t ctx) { OM_uint32 minor, major; unsigned char tokbuf[128]; gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER; /* Seal token, 2-24 bytes */ store_16_be(KG_TOK_SEAL_MSG, tokbuf); make_token(tokbuf, 2, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); (void)gss_release_buffer(&minor, &out); /* Sign token, 2-24 bytes */ store_16_be(KG_TOK_SIGN_MSG, tokbuf); make_token(tokbuf, 2, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); (void)gss_release_buffer(&minor, &out); /* MIC token, 2-24 bytes */ store_16_be(KG_TOK_MIC_MSG, tokbuf); make_token(tokbuf, 2, &in); major = gss_verify_mic(&minor, ctx, &empty, &in, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); } /* Process wrap and MIC tokens with incomplete headers. */ static void test_short_header_iov(gss_ctx_id_t ctx, const struct test *test) { OM_uint32 minor, major; unsigned char tokbuf[128]; gss_iov_buffer_desc iov; /* IOV seal token, 16-23 bytes */ store_16_be(KG_TOK_SEAL_MSG, tokbuf); store_16_le(test->signalg, tokbuf + 2); store_16_le(test->sealalg, tokbuf + 4); store_16_be(0xFFFF, tokbuf + 6); memset(tokbuf + 8, 0, 8); iov.type = GSS_IOV_BUFFER_TYPE_HEADER; make_token(tokbuf, 16, &iov.buffer); major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(iov.buffer.value); /* IOV sign token, 16-23 bytes */ store_16_be(KG_TOK_SIGN_MSG, tokbuf); store_16_le(test->signalg, tokbuf + 2); store_16_le(SEAL_ALG_NONE, tokbuf + 4); store_16_le(0xFFFF, tokbuf + 6); memset(tokbuf + 8, 0, 8); iov.type = GSS_IOV_BUFFER_TYPE_HEADER; make_token(tokbuf, 16, &iov.buffer); major = gss_unwrap_iov(&minor, ctx, NULL, NULL, &iov, 1); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(iov.buffer.value); /* IOV MIC token, 16-23 bytes */ store_16_be(KG_TOK_MIC_MSG, tokbuf); store_16_be(test->signalg, tokbuf + 2); store_16_le(SEAL_ALG_NONE, tokbuf + 4); store_16_le(0xFFFF, tokbuf + 6); memset(tokbuf + 8, 0, 8); iov.type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN; make_token(tokbuf, 16, &iov.buffer); major = gss_verify_mic_iov(&minor, ctx, NULL, &iov, 1); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(iov.buffer.value); } /* Process wrap and MIC tokens with incomplete checksums. */ static void test_short_checksum(gss_ctx_id_t ctx, const struct test *test) { OM_uint32 minor, major; unsigned char tokbuf[128]; gss_buffer_desc in, out, empty = GSS_C_EMPTY_BUFFER; /* Can only do this with the DES3 checksum, as we can't easily get past * retrieving the sequence number when the checksum is only eight bytes. */ if (test->cksum_size <= 8) return; /* Seal token, fewer than 16 + cksum_size bytes. Use the token from the * test data to get a valid sequence number. */ make_token((unsigned char *)test->token + 13, 24, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); (void)gss_release_buffer(&minor, &out); /* Sign token, fewer than 16 + cksum_size bytes. */ memcpy(tokbuf, test->token + 13, 24); store_16_be(KG_TOK_SIGN_MSG, tokbuf); store_16_le(SEAL_ALG_NONE, tokbuf + 4); make_token(tokbuf, 24, &in); major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); (void)gss_release_buffer(&minor, &out); /* MIC token, fewer than 16 + cksum_size bytes. */ memcpy(tokbuf, test->token + 13, 24); store_16_be(KG_TOK_MIC_MSG, tokbuf); store_16_le(SEAL_ALG_NONE, tokbuf + 4); make_token(tokbuf, 24, &in); major = gss_verify_mic(&minor, ctx, &empty, &in, NULL); if (major != GSS_S_DEFECTIVE_TOKEN) abort(); free(in.value); } /* Unwrap a token with a bogus padding byte in the decrypted ciphertext. */ static void test_bad_pad(gss_ctx_id_t ctx, const struct test *test) { OM_uint32 minor, major; gss_buffer_desc in, out; in.length = test->toklen; in.value = (char *)test->token; major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL); if (major != GSS_S_BAD_SIG) abort(); (void)gss_release_buffer(&minor, &out); } static void try_accept(void *value, size_t len) { OM_uint32 minor; gss_buffer_desc in, out; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; /* Copy the provided value to make input overruns more obvious. */ in.value = ealloc(len); memcpy(in.value, value, len); in.length = len; (void)gss_accept_sec_context(&minor, &ctx, GSS_C_NO_CREDENTIAL, &in, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &out, NULL, NULL, NULL); gss_release_buffer(&minor, &out); gss_delete_sec_context(&minor, &ctx, GSS_C_NO_BUFFER); free(in.value); } /* Accept contexts using superficially valid but truncated encapsulations. */ static void test_short_encapsulation(void) { /* Include just the initial application tag, to see if we overrun reading * the sequence length. */ try_accept("\x60", 1); /* Indicate four additional sequence length bytes, to see if we overrun * reading them (or skipping them and reading the next byte). */ try_accept("\x60\x84", 2); /* Include an object identifier tag but no length, to see if we overrun * reading the length. */ try_accept("\x60\x40\x06", 3); /* Include an object identifier tag with a length matching the krb5 mech, * but no OID bytes, to see if we overrun comparing against mechs. */ try_accept("\x60\x40\x06\x09", 4); } int main(int argc, char **argv) { krb5_keyblock kb; krb5_key cfx_subkey; gss_ctx_id_t ctx; size_t i; kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; kb.length = 16; kb.contents = (unsigned char *)"1234567887654321"; if (krb5_k_create_key(NULL, &kb, &cfx_subkey) != 0) abort(); ctx = make_fake_cfx_context(cfx_subkey); test_bogus_1964_token(ctx); test_cfx_altered_ec(ctx, cfx_subkey); test_cfx_short_plaintext(ctx, cfx_subkey); test_cfx_large_ec(ctx, cfx_subkey); test_iov_large_asn1_wrapper(ctx); test_cfx_verify_mic(ctx); test_cfx_unwrap(ctx); free_fake_context(ctx); for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { ctx = make_fake_context(&tests[i]); test_short_header(ctx); test_short_header_iov(ctx, &tests[i]); test_short_checksum(ctx, &tests[i]); test_bad_pad(ctx, &tests[i]); test_verify_mic(ctx, &tests[i]); test_unwrap(ctx, &tests[i]); free_fake_context(ctx); } test_short_encapsulation(); return 0; } krb5-1.22.1/src/tests/gssapi/t_bindings.c0000664000175000017500000001061615051422640020050 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2020 by Red Hat, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "common.h" /* * Establish contexts (without and with GSS_C_DCE_STYLE) with the default * initiator name, a specified principal name as target name, initiator * bindings, and acceptor bindings. If any call is unsuccessful, display an * error message. Output "yes" or "no" to indicate whether the contexts were * reported as channel-bound on the acceptor. Exit with status 0 if all * operations are successful, or 1 if not. * * Usage: ./t_bindings [-s] [-b] targetname icb acb * * An icb or abc value of "-" will not specify channel bindings. The -s flag * uses the SPNEGO mechanism instead of the krb5 mecanism. The -b flag * includes GSS_C_CHANNEL_BOUND in req_flags, which requests strict enforcement * of channel bindings by the acceptor. */ int main(int argc, char *argv[]) { OM_uint32 client_flags = 0; OM_uint32 minor, flags1, flags2; gss_name_t target_name; gss_ctx_id_t ictx, actx; struct gss_channel_bindings_struct icb_data = {0}, acb_data = {0}; gss_channel_bindings_t icb = GSS_C_NO_CHANNEL_BINDINGS; gss_channel_bindings_t acb = GSS_C_NO_CHANNEL_BINDINGS; gss_OID_desc *mech = GSS_C_NO_OID; argv++; argc--; if (*argv != NULL && strcmp(*argv, "-s") == 0) { mech = &mech_spnego; argv++; argc--; } if (*argv != NULL && strcmp(*argv, "-b") == 0) { client_flags |= GSS_C_CHANNEL_BOUND_FLAG; argv++; argc--; } if (mech == GSS_C_NO_OID) mech = &mech_krb5; if (argc != 3) { fprintf(stderr, "Usage: t_bindings [-s] [-b] targetname icb acb\n"); return 1; } target_name = import_name(argv[0]); if (strcmp(argv[1], "-") != 0) { icb_data.application_data.length = strlen(argv[1]); icb_data.application_data.value = argv[1]; icb = &icb_data; } if (strcmp(argv[2], "-") != 0) { acb_data.application_data.length = strlen(argv[2]); acb_data.application_data.value = argv[2]; acb = &acb_data; } establish_contexts_ex(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, target_name, client_flags, &ictx, &actx, icb, acb, &flags1, NULL, NULL, NULL); /* Try again with GSS_C_DCE_STYLE */ (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); client_flags |= GSS_C_DCE_STYLE; establish_contexts_ex(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, target_name, client_flags, &ictx, &actx, icb, acb, &flags2, NULL, NULL, NULL); assert((flags1 & GSS_C_CHANNEL_BOUND_FLAG) == (flags2 & GSS_C_CHANNEL_BOUND_FLAG)); printf("%s\n", (flags1 & GSS_C_CHANNEL_BOUND_FLAG) ? "yes" : "no"); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); (void)gss_release_name(&minor, &target_name); return 0; } krb5-1.22.1/src/tests/gssapi/t_namingexts.c0000664000175000017500000001657015051422640020435 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include "common.h" static int use_spnego = 0; static void display_name(const char *tag, gss_name_t name) { OM_uint32 major, minor; gss_buffer_desc buf; major = gss_display_name(&minor, name, &buf, NULL); check_gsserr("gss_display_name", major, minor); printf("%s:\t%.*s\n", tag, (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&minor, &buf); } static void test_export_import_name(gss_name_t name) { OM_uint32 major, minor; gss_buffer_desc exported_name = GSS_C_EMPTY_BUFFER; gss_name_t imported_name = GSS_C_NO_NAME; gss_name_t imported_name_comp = GSS_C_NO_NAME; unsigned int i; major = gss_export_name_composite(&minor, name, &exported_name); check_gsserr("gss_export_name_composite", major, minor); printf("Exported name:\n"); for (i = 0; i < exported_name.length; i++) { if ((i % 32) == 0) printf("\n"); printf("%02x", ((char *)exported_name.value)[i] & 0xFF); } printf("\n"); major = gss_import_name(&minor, &exported_name, GSS_C_NT_EXPORT_NAME, &imported_name); check_gsserr("gss_import_name", major, minor); major = gss_import_name(&minor, &exported_name, GSS_C_NT_COMPOSITE_EXPORT, &imported_name_comp); check_gsserr("gss_import_name", major, minor); (void)gss_release_buffer(&minor, &exported_name); printf("\n"); display_canon_name("Re-imported name", imported_name, &mech_krb5); printf("Re-imported attributes:\n\n"); enumerate_attributes(imported_name, 0); display_name("Re-imported (as composite) name", imported_name_comp); printf("Re-imported (as composite) attributes:\n\n"); enumerate_attributes(imported_name_comp, 0); (void)gss_release_name(&minor, &imported_name); (void)gss_release_name(&minor, &imported_name_comp); } static void test_greet_authz_data(gss_name_t name) { OM_uint32 major, minor; gss_buffer_desc attr; gss_buffer_desc value; attr.value = "urn:greet:greeting"; attr.length = strlen((char *)attr.value); major = gss_delete_name_attribute(&minor, name, &attr); if (major == GSS_S_UNAVAILABLE) { fprintf(stderr, "Warning: greet_client plugin not installed\n"); exit(1); } check_gsserr("gss_delete_name_attribute", major, minor); value.value = "Hello, acceptor world!"; value.length = strlen((char *)value.value); major = gss_set_name_attribute(&minor, name, 1, &attr, &value); if (major == GSS_S_UNAVAILABLE) return; check_gsserr("gss_set_name_attribute", major, minor); } static void test_map_name_to_any(gss_name_t name) { OM_uint32 major, minor; gss_buffer_desc type_id; krb5_pac pac; krb5_context context = NULL; krb5_error_code ret; size_t len, i; krb5_ui_4 *types; type_id.value = "mspac"; type_id.length = strlen((char *)type_id.value); major = gss_map_name_to_any(&minor, name, 1, &type_id, (gss_any_t *)&pac); if (major == GSS_S_UNAVAILABLE) return; check_gsserr("gss_map_name_to_any", major, minor); ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); if (krb5_pac_get_types(context, pac, &len, &types) == 0) { printf("PAC buffer types:"); for (i = 0; i < len; i++) printf(" %d", types[i]); printf("\n"); free(types); } (void)gss_release_any_name_mapping(&minor, name, &type_id, (gss_any_t *)&pac); } static void init_accept_sec_context(gss_cred_id_t verifier_cred_handle) { OM_uint32 major, minor, flags; gss_name_t source_name = GSS_C_NO_NAME, target_name = GSS_C_NO_NAME; gss_ctx_id_t initiator_context, acceptor_context; gss_OID mech = use_spnego ? &mech_spnego : &mech_krb5; major = gss_inquire_cred(&minor, verifier_cred_handle, &target_name, NULL, NULL, NULL); check_gsserr("gss_inquire_cred", major, minor); display_canon_name("Target name", target_name, &mech_krb5); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(mech, verifier_cred_handle, verifier_cred_handle, target_name, flags, &initiator_context, &acceptor_context, &source_name, NULL, NULL); display_canon_name("Source name", source_name, &mech_krb5); enumerate_attributes(source_name, 1); test_export_import_name(source_name); test_map_name_to_any(source_name); (void)gss_release_name(&minor, &source_name); (void)gss_release_name(&minor, &target_name); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL; gss_OID_set mechs, actual_mechs = GSS_C_NO_OID_SET; gss_name_t tmp_name, name; if (argc > 1 && strcmp(argv[1], "--spnego") == 0) { use_spnego++; argc--; argv++; } if (argc < 2) { fprintf(stderr, "Usage: %s [--spnego] principal [keytab]\n", argv[0]); exit(1); } tmp_name = import_name(argv[1]); major = gss_canonicalize_name(&minor, tmp_name, &mech_krb5, &name); check_gsserr("gss_canonicalze_name", major, minor); (void)gss_release_name(&minor, &tmp_name); test_greet_authz_data(name); if (argc >= 3) { major = krb5_gss_register_acceptor_identity(argv[2]); check_gsserr("krb5_gss_register_acceptor_identity", major, minor); } mechs = use_spnego ? &mechset_spnego : &mechset_krb5; /* get default cred */ major = gss_acquire_cred(&minor, name, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, &cred_handle, &actual_mechs, NULL); check_gsserr("gss_acquire_cred", major, minor); (void)gss_release_oid_set(&minor, &actual_mechs); init_accept_sec_context(cred_handle); printf("\n"); (void)gss_release_cred(&minor, &cred_handle); (void)gss_release_oid_set(&minor, &actual_mechs); (void)gss_release_name(&minor, &name); return 0; } krb5-1.22.1/src/tests/gssapi/t_prf.c0000664000175000017500000001742715051422640017051 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2014 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "k5-hex.h" #include "common.h" #include "mglueP.h" #include "gssapiP_krb5.h" static const char inputstr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz123456789"; /* For each test, out1 corresponds to key1 with an empty input, and out2 * corresponds to key2 with the above 61-byte input string. */ static struct { krb5_enctype enctype; const char *key1; const char *out1; const char *key2; const char *out2; } tests[] = { { ENCTYPE_DES3_CBC_SHA1, "70378A19CD64134580C27C0115D6B34A1CF2FEECEF9886A2", "9F8D127C520BB826BFF3E0FE5EF352389C17E0C073D9" "AC4A333D644D21BA3EF24F4A886D143F85AC9F6377FB", "3452A167DF1094BA1089E0A20E9E51ABEF1525922558B69E", "6BF24FABC858F8DD9752E4FCD331BB831F238B5BE190" "4EEA42E38F7A60C588F075C5C96A67E7F8B7BD0AECF4" }, { ENCTYPE_ARCFOUR_HMAC, "3BB3AE288C12B3B9D06B208A4151B3B6", "9AEA11A3BCF3C53F1F91F5A0BA2132E2501ADF5F3C28" "3C8A983AB88757CE865A22132D6100EAD63E9E291AFA", "6DB7B33A01BD2B72F7655CB7B3D5FA0B", "CDA9A544869FC84873B692663A82AFDA101C8611498B" "A46138B01E927C9B95EEC953B562807434037837DDDF" }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "6C742096EB896230312B73972FA28B5D", "94208D982FC1BB7778128BDD77904420B45C9DA699F3" "117BCE66E39602128EF0296611A6D191A5828530F20F", "FA61138C109D834A477D24C7311BE6DA", "0FAEDF0F842CC834FEE750487E1B622739286B975FE5" "B7F45AB053143C75CA0DF5D3D4BBB80F6A616C7C9027" }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "08FCDAFD5832611B73BA7B497FEBFF8C954B4B58031CAD9B977C3B8C25192FD6", "E627EFC14EF5B6D629F830C7109DEA0D3D7D36E8CD57" "A1F301C5452494A1928F05AFFBEE3360232209D3BE0D", "F5B68B7823D8944F33F41541B4E4D38C9B2934F8D16334A796645B066152B4BE", "112F2B2D878590653CCC7DE278E9F0AA46FA5A380B62" "59F774CB7C134FCD37F61A50FD0D9F89BF8FE1A6B593" }, { ENCTYPE_CAMELLIA128_CTS_CMAC, "866E0466A178279A32AC0BDA92B72AEB", "97FBB354BF341C3A160DCC86A7A910FDA824601DF677" "68797BACEEBF5D250AE929DEC9760772084267F50A54", "D4893FD37DA1A211E12DD1E03E0F03B7", "1DEE2FF126CA563A2A2326B9DD3F0095013257414C83" "FAD4398901013D55F367C82681186B7B2FE62F746BA4" }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "203071B1AE77BD3D6FCE70174AF95C225B1CED46B35CF52B6479EFEB47E6B063", "9B30020634C10FDA28420CEE7B96B70A90A771CED43A" "D8346554163E5949CBAE2FB8EF36AFB6B32CE75116A0", "A171AD582C1AFBBAD52ABD622EE6B6A14D19BF95C6914B2BA40FFD99A88EC660", "A47CBB6E104DCC77E4DB48A7A474B977F2FB6A7A1AB6" "52317D50508AE72B7BE2E4E4BA24164E029CBACF786B" }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, "089BCA48B105EA6EA77CA5D2F39DC5E7", "ED1736209B7C59C9F6A3AE8CCC8A7C97ADFDD11688AD" "F304F2F74252CBACD311A2D9253211FDA49745CE4F62", "3705D96080C17728A0E800EAB6E0D23C", "2BB41B183D76D8D5B30CBB049A7EFE9F350EFA058DC2" "C4D868308D354A7B199BE6FD1F22B53C038BC6036581" }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, "45BD806DBF6A833A9CFFC1C94589A222367A79BC21C413718906E9F578A78467", "1C613AE8B77A3B4D783F3DCE6C9178FC025E87F48A44" "784A69CB5FC697FE266A6141905067EF78566D309085", "6D404D37FAF79F9DF0D33568D320669800EB4836472EA8A026D16B7182460C52", "D15944B0A44508D1E61213F6455F292A02298F870C01" "A3F74AD0345A4A6651EBE101976E933F32D44F0B5947" }, }; /* Decode hexstr into out. No length checking. */ static size_t fromhex(const char *hexstr, unsigned char *out) { uint8_t *bytes; size_t len; if (k5_hex_decode(hexstr, &bytes, &len) != 0) abort(); memcpy(out, bytes, len); free(bytes); return len; } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_ctx_id_t context; gss_union_ctx_id_desc uctx; krb5_gss_ctx_id_rec kgctx; krb5_key k1, k2; krb5_keyblock kb1, kb2; gss_buffer_desc in, out; unsigned char k1buf[32], k2buf[32], outbuf[44]; size_t i; /* * Fake up just enough of a krb5 GSS context to make gss_pseudo_random * work, with chosen subkeys and acceptor subkeys. If we implement * gss_import_lucid_sec_context, we can rewrite this to use public * interfaces and stop using private headers and internal knowledge of the * implementation. */ context = (gss_ctx_id_t)&uctx; memset(&uctx, 0, sizeof(uctx)); uctx.mech_type = &mech_krb5; uctx.internal_ctx_id = (gss_ctx_id_t)&kgctx; memset(&kgctx, 0, sizeof(kgctx)); kgctx.k5_context = NULL; kgctx.established = 1; kgctx.have_acceptor_subkey = 1; kb1.contents = k1buf; kb2.contents = k2buf; for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { /* Set up the keys for this test. */ kb1.enctype = tests[i].enctype; kb1.length = fromhex(tests[i].key1, k1buf); check_k5err(NULL, "create_key", krb5_k_create_key(NULL, &kb1, &k1)); kgctx.subkey = k1; kb2.enctype = tests[i].enctype; kb2.length = fromhex(tests[i].key2, k2buf); check_k5err(NULL, "create_key", krb5_k_create_key(NULL, &kb2, &k2)); kgctx.acceptor_subkey = k2; /* Generate a PRF value with the subkey and an empty input, and compare * it to the first expected output. */ in.length = 0; in.value = NULL; major = gss_pseudo_random(&minor, context, GSS_C_PRF_KEY_PARTIAL, &in, 44, &out); check_gsserr("gss_pseudo_random", major, minor); (void)fromhex(tests[i].out1, outbuf); assert(out.length == 44 && memcmp(out.value, outbuf, 44) == 0); (void)gss_release_buffer(&minor, &out); /* Generate a PRF value with the acceptor subkey and the 61-byte input * string, and compare it to the second expected output. */ in.length = strlen(inputstr); in.value = (char *)inputstr; major = gss_pseudo_random(&minor, context, GSS_C_PRF_KEY_FULL, &in, 44, &out); check_gsserr("gss_pseudo_random", major, minor); (void)fromhex(tests[i].out2, outbuf); assert(out.length == 44 && memcmp(out.value, outbuf, 44) == 0); (void)gss_release_buffer(&minor, &out); /* Also check that generating zero bytes of output works. */ major = gss_pseudo_random(&minor, context, GSS_C_PRF_KEY_FULL, &in, 0, &out); check_gsserr("gss_pseudo_random", major, minor); assert(out.length == 0); (void)gss_release_buffer(&minor, &out); krb5_k_free_key(NULL, k1); krb5_k_free_key(NULL, k2); } return 0; } krb5-1.22.1/src/tests/gssapi/t_imp_cred.c0000664000175000017500000000773415051422640020044 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_imp_cred.c - krb5_gss_import_cred test harness */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test program for krb5_gss_import_cred, intended to be run from a Python test * script. Creates an initiator credential for the default ccache and an * acceptor principal for the default keytab (possibly using a specified keytab * principal), and performs a one-token context exchange using a specified * target principal. If the exchange is successful, queries the context for * the acceptor name and prints it. If any call is unsuccessful, displays an * error message. Exits with status 0 if all operations are successful, or 1 * if not. * * Usage: ./t_imp_cred target-princ [keytab-princ] */ #include "k5-platform.h" #include #include "common.h" int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_cred_id_t initiator_cred, acceptor_cred; gss_ctx_id_t initiator_context, acceptor_context; gss_name_t target_name; krb5_context context = NULL; krb5_ccache cc; krb5_keytab kt; krb5_principal princ = NULL; krb5_error_code ret; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s targetname [acceptorprinc]\n", argv[0]); return 1; } /* Import the target name. */ target_name = import_name(argv[1]); /* Acquire the krb5 objects we need. */ ret = krb5_init_context(&context); check_k5err(context, "krb5_init_context", ret); ret = krb5_cc_default(context, &cc); check_k5err(context, "krb5_cc_default", ret); ret = krb5_kt_default(context, &kt); check_k5err(context, "krb5_kt_default", ret); if (argc >= 3) { ret = krb5_parse_name(context, argv[2], &princ); check_k5err(context, "krb5_parse_name", ret); } /* Get initiator cred. */ major = gss_krb5_import_cred(&minor, cc, NULL, NULL, &initiator_cred); check_gsserr("gss_krb5_import_cred (initiator)", major, minor); /* Get acceptor cred. */ major = gss_krb5_import_cred(&minor, NULL, princ, kt, &acceptor_cred); check_gsserr("gss_krb5_import_cred (acceptor)", major, minor); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_krb5, initiator_cred, acceptor_cred, target_name, flags, &initiator_context, &acceptor_context, NULL, NULL, NULL); krb5_cc_close(context, cc); krb5_kt_close(context, kt); krb5_free_principal(context, princ); krb5_free_context(context); (void)gss_release_name(&minor, &target_name); (void)gss_release_cred(&minor, &initiator_cred); (void)gss_release_cred(&minor, &acceptor_cred); (void)gss_delete_sec_context(&minor, &initiator_context, NULL); (void)gss_delete_sec_context(&minor, &acceptor_context, NULL); return 0; } krb5-1.22.1/src/tests/gssapi/common.c0000664000175000017500000002204515051422640017217 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/common.c - Common utility functions for GSSAPI test programs */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "common.h" gss_OID_desc mech_krb5 = { 9, "\052\206\110\206\367\022\001\002\002" }; gss_OID_desc mech_spnego = { 6, "\053\006\001\005\005\002" }; gss_OID_desc mech_iakerb = { 6, "\053\006\001\005\002\005" }; gss_OID_set_desc mechset_krb5 = { 1, &mech_krb5 }; gss_OID_set_desc mechset_spnego = { 1, &mech_spnego }; gss_OID_set_desc mechset_iakerb = { 1, &mech_iakerb }; static void display_status(const char *msg, OM_uint32 code, int type) { OM_uint32 min_stat, msg_ctx = 0; gss_buffer_desc buf; do { (void)gss_display_status(&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &buf); fprintf(stderr, "%s: %.*s\n", msg, (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&min_stat, &buf); } while (msg_ctx != 0); } void check_gsserr(const char *msg, OM_uint32 major, OM_uint32 minor) { if (GSS_ERROR(major)) { display_status(msg, major, GSS_C_GSS_CODE); display_status(msg, minor, GSS_C_MECH_CODE); exit(1); } } void check_k5err(krb5_context context, const char *msg, krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(context, code); printf("%s: %s\n", msg, errmsg); krb5_free_error_message(context, errmsg); exit(1); } } void errout(const char *msg) { fprintf(stderr, "%s\n", msg); exit(1); } gss_name_t import_name(const char *str) { OM_uint32 major, minor; gss_name_t name; gss_buffer_desc buf; gss_OID nametype = NULL; if (*str == 'u') nametype = GSS_C_NT_USER_NAME; else if (*str == 'p') nametype = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME; else if (*str == 'e') nametype = (gss_OID)GSS_KRB5_NT_ENTERPRISE_NAME; else if (*str == 'c') nametype = (gss_OID)GSS_KRB5_NT_X509_CERT; else if (*str == 'h') nametype = GSS_C_NT_HOSTBASED_SERVICE; if (nametype == NULL || str[1] != ':') errout("names must begin with u: or p: or e: or c: or h:"); buf.value = (char *)str + 2; buf.length = strlen(str) - 2; major = gss_import_name(&minor, &buf, nametype, &name); check_gsserr("gss_import_name", major, minor); return name; } void establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx, gss_ctx_id_t *actx, gss_name_t *src_name, gss_OID *amech, gss_cred_id_t *deleg_cred) { establish_contexts_ex(imech, icred, acred, tname, flags, ictx, actx, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_CHANNEL_BINDINGS, NULL, src_name, amech, deleg_cred); } void establish_contexts_ex(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred, gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx, gss_ctx_id_t *actx, gss_channel_bindings_t icb, gss_channel_bindings_t acb, OM_uint32 *aret_flags, gss_name_t *src_name, gss_OID *amech, gss_cred_id_t *deleg_cred) { OM_uint32 minor, imaj, amaj; gss_buffer_desc itok, atok; *ictx = *actx = GSS_C_NO_CONTEXT; imaj = amaj = GSS_S_CONTINUE_NEEDED; itok.value = atok.value = NULL; itok.length = atok.length = 0; for (;;) { (void)gss_release_buffer(&minor, &itok); imaj = gss_init_sec_context(&minor, icred, ictx, tname, imech, flags, GSS_C_INDEFINITE, icb, &atok, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context", imaj, minor); if (amaj == GSS_S_COMPLETE) break; (void)gss_release_buffer(&minor, &atok); amaj = gss_accept_sec_context(&minor, actx, acred, &itok, acb, src_name, amech, &atok, aret_flags, NULL, deleg_cred); check_gsserr("gss_accept_sec_context", amaj, minor); (void)gss_release_buffer(&minor, &itok); if (imaj == GSS_S_COMPLETE) break; } if (imaj != GSS_S_COMPLETE || amaj != GSS_S_COMPLETE) errout("One side wants to continue after the other is done"); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); } void export_import_cred(gss_cred_id_t *cred) { OM_uint32 major, minor; gss_buffer_desc buf; major = gss_export_cred(&minor, *cred, &buf); check_gsserr("gss_export_cred", major, minor); (void)gss_release_cred(&minor, cred); major = gss_import_cred(&minor, &buf, cred); check_gsserr("gss_import_cred", major, minor); (void)gss_release_buffer(&minor, &buf); } void display_canon_name(const char *tag, gss_name_t name, gss_OID mech) { gss_name_t canon; OM_uint32 major, minor; gss_buffer_desc buf; major = gss_canonicalize_name(&minor, name, mech, &canon); check_gsserr("gss_canonicalize_name", major, minor); major = gss_display_name(&minor, canon, &buf, NULL); check_gsserr("gss_display_name", major, minor); printf("%s:\t%.*s\n", tag, (int)buf.length, (char *)buf.value); (void)gss_release_name(&minor, &canon); (void)gss_release_buffer(&minor, &buf); } void display_oid(const char *tag, gss_OID oid) { OM_uint32 major, minor; gss_buffer_desc buf; major = gss_oid_to_str(&minor, oid, &buf); check_gsserr("gss_oid_to_str", major, minor); if (tag != NULL) printf("%s:\t", tag); printf("%.*s\n", (int)buf.length, (char *)buf.value); (void)gss_release_buffer(&minor, &buf); } static void dump_attribute(gss_name_t name, gss_buffer_t attribute, int noisy) { OM_uint32 major, minor; gss_buffer_desc value; gss_buffer_desc display_value; int authenticated = 0; int complete = 0; int more = -1; unsigned int i; while (more != 0) { value.value = NULL; display_value.value = NULL; major = gss_get_name_attribute(&minor, name, attribute, &authenticated, &complete, &value, &display_value, &more); check_gsserr("gss_get_name_attribute", major, minor); printf("Attribute %.*s %s %s\n\n%.*s\n", (int)attribute->length, (char *)attribute->value, authenticated ? "Authenticated" : "", complete ? "Complete" : "", (int)display_value.length, (char *)display_value.value); if (noisy) { for (i = 0; i < value.length; i++) { if ((i % 32) == 0) printf("\n"); printf("%02x", ((char *)value.value)[i] & 0xFF); } printf("\n\n"); } (void)gss_release_buffer(&minor, &value); (void)gss_release_buffer(&minor, &display_value); } } void enumerate_attributes(gss_name_t name, int noisy) { OM_uint32 major, minor; int is_mechname; gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET; size_t i; major = gss_inquire_name(&minor, name, &is_mechname, NULL, &attrs); check_gsserr("gss_inquire_name", major, minor); if (attrs != GSS_C_NO_BUFFER_SET) { for (i = 0; i < attrs->count; i++) dump_attribute(name, &attrs->elements[i], noisy); } (void)gss_release_buffer_set(&minor, &attrs); } void print_hex(FILE *fp, gss_buffer_t buf) { size_t i; const unsigned char *bytes = buf->value; for (i = 0; i < buf->length; i++) printf("%02X", bytes[i]); printf("\n"); } krb5-1.22.1/src/tests/gssapi/t_add_cred.c0000664000175000017500000001411115051422640017772 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_add_cred.c - gss_add_cred() tests */ /* * Copyright (C) 2018 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program tests the mechglue behavior of gss_add_cred(). It relies on a * krb5 keytab and credentials being present so that initiator and acceptor * credentials can be acquired, but does not use them to initiate or accept any * requests. */ #include #include #include "common.h" int main(void) { OM_uint32 minor, major; gss_cred_id_t cred1, cred2; gss_cred_usage_t usage; gss_name_t name; /* Check that we get the expected error if we pass neither an input nor an * output cred handle. */ major = gss_add_cred(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, &mech_krb5, GSS_C_INITIATE, GSS_C_INDEFINITE, GSS_C_INDEFINITE, NULL, NULL, NULL, NULL); assert(major == (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CRED)); /* Regression test for #8737: make sure that desired_name is honored when * creating a credential by passing in a non-matching name. */ name = import_name("p:does/not/match@WRONG_REALM"); major = gss_add_cred(&minor, GSS_C_NO_CREDENTIAL, name, &mech_krb5, GSS_C_INITIATE, GSS_C_INDEFINITE, GSS_C_INDEFINITE, &cred1, NULL, NULL, NULL); assert(major == GSS_S_NO_CRED); gss_release_name(&minor, &name); /* Create cred1 with a krb5 initiator cred by passing an output handle but * no input handle. */ major = gss_add_cred(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, &mech_krb5, GSS_C_INITIATE, GSS_C_INDEFINITE, GSS_C_INDEFINITE, &cred1, NULL, NULL, NULL); assert(major == GSS_S_COMPLETE); /* Verify that cred1 has the expected mechanism creds. */ major = gss_inquire_cred_by_mech(&minor, cred1, &mech_krb5, NULL, NULL, NULL, &usage); assert(major == GSS_S_COMPLETE && usage == GSS_C_INITIATE); major = gss_inquire_cred_by_mech(&minor, cred1, &mech_iakerb, NULL, NULL, NULL, &usage); assert(major == GSS_S_NO_CRED); /* Check that we get the expected error if we try to add another krb5 mech * cred to cred1. */ major = gss_add_cred(&minor, cred1, GSS_C_NO_NAME, &mech_krb5, GSS_C_INITIATE, GSS_C_INDEFINITE, GSS_C_INDEFINITE, NULL, NULL, NULL, NULL); assert(major == GSS_S_DUPLICATE_ELEMENT); /* Add an IAKERB acceptor mech cred to cred1. */ major = gss_add_cred(&minor, cred1, GSS_C_NO_NAME, &mech_iakerb, GSS_C_ACCEPT, GSS_C_INDEFINITE, GSS_C_INDEFINITE, NULL, NULL, NULL, NULL); assert(major == GSS_S_COMPLETE); /* Verify cred1 mechanism creds. */ major = gss_inquire_cred_by_mech(&minor, cred1, &mech_krb5, NULL, NULL, NULL, &usage); assert(major == GSS_S_COMPLETE && usage == GSS_C_INITIATE); major = gss_inquire_cred_by_mech(&minor, cred1, &mech_iakerb, NULL, NULL, NULL, &usage); assert(major == GSS_S_COMPLETE && usage == GSS_C_ACCEPT); /* Start over with another new cred. */ gss_release_cred(&minor, &cred1); major = gss_add_cred(&minor, GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, &mech_krb5, GSS_C_ACCEPT, GSS_C_INDEFINITE, GSS_C_INDEFINITE, &cred1, NULL, NULL, NULL); assert(major == GSS_S_COMPLETE); /* Create an expanded cred by passing both an output handle and an input * handle. */ major = gss_add_cred(&minor, cred1, GSS_C_NO_NAME, &mech_iakerb, GSS_C_INITIATE, GSS_C_INDEFINITE, GSS_C_INDEFINITE, &cred2, NULL, NULL, NULL); assert(major == GSS_S_COMPLETE); /* Verify mechanism creds in cred1 and cred2. */ major = gss_inquire_cred_by_mech(&minor, cred1, &mech_krb5, NULL, NULL, NULL, &usage); assert(major == GSS_S_COMPLETE && usage == GSS_C_ACCEPT); major = gss_inquire_cred_by_mech(&minor, cred1, &mech_iakerb, NULL, NULL, NULL, &usage); assert(major == GSS_S_NO_CRED); major = gss_inquire_cred_by_mech(&minor, cred2, &mech_krb5, NULL, NULL, NULL, &usage); assert(major == GSS_S_COMPLETE && usage == GSS_C_ACCEPT); major = gss_inquire_cred_by_mech(&minor, cred2, &mech_iakerb, NULL, NULL, NULL, &usage); assert(major == GSS_S_COMPLETE && usage == GSS_C_INITIATE); gss_release_cred(&minor, &cred1); gss_release_cred(&minor, &cred2); return 0; } krb5-1.22.1/src/tests/gssapi/t_bindings.py0000664000175000017500000000622415051422640020256 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm() server = 'p:' + realm.host_princ mark('krb5 channel bindings') realm.run(['./t_bindings', server, '-', '-'], expected_msg='no') realm.run(['./t_bindings', server, 'a', '-'], expected_msg='no') realm.run(['./t_bindings', server, 'a', 'a'], expected_msg='yes') realm.run(['./t_bindings', server, '-', 'a'], expected_msg='no') realm.run(['./t_bindings', server, 'a', 'x'], expected_code=1, expected_msg='Incorrect channel bindings') mark('SPNEGO channel bindings') realm.run(['./t_bindings', '-s', server, '-', '-'], expected_msg='no') realm.run(['./t_bindings', '-s', server, 'a', '-'], expected_msg='no') realm.run(['./t_bindings', '-s', server, 'a', 'a'], expected_msg='yes') realm.run(['./t_bindings', '-s', server, '-', 'a'], expected_msg='no') realm.run(['./t_bindings', '-s', server, 'a', 'x'], expected_code=1, expected_msg='Incorrect channel bindings') client_aware_conf = {'libdefaults': {'client_aware_channel_bindings': 'true'}} e = realm.special_env('cb_aware', False, krb5_conf=client_aware_conf) mark('krb5 client_aware_channel_bindings') realm.run(['./t_bindings', server, '-', '-'], env=e, expected_msg='no') realm.run(['./t_bindings', server, 'a', '-'], env=e, expected_msg='no') realm.run(['./t_bindings', server, 'a', 'a'], env=e, expected_msg='yes') realm.run(['./t_bindings', server, '-', 'a'], env=e, expected_code=1, expected_msg='Incorrect channel bindings') realm.run(['./t_bindings', server, 'a', 'x'], env=e, expected_code=1, expected_msg='Incorrect channel bindings') mark('SPNEGO client_aware_channel_bindings') realm.run(['./t_bindings', '-s', server, '-', '-'], env=e, expected_msg='no') realm.run(['./t_bindings', '-s', server, 'a', '-'], env=e, expected_msg='no') realm.run(['./t_bindings', '-s', server, 'a', 'a'], env=e, expected_msg='yes') realm.run(['./t_bindings', '-s', server, '-', 'a'], env=e, expected_code=1, expected_msg='Incorrect channel bindings') realm.run(['./t_bindings', '-s', server, 'a', 'x'], env=e, expected_code=1, expected_msg='Incorrect channel bindings') mark('krb5 GSS_C_CHANNEL_BOUND_FLAG initiator input flag') realm.run(['./t_bindings', '-b', server, '-', '-'], expected_msg='no') realm.run(['./t_bindings', '-b', server, 'a', '-'], expected_msg='no') realm.run(['./t_bindings', '-b', server, 'a', 'a'], expected_msg='yes') realm.run(['./t_bindings', '-b', server, '-', 'a'], expected_code=1, expected_msg='Incorrect channel bindings') realm.run(['./t_bindings', '-b', server, 'a', 'x'], expected_code=1, expected_msg='Incorrect channel bindings') mark('SPNEGO GSS_C_CHANNEL_BOUND_FLAG initiator input flag') realm.run(['./t_bindings', '-s', '-b', server, '-', '-'], expected_msg='no') realm.run(['./t_bindings', '-s', '-b', server, 'a', '-'], expected_msg='no') realm.run(['./t_bindings', '-s', '-b', server, 'a', 'a'], expected_msg='yes') realm.run(['./t_bindings', '-s', '-b', server, '-', 'a'], expected_code=1, expected_msg='Incorrect channel bindings') realm.run(['./t_bindings', '-s', '-b', server, 'a', 'x'], expected_code=1, expected_msg='Incorrect channel bindings') success('channel bindings tests') krb5-1.22.1/src/tests/gssapi/t_credstore.c0000664000175000017500000001206315051422640020243 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2011 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include "common.h" static void usage(void) { fprintf(stderr, "Usage: t_credstore [-sabi] principal [{key value} ...]\n"); exit(1); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_key_value_set_desc store; gss_name_t name = GSS_C_NO_NAME; gss_cred_usage_t cred_usage = GSS_C_BOTH; gss_OID_set mechs = GSS_C_NO_OID_SET; gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; gss_buffer_desc itok, atok; krb5_boolean store_creds = FALSE, replay = FALSE; char opt; /* Parse options. */ for (argv++; *argv != NULL && **argv == '-'; argv++) { opt = (*argv)[1]; if (opt == 's') store_creds = TRUE; else if (opt == 'r') replay = TRUE; else if (opt == 'a') cred_usage = GSS_C_ACCEPT; else if (opt == 'b') cred_usage = GSS_C_BOTH; else if (opt == 'i') cred_usage = GSS_C_INITIATE; else usage(); } /* Get the principal name. */ if (*argv == NULL) usage(); if (**argv != '\0') name = import_name(*argv); argv++; /* Put any remaining arguments into the store. */ store.elements = calloc(argc, sizeof(struct gss_key_value_element_struct)); if (!store.elements) errout("OOM"); store.count = 0; while (*argv != NULL) { if (*(argv + 1) == NULL) usage(); store.elements[store.count].key = *argv; store.elements[store.count].value = *(argv + 1); store.count++; argv += 2; } if (store_creds) { /* Acquire default creds and try to store them in the cred store. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, 0, GSS_C_NO_OID_SET, GSS_C_INITIATE, &cred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); major = gss_store_cred_into(&minor, cred, GSS_C_INITIATE, GSS_C_NO_OID, 1, 0, &store, NULL, NULL); check_gsserr("gss_store_cred_into", major, minor); gss_release_cred(&minor, &cred); } /* Try to acquire creds from store. */ major = gss_acquire_cred_from(&minor, name, 0, mechs, cred_usage, &store, &cred, NULL, NULL); check_gsserr("gss_acquire_cred_from", major, minor); if (replay) { /* Induce a replay using cred as the acceptor cred, to test the replay * cache indicated by the store. */ major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, name, &mech_krb5, 0, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context", major, minor); (void)gss_delete_sec_context(&minor, &ictx, NULL); major = gss_accept_sec_context(&minor, &actx, cred, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(1)", major, minor); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &actx, NULL); major = gss_accept_sec_context(&minor, &actx, cred, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(2)", major, minor); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &actx, NULL); } gss_release_name(&minor, &name); gss_release_cred(&minor, &cred); free(store.elements); return 0; } krb5-1.22.1/src/tests/gssapi/t_lifetime.c0000664000175000017500000001366415051422640020057 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_lifetime.c - display cred and context lifetimes */ /* * Copyright (C) 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "common.h" /* * Using the default credential, exercise the GSS functions which accept or * produce lifetimes. Display the following results, one per line, as ASCII * integers or the string "indefinite": * * initiator cred lifetime according to gss_acquire_cred() * initiator cred lifetime according to gss_inquire_cred() * acceptor cred lifetime according to gss_acquire_cred() * acceptor cred lifetime according to gss_inquire_cred() * initiator context lifetime according to gss_init_sec_context() * initiator context lifetime according to gss_inquire_context() * initiator context lifetime according to gss_context_time() * acceptor context lifetime according to gss_init_sec_context() * acceptor context lifetime according to gss_inquire_context() * acceptor context lifetime according to gss_context_time() */ static void display_time(OM_uint32 tval) { if (tval == GSS_C_INDEFINITE) puts("indefinite"); else printf("%u\n", (unsigned int)tval); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t icred, acred; gss_name_t tname; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER; OM_uint32 time_req = GSS_C_INDEFINITE, time_rec; if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: %s targetname [time_req]\n", argv[0]); return 1; } tname = import_name(argv[1]); if (argc >= 3) time_req = atoll(argv[2]); /* Get initiator cred and display its lifetime according to * gss_acquire_cred and gss_inquire_cred. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5, GSS_C_INITIATE, &icred, NULL, &time_rec); check_gsserr("gss_acquire_cred(initiate)", major, minor); display_time(time_rec); major = gss_inquire_cred(&minor, icred, NULL, &time_rec, NULL, NULL); check_gsserr("gss_inquire_cred(initiate)", major, minor); display_time(time_rec); /* Get acceptor cred and display its lifetime according to gss_acquire_cred * and gss_inquire_cred. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5, GSS_C_ACCEPT, &acred, NULL, &time_rec); check_gsserr("gss_acquire_cred(accept)", major, minor); display_time(time_rec); major = gss_inquire_cred(&minor, acred, NULL, &time_rec, NULL, NULL); check_gsserr("gss_inquire_cred(accept)", major, minor); display_time(time_rec); /* Make an initiator context and display its lifetime according to * gss_init_sec_context, gss_inquire_context, and gss_context_time. */ major = gss_init_sec_context(&minor, icred, &ictx, tname, &mech_krb5, 0, time_req, GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &itok, NULL, &time_rec); check_gsserr("gss_init_sec_context", major, minor); assert(major == GSS_S_COMPLETE); display_time(time_rec); major = gss_inquire_context(&minor, ictx, NULL, NULL, &time_rec, NULL, NULL, NULL, NULL); check_gsserr("gss_inquire_context(initiate)", major, minor); display_time(time_rec); major = gss_context_time(&minor, ictx, &time_rec); check_gsserr("gss_context_time(initiate)", major, minor); display_time(time_rec); major = gss_accept_sec_context(&minor, &actx, acred, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, &time_rec, NULL); check_gsserr("gss_accept_sec_context", major, minor); assert(major == GSS_S_COMPLETE); display_time(time_rec); major = gss_inquire_context(&minor, actx, NULL, NULL, &time_rec, NULL, NULL, NULL, NULL); check_gsserr("gss_inquire_context(accept)", major, minor); display_time(time_rec); major = gss_context_time(&minor, actx, &time_rec); check_gsserr("gss_context_time(accept)", major, minor); display_time(time_rec); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); (void)gss_release_name(&minor, &tname); (void)gss_release_cred(&minor, &icred); (void)gss_release_cred(&minor, &acred); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.22.1/src/tests/gssapi/reload.c0000664000175000017500000000550615051422640017200 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/reload.c - test loading libgssapi_krb5 twice */ /* * Copyright (C) 2020 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This is a regression test for ticket #8614. It ensures that libgssapi_krb5 * can be loaded multiple times in the same process when libkrb5support is held * open by another library. */ #include #include #include #include /* Load libgssapi_krb5, briefly use it (to force the initializer to run), and * close it. */ static void load_gssapi(void) { void *gssapi; OM_uint32 (*indmechs)(OM_uint32 *, gss_OID_set *); OM_uint32 (*reloidset)(OM_uint32 *, gss_OID_set *); OM_uint32 major, minor; gss_OID_set mechs; gssapi = dlopen("libgssapi_krb5.so", RTLD_NOW | RTLD_LOCAL); assert(gssapi != NULL); indmechs = dlsym(gssapi, "gss_indicate_mechs"); reloidset = dlsym(gssapi, "gss_release_oid_set"); assert(indmechs != NULL && reloidset != NULL); major = (*indmechs)(&minor, &mechs); assert(major == 0); (*reloidset)(&minor, &mechs); dlclose(gssapi); } int main(void) { void *support; /* Hold open libkrb5support to ensure that thread-local state remains */ support = dlopen("libkrb5support.so", RTLD_NOW | RTLD_LOCAL); if (support == NULL) { fprintf(stderr, "Error loading libkrb5support: %s\n", dlerror()); return 1; } load_gssapi(); load_gssapi(); dlclose(support); return 0; } krb5-1.22.1/src/tests/gssapi/ccinit.c0000664000175000017500000000466115051422640017204 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/ccinit.c - Initialize an empty ccache */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program initializes a ccache without attempting to get credentials in * it. It is used to test some finer points of gss_acquire_cred behavior. */ #include "k5-int.h" static void check(krb5_error_code code) { if (code != 0) { com_err("ccinit", code, NULL); abort(); } } int main(int argc, char **argv) { const char *ccname, *princname; krb5_context context; krb5_principal princ; krb5_ccache ccache; if (argc != 3) { fprintf(stderr, "Usage: %s ccname princname\n", argv[0]); return 1; } ccname = argv[1]; princname = argv[2]; check(krb5_init_context(&context)); check(krb5_parse_name(context, princname, &princ)); check(krb5_cc_resolve(context, ccname, &ccache)); check(krb5_cc_initialize(context, ccache, princ)); krb5_cc_close(context, ccache); krb5_free_principal(context, princ); krb5_free_context(context); return 0; } krb5-1.22.1/src/tests/gssapi/t_ciflags.c0000664000175000017500000001207415051422640017663 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_ciflags.c - GSS_KRB5_CRED_NO_CI_FLAGS_X tests */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include "common.h" static void flagtest(gss_OID mech, gss_cred_id_t icred, gss_name_t tname, OM_uint32 inflags, OM_uint32 expflags) { gss_ctx_id_t ictx, actx; OM_uint32 major, minor, flags; establish_contexts(mech, icred, GSS_C_NO_CREDENTIAL, tname, inflags, &ictx, &actx, NULL, NULL, NULL); major = gss_inquire_context(&minor, actx, NULL, NULL, NULL, NULL, &flags, NULL, NULL); check_gsserr("gss_inquire_context", major, minor); assert(flags == expflags); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); } int main(int argc, char *argv[]) { OM_uint32 minor, major; gss_cred_id_t icred; gss_name_t tname; gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; if (argc != 2) { fprintf(stderr, "Usage: %s targetname\n", argv[0]); return 1; } tname = import_name(argv[1]); /* With no flags, the initiator asserts conf, integ, trans */ flagtest(&mech_krb5, GSS_C_NO_CREDENTIAL, tname, 0, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, GSS_C_NO_CREDENTIAL, tname, 0, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); /* The initiator also asserts most flags specified by the caller. */ flagtest(&mech_krb5, GSS_C_NO_CREDENTIAL, tname, GSS_C_SEQUENCE_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG | GSS_C_SEQUENCE_FLAG); flagtest(&mech_spnego, GSS_C_NO_CREDENTIAL, tname, GSS_C_SEQUENCE_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG | GSS_C_SEQUENCE_FLAG); /* Get a normal initiator cred and re-test with no flags. */ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &icred, NULL, NULL); check_gsserr("gss_acquire_cred", major, minor); flagtest(&mech_krb5, icred, tname, 0, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, 0, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); /* Suppress confidentiality and integrity flags on the initiator cred and * check that they are suppressed, but can still be asserted explicitly. */ major = gss_set_cred_option(&minor, &icred, (gss_OID)GSS_KRB5_CRED_NO_CI_FLAGS_X, &empty_buffer); check_gsserr("gss_set_cred_option", major, minor); flagtest(&mech_krb5, icred, tname, 0, GSS_C_TRANS_FLAG); flagtest(&mech_krb5, icred, tname, GSS_C_CONF_FLAG, GSS_C_CONF_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_krb5, icred, tname, GSS_C_INTEG_FLAG, GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_krb5, icred, tname, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, 0, GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, GSS_C_INTEG_FLAG, GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, GSS_C_CONF_FLAG, GSS_C_CONF_FLAG | GSS_C_TRANS_FLAG); flagtest(&mech_spnego, icred, tname, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG, GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG | GSS_C_TRANS_FLAG); (void)gss_release_name(&minor, &tname); (void)gss_release_cred(&minor, &icred); return 0; } krb5-1.22.1/src/tests/gssapi/t_err.c0000664000175000017500000001170515051422640017043 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_err.c - Test accept_sec_context error generation */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This test program verifies that the krb5 gss_accept_sec_context can produce * error tokens and that gss_init_sec_context can interpret them. */ #include #include #include #include #include "common.h" static void check_replay_error(const char *msg, OM_uint32 major, OM_uint32 minor) { OM_uint32 tmpmin, msg_ctx = 0; const char *replay = "Request is a replay"; gss_buffer_desc m; if (major != GSS_S_FAILURE) { fprintf(stderr, "%s: expected major code GSS_S_FAILURE\n", msg); check_gsserr(msg, major, minor); exit(1); } (void)gss_display_status(&tmpmin, minor, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &m); if (m.length != strlen(replay) || memcmp(m.value, replay, m.length) != 0) { fprintf(stderr, "%s: expected replay error; got %.*s\n", msg, (int)m.length, (char *)m.value); exit(1); } (void)gss_release_buffer(&tmpmin, &m); } int main(int argc, char *argv[]) { OM_uint32 minor, major, flags; gss_OID mech = &mech_krb5; gss_name_t tname; gss_buffer_desc itok, atok; gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; argv++; if (*argv != NULL && strcmp(*argv, "--spnego") == 0) { mech = &mech_spnego; argv++; } if (*argv == NULL || argv[1] != NULL) { fprintf(stderr, "Usage: t_err targetname\n"); return 1; } tname = import_name(*argv); /* Get the initial context token. */ flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_MUTUAL_FLAG; major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, tname, mech, flags, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, NULL, &itok, NULL, NULL); check_gsserr("gss_init_sec_context(1)", major, minor); assert(major == GSS_S_CONTINUE_NEEDED); /* Process this token into an acceptor context, then discard it. */ major = gss_accept_sec_context(&minor, &actx, GSS_C_NO_CREDENTIAL, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_gsserr("gss_accept_sec_context(1)", major, minor); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &actx, NULL); /* Process the same token again, producing a replay error. */ major = gss_accept_sec_context(&minor, &actx, GSS_C_NO_CREDENTIAL, &itok, GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, &atok, NULL, NULL, NULL); check_replay_error("gss_accept_sec_context(2)", major, minor); assert(atok.length != 0); /* Send the error token back the initiator. */ (void)gss_release_buffer(&minor, &itok); major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, tname, mech, flags, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &itok, NULL, NULL); check_replay_error("gss_init_sec_context(2)", major, minor); (void)gss_release_name(&minor, &tname); (void)gss_release_buffer(&minor, &itok); (void)gss_release_buffer(&minor, &atok); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.22.1/src/tests/gssapi/t_context.c0000664000175000017500000000431415051422640017735 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/gssapi/t_context.c - Simple context establishment harness */ /* * Copyright (C) 2019 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "common.h" int main(int argc, char *argv[]) { OM_uint32 minor, flags; gss_name_t tname; gss_ctx_id_t ictx, actx; if (argc < 2) { fprintf(stderr, "Usage: %s targetname [acceptorname]\n", argv[0]); return 1; } tname = import_name(argv[1]); flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG; establish_contexts(&mech_spnego, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL, tname, flags, &ictx, &actx, NULL, NULL, NULL); (void)gss_release_name(&minor, &tname); (void)gss_delete_sec_context(&minor, &ictx, NULL); (void)gss_delete_sec_context(&minor, &actx, NULL); return 0; } krb5-1.22.1/src/tests/t_kdb.py0000775000175000017500000006563515051422640015751 0ustar ghudsonghudsonfrom k5test import * import time # Run kdbtest against the non-LDAP KDB modules. for realm in multidb_realms(create_kdb=False): realm.run(['./kdbtest']) # Set up an OpenLDAP test server if we can. if (not os.path.exists(os.path.join(plugins, 'kdb', 'kldap.so')) and not os.path.exists(os.path.join(buildtop, 'lib', 'libkdb_ldap.a'))): skip_rest('LDAP KDB tests', 'LDAP KDB module not built') if 'SLAPD' not in os.environ and not which('slapd'): skip_rest('LDAP KDB tests', 'slapd not found') slapadd = which('slapadd') if not slapadd: skip_rest('LDAP KDB tests', 'slapadd not found') ldapdir = os.path.abspath('ldap') dbdir = os.path.join(ldapdir, 'ldap') slapd_conf = os.path.join(ldapdir, 'slapd.d') slapd_out = os.path.join(ldapdir, 'slapd.out') slapd_pidfile = os.path.join(ldapdir, 'pid') ldap_pwfile = os.path.join(ldapdir, 'pw') ldap_sock = os.path.join(ldapdir, 'sock') ldap_uri = 'ldapi://%s/' % ldap_sock.replace(os.path.sep, '%2F') schema = os.path.join(srctop, 'plugins', 'kdb', 'ldap', 'libkdb_ldap', 'kerberos.openldap.ldif') top_dn = 'cn=krb5' admin_dn = 'cn=admin,cn=krb5' admin_pw = 'admin' shutil.rmtree(ldapdir, True) os.mkdir(ldapdir) os.mkdir(slapd_conf) os.mkdir(dbdir) if 'SLAPD' in os.environ: slapd = os.environ['SLAPD'] else: # Some Linux installations have AppArmor or similar restrictions # on the slapd binary, which would prevent it from accessing the # build directory. Try to defeat this by copying the binary. system_slapd = which('slapd') slapd = os.path.join(ldapdir, 'slapd') shutil.copy(system_slapd, slapd) def slap_add(ldif): proc = subprocess.Popen([slapadd, '-b', 'cn=config', '-F', slapd_conf], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) (out, dummy) = proc.communicate(ldif) output(out) return proc.wait() # Configure the pid file and some authorization rules we will need for # SASL testing. if slap_add('dn: cn=config\n' 'objectClass: olcGlobal\n' 'olcPidFile: %s\n' 'olcAuthzRegexp: ' '".*uidNumber=%d,cn=peercred,cn=external,cn=auth" "%s"\n' 'olcAuthzRegexp: "uid=digestuser,cn=digest-md5,cn=auth" "%s"\n' % (slapd_pidfile, os.geteuid(), admin_dn, admin_dn)) != 0: skip_rest('LDAP KDB tests', 'slapd basic configuration failed') # Find a working writable database type, trying mdb (added in OpenLDAP # 2.4.27) and bdb (deprecated and sometimes not built due to licensing # incompatibilities). for dbtype in ('mdb', 'bdb'): # Try to load the module. This could fail if OpenLDAP is built # without module support, so ignore errors. slap_add('dn: cn=module,cn=config\n' 'objectClass: olcModuleList\n' 'olcModuleLoad: back_%s\n' % dbtype) dbclass = 'olc%sConfig' % dbtype.capitalize() if slap_add('dn: olcDatabase=%s,cn=config\n' 'objectClass: olcDatabaseConfig\n' 'objectClass: %s\n' 'olcSuffix: %s\n' 'olcRootDN: %s\n' 'olcRootPW: %s\n' 'olcDbDirectory: %s\n' % (dbtype, dbclass, top_dn, admin_dn, admin_pw, dbdir)) == 0: break else: skip_rest('LDAP KDB tests', 'could not find working slapd db type') if slap_add('include: file://%s\n' % schema) != 0: skip_rest('LDAP KDB tests', 'failed to load Kerberos schema') # Load the core schema if we can. ldap_homes = ['/etc/ldap', '/etc/openldap', '/usr/local/etc/openldap', '/usr/local/etc/ldap'] local_schema_path = '/schema/core.ldif' core_schema = next((i for i in map(lambda x:x+local_schema_path, ldap_homes) if os.path.isfile(i)), None) if core_schema: if slap_add('include: file://%s\n' % core_schema) != 0: core_schema = None slapd_pid = -1 def kill_slapd(): global slapd_pid if slapd_pid != -1: os.kill(slapd_pid, signal.SIGTERM) slapd_pid = -1 atexit.register(kill_slapd) out = open(slapd_out, 'w') subprocess.call([slapd, '-h', ldap_uri, '-F', slapd_conf], stdout=out, stderr=out, universal_newlines=True) out.close() pidf = open(slapd_pidfile, 'r') slapd_pid = int(pidf.read()) pidf.close() output('*** Started slapd (pid %d, output in %s)\n' % (slapd_pid, slapd_out)) # slapd detaches before it finishes setting up its listener sockets # (they are bound but listen() has not been called). Give it a second # to finish. time.sleep(1) # Run kdbtest against the LDAP module. conf = {'realms': {'$realm': {'database_module': 'ldap'}}, 'dbmodules': {'ldap': {'db_library': 'kldap', 'ldap_kerberos_container_dn': top_dn, 'ldap_kdc_dn': admin_dn, 'ldap_kadmind_dn': admin_dn, 'ldap_service_password_file': ldap_pwfile, 'ldap_servers': ldap_uri}}} realm = K5Realm(create_kdb=False, kdc_conf=conf) input = admin_pw + '\n' + admin_pw + '\n' realm.run([kdb5_ldap_util, 'stashsrvpw', admin_dn], input=input) realm.run(['./kdbtest']) # Run a kdb5_ldap_util command using the test server's admin DN and password. def kldaputil(args, **kw): return realm.run([kdb5_ldap_util, '-D', admin_dn, '-w', admin_pw] + args, **kw) # kdbtest can't currently clean up after itself since the LDAP module # doesn't support krb5_db_destroy. So clean up after it with # kdb5_ldap_util before proceeding. kldaputil(['destroy', '-f']) ldapmodify = which('ldapmodify') ldapsearch = which('ldapsearch') if not ldapmodify or not ldapsearch: skip_rest('some LDAP KDB tests', 'ldapmodify or ldapsearch not found') def ldap_search(args): proc = subprocess.Popen([ldapsearch, '-H', ldap_uri, '-b', top_dn, '-D', admin_dn, '-w', admin_pw, args], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) (out, dummy) = proc.communicate() return out def ldap_modify(ldif, args=[]): proc = subprocess.Popen([ldapmodify, '-H', ldap_uri, '-D', admin_dn, '-x', '-w', admin_pw] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) (out, dummy) = proc.communicate(ldif) output(out) def ldap_add(dn, objectclass, attrs=[]): in_data = 'dn: %s\nobjectclass: %s\n' % (dn, objectclass) in_data += '\n'.join(attrs) + '\n' ldap_modify(in_data, ['-a']) # Create krbContainer objects for use as subtrees. ldap_add('cn=t1,cn=krb5', 'krbContainer') ldap_add('cn=t2,cn=krb5', 'krbContainer') ldap_add('cn=x,cn=t1,cn=krb5', 'krbContainer') ldap_add('cn=y,cn=t2,cn=krb5', 'krbContainer') # Create a realm, exercising all of the realm options. kldaputil(['create', '-s', '-P', 'master', '-subtrees', 'cn=t2,cn=krb5', '-containerref', 'cn=t2,cn=krb5', '-sscope', 'one', '-maxtktlife', '5min', '-maxrenewlife', '10min', '-allow_svr']) # Modify the realm, exercising overlapping subtree pruning. kldaputil(['modify', '-subtrees', 'cn=x,cn=t1,cn=krb5:cn=t1,cn=krb5:cn=t2,cn=krb5:cn=y,cn=t2,cn=krb5', '-containerref', 'cn=t1,cn=krb5', '-sscope', 'sub', '-maxtktlife', '5hour', '-maxrenewlife', '10hour', '+allow_svr']) out = kldaputil(['list']) if out != 'KRBTEST.COM\n': fail('Unexpected kdb5_ldap_util list output') # Create a principal at a specified DN. This is a little dodgy # because we're sticking a krbPrincipalAux objectclass onto a subtree # krbContainer, but it works and it avoids having to load core.schema # in the test LDAP server. mark('LDAP specified dn') realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=cn=krb5', 'princ1'], expected_code=1, expected_msg='DN is out of the realm subtree') # Check that the DN container check is a hierarchy test, not a simple # suffix match (CVE-2018-5730). We expect this operation to fail # either way (because "xcn" isn't a valid DN tag) but the container # check should happen before the DN is parsed. realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=xcn=t1,cn=krb5', 'princ1'], expected_code=1, expected_msg='DN is out of the realm subtree') realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=cn=t2,cn=krb5', 'princ1']) realm.run([kadminl, 'getprinc', 'princ1'], expected_msg='Principal: princ1') realm.run([kadminl, 'ank', '-randkey', '-x', 'dn=cn=t2,cn=krb5', 'again'], expected_code=1, expected_msg='ldap object is already kerberized') # Check that we can't set linkdn on a non-standalone object. realm.run([kadminl, 'modprinc', '-x', 'linkdn=cn=t1,cn=krb5', 'princ1'], expected_code=1, expected_msg='link information can not be set') # Create a principal with a specified linkdn. mark('LDAP specified linkdn') realm.run([kadminl, 'ank', '-randkey', '-x', 'linkdn=cn=krb5', 'princ2'], expected_code=1, expected_msg='DN is out of the realm subtree') realm.run([kadminl, 'ank', '-randkey', '-x', 'linkdn=cn=t1,cn=krb5', 'princ2']) # Check that we can't reset linkdn. realm.run([kadminl, 'modprinc', '-x', 'linkdn=cn=t2,cn=krb5', 'princ2'], expected_code=1, expected_msg='kerberos principal is already linked') # Create a principal with a specified containerdn. mark('LDAP specified containerdn') realm.run([kadminl, 'ank', '-randkey', '-x', 'containerdn=cn=krb5', 'princ3'], expected_code=1, expected_msg='DN is out of the realm subtree') realm.run([kadminl, 'ank', '-randkey', '-x', 'containerdn=cn=t1,cn=krb5', 'princ3']) realm.run([kadminl, 'modprinc', '-x', 'containerdn=cn=t2,cn=krb5', 'princ3'], expected_code=1, expected_msg='containerdn option not supported') # Verify that containerdn is checked when linkdn is also supplied # (CVE-2018-5730). realm.run([kadminl, 'ank', '-randkey', '-x', 'containerdn=cn=krb5', '-x', 'linkdn=cn=t2,cn=krb5', 'princ4'], expected_code=1, expected_msg='DN is out of the realm subtree') mark('LDAP ticket policy') # Create and modify a ticket policy. kldaputil(['create_policy', '-maxtktlife', '3hour', '-maxrenewlife', '6hour', '-allow_forwardable', 'tktpol']) kldaputil(['modify_policy', '-maxtktlife', '4hour', '-maxrenewlife', '8hour', '+requires_preauth', 'tktpol']) out = kldaputil(['view_policy', 'tktpol']) if ('Ticket policy: tktpol\n' not in out or 'Maximum ticket life: 0 days 04:00:00\n' not in out or 'Maximum renewable life: 0 days 08:00:00\n' not in out or 'Ticket flags: DISALLOW_FORWARDABLE REQUIRES_PRE_AUTH' not in out): fail('Unexpected kdb5_ldap_util view_policy output') out = kldaputil(['list_policy']) if out != 'tktpol\n': fail('Unexpected kdb5_ldap_util list_policy output') # Associate the ticket policy to a principal. realm.run([kadminl, 'ank', '-randkey', '-x', 'tktpolicy=tktpol', 'princ4']) out = realm.run([kadminl, 'getprinc', 'princ4']) if ('Maximum ticket life: 0 days 04:00:00\n' not in out or 'Maximum renewable life: 0 days 08:00:00\n' not in out or 'Attributes: DISALLOW_FORWARDABLE REQUIRES_PRE_AUTH\n' not in out): fail('Unexpected getprinc output with ticket policy') # Destroying the policy should fail while a principal references it. kldaputil(['destroy_policy', '-force', 'tktpol'], expected_code=1) # Dissociate the ticket policy from the principal. realm.run([kadminl, 'modprinc', '-x', 'tktpolicy=', 'princ4']) out = realm.run([kadminl, 'getprinc', 'princ4']) if ('Maximum ticket life: 0 days 05:00:00\n' not in out or 'Maximum renewable life: 0 days 10:00:00\n' not in out or 'Attributes:\n' not in out): fail('Unexpected getprinc output without ticket policy') # Destroy the ticket policy. kldaputil(['destroy_policy', '-force', 'tktpol']) kldaputil(['view_policy', 'tktpol'], expected_code=1) out = kldaputil(['list_policy']) if out: fail('Unexpected kdb5_ldap_util list_policy output after destroy') # Create another ticket policy to be destroyed with the realm. kldaputil(['create_policy', 'tktpol2']) # Try to create a password policy conflicting with a ticket policy. realm.run([kadminl, 'addpol', 'tktpol2'], expected_code=1, expected_msg='Already exists while creating policy "tktpol2"') # Try to create a ticket policy conflicting with a password policy. realm.run([kadminl, 'addpol', 'pwpol']) out = kldaputil(['create_policy', 'pwpol'], expected_code=1) if 'Already exists while creating policy object' not in out: fail('Expected error not seen in kdb5_ldap_util output') # Try to use a password policy as a ticket policy. realm.run([kadminl, 'modprinc', '-x', 'tktpolicy=pwpol', 'princ4'], expected_code=1, expected_msg='Object class violation') # Use a ticket policy as a password policy (CVE-2014-5353). This # works with a warning; use kadmin.local -q so the warning is shown. realm.run([kadminl, '-q', 'modprinc -policy tktpol2 princ4'], expected_msg='WARNING: policy "tktpol2" does not exist') # Do some basic tests with a KDC against the LDAP module, exercising the # db_args processing code. mark('LDAP KDC operation') realm.start_kdc(['-x', 'nconns=3', '-x', 'host=' + ldap_uri, '-x', 'binddn=' + admin_dn, '-x', 'bindpwd=' + admin_pw]) realm.addprinc(realm.user_princ, password('user')) realm.addprinc(realm.host_princ) realm.extract_keytab(realm.host_princ, realm.keytab) realm.kinit(realm.user_princ, password('user')) realm.run([kvno, realm.host_princ]) realm.klist(realm.user_princ, realm.host_princ) mark('LDAP auth indicator') # Test require_auth normalization. realm.addprinc('authind', password('authind')) realm.run([kadminl, 'setstr', 'authind', 'require_auth', 'otp radius']) # Check that krbPrincipalAuthInd attributes are set when the string # attribute it set. out = ldap_search('(krbPrincipalName=authind*)') if 'krbPrincipalAuthInd: otp' not in out: fail('Expected krbPrincipalAuthInd value not in output') if 'krbPrincipalAuthInd: radius' not in out: fail('Expected krbPrincipalAuthInd value not in output') # Check that the string attribute still appears when the principal is # loaded. realm.run([kadminl, 'getstrs', 'authind'], expected_msg='require_auth: otp radius') # Modify the LDAP attributes and check that the change is reflected in # the string attribute. ldap_modify('dn: krbPrincipalName=authind@KRBTEST.COM,cn=t1,cn=krb5\n' 'changetype: modify\n' 'replace: krbPrincipalAuthInd\n' 'krbPrincipalAuthInd: radius\n' 'krbPrincipalAuthInd: pkinit\n') realm.run([kadminl, 'getstrs', 'authind'], expected_msg='require_auth: radius pkinit') # Regression test for #8877: remove the string attribute and check # that it is reflected in the LDAP attributes and by getstrs. realm.run([kadminl, 'delstr', 'authind', 'require_auth']) out = ldap_search('(krbPrincipalName=authind*)') if 'krbPrincipalAuthInd' in out: fail('krbPrincipalAuthInd attribute still present after delstr') out = realm.run([kadminl, 'getstrs', 'authind']) if 'require_auth' in out: fail('require_auth string attribute still visible after delstr') mark('LDAP service principal aliases') # Test service principal aliases. realm.addprinc('canon', password('canon')) realm.run([kadminl, 'alias', 'alias', 'canon']) realm.run([kadminl, 'alias', 'ent\\@abc', 'canon']) out = ldap_search('(krbPrincipalName=canon*)') if ('krbPrincipalName: canon@KRBTEST.COM' not in out or 'krbPrincipalName: alias@KRBTEST.COM' not in out or 'krbPrincipalName: ent@abc@KRBTEST.COM' not in out or 'krbCanonicalName: canon@KRBTEST.COM' not in out): fail('expected names not found in canon object') realm.run([kadminl, 'getprinc', 'alias'], expected_msg='Principal: canon@KRBTEST.COM\n') realm.run([kadminl, 'getprinc', 'ent\\@abc'], expected_msg='Principal: canon@KRBTEST.COM\n') realm.run([kadminl, 'getprinc', 'canon'], expected_msg='Principal: canon@KRBTEST.COM\n') realm.run([kvno, 'alias', 'canon']) out = realm.run([klist]) if 'alias@KRBTEST.COM\n' not in out or 'canon@KRBTEST.COM' not in out: fail('After fetching alias and canon, klist is missing one or both') realm.kinit(realm.user_princ, password('user'), ['-S', 'alias']) realm.klist(realm.user_princ, 'alias@KRBTEST.COM') # Make sure an alias to the local TGS is still treated like an alias. realm.run([kadminl, 'alias', 'tgtalias', 'krbtgt/KRBTEST.COM']) realm.run([kadminl, 'getprinc', 'tgtalias'], expected_msg='Principal: krbtgt/KRBTEST.COM@KRBTEST.COM') realm.kinit(realm.user_princ, password('user')) realm.run([kvno, 'tgtalias']) realm.klist(realm.user_princ, 'tgtalias@KRBTEST.COM') # Make sure aliases work in header tickets. realm.run([kadminl, 'modprinc', '-maxrenewlife', '3 hours', 'user']) realm.run([kadminl, 'modprinc', '-maxrenewlife', '3 hours', 'krbtgt/KRBTEST.COM']) realm.kinit(realm.user_princ, password('user'), ['-l', '1h', '-r', '2h']) realm.run([kvno, 'alias']) realm.kinit(realm.user_princ, flags=['-R', '-S', 'alias']) realm.klist(realm.user_princ, 'alias@KRBTEST.COM') # Test client principal aliases, with and without preauth. realm.kinit('canon', password('canon')) realm.kinit('alias', password('canon')) realm.run([kvno, 'alias']) realm.klist('alias@KRBTEST.COM', 'alias@KRBTEST.COM') realm.kinit('alias', password('canon'), ['-C']) realm.run([kvno, 'alias']) realm.klist('canon@KRBTEST.COM', 'alias@KRBTEST.COM') realm.run([kadminl, 'modprinc', '+requires_preauth', 'canon']) realm.kinit('canon', password('canon')) realm.kinit('alias', password('canon'), ['-C']) # Test enterprise alias with and without canonicalization. realm.kinit('ent@abc', password('canon'), ['-E', '-C']) realm.run([kvno, 'alias']) realm.klist('canon@KRBTEST.COM', 'alias@KRBTEST.COM') realm.kinit('ent@abc', password('canon'), ['-E']) realm.run([kvno, 'alias']) realm.klist('ent\\@abc@KRBTEST.COM', 'alias@KRBTEST.COM') # Test client name canonicalization in non-krbtgt AS reply realm.kinit('alias', password('canon'), ['-C', '-S', 'kadmin/changepw']) # Test deleting an alias. mark('LDAP alias deletion') realm.run([kadminl, 'delprinc', 'alias']) realm.run([kadminl, 'getprinc', 'alias'], expected_code=1, expected_msg='Principal does not exist') realm.run([kadminl, 'getprinc', 'ent\\@abc'], expected_msg='Principal: canon@KRBTEST.COM\n') realm.run([kadminl, 'getprinc', 'canon'], expected_msg='Principal: canon@KRBTEST.COM\n') # Test deleting a canonical name when an alias is present. realm.run([kadminl, 'delprinc', 'canon']) realm.run([kadminl, 'getprinc', 'canon'], expected_code=1, expected_msg='Principal does not exist') realm.run([kadminl, 'getprinc', 'ent\\@abc'], expected_code=1, expected_msg='Principal does not exist') mark('LDAP password history') # Test password history. def test_pwhist(nhist): def cpw(n, **kwargs): realm.run([kadminl, 'cpw', '-pw', str(n), princ], **kwargs) def cpw_fail(n): cpw(n, expected_code=1) output('*** Testing password history of size %d\n' % nhist) princ = 'pwhistprinc' + str(nhist) pol = 'pwhistpol' + str(nhist) realm.run([kadminl, 'addpol', '-history', str(nhist), pol]) realm.run([kadminl, 'addprinc', '-policy', pol, '-nokey', princ]) for i in range(nhist): # Set a password, then check that all previous passwords fail. cpw(i) for j in range(i + 1): cpw_fail(j) # Set one more new password, and make sure the oldest key is # rotated out. cpw(nhist) cpw_fail(1) cpw(0) for n in (1, 2, 3, 4, 5): test_pwhist(n) # Regression test for #8193: test password character class requirements. princ = 'charclassprinc' pol = 'charclasspol' realm.run([kadminl, 'addpol', '-minclasses', '3', pol]) realm.run([kadminl, 'addprinc', '-policy', pol, '-nokey', princ]) realm.run([kadminl, 'cpw', '-pw', 'abcdef', princ], expected_code=1) realm.run([kadminl, 'cpw', '-pw', 'Abcdef', princ], expected_code=1) realm.run([kadminl, 'cpw', '-pw', 'Abcdef1', princ]) # Test principal renaming and make sure last modified is changed def get_princ(princ): out = realm.run([kadminl, 'getprinc', princ]) return dict(map(str.strip, x.split(":", 1)) for x in out.splitlines()) mark('LDAP principal renaming') realm.addprinc("rename", password('rename')) renameprinc = get_princ("rename") realm.run([kadminl, '-p', 'fake@KRBTEST.COM', 'renprinc', 'rename', 'renamed']) renamedprinc = get_princ("renamed") if renameprinc['Last modified'] == renamedprinc['Last modified']: fail('Last modified data not updated when principal was renamed') # Regression test for #7980 (fencepost when dividing keys up by kvno). mark('#7980 regression test') realm.run([kadminl, 'addprinc', '-randkey', '-e', 'aes256-cts,aes128-cts', 'kvnoprinc']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts,aes128-cts', 'kvnoprinc']) realm.run([kadminl, 'getprinc', 'kvnoprinc'], expected_msg='Number of keys: 4') realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts,aes128-cts', 'kvnoprinc']) realm.run([kadminl, 'getprinc', 'kvnoprinc'], expected_msg='Number of keys: 6') # Regression test for #8041 (NULL dereference on keyless principals). mark('#8041 regression test') realm.run([kadminl, 'addprinc', '-nokey', 'keylessprinc']) realm.run([kadminl, 'getprinc', 'keylessprinc'], expected_msg='Number of keys: 0') realm.run([kadminl, 'cpw', '-randkey', '-e', 'aes256-cts,aes128-cts', 'keylessprinc']) realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts,aes128-cts', 'keylessprinc']) realm.run([kadminl, 'getprinc', 'keylessprinc'], expected_msg='Number of keys: 4') realm.run([kadminl, 'purgekeys', '-all', 'keylessprinc']) realm.run([kadminl, 'getprinc', 'keylessprinc'], expected_msg='Number of keys: 0') # Test for 8354 (old password history entries when -keepold is used) mark('#8354 regression test') realm.run([kadminl, 'addpol', '-history', '2', 'keepoldpasspol']) realm.run([kadminl, 'addprinc', '-policy', 'keepoldpasspol', '-pw', 'aaaa', 'keepoldpassprinc']) for p in ('bbbb', 'cccc', 'aaaa'): realm.run([kadminl, 'cpw', '-keepold', '-pw', p, 'keepoldpassprinc']) if runenv.sizeof_time_t <= 4: skipped('y2038 LDAP test', 'platform has 32-bit time_t') else: # Test storage of timestamps after y2038. realm.run([kadminl, 'modprinc', '-pwexpire', '2040-02-03', 'user']) realm.run([kadminl, 'getprinc', 'user'], expected_msg=' 2040\n') # Regression test for #8861 (pw_expiration policy enforcement). mark('pw_expiration propogation') # Create a policy with a max life and verify its application. realm.run([kadminl, 'addpol', '-maxlife', '1s', 'pw_e']) realm.run([kadminl, 'addprinc', '-policy', 'pw_e', '-pw', 'password', 'pwuser']) out = realm.run([kadminl, 'getprinc', 'pwuser'], expected_msg='Password expiration date: ') if 'Password expiration date: [never]' in out: fail('pw_expiration not applied at principal creation') # Unset the policy max life and verify its application during password # change. realm.run([kadminl, 'modpol', '-maxlife', '0', 'pw_e']) realm.run([kadminl, 'cpw', '-pw', 'password_', 'pwuser']) realm.run([kadminl, 'getprinc', 'pwuser'], expected_msg='Password expiration date: [never]') realm.stop() # Test dump and load. Include a regression test for #8882 # (pw_expiration not set during load operation). mark('LDAP dump and load') realm.run([kadminl, 'modprinc', '-pwexpire', 'now', 'pwuser']) dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile], expected_code=1, expected_msg='KDB module requires -update argument') realm.run([kadminl, 'delprinc', 'pwuser']) realm.run([kdb5_util, 'load', '-update', dumpfile]) out = realm.run([kadminl, 'getprinc', 'pwuser']) if 'Password expiration date: [never]' in out: fail('pw_expiration not preserved across dump and load') realm.run([kadminl, 'getprinc', 'tgtalias'], expected_msg='Principal: krbtgt/KRBTEST.COM@KRBTEST.COM') # Destroy the realm. kldaputil(['destroy', '-f']) out = kldaputil(['list']) if out: fail('Unexpected kdb5_ldap_util list output after destroy') if not core_schema: skip_rest('LDAP SASL tests', 'core schema not found') if runenv.have_sasl != 'yes': skip_rest('LDAP SASL tests', 'SASL support not built') # Test SASL EXTERNAL auth. Remove the DNs and service password file # from the DB module config. mark('LDAP SASL EXTERNAL auth') os.remove(ldap_pwfile) dbmod = conf['dbmodules']['ldap'] dbmod['ldap_kdc_sasl_mech'] = dbmod['ldap_kadmind_sasl_mech'] = 'EXTERNAL' del dbmod['ldap_service_password_file'] del dbmod['ldap_kdc_dn'], dbmod['ldap_kadmind_dn'] realm = K5Realm(create_kdb=False, kdc_conf=conf) realm.run([kdb5_ldap_util, 'create', '-s', '-P', 'master']) realm.start_kdc() realm.addprinc(realm.user_princ, password('user')) realm.kinit(realm.user_princ, password('user')) realm.stop() realm.run([kdb5_ldap_util, 'destroy', '-f']) # Test SASL DIGEST-MD5 auth. We need to set a clear-text password for # the admin DN, so create a person entry (requires the core schema). # Restore the service password file in the config and set authcids. mark('LDAP SASL DIGEST-MD5 auth') ldap_add('cn=admin,cn=krb5', 'person', ['sn: dummy', 'userPassword: admin']) dbmod['ldap_kdc_sasl_mech'] = dbmod['ldap_kadmind_sasl_mech'] = 'DIGEST-MD5' dbmod['ldap_kdc_sasl_authcid'] = 'digestuser' dbmod['ldap_kadmind_sasl_authcid'] = 'digestuser' dbmod['ldap_service_password_file'] = ldap_pwfile realm = K5Realm(create_kdb=False, kdc_conf=conf) # Work around https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1091694 if runenv.asan == 'yes': realm.env['ASAN_OPTIONS'] = 'detect_leaks=false' input = admin_pw + '\n' + admin_pw + '\n' realm.run([kdb5_ldap_util, 'stashsrvpw', 'digestuser'], input=input) realm.run([kdb5_ldap_util, 'create', '-s', '-P', 'master']) realm.start_kdc() realm.addprinc(realm.user_princ, password('user')) realm.kinit(realm.user_princ, password('user')) realm.stop() # Exercise DB options, which should cause binding to fail. realm.run([kadminl, '-x', 'sasl_authcid=ab', 'getprinc', 'user'], expected_code=1, expected_msg='Cannot bind to LDAP server') realm.run([kadminl, '-x', 'bindpwd=wrong', 'getprinc', 'user'], expected_code=1, expected_msg='Cannot bind to LDAP server') realm.run([kdb5_ldap_util, 'destroy', '-f']) # We could still use tests to exercise: # * DB arg handling in krb5_ldap_create # * krbAllowedToDelegateTo attribute processing # * A load operation overwriting a standalone principal entry which # already exists but doesn't have a krbPrincipalName attribute # matching the principal name. # * A bunch of invalid-input error conditions # # There is no coverage for the following because it would be difficult: # * Out-of-memory error conditions # * Handling of failures from slapd (including krb5_retry_get_ldap_handle) # * Handling of servers which don't support mod-increment # * krb5_ldap_delete_krbcontainer (only happens if krb5_ldap_create fails) success('LDAP and DB2 KDB tests') krb5-1.22.1/src/tests/conccache.c0000664000175000017500000001242615051422640016351 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/conccache.c - ccache concurrent get_creds/refresh test program */ /* * Copyright (C) 2021 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Usage: conccache ccname clientprinc serverprinc * * This program spawns two subprocesses. One repeatedly runs * krb5_get_credentials() on ccname, and the other repeatedly refreshes ccname * from the default keytab. If either subprocess fails, the program exits with * status 1. The goal is to expose time windows where cache refreshes cause * get_cred operations to fail. */ #include "k5-platform.h" #include #include #include #include /* Run this many iterations of each operation. */ static const int iterations = 200; /* Saved command-line arguments. */ static const char *ccname, *server_name, *client_name; static void check(krb5_error_code code) { if (code) abort(); } static krb5_boolean get_cred(krb5_context context) { krb5_error_code ret; krb5_ccache cc; krb5_principal client, server; krb5_creds mcred, *cred; check(krb5_cc_resolve(context, ccname, &cc)); check(krb5_parse_name(context, client_name, &client)); check(krb5_parse_name(context, server_name, &server)); memset(&mcred, 0, sizeof(mcred)); mcred.client = client; mcred.server = server; ret = krb5_get_credentials(context, 0, cc, &mcred, &cred); krb5_free_creds(context, cred); krb5_free_principal(context, client); krb5_free_principal(context, server); krb5_cc_close(context, cc); return ret == 0; } static krb5_boolean refresh_cache(krb5_context context) { krb5_error_code ret; krb5_ccache cc; krb5_principal client; krb5_get_init_creds_opt *opt; krb5_creds cred; check(krb5_cc_resolve(context, ccname, &cc)); check(krb5_parse_name(context, client_name, &client)); check(krb5_get_init_creds_opt_alloc(context, &opt)); check(krb5_get_init_creds_opt_set_out_ccache(context, opt, cc)); ret = krb5_get_init_creds_keytab(context, &cred, client, NULL, 0, NULL, opt); krb5_get_init_creds_opt_free(context, opt); krb5_free_cred_contents(context, &cred); krb5_free_principal(context, client); krb5_cc_close(context, cc); return ret == 0; } static pid_t spawn_cred_subprocess(void) { krb5_context context; pid_t pid; int i; pid = fork(); assert(pid >= 0); if (pid > 0) return pid; check(krb5_init_context(&context)); for (i = 0; i < iterations; i++) { if (!get_cred(context)) { fprintf(stderr, "cred worker failed after %d successes\n", i); exit(1); } } krb5_free_context(context); exit(0); } static pid_t spawn_refresh_subprocess(void) { krb5_context context; pid_t pid; int i; pid = fork(); assert(pid >= 0); if (pid > 0) return pid; check(krb5_init_context(&context)); for (i = 0; i < iterations; i++) { if (!refresh_cache(context)) { fprintf(stderr, "refresh worker failed after %d successes\n", i); exit(1); } } krb5_free_context(context); exit(0); } int main(int argc, char *argv[]) { krb5_context context; pid_t cred_pid, refresh_pid, pid; int cstatus, rstatus; assert(argc == 4); ccname = argv[1]; client_name = argv[2]; server_name = argv[3]; /* Begin with an initialized cache. */ check(krb5_init_context(&context)); refresh_cache(context); krb5_free_context(context); cred_pid = spawn_cred_subprocess(); refresh_pid = spawn_refresh_subprocess(); pid = waitpid(cred_pid, &cstatus, 0); if (pid == -1) abort(); pid = waitpid(refresh_pid, &rstatus, 0); if (pid == -1) abort(); if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus) != 0) return 1; if (!WIFEXITED(rstatus) || WEXITSTATUS(rstatus) != 0) return 1; return 0; } krb5-1.22.1/src/tests/t_inetd.c0000664000175000017500000000651515051422640016073 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* tests/t_inetd.c */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * A simple program to simulate starting a process from inetd. * * Unlike a proper inetd situation, environment variables are passed * to the client. * * usage: t_inetd port program argv0 ... */ #include "autoconf.h" #ifdef HAVE_STDLIB_H #include #endif #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "com_err.h" char *progname; static void usage(void) { fprintf(stderr, "%s: port program argv0 argv1 ...\n", progname); exit(1); } int main(int argc, char **argv) { unsigned short port; char *path; int sock, acc; int one = 1; struct sockaddr_in l_inaddr, f_inaddr; /* local, foreign address */ socklen_t namelen = sizeof(f_inaddr); progname = argv[0]; if(argc <= 3) usage(); if(atoi(argv[1]) == 0) usage(); port = htons(atoi(argv[1])); path = argv[2]; if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { com_err(progname, errno, "creating socket"); exit(3); } (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof (one)); memset(&l_inaddr, 0, sizeof(l_inaddr)); l_inaddr.sin_family = AF_INET; l_inaddr.sin_addr.s_addr = 0; l_inaddr.sin_port = port; if (bind(sock, (struct sockaddr *)&l_inaddr, sizeof(l_inaddr))) { com_err(progname, errno, "binding socket"); exit(3); } if (listen(sock, 1) == -1) { com_err(progname, errno, "listening"); exit(3); } printf("Ready!\n"); fflush(stdout); if ((acc = accept(sock, (struct sockaddr *)&f_inaddr, &namelen)) == -1) { com_err(progname, errno, "accepting"); exit(3); } dup2(acc, 0); dup2(acc, 1); dup2(acc, 2); close(sock); sock = 0; if(execv(path, &argv[3])) fprintf(stderr, "t_inetd: Could not exec %s\n", path); exit(1); } krb5-1.22.1/src/tests/t_dump.py0000775000175000017500000000754515051422640016152 0ustar ghudsonghudsonfrom k5test import * from filecmp import cmp def dump_compare(realm, opt, srcfile): mark('dump comparison against %s' % os.path.basename(srcfile)) realm.run([kdb5_util, 'dump'] + opt + [dumpfile]) if not cmp(srcfile, dumpfile, False): fail('Dump output does not match %s' % srcfile) def load_dump_check_compare(realm, opt, srcfile): mark('load check from %s' % os.path.basename(srcfile)) realm.run([kdb5_util, 'destroy', '-f']) realm.run([kdb5_util, 'load'] + opt + [srcfile]) realm.run([kadminl, 'getprincs'], expected_msg='user@') realm.run([kadminl, 'getprinc', 'nokeys'], expected_msg='Number of keys: 0') realm.run([kadminl, 'getpols'], expected_msg='testpol') dump_compare(realm, opt, srcfile) for realm in multidb_realms(start_kdc=False): # Make sure we can dump and load an ordinary database, and that # principals and policies survive a dump/load cycle. realm.run([kadminl, 'addpol', 'fred']) # Create a dump file. dumpfile = os.path.join(realm.testdir, 'dump') realm.run([kdb5_util, 'dump', dumpfile]) # Write additional policy records to the dump. Use the 1.8 format for # one of them, to test retroactive compatibility (for issue #8213). f = open('testdir/dump', 'a') f.write('policy\tcompat\t0\t0\t3\t4\t5\t0\t0\t0\t0\n') f.write('policy\tbarney\t0\t0\t1\t1\t1\t0\t0\t0\t0\t0\t0\t0\t-\t1\t2\t28\t' 'fd100f5064625f6372656174696f6e404b5242544553542e434f4d00\n') f.close() # Destroy and load the database; check that the policies exist. # Spot-check principal and policy fields. mark('reload after dump') realm.run([kdb5_util, 'destroy', '-f']) realm.run([kdb5_util, 'load', dumpfile]) out = realm.run([kadminl, 'getprincs']) if realm.user_princ not in out or realm.host_princ not in out: fail('Missing principal after load') out = realm.run([kadminl, 'getprinc', realm.user_princ]) if 'Expiration date: [never]' not in out or 'MKey: vno 1' not in out: fail('Principal has wrong value after load') out = realm.run([kadminl, 'getpols']) if 'fred\n' not in out or 'barney\n' not in out: fail('Missing policy after load') realm.run([kadminl, 'getpol', 'compat'], expected_msg='Number of old keys kept: 5') realm.run([kadminl, 'getpol', 'barney'], expected_msg='Number of old keys kept: 1') # Dump/load again, and make sure everything is still there. mark('second reload') realm.run([kdb5_util, 'dump', dumpfile]) realm.run([kdb5_util, 'load', dumpfile]) out = realm.run([kadminl, 'getprincs']) if realm.user_princ not in out or realm.host_princ not in out: fail('Missing principal after load') out = realm.run([kadminl, 'getpols']) if 'compat\n' not in out or 'fred\n' not in out or 'barney\n' not in out: fail('Missing policy after second load') srcdumpdir = os.path.join(srctop, 'tests', 'dumpfiles') srcdump = os.path.join(srcdumpdir, 'dump') srcdump_r18 = os.path.join(srcdumpdir, 'dump.r18') srcdump_r13 = os.path.join(srcdumpdir, 'dump.r13') srcdump_b7 = os.path.join(srcdumpdir, 'dump.b7') # Load a dump file from the source directory. realm.run([kdb5_util, 'destroy', '-f']) realm.run([kdb5_util, 'load', srcdump]) realm.run([kdb5_util, 'stash', '-P', 'master']) # Dump the resulting DB in each non-iprop format and compare with # expected outputs. dump_compare(realm, [], srcdump) dump_compare(realm, ['-r18'], srcdump_r18) dump_compare(realm, ['-r13'], srcdump_r13) dump_compare(realm, ['-b7'], srcdump_b7) # Load each format of dump, check it, re-dump it, and compare. load_dump_check_compare(realm, ['-r18'], srcdump_r18) load_dump_check_compare(realm, ['-r13'], srcdump_r13) load_dump_check_compare(realm, ['-b7'], srcdump_b7) success('Dump/load tests') krb5-1.22.1/src/tests/t_etype_info.py0000664000175000017500000000632215051422640017333 0ustar ghudsonghudsonfrom k5test import * supported_enctypes = 'aes128-cts des3-cbc-sha1 rc4-hmac' conf = {'libdefaults': {'allow_des3': 'true', 'allow_rc4': 'true'}, 'realms': {'$realm': {'supported_enctypes': supported_enctypes}}} realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf) realm.run([kadminl, 'addprinc', '-pw', 'pw', '+requires_preauth', 'preauthuser']) realm.run([kadminl, 'addprinc', '-pw', 'pw', '-e', 'rc4-hmac', '+requires_preauth', 'rc4user']) realm.run([kadminl, 'addprinc', '-nokey', '+requires_preauth', 'nokeyuser']) # Run the test harness for the given principal and request enctype # list. Compare the output to the expected lines, ignoring order. def test_etinfo(princ, enctypes, expected_lines): mark('etinfo test: %s %s' % (princ.partition('@')[0], enctypes)) conf = {'libdefaults': {'default_tkt_enctypes': enctypes}} etypes_env = realm.special_env('etypes', False, krb5_conf=conf) lines = realm.run(['./etinfo', princ], env=etypes_env).splitlines() if sorted(lines) != sorted(expected_lines): fail('Unexpected output for princ %s, etypes %s' % (princ, enctypes)) # With no newer enctypes in the request, PA-ETYPE-INFO2, # PA-ETYPE-INFO, and PA-PW-SALT appear in the AS-REP, each listing one # key for the most preferred matching enctype. test_etinfo('user', 'rc4-hmac-exp des3 rc4', ['asrep etype_info2 des3-cbc-sha1 KRBTEST.COMuser', 'asrep etype_info des3-cbc-sha1 KRBTEST.COMuser', 'asrep pw_salt KRBTEST.COMuser']) # With a newer enctype in the request (even if it is not the most # preferred enctype and doesn't match any keys), only PA-ETYPE-INFO2 # appears. test_etinfo('user', 'rc4 aes256-cts', ['asrep etype_info2 rc4-hmac KRBTEST.COMuser']) # In preauth-required errors, PA-PW-SALT does not appear, but the same # etype-info2 values are expected. test_etinfo('preauthuser', 'rc4-hmac-exp des3 rc4', ['error etype_info2 des3-cbc-sha1 KRBTEST.COMpreauthuser', 'error etype_info des3-cbc-sha1 KRBTEST.COMpreauthuser']) test_etinfo('preauthuser', 'rc4 aes256-cts', ['error etype_info2 rc4-hmac KRBTEST.COMpreauthuser']) # If no keys are found matching the request enctypes, a # preauth-required error can be generated with no etype-info at all # (to allow for preauth mechs which don't depend on long-term keys). # An AS-REP cannot be generated without preauth as there is no reply # key. test_etinfo('rc4user', 'des3', []) test_etinfo('nokeyuser', 'des3', []) # Verify that etype-info2 is included in a MORE_PREAUTH_DATA_REQUIRED # error if the client does optimistic preauth. mark('MORE_PREAUTH_DATA_REQUIRED test') realm.stop() testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, 'clpreauth': {'module': 'test:' + testpreauth}}} realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf) realm.run([kadminl, 'setstr', realm.user_princ, '2rt', '2rtval']) out = realm.run(['./etinfo', realm.user_princ, '-123']) if out != 'more etype_info2 aes256-cts KRBTEST.COMuser\n': fail('Unexpected output for MORE_PREAUTH_DATA_REQUIRED test') success('KDC etype-info tests') krb5-1.22.1/src/tests/s4u2self.c0000664000175000017500000001002115051422640016077 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2019 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Usage: s4u2self user self out_cache [ad-type ad-contents] * * The default ccache contains a TGT for the intermediate service self. An * S4U2Self request is made to self. The resulting cred is stored in * out_cache. */ #include static krb5_context ctx; static void check(krb5_error_code code) { const char *errmsg; if (code) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); exit(1); } } static krb5_authdata ** make_request_authdata(int type, const char *contents) { krb5_authdata *ad; krb5_authdata **req_authdata; ad = malloc(sizeof(*ad)); assert(ad != NULL); ad->magic = KV5M_AUTHDATA; ad->ad_type = type; ad->length = strlen(contents); ad->contents = (unsigned char *)strdup(contents); assert(ad->contents != NULL); req_authdata = malloc(2 * sizeof(*req_authdata)); assert(req_authdata != NULL); req_authdata[0] = ad; req_authdata[1] = NULL; return req_authdata; } int main(int argc, char **argv) { krb5_context context; krb5_ccache defcc, ocache; krb5_principal client, self; krb5_creds mcred, *new_cred; krb5_authdata **req_authdata = NULL; if (argc == 6) { req_authdata = make_request_authdata(atoi(argv[4]), argv[5]); argc -= 2; } assert(argc == 4); check(krb5_init_context(&context)); /* Open the default ccache. */ check(krb5_cc_default(context, &defcc)); check(krb5_parse_name(context, argv[1], &client)); check(krb5_parse_name(context, argv[2], &self)); memset(&mcred, 0, sizeof(mcred)); mcred.client = client; mcred.server = self; mcred.authdata = req_authdata; check(krb5_get_credentials_for_user(context, KRB5_GC_NO_STORE | KRB5_GC_CANONICALIZE, defcc, &mcred, NULL, &new_cred)); if (strcmp(argv[3], "-") == 0) { check(krb5_cc_store_cred(context, defcc, new_cred)); } else { check(krb5_cc_resolve(context, argv[3], &ocache)); check(krb5_cc_initialize(context, ocache, new_cred->client)); check(krb5_cc_store_cred(context, ocache, new_cred)); krb5_cc_close(context, ocache); } assert(req_authdata == NULL || new_cred->authdata != NULL); krb5_cc_close(context, defcc); krb5_free_principal(context, client); krb5_free_principal(context, self); krb5_free_creds(context, new_cred); krb5_free_authdata(context, req_authdata); krb5_free_context(context); return 0; } krb5-1.22.1/src/patchlevel.h0000664000175000017500000000453715051422640015441 0ustar ghudsonghudson/* patchlevel.h */ /* * Copyright (C) 2004-2006 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This is the master file for version stamping purposes. The * checked-in version will contain the correct version information at * all times. Prior to an official release x.y.z, * KRB5_MAJOR_RELEASE=x, KRB5_MINOR_RELEASE=y, and KRB5_PATCHLEVEL=z. * KRB5_RELTAIL will reflect the release state. It will be * "prerelease" for unreleased code either on the trunk or on a * release branch. It will be undefined for a final release. * * Immediately following a final release, the release version numbers * will be incremented, and KRB5_RELTAIL will revert to "prerelease". * * KRB5_RELTAG contains the CVS tag name corresponding to the release. * KRB5_RELDATE identifies the date of the release. They should * normally be undefined for checked-in code. */ /* * ========== * IMPORTANT: * ========== * * If you are a vendor supplying modified code derived from MIT * Kerberos, you SHOULD update KRB5_RELTAIL to identify your * organization. */ #define KRB5_MAJOR_RELEASE 1 #define KRB5_MINOR_RELEASE 22 #define KRB5_PATCHLEVEL 1 /* #undef KRB5_RELTAIL */ #define KRB5_RELDATE "20250820" #define KRB5_RELTAG "krb5-1.22.1-final" krb5-1.22.1/src/lib/0000775000175000017500000000000015051422640013676 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/rpc/0000775000175000017500000000000015051422640014462 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/rpc/auth_gssapi.c0000664000175000017500000005675415051422640017156 0ustar ghudsonghudson/* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. * */ #include #include #include #include #include #ifdef GSSAPI_KRB5 #include #endif #include #include #include "gssrpcint.h" #ifdef __CODECENTER__ #define DEBUG_GSSAPI 1 #endif #ifdef DEBUG_GSSAPI int auth_debug_gssapi = DEBUG_GSSAPI; extern void gssrpcint_printf(const char *format, ...); #define L_PRINTF(l,args) if (auth_debug_gssapi >= l) gssrpcint_printf args #define PRINTF(args) L_PRINTF(99, args) #define AUTH_GSSAPI_DISPLAY_STATUS(args) \ if (auth_debug_gssapi) auth_gssapi_display_status args #else #define PRINTF(args) #define L_PRINTF(l, args) #define AUTH_GSSAPI_DISPLAY_STATUS(args) #endif static void auth_gssapi_nextverf(AUTH *); static bool_t auth_gssapi_marshall(AUTH *, XDR *); static bool_t auth_gssapi_validate(AUTH *, struct opaque_auth *); static bool_t auth_gssapi_refresh(AUTH *, struct rpc_msg *); static bool_t auth_gssapi_wrap(AUTH *, XDR *, xdrproc_t, caddr_t); static bool_t auth_gssapi_unwrap(AUTH *, XDR *, xdrproc_t, caddr_t); static void auth_gssapi_destroy(AUTH *); static bool_t marshall_new_creds(AUTH *, bool_t, gss_buffer_t); static struct auth_ops auth_gssapi_ops = { auth_gssapi_nextverf, auth_gssapi_marshall, auth_gssapi_validate, auth_gssapi_refresh, auth_gssapi_destroy, auth_gssapi_wrap, auth_gssapi_unwrap, }; /* * the ah_private data structure for an auth_handle */ struct auth_gssapi_data { bool_t established; CLIENT *clnt; gss_ctx_id_t context; gss_buffer_desc client_handle; uint32_t seq_num; int def_cred; /* pre-serialized ah_cred */ unsigned char cred_buf[MAX_AUTH_BYTES]; uint32_t cred_len; }; #define AUTH_PRIVATE(auth) ((struct auth_gssapi_data *)auth->ah_private) /* * Function: auth_gssapi_create_default * * Purpose: Create a GSS-API style authenticator, with default * options, and return the handle. * * Effects: See design document, section XXX. */ AUTH *auth_gssapi_create_default(CLIENT *clnt, char *service_name) { AUTH *auth; OM_uint32 gssstat, minor_stat; gss_buffer_desc input_name; gss_name_t target_name; input_name.value = service_name; input_name.length = strlen(service_name) + 1; gssstat = gss_import_name(&minor_stat, &input_name, gss_nt_service_name, &target_name); if (gssstat != GSS_S_COMPLETE) { AUTH_GSSAPI_DISPLAY_STATUS(("parsing name", gssstat, minor_stat)); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; return NULL; } auth = auth_gssapi_create(clnt, &gssstat, &minor_stat, GSS_C_NO_CREDENTIAL, target_name, GSS_C_NULL_OID, GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, 0, NULL, NULL, NULL); gss_release_name(&minor_stat, &target_name); return auth; } /* * Function: auth_gssapi_create * * Purpose: Create a GSS-API style authenticator, with all the * options, and return the handle. * * Effects: See design document, section XXX. */ AUTH *auth_gssapi_create( CLIENT *clnt, OM_uint32 *gssstat, OM_uint32 *minor_stat, gss_cred_id_t claimant_cred_handle, gss_name_t target_name, gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, gss_OID *actual_mech_type, OM_uint32 *ret_flags, OM_uint32 *time_rec) { AUTH *auth, *save_auth; struct auth_gssapi_data *pdata; struct gss_channel_bindings_struct bindings, *bindp; struct sockaddr_in laddr, raddr; enum clnt_stat callstat; struct timeval timeout; int bindings_failed; rpcproc_t init_func; auth_gssapi_init_arg call_arg; auth_gssapi_init_res call_res; gss_buffer_desc *input_token, isn_buf; memset(&rpc_createerr, 0, sizeof(rpc_createerr)); /* this timeout is only used if clnt_control(clnt, CLSET_TIMEOUT) */ /* has not already been called.. therefore, we can just pick */ /* something reasonable-sounding.. */ timeout.tv_sec = 30; timeout.tv_usec = 0; auth = NULL; pdata = NULL; /* don't assume the caller will want to change clnt->cl_auth */ save_auth = clnt->cl_auth; auth = (AUTH *) malloc(sizeof(*auth)); pdata = (struct auth_gssapi_data *) malloc(sizeof(*pdata)); if (auth == NULL || pdata == NULL) { /* They needn't both have failed; clean up. */ free(auth); free(pdata); auth = NULL; pdata = NULL; rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; goto cleanup; } memset(auth, 0, sizeof(*auth)); memset(pdata, 0, sizeof(*pdata)); auth->ah_ops = &auth_gssapi_ops; auth->ah_private = (caddr_t) pdata; /* initial creds are auth_msg TRUE and no handle */ marshall_new_creds(auth, TRUE, NULL); /* initial verifier is empty */ auth->ah_verf.oa_flavor = AUTH_GSSAPI; auth->ah_verf.oa_base = NULL; auth->ah_verf.oa_length = 0; AUTH_PRIVATE(auth)->established = FALSE; AUTH_PRIVATE(auth)->clnt = clnt; AUTH_PRIVATE(auth)->def_cred = (claimant_cred_handle == GSS_C_NO_CREDENTIAL); clnt->cl_auth = auth; /* start by trying latest version */ call_arg.version = 4; bindings_failed = 0; try_new_version: /* set state for initial call to init_sec_context */ input_token = GSS_C_NO_BUFFER; AUTH_PRIVATE(auth)->context = GSS_C_NO_CONTEXT; init_func = AUTH_GSSAPI_INIT; #ifdef GSSAPI_KRB5 /* * OV servers up to version 3 used the old mech id. Beta 7 * servers used version 3 with the new mech id; however, the beta * 7 gss-api accept_sec_context accepts either mech id. Thus, if * any server rejects version 4, we fall back to version 3 with * the old mech id; for the OV server it will be right, and for * the beta 7 server it will be accepted. Not ideal, but it * works. */ if (call_arg.version < 4 && (mech_type == gss_mech_krb5 || mech_type == GSS_C_NULL_OID)) mech_type = (gss_OID) gss_mech_krb5_old; #endif if (!bindings_failed && call_arg.version >= 3) { if (clnt_control(clnt, CLGET_LOCAL_ADDR, &laddr) == FALSE) { PRINTF(("gssapi_create: CLGET_LOCAL_ADDR failed")); goto cleanup; } if (clnt_control(clnt, CLGET_SERVER_ADDR, &raddr) == FALSE) { PRINTF(("gssapi_create: CLGET_SERVER_ADDR failed")); goto cleanup; } memset(&bindings, 0, sizeof(bindings)); bindings.application_data.length = 0; bindings.initiator_addrtype = GSS_C_AF_INET; bindings.initiator_address.length = 4; bindings.initiator_address.value = &laddr.sin_addr.s_addr; bindings.acceptor_addrtype = GSS_C_AF_INET; bindings.acceptor_address.length = 4; bindings.acceptor_address.value = &raddr.sin_addr.s_addr; bindp = &bindings; } else { bindp = NULL; } memset(&call_res, 0, sizeof(call_res)); next_token: *gssstat = gss_init_sec_context(minor_stat, claimant_cred_handle, &AUTH_PRIVATE(auth)->context, target_name, mech_type, req_flags, time_req, bindp, input_token, actual_mech_type, &call_arg.token, ret_flags, time_rec); if (*gssstat != GSS_S_COMPLETE && *gssstat != GSS_S_CONTINUE_NEEDED) { AUTH_GSSAPI_DISPLAY_STATUS(("initializing context", *gssstat, *minor_stat)); goto cleanup; } /* if we got a token, pass it on */ if (call_arg.token.length != 0) { /* * sanity check: if we received a signed isn in the last * response then there *cannot* be another token to send */ if (call_res.signed_isn.length != 0) { PRINTF(("gssapi_create: unexpected token from init_sec\n")); goto cleanup; } PRINTF(("gssapi_create: calling GSSAPI_INIT (%d)\n", init_func)); xdr_free((xdrproc_t)xdr_authgssapi_init_res, &call_res); memset(&call_res, 0, sizeof(call_res)); callstat = clnt_call(clnt, init_func, (xdrproc_t)xdr_authgssapi_init_arg, &call_arg, (xdrproc_t)xdr_authgssapi_init_res, &call_res, timeout); gss_release_buffer(minor_stat, &call_arg.token); if (callstat != RPC_SUCCESS) { struct rpc_err err; clnt_geterr(clnt, &err); if (callstat == RPC_AUTHERROR && (err.re_why == AUTH_BADCRED || err.re_why == AUTH_FAILED) && call_arg.version >= 1) { L_PRINTF(1, ("call_arg protocol version %d rejected, trying %d.\n", call_arg.version, call_arg.version-1)); call_arg.version--; goto try_new_version; } else { PRINTF(("gssapi_create: GSSAPI_INIT (%d) failed, stat %d\n", init_func, callstat)); } goto cleanup; } else if (call_res.version != call_arg.version && !(call_arg.version == 2 && call_res.version == 1)) { /* * The Secure 1.1 servers always respond with version * 1. Thus, if we just tried a version >=3, fall all * the way back to version 1 since that is all they * understand */ if (call_arg.version > 2 && call_res.version == 1) { L_PRINTF(1, ("Talking to Secure 1.1 server, using version 1.\n")); call_arg.version = 1; goto try_new_version; } PRINTF(("gssapi_create: invalid call_res vers %d\n", call_res.version)); goto cleanup; } else if (call_res.gss_major != GSS_S_COMPLETE) { AUTH_GSSAPI_DISPLAY_STATUS(("in response from server", call_res.gss_major, call_res.gss_minor)); goto cleanup; } PRINTF(("gssapi_create: GSSAPI_INIT (%d) succeeded\n", init_func)); init_func = AUTH_GSSAPI_CONTINUE_INIT; /* check for client_handle */ if (AUTH_PRIVATE(auth)->client_handle.length == 0) { if (call_res.client_handle.length == 0) { PRINTF(("gssapi_create: expected client_handle\n")); goto cleanup; } else { PRINTF(("gssapi_create: got client_handle %d\n", *((uint32_t *)call_res.client_handle.value))); GSS_DUP_BUFFER(AUTH_PRIVATE(auth)->client_handle, call_res.client_handle); /* auth_msg is TRUE; there may be more tokens */ marshall_new_creds(auth, TRUE, &AUTH_PRIVATE(auth)->client_handle); } } else if (!GSS_BUFFERS_EQUAL(AUTH_PRIVATE(auth)->client_handle, call_res.client_handle)) { PRINTF(("gssapi_create: got different client_handle\n")); goto cleanup; } /* check for token */ if (call_res.token.length==0 && *gssstat==GSS_S_CONTINUE_NEEDED) { PRINTF(("gssapi_create: expected token\n")); goto cleanup; } else if (call_res.token.length != 0) { if (*gssstat == GSS_S_COMPLETE) { PRINTF(("gssapi_create: got unexpected token\n")); goto cleanup; } else { /* assumes call_res is safe until init_sec_context */ input_token = &call_res.token; PRINTF(("gssapi_create: got new token\n")); } } } /* check for isn */ if (*gssstat == GSS_S_COMPLETE) { if (call_res.signed_isn.length == 0) { PRINTF(("gssapi_created: expected signed isn\n")); goto cleanup; } else { PRINTF(("gssapi_create: processing signed isn\n")); /* don't check conf (integ only) or qop (accept default) */ *gssstat = gss_unseal(minor_stat, AUTH_PRIVATE(auth)->context, &call_res.signed_isn, &isn_buf, NULL, NULL); if (*gssstat != GSS_S_COMPLETE) { AUTH_GSSAPI_DISPLAY_STATUS(("unsealing isn", *gssstat, *minor_stat)); goto cleanup; } else if (isn_buf.length != sizeof(uint32_t)) { PRINTF(("gssapi_create: gss_unseal gave %d bytes\n", (int) isn_buf.length)); goto cleanup; } AUTH_PRIVATE(auth)->seq_num = (uint32_t) ntohl(*((uint32_t*)isn_buf.value)); *gssstat = gss_release_buffer(minor_stat, &isn_buf); if (*gssstat != GSS_S_COMPLETE) { AUTH_GSSAPI_DISPLAY_STATUS(("releasing unsealed isn", *gssstat, *minor_stat)); goto cleanup; } PRINTF(("gssapi_create: isn is %d\n", AUTH_PRIVATE(auth)->seq_num)); } } else if (call_res.signed_isn.length != 0) { PRINTF(("gssapi_create: got signed isn, can't check yet\n")); } /* results were okay.. continue if necessary */ if (*gssstat == GSS_S_CONTINUE_NEEDED) { PRINTF(("gssapi_create: not done, continuing\n")); goto next_token; } /* * Done! Context is established, we have client_handle and isn. */ AUTH_PRIVATE(auth)->established = TRUE; marshall_new_creds(auth, FALSE, &AUTH_PRIVATE(auth)->client_handle); PRINTF(("gssapi_create: done. client_handle %#x, isn %d\n\n", *((uint32_t *)AUTH_PRIVATE(auth)->client_handle.value), AUTH_PRIVATE(auth)->seq_num)); /* don't assume the caller will want to change clnt->cl_auth */ clnt->cl_auth = save_auth; xdr_free((xdrproc_t)xdr_authgssapi_init_res, &call_res); return auth; /******************************************************************/ cleanup: PRINTF(("gssapi_create: bailing\n\n")); if (auth) { if (AUTH_PRIVATE(auth)) auth_gssapi_destroy(auth); else free(auth); auth = NULL; } /* don't assume the caller will want to change clnt->cl_auth */ clnt->cl_auth = save_auth; if (rpc_createerr.cf_stat == 0) rpc_createerr.cf_stat = RPC_AUTHERROR; xdr_free((xdrproc_t)xdr_authgssapi_init_res, &call_res); return auth; } /* * Function: marshall_new_creds * * Purpose: (pre-)serialize auth_msg and client_handle fields of * auth_gssapi_creds into auth->cred_buf * * Arguments: * * auth (r/w) the AUTH structure to modify * auth_msg (r) the auth_msg field to serialize * client_handle (r) the client_handle field to serialize, or * NULL * * Returns: TRUE if successful, FALSE if not * * Requires: auth must point to a valid GSS-API auth structure, auth_msg * must be TRUE or FALSE, client_handle must be a gss_buffer_t with a valid * value and length field or NULL. * * Effects: auth->ah_cred is set to the serialized auth_gssapi_creds * version 2 structure (stored in the cred_buf field of private data) * containing version, auth_msg and client_handle. * auth->ah_cred.oa_flavor is set to AUTH_GSSAPI. If cliend_handle is * NULL, it is treated as if it had a length of 0 and a value of NULL. * * Modifies: auth */ static bool_t marshall_new_creds( AUTH *auth, bool_t auth_msg, gss_buffer_t client_handle) { auth_gssapi_creds creds; XDR xdrs; PRINTF(("marshall_new_creds: starting\n")); creds.version = 2; creds.auth_msg = auth_msg; if (client_handle) GSS_COPY_BUFFER(creds.client_handle, *client_handle) else { creds.client_handle.length = 0; creds.client_handle.value = NULL; } xdrmem_create(&xdrs, (caddr_t) AUTH_PRIVATE(auth)->cred_buf, MAX_AUTH_BYTES, XDR_ENCODE); if (! xdr_authgssapi_creds(&xdrs, &creds)) { PRINTF(("marshall_new_creds: failed encoding auth_gssapi_creds\n")); XDR_DESTROY(&xdrs); return FALSE; } AUTH_PRIVATE(auth)->cred_len = xdr_getpos(&xdrs); XDR_DESTROY(&xdrs); PRINTF(("marshall_new_creds: auth_gssapi_creds is %d bytes\n", AUTH_PRIVATE(auth)->cred_len)); auth->ah_cred.oa_flavor = AUTH_GSSAPI; auth->ah_cred.oa_base = (char *) AUTH_PRIVATE(auth)->cred_buf; auth->ah_cred.oa_length = AUTH_PRIVATE(auth)->cred_len; PRINTF(("marshall_new_creds: succeeding\n")); return TRUE; } /* * Function: auth_gssapi_nextverf * * Purpose: None. * * Effects: None. Never called. */ static void auth_gssapi_nextverf(AUTH *auth) { } /* * Function: auth_gssapi_marhsall * * Purpose: Marshall RPC credentials and verifier onto xdr stream. * * Arguments: * * auth (r/w) AUTH structure for client * xdrs (r/w) XDR stream to marshall to * * Returns: boolean indicating success/failure * * Effects: * * The pre-serialized credentials in cred_buf are serialized. If the * context is established, the sealed sequence number is serialized as * the verifier. If the context is not established, an empty verifier * is serialized. The sequence number is *not* incremented, because * this function is called multiple times if retransmission is required. * * If this took all the header fields as arguments, it could sign * them. */ static bool_t auth_gssapi_marshall( AUTH *auth, XDR *xdrs) { OM_uint32 minor_stat; gss_buffer_desc out_buf; uint32_t seq_num; if (AUTH_PRIVATE(auth)->established == TRUE) { PRINTF(("gssapi_marshall: starting\n")); seq_num = AUTH_PRIVATE(auth)->seq_num + 1; PRINTF(("gssapi_marshall: sending seq_num %d\n", seq_num)); if (auth_gssapi_seal_seq(AUTH_PRIVATE(auth)->context, seq_num, &out_buf) == FALSE) { PRINTF(("gssapi_marhshall: seal failed\n")); } auth->ah_verf.oa_base = out_buf.value; auth->ah_verf.oa_length = out_buf.length; if (! xdr_opaque_auth(xdrs, &auth->ah_cred) || ! xdr_opaque_auth(xdrs, &auth->ah_verf)) { (void) gss_release_buffer(&minor_stat, &out_buf); return FALSE; } (void) gss_release_buffer(&minor_stat, &out_buf); } else { PRINTF(("gssapi_marshall: not established, sending null verf\n")); auth->ah_verf.oa_base = NULL; auth->ah_verf.oa_length = 0; if (! xdr_opaque_auth(xdrs, &auth->ah_cred) || ! xdr_opaque_auth(xdrs, &auth->ah_verf)) { return FALSE; } } return TRUE; } /* * Function: auth_gssapi_validate * * Purpose: Validate RPC response verifier from server. * * Effects: See design document, section XXX. */ static bool_t auth_gssapi_validate( AUTH *auth, struct opaque_auth *verf) { gss_buffer_desc in_buf; uint32_t seq_num; if (AUTH_PRIVATE(auth)->established == FALSE) { PRINTF(("gssapi_validate: not established, noop\n")); return TRUE; } PRINTF(("gssapi_validate: starting\n")); in_buf.length = verf->oa_length; in_buf.value = verf->oa_base; if (auth_gssapi_unseal_seq(AUTH_PRIVATE(auth)->context, &in_buf, &seq_num) == FALSE) { PRINTF(("gssapi_validate: failed unsealing verifier\n")); return FALSE; } /* we sent seq_num+1, so we should get back seq_num+2 */ if (AUTH_PRIVATE(auth)->seq_num+2 != seq_num) { PRINTF(("gssapi_validate: expecting seq_num %d, got %d (%#x)\n", AUTH_PRIVATE(auth)->seq_num + 2, seq_num, seq_num)); return FALSE; } PRINTF(("gssapi_validate: seq_num %d okay\n", seq_num)); /* +1 for successful transmission, +1 for successful validation */ AUTH_PRIVATE(auth)->seq_num += 2; PRINTF(("gssapi_validate: succeeding\n")); return TRUE; } /* * Function: auth_gssapi_refresh * * Purpose: Attempts to resyncrhonize the sequence number. * * Effects: * * When the server receives a properly authenticated RPC call, it * increments the sequence number it is expecting from the client. * But if the server's response is lost for any reason, the client * can't know whether the server ever received it, assumes it didn't, * and does *not* increment its sequence number. Thus, the client's * next call will fail with AUTH_REJECTEDCRED because the server will * think it is a replay attack. * * When an AUTH_REJECTEDCRED error arrives, this function attempts to * resyncrhonize by incrementing the client's sequence number and * returning TRUE. If any other error arrives, it returns FALSE. */ static bool_t auth_gssapi_refresh( AUTH *auth, struct rpc_msg *msg) { if (msg->rm_reply.rp_rjct.rj_stat == AUTH_ERROR && msg->rm_reply.rp_rjct.rj_why == AUTH_REJECTEDVERF) { PRINTF(("gssapi_refresh: rejected verifier, incrementing\n")); AUTH_PRIVATE(auth)->seq_num++; return TRUE; } else { PRINTF(("gssapi_refresh: failing\n")); return FALSE; } } /* * Function: auth_gssapi_destroy * * Purpose: Destroy a GSS-API authentication structure. * * Effects: This function destroys the GSS-API authentication * context, and sends a message to the server instructing it to * invokte gss_process_token() and thereby destroy its corresponding * context. Since the client doesn't really care whether the server * gets this message, no failures are reported. */ static void auth_gssapi_destroy(AUTH *auth) { struct timeval timeout; OM_uint32 gssstat, minor_stat; gss_cred_id_t cred; int callstat; if (AUTH_PRIVATE(auth)->client_handle.length == 0) { PRINTF(("gssapi_destroy: no client_handle, not calling destroy\n")); goto skip_call; } PRINTF(("gssapi_destroy: marshalling new creds\n")); if (!marshall_new_creds(auth, TRUE, &AUTH_PRIVATE(auth)->client_handle)) { PRINTF(("gssapi_destroy: marshall_new_creds failed\n")); goto skip_call; } PRINTF(("gssapi_destroy: calling GSSAPI_DESTROY\n")); timeout.tv_sec = 1; timeout.tv_usec = 0; callstat = clnt_call(AUTH_PRIVATE(auth)->clnt, AUTH_GSSAPI_DESTROY, xdr_void, NULL, xdr_void, NULL, timeout); if (callstat != RPC_SUCCESS) clnt_sperror(AUTH_PRIVATE(auth)->clnt, "gssapi_destroy: GSSAPI_DESTROY failed"); skip_call: PRINTF(("gssapi_destroy: deleting context\n")); gssstat = gss_delete_sec_context(&minor_stat, &AUTH_PRIVATE(auth)->context, NULL); if (gssstat != GSS_S_COMPLETE) AUTH_GSSAPI_DISPLAY_STATUS(("deleting context", gssstat, minor_stat)); if (AUTH_PRIVATE(auth)->def_cred) { cred = GSS_C_NO_CREDENTIAL; gssstat = gss_release_cred(&minor_stat, &cred); if (gssstat != GSS_S_COMPLETE) AUTH_GSSAPI_DISPLAY_STATUS(("deleting default credential", gssstat, minor_stat)); } free(AUTH_PRIVATE(auth)->client_handle.value); free(auth->ah_private); free(auth); PRINTF(("gssapi_destroy: done\n")); } /* * Function: auth_gssapi_wrap * * Purpose: encrypt the serialized arguments from xdr_func applied to * xdr_ptr and write the result to xdrs. * * Effects: See design doc, section XXX. */ static bool_t auth_gssapi_wrap( AUTH *auth, XDR *out_xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { OM_uint32 gssstat, minor_stat; if (! AUTH_PRIVATE(auth)->established) { PRINTF(("gssapi_wrap: context not established, noop\n")); return (*xdr_func)(out_xdrs, xdr_ptr); } else if (! auth_gssapi_wrap_data(&gssstat, &minor_stat, AUTH_PRIVATE(auth)->context, AUTH_PRIVATE(auth)->seq_num+1, out_xdrs, xdr_func, xdr_ptr)) { if (gssstat != GSS_S_COMPLETE) AUTH_GSSAPI_DISPLAY_STATUS(("encrypting function arguments", gssstat, minor_stat)); return FALSE; } else return TRUE; } /* * Function: auth_gssapi_unwrap * * Purpose: read encrypted arguments from xdrs, decrypt, and * deserialize with xdr_func into xdr_ptr. * * Effects: See design doc, section XXX. */ static bool_t auth_gssapi_unwrap( AUTH *auth, XDR *in_xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { OM_uint32 gssstat, minor_stat; if (! AUTH_PRIVATE(auth)->established) { PRINTF(("gssapi_unwrap: context not established, noop\n")); return (*xdr_func)(in_xdrs, xdr_ptr); } else if (! auth_gssapi_unwrap_data(&gssstat, &minor_stat, AUTH_PRIVATE(auth)->context, AUTH_PRIVATE(auth)->seq_num, in_xdrs, xdr_func, xdr_ptr)) { if (gssstat != GSS_S_COMPLETE) AUTH_GSSAPI_DISPLAY_STATUS(("decrypting function arguments", gssstat, minor_stat)); return FALSE; } else return TRUE; } krb5-1.22.1/src/lib/rpc/getrpcent.c0000664000175000017500000001200415051422640016616 0ustar ghudsonghudson/* lib/rpc/getrpcent.c */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include SETRPCENT_TYPE setrpcent (int); ENDRPCENT_TYPE endrpcent (void); /* * Internet version. */ struct rpcdata { FILE *rpcf; char *current; int currentlen; int stayopen; #define MAXALIASES 35 char *rpc_aliases[MAXALIASES]; struct rpcent rpc; char line[BUFSIZ+1]; char *domain; } *rpcdata; static struct rpcdata *get_rpcdata(void); static struct rpcent *interpret(void); struct hostent *gethostent(void); static char RPCDB[] = "/etc/rpc"; static struct rpcdata * get_rpcdata(void) { struct rpcdata *d = rpcdata; if (d == 0) { d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata)); rpcdata = d; } return (d); } struct rpcent * getrpcbynumber(int number) { struct rpcdata *d = get_rpcdata(); struct rpcent *p; int reason; char adrstr[16], *val = NULL; int vallen; if (d == 0) return (0); setrpcent(0); while (p = getrpcent()) { if (p->r_number == number) break; } endrpcent(); return (p); } struct rpcent * getrpcbyname(const char *name) { struct rpcent *rpc; char **rp; setrpcent(0); while(rpc = getrpcent()) { if (strcmp(rpc->r_name, name) == 0) return (rpc); for (rp = rpc->r_aliases; *rp != NULL; rp++) { if (strcmp(*rp, name) == 0) return (rpc); } } endrpcent(); return (NULL); } SETRPCENT_TYPE setrpcent(int f) { struct rpcdata *d = _rpcdata(); if (d == 0) return; if (d->rpcf == NULL) { d->rpcf = fopen(RPCDB, "r"); if (d->rpcf) set_cloexec_file(d->rpcf); } else rewind(d->rpcf); if (d->current) free(d->current); d->current = NULL; d->stayopen |= f; } ENDRPCENT_TYPE endrpcent(void) { struct rpcdata *d = _rpcdata(); if (d == 0) return; if (d->current && !d->stayopen) { free(d->current); d->current = NULL; } if (d->rpcf && !d->stayopen) { fclose(d->rpcf); d->rpcf = NULL; } } struct rpcent * getrpcent(void) { struct rpcent *hp; int reason; char *key = NULL, *val = NULL; int keylen, vallen; struct rpcdata *d = _rpcdata(); if (d == 0) return(NULL); if (d->rpcf == NULL) { if ((d->rpcf = fopen(RPCDB, "r")) == NULL) return (NULL); set_cloexec_file(d->rpcf); } if (fgets(d->line, BUFSIZ, d->rpcf) == NULL) return (NULL); return interpret(d->line, strlen(d->line)); } static struct rpcent * interpret(char *val, int len) { struct rpcdata *d = _rpcdata(); char *p; char *cp, **q; if (d == 0) return; strncpy(d->line, val, len); p = d->line; d->line[len] = '\n'; if (*p == '#') return (getrpcent()); cp = strchr(p, '#'); if (cp == NULL) { cp = strchr(p, '\n'); if (cp == NULL) return (getrpcent()); } *cp = '\0'; cp = strchr(p, ' '); if (cp == NULL) { cp = strchr(p, '\t'); if (cp == NULL) return (getrpcent()); } *cp++ = '\0'; /* THIS STUFF IS INTERNET SPECIFIC */ d->rpc.r_name = d->line; while (*cp == ' ' || *cp == '\t') cp++; d->rpc.r_number = atoi(cp); q = d->rpc.r_aliases = d->rpc_aliases; cp = strchr(p, ' '); if (cp != NULL) *cp++ = '\0'; else { cp = strchr(p, '\t'); if (cp != NULL) *cp++ = '\0'; } while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } if (q < &(d->rpc_aliases[MAXALIASES - 1])) *q++ = cp; cp = strchr(p, ' '); if (cp != NULL) *cp++ = '\0'; else { cp = strchr(p, '\t'); if (cp != NULL) *cp++ = '\0'; } } *q = NULL; return (&d->rpc); } krb5-1.22.1/src/lib/rpc/authgss_prot.c0000664000175000017500000002275415051422640017362 0ustar ghudsonghudson/* lib/rpc/authgss_prot.c */ /* Copyright (c) 2000 The Regents of the University of Michigan. All rights reserved. Copyright (c) 2000 Dug Song . All rights reserved, all wrongs reversed. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Id: authgss_prot.c,v 1.18 2000/09/01 04:14:03 dugsong Exp */ #include #include #include #include #include #ifdef HAVE_HEIMDAL #include #else #include #endif bool_t xdr_rpc_gss_buf(XDR *xdrs, gss_buffer_t buf, u_int maxsize) { bool_t xdr_stat; u_int tmplen; char *cp; if (xdrs->x_op != XDR_DECODE) { if (buf->length > UINT_MAX) return (FALSE); else tmplen = buf->length; } cp = buf->value; xdr_stat = xdr_bytes(xdrs, &cp, &tmplen, maxsize); buf->value = cp; if (xdr_stat && xdrs->x_op == XDR_DECODE) buf->length = tmplen; return (xdr_stat); } bool_t xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p) { bool_t xdr_stat; xdr_stat = (xdr_u_int(xdrs, &p->gc_v) && xdr_enum(xdrs, (enum_t *)&p->gc_proc) && xdr_u_int32(xdrs, &p->gc_seq) && xdr_enum(xdrs, (enum_t *)&p->gc_svc) && xdr_rpc_gss_buf(xdrs, &p->gc_ctx, MAX_AUTH_BYTES)); log_debug("xdr_rpc_gss_cred: %s %s " "(v %d, proc %d, seq %d, svc %d, ctx %p:%d)", (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode", (xdr_stat == TRUE) ? "success" : "failure", p->gc_v, p->gc_proc, p->gc_seq, p->gc_svc, p->gc_ctx.value, p->gc_ctx.length); return (xdr_stat); } bool_t xdr_rpc_gss_init_args(XDR *xdrs, gss_buffer_desc *p) { bool_t xdr_stat; xdr_stat = xdr_rpc_gss_buf(xdrs, p, MAX_NETOBJ_SZ); log_debug("xdr_rpc_gss_init_args: %s %s (token %p:%d)", (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode", (xdr_stat == TRUE) ? "success" : "failure", p->value, p->length); return (xdr_stat); } bool_t xdr_rpc_gss_init_res(XDR *xdrs, struct rpc_gss_init_res *p) { bool_t xdr_stat; xdr_stat = (xdr_rpc_gss_buf(xdrs, &p->gr_ctx, MAX_NETOBJ_SZ) && xdr_u_int32(xdrs, &p->gr_major) && xdr_u_int32(xdrs, &p->gr_minor) && xdr_u_int32(xdrs, &p->gr_win) && xdr_rpc_gss_buf(xdrs, &p->gr_token, MAX_NETOBJ_SZ)); log_debug("xdr_rpc_gss_init_res %s %s " "(ctx %p:%d, maj %d, min %d, win %d, token %p:%d)", (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode", (xdr_stat == TRUE) ? "success" : "failure", p->gr_ctx.value, p->gr_ctx.length, p->gr_major, p->gr_minor, p->gr_win, p->gr_token.value, p->gr_token.length); return (xdr_stat); } bool_t xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_svc_t svc, uint32_t seq) { XDR tmpxdrs; gss_buffer_desc databuf, wrapbuf; OM_uint32 maj_stat, min_stat; int conf_state; bool_t xdr_stat; xdralloc_create(&tmpxdrs, XDR_ENCODE); xdr_stat = FALSE; /* Marshal rpc_gss_data_t (sequence number + arguments). */ if (!xdr_u_int32(&tmpxdrs, &seq) || !(*xdr_func)(&tmpxdrs, xdr_ptr)) goto errout; /* Set databuf to marshalled rpc_gss_data_t. */ databuf.length = xdr_getpos(&tmpxdrs); databuf.value = xdralloc_getdata(&tmpxdrs); if (svc == RPCSEC_GSS_SVC_INTEGRITY) { if (!xdr_rpc_gss_buf(xdrs, &databuf, (unsigned int)-1)) goto errout; /* Checksum rpc_gss_data_t. */ maj_stat = gss_get_mic(&min_stat, ctx, qop, &databuf, &wrapbuf); if (maj_stat != GSS_S_COMPLETE) { log_debug("gss_get_mic failed"); goto errout; } /* Marshal checksum. */ xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1); gss_release_buffer(&min_stat, &wrapbuf); } else if (svc == RPCSEC_GSS_SVC_PRIVACY) { /* Encrypt rpc_gss_data_t. */ maj_stat = gss_wrap(&min_stat, ctx, TRUE, qop, &databuf, &conf_state, &wrapbuf); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_wrap", maj_stat, min_stat); goto errout; } /* Marshal databody_priv. */ xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1); gss_release_buffer(&min_stat, &wrapbuf); } errout: xdr_destroy(&tmpxdrs); return (xdr_stat); } bool_t xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_svc_t svc, uint32_t seq) { XDR tmpxdrs; gss_buffer_desc databuf, wrapbuf; OM_uint32 maj_stat, min_stat; uint32_t seq_num; int conf_state; gss_qop_t qop_state; bool_t xdr_stat; if (xdr_func == xdr_void || xdr_ptr == NULL) return (TRUE); memset(&databuf, 0, sizeof(databuf)); memset(&wrapbuf, 0, sizeof(wrapbuf)); if (svc == RPCSEC_GSS_SVC_INTEGRITY) { /* Decode databody_integ. */ if (!xdr_rpc_gss_buf(xdrs, &databuf, (unsigned int)-1)) { log_debug("xdr decode databody_integ failed"); return (FALSE); } /* Decode checksum. */ if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1)) { gss_release_buffer(&min_stat, &databuf); log_debug("xdr decode checksum failed"); return (FALSE); } /* Verify checksum and QOP. */ maj_stat = gss_verify_mic(&min_stat, ctx, &databuf, &wrapbuf, &qop_state); free(wrapbuf.value); if (maj_stat != GSS_S_COMPLETE || qop_state != qop) { gss_release_buffer(&min_stat, &databuf); log_status("gss_verify_mic", maj_stat, min_stat); return (FALSE); } } else if (svc == RPCSEC_GSS_SVC_PRIVACY) { /* Decode databody_priv. */ if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1)) { log_debug("xdr decode databody_priv failed"); return (FALSE); } /* Decrypt databody. */ maj_stat = gss_unwrap(&min_stat, ctx, &wrapbuf, &databuf, &conf_state, &qop_state); free(wrapbuf.value); /* Verify encryption and QOP. */ if (maj_stat != GSS_S_COMPLETE || qop_state != qop || conf_state != TRUE) { gss_release_buffer(&min_stat, &databuf); log_status("gss_unwrap", maj_stat, min_stat); return (FALSE); } } /* Decode rpc_gss_data_t (sequence number + arguments). */ xdrmem_create(&tmpxdrs, databuf.value, databuf.length, XDR_DECODE); xdr_stat = (xdr_u_int32(&tmpxdrs, &seq_num) && (*xdr_func)(&tmpxdrs, xdr_ptr)); XDR_DESTROY(&tmpxdrs); gss_release_buffer(&min_stat, &databuf); /* Verify sequence number. */ if (xdr_stat == TRUE && seq_num != seq) { log_debug("wrong sequence number in databody"); return (FALSE); } return (xdr_stat); } bool_t xdr_rpc_gss_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_svc_t svc, uint32_t seq) { switch (xdrs->x_op) { case XDR_ENCODE: return (xdr_rpc_gss_wrap_data(xdrs, xdr_func, xdr_ptr, ctx, qop, svc, seq)); case XDR_DECODE: return (xdr_rpc_gss_unwrap_data(xdrs, xdr_func, xdr_ptr, ctx, qop,svc, seq)); case XDR_FREE: return (TRUE); } return (FALSE); } #ifdef DEBUG #include void log_debug(const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "rpcsec_gss: "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); } void log_status(char *m, OM_uint32 maj_stat, OM_uint32 min_stat) { OM_uint32 min, msg_ctx; gss_buffer_desc msgg, msgm; msg_ctx = 0; gss_display_status(&min, maj_stat, GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &msgg); msg_ctx = 0; gss_display_status(&min, min_stat, GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &msgm); log_debug("%s: %.*s - %.*s\n", m, msgg.length, (char *)msgg.value, msgm.length, (char *)msgm.value); gss_release_buffer(&min, &msgg); gss_release_buffer(&min, &msgm); } void log_hexdump(const u_char *buf, int len, int offset) { u_int i, j, jm; int c; fprintf(stderr, "\n"); for (i = 0; i < len; i += 0x10) { fprintf(stderr, " %04x: ", (u_int)(i + offset)); jm = len - i; jm = jm > 16 ? 16 : jm; for (j = 0; j < jm; j++) { if ((j % 2) == 1) fprintf(stderr, "%02x ", (u_int) buf[i+j]); else fprintf(stderr, "%02x", (u_int) buf[i+j]); } for (; j < 16; j++) { if ((j % 2) == 1) printf(" "); else fprintf(stderr, " "); } fprintf(stderr, " "); for (j = 0; j < jm; j++) { c = buf[i+j]; c = isprint(c) ? c : '.'; fprintf(stderr, "%c", c); } fprintf(stderr, "\n"); } } #else void log_debug(const char *fmt, ...) { } void log_status(char *m, OM_uint32 maj_stat, OM_uint32 min_stat) { } void log_hexdump(const u_char *buf, int len, int offset) { } #endif krb5-1.22.1/src/lib/rpc/xdr_rec.c0000664000175000017500000003643715051422640016271 0ustar ghudsonghudson/* @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro"; #endif /* * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" * layer above tcp (for rpc's use). * * These routines interface XDRSTREAMS to a tcp/ip connection. * There is a record marking layer between the xdr stream * and the tcp transport level. A record is composed on one or more * record fragments. A record fragment is a thirty-two bit header followed * by n bytes of data, where n is contained in the header. The header * is represented as a htonl(uint32_t). Thegh order bit encodes * whether or not the fragment is the last fragment of the record * (1 => fragment is last, 0 => more fragments to follow. * The other 31 bits encode the byte length of the fragment. */ #include #include #include #include #include #include static bool_t xdrrec_getlong(XDR *, long *); static bool_t xdrrec_putlong(XDR *, long *); static bool_t xdrrec_getbytes(XDR *, caddr_t, u_int); static bool_t xdrrec_putbytes(XDR *, caddr_t, u_int); static u_int xdrrec_getpos(XDR *); static bool_t xdrrec_setpos(XDR *, u_int); static rpc_inline_t * xdrrec_inline(XDR *, int); static void xdrrec_destroy(XDR *); static struct xdr_ops xdrrec_ops = { xdrrec_getlong, xdrrec_putlong, xdrrec_getbytes, xdrrec_putbytes, xdrrec_getpos, xdrrec_setpos, xdrrec_inline, xdrrec_destroy }; /* * A record is composed of one or more record fragments. * A record fragment is a four-byte header followed by zero to * 2**31-1 bytes. The header is treated as an unsigned 32 bit integer and is * encode/decoded to the network via htonl/ntohl. The low order 31 bits * are a byte count of the fragment. The highest order bit is a boolean: * 1 => this fragment is the last fragment of the record, * 0 => this fragment is followed by more fragment(s). * * The fragment/record machinery is not general; it is constructed to * meet the needs of xdr and rpc based on tcp. */ #define LAST_FRAG ((uint32_t)(1UL << 31)) typedef struct rec_strm { caddr_t tcp_handle; caddr_t the_buffer; /* * out-goung bits */ int (*writeit)(caddr_t, caddr_t, int); caddr_t out_base; /* output buffer (points to frag header) */ caddr_t out_finger; /* next output position */ caddr_t out_boundry; /* data cannot up to this address */ uint32_t *frag_header; /* beginning of curren fragment */ bool_t frag_sent; /* true if buffer sent in middle of record */ /* * in-coming bits */ int (*readit)(caddr_t, caddr_t, int); uint32_t in_size; /* fixed size of the input buffer */ caddr_t in_base; caddr_t in_finger; /* location of next byte to be had */ caddr_t in_boundry; /* can read up to this location */ int32_t fbtbc; /* fragment bytes to be consumed */ bool_t last_frag; u_int sendsize; u_int recvsize; } RECSTREAM; static u_int fix_buf_size(u_int); static bool_t flush_out(RECSTREAM *, bool_t); static bool_t get_input_bytes(RECSTREAM *, caddr_t, int); static bool_t set_input_fragment(RECSTREAM *); static bool_t skip_input_bytes(RECSTREAM *, int32_t); /* * Create an xdr handle for xdrrec * xdrrec_create fills in xdrs. Sendsize and recvsize are * send and recv buffer sizes (0 => use default). * tcp_handle is an opaque handle that is passed as the first parameter to * the procedures readit and writeit. Readit and writeit are read and * write respectively. They are like the system * calls expect that they take an opaque handle rather than an fd. */ void xdrrec_create( XDR *xdrs, u_int sendsize, u_int recvsize, caddr_t tcp_handle, /* like read, but pass it a tcp_handle, not sock */ int (*readit)(caddr_t, caddr_t, int), /* like write, but pass it a tcp_handle, not sock */ int (*writeit)(caddr_t, caddr_t, int) ) { RECSTREAM *rstrm = mem_alloc(sizeof(RECSTREAM)); if (rstrm == NULL) { (void)fprintf(stderr, "xdrrec_create: out of memory\n"); /* * This is bad. Should rework xdrrec_create to * return a handle, and in this case return NULL */ return; } /* * adjust sizes and allocate buffer quad byte aligned */ rstrm->sendsize = sendsize = fix_buf_size(sendsize); rstrm->recvsize = recvsize = fix_buf_size(recvsize); rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); if (rstrm->the_buffer == NULL) { (void)fprintf(stderr, "xdrrec_create: out of memory\n"); return; } for (rstrm->out_base = rstrm->the_buffer; /* Pointer arithmetic - long cast allowed... */ (u_long)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; rstrm->out_base++); rstrm->in_base = rstrm->out_base + sendsize; /* * now the rest ... */ xdrs->x_ops = &xdrrec_ops; xdrs->x_private = (caddr_t)rstrm; rstrm->tcp_handle = tcp_handle; rstrm->readit = readit; rstrm->writeit = writeit; rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; rstrm->frag_header = (uint32_t *)(void *)rstrm->out_base; rstrm->out_finger += BYTES_PER_XDR_UNIT; rstrm->out_boundry += sendsize; rstrm->frag_sent = FALSE; rstrm->in_size = recvsize; rstrm->in_boundry = rstrm->in_base; rstrm->in_finger = (rstrm->in_boundry += recvsize); rstrm->fbtbc = 0; rstrm->last_frag = TRUE; } /* * The reoutines defined below are the xdr ops which will go into the * xdr handle filled in by xdrrec_create. */ static bool_t xdrrec_getlong(XDR *xdrs, long *lp) { RECSTREAM *rstrm = xdrs->x_private; int32_t *buflp = (void *)(rstrm->in_finger); uint32_t mylong; /* first try the inline, fast case */ if ((rstrm->fbtbc >= BYTES_PER_XDR_UNIT) && (((long)rstrm->in_boundry - (long)buflp) >= BYTES_PER_XDR_UNIT)) { *lp = (long)ntohl((uint32_t)(*buflp)); rstrm->fbtbc -= BYTES_PER_XDR_UNIT; rstrm->in_finger += BYTES_PER_XDR_UNIT; } else { if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, BYTES_PER_XDR_UNIT)) return (FALSE); *lp = (long)(int32_t)ntohl(mylong); } return (TRUE); } static bool_t xdrrec_putlong(XDR *xdrs, long *lp) { RECSTREAM *rstrm = xdrs->x_private; int32_t *dest_lp = (void *)(rstrm->out_finger); if (rstrm->out_boundry - rstrm->out_finger < BYTES_PER_XDR_UNIT) { /* * this case should almost never happen so the code is * inefficient */ rstrm->frag_sent = TRUE; if (! flush_out(rstrm, FALSE)) return (FALSE); dest_lp = ((int32_t *)(void *)(rstrm->out_finger)); } rstrm->out_finger += BYTES_PER_XDR_UNIT; *dest_lp = (int32_t)htonl((uint32_t)(*lp)); return (TRUE); } static bool_t /* must manage buffers, fragments, and records */ xdrrec_getbytes(XDR *xdrs, caddr_t addr, u_int len) { RECSTREAM *rstrm = xdrs->x_private; u_int current; while (len > 0) { current = rstrm->fbtbc; if (current == 0) { if (rstrm->last_frag) return (FALSE); if (! set_input_fragment(rstrm)) return (FALSE); continue; } current = (len < current) ? len : current; if (! get_input_bytes(rstrm, addr, current)) return (FALSE); addr += current; rstrm->fbtbc -= current; len -= current; } return (TRUE); } static bool_t xdrrec_putbytes(XDR *xdrs, caddr_t addr, u_int len) { RECSTREAM *rstrm = xdrs->x_private; size_t current; while (len > 0) { current = (size_t) ((long)rstrm->out_boundry - (long)rstrm->out_finger); current = (len < current) ? len : current; memmove(rstrm->out_finger, addr, current); rstrm->out_finger += current; addr += current; len -= current; if (rstrm->out_finger == rstrm->out_boundry) { rstrm->frag_sent = TRUE; if (! flush_out(rstrm, FALSE)) return (FALSE); } } return (TRUE); } static u_int xdrrec_getpos(XDR *xdrs) { RECSTREAM *rstrm = xdrs->x_private; int pos; switch (xdrs->x_op) { case XDR_ENCODE: pos = rstrm->out_finger - rstrm->out_base - BYTES_PER_XDR_UNIT; break; case XDR_DECODE: pos = rstrm->in_boundry - rstrm->in_finger - BYTES_PER_XDR_UNIT; break; default: pos = -1; break; } return ((u_int) pos); } static bool_t xdrrec_setpos(XDR *xdrs, u_int pos) { RECSTREAM *rstrm = xdrs->x_private; u_int currpos = xdrrec_getpos(xdrs); int delta = currpos - pos; caddr_t newpos; if ((int)currpos != -1) switch (xdrs->x_op) { case XDR_ENCODE: newpos = rstrm->out_finger - delta; if ((newpos > (caddr_t)(rstrm->frag_header)) && (newpos < rstrm->out_boundry)) { rstrm->out_finger = newpos; return (TRUE); } break; case XDR_DECODE: newpos = rstrm->in_finger - delta; if ((delta < (int)(rstrm->fbtbc)) && (newpos <= rstrm->in_boundry) && (newpos >= rstrm->in_base)) { rstrm->in_finger = newpos; rstrm->fbtbc -= delta; return (TRUE); } break; case XDR_FREE: break; } return (FALSE); } static rpc_inline_t * xdrrec_inline(XDR *xdrs, int len) { RECSTREAM *rstrm = xdrs->x_private; rpc_inline_t * buf = NULL; if (len < 0) return (FALSE); switch (xdrs->x_op) { case XDR_ENCODE: if (len <= (rstrm->out_boundry - rstrm->out_finger)) { buf = (rpc_inline_t *)(void *) rstrm->out_finger; rstrm->out_finger += len; } break; case XDR_DECODE: if ((len <= rstrm->fbtbc) && (len <= (rstrm->in_boundry - rstrm->in_finger))) { buf = (rpc_inline_t *)(void *) rstrm->in_finger; rstrm->fbtbc -= len; rstrm->in_finger += len; } break; case XDR_FREE: break; } return (buf); } static void xdrrec_destroy(XDR *xdrs) { RECSTREAM *rstrm = xdrs->x_private; mem_free(rstrm->the_buffer, rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); mem_free((caddr_t)rstrm, sizeof(RECSTREAM)); } /* * Exported routines to manage xdr records */ /* * Before reading (deserializing from the stream, one should always call * this procedure to guarantee proper record alignment. */ bool_t xdrrec_skiprecord(XDR *xdrs) { RECSTREAM *rstrm = xdrs->x_private; while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { if (! skip_input_bytes(rstrm, rstrm->fbtbc)) return (FALSE); rstrm->fbtbc = 0; if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) return (FALSE); } rstrm->last_frag = FALSE; return (TRUE); } /* * Look ahead function. * Returns TRUE iff there is no more input in the buffer * after consuming the rest of the current record. */ bool_t xdrrec_eof(XDR *xdrs) { RECSTREAM *rstrm = xdrs->x_private; while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { if (! skip_input_bytes(rstrm, rstrm->fbtbc)) return (TRUE); rstrm->fbtbc = 0; if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) return (TRUE); } if (rstrm->in_finger == rstrm->in_boundry) return (TRUE); return (FALSE); } /* * The client must tell the package when an end-of-record has occurred. * The second paraemters tells whether the record should be flushed to the * (output) tcp stream. (This lets the package support batched or * pipelined procedure calls.) TRUE => immediate flush to tcp connection. */ bool_t xdrrec_endofrecord(XDR *xdrs, bool_t sendnow) { RECSTREAM *rstrm = xdrs->x_private; uint32_t len; /* fragment length */ if (sendnow || rstrm->frag_sent || ((long)rstrm->out_finger + BYTES_PER_XDR_UNIT >= (long)rstrm->out_boundry)) { rstrm->frag_sent = FALSE; return (flush_out(rstrm, TRUE)); } len = (long)(rstrm->out_finger) - (long)(rstrm->frag_header) - BYTES_PER_XDR_UNIT; *(rstrm->frag_header) = htonl((uint32_t)len | LAST_FRAG); rstrm->frag_header = (uint32_t *)(void *)rstrm->out_finger; rstrm->out_finger += BYTES_PER_XDR_UNIT; return (TRUE); } /* * Internal useful routines */ static bool_t flush_out(RECSTREAM *rstrm, bool_t eor) { uint32_t eormask = (eor == TRUE) ? LAST_FRAG : 0; uint32_t len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) - BYTES_PER_XDR_UNIT; *(rstrm->frag_header) = htonl(len | eormask); len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base); if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len) != (int)len) return (FALSE); rstrm->frag_header = (uint32_t *)(void *)rstrm->out_base; rstrm->out_finger = (caddr_t)rstrm->out_base + BYTES_PER_XDR_UNIT; return (TRUE); } static bool_t /* knows nothing about records! Only about input buffers */ fill_input_buf(RECSTREAM *rstrm) { caddr_t where; u_int i; int len; where = rstrm->in_base; i = (u_int)((u_long)rstrm->in_boundry % BYTES_PER_XDR_UNIT); where += i; len = rstrm->in_size - i; if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1) return (FALSE); rstrm->in_finger = where; where += len; rstrm->in_boundry = where; return (TRUE); } static bool_t /* knows nothing about records! Only about input buffers */ get_input_bytes(RECSTREAM *rstrm, caddr_t addr, int len) { size_t current; while (len > 0) { current = (size_t)((long)rstrm->in_boundry - (long)rstrm->in_finger); if (current == 0) { if (! fill_input_buf(rstrm)) return (FALSE); continue; } current = ((size_t)len < current) ? (size_t)len : current; memmove(addr, rstrm->in_finger, current); rstrm->in_finger += current; addr += current; len -= current; } return (TRUE); } static bool_t /* next four bytes of input stream are treated as a header */ set_input_fragment(RECSTREAM *rstrm) { uint32_t header; if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header))) return (FALSE); header = ntohl(header); rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE; rstrm->fbtbc = header & (~LAST_FRAG); return (TRUE); } static bool_t /* consumes input bytes; knows nothing about records! */ skip_input_bytes(RECSTREAM *rstrm, int32_t cnt) { int current; while (cnt > 0) { current = (int)((long)rstrm->in_boundry - (long)rstrm->in_finger); if (current == 0) { if (! fill_input_buf(rstrm)) return (FALSE); continue; } current = (cnt < current) ? cnt : current; rstrm->in_finger += current; cnt -= current; } return (TRUE); } static u_int fix_buf_size(u_int s) { if (s < 100) s = 4000; return (RNDUP(s)); } krb5-1.22.1/src/lib/rpc/clnt_perror.c0000664000175000017500000002101315051422640017154 0ustar ghudsonghudson/* @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro"; #endif /* * clnt_perror.c */ #include "autoconf.h" #include #include #include #include #include #include #ifndef HAVE_STRERROR #ifdef NEED_SYS_ERRLIST extern char *sys_errlist[]; #endif extern int sys_nerr; #undef strerror #define strerror(N) (((N) > 0 && (N) < sys_nerr) ? sys_errlist[N] : (char *)0) #endif /* HAVE_STRERROR */ static char *auth_errmsg(enum auth_stat); static char *buf; static char * get_buf(void) { if (buf == NULL) buf = (char *)malloc(BUFSIZ); return (buf); } /* * Print reply error info */ char * clnt_sperror(CLIENT *rpch, char *s) { struct rpc_err e; char *err; char *bufstart = get_buf(); char *str = bufstart; char *strstart = str; char *strend; if (str == 0) return (0); strend = str + BUFSIZ; CLNT_GETERR(rpch, &e); strncpy (str, s, BUFSIZ - 1); str[BUFSIZ - 1] = 0; strncat (str, ": ", BUFSIZ - 1 - strlen (bufstart)); str += strlen(str); strncat (str, clnt_sperrno(e.re_status), BUFSIZ - 1 - strlen (bufstart)); strstart[BUFSIZ - 1] = '\0'; str += strlen(str); switch (e.re_status) { case RPC_SUCCESS: case RPC_CANTENCODEARGS: case RPC_CANTDECODERES: case RPC_TIMEDOUT: case RPC_PROGUNAVAIL: case RPC_PROCUNAVAIL: case RPC_CANTDECODEARGS: case RPC_SYSTEMERROR: case RPC_UNKNOWNHOST: case RPC_UNKNOWNPROTO: case RPC_PMAPFAILURE: case RPC_PROGNOTREGISTERED: case RPC_FAILED: break; case RPC_CANTSEND: case RPC_CANTRECV: /* 10 for the string */ if (str - bufstart + 10 + strlen(strerror(e.re_errno)) < BUFSIZ) (void) snprintf(str, strend-str, "; errno = %s", strerror(e.re_errno)); str += strlen(str); break; case RPC_VERSMISMATCH: /* 33 for the string, 22 for the numbers */ if(str - bufstart + 33 + 22 < BUFSIZ) (void) snprintf(str, strend-str, "; low version = %lu, high version = %lu", (u_long) e.re_vers.low, (u_long) e.re_vers.high); str += strlen(str); break; case RPC_AUTHERROR: err = auth_errmsg(e.re_why); /* 8 for the string */ if(str - bufstart + 8 < BUFSIZ) (void) snprintf(str, strend-str, "; why = "); str += strlen(str); if (err != NULL) { if(str - bufstart + strlen(err) < BUFSIZ) (void) snprintf(str, strend-str, "%s",err); } else { /* 33 for the string, 11 for the number */ if(str - bufstart + 33 + 11 < BUFSIZ) (void) snprintf(str, strend-str, "(unknown authentication error - %d)", (int) e.re_why); } str += strlen(str); break; case RPC_PROGVERSMISMATCH: /* 33 for the string, 22 for the numbers */ if(str - bufstart + 33 + 22 < BUFSIZ) (void) snprintf(str, strend-str, "; low version = %lu, high version = %lu", (u_long) e.re_vers.low, (u_long) e.re_vers.high); str += strlen(str); break; default: /* unknown */ /* 14 for the string, 22 for the numbers */ if(str - bufstart + 14 + 22 < BUFSIZ) (void) snprintf(str, strend-str, "; s1 = %lu, s2 = %lu", (u_long) e.re_lb.s1, (u_long) e.re_lb.s2); str += strlen(str); break; } if (str - bufstart + 1 < BUFSIZ) (void) snprintf(str, strend-str, "\n"); return(strstart) ; } void clnt_perror(CLIENT *rpch, char *s) { (void) fprintf(stderr,"%s",clnt_sperror(rpch,s)); } struct rpc_errtab { enum clnt_stat status; char *message; }; static struct rpc_errtab rpc_errlist[] = { { RPC_SUCCESS, "RPC: Success" }, { RPC_CANTENCODEARGS, "RPC: Can't encode arguments" }, { RPC_CANTDECODERES, "RPC: Can't decode result" }, { RPC_CANTSEND, "RPC: Unable to send" }, { RPC_CANTRECV, "RPC: Unable to receive" }, { RPC_TIMEDOUT, "RPC: Timed out" }, { RPC_VERSMISMATCH, "RPC: Incompatible versions of RPC" }, { RPC_AUTHERROR, "RPC: Authentication error" }, { RPC_PROGUNAVAIL, "RPC: Program unavailable" }, { RPC_PROGVERSMISMATCH, "RPC: Program/version mismatch" }, { RPC_PROCUNAVAIL, "RPC: Procedure unavailable" }, { RPC_CANTDECODEARGS, "RPC: Server can't decode arguments" }, { RPC_SYSTEMERROR, "RPC: Remote system error" }, { RPC_UNKNOWNHOST, "RPC: Unknown host" }, { RPC_UNKNOWNPROTO, "RPC: Unknown protocol" }, { RPC_PMAPFAILURE, "RPC: Port mapper failure" }, { RPC_PROGNOTREGISTERED, "RPC: Program not registered"}, { RPC_FAILED, "RPC: Failed (unspecified error)"} }; /* * This interface for use by clntrpc */ char * clnt_sperrno(enum clnt_stat stat) { unsigned int i; for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) { if (rpc_errlist[i].status == stat) { return (rpc_errlist[i].message); } } return ("RPC: (unknown error code)"); } void clnt_perrno(enum clnt_stat num) { (void) fprintf(stderr,"%s",clnt_sperrno(num)); } char * clnt_spcreateerror(char *s) { char *str = get_buf(); char *strend; if (str == 0) return(0); strend = str+BUFSIZ; (void) snprintf(str, strend-str, "%s: ", s); str[BUFSIZ - 1] = '\0'; (void) strncat(str, clnt_sperrno(rpc_createerr.cf_stat), BUFSIZ - 1); switch (rpc_createerr.cf_stat) { case RPC_PMAPFAILURE: (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str)); (void) strncat(str, clnt_sperrno(rpc_createerr.cf_error.re_status), BUFSIZ - 1 - strlen(str)); break; case RPC_SYSTEMERROR: (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str)); { const char *m = strerror(rpc_createerr.cf_error.re_errno); if (m) (void) strncat(str, m, BUFSIZ - 1 - strlen(str)); else (void) snprintf(&str[strlen(str)], BUFSIZ - strlen(str), "Error %d", rpc_createerr.cf_error.re_errno); } break; case RPC_CANTSEND: case RPC_CANTDECODERES: case RPC_CANTENCODEARGS: case RPC_SUCCESS: case RPC_UNKNOWNPROTO: case RPC_PROGNOTREGISTERED: case RPC_FAILED: case RPC_UNKNOWNHOST: case RPC_CANTDECODEARGS: case RPC_PROCUNAVAIL: case RPC_PROGVERSMISMATCH: case RPC_PROGUNAVAIL: case RPC_AUTHERROR: case RPC_VERSMISMATCH: case RPC_TIMEDOUT: case RPC_CANTRECV: default: break; } (void) strncat(str, "\n", BUFSIZ - 1 - strlen(str)); return (str); } void clnt_pcreateerror(char *s) { (void) fprintf(stderr,"%s",clnt_spcreateerror(s)); } struct auth_errtab { enum auth_stat status; char *message; }; static struct auth_errtab auth_errlist[] = { { AUTH_OK, "Authentication OK" }, { AUTH_BADCRED, "Invalid client credential" }, { AUTH_REJECTEDCRED, "Server rejected credential" }, { AUTH_BADVERF, "Invalid client verifier" }, { AUTH_REJECTEDVERF, "Server rejected verifier" }, { AUTH_TOOWEAK, "Client credential too weak" }, { AUTH_INVALIDRESP, "Invalid server verifier" }, { AUTH_FAILED, "Failed (unspecified error)" }, }; static char * auth_errmsg(enum auth_stat stat) { unsigned int i; for (i = 0; i < sizeof(auth_errlist)/sizeof(struct auth_errtab); i++) { if (auth_errlist[i].status == stat) { return(auth_errlist[i].message); } } return(NULL); } krb5-1.22.1/src/lib/rpc/clnt_udp.c0000664000175000017500000003267315051422640016451 0ustar ghudsonghudson/* @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro"; #endif /* * clnt_udp.c, Implements a UDP/IP based, client side RPC. */ #include #include #include #include #include #if defined(sun) #include #endif #include #include #include #include #include #include #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE int #endif /* * UDP bases client side rpc operations */ static enum clnt_stat clntudp_call(CLIENT *, rpcproc_t, xdrproc_t, void *, xdrproc_t, void *, struct timeval); static void clntudp_abort(CLIENT *); static void clntudp_geterr(CLIENT *, struct rpc_err *); static bool_t clntudp_freeres(CLIENT *, xdrproc_t, void *); static bool_t clntudp_control(CLIENT *, int, void *); static void clntudp_destroy(CLIENT *); static struct clnt_ops udp_ops = { clntudp_call, clntudp_abort, clntudp_geterr, clntudp_freeres, clntudp_destroy, clntudp_control }; /* * Private data kept per client handle */ struct cu_data { SOCKET cu_sock; bool_t cu_closeit; struct sockaddr_in cu_raddr; int cu_rlen; struct sockaddr_in cu_laddr; GETSOCKNAME_ARG3_TYPE cu_llen; struct timeval cu_wait; struct timeval cu_total; struct rpc_err cu_error; XDR cu_outxdrs; u_int cu_xdrpos; u_int cu_sendsz; char *cu_outbuf; u_int cu_recvsz; char cu_inbuf[1]; }; /* * Create a UDP based client handle. * If *sockp<0, *sockp is set to a newly created UPD socket. * If raddr->sin_port is 0 a binder on the remote machine * is consulted for the correct port number. * NB: It is the clients responsibility to close *sockp. * NB: The rpch->cl_auth is initialized to null authentication. * Caller may wish to set this something more useful. * * wait is the amount of time used between retransmitting a call if * no response has been heard; retransmission occurs until the actual * rpc call times out. * * sendsz and recvsz are the maximum allowable packet sizes that can be * sent and received. */ CLIENT * clntudp_bufcreate( struct sockaddr_in *raddr, rpcprog_t program, rpcvers_t version, struct timeval wait, int *sockp, u_int sendsz, u_int recvsz) { CLIENT *cl; struct cu_data *cu = 0; struct timeval now; struct rpc_msg call_msg; cl = (CLIENT *)mem_alloc(sizeof(CLIENT)); if (cl == NULL) { (void) fprintf(stderr, "clntudp_create: out of memory\n"); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; goto fooy; } sendsz = ((sendsz + 3) / 4) * 4; recvsz = ((recvsz + 3) / 4) * 4; cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz); if (cu == NULL) { (void) fprintf(stderr, "clntudp_create: out of memory\n"); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; goto fooy; } cu->cu_outbuf = &cu->cu_inbuf[recvsz]; (void)gettimeofday(&now, (struct timezone *)0); if (raddr->sin_port == 0) { u_short port; if ((port = pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) { goto fooy; } raddr->sin_port = htons(port); } cl->cl_ops = &udp_ops; cl->cl_private = (caddr_t)cu; cu->cu_raddr = *raddr; cu->cu_rlen = sizeof (cu->cu_raddr); cu->cu_wait = wait; cu->cu_total.tv_sec = -1; cu->cu_total.tv_usec = -1; cu->cu_sendsz = sendsz; cu->cu_recvsz = recvsz; call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; call_msg.rm_direction = CALL; call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; call_msg.rm_call.cb_prog = program; call_msg.rm_call.cb_vers = version; xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE); if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) { goto fooy; } cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs)); if (*sockp < 0) { int dontblock = 1; *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (*sockp < 0) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; goto fooy; } /* attempt to bind to prov port */ (void)bindresvport_sa(*sockp, NULL); /* the sockets rpc controls are non-blocking */ (void)ioctl(*sockp, FIONBIO, (char *) &dontblock); cu->cu_closeit = TRUE; } else { cu->cu_closeit = FALSE; } if (connect(*sockp, (struct sockaddr *)raddr, sizeof(*raddr)) < 0) goto fooy; cu->cu_llen = sizeof(cu->cu_laddr); if (getsockname(*sockp, (struct sockaddr *)&cu->cu_laddr, &cu->cu_llen) < 0) goto fooy; cu->cu_sock = *sockp; cl->cl_auth = authnone_create(); return (cl); fooy: if (cu) mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz); if (cl) mem_free((caddr_t)cl, sizeof(CLIENT)); return ((CLIENT *)NULL); } CLIENT * clntudp_create( struct sockaddr_in *raddr, rpcprog_t program, rpcvers_t version, struct timeval wait, int *sockp) { return(clntudp_bufcreate(raddr, program, version, wait, sockp, UDPMSGSIZE, UDPMSGSIZE)); } static enum clnt_stat clntudp_call( CLIENT *cl, /* client handle */ rpcproc_t proc, /* procedure number */ xdrproc_t xargs, /* xdr routine for args */ void * argsp, /* pointer to args */ xdrproc_t xresults, /* xdr routine for results */ void * resultsp, /* pointer to results */ struct timeval utimeout /* seconds to wait before * giving up */ ) { struct cu_data *cu = (struct cu_data *)cl->cl_private; XDR *xdrs; int outlen; ssize_t inlen; GETSOCKNAME_ARG3_TYPE fromlen; /* Assumes recvfrom uses same type */ #ifdef FD_SETSIZE fd_set readfds; fd_set mask; #else int readfds; int mask; #endif /* def FD_SETSIZE */ struct sockaddr_in from; struct rpc_msg reply_msg; XDR reply_xdrs; struct timeval time_waited, seltimeout; bool_t ok; int nrefreshes = 2; /* number of times to refresh cred */ struct timeval timeout; long procl = proc; if (cu->cu_total.tv_usec == -1) { timeout = utimeout; /* use supplied timeout */ } else { timeout = cu->cu_total; /* use default timeout */ } time_waited.tv_sec = 0; time_waited.tv_usec = 0; call_again: xdrs = &(cu->cu_outxdrs); xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, cu->cu_xdrpos); /* * the transaction is the first thing in the out buffer */ (*(uint32_t *)(void *)(cu->cu_outbuf))++; if ((! XDR_PUTLONG(xdrs, &procl)) || (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || (! AUTH_WRAP(cl->cl_auth, xdrs, xargs, argsp))) return (cu->cu_error.re_status = RPC_CANTENCODEARGS); outlen = (int)XDR_GETPOS(xdrs); send_again: if (send(cu->cu_sock, cu->cu_outbuf, (u_int)outlen, 0) != outlen) { cu->cu_error.re_errno = errno; return (cu->cu_error.re_status = RPC_CANTSEND); } /* * Hack to provide rpc-based message passing */ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { return (cu->cu_error.re_status = RPC_TIMEDOUT); } /* * sub-optimal code appears here because we have * some clock time to spare while the packets are in flight. * (We assume that this is actually only executed once.) */ reply_msg.acpted_rply.ar_verf = gssrpc__null_auth; reply_msg.acpted_rply.ar_results.where = NULL; reply_msg.acpted_rply.ar_results.proc = xdr_void; #ifdef FD_SETSIZE FD_ZERO(&mask); FD_SET(cu->cu_sock, &mask); #else mask = 1 << cu->cu_sock; #endif /* def FD_SETSIZE */ for (;;) { readfds = mask; seltimeout = cu->cu_wait; switch (select(gssrpc__rpc_dtablesize(), &readfds, (fd_set *)NULL, (fd_set *)NULL, &seltimeout)) { case 0: time_waited.tv_sec += cu->cu_wait.tv_sec; time_waited.tv_usec += cu->cu_wait.tv_usec; while (time_waited.tv_usec >= 1000000) { time_waited.tv_sec++; time_waited.tv_usec -= 1000000; } if ((time_waited.tv_sec < timeout.tv_sec) || ((time_waited.tv_sec == timeout.tv_sec) && (time_waited.tv_usec < timeout.tv_usec))) goto send_again; return (cu->cu_error.re_status = RPC_TIMEDOUT); /* * buggy in other cases because time_waited is not being * updated. */ case -1: if (errno == EINTR) continue; cu->cu_error.re_errno = errno; return (cu->cu_error.re_status = RPC_CANTRECV); } do { fromlen = sizeof(struct sockaddr); inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, cu->cu_recvsz, 0, (struct sockaddr *)&from, &fromlen); } while (inlen < 0 && errno == EINTR); if (inlen < 0) { if (errno == EWOULDBLOCK) continue; cu->cu_error.re_errno = errno; return (cu->cu_error.re_status = RPC_CANTRECV); } if ((size_t)inlen < sizeof(uint32_t)) continue; /* see if reply transaction id matches sent id */ if (*((uint32_t *)(void *)(cu->cu_inbuf)) != *((uint32_t *)(void *)(cu->cu_outbuf))) continue; /* we now assume we have the proper reply */ break; } /* * now decode and validate the response */ xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE); ok = xdr_replymsg(&reply_xdrs, &reply_msg); /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */ if (ok) { gssrpc__seterr_reply(&reply_msg, &(cu->cu_error)); if (cu->cu_error.re_status == RPC_SUCCESS) { if (! AUTH_VALIDATE(cl->cl_auth, &reply_msg.acpted_rply.ar_verf)) { cu->cu_error.re_status = RPC_AUTHERROR; cu->cu_error.re_why = AUTH_INVALIDRESP; } else if (! AUTH_UNWRAP(cl->cl_auth, &reply_xdrs, xresults, resultsp)) { if (cu->cu_error.re_status == RPC_SUCCESS) cu->cu_error.re_status = RPC_CANTDECODERES; } } /* end successful completion */ else { /* maybe our credentials need to be refreshed ... */ if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth, &reply_msg)) { nrefreshes--; goto call_again; } } /* end of unsuccessful completion */ /* free verifier */ if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) && (reply_msg.acpted_rply.ar_verf.oa_base != NULL)) { xdrs->x_op = XDR_FREE; (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); } } /* end of valid reply message */ else { /* * It's possible for xdr_replymsg() to fail partway * through its attempt to decode the result from the * server. If this happens, it will leave the reply * structure partially populated with dynamically * allocated memory. (This can happen if someone uses * clntudp_bufcreate() to create a CLIENT handle and * specifies a receive buffer size that is too small.) * This memory must be free()ed to avoid a leak. */ enum xdr_op op = reply_xdrs.x_op; reply_xdrs.x_op = XDR_FREE; xdr_replymsg(&reply_xdrs, &reply_msg); reply_xdrs.x_op = op; cu->cu_error.re_status = RPC_CANTDECODERES; } return (cu->cu_error.re_status); } static void clntudp_geterr( CLIENT *cl, struct rpc_err *errp) { struct cu_data *cu = (struct cu_data *)cl->cl_private; *errp = cu->cu_error; } static bool_t clntudp_freeres( CLIENT *cl, xdrproc_t xdr_res, void *res_ptr) { struct cu_data *cu = cl->cl_private; XDR *xdrs = &cu->cu_outxdrs; xdrs->x_op = XDR_FREE; return ((*xdr_res)(xdrs, res_ptr)); } /*ARGSUSED*/ static void clntudp_abort(CLIENT *h) { } static bool_t clntudp_control( CLIENT *cl, int request, void *info) { struct cu_data *cu = cl->cl_private; switch (request) { case CLSET_TIMEOUT: cu->cu_total = *(struct timeval *)info; break; case CLGET_TIMEOUT: *(struct timeval *)info = cu->cu_total; break; case CLSET_RETRY_TIMEOUT: cu->cu_wait = *(struct timeval *)info; break; case CLGET_RETRY_TIMEOUT: *(struct timeval *)info = cu->cu_wait; break; case CLGET_SERVER_ADDR: *(struct sockaddr_in *)info = cu->cu_raddr; break; case CLGET_LOCAL_ADDR: *(struct sockaddr_in *)info = cu->cu_laddr; break; default: return (FALSE); } return (TRUE); } static void clntudp_destroy(CLIENT *cl) { struct cu_data *cu = (struct cu_data *)cl->cl_private; if (cu->cu_closeit) (void)closesocket(cu->cu_sock); XDR_DESTROY(&(cu->cu_outxdrs)); mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz)); mem_free((caddr_t)cl, sizeof(CLIENT)); } krb5-1.22.1/src/lib/rpc/Makefile.in0000664000175000017500000001236415051422640016535 0ustar ghudsonghudsonmydir=lib$(S)rpc BUILDTOP=$(REL)..$(S).. DEFINES = -DGSSAPI_KRB5 -DDEBUG_GSSAPI=0 -DGSSRPC__IMPL SUBDIRS=unit-test ##DOSBUILDTOP = ..\.. ##DOSLIBNAME=libgssrpc.lib LIBBASE=gssrpc LIBMAJOR=4 LIBMINOR=2 SHLIB_EXPDEPS= \ $(TOPLIBD)/libgssapi_krb5$(SHLIBEXT) \ $(TOPLIBD)/libkrb5$(SHLIBEXT) \ $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ $(COM_ERR_DEPLIB) SHLIB_EXPLIBS=-lgssapi_krb5 -lkrb5 -lk5crypto $(COM_ERR_LIB) $(LIBS) RELDIR=rpc SRCS = $(srcdir)/auth_none.c \ $(srcdir)/auth_unix.c \ $(srcdir)/authgss_prot.c \ $(srcdir)/authunix_prot.c \ $(srcdir)/auth_gss.c \ $(srcdir)/auth_gssapi.c \ $(srcdir)/auth_gssapi_misc.c \ $(srcdir)/bindresvport.c \ $(srcdir)/clnt_generic.c \ $(srcdir)/clnt_perror.c \ $(srcdir)/clnt_raw.c \ $(srcdir)/clnt_simple.c \ $(srcdir)/clnt_tcp.c \ $(srcdir)/clnt_udp.c \ $(srcdir)/dyn.c \ $(srcdir)/rpc_dtablesize.c \ $(srcdir)/get_myaddress.c \ $(srcdir)/getrpcport.c \ $(srcdir)/pmap_clnt.c \ $(srcdir)/pmap_getmaps.c \ $(srcdir)/pmap_getport.c \ $(srcdir)/pmap_prot.c \ $(srcdir)/pmap_prot2.c \ $(srcdir)/pmap_rmt.c \ $(srcdir)/rpc_prot.c \ $(srcdir)/rpc_commondata.c \ $(srcdir)/rpc_callmsg.c \ $(srcdir)/svc.c \ $(srcdir)/svc_auth.c \ $(srcdir)/svc_auth_gss.c \ $(srcdir)/svc_auth_none.c \ $(srcdir)/svc_auth_unix.c \ $(srcdir)/svc_auth_gssapi.c \ $(srcdir)/svc_raw.c \ $(srcdir)/svc_run.c \ $(srcdir)/svc_simple.c \ $(srcdir)/svc_tcp.c \ $(srcdir)/svc_udp.c \ $(srcdir)/xdr.c \ $(srcdir)/xdr_array.c \ $(srcdir)/xdr_float.c \ $(srcdir)/xdr_mem.c \ $(srcdir)/xdr_rec.c \ $(srcdir)/xdr_reference.c \ $(srcdir)/xdr_stdio.c \ $(srcdir)/xdr_sizeof.c \ $(srcdir)/xdr_alloc.c OBJS = auth_none.$(OBJEXT) \ auth_unix.$(OBJEXT) \ authunix_prot.$(OBJEXT) \ authgss_prot.$(OBJEXT) \ auth_gss.$(OBJEXT) \ auth_gssapi.$(OBJEXT) \ auth_gssapi_misc.$(OBJEXT) \ bindresvport.$(OBJEXT) \ clnt_generic.$(OBJEXT) \ clnt_perror.$(OBJEXT) \ clnt_raw.$(OBJEXT) \ clnt_simple.$(OBJEXT) \ clnt_tcp.$(OBJEXT) \ clnt_udp.$(OBJEXT) \ dyn.$(OBJEXT) \ rpc_dtablesize.$(OBJEXT) \ get_myaddress.$(OBJEXT) \ getrpcport.$(OBJEXT) \ pmap_clnt.$(OBJEXT) \ pmap_getmaps.$(OBJEXT) \ pmap_getport.$(OBJEXT) \ pmap_prot.$(OBJEXT) \ pmap_prot2.$(OBJEXT) \ pmap_rmt.$(OBJEXT) \ rpc_prot.$(OBJEXT) \ rpc_commondata.$(OBJEXT) \ rpc_callmsg.$(OBJEXT) \ svc.$(OBJEXT) \ svc_auth.$(OBJEXT) \ svc_auth_gss.$(OBJEXT) \ svc_auth_none.$(OBJEXT) \ svc_auth_unix.$(OBJEXT) \ svc_auth_gssapi.$(OBJEXT) \ svc_raw.$(OBJEXT) \ svc_run.$(OBJEXT) \ svc_simple.$(OBJEXT) \ svc_tcp.$(OBJEXT) \ svc_udp.$(OBJEXT) \ xdr.$(OBJEXT) \ xdr_array.$(OBJEXT) \ xdr_float.$(OBJEXT) \ xdr_mem.$(OBJEXT) \ xdr_rec.$(OBJEXT) \ xdr_reference.$(OBJEXT) \ xdr_stdio.$(OBJEXT) \ xdr_sizeof.$(OBJEXT) \ xdr_alloc.$(OBJEXT) STLIBOBJS = \ auth_none.o \ auth_unix.o \ authgss_prot.o \ authunix_prot.o \ auth_gss.o \ auth_gssapi.o \ auth_gssapi_misc.o \ bindresvport.o \ clnt_generic.o \ clnt_perror.o \ clnt_raw.o \ clnt_simple.o \ clnt_tcp.o \ clnt_udp.o \ dyn.o \ rpc_dtablesize.o \ get_myaddress.o \ getrpcport.o \ pmap_clnt.o \ pmap_getmaps.o \ pmap_getport.o \ pmap_prot.o \ pmap_prot2.o \ pmap_rmt.o \ rpc_prot.o \ rpc_commondata.o \ rpc_callmsg.o \ svc.o \ svc_auth.o \ svc_auth_gss.o \ svc_auth_gssapi.o \ svc_auth_none.o \ svc_auth_unix.o \ svc_raw.o \ svc_run.o \ svc_simple.o \ svc_tcp.o \ svc_udp.o \ xdr.o \ xdr_array.o \ xdr_float.o \ xdr_mem.o \ xdr_rec.o \ xdr_reference.o \ xdr_stdio.o \ xdr_sizeof.o \ xdr_alloc.o HDRDIR=$(BUILDTOP)/include/gssrpc all-prerecurse: all-liblinks all-windows: $(OBJS) generate-files-mac: darwin.exports install-unix: install-libs install-unix: for i in $(SRC_HDRS); do \ (set -x; $(INSTALL_DATA) $(srcdir)/../../include/gssrpc/$$i $(DESTDIR)$(KRB5_INCDIR)$(S)gssrpc$(S)$$i) ; \ done for i in $(BUILD_HDRS); do \ (set -x; $(INSTALL_DATA) ../../include/gssrpc/$$i $(DESTDIR)$(KRB5_INCDIR)$(S)gssrpc$(S)$$i) ; \ done BUILD_HDRS = types.h SRC_HDRS = auth.h auth_gss.h auth_gssapi.h auth_unix.h clnt.h \ netdb.h pmap_clnt.h pmap_prot.h pmap_rmt.h rename.h \ rpc.h rpc_msg.h svc.h svc_auth.h xdr.h check-windows: clean-unix:: clean-liblinks clean-libs clean-libobjs clean-windows:: # stuff picked up from old "dyn" library #check-unix: run-dyntest run-dyntest: dyntest ./dyntest dyntest: dyntest.o dyn.o $(CC) -o dyntest dyntest.o dyn.o clean-unix:: clean-dyntest clean-dyntest: $(RM) dyntest dyntest.o LCLINT= lclint # +posixlib gets more complete errno list than ansilib # -usedef turns off bogus warnings from poor dataflow analysis (should be # redundant with gcc warnings anyways) # -warnposix # +charintliteral # +ignoresigns # -predboolint # -exportlocal # -retvalint allow ignoring of int return values (e.g., fputs) LCLINTOPTS=+posixlib \ +ignoresigns -predboolint \ +mod-uncon +modinternalstrict +modfilesys \ -expect 2 do-dyn-lclint: $(LCLINT) $(LCLINTOPTS) $(LOCALINCLUDES) $(DEFS) dyn.c dyntest.c $(BUILDTOP)/include/gssrpc/types.h: types.stamp types.stamp: $(top_srcdir)/include/gssrpc/types.hin $(BUILDTOP)/config.status (cd $(BUILDTOP) && $(SHELL) config.status include/gssrpc/types.h) touch types.stamp clean-unix:: $(RM) types.stamp $(BUILDTOP)/include/gssrpc/types.h clean-windows:: $(RM) types.stamp @lib_frag@ @libobj_frag@ krb5-1.22.1/src/lib/rpc/xdr_mem.c0000664000175000017500000001163215051422640016264 0ustar ghudsonghudson/* @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro"; #endif /* * xdr_mem.h, XDR implementation using memory buffers. * * If you have some data to be interpreted as external data representation * or to be converted to external data representation in a memory buffer, * then this is the package for you. * */ #include #include #include #include #include #include static bool_t xdrmem_getlong(XDR *, long *); static bool_t xdrmem_putlong(XDR *, long *); static bool_t xdrmem_getbytes(XDR *, caddr_t, u_int); static bool_t xdrmem_putbytes(XDR *, caddr_t, u_int); static u_int xdrmem_getpos(XDR *); static bool_t xdrmem_setpos(XDR *, u_int); static rpc_inline_t * xdrmem_inline(XDR *, int); static void xdrmem_destroy(XDR *); static struct xdr_ops xdrmem_ops = { xdrmem_getlong, xdrmem_putlong, xdrmem_getbytes, xdrmem_putbytes, xdrmem_getpos, xdrmem_setpos, xdrmem_inline, xdrmem_destroy }; /* * The procedure xdrmem_create initializes a stream descriptor for a * memory buffer. */ void xdrmem_create( XDR *xdrs, caddr_t addr, u_int size, enum xdr_op op) { xdrs->x_op = op; xdrs->x_ops = &xdrmem_ops; xdrs->x_private = xdrs->x_base = addr; xdrs->x_handy = (size > INT_MAX) ? INT_MAX : size; /* XXX */ } static void xdrmem_destroy(XDR *xdrs) { } static bool_t xdrmem_getlong(XDR *xdrs, long *lp) { if (xdrs->x_handy < BYTES_PER_XDR_UNIT) return (FALSE); else xdrs->x_handy -= BYTES_PER_XDR_UNIT; *lp = (long)(int32_t)ntohl(*((uint32_t *)(xdrs->x_private))); xdrs->x_private = (char *)xdrs->x_private + BYTES_PER_XDR_UNIT; return (TRUE); } static bool_t xdrmem_putlong(XDR *xdrs, long *lp) { if (xdrs->x_handy < BYTES_PER_XDR_UNIT) return (FALSE); else xdrs->x_handy -= BYTES_PER_XDR_UNIT; *(int32_t *)xdrs->x_private = (int32_t)htonl((uint32_t)(*lp)); xdrs->x_private = (char *)xdrs->x_private + BYTES_PER_XDR_UNIT; return (TRUE); } static bool_t xdrmem_getbytes(XDR *xdrs, caddr_t addr, u_int len) { if ((u_int)xdrs->x_handy < len) return (FALSE); else xdrs->x_handy -= len; memmove(addr, xdrs->x_private, len); xdrs->x_private = (char *)xdrs->x_private + len; return (TRUE); } static bool_t xdrmem_putbytes(XDR *xdrs, caddr_t addr, u_int len) { if ((u_int)xdrs->x_handy < len) return (FALSE); else xdrs->x_handy -= len; memmove(xdrs->x_private, addr, len); xdrs->x_private = (char *)xdrs->x_private + len; return (TRUE); } static u_int xdrmem_getpos(XDR *xdrs) { /* * 11/3/95 - JRG - Rather than recast everything for 64 bit, just convert * pointers to longs, then cast to int. */ return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base); } static bool_t xdrmem_setpos(XDR *xdrs, u_int pos) { caddr_t newaddr = xdrs->x_base + pos; caddr_t lastaddr = (char *)xdrs->x_private + xdrs->x_handy; if ((long)newaddr > (long)lastaddr) return (FALSE); xdrs->x_private = newaddr; xdrs->x_handy = (int)((long)lastaddr - (long)newaddr); return (TRUE); } static rpc_inline_t * xdrmem_inline(XDR *xdrs, int len) { rpc_inline_t *buf = 0; if (len >= 0 && xdrs->x_handy >= len) { xdrs->x_handy -= len; buf = (rpc_inline_t *) xdrs->x_private; xdrs->x_private = (char *)xdrs->x_private + len; } return (buf); } krb5-1.22.1/src/lib/rpc/pmap_getmaps.c0000664000175000017500000000575015051422640017312 0ustar ghudsonghudson/* @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro"; #endif /* * pmap_getmap.c * Client interface to pmap rpc service. * contains pmap_getmaps, which is only tcp service involved */ #include #include #include #include #include #include #include #include #ifdef OSF1 #include #include #endif #include #include #define NAMELEN 255 #define MAX_BROADCAST_SIZE 1400 /* * Get a copy of the current port maps. * Calls the pmap service remotely to do get the maps. */ struct pmaplist * pmap_getmaps(struct sockaddr_in *address) { struct pmaplist *head = (struct pmaplist *)NULL; int sock = -1; struct timeval minutetimeout; CLIENT *client; minutetimeout.tv_sec = 60; minutetimeout.tv_usec = 0; address->sin_port = htons(PMAPPORT); client = clnttcp_create(address, PMAPPROG, PMAPVERS, &sock, 50, 500); if (client != (CLIENT *)NULL) { if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, (xdrproc_t)xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) { clnt_perror(client, "pmap_getmaps rpc problem"); } CLNT_DESTROY(client); } (void)close(sock); address->sin_port = 0; return (head); } krb5-1.22.1/src/lib/rpc/clnt_raw.c0000664000175000017500000001553215051422640016445 0ustar ghudsonghudson/* @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro"; #endif /* * clnt_raw.c * * Memory based rpc for simple testing and timing. * Interface to create an rpc client and server in the same process. * This lets us similate rpc and get round trip overhead, without * any interference from the kernel. */ #include #define MCALL_MSG_SIZE 24 /* * This is the "network" we will be moving stuff over. */ static struct clntraw_private { CLIENT client_object; XDR xdr_stream; char _raw_buf[UDPMSGSIZE]; union { struct rpc_msg mashl_rpcmsg; char mashl_callmsg[MCALL_MSG_SIZE]; } u; u_int mcnt; } *clntraw_private; static enum clnt_stat clntraw_call(CLIENT *, rpcproc_t, xdrproc_t, void *, xdrproc_t, void *, struct timeval); static void clntraw_abort(CLIENT *); static void clntraw_geterr(CLIENT *, struct rpc_err *); static bool_t clntraw_freeres(CLIENT *, xdrproc_t, void *); static bool_t clntraw_control(CLIENT *, int, void *); static void clntraw_destroy(CLIENT *); static struct clnt_ops client_ops = { clntraw_call, clntraw_abort, clntraw_geterr, clntraw_freeres, clntraw_destroy, clntraw_control }; void svc_getreq(int); /* * Create a client handle for memory based rpc. */ CLIENT * clntraw_create( rpcprog_t prog, rpcvers_t vers) { struct clntraw_private *clp; struct rpc_msg call_msg; XDR *xdrs; CLIENT *client; if (clntraw_private == NULL) { clntraw_private = calloc(1, sizeof(*clp)); if (clntraw_private == NULL) return (NULL); } clp = clntraw_private; xdrs = &clp->xdr_stream; client = &clp->client_object; /* * pre-serialize the staic part of the call msg and stash it away */ call_msg.rm_direction = CALL; call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; call_msg.rm_call.cb_prog = prog; call_msg.rm_call.cb_vers = vers; xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); if (! xdr_callhdr(xdrs, &call_msg)) { perror("clnt_raw.c - Fatal header serialization error."); } clp->mcnt = XDR_GETPOS(xdrs); XDR_DESTROY(xdrs); /* * Set xdrmem for client/server shared buffer */ xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE); /* * create client handle */ client->cl_ops = &client_ops; client->cl_auth = authnone_create(); return (client); } static enum clnt_stat clntraw_call( CLIENT *h, rpcproc_t proc, xdrproc_t xargs, void * argsp, xdrproc_t xresults, void * resultsp, struct timeval timeout) { struct clntraw_private *clp = clntraw_private; XDR *xdrs = &clp->xdr_stream; struct rpc_msg msg; enum clnt_stat status; struct rpc_err error; long procl = proc; if (clp == 0) return (RPC_FAILED); call_again: /* * send request */ xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); clp->u.mashl_rpcmsg.rm_xid ++ ; if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) || (! XDR_PUTLONG(xdrs, &procl)) || (! AUTH_MARSHALL(h->cl_auth, xdrs)) || (! (*xargs)(xdrs, argsp))) { return (RPC_CANTENCODEARGS); } (void)XDR_GETPOS(xdrs); /* called just to cause overhead */ /* * We have to call server input routine here because this is * all going on in one process. Yuk. */ svc_getreq(1); /* * get results */ xdrs->x_op = XDR_DECODE; XDR_SETPOS(xdrs, 0); msg.acpted_rply.ar_verf = gssrpc__null_auth; msg.acpted_rply.ar_results.where = resultsp; msg.acpted_rply.ar_results.proc = xresults; if (! xdr_replymsg(xdrs, &msg)) { /* * It's possible for xdr_replymsg() to fail partway * through its attempt to decode the result from the * server. If this happens, it will leave the reply * structure partially populated with dynamically * allocated memory. (This can happen if someone uses * clntudp_bufcreate() to create a CLIENT handle and * specifies a receive buffer size that is too small.) * This memory must be free()ed to avoid a leak. */ enum xdr_op op = xdrs->x_op; xdrs->x_op = XDR_FREE; xdr_replymsg(xdrs, &msg); xdrs->x_op = op; return (RPC_CANTDECODERES); } gssrpc__seterr_reply(&msg, &error); status = error.re_status; if (status == RPC_SUCCESS) { if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { status = RPC_AUTHERROR; } } /* end successful completion */ else { if (AUTH_REFRESH(h->cl_auth, &msg)) goto call_again; } /* end of unsuccessful completion */ if (status == RPC_SUCCESS) { if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { status = RPC_AUTHERROR; } if (msg.acpted_rply.ar_verf.oa_base != NULL) { xdrs->x_op = XDR_FREE; (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf)); } } return (status); } /*ARGSUSED*/ static void clntraw_geterr( CLIENT *cl, struct rpc_err *err) { } static bool_t clntraw_freeres( CLIENT *cl, xdrproc_t xdr_res, void *res_ptr) { struct clntraw_private *clp = clntraw_private; XDR *xdrs = &clp->xdr_stream; bool_t rval; if (clp == 0) { rval = (bool_t) RPC_FAILED; return (rval); } xdrs->x_op = XDR_FREE; return ((*xdr_res)(xdrs, res_ptr)); } /*ARGSUSED*/ static void clntraw_abort(CLIENT *cl) { } /*ARGSUSED*/ static bool_t clntraw_control( CLIENT *cl, int request, void *info) { return (FALSE); } /*ARGSUSED*/ static void clntraw_destroy(CLIENT *cl) { } krb5-1.22.1/src/lib/rpc/authunix_prot.c0000664000175000017500000000462215051422640017543 0ustar ghudsonghudson/* @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro"; #endif /* * authunix_prot.c * XDR for UNIX style authentication parameters for RPC */ #include #include #include #include /* * XDR for unix authentication parameters. */ bool_t xdr_authunix_parms(XDR *xdrs, struct authunix_parms *p) { if (xdr_u_int32(xdrs, &(p->aup_time)) && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME) && xdr_int(xdrs, &(p->aup_uid)) && xdr_int(xdrs, &(p->aup_gid)) && xdr_array(xdrs, (caddr_t *)&(p->aup_gids), &(p->aup_len), NGRPS, sizeof(int), (xdrproc_t)xdr_int)) { return (TRUE); } return (FALSE); } krb5-1.22.1/src/lib/rpc/gssrpcint.h0000664000175000017500000000271615051422640016655 0ustar ghudsonghudson/* lib/rpc/gssrpcint.h */ /* * Copyright (C) 2008 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __GSSRPCINT_H__ #define __GSSRPCINT_H__ extern void gssrpcint_printf(const char *format, ...) #if !defined(__cplusplus) && (__GNUC__ > 2) __attribute__((__format__(__printf__, 1, 2))) #endif ; #endif /* __GSSRPCINT_H__ */ krb5-1.22.1/src/lib/rpc/svc_simple.c0000664000175000017500000001056015051422640016774 0ustar ghudsonghudson/* @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro"; #endif /* * svc_simple.c * Simplified front end to rpc. */ #include #include #include #include #include #include static struct proglst { char *(*p_progname)(void *); int p_prognum; int p_procnum; xdrproc_t p_inproc, p_outproc; struct proglst *p_nxt; } *proglst; static void universal(struct svc_req *, SVCXPRT *); static SVCXPRT *transp; int registerrpc( rpcprog_t prognum, rpcvers_t versnum, rpcproc_t procnum, char *(*progname)(void *), xdrproc_t inproc, xdrproc_t outproc) { struct proglst *pl; if (procnum == NULLPROC) { (void) fprintf(stderr, "can't reassign procedure number %d\n", NULLPROC); return (-1); } if (transp == 0) { transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { (void) fprintf(stderr, "couldn't create an rpc server\n"); return (-1); } } (void) pmap_unset(prognum, versnum); if (!svc_register(transp, prognum, versnum, universal, IPPROTO_UDP)) { (void) fprintf(stderr, "couldn't register prog %d vers %d\n", prognum, versnum); return (-1); } pl = (struct proglst *)malloc(sizeof(struct proglst)); if (pl == NULL) { (void) fprintf(stderr, "registerrpc: out of memory\n"); return (-1); } pl->p_progname = progname; pl->p_prognum = prognum; pl->p_procnum = procnum; pl->p_inproc = inproc; pl->p_outproc = outproc; pl->p_nxt = proglst; proglst = pl; return (0); } static void universal( struct svc_req *rqstp, SVCXPRT *s_transp) { int prog, proc; char *outdata; char xdrbuf[UDPMSGSIZE]; struct proglst *pl; /* * enforce "procnum 0 is echo" convention */ if (rqstp->rq_proc == NULLPROC) { if (svc_sendreply(s_transp, xdr_void, (char *)NULL) == FALSE) { (void) fprintf(stderr, "xxx\n"); exit(1); } return; } prog = rqstp->rq_prog; proc = rqstp->rq_proc; for (pl = proglst; pl != NULL; pl = pl->p_nxt) if (pl->p_prognum == prog && pl->p_procnum == proc) { /* decode arguments into a CLEAN buffer */ memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */ if (!svc_getargs(s_transp, pl->p_inproc, xdrbuf)) { svcerr_decode(s_transp); return; } outdata = (*(pl->p_progname))(xdrbuf); if (outdata == NULL && pl->p_outproc != xdr_void) /* there was an error */ return; if (!svc_sendreply(s_transp, pl->p_outproc, outdata)) { (void) fprintf(stderr, "trouble replying to prog %d\n", pl->p_prognum); exit(1); } /* free the decoded arguments */ (void)svc_freeargs(s_transp, pl->p_inproc, xdrbuf); return; } (void) fprintf(stderr, "never registered prog %d\n", prog); exit(1); } krb5-1.22.1/src/lib/rpc/xdr_array.c0000664000175000017500000001051215051422640016620 0ustar ghudsonghudson/* @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro"; #endif /* * xdr_array.c, Generic XDR routines impelmentation. * * These are the "non-trivial" xdr primitives used to serialize and de-serialize * arrays. See xdr.h for more info on the interface to xdr. */ #include #include #include #include #define LASTUNSIGNED ((u_int)0-1) /* * XDR an array of arbitrary elements * *addrp is a pointer to the array, *sizep is the number of elements. * If addrp is NULL (*sizep * elsize) bytes are allocated. * elsize is the size (in bytes) of each element, and elproc is the * xdr procedure to call to handle each element of the array. */ bool_t xdr_array( XDR *xdrs, caddr_t *addrp, /* array pointer */ u_int *sizep, /* number of elements */ u_int maxsize, /* max numberof elements */ u_int elsize, /* size in bytes of each element */ xdrproc_t elproc /* xdr routine to handle each element */ ) { u_int i; caddr_t target = *addrp; u_int c; /* the actual element count */ bool_t stat = TRUE; u_int nodesize; /* like strings, arrays are really counted arrays */ if (! xdr_u_int(xdrs, sizep)) { return (FALSE); } c = *sizep; if ((c > maxsize || c > LASTUNSIGNED / elsize) && (xdrs->x_op != XDR_FREE)) { return (FALSE); } nodesize = c * elsize; /* * if we are deserializing, we may need to allocate an array. * We also save time by checking for a null array if we are freeing. */ if (target == NULL) switch (xdrs->x_op) { case XDR_DECODE: if (c == 0) return (TRUE); *addrp = target = mem_alloc(nodesize); if (target == NULL) { (void) fprintf(stderr, "xdr_array: out of memory\n"); return (FALSE); } memset(target, 0, nodesize); break; case XDR_FREE: return (TRUE); case XDR_ENCODE: break; } /* * now we xdr each element of array */ for (i = 0; (i < c) && stat; i++) { stat = (*elproc)(xdrs, target); target += elsize; } /* * the array may need freeing */ if (xdrs->x_op == XDR_FREE) { mem_free(*addrp, nodesize); *addrp = NULL; } return (stat); } /* * xdr_vector(): * * XDR a fixed length array. Unlike variable-length arrays, * the storage of fixed length arrays is static and unfreeable. * > basep: base of the array * > size: size of the array * > elemsize: size of each element * > xdr_elem: routine to XDR each element */ bool_t xdr_vector( XDR *xdrs, char *basep, u_int nelem, u_int elemsize, xdrproc_t xdr_elem) { u_int i; char *elptr; elptr = basep; for (i = 0; i < nelem; i++) { if (! (*xdr_elem)(xdrs, elptr)) { return(FALSE); } elptr += elemsize; } return(TRUE); } krb5-1.22.1/src/lib/rpc/svc.c0000664000175000017500000003050115051422640015420 0ustar ghudsonghudson/* @(#)svc.c 2.4 88/08/11 4.0 RPCSRC; from 1.44 88/02/08 SMI */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)svc.c 1.41 87/10/13 Copyr 1984 Sun Micro"; #endif /* * svc.c, Server-side remote procedure call interface. * * There are two sets of procedures here. The xprt routines are * for handling transport handles. The svc routines handle the * list of service routines. */ #include "autoconf.h" #if HAVE_SYS_PARAM_H #include #endif #include #include #include #include #include #ifdef FD_SETSIZE static SVCXPRT **xports; extern int gssrpc_svc_fdset_init; #else #ifdef NBBY #define NOFILE (sizeof(int) * NBBY) #else #define NOFILE (sizeof(int) * 8) #endif static SVCXPRT *xports[NOFILE]; #endif /* def FD_SETSIZE */ #define NULL_SVC ((struct svc_callout *)0) #define RQCRED_SIZE 1024 /* this size is excessive */ /* * The services list * Each entry represents a set of procedures (an rpc program). * The dispatch routine takes request structs and runs the * appropriate procedure. */ static struct svc_callout { struct svc_callout *sc_next; rpcprog_t sc_prog; rpcprog_t sc_vers; void (*sc_dispatch)(struct svc_req *, SVCXPRT *); } *svc_head; static struct svc_callout *svc_find(rpcprog_t, rpcvers_t, struct svc_callout **); static void svc_do_xprt(SVCXPRT *xprt); /* *************** SVCXPRT related stuff **************** */ /* * Activate a transport handle. */ void xprt_register(SVCXPRT *xprt) { int sock = xprt->xp_sock; #ifdef FD_SETSIZE if (gssrpc_svc_fdset_init == 0) { FD_ZERO(&svc_fdset); gssrpc_svc_fdset_init++; } if (xports == NULL) { xports = (SVCXPRT **) mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); memset(xports, 0, FD_SETSIZE * sizeof(SVCXPRT *)); } if (sock < FD_SETSIZE) { xports[sock] = xprt; FD_SET(sock, &svc_fdset); if (sock > svc_maxfd) svc_maxfd = sock; } #else if (sock < NOFILE) { xports[sock] = xprt; svc_fds |= (1 << sock); if (sock > svc_maxfd) svc_maxfd = sock; } #endif /* def FD_SETSIZE */ } /* * De-activate a transport handle. */ void xprt_unregister(SVCXPRT *xprt) { int sock = xprt->xp_sock; #ifdef FD_SETSIZE if ((sock < FD_SETSIZE) && (xports[sock] == xprt)) { xports[sock] = (SVCXPRT *)0; FD_CLR(sock, &svc_fdset); } #else if ((sock < NOFILE) && (xports[sock] == xprt)) { xports[sock] = (SVCXPRT *)0; svc_fds &= ~(1 << sock); } #endif /* def FD_SETSIZE */ if (svc_maxfd <= sock) { while ((svc_maxfd > 0) && xports[svc_maxfd] == 0) svc_maxfd--; } } /* ********************** CALLOUT list related stuff ************* */ /* * Add a service program to the callout list. * The dispatch routine will be called when a rpc request for this * program number comes in. */ bool_t svc_register( SVCXPRT *xprt, rpcprog_t prog, rpcvers_t vers, void (*dispatch)(struct svc_req *, SVCXPRT *), int protocol) { struct svc_callout *prev; struct svc_callout *s; if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) { if (s->sc_dispatch == dispatch) goto pmap_it; /* he is registering another xptr */ return (FALSE); } s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout)); if (s == (struct svc_callout *)0) { return (FALSE); } s->sc_prog = prog; s->sc_vers = vers; s->sc_dispatch = dispatch; s->sc_next = svc_head; svc_head = s; pmap_it: /* now register the information with the local binder service */ if (protocol) { return (pmap_set(prog, vers, protocol, xprt->xp_port)); } return (TRUE); } /* * Remove a service program from the callout list. */ void svc_unregister( rpcprog_t prog, rpcvers_t vers) { struct svc_callout *prev; struct svc_callout *s; if ((s = svc_find(prog, vers, &prev)) == NULL_SVC) return; if (prev == NULL_SVC) { svc_head = s->sc_next; } else { prev->sc_next = s->sc_next; } s->sc_next = NULL_SVC; mem_free((char *) s, (u_int) sizeof(struct svc_callout)); /* now unregister the information with the local binder service */ (void)pmap_unset(prog, vers); } /* * Search the callout list for a program number, return the callout * struct. */ static struct svc_callout * svc_find( rpcprog_t prog, rpcvers_t vers, struct svc_callout **prev) { struct svc_callout *s, *p; p = NULL_SVC; for (s = svc_head; s != NULL_SVC; s = s->sc_next) { if ((s->sc_prog == prog) && (s->sc_vers == vers)) goto done; p = s; } done: *prev = p; return (s); } /* ******************* REPLY GENERATION ROUTINES ************ */ /* * Send a reply to an rpc request */ bool_t svc_sendreply( SVCXPRT *xprt, xdrproc_t xdr_results, caddr_t xdr_location) { struct rpc_msg rply; rply.rm_direction = REPLY; rply.rm_reply.rp_stat = MSG_ACCEPTED; rply.acpted_rply.ar_verf = xprt->xp_verf; rply.acpted_rply.ar_stat = SUCCESS; rply.acpted_rply.ar_results.where = xdr_location; rply.acpted_rply.ar_results.proc = xdr_results; return (SVC_REPLY(xprt, &rply)); } /* * No procedure error reply */ void svcerr_noproc(SVCXPRT *xprt) { struct rpc_msg rply; rply.rm_direction = REPLY; rply.rm_reply.rp_stat = MSG_ACCEPTED; rply.acpted_rply.ar_verf = xprt->xp_verf; rply.acpted_rply.ar_stat = PROC_UNAVAIL; SVC_REPLY(xprt, &rply); } /* * Can't decode args error reply */ void svcerr_decode(SVCXPRT *xprt) { struct rpc_msg rply; rply.rm_direction = REPLY; rply.rm_reply.rp_stat = MSG_ACCEPTED; rply.acpted_rply.ar_verf = xprt->xp_verf; rply.acpted_rply.ar_stat = GARBAGE_ARGS; SVC_REPLY(xprt, &rply); } /* * Some system error */ void svcerr_systemerr(SVCXPRT *xprt) { struct rpc_msg rply; rply.rm_direction = REPLY; rply.rm_reply.rp_stat = MSG_ACCEPTED; rply.acpted_rply.ar_verf = xprt->xp_verf; rply.acpted_rply.ar_stat = SYSTEM_ERR; SVC_REPLY(xprt, &rply); } /* * Authentication error reply */ void svcerr_auth( SVCXPRT *xprt, enum auth_stat why) { struct rpc_msg rply; rply.rm_direction = REPLY; rply.rm_reply.rp_stat = MSG_DENIED; rply.rjcted_rply.rj_stat = AUTH_ERROR; rply.rjcted_rply.rj_why = why; SVC_REPLY(xprt, &rply); } /* * Auth too weak error reply */ void svcerr_weakauth(SVCXPRT *xprt) { svcerr_auth(xprt, AUTH_TOOWEAK); } /* * Program unavailable error reply */ void svcerr_noprog(SVCXPRT *xprt) { struct rpc_msg rply; rply.rm_direction = REPLY; rply.rm_reply.rp_stat = MSG_ACCEPTED; rply.acpted_rply.ar_verf = xprt->xp_verf; rply.acpted_rply.ar_stat = PROG_UNAVAIL; SVC_REPLY(xprt, &rply); } /* * Program version mismatch error reply */ void svcerr_progvers( SVCXPRT *xprt, rpcvers_t low_vers, rpcvers_t high_vers) { struct rpc_msg rply; rply.rm_direction = REPLY; rply.rm_reply.rp_stat = MSG_ACCEPTED; rply.acpted_rply.ar_verf = xprt->xp_verf; rply.acpted_rply.ar_stat = PROG_MISMATCH; rply.acpted_rply.ar_vers.low = low_vers; rply.acpted_rply.ar_vers.high = high_vers; SVC_REPLY(xprt, &rply); } /* ******************* SERVER INPUT STUFF ******************* */ /* * Get server side input from some transport. * * Statement of authentication parameters management: * This function owns and manages all authentication parameters, specifically * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and * the "cooked" credentials (rqst->rq_clntcred). * However, this function does not know the structure of the cooked * credentials, so it make the following assumptions: * a) the structure is contiguous (no pointers), and * b) the cred structure size does not exceed RQCRED_SIZE bytes. * In all events, all three parameters are freed upon exit from this routine. * The storage is trivially management on the call stack in user land, but * is mallocated in kernel land. */ void svc_getreq(int rdfds) { #ifdef FD_SETSIZE fd_set readfds; int i, mask; FD_ZERO(&readfds); for (i=0, mask=1; rdfds; i++, mask <<=1) { if (rdfds & mask) FD_SET(i, &readfds); rdfds &= ~mask; } svc_getreqset(&readfds); #else int readfds = rdfds & svc_fds; svc_getreqset(&readfds); #endif /* def FD_SETSIZE */ } #ifdef FD_SETSIZE #define FDSET_TYPE fd_set #else #define FDSET_TYPE int #endif void svc_getreqset(FDSET_TYPE *readfds) { #ifndef FD_SETSIZE int readfds_local = *readfds; #endif SVCXPRT *xprt; int sock; #ifdef FD_SETSIZE for (sock = 0; sock <= svc_maxfd; sock++) { if (!FD_ISSET(sock, readfds)) continue; /* sock has input waiting */ xprt = xports[sock]; /* now receive msgs from xprtprt (support batch calls) */ svc_do_xprt(xprt); } #else for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) { if ((readfds_local & 1) == 0) continue; /* sock has input waiting */ xprt = xports[sock]; /* now receive msgs from xprtprt (support batch calls) */ svc_do_xprt(xprt); } #endif } extern struct svc_auth_ops svc_auth_gss_ops; static void svc_do_xprt(SVCXPRT *xprt) { caddr_t rawcred, rawverf, cookedcred; struct rpc_msg msg; struct svc_req r; bool_t no_dispatch; int prog_found; rpcvers_t low_vers; rpcvers_t high_vers; enum xprt_stat stat; rawcred = mem_alloc(MAX_AUTH_BYTES); rawverf = mem_alloc(MAX_AUTH_BYTES); cookedcred = mem_alloc(RQCRED_SIZE); if (rawcred == NULL || rawverf == NULL || cookedcred == NULL) return; msg.rm_call.cb_cred.oa_base = rawcred; msg.rm_call.cb_verf.oa_base = rawverf; r.rq_clntcred = cookedcred; do { struct svc_callout *s; enum auth_stat why; if (!SVC_RECV(xprt, &msg)) goto call_done; /* now find the exported program and call it */ r.rq_xprt = xprt; r.rq_prog = msg.rm_call.cb_prog; r.rq_vers = msg.rm_call.cb_vers; r.rq_proc = msg.rm_call.cb_proc; r.rq_cred = msg.rm_call.cb_cred; no_dispatch = FALSE; /* first authenticate the message */ why = gssrpc__authenticate(&r, &msg, &no_dispatch); if (why != AUTH_OK) { svcerr_auth(xprt, why); goto call_done; } else if (no_dispatch) { goto call_done; } /* now match message with a registered service*/ prog_found = FALSE; low_vers = (rpcvers_t) -1L; high_vers = 0; for (s = svc_head; s != NULL_SVC; s = s->sc_next) { if (s->sc_prog == r.rq_prog) { if (s->sc_vers == r.rq_vers) { (*s->sc_dispatch)(&r, xprt); goto call_done; } /* found correct version */ prog_found = TRUE; if (s->sc_vers < low_vers) low_vers = s->sc_vers; if (s->sc_vers > high_vers) high_vers = s->sc_vers; } /* found correct program */ } /* * if we got here, the program or version * is not served ... */ if (prog_found) svcerr_progvers(xprt, low_vers, high_vers); else svcerr_noprog(xprt); /* Fall through to ... */ call_done: if ((stat = SVC_STAT(xprt)) == XPRT_DIED){ SVC_DESTROY(xprt); break; } else if ((xprt->xp_auth != NULL) && (xprt->xp_auth->svc_ah_ops != &svc_auth_gss_ops)) { xprt->xp_auth = NULL; } } while (stat == XPRT_MOREREQS); mem_free(rawcred, MAX_AUTH_BYTES); mem_free(rawverf, MAX_AUTH_BYTES); mem_free(cookedcred, RQCRED_SIZE); } krb5-1.22.1/src/lib/rpc/pmap_prot.c0000664000175000017500000000422015051422640016625 0ustar ghudsonghudson/* @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro"; #endif /* * pmap_prot.c * Protocol for the local binder service, or pmap. */ #include #include #include bool_t xdr_pmap(XDR *xdrs, struct pmap *regs) { if (xdr_rpcprog(xdrs, ®s->pm_prog) && xdr_rpcvers(xdrs, ®s->pm_vers) && xdr_rpcprot(xdrs, ®s->pm_prot)) return (xdr_rpcport(xdrs, ®s->pm_port)); return (FALSE); } krb5-1.22.1/src/lib/rpc/dynP.h0000664000175000017500000000250115051422640015543 0ustar ghudsonghudson/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the private header file. * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. */ /* * dynP.h -- private header file included by source files for libdyn.a. */ #ifndef _DynP_h #define _DynP_h #include "dyn.h" #ifdef USE_DBMALLOC #include #include #endif /* * Rep invariant: * 1) el_size is the number of bytes per element in the object * 2) num_el is the number of elements currently in the object. It is * one higher than the highest index at which an element lives. * 3) size is the number of elements the object can hold without * resizing. num_el <= index. * 4) inc is a multiple of the number of elements the object grows by * each time it is reallocated. */ typedef struct _DynObject DynObjectRecP, *DynObjectP; #define _DynRealloc gssrpcint_DynRealloc #define _DynResize gssrpcint_DynResize /* Internal functions */ int _DynRealloc (DynObjectP obj, int req), _DynResize (DynObjectP obj, int req); #undef P #endif /* _DynP_h */ /* DON'T ADD STUFF AFTER THIS #endif */ krb5-1.22.1/src/lib/rpc/auth_gssapi_misc.c0000664000175000017500000002205215051422640020151 0ustar ghudsonghudson/* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. * */ #include #include #include #include #include "gssrpcint.h" #ifdef __CODECENTER__ #define DEBUG_GSSAPI 1 #endif #ifdef DEBUG_GSSAPI int misc_debug_gssapi = DEBUG_GSSAPI; extern void gssrpcint_printf(const char *, ...); #define L_PRINTF(l,args) if (misc_debug_gssapi >= l) gssrpcint_printf args #define PRINTF(args) L_PRINTF(99, args) #define AUTH_GSSAPI_DISPLAY_STATUS(args) \ if (misc_debug_gssapi) auth_gssapi_display_status args #else #define PRINTF(args) #define L_PRINTF(l, args) #define AUTH_GSSAPI_DISPLAY_STATUS(args) #endif static void auth_gssapi_display_status_1 (char *, OM_uint32, int, int); bool_t xdr_gss_buf( XDR *xdrs, gss_buffer_t buf) { /* * On decode, xdr_bytes will only allocate buf->value if the * length read in is < maxsize (last arg). This is dumb, because * the whole point of allocating memory is so that I don't *have* * to know the maximum length. -1 effectively disables this * braindamage. */ bool_t result; /* Fix type mismatches between APIs. */ unsigned int length = buf->length; char *cp = buf->value; result = xdr_bytes(xdrs, &cp, &length, (xdrs->x_op == XDR_DECODE && buf->value == NULL) ? (unsigned int) -1 : (unsigned int) buf->length); buf->value = cp; buf->length = length; return result; } bool_t xdr_authgssapi_creds( XDR *xdrs, auth_gssapi_creds *creds) { if (! xdr_u_int32(xdrs, &creds->version) || ! xdr_bool(xdrs, &creds->auth_msg) || ! xdr_gss_buf(xdrs, &creds->client_handle)) return FALSE; return TRUE; } bool_t xdr_authgssapi_init_arg( XDR *xdrs, auth_gssapi_init_arg *init_arg) { if (! xdr_u_int32(xdrs, &init_arg->version) || ! xdr_gss_buf(xdrs, &init_arg->token)) return FALSE; return TRUE; } bool_t xdr_authgssapi_init_res( XDR *xdrs, auth_gssapi_init_res *init_res) { if (! xdr_u_int32(xdrs, &init_res->version) || ! xdr_gss_buf(xdrs, &init_res->client_handle) || ! xdr_u_int32(xdrs, &init_res->gss_major) || ! xdr_u_int32(xdrs, &init_res->gss_minor) || ! xdr_gss_buf(xdrs, &init_res->token) || ! xdr_gss_buf(xdrs, &init_res->signed_isn)) return FALSE; return TRUE; } bool_t auth_gssapi_seal_seq( gss_ctx_id_t context, uint32_t seq_num, gss_buffer_t out_buf) { gss_buffer_desc in_buf; OM_uint32 gssstat, minor_stat; uint32_t nl_seq_num; nl_seq_num = htonl(seq_num); in_buf.length = sizeof(uint32_t); in_buf.value = (char *) &nl_seq_num; gssstat = gss_seal(&minor_stat, context, 0, GSS_C_QOP_DEFAULT, &in_buf, NULL, out_buf); if (gssstat != GSS_S_COMPLETE) { PRINTF(("gssapi_seal_seq: failed\n")); AUTH_GSSAPI_DISPLAY_STATUS(("sealing sequence number", gssstat, minor_stat)); return FALSE; } return TRUE; } bool_t auth_gssapi_unseal_seq( gss_ctx_id_t context, gss_buffer_t in_buf, uint32_t *seq_num) { gss_buffer_desc out_buf; OM_uint32 gssstat, minor_stat; uint32_t nl_seq_num; gssstat = gss_unseal(&minor_stat, context, in_buf, &out_buf, NULL, NULL); if (gssstat != GSS_S_COMPLETE) { PRINTF(("gssapi_unseal_seq: failed\n")); AUTH_GSSAPI_DISPLAY_STATUS(("unsealing sequence number", gssstat, minor_stat)); return FALSE; } else if (out_buf.length != sizeof(uint32_t)) { PRINTF(("gssapi_unseal_seq: unseal gave %d bytes\n", (int) out_buf.length)); gss_release_buffer(&minor_stat, &out_buf); return FALSE; } nl_seq_num = *((uint32_t *) out_buf.value); *seq_num = (uint32_t) ntohl(nl_seq_num); gss_release_buffer(&minor_stat, &out_buf); return TRUE; } void auth_gssapi_display_status( char *msg, OM_uint32 major, OM_uint32 minor) { auth_gssapi_display_status_1(msg, major, GSS_C_GSS_CODE, 0); auth_gssapi_display_status_1(msg, minor, GSS_C_MECH_CODE, 0); } static void auth_gssapi_display_status_1( char *m, OM_uint32 code, int type, int rec) { OM_uint32 gssstat, minor_stat; gss_buffer_desc msg; OM_uint32 msg_ctx; msg_ctx = 0; while (1) { gssstat = gss_display_status(&minor_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg); if (gssstat != GSS_S_COMPLETE) { if (!rec) { auth_gssapi_display_status_1(m,gssstat,GSS_C_GSS_CODE,1); auth_gssapi_display_status_1(m, minor_stat, GSS_C_MECH_CODE, 1); } else { fputs ("GSS-API authentication error ", stderr); fwrite (msg.value, msg.length, 1, stderr); fputs (": recursive failure!\n", stderr); } return; } fprintf (stderr, "GSS-API authentication error %s: ", m); fwrite (msg.value, msg.length, 1, stderr); putc ('\n', stderr); if (misc_debug_gssapi) gssrpcint_printf("GSS-API authentication error %s: %*s\n", m, (int)msg.length, (char *) msg.value); (void) gss_release_buffer(&minor_stat, &msg); if (!msg_ctx) break; } } bool_t auth_gssapi_wrap_data( OM_uint32 *major, OM_uint32 *minor, gss_ctx_id_t context, uint32_t seq_num, XDR *out_xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { gss_buffer_desc in_buf, out_buf; XDR temp_xdrs; int conf_state; unsigned int length; char *cp; PRINTF(("gssapi_wrap_data: starting\n")); *major = GSS_S_COMPLETE; *minor = 0; /* assumption */ xdralloc_create(&temp_xdrs, XDR_ENCODE); /* serialize the sequence number into local memory */ PRINTF(("gssapi_wrap_data: encoding seq_num %d\n", seq_num)); if (! xdr_u_int32(&temp_xdrs, &seq_num)) { PRINTF(("gssapi_wrap_data: serializing seq_num failed\n")); XDR_DESTROY(&temp_xdrs); return FALSE; } /* serialize the arguments into local memory */ if (!(*xdr_func)(&temp_xdrs, xdr_ptr)) { PRINTF(("gssapi_wrap_data: serializing arguments failed\n")); XDR_DESTROY(&temp_xdrs); return FALSE; } in_buf.length = xdr_getpos(&temp_xdrs); in_buf.value = xdralloc_getdata(&temp_xdrs); *major = gss_seal(minor, context, 1, GSS_C_QOP_DEFAULT, &in_buf, &conf_state, &out_buf); if (*major != GSS_S_COMPLETE) { XDR_DESTROY(&temp_xdrs); return FALSE; } PRINTF(("gssapi_wrap_data: %d bytes data, %d bytes sealed\n", (int) in_buf.length, (int) out_buf.length)); /* write the token */ length = out_buf.length; cp = out_buf.value; if (! xdr_bytes(out_xdrs, &cp, &length, out_buf.length)) { PRINTF(("gssapi_wrap_data: serializing encrypted data failed\n")); XDR_DESTROY(&temp_xdrs); return FALSE; } out_buf.value = cp; *major = gss_release_buffer(minor, &out_buf); PRINTF(("gssapi_wrap_data: succeeding\n\n")); XDR_DESTROY(&temp_xdrs); return TRUE; } bool_t auth_gssapi_unwrap_data( OM_uint32 *major, OM_uint32 *minor, gss_ctx_id_t context, uint32_t seq_num, XDR *in_xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { gss_buffer_desc in_buf, out_buf; XDR temp_xdrs; uint32_t verf_seq_num; int conf, qop; unsigned int length; char *cp; PRINTF(("gssapi_unwrap_data: starting\n")); *major = GSS_S_COMPLETE; *minor = 0; /* assumption */ in_buf.value = NULL; out_buf.value = NULL; cp = in_buf.value; if (! xdr_bytes(in_xdrs, &cp, &length, (unsigned int) -1)) { PRINTF(("gssapi_unwrap_data: deserializing encrypted data failed\n")); temp_xdrs.x_op = XDR_FREE; (void)xdr_bytes(&temp_xdrs, &cp, &length, (unsigned int) -1); in_buf.value = NULL; return FALSE; } in_buf.value = cp; in_buf.length = length; *major = gss_unseal(minor, context, &in_buf, &out_buf, &conf, &qop); free(in_buf.value); if (*major != GSS_S_COMPLETE) return FALSE; PRINTF(("gssapi_unwrap_data: %llu bytes data, %llu bytes sealed\n", (unsigned long long)out_buf.length, (unsigned long long)in_buf.length)); xdrmem_create(&temp_xdrs, out_buf.value, out_buf.length, XDR_DECODE); /* deserialize the sequence number */ if (! xdr_u_int32(&temp_xdrs, &verf_seq_num)) { PRINTF(("gssapi_unwrap_data: deserializing verf_seq_num failed\n")); gss_release_buffer(minor, &out_buf); XDR_DESTROY(&temp_xdrs); return FALSE; } if (verf_seq_num != seq_num) { PRINTF(("gssapi_unwrap_data: seq %d specified, read %d\n", seq_num, verf_seq_num)); gss_release_buffer(minor, &out_buf); XDR_DESTROY(&temp_xdrs); return FALSE; } PRINTF(("gssapi_unwrap_data: unwrap seq_num %d okay\n", verf_seq_num)); /* deserialize the arguments into xdr_ptr */ if (! (*xdr_func)(&temp_xdrs, xdr_ptr)) { PRINTF(("gssapi_unwrap_data: deserializing arguments failed\n")); gss_release_buffer(minor, &out_buf); XDR_DESTROY(&temp_xdrs); return FALSE; } PRINTF(("gssapi_unwrap_data: succeeding\n\n")); gss_release_buffer(minor, &out_buf); XDR_DESTROY(&temp_xdrs); return TRUE; } krb5-1.22.1/src/lib/rpc/xdr_float.c0000664000175000017500000001673515051422640016624 0ustar ghudsonghudson/* @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro"; #endif /* * xdr_float.c, Generic XDR routines impelmentation. * * These are the "floating point" xdr routines used to (de)serialize * most common data items. See xdr.h for more info on the interface to * xdr. */ #include #include #include /* * NB: Not portable. * This routine works on Suns (Sky / 68000's) and Vaxen. */ #ifdef IGNORE #ifdef vax /* What IEEE single precision floating point looks like on a Vax */ struct ieee_single { unsigned int mantissa: 23; unsigned int exp : 8; unsigned int sign : 1; }; /* Vax single precision floating point */ struct vax_single { unsigned int mantissa1 : 7; unsigned int exp : 8; unsigned int sign : 1; unsigned int mantissa2 : 16; }; #define VAX_SNG_BIAS 0x81 #define IEEE_SNG_BIAS 0x7f static struct sgl_limits { struct vax_single s; struct ieee_single ieee; } sgl_limits[2] = { {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ { 0x0, 0xff, 0x0 }}, /* Max IEEE */ {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ { 0x0, 0x0, 0x0 }} /* Min IEEE */ }; #endif /* vax */ bool_t xdr_float(XDR *xdrs, float *fp) { #if defined(vax) struct ieee_single is; struct vax_single vs, *vsp; struct sgl_limits *lim; int i; #endif long lg; switch (xdrs->x_op) { case XDR_ENCODE: #if !defined(vax) lg = * (int_32 *) fp; return (XDR_PUTLONG(xdrs, &lg)); #else vs = *((struct vax_single *)fp); for (i = 0, lim = sgl_limits; i < sizeof(sgl_limits)/sizeof(struct sgl_limits); i++, lim++) { if ((vs.mantissa2 == lim->s.mantissa2) && (vs.exp == lim->s.exp) && (vs.mantissa1 == lim->s.mantissa1)) { is = lim->ieee; goto shipit; } } is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; shipit: is.sign = vs.sign; return (XDR_PUTLONG(xdrs, (int32_t *)&is)); #endif case XDR_DECODE: #if !defined(vax) if (!(XDR_GETLONG(xdrs, &lg))) { return (FALSE); } *fp = (float) ((int) lg); return (TRUE); #else vsp = (struct vax_single *)fp; if (!XDR_GETLONG(xdrs, (int32_t *)&is)) return (FALSE); for (i = 0, lim = sgl_limits; i < sizeof(sgl_limits)/sizeof(struct sgl_limits); i++, lim++) { if ((is.exp == lim->ieee.exp) && (is.mantissa == lim->ieee.mantissa)) { *vsp = lim->s; goto doneit; } } vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; vsp->mantissa2 = is.mantissa; vsp->mantissa1 = (is.mantissa >> 16); doneit: vsp->sign = is.sign; return (TRUE); #endif case XDR_FREE: return (TRUE); } return (FALSE); } /* * This routine works on Suns (Sky / 68000's) and Vaxen. */ #ifdef vax /* What IEEE double precision floating point looks like on a Vax */ struct ieee_double { unsigned int mantissa1 : 20; unsigned int exp : 11; unsigned int sign : 1; unsigned int mantissa2 : 32; }; /* Vax double precision floating point */ struct vax_double { unsigned int mantissa1 : 7; unsigned int exp : 8; unsigned int sign : 1; unsigned int mantissa2 : 16; unsigned int mantissa3 : 16; unsigned int mantissa4 : 16; }; #define VAX_DBL_BIAS 0x81 #define IEEE_DBL_BIAS 0x3ff #define MASK(nbits) ((1 << nbits) - 1) static struct dbl_limits { struct vax_double d; struct ieee_double ieee; } dbl_limits[2] = { {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */ {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */ }; #endif /* vax */ bool_t xdr_double(XDR *xdrs, double *dp) { int32_t *lp; #if defined(vax) struct ieee_double id; struct vax_double vd; struct dbl_limits *lim; int i; #endif switch (xdrs->x_op) { case XDR_ENCODE: #if !defined(vax) lp = (int32_t *)dp; if (sizeof(int32_t) == sizeof(long)) { return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); } else { long lg1 = *lp++;; long lg2 = *lp; return (XDR_PUTLONG(xdrs, &lg1) && XDR_PUTLONG(xdrs, &lg2)); } #else vd = *((struct vax_double *)dp); for (i = 0, lim = dbl_limits; i < sizeof(dbl_limits)/sizeof(struct dbl_limits); i++, lim++) { if ((vd.mantissa4 == lim->d.mantissa4) && (vd.mantissa3 == lim->d.mantissa3) && (vd.mantissa2 == lim->d.mantissa2) && (vd.mantissa1 == lim->d.mantissa1) && (vd.exp == lim->d.exp)) { id = lim->ieee; goto shipit; } } id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | (vd.mantissa3 << 13) | ((vd.mantissa4 >> 3) & MASK(13)); shipit: id.sign = vd.sign; lp = (int32_t *)&id; return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); #endif case XDR_DECODE: #if !defined(vax) lp = (int32_t *)dp; if (sizeof(int32_t) == sizeof(long)) { return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp)); } else { long lg1, lg2; bool_t flag = (XDR_GETLONG(xdrs, &lg1) && XDR_GETLONG(xdrs, &lg2)); *lp++ = lg1; *lp = lg2; return flag; } #else lp = (int32_t *)&id; if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp)) return (FALSE); for (i = 0, lim = dbl_limits; i < sizeof(dbl_limits)/sizeof(struct dbl_limits); i++, lim++) { if ((id.mantissa2 == lim->ieee.mantissa2) && (id.mantissa1 == lim->ieee.mantissa1) && (id.exp == lim->ieee.exp)) { vd = lim->d; goto doneit; } } vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; vd.mantissa1 = (id.mantissa1 >> 13); vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | (id.mantissa2 >> 29); vd.mantissa3 = (id.mantissa2 >> 13); vd.mantissa4 = (id.mantissa2 << 3); doneit: vd.sign = id.sign; *dp = *((double *)&vd); return (TRUE); #endif case XDR_FREE: return (TRUE); } return (FALSE); } #endif /* IGNORE */ krb5-1.22.1/src/lib/rpc/auth_gss.c0000664000175000017500000003722415051422640016453 0ustar ghudsonghudson/* lib/rpc/auth_gss.c */ /* Copyright (c) 2000 The Regents of the University of Michigan. All rights reserved. Copyright (c) 2000 Dug Song . All rights reserved, all wrongs reversed. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Id: auth_gss.c,v 1.35 2002/10/15 21:25:25 kwc Exp */ /* RPCSEC_GSS client routines. */ #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_HEIMDAL #include #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE #else #include #include #endif #ifdef DEBUG_GSSAPI int auth_debug_gss = DEBUG_GSSAPI; int misc_debug_gss = DEBUG_GSSAPI; #endif static void authgss_nextverf(AUTH *); static bool_t authgss_marshal(AUTH *, XDR *); static bool_t authgss_refresh(AUTH *, struct rpc_msg *); static bool_t authgss_validate(AUTH *, struct opaque_auth *); static void authgss_destroy(AUTH *); static void authgss_destroy_context(AUTH *); static bool_t authgss_wrap(AUTH *, XDR *, xdrproc_t, caddr_t); static bool_t authgss_unwrap(AUTH *, XDR *, xdrproc_t, caddr_t); /* * from mit-krb5-1.2.1 mechglue/mglueP.h: * Array of context IDs typed by mechanism OID */ typedef struct gss_union_ctx_id_t { gss_OID mech_type; gss_ctx_id_t internal_ctx_id; } gss_union_ctx_id_desc, *gss_union_ctx_id_t; static struct auth_ops authgss_ops = { authgss_nextverf, authgss_marshal, authgss_validate, authgss_refresh, authgss_destroy, authgss_wrap, authgss_unwrap }; #ifdef DEBUG /* useful as i add more mechanisms */ void print_rpc_gss_sec(struct rpc_gss_sec *ptr) { int i; char *p; log_debug("rpc_gss_sec:"); if(ptr->mech == NULL) log_debug("NULL gss_OID mech"); else { fprintf(stderr, " mechanism_OID: {"); p = (char *)ptr->mech->elements; for (i=0; i < ptr->mech->length; i++) /* First byte of OIDs encoded to save a byte */ if (i == 0) { int first, second; if (*p < 40) { first = 0; second = *p; } else if (40 <= *p && *p < 80) { first = 1; second = *p - 40; } else if (80 <= *p && *p < 127) { first = 2; second = *p - 80; } else { /* Invalid value! */ first = -1; second = -1; } fprintf(stderr, " %u %u", first, second); p++; } else { fprintf(stderr, " %u", (unsigned char)*p++); } fprintf(stderr, " }\n"); } fprintf(stderr, " qop: %d\n", ptr->qop); fprintf(stderr, " service: %d\n", ptr->svc); fprintf(stderr, " cred: %p\n", ptr->cred); fprintf(stderr, " req_flags: 0x%08x", ptr->req_flags); } #endif /*DEBUG*/ struct rpc_gss_data { bool_t established; /* context established */ bool_t inprogress; gss_buffer_desc gc_wire_verf; /* save GSS_S_COMPLETE NULL RPC verfier * to process at end of context negotiation*/ CLIENT *clnt; /* client handle */ gss_name_t name; /* service name */ struct rpc_gss_sec sec; /* security tuple */ gss_ctx_id_t ctx; /* context id */ struct rpc_gss_cred gc; /* client credentials */ uint32_t win; /* sequence window */ }; #define AUTH_PRIVATE(auth) ((struct rpc_gss_data *)auth->ah_private) static struct timeval AUTH_TIMEOUT = { 25, 0 }; AUTH * authgss_create(CLIENT *clnt, gss_name_t name, struct rpc_gss_sec *sec) { AUTH *auth, *save_auth; struct rpc_gss_data *gd; OM_uint32 min_stat = 0; log_debug("in authgss_create()"); memset(&rpc_createerr, 0, sizeof(rpc_createerr)); if ((auth = calloc(sizeof(*auth), 1)) == NULL) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; return (NULL); } if ((gd = calloc(sizeof(*gd), 1)) == NULL) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; free(auth); return (NULL); } if (name != GSS_C_NO_NAME) { if (gss_duplicate_name(&min_stat, name, &gd->name) != GSS_S_COMPLETE) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = ENOMEM; free(auth); free(gd); return (NULL); } } else gd->name = name; gd->clnt = clnt; gd->ctx = GSS_C_NO_CONTEXT; gd->sec = *sec; gd->gc.gc_v = RPCSEC_GSS_VERSION; gd->gc.gc_proc = RPCSEC_GSS_INIT; gd->gc.gc_svc = gd->sec.svc; auth->ah_ops = &authgss_ops; auth->ah_private = (caddr_t)gd; save_auth = clnt->cl_auth; clnt->cl_auth = auth; if (!authgss_refresh(auth, NULL)) auth = NULL; clnt->cl_auth = save_auth; log_debug("authgss_create returning auth 0x%08x", auth); return (auth); } AUTH * authgss_create_default(CLIENT *clnt, char *service, struct rpc_gss_sec *sec) { AUTH *auth; OM_uint32 maj_stat = 0, min_stat = 0; gss_buffer_desc sname; gss_name_t name; log_debug("in authgss_create_default()"); sname.value = service; sname.length = strlen(service); maj_stat = gss_import_name(&min_stat, &sname, (gss_OID)gss_nt_service_name, &name); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_import_name", maj_stat, min_stat); rpc_createerr.cf_stat = RPC_AUTHERROR; return (NULL); } auth = authgss_create(clnt, name, sec); if (name != GSS_C_NO_NAME) gss_release_name(&min_stat, &name); log_debug("authgss_create_default returning auth 0x%08x", auth); return (auth); } bool_t authgss_get_private_data(AUTH *auth, struct authgss_private_data *pd) { struct rpc_gss_data *gd; log_debug("in authgss_get_private_data()"); if (!auth || !pd) return (FALSE); gd = AUTH_PRIVATE(auth); if (!gd || !gd->established) return (FALSE); pd->pd_ctx = gd->ctx; pd->pd_ctx_hndl = gd->gc.gc_ctx; pd->pd_seq_win = gd->win; return (TRUE); } static void authgss_nextverf(AUTH *auth) { log_debug("in authgss_nextverf()\n"); /* no action necessary */ } static bool_t authgss_marshal(AUTH *auth, XDR *xdrs) { XDR tmpxdrs; char tmp[MAX_AUTH_BYTES]; struct rpc_gss_data *gd; gss_buffer_desc rpcbuf, checksum; OM_uint32 maj_stat, min_stat; bool_t xdr_stat; log_debug("in authgss_marshal()"); gd = AUTH_PRIVATE(auth); if (gd->established) gd->gc.gc_seq++; xdrmem_create(&tmpxdrs, tmp, sizeof(tmp), XDR_ENCODE); if (!xdr_rpc_gss_cred(&tmpxdrs, &gd->gc)) { XDR_DESTROY(&tmpxdrs); return (FALSE); } auth->ah_cred.oa_flavor = RPCSEC_GSS; auth->ah_cred.oa_base = tmp; auth->ah_cred.oa_length = XDR_GETPOS(&tmpxdrs); XDR_DESTROY(&tmpxdrs); if (!xdr_opaque_auth(xdrs, &auth->ah_cred)) return (FALSE); if (gd->gc.gc_proc == RPCSEC_GSS_INIT || gd->gc.gc_proc == RPCSEC_GSS_CONTINUE_INIT) { return (xdr_opaque_auth(xdrs, &gssrpc__null_auth)); } /* Checksum serialized RPC header, up to and including credential. */ rpcbuf.length = XDR_GETPOS(xdrs); XDR_SETPOS(xdrs, 0); rpcbuf.value = XDR_INLINE(xdrs, (int)rpcbuf.length); maj_stat = gss_get_mic(&min_stat, gd->ctx, gd->sec.qop, &rpcbuf, &checksum); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_get_mic", maj_stat, min_stat); if (maj_stat == GSS_S_CONTEXT_EXPIRED) { gd->established = FALSE; authgss_destroy_context(auth); } return (FALSE); } auth->ah_verf.oa_flavor = RPCSEC_GSS; auth->ah_verf.oa_base = checksum.value; auth->ah_verf.oa_length = checksum.length; xdr_stat = xdr_opaque_auth(xdrs, &auth->ah_verf); gss_release_buffer(&min_stat, &checksum); return (xdr_stat); } static bool_t authgss_validate(AUTH *auth, struct opaque_auth *verf) { struct rpc_gss_data *gd; uint32_t num; gss_qop_t qop_state; gss_buffer_desc signbuf, checksum; OM_uint32 maj_stat, min_stat; log_debug("in authgss_validate()"); gd = AUTH_PRIVATE(auth); if (gd->established == FALSE) { /* would like to do this only on NULL rpc - gc->established is good enough. * save the on the wire verifier to validate last INIT phase packet * after decode if the major status is GSS_S_COMPLETE */ if ((gd->gc_wire_verf.value = mem_alloc(verf->oa_length)) == NULL) { fprintf(stderr, "gss_validate: out of memory\n"); return (FALSE); } memcpy(gd->gc_wire_verf.value, verf->oa_base, verf->oa_length); gd->gc_wire_verf.length = verf->oa_length; return (TRUE); } if (gd->gc.gc_proc == RPCSEC_GSS_INIT || gd->gc.gc_proc == RPCSEC_GSS_CONTINUE_INIT) { num = htonl(gd->win); } else num = htonl(gd->gc.gc_seq); signbuf.value = # signbuf.length = sizeof(num); checksum.value = verf->oa_base; checksum.length = verf->oa_length; maj_stat = gss_verify_mic(&min_stat, gd->ctx, &signbuf, &checksum, &qop_state); if (maj_stat != GSS_S_COMPLETE || qop_state != gd->sec.qop) { log_status("gss_verify_mic", maj_stat, min_stat); if (maj_stat == GSS_S_CONTEXT_EXPIRED) { gd->established = FALSE; authgss_destroy_context(auth); } return (FALSE); } return (TRUE); } static bool_t authgss_refresh(AUTH *auth, struct rpc_msg *msg) { struct rpc_gss_data *gd; struct rpc_gss_init_res gr; gss_buffer_desc *recv_tokenp, send_token; OM_uint32 maj_stat, min_stat, call_stat, ret_flags; log_debug("in authgss_refresh()"); gd = AUTH_PRIVATE(auth); if (gd->established || gd->inprogress) return (TRUE); /* GSS context establishment loop. */ memset(&gr, 0, sizeof(gr)); recv_tokenp = GSS_C_NO_BUFFER; #ifdef DEBUG print_rpc_gss_sec(&gd->sec); #endif /*DEBUG*/ for (;;) { gd->inprogress = TRUE; maj_stat = gss_init_sec_context(&min_stat, gd->sec.cred, &gd->ctx, gd->name, gd->sec.mech, gd->sec.req_flags, 0, /* time req */ GSS_C_NO_CHANNEL_BINDINGS, recv_tokenp, NULL, /* used mech */ &send_token, &ret_flags, NULL); /* time rec */ log_status("gss_init_sec_context", maj_stat, min_stat); if (recv_tokenp != GSS_C_NO_BUFFER) { free(gr.gr_token.value); gr.gr_token.value = NULL; recv_tokenp = GSS_C_NO_BUFFER; } if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { log_status("gss_init_sec_context (error)", maj_stat, min_stat); break; } if (send_token.length != 0) { memset(&gr, 0, sizeof(gr)); call_stat = clnt_call(gd->clnt, NULLPROC, (xdrproc_t)xdr_rpc_gss_init_args, &send_token, (xdrproc_t)xdr_rpc_gss_init_res, (caddr_t)&gr, AUTH_TIMEOUT); gss_release_buffer(&min_stat, &send_token); log_debug("authgss_refresh: call_stat=%d", call_stat); log_debug("%s", clnt_sperror(gd->clnt, "authgss_refresh")); if (call_stat != RPC_SUCCESS || (gr.gr_major != GSS_S_COMPLETE && gr.gr_major != GSS_S_CONTINUE_NEEDED)) break; if (gr.gr_ctx.length != 0) { free(gd->gc.gc_ctx.value); gd->gc.gc_ctx = gr.gr_ctx; } if (gr.gr_token.length != 0) { if (maj_stat != GSS_S_CONTINUE_NEEDED) break; recv_tokenp = &gr.gr_token; } gd->gc.gc_proc = RPCSEC_GSS_CONTINUE_INIT; } /* GSS_S_COMPLETE => check gss header verifier, usually checked in * gss_validate */ if (maj_stat == GSS_S_COMPLETE) { gss_buffer_desc bufin; gss_buffer_desc bufout; uint32_t seq; gss_qop_t qop_state = 0; seq = htonl(gr.gr_win); bufin.value = (u_char *)&seq; bufin.length = sizeof(seq); bufout.value = (u_char *)gd->gc_wire_verf.value; bufout.length = gd->gc_wire_verf.length; log_debug("authgss_refresh: GSS_S_COMPLETE: calling verify_mic"); maj_stat = gss_verify_mic(&min_stat,gd->ctx, &bufin, &bufout, &qop_state); free(gd->gc_wire_verf.value); gd->gc_wire_verf.length = 0; gd->gc_wire_verf.value = NULL; if (maj_stat != GSS_S_COMPLETE || qop_state != gd->sec.qop) { log_status("gss_verify_mic", maj_stat, min_stat); if (maj_stat == GSS_S_CONTEXT_EXPIRED) { gd->established = FALSE; authgss_destroy_context(auth); } return (FALSE); } gd->established = TRUE; gd->inprogress = FALSE; gd->gc.gc_proc = RPCSEC_GSS_DATA; gd->gc.gc_seq = 0; gd->win = gr.gr_win; break; } } log_status("authgss_refresh: at end of context negotiation", maj_stat, min_stat); /* End context negotiation loop. */ if (gd->gc.gc_proc != RPCSEC_GSS_DATA) { log_debug("authgss_refresh: returning ERROR (gc_proc %d)", gd->gc.gc_proc); free(gr.gr_token.value); authgss_destroy(auth); auth = NULL; rpc_createerr.cf_stat = RPC_AUTHERROR; return (FALSE); } log_debug("authgss_refresh: returning SUCCESS"); return (TRUE); } bool_t authgss_service(AUTH *auth, int svc) { struct rpc_gss_data *gd; log_debug("in authgss_service()"); if (!auth) return(FALSE); gd = AUTH_PRIVATE(auth); if (!gd || !gd->established) return (FALSE); gd->sec.svc = svc; gd->gc.gc_svc = svc; return (TRUE); } static void authgss_destroy_context(AUTH *auth) { struct rpc_gss_data *gd; OM_uint32 min_stat; log_debug("in authgss_destroy_context()"); gd = AUTH_PRIVATE(auth); if (gd->gc.gc_ctx.length != 0) { if (gd->established) { gd->gc.gc_proc = RPCSEC_GSS_DESTROY; (void)clnt_call(gd->clnt, NULLPROC, xdr_void, NULL, xdr_void, NULL, AUTH_TIMEOUT); log_debug("%s", clnt_sperror(gd->clnt, "authgss_destroy_context")); } free(gd->gc.gc_ctx.value); /* XXX ANDROS check size of context - should be 8 */ memset(&gd->gc.gc_ctx, 0, sizeof(gd->gc.gc_ctx)); } if (gd->ctx != GSS_C_NO_CONTEXT) { gss_delete_sec_context(&min_stat, &gd->ctx, NULL); gd->ctx = GSS_C_NO_CONTEXT; } gd->established = FALSE; log_debug("finished authgss_destroy_context()"); } static void authgss_destroy(AUTH *auth) { struct rpc_gss_data *gd; OM_uint32 min_stat; log_debug("in authgss_destroy()"); gd = AUTH_PRIVATE(auth); authgss_destroy_context(auth); if (gd->name != GSS_C_NO_NAME) gss_release_name(&min_stat, &gd->name); free(gd); free(auth); } bool_t authgss_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { struct rpc_gss_data *gd; log_debug("in authgss_wrap()"); gd = AUTH_PRIVATE(auth); if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE) { return ((*xdr_func)(xdrs, xdr_ptr)); } return (xdr_rpc_gss_data(xdrs, xdr_func, xdr_ptr, gd->ctx, gd->sec.qop, gd->sec.svc, gd->gc.gc_seq)); } bool_t authgss_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { struct rpc_gss_data *gd; log_debug("in authgss_unwrap()"); gd = AUTH_PRIVATE(auth); if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE) { return ((*xdr_func)(xdrs, xdr_ptr)); } return (xdr_rpc_gss_data(xdrs, xdr_func, xdr_ptr, gd->ctx, gd->sec.qop, gd->sec.svc, gd->gc.gc_seq)); } krb5-1.22.1/src/lib/rpc/pmap_getport.c0000664000175000017500000000625215051422640017334 0ustar ghudsonghudson/* @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro"; #endif /* * pmap_getport.c * Client interface to pmap rpc service. */ #include #include #include #include #include #ifdef OSF1 #include #include #endif #include static struct timeval timeout = { 5, 0 }; static struct timeval tottimeout = { 60, 0 }; /* * Find the mapped port for program,version. * Calls the pmap service remotely to do the lookup. * Returns 0 if no map exists. */ u_short pmap_getport( struct sockaddr_in *address, rpcprog_t program, rpcvers_t version, rpcprot_t protocol) { unsigned short port = 0; int sock = -1; CLIENT *client; struct pmap parms; address->sin_port = htons(PMAPPORT); client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); if (client != (CLIENT *)NULL) { parms.pm_prog = program; parms.pm_vers = version; parms.pm_prot = protocol; parms.pm_port = 0; /* not needed or used */ if (CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap, &parms, (xdrproc_t)xdr_u_short, &port, tottimeout) != RPC_SUCCESS){ rpc_createerr.cf_stat = RPC_PMAPFAILURE; clnt_geterr(client, &rpc_createerr.cf_error); } else if (port == 0) { rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; } CLNT_DESTROY(client); } (void)close(sock); address->sin_port = 0; return (port); } krb5-1.22.1/src/lib/rpc/deps0000664000175000017500000005437515051422640015356 0ustar ghudsonghudson# # Generated makefile dependencies follow. # auth_none.so auth_none.po $(OUTPRE)auth_none.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/xdr.h \ auth_none.c auth_unix.so auth_unix.po $(OUTPRE)auth_unix.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/xdr.h \ auth_unix.c authgss_prot.so authgss_prot.po $(OUTPRE)authgss_prot.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ authgss_prot.c authunix_prot.so authunix_prot.po $(OUTPRE)authunix_prot.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/xdr.h authunix_prot.c auth_gss.so auth_gss.po $(OUTPRE)auth_gss.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h auth_gss.c auth_gssapi.so auth_gssapi.po $(OUTPRE)auth_gssapi.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_generic.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_gssapi.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/krb5.h auth_gssapi.c gssrpcint.h auth_gssapi_misc.so auth_gssapi_misc.po $(OUTPRE)auth_gssapi_misc.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_gssapi.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h auth_gssapi_misc.c \ gssrpcint.h bindresvport.so bindresvport.po $(OUTPRE)bindresvport.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h bindresvport.c clnt_generic.so clnt_generic.po $(OUTPRE)clnt_generic.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h clnt_generic.c clnt_perror.so clnt_perror.po $(OUTPRE)clnt_perror.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/xdr.h \ clnt_perror.c clnt_raw.so clnt_raw.po $(OUTPRE)clnt_raw.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ clnt_raw.c clnt_simple.so clnt_simple.po $(OUTPRE)clnt_simple.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/port-sockets.h \ clnt_simple.c clnt_tcp.so clnt_tcp.po $(OUTPRE)clnt_tcp.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/pmap_clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/port-sockets.h clnt_tcp.c clnt_udp.so clnt_udp.po $(OUTPRE)clnt_udp.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/pmap_clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/port-sockets.h clnt_udp.c dyn.so dyn.po $(OUTPRE)dyn.$(OBJEXT): dyn.c dyn.h dynP.h rpc_dtablesize.so rpc_dtablesize.po $(OUTPRE)rpc_dtablesize.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ rpc_dtablesize.c get_myaddress.so get_myaddress.po $(OUTPRE)get_myaddress.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/pmap_prot.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/krb5.h get_myaddress.c getrpcport.so getrpcport.po $(OUTPRE)getrpcport.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/pmap_clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ getrpcport.c pmap_clnt.so pmap_clnt.po $(OUTPRE)pmap_clnt.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/pmap_clnt.h $(top_srcdir)/include/gssrpc/pmap_prot.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ pmap_clnt.c pmap_getmaps.so pmap_getmaps.po $(OUTPRE)pmap_getmaps.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/pmap_clnt.h $(top_srcdir)/include/gssrpc/pmap_prot.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ pmap_getmaps.c pmap_getport.so pmap_getport.po $(OUTPRE)pmap_getport.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/pmap_clnt.h $(top_srcdir)/include/gssrpc/pmap_prot.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ pmap_getport.c pmap_prot.so pmap_prot.po $(OUTPRE)pmap_prot.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/pmap_prot.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/xdr.h \ pmap_prot.c pmap_prot2.so pmap_prot2.po $(OUTPRE)pmap_prot2.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/pmap_prot.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/xdr.h \ pmap_prot2.c pmap_rmt.so pmap_rmt.po $(OUTPRE)pmap_rmt.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/pmap_clnt.h \ $(top_srcdir)/include/gssrpc/pmap_prot.h $(top_srcdir)/include/gssrpc/pmap_rmt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ pmap_rmt.c rpc_prot.so rpc_prot.po $(OUTPRE)rpc_prot.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ rpc_prot.c rpc_commondata.so rpc_commondata.po $(OUTPRE)rpc_commondata.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ rpc_commondata.c rpc_callmsg.so rpc_callmsg.po $(OUTPRE)rpc_callmsg.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ rpc_callmsg.c svc.so svc.po $(OUTPRE)svc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/pmap_clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h svc.c svc_auth.so svc_auth.po $(OUTPRE)svc_auth.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ svc_auth.c svc_auth_gss.so svc_auth_gss.po $(OUTPRE)svc_auth_gss.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssapi/gssapi_generic.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_gssapi.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h svc_auth_gss.c svc_auth_none.so svc_auth_none.po $(OUTPRE)svc_auth_none.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ svc_auth_none.c svc_auth_unix.so svc_auth_unix.po $(OUTPRE)svc_auth_unix.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ svc_auth_unix.c svc_auth_gssapi.so svc_auth_gssapi.po $(OUTPRE)svc_auth_gssapi.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_gssapi.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/krb5.h gssrpcint.h svc_auth_gssapi.c svc_raw.so svc_raw.po $(OUTPRE)svc_raw.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h svc_raw.c svc_run.so svc_run.po $(OUTPRE)svc_run.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h svc_run.c svc_simple.so svc_simple.po $(OUTPRE)svc_simple.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/pmap_clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h svc_simple.c svc_tcp.so svc_tcp.po $(OUTPRE)svc_tcp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ svc_tcp.c svc_udp.so svc_udp.po $(OUTPRE)svc_udp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ svc_udp.c xdr.so xdr.po $(OUTPRE)xdr.$(OBJEXT): $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/xdr.h \ xdr.c xdr_array.so xdr_array.po $(OUTPRE)xdr_array.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/xdr.h xdr_array.c xdr_float.so xdr_float.po $(OUTPRE)xdr_float.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/xdr.h xdr_float.c xdr_mem.so xdr_mem.po $(OUTPRE)xdr_mem.$(OBJEXT): $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/xdr.h \ xdr_mem.c xdr_rec.so xdr_rec.po $(OUTPRE)xdr_rec.$(OBJEXT): $(BUILDTOP)/include/gssrpc/types.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/xdr.h \ xdr_rec.c xdr_reference.so xdr_reference.po $(OUTPRE)xdr_reference.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/xdr.h xdr_reference.c xdr_stdio.so xdr_stdio.po $(OUTPRE)xdr_stdio.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/xdr.h xdr_stdio.c xdr_sizeof.so xdr_sizeof.po $(OUTPRE)xdr_sizeof.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/xdr.h xdr_sizeof.c xdr_alloc.so xdr_alloc.po $(OUTPRE)xdr_alloc.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/xdr.h dyn.h xdr_alloc.c krb5-1.22.1/src/lib/rpc/svc_tcp.c0000664000175000017500000003135315051422640016274 0ustar ghudsonghudson/* @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; #endif /* * svc_tcp.c, Server side for TCP/IP based RPC. * * Actually implements two flavors of transporter - * a tcp rendezvouser (a listener and connection establisher) * and a record/tcp stream. */ #include "k5-platform.h" #include #include #include #include #include /*extern bool_t abort(); extern errno; */ #ifndef FD_SETSIZE #ifdef NBBY #define NOFILE (sizeof(int) * NBBY) #else #define NOFILE (sizeof(int) * 8) #endif #endif /* * Ops vector for TCP/IP based rpc service handle */ static bool_t svctcp_recv(SVCXPRT *, struct rpc_msg *); static enum xprt_stat svctcp_stat(SVCXPRT *); static bool_t svctcp_getargs(SVCXPRT *, xdrproc_t, void *); static bool_t svctcp_reply(SVCXPRT *, struct rpc_msg *); static bool_t svctcp_freeargs(SVCXPRT *, xdrproc_t, void *); static void svctcp_destroy(SVCXPRT *); static struct xp_ops svctcp_op = { svctcp_recv, svctcp_stat, svctcp_getargs, svctcp_reply, svctcp_freeargs, svctcp_destroy }; /* * Ops vector for TCP/IP rendezvous handler */ static bool_t rendezvous_request(SVCXPRT *, struct rpc_msg *); static bool_t abortx(void); static bool_t abortx_getargs(SVCXPRT *, xdrproc_t, void *); static bool_t abortx_reply(SVCXPRT *, struct rpc_msg *); static bool_t abortx_freeargs(SVCXPRT *, xdrproc_t, void *); static enum xprt_stat rendezvous_stat(SVCXPRT *); static struct xp_ops svctcp_rendezvous_op = { rendezvous_request, rendezvous_stat, abortx_getargs, abortx_reply, abortx_freeargs, svctcp_destroy }; static int readtcp(char *, caddr_t, int), writetcp(char *, caddr_t, int); static SVCXPRT *makefd_xprt(int, u_int, u_int); struct tcp_rendezvous { /* kept in xprt->xp_p1 */ u_int sendsize; u_int recvsize; }; struct tcp_conn { /* kept in xprt->xp_p1 */ enum xprt_stat strm_stat; uint32_t x_id; XDR xdrs; char verf_body[MAX_AUTH_BYTES]; }; /* * Usage: * xprt = svctcp_create(sock, send_buf_size, recv_buf_size); * * Creates, registers, and returns a (rpc) tcp based transporter. * Once *xprt is initialized, it is registered as a transporter * see (svc.h, xprt_register). This routine returns * a NULL if a problem occurred. * * If sock<0 then a socket is created, else sock is used. * If the socket, sock is not bound to a port then svctcp_create * binds it to an arbitrary port. The routine then starts a tcp * listener on the socket's associated port. In any (successful) case, * xprt->xp_sock is the registered socket number and xprt->xp_port is the * associated port number. * * Since tcp streams do buffered io similar to stdio, the caller can specify * how big the send and receive buffers are via the second and third parms; * 0 => use the system default. */ SVCXPRT * svctcp_create( SOCKET sock, u_int sendsize, u_int recvsize) { bool_t madesock = FALSE; SVCXPRT *xprt; struct tcp_rendezvous *r; struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; socklen_t len; if (sock == RPC_ANYSOCK) { if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { perror("svctcp_.c - udp socket creation problem"); return ((SVCXPRT *)NULL); } set_cloexec_fd(sock); madesock = TRUE; memset(&ss, 0, sizeof(ss)); sa->sa_family = AF_INET; } else { len = sizeof(struct sockaddr_storage); if (getsockname(sock, sa, &len) != 0) { perror("svc_tcp.c - cannot getsockname"); return ((SVCXPRT *)NULL); } } if (bindresvport_sa(sock, sa)) { sa_setport(sa, 0); (void)bind(sock, sa, sa_socklen(sa)); } len = sizeof(struct sockaddr_storage); if (getsockname(sock, sa, &len) != 0) { perror("svc_tcp.c - cannot getsockname"); if (madesock) (void)closesocket(sock); return ((SVCXPRT *)NULL); } if (listen(sock, 2) != 0) { perror("svctcp_.c - cannot listen"); if (madesock) (void)closesocket(sock); return ((SVCXPRT *)NULL); } r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r)); if (r == NULL) { (void) fprintf(stderr, "svctcp_create: out of memory\n"); return (NULL); } r->sendsize = sendsize; r->recvsize = recvsize; xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); if (xprt == NULL) { (void) fprintf(stderr, "svctcp_create: out of memory\n"); return (NULL); } xprt->xp_p2 = NULL; xprt->xp_p1 = (caddr_t)r; xprt->xp_auth = NULL; xprt->xp_verf = gssrpc__null_auth; xprt->xp_ops = &svctcp_rendezvous_op; xprt->xp_port = sa_getport(sa); xprt->xp_sock = sock; xprt->xp_laddrlen = 0; xprt_register(xprt); return (xprt); } /* * Like svtcp_create(), except the routine takes any *open* UNIX file * descriptor as its first input. */ SVCXPRT * svcfd_create( int fd, u_int sendsize, u_int recvsize) { return (makefd_xprt(fd, sendsize, recvsize)); } static SVCXPRT * makefd_xprt( int fd, u_int sendsize, u_int recvsize) { SVCXPRT *xprt; struct tcp_conn *cd; #ifdef FD_SETSIZE if (fd >= FD_SETSIZE) { (void) fprintf(stderr, "svc_tcp: makefd_xprt: fd too high\n"); xprt = NULL; goto done; } #else if (fd >= NOFILE) { (void) fprintf(stderr, "svc_tcp: makefd_xprt: fd too high\n"); xprt = NULL; goto done; } #endif xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); if (xprt == (SVCXPRT *)NULL) { (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); goto done; } cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn)); if (cd == (struct tcp_conn *)NULL) { (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); mem_free((char *) xprt, sizeof(SVCXPRT)); xprt = (SVCXPRT *)NULL; goto done; } cd->strm_stat = XPRT_IDLE; xdrrec_create(&(cd->xdrs), sendsize, recvsize, (caddr_t)xprt, readtcp, writetcp); xprt->xp_p2 = NULL; xprt->xp_p1 = (caddr_t)cd; xprt->xp_auth = NULL; xprt->xp_verf.oa_base = cd->verf_body; xprt->xp_addrlen = 0; xprt->xp_laddrlen = 0; xprt->xp_ops = &svctcp_op; /* truly deals with calls */ xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ xprt->xp_sock = fd; xprt_register(xprt); done: return (xprt); } static bool_t rendezvous_request( SVCXPRT *xprt, struct rpc_msg *msg) { SOCKET sock; struct tcp_rendezvous *r; struct sockaddr_in addr, laddr; socklen_t len, llen; r = (struct tcp_rendezvous *)xprt->xp_p1; again: len = llen = sizeof(struct sockaddr_in); if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr, &len)) < 0) { if (errno == EINTR) goto again; return (FALSE); } set_cloexec_fd(sock); if (getsockname(sock, (struct sockaddr *) &laddr, &llen) < 0) return (FALSE); /* * make a new transporter (re-uses xprt) */ xprt = makefd_xprt(sock, r->sendsize, r->recvsize); if (xprt == NULL) { (void)closesocket(sock); return (FALSE); } xprt->xp_raddr = addr; xprt->xp_addrlen = len; xprt->xp_laddr = laddr; xprt->xp_laddrlen = llen; return (FALSE); /* there is never an rpc msg to be processed */ } static enum xprt_stat rendezvous_stat(SVCXPRT *xprt) { return (XPRT_IDLE); } static void svctcp_destroy(SVCXPRT *xprt) { struct tcp_conn *cd = xprt->xp_p1; xprt_unregister(xprt); (void)closesocket(xprt->xp_sock); if (xprt->xp_port != 0) { /* a rendezvouser socket */ xprt->xp_port = 0; } else { /* an actual connection socket */ XDR_DESTROY(&(cd->xdrs)); } if (xprt->xp_auth != NULL) { SVCAUTH_DESTROY(xprt->xp_auth); xprt->xp_auth = NULL; } mem_free((caddr_t)cd, sizeof(struct tcp_conn)); mem_free((caddr_t)xprt, sizeof(SVCXPRT)); } /* * All read operations timeout after 35 seconds. * A timeout is fatal for the connection. */ static struct timeval wait_per_try = { 35, 0 }; /* * reads data from the tcp connection. * any error is fatal and the connection is closed. * (And a read of zero bytes is a half closed stream => error.) */ static int readtcp( char *xprtptr, caddr_t buf, int len) { SVCXPRT *xprt = (void *)xprtptr; int sock = xprt->xp_sock; struct timeval tout; #ifdef FD_SETSIZE fd_set mask; fd_set readfds; FD_ZERO(&mask); FD_SET(sock, &mask); #else int mask = 1 << sock; int readfds; #endif /* def FD_SETSIZE */ #ifdef FD_SETSIZE #define loopcond (!FD_ISSET(sock, &readfds)) #else #define loopcond (readfds != mask) #endif do { readfds = mask; tout = wait_per_try; if (select(sock + 1, &readfds, (fd_set*)NULL, (fd_set*)NULL, &tout) <= 0) { if (errno == EINTR) { continue; } goto fatal_err; } } while (loopcond); if ((len = read(sock, buf, (size_t) len)) > 0) { return (len); } fatal_err: ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; return (-1); } /* * writes data to the tcp connection. * Any error is fatal and the connection is closed. */ static int writetcp( char *xprtptr, caddr_t buf, int len) { SVCXPRT *xprt = (void *)xprtptr; int i, cnt; for (cnt = len; cnt > 0; cnt -= i, buf += i) { if ((i = write(xprt->xp_sock, buf, (size_t) cnt)) < 0) { ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; return (-1); } } return (len); } static enum xprt_stat svctcp_stat(SVCXPRT *xprt) { struct tcp_conn *cd = xprt->xp_p1; if (cd->strm_stat == XPRT_DIED) return (XPRT_DIED); if (! xdrrec_eof(&(cd->xdrs))) return (XPRT_MOREREQS); return (XPRT_IDLE); } static bool_t svctcp_recv( SVCXPRT *xprt, struct rpc_msg *msg) { struct tcp_conn *cd = xprt->xp_p1; XDR *xdrs = &cd->xdrs; xdrs->x_op = XDR_DECODE; (void)xdrrec_skiprecord(xdrs); if (xdr_callmsg(xdrs, msg)) { cd->x_id = msg->rm_xid; return (TRUE); } return (FALSE); } static bool_t svctcp_getargs( SVCXPRT *xprt, xdrproc_t xdr_args, void *args_ptr) { if (! SVCAUTH_UNWRAP(xprt->xp_auth, &(((struct tcp_conn *)(xprt->xp_p1))->xdrs), xdr_args, args_ptr)) { (void)svctcp_freeargs(xprt, xdr_args, args_ptr); return FALSE; } return TRUE; } static bool_t svctcp_freeargs( SVCXPRT *xprt, xdrproc_t xdr_args, void * args_ptr) { XDR *xdrs = &((struct tcp_conn *)(xprt->xp_p1))->xdrs; xdrs->x_op = XDR_FREE; return ((*xdr_args)(xdrs, args_ptr)); } static bool_t svctcp_reply( SVCXPRT *xprt, struct rpc_msg *msg) { struct tcp_conn *cd = xprt->xp_p1; XDR *xdrs = &cd->xdrs; bool_t stat; xdrproc_t xdr_results = NULL; caddr_t xdr_location = 0; bool_t has_args; if (msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { has_args = TRUE; xdr_results = msg->acpted_rply.ar_results.proc; xdr_location = msg->acpted_rply.ar_results.where; msg->acpted_rply.ar_results.proc = xdr_void; msg->acpted_rply.ar_results.where = NULL; } else has_args = FALSE; xdrs->x_op = XDR_ENCODE; msg->rm_xid = cd->x_id; stat = FALSE; if (xdr_replymsg(xdrs, msg) && (!has_args || (SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) { stat = TRUE; } (void)xdrrec_endofrecord(xdrs, TRUE); return (stat); } static bool_t abortx(void) { abort(); return 1; } static bool_t abortx_getargs( SVCXPRT *xprt, xdrproc_t proc, void *info) { return abortx(); } static bool_t abortx_reply(SVCXPRT *xprt, struct rpc_msg *msg) { return abortx(); } static bool_t abortx_freeargs( SVCXPRT *xprt, xdrproc_t proc, void * info) { return abortx(); } krb5-1.22.1/src/lib/rpc/auth_unix.c0000664000175000017500000002074615051422640016643 0ustar ghudsonghudson/* @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro"; #endif /* * auth_unix.c, Implements UNIX style authentication parameters. * * The system is very weak. The client uses no encryption for its * credentials and only sends null verifiers. The server sends backs * null verifiers or optionally a verifier that suggests a new short hand * for the credentials. * */ #include "autoconf.h" #include #include #include #include #include #include #include /* * Unix authenticator operations vector */ static void authunix_nextverf(AUTH *); static bool_t authunix_marshal(AUTH *, XDR *); static bool_t authunix_validate(AUTH *, struct opaque_auth *); static bool_t authunix_refresh(AUTH *, struct rpc_msg *); static void authunix_destroy(AUTH *); static bool_t authunix_wrap(AUTH *, XDR *, xdrproc_t, caddr_t); static struct auth_ops auth_unix_ops = { authunix_nextverf, authunix_marshal, authunix_validate, authunix_refresh, authunix_destroy, authunix_wrap, authunix_wrap }; /* * This struct is pointed to by the ah_private field of an auth_handle. */ struct audata { struct opaque_auth au_origcred; /* original credentials */ struct opaque_auth au_shcred; /* short hand cred */ uint32_t au_shfaults; /* short hand cache faults */ char au_marshed[MAX_AUTH_BYTES]; u_int au_mpos; /* xdr pos at end of marshed */ }; #define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) static void marshal_new_auth(AUTH *); /* * Create a unix style authenticator. * Returns an auth handle with the given stuff in it. */ AUTH * authunix_create( char *machname, int uid, int gid, int len, int *aup_gids) { struct authunix_parms aup; char mymem[MAX_AUTH_BYTES]; struct timeval now; XDR xdrs; AUTH *auth; struct audata *au; /* * Allocate and set up auth handle */ auth = (AUTH *)mem_alloc(sizeof(*auth)); #ifndef KERNEL if (auth == NULL) { (void)fprintf(stderr, "authunix_create: out of memory\n"); return (NULL); } #endif au = (struct audata *)mem_alloc(sizeof(*au)); #ifndef KERNEL if (au == NULL) { (void)fprintf(stderr, "authunix_create: out of memory\n"); return (NULL); } #endif auth->ah_ops = &auth_unix_ops; auth->ah_private = (caddr_t)au; auth->ah_verf = au->au_shcred = gssrpc__null_auth; au->au_shfaults = 0; /* * fill in param struct from the given params */ (void)gettimeofday(&now, (struct timezone *)0); aup.aup_time = now.tv_sec; aup.aup_machname = machname; aup.aup_uid = uid; aup.aup_gid = gid; aup.aup_len = (u_int)len; aup.aup_gids = aup_gids; /* * Serialize the parameters into origcred */ xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); if (! xdr_authunix_parms(&xdrs, &aup)) abort(); au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); au->au_origcred.oa_flavor = AUTH_UNIX; #ifdef KERNEL au->au_origcred.oa_base = mem_alloc((u_int) len); #else if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { (void)fprintf(stderr, "authunix_create: out of memory\n"); return (NULL); } #endif memmove(au->au_origcred.oa_base, mymem, (u_int)len); /* * set auth handle to reflect new cred. */ auth->ah_cred = au->au_origcred; marshal_new_auth(auth); return (auth); } /* * Returns an auth handle with parameters determined by doing lots of * syscalls. */ AUTH * authunix_create_default(void) { int len; char machname[MAX_MACHINE_NAME + 1]; int uid; int gid; GETGROUPS_T gids[NGRPS]; int igids[NGRPS], i; if (gethostname(machname, MAX_MACHINE_NAME) == -1) abort(); machname[MAX_MACHINE_NAME] = 0; uid = geteuid(); gid = getegid(); if ((len = getgroups(NGRPS, gids)) < 0) abort(); for(i = 0; i < NGRPS; i++) { igids[i] = gids[i]; } return (authunix_create(machname, uid, gid, len, igids)); } /* * authunix operations */ static void authunix_nextverf(AUTH *auth) { /* no action necessary */ } static bool_t authunix_marshal(AUTH *auth, XDR *xdrs) { struct audata *au = AUTH_PRIVATE(auth); return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); } static bool_t authunix_validate(AUTH *auth, struct opaque_auth *verf) { struct audata *au; XDR xdrs; if (verf->oa_flavor == AUTH_SHORT) { au = AUTH_PRIVATE(auth); xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, XDR_DECODE); if (au->au_shcred.oa_base != NULL) { mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); au->au_shcred.oa_base = NULL; } if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { auth->ah_cred = au->au_shcred; } else { xdrs.x_op = XDR_FREE; (void)xdr_opaque_auth(&xdrs, &au->au_shcred); au->au_shcred.oa_base = NULL; auth->ah_cred = au->au_origcred; } marshal_new_auth(auth); } return (TRUE); } static bool_t authunix_refresh(AUTH *auth, struct rpc_msg *msg) { struct audata *au = AUTH_PRIVATE(auth); struct authunix_parms aup; struct timeval now; XDR xdrs; int stat; if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { /* there is no hope. Punt */ return (FALSE); } au->au_shfaults ++; /* first deserialize the creds back into a struct authunix_parms */ aup.aup_machname = NULL; aup.aup_gids = (int *)NULL; xdrmem_create(&xdrs, au->au_origcred.oa_base, au->au_origcred.oa_length, XDR_DECODE); stat = xdr_authunix_parms(&xdrs, &aup); if (! stat) goto done; /* update the time and serialize in place */ (void)gettimeofday(&now, (struct timezone *)0); aup.aup_time = now.tv_sec; xdrs.x_op = XDR_ENCODE; XDR_SETPOS(&xdrs, 0); stat = xdr_authunix_parms(&xdrs, &aup); if (! stat) goto done; auth->ah_cred = au->au_origcred; marshal_new_auth(auth); done: /* free the struct authunix_parms created by deserializing */ xdrs.x_op = XDR_FREE; (void)xdr_authunix_parms(&xdrs, &aup); XDR_DESTROY(&xdrs); return (stat); } static void authunix_destroy(AUTH *auth) { struct audata *au = AUTH_PRIVATE(auth); mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); if (au->au_shcred.oa_base != NULL) mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); mem_free(auth->ah_private, sizeof(struct audata)); if (auth->ah_verf.oa_base != NULL) mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); mem_free((caddr_t)auth, sizeof(*auth)); } /* * Marshals (pre-serializes) an auth struct. * sets private data, au_marshed and au_mpos */ static void marshal_new_auth(AUTH *auth) { XDR xdr_stream; XDR *xdrs = &xdr_stream; struct audata *au = AUTH_PRIVATE(auth); xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { perror("auth_none.c - Fatal marshalling problem"); } else { au->au_mpos = XDR_GETPOS(xdrs); } XDR_DESTROY(xdrs); } static bool_t authunix_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xfunc, caddr_t xwhere) { return ((*xfunc)(xdrs, xwhere)); } krb5-1.22.1/src/lib/rpc/rpc_commondata.c0000664000175000017500000000430015051422640017611 0ustar ghudsonghudson/* @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include /* * This file should only contain common data (global data) that is exported * by public interfaces. * * Actually initialized to prevent creation of common blocks, which * can be problematic on some architectures. */ /* RENAMED: should be _null_auth */ struct opaque_auth gssrpc__null_auth = {0}; #ifdef FD_SETSIZE fd_set svc_fdset; /* Will be zeroed in data segment */ int gssrpc_svc_fdset_init = 0; #else int svc_fds = 0; #endif /* def FD_SETSIZE */ struct rpc_createerr rpc_createerr = {RPC_SUCCESS}; int svc_maxfd = -1; krb5-1.22.1/src/lib/rpc/getrpcport.c0000664000175000017500000000426615051422640017027 0ustar ghudsonghudson/* lib/rpc/getrpcport.c */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "autoconf.h" #include #include #include #include #include #include int gssrpc_getrpcport( char *host, rpcprog_t prognum, rpcvers_t versnum, rpcprot_t proto) { struct sockaddr_in addr; struct hostent *hp; if ((hp = gethostbyname(host)) == NULL) return (0); memset(&addr, 0, sizeof(addr)); memmove((char *) &addr.sin_addr, hp->h_addr, sizeof(addr.sin_addr)); addr.sin_family = AF_INET; addr.sin_port = 0; return (pmap_getport(&addr, prognum, versnum, proto)); } krb5-1.22.1/src/lib/rpc/dyn.h0000664000175000017500000000473515051422640015436 0ustar ghudsonghudson/* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the public header file. * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. * * 2002-07-17 Moved here from util/dyn; for old changes see dyn.c. * Added macros to rename exposed symbols. For newer changes * see ChangeLog in the current directory. */ /* * dyn.h -- header file to be included by programs linking against * libdyn.a. */ #ifndef _Dyn_h #define _Dyn_h typedef char *DynPtr; typedef struct _DynObject { DynPtr array; int el_size, num_el, size, inc; int debug, paranoid, initzero; } DynObjectRec, *DynObject; /* Function macros */ #define DynHigh(obj) (DynSize(obj) - 1) #define DynLow(obj) (0) /* Return status codes */ #define DYN_OK -1000 #define DYN_NOMEM -1001 #define DYN_BADINDEX -1002 #define DYN_BADVALUE -1003 #define DynCreate gssrpcint_DynCreate #define DynDestroy gssrpcint_DynDestroy #define DynRelease gssrpcint_DynRelease #define DynAdd gssrpcint_DynAdd #define DynPut gssrpcint_DynPut #define DynInsert gssrpcint_DynInsert #define DynGet gssrpcint_DynGet #define DynArray gssrpcint_DynArray #define DynSize gssrpcint_DynSize #define DynCopy gssrpcint_DynCopy #define DynDelete gssrpcint_DynDelete #define DynDebug gssrpcint_DynDebug #define DynParanoid gssrpcint_DynParanoid #define DynInitzero gssrpcint_DynInitzero #define DynCapacity gssrpcint_DynCapacity #define DynAppend gssrpcint_DynAppend /*@null@*//*@only@*/ DynObject DynCreate (int el_size, int inc); /*@null@*//*@only@*/ DynObject DynCopy (DynObject obj); int DynDestroy (/*@only@*/DynObject obj), DynRelease (DynObject obj); int DynAdd (DynObject obj, void *el); int DynPut (DynObject obj, void *el, int idx); int DynInsert (DynObject obj, int idx, /*@observer@*/void *els, int num); int DynDelete (DynObject obj, int idx); /*@dependent@*//*@null@*/ DynPtr DynGet (DynObject obj, int num); /*@observer@*/ DynPtr DynArray (DynObject obj); int DynDebug (DynObject obj, int state); int DynParanoid (DynObject obj, int state); int DynInitzero (DynObject obj, int state); int DynSize (DynObject obj); int DynCapacity (DynObject obj); int DynAppend (DynObject obj, DynPtr els, int num); #undef P #endif /* _Dyn_h */ /* DO NOT ADD ANYTHING AFTER THIS #endif */ krb5-1.22.1/src/lib/rpc/clnt_generic.c0000664000175000017500000000660415051422640017270 0ustar ghudsonghudson/* @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI"; #endif #include "autoconf.h" #include #include #include #include #include /* * Generic client creation: takes (hostname, program-number, protocol) and * returns client handle. Default options are set, which the user can * change using the rpc equivalent of ioctl()'s. */ CLIENT * clnt_create( char *hostname, rpcprog_t prog, rpcvers_t vers, char *proto) { struct hostent *h; struct protoent *p; struct sockaddr_in sockin; int sock; struct timeval tv; CLIENT *client; h = gethostbyname(hostname); if (h == NULL) { rpc_createerr.cf_stat = RPC_UNKNOWNHOST; return (NULL); } if (h->h_addrtype != AF_INET) { /* * Only support INET for now */ rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; return (NULL); } memset(&sockin, 0, sizeof(sockin)); sockin.sin_family = h->h_addrtype; sockin.sin_port = 0; memmove((char*)&sockin.sin_addr, h->h_addr, sizeof(sockin.sin_addr)); p = getprotobyname(proto); if (p == NULL) { rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; return (NULL); } sock = RPC_ANYSOCK; switch (p->p_proto) { case IPPROTO_UDP: tv.tv_sec = 5; tv.tv_usec = 0; client = clntudp_create(&sockin, prog, vers, tv, &sock); if (client == NULL) { return (NULL); } break; case IPPROTO_TCP: client = clnttcp_create(&sockin, prog, vers, &sock, 0, 0); if (client == NULL) { return (NULL); } break; default: rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; return (NULL); } return (client); } krb5-1.22.1/src/lib/rpc/xdr_sizeof.c0000664000175000017500000000750715051422640017013 0ustar ghudsonghudson/* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * xdr_sizeof.c * * General purpose routine to see how much space something will use * when serialized using XDR. */ #include #include #include /* ARGSUSED */ static bool_t x_putlong(XDR *xdrs, long *longp) { xdrs->x_handy += BYTES_PER_XDR_UNIT; return (TRUE); } /* ARGSUSED */ static bool_t x_putbytes(XDR *xdrs, char *bp, u_int len) { xdrs->x_handy += len; return (TRUE); } static u_int x_getpostn(XDR *xdrs) { return (xdrs->x_handy); } /* ARGSUSED */ static bool_t x_setpostn(XDR *xdrs, u_int pos) { /* This is not allowed */ return (FALSE); } static rpc_inline_t * x_inline(XDR *xdrs, int len) { if (len == 0) { return (NULL); } if (xdrs->x_op != XDR_ENCODE) { return (NULL); } if (len < (int) ((caddr_t) xdrs->x_private - xdrs->x_base)) { /* x_private was already allocated */ xdrs->x_handy += len; return ((rpc_inline_t *) xdrs->x_private); } else { /* Free the earlier space and allocate new area */ if (xdrs->x_base) free(xdrs->x_base); if ((xdrs->x_base = (caddr_t) malloc(len)) == NULL) { xdrs->x_private = NULL; return (NULL); } xdrs->x_private = xdrs->x_base + len; xdrs->x_handy += len; return ((rpc_inline_t *) (void *) xdrs->x_base); } } static int harmless(void) { /* Always return FALSE/NULL, as the case may be */ return (0); } static void x_destroy(XDR *xdrs) { xdrs->x_handy = 0; xdrs->x_private = NULL; if (xdrs->x_base) { free(xdrs->x_base); xdrs->x_base = NULL; } return; } unsigned long xdr_sizeof(xdrproc_t func, void *data) { XDR x; struct xdr_ops ops; bool_t stat; /* to stop ANSI-C compiler from complaining */ typedef bool_t (* dummyfunc1)(XDR *, long *); typedef bool_t (* dummyfunc2)(XDR *, caddr_t, u_int); ops.x_putlong = x_putlong; ops.x_putbytes = x_putbytes; ops.x_inline = x_inline; ops.x_getpostn = x_getpostn; ops.x_setpostn = x_setpostn; ops.x_destroy = x_destroy; /* the other harmless ones */ ops.x_getlong = (dummyfunc1) harmless; ops.x_getbytes = (dummyfunc2) harmless; x.x_op = XDR_ENCODE; x.x_ops = &ops; x.x_handy = 0; x.x_private = (caddr_t) NULL; x.x_base = (caddr_t) 0; stat = func(&x, data); if (x.x_base) free(x.x_base); return (stat == TRUE ? (unsigned) x.x_handy: 0); } krb5-1.22.1/src/lib/rpc/svc_auth_gssapi.c0000664000175000017500000007536715051422640020032 0ustar ghudsonghudson/* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. * * $Id$ * */ /* * svc_auth_gssapi.c * Handles the GSS-API flavor authentication parameters on the service * side of RPC. */ #include #include #include #include #include #include #include #ifdef GSS_BACKWARD_HACK #include #endif #include "gssrpcint.h" #ifdef GSSAPI_KRB5 /* This is here for the krb5_error_code typedef and the * KRB5KRB_AP_ERR_NOT_US #define.*/ #include #endif #include #include #include #define INITIATION_TIMEOUT 60*15 /* seconds until partially created */ /* context is destroed */ #define INDEF_EXPIRE 60*60*24 /* seconds until an context with no */ /* expiration time is expired */ #ifdef __CODECENTER__ #define DEBUG_GSSAPI 1 #endif #ifdef DEBUG_GSSAPI int svc_debug_gssapi = DEBUG_GSSAPI; void gssrpcint_printf(const char *format, ...) { va_list ap; va_start(ap, format); #if 1 vprintf(format, ap); #else { static FILE *f; if (f == NULL) f = fopen("/dev/pts/4", "a"); if (f) { vfprintf(f, format, ap); fflush(f); } } #endif va_end(ap); } #define L_PRINTF(l,args) if (svc_debug_gssapi >= l) gssrpcint_printf args #define PRINTF(args) L_PRINTF(99, args) #define AUTH_GSSAPI_DISPLAY_STATUS(args) \ if (svc_debug_gssapi) auth_gssapi_display_status args #else #define PRINTF(args) #define L_PRINTF(l, args) #define AUTH_GSSAPI_DISPLAY_STATUS(args) #endif typedef struct _svc_auth_gssapi_data { bool_t established; gss_ctx_id_t context; gss_name_t client_name, server_name; gss_cred_id_t server_creds; uint32_t expiration; uint32_t seq_num; uint32_t key; SVCAUTH svcauth; /* kludge to free verifiers on next call */ gss_buffer_desc prev_verf; } svc_auth_gssapi_data; #define SVCAUTH_PRIVATE(auth) \ ((svc_auth_gssapi_data *)(auth)->svc_ah_private) static bool_t svc_auth_gssapi_wrap(SVCAUTH *, XDR *, xdrproc_t, caddr_t); static bool_t svc_auth_gssapi_unwrap(SVCAUTH *, XDR *, xdrproc_t, caddr_t); static bool_t svc_auth_gssapi_destroy(SVCAUTH *); static svc_auth_gssapi_data *create_client(void); static svc_auth_gssapi_data *get_client (gss_buffer_t client_handle); static void destroy_client (svc_auth_gssapi_data *client_data); static void clean_client(void), cleanup(void); static void client_expire (svc_auth_gssapi_data *client_data, uint32_t exp); static void dump_db (char *msg); struct svc_auth_ops svc_auth_gssapi_ops = { svc_auth_gssapi_wrap, svc_auth_gssapi_unwrap, svc_auth_gssapi_destroy }; /* * Globals! Eeek! Run for the hills! */ static gss_cred_id_t *server_creds_list = NULL; static gss_name_t *server_name_list = NULL; static int server_creds_count = 0; static auth_gssapi_log_badauth_func log_badauth = NULL; static caddr_t log_badauth_data = NULL; static auth_gssapi_log_badauth2_func log_badauth2 = NULL; static caddr_t log_badauth2_data = NULL; static auth_gssapi_log_badverf_func log_badverf = NULL; static caddr_t log_badverf_data = NULL; static auth_gssapi_log_miscerr_func log_miscerr = NULL; static caddr_t log_miscerr_data = NULL; #define LOG_MISCERR(arg) if (log_miscerr) \ (*log_miscerr)(rqst, msg, arg, log_miscerr_data) typedef struct _client_list { svc_auth_gssapi_data *client; struct _client_list *next; } client_list; static client_list *clients = NULL; /* Invoke log_badauth callbacks for an authentication failure. */ static void badauth(OM_uint32 maj, OM_uint32 minor, SVCXPRT *xprt) { if (log_badauth != NULL) (*log_badauth)(maj, minor, &xprt->xp_raddr, log_badauth_data); if (log_badauth2 != NULL) (*log_badauth2)(maj, minor, xprt, log_badauth2_data); } enum auth_stat gssrpc__svcauth_gssapi( struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch) { XDR xdrs; auth_gssapi_creds creds; auth_gssapi_init_arg call_arg; auth_gssapi_init_res call_res; gss_buffer_desc output_token, in_buf, out_buf; gss_cred_id_t server_creds; struct gss_channel_bindings_struct bindings, *bindp; OM_uint32 gssstat, minor_stat, time_rec; struct opaque_auth *cred, *verf; svc_auth_gssapi_data *client_data; int i; enum auth_stat ret; OM_uint32 ret_flags; uint32_t seq_num; PRINTF(("svcauth_gssapi: starting\n")); /* clean up expired entries */ clean_client(); /* use AUTH_NONE until there is a client_handle */ rqst->rq_xprt->xp_auth = &svc_auth_none; memset(&call_res, 0, sizeof(call_res)); creds.client_handle.length = 0; creds.client_handle.value = NULL; cred = &msg->rm_call.cb_cred; verf = &msg->rm_call.cb_verf; if (cred->oa_length == 0) { PRINTF(("svcauth_gssapi: empty creds, failing\n")); LOG_MISCERR("empty client credentials"); ret = AUTH_BADCRED; goto error; } PRINTF(("svcauth_gssapi: decoding credentials\n")); xdrmem_create(&xdrs, cred->oa_base, cred->oa_length, XDR_DECODE); memset(&creds, 0, sizeof(creds)); if (! xdr_authgssapi_creds(&xdrs, &creds)) { PRINTF(("svcauth_gssapi: failed decoding creds\n")); LOG_MISCERR("protocol error in client credentials"); xdr_free((xdrproc_t)xdr_authgssapi_creds, &creds); XDR_DESTROY(&xdrs); ret = AUTH_BADCRED; goto error; } XDR_DESTROY(&xdrs); PRINTF(("svcauth_gssapi: got credentials, version %d, client_handle len %d\n", creds.version, (int) creds.client_handle.length)); if (creds.version != 2) { PRINTF(("svcauth_gssapi: bad credential version\n")); LOG_MISCERR("unsupported client credentials version"); ret = AUTH_BADCRED; goto error; } #ifdef DEBUG_GSSAPI if (svc_debug_gssapi) { if (creds.auth_msg && rqst->rq_proc == AUTH_GSSAPI_EXIT) { PRINTF(("svcauth_gssapi: GSSAPI_EXIT, cleaning up\n")); svc_sendreply(rqst->rq_xprt, xdr_void, NULL); xdr_free((xdrproc_t)xdr_authgssapi_creds, &creds); cleanup(); exit(0); } } #endif /* * If this is an auth_msg and proc is GSSAPI_INIT, then create a * client handle for this client. Otherwise, look up the * existing handle. */ if (creds.auth_msg && rqst->rq_proc == AUTH_GSSAPI_INIT) { if (creds.client_handle.length != 0) { PRINTF(("svcauth_gssapi: non-empty handle on GSSAPI_INIT\n")); LOG_MISCERR("protocol error in client handle"); ret = AUTH_FAILED; goto error; } PRINTF(("svcauth_gssapi: GSSAPI_INIT, creating client.\n")); client_data = create_client(); if (client_data == NULL) { PRINTF(("svcauth_gssapi: create_client failed\n")); LOG_MISCERR("internal error creating client record"); ret = AUTH_FAILED; goto error; } } else { if (creds.client_handle.length == 0) { PRINTF(("svcauth_gssapi: expected non-empty creds\n")); LOG_MISCERR("protocol error in client credentials"); ret = AUTH_FAILED; goto error; } PRINTF(("svcauth_gssapi: incoming client_handle %d, len %d\n", *((uint32_t *) creds.client_handle.value), (int) creds.client_handle.length)); client_data = get_client(&creds.client_handle); if (client_data == NULL) { PRINTF(("svcauth_gssapi: client_handle lookup failed\n")); LOG_MISCERR("invalid client handle received"); ret = AUTH_BADCRED; goto error; } PRINTF(("svcauth_gssapi: client_handle lookup succeeded\n")); } /* any response we send will use client_handle, so set it now */ call_res.client_handle.length = sizeof(client_data->key); call_res.client_handle.value = (char *) &client_data->key; /* mark this call as using AUTH_GSSAPI via client_data's SVCAUTH */ rqst->rq_xprt->xp_auth = &client_data->svcauth; if (client_data->established == FALSE) { PRINTF(("svcauth_gssapi: context is not established\n")); if (creds.auth_msg == FALSE) { PRINTF(("svcauth_gssapi: expected auth_msg TRUE\n")); LOG_MISCERR("protocol error on incomplete connection"); ret = AUTH_REJECTEDCRED; goto error; } /* * If the context is not established, then only GSSAPI_INIT * and _CONTINUE requests are valid. */ if (rqst->rq_proc != AUTH_GSSAPI_INIT && rqst->rq_proc != AUTH_GSSAPI_CONTINUE_INIT) { PRINTF(("svcauth_gssapi: unacceptable procedure %d\n", rqst->rq_proc)); LOG_MISCERR("protocol error on incomplete connection"); ret = AUTH_FAILED; goto error; } /* call is for us, deserialize arguments */ memset(&call_arg, 0, sizeof(call_arg)); if (! svc_getargs(rqst->rq_xprt, (xdrproc_t)xdr_authgssapi_init_arg, &call_arg)) { PRINTF(("svcauth_gssapi: cannot decode args\n")); LOG_MISCERR("protocol error in procedure arguments"); ret = AUTH_BADCRED; goto error; } /* * Process the call arg version number. * * Set the krb5_gss backwards-compatibility mode based on client * version. This controls whether the AP_REP message is * encrypted with the session key (version 2+, correct) or the * session subkey (version 1, incorrect). This function can * never fail, so we don't bother checking its return value. */ switch (call_arg.version) { case 1: case 2: LOG_MISCERR("Warning: Accepted old RPC protocol request"); call_res.version = 1; break; case 3: case 4: /* 3 and 4 are essentially the same, don't bother warning */ call_res.version = call_arg.version; break; default: PRINTF(("svcauth_gssapi: bad GSSAPI_INIT version\n")); LOG_MISCERR("unsupported GSSAPI_INIT version"); ret = AUTH_BADCRED; goto error; } #ifdef GSS_BACKWARD_HACK krb5_gss_set_backward_mode(&minor_stat, call_arg.version == 1); #endif if (call_arg.version >= 3) { memset(&bindings, 0, sizeof(bindings)); bindings.application_data.length = 0; bindings.initiator_addrtype = GSS_C_AF_INET; bindings.initiator_address.length = 4; bindings.initiator_address.value = &svc_getcaller(rqst->rq_xprt)->sin_addr.s_addr; if (rqst->rq_xprt->xp_laddrlen > 0) { bindings.acceptor_addrtype = GSS_C_AF_INET; bindings.acceptor_address.length = 4; bindings.acceptor_address.value = &rqst->rq_xprt->xp_laddr.sin_addr.s_addr; } else { LOG_MISCERR("cannot get local address"); ret = AUTH_FAILED; goto error; } bindp = &bindings; } else { bindp = GSS_C_NO_CHANNEL_BINDINGS; } /* * If the client's server_creds is already set, use it. * Otherwise, try each credential in server_creds_list until * one of them succeeds, then set the client server_creds * to that. If all fail, the client's server_creds isn't * set (which is fine, because the client will be gc'ed * anyway). * * If accept_sec_context returns something other than * success and GSS_S_FAILURE, then assume different * credentials won't help and stop looping. * * Note that there are really two cases here: (1) the client * has a server_creds already, and (2) it does not. They * are both written in the same loop so that there is only * one textual call to gss_accept_sec_context; in fact, in * case (1), the loop is executed exactly once. */ for (i = 0; i < server_creds_count; i++) { if (client_data->server_creds != NULL) { PRINTF(("svcauth_gssapi: using's clients server_creds\n")); server_creds = client_data->server_creds; } else { PRINTF(("svcauth_gssapi: trying creds %d\n", i)); server_creds = server_creds_list[i]; } /* Free previous output_token from loop */ if(i != 0) gss_release_buffer(&minor_stat, &output_token); call_res.gss_major = gss_accept_sec_context(&call_res.gss_minor, &client_data->context, server_creds, &call_arg.token, bindp, &client_data->client_name, NULL, &output_token, &ret_flags, &time_rec, NULL); if (server_creds == client_data->server_creds) break; PRINTF(("accept_sec_context returned 0x%x 0x%x not-us=%#x\n", call_res.gss_major, call_res.gss_minor, (int) KRB5KRB_AP_ERR_NOT_US)); if (call_res.gss_major == GSS_S_COMPLETE || call_res.gss_major == GSS_S_CONTINUE_NEEDED) { /* server_creds was right, set it! */ PRINTF(("svcauth_gssapi: creds are correct, storing\n")); client_data->server_creds = server_creds; client_data->server_name = server_name_list[i]; break; } else if (call_res.gss_major != GSS_S_FAILURE #ifdef GSSAPI_KRB5 /* * hard-coded because there is no other way * to prevent all GSS_S_FAILURES from * returning a "wrong principal in request" * error */ || ((krb5_error_code) call_res.gss_minor != (krb5_error_code) KRB5KRB_AP_ERR_NOT_US) #endif ) { break; } } gssstat = call_res.gss_major; minor_stat = call_res.gss_minor; /* done with call args */ xdr_free((xdrproc_t)xdr_authgssapi_init_arg, &call_arg); PRINTF(("svcauth_gssapi: accept_sec_context returned %#x %#x\n", call_res.gss_major, call_res.gss_minor)); if (call_res.gss_major != GSS_S_COMPLETE && call_res.gss_major != GSS_S_CONTINUE_NEEDED) { AUTH_GSSAPI_DISPLAY_STATUS(("accepting context", call_res.gss_major, call_res.gss_minor)); badauth(call_res.gss_major, call_res.gss_minor, rqst->rq_xprt); gss_release_buffer(&minor_stat, &output_token); svc_sendreply(rqst->rq_xprt, (xdrproc_t)xdr_authgssapi_init_res, (caddr_t) &call_res); *no_dispatch = TRUE; ret = AUTH_OK; goto error; } if (output_token.length != 0) { PRINTF(("svcauth_gssapi: got new output token\n")); GSS_COPY_BUFFER(call_res.token, output_token); } if (gssstat == GSS_S_COMPLETE) { client_data->seq_num = rand(); client_expire(client_data, (time_rec == GSS_C_INDEFINITE ? INDEF_EXPIRE : time_rec) + time(0)); PRINTF(("svcauth_gssapi: context established, isn %d\n", client_data->seq_num)); if (auth_gssapi_seal_seq(client_data->context, client_data->seq_num, &call_res.signed_isn) == FALSE) { ret = AUTH_FAILED; LOG_MISCERR("internal error sealing sequence number"); gss_release_buffer(&minor_stat, &output_token); goto error; } } PRINTF(("svcauth_gssapi: sending reply\n")); svc_sendreply(rqst->rq_xprt, (xdrproc_t)xdr_authgssapi_init_res, (caddr_t) &call_res); *no_dispatch = TRUE; /* * If appropriate, set established to TRUE *after* sending * response (otherwise, the client will receive the final * token encrypted) */ if (gssstat == GSS_S_COMPLETE) { gss_release_buffer(&minor_stat, &call_res.signed_isn); client_data->established = TRUE; } gss_release_buffer(&minor_stat, &output_token); } else { PRINTF(("svcauth_gssapi: context is established\n")); /* check the verifier */ PRINTF(("svcauth_gssapi: checking verifier, len %d\n", verf->oa_length)); in_buf.length = verf->oa_length; in_buf.value = verf->oa_base; if (auth_gssapi_unseal_seq(client_data->context, &in_buf, &seq_num) == FALSE) { ret = AUTH_BADVERF; LOG_MISCERR("internal error unsealing sequence number"); goto error; } if (seq_num != client_data->seq_num + 1) { PRINTF(("svcauth_gssapi: expected isn %d, got %d\n", client_data->seq_num + 1, seq_num)); if (log_badverf != NULL) (*log_badverf)(client_data->client_name, client_data->server_name, rqst, msg, log_badverf_data); ret = AUTH_REJECTEDVERF; goto error; } client_data->seq_num++; PRINTF(("svcauth_gssapi: seq_num %d okay\n", seq_num)); /* free previous response verifier, if any */ if (client_data->prev_verf.length != 0) { gss_release_buffer(&minor_stat, &client_data->prev_verf); client_data->prev_verf.length = 0; } /* prepare response verifier */ seq_num = client_data->seq_num + 1; if (auth_gssapi_seal_seq(client_data->context, seq_num, &out_buf) == FALSE) { ret = AUTH_FAILED; LOG_MISCERR("internal error sealing sequence number"); goto error; } client_data->seq_num++; PRINTF(("svcauth_gssapi; response seq_num %d\n", seq_num)); rqst->rq_xprt->xp_verf.oa_flavor = AUTH_GSSAPI; rqst->rq_xprt->xp_verf.oa_base = out_buf.value; rqst->rq_xprt->xp_verf.oa_length = out_buf.length; /* save verifier so it can be freed next time */ client_data->prev_verf.value = out_buf.value; client_data->prev_verf.length = out_buf.length; /* * Message is authentic. If auth_msg if true, process the * call; otherwise, return AUTH_OK so it will be dispatched * to the application server. */ if (creds.auth_msg == TRUE) { /* * If process_token fails, then the token probably came * from an attacker. No response (error or otherwise) * should be returned to the client, since it won't be * accepting one. */ switch (rqst->rq_proc) { case AUTH_GSSAPI_MSG: PRINTF(("svcauth_gssapi: GSSAPI_MSG, getting args\n")); memset(&call_arg, 0, sizeof(call_arg)); if (! svc_getargs(rqst->rq_xprt, (xdrproc_t)xdr_authgssapi_init_arg, &call_arg)) { PRINTF(("svcauth_gssapi: cannot decode args\n")); LOG_MISCERR("protocol error in call arguments"); xdr_free((xdrproc_t)xdr_authgssapi_init_arg, &call_arg); ret = AUTH_BADCRED; goto error; } PRINTF(("svcauth_gssapi: processing token\n")); gssstat = gss_process_context_token(&minor_stat, client_data->context, &call_arg.token); /* done with call args */ xdr_free((xdrproc_t)xdr_authgssapi_init_arg, &call_arg); if (gssstat != GSS_S_COMPLETE) { AUTH_GSSAPI_DISPLAY_STATUS(("processing token", gssstat, minor_stat)); ret = AUTH_FAILED; goto error; } svc_sendreply(rqst->rq_xprt, xdr_void, NULL); *no_dispatch = TRUE; break; case AUTH_GSSAPI_DESTROY: PRINTF(("svcauth_gssapi: GSSAPI_DESTROY\n")); PRINTF(("svcauth_gssapi: sending reply\n")); svc_sendreply(rqst->rq_xprt, xdr_void, NULL); *no_dispatch = TRUE; destroy_client(client_data); rqst->rq_xprt->xp_auth = NULL; break; default: PRINTF(("svcauth_gssapi: unacceptable procedure %d\n", rqst->rq_proc)); LOG_MISCERR("invalid call procedure number"); ret = AUTH_FAILED; goto error; } } else { /* set credentials for app server; comment in svc.c */ /* seems to imply this is incorrect, but I don't see */ /* any problem with it... */ rqst->rq_clntcred = (char *)client_data->client_name; rqst->rq_svccred = (char *)client_data->context; } } if (creds.client_handle.length != 0) { PRINTF(("svcauth_gssapi: freeing client_handle len %d\n", (int) creds.client_handle.length)); xdr_free((xdrproc_t)xdr_authgssapi_creds, &creds); } PRINTF(("\n")); return AUTH_OK; error: if (creds.client_handle.length != 0) { PRINTF(("svcauth_gssapi: freeing client_handle len %d\n", (int) creds.client_handle.length)); xdr_free((xdrproc_t)xdr_authgssapi_creds, &creds); } PRINTF(("\n")); return ret; } static void cleanup(void) { client_list *c, *c2; PRINTF(("cleanup_and_exit: starting\n")); c = clients; while (c) { c2 = c; c = c->next; destroy_client(c2->client); free(c2); } exit(0); } /* * Function: create_client * * Purpose: Creates an new client_data structure and stores it in the * database. * * Returns: the new client_data structure, or NULL on failure. * * Effects: * * A new client_data is created and stored in the hash table and * b-tree. A new key that is unique in the current database is * chosen; this key should be used as the client's client_handle. */ static svc_auth_gssapi_data *create_client(void) { client_list *c; svc_auth_gssapi_data *client_data; static int client_key = 1; PRINTF(("svcauth_gssapi: empty creds, creating\n")); client_data = (svc_auth_gssapi_data *) malloc(sizeof(*client_data)); if (client_data == NULL) return NULL; memset(client_data, 0, sizeof(*client_data)); L_PRINTF(2, ("create_client: new client_data = %p\n", (void *) client_data)); /* set up client data structure */ client_data->established = 0; client_data->context = GSS_C_NO_CONTEXT; client_data->expiration = time(0) + INITIATION_TIMEOUT; /* set up psycho-recursive SVCAUTH hack */ client_data->svcauth.svc_ah_ops = &svc_auth_gssapi_ops; client_data->svcauth.svc_ah_private = (caddr_t) client_data; client_data->key = client_key++; c = (client_list *) malloc(sizeof(client_list)); if (c == NULL) return NULL; c->client = client_data; c->next = NULL; if (clients == NULL) clients = c; else { c->next = clients; clients = c; } PRINTF(("svcauth_gssapi: new handle %d\n", client_data->key)); L_PRINTF(2, ("create_client: done\n")); return client_data; } /* * Function: client_expire * * Purpose: change the expiration time of a client in the database * * Arguments: * * client_data (r) the client_data to expire * exp (r) the new expiration time * * Effects: * * client_data->expiration = exp * * This function used to remove client_data from the database, change * its expiration time, and re-add it, which was necessary because the * database was sorted by expiration time so a simple modification * would break the rep invariant. Now the database is an unsorted * linked list, so it doesn't matter. */ static void client_expire( svc_auth_gssapi_data *client_data, uint32_t exp) { client_data->expiration = exp; } /* * Function get_client * * Purpose: retrieve a client_data structure from the database based * on its client handle (key) * * Arguments: * * client_handle (r) the handle (key) to retrieve * * Effects: * * Searches the list and returns the client_data whose key field * matches the contents of client_handle, or returns NULL if none was * found. */ static svc_auth_gssapi_data *get_client(gss_buffer_t client_handle) { client_list *c; uint32_t handle; memcpy(&handle, client_handle->value, 4); L_PRINTF(2, ("get_client: looking for client %d\n", handle)); c = clients; while (c) { if (c->client->key == handle) return c->client; c = c->next; } L_PRINTF(2, ("get_client: client_handle lookup failed\n")); return NULL; } /* * Function: destroy_client * * Purpose: destroys a client entry and removes it from the database * * Arguments: * * client_data (r) the client to be destroyed * * Effects: * * client_data->context is deleted with gss_delete_sec_context. * client_data's entry in the database is destroyed. client_data is * freed. */ static void destroy_client(svc_auth_gssapi_data *client_data) { OM_uint32 gssstat, minor_stat; gss_buffer_desc out_buf; client_list *c, *c2; PRINTF(("destroy_client: destroying client_data\n")); L_PRINTF(2, ("destroy_client: client_data = %p\n", (void *) client_data)); #ifdef DEBUG_GSSAPI if (svc_debug_gssapi >= 3) dump_db("before frees"); #endif /* destroy client struct even if error occurs */ gssstat = gss_delete_sec_context(&minor_stat, &client_data->context, &out_buf); if (gssstat != GSS_S_COMPLETE) AUTH_GSSAPI_DISPLAY_STATUS(("deleting context", gssstat, minor_stat)); gss_release_buffer(&minor_stat, &out_buf); gss_release_name(&minor_stat, &client_data->client_name); if (client_data->prev_verf.length != 0) gss_release_buffer(&minor_stat, &client_data->prev_verf); if (clients == NULL) { PRINTF(("destroy_client: called on empty database\n")); abort(); } else if (clients->client == client_data) { c = clients; clients = clients->next; free(c); } else { c2 = clients; c = clients->next; while (c) { if (c->client == client_data) { c2->next = c->next; free(c); goto done; } else { c2 = c; c = c->next; } } PRINTF(("destroy_client: client_handle delete failed\n")); abort(); } done: L_PRINTF(2, ("destroy_client: client %d destroyed\n", client_data->key)); free(client_data); } static void dump_db(char *msg) { svc_auth_gssapi_data *client_data; client_list *c; L_PRINTF(3, ("dump_db: %s:\n", msg)); c = clients; while (c) { client_data = c->client; L_PRINTF(3, ("\tclient_data = %p, exp = %d\n", (void *) client_data, client_data->expiration)); c = c->next; } L_PRINTF(3, ("\n")); } static void clean_client(void) { svc_auth_gssapi_data *client_data; client_list *c; PRINTF(("clean_client: starting\n")); c = clients; while (c) { client_data = c->client; L_PRINTF(2, ("clean_client: client_data = %p\n", (void *) client_data)); if (client_data->expiration < time(0)) { PRINTF(("clean_client: client %d expired\n", client_data->key)); destroy_client(client_data); c = clients; /* start over, just to be safe */ } else { c = c->next; } } PRINTF(("clean_client: done\n")); } /* * Function: svcauth_gssapi_set_names * * Purpose: Sets the list of service names for which incoming * authentication requests should be honored. * * See functional specifications. */ bool_t svcauth_gssapi_set_names( auth_gssapi_name *names, int num) { OM_uint32 gssstat, minor_stat; gss_buffer_desc in_buf; int i; if (num == 0) for (; names[num].name != NULL; num++) ; server_creds_list = NULL; server_name_list = NULL; server_creds_list = (gss_cred_id_t *) malloc(num*sizeof(gss_cred_id_t)); if (server_creds_list == NULL) goto fail; server_name_list = (gss_name_t *) malloc(num*sizeof(gss_name_t)); if (server_name_list == NULL) goto fail; for (i = 0; i < num; i++) { server_name_list[i] = 0; server_creds_list[i] = 0; } server_creds_count = num; for (i = 0; i < num; i++) { in_buf.value = names[i].name; in_buf.length = strlen(in_buf.value) + 1; PRINTF(("svcauth_gssapi_set_names: importing %s\n", names[i].name)); gssstat = gss_import_name(&minor_stat, &in_buf, names[i].type, &server_name_list[i]); if (gssstat != GSS_S_COMPLETE) { AUTH_GSSAPI_DISPLAY_STATUS(("importing name", gssstat, minor_stat)); goto fail; } gssstat = gss_acquire_cred(&minor_stat, server_name_list[i], 0, GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &server_creds_list[i], NULL, NULL); if (gssstat != GSS_S_COMPLETE) { AUTH_GSSAPI_DISPLAY_STATUS(("acquiring credentials", gssstat, minor_stat)); goto fail; } } return TRUE; fail: svcauth_gssapi_unset_names(); return FALSE; } /* Function: svcauth_gssapi_unset_names * * Purpose: releases the names and credentials allocated by * svcauth_gssapi_set_names */ void svcauth_gssapi_unset_names(void) { int i; OM_uint32 minor_stat; if (server_creds_list) { for (i = 0; i < server_creds_count; i++) if (server_creds_list[i]) gss_release_cred(&minor_stat, &server_creds_list[i]); free(server_creds_list); server_creds_list = NULL; } if (server_name_list) { for (i = 0; i < server_creds_count; i++) if (server_name_list[i]) gss_release_name(&minor_stat, &server_name_list[i]); free(server_name_list); server_name_list = NULL; } server_creds_count = 0; } /* * Function: svcauth_gssapi_set_log_badauth_func * * Purpose: sets the logging function called when an invalid RPC call * arrives * * See functional specifications. */ void svcauth_gssapi_set_log_badauth_func( auth_gssapi_log_badauth_func func, caddr_t data) { log_badauth = func; log_badauth_data = data; } void svcauth_gssapi_set_log_badauth2_func(auth_gssapi_log_badauth2_func func, caddr_t data) { log_badauth2 = func; log_badauth2_data = data; } /* * Function: svcauth_gssapi_set_log_badverf_func * * Purpose: sets the logging function called when an invalid RPC call * arrives * * See functional specifications. */ void svcauth_gssapi_set_log_badverf_func( auth_gssapi_log_badverf_func func, caddr_t data) { log_badverf = func; log_badverf_data = data; } /* * Function: svcauth_gssapi_set_log_miscerr_func * * Purpose: sets the logging function called when a miscellaneous * AUTH_GSSAPI error occurs * * See functional specifications. */ void svcauth_gssapi_set_log_miscerr_func( auth_gssapi_log_miscerr_func func, caddr_t data) { log_miscerr = func; log_miscerr_data = data; } /* * Encrypt the serialized arguments from xdr_func applied to xdr_ptr * and write the result to xdrs. */ static bool_t svc_auth_gssapi_wrap( SVCAUTH *auth, XDR *out_xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { OM_uint32 gssstat, minor_stat; if (! SVCAUTH_PRIVATE(auth)->established) { PRINTF(("svc_gssapi_wrap: not established, noop\n")); return (*xdr_func)(out_xdrs, xdr_ptr); } else if (! auth_gssapi_wrap_data(&gssstat, &minor_stat, SVCAUTH_PRIVATE(auth)->context, SVCAUTH_PRIVATE(auth)->seq_num, out_xdrs, xdr_func, xdr_ptr)) { if (gssstat != GSS_S_COMPLETE) AUTH_GSSAPI_DISPLAY_STATUS(("encrypting function arguments", gssstat, minor_stat)); return FALSE; } else return TRUE; } static bool_t svc_auth_gssapi_unwrap( SVCAUTH *auth, XDR *in_xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { svc_auth_gssapi_data *client_data = SVCAUTH_PRIVATE(auth); OM_uint32 gssstat, minor_stat; if (! client_data->established) { PRINTF(("svc_gssapi_unwrap: not established, noop\n")); return (*xdr_func)(in_xdrs, (auth_gssapi_init_arg *)(void *) xdr_ptr); } else if (! auth_gssapi_unwrap_data(&gssstat, &minor_stat, client_data->context, client_data->seq_num-1, in_xdrs, xdr_func, xdr_ptr)) { if (gssstat != GSS_S_COMPLETE) AUTH_GSSAPI_DISPLAY_STATUS(("decrypting function arguments", gssstat, minor_stat)); return FALSE; } else return TRUE; } static bool_t svc_auth_gssapi_destroy(SVCAUTH *auth) { svc_auth_gssapi_data *client_data = SVCAUTH_PRIVATE(auth); destroy_client(client_data); return TRUE; } krb5-1.22.1/src/lib/rpc/xdr_reference.c0000664000175000017500000000753315051422640017451 0ustar ghudsonghudson/* @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI"; #endif /* * xdr_reference.c, Generic XDR routines impelmentation. * * These are the "non-trivial" xdr primitives used to serialize and de-serialize * "pointers". See xdr.h for more info on the interface to xdr. */ #include #include #include #include /* * XDR an indirect pointer * xdr_reference is for recursively translating a structure that is * referenced by a pointer inside the structure that is currently being * translated. pp references a pointer to storage. If *pp is null * the necessary storage is allocated. * size is the sizeof the referenced structure. * proc is the routine to handle the referenced structure. */ bool_t xdr_reference( XDR *xdrs, caddr_t *pp, /* the pointer to work on */ u_int size, /* size of the object pointed to */ xdrproc_t proc /* xdr routine to handle the object */ ) { caddr_t loc = *pp; bool_t stat; if (loc == NULL) switch (xdrs->x_op) { case XDR_FREE: return (TRUE); case XDR_DECODE: *pp = loc = (caddr_t) mem_alloc(size); if (loc == NULL) { (void) fprintf(stderr, "xdr_reference: out of memory\n"); return (FALSE); } memset(loc, 0, size); break; case XDR_ENCODE: break; } stat = (*proc)(xdrs, loc); if (xdrs->x_op == XDR_FREE) { mem_free(loc, size); *pp = NULL; } return (stat); } /* * xdr_pointer(): * * XDR a pointer to a possibly recursive data structure. This * differs with xdr_reference in that it can serialize/deserialiaze * trees correctly. * * What's sent is actually a union: * * union object_pointer switch (boolean b) { * case TRUE: object_data data; * case FALSE: void nothing; * } * * > objpp: Pointer to the pointer to the object. * > obj_size: size of the object. * > xdr_obj: routine to XDR an object. * */ bool_t xdr_pointer( XDR *xdrs, char **objpp, u_int obj_size, xdrproc_t xdr_obj) { bool_t more_data; more_data = (*objpp != NULL); if (! xdr_bool(xdrs,&more_data)) { return (FALSE); } if (! more_data) { *objpp = NULL; return (TRUE); } return (xdr_reference(xdrs,objpp,obj_size,xdr_obj)); } krb5-1.22.1/src/lib/rpc/auth_none.c0000664000175000017500000000770715051422640016621 0ustar ghudsonghudson/* @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro"; #endif /* * auth_none.c * Creates a client authentication handle for passing "null" * credentials and verifiers to remote systems. */ #include #include #include #include #define MAX_MARSHEL_SIZE 20 /* * Authenticator operations routines */ static void authnone_verf(AUTH *); static void authnone_destroy(AUTH *); static bool_t authnone_marshal(AUTH *, XDR *); static bool_t authnone_validate(AUTH *, struct opaque_auth *); static bool_t authnone_refresh(AUTH *, struct rpc_msg *); static bool_t authnone_wrap(AUTH *, XDR *, xdrproc_t, caddr_t); static struct auth_ops ops = { authnone_verf, authnone_marshal, authnone_validate, authnone_refresh, authnone_destroy, authnone_wrap, authnone_wrap }; static struct authnone_private { AUTH no_client; char marshalled_client[MAX_MARSHEL_SIZE]; u_int mcnt; } *authnone_private; AUTH * authnone_create(void) { struct authnone_private *ap = authnone_private; XDR xdr_stream; XDR *xdrs; if (ap == 0) { ap = (struct authnone_private *)calloc(1, sizeof (*ap)); if (ap == 0) return (0); authnone_private = ap; } if (!ap->mcnt) { ap->no_client.ah_cred = ap->no_client.ah_verf = gssrpc__null_auth; ap->no_client.ah_ops = &ops; xdrs = &xdr_stream; xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE, XDR_ENCODE); (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred); (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf); ap->mcnt = XDR_GETPOS(xdrs); XDR_DESTROY(xdrs); } return (&ap->no_client); } /*ARGSUSED*/ static bool_t authnone_marshal(AUTH *client, XDR *xdrs) { struct authnone_private *ap = authnone_private; if (ap == 0) return (0); return ((*xdrs->x_ops->x_putbytes)(xdrs, ap->marshalled_client, ap->mcnt)); } /*ARGSUSED*/ static void authnone_verf(AUTH *auth) { } /*ARGSUSED*/ static bool_t authnone_validate(AUTH *auth, struct opaque_auth *verf) { return (TRUE); } /*ARGSUSED*/ static bool_t authnone_refresh(AUTH *auth, struct rpc_msg *msg) { return (FALSE); } /*ARGSUSED*/ static void authnone_destroy(AUTH *auth) { } static bool_t authnone_wrap(AUTH *auth, XDR *xdrs, xdrproc_t xfunc, caddr_t xwhere) { return ((*xfunc)(xdrs, xwhere)); } krb5-1.22.1/src/lib/rpc/svc_auth_none.c0000664000175000017500000000456115051422640017467 0ustar ghudsonghudson/* lib/rpc/svc_auth_none.c */ /* Copyright (c) 2000 The Regents of the University of Michigan. All rights reserved. Copyright (c) 2000 Dug Song . All rights reserved, all wrongs reversed. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Id: svc_auth_none.c,v 1.1 2000/08/24 20:51:34 dugsong Exp */ #include static bool_t svcauth_none_destroy(SVCAUTH *); static bool_t svcauth_none_wrap(SVCAUTH *, XDR *, xdrproc_t, caddr_t); struct svc_auth_ops svc_auth_none_ops = { svcauth_none_wrap, svcauth_none_wrap, svcauth_none_destroy }; SVCAUTH svc_auth_none = { &svc_auth_none_ops, NULL, }; static bool_t svcauth_none_destroy(SVCAUTH *auth) { return (TRUE); } static bool_t svcauth_none_wrap(SVCAUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { return ((*xdr_func)(xdrs, xdr_ptr)); } enum auth_stat gssrpc__svcauth_none(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch) { rqst->rq_xprt->xp_auth = &svc_auth_none; return (AUTH_OK); } krb5-1.22.1/src/lib/rpc/get_myaddress.c0000664000175000017500000000710015051422640017456 0ustar ghudsonghudson/* @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro"; #endif /* * get_myaddress.c * * Get client's IP address via ioctl. This avoids using the yellowpages. */ #ifdef GSSAPI_KRB5 #include #include #include #include #include #include #include /* * don't use gethostbyname, which would invoke yellow pages */ int get_myaddress(struct sockaddr_in *addr) { memset(addr, 0, sizeof(*addr)); addr->sin_family = AF_INET; addr->sin_port = htons(PMAPPORT); addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); return (0); } #else /* !GSSAPI_KRB5 */ #include #include #include #if defined(sun) #include #endif #include #ifdef OSF1 #include #include #endif #include #include #include #include /* * don't use gethostbyname, which would invoke yellow pages */ get_myaddress(struct sockaddr_in *addr) { int s; char buf[256 * sizeof (struct ifreq)]; struct ifconf ifc; struct ifreq ifreq, *ifr; int len; if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("get_myaddress: socket"); exit(1); } set_cloexec_fd(s); ifc.ifc_len = sizeof (buf); ifc.ifc_buf = buf; if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { perror("get_myaddress: ioctl (get interface configuration)"); exit(1); } ifr = ifc.ifc_req; for (len = ifc.ifc_len; len; len -= sizeof ifreq) { ifreq = *ifr; if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { perror("get_myaddress: ioctl"); exit(1); } if ((ifreq.ifr_flags & IFF_UP) && ifr->ifr_addr.sa_family == AF_INET) { *addr = *((struct sockaddr_in *)&ifr->ifr_addr); addr->sin_port = htons(PMAPPORT); break; } ifr++; } (void) close(s); } #endif /* !GSSAPI_KRB5 */ krb5-1.22.1/src/lib/rpc/xdr_alloc.c0000664000175000017500000001011215051422640016570 0ustar ghudsonghudson/* lib/rpc/xdr_alloc.c */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. */ #include #include #include "dyn.h" static bool_t xdralloc_putlong(XDR *, long *); static bool_t xdralloc_putbytes(XDR *, caddr_t, unsigned int); static unsigned int xdralloc_getpos(XDR *); static rpc_inline_t * xdralloc_inline(XDR *, int); static void xdralloc_destroy(XDR *); static bool_t xdralloc_notsup_getlong(XDR *, long *); static bool_t xdralloc_notsup_getbytes(XDR *, caddr_t, unsigned int); static bool_t xdralloc_notsup_setpos(XDR *, unsigned int); static struct xdr_ops xdralloc_ops = { xdralloc_notsup_getlong, xdralloc_putlong, xdralloc_notsup_getbytes, xdralloc_putbytes, xdralloc_getpos, xdralloc_notsup_setpos, xdralloc_inline, xdralloc_destroy, }; /* * The procedure xdralloc_create initializes a stream descriptor for a * memory buffer. */ void xdralloc_create(XDR *xdrs, enum xdr_op op) { xdrs->x_op = op; xdrs->x_ops = &xdralloc_ops; xdrs->x_private = (caddr_t) DynCreate(sizeof(char), -4); /* not allowed to fail */ } caddr_t xdralloc_getdata(XDR *xdrs) { return (caddr_t) DynGet((DynObject) xdrs->x_private, 0); } void xdralloc_release(XDR *xdrs) { DynRelease((DynObject) xdrs->x_private); } static void xdralloc_destroy(XDR *xdrs) { DynDestroy((DynObject) xdrs->x_private); } static bool_t xdralloc_notsup_getlong( XDR *xdrs, long *lp) { return FALSE; } static bool_t xdralloc_putlong( XDR *xdrs, long *lp) { int l = htonl((uint32_t) *lp); /* XXX need bounds checking */ /* XXX assumes sizeof(int)==4 */ if (DynInsert((DynObject) xdrs->x_private, DynSize((DynObject) xdrs->x_private), &l, sizeof(int)) != DYN_OK) return FALSE; return (TRUE); } static bool_t xdralloc_notsup_getbytes( XDR *xdrs, caddr_t addr, unsigned int len) { return FALSE; } static bool_t xdralloc_putbytes( XDR *xdrs, caddr_t addr, unsigned int len) { if (DynInsert((DynObject) xdrs->x_private, DynSize((DynObject) xdrs->x_private), addr, (int) len) != DYN_OK) return FALSE; return TRUE; } static unsigned int xdralloc_getpos(XDR *xdrs) { return DynSize((DynObject) xdrs->x_private); } static bool_t xdralloc_notsup_setpos( XDR *xdrs, unsigned int lp) { return FALSE; } static rpc_inline_t *xdralloc_inline( XDR *xdrs, int len) { return (rpc_inline_t *) 0; } krb5-1.22.1/src/lib/rpc/dyntest.c0000664000175000017500000001267015051422640016326 0ustar ghudsonghudson/* * This file is a (rather silly) demonstration of the use of the * C Dynamic Object library. It is a also reasonably thorough test * of the library (except that it only tests it with one data size). * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. * * 2002-07-17 Moved here from util/dyn/test.c. Older changes described * at end of file; for newer changes see ChangeLog. */ #include #include #ifdef USE_DBMALLOC #include #include #endif #include #include "dyn.h" static char random_string[] = "This is a random string."; static char insert1[] = "This will be put at the beginning."; static char insert2[] = "(parenthetical remark!) "; static char insert3[] = " This follows the random string."; int main(argc, argv) /*@unused@*/int argc; /*@unused@*/char **argv; { /*@-exitarg@*/ DynObject obj; int i, s; char d, *data; #ifdef _DEBUG_MALLOC_INC union dbmalloptarg arg; unsigned long hist1, hist2, o_size, c_size; #endif #ifdef _DEBUG_MALLOC_INC arg.i = 0; dbmallopt(MALLOC_ZERO, &arg); dbmallopt(MALLOC_REUSE, &arg); o_size = malloc_inuse(&hist1); #endif /*@+matchanyintegral@*/ obj = DynCreate(sizeof(char), -8); if (! obj) { fprintf(stderr, "test: create failed.\n"); exit(1); } if(DynDebug(obj, 1) != DYN_OK) { fprintf(stderr, "test: setting paranoid failed.\n"); exit(1); } if(DynParanoid(obj, 1) != DYN_OK) { fprintf(stderr, "test: setting paranoid failed.\n"); exit(1); } if ((DynGet(obj, -5) != NULL) || (DynGet(obj, 0) != NULL) || (DynGet(obj, 1000) != NULL)) { fprintf(stderr, "test: Get did not fail when it should have.\n"); exit(1); } if (DynDelete(obj, -1) != DYN_BADINDEX || DynDelete(obj, 0) != DYN_BADINDEX || DynDelete(obj, 100) != DYN_BADINDEX) { fprintf(stderr, "test: Delete did not fail when it should have.\n"); exit(1); } printf("Size of empty object: %d\n", DynSize(obj)); for (i=0; i<14; i++) { d = (char) i; if (DynAdd(obj, &d) != DYN_OK) { fprintf(stderr, "test: Adding %d failed.\n", i); exit(1); } } if (DynAppend(obj, random_string, strlen(random_string)+1) != DYN_OK) { fprintf(stderr, "test: appending array failed.\n"); exit(1); } if (DynDelete(obj, DynHigh(obj) / 2) != DYN_OK) { fprintf(stderr, "test: deleting element failed.\n"); exit(1); } if (DynDelete(obj, DynHigh(obj) * 2) == DYN_OK) { fprintf(stderr, "test: delete should have failed here.\n"); exit(1); } d = '\200'; if (DynAdd(obj, &d) != DYN_OK) { fprintf(stderr, "test: Adding %d failed.\n", i); exit(1); } data = (char *) DynGet(obj, 0); if(data == NULL) { fprintf(stderr, "test: getting object 0 failed.\n"); exit(1); } s = DynSize(obj); for (i=0; i < s; i++) printf("Element %d is %d.\n", i, (int) data[i]); data = (char *) DynGet(obj, 13); if(data == NULL) { fprintf(stderr, "test: getting element 13 failed.\n"); exit(1); } printf("Element 13 is %d.\n", (int) *data); data = (char *) DynGet(obj, DynSize(obj)); if (data) { fprintf(stderr, "DynGet did not return NULL when it should have.\n"); exit(1); } data = DynGet(obj, 14); if(data == NULL) { fprintf(stderr, "test: getting element 13 failed.\n"); exit(1); } printf("This should be the random string: \"%s\"\n", data); if (DynInsert(obj, -1, "foo", 4) != DYN_BADINDEX || DynInsert(obj, DynSize(obj) + 1, "foo", 4) != DYN_BADINDEX || DynInsert(obj, 0, "foo", -1) != DYN_BADVALUE) { fprintf(stderr, "DynInsert did not fail when it should have.\n"); exit(1); } if (DynInsert(obj, DynSize(obj) - 2, insert3, strlen(insert3) + 1) != DYN_OK) { fprintf(stderr, "DynInsert to end failed.\n"); exit(1); } if (DynInsert(obj, 19, insert2, strlen(insert2)) != DYN_OK) { fprintf(stderr, "DynInsert to middle failed.\n"); exit(1); } if (DynInsert(obj, 0, insert1, strlen(insert1)+1) != DYN_OK) { fprintf(stderr, "DynInsert to start failed.\n"); exit(1); } data = DynGet(obj, 14 + strlen(insert1) + 1); if (data == NULL) { fprintf(stderr, "DynGet of 14+strelen(insert1) failed.\n"); exit(1); } printf("A new random string: \"%s\"\n", data); data = DynGet(obj, 0); if (data == NULL) { fprintf(stderr, "DynGet of 0 failed.\n"); exit(1); } printf("This was put at the beginning: \"%s\"\n", data); if(DynDestroy(obj) != DYN_OK) { fprintf(stderr, "test: destroy failed.\n"); exit(1); } #ifdef _DEBUG_MALLOC_INC c_size = malloc_inuse(&hist2); if (o_size != c_size) { printf("\n\nIgnore a single unfreed malloc segment " "(stdout buffer).\n\n"); malloc_list(2, hist1, hist2); } #endif printf("All tests pass\n"); return 0; } /* Old change log, as it relates to source code; build system stuff discarded. 2001-04-25 Ezra Peisach * test.c: Always include stdlib.h * test.c: Check the return values of all library calls. 2000-11-09 Ezra Peisach * test.c: Include string,h, stdlib.h. */ krb5-1.22.1/src/lib/rpc/svc_auth_unix.c0000664000175000017500000001070015051422640017503 0ustar ghudsonghudson/* @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC; from 1.28 88/02/08 SMI */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro"; #endif /* * svc_auth_unix.c * Handles UNIX flavor authentication parameters on the service side of rpc. * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT. * _svcauth_unix does full blown unix style uid,gid+gids auth, * _svcauth_short uses a shorthand auth to index into a cache of longhand auths. * Note: the shorthand has been gutted for efficiency. */ #include #include #include /* * Unix longhand authenticator */ enum auth_stat gssrpc__svcauth_unix( struct svc_req *rqst, struct rpc_msg *msg, bool_t *dispatch) { enum auth_stat stat; XDR xdrs; struct authunix_parms *aup; rpc_inline_t *buf; struct area { struct authunix_parms area_aup; char area_machname[MAX_MACHINE_NAME+1]; int area_gids[NGRPS]; } *area; u_int auth_len, str_len, gid_len, i; rqst->rq_xprt->xp_auth = &svc_auth_none; area = (struct area *) rqst->rq_clntcred; aup = &area->area_aup; aup->aup_machname = area->area_machname; aup->aup_gids = area->area_gids; auth_len = msg->rm_call.cb_cred.oa_length; if (auth_len > INT_MAX) return AUTH_BADCRED; xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE); buf = XDR_INLINE(&xdrs, (int)auth_len); if (buf != NULL) { aup->aup_time = IXDR_GET_LONG(buf); str_len = IXDR_GET_U_LONG(buf); if (str_len > MAX_MACHINE_NAME) { stat = AUTH_BADCRED; goto done; } memmove(aup->aup_machname, buf, str_len); aup->aup_machname[str_len] = 0; str_len = RNDUP(str_len); buf += str_len / BYTES_PER_XDR_UNIT; aup->aup_uid = IXDR_GET_LONG(buf); aup->aup_gid = IXDR_GET_LONG(buf); gid_len = IXDR_GET_U_LONG(buf); if (gid_len > NGRPS) { stat = AUTH_BADCRED; goto done; } aup->aup_len = gid_len; for (i = 0; i < gid_len; i++) { aup->aup_gids[i] = IXDR_GET_LONG(buf); } /* * five is the smallest unix credentials structure - * timestamp, hostname len (0), uid, gid, and gids len (0). */ if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) { (void) printf("bad auth_len gid %u str %u auth %u\n", gid_len, str_len, auth_len); stat = AUTH_BADCRED; goto done; } } else if (! xdr_authunix_parms(&xdrs, aup)) { xdrs.x_op = XDR_FREE; (void)xdr_authunix_parms(&xdrs, aup); stat = AUTH_BADCRED; goto done; } rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL; rqst->rq_xprt->xp_verf.oa_length = 0; stat = AUTH_OK; done: XDR_DESTROY(&xdrs); return (stat); } /* * Shorthand unix authenticator * Looks up longhand in a cache. */ /*ARGSUSED*/ enum auth_stat gssrpc__svcauth_short( struct svc_req *rqst, struct rpc_msg *msg, bool_t *dispatch) { rqst->rq_xprt->xp_auth = &svc_auth_none; return (AUTH_REJECTEDCRED); } krb5-1.22.1/src/lib/rpc/pmap_clnt.c0000664000175000017500000001201715051422640016604 0ustar ghudsonghudson/* @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro"; #endif /* * pmap_clnt.c * Client interface to pmap rpc service. */ #include #include #include #include #if TARGET_OS_MAC #include #include #include #endif static struct timeval timeout = { 5, 0 }; static struct timeval tottimeout = { 60, 0 }; /* * Set a mapping between program,version and port. * Calls the pmap service remotely to do the mapping. */ bool_t pmap_set( rpcprog_t program, rpcvers_t version, rpcprot_t protocol, u_int port) { struct sockaddr_in myaddress; int sock = -1; CLIENT *client; struct pmap parms; bool_t rslt; get_myaddress(&myaddress); client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); if (client == (CLIENT *)NULL) return (FALSE); parms.pm_prog = program; parms.pm_vers = version; parms.pm_prot = protocol; parms.pm_port = port; #if TARGET_OS_MAC { /* * Poke launchd, then wait for portmap to start up. * * My impression is that the protocol involves getting * something back from the server. So wait, briefly, to * see if it's going to send us something. Then continue * on, regardless. I don't actually check what the data * is, because I have no idea what sort of validation, if * any, is needed. * * However, for whatever reason, the socket seems to be * mode 700 owner root on my system, so if you don't * change its ownership or mode, and if the program isn't * running as root, you still lose. */ #define TICKLER_SOCKET "/var/run/portmap.socket" int tickle; struct sockaddr_un a = { .sun_family = AF_UNIX, .sun_path = TICKLER_SOCKET, .sun_len = (sizeof(TICKLER_SOCKET) + offsetof(struct sockaddr_un, sun_path)), }; if (sizeof(TICKLER_SOCKET) <= sizeof(a.sun_path)) { tickle = socket(AF_UNIX, SOCK_STREAM, 0); if (tickle >= 0) { if (connect(tickle, (struct sockaddr *)&a, a.sun_len) == 0 && tickle < FD_SETSIZE) { fd_set readfds; struct timeval tv; FD_ZERO(&readfds); /* XXX Range check. */ FD_SET(tickle, &readfds); tv.tv_sec = 5; tv.tv_usec = 0; (void) select(tickle+1, &readfds, 0, 0, &tv); } close(tickle); } } } #endif if (CLNT_CALL(client, PMAPPROC_SET, (xdrproc_t)xdr_pmap, &parms, (xdrproc_t)xdr_bool, &rslt, tottimeout) != RPC_SUCCESS) { clnt_perror(client, "Cannot register service"); return (FALSE); } CLNT_DESTROY(client); (void)close(sock); return (rslt); } /* * Remove the mapping between program,version and port. * Calls the pmap service remotely to do the un-mapping. */ bool_t pmap_unset( rpcprog_t program, rpcvers_t version) { struct sockaddr_in myaddress; int sock = -1; CLIENT *client; struct pmap parms; bool_t rslt; get_myaddress(&myaddress); client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); if (client == (CLIENT *)NULL) return (FALSE); parms.pm_prog = program; parms.pm_vers = version; parms.pm_port = parms.pm_prot = 0; CLNT_CALL(client, PMAPPROC_UNSET, (xdrproc_t)xdr_pmap, &parms, (xdrproc_t)xdr_bool, &rslt, tottimeout); CLNT_DESTROY(client); (void)close(sock); return (rslt); } krb5-1.22.1/src/lib/rpc/pmap_prot2.c0000664000175000017500000001001315051422640016704 0ustar ghudsonghudson/* @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro"; #endif /* * pmap_prot2.c * Protocol for the local binder service, or pmap. */ #include #include #include /* * What is going on with linked lists? (!) * First recall the link list declaration from pmap_prot.h: * * struct pmaplist { * struct pmap pml_map; * struct pmaplist *pml_map; * }; * * Compare that declaration with a corresponding xdr declaration that * is (a) pointer-less, and (b) recursive: * * typedef union switch (bool_t) { * * case TRUE: struct { * struct pmap; * pmaplist_t foo; * }; * * case FALSE: struct {}; * } pmaplist_t; * * Notice that the xdr declaration has no nxt pointer while * the C declaration has no bool_t variable. The bool_t can be * interpreted as ``more data follows me''; if FALSE then nothing * follows this bool_t; if TRUE then the bool_t is followed by * an actual struct pmap, and then (recursively) by the * xdr union, pamplist_t. * * This could be implemented via the xdr_union primitive, though this * would cause a one recursive call per element in the list. Rather than do * that we can ``unwind'' the recursion * into a while loop and do the union arms in-place. * * The head of the list is what the C programmer wishes to past around * the net, yet is the data that the pointer points to which is interesting; * this sounds like a job for xdr_reference! */ bool_t xdr_pmaplist(XDR *xdrs, struct pmaplist **rp) { /* * more_elements is pre-computed in case the direction is * XDR_ENCODE or XDR_FREE. more_elements is overwritten by * xdr_bool when the direction is XDR_DECODE. */ bool_t more_elements; int freeing = (xdrs->x_op == XDR_FREE); struct pmaplist **next = NULL; while (TRUE) { more_elements = (bool_t)(*rp != NULL); if (! xdr_bool(xdrs, &more_elements)) return (FALSE); if (! more_elements) return (TRUE); /* we are done */ /* * the unfortunate side effect of non-recursion is that in * the case of freeing we must remember the next object * before we free the current object ... */ if (freeing) next = &((*rp)->pml_next); if (! xdr_reference(xdrs, (caddr_t *)rp, (u_int)sizeof(struct pmaplist), (xdrproc_t)xdr_pmap)) return (FALSE); rp = (freeing) ? next : &((*rp)->pml_next); } } krb5-1.22.1/src/lib/rpc/clnt_simple.c0000664000175000017500000000770715051422640017152 0ustar ghudsonghudson/* @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro"; #endif /* * clnt_simple.c * Simplified front end to rpc. */ #include "autoconf.h" #include /* for close() */ #include #include #include #include #include #include static struct callrpc_private { CLIENT *client; SOCKET socket; rpcprog_t oldprognum; rpcvers_t oldversnum; int valid; char *oldhost; } *callrpc_private; int callrpc( char *host, rpcprog_t prognum, rpcvers_t versnum, rpcproc_t procnum, xdrproc_t inproc, char *in, xdrproc_t outproc, char *out) { struct callrpc_private *crp = callrpc_private; struct sockaddr_in server_addr; enum clnt_stat clnt_stat; struct hostent *hp; struct timeval timeout, tottimeout; if (crp == 0) { crp = (struct callrpc_private *)calloc(1, sizeof (*crp)); if (crp == 0) return (0); callrpc_private = crp; } if (crp->oldhost == NULL) { crp->oldhost = mem_alloc(256); if (crp->oldhost == 0) return 0; crp->oldhost[0] = 0; crp->socket = RPC_ANYSOCK; } if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum && strcmp(crp->oldhost, host) == 0) { /* reuse old client */ } else { crp->valid = 0; (void)closesocket(crp->socket); crp->socket = RPC_ANYSOCK; if (crp->client) { clnt_destroy(crp->client); crp->client = NULL; } if ((hp = gethostbyname(host)) == NULL) return ((int) RPC_UNKNOWNHOST); timeout.tv_usec = 0; timeout.tv_sec = 5; memset(&server_addr, 0, sizeof(server_addr)); memmove((char *)&server_addr.sin_addr, hp->h_addr, sizeof(server_addr.sin_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = 0; if ((crp->client = clntudp_create(&server_addr, prognum, versnum, timeout, &crp->socket)) == NULL) return ((int) rpc_createerr.cf_stat); crp->valid = 1; crp->oldprognum = prognum; crp->oldversnum = versnum; (void) strncpy(crp->oldhost, host, 255); crp->oldhost[255] = '\0'; } tottimeout.tv_sec = 25; tottimeout.tv_usec = 0; clnt_stat = clnt_call(crp->client, procnum, inproc, in, outproc, out, tottimeout); /* * if call failed, empty cache */ if (clnt_stat != RPC_SUCCESS) crp->valid = 0; return ((int) clnt_stat); } krb5-1.22.1/src/lib/rpc/rpc_callmsg.c0000664000175000017500000001403215051422640017114 0ustar ghudsonghudson/* @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro"; #endif /* * rpc_callmsg.c */ #include #include #include /* * XDR a call message */ bool_t xdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg) { rpc_inline_t *buf; struct opaque_auth *oa; if (xdrs->x_op == XDR_ENCODE) { if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { return (FALSE); } if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { return (FALSE); } buf = (rpc_inline_t *) XDR_INLINE(xdrs, (int) ( 8 * BYTES_PER_XDR_UNIT + RNDUP(cmsg->rm_call.cb_cred.oa_length) + 2 * BYTES_PER_XDR_UNIT + RNDUP(cmsg->rm_call.cb_verf.oa_length))); if (buf != NULL) { IXDR_PUT_LONG(buf, cmsg->rm_xid); IXDR_PUT_ENUM(buf, cmsg->rm_direction); if (cmsg->rm_direction != CALL) { return (FALSE); } IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers); if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { return (FALSE); } IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog); IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers); IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc); oa = &cmsg->rm_call.cb_cred; IXDR_PUT_ENUM(buf, oa->oa_flavor); IXDR_PUT_LONG(buf, oa->oa_length); if (oa->oa_length) { memmove((caddr_t)buf, oa->oa_base, oa->oa_length); buf += RNDUP(oa->oa_length) / BYTES_PER_XDR_UNIT; } oa = &cmsg->rm_call.cb_verf; IXDR_PUT_ENUM(buf, oa->oa_flavor); IXDR_PUT_LONG(buf, oa->oa_length); if (oa->oa_length) { memmove((caddr_t)buf, oa->oa_base, oa->oa_length); /* no real need.... buf += RNDUP(oa->oa_length) / BYTES_PER_XDR_UNIT; */ } return (TRUE); } } if (xdrs->x_op == XDR_DECODE) { buf = (rpc_inline_t *) XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); if (buf != NULL) { cmsg->rm_xid = IXDR_GET_LONG(buf); cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); if (cmsg->rm_direction != CALL) { return (FALSE); } cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf); if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { return (FALSE); } cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf); cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf); cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf); oa = &cmsg->rm_call.cb_cred; oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); oa->oa_length = IXDR_GET_LONG(buf); if (oa->oa_length) { if (oa->oa_length > MAX_AUTH_BYTES) { return (FALSE); } if (oa->oa_base == NULL) { oa->oa_base = (caddr_t) mem_alloc(oa->oa_length); } buf = (rpc_inline_t *) XDR_INLINE(xdrs, (int)RNDUP(oa->oa_length)); if (buf == NULL) { if (xdr_opaque(xdrs, oa->oa_base, oa->oa_length) == FALSE) { return (FALSE); } } else { memmove(oa->oa_base, (caddr_t)buf, oa->oa_length); /* no real need.... buf += RNDUP(oa->oa_length) / BYTES_PER_XDR_UNIT; */ } } oa = &cmsg->rm_call.cb_verf; buf = (rpc_inline_t *) XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); if (buf == NULL) { if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || xdr_u_int(xdrs, &oa->oa_length) == FALSE) { return (FALSE); } } else { oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); oa->oa_length = IXDR_GET_LONG(buf); } if (oa->oa_length) { if (oa->oa_length > MAX_AUTH_BYTES) { return (FALSE); } if (oa->oa_base == NULL) { oa->oa_base = (caddr_t) mem_alloc(oa->oa_length); } buf = (rpc_inline_t *) XDR_INLINE(xdrs, (int)RNDUP(oa->oa_length)); if (buf == NULL) { if (xdr_opaque(xdrs, oa->oa_base, oa->oa_length) == FALSE) { return (FALSE); } } else { memmove(oa->oa_base, (caddr_t) buf, oa->oa_length); /* no real need... buf += RNDUP(oa->oa_length) / BYTES_PER_XDR_UNIT; */ } } return (TRUE); } } if ( xdr_u_int32(xdrs, &(cmsg->rm_xid)) && xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && (cmsg->rm_direction == CALL) && xdr_u_int32(xdrs, &(cmsg->rm_call.cb_rpcvers)) && (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && xdr_u_int32(xdrs, &(cmsg->rm_call.cb_prog)) && xdr_u_int32(xdrs, &(cmsg->rm_call.cb_vers)) && xdr_u_int32(xdrs, &(cmsg->rm_call.cb_proc)) && xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) ) return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf))); return (FALSE); } krb5-1.22.1/src/lib/rpc/unit-test/0000775000175000017500000000000015051422640016416 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/rpc/unit-test/Makefile.in0000664000175000017500000000216315051422640020465 0ustar ghudsonghudsonmydir=lib$(S)rpc$(S)unit-test BUILDTOP=$(REL)..$(S)..$(S).. OBJS= client.o rpc_test_clnt.o rpc_test_svc.o server.o SRCS= client.c rpc_test_clnt.c rpc_test_svc.c server.c all: client server client: client.o rpc_test_clnt.o $(GSSRPC_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o client client.o rpc_test_clnt.o \ $(GSSRPC_LIBS) $(KRB5_BASE_LIBS) server: server.o rpc_test_svc.o $(GSSRPC_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o server server.o rpc_test_svc.o \ $(GSSRPC_LIBS) $(KRB5_BASE_LIBS) client.o server.o: rpc_test.h # If rpc_test.h and rpc_test_*.c do not work on your system, you can # try using rpcgen by uncommenting these lines (be sure to uncomment # then in the generated not Makefile.in). # rpc_test.h rpc_test_clnt.c rpc_test_svc.c: rpc_test.x # -rm -f rpc_test_clnt.c rpc_test_svc.c rpc_test.h # -ln -s $(srcdir)/rpc_test.x . # rpcgen -l rpc_test.x -o rpc_test_clnt.c # rpcgen -m rpc_test.x -o rpc_test_svc.c # rpcgen -h rpc_test.x -o rpc_test.h # # clean: # rm -f rpc_test.h rpc_test_clnt.c rpc_test_svc.c # check-pytests: $(RUNPYTEST) $(srcdir)/t_rpc.py $(PYTESTFLAGS) clean: $(RM) server client krb5-1.22.1/src/lib/rpc/unit-test/rpc_test.x0000664000175000017500000000156115051422640020435 0ustar ghudsonghudson/* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. * * $Id$ * $Source$ * * $Log$ * Revision 1.2 1996/07/22 20:41:42 marc * this commit includes all the changes on the OV_9510_INTEGRATION and * OV_MERGE branches. This includes, but is not limited to, the new openvision * admin system, and major changes to gssapi to add functionality, and bring * the implementation in line with rfc1964. before committing, the * code was built and tested for netbsd and solaris. * * Revision 1.1.4.1 1996/07/18 04:20:04 marc * merged in changes from OV_9510_BP to OV_9510_FINAL1 * # Revision 1.1.2.1 1996/06/20 23:42:06 marc # File added to the repository on a branch # # Revision 1.1 1993/11/03 23:53:58 bjaspan # Initial revision # */ program RPC_TEST_PROG { version RPC_TEST_VERS_1 { string RPC_TEST_ECHO(string) = 1; } = 1; } = 1000001; krb5-1.22.1/src/lib/rpc/unit-test/client.c0000664000175000017500000001565715051422640020056 0ustar ghudsonghudson/* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. * * $Id$ * */ #include "autoconf.h" #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include "rpc_test.h" #define BIG_BUF 4096 /* copied from auth_gssapi.c for hackery */ struct auth_gssapi_data { bool_t established; CLIENT *clnt; gss_ctx_id_t context; gss_buffer_desc client_handle; OM_uint32 seq_num; int def_cred; /* pre-serialized ah_cred */ u_char cred_buf[MAX_AUTH_BYTES]; int32_t cred_len; }; #define AUTH_PRIVATE(auth) ((struct auth_gssapi_data *)auth->ah_private) extern int auth_debug_gssapi; char *whoami; #ifdef __GNUC__ __attribute__((noreturn)) #endif static void usage(void) { fprintf(stderr, "usage: %s {-t|-u} [-a] [-s num] [-m num] host service [count]\n", whoami); exit(1); } int main(int argc, char **argv) { char *host, *port, *target, *echo_arg, **echo_resp, buf[BIG_BUF]; CLIENT *clnt; AUTH *tmp_auth; struct rpc_err e; int auth_once, sock, use_tcp; unsigned int count, i; extern int optind; extern char *optarg; extern int svc_debug_gssapi, misc_debug_gssapi, auth_debug_gssapi; int c; struct sockaddr_in sin; struct hostent *h; struct timeval tv; extern int krb5_gss_dbg_client_expcreds; krb5_gss_dbg_client_expcreds = 1; whoami = argv[0]; count = 1026; auth_once = 0; use_tcp = -1; while ((c = getopt(argc, argv, "a:m:os:tu")) != -1) { switch (c) { case 'a': auth_debug_gssapi = atoi(optarg); break; case 'm': misc_debug_gssapi = atoi(optarg); break; case 'o': auth_once++; break; case 's': svc_debug_gssapi = atoi(optarg); break; case 't': use_tcp = 1; break; case 'u': use_tcp = 0; break; case '?': usage(); break; } } if (use_tcp == -1) usage(); argv += optind; argc -= optind; switch (argc) { case 4: count = atoi(argv[3]); if (count > BIG_BUF-1) { fprintf(stderr, "Test count cannot exceed %d.\n", BIG_BUF-1); usage(); } case 3: host = argv[0]; port = argv[1]; target = argv[2]; break; default: usage(); } /* get server address */ h = gethostbyname(host); if (h == NULL) { fprintf(stderr, "Can't resolve hostname %s\n", host); exit(1); } memset(&sin, 0, sizeof(sin)); sin.sin_family = h->h_addrtype; sin.sin_port = ntohs(atoi(port)); memmove(&sin.sin_addr, h->h_addr, sizeof(sin.sin_addr)); /* client handle to rstat */ sock = RPC_ANYSOCK; if (use_tcp) { clnt = clnttcp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, &sock, 0, 0); } else { tv.tv_sec = 5; tv.tv_usec = 0; clnt = clntudp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, tv, &sock); } if (clnt == NULL) { clnt_pcreateerror(whoami); exit(1); } clnt->cl_auth = auth_gssapi_create_default(clnt, target); if (clnt->cl_auth == NULL) { clnt_pcreateerror(whoami); exit(2); } /* * Call the echo service multiple times. */ echo_arg = buf; for (i = 0; i < 3; i++) { snprintf(buf, sizeof(buf), "testing %d\n", i); echo_resp = rpc_test_echo_1(&echo_arg, clnt); if (echo_resp == NULL) { fprintf(stderr, "RPC_TEST_ECHO call %d%s", i, clnt_sperror(clnt, "")); break; } if (strncmp(*echo_resp, "Echo: ", 6) && strcmp(echo_arg, (*echo_resp) + 6) != 0) fprintf(stderr, "RPC_TEST_ECHO call %d response wrong: " "arg = %s, resp = %s\n", i, echo_arg, *echo_resp); gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp); } /* * Make a call with an invalid verifier and check for error; * server should log error message. It is important to *increment* seq_num here, since a decrement would be fixed (see * below). Note that seq_num will be incremented (by * authg_gssapi_refresh) twice, so we need to decrement by three * to reset. */ AUTH_PRIVATE(clnt->cl_auth)->seq_num++; echo_arg = "testing with bad verf"; echo_resp = rpc_test_echo_1(&echo_arg, clnt); if (echo_resp == NULL) { CLNT_GETERR(clnt, &e); if (e.re_status != RPC_AUTHERROR || e.re_why != AUTH_REJECTEDVERF) clnt_perror(clnt, whoami); } else { fprintf(stderr, "bad seq didn't cause failure\n"); gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp); } AUTH_PRIVATE(clnt->cl_auth)->seq_num -= 3; /* * Make sure we're resyncronized. */ echo_arg = "testing for reset"; echo_resp = rpc_test_echo_1(&echo_arg, clnt); if (echo_resp == NULL) clnt_perror(clnt, "Sequence number improperly reset"); else gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp); /* * Now simulate a lost server response, and see if * auth_gssapi_refresh recovers. */ AUTH_PRIVATE(clnt->cl_auth)->seq_num--; echo_arg = "forcing auto-resynchronization"; echo_resp = rpc_test_echo_1(&echo_arg, clnt); if (echo_resp == NULL) clnt_perror(clnt, "Auto-resynchronization failed"); else gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp); /* * Now make sure auto-resyncrhonization actually worked */ echo_arg = "testing for resynchronization"; echo_resp = rpc_test_echo_1(&echo_arg, clnt); if (echo_resp == NULL) clnt_perror(clnt, "Auto-resynchronization did not work"); else gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp); if (! auth_once) { tmp_auth = clnt->cl_auth; clnt->cl_auth = auth_gssapi_create_default(clnt, target); if (clnt->cl_auth == NULL) { clnt_pcreateerror(whoami); exit(2); } AUTH_DESTROY(clnt->cl_auth); clnt->cl_auth = tmp_auth; } /* * Try RPC calls with argument/result lengths [0, 1025]. Do * this last, since it takes a while.. */ echo_arg = buf; memset(buf, 0, count+1); for (i = 0; i < count; i++) { echo_resp = rpc_test_echo_1(&echo_arg, clnt); if (echo_resp == NULL) { fprintf(stderr, "RPC_TEST_LENGTHS call %d%s", i, clnt_sperror(clnt, "")); break; } else { if (strncmp(*echo_resp, "Echo: ", 6) && strcmp(echo_arg, (*echo_resp) + 6) != 0) fprintf(stderr, "RPC_TEST_LENGTHS call %d response wrong\n", i); gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp); } /* cycle from 1 to 255 */ buf[i] = (i % 255) + 1; if (i % 100 == 0) { fputc('.', stdout); fflush(stdout); } } fputc('\n', stdout); AUTH_DESTROY(clnt->cl_auth); CLNT_DESTROY(clnt); exit(0); } krb5-1.22.1/src/lib/rpc/unit-test/deps0000664000175000017500000000510115051422640017271 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)client.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_ext.h \ $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_gssapi.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/krb5.h client.c rpc_test.h $(OUTPRE)rpc_test_clnt.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h rpc_test.h rpc_test_clnt.c $(OUTPRE)rpc_test_svc.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h rpc_test.h rpc_test_svc.c $(OUTPRE)server.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(BUILDTOP)/include/gssrpc/types.h $(top_srcdir)/include/gssrpc/auth.h \ $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_gssapi.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/pmap_clnt.h $(top_srcdir)/include/gssrpc/rename.h \ $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-thread.h rpc_test.h server.c krb5-1.22.1/src/lib/rpc/unit-test/server.c0000664000175000017500000001470015051422640020072 0ustar ghudsonghudson/* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. * * $Id$ * $Source$ */ #include "k5-platform.h" #include #include #include "autoconf.h" #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include /* inet_ntoa */ #include #include #include #include /* MAXHOSTNAMELEN */ #include "rpc_test.h" extern int svc_debug_gssapi, misc_debug_gssapi; void rpc_test_badauth(OM_uint32 major, OM_uint32 minor, struct sockaddr_in *addr, caddr_t data); void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg, char *error, char *data); void log_badauth_display_status(OM_uint32 major, OM_uint32 minor); void log_badauth_display_status_1(OM_uint32 code, int type, int rec); static void rpc_test_badverf(gss_name_t client, gss_name_t server, struct svc_req *rqst, struct rpc_msg *msg, caddr_t data); #ifndef SERVICE_NAME #define SERVICE_NAME "host" #endif static void usage(void) { fprintf(stderr, "Usage: server {-t|-u} [svc-debug] [misc-debug]\n"); exit(1); } #ifdef POSIX_SIGNALS static void handlesig(int dummy) #else static void handlesig(void) #endif { exit(0); } int main(int argc, char **argv) { int c, prot; auth_gssapi_name names[2]; SVCXPRT *transp; extern int optind; #ifdef POSIX_SIGNALS struct sigaction sa; #endif names[0].name = SERVICE_NAME; names[0].type = (gss_OID) gss_nt_service_name; names[1].name = 0; names[1].type = 0; prot = 0; while ((c = getopt(argc, argv, "tu")) != -1) { switch (c) { case 't': prot = IPPROTO_TCP; break; case 'u': prot = IPPROTO_UDP; break; case '?': usage(); break; } } if (prot == 0) usage(); argv += optind; argc -= optind; switch (argc) { case 2: misc_debug_gssapi = atoi(argv[1]); case 1: svc_debug_gssapi = atoi(argv[0]); case 0: break; default: usage(); exit(1); } (void) pmap_unset(RPC_TEST_PROG, RPC_TEST_VERS_1); if (prot == IPPROTO_TCP) transp = svctcp_create(RPC_ANYSOCK, 0, 0); else transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { fprintf(stderr, "cannot create tcp service."); exit(1); } if (!svc_register(transp, RPC_TEST_PROG, RPC_TEST_VERS_1, rpc_test_prog_1_svc, 0)) { fprintf(stderr, "unable to register (RPC_TEST_PROG, RPC_TEST_VERS_1, %s).", prot == IPPROTO_TCP ? "tcp" : "udp"); exit(1); } if (svcauth_gssapi_set_names(names, 0) == FALSE) { fprintf(stderr, "unable to set gssapi names\n"); exit(1); } svcauth_gssapi_set_log_badauth_func(rpc_test_badauth, NULL); svcauth_gssapi_set_log_badverf_func(rpc_test_badverf, NULL); svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL); #ifdef POSIX_SIGNALS (void) sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = handlesig; (void) sigaction(SIGHUP, &sa, NULL); (void) sigaction(SIGINT, &sa, NULL); (void) sigaction(SIGTERM, &sa, NULL); #else signal(SIGHUP, handlesig); signal(SIGINT, handlesig); signal(SIGTERM, handlesig); #endif printf("running\n"); printf("port: %d\n", (int)transp->xp_port); fflush(stdout); svc_run(); fprintf(stderr, "svc_run returned"); exit(1); /* NOTREACHED */ } char **rpc_test_echo_1_svc(char **arg, struct svc_req *h) { static char *res = NULL; if (res) free(res); asprintf(&res, "Echo: %s", *arg); return &res; } static void rpc_test_badverf(gss_name_t client, gss_name_t server, struct svc_req *rqst, struct rpc_msg *msg, caddr_t data) { OM_uint32 minor_stat; gss_OID type; gss_buffer_desc client_name, server_name; (void) gss_display_name(&minor_stat, client, &client_name, &type); (void) gss_display_name(&minor_stat, server, &server_name, &type); printf("rpc_test server: bad verifier from %.*s at %s:%d for %.*s\n", (int) client_name.length, (char *) client_name.value, inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr), ntohs(rqst->rq_xprt->xp_raddr.sin_port), (int) server_name.length, (char *) server_name.value); fflush(stdout); (void) gss_release_buffer(&minor_stat, &client_name); (void) gss_release_buffer(&minor_stat, &server_name); } /* * Function: log_badauth * * Purpose: Callback from GSS-API Sun RPC for authentication * failures/errors. * * Arguments: * major (r) GSS-API major status * minor (r) GSS-API minor status * addr (r) originating address * data (r) arbitrary data (NULL), not used * * Effects: * * Logs the GSS-API error to stdout. */ void rpc_test_badauth(OM_uint32 major, OM_uint32 minor, struct sockaddr_in *addr, caddr_t data) { char *a; /* Authentication attempt failed: , */ a = inet_ntoa(addr->sin_addr); printf("rpc_test server: Authentication attempt failed: %s", a); log_badauth_display_status(major, minor); printf("\n"); fflush(stdout); } void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg, char *error, char *data) { char *a; a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr); printf("Miscellaneous RPC error: %s, %s\n", a, error); fflush(stdout); } void log_badauth_display_status(OM_uint32 major, OM_uint32 minor) { log_badauth_display_status_1(major, GSS_C_GSS_CODE, 0); log_badauth_display_status_1(minor, GSS_C_MECH_CODE, 0); } void log_badauth_display_status_1(OM_uint32 code, int type, int rec) { OM_uint32 gssstat, minor_stat, msg_ctx; gss_buffer_desc msg; msg_ctx = 0; while (1) { gssstat = gss_display_status(&minor_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg); if (gssstat != GSS_S_COMPLETE) { if (!rec) { log_badauth_display_status_1(gssstat,GSS_C_GSS_CODE,1); log_badauth_display_status_1(minor_stat, GSS_C_MECH_CODE, 1); } else { printf("GSS-API authentication error %.*s: " "recursive failure!\n", (int) msg.length, (char *)msg.value); } fflush(stdout); return; } printf(", %.*s", (int) msg.length, (char *)msg.value); (void) gss_release_buffer(&minor_stat, &msg); if (!msg_ctx) break; } fflush(stdout); } krb5-1.22.1/src/lib/rpc/unit-test/rpc_test_clnt.c0000664000175000017500000000072615051422640021432 0ustar ghudsonghudson#include "rpc_test.h" #include /* Default timeout can be changed using clnt_control() */ static struct timeval TIMEOUT = { 25, 0 }; char ** rpc_test_echo_1(char **argp, CLIENT *clnt) { static char *clnt_res; memset(&clnt_res, 0, sizeof (clnt_res)); if (clnt_call(clnt, RPC_TEST_ECHO, (xdrproc_t) xdr_wrapstring, (caddr_t) argp, (xdrproc_t) xdr_wrapstring, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); } krb5-1.22.1/src/lib/rpc/unit-test/rpc_test_svc.c0000664000175000017500000000277315051422640021271 0ustar ghudsonghudson#include "rpc_test.h" #include #include #include /* getenv, exit */ #include #include /* States a server can be in wrt request */ #define _IDLE 0 #define _SERVED 1 static int _rpcsvcstate = _IDLE; /* Set when a request is serviced */ static int _rpcsvccount = 0; /* Number of requests being serviced */ void rpc_test_prog_1_svc(struct svc_req *rqstp, SVCXPRT *transp) { union { char *rpc_test_echo_1_arg; } argument; char *result; xdrproc_t xdr_argument, xdr_result; char *(*local)(char *, struct svc_req *); _rpcsvccount++; switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply(transp, xdr_void, (char *)NULL); _rpcsvccount--; _rpcsvcstate = _SERVED; return; case RPC_TEST_ECHO: xdr_argument = (xdrproc_t)xdr_wrapstring; xdr_result = (xdrproc_t)xdr_wrapstring; local = (char *(*)(char *, struct svc_req *)) rpc_test_echo_1_svc; break; default: svcerr_noproc(transp); _rpcsvccount--; _rpcsvcstate = _SERVED; return; } (void) memset(&argument, 0, sizeof (argument)); if (!svc_getargs(transp, xdr_argument, &argument)) { svcerr_decode(transp); _rpcsvccount--; _rpcsvcstate = _SERVED; return; } result = (*local)((char *)&argument, rqstp); if (result != NULL && !svc_sendreply(transp, xdr_result, result)) { svcerr_systemerr(transp); } if (!svc_freeargs(transp, xdr_argument, &argument)) { syslog(LOG_ERR, "unable to free arguments"); exit(1); } _rpcsvccount--; _rpcsvcstate = _SERVED; return; } krb5-1.22.1/src/lib/rpc/unit-test/rpc_test.h0000664000175000017500000000065315051422640020416 0ustar ghudsonghudson#ifndef _RPC_TEST_H_RPCGEN #define _RPC_TEST_H_RPCGEN #include #define RPC_TEST_PROG ((unsigned long)(1000001)) #define RPC_TEST_VERS_1 ((unsigned long)(1)) #define RPC_TEST_ECHO ((unsigned long)(1)) extern char ** rpc_test_echo_1_svc(char **, struct svc_req *); extern char ** rpc_test_echo_1(char **, CLIENT *); extern void rpc_test_prog_1_svc(struct svc_req *, SVCXPRT *); #endif /* !_RPC_TEST_H_RPCGEN */ krb5-1.22.1/src/lib/rpc/unit-test/t_rpc.py0000664000175000017500000000151015051422640020074 0ustar ghudsonghudsonimport re from k5test import * realm = K5Realm() server = realm.start_server(['./server', '-t'], 'running') line = server.stdout.readline() portstr = re.match(r'^port: (\d+)$', line).group(1) realm.run(['./client', '-t', hostname, portstr, 'host@' + hostname, '1026'], expected_msg='...........') for i in range(4): line = server.stdout.readline() if 'rpc_test server: bad verifier from user@KRBTEST.COM at ' not in line: fail('unexpected server message: ' + line) output(line) realm.addprinc('nokey/' + hostname) realm.run(['./client', '-t', hostname, portstr, 'nokey@' + hostname, '1026'], expected_code=2) line = server.stdout.readline() if 'rpc_test server: Authentication attempt failed: ' not in line: fail('unexpected server message: ' + line) success('gssrpc auth_gssapi tests') krb5-1.22.1/src/lib/rpc/svc_run.c0000664000175000017500000000440215051422640016305 0ustar ghudsonghudson/* lib/rpc/svc_run.c */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This is the rpc server side idle loop * Wait for input, call server program. */ #include #include extern int svc_maxfd; void svc_run(void) { #ifdef FD_SETSIZE fd_set readfds; #else int readfds; #endif /* def FD_SETSIZE */ for (;;) { #ifdef FD_SETSIZE readfds = svc_fdset; #else readfds = svc_fds; #endif /* def FD_SETSIZE */ switch (select(svc_maxfd + 1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0)) { case -1: if (errno == EINTR) { continue; } perror("svc_run: - select failed"); return; case 0: continue; default: svc_getreqset(&readfds); } } } krb5-1.22.1/src/lib/rpc/libgssrpc.exports0000664000175000017500000000642315051422640020105 0ustar ghudsonghudsongssrpc_auth_debug_gss gssrpc_auth_debug_gssapi gssrpc_auth_gssapi_create gssrpc_auth_gssapi_create_default gssrpc_auth_gssapi_display_status gssrpc_auth_gssapi_seal_seq gssrpc_auth_gssapi_unseal_seq gssrpc_auth_gssapi_unwrap_data gssrpc_auth_gssapi_wrap_data gssrpc_authgss_create gssrpc_authgss_create_default gssrpc_authgss_get_private_data gssrpc_authgss_service gssrpc_authnone_create gssrpc_authunix_create gssrpc_authunix_create_default gssrpc_bindresvport gssrpc_bindresvport_sa gssrpc_callrpc gssrpc_clnt_broadcast gssrpc_clnt_create gssrpc_clnt_pcreateerror gssrpc_clnt_perrno gssrpc_clnt_perror gssrpc_clnt_spcreateerror gssrpc_clnt_sperrno gssrpc_clnt_sperror gssrpc_clntraw_create gssrpc_clnttcp_create gssrpc_clntudp_bufcreate gssrpc_clntudp_create gssrpc_get_myaddress gssrpc_getrpcport gssrpc_log_debug gssrpc_log_hexdump gssrpc_log_status gssrpc_misc_debug_gss gssrpc_misc_debug_gssapi gssrpc_pmap_getmaps gssrpc_pmap_getport gssrpc_pmap_rmtcall gssrpc_pmap_set gssrpc_pmap_unset gssrpc_registerrpc gssrpc_rpc_createrr gssrpc_svc_auth_gss_ops gssrpc_svc_auth_gssapi_ops gssrpc_svc_auth_none gssrpc_svc_auth_none_ops gssrpc_svc_debug_gss gssrpc_svc_debug_gssapi gssrpc_svc_fdset gssrpc_svc_fdset_init gssrpc_svc_getreq gssrpc_svc_getreqset gssrpc_svc_maxfd gssrpc_svc_register gssrpc_svc_run gssrpc_svc_sendreply gssrpc_svc_unregister gssrpc_svcauth_gss_get_principal gssrpc_svcauth_gss_set_log_badauth_func gssrpc_svcauth_gss_set_log_badauth2_func gssrpc_svcauth_gss_set_log_badverf_func gssrpc_svcauth_gss_set_log_miscerr_func gssrpc_svcauth_gss_set_svc_name gssrpc_svcauth_gssapi_set_log_badauth_func gssrpc_svcauth_gssapi_set_log_badauth2_func gssrpc_svcauth_gssapi_set_log_badverf_func gssrpc_svcauth_gssapi_set_log_miscerr_func gssrpc_svcauth_gssapi_set_names gssrpc_svcauth_gssapi_unset_names gssrpc_svcerr_auth gssrpc_svcerr_decode gssrpc_svcerr_noproc gssrpc_svcerr_noprog gssrpc_svcerr_progvers gssrpc_svcerr_systemerr gssrpc_svcerr_weakauth gssrpc_svcfd_create gssrpc_svcraw_create gssrpc_svctcp_create gssrpc_svcudp_bufcreate gssrpc_svcudp_create gssrpc_svcudp_enablecache gssrpc_xdr_accepted_reply gssrpc_xdr_array gssrpc_xdr_authgssapi_creds gssrpc_xdr_authgssapi_init_arg gssrpc_xdr_authgssapi_init_res gssrpc_xdr_authunix_parms gssrpc_xdr_bool gssrpc_xdr_bytes gssrpc_xdr_callhdr gssrpc_xdr_callmsg gssrpc_xdr_char gssrpc_xdr_des_block gssrpc_xdr_enum gssrpc_xdr_free gssrpc_xdr_gss_buf gssrpc_xdr_int gssrpc_xdr_int32 gssrpc_xdr_long gssrpc_xdr_netobj gssrpc_xdr_opaque gssrpc_xdr_opaque_auth gssrpc_xdr_pmap gssrpc_xdr_pmaplist gssrpc_xdr_pointer gssrpc_xdr_reference gssrpc_xdr_rejected_reply gssrpc_xdr_replymsg gssrpc_xdr_rmtcall_args gssrpc_xdr_rmtcallres gssrpc_xdr_rpc_gss_buf gssrpc_xdr_rpc_gss_cred gssrpc_xdr_rpc_gss_data gssrpc_xdr_rpc_gss_init_args gssrpc_xdr_rpc_gss_init_res gssrpc_xdr_rpc_gss_unwrap_data gssrpc_xdr_rpc_gss_wrap_data gssrpc_xdr_short gssrpc_xdr_sizeof gssrpc_xdr_string gssrpc_xdr_u_char gssrpc_xdr_u_int gssrpc_xdr_u_int32 gssrpc_xdr_u_long gssrpc_xdr_u_short gssrpc_xdr_union gssrpc_xdr_vector gssrpc_xdr_void gssrpc_xdr_wrapstring gssrpc_xdralloc_create gssrpc_xdralloc_getdata gssrpc_xdralloc_release gssrpc_xdrmem_create gssrpc_xdrrec_create gssrpc_xdrrec_endofrecord gssrpc_xdrrec_eof gssrpc_xdrrec_skiprecord gssrpc_xdrstdio_create gssrpc_xprt_register gssrpc_xprt_unregister krb5-1.22.1/src/lib/rpc/bindresvport.c0000664000175000017500000000537515051422640017361 0ustar ghudsonghudson/* lib/rpc/bindresvport.c */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include "socket-utils.h" /* * Bind a socket to a privileged IP port */ int bindresvport_sa(int sd, struct sockaddr *sa) { int res; static short port; struct sockaddr_storage myaddr; socklen_t salen; int i; #define STARTPORT 600 #define ENDPORT (IPPORT_RESERVED - 1) #define NPORTS (ENDPORT - STARTPORT + 1) if (sa == NULL) { salen = sizeof(myaddr); sa = ss2sa(&myaddr); res = getsockname(sd, sa, &salen); if (res < 0) return (-1); } if (!sa_is_inet(sa)) { errno = EPFNOSUPPORT; return (-1); } if (port == 0) { port = (getpid() % NPORTS) + STARTPORT; } res = -1; errno = EADDRINUSE; for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) { sa_setport(sa, port++); if (port > ENDPORT) { port = STARTPORT; } res = bind(sd, sa, sa_socklen(sa)); } return (res); } int bindresvport(int sd, struct sockaddr_in *sockin) { return (bindresvport_sa(sd, (struct sockaddr *)sockin)); } krb5-1.22.1/src/lib/rpc/svc_raw.c0000664000175000017500000001067615051422640016304 0ustar ghudsonghudson/* @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro"; #endif /* * svc_raw.c, This a toy for simple testing and timing. * Interface to create an rpc client and server in the same UNIX process. * This lets us similate rpc and get rpc (round trip) overhead, without * any interference from the kernel. */ #include /* * This is the "network" that we will be moving data over */ static struct svcraw_private { char _raw_buf[UDPMSGSIZE]; SVCXPRT server; XDR xdr_stream; char verf_body[MAX_AUTH_BYTES]; } *svcraw_private; static bool_t svcraw_recv(SVCXPRT *, struct rpc_msg *); static enum xprt_stat svcraw_stat(SVCXPRT *); static bool_t svcraw_getargs(SVCXPRT *, xdrproc_t, void *); static bool_t svcraw_reply(SVCXPRT *, struct rpc_msg *); static bool_t svcraw_freeargs(SVCXPRT *, xdrproc_t, void *); static void svcraw_destroy(SVCXPRT *); static struct xp_ops server_ops = { svcraw_recv, svcraw_stat, svcraw_getargs, svcraw_reply, svcraw_freeargs, svcraw_destroy }; SVCXPRT * svcraw_create(void) { struct svcraw_private *srp = svcraw_private; if (srp == 0) { srp = (struct svcraw_private *)calloc(1, sizeof (*srp)); if (srp == 0) return (0); svcraw_private = srp; } srp->server.xp_sock = 0; srp->server.xp_port = 0; srp->server.xp_ops = &server_ops; srp->server.xp_verf.oa_base = srp->verf_body; xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE); return (&srp->server); } static enum xprt_stat svcraw_stat(SVCXPRT *xprt) { return (XPRT_IDLE); } static bool_t svcraw_recv(SVCXPRT *xprt, struct rpc_msg *msg) { struct svcraw_private *srp = svcraw_private; XDR *xdrs; if (srp == 0) return (0); xdrs = &srp->xdr_stream; xdrs->x_op = XDR_DECODE; XDR_SETPOS(xdrs, 0); if (! xdr_callmsg(xdrs, msg)) return (FALSE); return (TRUE); } static bool_t svcraw_reply(SVCXPRT *xprt, struct rpc_msg *msg) { struct svcraw_private *srp = svcraw_private; XDR *xdrs; if (srp == 0) return (FALSE); xdrs = &srp->xdr_stream; xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); if (! xdr_replymsg(xdrs, msg)) return (FALSE); (void)XDR_GETPOS(xdrs); /* called just for overhead */ return (TRUE); } static bool_t svcraw_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, void *args_ptr) { struct svcraw_private *srp = svcraw_private; if (srp == 0) return (FALSE); if (! (*xdr_args)(&srp->xdr_stream, args_ptr)) { (void)svcraw_freeargs(xprt, xdr_args, args_ptr); return FALSE; } return TRUE; } static bool_t svcraw_freeargs(SVCXPRT *xprt, xdrproc_t xdr_args, void *args_ptr) { struct svcraw_private *srp = svcraw_private; XDR *xdrs; if (srp == 0) return (FALSE); xdrs = &srp->xdr_stream; xdrs->x_op = XDR_FREE; return ((*xdr_args)(xdrs, args_ptr)); } static void svcraw_destroy(SVCXPRT *xprt) { } krb5-1.22.1/src/lib/rpc/svc_udp.c0000664000175000017500000003373615051422640016305 0ustar ghudsonghudson/* @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro"; #endif /* * svc_udp.c, * Server side for UDP/IP based RPC. (Does some caching in the hopes of * achieving execute-at-most-once semantics.) */ #include "k5-platform.h" #include #include #include #ifdef HAVE_SYS_UIO_H #include #endif #include #include #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE int #endif #define rpc_buffer(xprt) ((xprt)->xp_p1) #ifndef MAX #define MAX(a, b) ((a > b) ? a : b) #endif static bool_t svcudp_recv(SVCXPRT *, struct rpc_msg *); static bool_t svcudp_reply(SVCXPRT *, struct rpc_msg *); static enum xprt_stat svcudp_stat(SVCXPRT *); static bool_t svcudp_getargs(SVCXPRT *, xdrproc_t, void *); static bool_t svcudp_freeargs(SVCXPRT *, xdrproc_t, void *); static void svcudp_destroy(SVCXPRT *); static void cache_set(SVCXPRT *, uint32_t); static int cache_get(SVCXPRT *, struct rpc_msg *, char **, uint32_t *); static struct xp_ops svcudp_op = { svcudp_recv, svcudp_stat, svcudp_getargs, svcudp_reply, svcudp_freeargs, svcudp_destroy }; /* * kept in xprt->xp_p2 */ struct svcudp_data { u_int su_iosz; /* byte size of send.recv buffer */ uint32_t su_xid; /* transaction id */ XDR su_xdrs; /* XDR handle */ char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ void * su_cache; /* cached data, NULL if no cache */ }; #define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2)) /* * Usage: * xprt = svcudp_create(sock); * * If sock<0 then a socket is created, else sock is used. * If the socket, sock is not bound to a port then svcudp_create * binds it to an arbitrary port. In any (successful) case, * xprt->xp_sock is the registered socket number and xprt->xp_port is the * associated port number. * Once *xprt is initialized, it is registered as a transporter; * see (svc.h, xprt_register). * The routines returns NULL if a problem occurred. */ SVCXPRT * svcudp_bufcreate( int sock, u_int sendsz, u_int recvsz) { bool_t madesock = FALSE; SVCXPRT *xprt; struct svcudp_data *su; struct sockaddr_storage ss; struct sockaddr *sa = (struct sockaddr *)&ss; socklen_t len; if (sock == RPC_ANYSOCK) { if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("svcudp_create: socket creation problem"); return ((SVCXPRT *)NULL); } set_cloexec_fd(sock); madesock = TRUE; memset(&ss, 0, sizeof(ss)); sa->sa_family = AF_INET; } else { len = sizeof(struct sockaddr_storage); if (getsockname(sock, sa, &len) < 0) { perror("svcudp_create - cannot getsockname"); return ((SVCXPRT *)NULL); } } if (bindresvport_sa(sock, sa)) { sa_setport(sa, 0); (void)bind(sock, sa, sa_socklen(sa)); } len = sizeof(struct sockaddr_storage); if (getsockname(sock, sa, &len) != 0) { perror("svcudp_create - cannot getsockname"); if (madesock) (void)close(sock); return ((SVCXPRT *)NULL); } xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); if (xprt == NULL) { (void)fprintf(stderr, "svcudp_create: out of memory\n"); return (NULL); } su = (struct svcudp_data *)mem_alloc(sizeof(*su)); if (su == NULL) { (void)fprintf(stderr, "svcudp_create: out of memory\n"); return (NULL); } su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) { (void)fprintf(stderr, "svcudp_create: out of memory\n"); return (NULL); } xdrmem_create( &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); su->su_cache = NULL; xprt->xp_p2 = (caddr_t)su; xprt->xp_auth = NULL; xprt->xp_verf.oa_base = su->su_verfbody; xprt->xp_ops = &svcudp_op; xprt->xp_port = sa_getport(sa); xprt->xp_sock = sock; xprt_register(xprt); return (xprt); } SVCXPRT * svcudp_create(int sock) { return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE)); } static enum xprt_stat svcudp_stat(SVCXPRT *xprt) { return (XPRT_IDLE); } static bool_t svcudp_recv( SVCXPRT *xprt, struct rpc_msg *msg) { struct msghdr dummy; struct iovec dummy_iov[1]; struct svcudp_data *su = su_data(xprt); XDR *xdrs = &su->su_xdrs; int rlen; char *reply; uint32_t replylen; socklen_t addrlen; again: memset(&dummy, 0, sizeof(dummy)); dummy_iov[0].iov_base = rpc_buffer(xprt); dummy_iov[0].iov_len = (int) su->su_iosz; dummy.msg_iov = dummy_iov; dummy.msg_iovlen = 1; dummy.msg_namelen = xprt->xp_laddrlen = sizeof(struct sockaddr_in); dummy.msg_name = (char *) &xprt->xp_laddr; rlen = recvmsg(xprt->xp_sock, &dummy, MSG_PEEK); if (rlen == -1) { if (errno == EINTR) goto again; else return (FALSE); } addrlen = sizeof(struct sockaddr_in); rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, 0, (struct sockaddr *)&(xprt->xp_raddr), &addrlen); if (rlen == -1 && errno == EINTR) goto again; if (rlen < (int) (4*sizeof(uint32_t))) return (FALSE); xprt->xp_addrlen = addrlen; xdrs->x_op = XDR_DECODE; XDR_SETPOS(xdrs, 0); if (! xdr_callmsg(xdrs, msg)) return (FALSE); su->su_xid = msg->rm_xid; if (su->su_cache != NULL) { if (cache_get(xprt, msg, &reply, &replylen)) { (void) sendto(xprt->xp_sock, reply, (int) replylen, 0, (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen); return (TRUE); } } return (TRUE); } static bool_t svcudp_reply( SVCXPRT *xprt, struct rpc_msg *msg) { struct svcudp_data *su = su_data(xprt); XDR *xdrs = &su->su_xdrs; u_int slen; bool_t stat = FALSE; ssize_t r; xdrproc_t xdr_results = NULL; caddr_t xdr_location = 0; bool_t has_args; if (msg->rm_reply.rp_stat == MSG_ACCEPTED && msg->rm_reply.rp_acpt.ar_stat == SUCCESS) { has_args = TRUE; xdr_results = msg->acpted_rply.ar_results.proc; xdr_location = msg->acpted_rply.ar_results.where; msg->acpted_rply.ar_results.proc = xdr_void; msg->acpted_rply.ar_results.where = NULL; } else has_args = FALSE; xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); msg->rm_xid = su->su_xid; if (xdr_replymsg(xdrs, msg) && (!has_args || (SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) { slen = XDR_GETPOS(xdrs); r = sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0, (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen); if (r >= 0 && (u_int)r == slen) { stat = TRUE; if (su->su_cache) { cache_set(xprt, (uint32_t) slen); } } } return (stat); } static bool_t svcudp_getargs( SVCXPRT *xprt, xdrproc_t xdr_args, void * args_ptr) { if (! SVCAUTH_UNWRAP(xprt->xp_auth, &(su_data(xprt)->su_xdrs), xdr_args, args_ptr)) { (void)svcudp_freeargs(xprt, xdr_args, args_ptr); return FALSE; } return TRUE; } static bool_t svcudp_freeargs( SVCXPRT *xprt, xdrproc_t xdr_args, void * args_ptr) { XDR *xdrs = &su_data(xprt)->su_xdrs; xdrs->x_op = XDR_FREE; return ((*xdr_args)(xdrs, args_ptr)); } static void svcudp_destroy(SVCXPRT *xprt) { struct svcudp_data *su = su_data(xprt); xprt_unregister(xprt); if (xprt->xp_sock != INVALID_SOCKET) (void)closesocket(xprt->xp_sock); xprt->xp_sock = INVALID_SOCKET; if (xprt->xp_auth != NULL) { SVCAUTH_DESTROY(xprt->xp_auth); xprt->xp_auth = NULL; } XDR_DESTROY(&(su->su_xdrs)); mem_free(rpc_buffer(xprt), su->su_iosz); mem_free((caddr_t)su, sizeof(struct svcudp_data)); mem_free((caddr_t)xprt, sizeof(SVCXPRT)); } /***********this could be a separate file*********************/ /* * Fifo cache for udp server * Copies pointers to reply buffers into fifo cache * Buffers are sent again if retransmissions are detected. */ #define SPARSENESS 4 /* 75% sparse */ #define CACHE_PERROR(msg) \ (void) fprintf(stderr,"%s\n", msg) #define ALLOC(type, size) \ (type *) mem_alloc((unsigned) (sizeof(type) * (size))) #define BZERO(addr, type, size) \ memset(addr, 0, sizeof(type) * (int) (size)) /* * An entry in the cache */ typedef struct cache_node *cache_ptr; struct cache_node { /* * Index into cache is xid, proc, vers, prog and address */ uint32_t cache_xid; rpcproc_t cache_proc; rpcvers_t cache_vers; rpcprog_t cache_prog; struct sockaddr_in cache_addr; /* * The cached reply and length */ char * cache_reply; uint32_t cache_replylen; /* * Next node on the list, if there is a collision */ cache_ptr cache_next; }; /* * The entire cache */ struct udp_cache { uint32_t uc_size; /* size of cache */ cache_ptr *uc_entries; /* hash table of entries in cache */ cache_ptr *uc_fifo; /* fifo list of entries in cache */ uint32_t uc_nextvictim; /* points to next victim in fifo list */ rpcprog_t uc_prog; /* saved program number */ rpcvers_t uc_vers; /* saved version number */ rpcproc_t uc_proc; /* saved procedure number */ struct sockaddr_in uc_addr; /* saved caller's address */ }; /* * the hashing function */ #define CACHE_LOC(transp, xid) \ (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size)) /* * Enable use of the cache. * Note: there is no disable. */ int svcudp_enablecache( SVCXPRT *transp, uint32_t size) { struct svcudp_data *su = su_data(transp); struct udp_cache *uc; if (su->su_cache != NULL) { CACHE_PERROR("enablecache: cache already enabled"); return(0); } uc = ALLOC(struct udp_cache, 1); if (uc == NULL) { CACHE_PERROR("enablecache: could not allocate cache"); return(0); } uc->uc_size = size; uc->uc_nextvictim = 0; uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS); if (uc->uc_entries == NULL) { CACHE_PERROR("enablecache: could not allocate cache data"); return(0); } BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS); uc->uc_fifo = ALLOC(cache_ptr, size); if (uc->uc_fifo == NULL) { CACHE_PERROR("enablecache: could not allocate cache fifo"); return(0); } BZERO(uc->uc_fifo, cache_ptr, size); su->su_cache = (char *) uc; return(1); } /* * Set an entry in the cache */ static void cache_set( SVCXPRT *xprt, uint32_t replylen) { cache_ptr victim; cache_ptr *vicp; struct svcudp_data *su = su_data(xprt); struct udp_cache *uc = (struct udp_cache *) su->su_cache; u_int loc; char *newbuf; /* * Find space for the new entry, either by * reusing an old entry, or by mallocing a new one */ victim = uc->uc_fifo[uc->uc_nextvictim]; if (victim != NULL) { loc = CACHE_LOC(xprt, victim->cache_xid); for (vicp = &uc->uc_entries[loc]; *vicp != NULL && *vicp != victim; vicp = &(*vicp)->cache_next) ; if (*vicp == NULL) { CACHE_PERROR("cache_set: victim not found"); return; } *vicp = victim->cache_next; /* remote from cache */ newbuf = victim->cache_reply; } else { victim = ALLOC(struct cache_node, 1); if (victim == NULL) { CACHE_PERROR("cache_set: victim alloc failed"); return; } newbuf = mem_alloc(su->su_iosz); if (newbuf == NULL) { CACHE_PERROR("cache_set: could not allocate new rpc_buffer"); free(victim); return; } } /* * Store it away */ victim->cache_replylen = replylen; victim->cache_reply = rpc_buffer(xprt); rpc_buffer(xprt) = newbuf; xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE); victim->cache_xid = su->su_xid; victim->cache_proc = uc->uc_proc; victim->cache_vers = uc->uc_vers; victim->cache_prog = uc->uc_prog; victim->cache_addr = uc->uc_addr; loc = CACHE_LOC(xprt, victim->cache_xid); victim->cache_next = uc->uc_entries[loc]; uc->uc_entries[loc] = victim; uc->uc_fifo[uc->uc_nextvictim++] = victim; uc->uc_nextvictim %= uc->uc_size; } /* * Try to get an entry from the cache * return 1 if found, 0 if not found */ static int cache_get( SVCXPRT *xprt, struct rpc_msg *msg, char **replyp, uint32_t *replylenp) { u_int loc; cache_ptr ent; struct svcudp_data *su = su_data(xprt); struct udp_cache *uc = su->su_cache; # define EQADDR(a1, a2) (memcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0) loc = CACHE_LOC(xprt, su->su_xid); for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) { if (ent->cache_xid == su->su_xid && ent->cache_proc == uc->uc_proc && ent->cache_vers == uc->uc_vers && ent->cache_prog == uc->uc_prog && EQADDR(ent->cache_addr, uc->uc_addr)) { *replyp = ent->cache_reply; *replylenp = ent->cache_replylen; return(1); } } /* * Failed to find entry * Remember a few things so we can do a set later */ uc->uc_proc = msg->rm_call.cb_proc; uc->uc_vers = msg->rm_call.cb_vers; uc->uc_prog = msg->rm_call.cb_prog; uc->uc_addr = xprt->xp_raddr; return(0); } krb5-1.22.1/src/lib/rpc/svc_auth_gss.c0000664000175000017500000004352215051422640017324 0ustar ghudsonghudson/* lib/rpc/svc_auth_gss.c */ /* Copyright (c) 2000 The Regents of the University of Michigan. All rights reserved. Copyright (c) 2000 Dug Song . All rights reserved, all wrongs reversed. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Id: svc_auth_gss.c,v 1.28 2002/10/15 21:29:36 kwc Exp */ #include "k5-platform.h" #include #include #ifdef HAVE_HEIMDAL #include #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE #else #include #include #endif #ifdef DEBUG_GSSAPI int svc_debug_gss = DEBUG_GSSAPI; #endif #ifdef SPKM #ifndef OID_EQ #define g_OID_equal(o1,o2) \ (((o1)->length == (o2)->length) && \ ((o1)->elements != 0) && ((o2)->elements != 0) && \ (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) #define OID_EQ 1 #endif /* OID_EQ */ extern const gss_OID_desc * const gss_mech_spkm3; #endif /* SPKM */ extern SVCAUTH svc_auth_none; static auth_gssapi_log_badauth_func log_badauth = NULL; static caddr_t log_badauth_data = NULL; static auth_gssapi_log_badauth2_func log_badauth2 = NULL; static caddr_t log_badauth2_data = NULL; static auth_gssapi_log_badverf_func log_badverf = NULL; static caddr_t log_badverf_data = NULL; static auth_gssapi_log_miscerr_func log_miscerr = NULL; static caddr_t log_miscerr_data = NULL; #define LOG_MISCERR(arg) if (log_miscerr) \ (*log_miscerr)(rqst, msg, arg, log_miscerr_data) static bool_t svcauth_gss_destroy(SVCAUTH *); static bool_t svcauth_gss_wrap(SVCAUTH *, XDR *, xdrproc_t, caddr_t); static bool_t svcauth_gss_unwrap(SVCAUTH *, XDR *, xdrproc_t, caddr_t); static bool_t svcauth_gss_nextverf(struct svc_req *, u_int); struct svc_auth_ops svc_auth_gss_ops = { svcauth_gss_wrap, svcauth_gss_unwrap, svcauth_gss_destroy }; struct svc_rpc_gss_data { bool_t established; /* context established */ gss_cred_id_t cred; /* credential */ gss_ctx_id_t ctx; /* context id */ struct rpc_gss_sec sec; /* security triple */ gss_buffer_desc cname; /* GSS client name */ u_int seq; /* sequence number */ u_int win; /* sequence window */ u_int seqlast; /* last sequence number */ uint32_t seqmask; /* bitmask of seqnums */ gss_name_t client_name; /* unparsed name string */ gss_buffer_desc checksum; /* so we can free it */ }; #define SVCAUTH_PRIVATE(auth) \ (*(struct svc_rpc_gss_data **)&(auth)->svc_ah_private) /* Global server credentials. */ static gss_name_t svcauth_gss_name = NULL; bool_t svcauth_gss_set_svc_name(gss_name_t name) { OM_uint32 maj_stat, min_stat; log_debug("in svcauth_gss_set_svc_name()"); if (svcauth_gss_name != NULL) { maj_stat = gss_release_name(&min_stat, &svcauth_gss_name); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_release_name", maj_stat, min_stat); return (FALSE); } svcauth_gss_name = NULL; } if (svcauth_gss_name == GSS_C_NO_NAME) return (TRUE); maj_stat = gss_duplicate_name(&min_stat, name, &svcauth_gss_name); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_duplicate_name", maj_stat, min_stat); return (FALSE); } return (TRUE); } static bool_t svcauth_gss_acquire_cred(struct svc_rpc_gss_data *gd) { OM_uint32 maj_stat, min_stat; log_debug("in svcauth_gss_acquire_cred()"); /* We don't need to acquire a credential if using the default name. */ if (svcauth_gss_name == GSS_C_NO_NAME) return (TRUE); /* Only acquire a credential once per authentication. */ if (gd->cred != GSS_C_NO_CREDENTIAL) return (TRUE); maj_stat = gss_acquire_cred(&min_stat, svcauth_gss_name, 0, GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &gd->cred, NULL, NULL); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_acquire_cred", maj_stat, min_stat); return (FALSE); } return (TRUE); } /* Invoke log_badauth callbacks for an authentication failure. */ static void badauth(OM_uint32 maj, OM_uint32 minor, SVCXPRT *xprt) { if (log_badauth != NULL) (*log_badauth)(maj, minor, &xprt->xp_raddr, log_badauth_data); if (log_badauth2 != NULL) (*log_badauth2)(maj, minor, xprt, log_badauth2_data); } static bool_t svcauth_gss_accept_sec_context(struct svc_req *rqst, struct rpc_gss_init_res *gr) { struct svc_rpc_gss_data *gd; struct rpc_gss_cred *gc; gss_buffer_desc recv_tok, seqbuf; gss_OID mech; OM_uint32 maj_stat = 0, min_stat = 0, ret_flags, seq; log_debug("in svcauth_gss_accept_context()"); gd = SVCAUTH_PRIVATE(rqst->rq_xprt->xp_auth); gc = (struct rpc_gss_cred *)rqst->rq_clntcred; memset(gr, 0, sizeof(*gr)); /* Deserialize arguments. */ memset(&recv_tok, 0, sizeof(recv_tok)); if (!svc_getargs(rqst->rq_xprt, (xdrproc_t)xdr_rpc_gss_init_args, (caddr_t)&recv_tok)) return (FALSE); gr->gr_major = gss_accept_sec_context(&gr->gr_minor, &gd->ctx, gd->cred, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &gd->client_name, &mech, &gr->gr_token, &ret_flags, NULL, NULL); svc_freeargs(rqst->rq_xprt, (xdrproc_t)xdr_rpc_gss_init_args, (caddr_t)&recv_tok); log_status("accept_sec_context", gr->gr_major, gr->gr_minor); if (gr->gr_major != GSS_S_COMPLETE && gr->gr_major != GSS_S_CONTINUE_NEEDED) { badauth(gr->gr_major, gr->gr_minor, rqst->rq_xprt); gd->ctx = GSS_C_NO_CONTEXT; goto errout; } gr->gr_ctx.value = "xxxx"; gr->gr_ctx.length = 4; /* gr->gr_win = 0x00000005; ANDROS: for debugging linux kernel version... */ gr->gr_win = sizeof(gd->seqmask) * 8; /* Save client info. */ gd->sec.mech = mech; gd->sec.qop = GSS_C_QOP_DEFAULT; gd->sec.svc = gc->gc_svc; gd->seq = gc->gc_seq; gd->win = gr->gr_win; if (gr->gr_major == GSS_S_COMPLETE) { #ifdef SPKM /* spkm3: no src_name (anonymous) */ if(!g_OID_equal(gss_mech_spkm3, mech)) { #endif maj_stat = gss_display_name(&min_stat, gd->client_name, &gd->cname, &gd->sec.mech); #ifdef SPKM } #endif if (maj_stat != GSS_S_COMPLETE) { log_status("display_name", maj_stat, min_stat); goto errout; } #ifdef DEBUG #ifdef HAVE_HEIMDAL log_debug("accepted context for %.*s with " "", gd->cname.length, (char *)gd->cname.value, gd->sec.qop, gd->sec.svc); #else { gss_buffer_desc mechname; gss_oid_to_str(&min_stat, mech, &mechname); log_debug("accepted context for %.*s with " "", gd->cname.length, (char *)gd->cname.value, mechname.length, (char *)mechname.value, gd->sec.qop, gd->sec.svc); gss_release_buffer(&min_stat, &mechname); } #endif #endif /* DEBUG */ seq = htonl(gr->gr_win); seqbuf.value = &seq; seqbuf.length = sizeof(seq); gss_release_buffer(&min_stat, &gd->checksum); maj_stat = gss_sign(&min_stat, gd->ctx, GSS_C_QOP_DEFAULT, &seqbuf, &gd->checksum); if (maj_stat != GSS_S_COMPLETE) { goto errout; } rqst->rq_xprt->xp_verf.oa_flavor = RPCSEC_GSS; rqst->rq_xprt->xp_verf.oa_base = gd->checksum.value; rqst->rq_xprt->xp_verf.oa_length = gd->checksum.length; } return (TRUE); errout: gss_release_buffer(&min_stat, &gr->gr_token); return (FALSE); } static bool_t svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct rpc_msg *msg) { struct opaque_auth *oa; gss_buffer_desc rpcbuf, checksum; OM_uint32 maj_stat, min_stat, qop_state; u_char rpchdr[32 + MAX_AUTH_BYTES]; int32_t *buf; log_debug("in svcauth_gss_validate()"); memset(rpchdr, 0, sizeof(rpchdr)); /* XXX - Reconstruct RPC header for signing (from xdr_callmsg). */ oa = &msg->rm_call.cb_cred; if (oa->oa_length > MAX_AUTH_BYTES) return (FALSE); /* 8 XDR units from the IXDR macro calls. */ if (sizeof(rpchdr) < (8 * BYTES_PER_XDR_UNIT + RNDUP(oa->oa_length))) return (FALSE); buf = (int32_t *)(void *)rpchdr; /* Write the 32 first bytes of the header. */ IXDR_PUT_LONG(buf, msg->rm_xid); IXDR_PUT_ENUM(buf, msg->rm_direction); IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers); IXDR_PUT_LONG(buf, msg->rm_call.cb_prog); IXDR_PUT_LONG(buf, msg->rm_call.cb_vers); IXDR_PUT_LONG(buf, msg->rm_call.cb_proc); IXDR_PUT_ENUM(buf, oa->oa_flavor); IXDR_PUT_LONG(buf, oa->oa_length); if (oa->oa_length) { memcpy((caddr_t)buf, oa->oa_base, oa->oa_length); buf += RNDUP(oa->oa_length) / sizeof(int32_t); } rpcbuf.value = rpchdr; rpcbuf.length = (u_char *)buf - rpchdr; checksum.value = msg->rm_call.cb_verf.oa_base; checksum.length = msg->rm_call.cb_verf.oa_length; maj_stat = gss_verify_mic(&min_stat, gd->ctx, &rpcbuf, &checksum, &qop_state); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_verify_mic", maj_stat, min_stat); if (log_badverf != NULL) (*log_badverf)(gd->client_name, svcauth_gss_name, rqst, msg, log_badverf_data); return (FALSE); } return (TRUE); } static bool_t svcauth_gss_nextverf(struct svc_req *rqst, u_int num) { struct svc_rpc_gss_data *gd; gss_buffer_desc signbuf; OM_uint32 maj_stat, min_stat; log_debug("in svcauth_gss_nextverf()"); if (rqst->rq_xprt->xp_auth == NULL) return (FALSE); gd = SVCAUTH_PRIVATE(rqst->rq_xprt->xp_auth); gss_release_buffer(&min_stat, &gd->checksum); signbuf.value = # signbuf.length = sizeof(num); maj_stat = gss_get_mic(&min_stat, gd->ctx, gd->sec.qop, &signbuf, &gd->checksum); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_get_mic", maj_stat, min_stat); return (FALSE); } rqst->rq_xprt->xp_verf.oa_flavor = RPCSEC_GSS; rqst->rq_xprt->xp_verf.oa_base = (caddr_t)gd->checksum.value; rqst->rq_xprt->xp_verf.oa_length = (u_int)gd->checksum.length; return (TRUE); } enum auth_stat gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch) { enum auth_stat retstat; XDR xdrs; SVCAUTH *auth; struct svc_rpc_gss_data *gd; struct rpc_gss_cred *gc; struct rpc_gss_init_res gr; int call_stat, offset; OM_uint32 min_stat; log_debug("in svcauth_gss()"); /* Initialize reply. */ rqst->rq_xprt->xp_verf = gssrpc__null_auth; /* Allocate and set up server auth handle. */ if (rqst->rq_xprt->xp_auth == NULL || rqst->rq_xprt->xp_auth == &svc_auth_none) { if ((auth = calloc(sizeof(*auth), 1)) == NULL) { fprintf(stderr, "svcauth_gss: out_of_memory\n"); return (AUTH_FAILED); } if ((gd = calloc(sizeof(*gd), 1)) == NULL) { fprintf(stderr, "svcauth_gss: out_of_memory\n"); return (AUTH_FAILED); } auth->svc_ah_ops = &svc_auth_gss_ops; SVCAUTH_PRIVATE(auth) = gd; rqst->rq_xprt->xp_auth = auth; } else gd = SVCAUTH_PRIVATE(rqst->rq_xprt->xp_auth); log_debug("xp_auth=%p, gd=%p", rqst->rq_xprt->xp_auth, gd); /* Deserialize client credentials. */ if (rqst->rq_cred.oa_length <= 0) return (AUTH_BADCRED); gc = (struct rpc_gss_cred *)rqst->rq_clntcred; memset(gc, 0, sizeof(*gc)); log_debug("calling xdrmem_create()"); log_debug("oa_base=%p, oa_length=%u", rqst->rq_cred.oa_base, rqst->rq_cred.oa_length); xdrmem_create(&xdrs, rqst->rq_cred.oa_base, rqst->rq_cred.oa_length, XDR_DECODE); log_debug("xdrmem_create() returned"); if (!xdr_rpc_gss_cred(&xdrs, gc)) { log_debug("xdr_rpc_gss_cred() failed"); XDR_DESTROY(&xdrs); return (AUTH_BADCRED); } XDR_DESTROY(&xdrs); retstat = AUTH_FAILED; #define ret_freegc(code) do { retstat = code; goto freegc; } while (0) /* Check version. */ if (gc->gc_v != RPCSEC_GSS_VERSION) ret_freegc (AUTH_BADCRED); /* Check RPCSEC_GSS service. */ if (gc->gc_svc != RPCSEC_GSS_SVC_NONE && gc->gc_svc != RPCSEC_GSS_SVC_INTEGRITY && gc->gc_svc != RPCSEC_GSS_SVC_PRIVACY) ret_freegc (AUTH_BADCRED); /* Check sequence number. */ if (gd->established) { if (gc->gc_seq > MAXSEQ) ret_freegc (RPCSEC_GSS_CTXPROBLEM); if ((offset = gd->seqlast - gc->gc_seq) < 0) { gd->seqlast = gc->gc_seq; offset = 0 - offset; gd->seqmask <<= offset; offset = 0; } else if ((u_int)offset >= gd->win || (gd->seqmask & (1 << offset))) { *no_dispatch = 1; ret_freegc (RPCSEC_GSS_CTXPROBLEM); } gd->seq = gc->gc_seq; gd->seqmask |= (1 << offset); } if (gd->established) { rqst->rq_clntname = (char *)gd->client_name; rqst->rq_svccred = (char *)gd->ctx; } /* Handle RPCSEC_GSS control procedure. */ switch (gc->gc_proc) { case RPCSEC_GSS_INIT: case RPCSEC_GSS_CONTINUE_INIT: if (rqst->rq_proc != NULLPROC) ret_freegc (AUTH_FAILED); /* XXX ? */ if (!svcauth_gss_acquire_cred(gd)) ret_freegc (AUTH_FAILED); if (!svcauth_gss_accept_sec_context(rqst, &gr)) ret_freegc (AUTH_REJECTEDCRED); if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win))) { gss_release_buffer(&min_stat, &gr.gr_token); ret_freegc (AUTH_FAILED); } *no_dispatch = TRUE; call_stat = svc_sendreply(rqst->rq_xprt, (xdrproc_t)xdr_rpc_gss_init_res, (caddr_t)&gr); gss_release_buffer(&min_stat, &gr.gr_token); gss_release_buffer(&min_stat, &gd->checksum); if (!call_stat) ret_freegc (AUTH_FAILED); if (gr.gr_major == GSS_S_COMPLETE) gd->established = TRUE; break; case RPCSEC_GSS_DATA: if (!svcauth_gss_validate(rqst, gd, msg)) ret_freegc (RPCSEC_GSS_CREDPROBLEM); if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq))) ret_freegc (AUTH_FAILED); break; case RPCSEC_GSS_DESTROY: if (rqst->rq_proc != NULLPROC) ret_freegc (AUTH_FAILED); /* XXX ? */ if (!svcauth_gss_validate(rqst, gd, msg)) ret_freegc (RPCSEC_GSS_CREDPROBLEM); if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq))) ret_freegc (AUTH_FAILED); *no_dispatch = TRUE; call_stat = svc_sendreply(rqst->rq_xprt, xdr_void, (caddr_t)NULL); log_debug("sendreply in destroy: %d", call_stat); SVCAUTH_DESTROY(rqst->rq_xprt->xp_auth); rqst->rq_xprt->xp_auth = &svc_auth_none; break; default: ret_freegc (AUTH_REJECTEDCRED); break; } retstat = AUTH_OK; freegc: xdr_free((xdrproc_t)xdr_rpc_gss_cred, gc); log_debug("returning %d from svcauth_gss()", retstat); return (retstat); } static bool_t svcauth_gss_destroy(SVCAUTH *auth) { struct svc_rpc_gss_data *gd; OM_uint32 min_stat; log_debug("in svcauth_gss_destroy()"); gd = SVCAUTH_PRIVATE(auth); gss_delete_sec_context(&min_stat, &gd->ctx, GSS_C_NO_BUFFER); gss_release_cred(&min_stat, &gd->cred); gss_release_buffer(&min_stat, &gd->cname); gss_release_buffer(&min_stat, &gd->checksum); if (gd->client_name) gss_release_name(&min_stat, &gd->client_name); mem_free(gd, sizeof(*gd)); mem_free(auth, sizeof(*auth)); return (TRUE); } static bool_t svcauth_gss_wrap(SVCAUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { struct svc_rpc_gss_data *gd; log_debug("in svcauth_gss_wrap()"); gd = SVCAUTH_PRIVATE(auth); if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE) { return ((*xdr_func)(xdrs, xdr_ptr)); } return (xdr_rpc_gss_data(xdrs, xdr_func, xdr_ptr, gd->ctx, gd->sec.qop, gd->sec.svc, gd->seq)); } static bool_t svcauth_gss_unwrap(SVCAUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { struct svc_rpc_gss_data *gd; log_debug("in svcauth_gss_unwrap()"); gd = SVCAUTH_PRIVATE(auth); if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE) { return ((*xdr_func)(xdrs, xdr_ptr)); } return (xdr_rpc_gss_data(xdrs, xdr_func, xdr_ptr, gd->ctx, gd->sec.qop, gd->sec.svc, gd->seq)); } char * svcauth_gss_get_principal(SVCAUTH *auth) { struct svc_rpc_gss_data *gd; char *pname; gd = SVCAUTH_PRIVATE(auth); if (gd->cname.length == 0 || gd->cname.length >= SIZE_MAX) return (NULL); if ((pname = malloc(gd->cname.length + 1)) == NULL) return (NULL); memcpy(pname, gd->cname.value, gd->cname.length); pname[gd->cname.length] = '\0'; return (pname); } /* * Function: svcauth_gss_set_log_badauth_func * * Purpose: sets the logging function called when an invalid RPC call * arrives * * See functional specifications. */ void svcauth_gss_set_log_badauth_func( auth_gssapi_log_badauth_func func, caddr_t data) { log_badauth = func; log_badauth_data = data; } void svcauth_gss_set_log_badauth2_func(auth_gssapi_log_badauth2_func func, caddr_t data) { log_badauth2 = func; log_badauth2_data = data; } /* * Function: svcauth_gss_set_log_badverf_func * * Purpose: sets the logging function called when an invalid RPC call * arrives * * See functional specifications. */ void svcauth_gss_set_log_badverf_func( auth_gssapi_log_badverf_func func, caddr_t data) { log_badverf = func; log_badverf_data = data; } /* * Function: svcauth_gss_set_log_miscerr_func * * Purpose: sets the logging function called when a miscellaneous * AUTH_GSSAPI error occurs * * See functional specifications. */ void svcauth_gss_set_log_miscerr_func( auth_gssapi_log_miscerr_func func, caddr_t data) { log_miscerr = func; log_miscerr_data = data; } krb5-1.22.1/src/lib/rpc/clnt_tcp.c0000664000175000017500000003261015051422640016436 0ustar ghudsonghudson/* @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; #endif /* * clnt_tcp.c, Implements a TCP/IP based, client side RPC. * * TCP based RPC supports 'batched calls'. * A sequence of calls may be batched-up in a send buffer. The rpc call * return immediately to the client even though the call was not necessarily * sent. The batching occurs if the results' xdr routine is NULL (0) AND * the rpc timeout value is zero (see clnt.h, rpc). * * Clients should NOT casually batch calls that in fact return results; that is, * the server side should be aware that a call is batched and not produce any * return message. Batched calls that produce many result messages can * deadlock (netlock) the client and the server.... * * Now go hang yourself. */ #include #include #include #include #include #include #include #include /* FD_ZERO may need memset declaration (e.g., Solaris 9) */ #include #include #define MCALL_MSG_SIZE 24 #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE int #endif static enum clnt_stat clnttcp_call(CLIENT *, rpcproc_t, xdrproc_t, void *, xdrproc_t, void *, struct timeval); static void clnttcp_abort(CLIENT *); static void clnttcp_geterr(CLIENT *, struct rpc_err *); static bool_t clnttcp_freeres(CLIENT *, xdrproc_t, void *); static bool_t clnttcp_control(CLIENT *, int, void *); static void clnttcp_destroy(CLIENT *); static struct clnt_ops tcp_ops = { clnttcp_call, clnttcp_abort, clnttcp_geterr, clnttcp_freeres, clnttcp_destroy, clnttcp_control }; struct ct_data { int ct_sock; bool_t ct_closeit; struct timeval ct_wait; bool_t ct_waitset; /* wait set by clnt_control? */ struct sockaddr_in ct_addr; struct rpc_err ct_error; union { char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */ uint32_t ct_mcalli; } ct_u; u_int ct_mpos; /* pos after marshal */ XDR ct_xdrs; }; static int readtcp(char *, caddr_t, int); static int writetcp(char *, caddr_t, int); /* * Create a client handle for a tcp/ip connection. * If *sockp<0, *sockp is set to a newly created TCP socket and it is * connected to raddr. If *sockp non-negative then * raddr is ignored. The rpc/tcp package does buffering * similar to stdio, so the client must pick send and receive buffer sizes,]; * 0 => use the default. * If raddr->sin_port is 0, then a binder on the remote machine is * consulted for the right port number. * NB: *sockp is copied into a private area. * NB: It is the clients responsibility to close *sockp. * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this * something more useful. */ CLIENT * clnttcp_create( struct sockaddr_in *raddr, rpcprog_t prog, rpcvers_t vers, SOCKET *sockp, u_int sendsz, u_int recvsz) { CLIENT *h; struct ct_data *ct = 0; struct timeval now; struct rpc_msg call_msg; h = (CLIENT *)mem_alloc(sizeof(*h)); if (h == NULL) { (void)fprintf(stderr, "clnttcp_create: out of memory\n"); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; goto fooy; } ct = (struct ct_data *)mem_alloc(sizeof(*ct)); if (ct == NULL) { (void)fprintf(stderr, "clnttcp_create: out of memory\n"); rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; goto fooy; } /* * If no port number given ask the pmap for one */ if (raddr != NULL && raddr->sin_port == 0) { u_short port; if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) { mem_free((caddr_t)ct, sizeof(struct ct_data)); mem_free((caddr_t)h, sizeof(CLIENT)); return ((CLIENT *)NULL); } raddr->sin_port = htons(port); } /* * If no socket given, open one */ if (*sockp < 0) { *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); (void)bindresvport_sa(*sockp, NULL); if (*sockp < 0 || raddr == NULL || connect(*sockp, (struct sockaddr *)raddr, sizeof(*raddr)) < 0) { rpc_createerr.cf_stat = RPC_SYSTEMERROR; rpc_createerr.cf_error.re_errno = errno; (void)closesocket(*sockp); goto fooy; } ct->ct_closeit = TRUE; } else { ct->ct_closeit = FALSE; } /* * Set up private data struct */ ct->ct_sock = *sockp; ct->ct_wait.tv_usec = 0; ct->ct_waitset = FALSE; if (raddr == NULL) { /* Get the remote address from the socket, if it's IPv4. */ struct sockaddr_in sin; socklen_t len = sizeof(sin); int ret = getpeername(ct->ct_sock, (struct sockaddr *)&sin, &len); if (ret == 0 && len == sizeof(sin) && sin.sin_family == AF_INET) ct->ct_addr = sin; else memset(&ct->ct_addr, 0, sizeof(ct->ct_addr)); } else ct->ct_addr = *raddr; /* * Initialize call message */ (void)gettimeofday(&now, (struct timezone *)0); call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; call_msg.rm_direction = CALL; call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; call_msg.rm_call.cb_prog = prog; call_msg.rm_call.cb_vers = vers; /* * pre-serialize the staic part of the call msg and stash it away */ xdrmem_create(&(ct->ct_xdrs), ct->ct_u.ct_mcall, MCALL_MSG_SIZE, XDR_ENCODE); if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) { if (ct->ct_closeit) (void)closesocket(*sockp); goto fooy; } ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs)); XDR_DESTROY(&(ct->ct_xdrs)); /* * Create a client handle which uses xdrrec for serialization * and authnone for authentication. */ xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz, (caddr_t)ct, readtcp, writetcp); h->cl_ops = &tcp_ops; h->cl_private = (caddr_t) ct; h->cl_auth = authnone_create(); return (h); fooy: /* * Something goofed, free stuff and barf */ mem_free((caddr_t)ct, sizeof(struct ct_data)); mem_free((caddr_t)h, sizeof(CLIENT)); return ((CLIENT *)NULL); } static enum clnt_stat clnttcp_call( CLIENT *h, rpcproc_t proc, xdrproc_t xdr_args, void * args_ptr, xdrproc_t xdr_results, void * results_ptr, struct timeval timeout) { struct ct_data *ct = h->cl_private; XDR *xdrs = &ct->ct_xdrs; struct rpc_msg reply_msg; uint32_t x_id; uint32_t *msg_x_id = &ct->ct_u.ct_mcalli; /* yuk */ bool_t shipnow; int refreshes = 2; long procl = proc; if (!ct->ct_waitset) { ct->ct_wait = timeout; } shipnow = (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0 && timeout.tv_usec == 0) ? FALSE : TRUE; call_again: xdrs->x_op = XDR_ENCODE; ct->ct_error.re_status = RPC_SUCCESS; x_id = ntohl(--(*msg_x_id)); if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcall, ct->ct_mpos)) || (! XDR_PUTLONG(xdrs, &procl)) || (! AUTH_MARSHALL(h->cl_auth, xdrs)) || (! AUTH_WRAP(h->cl_auth, xdrs, xdr_args, args_ptr))) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTENCODEARGS; (void)xdrrec_endofrecord(xdrs, TRUE); return (ct->ct_error.re_status); } if (! xdrrec_endofrecord(xdrs, shipnow)) return (ct->ct_error.re_status = RPC_CANTSEND); if (! shipnow) return (RPC_SUCCESS); /* * Hack to provide rpc-based message passing */ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { return(ct->ct_error.re_status = RPC_TIMEDOUT); } /* * Keep receiving until we get a valid transaction id */ xdrs->x_op = XDR_DECODE; while (TRUE) { reply_msg.acpted_rply.ar_verf = gssrpc__null_auth; reply_msg.acpted_rply.ar_results.where = NULL; reply_msg.acpted_rply.ar_results.proc = xdr_void; if (! xdrrec_skiprecord(xdrs)) return (ct->ct_error.re_status); /* now decode and validate the response header */ if (! xdr_replymsg(xdrs, &reply_msg)) { /* * Free some stuff allocated by xdr_replymsg() * to avoid leaks, since it may allocate * memory from partially successful decodes. */ enum xdr_op op = xdrs->x_op; xdrs->x_op = XDR_FREE; xdr_replymsg(xdrs, &reply_msg); xdrs->x_op = op; if (ct->ct_error.re_status == RPC_SUCCESS) continue; return (ct->ct_error.re_status); } if (reply_msg.rm_xid == x_id) break; } /* * process header */ gssrpc__seterr_reply(&reply_msg, &(ct->ct_error)); if (ct->ct_error.re_status == RPC_SUCCESS) { if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { ct->ct_error.re_status = RPC_AUTHERROR; ct->ct_error.re_why = AUTH_INVALIDRESP; } else if (! AUTH_UNWRAP(h->cl_auth, xdrs, xdr_results, results_ptr)) { if (ct->ct_error.re_status == RPC_SUCCESS) ct->ct_error.re_status = RPC_CANTDECODERES; } } /* end successful completion */ else { /* maybe our credentials need to be refreshed ... */ if (refreshes-- && AUTH_REFRESH(h->cl_auth, &reply_msg)) goto call_again; } /* end of unsuccessful completion */ /* free verifier ... */ if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) && (reply_msg.acpted_rply.ar_verf.oa_base != NULL)) { xdrs->x_op = XDR_FREE; (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); } return (ct->ct_error.re_status); } static void clnttcp_geterr( CLIENT *h, struct rpc_err *errp) { struct ct_data *ct = h->cl_private; *errp = ct->ct_error; } static bool_t clnttcp_freeres( CLIENT *cl, xdrproc_t xdr_res, void * res_ptr) { struct ct_data *ct = cl->cl_private; XDR *xdrs = &ct->ct_xdrs; xdrs->x_op = XDR_FREE; return ((*xdr_res)(xdrs, res_ptr)); } /*ARGSUSED*/ static void clnttcp_abort(CLIENT *cl) { } static bool_t clnttcp_control( CLIENT *cl, int request, void *info) { struct ct_data *ct = cl->cl_private; GETSOCKNAME_ARG3_TYPE len; switch (request) { case CLSET_TIMEOUT: ct->ct_wait = *(struct timeval *)info; ct->ct_waitset = TRUE; break; case CLGET_TIMEOUT: *(struct timeval *)info = ct->ct_wait; break; case CLGET_SERVER_ADDR: *(struct sockaddr_in *)info = ct->ct_addr; break; case CLGET_LOCAL_ADDR: len = sizeof(struct sockaddr); if (getsockname(ct->ct_sock, (struct sockaddr*)info, &len) < 0) return FALSE; else return TRUE; default: return (FALSE); } return (TRUE); } static void clnttcp_destroy(CLIENT *h) { struct ct_data *ct = h->cl_private; if (ct->ct_closeit) (void)closesocket(ct->ct_sock); XDR_DESTROY(&(ct->ct_xdrs)); mem_free((caddr_t)ct, sizeof(struct ct_data)); mem_free((caddr_t)h, sizeof(CLIENT)); } /* * Interface between xdr serializer and tcp connection. * Behaves like the system calls, read & write, but keeps some error state * around for the rpc level. */ static int readtcp( char *ctptr, caddr_t buf, int len) { struct ct_data *ct = (void *)ctptr; struct timeval tout; #ifdef FD_SETSIZE fd_set mask; fd_set readfds; if (len == 0) return (0); FD_ZERO(&mask); FD_SET(ct->ct_sock, &mask); #else int mask = 1 << (ct->ct_sock); int readfds; if (len == 0) return (0); #endif /* def FD_SETSIZE */ while (TRUE) { readfds = mask; tout = ct->ct_wait; switch (select(gssrpc__rpc_dtablesize(), &readfds, (fd_set*)NULL, (fd_set*)NULL, &tout)) { case 0: ct->ct_error.re_status = RPC_TIMEDOUT; return (-1); case -1: if (errno == EINTR) continue; ct->ct_error.re_status = RPC_CANTRECV; ct->ct_error.re_errno = errno; return (-1); } break; } switch (len = read(ct->ct_sock, buf, (size_t) len)) { case 0: /* premature eof */ ct->ct_error.re_errno = ECONNRESET; ct->ct_error.re_status = RPC_CANTRECV; len = -1; /* it's really an error */ break; case -1: ct->ct_error.re_errno = errno; ct->ct_error.re_status = RPC_CANTRECV; break; } return (len); } static int writetcp( char *ctptr, caddr_t buf, int len) { struct ct_data *ct = (struct ct_data *)(void *)ctptr; int i, cnt; for (cnt = len; cnt > 0; cnt -= i, buf += i) { if ((i = write(ct->ct_sock, buf, (size_t) cnt)) == -1) { ct->ct_error.re_errno = errno; ct->ct_error.re_status = RPC_CANTSEND; return (-1); } } return (len); } krb5-1.22.1/src/lib/rpc/xdr_stdio.c0000664000175000017500000001165315051422640016633 0ustar ghudsonghudson/* @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro"; #endif /* * xdr_stdio.c, XDR implementation on standard i/o file. * * This set of routines implements a XDR on a stdio stream. * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes * from the stream. */ #include #include #include static bool_t xdrstdio_getlong(XDR *, long *); static bool_t xdrstdio_putlong(XDR *, long *); static bool_t xdrstdio_getbytes(XDR *, caddr_t, u_int); static bool_t xdrstdio_putbytes(XDR *, caddr_t, u_int); static u_int xdrstdio_getpos(XDR *); static bool_t xdrstdio_setpos(XDR *, u_int); static rpc_inline_t * xdrstdio_inline(XDR *, int); static void xdrstdio_destroy(XDR *); /* * Ops vector for stdio type XDR */ static struct xdr_ops xdrstdio_ops = { xdrstdio_getlong, /* deseraialize a long int */ xdrstdio_putlong, /* seraialize a long int */ xdrstdio_getbytes, /* deserialize counted bytes */ xdrstdio_putbytes, /* serialize counted bytes */ xdrstdio_getpos, /* get offset in the stream */ xdrstdio_setpos, /* set offset in the stream */ xdrstdio_inline, /* prime stream for inline macros */ xdrstdio_destroy /* destroy stream */ }; /* * Initialize a stdio xdr stream. * Sets the xdr stream handle xdrs for use on the stream file. * Operation flag is set to op. */ void xdrstdio_create(XDR *xdrs, FILE *file, enum xdr_op op) { xdrs->x_op = op; xdrs->x_ops = &xdrstdio_ops; xdrs->x_private = (caddr_t)file; xdrs->x_handy = 0; xdrs->x_base = 0; } /* * Destroy a stdio xdr stream. * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create. */ static void xdrstdio_destroy(XDR *xdrs) { (void)fflush((FILE *)xdrs->x_private); /* xx should we close the file ?? */ } static bool_t xdrstdio_getlong(XDR *xdrs, long *lp) { uint32_t tmp; if (fread((caddr_t)&tmp, sizeof(uint32_t), 1, (FILE *)xdrs->x_private) != 1) return (FALSE); *lp = (long)ntohl(tmp); return (TRUE); } static bool_t xdrstdio_putlong(XDR *xdrs, long *lp) { uint32_t mycopy = htonl((uint32_t)*lp); if (fwrite((caddr_t)&mycopy, sizeof(uint32_t), 1, (FILE *)xdrs->x_private) != 1) return (FALSE); return (TRUE); } static bool_t xdrstdio_getbytes(XDR *xdrs, caddr_t addr, u_int len) { if ((len != 0) && (fread(addr, (size_t)len, 1, (FILE *)xdrs->x_private) != 1)) return (FALSE); return (TRUE); } static bool_t xdrstdio_putbytes(XDR *xdrs, caddr_t addr, u_int len) { if ((len != 0) && (fwrite(addr, (size_t)len, 1, (FILE *)xdrs->x_private) != 1)) return (FALSE); return (TRUE); } static u_int xdrstdio_getpos(XDR *xdrs) { return ((u_int) ftell((FILE *)xdrs->x_private)); } static bool_t xdrstdio_setpos(XDR *xdrs, u_int pos) { return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ? FALSE : TRUE); } static rpc_inline_t * xdrstdio_inline(XDR *xdrs, int len) { /* * Must do some work to implement this: must insure * enough data in the underlying stdio buffer, * that the buffer is aligned so that we can indirect through a * long *, and stuff this pointer in xdrs->x_buf. Doing * a fread or fwrite to a scratch buffer would defeat * most of the gains to be had here and require storage * management on this buffer, so we don't do this. */ return (NULL); } krb5-1.22.1/src/lib/rpc/pmap_rmt.c0000664000175000017500000002677415051422640016465 0ustar ghudsonghudson/* @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro"; #endif /* * pmap_rmt.c * Client interface to pmap rpc service. * remote call and broadcast service */ #include "k5-platform.h" #include #include #include #include #include #include #ifdef sun #include #endif #ifdef OSF1 #include #include #endif #include #include #include #define MAX_BROADCAST_SIZE 1400 #include #include "socket-utils.h" static struct timeval timeout = { 3, 0 }; #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE int #endif /* * pmapper remote-call-service interface. * This routine is used to call the pmapper remote call service * which will look up a service program in the port maps, and then * remotely call that routine with the given parameters. This allows * programs to do a lookup and call in one step. */ enum clnt_stat pmap_rmtcall( struct sockaddr_in *addr, rpcprog_t prog, rpcvers_t vers, rpcproc_t proc, xdrproc_t xdrargs, caddr_t argsp, xdrproc_t xdrres, caddr_t resp, struct timeval tout, rpcport_t *port_ptr) { SOCKET sock = INVALID_SOCKET; CLIENT *client; struct rmtcallargs a; struct rmtcallres r; enum clnt_stat stat; addr->sin_port = htons(PMAPPORT); client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &sock); if (client != (CLIENT *)NULL) { a.prog = prog; a.vers = vers; a.proc = proc; a.args_ptr = argsp; a.xdr_args = xdrargs; r.port_ptr = port_ptr; r.results_ptr = resp; r.xdr_results = xdrres; stat = CLNT_CALL(client, PMAPPROC_CALLIT, (xdrproc_t)xdr_rmtcall_args, &a, (xdrproc_t)xdr_rmtcallres, &r, tout); CLNT_DESTROY(client); } else { stat = RPC_FAILED; } (void)closesocket(sock); addr->sin_port = 0; return (stat); } /* * XDR remote call arguments * written for XDR_ENCODE direction only */ bool_t xdr_rmtcall_args( XDR *xdrs, struct rmtcallargs *cap) { u_int lenposition, argposition, position; if (xdr_u_int32(xdrs, &(cap->prog)) && xdr_u_int32(xdrs, &(cap->vers)) && xdr_u_int32(xdrs, &(cap->proc))) { lenposition = XDR_GETPOS(xdrs); if (! xdr_u_int32(xdrs, &(cap->arglen))) return (FALSE); argposition = XDR_GETPOS(xdrs); if (! (*(cap->xdr_args))(xdrs, cap->args_ptr)) return (FALSE); position = XDR_GETPOS(xdrs); cap->arglen = (uint32_t)position - (uint32_t)argposition; XDR_SETPOS(xdrs, lenposition); if (! xdr_u_int32(xdrs, &(cap->arglen))) return (FALSE); XDR_SETPOS(xdrs, position); return (TRUE); } return (FALSE); } /* * XDR remote call results * written for XDR_DECODE direction only */ bool_t xdr_rmtcallres( XDR *xdrs, struct rmtcallres *crp) { caddr_t port_ptr; port_ptr = (caddr_t)(void *)crp->port_ptr; if (!xdr_reference(xdrs, &port_ptr, sizeof (uint32_t), (xdrproc_t)xdr_u_int32)) return (FALSE); crp->port_ptr = (uint32_t *)(void *)port_ptr; if (xdr_u_int32(xdrs, &crp->resultslen)) return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); return (FALSE); } /* * The following is kludged-up support for simple rpc broadcasts. * Someday a large, complicated system will replace these trivial * routines which only support udp/ip . */ #define GIFCONF_BUFSIZE (256 * sizeof (struct ifconf)) static int getbroadcastnets( struct in_addr *addrs, int sock, /* any valid socket will do */ char *buf /* why allocxate more when we can use existing... */ ) { struct ifconf ifc; struct ifreq ifreq, *ifr; int n, i; ifc.ifc_len = GIFCONF_BUFSIZE; ifc.ifc_buf = buf; memset (buf, 0, GIFCONF_BUFSIZE); if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { perror("broadcast: ioctl (get interface configuration)"); return (0); } ifr = ifc.ifc_req; for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) { ifreq = *ifr; if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) { perror("broadcast: ioctl (get interface flags)"); continue; } if ((ifreq.ifr_flags & IFF_BROADCAST) && (ifreq.ifr_flags & IFF_UP) && ifr->ifr_addr.sa_family == AF_INET) { #ifdef SIOCGIFBRDADDR /* 4.3BSD */ if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { addrs[i++].s_addr = INADDR_ANY; } else { addrs[i++] = sa2sin(&ifreq.ifr_addr)->sin_addr; } #else /* 4.2 BSD */ struct sockaddr_in *sockin; sockin = sa2sin(&ifr->ifr_addr); addrs[i++] = inet_makeaddr(inet_netof (sockin->sin_addr.s_addr), INADDR_ANY); #endif } } return (i); } enum clnt_stat clnt_broadcast( rpcprog_t prog, /* program number */ rpcvers_t vers, /* version number */ rpcproc_t proc, /* procedure number */ xdrproc_t xargs, /* xdr routine for args */ caddr_t argsp, /* pointer to args */ xdrproc_t xresults, /* xdr routine for results */ caddr_t resultsp, /* pointer to results */ resultproc_t eachresult /* call with each result obtained */ ) { enum clnt_stat stat; AUTH *unix_auth = authunix_create_default(); XDR xdr_stream; XDR *xdrs = &xdr_stream; int outlen, nets; ssize_t inlen; GETSOCKNAME_ARG3_TYPE fromlen; SOCKET sock; int on = 1; #ifdef FD_SETSIZE fd_set mask; fd_set readfds; #else int readfds; int mask; #endif /* def FD_SETSIZE */ int i; bool_t done = FALSE; uint32_t xid; rpcport_t port; struct in_addr addrs[20]; struct sockaddr_in baddr, raddr; /* broadcast and response addresses */ struct rmtcallargs a; struct rmtcallres r; struct rpc_msg msg; struct timeval t, t2; char outbuf[MAX_BROADCAST_SIZE]; #ifndef MAX #define MAX(A,B) ((A)<(B)?(B):(A)) #endif char inbuf[MAX (UDPMSGSIZE, GIFCONF_BUFSIZE)]; /* * initialization: create a socket, a broadcast address, and * preserialize the arguments into a send buffer. */ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { perror("Cannot create socket for broadcast rpc"); stat = RPC_CANTSEND; goto done_broad; } set_cloexec_fd(sock); #ifdef SO_BROADCAST if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof (on)) < 0) { perror("Cannot set socket option SO_BROADCAST"); stat = RPC_CANTSEND; goto done_broad; } #endif /* def SO_BROADCAST */ #ifdef FD_SETSIZE FD_ZERO(&mask); FD_SET(sock, &mask); #else mask = (1 << sock); #endif /* def FD_SETSIZE */ nets = getbroadcastnets(addrs, sock, inbuf); memset(&baddr, 0, sizeof (baddr)); baddr.sin_family = AF_INET; baddr.sin_port = htons(PMAPPORT); baddr.sin_addr.s_addr = htonl(INADDR_ANY); /* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */ (void)gettimeofday(&t, (struct timezone *)0); msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec; t.tv_usec = 0; msg.rm_direction = CALL; msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; msg.rm_call.cb_prog = PMAPPROG; msg.rm_call.cb_vers = PMAPVERS; msg.rm_call.cb_proc = PMAPPROC_CALLIT; msg.rm_call.cb_cred = unix_auth->ah_cred; msg.rm_call.cb_verf = unix_auth->ah_verf; a.prog = prog; a.vers = vers; a.proc = proc; a.xdr_args = xargs; a.args_ptr = argsp; r.port_ptr = &port; r.xdr_results = xresults; r.results_ptr = resultsp; xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE); if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) { stat = RPC_CANTENCODEARGS; goto done_broad; } outlen = (int)xdr_getpos(xdrs); xdr_destroy(xdrs); /* * Basic loop: broadcast a packet and wait a while for response(s). * The response timeout grows larger per iteration. */ for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) { for (i = 0; i < nets; i++) { baddr.sin_addr = addrs[i]; if (sendto(sock, outbuf, outlen, 0, (struct sockaddr *)&baddr, sizeof (struct sockaddr)) != outlen) { perror("Cannot send broadcast packet"); stat = RPC_CANTSEND; goto done_broad; } } if (eachresult == NULL) { stat = RPC_SUCCESS; goto done_broad; } recv_again: msg.acpted_rply.ar_verf = gssrpc__null_auth; msg.acpted_rply.ar_results.where = (caddr_t)&r; msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_rmtcallres; readfds = mask; t2 = t; switch (select(gssrpc__rpc_dtablesize(), &readfds, (fd_set *)NULL, (fd_set *)NULL, &t2)) { case 0: /* timed out */ stat = RPC_TIMEDOUT; continue; case -1: /* some kind of error */ if (errno == EINTR) goto recv_again; perror("Broadcast select problem"); stat = RPC_CANTRECV; goto done_broad; } /* end of select results switch */ try_again: fromlen = sizeof(struct sockaddr); inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0, (struct sockaddr *)&raddr, &fromlen); if (inlen < 0) { if (errno == EINTR) goto try_again; perror("Cannot receive reply to broadcast"); stat = RPC_CANTRECV; goto done_broad; } if ((size_t)inlen < sizeof(uint32_t)) goto recv_again; /* * see if reply transaction id matches sent id. * If so, decode the results. */ xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE); if (xdr_replymsg(xdrs, &msg)) { if ((msg.rm_xid == xid) && (msg.rm_reply.rp_stat == MSG_ACCEPTED) && (msg.acpted_rply.ar_stat == SUCCESS)) { raddr.sin_port = htons((u_short)port); done = (*eachresult)(resultsp, &raddr); } /* otherwise, we just ignore the errors ... */ } else { #ifdef notdef /* some kind of deserialization problem ... */ if (msg.rm_xid == xid) fprintf(stderr, "Broadcast deserialization problem"); /* otherwise, just random garbage */ #endif } xdrs->x_op = XDR_FREE; msg.acpted_rply.ar_results.proc = xdr_void; (void)xdr_replymsg(xdrs, &msg); (void)(*xresults)(xdrs, resultsp); xdr_destroy(xdrs); if (done) { stat = RPC_SUCCESS; goto done_broad; } else { goto recv_again; } } done_broad: (void)closesocket(sock); AUTH_DESTROY(unix_auth); return (stat); } krb5-1.22.1/src/lib/rpc/rpc_dtablesize.c0000664000175000017500000000447715051422640017634 0ustar ghudsonghudson/* @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro"; #endif #include #include /* * Cache the result of getdtablesize(), so we don't have to do an * expensive system call every time. */ int gssrpc__rpc_dtablesize(void) { static int size; if (size == 0) { #ifdef _SC_OPEN_MAX size = (int) sysconf(_SC_OPEN_MAX); #else size = getdtablesize(); #endif /* sysconf() can return a number larger than what will fit in an fd_set. we can't use fd's larger than this, anyway. */ #ifdef FD_SETSIZE if (size >= FD_SETSIZE) size = FD_SETSIZE-1; #endif } return (size); } krb5-1.22.1/src/lib/rpc/rpc_prot.c0000664000175000017500000001703715051422640016466 0ustar ghudsonghudson/* @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro"; #endif /* * rpc_prot.c * * This set of routines implements the rpc message definition, * its serializer and some common rpc utility routines. * The routines are meant for various implementations of rpc - * they are NOT for the rpc client or rpc service implementations! * Because authentication stuff is easy and is part of rpc, the opaque * routines are also in this program. */ #include #include /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ /* * XDR an opaque authentication struct * (see auth.h) */ bool_t xdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap) { if (xdr_enum(xdrs, &(ap->oa_flavor))) return (xdr_bytes(xdrs, &ap->oa_base, &ap->oa_length, MAX_AUTH_BYTES)); return (FALSE); } /* * XDR a DES block */ bool_t xdr_des_block(XDR *xdrs, des_block *blkp) { return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block))); } /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ /* * XDR the MSG_ACCEPTED part of a reply message union */ bool_t xdr_accepted_reply(XDR *xdrs, struct accepted_reply *ar) { /* personalized union, rather than calling xdr_union */ if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) return (FALSE); if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat))) return (FALSE); switch (ar->ar_stat) { case SUCCESS: return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); case PROG_MISMATCH: if (! xdr_rpcvers(xdrs, &(ar->ar_vers.low))) return (FALSE); return (xdr_rpcvers(xdrs, &(ar->ar_vers.high))); case GARBAGE_ARGS: case SYSTEM_ERR: case PROC_UNAVAIL: case PROG_UNAVAIL: break; } return (TRUE); /* TRUE => open ended set of problems */ } /* * XDR the MSG_DENIED part of a reply message union */ bool_t xdr_rejected_reply(XDR *xdrs, struct rejected_reply *rr) { /* personalized union, rather than calling xdr_union */ if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat))) return (FALSE); switch (rr->rj_stat) { case RPC_MISMATCH: if (! xdr_rpcvers(xdrs, &(rr->rj_vers.low))) return (FALSE); return (xdr_rpcvers(xdrs, &(rr->rj_vers.high))); case AUTH_ERROR: return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why))); } return (FALSE); } static struct xdr_discrim reply_dscrm[3] = { { (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply }, { (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply }, { __dontcare__, NULL_xdrproc_t } }; /* * XDR a reply message */ bool_t xdr_replymsg(XDR *xdrs, struct rpc_msg *rmsg) { if ( xdr_u_int32(xdrs, &(rmsg->rm_xid)) && xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) && (rmsg->rm_direction == REPLY) ) return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat), (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t)); return (FALSE); } /* * Serializes the "static part" of a call message header. * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. * The rm_xid is not really static, but the user can easily munge on the fly. */ bool_t xdr_callhdr(XDR *xdrs, struct rpc_msg *cmsg) { cmsg->rm_direction = CALL; cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; if ( (xdrs->x_op == XDR_ENCODE) && xdr_u_int32(xdrs, &(cmsg->rm_xid)) && xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && xdr_rpcvers(xdrs, &(cmsg->rm_call.cb_rpcvers)) && xdr_rpcprog(xdrs, &(cmsg->rm_call.cb_prog)) ) return (xdr_rpcvers(xdrs, &(cmsg->rm_call.cb_vers))); return (FALSE); } /* ************************** Client utility routine ************* */ static void accepted(enum accept_stat acpt_stat, struct rpc_err *error) { switch (acpt_stat) { case PROG_UNAVAIL: error->re_status = RPC_PROGUNAVAIL; return; case PROG_MISMATCH: error->re_status = RPC_PROGVERSMISMATCH; return; case PROC_UNAVAIL: error->re_status = RPC_PROCUNAVAIL; return; case GARBAGE_ARGS: error->re_status = RPC_CANTDECODEARGS; return; case SYSTEM_ERR: error->re_status = RPC_SYSTEMERROR; return; case SUCCESS: error->re_status = RPC_SUCCESS; return; } /* something's wrong, but we don't know what ... */ error->re_status = RPC_FAILED; error->re_lb.s1 = (int32_t)MSG_ACCEPTED; error->re_lb.s2 = (int32_t)acpt_stat; } static void rejected(enum reject_stat rjct_stat, struct rpc_err *error) { switch (rjct_stat) { case RPC_MISMATCH: error->re_status = RPC_VERSMISMATCH; return; case AUTH_ERROR: error->re_status = RPC_AUTHERROR; return; } /* something's wrong, but we don't know what ... */ error->re_status = RPC_FAILED; error->re_lb.s1 = (int32_t)MSG_DENIED; error->re_lb.s2 = (int32_t)rjct_stat; } /* * given a reply message, fills in the error */ void gssrpc__seterr_reply(struct rpc_msg *msg, struct rpc_err *error) { /* optimized for normal, SUCCESSful case */ switch (msg->rm_reply.rp_stat) { case MSG_ACCEPTED: if (msg->acpted_rply.ar_stat == SUCCESS) { error->re_status = RPC_SUCCESS; return; }; accepted(msg->acpted_rply.ar_stat, error); break; case MSG_DENIED: rejected(msg->rjcted_rply.rj_stat, error); break; default: error->re_status = RPC_FAILED; error->re_lb.s1 = (int32_t)(msg->rm_reply.rp_stat); break; } switch (error->re_status) { case RPC_VERSMISMATCH: error->re_vers.low = msg->rjcted_rply.rj_vers.low; error->re_vers.high = msg->rjcted_rply.rj_vers.high; break; case RPC_AUTHERROR: error->re_why = msg->rjcted_rply.rj_why; break; case RPC_PROGVERSMISMATCH: error->re_vers.low = msg->acpted_rply.ar_vers.low; error->re_vers.high = msg->acpted_rply.ar_vers.high; break; case RPC_FAILED: case RPC_SUCCESS: case RPC_PROGNOTREGISTERED: case RPC_PMAPFAILURE: case RPC_UNKNOWNPROTO: case RPC_UNKNOWNHOST: case RPC_SYSTEMERROR: case RPC_CANTDECODEARGS: case RPC_PROCUNAVAIL: case RPC_PROGUNAVAIL: case RPC_TIMEDOUT: case RPC_CANTRECV: case RPC_CANTSEND: case RPC_CANTDECODERES: case RPC_CANTENCODEARGS: default: break; } } krb5-1.22.1/src/lib/rpc/svc_auth.c0000664000175000017500000000750615051422640016452 0ustar ghudsonghudson/* lib/rpc/svc_auth.c */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * svc_auth_nodes.c, Server-side rpc authenticator interface, * *WITHOUT* DES authentication. */ #include /* * Server side authenticators are called from authenticate by * using the client auth struct flavor field to index into svcauthsw. * The server auth flavors must implement a routine that looks * like: * * enum auth_stat * flavorx_auth(rqst, msg) * struct svc_req *rqst; * struct rpc_msg *msg; * */ static struct svcauthsw_type { enum_t flavor; enum auth_stat (*authenticator)(struct svc_req *, struct rpc_msg *, bool_t *); } svcauthsw[] = { {AUTH_GSSAPI, gssrpc__svcauth_gssapi}, /* AUTH_GSSAPI */ {AUTH_NONE, gssrpc__svcauth_none}, /* AUTH_NONE */ {AUTH_UNIX, gssrpc__svcauth_unix}, /* AUTH_UNIX */ {AUTH_SHORT, gssrpc__svcauth_short}, /* AUTH_SHORT */ {RPCSEC_GSS, gssrpc__svcauth_gss} /* RPCSEC_GSS */ }; static int svcauthnum = sizeof(svcauthsw) / sizeof(struct svcauthsw_type); /* * The call rpc message, msg has been obtained from the wire. The msg contains * the raw form of credentials and verifiers. authenticate returns AUTH_OK * if the msg is successfully authenticated. If AUTH_OK then the routine also * does the following things: * set rqst->rq_xprt->verf to the appropriate response verifier; * sets rqst->rq_client_cred to the "cooked" form of the credentials. * * NB: rqst->rq_cxprt->verf must be pre-alloctaed; * its length is set appropriately. * * The caller still owns and is responsible for msg->u.cmb.cred and * msg->u.cmb.verf. The authentication system retains ownership of * rqst->rq_client_cred, the cooked credentials. */ enum auth_stat gssrpc__authenticate( struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch) { int cred_flavor, i; rqst->rq_cred = msg->rm_call.cb_cred; rqst->rq_xprt->xp_verf.oa_flavor = gssrpc__null_auth.oa_flavor; rqst->rq_xprt->xp_verf.oa_length = 0; cred_flavor = rqst->rq_cred.oa_flavor; *no_dispatch = FALSE; for (i = 0; i < svcauthnum; i++) { if (cred_flavor == svcauthsw[i].flavor && svcauthsw[i].authenticator != NULL) { return ((*(svcauthsw[i].authenticator))(rqst, msg, no_dispatch)); } } return (AUTH_REJECTEDCRED); } krb5-1.22.1/src/lib/rpc/dyn.c0000664000175000017500000003104415051422640015422 0ustar ghudsonghudson/* * This file is the collected implementation of libdyn.a, the C * Dynamic Object library. It contains everything. * * There are no restrictions on this code; however, if you make any * changes, I request that you document them so that I do not get * credit or blame for your modifications. * * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) * and MIT-Project Athena, 1989. * * 2002-07-17 Collected full implementation into one source file for * easy inclusion into the one library still dependent on * libdyn. Assume memmove. Old ChangeLog appended. */ #include #include #include #include "dynP.h" /* old dyn_append.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynAppend(). */ /* * Made obsolete by DynInsert, now just a convenience function. */ int DynAppend(DynObjectP obj, DynPtr els, int num) { return DynInsert(obj, DynSize(obj), els, num); } /* old dyn_create.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the functions DynCreate() and * DynDestroy(). */ #ifndef DEFAULT_INC #define DEFAULT_INC 100 #endif static int default_increment = DEFAULT_INC; DynObjectP DynCreate(int el_size, int inc) { DynObjectP obj; obj = (DynObjectP) malloc(sizeof(DynObjectRecP)); if (obj == NULL) return NULL; obj->array = (DynPtr) malloc(1); if (obj->array == NULL) { free(obj); return NULL; } obj->array[0] = '\0'; obj->el_size = el_size; obj->num_el = obj->size = 0; obj->debug = obj->paranoid = 0; obj->inc = (inc) ? inc : default_increment; obj->initzero = 0; return obj; } DynObjectP DynCopy(DynObjectP obj) { DynObjectP obj1; obj1 = (DynObjectP) malloc(sizeof(DynObjectRecP)); if (obj1 == NULL) return NULL; obj1->el_size = obj->el_size; obj1->num_el = obj->num_el; obj1->size = obj->size; obj1->inc = obj->inc; obj1->debug = obj->debug; obj1->paranoid = obj->paranoid; obj1->initzero = obj->initzero; obj1->array = (char *) malloc((size_t) (obj1->el_size * obj1->size)); if (obj1->array == NULL) { free(obj1); return NULL; } memcpy(obj1->array, obj->array, (size_t) (obj1->el_size * obj1->size)); return obj1; } int DynDestroy(/*@only@*/DynObjectP obj) { if (obj->paranoid) { if (obj->debug) fprintf(stderr, "dyn: destroy: zeroing %d bytes from %p.\n", obj->el_size * obj->size, obj->array); memset(obj->array, 0, (size_t) (obj->el_size * obj->size)); } free(obj->array); free(obj); return DYN_OK; } int DynRelease(DynObjectP obj) { if (obj->debug) fprintf(stderr, "dyn: release: freeing object structure.\n"); free(obj); return DYN_OK; } /* old dyn_debug.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynDebug(). */ int DynDebug(DynObjectP obj, int state) { obj->debug = state; fprintf(stderr, "dyn: debug: Debug state set to %d.\n", state); return DYN_OK; } /* old dyn_delete.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynDelete(). */ /* * Checkers! Get away from that "hard disk erase" button! * (Stupid dog. He almost did it to me again ...) */ int DynDelete(DynObjectP obj, int idx) { if (idx < 0) { if (obj->debug) fprintf(stderr, "dyn: delete: bad index %d\n", idx); return DYN_BADINDEX; } if (idx >= obj->num_el) { if (obj->debug) fprintf(stderr, "dyn: delete: Highest index is %d.\n", obj->num_el); return DYN_BADINDEX; } if (idx == obj->num_el-1) { if (obj->paranoid) { if (obj->debug) fprintf(stderr, "dyn: delete: last element, zeroing.\n"); memset(obj->array + idx*obj->el_size, 0, (size_t) obj->el_size); } else { if (obj->debug) fprintf(stderr, "dyn: delete: last element, punting.\n"); } } else { if (obj->debug) fprintf(stderr, "dyn: delete: copying %d bytes from %p + %d to + %d.\n", obj->el_size*(obj->num_el - idx), obj->array, (idx+1)*obj->el_size, idx*obj->el_size); memmove(obj->array + idx*obj->el_size, obj->array + (idx+1)*obj->el_size, (size_t) obj->el_size*(obj->num_el - idx)); if (obj->paranoid) { if (obj->debug) fprintf(stderr, "dyn: delete: zeroing %d bytes from %p + %d\n", obj->el_size, obj->array, obj->el_size*(obj->num_el - 1)); memset(obj->array + obj->el_size*(obj->num_el - 1), 0, (size_t) obj->el_size); } } --obj->num_el; if (obj->debug) fprintf(stderr, "dyn: delete: done.\n"); return DYN_OK; } /* old dyn_initzero.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynInitZero(). */ int DynInitzero(DynObjectP obj, int state) { obj->initzero = state; if (obj->debug) fprintf(stderr, "dyn: initzero: initzero set to %d.\n", state); return DYN_OK; } /* old dyn_insert.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynInsert(). */ int DynInsert(DynObjectP obj, int idx, void *els_in, int num) { DynPtr els = (DynPtr) els_in; int ret; if (idx < 0 || idx > obj->num_el) { if (obj->debug) fprintf(stderr, "dyn: insert: index %d is not in [0,%d]\n", idx, obj->num_el); return DYN_BADINDEX; } if (num < 1) { if (obj->debug) fprintf(stderr, "dyn: insert: cannot insert %d elements\n", num); return DYN_BADVALUE; } if (obj->debug) fprintf(stderr,"dyn: insert: Moving %d bytes from %p + %d to + %d\n", (obj->num_el-idx)*obj->el_size, obj->array, obj->el_size*idx, obj->el_size*(idx+num)); if ((ret = _DynResize(obj, obj->num_el + num)) != DYN_OK) return ret; memmove(obj->array + obj->el_size*(idx + num), obj->array + obj->el_size*idx, (size_t) ((obj->num_el-idx)*obj->el_size)); if (obj->debug) fprintf(stderr, "dyn: insert: Copying %d bytes from %p to %p + %d\n", obj->el_size*num, els, obj->array, obj->el_size*idx); memmove(obj->array + obj->el_size*idx, els, (size_t) (obj->el_size*num)); obj->num_el += num; if (obj->debug) fprintf(stderr, "dyn: insert: done.\n"); return DYN_OK; } /* old dyn_paranoid.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynDebug(). */ int DynParanoid(DynObjectP obj, int state) { obj->paranoid = state; if (obj->debug) fprintf(stderr, "dyn: paranoid: Paranoia set to %d.\n", state); return DYN_OK; } /* old dyn_put.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the functions DynGet() and DynAdd(). */ DynPtr DynArray(DynObjectP obj) { if (obj->debug) fprintf(stderr, "dyn: array: returning array pointer %p.\n", obj->array); return obj->array; } DynPtr DynGet(DynObjectP obj, int num) { if (num < 0) { if (obj->debug) fprintf(stderr, "dyn: get: bad index %d\n", num); return NULL; } if (num >= obj->num_el) { if (obj->debug) fprintf(stderr, "dyn: get: highest element is %d.\n", obj->num_el); return NULL; } if (obj->debug) fprintf(stderr, "dyn: get: Returning address %p + %d.\n", obj->array, obj->el_size*num); return (DynPtr) obj->array + obj->el_size*num; } int DynAdd(DynObjectP obj, void *el) { int ret; ret = DynPut(obj, el, obj->num_el); if (ret != DYN_OK) return ret; ++obj->num_el; return ret; } /* * WARNING! There is a reason this function is not documented in the * man page. If DynPut used to mutate already existing elements, * everything will go fine. If it is used to add new elements * directly, however, the state within the object (such as * obj->num_el) will not be updated properly and many other functions * in the library will lose. Have a nice day. */ int DynPut(DynObjectP obj, void *el_in, int idx) { DynPtr el = (DynPtr) el_in; int ret; if (obj->debug) fprintf(stderr, "dyn: put: Writing %d bytes from %p to %p + %d\n", obj->el_size, el, obj->array, idx*obj->el_size); if ((ret = _DynResize(obj, idx)) != DYN_OK) return ret; memmove(obj->array + idx*obj->el_size, el, (size_t) obj->el_size); if (obj->debug) fprintf(stderr, "dyn: put: done.\n"); return DYN_OK; } /* old dyn_realloc.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the internal function _DynRealloc(). */ /* * Resize the array so that element req exists. */ int _DynResize(DynObjectP obj, int req) { int size; if (obj->size > req) return DYN_OK; else if (obj->inc > 0) return _DynRealloc(obj, (req - obj->size) / obj->inc + 1); else { if (obj->size == 0) size = -obj->inc; else size = obj->size; /*@-shiftsigned@*/ while (size <= req) size <<= 1; /*@=shiftsigned@*/ return _DynRealloc(obj, size); } } /* * Resize the array by num_incs units. If obj->inc is positive, this * means make it obj->inc*num_incs elements larger. If obj->inc is * negative, this means make the array num_incs elements long. * * Ideally, this function should not be called from outside the * library. However, nothing will break if it is. */ int _DynRealloc(DynObjectP obj, int num_incs) { DynPtr temp; int new_size_in_bytes; if (obj->inc > 0) new_size_in_bytes = obj->el_size*(obj->size + obj->inc*num_incs); else new_size_in_bytes = obj->el_size*num_incs; if (obj->debug) fprintf(stderr, "dyn: alloc: Increasing object by %d bytes (%d incs).\n", new_size_in_bytes - obj->el_size*obj->size, num_incs); temp = (DynPtr) realloc(obj->array, (size_t) new_size_in_bytes); if (temp == NULL) { if (obj->debug) fprintf(stderr, "dyn: alloc: Out of memory.\n"); return DYN_NOMEM; } else { obj->array = temp; if (obj->inc > 0) obj->size += obj->inc*num_incs; else obj->size = num_incs; } if (obj->debug) fprintf(stderr, "dyn: alloc: done.\n"); return DYN_OK; } /* old dyn_size.c */ /* * This file is part of libdyn.a, the C Dynamic Object library. It * contains the source code for the function DynSize(). */ int DynSize(DynObjectP obj) { if (obj->debug) fprintf(stderr, "dyn: size: returning size %d.\n", obj->num_el); return obj->num_el; } int DynCapacity(DynObjectP obj) { if (obj->debug) fprintf(stderr, "dyn: capacity: returning cap of %d.\n", obj->size); return obj->size; } /* Old change log, as it relates to source code; build system stuff discarded. 2001-10-09 Ken Raeburn * dyn.h, dynP.h: Make prototypes unconditional. Don't define P(). 2001-04-25 Ezra Peisach * dyn.h: Lclint annotate functions. * dyn_create.c (DynCreate): Do not assume that malloc(0) is valid and returns a valid pointer. Fix memory leak if malloc fails. * dyn_realloc.c (_DynResize): Turn off warning of shifting a signed variable. Thu Nov 9 15:31:31 2000 Ezra Peisach * dyn_create.c (DynCopy): Arguments to memcpy were reversed. Found while playing with lclint. 2000-11-09 Ezra Peisach * dyn_create.c, dyn_delete.c, dyn_insert.c, dyn_put.c, dyn_realloc.c: Cast arguments to malloc(), realloc(), memmove() to size_t. * dynP.h: Provide full prototypes for _DynRealloc() and _DynResize(). * dyn.h: Add prototype for DynAppend. 2000-06-29 Ezra Peisach * dyn_insert.c, dyn_put.c: Include string.h for memmove prototype. 2000-06-28 Ezra Peisach * dyn_create.c, dyn_delete.c, dyn_insert.c, dyn_put.c: Use %p format for displaying pointers. 2000-06-26 Ezra Peisach * dyn_realloc.c: Remove unused variable. Sat Dec 6 22:50:03 1997 Ezra Peisach * dyn_delete.c: Include Mon Jul 22 21:37:52 1996 Ezra Peisach * dyn.h: If __STDC__ is not defined, generate prototypes implying functions and not variables. Mon Jul 22 04:20:48 1996 Marc Horowitz * dyn_insert.c (DynInsert): what used to be #ifdef POSIX, should be #ifdef HAVE_MEMMOVE */ krb5-1.22.1/src/lib/rpc/xdr.c0000664000175000017500000003106215051422640015425 0ustar ghudsonghudson/* @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * * Neither the name of the "Oracle America, Inc." nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if !defined(lint) && defined(SCCSIDS) static char sccsid[] = "@(#)xdr.c 1.35 87/08/12"; #endif /* * xdr.c, Generic XDR routines implementation. * * These are the "generic" xdr routines used to serialize and de-serialize * most common data items. See xdr.h for more info on the interface to * xdr. */ #include #include #include #include /* * constants specific to the xdr "protocol" */ #define XDR_FALSE ((long) 0) #define XDR_TRUE ((long) 1) #define LASTUNSIGNED ((u_int) 0-1) #ifdef USE_VALGRIND #include #else #define VALGRIND_CHECK_DEFINED(LVALUE) ((void)0) #define VALGRIND_CHECK_READABLE(PTR,SIZE) ((void)0) #endif /* * for unit alignment */ static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; /* * Free a data structure using XDR * Not a filter, but a convenient utility nonetheless */ void xdr_free(xdrproc_t proc, void *objp) { XDR x; x.x_op = XDR_FREE; (*proc)(&x, objp); } /* * XDR nothing */ bool_t xdr_void(XDR *xdrs, void *addr) { return (TRUE); } /* * XDR integers */ bool_t xdr_int(XDR *xdrs, int *ip) { long l; switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*ip); if (*ip > 0x7fffffffL || *ip < -0x7fffffffL - 1L) return (FALSE); l = (long) *ip; return (XDR_PUTLONG(xdrs, &l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, &l)) return (FALSE); if (l > INT_MAX || l < INT_MIN) return (FALSE); *ip = (int) l; case XDR_FREE: return (TRUE); } /*NOTREACHED*/ return(FALSE); } /* * XDR unsigned integers */ bool_t xdr_u_int(XDR *xdrs, u_int *up) { u_long l; switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*up); if (*up > 0xffffffffUL) return (FALSE); l = (u_long)*up; return (XDR_PUTLONG(xdrs, (long *) &l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, (long *) &l)) return (FALSE); if ((uint32_t)l > UINT_MAX) return (FALSE); *up = (u_int) l; return (TRUE); case XDR_FREE: return (TRUE); } /*NOTREACHED*/ return(FALSE); } /* * XDR long integers */ bool_t xdr_long(XDR *xdrs, long *lp) { switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*lp); if (*lp > 0x7fffffffL || *lp < -0x7fffffffL - 1L) return (FALSE); return (XDR_PUTLONG(xdrs, lp)); case XDR_DECODE: return (XDR_GETLONG(xdrs, lp)); case XDR_FREE: return (TRUE); } return (FALSE); } /* * XDR unsigned long integers */ bool_t xdr_u_long(XDR *xdrs, u_long *ulp) { switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*ulp); if (*ulp > 0xffffffffUL) return (FALSE); return (XDR_PUTLONG(xdrs, (long *) ulp)); case XDR_DECODE: return (XDR_GETLONG(xdrs, (long *) ulp)); case XDR_FREE: return (TRUE); } return (FALSE); } /* * XDR short integers */ bool_t xdr_short(XDR *xdrs, short *sp) { long l; switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*sp); l = (long) *sp; return (XDR_PUTLONG(xdrs, &l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, &l)) { return (FALSE); } if (l > SHRT_MAX || l < SHRT_MIN) return (FALSE); *sp = (short) l; return (TRUE); case XDR_FREE: return (TRUE); } return (FALSE); } /* * XDR unsigned short integers */ bool_t xdr_u_short(XDR *xdrs, u_short *usp) { u_long l; switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*usp); l = (u_long) *usp; return (XDR_PUTLONG(xdrs, (long *) &l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, (long *) &l)) { return (FALSE); } *usp = (u_short) l; return (TRUE); case XDR_FREE: return (TRUE); } return (FALSE); } /* * XDR a char */ bool_t xdr_char(XDR *xdrs, char *cp) { int i; switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*cp); break; default: break; } i = (*cp); if (!xdr_int(xdrs, &i)) { return (FALSE); } *cp = i; return (TRUE); } /* * XDR an unsigned char */ bool_t xdr_u_char(XDR *xdrs, u_char *cp) { u_int u; switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*cp); break; default: break; } u = (*cp); if (!xdr_u_int(xdrs, &u)) { return (FALSE); } *cp = u; return (TRUE); } /* * XDR booleans */ bool_t xdr_bool(XDR *xdrs, bool_t *bp) { long lb; switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*bp); lb = *bp ? XDR_TRUE : XDR_FALSE; return (XDR_PUTLONG(xdrs, &lb)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, &lb)) { return (FALSE); } *bp = (lb == XDR_FALSE) ? FALSE : TRUE; return (TRUE); case XDR_FREE: return (TRUE); } return (FALSE); } /* * XDR enumerations */ bool_t xdr_enum(XDR *xdrs, enum_t *ep) { #ifndef lint enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ /* * enums are treated as ints */ switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*ep); break; default: break; } if (sizeof (enum sizecheck) == sizeof (long)) { return (xdr_long(xdrs, (long *)(void *)ep)); } else if (sizeof (enum sizecheck) == sizeof (int)) { return (xdr_int(xdrs, (int *)(void *)ep)); } else if (sizeof (enum sizecheck) == sizeof (short)) { return (xdr_short(xdrs, (short *)(void *)ep)); } else { return (FALSE); } #else (void) (xdr_short(xdrs, (short *)(void *)ep)); return (xdr_long(xdrs, (long *)(void *)ep)); #endif } /* * XDR opaque data * Allows the specification of a fixed size sequence of opaque bytes. * cp points to the opaque object and cnt gives the byte length. */ bool_t xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt) { u_int rndup; static int crud[BYTES_PER_XDR_UNIT]; /* * if no data we are done */ if (cnt == 0) return (TRUE); /* * round byte count to full xdr units */ rndup = cnt % BYTES_PER_XDR_UNIT; if (rndup > 0) rndup = BYTES_PER_XDR_UNIT - rndup; if (xdrs->x_op == XDR_DECODE) { if (!XDR_GETBYTES(xdrs, cp, cnt)) { return (FALSE); } if (rndup == 0) return (TRUE); return (XDR_GETBYTES(xdrs, (caddr_t) (void *)crud, rndup)); } if (xdrs->x_op == XDR_ENCODE) { VALGRIND_CHECK_READABLE((volatile void *)cp, cnt); if (!XDR_PUTBYTES(xdrs, cp, cnt)) { return (FALSE); } if (rndup == 0) return (TRUE); return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); } if (xdrs->x_op == XDR_FREE) { return (TRUE); } return (FALSE); } /* * XDR counted bytes * *cpp is a pointer to the bytes, *sizep is the count. * If *cpp is NULL maxsize bytes are allocated */ bool_t xdr_bytes( XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) { char *sp = *cpp; /* sp is the actual string pointer */ u_int nodesize; /* * first deal with the length since xdr bytes are counted */ if (! xdr_u_int(xdrs, sizep)) { return (FALSE); } nodesize = *sizep; if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { return (FALSE); } /* * now deal with the actual bytes */ switch (xdrs->x_op) { case XDR_DECODE: if (nodesize == 0) { return (TRUE); } if (sp == NULL) { *cpp = sp = (char *)mem_alloc(nodesize); } if (sp == NULL) { (void) fprintf(stderr, "xdr_bytes: out of memory\n"); return (FALSE); } /* fall into ... */ case XDR_ENCODE: return (xdr_opaque(xdrs, sp, nodesize)); case XDR_FREE: if (sp != NULL) { mem_free(sp, nodesize); *cpp = NULL; } return (TRUE); } return (FALSE); } /* * Implemented here due to commonality of the object. */ bool_t xdr_netobj(XDR *xdrs, struct netobj *np) { return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); } bool_t xdr_int32(XDR *xdrs, int32_t *ip) { long l; switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*ip); l = *ip; return (xdr_long(xdrs, &l)); case XDR_DECODE: if (!xdr_long(xdrs, &l)) { return (FALSE); } *ip = l; return (TRUE); case XDR_FREE: return (TRUE); } return (FALSE); } bool_t xdr_u_int32(XDR *xdrs, uint32_t *up) { u_long ul; switch (xdrs->x_op) { case XDR_ENCODE: VALGRIND_CHECK_DEFINED(*up); ul = *up; return (xdr_u_long(xdrs, &ul)); case XDR_DECODE: if (!xdr_u_long(xdrs, &ul)) { return (FALSE); } *up = ul; return (TRUE); case XDR_FREE: return (TRUE); } return (FALSE); } /* * XDR a discriminated union * Support routine for discriminated unions. * You create an array of xdrdiscrim structures, terminated with * an entry with a null procedure pointer. The routine gets * the discriminant value and then searches the array of xdrdiscrims * looking for that value. It calls the procedure given in the xdrdiscrim * to handle the discriminant. If there is no specific routine a default * routine may be called. * If there is no specific or default routine an error is returned. */ bool_t xdr_union( XDR *xdrs, enum_t *dscmp, /* enum to decide which arm to work on */ char *unp, /* the union itself */ struct xdr_discrim *choices, /* [value, xdr proc] for each arm */ xdrproc_t dfault /* default xdr routine */ ) { enum_t dscm; /* * we deal with the discriminator; it's an enum */ if (! xdr_enum(xdrs, dscmp)) { return (FALSE); } dscm = *dscmp; /* * search choices for a value that matches the discriminator. * if we find one, execute the xdr routine for that value. */ for (; choices->proc != NULL_xdrproc_t; choices++) { if (choices->value == dscm) return choices->proc(xdrs, unp); } /* * no match - execute the default xdr routine if there is one */ return ((dfault == NULL_xdrproc_t) ? FALSE : (*dfault)(xdrs, unp)); } /* * Non-portable xdr primitives. * Care should be taken when moving these routines to new architectures. */ /* * XDR null terminated ASCII strings * xdr_string deals with "C strings" - arrays of bytes that are * terminated by a NULL character. The parameter cpp references a * pointer to storage; If the pointer is null, then the necessary * storage is allocated. The last parameter is the max allowed length * of the string as specified by a protocol. */ bool_t xdr_string(XDR *xdrs, char **cpp, u_int maxsize) { char *sp = *cpp; /* sp is the actual string pointer */ u_int size; u_int nodesize; /* * first deal with the length since xdr strings are counted-strings */ switch (xdrs->x_op) { case XDR_FREE: if (sp == NULL) { return(TRUE); /* already free */ } /* fall through... */ case XDR_ENCODE: size = strlen(sp); break; case XDR_DECODE: break; } if (! xdr_u_int(xdrs, &size)) { return (FALSE); } if (size >= maxsize) { return (FALSE); } nodesize = size + 1; /* * now deal with the actual bytes */ switch (xdrs->x_op) { case XDR_DECODE: if (nodesize == 0) { return (TRUE); } if (sp == NULL) *cpp = sp = (char *)mem_alloc(nodesize); if (sp == NULL) { (void) fprintf(stderr, "xdr_string: out of memory\n"); return (FALSE); } sp[size] = 0; /* fall into ... */ case XDR_ENCODE: return (xdr_opaque(xdrs, sp, size)); case XDR_FREE: mem_free(sp, nodesize); *cpp = NULL; return (TRUE); } return (FALSE); } /* * Wrapper for xdr_string that can be called directly from * routines like clnt_call */ bool_t xdr_wrapstring(XDR *xdrs, char **cpp) { if (xdr_string(xdrs, cpp, LASTUNSIGNED)) { return (TRUE); } return (FALSE); } krb5-1.22.1/src/lib/gssapi32.def0000664000175000017500000001305215051422640016012 0ustar ghudsonghudson;---------------------------------------------------- ; GSSAPI32.DEF - GSSAPI32.DLL module definition file ;---------------------------------------------------- ;LIBRARY GSSAPI32 DESCRIPTION 'Base Generic Security Service API' HEAPSIZE 8192 EXPORTS gss_acquire_cred @10 gss_release_cred @54 gss_init_sec_context @27 gss_accept_sec_context @9 gss_process_context_token @52 gss_delete_sec_context @17 gss_context_time @15 gss_sign @59 gss_verify @64 gss_seal @58 gss_unseal @62 gss_display_status @19 gss_indicate_mechs @26 gss_compare_name @14 gss_display_name @18 gss_import_name @24 gss_release_name @55 gss_release_buffer @53 gss_release_oid_set @57 gss_inquire_cred @29 ; ; GSS-API v2 additional credential calls ; gss_add_cred @11 gss_inquire_cred_by_mech @30 ; ; GSS-API v2 additional context-level calls ; gss_inquire_context @28 gss_wrap_size_limit @67 gss_export_sec_context @22 gss_import_sec_context @25 ; ; GSS-API v2 additional calls for OID and OID_set operations ; gss_release_oid gss_create_empty_oid_set @16 gss_add_oid_set_member @12 gss_test_oid_set_member @61 gss_oid_to_str @51 gss_str_to_oid @60 ; ; GSS-API v2 renamed message protection calls ; gss_wrap @66 gss_unwrap @63 gss_get_mic @23 gss_verify_mic @65 ; ; GSS-API v2 future extensions ; gss_inquire_names_for_mech @32 gss_inquire_mechs_for_name @31 gss_canonicalize_name @13 gss_export_name @21 gss_duplicate_name @20 ; ; Krb5 specific function extensions ; gss_krb5_get_tkt_flags @37 gss_krb5_copy_ccache @34 gss_krb5_ccache_name @33 gss_krb5_set_allowable_enctypes @38 gss_krb5_export_lucid_sec_context @35 gss_krb5_free_lucid_sec_context @36 krb5_gss_register_acceptor_identity @69 ; ; GSS-API variables ; gss_nt_krb5_name @45 DATA gss_nt_krb5_principal @46 DATA gss_nt_user_name @50 DATA gss_nt_machine_uid_name @47 DATA gss_nt_string_uid_name @49 DATA gss_nt_service_name @48 DATA GSS_C_NT_USER_NAME @7 DATA GSS_C_NT_MACHINE_UID_NAME @5 DATA GSS_C_NT_STRING_UID_NAME @6 DATA GSS_C_NT_HOSTBASED_SERVICE @3 DATA GSS_C_NT_HOSTBASED_SERVICE_X @4 DATA GSS_C_NT_ANONYMOUS @1 DATA GSS_C_NT_EXPORT_NAME @2 DATA krb5_gss_oid_array @68 DATA gss_mech_krb5 @39 DATA gss_mech_krb5_old @40 DATA gss_mech_set_krb5 @42 DATA gss_mech_set_krb5_old @44 DATA gss_mech_set_krb5_both @43 DATA GSS_KRB5_NT_PRINCIPAL_NAME @8 DATA gss_mech_krb5_wrong @41 DATA ; Added in krb5 1.7-1.9 gss_acquire_cred_impersonate_name @70 gss_acquire_cred_with_password @71 gss_add_buffer_set_member @72 gss_add_cred_impersonate_name @73 gss_complete_auth_token @74 gss_create_empty_buffer_set @75 gss_delete_name_attribute @76 gss_display_mech_attr @77 gss_display_name_ext @78 gss_export_name_composite @79 gss_get_name_attribute @80 gss_indicate_mechs_by_attrs @81 gss_inquire_attrs_for_mech @82 gss_inquire_cred_by_oid @83 gss_inquire_mech_for_saslname @84 gss_inquire_name @85 gss_inquire_saslname_for_mech @86 gss_inquire_sec_context_by_oid @87 gsskrb5_extract_authtime_from_sec_context @88 gsskrb5_extract_authz_data_from_sec_context @89 gss_krb5_import_cred @90 gss_krb5_set_cred_rcache @91 gss_map_name_to_any @92 gss_pseudo_random @93 gss_release_any_name_mapping @94 gss_release_buffer_set @95 gss_release_iov_buffer @96 gss_set_cred_option @97 gss_set_name_attribute @98 gss_set_neg_mechs @99 gss_set_sec_context_option @100 gss_store_cred @101 gss_unwrap_aead @102 gss_unwrap_iov @103 gss_wrap_aead @104 gss_wrap_iov @105 gss_wrap_iov_length @106 GSS_C_INQ_SSPI_SESSION_KEY @107 DATA GSS_C_MA_AUTH_INIT @108 DATA GSS_C_MA_AUTH_INIT_ANON @109 DATA GSS_C_MA_AUTH_INIT_INIT @110 DATA GSS_C_MA_AUTH_TARG @111 DATA GSS_C_MA_AUTH_TARG_ANON @112 DATA GSS_C_MA_AUTH_TARG_INIT @113 DATA GSS_C_MA_CBINDINGS @114 DATA GSS_C_MA_COMPRESS @115 DATA GSS_C_MA_CONF_PROT @116 DATA GSS_C_MA_CTX_TRANS @117 DATA GSS_C_MA_DELEG_CRED @118 DATA GSS_C_MA_DEPRECATED @119 DATA GSS_C_MA_INTEG_PROT @120 DATA GSS_C_MA_ITOK_FRAMED @121 DATA GSS_C_MA_MECH_COMPOSITE @122 DATA GSS_C_MA_MECH_CONCRETE @123 DATA GSS_C_MA_MECH_GLUE @124 DATA GSS_C_MA_MECH_NEGO @125 DATA GSS_C_MA_MECH_PSEUDO @126 DATA GSS_C_MA_MIC @127 DATA GSS_C_MA_NOT_DFLT_MECH @128 DATA GSS_C_MA_NOT_MECH @129 DATA GSS_C_MA_OOS_DET @130 DATA GSS_C_MA_PFS @131 DATA GSS_C_MA_PROT_READY @132 DATA GSS_C_MA_REPLAY_DET @133 DATA GSS_C_MA_WRAP @134 DATA gss_mech_iakerb @135 DATA gss_nt_exported_name @136 DATA gss_nt_service_name_v2 @137 DATA ; Added in 1.10 gss_localname @138 ; Added in 1.11 gss_acquire_cred_from @139 gss_add_cred_from @140 gss_store_cred_into @141 gss_export_cred @142 gss_import_cred @143 ; Added in 1.12 gss_get_mic_iov @144 gss_get_mic_iov_length @145 gss_verify_mic_iov @146 ; Added in 1.14 GSS_KRB5_CRED_NO_CI_FLAGS_X @147 DATA ; Added in 1.16 GSS_KRB5_GET_CRED_IMPERSONATOR @148 DATA GSS_C_SEC_CONTEXT_SASL_SSF @149 DATA ; Added in 1.17 GSS_KRB5_NT_ENTERPRISE_NAME @150 DATA ; Added in 1.19 GSS_KRB5_NT_X509_CERT @151 DATA krb5-1.22.1/src/lib/apputils/0000775000175000017500000000000015051422640015537 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/apputils/daemon.c0000664000175000017500000000554715051422640017161 0ustar ghudsonghudson/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */ /* * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "k5-int.h" #include #include #include #include #ifdef HAVE_PATHS_H #include #endif #ifndef _PATH_DEVNULL #define _PATH_DEVNULL "/dev/null" #endif int daemon(nochdir, noclose) int nochdir, noclose; { int cpid; if ((cpid = fork()) == -1) return (-1); if (cpid) exit(0); #ifdef HAVE_SETSID (void) setsid(); #else #ifndef TIOCNOTTY setpgrp(); #else { int n; /* * The open below may hang on pseudo ttys if the person * who starts named logs out before this point. Thus, * the need for the timer. */ alarm(120); n = open("/dev/tty", O_RDWR); alarm(0); if (n > 0) { (void) ioctl(n, TIOCNOTTY, (char *)NULL); (void) close(n); } } #endif #endif if (!nochdir) (void) chdir("/"); if (!noclose) { int devnull = open(_PATH_DEVNULL, O_RDWR, 0); if (devnull != -1) { (void) dup2(devnull, 0); (void) dup2(devnull, 1); (void) dup2(devnull, 2); if (devnull > 2) (void) close(devnull); } } return (0); } krb5-1.22.1/src/lib/apputils/Makefile.in0000664000175000017500000000116715051422640017611 0ustar ghudsonghudsonprefix=@prefix@ bindir=@bindir@ datadir=@datadir@ mydatadir=$(datadir)/apputils mydir=lib$(S)apputils BUILDTOP=$(REL)..$(S).. RELDIR=../lib/apputils SED = sed ##DOS##BUILDTOP = ..\.. ##DOS##LIBNAME=$(OUTPRE)apputils.lib ##DOS##XTRA= ##DOS##OBJFILE=$(OUTPRE)apputils.lst STLIBOBJS=net-server.o udppktinfo.o @LIBOBJS@ LIBBASE=apputils all-unix: all-liblinks clean-unix:: clean-liblinks clean-libs clean-libobjs install-unix: install-libs LINTFLAGS=-uhvb LINTFILES= daemon.c LIBOBJS=$(OUTPRE)daemon.$(OBJEXT) SRCS= $(srcdir)/daemon.c \ $(srcdir)/net-server.c \ $(srcdir)/udppktinfo.c @libpriv_frag@ @lib_frag@ @libobj_frag@ krb5-1.22.1/src/lib/apputils/deps0000664000175000017500000000553315051422640016423 0ustar ghudsonghudson# # Generated makefile dependencies follow. # daemon.so daemon.po $(OUTPRE)daemon.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h daemon.c net-server.so net-server.po $(OUTPRE)net-server.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(VERTO_DEPS) $(top_srcdir)/include/adm_proto.h \ $(top_srcdir)/include/fake-addrinfo.h $(top_srcdir)/include/foreachaddr.h \ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/net-server.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h net-server.c udppktinfo.h udppktinfo.so udppktinfo.po $(OUTPRE)udppktinfo.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ udppktinfo.c udppktinfo.h krb5-1.22.1/src/lib/apputils/udppktinfo.h0000664000175000017500000000422015051422640020071 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2016 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef UDPPKTINFO_H #define UDPPKTINFO_H #include "k5-int.h" /* * This holds whatever additional information might be needed to * properly send back to the client from the correct local address. * * In this case, we only need one datum so far: On macOS, the * kernel doesn't seem to like sending from link-local addresses * unless we specify the correct interface. */ typedef union aux_addressing_info { int ipv6_ifindex; } aux_addressing_info; krb5_error_code set_pktinfo(int sock, int family); krb5_error_code recv_from_to(int sock, void *buf, size_t len, int flags, struct sockaddr_storage *from, struct sockaddr_storage *to, aux_addressing_info *auxaddr); krb5_error_code send_to_from(int sock, void *buf, size_t len, int flags, const struct sockaddr *to, const struct sockaddr *from, aux_addressing_info *auxaddr); #endif /* UDPPKTINFO_H */ krb5-1.22.1/src/lib/apputils/udppktinfo.c0000664000175000017500000003502015051422640020066 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2016 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* macOS requires this define for IPV6_PKTINFO. */ #define __APPLE_USE_RFC_3542 #include "udppktinfo.h" #include #include #if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO) #define HAVE_IP_PKTINFO #endif #if defined(IPV6_PKTINFO) && defined(HAVE_STRUCT_IN6_PKTINFO) #define HAVE_IPV6_PKTINFO #endif #if defined(HAVE_IP_PKTINFO) || defined(IP_SENDSRCADDR) || \ defined(HAVE_IPV6_PKTINFO) #define HAVE_PKTINFO_SUPPORT #endif /* Use RFC 3542 API below, but fall back from IPV6_RECVPKTINFO to IPV6_PKTINFO * for RFC 2292 implementations. */ #if !defined(IPV6_RECVPKTINFO) && defined(IPV6_PKTINFO) #define IPV6_RECVPKTINFO IPV6_PKTINFO #endif /* Parallel, though not standardized. */ #if !defined(IP_RECVPKTINFO) && defined(IP_PKTINFO) #define IP_RECVPKTINFO IP_PKTINFO #endif /* IP_RECVPKTINFO */ #if defined(CMSG_SPACE) && defined(HAVE_STRUCT_CMSGHDR) && \ defined(HAVE_PKTINFO_SUPPORT) union pktinfo { #ifdef HAVE_STRUCT_IN6_PKTINFO struct in6_pktinfo pi6; #endif #ifdef HAVE_STRUCT_IN_PKTINFO struct in_pktinfo pi4; #endif #ifdef IP_RECVDSTADDR struct in_addr iaddr; #endif char c; }; #endif /* HAVE_IPV6_PKTINFO && HAVE_STRUCT_CMSGHDR && HAVE_PKTINFO_SUPPORT */ #ifdef HAVE_IP_PKTINFO #define set_ipv4_pktinfo set_ipv4_recvpktinfo static inline krb5_error_code set_ipv4_recvpktinfo(int sock) { int sockopt = 1; return setsockopt(sock, IPPROTO_IP, IP_RECVPKTINFO, &sockopt, sizeof(sockopt)); } #elif defined(IP_RECVDSTADDR) /* HAVE_IP_PKTINFO */ #define set_ipv4_pktinfo set_ipv4_recvdstaddr static inline krb5_error_code set_ipv4_recvdstaddr(int sock) { int sockopt = 1; return setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, &sockopt, sizeof(sockopt)); } #else /* HAVE_IP_PKTINFO || IP_RECVDSTADDR */ #define set_ipv4_pktinfo(s) EINVAL #endif /* HAVE_IP_PKTINFO || IP_RECVDSTADDR */ #ifdef HAVE_IPV6_PKTINFO #define set_ipv6_pktinfo set_ipv6_recvpktinfo static inline krb5_error_code set_ipv6_recvpktinfo(int sock) { int sockopt = 1; return setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &sockopt, sizeof(sockopt)); } #else /* HAVE_IPV6_PKTINFO */ #define set_ipv6_pktinfo(s) EINVAL #endif /* HAVE_IPV6_PKTINFO */ /* * Set pktinfo option on a socket. Takes a socket and the socket address family * as arguments. * * Returns 0 on success, EINVAL if pktinfo is not supported for the address * family. */ krb5_error_code set_pktinfo(int sock, int family) { switch (family) { case AF_INET: return set_ipv4_pktinfo(sock); case AF_INET6: return set_ipv6_pktinfo(sock); default: return EINVAL; } } #if defined(HAVE_PKTINFO_SUPPORT) && defined(CMSG_SPACE) /* * Check if a socket is bound to a wildcard address. * Returns 1 if it is, 0 if it's bound to a specific address, or -1 on error * with errno set to the error. */ static int is_socket_bound_to_wildcard(int sock) { struct sockaddr_storage bound_addr; socklen_t bound_addr_len = sizeof(bound_addr); struct sockaddr *sa = ss2sa(&bound_addr); if (getsockname(sock, sa, &bound_addr_len) < 0) return -1; if (!sa_is_inet(sa)) { errno = EINVAL; return -1; } return sa_is_wildcard(sa); } #ifdef HAVE_IP_PKTINFO static inline struct in_pktinfo * cmsg2pktinfo(struct cmsghdr *cmsgptr) { return (struct in_pktinfo *)(void *)CMSG_DATA(cmsgptr); } #define check_cmsg_v4_pktinfo check_cmsg_ip_pktinfo static int check_cmsg_ip_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr_in *to, aux_addressing_info *auxaddr) { struct in_pktinfo *pktinfo; if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO) { memset(to, 0, sizeof(*to)); pktinfo = cmsg2pktinfo(cmsgptr); to->sin_addr = pktinfo->ipi_addr; to->sin_family = AF_INET; return 1; } return 0; } #elif defined(IP_RECVDSTADDR) /* HAVE_IP_PKTINFO */ static inline struct in_addr * cmsg2sin(struct cmsghdr *cmsgptr) { return (struct in_addr *)(void *)CMSG_DATA(cmsgptr); } #define check_cmsg_v4_pktinfo check_cmsg_ip_recvdstaddr static int check_cmsg_ip_recvdstaddr(struct cmsghdr *cmsgptr, struct sockaddr_in *to, aux_addressing_info *auxaddr) { struct in_addr *sin_addr; if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVDSTADDR) { memset(to, 0, sizeof(*to)); sin_addr = cmsg2sin(cmsgptr); to->sin_addr = *sin_addr; to->sin_family = AF_INET; return 1; } return 0; } #else /* HAVE_IP_PKTINFO || IP_RECVDSTADDR */ #define check_cmsg_v4_pktinfo(c, t, l, a) 0 #endif /* HAVE_IP_PKTINFO || IP_RECVDSTADDR */ #ifdef HAVE_IPV6_PKTINFO static inline struct in6_pktinfo * cmsg2pktinfo6(struct cmsghdr *cmsgptr) { return (struct in6_pktinfo *)(void *)CMSG_DATA(cmsgptr); } #define check_cmsg_v6_pktinfo check_cmsg_ipv6_pktinfo static int check_cmsg_ipv6_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr_in6 *to, aux_addressing_info *auxaddr) { struct in6_pktinfo *pktinfo; if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO) { memset(to, 0, sizeof(*to)); pktinfo = cmsg2pktinfo6(cmsgptr); to->sin6_addr = pktinfo->ipi6_addr; to->sin6_family = AF_INET6; auxaddr->ipv6_ifindex = pktinfo->ipi6_ifindex; return 1; } return 0; } #else /* HAVE_IPV6_PKTINFO */ #define check_cmsg_v6_pktinfo(c, t, l, a) 0 #endif /* HAVE_IPV6_PKTINFO */ static int check_cmsg_pktinfo(struct cmsghdr *cmsgptr, struct sockaddr_storage *to, aux_addressing_info *auxaddr) { return check_cmsg_v4_pktinfo(cmsgptr, ss2sin(to), auxaddr) || check_cmsg_v6_pktinfo(cmsgptr, ss2sin6(to), auxaddr); } /* * Receive a message from a socket. * * Arguments: * sock * buf - The buffer to store the message in. * len - buf length * flags * from - Set to the address that sent the message * to - Set to the address that the message was sent to if possible. * May not be set in certain cases such as if pktinfo support is * missing. May be NULL. * auxaddr - Miscellaneous address information. * * Returns 0 on success, otherwise an error code. */ krb5_error_code recv_from_to(int sock, void *buf, size_t len, int flags, struct sockaddr_storage *from, struct sockaddr_storage *to, aux_addressing_info *auxaddr) { int r; struct iovec iov; char cmsg[CMSG_SPACE(sizeof(union pktinfo))]; struct cmsghdr *cmsgptr; struct msghdr msg; socklen_t fromlen = sizeof(*from); /* Don't use pktinfo if the socket isn't bound to a wildcard address. */ r = is_socket_bound_to_wildcard(sock); if (r < 0) return errno; if (to == NULL || !r) return recvfrom(sock, buf, len, flags, ss2sa(from), &fromlen); /* Clobber with something recognizable in case we can't extract the address * but try to use it anyways. */ memset(to, 0x40, sizeof(*to)); to->ss_family = AF_UNSPEC; iov.iov_base = buf; iov.iov_len = len; memset(&msg, 0, sizeof(msg)); msg.msg_name = ss2sa(from); msg.msg_namelen = sizeof(*from); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = cmsg; msg.msg_controllen = sizeof(cmsg); r = recvmsg(sock, &msg, flags); if (r < 0) return r; /* * On Darwin (and presumably all *BSD with KAME stacks), CMSG_FIRSTHDR * doesn't check for a non-zero controllen. RFC 3542 recommends making * this check, even though the (new) spec for CMSG_FIRSTHDR says it's * supposed to do the check. */ if (msg.msg_controllen) { cmsgptr = CMSG_FIRSTHDR(&msg); while (cmsgptr) { if (check_cmsg_pktinfo(cmsgptr, to, auxaddr)) return r; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr); } } /* No info about destination addr was available. */ return r; } #ifdef HAVE_IP_PKTINFO #define set_msg_from_ipv4 set_msg_from_ip_pktinfo static krb5_error_code set_msg_from_ip_pktinfo(struct msghdr *msg, struct cmsghdr *cmsgptr, const struct sockaddr_in *from, aux_addressing_info *auxaddr) { struct in_pktinfo *p = cmsg2pktinfo(cmsgptr); cmsgptr->cmsg_level = IPPROTO_IP; cmsgptr->cmsg_type = IP_PKTINFO; cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); p->ipi_spec_dst = from->sin_addr; msg->msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); return 0; } #elif defined(IP_SENDSRCADDR) /* HAVE_IP_PKTINFO */ #define set_msg_from_ipv4 set_msg_from_ip_sendsrcaddr static krb5_error_code set_msg_from_ip_sendsrcaddr(struct msghdr *msg, struct cmsghdr *cmsgptr, const struct sockaddr_in *from, aux_addressing_info *auxaddr) { struct in_addr *sin_addr = cmsg2sin(cmsgptr); cmsgptr->cmsg_level = IPPROTO_IP; cmsgptr->cmsg_type = IP_SENDSRCADDR; cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); msg->msg_controllen = CMSG_SPACE(sizeof(struct in_addr)); *sin_addr = from->sin_addr; return 0; } #else /* HAVE_IP_PKTINFO || IP_SENDSRCADDR */ #define set_msg_from_ipv4(m, c, f, l, a) EINVAL #endif /* HAVE_IP_PKTINFO || IP_SENDSRCADDR */ #ifdef HAVE_IPV6_PKTINFO #define set_msg_from_ipv6 set_msg_from_ipv6_pktinfo static krb5_error_code set_msg_from_ipv6_pktinfo(struct msghdr *msg, struct cmsghdr *cmsgptr, const struct sockaddr_in6 *from, aux_addressing_info *auxaddr) { struct in6_pktinfo *p = cmsg2pktinfo6(cmsgptr); cmsgptr->cmsg_level = IPPROTO_IPV6; cmsgptr->cmsg_type = IPV6_PKTINFO; cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); p->ipi6_addr = from->sin6_addr; /* * Because of the possibility of asymmetric routing, we * normally don't want to specify an interface. However, * macOS doesn't like sending from a link-local address * (which can come up in testing at least, if you wind up * with a "foo.local" name) unless we do specify the * interface. */ if (IN6_IS_ADDR_LINKLOCAL(&from->sin6_addr)) p->ipi6_ifindex = auxaddr->ipv6_ifindex; /* otherwise, already zero */ msg->msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); return 0; } #else /* HAVE_IPV6_PKTINFO */ #define set_msg_from_ipv6(m, c, f, l, a) EINVAL #endif /* HAVE_IPV6_PKTINFO */ static krb5_error_code set_msg_from(struct msghdr *msg, struct cmsghdr *cmsgptr, const struct sockaddr *from, aux_addressing_info *auxaddr) { switch (from->sa_family) { case AF_INET: return set_msg_from_ipv4(msg, cmsgptr, sa2sin(from), auxaddr); case AF_INET6: return set_msg_from_ipv6(msg, cmsgptr, sa2sin6(from), auxaddr); } return EINVAL; } /* * Send a message to an address. * * Arguments: * sock * buf - The message to send. * len - buf length * flags * to - The address to send the message to. * from - The address to attempt to send the message from. May be NULL. * auxaddr - Miscellaneous address information. * * Returns 0 on success, otherwise an error code. */ krb5_error_code send_to_from(int sock, void *buf, size_t len, int flags, const struct sockaddr *to, const struct sockaddr *from, aux_addressing_info *auxaddr) { int r; struct iovec iov; struct msghdr msg; struct cmsghdr *cmsgptr; char cbuf[CMSG_SPACE(sizeof(union pktinfo))]; /* Don't use pktinfo if the socket isn't bound to a wildcard address. */ r = is_socket_bound_to_wildcard(sock); if (r < 0) return errno; if (from == NULL || from->sa_family != to->sa_family || !r) goto use_sendto; iov.iov_base = buf; iov.iov_len = len; /* Truncation? */ if (iov.iov_len != len) return EINVAL; memset(cbuf, 0, sizeof(cbuf)); memset(&msg, 0, sizeof(msg)); msg.msg_name = (void *)to; msg.msg_namelen = sa_socklen(to); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = cbuf; /* CMSG_FIRSTHDR needs a non-zero controllen, or it'll return NULL on * Linux. */ msg.msg_controllen = sizeof(cbuf); cmsgptr = CMSG_FIRSTHDR(&msg); msg.msg_controllen = 0; if (set_msg_from(&msg, cmsgptr, from, auxaddr)) goto use_sendto; return sendmsg(sock, &msg, flags); use_sendto: return sendto(sock, buf, len, flags, to, sa_socklen(to)); } #else /* HAVE_PKTINFO_SUPPORT && CMSG_SPACE */ krb5_error_code recv_from_to(int sock, void *buf, size_t len, int flags, struct sockaddr_storage *from, struct sockaddr_storage *to, aux_addressing_info *auxaddr) { socklen_t fromlen = sizeof(*from); if (to != NULL) { /* Clobber with something recognizable in case we try to use the * address. */ memset(to, 0x40, sizeof(*to)); to->ss_family = AF_UNSPEC; } return recvfrom(sock, buf, len, flags, ss2sa(from), &fromlen); } krb5_error_code send_to_from(int sock, void *buf, size_t len, int flags, const struct sockaddr *to, const struct sockaddr *from, aux_addressing_info *auxaddr) { return sendto(sock, buf, len, flags, to, sa_socklen(to)); } #endif /* HAVE_PKTINFO_SUPPORT && CMSG_SPACE */ krb5-1.22.1/src/lib/apputils/net-server.c0000664000175000017500000013451615051422640020007 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/apputils/net-server.c - Network code for krb5 servers (kdc, kadmind) */ /* * Copyright 1990,2000,2007,2008,2009,2010,2016 by the Massachusetts Institute * of Technology. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "adm_proto.h" #include #include #include #include "port-sockets.h" #include "socket-utils.h" #include #ifdef HAVE_NETINET_IN_H #include #include #include #include #ifdef HAVE_SYS_SOCKIO_H /* for SIOCGIFCONF, etc. */ #include #endif #include #if HAVE_SYS_SELECT_H #include #endif #include #ifndef ARPHRD_ETHER /* OpenBSD breaks on multiple inclusions */ #include #endif #ifdef HAVE_SYS_FILIO_H #include /* FIONBIO */ #endif #include "fake-addrinfo.h" #include "net-server.h" #include #include #include "udppktinfo.h" /* List of systemd socket activation addresses and socket types. */ struct sockact_list { size_t nsockets; struct { struct sockaddr_storage addr; int type; } *fds; }; /* When systemd socket activation is used, caller-provided sockets begin at * file descriptor 3. */ const int SOCKACT_START = 3; /* XXX */ #define KDC5_NONET (-1779992062L) static int stream_data_counter; static int max_stream_data_connections = 45; static int setreuseaddr(int sock, int value) { int st; st = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); if (st) return st; #if defined(SO_REUSEPORT) && defined(__APPLE__) /* macOS experimentally needs this flag as well to avoid conflicts between * recently exited server processes and new ones. */ st = setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)); if (st) return st; #endif return 0; } #if defined(IPV6_V6ONLY) static int setv6only(int sock, int value) { return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &value, sizeof(value)); } #endif /* KDC data. */ enum conn_type { CONN_UDP, CONN_TCP_LISTENER, CONN_TCP, CONN_RPC_LISTENER, CONN_RPC, CONN_UNIXSOCK_LISTENER, CONN_UNIXSOCK }; static const char *const conn_type_names[] = { [CONN_UDP] = "UDP", [CONN_TCP_LISTENER] = "TCP listener", [CONN_TCP] = "TCP", [CONN_RPC_LISTENER] = "RPC listener", [CONN_RPC] = "RPC", [CONN_UNIXSOCK_LISTENER] = "UNIX domain socket listener", [CONN_UNIXSOCK] = "UNIX domain socket" }; enum bind_type { UDP, TCP, RPC, UNX }; static const char *const bind_type_names[] = { [UDP] = "UDP", [TCP] = "TCP", [RPC] = "RPC", [UNX] = "UNIXSOCK", }; /* Per-connection info. */ struct connection { void *handle; const char *prog; enum conn_type type; /* Connection fields (TCP or RPC) */ struct sockaddr_storage addr_s; socklen_t addrlen; char addrbuf[128]; /* Incoming data (TCP) */ size_t bufsiz; size_t offset; char *buffer; size_t msglen; /* Outgoing data (TCP) */ krb5_data *response; unsigned char lenbuf[4]; sg_buf sgbuf[2]; sg_buf *sgp; int sgnum; /* Crude denial-of-service avoidance support (TCP or RPC) */ time_t start_time; /* RPC-specific fields */ SVCXPRT *transp; int rpc_force_close; }; #define SET(TYPE) struct { TYPE *data; size_t n, max; } /* Start at the top and work down -- this should allow for deletions without disrupting the iteration, since we delete by overwriting the element to be removed with the last element. */ #define FOREACH_ELT(set,idx,vvar) \ for (idx = set.n-1; idx >= 0 && (vvar = set.data[idx], 1); idx--) #define GROW_SET(set, incr, tmpptr) \ ((set.max + incr < set.max \ || ((set.max + incr) * sizeof(set.data[0]) / sizeof(set.data[0]) \ != set.max + incr)) \ ? 0 /* overflow */ \ : ((tmpptr = realloc(set.data, \ (set.max + incr) * sizeof(set.data[0]))) \ ? (set.data = tmpptr, set.max += incr, 1) \ : 0)) /* 1 = success, 0 = failure */ #define ADD(set, val, tmpptr) \ ((set.n < set.max || GROW_SET(set, 10, tmpptr)) \ ? (set.data[set.n++] = val, 1) \ : 0) #define DEL(set, idx) \ (set.data[idx] = set.data[--set.n], 0) #define FREE_SET_DATA(set) \ (free(set.data), set.data = 0, set.max = 0, set.n = 0) /* * N.B.: The Emacs cc-mode indentation code seems to get confused if * the macro argument here is one word only. So use "unsigned short" * instead of the "u_short" we were using before. */ struct rpc_svc_data { u_long prognum; u_long versnum; void (*dispatch)(struct svc_req *, SVCXPRT *); }; struct bind_address { char *address; u_short port; enum bind_type type; struct rpc_svc_data rpc_svc_data; }; static SET(verto_ev *) events; static SET(struct bind_address) bind_addresses; verto_ctx * loop_init(verto_ev_type types) { types |= VERTO_EV_TYPE_IO; types |= VERTO_EV_TYPE_SIGNAL; types |= VERTO_EV_TYPE_TIMEOUT; return verto_default(NULL, types); } static void do_break(verto_ctx *ctx, verto_ev *ev) { krb5_klog_syslog(LOG_DEBUG, _("Got signal to request exit")); verto_break(ctx); } struct sighup_context { void *handle; void (*reset)(void *); }; static void do_reset(verto_ctx *ctx, verto_ev *ev) { struct sighup_context *sc = (struct sighup_context*) verto_get_private(ev); krb5_klog_syslog(LOG_DEBUG, _("Got signal to reset")); krb5_klog_reopen(get_context(sc->handle)); if (sc->reset) sc->reset(sc->handle); } static void free_sighup_context(verto_ctx *ctx, verto_ev *ev) { free(verto_get_private(ev)); } krb5_error_code loop_setup_signals(verto_ctx *ctx, void *handle, void (*reset)(void *)) { struct sighup_context *sc; verto_ev *ev; if (!verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_break, SIGINT) || !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_break, SIGTERM) || !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_break, SIGQUIT) || !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, VERTO_SIG_IGN, SIGPIPE)) return ENOMEM; ev = verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_reset, SIGHUP); if (!ev) return ENOMEM; sc = malloc(sizeof(*sc)); if (!sc) return ENOMEM; sc->handle = handle; sc->reset = reset; verto_set_private(ev, sc, free_sighup_context); return 0; } /* * Add a bind address to the loop. * * Arguments: * - address * An address string, hostname, or UNIX socket path. * Pass NULL to use the wildcard address for IP sockets. * - port * What port the socket should be set to (for IPv4 or IPv6). * - type * bind_type for the socket. * - rpc_data * For RPC addresses, the svc_register() arguments to use when TCP * connections are created. Ignored for other types. */ static krb5_error_code loop_add_address(const char *address, int port, enum bind_type type, struct rpc_svc_data *rpc_data) { struct bind_address addr, val; int i; void *tmp; char *addr_copy = NULL; assert(!(type == RPC && rpc_data == NULL)); /* Make sure a valid port number was passed. */ if (port < 0 || port > 65535) { krb5_klog_syslog(LOG_ERR, _("Invalid port %d"), port); return EINVAL; } /* Check for conflicting addresses. */ FOREACH_ELT(bind_addresses, i, val) { if (type != val.type || port != val.port) continue; /* If a wildcard address is being added, make sure to remove any direct * addresses. */ if (address == NULL && val.address != NULL) { krb5_klog_syslog(LOG_DEBUG, _("Removing address %s since wildcard address" " is being added"), val.address); free(val.address); DEL(bind_addresses, i); } else if (val.address == NULL || !strcmp(address, val.address)) { krb5_klog_syslog(LOG_DEBUG, _("Address already added to server")); return 0; } } /* Copy the address if it is specified. */ if (address != NULL) { addr_copy = strdup(address); if (addr_copy == NULL) return ENOMEM; } /* Add the new address to bind_addresses. */ memset(&addr, 0, sizeof(addr)); addr.address = addr_copy; addr.port = port; addr.type = type; if (rpc_data != NULL) addr.rpc_svc_data = *rpc_data; if (!ADD(bind_addresses, addr, tmp)) { free(addr_copy); return ENOMEM; } return 0; } /* * Add bind addresses to the loop. * * Arguments: * * - addresses * A string for the addresses. Pass NULL to use the wildcard address. * Supported delimiters can be found in ADDRESSES_DELIM. Addresses are * parsed with k5_parse_host_name(). * - default_port * What port the socket should be set to if not specified in addresses. * - type * bind_type for the socket. * - rpc_data * For RPC addresses, the svc_register() arguments to use when TCP * connections are created. Ignored for other types. */ static krb5_error_code loop_add_addresses(const char *addresses, int default_port, enum bind_type type, struct rpc_svc_data *rpc_data) { krb5_error_code ret = 0; char *addresses_copy = NULL, *host = NULL, *saveptr, *addr; int port; /* If no addresses are set, add a wildcard address. */ if (addresses == NULL) return loop_add_address(NULL, default_port, type, rpc_data); /* Copy the addresses string before using strtok(). */ addresses_copy = strdup(addresses); if (addresses_copy == NULL) { ret = ENOMEM; goto cleanup; } /* Loop through each address in the string and add it to the loop. */ addr = strtok_r(addresses_copy, ADDRESSES_DELIM, &saveptr); for (; addr != NULL; addr = strtok_r(NULL, ADDRESSES_DELIM, &saveptr)) { if (type == UNX) { /* Skip non-pathnames when binding UNIX domain sockets. */ if (*addr != '/') continue; ret = loop_add_address(addr, 0, type, rpc_data); if (ret) goto cleanup; continue; } else if (*addr == '/') { /* Skip pathnames when not binding UNIX domain sockets. */ continue; } /* Parse the host string. */ ret = k5_parse_host_string(addr, default_port, &host, &port); if (ret) goto cleanup; ret = loop_add_address(host, port, type, rpc_data); if (ret) goto cleanup; free(host); host = NULL; } ret = 0; cleanup: free(addresses_copy); free(host); return ret; } krb5_error_code loop_add_udp_address(int default_port, const char *addresses) { return loop_add_addresses(addresses, default_port, UDP, NULL); } krb5_error_code loop_add_tcp_address(int default_port, const char *addresses) { return loop_add_addresses(addresses, default_port, TCP, NULL); } krb5_error_code loop_add_rpc_service(int default_port, const char *addresses, u_long prognum, u_long versnum, void (*dispatchfn)(struct svc_req *, SVCXPRT *)) { struct rpc_svc_data svc; svc.prognum = prognum; svc.versnum = versnum; svc.dispatch = dispatchfn; return loop_add_addresses(addresses, default_port, RPC, &svc); } krb5_error_code loop_add_unix_socket(const char *socket_paths) { /* There is no wildcard or default UNIX domain socket. */ if (socket_paths == NULL) return 0; return loop_add_addresses(socket_paths, 0, UNX, NULL); } #define USE_AF AF_INET #define USE_TYPE SOCK_DGRAM #define USE_PROTO 0 #define SOCKET_ERRNO errno #include "foreachaddr.h" static void free_connection(struct connection *conn) { if (!conn) return; if (conn->response) krb5_free_data(get_context(conn->handle), conn->response); if (conn->buffer) free(conn->buffer); if (conn->type == CONN_RPC_LISTENER && conn->transp != NULL) svc_destroy(conn->transp); free(conn); } static void remove_event_from_set(verto_ev *ev) { verto_ev *tmp; int i; /* Remove the event from the events. */ FOREACH_ELT(events, i, tmp) if (tmp == ev) { DEL(events, i); break; } } static void free_socket(verto_ctx *ctx, verto_ev *ev) { struct connection *conn = NULL; fd_set fds; int fd; remove_event_from_set(ev); fd = verto_get_fd(ev); conn = verto_get_private(ev); /* Close the file descriptor. */ krb5_klog_syslog(LOG_INFO, _("closing down fd %d"), fd); if (fd >= 0 && (!conn || conn->type != CONN_RPC || conn->rpc_force_close)) close(fd); /* Free the connection struct. */ if (conn) { switch (conn->type) { case CONN_RPC: if (conn->rpc_force_close) { FD_ZERO(&fds); FD_SET(fd, &fds); svc_getreqset(&fds); if (FD_ISSET(fd, &svc_fdset)) { krb5_klog_syslog(LOG_ERR, _("descriptor %d closed but still " "in svc_fdset"), fd); } } /* Fall through. */ case CONN_TCP: case CONN_UNIXSOCK: stream_data_counter--; break; default: break; } free_connection(conn); } } static verto_ev * make_event(verto_ctx *ctx, verto_ev_flag flags, verto_callback callback, int sock, struct connection *conn) { verto_ev *ev; void *tmp; ev = verto_add_io(ctx, flags, callback, sock); if (!ev) { com_err(conn->prog, ENOMEM, _("cannot create io event")); return NULL; } if (!ADD(events, ev, tmp)) { com_err(conn->prog, ENOMEM, _("cannot save event")); verto_del(ev); return NULL; } verto_set_private(ev, conn, free_socket); return ev; } static krb5_error_code add_fd(int sock, enum conn_type conntype, verto_ev_flag flags, void *handle, const char *prog, verto_ctx *ctx, verto_callback callback, verto_ev **ev_out) { struct connection *newconn; *ev_out = NULL; #ifndef _WIN32 if (sock >= FD_SETSIZE) { com_err(prog, 0, _("file descriptor number %d too high"), sock); return EMFILE; } #endif newconn = malloc(sizeof(*newconn)); if (newconn == NULL) { com_err(prog, ENOMEM, _("cannot allocate storage for connection info")); return ENOMEM; } memset(newconn, 0, sizeof(*newconn)); newconn->handle = handle; newconn->prog = prog; newconn->type = conntype; *ev_out = make_event(ctx, flags, callback, sock, newconn); return 0; } static void process_packet(verto_ctx *ctx, verto_ev *ev); static void accept_stream_connection(verto_ctx *ctx, verto_ev *ev); static void process_stream_connection_read(verto_ctx *ctx, verto_ev *ev); static void process_stream_connection_write(verto_ctx *ctx, verto_ev *ev); static void accept_rpc_connection(verto_ctx *ctx, verto_ev *ev); static void process_rpc_connection(verto_ctx *ctx, verto_ev *ev); /* * Create a socket and bind it to addr. Ensure the socket will work with * select(). Set the socket cloexec, reuseaddr, and if applicable v6-only. * Does not call listen(). On failure, log an error and return an error code. */ static krb5_error_code create_server_socket(struct sockaddr *addr, int type, const char *prog, int *fd_out) { int sock, e; char addrbuf[128]; *fd_out = -1; if (addr->sa_family == AF_UNIX) (void)unlink(sa2sun(addr)->sun_path); sock = socket(addr->sa_family, type, 0); if (sock == -1) { e = errno; k5_print_addr_port(addr, addrbuf, sizeof(addrbuf)); com_err(prog, e, _("Cannot create TCP server socket on %s"), addrbuf); return e; } set_cloexec_fd(sock); #ifndef _WIN32 /* Windows FD_SETSIZE is a count. */ if (sock >= FD_SETSIZE) { close(sock); k5_print_addr_port(addr, addrbuf, sizeof(addrbuf)); com_err(prog, 0, _("TCP socket fd number %d (for %s) too high"), sock, addrbuf); return EMFILE; } #endif if (setreuseaddr(sock, 1) < 0) com_err(prog, errno, _("Cannot enable SO_REUSEADDR on fd %d"), sock); if (addr->sa_family == AF_INET6) { #ifdef IPV6_V6ONLY if (setv6only(sock, 1)) { com_err(prog, errno, _("setsockopt(%d,IPV6_V6ONLY,1) failed"), sock); } else { com_err(prog, 0, _("setsockopt(%d,IPV6_V6ONLY,1) worked"), sock); } #else krb5_klog_syslog(LOG_INFO, _("no IPV6_V6ONLY socket option support")); #endif /* IPV6_V6ONLY */ } if (bind(sock, addr, sa_socklen(addr)) == -1) { e = errno; k5_print_addr_port(addr, addrbuf, sizeof(addrbuf)); com_err(prog, e, _("Cannot bind server socket on %s"), addrbuf); close(sock); return e; } *fd_out = sock; return 0; } static const int one = 1; static int setnbio(int sock) { return ioctlsocket(sock, FIONBIO, (const void *)&one); } static int setkeepalive(int sock) { return setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one)); } static int setnolinger(int s) { static const struct linger ling = { 0, 0 }; return setsockopt(s, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); } /* An enum map to socket families for each bind_type. */ static const int bind_socktypes[] = { [UDP] = SOCK_DGRAM, [TCP] = SOCK_STREAM, [RPC] = SOCK_STREAM, [UNX] = SOCK_STREAM }; /* An enum map containing conn_type (for struct connection) for each * bind_type. */ static const enum conn_type bind_conn_types[] = { [UDP] = CONN_UDP, [TCP] = CONN_TCP_LISTENER, [RPC] = CONN_RPC_LISTENER, [UNX] = CONN_UNIXSOCK_LISTENER }; /* If any systemd socket activation fds are indicated by the environment, set * them close-on-exec and put their addresses and socket types into *list. */ static void init_sockact_list(struct sockact_list *list) { const char *v; char *end; long lpid; int fd; size_t nfds, i; socklen_t slen; list->nsockets = 0; list->fds = NULL; /* Check if LISTEN_FDS is meant for this process. */ v = getenv("LISTEN_PID"); if (v == NULL) return; lpid = strtol(v, &end, 10); if (end == NULL || end == v || *end != '\0' || lpid != getpid()) return; /* Get the number of activated sockets. */ v = getenv("LISTEN_FDS"); if (v == NULL) return; nfds = strtoul(v, &end, 10); if (end == NULL || end == v || *end != '\0') return; if (nfds == 0 || nfds > (size_t)INT_MAX - SOCKACT_START) return; list->fds = calloc(nfds, sizeof(*list->fds)); if (list->fds == NULL) return; for (i = 0; i < nfds; i++) { fd = i + SOCKACT_START; set_cloexec_fd(fd); slen = sizeof(list->fds[i].addr); (void)getsockname(fd, ss2sa(&list->fds[i].addr), &slen); slen = sizeof(list->fds[i].type); (void)getsockopt(fd, SOL_SOCKET, SO_TYPE, &list->fds[i].type, &slen); } list->nsockets = nfds; } /* Release any storage used by *list. */ static void fini_sockact_list(struct sockact_list *list) { free(list->fds); list->fds = NULL; list->nsockets = 0; } /* If sa matches an address in *list, return the associated file descriptor and * clear the address from *list. Otherwise return -1. */ static int find_sockact(struct sockact_list *list, const struct sockaddr *sa, int type) { size_t i; for (i = 0; i < list->nsockets; i++) { if (list->fds[i].type == type && sa_equal(ss2sa(&list->fds[i].addr), sa)) { list->fds[i].type = -1; memset(&list->fds[i].addr, 0, sizeof(list->fds[i].addr)); return i + SOCKACT_START; } } return -1; } /* * Set up a listening socket. * * Arguments: * * - ba * The bind address and port for the socket. * - ai * The addrinfo struct to use for creating the socket. * - ctype * The conn_type of this socket. */ static krb5_error_code setup_socket(struct bind_address *ba, struct sockaddr *sock_address, struct sockact_list *sockacts, void *handle, const char *prog, verto_ctx *ctx, int listen_backlog, verto_callback vcb, enum conn_type ctype) { krb5_error_code ret; struct connection *conn; verto_ev_flag flags; verto_ev *ev = NULL; int sock = -1; char addrbuf[128]; k5_print_addr_port(sock_address, addrbuf, sizeof(addrbuf)); krb5_klog_syslog(LOG_DEBUG, _("Setting up %s socket for address %s"), bind_type_names[ba->type], addrbuf); if (sockacts->nsockets > 0) { /* Look for a systemd socket activation fd matching sock_address. */ sock = find_sockact(sockacts, sock_address, bind_socktypes[ba->type]); if (sock == -1) { /* Ignore configured addresses that don't match any caller-provided * sockets. */ ret = 0; goto cleanup; } } else { /* We're not using socket activation; create the socket. */ ret = create_server_socket(sock_address, bind_socktypes[ba->type], prog, &sock); if (ret) goto cleanup; /* Listen for backlogged connections on stream sockets. (For RPC * sockets this will be done by svc_register().) */ if ((ba->type == TCP || ba->type == UNX) && listen(sock, listen_backlog) != 0) { ret = errno; com_err(prog, errno, _("Cannot listen on %s server socket on %s"), bind_type_names[ba->type], addrbuf); goto cleanup; } } /* Set non-blocking I/O for non-RPC listener sockets. */ if (ba->type != RPC && setnbio(sock) != 0) { ret = errno; com_err(prog, errno, _("cannot set listening %s socket on %s non-blocking"), bind_type_names[ba->type], addrbuf); goto cleanup; } /* Turn off the linger option for TCP sockets. */ if (ba->type == TCP && setnolinger(sock) != 0) { ret = errno; com_err(prog, errno, _("cannot set SO_LINGER on %s socket on %s"), bind_type_names[ba->type], addrbuf); goto cleanup; } /* Try to turn on pktinfo for UDP wildcard sockets. */ if (ba->type == UDP && sa_is_wildcard(sock_address)) { krb5_klog_syslog(LOG_DEBUG, _("Setting pktinfo on socket %s"), addrbuf); ret = set_pktinfo(sock, sock_address->sa_family); if (ret) { com_err(prog, ret, _("Cannot request packet info for UDP socket address " "%s port %d"), addrbuf, ba->port); krb5_klog_syslog(LOG_INFO, _("System does not support pktinfo yet " "binding to a wildcard address. " "Packets are not guaranteed to " "return on the received address.")); } } /* Add the socket to the event loop. */ flags = VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_REINITIABLE; ret = add_fd(sock, ctype, flags, handle, prog, ctx, vcb, &ev); if (ret) { krb5_klog_syslog(LOG_ERR, _("Error attempting to add verto event")); goto cleanup; } if (ba->type == RPC) { conn = verto_get_private(ev); conn->transp = svctcp_create(sock, 0, 0); if (conn->transp == NULL) { ret = errno; krb5_klog_syslog(LOG_ERR, _("Cannot create RPC service: %s"), strerror(ret)); goto cleanup; } ret = svc_register(conn->transp, ba->rpc_svc_data.prognum, ba->rpc_svc_data.versnum, ba->rpc_svc_data.dispatch, 0); if (!ret) { ret = errno; krb5_klog_syslog(LOG_ERR, _("Cannot register RPC service: %s"), strerror(ret)); goto cleanup; } } ev = NULL; sock = -1; ret = 0; cleanup: if (sock >= 0) close(sock); if (ev != NULL) verto_del(ev); return ret; } /* * Setup all the socket addresses that the net-server should listen to. * * This function uses getaddrinfo to figure out all the addresses. This will * automatically figure out which socket families that should be used on the * host making it useful even for wildcard addresses. */ static krb5_error_code setup_addresses(verto_ctx *ctx, void *handle, const char *prog, int listen_backlog) { /* An bind_type enum map for the verto callback functions. */ static verto_callback *const verto_callbacks[] = { [UDP] = &process_packet, [TCP] = &accept_stream_connection, [RPC] = &accept_rpc_connection, [UNX] = &accept_stream_connection }; krb5_error_code ret = 0; size_t i; int err, bound_any; struct bind_address addr; struct sockaddr_un sun; struct addrinfo hints, *ai_list = NULL, *ai = NULL; struct sockact_list sockacts = { 0 }; verto_callback vcb; char addrbuf[128]; /* Check to make sure addresses were added to the server. */ if (bind_addresses.n == 0) { krb5_klog_syslog(LOG_ERR, _("No addresses added to the net server")); return EINVAL; } /* Ask for all address families, listener addresses, and no port name * resolution. */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_PASSIVE; #ifdef AI_NUMERICSERV hints.ai_flags |= AI_NUMERICSERV; #endif init_sockact_list(&sockacts); /* Add all the requested addresses. */ for (i = 0; i < bind_addresses.n; i++) { addr = bind_addresses.data[i]; hints.ai_socktype = bind_socktypes[addr.type]; if (addr.type == UNX) { sun.sun_family = AF_UNIX; if (strlcpy(sun.sun_path, addr.address, sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) { ret = ENAMETOOLONG; krb5_klog_syslog(LOG_ERR, _("UNIX domain socket path too long: %s"), addr.address); goto cleanup; } ret = setup_socket(&addr, (struct sockaddr *)&sun, &sockacts, handle, prog, ctx, listen_backlog, verto_callbacks[addr.type], bind_conn_types[addr.type]); if (ret) { krb5_klog_syslog(LOG_ERR, _("Failed setting up a UNIX socket (for %s)"), addr.address); goto cleanup; } continue; } /* Call getaddrinfo, using a dummy port value. */ err = getaddrinfo(addr.address, "0", &hints, &ai_list); if (err) { krb5_klog_syslog(LOG_ERR, _("Failed getting address info (for %s): %s"), (addr.address == NULL) ? "" : addr.address, gai_strerror(err)); ret = EIO; goto cleanup; } /* * Loop through all the sockets that getaddrinfo could find to match * the requested address. For wildcard listeners, this should usually * have two results, one for each of IPv4 and IPv6, or one or the * other, depending on the system. On IPv4-only systems, getaddrinfo() * may return both IPv4 and IPv6 addresses, but creating an IPv6 socket * may give an EAFNOSUPPORT error, so tolerate that error as long as we * can bind at least one socket. */ bound_any = 0; for (ai = ai_list; ai != NULL; ai = ai->ai_next) { /* Make sure getaddrinfo returned a socket with the same type that * was requested. */ assert(hints.ai_socktype == ai->ai_socktype); /* Set the real port number. */ sa_setport(ai->ai_addr, addr.port); ret = setup_socket(&addr, ai->ai_addr, &sockacts, handle, prog, ctx, listen_backlog, verto_callbacks[addr.type], bind_conn_types[addr.type]); if (ret) { k5_print_addr(ai->ai_addr, addrbuf, sizeof(addrbuf)); krb5_klog_syslog(LOG_ERR, _("Failed setting up a %s socket (for %s)"), bind_type_names[addr.type], addrbuf); if (ret != EAFNOSUPPORT) goto cleanup; } else { bound_any = 1; } } if (!bound_any) goto cleanup; ret = 0; if (ai_list != NULL) freeaddrinfo(ai_list); ai_list = NULL; } cleanup: if (ai_list != NULL) freeaddrinfo(ai_list); fini_sockact_list(&sockacts); return ret; } krb5_error_code loop_setup_network(verto_ctx *ctx, void *handle, const char *prog, int listen_backlog) { krb5_error_code ret; verto_ev *ev; int i; /* Check to make sure that at least one address was added to the loop. */ if (bind_addresses.n == 0) return EINVAL; /* Close any open connections. */ FOREACH_ELT(events, i, ev) verto_del(ev); events.n = 0; krb5_klog_syslog(LOG_INFO, _("setting up network...")); ret = setup_addresses(ctx, handle, prog, listen_backlog); if (ret) { com_err(prog, ret, _("Error setting up network")); exit(1); } krb5_klog_syslog (LOG_INFO, _("set up %d sockets"), (int) events.n); if (events.n == 0) { /* If no sockets were set up, we can't continue. */ com_err(prog, 0, _("no sockets set up?")); exit (1); } return 0; } struct udp_dispatch_state { void *handle; const char *prog; int port_fd; struct sockaddr_storage saddr; struct sockaddr_storage daddr; aux_addressing_info auxaddr; krb5_data request; char pktbuf[MAX_DGRAM_SIZE]; }; static void process_packet_response(void *arg, krb5_error_code code, krb5_data *response) { struct udp_dispatch_state *state = arg; int cc; if (code) com_err(state->prog ? state->prog : NULL, code, _("while dispatching (udp)")); if (code || response == NULL) goto out; cc = send_to_from(state->port_fd, response->data, (socklen_t)response->length, 0, ss2sa(&state->saddr), ss2sa(&state->daddr), &state->auxaddr); if (cc == -1) { /* Note that the local address (daddr*) has no port number * info associated with it. */ char sbuf[128], dbuf[128]; int e = errno; k5_print_addr_port(ss2sa(&state->saddr), sbuf, sizeof(sbuf)); k5_print_addr(ss2sa(&state->daddr), dbuf, sizeof(dbuf)); com_err(state->prog, e, _("while sending reply to %s from %s"), sbuf, dbuf); goto out; } if ((size_t)cc != response->length) { com_err(state->prog, 0, _("short reply write %d vs %d\n"), response->length, cc); } out: krb5_free_data(get_context(state->handle), response); free(state); } static void process_packet(verto_ctx *ctx, verto_ev *ev) { int cc; struct connection *conn; struct udp_dispatch_state *state; socklen_t slen; conn = verto_get_private(ev); state = malloc(sizeof(*state)); if (!state) { com_err(conn->prog, ENOMEM, _("while dispatching (udp)")); return; } state->handle = conn->handle; state->prog = conn->prog; state->port_fd = verto_get_fd(ev); assert(state->port_fd >= 0); memset(&state->auxaddr, 0, sizeof(state->auxaddr)); cc = recv_from_to(state->port_fd, state->pktbuf, sizeof(state->pktbuf), 0, &state->saddr, &state->daddr, &state->auxaddr); if (cc == -1) { if (errno != EINTR && errno != EAGAIN /* * This is how Linux indicates that a previous transmission was * refused, e.g., if the client timed out before getting the * response packet. */ && errno != ECONNREFUSED ) com_err(conn->prog, errno, _("while receiving from network")); free(state); return; } if (!cc) { /* zero-length packet? */ free(state); return; } if (state->daddr.ss_family == AF_UNSPEC && conn->type == CONN_UDP) { /* * An address couldn't be obtained, so the PKTINFO option probably * isn't available. If the socket is bound to a specific address, then * try to get the address here. */ slen = sizeof(state->daddr); (void)getsockname(state->port_fd, ss2sa(&state->daddr), &slen); } state->request.length = cc; state->request.data = state->pktbuf; dispatch(state->handle, ss2sa(&state->daddr), ss2sa(&state->saddr), &state->request, 0, ctx, process_packet_response, state); } static int kill_lru_stream_connection(void *handle, verto_ev *newev) { struct connection *c = NULL, *oldest_c = NULL; verto_ev *ev, *oldest_ev = NULL; int i, fd = -1; krb5_klog_syslog(LOG_INFO, _("too many connections")); FOREACH_ELT (events, i, ev) { if (ev == newev) continue; c = verto_get_private(ev); if (!c) continue; if (c->type != CONN_TCP && c->type != CONN_RPC && c->type != CONN_UNIXSOCK) continue; if (oldest_c == NULL || oldest_c->start_time > c->start_time) { oldest_ev = ev; oldest_c = c; } } if (oldest_c != NULL) { krb5_klog_syslog(LOG_INFO, _("dropping %s fd %d from %s"), conn_type_names[oldest_c->type], verto_get_fd(oldest_ev), oldest_c->addrbuf); if (oldest_c->type == CONN_RPC) oldest_c->rpc_force_close = 1; verto_del(oldest_ev); } return fd; } static void accept_stream_connection(verto_ctx *ctx, verto_ev *ev) { int s; struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); struct connection *newconn, *conn; enum conn_type ctype; verto_ev_flag flags; verto_ev *newev; conn = verto_get_private(ev); s = accept(verto_get_fd(ev), ss2sa(&addr), &addrlen); if (s < 0) return; set_cloexec_fd(s); #ifndef _WIN32 if (s >= FD_SETSIZE) { close(s); return; } #endif setnbio(s); setnolinger(s); if (addr.ss_family != AF_UNIX) setkeepalive(s); flags = VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST; ctype = (conn->type == CONN_TCP_LISTENER) ? CONN_TCP : CONN_UNIXSOCK; if (add_fd(s, ctype, flags, conn->handle, conn->prog, ctx, process_stream_connection_read, &newev) != 0) { close(s); return; } newconn = verto_get_private(newev); if (addr.ss_family == AF_UNIX) { /* accept() doesn't fill in sun_path as the client socket isn't bound. * For logging purposes we will use the target address. */ addrlen = sizeof(addr); if (getsockname(s, ss2sa(&addr), &addrlen) < 0) { com_err(conn->prog, errno, _("Failed to get address for %d"), s); close(s); return; } } k5_print_addr_port(ss2sa(&addr), newconn->addrbuf, sizeof(newconn->addrbuf)); newconn->addr_s = addr; newconn->addrlen = addrlen; newconn->bufsiz = 1024 * 1024; newconn->buffer = malloc(newconn->bufsiz); newconn->start_time = time(0); if (++stream_data_counter > max_stream_data_connections) kill_lru_stream_connection(conn->handle, newev); if (newconn->buffer == 0) { com_err(conn->prog, errno, _("allocating buffer for new TCP session from %s"), newconn->addrbuf); verto_del(newev); return; } newconn->offset = 0; SG_SET(&newconn->sgbuf[0], newconn->lenbuf, 4); SG_SET(&newconn->sgbuf[1], 0, 0); } struct tcp_dispatch_state { struct sockaddr_storage local_saddr; struct connection *conn; krb5_data request; verto_ctx *ctx; int sock; }; static void process_stream_response(void *arg, krb5_error_code code, krb5_data *response) { struct tcp_dispatch_state *state = arg; verto_ev *ev; assert(state); state->conn->response = response; if (code) com_err(state->conn->prog, code, _("while dispatching (tcp)")); if (code || !response) goto kill_tcp_connection; /* Queue outgoing response. */ store_32_be(response->length, state->conn->lenbuf); SG_SET(&state->conn->sgbuf[1], response->data, response->length); state->conn->sgp = state->conn->sgbuf; state->conn->sgnum = 2; ev = make_event(state->ctx, VERTO_EV_FLAG_IO_WRITE | VERTO_EV_FLAG_PERSIST, process_stream_connection_write, state->sock, state->conn); if (ev) { free(state); return; } kill_tcp_connection: stream_data_counter--; free_connection(state->conn); close(state->sock); free(state); } /* Creates the tcp_dispatch_state and deletes the verto event. */ static struct tcp_dispatch_state * prepare_for_dispatch(verto_ctx *ctx, verto_ev *ev) { struct tcp_dispatch_state *state; state = malloc(sizeof(*state)); if (!state) { krb5_klog_syslog(LOG_ERR, _("error allocating tcp dispatch private!")); return NULL; } state->conn = verto_get_private(ev); state->sock = verto_get_fd(ev); state->ctx = ctx; verto_set_private(ev, NULL, NULL); /* Don't close the fd or free conn! */ remove_event_from_set(ev); /* Remove it from the set. */ verto_del(ev); return state; } static void process_stream_connection_read(verto_ctx *ctx, verto_ev *ev) { struct tcp_dispatch_state *state = NULL; struct connection *conn = NULL; ssize_t nread; size_t len; conn = verto_get_private(ev); /* * Read message length and data into one big buffer, already allocated * at connect time. If we have a complete message, we stop reading, so * we should only be here if there is no data in the buffer, or only an * incomplete message. */ if (conn->offset < 4) { krb5_data *response = NULL; /* msglen has not been computed. XXX Doing at least two reads * here, letting the kernel worry about buffering. */ len = 4 - conn->offset; nread = SOCKET_READ(verto_get_fd(ev), conn->buffer + conn->offset, len); if (nread < 0) /* error */ goto kill_tcp_connection; if (nread == 0) /* eof */ goto kill_tcp_connection; conn->offset += nread; if (conn->offset == 4) { unsigned char *p = (unsigned char *)conn->buffer; conn->msglen = load_32_be(p); if (conn->msglen > conn->bufsiz - 4) { krb5_error_code err; /* Message too big. */ krb5_klog_syslog(LOG_ERR, _("TCP client %s wants %lu bytes, " "cap is %lu"), conn->addrbuf, (unsigned long) conn->msglen, (unsigned long) conn->bufsiz - 4); /* XXX Should return an error. */ err = make_toolong_error (conn->handle, &response); if (err) { krb5_klog_syslog(LOG_ERR, _("error constructing " "KRB_ERR_FIELD_TOOLONG error! %s"), error_message(err)); goto kill_tcp_connection; } state = prepare_for_dispatch(ctx, ev); if (!state) { krb5_free_data(get_context(conn->handle), response); goto kill_tcp_connection; } process_stream_response(state, 0, response); } } } else { /* msglen known. */ socklen_t local_saddrlen = sizeof(struct sockaddr_storage); len = conn->msglen - (conn->offset - 4); nread = SOCKET_READ(verto_get_fd(ev), conn->buffer + conn->offset, len); if (nread < 0) /* error */ goto kill_tcp_connection; if (nread == 0) /* eof */ goto kill_tcp_connection; conn->offset += nread; if (conn->offset < conn->msglen + 4) return; /* Have a complete message, and exactly one message. */ state = prepare_for_dispatch(ctx, ev); if (!state) goto kill_tcp_connection; state->request.length = conn->msglen; state->request.data = conn->buffer + 4; if (getsockname(verto_get_fd(ev), ss2sa(&state->local_saddr), &local_saddrlen) < 0) { krb5_klog_syslog(LOG_ERR, _("getsockname failed: %s"), error_message(errno)); goto kill_tcp_connection; } dispatch(state->conn->handle, ss2sa(&state->local_saddr), ss2sa(&conn->addr_s), &state->request, 1, ctx, process_stream_response, state); } return; kill_tcp_connection: verto_del(ev); } static void process_stream_connection_write(verto_ctx *ctx, verto_ev *ev) { struct connection *conn; SOCKET_WRITEV_TEMP tmp; ssize_t nwrote; int sock; conn = verto_get_private(ev); sock = verto_get_fd(ev); nwrote = SOCKET_WRITEV(sock, conn->sgp, conn->sgnum, tmp); if (nwrote > 0) { /* non-error and non-eof */ while (nwrote) { sg_buf *sgp = conn->sgp; if ((size_t)nwrote < SG_LEN(sgp)) { SG_ADVANCE(sgp, (size_t)nwrote); nwrote = 0; } else { nwrote -= SG_LEN(sgp); conn->sgp++; conn->sgnum--; if (conn->sgnum == 0 && nwrote != 0) abort(); } } /* If we still have more data to send, just return so that * the main loop can call this function again when the socket * is ready for more writing. */ if (conn->sgnum > 0) return; } /* Finished sending. We should go back to reading, though if we * sent a FIELD_TOOLONG error in reply to a length with the high * bit set, RFC 4120 says we have to close the TCP stream. */ verto_del(ev); } void loop_free(verto_ctx *ctx) { int i; struct bind_address val; verto_free(ctx); /* Free each addresses added to the loop. */ FOREACH_ELT(bind_addresses, i, val) free(val.address); FREE_SET_DATA(bind_addresses); FREE_SET_DATA(events); } static int have_event_for_fd(int fd) { verto_ev *ev; int i; FOREACH_ELT(events, i, ev) { if (verto_get_fd(ev) == fd) return 1; } return 0; } static void accept_rpc_connection(verto_ctx *ctx, verto_ev *ev) { verto_ev_flag flags; struct connection *conn; fd_set fds; int s; conn = verto_get_private(ev); /* Service the woken RPC listener descriptor. */ FD_ZERO(&fds); FD_SET(verto_get_fd(ev), &fds); svc_getreqset(&fds); /* Scan svc_fdset for any new connections. */ for (s = 0; s < FD_SETSIZE; s++) { struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); struct connection *newconn; verto_ev *newev; /* If we already have this fd, continue. */ if (!FD_ISSET(s, &svc_fdset) || have_event_for_fd(s)) continue; flags = VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST; if (add_fd(s, CONN_RPC, flags, conn->handle, conn->prog, ctx, process_rpc_connection, &newev) != 0) continue; newconn = verto_get_private(newev); set_cloexec_fd(s); if (getpeername(s, ss2sa(&addr), &addrlen) != 0) { strlcpy(newconn->addrbuf, "", sizeof(newconn->addrbuf)); } else { k5_print_addr_port(ss2sa(&addr), newconn->addrbuf, sizeof(newconn->addrbuf)); } newconn->addr_s = addr; newconn->addrlen = addrlen; newconn->start_time = time(0); if (++stream_data_counter > max_stream_data_connections) kill_lru_stream_connection(newconn->handle, newev); } } static void process_rpc_connection(verto_ctx *ctx, verto_ev *ev) { fd_set fds; FD_ZERO(&fds); FD_SET(verto_get_fd(ev), &fds); svc_getreqset(&fds); if (!FD_ISSET(verto_get_fd(ev), &svc_fdset)) verto_del(ev); } #endif /* INET */ krb5-1.22.1/src/lib/krb5.rc0000664000175000017500000000336315051422640015074 0ustar ghudsonghudson/* * lib/krb5/os/win-pwd.h * * Copyright 1997 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * */ #include "win-mac.h" ID_READ_PWD_DIALOG DIALOG 60, 72, 200, 84 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_SETFONT CAPTION "Kerberos Password/Challenge" FONT 8, "Helv" { LTEXT "", ID_READ_PWD_PROMPT, 10, 8, 180, 10 LTEXT "", ID_READ_PWD_PROMPT2, 10, 24, 180, 10 EDITTEXT ID_READ_PWD_PWD, 10, 42, 180, 12, ES_AUTOHSCROLL | ES_PASSWORD | WS_BORDER | WS_TABSTOP DEFPUSHBUTTON "&OK", IDOK, 55, 61, 40, 14 PUSHBUTTON "&Cancel", IDCANCEL, 107, 61, 40, 14 } #include "..\windows\version.rc" krb5-1.22.1/src/lib/Makefile.in0000664000175000017500000001150115051422640015741 0ustar ghudsonghudsonmydir=lib SUBDIRS=crypto krb5 gssapi rpc kdb kadm5 apputils krad WINSUBDIRS=crypto krb5 gssapi BUILDTOP=$(REL).. all-unix: CLEANLIBS = libkrb5.a libkdb5.a libcrypto.a libgssapi_krb5.a libkadm.a \ libcom_err.a libpty.a ibss.a libgssapi.a libapputils.a libkrb5.so \ libcrypto.so clean-unix:: clean-windows:: # Windows stuff to make krb5 and gssapi DLLs. ##MIT##!if !defined(VS_INC) ##MIT##!message Must define VS_INC to point to version server include dir! ##MIT##!error ##MIT##!endif ##MIT##!if !defined(VS_LIB) ##MIT##!message Must define VS_LIB to point to version server library! ##MIT##!error ##MIT##!endif ##MIT##MITLIBS=$(VS_LIB) ##MIT##MITFLAGS=-I$(VS_INC) /DVERSERV=1 ##WIN32##SLIBS = $(BUILDTOP)\util\support\$(OUTPRE)k5sprt$(BITS).lib ##WIN32##CLIBS = $(BUILDTOP)\util\et\$(OUTPRE)comerr.lib ##WIN32##PLIBS = $(BUILDTOP)\util\profile\$(OUTPRE)profile.lib ##WIN32##KLIBS = krb5\$(OUTPRE)krb5.lib crypto\$(OUTPRE)crypto.lib \ ##WIN32## $(BUILDTOP)\util\profile\$(OUTPRE)profile.lib ##WIN32##GLIBS = gssapi\$(OUTPRE)gssapi.lib ##WIN32##SDEF = k5sprt32.def ##WIN32##CDEF = comerr32.def ##WIN32##PDEF = xpprof32.def ##WIN32##KDEF = krb5_32.def ##WIN32##GDEF = gssapi32.def ##WIN32##KRB5RC = krb5.rc ##WIN32##VERSIONRC = $(BUILDTOP)\windows\version.rc ##WIN32##!if defined(VISUALSTUDIOVERSION) ##WIN32##!if $(VISUALSTUDIOVERSION:.=) >= 140 ##WIN32##!ifdef NODEBUG ##WIN32##WINCRTEXTRA = ucrt.lib vcruntime.lib ##WIN32##!else ##WIN32##WINCRTEXTRA = ucrtd.lib vcruntimed.lib ##WIN32##!endif ##WIN32##!endif ##WIN32##!endif ##WIN32##WINLIBS = kernel32.lib ws2_32.lib user32.lib shell32.lib oldnames.lib \ ##WIN32## version.lib secur32.lib advapi32.lib gdi32.lib delayimp.lib \ ##WIN32## $(WINCRTEXTRA) ##WIN32##WINDLLFLAGS = $(DLL_LINKOPTS) /DELAYLOAD:secur32.dll \ ##WIN32## /DELAYLOAD:advapi32.dll /DELAY:UNLOAD /DELAY:NOBIND ##WIN32##S_GLUE=$(OUTPRE)support_glue.obj ##WIN32##K5_GLUE=$(OUTPRE)k5_glue.obj ##WIN32##GSS_GLUE=$(OUTPRE)gss_glue.obj ##WIN32##COMERR_GLUE=$(OUTPRE)comerr_glue.obj ##WIN32##PROF_GLUE=$(OUTPRE)prof_glue.obj ##WIN32##SGLUE=$(S_GLUE) ##WIN32##CGLUE=$(COMERR_GLUE) ##WIN32##PGLUE=$(PROF_GLUE) ##WIN32##KGLUE=$(K5_GLUE) ##WIN32##GGLUE=$(GSS_GLUE) ##WIN32##RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY ##WIN32##SRES=$(SLIB:.lib=.res) ##WIN32##CRES=$(CLIB:.lib=.res) ##WIN32##PRES=$(PLIB:.lib=.res) ##WIN32##KRES=$(KLIB:.lib=.res) ##WIN32##GRES=$(GLIB:.lib=.res) ##WIN32##$(SRES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DSUPPORT_LIB -fo $@ -r $** ##WIN32##$(CRES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DCE_LIB -fo $@ -r $** ##WIN32##$(PRES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DPROF_LIB -fo $@ -r $** ##WIN32##$(KRES): $(KRB5RC) ##WIN32## $(RC) $(RCFLAGS) -DKRB5_LIB -fo $@ -r $** ##WIN32##$(GRES): $(VERSIONRC) ##WIN32## $(RC) $(RCFLAGS) -DGSSAPI_LIB -fo $@ -r $** ##WIN32##$(KRB5RC): $(VERSIONRC) ##WIN32##$(SLIB): $(SDEF) $(SLIBS) $(SGLUE) $(SRES) ##WIN32## link $(WINDLLFLAGS) -def:$(SDEF) -out:$*.dll \ ##WIN32## $(SLIBS) $(SGLUE) $(SRES) $(WINLIBS) ##WIN32## $(_VC_MANIFEST_EMBED_DLL) ##WIN32##$(SDEF): ..\util\support\libkrb5support.exports ##WIN32## echo EXPORTS > $(SDEF).new ##WIN32## type ..\util\support\libkrb5support.exports >> $(SDEF).new ##WIN32## -$(RM) $(SDEF) ##WIN32## ren $(SDEF).new $(SDEF) ##WIN32##$(CLIB): $(CDEF) $(CLIBS) $(CGLUE) $(CRES) $(SLIB) ##WIN32## link $(WINDLLFLAGS) -def:$(CDEF) -out:$*.dll \ ##WIN32## $(CLIBS) $(CGLUE) $(CRES) $(SLIB) $(WINLIBS) ##WIN32## $(_VC_MANIFEST_EMBED_DLL) ##WIN32##$(PLIB): $(PDEF) $(PLIBS) $(PGLUE) $(PRES) $(CLIB) $(SLIB) ##WIN32## link $(WINDLLFLAGS) -def:$(PDEF) -out:$*.dll \ ##WIN32## $(PLIBS) $(PGLUE) $(PRES) $(CLIB) $(SLIB) $(WINLIBS) ##WIN32## $(_VC_MANIFEST_EMBED_DLL) ##WIN32##$(KLIB): $(KDEF) $(KLIBS) $(KGLUE) $(KRES) $(CLIB) $(SLIB) $(MITLIBS) ##WIN32## link $(WINDLLFLAGS) -def:$(KDEF) -out:$*.dll \ ##WIN32## $(KLIBS) $(KGLUE) $(KRES) $(CLIB) $(SLIB) $(MITLIBS) $(DNSLIBS) $(WINLIBS) ##WIN32## $(_VC_MANIFEST_EMBED_DLL) ##WIN32##$(GLIB): $(GDEF) $(GLIBS) $(GGLUE) $(GRES) $(KLIB) $(CLIB) $(SLIB) ##WIN32## link $(WINDLLFLAGS) -def:$(GDEF) -out:$*.dll \ ##WIN32## $(GLIBS) $(GGLUE) $(GRES) $(KLIB) $(CLIB) $(SLIB) $(WINLIBS) ##WIN32## $(_VC_MANIFEST_EMBED_DLL) ##WIN32##$(K5_GLUE): win_glue.c ##WIN32## $(CC) $(ALL_CFLAGS) $(MITFLAGS) /c /DKRB5=1 /Fo$@ $** ##WIN32##$(GSS_GLUE): win_glue.c ##WIN32## $(CC) $(ALL_CFLAGS) /c /DGSSAPI=1 /Fo$@ $** ##WIN32##$(COMERR_GLUE): win_glue.c ##WIN32## $(CC) $(ALL_CFLAGS) /c /DCOMERR=1 /Fo$@ $** ##WIN32##$(PROF_GLUE): win_glue.c ##WIN32## $(CC) $(ALL_CFLAGS) /c /DPROFILELIB=1 /Fo$@ $** ##WIN32##$(S_GLUE): win_glue.c ##WIN32## $(CC) $(ALL_CFLAGS) /c /DSUPPORTLIB=1 /Fo$@ $** ##WIN32### Build Convenience ##WIN32##comerr.lib: $(CLIB) ##WIN32##krb5.lib: $(KLIB) ##WIN32##gssapi.lib: $(GLIB) ##WIN32##profile.lib: $(PLIB) ##WIN32##all-windows: all-recurse lib-windows ##WIN32##lib-windows: krb5.lib gssapi.lib profile.lib krb5-1.22.1/src/lib/crypto/0000775000175000017500000000000015051422640015216 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/openssl/0000775000175000017500000000000015051422640016701 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/openssl/pbkdf2.c0000664000175000017500000000440215051422640020215 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/pbkdf2.c */ /* * Copyright 2002, 2008, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #ifdef K5_OPENSSL_HMAC #include #include #include krb5_error_code krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash, const krb5_data *out, unsigned long count, const krb5_data *pass, const krb5_data *salt) { const EVP_MD *md = NULL; int ok; /* Get the message digest handle corresponding to the hash. */ if (hash == &krb5int_hash_sha1) md = EVP_sha1(); else if (hash == &krb5int_hash_sha256) md = EVP_sha256(); else if (hash == &krb5int_hash_sha384) md = EVP_sha384(); if (md == NULL) return KRB5_CRYPTO_INTERNAL; ok = PKCS5_PBKDF2_HMAC(pass->data, pass->length, (unsigned char *)salt->data, salt->length, count, md, out->length, (unsigned char *)out->data); return ok ? 0 : KRB5_CRYPTO_INTERNAL; } #endif /* K5_OPENSSL_HMAC */ krb5-1.22.1/src/lib/crypto/openssl/hash_provider/0000775000175000017500000000000015051422640021536 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/openssl/hash_provider/hash_evp.c0000664000175000017500000000777615051422640023520 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/hash_provider/hash_evp.c - OpenSSL hash providers */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "crypto_int.h" #if defined(K5_OPENSSL_MD4) || defined(K5_OPENSSL_MD5) || \ defined(K5_OPENSSL_SHA1) || defined(K5_OPENSSL_SHA2) #include /* 1.1 standardizes constructor and destructor names, renaming * EVP_MD_CTX_create and EVP_MD_CTX_destroy. */ #if OPENSSL_VERSION_NUMBER < 0x10100000L #define EVP_MD_CTX_new EVP_MD_CTX_create #define EVP_MD_CTX_free EVP_MD_CTX_destroy #endif static krb5_error_code hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { EVP_MD_CTX *ctx; const krb5_data *d; size_t i; int ok; if (output->length != (unsigned int)EVP_MD_size(type)) return KRB5_CRYPTO_INTERNAL; ctx = EVP_MD_CTX_new(); if (ctx == NULL) return ENOMEM; ok = EVP_DigestInit_ex(ctx, type, NULL); for (i = 0; i < num_data; i++) { if (!SIGN_IOV(&data[i])) continue; d = &data[i].data; ok = ok && EVP_DigestUpdate(ctx, d->data, d->length); } ok = ok && EVP_DigestFinal_ex(ctx, (uint8_t *)output->data, NULL); EVP_MD_CTX_free(ctx); return ok ? 0 : KRB5_CRYPTO_INTERNAL; } #endif #ifdef K5_OPENSSL_MD4 static krb5_error_code hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { return hash_evp(EVP_md4(), data, num_data, output); } const struct krb5_hash_provider krb5int_hash_md4 = { "MD4", 16, 64, hash_md4 }; #endif #ifdef K5_OPENSSL_MD5 static krb5_error_code hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { return hash_evp(EVP_md5(), data, num_data, output); } const struct krb5_hash_provider krb5int_hash_md5 = { "MD5", 16, 64, hash_md5 }; #endif #ifdef K5_OPENSSL_SHA1 static krb5_error_code hash_sha1(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { return hash_evp(EVP_sha1(), data, num_data, output); } const struct krb5_hash_provider krb5int_hash_sha1 = { "SHA1", 20, 64, hash_sha1 }; #endif #ifdef K5_OPENSSL_SHA2 static krb5_error_code hash_sha256(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { return hash_evp(EVP_sha256(), data, num_data, output); } static krb5_error_code hash_sha384(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { return hash_evp(EVP_sha384(), data, num_data, output); } const struct krb5_hash_provider krb5int_hash_sha256 = { "SHA-256", 32, 64, hash_sha256 }; const struct krb5_hash_provider krb5int_hash_sha384 = { "SHA-384", 48, 128, hash_sha384 }; #endif krb5-1.22.1/src/lib/crypto/openssl/hash_provider/Makefile.in0000664000175000017500000000052015051422640023600 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)openssl$(S)hash_provider BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLAGS) STLIBOBJS= hash_evp.o OBJS= $(OUTPRE)hash_evp.$(OBJEXT) SRCS= $(srcdir)/hash_evp.c all-unix: all-libobjs includes: depend depend: $(SRCS) clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/openssl/hash_provider/deps0000664000175000017500000000145315051422640022417 0ustar ghudsonghudson# # Generated makefile dependencies follow. # hash_evp.so hash_evp.po $(OUTPRE)hash_evp.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h hash_evp.c krb5-1.22.1/src/lib/crypto/openssl/Makefile.in0000664000175000017500000000141515051422640020747 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)openssl BUILDTOP=$(REL)..$(S)..$(S).. SUBDIRS=des enc_provider hash_provider LOCALINCLUDES=-I$(srcdir)/../krb $(CRYPTO_IMPL_CFLAGS) STLIBOBJS=\ cmac.o \ hmac.o \ kdf.o \ pbkdf2.o \ sha256.o OBJS=\ $(OUTPRE)cmac.$(OBJEXT) \ $(OUTPRE)hmac.$(OBJEXT) \ $(OUTPRE)kdf.$(OBJEXT) \ $(OUTPRE)pbkdf2.$(OBJEXT) \ $(OUTPRE)sha256.$(OBJEXT) SRCS=\ $(srcdir)/cmac.c \ $(srcdir)/hmac.c \ $(srcdir)/kdf.c \ $(srcdir)/pbkdf2.c \ $(srcdir)/sha256.c SUBDIROBJLISTS= des/OBJS.ST md4/OBJS.ST \ md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ enc_provider/OBJS.ST \ hash_provider/OBJS.ST \ aes/OBJS.ST STOBJLISTS= $(SUBDIROBJLISTS) OBJS.ST all-unix: all-libobjs includes: depend depend: $(SRCS) clean-unix:: clean-libobjs @lib_frag@ @libobj_frag@ krb5-1.22.1/src/lib/crypto/openssl/cmac.c0000664000175000017500000000620115051422640017747 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/cmac.c - OpenSSL CMAC implementation */ /* * Copyright (C) 2021 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "crypto_int.h" #ifdef K5_OPENSSL_CMAC #include #include #include krb5_error_code krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { int ok; EVP_MAC *mac = NULL; EVP_MAC_CTX *ctx = NULL; OSSL_PARAM params[2], *p = params; size_t i = 0, md_len; char *cipher; if (enc == &krb5int_enc_camellia128) cipher = "CAMELLIA-128-CBC"; else if (enc == &krb5int_enc_camellia256) cipher = "CAMELLIA-256-CBC"; else return KRB5_CRYPTO_INTERNAL; mac = EVP_MAC_fetch(NULL, "CMAC", NULL); if (mac == NULL) return KRB5_CRYPTO_INTERNAL; ctx = EVP_MAC_CTX_new(mac); if (ctx == NULL) { ok = 0; goto cleanup; } *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER, cipher, 0); *p = OSSL_PARAM_construct_end(); ok = EVP_MAC_init(ctx, key->keyblock.contents, key->keyblock.length, params); for (i = 0; ok && i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (!SIGN_IOV(iov)) continue; ok = EVP_MAC_update(ctx, (uint8_t *)iov->data.data, iov->data.length); } ok = ok && EVP_MAC_final(ctx, (unsigned char *)output->data, &md_len, output->length); if (!ok) goto cleanup; output->length = md_len; cleanup: EVP_MAC_free(mac); EVP_MAC_CTX_free(ctx); return ok ? 0 : KRB5_CRYPTO_INTERNAL; } #endif /* K5_OPENSSL_CMAC */ krb5-1.22.1/src/lib/crypto/openssl/kdf.c0000664000175000017500000001662315051422640017621 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2021 by Red Hat, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "crypto_int.h" #ifdef K5_OPENSSL_KDF #include #include #include static char * hash_name(const struct krb5_hash_provider *hash) { if (hash == &krb5int_hash_sha1) return "SHA1"; if (hash == &krb5int_hash_sha256) return "SHA256"; if (hash == &krb5int_hash_sha384) return "SHA384"; return NULL; } static char * enc_name(const struct krb5_enc_provider *enc) { if (enc == &krb5int_enc_camellia128) return "CAMELLIA-128-CBC"; if (enc == &krb5int_enc_camellia256) return "CAMELLIA-256-CBC"; if (enc == &krb5int_enc_aes128) return "AES-128-CBC"; if (enc == &krb5int_enc_aes256) return "AES-256-CBC"; if (enc == &krb5int_enc_des3) return "DES-EDE3-CBC"; return NULL; } krb5_error_code k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash, krb5_key key, const krb5_data *label, const krb5_data *context, krb5_data *rnd_out) { krb5_error_code ret; EVP_KDF *kdf = NULL; EVP_KDF_CTX *kctx = NULL; OSSL_PARAM params[6], *p = params; char *digest; digest = hash_name(hash); if (digest == NULL) { ret = KRB5_CRYPTO_INTERNAL; goto done; } kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL); if (!kdf) { ret = KRB5_CRYPTO_INTERNAL; goto done; } kctx = EVP_KDF_CTX_new(kdf); if (!kctx) { ret = KRB5_CRYPTO_INTERNAL; goto done; } *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, digest, 0); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, OSSL_MAC_NAME_HMAC, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key->keyblock.contents, key->keyblock.length); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, context->data, context->length); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, label->data, label->length); *p = OSSL_PARAM_construct_end(); if (EVP_KDF_derive(kctx, (uint8_t *)rnd_out->data, rnd_out->length, params) <= 0) { ret = KRB5_CRYPTO_INTERNAL; goto done; } ret = 0; done: if (ret) zap(rnd_out->data, rnd_out->length); EVP_KDF_free(kdf); EVP_KDF_CTX_free(kctx); return ret; } krb5_error_code k5_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc, krb5_key key, const krb5_data *label, krb5_data *rnd_out) { krb5_error_code ret; EVP_KDF *kdf = NULL; EVP_KDF_CTX *kctx = NULL; OSSL_PARAM params[7], *p = params; char *cipher; static uint8_t zeroes[16]; memset(zeroes, 0, sizeof(zeroes)); cipher = enc_name(enc); if (cipher == NULL) { ret = KRB5_CRYPTO_INTERNAL; goto done; } kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL); if (!kdf) { ret = KRB5_CRYPTO_INTERNAL; goto done; } kctx = EVP_KDF_CTX_new(kdf); if (!kctx) { ret = KRB5_CRYPTO_INTERNAL; goto done; } *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE, "FEEDBACK", 0); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, OSSL_MAC_NAME_CMAC, 0); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER, cipher, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key->keyblock.contents, key->keyblock.length); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, label->data, label->length); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, zeroes, sizeof(zeroes)); *p = OSSL_PARAM_construct_end(); if (EVP_KDF_derive(kctx, (uint8_t *)rnd_out->data, rnd_out->length, params) <= 0) { ret = KRB5_CRYPTO_INTERNAL; goto done; } ret = 0; done: if (ret) zap(rnd_out->data, rnd_out->length); EVP_KDF_free(kdf); EVP_KDF_CTX_free(kctx); return ret; } krb5_error_code k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key key, const krb5_data *constant, krb5_data *rnd_out) { krb5_error_code ret; EVP_KDF *kdf = NULL; EVP_KDF_CTX *kctx = NULL; OSSL_PARAM params[4], *p = params; char *cipher; if (key->keyblock.length != enc->keylength || rnd_out->length != enc->keybytes) { return KRB5_CRYPTO_INTERNAL; } cipher = enc_name(enc); if (cipher == NULL) { ret = KRB5_CRYPTO_INTERNAL; goto done; } kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL); if (kdf == NULL) { ret = KRB5_CRYPTO_INTERNAL; goto done; } kctx = EVP_KDF_CTX_new(kdf); if (kctx == NULL) { ret = KRB5_CRYPTO_INTERNAL; goto done; } *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER, cipher, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key->keyblock.contents, key->keyblock.length); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_CONSTANT, constant->data, constant->length); *p = OSSL_PARAM_construct_end(); if (EVP_KDF_derive(kctx, (uint8_t *)rnd_out->data, rnd_out->length, params) <= 0) { ret = KRB5_CRYPTO_INTERNAL; goto done; } ret = 0; done: if (ret) zap(rnd_out->data, rnd_out->length); EVP_KDF_free(kdf); EVP_KDF_CTX_free(kctx); return ret; } #endif /* K5_OPENSSL_KDF */ krb5-1.22.1/src/lib/crypto/openssl/deps0000664000175000017500000000731415051422640017564 0ustar ghudsonghudson# # Generated makefile dependencies follow. # cmac.so cmac.po $(OUTPRE)cmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cmac.c hmac.so hmac.po $(OUTPRE)hmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hmac.c kdf.so kdf.po $(OUTPRE)kdf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ kdf.c pbkdf2.so pbkdf2.po $(OUTPRE)pbkdf2.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ pbkdf2.c sha256.so sha256.po $(OUTPRE)sha256.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ sha256.c krb5-1.22.1/src/lib/crypto/openssl/des/0000775000175000017500000000000015051422640017454 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/openssl/des/Makefile.in0000664000175000017500000000050215051422640021516 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)openssl$(S)des BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLAGS) STLIBOBJS= des_keys.o OBJS= $(OUTPRE)des_keys.$(OBJEXT) SRCS= $(srcdir)/des_keys.c all-unix: all-libobjs includes: depend depend: $(SRCS) clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/openssl/des/des_keys.c0000664000175000017500000000303115051422640021423 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/des/des_keys.c - Key functions used by Kerberos code */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #ifdef K5_OPENSSL_DES_KEY_PARITY #include void k5_des_fixup_key_parity(unsigned char *keybits) { DES_set_odd_parity((DES_cblock *)keybits); } #endif krb5-1.22.1/src/lib/crypto/openssl/des/deps0000664000175000017500000000145315051422640020335 0ustar ghudsonghudson# # Generated makefile dependencies follow. # des_keys.so des_keys.po $(OUTPRE)des_keys.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h des_keys.c krb5-1.22.1/src/lib/crypto/openssl/enc_provider/0000775000175000017500000000000015051422640021360 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/openssl/enc_provider/camellia.c0000664000175000017500000003245615051422640023305 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/enc_provider/camellia.c */ /* * Copyright (C) 2003, 2007, 2008, 2009, 2010 by the Massachusetts Institute of * Technology. All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #ifdef K5_OPENSSL_CAMELLIA #include #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L #include #else #include #endif static krb5_error_code cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); static krb5_error_code cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); static krb5_error_code cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen); static krb5_error_code cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen); #define BLOCK_SIZE 16 #define NUM_BITS 8 #define IV_CTS_BUF_SIZE 16 /* 16 - hardcoded in CRYPTO_cts128_en/decrypt */ static const EVP_CIPHER * map_mode(unsigned int len) { if (len==16) return EVP_camellia_128_cbc(); if (len==32) return EVP_camellia_256_cbc(); else return NULL; } /* Encrypt one block using CBC. */ static krb5_error_code cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX *ctx; struct iov_cursor cursor; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return ENOMEM; ret = EVP_EncryptInit_ex(ctx, map_mode(key->keyblock.length), NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); return KRB5_CRYPTO_INTERNAL; } k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); k5_iov_cursor_get(&cursor, iblock); EVP_CIPHER_CTX_set_padding(ctx,0); ret = EVP_EncryptUpdate(ctx, oblock, &olen, iblock, BLOCK_SIZE); if (ret == 1) k5_iov_cursor_put(&cursor, oblock); EVP_CIPHER_CTX_free(ctx); zap(iblock, BLOCK_SIZE); zap(oblock, BLOCK_SIZE); return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; } /* Decrypt one block using CBC. */ static krb5_error_code cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX *ctx; struct iov_cursor cursor; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return ENOMEM; ret = EVP_DecryptInit_ex(ctx, map_mode(key->keyblock.length), NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); return KRB5_CRYPTO_INTERNAL; } k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); k5_iov_cursor_get(&cursor, iblock); EVP_CIPHER_CTX_set_padding(ctx,0); ret = EVP_DecryptUpdate(ctx, oblock, &olen, iblock, BLOCK_SIZE); if (ret == 1) k5_iov_cursor_put(&cursor, oblock); EVP_CIPHER_CTX_free(ctx); zap(iblock, BLOCK_SIZE); zap(oblock, BLOCK_SIZE); return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; } #if OPENSSL_VERSION_NUMBER >= 0x30000000L static krb5_error_code do_cts(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen, int encrypt) { krb5_error_code ret; int outlen, len; unsigned char *oblock = NULL, *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; struct iov_cursor cursor; OSSL_PARAM params[2], *p = params; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER *cipher = NULL; memset(iv_cts, 0, sizeof(iv_cts)); if (ivec != NULL && ivec->data != NULL){ if (ivec->length != sizeof(iv_cts)) return KRB5_CRYPTO_INTERNAL; memcpy(iv_cts, ivec->data, ivec->length); } if (key->keyblock.length == 16) cipher = EVP_CIPHER_fetch(NULL, "CAMELLIA-128-CBC-CTS", NULL); else if (key->keyblock.length == 32) cipher = EVP_CIPHER_fetch(NULL, "CAMELLIA-256-CBC-CTS", NULL); if (cipher == NULL) return KRB5_CRYPTO_INTERNAL; oblock = OPENSSL_malloc(dlen); dbuf = OPENSSL_malloc(dlen); ctx = EVP_CIPHER_CTX_new(); if (oblock == NULL || dbuf == NULL || ctx == NULL) { ret = ENOMEM; goto cleanup; } k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); k5_iov_cursor_get(&cursor, dbuf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, "CS3", 0); *p = OSSL_PARAM_construct_end(); if (!EVP_CipherInit_ex2(ctx, cipher, key->keyblock.contents, iv_cts, encrypt, params) || !EVP_CipherUpdate(ctx, oblock, &outlen, dbuf, dlen) || !EVP_CipherFinal_ex(ctx, oblock + outlen, &len)) { ret = KRB5_CRYPTO_INTERNAL; goto cleanup; } if (ivec != NULL && ivec->data != NULL && !EVP_CIPHER_CTX_get_updated_iv(ctx, ivec->data, sizeof(iv_cts))) { ret = KRB5_CRYPTO_INTERNAL; goto cleanup; } k5_iov_cursor_put(&cursor, oblock); ret = 0; cleanup: OPENSSL_clear_free(oblock, dlen); OPENSSL_clear_free(dbuf, dlen); EVP_CIPHER_CTX_free(ctx); EVP_CIPHER_free(cipher); return ret; } static inline krb5_error_code cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) { return do_cts(key, ivec, data, num_data, dlen, 1); } static inline krb5_error_code cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) { return do_cts(key, ivec, data, num_data, dlen, 0); } #else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ static krb5_error_code cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) { int ret = 0; size_t size = 0; unsigned char *oblock = NULL, *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; struct iov_cursor cursor; CAMELLIA_KEY enck; memset(iv_cts,0,sizeof(iv_cts)); if (ivec && ivec->data){ if (ivec->length != sizeof(iv_cts)) return KRB5_CRYPTO_INTERNAL; memcpy(iv_cts, ivec->data,ivec->length); } oblock = OPENSSL_malloc(dlen); if (!oblock){ return ENOMEM; } dbuf = OPENSSL_malloc(dlen); if (!dbuf){ OPENSSL_free(oblock); return ENOMEM; } k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); k5_iov_cursor_get(&cursor, dbuf); Camellia_set_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, &enck); size = CRYPTO_cts128_encrypt((unsigned char *)dbuf, oblock, dlen, &enck, iv_cts, (cbc128_f)Camellia_cbc_encrypt); if (size <= 0) ret = KRB5_CRYPTO_INTERNAL; else k5_iov_cursor_put(&cursor, oblock); if (!ret && ivec && ivec->data) memcpy(ivec->data, iv_cts, sizeof(iv_cts)); zap(oblock, dlen); zap(dbuf, dlen); OPENSSL_free(oblock); OPENSSL_free(dbuf); return ret; } static krb5_error_code cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) { int ret = 0; size_t size = 0; unsigned char *oblock = NULL; unsigned char *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; struct iov_cursor cursor; CAMELLIA_KEY deck; memset(iv_cts,0,sizeof(iv_cts)); if (ivec && ivec->data){ if (ivec->length != sizeof(iv_cts)) return KRB5_CRYPTO_INTERNAL; memcpy(iv_cts, ivec->data,ivec->length); } oblock = OPENSSL_malloc(dlen); if (!oblock) return ENOMEM; dbuf = OPENSSL_malloc(dlen); if (!dbuf){ OPENSSL_free(oblock); return ENOMEM; } Camellia_set_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, &deck); k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); k5_iov_cursor_get(&cursor, dbuf); size = CRYPTO_cts128_decrypt((unsigned char *)dbuf, oblock, dlen, &deck, iv_cts, (cbc128_f)Camellia_cbc_encrypt); if (size <= 0) ret = KRB5_CRYPTO_INTERNAL; else k5_iov_cursor_put(&cursor, oblock); if (!ret && ivec && ivec->data) memcpy(ivec->data, iv_cts, sizeof(iv_cts)); zap(oblock, dlen); zap(dbuf, dlen); OPENSSL_free(oblock); OPENSSL_free(dbuf); return ret; } #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ krb5_error_code krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0; size_t input_length, nblocks; input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { if (input_length != BLOCK_SIZE) return KRB5_BAD_MSIZE; ret = cbc_enc(key, ivec, data, num_data); } else if (nblocks > 1) { ret = cts_encr(key, ivec, data, num_data, input_length); } return ret; } static krb5_error_code krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0; size_t input_length, nblocks; input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { if (input_length != BLOCK_SIZE) return KRB5_BAD_MSIZE; ret = cbc_decr(key, ivec, data, num_data); } else if (nblocks > 1) { ret = cts_decr(key, ivec, data, num_data, input_length); } return ret; } #ifdef K5_BUILTIN_CMAC static void xorblock(uint8_t *out, const uint8_t *in) { int z; for (z = 0; z < CAMELLIA_BLOCK_SIZE / 4; z++) { uint8_t *outptr = &out[z * 4]; const uint8_t *inptr = &in[z * 4]; store_32_n(load_32_n(outptr) ^ load_32_n(inptr), outptr); } } static krb5_error_code krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data, const krb5_data *iv, krb5_data *output) { CAMELLIA_KEY enck; unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE]; struct iov_cursor cursor; if (output->length < CAMELLIA_BLOCK_SIZE) return KRB5_BAD_MSIZE; Camellia_set_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, &enck); if (iv != NULL) memcpy(blockY, iv->data, CAMELLIA_BLOCK_SIZE); else memset(blockY, 0, CAMELLIA_BLOCK_SIZE); k5_iov_cursor_init(&cursor, data, num_data, CAMELLIA_BLOCK_SIZE, FALSE); while (k5_iov_cursor_get(&cursor, blockB)) { xorblock(blockB, blockY); Camellia_ecb_encrypt(blockB, blockY, &enck, 1); } output->length = CAMELLIA_BLOCK_SIZE; memcpy(output->data, blockY, CAMELLIA_BLOCK_SIZE); return 0; } #else #define krb5int_camellia_cbc_mac NULL #endif static krb5_error_code krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage, krb5_data *state) { state->length = 16; state->data = (void *) malloc(16); if (state->data == NULL) return ENOMEM; memset(state->data, 0, state->length); return 0; } const struct krb5_enc_provider krb5int_enc_camellia128 = { 16, 16, 16, krb5int_camellia_encrypt, krb5int_camellia_decrypt, krb5int_camellia_cbc_mac, /* NULL if K5_BUILTIN_CMAC not defined */ krb5int_camellia_init_state, krb5int_default_free_state }; const struct krb5_enc_provider krb5int_enc_camellia256 = { 16, 32, 32, krb5int_camellia_encrypt, krb5int_camellia_decrypt, krb5int_camellia_cbc_mac, /* NULL if K5_BUILTIN_CMAC not defined */ krb5int_camellia_init_state, krb5int_default_free_state }; #endif /* K5_OPENSSL_CAMELLIA */ krb5-1.22.1/src/lib/crypto/openssl/enc_provider/rc4.c0000664000175000017500000001242415051422640022217 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/enc_provider/rc4.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (c) 2000 by Computer Science Laboratory, * Rensselaer Polytechnic Institute * * #include STD_DISCLAIMER */ #include "crypto_int.h" #ifdef K5_OPENSSL_RC4 #include /* * The loopback field is a pointer to the structure. If the application copies * the state (not a valid operation, but one which happens to works with some * other enc providers), we can detect it via the loopback field and return a * sane error code. */ struct arcfour_state { struct arcfour_state *loopback; EVP_CIPHER_CTX *ctx; }; #define RC4_KEY_SIZE 16 #define RC4_BLOCK_SIZE 1 /* Interface layer to krb5 crypto layer */ /* The workhorse of the arcfour system, * this implements the cipher */ /* In-place IOV crypto */ static krb5_error_code k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data, size_t num_data) { size_t i; int ret = 1, tmp_len = 0; krb5_crypto_iov *iov = NULL; EVP_CIPHER_CTX *ctx = NULL; struct arcfour_state *arcstate; arcstate = (state != NULL) ? (void *)state->data : NULL; if (arcstate != NULL) { ctx = arcstate->ctx; if (arcstate->loopback != arcstate) return KRB5_CRYPTO_INTERNAL; } if (ctx == NULL) { ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return ENOMEM; ret = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, key->keyblock.contents, NULL); if (!ret) { EVP_CIPHER_CTX_free(ctx); return KRB5_CRYPTO_INTERNAL; } if (arcstate != NULL) arcstate->ctx = ctx; } for (i = 0; i < num_data; i++) { iov = &data[i]; if (ENCRYPT_IOV(iov)) { ret = EVP_EncryptUpdate(ctx, (unsigned char *) iov->data.data, &tmp_len, (unsigned char *) iov->data.data, iov->data.length); if (!ret) break; } } if (arcstate == NULL) EVP_CIPHER_CTX_free(ctx); if (!ret) return KRB5_CRYPTO_INTERNAL; return 0; } static void k5_arcfour_free_state(krb5_data *state) { struct arcfour_state *arcstate = (void *)state->data; EVP_CIPHER_CTX_free(arcstate->ctx); free(arcstate); } static krb5_error_code k5_arcfour_init_state(const krb5_keyblock *key, krb5_keyusage keyusage, krb5_data *new_state) { struct arcfour_state *arcstate; /* * The cipher state here is a saved pointer to a struct arcfour_state * object, rather than a flat byte array as in most enc providers. The * object includes a loopback pointer to detect if if the caller made a * copy of the krb5_data value or otherwise assumed it was a simple byte * array. When we cast the data pointer back, we need to go through void * * to avoid increased alignment warnings. */ /* Create a state structure with an uninitialized context. */ arcstate = calloc(1, sizeof(*arcstate)); if (arcstate == NULL) return ENOMEM; arcstate->loopback = arcstate; arcstate->ctx = NULL; new_state->data = (char *) arcstate; new_state->length = sizeof(*arcstate); return 0; } /* Since the arcfour cipher is identical going forwards and backwards, we just call "docrypt" directly */ const struct krb5_enc_provider krb5int_enc_arcfour = { /* This seems to work... although I am not sure what the implications are in other places in the kerberos library */ RC4_BLOCK_SIZE, /* Keysize is arbitrary in arcfour, but the constraints of the system, and to attempt to work with the MSFT system forces us to 16byte/128bit. Since there is no parity in the key, the byte and length are the same. */ RC4_KEY_SIZE, RC4_KEY_SIZE, k5_arcfour_docrypt, k5_arcfour_docrypt, NULL, k5_arcfour_init_state, k5_arcfour_free_state }; #endif /* K5_OPENSSL_RC4 */ krb5-1.22.1/src/lib/crypto/openssl/enc_provider/Makefile.in0000664000175000017500000000100215051422640023416 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)openssl$(S)enc_provider BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLAGS) STLIBOBJS= \ des3.o \ rc4.o \ aes.o \ camellia.o OBJS= \ $(OUTPRE)des3.$(OBJEXT) \ $(OUTPRE)aes.$(OBJEXT) \ $(OUTPRE)camellia.$(OBJEXT) \ $(OUTPRE)rc4.$(OBJEXT) SRCS= \ $(srcdir)/des3.c \ $(srcdir)/aes.c \ $(srcdir)/camellia.c \ $(srcdir)/rc4.c all-unix: all-libobjs includes: depend depend: $(SRCS) clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/openssl/enc_provider/deps0000664000175000017500000000575215051422640022247 0ustar ghudsonghudson# # Generated makefile dependencies follow. # des3.so des3.po $(OUTPRE)des3.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ des3.c aes.so aes.po $(OUTPRE)aes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ aes.c camellia.so camellia.po $(OUTPRE)camellia.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h camellia.c rc4.so rc4.po $(OUTPRE)rc4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ rc4.c krb5-1.22.1/src/lib/crypto/openssl/enc_provider/des3.c0000664000175000017500000001407015051422640022364 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/enc_provider/des3.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" #ifdef K5_OPENSSL_DES #include #define DES3_BLOCK_SIZE 8 #define DES3_KEY_SIZE 24 #define DES3_KEY_BYTES 21 static krb5_error_code validate(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data, krb5_boolean *empty) { size_t input_length = iov_total_length(data, num_data, FALSE); if (key->keyblock.length != DES3_KEY_SIZE) return(KRB5_BAD_KEYSIZE); if ((input_length%DES3_BLOCK_SIZE) != 0) return(KRB5_BAD_MSIZE); if (ivec && (ivec->length != 8)) return(KRB5_BAD_MSIZE); *empty = (input_length == 0); return 0; } static krb5_error_code k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret, olen = DES3_BLOCK_SIZE; unsigned char iblock[DES3_BLOCK_SIZE], oblock[DES3_BLOCK_SIZE]; struct iov_cursor cursor; EVP_CIPHER_CTX *ctx; krb5_boolean empty; ret = validate(key, ivec, data, num_data, &empty); if (ret != 0 || empty) return ret; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return ENOMEM; ret = EVP_EncryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); if (!ret) { EVP_CIPHER_CTX_free(ctx); return KRB5_CRYPTO_INTERNAL; } EVP_CIPHER_CTX_set_padding(ctx,0); k5_iov_cursor_init(&cursor, data, num_data, DES3_BLOCK_SIZE, FALSE); while (k5_iov_cursor_get(&cursor, iblock)) { ret = EVP_EncryptUpdate(ctx, oblock, &olen, iblock, DES3_BLOCK_SIZE); if (!ret) break; k5_iov_cursor_put(&cursor, oblock); } if (ivec != NULL) memcpy(ivec->data, oblock, DES3_BLOCK_SIZE); EVP_CIPHER_CTX_free(ctx); zap(iblock, sizeof(iblock)); zap(oblock, sizeof(oblock)); if (ret != 1) return KRB5_CRYPTO_INTERNAL; return 0; } static krb5_error_code k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret, olen = DES3_BLOCK_SIZE; unsigned char iblock[DES3_BLOCK_SIZE], oblock[DES3_BLOCK_SIZE]; struct iov_cursor cursor; EVP_CIPHER_CTX *ctx; krb5_boolean empty; ret = validate(key, ivec, data, num_data, &empty); if (ret != 0 || empty) return ret; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return ENOMEM; ret = EVP_DecryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); if (!ret) { EVP_CIPHER_CTX_free(ctx); return KRB5_CRYPTO_INTERNAL; } EVP_CIPHER_CTX_set_padding(ctx,0); k5_iov_cursor_init(&cursor, data, num_data, DES3_BLOCK_SIZE, FALSE); while (k5_iov_cursor_get(&cursor, iblock)) { ret = EVP_DecryptUpdate(ctx, oblock, &olen, (unsigned char *)iblock, DES3_BLOCK_SIZE); if (!ret) break; k5_iov_cursor_put(&cursor, oblock); } if (ivec != NULL) memcpy(ivec->data, iblock, DES3_BLOCK_SIZE); EVP_CIPHER_CTX_free(ctx); zap(iblock, sizeof(iblock)); zap(oblock, sizeof(oblock)); if (ret != 1) return KRB5_CRYPTO_INTERNAL; return 0; } const struct krb5_enc_provider krb5int_enc_des3 = { DES3_BLOCK_SIZE, DES3_KEY_BYTES, DES3_KEY_SIZE, k5_des3_encrypt, k5_des3_decrypt, NULL, krb5int_des_init_state, krb5int_default_free_state }; #endif /* K5_OPENSSL_DES */ krb5-1.22.1/src/lib/crypto/openssl/enc_provider/aes.c0000664000175000017500000002740515051422640022304 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/enc_provider/aes.c */ /* * Copyright (C) 2003, 2007, 2008, 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #ifdef K5_OPENSSL_AES #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L #include #else #include #include #endif /* proto's */ static krb5_error_code cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); static krb5_error_code cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); static krb5_error_code cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen); static krb5_error_code cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen); #define BLOCK_SIZE 16 #define NUM_BITS 8 #define IV_CTS_BUF_SIZE 16 /* 16 - hardcoded in CRYPTO_cts128_en/decrypt */ static const EVP_CIPHER * map_mode(unsigned int len) { if (len==16) return EVP_aes_128_cbc(); if (len==32) return EVP_aes_256_cbc(); else return NULL; } /* Encrypt one block using CBC. */ static krb5_error_code cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX *ctx; struct iov_cursor cursor; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return ENOMEM; ret = EVP_EncryptInit_ex(ctx, map_mode(key->keyblock.length), NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); return KRB5_CRYPTO_INTERNAL; } k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); k5_iov_cursor_get(&cursor, iblock); EVP_CIPHER_CTX_set_padding(ctx,0); ret = EVP_EncryptUpdate(ctx, oblock, &olen, iblock, BLOCK_SIZE); if (ret == 1) k5_iov_cursor_put(&cursor, oblock); EVP_CIPHER_CTX_free(ctx); zap(iblock, BLOCK_SIZE); zap(oblock, BLOCK_SIZE); return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; } /* Decrypt one block using CBC. */ static krb5_error_code cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0, olen = BLOCK_SIZE; unsigned char iblock[BLOCK_SIZE], oblock[BLOCK_SIZE]; EVP_CIPHER_CTX *ctx; struct iov_cursor cursor; ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return ENOMEM; ret = EVP_DecryptInit_ex(ctx, map_mode(key->keyblock.length), NULL, key->keyblock.contents, (ivec) ? (unsigned char*)ivec->data : NULL); if (ret == 0) { EVP_CIPHER_CTX_free(ctx); return KRB5_CRYPTO_INTERNAL; } k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); k5_iov_cursor_get(&cursor, iblock); EVP_CIPHER_CTX_set_padding(ctx,0); ret = EVP_DecryptUpdate(ctx, oblock, &olen, iblock, BLOCK_SIZE); if (ret == 1) k5_iov_cursor_put(&cursor, oblock); EVP_CIPHER_CTX_free(ctx); zap(iblock, BLOCK_SIZE); zap(oblock, BLOCK_SIZE); return (ret == 1) ? 0 : KRB5_CRYPTO_INTERNAL; } #if OPENSSL_VERSION_NUMBER >= 0x30000000L static krb5_error_code do_cts(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen, int encrypt) { krb5_error_code ret; int outlen, len; unsigned char *oblock = NULL, *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; struct iov_cursor cursor; OSSL_PARAM params[2], *p = params; EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER *cipher = NULL; memset(iv_cts, 0, sizeof(iv_cts)); if (ivec != NULL && ivec->data != NULL){ if (ivec->length != sizeof(iv_cts)) return KRB5_CRYPTO_INTERNAL; memcpy(iv_cts, ivec->data, ivec->length); } if (key->keyblock.length == 16) cipher = EVP_CIPHER_fetch(NULL, "AES-128-CBC-CTS", NULL); else if (key->keyblock.length == 32) cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC-CTS", NULL); if (cipher == NULL) return KRB5_CRYPTO_INTERNAL; oblock = OPENSSL_malloc(dlen); dbuf = OPENSSL_malloc(dlen); ctx = EVP_CIPHER_CTX_new(); if (oblock == NULL || dbuf == NULL || ctx == NULL) { ret = ENOMEM; goto cleanup; } k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); k5_iov_cursor_get(&cursor, dbuf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, "CS3", 0); *p = OSSL_PARAM_construct_end(); if (!EVP_CipherInit_ex2(ctx, cipher, key->keyblock.contents, iv_cts, encrypt, params) || !EVP_CipherUpdate(ctx, oblock, &outlen, dbuf, dlen) || !EVP_CipherFinal_ex(ctx, oblock + outlen, &len)) { ret = KRB5_CRYPTO_INTERNAL; goto cleanup; } if (ivec != NULL && ivec->data != NULL && !EVP_CIPHER_CTX_get_updated_iv(ctx, ivec->data, sizeof(iv_cts))) { ret = KRB5_CRYPTO_INTERNAL; goto cleanup; } k5_iov_cursor_put(&cursor, oblock); ret = 0; cleanup: OPENSSL_clear_free(oblock, dlen); OPENSSL_clear_free(dbuf, dlen); EVP_CIPHER_CTX_free(ctx); EVP_CIPHER_free(cipher); return ret; } static inline krb5_error_code cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) { return do_cts(key, ivec, data, num_data, dlen, 1); } static inline krb5_error_code cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) { return do_cts(key, ivec, data, num_data, dlen, 0); } #else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ static krb5_error_code cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) { int ret = 0; size_t size = 0; unsigned char *oblock = NULL, *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; struct iov_cursor cursor; AES_KEY enck; memset(iv_cts,0,sizeof(iv_cts)); if (ivec && ivec->data){ if (ivec->length != sizeof(iv_cts)) return KRB5_CRYPTO_INTERNAL; memcpy(iv_cts, ivec->data,ivec->length); } oblock = OPENSSL_malloc(dlen); if (!oblock){ return ENOMEM; } dbuf = OPENSSL_malloc(dlen); if (!dbuf){ OPENSSL_free(oblock); return ENOMEM; } k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); k5_iov_cursor_get(&cursor, dbuf); AES_set_encrypt_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, &enck); size = CRYPTO_cts128_encrypt((unsigned char *)dbuf, oblock, dlen, &enck, iv_cts, (cbc128_f)AES_cbc_encrypt); if (size <= 0) ret = KRB5_CRYPTO_INTERNAL; else k5_iov_cursor_put(&cursor, oblock); if (!ret && ivec && ivec->data) memcpy(ivec->data, iv_cts, sizeof(iv_cts)); zap(oblock, dlen); zap(dbuf, dlen); OPENSSL_free(oblock); OPENSSL_free(dbuf); return ret; } static krb5_error_code cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, size_t dlen) { int ret = 0; size_t size = 0; unsigned char *oblock = NULL; unsigned char *dbuf = NULL; unsigned char iv_cts[IV_CTS_BUF_SIZE]; struct iov_cursor cursor; AES_KEY deck; memset(iv_cts,0,sizeof(iv_cts)); if (ivec && ivec->data){ if (ivec->length != sizeof(iv_cts)) return KRB5_CRYPTO_INTERNAL; memcpy(iv_cts, ivec->data,ivec->length); } oblock = OPENSSL_malloc(dlen); if (!oblock) return ENOMEM; dbuf = OPENSSL_malloc(dlen); if (!dbuf){ OPENSSL_free(oblock); return ENOMEM; } AES_set_decrypt_key(key->keyblock.contents, NUM_BITS * key->keyblock.length, &deck); k5_iov_cursor_init(&cursor, data, num_data, dlen, FALSE); k5_iov_cursor_get(&cursor, dbuf); size = CRYPTO_cts128_decrypt((unsigned char *)dbuf, oblock, dlen, &deck, iv_cts, (cbc128_f)AES_cbc_encrypt); if (size <= 0) ret = KRB5_CRYPTO_INTERNAL; else k5_iov_cursor_put(&cursor, oblock); if (!ret && ivec && ivec->data) memcpy(ivec->data, iv_cts, sizeof(iv_cts)); zap(oblock, dlen); zap(dbuf, dlen); OPENSSL_free(oblock); OPENSSL_free(dbuf); return ret; } #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ krb5_error_code krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0; size_t input_length, nblocks; input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { if (input_length != BLOCK_SIZE) return KRB5_BAD_MSIZE; ret = cbc_enc(key, ivec, data, num_data); } else if (nblocks > 1) { ret = cts_encr(key, ivec, data, num_data, input_length); } return ret; } krb5_error_code krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { int ret = 0; size_t input_length, nblocks; input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { if (input_length != BLOCK_SIZE) return KRB5_BAD_MSIZE; ret = cbc_decr(key, ivec, data, num_data); } else if (nblocks > 1) { ret = cts_decr(key, ivec, data, num_data, input_length); } return ret; } static krb5_error_code krb5int_aes_init_state (const krb5_keyblock *key, krb5_keyusage usage, krb5_data *state) { state->length = 16; state->data = (void *) malloc(16); if (state->data == NULL) return ENOMEM; memset(state->data, 0, state->length); return 0; } const struct krb5_enc_provider krb5int_enc_aes128 = { 16, 16, 16, krb5int_aes_encrypt, krb5int_aes_decrypt, NULL, krb5int_aes_init_state, krb5int_default_free_state }; const struct krb5_enc_provider krb5int_enc_aes256 = { 16, 32, 32, krb5int_aes_encrypt, krb5int_aes_decrypt, NULL, krb5int_aes_init_state, krb5int_default_free_state }; #endif /* K5_OPENSSL_AES */ krb5-1.22.1/src/lib/crypto/openssl/sha256.c0000664000175000017500000000445515051422640020065 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/sha256.c - k5_sha256() implementation */ /* * Copyright (C) 2016 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "crypto_int.h" #ifdef K5_OPENSSL_SHA2 #include /* 1.1 standardizes constructor and destructor names, renaming * EVP_MD_CTX_create and EVP_MD_CTX_destroy. */ #if OPENSSL_VERSION_NUMBER < 0x10100000L #define EVP_MD_CTX_new EVP_MD_CTX_create #define EVP_MD_CTX_free EVP_MD_CTX_destroy #endif krb5_error_code k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN]) { EVP_MD_CTX *ctx; size_t i; int ok; ctx = EVP_MD_CTX_new(); if (ctx == NULL) return ENOMEM; ok = EVP_DigestInit_ex(ctx, EVP_sha256(), NULL); for (i = 0; i < n; i++) ok = ok && EVP_DigestUpdate(ctx, in[i].data, in[i].length); ok = ok && EVP_DigestFinal_ex(ctx, out, NULL); EVP_MD_CTX_free(ctx); return ok ? 0 : KRB5_CRYPTO_INTERNAL; } #endif krb5-1.22.1/src/lib/crypto/openssl/hmac.c0000664000175000017500000001622515051422640017763 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/openssl/hmac.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" #ifdef K5_OPENSSL_HMAC #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L #include #include #else #include #endif #if OPENSSL_VERSION_NUMBER < 0x10100000L /* OpenSSL 1.1 makes HMAC_CTX opaque, while 1.0 does not have pointer * constructors or destructors. */ #define HMAC_CTX_new compat_hmac_ctx_new static HMAC_CTX * compat_hmac_ctx_new(void) { HMAC_CTX *ctx; ctx = calloc(1, sizeof(*ctx)); if (ctx != NULL) HMAC_CTX_init(ctx); return ctx; } #define HMAC_CTX_free compat_hmac_ctx_free static void compat_hmac_ctx_free(HMAC_CTX *ctx) { HMAC_CTX_cleanup(ctx); free(ctx); } #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ /* * the HMAC transform looks like: * * H(K XOR opad, H(K XOR ipad, text)) * * where H is a cryptographic hash * K is an n byte key * ipad is the byte 0x36 repeated blocksize times * opad is the byte 0x5c repeated blocksize times * and text is the data being protected */ static const EVP_MD * map_digest(const struct krb5_hash_provider *hash) { if (hash == &krb5int_hash_sha1) return EVP_sha1(); else if (hash == &krb5int_hash_sha256) return EVP_sha256(); else if (hash == &krb5int_hash_sha384) return EVP_sha384(); else if (hash == &krb5int_hash_md5) return EVP_md5(); else if (hash == &krb5int_hash_md4) return EVP_md4(); else return NULL; } #if OPENSSL_VERSION_NUMBER >= 0x30000000L krb5_error_code krb5int_hmac_keyblock(const struct krb5_hash_provider *hash, const krb5_keyblock *keyblock, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { int ok; const EVP_MD *md = map_digest(hash); EVP_MAC *mac = NULL; EVP_MAC_CTX *ctx = NULL; OSSL_PARAM params[2], *p = params; size_t i = 0, md_len; if (md == NULL || keyblock->length > hash->blocksize) return KRB5_CRYPTO_INTERNAL; if (output->length < hash->hashsize) return KRB5_BAD_MSIZE; mac = EVP_MAC_fetch(NULL, "HMAC", NULL); if (mac == NULL) return KRB5_CRYPTO_INTERNAL; ctx = EVP_MAC_CTX_new(mac); if (ctx == NULL) { ok = 0; goto cleanup; } *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST, (char *)EVP_MD_get0_name(md), 0); *p = OSSL_PARAM_construct_end(); ok = EVP_MAC_init(ctx, keyblock->contents, keyblock->length, params); for (i = 0; ok && i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (!SIGN_IOV(iov)) continue; ok = EVP_MAC_update(ctx, (uint8_t *)iov->data.data, iov->data.length); } ok = ok && EVP_MAC_final(ctx, (uint8_t *)output->data, &md_len, output->length); if (!ok) goto cleanup; output->length = md_len; cleanup: EVP_MAC_free(mac); EVP_MAC_CTX_free(ctx); return ok ? 0 : KRB5_CRYPTO_INTERNAL; } #else /* OPENSSL_VERSION_NUMBER < 0x30000000L */ krb5_error_code krb5int_hmac_keyblock(const struct krb5_hash_provider *hash, const krb5_keyblock *keyblock, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { unsigned int i = 0, md_len = 0, ok; unsigned char md[EVP_MAX_MD_SIZE]; HMAC_CTX *ctx; size_t hashsize, blocksize; hashsize = hash->hashsize; blocksize = hash->blocksize; if (keyblock->length > blocksize) return(KRB5_CRYPTO_INTERNAL); if (output->length < hashsize) return(KRB5_BAD_MSIZE); if (!map_digest(hash)) return(KRB5_CRYPTO_INTERNAL); // unsupported alg ctx = HMAC_CTX_new(); if (ctx == NULL) return ENOMEM; ok = HMAC_Init_ex(ctx, keyblock->contents, keyblock->length, map_digest(hash), NULL); for (i = 0; ok && i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (SIGN_IOV(iov)) ok = HMAC_Update(ctx, (uint8_t *)iov->data.data, iov->data.length); } if (ok) ok = HMAC_Final(ctx, md, &md_len); if (ok && md_len <= output->length) { output->length = md_len; memcpy(output->data, md, output->length); } HMAC_CTX_free(ctx); return ok ? 0 : KRB5_CRYPTO_INTERNAL; } #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ krb5_error_code krb5int_hmac(const struct krb5_hash_provider *hash, krb5_key key, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { return krb5int_hmac_keyblock(hash, &key->keyblock, data, num_data, output); } #endif /* K5_OPENSSL_HMAC */ krb5-1.22.1/src/lib/crypto/libk5crypto.exports0000664000175000017500000000420715051422640021116 0ustar ghudsonghudsonkrb5_c_make_random_key krb5_c_encrypt_length krb5_process_key krb5_string_to_cksumtype krb5_c_valid_enctype krb5_c_valid_cksumtype krb5_string_to_key krb5_c_encrypt_iov krb5_c_checksum_length is_keyed_cksum krb5_c_padding_length is_coll_proof_cksum krb5_init_random_key krb5_c_string_to_key_with_params krb5_c_random_make_octets krb5_c_random_os_entropy krb5_c_decrypt krb5_c_crypto_length krb5_c_block_size krb5_cksumtype_to_string krb5_c_keyed_checksum_types krb5_c_is_keyed_cksum krb5_c_crypto_length_iov valid_cksumtype krb5_c_random_seed krb5_c_random_to_key krb5_verify_checksum krb5_c_free_state krb5_c_verify_checksum krb5_c_random_add_entropy krb5_c_decrypt_iov krb5_c_make_checksum krb5_checksum_size krb5_free_cksumtypes krb5_finish_key krb5_encrypt_size krb5_c_keylengths krb5_c_prf krb5_encrypt krb5_string_to_enctype krb5_c_is_coll_proof_cksum krb5_c_init_state krb5_eblock_enctype krb5_decrypt krb5_c_encrypt krb5_c_enctype_compare krb5_c_verify_checksum_iov valid_enctype krb5_enctype_to_string krb5_enctype_to_name krb5_c_make_checksum_iov krb5_calculate_checksum krb5_c_string_to_key krb5_use_enctype krb5_random_key krb5_finish_random_key krb5_c_prf_length krb5int_c_mandatory_cksumtype krb5_c_fx_cf2_simple krb5int_c_weak_enctype krb5_encrypt_data krb5int_c_copy_keyblock krb5int_c_copy_keyblock_contents krb5int_c_free_keyblock_contents krb5int_c_free_keyblock krb5int_c_init_keyblock krb5int_hash_md4 krb5int_hash_md5 krb5int_hash_sha256 krb5int_hash_sha384 krb5int_enc_arcfour krb5int_hmac krb5_k_create_key krb5_k_decrypt krb5_k_decrypt_iov krb5_k_encrypt krb5_k_encrypt_iov krb5_k_free_key krb5_k_key_enctype krb5_k_key_keyblock krb5_k_make_checksum krb5_k_make_checksum_iov krb5_k_prf krb5_k_reference_key krb5_k_verify_checksum krb5_k_verify_checksum_iov krb5int_aes_encrypt krb5int_aes_decrypt krb5int_enc_des3 krb5int_arcfour_gsscrypt krb5int_camellia_encrypt krb5int_cmac_checksum krb5int_enc_aes128 krb5int_enc_aes256 krb5int_enc_camellia128 krb5int_enc_camellia256 krb5int_derive_key krb5int_derive_random k5_sha256 krb5int_nfold k5_allow_weak_pbkdf2iter krb5_c_prfplus krb5_c_derive_prfplus k5_enctype_to_ssf krb5int_c_deprecated_enctype k5_hmac_md5 krb5-1.22.1/src/lib/crypto/Makefile.in0000664000175000017500000000307215051422640017265 0ustar ghudsonghudsonmydir=lib$(S)crypto BUILDTOP=$(REL)..$(S).. SUBDIRS= krb builtin openssl crypto_tests WINSUBDIRS= krb builtin crypto_tests LOCALINCLUDES=$(CRYPTO_IMPL_CFLAGS) LIBBASE=k5crypto LIBMAJOR=3 LIBMINOR=1 RELDIR=crypto STOBJLISTS=krb/OBJS.ST \ builtin/OBJS.ST builtin/des/OBJS.ST \ builtin/aes/OBJS.ST builtin/camellia/OBJS.ST \ builtin/md4/OBJS.ST builtin/md5/OBJS.ST \ builtin/sha1/OBJS.ST builtin/sha2/OBJS.ST \ builtin/enc_provider/OBJS.ST builtin/hash_provider/OBJS.ST \ openssl/OBJS.ST openssl/des/OBJS.ST \ openssl/enc_provider/OBJS.ST openssl/hash_provider/OBJS.ST SUBDIROBJLISTS=$(STOBJLISTS) # No dependencies. Record places to find this shared object if the target # link editor and loader support it. DEPLIBS= SHLIB_EXPLIBS= $(SUPPORT_LIB) $(CRYPTO_IMPL_LIBS) $(LIBS) SHLIB_EXPDEPLIBS= $(SUPPORT_DEPLIB) SHLIB_LDFLAGS= $(LDFLAGS) @SHLIB_RPATH_DIRS@ ##DOS##LIBNAME=$(OUTPRE)crypto.lib ##DOS##OBJFILEDEP=$(OUTPRE)krb.lst $(OUTPRE)aes.lst $(OUTPRE)enc_provider.lst $(OUTPRE)des.lst $(OUTPRE)md5.lst $(OUTPRE)camellia.lst $(OUTPRE)md4.lst $(OUTPRE)hash_provider.lst $(OUTPRE)sha2.lst $(OUTPRE)sha1.lst $(OUTPRE)builtin.lst ##DOS##OBJFILELIST=@$(OUTPRE)krb.lst @$(OUTPRE)aes.lst @$(OUTPRE)enc_provider.lst @$(OUTPRE)des.lst @$(OUTPRE)md5.lst @$(OUTPRE)camellia.lst @$(OUTPRE)md4.lst @$(OUTPRE)hash_provider.lst @$(OUTPRE)sha2.lst @$(OUTPRE)sha1.lst @$(OUTPRE)builtin.lst all-unix: all-liblinks install-unix: install-libs # all-unix: # install-unix: libcrypto.lib: libdir crypto.lib clean-unix:: clean-liblinks clean-libs clean-libobjs @lib_frag@ @libobj_frag@ krb5-1.22.1/src/lib/crypto/crypto_tests/0000775000175000017500000000000015051422640017760 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/crypto_tests/t_cts.c0000664000175000017500000001140015051422640021234 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_cts.c */ /* * Copyright 2001, 2007 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * Test vectors for crypto code, matching data submitted for inclusion * with RFC1510bis. * * N.B.: Doesn't compile -- this file uses some routines internal to our * crypto library which are declared "static" and thus aren't accessible * without modifying the other sources. */ #include #include #include #include #include "crypto_int.h" #define ASIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0])) const char *whoami; #define JURISIC "Juri\305\241i\304\207" /* hi Miro */ #define ESZETT "\303\237" #define GCLEF "\360\235\204\236" /* outside BMP, woo hoo! */ static void printd (const char *descr, krb5_data *d) { unsigned int i, j; const int r = 16; printf("%s:", descr); for (i = 0; i < d->length; i += r) { printf("\n %04x: ", i); for (j = i; j < i + r && j < d->length; j++) printf(" %02x", 0xff & d->data[j]); #ifdef SHOW_TEXT for (; j < i + r; j++) printf(" "); printf(" "); for (j = i; j < i + r && j < d->length; j++) { int c = 0xff & d->data[j]; printf("%c", isprint(c) ? c : '.'); } #endif } printf("\n"); } static void printk(const char *descr, krb5_keyblock *k) { krb5_data d; d.data = (char *) k->contents; d.length = k->length; printd(descr, &d); } static void test_cts(void) { static const char input[4*16] = "I would like the General Gau's Chicken, please, and wonton soup."; static const unsigned char aeskey[16] = "chicken teriyaki"; static const int lengths[] = { 17, 31, 32, 47, 48, 64 }; unsigned int i; char outbuf[64], encivbuf[16], decivbuf[16]; krb5_crypto_iov iov; krb5_data in, enciv, deciv; krb5_keyblock keyblock; krb5_key key; krb5_error_code err; iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data.data = outbuf; in.data = (char *)input; enciv.length = deciv.length = 16; enciv.data = encivbuf; deciv.data = decivbuf; keyblock.contents = (krb5_octet *)aeskey; keyblock.length = 16; keyblock.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96; err = krb5_k_create_key(NULL, &keyblock, &key); if (err) { printf("error %ld from krb5_k_create_key\n", (long)err); exit(1); } memset(enciv.data, 0, 16); printk("AES 128-bit key", &keyblock); for (i = 0; i < sizeof(lengths)/sizeof(lengths[0]); i++) { memset(enciv.data, 0, 16); memset(deciv.data, 0, 16); printf("\n"); iov.data.length = in.length = lengths[i]; memcpy(outbuf, input, lengths[i]); printd("IV", &enciv); err = krb5int_aes_encrypt(key, &enciv, &iov, 1); if (err) { printf("error %ld from krb5int_aes_encrypt\n", (long)err); exit(1); } printd("Input", &in); printd("Output", &iov.data); printd("Next IV", &enciv); err = krb5int_aes_decrypt(key, &deciv, &iov, 1); if (err) { printf("error %ld from krb5int_aes_decrypt\n", (long)err); exit(1); } if (memcmp(outbuf, input, lengths[i]) != 0) { printd("Decryption result DOESN'T MATCH", &iov.data); exit(1); } if (memcmp(enciv.data, deciv.data, 16)) { printd("Decryption IV result DOESN'T MATCH", &deciv); exit(1); } } krb5_k_free_key(NULL, key); } int main (int argc, char **argv) { whoami = argv[0]; test_cts(); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_fork.c0000664000175000017500000001014215051422640021406 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_fork.c */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test basic libk5crypto behavior across forks. This is primarily interesting * for back ends with PKCS11-based constraints. */ #include "k5-int.h" #include #include #include static krb5_context ctx = NULL; static void t(krb5_error_code code) { if (code != 0) { fprintf(stderr, "Failure: %s\n", krb5_get_error_message(ctx, code)); exit(1); } } static void prepare_enc_data(krb5_key key, size_t in_len, krb5_enc_data *enc_data) { size_t out_len; t(krb5_c_encrypt_length(ctx, key->keyblock.enctype, in_len, &out_len)); t(alloc_data(&enc_data->ciphertext, out_len)); } int main(void) { krb5_keyblock kb_aes, kb_rc4; krb5_key key_aes, key_rc4; krb5_data state_rc4, plain = string2data("plain"), decrypted; krb5_enc_data out_aes, out_rc4; pid_t pid, wpid; int status; /* Seed the PRNG instead of creating a context, so we don't need * krb5.conf. */ t(krb5_c_random_seed(ctx, &plain)); /* Create AES and RC4 ciphertexts with random keys. Use cipher state for * RC4. */ t(krb5_c_make_random_key(ctx, ENCTYPE_AES256_CTS_HMAC_SHA1_96, &kb_aes)); t(krb5_c_make_random_key(ctx, ENCTYPE_ARCFOUR_HMAC, &kb_rc4)); t(krb5_k_create_key(ctx, &kb_aes, &key_aes)); t(krb5_k_create_key(ctx, &kb_rc4, &key_rc4)); prepare_enc_data(key_aes, plain.length, &out_aes); prepare_enc_data(key_aes, plain.length, &out_rc4); t(krb5_c_init_state(ctx, &kb_rc4, 0, &state_rc4)); t(krb5_k_encrypt(ctx, key_aes, 0, NULL, &plain, &out_aes)); t(krb5_k_encrypt(ctx, key_rc4, 0, &state_rc4, &plain, &out_rc4)); /* Fork; continue in both parent and child. */ pid = fork(); assert(pid >= 0); /* Decrypt the AES message with both key and keyblock. */ t(alloc_data(&decrypted, plain.length)); t(krb5_k_decrypt(ctx, key_aes, 0, NULL, &out_aes, &decrypted)); assert(data_eq(plain, decrypted)); t(krb5_c_decrypt(ctx, &kb_aes, 0, NULL, &out_aes, &decrypted)); assert(data_eq(plain, decrypted)); /* Encrypt another RC4 message. */ t(krb5_k_encrypt(ctx, key_rc4, 0, &state_rc4, &plain, &out_rc4)); t(krb5_c_free_state(ctx, &kb_rc4, &state_rc4)); krb5_free_keyblock_contents(ctx, &kb_aes); krb5_free_keyblock_contents(ctx, &kb_rc4); krb5_k_free_key(ctx, key_aes); krb5_k_free_key(ctx, key_rc4); krb5_free_data_contents(ctx, &out_aes.ciphertext); krb5_free_data_contents(ctx, &out_rc4.ciphertext); krb5_free_data_contents(ctx, &decrypted); /* If we're the parent, make sure the child succeeded. */ if (pid != 0) { wpid = wait(&status); assert(wpid == pid); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { fprintf(stderr, "Child failed with status %d\n", status); return 1; } } return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_short.c0000664000175000017500000001036315051422640021611 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_short.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Tests the outcome of decrypting overly short tokens. This program can be * run under a tool like valgrind to detect bad memory accesses; when run * normally by the test suite, it verifies that each operation returns * KRB5_BAD_MSIZE. */ #include "k5-int.h" krb5_enctype interesting_enctypes[] = { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC_EXP, ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96, ENCTYPE_CAMELLIA128_CTS_CMAC, ENCTYPE_CAMELLIA256_CTS_CMAC, ENCTYPE_AES128_CTS_HMAC_SHA256_128, ENCTYPE_AES256_CTS_HMAC_SHA384_192, 0 }; /* Abort if an operation unexpectedly fails. */ static void x(krb5_error_code code) { if (code != 0) abort(); } /* Abort if a decrypt operation doesn't have the expected result. */ static void check_decrypt_result(krb5_error_code code, size_t len, size_t min_len) { if (len < min_len) { /* Undersized tokens should always result in BAD_MSIZE. */ if (code != KRB5_BAD_MSIZE) abort(); } else { /* Min-size tokens should succeed or fail the integrity check. */ if (code != 0 && code != KRB5KRB_AP_ERR_BAD_INTEGRITY) abort(); } } static void test_enctype(krb5_enctype enctype) { krb5_error_code ret; krb5_keyblock keyblock; krb5_enc_data input; krb5_data output; krb5_crypto_iov iov[2]; unsigned int dummy; size_t min_len, len; printf("Testing enctype %d\n", (int) enctype); x(krb5_c_encrypt_length(NULL, enctype, 0, &min_len)); x(krb5_c_make_random_key(NULL, enctype, &keyblock)); input.enctype = enctype; /* Try each length up to the minimum length. */ for (len = 0; len <= min_len; len++) { input.ciphertext.data = calloc(len, 1); input.ciphertext.length = len; output.data = calloc(len, 1); output.length = len; /* Attempt a normal decryption. */ ret = krb5_c_decrypt(NULL, &keyblock, 0, NULL, &input, &output); check_decrypt_result(ret, len, min_len); if (krb5_c_crypto_length(NULL, enctype, KRB5_CRYPTO_TYPE_HEADER, &dummy) == 0) { /* Attempt an IOV stream decryption. */ iov[0].flags = KRB5_CRYPTO_TYPE_STREAM; iov[0].data = input.ciphertext; iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data.data = NULL; iov[1].data.length = 0; ret = krb5_c_decrypt_iov(NULL, &keyblock, 0, NULL, iov, 2); check_decrypt_result(ret, len, min_len); } free(input.ciphertext.data); free(output.data); } krb5int_c_free_keyblock_contents (NULL, &keyblock); } int main(int argc, char **argv) { int i; krb5_data notrandom; notrandom.data = "notrandom"; notrandom.length = 9; krb5_c_random_seed(NULL, ¬random); for (i = 0; interesting_enctypes[i]; i++) test_enctype(interesting_enctypes[i]); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/aes-test.c0000664000175000017500000000773215051422640021662 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/aes-test.c */ /* * Copyright (C) 2002 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Subset of NIST tests for AES; specifically, the variable-key and * variable-text tests for 128- and 256-bit keys. */ #include #include "crypto_int.h" static char key[32]; static char plain[16], cipher[16], zero[16]; static krb5_keyblock enc_key; static krb5_data ivec; static void init(void) { enc_key.contents = (krb5_octet *)key; enc_key.length = 16; ivec.data = zero; ivec.length = 16; } static void enc(void) { krb5_key k; krb5_crypto_iov iov; memcpy(cipher, plain, 16); iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(cipher, 16); krb5_k_create_key(NULL, &enc_key, &k); krb5int_aes_encrypt(k, &ivec, &iov, 1); krb5_k_free_key(NULL, k); } static void hexdump(const char *label, const char *cp, int len) { printf("%s=", label); while (len--) printf("%02X", 0xff & *cp++); printf("\n"); } static void set_bit(char *ptr, int bitnum) { int bytenum; bytenum = bitnum / 8; bitnum %= 8; /* First bit is the high bit! */ ptr[bytenum] = 1 << (7 - bitnum); } /* Variable-Key tests */ static void vk_test_1(int len, krb5_enctype etype) { int i; enc_key.length = len; enc_key.enctype = etype; printf("\nKEYSIZE=%d\n\n", len * 8); memset(plain, 0, sizeof(plain)); hexdump("PT", plain, 16); for (i = 0; i < len * 8; i++) { memset(key, 0, len); set_bit(key, i); printf("\nI=%d\n", i+1); hexdump("KEY", key, len); enc(); hexdump("CT", cipher, 16); } printf("\n==========\n"); } static void vk_test(void) { vk_test_1(16, ENCTYPE_AES128_CTS_HMAC_SHA1_96); vk_test_1(32, ENCTYPE_AES256_CTS_HMAC_SHA1_96); } /* Variable-Text tests */ static void vt_test_1(int len, krb5_enctype etype) { int i; enc_key.length = len; enc_key.enctype = etype; printf("\nKEYSIZE=%d\n\n", len * 8); memset(key, 0, len); hexdump("KEY", key, len); for (i = 0; i < 16 * 8; i++) { memset(plain, 0, sizeof(plain)); set_bit(plain, i); printf("\nI=%d\n", i+1); hexdump("PT", plain, 16); enc(); hexdump("CT", cipher, 16); } printf("\n==========\n"); } static void vt_test(void) { vt_test_1(16, ENCTYPE_AES128_CTS_HMAC_SHA1_96); vt_test_1(32, ENCTYPE_AES256_CTS_HMAC_SHA1_96); } int main (int argc, char *argv[]) { if (argc > 2 || (argc == 2 && strcmp(argv[1], "-k"))) { fprintf(stderr, "usage:\t%s -k\tfor variable-key tests\n" " or:\t%s \tfor variable-plaintext tests\n", argv[0], argv[0]); return 1; } init(); if (argc == 2) vk_test(); else vt_test(); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/Makefile.in0000664000175000017500000001073515051422640022033 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)crypto_tests BUILDTOP=$(REL)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../krb EXTRADEPSRCS=\ $(srcdir)/t_nfold.c \ $(srcdir)/t_encrypt.c \ $(srcdir)/t_decrypt.c \ $(srcdir)/t_prf.c \ $(srcdir)/t_cmac.c \ $(srcdir)/t_hmac.c \ $(srcdir)/t_pkcs5.c \ $(srcdir)/t_cts.c \ $(srcdir)/vectors.c \ $(srcdir)/aes-test.c \ $(srcdir)/camellia-test.c \ $(srcdir)/t_cf2.c \ $(srcdir)/t_cksums.c \ $(srcdir)/t_mddriver.c \ $(srcdir)/t_kperf.c \ $(srcdir)/t_sha2.c \ $(srcdir)/t_short.c \ $(srcdir)/t_str2key.c \ $(srcdir)/t_derive.c \ $(srcdir)/t_fork.c ##DOS##BUILDTOP = ..\..\.. check-unix: t_nfold t_encrypt t_decrypt t_prf t_cmac t_hmac \ t_cksums \ aes-test \ camellia-test \ t_mddriver4 t_mddriver \ t_cts t_sha2 t_short t_str2key t_derive t_fork t_cf2 $(RUN_TEST) ./t_nfold $(RUN_TEST) ./t_encrypt $(RUN_TEST) ./t_decrypt $(RUN_TEST) ./t_cmac $(RUN_TEST) ./t_hmac $(RUN_TEST) ./t_prf $(RUN_TEST) ./t_cksums $(RUN_TEST) ./t_cts $(RUN_TEST) ./aes-test -k > vk.txt cmp vk.txt $(srcdir)/expect-vk.txt $(RUN_TEST) ./aes-test > vt.txt cmp vt.txt $(srcdir)/expect-vt.txt $(RUN_TEST) ./camellia-test > camellia-vt.txt cmp camellia-vt.txt $(srcdir)/camellia-expect-vt.txt $(RUN_TEST) $(C)t_mddriver4 -x $(RUN_TEST) $(C)t_mddriver -x $(RUN_TEST) ./t_sha2 $(RUN_TEST) ./t_short $(RUN_TEST) ./t_str2key $(RUN_TEST) ./t_derive $(RUN_TEST) ./t_fork $(RUN_TEST) ./t_cf2 <$(srcdir)/t_cf2.in >t_cf2.output diff t_cf2.output $(srcdir)/t_cf2.expected # $(RUN_TEST) ./t_pkcs5 t_nfold$(EXEEXT): t_nfold.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_nfold.$(OBJEXT) $(KRB5_BASE_LIBS) t_encrypt$(EXEEXT): t_encrypt.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_encrypt.$(OBJEXT) $(KRB5_BASE_LIBS) t_decrypt$(EXEEXT): t_decrypt.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_decrypt.$(OBJEXT) $(KRB5_BASE_LIBS) t_prf$(EXEEXT): t_prf.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_prf.$(OBJEXT) $(KRB5_BASE_LIBS) t_cmac$(EXEEXT): t_cmac.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_cmac.$(OBJEXT) $(KRB5_BASE_LIBS) t_hmac$(EXEEXT): t_hmac.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_hmac.$(OBJEXT) $(KRB5_BASE_LIBS) #t_pkcs5$(EXEEXT): t_pkcs5.$(OBJEXT) $(KRB5_BASE_DEPLIBS) # $(CC_LINK) -o $@ t_pkcs5.$(OBJEXT) $(KRB5_BASE_LIBS) vectors$(EXEEXT): vectors.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ vectors.$(OBJEXT) $(KRB5_BASE_LIBS) t_cts$(EXEEXT): t_cts.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_cts.$(OBJEXT) \ $(KRB5_BASE_LIBS) t_sha2$(EXEEXT): t_sha2.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_sha2.$(OBJEXT) \ $(KRB5_BASE_LIBS) t_short$(EXEEXT): t_short.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_short.$(OBJEXT) \ $(KRB5_BASE_LIBS) t_cksums: t_cksums.o $(CRYTPO_DEPLIB) $(CC_LINK) -o t_cksums t_cksums.o -lkrb5 $(KRB5_BASE_LIBS) aes-test: aes-test.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o aes-test aes-test.$(OBJEXT) $(KRB5_BASE_LIBS) camellia-test: camellia-test.$(OBJEXT) $(CRYPTO_DEPLIB) $(CC_LINK) -o camellia-test camellia-test.$(OBJEXT) $(KRB5_BASE_LIBS) t_mddriver4.o: $(srcdir)/t_mddriver.c $(CC) -DMD=4 $(ALL_CFLAGS) -o t_mddriver4.o -c $(srcdir)/t_mddriver.c t_mddriver4: t_mddriver4.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -DMD4 -o t_mddriver4 t_mddriver4.o $(KRB5_BASE_LIBS) t_mddriver: t_mddriver.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_mddriver t_mddriver.o $(KRB5_BASE_LIBS) t_kperf: t_kperf.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_kperf t_kperf.o $(KRB5_BASE_LIBS) t_str2key$(EXEEXT): t_str2key.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_str2key.$(OBJEXT) $(KRB5_BASE_LIBS) t_derive$(EXEEXT): t_derive.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_derive.$(OBJEXT) $(KRB5_BASE_LIBS) t_fork$(EXEEXT): t_fork.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_fork.$(OBJEXT) $(KRB5_BASE_LIBS) t_cf2$(EXEEXT): t_cf2.$(OBJEXT) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_cf2.$(OBJEXT) $(KRB5_BASE_LIBS) clean: $(RM) t_nfold.o t_nfold t_encrypt t_encrypt.o \ t_decrypt.o t_decrypt t_cmac.o t_cmac \ t_hmac.o t_hmac t_pkcs5.o t_pkcs5 t_prf t_prf.o \ aes-test.o aes-test vt.txt vk.txt kresults.out \ t_cts.o t_cts \ t_mddriver4.o t_mddriver4 t_mddriver.o t_mddriver \ t_cksums t_cksums.o \ t_kperf.o t_kperf t_sha2.o t_sha2 t_short t_short.o t_str2key \ t_str2key.o t_derive t_derive.o t_fork t_fork.o \ t_mddriver$(EXEEXT) $(OUTPRE)t_mddriver.$(OBJEXT) \ camellia-test camellia-test.o camellia-vt.txt \ t_cf2 t_cf2.o t_cf2.output -$(RM) t_prf.output @lib_frag@ @libobj_frag@ krb5-1.22.1/src/lib/crypto/crypto_tests/t_encrypt.c0000664000175000017500000002556315051422640022146 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_encrypt.c */ /* * Copyright 2001, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * <<< Description >>> */ /* * Some black-box tests of crypto systems. Make sure that we can decrypt things we encrypt, etc. */ #include "crypto_int.h" #include /* What enctypes should we test?*/ krb5_enctype interesting_enctypes[] = { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC_EXP, ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96, ENCTYPE_CAMELLIA128_CTS_CMAC, ENCTYPE_CAMELLIA256_CTS_CMAC, ENCTYPE_AES128_CTS_HMAC_SHA256_128, ENCTYPE_AES256_CTS_HMAC_SHA384_192, 0 }; static void test(const char *msg, krb5_error_code retval) { printf("%s: . . . ", msg); if (retval) { printf("Failed: %s\n", error_message(retval)); abort(); } else printf("OK\n"); } static int compare_results(krb5_data *d1, krb5_data *d2) { if (d1->length != d2->length) { /* Decryption can leave a little trailing cruft. For the current cryptosystems, this can be up to 7 bytes. */ if (d1->length + 8 <= d2->length) return EINVAL; if (d1->length > d2->length) return EINVAL; } if (memcmp(d1->data, d2->data, d1->length)) { return EINVAL; } return 0; } static void display(const char *msg, const krb5_data *d) { unsigned int i; printf("%s:", msg); for (i = 0; i < d->length; i++) printf(" %02X", (unsigned char) d->data[i]); printf("\n"); } int main(void) { krb5_context context = 0; krb5_data in, in2, out, out2, check, check2, state, signdata; krb5_crypto_iov iov[5]; int i, j, pos; unsigned int dummy; size_t len; krb5_enc_data enc_out, enc_out2; krb5_keyblock *keyblock; krb5_key key; memset(iov, 0, sizeof(iov)); in.data = "This is a test.\n"; in.length = strlen (in.data); in2.data = "This is another test.\n"; in2.length = strlen (in2.data); test ("Seeding random number generator", krb5_c_random_seed (context, &in)); /* Set up output buffers. */ out.data = malloc(2048); out2.data = malloc(2048); check.data = malloc(2048); check2.data = malloc(2048); if (out.data == NULL || out2.data == NULL || check.data == NULL || check2.data == NULL) abort(); out.magic = KV5M_DATA; out.length = 2048; out2.magic = KV5M_DATA; out2.length = 2048; check.length = 2048; check2.length = 2048; for (i = 0; interesting_enctypes[i]; i++) { krb5_enctype enctype = interesting_enctypes [i]; printf ("Testing enctype %d\n", enctype); test ("Initializing a keyblock", krb5_init_keyblock (context, enctype, 0, &keyblock)); test ("Generating random keyblock", krb5_c_make_random_key (context, enctype, keyblock)); test ("Creating opaque key from keyblock", krb5_k_create_key (context, keyblock, &key)); enc_out.ciphertext = out; enc_out2.ciphertext = out2; /* We use an intermediate `len' because size_t may be different size than `int' */ krb5_c_encrypt_length (context, keyblock->enctype, in.length, &len); enc_out.ciphertext.length = len; /* Encrypt, decrypt, and see if we got the plaintext back again. */ test ("Encrypting (c)", krb5_c_encrypt (context, keyblock, 7, 0, &in, &enc_out)); display ("Enc output", &enc_out.ciphertext); test ("Decrypting", krb5_c_decrypt (context, keyblock, 7, 0, &enc_out, &check)); test ("Comparing", compare_results (&in, &check)); /* Try again with the opaque-key-using variants. */ memset(out.data, 0, out.length); test ("Encrypting (k)", krb5_k_encrypt (context, key, 7, 0, &in, &enc_out)); display ("Enc output", &enc_out.ciphertext); test ("Decrypting", krb5_k_decrypt (context, key, 7, 0, &enc_out, &check)); test ("Comparing", compare_results (&in, &check)); /* Check if this enctype supports IOV encryption. */ if ( krb5_c_crypto_length(context, keyblock->enctype, KRB5_CRYPTO_TYPE_HEADER, &dummy) == 0 ){ /* Set up iovecs for stream decryption. */ memcpy(out2.data, enc_out.ciphertext.data, enc_out.ciphertext.length); iov[0].flags= KRB5_CRYPTO_TYPE_STREAM; iov[0].data.data = out2.data; iov[0].data.length = enc_out.ciphertext.length; iov[1].flags = KRB5_CRYPTO_TYPE_DATA; /* Decrypt the encrypted data from above and check it. */ test("IOV stream decrypting (c)", krb5_c_decrypt_iov( context, keyblock, 7, 0, iov, 2)); test("Comparing results", compare_results(&in, &iov[1].data)); /* Try again with the opaque-key-using variant. */ memcpy(out2.data, enc_out.ciphertext.data, enc_out.ciphertext.length); test("IOV stream decrypting (k)", krb5_k_decrypt_iov( context, key, 7, 0, iov, 2)); test("Comparing results", compare_results(&in, &iov[1].data)); /* Set up iovecs for AEAD encryption. */ signdata.magic = KV5M_DATA; signdata.data = (char *) "This should be signed"; signdata.length = strlen(signdata.data); iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data = in; /*We'll need to copy memory before encrypt*/ iov[2].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY; iov[2].data = signdata; iov[3].flags = KRB5_CRYPTO_TYPE_PADDING; iov[4].flags = KRB5_CRYPTO_TYPE_TRAILER; /* "Allocate" data for the iovec buffers from the "out" buffer. */ test("Setting up iov lengths", krb5_c_crypto_length_iov(context, keyblock->enctype, iov, 5)); for (j=0,pos=0; j <= 4; j++ ){ if (iov[j].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY) continue; iov[j].data.data = &out.data[pos]; pos += iov[j].data.length; } assert (iov[1].data.length == in.length); memcpy(iov[1].data.data, in.data, in.length); /* Encrypt and decrypt in place, and check the result. */ test("iov encrypting (c)", krb5_c_encrypt_iov(context, keyblock, 7, 0, iov, 5)); assert(iov[1].data.length == in.length); display("Header", &iov[0].data); display("Data", &iov[1].data); display("Padding", &iov[3].data); display("Trailer", &iov[4].data); test("iov decrypting", krb5_c_decrypt_iov(context, keyblock, 7, 0, iov, 5)); test("Comparing results", compare_results(&in, &iov[1].data)); /* Try again with opaque-key-using variants. */ test("iov encrypting (k)", krb5_k_encrypt_iov(context, key, 7, 0, iov, 5)); assert(iov[1].data.length == in.length); display("Header", &iov[0].data); display("Data", &iov[1].data); display("Padding", &iov[3].data); display("Trailer", &iov[4].data); test("iov decrypting", krb5_k_decrypt_iov(context, key, 7, 0, iov, 5)); test("Comparing results", compare_results(&in, &iov[1].data)); } enc_out.ciphertext.length = out.length; check.length = 2048; test ("init_state", krb5_c_init_state (context, keyblock, 7, &state)); test ("Encrypting with state", krb5_c_encrypt (context, keyblock, 7, &state, &in, &enc_out)); display ("Enc output", &enc_out.ciphertext); test ("Encrypting again with state", krb5_c_encrypt (context, keyblock, 7, &state, &in2, &enc_out2)); display ("Enc output", &enc_out2.ciphertext); test ("free_state", krb5_c_free_state (context, keyblock, &state)); test ("init_state", krb5_c_init_state (context, keyblock, 7, &state)); test ("Decrypting with state", krb5_c_decrypt (context, keyblock, 7, &state, &enc_out, &check)); test ("Decrypting again with state", krb5_c_decrypt (context, keyblock, 7, &state, &enc_out2, &check2)); test ("free_state", krb5_c_free_state (context, keyblock, &state)); test ("Comparing", compare_results (&in, &check)); test ("Comparing", compare_results (&in2, &check2)); krb5_free_keyblock (context, keyblock); krb5_k_free_key (context, key); } /* Test the RC4 decrypt fallback from key usage 9 to 8. */ test ("Initializing an RC4 keyblock", krb5_init_keyblock (context, ENCTYPE_ARCFOUR_HMAC, 0, &keyblock)); test ("Generating random RC4 key", krb5_c_make_random_key (context, ENCTYPE_ARCFOUR_HMAC, keyblock)); enc_out.ciphertext = out; krb5_c_encrypt_length (context, keyblock->enctype, in.length, &len); enc_out.ciphertext.length = len; check.length = 2048; test ("Encrypting with RC4 key usage 8", krb5_c_encrypt (context, keyblock, 8, 0, &in, &enc_out)); display ("Enc output", &enc_out.ciphertext); test ("Decrypting with RC4 key usage 9", krb5_c_decrypt (context, keyblock, 9, 0, &enc_out, &check)); test ("Comparing", compare_results (&in, &check)); krb5_free_keyblock (context, keyblock); free(out.data); free(out2.data); free(check.data); free(check2.data); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_kperf.c0000664000175000017500000001072315051422640021561 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_kperf.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This file contains a harness to measure the performance improvement * of using the the krb5_k functions (which cache derived keys) over * the equivalent krb5_c functions which do not. Sample usages: * * ./t_kperf ce aes128-cts 10 100000 * ./t_kperf kv aes256-cts 1024 10000 * * The first usage encrypts ('e') a hundred thousand ten-byte blobs * with aes128-cts, using the non-caching APIs ('c'). The second * usage verifies ('v') ten thousand checksums over 1K blobs with the * first available keyed checksum type for aes256-cts, using the * caching APIs ('k'). Run commands under "time" to measure how much * time is used by the operations. */ #include "k5-int.h" int main(int argc, char **argv) { krb5_error_code ret; krb5_keyblock kblock; krb5_key key; krb5_enctype enctype; krb5_cksumtype cktype; int blocksize, num_blocks, intf, op, i; size_t outlen, cklen; krb5_data block; krb5_enc_data outblock; krb5_checksum sum; krb5_boolean val; if (argc != 5) { fprintf(stderr, "Usage: t_kperf {c|k}{e|d|m|v} type size nblocks\n"); exit(1); } intf = argv[1][0]; assert(intf == 'c' || intf =='k'); op = argv[1][1]; ret = krb5_string_to_enctype(argv[2], &enctype); assert(!ret); blocksize = atoi(argv[3]); num_blocks = atoi(argv[4]); block.data = "notrandom"; block.length = 9; krb5_c_random_seed(NULL, &block); krb5_c_make_random_key(NULL, enctype, &kblock); krb5_k_create_key(NULL, &kblock, &key); block.length = blocksize; block.data = calloc(1, blocksize); krb5_c_encrypt_length(NULL, enctype, blocksize, &outlen); outblock.enctype = enctype; outblock.ciphertext.length = outlen; outblock.ciphertext.data = calloc(1, outlen); krb5int_c_mandatory_cksumtype(NULL, enctype, &cktype); krb5_c_checksum_length(NULL, cktype, &cklen); sum.checksum_type = cktype; sum.length = cklen; sum.contents = calloc(1, cklen); /* * Decrypting typically involves copying the output after checking the * hash, so we need to create a valid ciphertext to correctly measure its * performance. */ if (op == 'd') krb5_c_encrypt(NULL, &kblock, 0, NULL, &block, &outblock); for (i = 0; i < num_blocks; i++) { if (intf == 'c') { if (op == 'e') krb5_c_encrypt(NULL, &kblock, 0, NULL, &block, &outblock); else if (op == 'd') krb5_c_decrypt(NULL, &kblock, 0, NULL, &outblock, &block); else if (op == 'm') krb5_c_make_checksum(NULL, cktype, &kblock, 0, &block, &sum); else if (op == 'v') krb5_c_verify_checksum(NULL, &kblock, 0, &block, &sum, &val); } else { if (op == 'e') krb5_k_encrypt(NULL, key, 0, NULL, &block, &outblock); else if (op == 'd') krb5_k_decrypt(NULL, key, 0, NULL, &outblock, &block); else if (op == 'm') krb5_k_make_checksum(NULL, cktype, key, 0, &block, &sum); else if (op == 'v') krb5_k_verify_checksum(NULL, key, 0, &block, &sum, &val); } } return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_cf2.expected0000664000175000017500000000042615051422640022502 0ustar ghudsonghudson97df97e4b798b29eb31ed7280287a92a 4d6ca4e629785c1f01baf55e2e548566b9617ae3a96868c337cb93b5e72b1c7b e58f9eb643862c13ad38e529313462a7f73e62834fe54a01 24d7f6b6bae4e5c00d2082c5ebab3672 edd02a39d2dbde31611c16e610be062c 67f6ea530aea85a37dcbb23349ea52dcc61ca8493ff557252327fd8304341584 krb5-1.22.1/src/lib/crypto/crypto_tests/t_nfold.c0000664000175000017500000001247115051422640021556 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_nfold.c - Test nfold implementation correctness */ /* * Copyright 1988, 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include #include "crypto_int.h" #define ASIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0])) static void printhex(size_t len, const unsigned char *p) { while (len--) printf ("%02x", 0xff & *p++); } static void printstringhex(const unsigned char *p) { printhex (strlen ((const char *) p), p); } static void rfc_tests(void) { unsigned i; struct { char *input; unsigned int n; unsigned char exp[192/8]; } tests[] = { { "012345", 64, { 0xbe,0x07,0x26,0x31,0x27,0x6b,0x19,0x55, } }, { "password", 56, { 0x78,0xa0,0x7b,0x6c,0xaf,0x85,0xfa, } }, { "Rough Consensus, and Running Code", 64, { 0xbb,0x6e,0xd3,0x08,0x70,0xb7,0xf0,0xe0, } }, { "password", 168, { 0x59,0xe4,0xa8,0xca,0x7c,0x03,0x85,0xc3, 0xc3,0x7b,0x3f,0x6d,0x20,0x00,0x24,0x7c, 0xb6,0xe6,0xbd,0x5b,0x3e, } }, { "MASSACHVSETTS INSTITVTE OF TECHNOLOGY", 192, { 0xdb,0x3b,0x0d,0x8f,0x0b,0x06,0x1e,0x60, 0x32,0x82,0xb3,0x08,0xa5,0x08,0x41,0x22, 0x9a,0xd7,0x98,0xfa,0xb9,0x54,0x0c,0x1b, } }, }; unsigned char outbuf[192/8]; printf ("RFC tests:\n"); for (i = 0; i < ASIZE (tests); i++) { unsigned char *p = (unsigned char *) tests[i].input; assert (tests[i].n / 8 <= sizeof (outbuf)); krb5int_nfold (8 * strlen ((char *) p), p, tests[i].n, outbuf); printf ("%d-fold(\"%s\") =\n", tests[i].n, p); printf ("%d-fold(", tests[i].n); printstringhex (p); printf (") =\n\t"); printhex (tests[i].n / 8, outbuf); printf ("\n\n"); if (memcmp (outbuf, tests[i].exp, tests[i].n/8) != 0) { printf ("wrong value! expected:\n\t"); printhex (tests[i].n / 8, tests[i].exp); exit (1); } } } static void fold_kerberos(unsigned int nbytes) { unsigned char cipher_text[300]; unsigned int j; if (nbytes > 300) abort(); printf("%d-fold(\"kerberos\") =\n\t", nbytes*8); krb5int_nfold(64, (unsigned char *) "kerberos", 8*nbytes, cipher_text); for (j=0; j #include #include #include #include "crypto_int.h" #define ASIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0])) const char *whoami; static void printhex (size_t len, const char *p) { while (len--) printf ("%02x", 0xff & *p++); } static void printstringhex (const char *p) { printhex (strlen (p), p); } static void printdata (krb5_data *d) { printhex (d->length, d->data); } static void printkey (krb5_keyblock *k) { printhex (k->length, k->contents); } static void test_nfold (void) { int i; static const struct { char *input; int n; } tests[] = { { "012345", 64, }, { "password", 56, }, { "Rough Consensus, and Running Code", 64, }, { "password", 168, }, { "MASSACHVSETTS INSTITVTE OF TECHNOLOGY", 192 }, { "Q", 168 }, { "ba", 168 }, }; unsigned char outbuf[192/8]; for (i = 0; i < ASIZE (tests); i++) { char *p = tests[i].input; assert (tests[i].n / 8 <= sizeof (outbuf)); printf ("%d-fold(\"%s\") =\n", tests[i].n, p); printf ("%d-fold(", tests[i].n); printstringhex (p); printf (") =\n\t"); krb5int_nfold (8 * strlen (p), p, tests[i].n, outbuf); printhex (tests[i].n / 8U, outbuf); printf ("\n\n"); } } #define JURISIC "Juri\305\241i\304\207" /* hi Miro */ #define ESZETT "\303\237" #define GCLEF "\360\235\204\236" /* outside BMP, woo hoo! */ /* Some weak keys: {0x1f,0x1f,0x1f,0x1f,0x0e,0x0e,0x0e,0x0e}, {0xe0,0xe0,0xe0,0xe0,0xf1,0xf1,0xf1,0xf1}, so try to generate them. */ static void test_mit_des_s2k (void) { static const struct { const char *pass; const char *salt; } pairs[] = { { "password", "ATHENA.MIT.EDUraeburn" }, { "potatoe", "WHITEHOUSE.GOVdanny" }, { "penny", "EXAMPLE.COMbuckaroo", }, { GCLEF, "EXAMPLE.COMpianist" }, { ESZETT, "ATHENA.MIT.EDU" JURISIC }, /* These two trigger weak-key fixups. */ { "11119999", "AAAAAAAA" }, { "NNNN6666", "FFFFAAAA" }, }; int i; for (i = 0; i < ASIZE (pairs); i++) { const char *p = pairs[i].pass; const char *s = pairs[i].salt; krb5_data pd; krb5_data sd; unsigned char key_contents[60]; krb5_keyblock key; krb5_error_code r; char buf[80]; key.contents = key_contents; pd.length = strlen (p); pd.data = (char *) p; sd.length = strlen (s); sd.data = (char *) s; assert (strlen (s) + 4 < sizeof (buf)); snprintf (buf, sizeof (buf), "\"%s\"", s); printf ( "salt: %-25s", buf); printhex (strlen(s), s); snprintf (buf, sizeof (buf), "\"%s\"", p); printf ("\npassword: %-25s", buf); printhex (strlen(p), p); printf ("\n"); r = krb5int_des_string_to_key (0, &pd, &sd, 0, &key); printf ( "DES key: %-25s", ""); printhex (key.length, key.contents); printf ("\n\n"); } } static void test_s2k (krb5_enctype enctype) { static const struct { const char *pass; const char *salt; } pairs[] = { { "password", "ATHENA.MIT.EDUraeburn" }, { "potatoe", "WHITEHOUSE.GOVdanny" }, { "penny", "EXAMPLE.COMbuckaroo", }, { ESZETT, "ATHENA.MIT.EDU" JURISIC }, { GCLEF, "EXAMPLE.COMpianist" }, }; int i; for (i = 0; i < ASIZE (pairs); i++) { const char *p = pairs[i].pass; const char *s = pairs[i].salt; krb5_data pd, sd; unsigned char key_contents[60]; krb5_keyblock key; krb5_error_code r; char buf[80]; pd.length = strlen (p); pd.data = (char *) p; sd.length = strlen (s); sd.data = (char *) s; key.contents = key_contents; assert (strlen (s) + 4 < sizeof (buf)); snprintf (buf, sizeof(buf), "\"%s\"", s); printf ( "salt:\t%s\n\t", buf); printhex (strlen(s), s); snprintf (buf, sizeof(buf), "\"%s\"", p); printf ("\npasswd:\t%s\n\t", buf); printhex (strlen(p), p); printf ("\n"); r = krb5_c_string_to_key (0, enctype, &pd, &sd, &key); printf ( "key:\t"); printhex (key.length, key.contents); printf ("\n\n"); } } static void test_des3_s2k (void) { test_s2k (ENCTYPE_DES3_CBC_SHA1); } static void keyToData (krb5_keyblock *k, krb5_data *d) { d->length = k->length; d->data = k->contents; } void check_error (int r, int line) { if (r != 0) { fprintf (stderr, "%s:%d: %s\n", __FILE__, line, error_message (r)); exit (1); } } #define CHECK check_error(r, __LINE__) extern struct krb5_enc_provider krb5int_enc_des3; struct krb5_enc_provider *enc = &krb5int_enc_des3; extern struct krb5_enc_provider krb5int_enc_aes128, krb5int_enc_aes256; void DK (krb5_keyblock *out, krb5_keyblock *in, const krb5_data *usage) { krb5_error_code r; r = krb5int_derive_key (enc, in, out, usage, DERIVE_RFC3961); CHECK; } void DR (krb5_data *out, krb5_keyblock *in, const krb5_data *usage) { krb5_error_code r; r = krb5int_derive_random (enc, in, out, usage, DERIVE_RFC3961); CHECK; } #define KEYBYTES 21 #define KEYLENGTH 24 void test_dr_dk (void) { static const struct { unsigned char keydata[KEYLENGTH]; int usage_len; unsigned char usage[8]; } derive_tests[] = { { { 0xdc, 0xe0, 0x6b, 0x1f, 0x64, 0xc8, 0x57, 0xa1, 0x1c, 0x3d, 0xb5, 0x7c, 0x51, 0x89, 0x9b, 0x2c, 0xc1, 0x79, 0x10, 0x08, 0xce, 0x97, 0x3b, 0x92, }, 5, { 0x00, 0x00, 0x00, 0x01, 0x55 }, }, { { 0x5e, 0x13, 0xd3, 0x1c, 0x70, 0xef, 0x76, 0x57, 0x46, 0x57, 0x85, 0x31, 0xcb, 0x51, 0xc1, 0x5b, 0xf1, 0x1c, 0xa8, 0x2c, 0x97, 0xce, 0xe9, 0xf2, }, 5, { 0x00, 0x00, 0x00, 0x01, 0xaa }, }, { { 0x98, 0xe6, 0xfd, 0x8a, 0x04, 0xa4, 0xb6, 0x85, 0x9b, 0x75, 0xa1, 0x76, 0x54, 0x0b, 0x97, 0x52, 0xba, 0xd3, 0xec, 0xd6, 0x10, 0xa2, 0x52, 0xbc, }, 5, { 0x00, 0x00, 0x00, 0x01, 0x55 }, }, { { 0x62, 0x2a, 0xec, 0x25, 0xa2, 0xfe, 0x2c, 0xad, 0x70, 0x94, 0x68, 0x0b, 0x7c, 0x64, 0x94, 0x02, 0x80, 0x08, 0x4c, 0x1a, 0x7c, 0xec, 0x92, 0xb5, }, 5, { 0x00, 0x00, 0x00, 0x01, 0xaa }, }, { { 0xd3, 0xf8, 0x29, 0x8c, 0xcb, 0x16, 0x64, 0x38, 0xdc, 0xb9, 0xb9, 0x3e, 0xe5, 0xa7, 0x62, 0x92, 0x86, 0xa4, 0x91, 0xf8, 0x38, 0xf8, 0x02, 0xfb, }, 8, { 'k', 'e', 'r', 'b', 'e', 'r', 'o', 's' }, }, { { 0xb5, 0x5e, 0x98, 0x34, 0x67, 0xe5, 0x51, 0xb3, 0xe5, 0xd0, 0xe5, 0xb6, 0xc8, 0x0d, 0x45, 0x76, 0x94, 0x23, 0xa8, 0x73, 0xdc, 0x62, 0xb3, 0x0e, }, 7, { 'c', 'o', 'm', 'b', 'i', 'n', 'e', }, }, { { 0xc1, 0x08, 0x16, 0x49, 0xad, 0xa7, 0x43, 0x62, 0xe6, 0xa1, 0x45, 0x9d, 0x01, 0xdf, 0xd3, 0x0d, 0x67, 0xc2, 0x23, 0x4c, 0x94, 0x07, 0x04, 0xda, }, 5, { 0x00, 0x00, 0x00, 0x01, 0x55 }, }, { { 0x5d, 0x15, 0x4a, 0xf2, 0x38, 0xf4, 0x67, 0x13, 0x15, 0x57, 0x19, 0xd5, 0x5e, 0x2f, 0x1f, 0x79, 0x0d, 0xd6, 0x61, 0xf2, 0x79, 0xa7, 0x91, 0x7c, }, 5, { 0x00, 0x00, 0x00, 0x01, 0xaa }, }, { { 0x79, 0x85, 0x62, 0xe0, 0x49, 0x85, 0x2f, 0x57, 0xdc, 0x8c, 0x34, 0x3b, 0xa1, 0x7f, 0x2c, 0xa1, 0xd9, 0x73, 0x94, 0xef, 0xc8, 0xad, 0xc4, 0x43, }, 5, { 0x00, 0x00, 0x00, 0x01, 0x55 }, }, { { 0x26, 0xdc, 0xe3, 0x34, 0xb5, 0x45, 0x29, 0x2f, 0x2f, 0xea, 0xb9, 0xa8, 0x70, 0x1a, 0x89, 0xa4, 0xb9, 0x9e, 0xb9, 0x94, 0x2c, 0xec, 0xd0, 0x16, }, 5, { 0x00, 0x00, 0x00, 0x01, 0xaa }, }, }; int i; for (i = 0; i < ASIZE(derive_tests); i++) { #define D (derive_tests[i]) krb5_keyblock key; krb5_data usage; unsigned char drData[KEYBYTES]; krb5_data dr; unsigned char dkData[KEYLENGTH]; krb5_keyblock dk; key.length = KEYLENGTH, key.contents = D.keydata; usage.length = D.usage_len, usage.data = D.usage; dr.length = KEYBYTES, dr.data = drData; dk.length = KEYLENGTH, dk.contents = dkData; printf ("key:\t"); printkey (&key); printf ("\n"); printf ("usage:\t"); printdata (&usage); printf ("\n"); DR (&dr, &key, &usage); printf ("DR:\t"); printdata (&dr); printf ("\n"); DK (&dk, &key, &usage); printf ("DK:\t"); printkey (&dk); printf ("\n\n"); } } static void printd (const char *descr, krb5_data *d) { int i, j; const int r = 16; printf("%s:", descr); for (i = 0; i < d->length; i += r) { printf("\n %04x: ", i); for (j = i; j < i + r && j < d->length; j++) printf(" %02x", 0xff & d->data[j]); for (; j < i + r; j++) printf(" "); printf(" "); for (j = i; j < i + r && j < d->length; j++) { int c = 0xff & d->data[j]; printf("%c", isprint(c) ? c : '.'); } } printf("\n"); } static void printk(const char *descr, krb5_keyblock *k) { krb5_data d; d.data = k->contents; d.length = k->length; printd(descr, &d); } static void test_pbkdf2(void) { static struct { int count; char *pass; char *salt; } test[] = { { 1, "password", "ATHENA.MIT.EDUraeburn" }, { 2, "password", "ATHENA.MIT.EDUraeburn" }, { 1200, "password", "ATHENA.MIT.EDUraeburn" }, { 5, "password", "\x12\x34\x56\x78\x78\x56\x34\x12" }, { 1200, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase equals block size" }, { 1200, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size" }, { 50, "\xf0\x9d\x84\x9e", "EXAMPLE.COMpianist" }, }; unsigned char x[100]; unsigned char x2[100]; int j; krb5_error_code err; krb5_data d; krb5_keyblock k, dk; krb5_data usage, pass, salt; d.data = x; dk.contents = x2; usage.data = "kerberos"; usage.length = 8; for (j = 0; j < sizeof(test)/sizeof(test[0]); j++) { printf("pkbdf2(count=%d, pass=\"%s\", salt=", test[j].count, test[j].pass); if (isprint(test[j].salt[0])) printf("\"%s\")\n", test[j].salt); else { char *s = test[j].salt; printf("0x"); while (*s) printf("%02X", 0xff & *s++); printf(")\n"); } d.length = 16; pass.data = test[j].pass; pass.length = strlen(pass.data); salt.data = test[j].salt; salt.length = strlen(salt.data); err = krb5int_pbkdf2_hmac_sha1 (&d, test[j].count, &pass, &salt); printd("128-bit PBKDF2 output", &d); enc = &krb5int_enc_aes128; k.contents = d.data; k.length = d.length; dk.length = d.length; DK (&dk, &k, &usage); printk("128-bit AES key",&dk); d.length = 32; err = krb5int_pbkdf2_hmac_sha1 (&d, test[j].count, &pass, &salt); printd("256-bit PBKDF2 output", &d); enc = &krb5int_enc_aes256; k.contents = d.data; k.length = d.length; dk.length = d.length; DK (&dk, &k, &usage); printk("256-bit AES key", &dk); printf("\n"); } } int main (int argc, char **argv) { whoami = argv[0]; test_nfold (); test_pbkdf2(); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_decrypt.c0000664000175000017500000006125015051422640022125 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_decrypt.c - Test decrypting known ciphertexts */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This harness decrypts known ciphertexts to detect changes in encryption code * which are self-compatible but not compatible across versions. With the -g * flag, the program generates a set of test cases. */ #include "k5-int.h" struct test { krb5_enctype enctype; krb5_data plaintext; krb5_keyusage usage; krb5_data keybits; krb5_data ciphertext; } test_cases[] = { { ENCTYPE_DES3_CBC_SHA1, { KV5M_DATA, 0, "", }, 0, { KV5M_DATA, 24, "\x7A\x25\xDF\x89\x92\x29\x6D\xCE\xDA\x0E\x13\x5B\xC4\x04\x6E\x23" "\x75\xB3\xC1\x4C\x98\xFB\xC1\x62" }, { KV5M_DATA, 28, "\x54\x8A\xF4\xD5\x04\xF7\xD7\x23\x30\x3F\x12\x17\x5F\xE8\x38\x6B" "\x7B\x53\x35\xA9\x67\xBA\xD6\x1F\x3B\xF0\xB1\x43" } }, { ENCTYPE_DES3_CBC_SHA1, { KV5M_DATA, 1, "1", }, 1, { KV5M_DATA, 24, "\xBC\x07\x83\x89\x15\x13\xD5\xCE\x57\xBC\x13\x8F\xD3\xC1\x1A\xE6" "\x40\x45\x23\x85\x32\x29\x62\xB6" }, { KV5M_DATA, 36, "\x9C\x3C\x1D\xBA\x47\x47\xD8\x5A\xF2\x91\x6E\x47\x45\xF2\xDC\xE3" "\x80\x46\x79\x6E\x51\x04\xBC\xCD\xFB\x66\x9A\x91\xD4\x4B\xC3\x56" "\x66\x09\x45\xC7" } }, { ENCTYPE_DES3_CBC_SHA1, { KV5M_DATA, 9, "9 bytesss", }, 2, { KV5M_DATA, 24, "\x2F\xD0\xF7\x25\xCE\x04\x10\x0D\x2F\xC8\xA1\x80\x98\x83\x1F\x85" "\x0B\x45\xD9\xEF\x85\x0B\xD9\x20" }, { KV5M_DATA, 44, "\xCF\x91\x44\xEB\xC8\x69\x79\x81\x07\x5A\x8B\xAD\x8D\x74\xE5\xD7" "\xD5\x91\xEB\x7D\x97\x70\xC7\xAD\xA2\x5E\xE8\xC5\xB3\xD6\x94\x44" "\xDF\xEC\x79\xA5\xB7\xA0\x14\x82\xD9\xAF\x74\xE6" } }, { ENCTYPE_DES3_CBC_SHA1, { KV5M_DATA, 13, "13 bytes byte", }, 3, { KV5M_DATA, 24, "\x0D\xD5\x20\x94\xE0\xF4\x1C\xEC\xCB\x5B\xE5\x10\xA7\x64\xB3\x51" "\x76\xE3\x98\x13\x32\xF1\xE5\x98" }, { KV5M_DATA, 44, "\x83\x9A\x17\x08\x1E\xCB\xAF\xBC\xDC\x91\xB8\x8C\x69\x55\xDD\x3C" "\x45\x14\x02\x3C\xF1\x77\xB7\x7B\xF0\xD0\x17\x7A\x16\xF7\x05\xE8" "\x49\xCB\x77\x81\xD7\x6A\x31\x6B\x19\x3F\x8D\x30" } }, { ENCTYPE_DES3_CBC_SHA1, { KV5M_DATA, 30, "30 bytes bytes bytes bytes byt", }, 4, { KV5M_DATA, 24, "\xF1\x16\x86\xCB\xBC\x9E\x23\xEA\x54\xFE\xCD\x2A\x3D\xCD\xFB\x20" "\xB6\xFE\x98\xBF\x26\x45\xC4\xC4" }, { KV5M_DATA, 60, "\x89\x43\x3E\x83\xFD\x0E\xA3\x66\x6C\xFF\xCD\x18\xD8\xDE\xEB\xC5" "\x3B\x9A\x34\xED\xBE\xB1\x59\xD9\xF6\x67\xC6\xC2\xB9\xA9\x64\x40" "\x1D\x55\xE7\xE9\xC6\x8D\x64\x8D\x65\xC3\xAA\x84\xFF\xA3\x79\x0C" "\x14\xA8\x64\xDA\x80\x73\xA9\xA9\x5C\x4B\xA2\xBC" } }, { ENCTYPE_ARCFOUR_HMAC, { KV5M_DATA, 0, "", }, 0, { KV5M_DATA, 16, "\xF8\x1F\xEC\x39\x25\x5F\x57\x84\xE8\x50\xC4\x37\x7C\x88\xBD\x85" }, { KV5M_DATA, 24, "\x02\xC1\xEB\x15\x58\x61\x44\x12\x2E\xC7\x17\x76\x3D\xD3\x48\xBF" "\x00\x43\x4D\xDC\x65\x85\x95\x4C" } }, { ENCTYPE_ARCFOUR_HMAC, { KV5M_DATA, 1, "1", }, 1, { KV5M_DATA, 16, "\x67\xD1\x30\x0D\x28\x12\x23\x86\x7F\x96\x47\xFF\x48\x72\x12\x73" }, { KV5M_DATA, 25, "\x61\x56\xE0\xCC\x04\xE0\xA0\x87\x4F\x9F\xDA\x00\x8F\x49\x8A\x7A" "\xDB\xBC\x80\xB7\x0B\x14\xDD\xDB\xC0" } }, { ENCTYPE_ARCFOUR_HMAC, { KV5M_DATA, 9, "9 bytesss", }, 2, { KV5M_DATA, 16, "\x3E\x40\xAB\x60\x93\x69\x52\x81\xB3\xAC\x1A\x93\x04\x22\x4D\x98" }, { KV5M_DATA, 33, "\x0F\x9A\xD1\x21\xD9\x9D\x4A\x09\x44\x8E\x4F\x1F\x71\x8C\x4F\x5C" "\xBE\x60\x96\x26\x2C\x66\xF2\x9D\xF2\x32\xA8\x7C\x9F\x98\x75\x5D" "\x55" } }, { ENCTYPE_ARCFOUR_HMAC, { KV5M_DATA, 13, "13 bytes byte", }, 3, { KV5M_DATA, 16, "\x4B\xA2\xFB\xF0\x37\x9F\xAE\xD8\x7A\x25\x4D\x3B\x35\x3D\x5A\x7E" }, { KV5M_DATA, 37, "\x61\x2C\x57\x56\x8B\x17\xA7\x03\x52\xBA\xE8\xCF\x26\xFB\x94\x59" "\xA6\xF3\x35\x3C\xD3\x5F\xD4\x39\xDB\x31\x07\xCB\xEC\x76\x5D\x32" "\x6D\xFC\x04\xC1\xDD" } }, { ENCTYPE_ARCFOUR_HMAC, { KV5M_DATA, 30, "30 bytes bytes bytes bytes byt", }, 4, { KV5M_DATA, 16, "\x68\xF2\x63\xDB\x3F\xCE\x15\xD0\x31\xC9\xEA\xB0\x2D\x67\x10\x7A" }, { KV5M_DATA, 54, "\x95\xF9\x04\x7C\x3A\xD7\x58\x91\xC2\xE9\xB0\x4B\x16\x56\x6D\xC8" "\xB6\xEB\x9C\xE4\x23\x1A\xFB\x25\x42\xEF\x87\xA7\xB5\xA0\xF2\x60" "\xA9\x9F\x04\x60\x50\x8D\xE0\xCE\xCC\x63\x2D\x07\xC3\x54\x12\x4E" "\x46\xC5\xD2\x23\x4E\xB8" } }, { ENCTYPE_ARCFOUR_HMAC_EXP, { KV5M_DATA, 0, "", }, 0, { KV5M_DATA, 16, "\xF7\xD3\xA1\x55\xAF\x5E\x23\x8A\x0B\x7A\x87\x1A\x96\xBA\x2A\xB2" }, { KV5M_DATA, 24, "\x28\x27\xF0\xE9\x0F\x62\xE7\x46\x0C\x4E\x2F\xB3\x9F\x96\x57\xBA" "\x8B\xFA\xA9\x91\xD7\xFD\xAD\xFF" } }, { ENCTYPE_ARCFOUR_HMAC_EXP, { KV5M_DATA, 1, "1", }, 1, { KV5M_DATA, 16, "\xDE\xEA\xA0\x60\x7D\xB7\x99\xE2\xFD\xD6\xDB\x29\x86\xBB\x8D\x65" }, { KV5M_DATA, 25, "\x3D\xDA\x39\x2E\x2E\x27\x5A\x4D\x75\x18\x3F\xA6\x32\x8A\x0A\x4E" "\x6B\x75\x2D\xF6\xCD\x2A\x25\xFA\x4E" } }, { ENCTYPE_ARCFOUR_HMAC_EXP, { KV5M_DATA, 9, "9 bytesss", }, 2, { KV5M_DATA, 16, "\x33\xAD\x7F\xC2\x67\x86\x15\x56\x9B\x2B\x09\x83\x6E\x0A\x3A\xB6" }, { KV5M_DATA, 33, "\x09\xD1\x36\xAC\x48\x5D\x92\x64\x4E\xC6\x70\x1D\x6A\x0D\x03\xE8" "\x98\x2D\x7A\x3C\xA7\xEF\xD0\xF8\xF4\xF8\x36\x60\xEF\x42\x77\xBB" "\x81" } }, { ENCTYPE_ARCFOUR_HMAC_EXP, { KV5M_DATA, 13, "13 bytes byte", }, 3, { KV5M_DATA, 16, "\x39\xF2\x5C\xD4\xF0\xD4\x1B\x2B\x2D\x9D\x30\x0F\xCB\x29\x81\xCB" }, { KV5M_DATA, 37, "\x91\x23\x88\xD7\xC0\x76\x12\x81\x9E\x3B\x64\x0F\xF5\xCE\xCD\xAF" "\x72\xE5\xA5\x9D\xF1\x0F\x10\x91\xA6\xBE\xC3\x9C\xAA\xD7\x48\xAF" "\x9B\xD2\xD8\xD5\x46" } }, { ENCTYPE_ARCFOUR_HMAC_EXP, { KV5M_DATA, 30, "30 bytes bytes bytes bytes byt", }, 4, { KV5M_DATA, 16, "\x9F\x72\x55\x42\xD9\xF7\x2A\xA1\xF3\x86\xCB\xE7\x89\x69\x84\xFC" }, { KV5M_DATA, 54, "\x78\xB3\x5A\x08\xB0\x8B\xE2\x65\xAE\xB4\x14\x5F\x07\x65\x13\xB6" "\xB5\x6E\xFE\xD3\xF7\x52\x65\x74\xAF\x74\xF7\xD2\xF9\xBA\xE9\x6E" "\xAB\xB7\x6F\x2D\x87\x38\x6D\x2E\x93\xE3\xA7\x7B\x99\x91\x9F\x1D" "\x97\x64\x90\xE2\xBD\x45" } }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 0, "", }, 0, { KV5M_DATA, 16, "\x5A\x5C\x0F\x0B\xA5\x4F\x38\x28\xB2\x19\x5E\x66\xCA\x24\xA2\x89" }, { KV5M_DATA, 28, "\x49\xFF\x8E\x11\xC1\x73\xD9\x58\x3A\x32\x54\xFB\xE7\xB1\xF1\xDF" "\x36\xC5\x38\xE8\x41\x67\x84\xA1\x67\x2E\x66\x76" } }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 1, "1", }, 1, { KV5M_DATA, 16, "\x98\x45\x0E\x3F\x3B\xAA\x13\xF5\xC9\x9B\xEB\x93\x69\x81\xB0\x6F" }, { KV5M_DATA, 29, "\xF8\x67\x42\xF5\x37\xB3\x5D\xC2\x17\x4A\x4D\xBA\xA9\x20\xFA\xF9" "\x04\x20\x90\xB0\x65\xE1\xEB\xB1\xCA\xD9\xA6\x53\x94" } }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 9, "9 bytesss", }, 2, { KV5M_DATA, 16, "\x90\x62\x43\x0C\x8C\xDA\x33\x88\x92\x2E\x6D\x6A\x50\x9F\x5B\x7A" }, { KV5M_DATA, 37, "\x68\xFB\x96\x79\x60\x1F\x45\xC7\x88\x57\xB2\xBF\x82\x0F\xD6\xE5" "\x3E\xCA\x8D\x42\xFD\x4B\x1D\x70\x24\xA0\x92\x05\xAB\xB7\xCD\x2E" "\xC2\x6C\x35\x5D\x2F" } }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 13, "13 bytes byte", }, 3, { KV5M_DATA, 16, "\x03\x3E\xE6\x50\x2C\x54\xFD\x23\xE2\x77\x91\xE9\x87\x98\x38\x27" }, { KV5M_DATA, 41, "\xEC\x36\x6D\x03\x27\xA9\x33\xBF\x49\x33\x0E\x65\x0E\x49\xBC\x6B" "\x97\x46\x37\xFE\x80\xBF\x53\x2F\xE5\x17\x95\xB4\x80\x97\x18\xE6" "\x19\x47\x24\xDB\x94\x8D\x1F\xD6\x37" } }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 30, "30 bytes bytes bytes bytes byt", }, 4, { KV5M_DATA, 16, "\xDC\xEE\xB7\x0B\x3D\xE7\x65\x62\xE6\x89\x22\x6C\x76\x42\x91\x48" }, { KV5M_DATA, 58, "\xC9\x60\x81\x03\x2D\x5D\x8E\xEB\x7E\x32\xB4\x08\x9F\x78\x9D\x0F" "\xAA\x48\x1D\xEA\x74\xC0\xF9\x7C\xBF\x31\x46\xDD\xFC\xF8\xE8\x00" "\x15\x6E\xCB\x53\x2F\xC2\x03\xE3\x0F\xF6\x00\xB6\x3B\x35\x09\x39" "\xFE\xCE\x51\x0F\x02\xD7\xFF\x1E\x7B\xAC" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 0, "", }, 0, { KV5M_DATA, 32, "\x17\xF2\x75\xF2\x95\x4F\x2E\xD1\xF9\x0C\x37\x7B\xA7\xF4\xD6\xA3" "\x69\xAA\x01\x36\xE0\xBF\x0C\x92\x7A\xD6\x13\x3C\x69\x37\x59\xA9" }, { KV5M_DATA, 28, "\xE5\x09\x4C\x55\xEE\x7B\x38\x26\x2E\x2B\x04\x42\x80\xB0\x69\x37" "\x9A\x95\xBF\x95\xBD\x83\x76\xFB\x32\x81\xB4\x35" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 1, "1", }, 1, { KV5M_DATA, 32, "\xB9\x47\x7E\x1F\xF0\x32\x9C\x00\x50\xE2\x0C\xE6\xC7\x2D\x2D\xFF" "\x27\xE8\xFE\x54\x1A\xB0\x95\x44\x29\xA9\xCB\x5B\x4F\x7B\x1E\x2A" }, { KV5M_DATA, 29, "\x40\x61\x50\xB9\x7A\xEB\x76\xD4\x3B\x36\xB6\x2C\xC1\xEC\xDF\xBE" "\x6F\x40\xE9\x57\x55\xE0\xBE\xB5\xC2\x78\x25\xF3\xA4" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 9, "9 bytesss", }, 2, { KV5M_DATA, 32, "\xB1\xAE\x4C\xD8\x46\x2A\xFF\x16\x77\x05\x3C\xC9\x27\x9A\xAC\x30" "\xB7\x96\xFB\x81\xCE\x21\x47\x4D\xD3\xDD\xBC\xFE\xA4\xEC\x76\xD7" }, { KV5M_DATA, 37, "\x09\x95\x7A\xA2\x5F\xCA\xF8\x8F\x7B\x39\xE4\x40\x6E\x63\x30\x12" "\xD5\xFE\xA2\x18\x53\xF6\x47\x8D\xA7\x06\x5C\xAE\xF4\x1F\xD4\x54" "\xA4\x08\x24\xEE\xC5" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 13, "13 bytes byte", }, 3, { KV5M_DATA, 32, "\xE5\xA7\x2B\xE9\xB7\x92\x6C\x12\x25\xBA\xFE\xF9\xC1\x87\x2E\x7B" "\xA4\xCD\xB2\xB1\x78\x93\xD8\x4A\xBD\x90\xAC\xDD\x87\x64\xD9\x66" }, { KV5M_DATA, 41, "\xD8\xF1\xAA\xFE\xEC\x84\x58\x7C\xC3\xE7\x00\xA7\x74\xE5\x66\x51" "\xA6\xD6\x93\xE1\x74\xEC\x44\x73\xB5\xE6\xD9\x6F\x80\x29\x7A\x65" "\x3F\xB8\x18\xAD\x89\x3E\x71\x9F\x96" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 30, "30 bytes bytes bytes bytes byt", }, 4, { KV5M_DATA, 32, "\xF1\xC7\x95\xE9\x24\x8A\x09\x33\x8D\x82\xC3\xF8\xD5\xB5\x67\x04" "\x0B\x01\x10\x73\x68\x45\x04\x13\x47\x23\x5B\x14\x04\x23\x13\x98" }, { KV5M_DATA, 58, "\xD1\x13\x7A\x4D\x63\x4C\xFE\xCE\x92\x4D\xBC\x3B\xF6\x79\x06\x48" "\xBD\x5C\xFF\x7D\xE0\xE7\xB9\x94\x60\x21\x1D\x0D\xAE\xF3\xD7\x9A" "\x29\x5C\x68\x88\x58\xF3\xB3\x4B\x9C\xBD\x6E\xEB\xAE\x81\xDA\xF6" "\xB7\x34\xD4\xD4\x98\xB6\x71\x4F\x1C\x1D" } }, { ENCTYPE_CAMELLIA128_CTS_CMAC, { KV5M_DATA, 0, "", }, 0, { KV5M_DATA, 16, "\x1D\xC4\x6A\x8D\x76\x3F\x4F\x93\x74\x2B\xCB\xA3\x38\x75\x76\xC3" }, { KV5M_DATA, 32, "\xC4\x66\xF1\x87\x10\x69\x92\x1E\xDB\x7C\x6F\xDE\x24\x4A\x52\xDB" "\x0B\xA1\x0E\xDC\x19\x7B\xDB\x80\x06\x65\x8C\xA3\xCC\xCE\x6E\xB8" } }, { ENCTYPE_CAMELLIA128_CTS_CMAC, { KV5M_DATA, 1, "1", }, 1, { KV5M_DATA, 16, "\x50\x27\xBC\x23\x1D\x0F\x3A\x9D\x23\x33\x3F\x1C\xA6\xFD\xBE\x7C" }, { KV5M_DATA, 33, "\x84\x2D\x21\xFD\x95\x03\x11\xC0\xDD\x46\x4A\x3F\x4B\xE8\xD6\xDA" "\x88\xA5\x6D\x55\x9C\x9B\x47\xD3\xF9\xA8\x50\x67\xAF\x66\x15\x59" "\xB8" } }, { ENCTYPE_CAMELLIA128_CTS_CMAC, { KV5M_DATA, 9, "9 bytesss", }, 2, { KV5M_DATA, 16, "\xA1\xBB\x61\xE8\x05\xF9\xBA\x6D\xDE\x8F\xDB\xDD\xC0\x5C\xDE\xA0" }, { KV5M_DATA, 41, "\x61\x9F\xF0\x72\xE3\x62\x86\xFF\x0A\x28\xDE\xB3\xA3\x52\xEC\x0D" "\x0E\xDF\x5C\x51\x60\xD6\x63\xC9\x01\x75\x8C\xCF\x9D\x1E\xD3\x3D" "\x71\xDB\x8F\x23\xAA\xBF\x83\x48\xA0" } }, { ENCTYPE_CAMELLIA128_CTS_CMAC, { KV5M_DATA, 13, "13 bytes byte", }, 3, { KV5M_DATA, 16, "\x2C\xA2\x7A\x5F\xAF\x55\x32\x24\x45\x06\x43\x4E\x1C\xEF\x66\x76" }, { KV5M_DATA, 45, "\xB8\xEC\xA3\x16\x7A\xE6\x31\x55\x12\xE5\x9F\x98\xA7\xC5\x00\x20" "\x5E\x5F\x63\xFF\x3B\xB3\x89\xAF\x1C\x41\xA2\x1D\x64\x0D\x86\x15" "\xC9\xED\x3F\xBE\xB0\x5A\xB6\xAC\xB6\x76\x89\xB5\xEA" } }, { ENCTYPE_CAMELLIA128_CTS_CMAC, { KV5M_DATA, 30, "30 bytes bytes bytes bytes byt", }, 4, { KV5M_DATA, 16, "\x78\x24\xF8\xC1\x6F\x83\xFF\x35\x4C\x6B\xF7\x51\x5B\x97\x3F\x43" }, { KV5M_DATA, 62, "\xA2\x6A\x39\x05\xA4\xFF\xD5\x81\x6B\x7B\x1E\x27\x38\x0D\x08\x09" "\x0C\x8E\xC1\xF3\x04\x49\x6E\x1A\xBD\xCD\x2B\xDC\xD1\xDF\xFC\x66" "\x09\x89\xE1\x17\xA7\x13\xDD\xBB\x57\xA4\x14\x6C\x15\x87\xCB\xA4" "\x35\x66\x65\x59\x1D\x22\x40\x28\x2F\x58\x42\xB1\x05\xA5" } }, { ENCTYPE_CAMELLIA256_CTS_CMAC, { KV5M_DATA, 0, "", }, 0, { KV5M_DATA, 32, "\xB6\x1C\x86\xCC\x4E\x5D\x27\x57\x54\x5A\xD4\x23\x39\x9F\xB7\x03" "\x1E\xCA\xB9\x13\xCB\xB9\x00\xBD\x7A\x3C\x6D\xD8\xBF\x92\x01\x5B" }, { KV5M_DATA, 32, "\x03\x88\x6D\x03\x31\x0B\x47\xA6\xD8\xF0\x6D\x7B\x94\xD1\xDD\x83" "\x7E\xCC\xE3\x15\xEF\x65\x2A\xFF\x62\x08\x59\xD9\x4A\x25\x92\x66" } }, { ENCTYPE_CAMELLIA256_CTS_CMAC, { KV5M_DATA, 1, "1", }, 1, { KV5M_DATA, 32, "\x1B\x97\xFE\x0A\x19\x0E\x20\x21\xEB\x30\x75\x3E\x1B\x6E\x1E\x77" "\xB0\x75\x4B\x1D\x68\x46\x10\x35\x58\x64\x10\x49\x63\x46\x38\x33" }, { KV5M_DATA, 33, "\x2C\x9C\x15\x70\x13\x3C\x99\xBF\x6A\x34\xBC\x1B\x02\x12\x00\x2F" "\xD1\x94\x33\x87\x49\xDB\x41\x35\x49\x7A\x34\x7C\xFC\xD9\xD1\x8A" "\x12" } }, { ENCTYPE_CAMELLIA256_CTS_CMAC, { KV5M_DATA, 9, "9 bytesss", }, 2, { KV5M_DATA, 32, "\x32\x16\x4C\x5B\x43\x4D\x1D\x15\x38\xE4\xCF\xD9\xBE\x80\x40\xFE" "\x8C\x4A\xC7\xAC\xC4\xB9\x3D\x33\x14\xD2\x13\x36\x68\x14\x7A\x05" }, { KV5M_DATA, 41, "\x9C\x6D\xE7\x5F\x81\x2D\xE7\xED\x0D\x28\xB2\x96\x35\x57\xA1\x15" "\x64\x09\x98\x27\x5B\x0A\xF5\x15\x27\x09\x91\x3F\xF5\x2A\x2A\x9C" "\x8E\x63\xB8\x72\xF9\x2E\x64\xC8\x39" } }, { ENCTYPE_CAMELLIA256_CTS_CMAC, { KV5M_DATA, 13, "13 bytes byte", }, 3, { KV5M_DATA, 32, "\xB0\x38\xB1\x32\xCD\x8E\x06\x61\x22\x67\xFA\xB7\x17\x00\x66\xD8" "\x8A\xEC\xCB\xA0\xB7\x44\xBF\xC6\x0D\xC8\x9B\xCA\x18\x2D\x07\x15" }, { KV5M_DATA, 45, "\xEE\xEC\x85\xA9\x81\x3C\xDC\x53\x67\x72\xAB\x9B\x42\xDE\xFC\x57" "\x06\xF7\x26\xE9\x75\xDD\xE0\x5A\x87\xEB\x54\x06\xEA\x32\x4C\xA1" "\x85\xC9\x98\x6B\x42\xAA\xBE\x79\x4B\x84\x82\x1B\xEE" } }, { ENCTYPE_CAMELLIA256_CTS_CMAC, { KV5M_DATA, 30, "30 bytes bytes bytes bytes byt", }, 4, { KV5M_DATA, 32, "\xCC\xFC\xD3\x49\xBF\x4C\x66\x77\xE8\x6E\x4B\x02\xB8\xEA\xB9\x24" "\xA5\x46\xAC\x73\x1C\xF9\xBF\x69\x89\xB9\x96\xE7\xD6\xBF\xBB\xA7" }, { KV5M_DATA, 62, "\x0E\x44\x68\x09\x85\x85\x5F\x2D\x1F\x18\x12\x52\x9C\xA8\x3B\xFD" "\x8E\x34\x9D\xE6\xFD\x9A\xDA\x0B\xAA\xA0\x48\xD6\x8E\x26\x5F\xEB" "\xF3\x4A\xD1\x25\x5A\x34\x49\x99\xAD\x37\x14\x68\x87\xA6\xC6\x84" "\x57\x31\xAC\x7F\x46\x37\x6A\x05\x04\xCD\x06\x57\x14\x74" } }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, { KV5M_DATA, 0, "", }, 2, { KV5M_DATA, 16, "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" }, { KV5M_DATA, 32, "\xEF\x85\xFB\x89\x0B\xB8\x47\x2F\x4D\xAB\x20\x39\x4D\xCA\x78\x1D" "\xAD\x87\x7E\xDA\x39\xD5\x0C\x87\x0C\x0D\x5A\x0A\x8E\x48\xC7\x18" } }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, { KV5M_DATA, 6, "\x00\x01\x02\x03\x04\x05", }, 2, { KV5M_DATA, 16, "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" }, { KV5M_DATA, 38, "\x84\xD7\xF3\x07\x54\xED\x98\x7B\xAB\x0B\xF3\x50\x6B\xEB\x09\xCF" "\xB5\x54\x02\xCE\xF7\xE6\x87\x7C\xE9\x9E\x24\x7E\x52\xD1\x6E\xD4" "\x42\x1D\xFD\xF8\x97\x6C" } }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, { KV5M_DATA, 16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" }, 2, { KV5M_DATA, 16, "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" }, { KV5M_DATA, 48, "\x35\x17\xD6\x40\xF5\x0D\xDC\x8A\xD3\x62\x87\x22\xB3\x56\x9D\x2A" "\xE0\x74\x93\xFA\x82\x63\x25\x40\x80\xEA\x65\xC1\x00\x8E\x8F\xC2" "\x95\xFB\x48\x52\xE7\xD8\x3E\x1E\x7C\x48\xC3\x7E\xEB\xE6\xB0\xD3" } }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, { KV5M_DATA, 21, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14" }, 2, { KV5M_DATA, 16, "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" }, { KV5M_DATA, 53, "\x72\x0F\x73\xB1\x8D\x98\x59\xCD\x6C\xCB\x43\x46\x11\x5C\xD3\x36" "\xC7\x0F\x58\xED\xC0\xC4\x43\x7C\x55\x73\x54\x4C\x31\xC8\x13\xBC" "\xE1\xE6\xD0\x72\xC1\x86\xB3\x9A\x41\x3C\x2F\x92\xCA\x9B\x83\x34" "\xA2\x87\xFF\xCB\xFC" } }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, { KV5M_DATA, 0, "", }, 2, { KV5M_DATA, 32, "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98" "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" }, { KV5M_DATA, 40, "\x41\xF5\x3F\xA5\xBF\xE7\x02\x6D\x91\xFA\xF9\xBE\x95\x91\x95\xA0" "\x58\x70\x72\x73\xA9\x6A\x40\xF0\xA0\x19\x60\x62\x1A\xC6\x12\x74" "\x8B\x9B\xBF\xBE\x7E\xB4\xCE\x3C" } }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, { KV5M_DATA, 6, "\x00\x01\x02\x03\x04\x05", }, 2, { KV5M_DATA, 32, "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98" "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" }, { KV5M_DATA, 46, "\x4E\xD7\xB3\x7C\x2B\xCA\xC8\xF7\x4F\x23\xC1\xCF\x07\xE6\x2B\xC7" "\xB7\x5F\xB3\xF6\x37\xB9\xF5\x59\xC7\xF6\x64\xF6\x9E\xAB\x7B\x60" "\x92\x23\x75\x26\xEA\x0D\x1F\x61\xCB\x20\xD6\x9D\x10\xF2" } }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, { KV5M_DATA, 16, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" }, 2, { KV5M_DATA, 32, "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98" "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" }, { KV5M_DATA, 56, "\xBC\x47\xFF\xEC\x79\x98\xEB\x91\xE8\x11\x5C\xF8\xD1\x9D\xAC\x4B" "\xBB\xE2\xE1\x63\xE8\x7D\xD3\x7F\x49\xBE\xCA\x92\x02\x77\x64\xF6" "\x8C\xF5\x1F\x14\xD7\x98\xC2\x27\x3F\x35\xDF\x57\x4D\x1F\x93\x2E" "\x40\xC4\xFF\x25\x5B\x36\xA2\x66" } }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, { KV5M_DATA, 21, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14" }, 2, { KV5M_DATA, 32, "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98" "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" }, { KV5M_DATA, 61, "\x40\x01\x3E\x2D\xF5\x8E\x87\x51\x95\x7D\x28\x78\xBC\xD2\xD6\xFE" "\x10\x1C\xCF\xD5\x56\xCB\x1E\xAE\x79\xDB\x3C\x3E\xE8\x64\x29\xF2" "\xB2\xA6\x02\xAC\x86\xFE\xF6\xEC\xB6\x47\xD6\x29\x5F\xAE\x07\x7A" "\x1F\xEB\x51\x75\x08\xD2\xC1\x6B\x41\x92\xE0\x1F\x62" } }, }; static void printhex(const char *head, void *data, size_t len) { size_t i; printf("%s", head); for (i = 0; i < len; i++) { printf("%02X", ((unsigned char*)data)[i]); if (i % 16 == 15 && i + 1 < len) printf("\n%*s", (int)strlen(head), ""); else if (i + 1 < len) printf(" "); } printf("\n"); } static krb5_enctype enctypes[] = { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC_EXP, ENCTYPE_AES128_CTS_HMAC_SHA1_96, ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_CAMELLIA128_CTS_CMAC, ENCTYPE_CAMELLIA256_CTS_CMAC, ENCTYPE_AES128_CTS_HMAC_SHA256_128, ENCTYPE_AES256_CTS_HMAC_SHA384_192 }; static char *plaintexts[] = { "", "1", "9 bytesss", "13 bytes byte", "30 bytes bytes bytes bytes byt" }; static int generate(krb5_context context) { krb5_error_code ret; size_t i, j; krb5_keyblock kb; krb5_data plain, seed = string2data("seed"); krb5_enc_data enc; size_t enclen; char buf[64]; ret = krb5_c_random_seed(context, &seed); assert(!ret); for (i = 0; i < sizeof(enctypes) / sizeof(*enctypes); i++) { for (j = 0; j < sizeof(plaintexts) / sizeof(*plaintexts); j++) { ret = krb5_c_make_random_key(context, enctypes[i], &kb); assert(!ret); plain = string2data(plaintexts[j]); ret = krb5_c_encrypt_length(context, enctypes[i], plain.length, &enclen); assert(!ret); ret = alloc_data(&enc.ciphertext, enclen); assert(!ret); ret = krb5_c_encrypt(context, &kb, j, NULL, &plain, &enc); assert(!ret); krb5_enctype_to_name(enctypes[i], FALSE, buf, sizeof(buf)); printf("\nEnctype: %s\n", buf); printf("Plaintext: %s\n", plaintexts[j]); printhex("Key: ", kb.contents, kb.length); printhex("Ciphertext: ", enc.ciphertext.data, enc.ciphertext.length); free(enc.ciphertext.data); } } return 0; } int main(int argc, char **argv) { krb5_error_code ret; krb5_context context = NULL; krb5_data plain; size_t i; struct test *test; krb5_keyblock kb; krb5_enc_data enc; if (argc >= 2 && strcmp(argv[1], "-g") == 0) return generate(context); for (i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) { test = &test_cases[i]; kb.magic = KV5M_KEYBLOCK; kb.enctype = test->enctype; kb.length = test->keybits.length; kb.contents = (unsigned char *)test->keybits.data; ret = alloc_data(&plain, test->ciphertext.length); assert(!ret); enc.magic = KV5M_ENC_DATA; enc.enctype = test->enctype; enc.kvno = 0; enc.ciphertext = test->ciphertext; if (krb5_c_decrypt(context, &kb, test->usage, NULL, &enc, &plain) != 0) { printf("decrypt test %d failed to decrypt\n", (int)i); return 1; } assert(plain.length >= test->plaintext.length); if (memcmp(plain.data, test->plaintext.data, test->plaintext.length) != 0) { printf("decrypt test %d produced wrong result\n", (int)i); return 1; } free(plain.data); } return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/deps0000664000175000017500000003314415051422640020643 0ustar ghudsonghudson# # Generated makefile dependencies follow. # $(OUTPRE)t_nfold.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ t_nfold.c $(OUTPRE)t_encrypt.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ t_encrypt.c $(OUTPRE)t_decrypt.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_decrypt.c $(OUTPRE)t_prf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_prf.c $(OUTPRE)t_cmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ t_cmac.c $(OUTPRE)t_hmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hex.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_hmac.c $(OUTPRE)t_pkcs5.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_pkcs5.c $(OUTPRE)t_cts.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ t_cts.c $(OUTPRE)vectors.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ vectors.c $(OUTPRE)aes-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ aes-test.c $(OUTPRE)camellia-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ camellia-test.c $(OUTPRE)t_cf2.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h t_cf2.c $(OUTPRE)t_cksums.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_cksums.c $(OUTPRE)t_mddriver.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ t_mddriver.c $(OUTPRE)t_kperf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_kperf.c $(OUTPRE)t_sha2.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ t_sha2.c $(OUTPRE)t_short.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_short.c $(OUTPRE)t_str2key.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_str2key.c $(OUTPRE)t_derive.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ t_derive.c $(OUTPRE)t_fork.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h t_fork.c krb5-1.22.1/src/lib/crypto/crypto_tests/t_cksums.c0000664000175000017500000002345515051422640021765 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_cksums.c - Test known checksum results */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This harness tests checksum results against known values. With the -v flag, * results for all tests are displayed. This harness only works for * deterministic checksums. */ #include "k5-int.h" struct test { krb5_data plaintext; krb5_cksumtype sumtype; krb5_enctype enctype; krb5_keyusage usage; krb5_data keybits; krb5_data cksum; } test_cases[] = { { { KV5M_DATA, 3, "one" }, CKSUMTYPE_RSA_MD4, 0, 0, { KV5M_DATA, 0, "" }, { KV5M_DATA, 16, "\x30\x5D\xCC\x2C\x0F\xDD\x53\x39\x96\x95\x52\xC7\xB8\x99\x63\x48" } }, { { KV5M_DATA, 19, "two three four five" }, CKSUMTYPE_RSA_MD5, 0, 0, { KV5M_DATA, 0, "" }, { KV5M_DATA, 16, "\xBA\xB5\x32\x15\x51\xE1\x08\x44\x90\x86\x96\x35\xB3\xC2\x68\x15" } }, { { KV5M_DATA, 0, "" }, CKSUMTYPE_SHA1, 0, 0, { KV5M_DATA, 0, "" }, { KV5M_DATA, 20, "\xDA\x39\xA3\xEE\x5E\x6B\x4B\x0D\x32\x55\xBF\xEF\x95\x60\x18\x90" "\xAF\xD8\x07\x09" } }, { { KV5M_DATA, 9, "six seven" }, CKSUMTYPE_HMAC_SHA1_DES3, ENCTYPE_DES3_CBC_SHA1, 2, { KV5M_DATA, 24, "\x7A\x25\xDF\x89\x92\x29\x6D\xCE\xDA\x0E\x13\x5B\xC4\x04\x6E\x23" "\x75\xB3\xC1\x4C\x98\xFB\xC1\x62" }, { KV5M_DATA, 20, "\x0E\xEF\xC9\xC3\xE0\x49\xAA\xBC\x1B\xA5\xC4\x01\x67\x7D\x9A\xB6" "\x99\x08\x2B\xB4" } }, { { KV5M_DATA, 37, "eight nine ten eleven twelve thirteen" }, CKSUMTYPE_HMAC_SHA1_96_AES128, ENCTYPE_AES128_CTS_HMAC_SHA1_96, 3, { KV5M_DATA, 16, "\x90\x62\x43\x0C\x8C\xDA\x33\x88\x92\x2E\x6D\x6A\x50\x9F\x5B\x7A" }, { KV5M_DATA, 12, "\x01\xA4\xB0\x88\xD4\x56\x28\xF6\x94\x66\x14\xE3" } }, { { KV5M_DATA, 8, "fourteen" }, CKSUMTYPE_HMAC_SHA1_96_AES256, ENCTYPE_AES256_CTS_HMAC_SHA1_96, 4, { KV5M_DATA, 32, "\xB1\xAE\x4C\xD8\x46\x2A\xFF\x16\x77\x05\x3C\xC9\x27\x9A\xAC\x30" "\xB7\x96\xFB\x81\xCE\x21\x47\x4D\xD3\xDD\xBC\xFE\xA4\xEC\x76\xD7" }, { KV5M_DATA, 12, "\xE0\x87\x39\xE3\x27\x9E\x29\x03\xEC\x8E\x38\x36" } }, { { KV5M_DATA, 15, "fifteen sixteen" }, CKSUMTYPE_MD5_HMAC_ARCFOUR, ENCTYPE_ARCFOUR_HMAC, 5, { KV5M_DATA, 16, "\xF7\xD3\xA1\x55\xAF\x5E\x23\x8A\x0B\x7A\x87\x1A\x96\xBA\x2A\xB2" }, { KV5M_DATA, 16, "\x9F\x41\xDF\x30\x49\x07\xDE\x73\x54\x47\x00\x1F\xD2\xA1\x97\xB9" } }, { { KV5M_DATA, 34, "seventeen eighteen nineteen twenty" }, CKSUMTYPE_HMAC_MD5_ARCFOUR, ENCTYPE_ARCFOUR_HMAC, 6, { KV5M_DATA, 16, "\xF7\xD3\xA1\x55\xAF\x5E\x23\x8A\x0B\x7A\x87\x1A\x96\xBA\x2A\xB2" }, { KV5M_DATA, 16, "\xEB\x38\xCC\x97\xE2\x23\x0F\x59\xDA\x41\x17\xDC\x58\x59\xD7\xEC" } }, { { KV5M_DATA, 11, "abcdefghijk" }, CKSUMTYPE_CMAC_CAMELLIA128, ENCTYPE_CAMELLIA128_CTS_CMAC, 7, { KV5M_DATA, 16, "\x1D\xC4\x6A\x8D\x76\x3F\x4F\x93\x74\x2B\xCB\xA3\x38\x75\x76\xC3" }, { KV5M_DATA, 16, "\x11\x78\xE6\xC5\xC4\x7A\x8C\x1A\xE0\xC4\xB9\xC7\xD4\xEB\x7B\x6B" } }, { { KV5M_DATA, 26, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }, CKSUMTYPE_CMAC_CAMELLIA128, ENCTYPE_CAMELLIA128_CTS_CMAC, 8, { KV5M_DATA, 16, "\x50\x27\xBC\x23\x1D\x0F\x3A\x9D\x23\x33\x3F\x1C\xA6\xFD\xBE\x7C" }, { KV5M_DATA, 16, "\xD1\xB3\x4F\x70\x04\xA7\x31\xF2\x3A\x0C\x00\xBF\x6C\x3F\x75\x3A" } }, { { KV5M_DATA, 9, "123456789" }, CKSUMTYPE_CMAC_CAMELLIA256, ENCTYPE_CAMELLIA256_CTS_CMAC, 9, { KV5M_DATA, 32, "\xB6\x1C\x86\xCC\x4E\x5D\x27\x57\x54\x5A\xD4\x23\x39\x9F\xB7\x03" "\x1E\xCA\xB9\x13\xCB\xB9\x00\xBD\x7A\x3C\x6D\xD8\xBF\x92\x01\x5B" }, { KV5M_DATA, 16, "\x87\xA1\x2C\xFD\x2B\x96\x21\x48\x10\xF0\x1C\x82\x6E\x77\x44\xB1" } }, { { KV5M_DATA, 30, "!@#$%^&*()!@#$%^&*()!@#$%^&*()" }, CKSUMTYPE_CMAC_CAMELLIA256, ENCTYPE_CAMELLIA256_CTS_CMAC, 10, { KV5M_DATA, 32, "\x32\x16\x4C\x5B\x43\x4D\x1D\x15\x38\xE4\xCF\xD9\xBE\x80\x40\xFE" "\x8C\x4A\xC7\xAC\xC4\xB9\x3D\x33\x14\xD2\x13\x36\x68\x14\x7A\x05" }, { KV5M_DATA, 16, "\x3F\xA0\xB4\x23\x55\xE5\x2B\x18\x91\x87\x29\x4A\xA2\x52\xAB\x64" } }, { { KV5M_DATA, 21, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14" }, CKSUMTYPE_HMAC_SHA256_128_AES128, ENCTYPE_AES128_CTS_HMAC_SHA256_128, 2, { KV5M_DATA, 16, "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" }, { KV5M_DATA, 16, "\xD7\x83\x67\x18\x66\x43\xD6\x7B\x41\x1C\xBA\x91\x39\xFC\x1D\xEE" } }, { { KV5M_DATA, 21, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14" }, CKSUMTYPE_HMAC_SHA384_192_AES256, ENCTYPE_AES256_CTS_HMAC_SHA384_192, 2, { KV5M_DATA, 32, "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98" "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" }, { KV5M_DATA, 24, "\x45\xEE\x79\x15\x67\xEE\xFC\xA3\x7F\x4A\xC1\xE0\x22\x2D\xE8\x0D" "\x43\xC3\xBF\xA0\x66\x99\x67\x2A" } }, }; static void printhex(const char *head, void *data, size_t len) { size_t i; printf("%s", head); for (i = 0; i < len; i++) { printf("%02X", ((unsigned char*)data)[i]); if (i % 16 == 15 && i + 1 < len) printf("\n%*s", (int)strlen(head), ""); else if (i + 1 < len) printf(" "); } printf("\n"); } int main(int argc, char **argv) { krb5_error_code ret; krb5_context context = NULL; size_t i; struct test *test; krb5_keyblock kb, *kbp; krb5_checksum cksum; krb5_cksumtype mtype; krb5_boolean valid, verbose = FALSE; int status = 0; if (argc >= 2 && strcmp(argv[1], "-v") == 0) verbose = TRUE; for (i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) { test = &test_cases[i]; if (test->enctype != 0) { kb.magic = KV5M_KEYBLOCK; kb.enctype = test->enctype; kb.length = test->keybits.length; kb.contents = (unsigned char *)test->keybits.data; kbp = &kb; } else kbp = NULL; ret = krb5_c_make_checksum(context, test->sumtype, kbp, test->usage, &test->plaintext, &cksum); assert(!ret); if (verbose) { char buf[64]; krb5_cksumtype_to_string(test->sumtype, buf, sizeof(buf)); printf("\nTest %d:\n", (int)i); printf("Plaintext: %.*s\n", (int)test->plaintext.length, test->plaintext.data); printf("Checksum type: %s\n", buf); if (test->enctype != 0) { krb5_enctype_to_name(test->enctype, FALSE, buf, sizeof(buf)); printf("Enctype: %s\n", buf); printhex("Key: ", test->keybits.data, test->keybits.length); printf("Key usage: %d\n", (int)test->usage); } printhex("Checksum: ", cksum.contents, cksum.length); } if (test->cksum.length != cksum.length || memcmp(test->cksum.data, cksum.contents, cksum.length) != 0) { printf("derive test %d failed\n", (int)i); status = 1; if (!verbose) break; } /* Test that the checksum verifies successfully. */ ret = krb5_c_verify_checksum(context, kbp, test->usage, &test->plaintext, &cksum, &valid); assert(!ret); if (!valid) { printf("test %d verify failed\n", (int)i); status = 1; if (!verbose) break; } if (kbp != NULL) { ret = krb5int_c_mandatory_cksumtype(context, kbp->enctype, &mtype); assert(!ret); if (test->sumtype == mtype) { /* Test that a checksum type of 0 uses the mandatory checksum * type for the key. */ cksum.checksum_type = 0; ret = krb5_c_verify_checksum(context, kbp, test->usage, &test->plaintext, &cksum, &valid); assert(!ret && valid); } } krb5_free_checksum_contents(context, &cksum); assert(cksum.length == 0); } return status; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_cmac.c0000664000175000017500000001203315051422640021351 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_cmac.c */ /* * Copyright 2010 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test vectors for CMAC. Inputs are taken from RFC 4493 section 4. Outputs * are changed for the use of Camellia-128 in place of AES-128. * * Ideally we would double-check subkey values, but we have no easy way to see * them. * * Ideally we would test AES-CMAC against the expected results in RFC 4493, * instead of Camellia-CMAC against results we generated ourselves. This has * been done manually, but is not convenient to do automatically since the * AES-128 enc provider has no cbc_mac method and therefore cannot be used with * krb5int_cmac_checksum. */ #include "crypto_int.h" /* All examples use the following Camellia-128 key. */ static unsigned char keybytes[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; /* Example inputs are this message truncated to 0, 16, 40, and 64 bytes. */ unsigned char input[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }; /* Expected result of CMAC on empty input. */ static unsigned char cmac1[] = { 0xba, 0x92, 0x57, 0x82, 0xaa, 0xa1, 0xf5, 0xd9, 0xa0, 0x0f, 0x89, 0x64, 0x80, 0x94, 0xfc, 0x71 }; /* Expected result of CMAC on first 16 bytes of input. */ static unsigned char cmac2[] = { 0x6d, 0x96, 0x28, 0x54, 0xa3, 0xb9, 0xfd, 0xa5, 0x6d, 0x7d, 0x45, 0xa9, 0x5e, 0xe1, 0x79, 0x93 }; /* Expected result of CMAC on first 40 bytes of input. */ static unsigned char cmac3[] = { 0x5c, 0x18, 0xd1, 0x19, 0xcc, 0xd6, 0x76, 0x61, 0x44, 0xac, 0x18, 0x66, 0x13, 0x1d, 0x9f, 0x22 }; /* Expected result of CMAC on all 64 bytes of input. */ static unsigned char cmac4[] = { 0xc2, 0x69, 0x9a, 0x6e, 0xba, 0x55, 0xce, 0x9d, 0x93, 0x9a, 0x8a, 0x4e, 0x19, 0x46, 0x6e, 0xe9 }; static void check_result(const char *name, const unsigned char *result, const unsigned char *expected) { int i; for (i = 0; i < 16; i++) { if (result[i] != expected[i]) { fprintf(stderr, "CMAC test vector failure: %s\n", name); exit(1); } } } int main(int argc, char **argv) { krb5_error_code ret; krb5_context context = NULL; krb5_keyblock keyblock; krb5_key key; const struct krb5_enc_provider *enc = &krb5int_enc_camellia128; krb5_crypto_iov iov; unsigned char resultbuf[16]; krb5_data result = make_data(resultbuf, 16); /* Create the example key. */ keyblock.magic = KV5M_KEYBLOCK; keyblock.enctype = ENCTYPE_CAMELLIA128_CTS_CMAC; keyblock.length = 16; keyblock.contents = keybytes; ret = krb5_k_create_key(context, &keyblock, &key); assert(!ret); /* Example 1. */ iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(input, 0); ret = krb5int_cmac_checksum(enc, key, &iov, 1, &result); assert(!ret); check_result("example 1", resultbuf, cmac1); /* Example 2. */ iov.data.length = 16; ret = krb5int_cmac_checksum(enc, key, &iov, 1, &result); assert(!ret); check_result("example 2", resultbuf, cmac2); /* Example 3. */ iov.data.length = 40; ret = krb5int_cmac_checksum(enc, key, &iov, 1, &result); assert(!ret); check_result("example 3", resultbuf, cmac3); /* Example 4. */ iov.data.length = 64; ret = krb5int_cmac_checksum(enc, key, &iov, 1, &result); assert(!ret); check_result("example 4", resultbuf, cmac4); printf("All CMAC tests passed.\n"); krb5_k_free_key(context, key); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/camellia-test.c0000664000175000017500000000734315051422640022657 0ustar ghudsonghudson/* lib/crypto/crypto_tests/camellia-test.c */ /* * Copyright (c) 2009 * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * * Subset of NIST tests for AES as applied to Camellia; specifically, the * variable-key and variable-text tests for 128- and 256-bit keys. */ #include #include "crypto_int.h" static char key[32]; static char plain[16], cipher[16], zero[16]; static krb5_keyblock enc_key; static krb5_data ivec; static void init(void) { enc_key.contents = (unsigned char *)key; enc_key.length = 16; ivec.data = zero; ivec.length = 16; } static void enc(void) { krb5_key k; krb5_crypto_iov iov; memcpy(cipher, plain, 16); iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(cipher, 16); krb5_k_create_key(NULL, &enc_key, &k); krb5int_camellia_encrypt(k, &ivec, &iov, 1); krb5_k_free_key(NULL, k); } static void hexdump(const char *label, const char *cp, int len) { printf("%s=", label); while (len--) printf("%02X", 0xff & *cp++); printf("\n"); } static void set_bit(char *ptr, int bitnum) { int bytenum; bytenum = bitnum / 8; bitnum %= 8; /* First bit is the high bit! */ ptr[bytenum] = 1 << (7 - bitnum); } /* Variable-Key tests */ static void vk_test_1(int len) { int i; enc_key.enctype = ENCTYPE_CAMELLIA128_CTS_CMAC; enc_key.length = len; printf("\nKEYSIZE=%d\n\n", len * 8); memset(plain, 0, sizeof(plain)); hexdump("PT", plain, 16); for (i = 0; i < len * 8; i++) { memset(key, 0, len); set_bit(key, i); printf("\nI=%d\n", i+1); hexdump("KEY", key, len); enc(); hexdump("CT", cipher, 16); } printf("\n==========\n"); } static void vk_test(void) { vk_test_1(16); vk_test_1(32); } /* Variable-Text tests */ static void vt_test_1(int len, krb5_enctype etype) { int i; enc_key.enctype = etype; enc_key.length = len; printf("\nKEYSIZE=%d\n\n", len * 8); memset(key, 0, len); hexdump("KEY", key, len); for (i = 0; i < 16 * 8; i++) { memset(plain, 0, sizeof(plain)); set_bit(plain, i); printf("\nI=%d\n", i+1); hexdump("PT", plain, 16); enc(); hexdump("CT", cipher, 16); } printf("\n==========\n"); } static void vt_test(void) { vt_test_1(16, ENCTYPE_CAMELLIA128_CTS_CMAC); vt_test_1(32, ENCTYPE_CAMELLIA256_CTS_CMAC); } int main (int argc, char *argv[]) { if (argc > 2 || (argc == 2 && strcmp(argv[1], "-k"))) { fprintf(stderr, "usage:\t%s -k\tfor variable-key tests\n" " or:\t%s \tfor variable-plaintext tests\n", argv[0], argv[0]); return 1; } init(); if (argc == 2) vk_test(); else vt_test(); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/expect-vt.txt0000664000175000017500000004730615051422640022452 0ustar ghudsonghudson KEYSIZE=128 KEY=00000000000000000000000000000000 I=1 PT=80000000000000000000000000000000 CT=3AD78E726C1EC02B7EBFE92B23D9EC34 I=2 PT=40000000000000000000000000000000 CT=45BC707D29E8204D88DFBA2F0B0CAD9B I=3 PT=20000000000000000000000000000000 CT=161556838018F52805CDBD6202002E3F I=4 PT=10000000000000000000000000000000 CT=F5569B3AB6A6D11EFDE1BF0A64C6854A I=5 PT=08000000000000000000000000000000 CT=64E82B50E501FBD7DD4116921159B83E I=6 PT=04000000000000000000000000000000 CT=BAAC12FB613A7DE11450375C74034041 I=7 PT=02000000000000000000000000000000 CT=BCF176A7EAAD8085EBACEA362462A281 I=8 PT=01000000000000000000000000000000 CT=47711816E91D6FF059BBBF2BF58E0FD3 I=9 PT=00800000000000000000000000000000 CT=B970DFBE40698AF1638FE38BD3DF3B2F I=10 PT=00400000000000000000000000000000 CT=F95B59A44F391E14CF20B74BDC32FCFF I=11 PT=00200000000000000000000000000000 CT=720F74AE04A2A435B9A7256E49378F5B I=12 PT=00100000000000000000000000000000 CT=2A0445F61D36BFA7E277070730CF76DA I=13 PT=00080000000000000000000000000000 CT=8D0536B997AEFEC1D94011BAB6699A03 I=14 PT=00040000000000000000000000000000 CT=674F002E19F6ED47EFF319E51FAD4498 I=15 PT=00020000000000000000000000000000 CT=292C02C5CB9163C80AC0F6CF1DD8E92D I=16 PT=00010000000000000000000000000000 CT=FA321CF18EF5FE727DD82A5C1E945141 I=17 PT=00008000000000000000000000000000 CT=A5A7AFE1034C39CCCEBE3C584BC0BE05 I=18 PT=00004000000000000000000000000000 CT=4FF5A52E697E77D081205DBDB21CEA39 I=19 PT=00002000000000000000000000000000 CT=209E88DC94C9003000CE0769AF7B7166 I=20 PT=00001000000000000000000000000000 CT=5DEE41AF864CB4B650E5F51551824D38 I=21 PT=00000800000000000000000000000000 CT=A79A63FA7E4503AE6D6E09F5F9053030 I=22 PT=00000400000000000000000000000000 CT=A48316749FAE7FAC7002031A6AFD8BA7 I=23 PT=00000200000000000000000000000000 CT=D6EEE8A7357A0E1D64262CA9C337AC42 I=24 PT=00000100000000000000000000000000 CT=B013CA8A62A858053E9FB667ED39829E I=25 PT=00000080000000000000000000000000 CT=DF6EA9E4538A45A52D5C1A43C88F4B55 I=26 PT=00000040000000000000000000000000 CT=7D03BA451371591D3FD5547D9165C73B I=27 PT=00000020000000000000000000000000 CT=0E0426281A6277E186499D365D5F49FF I=28 PT=00000010000000000000000000000000 CT=DBC02169DD2059E6CC4C57C1FEDF5AB4 I=29 PT=00000008000000000000000000000000 CT=826590E05D167DA6F00DCC75E22788EB I=30 PT=00000004000000000000000000000000 CT=34A73F21A04421D9786335FAAB49423A I=31 PT=00000002000000000000000000000000 CT=ED347D0E0128EE1A7392A1D36AB78AA9 I=32 PT=00000001000000000000000000000000 CT=EE944B2FE6E9FC888042608DA9615F75 I=33 PT=00000000800000000000000000000000 CT=9E7C85A909EF7218BA7947CFB4718F46 I=34 PT=00000000400000000000000000000000 CT=811AE07A0B2B1F816587FA73699AE77D I=35 PT=00000000200000000000000000000000 CT=68466FBF43C2FE13D4B18F7EC5EA745F I=36 PT=00000000100000000000000000000000 CT=D20B015C7191B219780956E6101F9354 I=37 PT=00000000080000000000000000000000 CT=5939D5C1BBF54EE1B3E326D757BDDE25 I=38 PT=00000000040000000000000000000000 CT=B1FDAFE9A0240E8FFEA19CE94B5105D3 I=39 PT=00000000020000000000000000000000 CT=D62962ECE02CDD68C06BDFEFB2F9495B I=40 PT=00000000010000000000000000000000 CT=B3BB2DE6F3C26587BA8BAC4F7AD9499A I=41 PT=00000000008000000000000000000000 CT=E0B1072D6D9FF703D6FBEF77852B0A6B I=42 PT=00000000004000000000000000000000 CT=D8DD51C907F478DE0228E83E61FD1758 I=43 PT=00000000002000000000000000000000 CT=A42DFFE6E7C1671C06A25236FDD10017 I=44 PT=00000000001000000000000000000000 CT=25ACF141550BFAB9EF451B6C6A5B2163 I=45 PT=00000000000800000000000000000000 CT=4DA7FCA3949B16E821DBC84F19581018 I=46 PT=00000000000400000000000000000000 CT=7D49B6347CBCC8919C7FA96A37A7A215 I=47 PT=00000000000200000000000000000000 CT=900024B29A08C6721B95BA3B753DDB4D I=48 PT=00000000000100000000000000000000 CT=6D2182FB283B6934D90BA7848CAB5E66 I=49 PT=00000000000080000000000000000000 CT=F73EF01B448D23A4D90DE8B2F9666E7A I=50 PT=00000000000040000000000000000000 CT=4AD9CDA2418643E9A3D926AF5E6B0412 I=51 PT=00000000000020000000000000000000 CT=7CAEC8E7E5953997D545B033201C8C5B I=52 PT=00000000000010000000000000000000 CT=3C43CA1F6B6864503E27B48D88230CF5 I=53 PT=00000000000008000000000000000000 CT=44F779B93108FE9FEEC880D79BA74488 I=54 PT=00000000000004000000000000000000 CT=9E50E8D9CFD3A682A78E527C9072A1CF I=55 PT=00000000000002000000000000000000 CT=68D000CBC838BBE3C505D6F814C01F28 I=56 PT=00000000000001000000000000000000 CT=2CB2A9FEC1ACD1D9B0FA05205E304F57 I=57 PT=00000000000000800000000000000000 CT=01EB2806606E46444520A5CC6180CD4B I=58 PT=00000000000000400000000000000000 CT=DAA9B25168CC702326F217F1A0C0B162 I=59 PT=00000000000000200000000000000000 CT=3E07E648975D9578D03555B1755807ED I=60 PT=00000000000000100000000000000000 CT=0B45F52E802C8B8DE09579425B80B711 I=61 PT=00000000000000080000000000000000 CT=659595DA0B68F6DF0DD6CA77202986E1 I=62 PT=00000000000000040000000000000000 CT=05FF42873893536E58C8FA98A45C73C4 I=63 PT=00000000000000020000000000000000 CT=B5B03421DE8BBFFC4EADEC767339A9BD I=64 PT=00000000000000010000000000000000 CT=788BCD111ECF73D4E78D2E21BEF55460 I=65 PT=00000000000000008000000000000000 CT=909CD9EC6790359F982DC6F2393D5315 I=66 PT=00000000000000004000000000000000 CT=332950F361535FF24EFAC8C76293F12C I=67 PT=00000000000000002000000000000000 CT=A68CCD4E330FFDA9D576DA436DB53D75 I=68 PT=00000000000000001000000000000000 CT=27C8A1CCFDB0B015D1ED5B3E77143791 I=69 PT=00000000000000000800000000000000 CT=D76A4B95887A77DF610DD3E1D3B20325 I=70 PT=00000000000000000400000000000000 CT=C068AB0DE71C66DAE83C361EF4B2D989 I=71 PT=00000000000000000200000000000000 CT=C2120BCD49EDA9A288B3B4BE79AC8158 I=72 PT=00000000000000000100000000000000 CT=0C546F62BF2773CD0F564FCECA7BA688 I=73 PT=00000000000000000080000000000000 CT=18F3462BEDE4920213CCB66DAB1640AA I=74 PT=00000000000000000040000000000000 CT=FE42F245EDD0E24B216AEBD8B392D690 I=75 PT=00000000000000000020000000000000 CT=3D3EEBC8D3D1558A194C2D00C337FF2B I=76 PT=00000000000000000010000000000000 CT=29AAEDF043E785DB42836F79BE6CBA28 I=77 PT=00000000000000000008000000000000 CT=215F90C6744E2944358E78619159A611 I=78 PT=00000000000000000004000000000000 CT=8606B1AA9E1D548E5442B06551E2C6DC I=79 PT=00000000000000000002000000000000 CT=987BB4B8740EC0EDE7FEA97DF033B5B1 I=80 PT=00000000000000000001000000000000 CT=C0A3500DA5B0AE07D2F450930BEEDF1B I=81 PT=00000000000000000000800000000000 CT=525FDF8312FE8F32C781481A8DAAAE37 I=82 PT=00000000000000000000400000000000 CT=BFD2C56AE5FB9C9DE33A6944572A6487 I=83 PT=00000000000000000000200000000000 CT=7975A57A425CDF5AA1FA929101F650B0 I=84 PT=00000000000000000000100000000000 CT=BF174BC49609A8709B2CD8366DAA79FE I=85 PT=00000000000000000000080000000000 CT=06C50C43222F56C874B1704E9F44BF7D I=86 PT=00000000000000000000040000000000 CT=0CEC48CD34043EA29CA3B8ED5278721E I=87 PT=00000000000000000000020000000000 CT=9548EA34A1560197B304D0ACB8A1698D I=88 PT=00000000000000000000010000000000 CT=22F9E9B1BD73B6B5B7D3062C986272F3 I=89 PT=00000000000000000000008000000000 CT=FEE8E934BD0873295059002230E298D4 I=90 PT=00000000000000000000004000000000 CT=1B08E2E3EB820D139CB4ABBDBE81D00D I=91 PT=00000000000000000000002000000000 CT=0021177681E4D90CEAF69DCED0145125 I=92 PT=00000000000000000000001000000000 CT=4A8E314452CA8A8A3619FC54BC423643 I=93 PT=00000000000000000000000800000000 CT=65047474F7222C94C6965425FF1BFD0A I=94 PT=00000000000000000000000400000000 CT=E123F551A9C4A8489622B16F961A9AA4 I=95 PT=00000000000000000000000200000000 CT=EF05530948B80915028BB2B6FE429380 I=96 PT=00000000000000000000000100000000 CT=72535B7FE0F0F777CEDCD55CD77E2DDF I=97 PT=00000000000000000000000080000000 CT=3423D8EFC31FA2F4C365C77D8F3B5C63 I=98 PT=00000000000000000000000040000000 CT=DE0E51C264663F3C5DBC59580A98D8E4 I=99 PT=00000000000000000000000020000000 CT=B2D9391166680947AB09264156719679 I=100 PT=00000000000000000000000010000000 CT=10DB79F23B06D263835C424AF749ADB7 I=101 PT=00000000000000000000000008000000 CT=DDF72D27E6B01EC107EA3E005B59563B I=102 PT=00000000000000000000000004000000 CT=8266B57485A5954A4236751DE07F6694 I=103 PT=00000000000000000000000002000000 CT=669A501E1F1ADE6E5523DE01D6DBC987 I=104 PT=00000000000000000000000001000000 CT=C20C48F2989725D461D1DB589DC0896E I=105 PT=00000000000000000000000000800000 CT=DE35158E7810ED1191825D2AA98FA97D I=106 PT=00000000000000000000000000400000 CT=4FE294F2C0F34D0671B693A237EBDDC8 I=107 PT=00000000000000000000000000200000 CT=087AE74B10CCBFDF6739FEB9559C01A4 I=108 PT=00000000000000000000000000100000 CT=5DC278970B7DEF77A5536C77AB59C207 I=109 PT=00000000000000000000000000080000 CT=7607F078C77085184EAA9B060C1FBFFF I=110 PT=00000000000000000000000000040000 CT=9DB841531BCBE7998DAD19993FB3CC00 I=111 PT=00000000000000000000000000020000 CT=D6A089B654854A94560BAE13298835B8 I=112 PT=00000000000000000000000000010000 CT=E1E223C4CF90CC5D195B370D65114622 I=113 PT=00000000000000000000000000008000 CT=1CBED73C50D053BDAD372CEEE54836A1 I=114 PT=00000000000000000000000000004000 CT=D309E69376D257ADF2BFDA152B26555F I=115 PT=00000000000000000000000000002000 CT=740F7649117F0DEE6EAA7789A9994C36 I=116 PT=00000000000000000000000000001000 CT=76AE64417C297184D668C5FD908B3CE5 I=117 PT=00000000000000000000000000000800 CT=6095FEA4AA8035591F1787A819C48787 I=118 PT=00000000000000000000000000000400 CT=D1FF4E7ACD1C79967FEBAB0F7465D450 I=119 PT=00000000000000000000000000000200 CT=5F5AD3C42B9489557BB63BF49ECF5F8A I=120 PT=00000000000000000000000000000100 CT=FB56CC09B680B1D07C5A52149E29F07C I=121 PT=00000000000000000000000000000080 CT=FF49B8DF4A97CBE03833E66197620DAD I=122 PT=00000000000000000000000000000040 CT=5E070ADE533D2E090ED0F5BE13BC0983 I=123 PT=00000000000000000000000000000020 CT=3AB4FB1D2B7BA376590A2C241D1F508D I=124 PT=00000000000000000000000000000010 CT=58B2431BC0BEDE02550F40238969EC78 I=125 PT=00000000000000000000000000000008 CT=0253786E126504F0DAB90C48A30321DE I=126 PT=00000000000000000000000000000004 CT=200211214E7394DA2089B6ACD093ABE0 I=127 PT=00000000000000000000000000000002 CT=0388DACE60B6A392F328C2B971B2FE78 I=128 PT=00000000000000000000000000000001 CT=58E2FCCEFA7E3061367F1D57A4E7455A ========== KEYSIZE=256 KEY=0000000000000000000000000000000000000000000000000000000000000000 I=1 PT=80000000000000000000000000000000 CT=DDC6BF790C15760D8D9AEB6F9A75FD4E I=2 PT=40000000000000000000000000000000 CT=C7098C217C334D0C9BDF37EA13B0822C I=3 PT=20000000000000000000000000000000 CT=60F0FB0D4C56A8D4EEFEC5264204042D I=4 PT=10000000000000000000000000000000 CT=73376FBBF654D0686E0E84001477106B I=5 PT=08000000000000000000000000000000 CT=2F443B52BA5F0C6EA0602C7C4FD259B6 I=6 PT=04000000000000000000000000000000 CT=75D11B0E3A68C4223D88DBF017977DD7 I=7 PT=02000000000000000000000000000000 CT=779B38D15BFFB63D8D609D551A5CC98E I=8 PT=01000000000000000000000000000000 CT=5275F3D86B4FB8684593133EBFA53CD3 I=9 PT=00800000000000000000000000000000 CT=1CEF2074B336CEC62F12DEA2F6AB1481 I=10 PT=00400000000000000000000000000000 CT=1AEF5ABBAD9D7160874578DCD8BAE172 I=11 PT=00200000000000000000000000000000 CT=46C525DB17E72F26BF03216846B6F609 I=12 PT=00100000000000000000000000000000 CT=E24411F941BBE08788781E3EC52CBAA4 I=13 PT=00080000000000000000000000000000 CT=83A3DEDD1DD27018F6A6477E40527581 I=14 PT=00040000000000000000000000000000 CT=B68F8A2CDBAB0C923C67FC8F0F1087DE I=15 PT=00020000000000000000000000000000 CT=649944A70C32BF87A7409E7AE128FDE8 I=16 PT=00010000000000000000000000000000 CT=2846526D67387539C89314DE9E0C2D02 I=17 PT=00008000000000000000000000000000 CT=A9A0B8402E53C70DD1688054BA58DDFD I=18 PT=00004000000000000000000000000000 CT=4A72E6E1B79C83AC4BE3EBA5699EED48 I=19 PT=00002000000000000000000000000000 CT=B0E36B867BA4FF2B77D0614B0E364E4C I=20 PT=00001000000000000000000000000000 CT=49B57DE141F6418E3090F24DDD4014B6 I=21 PT=00000800000000000000000000000000 CT=A6C0D5B9797258E1987AC5F6CD20146D I=22 PT=00000400000000000000000000000000 CT=426CF4BDCAA369175965D26E7C71EEA2 I=23 PT=00000200000000000000000000000000 CT=E27F484CE54BC99BC1A52BDA3B518A26 I=24 PT=00000100000000000000000000000000 CT=D16D186284C7E6EE64B8104E0EF20BA5 I=25 PT=00000080000000000000000000000000 CT=6431F8538AD54E1E044A9F71F8EF556B I=26 PT=00000040000000000000000000000000 CT=ECD57CEB451D27EB96C55B2042257E8E I=27 PT=00000020000000000000000000000000 CT=4F0F188DC911B1954AFBC734C9F68872 I=28 PT=00000010000000000000000000000000 CT=B54DEF0337626B65614E81EDFDE620F3 I=29 PT=00000008000000000000000000000000 CT=6655D8074CAE0B90B0D3A3FE72D4D9DB I=30 PT=00000004000000000000000000000000 CT=C6B74B6B9EB4FC0C9A237DB1B616D09A I=31 PT=00000002000000000000000000000000 CT=D7B5D076EA56EC2B20791D7AD51CCF8F I=32 PT=00000001000000000000000000000000 CT=FE160C224BF003CE3BDDC90CB52ED22C I=33 PT=00000000800000000000000000000000 CT=5E00DA9BA94B5EC0D258D8A8002E0F6A I=34 PT=00000000400000000000000000000000 CT=09AC6DCFF4DACFF1651E2BA212A292A3 I=35 PT=00000000200000000000000000000000 CT=B283617E318D99AF83A05D9810BA89F7 I=36 PT=00000000100000000000000000000000 CT=0B5F70CCB40B0EF2538AE9B4A9770B35 I=37 PT=00000000080000000000000000000000 CT=43282BF180248FB517839B37F4DDAAE4 I=38 PT=00000000040000000000000000000000 CT=DDBD534C8B2E6D30A268F88C55AD765B I=39 PT=00000000020000000000000000000000 CT=A41A164E50EC2D9F175E752B755E0B5C I=40 PT=00000000010000000000000000000000 CT=37BFF99FF2F7AA97779E4ADF6F13FB10 I=41 PT=00000000008000000000000000000000 CT=9BA4F7BD298152903A683C4CEC669216 I=42 PT=00000000004000000000000000000000 CT=5FB750C7CE10DE7B4504248914D0DA06 I=43 PT=00000000002000000000000000000000 CT=3E748BFA108E086F51D56EC74A9E0FB9 I=44 PT=00000000001000000000000000000000 CT=31D4E56B99F5B73C1B8437DF332AFB98 I=45 PT=00000000000800000000000000000000 CT=9DC6717B84FC55D266E7B1D9B5C52A5F I=46 PT=00000000000400000000000000000000 CT=8EF8BA007F23C0A50FC120E07041BCCD I=47 PT=00000000000200000000000000000000 CT=C58F38E1839FC1918A12B8C9E88C66B6 I=48 PT=00000000000100000000000000000000 CT=B695D72A3FCF508C4050E12E40061C2D I=49 PT=00000000000080000000000000000000 CT=5D2736AD478A50583BC8C11BEFF16D7A I=50 PT=00000000000040000000000000000000 CT=DF0EACA8F17847AD41F9578F14C7B56B I=51 PT=00000000000020000000000000000000 CT=E5AA14AD48AD0A3C47CC35D5F8020E51 I=52 PT=00000000000010000000000000000000 CT=11BE6C8F58EBD8CEF1A53F591A68E8CE I=53 PT=00000000000008000000000000000000 CT=ECFE7BAFCBF42C1FEE015488770B3053 I=54 PT=00000000000004000000000000000000 CT=E552649F8D8EC4A1E1CD6DF50B6E6777 I=55 PT=00000000000002000000000000000000 CT=521C0629DE93B9119CDB1DDC5809DDEA I=56 PT=00000000000001000000000000000000 CT=CB38A62A0BAB1784156BA038CBA99BF6 I=57 PT=00000000000000800000000000000000 CT=76CCEE8AAACD394DE1EEF3DDA10CB54B I=58 PT=00000000000000400000000000000000 CT=6AFF910FA1D5673140E2DB59B8416049 I=59 PT=00000000000000200000000000000000 CT=064A12C0EF73FB386801BF4F35F3120D I=60 PT=00000000000000100000000000000000 CT=2240E374929D5B1BB8FF0FFDDDF640EC I=61 PT=00000000000000080000000000000000 CT=D4BA15C904C7692185DE85C02052E180 I=62 PT=00000000000000040000000000000000 CT=1714A315AB0166728A44CD91D4AE9018 I=63 PT=00000000000000020000000000000000 CT=6C970BDD9F0E222722EA31A1D12DD0AD I=64 PT=00000000000000010000000000000000 CT=F5956EDF02BD36A401BBB6CE77C3D3FB I=65 PT=00000000000000008000000000000000 CT=0CA11F122CCD7C259DC597EED3DF9BC4 I=66 PT=00000000000000004000000000000000 CT=50109AB4912AD2560B206F331B62EB6C I=67 PT=00000000000000002000000000000000 CT=DBE7C91A4175614889A2D4BEFD64845E I=68 PT=00000000000000001000000000000000 CT=0D3322853A571A6B46B79C0228E0DD25 I=69 PT=00000000000000000800000000000000 CT=96E4EE0BB9A11C6FB8522F285BADDEB6 I=70 PT=00000000000000000400000000000000 CT=96705C52D2CFCE82E630C93477C79C49 I=71 PT=00000000000000000200000000000000 CT=C50130AED6A126149D71F3888C83C232 I=72 PT=00000000000000000100000000000000 CT=4816EFE3DEB380566EBA0C17BF582090 I=73 PT=00000000000000000080000000000000 CT=0390857B4C8C98E4CF7A2B6F3394C507 I=74 PT=00000000000000000040000000000000 CT=422E73A02025EBE8B8B5D6E0FA24FCB2 I=75 PT=00000000000000000020000000000000 CT=3271AA7F4BF1D7C38050A43076D4FF76 I=76 PT=00000000000000000010000000000000 CT=D2074946F0D37B8975607BFC2E70234C I=77 PT=00000000000000000008000000000000 CT=1A509194C1270AB92E5A42D3A9F8D98B I=78 PT=00000000000000000004000000000000 CT=512438946360CCC4A5C6D73F6EED7130 I=79 PT=00000000000000000002000000000000 CT=98CFCDEC46EBEA1A286B3004F2746A0D I=80 PT=00000000000000000001000000000000 CT=A1CF369949677A3AF3D58E3EABF2741B I=81 PT=00000000000000000000800000000000 CT=D84C2E1A0E4A52166FA8FF6889D1E5E2 I=82 PT=00000000000000000000400000000000 CT=4AD91CCEEF60119B5078FD162D2735DE I=83 PT=00000000000000000000200000000000 CT=2860793D818E97AAFF1D339D7702438D I=84 PT=00000000000000000000100000000000 CT=6F9068BE73364AE250D89D78A6C9CE6F I=85 PT=00000000000000000000080000000000 CT=024FC3FEF4883FEB1A8DD005305FECCE I=86 PT=00000000000000000000040000000000 CT=08A61FE0816D75EA15EB3C9FB9CCDED6 I=87 PT=00000000000000000000020000000000 CT=449C86DFA13F260175CE39797686FFA4 I=88 PT=00000000000000000000010000000000 CT=4FFFFC29A59858E1133F2BFB1A8A4817 I=89 PT=00000000000000000000008000000000 CT=19425D1F6480B25096561295697DC2B7 I=90 PT=00000000000000000000004000000000 CT=31974727ECDD2C77C3A428FC3A8CB3FC I=91 PT=00000000000000000000002000000000 CT=A57CD704B3C95E744D08DF443458F2F5 I=92 PT=00000000000000000000001000000000 CT=486D8C193DB1ED73ACB17990442FC40B I=93 PT=00000000000000000000000800000000 CT=5E4DBF4E83AB3BC055B9FCC7A6B3A763 I=94 PT=00000000000000000000000400000000 CT=ACF2E0A693FBBCBA4D41B861E0D89E37 I=95 PT=00000000000000000000000200000000 CT=32A7CB2AE066A51D2B78FC4B4CFCB608 I=96 PT=00000000000000000000000100000000 CT=677D494DBB73CAF55C1990158DA12F14 I=97 PT=00000000000000000000000080000000 CT=082A0D2367512ADF0D75A151BFBE0A17 I=98 PT=00000000000000000000000040000000 CT=5E5BB7337923C482CE8CBA249E6A8C7D I=99 PT=00000000000000000000000020000000 CT=D3001BA7C7026EE3E5003179530AFCFC I=100 PT=00000000000000000000000010000000 CT=46EC44F8931E629FE8FD8961312EDDE1 I=101 PT=00000000000000000000000008000000 CT=C5F8ECD79C7B30E81D17E32079969310 I=102 PT=00000000000000000000000004000000 CT=5B8AD6919E24CAEBCC55401AEE0C9802 I=103 PT=00000000000000000000000002000000 CT=C2302B7E701B5CC7F8B29E3516DBBFA6 I=104 PT=00000000000000000000000001000000 CT=A1D04D6A76F9F7A94D49FAA64A87F244 I=105 PT=00000000000000000000000000800000 CT=7FB6F92D35B5CB6C631600EDB9E860BA I=106 PT=00000000000000000000000000400000 CT=B2EF7078BCFACE07AEEC3F9B48830EB3 I=107 PT=00000000000000000000000000200000 CT=F475A7493D24C7036E53390374C378B3 I=108 PT=00000000000000000000000000100000 CT=B36802AC987377A37BD8EADC97C57D60 I=109 PT=00000000000000000000000000080000 CT=ADDCD3D19689C4DDC738CE5F69DC9505 I=110 PT=00000000000000000000000000040000 CT=0DAF8CA22884915403C0F0BB1F4BD74F I=111 PT=00000000000000000000000000020000 CT=4AF36BAE2660503B3248E4685059FD05 I=112 PT=00000000000000000000000000010000 CT=7D5631814DD8E917D97A0D514C743971 I=113 PT=00000000000000000000000000008000 CT=BC3352500FC0CBB9DB5B5F6B491C1BE8 I=114 PT=00000000000000000000000000004000 CT=6A4A30BA87E87AF65C90AEB7AFEDC76B I=115 PT=00000000000000000000000000002000 CT=77E6125897668AC8E73E8C79A6FF8336 I=116 PT=00000000000000000000000000001000 CT=3FA9D39104EBB323C7AAAA248960DD1E I=117 PT=00000000000000000000000000000800 CT=FAD75AD76AB10ADC49036B250E229D39 I=118 PT=00000000000000000000000000000400 CT=2FACAA5FE35B228A16AC74088D702EC4 I=119 PT=00000000000000000000000000000200 CT=88B6CBCFDFEF8AD91720A1BB69A1F33E I=120 PT=00000000000000000000000000000100 CT=C7E9D250998632D444356242EF04058D I=121 PT=00000000000000000000000000000080 CT=B14DAD8D3D9153F46C0D3A1AD63C7A05 I=122 PT=00000000000000000000000000000040 CT=60ABA678A506608D0845966D29B5F790 I=123 PT=00000000000000000000000000000020 CT=482DC43F2388EF25D24144E144BD834E I=124 PT=00000000000000000000000000000010 CT=1490A05A7CEE43BDE98B56E309DC0126 I=125 PT=00000000000000000000000000000008 CT=ABFA77CD6E85DA245FB0BDC5E52CFC29 I=126 PT=00000000000000000000000000000004 CT=DD4AB1284D4AE17B41E85924470C36F7 I=127 PT=00000000000000000000000000000002 CT=CEA7403D4D606B6E074EC5D3BAF39D18 I=128 PT=00000000000000000000000000000001 CT=530F8AFBC74536B9A963B4F1C4CB738B ========== krb5-1.22.1/src/lib/crypto/crypto_tests/camellia-expect-vt.txt0000664000175000017500000004730615051422640024217 0ustar ghudsonghudson KEYSIZE=128 KEY=00000000000000000000000000000000 I=1 PT=80000000000000000000000000000000 CT=07923A39EB0A817D1C4D87BDB82D1F1C I=2 PT=40000000000000000000000000000000 CT=48CD6419809672D2349260D89A08D3D3 I=3 PT=20000000000000000000000000000000 CT=D07493CCB2E95CE0B4945A05ACC97D82 I=4 PT=10000000000000000000000000000000 CT=5DBE1EAC9F7080A88DBED7F6DA101448 I=5 PT=08000000000000000000000000000000 CT=F01EE477D199DF2701027034B229622F I=6 PT=04000000000000000000000000000000 CT=C841587ABD9A912E563774CB569D051E I=7 PT=02000000000000000000000000000000 CT=1D9BC0C04546F0915C8CCD11391A455C I=8 PT=01000000000000000000000000000000 CT=05E6EBB4BA167F5C479CEFF3152F943B I=9 PT=00800000000000000000000000000000 CT=93211E0F788845B9FC0E4551FFE92AC9 I=10 PT=00400000000000000000000000000000 CT=B6D35701CD8FADDE383BBE8E6B70BAF7 I=11 PT=00200000000000000000000000000000 CT=8358F9F4EBCFEE348CB30551ACB151A0 I=12 PT=00100000000000000000000000000000 CT=D57516EB5AD93C523E40521BF447AFCE I=13 PT=00080000000000000000000000000000 CT=66B2534C279C439133F52E5AD8B439A9 I=14 PT=00040000000000000000000000000000 CT=A71C69184A9F63C2992A5F18F77C1FE9 I=15 PT=00020000000000000000000000000000 CT=1ADCBE49AEACB9ECEBBD492B10E82C7B I=16 PT=00010000000000000000000000000000 CT=27E3BCFB227C5561DB6CF7FC30387036 I=17 PT=00008000000000000000000000000000 CT=F4AE20365CC9D06B0CAE6B695ED2CEC1 I=18 PT=00004000000000000000000000000000 CT=3DD682F0B641ED32AD3D43EA2A0456E4 I=19 PT=00002000000000000000000000000000 CT=6E5D14A95ECC290B509EA6B673652E3A I=20 PT=00001000000000000000000000000000 CT=F1CDF0F8D7B3FFD95422D7CC0CF40B7B I=21 PT=00000800000000000000000000000000 CT=A9253D459A34C385A1F1B2CFFA3935C5 I=22 PT=00000400000000000000000000000000 CT=291024D99FF09A47A1DEE45BA700AE52 I=23 PT=00000200000000000000000000000000 CT=49241D9459B277187BB10081C60361C0 I=24 PT=00000100000000000000000000000000 CT=AD9BA365CC4DD5553D2D9FE303841D88 I=25 PT=00000080000000000000000000000000 CT=C2ECA616664A249DC622CC11196B4AE1 I=26 PT=00000040000000000000000000000000 CT=6E1A2D4794BB0DC08777A0BC7523E70E I=27 PT=00000020000000000000000000000000 CT=6DB1F0CF59656BDD235E82B8CEF0BE8E I=28 PT=00000010000000000000000000000000 CT=52F239C5EAF401EBDC54D2F011FF4B6A I=29 PT=00000008000000000000000000000000 CT=6B58A08F648414B67FD6847D2AA51CBF I=30 PT=00000004000000000000000000000000 CT=2959DD5367885A75EB48053CF3251A36 I=31 PT=00000002000000000000000000000000 CT=630B292E3B88EF641CDFD531E206605E I=32 PT=00000001000000000000000000000000 CT=4BBB88EF82B70593FCC56AFD91540FDB I=33 PT=00000000800000000000000000000000 CT=0A13055B118A45C606999257BD191426 I=34 PT=00000000400000000000000000000000 CT=5CF8E5C9F15D7E4F865020224853EB77 I=35 PT=00000000200000000000000000000000 CT=3898805042C7A4315C5EE51AF2DE47E2 I=36 PT=00000000100000000000000000000000 CT=8D3F96372E87CBB0B375425B3A10B9E7 I=37 PT=00000000080000000000000000000000 CT=4D9510A378BD784A70A66BCC75B7D3C8 I=38 PT=00000000040000000000000000000000 CT=70DB1902D37CFBDFB98F7C516F79D416 I=39 PT=00000000020000000000000000000000 CT=383C6C2AABEF7FDE25CD470BF774A331 I=40 PT=00000000010000000000000000000000 CT=47CBCB5288349B1A15DC9F81FBEE6B8F I=41 PT=00000000008000000000000000000000 CT=21DA34D4468EEB13AED95DAE0FF48310 I=42 PT=00000000004000000000000000000000 CT=021C9A8E6BD36FBD036411E5D852A80F I=43 PT=00000000002000000000000000000000 CT=6A459E2F839AF60ACDE83774D0BB5574 I=44 PT=00000000001000000000000000000000 CT=C19255121F1B933CAE09E58AEC0E9977 I=45 PT=00000000000800000000000000000000 CT=7BA949E27B2BE148A6B801F9305F43D5 I=46 PT=00000000000400000000000000000000 CT=E8CEB1026BCF7BCEA32E8A380EA76DB7 I=47 PT=00000000000200000000000000000000 CT=63F97747ED56A8F521B20CC65F6F9465 I=48 PT=00000000000100000000000000000000 CT=2091CFDC629819106188424AC694F75B I=49 PT=00000000000080000000000000000000 CT=A91BDF8E8B88407942423CCE000527C4 I=50 PT=00000000000040000000000000000000 CT=73F9B44B9635A3FD683DBF8D49E9825B I=51 PT=00000000000020000000000000000000 CT=9DC64B2133FAD5069FD9A7CC2FFFD1CC I=52 PT=00000000000010000000000000000000 CT=28240F81FEC36B71E13F1FEA7A7641E3 I=53 PT=00000000000008000000000000000000 CT=20DD39FEE96CD2EFF972872A692B28FD I=54 PT=00000000000004000000000000000000 CT=47A9E40483EC1925B635E47E964E8E93 I=55 PT=00000000000002000000000000000000 CT=9C0EBD822C49FB3D853DF5B315A87BA0 I=56 PT=00000000000001000000000000000000 CT=C18D813FDB45A594C6DC24E5A1F6CE32 I=57 PT=00000000000000800000000000000000 CT=7E5467FF245ECF80CB55C2D8E91F0711 I=58 PT=00000000000000400000000000000000 CT=394D4365B77954FDEA4145FCF7A7A041 I=59 PT=00000000000000200000000000000000 CT=B1D8311A492ED11F11E57B29221610C4 I=60 PT=00000000000000100000000000000000 CT=E5FBB947A63AEA90163AF04AD6951EF8 I=61 PT=00000000000000080000000000000000 CT=CA0627DDF580F0E7D59562825C9D0492 I=62 PT=00000000000000040000000000000000 CT=EF98FFD1AED295AAE1860F0274C8F555 I=63 PT=00000000000000020000000000000000 CT=8C698E5CFFF08FACE10C2DC5FF1E2A81 I=64 PT=00000000000000010000000000000000 CT=35A7767E02032C35B5CE1A6F49C57C28 I=65 PT=00000000000000008000000000000000 CT=AB36F8734E76EBA306CF00D6763D90B0 I=66 PT=00000000000000004000000000000000 CT=E854EB66D4EC66889B5E6CD4F44A5806 I=67 PT=00000000000000002000000000000000 CT=15B66DF1455ACD640B8716BCF5DB2D69 I=68 PT=00000000000000001000000000000000 CT=4C57AB5333E5C2D4B7E30A007E449F48 I=69 PT=00000000000000000800000000000000 CT=BA3E7FF28EB38EA09D8DB1440A9A3552 I=70 PT=00000000000000000400000000000000 CT=64E60227AFD80C40C70186CC94804C1A I=71 PT=00000000000000000200000000000000 CT=CEB4423C20B4C91C2551F6FC227C9514 I=72 PT=00000000000000000100000000000000 CT=F736894B843EF32DA28576DE500D448C I=73 PT=00000000000000000080000000000000 CT=58FDA98B678D15053D4B6C060368108C I=74 PT=00000000000000000040000000000000 CT=E28CAE384E578F47657755EBCD97996C I=75 PT=00000000000000000020000000000000 CT=0A64617BD4B5B166668240D105B7B6A2 I=76 PT=00000000000000000010000000000000 CT=4BD090C7E3D365B5EA80F19B4798881E I=77 PT=00000000000000000008000000000000 CT=BC7B6CB9BFF4F72973BB2CD20A512C06 I=78 PT=00000000000000000004000000000000 CT=4C7ADDC5C867594E9EE75F0AA6AB9C23 I=79 PT=00000000000000000002000000000000 CT=1FBD05C71A36691AC6566A5298101D53 I=80 PT=00000000000000000001000000000000 CT=42D7D6B1F499D412F8793972BD968DA2 I=81 PT=00000000000000000000800000000000 CT=260EC86E2786FC68824576B934F32814 I=82 PT=00000000000000000000400000000000 CT=576C26DFD7046F9357F34BEA7DFB26A0 I=83 PT=00000000000000000000200000000000 CT=6D55E54BFB6F927174A02294C95E0F8F I=84 PT=00000000000000000000100000000000 CT=1A6CE91DD458229C7675A34950D10E23 I=85 PT=00000000000000000000080000000000 CT=DAD0D5E7E000652825AA34D228EA8D8F I=86 PT=00000000000000000000040000000000 CT=E68013F48D75EAD2BBC0B0BDA5E690BF I=87 PT=00000000000000000000020000000000 CT=A07D92312FBAE37BFE8A834210AE4F9C I=88 PT=00000000000000000000010000000000 CT=6EEE5F8544CD7D456366EB448813989A I=89 PT=00000000000000000000008000000000 CT=F8E5C7FF4B79D7ABE8BFA2DD148820A8 I=90 PT=00000000000000000000004000000000 CT=C6349D75C7472BBD66F95B3A07C79C91 I=91 PT=00000000000000000000002000000000 CT=B85713C12D8658951CD1AD21C74D2CD2 I=92 PT=00000000000000000000001000000000 CT=907AA00B9F7D47A97623FB55BA911F29 I=93 PT=00000000000000000000000800000000 CT=DC3CD0ED23D11776FAB43A2A6A8F3557 I=94 PT=00000000000000000000000400000000 CT=4BFE58A8FD69179C14765B09AB70B705 I=95 PT=00000000000000000000000200000000 CT=A23996E0EA67EC280356E5F77130A551 I=96 PT=00000000000000000000000100000000 CT=CDEADE859B3AACD273CCA85A3E2E45F2 I=97 PT=00000000000000000000000080000000 CT=E0FC78489857D84DA03F40CE97147174 I=98 PT=00000000000000000000000040000000 CT=7615EA6351F6BB12855E8579C6995D8E I=99 PT=00000000000000000000000020000000 CT=13E184344FE28C2E70ED0E4D0A8037F9 I=100 PT=00000000000000000000000010000000 CT=A5FE395F568482B87BC3EB208C81C942 I=101 PT=00000000000000000000000008000000 CT=B3103E11AF06C85565823F8CAA3159F6 I=102 PT=00000000000000000000000004000000 CT=7EBC2234D271B89C519C396985300030 I=103 PT=00000000000000000000000002000000 CT=0661D338F2E0C939BA1687820A768467 I=104 PT=00000000000000000000000001000000 CT=EC2B42667C0195A90715499617884DA5 I=105 PT=00000000000000000000000000800000 CT=AE077BA19D24E7188DDD3682FF196892 I=106 PT=00000000000000000000000000400000 CT=98823C24B9C65A66073C7952DC2B4B5E I=107 PT=00000000000000000000000000200000 CT=6AB58432CBB3C2F503DA2D16796CC297 I=108 PT=00000000000000000000000000100000 CT=EEB5EBB3A53E4196C2F22BC1A4DDF5E8 I=109 PT=00000000000000000000000000080000 CT=33DC40AC5FDC126D38878416AF6C0FA6 I=110 PT=00000000000000000000000000040000 CT=38EDDC08E18B4AD982CEA921D2765A9A I=111 PT=00000000000000000000000000020000 CT=7D6BEA038E9347C642E18631660A9558 I=112 PT=00000000000000000000000000010000 CT=FDA57921A473B5EE3700AD5ADF035019 I=113 PT=00000000000000000000000000008000 CT=699B4812E200337E9C1D2C397F0DFE4E I=114 PT=00000000000000000000000000004000 CT=7A1EADF68B0807145D6C414852DECFC8 I=115 PT=00000000000000000000000000002000 CT=1645FFAA8AD76689C01DA8C40882781F I=116 PT=00000000000000000000000000001000 CT=BA0C053BE702FA62FC66D8FEB12FC97E I=117 PT=00000000000000000000000000000800 CT=841FD8AF69CF2C31F7D4D7B6959662B5 I=118 PT=00000000000000000000000000000400 CT=F675D59BDB33231861268F539829DA0B I=119 PT=00000000000000000000000000000200 CT=A4967F45ABB4E8C7DC5E3806680F35E0 I=120 PT=00000000000000000000000000000100 CT=4D7E08081CC82F92ABA7C58C99F8343F I=121 PT=00000000000000000000000000000080 CT=9AEFDB287C119B82353612B60ECCBFD8 I=122 PT=00000000000000000000000000000040 CT=979BB6A1553A17592A86E78DF144A699 I=123 PT=00000000000000000000000000000020 CT=A6FA8CAB06FD2E5BF3A858983C01757A I=124 PT=00000000000000000000000000000010 CT=BE8511254C31E25420B91D6FEF1710ED I=125 PT=00000000000000000000000000000008 CT=F589A908D18A21894971C0433581E1A5 I=126 PT=00000000000000000000000000000004 CT=4237585130E7C9F715235EB1D8C94DE7 I=127 PT=00000000000000000000000000000002 CT=DEFE3E0B5C54C94B4F2A0F5A46F6210D I=128 PT=00000000000000000000000000000001 CT=F5574ACC3148DFCB9015200631024DF9 ========== KEYSIZE=256 KEY=0000000000000000000000000000000000000000000000000000000000000000 I=1 PT=80000000000000000000000000000000 CT=B0C6B88AEA518AB09E847248E91B1B9D I=2 PT=40000000000000000000000000000000 CT=B8D7684E35FA1DB15BDCEE7A48659858 I=3 PT=20000000000000000000000000000000 CT=F0CAD59AF92FBB79F36951E697492750 I=4 PT=10000000000000000000000000000000 CT=117100F6635389560DC4A2DA24EBA70F I=5 PT=08000000000000000000000000000000 CT=DBDD62355553019ED84C35886421E532 I=6 PT=04000000000000000000000000000000 CT=9CB8D04FA506F19848F7B9110518BFC8 I=7 PT=02000000000000000000000000000000 CT=E4308E253BC3444D293500701BA82C6A I=8 PT=01000000000000000000000000000000 CT=EA2FAE53F7F30C0170A20E95A068503E I=9 PT=00800000000000000000000000000000 CT=14B14839EA221880B2C64D1FE000B93D I=10 PT=00400000000000000000000000000000 CT=A5CFC075B342D5101AACC334E73058BB I=11 PT=00200000000000000000000000000000 CT=477EA56B2EBAD0F8AC5E1936866560FF I=12 PT=00100000000000000000000000000000 CT=107E8598418404196EC59F63E45B7F6D I=13 PT=00080000000000000000000000000000 CT=FF6A891E7C1C074A68FEC291928FDD8D I=14 PT=00040000000000000000000000000000 CT=F64C250A13F45D377ADB7545B2B157A9 I=15 PT=00020000000000000000000000000000 CT=FAD0F252086F11C830C65B63197CBC38 I=16 PT=00010000000000000000000000000000 CT=9DCB89B209441F02AD0D25C6AB826629 I=17 PT=00008000000000000000000000000000 CT=E62E4ED4E4F34EDC563710D960E09D4C I=18 PT=00004000000000000000000000000000 CT=98A1B926BA06895C3F2E84CCBACBC356 I=19 PT=00002000000000000000000000000000 CT=29BE0BE4DB7F4D196718AEA38F3B0BFD I=20 PT=00001000000000000000000000000000 CT=F670C4EBECBA0B43E71F6D752BFD4854 I=21 PT=00000800000000000000000000000000 CT=7D7666B4484CDB7E3605468E093A787C I=22 PT=00000400000000000000000000000000 CT=562D06B181C091DA6C43642AE99460C6 I=23 PT=00000200000000000000000000000000 CT=AB0EFB5975E6186B7D76BC9672453488 I=24 PT=00000100000000000000000000000000 CT=10C0756538E7BFF88D19AE2B1F7B859A I=25 PT=00000080000000000000000000000000 CT=AF7FCD5248F8C72F1695AA05DD1CADE0 I=26 PT=00000040000000000000000000000000 CT=9841E555655609A75D7BE20B8A90EF1E I=27 PT=00000020000000000000000000000000 CT=27F9546E6A1B7464780000561783569C I=28 PT=00000010000000000000000000000000 CT=8671D935D7A8354EECB7288803D42D7A I=29 PT=00000008000000000000000000000000 CT=0DA44F508DEBC6F044394624FCEB8EBE I=30 PT=00000004000000000000000000000000 CT=AB137369BE6D93FBB18006BDB236EC09 I=31 PT=00000002000000000000000000000000 CT=EB90C4E597A7E1779FFA260886E26F75 I=32 PT=00000001000000000000000000000000 CT=618CF3588D5C128EAF252616230E08F7 I=33 PT=00000000800000000000000000000000 CT=98DC4DB49D197AB9152D12B9DE2D73CA I=34 PT=00000000400000000000000000000000 CT=5BDDE24B15702A35E1F140C57D206443 I=35 PT=00000000200000000000000000000000 CT=CF755809882BED8BA2F9F1A4ED296A2B I=36 PT=00000000100000000000000000000000 CT=F1A8DBB999538AE89D16F92A7F4D1DF1 I=37 PT=00000000080000000000000000000000 CT=775222FDDAAECB81CF675C4E0B98179E I=38 PT=00000000040000000000000000000000 CT=12A648CADCD153C760A965826683119A I=39 PT=00000000020000000000000000000000 CT=0503FB10AB241E7CF45D8CDEEE474335 I=40 PT=00000000010000000000000000000000 CT=3D299C0070CBBD831B802690B8E7CA24 I=41 PT=00000000008000000000000000000000 CT=33105BD4D11D66753DC34D128BEFE3F4 I=42 PT=00000000004000000000000000000000 CT=5EFCE2B4B987C0F77D27B44836881682 I=43 PT=00000000002000000000000000000000 CT=7835449454128035D7F0EA99E327577B I=44 PT=00000000001000000000000000000000 CT=27BEDDA0601BE35122FB1D272D73AB3E I=45 PT=00000000000800000000000000000000 CT=54C3F99FF48E318CC515EDE75800C4B3 I=46 PT=00000000000400000000000000000000 CT=C627C329F8E48299F6FDB23B9DBEA0BB I=47 PT=00000000000200000000000000000000 CT=1B6578F9E23BD8C1845A02431C5F9AA3 I=48 PT=00000000000100000000000000000000 CT=6DB2FB8C0B9344D0547C0FF1292020C6 I=49 PT=00000000000080000000000000000000 CT=4FAD9B2C37C131493FBEF53581FA4F83 I=50 PT=00000000000040000000000000000000 CT=47502A01E93D2C87BD5584F6AFD3D99D I=51 PT=00000000000020000000000000000000 CT=056E1C6F651BFE50271B3B7A18E76D84 I=52 PT=00000000000010000000000000000000 CT=5632BAF6627B3D96AD4E06FA6A561F55 I=53 PT=00000000000008000000000000000000 CT=E29807CAACDFA2D41A7D9E91FA7FD8EB I=54 PT=00000000000004000000000000000000 CT=81DD44BB5D1822DEE605F9E6FF01D7B3 I=55 PT=00000000000002000000000000000000 CT=5C3649925E47D7FF96482A8FBD9666FD I=56 PT=00000000000001000000000000000000 CT=695415A836E66E737887845EC08A1ADB I=57 PT=00000000000000800000000000000000 CT=F5416BCE292D9E2CEA5D1CC70BBAEED1 I=58 PT=00000000000000400000000000000000 CT=7AEC4F1388FC29C47F7FED74ADDE8485 I=59 PT=00000000000000200000000000000000 CT=82A9F1A6CE08BC4876E649D8A8EA7EB6 I=60 PT=00000000000000100000000000000000 CT=B6296C88ADF1A792908B065EEB04BFC2 I=61 PT=00000000000000080000000000000000 CT=E766A39AECCA40BDBFBE6FF3FA292913 I=62 PT=00000000000000040000000000000000 CT=C6D081454EA00D83C23B5A62C84359E1 I=63 PT=00000000000000020000000000000000 CT=85D259A79CCA80484504D1603F7A8F53 I=64 PT=00000000000000010000000000000000 CT=D8291FA1C6DC250078824B2D0A20883F I=65 PT=00000000000000008000000000000000 CT=95387CB74C48FFBD1F8D64A6CC45E074 I=66 PT=00000000000000004000000000000000 CT=A17F975F538F56CDF629B516011DE837 I=67 PT=00000000000000002000000000000000 CT=B50B615A1654C6E1CB6AB33716C097FE I=68 PT=00000000000000001000000000000000 CT=7BBB2CBB874DF6C8B821DA7FB0F9011B I=69 PT=00000000000000000800000000000000 CT=E9EFE074D096A275E47CD2E6206DF6A1 I=70 PT=00000000000000000400000000000000 CT=88F2F8D5A836406AE8BBB98C65BBDA55 I=71 PT=00000000000000000200000000000000 CT=F64620D8D87585A3EF038B9AD58F5EA0 I=72 PT=00000000000000000100000000000000 CT=694438EC141C8ED5F2F898B4554A298F I=73 PT=00000000000000000080000000000000 CT=3E6226EC7726A1EE5F5FA9B18CCE8C44 I=74 PT=00000000000000000040000000000000 CT=8AB6949E79911647800B9E87362AB97A I=75 PT=00000000000000000020000000000000 CT=093C5CF24EDAF7F9F1C8A80DE4FF50A9 I=76 PT=00000000000000000010000000000000 CT=28A36E50061F19E240351ED0E378CBF4 I=77 PT=00000000000000000008000000000000 CT=B93BB36CB88BF26EA79198652AA51D3C I=78 PT=00000000000000000004000000000000 CT=DE4948083D044FAC9BCA6DA8CD67B8A6 I=79 PT=00000000000000000002000000000000 CT=6E778B5BDA6CA118117E47470D080D3C I=80 PT=00000000000000000001000000000000 CT=0A9107324DA32B4281D032A3487EF875 I=81 PT=00000000000000000000800000000000 CT=18ED5635312D71ABD123CCE779D4D68A I=82 PT=00000000000000000000400000000000 CT=2E3C63F95C4BC1F944BAB06DEDC9AA8E I=83 PT=00000000000000000000200000000000 CT=ACCC869EF07004C8C3C709083BE7BA2F I=84 PT=00000000000000000000100000000000 CT=DF60B34FB1A59147CC1FB049C1578206 I=85 PT=00000000000000000000080000000000 CT=4228DC636C08E41021054AA0E1E2227A I=86 PT=00000000000000000000040000000000 CT=7CE27F66EFD735FFD6B3E1738C50495B I=87 PT=00000000000000000000020000000000 CT=F8E74B33A9CDE351DA0BBC06D69093D7 I=88 PT=00000000000000000000010000000000 CT=AE0D22A5B37B8DC5D81CC641EED334D0 I=89 PT=00000000000000000000008000000000 CT=C181C6CA5E163743458B9167A0B6A16A I=90 PT=00000000000000000000004000000000 CT=5171F4F6095E4B276CFBA1F07223FBE6 I=91 PT=00000000000000000000002000000000 CT=2732F4D3A8C9D1D8D493840D6E0B864F I=92 PT=00000000000000000000001000000000 CT=3EF04E0059A061D973532CA5C1DFBE7B I=93 PT=00000000000000000000000800000000 CT=6D9A8F23579E4978EBAA87B5ADEB77E5 I=94 PT=00000000000000000000000400000000 CT=BBD08873CC44BA4253C0C41FEEB7F124 I=95 PT=00000000000000000000000200000000 CT=72E4B2437CBD283F3809CE686F6A591E I=96 PT=00000000000000000000000100000000 CT=6E5580514B92512B1BF4B1B987B9AA1B I=97 PT=00000000000000000000000080000000 CT=5EF5D0C5BCBDCB604D3A083B68CE0FA3 I=98 PT=00000000000000000000000040000000 CT=9D991FDD723AD2182777A15CA0E0F665 I=99 PT=00000000000000000000000020000000 CT=24440626EFC8F86BEA7DE78085AB8A22 I=100 PT=00000000000000000000000010000000 CT=17C3630D62D13C1E826C0FCCBD74A864 I=101 PT=00000000000000000000000008000000 CT=4CF5AB86A56AB134A7FE46CCE3F9FCE9 I=102 PT=00000000000000000000000004000000 CT=3E6B9C0388F6D9B8F458F30221907607 I=103 PT=00000000000000000000000002000000 CT=AD9C926B8A5CD98EEE88200617E59958 I=104 PT=00000000000000000000000001000000 CT=AFF8AED5E075E02AF720CA4BF0028B3B I=105 PT=00000000000000000000000000800000 CT=D90EAFF909202BB209BB3BB8C7F9A954 I=106 PT=00000000000000000000000000400000 CT=2C709B00E6A22F00F64A7D8EE341853F I=107 PT=00000000000000000000000000200000 CT=CCEC598F0D9F0BF201B2F487136D54A4 I=108 PT=00000000000000000000000000100000 CT=73B2883A0A166AAE1BF14E60A5195FA3 I=109 PT=00000000000000000000000000080000 CT=E676867BD9AD5EF915143388496779D7 I=110 PT=00000000000000000000000000040000 CT=CDCB73D1BFCFD4BE7F1DAA9B1C6A4055 I=111 PT=00000000000000000000000000020000 CT=02A3A5C89DAA24CD2C517F7A73286A89 I=112 PT=00000000000000000000000000010000 CT=C0FA2AC9E92EE58C2DD12D6D43AB7035 I=113 PT=00000000000000000000000000008000 CT=EDC2CB1F7291353BDBF2385519E6AE16 I=114 PT=00000000000000000000000000004000 CT=B4B62D16D197A98CD3B978812B9D9884 I=115 PT=00000000000000000000000000002000 CT=5CDFC95A529A905101CEA26BC1B891ED I=116 PT=00000000000000000000000000001000 CT=CC7150CD3650B98363296C7C4ED368D1 I=117 PT=00000000000000000000000000000800 CT=CC57706B0C6526B8E25A5DBD32EACBDB I=118 PT=00000000000000000000000000000400 CT=30D30456AD98B182D64C649648F6AEC9 I=119 PT=00000000000000000000000000000200 CT=D7E9DA7F631938EB649A08AF82FBD75F I=120 PT=00000000000000000000000000000100 CT=B8DA2AF6600B07895B5D0FFAF4991469 I=121 PT=00000000000000000000000000000080 CT=0F6F64F930BA6C178943322B98114599 I=122 PT=00000000000000000000000000000040 CT=8B1F247802E47C91BEE2AA34ECFD7A01 I=123 PT=00000000000000000000000000000020 CT=7A6985778D3A66E97F23E01F0D0E45E7 I=124 PT=00000000000000000000000000000010 CT=BA664AC39855518DFDEE10D1B3111FAE I=125 PT=00000000000000000000000000000008 CT=7C92854D801A1648F65CA81813DDBF83 I=126 PT=00000000000000000000000000000004 CT=6A3F25AAB7E92D9CF378E5D9C040F26B I=127 PT=00000000000000000000000000000002 CT=3D4B2CDE666761BA5DFB305178E667FB I=128 PT=00000000000000000000000000000001 CT=9CDB269B5D293BC5DB9C55B057D9B591 ========== krb5-1.22.1/src/lib/crypto/crypto_tests/t_str2key.c0000664000175000017500000004250215051422640022055 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_str2key.c - String-to-key test vectors */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" struct test { krb5_enctype enctype; char *string; krb5_data salt; krb5_data params; krb5_data expected_key; krb5_error_code expected_err; krb5_boolean allow_weak; } test_cases[] = { /* Test vectors from RFC 3961 appendix A.4. */ { ENCTYPE_DES3_CBC_SHA1, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 0, NULL }, { KV5M_DATA, 24, "\x85\x0B\xB5\x13\x58\x54\x8C\xD0\x5E\x86\x76\x8C" "\x31\x3E\x3B\xFE\xF7\x51\x19\x37\xDC\xF7\x2C\x3E" }, 0, FALSE }, { ENCTYPE_DES3_CBC_SHA1, "potatoe", { KV5M_DATA, 19, "WHITEHOUSE.GOVdanny" }, { KV5M_DATA, 0, NULL }, { KV5M_DATA, 24, "\xDF\xCD\x23\x3D\xD0\xA4\x32\x04\xEA\x6D\xC4\x37" "\xFB\x15\xE0\x61\xB0\x29\x79\xC1\xF7\x4F\x37\x7A" }, 0, FALSE }, { ENCTYPE_DES3_CBC_SHA1, "penny", { KV5M_DATA, 19, "EXAMPLE.COMbuckaroo" }, { KV5M_DATA, 0, NULL }, { KV5M_DATA, 24, "\x6D\x2F\xCD\xF2\xD6\xFB\xBC\x3D\xDC\xAD\xB5\xDA" "\x57\x10\xA2\x34\x89\xB0\xD3\xB6\x9D\x5D\x9D\x4A" }, 0, FALSE }, { ENCTYPE_DES3_CBC_SHA1, "\xC3\x9F", { KV5M_DATA, 23, "ATHENA.MIT.EDUJuri\xC5\xA1\x69\xC4\x87" }, { KV5M_DATA, 0, NULL }, { KV5M_DATA, 24, "\x16\xD5\xA4\x0E\x1C\xE3\xBA\xCB\x61\xB9\xDC\xE0" "\x04\x70\x32\x4C\x83\x19\x73\xA7\xB9\x52\xFE\xB0" }, 0, FALSE }, { ENCTYPE_DES3_CBC_SHA1, "\xF0\x9D\x84\x9E", { KV5M_DATA, 18, "EXAMPLE.COMpianist" }, { KV5M_DATA, 0, NULL }, { KV5M_DATA, 24, "\x85\x76\x37\x26\x58\x5D\xBC\x1C\xCE\x6E\xC4\x3E" "\x1F\x75\x1F\x07\xF1\xC4\xCB\xB0\x98\xF4\x0B\x19" }, 0, FALSE }, /* Test vectors from RFC 3962 appendix B. */ { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\0\1" }, { KV5M_DATA, 16, "\x42\x26\x3C\x6E\x89\xF4\xFC\x28\xB8\xDF\x68\xEE\x09\x79\x9F\x15" }, 0, TRUE }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\0\1" }, { KV5M_DATA, 32, "\xFE\x69\x7B\x52\xBC\x0D\x3C\xE1\x44\x32\xBA\x03\x6A\x92\xE6\x5B" "\xBB\x52\x28\x09\x90\xA2\xFA\x27\x88\x39\x98\xD7\x2A\xF3\x01\x61" }, 0, TRUE }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\0\2" }, { KV5M_DATA, 16, "\xC6\x51\xBF\x29\xE2\x30\x0A\xC2\x7F\xA4\x69\xD6\x93\xBD\xDA\x13" }, 0, TRUE }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\0\2" }, { KV5M_DATA, 32, "\xA2\xE1\x6D\x16\xB3\x60\x69\xC1\x35\xD5\xE9\xD2\xE2\x5F\x89\x61" "\x02\x68\x56\x18\xB9\x59\x14\xB4\x67\xC6\x76\x22\x22\x58\x24\xFF" }, 0, TRUE }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 16, "\x4C\x01\xCD\x46\xD6\x32\xD0\x1E\x6D\xBE\x23\x0A\x01\xED\x64\x2A" }, 0, TRUE }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 32, "\x55\xA6\xAC\x74\x0A\xD1\x7B\x48\x46\x94\x10\x51\xE1\xE8\xB0\xA7" "\x54\x8D\x93\xB0\xAB\x30\xA8\xBC\x3F\xF1\x62\x80\x38\x2B\x8C\x2A" }, 0, TRUE }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "password", { KV5M_DATA, 8, "\x12\x34\x56\x78\x78\x56\x34\x12" }, { KV5M_DATA, 4, "\0\0\0\5" }, { KV5M_DATA, 16, "\xE9\xB2\x3D\x52\x27\x37\x47\xDD\x5C\x35\xCB\x55\xBE\x61\x9D\x8E" }, 0, TRUE }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "password", { KV5M_DATA, 8, "\x12\x34\x56\x78\x78\x56\x34\x12" }, { KV5M_DATA, 4, "\0\0\0\5" }, { KV5M_DATA, 32, "\x97\xA4\xE7\x86\xBE\x20\xD8\x1A\x38\x2D\x5E\xBC\x96\xD5\x90\x9C" "\xAB\xCD\xAD\xC8\x7C\xA4\x8F\x57\x45\x04\x15\x9F\x16\xC3\x6E\x31" }, 0, TRUE }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", { KV5M_DATA, 29, "pass phrase equals block size" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 16, "\x59\xD1\xBB\x78\x9A\x82\x8B\x1A\xA5\x4E\xF9\xC2\x88\x3F\x69\xED" }, 0, TRUE }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", { KV5M_DATA, 29, "pass phrase equals block size" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 32, "\x89\xAD\xEE\x36\x08\xDB\x8B\xC7\x1F\x1B\xFB\xFE\x45\x94\x86\xB0" "\x56\x18\xB7\x0C\xBA\xE2\x20\x92\x53\x4E\x56\xC5\x53\xBA\x4B\x34" }, 0, TRUE }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", { KV5M_DATA, 30, "pass phrase exceeds block size" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 16, "\xCB\x80\x05\xDC\x5F\x90\x17\x9A\x7F\x02\x10\x4C\x00\x18\x75\x1D" }, 0, TRUE }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", { KV5M_DATA, 30, "pass phrase exceeds block size" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 32, "\xD7\x8C\x5C\x9C\xB8\x72\xA8\xC9\xDA\xD4\x69\x7F\x0B\xB5\xB2\xD2" "\x14\x96\xC8\x2B\xEB\x2C\xAE\xDA\x21\x12\xFC\xEE\xA0\x57\x40\x1B" }, 0, TRUE }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "\xF0\x9D\x84\x9E", { KV5M_DATA, 18, "EXAMPLE.COMpianist" }, { KV5M_DATA, 4, "\0\0\0\x32" }, /* 50 */ { KV5M_DATA, 16, "\xF1\x49\xC1\xF2\xE1\x54\xA7\x34\x52\xD4\x3E\x7F\xE6\x2A\x56\xE5" }, 0, TRUE }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "\xF0\x9D\x84\x9E", { KV5M_DATA, 18, "EXAMPLE.COMpianist" }, { KV5M_DATA, 4, "\0\0\0\x32" }, /* 50 */ { KV5M_DATA, 32, "\x4B\x6D\x98\x39\xF8\x44\x06\xDF\x1F\x09\xCC\x16\x6D\xB4\xB8\x3C" "\x57\x18\x48\xB7\x84\xA3\xD6\xBD\xC3\x46\x58\x9A\x3E\x39\x3F\x9E" }, 0, TRUE }, /* Check for KRB5_ERR_BAD_S2K_PARAMS return when weak iteration counts are * forbidden. */ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "\xF0\x9D\x84\x9E", { KV5M_DATA, 18, "EXAMPLE.COMpianist" }, { KV5M_DATA, 4, "\0\0\0\x32" }, /* 50 */ { KV5M_DATA, 32, "\x4B\x6D\x98\x39\xF8\x44\x06\xDF\x1F\x09\xCC\x16\x6D\xB4\xB8\x3C" "\x57\x18\x48\xB7\x84\xA3\xD6\xBD\xC3\x46\x58\x9A\x3E\x39\x3F\x9E" }, KRB5_ERR_BAD_S2K_PARAMS, FALSE }, /* The same inputs applied to Camellia enctypes. */ { ENCTYPE_CAMELLIA128_CTS_CMAC, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\0\1" }, { KV5M_DATA, 16, "\x57\xD0\x29\x72\x98\xFF\xD9\xD3\x5D\xE5\xA4\x7F\xB4\xBD\xE2\x4B" }, 0, TRUE }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\0\1" }, { KV5M_DATA, 32, "\xB9\xD6\x82\x8B\x20\x56\xB7\xBE\x65\x6D\x88\xA1\x23\xB1\xFA\xC6" "\x82\x14\xAC\x2B\x72\x7E\xCF\x5F\x69\xAF\xE0\xC4\xDF\x2A\x6D\x2C" }, 0, TRUE }, { ENCTYPE_CAMELLIA128_CTS_CMAC, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\0\2" }, { KV5M_DATA, 16, "\x73\xF1\xB5\x3A\xA0\xF3\x10\xF9\x3B\x1D\xE8\xCC\xAA\x0C\xB1\x52" }, 0, TRUE }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\0\2" }, { KV5M_DATA, 32, "\x83\xFC\x58\x66\xE5\xF8\xF4\xC6\xF3\x86\x63\xC6\x5C\x87\x54\x9F" "\x34\x2B\xC4\x7E\xD3\x94\xDC\x9D\x3C\xD4\xD1\x63\xAD\xE3\x75\xE3" }, 0, TRUE }, { ENCTYPE_CAMELLIA128_CTS_CMAC, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 16, "\x8E\x57\x11\x45\x45\x28\x55\x57\x5F\xD9\x16\xE7\xB0\x44\x87\xAA" }, 0, TRUE }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "password", { KV5M_DATA, 21, "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 32, "\x77\xF4\x21\xA6\xF2\x5E\x13\x83\x95\xE8\x37\xE5\xD8\x5D\x38\x5B" "\x4C\x1B\xFD\x77\x2E\x11\x2C\xD9\x20\x8C\xE7\x2A\x53\x0B\x15\xE6" }, 0, TRUE }, { ENCTYPE_CAMELLIA128_CTS_CMAC, "password", { KV5M_DATA, 8, "\x12\x34\x56\x78\x78\x56\x34\x12" }, { KV5M_DATA, 4, "\0\0\0\5" }, { KV5M_DATA, 16, "\x00\x49\x8F\xD9\x16\xBF\xC1\xC2\xB1\x03\x1C\x17\x08\x01\xB3\x81" }, 0, TRUE }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "password", { KV5M_DATA, 8, "\x12\x34\x56\x78\x78\x56\x34\x12" }, { KV5M_DATA, 4, "\0\0\0\5" }, { KV5M_DATA, 32, "\x11\x08\x3A\x00\xBD\xFE\x6A\x41\xB2\xF1\x97\x16\xD6\x20\x2F\x0A" "\xFA\x94\x28\x9A\xFE\x8B\x27\xA0\x49\xBD\x28\xB1\xD7\x6C\x38\x9A" }, 0, TRUE }, { ENCTYPE_CAMELLIA128_CTS_CMAC, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", { KV5M_DATA, 29, "pass phrase equals block size" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 16, "\x8B\xF6\xC3\xEF\x70\x9B\x98\x1D\xBB\x58\x5D\x08\x68\x43\xBE\x05" }, 0, TRUE }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", { KV5M_DATA, 29, "pass phrase equals block size" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 32, "\x11\x9F\xE2\xA1\xCB\x0B\x1B\xE0\x10\xB9\x06\x7A\x73\xDB\x63\xED" "\x46\x65\xB4\xE5\x3A\x98\xD1\x78\x03\x5D\xCF\xE8\x43\xA6\xB9\xB0" }, 0, TRUE }, { ENCTYPE_CAMELLIA128_CTS_CMAC, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", { KV5M_DATA, 30, "pass phrase exceeds block size" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 16, "\x57\x52\xAC\x8D\x6A\xD1\xCC\xFE\x84\x30\xB3\x12\x87\x1C\x2F\x74" }, 0, TRUE }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", { KV5M_DATA, 30, "pass phrase exceeds block size" }, { KV5M_DATA, 4, "\0\0\x04\xB0" }, /* 1200 */ { KV5M_DATA, 32, "\x61\x4D\x5D\xFC\x0B\xA6\xD3\x90\xB4\x12\xB8\x9A\xE4\xD5\xB0\x88" "\xB6\x12\xB3\x16\x51\x09\x94\x67\x9D\xDB\x43\x83\xC7\x12\x6D\xDF" }, 0, TRUE }, { ENCTYPE_CAMELLIA128_CTS_CMAC, "\xf0\x9d\x84\x9e", { KV5M_DATA, 18, "EXAMPLE.COMpianist" }, { KV5M_DATA, 4, "\0\0\0\x32" }, /* 50 */ { KV5M_DATA, 16, "\xCC\x75\xC7\xFD\x26\x0F\x1C\x16\x58\x01\x1F\xCC\x0D\x56\x06\x16" }, 0, TRUE }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "\xf0\x9d\x84\x9e", { KV5M_DATA, 18, "EXAMPLE.COMpianist" }, { KV5M_DATA, 4, "\0\0\0\x32" }, /* 50 */ { KV5M_DATA, 32, "\x16\x3B\x76\x8C\x6D\xB1\x48\xB4\xEE\xC7\x16\x3D\xF5\xAE\xD7\x0E" "\x20\x6B\x68\xCE\xC0\x78\xBC\x06\x9E\xD6\x8A\x7E\xD3\x6B\x1E\xCC" }, 0, TRUE }, /* Check for KRB5_ERR_BAD_S2K_PARAMS return when weak iteration counts are * forbidden. */ { ENCTYPE_CAMELLIA256_CTS_CMAC, "\xf0\x9d\x84\x9e", { KV5M_DATA, 18, "EXAMPLE.COMpianist" }, { KV5M_DATA, 4, "\0\0\0\x32" }, /* 50 */ { KV5M_DATA, 32, "\x16\x3B\x76\x8C\x6D\xB1\x48\xB4\xEE\xC7\x16\x3D\xF5\xAE\xD7\x0E" "\x20\x6B\x68\xCE\xC0\x78\xBC\x06\x9E\xD6\x8A\x7E\xD3\x6B\x1E\xCC" }, KRB5_ERR_BAD_S2K_PARAMS, FALSE }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, "password", { KV5M_DATA, 37, "\x10\xDF\x9D\xD7\x83\xE5\xBC\x8A\xCE\xA1\x73\x0E\x74\x35\x5F\x61" "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\x00\x00\x80\x00" }, { KV5M_DATA, 16, "\x08\x9B\xCA\x48\xB1\x05\xEA\x6E\xA7\x7C\xA5\xD2\xF3\x9D\xC5\xE7" }, 0, FALSE }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, "password", { KV5M_DATA, 37, "\x10\xDF\x9D\xD7\x83\xE5\xBC\x8A\xCE\xA1\x73\x0E\x74\x35\x5F\x61" "ATHENA.MIT.EDUraeburn" }, { KV5M_DATA, 4, "\x00\x00\x80\x00" }, { KV5M_DATA, 32, "\x45\xBD\x80\x6D\xBF\x6A\x83\x3A\x9C\xFF\xC1\xC9\x45\x89\xA2\x22" "\x36\x7A\x79\xBC\x21\xC4\x13\x71\x89\x06\xE9\xF5\x78\xA7\x84\x67" }, 0, FALSE }, }; static void printhex(const char *head, void *data, size_t len) { size_t i; printf("%s", head); for (i = 0; i < len; i++) { printf("%02X", ((unsigned char*)data)[i]); if (i % 16 == 15 && i + 1 < len) printf("\n%*s", (int)strlen(head), ""); else if (i + 1 < len) printf(" "); } printf("\n"); } extern int k5_allow_weak_pbkdf2iter; int main(int argc, char **argv) { krb5_context context = NULL; krb5_data string; krb5_error_code ret; krb5_keyblock *keyblock; size_t i; struct test *test; krb5_boolean verbose = FALSE; int status = 0; if (argc >= 2 && strcmp(argv[1], "-v") == 0) verbose = TRUE; for (i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) { test = &test_cases[i]; string = string2data(test->string); ret = krb5_init_keyblock(context, test->enctype, 0, &keyblock); assert(!ret); k5_allow_weak_pbkdf2iter = test->allow_weak; ret = krb5_c_string_to_key_with_params(context, test->enctype, &string, &test->salt, &test->params, keyblock); if (ret != test->expected_err) { com_err(argv[0], ret, "in krb5_c_string_to_key_with_params"); exit(1); } if (verbose) { char buf[64]; krb5_enctype_to_name(test->enctype, FALSE, buf, sizeof(buf)); printf("\nTest %d:\n", (int)i); printf("Enctype: %s\n", buf); printf("String: %s\n", test->string); printhex("Salt: ", test->salt.data, test->salt.length); printhex("Params: ", test->params.data, test->params.length); if (test->expected_err == 0) printhex("Key: ", keyblock->contents, keyblock->length); else printf("Expected error: %d\n", (int)test->expected_err); } if (test->expected_err != 0) { krb5_free_keyblock(context, keyblock); continue; } assert(keyblock->length == test->expected_key.length); if (memcmp(keyblock->contents, test->expected_key.data, keyblock->length) != 0) { printf("str2key test %d failed\n", (int)i); status = 1; if (!verbose) break; } krb5_free_keyblock(context, keyblock); } return status; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_sha2.c0000664000175000017500000001157715051422640021317 0ustar ghudsonghudson/* * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include "crypto_int.h" #define ONE_MILLION_A "one million a's" struct test { char *str; unsigned char hash[64]; }; struct test sha256_tests[] = { { "abc", { 0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea, 0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23, 0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c, 0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad }}, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8, 0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39, 0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67, 0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1 }}, { ONE_MILLION_A, { 0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92, 0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67, 0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e, 0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0 }}, { NULL } }; struct test sha384_tests[] = { { "abc", { 0xcb,0x00,0x75,0x3f,0x45,0xa3,0x5e,0x8b, 0xb5,0xa0,0x3d,0x69,0x9a,0xc6,0x50,0x07, 0x27,0x2c,0x32,0xab,0x0e,0xde,0xd1,0x63, 0x1a,0x8b,0x60,0x5a,0x43,0xff,0x5b,0xed, 0x80,0x86,0x07,0x2b,0xa1,0xe7,0xcc,0x23, 0x58,0xba,0xec,0xa1,0x34,0xc8,0x25,0xa7 }}, { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno" "ijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", { 0x09,0x33,0x0c,0x33,0xf7,0x11,0x47,0xe8, 0x3d,0x19,0x2f,0xc7,0x82,0xcd,0x1b,0x47, 0x53,0x11,0x1b,0x17,0x3b,0x3b,0x05,0xd2, 0x2f,0xa0,0x80,0x86,0xe3,0xb0,0xf7,0x12, 0xfc,0xc7,0xc7,0x1a,0x55,0x7e,0x2d,0xb9, 0x66,0xc3,0xe9,0xfa,0x91,0x74,0x60,0x39 }}, { ONE_MILLION_A, { 0x9d,0x0e,0x18,0x09,0x71,0x64,0x74,0xcb, 0x08,0x6e,0x83,0x4e,0x31,0x0a,0x4a,0x1c, 0xed,0x14,0x9e,0x9c,0x00,0xf2,0x48,0x52, 0x79,0x72,0xce,0xc5,0x70,0x4c,0x2a,0x5b, 0x07,0xb8,0xb3,0xdc,0x38,0xec,0xc4,0xeb, 0xae,0x97,0xdd,0xd8,0x7f,0x3d,0x89,0x85 }}, { NULL } }; static int hash_test(const struct krb5_hash_provider *hash, struct test *tests) { struct test *t; krb5_crypto_iov iov, *iovs; krb5_data hval; size_t i; if (alloc_data(&hval, hash->hashsize)) abort(); for (t = tests; t->str; ++t) { if (strcmp(t->str, ONE_MILLION_A) == 0) { /* Hash a million 'a's using a thousand iovs. */ iovs = calloc(1000, sizeof(*iovs)); assert(iovs != NULL); for (i = 0; i < 1000; i++) { iovs[i].flags = KRB5_CRYPTO_TYPE_DATA; if (alloc_data(&iovs[i].data, 1000) != 0) abort(); memset(iovs[i].data.data, 'a', 1000); } if (hash->hash(iovs, 1000, &hval) != 0) abort(); if (memcmp(hval.data, t->hash, hval.length) != 0) abort(); for (i = 0; i < 1000; i++) free(iovs[i].data.data); free(iovs); } else { /* Hash the input in the test. */ iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = string2data(t->str); if (hash->hash(&iov, 1, &hval) != 0) abort(); if (memcmp(hval.data, t->hash, hval.length) != 0) abort(); if (hash == &krb5int_hash_sha256) { /* Try again using k5_sha256(). */ if (k5_sha256(&iov.data, 1, (uint8_t *)hval.data) != 0) abort(); if (memcmp(hval.data, t->hash, hval.length) != 0) abort(); } } } free(hval.data); return 0; } int main(void) { hash_test(&krb5int_hash_sha256, sha256_tests); hash_test(&krb5int_hash_sha384, sha384_tests); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_hmac.c0000664000175000017500000002110715051422640021360 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_hmac.c */ /* * Copyright 2001,2002 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Test vectors for HMAC-MD5 and HMAC-SHA1 (placeholder only). * Tests taken from RFC 2202. */ #include #include #include #include #include #include "crypto_int.h" #define ASIZE(ARRAY) (sizeof(ARRAY)/sizeof(ARRAY[0])) const char *whoami; static void keyToData (krb5_keyblock *k, krb5_data *d) { d->length = k->length; d->data = (char *) k->contents; } static void printd (const char *descr, krb5_data *d) { unsigned int i, j; const int r = 16; printf("%s (%d bytes):", descr, d->length); for (i = 0; i < d->length; i += r) { printf("\n %04x: ", i); for (j = i; j < i + r && j < d->length; j++) printf(" %02x", 0xff & d->data[j]); for (; j < i + r; j++) printf(" "); printf(" "); for (j = i; j < i + r && j < d->length; j++) { int c = 0xff & d->data[j]; printf("%c", isprint(c) ? c : '.'); } } printf("\n"); } static void printk(const char *descr, krb5_keyblock *k) { krb5_data d; keyToData(k,&d); printd(descr, &d); } struct hmac_test { int key_len; unsigned char key[180]; int data_len; unsigned char data[80]; const char *hexdigest; }; static krb5_error_code hmac1(const struct krb5_hash_provider *h, krb5_keyblock *key, krb5_data *in, krb5_data *out) { char tmp[40]; size_t blocksize, hashsize; krb5_error_code err; krb5_key k; krb5_crypto_iov iov; krb5_data d; printk(" test key", key); blocksize = h->blocksize; hashsize = h->hashsize; if (hashsize > sizeof(tmp)) abort(); if (key->length > blocksize) { iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(key->contents, key->length); d = make_data(tmp, hashsize); err = h->hash(&iov, 1, &d); if (err) { com_err(whoami, err, "hashing key before calling hmac"); exit(1); } key->length = d.length; key->contents = (krb5_octet *) d.data; printk(" pre-hashed key", key); } printd(" hmac input", in); krb5_k_create_key(NULL, key, &k); iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *in; err = krb5int_hmac(h, k, &iov, 1, out); krb5_k_free_key(NULL, k); if (err == 0) printd(" hmac output", out); return err; } static void test_hmac(void) { krb5_keyblock key; krb5_data in, out; char outbuf[20], *hexdigest; krb5_error_code err; unsigned int i; int lose = 0; /* RFC 2202 test vector. */ static const struct hmac_test md5tests[] = { { 16, { 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, }, 8, "Hi There", "9294727a3638bb1c13f48ef8158bfc9d" }, { 4, "Jefe", 28, "what do ya want for nothing?", "750c783e6ab0b503eaa86e310a5db738" }, { 16, { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, 50, { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, }, "56be34521d144c88dbb8c733f0e8b3f6" }, { 25, { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 }, 50, { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, }, "697eaf0aca3a3aea3a75164746ffaa79" }, { 16, { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, 20, "Test With Truncation", "56461ef2342edc00f9bab995690efd4c" }, { 80, { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, }, 54, "Test Using Larger Than Block-Size Key - Hash Key First", "6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd" }, { 80, { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, }, 73, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", "6f630fad67cda0ee1fb1f562db3aa53e" }, }; for (i = 0; i < sizeof(md5tests)/sizeof(md5tests[0]); i++) { key.contents = (krb5_octet *)md5tests[i].key; key.length = md5tests[i].key_len; in = make_data((char *)md5tests[i].data, md5tests[i].data_len); out.data = outbuf; out.length = 20; printf("\nTest #%d:\n", i+1); err = hmac1(&krb5int_hash_md5, &key, &in, &out); if (err) { com_err(whoami, err, "computing hmac"); exit(1); } if (k5_hex_encode(out.data, out.length, FALSE, &hexdigest) != 0) abort(); if (strcmp(hexdigest, md5tests[i].hexdigest)) { printf("*** CHECK FAILED!\n" "\tReturned: 0x%s.\n" "\tExpected: 0x%s.\n", hexdigest, md5tests[i].hexdigest); lose++; } else printf("Matches expected result.\n"); free(hexdigest); } /* Do again with SHA-1 tests.... */ if (lose) { printf("%d failures; exiting.\n", lose); exit(1); } } int main (int argc, char **argv) { whoami = argv[0]; test_hmac(); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_pkcs5.c0000664000175000017500000000644515051422640021505 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_pkcs5.c */ /* * Copyright 2002 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* Test vectors for PBKDF2 (from PKCS #5v2), based on RFC 3211. */ #include "k5-int.h" static void printhex (size_t len, const char *p) { while (len--) printf (" %02X", 0xff & *p++); } static void printdata (krb5_data *d) { printhex (d->length, d->data); } static void test_pbkdf2_rfc3211(void) { char x[100]; krb5_error_code err; krb5_data d, pass, salt; int i; /* RFC 3211 test cases. */ static const struct { const char *pass; const char *salt; unsigned int count; size_t len; const unsigned char expected[24]; } t[] = { { "password", "\x12\x34\x56\x78\x78\x56\x34\x12", 5, 8, { 0xD1, 0xDA, 0xA7, 0x86, 0x15, 0xF2, 0x87, 0xE6 } }, { "All n-entities must communicate with other " "n-entities via n-1 entiteeheehees", "\x12\x34\x56\x78\x78\x56\x34\x12", 500, 24, { 0x6A, 0x89, 0x70, 0xBF, 0x68, 0xC9, 0x2C, 0xAE, 0xA8, 0x4A, 0x8D, 0xF2, 0x85, 0x10, 0x85, 0x86, 0x07, 0x12, 0x63, 0x80, 0xCC, 0x47, 0xAB, 0x2D } }, }; d.data = x; printf("RFC 3211 test of PBKDF#2\n"); for (i = 0; i < sizeof(t)/sizeof(t[0]); i++) { printf("pkbdf2(iter_count=%d, dklen=%d (%d bytes), salt=12 34 56 78 78 56 34 12,\n" " pass=%s):\n ->", t[i].count, t[i].len * 8, t[i].len, t[i].pass); d.length = t[i].len; pass.data = t[i].pass; pass.length = strlen(pass.data); salt.data = t[i].salt; salt.length = strlen(salt.data); err = krb5int_pbkdf2_hmac_sha1 (&d, t[i].count, &pass, &salt); if (err) { printf("error in computing pbkdf2: %s\n", error_message(err)); exit(1); } printdata(&d); if (!memcmp(x, t[i].expected, t[i].len)) printf("\nTest passed.\n\n"); else { printf("\n*** CHECK FAILED!\n"); exit(1); } } } int main(void) { test_pbkdf2_rfc3211(); return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/expect-vk.txt0000664000175000017500000011364415051422640022440 0ustar ghudsonghudson KEYSIZE=128 PT=00000000000000000000000000000000 I=1 KEY=80000000000000000000000000000000 CT=0EDD33D3C621E546455BD8BA1418BEC8 I=2 KEY=40000000000000000000000000000000 CT=C0CC0C5DA5BD63ACD44A80774FAD5222 I=3 KEY=20000000000000000000000000000000 CT=2F0B4B71BC77851B9CA56D42EB8FF080 I=4 KEY=10000000000000000000000000000000 CT=6B1E2FFFE8A114009D8FE22F6DB5F876 I=5 KEY=08000000000000000000000000000000 CT=9AA042C315F94CBB97B62202F83358F5 I=6 KEY=04000000000000000000000000000000 CT=DBE01DE67E346A800C4C4B4880311DE4 I=7 KEY=02000000000000000000000000000000 CT=C117D2238D53836ACD92DDCDB85D6A21 I=8 KEY=01000000000000000000000000000000 CT=DC0ED85DF9611ABB7249CDD168C5467E I=9 KEY=00800000000000000000000000000000 CT=807D678FFF1F56FA92DE3381904842F2 I=10 KEY=00400000000000000000000000000000 CT=0E53B3FCAD8E4B130EF73AEB957FB402 I=11 KEY=00200000000000000000000000000000 CT=969FFD3B7C35439417E7BDE923035D65 I=12 KEY=00100000000000000000000000000000 CT=A99B512C19CA56070491166A1503BF15 I=13 KEY=00080000000000000000000000000000 CT=6E9985252126EE344D26AE369D2327E3 I=14 KEY=00040000000000000000000000000000 CT=B85F4809F904C275491FCDCD1610387E I=15 KEY=00020000000000000000000000000000 CT=ED365B8D7D20C1F5D53FB94DD211DF7B I=16 KEY=00010000000000000000000000000000 CT=B3A575E86A8DB4A7135D604C43304896 I=17 KEY=00008000000000000000000000000000 CT=89704BCB8E69F846259EB0ACCBC7F8A2 I=18 KEY=00004000000000000000000000000000 CT=C56EE7C92197861F10D7A92B90882055 I=19 KEY=00002000000000000000000000000000 CT=92F296F6846E0EAF9422A5A24A08B069 I=20 KEY=00001000000000000000000000000000 CT=E67E32BB8F11DEB8699318BEE9E91A60 I=21 KEY=00000800000000000000000000000000 CT=B08EEF85EAF626DD91B65C4C3A97D92B I=22 KEY=00000400000000000000000000000000 CT=661083A6ADDCE79BB4E0859AB5538013 I=23 KEY=00000200000000000000000000000000 CT=55DFE2941E0EB10AFC0B333BD34DE1FE I=24 KEY=00000100000000000000000000000000 CT=6BFE5945E715C9662609770F8846087A I=25 KEY=00000080000000000000000000000000 CT=79848E9C30C2F8CDA8B325F7FED2B139 I=26 KEY=00000040000000000000000000000000 CT=7A713A53B99FEF34AC04DEEF80965BD0 I=27 KEY=00000020000000000000000000000000 CT=18144A2B46620D32C3C32CE52D49257F I=28 KEY=00000010000000000000000000000000 CT=872E827C70887C80749F7B8BB1847C7E I=29 KEY=00000008000000000000000000000000 CT=6B86C6A4FE6A60C59B1A3102F8DE49F3 I=30 KEY=00000004000000000000000000000000 CT=9848BB3DFDF6F532F094679A4C231A20 I=31 KEY=00000002000000000000000000000000 CT=925AD528E852E329B2091CD3F1C2BCEE I=32 KEY=00000001000000000000000000000000 CT=80DF436544B0DD596722E46792A40CD8 I=33 KEY=00000000800000000000000000000000 CT=525DAF18F93E83E1E74BBBDDE4263BBA I=34 KEY=00000000400000000000000000000000 CT=F65C9D2EE485D24701FFA3313B9D5BE6 I=35 KEY=00000000200000000000000000000000 CT=E4FC8D8BCA06425BDF94AFA40FCC14BA I=36 KEY=00000000100000000000000000000000 CT=A53F0A5CA1E4E6440BB975FF320DE6F8 I=37 KEY=00000000080000000000000000000000 CT=D55313B9394080462E87E02899B553F0 I=38 KEY=00000000040000000000000000000000 CT=34A71D761F71BCD344384C7F97D27906 I=39 KEY=00000000020000000000000000000000 CT=233F3D819599612EBC89580245C996A8 I=40 KEY=00000000010000000000000000000000 CT=B4F1374E5268DBCB676E447529E53F89 I=41 KEY=00000000008000000000000000000000 CT=0816BD27861D2BA891D1044E39951E96 I=42 KEY=00000000004000000000000000000000 CT=F3BE9EA3F10C73CA64FDE5DB13A951D1 I=43 KEY=00000000002000000000000000000000 CT=2448086A8106FBD03048DDF857D3F1C8 I=44 KEY=00000000001000000000000000000000 CT=670756E65BEC8B68F03D77CDCDCE7B91 I=45 KEY=00000000000800000000000000000000 CT=EF968CF0D36FD6C6EFFD225F6FB44CA9 I=46 KEY=00000000000400000000000000000000 CT=2E8767157922E3826DDCEC1B0CC1E105 I=47 KEY=00000000000200000000000000000000 CT=78CE7EEC670E45A967BAB17E26A1AD36 I=48 KEY=00000000000100000000000000000000 CT=3C5CEE825655F098F6E81A2F417DA3FB I=49 KEY=00000000000080000000000000000000 CT=67BFDB431DCE1292200BC6F5207ADB12 I=50 KEY=00000000000040000000000000000000 CT=7540FD38E447C0779228548747843A6F I=51 KEY=00000000000020000000000000000000 CT=B85E513301F8A936EA9EC8A21A85B5E6 I=52 KEY=00000000000010000000000000000000 CT=04C67DBF16C11427D507A455DE2C9BC5 I=53 KEY=00000000000008000000000000000000 CT=03F75EB8959E55079CFFB4FF149A37B6 I=54 KEY=00000000000004000000000000000000 CT=74550287F666C63BB9BC7838433434B0 I=55 KEY=00000000000002000000000000000000 CT=7D537200195EBC3AEFD1EAAB1C385221 I=56 KEY=00000000000001000000000000000000 CT=CE24E4D40C68A82B535CBD3C8E21652A I=57 KEY=00000000000000800000000000000000 CT=AB20072405AA8FC40265C6F1F3DC8BC0 I=58 KEY=00000000000000400000000000000000 CT=6CFD2CF688F566B093F67B9B3839E80A I=59 KEY=00000000000000200000000000000000 CT=BD95977E6B7239D407A012C5544BF584 I=60 KEY=00000000000000100000000000000000 CT=DF9C0130AC77E7C72C997F587B46DBE0 I=61 KEY=00000000000000080000000000000000 CT=E7F1B82CADC53A648798945B34EFEFF2 I=62 KEY=00000000000000040000000000000000 CT=932C6DBF69255CF13EDCDB72233ACEA3 I=63 KEY=00000000000000020000000000000000 CT=5C76002BC7206560EFE550C80B8F12CC I=64 KEY=00000000000000010000000000000000 CT=F6B7BDD1CAEEBAB574683893C4475484 I=65 KEY=00000000000000008000000000000000 CT=A920E37CC6DC6B31DA8C0169569F5034 I=66 KEY=00000000000000004000000000000000 CT=919380ECD9C778BC513148B0C28D65FD I=67 KEY=00000000000000002000000000000000 CT=EE67308DD3F2D9E6C2170755E5784BE1 I=68 KEY=00000000000000001000000000000000 CT=3CC73E53B85609023A05E149B223AE09 I=69 KEY=00000000000000000800000000000000 CT=983E8AF7CF05EBB28D71EB841C9406E6 I=70 KEY=00000000000000000400000000000000 CT=0F3099B2D31FA5299EE5BF43193287FC I=71 KEY=00000000000000000200000000000000 CT=B763D84F38C27FE6931DCEB6715D4DB6 I=72 KEY=00000000000000000100000000000000 CT=5AE3C9B0E3CC29C0C61565CD01F8A248 I=73 KEY=00000000000000000080000000000000 CT=F58083572CD90981958565D48D2DEE25 I=74 KEY=00000000000000000040000000000000 CT=7E6255EEF8F70C0EF10337AAB1CCCEF8 I=75 KEY=00000000000000000020000000000000 CT=AAD4BAC34DB22821841CE2F631961902 I=76 KEY=00000000000000000010000000000000 CT=D7431C0409BB1441BA9C6858DC7D4E81 I=77 KEY=00000000000000000008000000000000 CT=EF9298C65E339F6E801A59C626456993 I=78 KEY=00000000000000000004000000000000 CT=53FE29F68FF541ABC3F0EF3350B72F7E I=79 KEY=00000000000000000002000000000000 CT=F6BBA5C10DB02529E2C2DA3FB582CC14 I=80 KEY=00000000000000000001000000000000 CT=E4239AA37FC531A386DAD1126FC0E9CD I=81 KEY=00000000000000000000800000000000 CT=8F7758F857D15BBE7BFD0E416404C365 I=82 KEY=00000000000000000000400000000000 CT=D273EB57C687BCD1B4EA7218A509E7B8 I=83 KEY=00000000000000000000200000000000 CT=65D64F8D76E8B3423FA25C4EB58A210A I=84 KEY=00000000000000000000100000000000 CT=623D802B4EC450D66A16625702FCDBE0 I=85 KEY=00000000000000000000080000000000 CT=7496460CB28E5791BAEAF9B68FB00022 I=86 KEY=00000000000000000000040000000000 CT=34EA600F18BB0694B41681A49D510C1D I=87 KEY=00000000000000000000020000000000 CT=5F8FF0D47D5766D29B5D6E8F46423BD8 I=88 KEY=00000000000000000000010000000000 CT=225F9286C5928BF09F84D3F93F541959 I=89 KEY=00000000000000000000008000000000 CT=B21E90D25DF383416A5F072CEBEB1FFB I=90 KEY=00000000000000000000004000000000 CT=4AEFCDA089318125453EB9E8EB5E492E I=91 KEY=00000000000000000000002000000000 CT=4D3E75C6CD40EC4869BC85158591ADB8 I=92 KEY=00000000000000000000001000000000 CT=63A8B904405436A1B99D7751866771B7 I=93 KEY=00000000000000000000000800000000 CT=64F0DAAE47529199792EAE172BA53293 I=94 KEY=00000000000000000000000400000000 CT=C3EEF84BEA18225D515A8C852A9047EE I=95 KEY=00000000000000000000000200000000 CT=A44AC422B47D47B81AF73B3E9AC9596E I=96 KEY=00000000000000000000000100000000 CT=D16E04A8FBC435094F8D53ADF25F5084 I=97 KEY=00000000000000000000000080000000 CT=EF13DC34BAB03E124EEAD8B6BF44B532 I=98 KEY=00000000000000000000000040000000 CT=D94799075C24DCC067AF0D392049250D I=99 KEY=00000000000000000000000020000000 CT=14F431771EDDCE4764C21A2254B5E3C8 I=100 KEY=00000000000000000000000010000000 CT=7039329F36F2ED682B02991F28D64679 I=101 KEY=00000000000000000000000008000000 CT=124EE24EDE5551639DB8B8B941F6141D I=102 KEY=00000000000000000000000004000000 CT=C2852879A34D5184E478EC918B993FEE I=103 KEY=00000000000000000000000002000000 CT=86A806A3525B93E432053C9AB5ABBEDF I=104 KEY=00000000000000000000000001000000 CT=C1609BF5A4F07E37C17A36366EC23ECC I=105 KEY=00000000000000000000000000800000 CT=7E81E7CB92159A51FFCEA331B1E8EA53 I=106 KEY=00000000000000000000000000400000 CT=37A7BE002856C5A59A6E03EAFCE7729A I=107 KEY=00000000000000000000000000200000 CT=BDF98A5A4F91E890C9A1D1E5FAAB138F I=108 KEY=00000000000000000000000000100000 CT=4E96ACB66E051F2BC739CC3D3E34A26B I=109 KEY=00000000000000000000000000080000 CT=EE996CDD120EB86E21ECFA49E8E1FCF1 I=110 KEY=00000000000000000000000000040000 CT=61B9E6B579DBF6070C351A1440DD85FF I=111 KEY=00000000000000000000000000020000 CT=AC369E484316440B40DFC83AA96E28E7 I=112 KEY=00000000000000000000000000010000 CT=0A2D16DE985C76D45C579C1159413BBE I=113 KEY=00000000000000000000000000008000 CT=DA3FDC38DA1D374FA4802CDA1A1C6B0F I=114 KEY=00000000000000000000000000004000 CT=B842523D4C41C2211AFE43A5800ADCE3 I=115 KEY=00000000000000000000000000002000 CT=9E2CDA90D8E992DBA6C73D8229567192 I=116 KEY=00000000000000000000000000001000 CT=D49583B781D9E20F5BE101415957FC49 I=117 KEY=00000000000000000000000000000800 CT=EF09DA5C12B376E458B9B8670032498E I=118 KEY=00000000000000000000000000000400 CT=A96BE0463DA774461A5E1D5A9DD1AC10 I=119 KEY=00000000000000000000000000000200 CT=32CEE3341060790D2D4B1362EF397090 I=120 KEY=00000000000000000000000000000100 CT=21CEA416A3D3359D2C4D58FB6A035F06 I=121 KEY=00000000000000000000000000000080 CT=172AEAB3D507678ECAF455C12587ADB7 I=122 KEY=00000000000000000000000000000040 CT=B6F897941EF8EBFF9FE80A567EF38478 I=123 KEY=00000000000000000000000000000020 CT=A9723259D94A7DC662FB0C782CA3F1DD I=124 KEY=00000000000000000000000000000010 CT=2F91C984B9A4839F30001B9F430493B4 I=125 KEY=00000000000000000000000000000008 CT=0472406345A610B048CB99EE0EF3FA0F I=126 KEY=00000000000000000000000000000004 CT=F5F39086646F8C05ED16EFA4B617957C I=127 KEY=00000000000000000000000000000002 CT=26D50F485A30408D5AF47A5736292450 I=128 KEY=00000000000000000000000000000001 CT=0545AAD56DA2A97C3663D1432A3D1C84 ========== KEYSIZE=256 PT=00000000000000000000000000000000 I=1 KEY=8000000000000000000000000000000000000000000000000000000000000000 CT=E35A6DCB19B201A01EBCFA8AA22B5759 I=2 KEY=4000000000000000000000000000000000000000000000000000000000000000 CT=5075C2405B76F22F553488CAE47CE90B I=3 KEY=2000000000000000000000000000000000000000000000000000000000000000 CT=49DF95D844A0145A7DE01C91793302D3 I=4 KEY=1000000000000000000000000000000000000000000000000000000000000000 CT=E7396D778E940B8418A86120E5F421FE I=5 KEY=0800000000000000000000000000000000000000000000000000000000000000 CT=05F535C36FCEDE4657BE37F4087DB1EF I=6 KEY=0400000000000000000000000000000000000000000000000000000000000000 CT=D0C1DDDD10DA777C68AB36AF51F2C204 I=7 KEY=0200000000000000000000000000000000000000000000000000000000000000 CT=1C55FB811B5C6464C4E5DE1535A75514 I=8 KEY=0100000000000000000000000000000000000000000000000000000000000000 CT=52917F3AE957D5230D3A2AF57C7B5A71 I=9 KEY=0080000000000000000000000000000000000000000000000000000000000000 CT=C6E3D5501752DD5E9AEF086D6B45D705 I=10 KEY=0040000000000000000000000000000000000000000000000000000000000000 CT=A24A9C7AF1D9B1E17E1C9A3E711B3FA7 I=11 KEY=0020000000000000000000000000000000000000000000000000000000000000 CT=B881ECA724A6D43DBC6B96F6F59A0D20 I=12 KEY=0010000000000000000000000000000000000000000000000000000000000000 CT=EC524D9A24DFFF2A9639879B83B8E137 I=13 KEY=0008000000000000000000000000000000000000000000000000000000000000 CT=34C4F345F5466215A037F443635D6F75 I=14 KEY=0004000000000000000000000000000000000000000000000000000000000000 CT=5BA5055BEDB8895F672E29F2EB5A355D I=15 KEY=0002000000000000000000000000000000000000000000000000000000000000 CT=B3F692AA3A435259EBBEF9B51AD1E08D I=16 KEY=0001000000000000000000000000000000000000000000000000000000000000 CT=414FEB4376F2C64A5D2FBB2ED531BA7D I=17 KEY=0000800000000000000000000000000000000000000000000000000000000000 CT=A20D519E3BCA3303F07E81719F61605E I=18 KEY=0000400000000000000000000000000000000000000000000000000000000000 CT=A08D10E520AF811F45BD60A2DC0DC4B1 I=19 KEY=0000200000000000000000000000000000000000000000000000000000000000 CT=B06893A8C563C430E6F3858826EFBBE4 I=20 KEY=0000100000000000000000000000000000000000000000000000000000000000 CT=0FFEE26AE2D3929C6BD9C6BEDFF84409 I=21 KEY=0000080000000000000000000000000000000000000000000000000000000000 CT=4D0F5E906ED77801FC0EF53EDC5F9E2B I=22 KEY=0000040000000000000000000000000000000000000000000000000000000000 CT=8B6EC00119AD8B026DCE56EA7DEFE930 I=23 KEY=0000020000000000000000000000000000000000000000000000000000000000 CT=69026591D43363EE9D83B5007F0B484E I=24 KEY=0000010000000000000000000000000000000000000000000000000000000000 CT=27135D86950C6A2F86872706279A4761 I=25 KEY=0000008000000000000000000000000000000000000000000000000000000000 CT=35E6DB8723F281DA410C3AC8535ED77C I=26 KEY=0000004000000000000000000000000000000000000000000000000000000000 CT=57427CF214B8C28E4BBF487CCB8D0E09 I=27 KEY=0000002000000000000000000000000000000000000000000000000000000000 CT=6DF01BF56E5131AC87F96E99CAB86367 I=28 KEY=0000001000000000000000000000000000000000000000000000000000000000 CT=3856C5B55790B768BBF7D43031579BCF I=29 KEY=0000000800000000000000000000000000000000000000000000000000000000 CT=1E6ED8FB7C15BC4D2F63BA7037ED44D0 I=30 KEY=0000000400000000000000000000000000000000000000000000000000000000 CT=E1B2ED6CD8D93D455534E401156D4BCF I=31 KEY=0000000200000000000000000000000000000000000000000000000000000000 CT=EFBCCA5BDFDAD10E875F02336212CE36 I=32 KEY=0000000100000000000000000000000000000000000000000000000000000000 CT=0B777F02FD18DCE2646DCFE868DFAFAD I=33 KEY=0000000080000000000000000000000000000000000000000000000000000000 CT=C8A104B5693D1B14F5BF1F10100BF508 I=34 KEY=0000000040000000000000000000000000000000000000000000000000000000 CT=4CCE6615244AFCB38408FECE219962EA I=35 KEY=0000000020000000000000000000000000000000000000000000000000000000 CT=F99E7845D3A255B394C9C050CBA258B1 I=36 KEY=0000000010000000000000000000000000000000000000000000000000000000 CT=B4AFBB787F9BCFB7B55FDF447F611295 I=37 KEY=0000000008000000000000000000000000000000000000000000000000000000 CT=AE1C426A697FAF2808B7EF6ADDB5C020 I=38 KEY=0000000004000000000000000000000000000000000000000000000000000000 CT=7572F92811A85B9BDD38DEAD9945BCAE I=39 KEY=0000000002000000000000000000000000000000000000000000000000000000 CT=71BC7AA46E43FB95A181527D9F6A360F I=40 KEY=0000000001000000000000000000000000000000000000000000000000000000 CT=5542EF2923066F1EC8F546DD0D8E7CA8 I=41 KEY=0000000000800000000000000000000000000000000000000000000000000000 CT=6B92317C7D623790B748FDD7EFC42422 I=42 KEY=0000000000400000000000000000000000000000000000000000000000000000 CT=0FE7C097E899C71EF045360F8D6C25CF I=43 KEY=0000000000200000000000000000000000000000000000000000000000000000 CT=4ECE7EE107D0264D04693151C25B9DF6 I=44 KEY=0000000000100000000000000000000000000000000000000000000000000000 CT=FD6AE687CBFCA9E301045888D3BB9605 I=45 KEY=0000000000080000000000000000000000000000000000000000000000000000 CT=476B579C8556C7254424902CC1D6D36E I=46 KEY=0000000000040000000000000000000000000000000000000000000000000000 CT=4133CBCDFDD6B8860A1FC18665D6D71B I=47 KEY=0000000000020000000000000000000000000000000000000000000000000000 CT=3B36EC2664798C108B816812C65DFDC7 I=48 KEY=0000000000010000000000000000000000000000000000000000000000000000 CT=364E20A234FEA385D48DC5A09C9E70CF I=49 KEY=0000000000008000000000000000000000000000000000000000000000000000 CT=4A4BA25969DE3F5EE5642C71AAD0EFD1 I=50 KEY=0000000000004000000000000000000000000000000000000000000000000000 CT=E42CBAAE43297F67A76C1C501BB79E36 I=51 KEY=0000000000002000000000000000000000000000000000000000000000000000 CT=23CEDEDA4C15B4C037E8C61492217937 I=52 KEY=0000000000001000000000000000000000000000000000000000000000000000 CT=A1719147A1F4A1A1180BD16E8593DCDE I=53 KEY=0000000000000800000000000000000000000000000000000000000000000000 CT=AB82337E9FB0EC60D1F25A1D0014192C I=54 KEY=0000000000000400000000000000000000000000000000000000000000000000 CT=74BF2D8FC5A8388DF1A3A4D7D33FC164 I=55 KEY=0000000000000200000000000000000000000000000000000000000000000000 CT=D5B493317E6FBC6FFFD664B3C491368A I=56 KEY=0000000000000100000000000000000000000000000000000000000000000000 CT=BA767381586DA56A2A8D503D5F7ADA0B I=57 KEY=0000000000000080000000000000000000000000000000000000000000000000 CT=E8E6BC57DFE9CCADB0DECABF4E5CF91F I=58 KEY=0000000000000040000000000000000000000000000000000000000000000000 CT=3C8E5A5CDC9CEED90815D1F84BB2998C I=59 KEY=0000000000000020000000000000000000000000000000000000000000000000 CT=283843020BA38F056001B2FD585F7CC9 I=60 KEY=0000000000000010000000000000000000000000000000000000000000000000 CT=D8ADC7426F623ECE8741A70621D28870 I=61 KEY=0000000000000008000000000000000000000000000000000000000000000000 CT=D7C5C215592D06F00E6A80DA69A28EA9 I=62 KEY=0000000000000004000000000000000000000000000000000000000000000000 CT=52CF6FA433C3C870CAC70190358F7F16 I=63 KEY=0000000000000002000000000000000000000000000000000000000000000000 CT=F63D442A584DA71786ADEC9F3346DF75 I=64 KEY=0000000000000001000000000000000000000000000000000000000000000000 CT=549078F4B0CA7079B45F9A5ADAFAFD99 I=65 KEY=0000000000000000800000000000000000000000000000000000000000000000 CT=F2A5986EE4E9984BE2BAFB79EA8152FA I=66 KEY=0000000000000000400000000000000000000000000000000000000000000000 CT=8A74535017B4DB2776668A1FAE64384C I=67 KEY=0000000000000000200000000000000000000000000000000000000000000000 CT=E613342F57A97FD95DC088711A5D0ECD I=68 KEY=0000000000000000100000000000000000000000000000000000000000000000 CT=3FFAEBF6B22CF1DC82AE17CD48175B01 I=69 KEY=0000000000000000080000000000000000000000000000000000000000000000 CT=BAFD52EFA15C248CCBF9757735E6B1CE I=70 KEY=0000000000000000040000000000000000000000000000000000000000000000 CT=7AF94BC018D9DDD4539D2DD1C6F4000F I=71 KEY=0000000000000000020000000000000000000000000000000000000000000000 CT=FE177AD61CA0FDB281086FBA8FE76803 I=72 KEY=0000000000000000010000000000000000000000000000000000000000000000 CT=74DBEA15E2E9285BAD163D7D534251B6 I=73 KEY=0000000000000000008000000000000000000000000000000000000000000000 CT=23DD21331B3A92F200FE56FF050FFE74 I=74 KEY=0000000000000000004000000000000000000000000000000000000000000000 CT=A69C5AA34AB20A858CAFA766EACED6D8 I=75 KEY=0000000000000000002000000000000000000000000000000000000000000000 CT=3F72BB4DF2A4F941A4A09CB78F04B97A I=76 KEY=0000000000000000001000000000000000000000000000000000000000000000 CT=72CC43577E1FD5FD14622D24D97FCDCC I=77 KEY=0000000000000000000800000000000000000000000000000000000000000000 CT=D83AF8EBE93E0B6B99CAFADE224937D1 I=78 KEY=0000000000000000000400000000000000000000000000000000000000000000 CT=44042329128D56CAA8D084C8BD769D1E I=79 KEY=0000000000000000000200000000000000000000000000000000000000000000 CT=14102D72290DE4F2C430ADD1ED64BA1D I=80 KEY=0000000000000000000100000000000000000000000000000000000000000000 CT=449124097B1ECD0AE7065206DF06F03C I=81 KEY=0000000000000000000080000000000000000000000000000000000000000000 CT=D060A99F8CC153A42E11E5F97BD7584A I=82 KEY=0000000000000000000040000000000000000000000000000000000000000000 CT=65605B3EA9261488D53E48602ADEA299 I=83 KEY=0000000000000000000020000000000000000000000000000000000000000000 CT=C5E5CAD7A208DE8EA6BE049EFE5C7346 I=84 KEY=0000000000000000000010000000000000000000000000000000000000000000 CT=4C280C46D2181646048DD5BC0C0831A5 I=85 KEY=0000000000000000000008000000000000000000000000000000000000000000 CT=5DD65CF37F2A0929559AABAFDA08E730 I=86 KEY=0000000000000000000004000000000000000000000000000000000000000000 CT=31F2335CAAF264172F69A693225E6D22 I=87 KEY=0000000000000000000002000000000000000000000000000000000000000000 CT=3E28B35F99A72662590DA96426DD377F I=88 KEY=0000000000000000000001000000000000000000000000000000000000000000 CT=570F40F5D7B20441486578ED344343BE I=89 KEY=0000000000000000000000800000000000000000000000000000000000000000 CT=C54308AD1C9E3B19F8B7417873045A8C I=90 KEY=0000000000000000000000400000000000000000000000000000000000000000 CT=CBF335E39CE13ADE2B696179E8FD0CE1 I=91 KEY=0000000000000000000000200000000000000000000000000000000000000000 CT=9C2FBF422355D8293083D51F4A3C18A9 I=92 KEY=0000000000000000000000100000000000000000000000000000000000000000 CT=5ED8B5A31ECEFAB16C9AA6986DA67BCE I=93 KEY=0000000000000000000000080000000000000000000000000000000000000000 CT=627815DCFC814ABC75900041B1DD7B59 I=94 KEY=0000000000000000000000040000000000000000000000000000000000000000 CT=9EF3E82A50A59F166260494F7A7F2CC3 I=95 KEY=0000000000000000000000020000000000000000000000000000000000000000 CT=878CD0D8D920888B5935D6C351128737 I=96 KEY=0000000000000000000000010000000000000000000000000000000000000000 CT=E44429474D6FC3084EB2A6B8B46AF754 I=97 KEY=0000000000000000000000008000000000000000000000000000000000000000 CT=EBAACF9641D54E1FB18D0A2BE4F19BE5 I=98 KEY=0000000000000000000000004000000000000000000000000000000000000000 CT=13B3BF497CEE780E123C7E193DEA3A01 I=99 KEY=0000000000000000000000002000000000000000000000000000000000000000 CT=6E8F381DE00A41161F0DF03B4155BFD4 I=100 KEY=0000000000000000000000001000000000000000000000000000000000000000 CT=35E4F29BBA2BAE01144910783C3FEF49 I=101 KEY=0000000000000000000000000800000000000000000000000000000000000000 CT=55B17BD66788CEAC366398A31F289FFB I=102 KEY=0000000000000000000000000400000000000000000000000000000000000000 CT=11341F56C0D6D1008D28741DAA7679CE I=103 KEY=0000000000000000000000000200000000000000000000000000000000000000 CT=4DF7253DF421D83358BDBE924745D98C I=104 KEY=0000000000000000000000000100000000000000000000000000000000000000 CT=BAE2EE651116D93EDC8E83B5F3347BE1 I=105 KEY=0000000000000000000000000080000000000000000000000000000000000000 CT=F9721ABD06709157183AF3965A659D9D I=106 KEY=0000000000000000000000000040000000000000000000000000000000000000 CT=19A1C252A613FE2860A4AE6D75CE6FA3 I=107 KEY=0000000000000000000000000020000000000000000000000000000000000000 CT=B5DDB2F5D9752C949FBDE3FFF5556C6E I=108 KEY=0000000000000000000000000010000000000000000000000000000000000000 CT=81B044FCFFC78ECCFCD171AAD0405C66 I=109 KEY=0000000000000000000000000008000000000000000000000000000000000000 CT=C640566D3C06020EB2C42F1D62E56A9B I=110 KEY=0000000000000000000000000004000000000000000000000000000000000000 CT=EA6C4BCF425291679FDFFD26A424FBCC I=111 KEY=0000000000000000000000000002000000000000000000000000000000000000 CT=57F6901465D9440D9F15EE2CBA5A4090 I=112 KEY=0000000000000000000000000001000000000000000000000000000000000000 CT=FBCFA74CADC7406260F63D96C8AAB6B1 I=113 KEY=0000000000000000000000000000800000000000000000000000000000000000 CT=DFF4F096CEA211D4BBDACA033D0EC7D1 I=114 KEY=0000000000000000000000000000400000000000000000000000000000000000 CT=1EE5190D551F0F42F675227A381296A9 I=115 KEY=0000000000000000000000000000200000000000000000000000000000000000 CT=F98E1905012E580F097623C10B93054F I=116 KEY=0000000000000000000000000000100000000000000000000000000000000000 CT=E7D43743D21DD3C9F168C86856558B9A I=117 KEY=0000000000000000000000000000080000000000000000000000000000000000 CT=632A9DDA730DAB67593C5D08D8AC1059 I=118 KEY=0000000000000000000000000000040000000000000000000000000000000000 CT=E084317000715B9057BC9DE9F3AB6124 I=119 KEY=0000000000000000000000000000020000000000000000000000000000000000 CT=61F9EF33A0BB4E666C2ED99101919FAB I=120 KEY=0000000000000000000000000000010000000000000000000000000000000000 CT=6DC1D68A11834657D46703C22578D59A I=121 KEY=0000000000000000000000000000008000000000000000000000000000000000 CT=53AC1548863D3D16F1D4DC7242E05F2C I=122 KEY=0000000000000000000000000000004000000000000000000000000000000000 CT=E82CD587A408306AD78CEAE0916B9F8C I=123 KEY=0000000000000000000000000000002000000000000000000000000000000000 CT=0FD2D40EA6AD17A3A767F0A8600D6295 I=124 KEY=0000000000000000000000000000001000000000000000000000000000000000 CT=AD84CC8255ADB39DFCA23F92761AE7E9 I=125 KEY=0000000000000000000000000000000800000000000000000000000000000000 CT=F4F20CF7D51BEE7DA024A2B11A7ECA0B I=126 KEY=0000000000000000000000000000000400000000000000000000000000000000 CT=5057691B85D9CE93A193214DB0A016B6 I=127 KEY=0000000000000000000000000000000200000000000000000000000000000000 CT=0F58C960876390BDEF4BB6BE95CAA1EE I=128 KEY=0000000000000000000000000000000100000000000000000000000000000000 CT=9A3E66EEBC21BC0BD9430B341EF465FA I=129 KEY=0000000000000000000000000000000080000000000000000000000000000000 CT=20415035F34B8BCBCB28ABF07F78F0D4 I=130 KEY=0000000000000000000000000000000040000000000000000000000000000000 CT=AC89FC7BA10479EBF10DE65BCEF89B3C I=131 KEY=0000000000000000000000000000000020000000000000000000000000000000 CT=068FA75A30BE443171AF3F6FEB1A20D2 I=132 KEY=0000000000000000000000000000000010000000000000000000000000000000 CT=50E02F213246C525A8C27700CA34B502 I=133 KEY=0000000000000000000000000000000008000000000000000000000000000000 CT=227DA47D5A0906DB3AB042BB0A695FB6 I=134 KEY=0000000000000000000000000000000004000000000000000000000000000000 CT=8663AC30ED12514F1DE46777F4514BFC I=135 KEY=0000000000000000000000000000000002000000000000000000000000000000 CT=A987D4BC12E1DE9F4B6DF43567C34A8B I=136 KEY=0000000000000000000000000000000001000000000000000000000000000000 CT=6D5A0370F599ACA605F63B04E5143D0C I=137 KEY=0000000000000000000000000000000000800000000000000000000000000000 CT=9809266E378B07B7AFDB3BAA97B7E442 I=138 KEY=0000000000000000000000000000000000400000000000000000000000000000 CT=8F753252B30CCCACE12D9A301F4D5090 I=139 KEY=0000000000000000000000000000000000200000000000000000000000000000 CT=032465F6C0CE34D41962F561692A1AFF I=140 KEY=0000000000000000000000000000000000100000000000000000000000000000 CT=C50E9AD5BEB8F3B00821DD47FF8AC093 I=141 KEY=0000000000000000000000000000000000080000000000000000000000000000 CT=9C6FEA3D46268D54A6829B2AD25BB276 I=142 KEY=0000000000000000000000000000000000040000000000000000000000000000 CT=0FD8575E87706F561343D7B3A41E044A I=143 KEY=0000000000000000000000000000000000020000000000000000000000000000 CT=BEE9BEB3739540D88CBCE77925F0A114 I=144 KEY=0000000000000000000000000000000000010000000000000000000000000000 CT=D24EAEE7FFFBAC3D6F26C2DCE0DCDE28 I=145 KEY=0000000000000000000000000000000000008000000000000000000000000000 CT=47771A90398FF0F7FA821C2F8F5E1398 I=146 KEY=0000000000000000000000000000000000004000000000000000000000000000 CT=4639741B6F84B135AD118C8249B64ED0 I=147 KEY=0000000000000000000000000000000000002000000000000000000000000000 CT=8EE5505EC85567697A3306F250A27720 I=148 KEY=0000000000000000000000000000000000001000000000000000000000000000 CT=7C8A19AC1AEFBC5E0119D91A5F05D4C2 I=149 KEY=0000000000000000000000000000000000000800000000000000000000000000 CT=5141B9B672E54773B672E3A6C424887B I=150 KEY=0000000000000000000000000000000000000400000000000000000000000000 CT=B5A2D3CD206653C6402F34FB0AE3613D I=151 KEY=0000000000000000000000000000000000000200000000000000000000000000 CT=0F5BD9408738231D114B0A82753279A3 I=152 KEY=0000000000000000000000000000000000000100000000000000000000000000 CT=FEF033FF4268EA487FC74C5E43A45338 I=153 KEY=0000000000000000000000000000000000000080000000000000000000000000 CT=A3EDC09DCD529B113910D904AD855581 I=154 KEY=0000000000000000000000000000000000000040000000000000000000000000 CT=AB8FBB6F27A0AC7C55B59FDD36B72F1C I=155 KEY=0000000000000000000000000000000000000020000000000000000000000000 CT=EEA44D5ED4D769CC930CD83D8999EC46 I=156 KEY=0000000000000000000000000000000000000010000000000000000000000000 CT=6972276803AE9AA7C6F431AB10979C34 I=157 KEY=0000000000000000000000000000000000000008000000000000000000000000 CT=86DEAA9F39244101818178474D7DBDE9 I=158 KEY=0000000000000000000000000000000000000004000000000000000000000000 CT=88C6B466EA361D662D8D08CBF181F4FE I=159 KEY=0000000000000000000000000000000000000002000000000000000000000000 CT=91AB2C6B7C63FF59F7CBEEBF91B20B95 I=160 KEY=0000000000000000000000000000000000000001000000000000000000000000 CT=2DFE6C146AD5B3D8C3C1718F13B48E01 I=161 KEY=0000000000000000000000000000000000000000800000000000000000000000 CT=C7CFF1623451711391A302EEC3584AAA I=162 KEY=0000000000000000000000000000000000000000400000000000000000000000 CT=089FE845CC05011686C66019D18BE050 I=163 KEY=0000000000000000000000000000000000000000200000000000000000000000 CT=08C8410B9B427211A67124B0DCCEAD48 I=164 KEY=0000000000000000000000000000000000000000100000000000000000000000 CT=8D91592F5566085254784606334D7629 I=165 KEY=0000000000000000000000000000000000000000080000000000000000000000 CT=3298FEAAF2E1201D6299FF8846639C97 I=166 KEY=0000000000000000000000000000000000000000040000000000000000000000 CT=C497CB9F0BDFE0EFC8C2F3F90760AA72 I=167 KEY=0000000000000000000000000000000000000000020000000000000000000000 CT=2788AFD046E0309CBE4424690DA2AB89 I=168 KEY=0000000000000000000000000000000000000000010000000000000000000000 CT=E9891707F25EF29FEE372890D4258982 I=169 KEY=0000000000000000000000000000000000000000008000000000000000000000 CT=DB041D94A23D45D4D4DCED5A030CAF61 I=170 KEY=0000000000000000000000000000000000000000004000000000000000000000 CT=FFAFDBF0ECB18DF9EA02C27077448E6D I=171 KEY=0000000000000000000000000000000000000000002000000000000000000000 CT=2DAAA42A7D0A1D3B0E4761D99CF2150A I=172 KEY=0000000000000000000000000000000000000000001000000000000000000000 CT=3B7A54CB7CF30ABE263DD6ED5BFE8D63 I=173 KEY=0000000000000000000000000000000000000000000800000000000000000000 CT=EEFA090174C590C448A55D43648F534A I=174 KEY=0000000000000000000000000000000000000000000400000000000000000000 CT=9E15798731ED42F43EA2740A691DA872 I=175 KEY=0000000000000000000000000000000000000000000200000000000000000000 CT=31FBD661540A5DEAAD1017CFD3909EC8 I=176 KEY=0000000000000000000000000000000000000000000100000000000000000000 CT=CDA9AE05F224140E28CB951721B44D6A I=177 KEY=0000000000000000000000000000000000000000000080000000000000000000 CT=0C5BC512C60A1EAC3434EFB1A8FBB182 I=178 KEY=0000000000000000000000000000000000000000000040000000000000000000 CT=AA863610DEEEEB62D045E87EA30B59B5 I=179 KEY=0000000000000000000000000000000000000000000020000000000000000000 CT=6AC2448DE568D279C7EEBE1DF403920C I=180 KEY=0000000000000000000000000000000000000000000010000000000000000000 CT=E2011E3D292B26888AE801215FD0CB40 I=181 KEY=0000000000000000000000000000000000000000000008000000000000000000 CT=E06F3E15EE3A61672D1C99BADE5B9DBE I=182 KEY=0000000000000000000000000000000000000000000004000000000000000000 CT=BB7027F0548CF6712CEB4C7A4B28E178 I=183 KEY=0000000000000000000000000000000000000000000002000000000000000000 CT=061EC21FB70FADBDF87C3BD2AE23825B I=184 KEY=0000000000000000000000000000000000000000000001000000000000000000 CT=4C21F26FE94ABBAC381352375314C3EB I=185 KEY=0000000000000000000000000000000000000000000000800000000000000000 CT=F7CEE6DD99909C2B569EEDA61ED8942E I=186 KEY=0000000000000000000000000000000000000000000000400000000000000000 CT=CE98C4A876C65E4CCB261EBB1D9DF7F5 I=187 KEY=0000000000000000000000000000000000000000000000200000000000000000 CT=A5491881CF833C3604ABC08044F402AC I=188 KEY=0000000000000000000000000000000000000000000000100000000000000000 CT=A1BA16E64CCCB3087D57A768507B0BFC I=189 KEY=0000000000000000000000000000000000000000000000080000000000000000 CT=D55951E202D2949EBD3BE43120C738BF I=190 KEY=0000000000000000000000000000000000000000000000040000000000000000 CT=EBB8E43069E69F450EFEC65DCD52B7FD I=191 KEY=0000000000000000000000000000000000000000000000020000000000000000 CT=2B292135663B4AA5ABFE9423D57E7EE9 I=192 KEY=0000000000000000000000000000000000000000000000010000000000000000 CT=E91BF974B3BE3AD966249D8655292A85 I=193 KEY=0000000000000000000000000000000000000000000000008000000000000000 CT=384365998EAA9562236CC58F6ADF9610 I=194 KEY=0000000000000000000000000000000000000000000000004000000000000000 CT=C2E997012AA3D4D8D359C9A947CBE69F I=195 KEY=0000000000000000000000000000000000000000000000002000000000000000 CT=F49421204148BA213BE87E2D5C22B0BF I=196 KEY=0000000000000000000000000000000000000000000000001000000000000000 CT=82ED0ED9953AA92E4DF30929CA65C00F I=197 KEY=0000000000000000000000000000000000000000000000000800000000000000 CT=291EB1D11653C8479437C74A977F5106 I=198 KEY=0000000000000000000000000000000000000000000000000400000000000000 CT=BCB997B1939B8983ABD550D6025683E3 I=199 KEY=0000000000000000000000000000000000000000000000000200000000000000 CT=1FBA2592C6F489775CAADA71F9B983E9 I=200 KEY=0000000000000000000000000000000000000000000000000100000000000000 CT=969F66F217AF1A3DB9E41C1B29039824 I=201 KEY=0000000000000000000000000000000000000000000000000080000000000000 CT=A54BB7D6B17E423AC0A7744C19073CB8 I=202 KEY=0000000000000000000000000000000000000000000000000040000000000000 CT=B0AC6E6578D1021F47DCF9748A32EAD5 I=203 KEY=0000000000000000000000000000000000000000000000000020000000000000 CT=B87B361C3B7B194C77A4358D4669153E I=204 KEY=0000000000000000000000000000000000000000000000000010000000000000 CT=46A133847F96EAA8282A799DC8899D58 I=205 KEY=0000000000000000000000000000000000000000000000000008000000000000 CT=2265EC3A9F2D5C9547A091CC8CFB18EA I=206 KEY=0000000000000000000000000000000000000000000000000004000000000000 CT=54CBF3A6FC4FE56D426117AA1FFD1DDE I=207 KEY=0000000000000000000000000000000000000000000000000002000000000000 CT=5312877CCEAB6CFB0905394A370A8003 I=208 KEY=0000000000000000000000000000000000000000000000000001000000000000 CT=7190BD6EC613FE38B84ECFE28F702FE4 I=209 KEY=0000000000000000000000000000000000000000000000000000800000000000 CT=D1FA5B9CA89A43B04C05F0EF29EF68CD I=210 KEY=0000000000000000000000000000000000000000000000000000400000000000 CT=808285751548ED934FD1056D2D9AE8BA I=211 KEY=0000000000000000000000000000000000000000000000000000200000000000 CT=2758DEF3E7B95A9AE89777BE64D5A6CF I=212 KEY=0000000000000000000000000000000000000000000000000000100000000000 CT=07D81F87DB3E0ACC82B01E08FB22F3C1 I=213 KEY=0000000000000000000000000000000000000000000000000000080000000000 CT=8DA250E5553D650711A75EE1CB4FD1C7 I=214 KEY=0000000000000000000000000000000000000000000000000000040000000000 CT=A93D946BD0E87F32719DF5F158CEE669 I=215 KEY=0000000000000000000000000000000000000000000000000000020000000000 CT=03945236EC2A4D4EAF30B8ABEB54330D I=216 KEY=0000000000000000000000000000000000000000000000000000010000000000 CT=11CC35301F24B79DDE31AEA2D1354F88 I=217 KEY=0000000000000000000000000000000000000000000000000000008000000000 CT=E73715B3E8D9A290F44AE6FFBF247E5D I=218 KEY=0000000000000000000000000000000000000000000000000000004000000000 CT=7345E07732B71CB158BBF64CCA5C5B96 I=219 KEY=0000000000000000000000000000000000000000000000000000002000000000 CT=6E128F296D24705A1924FD9B70C4ED04 I=220 KEY=0000000000000000000000000000000000000000000000000000001000000000 CT=95A789776F036783FBD330947083F54F I=221 KEY=0000000000000000000000000000000000000000000000000000000800000000 CT=360DEC2533EA4AA2E3E54FD3DE2906EB I=222 KEY=0000000000000000000000000000000000000000000000000000000400000000 CT=E68EFD7FECF4D601EA22727BD764965B I=223 KEY=0000000000000000000000000000000000000000000000000000000200000000 CT=9065C64A8BFF44AC33EDBB611CF83D7B I=224 KEY=0000000000000000000000000000000000000000000000000000000100000000 CT=8F33C8DF2A7A51CE8090E8F123BC3723 I=225 KEY=0000000000000000000000000000000000000000000000000000000080000000 CT=807F391FFBA8291BA625623210F99018 I=226 KEY=0000000000000000000000000000000000000000000000000000000040000000 CT=5E8B3F3A701522CE5CAA761C929D6292 I=227 KEY=0000000000000000000000000000000000000000000000000000000020000000 CT=3BA404DC38735A78289E3809E8364835 I=228 KEY=0000000000000000000000000000000000000000000000000000000010000000 CT=D23BEDBAD229F8305DC425B6B759DCC9 I=229 KEY=0000000000000000000000000000000000000000000000000000000008000000 CT=44880F21CF5913040AE376AEE2A10AD8 I=230 KEY=0000000000000000000000000000000000000000000000000000000004000000 CT=9BC98E29D057C0E828C3B5CCE69256C1 I=231 KEY=0000000000000000000000000000000000000000000000000000000002000000 CT=B293CC7A975DA141A68279368057CC41 I=232 KEY=0000000000000000000000000000000000000000000000000000000001000000 CT=8D60FB87ACD91385B313BE5F1D7BD30F I=233 KEY=0000000000000000000000000000000000000000000000000000000000800000 CT=2C8E56132D70291B303C48FDF75543CD I=234 KEY=0000000000000000000000000000000000000000000000000000000000400000 CT=D1F80035B826791F6CE4E59B7DB1BB0D I=235 KEY=0000000000000000000000000000000000000000000000000000000000200000 CT=42CE6224FC36469339A133DD08173BD4 I=236 KEY=0000000000000000000000000000000000000000000000000000000000100000 CT=61817155EA41BCBA2AF7F06AE7CBF585 I=237 KEY=0000000000000000000000000000000000000000000000000000000000080000 CT=D1923A9866068D2EF5FB77D57C3315B6 I=238 KEY=0000000000000000000000000000000000000000000000000000000000040000 CT=B37CBDB5D719F49691CA968EF2E84140 I=239 KEY=0000000000000000000000000000000000000000000000000000000000020000 CT=EC974E653A055D7F8F22171030F68E1D I=240 KEY=0000000000000000000000000000000000000000000000000000000000010000 CT=DDE5D3B9AAD9C32213BB3675A822499C I=241 KEY=0000000000000000000000000000000000000000000000000000000000008000 CT=D3B6E9216EA1AE57EB1C628A3C38AB78 I=242 KEY=0000000000000000000000000000000000000000000000000000000000004000 CT=82C99ECC69472B7E96324B042AE8B87A I=243 KEY=0000000000000000000000000000000000000000000000000000000000002000 CT=97144DC5338C43600F84439C0AA0D147 I=244 KEY=0000000000000000000000000000000000000000000000000000000000001000 CT=400AC4A0BBADA1DB2121EB144C7E5209 I=245 KEY=0000000000000000000000000000000000000000000000000000000000000800 CT=EFD9D550EB419ED278F4885A490AB54C I=246 KEY=0000000000000000000000000000000000000000000000000000000000000400 CT=2AB7816E149B7C0404C88A8857793670 I=247 KEY=0000000000000000000000000000000000000000000000000000000000000200 CT=5B591DFF9E8DEE15BAD24C025DBCA481 I=248 KEY=0000000000000000000000000000000000000000000000000000000000000100 CT=0C06633E30721C3749F49AD8CBF2B754 I=249 KEY=0000000000000000000000000000000000000000000000000000000000000080 CT=96D6D31A41B5123B2035FD91A921D4CA I=250 KEY=0000000000000000000000000000000000000000000000000000000000000040 CT=E7F6C34D86668BC2805CA7793C5E86AD I=251 KEY=0000000000000000000000000000000000000000000000000000000000000020 CT=F46DFF5FF500D6879C4D3E45CF0CF0F3 I=252 KEY=0000000000000000000000000000000000000000000000000000000000000010 CT=60D842D9C61DA7495C116197B7CECBBE I=253 KEY=0000000000000000000000000000000000000000000000000000000000000008 CT=D45B24EDB673353EBDF248B8FA06B67A I=254 KEY=0000000000000000000000000000000000000000000000000000000000000004 CT=119EAEBCC165D0BD02C0D35DC82EF992 I=255 KEY=0000000000000000000000000000000000000000000000000000000000000002 CT=E673143680414ADA301D0ED34626B9FE I=256 KEY=0000000000000000000000000000000000000000000000000000000000000001 CT=6B6CFE160A6263631B292F879EEFF926 ========== krb5-1.22.1/src/lib/crypto/crypto_tests/t_mddriver.c0000664000175000017500000001617715051422640022277 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_mddriver.c - test driver for MD2, MD4 and MD5 */ /* * Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All * rights reserved. * * RSA Data Security, Inc. makes no representations concerning either * the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" * without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. */ /* The following makes MD default to MD5 if it has not already been defined with C compiler flags. */ #ifndef MD #define MD 5 #endif #include "crypto_int.h" /* Length of test block, number of test blocks. */ #define TEST_BLOCK_LEN 1000 #define TEST_BLOCK_COUNT 1000 static void MDHash (char *, size_t, size_t, unsigned char *); static void MDString (char *); static void MDTimeTrial (void); static void MDTestSuite (void); static void MDPrint (unsigned char [16]); struct md_test_entry { char *string; unsigned char digest[16]; }; #if MD == 4 #define MDProvider krb5int_hash_md4 #define HAVE_TEST_SUITE /* Test suite from RFC 1320 */ struct md_test_entry md_test_suite[] = { { "", {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 }}, { "a", {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24 }}, { "abc", {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d }}, { "message digest", {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b }}, { "abcdefghijklmnopqrstuvwxyz", {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9 }}, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4 }}, { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 }}, {0, {0}} }; #endif #if MD == 5 #define MDProvider krb5int_hash_md5 #define HAVE_TEST_SUITE /* Test suite from RFC 1321 */ struct md_test_entry md_test_suite[] = { { "", {0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e }}, { "a", {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 }}, { "abc", {0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 }}, { "message digest", {0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 }}, { "abcdefghijklmnopqrstuvwxyz", {0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b }}, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", {0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f }}, { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", {0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a }}, { 0, {0} } }; #endif /* Main driver. Arguments (may be any combination): -sstring - digests string -t - runs time trial -x - runs test script */ int main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] == 's') MDString (argv[i] + 2); else if (strcmp (argv[i], "-t") == 0) MDTimeTrial (); else if (strcmp (argv[i], "-x") == 0) MDTestSuite (); } return (0); } static void MDHash(char *bytes, size_t len, size_t count, unsigned char *out) { krb5_crypto_iov *iov; krb5_data outdata = make_data (out, MDProvider.hashsize); size_t i; iov = malloc (count * sizeof(*iov)); if (iov == NULL) abort (); for (i = 0; i < count; i++) { iov[i].flags = KRB5_CRYPTO_TYPE_DATA; iov[i].data = make_data (bytes, len); } MDProvider.hash(iov, count, &outdata); free(iov); } /* Digests a string and prints the result. */ static void MDString(char *string) { unsigned char digest[16]; MDHash (string, strlen(string), 1, digest); printf ("MD%d (\"%s\") = ", MD, string); MDPrint (digest); printf ("\n"); } /* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte blocks. */ static void MDTimeTrial(void) { time_t endTime, startTime; unsigned char block[TEST_BLOCK_LEN], digest[16]; unsigned int i; printf("MD%d time trial. Digesting %d %d-byte blocks ...", MD, TEST_BLOCK_LEN, TEST_BLOCK_COUNT); /* Initialize block */ for (i = 0; i < TEST_BLOCK_LEN; i++) block[i] = (unsigned char)(i & 0xff); /* Start timer */ time (&startTime); /* Digest blocks */ MDHash ((char *)block, TEST_BLOCK_LEN, TEST_BLOCK_COUNT, digest); /* Stop timer */ time (&endTime); printf (" done\n"); printf ("Digest = "); MDPrint (digest); printf ("\nTime = %ld seconds\n", (long)(endTime-startTime)); printf ("Speed = %ld bytes/second\n", (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime)); } /* Digests a reference suite of strings and prints the results. */ static void MDTestSuite(void) { #ifdef HAVE_TEST_SUITE struct md_test_entry *entry; int num_tests = 0, num_failed = 0; unsigned char digest[16]; printf ("MD%d test suite:\n\n", MD); for (entry = md_test_suite; entry->string; entry++) { unsigned int len = strlen (entry->string); MDHash (entry->string, len, 1, digest); printf ("MD%d (\"%s\") = ", MD, entry->string); MDPrint (digest); printf ("\n"); if (memcmp(digest, entry->digest, 16) != 0) { printf("\tIncorrect MD%d digest! Should have been:\n\t\t ", MD); MDPrint(entry->digest); printf("\n"); num_failed++; } num_tests++; } if (num_failed) { printf("%d out of %d tests failed for MD%d!!!\n", num_failed, num_tests, MD); exit(1); } else { printf ("%d tests passed successfully for MD%d.\n", num_tests, MD); exit(0); } #else printf ("MD%d test suite:\n", MD); MDString (""); MDString ("a"); MDString ("abc"); MDString ("message digest"); MDString ("abcdefghijklmnopqrstuvwxyz"); MDString ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); MDString ("12345678901234567890123456789012345678901234567890123456789012345678901234567890"); #endif } /* Prints a message digest in hexadecimal. */ static void MDPrint(unsigned char digest[16]) { unsigned int i; for (i = 0; i < 16; i++) printf ("%02x", digest[i]); } krb5-1.22.1/src/lib/crypto/crypto_tests/t_prf.c0000664000175000017500000001261315051422640021241 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_prf.c - PRF test cases */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" struct test { krb5_enctype enctype; krb5_data keybits; krb5_data prf_input; krb5_data expected; } tests[] = { { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 16, "\xAE\x27\x2E\x7C\xDE\xC8\x6A\xC5\x13\x8C\xDB\x19\x6D\x8E\x29\x7D" }, { KV5M_DATA, 2, "\x01\x61" }, { KV5M_DATA, 16, "\x77\xB3\x9A\x37\xA8\x68\x92\x0F\x2A\x51\xF9\xDD\x15\x0C\x57\x17" } }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 16, "\x67\xAB\x1C\xFE\xF3\x5E\x4C\x27\xFF\xDE\xAC\x60\x38\x5A\x3E\x9C" }, { KV5M_DATA, 2, "\x01\x62" }, { KV5M_DATA, 16, "\xE0\x6C\x0D\xD3\x1F\xF0\x20\x91\x99\x4F\x2E\xF5\x17\x8B\xFE\x3D" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 32, "\xC0\x1F\x15\x72\x11\xF7\xB7\x7E\xAA\xF4\x57\xC3\xE1\x56\x69\x01" "\x27\xEE\x12\x7D\x81\x0B\xA6\x39\x2E\x97\xBA\xA2\x43\xEB\x06\x16" }, { KV5M_DATA, 2, "\x01\x61" }, { KV5M_DATA, 16, "\xB2\x62\x8C\x78\x8E\x2E\x9C\x4A\x9B\xB4\x64\x46\x78\xC2\x9F\x2F" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 32, "\xC0\x1F\x15\x72\x11\xF7\xB7\x7E\xAA\xF4\x57\xC3\xE1\x56\x69\x01" "\x27\xEE\x12\x7D\x81\x0B\xA6\x39\x2E\x97\xBA\xA2\x43\xEB\x06\x16" }, { KV5M_DATA, 2, "\x02\x61" }, { KV5M_DATA, 16, "\xB4\x06\x37\x33\x50\xCE\xE8\xA6\x12\x6F\x4A\x9B\x65\xA0\xCD\x21" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 32, "\x9D\x52\x0D\x2D\x98\x0A\xA7\xCB\x6B\x69\x36\x82\xB6\x2D\xA2\x58" "\xB3\x33\x86\x79\x51\x64\x2C\xE6\x47\xAE\x62\xB1\xE5\xE0\xB5\xE9" }, { KV5M_DATA, 2, "\x01\x62" }, { KV5M_DATA, 16, "\xFF\x0E\x28\x9E\xA7\x56\xC0\x55\x9A\x0E\x91\x18\x56\x96\x1A\x49" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 32, "\x9D\x52\x0D\x2D\x98\x0A\xA7\xCB\x6B\x69\x36\x82\xB6\x2D\xA2\x58" "\xB3\x33\x86\x79\x51\x64\x2C\xE6\x47\xAE\x62\xB1\xE5\xE0\xB5\xE9" }, { KV5M_DATA, 2, "\x02\x62" }, { KV5M_DATA, 16, "\x0D\x67\x4D\xD0\xF9\xA6\x80\x65\x25\xA4\xD9\x2E\x82\x8B\xD1\x5A" } }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, { KV5M_DATA, 16, "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" }, { KV5M_DATA, 4, "test" }, { KV5M_DATA, 32, "\x9D\x18\x86\x16\xF6\x38\x52\xFE\x86\x91\x5B\xB8\x40\xB4\xA8\x86" "\xFF\x3E\x6B\xB0\xF8\x19\xB4\x9B\x89\x33\x93\xD3\x93\x85\x42\x95" } }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, { KV5M_DATA, 32, "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98" "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" }, { KV5M_DATA, 4, "test" }, { KV5M_DATA, 48, "\x98\x01\xF6\x9A\x36\x8C\x2B\xF6\x75\xE5\x95\x21\xE1\x77\xD9\xA0" "\x7F\x67\xEF\xE1\xCF\xDE\x8D\x3C\x8D\x6F\x6A\x02\x56\xE3\xB1\x7D" "\xB3\xC1\xB6\x2A\xD1\xB8\x55\x33\x60\xD1\x73\x67\xEB\x15\x14\xD2" } }, }; int main(void) { krb5_error_code ret; krb5_data output; krb5_keyblock kb; size_t i, prfsz; const struct test *test; for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) { test = &tests[i]; kb.magic = KV5M_KEYBLOCK; kb.enctype = test->enctype; kb.length = test->keybits.length; kb.contents = (uint8_t *)test->keybits.data; ret = krb5_c_prf_length(NULL, test->enctype, &prfsz); assert(!ret); ret = alloc_data(&output, prfsz); assert(!ret); ret = krb5_c_prf(NULL, &kb, &tests[i].prf_input, &output); assert(!ret); if (!data_eq(output, tests[i].expected)) { printf("Test %d failed\n", (int)i); exit(1); } free(output.data); } return 0; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_cf2.in0000664000175000017500000000014615051422640021306 0ustar ghudsonghudson17 key1 key2 a b 18 key1 key2 a b 16 key1 key2 a b 23 key1 key2 a b 19 key1 key2 a b 20 key1 key2 a b krb5-1.22.1/src/lib/crypto/crypto_tests/t_derive.c0000664000175000017500000003366215051422640021737 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_derive.c - Test harness for key derivation */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This harness detects changes in key derivation results using known values. * With the -v flag, results for all tests are displayed. */ #include "crypto_int.h" struct test { krb5_enctype enctype; krb5_data inkey; krb5_data constant; enum deriv_alg alg; krb5_data expected_key; } test_cases[] = { /* Kc, Ke, Kei for a DES3 key */ { ENCTYPE_DES3_CBC_SHA1, { KV5M_DATA, 24, "\x85\x0B\xB5\x13\x58\x54\x8C\xD0\x5E\x86\x76\x8C\x31\x3E\x3B\xFE" "\xF7\x51\x19\x37\xDC\xF7\x2C\x3E" }, { KV5M_DATA, 5, "\0\0\0\2\x99" }, DERIVE_RFC3961, { KV5M_DATA, 24, "\xF7\x8C\x49\x6D\x16\xE6\xC2\xDA\xE0\xE0\xB6\xC2\x40\x57\xA8\x4C" "\x04\x26\xAE\xEF\x26\xFD\x6D\xCE" } }, { ENCTYPE_DES3_CBC_SHA1, { KV5M_DATA, 24, "\x85\x0B\xB5\x13\x58\x54\x8C\xD0\x5E\x86\x76\x8C\x31\x3E\x3B\xFE" "\xF7\x51\x19\x37\xDC\xF7\x2C\x3E" }, { KV5M_DATA, 5, "\0\0\0\2\xAA" }, DERIVE_RFC3961, { KV5M_DATA, 24, "\x5B\x57\x23\xD0\xB6\x34\xCB\x68\x4C\x3E\xBA\x52\x64\xE9\xA7\x0D" "\x52\xE6\x83\x23\x1A\xD3\xC4\xCE" } }, { ENCTYPE_DES3_CBC_SHA1, { KV5M_DATA, 24, "\x85\x0B\xB5\x13\x58\x54\x8C\xD0\x5E\x86\x76\x8C\x31\x3E\x3B\xFE" "\xF7\x51\x19\x37\xDC\xF7\x2C\x3E" }, { KV5M_DATA, 5, "\0\0\0\2\x55" }, DERIVE_RFC3961, { KV5M_DATA, 24, "\xA7\x7C\x94\x98\x0E\x9B\x73\x45\xA8\x15\x25\xC4\x23\xA7\x37\xCE" "\x67\xF4\xCD\x91\xB6\xB3\xDA\x45" } }, /* Kc, Ke, Ki for an AES-128 key */ { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 16, "\x42\x26\x3C\x6E\x89\xF4\xFC\x28\xB8\xDF\x68\xEE\x09\x79\x9F\x15" }, { KV5M_DATA, 5, "\0\0\0\2\x99" }, DERIVE_RFC3961, { KV5M_DATA, 16, "\x34\x28\x0A\x38\x2B\xC9\x27\x69\xB2\xDA\x2F\x9E\xF0\x66\x85\x4B" } }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 16, "\x42\x26\x3C\x6E\x89\xF4\xFC\x28\xB8\xDF\x68\xEE\x09\x79\x9F\x15" }, { KV5M_DATA, 5, "\0\0\0\2\xAA" }, DERIVE_RFC3961, { KV5M_DATA, 16, "\x5B\x14\xFC\x4E\x25\x0E\x14\xDD\xF9\xDC\xCF\x1A\xF6\x67\x4F\x53" } }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, { KV5M_DATA, 16, "\x42\x26\x3C\x6E\x89\xF4\xFC\x28\xB8\xDF\x68\xEE\x09\x79\x9F\x15" }, { KV5M_DATA, 5, "\0\0\0\2\x55" }, DERIVE_RFC3961, { KV5M_DATA, 16, "\x4E\xD3\x10\x63\x62\x16\x84\xF0\x9A\xE8\xD8\x99\x91\xAF\x3E\x8F" } }, /* Kc, Ke, Ki for an AES-256 key */ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 32, "\xFE\x69\x7B\x52\xBC\x0D\x3C\xE1\x44\x32\xBA\x03\x6A\x92\xE6\x5B" "\xBB\x52\x28\x09\x90\xA2\xFA\x27\x88\x39\x98\xD7\x2A\xF3\x01\x61" }, { KV5M_DATA, 5, "\0\0\0\2\x99" }, DERIVE_RFC3961, { KV5M_DATA, 32, "\xBF\xAB\x38\x8B\xDC\xB2\x38\xE9\xF9\xC9\x8D\x6A\x87\x83\x04\xF0" "\x4D\x30\xC8\x25\x56\x37\x5A\xC5\x07\xA7\xA8\x52\x79\x0F\x46\x74" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 32, "\xFE\x69\x7B\x52\xBC\x0D\x3C\xE1\x44\x32\xBA\x03\x6A\x92\xE6\x5B" "\xBB\x52\x28\x09\x90\xA2\xFA\x27\x88\x39\x98\xD7\x2A\xF3\x01\x61" }, { KV5M_DATA, 5, "\0\0\0\2\xAA" }, DERIVE_RFC3961, { KV5M_DATA, 32, "\xC7\xCF\xD9\xCD\x75\xFE\x79\x3A\x58\x6A\x54\x2D\x87\xE0\xD1\x39" "\x6F\x11\x34\xA1\x04\xBB\x1A\x91\x90\xB8\xC9\x0A\xDA\x3D\xDF\x37" } }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, { KV5M_DATA, 32, "\xFE\x69\x7B\x52\xBC\x0D\x3C\xE1\x44\x32\xBA\x03\x6A\x92\xE6\x5B" "\xBB\x52\x28\x09\x90\xA2\xFA\x27\x88\x39\x98\xD7\x2A\xF3\x01\x61" }, { KV5M_DATA, 5, "\0\0\0\2\x55" }, DERIVE_RFC3961, { KV5M_DATA, 32, "\x97\x15\x1B\x4C\x76\x94\x50\x63\xE2\xEB\x05\x29\xDC\x06\x7D\x97" "\xD7\xBB\xA9\x07\x76\xD8\x12\x6D\x91\xF3\x4F\x31\x01\xAE\xA8\xBA" } }, /* Kc, Ke, Ki for a Camellia-128 key */ { ENCTYPE_CAMELLIA128_CTS_CMAC, { KV5M_DATA, 16, "\x57\xD0\x29\x72\x98\xFF\xD9\xD3\x5D\xE5\xA4\x7F\xB4\xBD\xE2\x4B" }, { KV5M_DATA, 5, "\0\0\0\2\x99" }, DERIVE_SP800_108_CMAC, { KV5M_DATA, 16, "\xD1\x55\x77\x5A\x20\x9D\x05\xF0\x2B\x38\xD4\x2A\x38\x9E\x5A\x56" } }, { ENCTYPE_CAMELLIA128_CTS_CMAC, { KV5M_DATA, 16, "\x57\xD0\x29\x72\x98\xFF\xD9\xD3\x5D\xE5\xA4\x7F\xB4\xBD\xE2\x4B" }, { KV5M_DATA, 5, "\0\0\0\2\xAA" }, DERIVE_SP800_108_CMAC, { KV5M_DATA, 16, "\x64\xDF\x83\xF8\x5A\x53\x2F\x17\x57\x7D\x8C\x37\x03\x57\x96\xAB" } }, { ENCTYPE_CAMELLIA128_CTS_CMAC, { KV5M_DATA, 16, "\x57\xD0\x29\x72\x98\xFF\xD9\xD3\x5D\xE5\xA4\x7F\xB4\xBD\xE2\x4B" }, { KV5M_DATA, 5, "\0\0\0\2\x55" }, DERIVE_SP800_108_CMAC, { KV5M_DATA, 16, "\x3E\x4F\xBD\xF3\x0F\xB8\x25\x9C\x42\x5C\xB6\xC9\x6F\x1F\x46\x35" } }, /* Kc, Ke, Ki for a Camellia-256 key */ { ENCTYPE_CAMELLIA256_CTS_CMAC, { KV5M_DATA, 32, "\xB9\xD6\x82\x8B\x20\x56\xB7\xBE\x65\x6D\x88\xA1\x23\xB1\xFA\xC6" "\x82\x14\xAC\x2B\x72\x7E\xCF\x5F\x69\xAF\xE0\xC4\xDF\x2A\x6D\x2C" }, { KV5M_DATA, 5, "\0\0\0\2\x99" }, DERIVE_SP800_108_CMAC, { KV5M_DATA, 32, "\xE4\x67\xF9\xA9\x55\x2B\xC7\xD3\x15\x5A\x62\x20\xAF\x9C\x19\x22" "\x0E\xEE\xD4\xFF\x78\xB0\xD1\xE6\xA1\x54\x49\x91\x46\x1A\x9E\x50" } }, { ENCTYPE_CAMELLIA256_CTS_CMAC, { KV5M_DATA, 32, "\xB9\xD6\x82\x8B\x20\x56\xB7\xBE\x65\x6D\x88\xA1\x23\xB1\xFA\xC6" "\x82\x14\xAC\x2B\x72\x7E\xCF\x5F\x69\xAF\xE0\xC4\xDF\x2A\x6D\x2C" }, { KV5M_DATA, 5, "\0\0\0\2\xAA" }, DERIVE_SP800_108_CMAC, { KV5M_DATA, 32, "\x41\x2A\xEF\xC3\x62\xA7\x28\x5F\xC3\x96\x6C\x6A\x51\x81\xE7\x60" "\x5A\xE6\x75\x23\x5B\x6D\x54\x9F\xBF\xC9\xAB\x66\x30\xA4\xC6\x04" } }, { ENCTYPE_CAMELLIA256_CTS_CMAC, { KV5M_DATA, 32, "\xB9\xD6\x82\x8B\x20\x56\xB7\xBE\x65\x6D\x88\xA1\x23\xB1\xFA\xC6" "\x82\x14\xAC\x2B\x72\x7E\xCF\x5F\x69\xAF\xE0\xC4\xDF\x2A\x6D\x2C" }, { KV5M_DATA, 5, "\0\0\0\2\x55" }, DERIVE_SP800_108_CMAC, { KV5M_DATA, 32, "\xFA\x62\x4F\xA0\xE5\x23\x99\x3F\xA3\x88\xAE\xFD\xC6\x7E\x67\xEB" "\xCD\x8C\x08\xE8\xA0\x24\x6B\x1D\x73\xB0\xD1\xDD\x9F\xC5\x82\xB0" } }, /* Kc, Ke, Ki for an aes128-sha2 key. */ { ENCTYPE_AES128_CTS_HMAC_SHA256_128, { KV5M_DATA, 16, "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" }, { KV5M_DATA, 5, "\0\0\0\2\x99" }, DERIVE_SP800_108_HMAC, { KV5M_DATA, 16, "\xB3\x1A\x01\x8A\x48\xF5\x47\x76\xF4\x03\xE9\xA3\x96\x32\x5D\xC3" } }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, { KV5M_DATA, 16, "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" }, { KV5M_DATA, 5, "\0\0\0\2\xAA" }, DERIVE_SP800_108_HMAC, { KV5M_DATA, 16, "\x9B\x19\x7D\xD1\xE8\xC5\x60\x9D\x6E\x67\xC3\xE3\x7C\x62\xC7\x2E" } }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, { KV5M_DATA, 16, "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" }, { KV5M_DATA, 5, "\0\0\0\2\x55" }, DERIVE_SP800_108_HMAC, { KV5M_DATA, 16, "\x9F\xDA\x0E\x56\xAB\x2D\x85\xE1\x56\x9A\x68\x86\x96\xC2\x6A\x6C" } }, /* Kc, Ke, Ki for an aes256-sha2 key. */ { ENCTYPE_AES256_CTS_HMAC_SHA384_192, { KV5M_DATA, 32, "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98" "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" }, { KV5M_DATA, 5, "\0\0\0\2\x99" }, DERIVE_SP800_108_HMAC, { KV5M_DATA, 24, "\xEF\x57\x18\xBE\x86\xCC\x84\x96\x3D\x8B\xBB\x50\x31\xE9\xF5\xC4" "\xBA\x41\xF2\x8F\xAF\x69\xE7\x3D" } }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, { KV5M_DATA, 32, "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98" "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" }, { KV5M_DATA, 5, "\0\0\0\2\xAA" }, DERIVE_SP800_108_HMAC, { KV5M_DATA, 32, "\x56\xAB\x22\xBE\xE6\x3D\x82\xD7\xBC\x52\x27\xF6\x77\x3F\x8E\xA7" "\xA5\xEB\x1C\x82\x51\x60\xC3\x83\x12\x98\x0C\x44\x2E\x5C\x7E\x49" } }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, { KV5M_DATA, 32, "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98" "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" }, { KV5M_DATA, 5, "\0\0\0\2\x55" }, DERIVE_SP800_108_HMAC, { KV5M_DATA, 24, "\x69\xB1\x65\x14\xE3\xCD\x8E\x56\xB8\x20\x10\xD5\xC7\x30\x12\xB6" "\x22\xC4\xD0\x0F\xFC\x23\xED\x1F" } }, }; static void printhex(const char *head, void *data, size_t len) { size_t i; printf("%s", head); for (i = 0; i < len; i++) { printf("%02X", ((unsigned char*)data)[i]); if (i % 16 == 15 && i + 1 < len) printf("\n%*s", (int)strlen(head), ""); else if (i + 1 < len) printf(" "); } printf("\n"); } static const struct krb5_enc_provider * get_enc_provider(krb5_enctype enctype) { switch (enctype) { case ENCTYPE_DES3_CBC_SHA1: return &krb5int_enc_des3; case ENCTYPE_AES128_CTS_HMAC_SHA1_96: return &krb5int_enc_aes128; case ENCTYPE_AES256_CTS_HMAC_SHA1_96: return &krb5int_enc_aes256; case ENCTYPE_CAMELLIA128_CTS_CMAC: return &krb5int_enc_camellia128; case ENCTYPE_CAMELLIA256_CTS_CMAC: return &krb5int_enc_camellia256; case ENCTYPE_AES128_CTS_HMAC_SHA256_128: return &krb5int_enc_aes128; case ENCTYPE_AES256_CTS_HMAC_SHA384_192: return &krb5int_enc_aes256; } abort(); } static const struct krb5_hash_provider * get_hash_provider(krb5_enctype enctype) { switch (enctype) { case ENCTYPE_AES128_CTS_HMAC_SHA256_128: return &krb5int_hash_sha256; case ENCTYPE_AES256_CTS_HMAC_SHA384_192: return &krb5int_hash_sha384; } return NULL; } int main(int argc, char **argv) { krb5_error_code ret; krb5_context context = NULL; size_t i; struct test *test; krb5_keyblock kb; krb5_key inkey = NULL, key = NULL; krb5_data rnd = empty_data(), outcmp; const struct krb5_enc_provider *enc; const struct krb5_hash_provider *hash; krb5_boolean verbose = FALSE; int status = 0; if (argc >= 2 && strcmp(argv[1], "-v") == 0) verbose = TRUE; for (i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) { test = &test_cases[i]; kb.magic = KV5M_KEYBLOCK; kb.enctype = test->enctype; kb.length = test->inkey.length; kb.contents = (unsigned char *)test->inkey.data; ret = krb5_k_create_key(context, &kb, &inkey); assert(!ret); enc = get_enc_provider(test->enctype); hash = get_hash_provider(test->enctype); if (test->expected_key.length == enc->keylength) { ret = krb5int_derive_key(enc, hash, inkey, &key, &test->constant, test->alg); assert(!ret); outcmp = make_data(key->keyblock.contents, key->keyblock.length); } else { ret = alloc_data(&rnd, test->expected_key.length); assert(!ret); ret = krb5int_derive_random(enc, hash, inkey, &rnd, &test->constant, test->alg); assert(!ret); outcmp = rnd; } if (verbose) { char buf[64]; krb5_enctype_to_name(test->enctype, FALSE, buf, sizeof(buf)); printf("\nTest %d:\n", (int)i); printf("Enctype: %s\n", buf); printhex("Input key: ", inkey->keyblock.contents, inkey->keyblock.length); printhex("Constant: ", test->constant.data, test->constant.length); printhex("Output: ", outcmp.data, outcmp.length); } assert(outcmp.length == test->expected_key.length); if (memcmp(outcmp.data, test->expected_key.data, outcmp.length) != 0) { printf("derive test %d failed\n", (int)i); status = 1; if (!verbose) break; } krb5_k_free_key(context, inkey); krb5_k_free_key(context, key); zapfree(rnd.data, rnd.length); inkey = key = NULL; rnd = empty_data(); } return status; } krb5-1.22.1/src/lib/crypto/crypto_tests/t_cf2.c0000664000175000017500000000660115051422640021124 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/crypto_tests/t_cf2.c */ /* * Copyright (C) 2004, 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This file contains tests for the KRB-FX-CF2 code in Kerberos, based on the * PRF regression tests. It reads an input file, and writes an output file. * It is assumed that the output file will be diffed against expected output to * see whether regression tests pass. The input file is a very primitive * format. * * Line 1: enctype * Line 2: key to pass to string2key; also used as salt * Line 3: second key to pass to string2key * Line 4: pepper1 * Line 5: pepper2 * * scanf is used to read the file, so interior spaces are not permitted. The * program outputs the hex bytes of the key. */ #include #include #include #include int main(void) { krb5_error_code ret; char pepper1[1025], pepper2[1025]; krb5_keyblock *k1 = NULL, *k2 = NULL, *out = NULL; krb5_data s2k; unsigned int i; while (1) { krb5_enctype enctype; char s[1025]; if (scanf( "%d", &enctype) == EOF) break; if (scanf("%1024s", &s[0]) == EOF) break; ret = krb5_init_keyblock(0, enctype, 0, &k1); assert(!ret); s2k.data = &s[0]; s2k.length = strlen(s); ret = krb5_c_string_to_key (0, enctype, &s2k, &s2k, k1); assert(!ret); if (scanf("%1024s", &s[0]) == EOF) break; ret = krb5_init_keyblock(0, enctype, 0, &k2); assert(!ret); s2k.data = &s[0]; s2k.length = strlen(s); ret = krb5_c_string_to_key (0, enctype, &s2k, &s2k, k2); assert(!ret); if (scanf("%1024s %1024s", pepper1, pepper2) == EOF) break; ret = krb5_c_fx_cf2_simple(0, k1, pepper1, k2, pepper2, &out); assert(!ret); i = out->length; for (; i > 0; i--) { printf ("%02x", (unsigned int) ((unsigned char) out->contents[out->length-i])); } printf ("\n"); krb5_free_keyblock(0,out); out = NULL; krb5_free_keyblock(0, k1); k1 = NULL; krb5_free_keyblock(0, k2); k2 = NULL; } return (0); } krb5-1.22.1/src/lib/crypto/crypto_tests/t_cf2.comments0000664000175000017500000000035615051422640022530 0ustar ghudsonghudsonThe first test mirrors the first two tests in t_prf.in. The second test mirrors the following four tests in t_prf.in. The third and fourth tests are simple tests of the DES and 3DES PRF. The fifth test is the same simple test for RC4. krb5-1.22.1/src/lib/crypto/deps0000664000175000017500000000003015051422640016065 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/lib/crypto/builtin/0000775000175000017500000000000015051422640016664 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/pbkdf2.c0000664000175000017500000001533215051422640020204 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/pbkdf2.c - Implementation of PBKDF2 from RFC 2898 */ /* * Copyright 2002, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include "crypto_int.h" #ifdef K5_BUILTIN_PBKDF2 /* * RFC 2898 specifies PBKDF2 in terms of an underlying pseudo-random * function with two arguments (password and salt||blockindex). Right * now we only use PBKDF2 with the hmac-sha1 PRF, also specified in * RFC 2898, which invokes HMAC with the password as the key and the * second argument as the text. (HMAC accepts any key size up to the * block size; the password is pre-hashed with unkeyed SHA1 if it is * longer than the block size.) * * For efficiency, it is better to generate the key from the password * once at the beginning, so we specify prf_fn in terms of a * krb5_key first argument. That might not be convenient for a PRF * which uses the password in some other way, so this might need to be * adjusted in the future. */ typedef krb5_error_code (*prf_fn)(krb5_key pass, krb5_data *salt, krb5_data *out); static int debug_hmac = 0; static void printd (const char *descr, krb5_data *d) { unsigned int i, j; const int r = 16; printf("%s:", descr); for (i = 0; i < d->length; i += r) { printf("\n %04x: ", i); for (j = i; j < i + r && j < d->length; j++) printf(" %02x", 0xff & d->data[j]); for (; j < i + r; j++) printf(" "); printf(" "); for (j = i; j < i + r && j < d->length; j++) { int c = 0xff & d->data[j]; printf("%c", isprint(c) ? c : '.'); } } printf("\n"); } /* * Implements the hmac-sha1 PRF. pass has been pre-hashed (if * necessary) and converted to a key already; salt has had the block * index appended to the original salt. * * NetBSD 8 declares an hmac() function in stdlib.h, so avoid that name. */ static krb5_error_code k5_hmac(const struct krb5_hash_provider *hash, krb5_keyblock *pass, krb5_data *salt, krb5_data *out) { krb5_error_code err; krb5_crypto_iov iov; if (debug_hmac) printd(" hmac input", salt); iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *salt; err = krb5int_hmac_keyblock(hash, pass, &iov, 1, out); if (err == 0 && debug_hmac) printd(" hmac output", out); return err; } static krb5_error_code F(char *output, char *u_tmp1, char *u_tmp2, const struct krb5_hash_provider *hash, size_t hlen, krb5_keyblock *pass, const krb5_data *salt, unsigned long count, int i) { unsigned char ibytes[4]; unsigned int j, k; krb5_data sdata; krb5_data out; krb5_error_code err; /* Compute U_1. */ store_32_be(i, ibytes); memcpy(u_tmp2, salt->data, salt->length); memcpy(u_tmp2 + salt->length, ibytes, 4); sdata = make_data(u_tmp2, salt->length + 4); out = make_data(u_tmp1, hlen); err = k5_hmac(hash, pass, &sdata, &out); if (err) return err; memcpy(output, u_tmp1, hlen); /* Compute U_2, .. U_c. */ sdata.length = hlen; for (j = 2; j <= count; j++) { memcpy(u_tmp2, u_tmp1, hlen); err = k5_hmac(hash, pass, &sdata, &out); if (err) return err; /* And xor them together. */ for (k = 0; k < hlen; k++) output[k] ^= u_tmp1[k]; } return 0; } static krb5_error_code pbkdf2(const struct krb5_hash_provider *hash, krb5_keyblock *pass, const krb5_data *salt, unsigned long count, const krb5_data *output) { size_t hlen = hash->hashsize; int l, i; char *utmp1, *utmp2; char utmp3[128]; /* XXX length shouldn't be hardcoded! */ if (output->length == 0 || hlen == 0) abort(); /* Step 1 & 2. */ if (output->length / hlen > 0xffffffff) abort(); /* Step 2. */ l = (output->length + hlen - 1) / hlen; utmp1 = /*output + dklen; */ malloc(hlen); if (utmp1 == NULL) return ENOMEM; utmp2 = /*utmp1 + hlen; */ malloc(salt->length + 4 + hlen); if (utmp2 == NULL) { free(utmp1); return ENOMEM; } /* Step 3. */ for (i = 1; i <= l; i++) { krb5_error_code err; char *out; if (i == l) out = utmp3; else out = output->data + (i-1) * hlen; err = F(out, utmp1, utmp2, hash, hlen, pass, salt, count, i); if (err) { free(utmp1); free(utmp2); return err; } if (i == l) memcpy(output->data + (i-1) * hlen, utmp3, output->length - (i-1) * hlen); } free(utmp1); free(utmp2); return 0; } krb5_error_code krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash, const krb5_data *out, unsigned long count, const krb5_data *pass, const krb5_data *salt) { krb5_keyblock keyblock; char tmp[128]; krb5_data d; krb5_crypto_iov iov; krb5_error_code err; assert(hash->hashsize <= sizeof(tmp)); if (pass->length > hash->blocksize) { d = make_data(tmp, hash->hashsize); iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *pass; err = hash->hash(&iov, 1, &d); if (err) return err; keyblock.length = d.length; keyblock.contents = (krb5_octet *) d.data; } else { keyblock.length = pass->length; keyblock.contents = (krb5_octet *) pass->data; } keyblock.enctype = ENCTYPE_NULL; err = pbkdf2(hash, &keyblock, salt, count, out); return err; } #endif /* K5_BUILTIN_PBKDF2 */ krb5-1.22.1/src/lib/crypto/builtin/sha2/0000775000175000017500000000000015051422640017521 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/sha2/Makefile.in0000664000175000017500000000076315051422640021574 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)builtin$(S)sha2 BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES=-I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLAGS) ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = builtin\sha2 ##DOS##OBJFILE = ..\..\$(OUTPRE)sha2.lst STLIBOBJS= sha256.o sha512.o OBJS= $(OUTPRE)sha256.$(OBJEXT) $(OUTPRE)sha512.$(OBJEXT) SRCS= $(srcdir)/sha256.c $(srcdir)/sha512.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs includes: depend depend: $(SRCS) clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/sha2/sha2.h0000664000175000017500000000537415051422640020540 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/sha2/sha2.h - SHA-256 declarations */ /* * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef SHA2_H #define SHA2_H 1 #include "crypto_int.h" #define SHA256_DIGEST_LENGTH 32 #define SHA384_DIGEST_LENGTH 48 #define SHA512_DIGEST_LENGTH 64 #define SHA256_BLOCK_SIZE 64 #define SHA384_BLOCK_SIZE 128 #define SHA512_BLOCK_SIZE 128 struct sha256state { unsigned int sz[2]; uint32_t counter[8]; unsigned char save[64]; }; struct sha512state { uint64_t sz[2]; uint64_t counter[8]; unsigned char save[128]; }; /* SHA-384 and SHA-512 use the same state object. */ typedef struct sha256state SHA256_CTX; typedef struct sha512state SHA384_CTX; typedef struct sha512state SHA512_CTX; void k5_sha256_init(SHA256_CTX *); void k5_sha256_update(SHA256_CTX *, const void *, size_t); void k5_sha256_final(void *, SHA256_CTX *); void k5_sha384_init(SHA384_CTX *); void k5_sha384_update(SHA384_CTX *, const void *, size_t); void k5_sha384_final(void *, SHA384_CTX *); void k5_sha512_init(SHA512_CTX *); void k5_sha512_update(SHA512_CTX *, const void *, size_t); void k5_sha512_final(void *, SHA512_CTX *); #endif /* SHA2_H */ krb5-1.22.1/src/lib/crypto/builtin/sha2/deps0000664000175000017500000000304615051422640020402 0ustar ghudsonghudson# # Generated makefile dependencies follow. # sha256.so sha256.po $(OUTPRE)sha256.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ sha2.h sha256.c sha512.so sha512.po $(OUTPRE)sha512.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ sha2.h sha512.c krb5-1.22.1/src/lib/crypto/builtin/sha2/sha256.c0000664000175000017500000001633715051422640020707 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/sha2/sha256.c - SHA-256 implementation */ /* * Copyright (c) 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "sha2.h" #ifdef K5_BUILTIN_SHA2 #ifdef K5_BE #define WORDS_BIGENDIAN #endif #ifndef min #define min(a,b) (((a)>(b))?(b):(a)) #endif /* Vector Crays doesn't have a good 32-bit type, or more precisely, * int32_t as defined by isn't 32 bits, and we don't * want to depend in being able to redefine this type. To cope with * this we have to clamp the result in some places to [0,2^32); no * need to do this on other machines. Did I say this was a mess? */ #ifdef _CRAY #define CRAYFIX(X) ((X) & 0xffffffff) #else #define CRAYFIX(X) (X) #endif static inline uint32_t cshift (uint32_t x, unsigned int n) { x = CRAYFIX(x); return CRAYFIX((x << n) | (x >> (32 - n))); } #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) #define ROTR(x,n) (((x)>>(n)) | ((x) << (32 - (n)))) #define Sigma0(x) (ROTR(x,2) ^ ROTR(x,13) ^ ROTR(x,22)) #define Sigma1(x) (ROTR(x,6) ^ ROTR(x,11) ^ ROTR(x,25)) #define sigma0(x) (ROTR(x,7) ^ ROTR(x,18) ^ ((x)>>3)) #define sigma1(x) (ROTR(x,17) ^ ROTR(x,19) ^ ((x)>>10)) #define A m->counter[0] #define B m->counter[1] #define C m->counter[2] #define D m->counter[3] #define E m->counter[4] #define F m->counter[5] #define G m->counter[6] #define H m->counter[7] static const uint32_t constant_256[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; void k5_sha256_init(SHA256_CTX *m) { m->sz[0] = 0; m->sz[1] = 0; A = 0x6a09e667; B = 0xbb67ae85; C = 0x3c6ef372; D = 0xa54ff53a; E = 0x510e527f; F = 0x9b05688c; G = 0x1f83d9ab; H = 0x5be0cd19; } static void calc(SHA256_CTX *m, uint32_t *in) { uint32_t AA, BB, CC, DD, EE, FF, GG, HH; uint32_t data[64]; int i; AA = A; BB = B; CC = C; DD = D; EE = E; FF = F; GG = G; HH = H; for (i = 0; i < 16; ++i) data[i] = in[i]; for (i = 16; i < 64; ++i) data[i] = sigma1(data[i-2]) + data[i-7] + sigma0(data[i-15]) + data[i - 16]; for (i = 0; i < 64; i++) { uint32_t T1, T2; T1 = HH + Sigma1(EE) + Ch(EE, FF, GG) + constant_256[i] + data[i]; T2 = Sigma0(AA) + Maj(AA,BB,CC); HH = GG; GG = FF; FF = EE; EE = DD + T1; DD = CC; CC = BB; BB = AA; AA = T1 + T2; } A += AA; B += BB; C += CC; D += DD; E += EE; F += FF; G += GG; H += HH; } /* * From `Performance analysis of MD5' by Joseph D. Touch */ #if !defined(WORDS_BIGENDIAN) || defined(_CRAY) static inline uint32_t swap_uint32_t(uint32_t t) { #define ROL(x,n) ((x)<<(n))|((x)>>(32-(n))) uint32_t temp1, temp2; temp1 = cshift(t, 16); temp2 = temp1 >> 8; temp1 &= 0x00ff00ff; temp2 &= 0x00ff00ff; temp1 <<= 8; return temp1 | temp2; } #endif struct x32 { unsigned int a:32; unsigned int b:32; }; void k5_sha256_update(SHA256_CTX *m, const void *v, size_t len) { const unsigned char *p = v; size_t old_sz = m->sz[0]; size_t offset; m->sz[0] += len * 8; if (m->sz[0] < old_sz) ++m->sz[1]; offset = (old_sz / 8) % 64; while(len > 0){ size_t l = min(len, 64 - offset); memcpy(m->save + offset, p, l); offset += l; p += l; len -= l; if(offset == 64){ #if !defined(WORDS_BIGENDIAN) || defined(_CRAY) int i; uint32_t current[16]; struct x32 *u = (struct x32*)(void*)m->save; for(i = 0; i < 8; i++){ current[2*i+0] = swap_uint32_t(u[i].a); current[2*i+1] = swap_uint32_t(u[i].b); } calc(m, current); #else calc(m, (uint32_t*)(void*)m->save); #endif offset = 0; } } } void k5_sha256_final(void *res, SHA256_CTX *m) { unsigned char zeros[72]; unsigned offset = (m->sz[0] / 8) % 64; unsigned int dstart = (120 - offset - 1) % 64 + 1; *zeros = 0x80; memset (zeros + 1, 0, sizeof(zeros) - 1); zeros[dstart+7] = (m->sz[0] >> 0) & 0xff; zeros[dstart+6] = (m->sz[0] >> 8) & 0xff; zeros[dstart+5] = (m->sz[0] >> 16) & 0xff; zeros[dstart+4] = (m->sz[0] >> 24) & 0xff; zeros[dstart+3] = (m->sz[1] >> 0) & 0xff; zeros[dstart+2] = (m->sz[1] >> 8) & 0xff; zeros[dstart+1] = (m->sz[1] >> 16) & 0xff; zeros[dstart+0] = (m->sz[1] >> 24) & 0xff; k5_sha256_update(m, zeros, dstart + 8); { int i; unsigned char *r = (unsigned char*)res; for (i = 0; i < 8; ++i) { r[4*i+3] = m->counter[i] & 0xFF; r[4*i+2] = (m->counter[i] >> 8) & 0xFF; r[4*i+1] = (m->counter[i] >> 16) & 0xFF; r[4*i] = (m->counter[i] >> 24) & 0xFF; } } } krb5_error_code k5_sha256(const krb5_data *in, size_t n, uint8_t out[K5_SHA256_HASHLEN]) { SHA256_CTX ctx; size_t i; k5_sha256_init(&ctx); for (i = 0; i < n; i++) k5_sha256_update(&ctx, in[i].data, in[i].length); k5_sha256_final(out, &ctx); return 0; } #endif /* K5_BUILTIN_SHA2 */ krb5-1.22.1/src/lib/crypto/builtin/sha2/sha512.c0000664000175000017500000002150715051422640020675 0ustar ghudsonghudson/* * Copyright (c) 2006, 2010 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "sha2.h" #ifdef K5_BUILTIN_SHA2 #ifdef K5_BE #define WORDS_BIGENDIAN #endif #ifndef min #define min(a,b) (((a)>(b))?(b):(a)) #endif #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) #define ROTR(x,n) (((x)>>(n)) | ((x) << (64 - (n)))) #define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) #define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) #define sigma0(x) (ROTR(x,1) ^ ROTR(x,8) ^ ((x)>>7)) #define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ ((x)>>6)) #define A m->counter[0] #define B m->counter[1] #define C m->counter[2] #define D m->counter[3] #define E m->counter[4] #define F m->counter[5] #define G m->counter[6] #define H m->counter[7] static const uint64_t constant_512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; static inline uint64_t cshift64 (uint64_t x, unsigned int n) { return ((uint64_t)x << (uint64_t)n) | ((uint64_t)x >> ((uint64_t)64 - (uint64_t)n)); } void k5_sha512_init (SHA512_CTX *m) { m->sz[0] = 0; m->sz[1] = 0; A = 0x6a09e667f3bcc908ULL; B = 0xbb67ae8584caa73bULL; C = 0x3c6ef372fe94f82bULL; D = 0xa54ff53a5f1d36f1ULL; E = 0x510e527fade682d1ULL; F = 0x9b05688c2b3e6c1fULL; G = 0x1f83d9abfb41bd6bULL; H = 0x5be0cd19137e2179ULL; } static void calc (SHA512_CTX *m, uint64_t *in) { uint64_t AA, BB, CC, DD, EE, FF, GG, HH; uint64_t data[80]; int i; AA = A; BB = B; CC = C; DD = D; EE = E; FF = F; GG = G; HH = H; for (i = 0; i < 16; ++i) data[i] = in[i]; for (i = 16; i < 80; ++i) data[i] = sigma1(data[i-2]) + data[i-7] + sigma0(data[i-15]) + data[i - 16]; for (i = 0; i < 80; i++) { uint64_t T1, T2; T1 = HH + Sigma1(EE) + Ch(EE, FF, GG) + constant_512[i] + data[i]; T2 = Sigma0(AA) + Maj(AA,BB,CC); HH = GG; GG = FF; FF = EE; EE = DD + T1; DD = CC; CC = BB; BB = AA; AA = T1 + T2; } A += AA; B += BB; C += CC; D += DD; E += EE; F += FF; G += GG; H += HH; } /* * From `Performance analysis of MD5' by Joseph D. Touch */ #if !defined(WORDS_BIGENDIAN) || defined(_CRAY) static inline uint64_t swap_uint64_t (uint64_t t) { uint64_t temp; temp = cshift64(t, 32); temp = ((temp & 0xff00ff00ff00ff00ULL) >> 8) | ((temp & 0x00ff00ff00ff00ffULL) << 8); return ((temp & 0xffff0000ffff0000ULL) >> 16) | ((temp & 0x0000ffff0000ffffULL) << 16); } struct x64{ uint64_t a; uint64_t b; }; #endif void k5_sha512_update (SHA512_CTX *m, const void *v, size_t len) { const unsigned char *p = v; size_t old_sz = m->sz[0]; size_t offset; m->sz[0] += len * 8; if (m->sz[0] < old_sz) ++m->sz[1]; offset = (old_sz / 8) % 128; while(len > 0){ size_t l = min(len, 128 - offset); memcpy(m->save + offset, p, l); offset += l; p += l; len -= l; if(offset == 128){ #if !defined(WORDS_BIGENDIAN) || defined(_CRAY) int i; uint64_t current[16]; struct x64 *us = (struct x64*)(void*)m->save; for(i = 0; i < 8; i++){ current[2*i+0] = swap_uint64_t(us[i].a); current[2*i+1] = swap_uint64_t(us[i].b); } calc(m, current); #else calc(m, (uint64_t*)(void*)m->save); #endif offset = 0; } } } void k5_sha512_final (void *res, SHA512_CTX *m) { unsigned char zeros[128 + 16]; unsigned offset = (m->sz[0] / 8) % 128; unsigned int dstart = (240 - offset - 1) % 128 + 1; *zeros = 0x80; memset (zeros + 1, 0, sizeof(zeros) - 1); zeros[dstart+15] = (m->sz[0] >> 0) & 0xff; zeros[dstart+14] = (m->sz[0] >> 8) & 0xff; zeros[dstart+13] = (m->sz[0] >> 16) & 0xff; zeros[dstart+12] = (m->sz[0] >> 24) & 0xff; zeros[dstart+11] = (m->sz[0] >> 32) & 0xff; zeros[dstart+10] = (m->sz[0] >> 40) & 0xff; zeros[dstart+9] = (m->sz[0] >> 48) & 0xff; zeros[dstart+8] = (m->sz[0] >> 56) & 0xff; zeros[dstart+7] = (m->sz[1] >> 0) & 0xff; zeros[dstart+6] = (m->sz[1] >> 8) & 0xff; zeros[dstart+5] = (m->sz[1] >> 16) & 0xff; zeros[dstart+4] = (m->sz[1] >> 24) & 0xff; zeros[dstart+3] = (m->sz[1] >> 32) & 0xff; zeros[dstart+2] = (m->sz[1] >> 40) & 0xff; zeros[dstart+1] = (m->sz[1] >> 48) & 0xff; zeros[dstart+0] = (m->sz[1] >> 56) & 0xff; k5_sha512_update (m, zeros, dstart + 16); { int i; unsigned char *r = (unsigned char*)res; for (i = 0; i < 8; ++i) { r[8*i+7] = m->counter[i] & 0xFF; r[8*i+6] = (m->counter[i] >> 8) & 0xFF; r[8*i+5] = (m->counter[i] >> 16) & 0xFF; r[8*i+4] = (m->counter[i] >> 24) & 0xFF; r[8*i+3] = (m->counter[i] >> 32) & 0XFF; r[8*i+2] = (m->counter[i] >> 40) & 0xFF; r[8*i+1] = (m->counter[i] >> 48) & 0xFF; r[8*i] = (m->counter[i] >> 56) & 0xFF; } } } void k5_sha384_init (SHA384_CTX *m) { m->sz[0] = 0; m->sz[1] = 0; A = 0xcbbb9d5dc1059ed8ULL; B = 0x629a292a367cd507ULL; C = 0x9159015a3070dd17ULL; D = 0x152fecd8f70e5939ULL; E = 0x67332667ffc00b31ULL; F = 0x8eb44a8768581511ULL; G = 0xdb0c2e0d64f98fa7ULL; H = 0x47b5481dbefa4fa4ULL; } void k5_sha384_update (SHA384_CTX *m, const void *v, size_t len) { k5_sha512_update(m, v, len); } void k5_sha384_final (void *res, SHA384_CTX *m) { unsigned char data[SHA512_DIGEST_LENGTH]; k5_sha512_final(data, m); memcpy(res, data, SHA384_DIGEST_LENGTH); } #endif /* K5_BUILTIN_SHA2 */ krb5-1.22.1/src/lib/crypto/builtin/hash_provider/0000775000175000017500000000000015051422640021521 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/hash_provider/hash_md5.c0000664000175000017500000000407515051422640023363 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" #include "rsa-md5.h" #ifdef K5_BUILTIN_MD5 static krb5_error_code k5_md5_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_MD5_CTX ctx; unsigned int i; if (output->length != RSA_MD5_CKSUM_LENGTH) return KRB5_CRYPTO_INTERNAL; krb5int_MD5Init(&ctx); for (i = 0; i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (SIGN_IOV(iov)) { krb5int_MD5Update(&ctx, (unsigned char *) iov->data.data, iov->data.length); } } krb5int_MD5Final(&ctx); memcpy(output->data, ctx.digest, RSA_MD5_CKSUM_LENGTH); return 0; } const struct krb5_hash_provider krb5int_hash_md5 = { "MD5", RSA_MD5_CKSUM_LENGTH, 64, k5_md5_hash }; #endif /* K5_BUILTIN_MD5 */ krb5-1.22.1/src/lib/crypto/builtin/hash_provider/Makefile.in0000664000175000017500000000144315051422640023570 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)builtin$(S)hash_provider BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../krb -I$(srcdir)/../md4 \ -I$(srcdir)/../md5 -I$(srcdir)/../sha1 -I$(srcdir)/../sha2 \ $(CRYPTO_IMPL_CFLAGS) ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = builtin\hash_provider ##DOS##OBJFILE = ..\..\$(OUTPRE)hash_provider.lst STLIBOBJS= \ hash_md4.o \ hash_md5.o \ hash_sha1.o \ hash_sha2.o OBJS= $(OUTPRE)hash_md4.$(OBJEXT) \ $(OUTPRE)hash_md5.$(OBJEXT) \ $(OUTPRE)hash_sha1.$(OBJEXT) \ $(OUTPRE)hash_sha2.$(OBJEXT) SRCS= $(srcdir)/hash_md4.c \ $(srcdir)/hash_md5.c \ $(srcdir)/hash_sha1.c \ $(srcdir)/hash_sha2.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs includes: depend depend: $(SRCS) clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/hash_provider/hash_sha1.c0000664000175000017500000000413215051422640023524 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" #include "shs.h" #ifdef K5_BUILTIN_SHA1 static krb5_error_code k5_sha1_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { SHS_INFO ctx; unsigned int i; if (output->length != SHS_DIGESTSIZE) return KRB5_CRYPTO_INTERNAL; shsInit(&ctx); for (i = 0; i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (SIGN_IOV(iov)) { shsUpdate(&ctx, (unsigned char *) iov->data.data, iov->data.length); } } shsFinal(&ctx); for (i = 0; i < sizeof(ctx.digest) / sizeof(ctx.digest[0]); i++) store_32_be(ctx.digest[i], &output->data[i*4]); return 0; } const struct krb5_hash_provider krb5int_hash_sha1 = { "SHA1", SHS_DIGESTSIZE, SHS_DATASIZE, k5_sha1_hash }; #endif /* K5_BUILTIN_SHA1 */ krb5-1.22.1/src/lib/crypto/builtin/hash_provider/deps0000664000175000017500000000624115051422640022402 0ustar ghudsonghudson# # Generated makefile dependencies follow. # hash_md4.so hash_md4.po $(OUTPRE)hash_md4.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../md4/rsa-md4.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hash_md4.c hash_md5.so hash_md5.po $(OUTPRE)hash_md5.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../md5/rsa-md5.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hash_md5.c hash_sha1.so hash_sha1.po $(OUTPRE)hash_sha1.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../sha1/shs.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hash_sha1.c hash_sha2.so hash_sha2.po $(OUTPRE)hash_sha2.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../sha2/sha2.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hash_sha2.c krb5-1.22.1/src/lib/crypto/builtin/hash_provider/hash_sha2.c0000664000175000017500000000557515051422640023541 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/hash_provider/sha2.c - SHA-2 hash providers */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "crypto_int.h" #include "sha2.h" #ifdef K5_BUILTIN_SHA2 static krb5_error_code k5_sha256_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { SHA256_CTX ctx; size_t i; const krb5_crypto_iov *iov; if (output->length != SHA256_DIGEST_LENGTH) return KRB5_CRYPTO_INTERNAL; k5_sha256_init(&ctx); for (i = 0; i < num_data; i++) { iov = &data[i]; if (SIGN_IOV(iov)) k5_sha256_update(&ctx, iov->data.data, iov->data.length); } k5_sha256_final(output->data, &ctx); return 0; } static krb5_error_code k5_sha384_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { SHA384_CTX ctx; size_t i; const krb5_crypto_iov *iov; if (output->length != SHA384_DIGEST_LENGTH) return KRB5_CRYPTO_INTERNAL; k5_sha384_init(&ctx); for (i = 0; i < num_data; i++) { iov = &data[i]; if (SIGN_IOV(iov)) k5_sha384_update(&ctx, iov->data.data, iov->data.length); } k5_sha384_final(output->data, &ctx); return 0; } const struct krb5_hash_provider krb5int_hash_sha256 = { "SHA-256", SHA256_DIGEST_LENGTH, SHA256_BLOCK_SIZE, k5_sha256_hash }; const struct krb5_hash_provider krb5int_hash_sha384 = { "SHA-384", SHA384_DIGEST_LENGTH, SHA384_BLOCK_SIZE, k5_sha384_hash }; #endif /* K5_BUILTIN_SHA2 */ krb5-1.22.1/src/lib/crypto/builtin/hash_provider/hash_md4.c0000664000175000017500000000407715051422640023364 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" #include "rsa-md4.h" #ifdef K5_BUILTIN_MD4 static krb5_error_code k5_md4_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_MD4_CTX ctx; unsigned int i; if (output->length != RSA_MD4_CKSUM_LENGTH) return(KRB5_CRYPTO_INTERNAL); krb5int_MD4Init(&ctx); for (i = 0; i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (SIGN_IOV(iov)) { krb5int_MD4Update(&ctx, (unsigned char *) iov->data.data, iov->data.length); } } krb5int_MD4Final(&ctx); memcpy(output->data, ctx.digest, RSA_MD4_CKSUM_LENGTH); return(0); } const struct krb5_hash_provider krb5int_hash_md4 = { "MD4", RSA_MD4_CKSUM_LENGTH, 64, k5_md4_hash }; #endif /* K5_BUILTIN_MD4 */ krb5-1.22.1/src/lib/crypto/builtin/Makefile.in0000664000175000017500000000157715051422640020743 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)builtin BUILDTOP=$(REL)..$(S)..$(S).. SUBDIRS=camellia des aes md4 md5 sha1 sha2 enc_provider hash_provider LOCALINCLUDES=-I$(srcdir)/../krb $(CRYPTO_IMPL_CFLAGS) ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR = builtin ##DOS##OBJFILE = ..\$(OUTPRE)builtin.lst STLIBOBJS=\ cmac.o \ hmac.o \ kdf.o \ pbkdf2.o OBJS=\ $(OUTPRE)cmac.$(OBJEXT) \ $(OUTPRE)hmac.$(OBJEXT) \ $(OUTPRE)kdf.$(OBJEXT) \ $(OUTPRE)pbkdf2.$(OBJEXT) SRCS=\ $(srcdir)/cmac.c \ $(srcdir)/hmac.c \ $(srcdir)/kdf.c \ $(srcdir)/pbkdf2.c SUBDIROBJLISTS= des/OBJS.ST md4/OBJS.ST \ md5/OBJS.ST sha1/OBJS.ST sha2/OBJS.ST \ enc_provider/OBJS.ST \ hash_provider/OBJS.ST \ aes/OBJS.ST \ camellia/OBJS.ST STOBJLISTS= $(SUBDIROBJLISTS) OBJS.ST ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs includes: depend depend: $(SRCS) clean-unix:: clean-libobjs @lib_frag@ @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/aes/0000775000175000017500000000000015051422640017434 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/aes/aes.h0000664000175000017500000002317715051422640020367 0ustar ghudsonghudson/* --------------------------------------------------------------------------- Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. --------------------------------------------------------------------------- Issue Date: 02/09/2018 This file contains the definitions required to use AES in C. See aesopt.h for optimisation details. */ #ifndef _AES_H #define _AES_H /* For MIT krb5, give the linker-visible symbols a prefix. */ #define aes_decrypt k5_aes_decrypt #define aes_decrypt_key k5_aes_decrypt_key #define aes_decrypt_key128 k5_aes_decrypt_key128 #define aes_decrypt_key256 k5_aes_decrypt_key256 #define aes_encrypt k5_aes_encrypt #define aes_encrypt_key k5_aes_encrypt_key #define aes_encrypt_key128 k5_aes_encrypt_key128 #define aes_encrypt_key256 k5_aes_encrypt_key256 #define aes_init k5_aes_init #include /* This include is used to find 8 & 32 bit unsigned integer types */ #include "brg_types.h" #if defined(__cplusplus) extern "C" { #endif #define AES_128 /* if a fast 128 bit key scheduler is needed */ #undef AES_192 /* if a fast 192 bit key scheduler is needed */ #define AES_256 /* if a fast 256 bit key scheduler is needed */ #define AES_VAR /* if variable key size scheduler is needed */ #if 1 # define AES_MODES /* if support is needed for modes in the C code */ #endif /* (these will use AES_NI if it is present) */ #if 0 /* add this to make direct calls to the AES_NI */ # /* implemented CBC and CTR modes available */ # define ADD_AESNI_MODE_CALLS #endif /* The following must also be set in assembler files if being used */ #define AES_ENCRYPT /* if support for encryption is needed */ #define AES_DECRYPT /* if support for decryption is needed */ #define AES_BLOCK_SIZE_P2 4 /* AES block size as a power of 2 */ #define AES_BLOCK_SIZE (1 << AES_BLOCK_SIZE_P2) /* AES block size */ #define N_COLS 4 /* the number of columns in the state */ /* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */ /* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */ /* or 44, 52 or 60 32-bit words. */ #if defined( AES_VAR ) || defined( AES_256 ) #define KS_LENGTH 60 #elif defined( AES_192 ) #define KS_LENGTH 52 #else #define KS_LENGTH 44 #endif #define AES_RETURN INT_RETURN /* the character array 'inf' in the following structures is used */ /* to hold AES context information. This AES code uses cx->inf.b[0] */ /* to hold the number of rounds multiplied by 16. The other three */ /* elements can be used by code that implements additional modes */ typedef union { uint32_t l; uint8_t b[4]; } aes_inf; /* Macros for detecting whether a given context was initialized for */ /* use with encryption or decryption code. These should only be used */ /* by e.g. language bindings which lose type information when the */ /* context pointer is passed to the calling language's runtime. */ #define IS_ENCRYPTION_CTX(cx) (((cx)->inf.b[2] & (uint8_t)0x01) == 1) #define IS_DECRYPTION_CTX(cx) (((cx)->inf.b[2] & (uint8_t)0x01) == 0) #ifdef _MSC_VER # pragma warning( disable : 4324 ) #endif #if defined(_MSC_VER) && defined(_WIN64) #define ALIGNED_(x) __declspec(align(x)) #elif defined(__GNUC__) && defined(__x86_64__) #define ALIGNED_(x) __attribute__ ((aligned(x))) #else #define ALIGNED_(x) #endif typedef struct ALIGNED_(16) { uint32_t ks[KS_LENGTH]; aes_inf inf; } aes_crypt_ctx; typedef aes_crypt_ctx aes_encrypt_ctx; typedef aes_crypt_ctx aes_decrypt_ctx; #ifdef _MSC_VER # pragma warning( default : 4324 ) #endif /* This routine must be called before first use if non-static */ /* tables are being used */ AES_RETURN aes_init(void); /* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */ /* those in the range 128 <= key_len <= 256 are given in bits */ #if defined( AES_ENCRYPT ) #if defined( AES_128 ) || defined( AES_VAR) AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); #endif #if defined( AES_192 ) || defined( AES_VAR) AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); #endif #if defined( AES_256 ) || defined( AES_VAR) AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); #endif #if defined( AES_VAR ) AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]); #endif AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]); #endif #if defined( AES_DECRYPT ) #if defined( AES_128 ) || defined( AES_VAR) AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); #endif #if defined( AES_192 ) || defined( AES_VAR) AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); #endif #if defined( AES_256 ) || defined( AES_VAR) AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); #endif #if defined( AES_VAR ) AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]); #endif AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]); #endif #if defined( AES_MODES ) /* Multiple calls to the following subroutines for multiple block */ /* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */ /* long messages incrementally provided that the context AND the iv */ /* are preserved between all such calls. For the ECB and CBC modes */ /* each individual call within a series of incremental calls must */ /* process only full blocks (i.e. len must be a multiple of 16) but */ /* the CFB, OFB and CTR mode calls can handle multiple incremental */ /* calls of any length. Each mode is reset when a new AES key is */ /* set but ECB needs no reset and CBC can be reset without setting */ /* a new key by setting a new IV value. To reset CFB, OFB and CTR */ /* without setting the key, aes_mode_reset() must be called and the */ /* IV must be set. NOTE: All these calls update the IV on exit so */ /* this has to be reset if a new operation with the same IV as the */ /* previous one is required (or decryption follows encryption with */ /* the same IV array). */ AES_RETURN aes_test_alignment_detection(unsigned int n); AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, const aes_encrypt_ctx cx[1]); AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, const aes_decrypt_ctx cx[1]); AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, const aes_encrypt_ctx cx[1]); AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, const aes_decrypt_ctx cx[1]); AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]); AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]); AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]); #define aes_ofb_encrypt aes_ofb_crypt #define aes_ofb_decrypt aes_ofb_crypt AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]); typedef void cbuf_inc(unsigned char *cbuf); #define aes_ctr_encrypt aes_ctr_crypt #define aes_ctr_decrypt aes_ctr_crypt AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]); #endif #if 0 && defined( ADD_AESNI_MODE_CALLS ) # define USE_AES_CONTEXT #endif #ifdef ADD_AESNI_MODE_CALLS # ifdef USE_AES_CONTEXT AES_RETURN aes_CBC_encrypt(const unsigned char *in, unsigned char *out, unsigned char ivec[16], unsigned long length, const aes_encrypt_ctx cx[1]); AES_RETURN aes_CBC_decrypt(const unsigned char *in, unsigned char *out, unsigned char ivec[16], unsigned long length, const aes_decrypt_ctx cx[1]); AES_RETURN AES_CTR_encrypt(const unsigned char *in, unsigned char *out, const unsigned char ivec[8], const unsigned char nonce[4], unsigned long length, const aes_encrypt_ctx cx[1]); # else void aes_CBC_encrypt(const unsigned char *in, unsigned char *out, unsigned char ivec[16], unsigned long length, unsigned char *key, int number_of_rounds); void aes_CBC_decrypt(const unsigned char *in, unsigned char *out, unsigned char ivec[16], unsigned long length, unsigned char *key, int number_of_rounds); void aes_CTR_encrypt(const unsigned char *in, unsigned char *out, const unsigned char ivec[8], const unsigned char nonce[4], unsigned long length, const unsigned char *key, int number_of_rounds); # endif #endif #if defined(__cplusplus) } #endif #endif krb5-1.22.1/src/lib/crypto/builtin/aes/kresults.expected0000664000175000017500000001555315051422640023044 0ustar ghudsonghudsonFIPS test: key: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F input: 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF output: 69 C4 E0 D8 6A 7B 04 30 D8 CD B7 80 70 B4 C5 5A ok. ECB tests: key: 46 64 31 29 64 86 ED 9C D7 1F C2 07 25 48 20 A2 test 0 - 32 bytes input: C4 A8 5A EB 0B 20 41 49 4F 8B F1 F8 CD 30 F1 13 94 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 output: 1B 39 DA 37 40 D3 DF FE AC 89 D6 BB 4C 29 F1 0A E1 43 64 CB 16 D3 FF CF E8 FA 6A 2C EC A2 69 34 test 1 - 32 bytes input: 22 3C F8 A8 29 95 80 49 57 87 6E 9F A7 11 63 50 6B 4E 5B 8C 8F A4 DB 1B 95 D3 E8 C5 C5 FB 5A 00 output: F3 B2 BB 53 D6 F4 A3 AE 9E EB B1 3D B2 F7 E9 90 83 FE B6 7B 73 4F CE DB 8E 97 D4 06 96 11 B7 23 test 2 - 32 bytes input: E7 37 52 90 60 E7 10 A9 3E 97 18 DD 3E 29 41 8E 94 8F E9 20 1F 8D FB 3A 22 CF 22 E8 94 1D 42 7B output: 25 4F 90 96 01 9B 09 27 5E FF 95 69 E0 70 DC 50 A3 D1 6F E1 EF 7B 6D 2F 4F 93 48 90 02 0D F1 8A test 3 - 48 bytes input: 54 94 0B B4 7C 1B 5E BA B2 76 98 F1 9F D9 7F 33 68 69 54 87 F6 4F C1 19 1E E3 01 B2 00 43 2E 54 D7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 output: D3 7F 6D 39 57 32 A6 C5 A4 49 F4 4B C6 EE 0A E0 86 D8 A3 C0 E5 6D BB 39 5F C0 CC 0A DA 8F 87 C6 14 C1 8E 34 7A A8 2F BB EA 53 F0 7A 64 53 5B 28 test 4 - 48 bytes input: 39 09 53 55 67 0E 07 DD A6 F8 7C 7F 78 AF E7 E1 03 6F D7 53 30 F0 71 14 F1 24 14 34 52 69 0C 8B 72 5F E0 D9 6D E8 B6 13 E0 32 92 58 E1 7A 39 00 output: AD 96 1C 40 05 54 CB 0E 37 32 AE 2C 64 DB EF 8E B5 76 2B EE F3 A1 04 A1 E0 3F FE CA 17 7B 4C 91 53 2F B3 16 33 48 27 D6 49 62 E8 77 10 DC 46 E6 test 5 - 48 bytes input: E5 E9 11 38 19 01 A9 2D F3 CD 42 27 1F AB 33 AB 1D 93 8B F6 00 73 AC 14 54 DE A6 AC BF 20 E6 A4 09 F7 DC 23 F8 86 50 EB 53 92 13 73 3D 46 1E 5A output: 1A 03 F3 10 7A F0 62 07 D1 22 60 2B 9E 07 D0 8D FE 7A E7 E7 DF 7F 12 C6 5E 29 F9 A2 55 C0 93 F1 FF AC 97 44 E1 C0 C7 39 F8 7A 4B F8 ED 01 58 6B test 6 - 64 bytes input: D9 A9 50 DA 1D FC EE 71 DA 94 1D 9A B5 03 3E BE FA 1B E1 F3 A1 32 DE F4 C4 F1 67 02 38 85 5C 11 2F AD EB 4C A9 D9 BD 84 6E DA 1E 23 DE 5C E1 D8 77 C3 CB 18 F5 AA 0D B9 9B 74 BB D3 FA 18 E5 29 output: D0 18 22 59 85 05 AB 87 0D 9D D0 99 7B 15 CC 43 4D C5 13 1B B5 3E 8F 4E B4 75 FC A5 E5 47 94 7F 14 68 15 F7 6D F1 9E 12 B8 81 39 06 3C 3D F5 44 83 BE 19 E3 3E 68 15 A0 50 93 03 73 0C 99 52 C3 CBC tests: initial vector: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 test 0 - 32 bytes input: C4 A8 5A EB 0B 20 41 49 4F 8B F1 F8 CD 30 F1 13 94 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 output: 1B 39 DA 37 40 D3 DF FE AC 89 D6 BB 4C 29 F1 0A D4 3C 74 F5 5B 8B 3E CF 67 F8 F7 00 03 27 8A 91 test 1 - 32 bytes input: 22 3C F8 A8 29 95 80 49 57 87 6E 9F A7 11 63 50 6B 4E 5B 8C 8F A4 DB 1B 95 D3 E8 C5 C5 FB 5A 00 output: F3 B2 BB 53 D6 F4 A3 AE 9E EB B1 3D B2 F7 E9 90 54 03 C8 DF 5F 11 82 94 93 4E B3 4B F9 B5 39 D1 test 2 - 32 bytes input: E7 37 52 90 60 E7 10 A9 3E 97 18 DD 3E 29 41 8E 94 8F E9 20 1F 8D FB 3A 22 CF 22 E8 94 1D 42 7B output: 25 4F 90 96 01 9B 09 27 5E FF 95 69 E0 70 DC 50 D7 7C 5F B0 DA F7 80 2E 3F 3A 2E B7 5D F0 B3 23 test 3 - 48 bytes input: 54 94 0B B4 7C 1B 5E BA B2 76 98 F1 9F D9 7F 33 68 69 54 87 F6 4F C1 19 1E E3 01 B2 00 43 2E 54 D7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 output: D3 7F 6D 39 57 32 A6 C5 A4 49 F4 4B C6 EE 0A E0 88 D0 90 16 44 A7 38 01 63 5D BE 56 9E C3 78 7A 51 6F 31 69 BF 9C 75 AD A1 C6 66 A6 1B A2 38 0D test 4 - 48 bytes input: 39 09 53 55 67 0E 07 DD A6 F8 7C 7F 78 AF E7 E1 03 6F D7 53 30 F0 71 14 F1 24 14 34 52 69 0C 8B 72 5F E0 D9 6D E8 B6 13 E0 32 92 58 E1 7A 39 00 output: AD 96 1C 40 05 54 CB 0E 37 32 AE 2C 64 DB EF 8E F0 68 8B 66 32 FE 41 EF 11 51 1B 6E F0 C0 17 96 A1 BD F6 34 5D F3 BC 03 86 72 D0 C3 13 FE C3 95 test 5 - 48 bytes input: E5 E9 11 38 19 01 A9 2D F3 CD 42 27 1F AB 33 AB 1D 93 8B F6 00 73 AC 14 54 DE A6 AC BF 20 E6 A4 09 F7 DC 23 F8 86 50 EB 53 92 13 73 3D 46 1E 5A output: 1A 03 F3 10 7A F0 62 07 D1 22 60 2B 9E 07 D0 8D 22 F4 2B 92 92 D4 D5 E7 EA 90 72 9F 03 31 10 1F 65 DE 01 93 8B 51 17 F8 32 6F 4B 05 AF 02 E2 3D test 6 - 64 bytes input: D9 A9 50 DA 1D FC EE 71 DA 94 1D 9A B5 03 3E BE FA 1B E1 F3 A1 32 DE F4 C4 F1 67 02 38 85 5C 11 2F AD EB 4C A9 D9 BD 84 6E DA 1E 23 DE 5C E1 D8 77 C3 CB 18 F5 AA 0D B9 9B 74 BB D3 FA 18 E5 29 output: D0 18 22 59 85 05 AB 87 0D 9D D0 99 7B 15 CC 43 F7 43 1B BF 3C 7D A0 21 1E 3D 3F 6A 4D 8A CE 08 37 9D EB CD 52 52 3B C5 76 02 7D 35 19 76 05 7D 76 22 5A 42 DF 73 CB 5D CE 88 C3 4C CE 92 00 E6 CTS tests: initial vector: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 test 0 - 17 bytes input: C4 A8 5A EB 0B 20 41 49 4F 8B F1 F8 CD 30 F1 13 94 (did CBC mode for 0) output: D4 3C 74 F5 5B 8B 3E CF 67 F8 F7 00 03 27 8A 91 1B test 1 - 31 bytes input: 22 3C F8 A8 29 95 80 49 57 87 6E 9F A7 11 63 50 6B 4E 5B 8C 8F A4 DB 1B 95 D3 E8 C5 C5 FB 5A (did CBC mode for 0) output: 54 03 C8 DF 5F 11 82 94 93 4E B3 4B F9 B5 39 D1 F3 B2 BB 53 D6 F4 A3 AE 9E EB B1 3D B2 F7 E9 test 2 - 32 bytes input: E7 37 52 90 60 E7 10 A9 3E 97 18 DD 3E 29 41 8E 94 8F E9 20 1F 8D FB 3A 22 CF 22 E8 94 1D 42 7B (did CBC mode for 0) output: D7 7C 5F B0 DA F7 80 2E 3F 3A 2E B7 5D F0 B3 23 25 4F 90 96 01 9B 09 27 5E FF 95 69 E0 70 DC 50 test 3 - 33 bytes input: 54 94 0B B4 7C 1B 5E BA B2 76 98 F1 9F D9 7F 33 68 69 54 87 F6 4F C1 19 1E E3 01 B2 00 43 2E 54 D7 (did CBC mode for 16) output: D3 7F 6D 39 57 32 A6 C5 A4 49 F4 4B C6 EE 0A E0 51 6F 31 69 BF 9C 75 AD A1 C6 66 A6 1B A2 38 0D 88 test 4 - 47 bytes input: 39 09 53 55 67 0E 07 DD A6 F8 7C 7F 78 AF E7 E1 03 6F D7 53 30 F0 71 14 F1 24 14 34 52 69 0C 8B 72 5F E0 D9 6D E8 B6 13 E0 32 92 58 E1 7A 39 (did CBC mode for 16) output: AD 96 1C 40 05 54 CB 0E 37 32 AE 2C 64 DB EF 8E A1 BD F6 34 5D F3 BC 03 86 72 D0 C3 13 FE C3 95 F0 68 8B 66 32 FE 41 EF 11 51 1B 6E F0 C0 17 test 5 - 48 bytes input: E5 E9 11 38 19 01 A9 2D F3 CD 42 27 1F AB 33 AB 1D 93 8B F6 00 73 AC 14 54 DE A6 AC BF 20 E6 A4 09 F7 DC 23 F8 86 50 EB 53 92 13 73 3D 46 1E 5A (did CBC mode for 16) output: 1A 03 F3 10 7A F0 62 07 D1 22 60 2B 9E 07 D0 8D 65 DE 01 93 8B 51 17 F8 32 6F 4B 05 AF 02 E2 3D 22 F4 2B 92 92 D4 D5 E7 EA 90 72 9F 03 31 10 1F test 6 - 64 bytes input: D9 A9 50 DA 1D FC EE 71 DA 94 1D 9A B5 03 3E BE FA 1B E1 F3 A1 32 DE F4 C4 F1 67 02 38 85 5C 11 2F AD EB 4C A9 D9 BD 84 6E DA 1E 23 DE 5C E1 D8 77 C3 CB 18 F5 AA 0D B9 9B 74 BB D3 FA 18 E5 29 (did CBC mode for 32) output: D0 18 22 59 85 05 AB 87 0D 9D D0 99 7B 15 CC 43 F7 43 1B BF 3C 7D A0 21 1E 3D 3F 6A 4D 8A CE 08 76 22 5A 42 DF 73 CB 5D CE 88 C3 4C CE 92 00 E6 37 9D EB CD 52 52 3B C5 76 02 7D 35 19 76 05 7D krb5-1.22.1/src/lib/crypto/builtin/aes/aes-gen.c0000664000175000017500000002324515051422640021125 0ustar ghudsonghudson/* * To be compiled against the AES code from: * https://github.com/BrianGladman/AES */ #include #include #include #include #include "aes.h" #define B 16U uint8_t key[16] = { 0x46, 0x64, 0x31, 0x29, 0x64, 0x86, 0xED, 0x9C, 0xD7, 0x1F, 0xC2, 0x07, 0x25, 0x48, 0x20, 0xA2 }; size_t test_case_len[] = { B+1, 2*B-1, 2*B, 2*B+1, 3*B-1, 3*B, 4*B, }; #define NTESTS (sizeof(test_case_len) / sizeof(*test_case_len)) uint8_t test_case[NTESTS][4 * B] = { { 0xC4, 0xA8, 0x5A, 0xEB, 0x0B, 0x20, 0x41, 0x49, 0x4F, 0x8B, 0xF1, 0xF8, 0xCD, 0x30, 0xF1, 0x13, 0x94 }, { 0x22, 0x3C, 0xF8, 0xA8, 0x29, 0x95, 0x80, 0x49, 0x57, 0x87, 0x6E, 0x9F, 0xA7, 0x11, 0x63, 0x50, 0x6B, 0x4E, 0x5B, 0x8C, 0x8F, 0xA4, 0xDB, 0x1B, 0x95, 0xD3, 0xE8, 0xC5, 0xC5, 0xFB, 0x5A }, { 0xE7, 0x37, 0x52, 0x90, 0x60, 0xE7, 0x10, 0xA9, 0x3E, 0x97, 0x18, 0xDD, 0x3E, 0x29, 0x41, 0x8E, 0x94, 0x8F, 0xE9, 0x20, 0x1F, 0x8D, 0xFB, 0x3A, 0x22, 0xCF, 0x22, 0xE8, 0x94, 0x1D, 0x42, 0x7B }, { 0x54, 0x94, 0x0B, 0xB4, 0x7C, 0x1B, 0x5E, 0xBA, 0xB2, 0x76, 0x98, 0xF1, 0x9F, 0xD9, 0x7F, 0x33, 0x68, 0x69, 0x54, 0x87, 0xF6, 0x4F, 0xC1, 0x19, 0x1E, 0xE3, 0x01, 0xB2, 0x00, 0x43, 0x2E, 0x54, 0xD7 }, { 0x39, 0x09, 0x53, 0x55, 0x67, 0x0E, 0x07, 0xDD, 0xA6, 0xF8, 0x7C, 0x7F, 0x78, 0xAF, 0xE7, 0xE1, 0x03, 0x6F, 0xD7, 0x53, 0x30, 0xF0, 0x71, 0x14, 0xF1, 0x24, 0x14, 0x34, 0x52, 0x69, 0x0C, 0x8B, 0x72, 0x5F, 0xE0, 0xD9, 0x6D, 0xE8, 0xB6, 0x13, 0xE0, 0x32, 0x92, 0x58, 0xE1, 0x7A, 0x39 }, { 0xE5, 0xE9, 0x11, 0x38, 0x19, 0x01, 0xA9, 0x2D, 0xF3, 0xCD, 0x42, 0x27, 0x1F, 0xAB, 0x33, 0xAB, 0x1D, 0x93, 0x8B, 0xF6, 0x00, 0x73, 0xAC, 0x14, 0x54, 0xDE, 0xA6, 0xAC, 0xBF, 0x20, 0xE6, 0xA4, 0x09, 0xF7, 0xDC, 0x23, 0xF8, 0x86, 0x50, 0xEB, 0x53, 0x92, 0x13, 0x73, 0x3D, 0x46, 0x1E, 0x5A }, { 0xD9, 0xA9, 0x50, 0xDA, 0x1D, 0xFC, 0xEE, 0x71, 0xDA, 0x94, 0x1D, 0x9A, 0xB5, 0x03, 0x3E, 0xBE, 0xFA, 0x1B, 0xE1, 0xF3, 0xA1, 0x32, 0xDE, 0xF4, 0xC4, 0xF1, 0x67, 0x02, 0x38, 0x85, 0x5C, 0x11, 0x2F, 0xAD, 0xEB, 0x4C, 0xA9, 0xD9, 0xBD, 0x84, 0x6E, 0xDA, 0x1E, 0x23, 0xDE, 0x5C, 0xE1, 0xD8, 0x77, 0xC3, 0xCB, 0x18, 0xF5, 0xAA, 0x0D, 0xB9, 0x9B, 0x74, 0xBB, 0xD3, 0xFA, 0x18, 0xE5, 0x29 } }; aes_encrypt_ctx ctx; aes_decrypt_ctx dctx; static void init (void) { AES_RETURN r; r = aes_encrypt_key128(key, &ctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); r = aes_decrypt_key128(key, &dctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); } static void hexdump(const unsigned char *ptr, size_t len) { size_t i; for (i = 0; i < len; i++) printf ("%s%02X", (i % 16 == 0) ? "\n " : " ", ptr[i]); } static void fips_test (void) { static const unsigned char fipskey[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }; static const unsigned char input[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, }; static const unsigned char expected[16] = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a, }; unsigned char output[16]; unsigned char tmp[16]; aes_crypt_ctx fipsctx; int r; printf ("FIPS test:\nkey:"); hexdump (fipskey, 16); printf ("\ninput:"); hexdump (input, 16); r = aes_encrypt_key128(fipskey, &fipsctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); r = aes_encrypt(input, output, &fipsctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); printf ("\noutput:"); hexdump (output, 16); printf ("\n"); if (memcmp(expected, output, 16)) fprintf(stderr, "wrong results!!!\n"), exit (1); r = aes_decrypt_key128(fipskey, &fipsctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); r = aes_decrypt(output, tmp, &fipsctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); if (memcmp(input, tmp, 16)) fprintf(stderr, "decryption failed!!\n"), exit(1); printf ("ok.\n\n"); } static void xor (unsigned char *out, const unsigned char *a, const unsigned char *b) { unsigned int i; for (i = 0; i < B; i++) out[i] = a[i] ^ b[i]; } static void ecb_enc (unsigned char *out, unsigned char *in, unsigned int len) { unsigned int i, r; for (i = 0; i < len; i += 16) { r = aes_encrypt(in + i, out + i, &ctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); } if (i != len) abort (); } static void ecb_dec (unsigned char *out, unsigned char *in, unsigned int len) { unsigned int i, r; for (i = 0; i < len; i += 16) { r = aes_decrypt(in + i, out + i, &dctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); } if (i != len) abort (); } #define D(X) (printf("%s %d: %s=",__FUNCTION__,__LINE__, #X),hexdump(X,B),printf("\n")) #undef D #define D(X) static void cbc_enc (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { unsigned int i, r; unsigned char tmp[B]; D(iv); memcpy (tmp, iv, B); for (i = 0; i < len; i += B) { D(in+i); xor (tmp, tmp, in + i); D(tmp); r = aes_encrypt(tmp, out + i, &ctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); memcpy (tmp, out + i, B); D(out+i); } if (i != len) abort (); } static void cbc_dec (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { unsigned int i, r; unsigned char tmp[B]; memcpy (tmp, iv, B); for (i = 0; i < len; i += B) { r = aes_decrypt(in + i, tmp, &dctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); xor (tmp, tmp, iv); iv = in + i; memcpy (out + i, tmp, B); } if (i != len) abort (); } static void cts_enc (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { int r; unsigned int len2; unsigned char pn1[B], pn[B], cn[B], cn1[B]; if (len < B + 1) abort (); len2 = (len - B - 1) & ~(B-1); cbc_enc (out, in, iv, len2); out += len2; in += len2; len -= len2; if (len2) iv = out - B; if (len <= B || len > 2 * B) abort (); printf ("(did CBC mode for %d)\n", len2); D(in); xor (pn1, in, iv); D(pn1); r = aes_encrypt(pn1, cn, &ctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); D(cn); memset (pn, 0, sizeof(pn)); memcpy (pn, in+B, len-B); D(pn); xor (pn, pn, cn); D(pn); r = aes_encrypt(pn, cn1, &ctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); D(cn1); memcpy(out, cn1, B); memcpy(out+B, cn, len-B); } static void cts_dec (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { int r; unsigned int len2; unsigned char pn1[B], pn[B], cn[B], cn1[B]; if (len < B + 1) abort (); len2 = (len - B - 1) & ~(B-1); cbc_dec (out, in, iv, len2); out += len2; in += len2; len -= len2; if (len2) iv = in - B; if (len <= B || len > 2 * B) abort (); memcpy (cn1, in, B); r = aes_decrypt(cn1, pn, &dctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); memset (cn, 0, sizeof(cn)); memcpy (cn, in+B, len-B); xor (pn, pn, cn); memcpy (cn+len-B, pn+len-B, 2*B-len); r = aes_decrypt(cn, pn1, &dctx); if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); xor (pn1, pn1, iv); memcpy(out, pn1, B); memcpy(out+B, pn, len-B); } static void ecb_test (void) { unsigned int testno; uint8_t output[4 * B], tmp[4 * B]; printf ("ECB tests:\n"); printf ("key:"); hexdump (key, sizeof(key)); for (testno = 0; testno < NTESTS; testno++) { unsigned len = (test_case_len[testno] + 15) & ~15; printf ("\ntest %d - %d bytes\n", testno, len); printf ("input:"); hexdump (test_case[testno], len); printf ("\n"); ecb_enc (output, test_case[testno], len); printf ("output:"); hexdump (output, len); printf ("\n"); ecb_dec (tmp, output, len); if (memcmp (tmp, test_case[testno], len)) { printf ("ecb decrypt failed!!"); hexdump (tmp, len); printf ("\n"); exit (1); } } printf ("\n"); } unsigned char ivec[16] = { 0 }; static void cbc_test (void) { unsigned int testno; uint8_t output[4 * B], tmp[4 * B]; printf ("CBC tests:\n"); printf ("initial vector:"); hexdump (ivec, sizeof(ivec)); for (testno = 0; testno < NTESTS; testno++) { unsigned len = (test_case_len[testno] + 15) & ~15; printf ("\ntest %d - %d bytes\n", testno, len); printf ("input:"); hexdump (test_case[testno], len); printf ("\n"); cbc_enc (output, test_case[testno], ivec, len); printf ("output:"); hexdump (output, len); printf ("\n"); cbc_dec (tmp, output, ivec, len); if (memcmp (tmp, test_case[testno], len)) { printf("cbc decrypt failed!!"); hexdump (tmp, len); printf ("\n"); exit(1); } } printf ("\n"); } static void cts_test (void) { unsigned int testno; uint8_t output[4 * B], tmp[4 * B]; printf ("CTS tests:\n"); printf ("initial vector:"); hexdump (ivec, sizeof(ivec)); for (testno = 0; testno < NTESTS; testno++) { unsigned int len = test_case_len[testno]; printf ("\ntest %d - %d bytes\n", testno, len); printf ("input:"); hexdump (test_case[testno], len); printf ("\n"); cts_enc (output, test_case[testno], ivec, len); printf ("output:"); hexdump (output, len); printf ("\n"); cts_dec (tmp, output, ivec, len); if (memcmp (tmp, test_case[testno], len)) fprintf (stderr, "cts decrypt failed!!\n"), exit(1); } printf ("\n"); } int main (void) { init (); fips_test (); ecb_test(); cbc_test(); cts_test(); return 0; } krb5-1.22.1/src/lib/crypto/builtin/aes/Makefile.in0000664000175000017500000000244415051422640021505 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)builtin$(S)aes BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLGAS) ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = builtin\aes ##DOS##OBJFILE = ..\..\$(OUTPRE)aes.lst YASM=@YASM@ AESNI_OBJ=@AESNI_OBJ@ AESNI_FLAGS=@AESNI_FLAGS@ STLIBOBJS=\ aescrypt.o \ aestab.o \ aeskey.o \ @AESNI_OBJ@ OBJS=\ $(OUTPRE)aescrypt.$(OBJEXT) \ $(OUTPRE)aestab.$(OBJEXT) \ $(OUTPRE)aeskey.$(OBJEXT) SRCS=\ $(srcdir)/aescrypt.c \ $(srcdir)/aestab.c \ $(srcdir)/aeskey.c \ EXTRADEPSRCS=\ $(srcdir)/aes-gen.c GEN_OBJS=\ $(OUTPRE)aescrypt.$(OBJEXT) \ $(OUTPRE)aestab.$(OBJEXT) \ $(OUTPRE)aeskey.$(OBJEXT) ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs # aes-gen iaesx64@SHOBJEXT@ iaesx64@STOBJEXT@: $(srcdir)/iaesx64.s $(YASM) $(AESNI_FLAGS) -o $@ $(srcdir)/iaesx64.s iaesx86@SHOBJEXT@ iaesx86@STOBJEXT@: $(srcdir)/iaesx86.s $(YASM) $(AESNI_FLAGS) -o $@ $(srcdir)/iaesx86.s includes: depend depend: $(SRCS) aes-gen: aes-gen.o $(GEN_OBJS) $(CC_LINK) -o aes-gen aes-gen.o $(GEN_OBJS) run-aes-gen: aes-gen ./aes-gen > kresults.out cmp kresults.out $(srcdir)/kresults.expected check-unix: check-@CRYPTO_BUILTIN_TESTS@ check-no: check-yes: run-aes-gen clean-unix:: clean-libobjs clean: -$(RM) aes-gen aes-gen.o kresults.out @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/aes/aes.txt0000664000175000017500000006042715051422640020756 0ustar ghudsonghudson An AES (Rijndael) Implementation in C/C++ (as specified in FIPS-197) ==================================================================== Change (26/09/2018) =================== 1. Changes to test programs to allow them to be built on Linux/GCC (with thanks to Michael Mohr). 2. Rationalisation of the defines DLL_IMPORT, DYNAMIC_DLL and USE_DLL in the test code - now DLL_IMPORT and DLL_DYNAMIC_LOAD 3. Update the test_avs test to allow the testing of static, DLL and dynamically loaded DLL libraries. Change (21/05/2018) =================== 1. Properly dectect presence of AESNI when using GCC (my thanks to Peter Gutmann for this fix) Changes (6/12/2016) ==================== 1. Changed function definition of has_aes_ni() to has_aes_ni(void), suggested by Peter Gutmann 2. Changed the default location for the vsyasm assembler to: C:\Program Files\yasm Changes (27/09/2015) ==================== 1. Added automatic dynamic table initialisation (my thanks to Henrik S. Gaßmann who proposed this addition). Changes (09/09/2014) ==================== 1. Added the ability to use Intel's hardware support for AES with GCC on Windows and Linux Changes (01/09/2014) ==================== 1. Clarify some user choices in the file aes_amd64.asm 2. Change the detection of the x86 and x86_64 processors in aesopt.h to allow assembler code use with GCC Changes (14/11/2013) ==================== 1. Added the ability to use Intel's hardware support for AES on Windows using Microsoft Visual Studio. 2. Added the include 'stdint.h' and used the uint_t instead of the old uint_t (e.g. uint_32t is now uint32_t). 3. Added a missing .text directive in aes_x86_v2.asm that caused runtime errors in one build configuration. Changes (16/04/2007) ==================== These changes remove errors in the VC++ build files and add some improvements in file naming consitency and portability. There are no changes to overcome reported bugs in the code. 1. gen_tabs() has been renamed to aes_init() to better decribe its function to those not familiar with AES internals. 2. via_ace.h has been renamed to aes_via_ace.h. 3. Minor changes have been made to aestab.h and aestab.c to enable all the code to be compiled in either C or C++. 4. The code for detecting memory alignment in aesmdoes.c has been simplified and a new routine has been added: aes_test_alignment_detection() to check that the aligment test is likely to be correct. 5. The addition of support for Structured Exception Handling (SEH) to YASM (well done Peter and Michael!) has allowed the AMD64 x64 assembler code to be changed to comply with SEH requriements. 6. Corrections to build files (for win32 debug build). Overview ======== This code implements AES for both 32 and 64 bit systems with optional assembler support for x86 and AMD64/EM64T (but optimised for AMD64). The basic AES source code files are as follows: aes.h the header file needed to use AES in C aescpp.h the header file required with to use AES in C++ aesopt.h the header file for setting options (and some common code) aestab.h the header file for the AES table declaration aescrypt.c the main C source code file for encryption and decryption aeskey.c the main C source code file for the key schedule aestab.c the main file for the AES tables brg_types.h a header defining some standard types and DLL defines brg_endian.h a header containing code to detect or define endianness aes_x86_v1.asm x86 assembler (YASM) alternative to aescrypt.c using large tables aes_x86_v2.asm x86 assembler (YASM) alternative to aescrypt.c using compressed tables aes_amd64.asm AMD64 assembler (YASM) alternative to aescrypt.c using compressed tables In addition AES modes are implemented in the files: aes_modes.c AES modes with optional support for VIA ACE detection and use aes_via_ace.h the header file for VIA ACE support and Intel hardware support for AES (AES_NI) is implemented in the files aes_ni.h defines for AES_NI implementation aes_ni.c the AES_NI implementation Other associated files for testing and support are: aesaux.h header for auxilliary routines for testsing aesaux.c auxilliary routines for testsingt aestst.h header file for setting the testing environment rdtsc.h a header file that provides access to the Time Stamp Counter aestst.c a simple test program for quick tests of the AES code aesgav.c a program to generate and verify the test vector files aesrav.c a program to verify output against the test vector files aestmr.c a program to time the code on x86 systems modetest.c a program to test the AES modes support vbxam.doc a demonstration of AES DLL use from Visual Basic in Microsoft Word vb.txt Visual Basic code from the above example (win32 only) aesxam.c an example of AES use tablegen.c a program to generate a simplified 'aestab.c' file for use with compilers that find aestab.c too complex yasm.rules the YASM build rules file for Microsoft Visual Studio 2005 via_ace.txt describes support for the VIA ACE cryptography engine aes.txt this file Building The AES Libraries -------------------------- A. Versions ----------- The code can be used to build static and dynamic libraries, each in five versions: Key scheduling code in C, encrypt/decrypt in: C C source code (win32 and x64) ASM_X86_V1C large table x86 assembler code (win32) ASM_X86_V2C compressed table x86 assembler code (win32) ASM_AMD64 compressed table x64 assembler code (x64) Key scheduling and encrypt/decrypt code in assembler: ASM_X86_V2 compressed table x86 assembler (win32) The C version can be compiled for Win32 or x64 whereas the x86 and x64 assembler versions are for Win32 and x64 respectively. If Intel's hardware support for AES (AES_NI) is available, it can be used with either the C or the ASM_AMD64 version. If ASM_AMD64 is to be used, it is important that the define USE_INTEL_AES_IF_PRESENT in asm_amd64.asm is set to the same value as it has in aesopt.h B. YASM ------- If you wish to use the x86 assembler files you will also need the YASM open source x86 assembler (r1331 or later) for Windows which can be obtained from: http://www.tortall.net/projects/yasm/ This assembler (vsyasm.exe) should be placed in the directory: C:\Program Files\yasm C. Configuration ---------------- The following configurations are available as projects for Visual Studio but the following descriptions should allow them to be built in other x86 environments lib_generic_c Win32 and x64 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h (+ aes_ni.h for AES_NI) C source: aescrypt.c, aeskey.c, aestab.c, aes_modes.c (+ aes_ni.c for AES_NI) defines dll_generic_c Win32 and x64 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h (+ aes_ni.h for AES_NI) C source: aescrypt.c, aeskey.c, aestab.c, aes_modes.c (+ aes_ni.c for AES_NI) defines DLL_EXPORT lib_asm_x86_v1c Win32 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h C source: aeskey.c, aestab.c, aes_modes.c x86 assembler: aes_x86_v1.asm defines ASM_X86_V1C (set for C and assembler files) dll_asm_x86_v1c Win32 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h C source: aeskey.c, aestab.c, aes_modes.c x86 assembler: aes_x86_v1.asm defines DLL_EXPORT, ASM_X86_V1C (set for C and assembler files) lib_asm_x86_v2c Win32 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h C source: aeskey.c, aestab.c, aes_modes.c x86 assembler: aes_x86_v2.asm defines ASM_X86_V2C (set for C and assembler files) dll_asm_x86_v2c Win32 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h C source: aeskey.c, aestab.c, aes_modes.c x86 assembler: aes_x86_v1.asm defines DLL_EXPORT, ASM_X86_V2C (set for C and assembler files) lib_asm_x86_v2 Win32 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h C source: aes_modes.c x86 assembler: aes_x86_v1.asm defines ASM_X86_V2 (set for C and assembler files) dll_asm_x86_v2 Win32 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h C source: aes_modes.c x86 assembler: aes_x86_v1.asm defines DLL_EXPORT, ASM_AMD64_C (set for C and assembler files) lib_asm_amd64_c x64 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h (+ aes_ni.h for AES_NI) C source: aes_modes.c (+ aes_ni.c for AES_NI) x86 assembler: aes_amd64.asm defines ASM_AMD64_C (set for C and assembler files) dll_asm_amd64_c x64 headers: aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h (+ aes_ni.h for AES_NI) C source: aes_modes.c (+ aes_ni.c for AES_NI) x86 assembler: aes_amd64.asm defines DLL_EXPORT, ASM_AMD64_C (set for C and assembler files) Notes: ASM_X86_V1C is defined if using the version 1 assembler code (aescrypt1.asm). The defines in the assember file must match those in aes.h and aesopt.h). Also remember to include/exclude the right assembler and C files in the build to avoid undefined or multiply defined symbols - include aes_x86_v1.asm and exclude aescrypt.c ASM_X86_V2 is defined if using the version 2 assembler code (aes_x86_v2.asm). This version provides a full, self contained assembler version and does not use any C source code files except for the mutiple block encryption modes that are provided by aes_modes.c. The define ASM_X86_V2 must be set on the YASM command line (or in aes_x86_v2.asm) to use this version and all C files except aec_modes.c and, for the DLL build, aestab.c must be excluded from the build. ASM_X86_V2C is defined when using the version 2 assembler code (aes_x86_v2.asm) with faster key scheduling provided by the in C code (the options in the assember file must match those in aes.h and aesopt.h). In this case aeskey.c and aestab.c are needed with aes_x86_v2.asm and the define ASM_X86_V2C must be set for both the C files and for aes_x86_v2.asm in the build commands(or in aesopt.h and aes_x86_v2.asm). Include aes_x86_v2.asm, aeskey.c and aestab.c, exclude aescrypt.c for this option. ASM_AMD64_C is defined when using the AMD64 assembly code because the C key scheduling is used in this case. DLL_EXPORT must be defined to generate the DLL version of the code and to run tests on it DLL_IMPORT must be defined to use the DLL version of the code in an application program Directories the paths for the various directories for test vector input and output have to be set in aestst.h VIA ACE see the via_ace.txt for this item Static The static libraries are named: Libraries aes_lib_generic_c.lib aes_lib_asm_x86_v1c.lib aes_lib_asm_x86_v2.lib aes_lib_asm_x86_v2c.lib aes_lib_asm_amd64_c.lib and placed in one of the the directories: lib\win32\release\ lib\win32\debug\ lib\x64\release\ lib\x64\debug\ in the aes root directory depending on the platform(win32 or x64) and the build (release or debug). After any of these is built it is then copied into the aes\lib directory, which is the library location that is subsequently used for testing. Hence testing is always for the last static library built. Dynamic These libraries are named: Libraries aes_lib_generic_c.dll aes_lib_asm_x86_v1c.dll aes_lib_asm_x86_v2.dll aes_lib_asm_x86_v2c.dll aes_lib_asm_amd64_c.dll and placed in one of the the directories: dll\win32\release\ dll\win32\debug\ dll\x64\release\ dll\x64\debug\ in the aes root directory depending on the platform(win32 or x64) and the build (release or debug). Each DLL library: aes_.dll has three associated files: aes_dll_.lib the library file for implicit linking aes_dll_.exp the exports file aes_dll_.pdb the symbol file After any DLL is built it and its three related files are then copied to the aes\dll directory, which is the library location used in subsequent testing. Hence testing is always for the last DLL built. D. Testing ---------- These tests require that the test vector files are placed in the 'testvals' subdirectory. If the AES Algorithm Validation Suite tests are used then the *.fax files need to be put in the 'testvals\fax' subdirectory. This is covered in more detail below. The projects test_lib and time_lib are used to test and time the last static library built. They use the files: test_lib: Win32 (x64 for the C and AMD64 versions) headers: aes.h, aescpp.h, brg_types.h, aesaux.h and aestst.h C source: aesaux.c, aesrav.c defines: time_lib: Win32 (x64 for the C and AMD64 versions) headers: aes.h, aescpp.h, brg_types.h, aesaux.h, aestst.h and rdtsc.h C source: aesaux.c, aestmr.c defines: The projects test_dll and time_dll are used to test and time the last DLL built. These use the files: test_dll: Win32 (x64 for the C and AMD64 versions) headers: aes.h, aescpp.h, brg_types.h, aesaux.h and aestst.h C source: aesaux.c, aesrav.c defines: DLL_IMPORT time_dll: Win32 (x64 for the C and AMD64 versions) headers: aes.h, aescpp.h, brg_types.h, aesaux.h aestst.h and rdtsc.h C source: aesaux.c, aestmr.c defines: DLL_IMPORT and default to linkingto with the AES DLL using dynamic (run-time) linking. Implicit linking can be used by adding the lib file associated with the AES DLL (in the aes\dll sub-directory) to the build (under project Properties|Linker in Visual Studio) and removing the DLL_DYNAMIC_LOAD define (under project Properties|C/C++|Preprocessor). 0 Link is linked into this project and the symbol DLL_DYNAMIC_LOAD is left undefined, then implicit linking will be used The above tests take command line arguments that determine which test are run as follows: test_lib /t:[knec] /k:[468] test_dll /t:[knec] /k:[468] where the symbols in square brackets can be used in any combination (without the brackets) and have the following meanings: /t:[knec] selects which tests are used /k:[468] selects the key lengths used /c compares output with reference (see later) k: generate ECB Known Answer Test files n: generate ECB Known Answer Test files (new) e: generate ECB Monte Carlo Test files c: generate CBC Monte Carlo Test files and the characters giving the lengths are digits representing the key lengths in 32-bit units (4, 6, 8 for lengths of 128, 192 or 256 bits respectively). The project test_modes tests the AES modes. It uses the files: test_modes: Win32 or x64 headers: aes.h, aescpp.h, brg_types.h, aesaux,h and aestst.h C source: aesaux.c, modetest.c defines: none for static library test, DLL_IMPORT for DLL test which again links to the last library built. E. Other Applications --------------------- These are: gen_tests builds the test_vector files. The commad line is gen_tests /t:knec /k:468 /c as described earlier test_aes_avs run the AES Algorithm Validation Suite tests for ECB, CBC, CFB and OFB modes gen_tables builds a simple version of aes_tab.c (in aestab2.c) for compilers that cannot handle the normal version aes_example provides an example of AES use These applications are linked to the last static library built or, if DLL_IMPORT is defined during compilation, to the last DLL built. F. Use of the VIA ACE Cryptography Engine (x86 only) ---------------------------------------------------- The use of the code with the VIA ACE cryptography engine in described in the file via_ace.txt. In outline aes_modes.c is used and USE_VIA_ACE_IF_PRESENT is defined either in section 2 of aesopt.h or as a compilation option in Visual Studio. If in addition ASSUME_VIA_ACE_PRESENT is also defined then all normal AES code will be removed if not needed to support VIA ACE use. If VIA ACE support is needed and AES assembler is being used only the ASM_X86_V1C and ASM_X86_V2C versions should be used since ASM_X86_V2 and ASM_AMD64 do not support the VIA ACE engine. G. The AES Test Vector Files ---------------------------- These files fall in the following groups (where is a two digit number): 1. ecbvk.txt ECB vectors with variable key 2. ecbvt.txt ECB vectors with variable text 3. ecbnk.txt new ECB vectors with variable key 4. ecbnt.txt new ECB vectors with variable text 5. ecbme.txt ECB monte carlo encryption test vectors 6. ecbmd.txt ECB monte carlo decryption test vectors 7. cbcme.txt CBC monte carlo encryption test vectors 8. cbcmd.txt CBC monte carlo decryption test vectors The first digit of the numeric suffix on the filename gives the block size in 32 bit units and the second numeric digit gives the key size. For example, the file ecbvk44.txt provides the test vectors for ECB encryption with a 128 bit block size and a 128 bit key size. The test routines expect to find these files in the 'testvals' subdirectory within the aes root directory. The 'outvals' subdirectory is used for outputs that are compared with the files in 'testvals'. Note that the monte carlo test vectors are the result of applying AES iteratively 10000 times, not just once. The AES Algorithm Validation Suite tests can be run for ECB, CBC, CFB and OFB modes (CFB1 and CFB8 are not implemented). The test routine uses the *.fax test files, which should be placed in the 'testvals\fax' subdirectory. H. The Basic AES Calling Interface ---------------------------------- The basic AES code keeps its state in a context, there being different contexts for encryption and decryption: aes_encrypt_ctx aes_decrypt_ctx The AES code is initialised with the call aes_init(void) although this is only essential if the option to generate the AES tables at run-time has been set in the options (i.e.fixed tables are not being used). The AES encryption key is set by one of the calls: aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]) aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]) aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]) or by: aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) where the key length is set by 'key_len', which can be the length in bits or bytes. Similarly, the AES decryption key is set by one of: aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]) aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]) aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]) or by: aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) Encryption and decryption for a single 16 byte block is then achieved using: aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]) aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]) The above subroutines return a value of EXIT_SUCCESS or EXIT_FAILURE depending on whether the operation succeeded or failed. I. The Calling Interface for the AES Modes ------------------------------------------ The subroutines for the AES modes, ECB, CBC, CFB, OFB and CTR, each process blocks of variable length and can also be called several times to complete single mode operations incrementally on long messages (or those messages, not all of which are available at the same time). The calls: aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, const aes_encrypt_ctx cx[1]) aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, const aes_decrypt_ctx cx[1]) for ECB operations and those for CBC: aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, const aes_encrypt_ctx cx[1]) aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, const aes_decrypt_ctx cx[1]) can only process blocks whose lengths are multiples of 16 bytes but the calls for CFB, OFB and CTR mode operations: aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]) aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]) aes_ofb_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]) aes_ofb_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *iv, aes_encrypt_ctx cx[1]) aes_ctr_encrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]) aes_ctr_decrypt(const unsigned char *ibuf, unsigned char *obuf, int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]) can process blocks of any length. Note also that CFB, OFB and CTR mode calls only use AES encryption contexts even during decryption operations. The calls CTR mode operations use a buffer (cbuf) which holds the counter value together with a function parameter: void cbuf_inc(unsigned char *cbuf); that is ued to update the counter value after each 16 byte AES operation. The counter buffer is updated appropriately to allow for incremental operations. Please note the following IMPORTANT points about the AES mode subroutines: 1. All modes are reset when a new AES key is set. 2. Incremental calls to the different modes cannot be mixed. If a change of mode is needed a new key must be set or a reset must be issued (see below). 3. For modes with IVs, the IV value is an input AND an output since it is updated after each call to the value needed for any subsequent incremental call(s). If the mode is reset, the IV hence has to be set (or reset) as well. 4. ECB operations must be multiples of 16 bytes but do not need to be reset for new operations. 5. CBC operations must also be multiples of 16 bytes and are reset for a new operation by setting the IV. 6. CFB, OFB and CTR mode must be reset by setting a new IV value AND by calling: aes_mode_reset(aes_encrypt_ctx cx[1]) For CTR mode the cbuf value also has to be reset. 7. CFB, OFB and CTR modes only use AES encryption operations and contexts and do not need AES decryption operations. 8. AES keys remain valid across resets and changes of mode (but encryption and decryption keys must both be set if they are needed). Brian Gladman 26/09/2018 krb5-1.22.1/src/lib/crypto/builtin/aes/aestab.h0000664000175000017500000001205215051422640021044 0ustar ghudsonghudson/* --------------------------------------------------------------------------- Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. --------------------------------------------------------------------------- Issue Date: 20/12/2007 This file contains the code for declaring the tables needed to implement AES. The file aesopt.h is assumed to be included before this header file. If there are no global variables, the definitions here can be used to put the AES tables in a structure so that a pointer can then be added to the AES context to pass them to the AES routines that need them. If this facility is used, the calling program has to ensure that this pointer is managed appropriately. In particular, the value of the t_dec(in,it) item in the table structure must be set to zero in order to ensure that the tables are initialised. In practice the three code sequences in aeskey.c that control the calls to aes_init() and the aes_init() routine itself will have to be changed for a specific implementation. If global variables are available it will generally be preferable to use them with the precomputed STATIC_TABLES option that uses static global tables. The following defines can be used to control the way the tables are defined, initialised and used in embedded environments that require special features for these purposes the 't_dec' construction is used to declare fixed table arrays the 't_set' construction is used to set fixed table values the 't_use' construction is used to access fixed table values 256 byte tables: t_xxx(s,box) => forward S box t_xxx(i,box) => inverse S box 256 32-bit word OR 4 x 256 32-bit word tables: t_xxx(f,n) => forward normal round t_xxx(f,l) => forward last round t_xxx(i,n) => inverse normal round t_xxx(i,l) => inverse last round t_xxx(l,s) => key schedule table t_xxx(i,m) => key schedule table Other variables and tables: t_xxx(r,c) => the rcon table */ #if !defined( _AESTAB_H ) #define _AESTAB_H #if defined(__cplusplus) extern "C" { #endif #define t_dec(m,n) t_##m##n #define t_set(m,n) t_##m##n #define t_use(m,n) t_##m##n #if defined(STATIC_TABLES) # if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ )) /* make tables far data to avoid using too much DGROUP space (PG) */ # define CONST const far # else # define CONST const # endif #else # define CONST #endif #if defined(DO_TABLES) # define EXTERN #else # define EXTERN extern #endif #if defined(_MSC_VER) && defined(TABLE_ALIGN) #define ALIGN __declspec(align(TABLE_ALIGN)) #else #define ALIGN #endif #if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 ) # define XP_DIR __cdecl #else # define XP_DIR #endif #if defined(DO_TABLES) && defined(STATIC_TABLES) #define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e) #define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) } EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH] = rc_data(w0); #else #define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] #define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH]; #endif #if defined( SBX_SET ) d_1(uint8_t, t_dec(s,box), sb_data, h0); #endif #if defined( ISB_SET ) d_1(uint8_t, t_dec(i,box), isb_data, h0); #endif #if defined( FT1_SET ) d_1(uint32_t, t_dec(f,n), sb_data, u0); #endif #if defined( FT4_SET ) d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3); #endif #if defined( FL1_SET ) d_1(uint32_t, t_dec(f,l), sb_data, w0); #endif #if defined( FL4_SET ) d_4(uint32_t, t_dec(f,l), sb_data, w0, w1, w2, w3); #endif #if defined( IT1_SET ) d_1(uint32_t, t_dec(i,n), isb_data, v0); #endif #if defined( IT4_SET ) d_4(uint32_t, t_dec(i,n), isb_data, v0, v1, v2, v3); #endif #if defined( IL1_SET ) d_1(uint32_t, t_dec(i,l), isb_data, w0); #endif #if defined( IL4_SET ) d_4(uint32_t, t_dec(i,l), isb_data, w0, w1, w2, w3); #endif #if defined( LS1_SET ) #if defined( FL1_SET ) #undef LS1_SET #else d_1(uint32_t, t_dec(l,s), sb_data, w0); #endif #endif #if defined( LS4_SET ) #if defined( FL4_SET ) #undef LS4_SET #else d_4(uint32_t, t_dec(l,s), sb_data, w0, w1, w2, w3); #endif #endif #if defined( IM1_SET ) d_1(uint32_t, t_dec(i,m), mm_data, v0); #endif #if defined( IM4_SET ) d_4(uint32_t, t_dec(i,m), mm_data, v0, v1, v2, v3); #endif #if defined(__cplusplus) } #endif #endif krb5-1.22.1/src/lib/crypto/builtin/aes/deps0000664000175000017500000000477615051422640020330 0ustar ghudsonghudson# # Generated makefile dependencies follow. # aescrypt.so aescrypt.po $(OUTPRE)aescrypt.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h aes.h aescrypt.c \ aesopt.h aestab.h brg_endian.h brg_types.h aestab.so aestab.po $(OUTPRE)aestab.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ aes.h aesopt.h aestab.c aestab.h brg_endian.h brg_types.h aeskey.so aeskey.po $(OUTPRE)aeskey.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ aes.h aeskey.c aesopt.h aestab.h brg_endian.h brg_types.h aes-gen.so aes-gen.po $(OUTPRE)aes-gen.$(OBJEXT): aes-gen.c \ aes.h brg_types.h krb5-1.22.1/src/lib/crypto/builtin/aes/iaesx64.s0000664000175000017500000003514715051422640021115 0ustar ghudsonghudson[bits 64] [CPU intelnop] ; Copyright (c) 2010, Intel Corporation ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: ; ; * Redistributions of source code must retain the above copyright notice, ; this list of conditions and the following disclaimer. ; * Redistributions in binary form must reproduce the above copyright notice, ; this list of conditions and the following disclaimer in the documentation ; and/or other materials provided with the distribution. ; * Neither the name of Intel Corporation nor the names of its contributors ; may be used to endorse or promote products derived from this software ; without specific prior written permission. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ; IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE ; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %define iEncExpandKey128 k5_iEncExpandKey128 %define iEncExpandKey256 k5_iEncExpandKey256 %define iDecExpandKey128 k5_iDecExpandKey128 %define iDecExpandKey256 k5_iDecExpandKey256 %define iEnc128_CBC k5_iEnc128_CBC %define iEnc256_CBC k5_iEnc256_CBC %define iDec128_CBC k5_iDec128_CBC %define iDec256_CBC k5_iDec256_CBC %macro linux_setup 0 %ifdef __linux__ mov rcx, rdi mov rdx, rsi %endif %endmacro %macro inversekey 1 movdqu xmm1,%1 aesimc xmm0,xmm1 movdqu %1,xmm0 %endmacro %macro aesdeclast1 1 aesdeclast xmm0,%1 %endmacro %macro aesenclast1 1 aesenclast xmm0,%1 %endmacro %macro aesdec1 1 aesdec xmm0,%1 %endmacro %macro aesenc1 1 aesenc xmm0,%1 %endmacro %macro aesdeclast1_u 1 movdqu xmm4,%1 aesdeclast xmm0,xmm4 %endmacro %macro aesenclast1_u 1 movdqu xmm4,%1 aesenclast xmm0,xmm4 %endmacro %macro aesdec1_u 1 movdqu xmm4,%1 aesdec xmm0,xmm4 %endmacro %macro aesenc1_u 1 movdqu xmm4,%1 aesenc xmm0,xmm4 %endmacro %macro aesdec4 1 movdqa xmm4,%1 aesdec xmm0,xmm4 aesdec xmm1,xmm4 aesdec xmm2,xmm4 aesdec xmm3,xmm4 %endmacro %macro aesdeclast4 1 movdqa xmm4,%1 aesdeclast xmm0,xmm4 aesdeclast xmm1,xmm4 aesdeclast xmm2,xmm4 aesdeclast xmm3,xmm4 %endmacro %macro aesenc4 1 movdqa xmm4,%1 aesenc xmm0,xmm4 aesenc xmm1,xmm4 aesenc xmm2,xmm4 aesenc xmm3,xmm4 %endmacro %macro aesenclast4 1 movdqa xmm4,%1 aesenclast xmm0,xmm4 aesenclast xmm1,xmm4 aesenclast xmm2,xmm4 aesenclast xmm3,xmm4 %endmacro %macro xor_with_input4 1 movdqu xmm4,[%1] pxor xmm0,xmm4 movdqu xmm4,[%1+16] pxor xmm1,xmm4 movdqu xmm4,[%1+32] pxor xmm2,xmm4 movdqu xmm4,[%1+48] pxor xmm3,xmm4 %endmacro %macro load_and_xor4 2 movdqa xmm4,%2 movdqu xmm0,[%1 + 0*16] pxor xmm0,xmm4 movdqu xmm1,[%1 + 1*16] pxor xmm1,xmm4 movdqu xmm2,[%1 + 2*16] pxor xmm2,xmm4 movdqu xmm3,[%1 + 3*16] pxor xmm3,xmm4 %endmacro %macro store4 1 movdqu [%1 + 0*16],xmm0 movdqu [%1 + 1*16],xmm1 movdqu [%1 + 2*16],xmm2 movdqu [%1 + 3*16],xmm3 %endmacro %macro copy_round_keys 3 movdqu xmm4,[%2 + ((%3)*16)] movdqa [%1 + ((%3)*16)],xmm4 %endmacro %macro key_expansion_1_192 1 ;; Assumes the xmm3 includes all zeros at this point. pshufd xmm2, xmm2, 11111111b shufps xmm3, xmm1, 00010000b pxor xmm1, xmm3 shufps xmm3, xmm1, 10001100b pxor xmm1, xmm3 pxor xmm1, xmm2 movdqu [rdx+%1], xmm1 %endmacro ; Calculate w10 and w11 using calculated w9 and known w4-w5 %macro key_expansion_2_192 1 movdqa xmm5, xmm4 pslldq xmm5, 4 shufps xmm6, xmm1, 11110000b pxor xmm6, xmm5 pxor xmm4, xmm6 pshufd xmm7, xmm4, 00001110b movdqu [rdx+%1], xmm7 %endmacro section .rodata align 16 shuffle_mask: DD 0FFFFFFFFh DD 03020100h DD 07060504h DD 0B0A0908h section .text align 16 key_expansion256: pshufd xmm2, xmm2, 011111111b movdqa xmm4, xmm1 pshufb xmm4, xmm5 pxor xmm1, xmm4 pshufb xmm4, xmm5 pxor xmm1, xmm4 pshufb xmm4, xmm5 pxor xmm1, xmm4 pxor xmm1, xmm2 movdqu [rdx], xmm1 add rdx, 0x10 aeskeygenassist xmm4, xmm1, 0 pshufd xmm2, xmm4, 010101010b movdqa xmm4, xmm3 pshufb xmm4, xmm5 pxor xmm3, xmm4 pshufb xmm4, xmm5 pxor xmm3, xmm4 pshufb xmm4, xmm5 pxor xmm3, xmm4 pxor xmm3, xmm2 movdqu [rdx], xmm3 add rdx, 0x10 ret align 16 key_expansion128: pshufd xmm2, xmm2, 0xFF; movdqa xmm3, xmm1 pshufb xmm3, xmm5 pxor xmm1, xmm3 pshufb xmm3, xmm5 pxor xmm1, xmm3 pshufb xmm3, xmm5 pxor xmm1, xmm3 pxor xmm1, xmm2 ; storing the result in the key schedule array movdqu [rdx], xmm1 add rdx, 0x10 ret align 16 global iEncExpandKey128 iEncExpandKey128: linux_setup movdqu xmm1, [rcx] ; loading the key movdqu [rdx], xmm1 movdqa xmm5, [shuffle_mask wrt rip] add rdx,16 aeskeygenassist xmm2, xmm1, 0x1 ; Generating round key 1 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x2 ; Generating round key 2 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x4 ; Generating round key 3 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x8 ; Generating round key 4 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x10 ; Generating round key 5 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x20 ; Generating round key 6 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x40 ; Generating round key 7 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x80 ; Generating round key 8 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x1b ; Generating round key 9 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x36 ; Generating round key 10 call key_expansion128 ret align 16 global iDecExpandKey128 iDecExpandKey128: linux_setup push rcx push rdx sub rsp,16+8 call iEncExpandKey128 add rsp,16+8 pop rdx pop rcx inversekey [rdx + 1*16] inversekey [rdx + 2*16] inversekey [rdx + 3*16] inversekey [rdx + 4*16] inversekey [rdx + 5*16] inversekey [rdx + 6*16] inversekey [rdx + 7*16] inversekey [rdx + 8*16] inversekey [rdx + 9*16] ret align 16 global iDecExpandKey256 iDecExpandKey256: linux_setup push rcx push rdx sub rsp,16+8 call iEncExpandKey256 add rsp,16+8 pop rdx pop rcx inversekey [rdx + 1*16] inversekey [rdx + 2*16] inversekey [rdx + 3*16] inversekey [rdx + 4*16] inversekey [rdx + 5*16] inversekey [rdx + 6*16] inversekey [rdx + 7*16] inversekey [rdx + 8*16] inversekey [rdx + 9*16] inversekey [rdx + 10*16] inversekey [rdx + 11*16] inversekey [rdx + 12*16] inversekey [rdx + 13*16] ret align 16 global iEncExpandKey256 iEncExpandKey256: linux_setup movdqu xmm1, [rcx] ; loading the key movdqu xmm3, [rcx+16] movdqu [rdx], xmm1 ; Storing key in memory where all key schedule will be stored movdqu [rdx+16], xmm3 add rdx,32 movdqa xmm5, [shuffle_mask wrt rip] ; this mask is used by key_expansion aeskeygenassist xmm2, xmm3, 0x1 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x2 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x4 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x8 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x10 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x20 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x40 ; ; call key_expansion256 pshufd xmm2, xmm2, 011111111b movdqa xmm4, xmm1 pshufb xmm4, xmm5 pxor xmm1, xmm4 pshufb xmm4, xmm5 pxor xmm1, xmm4 pshufb xmm4, xmm5 pxor xmm1, xmm4 pxor xmm1, xmm2 movdqu [rdx], xmm1 ret align 16 global iDec128_CBC iDec128_CBC: linux_setup sub rsp,16*16+8 mov r9,rcx mov rax,[rcx+24] movdqu xmm5,[rax] mov eax,[rcx+32] ; numblocks mov rdx,[rcx] mov r8,[rcx+8] mov rcx,[rcx+16] sub r8,rdx test eax,eax jz end_dec128_CBC cmp eax,4 jl lp128decsingle_CBC test rcx,0xf jz lp128decfour_CBC copy_round_keys rsp,rcx,0 copy_round_keys rsp,rcx,1 copy_round_keys rsp,rcx,2 copy_round_keys rsp,rcx,3 copy_round_keys rsp,rcx,4 copy_round_keys rsp,rcx,5 copy_round_keys rsp,rcx,6 copy_round_keys rsp,rcx,7 copy_round_keys rsp,rcx,8 copy_round_keys rsp,rcx,9 copy_round_keys rsp,rcx,10 mov rcx,rsp align 16 lp128decfour_CBC: test eax,eax jz end_dec128_CBC cmp eax,4 jl lp128decsingle_CBC load_and_xor4 rdx, [rcx+10*16] add rdx,16*4 aesdec4 [rcx+9*16] aesdec4 [rcx+8*16] aesdec4 [rcx+7*16] aesdec4 [rcx+6*16] aesdec4 [rcx+5*16] aesdec4 [rcx+4*16] aesdec4 [rcx+3*16] aesdec4 [rcx+2*16] aesdec4 [rcx+1*16] aesdeclast4 [rcx+0*16] pxor xmm0,xmm5 movdqu xmm4,[rdx - 16*4 + 0*16] pxor xmm1,xmm4 movdqu xmm4,[rdx - 16*4 + 1*16] pxor xmm2,xmm4 movdqu xmm4,[rdx - 16*4 + 2*16] pxor xmm3,xmm4 movdqu xmm5,[rdx - 16*4 + 3*16] sub eax,4 store4 r8+rdx-(16*4) jmp lp128decfour_CBC align 16 lp128decsingle_CBC: movdqu xmm0, [rdx] movdqa xmm1,xmm0 movdqu xmm4,[rcx+10*16] pxor xmm0, xmm4 aesdec1_u [rcx+9*16] aesdec1_u [rcx+8*16] aesdec1_u [rcx+7*16] aesdec1_u [rcx+6*16] aesdec1_u [rcx+5*16] aesdec1_u [rcx+4*16] aesdec1_u [rcx+3*16] aesdec1_u [rcx+2*16] aesdec1_u [rcx+1*16] aesdeclast1_u [rcx+0*16] pxor xmm0,xmm5 movdqa xmm5,xmm1 add rdx, 16 movdqu [r8 + rdx - 16], xmm0 dec eax jnz lp128decsingle_CBC end_dec128_CBC: mov r9,[r9+24] movdqu [r9],xmm5 add rsp,16*16+8 ret align 16 global iDec256_CBC iDec256_CBC: linux_setup sub rsp,16*16+8 mov r9,rcx mov rax,[rcx+24] movdqu xmm5,[rax] mov eax,[rcx+32] ; numblocks mov rdx,[rcx] mov r8,[rcx+8] mov rcx,[rcx+16] sub r8,rdx test eax,eax jz end_dec256_CBC cmp eax,4 jl lp256decsingle_CBC test rcx,0xf jz lp256decfour_CBC copy_round_keys rsp,rcx,0 copy_round_keys rsp,rcx,1 copy_round_keys rsp,rcx,2 copy_round_keys rsp,rcx,3 copy_round_keys rsp,rcx,4 copy_round_keys rsp,rcx,5 copy_round_keys rsp,rcx,6 copy_round_keys rsp,rcx,7 copy_round_keys rsp,rcx,8 copy_round_keys rsp,rcx,9 copy_round_keys rsp,rcx,10 copy_round_keys rsp,rcx,11 copy_round_keys rsp,rcx,12 copy_round_keys rsp,rcx,13 copy_round_keys rsp,rcx,14 mov rcx,rsp align 16 lp256decfour_CBC: test eax,eax jz end_dec256_CBC cmp eax,4 jl lp256decsingle_CBC load_and_xor4 rdx, [rcx+14*16] add rdx,16*4 aesdec4 [rcx+13*16] aesdec4 [rcx+12*16] aesdec4 [rcx+11*16] aesdec4 [rcx+10*16] aesdec4 [rcx+9*16] aesdec4 [rcx+8*16] aesdec4 [rcx+7*16] aesdec4 [rcx+6*16] aesdec4 [rcx+5*16] aesdec4 [rcx+4*16] aesdec4 [rcx+3*16] aesdec4 [rcx+2*16] aesdec4 [rcx+1*16] aesdeclast4 [rcx+0*16] pxor xmm0,xmm5 movdqu xmm4,[rdx - 16*4 + 0*16] pxor xmm1,xmm4 movdqu xmm4,[rdx - 16*4 + 1*16] pxor xmm2,xmm4 movdqu xmm4,[rdx - 16*4 + 2*16] pxor xmm3,xmm4 movdqu xmm5,[rdx - 16*4 + 3*16] sub eax,4 store4 r8+rdx-(16*4) jmp lp256decfour_CBC align 16 lp256decsingle_CBC: movdqu xmm0, [rdx] movdqu xmm4,[rcx+14*16] movdqa xmm1,xmm0 pxor xmm0, xmm4 aesdec1_u [rcx+13*16] aesdec1_u [rcx+12*16] aesdec1_u [rcx+11*16] aesdec1_u [rcx+10*16] aesdec1_u [rcx+9*16] aesdec1_u [rcx+8*16] aesdec1_u [rcx+7*16] aesdec1_u [rcx+6*16] aesdec1_u [rcx+5*16] aesdec1_u [rcx+4*16] aesdec1_u [rcx+3*16] aesdec1_u [rcx+2*16] aesdec1_u [rcx+1*16] aesdeclast1_u [rcx+0*16] pxor xmm0,xmm5 movdqa xmm5,xmm1 add rdx, 16 movdqu [r8 + rdx - 16], xmm0 dec eax jnz lp256decsingle_CBC end_dec256_CBC: mov r9,[r9+24] movdqu [r9],xmm5 add rsp,16*16+8 ret align 16 global iEnc128_CBC iEnc128_CBC: linux_setup sub rsp,16*16+8 mov r9,rcx mov rax,[rcx+24] movdqu xmm1,[rax] mov eax,[rcx+32] ; numblocks mov rdx,[rcx] mov r8,[rcx+8] mov rcx,[rcx+16] sub r8,rdx test rcx,0xf jz lp128encsingle_CBC copy_round_keys rsp,rcx,0 copy_round_keys rsp,rcx,1 copy_round_keys rsp,rcx,2 copy_round_keys rsp,rcx,3 copy_round_keys rsp,rcx,4 copy_round_keys rsp,rcx,5 copy_round_keys rsp,rcx,6 copy_round_keys rsp,rcx,7 copy_round_keys rsp,rcx,8 copy_round_keys rsp,rcx,9 copy_round_keys rsp,rcx,10 mov rcx,rsp align 16 lp128encsingle_CBC: movdqu xmm0, [rdx] movdqu xmm4,[rcx+0*16] add rdx, 16 pxor xmm0, xmm1 pxor xmm0, xmm4 aesenc1 [rcx+1*16] aesenc1 [rcx+2*16] aesenc1 [rcx+3*16] aesenc1 [rcx+4*16] aesenc1 [rcx+5*16] aesenc1 [rcx+6*16] aesenc1 [rcx+7*16] aesenc1 [rcx+8*16] aesenc1 [rcx+9*16] aesenclast1 [rcx+10*16] movdqa xmm1,xmm0 ; Store output encrypted data into CIPHERTEXT array movdqu [r8+rdx-16], xmm0 dec eax jnz lp128encsingle_CBC mov r9,[r9+24] movdqu [r9],xmm1 add rsp,16*16+8 ret align 16 global iEnc256_CBC iEnc256_CBC: linux_setup sub rsp,16*16+8 mov r9,rcx mov rax,[rcx+24] movdqu xmm1,[rax] mov eax,[rcx+32] ; numblocks mov rdx,[rcx] mov r8,[rcx+8] mov rcx,[rcx+16] sub r8,rdx test rcx,0xf jz lp256encsingle_CBC copy_round_keys rsp,rcx,0 copy_round_keys rsp,rcx,1 copy_round_keys rsp,rcx,2 copy_round_keys rsp,rcx,3 copy_round_keys rsp,rcx,4 copy_round_keys rsp,rcx,5 copy_round_keys rsp,rcx,6 copy_round_keys rsp,rcx,7 copy_round_keys rsp,rcx,8 copy_round_keys rsp,rcx,9 copy_round_keys rsp,rcx,10 copy_round_keys rsp,rcx,11 copy_round_keys rsp,rcx,12 copy_round_keys rsp,rcx,13 copy_round_keys rsp,rcx,14 mov rcx,rsp align 16 lp256encsingle_CBC: movdqu xmm0, [rdx] movdqu xmm4, [rcx+0*16] add rdx, 16 pxor xmm0, xmm1 pxor xmm0, xmm4 aesenc1 [rcx+1*16] aesenc1 [rcx+2*16] aesenc1 [rcx+3*16] aesenc1 [rcx+4*16] aesenc1 [rcx+5*16] aesenc1 [rcx+6*16] aesenc1 [rcx+7*16] aesenc1 [rcx+8*16] aesenc1 [rcx+9*16] aesenc1 [rcx+10*16] aesenc1 [rcx+11*16] aesenc1 [rcx+12*16] aesenc1 [rcx+13*16] aesenclast1 [rcx+14*16] movdqa xmm1,xmm0 ; Store output encrypted data into CIPHERTEXT array movdqu [r8+rdx-16], xmm0 dec eax jnz lp256encsingle_CBC mov r9,[r9+24] movdqu [r9],xmm1 add rsp,16*16+8 ret ; Mark this file as not needing an executable stack. %ifidn __OUTPUT_FORMAT__,elf section .note.GNU-stack noalloc noexec nowrite progbits %endif %ifidn __OUTPUT_FORMAT__,elf32 section .note.GNU-stack noalloc noexec nowrite progbits %endif %ifidn __OUTPUT_FORMAT__,elf64 section .note.GNU-stack noalloc noexec nowrite progbits %endif krb5-1.22.1/src/lib/crypto/builtin/aes/iaesx86.s0000664000175000017500000003664415051422640021124 0ustar ghudsonghudson[bits 32] [CPU intelnop] ; Copyright (c) 2010, Intel Corporation ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: ; ; * Redistributions of source code must retain the above copyright notice, ; this list of conditions and the following disclaimer. ; * Redistributions in binary form must reproduce the above copyright notice, ; this list of conditions and the following disclaimer in the documentation ; and/or other materials provided with the distribution. ; * Neither the name of Intel Corporation nor the names of its contributors ; may be used to endorse or promote products derived from this software ; without specific prior written permission. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ; IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, ; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE ; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. %define _iEncExpandKey128 k5_iEncExpandKey128 %define _iEncExpandKey256 k5_iEncExpandKey256 %define _iDecExpandKey128 k5_iDecExpandKey128 %define _iDecExpandKey256 k5_iDecExpandKey256 %define _iEnc128_CBC k5_iEnc128_CBC %define _iEnc256_CBC k5_iEnc256_CBC %define _iDec128_CBC k5_iDec128_CBC %define _iDec256_CBC k5_iDec256_CBC %macro inversekey 1 movdqu xmm1,%1 aesimc xmm0,xmm1 movdqu %1,xmm0 %endmacro %macro aesdec4 1 movdqa xmm4,%1 aesdec xmm0,xmm4 aesdec xmm1,xmm4 aesdec xmm2,xmm4 aesdec xmm3,xmm4 %endmacro %macro aesdeclast4 1 movdqa xmm4,%1 aesdeclast xmm0,xmm4 aesdeclast xmm1,xmm4 aesdeclast xmm2,xmm4 aesdeclast xmm3,xmm4 %endmacro %macro aesenc4 1 movdqa xmm4,%1 aesenc xmm0,xmm4 aesenc xmm1,xmm4 aesenc xmm2,xmm4 aesenc xmm3,xmm4 %endmacro %macro aesenclast4 1 movdqa xmm4,%1 aesenclast xmm0,xmm4 aesenclast xmm1,xmm4 aesenclast xmm2,xmm4 aesenclast xmm3,xmm4 %endmacro %macro aesdeclast1 1 aesdeclast xmm0,%1 %endmacro %macro aesenclast1 1 aesenclast xmm0,%1 %endmacro %macro aesdec1 1 aesdec xmm0,%1 %endmacro ;abab %macro aesenc1 1 aesenc xmm0,%1 %endmacro %macro aesdeclast1_u 1 movdqu xmm4,%1 aesdeclast xmm0,xmm4 %endmacro %macro aesenclast1_u 1 movdqu xmm4,%1 aesenclast xmm0,xmm4 %endmacro %macro aesdec1_u 1 movdqu xmm4,%1 aesdec xmm0,xmm4 %endmacro %macro aesenc1_u 1 movdqu xmm4,%1 aesenc xmm0,xmm4 %endmacro %macro load_and_xor4 2 movdqa xmm4,%2 movdqu xmm0,[%1 + 0*16] pxor xmm0,xmm4 movdqu xmm1,[%1 + 1*16] pxor xmm1,xmm4 movdqu xmm2,[%1 + 2*16] pxor xmm2,xmm4 movdqu xmm3,[%1 + 3*16] pxor xmm3,xmm4 %endmacro %macro xor_with_input4 1 movdqu xmm4,[%1] pxor xmm0,xmm4 movdqu xmm4,[%1+16] pxor xmm1,xmm4 movdqu xmm4,[%1+32] pxor xmm2,xmm4 movdqu xmm4,[%1+48] pxor xmm3,xmm4 %endmacro %macro store4 1 movdqu [%1 + 0*16],xmm0 movdqu [%1 + 1*16],xmm1 movdqu [%1 + 2*16],xmm2 movdqu [%1 + 3*16],xmm3 %endmacro %macro copy_round_keys 3 movdqu xmm4,[%2 + ((%3)*16)] movdqa [%1 + ((%3)*16)],xmm4 %endmacro ;abab %macro copy_round_keyx 3 movdqu xmm4,[%2 + ((%3)*16)] movdqa %1,xmm4 %endmacro %macro key_expansion_1_192 1 ;; Assumes the xmm3 includes all zeros at this point. pshufd xmm2, xmm2, 11111111b shufps xmm3, xmm1, 00010000b pxor xmm1, xmm3 shufps xmm3, xmm1, 10001100b pxor xmm1, xmm3 pxor xmm1, xmm2 movdqu [edx+%1], xmm1 %endmacro ; Calculate w10 and w11 using calculated w9 and known w4-w5 %macro key_expansion_2_192 1 movdqa xmm5, xmm4 pslldq xmm5, 4 shufps xmm6, xmm1, 11110000b pxor xmm6, xmm5 pxor xmm4, xmm6 pshufd xmm7, xmm4, 00001110b movdqu [edx+%1], xmm7 %endmacro section .rodata align 16 shuffle_mask: DD 0FFFFFFFFh DD 03020100h DD 07060504h DD 0B0A0908h section .text align 16 key_expansion256: pshufd xmm2, xmm2, 011111111b movdqu xmm4, xmm1 pshufb xmm4, xmm5 pxor xmm1, xmm4 pshufb xmm4, xmm5 pxor xmm1, xmm4 pshufb xmm4, xmm5 pxor xmm1, xmm4 pxor xmm1, xmm2 movdqu [edx], xmm1 add edx, 0x10 aeskeygenassist xmm4, xmm1, 0 pshufd xmm2, xmm4, 010101010b movdqu xmm4, xmm3 pshufb xmm4, xmm5 pxor xmm3, xmm4 pshufb xmm4, xmm5 pxor xmm3, xmm4 pshufb xmm4, xmm5 pxor xmm3, xmm4 pxor xmm3, xmm2 movdqu [edx], xmm3 add edx, 0x10 ret align 16 key_expansion128: pshufd xmm2, xmm2, 0xFF; movdqu xmm3, xmm1 pshufb xmm3, xmm5 pxor xmm1, xmm3 pshufb xmm3, xmm5 pxor xmm1, xmm3 pshufb xmm3, xmm5 pxor xmm1, xmm3 pxor xmm1, xmm2 ; storing the result in the key schedule array movdqu [edx], xmm1 add edx, 0x10 ret align 16 global _iEncExpandKey128 _iEncExpandKey128: mov ecx,[esp-4+8] ;input mov edx,[esp-4+12] ;ctx movdqu xmm1, [ecx] ; loading the key movdqu [edx], xmm1 call .next .next: pop ecx movdqa xmm5, [ecx-.next+shuffle_mask] add edx,16 aeskeygenassist xmm2, xmm1, 0x1 ; Generating round key 1 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x2 ; Generating round key 2 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x4 ; Generating round key 3 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x8 ; Generating round key 4 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x10 ; Generating round key 5 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x20 ; Generating round key 6 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x40 ; Generating round key 7 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x80 ; Generating round key 8 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x1b ; Generating round key 9 call key_expansion128 aeskeygenassist xmm2, xmm1, 0x36 ; Generating round key 10 call key_expansion128 ret align 16 global _iDecExpandKey128 _iDecExpandKey128: push DWORD [esp+8] push DWORD [esp+8] call _iEncExpandKey128 add esp,8 mov edx,[esp-4+12] ;ctx inversekey [edx + 1*16] inversekey [edx + 2*16] inversekey [edx + 3*16] inversekey [edx + 4*16] inversekey [edx + 5*16] inversekey [edx + 6*16] inversekey [edx + 7*16] inversekey [edx + 8*16] inversekey [edx + 9*16] ret align 16 global _iDecExpandKey256 _iDecExpandKey256: push DWORD [esp+8] push DWORD [esp+8] call _iEncExpandKey256 add esp, 8 mov edx, [esp-4+12] ;expanded key inversekey [edx + 1*16] inversekey [edx + 2*16] inversekey [edx + 3*16] inversekey [edx + 4*16] inversekey [edx + 5*16] inversekey [edx + 6*16] inversekey [edx + 7*16] inversekey [edx + 8*16] inversekey [edx + 9*16] inversekey [edx + 10*16] inversekey [edx + 11*16] inversekey [edx + 12*16] inversekey [edx + 13*16] ret align 16 global _iEncExpandKey256 _iEncExpandKey256: mov ecx, [esp-4+8] ;input mov edx, [esp-4+12] ;expanded key movdqu xmm1, [ecx] ; loading the key movdqu xmm3, [ecx+16] movdqu [edx], xmm1 ; Storing key in memory where all key schedule will be stored movdqu [edx+16], xmm3 add edx,32 call .next .next: pop ecx movdqa xmm5, [ecx-.next+shuffle_mask] ; this mask is used by key_expansion aeskeygenassist xmm2, xmm3, 0x1 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x2 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x4 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x8 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x10 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x20 ; call key_expansion256 aeskeygenassist xmm2, xmm3, 0x40 ; ; call key_expansion256 pshufd xmm2, xmm2, 011111111b movdqu xmm4, xmm1 pshufb xmm4, xmm5 pxor xmm1, xmm4 pshufb xmm4, xmm5 pxor xmm1, xmm4 pshufb xmm4, xmm5 pxor xmm1, xmm4 pxor xmm1, xmm2 movdqu [edx], xmm1 ret align 16 global _iDec128_CBC _iDec128_CBC: mov ecx,[esp-4+8] push esi push edi push ebp mov ebp,esp sub esp,16*16 and esp,0xfffffff0 mov eax,[ecx+12] movdqu xmm5,[eax] ;iv mov eax,[ecx+16] ; numblocks mov esi,[ecx] mov edi,[ecx+4] mov ecx,[ecx+8] sub edi,esi test eax,eax jz end_dec128_CBC cmp eax,4 jl lp128decsingle_CBC test ecx,0xf jz lp128decfour_CBC copy_round_keys esp,ecx,0 copy_round_keys esp,ecx,1 copy_round_keys esp,ecx,2 copy_round_keys esp,ecx,3 copy_round_keys esp,ecx,4 copy_round_keys esp,ecx,5 copy_round_keys esp,ecx,6 copy_round_keys esp,ecx,7 copy_round_keys esp,ecx,8 copy_round_keys esp,ecx,9 copy_round_keys esp,ecx,10 mov ecx,esp align 16 lp128decfour_CBC: test eax,eax jz end_dec128_CBC cmp eax,4 jl lp128decsingle_CBC load_and_xor4 esi, [ecx+10*16] add esi,16*4 aesdec4 [ecx+9*16] aesdec4 [ecx+8*16] aesdec4 [ecx+7*16] aesdec4 [ecx+6*16] aesdec4 [ecx+5*16] aesdec4 [ecx+4*16] aesdec4 [ecx+3*16] aesdec4 [ecx+2*16] aesdec4 [ecx+1*16] aesdeclast4 [ecx+0*16] pxor xmm0,xmm5 movdqu xmm4,[esi- 16*4 + 0*16] pxor xmm1,xmm4 movdqu xmm4,[esi- 16*4 + 1*16] pxor xmm2,xmm4 movdqu xmm4,[esi- 16*4 + 2*16] pxor xmm3,xmm4 movdqu xmm5,[esi- 16*4 + 3*16] sub eax,4 store4 esi+edi-(16*4) jmp lp128decfour_CBC align 16 lp128decsingle_CBC: movdqu xmm0, [esi] movdqa xmm1,xmm0 movdqu xmm4,[ecx+10*16] pxor xmm0, xmm4 aesdec1_u [ecx+9*16] aesdec1_u [ecx+8*16] aesdec1_u [ecx+7*16] aesdec1_u [ecx+6*16] aesdec1_u [ecx+5*16] aesdec1_u [ecx+4*16] aesdec1_u [ecx+3*16] aesdec1_u [ecx+2*16] aesdec1_u [ecx+1*16] aesdeclast1_u [ecx+0*16] pxor xmm0,xmm5 movdqa xmm5,xmm1 add esi, 16 movdqu [edi+esi - 16], xmm0 dec eax jnz lp128decsingle_CBC end_dec128_CBC: mov esp,ebp pop ebp pop edi pop esi mov ecx,[esp-4+8] ; first arg mov ecx,[ecx+12] movdqu [ecx],xmm5 ; store last iv for chaining ret align 16 global _iDec256_CBC _iDec256_CBC: mov ecx,[esp-4+8] push esi push edi push ebp mov ebp,esp sub esp,16*16 and esp,0xfffffff0 mov eax,[ecx+12] movdqu xmm5,[eax] ;iv mov eax,[ecx+16] ; numblocks mov esi,[ecx] mov edi,[ecx+4] mov ecx,[ecx+8] sub edi,esi test eax,eax jz end_dec256_CBC cmp eax,4 jl lp256decsingle_CBC test ecx,0xf jz lp256decfour_CBC copy_round_keys esp,ecx,0 copy_round_keys esp,ecx,1 copy_round_keys esp,ecx,2 copy_round_keys esp,ecx,3 copy_round_keys esp,ecx,4 copy_round_keys esp,ecx,5 copy_round_keys esp,ecx,6 copy_round_keys esp,ecx,7 copy_round_keys esp,ecx,8 copy_round_keys esp,ecx,9 copy_round_keys esp,ecx,10 copy_round_keys esp,ecx,11 copy_round_keys esp,ecx,12 copy_round_keys esp,ecx,13 copy_round_keys esp,ecx,14 mov ecx,esp align 16 lp256decfour_CBC: test eax,eax jz end_dec256_CBC cmp eax,4 jl lp256decsingle_CBC load_and_xor4 esi, [ecx+14*16] add esi,16*4 aesdec4 [ecx+13*16] aesdec4 [ecx+12*16] aesdec4 [ecx+11*16] aesdec4 [ecx+10*16] aesdec4 [ecx+9*16] aesdec4 [ecx+8*16] aesdec4 [ecx+7*16] aesdec4 [ecx+6*16] aesdec4 [ecx+5*16] aesdec4 [ecx+4*16] aesdec4 [ecx+3*16] aesdec4 [ecx+2*16] aesdec4 [ecx+1*16] aesdeclast4 [ecx+0*16] pxor xmm0,xmm5 movdqu xmm4,[esi- 16*4 + 0*16] pxor xmm1,xmm4 movdqu xmm4,[esi- 16*4 + 1*16] pxor xmm2,xmm4 movdqu xmm4,[esi- 16*4 + 2*16] pxor xmm3,xmm4 movdqu xmm5,[esi- 16*4 + 3*16] sub eax,4 store4 esi+edi-(16*4) jmp lp256decfour_CBC align 16 lp256decsingle_CBC: movdqu xmm0, [esi] movdqa xmm1,xmm0 movdqu xmm4, [ecx+14*16] pxor xmm0, xmm4 aesdec1_u [ecx+13*16] aesdec1_u [ecx+12*16] aesdec1_u [ecx+11*16] aesdec1_u [ecx+10*16] aesdec1_u [ecx+9*16] aesdec1_u [ecx+8*16] aesdec1_u [ecx+7*16] aesdec1_u [ecx+6*16] aesdec1_u [ecx+5*16] aesdec1_u [ecx+4*16] aesdec1_u [ecx+3*16] aesdec1_u [ecx+2*16] aesdec1_u [ecx+1*16] aesdeclast1_u [ecx+0*16] pxor xmm0,xmm5 movdqa xmm5,xmm1 add esi, 16 movdqu [edi+esi - 16], xmm0 dec eax jnz lp256decsingle_CBC end_dec256_CBC: mov esp,ebp pop ebp pop edi pop esi mov ecx,[esp-4+8] ; first arg mov ecx,[ecx+12] movdqu [ecx],xmm5 ; store last iv for chaining ret align 16 global _iEnc128_CBC _iEnc128_CBC: mov ecx,[esp-4+8] push esi push edi push ebp mov ebp,esp sub esp,16*16 and esp,0xfffffff0 mov eax,[ecx+12] movdqu xmm1,[eax] ;iv mov eax,[ecx+16] ; numblocks mov esi,[ecx] mov edi,[ecx+4] mov ecx,[ecx+8] sub edi,esi test ecx,0xf jz lp128encsingle_CBC copy_round_keys esp,ecx,0 copy_round_keys esp,ecx,1 copy_round_keys esp,ecx,2 copy_round_keys esp,ecx,3 copy_round_keys esp,ecx,4 copy_round_keys esp,ecx,5 copy_round_keys esp,ecx,6 copy_round_keys esp,ecx,7 copy_round_keys esp,ecx,8 copy_round_keys esp,ecx,9 copy_round_keys esp,ecx,10 mov ecx,esp align 16 lp128encsingle_CBC: movdqu xmm0, [esi] add esi, 16 pxor xmm0, xmm1 movdqu xmm4,[ecx+0*16] pxor xmm0, xmm4 aesenc1 [ecx+1*16] aesenc1 [ecx+2*16] aesenc1 [ecx+3*16] aesenc1 [ecx+4*16] aesenc1 [ecx+5*16] aesenc1 [ecx+6*16] aesenc1 [ecx+7*16] aesenc1 [ecx+8*16] aesenc1 [ecx+9*16] aesenclast1 [ecx+10*16] ; Store output encrypted data into CIPHERTEXT array movdqu [esi+edi-16], xmm0 movdqa xmm1,xmm0 dec eax jnz lp128encsingle_CBC mov esp,ebp pop ebp pop edi pop esi mov ecx,[esp-4+8] ; first arg mov ecx,[ecx+12] movdqu [ecx],xmm1 ; store last iv for chaining ret align 16 global _iEnc256_CBC _iEnc256_CBC: mov ecx,[esp-4+8] ; first arg push esi push edi push ebp mov ebp,esp sub esp,16*16 and esp,0xfffffff0 mov eax,[ecx+12] movdqu xmm1,[eax] ;iv mov eax,[ecx+16] ; numblocks mov esi,[ecx] mov edi,[ecx+4] mov ecx,[ecx+8] sub edi,esi test ecx,0xf jz lp256encsingle_CBC copy_round_keys esp,ecx,0 copy_round_keys esp,ecx,1 copy_round_keys esp,ecx,2 copy_round_keys esp,ecx,3 copy_round_keys esp,ecx,4 copy_round_keys esp,ecx,5 copy_round_keys esp,ecx,6 copy_round_keys esp,ecx,7 copy_round_keys esp,ecx,8 copy_round_keys esp,ecx,9 copy_round_keys esp,ecx,10 copy_round_keys esp,ecx,11 copy_round_keys esp,ecx,12 copy_round_keys esp,ecx,13 copy_round_keys esp,ecx,14 mov ecx,esp align 16 lp256encsingle_CBC: ;abab movdqu xmm0, [esi] add esi, 16 pxor xmm0, xmm1 movdqu xmm4,[ecx+0*16] pxor xmm0, xmm4 aesenc1 [ecx+1*16] aesenc1 [ecx+2*16] aesenc1 [ecx+3*16] aesenc1 [ecx+4*16] aesenc1 [ecx+5*16] aesenc1 [ecx+6*16] aesenc1 [ecx+7*16] aesenc1 [ecx+8*16] aesenc1 [ecx+9*16] aesenc1 [ecx+10*16] aesenc1 [ecx+11*16] aesenc1 [ecx+12*16] aesenc1 [ecx+13*16] aesenclast1 [ecx+14*16] ; Store output encrypted data into CIPHERTEXT array movdqu [esi+edi-16], xmm0 movdqa xmm1,xmm0 dec eax jnz lp256encsingle_CBC mov esp,ebp pop ebp pop edi pop esi mov ecx,[esp-4+8] mov ecx,[ecx+12] movdqu [ecx],xmm1 ; store last iv for chaining ret ; Mark this file as not needing an executable stack. %ifidn __OUTPUT_FORMAT__,elf section .note.GNU-stack noalloc noexec nowrite progbits %endif %ifidn __OUTPUT_FORMAT__,elf32 section .note.GNU-stack noalloc noexec nowrite progbits %endif %ifidn __OUTPUT_FORMAT__,elf64 section .note.GNU-stack noalloc noexec nowrite progbits %endif krb5-1.22.1/src/lib/crypto/builtin/aes/aestab.c0000664000175000017500000003727315051422640021053 0ustar ghudsonghudson/* --------------------------------------------------------------------------- Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. --------------------------------------------------------------------------- Issue Date: 20/12/2007 */ #define DO_TABLES #include "aes.h" #include "aesopt.h" #include "crypto_int.h" #ifdef K5_BUILTIN_AES #if defined(STATIC_TABLES) #define sb_data(w) {\ w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\ w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\ w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\ w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\ w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\ w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\ w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\ w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\ w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\ w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\ w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\ w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\ w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\ w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\ w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\ w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\ w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\ w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\ w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\ w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\ w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\ w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\ w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\ w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\ w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\ w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\ w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\ w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\ w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\ w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\ w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) } #define isb_data(w) {\ w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\ w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\ w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\ w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\ w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\ w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\ w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\ w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\ w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\ w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\ w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\ w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\ w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\ w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\ w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\ w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\ w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\ w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\ w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\ w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\ w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\ w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\ w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\ w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\ w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\ w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\ w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\ w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\ w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\ w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\ w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\ w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) } #define mm_data(w) {\ w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\ w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\ w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\ w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\ w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\ w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\ w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\ w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\ w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\ w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\ w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\ w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\ w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\ w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\ w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\ w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\ w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\ w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\ w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\ w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\ w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\ w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\ w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\ w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\ w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\ w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\ w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\ w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\ w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\ w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\ w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\ w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) } #define rc_data(w) {\ w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\ w(0x1b), w(0x36) } #define h0(x) (x) #define w0(p) bytes2word(p, 0, 0, 0) #define w1(p) bytes2word(0, p, 0, 0) #define w2(p) bytes2word(0, 0, p, 0) #define w3(p) bytes2word(0, 0, 0, p) #define u0(p) bytes2word(f2(p), p, p, f3(p)) #define u1(p) bytes2word(f3(p), f2(p), p, p) #define u2(p) bytes2word(p, f3(p), f2(p), p) #define u3(p) bytes2word(p, p, f3(p), f2(p)) #define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) #define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) #define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) #define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) #endif #if defined(STATIC_TABLES) || !defined(FF_TABLES) #define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) #define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) #define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \ ^ (((x>>5) & 4) * WPOLY)) #define f3(x) (f2(x) ^ x) #define f9(x) (f8(x) ^ x) #define fb(x) (f8(x) ^ f2(x) ^ x) #define fd(x) (f8(x) ^ f4(x) ^ x) #define fe(x) (f8(x) ^ f4(x) ^ f2(x)) #else #define f2(x) ((x) ? pow[log[x] + 0x19] : 0) #define f3(x) ((x) ? pow[log[x] + 0x01] : 0) #define f9(x) ((x) ? pow[log[x] + 0xc7] : 0) #define fb(x) ((x) ? pow[log[x] + 0x68] : 0) #define fd(x) ((x) ? pow[log[x] + 0xee] : 0) #define fe(x) ((x) ? pow[log[x] + 0xdf] : 0) #endif #include "aestab.h" #if defined(__cplusplus) extern "C" { #endif #if defined(STATIC_TABLES) /* implemented in case of wrong call for fixed tables */ AES_RETURN aes_init(void) { return EXIT_SUCCESS; } #else /* Generate the tables for the dynamic table option */ #if defined(FF_TABLES) #define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0) #else /* It will generally be sensible to use tables to compute finite field multiplies and inverses but where memory is scarse this code might sometimes be better. But it only has effect during initialisation so its pretty unimportant in overall terms. */ /* return 2 ^ (n - 1) where n is the bit number of the highest bit set in x with x in the range 1 < x < 0x00000200. This form is used so that locals within fi can be bytes rather than words */ static uint8_t hibit(const uint32_t x) { uint8_t r = (uint8_t)((x >> 1) | (x >> 2)); r |= (r >> 2); r |= (r >> 4); return (r + 1) >> 1; } /* return the inverse of the finite field element x */ static uint8_t gf_inv(const uint8_t x) { uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; if(x < 2) return x; for( ; ; ) { if(n1) while(n2 >= n1) /* divide polynomial p2 by p1 */ { n2 /= n1; /* shift smaller polynomial left */ p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */ v2 ^= v1 * n2; /* shift accumulated value and */ n2 = hibit(p2); /* add into result */ } else return v1; if(n2) /* repeat with values swapped */ while(n1 >= n2) { n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1); } else return v2; } } #endif /* The forward and inverse affine transformations used in the S-box */ uint8_t fwd_affine(const uint8_t x) { uint32_t w = x; w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4); return 0x63 ^ ((w ^ (w >> 8)) & 0xff); } uint8_t inv_affine(const uint8_t x) { uint32_t w = x; w = (w << 1) ^ (w << 3) ^ (w << 6); return 0x05 ^ ((w ^ (w >> 8)) & 0xff); } static int init = 0; AES_RETURN aes_init(void) { uint32_t i, w; #if defined(FF_TABLES) uint8_t pow[512], log[256]; if(init) return EXIT_SUCCESS; /* log and power tables for GF(2^8) finite field with WPOLY as modular polynomial - the simplest primitive root is 0x03, used here to generate the tables */ i = 0; w = 1; do { pow[i] = (uint8_t)w; pow[i + 255] = (uint8_t)w; log[w] = (uint8_t)i++; w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0); } while (w != 1); #else if(init) return EXIT_SUCCESS; #endif for(i = 0, w = 1; i < RC_LENGTH; ++i) { t_set(r,c)[i] = bytes2word(w, 0, 0, 0); w = f2(w); } for(i = 0; i < 256; ++i) { uint8_t b; b = fwd_affine(gf_inv((uint8_t)i)); w = bytes2word(f2(b), b, b, f3(b)); #if defined( SBX_SET ) t_set(s,box)[i] = b; #endif #if defined( FT1_SET ) /* tables for a normal encryption round */ t_set(f,n)[i] = w; #endif #if defined( FT4_SET ) t_set(f,n)[0][i] = w; t_set(f,n)[1][i] = upr(w,1); t_set(f,n)[2][i] = upr(w,2); t_set(f,n)[3][i] = upr(w,3); #endif w = bytes2word(b, 0, 0, 0); #if defined( FL1_SET ) /* tables for last encryption round (may also */ t_set(f,l)[i] = w; /* be used in the key schedule) */ #endif #if defined( FL4_SET ) t_set(f,l)[0][i] = w; t_set(f,l)[1][i] = upr(w,1); t_set(f,l)[2][i] = upr(w,2); t_set(f,l)[3][i] = upr(w,3); #endif #if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/ t_set(l,s)[i] = w; /* not of the required form */ #endif #if defined( LS4_SET ) t_set(l,s)[0][i] = w; t_set(l,s)[1][i] = upr(w,1); t_set(l,s)[2][i] = upr(w,2); t_set(l,s)[3][i] = upr(w,3); #endif b = gf_inv(inv_affine((uint8_t)i)); w = bytes2word(fe(b), f9(b), fd(b), fb(b)); #if defined( IM1_SET ) /* tables for the inverse mix column operation */ t_set(i,m)[b] = w; #endif #if defined( IM4_SET ) t_set(i,m)[0][b] = w; t_set(i,m)[1][b] = upr(w,1); t_set(i,m)[2][b] = upr(w,2); t_set(i,m)[3][b] = upr(w,3); #endif #if defined( ISB_SET ) t_set(i,box)[i] = b; #endif #if defined( IT1_SET ) /* tables for a normal decryption round */ t_set(i,n)[i] = w; #endif #if defined( IT4_SET ) t_set(i,n)[0][i] = w; t_set(i,n)[1][i] = upr(w,1); t_set(i,n)[2][i] = upr(w,2); t_set(i,n)[3][i] = upr(w,3); #endif w = bytes2word(b, 0, 0, 0); #if defined( IL1_SET ) /* tables for last decryption round */ t_set(i,l)[i] = w; #endif #if defined( IL4_SET ) t_set(i,l)[0][i] = w; t_set(i,l)[1][i] = upr(w,1); t_set(i,l)[2][i] = upr(w,2); t_set(i,l)[3][i] = upr(w,3); #endif } init = 1; return EXIT_SUCCESS; } /* Automatic code initialisation (suggested by by Henrik S. Gaßmann) based on code provided by Joe Lowe and placed in the public domain at: http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc */ #ifdef _MSC_VER #pragma section(".CRT$XCU", read) __declspec(allocate(".CRT$XCU")) void (__cdecl *aes_startup)(void) = aes_init; #elif defined(__GNUC__) static void aes_startup(void) __attribute__((constructor)); static void aes_startup(void) { aes_init(); } #else #pragma message( "dynamic tables must be initialised manually on your system" ) #endif #endif #if defined(__cplusplus) } #endif #else /* K5_BUILTIN_AES */ /* Include aestab.h for proper dependency generation, but without defining the * table objects. */ #undef DO_TABLES #include "aestab.h" #endif krb5-1.22.1/src/lib/crypto/builtin/aes/brg_endian.h0000664000175000017500000001342115051422640021676 0ustar ghudsonghudson/* --------------------------------------------------------------------------- Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. --------------------------------------------------------------------------- Issue Date: 10/09/2018 */ #ifndef _BRG_ENDIAN_H #define _BRG_ENDIAN_H #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ #define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ /* This is needed when using clang with MSVC to avoid including */ /* endian.h and byteswap.h which are not present on Windows */ #if defined( _MSC_VER ) && defined( __clang__ ) # undef __GNUC__ #endif /* Include files where endian defines and byteswap functions may reside */ #if defined( __sun ) # include #elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) # include #elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) # include #elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) # if !defined( __MINGW32__ ) && !defined( _AIX ) # include # if !defined( __BEOS__ ) # include # endif # endif #endif /* Now attempt to set the define for platform byte order using any */ /* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, ... */ /* which seem to encompass most endian symbol definitions */ #if defined( __ORDER_BIG_ENDIAN__ ) && defined( __ORDER_LITTLE_ENDIAN__ ) # if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN # elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN # endif #elif defined( __ORDER_BIG_ENDIAN__ ) # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN #elif defined( __ORDER_LITTLE_ENDIAN__ ) # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN #endif #if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) # if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN # elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN # endif #elif defined( BIG_ENDIAN ) # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN #elif defined( LITTLE_ENDIAN ) # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN #endif #if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) # if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN # elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN # endif #elif defined( _BIG_ENDIAN ) # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN #elif defined( _LITTLE_ENDIAN ) # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN #endif #if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) # if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN # elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN # endif #elif defined( __BIG_ENDIAN ) # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN #elif defined( __LITTLE_ENDIAN ) # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN #endif #if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) # if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN # elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN # endif #elif defined( __BIG_ENDIAN__ ) # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN #elif defined( __LITTLE_ENDIAN__ ) # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN #endif /* if the platform byte order could not be determined, then try to */ /* set this define using common machine defines */ #if !defined(PLATFORM_BYTE_ORDER) #if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ defined( vax ) || defined( vms ) || defined( VMS ) || \ defined( __VMS ) || defined( _M_X64 ) || defined( _M_ARM64 ) # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN #elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN #elif 0 /* **** EDIT HERE IF NECESSARY **** */ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN #elif 0 /* **** EDIT HERE IF NECESSARY **** */ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN #else # error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order #endif #endif #endif krb5-1.22.1/src/lib/crypto/builtin/aes/aescrypt.c0000664000175000017500000002405615051422640021441 0ustar ghudsonghudson/* --------------------------------------------------------------------------- Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. --------------------------------------------------------------------------- Issue Date: 20/12/2007 */ #include "aesopt.h" #include "aestab.h" #include "crypto_int.h" #ifdef K5_BUILTIN_AES #if defined( USE_INTEL_AES_IF_PRESENT ) # include "aes_ni.h" #else /* map names here to provide the external API ('name' -> 'aes_name') */ # define aes_xi(x) aes_ ## x #endif #if defined(__cplusplus) extern "C" { #endif #define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c]) #define so(y,x,c) word_out(y, c, s(x,c)) #if defined(ARRAYS) #define locals(y,x) x[4],y[4] #else #define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 #endif #define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ s(y,2) = s(x,2); s(y,3) = s(x,3); #define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) #define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) #define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) #if ( FUNCS_IN_C & ENCRYPTION_IN_C ) /* Visual C++ .Net v7.1 provides the fastest encryption code when using Pentium optimisation with small code but this is poor for decryption so we need to control this with the following VC++ pragmas */ #if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ ) #pragma optimize( "s", on ) #endif /* Given the column (c) of the output state variable, the following macros give the input state variables which are needed in its computation for each row (r) of the state. All the alternative macros give the same end values but expand into different ways of calculating these values. In particular the complex macro used for dynamically variable block sizes is designed to expand to a compile time constant whenever possible but will expand to conditional clauses on some branches (I am grateful to Frank Yellin for this construction) */ #define fwd_var(x,r,c)\ ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\ : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))) #if defined(FT4_SET) #undef dec_fmvars #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c)) #elif defined(FT1_SET) #undef dec_fmvars #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c)) #else #define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c))) #endif #if defined(FL4_SET) #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c)) #elif defined(FL1_SET) #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c)) #else #define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c)) #endif AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]) { uint32_t locals(b0, b1); const uint32_t *kp; #if defined( dec_fmvars ) dec_fmvars; /* declare variables for fwd_mcol() if needed */ #endif if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE) return EXIT_FAILURE; kp = cx->ks; state_in(b0, in, kp); #if (ENC_UNROLL == FULL) switch(cx->inf.b[0]) { case 14 * AES_BLOCK_SIZE: round(fwd_rnd, b1, b0, kp + 1 * N_COLS); round(fwd_rnd, b0, b1, kp + 2 * N_COLS); kp += 2 * N_COLS; case 12 * AES_BLOCK_SIZE: round(fwd_rnd, b1, b0, kp + 1 * N_COLS); round(fwd_rnd, b0, b1, kp + 2 * N_COLS); kp += 2 * N_COLS; case 10 * AES_BLOCK_SIZE: round(fwd_rnd, b1, b0, kp + 1 * N_COLS); round(fwd_rnd, b0, b1, kp + 2 * N_COLS); round(fwd_rnd, b1, b0, kp + 3 * N_COLS); round(fwd_rnd, b0, b1, kp + 4 * N_COLS); round(fwd_rnd, b1, b0, kp + 5 * N_COLS); round(fwd_rnd, b0, b1, kp + 6 * N_COLS); round(fwd_rnd, b1, b0, kp + 7 * N_COLS); round(fwd_rnd, b0, b1, kp + 8 * N_COLS); round(fwd_rnd, b1, b0, kp + 9 * N_COLS); round(fwd_lrnd, b0, b1, kp +10 * N_COLS); } #else #if (ENC_UNROLL == PARTIAL) { uint32_t rnd; for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1ul; ++rnd) { kp += N_COLS; round(fwd_rnd, b1, b0, kp); kp += N_COLS; round(fwd_rnd, b0, b1, kp); } kp += N_COLS; round(fwd_rnd, b1, b0, kp); #else { uint32_t rnd; for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1ul; ++rnd) { kp += N_COLS; round(fwd_rnd, b1, b0, kp); l_copy(b0, b1); } #endif kp += N_COLS; round(fwd_lrnd, b0, b1, kp); } #endif state_out(out, b0); return EXIT_SUCCESS; } #endif #if ( FUNCS_IN_C & DECRYPTION_IN_C) /* Visual C++ .Net v7.1 provides the fastest encryption code when using Pentium optimisation with small code but this is poor for decryption so we need to control this with the following VC++ pragmas */ #if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ ) #pragma optimize( "t", on ) #endif /* Given the column (c) of the output state variable, the following macros give the input state variables which are needed in its computation for each row (r) of the state. All the alternative macros give the same end values but expand into different ways of calculating these values. In particular the complex macro used for dynamically variable block sizes is designed to expand to a compile time constant whenever possible but will expand to conditional clauses on some branches (I am grateful to Frank Yellin for this construction) */ #define inv_var(x,r,c)\ ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\ : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))) #if defined(IT4_SET) #undef dec_imvars #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c)) #elif defined(IT1_SET) #undef dec_imvars #define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c)) #else #define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))) #endif #if defined(IL4_SET) #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c)) #elif defined(IL1_SET) #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c)) #else #define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)) #endif /* This code can work with the decryption key schedule in the */ /* order that is used for encryption (where the 1st decryption */ /* round key is at the high end ot the schedule) or with a key */ /* schedule that has been reversed to put the 1st decryption */ /* round key at the low end of the schedule in memory (when */ /* AES_REV_DKS is defined) */ #ifdef AES_REV_DKS #define key_ofs 0 #define rnd_key(n) (kp + n * N_COLS) #else #define key_ofs 1 #define rnd_key(n) (kp - n * N_COLS) #endif AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]) { uint32_t locals(b0, b1); #if defined( dec_imvars ) dec_imvars; /* declare variables for inv_mcol() if needed */ #endif const uint32_t *kp; if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE) return EXIT_FAILURE; kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0); state_in(b0, in, kp); #if (DEC_UNROLL == FULL) kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2)); switch(cx->inf.b[0]) { case 14 * AES_BLOCK_SIZE: round(inv_rnd, b1, b0, rnd_key(-13)); round(inv_rnd, b0, b1, rnd_key(-12)); case 12 * AES_BLOCK_SIZE: round(inv_rnd, b1, b0, rnd_key(-11)); round(inv_rnd, b0, b1, rnd_key(-10)); case 10 * AES_BLOCK_SIZE: round(inv_rnd, b1, b0, rnd_key(-9)); round(inv_rnd, b0, b1, rnd_key(-8)); round(inv_rnd, b1, b0, rnd_key(-7)); round(inv_rnd, b0, b1, rnd_key(-6)); round(inv_rnd, b1, b0, rnd_key(-5)); round(inv_rnd, b0, b1, rnd_key(-4)); round(inv_rnd, b1, b0, rnd_key(-3)); round(inv_rnd, b0, b1, rnd_key(-2)); round(inv_rnd, b1, b0, rnd_key(-1)); round(inv_lrnd, b0, b1, rnd_key( 0)); } #else #if (DEC_UNROLL == PARTIAL) { uint32_t rnd; for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1ul; ++rnd) { kp = rnd_key(1); round(inv_rnd, b1, b0, kp); kp = rnd_key(1); round(inv_rnd, b0, b1, kp); } kp = rnd_key(1); round(inv_rnd, b1, b0, kp); #else { uint32_t rnd; for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1ul; ++rnd) { kp = rnd_key(1); round(inv_rnd, b1, b0, kp); l_copy(b0, b1); } #endif kp = rnd_key(1); round(inv_lrnd, b0, b1, kp); } #endif state_out(out, b0); return EXIT_SUCCESS; } #endif #if defined(__cplusplus) } #endif #endif /* K5_BUILTIN_AES */ krb5-1.22.1/src/lib/crypto/builtin/aes/aesopt.h0000664000175000017500000006715215051422640021113 0ustar ghudsonghudson/* --------------------------------------------------------------------------- Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. --------------------------------------------------------------------------- Issue Date: 20/12/2007 This file contains the compilation options for AES (Rijndael) and code that is common across encryption, key scheduling and table generation. OPERATION These source code files implement the AES algorithm Rijndael designed by Joan Daemen and Vincent Rijmen. This version is designed for the standard block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes). This version is designed for flexibility and speed using operations on 32-bit words rather than operations on bytes. It can be compiled with either big or little endian internal byte order but is faster when the native byte order for the processor is used. THE CIPHER INTERFACE The cipher interface is implemented as an array of bytes in which lower AES bit sequence indexes map to higher numeric significance within bytes. uint8_t (an unsigned 8-bit type) uint32_t (an unsigned 32-bit type) struct aes_encrypt_ctx (structure for the cipher encryption context) struct aes_decrypt_ctx (structure for the cipher decryption context) AES_RETURN the function return type C subroutine calls: AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]); AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]); IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that you call aes_init() before AES is used so that the tables are initialised. C++ aes class subroutines: Class AESencrypt for encryption Constructors: AESencrypt(void) AESencrypt(const unsigned char *key) - 128 bit key Members: AES_RETURN key128(const unsigned char *key) AES_RETURN key192(const unsigned char *key) AES_RETURN key256(const unsigned char *key) AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const Class AESdecrypt for encryption Constructors: AESdecrypt(void) AESdecrypt(const unsigned char *key) - 128 bit key Members: AES_RETURN key128(const unsigned char *key) AES_RETURN key192(const unsigned char *key) AES_RETURN key256(const unsigned char *key) AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const */ #if !defined( _AESOPT_H ) #define _AESOPT_H #if defined( __cplusplus ) #include "aescpp.h" #else #include "aes.h" #endif /* PLATFORM SPECIFIC INCLUDES */ #include "brg_endian.h" /* CONFIGURATION - THE USE OF DEFINES Later in this section there are a number of defines that control the operation of the code. In each section, the purpose of each define is explained so that the relevant form can be included or excluded by setting either 1's or 0's respectively on the branches of the related #if clauses. The following local defines should not be changed. */ #define ENCRYPTION_IN_C 1 #define DECRYPTION_IN_C 2 #define ENC_KEYING_IN_C 4 #define DEC_KEYING_IN_C 8 #define NO_TABLES 0 #define ONE_TABLE 1 #define FOUR_TABLES 4 #define NONE 0 #define PARTIAL 1 #define FULL 2 /* --- START OF USER CONFIGURED OPTIONS --- */ /* 1. BYTE ORDER WITHIN 32 BIT WORDS The fundamental data processing units in Rijndael are 8-bit bytes. The input, output and key input are all enumerated arrays of bytes in which bytes are numbered starting at zero and increasing to one less than the number of bytes in the array in question. This enumeration is only used for naming bytes and does not imply any adjacency or order relationship from one byte to another. When these inputs and outputs are considered as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte. In this implementation bits are numbered from 0 to 7 starting at the numerically least significant end of each byte (bit n represents 2^n). However, Rijndael can be implemented more efficiently using 32-bit words by packing bytes into words so that bytes 4*n to 4*n+3 are placed into word[n]. While in principle these bytes can be assembled into words in any positions, this implementation only supports the two formats in which bytes in adjacent positions within words also have adjacent byte numbers. This order is called big-endian if the lowest numbered bytes in words have the highest numeric significance and little-endian if the opposite applies. This code can work in either order irrespective of the order used by the machine on which it runs. Normally the internal byte order will be set to the order of the processor on which the code is to be run but this define can be used to reverse this in special situations WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set. This define will hence be redefined later (in section 4) if necessary */ #if 1 # define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER #elif 0 # define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN #elif 0 # define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN #else # error The algorithm byte order is not defined #endif /* 2. Intel AES AND VIA ACE SUPPORT */ #if defined( __GNUC__ ) && defined( __i386__ ) && !defined(__BEOS__) \ || defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \ || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 )) # define VIA_ACE_POSSIBLE #endif /* AESNI is supported by all Windows x64 compilers, but for Linux/GCC we have to test for SSE 2, SSE 3, and AES to before enabling it; */ #if !defined( INTEL_AES_POSSIBLE ) # if defined( _WIN64 ) && defined( _MSC_VER ) \ || defined( __GNUC__ ) && defined( __x86_64__ ) && \ defined( __SSE2__ ) && defined( __SSE3__ ) && \ defined( __AES__ ) # define INTEL_AES_POSSIBLE # endif #endif /* Define this option if support for the Intel AESNI is required If USE_INTEL_AES_IF_PRESENT is defined then AESNI will be used if it is detected (both present and enabled). AESNI uses a decryption key schedule with the first decryption round key at the high end of the key schedule with the following round keys at lower positions in memory. So AES_REV_DKS must NOT be defined when AESNI will be used. Although it is unlikely that assembler code will be used with an AESNI build, if it is then AES_REV_DKS must NOT be defined when the assembler files are built (the definition of USE_INTEL_AES_IF_PRESENT in the assembler code files must match that here if they are used). */ #if defined( INTEL_AES_POSSIBLE ) # if 0 && !defined( USE_INTEL_AES_IF_PRESENT ) # define USE_INTEL_AES_IF_PRESENT # endif #elif defined( USE_INTEL_AES_IF_PRESENT ) # error: AES_NI is not available on this platform #endif /* Define this option if support for the VIA ACE is required. This uses inline assembler instructions and is only implemented for the Microsoft, Intel and GCC compilers. If VIA ACE is known to be present, then defining ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if it is detected (both present and enabled) but the normal AES code will also be present. When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte aligned; other input/output buffers do not need to be 16 byte aligned but there are very large performance gains if this can be arranged. VIA ACE also requires the decryption key schedule to be in reverse order (which later checks below ensure). AES_REV_DKS must be set for assembler code used with a VIA ACE build */ #if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT ) # define USE_VIA_ACE_IF_PRESENT #endif #if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT ) # define ASSUME_VIA_ACE_PRESENT # endif /* 3. ASSEMBLER SUPPORT This define (which can be on the command line) enables the use of the assembler code routines for encryption, decryption and key scheduling as follows: ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for encryption and decryption and but with key scheduling in C ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for encryption, decryption and key scheduling ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for encryption and decryption and but with key scheduling in C ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for encryption and decryption and but with key scheduling in C Change one 'if 0' below to 'if 1' to select the version or define as a compilation option. */ #if 0 && !defined( ASM_X86_V1C ) # define ASM_X86_V1C #elif 0 && !defined( ASM_X86_V2 ) # define ASM_X86_V2 #elif 0 && !defined( ASM_X86_V2C ) # define ASM_X86_V2C #elif 0 && !defined( ASM_AMD64_C ) # define ASM_AMD64_C #endif #if defined( __i386 ) || defined( _M_IX86 ) # define A32_ #elif defined( __x86_64__ ) || defined( _M_X64 ) # define A64_ #endif #if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \ && !defined( A32_ ) || defined( ASM_AMD64_C ) && !defined( A64_ ) # error Assembler code is only available for x86 and AMD64 systems #endif /* 4. FAST INPUT/OUTPUT OPERATIONS. On some machines it is possible to improve speed by transferring the bytes in the input and output arrays to and from the internal 32-bit variables by addressing these arrays as if they are arrays of 32-bit words. On some machines this will always be possible but there may be a large performance penalty if the byte arrays are not aligned on the normal word boundaries. On other machines this technique will lead to memory access errors when such 32-bit word accesses are not properly aligned. The option SAFE_IO avoids such problems but will often be slower on those machines that support misaligned access (especially so if care is taken to align the input and output byte arrays on 32-bit word boundaries). If SAFE_IO is not defined it is assumed that access to byte arrays as if they are arrays of 32-bit words will not cause problems when such accesses are misaligned. */ #if 1 && !defined( _MSC_VER ) # define SAFE_IO #endif /* 5. LOOP UNROLLING The code for encryption and decryption cycles through a number of rounds that can be implemented either in a loop or by expanding the code into a long sequence of instructions, the latter producing a larger program but one that will often be much faster. The latter is called loop unrolling. There are also potential speed advantages in expanding two iterations in a loop with half the number of iterations, which is called partial loop unrolling. The following options allow partial or full loop unrolling to be set independently for encryption and decryption */ #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) # define ENC_UNROLL FULL #elif 0 # define ENC_UNROLL PARTIAL #else # define ENC_UNROLL NONE #endif #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) # define DEC_UNROLL FULL #elif 0 # define DEC_UNROLL PARTIAL #else # define DEC_UNROLL NONE #endif #if 1 # define ENC_KS_UNROLL #endif #if 1 # define DEC_KS_UNROLL #endif /* 6. FAST FINITE FIELD OPERATIONS If this section is included, tables are used to provide faster finite field arithmetic (this has no effect if STATIC_TABLES is defined). */ #if 1 # define FF_TABLES #endif /* 7. INTERNAL STATE VARIABLE FORMAT The internal state of Rijndael is stored in a number of local 32-bit word variables which can be defined either as an array or as individual names variables. Include this section if you want to store these local variables in arrays. Otherwise individual local variables will be used. */ #if 1 # define ARRAYS #endif /* 8. FIXED OR DYNAMIC TABLES When this section is included the tables used by the code are compiled statically into the binary file. Otherwise the subroutine aes_init() must be called to compute them before the code is first used. */ #if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 )) # define STATIC_TABLES #endif /* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES In some systems it is better to mask longer values to extract bytes rather than using a cast. This option allows this choice. */ #if 0 # define to_byte(x) ((uint8_t)(x)) #else # define to_byte(x) ((x) & 0xff) #endif /* 10. TABLE ALIGNMENT On some systems speed will be improved by aligning the AES large lookup tables on particular boundaries. This define should be set to a power of two giving the desired alignment. It can be left undefined if alignment is not needed. This option is specific to the Microsoft VC++ compiler - it seems to sometimes cause trouble for the VC++ version 6 compiler. */ #if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) # define TABLE_ALIGN 32 #endif /* 11. REDUCE CODE AND TABLE SIZE This replaces some expanded macros with function calls if AES_ASM_V2 or AES_ASM_V2C are defined */ #if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) # define REDUCE_CODE_SIZE #endif /* 12. TABLE OPTIONS This cipher proceeds by repeating in a number of cycles known as 'rounds' which are implemented by a round function which can optionally be speeded up using tables. The basic tables are each 256 32-bit words, with either one or four tables being required for each round function depending on how much speed is required. The encryption and decryption round functions are different and the last encryption and decryption round functions are different again making four different round functions in all. This means that: 1. Normal encryption and decryption rounds can each use either 0, 1 or 4 tables and table spaces of 0, 1024 or 4096 bytes each. 2. The last encryption and decryption rounds can also use either 0, 1 or 4 tables and table spaces of 0, 1024 or 4096 bytes each. Include or exclude the appropriate definitions below to set the number of tables used by this implementation. */ #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) /* set tables for the normal encryption round */ # define ENC_ROUND FOUR_TABLES #elif 0 # define ENC_ROUND ONE_TABLE #else # define ENC_ROUND NO_TABLES #endif #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) /* set tables for the last encryption round */ # define LAST_ENC_ROUND FOUR_TABLES #elif 0 # define LAST_ENC_ROUND ONE_TABLE #else # define LAST_ENC_ROUND NO_TABLES #endif #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) /* set tables for the normal decryption round */ # define DEC_ROUND FOUR_TABLES #elif 0 # define DEC_ROUND ONE_TABLE #else # define DEC_ROUND NO_TABLES #endif #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) /* set tables for the last decryption round */ # define LAST_DEC_ROUND FOUR_TABLES #elif 0 # define LAST_DEC_ROUND ONE_TABLE #else # define LAST_DEC_ROUND NO_TABLES #endif /* The decryption key schedule can be speeded up with tables in the same way that the round functions can. Include or exclude the following defines to set this requirement. */ #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO) # define KEY_SCHED FOUR_TABLES #elif 0 # define KEY_SCHED ONE_TABLE #else # define KEY_SCHED NO_TABLES #endif /* ---- END OF USER CONFIGURED OPTIONS ---- */ /* VIA ACE support is only available for VC++ and GCC */ #if !defined( _MSC_VER ) && !defined( __GNUC__ ) # if defined( ASSUME_VIA_ACE_PRESENT ) # undef ASSUME_VIA_ACE_PRESENT # endif # if defined( USE_VIA_ACE_IF_PRESENT ) # undef USE_VIA_ACE_IF_PRESENT # endif #endif #if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT ) # define USE_VIA_ACE_IF_PRESENT #endif /* define to reverse decryption key schedule */ #if 1 || defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS ) # define AES_REV_DKS #endif /* Intel AESNI uses a decryption key schedule in the encryption order */ #if defined( USE_INTEL_AES_IF_PRESENT ) && defined ( AES_REV_DKS ) # undef AES_REV_DKS #endif /* Assembler support requires the use of platform byte order */ #if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \ && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER) # undef ALGORITHM_BYTE_ORDER # define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER #endif /* In this implementation the columns of the state array are each held in 32-bit words. The state array can be held in various ways: in an array of words, in a number of individual word variables or in a number of processor registers. The following define maps a variable name x and a column number c to the way the state array variable is to be held. The first define below maps the state into an array x[c] whereas the second form maps the state into a number of individual variables x0, x1, etc. Another form could map individual state columns to machine register names. */ #if defined( ARRAYS ) # define s(x,c) x[c] #else # define s(x,c) x##c #endif /* This implementation provides subroutines for encryption, decryption and for setting the three key lengths (separately) for encryption and decryption. Since not all functions are needed, masks are set up here to determine which will be implemented in C */ #if !defined( AES_ENCRYPT ) # define EFUNCS_IN_C 0 #elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \ || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) # define EFUNCS_IN_C ENC_KEYING_IN_C #elif !defined( ASM_X86_V2 ) # define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C ) #else # define EFUNCS_IN_C 0 #endif #if !defined( AES_DECRYPT ) # define DFUNCS_IN_C 0 #elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \ || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) # define DFUNCS_IN_C DEC_KEYING_IN_C #elif !defined( ASM_X86_V2 ) # define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C ) #else # define DFUNCS_IN_C 0 #endif #define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C ) /* END OF CONFIGURATION OPTIONS */ #define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2)) /* Disable or report errors on some combinations of options */ #if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES # undef LAST_ENC_ROUND # define LAST_ENC_ROUND NO_TABLES #elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES # undef LAST_ENC_ROUND # define LAST_ENC_ROUND ONE_TABLE #endif #if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE # undef ENC_UNROLL # define ENC_UNROLL NONE #endif #if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES # undef LAST_DEC_ROUND # define LAST_DEC_ROUND NO_TABLES #elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES # undef LAST_DEC_ROUND # define LAST_DEC_ROUND ONE_TABLE #endif #if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE # undef DEC_UNROLL # define DEC_UNROLL NONE #endif #if defined( bswap32 ) # define aes_sw32 bswap32 #elif defined( bswap_32 ) # define aes_sw32 bswap_32 #else # define brot(x,n) (((uint32_t)(x) << n) | ((uint32_t)(x) >> (32 - n))) # define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00)) #endif /* upr(x,n): rotates bytes within words by n positions, moving bytes to higher index positions with wrap around into low positions ups(x,n): moves bytes by n positions to higher index positions in words but without wrap around bval(x,n): extracts a byte from a word WARNING: The definitions given here are intended only for use with unsigned variables and with shift counts that are compile time constants */ #if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN ) # define upr(x,n) (((uint32_t)(x) << (8 * (n))) | ((uint32_t)(x) >> (32 - 8 * (n)))) # define ups(x,n) ((uint32_t) (x) << (8 * (n))) # define bval(x,n) to_byte((x) >> (8 * (n))) # define bytes2word(b0, b1, b2, b3) \ (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0)) #endif #if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN ) # define upr(x,n) (((uint32_t)(x) >> (8 * (n))) | ((uint32_t)(x) << (32 - 8 * (n)))) # define ups(x,n) ((uint32_t) (x) >> (8 * (n))) # define bval(x,n) to_byte((x) >> (24 - 8 * (n))) # define bytes2word(b0, b1, b2, b3) \ (((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3)) #endif #if defined( SAFE_IO ) # define word_in(x,c) bytes2word(((const uint8_t*)(x)+4*c)[0], ((const uint8_t*)(x)+4*c)[1], \ ((const uint8_t*)(x)+4*c)[2], ((const uint8_t*)(x)+4*c)[3]) # define word_out(x,c,v) { ((uint8_t*)(x)+4*c)[0] = bval(v,0); ((uint8_t*)(x)+4*c)[1] = bval(v,1); \ ((uint8_t*)(x)+4*c)[2] = bval(v,2); ((uint8_t*)(x)+4*c)[3] = bval(v,3); } #elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER ) # define word_in(x,c) (*((uint32_t*)(x)+(c))) # define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v)) #else # define word_in(x,c) aes_sw32(*((uint32_t*)(x)+(c))) # define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = aes_sw32(v)) #endif /* the finite field modular polynomial and elements */ #define WPOLY 0x011b #define BPOLY 0x1b /* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ #define gf_c1 0x80808080 #define gf_c2 0x7f7f7f7f #define gf_mulx(x) ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY)) /* The following defines provide alternative definitions of gf_mulx that might give improved performance if a fast 32-bit multiply is not available. Note that a temporary variable u needs to be defined where gf_mulx is used. #define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6)) #define gf_c4 (0x01010101 * BPOLY) #define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4) */ /* Work out which tables are needed for the different options */ #if defined( ASM_X86_V1C ) # if defined( ENC_ROUND ) # undef ENC_ROUND # endif # define ENC_ROUND FOUR_TABLES # if defined( LAST_ENC_ROUND ) # undef LAST_ENC_ROUND # endif # define LAST_ENC_ROUND FOUR_TABLES # if defined( DEC_ROUND ) # undef DEC_ROUND # endif # define DEC_ROUND FOUR_TABLES # if defined( LAST_DEC_ROUND ) # undef LAST_DEC_ROUND # endif # define LAST_DEC_ROUND FOUR_TABLES # if defined( KEY_SCHED ) # undef KEY_SCHED # define KEY_SCHED FOUR_TABLES # endif #endif #if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C ) # if ENC_ROUND == ONE_TABLE # define FT1_SET # elif ENC_ROUND == FOUR_TABLES # define FT4_SET # else # define SBX_SET # endif # if LAST_ENC_ROUND == ONE_TABLE # define FL1_SET # elif LAST_ENC_ROUND == FOUR_TABLES # define FL4_SET # elif !defined( SBX_SET ) # define SBX_SET # endif #endif #if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C ) # if DEC_ROUND == ONE_TABLE # define IT1_SET # elif DEC_ROUND == FOUR_TABLES # define IT4_SET # else # define ISB_SET # endif # if LAST_DEC_ROUND == ONE_TABLE # define IL1_SET # elif LAST_DEC_ROUND == FOUR_TABLES # define IL4_SET # elif !defined(ISB_SET) # define ISB_SET # endif #endif #if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) # if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C)) # if KEY_SCHED == ONE_TABLE # if !defined( FL1_SET ) && !defined( FL4_SET ) # define LS1_SET # endif # elif KEY_SCHED == FOUR_TABLES # if !defined( FL4_SET ) # define LS4_SET # endif # elif !defined( SBX_SET ) # define SBX_SET # endif # endif # if (FUNCS_IN_C & DEC_KEYING_IN_C) # if KEY_SCHED == ONE_TABLE # define IM1_SET # elif KEY_SCHED == FOUR_TABLES # define IM4_SET # elif !defined( SBX_SET ) # define SBX_SET # endif # endif #endif /* generic definitions of Rijndael macros that use tables */ #define no_table(x,box,vf,rf,c) bytes2word( \ box[bval(vf(x,0,c),rf(0,c))], \ box[bval(vf(x,1,c),rf(1,c))], \ box[bval(vf(x,2,c),rf(2,c))], \ box[bval(vf(x,3,c),rf(3,c))]) #define one_table(x,op,tab,vf,rf,c) \ ( tab[bval(vf(x,0,c),rf(0,c))] \ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) #define four_tables(x,tab,vf,rf,c) \ ( tab[0][bval(vf(x,0,c),rf(0,c))] \ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ ^ tab[3][bval(vf(x,3,c),rf(3,c))]) #define vf1(x,r,c) (x) #define rf1(r,c) (r) #define rf2(r,c) ((8+r-c)&3) /* perform forward and inverse column mix operation on four bytes in long word x in */ /* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */ #if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) #if defined( FM4_SET ) /* not currently used */ # define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0) #elif defined( FM1_SET ) /* not currently used */ # define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0) #else # define dec_fmvars uint32_t g2 # define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1)) #endif #if defined( IM4_SET ) # define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0) #elif defined( IM1_SET ) # define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0) #else # define dec_imvars uint32_t g2, g4, g9 # define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \ (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1)) #endif #if defined( FL4_SET ) # define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c) #elif defined( LS4_SET ) # define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c) #elif defined( FL1_SET ) # define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c) #elif defined( LS1_SET ) # define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c) #else # define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c) #endif #endif #if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET ) # define ISB_SET #endif #endif krb5-1.22.1/src/lib/crypto/builtin/aes/brg_types.h0000664000175000017500000001716415051422640021614 0ustar ghudsonghudson/* --------------------------------------------------------------------------- Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. --------------------------------------------------------------------------- Issue Date: 30/09/2017 */ #ifndef _BRG_TYPES_H #define _BRG_TYPES_H #if defined(__cplusplus) extern "C" { #endif #include #include #if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) # include # define ptrint_t intptr_t #elif defined( __ECOS__ ) # define intptr_t unsigned int # define ptrint_t intptr_t #elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) && !(defined( __HAIKU__ ) || defined( __VxWorks__ )) # define ptrint_t intptr_t #else # define ptrint_t int #endif /* define unsigned 8-bit type if not available in stdint.h */ #if !defined(UINT8_MAX) typedef unsigned char uint8_t; #endif /* define unsigned 16-bit type if not available in stdint.h */ #if !defined(UINT16_MAX) typedef unsigned short uint16_t; #endif /* define unsigned 32-bit type if not available in stdint.h and define the macro li_32(h) which converts a sequence of eight hexadecimal characters into a 32 bit constant */ #if defined(UINT_MAX) && UINT_MAX == 4294967295u # define li_32(h) 0x##h##u # if !defined(UINT32_MAX) typedef unsigned int uint32_t; # endif #elif defined(ULONG_MAX) && ULONG_MAX == 4294967295u # define li_32(h) 0x##h##ul # if !defined(UINT32_MAX) typedef unsigned long uint32_t; # endif #elif defined( _CRAY ) # error This code needs 32-bit data types, which Cray machines do not provide #else # error Please define uint32_t as a 32-bit unsigned integer type in brg_types.h #endif /* define unsigned 64-bit type if not available in stdint.h and define the macro li_64(h) which converts a sequence of eight hexadecimal characters into a 64 bit constant */ #if defined( __BORLANDC__ ) && !defined( __MSDOS__ ) # define li_64(h) 0x##h##ui64 # if !defined(UINT64_MAX) typedef unsigned __int64 uint64_t; # endif #elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */ # define li_64(h) 0x##h##ui64 # if !defined(UINT64_MAX) typedef unsigned __int64 uint64_t; # endif #elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful # define li_64(h) 0x##h##ull # if !defined(UINT64_MAX) typedef unsigned long long uint64_t; # endif #elif defined( __MVS__ ) # define li_64(h) 0x##h##ull # if !defined(UINT64_MAX) typedef unsigned long long uint64_t; # endif #elif defined( UINT_MAX ) && UINT_MAX > 4294967295u # if UINT_MAX == 18446744073709551615u # define li_64(h) 0x##h##u # if !defined(UINT64_MAX) typedef unsigned int uint64_t; # endif # endif #elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u # if ULONG_MAX == 18446744073709551615ul # define li_64(h) 0x##h##ul # if !defined(UINT64_MAX) && !defined(_UINT64_T) typedef unsigned long uint64_t; # endif # endif #elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u # if ULLONG_MAX == 18446744073709551615ull # define li_64(h) 0x##h##ull # if !defined(UINT64_MAX) && !defined( __HAIKU__ ) typedef unsigned long long uint64_t; # endif # endif #elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u # if ULONG_LONG_MAX == 18446744073709551615ull # define li_64(h) 0x##h##ull # if !defined(UINT64_MAX) typedef unsigned long long uint64_t; # endif # endif #endif #if !defined( li_64 ) # if defined( NEED_UINT_64T ) # error Please define uint64_t as an unsigned 64 bit type in brg_types.h # endif #endif #ifndef RETURN_VALUES # define RETURN_VALUES # if defined( DLL_EXPORT ) # if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) # define VOID_RETURN __declspec( dllexport ) void __stdcall # define INT_RETURN __declspec( dllexport ) int __stdcall # elif defined( __GNUC__ ) # define VOID_RETURN __declspec( __dllexport__ ) void # define INT_RETURN __declspec( __dllexport__ ) int # else # error Use of the DLL is only available on the Microsoft, Intel and GCC compilers # endif # elif defined( DLL_IMPORT ) # if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) # define VOID_RETURN __declspec( dllimport ) void __stdcall # define INT_RETURN __declspec( dllimport ) int __stdcall # elif defined( __GNUC__ ) # define VOID_RETURN __declspec( __dllimport__ ) void # define INT_RETURN __declspec( __dllimport__ ) int # else # error Use of the DLL is only available on the Microsoft, Intel and GCC compilers # endif # elif defined( __WATCOMC__ ) # define VOID_RETURN void __cdecl # define INT_RETURN int __cdecl # else # define VOID_RETURN void # define INT_RETURN int # endif #endif /* These defines are used to detect and set the memory alignment of pointers. Note that offsets are in bytes. ALIGN_OFFSET(x,n) return the positive or zero offset of the memory addressed by the pointer 'x' from an address that is aligned on an 'n' byte boundary ('n' is a power of 2) ALIGN_FLOOR(x,n) return a pointer that points to memory that is aligned on an 'n' byte boundary and is not higher than the memory address pointed to by 'x' ('n' is a power of 2) ALIGN_CEIL(x,n) return a pointer that points to memory that is aligned on an 'n' byte boundary and is not lower than the memory address pointed to by 'x' ('n' is a power of 2) */ #define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1)) #define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1))) #define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((ptrint_t)(x)) & ((n) - 1))) /* These defines are used to declare buffers in a way that allows faster operations on longer variables to be used. In all these defines 'size' must be a power of 2 and >= 8. NOTE that the buffer size is in bytes but the type length is in bits UNIT_TYPEDEF(x,size) declares a variable 'x' of length 'size' bits BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize' bytes defined as an array of variables each of 'size' bits (bsize must be a multiple of size / 8) UNIT_CAST(x,size) casts a variable to a type of length 'size' bits UPTR_CAST(x,size) casts a pointer to a pointer to a variable of length 'size' bits */ #define UI_TYPE(size) uint##size##_t #define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x #define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)] #define UNIT_CAST(x,size) ((UI_TYPE(size) )(x)) #define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x)) #if defined(__cplusplus) } #endif #endif krb5-1.22.1/src/lib/crypto/builtin/aes/aeskey.c0000664000175000017500000004040115051422640021060 0ustar ghudsonghudson/* --------------------------------------------------------------------------- Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: source code distributions include the above copyright notice, this list of conditions and the following disclaimer; binary distributions include the above copyright notice, this list of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties in respect of its operation, including, but not limited to, correctness and fitness for purpose. --------------------------------------------------------------------------- Issue Date: 20/12/2007 */ #include "aesopt.h" #include "aestab.h" #include "crypto_int.h" #ifdef K5_BUILTIN_AES #if defined( USE_INTEL_AES_IF_PRESENT ) # include "aes_ni.h" #else /* map names here to provide the external API ('name' -> 'aes_name') */ # define aes_xi(x) aes_ ## x #endif #ifdef USE_VIA_ACE_IF_PRESENT # include "aes_via_ace.h" #endif #if defined(__cplusplus) extern "C" { #endif /* Use the low bit in the context's inf.b[2] as a flag to indicate whether a context was initialized for encryption or decryption. */ #define MARK_AS_ENCRYPTION_CTX(cx) (cx)->inf.b[2] |= (uint8_t)0x01 #define MARK_AS_DECRYPTION_CTX(cx) (cx)->inf.b[2] &= (uint8_t)0xfe /* Initialise the key schedule from the user supplied key. The key length can be specified in bytes, with legal values of 16, 24 and 32, or in bits, with legal values of 128, 192 and 256. These values correspond with Nk values of 4, 6 and 8 respectively. The following macros implement a single cycle in the key schedule generation process. The number of cycles needed for each cx->n_col and nk value is: nk = 4 5 6 7 8 ------------------------------ cx->n_col = 4 10 9 8 7 7 cx->n_col = 5 14 11 10 9 9 cx->n_col = 6 19 15 12 11 11 cx->n_col = 7 21 19 16 13 14 cx->n_col = 8 29 23 19 17 14 */ #if defined( REDUCE_CODE_SIZE ) # define ls_box ls_sub uint32_t ls_sub(const uint32_t t, const uint32_t n); # define inv_mcol im_sub uint32_t im_sub(const uint32_t x); # ifdef ENC_KS_UNROLL # undef ENC_KS_UNROLL # endif # ifdef DEC_KS_UNROLL # undef DEC_KS_UNROLL # endif #endif #if (FUNCS_IN_C & ENC_KEYING_IN_C) #if defined(AES_128) || defined( AES_VAR ) #define ke4(k,i) \ { k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ k[4*(i)+5] = ss[1] ^= ss[0]; \ k[4*(i)+6] = ss[2] ^= ss[1]; \ k[4*(i)+7] = ss[3] ^= ss[2]; \ } AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1]) { uint32_t ss[4]; cx->ks[0] = ss[0] = word_in(key, 0); cx->ks[1] = ss[1] = word_in(key, 1); cx->ks[2] = ss[2] = word_in(key, 2); cx->ks[3] = ss[3] = word_in(key, 3); #ifdef ENC_KS_UNROLL ke4(cx->ks, 0); ke4(cx->ks, 1); ke4(cx->ks, 2); ke4(cx->ks, 3); ke4(cx->ks, 4); ke4(cx->ks, 5); ke4(cx->ks, 6); ke4(cx->ks, 7); ke4(cx->ks, 8); #else { uint32_t i; for(i = 0; i < 9; ++i) ke4(cx->ks, i); } #endif ke4(cx->ks, 9); cx->inf.l = 0; cx->inf.b[0] = 10 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif MARK_AS_ENCRYPTION_CTX(cx); return EXIT_SUCCESS; } #endif #if defined(AES_192) || defined( AES_VAR ) #define kef6(k,i) \ { k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ k[6*(i)+ 7] = ss[1] ^= ss[0]; \ k[6*(i)+ 8] = ss[2] ^= ss[1]; \ k[6*(i)+ 9] = ss[3] ^= ss[2]; \ } #define ke6(k,i) \ { kef6(k,i); \ k[6*(i)+10] = ss[4] ^= ss[3]; \ k[6*(i)+11] = ss[5] ^= ss[4]; \ } AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1]) { uint32_t ss[6]; cx->ks[0] = ss[0] = word_in(key, 0); cx->ks[1] = ss[1] = word_in(key, 1); cx->ks[2] = ss[2] = word_in(key, 2); cx->ks[3] = ss[3] = word_in(key, 3); cx->ks[4] = ss[4] = word_in(key, 4); cx->ks[5] = ss[5] = word_in(key, 5); #ifdef ENC_KS_UNROLL ke6(cx->ks, 0); ke6(cx->ks, 1); ke6(cx->ks, 2); ke6(cx->ks, 3); ke6(cx->ks, 4); ke6(cx->ks, 5); ke6(cx->ks, 6); #else { uint32_t i; for(i = 0; i < 7; ++i) ke6(cx->ks, i); } #endif kef6(cx->ks, 7); cx->inf.l = 0; cx->inf.b[0] = 12 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif MARK_AS_ENCRYPTION_CTX(cx); return EXIT_SUCCESS; } #endif #if defined(AES_256) || defined( AES_VAR ) #define kef8(k,i) \ { k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ k[8*(i)+ 9] = ss[1] ^= ss[0]; \ k[8*(i)+10] = ss[2] ^= ss[1]; \ k[8*(i)+11] = ss[3] ^= ss[2]; \ } #define ke8(k,i) \ { kef8(k,i); \ k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \ k[8*(i)+13] = ss[5] ^= ss[4]; \ k[8*(i)+14] = ss[6] ^= ss[5]; \ k[8*(i)+15] = ss[7] ^= ss[6]; \ } AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1]) { uint32_t ss[8]; cx->ks[0] = ss[0] = word_in(key, 0); cx->ks[1] = ss[1] = word_in(key, 1); cx->ks[2] = ss[2] = word_in(key, 2); cx->ks[3] = ss[3] = word_in(key, 3); cx->ks[4] = ss[4] = word_in(key, 4); cx->ks[5] = ss[5] = word_in(key, 5); cx->ks[6] = ss[6] = word_in(key, 6); cx->ks[7] = ss[7] = word_in(key, 7); #ifdef ENC_KS_UNROLL ke8(cx->ks, 0); ke8(cx->ks, 1); ke8(cx->ks, 2); ke8(cx->ks, 3); ke8(cx->ks, 4); ke8(cx->ks, 5); #else { uint32_t i; for(i = 0; i < 6; ++i) ke8(cx->ks, i); } #endif kef8(cx->ks, 6); cx->inf.l = 0; cx->inf.b[0] = 14 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif MARK_AS_ENCRYPTION_CTX(cx); return EXIT_SUCCESS; } #endif #endif #if (FUNCS_IN_C & DEC_KEYING_IN_C) /* this is used to store the decryption round keys */ /* in forward or reverse order */ #ifdef AES_REV_DKS #define v(n,i) ((n) - (i) + 2 * ((i) & 3)) #else #define v(n,i) (i) #endif #if DEC_ROUND == NO_TABLES #define ff(x) (x) #else #define ff(x) inv_mcol(x) #if defined( dec_imvars ) #define d_vars dec_imvars #endif #endif #if defined(AES_128) || defined( AES_VAR ) #define k4e(k,i) \ { k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \ k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \ k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \ } #if 1 #define kdf4(k,i) \ { ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \ ss[1] = ss[1] ^ ss[3]; \ ss[2] = ss[2] ^ ss[3]; \ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ ss[i % 4] ^= ss[4]; \ ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \ ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \ ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \ ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \ } #define kd4(k,i) \ { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \ k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \ k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \ k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \ k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \ } #define kdl4(k,i) \ { ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \ k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \ k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \ k[v(40,(4*(i))+6)] = ss[0]; \ k[v(40,(4*(i))+7)] = ss[1]; \ } #else #define kdf4(k,i) \ { ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \ ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \ ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \ ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \ } #define kd4(k,i) \ { ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \ ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \ ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \ ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \ ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \ } #define kdl4(k,i) \ { ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \ ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \ ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \ ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \ } #endif AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1]) { uint32_t ss[5]; #if defined( d_vars ) d_vars; #endif cx->ks[v(40,(0))] = ss[0] = word_in(key, 0); cx->ks[v(40,(1))] = ss[1] = word_in(key, 1); cx->ks[v(40,(2))] = ss[2] = word_in(key, 2); cx->ks[v(40,(3))] = ss[3] = word_in(key, 3); #ifdef DEC_KS_UNROLL kdf4(cx->ks, 0); kd4(cx->ks, 1); kd4(cx->ks, 2); kd4(cx->ks, 3); kd4(cx->ks, 4); kd4(cx->ks, 5); kd4(cx->ks, 6); kd4(cx->ks, 7); kd4(cx->ks, 8); kdl4(cx->ks, 9); #else { uint32_t i; for(i = 0; i < 10; ++i) k4e(cx->ks, i); #if !(DEC_ROUND == NO_TABLES) for(i = N_COLS; i < 10 * N_COLS; ++i) cx->ks[i] = inv_mcol(cx->ks[i]); #endif } #endif cx->inf.l = 0; cx->inf.b[0] = 10 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif MARK_AS_DECRYPTION_CTX(cx); return EXIT_SUCCESS; } #endif #if defined(AES_192) || defined( AES_VAR ) #define k6ef(k,i) \ { k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \ k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \ k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \ } #define k6e(k,i) \ { k6ef(k,i); \ k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \ k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \ } #define kdf6(k,i) \ { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \ ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \ ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \ ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \ ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \ ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \ } #define kd6(k,i) \ { ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \ ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \ ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \ ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \ ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \ ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \ ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \ } #define kdl6(k,i) \ { ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \ ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \ ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \ ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \ } AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1]) { uint32_t ss[7]; #if defined( d_vars ) d_vars; #endif cx->ks[v(48,(0))] = ss[0] = word_in(key, 0); cx->ks[v(48,(1))] = ss[1] = word_in(key, 1); cx->ks[v(48,(2))] = ss[2] = word_in(key, 2); cx->ks[v(48,(3))] = ss[3] = word_in(key, 3); #ifdef DEC_KS_UNROLL ss[4] = word_in(key, 4); ss[5] = word_in(key, 5); cx->ks[v(48, (4))] = ff(ss[4]); cx->ks[v(48, (5))] = ff(ss[5]); kdf6(cx->ks, 0); kd6(cx->ks, 1); kd6(cx->ks, 2); kd6(cx->ks, 3); kd6(cx->ks, 4); kd6(cx->ks, 5); kd6(cx->ks, 6); kdl6(cx->ks, 7); #else cx->ks[v(48,(4))] = ss[4] = word_in(key, 4); cx->ks[v(48,(5))] = ss[5] = word_in(key, 5); { uint32_t i; for(i = 0; i < 7; ++i) k6e(cx->ks, i); k6ef(cx->ks, 7); #if !(DEC_ROUND == NO_TABLES) for(i = N_COLS; i < 12 * N_COLS; ++i) cx->ks[i] = inv_mcol(cx->ks[i]); #endif } #endif cx->inf.l = 0; cx->inf.b[0] = 12 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif MARK_AS_DECRYPTION_CTX(cx); return EXIT_SUCCESS; } #endif #if defined(AES_256) || defined( AES_VAR ) #define k8ef(k,i) \ { k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \ k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \ k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \ } #define k8e(k,i) \ { k8ef(k,i); \ k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \ k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \ k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \ k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \ } #define kdf8(k,i) \ { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \ ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \ ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \ ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \ ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \ ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \ ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \ ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \ } #define kd8(k,i) \ { ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \ ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \ ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \ ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \ ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \ ss[8] = ls_box(ss[3],0); \ ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \ ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \ ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \ ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \ } #define kdl8(k,i) \ { ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \ ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \ ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \ ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \ } AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1]) { uint32_t ss[9]; #if defined( d_vars ) d_vars; #endif cx->ks[v(56,(0))] = ss[0] = word_in(key, 0); cx->ks[v(56,(1))] = ss[1] = word_in(key, 1); cx->ks[v(56,(2))] = ss[2] = word_in(key, 2); cx->ks[v(56,(3))] = ss[3] = word_in(key, 3); #ifdef DEC_KS_UNROLL ss[4] = word_in(key, 4); ss[5] = word_in(key, 5); ss[6] = word_in(key, 6); ss[7] = word_in(key, 7); cx->ks[v(56,(4))] = ff(ss[4]); cx->ks[v(56,(5))] = ff(ss[5]); cx->ks[v(56,(6))] = ff(ss[6]); cx->ks[v(56,(7))] = ff(ss[7]); kdf8(cx->ks, 0); kd8(cx->ks, 1); kd8(cx->ks, 2); kd8(cx->ks, 3); kd8(cx->ks, 4); kd8(cx->ks, 5); kdl8(cx->ks, 6); #else cx->ks[v(56,(4))] = ss[4] = word_in(key, 4); cx->ks[v(56,(5))] = ss[5] = word_in(key, 5); cx->ks[v(56,(6))] = ss[6] = word_in(key, 6); cx->ks[v(56,(7))] = ss[7] = word_in(key, 7); { uint32_t i; for(i = 0; i < 6; ++i) k8e(cx->ks, i); k8ef(cx->ks, 6); #if !(DEC_ROUND == NO_TABLES) for(i = N_COLS; i < 14 * N_COLS; ++i) cx->ks[i] = inv_mcol(cx->ks[i]); #endif } #endif cx->inf.l = 0; cx->inf.b[0] = 14 * AES_BLOCK_SIZE; #ifdef USE_VIA_ACE_IF_PRESENT if(VIA_ACE_AVAILABLE) cx->inf.b[1] = 0xff; #endif MARK_AS_DECRYPTION_CTX(cx); return EXIT_SUCCESS; } #endif #endif #if defined( AES_VAR ) AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) { switch(key_len) { case 16: case 128: return aes_encrypt_key128(key, cx); case 24: case 192: return aes_encrypt_key192(key, cx); case 32: case 256: return aes_encrypt_key256(key, cx); default: return EXIT_FAILURE; } } AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) { switch(key_len) { case 16: case 128: return aes_decrypt_key128(key, cx); case 24: case 192: return aes_decrypt_key192(key, cx); case 32: case 256: return aes_decrypt_key256(key, cx); default: return EXIT_FAILURE; } } #endif #if defined(__cplusplus) } #endif #endif /* K5_BUILTIN_AES */ krb5-1.22.1/src/lib/crypto/builtin/cmac.c0000664000175000017500000001314515051422640017737 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/cmac.c */ /* * Copyright 2010 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #ifdef K5_BUILTIN_CMAC #define BLOCK_SIZE 16 static unsigned char const_Rb[BLOCK_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }; static void xor_128(unsigned char *a, unsigned char *b, unsigned char *out) { int z; for (z = 0; z < BLOCK_SIZE / 4; z++) { unsigned char *aptr = &a[z * 4]; unsigned char *bptr = &b[z * 4]; unsigned char *outptr = &out[z * 4]; store_32_n(load_32_n(aptr) ^ load_32_n(bptr), outptr); } } static void leftshift_onebit(unsigned char *input, unsigned char *output) { int i; unsigned char overflow = 0; for (i = BLOCK_SIZE - 1; i >= 0; i--) { output[i] = input[i] << 1; output[i] |= overflow; overflow = (input[i] & 0x80) ? 1 : 0; } } /* Generate subkeys K1 and K2 as described in RFC 4493 figure 2.2. */ static krb5_error_code generate_subkey(const struct krb5_enc_provider *enc, krb5_key key, unsigned char *K1, unsigned char *K2) { unsigned char L[BLOCK_SIZE]; unsigned char tmp[BLOCK_SIZE]; krb5_data d; krb5_error_code ret; /* L := encrypt(K, const_Zero) */ memset(L, 0, sizeof(L)); d = make_data(L, BLOCK_SIZE); ret = encrypt_block(enc, key, &d); if (ret != 0) return ret; /* K1 := (MSB(L) == 0) ? L << 1 : (L << 1) XOR const_Rb */ if ((L[0] & 0x80) == 0) { leftshift_onebit(L, K1); } else { leftshift_onebit(L, tmp); xor_128(tmp, const_Rb, K1); } /* K2 := (MSB(K1) == 0) ? K1 << 1 : (K1 << 1) XOR const_Rb */ if ((K1[0] & 0x80) == 0) { leftshift_onebit(K1, K2); } else { leftshift_onebit(K1, tmp); xor_128(tmp, const_Rb, K2); } return 0; } /* Pad out lastb with a 1 bit followed by 0 bits, placing the result in pad. */ static void padding(unsigned char *lastb, unsigned char *pad, int length) { int j; /* original last block */ for (j = 0; j < BLOCK_SIZE; j++) { if (j < length) { pad[j] = lastb[j]; } else if (j == length) { pad[j] = 0x80; } else { pad[j] = 0x00; } } } /* * Implementation of CMAC algorithm. When used with AES, this function * is compatible with RFC 4493 figure 2.3. */ krb5_error_code krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { unsigned char Y[BLOCK_SIZE], M_last[BLOCK_SIZE], padded[BLOCK_SIZE]; unsigned char K1[BLOCK_SIZE], K2[BLOCK_SIZE]; unsigned char input[BLOCK_SIZE]; unsigned int n, i, flag; krb5_error_code ret; struct iov_cursor cursor; size_t length; krb5_crypto_iov iov[1]; krb5_data d; assert(enc->cbc_mac != NULL); if (enc->block_size != BLOCK_SIZE) return KRB5_BAD_MSIZE; length = iov_total_length(data, num_data, TRUE); /* Step 1. */ ret = generate_subkey(enc, key, K1, K2); if (ret != 0) return ret; /* Step 2. */ n = (length + BLOCK_SIZE - 1) / BLOCK_SIZE; /* Step 3. */ if (n == 0) { n = 1; flag = 0; } else { flag = ((length % BLOCK_SIZE) == 0); } iov[0].flags = KRB5_CRYPTO_TYPE_DATA; iov[0].data = make_data(input, BLOCK_SIZE); /* Step 5 (we'll do step 4 in a bit). */ memset(Y, 0, BLOCK_SIZE); d = make_data(Y, BLOCK_SIZE); /* Step 6 (all but last block). */ k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, TRUE); for (i = 0; i < n - 1; i++) { k5_iov_cursor_get(&cursor, input); ret = enc->cbc_mac(key, iov, 1, &d, &d); if (ret != 0) return ret; } /* Step 4. */ k5_iov_cursor_get(&cursor, input); if (flag) { /* last block is complete block */ xor_128(input, K1, M_last); } else { padding(input, padded, length % BLOCK_SIZE); xor_128(padded, K2, M_last); } /* Step 6 (last block). */ iov[0].data = make_data(M_last, BLOCK_SIZE); ret = enc->cbc_mac(key, iov, 1, &d, &d); if (ret != 0) return ret; assert(output->length >= d.length); output->length = d.length; memcpy(output->data, d.data, d.length); return 0; } #endif /* K5_BUILTIN_CMAC */ krb5-1.22.1/src/lib/crypto/builtin/sha1/0000775000175000017500000000000015051422640017520 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/sha1/t_shs.c0000664000175000017500000000745415051422640021016 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /**************************************************************************** * * * SHS Test Code * * * ****************************************************************************/ #include #include #include #include "shs.h" /* Test the SHS implementation */ #ifdef NEW_SHS static SHS_LONG shsTestResults[][ 5 ] = { { 0xA9993E36L, 0x4706816AL, 0xBA3E2571L, 0x7850C26CL, 0x9CD0D89DL, }, { 0x84983E44L, 0x1C3BD26EL, 0xBAAE4AA1L, 0xF95129E5L, 0xE54670F1L, }, { 0x34AA973CL, 0xD4C4DAA4L, 0xF61EEB2BL, 0xDBAD2731L, 0x6534016FL, } }; #else static SHS_LONG shsTestResults[][ 5 ] = { { 0x0164B8A9L, 0x14CD2A5EL, 0x74C4F7FFL, 0x082C4D97L, 0xF1EDF880L }, { 0xD2516EE1L, 0xACFA5BAFL, 0x33DFC1C4L, 0x71E43844L, 0x9EF134C8L }, { 0x3232AFFAL, 0x48628A26L, 0x653B5AAAL, 0x44541FD9L, 0x0D690603L } }; #endif /* NEW_SHS */ static int compareSHSresults(SHS_INFO *shsInfo, int shsTestLevel) { int i, fail = 0; /* Compare the returned digest and required values */ for( i = 0; i < 5; i++ ) if( shsInfo->digest[ i ] != shsTestResults[ shsTestLevel ][ i ] ) fail = 1; if (fail) { printf("\nExpected: "); for (i = 0; i < 5; i++) { printf("%8.8lx ", (unsigned long) shsTestResults[shsTestLevel][i]); } printf("\nGot: "); for (i = 0; i < 5; i++) { printf("%8.8lx ", (unsigned long) shsInfo->digest[i]); } printf("\n"); return( -1 ); } return( 0 ); } int main(int argc, char *argv[]) { SHS_INFO shsInfo; unsigned int i; /* Make sure we've got the endianness set right. If the machine is big-endian (up to 64 bits) the following value will be signed, otherwise it will be unsigned. Unfortunately we can't test for odd things like middle-endianness without knowing the size of the data types */ /* Test SHS against values given in SHS standards document */ printf( "Running SHS test 1 ... " ); shsInit( &shsInfo ); shsUpdate( &shsInfo, ( SHS_BYTE * ) "abc", 3 ); shsFinal( &shsInfo ); if( compareSHSresults( &shsInfo, 0 ) == -1 ) { putchar( '\n' ); puts( "SHS test 1 failed" ); exit( -1 ); } #ifdef NEW_SHS puts( "passed, result= A9993E364706816ABA3E25717850C26C9CD0D89D" ); #else puts( "passed, result= 0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880" ); #endif /* NEW_SHS */ printf( "Running SHS test 2 ... " ); shsInit( &shsInfo ); shsUpdate( &shsInfo, ( SHS_BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 ); shsFinal( &shsInfo ); if( compareSHSresults( &shsInfo, 1 ) == -1 ) { putchar( '\n' ); puts( "SHS test 2 failed" ); exit( -1 ); } #ifdef NEW_SHS puts( "passed, result= 84983E441C3BD26EBAAE4AA1F95129E5E54670F1" ); #else puts( "passed, result= D2516EE1ACFA5BAF33DFC1C471E438449EF134C8" ); #endif /* NEW_SHS */ printf( "Running SHS test 3 ... " ); shsInit( &shsInfo ); for( i = 0; i < 15625; i++ ) shsUpdate( &shsInfo, ( SHS_BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 ); shsFinal( &shsInfo ); if( compareSHSresults( &shsInfo, 2 ) == -1 ) { putchar( '\n' ); puts( "SHS test 3 failed" ); exit( -1 ); } #ifdef NEW_SHS puts( "passed, result= 34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" ); #else puts( "passed, result= 3232AFFA48628A26653B5AAA44541FD90D690603" ); #endif /* NEW_SHS */ puts( "\nAll SHS tests passed" ); exit( 0 ); } krb5-1.22.1/src/lib/crypto/builtin/sha1/Makefile.in0000664000175000017500000000177615051422640021600 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)builtin$(S)sha1 BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES=-I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLAGS) ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = builtin\sha1 ##DOS##OBJFILE = ..\..\$(OUTPRE)sha1.lst STLIBOBJS= shs.o OBJS= $(OUTPRE)shs.$(OBJEXT) SRCS= $(srcdir)/shs.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs includes: depend depend: $(SRCS) t_shs: t_shs.o shs.o $(SUPPORT_DEPLIB) $(CC_LINK) -o t_shs t_shs.o shs.o $(SUPPORT_LIB) $(OUTPRE)t_shs.exe: $(OUTPRE)t_shs.obj $(OUTPRE)shs.obj link -out:$@ $** t_shs3: t_shs3.o shs.o $(SUPPORT_DEPLIB) $(CC_LINK) -o t_shs3 t_shs3.o shs.o $(SUPPORT_LIB) check-unix: check-unix-@CRYPTO_BUILTIN_TESTS@ check-unix-no: check-unix-yes: t_shs t_shs3 $(RUN_TEST) $(C)t_shs -x $(RUN_TEST) $(C)t_shs3 check-windows: $(OUTPRE)t_shs.exe $(OUTPRE)t_shs3.exe $(OUTPRE)$(C)t_shs.exe -x $(OUTPRE)$(C)t_shs3.exe clean: $(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT) t_shs3$(EXEEXT) t_shs3.$(OBJEXT) clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/sha1/shs.c0000664000175000017500000003334515051422640020471 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "shs.h" #ifdef HAVE_SYS_TYPES_H #include #endif #include #ifdef K5_BUILTIN_SHA1 /* The SHS f()-functions. The f1 and f3 functions can be optimized to save one boolean operation each - thanks to Rich Schroeppel, rcs@cs.arizona.edu for discovering this */ #define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */ #define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */ #define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */ #define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */ /* The SHS Mysterious Constants */ #define K1 0x5A827999L /* Rounds 0-19 */ #define K2 0x6ED9EBA1L /* Rounds 20-39 */ #define K3 0x8F1BBCDCL /* Rounds 40-59 */ #define K4 0xCA62C1D6L /* Rounds 60-79 */ /* SHS initial values */ #define h0init 0x67452301L #define h1init 0xEFCDAB89L #define h2init 0x98BADCFEL #define h3init 0x10325476L #define h4init 0xC3D2E1F0L /* Note that it may be necessary to add parentheses to these macros if they are to be called with expressions as arguments */ /* 32-bit rotate left - kludged with shifts */ #define ROTL(n,X) ((((X) << (n)) & 0xffffffff) | ((X) >> (32 - n))) /* The initial expanding function. The hash function is defined over an 80-word expanded input array W, where the first 16 are copies of the input data, and the remaining 64 are defined by W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ] This implementation generates these values on the fly in a circular buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this optimization. The updated SHS changes the expanding function by adding a rotate of 1 bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor for this information */ #ifdef NEW_SHS #define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \ W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ))) #else #define expand(W,i) ( W[ i & 15 ] ^= W[ (i - 14) & 15 ] ^ \ W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) #endif /* NEW_SHS */ /* The prototype SHS sub-round. The fundamental sub-round is: a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data; b' = a; c' = ROTL( 30, b ); d' = c; e' = d; but this is implemented by unrolling the loop 5 times and renaming the variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration. This code is then replicated 20 times for each of the 4 functions, using the next 20 values from the W[] array each time */ #define subRound(a, b, c, d, e, f, k, data) \ ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, \ e &= 0xffffffff, b = ROTL( 30, b ) ) /* Initialize the SHS values */ void shsInit(SHS_INFO *shsInfo) { /* Set the h-vars to their initial values */ shsInfo->digest[ 0 ] = h0init; shsInfo->digest[ 1 ] = h1init; shsInfo->digest[ 2 ] = h2init; shsInfo->digest[ 3 ] = h3init; shsInfo->digest[ 4 ] = h4init; /* Initialise bit count */ shsInfo->countLo = shsInfo->countHi = 0; } /* Perform the SHS transformation. Note that this code, like MD5, seems to break some optimizing compilers due to the complexity of the expressions and the size of the basic block. It may be necessary to split it into sections, e.g. based on the four subrounds Note that this corrupts the shsInfo->data area */ static void SHSTransform (SHS_LONG *digest, const SHS_LONG *data); static void SHSTransform(SHS_LONG *digest, const SHS_LONG *data) { SHS_LONG A, B, C, D, E; /* Local vars */ SHS_LONG eData[ 16 ]; /* Expanded data */ /* Set up first buffer and local data buffer */ A = digest[ 0 ]; B = digest[ 1 ]; C = digest[ 2 ]; D = digest[ 3 ]; E = digest[ 4 ]; memcpy(eData, data, sizeof (eData)); #if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO) { int i; SHS_LONG temp; for (i = 0; i < 20; i++) { SHS_LONG x = (i < 16) ? eData[i] : expand(eData, i); subRound(A, B, C, D, E, f1, K1, x); temp = E, E = D, D = C, C = B, B = A, A = temp; } for (i = 20; i < 40; i++) { subRound(A, B, C, D, E, f2, K2, expand(eData, i)); temp = E, E = D, D = C, C = B, B = A, A = temp; } for (i = 40; i < 60; i++) { subRound(A, B, C, D, E, f3, K3, expand(eData, i)); temp = E, E = D, D = C, C = B, B = A, A = temp; } for (i = 60; i < 80; i++) { subRound(A, B, C, D, E, f4, K4, expand(eData, i)); temp = E, E = D, D = C, C = B, B = A, A = temp; } } #else /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */ subRound( A, B, C, D, E, f1, K1, eData[ 0 ] ); subRound( E, A, B, C, D, f1, K1, eData[ 1 ] ); subRound( D, E, A, B, C, f1, K1, eData[ 2 ] ); subRound( C, D, E, A, B, f1, K1, eData[ 3 ] ); subRound( B, C, D, E, A, f1, K1, eData[ 4 ] ); subRound( A, B, C, D, E, f1, K1, eData[ 5 ] ); subRound( E, A, B, C, D, f1, K1, eData[ 6 ] ); subRound( D, E, A, B, C, f1, K1, eData[ 7 ] ); subRound( C, D, E, A, B, f1, K1, eData[ 8 ] ); subRound( B, C, D, E, A, f1, K1, eData[ 9 ] ); subRound( A, B, C, D, E, f1, K1, eData[ 10 ] ); subRound( E, A, B, C, D, f1, K1, eData[ 11 ] ); subRound( D, E, A, B, C, f1, K1, eData[ 12 ] ); subRound( C, D, E, A, B, f1, K1, eData[ 13 ] ); subRound( B, C, D, E, A, f1, K1, eData[ 14 ] ); subRound( A, B, C, D, E, f1, K1, eData[ 15 ] ); subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) ); subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) ); subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) ); subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) ); subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) ); subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) ); subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) ); subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) ); subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) ); subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) ); subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) ); subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) ); subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) ); subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) ); subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) ); subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) ); subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) ); subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) ); subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) ); subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) ); subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) ); subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) ); subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) ); subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) ); subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) ); subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) ); subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) ); subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) ); subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) ); subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) ); subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) ); subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) ); subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) ); subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) ); subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) ); subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) ); subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) ); subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) ); subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) ); subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) ); subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) ); subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) ); subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) ); subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) ); subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) ); subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) ); subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) ); subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) ); subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) ); subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) ); subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) ); subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) ); subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) ); subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) ); subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) ); subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) ); subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) ); subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) ); subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) ); subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) ); subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) ); subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) ); subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) ); subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) ); #endif /* Build message digest */ digest[ 0 ] += A; digest[ 0 ] &= 0xffffffff; digest[ 1 ] += B; digest[ 1 ] &= 0xffffffff; digest[ 2 ] += C; digest[ 2 ] &= 0xffffffff; digest[ 3 ] += D; digest[ 3 ] &= 0xffffffff; digest[ 4 ] += E; digest[ 4 ] &= 0xffffffff; } /* Update SHS for a block of data */ void shsUpdate(SHS_INFO *shsInfo, const SHS_BYTE *buffer, unsigned int count) { SHS_LONG tmp; unsigned int dataCount; int canfill; SHS_LONG *lp; /* Update bitcount */ tmp = shsInfo->countLo; shsInfo->countLo = tmp + (((SHS_LONG) count) << 3 ); if ((shsInfo->countLo &= 0xffffffff) < tmp) shsInfo->countHi++; /* Carry from low to high */ shsInfo->countHi += count >> 29; /* Get count of bytes already in data */ dataCount = (tmp >> 3) & 0x3F; /* Handle any leading odd-sized chunks */ if (dataCount) { lp = shsInfo->data + dataCount / 4; dataCount = SHS_DATASIZE - dataCount; canfill = (count >= dataCount); if (dataCount % 4) { /* Fill out a full 32 bit word first if needed -- this is not very efficient (computed shift amount), but it shouldn't happen often. */ while (dataCount % 4 && count > 0) { *lp |= (SHS_LONG) *buffer++ << ((--dataCount % 4) * 8); count--; } lp++; } while (lp < shsInfo->data + 16) { if (count < 4) { *lp = 0; switch (count % 4) { case 3: *lp |= (SHS_LONG) buffer[2] << 8; case 2: *lp |= (SHS_LONG) buffer[1] << 16; case 1: *lp |= (SHS_LONG) buffer[0] << 24; } count = 0; break; /* out of while loop */ } *lp++ = load_32_be(buffer); buffer += 4; count -= 4; } if (canfill) { SHSTransform(shsInfo->digest, shsInfo->data); } } /* Process data in SHS_DATASIZE chunks */ while (count >= SHS_DATASIZE) { lp = shsInfo->data; while (lp < shsInfo->data + 16) { *lp++ = load_32_be(buffer); buffer += 4; } SHSTransform(shsInfo->digest, shsInfo->data); count -= SHS_DATASIZE; } if (count > 0) { lp = shsInfo->data; while (count > 4) { *lp++ = load_32_be(buffer); buffer += 4; count -= 4; } *lp = 0; switch (count % 4) { case 0: *lp |= ((SHS_LONG) buffer[3]); case 3: *lp |= ((SHS_LONG) buffer[2]) << 8; case 2: *lp |= ((SHS_LONG) buffer[1]) << 16; case 1: *lp |= ((SHS_LONG) buffer[0]) << 24; } } } /* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern 1 0* (64-bit count of bits processed, MSB-first) */ void shsFinal(SHS_INFO *shsInfo) { int count; SHS_LONG *lp; /* Compute number of bytes mod 64 */ count = (int) shsInfo->countLo; count = (count >> 3) & 0x3F; /* Set the first char of padding to 0x80. This is safe since there is always at least one byte free */ lp = shsInfo->data + count / 4; switch (count % 4) { case 3: *lp++ |= (SHS_LONG) 0x80; break; case 2: *lp++ |= (SHS_LONG) 0x80 << 8; break; case 1: *lp++ |= (SHS_LONG) 0x80 << 16; break; case 0: *lp++ = (SHS_LONG) 0x80 << 24; } /* at this point, lp can point *past* shsInfo->data. If it points there, just Transform and reset. If it points to the last element, set that to zero. This pads out to 64 bytes if not enough room for length words */ if (lp == shsInfo->data + 15) *lp++ = 0; if (lp == shsInfo->data + 16) { SHSTransform(shsInfo->digest, shsInfo->data); lp = shsInfo->data; } /* Pad out to 56 bytes */ while (lp < shsInfo->data + 14) *lp++ = 0; /* Append length in bits and transform */ *lp++ = shsInfo->countHi; *lp++ = shsInfo->countLo; SHSTransform(shsInfo->digest, shsInfo->data); } #endif /* K5_BUILTIN_SHA1 */ krb5-1.22.1/src/lib/crypto/builtin/sha1/t_shs3.c0000664000175000017500000004631315051422640021076 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* test shs code */ #include #include #include #include "shs.h" static void process(void); static void test1(void); static void test2(void); static void test3(void); static void test4(void); static void test5(void); static void test6(void); static void test7(void); /* When run on a little-endian CPU we need to perform byte reversal on an array of longwords. It is possible to make the code endianness- independent by fiddling around with data at the byte level, but this makes for very slow code, so we rely on the user to sort out endianness at compile time */ static void longReverse( SHS_LONG *buffer, int byteCount ) { SHS_LONG value; static int init = 0; char *cp; switch (init) { case 0: init=1; cp = (char *) &init; if (*cp == 1) { init=2; break; } init=1; /* fall through - MSB */ case 1: return; } byteCount /= sizeof( SHS_LONG ); while( byteCount-- ) { value = *buffer; value = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 ); *buffer++ = ( value << 16 ) | ( value >> 16 ); } } int rc; int mode; int Dflag; int main(int argc, char **argv) { char *argp; while (--argc > 0) if (*(argp = *++argv)=='-') while (*++argp) switch(*argp) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': if (mode) goto Usage; mode = *argp; break; case 'D': if (argc <= 1) goto Usage; --argc; Dflag = atoi(*++argv); break; case '-': break; default: fprintf (stderr,"Bad switch char <%c>\n", *argp); Usage: fprintf(stderr, "Usage: t_shs [-1234567] [-D #]\n"); exit(1); } else goto Usage; process(); exit(rc); } static void process(void) { switch(mode) { case '1': test1(); break; case '2': test2(); break; case '3': test3(); break; case '4': test4(); break; case '5': test5(); break; case '6': test6(); break; case '7': test7(); break; default: test1(); test2(); test3(); test4(); test5(); test6(); test7(); } } #ifndef shsDigest static unsigned char * shsDigest(SHS_INFO *si) { longReverse(si->digest, SHS_DIGESTSIZE); return (unsigned char*) si->digest; } #endif unsigned char results1[SHS_DIGESTSIZE] = { 0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e, 0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d}; static void test1(void) { SHS_INFO si[1]; unsigned char digest[SHS_DIGESTSIZE]; int failed; int i; printf("Running SHS test 1 ...\n"); shsInit(si); shsUpdate(si, (SHS_BYTE *) "abc", 3); shsFinal(si); memcpy(digest, shsDigest(si), SHS_DIGESTSIZE); if ((failed = memcmp(digest, results1, SHS_DIGESTSIZE)) != 0) { fprintf(stderr,"SHS test 1 failed!\n"); rc = 1; } printf ("%s, results = ", failed ? "Failed" : "Passed"); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",digest[i]); if (failed) { printf ("\n, expected "); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",results1[i]); } printf("\n"); } unsigned char results2[SHS_DIGESTSIZE] = { 0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae, 0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1}; static void test2(void) { SHS_INFO si[1]; unsigned char digest[SHS_DIGESTSIZE]; int failed; int i; printf("Running SHS test 2 ...\n"); shsInit(si); shsUpdate(si, (SHS_BYTE *) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56); shsFinal(si); memcpy(digest, shsDigest(si), SHS_DIGESTSIZE); if ((failed = memcmp(digest, results2, SHS_DIGESTSIZE)) != 0) { fprintf(stderr,"SHS test 2 failed!\n"); rc = 1; } printf ("%s, results = ", failed ? "Failed" : "Passed"); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",digest[i]); if (failed) { printf ("\n, expected "); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",results2[i]); } printf("\n"); } unsigned char results3[SHS_DIGESTSIZE] = { 0x34,0xaa,0x97,0x3c,0xd4,0xc4,0xda,0xa4,0xf6,0x1e, 0xeb,0x2b,0xdb,0xad,0x27,0x31,0x65,0x34,0x01,0x6f}; static void test3(void) { SHS_INFO si[1]; unsigned char digest[SHS_DIGESTSIZE]; int failed; int i; printf("Running SHS test 3 ...\n"); shsInit(si); for (i = 0; i < 15625; ++i) shsUpdate(si, (SHS_BYTE *) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64); shsFinal(si); memcpy(digest, shsDigest(si), SHS_DIGESTSIZE); if ((failed = memcmp(digest, results3, SHS_DIGESTSIZE)) != 0) { fprintf(stderr,"SHS test 3 failed!\n"); rc = 1; } printf ("%s, results = ", failed ? "Failed" : "Passed"); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",digest[i]); if (failed) { printf ("\n, expected "); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",results3[i]); } printf("\n"); } unsigned char randdata[] = { 0xfe,0x28,0x79,0x25,0xf5,0x03,0xf9,0x1c,0xcd,0x70,0x7b,0xb0,0x42,0x02,0xb8,0x2f, 0xf3,0x63,0xa2,0x79,0x8e,0x9b,0x33,0xd7,0x2b,0xc4,0xb4,0xd2,0xcb,0x61,0xec,0xbb, 0x94,0xe1,0x8f,0x53,0x80,0x55,0xd9,0x90,0xb2,0x03,0x58,0xfa,0xa6,0xe5,0x18,0x57, 0x68,0x04,0x24,0x98,0x41,0x7e,0x84,0xeb,0xc1,0x39,0xbc,0x1d,0xf7,0x4e,0x92,0x72, 0x1a,0x5b,0xb6,0x99,0x43,0xa5,0x0a,0x45,0x73,0x55,0xfd,0x57,0x83,0x45,0x36,0x5c, 0xfd,0x39,0x08,0x6e,0xe2,0x01,0x9a,0x8c,0x4e,0x39,0xd2,0x0d,0x5f,0x0e,0x35,0x15, 0xb9,0xac,0x5f,0xa1,0x8a,0xe6,0xdd,0x6e,0x68,0x9d,0xf6,0x29,0x95,0xf6,0x7d,0x7b, 0xd9,0x5e,0xf4,0x67,0x25,0xbd,0xee,0xed,0x53,0x60,0xb0,0x47,0xdf,0xef,0xf4,0x41, 0xbd,0x45,0xcf,0x5c,0x93,0x41,0x87,0x97,0x82,0x39,0x20,0x66,0xb4,0xda,0xcb,0x66, 0x93,0x02,0x2e,0x7f,0x94,0x4c,0xc7,0x3b,0x2c,0xcf,0xf6,0x99,0x6f,0x13,0xf1,0xc5, 0x28,0x2b,0xa6,0x6c,0x39,0x26,0x7f,0x76,0x24,0x4a,0x6e,0x01,0x40,0x63,0xf8,0x00, 0x06,0x23,0x5a,0xaa,0xa6,0x2f,0xd1,0x37,0xc7,0xcc,0x76,0xe9,0x54,0x1e,0x57,0x73, 0xf5,0x33,0xaa,0x96,0xbe,0x35,0xcd,0x1d,0xd5,0x7d,0xac,0x50,0xd5,0xf8,0x47,0x2d, 0xd6,0x93,0x5f,0x6e,0x38,0xd3,0xac,0xd0,0x7e,0xad,0x9e,0xf8,0x87,0x95,0x63,0x15, 0x65,0xa3,0xd4,0xb3,0x9a,0x6c,0xac,0xcd,0x2a,0x54,0x83,0x13,0xc4,0xb4,0x94,0xfa, 0x76,0x87,0xc5,0x8b,0x4a,0x10,0x92,0x05,0xd1,0x0e,0x97,0xfd,0xc8,0xfb,0xc5,0xdc, 0x21,0x4c,0xc8,0x77,0x5c,0xed,0x32,0x22,0x77,0xc1,0x38,0x30,0xd7,0x8e,0x2a,0x70, 0x72,0x67,0x13,0xe4,0xb7,0x18,0xd4,0x76,0xdd,0x32,0x12,0xf4,0x5d,0xc9,0xec,0xc1, 0x2c,0x8a,0xfe,0x08,0x6c,0xea,0xf6,0xab,0x5a,0x0e,0x8e,0x81,0x1d,0xc8,0x5a,0x4b, 0xed,0xb9,0x7f,0x4b,0x67,0xe3,0x65,0x46,0xc9,0xf2,0xab,0x37,0x0a,0x98,0x67,0x5b, 0xb1,0x3b,0x02,0x91,0x38,0x71,0xea,0x62,0x88,0xae,0xb6,0xdb,0xfc,0x55,0x79,0x33, 0x69,0x95,0x51,0xb6,0xe1,0x3b,0xab,0x22,0x68,0x54,0xf9,0x89,0x9c,0x94,0xe0,0xe3, 0xd3,0x48,0x5c,0xe9,0x78,0x5b,0xb3,0x4b,0xba,0xd8,0x48,0xd8,0xaf,0x91,0x4e,0x23, 0x38,0x23,0x23,0x6c,0xdf,0x2e,0xf0,0xff,0xac,0x1d,0x2d,0x27,0x10,0x45,0xa3,0x2d, 0x8b,0x00,0xcd,0xe2,0xfc,0xb7,0xdb,0x52,0x13,0xb7,0x66,0x79,0xd9,0xd8,0x29,0x0e, 0x32,0xbd,0x52,0x6b,0x75,0x71,0x08,0x83,0x1b,0x67,0x28,0x93,0x97,0x97,0x32,0xff, 0x8b,0xd3,0x98,0xa3,0xce,0x2b,0x88,0x37,0x1c,0xcc,0xa0,0xd1,0x19,0x9b,0xe6,0x11, 0xfc,0xc0,0x3c,0x4e,0xe1,0x35,0x49,0x29,0x19,0xcf,0x1d,0xe1,0x60,0x74,0xc0,0xe9, 0xf7,0xb4,0x99,0xa0,0x23,0x50,0x51,0x78,0xcf,0xc0,0xe5,0xc2,0x1c,0x16,0xd2,0x24, 0x5a,0x63,0x54,0x83,0xaa,0x74,0x3d,0x41,0x0d,0x52,0xee,0xfe,0x0f,0x4d,0x13,0xe1, 0x27,0x00,0xc4,0xf3,0x2b,0x55,0xe0,0x9c,0x81,0xe0,0xfc,0xc2,0x13,0xd4,0x39,0x09 }; unsigned char results4[SHS_DIGESTSIZE] = { 0x13,0x62,0xfc,0x87,0x68,0x33,0xd5,0x1d,0x2f,0x0c, 0x73,0xe3,0xfb,0x87,0x6a,0x6b,0xc3,0x25,0x54,0xfc}; static void test4(void) { SHS_INFO si[1]; unsigned char digest[SHS_DIGESTSIZE]; int failed; int i; printf("Running SHS test 4 ...\n"); shsInit(si); shsUpdate(si, randdata, 19); shsFinal(si); memcpy(digest, shsDigest(si), SHS_DIGESTSIZE); if ((failed = memcmp(digest, results4, SHS_DIGESTSIZE)) != 0) { fprintf(stderr,"SHS test 4 failed!\n"); rc = 1; } printf ("%s, results = ", failed ? "Failed" : "Passed"); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",digest[i]); if (failed) { printf ("\n, expected "); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",results4[i]); } printf("\n"); } unsigned char results5[SHS_DIGESTSIZE] = { 0x19,0x4d,0xf6,0xeb,0x8e,0x02,0x6d,0x37,0x58,0x64, 0xe5,0x95,0x19,0x2a,0xdd,0x1c,0xc4,0x3c,0x24,0x86}; static void test5(void) { SHS_INFO si[1]; unsigned char digest[SHS_DIGESTSIZE]; int failed; int i; printf("Running SHS test 5 ...\n"); shsInit(si); shsUpdate(si, randdata, 19); shsUpdate(si, randdata+32, 15); shsFinal(si); memcpy(digest, shsDigest(si), SHS_DIGESTSIZE); if ((failed = memcmp(digest, results5, SHS_DIGESTSIZE)) != 0) { fprintf(stderr,"SHS test 5 failed!\n"); rc = 1; } printf ("%s, results = ", failed ? "Failed" : "Passed"); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",digest[i]); if (failed) { printf ("\n, expected "); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",results5[i]); } printf("\n"); } unsigned char results6[SHS_DIGESTSIZE] = { 0x4e,0x16,0x57,0x9d,0x4b,0x48,0xa9,0x1c,0x88,0x72, 0x83,0xdb,0x88,0xd1,0xea,0x3a,0x45,0xdf,0xa1,0x10}; static void test6(void) { struct { unsigned long pad1; SHS_INFO si1; unsigned long pad2; SHS_INFO si2; unsigned long pad3; } sdata; unsigned char digest[SHS_DIGESTSIZE]; int failed; unsigned int i, j; printf("Running SHS test 6 ...\n"); sdata.pad1 = 0x12345678; sdata.pad2 = 0x87654321; sdata.pad3 = 0x78563412; shsInit((&sdata.si2)); if (sdata.pad2 != 0x87654321) { printf ("Overrun #20 %#lx\n", sdata.pad2); sdata.pad2 = 0x87654321; } if (sdata.pad3 != 0x78563412) { printf ("Overrun #21 %#lx\n", sdata.pad3); sdata.pad3 = 0x78563412; } for (i = 0; i < 400; ++i) { shsInit(&sdata.si1); if (sdata.pad1 != 0x12345678) { printf ("Overrun #22 %#lx at %d\n", sdata.pad1, i); sdata.pad1 = 0x12345678; } if (sdata.pad2 != 0x87654321) { printf ("Overrun #23 %#lx at %d\n", sdata.pad2, i); sdata.pad2 = 0x87654321; } shsUpdate(&sdata.si1, (randdata+sizeof(randdata))-i, i); if (sdata.pad1 != 0x12345678) { printf ("Overrun #24 %#lx at %d\n", sdata.pad1, i); sdata.pad1 = 0x12345678; } if (sdata.pad2 != 0x87654321) { printf ("Overrun #25 %#lx at %d\n", sdata.pad2, i); sdata.pad2 = 0x87654321; } shsFinal(&sdata.si1); if (sdata.pad1 != 0x12345678) { printf ("Overrun #26 %#lx at %d\n", sdata.pad1, i); sdata.pad1 = 0x12345678; } if (sdata.pad2 != 0x87654321) { printf ("Overrun #27 %#lx at %d\n", sdata.pad2, i); sdata.pad2 = 0x87654321; } memcpy(digest, shsDigest(&sdata.si1), SHS_DIGESTSIZE); if (Dflag & 1) { printf ("%d: ", i); for (j = 0; j < SHS_DIGESTSIZE; ++j) printf("%02x",digest[j]); printf("\n"); } shsUpdate((&sdata.si2), digest, SHS_DIGESTSIZE); if (sdata.pad2 != 0x87654321) { printf ("Overrun #28 %#lx at %d\n", sdata.pad2, i); sdata.pad2 = 0x87654321; } if (sdata.pad3 != 0x78563412) { printf ("Overrun #29 %#lx at %d\n", sdata.pad3, i); sdata.pad3 = 0x78563412; } if (Dflag & 2) printf ("%d: %08lx%08lx%08lx%08lx%08lx\n", i, (unsigned long) sdata.si2.digest[0], (unsigned long) sdata.si2.digest[1], (unsigned long) sdata.si2.digest[2], (unsigned long) sdata.si2.digest[3], (unsigned long) sdata.si2.digest[4]); } shsFinal((&sdata.si2)); if (sdata.pad2 != 0x87654321) { printf ("Overrun #30 %#lx\n", sdata.pad2); sdata.pad2 = 0x87654321; } if (sdata.pad3 != 0x78563412) { printf ("Overrun #31 %#lx\n", sdata.pad3); sdata.pad3 = 0x78563412; } memcpy(digest, shsDigest((&sdata.si2)), SHS_DIGESTSIZE); if ((failed = memcmp(digest, results6, SHS_DIGESTSIZE)) != 0) { fprintf(stderr,"SHS test 6 failed!\n"); rc = 1; } printf ("%s, results = ", failed ? "Failed" : "Passed"); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",digest[i]); if (failed) { printf ("\n, expected "); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",results6[i]); } printf("\n"); } unsigned char results7[SHS_DIGESTSIZE] = { 0x89,0x41,0x65,0xce,0x76,0xc1,0xd1,0xd1,0xc3,0x6f, 0xab,0x92,0x79,0x30,0x01,0x71,0x63,0x1f,0x74,0xfe}; unsigned int jfsize[] = {0,1,31,32, 33,55,56,63, 64,65,71,72, 73,95,96,97, 119,120,123,127}; unsigned int kfsize[] = {0,1,31,32,33,55,56,63}; static void test7(void) { struct { unsigned long pad1; SHS_INFO si1; unsigned long pad2; SHS_INFO si2; unsigned long pad3; } sdata; unsigned char digest[SHS_DIGESTSIZE]; int failed; unsigned int i, j, k, l; printf("Running SHS test 7 ...\n"); sdata.pad1 = 0x12345678; sdata.pad2 = 0x87654321; sdata.pad3 = 0x78563412; shsInit((&sdata.si2)); for (i = 1; i <= 128; ++i) for (j = 0; j < 20; ++j) for (k = 0; k < 8; ++k) { shsInit(&sdata.si1); shsUpdate(&sdata.si1, (randdata+80+j), i); if (sdata.pad1 != 0x12345678) { printf ("Overrun #1 %#lx at %d,%d,%d\n", sdata.pad1, i,j,k); sdata.pad1 = 0x12345678; } if (sdata.pad2 != 0x87654321) { printf ("Overrun #2 %#lx at %d,%d,%d\n", sdata.pad2, i,j,k); sdata.pad2 = 0x87654321; } shsUpdate(&sdata.si1, randdata+i, jfsize[j]); if (sdata.pad1 != 0x12345678) { printf ("Overrun #3 %#lx at %d,%d,%d\n", sdata.pad1, i,j,k); sdata.pad1 = 0x12345678; } if (sdata.pad2 != 0x87654321) { printf ("Overrun #4 %#lx at %d,%d,%d\n", sdata.pad2, i,j,k); sdata.pad2 = 0x87654321; } if (k) shsUpdate(&sdata.si1, randdata+(i^j), kfsize[k]); if (sdata.pad1 != 0x12345678) { printf ("Overrun #5 %#lx at %d,%d,%d\n", sdata.pad1, i,j,k); sdata.pad1 = 0x12345678; } if (sdata.pad2 != 0x87654321) { printf ("Overrun #6 %#lx at %d,%d,%d\n", sdata.pad2, i,j,k); sdata.pad2 = 0x87654321; } shsFinal(&sdata.si1); if (sdata.pad1 != 0x12345678) { printf ("Overrun #7 %#lx at %d,%d,%d\n", sdata.pad1, i,j,k); sdata.pad1 = 0x12345678; } if (sdata.pad2 != 0x87654321) { printf ("Overrun #8 %#lx at %d,%d,%d\n", sdata.pad2, i,j,k); sdata.pad2 = 0x87654321; } memcpy(digest, shsDigest(&sdata.si1), SHS_DIGESTSIZE); if (Dflag & 1) { printf ("%d,%d,%d: ", i, j, k); for (l = 0; l < SHS_DIGESTSIZE; ++l) printf("%02x",digest[l]); printf("\n"); } shsUpdate((&sdata.si2), digest, SHS_DIGESTSIZE); if (sdata.pad2 != 0x87654321) { printf ("Overrun #9 %#lx at %d,%d,%d\n", sdata.pad2, i,j,k); sdata.pad2 = 0x87654321; } if (sdata.pad3 != 0x78563412) { printf ("Overrun #10 %#lx at %d,%d,%d\n", sdata.pad3, i,j,k); sdata.pad3 = 0x78563412; } if (Dflag & 2) printf ("%d,%d,%d: %08lx%08lx%08lx%08lx%08lx\n", i,j,k, (unsigned long) sdata.si2.digest[0], (unsigned long) sdata.si2.digest[1], (unsigned long) sdata.si2.digest[2], (unsigned long) sdata.si2.digest[3], (unsigned long) sdata.si2.digest[4]); } shsFinal((&sdata.si2)); memcpy(digest, shsDigest((&sdata.si2)), SHS_DIGESTSIZE); if ((failed = memcmp(digest, results7, SHS_DIGESTSIZE)) != 0) { fprintf(stderr,"SHS test 7 failed!\n"); rc = 1; } printf ("%s, results = ", failed ? "Failed" : "Passed"); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",digest[i]); if (failed) { printf ("\n, expected "); for (i = 0; i < SHS_DIGESTSIZE; ++i) printf("%02x",results7[i]); } printf("\n"); } krb5-1.22.1/src/lib/crypto/builtin/sha1/deps0000664000175000017500000000143515051422640020401 0ustar ghudsonghudson# # Generated makefile dependencies follow. # shs.so shs.po $(OUTPRE)shs.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ shs.c shs.h krb5-1.22.1/src/lib/crypto/builtin/sha1/shs.h0000664000175000017500000000236715051422640020476 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #ifndef _SHS_DEFINED #include "crypto_int.h" #define _SHS_DEFINED /* Some useful types */ typedef krb5_octet SHS_BYTE; typedef krb5_ui_4 SHS_LONG; /* Define the following to use the updated SHS implementation */ #define NEW_SHS /**/ /* The SHS block size and message digest sizes, in bytes */ #define SHS_DATASIZE 64 #define SHS_DIGESTSIZE 20 /* The structure for storing SHS info */ typedef struct { SHS_LONG digest[ 5 ]; /* Message digest */ SHS_LONG countLo, countHi; /* 64-bit bit count */ SHS_LONG data[ 16 ]; /* SHS data buffer */ } SHS_INFO; /* Message digest functions (shs.c) */ void shsInit(SHS_INFO *shsInfo); void shsUpdate(SHS_INFO *shsInfo, const SHS_BYTE *buffer, unsigned int count); void shsFinal(SHS_INFO *shsInfo); /* Keyed Message digest functions (hmac_sha.c) */ krb5_error_code hmac_sha(krb5_octet *text, int text_len, krb5_octet *key, int key_len, krb5_octet *digest); #define NIST_SHA_CKSUM_LENGTH SHS_DIGESTSIZE #define HMAC_SHA_CKSUM_LENGTH SHS_DIGESTSIZE #endif /* _SHS_DEFINED */ krb5-1.22.1/src/lib/crypto/builtin/kdf.c0000664000175000017500000001422015051422640017573 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" #ifdef K5_BUILTIN_KDF krb5_error_code k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash, krb5_key key, const krb5_data *label, const krb5_data *context, krb5_data *rnd_out) { krb5_crypto_iov iov[5]; krb5_error_code ret; krb5_data prf; unsigned char ibuf[4], lbuf[4]; if (hash == NULL || rnd_out->length > hash->hashsize) return KRB5_CRYPTO_INTERNAL; /* Allocate encryption data buffer. */ ret = alloc_data(&prf, hash->hashsize); if (ret) return ret; /* [i]2: four-byte big-endian binary string giving the block counter (1) */ iov[0].flags = KRB5_CRYPTO_TYPE_DATA; iov[0].data = make_data(ibuf, sizeof(ibuf)); store_32_be(1, ibuf); /* Label */ iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data = *label; /* 0x00: separator byte */ iov[2].flags = KRB5_CRYPTO_TYPE_DATA; iov[2].data = make_data("", 1); /* Context */ iov[3].flags = KRB5_CRYPTO_TYPE_DATA; iov[3].data = *context; /* [L]2: four-byte big-endian binary string giving the output length */ iov[4].flags = KRB5_CRYPTO_TYPE_DATA; iov[4].data = make_data(lbuf, sizeof(lbuf)); store_32_be(rnd_out->length * 8, lbuf); ret = krb5int_hmac(hash, key, iov, 5, &prf); if (!ret) memcpy(rnd_out->data, prf.data, rnd_out->length); zapfree(prf.data, prf.length); return ret; } krb5_error_code k5_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc, krb5_key key, const krb5_data *label, krb5_data *rnd_out) { size_t blocksize, keybytes, n; krb5_crypto_iov iov[6]; krb5_error_code ret; krb5_data prf; unsigned int i; unsigned char ibuf[4], Lbuf[4]; blocksize = enc->block_size; keybytes = enc->keybytes; if (key->keyblock.length != enc->keylength || rnd_out->length != keybytes) return KRB5_CRYPTO_INTERNAL; /* Allocate encryption data buffer. */ ret = alloc_data(&prf, blocksize); if (ret) return ret; /* K(i-1): the previous block of PRF output, initially all-zeros. */ iov[0].flags = KRB5_CRYPTO_TYPE_DATA; iov[0].data = prf; /* [i]2: four-byte big-endian binary string giving the block counter */ iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data = make_data(ibuf, sizeof(ibuf)); /* Label: the fixed derived-key input */ iov[2].flags = KRB5_CRYPTO_TYPE_DATA; iov[2].data = *label; /* 0x00: separator byte */ iov[3].flags = KRB5_CRYPTO_TYPE_DATA; iov[3].data = make_data("", 1); /* Context: (unused) */ iov[4].flags = KRB5_CRYPTO_TYPE_DATA; iov[4].data = empty_data(); /* [L]2: four-byte big-endian binary string giving the output length */ iov[5].flags = KRB5_CRYPTO_TYPE_DATA; iov[5].data = make_data(Lbuf, sizeof(Lbuf)); store_32_be(rnd_out->length * 8, Lbuf); for (i = 1, n = 0; n < keybytes; i++) { /* Update the block counter. */ store_32_be(i, ibuf); /* Compute a CMAC checksum, storing the result into K(i-1). */ ret = krb5int_cmac_checksum(enc, key, iov, 6, &prf); if (ret) goto cleanup; /* Copy the result into the appropriate part of the output buffer. */ if (keybytes - n <= blocksize) { memcpy(rnd_out->data + n, prf.data, keybytes - n); break; } memcpy(rnd_out->data + n, prf.data, blocksize); n += blocksize; } cleanup: zapfree(prf.data, blocksize); return ret; } krb5_error_code k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key key, const krb5_data *constant, krb5_data *rnd_out) { size_t blocksize, keybytes, n; krb5_error_code ret; krb5_data block = empty_data(); blocksize = enc->block_size; keybytes = enc->keybytes; if (blocksize == 1) return KRB5_BAD_ENCTYPE; if (key->keyblock.length != enc->keylength || rnd_out->length != keybytes) return KRB5_CRYPTO_INTERNAL; /* Allocate encryption data buffer. */ ret = alloc_data(&block, blocksize); if (ret) return ret; /* Initialize the input block. */ if (constant->length == blocksize) { memcpy(block.data, constant->data, blocksize); } else { krb5int_nfold(constant->length * 8, (uint8_t *)constant->data, blocksize * 8, (uint8_t *)block.data); } /* Loop encrypting the blocks until enough key bytes are generated. */ n = 0; while (n < keybytes) { ret = encrypt_block(enc, key, &block); if (ret) goto cleanup; if ((keybytes - n) <= blocksize) { memcpy(rnd_out->data + n, block.data, (keybytes - n)); break; } memcpy(rnd_out->data + n, block.data, blocksize); n += blocksize; } cleanup: zapfree(block.data, blocksize); return ret; } #endif /* K5_BUILTIN_KDF */ krb5-1.22.1/src/lib/crypto/builtin/deps0000664000175000017500000000573215051422640017551 0ustar ghudsonghudson# # Generated makefile dependencies follow. # cmac.so cmac.po $(OUTPRE)cmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cmac.c hmac.so hmac.po $(OUTPRE)hmac.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hmac.c kdf.so kdf.po $(OUTPRE)kdf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ kdf.c pbkdf2.so pbkdf2.po $(OUTPRE)pbkdf2.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ pbkdf2.c krb5-1.22.1/src/lib/crypto/builtin/camellia/0000775000175000017500000000000015051422640020433 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/camellia/camellia.h0000664000175000017500000001121515051422640022353 0ustar ghudsonghudson/* lib/crypto/builtin/camellia/camellia.h - Camellia version 1.2.0 */ /* * Copyright (c) 2006,2007,2009 * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer as * the first lines of this file unmodified. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef HEADER_CAMELLIA_H #define HEADER_CAMELLIA_H #ifdef __cplusplus extern "C" { #endif #include #define CAMELLIA_BLOCK_SIZE 16 #define CAMELLIA_TABLE_BYTE_LEN 272 #define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) #ifndef BLOCK_SIZE #define BLOCK_SIZE CAMELLIA_BLOCK_SIZE #endif typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* u32 must be 32bit word */ typedef uint32_t u32; typedef uint8_t u8; /* For the Kerberos 5 tree, hide the Camellia symbol names. */ #define camellia_setup128 k5_camellia_setup128 #define camellia_setup192 k5_camellia_setup192 #define camellia_setup256 k5_camellia_setup256 #define camellia_encrypt128 k5_camellia_encrypt128 #define camellia_decrypt128 k5_camellia_decrypt128 #define camellia_encrypt256 k5_camellia_encrypt256 #define camellia_decrypt256 k5_camellia_decrypt256 #define Camellia_Ekeygen k5_Camellia_Ekeygen #define Camellia_EncryptBlock k5_Camellia_EncryptBlock #define Camellia_DecryptBlock k5_Camellia_DecryptBlock void camellia_setup128(const unsigned char *key, u32 *subkey); void camellia_setup192(const unsigned char *key, u32 *subkey); void camellia_setup256(const unsigned char *key, u32 *subkey); void camellia_encrypt128(const u32 *subkey, u32 *io); void camellia_decrypt128(const u32 *subkey, u32 *io); void camellia_encrypt256(const u32 *subkey, u32 *io); void camellia_decrypt256(const u32 *subkey, u32 *io); void Camellia_Ekeygen(const int keyBitLength, const unsigned char *rawKey, KEY_TABLE_TYPE keyTable); void Camellia_EncryptBlock(const int keyBitLength, const unsigned char *plaintext, const KEY_TABLE_TYPE keyTable, unsigned char *cipherText); void Camellia_DecryptBlock(const int keyBitLength, const unsigned char *cipherText, const KEY_TABLE_TYPE keyTable, unsigned char *plaintext); typedef uint16_t cam_fret; /* type for function return value */ #define camellia_good 1 #define camellia_bad 1 #ifndef CAMELLIA_DLL /* implement normal or DLL functions */ #define cam_rval cam_fret #else #define cam_rval cam_fret __declspec(dllexport) _stdcall #endif typedef struct /* the Camellia context for encryption */ { uint32_t k_sch[CAMELLIA_TABLE_WORD_LEN]; /* the encryption key schedule */ int keybitlen; /* bitlength of key */ } camellia_ctx; /* for Kerberos 5 tree -- hide names! */ #define camellia_blk_len krb5int_camellia_blk_len #define camellia_enc_key krb5int_camellia_enc_key #define camellia_enc_blk krb5int_camellia_enc_blk #define camellia_dec_key krb5int_camellia_dec_key #define camellia_dec_blk krb5int_camellia_dec_blk cam_rval camellia_blk_len(unsigned int blen, camellia_ctx cx[1]); cam_rval camellia_enc_key(const unsigned char in_key[], unsigned int klen, camellia_ctx cx[1]); cam_rval camellia_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const camellia_ctx cx[1]); cam_rval camellia_dec_key(const unsigned char in_key[], unsigned int klen, camellia_ctx cx[1]); cam_rval camellia_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const camellia_ctx cx[1]); #ifdef __cplusplus } #endif #endif /* HEADER_CAMELLIA_H */ krb5-1.22.1/src/lib/crypto/builtin/camellia/camellia.c0000664000175000017500000015715615051422640022365 0ustar ghudsonghudson/* lib/crypto/builtin/camellia/camellia.c - Camellia version 1.2.0 */ /* * Copyright (c) 2006,2007,2009 * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer as * the first lines of this file unmodified. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Algorithm Specification * https://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html */ #include #include #include "camellia.h" #include "crypto_int.h" #ifdef K5_BUILTIN_CAMELLIA /* key constants */ #define CAMELLIA_SIGMA1L (0xA09E667FL) #define CAMELLIA_SIGMA1R (0x3BCC908BL) #define CAMELLIA_SIGMA2L (0xB67AE858L) #define CAMELLIA_SIGMA2R (0x4CAA73B2L) #define CAMELLIA_SIGMA3L (0xC6EF372FL) #define CAMELLIA_SIGMA3R (0xE94F82BEL) #define CAMELLIA_SIGMA4L (0x54FF53A5L) #define CAMELLIA_SIGMA4R (0xF1D36F1CL) #define CAMELLIA_SIGMA5L (0x10E527FAL) #define CAMELLIA_SIGMA5R (0xDE682D1DL) #define CAMELLIA_SIGMA6L (0xB05688C2L) #define CAMELLIA_SIGMA6R (0xB3E6C1FDL) /* * macros */ #if defined(_MSC_VER) # define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) # define GETU32(p) SWAP(*((u32 *)(p))) # define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));} #else /* not MS-VC */ # define GETU32(pt) \ (((u32)(pt)[0] << 24) \ ^ ((u32)(pt)[1] << 16) \ ^ ((u32)(pt)[2] << 8) \ ^ ((u32)(pt)[3])) # define PUTU32(ct, st) { \ (ct)[0] = (u8)((st) >> 24); \ (ct)[1] = (u8)((st) >> 16); \ (ct)[2] = (u8)((st) >> 8); \ (ct)[3] = (u8)(st); } #endif #define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2]) #define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1]) /* rotation right shift 1byte */ #define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) /* rotation left shift 1bit */ #define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) /* rotation left shift 1byte */ #define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24)) #define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ do { \ w0 = ll; \ ll = (ll << bits) + (lr >> (32 - bits)); \ lr = (lr << bits) + (rl >> (32 - bits)); \ rl = (rl << bits) + (rr >> (32 - bits)); \ rr = (rr << bits) + (w0 >> (32 - bits)); \ } while(0) #define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \ do { \ w0 = ll; \ w1 = lr; \ ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \ lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \ rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \ rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \ } while(0) #define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)]) #define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)]) #define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)]) #define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)]) #define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ do { \ il = xl ^ kl; \ ir = xr ^ kr; \ t0 = il >> 16; \ t1 = ir >> 16; \ yl = CAMELLIA_SP1110(ir & 0xff) \ ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ ^ CAMELLIA_SP3033(t1 & 0xff) \ ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ ^ CAMELLIA_SP0222(t0 & 0xff) \ ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ ^ CAMELLIA_SP4404(il & 0xff); \ yl ^= yr; \ yr = CAMELLIA_RR8(yr); \ yr ^= yl; \ } while(0) /* * for speed up * */ #define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \ do { \ t0 = kll; \ t0 &= ll; \ lr ^= CAMELLIA_RL1(t0); \ t1 = klr; \ t1 |= lr; \ ll ^= t1; \ \ t2 = krr; \ t2 |= rr; \ rl ^= t2; \ t3 = krl; \ t3 &= rl; \ rr ^= CAMELLIA_RL1(t3); \ } while(0) #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ do { \ ir = CAMELLIA_SP1110(xr & 0xff) \ ^ CAMELLIA_SP0222((xr >> 24) & 0xff) \ ^ CAMELLIA_SP3033((xr >> 16) & 0xff) \ ^ CAMELLIA_SP4404((xr >> 8) & 0xff); \ il = CAMELLIA_SP1110((xl >> 24) & 0xff) \ ^ CAMELLIA_SP0222((xl >> 16) & 0xff) \ ^ CAMELLIA_SP3033((xl >> 8) & 0xff) \ ^ CAMELLIA_SP4404(xl & 0xff); \ il ^= kl; \ ir ^= kr; \ ir ^= il; \ il = CAMELLIA_RR8(il); \ il ^= ir; \ yl ^= ir; \ yr ^= il; \ } while(0) static const u32 camellia_sp1110[256] = { 0x70707000,0x82828200,0x2c2c2c00,0xececec00, 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500, 0xe4e4e400,0x85858500,0x57575700,0x35353500, 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100, 0x23232300,0xefefef00,0x6b6b6b00,0x93939300, 0x45454500,0x19191900,0xa5a5a500,0x21212100, 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00, 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00, 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00, 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00, 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00, 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00, 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00, 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00, 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600, 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00, 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600, 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00, 0x74747400,0x12121200,0x2b2b2b00,0x20202000, 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900, 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200, 0x34343400,0x7e7e7e00,0x76767600,0x05050500, 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100, 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700, 0x14141400,0x58585800,0x3a3a3a00,0x61616100, 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00, 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600, 0x53535300,0x18181800,0xf2f2f200,0x22222200, 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200, 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100, 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800, 0x60606000,0xfcfcfc00,0x69696900,0x50505000, 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00, 0xa1a1a100,0x89898900,0x62626200,0x97979700, 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500, 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200, 0x10101000,0xc4c4c400,0x00000000,0x48484800, 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00, 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00, 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400, 0x87878700,0x5c5c5c00,0x83838300,0x02020200, 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300, 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300, 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200, 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600, 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00, 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00, 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00, 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00, 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00, 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600, 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900, 0x78787800,0x98989800,0x06060600,0x6a6a6a00, 0xe7e7e700,0x46464600,0x71717100,0xbababa00, 0xd4d4d400,0x25252500,0xababab00,0x42424200, 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00, 0x72727200,0x07070700,0xb9b9b900,0x55555500, 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00, 0x36363600,0x49494900,0x2a2a2a00,0x68686800, 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400, 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00, 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100, 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400, 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00, }; static const u32 camellia_sp0222[256] = { 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9, 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb, 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a, 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282, 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727, 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242, 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c, 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b, 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f, 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d, 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe, 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434, 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595, 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a, 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad, 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a, 0x00171717,0x001a1a1a,0x00353535,0x00cccccc, 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a, 0x00e8e8e8,0x00242424,0x00565656,0x00404040, 0x00e1e1e1,0x00636363,0x00090909,0x00333333, 0x00bfbfbf,0x00989898,0x00979797,0x00858585, 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a, 0x00dadada,0x006f6f6f,0x00535353,0x00626262, 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf, 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2, 0x00bdbdbd,0x00363636,0x00222222,0x00383838, 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c, 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444, 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565, 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323, 0x00484848,0x00101010,0x00d1d1d1,0x00515151, 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0, 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa, 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f, 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b, 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5, 0x00202020,0x00898989,0x00000000,0x00909090, 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7, 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5, 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929, 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404, 0x009b9b9b,0x00949494,0x00212121,0x00666666, 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7, 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5, 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c, 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676, 0x00030303,0x002d2d2d,0x00dedede,0x00969696, 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c, 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919, 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d, 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d, 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2, 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4, 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575, 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484, 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5, 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa, 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414, 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0, 0x00787878,0x00707070,0x00e3e3e3,0x00494949, 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6, 0x00777777,0x00939393,0x00868686,0x00838383, 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9, 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d, }; static const u32 camellia_sp3033[256] = { 0x38003838,0x41004141,0x16001616,0x76007676, 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2, 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a, 0x75007575,0x06000606,0x57005757,0xa000a0a0, 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9, 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090, 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727, 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede, 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7, 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767, 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf, 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d, 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565, 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e, 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b, 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6, 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333, 0xfd00fdfd,0x66006666,0x58005858,0x96009696, 0x3a003a3a,0x09000909,0x95009595,0x10001010, 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc, 0xef00efef,0x26002626,0xe500e5e5,0x61006161, 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282, 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898, 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb, 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0, 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e, 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b, 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111, 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959, 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8, 0x12001212,0x04000404,0x74007474,0x54005454, 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828, 0x55005555,0x68006868,0x50005050,0xbe00bebe, 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb, 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca, 0x70007070,0xff00ffff,0x32003232,0x69006969, 0x08000808,0x62006262,0x00000000,0x24002424, 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded, 0x45004545,0x81008181,0x73007373,0x6d006d6d, 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a, 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101, 0xe600e6e6,0x25002525,0x48004848,0x99009999, 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9, 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171, 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313, 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d, 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5, 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717, 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646, 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747, 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b, 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac, 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535, 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d, 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121, 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d, 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa, 0x7c007c7c,0x77007777,0x56005656,0x05000505, 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434, 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252, 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd, 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0, 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a, 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f, }; static const u32 camellia_sp4404[256] = { 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0, 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae, 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5, 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092, 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f, 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b, 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d, 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c, 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0, 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084, 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076, 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004, 0x14140014,0x3a3a003a,0xdede00de,0x11110011, 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2, 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a, 0x24240024,0xe8e800e8,0x60600060,0x69690069, 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062, 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064, 0x10100010,0x00000000,0xa3a300a3,0x75750075, 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd, 0x87870087,0x83830083,0xcdcd00cd,0x90900090, 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf, 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6, 0x81810081,0x6f6f006f,0x13130013,0x63630063, 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc, 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4, 0x78780078,0x06060006,0xe7e700e7,0x71710071, 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d, 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac, 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1, 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043, 0x15150015,0xadad00ad,0x77770077,0x80800080, 0x82820082,0xecec00ec,0x27270027,0xe5e500e5, 0x85850085,0x35350035,0x0c0c000c,0x41410041, 0xefef00ef,0x93930093,0x19190019,0x21210021, 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd, 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce, 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a, 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d, 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d, 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d, 0x12120012,0x20200020,0xb1b100b1,0x99990099, 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005, 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7, 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c, 0x0f0f000f,0x16160016,0x18180018,0x22220022, 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091, 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050, 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097, 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2, 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db, 0x03030003,0xdada00da,0x3f3f003f,0x94940094, 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033, 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2, 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b, 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e, 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e, 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059, 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba, 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa, 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a, 0x49490049,0x68680068,0x38380038,0xa4a400a4, 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1, 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e, }; /** * Stuff related to the Camellia key schedule */ #define subl(x) subL[(x)] #define subr(x) subR[(x)] void camellia_setup128(const unsigned char *key, u32 *subkey) { u32 kll, klr, krl, krr; u32 il, ir, t0, t1, w0, w1; u32 kw4l, kw4r, dw, tl, tr; u32 subL[26]; u32 subR[26]; /** * k == kll || klr || krl || krr (|| is concatination) */ kll = GETU32(key ); klr = GETU32(key + 4); krl = GETU32(key + 8); krr = GETU32(key + 12); /** * generate KL dependent subkeys */ subl(0) = kll; subr(0) = klr; subl(1) = krl; subr(1) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); subl(4) = kll; subr(4) = klr; subl(5) = krl; subr(5) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); subl(10) = kll; subr(10) = klr; subl(11) = krl; subr(11) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); subl(13) = krl; subr(13) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); subl(16) = kll; subr(16) = klr; subl(17) = krl; subr(17) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); subl(18) = kll; subr(18) = klr; subl(19) = krl; subr(19) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); subl(22) = kll; subr(22) = klr; subl(23) = krl; subr(23) = krr; /* generate KA */ kll = subl(0); klr = subr(0); krl = subl(1); krr = subr(1); CAMELLIA_F(kll, klr, CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, w0, w1, il, ir, t0, t1); krl ^= w0; krr ^= w1; CAMELLIA_F(krl, krr, CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, kll, klr, il, ir, t0, t1); CAMELLIA_F(kll, klr, CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, krl, krr, il, ir, t0, t1); krl ^= w0; krr ^= w1; CAMELLIA_F(krl, krr, CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, w0, w1, il, ir, t0, t1); kll ^= w0; klr ^= w1; /* generate KA dependent subkeys */ subl(2) = kll; subr(2) = klr; subl(3) = krl; subr(3) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); subl(6) = kll; subr(6) = klr; subl(7) = krl; subr(7) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); subl(8) = kll; subr(8) = klr; subl(9) = krl; subr(9) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); subl(12) = kll; subr(12) = klr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); subl(14) = kll; subr(14) = klr; subl(15) = krl; subr(15) = krr; CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); subl(20) = kll; subr(20) = klr; subl(21) = krl; subr(21) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); subl(24) = kll; subr(24) = klr; subl(25) = krl; subr(25) = krr; /* absorb kw2 to other subkeys */ subl(3) ^= subl(1); subr(3) ^= subr(1); subl(5) ^= subl(1); subr(5) ^= subr(1); subl(7) ^= subl(1); subr(7) ^= subr(1); subl(1) ^= subr(1) & ~subr(9); dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); subl(11) ^= subl(1); subr(11) ^= subr(1); subl(13) ^= subl(1); subr(13) ^= subr(1); subl(15) ^= subl(1); subr(15) ^= subr(1); subl(1) ^= subr(1) & ~subr(17); dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); subl(19) ^= subl(1); subr(19) ^= subr(1); subl(21) ^= subl(1); subr(21) ^= subr(1); subl(23) ^= subl(1); subr(23) ^= subr(1); subl(24) ^= subl(1); subr(24) ^= subr(1); /* absorb kw4 to other subkeys */ kw4l = subl(25); kw4r = subr(25); subl(22) ^= kw4l; subr(22) ^= kw4r; subl(20) ^= kw4l; subr(20) ^= kw4r; subl(18) ^= kw4l; subr(18) ^= kw4r; kw4l ^= kw4r & ~subr(16); dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw); subl(14) ^= kw4l; subr(14) ^= kw4r; subl(12) ^= kw4l; subr(12) ^= kw4r; subl(10) ^= kw4l; subr(10) ^= kw4r; kw4l ^= kw4r & ~subr(8); dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw); subl(6) ^= kw4l; subr(6) ^= kw4r; subl(4) ^= kw4l; subr(4) ^= kw4r; subl(2) ^= kw4l; subr(2) ^= kw4r; subl(0) ^= kw4l; subr(0) ^= kw4r; /* key XOR is end of F-function */ CamelliaSubkeyL(0) = subl(0) ^ subl(2); CamelliaSubkeyR(0) = subr(0) ^ subr(2); CamelliaSubkeyL(2) = subl(3); CamelliaSubkeyR(2) = subr(3); CamelliaSubkeyL(3) = subl(2) ^ subl(4); CamelliaSubkeyR(3) = subr(2) ^ subr(4); CamelliaSubkeyL(4) = subl(3) ^ subl(5); CamelliaSubkeyR(4) = subr(3) ^ subr(5); CamelliaSubkeyL(5) = subl(4) ^ subl(6); CamelliaSubkeyR(5) = subr(4) ^ subr(6); CamelliaSubkeyL(6) = subl(5) ^ subl(7); CamelliaSubkeyR(6) = subr(5) ^ subr(7); tl = subl(10) ^ (subr(10) & ~subr(8)); dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(7) = subl(6) ^ tl; CamelliaSubkeyR(7) = subr(6) ^ tr; CamelliaSubkeyL(8) = subl(8); CamelliaSubkeyR(8) = subr(8); CamelliaSubkeyL(9) = subl(9); CamelliaSubkeyR(9) = subr(9); tl = subl(7) ^ (subr(7) & ~subr(9)); dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(10) = tl ^ subl(11); CamelliaSubkeyR(10) = tr ^ subr(11); CamelliaSubkeyL(11) = subl(10) ^ subl(12); CamelliaSubkeyR(11) = subr(10) ^ subr(12); CamelliaSubkeyL(12) = subl(11) ^ subl(13); CamelliaSubkeyR(12) = subr(11) ^ subr(13); CamelliaSubkeyL(13) = subl(12) ^ subl(14); CamelliaSubkeyR(13) = subr(12) ^ subr(14); CamelliaSubkeyL(14) = subl(13) ^ subl(15); CamelliaSubkeyR(14) = subr(13) ^ subr(15); tl = subl(18) ^ (subr(18) & ~subr(16)); dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(15) = subl(14) ^ tl; CamelliaSubkeyR(15) = subr(14) ^ tr; CamelliaSubkeyL(16) = subl(16); CamelliaSubkeyR(16) = subr(16); CamelliaSubkeyL(17) = subl(17); CamelliaSubkeyR(17) = subr(17); tl = subl(15) ^ (subr(15) & ~subr(17)); dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(18) = tl ^ subl(19); CamelliaSubkeyR(18) = tr ^ subr(19); CamelliaSubkeyL(19) = subl(18) ^ subl(20); CamelliaSubkeyR(19) = subr(18) ^ subr(20); CamelliaSubkeyL(20) = subl(19) ^ subl(21); CamelliaSubkeyR(20) = subr(19) ^ subr(21); CamelliaSubkeyL(21) = subl(20) ^ subl(22); CamelliaSubkeyR(21) = subr(20) ^ subr(22); CamelliaSubkeyL(22) = subl(21) ^ subl(23); CamelliaSubkeyR(22) = subr(21) ^ subr(23); CamelliaSubkeyL(23) = subl(22); CamelliaSubkeyR(23) = subr(22); CamelliaSubkeyL(24) = subl(24) ^ subl(23); CamelliaSubkeyR(24) = subr(24) ^ subr(23); /* apply the inverse of the last half of P-function */ dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw; dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw; dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw; dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw; dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw; dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw; dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw; dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw; dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw; dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw; dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw; dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw; dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw; dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw; dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw; dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw; dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw; dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw; return; } void camellia_setup256(const unsigned char *key, u32 *subkey) { u32 kll,klr,krl,krr; /* left half of key */ u32 krll,krlr,krrl,krrr; /* right half of key */ u32 il, ir, t0, t1, w0, w1; /* temporary variables */ u32 kw4l, kw4r, dw, tl, tr; u32 subL[34]; u32 subR[34]; /** * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) * (|| is concatination) */ kll = GETU32(key ); klr = GETU32(key + 4); krl = GETU32(key + 8); krr = GETU32(key + 12); krll = GETU32(key + 16); krlr = GETU32(key + 20); krrl = GETU32(key + 24); krrr = GETU32(key + 28); /* generate KL dependent subkeys */ subl(0) = kll; subr(0) = klr; subl(1) = krl; subr(1) = krr; CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45); subl(12) = kll; subr(12) = klr; subl(13) = krl; subr(13) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); subl(16) = kll; subr(16) = klr; subl(17) = krl; subr(17) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); subl(22) = kll; subr(22) = klr; subl(23) = krl; subr(23) = krr; CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); subl(30) = kll; subr(30) = klr; subl(31) = krl; subr(31) = krr; /* generate KR dependent subkeys */ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); subl(4) = krll; subr(4) = krlr; subl(5) = krrl; subr(5) = krrr; CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); subl(8) = krll; subr(8) = krlr; subl(9) = krrl; subr(9) = krrr; CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); subl(18) = krll; subr(18) = krlr; subl(19) = krrl; subr(19) = krrr; CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); subl(26) = krll; subr(26) = krlr; subl(27) = krrl; subr(27) = krrr; CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); /* generate KA */ kll = subl(0) ^ krll; klr = subr(0) ^ krlr; krl = subl(1) ^ krrl; krr = subr(1) ^ krrr; CAMELLIA_F(kll, klr, CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, w0, w1, il, ir, t0, t1); krl ^= w0; krr ^= w1; CAMELLIA_F(krl, krr, CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, kll, klr, il, ir, t0, t1); kll ^= krll; klr ^= krlr; CAMELLIA_F(kll, klr, CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, krl, krr, il, ir, t0, t1); krl ^= w0 ^ krrl; krr ^= w1 ^ krrr; CAMELLIA_F(krl, krr, CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, w0, w1, il, ir, t0, t1); kll ^= w0; klr ^= w1; /* generate KB */ krll ^= kll; krlr ^= klr; krrl ^= krl; krrr ^= krr; CAMELLIA_F(krll, krlr, CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R, w0, w1, il, ir, t0, t1); krrl ^= w0; krrr ^= w1; CAMELLIA_F(krrl, krrr, CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R, w0, w1, il, ir, t0, t1); krll ^= w0; krlr ^= w1; /* generate KA dependent subkeys */ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); subl(6) = kll; subr(6) = klr; subl(7) = krl; subr(7) = krr; CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); subl(14) = kll; subr(14) = klr; subl(15) = krl; subr(15) = krr; subl(24) = klr; subr(24) = krl; subl(25) = krr; subr(25) = kll; CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49); subl(28) = kll; subr(28) = klr; subl(29) = krl; subr(29) = krr; /* generate KB dependent subkeys */ subl(2) = krll; subr(2) = krlr; subl(3) = krrl; subr(3) = krrr; CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); subl(10) = krll; subr(10) = krlr; subl(11) = krrl; subr(11) = krrr; CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); subl(20) = krll; subr(20) = krlr; subl(21) = krrl; subr(21) = krrr; CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51); subl(32) = krll; subr(32) = krlr; subl(33) = krrl; subr(33) = krrr; /* absorb kw2 to other subkeys */ subl(3) ^= subl(1); subr(3) ^= subr(1); subl(5) ^= subl(1); subr(5) ^= subr(1); subl(7) ^= subl(1); subr(7) ^= subr(1); subl(1) ^= subr(1) & ~subr(9); dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); subl(11) ^= subl(1); subr(11) ^= subr(1); subl(13) ^= subl(1); subr(13) ^= subr(1); subl(15) ^= subl(1); subr(15) ^= subr(1); subl(1) ^= subr(1) & ~subr(17); dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); subl(19) ^= subl(1); subr(19) ^= subr(1); subl(21) ^= subl(1); subr(21) ^= subr(1); subl(23) ^= subl(1); subr(23) ^= subr(1); subl(1) ^= subr(1) & ~subr(25); dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw); subl(27) ^= subl(1); subr(27) ^= subr(1); subl(29) ^= subl(1); subr(29) ^= subr(1); subl(31) ^= subl(1); subr(31) ^= subr(1); subl(32) ^= subl(1); subr(32) ^= subr(1); /* absorb kw4 to other subkeys */ kw4l = subl(33); kw4r = subr(33); subl(30) ^= kw4l; subr(30) ^= kw4r; subl(28) ^= kw4l; subr(28) ^= kw4r; subl(26) ^= kw4l; subr(26) ^= kw4r; kw4l ^= kw4r & ~subr(24); dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw); subl(22) ^= kw4l; subr(22) ^= kw4r; subl(20) ^= kw4l; subr(20) ^= kw4r; subl(18) ^= kw4l; subr(18) ^= kw4r; kw4l ^= kw4r & ~subr(16); dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw); subl(14) ^= kw4l; subr(14) ^= kw4r; subl(12) ^= kw4l; subr(12) ^= kw4r; subl(10) ^= kw4l; subr(10) ^= kw4r; kw4l ^= kw4r & ~subr(8); dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw); subl(6) ^= kw4l; subr(6) ^= kw4r; subl(4) ^= kw4l; subr(4) ^= kw4r; subl(2) ^= kw4l; subr(2) ^= kw4r; subl(0) ^= kw4l; subr(0) ^= kw4r; /* key XOR is end of F-function */ CamelliaSubkeyL(0) = subl(0) ^ subl(2); CamelliaSubkeyR(0) = subr(0) ^ subr(2); CamelliaSubkeyL(2) = subl(3); CamelliaSubkeyR(2) = subr(3); CamelliaSubkeyL(3) = subl(2) ^ subl(4); CamelliaSubkeyR(3) = subr(2) ^ subr(4); CamelliaSubkeyL(4) = subl(3) ^ subl(5); CamelliaSubkeyR(4) = subr(3) ^ subr(5); CamelliaSubkeyL(5) = subl(4) ^ subl(6); CamelliaSubkeyR(5) = subr(4) ^ subr(6); CamelliaSubkeyL(6) = subl(5) ^ subl(7); CamelliaSubkeyR(6) = subr(5) ^ subr(7); tl = subl(10) ^ (subr(10) & ~subr(8)); dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(7) = subl(6) ^ tl; CamelliaSubkeyR(7) = subr(6) ^ tr; CamelliaSubkeyL(8) = subl(8); CamelliaSubkeyR(8) = subr(8); CamelliaSubkeyL(9) = subl(9); CamelliaSubkeyR(9) = subr(9); tl = subl(7) ^ (subr(7) & ~subr(9)); dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(10) = tl ^ subl(11); CamelliaSubkeyR(10) = tr ^ subr(11); CamelliaSubkeyL(11) = subl(10) ^ subl(12); CamelliaSubkeyR(11) = subr(10) ^ subr(12); CamelliaSubkeyL(12) = subl(11) ^ subl(13); CamelliaSubkeyR(12) = subr(11) ^ subr(13); CamelliaSubkeyL(13) = subl(12) ^ subl(14); CamelliaSubkeyR(13) = subr(12) ^ subr(14); CamelliaSubkeyL(14) = subl(13) ^ subl(15); CamelliaSubkeyR(14) = subr(13) ^ subr(15); tl = subl(18) ^ (subr(18) & ~subr(16)); dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(15) = subl(14) ^ tl; CamelliaSubkeyR(15) = subr(14) ^ tr; CamelliaSubkeyL(16) = subl(16); CamelliaSubkeyR(16) = subr(16); CamelliaSubkeyL(17) = subl(17); CamelliaSubkeyR(17) = subr(17); tl = subl(15) ^ (subr(15) & ~subr(17)); dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(18) = tl ^ subl(19); CamelliaSubkeyR(18) = tr ^ subr(19); CamelliaSubkeyL(19) = subl(18) ^ subl(20); CamelliaSubkeyR(19) = subr(18) ^ subr(20); CamelliaSubkeyL(20) = subl(19) ^ subl(21); CamelliaSubkeyR(20) = subr(19) ^ subr(21); CamelliaSubkeyL(21) = subl(20) ^ subl(22); CamelliaSubkeyR(21) = subr(20) ^ subr(22); CamelliaSubkeyL(22) = subl(21) ^ subl(23); CamelliaSubkeyR(22) = subr(21) ^ subr(23); tl = subl(26) ^ (subr(26) & ~subr(24)); dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(23) = subl(22) ^ tl; CamelliaSubkeyR(23) = subr(22) ^ tr; CamelliaSubkeyL(24) = subl(24); CamelliaSubkeyR(24) = subr(24); CamelliaSubkeyL(25) = subl(25); CamelliaSubkeyR(25) = subr(25); tl = subl(23) ^ (subr(23) & ~subr(25)); dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw); CamelliaSubkeyL(26) = tl ^ subl(27); CamelliaSubkeyR(26) = tr ^ subr(27); CamelliaSubkeyL(27) = subl(26) ^ subl(28); CamelliaSubkeyR(27) = subr(26) ^ subr(28); CamelliaSubkeyL(28) = subl(27) ^ subl(29); CamelliaSubkeyR(28) = subr(27) ^ subr(29); CamelliaSubkeyL(29) = subl(28) ^ subl(30); CamelliaSubkeyR(29) = subr(28) ^ subr(30); CamelliaSubkeyL(30) = subl(29) ^ subl(31); CamelliaSubkeyR(30) = subr(29) ^ subr(31); CamelliaSubkeyL(31) = subl(30); CamelliaSubkeyR(31) = subr(30); CamelliaSubkeyL(32) = subl(32) ^ subl(31); CamelliaSubkeyR(32) = subr(32) ^ subr(31); /* apply the inverse of the last half of P-function */ dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw; dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw; dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw; dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw; dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw; dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw; dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw; dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw; dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw; dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw; dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw; dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw; dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw; dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw; dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw; dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw; dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw; dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw; dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw; dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw; dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw; dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw; dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw; dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw); CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw; return; } void camellia_setup192(const unsigned char *key, u32 *subkey) { unsigned char kk[32]; u32 krll, krlr, krrl,krrr; memcpy(kk, key, 24); memcpy((unsigned char *)&krll, key+16,4); memcpy((unsigned char *)&krlr, key+20,4); krrl = ~krll; krrr = ~krlr; memcpy(kk+24, (unsigned char *)&krrl, 4); memcpy(kk+28, (unsigned char *)&krrr, 4); camellia_setup256(kk, subkey); return; } /** * Stuff related to camellia encryption/decryption * * "io" must be 4byte aligned and big-endian data. */ void camellia_encrypt128(const u32 *subkey, u32 *io) { u32 il, ir, t0, t1; /* pre whitening but absorb kw2*/ io[0] ^= CamelliaSubkeyL(0); io[1] ^= CamelliaSubkeyR(0); /* main iteration */ CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(2),CamelliaSubkeyR(2), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(3),CamelliaSubkeyR(3), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(4),CamelliaSubkeyR(4), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(5),CamelliaSubkeyR(5), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(6),CamelliaSubkeyR(6), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(7),CamelliaSubkeyR(7), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(8),CamelliaSubkeyR(8), CamelliaSubkeyL(9),CamelliaSubkeyR(9), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(10),CamelliaSubkeyR(10), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(11),CamelliaSubkeyR(11), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(12),CamelliaSubkeyR(12), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(13),CamelliaSubkeyR(13), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(14),CamelliaSubkeyR(14), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(15),CamelliaSubkeyR(15), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(16),CamelliaSubkeyR(16), CamelliaSubkeyL(17),CamelliaSubkeyR(17), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(18),CamelliaSubkeyR(18), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(19),CamelliaSubkeyR(19), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(20),CamelliaSubkeyR(20), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(21),CamelliaSubkeyR(21), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(22),CamelliaSubkeyR(22), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(23),CamelliaSubkeyR(23), io[0],io[1],il,ir,t0,t1); /* post whitening but kw4 */ io[2] ^= CamelliaSubkeyL(24); io[3] ^= CamelliaSubkeyR(24); t0 = io[0]; t1 = io[1]; io[0] = io[2]; io[1] = io[3]; io[2] = t0; io[3] = t1; return; } void camellia_decrypt128(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ /* pre whitening but absorb kw2*/ io[0] ^= CamelliaSubkeyL(24); io[1] ^= CamelliaSubkeyR(24); /* main iteration */ CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(23),CamelliaSubkeyR(23), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(22),CamelliaSubkeyR(22), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(21),CamelliaSubkeyR(21), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(20),CamelliaSubkeyR(20), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(19),CamelliaSubkeyR(19), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(18),CamelliaSubkeyR(18), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(17),CamelliaSubkeyR(17), CamelliaSubkeyL(16),CamelliaSubkeyR(16), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(15),CamelliaSubkeyR(15), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(14),CamelliaSubkeyR(14), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(13),CamelliaSubkeyR(13), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(12),CamelliaSubkeyR(12), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(11),CamelliaSubkeyR(11), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(10),CamelliaSubkeyR(10), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(9),CamelliaSubkeyR(9), CamelliaSubkeyL(8),CamelliaSubkeyR(8), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(7),CamelliaSubkeyR(7), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(6),CamelliaSubkeyR(6), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(5),CamelliaSubkeyR(5), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(4),CamelliaSubkeyR(4), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(3),CamelliaSubkeyR(3), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(2),CamelliaSubkeyR(2), io[0],io[1],il,ir,t0,t1); /* post whitening but kw4 */ io[2] ^= CamelliaSubkeyL(0); io[3] ^= CamelliaSubkeyR(0); t0 = io[0]; t1 = io[1]; io[0] = io[2]; io[1] = io[3]; io[2] = t0; io[3] = t1; return; } /** * stuff for 192 and 256bit encryption/decryption */ void camellia_encrypt256(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ /* pre whitening but absorb kw2*/ io[0] ^= CamelliaSubkeyL(0); io[1] ^= CamelliaSubkeyR(0); /* main iteration */ CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(2),CamelliaSubkeyR(2), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(3),CamelliaSubkeyR(3), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(4),CamelliaSubkeyR(4), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(5),CamelliaSubkeyR(5), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(6),CamelliaSubkeyR(6), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(7),CamelliaSubkeyR(7), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(8),CamelliaSubkeyR(8), CamelliaSubkeyL(9),CamelliaSubkeyR(9), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(10),CamelliaSubkeyR(10), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(11),CamelliaSubkeyR(11), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(12),CamelliaSubkeyR(12), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(13),CamelliaSubkeyR(13), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(14),CamelliaSubkeyR(14), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(15),CamelliaSubkeyR(15), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(16),CamelliaSubkeyR(16), CamelliaSubkeyL(17),CamelliaSubkeyR(17), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(18),CamelliaSubkeyR(18), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(19),CamelliaSubkeyR(19), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(20),CamelliaSubkeyR(20), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(21),CamelliaSubkeyR(21), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(22),CamelliaSubkeyR(22), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(23),CamelliaSubkeyR(23), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(24),CamelliaSubkeyR(24), CamelliaSubkeyL(25),CamelliaSubkeyR(25), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(26),CamelliaSubkeyR(26), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(27),CamelliaSubkeyR(27), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(28),CamelliaSubkeyR(28), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(29),CamelliaSubkeyR(29), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(30),CamelliaSubkeyR(30), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(31),CamelliaSubkeyR(31), io[0],io[1],il,ir,t0,t1); /* post whitening but kw4 */ io[2] ^= CamelliaSubkeyL(32); io[3] ^= CamelliaSubkeyR(32); t0 = io[0]; t1 = io[1]; io[0] = io[2]; io[1] = io[3]; io[2] = t0; io[3] = t1; return; } void camellia_decrypt256(const u32 *subkey, u32 *io) { u32 il,ir,t0,t1; /* temporary valiables */ /* pre whitening but absorb kw2*/ io[0] ^= CamelliaSubkeyL(32); io[1] ^= CamelliaSubkeyR(32); /* main iteration */ CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(31),CamelliaSubkeyR(31), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(30),CamelliaSubkeyR(30), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(29),CamelliaSubkeyR(29), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(28),CamelliaSubkeyR(28), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(27),CamelliaSubkeyR(27), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(26),CamelliaSubkeyR(26), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(25),CamelliaSubkeyR(25), CamelliaSubkeyL(24),CamelliaSubkeyR(24), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(23),CamelliaSubkeyR(23), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(22),CamelliaSubkeyR(22), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(21),CamelliaSubkeyR(21), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(20),CamelliaSubkeyR(20), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(19),CamelliaSubkeyR(19), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(18),CamelliaSubkeyR(18), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(17),CamelliaSubkeyR(17), CamelliaSubkeyL(16),CamelliaSubkeyR(16), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(15),CamelliaSubkeyR(15), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(14),CamelliaSubkeyR(14), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(13),CamelliaSubkeyR(13), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(12),CamelliaSubkeyR(12), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(11),CamelliaSubkeyR(11), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(10),CamelliaSubkeyR(10), io[0],io[1],il,ir,t0,t1); CAMELLIA_FLS(io[0],io[1],io[2],io[3], CamelliaSubkeyL(9),CamelliaSubkeyR(9), CamelliaSubkeyL(8),CamelliaSubkeyR(8), t0,t1,il,ir); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(7),CamelliaSubkeyR(7), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(6),CamelliaSubkeyR(6), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(5),CamelliaSubkeyR(5), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(4),CamelliaSubkeyR(4), io[0],io[1],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[0],io[1], CamelliaSubkeyL(3),CamelliaSubkeyR(3), io[2],io[3],il,ir,t0,t1); CAMELLIA_ROUNDSM(io[2],io[3], CamelliaSubkeyL(2),CamelliaSubkeyR(2), io[0],io[1],il,ir,t0,t1); /* post whitening but kw4 */ io[2] ^= CamelliaSubkeyL(0); io[3] ^= CamelliaSubkeyR(0); t0 = io[0]; t1 = io[1]; io[0] = io[2]; io[1] = io[3]; io[2] = t0; io[3] = t1; return; } /*** * * API for compatibility */ void Camellia_Ekeygen(const int keyBitLength, const unsigned char *rawKey, KEY_TABLE_TYPE keyTable) { switch(keyBitLength) { case 128: camellia_setup128(rawKey, keyTable); break; case 192: camellia_setup192(rawKey, keyTable); break; case 256: camellia_setup256(rawKey, keyTable); break; default: break; } } void Camellia_EncryptBlock(const int keyBitLength, const unsigned char *plaintext, const KEY_TABLE_TYPE keyTable, unsigned char *ciphertext) { u32 tmp[4]; tmp[0] = GETU32(plaintext); tmp[1] = GETU32(plaintext + 4); tmp[2] = GETU32(plaintext + 8); tmp[3] = GETU32(plaintext + 12); switch (keyBitLength) { case 128: camellia_encrypt128(keyTable, tmp); break; case 192: /* fall through */ case 256: camellia_encrypt256(keyTable, tmp); break; default: break; } PUTU32(ciphertext, tmp[0]); PUTU32(ciphertext + 4, tmp[1]); PUTU32(ciphertext + 8, tmp[2]); PUTU32(ciphertext + 12, tmp[3]); } void Camellia_DecryptBlock(const int keyBitLength, const unsigned char *ciphertext, const KEY_TABLE_TYPE keyTable, unsigned char *plaintext) { u32 tmp[4]; tmp[0] = GETU32(ciphertext); tmp[1] = GETU32(ciphertext + 4); tmp[2] = GETU32(ciphertext + 8); tmp[3] = GETU32(ciphertext + 12); switch (keyBitLength) { case 128: camellia_decrypt128(keyTable, tmp); break; case 192: /* fall through */ case 256: camellia_decrypt256(keyTable, tmp); break; default: break; } PUTU32(plaintext, tmp[0]); PUTU32(plaintext + 4, tmp[1]); PUTU32(plaintext + 8, tmp[2]); PUTU32(plaintext + 12, tmp[3]); } cam_rval camellia_blk_len(unsigned int blen, camellia_ctx cx[1]){ if(blen != 16) return camellia_bad; return camellia_good; } cam_rval camellia_enc_key(const unsigned char in_key[], unsigned int klen, camellia_ctx cx[1]){ switch(klen){ case 16: camellia_setup128(in_key, cx->k_sch); cx->keybitlen = 128; break; case 24: camellia_setup192(in_key, cx->k_sch); cx->keybitlen = 192; break; case 32: camellia_setup256(in_key, cx->k_sch); cx->keybitlen = 256; break; default: return camellia_bad; } return camellia_good; } cam_rval camellia_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const camellia_ctx cx[1]){ Camellia_EncryptBlock(cx->keybitlen, in_blk, cx->k_sch, out_blk); return camellia_good; } cam_rval camellia_dec_key(const unsigned char in_key[], unsigned int klen, camellia_ctx cx[1]){ switch(klen){ case 16: camellia_setup128(in_key, cx->k_sch); cx->keybitlen = 128; break; case 24: camellia_setup192(in_key, cx->k_sch); cx->keybitlen = 192; break; case 32: camellia_setup256(in_key, cx->k_sch); cx->keybitlen = 256; break; default: return camellia_bad; } return camellia_good; } cam_rval camellia_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const camellia_ctx cx[1]){ Camellia_DecryptBlock(cx->keybitlen, in_blk, cx->k_sch, out_blk); return camellia_good; } #endif /* K5_BUILTIN_CAMELLIA */ krb5-1.22.1/src/lib/crypto/builtin/camellia/Makefile.in0000664000175000017500000000162615051422640022505 0ustar ghudsonghudsonthisconfigdir=../../../.. myfulldir=lib/crypto/builtin/camellia mydir=lib$(S)crypto$(S)builtin$(S)camellia BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES=-I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLGAS) ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = builtin\camellia ##DOS##OBJFILE = ..\..\$(OUTPRE)camellia.lst STLIBOBJS= camellia.o OBJS= $(OUTPRE)camellia.$(OBJEXT) SRCS= $(srcdir)/camellia.c EXTRADEPSRCS= $(srcdir)/camellia-gen.c GEN_OBJS= $(OUTPRE)camellia.$(OBJEXT) ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs # camellia-gen includes: depend depend: $(SRCS) camellia-gen: camellia-gen.o $(GEN_OBJS) $(CC_LINK) -o camellia-gen camellia-gen.o $(GEN_OBJS) run-camellia-gen: camellia-gen ./camellia-gen > kresults.out check-unix: check-@CRYPTO_BUILTIN_TESTS@ check-no: check-yes: run-camellia-gen clean-unix:: clean-libobjs clean: -$(RM) camellia-gen camellia-gen.o kresults.out @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/camellia/camellia-gen.c0000664000175000017500000002063515051422640023123 0ustar ghudsonghudson/* * Copyright (c) 2009 * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved. */ #include #include #include #include #include "camellia.h" #define B 16U unsigned char key[16]; unsigned char test_case_len[] = { B+1, 2*B-1, 2*B, 2*B+1, 3*B-1, 3*B, 4*B, }; #define NTESTS (sizeof(test_case_len)) struct { unsigned char ivec[16]; unsigned char input[4*16]; unsigned char output[4*16]; } test_case[NTESTS]; camellia_ctx ctx, dctx; static void init (void) { size_t i, j; cam_rval r; srand(42); for (i = 0; i < 16; i++) key[i] = 0xff & rand(); memset(test_case, 0, sizeof(test_case)); for (i = 0; i < NTESTS; i++) for (j = 0; j < test_case_len[i]; j++) { test_case[i].input[j] = 0xff & rand(); } r = camellia_enc_key (key, sizeof(key), &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); r = camellia_dec_key (key, sizeof(key), &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); } static void hexdump(const unsigned char *ptr, size_t len) { size_t i; for (i = 0; i < len; i++) printf ("%s%02X", (i % 16 == 0) ? "\n " : " ", ptr[i]); } static void fips_test (void) { static const unsigned char fipskey[16] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, }; static const unsigned char input[16] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, }; static const unsigned char expected[16] = { 0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73, 0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43 }; unsigned char output[16]; unsigned char tmp[16]; camellia_ctx fipsctx; int r; printf ("FIPS test:\nkey:"); hexdump (fipskey, 16); printf ("\ninput:"); hexdump (input, 16); r = camellia_enc_key (fipskey, sizeof(fipskey), &fipsctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); r = camellia_enc_blk (input, output, &fipsctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); printf ("\noutput:"); hexdump (output, 16); printf ("\n"); if (memcmp(expected, output, 16)) fprintf(stderr, "wrong results!!!\n"), exit (1); r = camellia_dec_key (fipskey, sizeof(fipskey), &fipsctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); r = camellia_dec_blk (output, tmp, &fipsctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); if (memcmp(input, tmp, 16)) fprintf(stderr, "decryption failed!!\n"), exit(1); printf ("ok.\n\n"); } static void xor (unsigned char *out, const unsigned char *a, const unsigned char *b) { size_t i; for (i = 0; i < B; i++) out[i] = a[i] ^ b[i]; } static void ecb_enc (unsigned char *out, unsigned char *in, unsigned int len) { size_t i; cam_rval r; for (i = 0; i < len; i += 16) { r = camellia_enc_blk (in + i, out + i, &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); } if (i != len) abort (); } static void ecb_dec (unsigned char *out, unsigned char *in, unsigned int len) { size_t i; cam_rval r; for (i = 0; i < len; i += 16) { r = camellia_dec_blk (in + i, out + i, &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); } if (i != len) abort (); } #define D(X) (printf("%s %d: %s=",__FUNCTION__,__LINE__, #X),hexdump(X,B),printf("\n")) #undef D #define D(X) static void cbc_enc (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { size_t i; cam_rval r; unsigned char tmp[B]; D(iv); memcpy (tmp, iv, B); for (i = 0; i < len; i += B) { D(in+i); xor (tmp, tmp, in + i); D(tmp); r = camellia_enc_blk (tmp, out + i, &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); memcpy (tmp, out + i, B); D(out+i); } if (i != len) abort (); } static void cbc_dec (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { size_t i; cam_rval r; unsigned char tmp[B]; memcpy (tmp, iv, B); for (i = 0; i < len; i += B) { r = camellia_dec_blk (in + i, tmp, &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); xor (tmp, tmp, iv); iv = in + i; memcpy (out + i, tmp, B); } if (i != len) abort (); } static void cts_enc (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { int r; unsigned int len2; unsigned char pn1[B], pn[B], cn[B], cn1[B]; if (len < B + 1) abort (); len2 = (len - B - 1) & ~(B-1); cbc_enc (out, in, iv, len2); out += len2; in += len2; len -= len2; if (len2) iv = out - B; if (len <= B || len > 2 * B) abort (); printf ("(did CBC mode for %d)\n", len2); D(in); xor (pn1, in, iv); D(pn1); r = camellia_enc_blk (pn1, cn, &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); D(cn); memset (pn, 0, sizeof(pn)); memcpy (pn, in+B, len-B); D(pn); xor (pn, pn, cn); D(pn); r = camellia_enc_blk (pn, cn1, &ctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); D(cn1); memcpy(out, cn1, B); memcpy(out+B, cn, len-B); } static void cts_dec (unsigned char *out, unsigned char *in, unsigned char *iv, unsigned int len) { int r; unsigned int len2; unsigned char pn1[B], pn[B], cn[B], cn1[B]; if (len < B + 1) abort (); len2 = (len - B - 1) & ~(B-1); cbc_dec (out, in, iv, len2); out += len2; in += len2; len -= len2; if (len2) iv = in - B; if (len <= B || len > 2 * B) abort (); memcpy (cn1, in, B); r = camellia_dec_blk (cn1, pn, &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); memset (cn, 0, sizeof(cn)); memcpy (cn, in+B, len-B); xor (pn, pn, cn); memcpy (cn+len-B, pn+len-B, 2*B-len); r = camellia_dec_blk (cn, pn1, &dctx); if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1); xor (pn1, pn1, iv); memcpy(out, pn1, B); memcpy(out+B, pn, len-B); } static void ecb_test (void) { size_t testno; unsigned char tmp[4*B]; printf ("ECB tests:\n"); printf ("key:"); hexdump (key, sizeof(key)); for (testno = 0; testno < NTESTS; testno++) { unsigned len = (test_case_len[testno] + 15) & ~15; printf ("\ntest %d - %d bytes\n", (int)testno, len); printf ("input:"); hexdump (test_case[testno].input, len); printf ("\n"); ecb_enc (test_case[testno].output, test_case[testno].input, len); printf ("output:"); hexdump (test_case[testno].output, len); printf ("\n"); ecb_dec (tmp, test_case[testno].output, len); if (memcmp (tmp, test_case[testno].input, len)) { printf ("ecb decrypt failed!!"); hexdump (tmp, len); printf ("\n"); exit (1); } } printf ("\n"); } unsigned char ivec[16] = { 0 }; static void cbc_test (void) { size_t testno; unsigned char tmp[4*B]; printf ("CBC tests:\n"); printf ("initial vector:"); hexdump (ivec, sizeof(ivec)); for (testno = 0; testno < NTESTS; testno++) { unsigned len = (test_case_len[testno] + 15) & ~15; printf ("\ntest %d - %d bytes\n", (int)testno, len); printf ("input:"); hexdump (test_case[testno].input, len); printf ("\n"); cbc_enc (test_case[testno].output, test_case[testno].input, ivec, len); printf ("output:"); hexdump (test_case[testno].output, len); printf ("\n"); cbc_dec (tmp, test_case[testno].output, ivec, len); if (memcmp (tmp, test_case[testno].input, len)) { printf("cbc decrypt failed!!"); hexdump (tmp, len); printf ("\n"); exit(1); } } printf ("\n"); } static void cts_test (void) { size_t testno; unsigned char tmp[4*B]; printf ("CTS tests:\n"); printf ("initial vector:"); hexdump (ivec, sizeof(ivec)); for (testno = 0; testno < NTESTS; testno++) { unsigned int len = test_case_len[testno]; printf ("\ntest %d - %d bytes\n", (int)testno, len); printf ("input:"); hexdump (test_case[testno].input, len); printf ("\n"); cts_enc (test_case[testno].output, test_case[testno].input, ivec, len); printf ("output:"); hexdump (test_case[testno].output, len); printf ("\n"); cts_dec (tmp, test_case[testno].output, ivec, len); if (memcmp (tmp, test_case[testno].input, len)) fprintf (stderr, "cts decrypt failed!!\n"), exit(1); } printf ("\n"); } int main (void) { init (); fips_test (); ecb_test(); cbc_test(); cts_test(); return 0; } krb5-1.22.1/src/lib/crypto/builtin/camellia/deps0000664000175000017500000000162515051422640021315 0ustar ghudsonghudson# # Generated makefile dependencies follow. # camellia.so camellia.po $(OUTPRE)camellia.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h camellia.c camellia.h camellia-gen.so camellia-gen.po $(OUTPRE)camellia-gen.$(OBJEXT): \ camellia-gen.c camellia.h krb5-1.22.1/src/lib/crypto/builtin/md5/0000775000175000017500000000000015051422640017351 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/md5/rsa-md5.h0000664000175000017500000000513415051422640020775 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. * * License to copy and use this software is granted provided that * it is identified as the "RSA Data Security, Inc. MD5 Message- * Digest Algorithm" in all material mentioning or referencing this * software or this function. * * License is also granted to make and use derivative works * provided that such works are identified as "derived from the RSA * Data Security, Inc. MD5 Message-Digest Algorithm" in all * material mentioning or referencing the derived work. * * RSA Data Security, Inc. makes no representations concerning * either the merchantability of this software or the suitability * of this software for any particular purpose. It is provided "as * is" without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. */ /* *********************************************************************** ** md5.h -- header file for implementation of MD5 ** ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** ** Revised (for MD5): RLR 4/27/91 ** ** -- G modified to have y&~z instead of y&z ** ** -- FF, GG, HH modified to add in last register done ** ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** ** -- distinct additive constant for each step ** ** -- round 4 added, working mod 7 ** *********************************************************************** */ #ifndef KRB5_RSA_MD5__ #define KRB5_RSA_MD5__ /* Data structure for MD5 (Message-Digest) computation */ typedef struct { krb5_ui_4 i[2]; /* number of _bits_ handled mod 2^64 */ krb5_ui_4 buf[4]; /* scratch buffer */ unsigned char in[64]; /* input buffer */ unsigned char digest[16]; /* actual digest after MD5Final call */ } krb5_MD5_CTX; extern void krb5int_MD5Init(krb5_MD5_CTX *); extern void krb5int_MD5Update(krb5_MD5_CTX *,const unsigned char *,unsigned int); extern void krb5int_MD5Final(krb5_MD5_CTX *); #define RSA_MD5_CKSUM_LENGTH 16 #define OLD_RSA_MD5_DES_CKSUM_LENGTH 16 #define NEW_RSA_MD5_DES_CKSUM_LENGTH 24 #define RSA_MD5_DES_CONFOUND_LENGTH 8 #endif /* KRB5_RSA_MD5__ */ krb5-1.22.1/src/lib/crypto/builtin/md5/Makefile.in0000664000175000017500000000072715051422640021424 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)builtin$(S)md5 BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES=-I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLAGS) ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = builtin\md5 ##DOS##OBJFILE = ..\..\$(OUTPRE)md5.lst STLIBOBJS= md5.o OBJS= $(OUTPRE)md5.$(OBJEXT) SRCS= $(srcdir)/md5.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs includes: depend depend: $(SRCS) check-unix: check-windows: clean: clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/md5/deps0000664000175000017500000000144115051422640020227 0ustar ghudsonghudson# # Generated makefile dependencies follow. # md5.so md5.po $(OUTPRE)md5.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ md5.c rsa-md5.h krb5-1.22.1/src/lib/crypto/builtin/md5/md5.c0000664000175000017500000003260615051422640020211 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. * * License to copy and use this software is granted provided that * it is identified as the "RSA Data Security, Inc. MD5 Message- * Digest Algorithm" in all material mentioning or referencing this * software or this function. * * License is also granted to make and use derivative works * provided that such works are identified as "derived from the RSA * Data Security, Inc. MD5 Message-Digest Algorithm" in all * material mentioning or referencing the derived work. * * RSA Data Security, Inc. makes no representations concerning * either the merchantability of this software or the suitability * of this software for any particular purpose. It is provided "as * is" without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. */ /* *********************************************************************** ** md5.c -- the source code for MD5 routines ** ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** *********************************************************************** */ /* * Modified by John Carr, MIT, to use Kerberos 5 typedefs. */ #include "crypto_int.h" #include "rsa-md5.h" #ifdef K5_BUILTIN_MD5 /* *********************************************************************** ** Message-digest routines: ** ** To form the message digest for a message M ** ** (1) Initialize a context buffer mdContext using krb5int_MD5Init ** ** (2) Call krb5int_MD5Update on mdContext and M ** ** (3) Call krb5int_MD5Final on mdContext ** ** The message digest is now in mdContext->digest[0...15] ** *********************************************************************** */ /* forward declaration */ static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in); static const unsigned char PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* F, G, H and I are basic MD5 functions */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits */ #define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffff) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ /* Rotation is separate from addition to prevent recomputation */ #define FF(a, b, c, d, x, s, ac) \ {(a) += F ((b), (c), (d)) + (x) + (krb5_ui_4)(ac); \ (a) &= 0xffffffff; \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ (a) &= 0xffffffff; \ } #define GG(a, b, c, d, x, s, ac) \ {(a) += G ((b), (c), (d)) + (x) + (krb5_ui_4)(ac); \ (a) &= 0xffffffff; \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ (a) &= 0xffffffff; \ } #define HH(a, b, c, d, x, s, ac) \ {(a) += H ((b), (c), (d)) + (x) + (krb5_ui_4)(ac); \ (a) &= 0xffffffff; \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ (a) &= 0xffffffff; \ } #define II(a, b, c, d, x, s, ac) \ {(a) += I ((b), (c), (d)) + (x) + (krb5_ui_4)(ac); \ (a) &= 0xffffffff; \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ (a) &= 0xffffffff; \ } /* The routine krb5int_MD5Init initializes the message-digest context mdContext. All fields are set to zero. */ void krb5int_MD5Init (krb5_MD5_CTX *mdContext) { mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0; /* Load magic initialization constants. */ mdContext->buf[0] = 0x67452301UL; mdContext->buf[1] = 0xefcdab89UL; mdContext->buf[2] = 0x98badcfeUL; mdContext->buf[3] = 0x10325476UL; } /* The routine krb5int_MD5Update updates the message-digest context to account for the presence of each of the characters inBuf[0..inLen-1] in the message whose digest is being computed. */ void krb5int_MD5Update (krb5_MD5_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen) { krb5_ui_4 in[16]; int mdi; unsigned int i, ii; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* update number of bits */ if ((mdContext->i[0] + ((krb5_ui_4)inLen << 3)) < mdContext->i[0]) mdContext->i[1]++; mdContext->i[0] += ((krb5_ui_4)inLen << 3); mdContext->i[1] += ((krb5_ui_4)inLen >> 29); while (inLen--) { /* add new character to buffer, increment mdi */ mdContext->in[mdi++] = *inBuf++; /* transform if necessary */ if (mdi == 0x40) { for (i = 0, ii = 0; i < 16; i++, ii += 4) in[i] = load_32_le(mdContext->in+ii); Transform (mdContext->buf, in); mdi = 0; } } } /* The routine krb5int_MD5Final terminates the message-digest computation and ends with the desired message digest in mdContext->digest[0...15]. */ void krb5int_MD5Final (krb5_MD5_CTX *mdContext) { krb5_ui_4 in[16]; int mdi; unsigned int i, ii; unsigned int padLen; /* save number of bits */ in[14] = mdContext->i[0]; in[15] = mdContext->i[1]; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* pad out to 56 mod 64 */ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); krb5int_MD5Update (mdContext, PADDING, padLen); /* append length in bits and transform */ for (i = 0, ii = 0; i < 14; i++, ii += 4) in[i] = load_32_le(mdContext->in+ii); Transform (mdContext->buf, in); /* store buffer in digest */ for (i = 0, ii = 0; i < 4; i++, ii += 4) { store_32_le(mdContext->buf[i], mdContext->digest+ii); } } /* Basic MD5 step. Transforms buf based on in. */ static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in) { krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; #if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO) int i; #define ROTATE { krb5_ui_4 temp; temp = d, d = c, c = b, b = a, a = temp; } for (i = 0; i < 16; i++) { const unsigned char round1s[] = { 7, 12, 17, 22 }; const krb5_ui_4 round1consts[] = { 3614090360UL, 3905402710UL, 606105819UL, 3250441966UL, 4118548399UL, 1200080426UL, 2821735955UL, 4249261313UL, 1770035416UL, 2336552879UL, 4294925233UL, 2304563134UL, 1804603682UL, 4254626195UL, 2792965006UL, 1236535329UL, }; FF (a, b, c, d, in[i], round1s[i%4], round1consts[i]); ROTATE; } for (i = 0; i < 16; i++) { const unsigned char round2s[] = { 5, 9, 14, 20 }; const krb5_ui_4 round2consts[] = { 4129170786UL, 3225465664UL, 643717713UL, 3921069994UL, 3593408605UL, 38016083UL, 3634488961UL, 3889429448UL, 568446438UL, 3275163606UL, 4107603335UL, 1163531501UL, 2850285829UL, 4243563512UL, 1735328473UL, 2368359562UL, }; int r2index = (1 + i * 5) % 16; GG (a, b, c, d, in[r2index], round2s[i%4], round2consts[i]); ROTATE; } for (i = 0; i < 16; i++) { static const unsigned char round3s[] = { 4, 11, 16, 23 }; static const krb5_ui_4 round3consts[] = { 4294588738UL, 2272392833UL, 1839030562UL, 4259657740UL, 2763975236UL, 1272893353UL, 4139469664UL, 3200236656UL, 681279174UL, 3936430074UL, 3572445317UL, 76029189UL, 3654602809UL, 3873151461UL, 530742520UL, 3299628645UL, }; int r3index = (5 + i * 3) % 16; HH (a, b, c, d, in[r3index], round3s[i%4], round3consts[i]); ROTATE; } for (i = 0; i < 16; i++) { static const unsigned char round4s[] = { 6, 10, 15, 21 }; static const krb5_ui_4 round4consts[] = { 4096336452UL, 1126891415UL, 2878612391UL, 4237533241UL, 1700485571UL, 2399980690UL, 4293915773UL, 2240044497UL, 1873313359UL, 4264355552UL, 2734768916UL, 1309151649UL, 4149444226UL, 3174756917UL, 718787259UL, 3951481745UL, }; int r4index = (7 * i) % 16; II (a, b, c, d, in[r4index], round4s[i%4], round4consts[i]); ROTATE; } #else /* Round 1 */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 FF ( a, b, c, d, in[ 0], S11, 3614090360UL); /* 1 */ FF ( d, a, b, c, in[ 1], S12, 3905402710UL); /* 2 */ FF ( c, d, a, b, in[ 2], S13, 606105819UL); /* 3 */ FF ( b, c, d, a, in[ 3], S14, 3250441966UL); /* 4 */ FF ( a, b, c, d, in[ 4], S11, 4118548399UL); /* 5 */ FF ( d, a, b, c, in[ 5], S12, 1200080426UL); /* 6 */ FF ( c, d, a, b, in[ 6], S13, 2821735955UL); /* 7 */ FF ( b, c, d, a, in[ 7], S14, 4249261313UL); /* 8 */ FF ( a, b, c, d, in[ 8], S11, 1770035416UL); /* 9 */ FF ( d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */ FF ( c, d, a, b, in[10], S13, 4294925233UL); /* 11 */ FF ( b, c, d, a, in[11], S14, 2304563134UL); /* 12 */ FF ( a, b, c, d, in[12], S11, 1804603682UL); /* 13 */ FF ( d, a, b, c, in[13], S12, 4254626195UL); /* 14 */ FF ( c, d, a, b, in[14], S13, 2792965006UL); /* 15 */ FF ( b, c, d, a, in[15], S14, 1236535329UL); /* 16 */ /* Round 2 */ #define S21 5 #define S22 9 #define S23 14 #define S24 20 GG ( a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */ GG ( d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */ GG ( c, d, a, b, in[11], S23, 643717713UL); /* 19 */ GG ( b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */ GG ( a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */ GG ( d, a, b, c, in[10], S22, 38016083UL); /* 22 */ GG ( c, d, a, b, in[15], S23, 3634488961UL); /* 23 */ GG ( b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */ GG ( a, b, c, d, in[ 9], S21, 568446438UL); /* 25 */ GG ( d, a, b, c, in[14], S22, 3275163606UL); /* 26 */ GG ( c, d, a, b, in[ 3], S23, 4107603335UL); /* 27 */ GG ( b, c, d, a, in[ 8], S24, 1163531501UL); /* 28 */ GG ( a, b, c, d, in[13], S21, 2850285829UL); /* 29 */ GG ( d, a, b, c, in[ 2], S22, 4243563512UL); /* 30 */ GG ( c, d, a, b, in[ 7], S23, 1735328473UL); /* 31 */ GG ( b, c, d, a, in[12], S24, 2368359562UL); /* 32 */ /* Round 3 */ #define S31 4 #define S32 11 #define S33 16 #define S34 23 HH ( a, b, c, d, in[ 5], S31, 4294588738UL); /* 33 */ HH ( d, a, b, c, in[ 8], S32, 2272392833UL); /* 34 */ HH ( c, d, a, b, in[11], S33, 1839030562UL); /* 35 */ HH ( b, c, d, a, in[14], S34, 4259657740UL); /* 36 */ HH ( a, b, c, d, in[ 1], S31, 2763975236UL); /* 37 */ HH ( d, a, b, c, in[ 4], S32, 1272893353UL); /* 38 */ HH ( c, d, a, b, in[ 7], S33, 4139469664UL); /* 39 */ HH ( b, c, d, a, in[10], S34, 3200236656UL); /* 40 */ HH ( a, b, c, d, in[13], S31, 681279174UL); /* 41 */ HH ( d, a, b, c, in[ 0], S32, 3936430074UL); /* 42 */ HH ( c, d, a, b, in[ 3], S33, 3572445317UL); /* 43 */ HH ( b, c, d, a, in[ 6], S34, 76029189UL); /* 44 */ HH ( a, b, c, d, in[ 9], S31, 3654602809UL); /* 45 */ HH ( d, a, b, c, in[12], S32, 3873151461UL); /* 46 */ HH ( c, d, a, b, in[15], S33, 530742520UL); /* 47 */ HH ( b, c, d, a, in[ 2], S34, 3299628645UL); /* 48 */ /* Round 4 */ #define S41 6 #define S42 10 #define S43 15 #define S44 21 II ( a, b, c, d, in[ 0], S41, 4096336452UL); /* 49 */ II ( d, a, b, c, in[ 7], S42, 1126891415UL); /* 50 */ II ( c, d, a, b, in[14], S43, 2878612391UL); /* 51 */ II ( b, c, d, a, in[ 5], S44, 4237533241UL); /* 52 */ II ( a, b, c, d, in[12], S41, 1700485571UL); /* 53 */ II ( d, a, b, c, in[ 3], S42, 2399980690UL); /* 54 */ II ( c, d, a, b, in[10], S43, 4293915773UL); /* 55 */ II ( b, c, d, a, in[ 1], S44, 2240044497UL); /* 56 */ II ( a, b, c, d, in[ 8], S41, 1873313359UL); /* 57 */ II ( d, a, b, c, in[15], S42, 4264355552UL); /* 58 */ II ( c, d, a, b, in[ 6], S43, 2734768916UL); /* 59 */ II ( b, c, d, a, in[13], S44, 1309151649UL); /* 60 */ II ( a, b, c, d, in[ 4], S41, 4149444226UL); /* 61 */ II ( d, a, b, c, in[11], S42, 3174756917UL); /* 62 */ II ( c, d, a, b, in[ 2], S43, 718787259UL); /* 63 */ II ( b, c, d, a, in[ 9], S44, 3951481745UL); /* 64 */ #endif /* small? */ buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } #endif /* K5_BUILTIN_MD5 */ krb5-1.22.1/src/lib/crypto/builtin/des/0000775000175000017500000000000015051422640017437 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/des/doc/0000775000175000017500000000000015051422640020204 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/des/doc/libdes.doc0000664000175000017500000001670515051422640022146 0ustar ghudsonghudson How to use the Kerberos encryption library. Revised 10/15/85 spm 1) The following include file is needed: /projects/auth/include/des.h (VAX) --------------- (PC8086) 2) The encryption library that should be linked to is: /projects/auth/lib/libdes.a (VAX) | /projects/auth/ibm/lib/libdes.a (PC8086 cross-compilation environment) 3) For each key that may be simultaneously active, allocate (either compile or malloc) a "Key_schedule" struct, defined in "des.h" 4) Create key schedules, as needed, prior to using the encryption routines, via "des_set_key()". 5) Setup the input and output areas. Make sure to note the restrictions on lengths being multiples of eight bytes. 6) Invoke the encryption/decryption routines, "ecb_encrypt()" or "cbc_encrypt()" 7) To generate a cryptographic checksum, use "cbc_cksum()" /* ---------------------------------------------------------------- */ Routine Interfaces-- /* ----------------------------------------------------------------- */ int des_set_key(k,schedule) C_Block *k; Key_schedule schedule; Calculates a key schedule from (all) eight bytes of the input key, and puts it into the indicated "Key_schedule" struct; Make sure to pass valid eight bytes, no padding or other processing it done. The key schedule is then used in subsequent encryption/decryption operations. Many key schedules may be created and cached for later use. The user is responsible to clear keys and schedules no longer needed to prevent their disclosure. | Checks the parity of the key provided, to make sure it is odd per | FIPS spec. Returns 0 value for key ok, 1 for key_parity error. /* ---------------------------------------------------------------- */ int ecb_encrypt(input,output,schedule,encrypt) C_Block *input; /* ptr to eight byte input value */ C_Block *output; /* ptr to eight byte output value */ int encrypt; /* 0 ==> decrypt, else encrypt */ Key_schedule schedule; /* addr of key schedule */ This is the low level routine that encrypts or decrypts a single 8-byte block in electronic code book mode. Always transforms the input data into the output data. If encrypt is non-zero, the input (cleartext) is encrypted into the output (ciphertext) using the specified key_schedule, pre-set via "des_set_key". If encrypt is zero, the input (now ciphertext) is decrypted into the output (now cleartext). Input and output may be the same space. Does not return any meaningful value. Void is not used for compatibility with other compilers. /* -------------------------------------------------------------- */ int cbc_encrypt(input,output,length,schedule,ivec,encrypt) C_Block *input; /* ptr to input data */ C_Block *output; /* ptr to output data */ int length; /* desired length, in bytes */ Key_schedule schedule; /* addr of precomputed schedule */ C_Block *ivec; /* pointer to 8 byte initialization * vector */ int encrypt /* 0 ==> decrypt; else encrypt*/ If encrypt is non-zero, the routine cipher-block-chain encrypts the INPUT (cleartext) into the OUTPUT (ciphertext) using the provided key schedule and initialization vector. If the length is not an integral multiple of eight bytes, the last block is copied to a temp and zero filled (highest addresses). The output is ALWAYS an integral multiple of eight bytes. If encrypt is zero, the routine cipher-block chain decrypts the INPUT (ciphertext) into the OUTPUT (cleartext) using the provided key schedule and initialization vector. Decryption ALWAYS operates on integral multiples of 8 bytes, so will round the length provided up to the appropriate multiple. Consequently, it will always produce the rounded-up number of bytes of output cleartext. The application must determine if the output cleartext was zero-padded due to cleartext lengths not integral multiples of 8. No errors or meaningful value are returned. Void is not used for compatibility with other compilers. /* cbc checksum (MAC) only routine ---------------------------------------- */ int cbc_cksum(input,output,length,schedule,ivec) C_Block *input; /* >= length bytes of inputtext */ C_Block *output; /* >= length bytes of outputtext */ int length; /* in bytes */ Key_schedule schedule; /* precomputed key schedule */ C_Block *ivec; /* 8 bytes of ivec */ Produces a cryptographic checksum, 8 bytes, by cipher-block-chain encrypting the input, discarding the ciphertext output, and only retaining the last ciphertext 8-byte block. Uses the provided key schedule and ivec. The input is effectively zero-padded to an integral multiple of eight bytes, though the original input is not modified. No meaningful value is returned. Void is not used for compatibility with other compilers. /* random_key ----------------------------------------*/ int random_key(key) C_Block *key; The start for the random number generated is set from the current time in microseconds, then the random number generator is invoked to create an eight byte output key (not a schedule). The key generated is set to odd parity per FIPS spec. The caller must supply space for the output key, pointed to by "*key", then after getting a new key, call the des_set_key() routine when needed. No meaningful value is returned. Void is not used for compatibility with other compilers. /* string_to_key --------------------------------------------*/ int string_to_key(str,key) char *str; C_Block *key; This routines converts an arbitrary length, null terminated string to an 8 byte DES key, with each byte parity set to odd, per FIPS spec. The algorithm is as follows: | Take the first 8 bytes and remove the parity (leaving 56 bits). | Do the same for the second 8 bytes, and the third, etc. Do this for | as many sets of 8 bytes as necessary, filling in the remainder of the | last set with nulls. Fold the second set back on the first (i.e. bit | 0 over bit 55, and bit 55 over bit 0). Fold the third over the second | (bit 0 of the third set is now over bit 0 of the first set). Repeat | until you have done this to all sets. Xor the folded sets. Break the | result into 8 7 bit bytes, and generate odd parity for each byte. You | now have 64 bits. Note that DES takes a 64 bit key, and uses only the | non parity bits. /* read_password -------------------------------------------*/ read_password(k,prompt,verify) C_Block *k; char *prompt; int verify; This routine issues the supplied prompt, turns off echo, if possible, and reads an input string. If verify is non-zero, it does it again, for use in applications such as changing a password. If verify is non-zero, both versions are compared, and the input is requested repeatedly until they match. Then, the input string is mapped into a valid DES key, internally using the string_to_key routine. The newly created key is copied to the area pointed to by parameter "k". No meaningful value is returned. If an error occurs trying to manipulate the terminal echo, the routine forces the process to exit. /* get_line ------------------------*/ long get_line(p,max) char *p; long max; Reads input characters from standard input until either a newline appears or else the max length is reached. The characters read are stuffed into the string pointed to, which will always be null terminated. The newline is not inserted in the string. The max parameter includes the byte needed for the null terminator, so allocate and pass one more than the maximum string length desired. krb5-1.22.1/src/lib/crypto/builtin/des/Makefile.in0000664000175000017500000000363615051422640021514 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)builtin$(S)des BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES=-I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLAGS) ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = builtin\des ##DOS##OBJFILE = ..\..\$(OUTPRE)des.lst STLIBOBJS=\ d3_aead.o \ d3_kysched.o \ des_keys.o \ f_aead.o \ f_cksum.o \ f_parity.o \ f_sched.o \ f_tables.o \ key_sched.o \ weak_key.o OBJS= $(OUTPRE)d3_aead.$(OBJEXT) \ $(OUTPRE)d3_kysched.$(OBJEXT) \ $(OUTPRE)des_keys.$(OBJEXT) \ $(OUTPRE)f_aead.$(OBJEXT) \ $(OUTPRE)f_cksum.$(OBJEXT) \ $(OUTPRE)f_parity.$(OBJEXT) \ $(OUTPRE)f_sched.$(OBJEXT) \ $(OUTPRE)f_tables.$(OBJEXT) \ $(OUTPRE)key_sched.$(OBJEXT) \ $(OUTPRE)weak_key.$(OBJEXT) SRCS= $(srcdir)/d3_aead.c \ $(srcdir)/d3_kysched.c \ $(srcdir)/des_keys.c \ $(srcdir)/f_aead.c \ $(srcdir)/f_cksum.c \ $(srcdir)/f_parity.c \ $(srcdir)/f_sched.c \ $(srcdir)/f_tables.c \ $(srcdir)/key_sched.c \ $(srcdir)/weak_key.c EXTRADEPSRCS = $(srcdir)/destest.c $(srcdir)/f_cbc.c $(srcdir)/t_verify.c ##DOS##LIBOBJS = $(OBJS) TOBJS = $(OUTPRE)key_sched.$(OBJEXT) $(OUTPRE)f_sched.$(OBJEXT) \ $(OUTPRE)f_cbc.$(OBJEXT) $(OUTPRE)f_tables.$(OBJEXT) \ $(OUTPRE)f_cksum.$(OBJEXT) verify$(EXEEXT): t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \ $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB) $(CC_LINK) -o $@ t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \ $(COM_ERR_LIB) $(SUPPORT_LIB) destest$(EXEEXT): destest.$(OBJEXT) $(TOBJS) $(SUPPORT_DEPLIB) $(CC_LINK) -o $@ destest.$(OBJEXT) $(TOBJS) $(SUPPORT_LIB) all-unix: all-libobjs check-unix: check-unix-@CRYPTO_BUILTIN_TESTS@ check-unix-no: check-unix-yes: verify destest $(RUN_TEST) ./verify -z $(RUN_TEST) ./verify -m $(RUN_TEST) ./verify $(RUN_TEST) ./destest < $(srcdir)/keytest.data includes: depend depend: $(SRCS) check-windows: clean: $(RM) destest.$(OBJEXT) destest$(EXEEXT) verify$(EXEEXT) \ t_verify.$(OBJEXT) $(TOBJS) clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/des/des_keys.c0000664000175000017500000000305415051422640021413 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/des/des_keys.c - Key functions used by Kerberos code */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #include "des_int.h" #ifdef K5_BUILTIN_DES_KEY_PARITY void k5_des_fixup_key_parity(unsigned char *keybits) { mit_des_fixup_key_parity(keybits); } #endif /* K5_BUILTIN_DES_KEY_PARITY */ krb5-1.22.1/src/lib/crypto/builtin/des/f_tables.h0000664000175000017500000003302515051422640021372 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/des/f_tables.h */ /* * Copyright (C) 1990 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * DES implementation donated by Dennis Ferguson */ /* * des_tables.h - declarations to import the DES tables, used internally * by some of the library routines. */ #ifndef __DES_TABLES_H__ #define __DES_TABLES_H__ /* nothing */ #include "k5-platform.h" /* * These may be declared const if you wish. Be sure to change the * declarations in des_tables.c as well. */ extern const unsigned DES_INT32 des_IP_table[256]; extern const unsigned DES_INT32 des_FP_table[256]; extern const unsigned DES_INT32 des_SP_table[8][64]; /* * Use standard shortforms to reference these to save typing */ #define IP des_IP_table #define FP des_FP_table #define SP des_SP_table #ifdef DEBUG #define DEB(foofraw) printf foofraw #else #define DEB(foofraw) /* nothing */ #endif /* * Code to do a DES round using the tables. Note that the E expansion * is easy to compute algorithmically, especially if done out-of-order. * Take a look at its form and compare it to everything involving temp * below. Since SP[0-7] don't have any bits in common set it is okay * to do the successive xor's. * * Note too that the SP table has been reordered to match the order of * the keys (if the original order of SP was 12345678, the reordered * table is 71354682). This is unnecessary, but was done since some * compilers seem to like you going through the matrix from beginning * to end. * * There is a difference in the best way to do this depending on whether * one is encrypting or decrypting. If encrypting we move forward through * the keys and hence should move forward through the table. If decrypting * we go back. Part of the need for this comes from trying to emulate * existing software which generates a single key schedule and uses it * both for encrypting and decrypting. Generating separate encryption * and decryption key schedules would allow one to use the same code * for both. * * left, right and temp should be unsigned DES_INT32 values. left and right * should be the high and low order parts of the cipher block at the * current stage of processing (this makes sense if you read the spec). * kp should be an unsigned DES_INT32 pointer which points at the current * set of subkeys in the key schedule. It is advanced to the next set * (i.e. by 8 bytes) when this is done. * * This occurs in the innermost loop of the DES function. The four * variables should really be in registers. * * When using this, the inner loop of the DES function might look like: * * for (i = 0; i < 8; i++) { * DES_SP_{EN,DE}CRYPT_ROUND(left, right, temp, kp); * DES_SP_{EN,DE}CRYPT_ROUND(right, left, temp, kp); * } * * Note the trick above. You are supposed to do 16 rounds, swapping * left and right at the end of each round. By doing two rounds at * a time and swapping left and right in the code we can avoid the * swaps altogether. */ #define DES_SP_ENCRYPT_ROUND(left, right, temp, kp) do { \ (temp) = (((right) >> 11) | ((right) << 21)) ^ *(kp)++; \ (left) ^= SP[0][((temp) >> 24) & 0x3f] \ | SP[1][((temp) >> 16) & 0x3f] \ | SP[2][((temp) >> 8) & 0x3f] \ | SP[3][((temp) ) & 0x3f]; \ (temp) = (((right) >> 23) | ((right) << 9)) ^ *(kp)++; \ (left) ^= SP[4][((temp) >> 24) & 0x3f] \ | SP[5][((temp) >> 16) & 0x3f] \ | SP[6][((temp) >> 8) & 0x3f] \ | SP[7][((temp) ) & 0x3f]; \ } while(0); #define DES_SP_DECRYPT_ROUND(left, right, temp, kp) do { \ (temp) = (((right) >> 23) | ((right) << 9)) ^ *(--(kp)); \ (left) ^= SP[7][((temp) ) & 0x3f] \ | SP[6][((temp) >> 8) & 0x3f] \ | SP[5][((temp) >> 16) & 0x3f] \ | SP[4][((temp) >> 24) & 0x3f]; \ (temp) = (((right) >> 11) | ((right) << 21)) ^ *(--(kp)); \ (left) ^= SP[3][((temp) ) & 0x3f] \ | SP[2][((temp) >> 8) & 0x3f] \ | SP[1][((temp) >> 16) & 0x3f] \ | SP[0][((temp) >> 24) & 0x3f]; \ } while (0); /* * Macros to help deal with the initial permutation table. Note * the IP table only deals with 32 bits at a time, allowing us to * collect the bits we need to deal with each half into an unsigned * DES_INT32. By carefully selecting how the bits are ordered we also * take advantages of symmetries in the table so that we can use a * single table to compute the permutation of all bytes. This sounds * complicated, but if you go through the process of designing the * table you'll find the symmetries fall right out. * * The follow macros compute the set of bits used to index the * table for produce the left and right permuted result. * * The inserted cast to unsigned DES_INT32 circumvents a bug in * the Macintosh MPW 3.2 C compiler which loses the unsignedness and * propagates the high-order bit in the shift. */ #define DES_IP_LEFT_BITS(left, right) \ ((((left) & 0x55555555) << 1) | ((right) & 0x55555555)) #define DES_IP_RIGHT_BITS(left, right) \ (((left) & 0xaaaaaaaa) | \ ( ( (unsigned DES_INT32) ((right) & 0xaaaaaaaa) ) >> 1)) /* * The following macro does an in-place initial permutation given * the current left and right parts of the block and a single * temporary. Use this more as a guide for rolling your own, though. * The best way to do the IP depends on the form of the data you * are dealing with. If you use this, though, try to make left, * right and temp unsigned DES_INT32s. */ #define DES_INITIAL_PERM(left, right, temp) do { \ (temp) = DES_IP_RIGHT_BITS((left), (right)); \ (right) = DES_IP_LEFT_BITS((left), (right)); \ (left) = IP[((right) >> 24) & 0xff] \ | (IP[((right) >> 16) & 0xff] << 1) \ | (IP[((right) >> 8) & 0xff] << 2) \ | (IP[(right) & 0xff] << 3); \ (right) = IP[((temp) >> 24) & 0xff] \ | (IP[((temp) >> 16) & 0xff] << 1) \ | (IP[((temp) >> 8) & 0xff] << 2) \ | (IP[(temp) & 0xff] << 3); \ } while(0); /* * Now the final permutation stuff. The same comments apply to * this as to the initial permutation, except that we use different * bits and shifts. * * The inserted cast to unsigned DES_INT32 circumvents a bug in * the Macintosh MPW 3.2 C compiler which loses the unsignedness and * propagates the high-order bit in the shift. */ #define DES_FP_LEFT_BITS(left, right) \ ((((left) & 0x0f0f0f0f) << 4) | ((right) & 0x0f0f0f0f)) #define DES_FP_RIGHT_BITS(left, right) \ (((left) & 0xf0f0f0f0) | \ ( ( (unsigned DES_INT32) ((right) & 0xf0f0f0f0) ) >> 4)) /* * Here is a sample final permutation. Note that there is a trick * here. DES requires swapping the left and right parts after the * last cipher round but before the final permutation. We do this * swapping internally, which is why left and right are confused * at the beginning. */ #define DES_FINAL_PERM(left, right, temp) do { \ (temp) = DES_FP_RIGHT_BITS((right), (left)); \ (right) = DES_FP_LEFT_BITS((right), (left)); \ (left) = (FP[((right) >> 24) & 0xff] << 6) \ | (FP[((right) >> 16) & 0xff] << 4) \ | (FP[((right) >> 8) & 0xff] << 2) \ | FP[(right) & 0xff]; \ (right) = (FP[((temp) >> 24) & 0xff] << 6) \ | (FP[((temp) >> 16) & 0xff] << 4) \ | (FP[((temp) >> 8) & 0xff] << 2) \ | FP[temp & 0xff]; \ } while(0); /* * Finally, as a sample of how all this might be held together, the * following two macros do in-place encryptions and decryptions. left * and right are two unsigned DES_INT32 variables which at the beginning * are expected to hold the clear (encrypted) block in host byte order * (left the high order four bytes, right the low order). At the end * they will contain the encrypted (clear) block. temp is an unsigned DES_INT32 * used as a temporary. kp is an unsigned DES_INT32 pointer pointing at * the start of the key schedule. All these should be in registers. * * You can probably do better than these by rewriting for particular * situations. These aren't bad, though. * * The DEB macros enable debugging when this code breaks (typically * when a buggy compiler breaks it), by printing the intermediate values * at each stage of the encryption, so that by comparing the output to * a known good machine, the location of the first error can be found. */ #define DES_DO_ENCRYPT_1(left, right, kp) \ do { \ int i; \ unsigned DES_INT32 temp1; \ DEB (("do_encrypt %8lX %8lX \n", left, right)); \ DES_INITIAL_PERM((left), (right), (temp1)); \ DEB ((" after IP %8lX %8lX\n", left, right)); \ for (i = 0; i < 8; i++) { \ DES_SP_ENCRYPT_ROUND((left), (right), (temp1), (kp)); \ DEB ((" round %2d %8lX %8lX \n", i*2, left, right)); \ DES_SP_ENCRYPT_ROUND((right), (left), (temp1), (kp)); \ DEB ((" round %2d %8lX %8lX \n", 1+i*2, left, right)); \ } \ DES_FINAL_PERM((left), (right), (temp1)); \ (kp) -= (2 * 16); \ DEB ((" after FP %8lX %8lX \n", left, right)); \ } while (0) #define DES_DO_DECRYPT_1(left, right, kp) \ do { \ int i; \ unsigned DES_INT32 temp2; \ DES_INITIAL_PERM((left), (right), (temp2)); \ (kp) += (2 * 16); \ for (i = 0; i < 8; i++) { \ DES_SP_DECRYPT_ROUND((left), (right), (temp2), (kp)); \ DES_SP_DECRYPT_ROUND((right), (left), (temp2), (kp)); \ } \ DES_FINAL_PERM((left), (right), (temp2)); \ } while (0) #if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO) extern void krb5int_des_do_encrypt_2(unsigned DES_INT32 *l, unsigned DES_INT32 *r, const unsigned DES_INT32 *k); extern void krb5int_des_do_decrypt_2(unsigned DES_INT32 *l, unsigned DES_INT32 *r, const unsigned DES_INT32 *k); #define DES_DO_ENCRYPT(L,R,K) krb5int_des_do_encrypt_2(&(L), &(R), (K)) #define DES_DO_DECRYPT(L,R,K) krb5int_des_do_decrypt_2(&(L), &(R), (K)) #else #define DES_DO_ENCRYPT DES_DO_ENCRYPT_1 #define DES_DO_DECRYPT DES_DO_DECRYPT_1 #endif /* * These are handy dandy utility thingies for straightening out bytes. * Included here because they're used a couple of places. */ #define GET_HALF_BLOCK(lr, ip) ((lr) = load_32_be(ip), (ip) += 4) #define PUT_HALF_BLOCK(lr, op) (store_32_be(lr, op), (op) += 4) /* Shorthand that we'll need in several places, for creating values that really can hold 32 bits regardless of the prevailing int size. */ #define FF_UINT32 ((unsigned DES_INT32) 0xFF) #endif /* __DES_TABLES_H__ */ krb5-1.22.1/src/lib/crypto/builtin/des/destest.c0000664000175000017500000001656115051422640021267 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/des/destest.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* Test a DES implementation against known inputs & outputs. */ #include "des_int.h" #include #include void convert (char *, unsigned char []); void des_cblock_print_file (mit_des_cblock, FILE *); krb5_octet zeroblock[8] = {0,0,0,0,0,0,0,0}; int main(int argc, char *argv[]) { char block1[17], block2[17], block3[17]; /* Force tests of unaligned accesses. */ union { unsigned char c[8*4+3]; long l; } u; unsigned char *ioblocks = u.c; unsigned char *input = ioblocks+1; unsigned char *output = ioblocks+10; unsigned char *output2 = ioblocks+19; unsigned char *key = ioblocks+27; mit_des_key_schedule sched; int num = 0; int retval; int error = 0; while (scanf("%16s %16s %16s", block1, block2, block3) == 3) { convert(block1, key); convert(block2, input); convert(block3, output); retval = mit_des_key_sched(key, sched); if (retval) { fprintf(stderr, "des test: can't process key: %d\n", retval); fprintf(stderr, "des test: %s %s %s\n", block1, block2, block3); exit(1); } mit_des_cbc_encrypt((const mit_des_cblock *) input, (mit_des_cblock *) output2, 8, sched, zeroblock, 1); if (memcmp((char *)output2, (char *)output, 8)) { fprintf(stderr, "DES ENCRYPT ERROR, key %s, text %s, real cipher %s, computed cyphertext %02X%02X%02X%02X%02X%02X%02X%02X\n", block1, block2, block3, output2[0],output2[1],output2[2],output2[3], output2[4],output2[5],output2[6],output2[7]); error++; } /* * Now try decrypting.... */ mit_des_cbc_encrypt((const mit_des_cblock *) output, (mit_des_cblock *) output2, 8, sched, zeroblock, 0); if (memcmp((char *)output2, (char *)input, 8)) { fprintf(stderr, "DES DECRYPT ERROR, key %s, text %s, real cipher %s, computed cleartext %02X%02X%02X%02X%02X%02X%02X%02X\n", block1, block2, block3, output2[0],output2[1],output2[2],output2[3], output2[4],output2[5],output2[6],output2[7]); error++; } num++; } if (error) printf("destest: failed to pass the test\n"); else printf("destest: %d tests passed successfully\n", num); exit( (error > 256 && error % 256) ? 1 : error); } int value[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; void convert(char *text, unsigned char cblock[]) { int i; for (i = 0; i < 8; i++) { if (!isascii((unsigned char)text[i * 2])) abort (); if (value[(int) text[i*2]] == -1 || value[(int) text[i*2+1]] == -1) { printf("Bad value byte %d in %s\n", i, text); exit(1); } cblock[i] = 16*value[(int) text[i*2]] + value[(int) text[i*2+1]]; } return; } /* * Fake out the DES library, for the purposes of testing. */ int mit_des_is_weak_key(mit_des_cblock key) { return 0; /* fake it out for testing */ } void des_cblock_print_file(mit_des_cblock x, FILE *fp) { unsigned char *y = (unsigned char *) x; int i = 0; fprintf(fp," 0x { "); while (i++ < 8) { fprintf(fp,"%x",*y++); if (i < 8) fprintf(fp,", "); } fprintf(fp," }"); } #define smask(step) ((1<>step)&smask(step))) #define parity_char(x) pstep(pstep(pstep((x),4),2),1) /* * des_check_key_parity: returns true iff key has the correct des parity. * See des_fix_key_parity for the definition of * correct des parity. */ int mit_des_check_key_parity(mit_des_cblock key) { unsigned int i; for (i=0; i #include #if TARGET_RT_MAC_CFM #error "Use KfM 4.0 SDK headers for CFM compilation." #endif #if defined(DEPRECATED_IN_MAC_OS_X_VERSION_10_5) && !defined(KRB5_SUPRESS_DEPRECATED_WARNINGS) #define KRB5INT_DES_DEPRECATED DEPRECATED_IN_MAC_OS_X_VERSION_10_5 #endif #endif /* defined(__MACH__) && defined(__APPLE__) */ /* Macro to add deprecated attribute to DES types and functions */ /* Currently only defined on macOS 10.5 and later. */ #ifndef KRB5INT_DES_DEPRECATED #define KRB5INT_DES_DEPRECATED #endif #include #if UINT_MAX >= 0xFFFFFFFFUL #define DES_INT32 int #define DES_UINT32 unsigned int #else #define DES_INT32 long #define DES_UINT32 unsigned long #endif typedef unsigned char des_cblock[8] /* crypto-block size */ KRB5INT_DES_DEPRECATED; /* * Key schedule. * * This used to be * * typedef struct des_ks_struct { * union { DES_INT32 pad; des_cblock _;} __; * } des_key_schedule[16]; * * but it would cause trouble if DES_INT32 were ever more than 4 * bytes. The reason is that all the encryption functions cast it to * (DES_INT32 *), and treat it as if it were DES_INT32[32]. If * 2*sizeof(DES_INT32) is ever more than sizeof(des_cblock), the * caller-allocated des_key_schedule will be overflowed by the key * scheduling functions. We can't assume that every platform will * have an exact 32-bit int, and nothing should be looking inside a * des_key_schedule anyway. */ typedef struct des_ks_struct { DES_INT32 _[2]; } des_key_schedule[16] KRB5INT_DES_DEPRECATED; typedef des_cblock mit_des_cblock; typedef des_key_schedule mit_des_key_schedule; /* Triple-DES structures */ typedef mit_des_cblock mit_des3_cblock[3]; typedef mit_des_key_schedule mit_des3_key_schedule[3]; #define MIT_DES_ENCRYPT 1 #define MIT_DES_DECRYPT 0 typedef struct mit_des_ran_key_seed { krb5_encrypt_block eblock; krb5_data sequence; } mit_des_random_state; /* the first byte of the key is already in the keyblock */ #define MIT_DES_BLOCK_LENGTH (8*sizeof(krb5_octet)) /* This used to be 8*sizeof(krb5_octet) */ #define MIT_DES_KEYSIZE 8 #define MIT_DES_CBC_CKSUM_LENGTH (4*sizeof(krb5_octet)) #endif /* KRB5_MIT_DES__ */ /* * End "mit-des.h" */ /* afsstring2key.c */ krb5_error_code mit_afs_string_to_key(krb5_keyblock *keyblock, const krb5_data *data, const krb5_data *salt); char *mit_afs_crypt(const char *pw, const char *salt, char *iobuf); /* f_cksum.c */ unsigned long mit_des_cbc_cksum(const krb5_octet *, krb5_octet *, unsigned long, const mit_des_key_schedule, const krb5_octet *); /* f_cbc.c (used by test programs) */ int mit_des_cbc_encrypt(const mit_des_cblock *in, mit_des_cblock *out, unsigned long length, const mit_des_key_schedule schedule, const mit_des_cblock ivec, int enc); #define mit_des_zeroblock krb5int_c_mit_des_zeroblock extern const mit_des_cblock mit_des_zeroblock; /* fin_rndkey.c */ krb5_error_code mit_des_finish_random_key(const krb5_encrypt_block *, krb5_pointer *); /* finish_key.c */ krb5_error_code mit_des_finish_key(krb5_encrypt_block *); /* init_rkey.c */ krb5_error_code mit_des_init_random_key(const krb5_encrypt_block *, const krb5_keyblock *, krb5_pointer *); /* key_parity.c */ void mit_des_fixup_key_parity(mit_des_cblock); int mit_des_check_key_parity(mit_des_cblock); /* key_sched.c */ int mit_des_key_sched(mit_des_cblock, mit_des_key_schedule); /* process_ky.c */ krb5_error_code mit_des_process_key(krb5_encrypt_block *, const krb5_keyblock *); /* random_key.c */ krb5_error_code mit_des_random_key(const krb5_encrypt_block *, krb5_pointer, krb5_keyblock **); /* string2key.c */ krb5_error_code mit_des_string_to_key(const krb5_encrypt_block *, krb5_keyblock *, const krb5_data *, const krb5_data *); krb5_error_code mit_des_string_to_key_int(krb5_keyblock *, const krb5_data *, const krb5_data *); /* weak_key.c */ int mit_des_is_weak_key(mit_des_cblock); /* cmb_keys.c */ krb5_error_code mit_des_combine_subkeys(const krb5_keyblock *, const krb5_keyblock *, krb5_keyblock **); /* f_sched.c */ int mit_des_make_key_sched(mit_des_cblock, mit_des_key_schedule); /* misc.c */ extern void swap_bits(char *); extern unsigned long long_swap_bits(unsigned long); extern unsigned long swap_six_bits_to_ansi(unsigned long); extern unsigned long swap_four_bits_to_ansi(unsigned long); extern unsigned long swap_bit_pos_1(unsigned long); extern unsigned long swap_bit_pos_0(unsigned long); extern unsigned long swap_bit_pos_0_to_ansi(unsigned long); extern unsigned long rev_swap_bit_pos_0(unsigned long); extern unsigned long swap_byte_bits(unsigned long); extern unsigned long swap_long_bytes_bit_number(unsigned long); #ifdef FILE /* XXX depends on FILE being a #define! */ extern void test_set(FILE *, const char *, int, const char *, int); #endif void krb5int_des3_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule ks1, const mit_des_key_schedule ks2, const mit_des_key_schedule ks3, mit_des_cblock ivec); void krb5int_des3_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule ks1, const mit_des_key_schedule ks2, const mit_des_key_schedule ks3, mit_des_cblock ivec); void krb5int_des_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule schedule, mit_des_cblock ivec); void krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule schedule, mit_des_cblock ivec); void krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule schedule, mit_des_cblock ivec, mit_des_cblock out); /* d3_procky.c */ krb5_error_code mit_des3_process_key(krb5_encrypt_block *eblock, const krb5_keyblock *keyblock); /* d3_kysched.c */ int mit_des3_key_sched(mit_des3_cblock key, mit_des3_key_schedule schedule); /* d3_str2ky.c */ krb5_error_code mit_des3_string_to_key(const krb5_encrypt_block *eblock, krb5_keyblock *keyblock, const krb5_data *data, const krb5_data *salt); /* u_nfold.c */ krb5_error_code mit_des_n_fold(const krb5_octet *input, const size_t in_len, krb5_octet *output, const size_t out_len); /* u_rn_key.c */ int mit_des_is_weak_keyblock(krb5_keyblock *keyblock); void mit_des_fixup_keyblock_parity(krb5_keyblock *keyblock); krb5_error_code mit_des_set_random_generator_seed(const krb5_data *seed, krb5_pointer random_state); krb5_error_code mit_des_set_random_sequence_number(const krb5_data *sequence, krb5_pointer random_state); #endif /*DES_INTERNAL_DEFS*/ krb5-1.22.1/src/lib/crypto/builtin/des/f_parity.c0000664000175000017500000000267215051422640021427 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * These routines check and fix parity of encryption keys for the DES * algorithm. * * They are a replacement for routines in key_parity.c, that don't require * the table building that they do. * * Mark Eichin -- Cygnus Support */ #include "crypto_int.h" #include "des_int.h" #ifdef K5_BUILTIN_DES_KEY_PARITY /* * des_fixup_key_parity: Forces odd parity per byte; parity is bits * 8,16,...64 in des order, implies 0, 8, 16, ... * vax order. */ #define smask(step) ((1<>step)&smask(step))) #define parity_char(x) pstep(pstep(pstep((x),4),2),1) void mit_des_fixup_key_parity(mit_des_cblock key) { unsigned int i; for (i=0; i> 1) for right half * * The scheme is that we index into the table using each byte. The * result from the high order byte is or'd with the result from the * next byte shifted left once is or'd with the result from the next * byte shifted left twice if or'd with the result from the low order * byte shifted left by three. Clear? */ const unsigned DES_INT32 des_IP_table[256] = { 0x00000000, 0x00000010, 0x00000001, 0x00000011, 0x00001000, 0x00001010, 0x00001001, 0x00001011, 0x00000100, 0x00000110, 0x00000101, 0x00000111, 0x00001100, 0x00001110, 0x00001101, 0x00001111, 0x00100000, 0x00100010, 0x00100001, 0x00100011, 0x00101000, 0x00101010, 0x00101001, 0x00101011, 0x00100100, 0x00100110, 0x00100101, 0x00100111, 0x00101100, 0x00101110, 0x00101101, 0x00101111, 0x00010000, 0x00010010, 0x00010001, 0x00010011, 0x00011000, 0x00011010, 0x00011001, 0x00011011, 0x00010100, 0x00010110, 0x00010101, 0x00010111, 0x00011100, 0x00011110, 0x00011101, 0x00011111, 0x00110000, 0x00110010, 0x00110001, 0x00110011, 0x00111000, 0x00111010, 0x00111001, 0x00111011, 0x00110100, 0x00110110, 0x00110101, 0x00110111, 0x00111100, 0x00111110, 0x00111101, 0x00111111, 0x10000000, 0x10000010, 0x10000001, 0x10000011, 0x10001000, 0x10001010, 0x10001001, 0x10001011, 0x10000100, 0x10000110, 0x10000101, 0x10000111, 0x10001100, 0x10001110, 0x10001101, 0x10001111, 0x10100000, 0x10100010, 0x10100001, 0x10100011, 0x10101000, 0x10101010, 0x10101001, 0x10101011, 0x10100100, 0x10100110, 0x10100101, 0x10100111, 0x10101100, 0x10101110, 0x10101101, 0x10101111, 0x10010000, 0x10010010, 0x10010001, 0x10010011, 0x10011000, 0x10011010, 0x10011001, 0x10011011, 0x10010100, 0x10010110, 0x10010101, 0x10010111, 0x10011100, 0x10011110, 0x10011101, 0x10011111, 0x10110000, 0x10110010, 0x10110001, 0x10110011, 0x10111000, 0x10111010, 0x10111001, 0x10111011, 0x10110100, 0x10110110, 0x10110101, 0x10110111, 0x10111100, 0x10111110, 0x10111101, 0x10111111, 0x01000000, 0x01000010, 0x01000001, 0x01000011, 0x01001000, 0x01001010, 0x01001001, 0x01001011, 0x01000100, 0x01000110, 0x01000101, 0x01000111, 0x01001100, 0x01001110, 0x01001101, 0x01001111, 0x01100000, 0x01100010, 0x01100001, 0x01100011, 0x01101000, 0x01101010, 0x01101001, 0x01101011, 0x01100100, 0x01100110, 0x01100101, 0x01100111, 0x01101100, 0x01101110, 0x01101101, 0x01101111, 0x01010000, 0x01010010, 0x01010001, 0x01010011, 0x01011000, 0x01011010, 0x01011001, 0x01011011, 0x01010100, 0x01010110, 0x01010101, 0x01010111, 0x01011100, 0x01011110, 0x01011101, 0x01011111, 0x01110000, 0x01110010, 0x01110001, 0x01110011, 0x01111000, 0x01111010, 0x01111001, 0x01111011, 0x01110100, 0x01110110, 0x01110101, 0x01110111, 0x01111100, 0x01111110, 0x01111101, 0x01111111, 0x11000000, 0x11000010, 0x11000001, 0x11000011, 0x11001000, 0x11001010, 0x11001001, 0x11001011, 0x11000100, 0x11000110, 0x11000101, 0x11000111, 0x11001100, 0x11001110, 0x11001101, 0x11001111, 0x11100000, 0x11100010, 0x11100001, 0x11100011, 0x11101000, 0x11101010, 0x11101001, 0x11101011, 0x11100100, 0x11100110, 0x11100101, 0x11100111, 0x11101100, 0x11101110, 0x11101101, 0x11101111, 0x11010000, 0x11010010, 0x11010001, 0x11010011, 0x11011000, 0x11011010, 0x11011001, 0x11011011, 0x11010100, 0x11010110, 0x11010101, 0x11010111, 0x11011100, 0x11011110, 0x11011101, 0x11011111, 0x11110000, 0x11110010, 0x11110001, 0x11110011, 0x11111000, 0x11111010, 0x11111001, 0x11111011, 0x11110100, 0x11110110, 0x11110101, 0x11110111, 0x11111100, 0x11111110, 0x11111101, 0x11111111 }; /* * The final permutation array. Like the IP array, used * to compute both the left and right results from the bytes * of words computed from: * * ((left & 0x0f0f0f0f) << 4) | (right & 0x0f0f0f0f) for left result * (left & 0xf0f0f0f0) | ((right & 0xf0f0f0f0) >> 4) for right result * * The result from the high order byte is shifted left 6 bits and * or'd with the result from the next byte shifted left 4 bits, which * is or'd with the result from the next byte shifted left 2 bits, * which is or'd with the result from the low byte. */ const unsigned DES_INT32 des_FP_table[256] = { 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202, 0x01000000, 0x03000000, 0x01020000, 0x03020000, 0x01000200, 0x03000200, 0x01020200, 0x03020200, 0x01000002, 0x03000002, 0x01020002, 0x03020002, 0x01000202, 0x03000202, 0x01020202, 0x03020202, 0x00010000, 0x02010000, 0x00030000, 0x02030000, 0x00010200, 0x02010200, 0x00030200, 0x02030200, 0x00010002, 0x02010002, 0x00030002, 0x02030002, 0x00010202, 0x02010202, 0x00030202, 0x02030202, 0x01010000, 0x03010000, 0x01030000, 0x03030000, 0x01010200, 0x03010200, 0x01030200, 0x03030200, 0x01010002, 0x03010002, 0x01030002, 0x03030002, 0x01010202, 0x03010202, 0x01030202, 0x03030202, 0x00000100, 0x02000100, 0x00020100, 0x02020100, 0x00000300, 0x02000300, 0x00020300, 0x02020300, 0x00000102, 0x02000102, 0x00020102, 0x02020102, 0x00000302, 0x02000302, 0x00020302, 0x02020302, 0x01000100, 0x03000100, 0x01020100, 0x03020100, 0x01000300, 0x03000300, 0x01020300, 0x03020300, 0x01000102, 0x03000102, 0x01020102, 0x03020102, 0x01000302, 0x03000302, 0x01020302, 0x03020302, 0x00010100, 0x02010100, 0x00030100, 0x02030100, 0x00010300, 0x02010300, 0x00030300, 0x02030300, 0x00010102, 0x02010102, 0x00030102, 0x02030102, 0x00010302, 0x02010302, 0x00030302, 0x02030302, 0x01010100, 0x03010100, 0x01030100, 0x03030100, 0x01010300, 0x03010300, 0x01030300, 0x03030300, 0x01010102, 0x03010102, 0x01030102, 0x03030102, 0x01010302, 0x03010302, 0x01030302, 0x03030302, 0x00000001, 0x02000001, 0x00020001, 0x02020001, 0x00000201, 0x02000201, 0x00020201, 0x02020201, 0x00000003, 0x02000003, 0x00020003, 0x02020003, 0x00000203, 0x02000203, 0x00020203, 0x02020203, 0x01000001, 0x03000001, 0x01020001, 0x03020001, 0x01000201, 0x03000201, 0x01020201, 0x03020201, 0x01000003, 0x03000003, 0x01020003, 0x03020003, 0x01000203, 0x03000203, 0x01020203, 0x03020203, 0x00010001, 0x02010001, 0x00030001, 0x02030001, 0x00010201, 0x02010201, 0x00030201, 0x02030201, 0x00010003, 0x02010003, 0x00030003, 0x02030003, 0x00010203, 0x02010203, 0x00030203, 0x02030203, 0x01010001, 0x03010001, 0x01030001, 0x03030001, 0x01010201, 0x03010201, 0x01030201, 0x03030201, 0x01010003, 0x03010003, 0x01030003, 0x03030003, 0x01010203, 0x03010203, 0x01030203, 0x03030203, 0x00000101, 0x02000101, 0x00020101, 0x02020101, 0x00000301, 0x02000301, 0x00020301, 0x02020301, 0x00000103, 0x02000103, 0x00020103, 0x02020103, 0x00000303, 0x02000303, 0x00020303, 0x02020303, 0x01000101, 0x03000101, 0x01020101, 0x03020101, 0x01000301, 0x03000301, 0x01020301, 0x03020301, 0x01000103, 0x03000103, 0x01020103, 0x03020103, 0x01000303, 0x03000303, 0x01020303, 0x03020303, 0x00010101, 0x02010101, 0x00030101, 0x02030101, 0x00010301, 0x02010301, 0x00030301, 0x02030301, 0x00010103, 0x02010103, 0x00030103, 0x02030103, 0x00010303, 0x02010303, 0x00030303, 0x02030303, 0x01010101, 0x03010101, 0x01030101, 0x03030101, 0x01010301, 0x03010301, 0x01030301, 0x03030301, 0x01010103, 0x03010103, 0x01030103, 0x03030103, 0x01010303, 0x03010303, 0x01030303, 0x03030303 }; /* * The SP table is actually the S boxes and the P permutation * table combined. This table is actually reordered from the * spec, to match the order of key application we follow. */ const unsigned DES_INT32 des_SP_table[8][64] = { { 0x00100000, 0x02100001, 0x02000401, 0x00000000, /* 7 */ 0x00000400, 0x02000401, 0x00100401, 0x02100400, 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401, 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001, 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400, 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001, 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400, 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401, 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001, }, { 0x00808200, 0x00000000, 0x00008000, 0x00808202, /* 1 */ 0x00808002, 0x00008202, 0x00000002, 0x00008000, 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002, 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202, 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000, 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200, 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202, 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200, 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002, }, { 0x00000104, 0x04010100, 0x00000000, 0x04010004, /* 3 */ 0x04000100, 0x00000000, 0x00010104, 0x04000100, 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104, 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104, 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000, 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000, 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004, 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004, 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100, }, { 0x00000080, 0x01040080, 0x01040000, 0x21000080, /* 5 */ 0x00040000, 0x00000080, 0x20000000, 0x01040000, 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000, 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080, 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080, 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080, 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000, 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000, 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080, }, { 0x80401000, 0x80001040, 0x80001040, 0x00000040, /* 4 */ 0x00401040, 0x80400040, 0x80400000, 0x80001000, 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000, 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040, 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040, 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000, 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040, 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040, }, { 0x10000008, 0x10200000, 0x00002000, 0x10202008, /* 6 */ 0x10200000, 0x00000008, 0x10202008, 0x00200000, 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008, 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008, 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000, 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008, 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000, 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008, 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008, }, { 0x08000820, 0x00000800, 0x00020000, 0x08020820, /* 8 */ 0x08000000, 0x08000820, 0x00000020, 0x08000000, 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020, 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800, 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000, 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820, 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820, 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000, 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800, }, { 0x40084010, 0x40004000, 0x00004000, 0x00084010, /* 2 */ 0x00080000, 0x00000010, 0x40080010, 0x40004010, 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010, 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000, 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010, 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000, 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000, 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010, 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000 }, }; #endif /* K5_BUILTIN_DES */ krb5-1.22.1/src/lib/crypto/builtin/des/keytest.data0000664000175000017500000002102115051422640021756 0ustar ghudsonghudson0101010101010101 95F8A5E5DD31D900 8000000000000000 0101010101010101 DD7F121CA5015619 4000000000000000 0101010101010101 2E8653104F3834EA 2000000000000000 0101010101010101 4BD388FF6CD81D4F 1000000000000000 0101010101010101 20B9E767B2FB1456 0800000000000000 0101010101010101 55579380D77138EF 0400000000000000 0101010101010101 6CC5DEFAAF04512F 0200000000000000 0101010101010101 0D9F279BA5D87260 0100000000000000 0101010101010101 D9031B0271BD5A0A 0080000000000000 0101010101010101 424250B37C3DD951 0040000000000000 0101010101010101 B8061B7ECD9A21E5 0020000000000000 0101010101010101 F15D0F286B65BD28 0010000000000000 0101010101010101 ADD0CC8D6E5DEBA1 0008000000000000 0101010101010101 E6D5F82752AD63D1 0004000000000000 0101010101010101 ECBFE3BD3F591A5E 0002000000000000 0101010101010101 F356834379D165CD 0001000000000000 0101010101010101 2B9F982F20037FA9 0000800000000000 0101010101010101 889DE068A16F0BE6 0000400000000000 0101010101010101 E19E275D846A1298 0000200000000000 0101010101010101 329A8ED523D71AEC 0000100000000000 0101010101010101 E7FCE22557D23C97 0000080000000000 0101010101010101 12A9F5817FF2D65D 0000040000000000 0101010101010101 A484C3AD38DC9C19 0000020000000000 0101010101010101 FBE00A8A1EF8AD72 0000010000000000 0101010101010101 750D079407521363 0000008000000000 0101010101010101 64FEED9C724C2FAF 0000004000000000 0101010101010101 F02B263B328E2B60 0000002000000000 0101010101010101 9D64555A9A10B852 0000001000000000 0101010101010101 D106FF0BED5255D7 0000000800000000 0101010101010101 E1652C6B138C64A5 0000000400000000 0101010101010101 E428581186EC8F46 0000000200000000 0101010101010101 AEB5F5EDE22D1A36 0000000100000000 0101010101010101 E943D7568AEC0C5C 0000000080000000 0101010101010101 DF98C8276F54B04B 0000000040000000 0101010101010101 B160E4680F6C696F 0000000020000000 0101010101010101 FA0752B07D9C4AB8 0000000010000000 0101010101010101 CA3A2B036DBC8502 0000000008000000 0101010101010101 5E0905517BB59BCF 0000000004000000 0101010101010101 814EEB3B91D90726 0000000002000000 0101010101010101 4D49DB1532919C9F 0000000001000000 0101010101010101 25EB5FC3F8CF0621 0000000000800000 0101010101010101 AB6A20C0620D1C6F 0000000000400000 0101010101010101 79E90DBC98F92CCA 0000000000200000 0101010101010101 866ECEDD8072BB0E 0000000000100000 0101010101010101 8B54536F2F3E64A8 0000000000080000 0101010101010101 EA51D3975595B86B 0000000000040000 0101010101010101 CAFFC6AC4542DE31 0000000000020000 0101010101010101 8DD45A2DDF90796C 0000000000010000 0101010101010101 1029D55E880EC2D0 0000000000008000 0101010101010101 5D86CB23639DBEA9 0000000000004000 0101010101010101 1D1CA853AE7C0C5F 0000000000002000 0101010101010101 CE332329248F3228 0000000000001000 0101010101010101 8405D1ABE24FB942 0000000000000800 0101010101010101 E643D78090CA4207 0000000000000400 0101010101010101 48221B9937748A23 0000000000000200 0101010101010101 DD7C0BBD61FAFD54 0000000000000100 0101010101010101 2FBC291A570DB5C4 0000000000000080 0101010101010101 E07C30D7E4E26E12 0000000000000040 0101010101010101 0953E2258E8E90A1 0000000000000020 0101010101010101 5B711BC4CEEBF2EE 0000000000000010 0101010101010101 CC083F1E6D9E85F6 0000000000000008 0101010101010101 D2FD8867D50D2DFE 0000000000000004 0101010101010101 06E7EA22CE92708F 0000000000000002 0101010101010101 166B40B44ABA4BD6 0000000000000001 8001010101010101 0000000000000000 95A8D72813DAA94D 4001010101010101 0000000000000000 0EEC1487DD8C26D5 2001010101010101 0000000000000000 7AD16FFB79C45926 1001010101010101 0000000000000000 D3746294CA6A6CF3 0801010101010101 0000000000000000 809F5F873C1FD761 0401010101010101 0000000000000000 C02FAFFEC989D1FC 0201010101010101 0000000000000000 4615AA1D33E72F10 0180010101010101 0000000000000000 2055123350C00858 0140010101010101 0000000000000000 DF3B99D6577397C8 0120010101010101 0000000000000000 31FE17369B5288C9 0110010101010101 0000000000000000 DFDD3CC64DAE1642 0108010101010101 0000000000000000 178C83CE2B399D94 0104010101010101 0000000000000000 50F636324A9B7F80 0102010101010101 0000000000000000 A8468EE3BC18F06D 0101800101010101 0000000000000000 A2DC9E92FD3CDE92 0101400101010101 0000000000000000 CAC09F797D031287 0101200101010101 0000000000000000 90BA680B22AEB525 0101100101010101 0000000000000000 CE7A24F350E280B6 0101080101010101 0000000000000000 882BFF0AA01A0B87 0101040101010101 0000000000000000 25610288924511C2 0101020101010101 0000000000000000 C71516C29C75D170 0101018001010101 0000000000000000 5199C29A52C9F059 0101014001010101 0000000000000000 C22F0A294A71F29F 0101012001010101 0000000000000000 EE371483714C02EA 0101011001010101 0000000000000000 A81FBD448F9E522F 0101010801010101 0000000000000000 4F644C92E192DFED 0101010401010101 0000000000000000 1AFA9A66A6DF92AE 0101010201010101 0000000000000000 B3C1CC715CB879D8 0101010180010101 0000000000000000 19D032E64AB0BD8B 0101010140010101 0000000000000000 3CFAA7A7DC8720DC 0101010120010101 0000000000000000 B7265F7F447AC6F3 0101010110010101 0000000000000000 9DB73B3C0D163F54 0101010108010101 0000000000000000 8181B65BABF4A975 0101010104010101 0000000000000000 93C9B64042EAA240 0101010102010101 0000000000000000 5570530829705592 0101010101800101 0000000000000000 8638809E878787A0 0101010101400101 0000000000000000 41B9A79AF79AC208 0101010101200101 0000000000000000 7A9BE42F2009A892 0101010101100101 0000000000000000 29038D56BA6D2745 0101010101080101 0000000000000000 5495C6ABF1E5DF51 0101010101040101 0000000000000000 AE13DBD561488933 0101010101020101 0000000000000000 024D1FFA8904E389 0101010101018001 0000000000000000 D1399712F99BF02E 0101010101014001 0000000000000000 14C1D7C1CFFEC79E 0101010101012001 0000000000000000 1DE5279DAE3BED6F 0101010101011001 0000000000000000 E941A33F85501303 0101010101010801 0000000000000000 DA99DBBC9A03F379 0101010101010401 0000000000000000 B7FC92F91D8E92E9 0101010101010201 0000000000000000 AE8E5CAA3CA04E85 0101010101010180 0000000000000000 9CC62DF43B6EED74 0101010101010140 0000000000000000 D863DBB5C59A91A0 0101010101010120 0000000000000000 A1AB2190545B91D7 0101010101010110 0000000000000000 0875041E64C570F7 0101010101010108 0000000000000000 5A594528BEBEF1CC 0101010101010104 0000000000000000 FCDB3291DE21F0C0 0101010101010102 0000000000000000 869EFD7F9F265A09 1046913489980131 0000000000000000 88D55E54F54C97B4 1007103489988020 0000000000000000 0C0CC00C83EA48FD 10071034C8980120 0000000000000000 83BC8EF3A6570183 1046103489988020 0000000000000000 DF725DCAD94EA2E9 1086911519190101 0000000000000000 E652B53B550BE8B0 1086911519580101 0000000000000000 AF527120C485CBB0 5107B01519580101 0000000000000000 0F04CE393DB926D5 1007B01519190101 0000000000000000 C9F00FFC74079067 3107915498080101 0000000000000000 7CFD82A593252B4E 3107919498080101 0000000000000000 CB49A2F9E91363E3 10079115B9080140 0000000000000000 00B588BE70D23F56 3107911598080140 0000000000000000 406A9A6AB43399AE 1007D01589980101 0000000000000000 6CB773611DCA9ADA 9107911589980101 0000000000000000 67FD21C17DBB5D70 9107D01589190101 0000000000000000 9592CB4110430787 1007D01598980120 0000000000000000 A6B7FF68A318DDD3 1007940498190101 0000000000000000 4D102196C914CA16 0107910491190401 0000000000000000 2DFA9F4573594965 0107910491190101 0000000000000000 B46604816C0E0774 0107940491190401 0000000000000000 6E7E6221A4F34E87 19079210981A0101 0000000000000000 AA85E74643233199 1007911998190801 0000000000000000 2E5A19DB4D1962D6 10079119981A0801 0000000000000000 23A866A809D30894 1007921098190101 0000000000000000 D812D961F017D320 100791159819010B 0000000000000000 055605816E58608F 1004801598190101 0000000000000000 ABD88E8B1B7716F1 1004801598190102 0000000000000000 537AC95BE69DA1E1 1004801598190108 0000000000000000 AED0F6AE3C25CDD8 1002911598100104 0000000000000000 B3E35A5EE53E7B8D 1002911598190104 0000000000000000 61C79C71921A2EF8 1002911598100201 0000000000000000 E2F5728F0995013C 1002911698100101 0000000000000000 1AEAC39A61F0A464 7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B 0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271 07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A 3849674C2602319E 51454B582DDF440A 7178876E01F19B2A 04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095 0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B 0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09 43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A 07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F 04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088 37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77 1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A 584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56 025816164629B007 480D39006EE762F2 A1F9915541020B56 49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556 4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC 49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A 018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41 1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793 krb5-1.22.1/src/lib/crypto/builtin/des/f_sched.c0000664000175000017500000003606315051422640021206 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/des/f_sched.c */ /* * Copyright (C) 1990 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* DES implementation donated by Dennis Ferguson */ /* * des_make_sched.c - permute a DES key, returning the resulting key schedule */ #include "crypto_int.h" #include "des_int.h" #ifdef K5_BUILTIN_DES /* * Permuted choice 1 tables. These are used to extract bits * from the left and right parts of the key to form Ci and Di. * The code that uses these tables knows which bits from which * part of each key are used to form Ci and Di. */ static const unsigned DES_INT32 PC1_CL[8] = { 0x00000000, 0x00000010, 0x00001000, 0x00001010, 0x00100000, 0x00100010, 0x00101000, 0x00101010 }; static const unsigned DES_INT32 PC1_DL[16] = { 0x00000000, 0x00100000, 0x00001000, 0x00101000, 0x00000010, 0x00100010, 0x00001010, 0x00101010, 0x00000001, 0x00100001, 0x00001001, 0x00101001, 0x00000011, 0x00100011, 0x00001011, 0x00101011 }; static const unsigned DES_INT32 PC1_CR[16] = { 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00010000, 0x00010001, 0x00010100, 0x00010101, 0x01000000, 0x01000001, 0x01000100, 0x01000101, 0x01010000, 0x01010001, 0x01010100, 0x01010101 }; static const unsigned DES_INT32 PC1_DR[8] = { 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100 }; /* * At the start of some iterations of the key schedule we do * a circular left shift by one place, while for others we do a shift by * two places. This has bits set for the iterations where we do 2 bit * shifts, starting at the low order bit. */ #define TWO_BIT_SHIFTS 0x7efc /* * Permuted choice 2 tables. The first actually produces the low order * 24 bits of the subkey Ki from the 28 bit value of Ci. The second produces * the high order 24 bits from Di. The tables are indexed by six bit * segments of Ci and Di respectively. The code is handcrafted to compute * the appropriate 6 bit chunks. * * Note that for ease of computation, the 24 bit values are produced with * six bits going into each byte. Note also that the table has been byte * rearranged to produce keys which match the order we will apply them * in in the des code. */ static const unsigned DES_INT32 PC2_C[4][64] = { { 0x00000000, 0x00000004, 0x00010000, 0x00010004, 0x00000400, 0x00000404, 0x00010400, 0x00010404, 0x00000020, 0x00000024, 0x00010020, 0x00010024, 0x00000420, 0x00000424, 0x00010420, 0x00010424, 0x01000000, 0x01000004, 0x01010000, 0x01010004, 0x01000400, 0x01000404, 0x01010400, 0x01010404, 0x01000020, 0x01000024, 0x01010020, 0x01010024, 0x01000420, 0x01000424, 0x01010420, 0x01010424, 0x00020000, 0x00020004, 0x00030000, 0x00030004, 0x00020400, 0x00020404, 0x00030400, 0x00030404, 0x00020020, 0x00020024, 0x00030020, 0x00030024, 0x00020420, 0x00020424, 0x00030420, 0x00030424, 0x01020000, 0x01020004, 0x01030000, 0x01030004, 0x01020400, 0x01020404, 0x01030400, 0x01030404, 0x01020020, 0x01020024, 0x01030020, 0x01030024, 0x01020420, 0x01020424, 0x01030420, 0x01030424, }, { 0x00000000, 0x02000000, 0x00000800, 0x02000800, 0x00080000, 0x02080000, 0x00080800, 0x02080800, 0x00000001, 0x02000001, 0x00000801, 0x02000801, 0x00080001, 0x02080001, 0x00080801, 0x02080801, 0x00000100, 0x02000100, 0x00000900, 0x02000900, 0x00080100, 0x02080100, 0x00080900, 0x02080900, 0x00000101, 0x02000101, 0x00000901, 0x02000901, 0x00080101, 0x02080101, 0x00080901, 0x02080901, 0x10000000, 0x12000000, 0x10000800, 0x12000800, 0x10080000, 0x12080000, 0x10080800, 0x12080800, 0x10000001, 0x12000001, 0x10000801, 0x12000801, 0x10080001, 0x12080001, 0x10080801, 0x12080801, 0x10000100, 0x12000100, 0x10000900, 0x12000900, 0x10080100, 0x12080100, 0x10080900, 0x12080900, 0x10000101, 0x12000101, 0x10000901, 0x12000901, 0x10080101, 0x12080101, 0x10080901, 0x12080901, }, { 0x00000000, 0x00040000, 0x00002000, 0x00042000, 0x00100000, 0x00140000, 0x00102000, 0x00142000, 0x20000000, 0x20040000, 0x20002000, 0x20042000, 0x20100000, 0x20140000, 0x20102000, 0x20142000, 0x00000008, 0x00040008, 0x00002008, 0x00042008, 0x00100008, 0x00140008, 0x00102008, 0x00142008, 0x20000008, 0x20040008, 0x20002008, 0x20042008, 0x20100008, 0x20140008, 0x20102008, 0x20142008, 0x00200000, 0x00240000, 0x00202000, 0x00242000, 0x00300000, 0x00340000, 0x00302000, 0x00342000, 0x20200000, 0x20240000, 0x20202000, 0x20242000, 0x20300000, 0x20340000, 0x20302000, 0x20342000, 0x00200008, 0x00240008, 0x00202008, 0x00242008, 0x00300008, 0x00340008, 0x00302008, 0x00342008, 0x20200008, 0x20240008, 0x20202008, 0x20242008, 0x20300008, 0x20340008, 0x20302008, 0x20342008, }, { 0x00000000, 0x00000010, 0x08000000, 0x08000010, 0x00000200, 0x00000210, 0x08000200, 0x08000210, 0x00000002, 0x00000012, 0x08000002, 0x08000012, 0x00000202, 0x00000212, 0x08000202, 0x08000212, 0x04000000, 0x04000010, 0x0c000000, 0x0c000010, 0x04000200, 0x04000210, 0x0c000200, 0x0c000210, 0x04000002, 0x04000012, 0x0c000002, 0x0c000012, 0x04000202, 0x04000212, 0x0c000202, 0x0c000212, 0x00001000, 0x00001010, 0x08001000, 0x08001010, 0x00001200, 0x00001210, 0x08001200, 0x08001210, 0x00001002, 0x00001012, 0x08001002, 0x08001012, 0x00001202, 0x00001212, 0x08001202, 0x08001212, 0x04001000, 0x04001010, 0x0c001000, 0x0c001010, 0x04001200, 0x04001210, 0x0c001200, 0x0c001210, 0x04001002, 0x04001012, 0x0c001002, 0x0c001012, 0x04001202, 0x04001212, 0x0c001202, 0x0c001212 }, }; static const unsigned DES_INT32 PC2_D[4][64] = { { 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000100, 0x02000100, 0x00020100, 0x02020100, 0x00000008, 0x02000008, 0x00020008, 0x02020008, 0x00000108, 0x02000108, 0x00020108, 0x02020108, 0x00200000, 0x02200000, 0x00220000, 0x02220000, 0x00200100, 0x02200100, 0x00220100, 0x02220100, 0x00200008, 0x02200008, 0x00220008, 0x02220008, 0x00200108, 0x02200108, 0x00220108, 0x02220108, 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000300, 0x02000300, 0x00020300, 0x02020300, 0x00000208, 0x02000208, 0x00020208, 0x02020208, 0x00000308, 0x02000308, 0x00020308, 0x02020308, 0x00200200, 0x02200200, 0x00220200, 0x02220200, 0x00200300, 0x02200300, 0x00220300, 0x02220300, 0x00200208, 0x02200208, 0x00220208, 0x02220208, 0x00200308, 0x02200308, 0x00220308, 0x02220308, }, { 0x00000000, 0x00001000, 0x00000020, 0x00001020, 0x00100000, 0x00101000, 0x00100020, 0x00101020, 0x08000000, 0x08001000, 0x08000020, 0x08001020, 0x08100000, 0x08101000, 0x08100020, 0x08101020, 0x00000004, 0x00001004, 0x00000024, 0x00001024, 0x00100004, 0x00101004, 0x00100024, 0x00101024, 0x08000004, 0x08001004, 0x08000024, 0x08001024, 0x08100004, 0x08101004, 0x08100024, 0x08101024, 0x00000400, 0x00001400, 0x00000420, 0x00001420, 0x00100400, 0x00101400, 0x00100420, 0x00101420, 0x08000400, 0x08001400, 0x08000420, 0x08001420, 0x08100400, 0x08101400, 0x08100420, 0x08101420, 0x00000404, 0x00001404, 0x00000424, 0x00001424, 0x00100404, 0x00101404, 0x00100424, 0x00101424, 0x08000404, 0x08001404, 0x08000424, 0x08001424, 0x08100404, 0x08101404, 0x08100424, 0x08101424, }, { 0x00000000, 0x10000000, 0x00010000, 0x10010000, 0x00000002, 0x10000002, 0x00010002, 0x10010002, 0x00002000, 0x10002000, 0x00012000, 0x10012000, 0x00002002, 0x10002002, 0x00012002, 0x10012002, 0x00040000, 0x10040000, 0x00050000, 0x10050000, 0x00040002, 0x10040002, 0x00050002, 0x10050002, 0x00042000, 0x10042000, 0x00052000, 0x10052000, 0x00042002, 0x10042002, 0x00052002, 0x10052002, 0x20000000, 0x30000000, 0x20010000, 0x30010000, 0x20000002, 0x30000002, 0x20010002, 0x30010002, 0x20002000, 0x30002000, 0x20012000, 0x30012000, 0x20002002, 0x30002002, 0x20012002, 0x30012002, 0x20040000, 0x30040000, 0x20050000, 0x30050000, 0x20040002, 0x30040002, 0x20050002, 0x30050002, 0x20042000, 0x30042000, 0x20052000, 0x30052000, 0x20042002, 0x30042002, 0x20052002, 0x30052002, }, { 0x00000000, 0x04000000, 0x00000001, 0x04000001, 0x01000000, 0x05000000, 0x01000001, 0x05000001, 0x00000010, 0x04000010, 0x00000011, 0x04000011, 0x01000010, 0x05000010, 0x01000011, 0x05000011, 0x00080000, 0x04080000, 0x00080001, 0x04080001, 0x01080000, 0x05080000, 0x01080001, 0x05080001, 0x00080010, 0x04080010, 0x00080011, 0x04080011, 0x01080010, 0x05080010, 0x01080011, 0x05080011, 0x00000800, 0x04000800, 0x00000801, 0x04000801, 0x01000800, 0x05000800, 0x01000801, 0x05000801, 0x00000810, 0x04000810, 0x00000811, 0x04000811, 0x01000810, 0x05000810, 0x01000811, 0x05000811, 0x00080800, 0x04080800, 0x00080801, 0x04080801, 0x01080800, 0x05080800, 0x01080801, 0x05080801, 0x00080810, 0x04080810, 0x00080811, 0x04080811, 0x01080810, 0x05080810, 0x01080811, 0x05080811 }, }; /* * Permute the key to give us our key schedule. */ int mit_des_make_key_sched(mit_des_cblock key, mit_des_key_schedule schedule) { unsigned DES_INT32 c, d; { /* * Need a pointer for the keys and a temporary DES_INT32 */ const unsigned char *k; unsigned DES_INT32 tmp; /* * Fetch the key into something we can work with */ k = key; /* * The first permutted choice gives us the 28 bits for C0 and * 28 for D0. C0 gets 12 bits from the left key and 16 from * the right, while D0 gets 16 from the left and 12 from the * right. The code knows which bits go where. */ tmp = load_32_be(k), k += 4; c = PC1_CL[(tmp >> 29) & 0x7] | (PC1_CL[(tmp >> 21) & 0x7] << 1) | (PC1_CL[(tmp >> 13) & 0x7] << 2) | (PC1_CL[(tmp >> 5) & 0x7] << 3); d = PC1_DL[(tmp >> 25) & 0xf] | (PC1_DL[(tmp >> 17) & 0xf] << 1) | (PC1_DL[(tmp >> 9) & 0xf] << 2) | (PC1_DL[(tmp >> 1) & 0xf] << 3); tmp = load_32_be(k), k += 4; c |= PC1_CR[(tmp >> 28) & 0xf] | (PC1_CR[(tmp >> 20) & 0xf] << 1) | (PC1_CR[(tmp >> 12) & 0xf] << 2) | (PC1_CR[(tmp >> 4) & 0xf] << 3); d |= PC1_DR[(tmp >> 25) & 0x7] | (PC1_DR[(tmp >> 17) & 0x7] << 1) | (PC1_DR[(tmp >> 9) & 0x7] << 2) | (PC1_DR[(tmp >> 1) & 0x7] << 3); } { /* * Need several temporaries in here */ unsigned DES_INT32 ltmp, rtmp; unsigned DES_INT32 *k; int two_bit_shifts; int i; /* * Now iterate to compute the key schedule. Note that we * record the entire set of subkeys in 6 bit chunks since * they are used that way. At 6 bits/char, we need * 48/6 char's/subkey * 16 subkeys/encryption == 128 bytes. * The schedule must be this big. */ k = (unsigned DES_INT32 *)schedule; two_bit_shifts = TWO_BIT_SHIFTS; for (i = 16; i > 0; i--) { /* * Do the rotation. One bit and two bit rotations * are done separately. Note C and D are 28 bits. */ if (two_bit_shifts & 0x1) { c = ((c << 2) & 0xffffffc) | (c >> 26); d = ((d << 2) & 0xffffffc) | (d >> 26); } else { c = ((c << 1) & 0xffffffe) | (c >> 27); d = ((d << 1) & 0xffffffe) | (d >> 27); } two_bit_shifts >>= 1; /* * Apply permutted choice 2 to C to get the first * 24 bits worth of keys. Note that bits 9, 18, 22 * and 25 (using DES numbering) in C are unused. The * shift-mask stuff is done to delete these bits from * the indices, since this cuts the table size in half. * * The table is torqued, by the way. If the standard * byte order for this (high to low order) is 1234, * the table actually gives us 4132. */ ltmp = PC2_C[0][((c >> 22) & 0x3f)] | PC2_C[1][((c >> 15) & 0xf) | ((c >> 16) & 0x30)] | PC2_C[2][((c >> 4) & 0x3) | ((c >> 9) & 0x3c)] | PC2_C[3][((c ) & 0x7) | ((c >> 4) & 0x38)]; /* * Apply permutted choice 2 to D to get the other half. * Here, bits 7, 10, 15 and 26 go unused. The sqeezing * actually turns out to be cheaper here. * * This table is similarly torqued. If the standard * byte order is 5678, the table has the bytes permuted * to give us 7685. */ rtmp = PC2_D[0][((d >> 22) & 0x3f)] | PC2_D[1][((d >> 14) & 0xf) | ((d >> 15) & 0x30)] | PC2_D[2][((d >> 7) & 0x3f)] | PC2_D[3][((d ) & 0x3) | ((d >> 1) & 0x3c)]; /* * Make up two words of the key schedule, with a * byte order which is convenient for the DES * inner loop. The high order (first) word will * hold bytes 7135 (high to low order) while the * second holds bytes 4682. */ *k++ = (ltmp & 0x00ffff00) | (rtmp & 0xff0000ff); *k++ = (ltmp & 0xff0000ff) | (rtmp & 0x00ffff00); } } return (0); } #endif /* K5_BUILTIN_DES */ krb5-1.22.1/src/lib/crypto/builtin/des/weak_key.c0000664000175000017500000000564515051422640021414 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/des/weak_key.c */ /* * Copyright 1989,1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Under U.S. law, this software may not be exported outside the US * without license from the U.S. Commerce department. * * These routines form the library interface to the DES facilities. * * Originally written 8/85 by Steve Miller, MIT Project Athena. */ #include "crypto_int.h" #include "des_int.h" #ifdef K5_BUILTIN_DES /* * The following are the weak DES keys: */ static const mit_des_cblock weak[16] = { /* weak keys */ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, {0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe}, {0x1f,0x1f,0x1f,0x1f,0x0e,0x0e,0x0e,0x0e}, {0xe0,0xe0,0xe0,0xe0,0xf1,0xf1,0xf1,0xf1}, /* semi-weak */ {0x01,0xfe,0x01,0xfe,0x01,0xfe,0x01,0xfe}, {0xfe,0x01,0xfe,0x01,0xfe,0x01,0xfe,0x01}, {0x1f,0xe0,0x1f,0xe0,0x0e,0xf1,0x0e,0xf1}, {0xe0,0x1f,0xe0,0x1f,0xf1,0x0e,0xf1,0x0e}, {0x01,0xe0,0x01,0xe0,0x01,0xf1,0x01,0xf1}, {0xe0,0x01,0xe0,0x01,0xf1,0x01,0xf1,0x01}, {0x1f,0xfe,0x1f,0xfe,0x0e,0xfe,0x0e,0xfe}, {0xfe,0x1f,0xfe,0x1f,0xfe,0x0e,0xfe,0x0e}, {0x01,0x1f,0x01,0x1f,0x01,0x0e,0x01,0x0e}, {0x1f,0x01,0x1f,0x01,0x0e,0x01,0x0e,0x01}, {0xe0,0xfe,0xe0,0xfe,0xf1,0xfe,0xf1,0xfe}, {0xfe,0xe0,0xfe,0xe0,0xfe,0xf1,0xfe,0xf1} }; /* * mit_des_is_weak_key: returns true iff key is a [semi-]weak des key. * * Requires: key has correct odd parity. */ int mit_des_is_weak_key(mit_des_cblock key) { unsigned int i; const mit_des_cblock *weak_p = weak; for (i = 0; i < (sizeof(weak)/sizeof(mit_des_cblock)); i++) { if (!memcmp(weak_p++,key,sizeof(mit_des_cblock))) return 1; } return 0; } #endif /* K5_BUILTIN_DES */ krb5-1.22.1/src/lib/crypto/builtin/des/d3_kysched.c0000664000175000017500000000364015051422640021626 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1995 by Richard P. Basch. All Rights Reserved. * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Richard P. Basch, * Lehman Brothers and M.I.T. make no representations about the suitability * of this software for any purpose. It is provided "as is" without * express or implied warranty. */ #include "crypto_int.h" #include "des_int.h" #ifdef K5_BUILTIN_DES int mit_des3_key_sched(mit_des3_cblock k, mit_des3_key_schedule schedule) { mit_des_make_key_sched(k[0],schedule[0]); mit_des_make_key_sched(k[1],schedule[1]); mit_des_make_key_sched(k[2],schedule[2]); if (!mit_des_check_key_parity(k[0])) /* bad parity --> return -1 */ return(-1); if (mit_des_is_weak_key(k[0])) return(-2); if (!mit_des_check_key_parity(k[1])) return(-1); if (mit_des_is_weak_key(k[1])) return(-2); if (!mit_des_check_key_parity(k[2])) return(-1); if (mit_des_is_weak_key(k[2])) return(-2); /* if key was good, return 0 */ return 0; } #endif /* K5_BUILTIN_DES */ krb5-1.22.1/src/lib/crypto/builtin/des/f_cbc.c0000664000175000017500000001730115051422640020641 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/des/f_cbc.c */ /* * Copyright (C) 1990 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * CBC functions; used only by the test programs at this time. (krb5 uses the * functions in f_aead.c instead.) */ /* * des_cbc_encrypt.c - an implementation of the DES cipher function in cbc mode */ #include "des_int.h" #include "f_tables.h" /* * des_cbc_encrypt - {en,de}crypt a stream in CBC mode */ /* * This routine performs DES cipher-block-chaining operation, either * encrypting from cleartext to ciphertext, if encrypt != 0 or * decrypting from ciphertext to cleartext, if encrypt == 0. * * The key schedule is passed as an arg, as well as the cleartext or * ciphertext. The cleartext and ciphertext should be in host order. * * NOTE-- the output is ALWAYS an multiple of 8 bytes long. If not * enough space was provided, your program will get trashed. * * For encryption, the cleartext string is null padded, at the end, to * an integral multiple of eight bytes. * * For decryption, the ciphertext will be used in integral multiples * of 8 bytes, but only the first "length" bytes returned into the * cleartext. */ const mit_des_cblock mit_des_zeroblock /* = all zero */; static void des_cbc_encrypt(const mit_des_cblock *in, mit_des_cblock *out, unsigned long length, const mit_des_key_schedule schedule, const mit_des_cblock ivec) { unsigned DES_INT32 left, right; const unsigned DES_INT32 *kp; const unsigned char *ip; unsigned char *op; /* * Get key pointer here. This won't need to be reinitialized */ kp = (const unsigned DES_INT32 *)schedule; /* * Initialize left and right with the contents of the initial * vector. */ ip = ivec; GET_HALF_BLOCK(left, ip); GET_HALF_BLOCK(right, ip); /* * Suitably initialized, now work the length down 8 bytes * at a time. */ ip = *in; op = *out; while (length > 0) { /* * Get more input, xor it in. If the length is * greater than or equal to 8 this is straight * forward. Otherwise we have to fart around. */ if (length >= 8) { unsigned DES_INT32 temp; GET_HALF_BLOCK(temp, ip); left ^= temp; GET_HALF_BLOCK(temp, ip); right ^= temp; length -= 8; } else { /* * Oh, shoot. We need to pad the * end with zeroes. Work backwards * to do this. */ ip += (int) length; switch(length) { case 7: right ^= (*(--ip) & FF_UINT32) << 8; case 6: right ^= (*(--ip) & FF_UINT32) << 16; case 5: right ^= (*(--ip) & FF_UINT32) << 24; case 4: left ^= *(--ip) & FF_UINT32; case 3: left ^= (*(--ip) & FF_UINT32) << 8; case 2: left ^= (*(--ip) & FF_UINT32) << 16; case 1: left ^= (*(--ip) & FF_UINT32) << 24; break; } length = 0; } /* * Encrypt what we have */ DES_DO_ENCRYPT(left, right, kp); /* * Copy the results out */ PUT_HALF_BLOCK(left, op); PUT_HALF_BLOCK(right, op); } } static void des_cbc_decrypt(const mit_des_cblock *in, mit_des_cblock *out, unsigned long length, const mit_des_key_schedule schedule, const mit_des_cblock ivec) { unsigned DES_INT32 left, right; const unsigned DES_INT32 *kp; const unsigned char *ip; unsigned char *op; unsigned DES_INT32 ocipherl, ocipherr; unsigned DES_INT32 cipherl, cipherr; /* * Get key pointer here. This won't need to be reinitialized */ kp = (const unsigned DES_INT32 *)schedule; /* * Decrypting is harder than encrypting because of * the necessity of remembering a lot more things. * Should think about this a little more... */ if (length <= 0) return; /* * Prime the old cipher with ivec. */ ip = ivec; GET_HALF_BLOCK(ocipherl, ip); GET_HALF_BLOCK(ocipherr, ip); /* * Now do this in earnest until we run out of length. */ ip = *in; op = *out; for (;;) { /* check done inside loop */ /* * Read a block from the input into left and * right. Save this cipher block for later. */ GET_HALF_BLOCK(left, ip); GET_HALF_BLOCK(right, ip); cipherl = left; cipherr = right; /* * Decrypt this. */ DES_DO_DECRYPT(left, right, kp); /* * Xor with the old cipher to get plain * text. Output 8 or less bytes of this. */ left ^= ocipherl; right ^= ocipherr; if (length > 8) { length -= 8; PUT_HALF_BLOCK(left, op); PUT_HALF_BLOCK(right, op); /* * Save current cipher block here */ ocipherl = cipherl; ocipherr = cipherr; } else { /* * Trouble here. Start at end of output, * work backwards. */ op += (int) length; switch(length) { case 8: *(--op) = (unsigned char) (right & 0xff); case 7: *(--op) = (unsigned char) ((right >> 8) & 0xff); case 6: *(--op) = (unsigned char) ((right >> 16) & 0xff); case 5: *(--op) = (unsigned char) ((right >> 24) & 0xff); case 4: *(--op) = (unsigned char) (left & 0xff); case 3: *(--op) = (unsigned char) ((left >> 8) & 0xff); case 2: *(--op) = (unsigned char) ((left >> 16) & 0xff); case 1: *(--op) = (unsigned char) ((left >> 24) & 0xff); break; } break; /* we're done */ } } } int mit_des_cbc_encrypt(const mit_des_cblock *in, mit_des_cblock *out, unsigned long length, const mit_des_key_schedule schedule, const mit_des_cblock ivec, int enc) { /* * Deal with encryption and decryption separately. */ if (enc) des_cbc_encrypt(in, out, length, schedule, ivec); else des_cbc_decrypt(in, out, length, schedule, ivec); return 0; } krb5-1.22.1/src/lib/crypto/builtin/des/f_aead.c0000664000175000017500000001374515051422640021014 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2008 by the Massachusetts Institute of Technology. * Copyright 1995 by Richard P. Basch. All Rights Reserved. * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Richard P. Basch, * Lehman Brothers and M.I.T. make no representations about the suitability * of this software for any purpose. It is provided "as is" without * express or implied warranty. */ #include "crypto_int.h" #include "des_int.h" #include "f_tables.h" #ifdef K5_BUILTIN_DES const mit_des_cblock mit_des_zeroblock /* = all zero */; void krb5int_des_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule schedule, mit_des_cblock ivec) { unsigned DES_INT32 left, right; const unsigned DES_INT32 *kp; const unsigned char *ip; struct iov_cursor cursor; unsigned char block[MIT_DES_BLOCK_LENGTH]; /* Get key pointer here. This won't need to be reinitialized. */ kp = (const unsigned DES_INT32 *)schedule; /* Initialize left and right with the contents of the initial vector. */ ip = (ivec != NULL) ? ivec : mit_des_zeroblock; left = load_32_be(ip); right = load_32_be(ip + 4); k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE); while (k5_iov_cursor_get(&cursor, block)) { /* Decompose this block and xor it with the previous ciphertext. */ left ^= load_32_be(block); right ^= load_32_be(block + 4); /* Encrypt what we have and put back into block. */ DES_DO_ENCRYPT(left, right, kp); store_32_be(left, block); store_32_be(right, block + 4); k5_iov_cursor_put(&cursor, block); } if (ivec != NULL) { store_32_be(left, ivec); store_32_be(right, ivec + 4); } } void krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule schedule, mit_des_cblock ivec) { unsigned DES_INT32 left, right; const unsigned DES_INT32 *kp; const unsigned char *ip; unsigned DES_INT32 ocipherl, ocipherr; unsigned DES_INT32 cipherl, cipherr; struct iov_cursor cursor; unsigned char block[MIT_DES_BLOCK_LENGTH]; /* Get key pointer here. This won't need to be reinitialized. */ kp = (const unsigned DES_INT32 *)schedule; /* * Decrypting is harder than encrypting because of * the necessity of remembering a lot more things. * Should think about this a little more... */ /* Prime the old cipher with ivec. */ ip = (ivec != NULL) ? ivec : mit_des_zeroblock; ocipherl = load_32_be(ip); ocipherr = load_32_be(ip + 4); k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE); while (k5_iov_cursor_get(&cursor, block)) { /* Split this block into left and right. */ cipherl = left = load_32_be(block); cipherr = right = load_32_be(block + 4); /* Decrypt and xor with the old cipher to get plain text. */ DES_DO_DECRYPT(left, right, kp); left ^= ocipherl; right ^= ocipherr; /* Store the encrypted halves back into block. */ store_32_be(left, block); store_32_be(right, block + 4); /* Save current cipher block halves. */ ocipherl = cipherl; ocipherr = cipherr; k5_iov_cursor_put(&cursor, block); } if (ivec != NULL) { store_32_be(ocipherl, ivec); store_32_be(ocipherr, ivec + 4); } } void krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule schedule, mit_des_cblock ivec, mit_des_cblock out) { unsigned DES_INT32 left, right; const unsigned DES_INT32 *kp; const unsigned char *ip; struct iov_cursor cursor; unsigned char block[MIT_DES_BLOCK_LENGTH]; /* Get key pointer here. This won't need to be reinitialized. */ kp = (const unsigned DES_INT32 *)schedule; /* Initialize left and right with the contents of the initial vector. */ ip = (ivec != NULL) ? ivec : mit_des_zeroblock; left = load_32_be(ip); right = load_32_be(ip + 4); k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, TRUE); while (k5_iov_cursor_get(&cursor, block)) { /* Decompose this block and xor it with the previous ciphertext. */ left ^= load_32_be(block); right ^= load_32_be(block + 4); /* Encrypt what we have. */ DES_DO_ENCRYPT(left, right, kp); } /* Output the final ciphertext block. */ store_32_be(left, out); store_32_be(right, out + 4); } #if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO) void krb5int_des_do_encrypt_2 (unsigned DES_INT32 *left, unsigned DES_INT32 *right, const unsigned DES_INT32 *kp) { DES_DO_ENCRYPT_1 (*left, *right, kp); } void krb5int_des_do_decrypt_2 (unsigned DES_INT32 *left, unsigned DES_INT32 *right, const unsigned DES_INT32 *kp) { DES_DO_DECRYPT_1 (*left, *right, kp); } #endif #endif /* K5_BUILTIN_DES */ krb5-1.22.1/src/lib/crypto/builtin/des/f_cksum.c0000664000175000017500000001071215051422640021233 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/des/f_cksum.c */ /* * Copyright (C) 1990 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* DES implementation donated by Dennis Ferguson */ /* * des_cbc_cksum.c - compute an 8 byte checksum using DES in CBC mode */ #include "crypto_int.h" #include "des_int.h" #include "f_tables.h" #ifdef K5_BUILTIN_DES /* * This routine performs DES cipher-block-chaining checksum operation, * a.k.a. Message Authentication Code. It ALWAYS encrypts from input * to a single 64 bit output MAC checksum. * * The key schedule is passed as an arg, as well as the cleartext or * ciphertext. The cleartext and ciphertext should be in host order. * * NOTE-- the output is ALWAYS 8 bytes long. If not enough space was * provided, your program will get trashed. * * The input is null padded, at the end (highest addr), to an integral * multiple of eight bytes. */ unsigned long mit_des_cbc_cksum(const krb5_octet *in, krb5_octet *out, unsigned long length, const mit_des_key_schedule schedule, const krb5_octet *ivec) { unsigned DES_INT32 left, right; const unsigned DES_INT32 *kp; const unsigned char *ip; unsigned char *op; DES_INT32 len; /* * Initialize left and right with the contents of the initial * vector. */ ip = ivec; GET_HALF_BLOCK(left, ip); GET_HALF_BLOCK(right, ip); /* * Suitably initialized, now work the length down 8 bytes * at a time. */ ip = in; len = length; while (len > 0) { /* * Get more input, xor it in. If the length is * greater than or equal to 8 this is straight * forward. Otherwise we have to fart around. */ if (len >= 8) { unsigned DES_INT32 temp; GET_HALF_BLOCK(temp, ip); left ^= temp; GET_HALF_BLOCK(temp, ip); right ^= temp; len -= 8; } else { /* * Oh, shoot. We need to pad the * end with zeroes. Work backwards * to do this. */ ip += (int) len; switch(len) { case 7: right ^= (*(--ip) & FF_UINT32) << 8; case 6: right ^= (*(--ip) & FF_UINT32) << 16; case 5: right ^= (*(--ip) & FF_UINT32) << 24; case 4: left ^= *(--ip) & FF_UINT32; case 3: left ^= (*(--ip) & FF_UINT32) << 8; case 2: left ^= (*(--ip) & FF_UINT32) << 16; case 1: left ^= (*(--ip) & FF_UINT32) << 24; break; } len = 0; } /* * Encrypt what we have */ kp = (const unsigned DES_INT32 *)schedule; DES_DO_ENCRYPT(left, right, kp); } /* * Done. Left and right have the checksum. Put it into * the output. */ op = out; PUT_HALF_BLOCK(left, op); PUT_HALF_BLOCK(right, op); /* * Return right. I'll bet the MIT code returns this * inconsistantly (with the low order byte of the checksum * not always in the low order byte of the DES_INT32). We won't. */ return right & 0xFFFFFFFFUL; } #endif /* K5_BUILTIN_DES */ krb5-1.22.1/src/lib/crypto/builtin/des/t_verify.c0000664000175000017500000003072115051422640021435 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/des/t_verify.c */ /* * Copyright 1988, 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* * * Program to test the correctness of the DES library * implementation. * * exit returns 0 ==> success * -1 ==> error */ #include "k5-int.h" #include "des_int.h" #include #include "com_err.h" static void do_encrypt(unsigned char *, unsigned char *); static void do_decrypt(unsigned char *, unsigned char *); char *progname; int nflag = 2; int vflag; int mflag; int zflag; int pid; int mit_des_debug; unsigned char cipher_text[64]; unsigned char clear_text[64] = "Now is the time for all " ; unsigned char clear_text2[64] = "7654321 Now is the time for "; unsigned char clear_text3[64] = {2,0,0,0, 1,0,0,0}; unsigned char output[64]; unsigned char zero_text[8] = {0x0,0,0,0,0,0,0,0}; unsigned char msb_text[8] = {0x0,0,0,0, 0,0,0,0x40}; /* to ANSI MSB */ unsigned char *input; /* 0x0123456789abcdef */ unsigned char default_key[8] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef }; unsigned char key2[8] = { 0x08,0x19,0x2a,0x3b,0x4c,0x5d,0x6e,0x7f }; unsigned char key3[8] = { 0x80,1,1,1,1,1,1,1 }; mit_des_cblock s_key; unsigned char default_ivec[8] = { 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef }; unsigned char *ivec; unsigned char zero_key[8] = {1,1,1,1,1,1,1,1}; /* just parity bits */ unsigned char cipher1[8] = { 0x25,0xdd,0xac,0x3e,0x96,0x17,0x64,0x67 }; unsigned char cipher2[8] = { 0x3f,0xa4,0x0e,0x8a,0x98,0x4d,0x48,0x15 }; unsigned char cipher3[64] = { 0xe5,0xc7,0xcd,0xde,0x87,0x2b,0xf2,0x7c, 0x43,0xe9,0x34,0x00,0x8c,0x38,0x9c,0x0f, 0x68,0x37,0x88,0x49,0x9a,0x7c,0x05,0xf6 }; unsigned char checksum[8] = { 0x58,0xd2,0xe7,0x7e,0x86,0x06,0x27,0x33 }; unsigned char zresult[8] = { 0x8c, 0xa6, 0x4d, 0xe9, 0xc1, 0xb1, 0x23, 0xa7 }; unsigned char mresult[8] = { 0xa3, 0x80, 0xe0, 0x2a, 0x6b, 0xe5, 0x46, 0x96 }; /* * Can also add : * plaintext = 0, key = 0, cipher = 0x8ca64de9c1b123a7 (or is it a 1?) */ mit_des_key_schedule sched; int main(int argc, char *argv[]) { /* Local Declarations */ size_t in_length; int retval; int i, j; #ifdef WINDOWS /* Set screen window buffer to infinite size -- MS default is tiny. */ _wsetscreenbuf (fileno (stdout), _WINBUFINF); #endif progname=argv[0]; /* salt away invoking program */ while (--argc > 0 && (*++argv)[0] == '-') for (i=1; argv[0][i] != '\0'; i++) { switch (argv[0][i]) { /* debug flag */ case 'd': mit_des_debug=3; continue; case 'z': zflag = 1; continue; case 'm': mflag = 1; continue; default: printf("%s: illegal flag \"%c\" ", progname,argv[0][i]); exit(1); } }; if (argc) { fprintf(stderr, "Usage: %s [-dmz]\n", progname); exit(1); } /* do some initialisation */ /* use known input and key */ /* ECB zero text zero key */ if (zflag) { input = zero_text; mit_des_key_sched(zero_key, sched); printf("plaintext = key = 0, cipher = 0x8ca64de9c1b123a7\n"); do_encrypt(input,cipher_text); printf("\tcipher = (low to high bytes)\n\t\t"); for (j = 0; j<=7; j++) printf("%02x ",cipher_text[j]); printf("\n"); do_decrypt(output,cipher_text); if ( memcmp((char *)cipher_text, (char *)zresult, 8) ) { printf("verify: error in zero key test\n"); exit(-1); } exit(0); } if (mflag) { input = msb_text; mit_des_key_sched(key3, sched); printf("plaintext = 0x00 00 00 00 00 00 00 40, "); printf("key = 0x80 01 01 01 01 01 01 01\n"); printf(" cipher = 0xa380e02a6be54696\n"); do_encrypt(input,cipher_text); printf("\tcipher = (low to high bytes)\n\t\t"); for (j = 0; j<=7; j++) { printf("%02x ",cipher_text[j]); } printf("\n"); do_decrypt(output,cipher_text); if ( memcmp((char *)cipher_text, (char *)mresult, 8) ) { printf("verify: error in msb test\n"); exit(-1); } exit(0); } /* ECB mode Davies and Price */ { input = zero_text; mit_des_key_sched(key2, sched); printf("Examples per FIPS publication 81, keys ivs and cipher\n"); printf("in hex. These are the correct answers, see below for\n"); printf("the actual answers.\n\n"); printf("Examples per Davies and Price.\n\n"); printf("EXAMPLE ECB\tkey = 08192a3b4c5d6e7f\n"); printf("\tclear = 0\n"); printf("\tcipher = 25 dd ac 3e 96 17 64 67\n"); printf("ACTUAL ECB\n"); printf("\tclear \"%s\"\n", input); do_encrypt(input,cipher_text); printf("\tcipher = (low to high bytes)\n\t\t"); for (j = 0; j<=7; j++) printf("%02x ",cipher_text[j]); printf("\n\n"); do_decrypt(output,cipher_text); if ( memcmp((char *)cipher_text, (char *)cipher1, 8) ) { printf("verify: error in ECB encryption\n"); exit(-1); } else printf("verify: ECB encryption is correct\n\n"); } /* ECB mode */ { mit_des_key_sched(default_key, sched); input = clear_text; ivec = default_ivec; printf("EXAMPLE ECB\tkey = 0123456789abcdef\n"); printf("\tclear = \"Now is the time for all \"\n"); printf("\tcipher = 3f a4 0e 8a 98 4d 48 15 ...\n"); printf("ACTUAL ECB\n\tclear \"%s\"",input); do_encrypt(input,cipher_text); printf("\n\tcipher = (low to high bytes)\n\t\t"); for (j = 0; j<=7; j++) { printf("%02x ",cipher_text[j]); } printf("\n\n"); do_decrypt(output,cipher_text); if ( memcmp((char *)cipher_text, (char *)cipher2, 8) ) { printf("verify: error in ECB encryption\n"); exit(-1); } else printf("verify: ECB encryption is correct\n\n"); } /* CBC mode */ printf("EXAMPLE CBC\tkey = 0123456789abcdef"); printf("\tiv = 1234567890abcdef\n"); printf("\tclear = \"Now is the time for all \"\n"); printf("\tcipher =\te5 c7 cd de 87 2b f2 7c\n"); printf("\t\t\t43 e9 34 00 8c 38 9c 0f\n"); printf("\t\t\t68 37 88 49 9a 7c 05 f6\n"); printf("ACTUAL CBC\n\tclear \"%s\"\n",input); in_length = strlen((char *)input); if ((retval = mit_des_cbc_encrypt((const mit_des_cblock *) input, (mit_des_cblock *) cipher_text, (size_t) in_length, sched, ivec, MIT_DES_ENCRYPT))) { com_err("des verify", retval, "can't encrypt"); exit(-1); } printf("\tciphertext = (low to high bytes)\n"); for (i = 0; i <= 2; i++) { printf("\t\t"); for (j = 0; j <= 7; j++) { printf("%02x ",cipher_text[i*8+j]); } printf("\n"); } if ((retval = mit_des_cbc_encrypt((const mit_des_cblock *) cipher_text, (mit_des_cblock *) clear_text, (size_t) in_length, sched, ivec, MIT_DES_DECRYPT))) { com_err("des verify", retval, "can't decrypt"); exit(-1); } printf("\tdecrypted clear_text = \"%s\"\n",clear_text); if ( memcmp((char *)cipher_text, (char *)cipher3, in_length) ) { printf("verify: error in CBC encryption\n"); exit(-1); } else printf("verify: CBC encryption is correct\n\n"); printf("EXAMPLE CBC checksum"); printf("\tkey = 0123456789abcdef\tiv = 1234567890abcdef\n"); printf("\tclear =\t\t\"7654321 Now is the time for \"\n"); printf("\tchecksum\t58 d2 e7 7e 86 06 27 33, "); printf("or some part thereof\n"); input = clear_text2; mit_des_cbc_cksum(input,cipher_text, strlen((char *)input), sched,ivec); printf("ACTUAL CBC checksum\n"); printf("\t\tencrypted cksum = (low to high bytes)\n\t\t"); for (j = 0; j<=7; j++) printf("%02x ",cipher_text[j]); printf("\n\n"); if ( memcmp((char *)cipher_text, (char *)checksum, 8) ) { printf("verify: error in CBC checksum\n"); exit(-1); } else printf("verify: CBC checksum is correct\n\n"); exit(0); } static void do_encrypt(unsigned char *in, unsigned char *out) { int i, j; for (i =1; i<=nflag; i++) { mit_des_cbc_encrypt((const mit_des_cblock *)in, (mit_des_cblock *)out, 8, sched, zero_text, MIT_DES_ENCRYPT); if (mit_des_debug) { printf("\nclear %s\n",in); for (j = 0; j<=7; j++) printf("%02X ",in[j] & 0xff); printf("\tcipher "); for (j = 0; j<=7; j++) printf("%02X ",out[j] & 0xff); } } } static void do_decrypt(unsigned char *in, unsigned char *out) /* try to invert it */ { int i, j; for (i =1; i<=nflag; i++) { mit_des_cbc_encrypt((const mit_des_cblock *)out, (mit_des_cblock *)in, 8, sched, zero_text, MIT_DES_DECRYPT); if (mit_des_debug) { printf("clear %s\n",in); for (j = 0; j<=7; j++) printf("%02X ",in[j] & 0xff); printf("\tcipher "); for (j = 0; j<=7; j++) printf("%02X ",out[j] & 0xff); } } } /* * Fake out the DES library, for the purposes of testing. */ int mit_des_is_weak_key(mit_des_cblock key) { return 0; /* fake it out for testing */ } krb5-1.22.1/src/lib/crypto/builtin/des/d3_aead.c0000664000175000017500000001154715051422640021073 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2008 by the Massachusetts Institute of Technology. * Copyright 1995 by Richard P. Basch. All Rights Reserved. * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Richard P. Basch, * Lehman Brothers and M.I.T. make no representations about the suitability * of this software for any purpose. It is provided "as is" without * express or implied warranty. */ #include "crypto_int.h" #include "des_int.h" #include "f_tables.h" #ifdef K5_BUILTIN_DES void krb5int_des3_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule ks1, const mit_des_key_schedule ks2, const mit_des_key_schedule ks3, mit_des_cblock ivec) { unsigned DES_INT32 left, right; const unsigned DES_INT32 *kp1, *kp2, *kp3; const unsigned char *ip; struct iov_cursor cursor; unsigned char block[MIT_DES_BLOCK_LENGTH]; /* Get key pointers here. These won't need to be reinitialized. */ kp1 = (const unsigned DES_INT32 *)ks1; kp2 = (const unsigned DES_INT32 *)ks2; kp3 = (const unsigned DES_INT32 *)ks3; /* Initialize left and right with the contents of the initial vector. */ ip = (ivec != NULL) ? ivec : mit_des_zeroblock; left = load_32_be(ip); right = load_32_be(ip + 4); k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE); while (k5_iov_cursor_get(&cursor, block)) { /* xor this block with the previous ciphertext. */ left ^= load_32_be(block); right ^= load_32_be(block + 4); /* Encrypt what we have and store it back into block. */ DES_DO_ENCRYPT(left, right, kp1); DES_DO_DECRYPT(left, right, kp2); DES_DO_ENCRYPT(left, right, kp3); store_32_be(left, block); store_32_be(right, block + 4); k5_iov_cursor_put(&cursor, block); } if (ivec != NULL) { store_32_be(left, ivec); store_32_be(right, ivec + 4); } } void krb5int_des3_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data, const mit_des_key_schedule ks1, const mit_des_key_schedule ks2, const mit_des_key_schedule ks3, mit_des_cblock ivec) { unsigned DES_INT32 left, right; const unsigned DES_INT32 *kp1, *kp2, *kp3; const unsigned char *ip; unsigned DES_INT32 ocipherl, ocipherr; unsigned DES_INT32 cipherl, cipherr; struct iov_cursor cursor; unsigned char block[MIT_DES_BLOCK_LENGTH]; /* Get key pointers here. These won't need to be reinitialized. */ kp1 = (const unsigned DES_INT32 *)ks1; kp2 = (const unsigned DES_INT32 *)ks2; kp3 = (const unsigned DES_INT32 *)ks3; /* * Decrypting is harder than encrypting because of * the necessity of remembering a lot more things. * Should think about this a little more... */ /* Prime the old cipher with ivec.*/ ip = (ivec != NULL) ? ivec : mit_des_zeroblock; ocipherl = load_32_be(ip); ocipherr = load_32_be(ip + 4); k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE); while (k5_iov_cursor_get(&cursor, block)) { /* Split this block into left and right. */ cipherl = left = load_32_be(block); cipherr = right = load_32_be(block + 4); /* Decrypt and xor with the old cipher to get plain text. */ DES_DO_DECRYPT(left, right, kp3); DES_DO_ENCRYPT(left, right, kp2); DES_DO_DECRYPT(left, right, kp1); left ^= ocipherl; right ^= ocipherr; /* Store the encrypted halves back into block. */ store_32_be(left, block); store_32_be(right, block + 4); /* Save current cipher block halves. */ ocipherl = cipherl; ocipherr = cipherr; k5_iov_cursor_put(&cursor, block); } if (ivec != NULL) { store_32_be(ocipherl, ivec); store_32_be(ocipherr, ivec + 4); } } #endif /* K5_BUILTIN_DES */ krb5-1.22.1/src/lib/crypto/builtin/des/key_sched.c0000664000175000017500000000453015051422640021543 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/des/key_sched.c */ /* * Copyright 1985, 1986, 1987, 1988, 1990 by the Massachusetts Institute * of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This routine computes the DES key schedule given a key. The * permutations and shifts have been done at compile time, resulting * in a direct one-step mapping from the input key to the key * schedule. * * Also checks parity and weak keys. * * Watch out for the subscripts -- most effectively start at 1 instead * of at zero. Maybe some bugs in that area. * * In case the user wants to cache the computed key schedule, it is * passed as an arg. Also implies that caller has explicit control * over zeroing both the key schedule and the key. * * Originally written 6/85 by Steve Miller, MIT Project Athena. */ #include "crypto_int.h" #include "des_int.h" #ifdef K5_BUILTIN_DES int mit_des_key_sched(mit_des_cblock k, mit_des_key_schedule schedule) { mit_des_make_key_sched(k,schedule); if (!mit_des_check_key_parity(k)) /* bad parity --> return -1 */ return(-1); if (mit_des_is_weak_key(k)) return(-2); /* if key was good, return 0 */ return 0; } #endif /* K5_BUILTIN_DES */ krb5-1.22.1/src/lib/crypto/builtin/enc_provider/0000775000175000017500000000000015051422640021343 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/enc_provider/camellia.c0000664000175000017500000002410615051422640023261 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/enc_provider/camellia.c - Camellia enc provider */ /* * Copyright (C) 2009, 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #include "camellia.h" #ifdef K5_BUILTIN_CAMELLIA /* * Private per-key data to cache after first generation. We don't want to mess * with the imported Camellia implementation too much, so we'll just use two * copies of its context, one for encryption and one for decryption, and use * the keybitlen field as a flag for whether we've initialized each half. */ struct camellia_key_info_cache { camellia_ctx enc_ctx, dec_ctx; }; #define CACHE(X) ((struct camellia_key_info_cache *)((X)->cache)) /* out = out ^ in */ static inline void xorblock(const unsigned char *in, unsigned char *out) { size_t q; for (q = 0; q < BLOCK_SIZE; q += 4) store_32_n(load_32_n(out + q) ^ load_32_n(in + q), out + q); } static inline krb5_error_code init_key_cache(krb5_key key) { if (key->cache != NULL) return 0; key->cache = malloc(sizeof(struct camellia_key_info_cache)); if (key->cache == NULL) return ENOMEM; CACHE(key)->enc_ctx.keybitlen = CACHE(key)->dec_ctx.keybitlen = 0; return 0; } static inline void expand_enc_key(krb5_key key) { if (CACHE(key)->enc_ctx.keybitlen) return; if (camellia_enc_key(key->keyblock.contents, key->keyblock.length, &CACHE(key)->enc_ctx) != camellia_good) abort(); } static inline void expand_dec_key(krb5_key key) { if (CACHE(key)->dec_ctx.keybitlen) return; if (camellia_dec_key(key->keyblock.contents, key->keyblock.length, &CACHE(key)->dec_ctx) != camellia_good) abort(); } /* CBC encrypt nblocks blocks of data in place, using and updating iv. */ static inline void cbc_enc(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv) { for (; nblocks > 0; nblocks--, data += BLOCK_SIZE) { xorblock(iv, data); if (camellia_enc_blk(data, data, &CACHE(key)->enc_ctx) != camellia_good) abort(); memcpy(iv, data, BLOCK_SIZE); } } /* CBC decrypt nblocks blocks of data in place, using and updating iv. */ static inline void cbc_dec(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv) { unsigned char last_cipherblock[BLOCK_SIZE]; assert(nblocks > 0); data += (nblocks - 1) * BLOCK_SIZE; memcpy(last_cipherblock, data, BLOCK_SIZE); for (; nblocks > 0; nblocks--, data -= BLOCK_SIZE) { if (camellia_dec_blk(data, data, &CACHE(key)->dec_ctx) != camellia_good) abort(); xorblock(nblocks == 1 ? iv : data - BLOCK_SIZE, data); } memcpy(iv, last_cipherblock, BLOCK_SIZE); } krb5_error_code krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { unsigned char iv[BLOCK_SIZE], block[BLOCK_SIZE]; unsigned char blockN2[BLOCK_SIZE], blockN1[BLOCK_SIZE]; size_t input_length, nblocks, ncontig; struct iov_cursor cursor; if (init_key_cache(key)) return ENOMEM; expand_enc_key(key); k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; if (nblocks == 1) { k5_iov_cursor_get(&cursor, block); memset(iv, 0, BLOCK_SIZE); cbc_enc(key, block, 1, iv); k5_iov_cursor_put(&cursor, block); return 0; } if (ivec != NULL) memcpy(iv, ivec->data, BLOCK_SIZE); else memset(iv, 0, BLOCK_SIZE); while (nblocks > 2) { ncontig = iov_cursor_contig_blocks(&cursor); if (ncontig > 0) { /* Encrypt a series of contiguous blocks in place if we can, but * don't touch the last two blocks. */ ncontig = (ncontig > nblocks - 2) ? nblocks - 2 : ncontig; cbc_enc(key, iov_cursor_ptr(&cursor), ncontig, iv); iov_cursor_advance(&cursor, ncontig); nblocks -= ncontig; } else { k5_iov_cursor_get(&cursor, block); cbc_enc(key, block, 1, iv); k5_iov_cursor_put(&cursor, block); nblocks--; } } /* Encrypt the last two blocks and put them back in reverse order, possibly * truncating the encrypted second-to-last block. */ k5_iov_cursor_get(&cursor, blockN2); k5_iov_cursor_get(&cursor, blockN1); cbc_enc(key, blockN2, 1, iv); cbc_enc(key, blockN1, 1, iv); k5_iov_cursor_put(&cursor, blockN1); k5_iov_cursor_put(&cursor, blockN2); if (ivec != NULL) memcpy(ivec->data, iv, BLOCK_SIZE); return 0; } static krb5_error_code krb5int_camellia_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { unsigned char iv[BLOCK_SIZE], dummy_iv[BLOCK_SIZE], block[BLOCK_SIZE]; unsigned char blockN2[BLOCK_SIZE], blockN1[BLOCK_SIZE]; size_t input_length, last_len, nblocks, ncontig; struct iov_cursor cursor; if (init_key_cache(key)) return ENOMEM; expand_dec_key(key); k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE; last_len = input_length - (nblocks - 1) * BLOCK_SIZE; if (nblocks == 1) { k5_iov_cursor_get(&cursor, block); memset(iv, 0, BLOCK_SIZE); cbc_dec(key, block, 1, iv); k5_iov_cursor_put(&cursor, block); return 0; } if (ivec != NULL) memcpy(iv, ivec->data, BLOCK_SIZE); else memset(iv, 0, BLOCK_SIZE); while (nblocks > 2) { ncontig = iov_cursor_contig_blocks(&cursor); if (ncontig > 0) { /* Encrypt a series of contiguous blocks in place if we can, but * don't touch the last two blocks. */ ncontig = (ncontig > nblocks - 2) ? nblocks - 2 : ncontig; cbc_dec(key, iov_cursor_ptr(&cursor), ncontig, iv); iov_cursor_advance(&cursor, ncontig); nblocks -= ncontig; } else { k5_iov_cursor_get(&cursor, block); cbc_dec(key, block, 1, iv); k5_iov_cursor_put(&cursor, block); nblocks--; } } /* Get the last two ciphertext blocks. Save the first as the new iv. */ k5_iov_cursor_get(&cursor, blockN2); k5_iov_cursor_get(&cursor, blockN1); if (ivec != NULL) memcpy(ivec->data, blockN2, BLOCK_SIZE); /* Decrypt the second-to-last ciphertext block, using the final ciphertext * block as the CBC IV. This produces the final plaintext block. */ memcpy(dummy_iv, blockN1, sizeof(dummy_iv)); cbc_dec(key, blockN2, 1, dummy_iv); /* Use the final bits of the decrypted plaintext to pad the last ciphertext * block, and decrypt it to produce the second-to-last plaintext block. */ memcpy(blockN1 + last_len, blockN2 + last_len, BLOCK_SIZE - last_len); cbc_dec(key, blockN1, 1, iv); /* Put the last two plaintext blocks back into the iovec. */ k5_iov_cursor_put(&cursor, blockN1); k5_iov_cursor_put(&cursor, blockN2); return 0; } static krb5_error_code krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data, const krb5_data *ivec, krb5_data *output) { unsigned char iv[BLOCK_SIZE], block[BLOCK_SIZE]; struct iov_cursor cursor; if (output->length < BLOCK_SIZE) return KRB5_BAD_MSIZE; if (init_key_cache(key)) return ENOMEM; expand_enc_key(key); if (ivec != NULL) memcpy(iv, ivec->data, BLOCK_SIZE); else memset(iv, 0, BLOCK_SIZE); k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE); while (k5_iov_cursor_get(&cursor, block)) cbc_enc(key, block, 1, iv); output->length = BLOCK_SIZE; memcpy(output->data, iv, BLOCK_SIZE); return 0; } static krb5_error_code camellia_init_state(const krb5_keyblock *key, krb5_keyusage usage, krb5_data *state) { state->length = 16; state->data = malloc(16); if (state->data == NULL) return ENOMEM; memset(state->data, 0, state->length); return 0; } static void camellia_key_cleanup(krb5_key key) { zapfree(key->cache, sizeof(struct camellia_key_info_cache)); } const struct krb5_enc_provider krb5int_enc_camellia128 = { 16, 16, 16, krb5int_camellia_encrypt, krb5int_camellia_decrypt, krb5int_camellia_cbc_mac, camellia_init_state, krb5int_default_free_state, camellia_key_cleanup }; const struct krb5_enc_provider krb5int_enc_camellia256 = { 16, 32, 32, krb5int_camellia_encrypt, krb5int_camellia_decrypt, krb5int_camellia_cbc_mac, camellia_init_state, krb5int_default_free_state, camellia_key_cleanup }; #endif /* K5_BUILTIN_CAMELLIA */ krb5-1.22.1/src/lib/crypto/builtin/enc_provider/rc4.c0000664000175000017500000001276115051422640022206 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/enc_provider/rc4.c */ /* * Copyright (c) 2000 by Computer Science Laboratory, * Rensselaer Polytechnic Institute * * #include STD_DISCLAIMER */ #include "crypto_int.h" #ifdef K5_BUILTIN_RC4 typedef struct { unsigned int x; unsigned int y; unsigned char state[256]; } ArcfourContext; typedef struct { int initialized; ArcfourContext ctx; } ArcFourCipherState; /* gets the next byte from the PRNG */ #if ((__GNUC__ >= 2) ) static __inline__ unsigned int k5_arcfour_byte(ArcfourContext *); #else static unsigned int k5_arcfour_byte(ArcfourContext *); #endif /* gcc inlines*/ /* Initializes the context and sets the key. */ static krb5_error_code k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key, unsigned int keylen); /* Encrypts/decrypts data. */ static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest, const unsigned char *src, unsigned int len); static inline unsigned int k5_arcfour_byte(ArcfourContext * ctx) { unsigned int x; unsigned int y; unsigned int sx, sy; unsigned char *state; state = ctx->state; x = (ctx->x + 1) & 0xff; sx = state[x]; y = (sx + ctx->y) & 0xff; sy = state[y]; ctx->x = x; ctx->y = y; state[y] = sx; state[x] = sy; return state[(sx + sy) & 0xff]; } static void k5_arcfour_crypt(ArcfourContext *ctx, unsigned char *dest, const unsigned char *src, unsigned int len) { unsigned int i; for (i = 0; i < len; i++) dest[i] = src[i] ^ k5_arcfour_byte(ctx); } static krb5_error_code k5_arcfour_init(ArcfourContext *ctx, const unsigned char *key, unsigned int key_len) { unsigned int t, u; unsigned int keyindex; unsigned int stateindex; unsigned char* state; unsigned int counter; if (key_len != 16) return KRB5_BAD_MSIZE; /*this is probably not the correct error code to return */ state = &ctx->state[0]; ctx->x = 0; ctx->y = 0; for (counter = 0; counter < 256; counter++) state[counter] = counter; keyindex = 0; stateindex = 0; for (counter = 0; counter < 256; counter++) { t = state[counter]; stateindex = (stateindex + key[keyindex] + t) & 0xff; u = state[stateindex]; state[stateindex] = t; state[counter] = u; if (++keyindex >= key_len) keyindex = 0; } return 0; } static krb5_error_code k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data, size_t num_data) { ArcfourContext *arcfour_ctx = NULL; ArcFourCipherState *cipher_state = NULL; krb5_error_code ret; size_t i; if (key->keyblock.length != 16) return KRB5_BAD_KEYSIZE; if (state != NULL && (state->length != sizeof(ArcFourCipherState))) return KRB5_BAD_MSIZE; if (state != NULL) { cipher_state = (ArcFourCipherState *)(void *)state->data; arcfour_ctx = &cipher_state->ctx; if (cipher_state->initialized == 0) { ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents, key->keyblock.length); if (ret != 0) return ret; cipher_state->initialized = 1; } } else { arcfour_ctx = (ArcfourContext *)malloc(sizeof(ArcfourContext)); if (arcfour_ctx == NULL) return ENOMEM; ret = k5_arcfour_init(arcfour_ctx, key->keyblock.contents, key->keyblock.length); if (ret != 0) { free(arcfour_ctx); return ret; } } for (i = 0; i < num_data; i++) { krb5_crypto_iov *iov = &data[i]; if (ENCRYPT_IOV(iov)) k5_arcfour_crypt(arcfour_ctx, (unsigned char *)iov->data.data, (const unsigned char *)iov->data.data, iov->data.length); } if (state == NULL) zapfree(arcfour_ctx, sizeof(ArcfourContext)); return 0; } static krb5_error_code k5_arcfour_init_state (const krb5_keyblock *key, krb5_keyusage keyusage, krb5_data *new_state) { /* Note that we can't actually set up the state here because the key * will change between now and when encrypt is called * because it is data dependent. Yeah, this has strange * properties. --SDH */ new_state->length = sizeof (ArcFourCipherState); new_state->data = malloc (new_state->length); if (new_state->data) { memset (new_state->data, 0 , new_state->length); /* That will set initialized to zero*/ }else { return (ENOMEM); } return 0; } /* Since the arcfour cipher is identical going forwards and backwards, we just call "docrypt" directly */ const struct krb5_enc_provider krb5int_enc_arcfour = { /* This seems to work... although I am not sure what the implications are in other places in the kerberos library */ 1, /* Keysize is arbitrary in arcfour, but the constraints of the system, and to attempt to work with the MSFT system forces us to 16byte/128bit. Since there is no parity in the key, the byte and length are the same. */ 16, 16, k5_arcfour_docrypt, k5_arcfour_docrypt, NULL, k5_arcfour_init_state, /*xxx not implemented yet*/ krb5int_default_free_state }; #endif /* K5_BUILTIN_RC4 */ krb5-1.22.1/src/lib/crypto/builtin/enc_provider/Makefile.in0000664000175000017500000000132515051422640023411 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)builtin$(S)enc_provider BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../des -I$(srcdir)/../aes -I$(srcdir)/../camellia \ -I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLAGS) ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = builtin\enc_provider ##DOS##OBJFILE = ..\..\$(OUTPRE)enc_provider.lst STLIBOBJS= \ des3.o \ rc4.o \ aes.o \ camellia.o OBJS= \ $(OUTPRE)des3.$(OBJEXT) \ $(OUTPRE)aes.$(OBJEXT) \ $(OUTPRE)camellia.$(OBJEXT) \ $(OUTPRE)rc4.$(OBJEXT) SRCS= \ $(srcdir)/des3.c \ $(srcdir)/aes.c \ $(srcdir)/camellia.c \ $(srcdir)/rc4.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs includes: depend depend: $(SRCS) clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/enc_provider/deps0000664000175000017500000000614215051422640022224 0ustar ghudsonghudson# # Generated makefile dependencies follow. # des3.so des3.po $(OUTPRE)des3.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(srcdir)/../des/des_int.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h des3.c aes.so aes.po $(OUTPRE)aes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(srcdir)/../aes/aes.h $(srcdir)/../aes/brg_types.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ aes.c camellia.so camellia.po $(OUTPRE)camellia.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../camellia/camellia.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ camellia.c rc4.so rc4.po $(OUTPRE)rc4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ rc4.c krb5-1.22.1/src/lib/crypto/builtin/enc_provider/des3.c0000664000175000017500000000672215051422640022354 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" #include "des_int.h" #ifdef K5_BUILTIN_DES static krb5_error_code validate_and_schedule(krb5_key key, const krb5_data *ivec, const krb5_crypto_iov *data, size_t num_data, mit_des3_key_schedule *schedule) { if (key->keyblock.length != 24) return(KRB5_BAD_KEYSIZE); if (iov_total_length(data, num_data, FALSE) % 8 != 0) return(KRB5_BAD_MSIZE); if (ivec && (ivec->length != 8)) return(KRB5_BAD_MSIZE); switch (mit_des3_key_sched(*(mit_des3_cblock *)key->keyblock.contents, *schedule)) { case -1: return(KRB5DES_BAD_KEYPAR); case -2: return(KRB5DES_WEAK_KEY); } return 0; } static krb5_error_code k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { mit_des3_key_schedule schedule; krb5_error_code err; err = validate_and_schedule(key, ivec, data, num_data, &schedule); if (err) return err; /* this has a return value, but the code always returns zero */ krb5int_des3_cbc_encrypt(data, num_data, schedule[0], schedule[1], schedule[2], ivec != NULL ? (unsigned char *) ivec->data : NULL); zap(schedule, sizeof(schedule)); return(0); } static krb5_error_code k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { mit_des3_key_schedule schedule; krb5_error_code err; err = validate_and_schedule(key, ivec, data, num_data, &schedule); if (err) return err; /* this has a return value, but the code always returns zero */ krb5int_des3_cbc_decrypt(data, num_data, schedule[0], schedule[1], schedule[2], ivec != NULL ? (unsigned char *) ivec->data : NULL); zap(schedule, sizeof(schedule)); return 0; } const struct krb5_enc_provider krb5int_enc_des3 = { 8, 21, 24, k5_des3_encrypt, k5_des3_decrypt, NULL, krb5int_des_init_state, krb5int_default_free_state }; #endif /* K5_BUILTIN_DES */ krb5-1.22.1/src/lib/crypto/builtin/enc_provider/aes.c0000664000175000017500000003041315051422640022260 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/enc_provider/aes.c */ /* * Copyright (C) 2003, 2007, 2008 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #include "aes.h" #ifdef K5_BUILTIN_AES /* * Private per-key data to cache after first generation. We don't * want to mess with the imported AES implementation too much, so * we'll just use two copies of its context, one for encryption and * one for decryption, and use the #rounds field as a flag for whether * we've initialized each half. */ struct aes_key_info_cache { aes_encrypt_ctx enc_ctx; aes_decrypt_ctx dec_ctx; krb5_boolean aesni; }; #define CACHE(X) ((struct aes_key_info_cache *)((X)->cache)) #ifdef AESNI /* Use AES-NI instructions (via assembly functions) when possible. */ #include struct aes_data { unsigned char *in_block; unsigned char *out_block; uint32_t *expanded_key; unsigned char *iv; size_t num_blocks; }; void k5_iEncExpandKey128(unsigned char *key, uint32_t *expanded_key); void k5_iEncExpandKey256(unsigned char *key, uint32_t *expanded_key); void k5_iDecExpandKey256(unsigned char *key, uint32_t *expanded_key); void k5_iDecExpandKey128(unsigned char *key, uint32_t *expanded_key); void k5_iEnc128_CBC(struct aes_data *data); void k5_iDec128_CBC(struct aes_data *data); void k5_iEnc256_CBC(struct aes_data *data); void k5_iDec256_CBC(struct aes_data *data); static krb5_boolean aesni_supported_by_cpu(void) { unsigned int a, b, c, d; return __get_cpuid(1, &a, &b, &c, &d) && (c & (1 << 25)); } static inline krb5_boolean aesni_supported(krb5_key key) { return CACHE(key)->aesni; } static void aesni_expand_enc_key(krb5_key key) { struct aes_key_info_cache *cache = CACHE(key); if (key->keyblock.length == 16) k5_iEncExpandKey128(key->keyblock.contents, cache->enc_ctx.ks); else k5_iEncExpandKey256(key->keyblock.contents, cache->enc_ctx.ks); cache->enc_ctx.inf.l = 1; } static void aesni_expand_dec_key(krb5_key key) { struct aes_key_info_cache *cache = CACHE(key); if (key->keyblock.length == 16) k5_iDecExpandKey128(key->keyblock.contents, cache->dec_ctx.ks); else k5_iDecExpandKey256(key->keyblock.contents, cache->dec_ctx.ks); cache->dec_ctx.inf.l = 1; } static inline void aesni_enc(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv) { struct aes_key_info_cache *cache = CACHE(key); struct aes_data d; d.in_block = data; d.out_block = data; d.expanded_key = cache->enc_ctx.ks; d.iv = iv; d.num_blocks = nblocks; if (key->keyblock.length == 16) k5_iEnc128_CBC(&d); else k5_iEnc256_CBC(&d); } static inline void aesni_dec(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv) { struct aes_key_info_cache *cache = CACHE(key); struct aes_data d; d.in_block = data; d.out_block = data; d.expanded_key = cache->dec_ctx.ks; d.iv = iv; d.num_blocks = nblocks; if (key->keyblock.length == 16) k5_iDec128_CBC(&d); else k5_iDec256_CBC(&d); } #else /* not AESNI */ #define aesni_supported_by_cpu() FALSE #define aesni_supported(key) FALSE #define aesni_expand_enc_key(key) #define aesni_expand_dec_key(key) #define aesni_enc(key, data, nblocks, iv) #define aesni_dec(key, data, nblocks, iv) #endif /* out = out ^ in */ static inline void xorblock(const unsigned char *in, unsigned char *out) { size_t q; for (q = 0; q < AES_BLOCK_SIZE; q += 4) store_32_n(load_32_n(out + q) ^ load_32_n(in + q), out + q); } static inline krb5_error_code init_key_cache(krb5_key key) { if (key->cache != NULL) return 0; key->cache = malloc(sizeof(struct aes_key_info_cache)); if (key->cache == NULL) return ENOMEM; CACHE(key)->enc_ctx.inf.l = CACHE(key)->dec_ctx.inf.l = 0; CACHE(key)->aesni = aesni_supported_by_cpu(); return 0; } static inline void expand_enc_key(krb5_key key) { if (CACHE(key)->enc_ctx.inf.l != 0) return; if (aesni_supported(key)) aesni_expand_enc_key(key); else if (aes_encrypt_key(key->keyblock.contents, key->keyblock.length, &CACHE(key)->enc_ctx) != EXIT_SUCCESS) abort(); } static inline void expand_dec_key(krb5_key key) { if (CACHE(key)->dec_ctx.inf.l != 0) return; if (aesni_supported(key)) aesni_expand_dec_key(key); else if (aes_decrypt_key(key->keyblock.contents, key->keyblock.length, &CACHE(key)->dec_ctx) != EXIT_SUCCESS) abort(); } /* CBC encrypt nblocks blocks of data in place, using and updating iv. */ static inline void cbc_enc(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv) { if (aesni_supported(key)) { aesni_enc(key, data, nblocks, iv); return; } for (; nblocks > 0; nblocks--, data += AES_BLOCK_SIZE) { xorblock(iv, data); if (aes_encrypt(data, data, &CACHE(key)->enc_ctx) != EXIT_SUCCESS) abort(); memcpy(iv, data, AES_BLOCK_SIZE); } } /* CBC decrypt nblocks blocks of data in place, using and updating iv. */ static inline void cbc_dec(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv) { unsigned char last_cipherblock[AES_BLOCK_SIZE]; if (aesni_supported(key)) { aesni_dec(key, data, nblocks, iv); return; } assert(nblocks > 0); data += (nblocks - 1) * AES_BLOCK_SIZE; memcpy(last_cipherblock, data, AES_BLOCK_SIZE); for (; nblocks > 0; nblocks--, data -= AES_BLOCK_SIZE) { if (aes_decrypt(data, data, &CACHE(key)->dec_ctx) != EXIT_SUCCESS) abort(); xorblock(nblocks == 1 ? iv : data - AES_BLOCK_SIZE, data); } memcpy(iv, last_cipherblock, AES_BLOCK_SIZE); } krb5_error_code krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { unsigned char iv[AES_BLOCK_SIZE], block[AES_BLOCK_SIZE]; unsigned char blockN2[AES_BLOCK_SIZE], blockN1[AES_BLOCK_SIZE]; size_t input_length, nblocks, ncontig; struct iov_cursor cursor; if (init_key_cache(key)) return ENOMEM; expand_enc_key(key); k5_iov_cursor_init(&cursor, data, num_data, AES_BLOCK_SIZE, FALSE); input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE; if (nblocks == 1) { k5_iov_cursor_get(&cursor, block); memset(iv, 0, AES_BLOCK_SIZE); cbc_enc(key, block, 1, iv); k5_iov_cursor_put(&cursor, block); return 0; } if (ivec != NULL) memcpy(iv, ivec->data, AES_BLOCK_SIZE); else memset(iv, 0, AES_BLOCK_SIZE); while (nblocks > 2) { ncontig = iov_cursor_contig_blocks(&cursor); if (ncontig > 0) { /* Encrypt a series of contiguous blocks in place if we can, but * don't touch the last two blocks. */ ncontig = (ncontig > nblocks - 2) ? nblocks - 2 : ncontig; cbc_enc(key, iov_cursor_ptr(&cursor), ncontig, iv); iov_cursor_advance(&cursor, ncontig); nblocks -= ncontig; } else { k5_iov_cursor_get(&cursor, block); cbc_enc(key, block, 1, iv); k5_iov_cursor_put(&cursor, block); nblocks--; } } /* Encrypt the last two blocks and put them back in reverse order, possibly * truncating the encrypted second-to-last block. */ k5_iov_cursor_get(&cursor, blockN2); k5_iov_cursor_get(&cursor, blockN1); cbc_enc(key, blockN2, 1, iv); cbc_enc(key, blockN1, 1, iv); k5_iov_cursor_put(&cursor, blockN1); k5_iov_cursor_put(&cursor, blockN2); if (ivec != NULL) memcpy(ivec->data, iv, AES_BLOCK_SIZE); return 0; } krb5_error_code krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { unsigned char iv[AES_BLOCK_SIZE], dummy_iv[AES_BLOCK_SIZE]; unsigned char block[AES_BLOCK_SIZE]; unsigned char blockN2[AES_BLOCK_SIZE], blockN1[AES_BLOCK_SIZE]; size_t input_length, last_len, nblocks, ncontig; struct iov_cursor cursor; if (init_key_cache(key)) return ENOMEM; expand_dec_key(key); k5_iov_cursor_init(&cursor, data, num_data, AES_BLOCK_SIZE, FALSE); input_length = iov_total_length(data, num_data, FALSE); nblocks = (input_length + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE; last_len = input_length - (nblocks - 1) * AES_BLOCK_SIZE; if (nblocks == 1) { k5_iov_cursor_get(&cursor, block); memset(iv, 0, AES_BLOCK_SIZE); cbc_dec(key, block, 1, iv); k5_iov_cursor_put(&cursor, block); return 0; } if (ivec != NULL) memcpy(iv, ivec->data, AES_BLOCK_SIZE); else memset(iv, 0, AES_BLOCK_SIZE); while (nblocks > 2) { ncontig = iov_cursor_contig_blocks(&cursor); if (ncontig > 0) { /* Decrypt a series of contiguous blocks in place if we can, but * don't touch the last two blocks. */ ncontig = (ncontig > nblocks - 2) ? nblocks - 2 : ncontig; cbc_dec(key, iov_cursor_ptr(&cursor), ncontig, iv); iov_cursor_advance(&cursor, ncontig); nblocks -= ncontig; } else { k5_iov_cursor_get(&cursor, block); cbc_dec(key, block, 1, iv); k5_iov_cursor_put(&cursor, block); nblocks--; } } /* Get the last two ciphertext blocks. Save the first as the new iv. */ k5_iov_cursor_get(&cursor, blockN2); k5_iov_cursor_get(&cursor, blockN1); if (ivec != NULL) memcpy(ivec->data, blockN2, AES_BLOCK_SIZE); /* Decrypt the second-to-last ciphertext block, using the final ciphertext * block as the CBC IV. This produces the final plaintext block. */ memcpy(dummy_iv, blockN1, sizeof(dummy_iv)); cbc_dec(key, blockN2, 1, dummy_iv); /* Use the final bits of the decrypted plaintext to pad the last ciphertext * block, and decrypt it to produce the second-to-last plaintext block. */ memcpy(blockN1 + last_len, blockN2 + last_len, AES_BLOCK_SIZE - last_len); cbc_dec(key, blockN1, 1, iv); /* Put the last two plaintext blocks back into the iovec. */ k5_iov_cursor_put(&cursor, blockN1); k5_iov_cursor_put(&cursor, blockN2); return 0; } static krb5_error_code aes_init_state(const krb5_keyblock *key, krb5_keyusage usage, krb5_data *state) { state->length = 16; state->data = malloc(16); if (state->data == NULL) return ENOMEM; memset(state->data, 0, state->length); return 0; } static void aes_key_cleanup(krb5_key key) { zapfree(key->cache, sizeof(struct aes_key_info_cache)); } const struct krb5_enc_provider krb5int_enc_aes128 = { 16, 16, 16, krb5int_aes_encrypt, krb5int_aes_decrypt, NULL, aes_init_state, krb5int_default_free_state, aes_key_cleanup }; const struct krb5_enc_provider krb5int_enc_aes256 = { 16, 32, 32, krb5int_aes_encrypt, krb5int_aes_decrypt, NULL, aes_init_state, krb5int_default_free_state, aes_key_cleanup }; #endif /* K5_BUILTIN_AES */ krb5-1.22.1/src/lib/crypto/builtin/hmac.c0000664000175000017500000001056615051422640017750 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" #ifdef K5_BUILTIN_HMAC /* * Because our built-in HMAC implementation doesn't need to invoke any * encryption or keyed hash functions, it is simplest to define it in terms of * keyblocks, and then supply a simple wrapper for the "normal" krb5_key-using * interfaces. The keyblock interfaces are useful for code which creates * intermediate keyblocks. */ /* * The HMAC transform looks like: * * H(K XOR opad, H(K XOR ipad, text)) * * where H is a cryptographic hash * K is an n byte key * ipad is the byte 0x36 repeated blocksize times * opad is the byte 0x5c repeated blocksize times * and text is the data being protected */ krb5_error_code krb5int_hmac_keyblock(const struct krb5_hash_provider *hash, const krb5_keyblock *keyblock, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { unsigned char *xorkey = NULL, *ihash = NULL; unsigned int i; krb5_crypto_iov *ihash_iov = NULL, ohash_iov[2]; krb5_data hashout; krb5_error_code ret; if (keyblock->length > hash->blocksize) return KRB5_CRYPTO_INTERNAL; if (output->length < hash->hashsize) return KRB5_BAD_MSIZE; /* Allocate space for the xor key, hash input vector, and inner hash */ xorkey = k5alloc(hash->blocksize, &ret); if (xorkey == NULL) goto cleanup; ihash = k5alloc(hash->hashsize, &ret); if (ihash == NULL) goto cleanup; ihash_iov = k5calloc(num_data + 1, sizeof(krb5_crypto_iov), &ret); if (ihash_iov == NULL) goto cleanup; /* Create the inner padded key. */ memset(xorkey, 0x36, hash->blocksize); for (i = 0; i < keyblock->length; i++) xorkey[i] ^= keyblock->contents[i]; /* Compute the inner hash over the inner key and input data. */ ihash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA; ihash_iov[0].data = make_data(xorkey, hash->blocksize); memcpy(ihash_iov + 1, data, num_data * sizeof(krb5_crypto_iov)); hashout = make_data(ihash, hash->hashsize); ret = hash->hash(ihash_iov, num_data + 1, &hashout); if (ret != 0) goto cleanup; /* Create the outer padded key. */ memset(xorkey, 0x5c, hash->blocksize); for (i = 0; i < keyblock->length; i++) xorkey[i] ^= keyblock->contents[i]; /* Compute the outer hash over the outer key and inner hash value. */ ohash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA; ohash_iov[0].data = make_data(xorkey, hash->blocksize); ohash_iov[1].flags = KRB5_CRYPTO_TYPE_DATA; ohash_iov[1].data = make_data(ihash, hash->hashsize); output->length = hash->hashsize; ret = hash->hash(ohash_iov, 2, output); if (ret != 0) memset(output->data, 0, output->length); cleanup: zapfree(xorkey, hash->blocksize); zapfree(ihash, hash->hashsize); free(ihash_iov); return ret; } krb5_error_code krb5int_hmac(const struct krb5_hash_provider *hash, krb5_key key, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { return krb5int_hmac_keyblock(hash, &key->keyblock, data, num_data, output); } #endif /* K5_BUILTIN_HMAC */ krb5-1.22.1/src/lib/crypto/builtin/md4/0000775000175000017500000000000015051422640017350 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/builtin/md4/md4.c0000664000175000017500000001774415051422640020215 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/md4/md4.c */ /* * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. * * License to copy and use this software is granted provided that * it is identified as the "RSA Data Security, Inc. MD4 Message * Digest Algorithm" in all material mentioning or referencing this * software or this function. * * License is also granted to make and use derivative works * provided that such works are identified as "derived from the RSA * Data Security, Inc. MD4 Message Digest Algorithm" in all * material mentioning or referencing the derived work. * * RSA Data Security, Inc. makes no representations concerning * either the merchantability of this software or the suitability * of this software for any particular purpose. It is provided "as * is" without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. */ /* ********************************************************************** ** md4.c ** ** RSA Data Security, Inc. MD4 Message Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** ********************************************************************** */ #include "crypto_int.h" #include "rsa-md4.h" #ifdef K5_BUILTIN_MD4 /* forward declaration */ static void Transform (krb5_ui_4 *, krb5_ui_4 *); static const unsigned char PADDING[64] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* F, G and H are basic MD4 functions: selection, majority, parity */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) /* ROTATE_LEFT rotates x left n bits */ #define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffff) | ((x) >> (32-(n)))) /* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */ /* Rotation is separate from addition to prevent recomputation */ #define FF(a, b, c, d, x, s) \ {(a) += F ((b), (c), (d)) + (x); \ (a) &= 0xffffffff; \ (a) = ROTATE_LEFT ((a), (s));} #define GG(a, b, c, d, x, s) \ {(a) += G ((b), (c), (d)) + (x) + 013240474631UL; \ (a) &= 0xffffffff; \ (a) = ROTATE_LEFT ((a), (s));} #define HH(a, b, c, d, x, s) \ {(a) += H ((b), (c), (d)) + (x) + 015666365641UL; \ (a) &= 0xffffffff; \ (a) = ROTATE_LEFT ((a), (s));} void krb5int_MD4Init (krb5_MD4_CTX *mdContext) { mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0; /* Load magic initialization constants. */ mdContext->buf[0] = 0x67452301UL; mdContext->buf[1] = 0xefcdab89UL; mdContext->buf[2] = 0x98badcfeUL; mdContext->buf[3] = 0x10325476UL; } void krb5int_MD4Update (krb5_MD4_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen) { krb5_ui_4 in[16]; int mdi; unsigned int i, ii; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* update number of bits */ if ((mdContext->i[0] + ((krb5_ui_4)inLen << 3)) < mdContext->i[0]) mdContext->i[1]++; mdContext->i[0] += ((krb5_ui_4)inLen << 3); mdContext->i[1] += ((krb5_ui_4)inLen >> 29); while (inLen--) { /* add new character to buffer, increment mdi */ mdContext->in[mdi++] = *inBuf++; /* transform if necessary */ if (mdi == 0x40) { for (i = 0, ii = 0; i < 16; i++, ii += 4) { in[i] = load_32_le(mdContext->in+ii); } Transform (mdContext->buf, in); mdi = 0; } } } void krb5int_MD4Final (krb5_MD4_CTX *mdContext) { krb5_ui_4 in[16]; int mdi; unsigned int i, ii; unsigned int padLen; /* save number of bits */ in[14] = mdContext->i[0]; in[15] = mdContext->i[1]; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* pad out to 56 mod 64 */ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); krb5int_MD4Update (mdContext, PADDING, padLen); /* append length in bits and transform */ for (i = 0, ii = 0; i < 14; i++, ii += 4) in[i] = load_32_le(mdContext->in+ii); Transform (mdContext->buf, in); /* store buffer in digest */ for (i = 0, ii = 0; i < 4; i++, ii += 4) { store_32_le(mdContext->buf[i], mdContext->digest+ii); } } /* Basic MD4 step. Transform buf based on in. */ static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in) { krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; #if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO) int i; #define ROTATE { krb5_ui_4 temp; temp = d, d = c, c = b, b = a, a = temp; } for (i = 0; i < 16; i++) { static const unsigned char round1consts[] = { 3, 7, 11, 19, }; FF (a, b, c, d, in[i], round1consts[i%4]); ROTATE; } for (i = 0; i < 16; i++) { static const unsigned char round2indices[] = { 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15 }; static const unsigned char round2consts[] = { 3, 5, 9, 13 }; GG (a, b, c, d, in[round2indices[i]], round2consts[i%4]); ROTATE; } for (i = 0; i < 16; i++) { static const unsigned char round3indices[] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }; static const unsigned char round3consts[] = { 3, 9, 11, 15 }; HH (a, b, c, d, in[round3indices[i]], round3consts[i%4]); ROTATE; } #else /* Round 1 */ FF (a, b, c, d, in[ 0], 3); FF (d, a, b, c, in[ 1], 7); FF (c, d, a, b, in[ 2], 11); FF (b, c, d, a, in[ 3], 19); FF (a, b, c, d, in[ 4], 3); FF (d, a, b, c, in[ 5], 7); FF (c, d, a, b, in[ 6], 11); FF (b, c, d, a, in[ 7], 19); FF (a, b, c, d, in[ 8], 3); FF (d, a, b, c, in[ 9], 7); FF (c, d, a, b, in[10], 11); FF (b, c, d, a, in[11], 19); FF (a, b, c, d, in[12], 3); FF (d, a, b, c, in[13], 7); FF (c, d, a, b, in[14], 11); FF (b, c, d, a, in[15], 19); /* Round 2 */ GG (a, b, c, d, in[ 0], 3); GG (d, a, b, c, in[ 4], 5); GG (c, d, a, b, in[ 8], 9); GG (b, c, d, a, in[12], 13); GG (a, b, c, d, in[ 1], 3); GG (d, a, b, c, in[ 5], 5); GG (c, d, a, b, in[ 9], 9); GG (b, c, d, a, in[13], 13); GG (a, b, c, d, in[ 2], 3); GG (d, a, b, c, in[ 6], 5); GG (c, d, a, b, in[10], 9); GG (b, c, d, a, in[14], 13); GG (a, b, c, d, in[ 3], 3); GG (d, a, b, c, in[ 7], 5); GG (c, d, a, b, in[11], 9); GG (b, c, d, a, in[15], 13); /* Round 3 */ HH (a, b, c, d, in[ 0], 3); HH (d, a, b, c, in[ 8], 9); HH (c, d, a, b, in[ 4], 11); HH (b, c, d, a, in[12], 15); HH (a, b, c, d, in[ 2], 3); HH (d, a, b, c, in[10], 9); HH (c, d, a, b, in[ 6], 11); HH (b, c, d, a, in[14], 15); HH (a, b, c, d, in[ 1], 3); HH (d, a, b, c, in[ 9], 9); HH (c, d, a, b, in[ 5], 11); HH (b, c, d, a, in[13], 15); HH (a, b, c, d, in[ 3], 3); HH (d, a, b, c, in[11], 9); HH (c, d, a, b, in[ 7], 11); HH (b, c, d, a, in[15], 15); #endif buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } /* ********************************************************************** ** End of md4.c ** ******************************* (cut) ******************************** */ #endif /* K5_BUILTIN_MD4 */ krb5-1.22.1/src/lib/crypto/builtin/md4/Makefile.in0000664000175000017500000000073015051422640021415 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)builtin$(S)md4 BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES=-I$(srcdir)/../../krb $(CRYPTO_IMPL_CFLAGS) ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = builtin\md4 ##DOS##OBJFILE = ..\..\$(OUTPRE)md4.lst STLIBOBJS= md4.o OBJS= $(OUTPRE)md4.$(OBJEXT) SRCS= $(srcdir)/md4.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs includes: depend depend: $(SRCS) check-unix: check-windows: clean: clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/crypto/builtin/md4/deps0000664000175000017500000000144115051422640020226 0ustar ghudsonghudson# # Generated makefile dependencies follow. # md4.so md4.po $(OUTPRE)md4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ md4.c rsa-md4.h krb5-1.22.1/src/lib/crypto/builtin/md4/rsa-md4.h0000664000175000017500000000747015051422640021000 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/builtin/md4/rsa-md4.h */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. * * License to copy and use this software is granted provided that * it is identified as the "RSA Data Security, Inc. MD4 Message * Digest Algorithm" in all material mentioning or referencing this * software or this function. * * License is also granted to make and use derivative works * provided that such works are identified as "derived from the RSA * Data Security, Inc. MD4 Message Digest Algorithm" in all * material mentioning or referencing the derived work. * * RSA Data Security, Inc. makes no representations concerning * either the merchantability of this software or the suitability * of this software for any particular purpose. It is provided "as * is" without express or implied warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. */ /* RSA MD4 header file, with Kerberos/STDC additions. */ #ifndef __KRB5_RSA_MD4_H__ #define __KRB5_RSA_MD4_H__ #ifdef unicos61 #include #endif /* unicos61 */ /* 16 u_char's in the digest */ #define RSA_MD4_CKSUM_LENGTH 16 /* des blocksize is 8, so this works nicely... */ #define OLD_RSA_MD4_DES_CKSUM_LENGTH 16 #define NEW_RSA_MD4_DES_CKSUM_LENGTH 24 #define RSA_MD4_DES_CONFOUND_LENGTH 8 /* ********************************************************************** ** md4.h -- Header file for implementation of MD4 ** ** RSA Data Security, Inc. MD4 Message Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** ********************************************************************** */ /* Data structure for MD4 (Message Digest) computation */ typedef struct { krb5_ui_4 i[2]; /* number of _bits_ handled mod 2^64 */ krb5_ui_4 buf[4]; /* scratch buffer */ unsigned char in[64]; /* input buffer */ unsigned char digest[16]; /* actual digest after MD4Final call */ } krb5_MD4_CTX; extern void krb5int_MD4Init(krb5_MD4_CTX *); extern void krb5int_MD4Update(krb5_MD4_CTX *, const unsigned char *, unsigned int); extern void krb5int_MD4Final(krb5_MD4_CTX *); /* ********************************************************************** ** End of md4.h ** ******************************* (cut) ******************************** */ #endif /* __KRB5_RSA_MD4_H__ */ krb5-1.22.1/src/lib/crypto/krb/0000775000175000017500000000000015051422640015774 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/crypto/krb/cf2.c0000664000175000017500000001302715051422640016615 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/cf2.c */ /* * Copyright (C) 2009, 2015 by the Massachusetts Institute of Technology. All * rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Implement KRB_FX_CF2 function per draft-ietf-krb-wg-preauth-framework-09. * Take two keys and two pepper strings as input and return a combined key. */ #include "crypto_int.h" #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif krb5_error_code KRB5_CALLCONV krb5_c_prfplus(krb5_context context, const krb5_keyblock *k, const krb5_data *input, krb5_data *output) { krb5_error_code ret; krb5_data prf_in = empty_data(), prf_out = empty_data(); size_t prflen, nblocks, i; /* Calculate the number of PRF invocations we will need. */ ret = krb5_c_prf_length(context, k->enctype, &prflen); if (ret) return ret; nblocks = (output->length + prflen - 1)/ prflen; if (nblocks > 255) return E2BIG; /* Allocate PRF input and output buffers. */ ret = alloc_data(&prf_in, input->length + 1); if (ret) goto cleanup; ret = alloc_data(&prf_out, prflen); if (ret) goto cleanup; /* Concatenate PRF(k, 1||input) || PRF(k, 2||input) || ... to produce the * desired number of bytes. */ memcpy(&prf_in.data[1], input->data, input->length); for (i = 0; i < nblocks; i++) { prf_in.data[0] = i + 1; ret = krb5_c_prf(context, k, &prf_in, &prf_out); if (ret) goto cleanup; memcpy(&output->data[i * prflen], prf_out.data, MIN(prflen, output->length - i * prflen)); } cleanup: zapfree(prf_out.data, prf_out.length); zapfree(prf_in.data, prf_in.length); return ret; } krb5_error_code KRB5_CALLCONV krb5_c_derive_prfplus(krb5_context context, const krb5_keyblock *k, const krb5_data *input, krb5_enctype enctype, krb5_keyblock **out) { krb5_error_code ret; const struct krb5_keytypes *ktp; krb5_data rnd = empty_data(); krb5_keyblock *kb = NULL; *out = NULL; ktp = find_enctype((enctype == ENCTYPE_NULL) ? k->enctype : enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; /* Generate enough pseudo-random bytes for the random-to-key function. */ ret = alloc_data(&rnd, ktp->enc->keybytes); if (ret) goto cleanup; ret = krb5_c_prfplus(context, k, input, &rnd); if (ret) goto cleanup; /* Generate a key from the pseudo-random bytes. */ ret = krb5int_c_init_keyblock(context, ktp->etype, ktp->enc->keylength, &kb); if (ret) goto cleanup; ret = (*ktp->rand2key)(&rnd, kb); if (ret) goto cleanup; *out = kb; kb = NULL; cleanup: zapfree(rnd.data, rnd.length); krb5int_c_free_keyblock(context, kb); return ret; } krb5_error_code KRB5_CALLCONV krb5_c_fx_cf2_simple(krb5_context context, const krb5_keyblock *k1, const char *pepper1, const krb5_keyblock *k2, const char *pepper2, krb5_keyblock **out) { krb5_error_code ret; const struct krb5_keytypes *ktp = NULL; const krb5_data pepper1_data = string2data((char *)pepper1); const krb5_data pepper2_data = string2data((char *)pepper2); krb5_data prf1 = empty_data(), prf2 = empty_data(); unsigned int i; krb5_keyblock *kb = NULL; *out = NULL; ktp = find_enctype(k1->enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; /* Generate PRF+(k1, pepper1) and PRF+(k2, kepper2). */ ret = alloc_data(&prf1, ktp->enc->keybytes); if (ret) goto cleanup; ret = krb5_c_prfplus(context, k1, &pepper1_data, &prf1); if (ret) goto cleanup; ret = alloc_data(&prf2, ktp->enc->keybytes); if (ret) goto cleanup; ret = krb5_c_prfplus(context, k2, &pepper2_data, &prf2); if (ret) goto cleanup; /* Compute the XOR of the two PRF+ values and generate a key. */ for (i = 0; i < prf1.length; i++) prf1.data[i] ^= prf2.data[i]; ret = krb5int_c_init_keyblock(context, ktp->etype, ktp->enc->keylength, &kb); if (ret) goto cleanup; ret = (*ktp->rand2key)(&prf1, kb); if (ret) goto cleanup; *out = kb; kb = NULL; cleanup: zapfree(prf2.data, prf2.length); zapfree(prf1.data, prf1.length); krb5int_c_free_keyblock(context, kb); return ret; } krb5-1.22.1/src/lib/crypto/krb/encrypt_length.c0000664000175000017500000000361015051422640021165 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_encrypt_length(krb5_context context, krb5_enctype enctype, size_t inputlen, size_t *length) { const struct krb5_keytypes *ktp; unsigned int header_len = 0, padding_len = 0, trailer_len = 0; ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; header_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_HEADER); padding_len = krb5int_c_padding_length(ktp, inputlen); trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER); *length = header_len + inputlen + padding_len + trailer_len; return 0; } krb5-1.22.1/src/lib/crypto/krb/mandatory_sumtype.c0000664000175000017500000000313715051422640021730 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2003 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code krb5int_c_mandatory_cksumtype(krb5_context ctx, krb5_enctype etype, krb5_cksumtype *cksumtype) { const struct krb5_keytypes *ktp; ktp = find_enctype(etype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; *cksumtype = ktp->required_ctype; return 0; } krb5-1.22.1/src/lib/crypto/krb/random_to_key.c0000664000175000017500000000646615051422640021006 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * COPYRIGHT (c) 2006 * The Regents of the University of Michigan * ALL RIGHTS RESERVED * * Permission is granted to use, copy, create derivative works * and redistribute this software and such derivative works * for any purpose, so long as the name of The University of * Michigan is not used in any advertising or publicity * pertaining to the use of distribution of this software * without specific, written prior authorization. If the * above copyright notice or any other identification of the * University of Michigan is included in any copy of any * portion of this software, then the disclaimer below must * also be included. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF * SUCH DAMAGES. */ /* * Create a key given random data. It is assumed that random_key has * already been initialized and random_key->contents have been allocated * with the correct length. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_random_to_key(krb5_context context, krb5_enctype enctype, krb5_data *random_data, krb5_keyblock *random_key) { krb5_error_code ret; const struct krb5_keytypes *ktp; if (random_data == NULL || random_key == NULL || random_key->contents == NULL) return EINVAL; ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; if (random_key->length != ktp->enc->keylength) return KRB5_BAD_KEYSIZE; ret = ktp->rand2key(random_data, random_key); if (ret) zap(random_key->contents, random_key->length); return ret; } krb5_error_code k5_rand2key_direct(const krb5_data *randombits, krb5_keyblock *keyblock) { if (randombits->length != keyblock->length) return KRB5_CRYPTO_INTERNAL; keyblock->magic = KV5M_KEYBLOCK; memcpy(keyblock->contents, randombits->data, randombits->length); return 0; } static inline void eighth_byte(unsigned char *b) { b[7] = (((b[0] & 1) << 1) | ((b[1] & 1) << 2) | ((b[2] & 1) << 3) | ((b[3] & 1) << 4) | ((b[4] & 1) << 5) | ((b[5] & 1) << 6) | ((b[6] & 1) << 7)); } krb5_error_code k5_rand2key_des3(const krb5_data *randombits, krb5_keyblock *keyblock) { int i; if (randombits->length != 21) return KRB5_CRYPTO_INTERNAL; keyblock->magic = KV5M_KEYBLOCK; /* Take the seven bytes, move them around into the top 7 bits of the * 8 key bytes, then compute the parity bits. Do this three times. */ for (i = 0; i < 3; i++) { memcpy(&keyblock->contents[i * 8], &randombits->data[i * 7], 7); eighth_byte(&keyblock->contents[i * 8]); k5_des_fixup_key_parity(&keyblock->contents[i * 8]); } return 0; } krb5-1.22.1/src/lib/crypto/krb/string_to_cksumtype.c0000664000175000017500000000403515051422640022256 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_string_to_cksumtype(char *string, krb5_cksumtype *cksumtypep) { unsigned int i, j; const char *alias; const struct krb5_cksumtypes *ctp; for (i=0; iname, string) == 0) { *cksumtypep = ctp->ctype; return 0; } #define MAX_ALIASES (sizeof(ctp->aliases) / sizeof(ctp->aliases[0])) for (j = 0; j < MAX_ALIASES; j++) { alias = ctp->aliases[j]; if (alias == NULL) break; if (strcasecmp(alias, string) == 0) { *cksumtypep = ctp->ctype; return 0; } } } return EINVAL; } krb5-1.22.1/src/lib/crypto/krb/prng.c0000664000175000017500000001147415051422640017115 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2001, 2002, 2004, 2007, 2008, 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_random_seed(krb5_context context, krb5_data *data) { return krb5_c_random_add_entropy(context, KRB5_C_RANDSOURCE_OLDAPI, data); } /* Routines to get entropy from the OS. */ #if defined(_WIN32) static krb5_boolean get_os_entropy(unsigned char *buf, size_t len) { krb5_boolean result; HCRYPTPROV provider; if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return FALSE; result = CryptGenRandom(provider, len, buf); (void)CryptReleaseContext(provider, 0); return result; } #else /* not Windows */ #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_SYS_RANDOM_H #include #endif #ifdef __linux__ #include #endif /* __linux__ */ /* Open device, ensure that it is not a regular file, and read entropy. Return * true on success, false on failure. */ static krb5_boolean read_entropy_from_device(const char *device, unsigned char *buf, size_t len) { struct stat sb; int fd; unsigned char *bp; size_t left; ssize_t count; krb5_boolean result = FALSE; fd = open(device, O_RDONLY); if (fd == -1) return FALSE; set_cloexec_fd(fd); if (fstat(fd, &sb) == -1 || S_ISREG(sb.st_mode)) goto cleanup; for (bp = buf, left = len; left > 0;) { count = read(fd, bp, left); if (count <= 0) goto cleanup; left -= count; bp += count; } result = TRUE; cleanup: close(fd); return result; } static krb5_boolean get_os_entropy(unsigned char *buf, size_t len) { #if defined(HAVE_GETENTROPY) int r; size_t seg; /* getentropy() has a maximum length of 256. */ while (len > 0) { seg = (len > 256) ? 256 : len; r = getentropy(buf, seg); if (r != 0) break; len -= seg; buf += seg; } if (len == 0) return TRUE; #elif defined(__linux__) && defined(SYS_getrandom) /* * Linux added SYS_getrandom in 3.17 (2014), but glibc did not have a * wrapper until 2.25 (2017). This block can be deleted when that interval * is far in the past, along with the conditional include of * above. */ int r; while (len > 0) { /* * Pull from the /dev/urandom pool, but require it to have been seeded. * This ensures strong randomness while only blocking during first * system boot. */ errno = 0; r = syscall(SYS_getrandom, buf, len, 0); if (r <= 0) { if (errno == EINTR) continue; /* ENOSYS or other unrecoverable failure */ break; } len -= r; buf += r; } if (len == 0) return TRUE; #endif /* defined(__linux__) && defined(SYS_getrandom) */ return read_entropy_from_device("/dev/urandom", buf, len); } #endif /* not Windows */ krb5_error_code KRB5_CALLCONV krb5_c_random_make_octets(krb5_context context, krb5_data *outdata) { krb5_boolean res; res = get_os_entropy((uint8_t *)outdata->data, outdata->length); return res ? 0 : KRB5_CRYPTO_INTERNAL; } krb5_error_code KRB5_CALLCONV krb5_c_random_add_entropy(krb5_context context, unsigned int randsource, const krb5_data *indata) { return 0; } krb5_error_code KRB5_CALLCONV krb5_c_random_os_entropy(krb5_context context, int strong, int *success) { *success = 0; return 0; } krb5-1.22.1/src/lib/crypto/krb/enc_dk_cmac.c0000664000175000017500000001413115051422640020346 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/enc_dk_cmac.c - Derived-key enctype functions using CMAC */ /* * Copyright 2008, 2009, 2010 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ /* AEAD */ unsigned int krb5int_camellia_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type) { switch (type) { case KRB5_CRYPTO_TYPE_HEADER: return ktp->enc->block_size; case KRB5_CRYPTO_TYPE_PADDING: return 0; case KRB5_CRYPTO_TYPE_TRAILER: case KRB5_CRYPTO_TYPE_CHECKSUM: return ktp->enc->block_size; default: assert(0 && "bad type passed to krb5int_camellia_crypto_length"); return 0; } } /* Derive encryption and integrity keys for CMAC-using enctypes. */ static krb5_error_code derive_keys(const struct krb5_enc_provider *enc, krb5_key key, krb5_keyusage usage, krb5_key *ke_out, krb5_key *ki_out) { krb5_error_code ret; unsigned char buf[K5CLENGTH]; krb5_data constant = make_data(buf, K5CLENGTH); krb5_key ke, ki; *ke_out = *ki_out = NULL; /* Derive the encryption key. */ store_32_be(usage, buf); buf[4] = 0xAA; ret = krb5int_derive_key(enc, NULL, key, &ke, &constant, DERIVE_SP800_108_CMAC); if (ret != 0) return ret; /* Derive the integrity key. */ buf[4] = 0x55; ret = krb5int_derive_key(enc, NULL, key, &ki, &constant, DERIVE_SP800_108_CMAC); if (ret != 0) { krb5_k_free_key(NULL, ke); return ret; } *ke_out = ke; *ki_out = ki; return 0; } krb5_error_code krb5int_dk_cmac_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { const struct krb5_enc_provider *enc = ktp->enc; krb5_error_code ret; krb5_crypto_iov *header, *trailer, *padding; krb5_key ke = NULL, ki = NULL; /* E(Confounder | Plaintext | Pad) | Checksum */ /* Validate header and trailer lengths, and zero out padding length. */ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); if (header == NULL || header->data.length < enc->block_size) return KRB5_BAD_MSIZE; trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); if (trailer == NULL || trailer->data.length < enc->block_size) return KRB5_BAD_MSIZE; padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING); if (padding != NULL) padding->data.length = 0; /* Derive the encryption and integrity keys. */ ret = derive_keys(enc, key, usage, &ke, &ki); if (ret != 0) goto cleanup; /* Generate confounder. */ header->data.length = enc->block_size; ret = krb5_c_random_make_octets(NULL, &header->data); if (ret != 0) goto cleanup; /* Checksum the plaintext. */ ret = krb5int_cmac_checksum(enc, ki, data, num_data, &trailer->data); if (ret != 0) goto cleanup; /* Encrypt the plaintext (header | data | padding) */ ret = enc->encrypt(ke, ivec, data, num_data); if (ret != 0) goto cleanup; cleanup: krb5_k_free_key(NULL, ke); krb5_k_free_key(NULL, ki); return ret; } krb5_error_code krb5int_dk_cmac_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { const struct krb5_enc_provider *enc = ktp->enc; krb5_error_code ret; krb5_crypto_iov *header, *trailer; krb5_data cksum = empty_data(); krb5_key ke = NULL, ki = NULL; /* E(Confounder | Plaintext | Pad) | Checksum */ /* Validate header and trailer lengths. */ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); if (header == NULL || header->data.length != enc->block_size) return KRB5_BAD_MSIZE; trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); if (trailer == NULL || trailer->data.length != enc->block_size) return KRB5_BAD_MSIZE; /* Derive the encryption and integrity keys. */ ret = derive_keys(enc, key, usage, &ke, &ki); if (ret != 0) goto cleanup; /* Decrypt the plaintext (header | data | padding). */ ret = enc->decrypt(ke, ivec, data, num_data); if (ret != 0) goto cleanup; /* Verify the hash. */ ret = alloc_data(&cksum, enc->block_size); if (ret != 0) goto cleanup; ret = krb5int_cmac_checksum(enc, ki, data, num_data, &cksum); if (ret != 0) goto cleanup; if (k5_bcmp(cksum.data, trailer->data.data, enc->block_size) != 0) ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; cleanup: krb5_k_free_key(NULL, ke); krb5_k_free_key(NULL, ki); zapfree(cksum.data, cksum.length); return ret; } krb5-1.22.1/src/lib/crypto/krb/etypes.c0000664000175000017500000001373215051422640017457 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" /* these will be linear searched. if they ever get big, a binary search or hash table would be better, which means these would need to be sorted. An array would be more efficient, but that assumes that the keytypes are all near each other. I'd rather not make that assumption. */ /* Deprecations come from RFC 6649 and RFC 8249. */ const struct krb5_keytypes krb5int_enctypes_list[] = { { ENCTYPE_DES3_CBC_RAW, "des3-cbc-raw", { 0 }, "Triple DES cbc mode raw", &krb5int_enc_des3, NULL, 16, krb5int_raw_crypto_length, krb5int_raw_encrypt, krb5int_raw_decrypt, krb5int_dk_string_to_key, k5_rand2key_des3, NULL, /*PRF*/ 0, ETYPE_WEAK | ETYPE_DEPRECATED, 112 }, { ENCTYPE_DES3_CBC_SHA1, "des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" }, "Triple DES cbc mode with HMAC/sha1", &krb5int_enc_des3, &krb5int_hash_sha1, 16, krb5int_dk_crypto_length, krb5int_dk_encrypt, krb5int_dk_decrypt, krb5int_dk_string_to_key, k5_rand2key_des3, krb5int_dk_prf, CKSUMTYPE_HMAC_SHA1_DES3, ETYPE_DEPRECATED, 112 }, /* rc4-hmac uses a 128-bit key, but due to weaknesses in the RC4 cipher, we * consider its strength degraded and assign it an SSF value of 64. */ { ENCTYPE_ARCFOUR_HMAC, "arcfour-hmac", { "rc4-hmac", "arcfour-hmac-md5" }, "ArcFour with HMAC/md5", &krb5int_enc_arcfour, &krb5int_hash_md5, 20, krb5int_arcfour_crypto_length, krb5int_arcfour_encrypt, krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key, k5_rand2key_direct, krb5int_arcfour_prf, CKSUMTYPE_HMAC_MD5_ARCFOUR, ETYPE_DEPRECATED, 64 }, { ENCTYPE_ARCFOUR_HMAC_EXP, "arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" }, "Exportable ArcFour with HMAC/md5", &krb5int_enc_arcfour, &krb5int_hash_md5, 20, krb5int_arcfour_crypto_length, krb5int_arcfour_encrypt, krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key, k5_rand2key_direct, krb5int_arcfour_prf, CKSUMTYPE_HMAC_MD5_ARCFOUR, ETYPE_WEAK | ETYPE_DEPRECATED, 40 }, { ENCTYPE_AES128_CTS_HMAC_SHA1_96, "aes128-cts-hmac-sha1-96", { "aes128-cts", "aes128-sha1" }, "AES-128 CTS mode with 96-bit SHA-1 HMAC", &krb5int_enc_aes128, &krb5int_hash_sha1, 16, krb5int_aes_crypto_length, krb5int_dk_encrypt, krb5int_dk_decrypt, krb5int_aes_string_to_key, k5_rand2key_direct, krb5int_dk_prf, CKSUMTYPE_HMAC_SHA1_96_AES128, 0 /*flags*/, 128 }, { ENCTYPE_AES256_CTS_HMAC_SHA1_96, "aes256-cts-hmac-sha1-96", { "aes256-cts", "aes256-sha1" }, "AES-256 CTS mode with 96-bit SHA-1 HMAC", &krb5int_enc_aes256, &krb5int_hash_sha1, 16, krb5int_aes_crypto_length, krb5int_dk_encrypt, krb5int_dk_decrypt, krb5int_aes_string_to_key, k5_rand2key_direct, krb5int_dk_prf, CKSUMTYPE_HMAC_SHA1_96_AES256, 0 /*flags*/, 256 }, { ENCTYPE_CAMELLIA128_CTS_CMAC, "camellia128-cts-cmac", { "camellia128-cts" }, "Camellia-128 CTS mode with CMAC", &krb5int_enc_camellia128, NULL, 16, krb5int_camellia_crypto_length, krb5int_dk_cmac_encrypt, krb5int_dk_cmac_decrypt, krb5int_camellia_string_to_key, k5_rand2key_direct, krb5int_dk_cmac_prf, CKSUMTYPE_CMAC_CAMELLIA128, 0 /*flags*/, 128 }, { ENCTYPE_CAMELLIA256_CTS_CMAC, "camellia256-cts-cmac", { "camellia256-cts" }, "Camellia-256 CTS mode with CMAC", &krb5int_enc_camellia256, NULL, 16, krb5int_camellia_crypto_length, krb5int_dk_cmac_encrypt, krb5int_dk_cmac_decrypt, krb5int_camellia_string_to_key, k5_rand2key_direct, krb5int_dk_cmac_prf, CKSUMTYPE_CMAC_CAMELLIA256, 0 /*flags */, 256 }, { ENCTYPE_AES128_CTS_HMAC_SHA256_128, "aes128-cts-hmac-sha256-128", { "aes128-sha2" }, "AES-128 CTS mode with 128-bit SHA-256 HMAC", &krb5int_enc_aes128, &krb5int_hash_sha256, 32, krb5int_aes2_crypto_length, krb5int_etm_encrypt, krb5int_etm_decrypt, krb5int_aes2_string_to_key, k5_rand2key_direct, krb5int_aes2_prf, CKSUMTYPE_HMAC_SHA256_128_AES128, 0 /*flags*/, 128 }, { ENCTYPE_AES256_CTS_HMAC_SHA384_192, "aes256-cts-hmac-sha384-192", { "aes256-sha2" }, "AES-256 CTS mode with 192-bit SHA-384 HMAC", &krb5int_enc_aes256, &krb5int_hash_sha384, 48, krb5int_aes2_crypto_length, krb5int_etm_encrypt, krb5int_etm_decrypt, krb5int_aes2_string_to_key, k5_rand2key_direct, krb5int_aes2_prf, CKSUMTYPE_HMAC_SHA384_192_AES256, 0 /*flags*/, 256 }, }; const int krb5int_enctypes_length = sizeof(krb5int_enctypes_list) / sizeof(struct krb5_keytypes); krb5-1.22.1/src/lib/crypto/krb/checksum_etm.c0000664000175000017500000000501115051422640020604 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/checksum_etm.c - checksum for encrypt-then-mac enctypes */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "crypto_int.h" krb5_error_code krb5int_etm_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_error_code ret; uint8_t label[5]; krb5_data label_data = make_data(label, 5), kc = empty_data(); krb5_keyblock kb = { 0 }; /* Derive the checksum key. */ store_32_be(usage, label); label[4] = 0x99; label_data = make_data(label, 5); ret = alloc_data(&kc, ctp->hash->hashsize / 2); if (ret) goto cleanup; ret = krb5int_derive_random(ctp->enc, ctp->hash, key, &kc, &label_data, DERIVE_SP800_108_HMAC); if (ret) goto cleanup; /* Compute an HMAC with kc over the data. */ kb.length = kc.length; kb.contents = (uint8_t *)kc.data; ret = krb5int_hmac_keyblock(ctp->hash, &kb, data, num_data, output); cleanup: zapfree(kc.data, kc.length); return ret; } krb5-1.22.1/src/lib/crypto/krb/valid_cksumtype.c0000664000175000017500000000275215051422640021351 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_boolean KRB5_CALLCONV krb5_c_valid_cksumtype(krb5_cksumtype ctype) { const struct krb5_cksumtypes *ctp; ctp = find_cksumtype(ctype); if (ctp == NULL) return FALSE; return TRUE; } krb5-1.22.1/src/lib/crypto/krb/derive.c0000664000175000017500000001261715051422640017425 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" static krb5_key find_cached_dkey(struct derived_key *list, const krb5_data *constant) { for (; list; list = list->next) { if (data_eq(list->constant, *constant)) { krb5_k_reference_key(NULL, list->dkey); return list->dkey; } } return NULL; } static krb5_error_code add_cached_dkey(krb5_key key, const krb5_data *constant, const krb5_keyblock *dkeyblock, krb5_key *cached_dkey) { krb5_key dkey; krb5_error_code ret; struct derived_key *dkent = NULL; char *data = NULL; /* Allocate fields for the new entry. */ dkent = malloc(sizeof(*dkent)); if (dkent == NULL) goto cleanup; data = k5memdup(constant->data, constant->length, &ret); if (data == NULL) goto cleanup; ret = krb5_k_create_key(NULL, dkeyblock, &dkey); if (ret != 0) goto cleanup; /* Add the new entry to the list. */ dkent->dkey = dkey; dkent->constant.data = data; dkent->constant.length = constant->length; dkent->next = key->derived; key->derived = dkent; /* Return a "copy" of the cached key. */ krb5_k_reference_key(NULL, dkey); *cached_dkey = dkey; return 0; cleanup: free(dkent); free(data); return ENOMEM; } krb5_error_code krb5int_derive_random(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, krb5_key inkey, krb5_data *outrnd, const krb5_data *in_constant, enum deriv_alg alg) { krb5_data empty = empty_data(); switch (alg) { case DERIVE_RFC3961: return k5_derive_random_rfc3961(enc, inkey, in_constant, outrnd); case DERIVE_SP800_108_CMAC: return k5_sp800_108_feedback_cmac(enc, inkey, in_constant, outrnd); case DERIVE_SP800_108_HMAC: return k5_sp800_108_counter_hmac(hash, inkey, in_constant, &empty, outrnd); default: return EINVAL; } } /* * Compute a derived key into the keyblock outkey. This variation on * krb5int_derive_key does not cache the result, as it is only used * directly in situations which are not expected to be repeated with * the same inkey and constant. */ krb5_error_code krb5int_derive_keyblock(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, krb5_key inkey, krb5_keyblock *outkey, const krb5_data *in_constant, enum deriv_alg alg) { krb5_error_code ret; krb5_data rawkey = empty_data(); /* Allocate a buffer for the raw key bytes. */ ret = alloc_data(&rawkey, enc->keybytes); if (ret) goto cleanup; /* Derive pseudo-random data for the key bytes. */ ret = krb5int_derive_random(enc, hash, inkey, &rawkey, in_constant, alg); if (ret) goto cleanup; /* Postprocess the key. */ ret = krb5_c_random_to_key(NULL, inkey->keyblock.enctype, &rawkey, outkey); cleanup: zapfree(rawkey.data, enc->keybytes); return ret; } krb5_error_code krb5int_derive_key(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, krb5_key inkey, krb5_key *outkey, const krb5_data *in_constant, enum deriv_alg alg) { krb5_keyblock keyblock; krb5_error_code ret; krb5_key dkey; *outkey = NULL; /* Check for a cached result. */ dkey = find_cached_dkey(inkey->derived, in_constant); if (dkey != NULL) { *outkey = dkey; return 0; } /* Derive into a temporary keyblock. */ keyblock.length = enc->keylength; keyblock.contents = malloc(keyblock.length); keyblock.enctype = inkey->keyblock.enctype; if (keyblock.contents == NULL) return ENOMEM; ret = krb5int_derive_keyblock(enc, hash, inkey, &keyblock, in_constant, alg); if (ret) goto cleanup; /* Cache the derived key. */ ret = add_cached_dkey(inkey, in_constant, &keyblock, &dkey); if (ret != 0) goto cleanup; *outkey = dkey; cleanup: zapfree(keyblock.contents, keyblock.length); return ret; } krb5-1.22.1/src/lib/crypto/krb/coll_proof_cksum.c0000664000175000017500000000276415051422640021511 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_boolean KRB5_CALLCONV krb5_c_is_coll_proof_cksum(krb5_cksumtype ctype) { const struct krb5_cksumtypes *ctp; ctp = find_cksumtype(ctype); return (ctp != NULL && !(ctp->flags & CKSUM_NOT_COLL_PROOF)); } krb5-1.22.1/src/lib/crypto/krb/block_size.c0000664000175000017500000000312115051422640020261 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_block_size(krb5_context context, krb5_enctype enctype, size_t *blocksize) { const struct krb5_keytypes *ktp; ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; *blocksize = ktp->enc->block_size; return 0; } krb5-1.22.1/src/lib/crypto/krb/make_random_key.c0000664000175000017500000000466215051422640021275 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_make_random_key(krb5_context context, krb5_enctype enctype, krb5_keyblock *random_key) { krb5_error_code ret; const struct krb5_keytypes *ktp; const struct krb5_enc_provider *enc; size_t keybytes, keylength; krb5_data random_data; unsigned char *bytes = NULL; ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; enc = ktp->enc; keybytes = enc->keybytes; keylength = enc->keylength; bytes = k5alloc(keybytes, &ret); if (ret) return ret; random_key->contents = k5alloc(keylength, &ret); if (ret) goto cleanup; random_data.data = (char *) bytes; random_data.length = keybytes; ret = krb5_c_random_make_octets(context, &random_data); if (ret) goto cleanup; random_key->magic = KV5M_KEYBLOCK; random_key->enctype = enctype; random_key->length = keylength; ret = (*ktp->rand2key)(&random_data, random_key); cleanup: if (ret) { zapfree(random_key->contents, keylength); random_key->contents = NULL; } zapfree(bytes, keybytes); return ret; } krb5-1.22.1/src/lib/crypto/krb/Makefile.in0000664000175000017500000001105115051422640020037 0ustar ghudsonghudsonmydir=lib$(S)crypto$(S)krb BUILDTOP=$(REL)..$(S)..$(S).. ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR = krb ##DOS##OBJFILE = ..\$(OUTPRE)krb.lst STLIBOBJS=\ aead.o \ block_size.o \ cf2.o \ checksum_dk_cmac.o \ checksum_dk_hmac.o \ checksum_etm.o \ checksum_hmac_md5.o \ checksum_unkeyed.o \ checksum_length.o \ cksumtype_to_string.o \ cksumtypes.o \ coll_proof_cksum.o \ crypto_length.o \ default_state.o \ decrypt.o \ decrypt_iov.o \ derive.o \ encrypt.o \ encrypt_iov.o \ encrypt_length.o \ enctype_util.o \ enc_dk_cmac.o \ enc_dk_hmac.o \ enc_etm.o \ enc_raw.o \ enc_rc4.o \ etypes.o \ key.o \ keyblocks.o \ keyed_cksum.o \ keyed_checksum_types.o \ keylengths.o \ make_checksum.o \ make_checksum_iov.o \ make_random_key.o \ mandatory_sumtype.o \ nfold.o \ old_api_glue.o \ prf.o \ prf_aes2.o \ prf_cmac.o \ prf_des.o \ prf_dk.o \ prf_rc4.o \ prng.o \ random_to_key.o \ s2k_pbkdf2.o \ s2k_rc4.o \ state.o \ string_to_cksumtype.o \ string_to_key.o \ valid_cksumtype.o \ verify_checksum.o \ verify_checksum_iov.o OBJS=\ $(OUTPRE)aead.$(OBJEXT) \ $(OUTPRE)block_size.$(OBJEXT) \ $(OUTPRE)cf2.$(OBJEXT) \ $(OUTPRE)checksum_dk_cmac.$(OBJEXT) \ $(OUTPRE)checksum_dk_hmac.$(OBJEXT) \ $(OUTPRE)checksum_etm.$(OBJEXT) \ $(OUTPRE)checksum_hmac_md5.$(OBJEXT) \ $(OUTPRE)checksum_unkeyed.$(OBJEXT) \ $(OUTPRE)checksum_length.$(OBJEXT) \ $(OUTPRE)cksumtype_to_string.$(OBJEXT) \ $(OUTPRE)cksumtypes.$(OBJEXT) \ $(OUTPRE)coll_proof_cksum.$(OBJEXT) \ $(OUTPRE)crypto_length.$(OBJEXT) \ $(OUTPRE)default_state.$(OBJEXT) \ $(OUTPRE)decrypt.$(OBJEXT) \ $(OUTPRE)decrypt_iov.$(OBJEXT) \ $(OUTPRE)derive.$(OBJEXT) \ $(OUTPRE)encrypt.$(OBJEXT) \ $(OUTPRE)encrypt_iov.$(OBJEXT) \ $(OUTPRE)encrypt_length.$(OBJEXT) \ $(OUTPRE)enctype_util.$(OBJEXT) \ $(OUTPRE)enc_dk_cmac.$(OBJEXT) \ $(OUTPRE)enc_dk_hmac.$(OBJEXT) \ $(OUTPRE)enc_etm.$(OBJEXT) \ $(OUTPRE)enc_raw.$(OBJEXT) \ $(OUTPRE)enc_rc4.$(OBJEXT) \ $(OUTPRE)etypes.$(OBJEXT) \ $(OUTPRE)key.$(OBJEXT) \ $(OUTPRE)keyblocks.$(OBJEXT) \ $(OUTPRE)keyed_cksum.$(OBJEXT) \ $(OUTPRE)keyed_checksum_types.$(OBJEXT) \ $(OUTPRE)keylengths.$(OBJEXT) \ $(OUTPRE)make_checksum.$(OBJEXT) \ $(OUTPRE)make_checksum_iov.$(OBJEXT) \ $(OUTPRE)make_random_key.$(OBJEXT) \ $(OUTPRE)mandatory_sumtype.$(OBJEXT) \ $(OUTPRE)nfold.$(OBJEXT) \ $(OUTPRE)old_api_glue.$(OBJEXT) \ $(OUTPRE)prf.$(OBJEXT) \ $(OUTPRE)prf_aes2.$(OBJEXT) \ $(OUTPRE)prf_cmac.$(OBJEXT) \ $(OUTPRE)prf_des.$(OBJEXT) \ $(OUTPRE)prf_dk.$(OBJEXT) \ $(OUTPRE)prf_rc4.$(OBJEXT) \ $(OUTPRE)prng.$(OBJEXT) \ $(OUTPRE)random_to_key.$(OBJEXT) \ $(OUTPRE)s2k_pbkdf2.$(OBJEXT) \ $(OUTPRE)s2k_rc4.$(OBJEXT) \ $(OUTPRE)state.$(OBJEXT) \ $(OUTPRE)string_to_cksumtype.$(OBJEXT) \ $(OUTPRE)string_to_key.$(OBJEXT) \ $(OUTPRE)valid_cksumtype.$(OBJEXT) \ $(OUTPRE)verify_checksum.$(OBJEXT) \ $(OUTPRE)verify_checksum_iov.$(OBJEXT) SRCS=\ $(srcdir)/aead.c \ $(srcdir)/block_size.c \ $(srcdir)/cf2.c \ $(srcdir)/checksum_dk_cmac.c \ $(srcdir)/checksum_dk_hmac.c \ $(srcdir)/checksum_etm.c \ $(srcdir)/checksum_hmac_md5.c \ $(srcdir)/checksum_unkeyed.c \ $(srcdir)/checksum_length.c \ $(srcdir)/cksumtype_to_string.c \ $(srcdir)/cksumtypes.c \ $(srcdir)/coll_proof_cksum.c \ $(srcdir)/crypto_length.c \ $(srcdir)/default_state.c \ $(srcdir)/decrypt.c \ $(srcdir)/decrypt_iov.c \ $(srcdir)/derive.c \ $(srcdir)/encrypt.c \ $(srcdir)/encrypt_iov.c \ $(srcdir)/encrypt_length.c \ $(srcdir)/enctype_util.c \ $(srcdir)/enc_dk_cmac.c \ $(srcdir)/enc_dk_hmac.c \ $(srcdir)/enc_etm.c \ $(srcdir)/enc_raw.c \ $(srcdir)/enc_rc4.c \ $(srcdir)/etypes.c \ $(srcdir)/key.c \ $(srcdir)/keyblocks.c \ $(srcdir)/keyed_cksum.c \ $(srcdir)/keyed_checksum_types.c\ $(srcdir)/keylengths.c \ $(srcdir)/make_checksum.c \ $(srcdir)/make_checksum_iov.c \ $(srcdir)/make_random_key.c \ $(srcdir)/mandatory_sumtype.c \ $(srcdir)/nfold.c \ $(srcdir)/old_api_glue.c \ $(srcdir)/prf.c \ $(srcdir)/prf_aes2.c \ $(srcdir)/prf_cmac.c \ $(srcdir)/prf_des.c \ $(srcdir)/prf_dk.c \ $(srcdir)/prf_rc4.c \ $(srcdir)/prng.c \ $(srcdir)/cf2.c \ $(srcdir)/random_to_key.c \ $(srcdir)/s2k_pbkdf2.c \ $(srcdir)/s2k_rc4.c \ $(srcdir)/state.c \ $(srcdir)/string_to_cksumtype.c \ $(srcdir)/string_to_key.c \ $(srcdir)/valid_cksumtype.c \ $(srcdir)/verify_checksum.c \ $(srcdir)/verify_checksum_iov.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs includes: depend depend: $(SRCS) clean-unix:: clean-libobjs @lib_frag@ @libobj_frag@ krb5-1.22.1/src/lib/crypto/krb/keyed_checksum_types.c0000664000175000017500000000507115051422640022352 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" static krb5_boolean is_keyed_for(const struct krb5_cksumtypes *ctp, const struct krb5_keytypes *ktp) { if (ctp->flags & CKSUM_UNKEYED) return FALSE; return (!ctp->enc || ktp->enc == ctp->enc); } krb5_error_code KRB5_CALLCONV krb5_c_keyed_checksum_types(krb5_context context, krb5_enctype enctype, unsigned int *count, krb5_cksumtype **cksumtypes) { unsigned int i, c, nctypes; krb5_cksumtype *ctypes; const struct krb5_cksumtypes *ctp; const struct krb5_keytypes *ktp; *count = 0; *cksumtypes = NULL; ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; nctypes = 0; for (i = 0; i < krb5int_cksumtypes_length; i++) { ctp = &krb5int_cksumtypes_list[i]; if (is_keyed_for(ctp, ktp)) nctypes++; } ctypes = malloc(nctypes * sizeof(krb5_cksumtype)); if (ctypes == NULL) return ENOMEM; c = 0; for (i = 0; i < krb5int_cksumtypes_length; i++) { ctp = &krb5int_cksumtypes_list[i]; if (is_keyed_for(ctp, ktp)) ctypes[c++] = ctp->ctype; } *count = nctypes; *cksumtypes = ctypes; return 0; } void KRB5_CALLCONV krb5_free_cksumtypes(krb5_context context, krb5_cksumtype *val) { free(val); } krb5-1.22.1/src/lib/crypto/krb/prf_cmac.c0000664000175000017500000000416215051422640017715 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/prf_cmac.c - CMAC-based PRF */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code krb5int_dk_cmac_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out) { krb5_crypto_iov iov; krb5_data prfconst = make_data("prf", 3); krb5_key kp = NULL; krb5_error_code ret; if (ktp->prf_length != ktp->enc->block_size) return KRB5_BAD_MSIZE; iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *in; /* Derive a key using the PRF constant. */ ret = krb5int_derive_key(ktp->enc, NULL, key, &kp, &prfconst, DERIVE_SP800_108_CMAC); if (ret != 0) goto cleanup; /* PRF is CMAC of input */ ret = krb5int_cmac_checksum(ktp->enc, kp, &iov, 1, out); if (ret != 0) goto cleanup; cleanup: krb5_k_free_key(NULL, kp); return ret; } krb5-1.22.1/src/lib/crypto/krb/crypto_length.c0000664000175000017500000000750115051422640021024 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/crypto_length.c */ /* * Copyright 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_crypto_length(krb5_context context, krb5_enctype enctype, krb5_cryptotype type, unsigned int *size) { const struct krb5_keytypes *ktp; ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; switch (type) { case KRB5_CRYPTO_TYPE_EMPTY: case KRB5_CRYPTO_TYPE_SIGN_ONLY: *size = 0; break; case KRB5_CRYPTO_TYPE_DATA: *size = (unsigned int)~0; /* match Heimdal */ break; case KRB5_CRYPTO_TYPE_HEADER: case KRB5_CRYPTO_TYPE_PADDING: case KRB5_CRYPTO_TYPE_TRAILER: case KRB5_CRYPTO_TYPE_CHECKSUM: *size = ktp->crypto_length(ktp, type); break; default: return EINVAL; } return 0; } krb5_error_code KRB5_CALLCONV krb5_c_padding_length(krb5_context context, krb5_enctype enctype, size_t data_length, unsigned int *pad_length) { const struct krb5_keytypes *ktp; ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; *pad_length = krb5int_c_padding_length(ktp, data_length); return 0; } krb5_error_code KRB5_CALLCONV krb5_c_crypto_length_iov(krb5_context context, krb5_enctype enctype, krb5_crypto_iov *data, size_t num_data) { size_t i; const struct krb5_keytypes *ktp; unsigned int data_length = 0, pad_length; krb5_crypto_iov *padding = NULL; /* * XXX need to rejig internal interface so we can accurately * report variable header lengths. */ ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; for (i = 0; i < num_data; i++) { krb5_crypto_iov *iov = &data[i]; switch (iov->flags) { case KRB5_CRYPTO_TYPE_DATA: data_length += iov->data.length; break; case KRB5_CRYPTO_TYPE_PADDING: if (padding != NULL) return EINVAL; padding = iov; break; case KRB5_CRYPTO_TYPE_HEADER: case KRB5_CRYPTO_TYPE_TRAILER: case KRB5_CRYPTO_TYPE_CHECKSUM: iov->data.length = ktp->crypto_length(ktp, iov->flags); break; case KRB5_CRYPTO_TYPE_EMPTY: case KRB5_CRYPTO_TYPE_SIGN_ONLY: default: break; } } pad_length = krb5int_c_padding_length(ktp, data_length); if (pad_length != 0 && padding == NULL) return EINVAL; if (padding != NULL) padding->data.length = pad_length; return 0; } krb5-1.22.1/src/lib/crypto/krb/prf_des.c0000664000175000017500000000362115051422640017564 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/prf_des.c - RFC 3961 DES-based PRF */ /* * Copyright (C) 2004, 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code krb5int_des_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out) { const struct krb5_hash_provider *hash = &krb5int_hash_md5; krb5_crypto_iov iov; krb5_error_code ret; /* Compute a hash of the input, storing into the output buffer. */ iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *in; ret = hash->hash(&iov, 1, out); if (ret != 0) return ret; /* Encrypt the hash in place. */ iov.data = *out; return ktp->enc->encrypt(key, NULL, &iov, 1); } krb5-1.22.1/src/lib/crypto/krb/enc_etm.c0000664000175000017500000002067615051422640017565 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/enc_etm.c - encrypt-then-mac construction for aes-sha2 */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "crypto_int.h" unsigned int krb5int_aes2_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type) { switch (type) { case KRB5_CRYPTO_TYPE_HEADER: return ktp->enc->block_size; case KRB5_CRYPTO_TYPE_PADDING: return 0; case KRB5_CRYPTO_TYPE_TRAILER: case KRB5_CRYPTO_TYPE_CHECKSUM: return ktp->hash->hashsize / 2; default: assert(0 && "invalid cryptotype passed to krb5int_aes2_crypto_length"); return 0; } } /* Derive encryption and integrity keys for CMAC-using enctypes. */ static krb5_error_code derive_keys(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, krb5_key *ke_out, krb5_data *ki_out) { krb5_error_code ret; uint8_t label[5]; krb5_data label_data = make_data(label, 5), ki = empty_data(); krb5_key ke = NULL; *ke_out = NULL; *ki_out = empty_data(); /* Derive the encryption key. */ store_32_be(usage, label); label[4] = 0xAA; ret = krb5int_derive_key(ktp->enc, ktp->hash, key, &ke, &label_data, DERIVE_SP800_108_HMAC); if (ret) goto cleanup; /* Derive the integrity key. */ label[4] = 0x55; ret = alloc_data(&ki, ktp->hash->hashsize / 2); if (ret) goto cleanup; ret = krb5int_derive_random(NULL, ktp->hash, key, &ki, &label_data, DERIVE_SP800_108_HMAC); if (ret) goto cleanup; *ke_out = ke; ke = NULL; *ki_out = ki; ki = empty_data(); cleanup: krb5_k_free_key(NULL, ke); zapfree(ki.data, ki.length); return ret; } /* Compute an HMAC checksum over the cipher state and data. Allocate enough * space in *out for the checksum. */ static krb5_error_code hmac_ivec_data(const struct krb5_keytypes *ktp, const krb5_data *ki, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data, krb5_data *out) { krb5_error_code ret; krb5_data zeroivec = empty_data(); krb5_crypto_iov *iovs = NULL; krb5_keyblock kb = { 0 }; if (ivec == NULL) { ret = ktp->enc->init_state(NULL, 0, &zeroivec); if (ret) goto cleanup; ivec = &zeroivec; } /* Make a copy of data with an extra iov at the beginning for the ivec. */ iovs = k5calloc(num_data + 1, sizeof(*iovs), &ret); if (iovs == NULL) goto cleanup; iovs[0].flags = KRB5_CRYPTO_TYPE_DATA; iovs[0].data = *ivec; memcpy(iovs + 1, data, num_data * sizeof(*iovs)); ret = alloc_data(out, ktp->hash->hashsize); if (ret) goto cleanup; kb.length = ki->length; kb.contents = (uint8_t *)ki->data; ret = krb5int_hmac_keyblock(ktp->hash, &kb, iovs, num_data + 1, out); cleanup: if (zeroivec.data != NULL) ktp->enc->free_state(&zeroivec); free(iovs); return ret; } krb5_error_code krb5int_etm_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { const struct krb5_enc_provider *enc = ktp->enc; krb5_error_code ret; krb5_data ivcopy = empty_data(), cksum = empty_data(); krb5_crypto_iov *header, *trailer, *padding; krb5_key ke = NULL; krb5_data ki = empty_data(); unsigned int trailer_len; /* E(Confounder | Plaintext) | Checksum(IV | ciphertext) */ trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER); /* Validate header and trailer lengths, and zero out padding length. */ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); if (header == NULL || header->data.length < enc->block_size) return KRB5_BAD_MSIZE; trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); if (trailer == NULL || trailer->data.length < trailer_len) return KRB5_BAD_MSIZE; padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING); if (padding != NULL) padding->data.length = 0; if (ivec != NULL) { ret = alloc_data(&ivcopy, ivec->length); if (ret) goto cleanup; memcpy(ivcopy.data, ivec->data, ivec->length); } /* Derive the encryption and integrity keys. */ ret = derive_keys(ktp, key, usage, &ke, &ki); if (ret) goto cleanup; /* Generate confounder. */ header->data.length = enc->block_size; ret = krb5_c_random_make_octets(NULL, &header->data); if (ret) goto cleanup; /* Encrypt the plaintext (header | data). */ ret = enc->encrypt(ke, (ivec == NULL) ? NULL : &ivcopy, data, num_data); if (ret) goto cleanup; /* HMAC the IV, confounder, and ciphertext with sign-only data. */ ret = hmac_ivec_data(ktp, &ki, ivec, data, num_data, &cksum); if (ret) goto cleanup; /* Truncate the HMAC checksum to the trailer length. */ assert(trailer_len <= cksum.length); memcpy(trailer->data.data, cksum.data, trailer_len); trailer->data.length = trailer_len; /* Copy out the updated ivec if desired. */ if (ivec != NULL) memcpy(ivec->data, ivcopy.data, ivcopy.length); cleanup: krb5_k_free_key(NULL, ke); zapfree(ki.data, ki.length); free(cksum.data); zapfree(ivcopy.data, ivcopy.length); return ret; } krb5_error_code krb5int_etm_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { const struct krb5_enc_provider *enc = ktp->enc; krb5_error_code ret; krb5_data cksum = empty_data(); krb5_crypto_iov *header, *trailer; krb5_key ke = NULL; krb5_data ki = empty_data(); unsigned int trailer_len; trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER); /* Validate header and trailer lengths. */ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); if (header == NULL || header->data.length != enc->block_size) return KRB5_BAD_MSIZE; trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); if (trailer == NULL || trailer->data.length != trailer_len) return KRB5_BAD_MSIZE; /* Derive the encryption and integrity keys. */ ret = derive_keys(ktp, key, usage, &ke, &ki); if (ret) goto cleanup; /* HMAC the IV, confounder, and ciphertext with sign-only data. */ ret = hmac_ivec_data(ktp, &ki, ivec, data, num_data, &cksum); if (ret) goto cleanup; /* Compare only the possibly truncated length. */ assert(trailer_len <= cksum.length); if (k5_bcmp(cksum.data, trailer->data.data, trailer_len) != 0) { ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; goto cleanup; } /* Decrypt the ciphertext (header | data | padding). */ ret = enc->decrypt(ke, ivec, data, num_data); cleanup: krb5_k_free_key(NULL, ke); zapfree(ki.data, ki.length); zapfree(cksum.data, cksum.length); return ret; } krb5-1.22.1/src/lib/crypto/krb/nfold.c0000664000175000017500000000704615051422640017251 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" /* * n-fold(k-bits): * l = lcm(n,k) * r = l/k * s = k-bits | k-bits rot 13 | k-bits rot 13*2 | ... | k-bits rot 13*(r-1) * compute the 1's complement sum: * n-fold = s[0..n-1]+s[n..2n-1]+s[2n..3n-1]+..+s[(k-1)*n..k*n-1] */ /* representation: msb first, assume n and k are multiples of 8, and * that k>=16. this is the case of all the cryptosystems which are * likely to be used. this function can be replaced if that * assumption ever fails. */ /* input length is in bits */ void krb5int_nfold(unsigned int inbits, const unsigned char *in, unsigned int outbits, unsigned char *out) { int a,b,c,lcm; int byte, i, msbit; /* the code below is more readable if I make these bytes instead of bits */ inbits >>= 3; outbits >>= 3; /* first compute lcm(n,k) */ a = outbits; b = inbits; while(b != 0) { c = b; b = a%b; a = c; } lcm = outbits*inbits/a; /* now do the real work */ memset(out, 0, outbits); byte = 0; /* this will end up cycling through k lcm(k,n)/k times, which is correct */ for (i=lcm-1; i>=0; i--) { /* compute the msbit in k which gets added into this byte */ msbit = (/* first, start with the msbit in the first, unrotated byte */ ((inbits<<3)-1) /* then, for each byte, shift to the right for each repetition */ +(((inbits<<3)+13)*(i/inbits)) /* last, pick out the correct byte within that shifted repetition */ +((inbits-(i%inbits))<<3) )%(inbits<<3); /* pull out the byte value itself */ byte += (((in[((inbits-1)-(msbit>>3))%inbits]<<8)| (in[((inbits)-(msbit>>3))%inbits])) >>((msbit&7)+1))&0xff; /* do the addition */ byte += out[i%outbits]; out[i%outbits] = byte&0xff; /* keep around the carry bit, if any */ byte >>= 8; } /* if there's a carry bit left over, add it back in */ if (byte) { for (i=outbits-1; i>=0; i--) { /* do the addition */ byte += out[i]; out[i] = byte&0xff; /* keep around the carry bit, if any */ byte >>= 8; } } } krb5-1.22.1/src/lib/crypto/krb/checksum_length.c0000664000175000017500000000313315051422640021303 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_checksum_length(krb5_context context, krb5_cksumtype cksumtype, size_t *length) { const struct krb5_cksumtypes *ctp; ctp = find_cksumtype(cksumtype); if (ctp == NULL) return KRB5_BAD_ENCTYPE; *length = ctp->output_size; return 0; } krb5-1.22.1/src/lib/crypto/krb/s2k_rc4.c0000664000175000017500000000230315051422640017405 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "crypto_int.h" #include "k5-utf8.h" krb5_error_code krb5int_arcfour_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key) { krb5_error_code err = 0; krb5_crypto_iov iov; krb5_data hash_out; char *utf8; unsigned char *copystr; size_t copystrlen; if (params != NULL) return KRB5_ERR_BAD_S2K_PARAMS; if (key->length != 16) return (KRB5_BAD_MSIZE); /* We ignore salt per the Microsoft spec. */ utf8 = k5memdup0(string->data, string->length, &err); if (utf8 == NULL) return err; err = k5_utf8_to_utf16le(utf8, ©str, ©strlen); zapfree(utf8, string->length); if (err) return err; /* the actual MD4 hash of the data */ iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(copystr, copystrlen); hash_out = make_data(key->contents, key->length); err = krb5int_hash_md4.hash(&iov, 1, &hash_out); /* Zero out the data behind us */ zapfree(copystr, copystrlen); return err; } krb5-1.22.1/src/lib/crypto/krb/keyblocks.c0000664000175000017500000000617715051422640020141 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/keyblocks.c - Keyblock utility functions */ /* * Copyright (C) 2002, 2005 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code krb5int_c_init_keyblock(krb5_context context, krb5_enctype enctype, size_t length, krb5_keyblock **out) { krb5_keyblock *kb; assert(out); *out = NULL; kb = malloc(sizeof(krb5_keyblock)); if (kb == NULL) return ENOMEM; kb->magic = KV5M_KEYBLOCK; kb->enctype = enctype; kb->length = length; if (length) { kb->contents = malloc(length); if (!kb->contents) { free(kb); return ENOMEM; } } else { kb->contents = NULL; } *out = kb; return 0; } void krb5int_c_free_keyblock(krb5_context context, krb5_keyblock *val) { krb5int_c_free_keyblock_contents(context, val); free(val); } void krb5int_c_free_keyblock_contents(krb5_context context, krb5_keyblock *key) { if (key && key->contents) { zapfree(key->contents, key->length); key->contents = NULL; key->length = 0; } } krb5_error_code krb5int_c_copy_keyblock(krb5_context context, const krb5_keyblock *from, krb5_keyblock **to) { krb5_keyblock *new_key; krb5_error_code code; *to = NULL; new_key = malloc(sizeof(*new_key)); if (!new_key) return ENOMEM; code = krb5int_c_copy_keyblock_contents(context, from, new_key); if (code) { free(new_key); return code; } *to = new_key; return 0; } krb5_error_code krb5int_c_copy_keyblock_contents(krb5_context context, const krb5_keyblock *from, krb5_keyblock *to) { *to = *from; if (to->length) { to->contents = malloc(to->length); if (!to->contents) return ENOMEM; memcpy(to->contents, from->contents, to->length); } else to->contents = 0; return 0; } krb5-1.22.1/src/lib/crypto/krb/old_api_glue.c0000664000175000017500000002614615051422640020574 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" /* * The following functions were removed from the API in krb5 1.3 but * still need to be exported for ABI compatibility. The other * functions defined in this file are still in the API (and thus * prototyped in krb5.hin) but are deprecated. */ krb5_boolean KRB5_CALLCONV valid_enctype(krb5_enctype ktype); krb5_boolean KRB5_CALLCONV valid_cksumtype(krb5_cksumtype ctype); krb5_boolean KRB5_CALLCONV is_coll_proof_cksum(krb5_cksumtype ctype); krb5_boolean KRB5_CALLCONV is_keyed_cksum(krb5_cksumtype ctype); krb5_error_code KRB5_CALLCONV krb5_random_confounder(size_t, krb5_pointer); krb5_error_code krb5_encrypt_data(krb5_context context, krb5_keyblock *key, krb5_pointer ivec, krb5_data *data, krb5_enc_data *enc_data); krb5_error_code krb5_decrypt_data(krb5_context context, krb5_keyblock *key, krb5_pointer ivec, krb5_enc_data *data, krb5_data *enc_data); krb5_error_code KRB5_CALLCONV krb5_encrypt(krb5_context context, krb5_const_pointer inptr, krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock, krb5_pointer ivec) { krb5_data inputd, ivecd; krb5_enc_data outputd; size_t blocksize, outlen; krb5_error_code ret; if (ivec) { ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize); if (ret) return ret; ivecd = make_data(ivec, blocksize); } /* size is the length of the input cleartext data. */ inputd = make_data((void *) inptr, size); /* * The size of the output buffer isn't part of the old api. Not too * safe. So, we assume here that it's big enough. */ ret = krb5_c_encrypt_length(context, eblock->key->enctype, size, &outlen); if (ret) return ret; outputd.ciphertext = make_data(outptr, outlen); return krb5_c_encrypt(context, eblock->key, 0, ivec ? &ivecd : 0, &inputd, &outputd); } krb5_error_code KRB5_CALLCONV krb5_decrypt(krb5_context context, krb5_const_pointer inptr, krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock, krb5_pointer ivec) { krb5_enc_data inputd; krb5_data outputd, ivecd; size_t blocksize; krb5_error_code ret; if (ivec) { ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize); if (ret) return ret; ivecd = make_data(ivec, blocksize); } /* size is the length of the input ciphertext data */ inputd.enctype = eblock->key->enctype; inputd.ciphertext = make_data((void *) inptr, size); /* we don't really know how big this is, but the code tends to assume that the output buffer size should be the same as the input buffer size */ outputd = make_data(outptr, size); return krb5_c_decrypt(context, eblock->key, 0, ivec ? &ivecd : 0, &inputd, &outputd); } krb5_error_code KRB5_CALLCONV krb5_process_key(krb5_context context, krb5_encrypt_block *eblock, const krb5_keyblock *key) { eblock->key = (krb5_keyblock *) key; return 0; } krb5_error_code KRB5_CALLCONV krb5_finish_key(krb5_context context, krb5_encrypt_block *eblock) { return 0; } krb5_error_code KRB5_CALLCONV krb5_string_to_key(krb5_context context, const krb5_encrypt_block *eblock, krb5_keyblock *keyblock, const krb5_data *data, const krb5_data *salt) { return krb5_c_string_to_key(context, eblock->crypto_entry, data, salt, keyblock); } krb5_error_code KRB5_CALLCONV krb5_init_random_key(krb5_context context, const krb5_encrypt_block *eblock, const krb5_keyblock *keyblock, krb5_pointer *ptr) { krb5_data data = make_data(keyblock->contents, keyblock->length); return krb5_c_random_seed(context, &data); } krb5_error_code KRB5_CALLCONV krb5_finish_random_key(krb5_context context, const krb5_encrypt_block *eblock, krb5_pointer *ptr) { return 0; } krb5_error_code KRB5_CALLCONV krb5_random_key(krb5_context context, const krb5_encrypt_block *eblock, krb5_pointer ptr, krb5_keyblock **keyblock) { krb5_keyblock *key; krb5_error_code ret; *keyblock = NULL; key = malloc(sizeof(krb5_keyblock)); if (key == NULL) return ENOMEM; ret = krb5_c_make_random_key(context, eblock->crypto_entry, key); if (ret) { free(key); return ret; } *keyblock = key; return(ret); } krb5_enctype KRB5_CALLCONV krb5_eblock_enctype(krb5_context context, const krb5_encrypt_block *eblock) { return eblock->crypto_entry; } krb5_error_code KRB5_CALLCONV krb5_use_enctype(krb5_context context, krb5_encrypt_block *eblock, krb5_enctype enctype) { eblock->crypto_entry = enctype; return 0; } size_t KRB5_CALLCONV krb5_encrypt_size(size_t length, krb5_enctype crypto) { size_t ret; if (krb5_c_encrypt_length(NULL, crypto, length, &ret)) return (size_t) -1; /* XXX */ return ret; } size_t KRB5_CALLCONV krb5_checksum_size(krb5_context context, krb5_cksumtype ctype) { size_t ret; if (krb5_c_checksum_length(context, ctype, &ret)) return (size_t) -1; /* XXX */ return ret; } /* Guess the enctype for an untyped key used with checksum type ctype. */ static krb5_enctype guess_enctype(krb5_cksumtype ctype) { const struct krb5_cksumtypes *ctp; int i; if (ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR) return ENCTYPE_ARCFOUR_HMAC; ctp = find_cksumtype(ctype); if (ctp == NULL || ctp->enc == NULL) return 0; for (i = 0; i < krb5int_enctypes_length; i++) { if (krb5int_enctypes_list[i].enc == ctp->enc) return i; } return 0; } krb5_error_code KRB5_CALLCONV krb5_calculate_checksum(krb5_context context, krb5_cksumtype ctype, krb5_const_pointer in, size_t in_length, krb5_const_pointer seed, size_t seed_length, krb5_checksum *outcksum) { krb5_data input = make_data((void *) in, in_length); krb5_keyblock keyblock, *kptr = NULL; krb5_error_code ret; krb5_checksum cksum; if (seed != NULL) { keyblock.enctype = guess_enctype(ctype); keyblock.length = seed_length; keyblock.contents = (unsigned char *) seed; kptr = &keyblock; } ret = krb5_c_make_checksum(context, ctype, kptr, 0, &input, &cksum); if (ret) return ret; if (outcksum->length < cksum.length) { memset(cksum.contents, 0, cksum.length); free(cksum.contents); return KRB5_BAD_MSIZE; } outcksum->magic = cksum.magic; outcksum->checksum_type = cksum.checksum_type; memcpy(outcksum->contents, cksum.contents, cksum.length); outcksum->length = cksum.length; free(cksum.contents); return(0); } krb5_error_code KRB5_CALLCONV krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype, const krb5_checksum *cksum, krb5_const_pointer in, size_t in_length, krb5_const_pointer seed, size_t seed_length) { krb5_data input = make_data((void *) in, in_length); krb5_keyblock keyblock, *kptr = NULL; krb5_error_code ret; krb5_boolean valid; if (seed != NULL) { keyblock.enctype = guess_enctype(ctype); keyblock.length = seed_length; keyblock.contents = (unsigned char *) seed; kptr = &keyblock; } ret = krb5_c_verify_checksum(context, kptr, 0, &input, cksum, &valid); if (ret) return ret; if (!valid) return KRB5KRB_AP_ERR_BAD_INTEGRITY; return 0; } krb5_error_code KRB5_CALLCONV krb5_random_confounder(size_t size, krb5_pointer ptr) { krb5_data random_data = make_data(ptr, size); return krb5_c_random_make_octets(NULL, &random_data); } krb5_error_code krb5_encrypt_data(krb5_context context, krb5_keyblock *key, krb5_pointer ivec, krb5_data *data, krb5_enc_data *enc_data) { krb5_error_code ret; size_t enclen, blocksize; krb5_data ivecd; ret = krb5_c_encrypt_length(context, key->enctype, data->length, &enclen); if (ret) return ret; if (ivec) { ret = krb5_c_block_size(context, key->enctype, &blocksize); if (ret) return ret; ivecd = make_data(ivec, blocksize); } enc_data->magic = KV5M_ENC_DATA; enc_data->kvno = 0; enc_data->enctype = key->enctype; ret = alloc_data(&enc_data->ciphertext, enclen); if (ret) return ret; ret = krb5_c_encrypt(context, key, 0, ivec ? &ivecd : 0, data, enc_data); if (ret) free(enc_data->ciphertext.data); return ret; } krb5_error_code krb5_decrypt_data(krb5_context context, krb5_keyblock *key, krb5_pointer ivec, krb5_enc_data *enc_data, krb5_data *data) { krb5_error_code ret; krb5_data ivecd; size_t blocksize; if (ivec) { ret = krb5_c_block_size(context, key->enctype, &blocksize); if (ret) return ret; ivecd = make_data(ivec, blocksize); } ret = alloc_data(data, enc_data->ciphertext.length); if (ret) return ret; ret = krb5_c_decrypt(context, key, 0, ivec ? &ivecd : 0, enc_data, data); if (ret) free(data->data); return 0; } krb5_boolean KRB5_CALLCONV valid_cksumtype(krb5_cksumtype ctype) { return krb5_c_valid_cksumtype(ctype); } krb5_boolean KRB5_CALLCONV is_keyed_cksum(krb5_cksumtype ctype) { return krb5_c_is_keyed_cksum(ctype); } krb5_boolean KRB5_CALLCONV is_coll_proof_cksum(krb5_cksumtype ctype) { return krb5_c_is_coll_proof_cksum(ctype); } krb5_boolean KRB5_CALLCONV valid_enctype(krb5_enctype etype) { return krb5_c_valid_enctype(etype); } krb5-1.22.1/src/lib/crypto/krb/checksum_unkeyed.c0000664000175000017500000000322515051422640021470 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/checksum_unkeyed.c - Unkeyed checksum handler */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code krb5int_unkeyed_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { return ctp->hash->hash(data, num_data, output); } krb5-1.22.1/src/lib/crypto/krb/prf.c0000664000175000017500000000536315051422640016736 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/prf.c */ /* * Copyright (C) 2004 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This contains the implementation of krb5_c_prf, which will find the * enctype-specific PRF and then generate pseudo-random data. This function * yields krb5_c_prf_length bytes of output. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_prf_length(krb5_context context, krb5_enctype enctype, size_t *len) { const struct krb5_keytypes *ktp; assert(len); ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; *len = ktp->prf_length; return 0; } krb5_error_code KRB5_CALLCONV krb5_k_prf(krb5_context context, krb5_key key, krb5_data *input, krb5_data *output) { const struct krb5_keytypes *ktp; krb5_error_code ret; assert(input && output); assert(output->data); ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; if (ktp->prf == NULL) return KRB5_CRYPTO_INTERNAL; output->magic = KV5M_DATA; if (ktp->prf_length != output->length) return KRB5_CRYPTO_INTERNAL; ret = ktp->prf(ktp, key, input, output); return ret; } krb5_error_code KRB5_CALLCONV krb5_c_prf(krb5_context context, const krb5_keyblock *keyblock, krb5_data *input, krb5_data *output) { krb5_key key; krb5_error_code ret; ret = krb5_k_create_key(context, keyblock, &key); if (ret != 0) return ret; ret = krb5_k_prf(context, key, input, output); krb5_k_free_key(context, key); return ret; } krb5-1.22.1/src/lib/crypto/krb/checksum_hmac_md5.c0000664000175000017500000001073115051422640021501 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/checksum_hmac_md5.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Microsoft HMAC-MD5 and MD5-HMAC checksums (see RFC 4757): * HMAC(KS, hash(msusage || input)) * KS is HMAC(key, "signaturekey\0") for HMAC-MD5, or just the key for * MD5-HMAC. */ #include "crypto_int.h" krb5_error_code krb5int_hmacmd5_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_keyusage ms_usage; krb5_error_code ret; krb5_keyblock ks, *keyblock; krb5_crypto_iov *hash_iov = NULL, iov; krb5_data ds = empty_data(), hashval = empty_data(); char t[4]; if (key == NULL || key->keyblock.length > ctp->hash->blocksize) return KRB5_BAD_ENCTYPE; if (ctp->ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR) { /* Compute HMAC(key, "signaturekey\0") to get the signing key ks. */ ret = alloc_data(&ds, ctp->hash->hashsize); if (ret != 0) goto cleanup; iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data("signaturekey", 13); ret = krb5int_hmac(ctp->hash, key, &iov, 1, &ds); if (ret) goto cleanup; ks.length = ds.length; ks.contents = (krb5_octet *) ds.data; keyblock = &ks; } else /* For md5-hmac, just use the key. */ keyblock = &key->keyblock; /* Compute the MD5 value of the input. */ ms_usage = krb5int_arcfour_translate_usage(usage); store_32_le(ms_usage, t); hash_iov = k5calloc(num_data + 1, sizeof(krb5_crypto_iov), &ret); if (hash_iov == NULL) goto cleanup; hash_iov[0].flags = KRB5_CRYPTO_TYPE_DATA; hash_iov[0].data = make_data(t, 4); memcpy(hash_iov + 1, data, num_data * sizeof(krb5_crypto_iov)); ret = alloc_data(&hashval, ctp->hash->hashsize); if (ret != 0) goto cleanup; ret = ctp->hash->hash(hash_iov, num_data + 1, &hashval); if (ret != 0) goto cleanup; /* Compute HMAC(ks, md5value). */ iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = hashval; ret = krb5int_hmac_keyblock(ctp->hash, keyblock, &iov, 1, output); cleanup: zapfree(ds.data, ds.length); zapfree(hashval.data, hashval.length); free(hash_iov); return ret; } krb5_error_code k5_hmac_md5(const krb5_data *key, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { krb5_error_code ret; const struct krb5_hash_provider *hash = &krb5int_hash_md5; krb5_keyblock keyblock = { 0 }; krb5_data hashed_key; uint8_t hkeybuf[16]; krb5_crypto_iov iov; /* Hash the key if it is longer than the block size. */ if (key->length > hash->blocksize) { hashed_key = make_data(hkeybuf, sizeof(hkeybuf)); iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *key; ret = hash->hash(&iov, 1, &hashed_key); if (ret) return ret; key = &hashed_key; } keyblock.magic = KV5M_KEYBLOCK; keyblock.length = key->length; keyblock.contents = (uint8_t *)key->data; return krb5int_hmac_keyblock(hash, &keyblock, data, num_data, output); } krb5-1.22.1/src/lib/crypto/krb/s2k_pbkdf2.c0000664000175000017500000001634515051422640020100 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" static const unsigned char kerberos[] = "kerberos"; #define kerberos_len (sizeof(kerberos)-1) krb5_error_code krb5int_dk_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string, const krb5_data *salt, const krb5_data *parms, krb5_keyblock *keyblock) { krb5_error_code ret; size_t keybytes, keylength, concatlen; unsigned char *concat = NULL, *foldstring = NULL, *foldkeydata = NULL; krb5_data indata; krb5_keyblock foldkeyblock; krb5_key foldkey = NULL; /* keyblock->length is checked by krb5int_derive_key. */ keybytes = ktp->enc->keybytes; keylength = ktp->enc->keylength; concatlen = string->length + salt->length; concat = k5alloc(concatlen, &ret); if (ret != 0) goto cleanup; foldstring = k5alloc(keybytes, &ret); if (ret != 0) goto cleanup; foldkeydata = k5alloc(keylength, &ret); if (ret != 0) goto cleanup; /* construct input string ( = string + salt), fold it, make_key it */ if (string->length > 0) memcpy(concat, string->data, string->length); if (salt->length > 0) memcpy(concat + string->length, salt->data, salt->length); krb5int_nfold(concatlen*8, concat, keybytes*8, foldstring); indata.length = keybytes; indata.data = (char *) foldstring; foldkeyblock.length = keylength; foldkeyblock.contents = foldkeydata; foldkeyblock.enctype = ktp->etype; ret = ktp->rand2key(&indata, &foldkeyblock); if (ret != 0) goto cleanup; ret = krb5_k_create_key(NULL, &foldkeyblock, &foldkey); if (ret != 0) goto cleanup; /* now derive the key from this one */ indata.length = kerberos_len; indata.data = (char *) kerberos; ret = krb5int_derive_keyblock(ktp->enc, NULL, foldkey, keyblock, &indata, DERIVE_RFC3961); if (ret != 0) memset(keyblock->contents, 0, keyblock->length); cleanup: zapfree(concat, concatlen); zapfree(foldstring, keybytes); zapfree(foldkeydata, keylength); krb5_k_free_key(NULL, foldkey); return ret; } #define MAX_ITERATION_COUNT 0x1000000L krb5_boolean k5_allow_weak_pbkdf2iter = FALSE; static krb5_error_code pbkdf2_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string, const krb5_data *salt, const krb5_data *pepper, const krb5_data *params, krb5_keyblock *key, enum deriv_alg deriv_alg, unsigned long def_iter_count) { const struct krb5_hash_provider *hash; unsigned long iter_count; krb5_data out; static const krb5_data usage = { KV5M_DATA, 8, "kerberos" }; krb5_key tempkey = NULL; krb5_error_code err; krb5_data sandp = empty_data(); if (params) { unsigned char *p = (unsigned char *) params->data; if (params->length != 4) return KRB5_ERR_BAD_S2K_PARAMS; iter_count = load_32_be(p); /* Zero means 2^32, which is way above what we will accept. Also don't * accept values less than the default, unless we're running tests. */ if (iter_count == 0 || (!k5_allow_weak_pbkdf2iter && iter_count < def_iter_count)) return KRB5_ERR_BAD_S2K_PARAMS; } else iter_count = def_iter_count; /* This is not a protocol specification constraint; this is an implementation limit, which should eventually be controlled by a config file. */ if (iter_count >= MAX_ITERATION_COUNT) return KRB5_ERR_BAD_S2K_PARAMS; /* Use the output keyblock contents for temporary space. */ out.data = (char *) key->contents; out.length = key->length; if (out.length != 16 && out.length != 32) return KRB5_CRYPTO_INTERNAL; if (pepper != NULL) { err = alloc_data(&sandp, pepper->length + 1 + salt->length); if (err) return err; if (pepper->length > 0) memcpy(sandp.data, pepper->data, pepper->length); sandp.data[pepper->length] = '\0'; if (salt->length > 0) memcpy(&sandp.data[pepper->length + 1], salt->data, salt->length); salt = &sandp; } hash = (ktp->hash != NULL) ? ktp->hash : &krb5int_hash_sha1; err = krb5int_pbkdf2_hmac(hash, &out, iter_count, string, salt); if (err) goto cleanup; err = krb5_k_create_key (NULL, key, &tempkey); if (err) goto cleanup; err = krb5int_derive_keyblock(ktp->enc, ktp->hash, tempkey, key, &usage, deriv_alg); cleanup: if (sandp.data) free(sandp.data); if (err) memset (out.data, 0, out.length); krb5_k_free_key (NULL, tempkey); return err; } krb5_error_code krb5int_aes_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key) { return pbkdf2_string_to_key(ktp, string, salt, NULL, params, key, DERIVE_RFC3961, 4096); } krb5_error_code krb5int_camellia_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key) { krb5_data pepper = string2data(ktp->name); return pbkdf2_string_to_key(ktp, string, salt, &pepper, params, key, DERIVE_SP800_108_CMAC, 32768); } krb5_error_code krb5int_aes2_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key) { krb5_data pepper = string2data(ktp->name); return pbkdf2_string_to_key(ktp, string, salt, &pepper, params, key, DERIVE_SP800_108_HMAC, 32768); } krb5-1.22.1/src/lib/crypto/krb/deps0000664000175000017500000011764015051422640016663 0ustar ghudsonghudson# # Generated makefile dependencies follow. # aead.so aead.po $(OUTPRE)aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h aead.c crypto_int.h block_size.so block_size.po $(OUTPRE)block_size.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ block_size.c crypto_int.h cf2.so cf2.po $(OUTPRE)cf2.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cf2.c crypto_int.h checksum_dk_cmac.so checksum_dk_cmac.po $(OUTPRE)checksum_dk_cmac.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ checksum_dk_cmac.c crypto_int.h checksum_dk_hmac.so checksum_dk_hmac.po $(OUTPRE)checksum_dk_hmac.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ checksum_dk_hmac.c crypto_int.h checksum_etm.so checksum_etm.po $(OUTPRE)checksum_etm.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ checksum_etm.c crypto_int.h checksum_hmac_md5.so checksum_hmac_md5.po $(OUTPRE)checksum_hmac_md5.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ checksum_hmac_md5.c crypto_int.h checksum_unkeyed.so checksum_unkeyed.po $(OUTPRE)checksum_unkeyed.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ checksum_unkeyed.c crypto_int.h checksum_length.so checksum_length.po $(OUTPRE)checksum_length.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ checksum_length.c crypto_int.h cksumtype_to_string.so cksumtype_to_string.po $(OUTPRE)cksumtype_to_string.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cksumtype_to_string.c crypto_int.h cksumtypes.so cksumtypes.po $(OUTPRE)cksumtypes.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cksumtypes.c crypto_int.h coll_proof_cksum.so coll_proof_cksum.po $(OUTPRE)coll_proof_cksum.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ coll_proof_cksum.c crypto_int.h crypto_length.so crypto_length.po $(OUTPRE)crypto_length.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h crypto_length.c default_state.so default_state.po $(OUTPRE)default_state.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h default_state.c decrypt.so decrypt.po $(OUTPRE)decrypt.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h decrypt.c decrypt_iov.so decrypt_iov.po $(OUTPRE)decrypt_iov.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h decrypt_iov.c derive.so derive.po $(OUTPRE)derive.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h derive.c encrypt.so encrypt.po $(OUTPRE)encrypt.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h encrypt.c encrypt_iov.so encrypt_iov.po $(OUTPRE)encrypt_iov.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h encrypt_iov.c encrypt_length.so encrypt_length.po $(OUTPRE)encrypt_length.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h encrypt_length.c enctype_util.so enctype_util.po $(OUTPRE)enctype_util.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h enctype_util.c enc_dk_cmac.so enc_dk_cmac.po $(OUTPRE)enc_dk_cmac.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h enc_dk_cmac.c enc_dk_hmac.so enc_dk_hmac.po $(OUTPRE)enc_dk_hmac.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h enc_dk_hmac.c enc_etm.so enc_etm.po $(OUTPRE)enc_etm.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h enc_etm.c enc_raw.so enc_raw.po $(OUTPRE)enc_raw.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h enc_raw.c enc_rc4.so enc_rc4.po $(OUTPRE)enc_rc4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h enc_rc4.c etypes.so etypes.po $(OUTPRE)etypes.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h etypes.c key.so key.po $(OUTPRE)key.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h key.c keyblocks.so keyblocks.po $(OUTPRE)keyblocks.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h keyblocks.c keyed_cksum.so keyed_cksum.po $(OUTPRE)keyed_cksum.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h keyed_cksum.c keyed_checksum_types.so keyed_checksum_types.po $(OUTPRE)keyed_checksum_types.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h keyed_checksum_types.c keylengths.so keylengths.po $(OUTPRE)keylengths.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h keylengths.c make_checksum.so make_checksum.po $(OUTPRE)make_checksum.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h make_checksum.c make_checksum_iov.so make_checksum_iov.po $(OUTPRE)make_checksum_iov.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h make_checksum_iov.c make_random_key.so make_random_key.po $(OUTPRE)make_random_key.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h make_random_key.c mandatory_sumtype.so mandatory_sumtype.po $(OUTPRE)mandatory_sumtype.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h mandatory_sumtype.c nfold.so nfold.po $(OUTPRE)nfold.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h nfold.c old_api_glue.so old_api_glue.po $(OUTPRE)old_api_glue.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h old_api_glue.c prf.so prf.po $(OUTPRE)prf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h prf.c prf_aes2.so prf_aes2.po $(OUTPRE)prf_aes2.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h prf_aes2.c prf_cmac.so prf_cmac.po $(OUTPRE)prf_cmac.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h prf_cmac.c prf_des.so prf_des.po $(OUTPRE)prf_des.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h prf_des.c prf_dk.so prf_dk.po $(OUTPRE)prf_dk.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h prf_dk.c prf_rc4.so prf_rc4.po $(OUTPRE)prf_rc4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h prf_rc4.c prng.so prng.po $(OUTPRE)prng.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h prng.c random_to_key.so random_to_key.po $(OUTPRE)random_to_key.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h random_to_key.c s2k_pbkdf2.so s2k_pbkdf2.po $(OUTPRE)s2k_pbkdf2.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h s2k_pbkdf2.c s2k_rc4.so s2k_rc4.po $(OUTPRE)s2k_rc4.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/k5-utf8.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h s2k_rc4.c state.so state.po $(OUTPRE)state.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h crypto_int.h state.c string_to_cksumtype.so string_to_cksumtype.po $(OUTPRE)string_to_cksumtype.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h string_to_cksumtype.c string_to_key.so string_to_key.po $(OUTPRE)string_to_key.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h string_to_key.c valid_cksumtype.so valid_cksumtype.po $(OUTPRE)valid_cksumtype.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h valid_cksumtype.c verify_checksum.so verify_checksum.po $(OUTPRE)verify_checksum.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h verify_checksum.c verify_checksum_iov.so verify_checksum_iov.po $(OUTPRE)verify_checksum_iov.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ crypto_int.h verify_checksum_iov.c krb5-1.22.1/src/lib/crypto/krb/cksumtypes.c0000664000175000017500000000746615051422640020364 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" const struct krb5_cksumtypes krb5int_cksumtypes_list[] = { { CKSUMTYPE_RSA_MD4, "md4", { 0 }, "RSA-MD4", NULL, &krb5int_hash_md4, krb5int_unkeyed_checksum, NULL, 16, 16, CKSUM_UNKEYED }, { CKSUMTYPE_RSA_MD5, "md5", { 0 }, "RSA-MD5", NULL, &krb5int_hash_md5, krb5int_unkeyed_checksum, NULL, 16, 16, CKSUM_UNKEYED }, { CKSUMTYPE_NIST_SHA, "sha", { 0 }, "NIST-SHA", NULL, &krb5int_hash_sha1, krb5int_unkeyed_checksum, NULL, 20, 20, CKSUM_UNKEYED }, { CKSUMTYPE_SHA1, "sha", { 0 }, "SHA-1", NULL, &krb5int_hash_sha1, krb5int_unkeyed_checksum, NULL, 20, 20, CKSUM_UNKEYED }, { CKSUMTYPE_HMAC_SHA1_DES3, "hmac-sha1-des3", { "hmac-sha1-des3-kd" }, "HMAC-SHA1 DES3 key", &krb5int_enc_des3, &krb5int_hash_sha1, krb5int_dk_checksum, NULL, 20, 20, 0 }, { CKSUMTYPE_HMAC_MD5_ARCFOUR, "hmac-md5-rc4", { "hmac-md5-enc", "hmac-md5-earcfour" }, "Microsoft HMAC MD5", NULL, &krb5int_hash_md5, krb5int_hmacmd5_checksum, NULL, 16, 16, 0 }, { CKSUMTYPE_HMAC_SHA1_96_AES128, "hmac-sha1-96-aes128", { 0 }, "HMAC-SHA1 AES128 key", &krb5int_enc_aes128, &krb5int_hash_sha1, krb5int_dk_checksum, NULL, 20, 12, 0 }, { CKSUMTYPE_HMAC_SHA1_96_AES256, "hmac-sha1-96-aes256", { 0 }, "HMAC-SHA1 AES256 key", &krb5int_enc_aes256, &krb5int_hash_sha1, krb5int_dk_checksum, NULL, 20, 12, 0 }, { CKSUMTYPE_MD5_HMAC_ARCFOUR, "md5-hmac-rc4", { 0 }, "Microsoft MD5 HMAC", &krb5int_enc_arcfour, &krb5int_hash_md5, krb5int_hmacmd5_checksum, NULL, 16, 16, 0 }, { CKSUMTYPE_CMAC_CAMELLIA128, "cmac-camellia128", { 0 }, "CMAC Camellia128 key", &krb5int_enc_camellia128, NULL, krb5int_dk_cmac_checksum, NULL, 16, 16, 0 }, { CKSUMTYPE_CMAC_CAMELLIA256, "cmac-camellia256", { 0 }, "CMAC Camellia256 key", &krb5int_enc_camellia256, NULL, krb5int_dk_cmac_checksum, NULL, 16, 16, 0 }, { CKSUMTYPE_HMAC_SHA256_128_AES128, "hmac-sha256-128-aes128", { 0 }, "HMAC-SHA256 AES128 key", &krb5int_enc_aes128, &krb5int_hash_sha256, krb5int_etm_checksum, NULL, 32, 16, 0 }, { CKSUMTYPE_HMAC_SHA384_192_AES256, "hmac-sha384-192-aes256", { 0 }, "HMAC-SHA384 AES256 key", &krb5int_enc_aes256, &krb5int_hash_sha384, krb5int_etm_checksum, NULL, 48, 24, 0 }, }; const size_t krb5int_cksumtypes_length = sizeof(krb5int_cksumtypes_list) / sizeof(struct krb5_cksumtypes); krb5-1.22.1/src/lib/crypto/krb/verify_checksum.c0000664000175000017500000000663415051422640021337 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_k_verify_checksum(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *data, const krb5_checksum *cksum, krb5_boolean *valid) { const struct krb5_cksumtypes *ctp; krb5_cksumtype cksumtype; krb5_crypto_iov iov; krb5_error_code ret; krb5_data cksum_data; krb5_checksum computed; iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *data; /* A 0 checksum type means use the mandatory checksum. */ cksumtype = cksum->checksum_type; if (cksumtype == 0 && key != NULL) { ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype, &cksumtype); if (ret) return ret; } ctp = find_cksumtype(cksumtype); if (ctp == NULL) return KRB5_BAD_ENCTYPE; ret = verify_key(ctp, key); if (ret != 0) return ret; /* If there's actually a verify function, call it. */ cksum_data = make_data(cksum->contents, cksum->length); if (ctp->verify != NULL) return ctp->verify(ctp, key, usage, &iov, 1, &cksum_data, valid); /* Otherwise, make the checksum again, and compare. */ if (cksum->length != ctp->output_size) return KRB5_BAD_MSIZE; ret = krb5_k_make_checksum(context, cksum->checksum_type, key, usage, data, &computed); if (ret) return ret; *valid = (k5_bcmp(computed.contents, cksum->contents, ctp->output_size) == 0); free(computed.contents); return 0; } krb5_error_code KRB5_CALLCONV krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *data, const krb5_checksum *cksum, krb5_boolean *valid) { krb5_key key = NULL; krb5_error_code ret; if (keyblock != NULL) { ret = krb5_k_create_key(context, keyblock, &key); if (ret != 0) return ret; } ret = krb5_k_verify_checksum(context, key, usage, data, cksum, valid); krb5_k_free_key(context, key); return ret; } krb5-1.22.1/src/lib/crypto/krb/enctype_util.c0000664000175000017500000001200615051422640020643 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/enctype_util.c */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* * krb5int_c_valid_enctype() * krb5int_c_weak_enctype() * krb5_c_enctype_compare() * krb5_string_to_enctype() * krb5_enctype_to_string() */ #include "crypto_int.h" struct { krb5_enctype etype; const char *name; } unsupported_etypes[] = { { ENCTYPE_DES_CBC_CRC, "des-cbc-crc" }, { ENCTYPE_DES_CBC_MD4, "des-cbc-md4" }, { ENCTYPE_DES_CBC_MD5, "des-cbc-md5" }, { ENCTYPE_DES_CBC_RAW, "des-cbc-raw" }, { ENCTYPE_DES_HMAC_SHA1, "des-hmac-sha1" }, { ENCTYPE_NULL, NULL } }; krb5_boolean KRB5_CALLCONV krb5_c_valid_enctype(krb5_enctype etype) { return (find_enctype(etype) != NULL); } krb5_boolean KRB5_CALLCONV krb5int_c_weak_enctype(krb5_enctype etype) { const struct krb5_keytypes *ktp; ktp = find_enctype(etype); return (ktp != NULL && (ktp->flags & ETYPE_WEAK) != 0); } krb5_boolean KRB5_CALLCONV krb5int_c_deprecated_enctype(krb5_enctype etype) { const struct krb5_keytypes *ktp = find_enctype(etype); return ktp == NULL || (ktp->flags & ETYPE_DEPRECATED) != 0; } krb5_error_code KRB5_CALLCONV krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2, krb5_boolean *similar) { const struct krb5_keytypes *ktp1, *ktp2; ktp1 = find_enctype(e1); ktp2 = find_enctype(e2); if (ktp1 == NULL || ktp2 == NULL) return KRB5_BAD_ENCTYPE; *similar = (ktp1->enc == ktp2->enc && ktp1->str2key == ktp2->str2key); return 0; } krb5_error_code KRB5_CALLCONV krb5_string_to_enctype(char *string, krb5_enctype *enctypep) { int i; unsigned int j; const char *alias; const struct krb5_keytypes *ktp; for (i = 0; i < krb5int_enctypes_length; i++) { ktp = &krb5int_enctypes_list[i]; if (strcasecmp(ktp->name, string) == 0) { *enctypep = ktp->etype; return 0; } for (j = 0; j < MAX_ETYPE_ALIASES; j++) { alias = ktp->aliases[j]; if (alias == NULL) break; if (strcasecmp(alias, string) == 0) { *enctypep = ktp->etype; return 0; } } } return EINVAL; } krb5_error_code KRB5_CALLCONV krb5_enctype_to_string(krb5_enctype enctype, char *buffer, size_t buflen) { const struct krb5_keytypes *ktp; ktp = find_enctype(enctype); if (ktp == NULL) return EINVAL; if (strlcpy(buffer, ktp->out_string, buflen) >= buflen) return ENOMEM; return 0; } krb5_error_code KRB5_CALLCONV krb5_enctype_to_name(krb5_enctype enctype, krb5_boolean shortest, char *buffer, size_t buflen) { const struct krb5_keytypes *ktp; const char *name; int i; for (i = 0; unsupported_etypes[i].etype != ENCTYPE_NULL; i++) { if (enctype == unsupported_etypes[i].etype) { if (strlcpy(buffer, unsupported_etypes[i].name, buflen) >= buflen) return ENOMEM; return 0; } } ktp = find_enctype(enctype); if (ktp == NULL) return EINVAL; name = ktp->name; if (shortest) { for (i = 0; i < MAX_ETYPE_ALIASES; i++) { if (ktp->aliases[i] == NULL) break; if (strlen(ktp->aliases[i]) < strlen(name)) name = ktp->aliases[i]; } } if (strlcpy(buffer, name, buflen) >= buflen) return ENOMEM; return 0; } /* The security of a mechanism cannot be summarized with a simple integer * value, but we provide a per-enctype value for Cyrus SASL's SSF. */ krb5_error_code k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out) { const struct krb5_keytypes *ktp; *ssf_out = 0; ktp = find_enctype(enctype); if (ktp == NULL) return EINVAL; *ssf_out = ktp->ssf; return 0; } krb5-1.22.1/src/lib/crypto/krb/encrypt_iov.c0000664000175000017500000000440315051422640020502 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/encrypt_iov.c */ /* * Copyright 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_k_encrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data) { const struct krb5_keytypes *ktp; ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; return ktp->encrypt(ktp, key, usage, cipher_state, data, num_data); } krb5_error_code KRB5_CALLCONV krb5_c_encrypt_iov(krb5_context context, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data) { krb5_key key; krb5_error_code ret; ret = krb5_k_create_key(context, keyblock, &key); if (ret != 0) return ret; ret = krb5_k_encrypt_iov(context, key, usage, cipher_state, data, num_data); krb5_k_free_key(context, key); return ret; } krb5-1.22.1/src/lib/crypto/krb/state.c0000664000175000017500000000447015051422640017265 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/state.c */ /* * Copyright (C) 2001 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * * * * * Section 6 (Encryption) of the Kerberos revisions document defines * cipher states to be used to chain encryptions and decryptions * together. Examples of cipher states include initialization vectors * for CBC encription. This file contains implementations of * krb5_c_init_state and krb5_c_free_state used by clients of the * Kerberos crypto library. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_init_state (krb5_context context, const krb5_keyblock *key, krb5_keyusage keyusage, krb5_data *new_state) { const struct krb5_keytypes *ktp; ktp = find_enctype(key->enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; return ktp->enc->init_state(key, keyusage, new_state); } krb5_error_code KRB5_CALLCONV krb5_c_free_state(krb5_context context, const krb5_keyblock *key, krb5_data *state) { const struct krb5_keytypes *ktp; ktp = find_enctype(key->enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; ktp->enc->free_state(state); return 0; } krb5-1.22.1/src/lib/crypto/krb/decrypt.c0000664000175000017500000000737715051422640017630 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_k_decrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_enc_data *input, krb5_data *output) { const struct krb5_keytypes *ktp; krb5_crypto_iov iov[4]; krb5_error_code ret; unsigned int header_len, trailer_len, plain_len; char *scratch = NULL; ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; if (input->enctype != ENCTYPE_UNKNOWN && ktp->etype != input->enctype) return KRB5_BAD_ENCTYPE; /* Verify the input and output lengths. */ header_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_HEADER); trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER); if (input->ciphertext.length < header_len + trailer_len) return KRB5_BAD_MSIZE; plain_len = input->ciphertext.length - header_len - trailer_len; if (output->length < plain_len) return KRB5_BAD_MSIZE; scratch = k5alloc(header_len + trailer_len, &ret); if (scratch == NULL) return ret; iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; iov[0].data = make_data(scratch, header_len); memcpy(iov[0].data.data, input->ciphertext.data, header_len); iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data = make_data(output->data, plain_len); memcpy(iov[1].data.data, input->ciphertext.data + header_len, plain_len); /* Use empty padding since tokens don't indicate the padding length. */ iov[2].flags = KRB5_CRYPTO_TYPE_PADDING; iov[2].data = empty_data(); iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER; iov[3].data = make_data(scratch + header_len, trailer_len); memcpy(iov[3].data.data, input->ciphertext.data + header_len + plain_len, trailer_len); ret = ktp->decrypt(ktp, key, usage, cipher_state, iov, 4); if (ret != 0) zap(output->data, plain_len); else output->length = plain_len; zapfree(scratch, header_len + trailer_len); return ret; } krb5_error_code KRB5_CALLCONV krb5_c_decrypt(krb5_context context, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_enc_data *input, krb5_data *output) { krb5_key key; krb5_error_code ret; ret = krb5_k_create_key(context, keyblock, &key); if (ret != 0) return ret; ret = krb5_k_decrypt(context, key, usage, cipher_state, input, output); krb5_k_free_key(context, key); return ret; } krb5-1.22.1/src/lib/crypto/krb/prf_aes2.c0000664000175000017500000000342715051422640017647 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/prf_aes2.c - PRF for aes-sha2 enctypes */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "crypto_int.h" krb5_error_code krb5int_aes2_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out) { krb5_data label = string2data("prf"); return k5_sp800_108_counter_hmac(ktp->hash, key, &label, in, out); } krb5-1.22.1/src/lib/crypto/krb/verify_checksum_iov.c0000664000175000017500000000736215051422640022213 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/verify_checksum_iov.c */ /* * Copyright 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_k_verify_checksum_iov(krb5_context context, krb5_cksumtype checksum_type, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_boolean *valid) { const struct krb5_cksumtypes *ctp; krb5_error_code ret; krb5_data computed; krb5_crypto_iov *checksum; if (checksum_type == 0 && key != NULL) { ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype, &checksum_type); if (ret != 0) return ret; } ctp = find_cksumtype(checksum_type); if (ctp == NULL) return KRB5_BAD_ENCTYPE; ret = verify_key(ctp, key); if (ret != 0) return ret; checksum = krb5int_c_locate_iov((krb5_crypto_iov *)data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM); if (checksum == NULL || checksum->data.length != ctp->output_size) return KRB5_BAD_MSIZE; /* If there's actually a verify function, call it. */ if (ctp->verify != NULL) { return ctp->verify(ctp, key, usage, data, num_data, &checksum->data, valid); } ret = alloc_data(&computed, ctp->compute_size); if (ret != 0) return ret; ret = ctp->checksum(ctp, key, usage, data, num_data, &computed); if (ret == 0) { *valid = (k5_bcmp(computed.data, checksum->data.data, ctp->output_size) == 0); } zapfree(computed.data, ctp->compute_size); return ret; } krb5_error_code KRB5_CALLCONV krb5_c_verify_checksum_iov(krb5_context context, krb5_cksumtype checksum_type, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_boolean *valid) { krb5_key key = NULL; krb5_error_code ret; if (keyblock != NULL) { ret = krb5_k_create_key(context, keyblock, &key); if (ret != 0) return ret; } ret = krb5_k_verify_checksum_iov(context, checksum_type, key, usage, data, num_data, valid); krb5_k_free_key(context, key); return ret; } krb5-1.22.1/src/lib/crypto/krb/aead.c0000664000175000017500000001603115051422640017033 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/aead.c */ /* * Copyright 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_crypto_iov * krb5int_c_locate_iov(krb5_crypto_iov *data, size_t num_data, krb5_cryptotype type) { size_t i; krb5_crypto_iov *iov = NULL; if (data == NULL) return NULL; for (i = 0; i < num_data; i++) { if (data[i].flags == type) { if (iov == NULL) iov = &data[i]; else return NULL; /* can't appear twice */ } } return iov; } krb5_error_code krb5int_c_iov_decrypt_stream(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { krb5_error_code ret; unsigned int header_len, trailer_len; krb5_crypto_iov *iov; krb5_crypto_iov *stream; size_t i, j; int got_data = 0; stream = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_STREAM); assert(stream != NULL); header_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_HEADER); trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER); if (stream->data.length < header_len + trailer_len) return KRB5_BAD_MSIZE; iov = calloc(num_data + 2, sizeof(krb5_crypto_iov)); if (iov == NULL) return ENOMEM; i = 0; iov[i].flags = KRB5_CRYPTO_TYPE_HEADER; /* takes place of STREAM */ iov[i].data = make_data(stream->data.data, header_len); i++; for (j = 0; j < num_data; j++) { if (data[j].flags == KRB5_CRYPTO_TYPE_DATA) { if (got_data) { free(iov); return KRB5_BAD_MSIZE; } got_data++; data[j].data.data = stream->data.data + header_len; data[j].data.length = stream->data.length - header_len - trailer_len; } if (data[j].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY || data[j].flags == KRB5_CRYPTO_TYPE_DATA) iov[i++] = data[j]; } /* Use empty padding since tokens don't indicate the padding length. */ iov[i].flags = KRB5_CRYPTO_TYPE_PADDING; iov[i].data = empty_data(); i++; iov[i].flags = KRB5_CRYPTO_TYPE_TRAILER; iov[i].data = make_data(stream->data.data + stream->data.length - trailer_len, trailer_len); i++; assert(i <= num_data + 2); ret = ktp->decrypt(ktp, key, keyusage, ivec, iov, i); free(iov); return ret; } unsigned int krb5int_c_padding_length(const struct krb5_keytypes *ktp, size_t data_length) { unsigned int header, padding; /* * Add in the header length since the header is encrypted along with the * data. (arcfour violates this assumption since not all of the header is * encrypted, but that's okay since it has no padding. If there is ever an * enctype using a similar token format and a block cipher, we will have to * move this logic into an enctype-dependent function.) */ header = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_HEADER); data_length += header; padding = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING); if (padding == 0 || (data_length % padding) == 0) return 0; else return padding - (data_length % padding); } /* Return the next iov (starting from ind) which cursor should process, or * cursor->iov_count if there are none remaining. */ static size_t next_iov_to_process(struct iov_cursor *cursor, size_t ind) { const krb5_crypto_iov *iov; for (; ind < cursor->iov_count; ind++) { iov = &cursor->iov[ind]; if (cursor->signing ? SIGN_IOV(iov) : ENCRYPT_IOV(iov)) break; } return ind; } void k5_iov_cursor_init(struct iov_cursor *cursor, const krb5_crypto_iov *iov, size_t count, size_t block_size, krb5_boolean signing) { cursor->iov = iov; cursor->iov_count = count; cursor->block_size = block_size; cursor->signing = signing; cursor->in_iov = next_iov_to_process(cursor, 0); cursor->out_iov = cursor->in_iov; cursor->in_pos = cursor->out_pos = 0; } /* Fetch one block from cursor's input position. */ krb5_boolean k5_iov_cursor_get(struct iov_cursor *cursor, unsigned char *block) { size_t nbytes, bsz = cursor->block_size, remain = cursor->block_size; const krb5_crypto_iov *iov; remain = cursor->block_size; while (remain > 0 && cursor->in_iov < cursor->iov_count) { iov = &cursor->iov[cursor->in_iov]; nbytes = iov->data.length - cursor->in_pos; if (nbytes > remain) nbytes = remain; memcpy(block + bsz - remain, iov->data.data + cursor->in_pos, nbytes); cursor->in_pos += nbytes; remain -= nbytes; if (cursor->in_pos == iov->data.length) { cursor->in_iov = next_iov_to_process(cursor, cursor->in_iov + 1); cursor->in_pos = 0; } } if (remain == bsz) return FALSE; if (remain > 0) memset(block + bsz - remain, 0, remain); return TRUE; } /* Write a block to a cursor's output position. */ void k5_iov_cursor_put(struct iov_cursor *cursor, unsigned char *block) { size_t nbytes, bsz = cursor->block_size, remain = cursor->block_size; const krb5_crypto_iov *iov; remain = cursor->block_size; while (remain > 0 && cursor->out_iov < cursor->iov_count) { iov = &cursor->iov[cursor->out_iov]; nbytes = iov->data.length - cursor->out_pos; if (nbytes > remain) nbytes = remain; memcpy(iov->data.data + cursor->out_pos, block + bsz - remain, nbytes); cursor->out_pos += nbytes; remain -= nbytes; if (cursor->out_pos == iov->data.length) { cursor->out_iov = next_iov_to_process(cursor, cursor->out_iov + 1); cursor->out_pos = 0; } } } krb5-1.22.1/src/lib/crypto/krb/keylengths.c0000664000175000017500000000375715051422640020331 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * COPYRIGHT (c) 2006 * The Regents of the University of Michigan * ALL RIGHTS RESERVED * * Permission is granted to use, copy, create derivative works * and redistribute this software and such derivative works * for any purpose, so long as the name of The University of * Michigan is not used in any advertising or publicity * pertaining to the use of distribution of this software * without specific, written prior authorization. If the * above copyright notice or any other identification of the * University of Michigan is included in any copy of any * portion of this software, then the disclaimer below must * also be included. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF * SUCH DAMAGES. */ #include "crypto_int.h" /* * keybytes is the number of bytes required as input to make a key, * keylength is the length of the final key in bytes */ krb5_error_code KRB5_CALLCONV krb5_c_keylengths(krb5_context context, krb5_enctype enctype, size_t *keybytes, size_t *keylength) { const struct krb5_keytypes *ktp; if (keybytes == NULL && keylength == NULL) return EINVAL; ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; if (keybytes) *keybytes = ktp->enc->keybytes; if (keylength) *keylength = ktp->enc->keylength; return 0; } krb5-1.22.1/src/lib/crypto/krb/cksumtype_to_string.c0000664000175000017500000000316015051422640022254 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_cksumtype_to_string(krb5_cksumtype cksumtype, char *buffer, size_t buflen) { const struct krb5_cksumtypes *ctp; ctp = find_cksumtype(cksumtype); if (ctp == NULL) return KRB5_BAD_ENCTYPE; if (strlcpy(buffer, ctp->out_string, buflen) >= buflen) return ENOMEM; return 0; } krb5-1.22.1/src/lib/crypto/krb/encrypt.c0000664000175000017500000000710315051422640017625 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_k_encrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_data *input, krb5_enc_data *output) { const struct krb5_keytypes *ktp; krb5_crypto_iov iov[4]; krb5_error_code ret; unsigned int header_len, padding_len, trailer_len, total_len; ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; output->magic = KV5M_ENC_DATA; output->kvno = 0; output->enctype = key->keyblock.enctype; /* Get the lengths of the token parts and compute the total. */ header_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_HEADER); padding_len = krb5int_c_padding_length(ktp, input->length); trailer_len = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER); total_len = header_len + input->length + padding_len + trailer_len; if (output->ciphertext.length < total_len) return KRB5_BAD_MSIZE; /* Set up the iov structures for the token parts. */ iov[0].flags = KRB5_CRYPTO_TYPE_HEADER; iov[0].data = make_data(output->ciphertext.data, header_len); iov[1].flags = KRB5_CRYPTO_TYPE_DATA; iov[1].data = make_data(output->ciphertext.data + header_len, input->length); if (input->length > 0) memcpy(iov[1].data.data, input->data, input->length); iov[2].flags = KRB5_CRYPTO_TYPE_PADDING; iov[2].data = make_data(iov[1].data.data + input->length, padding_len); iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER; iov[3].data = make_data(iov[2].data.data + padding_len, trailer_len); ret = ktp->encrypt(ktp, key, usage, cipher_state, iov, 4); if (ret != 0) zap(iov[1].data.data, iov[1].data.length); else output->ciphertext.length = total_len; return ret; } krb5_error_code KRB5_CALLCONV krb5_c_encrypt(krb5_context context, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_data *input, krb5_enc_data *output) { krb5_key key; krb5_error_code ret; ret = krb5_k_create_key(context, keyblock, &key); if (ret != 0) return ret; ret = krb5_k_encrypt(context, key, usage, cipher_state, input, output); krb5_k_free_key(context, key); return ret; } krb5-1.22.1/src/lib/crypto/krb/key.c0000664000175000017500000000647015051422640016737 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * Functions for manipulating krb5_key structures */ #include "crypto_int.h" /* * The krb5_key data type wraps an exposed keyblock in an opaque data * structure, to allow for internal optimizations such as caching of * derived keys. */ /* Create a krb5_key from the enctype and key data in a keyblock. */ krb5_error_code KRB5_CALLCONV krb5_k_create_key(krb5_context context, const krb5_keyblock *key_data, krb5_key *out) { krb5_key key = NULL; krb5_error_code code; *out = NULL; key = malloc(sizeof(*key)); if (key == NULL) return ENOMEM; code = krb5int_c_copy_keyblock_contents(context, key_data, &key->keyblock); if (code) goto cleanup; key->refcount = 1; key->derived = NULL; key->cache = NULL; *out = key; return 0; cleanup: free(key); return code; } void KRB5_CALLCONV krb5_k_reference_key(krb5_context context, krb5_key key) { if (key) key->refcount++; } /* Free the memory used by a krb5_key. */ void KRB5_CALLCONV krb5_k_free_key(krb5_context context, krb5_key key) { struct derived_key *dk; const struct krb5_keytypes *ktp; if (key == NULL || --key->refcount > 0) return; /* Free the derived key cache. */ while ((dk = key->derived) != NULL) { key->derived = dk->next; free(dk->constant.data); krb5_k_free_key(context, dk->dkey); free(dk); } krb5int_c_free_keyblock_contents(context, &key->keyblock); if (key->cache) { ktp = find_enctype(key->keyblock.enctype); if (ktp && ktp->enc->key_cleanup) ktp->enc->key_cleanup(key); } free(key); } /* Retrieve a copy of the keyblock from a krb5_key. */ krb5_error_code KRB5_CALLCONV krb5_k_key_keyblock(krb5_context context, krb5_key key, krb5_keyblock **key_data) { return krb5int_c_copy_keyblock(context, &key->keyblock, key_data); } /* Retrieve the enctype of a krb5_key. */ krb5_enctype KRB5_CALLCONV krb5_k_key_enctype(krb5_context context, krb5_key key) { return key->keyblock.enctype; } krb5-1.22.1/src/lib/crypto/krb/checksum_dk_cmac.c0000664000175000017500000000444415051422640021411 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/checksum_dk_cmac.c */ /* * Copyright 2010 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ krb5_error_code krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { const struct krb5_enc_provider *enc = ctp->enc; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data datain; krb5_key kc; /* Derive the key. */ datain = make_data(constantdata, K5CLENGTH); store_32_be(usage, constantdata); constantdata[4] = (char) 0x99; ret = krb5int_derive_key(enc, NULL, key, &kc, &datain, DERIVE_SP800_108_CMAC); if (ret != 0) return ret; /* Hash the data. */ ret = krb5int_cmac_checksum(enc, kc, data, num_data, output); if (ret != 0) memset(output->data, 0, output->length); krb5_k_free_key(NULL, kc); return ret; } krb5-1.22.1/src/lib/crypto/krb/default_state.c0000664000175000017500000000371615051422640020773 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2001, 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * Section 6 (Encryption) of the Kerberos revisions document defines * cipher states to be used to chain encryptions and decryptions * together. Examples of cipher states include initialization vectors * for CBC encription. Most Kerberos encryption systems can share * code for initializing and freeing cipher states. This file * contains that default code. */ #include "crypto_int.h" krb5_error_code krb5int_des_init_state(const krb5_keyblock *key, krb5_keyusage usage, krb5_data *state_out) { if (alloc_data(state_out, 8)) return ENOMEM; return 0; } void krb5int_default_free_state(krb5_data *state) { free(state->data); *state = empty_data(); } krb5-1.22.1/src/lib/crypto/krb/make_checksum_iov.c0000664000175000017500000000654315051422640021624 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/make_checksum_iov.c */ /* * Copyright 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_k_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, krb5_crypto_iov *data, size_t num_data) { krb5_error_code ret; krb5_data cksum_data; krb5_crypto_iov *checksum; const struct krb5_cksumtypes *ctp; if (cksumtype == 0 && key != NULL) { ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype, &cksumtype); if (ret != 0) return ret; } ctp = find_cksumtype(cksumtype); if (ctp == NULL) return KRB5_BAD_ENCTYPE; ret = verify_key(ctp, key); if (ret != 0) return ret; checksum = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM); if (checksum == NULL || checksum->data.length < ctp->output_size) return(KRB5_BAD_MSIZE); ret = alloc_data(&cksum_data, ctp->compute_size); if (ret != 0) return ret; ret = ctp->checksum(ctp, key, usage, data, num_data, &cksum_data); if (ret != 0) goto cleanup; memcpy(checksum->data.data, cksum_data.data, ctp->output_size); checksum->data.length = ctp->output_size; cleanup: zapfree(cksum_data.data, ctp->compute_size); return ret; } krb5_error_code KRB5_CALLCONV krb5_c_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock *keyblock, krb5_keyusage usage, krb5_crypto_iov *data, size_t num_data) { krb5_key key = NULL; krb5_error_code ret; if (keyblock != NULL) { ret = krb5_k_create_key(context, keyblock, &key); if (ret != 0) return ret; } ret = krb5_k_make_checksum_iov(context, cksumtype, key, usage, data, num_data); krb5_k_free_key(context, key); return ret; } krb5-1.22.1/src/lib/crypto/krb/prf_dk.c0000664000175000017500000000525415051422640017413 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/prf_dk.c - RFC 3961 simplified profile PRF */ /* * Copyright (C) 2004 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code krb5int_dk_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out) { const struct krb5_enc_provider *enc = ktp->enc; const struct krb5_hash_provider *hash = ktp->hash; krb5_crypto_iov iov; krb5_data cksum = empty_data(), prfconst = make_data("prf", 3); krb5_key kp = NULL; krb5_error_code ret; /* Hash the input data into an allocated buffer. */ ret = alloc_data(&cksum, hash->hashsize); if (ret != 0) goto cleanup; iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *in; ret = hash->hash(&iov, 1, &cksum); if (ret != 0) goto cleanup; /* Derive a key using the PRF constant. */ ret = krb5int_derive_key(ktp->enc, NULL, key, &kp, &prfconst, DERIVE_RFC3961); if (ret != 0) goto cleanup; /* Truncate the hash to the closest multiple of the block size. */ iov.data.data = cksum.data; iov.data.length = (hash->hashsize / enc->block_size) * enc->block_size; /* Encrypt the truncated hash in the derived key to get the output. */ ret = ktp->enc->encrypt(kp, NULL, &iov, 1); if (ret != 0) goto cleanup; memcpy(out->data, iov.data.data, out->length); cleanup: zapfree(cksum.data, hash->hashsize); krb5_k_free_key(NULL, kp); return ret; } krb5-1.22.1/src/lib/crypto/krb/enc_rc4.c0000664000175000017500000003006415051422640017460 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* ARCFOUR cipher (based on a cipher posted on the Usenet in Spring-95). This cipher is widely believed and has been tested to be equivalent with the RC4 cipher from RSA Data Security, Inc. (RC4 is a trademark of RSA Data Security) */ #include "crypto_int.h" #define CONFOUNDERLENGTH 8 const char l40[] = "fortybits"; krb5_keyusage krb5int_arcfour_translate_usage(krb5_keyusage usage) { switch (usage) { case 1: return 1; /* AS-REQ PA-ENC-TIMESTAMP padata timestamp, */ case 2: return 2; /* ticket from kdc */ case 3: return 8; /* as-rep encrypted part */ case 4: return 4; /* tgs-req authz data */ case 5: return 5; /* tgs-req authz data in subkey */ case 6: return 6; /* tgs-req authenticator cksum */ case 7: return 7; /* tgs-req authenticator */ case 8: return 8; case 9: return 9; /* tgs-rep encrypted with subkey */ case 10: return 10; /* ap-rep authentication cksum (never used by MS) */ case 11: return 11; /* app-req authenticator */ case 12: return 12; /* app-rep encrypted part */ case 23: return 13; /* sign wrap token*/ default: return usage; } } /* Derive a usage key from a session key and krb5 usage constant. */ static krb5_error_code usage_key(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, const krb5_keyblock *session_keyblock, krb5_keyusage usage, krb5_keyblock *out) { char salt_buf[14]; unsigned int salt_len; krb5_data out_data = make_data(out->contents, out->length); krb5_crypto_iov iov; krb5_keyusage ms_usage; /* Generate the salt. */ ms_usage = krb5int_arcfour_translate_usage(usage); if (session_keyblock->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { memcpy(salt_buf, l40, 10); store_32_le(ms_usage, salt_buf + 10); salt_len = 14; } else { store_32_le(ms_usage, salt_buf); salt_len = 4; } /* Compute HMAC(key, salt) to produce the usage key. */ iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = make_data(salt_buf, salt_len); return krb5int_hmac_keyblock(hash, session_keyblock, &iov, 1, &out_data); } /* Derive an encryption key from a usage key and (typically) checksum. */ static krb5_error_code enc_key(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, const krb5_keyblock *usage_keyblock, const krb5_data *checksum, krb5_keyblock *out) { krb5_keyblock *trunc_keyblock = NULL; krb5_data out_data = make_data(out->contents, out->length); krb5_crypto_iov iov; krb5_error_code ret; /* Copy usage_keyblock to trunc_keyblock and truncate if exportable. */ ret = krb5int_c_copy_keyblock(NULL, usage_keyblock, &trunc_keyblock); if (ret != 0) return ret; if (trunc_keyblock->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) memset(trunc_keyblock->contents + 7, 0xab, 9); /* Compute HMAC(trunc_key, checksum) to produce the encryption key. */ iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *checksum; ret = krb5int_hmac_keyblock(hash, trunc_keyblock, &iov, 1, &out_data); krb5int_c_free_keyblock(NULL, trunc_keyblock); return ret; } unsigned int krb5int_arcfour_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type) { switch (type) { case KRB5_CRYPTO_TYPE_HEADER: return ktp->hash->hashsize + CONFOUNDERLENGTH; case KRB5_CRYPTO_TYPE_PADDING: case KRB5_CRYPTO_TYPE_TRAILER: return 0; case KRB5_CRYPTO_TYPE_CHECKSUM: return ktp->hash->hashsize; default: assert(0 && "invalid cryptotype passed to krb5int_arcfour_crypto_length"); return 0; } } /* Encrypt or decrypt using a keyblock. */ static krb5_error_code keyblock_crypt(const struct krb5_enc_provider *enc, krb5_keyblock *keyblock, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { krb5_error_code ret; krb5_key key; ret = krb5_k_create_key(NULL, keyblock, &key); if (ret != 0) return ret; /* Works for encryption or decryption since arcfour is a stream cipher. */ ret = enc->encrypt(key, ivec, data, num_data); krb5_k_free_key(NULL, key); return ret; } krb5_error_code krb5int_arcfour_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { const struct krb5_enc_provider *enc = ktp->enc; const struct krb5_hash_provider *hash = ktp->hash; krb5_error_code ret; krb5_crypto_iov *header, *trailer; krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL; krb5_data checksum, confounder, header_data; size_t i; /* * Caller must have provided space for the header, padding * and trailer; per RFC 4757 we will arrange it as: * * Checksum | E(Confounder | Plaintext) */ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); if (header == NULL || header->data.length < hash->hashsize + CONFOUNDERLENGTH) return KRB5_BAD_MSIZE; header_data = header->data; /* Trailer may be absent. */ trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); if (trailer != NULL) trailer->data.length = 0; /* Ensure that there is no padding. */ for (i = 0; i < num_data; i++) { if (data[i].flags == KRB5_CRYPTO_TYPE_PADDING) data[i].data.length = 0; } ret = krb5int_c_init_keyblock(NULL, key->keyblock.enctype, enc->keybytes, &usage_keyblock); if (ret != 0) goto cleanup; ret = krb5int_c_init_keyblock(NULL, key->keyblock.enctype, enc->keybytes, &enc_keyblock); if (ret != 0) goto cleanup; /* Derive a usage key from the session key and usage. */ ret = usage_key(enc, hash, &key->keyblock, usage, usage_keyblock); if (ret != 0) goto cleanup; /* Generate a confounder in the header block, after the checksum. */ header->data.length = hash->hashsize + CONFOUNDERLENGTH; confounder = make_data(header->data.data + hash->hashsize, CONFOUNDERLENGTH); ret = krb5_c_random_make_octets(0, &confounder); if (ret != 0) goto cleanup; checksum = make_data(header->data.data, hash->hashsize); /* Adjust pointers so confounder is at start of header. */ header->data.length -= hash->hashsize; header->data.data += hash->hashsize; /* Compute the checksum using the usage key. */ ret = krb5int_hmac_keyblock(hash, usage_keyblock, data, num_data, &checksum); if (ret != 0) goto cleanup; /* Derive the encryption key from the usage key and checksum. */ ret = enc_key(enc, hash, usage_keyblock, &checksum, enc_keyblock); if (ret) goto cleanup; ret = keyblock_crypt(enc, enc_keyblock, ivec, data, num_data); cleanup: header->data = header_data; /* Restore header pointers. */ krb5int_c_free_keyblock(NULL, usage_keyblock); krb5int_c_free_keyblock(NULL, enc_keyblock); return ret; } krb5_error_code krb5int_arcfour_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { const struct krb5_enc_provider *enc = ktp->enc; const struct krb5_hash_provider *hash = ktp->hash; krb5_error_code ret; krb5_crypto_iov *header, *trailer; krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL; krb5_data checksum, header_data, comp_checksum = empty_data(); header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); if (header == NULL || header->data.length != hash->hashsize + CONFOUNDERLENGTH) return KRB5_BAD_MSIZE; header_data = header->data; trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); if (trailer != NULL && trailer->data.length != 0) return KRB5_BAD_MSIZE; /* Allocate buffers. */ ret = alloc_data(&comp_checksum, hash->hashsize); if (ret != 0) goto cleanup; ret = krb5int_c_init_keyblock(NULL, key->keyblock.enctype, enc->keybytes, &usage_keyblock); if (ret != 0) goto cleanup; ret = krb5int_c_init_keyblock(NULL, key->keyblock.enctype, enc->keybytes, &enc_keyblock); if (ret != 0) goto cleanup; checksum = make_data(header->data.data, hash->hashsize); /* Adjust pointers so confounder is at start of header. */ header->data.length -= hash->hashsize; header->data.data += hash->hashsize; /* We may have to try two usage values; see below. */ do { /* Derive a usage key from the session key and usage. */ ret = usage_key(enc, hash, &key->keyblock, usage, usage_keyblock); if (ret != 0) goto cleanup; /* Derive the encryption key from the usage key and checksum. */ ret = enc_key(enc, hash, usage_keyblock, &checksum, enc_keyblock); if (ret) goto cleanup; /* Decrypt the ciphertext. */ ret = keyblock_crypt(enc, enc_keyblock, ivec, data, num_data); if (ret != 0) goto cleanup; /* Compute HMAC(usage key, plaintext) to get the checksum. */ ret = krb5int_hmac_keyblock(hash, usage_keyblock, data, num_data, &comp_checksum); if (ret != 0) goto cleanup; if (k5_bcmp(checksum.data, comp_checksum.data, hash->hashsize) != 0) { if (usage == 9) { /* * RFC 4757 specifies usage 8 for TGS-REP encrypted parts * encrypted in a subkey, but the value used by MS is actually * 9. We now use 9 to start with, but fall back to 8 on * failure in case we are communicating with a KDC using the * value from the RFC. ivec is always NULL in this case. * We need to re-encrypt the data in the wrong key first. */ ret = keyblock_crypt(enc, enc_keyblock, NULL, data, num_data); if (ret != 0) goto cleanup; usage = 8; continue; } ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; goto cleanup; } break; } while (1); cleanup: header->data = header_data; /* Restore header pointers. */ krb5int_c_free_keyblock(NULL, usage_keyblock); krb5int_c_free_keyblock(NULL, enc_keyblock); zapfree(comp_checksum.data, comp_checksum.length); return ret; } krb5_error_code krb5int_arcfour_gsscrypt(const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *kd_data, krb5_crypto_iov *data, size_t num_data) { const struct krb5_enc_provider *enc = &krb5int_enc_arcfour; const struct krb5_hash_provider *hash = &krb5int_hash_md5; krb5_keyblock *usage_keyblock = NULL, *enc_keyblock = NULL; krb5_error_code ret; ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes, &usage_keyblock); if (ret != 0) goto cleanup; ret = krb5int_c_init_keyblock(NULL, keyblock->enctype, enc->keybytes, &enc_keyblock); if (ret != 0) goto cleanup; /* Derive a usage key from the session key and usage. */ ret = usage_key(enc, hash, keyblock, usage, usage_keyblock); if (ret != 0) goto cleanup; /* Derive the encryption key from the usage key and kd_data. */ ret = enc_key(enc, hash, usage_keyblock, kd_data, enc_keyblock); if (ret != 0) goto cleanup; /* Encrypt or decrypt (encrypt_iov works for both) the input. */ ret = keyblock_crypt(enc, enc_keyblock, 0, data, num_data); cleanup: krb5int_c_free_keyblock(NULL, usage_keyblock); krb5int_c_free_keyblock(NULL, enc_keyblock); return ret; } krb5-1.22.1/src/lib/crypto/krb/checksum_dk_hmac.c0000664000175000017500000000426515051422640021417 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ krb5_error_code krb5int_dk_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output) { const struct krb5_enc_provider *enc = ctp->enc; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data datain; krb5_key kc; /* Derive the key. */ datain = make_data(constantdata, K5CLENGTH); store_32_be(usage, constantdata); constantdata[4] = (char) 0x99; ret = krb5int_derive_key(enc, NULL, key, &kc, &datain, DERIVE_RFC3961); if (ret) return ret; /* Hash the data. */ ret = krb5int_hmac(ctp->hash, kc, data, num_data, output); if (ret) memset(output->data, 0, output->length); krb5_k_free_key(NULL, kc); return ret; } krb5-1.22.1/src/lib/crypto/krb/crypto_int.h0000664000175000017500000007175015051422640020351 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/crypto_int.h - Master libk5crypto internal header */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* This header is the entry point for libk5crypto sources, and also documents * requirements for crypto modules. */ #ifndef CRYPTO_INT_H #define CRYPTO_INT_H #include #if defined(CRYPTO_OPENSSL) #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L /* * OpenSSL 3.0 relegates MD4 and RC4 to the legacy provider, which must be * explicitly loaded into a library context. Performing this loading within a * library carries complications, so use the built-in implementations of these * primitives instead. OpenSSL 3.0 also deprecates DES_set_odd_parity() with * no replacement. * * OpenSSL 3.0 adds KDF implementations matching the ones we use to derive * encryption and authentication keys from protocol keys. It also adds * the EVP_MAC interface which can be used for CMAC. (We could use the CMAC * interface with OpenSSL 1.1 but currently do not.) */ #define K5_BUILTIN_DES_KEY_PARITY #define K5_BUILTIN_MD4 #define K5_BUILTIN_RC4 #define K5_OPENSSL_KDF #define K5_OPENSSL_CMAC #else #define K5_OPENSSL_DES_KEY_PARITY #define K5_OPENSSL_MD4 #define K5_OPENSSL_RC4 #define K5_BUILTIN_KDF #define K5_BUILTIN_CMAC #endif #define K5_OPENSSL_AES #define K5_OPENSSL_CAMELLIA #define K5_OPENSSL_DES #define K5_OPENSSL_HMAC #define K5_OPENSSL_MD5 #define K5_OPENSSL_PBKDF2 #define K5_OPENSSL_SHA1 #define K5_OPENSSL_SHA2 #else #define K5_BUILTIN_AES #define K5_BUILTIN_CAMELLIA #define K5_BUILTIN_CMAC #define K5_BUILTIN_DES #define K5_BUILTIN_DES_KEY_PARITY #define K5_BUILTIN_HMAC #define K5_BUILTIN_KDF #define K5_BUILTIN_MD4 #define K5_BUILTIN_MD5 #define K5_BUILTIN_PBKDF2 #define K5_BUILTIN_RC4 #define K5_BUILTIN_SHA1 #define K5_BUILTIN_SHA2 #endif /* Enc providers and hash providers specify well-known ciphers and hashes to be * implemented by the crypto module. */ struct krb5_enc_provider { /* keybytes is the input size to make_key; keylength is the output size */ size_t block_size, keybytes, keylength; krb5_error_code (*encrypt)(krb5_key key, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data); krb5_error_code (*decrypt)(krb5_key key, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data); /* May be NULL if the cipher is not used for a cbc-mac checksum. */ krb5_error_code (*cbc_mac)(krb5_key key, const krb5_crypto_iov *data, size_t num_data, const krb5_data *ivec, krb5_data *output); krb5_error_code (*init_state)(const krb5_keyblock *key, krb5_keyusage keyusage, krb5_data *out_state); void (*free_state)(krb5_data *state); /* May be NULL if there is no key-derived data cached. */ void (*key_cleanup)(krb5_key key); }; struct krb5_hash_provider { char hash_name[8]; size_t hashsize, blocksize; krb5_error_code (*hash)(const krb5_crypto_iov *data, size_t num_data, krb5_data *output); }; /*** RFC 3961 enctypes table ***/ #define MAX_ETYPE_ALIASES 2 struct krb5_keytypes; typedef unsigned int (*crypto_length_func)(const struct krb5_keytypes *ktp, krb5_cryptotype type); typedef krb5_error_code (*crypt_func)(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); typedef krb5_error_code (*str2key_func)(const struct krb5_keytypes *ktp, const krb5_data *string, const krb5_data *salt, const krb5_data *parm, krb5_keyblock *key); typedef krb5_error_code (*rand2key_func)(const krb5_data *randombits, krb5_keyblock *key); typedef krb5_error_code (*prf_func)(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out); struct krb5_keytypes { krb5_enctype etype; char *name; char *aliases[MAX_ETYPE_ALIASES]; char *out_string; const struct krb5_enc_provider *enc; const struct krb5_hash_provider *hash; size_t prf_length; crypto_length_func crypto_length; crypt_func encrypt; crypt_func decrypt; str2key_func str2key; rand2key_func rand2key; prf_func prf; krb5_cksumtype required_ctype; krb5_flags flags; unsigned int ssf; }; /* * "Weak" means the enctype is believed to be vulnerable to practical attacks, * and will be disabled unless allow_weak_crypto is set to true. "Deprecated" * means the enctype has been deprecated by the IETF, and affects display and * logging. */ #define ETYPE_WEAK (1 << 0) #define ETYPE_DEPRECATED (1 << 1) extern const struct krb5_keytypes krb5int_enctypes_list[]; extern const int krb5int_enctypes_length; /*** RFC 3961 checksum types table ***/ struct krb5_cksumtypes; /* * Compute a checksum over the header, data, padding, and sign-only fields of * the iov array data (of size num_data). The output buffer will already be * allocated with ctp->compute_size bytes available; the handler just needs to * fill in the contents. If ctp->enc is not NULL, the handler can assume that * key is a valid-length key of an enctype which uses that enc provider. */ typedef krb5_error_code (*checksum_func)(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); /* * Verify a checksum over the header, data, padding, and sign-only fields of * the iov array data (of size num_data), and store the boolean result in * *valid. The handler can assume that hash has length ctp->output_size. If * ctp->enc is not NULL, the handler can assume that key a valid-length key of * an enctype which uses that enc provider. */ typedef krb5_error_code (*verify_func)(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, const krb5_data *input, krb5_boolean *valid); struct krb5_cksumtypes { krb5_cksumtype ctype; char *name; char *aliases[2]; char *out_string; const struct krb5_enc_provider *enc; const struct krb5_hash_provider *hash; checksum_func checksum; verify_func verify; /* NULL means recompute checksum and compare */ unsigned int compute_size; /* Allocation size for checksum computation */ unsigned int output_size; /* Possibly truncated output size */ krb5_flags flags; }; #define CKSUM_UNKEYED 0x0001 #define CKSUM_NOT_COLL_PROOF 0x0002 extern const struct krb5_cksumtypes krb5int_cksumtypes_list[]; extern const size_t krb5int_cksumtypes_length; /*** Prototypes for enctype table functions ***/ /* Length */ unsigned int krb5int_raw_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type); unsigned int krb5int_arcfour_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type); unsigned int krb5int_dk_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type); unsigned int krb5int_aes_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type); unsigned int krb5int_camellia_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type); unsigned int krb5int_aes2_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type); /* Encrypt */ krb5_error_code krb5int_raw_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_arcfour_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_dk_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_dk_cmac_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_etm_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); /* Decrypt */ krb5_error_code krb5int_raw_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_arcfour_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_dk_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_dk_cmac_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_etm_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); /* String to key */ krb5_error_code krb5int_des_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key); krb5_error_code krb5int_arcfour_string_to_key(const struct krb5_keytypes *ktp, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key); krb5_error_code krb5int_dk_string_to_key(const struct krb5_keytypes *enc, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key); krb5_error_code krb5int_aes_string_to_key(const struct krb5_keytypes *enc, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key); krb5_error_code krb5int_camellia_string_to_key(const struct krb5_keytypes *enc, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key); krb5_error_code krb5int_aes2_string_to_key(const struct krb5_keytypes *enc, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key); /* Random to key */ krb5_error_code k5_rand2key_direct(const krb5_data *randombits, krb5_keyblock *keyblock); krb5_error_code k5_rand2key_des3(const krb5_data *randombits, krb5_keyblock *keyblock); /* Pseudo-random function */ krb5_error_code krb5int_des_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out); krb5_error_code krb5int_arcfour_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out); krb5_error_code krb5int_dk_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out); krb5_error_code krb5int_dk_cmac_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out); krb5_error_code krb5int_aes2_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out); /*** Prototypes for cksumtype handler functions ***/ krb5_error_code krb5int_unkeyed_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); krb5_error_code krb5int_hmacmd5_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); krb5_error_code krb5int_dk_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); krb5_error_code krb5int_dk_cmac_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); krb5_error_code krb5int_etm_checksum(const struct krb5_cksumtypes *ctp, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); /*** Key derivation functions ***/ enum deriv_alg { DERIVE_RFC3961, /* RFC 3961 section 5.1 */ DERIVE_SP800_108_CMAC, /* NIST SP 800-108 with CMAC as PRF */ DERIVE_SP800_108_HMAC /* NIST SP 800-108 with HMAC as PRF */ }; krb5_error_code krb5int_derive_keyblock(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, krb5_key inkey, krb5_keyblock *outkey, const krb5_data *in_constant, enum deriv_alg alg); krb5_error_code krb5int_derive_key(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, krb5_key inkey, krb5_key *outkey, const krb5_data *in_constant, enum deriv_alg alg); krb5_error_code krb5int_derive_random(const struct krb5_enc_provider *enc, const struct krb5_hash_provider *hash, krb5_key inkey, krb5_data *outrnd, const krb5_data *in_constant, enum deriv_alg alg); /*** Miscellaneous prototypes ***/ /* nfold algorithm from RFC 3961 */ void krb5int_nfold(unsigned int inbits, const unsigned char *in, unsigned int outbits, unsigned char *out); /* Translate an RFC 3961 key usage to a Microsoft RC4 usage. */ krb5_keyusage krb5int_arcfour_translate_usage(krb5_keyusage usage); /* Ensure library initialization has occurred. */ int krb5int_crypto_init(void); /* DES default state initialization handler (used by module enc providers). */ krb5_error_code krb5int_des_init_state(const krb5_keyblock *key, krb5_keyusage keyusage, krb5_data *state_out); /* Default state cleanup handler (used by module enc providers). */ void krb5int_default_free_state(krb5_data *state); /*** Input/output vector processing declarations **/ #define ENCRYPT_CONF_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_HEADER) #define ENCRYPT_DATA_IOV(_iov) ((_iov)->flags == KRB5_CRYPTO_TYPE_DATA || \ (_iov)->flags == KRB5_CRYPTO_TYPE_PADDING) #define ENCRYPT_IOV(_iov) (ENCRYPT_CONF_IOV(_iov) || ENCRYPT_DATA_IOV(_iov)) #define SIGN_IOV(_iov) (ENCRYPT_IOV(_iov) || \ (_iov)->flags == KRB5_CRYPTO_TYPE_SIGN_ONLY ) struct iov_cursor { const krb5_crypto_iov *iov; /* iov array we are iterating over */ size_t iov_count; /* size of iov array */ size_t block_size; /* size of blocks we will be obtaining */ krb5_boolean signing; /* should we process SIGN_ONLY blocks */ size_t in_iov; /* read index into iov array */ size_t in_pos; /* read index into iov contents */ size_t out_iov; /* write index into iov array */ size_t out_pos; /* write index into iov contents */ }; krb5_crypto_iov *krb5int_c_locate_iov(krb5_crypto_iov *data, size_t num_data, krb5_cryptotype type); krb5_error_code krb5int_c_iov_decrypt_stream(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage keyusage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); unsigned int krb5int_c_padding_length(const struct krb5_keytypes *ktp, size_t data_length); void k5_iov_cursor_init(struct iov_cursor *cursor, const krb5_crypto_iov *iov, size_t count, size_t block_size, krb5_boolean signing); krb5_boolean k5_iov_cursor_get(struct iov_cursor *cursor, unsigned char *block); void k5_iov_cursor_put(struct iov_cursor *cursor, unsigned char *block); /*** Crypto module declarations ***/ /* Modules must implement the k5_sha256() function prototyped in k5-int.h. */ /* Modules must implement the following enc_providers and hash_providers: */ extern const struct krb5_enc_provider krb5int_enc_des3; extern const struct krb5_enc_provider krb5int_enc_arcfour; extern const struct krb5_enc_provider krb5int_enc_aes128; extern const struct krb5_enc_provider krb5int_enc_aes256; extern const struct krb5_enc_provider krb5int_enc_aes128_ctr; extern const struct krb5_enc_provider krb5int_enc_aes256_ctr; extern const struct krb5_enc_provider krb5int_enc_camellia128; extern const struct krb5_enc_provider krb5int_enc_camellia256; extern const struct krb5_hash_provider krb5int_hash_md4; extern const struct krb5_hash_provider krb5int_hash_md5; extern const struct krb5_hash_provider krb5int_hash_sha1; extern const struct krb5_hash_provider krb5int_hash_sha256; extern const struct krb5_hash_provider krb5int_hash_sha384; /* Modules must implement the following functions. */ /* Set the parity bits to the correct values in keybits. */ void k5_des_fixup_key_parity(unsigned char *keybits); /* Compute an HMAC using the provided hash function, key, and data, storing the * result into output (caller-allocated). */ krb5_error_code krb5int_hmac(const struct krb5_hash_provider *hash, krb5_key key, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); /* Compute a CMAC checksum over data. */ krb5_error_code krb5int_cmac_checksum(const struct krb5_enc_provider *enc, krb5_key key, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); /* As above, using a keyblock as the key input. */ krb5_error_code krb5int_hmac_keyblock(const struct krb5_hash_provider *hash, const krb5_keyblock *keyblock, const krb5_crypto_iov *data, size_t num_data, krb5_data *output); /* * Compute the PBKDF2 (see RFC 2898) of password and salt, with the specified * count, using HMAC with the specified hash as the pseudo-random function, * storing the result into out (caller-allocated). */ krb5_error_code krb5int_pbkdf2_hmac(const struct krb5_hash_provider *hash, const krb5_data *out, unsigned long count, const krb5_data *password, const krb5_data *salt); /* * Compute the NIST SP800-108 KDF in counter mode (section 5.1) with the * following parameters: * - HMAC (with hash as the hash provider) is the PRF. * - A block counter of four bytes is used. * - Four bytes are used to encode the output length in the PRF input. * * There are no uses requiring more than a single PRF invocation. */ krb5_error_code k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash, krb5_key key, const krb5_data *label, const krb5_data *context, krb5_data *rnd_out); /* * Compute the NIST SP800-108 KDF in feedback mode (section 5.2) with the * following parameters: * - CMAC (with enc as the enc provider) is the PRF. * - A block counter of four bytes is used. * - Label is the key derivation constant. * - Context is empty. * - Four bytes are used to encode the output length in the PRF input. */ krb5_error_code k5_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc, krb5_key key, const krb5_data *label, krb5_data *rnd_out); /* Compute the RFC 3961 section 5.1 KDF (which uses n-fold) with enc as E, * inkey as Key, and in_constant as Constant. */ krb5_error_code k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key key, const krb5_data *constant, krb5_data *rnd_out); /* The following are used by test programs and are just handler functions from * the AES and Camellia enc providers. */ krb5_error_code krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); krb5_error_code krb5int_camellia_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data); /*** Inline helper functions ***/ /* Find an enctype by number in the enctypes table. */ static inline const struct krb5_keytypes * find_enctype(krb5_enctype enctype) { int i; for (i = 0; i < krb5int_enctypes_length; i++) { if (krb5int_enctypes_list[i].etype == enctype) break; } if (i == krb5int_enctypes_length) return NULL; return &krb5int_enctypes_list[i]; } /* Find a checksum type by number in the cksumtypes table. */ static inline const struct krb5_cksumtypes * find_cksumtype(krb5_cksumtype ctype) { size_t i; for (i = 0; i < krb5int_cksumtypes_length; i++) { if (krb5int_cksumtypes_list[i].ctype == ctype) break; } if (i == krb5int_cksumtypes_length) return NULL; return &krb5int_cksumtypes_list[i]; } /* Verify that a key is appropriate for a checksum type. */ static inline krb5_error_code verify_key(const struct krb5_cksumtypes *ctp, krb5_key key) { const struct krb5_keytypes *ktp; ktp = key ? find_enctype(key->keyblock.enctype) : NULL; if (ctp->enc != NULL && (!ktp || ktp->enc != ctp->enc)) return KRB5_BAD_ENCTYPE; if (key && (!ktp || key->keyblock.length != ktp->enc->keylength)) return KRB5_BAD_KEYSIZE; return 0; } /* Encrypt one block of plaintext in place, for block ciphers. */ static inline krb5_error_code encrypt_block(const struct krb5_enc_provider *enc, krb5_key key, krb5_data *block) { krb5_crypto_iov iov; /* Verify that this is a block cipher and block is the right length. */ if (block->length != enc->block_size || enc->block_size == 1) return EINVAL; iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *block; if (enc->cbc_mac != NULL) /* One-block cbc-mac with no ivec. */ return enc->cbc_mac(key, &iov, 1, NULL, block); else /* Assume cbc-mode encrypt. */ return enc->encrypt(key, 0, &iov, 1); } /* Return the total length of the to-be-signed or to-be-encrypted buffers in an * iov chain. */ static inline size_t iov_total_length(const krb5_crypto_iov *data, size_t num_data, krb5_boolean signing) { size_t i, total = 0; for (i = 0; i < num_data; i++) { if (signing ? SIGN_IOV(&data[i]) : ENCRYPT_IOV(&data[i])) total += data[i].data.length; } return total; } /* * Return the number of contiguous blocks available within the current input * IOV of the cursor c, so that the caller can do in-place encryption. * Do not call if c might be exhausted. */ static inline size_t iov_cursor_contig_blocks(struct iov_cursor *c) { return (c->iov[c->in_iov].data.length - c->in_pos) / c->block_size; } /* Return the current input pointer within the cursor c. Do not call if c * might be exhausted. */ static inline unsigned char * iov_cursor_ptr(struct iov_cursor *c) { return (unsigned char *)&c->iov[c->in_iov].data.data[c->in_pos]; } /* * Advance the input and output pointers of c by nblocks blocks. nblocks must * not be greater than the return value of iov_cursor_contig_blocks, and the * input and output positions must be identical. */ static inline void iov_cursor_advance(struct iov_cursor *c, size_t nblocks) { c->in_pos += nblocks * c->block_size; c->out_pos += nblocks * c->block_size; } #endif /* CRYPTO_INT_H */ krb5-1.22.1/src/lib/crypto/krb/enc_raw.c0000664000175000017500000000721415051422640017562 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/enc_raw.c */ /* * Copyright 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" unsigned int krb5int_raw_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type) { switch (type) { case KRB5_CRYPTO_TYPE_PADDING: return ktp->enc->block_size; default: return 0; } } krb5_error_code krb5int_raw_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { krb5_crypto_iov *padding; size_t i; unsigned int blocksize, plainlen = 0, padsize = 0; blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING); for (i = 0; i < num_data; i++) { krb5_crypto_iov *iov = &data[i]; if (iov->flags == KRB5_CRYPTO_TYPE_DATA) plainlen += iov->data.length; } if (blocksize != 0) { /* Check that the input data is correctly padded */ if (plainlen % blocksize) padsize = blocksize - (plainlen % blocksize); } padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING); if (padsize && (padding == NULL || padding->data.length < padsize)) return KRB5_BAD_MSIZE; if (padding != NULL) { memset(padding->data.data, 0, padsize); padding->data.length = padsize; } return ktp->enc->encrypt(key, ivec, data, num_data); } krb5_error_code krb5int_raw_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { size_t i; unsigned int blocksize = 0; /* enc block size, not confounder len */ unsigned int cipherlen = 0; /* E(Confounder | Plaintext | Pad) | Checksum */ blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING); for (i = 0; i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (ENCRYPT_DATA_IOV(iov)) cipherlen += iov->data.length; } if (blocksize == 0) { /* Check for correct input length in CTS mode */ if (ktp->enc->block_size != 0 && cipherlen < ktp->enc->block_size) return KRB5_BAD_MSIZE; } else { /* Check that the input data is correctly padded */ if (cipherlen % blocksize != 0) return KRB5_BAD_MSIZE; } return ktp->enc->decrypt(key, ivec, data, num_data); } krb5-1.22.1/src/lib/crypto/krb/keyed_cksum.c0000664000175000017500000000300215051422640020436 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_boolean KRB5_CALLCONV krb5_c_is_keyed_cksum(krb5_cksumtype ctype) { const struct krb5_cksumtypes *ctp; ctp = find_cksumtype(ctype); if (ctp == NULL) return FALSE; return !(ctp->flags & CKSUM_UNKEYED); } krb5-1.22.1/src/lib/crypto/krb/prf_rc4.c0000664000175000017500000000320215051422640017474 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/prf_rc4.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code krb5int_arcfour_prf(const struct krb5_keytypes *ktp, krb5_key key, const krb5_data *in, krb5_data *out) { krb5_crypto_iov iov; assert(out->length == 20); iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *in; return krb5int_hmac(&krb5int_hash_sha1, key, &iov, 1, out); } krb5-1.22.1/src/lib/crypto/krb/make_checksum.c0000664000175000017500000000647115051422640020747 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" /* A 0 checksum type means use the mandatory checksum. */ krb5_error_code KRB5_CALLCONV krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, const krb5_data *input, krb5_checksum *cksum) { const struct krb5_cksumtypes *ctp; krb5_crypto_iov iov; krb5_data cksum_data; krb5_octet *trunc; krb5_error_code ret; if (cksumtype == 0 && key != NULL) { ret = krb5int_c_mandatory_cksumtype(context, key->keyblock.enctype, &cksumtype); if (ret != 0) return ret; } ctp = find_cksumtype(cksumtype); if (ctp == NULL) return KRB5_BAD_ENCTYPE; ret = verify_key(ctp, key); if (ret != 0) return ret; ret = alloc_data(&cksum_data, ctp->compute_size); if (ret != 0) return ret; iov.flags = KRB5_CRYPTO_TYPE_DATA; iov.data = *input; ret = ctp->checksum(ctp, key, usage, &iov, 1, &cksum_data); if (ret != 0) goto cleanup; cksum->magic = KV5M_CHECKSUM; cksum->checksum_type = cksumtype; cksum->length = ctp->output_size; cksum->contents = (krb5_octet *) cksum_data.data; cksum_data.data = NULL; if (ctp->output_size < ctp->compute_size) { trunc = realloc(cksum->contents, ctp->output_size); if (trunc != NULL) cksum->contents = trunc; } cleanup: zapfree(cksum_data.data, ctp->compute_size); return ret; } krb5_error_code KRB5_CALLCONV krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *input, krb5_checksum *cksum) { krb5_key key = NULL; krb5_error_code ret; if (keyblock != NULL) { ret = krb5_k_create_key(context, keyblock, &key); if (ret != 0) return ret; } ret = krb5_k_make_checksum(context, cksumtype, key, usage, input, cksum); krb5_k_free_key(context, key); return ret; } krb5-1.22.1/src/lib/crypto/krb/enc_dk_hmac.c0000664000175000017500000002000615051422640020351 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/enc_dk_hmac.c */ /* * Copyright 2008, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" #define K5CLENGTH 5 /* 32 bit net byte order integer + one byte seed */ /* AEAD */ unsigned int krb5int_dk_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type) { switch (type) { case KRB5_CRYPTO_TYPE_HEADER: case KRB5_CRYPTO_TYPE_PADDING: return ktp->enc->block_size; case KRB5_CRYPTO_TYPE_TRAILER: case KRB5_CRYPTO_TYPE_CHECKSUM: return ktp->hash->hashsize; default: assert(0 && "invalid cryptotype passed to krb5int_dk_crypto_length"); return 0; } } unsigned int krb5int_aes_crypto_length(const struct krb5_keytypes *ktp, krb5_cryptotype type) { switch (type) { case KRB5_CRYPTO_TYPE_HEADER: return ktp->enc->block_size; case KRB5_CRYPTO_TYPE_PADDING: return 0; case KRB5_CRYPTO_TYPE_TRAILER: case KRB5_CRYPTO_TYPE_CHECKSUM: return 96 / 8; default: assert(0 && "invalid cryptotype passed to krb5int_aes_crypto_length"); return 0; } } krb5_error_code krb5int_dk_encrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { const struct krb5_enc_provider *enc = ktp->enc; const struct krb5_hash_provider *hash = ktp->hash; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data d1, d2; krb5_crypto_iov *header, *trailer, *padding; krb5_key ke = NULL, ki = NULL; size_t i; unsigned int blocksize, hmacsize, plainlen = 0, padsize = 0; unsigned char *cksum = NULL; /* E(Confounder | Plaintext | Pad) | Checksum */ blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING); hmacsize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER); for (i = 0; i < num_data; i++) { krb5_crypto_iov *iov = &data[i]; if (iov->flags == KRB5_CRYPTO_TYPE_DATA) plainlen += iov->data.length; } /* Validate header and trailer lengths. */ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); if (header == NULL || header->data.length < enc->block_size) return KRB5_BAD_MSIZE; trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); if (trailer == NULL || trailer->data.length < hmacsize) return KRB5_BAD_MSIZE; if (blocksize != 0) { /* Check that the input data is correctly padded. */ if (plainlen % blocksize) padsize = blocksize - (plainlen % blocksize); } padding = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_PADDING); if (padsize && (padding == NULL || padding->data.length < padsize)) return KRB5_BAD_MSIZE; if (padding != NULL) { memset(padding->data.data, 0, padsize); padding->data.length = padsize; } cksum = k5alloc(hash->hashsize, &ret); if (ret != 0) goto cleanup; /* Derive the keys. */ d1.data = (char *)constantdata; d1.length = K5CLENGTH; store_32_be(usage, constantdata); d1.data[4] = 0xAA; ret = krb5int_derive_key(enc, NULL, key, &ke, &d1, DERIVE_RFC3961); if (ret != 0) goto cleanup; d1.data[4] = 0x55; ret = krb5int_derive_key(enc, NULL, key, &ki, &d1, DERIVE_RFC3961); if (ret != 0) goto cleanup; /* Generate confounder. */ header->data.length = enc->block_size; ret = krb5_c_random_make_octets(/* XXX */ NULL, &header->data); if (ret != 0) goto cleanup; /* Hash the plaintext. */ d2.length = hash->hashsize; d2.data = (char *)cksum; ret = krb5int_hmac(hash, ki, data, num_data, &d2); if (ret != 0) goto cleanup; /* Encrypt the plaintext (header | data | padding) */ ret = enc->encrypt(ke, ivec, data, num_data); if (ret != 0) goto cleanup; /* Possibly truncate the hash */ assert(hmacsize <= d2.length); memcpy(trailer->data.data, cksum, hmacsize); trailer->data.length = hmacsize; cleanup: krb5_k_free_key(NULL, ke); krb5_k_free_key(NULL, ki); free(cksum); return ret; } krb5_error_code krb5int_dk_decrypt(const struct krb5_keytypes *ktp, krb5_key key, krb5_keyusage usage, const krb5_data *ivec, krb5_crypto_iov *data, size_t num_data) { const struct krb5_enc_provider *enc = ktp->enc; const struct krb5_hash_provider *hash = ktp->hash; krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data d1; krb5_crypto_iov *header, *trailer; krb5_key ke = NULL, ki = NULL; size_t i; unsigned int blocksize; /* enc block size, not confounder len */ unsigned int hmacsize, cipherlen = 0; unsigned char *cksum = NULL; /* E(Confounder | Plaintext | Pad) | Checksum */ blocksize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_PADDING); hmacsize = ktp->crypto_length(ktp, KRB5_CRYPTO_TYPE_TRAILER); if (blocksize != 0) { /* Check that the input data is correctly padded. */ for (i = 0; i < num_data; i++) { const krb5_crypto_iov *iov = &data[i]; if (ENCRYPT_DATA_IOV(iov)) cipherlen += iov->data.length; } if (cipherlen % blocksize != 0) return KRB5_BAD_MSIZE; } /* Validate header and trailer lengths */ header = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_HEADER); if (header == NULL || header->data.length != enc->block_size) return KRB5_BAD_MSIZE; trailer = krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_TRAILER); if (trailer == NULL || trailer->data.length != hmacsize) return KRB5_BAD_MSIZE; cksum = k5alloc(hash->hashsize, &ret); if (ret != 0) goto cleanup; /* Derive the keys. */ d1.data = (char *)constantdata; d1.length = K5CLENGTH; store_32_be(usage, constantdata); d1.data[4] = 0xAA; ret = krb5int_derive_key(enc, NULL, key, &ke, &d1, DERIVE_RFC3961); if (ret != 0) goto cleanup; d1.data[4] = 0x55; ret = krb5int_derive_key(enc, NULL, key, &ki, &d1, DERIVE_RFC3961); if (ret != 0) goto cleanup; /* Decrypt the plaintext (header | data | padding). */ ret = enc->decrypt(ke, ivec, data, num_data); if (ret != 0) goto cleanup; /* Verify the hash. */ d1.length = hash->hashsize; /* non-truncated length */ d1.data = (char *)cksum; ret = krb5int_hmac(hash, ki, data, num_data, &d1); if (ret != 0) goto cleanup; /* Compare only the possibly truncated length. */ if (k5_bcmp(cksum, trailer->data.data, hmacsize) != 0) { ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; goto cleanup; } cleanup: krb5_k_free_key(NULL, ke); krb5_k_free_key(NULL, ki); free(cksum); return ret; } krb5-1.22.1/src/lib/crypto/krb/string_to_key.c0000664000175000017500000000543515051422640021027 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_c_string_to_key(krb5_context context, krb5_enctype enctype, const krb5_data *string, const krb5_data *salt, krb5_keyblock *key) { return krb5_c_string_to_key_with_params(context, enctype, string, salt, NULL, key); } krb5_error_code KRB5_CALLCONV krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key) { krb5_error_code ret; krb5_data empty = empty_data(); const struct krb5_keytypes *ktp; size_t keylength; ktp = find_enctype(enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; keylength = ktp->enc->keylength; /* For compatibility with past behavior, treat a null salt as empty. */ if (salt == NULL) salt = ∅ /* Fail gracefully if someone is using the old AFS string-to-key hack. */ if (salt->length == SALT_TYPE_AFS_LENGTH) return EINVAL; key->contents = malloc(keylength); if (key->contents == NULL) return ENOMEM; key->magic = KV5M_KEYBLOCK; key->enctype = enctype; key->length = keylength; ret = (*ktp->str2key)(ktp, string, salt, params, key); if (ret) { zapfree(key->contents, keylength); key->length = 0; key->contents = NULL; } return ret; } krb5-1.22.1/src/lib/crypto/krb/decrypt_iov.c0000664000175000017500000000500015051422640020462 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/crypto/krb/decrypt_iov.c */ /* * Copyright 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "crypto_int.h" krb5_error_code KRB5_CALLCONV krb5_k_decrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data) { const struct krb5_keytypes *ktp; ktp = find_enctype(key->keyblock.enctype); if (ktp == NULL) return KRB5_BAD_ENCTYPE; if (krb5int_c_locate_iov(data, num_data, KRB5_CRYPTO_TYPE_STREAM) != NULL) { return krb5int_c_iov_decrypt_stream(ktp, key, usage, cipher_state, data, num_data); } return ktp->decrypt(ktp, key, usage, cipher_state, data, num_data); } krb5_error_code KRB5_CALLCONV krb5_c_decrypt_iov(krb5_context context, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data) { krb5_key key; krb5_error_code ret; ret = krb5_k_create_key(context, keyblock, &key); if (ret != 0) return ret; ret = krb5_k_decrypt_iov(context, key, usage, cipher_state, data, num_data); krb5_k_free_key(context, key); return ret; } krb5-1.22.1/src/lib/deps0000664000175000017500000000003015051422640014545 0ustar ghudsonghudson# No dependencies here. krb5-1.22.1/src/lib/krb5/0000775000175000017500000000000015051422640014541 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/error_tables/0000775000175000017500000000000015051422640017224 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/error_tables/Makefile.in0000664000175000017500000000431615051422640021275 0ustar ghudsonghudsonmydir=lib$(S)krb5$(S)error_tables BUILDTOP=$(REL)..$(S)..$(S).. ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=error_tables ##DOS##OBJFILE=..\$(OUTPRE)err_tbls.lst THDRDIR=$(BUILDTOP)$(S)include EHDRDIR=$(BUILDTOP)$(S)include ETDIR=$(top_srcdir)$(S)util$(S)et STLIBOBJS= asn1_err.o kdb5_err.o krb5_err.o k5e1_err.o \ kv5m_err.o krb524_err.o HDRS= asn1_err.h kdb5_err.h krb5_err.h k5e1_err.h kv5m_err.h krb524_err.h OBJS= $(OUTPRE)asn1_err.$(OBJEXT) $(OUTPRE)kdb5_err.$(OBJEXT) \ $(OUTPRE)krb5_err.$(OBJEXT) $(OUTPRE)k5e1_err.$(OBJEXT) \ $(OUTPRE)kv5m_err.$(OBJEXT) $(OUTPRE)krb524_err.$(OBJEXT) ETSRCS= asn1_err.c kdb5_err.c krb5_err.c k5e1_err.c kv5m_err.c krb524_err.c SRCS= asn1_err.c kdb5_err.c krb5_err.c k5e1_err.c kv5m_err.c krb524_err.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs all-libobjs: $(HDRS) includes: $(HDRS) awk-windows: $(AWK) -f $(ETDIR)/et_h.awk outfile=asn1_err.h asn1_err.et $(AWK) -f $(ETDIR)/et_h.awk outfile=kdb5_err.h kdb5_err.et $(AWK) -f $(ETDIR)/et_h.awk outfile=krb5_err.h krb5_err.et $(AWK) -f $(ETDIR)/et_h.awk outfile=k5e1_err.h k5e1_err.et $(AWK) -f $(ETDIR)/et_h.awk outfile=kv5m_err.h kv5m_err.et $(AWK) -f $(ETDIR)/et_h.awk outfile=krb524_err.h krb524_err.et $(AWK) -f $(ETDIR)/et_c.awk outfile=asn1_err.c asn1_err.et $(AWK) -f $(ETDIR)/et_c.awk outfile=kdb5_err.c kdb5_err.et $(AWK) -f $(ETDIR)/et_c.awk outfile=krb5_err.c krb5_err.et $(AWK) -f $(ETDIR)/et_c.awk outfile=k5e1_err.c k5e1_err.et $(AWK) -f $(ETDIR)/et_c.awk outfile=kv5m_err.c kv5m_err.et $(AWK) -f $(ETDIR)/et_c.awk outfile=krb524_err.c krb524_err.et if exist asn1_err.h copy asn1_err.h "$(EHDRDIR)" if exist kdb5_err.h copy kdb5_err.h "$(EHDRDIR)" if exist krb5_err.h copy krb5_err.h "$(EHDRDIR)" if exist k5e1_err.h copy k5e1_err.h "$(EHDRDIR)" if exist kv5m_err.h copy kv5m_err.h "$(EHDRDIR)" if exist krb524_err.h copy krb524_err.h "$(EHDRDIR)" # # dependencies for traditional makes # $(OUTPRE)asn1_err.$(OBJEXT): asn1_err.c $(OUTPRE)kdb5_err.$(OBJEXT): kdb5_err.c $(OUTPRE)krb5_err.$(OBJEXT): krb5_err.c $(OUTPRE)k5e1_err.$(OBJEXT): k5e1_err.c $(OUTPRE)kv5m_err.$(OBJEXT): kv5m_err.c $(OUTPRE)krb524_err.$(OBJEXT): krb524_err.c clean-unix:: clean-libobjs $(RM) $(HDRS) $(ETSRCS) @libobj_frag@ krb5-1.22.1/src/lib/krb5/error_tables/krb524_err.et0000664000175000017500000000322415051422640021440 0ustar ghudsonghudson# Copyright 1994 by OpenVision Technologies, Inc. # # Permission to use, copy, modify, distribute, and sell this software # and its documentation for any purpose is hereby granted without fee, # provided that the above copyright notice appears in all copies and # that both that copyright notice and this permission notice appear in # supporting documentation, and that the name of OpenVision not be used # in advertising or publicity pertaining to distribution of the software # without specific, written prior permission. OpenVision makes no # representations about the suitability of this software for any # purpose. It is provided "as is" without express or implied warranty. # # OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO # EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF # USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # error_table k524 error_code KRB524_BADKEY, "Cannot convert V5 keyblock" error_code KRB524_BADADDR, "Cannot convert V5 address information" error_code KRB524_BADPRINC, "Cannot convert V5 principal" error_code KRB524_BADREALM, "V5 realm name longer than V4 maximum" error_code KRB524_V4ERR, "Kerberos V4 error" error_code KRB524_ENCFULL, "Encoding too large" error_code KRB524_DECEMPTY, "Decoding out of data" error_code KRB524_NOTRESP, "Service not responding" error_code KRB524_KRB4_DISABLED, "Kerberos version 4 support is disabled" end krb5-1.22.1/src/lib/krb5/error_tables/k5e1_err.et0000664000175000017500000000456015051422640021200 0ustar ghudsonghudson# # lib/krb5/error_tables/k5e1_err.et # # Copyright 2010 by the Massachusetts Institute of Technology. # All Rights Reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. # # # The Kerberos v5 library error code expansion table (#1). # This table exists to hold new libkrb5 error codes since the # original krb5 error table is full. # error_table k5e1 error_code KRB5_PLUGIN_VER_NOTSUPP, "Plugin does not support interface version" error_code KRB5_PLUGIN_BAD_MODULE_SPEC, "Invalid module specifier" error_code KRB5_PLUGIN_NAME_NOTFOUND, "Plugin module name not found" error_code KRB5KDC_ERR_DISCARD, "The KDC should discard this request" error_code KRB5_DCC_CANNOT_CREATE, "Can't create new subsidiary cache" error_code KRB5_KCC_INVALID_ANCHOR, "Invalid keyring anchor name" error_code KRB5_KCC_UNKNOWN_VERSION, "Unknown keyring collection version" error_code KRB5_KCC_INVALID_UID, "Invalid UID in persistent keyring name" error_code KRB5_KCM_MALFORMED_REPLY, "Malformed reply from KCM daemon" error_code KRB5_KCM_RPC_ERROR, "Mach RPC error communicating with KCM daemon" error_code KRB5_KCM_REPLY_TOO_BIG, "KCM daemon reply too big" error_code KRB5_KCM_NO_SERVER, "No KCM server found" error_code KRB5_CERTAUTH_HWAUTH, "Authorize and set hw-authent ticket flag" error_code KRB5_CERTAUTH_HWAUTH_PASS, "Set hw-authent ticket flag but do not authorize" end krb5-1.22.1/src/lib/krb5/error_tables/init_ets.c0000664000175000017500000000336715051422640021217 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/error_tables/init_ets.c - Initialize krb5 library error tables */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" void krb5_init_ets (krb5_context context) { static int inited = 0; if (inited == 0) { initialize_krb5_error_table(); initialize_k5e1_error_table(); initialize_kv5m_error_table(); initialize_kdb5_error_table(); initialize_asn1_error_table(); initialize_k524_error_table(); inited++; } } void krb5_free_ets (krb5_context context) { } krb5-1.22.1/src/lib/krb5/error_tables/kv5m_err.et0000664000175000017500000001337015051422640021314 0ustar ghudsonghudson# # src/lib/krb5/kv5m_err.et # # Copyright 1994 by the Massachusetts Institute of Technology. # All Rights Reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. # # # The Kerberos v5 magic numbers errorcode table error_table kv5m error_code KV5M_NONE, "Kerberos V5 magic number table" error_code KV5M_PRINCIPAL, "Bad magic number for krb5_principal structure" error_code KV5M_DATA, "Bad magic number for krb5_data structure" error_code KV5M_KEYBLOCK, "Bad magic number for krb5_keyblock structure" error_code KV5M_CHECKSUM, "Bad magic number for krb5_checksum structure" error_code KV5M_ENCRYPT_BLOCK, "Bad magic number for krb5_encrypt_block structure" error_code KV5M_ENC_DATA, "Bad magic number for krb5_enc_data structure" error_code KV5M_CRYPTOSYSTEM_ENTRY, "Bad magic number for krb5_cryptosystem_entry structure" error_code KV5M_CS_TABLE_ENTRY, "Bad magic number for krb5_cs_table_entry structure" error_code KV5M_CHECKSUM_ENTRY, "Bad magic number for krb5_checksum_entry structure" error_code KV5M_AUTHDATA, "Bad magic number for krb5_authdata structure" error_code KV5M_TRANSITED, "Bad magic number for krb5_transited structure" error_code KV5M_ENC_TKT_PART, "Bad magic number for krb5_enc_tkt_part structure" error_code KV5M_TICKET, "Bad magic number for krb5_ticket structure" error_code KV5M_AUTHENTICATOR, "Bad magic number for krb5_authenticator structure" error_code KV5M_TKT_AUTHENT, "Bad magic number for krb5_tkt_authent structure" error_code KV5M_CREDS, "Bad magic number for krb5_creds structure" error_code KV5M_LAST_REQ_ENTRY, "Bad magic number for krb5_last_req_entry structure" error_code KV5M_PA_DATA, "Bad magic number for krb5_pa_data structure" error_code KV5M_KDC_REQ, "Bad magic number for krb5_kdc_req structure" error_code KV5M_ENC_KDC_REP_PART, "Bad magic number for krb5_enc_kdc_rep_part structure" error_code KV5M_KDC_REP, "Bad magic number for krb5_kdc_rep structure" error_code KV5M_ERROR, "Bad magic number for krb5_error structure" error_code KV5M_AP_REQ, "Bad magic number for krb5_ap_req structure" error_code KV5M_AP_REP, "Bad magic number for krb5_ap_rep structure" error_code KV5M_AP_REP_ENC_PART, "Bad magic number for krb5_ap_rep_enc_part structure" error_code KV5M_RESPONSE, "Bad magic number for krb5_response structure" error_code KV5M_SAFE, "Bad magic number for krb5_safe structure" error_code KV5M_PRIV, "Bad magic number for krb5_priv structure" error_code KV5M_PRIV_ENC_PART, "Bad magic number for krb5_priv_enc_part structure" error_code KV5M_CRED, "Bad magic number for krb5_cred structure" error_code KV5M_CRED_INFO, "Bad magic number for krb5_cred_info structure" error_code KV5M_CRED_ENC_PART, "Bad magic number for krb5_cred_enc_part structure" error_code KV5M_PWD_DATA, "Bad magic number for krb5_pwd_data structure" error_code KV5M_ADDRESS, "Bad magic number for krb5_address structure" error_code KV5M_KEYTAB_ENTRY, "Bad magic number for krb5_keytab_entry structure" error_code KV5M_CONTEXT, "Bad magic number for krb5_context structure" error_code KV5M_OS_CONTEXT, "Bad magic number for krb5_os_context structure" error_code KV5M_ALT_METHOD, "Bad magic number for krb5_alt_method structure" error_code KV5M_ETYPE_INFO_ENTRY, "Bad magic number for krb5_etype_info_entry structure" error_code KV5M_DB_CONTEXT, "Bad magic number for krb5_db_context structure" error_code KV5M_AUTH_CONTEXT, "Bad magic number for krb5_auth_context structure" error_code KV5M_KEYTAB, "Bad magic number for krb5_keytab structure" error_code KV5M_RCACHE, "Bad magic number for krb5_rcache structure" error_code KV5M_CCACHE, "Bad magic number for krb5_ccache structure" error_code KV5M_PREAUTH_OPS, "Bad magic number for krb5_preauth_ops" error_code KV5M_SAM_CHALLENGE, "Bad magic number for krb5_sam_challenge" error_code KV5M_SAM_CHALLENGE_2, "Bad magic number for krb5_sam_challenge_2" error_code KV5M_SAM_KEY, "Bad magic number for krb5_sam_key" error_code KV5M_ENC_SAM_RESPONSE_ENC, "Bad magic number for krb5_enc_sam_response_enc" error_code KV5M_ENC_SAM_RESPONSE_ENC_2, "Bad magic number for krb5_enc_sam_response_enc" error_code KV5M_SAM_RESPONSE, "Bad magic number for krb5_sam_response" error_code KV5M_SAM_RESPONSE_2, "Bad magic number for krb5_sam_response 2" error_code KV5M_PREDICTED_SAM_RESPONSE, "Bad magic number for krb5_predicted_sam_response" error_code KV5M_PASSWD_PHRASE_ELEMENT, "Bad magic number for passwd_phrase_element" error_code KV5M_GSS_OID, "Bad magic number for GSSAPI OID" error_code KV5M_GSS_QUEUE, "Bad magic number for GSSAPI QUEUE" error_code KV5M_FAST_ARMORED_REQ, "Bad magic number for fast armored request" error_code KV5M_FAST_REQ, "Bad magic number for FAST request" error_code KV5M_FAST_RESPONSE, "Bad magic number for FAST response" error_code KV5M_AUTHDATA_CONTEXT, "Bad magic number for krb5_authdata_context" end krb5-1.22.1/src/lib/krb5/error_tables/deps0000664000175000017500000000105615051422640020104 0ustar ghudsonghudson# # Generated makefile dependencies follow. # asn1_err.so asn1_err.po $(OUTPRE)asn1_err.$(OBJEXT): \ $(COM_ERR_DEPS) asn1_err.c kdb5_err.so kdb5_err.po $(OUTPRE)kdb5_err.$(OBJEXT): \ $(COM_ERR_DEPS) kdb5_err.c krb5_err.so krb5_err.po $(OUTPRE)krb5_err.$(OBJEXT): \ $(COM_ERR_DEPS) krb5_err.c k5e1_err.so k5e1_err.po $(OUTPRE)k5e1_err.$(OBJEXT): \ $(COM_ERR_DEPS) k5e1_err.c kv5m_err.so kv5m_err.po $(OUTPRE)kv5m_err.$(OBJEXT): \ $(COM_ERR_DEPS) kv5m_err.c krb524_err.so krb524_err.po $(OUTPRE)krb524_err.$(OBJEXT): \ $(COM_ERR_DEPS) krb524_err.c krb5-1.22.1/src/lib/krb5/error_tables/kdb5_err.et0000664000175000017500000001024215051422640021252 0ustar ghudsonghudson# # lib/krb5/error_tables/kdb5_err.et # # Copyright 1990, 2008 by the Massachusetts Institute of Technology. # All Rights Reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. # # # The Kerberos v5 database library error code table. # error_table kdb5 ec KRB5_KDB_RCSID, "$Id$" # /* From the server side routines */ ec KRB5_KDB_INUSE, "Entry already exists in database" ec KRB5_KDB_UK_SERROR, "Database store error" ec KRB5_KDB_UK_RERROR, "Database read error" ec KRB5_KDB_UNAUTH, "Insufficient access to perform requested operation" # KRB5_KDB_DATA isn't really an error, but... ec KRB5_KDB_NOENTRY, "No such entry in the database" ec KRB5_KDB_ILL_WILDCARD, "Illegal use of wildcard" ec KRB5_KDB_DB_INUSE, "Database is locked or in use--try again later" ec KRB5_KDB_DB_CHANGED, "Database was modified during read" ec KRB5_KDB_TRUNCATED_RECORD, "Database record is incomplete or corrupted" ec KRB5_KDB_RECURSIVELOCK, "Attempt to lock database twice" ec KRB5_KDB_NOTLOCKED, "Attempt to unlock database when not locked" ec KRB5_KDB_BADLOCKMODE, "Invalid kdb lock mode" ec KRB5_KDB_DBNOTINITED, "Database has not been initialized" ec KRB5_KDB_DBINITED, "Database has already been initialized" ec KRB5_KDB_ILLDIRECTION, "Bad direction for converting keys" ec KRB5_KDB_NOMASTERKEY, "Cannot find master key record in database" ec KRB5_KDB_BADMASTERKEY, "Master key does not match database" ec KRB5_KDB_INVALIDKEYSIZE, "Key size in database is invalid" ec KRB5_KDB_CANTREAD_STORED, "Cannot find/read stored master key" ec KRB5_KDB_BADSTORED_MKEY, "Stored master key is corrupted" ec KRB5_KDB_NOACTMASTERKEY, "Cannot find active master key" ec KRB5_KDB_KVNONOMATCH, "KVNO of new master key does not match expected value" ec KRB5_KDB_STORED_MKEY_NOTCURRENT, "Stored master key is not current" ec KRB5_KDB_CANTLOCK_DB, "Insufficient access to lock database" ec KRB5_KDB_DB_CORRUPT, "Database format error" ec KRB5_KDB_BAD_VERSION, "Unsupported version in database entry" ec KRB5_KDB_BAD_SALTTYPE, "Unsupported salt type" ec KRB5_KDB_BAD_ENCTYPE, "Unsupported encryption type" ec KRB5_KDB_BAD_CREATEFLAGS, "Bad database creation flags" ec KRB5_KDB_NO_PERMITTED_KEY, "No matching key in entry having a permitted enctype" ec KRB5_KDB_NO_MATCHING_KEY, "No matching key in entry" ec KRB5_KDB_DBTYPE_NOTFOUND, "Unable to find requested database type" ec KRB5_KDB_DBTYPE_NOSUP, "Database type not supported" ec KRB5_KDB_DBTYPE_INIT, "Database library failed to initialize" ec KRB5_KDB_SERVER_INTERNAL_ERR, "Server error" ec KRB5_KDB_ACCESS_ERROR, "Unable to access Kerberos database" ec KRB5_KDB_INTERNAL_ERROR, "Kerberos database internal error" ec KRB5_KDB_CONSTRAINT_VIOLATION, "Kerberos database constraints violated" ec KRB5_LOG_CONV, "Update log conversion error" ec KRB5_LOG_UNSTABLE, "Update log is unstable" ec KRB5_LOG_CORRUPT, "Update log is corrupt" ec KRB5_LOG_ERROR, "Generic update log error" ec KRB5_KDB_DBTYPE_MISMATCH, "Database module does not match KDC version" ec KRB5_KDB_POLICY_REF, "Policy is in use" ec KRB5_KDB_STRINGS_TOOLONG, "Too much string mapping data" ec KRB5_KDB_ALIAS_UNSUPPORTED, "Operation unsupported on alias principal name" end krb5-1.22.1/src/lib/krb5/error_tables/asn1_err.et0000664000175000017500000000160415051422640021271 0ustar ghudsonghudsonerror_table asn1 error_code ASN1_BAD_TIMEFORMAT, "ASN.1 failed call to system time library" error_code ASN1_MISSING_FIELD, "ASN.1 structure is missing a required field" error_code ASN1_MISPLACED_FIELD, "ASN.1 unexpected field number" error_code ASN1_TYPE_MISMATCH, "ASN.1 type numbers are inconsistent" error_code ASN1_OVERFLOW, "ASN.1 value too large" error_code ASN1_OVERRUN, "ASN.1 encoding ended unexpectedly" error_code ASN1_BAD_ID, "ASN.1 identifier doesn't match expected value" error_code ASN1_BAD_LENGTH, "ASN.1 length doesn't match expected value" error_code ASN1_BAD_FORMAT, "ASN.1 badly-formatted encoding" error_code ASN1_PARSE_ERROR, "ASN.1 parse error" error_code ASN1_BAD_GMTIME, "ASN.1 bad return from gmtime" error_code ASN1_INDEF, "ASN.1 indefinite encoding" error_code ASN1_MISSING_EOC, "ASN.1 missing expected EOC" error_code ASN1_OMITTED, "ASN.1 object omitted in sequence" end krb5-1.22.1/src/lib/krb5/error_tables/krb5_err.et0000664000175000017500000004612715051422640021303 0ustar ghudsonghudson# # lib/krb5/error_tables/krb5_err.et # # Copyright 1989,1990,1991,2007 by the Massachusetts Institute of Technology. # All Rights Reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. # # # The Kerberos v5 library error code table. # Protocol error codes are ERROR_TABLE_BASE_krb5 + the protocol error # code number; other error codes start at ERROR_TABLE_BASE_krb5 + 128. # error_table krb5 # # Note: the first 128 error codes are hard-coded and must match the error # numbers defined in the Kerberos protocol specification, RFC-1510 or # its successors. # # vv 0 error_code KRB5KDC_ERR_NONE, "No error" error_code KRB5KDC_ERR_NAME_EXP, "Client's entry in database has expired" error_code KRB5KDC_ERR_SERVICE_EXP, "Server's entry in database has expired" error_code KRB5KDC_ERR_BAD_PVNO, "Requested protocol version not supported" error_code KRB5KDC_ERR_C_OLD_MAST_KVNO, "Client's key is encrypted in an old master key" error_code KRB5KDC_ERR_S_OLD_MAST_KVNO, "Server's key is encrypted in an old master key" error_code KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "Client not found in Kerberos database" error_code KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "Server not found in Kerberos database" error_code KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "Principal has multiple entries in Kerberos database" error_code KRB5KDC_ERR_NULL_KEY, "Client or server has a null key" error_code KRB5KDC_ERR_CANNOT_POSTDATE, "Ticket is ineligible for postdating" error_code KRB5KDC_ERR_NEVER_VALID, "Requested effective lifetime is negative or too short" error_code KRB5KDC_ERR_POLICY, "KDC policy rejects request" error_code KRB5KDC_ERR_BADOPTION, "KDC can't fulfill requested option" error_code KRB5KDC_ERR_ETYPE_NOSUPP, "KDC has no support for encryption type" error_code KRB5KDC_ERR_SUMTYPE_NOSUPP, "KDC has no support for checksum type" error_code KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KDC has no support for padata type" error_code KRB5KDC_ERR_TRTYPE_NOSUPP, "KDC has no support for transited type" error_code KRB5KDC_ERR_CLIENT_REVOKED, "Client's credentials have been revoked" error_code KRB5KDC_ERR_SERVICE_REVOKED, "Credentials for server have been revoked" error_code KRB5KDC_ERR_TGT_REVOKED, "TGT has been revoked" error_code KRB5KDC_ERR_CLIENT_NOTYET, "Client not yet valid - try again later" error_code KRB5KDC_ERR_SERVICE_NOTYET, "Server not yet valid - try again later" error_code KRB5KDC_ERR_KEY_EXP, "Password has expired" error_code KRB5KDC_ERR_PREAUTH_FAILED, "Preauthentication failed" # ^^ 24 error_code KRB5KDC_ERR_PREAUTH_REQUIRED, "Additional pre-authentication required" error_code KRB5KDC_ERR_SERVER_NOMATCH, "Requested server and ticket don't match" error_code KRB5KDC_ERR_MUST_USE_USER2USER, "Server principal valid for user2user only" error_code KRB5KDC_ERR_PATH_NOT_ACCEPTED, "KDC policy rejects transited path" error_code KRB5KDC_ERR_SVC_UNAVAILABLE, "A service is not available that is required to process the request" error_code KRB5PLACEHOLD_30, "KRB5 error code 30" # vv 31 error_code KRB5KRB_AP_ERR_BAD_INTEGRITY, "Decrypt integrity check failed" error_code KRB5KRB_AP_ERR_TKT_EXPIRED, "Ticket expired" error_code KRB5KRB_AP_ERR_TKT_NYV, "Ticket not yet valid" error_code KRB5KRB_AP_ERR_REPEAT, "Request is a replay" error_code KRB5KRB_AP_ERR_NOT_US, "The ticket isn't for us" error_code KRB5KRB_AP_ERR_BADMATCH, "Ticket/authenticator don't match" error_code KRB5KRB_AP_ERR_SKEW, "Clock skew too great" error_code KRB5KRB_AP_ERR_BADADDR, "Incorrect net address" error_code KRB5KRB_AP_ERR_BADVERSION, "Protocol version mismatch" error_code KRB5KRB_AP_ERR_MSG_TYPE, "Invalid message type" error_code KRB5KRB_AP_ERR_MODIFIED, "Message stream modified" error_code KRB5KRB_AP_ERR_BADORDER, "Message out of order" error_code KRB5KRB_AP_ERR_ILL_CR_TKT, "Illegal cross-realm ticket" error_code KRB5KRB_AP_ERR_BADKEYVER, "Key version is not available" error_code KRB5KRB_AP_ERR_NOKEY, "Service key not available" error_code KRB5KRB_AP_ERR_MUT_FAIL, "Mutual authentication failed" error_code KRB5KRB_AP_ERR_BADDIRECTION, "Incorrect message direction" error_code KRB5KRB_AP_ERR_METHOD, "Alternative authentication method required" error_code KRB5KRB_AP_ERR_BADSEQ, "Incorrect sequence number in message" error_code KRB5KRB_AP_ERR_INAPP_CKSUM, "Inappropriate type of checksum in message" #^^ 50 error_code KRB5KRB_AP_PATH_NOT_ACCEPTED, "Policy rejects transited path" error_code KRB5KRB_ERR_RESPONSE_TOO_BIG, "Response too big for UDP, retry with TCP" error_code KRB5PLACEHOLD_53, "KRB5 error code 53" error_code KRB5PLACEHOLD_54, "KRB5 error code 54" error_code KRB5PLACEHOLD_55, "KRB5 error code 55" error_code KRB5PLACEHOLD_56, "KRB5 error code 56" error_code KRB5PLACEHOLD_57, "KRB5 error code 57" error_code KRB5PLACEHOLD_58, "KRB5 error code 58" error_code KRB5PLACEHOLD_59, "KRB5 error code 59" error_code KRB5KRB_ERR_GENERIC, "Generic error (see e-text)" error_code KRB5KRB_ERR_FIELD_TOOLONG, "Field is too long for this implementation" error_code KRB5KDC_ERR_CLIENT_NOT_TRUSTED, "Client not trusted" error_code KRB5KDC_ERR_KDC_NOT_TRUSTED, "KDC not trusted" error_code KRB5KDC_ERR_INVALID_SIG, "Invalid signature" error_code KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED, "Key parameters not accepted" error_code KRB5KDC_ERR_CERTIFICATE_MISMATCH, "Certificate mismatch" error_code KRB5KRB_AP_ERR_NO_TGT, "No ticket granting ticket" error_code KRB5KDC_ERR_WRONG_REALM, "Realm not local to KDC" error_code KRB5KRB_AP_ERR_USER_TO_USER_REQUIRED, "User to user required" error_code KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE, "Can't verify certificate" error_code KRB5KDC_ERR_INVALID_CERTIFICATE, "Invalid certificate" error_code KRB5KDC_ERR_REVOKED_CERTIFICATE, "Revoked certificate" error_code KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN, "Revocation status unknown" error_code KRB5KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "Revocation status unavailable" error_code KRB5KDC_ERR_CLIENT_NAME_MISMATCH, "Client name mismatch" error_code KRB5KDC_ERR_KDC_NAME_MISMATCH, "KDC name mismatch" error_code KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE, "Inconsistent key purpose" error_code KRB5KDC_ERR_DIGEST_IN_CERT_NOT_ACCEPTED, "Digest in certificate not accepted" error_code KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED, "Checksum must be included" error_code KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED, "Digest in signed-data not accepted" error_code KRB5KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED, "Public key encryption not supported" error_code KRB5PLACEHOLD_82, "KRB5 error code 82" error_code KRB5PLACEHOLD_83, "KRB5 error code 83" error_code KRB5PLACEHOLD_84, "KRB5 error code 84" error_code KRB5KRB_AP_ERR_IAKERB_KDC_NOT_FOUND, "The IAKERB proxy could not find a KDC" error_code KRB5KRB_AP_ERR_IAKERB_KDC_NO_RESPONSE, "The KDC did not respond to the IAKERB proxy" error_code KRB5PLACEHOLD_87, "KRB5 error code 87" error_code KRB5PLACEHOLD_88, "KRB5 error code 88" error_code KRB5PLACEHOLD_89, "KRB5 error code 89" error_code KRB5KDC_ERR_PREAUTH_EXPIRED, "Preauthentication expired" error_code KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, "More preauthentication data is required" error_code KRB5PLACEHOLD_92, "KRB5 error code 92" error_code KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION, "An unsupported critical FAST option was requested" error_code KRB5PLACEHOLD_94, "KRB5 error code 94" error_code KRB5PLACEHOLD_95, "KRB5 error code 95" error_code KRB5PLACEHOLD_96, "KRB5 error code 96" error_code KRB5PLACEHOLD_97, "KRB5 error code 97" error_code KRB5PLACEHOLD_98, "KRB5 error code 98" error_code KRB5PLACEHOLD_99, "KRB5 error code 99" error_code KRB5KDC_ERR_NO_ACCEPTABLE_KDF, "No acceptable KDF offered" error_code KRB5PLACEHOLD_101, "KRB5 error code 101" error_code KRB5PLACEHOLD_102, "KRB5 error code 102" error_code KRB5PLACEHOLD_103, "KRB5 error code 103" error_code KRB5PLACEHOLD_104, "KRB5 error code 104" error_code KRB5PLACEHOLD_105, "KRB5 error code 105" error_code KRB5PLACEHOLD_106, "KRB5 error code 106" error_code KRB5PLACEHOLD_107, "KRB5 error code 107" error_code KRB5PLACEHOLD_108, "KRB5 error code 108" error_code KRB5PLACEHOLD_109, "KRB5 error code 109" error_code KRB5PLACEHOLD_110, "KRB5 error code 110" error_code KRB5PLACEHOLD_111, "KRB5 error code 111" error_code KRB5PLACEHOLD_112, "KRB5 error code 112" error_code KRB5PLACEHOLD_113, "KRB5 error code 113" error_code KRB5PLACEHOLD_114, "KRB5 error code 114" error_code KRB5PLACEHOLD_115, "KRB5 error code 115" error_code KRB5PLACEHOLD_116, "KRB5 error code 116" error_code KRB5PLACEHOLD_117, "KRB5 error code 117" error_code KRB5PLACEHOLD_118, "KRB5 error code 118" error_code KRB5PLACEHOLD_119, "KRB5 error code 119" error_code KRB5PLACEHOLD_120, "KRB5 error code 120" error_code KRB5PLACEHOLD_121, "KRB5 error code 121" error_code KRB5PLACEHOLD_122, "KRB5 error code 122" error_code KRB5PLACEHOLD_123, "KRB5 error code 123" error_code KRB5PLACEHOLD_124, "KRB5 error code 124" error_code KRB5PLACEHOLD_125, "KRB5 error code 125" error_code KRB5PLACEHOLD_126, "KRB5 error code 126" error_code KRB5PLACEHOLD_127, "KRB5 error code 127" error_code KRB5_ERR_RCSID, "$Id$" error_code KRB5_LIBOS_BADLOCKFLAG, "Invalid flag for file lock mode" error_code KRB5_LIBOS_CANTREADPWD, "Cannot read password" error_code KRB5_LIBOS_BADPWDMATCH, "Password mismatch" error_code KRB5_LIBOS_PWDINTR, "Password read interrupted" error_code KRB5_PARSE_ILLCHAR, "Illegal character in component name" error_code KRB5_PARSE_MALFORMED, "Malformed representation of principal" error_code KRB5_CONFIG_CANTOPEN, "Can't open/find Kerberos configuration file" error_code KRB5_CONFIG_BADFORMAT, "Improper format of Kerberos configuration file" error_code KRB5_CONFIG_NOTENUFSPACE, "Insufficient space to return complete information" error_code KRB5_BADMSGTYPE, "Invalid message type specified for encoding" error_code KRB5_CC_BADNAME, "Credential cache name malformed" error_code KRB5_CC_UNKNOWN_TYPE, "Unknown credential cache type" error_code KRB5_CC_NOTFOUND, "Matching credential not found" error_code KRB5_CC_END, "End of credential cache reached" error_code KRB5_NO_TKT_SUPPLIED, "Request did not supply a ticket" error_code KRB5KRB_AP_WRONG_PRINC, "Wrong principal in request" error_code KRB5KRB_AP_ERR_TKT_INVALID, "Ticket has invalid flag set" error_code KRB5_PRINC_NOMATCH, "Requested principal and ticket don't match" error_code KRB5_KDCREP_MODIFIED, "KDC reply did not match expectations" error_code KRB5_KDCREP_SKEW, "Clock skew too great in KDC reply" error_code KRB5_IN_TKT_REALM_MISMATCH, "Client/server realm mismatch in initial ticket request" error_code KRB5_PROG_ETYPE_NOSUPP, "Program lacks support for encryption type" error_code KRB5_PROG_KEYTYPE_NOSUPP, "Program lacks support for key type" error_code KRB5_WRONG_ETYPE, "Requested encryption type not used in message" error_code KRB5_PROG_SUMTYPE_NOSUPP, "Program lacks support for checksum type" error_code KRB5_REALM_UNKNOWN, "Cannot find KDC for requested realm" error_code KRB5_SERVICE_UNKNOWN, "Kerberos service unknown" error_code KRB5_KDC_UNREACH, "Cannot contact any KDC for requested realm" error_code KRB5_NO_LOCALNAME, "No local name found for principal name" error_code KRB5_MUTUAL_FAILED, "Mutual authentication failed" # some of these should be combined/supplanted by system codes error_code KRB5_RC_TYPE_EXISTS, "Replay cache type is already registered" error_code KRB5_RC_MALLOC, "No more memory to allocate (in replay cache code)" error_code KRB5_RC_TYPE_NOTFOUND, "Replay cache type is unknown" error_code KRB5_RC_UNKNOWN, "Generic unknown RC error" error_code KRB5_RC_REPLAY, "Message is a replay" error_code KRB5_RC_IO, "Replay cache I/O operation failed" error_code KRB5_RC_NOIO, "Replay cache type does not support non-volatile storage" error_code KRB5_RC_PARSE, "Replay cache name parse/format error" error_code KRB5_RC_IO_EOF, "End-of-file on replay cache I/O" error_code KRB5_RC_IO_MALLOC, "No more memory to allocate (in replay cache I/O code)" error_code KRB5_RC_IO_PERM, "Permission denied in replay cache code" error_code KRB5_RC_IO_IO, "I/O error in replay cache i/o code" error_code KRB5_RC_IO_UNKNOWN, "Generic unknown RC/IO error" error_code KRB5_RC_IO_SPACE, "Insufficient system space to store replay information" error_code KRB5_TRANS_CANTOPEN, "Can't open/find realm translation file" error_code KRB5_TRANS_BADFORMAT, "Improper format of realm translation file" error_code KRB5_LNAME_CANTOPEN, "Can't open/find lname translation database" error_code KRB5_LNAME_NOTRANS, "No translation available for requested principal" error_code KRB5_LNAME_BADFORMAT, "Improper format of translation database entry" error_code KRB5_CRYPTO_INTERNAL, "Cryptosystem internal error" error_code KRB5_KT_BADNAME, "Key table name malformed" error_code KRB5_KT_UNKNOWN_TYPE, "Unknown Key table type" error_code KRB5_KT_NOTFOUND, "Key table entry not found" error_code KRB5_KT_END, "End of key table reached" error_code KRB5_KT_NOWRITE, "Cannot write to specified key table" error_code KRB5_KT_IOERR, "Error writing to key table" error_code KRB5_NO_TKT_IN_RLM, "Cannot find ticket for requested realm" error_code KRB5DES_BAD_KEYPAR, "DES key has bad parity" error_code KRB5DES_WEAK_KEY, "DES key is a weak key" error_code KRB5_BAD_ENCTYPE, "Bad encryption type" error_code KRB5_BAD_KEYSIZE, "Key size is incompatible with encryption type" error_code KRB5_BAD_MSIZE, "Message size is incompatible with encryption type" error_code KRB5_CC_TYPE_EXISTS, "Credentials cache type is already registered." error_code KRB5_KT_TYPE_EXISTS, "Key table type is already registered." error_code KRB5_CC_IO, "Credentials cache I/O operation failed" error_code KRB5_FCC_PERM, "Credentials cache permissions incorrect" error_code KRB5_FCC_NOFILE, "No credentials cache found" error_code KRB5_FCC_INTERNAL, "Internal credentials cache error" error_code KRB5_CC_WRITE, "Error writing to credentials cache" error_code KRB5_CC_NOMEM, "No more memory to allocate (in credentials cache code)" error_code KRB5_CC_FORMAT, "Bad format in credentials cache" error_code KRB5_CC_NOT_KTYPE, "No credentials found with supported encryption types" # errors for dual tgt library calls error_code KRB5_INVALID_FLAGS, "Invalid KDC option combination (library internal error)" error_code KRB5_NO_2ND_TKT, "Request missing second ticket" error_code KRB5_NOCREDS_SUPPLIED, "No credentials supplied to library routine" # errors for sendauth (and recvauth) error_code KRB5_SENDAUTH_BADAUTHVERS, "Bad sendauth version was sent" error_code KRB5_SENDAUTH_BADAPPLVERS, "Bad application version was sent (via sendauth)" error_code KRB5_SENDAUTH_BADRESPONSE, "Bad response (during sendauth exchange)" error_code KRB5_SENDAUTH_REJECTED, "Server rejected authentication (during sendauth exchange)" # errors for preauthentication error_code KRB5_PREAUTH_BAD_TYPE, "Unsupported preauthentication type" error_code KRB5_PREAUTH_NO_KEY, "Required preauthentication key not supplied" error_code KRB5_PREAUTH_FAILED, "Generic preauthentication failure" # version number errors error_code KRB5_RCACHE_BADVNO, "Unsupported replay cache format version number" error_code KRB5_CCACHE_BADVNO, "Unsupported credentials cache format version number" error_code KRB5_KEYTAB_BADVNO, "Unsupported key table format version number" # # error_code KRB5_PROG_ATYPE_NOSUPP, "Program lacks support for address type" error_code KRB5_RC_REQUIRED, "Message replay detection requires rcache parameter" error_code KRB5_ERR_BAD_HOSTNAME, "Hostname cannot be canonicalized" error_code KRB5_ERR_HOST_REALM_UNKNOWN, "Cannot determine realm for host" error_code KRB5_SNAME_UNSUPP_NAMETYPE, "Conversion to service principal undefined for name type" error_code KRB5KRB_AP_ERR_V4_REPLY, "Initial Ticket response appears to be Version 4 error" error_code KRB5_REALM_CANT_RESOLVE, "Cannot resolve network address for KDC in requested realm" error_code KRB5_TKT_NOT_FORWARDABLE, "Requesting ticket can't get forwardable tickets" error_code KRB5_FWD_BAD_PRINCIPAL, "Bad principal name while trying to forward credentials" error_code KRB5_GET_IN_TKT_LOOP, "Looping detected inside krb5_get_in_tkt" error_code KRB5_CONFIG_NODEFREALM, "Configuration file does not specify default realm" error_code KRB5_SAM_UNSUPPORTED, "Bad SAM flags in obtain_sam_padata" error_code KRB5_SAM_INVALID_ETYPE, "Invalid encryption type in SAM challenge" error_code KRB5_SAM_NO_CHECKSUM, "Missing checksum in SAM challenge" error_code KRB5_SAM_BAD_CHECKSUM, "Bad checksum in SAM challenge" error_code KRB5_KT_NAME_TOOLONG, "Keytab name too long" error_code KRB5_KT_KVNONOTFOUND, "Key version number for principal in key table is incorrect" error_code KRB5_APPL_EXPIRED, "This application has expired" error_code KRB5_LIB_EXPIRED, "This Krb5 library has expired" error_code KRB5_CHPW_PWDNULL, "New password cannot be zero length" error_code KRB5_CHPW_FAIL, "Password change failed" error_code KRB5_KT_FORMAT, "Bad format in keytab" error_code KRB5_NOPERM_ETYPE, "Encryption type not permitted" error_code KRB5_CONFIG_ETYPE_NOSUPP, "No supported encryption types (config file error?)" error_code KRB5_OBSOLETE_FN, "Program called an obsolete, deleted function" # translated versions of getaddrinfo errors error_code KRB5_EAI_FAIL, "unknown getaddrinfo failure" error_code KRB5_EAI_NODATA, "no data available for host/domain name" error_code KRB5_EAI_NONAME, "host/domain name not found" error_code KRB5_EAI_SERVICE, "service name unknown" error_code KRB5_ERR_NUMERIC_REALM, "Cannot determine realm for numeric host address" error_code KRB5_ERR_BAD_S2K_PARAMS, "Invalid key generation parameters from KDC" error_code KRB5_ERR_NO_SERVICE, "service not available" error_code KRB5_CC_READONLY, "Ccache function not supported: read-only ccache type" error_code KRB5_CC_NOSUPP, "Ccache function not supported: not implemented" error_code KRB5_DELTAT_BADFORMAT, "Invalid format of Kerberos lifetime or clock skew string" error_code KRB5_PLUGIN_NO_HANDLE, "Supplied data not handled by this plugin" error_code KRB5_PLUGIN_OP_NOTSUPP, "Plugin does not support the operation" error_code KRB5_ERR_INVALID_UTF8, "Invalid UTF-8 string" error_code KRB5_ERR_FAST_REQUIRED, "FAST protected pre-authentication required but not supported by KDC" error_code KRB5_LOCAL_ADDR_REQUIRED, "Auth context must contain local address" error_code KRB5_REMOTE_ADDR_REQUIRED, "Auth context must contain remote address" error_code KRB5_TRACE_NOSUPP, "Tracing unsupported" end krb5-1.22.1/src/lib/krb5/rcache/0000775000175000017500000000000015051422640015766 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/rcache/memrcache.h0000664000175000017500000000370115051422640020064 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/rcache/memrcache.h - declarations for in-memory replay cache */ /* * Copyright (C) 2019 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef MEMRCACHE_H #define MEMRCACHE_H typedef struct k5_memrcache_st *k5_memrcache; krb5_error_code k5_memrcache_create(krb5_context context, k5_memrcache *mrc_out); krb5_error_code k5_memrcache_store(krb5_context context, k5_memrcache mrc, const krb5_data *tag); void k5_memrcache_free(krb5_context context, k5_memrcache mrc); #endif /* MEMRCACHE_H */ krb5-1.22.1/src/lib/krb5/rcache/rc_dfl.c0000664000175000017500000001036215051422640017365 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/rcache/rc_dfl.c - default replay cache type */ /* * Copyright (C) 2019 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * The dfl rcache type is a wrapper around the file2 rcache type, selecting a * filename and (on Unix-like systems) applying open() safety appropriate for * using a shared temporary directory. */ #include "k5-int.h" #include "rc-int.h" #ifdef _WIN32 #include "../os/os-proto.h" #else #include #include #endif #ifdef _WIN32 static krb5_error_code open_file(krb5_context context, int *fd_out) { krb5_error_code ret; char *fname; const char *dir; *fd_out = -1; dir = getenv("KRB5RCACHEDIR"); if (dir != NULL) { if (asprintf(&fname, "%s\\krb5.rcache2") < 0) return ENOMEM; } else { ret = k5_expand_path_tokens(context, "%{LOCAL_APPDATA}\\krb5.rcache2", &fname); if (ret) return ret; } *fd_out = open(fname, O_CREAT | O_RDWR | O_BINARY, 0600); ret = (*fd_out < 0) ? errno : 0; if (ret) { k5_setmsg(context, ret, "%s (filename: %s)", error_message(ret), fname); } free(fname); return ret; } #else /* _WIN32 */ static krb5_error_code open_file(krb5_context context, int *fd_out) { krb5_error_code ret; int fd = -1; char *fname = NULL; const char *dir; struct stat statbuf; uid_t euid = geteuid(); *fd_out = -1; dir = secure_getenv("KRB5RCACHEDIR"); if (dir == NULL) { dir = secure_getenv("TMPDIR"); if (dir == NULL) dir = RCTMPDIR; } if (asprintf(&fname, "%s/krb5_%lu.rcache2", dir, (unsigned long)euid) < 0) return ENOMEM; fd = open(fname, O_CREAT | O_RDWR | O_NOFOLLOW, 0600); if (fd < 0) { ret = errno; k5_setmsg(context, ret, "%s (filename: %s)", error_message(ret), fname); goto cleanup; } if (fstat(fd, &statbuf) < 0 || statbuf.st_uid != euid) { ret = EIO; k5_setmsg(context, ret, "Replay cache file %s is not owned by uid %lu", fname, (unsigned long)euid); goto cleanup; } *fd_out = fd; fd = -1; ret = 0; cleanup: if (fd != -1) close(fd); free(fname); return ret; } #endif /* not _WIN32 */ static krb5_error_code dfl_resolve(krb5_context context, const char *residual, void **rcdata_out) { *rcdata_out = NULL; return 0; } static void dfl_close(krb5_context context, void *rcdata) { } static krb5_error_code dfl_store(krb5_context context, void *rcdata, const krb5_data *tag) { krb5_error_code ret; int fd; ret = open_file(context, &fd); if (ret) return ret; ret = k5_rcfile2_store(context, fd, tag); close(fd); return ret; } const krb5_rc_ops k5_rc_dfl_ops = { "dfl", dfl_resolve, dfl_close, dfl_store }; krb5-1.22.1/src/lib/krb5/rcache/Makefile.in0000664000175000017500000000221715051422640020035 0ustar ghudsonghudsonmydir=lib$(S)krb5$(S)rcache BUILDTOP=$(REL)..$(S)..$(S).. ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=rcache ##DOS##OBJFILE=..\$(OUTPRE)$(PREFIXDIR).lst STLIBOBJS = \ memrcache.o \ rc_base.o \ rc_dfl.o \ rc_file2.o \ rc_none.o OBJS= \ $(OUTPRE)memrcache.$(OBJEXT) \ $(OUTPRE)rc_base.$(OBJEXT) \ $(OUTPRE)rc_dfl.$(OBJEXT) \ $(OUTPRE)rc_file2.$(OBJEXT) \ $(OUTPRE)rc_none.$(OBJEXT) SRCS= \ $(srcdir)/memrcache.c \ $(srcdir)/rc_base.c \ $(srcdir)/rc_dfl.c \ $(srcdir)/rc_file2.c \ $(srcdir)/rc_none.c EXTRADEPSRCS= \ $(srcdir)/t_memrcache.c \ $(srcdir)/t_rcfile2.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs clean-unix:: clean-libobjs t_memrcache: t_memrcache.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_memrcache.o $(KRB5_BASE_LIBS) t_rcfile2: t_rcfile2.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_rcfile2.o $(KRB5_BASE_LIBS) check-unix: t_memrcache t_rcfile2 $(RUN_TEST) ./t_memrcache $(RUN_TEST) ./t_rcfile2 testrcache expiry 10000 $(RUN_TEST) ./t_rcfile2 testrcache concurrent 10 1000 $(RUN_TEST) ./t_rcfile2 testrcache race 10 100 clean-unix:: $(RM) t_memrcache.o t_memrcache t_rcfile2.o t_rcfile2 testrcache @libobj_frag@ krb5-1.22.1/src/lib/krb5/rcache/rc-int.h0000664000175000017500000000436715051422640017345 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/rcache/rc-int.h */ /* * Copyright 2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* This file contains constant and function declarations used in the * file-based replay cache routines. */ #ifndef RC_INT_H #define RC_INT_H typedef struct { const char *type; krb5_error_code (*resolve)(krb5_context context, const char *residual, void **rcdata_out); void (*close)(krb5_context context, void *rcdata); krb5_error_code (*store)(krb5_context, void *rcdata, const krb5_data *tag); } krb5_rc_ops; struct krb5_rc_st { krb5_magic magic; const krb5_rc_ops *ops; char *name; void *data; }; extern const krb5_rc_ops k5_rc_dfl_ops; extern const krb5_rc_ops k5_rc_file2_ops; extern const krb5_rc_ops k5_rc_none_ops; /* Check and store a replay record in an open (but not locked) file descriptor, * using the file2 format. fd is assumed to be at offset 0. */ krb5_error_code k5_rcfile2_store(krb5_context context, int fd, const krb5_data *tag_data); #endif /* RC_INT_H */ krb5-1.22.1/src/lib/krb5/rcache/deps0000664000175000017500000001265215051422640016652 0ustar ghudsonghudson# # Generated makefile dependencies follow. # memrcache.so memrcache.po $(OUTPRE)memrcache.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hashtab.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-queue.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ memrcache.c memrcache.h rc_base.so rc_base.po $(OUTPRE)rc_base.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../os/os-proto.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h rc-int.h rc_base.c rc_dfl.so rc_dfl.po $(OUTPRE)rc_dfl.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h rc-int.h rc_dfl.c rc_file2.so rc_file2.po $(OUTPRE)rc_file2.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hashtab.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h rc-int.h rc_file2.c rc_none.so rc_none.po $(OUTPRE)rc_none.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h rc-int.h rc_none.c t_memrcache.so t_memrcache.po $(OUTPRE)t_memrcache.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hashtab.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-queue.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ memrcache.c memrcache.h t_memrcache.c t_rcfile2.so t_rcfile2.po $(OUTPRE)t_rcfile2.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hashtab.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h rc-int.h rc_file2.c \ t_rcfile2.c krb5-1.22.1/src/lib/krb5/rcache/rc_file2.c0000664000175000017500000002001115051422640017611 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/rcache/rc_file2.c - file-based replay cache, version 2 */ /* * Copyright (C) 2019 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "k5-hashtab.h" #include "rc-int.h" #ifndef _WIN32 #include #include #endif #define MAX_SIZE INT32_MAX #define TAG_LEN 12 #define RECORD_LEN (TAG_LEN + 4) #define FIRST_TABLE_RECORDS 1023 /* Return the offset and number of records in the next table. *offset should * initially be -1. */ static inline krb5_error_code next_table(off_t *offset, off_t *nrecords) { if (*offset == -1) { *offset = K5_HASH_SEED_LEN; *nrecords = FIRST_TABLE_RECORDS; } else if (*offset == K5_HASH_SEED_LEN) { *offset += *nrecords * RECORD_LEN; *nrecords = (FIRST_TABLE_RECORDS + 1) * 2; } else { *offset += *nrecords * RECORD_LEN; *nrecords *= 2; } /* Make sure the next table fits within the maximum file size. */ if (*nrecords > MAX_SIZE / RECORD_LEN) return EOVERFLOW; if (*offset > MAX_SIZE - (*nrecords * RECORD_LEN)) return EOVERFLOW; return 0; } /* Read up to two records from fd at offset, and parse them out into tags and * timestamps. Place the number of records read in *nread. */ static krb5_error_code read_records(int fd, off_t offset, uint8_t tag1_out[TAG_LEN], uint32_t *timestamp1_out, uint8_t tag2_out[TAG_LEN], uint32_t *timestamp2_out, int *nread) { uint8_t buf[RECORD_LEN * 2]; ssize_t st; *nread = 0; st = lseek(fd, offset, SEEK_SET); if (st == -1) return errno; st = read(fd, buf, RECORD_LEN * 2); if (st == -1) return errno; if (st >= RECORD_LEN) { memcpy(tag1_out, buf, TAG_LEN); *timestamp1_out = load_32_be(buf + TAG_LEN); *nread = 1; } if (st == RECORD_LEN * 2) { memcpy(tag2_out, buf + RECORD_LEN, TAG_LEN); *timestamp2_out = load_32_be(buf + RECORD_LEN + TAG_LEN); *nread = 2; } return 0; } /* Write one record to fd at offset, marshalling the tag and timestamp. */ static krb5_error_code write_record(int fd, off_t offset, const uint8_t tag[TAG_LEN], uint32_t timestamp) { uint8_t record[RECORD_LEN]; ssize_t st; memcpy(record, tag, TAG_LEN); store_32_be(timestamp, record + TAG_LEN); st = lseek(fd, offset, SEEK_SET); if (st == -1) return errno; st = write(fd, record, RECORD_LEN); if (st == -1) return errno; if (st != RECORD_LEN) /* Unexpected for a regular file */ return EIO; return 0; } /* Return true if timestamp is expired, for the current timestamp (now) and * allowable clock skew. */ static inline krb5_boolean expired(uint32_t timestamp, uint32_t now, uint32_t skew) { return ts_after(now, ts_incr(timestamp, skew)); } /* Check and store a record into an open and locked file. fd is assumed to be * at offset 0. */ static krb5_error_code store(krb5_context context, int fd, const uint8_t tag[TAG_LEN], uint32_t now, uint32_t skew) { krb5_error_code ret; krb5_data d; off_t table_offset = -1, nrecords = 0, avail_offset = -1, record_offset; ssize_t st; int ind, nread; uint8_t seed[K5_HASH_SEED_LEN], r1tag[TAG_LEN], r2tag[TAG_LEN]; uint32_t r1stamp, r2stamp; /* Read or generate the hash seed. */ st = read(fd, seed, sizeof(seed)); if (st < 0) return errno; if ((size_t)st < sizeof(seed)) { d = make_data(seed, sizeof(seed)); ret = krb5_c_random_make_octets(context, &d); if (ret) return ret; st = write(fd, seed, sizeof(seed)); if (st < 0) return errno; if ((size_t)st != sizeof(seed)) return EIO; } for (;;) { ret = next_table(&table_offset, &nrecords); if (ret) return ret; ind = k5_siphash24(tag, TAG_LEN, seed) % nrecords; record_offset = table_offset + ind * RECORD_LEN; ret = read_records(fd, record_offset, r1tag, &r1stamp, r2tag, &r2stamp, &nread); if (ret) return ret; if ((nread >= 1 && r1stamp && memcmp(r1tag, tag, TAG_LEN) == 0) || (nread == 2 && r2stamp && memcmp(r2tag, tag, TAG_LEN) == 0)) return KRB5KRB_AP_ERR_REPEAT; /* Make note of the first record available for writing (empty, beyond * the end of the file, or expired). */ if (avail_offset == -1) { if (nread == 0 || !r1stamp || expired(r1stamp, now, skew)) avail_offset = record_offset; else if (nread == 1 || !r2stamp || expired(r2stamp, now, skew)) avail_offset = record_offset + RECORD_LEN; } /* Stop searching if we encountered an empty record or one beyond the * end of the file, as tag would have been written there previously. */ if (nread < 2 || !r1stamp || !r2stamp) return write_record(fd, avail_offset, tag, now); /* Use a different hash seed for the next table we search. */ seed[0]++; } } krb5_error_code k5_rcfile2_store(krb5_context context, int fd, const krb5_data *tag_data) { krb5_error_code ret; krb5_timestamp now; uint8_t tagbuf[TAG_LEN], *tag; ret = krb5_timeofday(context, &now); if (ret) return ret; /* Extract a tag from the authenticator checksum. */ if (tag_data->length >= TAG_LEN) { tag = (uint8_t *)tag_data->data; } else { memcpy(tagbuf, tag_data->data, tag_data->length); memset(tagbuf + tag_data->length, 0, TAG_LEN - tag_data->length); tag = tagbuf; } ret = krb5_lock_file(context, fd, KRB5_LOCKMODE_EXCLUSIVE); if (ret) return ret; ret = store(context, fd, tag, now, context->clockskew); (void)krb5_unlock_file(NULL, fd); return ret; } static krb5_error_code file2_resolve(krb5_context context, const char *residual, void **rcdata_out) { *rcdata_out = strdup(residual); return (*rcdata_out == NULL) ? ENOMEM : 0; } static void file2_close(krb5_context context, void *rcdata) { free(rcdata); } static krb5_error_code file2_store(krb5_context context, void *rcdata, const krb5_data *tag) { krb5_error_code ret; const char *filename = rcdata; int fd; fd = open(filename, O_CREAT | O_RDWR | O_BINARY, 0600); if (fd < 0) { ret = errno; k5_setmsg(context, ret, "%s (filename: %s)", error_message(ret), filename); return ret; } ret = k5_rcfile2_store(context, fd, tag); close(fd); return ret; } const krb5_rc_ops k5_rc_file2_ops = { "file2", file2_resolve, file2_close, file2_store }; krb5-1.22.1/src/lib/krb5/rcache/memrcache.c0000664000175000017500000001137215051422640020062 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/rcache/memrcache.c - in-memory replay cache implementation */ /* * Copyright (C) 2019 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "k5-queue.h" #include "k5-hashtab.h" #include "memrcache.h" struct entry { K5_TAILQ_ENTRY(entry) links; krb5_timestamp timestamp; krb5_data tag; }; K5_LIST_HEAD(entry_list, entry); K5_TAILQ_HEAD(entry_queue, entry); struct k5_memrcache_st { struct k5_hashtab *hash_table; struct entry_queue expiration_queue; }; static krb5_error_code insert_entry(krb5_context context, k5_memrcache mrc, const krb5_data *tag, krb5_timestamp now) { krb5_error_code ret; struct entry *entry = NULL; entry = calloc(1, sizeof(*entry)); if (entry == NULL) return ENOMEM; entry->timestamp = now; ret = krb5int_copy_data_contents(context, tag, &entry->tag); if (ret) goto error; ret = k5_hashtab_add(mrc->hash_table, entry->tag.data, entry->tag.length, entry); if (ret) goto error; K5_TAILQ_INSERT_TAIL(&mrc->expiration_queue, entry, links); return 0; error: if (entry != NULL) { krb5_free_data_contents(context, &entry->tag); free(entry); } return ret; } /* Remove entry from its hash bucket and the expiration queue, and free it. */ static void discard_entry(krb5_context context, k5_memrcache mrc, struct entry *entry) { k5_hashtab_remove(mrc->hash_table, entry->tag.data, entry->tag.length); K5_TAILQ_REMOVE(&mrc->expiration_queue, entry, links); krb5_free_data_contents(context, &entry->tag); free(entry); } /* Initialize the lookaside cache structures and randomize the hash seed. */ krb5_error_code k5_memrcache_create(krb5_context context, k5_memrcache *mrc_out) { krb5_error_code ret; k5_memrcache mrc; uint8_t seed[K5_HASH_SEED_LEN]; krb5_data seed_data = make_data(seed, sizeof(seed)); *mrc_out = NULL; ret = krb5_c_random_make_octets(context, &seed_data); if (ret) return ret; mrc = calloc(1, sizeof(*mrc)); if (mrc == NULL) return ENOMEM; ret = k5_hashtab_create(seed, 64, &mrc->hash_table); if (ret) { free(mrc); return ret; } K5_TAILQ_INIT(&mrc->expiration_queue); *mrc_out = mrc; return 0; } krb5_error_code k5_memrcache_store(krb5_context context, k5_memrcache mrc, const krb5_data *tag) { krb5_error_code ret; krb5_timestamp now; struct entry *e, *next; ret = krb5_timeofday(context, &now); if (ret) return ret; /* Check if we already have a matching entry. */ e = k5_hashtab_get(mrc->hash_table, tag->data, tag->length); if (e != NULL) return KRB5KRB_AP_ERR_REPEAT; /* Discard stale entries. */ K5_TAILQ_FOREACH_SAFE(e, &mrc->expiration_queue, links, next) { if (!ts_after(now, ts_incr(e->timestamp, context->clockskew))) break; discard_entry(context, mrc, e); } /* Add the new entry. */ return insert_entry(context, mrc, tag, now); } /* Free all entries in the lookaside cache. */ void k5_memrcache_free(krb5_context context, k5_memrcache mrc) { struct entry *e, *next; if (mrc == NULL) return; K5_TAILQ_FOREACH_SAFE(e, &mrc->expiration_queue, links, next) { discard_entry(context, mrc, e); } k5_hashtab_free(mrc->hash_table); free(mrc); } krb5-1.22.1/src/lib/krb5/rcache/rc_none.c0000664000175000017500000000342115051422640017555 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/rcache/rc_none.c */ /* * Copyright 2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * replay cache no-op implementation */ #include "k5-int.h" #include "rc-int.h" static krb5_error_code none_resolve(krb5_context ctx, const char *residual, void **rcdata_out) { *rcdata_out = NULL; return 0; } static void none_close(krb5_context ctx, void *rcdata) { } static krb5_error_code none_store(krb5_context ctx, void *rcdata, const krb5_data *tag) { return 0; } const krb5_rc_ops k5_rc_none_ops = { "none", none_resolve, none_close, none_store }; krb5-1.22.1/src/lib/krb5/rcache/t_rcfile2.c0000664000175000017500000001552515051422640020013 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/rcache/t_rcfile2.c - rcache file version 2 tests */ /* * Copyright (C) 2019 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Usage: * * t_rcfile2 expiry * store records spaced far enough apart that all records appear * expired; verify that the file size doesn't increase beyond one table. * * t_rcfile2 concurrent * spawn subprocesses, each of which stores unique * tags. As each process completes, the master process tests that the * records stored by the subprocess appears as replays. * * t_rcfile2 race * spawn subprocesses, each of which tries to store the same * tag and reports success or failure. The master process verifies that * exactly one subprocess succeeds. Repeat times. */ #include "rc_file2.c" #include #include krb5_context ctx; static krb5_error_code test_store(const char *filename, uint8_t *tag, krb5_timestamp timestamp, const uint32_t clockskew) { krb5_data tag_data = make_data(tag, TAG_LEN); ctx->clockskew = clockskew; (void)krb5_set_debugging_time(ctx, timestamp, 0); return file2_store(ctx, (void *)filename, &tag_data); } /* Store a sequence of unique tags, with timestamps far enough apart that all * previous records appear expired. Verify that we only use one table. */ static void expiry_test(const char *filename, int reps) { krb5_error_code ret; struct stat statbuf; uint8_t tag[TAG_LEN] = { 0 }, seed[K5_HASH_SEED_LEN] = { 0 }, data[4]; uint32_t timestamp; const uint32_t clockskew = 5, start = 1000; uint64_t hashval; int i, st; assert((uint32_t)reps < (UINT32_MAX - start) / clockskew / 2); for (i = 0, timestamp = start; i < reps; i++, timestamp += clockskew * 2) { store_32_be(i, data); hashval = k5_siphash24(data, 4, seed); store_64_be(hashval, tag); ret = test_store(filename, tag, timestamp, clockskew); assert(ret == 0); /* Since we increment timestamp enough to expire every record between * each call, we should never create a second hash table. */ st = stat(filename, &statbuf); assert(st == 0); assert(statbuf.st_size <= (FIRST_TABLE_RECORDS + 1) * RECORD_LEN); } } /* Store a sequence of unique tags with the same timestamp. Exit with failure * if any store operation doesn't succeed or fail as given by expect_fail. */ static void store_records(const char *filename, int id, int reps, int expect_fail) { krb5_error_code ret; uint8_t tag[TAG_LEN] = { 0 }; int i; store_32_be(id, tag); for (i = 0; i < reps; i++) { store_32_be(i, tag + 4); ret = test_store(filename, tag, 1000, 100); if (ret != (expect_fail ? KRB5KRB_AP_ERR_REPEAT : 0)) { fprintf(stderr, "store %d %d %sfail\n", id, i, expect_fail ? "didn't " : ""); _exit(1); } } } /* Spawn multiple child processes, each storing a sequence of unique tags. * After each process completes, verify that its tags appear as replays. */ static void concurrency_test(const char *filename, int nchildren, int reps) { pid_t *pids, pid; int i, nprocs, status; pids = calloc(nchildren, sizeof(*pids)); assert(pids != NULL); for (i = 0; i < nchildren; i++) { pids[i] = fork(); assert(pids[i] != -1); if (pids[i] == 0) { store_records(filename, i, reps, 0); _exit(0); } } for (nprocs = nchildren; nprocs > 0; nprocs--) { pid = wait(&status); assert(pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0); for (i = 0; i < nchildren; i++) { if (pids[i] == pid) store_records(filename, i, reps, 1); } } free(pids); } /* Spawn multiple child processes, all trying to store the same tag. Verify * that only one of the processes succeeded. Repeat reps times. */ static void race_test(const char *filename, int nchildren, int reps) { int i, j, status, nsuccess; uint8_t tag[TAG_LEN] = { 0 }; pid_t pid; for (i = 0; i < reps; i++) { store_32_be(i, tag); for (j = 0; j < nchildren; j++) { pid = fork(); assert(pid != -1); if (pid == 0) _exit(test_store(filename, tag, 1000, 100) != 0); } nsuccess = 0; for (j = 0; j < nchildren; j++) { pid = wait(&status); assert(pid != -1); if (WIFEXITED(status) && WEXITSTATUS(status) == 0) nsuccess++; } assert(nsuccess == 1); } } int main(int argc, char **argv) { const char *filename, *cmd; argv++; assert(*argv != NULL); if (krb5_init_context(&ctx) != 0) abort(); assert(*argv != NULL); filename = *argv++; unlink(filename); assert(*argv != NULL); cmd = *argv++; if (strcmp(cmd, "expiry") == 0) { assert(argv[0] != NULL); expiry_test(filename, atoi(argv[0])); } else if (strcmp(cmd, "concurrent") == 0) { assert(argv[0] != NULL && argv[1] != NULL); concurrency_test(filename, atoi(argv[0]), atoi(argv[1])); } else if (strcmp(cmd, "race") == 0) { assert(argv[0] != NULL && argv[1] != NULL); race_test(filename, atoi(argv[0]), atoi(argv[1])); } else { abort(); } krb5_free_context(ctx); return 0; } krb5-1.22.1/src/lib/krb5/rcache/rc_base.c0000664000175000017500000001213515051422640017532 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/rcache/rc_base.c */ /* * This file of the Kerberos V5 software is derived from public-domain code * contributed by Daniel J. Bernstein, . * */ /* * Base "glue" functions for the replay cache. */ #include "k5-int.h" #include "rc-int.h" #include "k5-thread.h" #include "../os/os-proto.h" struct typelist { const krb5_rc_ops *ops; struct typelist *next; }; static struct typelist none = { &k5_rc_none_ops, 0 }; static struct typelist file2 = { &k5_rc_file2_ops, &none }; static struct typelist dfl = { &k5_rc_dfl_ops, &file2 }; static struct typelist *typehead = &dfl; krb5_error_code k5_rc_default(krb5_context context, krb5_rcache *rc_out) { krb5_error_code ret; const char *val; char *profstr, *rcname; *rc_out = NULL; /* If KRB5RCACHENAME is set in the environment, resolve it. */ val = secure_getenv("KRB5RCACHENAME"); if (val != NULL) return k5_rc_resolve(context, val, rc_out); /* If KRB5RCACHETYPE is set in the environment, resolve it with an empty * residual (primarily to support KRB5RCACHETYPE=none). */ val = secure_getenv("KRB5RCACHETYPE"); if (val != NULL) { if (asprintf(&rcname, "%s:", val) < 0) return ENOMEM; ret = k5_rc_resolve(context, rcname, rc_out); free(rcname); return ret; } /* If [libdefaults] default_rcache_name is set, expand path tokens in the * value and resolve it. */ if (profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_DEFAULT_RCACHE_NAME, NULL, NULL, &profstr) == 0 && profstr != NULL) { ret = k5_expand_path_tokens(context, profstr, &rcname); profile_release_string(profstr); if (ret) return ret; ret = k5_rc_resolve(context, rcname, rc_out); free(rcname); return ret; } /* Resolve the default type with no residual. */ return k5_rc_resolve(context, "dfl:", rc_out); } krb5_error_code k5_rc_resolve(krb5_context context, const char *name, krb5_rcache *rc_out) { krb5_error_code ret; struct typelist *t; const char *sep; size_t len; krb5_rcache rc = NULL; *rc_out = NULL; sep = strchr(name, ':'); if (sep == NULL) return KRB5_RC_PARSE; len = sep - name; for (t = typehead; t != NULL; t = t->next) { if (strncmp(t->ops->type, name, len) == 0 && t->ops->type[len] == '\0') break; } if (t == NULL) return KRB5_RC_TYPE_NOTFOUND; rc = k5alloc(sizeof(*rc), &ret); if (rc == NULL) goto error; rc->name = strdup(name); if (rc->name == NULL) { ret = ENOMEM; goto error; } ret = t->ops->resolve(context, sep + 1, &rc->data); if (ret) goto error; rc->ops = t->ops; rc->magic = KV5M_RCACHE; *rc_out = rc; return 0; error: if (rc != NULL) { free(rc->name); free(rc); } return ret; } void k5_rc_close(krb5_context context, krb5_rcache rc) { rc->ops->close(context, rc->data); free(rc->name); free(rc); } krb5_error_code k5_rc_store(krb5_context context, krb5_rcache rc, const krb5_enc_data *authenticator) { krb5_error_code ret; krb5_data tag; ret = k5_rc_tag_from_ciphertext(context, authenticator, &tag); if (ret) return ret; return rc->ops->store(context, rc->data, &tag); } const char * k5_rc_get_name(krb5_context context, krb5_rcache rc) { return rc->name; } krb5_error_code k5_rc_tag_from_ciphertext(krb5_context context, const krb5_enc_data *enc, krb5_data *tag_out) { krb5_error_code ret; const krb5_data *cdata = &enc->ciphertext; unsigned int len; *tag_out = empty_data(); ret = krb5_c_crypto_length(context, enc->enctype, KRB5_CRYPTO_TYPE_CHECKSUM, &len); if (ret) return ret; if (cdata->length < len) return EINVAL; *tag_out = make_data(cdata->data + cdata->length - len, len); return 0; } /* * Stub functions for former internal replay cache functions used by OpenSSL * (despite the lack of prototypes) before the OpenSSL 1.1 release. */ krb5_error_code krb5_rc_default(krb5_context, krb5_rcache *); krb5_error_code KRB5_CALLCONV krb5_rc_destroy(krb5_context, krb5_rcache); krb5_error_code KRB5_CALLCONV krb5_rc_get_lifespan(krb5_context, krb5_rcache, krb5_deltat *); krb5_error_code KRB5_CALLCONV krb5_rc_initialize(krb5_context, krb5_rcache, krb5_deltat); krb5_error_code krb5_rc_default(krb5_context context, krb5_rcache *rc) { return EINVAL; } krb5_error_code KRB5_CALLCONV krb5_rc_destroy(krb5_context context, krb5_rcache rc) { return EINVAL; } krb5_error_code KRB5_CALLCONV krb5_rc_get_lifespan(krb5_context context, krb5_rcache rc, krb5_deltat *span) { return EINVAL; } krb5_error_code KRB5_CALLCONV krb5_rc_initialize(krb5_context context, krb5_rcache rc, krb5_deltat span) { return EINVAL; } krb5-1.22.1/src/lib/krb5/rcache/t_memrcache.c0000664000175000017500000000566015051422640020410 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/rcache/t_memrcache.c - memory replay cache tests */ /* * Copyright (C) 2019 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "memrcache.c" int main(void) { krb5_error_code ret; krb5_context context; k5_memrcache mrc; int i; uint8_t tag[4]; krb5_data tag_data = make_data(tag, 4); struct entry *e; ret = krb5_init_context(&context); assert(ret == 0); /* Store a thousand unique tags, then verify that they all appear as * replays. */ ret = k5_memrcache_create(context, &mrc); assert(ret == 0); for (i = 0; i < 1000; i++) { store_32_be(i, tag); ret = k5_memrcache_store(context, mrc, &tag_data); assert(ret == 0); } for (i = 0; i < 1000; i++) { store_32_be(i, tag); ret = k5_memrcache_store(context, mrc, &tag_data); assert(ret == KRB5KRB_AP_ERR_REPEAT); } k5_memrcache_free(context, mrc); /* Store a thousand unique tags, each spaced out so that previous entries * appear as expired. Verify that the expiration queue has one entry. */ ret = k5_memrcache_create(context, &mrc); assert(ret == 0); context->clockskew = 100; for (i = 1; i < 1000; i++) { krb5_set_debugging_time(context, i * 200, 0); store_32_be(i, tag); ret = k5_memrcache_store(context, mrc, &tag_data); assert(ret == 0); } e = K5_TAILQ_FIRST(&mrc->expiration_queue); assert(e != NULL && K5_TAILQ_NEXT(e, links) == NULL); k5_memrcache_free(context, mrc); krb5_free_context(context); return 0; } krb5-1.22.1/src/lib/krb5/Makefile.in0000664000175000017500000000331515051422640016610 0ustar ghudsonghudsonmydir=lib$(S)krb5 BUILDTOP=$(REL)..$(S).. LOCALINCLUDES = -I$(srcdir)/ccache -I$(srcdir)/keytab -I$(srcdir)/rcache -I$(srcdir)/os -I$(srcdir)/unicode SUBDIRS= error_tables asn.1 ccache keytab krb os rcache unicode DEFINES=-DLOCALEDIR=\"$(KRB5_LOCALEDIR)\" ##DOSBUILDTOP = ..\.. ##DOSLIBNAME=$(OUTPRE)krb5.lib ##DOSOBJFILEDEP=$(OUTPRE)asn1.lst $(OUTPRE)ccache.lst $(OUTPRE)err_tbls.lst $(OUTPRE)keytab.lst $(OUTPRE)krb.lst $(OUTPRE)os.lst $(OUTPRE)rcache.lst $(OUTPRE)krb5.lst $(OUTPRE)unicode.lst ##DOSOBJFILELIST=@$(OUTPRE)asn1.lst @$(OUTPRE)ccache.lst @$(OUTPRE)err_tbls.lst @$(OUTPRE)keytab.lst @$(OUTPRE)krb.lst @$(OUTPRE)os.lst @$(OUTPRE)rcache.lst @$(OUTPRE)krb5.lst @$(OUTPRE)unicode.lst ##DOSOBJFILE=$(OUTPRE)krb5.lst ##DOSLIBOBJS=$(OBJS) ##DOSLOCALINCLUDES=-Iccache\ccapi -I..\..\windows\lib -Iccache -Ikeytab -Ircache -Ios TST=if test -n "`cat DONE`" ; then STLIBOBJS=krb5_libinit.o LIBBASE=krb5 LIBMAJOR=3 LIBMINOR=3 LIBINITFUNC=profile_library_initializer krb5int_lib_init LIBFINIFUNC=profile_library_finalizer krb5int_lib_fini SUBDIROBJLISTS= \ error_tables/OBJS.ST \ asn.1/OBJS.ST \ ccache/OBJS.ST \ keytab/OBJS.ST \ krb/OBJS.ST \ rcache/OBJS.ST \ unicode/OBJS.ST \ os/OBJS.ST \ $(BUILDTOP)/util/profile/OBJS.ST STOBJLISTS= OBJS.ST $(SUBDIROBJLISTS) OBJS=\ $(OUTPRE)krb5_libinit.$(OBJEXT) SRCS=\ $(srcdir)/krb5_libinit.c RELDIR=krb5 SHLIB_EXPDEPS = \ $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB) SHLIB_EXPLIBS=-lk5crypto $(COM_ERR_LIB) $(SUPPORT_LIB) \ @MACOS_FRAMEWORK@ $(LIBS) all-unix: all-liblinks all-windows: clean-unix:: clean-liblinks clean-libs clean-libobjs clean-windows:: $(RM) $(OUTPRE)krb5.lib krb5.bak install-unix: install-libs @lib_frag@ @libobj_frag@ krb5-1.22.1/src/lib/krb5/krb5_libinit.c0000664000175000017500000000464315051422640017271 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "k5-int.h" #if defined(_WIN32) || defined(USE_CCAPI) #include "stdcc.h" #endif #include "krb5_libinit.h" #include "k5-platform.h" #include "cc-int.h" #include "kt-int.h" #include "os-proto.h" /* * Initialize the Kerberos v5 library. */ MAKE_INIT_FUNCTION(krb5int_lib_init); MAKE_FINI_FUNCTION(krb5int_lib_fini); /* Possibly load-time initialization -- mutexes, etc. */ int krb5int_lib_init(void) { int err; k5_set_error_info_callout_fn(error_message); #ifdef SHOW_INITFINI_FUNCS printf("krb5int_lib_init\n"); #endif add_error_table(&et_krb5_error_table); add_error_table(&et_k5e1_error_table); add_error_table(&et_kv5m_error_table); add_error_table(&et_kdb5_error_table); add_error_table(&et_asn1_error_table); add_error_table(&et_k524_error_table); bindtextdomain(KRB5_TEXTDOMAIN, LOCALEDIR); #ifndef LEAN_CLIENT err = krb5int_kt_initialize(); if (err) return err; #endif /* LEAN_CLIENT */ err = krb5int_cc_initialize(); if (err) return err; err = k5_mutex_finish_init(&krb5int_us_time_mutex); if (err) return err; return 0; } /* Always-delayed initialization -- error table linkage, etc. */ krb5_error_code krb5int_initialize_library (void) { return CALL_INIT_FUNCTION(krb5int_lib_init); } /* * Clean up the Kerberos v5 library state */ void krb5int_lib_fini(void) { if (!INITIALIZER_RAN(krb5int_lib_init) || PROGRAM_EXITING()) { #ifdef SHOW_INITFINI_FUNCS printf("krb5int_lib_fini: skipping\n"); #endif return; } #ifdef SHOW_INITFINI_FUNCS printf("krb5int_lib_fini\n"); #endif k5_mutex_destroy(&krb5int_us_time_mutex); krb5int_cc_finalize(); #ifndef LEAN_CLIENT krb5int_kt_finalize(); #endif /* LEAN_CLIENT */ #if defined(_WIN32) || defined(USE_CCAPI) krb5_stdcc_shutdown(); #endif remove_error_table(&et_krb5_error_table); remove_error_table(&et_k5e1_error_table); remove_error_table(&et_kv5m_error_table); remove_error_table(&et_kdb5_error_table); remove_error_table(&et_asn1_error_table); remove_error_table(&et_k524_error_table); k5_set_error_info_callout_fn(NULL); } /* Still exists because it went into the export list on Windows. But since the above function should be invoked at unload time, we don't actually want to do anything here. */ void krb5int_cleanup_library (void) { } krb5-1.22.1/src/lib/krb5/os/0000775000175000017500000000000015051422640015162 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/os/t_ctxprf.py0000664000175000017500000000062415051422640017367 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(create_kdb=False) mark('initially empty profile') realm.run(['./t_ctxprf', 'empty']) mark('modified single-file profile') realm.run(['./t_ctxprf']) with open(os.path.join(realm.testdir, 'krb5.conf')) as f: contents = f.read() if 'ctx.prf.test' in contents: fail('profile changes unexpectedly flushed') success('krb5_init_context_profile() tests') krb5-1.22.1/src/lib/krb5/os/unlck_file.c0000664000175000017500000000271215051422640017443 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/unlck_file.c */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include krb5_error_code krb5_unlock_file(krb5_context context, int fd) { return krb5_lock_file(context, fd, KRB5_LOCKMODE_UNLOCK); } krb5-1.22.1/src/lib/krb5/os/trace.c0000664000175000017500000004241415051422640016431 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/trace.c - krb5int_trace implementation */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * krb5int_trace is defined in k5-trace.h as a macro or static inline * function, and is called like so: * * void krb5int_trace(krb5_context context, const char *fmt, ...) * * Arguments may or may not be evaluated, so don't pass argument * expressions with side effects. Tracing support and calls can be * explicitly compiled out with DISABLE_TRACING, but compile-time * support is enabled by default. Tracing calls use a custom * formatter supporting the following format specifications: */ #include "k5-int.h" #include "os-proto.h" #ifndef DISABLE_TRACING static void subfmt(krb5_context context, struct k5buf *buf, const char *fmt, ...); static krb5_boolean buf_is_printable(const char *p, size_t len) { size_t i; for (i = 0; i < len; i++) { if (p[i] < 32 || p[i] > 126) break; } return i == len; } static void buf_add_printable_len(struct k5buf *buf, const char *p, size_t len) { char text[5]; size_t i; if (buf_is_printable(p, len)) { k5_buf_add_len(buf, p, len); } else { for (i = 0; i < len; i++) { if (buf_is_printable(p + i, 1)) { k5_buf_add_len(buf, p + i, 1); } else { snprintf(text, sizeof(text), "\\x%02x", (unsigned)(p[i] & 0xff)); k5_buf_add_len(buf, text, 4); } } } } static void buf_add_printable(struct k5buf *buf, const char *p) { buf_add_printable_len(buf, p, strlen(p)); } /* Return a four-byte hex string from the first two bytes of a SHA-1 hash of a * byte array. Return NULL on failure. */ static char * hash_bytes(krb5_context context, const void *ptr, size_t len) { krb5_checksum cksum; krb5_data d = make_data((void *) ptr, len); char *s = NULL; if (krb5_k_make_checksum(context, CKSUMTYPE_SHA1, NULL, 0, &d, &cksum) != 0) return NULL; if (cksum.length >= 2) (void) asprintf(&s, "%02X%02X", cksum.contents[0], cksum.contents[1]); krb5_free_checksum_contents(context, &cksum); return s; } static char * principal_type_string(krb5_int32 type) { switch (type) { case KRB5_NT_UNKNOWN: return "unknown"; case KRB5_NT_PRINCIPAL: return "principal"; case KRB5_NT_SRV_INST: return "service instance"; case KRB5_NT_SRV_HST: return "service with host as instance"; case KRB5_NT_SRV_XHST: return "service with host as components"; case KRB5_NT_UID: return "unique ID"; case KRB5_NT_X500_PRINCIPAL: return "X.509"; case KRB5_NT_SMTP_NAME: return "SMTP email"; case KRB5_NT_ENTERPRISE_PRINCIPAL: return "Windows 2000 UPN"; case KRB5_NT_WELLKNOWN: return "well-known"; case KRB5_NT_MS_PRINCIPAL: return "Windows 2000 UPN and SID"; case KRB5_NT_MS_PRINCIPAL_AND_ID: return "NT 4 style name"; case KRB5_NT_ENT_PRINCIPAL_AND_ID: return "NT 4 style name and SID"; default: return "?"; } } static char * padata_type_string(krb5_preauthtype type) { switch (type) { case KRB5_PADATA_TGS_REQ: return "PA-TGS-REQ"; case KRB5_PADATA_ENC_TIMESTAMP: return "PA-ENC-TIMESTAMP"; case KRB5_PADATA_PW_SALT: return "PA-PW-SALT"; case KRB5_PADATA_ENC_UNIX_TIME: return "PA-ENC-UNIX-TIME"; case KRB5_PADATA_ENC_SANDIA_SECURID: return "PA-SANDIA-SECUREID"; case KRB5_PADATA_SESAME: return "PA-SESAME"; case KRB5_PADATA_OSF_DCE: return "PA-OSF-DCE"; case KRB5_CYBERSAFE_SECUREID: return "PA-CYBERSAFE-SECUREID"; case KRB5_PADATA_AFS3_SALT: return "PA-AFS3-SALT"; case KRB5_PADATA_ETYPE_INFO: return "PA-ETYPE-INFO"; case KRB5_PADATA_SAM_CHALLENGE: return "PA-SAM-CHALLENGE"; case KRB5_PADATA_SAM_RESPONSE: return "PA-SAM-RESPONSE"; case KRB5_PADATA_PK_AS_REQ_OLD: return "PA-PK-AS-REQ_OLD"; case KRB5_PADATA_PK_AS_REP_OLD: return "PA-PK-AS-REP_OLD"; case KRB5_PADATA_PK_AS_REQ: return "PA-PK-AS-REQ"; case KRB5_PADATA_PK_AS_REP: return "PA-PK-AS-REP"; case KRB5_PADATA_ETYPE_INFO2: return "PA-ETYPE-INFO2"; case KRB5_PADATA_SVR_REFERRAL_INFO: return "PA-SVR-REFERRAL-INFO"; case KRB5_PADATA_SAM_REDIRECT: return "PA-SAM-REDIRECT"; case KRB5_PADATA_GET_FROM_TYPED_DATA: return "PA-GET-FROM-TYPED-DATA"; case KRB5_PADATA_SAM_CHALLENGE_2: return "PA-SAM-CHALLENGE2"; case KRB5_PADATA_SAM_RESPONSE_2: return "PA-SAM-RESPONSE2"; case KRB5_PADATA_PAC_REQUEST: return "PA-PAC-REQUEST"; case KRB5_PADATA_FOR_USER: return "PA-FOR_USER"; case KRB5_PADATA_S4U_X509_USER: return "PA-FOR-X509-USER"; case KRB5_PADATA_AS_CHECKSUM: return "PA-AS-CHECKSUM"; case KRB5_PADATA_FX_COOKIE: return "PA-FX-COOKIE"; case KRB5_PADATA_FX_FAST: return "PA-FX-FAST"; case KRB5_PADATA_FX_ERROR: return "PA-FX-ERROR"; case KRB5_PADATA_ENCRYPTED_CHALLENGE: return "PA-ENCRYPTED-CHALLENGE"; case KRB5_PADATA_OTP_CHALLENGE: return "PA-OTP-CHALLENGE"; case KRB5_PADATA_OTP_REQUEST: return "PA-OTP-REQUEST"; case KRB5_PADATA_OTP_PIN_CHANGE: return "PA-OTP-PIN-CHANGE"; case KRB5_PADATA_PKINIT_KX: return "PA-PKINIT-KX"; case KRB5_ENCPADATA_REQ_ENC_PA_REP: return "PA-REQ-ENC-PA-REP"; case KRB5_PADATA_AS_FRESHNESS: return "PA_AS_FRESHNESS"; case KRB5_PADATA_SPAKE: return "PA-SPAKE"; case KRB5_PADATA_REDHAT_IDP_OAUTH2: return "PA-REDHAT-IDP-OAUTH2"; case KRB5_PADATA_REDHAT_PASSKEY: return "PA-REDHAT-PASSKEY"; default: return NULL; } } static char * trace_format(krb5_context context, const char *fmt, va_list ap) { struct k5buf buf; krb5_error_code kerr; size_t len, i; int err; struct remote_address *ra; const krb5_data *d; krb5_data data; char addrbuf[128], tmpbuf[200], *str; const char *p; krb5_const_principal princ; const krb5_keyblock *keyblock; krb5_key key; const krb5_checksum *cksum; krb5_pa_data **padata; krb5_preauthtype pa_type; const char *name; krb5_ccache ccache; krb5_keytab keytab; krb5_creds *creds; krb5_enctype *etypes, etype; k5_buf_init_dynamic(&buf); while (TRUE) { /* Advance to the next word in braces. */ len = strcspn(fmt, "{"); k5_buf_add_len(&buf, fmt, len); if (fmt[len] == '\0') break; fmt += len + 1; len = strcspn(fmt, "}"); if (fmt[len] == '\0' || len > sizeof(tmpbuf) - 1) break; memcpy(tmpbuf, fmt, len); tmpbuf[len] = '\0'; fmt += len + 1; /* Process the format word. */ if (strcmp(tmpbuf, "int") == 0) { k5_buf_add_fmt(&buf, "%d", va_arg(ap, int)); } else if (strcmp(tmpbuf, "long") == 0) { k5_buf_add_fmt(&buf, "%ld", va_arg(ap, long)); } else if (strcmp(tmpbuf, "str") == 0) { p = va_arg(ap, const char *); buf_add_printable(&buf, (p == NULL) ? "(null)" : p); } else if (strcmp(tmpbuf, "lenstr") == 0) { len = va_arg(ap, size_t); p = va_arg(ap, const char *); if (p == NULL && len != 0) k5_buf_add(&buf, "(null)"); else if (p != NULL) buf_add_printable_len(&buf, p, len); } else if (strcmp(tmpbuf, "hexlenstr") == 0) { len = va_arg(ap, size_t); p = va_arg(ap, const char *); if (p == NULL && len != 0) k5_buf_add(&buf, "(null)"); else { for (i = 0; i < len; i++) k5_buf_add_fmt(&buf, "%02X", (unsigned char)p[i]); } } else if (strcmp(tmpbuf, "hashlenstr") == 0) { len = va_arg(ap, size_t); p = va_arg(ap, const char *); if (p == NULL && len != 0) k5_buf_add(&buf, "(null)"); else { str = hash_bytes(context, p, len); if (str != NULL) k5_buf_add(&buf, str); free(str); } } else if (strcmp(tmpbuf, "raddr") == 0) { ra = va_arg(ap, struct remote_address *); if (ra->transport == UDP) k5_buf_add(&buf, "dgram"); else if (ra->transport == TCP) k5_buf_add(&buf, "stream"); else if (ra->transport == HTTPS) k5_buf_add(&buf, "https"); else if (ra->transport == UNIXSOCK) k5_buf_add(&buf, "UNIX domain socket"); else k5_buf_add_fmt(&buf, "transport%d", ra->transport); k5_print_addr_port(ss2sa(&ra->saddr), addrbuf, sizeof(addrbuf)); k5_buf_add_fmt(&buf, " %s", addrbuf); } else if (strcmp(tmpbuf, "data") == 0) { d = va_arg(ap, krb5_data *); if (d == NULL || (d->length != 0 && d->data == NULL)) k5_buf_add(&buf, "(null)"); else buf_add_printable_len(&buf, d->data, d->length); } else if (strcmp(tmpbuf, "hexdata") == 0) { d = va_arg(ap, krb5_data *); if (d == NULL) k5_buf_add(&buf, "(null)"); else subfmt(context, &buf, "{hexlenstr}", d->length, d->data); } else if (strcmp(tmpbuf, "errno") == 0) { err = va_arg(ap, int); k5_buf_add_fmt(&buf, "%d", err); if (strerror_r(err, tmpbuf, sizeof(tmpbuf)) == 0) k5_buf_add_fmt(&buf, "/%s", tmpbuf); } else if (strcmp(tmpbuf, "kerr") == 0) { kerr = va_arg(ap, krb5_error_code); p = krb5_get_error_message(context, kerr); k5_buf_add_fmt(&buf, "%ld/%s", (long)kerr, kerr ? p : "Success"); krb5_free_error_message(context, p); } else if (strcmp(tmpbuf, "keyblock") == 0) { keyblock = va_arg(ap, const krb5_keyblock *); if (keyblock == NULL) k5_buf_add(&buf, "(null)"); else { subfmt(context, &buf, "{etype}/{hashlenstr}", keyblock->enctype, keyblock->length, keyblock->contents); } } else if (strcmp(tmpbuf, "key") == 0) { key = va_arg(ap, krb5_key); if (key == NULL) k5_buf_add(&buf, "(null)"); else subfmt(context, &buf, "{keyblock}", &key->keyblock); } else if (strcmp(tmpbuf, "cksum") == 0) { cksum = va_arg(ap, const krb5_checksum *); data = make_data(cksum->contents, cksum->length); subfmt(context, &buf, "{int}/{hexdata}", (int) cksum->checksum_type, &data); } else if (strcmp(tmpbuf, "princ") == 0) { princ = va_arg(ap, krb5_principal); if (krb5_unparse_name(context, princ, &str) == 0) { k5_buf_add(&buf, str); krb5_free_unparsed_name(context, str); } } else if (strcmp(tmpbuf, "ptype") == 0) { p = principal_type_string(va_arg(ap, krb5_int32)); k5_buf_add(&buf, p); } else if (strcmp(tmpbuf, "patypes") == 0) { padata = va_arg(ap, krb5_pa_data **); if (padata == NULL || *padata == NULL) k5_buf_add(&buf, "(empty)"); for (; padata != NULL && *padata != NULL; padata++) { pa_type = (*padata)->pa_type; name = padata_type_string(pa_type); if (name != NULL) k5_buf_add_fmt(&buf, "%s (%d)", name, (int)pa_type); else k5_buf_add_fmt(&buf, "%d", (int)pa_type); if (*(padata + 1) != NULL) k5_buf_add(&buf, ", "); } } else if (strcmp(tmpbuf, "patype") == 0) { pa_type = va_arg(ap, krb5_preauthtype); name = padata_type_string(pa_type); if (name != NULL) k5_buf_add_fmt(&buf, "%s (%d)", name, (int)pa_type); else k5_buf_add_fmt(&buf, "%d", (int)pa_type); } else if (strcmp(tmpbuf, "etype") == 0) { etype = va_arg(ap, krb5_enctype); if (krb5_enctype_to_name(etype, TRUE, tmpbuf, sizeof(tmpbuf)) == 0) k5_buf_add(&buf, tmpbuf); else k5_buf_add_fmt(&buf, "%d", (int)etype); } else if (strcmp(tmpbuf, "etypes") == 0) { etypes = va_arg(ap, krb5_enctype *); if (etypes == NULL || *etypes == 0) k5_buf_add(&buf, "(empty)"); for (; etypes != NULL && *etypes != 0; etypes++) { subfmt(context, &buf, "{etype}", *etypes); if (*(etypes + 1) != 0) k5_buf_add(&buf, ", "); } } else if (strcmp(tmpbuf, "ccache") == 0) { ccache = va_arg(ap, krb5_ccache); k5_buf_add(&buf, krb5_cc_get_type(context, ccache)); k5_buf_add(&buf, ":"); k5_buf_add(&buf, krb5_cc_get_name(context, ccache)); } else if (strcmp(tmpbuf, "keytab") == 0) { keytab = va_arg(ap, krb5_keytab); if (krb5_kt_get_name(context, keytab, tmpbuf, sizeof(tmpbuf)) == 0) k5_buf_add(&buf, tmpbuf); } else if (strcmp(tmpbuf, "creds") == 0) { creds = va_arg(ap, krb5_creds *); subfmt(context, &buf, "{princ} -> {princ}", creds->client, creds->server); } } return k5_buf_cstring(&buf); } /* Allows trace_format formatters to be represented in terms of other * formatters. */ static void subfmt(krb5_context context, struct k5buf *buf, const char *fmt, ...) { va_list ap; char *str; va_start(ap, fmt); str = trace_format(context, fmt, ap); if (str != NULL) k5_buf_add(buf, str); free(str); va_end(ap); } void k5_init_trace(krb5_context context) { const char *filename; filename = secure_getenv("KRB5_TRACE"); if (filename) (void) krb5_set_trace_filename(context, filename); } void krb5int_trace(krb5_context context, const char *fmt, ...) { va_list ap; krb5_trace_info info; char *str = NULL, *msg = NULL; krb5_timestamp sec; krb5_int32 usec; if (context == NULL || context->trace_callback == NULL) return; va_start(ap, fmt); str = trace_format(context, fmt, ap); if (str == NULL) goto cleanup; if (k5_us_timeofday(&sec, &usec) != 0) goto cleanup; if (asprintf(&msg, "[%d] %u.%06d: %s\n", (int)getpid(), (unsigned int)sec, (int)usec, str) < 0) goto cleanup; info.message = msg; context->trace_callback(context, &info, context->trace_callback_data); cleanup: free(str); free(msg); va_end(ap); } krb5_error_code KRB5_CALLCONV krb5_set_trace_callback(krb5_context context, krb5_trace_callback fn, void *cb_data) { /* Allow the old callback to destroy its data if necessary. */ if (context->trace_callback != NULL) context->trace_callback(context, NULL, context->trace_callback_data); context->trace_callback = fn; context->trace_callback_data = cb_data; return 0; } static void KRB5_CALLCONV file_trace_cb(krb5_context context, const krb5_trace_info *info, void *data) { int *fd = data; if (info == NULL) { /* Null info means destroy the callback data. */ close(*fd); free(fd); return; } (void) write(*fd, info->message, strlen(info->message)); } krb5_error_code KRB5_CALLCONV krb5_set_trace_filename(krb5_context context, const char *filename) { int *fd; /* Create callback data containing a file descriptor. */ fd = malloc(sizeof(*fd)); if (fd == NULL) return ENOMEM; *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); if (*fd == -1) { free(fd); return errno; } return krb5_set_trace_callback(context, file_trace_cb, fd); } #else /* DISABLE_TRACING */ krb5_error_code KRB5_CALLCONV krb5_set_trace_callback(krb5_context context, krb5_trace_callback fn, void *cb_data) { if (fn == NULL) return 0; return KRB5_TRACE_NOSUPP; } krb5_error_code KRB5_CALLCONV krb5_set_trace_filename(krb5_context context, const char *filename) { return KRB5_TRACE_NOSUPP; } #endif /* DISABLE_TRACING */ krb5-1.22.1/src/lib/krb5/os/t_expand_path.c0000664000175000017500000000054115051422640020144 0ustar ghudsonghudson#include "k5-int.h" #include "os-proto.h" int main(int argc, char **argv) { char *path; if (k5_expand_path_tokens_extra(NULL, argv[1], &path, "animal", "frog", "place", "pad", "s", "s", NULL) != 0) return 2; if (argc == 2) printf("%s\n", path); else if (strcmp(path, argv[2]) != 0) return 1; free(path); return 0; } krb5-1.22.1/src/lib/krb5/os/Makefile.in0000664000175000017500000001710315051422640017231 0ustar ghudsonghudsonmydir=lib$(S)krb5$(S)os BUILDTOP=$(REL)..$(S)..$(S).. DEFINES=-DLIBDIR=\"$(KRB5_LIBDIR)\" -DBINDIR=\"$(CLIENT_BINDIR)\" \ -DSBINDIR=\"$(ADMIN_BINDIR)\" # Like RUN_TEST, but use td_krb5.conf from this directory. RUN_TEST_LOCAL_CONF=$(RUN_SETUP) KRB5_CONFIG=$(srcdir)/td_krb5.conf LC_ALL=C \ $(VALGRIND) ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=os ##DOS##OBJFILE=..\$(OUTPRE)$(PREFIXDIR).lst STLIBOBJS= \ accessor.o \ addr.o \ c_ustime.o \ ccdefname.o \ changepw.o \ dnsglue.o \ dnssrv.o \ expand_path.o \ full_ipadr.o \ gen_port.o \ genaddrs.o \ gen_rname.o \ hostaddr.o \ hostrealm.o \ hostrealm_dns.o \ hostrealm_domain.o \ hostrealm_profile.o \ hostrealm_registry.o \ init_os_ctx.o \ krbfileio.o \ ktdefname.o \ mk_faddr.o \ localaddr.o \ localauth.o \ localauth_an2ln.o \ localauth_k5login.o \ localauth_names.o \ localauth_rule.o \ locate_kdc.o \ lock_file.o \ net_read.o \ net_write.o \ port2ip.o \ prompter.o \ read_msg.o \ read_pwd.o \ realm_dom.o \ sendto_kdc.o \ sn2princ.o \ thread_safe.o \ timeofday.o \ toffset.o \ trace.o \ unlck_file.o \ ustime.o \ write_msg.o OBJS= \ $(OUTPRE)accessor.$(OBJEXT) \ $(OUTPRE)addr.$(OBJEXT) \ $(OUTPRE)c_ustime.$(OBJEXT) \ $(OUTPRE)ccdefname.$(OBJEXT) \ $(OUTPRE)changepw.$(OBJEXT) \ $(OUTPRE)dnsglue.$(OBJEXT) \ $(OUTPRE)dnssrv.$(OBJEXT) \ $(OUTPRE)expand_path.$(OBJEXT) \ $(OUTPRE)full_ipadr.$(OBJEXT) \ $(OUTPRE)gen_port.$(OBJEXT) \ $(OUTPRE)genaddrs.$(OBJEXT) \ $(OUTPRE)gen_rname.$(OBJEXT) \ $(OUTPRE)hostaddr.$(OBJEXT) \ $(OUTPRE)hostrealm.$(OBJEXT) \ $(OUTPRE)hostrealm_dns.$(OBJEXT) \ $(OUTPRE)hostrealm_domain.$(OBJEXT) \ $(OUTPRE)hostrealm_profile.$(OBJEXT) \ $(OUTPRE)hostrealm_registry.$(OBJEXT) \ $(OUTPRE)init_os_ctx.$(OBJEXT) \ $(OUTPRE)krbfileio.$(OBJEXT) \ $(OUTPRE)ktdefname.$(OBJEXT) \ $(OUTPRE)mk_faddr.$(OBJEXT) \ $(OUTPRE)localaddr.$(OBJEXT) \ $(OUTPRE)localauth.$(OBJEXT) \ $(OUTPRE)localauth_an2ln.$(OBJEXT) \ $(OUTPRE)localauth_k5login.$(OBJEXT) \ $(OUTPRE)localauth_names.$(OBJEXT) \ $(OUTPRE)localauth_rule.$(OBJEXT) \ $(OUTPRE)locate_kdc.$(OBJEXT) \ $(OUTPRE)lock_file.$(OBJEXT) \ $(OUTPRE)net_read.$(OBJEXT) \ $(OUTPRE)net_write.$(OBJEXT) \ $(OUTPRE)port2ip.$(OBJEXT) \ $(OUTPRE)prompter.$(OBJEXT) \ $(OUTPRE)read_msg.$(OBJEXT) \ $(OUTPRE)read_pwd.$(OBJEXT) \ $(OUTPRE)realm_dom.$(OBJEXT) \ $(OUTPRE)sendto_kdc.$(OBJEXT) \ $(OUTPRE)sn2princ.$(OBJEXT) \ $(OUTPRE)thread_safe.$(OBJEXT) \ $(OUTPRE)timeofday.$(OBJEXT) \ $(OUTPRE)toffset.$(OBJEXT) \ $(OUTPRE)trace.$(OBJEXT) \ $(OUTPRE)unlck_file.$(OBJEXT) \ $(OUTPRE)ustime.$(OBJEXT) \ $(OUTPRE)write_msg.$(OBJEXT) SRCS= \ $(srcdir)/accessor.c \ $(srcdir)/addr.c \ $(srcdir)/c_ustime.c \ $(srcdir)/ccdefname.c \ $(srcdir)/changepw.c \ $(srcdir)/dnsglue.c \ $(srcdir)/dnssrv.c \ $(srcdir)/expand_path.c \ $(srcdir)/full_ipadr.c \ $(srcdir)/gen_port.c \ $(srcdir)/genaddrs.c \ $(srcdir)/gen_rname.c \ $(srcdir)/hostaddr.c \ $(srcdir)/hostrealm.c \ $(srcdir)/hostrealm_dns.c \ $(srcdir)/hostrealm_domain.c \ $(srcdir)/hostrealm_profile.c \ $(srcdir)/hostrealm_registry.c \ $(srcdir)/init_os_ctx.c \ $(srcdir)/krbfileio.c \ $(srcdir)/ktdefname.c \ $(srcdir)/mk_faddr.c \ $(srcdir)/localaddr.c \ $(srcdir)/localauth.c \ $(srcdir)/localauth_an2ln.c \ $(srcdir)/localauth_k5login.c \ $(srcdir)/localauth_names.c \ $(srcdir)/localauth_rule.c \ $(srcdir)/locate_kdc.c \ $(srcdir)/lock_file.c \ $(srcdir)/net_read.c \ $(srcdir)/net_write.c \ $(srcdir)/prompter.c \ $(srcdir)/read_msg.c \ $(srcdir)/read_pwd.c \ $(srcdir)/realm_dom.c \ $(srcdir)/port2ip.c \ $(srcdir)/sendto_kdc.c \ $(srcdir)/sn2princ.c \ $(srcdir)/thread_safe.c \ $(srcdir)/timeofday.c \ $(srcdir)/toffset.c \ $(srcdir)/trace.c \ $(srcdir)/unlck_file.c \ $(srcdir)/ustime.c \ $(srcdir)/write_msg.c EXTRADEPSRCS = \ t_ctxprf.c t_expand_path.c t_gifconf.c t_locate_kdc.c t_std_conf.c \ t_trace.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs clean-unix:: clean-libobjs shared: mkdir shared TEST_PROGS= t_std_conf t_locate_kdc t_trace t_expand_path t_ctxprf T_STD_CONF_OBJS= t_std_conf.o T_TRACE_OBJS = t_trace.o t_std_conf: $(T_STD_CONF_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_std_conf $(T_STD_CONF_OBJS) $(KRB5_BASE_LIBS) t_localaddr: localaddr.c $(CC_LINK) $(ALL_CFLAGS) -DTEST -o t_localaddr $(srcdir)/localaddr.c $(KRB5_BASE_LIBS) $(LIBS) t_locate_kdc: t_locate_kdc.o $(CC_LINK) $(ALL_CFLAGS) -o t_locate_kdc t_locate_kdc.o \ $(KRB5_BASE_LIBS) t_locate_kdc.o: t_locate_kdc.c locate_kdc.c dnssrv.c dnsglue.c $(OUTPRE)t_locate_kdc.exe: $(OUTPRE)t_locate_kdc.obj \ $(KLIB) $(PLIB) $(CLIB) $(SLIB) link $(EXE_LINKOPTS) -out:$@ $** ws2_32.lib t_trace: $(T_TRACE_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_trace $(T_TRACE_OBJS) $(KRB5_BASE_LIBS) t_expand_path: t_expand_path.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_expand_path.o $(KRB5_BASE_LIBS) t_ctxprf: t_ctxprf.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_ctxprf.o $(KRB5_BASE_LIBS) LCLINT=lclint LCLINTOPTS= -warnposix \ -usedef +charintliteral +ignoresigns -predboolint +boolint \ -exportlocal -retvalint \ +mod-uncon +modinternalstrict +modfilesys lclint-localaddr: localaddr.c $(LCLINT) $(LCLINTOPTS) $(CPPFLAGS) $(LOCALINCLUDES) $(DEFS) \ -DTEST $(srcdir)/localaddr.c check-unix: check-unix-stdconf check-unix-locate check-unix-trace \ check-unix-expand check-unix-uri check-unix-ctxprf check-unix-stdconf: t_std_conf $(RUN_TEST_LOCAL_CONF) ./t_std_conf -d -s NEW.DEFAULT.REALM -d \ -D DEFAULT_REALM.TST -r bad.idea -r itar.bad.idea \ -r really.BAD.IDEA. -r clipper.bad.idea -r KeYEsCrOW.BaD.IDea \ -r pgp.good.idea -r no_domain > test.out cmp test.out $(srcdir)/ref_std_conf.out $(RM) test.out # The following can be overriden on the make command line if needed: LOCREALM = ATHENA.MIT.EDU SRVNAME = _kerberos._udp.athena.mit.edu. DIGPAT = '^_kerberos.*srv' NSPAT = '^_kerberos.*service' DIG = @DIG@ NSLOOKUP = @NSLOOKUP@ check-unix-locate: t_locate_kdc if [ "$(OFFLINE)" = no ]; then \ if $(DIG) $(SRVNAME) srv | grep -i $(DIGPAT) || \ $(NSLOOKUP) -q=srv $(SRVNAME) | grep -i $(NSPAT); then \ $(RUN_TEST) ./t_locate_kdc $(LOCREALM); \ else \ echo '*** WARNING: skipped t_locate_kdc test: known DNS name not found'; \ echo 'Skipped t_locate_kdc test: known DNS name not found' >> $(SKIPTESTS); \ fi; \ else \ echo '*** WARNING: skipped t_locate_kdc test: OFFLINE'; \ echo 'Skipped t_locate_kdc test: OFFLINE' >> $(SKIPTESTS); \ fi ASAN = @ASAN@ check-unix-uri: t_locate_kdc if [ $(HAVE_RESOLV_WRAPPER) = 0 ]; then \ echo '*** WARNING: skipped t_discover_uri.py due to not using resolv_wrapper'; \ echo 'Skipped URI discovery tests: resolv_wrapper 1.1.5 not found' >> $(SKIPTESTS); \ elif [ $(ASAN) = yes ]; then \ echo '*** Skipping URI discovery tests: resolv_wrapper is incompatible with asan'; \ echo 'Skipped URI discovery tests: incompatible with asan' >> $(SKIPTESTS); \ else \ $(RUNPYTEST) $(srcdir)/t_discover_uri.py $(PYTESTFLAGS); \ fi check-unix-trace: t_trace rm -f t_trace.out KRB5_TRACE=t_trace.out ; export KRB5_TRACE ; \ $(RUN_TEST) ./t_trace sed -e 's/^[^:]*: //' t_trace.out | cmp - $(srcdir)/t_trace.ref rm -f t_trace.out check-unix-expand: t_expand_path $(RUN_TEST) ./t_expand_path '%{null}' '' $(RUN_TEST) ./t_expand_path ' %{BINDIR}%{LIBDIR} ' \ ' $(CLIENT_BINDIR)$(KRB5_LIBDIR) ' $(RUN_TEST) ./t_expand_path \ 'the %{animal}%{s} on the %{place}%{s}' \ 'the frogs on the pads' check-unix-ctxprf: t_ctxprf $(RUNPYTEST) $(srcdir)/t_ctxprf.py $(PYTESTFLAGS) clean: $(RM) $(TEST_PROGS) test.out t_std_conf.o t_locate_kdc.o t_trace.o $(RM) t_expand_path.o t_ctxprf.o @libobj_frag@ krb5-1.22.1/src/lib/krb5/os/localaddr.c0000664000175000017500000013140515051422640017257 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/localaddr.c */ /* * Copyright 1990,1991,2000,2001,2002,2004,2007,2008 by the Massachusetts * Institute of Technology. All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Return the protocol addresses supported by this host. * Exports from this file: * krb5int_foreach_localaddr (does callbacks) * krb5_os_localaddr (doesn't include krb5.conf extra_addresses) * * XNS support is untested, but "Should just work". (Hah!) */ #include "k5-int.h" #include "os-proto.h" #if !defined(_WIN32) /* needed for solaris, harmless elsewhere... */ #define BSD_COMP #include #include #include #include #include #if defined(TEST) || defined(DEBUG) # include "fake-addrinfo.h" #endif #include "foreachaddr.h" /* Note: foreach_localaddr is exported from the library through krb5int_accessor, for the KDC to use. This function iterates over all the addresses it can find for the local system, in one or two passes. In each pass, and between the two, it can invoke callback functions supplied by the caller. The two passes should operate on the same information, though not necessarily in the same order each time. Duplicate and local addresses should be eliminated. Storage passed to callback functions should not be assumed to be valid after foreach_localaddr returns. The int return value is an errno value (XXX or krb5_error_code returned for a socket error) if something internal to foreach_localaddr fails. If one of the callback functions wants to indicate an error, it should store something via the 'data' handle. If any callback function returns a non-zero value, foreach_localaddr will clean up and return immediately. Multiple definitions are provided below, dependent on various system facilities for extracting the necessary information. */ /* Now, on to the implementations, and heaps of debugging code. */ #ifdef TEST # define Tprintf(X) printf X # define Tperror(X) perror(X) #else # define Tprintf(X) (void) X # define Tperror(X) (void)(X) #endif /* * The SIOCGIF* ioctls require a socket. * It doesn't matter *what* kind of socket they use, but it has to be * a socket. * * Of course, you can't just ask the kernel for a socket of arbitrary * type; you have to ask for one with a valid type. * */ #ifdef HAVE_NETINET_IN_H #include #ifndef USE_AF #define USE_AF AF_INET #define USE_TYPE SOCK_DGRAM #define USE_PROTO 0 #endif #endif #ifdef KRB5_USE_NS #include #ifndef USE_AF #define USE_AF AF_NS #define USE_TYPE SOCK_DGRAM #define USE_PROTO 0 /* guess */ #endif #endif /* * Add more address families here. */ #if defined(__linux__) && !defined(HAVE_IFADDRS_H) #define LINUX_IPV6_HACK #endif #include /* * Return all the protocol addresses of this host. * * We could kludge up something to return all addresses, assuming that * they're valid kerberos protocol addresses, but we wouldn't know the * real size of the sockaddr or know which part of it was actually the * host part. * * This uses the SIOCGIFCONF, SIOCGIFFLAGS, and SIOCGIFADDR ioctl's. */ /* * BSD 4.4 defines the size of an ifreq to be * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len * However, under earlier systems, sa_len isn't present, so the size is * just sizeof(struct ifreq). */ #ifdef HAVE_SA_LEN #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif #define ifreq_size(i) max(sizeof(struct ifreq), \ sizeof((i).ifr_name)+(i).ifr_addr.sa_len) #else #define ifreq_size(i) sizeof(struct ifreq) #endif /* HAVE_SA_LEN*/ #if defined(DEBUG) || defined(TEST) #include #include #include "socket-utils.h" #include "fake-addrinfo.h" void printaddr (struct sockaddr *); void printaddr(struct sockaddr *sa) /*@modifies fileSystem@*/ { char buf[NI_MAXHOST]; int err; printf ("%p ", (void *) sa); err = getnameinfo (sa, sa_socklen (sa), buf, sizeof (buf), 0, 0, NI_NUMERICHOST); if (err) printf (" family=%d", err, gai_strerror (err), sa->sa_family); else printf ("%s", buf); } #endif static int is_loopback_address(struct sockaddr *sa) { switch (sa->sa_family) { case AF_INET: return sa2sin(sa)->sin_addr.s_addr == htonl(INADDR_LOOPBACK); case AF_INET6: return IN6_IS_ADDR_LOOPBACK(&sa2sin6(sa)->sin6_addr); default: return 0; } } #ifdef HAVE_IFADDRS_H #include #ifdef DEBUG void printifaddr(struct ifaddrs *ifp) { printf ("%p={\n", ifp); /* printf ("\tnext=%p\n", ifp->ifa_next); */ printf ("\tname=%s\n", ifp->ifa_name); printf ("\tflags="); { int ch, flags = ifp->ifa_flags; printf ("%x", flags); ch = '<'; #define X(F) if (flags & IFF_##F) { printf ("%c%s", ch, #F); flags &= ~IFF_##F; ch = ','; } X (UP); X (BROADCAST); X (DEBUG); X (LOOPBACK); X (POINTOPOINT); X (NOTRAILERS); X (RUNNING); X (NOARP); X (PROMISC); X (ALLMULTI); #ifdef IFF_OACTIVE X (OACTIVE); #endif #ifdef IFF_SIMPLE X (SIMPLEX); #endif X (MULTICAST); printf (">"); #undef X } if (ifp->ifa_addr) printf ("\n\taddr="), printaddr (ifp->ifa_addr); if (ifp->ifa_netmask) printf ("\n\tnetmask="), printaddr (ifp->ifa_netmask); if (ifp->ifa_broadaddr) printf ("\n\tbroadaddr="), printaddr (ifp->ifa_broadaddr); if (ifp->ifa_dstaddr) printf ("\n\tdstaddr="), printaddr (ifp->ifa_dstaddr); if (ifp->ifa_data) printf ("\n\tdata=%p", ifp->ifa_data); printf ("\n}\n"); } #endif /* DEBUG */ #include #include static int addr_eq (struct sockaddr *s1, struct sockaddr *s2) { if (s1->sa_family != s2->sa_family) return 0; switch (s1->sa_family) { case AF_INET: return !memcmp(&sa2sin(s1)->sin_addr, &sa2sin(s2)->sin_addr, sizeof(sa2sin(s1)->sin_addr)); case AF_INET6: return !memcmp(&sa2sin6(s1)->sin6_addr, &sa2sin6(s2)->sin6_addr, sizeof(sa2sin6(s1)->sin6_addr)); default: /* Err on side of duplicate listings. */ return 0; } } #endif #ifndef HAVE_IFADDRS_H /*@-usereleased@*/ /* lclint doesn't understand realloc */ static /*@null@*/ void * grow_or_free (/*@only@*/ void *ptr, size_t newsize) /*@*/ { void *newptr; newptr = realloc (ptr, newsize); if (newptr == NULL && newsize != 0) { free (ptr); /* lclint complains but this is right */ return NULL; } return newptr; } /*@=usereleased@*/ static int get_ifconf (int s, size_t *lenp, /*@out@*/ char *buf) /*@modifies *buf,*lenp@*/ { int ret; struct ifconf ifc; /*@+matchanyintegral@*/ ifc.ifc_len = *lenp; /*@=matchanyintegral@*/ ifc.ifc_buf = buf; memset(buf, 0, *lenp); /*@-moduncon@*/ ret = ioctl (s, SIOCGIFCONF, (char *)&ifc); /*@=moduncon@*/ /*@+matchanyintegral@*/ *lenp = ifc.ifc_len; /*@=matchanyintegral@*/ return ret; } /* Solaris uses SIOCGLIFCONF to return struct lifconf which is just an extended version of struct ifconf. HP-UX 11 also appears to have SIOCGLIFCONF, but uses struct if_laddrconf, and struct if_laddrreq to be used with SIOCGLIFADDR. */ #if defined(SIOCGLIFCONF) && defined(HAVE_STRUCT_LIFCONF) static int get_lifconf (int af, int s, size_t *lenp, /*@out@*/ char *buf) /*@modifies *buf,*lenp@*/ { int ret; struct lifconf lifc; lifc.lifc_family = af; lifc.lifc_flags = 0; /*@+matchanyintegral@*/ lifc.lifc_len = *lenp; /*@=matchanyintegral@*/ lifc.lifc_buf = buf; memset(buf, 0, *lenp); /*@-moduncon@*/ ret = ioctl (s, SIOCGLIFCONF, (char *)&lifc); if (ret) Tperror ("SIOCGLIFCONF"); /*@=moduncon@*/ /*@+matchanyintegral@*/ *lenp = lifc.lifc_len; /*@=matchanyintegral@*/ return ret; } #endif #if defined(SIOCGLIFCONF) && defined(HAVE_STRUCT_IF_LADDRCONF) && 0 /* I'm not sure if this is needed or if net/if.h will pull it in. */ /* #include */ static int get_if_laddrconf (int af, int s, size_t *lenp, /*@out@*/ char *buf) /*@modifies *buf,*lenp@*/ { int ret; struct if_laddrconf iflc; /*@+matchanyintegral@*/ iflc.iflc_len = *lenp; /*@=matchanyintegral@*/ iflc.iflc_buf = buf; memset(buf, 0, *lenp); /*@-moduncon@*/ ret = ioctl (s, SIOCGLIFCONF, (char *)&iflc); if (ret) Tperror ("SIOCGLIFCONF"); /*@=moduncon@*/ /*@+matchanyintegral@*/ *lenp = iflc.iflc_len; /*@=matchanyintegral@*/ return ret; } #endif #endif /* ! HAVE_IFADDRS_H */ #ifdef LINUX_IPV6_HACK #include /* Read IPv6 addresses out of /proc/net/if_inet6, since there isn't (currently) any ioctl to return them. */ struct linux_ipv6_addr_list { struct sockaddr_in6 addr; struct linux_ipv6_addr_list *next; }; static struct linux_ipv6_addr_list * get_linux_ipv6_addrs (void) { struct linux_ipv6_addr_list *lst = 0; FILE *f; /* _PATH_PROCNET_IFINET6 */ f = fopen("/proc/net/if_inet6", "r"); if (f) { char ifname[21]; unsigned int idx, pfxlen, scope, dadstat; struct in6_addr a6; struct linux_ipv6_addr_list *nw; int i; unsigned int addrbyte[16]; set_cloexec_file(f); while (fscanf(f, "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x" " %2x %2x %2x %2x %20s\n", &addrbyte[0], &addrbyte[1], &addrbyte[2], &addrbyte[3], &addrbyte[4], &addrbyte[5], &addrbyte[6], &addrbyte[7], &addrbyte[8], &addrbyte[9], &addrbyte[10], &addrbyte[11], &addrbyte[12], &addrbyte[13], &addrbyte[14], &addrbyte[15], &idx, &pfxlen, &scope, &dadstat, ifname) != EOF) { for (i = 0; i < 16; i++) a6.s6_addr[i] = addrbyte[i]; if (scope != 0) continue; nw = calloc (1, sizeof (struct linux_ipv6_addr_list)); if (nw == 0) continue; nw->addr.sin6_addr = a6; nw->addr.sin6_family = AF_INET6; /* Ignore other fields, we don't actually use them here. */ nw->next = lst; lst = nw; } fclose (f); } return lst; } #endif /* Return value is errno if internal stuff failed, otherwise zero, even in the case where a called function terminated the iteration. If one of the callback functions wants to pass back an error indication, it should do it via some field pointed to by the DATA argument. */ #ifdef HAVE_IFADDRS_H int foreach_localaddr (/*@null@*/ void *data, int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/, /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/, /*@null@*/ int (*pass2fn) (/*@null@*/ void *, struct sockaddr *) /*@*/) #if defined(DEBUG) || defined(TEST) /*@modifies fileSystem@*/ #endif { struct ifaddrs *ifp_head, *ifp, *ifp2; int match; if (getifaddrs (&ifp_head) < 0) return errno; for (ifp = ifp_head; ifp; ifp = ifp->ifa_next) { #ifdef DEBUG printifaddr (ifp); #endif if ((ifp->ifa_flags & IFF_UP) == 0) continue; if (ifp->ifa_addr == NULL) { /* Can't use an interface without an address. Linux apparently does this sometimes. [RT ticket 1770 from Maurice Massar, also Debian bug 206851, shows the problem with a PPP link on a newer kernel than I'm running.] Pretend it's not up, so the second pass will skip it. */ ifp->ifa_flags &= ~IFF_UP; continue; } if (is_loopback_address(ifp->ifa_addr)) { /* Pretend it's not up, so the second pass will skip it. */ ifp->ifa_flags &= ~IFF_UP; continue; } /* If this address is a duplicate, punt. */ match = 0; for (ifp2 = ifp_head; ifp2 && ifp2 != ifp; ifp2 = ifp2->ifa_next) { if ((ifp2->ifa_flags & IFF_UP) == 0) continue; if (addr_eq (ifp->ifa_addr, ifp2->ifa_addr)) { match = 1; ifp->ifa_flags &= ~IFF_UP; break; } } if (match) continue; if ((*pass1fn) (data, ifp->ifa_addr)) goto punt; } if (betweenfn && (*betweenfn)(data)) goto punt; if (pass2fn) for (ifp = ifp_head; ifp; ifp = ifp->ifa_next) { if (ifp->ifa_flags & IFF_UP) if ((*pass2fn) (data, ifp->ifa_addr)) goto punt; } punt: freeifaddrs (ifp_head); return 0; } #elif defined (SIOCGLIFNUM) && defined(HAVE_STRUCT_LIFCONF) /* Solaris 8 and later; Sol 7? */ int foreach_localaddr (/*@null@*/ void *data, int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/, /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/, /*@null@*/ int (*pass2fn) (/*@null@*/ void *, struct sockaddr *) /*@*/) #if defined(DEBUG) || defined(TEST) /*@modifies fileSystem@*/ #endif { /* Okay, this is kind of odd. We have to use each of the address families we care about, because with an AF_INET socket, extra interfaces like hme0:1 that have only AF_INET6 addresses will cause errors. Similarly, if hme0 has more AF_INET addresses than AF_INET6 addresses, we won't be able to retrieve all of the AF_INET addresses if we use an AF_INET6 socket. Since neither family is guaranteed to have the greater number of addresses, we should use both. If it weren't for this little quirk, we could use one socket of any type, and ask for addresses of all types. At least, it seems to work that way. */ static const int afs[] = { AF_INET, AF_NS, AF_INET6 }; #define N_AFS (sizeof (afs) / sizeof (afs[0])) struct { int af; int sock; void *buf; size_t buf_size; struct lifnum lifnum; } afp[N_AFS]; int code, i, j; int retval = 0, afidx; krb5_error_code sock_err = 0; struct lifreq *lifr, lifreq, *lifr2; #define FOREACH_AF() for (afidx = 0; afidx < N_AFS; afidx++) #define P (afp[afidx]) /* init */ FOREACH_AF () { P.af = afs[afidx]; P.sock = -1; P.buf = 0; } /* first pass: get raw data, discard uninteresting addresses, callback */ FOREACH_AF () { Tprintf (("trying af %d...\n", P.af)); P.sock = socket (P.af, USE_TYPE, USE_PROTO); if (P.sock < 0) { sock_err = SOCKET_ERROR; Tperror ("socket"); continue; } set_cloexec_fd(P.sock); P.lifnum.lifn_family = P.af; P.lifnum.lifn_flags = 0; P.lifnum.lifn_count = 0; code = ioctl (P.sock, SIOCGLIFNUM, &P.lifnum); if (code) { Tperror ("ioctl(SIOCGLIFNUM)"); retval = errno; goto punt; } P.buf_size = P.lifnum.lifn_count * sizeof (struct lifreq) * 2; P.buf = malloc (P.buf_size); if (P.buf == NULL) { retval = ENOMEM; goto punt; } code = get_lifconf (P.af, P.sock, &P.buf_size, P.buf); if (code < 0) { retval = errno; goto punt; } for (i = 0; i + sizeof(*lifr) <= P.buf_size; i+= sizeof (*lifr)) { lifr = (struct lifreq *)((caddr_t) P.buf+i); strncpy(lifreq.lifr_name, lifr->lifr_name, sizeof (lifreq.lifr_name)); Tprintf (("interface %s\n", lifreq.lifr_name)); /*@-moduncon@*/ /* ioctl unknown to lclint */ if (ioctl (P.sock, SIOCGLIFFLAGS, (char *)&lifreq) < 0) { Tperror ("ioctl(SIOCGLIFFLAGS)"); skip: /* mark for next pass */ lifr->lifr_name[0] = '\0'; continue; } /*@=moduncon@*/ /* None of the current callers want loopback addresses. */ if (is_loopback_address((struct sockaddr *)&lifr->lifr_addr)) { Tprintf ((" loopback\n")); goto skip; } /* Ignore interfaces that are down. */ if ((lifreq.lifr_flags & IFF_UP) == 0) { Tprintf ((" down\n")); goto skip; } /* Make sure we didn't process this address already. */ for (j = 0; j < i; j += sizeof (*lifr2)) { lifr2 = (struct lifreq *)((caddr_t) P.buf+j); if (lifr2->lifr_name[0] == '\0') continue; if (lifr2->lifr_addr.ss_family == lifr->lifr_addr.ss_family /* Compare address info. If this isn't good enough -- i.e., if random padding bytes turn out to differ when the addresses are the same -- then we'll have to do it on a per address family basis. */ && !memcmp (&lifr2->lifr_addr, &lifr->lifr_addr, sizeof (*lifr))) { Tprintf ((" duplicate addr\n")); goto skip; } } /*@-moduncon@*/ if ((*pass1fn) (data, ss2sa (&lifr->lifr_addr))) goto punt; /*@=moduncon@*/ } } /* Did we actually get any working sockets? */ FOREACH_AF () if (P.sock != -1) goto have_working_socket; retval = sock_err; goto punt; have_working_socket: /*@-moduncon@*/ if (betweenfn != NULL && (*betweenfn)(data)) goto punt; /*@=moduncon@*/ if (pass2fn) FOREACH_AF () if (P.sock >= 0) { for (i = 0; i + sizeof (*lifr) <= P.buf_size; i+= sizeof (*lifr)) { lifr = (struct lifreq *)((caddr_t) P.buf+i); if (lifr->lifr_name[0] == '\0') /* Marked in first pass to be ignored. */ continue; /*@-moduncon@*/ if ((*pass2fn) (data, ss2sa (&lifr->lifr_addr))) goto punt; /*@=moduncon@*/ } } punt: FOREACH_AF () { /*@-moduncon@*/ closesocket(P.sock); /*@=moduncon@*/ free (P.buf); } return retval; } #elif defined (SIOCGLIFNUM) && defined(HAVE_STRUCT_IF_LADDRCONF) && 0 /* HP-UX 11 support being debugged */ int foreach_localaddr (/*@null@*/ void *data, int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/, /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/, /*@null@*/ int (*pass2fn) (/*@null@*/ void *, struct sockaddr *) /*@*/) #if defined(DEBUG) || defined(TEST) /*@modifies fileSystem@*/ #endif { /* Okay, this is kind of odd. We have to use each of the address families we care about, because with an AF_INET socket, extra interfaces like hme0:1 that have only AF_INET6 addresses will cause errors. Similarly, if hme0 has more AF_INET addresses than AF_INET6 addresses, we won't be able to retrieve all of the AF_INET addresses if we use an AF_INET6 socket. Since neither family is guaranteed to have the greater number of addresses, we should use both. If it weren't for this little quirk, we could use one socket of any type, and ask for addresses of all types. At least, it seems to work that way. */ static const int afs[] = { AF_INET, AF_NS, AF_INET6 }; #define N_AFS (sizeof (afs) / sizeof (afs[0])) struct { int af; int sock; void *buf; size_t buf_size; int if_num; } afp[N_AFS]; int code, i, j; int retval = 0, afidx; krb5_error_code sock_err = 0; struct if_laddrreq *lifr, lifreq, *lifr2; #define FOREACH_AF() for (afidx = 0; afidx < N_AFS; afidx++) #define P (afp[afidx]) /* init */ FOREACH_AF () { P.af = afs[afidx]; P.sock = -1; P.buf = 0; } /* first pass: get raw data, discard uninteresting addresses, callback */ FOREACH_AF () { Tprintf (("trying af %d...\n", P.af)); P.sock = socket (P.af, USE_TYPE, USE_PROTO); if (P.sock < 0) { sock_err = SOCKET_ERROR; Tperror ("socket"); continue; } set_cloexec_fd(P.sock); code = ioctl (P.sock, SIOCGLIFNUM, &P.if_num); if (code) { Tperror ("ioctl(SIOCGLIFNUM)"); retval = errno; goto punt; } P.buf_size = P.if_num * sizeof (struct if_laddrreq) * 2; P.buf = malloc (P.buf_size); if (P.buf == NULL) { retval = ENOMEM; goto punt; } code = get_if_laddrconf (P.af, P.sock, &P.buf_size, P.buf); if (code < 0) { retval = errno; goto punt; } for (i = 0; i + sizeof(*lifr) <= P.buf_size; i+= sizeof (*lifr)) { lifr = (struct if_laddrreq *)((caddr_t) P.buf+i); strncpy(lifreq.iflr_name, lifr->iflr_name, sizeof (lifreq.iflr_name)); Tprintf (("interface %s\n", lifreq.iflr_name)); /*@-moduncon@*/ /* ioctl unknown to lclint */ if (ioctl (P.sock, SIOCGLIFFLAGS, (char *)&lifreq) < 0) { Tperror ("ioctl(SIOCGLIFFLAGS)"); skip: /* mark for next pass */ lifr->iflr_name[0] = '\0'; continue; } /*@=moduncon@*/ /* None of the current callers want loopback addresses. */ if (is_loopback_address(&lifr->iflr_addr)) { Tprintf ((" loopback\n")); goto skip; } /* Ignore interfaces that are down. */ if ((lifreq.iflr_flags & IFF_UP) == 0) { Tprintf ((" down\n")); goto skip; } /* Make sure we didn't process this address already. */ for (j = 0; j < i; j += sizeof (*lifr2)) { lifr2 = (struct if_laddrreq *)((caddr_t) P.buf+j); if (lifr2->iflr_name[0] == '\0') continue; if (lifr2->iflr_addr.sa_family == lifr->iflr_addr.sa_family /* Compare address info. If this isn't good enough -- i.e., if random padding bytes turn out to differ when the addresses are the same -- then we'll have to do it on a per address family basis. */ && !memcmp (&lifr2->iflr_addr, &lifr->iflr_addr, sizeof (*lifr))) { Tprintf ((" duplicate addr\n")); goto skip; } } /*@-moduncon@*/ if ((*pass1fn) (data, ss2sa (&lifr->iflr_addr))) goto punt; /*@=moduncon@*/ } } /* Did we actually get any working sockets? */ FOREACH_AF () if (P.sock != -1) goto have_working_socket; retval = sock_err; goto punt; have_working_socket: /*@-moduncon@*/ if (betweenfn != NULL && (*betweenfn)(data)) goto punt; /*@=moduncon@*/ if (pass2fn) FOREACH_AF () if (P.sock >= 0) { for (i = 0; i + sizeof(*lifr) <= P.buf_size; i+= sizeof (*lifr)) { lifr = (struct if_laddrreq *)((caddr_t) P.buf+i); if (lifr->iflr_name[0] == '\0') /* Marked in first pass to be ignored. */ continue; /*@-moduncon@*/ if ((*pass2fn) (data, ss2sa (&lifr->iflr_addr))) goto punt; /*@=moduncon@*/ } } punt: FOREACH_AF () { /*@-moduncon@*/ closesocket(P.sock); /*@=moduncon@*/ free (P.buf); } return retval; } #else /* not defined (SIOCGLIFNUM) */ #define SLOP (sizeof (struct ifreq) + 128) static int get_ifreq_array(char **bufp, size_t *np, int s) { int code; int est_if_count = 8; size_t est_ifreq_size; char *buf = 0; size_t current_buf_size = 0, size, n; #ifdef SIOCGSIZIFCONF int ifconfsize = -1; #endif #ifdef SIOCGIFNUM int numifs = -1; #endif *bufp = NULL; *np = 0; /* At least on NetBSD, an ifreq can hold an IPv4 address, but isn't big enough for an IPv6 or ethernet address. So add a little more space. */ est_ifreq_size = sizeof (struct ifreq) + 8; #ifdef SIOCGSIZIFCONF code = ioctl (s, SIOCGSIZIFCONF, &ifconfsize); if (!code) { current_buf_size = ifconfsize; est_if_count = ifconfsize / est_ifreq_size; } #elif defined (SIOCGIFNUM) code = ioctl (s, SIOCGIFNUM, &numifs); if (!code && numifs > 0) est_if_count = numifs; #endif if (current_buf_size == 0) current_buf_size = est_ifreq_size * est_if_count + SLOP; buf = malloc (current_buf_size); if (buf == NULL) return ENOMEM; ask_again: size = current_buf_size; code = get_ifconf (s, &size, buf); if (code < 0) { code = errno; free (buf); return code; } /* Test that the buffer was big enough that another ifreq could've fit easily, if the OS wanted to provide one. That seems to be the only indication we get, complicated by the fact that the associated address may make the required storage a little bigger than the size of an ifreq. */ if (current_buf_size - size < SLOP #ifdef SIOCGSIZIFCONF /* Unless we hear SIOCGSIZIFCONF is broken somewhere, let's trust the value it returns. */ && ifconfsize <= 0 #elif defined (SIOCGIFNUM) && numifs <= 0 #endif /* And we need *some* sort of bounds. */ && current_buf_size <= 100000 ) { size_t new_size; est_if_count *= 2; new_size = est_ifreq_size * est_if_count + SLOP; buf = grow_or_free (buf, new_size); if (buf == 0) return ENOMEM; current_buf_size = new_size; goto ask_again; } n = size; if (n > current_buf_size) n = current_buf_size; *bufp = buf; *np = n; return 0; } int foreach_localaddr (/*@null@*/ void *data, int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/, /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/, /*@null@*/ int (*pass2fn) (/*@null@*/ void *, struct sockaddr *) /*@*/) #if defined(DEBUG) || defined(TEST) /*@modifies fileSystem@*/ #endif { struct ifreq *ifr, ifreq, *ifr2; int s; char *buf = 0; size_t n, i, j; int retval = 0; #ifdef LINUX_IPV6_HACK struct linux_ipv6_addr_list *linux_ipv6_addrs = get_linux_ipv6_addrs (); struct linux_ipv6_addr_list *lx_v6; #endif s = socket (USE_AF, USE_TYPE, USE_PROTO); if (s < 0) return SOCKET_ERRNO; set_cloexec_fd(s); retval = get_ifreq_array(&buf, &n, s); if (retval) { /*@-moduncon@*/ /* close() unknown to lclint */ closesocket(s); /*@=moduncon@*/ return retval; } /* Note: Apparently some systems put the size (used or wanted?) into the start of the buffer, just none that I'm actually using. Fix this when there's such a test system available. The Samba mailing list archives mention that NTP looks for the size on these systems: *-fujitsu-uxp* *-ncr-sysv4* *-univel-sysv*. */ for (i = 0; i + sizeof(struct ifreq) <= n; i+= ifreq_size(*ifr) ) { ifr = (struct ifreq *)((caddr_t) buf+i); /* In case ifreq_size is more than sizeof(). */ if (i + ifreq_size(*ifr) > n) break; strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); Tprintf (("interface %s\n", ifreq.ifr_name)); /*@-moduncon@*/ /* ioctl unknown to lclint */ if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { skip: /* mark for next pass */ ifr->ifr_name[0] = '\0'; continue; } /*@=moduncon@*/ /* None of the current callers want loopback addresses. */ if (is_loopback_address(&ifreq.ifr_addr)) { Tprintf ((" loopback\n")); goto skip; } /* Ignore interfaces that are down. */ if ((ifreq.ifr_flags & IFF_UP) == 0) { Tprintf ((" down\n")); goto skip; } /* Make sure we didn't process this address already. */ for (j = 0; j < i; j += ifreq_size(*ifr2)) { ifr2 = (struct ifreq *)((caddr_t) buf+j); if (ifr2->ifr_name[0] == '\0') continue; if (ifr2->ifr_addr.sa_family == ifr->ifr_addr.sa_family && ifreq_size (*ifr) == ifreq_size (*ifr2) /* Compare address info. If this isn't good enough -- i.e., if random padding bytes turn out to differ when the addresses are the same -- then we'll have to do it on a per address family basis. */ && !memcmp (&ifr2->ifr_addr.sa_data, &ifr->ifr_addr.sa_data, (ifreq_size (*ifr) - offsetof (struct ifreq, ifr_addr.sa_data)))) { Tprintf ((" duplicate addr\n")); goto skip; } } /*@-moduncon@*/ if ((*pass1fn) (data, &ifr->ifr_addr)) goto punt; /*@=moduncon@*/ } #ifdef LINUX_IPV6_HACK for (lx_v6 = linux_ipv6_addrs; lx_v6; lx_v6 = lx_v6->next) if ((*pass1fn) (data, (struct sockaddr *) &lx_v6->addr)) goto punt; #endif /*@-moduncon@*/ if (betweenfn != NULL && (*betweenfn)(data)) goto punt; /*@=moduncon@*/ if (pass2fn) { for (i = 0; i + sizeof(struct ifreq) <= n; i+= ifreq_size(*ifr) ) { ifr = (struct ifreq *)((caddr_t) buf+i); if (ifr->ifr_name[0] == '\0') /* Marked in first pass to be ignored. */ continue; /*@-moduncon@*/ if ((*pass2fn) (data, &ifr->ifr_addr)) goto punt; /*@=moduncon@*/ } #ifdef LINUX_IPV6_HACK for (lx_v6 = linux_ipv6_addrs; lx_v6; lx_v6 = lx_v6->next) if ((*pass2fn) (data, (struct sockaddr *) &lx_v6->addr)) goto punt; #endif } punt: /*@-moduncon@*/ closesocket(s); /*@=moduncon@*/ free (buf); #ifdef LINUX_IPV6_HACK while (linux_ipv6_addrs) { lx_v6 = linux_ipv6_addrs->next; free (linux_ipv6_addrs); linux_ipv6_addrs = lx_v6; } #endif return retval; } #endif /* not HAVE_IFADDRS_H and not SIOCGLIFNUM */ static krb5_error_code get_localaddrs (krb5_context context, krb5_address ***addr, int use_profile); #ifdef TEST static int print_addr (/*@unused@*/ void *dataptr, struct sockaddr *sa) /*@modifies fileSystem@*/ { char hostbuf[NI_MAXHOST]; int err; socklen_t len; printf (" --> family %2d ", sa->sa_family); len = sa_socklen (sa); err = getnameinfo (sa, len, hostbuf, (socklen_t) sizeof (hostbuf), (char *) NULL, 0, NI_NUMERICHOST); if (err) { int e = errno; printf ("\n", err, gai_strerror (err)); if (err == EAI_SYSTEM) printf ("\t\t\n", e, strerror(e)); } else printf ("addr %s\n", hostbuf); return 0; } int main (void) { int r; (void) setvbuf (stdout, (char *)NULL, _IONBF, 0); r = foreach_localaddr (0, print_addr, NULL, NULL); printf ("return value = %d\n", r); return 0; } #else /* not TESTing */ struct localaddr_data { size_t count, cur_idx, cur_size; int mem_err; krb5_address **addr_temp; }; static int count_addrs (void *P_data, struct sockaddr *a) /*@*/ { struct localaddr_data *data = P_data; switch (a->sa_family) { case AF_INET: case AF_INET6: #ifdef KRB5_USE_NS case AF_XNS: #endif data->count++; break; default: break; } return 0; } static int allocate (void *P_data) /*@*/ { struct localaddr_data *data = P_data; size_t i; void *n; n = realloc (data->addr_temp, (1 + data->count + data->cur_idx) * sizeof (krb5_address *)); if (n == 0) { data->mem_err++; return 1; } data->addr_temp = n; data->cur_size = 1 + data->count + data->cur_idx; for (i = data->cur_idx; i <= data->count + data->cur_idx; i++) data->addr_temp[i] = 0; return 0; } static /*@null@*/ krb5_address * make_addr (int type, size_t length, const void *contents) /*@*/ { krb5_address *a; void *data; data = malloc (length); if (data == NULL) return NULL; a = malloc (sizeof (krb5_address)); if (a == NULL) { free (data); return NULL; } memcpy (data, contents, length); a->magic = KV5M_ADDRESS; a->addrtype = type; a->length = length; a->contents = data; return a; } static int add_addr (void *P_data, struct sockaddr *a) /*@modifies *P_data@*/ { struct localaddr_data *data = P_data; /*@null@*/ krb5_address *address = 0; switch (a->sa_family) { #ifdef HAVE_NETINET_IN_H case AF_INET: address = make_addr (ADDRTYPE_INET, sizeof (struct in_addr), &sa2sin(a)->sin_addr); if (address == NULL) data->mem_err++; break; case AF_INET6: { const struct sockaddr_in6 *in = sa2sin6(a); if (IN6_IS_ADDR_LINKLOCAL (&in->sin6_addr)) break; address = make_addr (ADDRTYPE_INET6, sizeof (struct in6_addr), &in->sin6_addr); if (address == NULL) data->mem_err++; break; } #endif /* netinet/in.h */ #ifdef KRB5_USE_NS case AF_XNS: address = make_addr (ADDRTYPE_XNS, sizeof (struct ns_addr), &((const struct sockaddr_ns *)a)->sns_addr); if (address == NULL) data->mem_err++; break; #endif #ifdef AF_LINK /* Some BSD-based systems (e.g. NetBSD 1.5) and AIX will include the ethernet address, but we don't want that, at least for now. */ case AF_LINK: break; #endif /* * Add more address families here.. */ default: break; } #ifdef __LCLINT__ /* Redundant but unconditional store un-confuses lclint. */ data->addr_temp[data->cur_idx] = address; #endif if (address) { data->addr_temp[data->cur_idx++] = address; } return data->mem_err; } static krb5_error_code krb5_os_localaddr_profile (krb5_context context, struct localaddr_data *datap) { krb5_error_code err; static const char *const profile_name[] = { KRB5_CONF_LIBDEFAULTS, KRB5_CONF_EXTRA_ADDRESSES, 0 }; char **values; char **iter; krb5_address **newaddrs; #ifdef DEBUG fprintf (stderr, "looking up extra_addresses foo\n"); #endif err = profile_get_values (context->profile, profile_name, &values); /* Ignore all errors for now? */ if (err) return 0; for (iter = values; *iter; iter++) { char *cp = *iter, *next, *current; size_t i, count; #ifdef DEBUG fprintf (stderr, " found line: '%s'\n", cp); #endif for (cp = *iter, next = 0; *cp; cp = next) { while (isspace ((int) *cp) || *cp == ',') cp++; if (*cp == 0) break; /* Start of an address. */ #ifdef DEBUG fprintf (stderr, " addr found in '%s'\n", cp); #endif current = cp; while (*cp != 0 && !isspace((int) *cp) && *cp != ',') cp++; if (*cp != 0) { next = cp + 1; *cp = 0; } else next = cp; /* Got a single address, process it. */ #ifdef DEBUG fprintf (stderr, " processing '%s'\n", current); #endif newaddrs = 0; err = k5_os_hostaddr (context, current, &newaddrs); if (err) continue; for (i = 0; newaddrs[i]; i++) { #ifdef DEBUG fprintf (stderr, " %d: family %d", i, newaddrs[i]->addrtype); fprintf (stderr, "\n"); #endif } count = i; #ifdef DEBUG fprintf (stderr, " %d addresses\n", count); #endif if (datap->cur_idx + count >= datap->cur_size) { krb5_address **bigger; bigger = realloc (datap->addr_temp, sizeof (krb5_address *) * (datap->cur_idx + count)); if (bigger) { datap->addr_temp = bigger; datap->cur_size = datap->cur_idx + count; } } for (i = 0; i < count; i++) { if (datap->cur_idx < datap->cur_size) datap->addr_temp[datap->cur_idx++] = newaddrs[i]; else free (newaddrs[i]->contents), free (newaddrs[i]); } free (newaddrs); } } return 0; } krb5_error_code KRB5_CALLCONV krb5_os_localaddr(krb5_context context, krb5_address ***addr) { return get_localaddrs(context, addr, 1); } static krb5_error_code get_localaddrs (krb5_context context, krb5_address ***addr, int use_profile) { struct localaddr_data data = { 0 }; int r; /* Ignore errors for now. */ if (use_profile) (void)krb5_os_localaddr_profile (context, &data); r = foreach_localaddr (&data, count_addrs, allocate, add_addr); if (r != 0) { size_t i; if (data.addr_temp) { for (i = 0; i < data.count; i++) free (data.addr_temp[i]); free (data.addr_temp); } if (data.mem_err) return ENOMEM; else return r; } data.cur_idx++; /* null termination */ if (data.mem_err) return ENOMEM; else if (data.cur_idx == data.count) *addr = data.addr_temp; else { /* This can easily happen if we have IPv6 link-local addresses. Just shorten the array. */ *addr = (krb5_address **) realloc (data.addr_temp, (sizeof (krb5_address *) * data.cur_idx)); if (*addr == 0) /* Okay, shortening failed, but the original should still be intact. */ *addr = data.addr_temp; } #ifdef DEBUG { size_t j; fprintf (stderr, "addresses:\n"); for (j = 0; addr[0][j]; j++) { struct sockaddr_storage ss; int err2; char namebuf[NI_MAXHOST]; void *addrp = 0; fprintf (stderr, "%2d: ", j); fprintf (stderr, "addrtype %2d, length %2d", addr[0][j]->addrtype, addr[0][j]->length); memset (&ss, 0, sizeof (ss)); switch (addr[0][j]->addrtype) { case ADDRTYPE_INET: { struct sockaddr_in *sinp = ss2sin (&ss); sinp->sin_family = AF_INET; addrp = &sinp->sin_addr; break; } case ADDRTYPE_INET6: { struct sockaddr_in6 *sin6p = ss2sin6 (&ss); sin6p->sin6_family = AF_INET6; addrp = &sin6p->sin6_addr; break; } default: ss2sa(&ss)->sa_family = 0; break; } if (addrp) memcpy (addrp, addr[0][j]->contents, addr[0][j]->length); err2 = getnameinfo (ss2sa(&ss), sa_socklen (ss2sa (&ss)), namebuf, sizeof (namebuf), 0, 0, NI_NUMERICHOST); if (err2 == 0) fprintf (stderr, ": addr %s\n", namebuf); else fprintf (stderr, ": getnameinfo error %d\n", err2); } } #endif return 0; } #endif /* not TESTing */ #else /* Windows/Mac version */ /* * Hold on to your lunch! Backup kludge method of obtaining your * local IP address, courtesy of Windows Socket Network Programming, * by Robert Quinn */ #if defined(_WIN32) static struct hostent *local_addr_fallback_kludge(void) { static struct hostent host; static SOCKADDR_IN addr; static char * ip_ptrs[2]; SOCKET sock; int size = sizeof(SOCKADDR); int err; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == INVALID_SOCKET) return NULL; set_cloexec_fd(sock); /* connect to arbitrary port and address (NOT loopback) */ addr.sin_family = AF_INET; addr.sin_port = htons(IPPORT_ECHO); addr.sin_addr.s_addr = inet_addr("204.137.220.51"); err = connect(sock, (LPSOCKADDR) &addr, sizeof(SOCKADDR)); if (err == SOCKET_ERROR) return NULL; err = getsockname(sock, (LPSOCKADDR) &addr, &size); if (err == SOCKET_ERROR) return NULL; closesocket(sock); host.h_name = 0; host.h_aliases = 0; host.h_addrtype = AF_INET; host.h_length = 4; host.h_addr_list = ip_ptrs; ip_ptrs[0] = (char *) &addr.sin_addr.s_addr; ip_ptrs[1] = NULL; return &host; } #endif /* No ioctls in winsock so we just assume there is only one networking * card per machine, so gethostent is good enough. */ krb5_error_code KRB5_CALLCONV krb5_os_localaddr (krb5_context context, krb5_address ***addr) { char host[64]; /* Name of local machine */ struct hostent *hostrec; size_t count, i; int err; krb5_address ** paddr; *addr = 0; paddr = 0; err = 0; if (gethostname (host, sizeof(host))) { err = SOCKET_ERRNO; } if (!err) { hostrec = gethostbyname (host); if (hostrec == NULL) { err = SOCKET_ERRNO; } } if (err) { hostrec = local_addr_fallback_kludge(); if (!hostrec) return err; else err = 0; /* otherwise we will die at cleanup */ } for (count = 0; hostrec->h_addr_list[count]; count++); paddr = (krb5_address **)calloc(count+1, sizeof(krb5_address *)); if (!paddr) { err = ENOMEM; goto cleanup; } for (i = 0; i < count; i++) { paddr[i] = (krb5_address *)malloc(sizeof(krb5_address)); if (paddr[i] == NULL) { err = ENOMEM; goto cleanup; } paddr[i]->magic = KV5M_ADDRESS; paddr[i]->addrtype = hostrec->h_addrtype; paddr[i]->length = hostrec->h_length; paddr[i]->contents = (unsigned char *)malloc(paddr[i]->length); if (!paddr[i]->contents) { err = ENOMEM; goto cleanup; } memcpy(paddr[i]->contents, hostrec->h_addr_list[i], paddr[i]->length); } cleanup: if (err) { if (paddr) { for (i = 0; i < count; i++) { if (paddr[i]) { if (paddr[i]->contents) free(paddr[i]->contents); free(paddr[i]); } } free(paddr); } } else *addr = paddr; return(err); } #endif krb5-1.22.1/src/lib/krb5/os/gen_port.c0000664000175000017500000000353015051422640017144 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/gen_port.c - Generate full address from IP address and port */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "os-proto.h" krb5_error_code krb5_gen_portaddr(krb5_context context, const krb5_address *addr, krb5_const_pointer ptr, krb5_address **outaddr) { #ifdef HAVE_NETINET_IN_H krb5_int32 adr; krb5_int16 port; if (addr->addrtype != ADDRTYPE_INET) return KRB5_PROG_ATYPE_NOSUPP; port = *(const krb5_int16 *)ptr; memcpy(&adr, addr->contents, sizeof(adr)); return krb5_make_full_ipaddr(context, adr, port, outaddr); #else return KRB5_PROG_ATYPE_NOSUPP; #endif } krb5-1.22.1/src/lib/krb5/os/hostrealm_dns.c0000664000175000017500000001060715051422640020174 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/hostream_dns.c - dns hostrealm module */ /* * Copyright (C) 1990,1991,2002,2008,2009,2013 by the Massachusetts Institute * of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file implements the built-in dns module for the hostrealm interface, * which uses TXT records in the DNS to determine the default realm or the * fallback realm of a host. */ #include "k5-int.h" #include "os-proto.h" #include #ifdef KRB5_DNS_LOOKUP /* Try a _kerberos TXT lookup for fqdn and each parent domain; return the * resulting realm (caller must free) or NULL. */ static char * txt_lookup(krb5_context context, const char *fqdn) { char *realm; while (fqdn != NULL && *fqdn != '\0') { if (k5_try_realm_txt_rr(context, "_kerberos", fqdn, &realm) == 0) return realm; fqdn = strchr(fqdn, '.'); if (fqdn != NULL) fqdn++; } return NULL; } static krb5_error_code dns_fallback_realm(krb5_context context, krb5_hostrealm_moddata data, const char *host, char ***realms_out) { krb5_error_code ret; char *realm; *realms_out = NULL; if (!_krb5_use_dns_realm(context) || k5_is_numeric_address(host)) return KRB5_PLUGIN_NO_HANDLE; /* Try a TXT record lookup for each component of host. */ realm = txt_lookup(context, host); if (realm == NULL) return KRB5_PLUGIN_NO_HANDLE; ret = k5_make_realmlist(realm, realms_out); free(realm); return ret; } static krb5_error_code dns_default_realm(krb5_context context, krb5_hostrealm_moddata data, char ***realms_out) { krb5_error_code ret; char *localhost, *realm; *realms_out = NULL; if (!_krb5_use_dns_realm(context)) return KRB5_PLUGIN_NO_HANDLE; ret = krb5int_get_fq_local_hostname(&localhost); if (ret) return ret; /* If we don't find a TXT record for localhost or any parent, look for a * global record. */ realm = txt_lookup(context, localhost); free(localhost); if (realm == NULL) (void)k5_try_realm_txt_rr(context, "_kerberos", NULL, &realm); if (realm == NULL) return KRB5_PLUGIN_NO_HANDLE; ret = k5_make_realmlist(realm, realms_out); free(realm); return ret; } static void dns_free_realmlist(krb5_context context, krb5_hostrealm_moddata data, char **list) { krb5_free_host_realm(context, list); } krb5_error_code hostrealm_dns_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_hostrealm_vtable vt = (krb5_hostrealm_vtable)vtable; vt->name = "dns"; vt->fallback_realm = dns_fallback_realm; vt->default_realm = dns_default_realm; vt->free_list = dns_free_realmlist; return 0; } #else /* KRB5_DNS_LOOKUP */ krb5_error_code hostrealm_dns_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_hostrealm_vtable vt = (krb5_hostrealm_vtable)vtable; vt->name = "dns"; return 0; } #endif /* KRB5_DNS_LOOKUP */ krb5-1.22.1/src/lib/krb5/os/sendto_kdc.c0000664000175000017500000014647515051422640017464 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/sendto_kdc.c */ /* * Copyright 1990,1991,2001,2002,2004,2005,2007,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * MS-KKDCP implementation Copyright 2013,2014 Red Hat, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Send packet to KDC for realm; wait for response, retransmitting * as necessary. */ #include "k5-int.h" #include "k5-tls.h" #include "fake-addrinfo.h" #include "os-proto.h" #if defined(HAVE_POLL_H) #include #define USE_POLL #define MAX_POLLFDS 1024 #elif defined(HAVE_SYS_SELECT_H) #include #endif #ifndef _WIN32 /* For FIONBIO. */ #include #ifdef HAVE_SYS_FILIO_H #include #endif #endif #define MAX_PASS 3 #define DEFAULT_UDP_PREF_LIMIT 1465 #define HARD_UDP_LIMIT 32700 /* could probably do 64K-epsilon ? */ #define PORT_LENGTH 6 /* decimal repr of UINT16_MAX */ /* Select state flags. */ #define SSF_READ 0x01 #define SSF_WRITE 0x02 #define SSF_EXCEPTION 0x04 typedef int64_t time_ms; /* This can be pretty large, so should not be stack-allocated. */ struct select_state { #ifdef USE_POLL struct pollfd fds[MAX_POLLFDS]; #else int max; fd_set rfds, wfds, xfds; #endif int nfds; }; /* connection states */ enum conn_states { INITIALIZING, CONNECTING, WRITING, READING, FAILED }; struct incoming_message { size_t bufsizebytes_read; size_t bufsize; size_t pos; char *buf; unsigned char bufsizebytes[4]; size_t n_left; }; struct outgoing_message { sg_buf sgbuf[2]; sg_buf *sgp; int sg_count; unsigned char msg_len_buf[4]; }; struct conn_state; typedef krb5_boolean fd_handler_fn(krb5_context context, const krb5_data *realm, struct conn_state *conn, struct select_state *selstate); struct conn_state { SOCKET fd; enum conn_states state; fd_handler_fn *service_connect; fd_handler_fn *service_write; fd_handler_fn *service_read; struct remote_address addr; struct incoming_message in; struct outgoing_message out; krb5_data callback_buffer; size_t server_index; struct conn_state *next; krb5_boolean defer; struct { const char *uri_path; const char *servername; char port[PORT_LENGTH]; char *https_request; k5_tls_handle tls; } http; }; /* Set up context->tls. On allocation failure, return ENOMEM. On plugin load * failure, set context->tls to point to a nulled vtable and return 0. */ static krb5_error_code init_tls_vtable(krb5_context context) { krb5_plugin_initvt_fn initfn; krb5_error_code ret; if (context->tls != NULL) return 0; context->tls = calloc(1, sizeof(*context->tls)); if (context->tls == NULL) return ENOMEM; /* Attempt to load the module; just let it stay nulled out on failure. */ k5_plugin_register_dyn(context, PLUGIN_INTERFACE_TLS, "k5tls", "tls"); ret = k5_plugin_load(context, PLUGIN_INTERFACE_TLS, "k5tls", &initfn); if (!ret) (*initfn)(context, 0, 0, (krb5_plugin_vtable)context->tls); else TRACE_SENDTO_KDC_K5TLS_LOAD_ERROR(context, ret); return 0; } /* Get current time in milliseconds. */ static krb5_error_code get_curtime_ms(time_ms *time_out) { struct timeval tv; *time_out = 0; if (gettimeofday(&tv, 0)) return errno; *time_out = (time_ms)tv.tv_sec * 1000 + tv.tv_usec / 1000; return 0; } static void free_http_tls_data(krb5_context context, struct conn_state *state) { if (state->http.tls != NULL) context->tls->free_handle(context, state->http.tls); state->http.tls = NULL; free(state->http.https_request); state->http.https_request = NULL; } #ifdef USE_POLL /* Find a pollfd in selstate by fd, or abort if we can't find it. */ static inline struct pollfd * find_pollfd(struct select_state *selstate, int fd) { int i; for (i = 0; i < selstate->nfds; i++) { if (selstate->fds[i].fd == fd) return &selstate->fds[i]; } abort(); } static void cm_init_selstate(struct select_state *selstate) { selstate->nfds = 0; } static krb5_boolean cm_add_fd(struct select_state *selstate, int fd) { if (selstate->nfds >= MAX_POLLFDS) return FALSE; selstate->fds[selstate->nfds].fd = fd; selstate->fds[selstate->nfds].events = 0; selstate->nfds++; return TRUE; } static void cm_remove_fd(struct select_state *selstate, int fd) { struct pollfd *pfd = find_pollfd(selstate, fd); *pfd = selstate->fds[selstate->nfds - 1]; selstate->nfds--; } /* Poll for reading (and not writing) on fd the next time we poll. */ static void cm_read(struct select_state *selstate, int fd) { find_pollfd(selstate, fd)->events = POLLIN; } /* Poll for writing (and not reading) on fd the next time we poll. */ static void cm_write(struct select_state *selstate, int fd) { find_pollfd(selstate, fd)->events = POLLOUT; } /* Get the output events for fd in the form of ssflags. */ static unsigned int cm_get_ssflags(struct select_state *selstate, int fd) { struct pollfd *pfd = find_pollfd(selstate, fd); /* * macOS sets POLLHUP without POLLOUT on connection error. Catch this as * well as other error events such as POLLNVAL, but only if POLLIN and * POLLOUT aren't set, as we can get POLLHUP along with POLLIN with TCP * data still to be read. */ if (pfd->revents != 0 && !(pfd->revents & (POLLIN | POLLOUT))) return SSF_EXCEPTION; return ((pfd->revents & POLLIN) ? SSF_READ : 0) | ((pfd->revents & POLLOUT) ? SSF_WRITE : 0) | ((pfd->revents & POLLERR) ? SSF_EXCEPTION : 0); } #else /* not USE_POLL */ static void cm_init_selstate(struct select_state *selstate) { selstate->nfds = 0; selstate->max = 0; FD_ZERO(&selstate->rfds); FD_ZERO(&selstate->wfds); FD_ZERO(&selstate->xfds); } static krb5_boolean cm_add_fd(struct select_state *selstate, int fd) { #ifndef _WIN32 /* On Windows FD_SETSIZE is a count, not a max value. */ if (fd >= FD_SETSIZE) return FALSE; #endif FD_SET(fd, &selstate->xfds); if (selstate->max <= fd) selstate->max = fd + 1; selstate->nfds++; return TRUE; } static void cm_remove_fd(struct select_state *selstate, int fd) { FD_CLR(fd, &selstate->rfds); FD_CLR(fd, &selstate->wfds); FD_CLR(fd, &selstate->xfds); if (selstate->max == fd + 1) { while (selstate->max > 0 && !FD_ISSET(selstate->max - 1, &selstate->rfds) && !FD_ISSET(selstate->max - 1, &selstate->wfds) && !FD_ISSET(selstate->max - 1, &selstate->xfds)) selstate->max--; } selstate->nfds--; } /* Select for reading (and not writing) on fd the next time we select. */ static void cm_read(struct select_state *selstate, int fd) { FD_SET(fd, &selstate->rfds); FD_CLR(fd, &selstate->wfds); } /* Select for writing (and not reading) on fd the next time we select. */ static void cm_write(struct select_state *selstate, int fd) { FD_CLR(fd, &selstate->rfds); FD_SET(fd, &selstate->wfds); } /* Get the events for fd from selstate after a select. */ static unsigned int cm_get_ssflags(struct select_state *selstate, int fd) { return (FD_ISSET(fd, &selstate->rfds) ? SSF_READ : 0) | (FD_ISSET(fd, &selstate->wfds) ? SSF_WRITE : 0) | (FD_ISSET(fd, &selstate->xfds) ? SSF_EXCEPTION : 0); } #endif /* not USE_POLL */ static krb5_error_code cm_select_or_poll(const struct select_state *in, time_ms endtime, struct select_state *out, int *sret) { #ifndef USE_POLL struct timeval tv, *tvp; #endif krb5_error_code retval; time_ms curtime, interval; if (endtime != 0) { retval = get_curtime_ms(&curtime); if (retval != 0) return retval; interval = (curtime < endtime) ? endtime - curtime : 0; } else { interval = -1; } /* We don't need a separate copy of the selstate for poll, but use one for * consistency with how we use select. */ *out = *in; #ifdef USE_POLL *sret = poll(out->fds, out->nfds, interval); #else if (interval != -1) { tv.tv_sec = interval / 1000; tv.tv_usec = interval % 1000 * 1000; tvp = &tv; } else { tvp = NULL; } *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, tvp); #endif return (*sret < 0) ? SOCKET_ERRNO : 0; } static int socktype_for_transport(k5_transport transport) { switch (transport) { case UDP: return SOCK_DGRAM; case TCP: case HTTPS: case UNIXSOCK: return SOCK_STREAM; default: return 0; } } static int check_for_svc_unavailable (krb5_context context, const krb5_data *reply, void *msg_handler_data) { krb5_error_code *retval = (krb5_error_code *)msg_handler_data; *retval = 0; if (krb5_is_krb_error(reply)) { krb5_error *err_reply; if (decode_krb5_error(reply, &err_reply) == 0) { *retval = err_reply->error; krb5_free_error(context, err_reply); /* Returning 0 means continue to next KDC */ return (*retval != KDC_ERR_SVC_UNAVAILABLE); } } return 1; } void KRB5_CALLCONV krb5_set_kdc_send_hook(krb5_context context, krb5_pre_send_fn send_hook, void *data) { context->kdc_send_hook = send_hook; context->kdc_send_hook_data = data; } void KRB5_CALLCONV krb5_set_kdc_recv_hook(krb5_context context, krb5_post_recv_fn recv_hook, void *data) { context->kdc_recv_hook = recv_hook; context->kdc_recv_hook_data = data; } /* * send the formatted request 'message' to a KDC for realm 'realm' and * return the response (if any) in 'reply'. * * If the message is sent and a response is received, 0 is returned, * otherwise an error code is returned. * * The storage for 'reply' is allocated and should be freed by the caller * when finished. */ krb5_error_code k5_sendto_kdc(krb5_context context, const krb5_data *message, const krb5_data *realm, krb5_boolean use_primary, krb5_boolean no_udp, krb5_data *reply_out, struct kdclist *kdcs) { krb5_error_code retval, oldret, err; struct serverlist servers; int server_used = -1; k5_transport_strategy strategy; krb5_data reply = empty_data(), *hook_message = NULL, *hook_reply = NULL; *reply_out = empty_data(); /* * find KDC location(s) for realm */ /* * BUG: This code won't return "interesting" errors (e.g., out of mem, * bad config file) from locate_kdc. KRB5_REALM_CANT_RESOLVE can be * ignored from one query of two, but if only one query is done, or * both return that error, it should be returned to the caller. Also, * "interesting" errors (not KRB5_KDC_UNREACH) from sendto_{udp,tcp} * should probably be returned as well. */ TRACE_SENDTO_KDC(context, message->length, realm, use_primary, no_udp); if (!no_udp && context->udp_pref_limit < 0) { int tmp; retval = profile_get_integer(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_UDP_PREFERENCE_LIMIT, 0, DEFAULT_UDP_PREF_LIMIT, &tmp); if (retval) return retval; if (tmp < 0) tmp = DEFAULT_UDP_PREF_LIMIT; else if (tmp > HARD_UDP_LIMIT) /* In the unlikely case that a *really* big value is given, let 'em use as big as we think we can support. */ tmp = HARD_UDP_LIMIT; context->udp_pref_limit = tmp; } if (no_udp) strategy = NO_UDP; else if (message->length <= (unsigned int) context->udp_pref_limit) strategy = UDP_FIRST; else strategy = UDP_LAST; retval = k5_locate_kdc(context, realm, &servers, use_primary, no_udp); if (retval) return retval; if (context->kdc_send_hook != NULL) { retval = context->kdc_send_hook(context, context->kdc_send_hook_data, realm, message, &hook_message, &hook_reply); if (retval) goto cleanup; if (hook_reply != NULL) { *reply_out = *hook_reply; free(hook_reply); goto cleanup; } if (hook_message != NULL) message = hook_message; } err = 0; retval = k5_sendto(context, message, realm, &servers, strategy, NULL, &reply, NULL, NULL, &server_used, check_for_svc_unavailable, &err); if (retval == KRB5_KDC_UNREACH) { if (err == KDC_ERR_SVC_UNAVAILABLE) { retval = KRB5KDC_ERR_SVC_UNAVAILABLE; } else { k5_setmsg(context, retval, _("Cannot contact any KDC for realm '%.*s'"), realm->length, realm->data); } } if (context->kdc_recv_hook != NULL) { oldret = retval; retval = context->kdc_recv_hook(context, context->kdc_recv_hook_data, retval, realm, message, &reply, &hook_reply); if (oldret && !retval) { /* The hook must set a reply if it overrides an error from * k5_sendto(). */ assert(hook_reply != NULL); } } if (retval) goto cleanup; if (hook_reply != NULL) { *reply_out = *hook_reply; free(hook_reply); goto cleanup; } *reply_out = reply; reply = empty_data(); /* Record which KDC we used if the caller asks. */ if (kdcs != NULL && server_used != -1) retval = k5_kdclist_add(kdcs, realm, &servers.servers[server_used]); cleanup: krb5_free_data(context, hook_message); krb5_free_data_contents(context, &reply); k5_free_serverlist(&servers); return retval; } krb5_error_code krb5_sendto_kdc(krb5_context context, const krb5_data *message, const krb5_data *realm, krb5_data *reply_out, int *use_primary, int no_udp) { return k5_sendto_kdc(context, message, realm, *use_primary, no_udp, reply_out, NULL); } /* * Notes: * * Getting "connection refused" on a connected UDP socket causes * select to indicate write capability on UNIX, but only shows up * as an exception on Windows. (I don't think any UNIX system flags * the error as an exception.) So we check for both, or make it * system-specific. * * Always watch for responses from *any* of the servers. Eventually * fix the UDP code to do the same. * * To do: * - TCP NOPUSH/CORK socket options? * - error codes that don't suck * - getsockopt(SO_ERROR) to check connect status * - handle error RESPONSE_TOO_BIG from UDP server and use TCP * connections already in progress */ static fd_handler_fn service_tcp_connect; static fd_handler_fn service_tcp_write; static fd_handler_fn service_tcp_read; static fd_handler_fn service_udp_read; static fd_handler_fn service_https_write; static fd_handler_fn service_https_read; static krb5_error_code make_proxy_request(struct conn_state *state, const krb5_data *realm, const krb5_data *message, char **req_out, size_t *len_out) { krb5_kkdcp_message pm; krb5_data *encoded_pm = NULL; struct k5buf buf; const char *uri_path; krb5_error_code ret; *req_out = NULL; *len_out = 0; /* * Stuff the message length in at the front of the kerb_message field * before encoding. The proxied messages are actually the payload we'd * be sending and receiving if we were using plain TCP. */ memset(&pm, 0, sizeof(pm)); ret = alloc_data(&pm.kerb_message, message->length + 4); if (ret != 0) goto cleanup; store_32_be(message->length, pm.kerb_message.data); memcpy(pm.kerb_message.data + 4, message->data, message->length); pm.target_domain = *realm; ret = encode_krb5_kkdcp_message(&pm, &encoded_pm); if (ret != 0) goto cleanup; /* Build the request to transmit: the headers + the proxy message. */ k5_buf_init_dynamic(&buf); uri_path = (state->http.uri_path != NULL) ? state->http.uri_path : ""; k5_buf_add_fmt(&buf, "POST /%s HTTP/1.0\r\n", uri_path); k5_buf_add_fmt(&buf, "Host: %s:%s\r\n", state->http.servername, state->http.port); k5_buf_add(&buf, "Cache-Control: no-cache\r\n"); k5_buf_add(&buf, "Pragma: no-cache\r\n"); k5_buf_add(&buf, "User-Agent: kerberos/1.0\r\n"); k5_buf_add(&buf, "Content-type: application/kerberos\r\n"); k5_buf_add_fmt(&buf, "Content-Length: %d\r\n\r\n", encoded_pm->length); k5_buf_add_len(&buf, encoded_pm->data, encoded_pm->length); if (k5_buf_status(&buf) != 0) { ret = ENOMEM; goto cleanup; } *req_out = buf.data; *len_out = buf.len; cleanup: krb5_free_data_contents(NULL, &pm.kerb_message); krb5_free_data(NULL, encoded_pm); return ret; } /* Set up the actual message we will send across the underlying transport to * communicate the payload message, using one or both of state->out.sgbuf. */ static krb5_error_code set_transport_message(struct conn_state *state, const krb5_data *realm, const krb5_data *message) { struct outgoing_message *out = &state->out; char *req = NULL; size_t reqlen; krb5_error_code ret; if (message == NULL || message->length == 0) return 0; if (state->addr.transport == TCP || state->addr.transport == UNIXSOCK) { store_32_be(message->length, out->msg_len_buf); SG_SET(&out->sgbuf[0], out->msg_len_buf, 4); SG_SET(&out->sgbuf[1], message->data, message->length); out->sg_count = 2; return 0; } else if (state->addr.transport == HTTPS) { ret = make_proxy_request(state, realm, message, &req, &reqlen); if (ret != 0) return ret; SG_SET(&state->out.sgbuf[0], req, reqlen); SG_SET(&state->out.sgbuf[1], 0, 0); state->out.sg_count = 1; free(state->http.https_request); state->http.https_request = req; return 0; } else { SG_SET(&out->sgbuf[0], message->data, message->length); SG_SET(&out->sgbuf[1], NULL, 0); out->sg_count = 1; return 0; } } static krb5_error_code add_connection(struct conn_state **conns, k5_transport transport, krb5_boolean defer, struct addrinfo *ai, size_t server_index, const krb5_data *realm, const char *hostname, const char *port, const char *uri_path, char **udpbufp) { struct conn_state *state, **tailptr; state = calloc(1, sizeof(*state)); if (state == NULL) return ENOMEM; state->state = INITIALIZING; state->out.sgp = state->out.sgbuf; state->addr.transport = transport; state->addr.family = ai->ai_family; state->addr.len = ai->ai_addrlen; memcpy(&state->addr.saddr, ai->ai_addr, ai->ai_addrlen); state->defer = defer; state->fd = INVALID_SOCKET; state->server_index = server_index; SG_SET(&state->out.sgbuf[1], NULL, 0); if (transport == TCP || transport == UNIXSOCK) { state->service_connect = service_tcp_connect; state->service_write = service_tcp_write; state->service_read = service_tcp_read; } else if (transport == HTTPS) { assert(hostname != NULL && port != NULL); state->service_connect = service_tcp_connect; state->service_write = service_https_write; state->service_read = service_https_read; state->http.uri_path = uri_path; state->http.servername = hostname; strlcpy(state->http.port, port, PORT_LENGTH); } else { state->service_connect = NULL; state->service_write = NULL; state->service_read = service_udp_read; if (*udpbufp == NULL) { *udpbufp = malloc(MAX_DGRAM_SIZE); if (*udpbufp == NULL) { free(state); return ENOMEM; } } state->in.buf = *udpbufp; state->in.bufsize = MAX_DGRAM_SIZE; } /* Chain the new state onto the tail of the list. */ for (tailptr = conns; *tailptr != NULL; tailptr = &(*tailptr)->next); *tailptr = state; return 0; } static int translate_ai_error (int err) { switch (err) { case 0: return 0; case EAI_BADFLAGS: case EAI_FAMILY: case EAI_SOCKTYPE: case EAI_SERVICE: /* All of these indicate bad inputs to getaddrinfo. */ return EINVAL; case EAI_AGAIN: /* Translate to standard errno code. */ return EAGAIN; case EAI_MEMORY: /* Translate to standard errno code. */ return ENOMEM; #ifdef EAI_ADDRFAMILY case EAI_ADDRFAMILY: #endif #if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME case EAI_NODATA: #endif case EAI_NONAME: /* Name not known or no address data, but no error. Do nothing more. */ return 0; #ifdef EAI_OVERFLOW case EAI_OVERFLOW: /* An argument buffer overflowed. */ return EINVAL; /* XXX */ #endif #ifdef EAI_SYSTEM case EAI_SYSTEM: /* System error, obviously. */ return errno; #endif default: /* An error code we haven't handled? */ return EINVAL; } } /* * Resolve the entry in servers with index ind, adding connections to the list * *conns. Connections are added for each of socktype1 and (if not zero) * socktype2. message and udpbufp are used to initialize the connections; see * add_connection above. If no addresses are available for an entry but no * internal name resolution failure occurs, return 0 without adding any new * connections. */ static krb5_error_code resolve_server(krb5_context context, const krb5_data *realm, const struct serverlist *servers, size_t ind, k5_transport_strategy strategy, const krb5_data *message, char **udpbufp, struct conn_state **conns) { krb5_error_code retval; struct server_entry *entry = &servers->servers[ind]; k5_transport transport; struct addrinfo *addrs, *a, hint, ai; krb5_boolean defer = FALSE; int err, result; char portbuf[PORT_LENGTH]; /* Skip entries excluded by the strategy. */ if (strategy == NO_UDP && entry->transport == UDP) return 0; if (strategy == ONLY_UDP && entry->transport != UDP && entry->transport != TCP_OR_UDP) return 0; transport = (strategy == UDP_FIRST || strategy == ONLY_UDP) ? UDP : TCP; /* If the entry has a specified transport, use it, but possibly defer the * addresses we add based on the strategy. */ if (entry->transport != TCP_OR_UDP) { transport = entry->transport; defer = (entry->transport == TCP && strategy == UDP_FIRST) || (entry->transport == UDP && strategy == UDP_LAST); } if (entry->hostname == NULL) { /* The entry contains an address; skip name resolution. */ ai.ai_socktype = socktype_for_transport(entry->transport); ai.ai_family = entry->family; ai.ai_addrlen = entry->addrlen; ai.ai_addr = ss2sa(&entry->addr); return add_connection(conns, entry->transport, defer, &ai, ind, realm, NULL, NULL, entry->uri_path, udpbufp); } memset(&hint, 0, sizeof(hint)); hint.ai_family = entry->family; hint.ai_socktype = socktype_for_transport(transport); hint.ai_flags = AI_ADDRCONFIG; #ifdef AI_NUMERICSERV hint.ai_flags |= AI_NUMERICSERV; #endif result = snprintf(portbuf, sizeof(portbuf), "%d", entry->port); if (SNPRINTF_OVERFLOW(result, sizeof(portbuf))) return EINVAL; TRACE_SENDTO_KDC_RESOLVING(context, entry->hostname); err = getaddrinfo(entry->hostname, portbuf, &hint, &addrs); if (err) return translate_ai_error(err); /* Add each address with the specified or preferred transport. */ retval = 0; for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { retval = add_connection(conns, transport, defer, a, ind, realm, entry->hostname, portbuf, entry->uri_path, udpbufp); } /* For TCP_OR_UDP entries, add each address again with the non-preferred * transport, if there is one. Flag these as deferred. */ if (retval == 0 && entry->transport == TCP_OR_UDP && (strategy == UDP_FIRST || strategy == UDP_LAST)) { transport = (strategy == UDP_FIRST) ? TCP : UDP; for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { a->ai_socktype = socktype_for_transport(transport); retval = add_connection(conns, transport, TRUE, a, ind, realm, entry->hostname, portbuf, entry->uri_path, udpbufp); } } freeaddrinfo(addrs); return retval; } static int start_connection(krb5_context context, struct conn_state *state, const krb5_data *message, struct select_state *selstate, const krb5_data *realm, struct sendto_callback_info *callback_info) { int fd, e, type; static const int one = 1; static const struct linger lopt = { 0, 0 }; type = socktype_for_transport(state->addr.transport); fd = socket(state->addr.family, type, 0); if (fd == INVALID_SOCKET) return -1; /* try other hosts */ set_cloexec_fd(fd); /* Make it non-blocking. */ ioctlsocket(fd, FIONBIO, (const void *) &one); if (state->addr.transport == TCP) { setsockopt(fd, SOL_SOCKET, SO_LINGER, &lopt, sizeof(lopt)); TRACE_SENDTO_KDC_TCP_CONNECT(context, &state->addr); } /* Start connecting to KDC. */ e = SOCKET_CONNECT(fd, (struct sockaddr *)&state->addr.saddr, state->addr.len); if (e != 0) { /* * This is the path that should be followed for non-blocking * connections. */ if (SOCKET_ERRNO == EINPROGRESS || SOCKET_ERRNO == EWOULDBLOCK) { state->state = CONNECTING; state->fd = fd; } else { (void) closesocket(fd); state->state = FAILED; return -2; } } else { /* * Connect returned zero even though we made it non-blocking. This * happens normally for UDP sockets, and can perhaps also happen for * TCP sockets connecting to localhost. */ state->state = WRITING; state->fd = fd; } /* * Here's where KPASSWD callback gets the socket information it needs for * a kpasswd request */ if (callback_info) { e = callback_info->pfn_callback(state->fd, callback_info->data, &state->callback_buffer); if (e != 0) { (void) closesocket(fd); state->fd = INVALID_SOCKET; state->state = FAILED; return -3; } message = &state->callback_buffer; } e = set_transport_message(state, realm, message); if (e != 0) { TRACE_SENDTO_KDC_ERROR_SET_MESSAGE(context, &state->addr, e); (void) closesocket(state->fd); state->fd = INVALID_SOCKET; state->state = FAILED; return -4; } if (state->addr.transport == UDP) { /* Send it now. */ ssize_t ret; sg_buf *sg = &state->out.sgbuf[0]; TRACE_SENDTO_KDC_UDP_SEND_INITIAL(context, &state->addr); ret = send(state->fd, SG_BUF(sg), SG_LEN(sg), 0); if (ret < 0 || (size_t) ret != SG_LEN(sg)) { TRACE_SENDTO_KDC_UDP_ERROR_SEND_INITIAL(context, &state->addr, SOCKET_ERRNO); (void) closesocket(state->fd); state->fd = INVALID_SOCKET; state->state = FAILED; return -5; } else { state->state = READING; } } if (!cm_add_fd(selstate, state->fd)) { (void) closesocket(state->fd); state->fd = INVALID_SOCKET; state->state = FAILED; return -1; } if (state->state == CONNECTING || state->state == WRITING) cm_write(selstate, state->fd); else cm_read(selstate, state->fd); return 0; } /* Return 0 if we sent something, non-0 otherwise. If 0 is returned, the caller should delay waiting for a response. Otherwise, the caller should immediately move on to process the next connection. */ static int maybe_send(krb5_context context, struct conn_state *conn, const krb5_data *message, struct select_state *selstate, const krb5_data *realm, struct sendto_callback_info *callback_info) { sg_buf *sg; ssize_t ret; if (conn->state == INITIALIZING) { return start_connection(context, conn, message, selstate, realm, callback_info); } /* Did we already shut down this channel? */ if (conn->state == FAILED) { return -1; } if (conn->addr.transport != UDP) { /* The select callback will handle flushing any data we haven't written yet, and we only write it once. */ return -1; } /* UDP - retransmit after a previous attempt timed out. */ sg = &conn->out.sgbuf[0]; TRACE_SENDTO_KDC_UDP_SEND_RETRY(context, &conn->addr); ret = send(conn->fd, SG_BUF(sg), SG_LEN(sg), 0); if (ret < 0 || (size_t) ret != SG_LEN(sg)) { TRACE_SENDTO_KDC_UDP_ERROR_SEND_RETRY(context, &conn->addr, SOCKET_ERRNO); /* Keep connection alive, we'll try again next pass. Is this likely to catch any errors we didn't get from the select callbacks? */ return -1; } /* Yay, it worked. */ return 0; } static void kill_conn(krb5_context context, struct conn_state *conn, struct select_state *selstate) { free_http_tls_data(context, conn); if (socktype_for_transport(conn->addr.transport) == SOCK_STREAM) TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr); cm_remove_fd(selstate, conn->fd); closesocket(conn->fd); conn->fd = INVALID_SOCKET; conn->state = FAILED; } /* Check socket for error. */ static int get_so_error(int fd) { int e, sockerr; socklen_t sockerrlen; sockerr = 0; sockerrlen = sizeof(sockerr); e = getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen); if (e != 0) { /* What to do now? */ e = SOCKET_ERRNO; return e; } return sockerr; } /* Perform next step in sending. Return true on usable data. */ static krb5_boolean service_dispatch(krb5_context context, const krb5_data *realm, struct conn_state *conn, struct select_state *selstate, int ssflags) { /* Check for a socket exception. */ if (ssflags & SSF_EXCEPTION) { kill_conn(context, conn, selstate); return FALSE; } switch (conn->state) { case CONNECTING: assert(conn->service_connect != NULL); return conn->service_connect(context, realm, conn, selstate); case WRITING: assert(conn->service_write != NULL); return conn->service_write(context, realm, conn, selstate); case READING: assert(conn->service_read != NULL); return conn->service_read(context, realm, conn, selstate); default: abort(); } } /* Initialize TCP transport. */ static krb5_boolean service_tcp_connect(krb5_context context, const krb5_data *realm, struct conn_state *conn, struct select_state *selstate) { /* Check whether the connection succeeded. */ int e = get_so_error(conn->fd); if (e) { TRACE_SENDTO_KDC_TCP_ERROR_CONNECT(context, &conn->addr, e); kill_conn(context, conn, selstate); return FALSE; } conn->state = WRITING; return conn->service_write(context, realm, conn, selstate); } /* Sets conn->state to READING when done. */ static krb5_boolean service_tcp_write(krb5_context context, const krb5_data *realm, struct conn_state *conn, struct select_state *selstate) { ssize_t nwritten; SOCKET_WRITEV_TEMP tmp; TRACE_SENDTO_KDC_TCP_SEND(context, &conn->addr); nwritten = SOCKET_WRITEV(conn->fd, conn->out.sgp, conn->out.sg_count, tmp); if (nwritten < 0) { TRACE_SENDTO_KDC_TCP_ERROR_SEND(context, &conn->addr, SOCKET_ERRNO); kill_conn(context, conn, selstate); return FALSE; } while (nwritten) { sg_buf *sgp = conn->out.sgp; if ((size_t)nwritten < SG_LEN(sgp)) { SG_ADVANCE(sgp, (size_t)nwritten); nwritten = 0; } else { nwritten -= SG_LEN(sgp); conn->out.sgp++; conn->out.sg_count--; } } if (conn->out.sg_count == 0) { /* Done writing, switch to reading. */ cm_read(selstate, conn->fd); conn->state = READING; } return FALSE; } /* Return true on usable data. */ static krb5_boolean service_tcp_read(krb5_context context, const krb5_data *realm, struct conn_state *conn, struct select_state *selstate) { ssize_t nread; int e = 0; struct incoming_message *in = &conn->in; if (in->bufsizebytes_read == 4) { /* Reading data. */ nread = SOCKET_READ(conn->fd, &in->buf[in->pos], in->n_left); if (nread <= 0) { e = nread ? SOCKET_ERRNO : ECONNRESET; TRACE_SENDTO_KDC_TCP_ERROR_RECV(context, &conn->addr, e); kill_conn(context, conn, selstate); return FALSE; } in->n_left -= nread; in->pos += nread; if (in->n_left <= 0) return TRUE; } else { /* Reading length. */ nread = SOCKET_READ(conn->fd, in->bufsizebytes + in->bufsizebytes_read, 4 - in->bufsizebytes_read); if (nread <= 0) { e = nread ? SOCKET_ERRNO : ECONNRESET; TRACE_SENDTO_KDC_TCP_ERROR_RECV_LEN(context, &conn->addr, e); kill_conn(context, conn, selstate); return FALSE; } in->bufsizebytes_read += nread; if (in->bufsizebytes_read == 4) { unsigned long len = load_32_be(in->bufsizebytes); /* Arbitrary 1M cap. */ if (len > 1 * 1024 * 1024) { kill_conn(context, conn, selstate); return FALSE; } in->bufsize = in->n_left = len; in->pos = 0; in->buf = malloc(len); if (in->buf == NULL) { kill_conn(context, conn, selstate); return FALSE; } } } return FALSE; } /* Process events on a UDP socket. Return true if we get a reply. */ static krb5_boolean service_udp_read(krb5_context context, const krb5_data *realm, struct conn_state *conn, struct select_state *selstate) { int nread; nread = recv(conn->fd, conn->in.buf, conn->in.bufsize, 0); if (nread < 0) { TRACE_SENDTO_KDC_UDP_ERROR_RECV(context, &conn->addr, SOCKET_ERRNO); kill_conn(context, conn, selstate); return FALSE; } conn->in.pos = nread; return TRUE; } /* Set up conn->http.tls. Return true on success. */ static krb5_boolean setup_tls(krb5_context context, const krb5_data *realm, struct conn_state *conn, struct select_state *selstate) { krb5_error_code ret; krb5_boolean ok = FALSE; char **anchors = NULL, *realmstr = NULL; const char *names[4]; if (init_tls_vtable(context) != 0 || context->tls->setup == NULL) return FALSE; realmstr = k5memdup0(realm->data, realm->length, &ret); if (realmstr == NULL) goto cleanup; /* Load the configured anchors. */ names[0] = KRB5_CONF_REALMS; names[1] = realmstr; names[2] = KRB5_CONF_HTTP_ANCHORS; names[3] = NULL; ret = profile_get_values(context->profile, names, &anchors); if (ret != 0 && ret != PROF_NO_RELATION) goto cleanup; if (context->tls->setup(context, conn->fd, conn->http.servername, anchors, &conn->http.tls) != 0) { TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(context, &conn->addr); goto cleanup; } ok = TRUE; cleanup: free(realmstr); profile_free_list(anchors); return ok; } /* Set conn->state to READING when done; otherwise, call a cm_set_. */ static krb5_boolean service_https_write(krb5_context context, const krb5_data *realm, struct conn_state *conn, struct select_state *selstate) { k5_tls_status st; /* If this is our first time in here, set up the SSL context. */ if (conn->http.tls == NULL && !setup_tls(context, realm, conn, selstate)) { kill_conn(context, conn, selstate); return FALSE; } /* Try to transmit our request to the server. */ st = context->tls->write(context, conn->http.tls, SG_BUF(conn->out.sgp), SG_LEN(conn->out.sgbuf)); if (st == DONE) { TRACE_SENDTO_KDC_HTTPS_SEND(context, &conn->addr); cm_read(selstate, conn->fd); conn->state = READING; } else if (st == WANT_READ) { cm_read(selstate, conn->fd); } else if (st == WANT_WRITE) { cm_write(selstate, conn->fd); } else if (st == ERROR_TLS) { TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(context, &conn->addr); kill_conn(context, conn, selstate); } return FALSE; } /* Return true on finished data. Call a cm_read/write function and return * false if the TLS layer needs it. Kill the connection on error. */ static krb5_boolean https_read_bytes(krb5_context context, struct conn_state *conn, struct select_state *selstate) { size_t bufsize, nread; k5_tls_status st; char *tmp; struct incoming_message *in = &conn->in; for (;;) { if (in->buf == NULL || in->bufsize - in->pos < 1024) { bufsize = in->bufsize ? in->bufsize * 2 : 8192; if (bufsize > 1024 * 1024) { kill_conn(context, conn, selstate); return FALSE; } tmp = realloc(in->buf, bufsize); if (tmp == NULL) { kill_conn(context, conn, selstate); return FALSE; } in->buf = tmp; in->bufsize = bufsize; } st = context->tls->read(context, conn->http.tls, &in->buf[in->pos], in->bufsize - in->pos - 1, &nread); if (st != DATA_READ) break; in->pos += nread; in->buf[in->pos] = '\0'; } if (st == DONE) return TRUE; if (st == WANT_READ) { cm_read(selstate, conn->fd); } else if (st == WANT_WRITE) { cm_write(selstate, conn->fd); } else if (st == ERROR_TLS) { TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(context, &conn->addr); kill_conn(context, conn, selstate); } return FALSE; } /* Return true on readable, valid KKDCPP data. */ static krb5_boolean service_https_read(krb5_context context, const krb5_data *realm, struct conn_state *conn, struct select_state *selstate) { krb5_kkdcp_message *pm = NULL; krb5_data buf; const char *rep; struct incoming_message *in = &conn->in; /* Read data through the encryption layer. */ if (!https_read_bytes(context, conn, selstate)) return FALSE; /* Find the beginning of the response body. */ rep = strstr(in->buf, "\r\n\r\n"); if (rep == NULL) goto kill_conn; rep += 4; /* Decode the response. */ buf = make_data((char *)rep, in->pos - (rep - in->buf)); if (decode_krb5_kkdcp_message(&buf, &pm) != 0) goto kill_conn; /* Check and discard the message length at the front of the kerb_message * field after decoding. If it's wrong or missing, something broke. */ if (pm->kerb_message.length < 4 || load_32_be(pm->kerb_message.data) != pm->kerb_message.length - 4) { goto kill_conn; } /* Replace all of the content that we read back with just the message. */ memcpy(in->buf, pm->kerb_message.data + 4, pm->kerb_message.length - 4); in->pos = pm->kerb_message.length - 4; k5_free_kkdcp_message(context, pm); return TRUE; kill_conn: TRACE_SENDTO_KDC_HTTPS_ERROR(context, in->buf); k5_free_kkdcp_message(context, pm); kill_conn(context, conn, selstate); return FALSE; } /* Return true if conns contains any states with connected TCP sockets. */ static krb5_boolean any_tcp_connections(struct conn_state *conns) { struct conn_state *state; for (state = conns; state != NULL; state = state->next) { if (state->addr.transport != UDP && (state->state == READING || state->state == WRITING)) return TRUE; } return FALSE; } static krb5_boolean service_fds(krb5_context context, struct select_state *selstate, time_ms interval, time_ms timeout, struct conn_state *conns, struct select_state *seltemp, const krb5_data *realm, int (*msg_handler)(krb5_context, const krb5_data *, void *), void *msg_handler_data, struct conn_state **winner_out) { int e, selret = 0; time_ms curtime, interval_end, endtime; struct conn_state *state; *winner_out = NULL; e = get_curtime_ms(&curtime); if (e) return TRUE; interval_end = curtime + interval; e = 0; while (selstate->nfds > 0) { endtime = any_tcp_connections(conns) ? 0 : interval_end; /* Don't wait longer than the whole request should last. */ if (timeout && (!endtime || endtime > timeout)) endtime = timeout; e = cm_select_or_poll(selstate, endtime, seltemp, &selret); if (e == EINTR) continue; if (e != 0) break; if (selret == 0) { /* We timed out. Stop if we hit the overall request timeout. */ if (timeout && (get_curtime_ms(&curtime) || curtime >= timeout)) return TRUE; /* Otherwise return to the caller to send the next request. */ return FALSE; } /* Got something on a socket, process it. */ for (state = conns; state != NULL; state = state->next) { int ssflags; if (state->fd == INVALID_SOCKET) continue; ssflags = cm_get_ssflags(seltemp, state->fd); if (!ssflags) continue; if (service_dispatch(context, realm, state, selstate, ssflags)) { int stop = 1; if (msg_handler != NULL) { krb5_data reply = make_data(state->in.buf, state->in.pos); if (!msg_handler(context, &reply, msg_handler_data)) { kill_conn(context, state, selstate); stop = 0; } } if (stop) { *winner_out = state; return TRUE; } } } } if (e != 0) return TRUE; return FALSE; } /* * Current timeout behavior when no request_timeout is set: * * First pass, 1s per udp or tcp server, plus 2s at end. * Second pass, 1s per udp server, plus 4s. * Third pass, 1s per udp server, plus 8s. * Fourth => 16s, etc. * * Restated: * Per UDP server, 1s per pass. * Per TCP server, 1s. * Backoff delay, 2**(P+1) - 2, where P is total number of passes. * * Total = 2**(P+1) + U*P + T - 2. * * If P=3, Total = 3*U + T + 14. * If P=4, Total = 4*U + T + 30. * * Note that if you try to reach two ports on one server, it counts as two. * * If a TCP connection is established, we wait on it indefinitely (or until * request_timeout has elapsed) and do not attempt to contact additional * servers. */ krb5_error_code k5_sendto(krb5_context context, const krb5_data *message, const krb5_data *realm, const struct serverlist *servers, k5_transport_strategy strategy, struct sendto_callback_info* callback_info, krb5_data *reply, struct sockaddr *remoteaddr, socklen_t *remoteaddrlen, int *server_used, /* return 0 -> keep going, 1 -> quit */ int (*msg_handler)(krb5_context, const krb5_data *, void *), void *msg_handler_data) { int pass; time_ms delay, timeout = 0; krb5_error_code retval; struct conn_state *conns = NULL, *state, **tailptr, *next, *winner; size_t s; struct select_state *sel_state = NULL, *seltemp; char *udpbuf = NULL; krb5_boolean done = FALSE; *reply = empty_data(); if (context->req_timeout) { retval = get_curtime_ms(&timeout); if (retval) return retval; timeout += 1000 * context->req_timeout; } /* One for use here, listing all our fds in use, and one for * temporary use in service_fds, for the fds of interest. */ sel_state = malloc(2 * sizeof(*sel_state)); if (sel_state == NULL) { retval = ENOMEM; goto cleanup; } seltemp = &sel_state[1]; cm_init_selstate(sel_state); /* First pass: resolve server hosts, communicate with resulting addresses * of the preferred transport, and wait 1s for an answer from each. */ for (s = 0; s < servers->nservers && !done; s++) { /* Find the current tail pointer. */ for (tailptr = &conns; *tailptr != NULL; tailptr = &(*tailptr)->next); retval = resolve_server(context, realm, servers, s, strategy, message, &udpbuf, &conns); if (retval) goto cleanup; for (state = *tailptr; state != NULL && !done; state = state->next) { /* Contact each new connection, deferring those which use the * non-preferred RFC 4120 transport. */ if (state->defer) continue; if (maybe_send(context, state, message, sel_state, realm, callback_info)) continue; done = service_fds(context, sel_state, 1000, timeout, conns, seltemp, realm, msg_handler, msg_handler_data, &winner); } } /* Complete the first pass by contacting servers of the non-preferred RFC * 4120 transport (if given), waiting 1s for an answer from each. */ for (state = conns; state != NULL && !done; state = state->next) { if (!state->defer) continue; if (maybe_send(context, state, message, sel_state, realm, callback_info)) continue; done = service_fds(context, sel_state, 1000, timeout, conns, seltemp, realm, msg_handler, msg_handler_data, &winner); } /* Wait for two seconds at the end of the first pass. */ if (!done) { done = service_fds(context, sel_state, 2000, timeout, conns, seltemp, realm, msg_handler, msg_handler_data, &winner); } /* Make remaining passes over all of the connections. */ delay = 4000; for (pass = 1; pass < MAX_PASS && !done; pass++) { for (state = conns; state != NULL && !done; state = state->next) { if (maybe_send(context, state, message, sel_state, realm, callback_info)) continue; done = service_fds(context, sel_state, 1000, timeout, conns, seltemp, realm, msg_handler, msg_handler_data, &winner); if (sel_state->nfds == 0) break; } /* Wait for the delay backoff at the end of this pass. */ if (!done) { done = service_fds(context, sel_state, delay, timeout, conns, seltemp, realm, msg_handler, msg_handler_data, &winner); } if (sel_state->nfds == 0) break; delay *= 2; } if (sel_state->nfds == 0 || !done || winner == NULL) { retval = KRB5_KDC_UNREACH; goto cleanup; } /* Success! */ *reply = make_data(winner->in.buf, winner->in.pos); retval = 0; winner->in.buf = NULL; if (server_used != NULL) *server_used = winner->server_index; if (remoteaddr != NULL && remoteaddrlen != 0 && *remoteaddrlen > 0) (void)getpeername(winner->fd, remoteaddr, remoteaddrlen); TRACE_SENDTO_KDC_RESPONSE(context, reply->length, &winner->addr); cleanup: for (state = conns; state != NULL; state = next) { next = state->next; if (state->fd != INVALID_SOCKET) { if (socktype_for_transport(state->addr.transport) == SOCK_STREAM) TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &state->addr); closesocket(state->fd); free_http_tls_data(context, state); } if (state->in.buf != udpbuf) free(state->in.buf); if (callback_info) { callback_info->pfn_cleanup(callback_info->data, &state->callback_buffer); } free(state); } if (reply->data != udpbuf) free(udpbuf); free(sel_state); return retval; } krb5-1.22.1/src/lib/krb5/os/hostrealm.c0000664000175000017500000003534715051422640017340 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/hostrealm.c - realm-of-host and default-realm APIs */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "os-proto.h" #include "fake-addrinfo.h" #include #include #if defined(_WIN32) && !defined(__CYGWIN32__) #ifndef EAFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT #endif #endif struct hostrealm_module_handle { struct krb5_hostrealm_vtable_st vt; krb5_hostrealm_moddata data; }; /* Release a list of hostrealm module handles. */ static void free_handles(krb5_context context, struct hostrealm_module_handle **handles) { struct hostrealm_module_handle *h, **hp; if (handles == NULL) return; for (hp = handles; *hp != NULL; hp++) { h = *hp; if (h->vt.fini != NULL) h->vt.fini(context, h->data); free(h); } free(handles); } /* Get the registered hostrealm modules including all built-in modules, in the * proper order. */ static krb5_error_code get_modules(krb5_context context, krb5_plugin_initvt_fn **modules_out) { krb5_error_code ret; const int intf = PLUGIN_INTERFACE_HOSTREALM; *modules_out = NULL; /* Register built-in modules. */ ret = k5_plugin_register(context, intf, "registry", hostrealm_registry_initvt); if (ret) return ret; ret = k5_plugin_register(context, intf, "profile", hostrealm_profile_initvt); if (ret) return ret; ret = k5_plugin_register(context, intf, "dns", hostrealm_dns_initvt); if (ret) return ret; ret = k5_plugin_register(context, intf, "domain", hostrealm_domain_initvt); if (ret) return ret; return k5_plugin_load_all(context, intf, modules_out); } /* Initialize context->hostrealm_handles with a list of module handles. */ static krb5_error_code load_hostrealm_modules(krb5_context context) { krb5_error_code ret; struct hostrealm_module_handle **list = NULL, *handle; krb5_plugin_initvt_fn *modules = NULL, *mod; size_t count; ret = get_modules(context, &modules); if (ret != 0) goto cleanup; /* Allocate a large enough list of handles. */ for (count = 0; modules[count] != NULL; count++); list = k5alloc((count + 1) * sizeof(*list), &ret); if (list == NULL) goto cleanup; /* Initialize each module, ignoring ones that fail. */ count = 0; for (mod = modules; *mod != NULL; mod++) { handle = k5alloc(sizeof(*handle), &ret); if (handle == NULL) goto cleanup; ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&handle->vt); if (ret != 0) { TRACE_HOSTREALM_VTINIT_FAIL(context, ret); free(handle); continue; } handle->data = NULL; if (handle->vt.init != NULL) { ret = handle->vt.init(context, &handle->data); if (ret != 0) { TRACE_HOSTREALM_INIT_FAIL(context, handle->vt.name, ret); free(handle); continue; } } list[count++] = handle; list[count] = NULL; } list[count] = NULL; ret = 0; context->hostrealm_handles = list; list = NULL; cleanup: k5_plugin_free_modules(context, modules); free_handles(context, list); return ret; } /* Invoke a module's host_realm method, if it has one. */ static krb5_error_code host_realm(krb5_context context, struct hostrealm_module_handle *h, const char *host, char ***realms_out) { if (h->vt.host_realm == NULL) return KRB5_PLUGIN_NO_HANDLE; return h->vt.host_realm(context, h->data, host, realms_out); } /* Invoke a module's fallback_realm method, if it has one. */ static krb5_error_code fallback_realm(krb5_context context, struct hostrealm_module_handle *h, const char *host, char ***realms_out) { if (h->vt.fallback_realm == NULL) return KRB5_PLUGIN_NO_HANDLE; return h->vt.fallback_realm(context, h->data, host, realms_out); } /* Invoke a module's default_realm method, if it has one. */ static krb5_error_code default_realm(krb5_context context, struct hostrealm_module_handle *h, char ***realms_out) { if (h->vt.default_realm == NULL) return KRB5_PLUGIN_NO_HANDLE; return h->vt.default_realm(context, h->data, realms_out); } /* Invoke a module's free_list method. */ static void free_list(krb5_context context, struct hostrealm_module_handle *h, char **list) { h->vt.free_list(context, h->data, list); } /* Copy a null-terminated list of strings. */ static krb5_error_code copy_list(char **in, char ***out) { size_t count, i; char **list; *out = NULL; for (count = 0; in[count] != NULL; count++); list = calloc(count + 1, sizeof(*list)); if (list == NULL) return ENOMEM; for (i = 0; i < count; i++) { list[i] = strdup(in[i]); if (list[i] == NULL) { krb5_free_host_realm(NULL, list); return ENOMEM; } } *out = list; return 0; } static krb5_error_code translate_gai_error(int num) { switch (num) { #ifdef EAI_ADDRFAMILY case EAI_ADDRFAMILY: return EAFNOSUPPORT; #endif case EAI_AGAIN: return EAGAIN; case EAI_BADFLAGS: return EINVAL; case EAI_FAIL: return KRB5_EAI_FAIL; case EAI_FAMILY: return EAFNOSUPPORT; case EAI_MEMORY: return ENOMEM; #if defined(EAI_NODATA) && EAI_NODATA != EAI_NONAME case EAI_NODATA: return KRB5_EAI_NODATA; #endif case EAI_NONAME: return KRB5_EAI_NONAME; #if defined(EAI_OVERFLOW) case EAI_OVERFLOW: return EINVAL; /* XXX */ #endif case EAI_SERVICE: return KRB5_EAI_SERVICE; case EAI_SOCKTYPE: return EINVAL; #ifdef EAI_SYSTEM case EAI_SYSTEM: return errno; #endif } abort(); return -1; } /* Get the canonical form of the local host name, using forward * canonicalization only. */ krb5_error_code krb5int_get_fq_local_hostname(char **hostname_out) { struct addrinfo *ai, hints; char buf[MAXHOSTNAMELEN]; int err; *hostname_out = NULL; if (gethostname(buf, sizeof(buf)) == -1) return SOCKET_ERRNO; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; err = getaddrinfo(buf, NULL, &hints, &ai); if (err) return translate_gai_error(err); if (ai->ai_canonname == NULL) { freeaddrinfo(ai); return KRB5_EAI_FAIL; } *hostname_out = strdup(ai->ai_canonname); freeaddrinfo(ai); return (*hostname_out == NULL) ? ENOMEM : 0; } static krb5_error_code clean_hostname(krb5_context context, const char *host, char **cleanname_out) { char *p, *cleanname; krb5_error_code ret; size_t l; *cleanname_out = NULL; if (host != NULL) { cleanname = strdup(host); if (cleanname == NULL) return ENOMEM; } else { ret = krb5int_get_fq_local_hostname(&cleanname); if (ret) return ret; } /* Fold to lowercase. */ for (p = cleanname; *p; p++) { if (isupper((unsigned char)*p)) *p = tolower((unsigned char)*p); } /* Strip off trailing dot. */ l = strlen(cleanname); if (l > 0 && cleanname[l - 1] == '.') cleanname[l - 1] = '\0'; *cleanname_out = cleanname; return 0; } /* Return true if name appears to be an IPv4 or IPv6 address. */ krb5_boolean k5_is_numeric_address(const char *name) { int ndots = 0; const char *p; /* If name contains only numbers and three dots, consider it to be an IPv4 * address. */ if (strspn(name, "01234567890.") == strlen(name)) { for (p = name; *p; p++) { if (*p == '.') ndots++; } if (ndots == 3) return TRUE; } /* If name contains a colon, consider it to be an IPv6 address. */ if (strchr(name, ':') != NULL) return TRUE; return FALSE; } /* Construct a one-element realm list containing a copy of realm. */ krb5_error_code k5_make_realmlist(const char *realm, char ***realms_out) { char **realms; *realms_out = NULL; realms = calloc(2, sizeof(*realms)); if (realms == NULL) return ENOMEM; realms[0] = strdup(realm); if (realms[0] == NULL) { free(realms); return ENOMEM; } *realms_out = realms; return 0; } krb5_error_code KRB5_CALLCONV krb5_get_host_realm(krb5_context context, const char *host, char ***realms_out) { krb5_error_code ret; struct hostrealm_module_handle **hp; char **realms, *cleanname = NULL; *realms_out = NULL; if (context->hostrealm_handles == NULL) { ret = load_hostrealm_modules(context); if (ret) goto cleanup; } ret = clean_hostname(context, host, &cleanname); if (ret) goto cleanup; /* Give each module a chance to determine the host's realms. */ for (hp = context->hostrealm_handles; *hp != NULL; hp++) { ret = host_realm(context, *hp, cleanname, &realms); if (ret == 0) { ret = copy_list(realms, realms_out); free_list(context, *hp, realms); goto cleanup; } else if (ret != KRB5_PLUGIN_NO_HANDLE) { goto cleanup; } } /* Return a list containing the "referral realm" (an empty realm), as a * cue to try referrals. */ ret = k5_make_realmlist(KRB5_REFERRAL_REALM, realms_out); cleanup: free(cleanname); return ret; } krb5_error_code KRB5_CALLCONV krb5_get_fallback_host_realm(krb5_context context, krb5_data *hdata, char ***realms_out) { krb5_error_code ret; struct hostrealm_module_handle **hp; char **realms, *defrealm, *host, *cleanname = NULL; *realms_out = NULL; /* Convert hdata into a string and clean it. */ host = k5memdup0(hdata->data, hdata->length, &ret); if (host == NULL) goto cleanup; ret = clean_hostname(context, host, &cleanname); free(host); if (ret) goto cleanup; if (context->hostrealm_handles == NULL) { ret = load_hostrealm_modules(context); if (ret) goto cleanup; } /* Give each module a chance to determine the fallback realms. */ for (hp = context->hostrealm_handles; *hp != NULL; hp++) { ret = fallback_realm(context, *hp, cleanname, &realms); if (ret == 0) { ret = copy_list(realms, realms_out); free_list(context, *hp, realms); goto cleanup; } else if (ret != KRB5_PLUGIN_NO_HANDLE) { goto cleanup; } } /* Return a list containing the default realm. */ ret = krb5_get_default_realm(context, &defrealm); if (ret) goto cleanup; ret = k5_make_realmlist(defrealm, realms_out); krb5_free_default_realm(context, defrealm); cleanup: free(cleanname); return ret; } krb5_error_code KRB5_CALLCONV krb5_free_host_realm(krb5_context context, char *const *list) { char *const *p; for (p = list; p != NULL && *p != NULL; p++) free(*p); free((char **)list); return 0; } /* Get the system default realm using hostrealm modules. */ static krb5_error_code get_default_realm(krb5_context context, char **realm_out) { krb5_error_code ret; struct hostrealm_module_handle **hp; char **realms; *realm_out = NULL; if (context->hostrealm_handles == NULL) { ret = load_hostrealm_modules(context); if (ret) return ret; } /* Give each module a chance to determine the default realm. */ for (hp = context->hostrealm_handles; *hp != NULL; hp++) { ret = default_realm(context, *hp, &realms); if (ret == 0) { if (*realms == NULL) { ret = KRB5_CONFIG_NODEFREALM; } else { *realm_out = strdup(realms[0]); if (*realm_out == NULL) ret = ENOMEM; } free_list(context, *hp, realms); return ret; } else if (ret != KRB5_PLUGIN_NO_HANDLE) { return ret; } } return KRB5_CONFIG_NODEFREALM; } krb5_error_code KRB5_CALLCONV krb5_get_default_realm(krb5_context context, char **realm_out) { krb5_error_code ret; *realm_out = NULL; if (context == NULL || context->magic != KV5M_CONTEXT) return KV5M_CONTEXT; if (context->default_realm == NULL) { ret = get_default_realm(context, &context->default_realm); if (ret) return ret; } *realm_out = strdup(context->default_realm); return (*realm_out == NULL) ? ENOMEM : 0; } krb5_error_code KRB5_CALLCONV krb5_set_default_realm(krb5_context context, const char *realm) { if (context == NULL || context->magic != KV5M_CONTEXT) return KV5M_CONTEXT; if (context->default_realm != NULL) { free(context->default_realm); context->default_realm = NULL; } /* Allow the caller to clear the default realm setting by passing NULL. */ if (realm != NULL) { context->default_realm = strdup(realm); if (context->default_realm == NULL) return ENOMEM; } return 0; } void KRB5_CALLCONV krb5_free_default_realm(krb5_context context, char *realm) { free(realm); } void k5_hostrealm_free_context(krb5_context context) { free_handles(context, context->hostrealm_handles); context->hostrealm_handles = NULL; } krb5-1.22.1/src/lib/krb5/os/ustime.c0000664000175000017500000000563115051422640016641 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/ustime.c */ /* * Copyright 1990,1991,2007 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * krb5_crypto_us_timeofday() does all of the real work; however, we * handle the time offset adjustment here, since this is context * specific, and the crypto version of this call doesn't have access * to the context variable. Fortunately the only user of * krb5_crypto_us_timeofday in the crypto library doesn't require that * this time adjustment be done. */ #include "k5-int.h" #include "os-proto.h" krb5_error_code k5_time_with_offset(krb5_timestamp offset, krb5_int32 offset_usec, krb5_timestamp *time_out, krb5_int32 *usec_out) { krb5_timestamp sec; krb5_int32 usec; krb5_error_code retval; retval = krb5_crypto_us_timeofday(&sec, &usec); if (retval) return retval; usec += offset_usec; if (usec > 1000000) { usec -= 1000000; sec = ts_incr(sec, 1); } if (usec < 0) { usec += 1000000; sec = ts_incr(sec, -1); } sec = ts_incr(sec, offset); *time_out = sec; *usec_out = usec; return 0; } krb5_error_code KRB5_CALLCONV krb5_us_timeofday(krb5_context context, krb5_timestamp *seconds, krb5_int32 *microseconds) { krb5_os_context os_ctx = &context->os_context; if (os_ctx->os_flags & KRB5_OS_TOFFSET_TIME) { *seconds = os_ctx->time_offset; *microseconds = os_ctx->usec_offset; return 0; } else if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) { return k5_time_with_offset(os_ctx->time_offset, os_ctx->usec_offset, seconds, microseconds); } else { return krb5_crypto_us_timeofday(seconds, microseconds); } } krb5-1.22.1/src/lib/krb5/os/dnssrv.c0000664000175000017500000002447515051422640016661 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/dnssrv.c - Perform DNS SRV queries */ /* * Copyright 1990,2000,2001,2002,2003 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "autoconf.h" #ifdef KRB5_DNS_LOOKUP #include "k5-int.h" #include "os-proto.h" /* * Lookup a KDC via DNS SRV records */ void krb5int_free_srv_dns_data (struct srv_dns_entry *p) { struct srv_dns_entry *next; while (p) { next = p->next; free(p->host); free(p); p = next; } } /* Construct a DNS label of the form "service.[protocol.]realm.". protocol may * and/or sitename be NULL. */ static char * make_lookup_name(const krb5_data *realm, const char *service, const char *protocol, const char *sitename) { struct k5buf buf; if (memchr(realm->data, 0, realm->length)) return NULL; k5_buf_init_dynamic(&buf); k5_buf_add_fmt(&buf, "%s.", service); if (protocol != NULL) k5_buf_add_fmt(&buf, "%s.", protocol); if (sitename != NULL) k5_buf_add_fmt(&buf, "%s._sites.", sitename); k5_buf_add_len(&buf, realm->data, realm->length); /* * Realm names don't (normally) end with ".", but if the query doesn't end * with "." and doesn't get an answer as is, the resolv code will try * appending the local domain. Since the realm names are absolutes, let's * stop that. */ if (buf.len > 0 && ((char *)buf.data)[buf.len - 1] != '.') k5_buf_add(&buf, "."); return k5_buf_cstring(&buf); } /* Insert new into the list *head, ordering by priority. Weight is not * currently used. */ static void place_srv_entry(struct srv_dns_entry **head, struct srv_dns_entry *new) { struct srv_dns_entry *entry; if (*head == NULL || (*head)->priority > new->priority) { new->next = *head; *head = new; return; } for (entry = *head; entry != NULL; entry = entry->next) { /* * Insert an entry into the next spot if there is no next entry (we're * at the end), or if the next entry has a higher priority (lower * priorities are preferred). */ if (entry->next == NULL || entry->next->priority > new->priority) { new->next = entry->next; entry->next = new; break; } } } #ifdef _WIN32 #include krb5_error_code k5_make_uri_query(krb5_context context, const krb5_data *realm, const char *service, const char *sitename, struct srv_dns_entry **answers) { /* Windows does not currently support the URI record type or make it * possible to query for a record type it does not have support for. */ *answers = NULL; return 0; } krb5_error_code krb5int_make_srv_query_realm(krb5_context context, const krb5_data *realm, const char *service, const char *protocol, const char *sitename, struct srv_dns_entry **answers) { char *name = NULL; DNS_STATUS st; PDNS_RECORD records, rr; struct srv_dns_entry *head = NULL, *srv = NULL; *answers = NULL; name = make_lookup_name(realm, service, protocol, sitename); if (name == NULL) return 0; TRACE_DNS_SRV_SEND(context, name); st = DnsQuery_UTF8(name, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &records, NULL); if (st != ERROR_SUCCESS && sitename != NULL) { /* Try again without the site name. */ free(name); return krb5int_make_srv_query_realm(context, realm, service, protocol, NULL, answers); } if (st != ERROR_SUCCESS) return 0; for (rr = records; rr != NULL; rr = rr->pNext) { if (rr->wType != DNS_TYPE_SRV) continue; srv = malloc(sizeof(struct srv_dns_entry)); if (srv == NULL) goto cleanup; srv->priority = rr->Data.SRV.wPriority; srv->weight = rr->Data.SRV.wWeight; srv->port = rr->Data.SRV.wPort; /* Make sure the name looks fully qualified to the resolver. */ if (asprintf(&srv->host, "%s.", rr->Data.SRV.pNameTarget) < 0) { free(srv); goto cleanup; } TRACE_DNS_SRV_ANS(context, srv->host, srv->port, srv->priority, srv->weight); place_srv_entry(&head, srv); } cleanup: free(name); if (records != NULL) DnsRecordListFree(records, DnsFreeRecordList); *answers = head; return 0; } #else /* _WIN32 */ #include "dnsglue.h" /* Query the URI RR, collecting weight, priority, and target. */ krb5_error_code k5_make_uri_query(krb5_context context, const krb5_data *realm, const char *service, const char *sitename, struct srv_dns_entry **answers) { const unsigned char *p = NULL, *base = NULL; char *name = NULL; int size, ret, rdlen; unsigned short priority, weight; struct krb5int_dns_state *ds = NULL; struct srv_dns_entry *head = NULL, *uri = NULL; *answers = NULL; /* Construct service.realm. */ name = make_lookup_name(realm, service, NULL, sitename); if (name == NULL) return 0; TRACE_DNS_URI_SEND(context, name); size = krb5int_dns_init(&ds, name, C_IN, T_URI); if (size < 0 && sitename != NULL) { /* Try again without the site name. */ free(name); return k5_make_uri_query(context, realm, service, NULL, answers); } if (size < 0) goto out; for (;;) { ret = krb5int_dns_nextans(ds, &base, &rdlen); if (ret < 0 || base == NULL) goto out; p = base; SAFE_GETUINT16(base, rdlen, p, 2, priority, out); SAFE_GETUINT16(base, rdlen, p, 2, weight, out); uri = k5alloc(sizeof(*uri), &ret); if (uri == NULL) goto out; uri->priority = priority; uri->weight = weight; /* rdlen - 4 bytes remain after the priority and weight. */ uri->host = k5memdup0(p, rdlen - 4, &ret); if (uri->host == NULL) { free(uri); goto out; } TRACE_DNS_URI_ANS(context, uri->host, uri->priority, uri->weight); place_srv_entry(&head, uri); } out: krb5int_dns_fini(ds); free(name); *answers = head; return 0; } /* * Do DNS SRV query, return results in *answers. * * Make a best effort to return all the data we can. On memory or decoding * errors, just return what we've got. Always return 0, currently. */ krb5_error_code krb5int_make_srv_query_realm(krb5_context context, const krb5_data *realm, const char *service, const char *protocol, const char *sitename, struct srv_dns_entry **answers) { const unsigned char *p = NULL, *base = NULL; char *name = NULL, host[MAXDNAME]; int size, ret, rdlen, nlen; unsigned short priority, weight, port; struct krb5int_dns_state *ds = NULL; struct srv_dns_entry *head = NULL, *srv = NULL; /* * First off, build a query of the form: * * service.protocol.realm * * which will most likely be something like: * * _kerberos._udp.REALM * */ name = make_lookup_name(realm, service, protocol, sitename); if (name == NULL) return 0; TRACE_DNS_SRV_SEND(context, name); size = krb5int_dns_init(&ds, name, C_IN, T_SRV); if (size < 0 && sitename) { /* Try again without the site name. */ free(name); return krb5int_make_srv_query_realm(context, realm, service, protocol, NULL, answers); } if (size < 0) goto out; for (;;) { ret = krb5int_dns_nextans(ds, &base, &rdlen); if (ret < 0 || base == NULL) goto out; p = base; SAFE_GETUINT16(base, rdlen, p, 2, priority, out); SAFE_GETUINT16(base, rdlen, p, 2, weight, out); SAFE_GETUINT16(base, rdlen, p, 2, port, out); /* * RFC 2782 says the target is never compressed in the reply; * do we believe that? We need to flatten it anyway, though. */ nlen = krb5int_dns_expand(ds, p, host, sizeof(host)); if (nlen < 0 || !INCR_OK(base, rdlen, p, nlen)) goto out; /* * We got everything! Insert it into our list, but make sure * it's in the right order. Right now we don't do anything * with the weight field */ srv = malloc(sizeof(struct srv_dns_entry)); if (srv == NULL) goto out; srv->priority = priority; srv->weight = weight; srv->port = port; /* The returned names are fully qualified. Don't let the * local resolver code do domain search path stuff. */ if (asprintf(&srv->host, "%s.", host) < 0) { free(srv); goto out; } TRACE_DNS_SRV_ANS(context, srv->host, srv->port, srv->priority, srv->weight); place_srv_entry(&head, srv); } out: krb5int_dns_fini(ds); free(name); *answers = head; return 0; } #endif /* not _WIN32 */ #endif /* KRB5_DNS_LOOKUP */ krb5-1.22.1/src/lib/krb5/os/t_discover_uri.py0000664000175000017500000000326215051422640020557 0ustar ghudsonghudsonfrom k5test import * entries = ('URI _kerberos.TEST krb5srv::kkdcp:https://kdc1 1 1\n', 'URI _kerberos.TEST krb5srv::kkdcp:https://kdc3:300/path 3 1\n', 'URI _kerberos.TEST krb5srv:m:kkdcp:https://kdc2/path 2 1\n', 'URI _kerberos.TEST KRB5SRV:xMz:UDP:KDC4 4 1\n', 'URI _kerberos.TEST krb5srv:xyz:tcp:192.168.1.6 6 1\n', 'URI _kerberos.TEST krb5srv::tcp:kdc5:500 5 1\n', 'URI _kerberos.TEST krb5srv::tcp:[dead:beef:cafe:7]:700 7 1\n', 'URI _kerberos.TEST bogustag:m:kkdcp:https://bogus 8 1\n', 'URI _kerberos.TEST krb5srv:m:bogustrans:https://bogus 10 1\n', 'URI _kerberos.TEST krb5srv:m:kkdcp:bogus 11 1\n', 'URI _kerberos.TEST krb5srv:m:bogusnotrans 12 1\n') expected = ('7 servers:', '0: h:kdc1 t:https p:443 m:0 P:', '1: h:kdc2 t:https p:443 m:1 P:path', '2: h:kdc3 t:https p:300 m:0 P:path', '3: h:KDC4 t:udp p:88 m:1 P:', '4: h:kdc5 t:tcp p:500 m:0 P:', '5: h:192.168.1.6 t:tcp p:88 m:0 P:', '6: h:dead:beef:cafe:7 t:tcp p:700 m:0 P:') conf = {'libdefaults': {'dns_lookup_kdc' : 'true'}} realm = K5Realm(create_kdb=False, krb5_conf=conf) hosts_filename = os.path.join(realm.testdir, 'resolv_hosts') f = open(hosts_filename, 'w') for line in entries: f.write(line) f.close() realm.env['LD_PRELOAD'] = 'libresolv_wrapper.so' realm.env['RESOLV_WRAPPER_HOSTS'] = hosts_filename out = realm.run(['./t_locate_kdc', 'TEST'], env=realm.env) l = out.splitlines() j = 0 for i in range(4, 12): if l[i].strip() != expected[j]: fail('URI answers do not match') j += 1 success('uri discovery tests') krb5-1.22.1/src/lib/krb5/os/localauth_k5login.c0000664000175000017500000001314415051422640020735 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/localauth_k5login.c - k5login localauth module */ /* * Copyright (C) 1990,1993,2007,2013 by the Massachusetts Institute * of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "os-proto.h" #include #if !defined(_WIN32) /* Not yet for Windows */ #include #if defined(__APPLE__) && defined(__MACH__) #include #define FILE_OWNER_OK(UID) ((UID) == 0 || (UID) == UNKNOWNUID) #else #define FILE_OWNER_OK(UID) ((UID) == 0) #endif /* * Find the k5login filename for luser, either in the user's homedir or in a * configured directory under the username. */ static krb5_error_code get_k5login_filename(krb5_context context, const char *lname, const char *homedir, char **filename_out) { krb5_error_code ret; char *dir, *filename; *filename_out = NULL; ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_K5LOGIN_DIRECTORY, NULL, NULL, &dir); if (ret != 0) return ret; if (dir == NULL) { /* Look in the user's homedir. */ if (asprintf(&filename, "%s/.k5login", homedir) < 0) return ENOMEM; } else { /* Look in the configured directory. */ if (asprintf(&filename, "%s/%s", dir, lname) < 0) ret = ENOMEM; profile_release_string(dir); if (ret) return ret; } *filename_out = filename; return 0; } /* Determine whether aname is authorized to log in as lname according to the * user's k5login file. */ static krb5_error_code userok_k5login(krb5_context context, krb5_localauth_moddata data, krb5_const_principal aname, const char *lname) { krb5_error_code ret; int authoritative = TRUE, gobble; char *filename = NULL, *princname = NULL; char *newline, linebuf[BUFSIZ], pwbuf[BUFSIZ]; struct stat sbuf; struct passwd pwx, *pwd; FILE *fp = NULL; ret = profile_get_boolean(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_K5LOGIN_AUTHORITATIVE, NULL, TRUE, &authoritative); if (ret) goto cleanup; /* Get the local user's .k5login filename. */ ret = k5_getpwnam_r(lname, &pwx, pwbuf, sizeof(pwbuf), &pwd); if (ret) { ret = EPERM; goto cleanup; } ret = get_k5login_filename(context, lname, pwd->pw_dir, &filename); if (ret) goto cleanup; if (access(filename, F_OK) != 0) { ret = KRB5_PLUGIN_NO_HANDLE; goto cleanup; } ret = krb5_unparse_name(context, aname, &princname); if (ret) goto cleanup; fp = fopen(filename, "r"); if (fp == NULL) { ret = errno; goto cleanup; } set_cloexec_file(fp); /* For security reasons, the .k5login file must be owned either by * the user or by root. */ if (fstat(fileno(fp), &sbuf)) { ret = errno; goto cleanup; } if (sbuf.st_uid != pwd->pw_uid && !FILE_OWNER_OK(sbuf.st_uid)) { ret = EPERM; goto cleanup; } /* Check each line. */ while (fgets(linebuf, sizeof(linebuf), fp) != NULL) { newline = strrchr(linebuf, '\n'); if (newline != NULL) *newline = '\0'; if (strcmp(linebuf, princname) == 0) { ret = 0; goto cleanup; } /* Clean up the rest of the line if necessary. */ if (newline == NULL) while ((gobble = getc(fp)) != EOF && gobble != '\n'); } /* We didn't find it. */ ret = EPERM; cleanup: free(princname); free(filename); if (fp != NULL) fclose(fp); /* If k5login files are non-authoritative, never reject. */ return (!authoritative && ret) ? KRB5_PLUGIN_NO_HANDLE : ret; } #else /* _WIN32 */ static krb5_error_code userok_k5login(krb5_context context, krb5_localauth_moddata data, krb5_const_principal aname, const char *lname) { return KRB5_PLUGIN_NO_HANDLE; } #endif krb5_error_code localauth_k5login_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_localauth_vtable vt = (krb5_localauth_vtable)vtable; vt->name = "k5login"; vt->userok = userok_k5login; return 0; } krb5-1.22.1/src/lib/krb5/os/toffset.c0000664000175000017500000001002015051422640016771 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/toffset.c - Manipulate time offset fields in os context */ /* * Copyright 1995, 2007 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" /* * This routine takes the "real time" as input, and sets the time * offset field in the context structure so that the krb5 time * routines will return the correct time as corrected by difference * between the system time and the "real time" as passed to this * routine * * If the real time microseconds are given as -1 the caller doesn't * know the microseconds value so the usec offset is always zero. */ krb5_error_code KRB5_CALLCONV krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds) { krb5_os_context os_ctx = &context->os_context; krb5_timestamp sec; krb5_int32 usec; krb5_error_code retval; retval = krb5_crypto_us_timeofday(&sec, &usec); if (retval) return retval; os_ctx->time_offset = ts_delta(seconds, sec); os_ctx->usec_offset = (microseconds > -1) ? microseconds - usec : 0; os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) | KRB5_OS_TOFFSET_VALID); return 0; } /* * This routine sets the krb5 time routines so that they will return * the seconds and microseconds value as input to this function. This * is useful for running the krb5 routines through test suites */ krb5_error_code krb5_set_debugging_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds) { krb5_os_context os_ctx = &context->os_context; os_ctx->time_offset = seconds; os_ctx->usec_offset = microseconds; os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_VALID) | KRB5_OS_TOFFSET_TIME); return 0; } /* * This routine turns off the time correction fields, so that the krb5 * routines return the "natural" time. */ krb5_error_code krb5_use_natural_time(krb5_context context) { krb5_os_context os_ctx = &context->os_context; os_ctx->os_flags &= ~(KRB5_OS_TOFFSET_VALID|KRB5_OS_TOFFSET_TIME); return 0; } /* * This routine returns the current time offsets in use. */ krb5_error_code KRB5_CALLCONV krb5_get_time_offsets(krb5_context context, krb5_timestamp *seconds, krb5_int32 *microseconds) { krb5_os_context os_ctx = &context->os_context; if (seconds) *seconds = os_ctx->time_offset; if (microseconds) *microseconds = os_ctx->usec_offset; return 0; } /* * This routine sets the time offsets directly. */ krb5_error_code krb5_set_time_offsets(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds) { krb5_os_context os_ctx = &context->os_context; os_ctx->time_offset = seconds; os_ctx->usec_offset = microseconds; os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) | KRB5_OS_TOFFSET_VALID); return 0; } krb5-1.22.1/src/lib/krb5/os/mk_faddr.c0000664000175000017500000000510015051422640017071 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/mk_faddr.c - Generate full address from IP addr and port */ /* * Copyright 1995, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #ifdef HAVE_NETINET_IN_H #include "os-proto.h" #if !defined(_WINSOCKAPI_) #include #endif krb5_error_code krb5_make_fulladdr(krb5_context context, krb5_address *kaddr, krb5_address *kport, krb5_address *raddr) { krb5_octet *marshal; krb5_int32 tmp32; krb5_int16 tmp16; if (kaddr == NULL || kport == NULL) return EINVAL; raddr->length = kaddr->length + kport->length + (4 * sizeof(krb5_int32)); if (!(raddr->contents = (krb5_octet *)malloc(raddr->length))) return ENOMEM; raddr->addrtype = ADDRTYPE_ADDRPORT; marshal = raddr->contents; tmp16 = kaddr->addrtype; *marshal++ = 0x00; *marshal++ = 0x00; store_16_le(tmp16, marshal); marshal += 2; tmp32 = kaddr->length; store_32_le(tmp32, marshal); marshal += 4; (void) memcpy(marshal, kaddr->contents, kaddr->length); marshal += kaddr->length; tmp16 = kport->addrtype; *marshal++ = 0x00; *marshal++ = 0x00; store_16_le(tmp16, marshal); marshal += 2; tmp32 = kport->length; store_32_le(tmp32, marshal); marshal += 4; (void) memcpy(marshal, kport->contents, kport->length); marshal += kport->length; return 0; } #endif krb5-1.22.1/src/lib/krb5/os/lock_file.c0000664000175000017500000001162215051422640017257 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/lock_file.c */ /* * Copyright 1990, 1998 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include #if !defined(_WIN32) /* Unix version... */ #if HAVE_UNISTD_H #include #endif #include #ifdef HAVE_FCNTL_H #include #endif #if defined(HAVE_FCNTL_H) && defined(F_SETLKW) && defined(F_RDLCK) #define POSIX_FILE_LOCKS /* * Gnu libc bug 20251, fixed in 2.28, breaks OFD lock support on * 32-bit platforms. Work around this bug by explicitly using the * fcntl64 system call and struct flock64. */ #if defined(__linux__) && __WORDSIZE == 32 #include #ifdef SYS_fcntl64 #define USE_FCNTL64 #endif #endif #ifdef USE_FCNTL64 /* Use the fcntl64 system call and struct flock64. (Gnu libc does not * define a fcntl64() function, so we must use syscall().) */ #define fcntl(fd, cmd, arg) syscall(SYS_fcntl64, fd, cmd, arg) typedef struct flock64 fcntl_lock_st; #else /* Use regular fcntl() and struct flock. */ typedef struct flock fcntl_lock_st; #endif #endif /* defined(HAVE_FCNTL_H) && defined(F_SETLKW) && defined(F_RDLCK) */ #ifdef HAVE_FLOCK #ifndef sysvimp #include #endif #else #ifndef LOCK_SH #define LOCK_SH 0 #define LOCK_EX 0 #define LOCK_UN 0 #endif #endif #ifdef POSIX_FILE_LOCKS /* * Try to use OFD locks where available (e.g. Linux 3.15 and later). OFD locks * contend with regular POSIX file locks, but are owned by the open file * description instead of the process, which is much better for thread safety. * Fall back to regular POSIX locks on EINVAL in case we are running with an * older kernel than we were built with. */ static int ofdlock(int fd, int cmd, fcntl_lock_st *lock_arg) { #ifdef F_OFD_SETLKW int st, ofdcmd; assert(cmd == F_SETLKW || cmd == F_SETLK); ofdcmd = (cmd == F_SETLKW) ? F_OFD_SETLKW : F_OFD_SETLK; st = fcntl(fd, ofdcmd, lock_arg); if (st == 0 || errno != EINVAL) return st; #endif return fcntl(fd, cmd, lock_arg); } #endif /* POSIX_FILE_LOCKS */ /*ARGSUSED*/ krb5_error_code krb5_lock_file(krb5_context context, int fd, int mode) { int lock_flag = -1; krb5_error_code retval = 0; #ifdef POSIX_FILE_LOCKS int lock_cmd = F_SETLKW; fcntl_lock_st lock_arg = { 0 }; #endif switch (mode & ~KRB5_LOCKMODE_DONTBLOCK) { case KRB5_LOCKMODE_SHARED: #ifdef POSIX_FILE_LOCKS lock_arg.l_type = F_RDLCK; #endif lock_flag = LOCK_SH; break; case KRB5_LOCKMODE_EXCLUSIVE: #ifdef POSIX_FILE_LOCKS lock_arg.l_type = F_WRLCK; #endif lock_flag = LOCK_EX; break; case KRB5_LOCKMODE_UNLOCK: #ifdef POSIX_FILE_LOCKS lock_arg.l_type = F_UNLCK; #endif lock_flag = LOCK_UN; break; } if (lock_flag == -1) return(KRB5_LIBOS_BADLOCKFLAG); if (mode & KRB5_LOCKMODE_DONTBLOCK) { #ifdef POSIX_FILE_LOCKS lock_cmd = F_SETLK; #endif #ifdef HAVE_FLOCK lock_flag |= LOCK_NB; #endif } #ifdef POSIX_FILE_LOCKS lock_arg.l_whence = 0; lock_arg.l_start = 0; lock_arg.l_len = 0; if (ofdlock(fd, lock_cmd, &lock_arg) == -1) { if (errno == EACCES || errno == EAGAIN) /* see POSIX/IEEE 1003.1-1988, 6.5.2.4 */ return(EAGAIN); if (errno != EINVAL) /* Fall back to flock if we get EINVAL */ return(errno); retval = errno; } else return 0; /* We succeeded. Yay. */ #endif #ifdef HAVE_FLOCK if (flock(fd, lock_flag) == -1) retval = errno; #endif return retval; } #else /* Windows or Macintosh */ krb5_error_code krb5_lock_file(context, fd, mode) krb5_context context; int fd; int mode; { return 0; } #endif krb5-1.22.1/src/lib/krb5/os/gen_rname.c0000664000175000017500000000370615051422640017267 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/gen_rname.c */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Take a port-style address and unique string, and return * a replay cache tag string. */ #include "k5-int.h" #include "os-proto.h" krb5_error_code krb5_gen_replay_name(krb5_context context, const krb5_address *address, const char *uniq, char **string) { char * tmp; unsigned int i; unsigned int len; len = strlen(uniq) + (address->length * 2) + 1; if ((*string = malloc(len)) == NULL) return ENOMEM; snprintf(*string, len, "%s", uniq); tmp = *string + strlen(uniq); for (i = 0; i < address->length; i++) { snprintf(tmp, len - (tmp-*string), "%.2x", address->contents[i] & 0xff); tmp += 2; } return 0; } krb5-1.22.1/src/lib/krb5/os/os-proto.h0000664000175000017500000002570315051422640017124 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/os-proto.h */ /* * Copyright 1990,1991,2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * LIBOS internal function prototypes. */ #ifndef KRB5_LIBOS_INT_PROTO__ #define KRB5_LIBOS_INT_PROTO__ #ifdef HAVE_SYS_TIME_H #include #endif #include typedef enum { TCP_OR_UDP = 0, TCP, UDP, HTTPS, UNIXSOCK, } k5_transport; typedef enum { UDP_FIRST = 0, UDP_LAST, NO_UDP, ONLY_UDP } k5_transport_strategy; /* A single server hostname or address. */ struct server_entry { char *hostname; /* NULL -> use addrlen/addr instead */ int port; /* Used only if hostname set */ k5_transport transport; /* May be 0 for UDP/TCP if hostname set */ char *uri_path; /* Used only if transport is HTTPS */ int family; /* May be 0 (aka AF_UNSPEC) if hostname set */ int primary; /* True, false, or -1 for unknown. */ size_t addrlen; struct sockaddr_storage addr; }; /* A list of server hostnames/addresses. */ struct serverlist { struct server_entry *servers; size_t nservers; }; #define SERVERLIST_INIT { NULL, 0 } struct kdclist; struct remote_address { k5_transport transport; int family; socklen_t len; struct sockaddr_storage saddr; }; struct sendto_callback_info { int (*pfn_callback)(SOCKET fd, void *data, krb5_data *message); void (*pfn_cleanup)(void *data, krb5_data *message); void *data; }; /* * Initialize with all zeros except for princ. Set no_hostrealm to disable * host-to-realm lookup, which ordinarily happens during fallback processing * after canonicalizing the host part. Set subst_defrealm to substitute the * default realm for the referral realm after realm lookup. Do not set both * flags. Free with free_canonprinc() when done. * * no_hostrealm only applies if fallback processing is in use * (dns_canonicalize_hostname = fallback). It will not remove the realm if * krb5_sname_to_principal() already canonicalized the hostname and looked up a * realm. subst_defrealm applies whether or not fallback processing is in use. */ struct canonprinc { krb5_const_principal princ; krb5_boolean no_hostrealm; krb5_boolean subst_defrealm; int step; char *canonhost; char *realm; krb5_principal_data copy; krb5_data components[2]; }; /* Yield one or two candidate canonical principal names for iter, then NULL. * Output names are valid for one iteration and must not be freed. */ krb5_error_code k5_canonprinc(krb5_context context, struct canonprinc *iter, krb5_const_principal *princ_out); static inline void free_canonprinc(struct canonprinc *iter) { free(iter->canonhost); free(iter->realm); } krb5_error_code k5_expand_hostname(krb5_context context, const char *host, krb5_boolean is_fallback, char **canonhost_out); krb5_error_code k5_locate_server(krb5_context, const krb5_data *realm, struct serverlist *serverlist, enum locate_service_type svc, krb5_boolean no_udp); krb5_error_code k5_locate_kdc(krb5_context context, const krb5_data *realm, struct serverlist *serverlist, krb5_boolean get_primaries, krb5_boolean no_udp); void k5_free_serverlist(struct serverlist *); /* Create an object for remembering a history of KDCs contacted during an * exchange. */ krb5_error_code k5_kdclist_create(struct kdclist **kdcs_out); /* Add a server entry to kdcs. Transfer ownership of memory from *server and * zero it. */ krb5_error_code k5_kdclist_add(struct kdclist *kdcs, const krb5_data *realm, struct server_entry *server); /* Return true if any KDC entries in kdcs are replicas, looking up realms' * primary KDCs as necessary. */ krb5_boolean k5_kdclist_any_replicas(krb5_context context, struct kdclist *kdcs); void k5_kdclist_free(struct kdclist *kdcs); #ifdef HAVE_NETINET_IN_H krb5_error_code krb5_unpack_full_ipaddr(krb5_context, const krb5_address *, krb5_int32 *, krb5_int16 *); krb5_error_code krb5_make_full_ipaddr(krb5_context, krb5_int32, int, /* unsigned short promotes to signed int */ krb5_address **); #endif /* HAVE_NETINET_IN_H */ struct srv_dns_entry { struct srv_dns_entry *next; int priority; int weight; unsigned short port; char *host; }; krb5_error_code krb5int_make_srv_query_realm(krb5_context context, const krb5_data *realm, const char *service, const char *protocol, const char *sitename, struct srv_dns_entry **answers); void krb5int_free_srv_dns_data(struct srv_dns_entry *); krb5_error_code k5_make_uri_query(krb5_context context, const krb5_data *realm, const char *service, const char *sitename, struct srv_dns_entry **answers); krb5_error_code k5_try_realm_txt_rr(krb5_context context, const char *prefix, const char *name, char **realm); char *k5_primary_domain(void); int _krb5_use_dns_realm (krb5_context); int _krb5_use_dns_kdc (krb5_context); int _krb5_conf_boolean (const char *); krb5_error_code k5_sendto(krb5_context context, const krb5_data *message, const krb5_data *realm, const struct serverlist *addrs, k5_transport_strategy strategy, struct sendto_callback_info *callback_info, krb5_data *reply, struct sockaddr *remoteaddr, socklen_t *remoteaddrlen, int *server_used, int (*msg_handler)(krb5_context, const krb5_data *, void *), void *msg_handler_data); krb5_error_code k5_sendto_kdc(krb5_context context, const krb5_data *message, const krb5_data *realm, krb5_boolean use_primary, krb5_boolean no_udp, krb5_data *reply_out, struct kdclist *hist); krb5_error_code krb5int_get_fq_local_hostname(char **); /* The io vector is *not* const here, unlike writev()! */ int krb5int_net_writev (krb5_context, int, sg_buf *, int); int k5_getcurtime(struct timeval *tvp); krb5_error_code k5_expand_path_tokens(krb5_context context, const char *path_in, char **path_out); krb5_error_code k5_expand_path_tokens_extra(krb5_context context, const char *path_in, char **path_out, ...); krb5_error_code k5_create_secure_file(krb5_context, const char * pathname); krb5_error_code k5_sync_disk_file(krb5_context, FILE *fp); krb5_error_code k5_os_init_context(krb5_context context, profile_t profile, krb5_flags flags); void k5_os_free_context(krb5_context); krb5_error_code k5_os_hostaddr(krb5_context, const char *, krb5_address ***); krb5_error_code k5_time_with_offset(krb5_timestamp offset, krb5_int32 offset_usec, krb5_timestamp *time_out, krb5_int32 *usec_out); void k5_set_prompt_types(krb5_context, krb5_prompt_type *); krb5_boolean k5_is_numeric_address(const char *name); krb5_error_code k5_make_realmlist(const char *realm, char ***realms_out); krb5_error_code k5_kt_client_default_name(krb5_context context, char **name_out); krb5_error_code k5_write_messages(krb5_context, krb5_pointer, krb5_data *, int); void k5_init_trace(krb5_context context); #include "k5-thread.h" extern k5_mutex_t krb5int_us_time_mutex; extern unsigned int krb5_max_skdc_timeout; extern unsigned int krb5_skdc_timeout_shift; extern unsigned int krb5_skdc_timeout_1; void k5_hostrealm_free_context(krb5_context); krb5_error_code hostrealm_profile_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code hostrealm_registry_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code hostrealm_dns_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code hostrealm_domain_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); void k5_localauth_free_context(krb5_context); krb5_error_code localauth_names_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code localauth_rule_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code localauth_k5login_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code localauth_an2ln_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); #endif /* KRB5_LIBOS_INT_PROTO__ */ krb5-1.22.1/src/lib/krb5/os/hostrealm_registry.c0000664000175000017500000001053615051422640021261 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/hostream_registry.c - registry hostrealm module */ /* * Copyright (C) 2015 by the Massachusetts Institute * of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file implements the built-in registry module for the hostrealm * interface, which uses Windows registry configuration to determine the * local default realm. */ #include "k5-int.h" #include "os-proto.h" #include #ifdef _WIN32 /* * Look up a default_realm entry starting from the given base key. * The output *buf_out will be non-NULL if an entry was found; the * caller is responsible for freeing *pbuffer. * * On success, return 0 and set *str_out to the default realm to be * used. Return KRB5_PLUGIN_NO_HANDLE if the registry key does not * exist, or another code if it cannot be read. */ static krb5_error_code get_from_registry(HKEY hBaseKey, char **str_out) { DWORD bsize = 0; LONG rc; krb5_error_code ret; char *str = NULL; const char *path = "Software\\MIT\\Kerberos5"; const char *value = "default_realm"; *str_out = NULL; /* Call with zero size to determine the amount of storage needed. */ rc = RegGetValue(hBaseKey, path, value, RRF_RT_REG_SZ, NULL, str, &bsize); if (rc == ERROR_FILE_NOT_FOUND) return KRB5_PLUGIN_NO_HANDLE; if (FAILED(rc) || bsize <= 0) return EIO; str = malloc(bsize); if (str == NULL) return ENOMEM; rc = RegGetValue(hBaseKey, path, value, RRF_RT_REG_SZ, NULL, str, &bsize); if (FAILED(rc)) { ret = EIO; goto cleanup; } ret = 0; *str_out = str; str = NULL; cleanup: free(str); return ret; } /* Look up the default_realm variable in the * {HKLM,HKCU}\Software\MIT\Kerberos5\default_realm registry values. */ static krb5_error_code registry_default_realm(krb5_context context, krb5_hostrealm_moddata data, char ***realms_out) { krb5_error_code ret; char *prof_realm; *realms_out = NULL; ret = get_from_registry(HKEY_LOCAL_MACHINE, &prof_realm); if (ret == KRB5_PLUGIN_NO_HANDLE) ret = get_from_registry(HKEY_CURRENT_USER, &prof_realm); if (ret) return ret; ret = k5_make_realmlist(prof_realm, realms_out); free(prof_realm); return ret; } #else /* _WIN32 */ static krb5_error_code registry_default_realm(krb5_context context, krb5_hostrealm_moddata data, char ***realms_out) { return KRB5_PLUGIN_NO_HANDLE; } #endif /* _WIN32 */ static void registry_free_realmlist(krb5_context context, krb5_hostrealm_moddata data, char **list) { krb5_free_host_realm(context, list); } krb5_error_code hostrealm_registry_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_hostrealm_vtable vt = (krb5_hostrealm_vtable)vtable; vt->name = "registry"; vt->default_realm = registry_default_realm; vt->free_list = registry_free_realmlist; return 0; } krb5-1.22.1/src/lib/krb5/os/krbfileio.c0000664000175000017500000000531515051422640017300 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/krbfileio.c */ /* * Copyright (c) Hewlett-Packard Company 1991 * Released to the Massachusetts Institute of Technology for inclusion * in the Kerberos source code distribution. * * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifdef MODULE_VERSION_ID static char *VersionID = "@(#)krbfileio.c 2 - 08/22/91"; #endif #include "k5-int.h" #include "os-proto.h" #ifdef HAVE_SYS_FILE_H #include #endif #include #ifndef O_BINARY #define O_BINARY 0 #endif #ifdef apollo # define OPEN_MODE_NOT_TRUSTWORTHY #endif krb5_error_code k5_create_secure_file(krb5_context context, const char *pathname) { int fd; /* * Create the file with access restricted to the owner */ fd = THREEPARAMOPEN(pathname, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600); #ifdef OPEN_MODE_NOT_TRUSTWORTHY /* * Some systems that support default acl inheritance do not * apply ownership information from the process - force the file * to have the proper info. */ if (fd > -1) { uid_t uid; gid_t gid; uid = getuid(); gid = getgid(); fchown(fd, uid, gid); fchmod(fd, 0600); } #endif /* OPEN_MODE_NOT_TRUSTWORTHY */ if (fd > -1) { close(fd); return 0; } else { return errno; } } krb5_error_code k5_sync_disk_file(krb5_context context, FILE *fp) { fflush(fp); #if !defined(MSDOS_FILESYSTEM) if (fsync(fileno(fp))) { return errno; } #endif return 0; } krb5-1.22.1/src/lib/krb5/os/port2ip.c0000664000175000017500000000565315051422640016736 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/port2ip.c - Split full address into IP address and port */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #ifdef HAVE_NETINET_IN_H #include "os-proto.h" krb5_error_code krb5_unpack_full_ipaddr(krb5_context context, const krb5_address *inaddr, krb5_int32 *adr, krb5_int16 *port) { unsigned long smushaddr; unsigned short smushport; krb5_octet *marshal; krb5_addrtype temptype; krb5_ui_4 templength; if (inaddr->addrtype != ADDRTYPE_ADDRPORT) return KRB5_PROG_ATYPE_NOSUPP; if (inaddr->length != sizeof(smushaddr)+ sizeof(smushport) + 2*sizeof(temptype) + 2*sizeof(templength)) return KRB5_PROG_ATYPE_NOSUPP; marshal = inaddr->contents; (void) memcpy(&temptype, marshal, sizeof(temptype)); marshal += sizeof(temptype); if (temptype != htons(ADDRTYPE_INET)) return KRB5_PROG_ATYPE_NOSUPP; (void) memcpy(&templength, marshal, sizeof(templength)); marshal += sizeof(templength); if (templength != htonl(sizeof(smushaddr))) return KRB5_PROG_ATYPE_NOSUPP; (void) memcpy(&smushaddr, marshal, sizeof(smushaddr)); /* leave in net order */ marshal += sizeof(smushaddr); (void) memcpy(&temptype, marshal, sizeof(temptype)); marshal += sizeof(temptype); if (temptype != htons(ADDRTYPE_IPPORT)) return KRB5_PROG_ATYPE_NOSUPP; (void) memcpy(&templength, marshal, sizeof(templength)); marshal += sizeof(templength); if (templength != htonl(sizeof(smushport))) return KRB5_PROG_ATYPE_NOSUPP; (void) memcpy(&smushport, marshal, sizeof(smushport)); /* leave in net order */ *adr = (krb5_int32) smushaddr; *port = (krb5_int16) smushport; return 0; } #endif krb5-1.22.1/src/lib/krb5/os/localauth.c0000664000175000017500000003273715051422640017316 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/localauth.c - Authorize access to local accounts */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "os-proto.h" #include struct localauth_module_handle { struct krb5_localauth_vtable_st vt; krb5_localauth_moddata data; }; static krb5_error_code localauth_auth_to_local_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); static krb5_error_code localauth_default_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); /* Release a list of localauth module handles. */ static void free_handles(krb5_context context, struct localauth_module_handle **handles) { struct localauth_module_handle *h, **hp; if (handles == NULL) return; for (hp = handles; *hp != NULL; hp++) { h = *hp; if (h->vt.fini != NULL) h->vt.fini(context, h->data); free(h); } free(handles); } /* Find a localauth module whose an2ln_types contains a match for type. */ static struct localauth_module_handle * find_typed_module(struct localauth_module_handle **handles, const char *type) { struct localauth_module_handle **hp, *h; const char **tp; for (hp = handles; *hp != NULL; hp++) { h = *hp; for (tp = h->vt.an2ln_types; tp != NULL && *tp != NULL; tp++) { if (strcmp(*tp, type) == 0) return h; } } return NULL; } /* Generate a trace log and return 1 if the an2ln_types of handle conflicts * with any of the handles in list. Return 0 otherwise. */ static int check_conflict(krb5_context context, struct localauth_module_handle **list, struct localauth_module_handle *handle) { struct localauth_module_handle *conflict; const char **tp; for (tp = handle->vt.an2ln_types; tp != NULL && *tp != NULL; tp++) { conflict = find_typed_module(list, *tp); if (conflict != NULL) { TRACE_LOCALAUTH_INIT_CONFLICT(context, *tp, handle->vt.name, conflict->vt.name); return 1; } } return 0; } /* Get the registered localauth modules including all built-in modules, in the * proper order. */ static krb5_error_code get_modules(krb5_context context, krb5_plugin_initvt_fn **modules_out) { krb5_error_code ret; const int intf = PLUGIN_INTERFACE_LOCALAUTH; *modules_out = NULL; /* Register built-in modules. */ ret = k5_plugin_register(context, intf, "default", localauth_default_initvt); if (ret) return ret; ret = k5_plugin_register(context, intf, "rule", localauth_rule_initvt); if (ret) return ret; ret = k5_plugin_register(context, intf, "names", localauth_names_initvt); if (ret) return ret; ret = k5_plugin_register(context, intf, "auth_to_local", localauth_auth_to_local_initvt); if (ret) return ret; ret = k5_plugin_register(context, intf, "k5login", localauth_k5login_initvt); if (ret) return ret; ret = k5_plugin_register(context, intf, "an2ln", localauth_an2ln_initvt); if (ret) return ret; ret = k5_plugin_load_all(context, intf, modules_out); if (ret) return ret; return 0; } /* Initialize context->localauth_handles with a list of module handles. */ static krb5_error_code load_localauth_modules(krb5_context context) { krb5_error_code ret; struct localauth_module_handle **list = NULL, *handle; krb5_plugin_initvt_fn *modules = NULL, *mod; size_t count; ret = get_modules(context, &modules); if (ret != 0) goto cleanup; /* Allocate a large enough list of handles. */ for (count = 0; modules[count] != NULL; count++); list = k5calloc(count + 1, sizeof(*list), &ret); if (list == NULL) goto cleanup; /* Initialize each module, ignoring ones that fail. */ count = 0; for (mod = modules; *mod != NULL; mod++) { handle = k5alloc(sizeof(*handle), &ret); if (handle == NULL) goto cleanup; ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&handle->vt); if (ret != 0) { TRACE_LOCALAUTH_VTINIT_FAIL(context, ret); free(handle); continue; } if (check_conflict(context, list, handle)) continue; handle->data = NULL; if (handle->vt.init != NULL) { ret = handle->vt.init(context, &handle->data); if (ret != 0) { TRACE_LOCALAUTH_INIT_FAIL(context, handle->vt.name, ret); free(handle); continue; } } list[count++] = handle; list[count] = NULL; } list[count] = NULL; ret = 0; context->localauth_handles = list; list = NULL; cleanup: k5_plugin_free_modules(context, modules); free_handles(context, list); return ret; } /* Invoke a module's userok method, if it has one. */ static krb5_error_code userok(krb5_context context, struct localauth_module_handle *h, krb5_const_principal aname, const char *lname) { if (h->vt.userok == NULL) return KRB5_PLUGIN_NO_HANDLE; return h->vt.userok(context, h->data, aname, lname); } /* Invoke a module's an2ln method, if it has one. */ static krb5_error_code an2ln(krb5_context context, struct localauth_module_handle *h, const char *type, const char *residual, krb5_const_principal aname, char **lname_out) { if (h->vt.an2ln == NULL) return KRB5_LNAME_NOTRANS; return h->vt.an2ln(context, h->data, type, residual, aname, lname_out); } /* Invoke a module's free_string method. */ static void free_lname(krb5_context context, struct localauth_module_handle *h, char *str) { h->vt.free_string(context, h->data, str); } /* Parse a TYPE or TYPE:residual string into its components. */ static krb5_error_code parse_mapping_value(const char *value, char **type_out, char **residual_out) { krb5_error_code ret; const char *p; char *type, *residual; *type_out = NULL; *residual_out = NULL; p = strchr(value, ':'); if (p == NULL) { type = strdup(value); if (type == NULL) return ENOMEM; residual = NULL; } else { type = k5memdup0(value, p - value, &ret); if (type == NULL) return ret; residual = strdup(p + 1); if (residual == NULL) { free(type); return ENOMEM; } } *type_out = type; *residual_out = residual; return 0; } /* Apply the default an2ln method, which translates name@defaultrealm or * name/defaultrealm@defaultrealm to name. */ static krb5_error_code an2ln_default(krb5_context context, krb5_localauth_moddata data, const char *type, const char *residual, krb5_const_principal aname, char **lname_out) { krb5_error_code ret; char *def_realm; *lname_out = NULL; ret = krb5_get_default_realm(context, &def_realm); if (ret) return KRB5_LNAME_NOTRANS; if (!data_eq_string(aname->realm, def_realm)) { ret = KRB5_LNAME_NOTRANS; } else if (aname->length == 2) { /* Allow a second component if it is the local realm. */ if (!data_eq_string(aname->data[1], def_realm)) ret = KRB5_LNAME_NOTRANS; } else if (aname->length != 1) { ret = KRB5_LNAME_NOTRANS; } free(def_realm); if (ret) return ret; *lname_out = k5memdup0(aname->data[0].data, aname->data[0].length, &ret); return ret; } /* * Perform aname-to-lname translation using the auth_to_local values in the * default realm's profile section. If no values exist, fall back to the * default method. */ static krb5_error_code an2ln_auth_to_local(krb5_context context, krb5_localauth_moddata data, const char *type_arg, const char *residual_arg, krb5_const_principal aname, char **lname_out) { krb5_error_code ret; struct localauth_module_handle *h; char *realm = NULL, **mapping_values = NULL, *type, *residual, *lname; const char *hierarchy[4]; size_t i; *lname_out = NULL; /* Fetch the profile values for realms->->auth_to_local. */ ret = krb5_get_default_realm(context, &realm); if (ret) return KRB5_LNAME_NOTRANS; hierarchy[0] = KRB5_CONF_REALMS; hierarchy[1] = realm; hierarchy[2] = KRB5_CONF_AUTH_TO_LOCAL; hierarchy[3] = NULL; ret = profile_get_values(context->profile, hierarchy, &mapping_values); if (ret) { /* Use default method if there are no auth_to_local values. */ ret = an2ln_default(context, data, NULL, NULL, aname, lname_out); goto cleanup; } ret = KRB5_LNAME_NOTRANS; for (i = 0; mapping_values[i] != NULL && ret == KRB5_LNAME_NOTRANS; i++) { ret = parse_mapping_value(mapping_values[i], &type, &residual); if (ret) goto cleanup; h = find_typed_module(context->localauth_handles, type); if (h != NULL) { ret = an2ln(context, h, type, residual, aname, &lname); if (ret == 0) { *lname_out = strdup(lname); if (*lname_out == NULL) ret = ENOMEM; free_lname(context, h, lname); } } else { ret = KRB5_CONFIG_BADFORMAT; } free(type); free(residual); } cleanup: free(realm); profile_free_list(mapping_values); return ret; } static void freestr(krb5_context context, krb5_localauth_moddata data, char *str) { free(str); } static krb5_error_code localauth_auth_to_local_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_localauth_vtable vt = (krb5_localauth_vtable)vtable; vt->name = "auth_to_local"; vt->an2ln = an2ln_auth_to_local; vt->free_string = freestr; return 0; } static krb5_error_code localauth_default_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_localauth_vtable vt = (krb5_localauth_vtable)vtable; static const char *types[] = { "DEFAULT", NULL }; vt->name = "default"; vt->an2ln_types = types; vt->an2ln = an2ln_default; vt->free_string = freestr; return 0; } krb5_boolean KRB5_CALLCONV krb5_kuserok(krb5_context context, krb5_principal aname, const char *lname) { krb5_error_code ret; struct localauth_module_handle **hp; krb5_boolean accepted = FALSE; if (context->localauth_handles == NULL && load_localauth_modules(context)) return FALSE; /* If any module denies access, return false immediately. Otherwise, * consult all modules and return true if one of them allows access. */ for (hp = context->localauth_handles; *hp != NULL; hp++) { ret = userok(context, *hp, aname, lname); if (ret == 0) accepted = TRUE; else if (ret != KRB5_PLUGIN_NO_HANDLE) return FALSE; } return accepted; } krb5_error_code KRB5_CALLCONV krb5_aname_to_localname(krb5_context context, krb5_const_principal aname, int lnsize, char *lname_out) { krb5_error_code ret; struct localauth_module_handle **hp; char *lname; size_t sz; if (context->localauth_handles == NULL) { ret = load_localauth_modules(context); if (ret) return ret; } for (hp = context->localauth_handles; *hp != NULL; hp++) { if ((*hp)->vt.an2ln_types != NULL) continue; ret = an2ln(context, *hp, NULL, NULL, aname, &lname); if (ret == 0) { sz = strlcpy(lname_out, lname, lnsize); free_lname(context, *hp, lname); return sz >= (size_t)lnsize ? KRB5_CONFIG_NOTENUFSPACE : 0; } else if (ret != KRB5_LNAME_NOTRANS) { return ret; } } return KRB5_LNAME_NOTRANS; } void k5_localauth_free_context(krb5_context context) { free_handles(context, context->localauth_handles); context->localauth_handles = NULL; } krb5-1.22.1/src/lib/krb5/os/hostrealm_domain.c0000664000175000017500000001064415051422640020660 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/hostream_domain.c - domain hostrealm module */ /* * Copyright (C) 1990,1991,2002,2008,2009,2013 by the Massachusetts Institute * of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file implements the built-in domain module for the hostrealm interface, * which uses domain-based heuristics to determine the fallback realm of a * host. */ #include "k5-int.h" #include "os-proto.h" #include #include static krb5_error_code domain_fallback_realm(krb5_context context, krb5_hostrealm_moddata data, const char *host, char ***realms_out) { krb5_error_code ret; struct serverlist slist; krb5_data drealm; char *uhost = NULL, *p; const char *suffix, *dot; int limit; *realms_out = NULL; /* These heuristics don't apply to address literals. */ if (k5_is_numeric_address(host)) return KRB5_PLUGIN_NO_HANDLE; /* Make an uppercase copy of host. */ uhost = strdup(host); if (uhost == NULL) return ENOMEM; for (p = uhost; *p != '\0'; p++) { if (islower((unsigned char)*p)) *p = toupper((unsigned char)*p); } /* * Try searching domain suffixes as realms. This heuristic is turned off * by default. If DNS lookups for KDCs are enabled (as they are by * default), an attacker could control which domain component is used as * the realm for a host. * * A realm_try_domains value of -1 (the default) means not to search at * all, a value of 0 means to try only the full domain itself, 1 means to * also try the parent domain, etc.. We will stop searching when we reach * a suffix with only one label. */ ret = profile_get_integer(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_REALM_TRY_DOMAINS, 0, -1, &limit); if (ret) goto cleanup; suffix = uhost; while (limit-- >= 0 && (dot = strchr(suffix, '.')) != NULL) { drealm = string2data((char *)suffix); if (k5_locate_kdc(context, &drealm, &slist, FALSE, FALSE) == 0) { k5_free_serverlist(&slist); ret = k5_make_realmlist(suffix, realms_out); goto cleanup; } suffix = dot + 1; } /* * If that didn't succeed, use the upper-cased parent domain of the * hostname, regardless of whether we can actually look it up as a realm. */ dot = strchr(uhost, '.'); if (dot != NULL) ret = k5_make_realmlist(dot + 1, realms_out); else ret = KRB5_PLUGIN_NO_HANDLE; cleanup: free(uhost); return ret; } static void domain_free_realmlist(krb5_context context, krb5_hostrealm_moddata data, char **list) { krb5_free_host_realm(context, list); } krb5_error_code hostrealm_domain_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_hostrealm_vtable vt = (krb5_hostrealm_vtable)vtable; vt->name = "domain"; vt->fallback_realm = domain_fallback_realm; vt->free_list = domain_free_realmlist; return 0; } krb5-1.22.1/src/lib/krb5/os/sn2princ.c0000664000175000017500000002717715051422640017102 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/sn2princ.c */ /* * Copyright 1991,2002 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* Convert a hostname and service name to a principal in the "standard" * form. */ #include "k5-int.h" #include "os-proto.h" #include "fake-addrinfo.h" #include #ifdef HAVE_SYS_PARAM_H #include #endif #if !defined(DEFAULT_RDNS_LOOKUP) #define DEFAULT_RDNS_LOOKUP 1 #endif static krb5_boolean use_reverse_dns(krb5_context context) { krb5_error_code ret; int value; ret = profile_get_boolean(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_RDNS, NULL, DEFAULT_RDNS_LOOKUP, &value); if (ret) return DEFAULT_RDNS_LOOKUP; return value; } /* Append a domain suffix to host and return the result in allocated memory. * Return NULL if no suffix is configured or on failure. */ static char * qualify_shortname(krb5_context context, const char *host) { krb5_error_code ret; char *fqdn = NULL, *prof_domain = NULL, *os_domain = NULL; const char *domain; ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_QUALIFY_SHORTNAME, NULL, NULL, &prof_domain); if (ret) return NULL; #ifdef KRB5_DNS_LOOKUP if (prof_domain == NULL) os_domain = k5_primary_domain(); #endif domain = (prof_domain != NULL) ? prof_domain : os_domain; if (domain != NULL && *domain != '\0') { if (asprintf(&fqdn, "%s.%s", host, domain) < 0) fqdn = NULL; } profile_release_string(prof_domain); free(os_domain); return fqdn; } static krb5_error_code expand_hostname(krb5_context context, const char *host, krb5_boolean use_dns, char **canonhost_out) { struct addrinfo *ai = NULL, hint; char namebuf[NI_MAXHOST], *qualified = NULL, *copy, *p; int err; const char *canonhost; *canonhost_out = NULL; canonhost = host; if (use_dns) { /* Try a forward lookup of the hostname. */ memset(&hint, 0, sizeof(hint)); hint.ai_flags = AI_CANONNAME; err = getaddrinfo(host, 0, &hint, &ai); if (err == EAI_MEMORY) goto cleanup; if (!err && ai->ai_canonname != NULL) canonhost = ai->ai_canonname; if (!err && use_reverse_dns(context)) { /* Try a reverse lookup of the address. */ err = getnameinfo(ai->ai_addr, ai->ai_addrlen, namebuf, sizeof(namebuf), NULL, 0, NI_NAMEREQD); if (err == EAI_MEMORY) goto cleanup; if (!err) canonhost = namebuf; } } /* If we didn't use DNS and the name is just one component, try to add a * domain suffix. */ if (canonhost == host && strchr(host, '.') == NULL) { qualified = qualify_shortname(context, host); if (qualified != NULL) canonhost = qualified; } copy = strdup(canonhost); if (copy == NULL) goto cleanup; /* Convert the hostname to lower case. */ for (p = copy; *p != '\0'; p++) { if (isupper((unsigned char)*p)) *p = tolower((unsigned char)*p); } /* Remove any trailing dot. */ if (copy[0] != '\0') { p = copy + strlen(copy) - 1; if (*p == '.') *p = '\0'; } *canonhost_out = copy; cleanup: /* We only return success or ENOMEM. */ if (ai != NULL) freeaddrinfo(ai); free(qualified); return (*canonhost_out == NULL) ? ENOMEM : 0; } krb5_error_code KRB5_CALLCONV krb5_expand_hostname(krb5_context context, const char *host, char **canonhost_out) { int use_dns = (context->dns_canonicalize_hostname == CANONHOST_TRUE); return expand_hostname(context, host, use_dns, canonhost_out); } /* Split data into hostname and trailer (:port or :instance). Trailers are * used in MSSQLSvc principals. */ static void split_trailer(const krb5_data *data, krb5_data *host, krb5_data *trailer) { char *p = memchr(data->data, ':', data->length); unsigned int tlen = (p == NULL) ? 0 : data->length - (p - data->data); /* Make sure we have a single colon followed by one or more characters. An * IPv6 address will have more than one colon, so don't accept that. */ if (p == NULL || tlen == 1 || memchr(p + 1, ':', tlen - 1) != NULL) { *host = *data; *trailer = make_data("", 0); } else { *host = make_data(data->data, p - data->data); *trailer = make_data(p, tlen); } } static krb5_error_code canonicalize_princ(krb5_context context, struct canonprinc *iter, krb5_boolean use_dns, krb5_const_principal *princ_out) { krb5_error_code ret; krb5_data host, trailer; char *hostname = NULL, *canonhost = NULL, *combined = NULL; char **hrealms = NULL; *princ_out = NULL; assert(iter->princ->length == 2); split_trailer(&iter->princ->data[1], &host, &trailer); hostname = k5memdup0(host.data, host.length, &ret); if (hostname == NULL) goto cleanup; if (iter->princ->type == KRB5_NT_SRV_HST) { /* Expand the hostname with or without DNS as specified. */ ret = expand_hostname(context, hostname, use_dns, &canonhost); if (ret) goto cleanup; } else { canonhost = strdup(hostname); if (canonhost == NULL) { ret = ENOMEM; goto cleanup; } } /* Add the trailer to the expanded hostname. */ if (asprintf(&combined, "%s%.*s", canonhost, trailer.length, trailer.data) < 0) { combined = NULL; ret = ENOMEM; goto cleanup; } /* Don't yield the same host part twice. */ if (iter->canonhost != NULL && strcmp(iter->canonhost, combined) == 0) goto cleanup; free(iter->canonhost); iter->canonhost = combined; combined = NULL; /* If the realm is unknown, look up the realm of the expanded hostname. */ if (iter->princ->realm.length == 0 && !iter->no_hostrealm) { ret = krb5_get_host_realm(context, canonhost, &hrealms); if (ret) goto cleanup; if (hrealms[0] == NULL) { ret = KRB5_ERR_HOST_REALM_UNKNOWN; goto cleanup; } free(iter->realm); if (*hrealms[0] == '\0' && iter->subst_defrealm) { ret = krb5_get_default_realm(context, &iter->realm); if (ret) goto cleanup; } else { iter->realm = strdup(hrealms[0]); if (iter->realm == NULL) { ret = ENOMEM; goto cleanup; } } } iter->copy = *iter->princ; if (iter->realm != NULL) iter->copy.realm = string2data(iter->realm); iter->components[0] = iter->princ->data[0]; iter->components[1] = string2data(iter->canonhost); iter->copy.data = iter->components; *princ_out = &iter->copy; cleanup: free(hostname); free(canonhost); free(combined); krb5_free_host_realm(context, hrealms); return ret; } krb5_error_code k5_canonprinc(krb5_context context, struct canonprinc *iter, krb5_const_principal *princ_out) { krb5_error_code ret; int step = ++iter->step; *princ_out = NULL; /* If the hostname isn't from krb5_sname_to_principal(), the input * principal is canonical. */ if (iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 || iter->princ->data[1].length == 0) { *princ_out = (step == 1) ? iter->princ : NULL; return 0; } /* If we're not doing fallback, the hostname is canonical, but we may need * to substitute the default realm. */ if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK) { if (step > 1) return 0; iter->copy = *iter->princ; if (iter->subst_defrealm && iter->copy.realm.length == 0) { ret = krb5_get_default_realm(context, &iter->realm); if (ret) return ret; iter->copy = *iter->princ; iter->copy.realm = string2data(iter->realm); } *princ_out = &iter->copy; return 0; } /* Canonicalize without DNS at step 1, with DNS at step 2. */ if (step > 2) return 0; return canonicalize_princ(context, iter, step == 2, princ_out); } krb5_boolean k5_sname_compare(krb5_context context, krb5_const_principal sname, krb5_const_principal princ) { krb5_error_code ret; struct canonprinc iter = { sname, .subst_defrealm = TRUE }; krb5_const_principal canonprinc = NULL; krb5_boolean match = FALSE; while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 && canonprinc != NULL) { if (krb5_principal_compare(context, canonprinc, princ)) { match = TRUE; break; } } free_canonprinc(&iter); return match; } krb5_error_code KRB5_CALLCONV krb5_sname_to_principal(krb5_context context, const char *hostname, const char *sname, krb5_int32 type, krb5_principal *princ_out) { krb5_error_code ret; krb5_principal princ; krb5_const_principal cprinc; krb5_boolean use_dns; char localname[MAXHOSTNAMELEN]; struct canonprinc iter = { NULL }; *princ_out = NULL; if (type != KRB5_NT_UNKNOWN && type != KRB5_NT_SRV_HST) return KRB5_SNAME_UNSUPP_NAMETYPE; /* If hostname is NULL, use the local hostname. */ if (hostname == NULL) { if (gethostname(localname, MAXHOSTNAMELEN) != 0) return SOCKET_ERRNO; hostname = localname; } /* If sname is NULL, use "host". */ if (sname == NULL) sname = "host"; /* Build an initial principal with what we have. */ ret = krb5_build_principal(context, &princ, 0, KRB5_REFERRAL_REALM, sname, hostname, (char *)NULL); if (ret) return ret; princ->type = type; if (type == KRB5_NT_SRV_HST && context->dns_canonicalize_hostname == CANONHOST_FALLBACK) { /* Delay canonicalization and realm lookup until use. */ *princ_out = princ; return 0; } use_dns = (context->dns_canonicalize_hostname == CANONHOST_TRUE); iter.princ = princ; ret = canonicalize_princ(context, &iter, use_dns, &cprinc); if (!ret) ret = krb5_copy_principal(context, cprinc, princ_out); free_canonprinc(&iter); krb5_free_principal(context, princ); return ret; } krb5-1.22.1/src/lib/krb5/os/dnsglue.h0000664000175000017500000001066415051422640017003 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/dnsglue.h */ /* * Copyright 2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Glue layer for DNS resolver, to make parsing of replies easier * whether we are using BIND 4, 8, or 9. This header is not used on * Windows. */ /* * BIND 4 doesn't have the ns_initparse() API, so we need to do some * manual parsing via the HEADER struct. BIND 8 does have * ns_initparse(), but has enums for the various protocol constants * rather than the BIND 4 macros. BIND 9 (at least on macOS 10.3) * appears to disable res_nsearch() if BIND_8_COMPAT is defined * (which is necessary to obtain the HEADER struct). * * We use ns_initparse() if available at all, and never define * BIND_8_COMPAT. If there is no ns_initparse(), we do manual parsing * by using the HEADER struct. */ #ifndef KRB5_DNSGLUE_H #define KRB5_DNSGLUE_H #include "autoconf.h" #ifdef KRB5_DNS_LOOKUP #include "k5-int.h" #include "os-proto.h" #include #include #include #include #include #if HAVE_SYS_PARAM_H #include /* for MAXHOSTNAMELEN */ #endif #ifndef MAXDNAME #ifdef NS_MAXDNAME #define MAXDNAME NS_MAXDNAME #else #ifdef MAXLABEL #define MAXDNAME (16 * MAXLABEL) #else #define MAXDNAME (16 * MAXHOSTNAMELEN) #endif #endif #endif #if HAVE_NS_INITPARSE /* * Solaris 7 has ns_rr_cl rather than ns_rr_class. */ #if !defined(ns_rr_class) && defined(ns_rr_cl) #define ns_rr_class ns_rr_cl #endif #endif #if HAVE_RES_NSEARCH /* * Some BIND 8 / BIND 9 implementations disable the BIND 4 style * constants. */ #ifndef C_IN #define C_IN ns_c_in #endif #ifndef T_SRV #define T_SRV ns_t_srv #endif #ifndef T_TXT #define T_TXT ns_t_txt #endif #else /* !HAVE_RES_NSEARCH */ /* * Some BIND implementations might be old enough to lack these. */ #ifndef T_TXT #define T_TXT 15 #endif #ifndef T_SRV #define T_SRV 33 #endif #endif /* HAVE_RES_NSEARCH */ #ifndef T_URI #define T_URI 256 #endif /* * INCR_OK * * Given moving pointer PTR offset from BASE, return true if adding * INCR to PTR doesn't move it PTR than MAX bytes from BASE. */ #define INCR_OK(base, max, ptr, incr) \ ((incr) <= (max) - ((const unsigned char *)(ptr) \ - (const unsigned char *)(base))) /* * SAFE_GETUINT16 * * Given PTR offset from BASE, if at least INCR bytes are safe to * read, get network byte order uint16 into S, and increment PTR. On * failure, goto LABEL. */ #define SAFE_GETUINT16(base, max, ptr, incr, s, label) \ do { \ if (!INCR_OK(base, max, ptr, incr)) goto label; \ (s) = (unsigned short)(ptr)[0] << 8 \ | (unsigned short)(ptr)[1]; \ (ptr) += (incr); \ } while (0) struct krb5int_dns_state; int krb5int_dns_init(struct krb5int_dns_state **, char *, int, int); int krb5int_dns_nextans(struct krb5int_dns_state *, const unsigned char **, int *); int krb5int_dns_expand(struct krb5int_dns_state *, const unsigned char *, char *, int); void krb5int_dns_fini(struct krb5int_dns_state *); #endif /* KRB5_DNS_LOOKUP */ #endif /* !defined(KRB5_DNSGLUE_H) */ krb5-1.22.1/src/lib/krb5/os/deps0000664000175000017500000012030415051422640016040 0ustar ghudsonghudson# # Generated makefile dependencies follow. # accessor.so accessor.po $(OUTPRE)accessor.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../krb/int-proto.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ accessor.c os-proto.h addr.so addr.po $(OUTPRE)addr.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h addr.c c_ustime.so c_ustime.po $(OUTPRE)c_ustime.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ c_ustime.c ccdefname.so ccdefname.po $(OUTPRE)ccdefname.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../ccache/cc-int.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ccdefname.c os-proto.h changepw.so changepw.po $(OUTPRE)changepw.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../krb/auth_con.h $(srcdir)/../krb/int-proto.h \ $(srcdir)/../rcache/memrcache.h $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h changepw.c os-proto.h dnsglue.so dnsglue.po $(OUTPRE)dnsglue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ dnsglue.c dnsglue.h os-proto.h dnssrv.so dnssrv.po $(OUTPRE)dnssrv.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ dnsglue.h dnssrv.c os-proto.h expand_path.so expand_path.po $(OUTPRE)expand_path.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h expand_path.c \ os-proto.h full_ipadr.so full_ipadr.po $(OUTPRE)full_ipadr.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h full_ipadr.c os-proto.h gen_port.so gen_port.po $(OUTPRE)gen_port.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h gen_port.c os-proto.h genaddrs.so genaddrs.po $(OUTPRE)genaddrs.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h genaddrs.c os-proto.h gen_rname.so gen_rname.po $(OUTPRE)gen_rname.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h gen_rname.c os-proto.h hostaddr.so hostaddr.po $(OUTPRE)hostaddr.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h hostaddr.c os-proto.h hostrealm.so hostrealm.po $(OUTPRE)hostrealm.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/hostrealm_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hostrealm.c os-proto.h hostrealm_dns.so hostrealm_dns.po $(OUTPRE)hostrealm_dns.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/hostrealm_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hostrealm_dns.c os-proto.h hostrealm_domain.so hostrealm_domain.po $(OUTPRE)hostrealm_domain.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/hostrealm_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hostrealm_domain.c os-proto.h hostrealm_profile.so hostrealm_profile.po $(OUTPRE)hostrealm_profile.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/hostrealm_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hostrealm_profile.c os-proto.h hostrealm_registry.so hostrealm_registry.po $(OUTPRE)hostrealm_registry.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/hostrealm_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ hostrealm_registry.c os-proto.h init_os_ctx.so init_os_ctx.po $(OUTPRE)init_os_ctx.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../krb/int-proto.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ init_os_ctx.c os-proto.h krbfileio.so krbfileio.po $(OUTPRE)krbfileio.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h krbfileio.c os-proto.h ktdefname.so ktdefname.po $(OUTPRE)ktdefname.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ktdefname.c os-proto.h mk_faddr.so mk_faddr.po $(OUTPRE)mk_faddr.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h mk_faddr.c os-proto.h localaddr.so localaddr.po $(OUTPRE)localaddr.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/foreachaddr.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h localaddr.c os-proto.h localauth.so localauth.po $(OUTPRE)localauth.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/localauth_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ localauth.c os-proto.h localauth_an2ln.so localauth_an2ln.po $(OUTPRE)localauth_an2ln.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/localauth_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ localauth_an2ln.c os-proto.h localauth_k5login.so localauth_k5login.po $(OUTPRE)localauth_k5login.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/localauth_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ localauth_k5login.c os-proto.h localauth_names.so localauth_names.po $(OUTPRE)localauth_names.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/localauth_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ localauth_names.c os-proto.h localauth_rule.so localauth_rule.po $(OUTPRE)localauth_rule.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-regex.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/localauth_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h localauth_rule.c \ os-proto.h locate_kdc.so locate_kdc.po $(OUTPRE)locate_kdc.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h locate_kdc.c os-proto.h lock_file.so lock_file.po $(OUTPRE)lock_file.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ lock_file.c net_read.so net_read.po $(OUTPRE)net_read.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ net_read.c net_write.so net_write.po $(OUTPRE)net_write.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h net_write.c os-proto.h prompter.so prompter.po $(OUTPRE)prompter.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h os-proto.h prompter.c read_msg.so read_msg.po $(OUTPRE)read_msg.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ read_msg.c read_pwd.so read_pwd.po $(OUTPRE)read_pwd.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ read_pwd.c realm_dom.so realm_dom.po $(OUTPRE)realm_dom.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ realm_dom.c port2ip.so port2ip.po $(OUTPRE)port2ip.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ os-proto.h port2ip.c sendto_kdc.so sendto_kdc.po $(OUTPRE)sendto_kdc.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-tls.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ os-proto.h sendto_kdc.c sn2princ.so sn2princ.po $(OUTPRE)sn2princ.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h os-proto.h sn2princ.c thread_safe.so thread_safe.po $(OUTPRE)thread_safe.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ thread_safe.c timeofday.so timeofday.po $(OUTPRE)timeofday.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ timeofday.c toffset.so toffset.po $(OUTPRE)toffset.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h toffset.c trace.so trace.po $(OUTPRE)trace.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ os-proto.h trace.c unlck_file.so unlck_file.po $(OUTPRE)unlck_file.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ unlck_file.c ustime.so ustime.po $(OUTPRE)ustime.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ os-proto.h ustime.c write_msg.so write_msg.po $(OUTPRE)write_msg.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h os-proto.h write_msg.c t_ctxprf.so t_ctxprf.po $(OUTPRE)t_ctxprf.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h os-proto.h t_ctxprf.c t_expand_path.so t_expand_path.po $(OUTPRE)t_expand_path.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h os-proto.h t_expand_path.c t_gifconf.so t_gifconf.po $(OUTPRE)t_gifconf.$(OBJEXT): \ t_gifconf.c t_locate_kdc.so t_locate_kdc.po $(OUTPRE)t_locate_kdc.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h dnsglue.c dnsglue.h \ dnssrv.c locate_kdc.c os-proto.h t_locate_kdc.c t_std_conf.so t_std_conf.po $(OUTPRE)t_std_conf.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/fake-addrinfo.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h os-proto.h t_std_conf.c t_trace.so t_trace.po $(OUTPRE)t_trace.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ os-proto.h t_trace.c krb5-1.22.1/src/lib/krb5/os/genaddrs.c0000664000175000017500000001032215051422640017113 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/genaddrs.c */ /* * Copyright 1995 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "os-proto.h" #if !defined(_WINSOCKAPI_) #include #endif struct addrpair { krb5_address addr, port; }; #define SET(TARG, THING, TYPE) \ ((TARG).contents = (krb5_octet *) &(THING), \ (TARG).length = sizeof (THING), \ (TARG).addrtype = (TYPE)) static void *cvtaddr (struct sockaddr_storage *a, struct addrpair *ap) { switch (ss2sa(a)->sa_family) { case AF_INET: SET (ap->port, ss2sin(a)->sin_port, ADDRTYPE_IPPORT); SET (ap->addr, ss2sin(a)->sin_addr, ADDRTYPE_INET); return a; case AF_INET6: SET (ap->port, ss2sin6(a)->sin6_port, ADDRTYPE_IPPORT); if (IN6_IS_ADDR_V4MAPPED (&ss2sin6(a)->sin6_addr)) { ap->addr.addrtype = ADDRTYPE_INET; ap->addr.contents = 12 + (krb5_octet *) &ss2sin6(a)->sin6_addr; ap->addr.length = 4; } else SET (ap->addr, ss2sin6(a)->sin6_addr, ADDRTYPE_INET6); return a; default: return 0; } } krb5_error_code KRB5_CALLCONV krb5_auth_con_genaddrs(krb5_context context, krb5_auth_context auth_context, int infd, int flags) { krb5_error_code retval; krb5_address * laddr; krb5_address * lport; krb5_address * raddr; krb5_address * rport; SOCKET fd = (SOCKET) infd; struct addrpair laddrs, raddrs; #ifdef HAVE_NETINET_IN_H struct sockaddr_storage lsaddr, rsaddr; GETSOCKNAME_ARG3_TYPE ssize; ssize = sizeof(struct sockaddr_storage); if ((flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) || (flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR)) { retval = getsockname(fd, ss2sa(&lsaddr), &ssize); if (retval) return retval; if (cvtaddr (&lsaddr, &laddrs)) { laddr = &laddrs.addr; if (flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) lport = &laddrs.port; else lport = 0; } else return KRB5_PROG_ATYPE_NOSUPP; } else { laddr = NULL; lport = NULL; } ssize = sizeof(struct sockaddr_storage); if ((flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) || (flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR)) { retval = getpeername(fd, ss2sa(&rsaddr), &ssize); if (retval) return errno; if (cvtaddr (&rsaddr, &raddrs)) { raddr = &raddrs.addr; if (flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) rport = &raddrs.port; else rport = 0; } else return KRB5_PROG_ATYPE_NOSUPP; } else { raddr = NULL; rport = NULL; } if (!(retval = krb5_auth_con_setaddrs(context, auth_context, laddr, raddr))) return (krb5_auth_con_setports(context, auth_context, lport, rport)); return retval; #else return KRB5_PROG_ATYPE_NOSUPP; #endif } krb5-1.22.1/src/lib/krb5/os/prompter.c0000664000175000017500000001772215051422640017207 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "k5-int.h" #include "os-proto.h" #if !defined(_WIN32) || (defined(_WIN32) && defined(__CYGWIN32__)) #include #include #include #include /* Is vxworks broken w.r.t. termios? --tlyu */ #ifdef __vxworks #define ECHO_PASSWORD #endif #include #ifdef POSIX_SIGNALS typedef struct sigaction osiginfo; #else typedef struct void (*osiginfo)(); #endif static void catch_signals(osiginfo *); static void restore_signals(osiginfo *); static void intrfunc(int sig); static krb5_error_code setup_tty(FILE*, int, struct termios *, osiginfo *); static krb5_error_code restore_tty(FILE*, struct termios *, osiginfo *); static volatile int got_int; /* should be sig_atomic_t */ krb5_error_code KRB5_CALLCONV krb5_prompter_posix( krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]) { int fd, i, scratchchar; FILE *fp; char *retp; krb5_error_code errcode; struct termios saveparm; osiginfo osigint; errcode = KRB5_LIBOS_CANTREADPWD; if (name) { fputs(name, stdout); fputs("\n", stdout); } if (banner) { fputs(banner, stdout); fputs("\n", stdout); } /* * Get a non-buffered stream on stdin. */ fp = NULL; fd = dup(STDIN_FILENO); if (fd < 0) return KRB5_LIBOS_CANTREADPWD; set_cloexec_fd(fd); fp = fdopen(fd, "r"); if (fp == NULL) goto cleanup; if (setvbuf(fp, NULL, _IONBF, 0)) goto cleanup; for (i = 0; i < num_prompts; i++) { errcode = KRB5_LIBOS_CANTREADPWD; /* fgets() takes int, but krb5_data.length is unsigned. */ if (prompts[i].reply->length > INT_MAX) goto cleanup; errcode = setup_tty(fp, prompts[i].hidden, &saveparm, &osigint); if (errcode) break; /* put out the prompt */ (void)fputs(prompts[i].prompt, stdout); (void)fputs(": ", stdout); (void)fflush(stdout); (void)memset(prompts[i].reply->data, 0, prompts[i].reply->length); got_int = 0; retp = fgets(prompts[i].reply->data, (int)prompts[i].reply->length, fp); if (prompts[i].hidden) putchar('\n'); if (retp == NULL) { if (got_int) errcode = KRB5_LIBOS_PWDINTR; else errcode = KRB5_LIBOS_CANTREADPWD; restore_tty(fp, &saveparm, &osigint); break; } /* replace newline with null */ retp = strchr(prompts[i].reply->data, '\n'); if (retp != NULL) *retp = '\0'; else { /* flush rest of input line */ do { scratchchar = getc(fp); } while (scratchchar != EOF && scratchchar != '\n'); } errcode = restore_tty(fp, &saveparm, &osigint); if (errcode) break; prompts[i].reply->length = strlen(prompts[i].reply->data); } cleanup: if (fp != NULL) fclose(fp); else if (fd >= 0) close(fd); return errcode; } static void intrfunc(int sig) { got_int = 1; } static void catch_signals(osiginfo *osigint) { #ifdef POSIX_SIGNALS struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = intrfunc; sigaction(SIGINT, &sa, osigint); #else *osigint = signal(SIGINT, intrfunc); #endif } static void restore_signals(osiginfo *osigint) { #ifdef POSIX_SIGNALS sigaction(SIGINT, osigint, NULL); #else signal(SIGINT, *osigint); #endif } static krb5_error_code setup_tty(FILE *fp, int hidden, struct termios *saveparm, osiginfo *osigint) { krb5_error_code ret; int fd; struct termios tparm; ret = KRB5_LIBOS_CANTREADPWD; catch_signals(osigint); fd = fileno(fp); do { if (!isatty(fd)) { ret = 0; break; } if (tcgetattr(fd, &tparm) < 0) break; *saveparm = tparm; #ifndef ECHO_PASSWORD if (hidden) tparm.c_lflag &= ~(ECHO|ECHONL); #endif tparm.c_lflag |= ISIG|ICANON; if (tcsetattr(STDIN_FILENO, TCSANOW, &tparm) < 0) break; ret = 0; } while (0); /* If we're losing, restore signal handlers. */ if (ret) restore_signals(osigint); return ret; } static krb5_error_code restore_tty(FILE* fp, struct termios *saveparm, osiginfo *osigint) { int ret, fd; ret = 0; fd = fileno(fp); if (isatty(fd)) { ret = tcsetattr(fd, TCSANOW, saveparm); if (ret < 0) ret = KRB5_LIBOS_CANTREADPWD; else ret = 0; } restore_signals(osigint); return ret; } #else /* non-Cygwin Windows, or Mac */ #if defined(_WIN32) #include krb5_error_code KRB5_CALLCONV krb5_prompter_posix(krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]) { HANDLE handle; DWORD old_mode, new_mode; char *ptr; int scratchchar; krb5_error_code errcode = 0; int i; handle = GetStdHandle(STD_INPUT_HANDLE); if (handle == INVALID_HANDLE_VALUE) return ENOTTY; if (!GetConsoleMode(handle, &old_mode)) return ENOTTY; new_mode = old_mode; new_mode |= ( ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT ); new_mode &= ~( ENABLE_ECHO_INPUT ); if (!SetConsoleMode(handle, new_mode)) return ENOTTY; if (!SetConsoleMode(handle, old_mode)) return ENOTTY; if (name) { fputs(name, stdout); fputs("\n", stdout); } if (banner) { fputs(banner, stdout); fputs("\n", stdout); } for (i = 0; i < num_prompts; i++) { if (prompts[i].hidden) { if (!SetConsoleMode(handle, new_mode)) { errcode = ENOTTY; goto cleanup; } } fputs(prompts[i].prompt,stdout); fputs(": ", stdout); fflush(stdout); memset(prompts[i].reply->data, 0, prompts[i].reply->length); if (fgets(prompts[i].reply->data, prompts[i].reply->length, stdin) == NULL) { if (prompts[i].hidden) putchar('\n'); errcode = KRB5_LIBOS_CANTREADPWD; goto cleanup; } if (prompts[i].hidden) putchar('\n'); /* fgets always null-terminates the returned string */ /* replace newline with null */ if ((ptr = strchr(prompts[i].reply->data, '\n'))) *ptr = '\0'; else /* flush rest of input line */ do { scratchchar = getchar(); } while (scratchchar != EOF && scratchchar != '\n'); prompts[i].reply->length = strlen(prompts[i].reply->data); if (!SetConsoleMode(handle, old_mode)) { errcode = ENOTTY; goto cleanup; } } cleanup: if (errcode) { for (i = 0; i < num_prompts; i++) { memset(prompts[i].reply->data, 0, prompts[i].reply->length); } } return errcode; } #else /* !_WIN32 */ krb5_error_code KRB5_CALLCONV krb5_prompter_posix(krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]) { return(EINVAL); } #endif /* !_WIN32 */ #endif /* Windows or Mac */ void k5_set_prompt_types(krb5_context context, krb5_prompt_type *types) { context->prompt_types = types; } krb5_prompt_type* KRB5_CALLCONV krb5_get_prompt_types(krb5_context context) { return context->prompt_types; } krb5-1.22.1/src/lib/krb5/os/write_msg.c0000664000175000017500000000534415051422640017334 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/write_msg.c - convenience sendauh/recvauth functions */ /* * Copyright 1991, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include #include "os-proto.h" /* * Try to write a series of messages with as few write(v) system calls * as possible, to avoid Nagle/DelayedAck problems. Cheating here a * little -- I know the only cases we have at the moment will send one * or two messages in a call. Sending more will work, but not as * efficiently. */ krb5_error_code k5_write_messages(krb5_context context, krb5_pointer fdp, krb5_data *outbuf, int nbufs) { int fd = *( (int *) fdp); while (nbufs) { int nbufs1; sg_buf sg[4]; krb5_int32 len[2]; if (nbufs > 1) nbufs1 = 2; else nbufs1 = 1; len[0] = htonl(outbuf[0].length); SG_SET(&sg[0], &len[0], 4); SG_SET(&sg[1], outbuf[0].length ? outbuf[0].data : NULL, outbuf[0].length); if (nbufs1 == 2) { len[1] = htonl(outbuf[1].length); SG_SET(&sg[2], &len[1], 4); SG_SET(&sg[3], outbuf[1].length ? outbuf[1].data : NULL, outbuf[1].length); } if (krb5int_net_writev(context, fd, sg, nbufs1 * 2) < 0) { return errno; } outbuf += nbufs1; nbufs -= nbufs1; } return(0); } krb5_error_code krb5_write_message(krb5_context context, krb5_pointer fdp, krb5_data *outbuf) { return k5_write_messages(context, fdp, outbuf, 1); } krb5-1.22.1/src/lib/krb5/os/timeofday.c0000664000175000017500000000433715051422640017316 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/timeofday.c */ /* * Copyright 1990, 2007 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include krb5_error_code KRB5_CALLCONV krb5_timeofday(krb5_context context, krb5_timestamp *timeret) { krb5_os_context os_ctx; time_t tval; if (context == NULL) return EINVAL; os_ctx = &context->os_context; if (os_ctx->os_flags & KRB5_OS_TOFFSET_TIME) { *timeret = os_ctx->time_offset; return 0; } tval = time(0); if (tval == (time_t) -1) return (krb5_error_code) errno; if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) tval += os_ctx->time_offset; *timeret = tval; return 0; } krb5_error_code KRB5_CALLCONV krb5_check_clockskew(krb5_context context, krb5_timestamp date) { krb5_timestamp currenttime; krb5_error_code retval; retval = krb5_timeofday(context, ¤ttime); if (retval) return retval; if (!ts_within(date, currenttime, context->clockskew)) return KRB5KRB_AP_ERR_SKEW; return 0; } krb5-1.22.1/src/lib/krb5/os/ref_std_conf.out0000664000175000017500000000110015051422640020336 0ustar ghudsonghudsonkrb5_get_default_realm() returned 'DEFAULT.REALM.TST' krb5_set_default_realm(NEW.DEFAULT.REALM) krb5_get_default_realm() returned 'NEW.DEFAULT.REALM' krb5_get_realm_domain(DEFAULT_REALM.TST) returned 'MIT.EDU' krb_get_host_realm(bad.idea) returned: 'US.GOV' krb_get_host_realm(itar.bad.idea) returned: 'NSA.GOV' krb_get_host_realm(really.BAD.IDEA.) returned: 'NSA.GOV' krb_get_host_realm(clipper.bad.idea) returned: 'NIST.GOV' krb_get_host_realm(KeYEsCrOW.BaD.IDea) returned: 'NSA.GOV' krb_get_host_realm(pgp.good.idea) returned: '' krb_get_host_realm(no_domain) returned: '' krb5-1.22.1/src/lib/krb5/os/accessor.c0000664000175000017500000001047715051422640017141 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/accessor.c */ /* * Copyright 1990, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "os-proto.h" #include "../krb/int-proto.h" /* If this trick gets used elsewhere, move it to k5-platform.h. */ #ifndef DESIGNATED_INITIALIZERS /* ANSI/ISO C 1999 supports this... */ #if __STDC_VERSION__ >= 199901L \ /* ...as does GCC, since version 2.something. */ \ || (!defined __cplusplus && __GNUC__ >= 3) #define DESIGNATED_INITIALIZERS 1 #else #define DESIGNATED_INITIALIZERS 0 #endif #endif krb5_error_code KRB5_CALLCONV krb5int_accessor(krb5int_access *internals, krb5_int32 version) { if (version == KRB5INT_ACCESS_VERSION) { #if DESIGNATED_INITIALIZERS #define S(FIELD, VAL) .FIELD = VAL #if defined __GNUC__ && __STDC_VERSION__ < 199901L __extension__ #endif static const krb5int_access internals_temp = { #else #define S(FIELD, VAL) internals_temp.FIELD = VAL krb5int_access internals_temp; #endif S (auth_con_get_subkey_enctype, krb5_auth_con_get_subkey_enctype), #ifndef LEAN_CLIENT #define SC(FIELD, VAL) S(FIELD, VAL) #else /* disable */ #define SC(FIELD, VAL) S(FIELD, 0) #endif SC (ser_pack_int64, krb5_ser_pack_int64), SC (ser_unpack_int64, krb5_ser_unpack_int64), #undef SC #ifdef ENABLE_LDAP #define SC(FIELD, VAL) S(FIELD, VAL) #else #define SC(FIELD, VAL) S(FIELD, 0) #endif SC (asn1_ldap_encode_sequence_of_keys, krb5int_ldap_encode_sequence_of_keys), SC (asn1_ldap_decode_sequence_of_keys, krb5int_ldap_decode_sequence_of_keys), #undef SC #ifndef DISABLE_PKINIT #define SC(FIELD, VAL) S(FIELD, VAL) #else /* disable */ #define SC(FIELD, VAL) S(FIELD, 0) #endif SC (encode_krb5_pa_pk_as_req, encode_krb5_pa_pk_as_req), SC (encode_krb5_pa_pk_as_rep, encode_krb5_pa_pk_as_rep), SC (encode_krb5_auth_pack, encode_krb5_auth_pack), SC (encode_krb5_kdc_dh_key_info, encode_krb5_kdc_dh_key_info), SC (encode_krb5_reply_key_pack, encode_krb5_reply_key_pack), SC (encode_krb5_td_trusted_certifiers, encode_krb5_td_trusted_certifiers), SC (encode_krb5_td_dh_parameters, encode_krb5_td_dh_parameters), SC (decode_krb5_pa_pk_as_req, decode_krb5_pa_pk_as_req), SC (decode_krb5_pa_pk_as_rep, decode_krb5_pa_pk_as_rep), SC (decode_krb5_auth_pack, decode_krb5_auth_pack), SC (decode_krb5_kdc_dh_key_info, decode_krb5_kdc_dh_key_info), SC (decode_krb5_principal_name, decode_krb5_principal_name), SC (decode_krb5_reply_key_pack, decode_krb5_reply_key_pack), SC (decode_krb5_td_trusted_certifiers, decode_krb5_td_trusted_certifiers), SC (decode_krb5_td_dh_parameters, decode_krb5_td_dh_parameters), SC (encode_krb5_kdc_req_body, encode_krb5_kdc_req_body), SC (free_kdc_req, krb5_free_kdc_req), SC (set_prompt_types, k5_set_prompt_types), #undef SC #if DESIGNATED_INITIALIZERS }; #else 0; #endif *internals = internals_temp; return 0; } return KRB5_OBSOLETE_FN; } krb5-1.22.1/src/lib/krb5/os/addr.c0000664000175000017500000000771515051422640016252 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/addr.c - socket address utilities */ /* * Copyright (C) 2024 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "socket-utils.h" const krb5_address k5_addr_directional_init = { KV5M_ADDRESS, ADDRTYPE_DIRECTIONAL, 4, (uint8_t *)"\x00\x00\x00\x00" }; const krb5_address k5_addr_directional_accept = { KV5M_ADDRESS, ADDRTYPE_DIRECTIONAL, 4, (uint8_t *)"\x00\x00\x00\x01" }; krb5_error_code k5_sockaddr_to_address(const struct sockaddr *sa, krb5_boolean local_use, krb5_address *out) { if (sa->sa_family == AF_INET) { const struct sockaddr_in *sin = sa2sin(sa); out->addrtype = ADDRTYPE_INET; out->length = sizeof(sin->sin_addr); out->contents = (uint8_t *)&sin->sin_addr; } else if (sa->sa_family == AF_INET6) { const struct sockaddr_in6 *sin6 = sa2sin6(sa); if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { out->addrtype = ADDRTYPE_INET; out->contents = (uint8_t *)&sin6->sin6_addr + 12; out->length = 4; } else { out->addrtype = ADDRTYPE_INET6; out->length = sizeof(sin6->sin6_addr); out->contents = (uint8_t *)&sin6->sin6_addr; } #ifndef _WIN32 } else if (sa->sa_family == AF_UNIX && local_use) { const struct sockaddr_un *sun = sa2sun(sa); out->addrtype = ADDRTYPE_UNIXSOCK; out->length = strlen(sun->sun_path); out->contents = (uint8_t *)sun->sun_path; #endif } else { return KRB5_PROG_ATYPE_NOSUPP; } out->magic = KV5M_ADDRESS; return 0; } void k5_print_addr(const struct sockaddr *sa, char *buf, size_t len) { if (sa_is_inet(sa)) { if (getnameinfo(sa, sa_socklen(sa), buf, len, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV) != 0) strlcpy(buf, "", len); #ifndef _WIN32 } else if (sa->sa_family == AF_UNIX) { strlcpy(buf, sa2sun(sa)->sun_path, len); #endif } else { strlcpy(buf, "", len); } } void k5_print_addr_port(const struct sockaddr *sa, char *buf, size_t len) { char addr[64], port[10]; if (sa_is_inet(sa)) { if (getnameinfo(sa, sa_socklen(sa), addr, sizeof(addr), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) != 0) { strlcpy(buf, "", len); } else if (sa->sa_family == AF_INET) { (void)snprintf(buf, len, "%s:%s", addr, port); } else { (void)snprintf(buf, len, "[%s]:%s", addr, port); } } else { k5_print_addr(sa, buf, len); } } krb5-1.22.1/src/lib/krb5/os/net_write.c0000664000175000017500000000517115051422640017332 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/net_write.c */ /* * Copyright 1987, 1988, 1990, 2009 by the Massachusetts Institute of * Technology. All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "os-proto.h" /* * krb5_net_write() writes "len" bytes from "buf" to the file * descriptor "fd". It returns the number of bytes written or * a write() error. (The calling interface is identical to * write(2).) * * XXX must not use non-blocking I/O */ int krb5_net_write(krb5_context context, int fd, const char *buf, int len) { sg_buf sg; SG_SET(&sg, buf, len); return krb5int_net_writev(context, fd, &sg, 1); } int krb5int_net_writev(krb5_context context, int fd, sg_buf *sgp, int nsg) { ssize_t cc, len = 0; SOCKET_WRITEV_TEMP tmp; while (nsg > 0) { /* Skip any empty data blocks. */ if (SG_LEN(sgp) == 0) { sgp++, nsg--; continue; } cc = SOCKET_WRITEV((SOCKET)fd, sgp, nsg, tmp); if (cc < 0) { if (SOCKET_ERRNO == SOCKET_EINTR) continue; /* XXX this interface sucks! */ errno = SOCKET_ERRNO; return -1; } len += cc; while (cc > 0) { if ((unsigned)cc < SG_LEN(sgp)) { SG_ADVANCE(sgp, (unsigned)cc); cc = 0; } else { cc -= SG_LEN(sgp); sgp++, nsg--; assert(nsg > 0 || cc == 0); } } } return len; } krb5-1.22.1/src/lib/krb5/os/hostaddr.c0000664000175000017500000001001415051422640017132 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/hostaddr.c - Return list of krb5 addresses for a hostname */ /* * Copyright 1990,1991,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "os-proto.h" #include "fake-addrinfo.h" krb5_error_code k5_os_hostaddr(krb5_context context, const char *name, krb5_address ***ret_addrs) { krb5_error_code retval; krb5_address **addrs = NULL; size_t i, j; int r; struct addrinfo hints, *ai = NULL, *aip; if (!name) return KRB5_ERR_BAD_HOSTNAME; memset (&hints, 0, sizeof (hints)); hints.ai_flags = AI_NUMERICHOST | AI_ADDRCONFIG; /* We don't care what kind at this point, really, but without this, we can get back multiple sockaddrs per address, for SOCK_DGRAM, SOCK_STREAM, and SOCK_RAW. I haven't checked if that's what the spec indicates. */ hints.ai_socktype = SOCK_DGRAM; r = getaddrinfo (name, 0, &hints, &ai); if (r && AI_NUMERICHOST != 0) { hints.ai_flags &= ~AI_NUMERICHOST; r = getaddrinfo (name, 0, &hints, &ai); } if (r) return KRB5_ERR_BAD_HOSTNAME; for (i = 0, aip = ai; aip; aip = aip->ai_next) { switch (aip->ai_addr->sa_family) { case AF_INET: case AF_INET6: i++; default: /* Ignore addresses of unknown families. */ ; } } addrs = k5calloc(i + 1, sizeof(*addrs), &retval); if (addrs == NULL) goto errout; for (j = 0; j < i + 1; j++) addrs[j] = 0; for (i = 0, aip = ai; aip; aip = aip->ai_next) { const void *ptr; size_t addrlen; int atype; switch (aip->ai_addr->sa_family) { case AF_INET: addrlen = sizeof (struct in_addr); ptr = &sa2sin(aip->ai_addr)->sin_addr; atype = ADDRTYPE_INET; break; case AF_INET6: addrlen = sizeof (struct in6_addr); ptr = &sa2sin6(aip->ai_addr)->sin6_addr; atype = ADDRTYPE_INET6; break; default: continue; } addrs[i] = (krb5_address *) malloc(sizeof(krb5_address)); if (!addrs[i]) { retval = ENOMEM; goto errout; } addrs[i]->magic = KV5M_ADDRESS; addrs[i]->addrtype = atype; addrs[i]->length = addrlen; addrs[i]->contents = k5memdup(ptr, addrlen, &retval); if (addrs[i]->contents == NULL) goto errout; i++; } *ret_addrs = addrs; if (ai) freeaddrinfo(ai); return 0; errout: if (addrs) { for (i = 0; addrs[i]; i++) { free (addrs[i]->contents); free (addrs[i]); } krb5_free_addresses(context, addrs); } if (ai) freeaddrinfo(ai); return retval; } krb5-1.22.1/src/lib/krb5/os/full_ipadr.c0000664000175000017500000000574515051422640017462 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/full_ipadr.c - Generate full address from IP addr and port */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #ifdef HAVE_NETINET_IN_H #include "os-proto.h" krb5_error_code krb5_make_full_ipaddr(krb5_context context, krb5_int32 adr, /*krb5_int16*/int port, krb5_address **outaddr) { unsigned long smushaddr = (unsigned long) adr; /* already in net order */ unsigned short smushport = (unsigned short) port; /* ditto */ krb5_address *retaddr; krb5_octet *marshal; krb5_addrtype temptype; krb5_int32 templength; if (!(retaddr = (krb5_address *)malloc(sizeof(*retaddr)))) { return ENOMEM; } retaddr->magic = KV5M_ADDRESS; retaddr->addrtype = ADDRTYPE_ADDRPORT; retaddr->length = sizeof(smushaddr)+ sizeof(smushport) + 2*sizeof(temptype) + 2*sizeof(templength); if (!(retaddr->contents = (krb5_octet *)malloc(retaddr->length))) { free(retaddr); return ENOMEM; } marshal = retaddr->contents; temptype = htons(ADDRTYPE_INET); (void) memcpy(marshal, &temptype, sizeof(temptype)); marshal += sizeof(temptype); templength = htonl(sizeof(smushaddr)); (void) memcpy(marshal, &templength, sizeof(templength)); marshal += sizeof(templength); (void) memcpy(marshal, &smushaddr, sizeof(smushaddr)); marshal += sizeof(smushaddr); temptype = htons(ADDRTYPE_IPPORT); (void) memcpy(marshal, &temptype, sizeof(temptype)); marshal += sizeof(temptype); templength = htonl(sizeof(smushport)); (void) memcpy(marshal, &templength, sizeof(templength)); marshal += sizeof(templength); (void) memcpy(marshal, &smushport, sizeof(smushport)); marshal += sizeof(smushport); *outaddr = retaddr; return 0; } #endif krb5-1.22.1/src/lib/krb5/os/locate_kdc.c0000664000175000017500000007263015051422640017426 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/locate_kdc.c - Get addresses for realm KDCs and other servers */ /* * Copyright 1990,2000,2001,2002,2003,2004,2006,2008 Massachusetts Institute of * Technology. All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "fake-addrinfo.h" #include "os-proto.h" #ifdef KRB5_DNS_LOOKUP #define DEFAULT_LOOKUP_KDC 1 #if KRB5_DNS_LOOKUP_REALM #define DEFAULT_LOOKUP_REALM 1 #else #define DEFAULT_LOOKUP_REALM 0 #endif #define DEFAULT_URI_LOOKUP TRUE struct kdclist_entry { krb5_data realm; struct server_entry server; }; struct kdclist { size_t count; struct kdclist_entry *list; }; static int maybe_use_dns (krb5_context context, const char *name, int defalt) { krb5_error_code code; char * value = NULL; int use_dns = 0; code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, name, 0, 0, &value); if (value == 0 && code == 0) { code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_DNS_FALLBACK, 0, 0, &value); } if (code) return defalt; if (value == 0) return defalt; use_dns = _krb5_conf_boolean(value); profile_release_string(value); return use_dns; } static krb5_boolean use_dns_uri(krb5_context ctx) { krb5_error_code ret; int use; ret = profile_get_boolean(ctx->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_DNS_URI_LOOKUP, NULL, DEFAULT_URI_LOOKUP, &use); return ret ? DEFAULT_URI_LOOKUP : use; } int _krb5_use_dns_kdc(krb5_context context) { return maybe_use_dns(context, KRB5_CONF_DNS_LOOKUP_KDC, DEFAULT_LOOKUP_KDC); } int _krb5_use_dns_realm(krb5_context context) { return maybe_use_dns(context, KRB5_CONF_DNS_LOOKUP_REALM, DEFAULT_LOOKUP_REALM); } static krb5_error_code get_sitename(krb5_context context, const krb5_data *realm, char **out) { krb5_error_code ret; char *realmstr; *out = NULL; realmstr = k5memdup0(realm->data, realm->length, &ret); if (realmstr == NULL) return ret; ret = profile_get_string(context->profile, KRB5_CONF_REALMS, realmstr, KRB5_CONF_SITENAME, NULL, out); free(realmstr); return ret; } #endif /* KRB5_DNS_LOOKUP */ /* Free up everything pointed to by the serverlist structure, but don't * free the structure itself. */ void k5_free_serverlist (struct serverlist *list) { size_t i; for (i = 0; i < list->nservers; i++) { free(list->servers[i].hostname); free(list->servers[i].uri_path); } free(list->servers); list->servers = NULL; list->nservers = 0; } #include static inline void Tprintf(const char *fmt, ...) { #ifdef TEST va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); #endif } /* Make room for a new server entry in list and return a pointer to the new * entry. (Do not increment list->nservers.) */ static struct server_entry * new_server_entry(struct serverlist *list) { struct server_entry *newservers, *entry; size_t newspace = (list->nservers + 1) * sizeof(struct server_entry); newservers = realloc(list->servers, newspace); if (newservers == NULL) return NULL; list->servers = newservers; entry = &newservers[list->nservers]; memset(entry, 0, sizeof(*entry)); entry->primary = -1; return entry; } /* Add an address entry to list. */ static int add_addr_to_list(struct serverlist *list, k5_transport transport, int family, size_t addrlen, struct sockaddr *addr) { struct server_entry *entry; entry = new_server_entry(list); if (entry == NULL) return ENOMEM; entry->transport = transport; entry->family = family; entry->hostname = NULL; entry->uri_path = NULL; entry->addrlen = addrlen; memcpy(&entry->addr, addr, addrlen); list->nservers++; return 0; } /* Add a hostname entry to list. */ static int add_host_to_list(struct serverlist *list, const char *hostname, int port, k5_transport transport, int family, const char *uri_path, int primary) { struct server_entry *entry; entry = new_server_entry(list); if (entry == NULL) return ENOMEM; entry->transport = transport; entry->family = family; entry->hostname = strdup(hostname); if (entry->hostname == NULL) goto oom; if (uri_path != NULL) { entry->uri_path = strdup(uri_path); if (entry->uri_path == NULL) goto oom; } entry->port = port; entry->primary = primary; list->nservers++; return 0; oom: free(entry->hostname); entry->hostname = NULL; return ENOMEM; } static void parse_uri_if_https(const char *host_or_uri, k5_transport *transport, const char **host, const char **uri_path) { char *cp; if (strncmp(host_or_uri, "https://", 8) == 0) { *transport = HTTPS; *host = host_or_uri + 8; cp = strchr(*host, '/'); if (cp != NULL) { *cp = '\0'; *uri_path = cp + 1; } } } /* Return true if server is identical to an entry in list. */ static krb5_boolean server_list_contains(struct serverlist *list, struct server_entry *server) { struct server_entry *ent; for (ent = list->servers; ent < list->servers + list->nservers; ent++) { if (server->port != ent->port) continue; if (server->hostname != NULL && ent->hostname != NULL && strcmp(server->hostname, ent->hostname) == 0) return TRUE; if (server->hostname == NULL && ent->hostname == NULL && server->addrlen == ent->addrlen && memcmp(&server->addr, &ent->addr, server->addrlen) == 0) return TRUE; } return FALSE; } static krb5_error_code locate_srv_conf_1(krb5_context context, const krb5_data *realm, const char * name, struct serverlist *serverlist, k5_transport transport, int udpport) { const char *realm_srv_names[4]; char **hostlist = NULL, *realmstr = NULL, *host = NULL; const char *hostspec; krb5_error_code code; size_t i; int default_port; Tprintf("looking in krb5.conf for realm %s entry %s; ports %d,%d\n", realm->data, name, udpport); realmstr = k5memdup0(realm->data, realm->length, &code); if (realmstr == NULL) goto cleanup; realm_srv_names[0] = KRB5_CONF_REALMS; realm_srv_names[1] = realmstr; realm_srv_names[2] = name; realm_srv_names[3] = 0; code = profile_get_values(context->profile, realm_srv_names, &hostlist); if (code == PROF_NO_RELATION && strcmp(name, KRB5_CONF_PRIMARY_KDC) == 0) { realm_srv_names[2] = KRB5_CONF_MASTER_KDC; code = profile_get_values(context->profile, realm_srv_names, &hostlist); } if (code) { Tprintf("config file lookup failed: %s\n", error_message(code)); if (code == PROF_NO_SECTION || code == PROF_NO_RELATION) code = 0; goto cleanup; } for (i = 0; hostlist[i]; i++) { int port_num; k5_transport this_transport = transport; const char *uri_path = NULL; hostspec = hostlist[i]; Tprintf("entry %d is '%s'\n", i, hostspec); #ifndef _WIN32 if (hostspec[0] == '/') { struct sockaddr_un sun = { 0 }; sun.sun_family = AF_UNIX; if (strlcpy(sun.sun_path, hostspec, sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) { code = ENAMETOOLONG; goto cleanup; } code = add_addr_to_list(serverlist, UNIXSOCK, AF_UNIX, sizeof(sun), (struct sockaddr *)&sun); if (code) goto cleanup; continue; } #endif parse_uri_if_https(hostspec, &this_transport, &hostspec, &uri_path); default_port = (this_transport == HTTPS) ? 443 : udpport; code = k5_parse_host_string(hostspec, default_port, &host, &port_num); if (code == 0 && host == NULL) code = EINVAL; if (code) goto cleanup; code = add_host_to_list(serverlist, host, port_num, this_transport, AF_UNSPEC, uri_path, -1); if (code) goto cleanup; free(host); host = NULL; } cleanup: free(realmstr); free(host); profile_free_list(hostlist); return code; } #ifdef TEST static krb5_error_code krb5_locate_srv_conf(krb5_context context, const krb5_data *realm, const char *name, struct serverlist *al, int udpport) { krb5_error_code ret; ret = locate_srv_conf_1(context, realm, name, al, TCP_OR_UDP, udpport); if (ret) return ret; if (al->nservers == 0) /* Couldn't resolve any KDC names */ return KRB5_REALM_CANT_RESOLVE; return 0; } #endif #ifdef KRB5_DNS_LOOKUP static krb5_error_code locate_srv_dns_1(krb5_context context, const krb5_data *realm, const char *service, const char *protocol, struct serverlist *serverlist) { struct srv_dns_entry *head = NULL, *entry = NULL; krb5_error_code code = 0; k5_transport transport; char *sitename; code = get_sitename(context, realm, &sitename); if (code) return code; code = krb5int_make_srv_query_realm(context, realm, service, protocol, sitename, &head); free(sitename); if (code) return 0; if (head == NULL) return 0; /* Check for the "." case indicating no support. */ if (head->next == NULL && head->host[0] == '\0') { code = KRB5_ERR_NO_SERVICE; goto cleanup; } for (entry = head; entry != NULL; entry = entry->next) { transport = (strcmp(protocol, "_tcp") == 0) ? TCP : UDP; code = add_host_to_list(serverlist, entry->host, entry->port, transport, AF_UNSPEC, NULL, -1); if (code) goto cleanup; } cleanup: krb5int_free_srv_dns_data(head); return code; } #endif #include #if TARGET_OS_MAC static const char *objdirs[] = { KRB5_PLUGIN_BUNDLE_DIR, LIBDIR "/krb5/plugins/libkrb5", NULL }; /* should be a list */ #else static const char *objdirs[] = { LIBDIR "/krb5/plugins/libkrb5", NULL }; #endif struct module_callback_data { int out_of_mem; struct serverlist *list; }; static int module_callback(void *cbdata, int socktype, struct sockaddr *sa) { struct module_callback_data *d = cbdata; size_t addrlen; k5_transport transport; if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM) return 0; if (sa->sa_family == AF_INET) addrlen = sizeof(struct sockaddr_in); else if (sa->sa_family == AF_INET6) addrlen = sizeof(struct sockaddr_in6); else return 0; transport = (socktype == SOCK_STREAM) ? TCP : UDP; if (add_addr_to_list(d->list, transport, sa->sa_family, addrlen, sa) != 0) { /* Assumes only error is ENOMEM. */ d->out_of_mem = 1; return 1; } return 0; } static krb5_error_code module_locate_server(krb5_context ctx, const krb5_data *realm, struct serverlist *serverlist, enum locate_service_type svc, k5_transport transport) { struct krb5plugin_service_locate_result *res = NULL; krb5_error_code code; struct krb5plugin_service_locate_ftable *vtbl = NULL; void **ptrs; char *realmz; /* NUL-terminated realm */ size_t i; int socktype; struct module_callback_data cbdata = { 0, }; const char *msg; Tprintf("in module_locate_server\n"); cbdata.list = serverlist; if (!PLUGIN_DIR_OPEN(&ctx->libkrb5_plugins)) { code = krb5int_open_plugin_dirs(objdirs, NULL, &ctx->libkrb5_plugins, &ctx->err); if (code) return KRB5_PLUGIN_NO_HANDLE; } code = krb5int_get_plugin_dir_data(&ctx->libkrb5_plugins, "service_locator", &ptrs, &ctx->err); if (code) { Tprintf("error looking up plugin symbols: %s\n", (msg = krb5_get_error_message(ctx, code))); krb5_free_error_message(ctx, msg); return KRB5_PLUGIN_NO_HANDLE; } if (realm->length >= UINT_MAX) { krb5int_free_plugin_dir_data(ptrs); return ENOMEM; } realmz = k5memdup0(realm->data, realm->length, &code); if (realmz == NULL) { krb5int_free_plugin_dir_data(ptrs); return code; } for (i = 0; ptrs[i]; i++) { void *blob; vtbl = ptrs[i]; Tprintf("element %d is %p\n", i, ptrs[i]); /* For now, don't keep the plugin data alive. For long-lived * contexts, it may be desirable to change that later. */ code = vtbl->init(ctx, &blob); if (code) continue; socktype = (transport == TCP) ? SOCK_STREAM : SOCK_DGRAM; code = vtbl->lookup(blob, svc, realmz, socktype, AF_UNSPEC, module_callback, &cbdata); /* Also ask for TCP addresses if we got UDP addresses and want both. */ if (code == 0 && transport == TCP_OR_UDP) { code = vtbl->lookup(blob, svc, realmz, SOCK_STREAM, AF_UNSPEC, module_callback, &cbdata); if (code == KRB5_PLUGIN_NO_HANDLE) code = 0; } vtbl->fini(blob); if (code == KRB5_PLUGIN_NO_HANDLE) { /* Module passes, keep going. */ /* XXX */ Tprintf("plugin doesn't handle this realm (KRB5_PLUGIN_NO_HANDLE)" "\n"); continue; } if (code != 0) { /* Module encountered an actual error. */ Tprintf("plugin lookup routine returned error %d: %s\n", code, error_message(code)); free(realmz); krb5int_free_plugin_dir_data(ptrs); return code; } break; } if (ptrs[i] == NULL) { Tprintf("ran off end of plugin list\n"); free(realmz); krb5int_free_plugin_dir_data(ptrs); return KRB5_PLUGIN_NO_HANDLE; } Tprintf("stopped with plugin #%d, res=%p\n", i, res); /* Got something back, yippee. */ Tprintf("now have %lu addrs in list %p\n", (unsigned long)serverlist->nservers, serverlist); free(realmz); krb5int_free_plugin_dir_data(ptrs); return 0; } static krb5_error_code prof_locate_server(krb5_context context, const krb5_data *realm, struct serverlist *serverlist, enum locate_service_type svc, k5_transport transport) { const char *profname; int dflport = 0; struct servent *serv; switch (svc) { case locate_service_kdc: profname = KRB5_CONF_KDC; /* We used to use /etc/services for these, but enough systems have old, * crufty, wrong settings that this is probably better. */ kdc_ports: dflport = KRB5_DEFAULT_PORT; break; case locate_service_primary_kdc: profname = KRB5_CONF_PRIMARY_KDC; goto kdc_ports; case locate_service_kadmin: profname = KRB5_CONF_ADMIN_SERVER; dflport = DEFAULT_KADM5_PORT; break; case locate_service_krb524: profname = KRB5_CONF_KRB524_SERVER; serv = getservbyname("krb524", "udp"); dflport = serv ? serv->s_port : 4444; break; case locate_service_kpasswd: profname = KRB5_CONF_KPASSWD_SERVER; dflport = DEFAULT_KPASSWD_PORT; break; default: return EBUSY; /* XXX */ } return locate_srv_conf_1(context, realm, profname, serverlist, transport, dflport); } #ifdef KRB5_DNS_LOOKUP /* * Parse the initial part of the URI, first confirming the scheme name. Get * the transport, flags (indicating primary status), and host. The host is * either an address or hostname with an optional port, or an HTTPS URL. * The format is krb5srv:flags:udp|tcp|kkdcp:host * * Return a NULL *host_out if there are any problems parsing the URI. */ static void parse_uri_fields(const char *uri, k5_transport *transport_out, const char **host_out, int *primary_out) { k5_transport transport; int primary = FALSE; *transport_out = 0; *host_out = NULL; *primary_out = -1; /* Confirm the scheme name. */ if (strncasecmp(uri, "krb5srv", 7) != 0) return; uri += 7; if (*uri != ':') return; uri++; if (*uri == '\0') return; /* Check the flags field for supported flags. */ for (; *uri != ':' && *uri != '\0'; uri++) { if (*uri == 'm' || *uri == 'M') primary = TRUE; } if (*uri != ':') return; /* Look for the transport type. */ uri++; if (strncasecmp(uri, "udp", 3) == 0) { transport = UDP; uri += 3; } else if (strncasecmp(uri, "tcp", 3) == 0) { transport = TCP; uri += 3; } else if (strncasecmp(uri, "kkdcp", 5) == 0) { /* Currently the only MS-KKDCP transport type is HTTPS. */ transport = HTTPS; uri += 5; } else { return; } if (*uri != ':') return; /* The rest of the URI is the host (with optional port) or URI. */ *host_out = uri + 1; *transport_out = transport; *primary_out = primary; } /* * Collect a list of servers from DNS URI records, for the requested service * and transport type. Problematic entries are skipped. */ static krb5_error_code locate_uri(krb5_context context, const krb5_data *realm, const char *req_service, struct serverlist *serverlist, k5_transport req_transport, int default_port, krb5_boolean primary_only) { krb5_error_code ret; k5_transport transport, host_trans; struct srv_dns_entry *answers, *entry; char *host, *sitename; const char *host_field, *path; int port, def_port, primary; ret = get_sitename(context, realm, &sitename); if (ret) return ret; ret = k5_make_uri_query(context, realm, req_service, sitename, &answers); free(sitename); if (ret || answers == NULL) return ret; for (entry = answers; entry != NULL; entry = entry->next) { def_port = default_port; path = NULL; parse_uri_fields(entry->host, &transport, &host_field, &primary); if (host_field == NULL) continue; /* TCP_OR_UDP allows entries of any transport type; otherwise * we're asking for a match. */ if (req_transport != TCP_OR_UDP && req_transport != transport) continue; /* Process a MS-KKDCP target. */ if (transport == HTTPS) { host_trans = 0; def_port = 443; parse_uri_if_https(host_field, &host_trans, &host_field, &path); if (host_trans != HTTPS) continue; } ret = k5_parse_host_string(host_field, def_port, &host, &port); if (ret == ENOMEM) break; if (ret || host == NULL) { ret = 0; continue; } ret = add_host_to_list(serverlist, host, port, transport, AF_UNSPEC, path, primary); free(host); if (ret) break; } krb5int_free_srv_dns_data(answers); return ret; } static krb5_error_code dns_locate_server_uri(krb5_context context, const krb5_data *realm, struct serverlist *serverlist, enum locate_service_type svc, k5_transport transport) { krb5_error_code ret; char *svcname; int def_port; krb5_boolean find_primary = FALSE; if (!_krb5_use_dns_kdc(context) || !use_dns_uri(context)) return 0; switch (svc) { case locate_service_primary_kdc: find_primary = TRUE; /* Fall through */ case locate_service_kdc: svcname = "_kerberos"; def_port = 88; break; case locate_service_kadmin: svcname = "_kerberos-adm"; def_port = 749; break; case locate_service_kpasswd: svcname = "_kpasswd"; def_port = 464; break; default: return 0; } ret = locate_uri(context, realm, svcname, serverlist, transport, def_port, find_primary); if (serverlist->nservers == 0) TRACE_DNS_URI_NOTFOUND(context); return ret; } static krb5_error_code dns_locate_server_srv(krb5_context context, const krb5_data *realm, struct serverlist *serverlist, enum locate_service_type svc, k5_transport transport) { const char *dnsname; int use_dns = _krb5_use_dns_kdc(context); krb5_error_code code; if (!use_dns) return 0; switch (svc) { case locate_service_kdc: dnsname = "_kerberos"; break; case locate_service_primary_kdc: dnsname = "_kerberos-master"; break; case locate_service_kadmin: dnsname = "_kerberos-adm"; break; case locate_service_krb524: dnsname = "_krb524"; break; case locate_service_kpasswd: dnsname = "_kpasswd"; break; default: return 0; } code = 0; if (transport == UDP || transport == TCP_OR_UDP) code = locate_srv_dns_1(context, realm, dnsname, "_udp", serverlist); if ((transport == TCP || transport == TCP_OR_UDP) && code == 0) code = locate_srv_dns_1(context, realm, dnsname, "_tcp", serverlist); if (serverlist->nservers == 0) TRACE_DNS_SRV_NOTFOUND(context); return code; } #endif /* KRB5_DNS_LOOKUP */ /* * Try all of the server location methods in sequence. transport must be * TCP_OR_UDP, TCP, or UDP. It is applied to hostname entries in the profile * and affects whether we query modules or DNS for UDP or TCP or both, but does * not restrict a method from returning entries of other transports. */ static krb5_error_code locate_server(krb5_context context, const krb5_data *realm, struct serverlist *serverlist, enum locate_service_type svc, k5_transport transport) { krb5_error_code ret; struct serverlist list = SERVERLIST_INIT; *serverlist = list; /* Try modules. If a module returns 0 but leaves the list empty, return an * empty list. */ ret = module_locate_server(context, realm, &list, svc, transport); if (ret != KRB5_PLUGIN_NO_HANDLE) goto done; /* Try the profile. Fall back to DNS if it returns an empty list. */ ret = prof_locate_server(context, realm, &list, svc, transport); if (ret) goto done; #ifdef KRB5_DNS_LOOKUP if (list.nservers == 0) { ret = dns_locate_server_uri(context, realm, &list, svc, transport); if (ret) goto done; } if (list.nservers == 0) ret = dns_locate_server_srv(context, realm, &list, svc, transport); #endif done: if (ret) { k5_free_serverlist(&list); return ret; } *serverlist = list; return 0; } /* * Wrapper function for the various backends */ krb5_error_code k5_locate_server(krb5_context context, const krb5_data *realm, struct serverlist *serverlist, enum locate_service_type svc, krb5_boolean no_udp) { krb5_error_code ret; k5_transport transport = no_udp ? TCP : TCP_OR_UDP; memset(serverlist, 0, sizeof(*serverlist)); if (realm == NULL || realm->data == NULL || realm->data[0] == 0) { k5_setmsg(context, KRB5_REALM_CANT_RESOLVE, "Cannot find KDC for invalid realm name \"\""); return KRB5_REALM_CANT_RESOLVE; } ret = locate_server(context, realm, serverlist, svc, transport); if (ret) return ret; if (serverlist->nservers == 0) { k5_free_serverlist(serverlist); k5_setmsg(context, KRB5_REALM_UNKNOWN, _("Cannot find KDC for realm \"%.*s\""), realm->length, realm->data); return KRB5_REALM_UNKNOWN; } return 0; } krb5_error_code k5_locate_kdc(krb5_context context, const krb5_data *realm, struct serverlist *serverlist, krb5_boolean get_primaries, krb5_boolean no_udp) { enum locate_service_type stype; stype = get_primaries ? locate_service_primary_kdc : locate_service_kdc; return k5_locate_server(context, realm, serverlist, stype, no_udp); } krb5_error_code k5_kdclist_create(struct kdclist **kdcs_out) { struct kdclist *kdcs; *kdcs_out = NULL; kdcs = malloc(sizeof(*kdcs)); if (kdcs == NULL) return ENOMEM; kdcs->count = 0; kdcs->list = NULL; *kdcs_out = kdcs; return 0; } krb5_error_code k5_kdclist_add(struct kdclist *kdcs, const krb5_data *realm, struct server_entry *server) { krb5_error_code ret; struct kdclist_entry *newptr, *ent; newptr = realloc(kdcs->list, (kdcs->count + 1) * sizeof(*kdcs->list)); if (newptr == NULL) return ENOMEM; kdcs->list = newptr; ent = &kdcs->list[kdcs->count]; ret = krb5int_copy_data_contents(NULL, realm, &ent->realm); if (ret) return ret; /* Steal memory ownership from *server. */ ent->server = *server; memset(server, 0, sizeof(*server)); kdcs->count++; return 0; } /* * If primaries is empty, mark ent as primary (the realm has no primary KDCs * and therefore no KDCs are replicas). Otherwise mark ent according to * whether it is present in primaries. Return true if ent is determined to be * a replica. */ static krb5_boolean mark_entry(struct kdclist_entry *ent, struct serverlist *primaries) { if (primaries->nservers == 0) { ent->server.primary = 1; return FALSE; } ent->server.primary = server_list_contains(primaries, &ent->server); return !ent->server.primary; } /* Mark kdcs->list[start] and all entries with the same realm and transport * according to primaries. Stop and return true if a replica is found. */ static krb5_boolean mark_matching_servers(struct kdclist *kdcs, size_t start, struct serverlist *primaries) { size_t i; struct kdclist_entry *ent = &kdcs->list[start]; if (mark_entry(ent, primaries)) return TRUE; for (i = start + 1; i < kdcs->count; i++) { if (kdcs->list[i].server.primary == 1) continue; if (kdcs->list[i].server.transport != ent->server.transport) continue; if (!data_eq(kdcs->list[i].realm, ent->realm)) continue; if (mark_entry(&kdcs->list[i], primaries)) return TRUE; } return FALSE; } /* Return true if any entry in kdcs is a replica. May modify the primary * fields of entries in kdcs. */ krb5_boolean k5_kdclist_any_replicas(krb5_context context, struct kdclist *kdcs) { size_t i; struct kdclist_entry *ent; struct serverlist primaries; krb5_boolean found; /* Check if we already know that any of the KDCs is a replica. */ for (i = 0; i < kdcs->count; i++) { if (kdcs->list[i].server.primary == 0) return TRUE; } for (i = 0; i < kdcs->count; i++) { ent = &kdcs->list[i]; /* Skip this entry if we already know that it's not a replica. */ if (ent->server.primary == 1) continue; /* Look up the primary KDCs for this entry's realm and transport. Give * up and return false on error. */ if (locate_server(context, &ent->realm, &primaries, locate_service_primary_kdc, ent->server.transport) != 0) return FALSE; /* Using the list of primaries, determine whether this entry and any * entries with the same realm and transport are replicas. */ found = mark_matching_servers(kdcs, i, &primaries); k5_free_serverlist(&primaries); if (found) return TRUE; } return FALSE; } void k5_kdclist_free(struct kdclist *kdcs) { size_t i; if (kdcs == NULL) return; for (i = 0; i < kdcs->count; i++) { free(kdcs->list[i].realm.data); free(kdcs->list[i].server.hostname); free(kdcs->list[i].server.uri_path); } free(kdcs->list); free(kdcs); } krb5-1.22.1/src/lib/krb5/os/expand_path.c0000664000175000017500000003513715051422640017632 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/expand_path.c - Parameterized path expansion facility */ /* * Copyright (c) 2009, Secure Endpoints Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "os-proto.h" typedef int PTYPE; #ifdef _WIN32 #include #include /* * Expand a %{TEMP} token * * The %{TEMP} token expands to the temporary path for the current * user as returned by GetTempPath(). * * @note: Since the GetTempPath() function relies on the TMP or TEMP * environment variables, this function will failover to the system * temporary directory until the user profile is loaded. In addition, * the returned path may or may not exist. */ static krb5_error_code expand_temp_folder(krb5_context context, PTYPE param, const char *postfix, char **ret) { TCHAR tpath[MAX_PATH]; size_t len; if (!GetTempPath(sizeof(tpath) / sizeof(tpath[0]), tpath)) { k5_setmsg(context, EINVAL, "Failed to get temporary path (GLE=%d)", GetLastError()); return EINVAL; } len = strlen(tpath); if (len > 0 && tpath[len - 1] == '\\') tpath[len - 1] = '\0'; *ret = strdup(tpath); if (*ret == NULL) return ENOMEM; return 0; } /* * Expand a %{BINDIR} token * * This is also used to expand a few other tokens on Windows, since * most of the executable binaries end up in the same directory. The * "bin" directory is considered to be the directory in which the * krb5.dll is located. */ static krb5_error_code expand_bin_dir(krb5_context context, PTYPE param, const char *postfix, char **ret) { TCHAR path[MAX_PATH]; TCHAR *lastSlash; DWORD nc; nc = GetModuleFileName(get_lib_instance(), path, sizeof(path) / sizeof(path[0])); if (nc == 0 || nc == sizeof(path) / sizeof(path[0])) { return EINVAL; } lastSlash = strrchr(path, '\\'); if (lastSlash != NULL) { TCHAR *fslash = strrchr(lastSlash, '/'); if (fslash != NULL) lastSlash = fslash; *lastSlash = '\0'; } if (postfix) { if (strlcat(path, postfix, sizeof(path) / sizeof(path[0])) >= sizeof(path) / sizeof(path[0])) return EINVAL; } *ret = strdup(path); if (*ret == NULL) return ENOMEM; return 0; } /* * Expand a %{USERID} token * * The %{USERID} token expands to the string representation of the * user's SID. The user account that will be used is the account * corresponding to the current thread's security token. This means * that: * * - If the current thread token has the anonymous impersonation * level, the call will fail. * * - If the current thread is impersonating a token at * SecurityIdentification level the call will fail. * */ static krb5_error_code expand_userid(krb5_context context, PTYPE param, const char *postfix, char **ret) { int rv = EINVAL; HANDLE hThread = NULL; HANDLE hToken = NULL; PTOKEN_OWNER pOwner = NULL; DWORD len = 0; LPTSTR strSid = NULL; hThread = GetCurrentThread(); if (!OpenThreadToken(hThread, TOKEN_QUERY, FALSE, /* Open the thread token as the current thread user. */ &hToken)) { DWORD le = GetLastError(); if (le == ERROR_NO_TOKEN) { HANDLE hProcess = GetCurrentProcess(); le = 0; if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) le = GetLastError(); } if (le != 0) { k5_setmsg(context, rv, "Can't open thread token (GLE=%d)", le); goto cleanup; } } if (!GetTokenInformation(hToken, TokenOwner, NULL, 0, &len)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { k5_setmsg(context, rv, "Unexpected error reading token information (GLE=%d)", GetLastError()); goto cleanup; } if (len == 0) { k5_setmsg(context, rv, "GetTokenInformation() returned truncated buffer"); goto cleanup; } pOwner = malloc(len); if (pOwner == NULL) { rv = ENOMEM; goto cleanup; } } else { k5_setmsg(context, rv, "GetTokenInformation() returned truncated buffer"); goto cleanup; } if (!GetTokenInformation(hToken, TokenOwner, pOwner, len, &len)) { k5_setmsg(context, rv, "GetTokenInformation() failed. GLE=%d", GetLastError()); goto cleanup; } if (!ConvertSidToStringSid(pOwner->Owner, &strSid)) { k5_setmsg(context, rv, "Can't convert SID to string. GLE=%d", GetLastError()); goto cleanup; } *ret = strdup(strSid); if (*ret == NULL) { rv = ENOMEM; goto cleanup; } rv = 0; cleanup: if (hToken != NULL) CloseHandle(hToken); if (pOwner != NULL) free(pOwner); if (strSid != NULL) LocalFree(strSid); return rv; } /* * Expand a folder identified by a CSIDL */ static krb5_error_code expand_csidl(krb5_context context, PTYPE folder, const char *postfix, char **ret) { TCHAR path[MAX_PATH]; size_t len; if (SHGetFolderPath(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path) != S_OK) { k5_setmsg(context, EINVAL, "Unable to determine folder path"); return EINVAL; } len = strlen(path); if (len > 0 && path[len - 1] == '\\') path[len - 1] = '\0'; if (postfix && strlcat(path, postfix, sizeof(path) / sizeof(path[0])) >= sizeof(path)/sizeof(path[0])) return ENOMEM; *ret = strdup(path); if (*ret == NULL) return ENOMEM; return 0; } #else /* not _WIN32 */ #include static krb5_error_code expand_path(krb5_context context, PTYPE param, const char *postfix, char **ret) { *ret = strdup(postfix); if (*ret == NULL) return ENOMEM; return 0; } static krb5_error_code expand_temp_folder(krb5_context context, PTYPE param, const char *postfix, char **ret) { const char *p = NULL; if (context == NULL || !context->profile_secure) p = secure_getenv("TMPDIR"); *ret = strdup((p != NULL) ? p : "/tmp"); if (*ret == NULL) return ENOMEM; return 0; } static krb5_error_code expand_userid(krb5_context context, PTYPE param, const char *postfix, char **str) { if (asprintf(str, "%lu", (unsigned long)getuid()) < 0) return ENOMEM; return 0; } static krb5_error_code expand_euid(krb5_context context, PTYPE param, const char *postfix, char **str) { if (asprintf(str, "%lu", (unsigned long)geteuid()) < 0) return ENOMEM; return 0; } static krb5_error_code expand_username(krb5_context context, PTYPE param, const char *postfix, char **str) { uid_t euid = geteuid(); struct passwd *pw, pwx; char pwbuf[BUFSIZ]; if (k5_getpwuid_r(euid, &pwx, pwbuf, sizeof(pwbuf), &pw) != 0) { k5_setmsg(context, ENOENT, _("Can't find username for uid %lu"), (unsigned long)euid); return ENOENT; } *str = strdup(pw->pw_name); if (*str == NULL) return ENOMEM; return 0; } #endif /* not _WIN32 */ /* * Expand an extra token */ static krb5_error_code expand_extra_token(krb5_context context, const char *value, char **ret) { *ret = strdup(value); if (*ret == NULL) return ENOMEM; return 0; } /* * Expand a %{null} token * * The expansion of a %{null} token is always the empty string. */ static krb5_error_code expand_null(krb5_context context, PTYPE param, const char *postfix, char **ret) { *ret = strdup(""); if (*ret == NULL) return ENOMEM; return 0; } static const struct { const char *tok; PTYPE param; const char *postfix; int (*exp_func)(krb5_context, PTYPE, const char *, char **); } tokens[] = { #ifdef _WIN32 /* Roaming application data (for current user) */ {"APPDATA", CSIDL_APPDATA, NULL, expand_csidl}, /* Application data (all users) */ {"COMMON_APPDATA", CSIDL_COMMON_APPDATA, NULL, expand_csidl}, /* Local application data (for current user) */ {"LOCAL_APPDATA", CSIDL_LOCAL_APPDATA, NULL, expand_csidl}, /* Windows System folder (e.g. %WINDIR%\System32) */ {"SYSTEM", CSIDL_SYSTEM, NULL, expand_csidl}, /* Windows folder */ {"WINDOWS", CSIDL_WINDOWS, NULL, expand_csidl}, /* Per user MIT krb5 configuration file directory */ {"USERCONFIG", CSIDL_APPDATA, "\\MIT\\Kerberos5", expand_csidl}, /* Common MIT krb5 configuration file directory */ {"COMMONCONFIG", CSIDL_COMMON_APPDATA, "\\MIT\\Kerberos5", expand_csidl}, {"LIBDIR", 0, NULL, expand_bin_dir}, {"BINDIR", 0, NULL, expand_bin_dir}, {"SBINDIR", 0, NULL, expand_bin_dir}, {"euid", 0, NULL, expand_userid}, #else {"LIBDIR", 0, LIBDIR, expand_path}, {"BINDIR", 0, BINDIR, expand_path}, {"SBINDIR", 0, SBINDIR, expand_path}, {"euid", 0, NULL, expand_euid}, {"username", 0, NULL, expand_username}, #endif {"TEMP", 0, NULL, expand_temp_folder}, {"USERID", 0, NULL, expand_userid}, {"uid", 0, NULL, expand_userid}, {"null", 0, NULL, expand_null} }; static krb5_error_code expand_token(krb5_context context, const char *token, const char *token_end, char **extra_tokens, char **ret) { size_t i; char **p; *ret = NULL; if (token[0] != '%' || token[1] != '{' || token_end[0] != '}' || token_end - token <= 2) { k5_setmsg(context, EINVAL, _("Invalid token")); return EINVAL; } for (p = extra_tokens; p != NULL && *p != NULL; p += 2) { if (strncmp(token + 2, *p, (token_end - token) - 2) == 0) return expand_extra_token(context, p[1], ret); } for (i = 0; i < sizeof(tokens) / sizeof(tokens[0]); i++) { if (!strncmp(token + 2, tokens[i].tok, (token_end - token) - 2)) { return tokens[i].exp_func(context, tokens[i].param, tokens[i].postfix, ret); } } k5_setmsg(context, EINVAL, _("Invalid token")); return EINVAL; } /* * Expand tokens in path_in to produce *path_out. The caller should free * *path_out with free(). */ krb5_error_code k5_expand_path_tokens(krb5_context context, const char *path_in, char **path_out) { return k5_expand_path_tokens_extra(context, path_in, path_out, NULL); } static void free_extra_tokens(char **extra_tokens) { char **p; for (p = extra_tokens; p != NULL && *p != NULL; p++) free(*p); free(extra_tokens); } /* * Expand tokens in path_in to produce *path_out. Arguments after path_out are * pairs of extra token names and replacement values, terminated by a NULL. * The caller should free *path_out with free(). */ krb5_error_code k5_expand_path_tokens_extra(krb5_context context, const char *path_in, char **path_out, ...) { krb5_error_code ret; struct k5buf buf; char *tok_begin, *tok_end, *tok_val, **extra_tokens = NULL, *path; const char *path_left; size_t nargs = 0, i; va_list ap; *path_out = NULL; k5_buf_init_dynamic(&buf); /* Count extra tokens. */ va_start(ap, path_out); while (va_arg(ap, const char *) != NULL) nargs++; va_end(ap); if (nargs % 2 != 0) return EINVAL; /* Get extra tokens. */ if (nargs > 0) { extra_tokens = k5calloc(nargs + 1, sizeof(char *), &ret); if (extra_tokens == NULL) goto cleanup; va_start(ap, path_out); for (i = 0; i < nargs; i++) { extra_tokens[i] = strdup(va_arg(ap, const char *)); if (extra_tokens[i] == NULL) { ret = ENOMEM; va_end(ap); goto cleanup; } } va_end(ap); } path_left = path_in; while (TRUE) { /* Find the next token in path_left and add the literal text up to it. * If there are no more tokens, we can finish up. */ tok_begin = strstr(path_left, "%{"); if (tok_begin == NULL) { k5_buf_add(&buf, path_left); break; } k5_buf_add_len(&buf, path_left, tok_begin - path_left); /* Find the end of this token. */ tok_end = strchr(tok_begin, '}'); if (tok_end == NULL) { ret = EINVAL; k5_setmsg(context, ret, _("variable missing }")); goto cleanup; } /* Expand this token and add its value. */ ret = expand_token(context, tok_begin, tok_end, extra_tokens, &tok_val); if (ret) goto cleanup; k5_buf_add(&buf, tok_val); free(tok_val); path_left = tok_end + 1; } path = k5_buf_cstring(&buf); if (path == NULL) { ret = ENOMEM; goto cleanup; } #ifdef _WIN32 /* Also deal with slashes. */ { char *p; for (p = path; *p != '\0'; p++) { if (*p == '/') *p = '\\'; } } #endif *path_out = path; memset(&buf, 0, sizeof(buf)); ret = 0; cleanup: k5_buf_free(&buf); free_extra_tokens(extra_tokens); return ret; } krb5-1.22.1/src/lib/krb5/os/thread_safe.c0000664000175000017500000000266515051422640017604 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/thread_safe.c */ /* * Copyright 2005 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" krb5_boolean KRB5_CALLCONV krb5_is_thread_safe(void) { #if defined(ENABLE_THREADS) return 1; #else return 0; #endif } krb5-1.22.1/src/lib/krb5/os/dnsglue.c0000664000175000017500000003135215051422640016773 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/dnsglue.c */ /* * Copyright 2004, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "os-proto.h" #ifdef KRB5_DNS_LOOKUP #ifndef _WIN32 #include "dnsglue.h" #ifdef __APPLE__ #include #endif /* * Only use res_ninit() if there's also a res_ndestroy(), to avoid * memory leaks (Linux & Solaris) and outright corruption (AIX 4.x, * 5.x). While we're at it, make sure res_nsearch() is there too. * * In any case, it is probable that platforms having broken * res_ninit() will have thread safety hacks for res_init() and _res. */ /* * Opaque handle */ struct krb5int_dns_state { int nclass; int ntype; void *ansp; int anslen; int ansmax; #if HAVE_NS_INITPARSE int cur_ans; ns_msg msg; #else unsigned char *ptr; unsigned short nanswers; #endif }; #if !HAVE_NS_INITPARSE static int initparse(struct krb5int_dns_state *); #endif /* * Define macros to use the best available DNS search functions. INIT_HANDLE() * returns true if handle initialization is successful, false if it is not. * SEARCH() returns the length of the response or -1 on error. * PRIMARY_DOMAIN() returns the first search domain in allocated memory. * DECLARE_HANDLE() must be used last in the declaration list since it may * evaluate to nothing. */ #if defined(__APPLE__) /* Use the macOS interfaces dns_open, dns_search, and dns_free. */ #define DECLARE_HANDLE(h) dns_handle_t h #define INIT_HANDLE(h) ((h = dns_open(NULL)) != NULL) #define SEARCH(h, n, c, t, a, l) dns_search(h, n, c, t, a, l, NULL, NULL) #define PRIMARY_DOMAIN(h) dns_search_list_domain(h, 0) #define DESTROY_HANDLE(h) dns_free(h) #elif HAVE_RES_NINIT && HAVE_RES_NSEARCH /* Use res_ninit, res_nsearch, and res_ndestroy or res_nclose. */ #define DECLARE_HANDLE(h) struct __res_state h #define INIT_HANDLE(h) (memset(&h, 0, sizeof(h)), res_ninit(&h) == 0) #define SEARCH(h, n, c, t, a, l) res_nsearch(&h, n, c, t, a, l) #define PRIMARY_DOMAIN(h) ((h.dnsrch[0] == NULL) ? NULL : strdup(h.dnsrch[0])) #if HAVE_RES_NDESTROY #define DESTROY_HANDLE(h) res_ndestroy(&h) #else #define DESTROY_HANDLE(h) res_nclose(&h) #endif #else /* Use res_init and res_search. */ #define DECLARE_HANDLE(h) #define INIT_HANDLE(h) (res_init() == 0) #define SEARCH(h, n, c, t, a, l) res_search(n, c, t, a, l) #define PRIMARY_DOMAIN(h) \ ((_res.defdname == NULL) ? NULL : strdup(_res.defdname)) #define DESTROY_HANDLE(h) #endif /* * krb5int_dns_init() * * Initialize an opaque handle. Do name lookup and initial parsing of * reply, skipping question section. Prepare to iterate over answer * section. Returns -1 on error, 0 on success. */ int krb5int_dns_init(struct krb5int_dns_state **dsp, char *host, int nclass, int ntype) { struct krb5int_dns_state *ds; int len, ret; size_t nextincr, maxincr; unsigned char *p; DECLARE_HANDLE(h); *dsp = ds = malloc(sizeof(*ds)); if (ds == NULL) return -1; ret = -1; ds->nclass = nclass; ds->ntype = ntype; ds->ansp = NULL; ds->anslen = 0; ds->ansmax = 0; nextincr = 4096; maxincr = INT_MAX; #if HAVE_NS_INITPARSE ds->cur_ans = 0; #endif if (!INIT_HANDLE(h)) return -1; do { p = (ds->ansp == NULL) ? malloc(nextincr) : realloc(ds->ansp, nextincr); if (p == NULL) { ret = -1; goto errout; } ds->ansp = p; ds->ansmax = nextincr; len = SEARCH(h, host, ds->nclass, ds->ntype, ds->ansp, ds->ansmax); if ((size_t) len > maxincr) { ret = -1; goto errout; } while (nextincr < (size_t) len) nextincr *= 2; if (len < 0 || nextincr > maxincr) { ret = -1; goto errout; } } while (len > ds->ansmax); ds->anslen = len; #if HAVE_NS_INITPARSE ret = ns_initparse(ds->ansp, ds->anslen, &ds->msg); #else ret = initparse(ds); #endif if (ret < 0) goto errout; ret = 0; errout: DESTROY_HANDLE(h); if (ret < 0) { if (ds->ansp != NULL) { free(ds->ansp); ds->ansp = NULL; } } return ret; } #if HAVE_NS_INITPARSE /* * krb5int_dns_nextans - get next matching answer record * * Sets pp to NULL if no more records. Returns -1 on error, 0 on * success. */ int krb5int_dns_nextans(struct krb5int_dns_state *ds, const unsigned char **pp, int *lenp) { int len; ns_rr rr; *pp = NULL; *lenp = 0; while (ds->cur_ans < ns_msg_count(ds->msg, ns_s_an)) { len = ns_parserr(&ds->msg, ns_s_an, ds->cur_ans, &rr); if (len < 0) return -1; ds->cur_ans++; if (ds->nclass == (int)ns_rr_class(rr) && ds->ntype == (int)ns_rr_type(rr)) { *pp = ns_rr_rdata(rr); *lenp = ns_rr_rdlen(rr); return 0; } } return 0; } #endif /* * krb5int_dns_expand - wrapper for dn_expand() */ int krb5int_dns_expand(struct krb5int_dns_state *ds, const unsigned char *p, char *buf, int len) { #if HAVE_NS_NAME_UNCOMPRESS return ns_name_uncompress(ds->ansp, (unsigned char *)ds->ansp + ds->anslen, p, buf, (size_t)len); #else return dn_expand(ds->ansp, (unsigned char *)ds->ansp + ds->anslen, p, buf, len); #endif } /* * Free stuff. */ void krb5int_dns_fini(struct krb5int_dns_state *ds) { if (ds == NULL) return; if (ds->ansp != NULL) free(ds->ansp); free(ds); } /* * Compat routines for BIND 4 */ #if !HAVE_NS_INITPARSE /* * initparse * * Skip header and question section of reply. Set a pointer to the * beginning of the answer section, and prepare to iterate over * answer records. */ static int initparse(struct krb5int_dns_state *ds) { HEADER *hdr; unsigned char *p; unsigned short nqueries, nanswers; int len; #if !HAVE_DN_SKIPNAME char host[MAXDNAME]; #endif if ((size_t) ds->anslen < sizeof(HEADER)) return -1; hdr = (HEADER *)ds->ansp; p = ds->ansp; nqueries = ntohs((unsigned short)hdr->qdcount); nanswers = ntohs((unsigned short)hdr->ancount); p += sizeof(HEADER); /* * Skip query records. */ while (nqueries--) { #if HAVE_DN_SKIPNAME len = dn_skipname(p, (unsigned char *)ds->ansp + ds->anslen); #else len = dn_expand(ds->ansp, (unsigned char *)ds->ansp + ds->anslen, p, host, sizeof(host)); #endif if (len < 0 || !INCR_OK(ds->ansp, ds->anslen, p, len + 4)) return -1; p += len + 4; } ds->ptr = p; ds->nanswers = nanswers; return 0; } /* * krb5int_dns_nextans() - get next answer record * * Sets pp to NULL if no more records. */ int krb5int_dns_nextans(struct krb5int_dns_state *ds, const unsigned char **pp, int *lenp) { int len; unsigned char *p; unsigned short ntype, nclass, rdlen; #if !HAVE_DN_SKIPNAME char host[MAXDNAME]; #endif *pp = NULL; *lenp = 0; p = ds->ptr; while (ds->nanswers--) { #if HAVE_DN_SKIPNAME len = dn_skipname(p, (unsigned char *)ds->ansp + ds->anslen); #else len = dn_expand(ds->ansp, (unsigned char *)ds->ansp + ds->anslen, p, host, sizeof(host)); #endif if (len < 0 || !INCR_OK(ds->ansp, ds->anslen, p, len)) return -1; p += len; SAFE_GETUINT16(ds->ansp, ds->anslen, p, 2, ntype, out); /* Also skip 4 bytes of TTL */ SAFE_GETUINT16(ds->ansp, ds->anslen, p, 6, nclass, out); SAFE_GETUINT16(ds->ansp, ds->anslen, p, 2, rdlen, out); if (!INCR_OK(ds->ansp, ds->anslen, p, rdlen)) return -1; if (rdlen > INT_MAX) return -1; if (nclass == ds->nclass && ntype == ds->ntype) { *pp = p; *lenp = rdlen; ds->ptr = p + rdlen; return 0; } p += rdlen; } return 0; out: return -1; } #endif /* !HAVE_NS_INITPARSE */ #endif /* not _WIN32 */ /* Construct a DNS label of the form "prefix[.name.]". name may be NULL. */ static char * txt_lookup_name(const char *prefix, const char *name) { struct k5buf buf; k5_buf_init_dynamic(&buf); if (name == NULL || name[0] == '\0') { k5_buf_add(&buf, prefix); } else { k5_buf_add_fmt(&buf, "%s.%s", prefix, name); /* * Realm names don't (normally) end with ".", but if the query doesn't * end with "." and doesn't get an answer as is, the resolv code will * try appending the local domain. Since the realm names are * absolutes, let's stop that. * * But only if a name has been specified. If we are performing a * search on the prefix alone then the intention is to allow the local * domain or domain search lists to be expanded. */ if (buf.len > 0 && ((char *)buf.data)[buf.len - 1] != '.') k5_buf_add(&buf, "."); } return k5_buf_cstring(&buf); } /* * Try to look up a TXT record pointing to a Kerberos realm */ #ifdef _WIN32 #include krb5_error_code k5_try_realm_txt_rr(krb5_context context, const char *prefix, const char *name, char **realm) { krb5_error_code ret = 0; char *txtname = NULL; PDNS_RECORD rr = NULL; DNS_STATUS st; *realm = NULL; txtname = txt_lookup_name(prefix, name); if (txtname == NULL) return ENOMEM; st = DnsQuery_UTF8(txtname, DNS_TYPE_TEXT, DNS_QUERY_STANDARD, NULL, &rr, NULL); if (st != ERROR_SUCCESS || rr == NULL) { TRACE_TXT_LOOKUP_NOTFOUND(context, txtname); ret = KRB5_ERR_HOST_REALM_UNKNOWN; goto cleanup; } *realm = strdup(rr->Data.TXT.pStringArray[0]); if (*realm == NULL) ret = ENOMEM; TRACE_TXT_LOOKUP_SUCCESS(context, txtname, *realm); cleanup: free(txtname); if (rr != NULL) DnsRecordListFree(rr, DnsFreeRecordList); return ret; } char * k5_primary_domain(void) { return NULL; } #else /* _WIN32 */ krb5_error_code k5_try_realm_txt_rr(krb5_context context, const char *prefix, const char *name, char **realm) { krb5_error_code retval = KRB5_ERR_HOST_REALM_UNKNOWN; const unsigned char *p, *base; char *txtname = NULL; int ret, rdlen, len; struct krb5int_dns_state *ds = NULL; /* * Form our query, and send it via DNS */ txtname = txt_lookup_name(prefix, name); if (txtname == NULL) return ENOMEM; ret = krb5int_dns_init(&ds, txtname, C_IN, T_TXT); if (ret < 0) { TRACE_TXT_LOOKUP_NOTFOUND(context, txtname); goto errout; } ret = krb5int_dns_nextans(ds, &base, &rdlen); if (ret < 0 || base == NULL) goto errout; p = base; if (!INCR_OK(base, rdlen, p, 1)) goto errout; len = *p++; *realm = malloc((size_t)len + 1); if (*realm == NULL) { retval = ENOMEM; goto errout; } strncpy(*realm, (const char *)p, (size_t)len); (*realm)[len] = '\0'; /* Avoid a common error. */ if ( (*realm)[len-1] == '.' ) (*realm)[len-1] = '\0'; retval = 0; TRACE_TXT_LOOKUP_SUCCESS(context, txtname, *realm); errout: krb5int_dns_fini(ds); free(txtname); return retval; } char * k5_primary_domain(void) { char *domain; DECLARE_HANDLE(h); if (!INIT_HANDLE(h)) return NULL; domain = PRIMARY_DOMAIN(h); DESTROY_HANDLE(h); return domain; } #endif /* not _WIN32 */ #endif /* KRB5_DNS_LOOKUP */ krb5-1.22.1/src/lib/krb5/os/hostrealm_profile.c0000664000175000017500000001026415051422640021047 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/hostream_profile.c - profile hostrealm module */ /* * Copyright (C) 1990,1991,2002,2008,2009,2013 by the Massachusetts Institute * of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file implements the built-in profile module for the hostrealm * interface, which uses profile configuration to determine the local default * realm or the authoritative realm of a host. */ #include "k5-int.h" #include "os-proto.h" #include /* * Search progressively shorter suffixes of host in the [domain_realms] section * of the profile to find the realm. For example, given a host a.b.c, try to * match a.b.c, then .b.c, then b.c, then .c, then c. If we don't find a * match, return success but set *realm_out to NULL. */ static krb5_error_code profile_host_realm(krb5_context context, krb5_hostrealm_moddata data, const char *host, char ***realms_out) { krb5_error_code ret; const char *p; char *prof_realm; *realms_out = NULL; /* Don't look up IP addresses in [domain_realms]. */ if (k5_is_numeric_address(host)) return KRB5_PLUGIN_NO_HANDLE; /* Look for the host and each suffix in the [domain_realms] section. */ for (p = host; p != NULL; p = (*p == '.') ? p + 1 : strchr(p, '.')) { ret = profile_get_string(context->profile, KRB5_CONF_DOMAIN_REALM, p, NULL, NULL, &prof_realm); if (ret) return ret; if (prof_realm != NULL) { ret = k5_make_realmlist(prof_realm, realms_out); profile_release_string(prof_realm); return ret; } } return KRB5_PLUGIN_NO_HANDLE; } /* Look up the default_realm variable in the [libdefaults] section of the * profile. */ static krb5_error_code profile_default_realm(krb5_context context, krb5_hostrealm_moddata data, char ***realms_out) { krb5_error_code ret; char *prof_realm; *realms_out = NULL; ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_DEFAULT_REALM, NULL, NULL, &prof_realm); if (ret) return ret; if (prof_realm == NULL) return KRB5_PLUGIN_NO_HANDLE; ret = k5_make_realmlist(prof_realm, realms_out); profile_release_string(prof_realm); return ret; } static void profile_free_realmlist(krb5_context context, krb5_hostrealm_moddata data, char **list) { krb5_free_host_realm(context, list); } krb5_error_code hostrealm_profile_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_hostrealm_vtable vt = (krb5_hostrealm_vtable)vtable; vt->name = "profile"; vt->host_realm = profile_host_realm; vt->default_realm = profile_default_realm; vt->free_list = profile_free_realmlist; return 0; } krb5-1.22.1/src/lib/krb5/os/c_ustime.c0000664000175000017500000001073115051422640017140 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/c_ustime.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "k5-thread.h" k5_mutex_t krb5int_us_time_mutex = K5_MUTEX_PARTIAL_INITIALIZER; struct time_now { krb5_timestamp sec; krb5_int32 usec; }; #if defined(_WIN32) /* Microsoft Windows NT and 95 (32bit) */ /* This one works for WOW (Windows on Windows, ntvdm on Win-NT) */ #include #include #include static krb5_error_code get_time_now(struct time_now *n) { struct _timeb timeptr; _ftime(&timeptr); n->sec = timeptr.time; n->usec = timeptr.millitm * 1000; return 0; } #else /* Everybody else is UNIX, right? POSIX 1996 doesn't give us gettimeofday, but what real OS doesn't? */ static krb5_error_code get_time_now(struct time_now *n) { struct timeval tv; if (gettimeofday(&tv, (struct timezone *)0) == -1) return errno; n->sec = tv.tv_sec; n->usec = tv.tv_usec; return 0; } #endif krb5_error_code k5_us_timeofday(krb5_timestamp *seconds, krb5_int32 *microseconds) { struct time_now now; krb5_error_code err; err = get_time_now(&now); if (err) return err; *seconds = now.sec; *microseconds = now.usec; return 0; } static struct time_now last_time; krb5_error_code krb5_crypto_us_timeofday(krb5_timestamp *seconds, krb5_int32 *microseconds) { struct time_now now; krb5_error_code err; now.sec = now.usec = 0; err = get_time_now(&now); if (err) return err; /* It would probably be more efficient to remove this mutex and use thread-local storage for last_time. But that could result in different threads getting the same value for time, which may be a technical violation of spec. */ k5_mutex_lock(&krb5int_us_time_mutex); /* Just guessing: If the number of seconds hasn't changed, yet the microseconds are moving backwards, we probably just got a third instance of returning the same clock value from the system, so the saved value was artificially incremented. On Windows, where we get millisecond accuracy currently, that's quite likely. On UNIX, it appears that we always get new microsecond values, so this case should never trigger. */ /* Check for case where previously usec rollover caused bump in sec, putting now.sec in the past. But don't just use '<' because we need to properly handle the case where the administrator intentionally adjusted time backwards. */ if (now.sec == ts_incr(last_time.sec, -1) || (now.sec == last_time.sec && now.usec <= last_time.usec)) { /* Correct 'now' to be exactly one microsecond later than 'last_time'. Note that _because_ we perform this hack, 'now' may be _earlier_ than 'last_time', even though the system time is monotonically increasing. */ now.sec = last_time.sec; now.usec = last_time.usec + 1; if (now.usec >= 1000000) { now.sec = ts_incr(now.sec, 1); now.usec = 0; } } last_time.sec = now.sec; /* Remember for next time */ last_time.usec = now.usec; k5_mutex_unlock(&krb5int_us_time_mutex); *seconds = now.sec; *microseconds = now.usec; return 0; } krb5-1.22.1/src/lib/krb5/os/read_msg.c0000664000175000017500000000433215051422640017111 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/read_msg.c */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include krb5_error_code krb5_read_message(krb5_context context, krb5_pointer fdp, krb5_data *inbuf) { krb5_int32 len; int len2, ilen; char *buf = NULL; int fd = *( (int *) fdp); *inbuf = empty_data(); if ((len2 = krb5_net_read(context, fd, (char *)&len, 4)) != 4) return((len2 < 0) ? errno : ECONNABORTED); len = ntohl(len); if ((len & VALID_UINT_BITS) != (krb5_ui_4) len) /* Overflow size_t??? */ return ENOMEM; ilen = (int)len; if (ilen) { /* * We may want to include a sanity check here someday.... */ if (!(buf = malloc(ilen))) { return(ENOMEM); } if ((len2 = krb5_net_read(context, fd, buf, ilen)) != ilen) { free(buf); return((len2 < 0) ? errno : ECONNABORTED); } } *inbuf = make_data(buf, ilen); return(0); } krb5-1.22.1/src/lib/krb5/os/changepw.c0000664000175000017500000003234315051422640017127 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/changepw.c */ /* * Copyright 1990,1999,2001,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * krb5_set_password - Implements set password per RFC 3244 * Added by Paul W. Nelson, Thursby Software Systems, Inc. * Modified by Todd Stecher, Isilon Systems, to use krb1.4 socket * infrastructure */ #include "k5-int.h" #include "fake-addrinfo.h" #include "os-proto.h" #include "../krb/auth_con.h" #include "../krb/int-proto.h" #include #include #ifndef GETSOCKNAME_ARG3_TYPE #define GETSOCKNAME_ARG3_TYPE int #endif struct sendto_callback_context { krb5_context context; krb5_auth_context auth_context; krb5_principal set_password_for; const char *newpw; krb5_data ap_req; krb5_ui_4 remote_seq_num, local_seq_num; }; /* * Wrapper function for the two backends */ static krb5_error_code locate_kpasswd(krb5_context context, const krb5_data *realm, struct serverlist *serverlist) { krb5_error_code code; code = k5_locate_server(context, realm, serverlist, locate_service_kpasswd, FALSE); if (code == KRB5_REALM_CANT_RESOLVE || code == KRB5_REALM_UNKNOWN) { code = k5_locate_server(context, realm, serverlist, locate_service_kadmin, TRUE); if (!code) { /* Success with admin_server but now we need to change the port * number to use DEFAULT_KPASSWD_PORT and the transport. */ size_t i; for (i = 0; i < serverlist->nservers; i++) { struct server_entry *s = &serverlist->servers[i]; if (s->transport == TCP) s->transport = TCP_OR_UDP; if (s->hostname != NULL) s->port = DEFAULT_KPASSWD_PORT; else if (s->family == AF_INET) ss2sin(&s->addr)->sin_port = htons(DEFAULT_KPASSWD_PORT); else if (s->family == AF_INET6) ss2sin6(&s->addr)->sin6_port = htons(DEFAULT_KPASSWD_PORT); } } } return (code); } /** * This routine is used for a callback in sendto_kdc.c code. Simply * put, we need the client addr to build the krb_priv portion of the * password request. */ static void kpasswd_sendto_msg_cleanup(void *data, krb5_data *message) { struct sendto_callback_context *ctx = data; krb5_free_data_contents(ctx->context, message); } static int kpasswd_sendto_msg_callback(SOCKET fd, void *data, krb5_data *message) { krb5_error_code code = 0; struct sockaddr_storage local_addr; krb5_address local_kaddr; struct sendto_callback_context *ctx = data; GETSOCKNAME_ARG3_TYPE addrlen; krb5_data output; krb5_address **addrs = NULL; memset (message, 0, sizeof(krb5_data)); /* * We need the local addr from the connection socket */ addrlen = sizeof(local_addr); if (getsockname(fd, ss2sa(&local_addr), &addrlen) < 0) { code = SOCKET_ERRNO; goto cleanup; } /* some brain-dead OS's don't return useful information from * the getsockname call. Namely, windows and solaris. */ if (local_addr.ss_family == AF_INET && ss2sin(&local_addr)->sin_addr.s_addr != 0) { local_kaddr.addrtype = ADDRTYPE_INET; local_kaddr.length = sizeof(ss2sin(&local_addr)->sin_addr); local_kaddr.contents = (krb5_octet *) &ss2sin(&local_addr)->sin_addr; } else if (local_addr.ss_family == AF_INET6 && memcmp(ss2sin6(&local_addr)->sin6_addr.s6_addr, in6addr_any.s6_addr, sizeof(in6addr_any.s6_addr)) != 0) { local_kaddr.addrtype = ADDRTYPE_INET6; local_kaddr.length = sizeof(ss2sin6(&local_addr)->sin6_addr); local_kaddr.contents = (krb5_octet *) &ss2sin6(&local_addr)->sin6_addr; #ifndef _WIN32 } else if (local_addr.ss_family == AF_UNIX) { /* There is no standard way to represent UNIX domain sockets. Assume * that the receiver will accept a directional address. */ local_kaddr = k5_addr_directional_init; #endif } else { code = krb5_os_localaddr(ctx->context, &addrs); if (code) goto cleanup; local_kaddr = *addrs[0]; } /* * TBD: Does this tamper w/ the auth context in such a way * to break us? Yes - provide 1 per conn-state / host... */ if ((code = krb5_auth_con_setaddrs(ctx->context, ctx->auth_context, &local_kaddr, NULL))) goto cleanup; ctx->auth_context->remote_seq_number = ctx->remote_seq_num; ctx->auth_context->local_seq_number = ctx->local_seq_num; if (ctx->set_password_for) code = krb5int_mk_setpw_req(ctx->context, ctx->auth_context, &ctx->ap_req, ctx->set_password_for, ctx->newpw, &output); else code = krb5int_mk_chpw_req(ctx->context, ctx->auth_context, &ctx->ap_req, ctx->newpw, &output); if (code) goto cleanup; message->length = output.length; message->data = output.data; cleanup: krb5_free_addresses(ctx->context, addrs); return code; } /* ** The logic for setting and changing a password is mostly the same ** change_set_password handles both cases ** if set_password_for is NULL, then a password change is performed, ** otherwise, the password is set for the principal indicated in set_password_for */ static krb5_error_code change_set_password(krb5_context context, krb5_creds *creds, const char *newpw, krb5_principal set_password_for, int *result_code, krb5_data *result_code_string, krb5_data *result_string) { krb5_data chpw_rep; GETSOCKNAME_ARG3_TYPE addrlen; krb5_error_code code = 0; char *code_string; int local_result_code; struct sendto_callback_context callback_ctx; struct sendto_callback_info callback_info; struct sockaddr_storage remote_addr; struct serverlist sl = SERVERLIST_INIT; memset(&chpw_rep, 0, sizeof(krb5_data)); memset( &callback_ctx, 0, sizeof(struct sendto_callback_context)); callback_ctx.context = context; callback_ctx.newpw = newpw; callback_ctx.set_password_for = set_password_for; if ((code = krb5_auth_con_init(callback_ctx.context, &callback_ctx.auth_context))) goto cleanup; if ((code = krb5_mk_req_extended(callback_ctx.context, &callback_ctx.auth_context, AP_OPTS_USE_SUBKEY, NULL, creds, &callback_ctx.ap_req))) goto cleanup; callback_ctx.remote_seq_num = callback_ctx.auth_context->remote_seq_number; callback_ctx.local_seq_num = callback_ctx.auth_context->local_seq_number; code = locate_kpasswd(callback_ctx.context, &creds->server->realm, &sl); if (code) goto cleanup; addrlen = sizeof(remote_addr); callback_info.data = &callback_ctx; callback_info.pfn_callback = kpasswd_sendto_msg_callback; callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup; krb5_free_data_contents(callback_ctx.context, &chpw_rep); /* UDP retransmits may be seen as replays. Only try UDP after other * transports fail completely. */ code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm, &sl, NO_UDP, &callback_info, &chpw_rep, ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); if (code == KRB5_KDC_UNREACH) { code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm, &sl, ONLY_UDP, &callback_info, &chpw_rep, ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); } if (code) goto cleanup; code = krb5int_rd_chpw_rep(callback_ctx.context, callback_ctx.auth_context, &chpw_rep, &local_result_code, result_string); if (code) goto cleanup; if (result_code) *result_code = local_result_code; if (result_code_string) { code = krb5_chpw_result_code_string(callback_ctx.context, local_result_code, &code_string); if (code) goto cleanup; result_code_string->length = strlen(code_string); result_code_string->data = malloc(result_code_string->length); if (result_code_string->data == NULL) { code = ENOMEM; goto cleanup; } strncpy(result_code_string->data, code_string, result_code_string->length); } cleanup: if (callback_ctx.auth_context != NULL) krb5_auth_con_free(callback_ctx.context, callback_ctx.auth_context); k5_free_serverlist(&sl); krb5_free_data_contents(callback_ctx.context, &callback_ctx.ap_req); krb5_free_data_contents(callback_ctx.context, &chpw_rep); return(code); } krb5_error_code KRB5_CALLCONV krb5_change_password(krb5_context context, krb5_creds *creds, const char *newpw, int *result_code, krb5_data *result_code_string, krb5_data *result_string) { return change_set_password(context, creds, newpw, NULL, result_code, result_code_string, result_string ); } /* * krb5_set_password - Implements set password per RFC 3244 * */ krb5_error_code KRB5_CALLCONV krb5_set_password(krb5_context context, krb5_creds *creds, const char *newpw, krb5_principal change_password_for, int *result_code, krb5_data *result_code_string, krb5_data *result_string ) { return change_set_password(context, creds, newpw, change_password_for, result_code, result_code_string, result_string ); } krb5_error_code KRB5_CALLCONV krb5_set_password_using_ccache(krb5_context context, krb5_ccache ccache, const char *newpw, krb5_principal change_password_for, int *result_code, krb5_data *result_code_string, krb5_data *result_string ) { krb5_creds creds; krb5_creds *credsp; krb5_error_code code; /* ** get the proper creds for use with krb5_set_password - */ memset (&creds, 0, sizeof(creds)); /* ** first get the principal for the password service - */ code = krb5_cc_get_principal (context, ccache, &creds.client); if (!code) { code = krb5_build_principal(context, &creds.server, change_password_for->realm.length, change_password_for->realm.data, "kadmin", "changepw", NULL); if (!code) { code = krb5_get_credentials(context, 0, ccache, &creds, &credsp); if (!code) { code = krb5_set_password(context, credsp, newpw, change_password_for, result_code, result_code_string, result_string); krb5_free_creds(context, credsp); } } krb5_free_cred_contents(context, &creds); } return code; } krb5-1.22.1/src/lib/krb5/os/t_trace.ref0000664000175000017500000000473615051422640017313 0ustar ghudsonghudsonsimple format int, in decimal: -1 long, in decimal: -2 const char *, display as C string: example.data size_t and const char *, as a counted string: example.data size_t and const char *, as a counted string: (null) size_t and const char *, as hex bytes: 6578616D706C652E64617461 size_t and const char *, as hex bytes: (null) size_t and const char *, as four-character hex hash: 7B9A size_t and const char *, as four-character hex hash: (null) struct remote_address *, show socket type, address, port: stream 0.0.0.0:88 struct remote_address *, show socket type, address, port: dgram 0.0.0.0:88 struct remote_address *, show socket type, address, port: transport1234 struct remote_address *, show socket type, address, port: transport1234 krb5_data *, display as counted string: example.data krb5_data *, display as counted string: (null) krb5_data *, display as hex bytes: 6578616D706C652E64617461 krb5_data *, display as hex bytes: (null) int, display as number/errorstring: 2/No such file or directory krb5_error_code, display as number/errorstring: 0/Success const krb5_keyblock *, display enctype and hash of key: 511/7B9A const krb5_keyblock *, display enctype and hash of key: (null) krb5_key, display enctype and hash of key: 511/7B9A krb5_key, display enctype and hash of key: (null) const krb5_checksum *, display cksumtype and hex checksum: -1/6578616D706C652E64617461 krb5_principal, unparse and display: @ATHENA.MIT.EDU int, krb5_principal type: unknown int, krb5_principal type: principal int, krb5_principal type: service instance int, krb5_principal type: service with host as instance int, krb5_principal type: service with host as components int, krb5_principal type: unique ID int, krb5_principal type: X.509 int, krb5_principal type: SMTP email int, krb5_principal type: Windows 2000 UPN int, krb5_principal type: well-known int, krb5_principal type: Windows 2000 UPN and SID int, krb5_principal type: NT 4 style name int, krb5_principal type: NT 4 style name and SID int, krb5_principal type: ? krb5_pa_data **, display list of padata type numbers: PA-PW-SALT (3), 0 krb5_pa_data **, display list of padata type numbers: (empty) krb5_enctype, display shortest name of enctype: aes128-cts krb5_enctype *, display list of enctypes: 5, rc4-hmac-exp, 511 krb5_enctype *, display list of enctypes: (empty) krb5_ccache, display type:name: FILE:/path/to/ccache krb5_keytab, display name: FILE:/etc/krb5.keytab krb5_creds *, display clientprinc -> serverprinc: @ATHENA.MIT.EDU -> @ZEUS.MIT.EDU krb5-1.22.1/src/lib/krb5/os/read_pwd.c0000664000175000017500000002037715051422640017124 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/read_pwd.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #if !defined(_WIN32) #define DEFINED_KRB5_READ_PASSWORD #include #include #include #include #ifndef ECHO_PASSWORD #include #endif /* ECHO_PASSWORD */ krb5_error_code krb5_read_password(krb5_context context, const char *prompt, const char *prompt2, char *return_pwd, unsigned int *size_return) { krb5_data reply_data, verify_data = empty_data(); krb5_prompt k5prompt, vprompt; krb5_error_code retval; /* *size_return is the space available in the return buffer on input. */ reply_data = make_data(return_pwd, *size_return); k5prompt.prompt = (char *)prompt; k5prompt.hidden = 1; k5prompt.reply = &reply_data; retval = krb5_prompter_posix(NULL, NULL, NULL, NULL, 1, &k5prompt); if (retval || prompt2 == NULL) goto done; retval = alloc_data(&verify_data, *size_return); if (retval) goto done; vprompt.prompt = (char *)prompt2; vprompt.hidden = 1; vprompt.reply = &verify_data; retval = krb5_prompter_posix(NULL, NULL, NULL, NULL, 1, &vprompt); if (retval) goto done; if (strncmp(return_pwd, verify_data.data, *size_return) != 0) retval = KRB5_LIBOS_BADPWDMATCH; done: zapfree(verify_data.data, verify_data.length); if (!retval) *size_return = k5prompt.reply->length; else zap(return_pwd, *size_return); return retval; } #endif #if defined(_WIN32) #define DEFINED_KRB5_READ_PASSWORD #include typedef struct { char *pwd_prompt; char *pwd_prompt2; char *pwd_return_pwd; int *pwd_size_return; } pwd_params; void center_dialog(HWND hwnd) { int scrwidth, scrheight; int dlgwidth, dlgheight; RECT r; HDC hdc; if (hwnd == NULL) return; GetWindowRect(hwnd, &r); dlgwidth = r.right - r.left; dlgheight = r.bottom - r.top ; hdc = GetDC(NULL); scrwidth = GetDeviceCaps(hdc, HORZRES); scrheight = GetDeviceCaps(hdc, VERTRES); ReleaseDC(NULL, hdc); r.left = (scrwidth - dlgwidth) / 2; r.top = (scrheight - dlgheight) / 2; MoveWindow(hwnd, r.left, r.top, dlgwidth, dlgheight, TRUE); } #ifdef _WIN32 static krb5_error_code read_console_password(krb5_context context, const char * prompt, const char * prompt2, char * password, int * pwsize) { HANDLE handle; DWORD old_mode, new_mode; char *tmpstr = 0; char *ptr; int scratchchar; krb5_error_code errcode = 0; handle = GetStdHandle(STD_INPUT_HANDLE); if (handle == INVALID_HANDLE_VALUE) return ENOTTY; if (!GetConsoleMode(handle, &old_mode)) return ENOTTY; new_mode = old_mode; new_mode |= ( ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT ); new_mode &= ~( ENABLE_ECHO_INPUT ); if (!SetConsoleMode(handle, new_mode)) return ENOTTY; (void) fputs(prompt, stdout); (void) fflush(stdout); (void) memset(password, 0, *pwsize); if (fgets(password, *pwsize, stdin) == NULL) { (void) putchar('\n'); errcode = KRB5_LIBOS_CANTREADPWD; goto cleanup; } (void) putchar('\n'); if ((ptr = strchr(password, '\n'))) *ptr = '\0'; else /* need to flush */ do { scratchchar = getchar(); } while (scratchchar != EOF && scratchchar != '\n'); if (prompt2) { if (! (tmpstr = (char *)malloc(*pwsize))) { errcode = ENOMEM; goto cleanup; } (void) fputs(prompt2, stdout); (void) fflush(stdout); if (fgets(tmpstr, *pwsize, stdin) == NULL) { (void) putchar('\n'); errcode = KRB5_LIBOS_CANTREADPWD; goto cleanup; } (void) putchar('\n'); if ((ptr = strchr(tmpstr, '\n'))) *ptr = '\0'; else /* need to flush */ do { scratchchar = getchar(); } while (scratchchar != EOF && scratchchar != '\n'); if (strncmp(password, tmpstr, *pwsize)) { errcode = KRB5_LIBOS_BADPWDMATCH; goto cleanup; } } cleanup: (void) SetConsoleMode(handle, old_mode); if (tmpstr) { (void) memset(tmpstr, 0, *pwsize); (void) free(tmpstr); } if (errcode) (void) memset(password, 0, *pwsize); else *pwsize = strlen(password); return errcode; } #endif static int CALLBACK read_pwd_proc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { pwd_params *dp; switch(msg) { case WM_INITDIALOG: dp = (pwd_params *) lParam; SetWindowLongPtr(hdlg, DWLP_USER, lParam); SetDlgItemText(hdlg, ID_READ_PWD_PROMPT, dp->pwd_prompt); SetDlgItemText(hdlg, ID_READ_PWD_PROMPT2, dp->pwd_prompt2); SetDlgItemText(hdlg, ID_READ_PWD_PWD, ""); center_dialog(hdlg); return TRUE; case WM_COMMAND: dp = (pwd_params *) GetWindowLongPtr(hdlg, DWLP_USER); switch (wParam) { case IDOK: *(dp->pwd_size_return) = GetDlgItemText(hdlg, ID_READ_PWD_PWD, dp->pwd_return_pwd, *(dp->pwd_size_return)); EndDialog(hdlg, TRUE); break; case IDCANCEL: memset(dp->pwd_return_pwd, 0 , *(dp->pwd_size_return)); *(dp->pwd_size_return) = 0; EndDialog(hdlg, FALSE); break; } return TRUE; default: return FALSE; } } krb5_error_code KRB5_CALLCONV krb5_read_password(context, prompt, prompt2, return_pwd, size_return) krb5_context context; const char *prompt; const char *prompt2; char *return_pwd; int *size_return; { DLGPROC dlgproc; HINSTANCE hinst; pwd_params dps; int rc; #ifdef _WIN32 if (_isatty(_fileno(stdin))) return(read_console_password (context, prompt, prompt2, return_pwd, size_return)); #endif dps.pwd_prompt = prompt; dps.pwd_prompt2 = prompt2; dps.pwd_return_pwd = return_pwd; dps.pwd_size_return = size_return; hinst = get_lib_instance(); #ifdef _WIN32 dlgproc = read_pwd_proc; #else dlgproc = (FARPROC) MakeProcInstance(read_pwd_proc, hinst); #endif rc = DialogBoxParam(hinst, MAKEINTRESOURCE(ID_READ_PWD_DIALOG), 0, dlgproc, (LPARAM) &dps); #ifndef _WIN32 FreeProcInstance ((FARPROC) dlgproc); #endif return 0; } #endif #ifndef DEFINED_KRB5_READ_PASSWORD #define DEFINED_KRB5_READ_PASSWORD /* * Don't expect to be called, just define it for sanity and the linker. */ krb5_error_code KRB5_CALLCONV krb5_read_password(context, prompt, prompt2, return_pwd, size_return) krb5_context context; const char *prompt; const char *prompt2; char *return_pwd; int *size_return; { *size_return = 0; return KRB5_LIBOS_CANTREADPWD; } #endif krb5-1.22.1/src/lib/krb5/os/t_kuserok.c0000664000175000017500000000376715051422640017351 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/t_kuserok.c - Test harness for krb5_kuserok */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include int main(int argc, char **argv) { krb5_error_code ret; krb5_context context; krb5_principal principal; krb5_boolean ok; char *progname; progname = argv[0]; if (argc != 3) { fprintf(stderr, "Usage: %s principal localuser\n", progname); return 1; } krb5_init_context(&context); ret = krb5_parse_name(context, argv[1], &principal); if (ret) { com_err(progname, ret, "while parsing principal name"); return 1; } ok = krb5_kuserok(context, principal, argv[2]); printf("krb5_kuserok returns %s\n", ok ? "true" : "false"); krb5_free_context(context); return 0; } krb5-1.22.1/src/lib/krb5/os/init_os_ctx.c0000664000175000017500000003221315051422640017651 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/init_os_ctx.c */ /* * Copyright 1994, 2007, 2008, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #define NEED_WINDOWS #include "k5-int.h" #include "os-proto.h" #include "../krb/int-proto.h" #if defined(_WIN32) #include #include static krb5_error_code get_from_windows_dir( char **pname ) { UINT size = GetWindowsDirectory(0, 0); *pname = malloc(size + strlen(DEFAULT_PROFILE_FILENAME) + 2); if (*pname) { GetWindowsDirectory(*pname, size); strcat(*pname, "\\"); strcat(*pname, DEFAULT_PROFILE_FILENAME); return 0; } else { return KRB5_CONFIG_CANTOPEN; } } static krb5_error_code get_from_module_dir( char **pname ) { const DWORD size = 1024; /* fixed buffer */ int found = 0; char *p = NULL; char *name = NULL; struct _stat s; *pname = 0; name = malloc(size); if (!name) return ENOMEM; #ifdef _WIN64 if (!GetModuleFileName(GetModuleHandle("krb5_64"), name, size)) #else if (!GetModuleFileName(GetModuleHandle("krb5_32"), name, size)) #endif goto cleanup; p = name + strlen(name); while ((p >= name) && (*p != '\\') && (*p != '/')) p--; if (p < name) goto cleanup; p++; strncpy(p, DEFAULT_PROFILE_FILENAME, size - (p - name)); name[size - 1] = 0; found = !_stat(name, &s); cleanup: if (found) *pname = name; else free(name); return 0; } /* * get_from_registry * * This will find a profile in the registry. *pbuffer != 0 if we * found something. Make sure to free(*pbuffer) when done. It will * return an error code if there is an error the user should know * about. We maintain the invariant: return value != 0 => * *pbuffer == 0. */ static krb5_error_code get_from_registry( char** pbuffer, HKEY hBaseKey ) { HKEY hKey = 0; LONG rc = 0; DWORD size = 0; krb5_error_code retval = 0; const char *key_path = "Software\\MIT\\Kerberos5"; const char *value_name = "config"; assert(pbuffer != NULL); *pbuffer = NULL; if ((rc = RegOpenKeyEx(hBaseKey, key_path, 0, KEY_QUERY_VALUE, &hKey)) != ERROR_SUCCESS) { /* not a real error */ goto cleanup; } rc = RegQueryValueEx(hKey, value_name, 0, 0, 0, &size); if ((rc != ERROR_SUCCESS) && (rc != ERROR_MORE_DATA)) { /* not a real error */ goto cleanup; } *pbuffer = malloc(size); if (!*pbuffer) { retval = ENOMEM; goto cleanup; } if ((rc = RegQueryValueEx(hKey, value_name, 0, 0, *pbuffer, &size)) != ERROR_SUCCESS) { /* * Let's not call it a real error in case it disappears, but * we need to free so that we say we did not find anything. */ free(*pbuffer); *pbuffer = 0; goto cleanup; } cleanup: if (hKey) RegCloseKey(hKey); if (retval && *pbuffer) { free(*pbuffer); /* Let's say we did not find anything: */ *pbuffer = 0; } return retval; } /* * get_from_known_folder * * This will find a profile in the specified known folder (e.g. CSIDL_APPDATA). * *pbuffer != 0 if we found something. Make sure to free(*pbuffer) when done. * It will return an error code if there is an error the user should know * about. We maintain the invariant: return value != 0 => * *pbuffer == 0. */ static krb5_error_code get_from_known_folder( int folderId, char** pbuffer ) { char szPath[MAX_PATH]; const char * software_suffix = "\\MIT\\Kerberos5"; krb5_error_code retval = 0; size_t size; struct _stat s; assert(pbuffer); *pbuffer = NULL; if (SUCCEEDED(SHGetFolderPath(NULL, folderId /*|CSIDL_FLAG_CREATE*/, NULL, SHGFP_TYPE_CURRENT, szPath))) { size = strlen(software_suffix) + strlen("\\" DEFAULT_PROFILE_FILENAME) + strlen(szPath); if ((size + 1) >= sizeof(szPath)) { goto cleanup; } strlcat(szPath, software_suffix, sizeof(szPath)); strlcat(szPath, "\\", sizeof(szPath)); strlcat(szPath, DEFAULT_PROFILE_FILENAME, sizeof(szPath)); } else { /* Might want to deliberate a bit better why we failed. But for the time being this is not an error */ goto cleanup; } if (_stat(szPath, &s)) { goto cleanup; } *pbuffer = malloc(size + 1); if (!*pbuffer) { retval = ENOMEM; goto cleanup; } strlcpy (*pbuffer, szPath, size + 1); cleanup: if (retval && *pbuffer) { free(*pbuffer); /* Let's say we did not find anything: */ *pbuffer = 0; } return retval; } #endif /* _WIN32 */ static void free_filespecs(profile_filespec_t *files) { char **cp; if (files == 0) return; for (cp = files; *cp; cp++) free(*cp); free(files); } /* This function is needed by KfM's KerberosPreferences API * because it needs to be able to specify "secure" */ static krb5_error_code os_get_default_config_files(profile_filespec_t **pfiles, krb5_boolean secure) { profile_filespec_t* files; #if defined(_WIN32) krb5_error_code retval = 0; char *name = 0; if (!secure) { char *env = secure_getenv("KRB5_CONFIG"); if (env) { name = strdup(env); if (!name) return ENOMEM; } } if (!name && !secure) { /* HKCU */ retval = get_from_registry(&name, HKEY_CURRENT_USER); if (retval) return retval; } if (!name) { /* HKLM */ retval = get_from_registry(&name, HKEY_LOCAL_MACHINE); if (retval) return retval; } if (!name && !secure) { retval = get_from_known_folder(CSIDL_APPDATA, &name); if (retval) return retval; } if (!name) { retval = get_from_known_folder(CSIDL_COMMON_APPDATA, &name); if (retval) return retval; } if (!name && !secure) { /* module dir */ retval = get_from_module_dir(&name); if (retval) return retval; } if (!name) { /* windows dir */ retval = get_from_windows_dir(&name); } if (retval) return retval; if (!name) return KRB5_CONFIG_CANTOPEN; /* should never happen */ files = malloc(2 * sizeof(char *)); if (!files) return ENOMEM; files[0] = name; files[1] = 0; #else /* !_WIN32 */ char* filepath = 0; int n_entries, i; unsigned int ent_len; const char *s, *t; if (secure) { filepath = DEFAULT_SECURE_PROFILE_PATH; } else { filepath = secure_getenv("KRB5_CONFIG"); if (!filepath) filepath = DEFAULT_PROFILE_PATH; } /* count the distinct filename components */ for(s = filepath, n_entries = 1; *s; s++) { if (*s == ':') n_entries++; } /* the array is NULL terminated */ files = (char**) malloc((n_entries+1) * sizeof(char*)); if (files == 0) return ENOMEM; /* measure, copy, and skip each one */ for(s = filepath, i=0; (t = strchr(s, ':')) || (t=s+strlen(s)); s=t+1, i++) { ent_len = t-s; files[i] = (char*) malloc(ent_len + 1); if (files[i] == 0) { /* if malloc fails, free the ones that worked */ while(--i >= 0) free(files[i]); free(files); return ENOMEM; } strncpy(files[i], s, ent_len); files[i][ent_len] = 0; if (*t == 0) { i++; break; } } /* cap the array */ files[i] = 0; #endif /* !_WIN32 */ *pfiles = (profile_filespec_t *)files; return 0; } static krb5_error_code add_kdc_config_file(profile_filespec_t **pfiles) { char *file = NULL; size_t count = 0; profile_filespec_t *newfiles; file = secure_getenv(KDC_PROFILE_ENV); if (file == NULL) file = DEFAULT_KDC_PROFILE; for (count = 0; (*pfiles)[count]; count++) ; count += 2; newfiles = malloc(count * sizeof(*newfiles)); if (newfiles == NULL) return ENOMEM; memcpy(newfiles + 1, *pfiles, (count-1) * sizeof(*newfiles)); newfiles[0] = strdup(file); if (newfiles[0] == NULL) { int e = ENOMEM; free(newfiles); return e; } free(*pfiles); *pfiles = newfiles; return 0; } /* Set the profile paths in the context. If secure is set to TRUE then do not include user paths (from environment variables, etc). If kdc is TRUE, include kdc.conf from wherever we expect to find it. */ static krb5_error_code os_init_paths(krb5_context ctx, krb5_boolean kdc) { krb5_error_code retval = 0; profile_filespec_t *files = 0; krb5_boolean secure = ctx->profile_secure; retval = os_get_default_config_files(&files, secure); if (retval == 0 && kdc) retval = add_kdc_config_file(&files); if (!retval) { retval = profile_init_flags((const_profile_filespec_t *) files, PROFILE_INIT_ALLOW_MODULE, &ctx->profile); /* If none of the filenames can be opened, use an empty profile. */ if (retval == ENOENT) retval = profile_init(NULL, &ctx->profile); } if (files) free_filespecs(files); if (retval) ctx->profile = 0; if (retval == ENOENT) return KRB5_CONFIG_CANTOPEN; if ((retval == PROF_SECTION_NOTOP) || (retval == PROF_SECTION_SYNTAX) || (retval == PROF_RELATION_SYNTAX) || (retval == PROF_EXTRA_CBRACE) || (retval == PROF_MISSING_OBRACE)) return KRB5_CONFIG_BADFORMAT; return retval; } krb5_error_code k5_os_init_context(krb5_context ctx, profile_t profile, krb5_flags flags) { krb5_os_context os_ctx; krb5_error_code retval = 0; #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; #endif /* _WIN32 */ os_ctx = &ctx->os_context; os_ctx->magic = KV5M_OS_CONTEXT; os_ctx->time_offset = 0; os_ctx->usec_offset = 0; os_ctx->os_flags = 0; os_ctx->default_ccname = 0; PLUGIN_DIR_INIT(&ctx->libkrb5_plugins); ctx->preauth_context = NULL; /* Use the profile we were handed, or create one from config files. */ if (profile) retval = profile_copy(profile, &ctx->profile); else retval = os_init_paths(ctx, (flags & KRB5_INIT_CONTEXT_KDC) != 0); if (retval) return retval; #ifdef _WIN32 /* We initialize winsock to version 1.1 but * we do not care if we succeed or fail. */ wVersionRequested = 0x0101; WSAStartup (wVersionRequested, &wsaData); #endif /* _WIN32 */ return 0; } krb5_error_code KRB5_CALLCONV krb5_get_profile (krb5_context ctx, profile_t *profile) { return profile_copy (ctx->profile, profile); } krb5_error_code krb5_set_config_files(krb5_context ctx, const char **filenames) { krb5_error_code retval = 0; profile_t profile; retval = profile_init_flags(filenames, PROFILE_INIT_ALLOW_MODULE, &profile); if (retval) return retval; if (ctx->profile) profile_abandon(ctx->profile); ctx->profile = profile; return 0; } krb5_error_code KRB5_CALLCONV krb5_get_default_config_files(char ***pfilenames) { if (!pfilenames) return EINVAL; return os_get_default_config_files(pfilenames, FALSE); } void KRB5_CALLCONV krb5_free_config_files(char **filenames) { free_filespecs(filenames); } void k5_os_free_context(krb5_context ctx) { krb5_os_context os_ctx; os_ctx = &ctx->os_context; if (os_ctx->default_ccname) { free(os_ctx->default_ccname); os_ctx->default_ccname = 0; } os_ctx->magic = 0; if (ctx->profile) { profile_abandon(ctx->profile); ctx->profile = 0; } if (ctx->preauth_context) { k5_free_preauth_context(ctx); ctx->preauth_context = NULL; } krb5int_close_plugin_dirs (&ctx->libkrb5_plugins); #ifdef _WIN32 WSACleanup(); #endif /* _WIN32 */ } krb5-1.22.1/src/lib/krb5/os/localauth_names.c0000664000175000017500000000674715051422640020503 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/localauth_names.c - names localauth module */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "os-proto.h" #include static krb5_error_code an2ln_names(krb5_context context, krb5_localauth_moddata data, const char *type, const char *residual, krb5_const_principal aname, char **lname_out) { krb5_error_code ret; char *realm = NULL, *pname = NULL, **mapping_values = NULL; const char *hierarchy[5]; size_t count; *lname_out = NULL; /* * Fetch the profile values for realms->-> * auth_to_local_names->. Use the principal name without realm; * this is problematic in many multiple-realm environments, but is how * we've historically done it. */ ret = krb5_get_default_realm(context, &realm); if (ret) return KRB5_LNAME_NOTRANS; ret = krb5_unparse_name_flags(context, aname, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &pname); if (ret) goto cleanup; hierarchy[0] = KRB5_CONF_REALMS; hierarchy[1] = realm; hierarchy[2] = KRB5_CONF_AUTH_TO_LOCAL_NAMES; hierarchy[3] = pname; hierarchy[4] = NULL; ret = profile_get_values(context->profile, hierarchy, &mapping_values); if (ret) { ret = KRB5_LNAME_NOTRANS; goto cleanup; } /* We found one or more explicit mappings. Use the last one. */ for (count = 0; mapping_values[count] != NULL; count++); *lname_out = strdup(mapping_values[count - 1]); if (*lname_out == NULL) ret = ENOMEM; cleanup: free(realm); free(pname); profile_free_list(mapping_values); return ret; } static void freestr(krb5_context context, krb5_localauth_moddata data, char *str) { free(str); } krb5_error_code localauth_names_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_localauth_vtable vt = (krb5_localauth_vtable)vtable; vt->name = "names"; vt->an2ln = an2ln_names; vt->free_string = freestr; return 0; } krb5-1.22.1/src/lib/krb5/os/t_trace.c0000664000175000017500000002201315051422640016745 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/t_trace.c - Test harness for trace.c */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "port-sockets.h" #include "os-proto.h" #include const char *prog; static void kfatal (krb5_error_code err) { com_err (prog, err, "- exiting"); exit (1); } int main (int argc, char *argv[]) { char *p; krb5_context ctx; krb5_error_code err; int i = -1; long ln = -2; size_t s = 0; char *str = "example.data"; krb5_octet *oct = (krb5_octet *) str; unsigned int oct_length = strlen(str); struct remote_address ra; struct sockaddr_in *addr_in; krb5_data data; struct krb5_key_st key; krb5_checksum checksum; krb5_principal_data principal_data, principal_data2; krb5_principal princ = &principal_data; krb5_pa_data padata, padata2, **padatap; krb5_enctype enctypes[4] = { ENCTYPE_DES3_CBC_SHA, ENCTYPE_ARCFOUR_HMAC_EXP, ENCTYPE_UNKNOWN, ENCTYPE_NULL}; krb5_ccache ccache; krb5_keytab keytab; krb5_creds creds; p = strrchr (argv[0], '/'); if (p) prog = p+1; else prog = argv[0]; if (argc != 1) { fprintf (stderr, "%s: usage: %s\n", prog, prog); return 1; } err = krb5_init_context (&ctx); if (err) kfatal (err); krb5int_trace(NULL, NULL); TRACE(ctx, "simple format"); TRACE(ctx, "int, in decimal: {int}", i); TRACE(ctx, "long, in decimal: {long}", ln); TRACE(ctx, "const char *, display as C string: {str}", str); s = strlen(str); TRACE(ctx, "size_t and const char *, as a counted string: {lenstr}", s, str); TRACE(ctx, "size_t and const char *, as a counted string: {lenstr}", 1, NULL); TRACE(ctx, "size_t and const char *, as hex bytes: {hexlenstr}", s, str); TRACE(ctx, "size_t and const char *, as hex bytes: {hexlenstr}", 1, NULL); TRACE(ctx, "size_t and const char *, as four-character hex hash: " "{hashlenstr}", s, str); TRACE(ctx, "size_t and const char *, as four-character hex hash: " "{hashlenstr}", 1, NULL); ra.transport = TCP; addr_in = (struct sockaddr_in *)&ra.saddr; addr_in->sin_family = AF_INET; addr_in->sin_addr.s_addr = INADDR_ANY; addr_in->sin_port = htons(88); ra.len = sizeof(struct sockaddr_in); ra.family = AF_INET; TRACE(ctx, "struct remote_address *, show socket type, address, port: " "{raddr}", &ra); ra.transport = UDP; TRACE(ctx, "struct remote_address *, show socket type, address, port: " "{raddr}", &ra); ra.transport = 1234; addr_in->sin_family = AF_UNSPEC; ra.family = AF_UNSPEC; TRACE(ctx, "struct remote_address *, show socket type, address, port: " "{raddr}", &ra); ra.family = 5678; TRACE(ctx, "struct remote_address *, show socket type, address, port: " "{raddr}", &ra); data.magic = 0; data.length = strlen(str); data.data = str; TRACE(ctx, "krb5_data *, display as counted string: {data}", &data); TRACE(ctx, "krb5_data *, display as counted string: {data}", NULL); TRACE(ctx, "krb5_data *, display as hex bytes: {hexdata}", &data); TRACE(ctx, "krb5_data *, display as hex bytes: {hexdata}", NULL); TRACE(ctx, "int, display as number/errorstring: {errno}", ENOENT); TRACE(ctx, "krb5_error_code, display as number/errorstring: {kerr}", 0); key.keyblock.magic = 0; key.keyblock.enctype = ENCTYPE_UNKNOWN; key.keyblock.length = strlen(str); key.keyblock.contents = (krb5_octet *)str; key.refcount = 0; key.derived = NULL; key.cache = NULL; TRACE(ctx, "const krb5_keyblock *, display enctype and hash of key: " "{keyblock}", &key.keyblock); TRACE(ctx, "const krb5_keyblock *, display enctype and hash of key: " "{keyblock}", NULL); TRACE(ctx, "krb5_key, display enctype and hash of key: {key}", &key); TRACE(ctx, "krb5_key, display enctype and hash of key: {key}", NULL); checksum.magic = 0; checksum.checksum_type = -1; checksum.length = oct_length; checksum.contents = oct; TRACE(ctx, "const krb5_checksum *, display cksumtype and hex checksum: " "{cksum}", &checksum); principal_data.magic = 0; principal_data.realm.magic = 0; principal_data.realm.data = "ATHENA.MIT.EDU"; principal_data.realm.length = strlen(principal_data.realm.data); principal_data.data = &data; principal_data.length = 0; principal_data.type = KRB5_NT_UNKNOWN; TRACE(ctx, "krb5_principal, unparse and display: {princ}", princ); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_UNKNOWN); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_PRINCIPAL); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_SRV_INST); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_SRV_HST); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_SRV_XHST); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_UID); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_X500_PRINCIPAL); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_SMTP_NAME); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_ENTERPRISE_PRINCIPAL); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_WELLKNOWN); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_MS_PRINCIPAL); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_MS_PRINCIPAL_AND_ID); TRACE(ctx, "int, krb5_principal type: {ptype}", KRB5_NT_ENT_PRINCIPAL_AND_ID); TRACE(ctx, "int, krb5_principal type: {ptype}", -1); padatap = malloc(sizeof(krb5_pa_data *) * 3); padatap[0] = &padata; padatap[1] = &padata2; padatap[2] = NULL; padata.magic = 0; padata.pa_type = KRB5_PADATA_NONE; padata.length = oct_length; padata.contents = oct; padata2 = padata; padata.pa_type = KRB5_PADATA_PW_SALT; TRACE(ctx, "krb5_pa_data **, display list of padata type numbers: " "{patypes}", padatap); TRACE(ctx, "krb5_pa_data **, display list of padata type numbers: " "{patypes}", NULL); free(padatap); padatap = NULL; TRACE(ctx, "krb5_enctype, display shortest name of enctype: {etype}", ENCTYPE_AES128_CTS_HMAC_SHA1_96); TRACE(ctx, "krb5_enctype *, display list of enctypes: {etypes}", enctypes); TRACE(ctx, "krb5_enctype *, display list of enctypes: {etypes}", NULL); err = krb5_cc_resolve(ctx, "FILE:/path/to/ccache", &ccache); TRACE(ctx, "krb5_ccache, display type:name: {ccache}", ccache); krb5_cc_close(ctx, ccache); err = krb5_kt_resolve(ctx, "FILE:/etc/krb5.keytab", &keytab); TRACE(ctx, "krb5_keytab, display name: {keytab}", keytab); krb5_kt_close(ctx, keytab); creds.magic = 0; creds.client = &principal_data; memcpy(&principal_data2, &principal_data, sizeof(principal_data)); principal_data2.realm.data = "ZEUS.MIT.EDU"; principal_data2.realm.length = strlen(principal_data2.realm.data); creds.server = &principal_data2; memcpy(&creds.keyblock, &key.keyblock, sizeof(creds.keyblock)); creds.times.authtime = 0; creds.times.starttime = 1; creds.times.endtime = 2; creds.times.renew_till = 3; creds.is_skey = FALSE; creds.ticket_flags = 0; creds.addresses = NULL; creds.ticket.magic = 0; creds.ticket.length = strlen(str); creds.ticket.data = str; creds.second_ticket.magic = 0; creds.second_ticket.length = strlen(str); creds.second_ticket.data = str; creds.authdata = NULL; TRACE(ctx, "krb5_creds *, display clientprinc -> serverprinc: {creds}", &creds); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/lib/krb5/os/localauth_rule.c0000664000175000017500000002403715051422640020337 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/localauth_rule.c - rule localauth module */ /* * Copyright (C) 1990,1991,2007,2008,2013 by the Massachusetts * Institute of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This module implements the RULE type for auth_to_local processing. * * There are three parts to each rule. The first part, if present, determines * the selection string. If this is not present, the selection string defaults * to the unparsed principal name without realm (which can be dangerous in * multi-realm environments, but is our historical behavior). The selection * string syntax is: * * "[" ":" "]" * * is the number of expected components for this rule. If the * principal does not have this many components, then this rule does * not apply. * * determines the selection string. Within , $0 will * be substituted with the principal's realm, $1 with its first * component, $2 with its second component, and so forth. * * The second part is an optional regular expression surrounded by parentheses. * If present, the rule will only apply if the selection string matches the * regular expression. At present, the regular expression may not contain a * ')' character. * * The third part is a sequence of zero or more transformation rules, using * the syntax: * * "s/" "/" "/" ["g"] * * No substitutions are allowed within . A "g" indicates that the * substitution should be performed globally; otherwise it will be performed at * most once. */ #include "k5-int.h" #include "os-proto.h" #include #include #include "k5-regex.h" /* Process the match portion of a rule and update *contextp. Return * KRB5_LNAME_NOTRANS if selstring doesn't match the regexp. */ static krb5_error_code aname_do_match(const char *selstring, const char **contextp) { krb5_error_code ret; const char *startp, *endp; char *regstr; regex_t re; regmatch_t m; /* If no regexp is present, leave *contextp alone and return success. */ if (**contextp != '(') return 0; /* Find the end of the regexp and make a copy of it. */ startp = *contextp + 1; endp = strchr(startp, ')'); if (endp == NULL) return KRB5_CONFIG_BADFORMAT; regstr = k5memdup0(startp, endp - startp, &ret); if (regstr == NULL) return ret; /* Perform the match. */ ret = (regcomp(&re, regstr, REG_EXTENDED) == 0 && regexec(&re, selstring, 1, &m, 0) == 0 && m.rm_so == 0 && (size_t)m.rm_eo == strlen(selstring)) ? 0 : KRB5_LNAME_NOTRANS; regfree(&re); free(regstr); *contextp = endp + 1; return ret; } /* Replace regular expression matches of regstr with repl in instr, producing * *outstr. If doall is true, replace all matches for regstr. */ static krb5_error_code do_replacement(const char *regstr, const char *repl, krb5_boolean doall, const char *instr, char **outstr) { struct k5buf buf; regex_t re; regmatch_t m; *outstr = NULL; if (regcomp(&re, regstr, REG_EXTENDED)) return KRB5_LNAME_NOTRANS; k5_buf_init_dynamic(&buf); while (regexec(&re, instr, 1, &m, 0) == 0) { k5_buf_add_len(&buf, instr, m.rm_so); k5_buf_add(&buf, repl); instr += m.rm_eo; if (!doall) break; } regfree(&re); k5_buf_add(&buf, instr); *outstr = k5_buf_cstring(&buf); return (*outstr == NULL) ? ENOMEM : 0; } /* * Perform any substitutions specified by *contextp, and advance *contextp past * the substitution expressions. Place the result of the substitutions in * *result. */ static krb5_error_code aname_replacer(const char *string, const char **contextp, char **result) { krb5_error_code ret = 0; const char *cp, *ep, *tp; char *newstr, *rule = NULL, *repl = NULL, *current = NULL; krb5_boolean doglobal; *result = NULL; current = strdup(string); if (current == NULL) return ENOMEM; /* Iterate over replacement expressions, updating current for each one. */ cp = *contextp; while (*cp != '\0') { /* Skip leading whitespace */ while (isspace((unsigned char)*cp)) cp++; /* Find the separators for an s/rule/repl/ expression. */ if (!(cp[0] == 's' && cp[1] == '/' && (ep = strchr(cp + 2, '/')) && (tp = strchr(ep + 1, '/')))) { ret = KRB5_CONFIG_BADFORMAT; goto cleanup; } /* Copy the rule and replacement strings. */ free(rule); rule = k5memdup0(cp + 2, ep - (cp + 2), &ret); if (rule == NULL) goto cleanup; free(repl); repl = k5memdup0(ep + 1, tp - (ep + 1), &ret); if (repl == NULL) goto cleanup; /* Advance past expression and check for trailing "g". */ cp = tp + 1; doglobal = (*cp == 'g'); if (doglobal) cp++; ret = do_replacement(rule, repl, doglobal, current, &newstr); if (ret) goto cleanup; free(current); current = newstr; } *result = current; current = NULL; cleanup: free(current); free(repl); free(rule); return ret; } /* * Compute selection string for RULE rules. Advance *contextp to the string * position after the selstring part if present, and set *result to the * selection string. */ static krb5_error_code aname_get_selstring(krb5_context context, krb5_const_principal aname, const char **contextp, char **selstring_out) { const char *current; char *end; long num_comps, ind; const krb5_data *datap; struct k5buf selstring; size_t nlit; *selstring_out = NULL; if (**contextp != '[') { /* * No selstring part; use the principal name without realm. This is * problematic in many multiple-realm environments, but is how we've * historically done it. */ return krb5_unparse_name_flags(context, aname, KRB5_PRINCIPAL_UNPARSE_NO_REALM, selstring_out); } /* Advance past the '[' and read the number of components. */ current = *contextp + 1; errno = 0; num_comps = strtol(current, &end, 10); if (errno != 0 || num_comps < 0 || *end != ':') return KRB5_CONFIG_BADFORMAT; current = end; if (num_comps != aname->length) return KRB5_LNAME_NOTRANS; current++; k5_buf_init_dynamic(&selstring); while (TRUE) { /* Copy in literal characters up to the next $ or ]. */ nlit = strcspn(current, "$]"); k5_buf_add_len(&selstring, current, nlit); current += nlit; if (*current != '$') break; /* Expand $ substitution to a principal component. */ errno = 0; ind = strtol(current + 1, &end, 10); if (errno || ind > num_comps) break; current = end; datap = ind > 0 ? &aname->data[ind - 1] : &aname->realm; k5_buf_add_len(&selstring, datap->data, datap->length); } /* Check that we hit a ']' and not the end of the string. */ if (*current != ']') { k5_buf_free(&selstring); return KRB5_CONFIG_BADFORMAT; } *selstring_out = k5_buf_cstring(&selstring); if (*selstring_out == NULL) return ENOMEM; *contextp = current + 1; return 0; } static krb5_error_code an2ln_rule(krb5_context context, krb5_localauth_moddata data, const char *type, const char *rule, krb5_const_principal aname, char **lname_out) { krb5_error_code ret; const char *current; char *selstring = NULL; *lname_out = NULL; if (rule == NULL) return KRB5_CONFIG_BADFORMAT; /* Compute the selection string. */ current = rule; ret = aname_get_selstring(context, aname, ¤t, &selstring); if (ret) return ret; /* Check the selection string against the regexp, if present. */ if (*current == '(') { ret = aname_do_match(selstring, ¤t); if (ret) goto cleanup; } /* Perform the substitution. */ ret = aname_replacer(selstring, ¤t, lname_out); cleanup: free(selstring); return ret; } static void freestr(krb5_context context, krb5_localauth_moddata data, char *str) { free(str); } krb5_error_code localauth_rule_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_localauth_vtable vt = (krb5_localauth_vtable)vtable; static const char *types[] = { "RULE", NULL }; vt->name = "rule"; vt->an2ln_types = types; vt->an2ln = an2ln_rule; vt->free_string = freestr; return 0; } krb5-1.22.1/src/lib/krb5/os/t_an_to_ln.c0000664000175000017500000000246415051422640017450 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "krb5.h" #include int main(int argc, char **argv) { krb5_error_code kret = 0; krb5_context kcontext; krb5_principal principal; char *programname; int i; char sbuf[1024]; programname = argv[0]; krb5_init_context(&kcontext); for (i=1; i < argc; i++) { if (!(kret = krb5_parse_name(kcontext, argv[i], &principal))) { if (!(kret = krb5_aname_to_localname(kcontext, principal, 1024, sbuf))) { printf("%s: aname_to_lname maps %s -> <%s>\n", programname, argv[i], sbuf); } else { printf("%s: aname to lname returns %s for %s\n", programname, error_message(kret), argv[i]); } krb5_free_principal(kcontext, principal); } else { printf("%s: parse_name returns %s\n", programname, error_message(kret)); } if (kret) break; } krb5_free_context(kcontext); return((kret) ? 1 : 0); } krb5-1.22.1/src/lib/krb5/os/realm_dom.c0000664000175000017500000000444515051422640017274 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/realm_dom.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Determines the proper domain name for a realm. This is mainly so that * a krb4 principal can be converted properly into a krb5 principal. * Currently, the same style of mapping file used in krb4. * * If realm is NULL, this function will assume the default realm * of the local host. * * The returned domain is allocated, and must be freed by the caller. * * This was hacked together from krb5_get_host_realm(). */ #include "k5-int.h" #include #include krb5_error_code KRB5_CALLCONV krb5_get_realm_domain(krb5_context context, const char *realm, char **domain) { krb5_error_code retval; char *temp_domain = 0; retval = profile_get_string(context->profile, KRB5_CONF_REALMS, realm, KRB5_CONF_DEFAULT_DOMAIN, realm, &temp_domain); if (!retval && temp_domain) { *domain = strdup(temp_domain); if (!*domain) { retval = ENOMEM; } profile_release_string(temp_domain); } return retval; } krb5-1.22.1/src/lib/krb5/os/localauth_an2ln.c0000664000175000017500000000434515051422640020402 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/localauth_an2ln.c - an2ln localauth module */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "os-proto.h" #include #define MAX_USERNAME 65 static krb5_error_code an2ln_userok(krb5_context context, krb5_localauth_moddata data, krb5_const_principal aname, const char *lname) { krb5_error_code ret; char kuser[MAX_USERNAME]; ret = krb5_aname_to_localname(context, aname, sizeof(kuser), kuser); return (ret == 0 && strcmp(kuser, lname) == 0) ? 0 : KRB5_PLUGIN_NO_HANDLE; } krb5_error_code localauth_an2ln_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_localauth_vtable vt = (krb5_localauth_vtable)vtable; vt->name = "an2ln"; vt->userok = an2ln_userok; return 0; } krb5-1.22.1/src/lib/krb5/os/t_ctxprf.c0000664000175000017500000000561715051422640017170 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/t_ctxprf.c - krb5_init_context_profile() test */ /* * Copyright (C) 2024 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program tests the use of krb5_init_context_profile() with a modified * profile object. If run with the single argument "empty", we create and * modifiemodify an empty profile; otherwise, we retrieve and modify the * profile for a normally created libkrb5 context. In both cases, we set a * realm KDC value in the profile and use k5_locate_kdc() to verify that the * setting is reflected in a libkrb5 context created using the modified * profile. */ #include "k5-int.h" #include "os-proto.h" static void check(long code) { assert(code == 0); } int main(int argc, char **argv) { profile_t p; krb5_context ctx; const char *names[] = { "realms", "KRBTEST.COM", "kdc", NULL }; krb5_data realm = string2data("KRBTEST.COM"); struct serverlist sl; if (argc > 1 && strcmp(argv[1], "empty") == 0) { check(profile_init(NULL, &p)); } else { check(krb5_init_context(&ctx)); check(krb5_get_profile(ctx, &p)); krb5_free_context(ctx); profile_clear_relation(p, names); } check(profile_add_relation(p, names, "ctx.prf.test")); check(krb5_init_context_profile(p, 0, &ctx)); check(k5_locate_kdc(ctx, &realm, &sl, FALSE, FALSE)); assert(sl.nservers == 1); assert(strcmp(sl.servers[0].hostname, "ctx.prf.test") == 0); profile_abandon(p); k5_free_serverlist(&sl); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/lib/krb5/os/net_read.c0000664000175000017500000000431615051422640017113 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/net_read.c */ /* * Copyright 1987, 1988, 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" /* * krb5_net_read() reads from the file descriptor "fd" to the buffer * "buf", until either 1) "len" bytes have been read or 2) cannot * read anymore from "fd". It returns the number of bytes read * or a read() error. (The calling interface is identical to * read(2).) * * XXX must not use non-blocking I/O */ int krb5_net_read(krb5_context context, int fd, char *buf, int len) { int cc, len2 = 0; do { cc = SOCKET_READ((SOCKET)fd, buf, len); if (cc < 0) { if (SOCKET_ERRNO == SOCKET_EINTR) continue; /* XXX this interface sucks! */ errno = SOCKET_ERRNO; return(cc); /* errno is already set */ } else if (cc == 0) { return(len2); } else { buf += cc; len2 += cc; len -= cc; } } while (len > 0); return(len2); } krb5-1.22.1/src/lib/krb5/os/td_krb5.conf0000664000175000017500000000053615051422640017367 0ustar ghudsonghudson[libdefaults] default_realm = DEFAULT.REALM.TST [realms] DEFAULT_REALM.TST = { kdc = FIRST.KDC.HOST kdc = SECOND.KDC.HOST:88 admin_server = FIRST.KDC.HOST default_domain = MIT.EDU } IGGY.ORG = { kdc = KERBEROS.IGGY.ORG kdc = KERBEROS-B.IGGY.ORG } [domain_realm] bad.idea = US.GOV .bad.idea = NSA.GOV clipper.bad.idea = NIST.GOV krb5-1.22.1/src/lib/krb5/os/t_locate_kdc.c0000664000175000017500000000634315051422640017747 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "k5-platform.h" #include "port-sockets.h" #include #include #define TEST #include "fake-addrinfo.h" #include "dnsglue.c" #include "dnssrv.c" #include "locate_kdc.c" enum { LOOKUP_CONF = 3, LOOKUP_DNS, LOOKUP_WHATEVER } how = LOOKUP_WHATEVER; const char *prog; struct serverlist sl; static void kfatal (krb5_error_code err) { com_err (prog, err, "- exiting"); exit (1); } static const char * ttypename (k5_transport ttype) { static char buf[20]; switch (ttype) { case TCP_OR_UDP: return "tcp or udp"; case TCP: return "tcp"; case UDP: return "udp"; case HTTPS: return "https"; default: snprintf(buf, sizeof(buf), "?%d", ttype); return buf; } } static void print_addrs (void) { size_t i; int err; printf("%d servers:\n", (int)sl.nservers); for (i = 0; i < sl.nservers; i++) { struct server_entry *entry = &sl.servers[i]; char hostbuf[NI_MAXHOST], srvbuf[NI_MAXSERV]; if (entry->hostname != NULL) { printf("%d: h:%s t:%s p:%d m:%d P:%s\n", (int)i, entry->hostname, ttypename(entry->transport), entry->port, entry->primary, entry->uri_path ? entry->uri_path : ""); continue; } err = getnameinfo((struct sockaddr *)&entry->addr, entry->addrlen, hostbuf, sizeof(hostbuf), srvbuf, sizeof(srvbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (err) { printf("%2d: getnameinfo returns error %d=%s\n", (int)i, err, gai_strerror(err)); } else { printf("%2d: address %s\t%s\tport %s\n", (int)i, hostbuf, ttypename(entry->transport), srvbuf); } } } int main (int argc, char *argv[]) { char *p, *realmname; krb5_data realm; krb5_context ctx; krb5_error_code err; int primary = 0; p = strrchr (argv[0], '/'); if (p) prog = p+1; else prog = argv[0]; switch (argc) { case 2: /* foo $realm */ realmname = argv[1]; break; case 3: if (!strcmp (argv[1], "-c")) how = LOOKUP_CONF; else if (!strcmp (argv[1], "-d")) how = LOOKUP_DNS; else if (!strcmp (argv[1], "-m")) primary = 1; else goto usage; realmname = argv[2]; break; default: usage: fprintf (stderr, "%s: usage: %s [-c | -d | -m] realm\n", prog, prog); return 1; } err = krb5_init_context (&ctx); if (err) kfatal (err); realm.data = realmname; realm.length = strlen (realmname); switch (how) { case LOOKUP_CONF: err = krb5_locate_srv_conf(ctx, &realm, "kdc", &sl, htons(88)); break; case LOOKUP_DNS: err = locate_srv_dns_1(ctx, &realm, "_kerberos", "_udp", &sl); break; case LOOKUP_WHATEVER: err = k5_locate_kdc(ctx, &realm, &sl, primary, FALSE); break; } if (err) kfatal (err); print_addrs(); k5_free_serverlist(&sl); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/lib/krb5/os/t_gifconf.c0000664000175000017500000001276315051422640017275 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* SIOCGIFCONF: The behavior of this ioctl varies across systems. The "largest gap" values are the largest number of bytes I've seen left unused at the end of the supplied buffer when there were more entries to return. These values may of coures be dependent on the configurations of the particular systems I was testing with. NetBSD 1.5-alpha: The returned ifc_len is the desired amount of space, always. The returned list may be truncated if there isn't enough room; no overrun. Largest gap: 43. (NetBSD now has getifaddrs.) BSD/OS 4.0.1 (courtesy djm): The returned ifc_len is equal to or less than the supplied ifc_len. Sometimes the entire buffer is used; sometimes N-1 bytes; occasionally, the buffer must have quite a bit of extra room before the next structure will be added. Largest gap: 39. Solaris 7,8: Return EINVAL if the buffer space is too small for all the data to be returned, including ifc_len==0. Solaris is the only system I've found so far that actually returns an error. No gap. However, SIOCGIFNUM may be used to query the number of interfaces. Linux 2.2.12 (RH 6.1 dist, x86): The buffer is filled in with as many entries as will fit, and the size used is returned in ifc_len. The list is truncated if needed, with no indication. Largest gap: 31. IRIX 6.5: The buffer is filled in with as many entries as will fit in N-1 bytes, and the size used is returned in ifc_len. Providing exactly the desired number of bytes is inadequate; the buffer must be *bigger* than needed. (E.g., 32->0, 33->32.) The returned ifc_len is always less than the supplied one. Largest gap: 32. AIX 4.3.3: Sometimes the returned ifc_len is bigger than the supplied one, but it may not be big enough for *all* the interfaces. Sometimes it's smaller than the supplied value, even if the returned list is truncated. The list is filled in with as many entries as will fit; no overrun. Largest gap: 143. Older AIX: We're told by W. David Shambroom in PR krb5-kdc/919 that older versions of AIX have a bug in the SIOCGIFCONF ioctl which can cause them to overrun the supplied buffer. However, we don't yet have details as to which version, whether the overrun amount was bounded (e.g., one ifreq's worth) or not, whether it's a real buffer overrun or someone assuming it was because ifc_len was increased, etc. Once we've got details, we can try to work around the problem. Digital UNIX 4.0F: If input ifc_len is zero, return an ifc_len that's big enough to include all entries. (Actually, on our system, it appears to be larger than that by 32.) If input ifc_len is nonzero, fill in as many entries as will fit, and set ifc_len accordingly. (Tested only with INIT of zero.) So... if the returned ifc_len is bigger than the supplied one, we'll need at least that much space -- but possibly more -- to hold all the results. If the returned value is smaller or the same, we may still need more space. Using this ioctl is going to be messy. Let's just hope that getifaddrs() catches on quickly.... */ #include #include #include #include #include #include #if (defined(sun) || defined(__sun__)) && !defined(SIOCGIFCONF) /* Sun puts socket ioctls in another file. */ #include #endif #define INIT 0xc3 int main(void) { char buffer[2048]; int i, sock, t, olen = -9, omod = -9; struct ifconf ifc; int gap = -1, lastgap = -1; sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror ("socket"); exit (1); } printf ("sizeof(struct if_req)=%d\n", sizeof (struct ifreq)); for (t = 0; t < sizeof (buffer); t++) { ifc.ifc_len = t; ifc.ifc_buf = buffer; memset (buffer, INIT, sizeof (buffer)); i = ioctl (sock, SIOCGIFCONF, (char *) &ifc); if (i < 0) { /* Solaris returns "Invalid argument" if the buffer is too small. AIX and Linux return no error indication. */ int e = errno; snprintf (buffer, sizeof(buffer), "SIOCGIFCONF(%d)", t); errno = e; perror (buffer); if (e == EINVAL) continue; fprintf (stderr, "exiting on unexpected error\n"); exit (1); } i = sizeof (buffer) - 1; while (buffer[i] == ((char)INIT) && i >= 0) i--; if (omod != i) { /* Okay... the gap computed on the *last* iteration is the largest for that particular size of returned data. Save it, and then start computing gaps for the next bigger size of returned data. If we never get anything bigger back, we discard the newer value and only keep LASTGAP because all we care about is how much slop we need to "prove" that there really weren't any more entries to be returned. */ if (gap > lastgap) lastgap = gap; } gap = t - i - 1; if (olen != ifc.ifc_len || omod != i) { printf ("ifc_len in = %4d, ifc_len out = %4d, last mod = %4d\n", t, ifc.ifc_len, i); olen = ifc.ifc_len; omod = i; } } printf ("finished at ifc_len %d\n", t); printf ("largest gap = %d\n", lastgap); exit (0); } krb5-1.22.1/src/lib/krb5/os/ccdefname.c0000664000175000017500000002067315051422640017243 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/ccdefname.c - Return default credential cache name */ /* * Copyright 1990, 2007 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #define NEED_WINDOWS #include "k5-int.h" #include "../ccache/cc-int.h" #include "os-proto.h" #include #if defined(_WIN32) static int get_from_registry_indirect(char *name_buf, int name_size) { /* If the RegKRB5CCNAME variable is set, it will point to * the registry key that has the name of the cache to use. * The Gradient PC-DCE sets the registry key * [HKEY_CURRENT_USER\Software\Gradient\DCE\Default\KRB5CCNAME] * to point at the cache file name (including the FILE: prefix). * By indirecting with the RegKRB5CCNAME entry in kerberos.ini, * we can accommodate other versions that might set a registry * variable. */ char newkey[256]; LONG name_buf_size; HKEY hkey; int found = 0; char *cp; newkey[0] = 0; GetPrivateProfileString(INI_FILES, "RegKRB5CCNAME", "", newkey, sizeof(newkey), KERBEROS_INI); if (!newkey[0]) return 0; newkey[sizeof(newkey)-1] = 0; cp = strrchr(newkey,'\\'); if (cp) { *cp = '\0'; /* split the string */ cp++; } else cp = ""; if (RegOpenKeyEx(HKEY_CURRENT_USER, newkey, 0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS) return 0; name_buf_size = name_size; if (RegQueryValueEx(hkey, cp, 0, 0, name_buf, &name_buf_size) != ERROR_SUCCESS) { RegCloseKey(hkey); return 0; } RegCloseKey(hkey); return 1; } static const char *key_path = "Software\\MIT\\Kerberos5"; static const char *value_name = "ccname"; static int set_to_registry( HKEY hBaseKey, const char *name_buf ) { HRESULT result; HKEY hKey; if ((result = RegCreateKeyEx(hBaseKey, key_path, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL)) != ERROR_SUCCESS) { return 0; } if (RegSetValueEx(hKey, value_name, 0, REG_SZ, name_buf, strlen(name_buf)+1) != ERROR_SUCCESS) { RegCloseKey(hKey); return 0; } RegCloseKey(hKey); return 1; } /* * get_from_registry * * This will find the ccname in the registry. Returns 0 on error, non-zero * on success. */ static int get_from_registry( HKEY hBaseKey, char *name_buf, int name_size ) { HKEY hKey; DWORD name_buf_size = (DWORD)name_size; if (RegOpenKeyEx(hBaseKey, key_path, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) return 0; if (RegQueryValueEx(hKey, value_name, 0, 0, name_buf, &name_buf_size) != ERROR_SUCCESS) { RegCloseKey(hKey); return 0; } RegCloseKey(hKey); return 1; } #define APPEND_KRB5CC "\\krb5cc" static int try_dir( char* dir, char* buffer, int buf_len ) { struct _stat s; if (!dir) return 0; if (_stat(dir, &s)) return 0; if (!(s.st_mode & _S_IFDIR)) return 0; if (buffer != dir) { strncpy(buffer, dir, buf_len); buffer[buf_len-1]='\0'; } strncat(buffer, APPEND_KRB5CC, buf_len-strlen(buffer)); buffer[buf_len-1] = '\0'; return 1; } static krb5_error_code get_from_os_buffer(char *name_buf, unsigned int name_size) { char *prefix = krb5_cc_dfl_ops->prefix; unsigned int size; char *p; DWORD gle; SetLastError(0); GetEnvironmentVariable(KRB5_ENV_CCNAME, name_buf, name_size); gle = GetLastError(); if (gle == 0) return 0; else if (gle != ERROR_ENVVAR_NOT_FOUND) return ENOMEM; if (get_from_registry(HKEY_CURRENT_USER, name_buf, name_size) != 0) return 0; if (get_from_registry(HKEY_LOCAL_MACHINE, name_buf, name_size) != 0) return 0; if (get_from_registry_indirect(name_buf, name_size) != 0) return 0; strncpy(name_buf, prefix, name_size - 1); name_buf[name_size - 1] = 0; size = name_size - strlen(prefix); if (size > 0) strcat(name_buf, ":"); size--; p = name_buf + name_size - size; if (!strcmp(prefix, "API")) { strncpy(p, "krb5cc", size); } else if (!strcmp(prefix, "FILE") || !strcmp(prefix, "STDIO")) { if (!try_dir(getenv("TEMP"), p, size) && !try_dir(getenv("TMP"), p, size)) { unsigned int len = GetWindowsDirectory(p, size); name_buf[name_size - 1] = 0; if (len < size - sizeof(APPEND_KRB5CC)) strcat(p, APPEND_KRB5CC); } } else { strncpy(p, "default_cache_name", size); } name_buf[name_size - 1] = 0; return 0; } static void get_from_os(krb5_context context) { krb5_error_code err; char buf[1024]; if (get_from_os_buffer(buf, sizeof(buf)) == 0) context->os_context.default_ccname = strdup(buf); } #else /* not _WIN32 */ static void get_from_os(krb5_context context) { (void)k5_expand_path_tokens(context, DEFCCNAME, &context->os_context.default_ccname); } #endif /* not _WIN32 */ #if defined(_WIN32) static void set_for_os(const char *name) { set_to_registry(HKEY_CURRENT_USER, name); } #else static void set_for_os(const char *name) { /* No implementation at present. */ } #endif /* * Set the default ccache name for all processes for the current user * (and the current context) */ krb5_error_code KRB5_CALLCONV krb5int_cc_user_set_default_name(krb5_context context, const char *name) { krb5_error_code err; err = krb5_cc_set_default_name(context, name); if (err) return err; set_for_os(name); return 0; } krb5_error_code KRB5_CALLCONV krb5_cc_set_default_name(krb5_context context, const char *name) { krb5_os_context os_ctx; char *new_ccname = NULL; if (!context || context->magic != KV5M_CONTEXT) return KV5M_CONTEXT; if (name != NULL) { new_ccname = strdup(name); if (new_ccname == NULL) return ENOMEM; } /* Free the old ccname and store the new one. */ os_ctx = &context->os_context; free(os_ctx->default_ccname); os_ctx->default_ccname = new_ccname; return 0; } const char * KRB5_CALLCONV krb5_cc_default_name(krb5_context context) { krb5_os_context os_ctx; char *profstr, *envstr; if (!context || context->magic != KV5M_CONTEXT) return NULL; os_ctx = &context->os_context; if (os_ctx->default_ccname != NULL) return os_ctx->default_ccname; /* Try the environment variable first. */ envstr = secure_getenv(KRB5_ENV_CCNAME); if (envstr != NULL) { os_ctx->default_ccname = strdup(envstr); return os_ctx->default_ccname; } if (profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_DEFAULT_CCACHE_NAME, NULL, NULL, &profstr) == 0 && profstr != NULL) { (void)k5_expand_path_tokens(context, profstr, &os_ctx->default_ccname); profile_release_string(profstr); return os_ctx->default_ccname; } /* Fall back on the default ccache name for the OS. */ get_from_os(context); return os_ctx->default_ccname; } krb5-1.22.1/src/lib/krb5/os/t_std_conf.c0000664000175000017500000001253015051422640017451 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * t_std_conf.c --- This program tests standard Krb5 routines which pull * values from the krb5 config file(s). */ #include "k5-int.h" #include "fake-addrinfo.h" #include #include #include #include #include #include #include #include #include "os-proto.h" static void test_get_default_realm(krb5_context ctx) { char *realm; krb5_error_code retval; retval = krb5_get_default_realm(ctx, &realm); if (retval) { com_err("krb5_get_default_realm", retval, 0); return; } printf("krb5_get_default_realm() returned '%s'\n", realm); free(realm); } static void test_set_default_realm(krb5_context ctx, char *realm) { krb5_error_code retval; retval = krb5_set_default_realm(ctx, realm); if (retval) { com_err("krb5_set_default_realm", retval, 0); return; } printf("krb5_set_default_realm(%s)\n", realm); } static void test_get_default_ccname(krb5_context ctx) { const char *ccname; ccname = krb5_cc_default_name(ctx); if (ccname) printf("krb5_cc_default_name() returned '%s'\n", ccname); else printf("krb5_cc_default_name() returned NULL\n"); } static void test_set_default_ccname(krb5_context ctx, char *ccname) { krb5_error_code retval; retval = krb5_cc_set_default_name(ctx, ccname); if (retval) { com_err("krb5_set_default_ccname", retval, 0); return; } printf("krb5_set_default_ccname(%s)\n", ccname); } static void test_locate_kdc(krb5_context ctx, char *realm) { struct serverlist servers; size_t i; int get_primaries = FALSE; krb5_data rlm; krb5_error_code retval; rlm.data = realm; rlm.length = strlen(realm); retval = k5_locate_kdc(ctx, &rlm, &servers, get_primaries, FALSE); if (retval) { com_err("krb5_locate_kdc", retval, 0); return; } printf("krb_locate_kdc(%s) returned:", realm); for (i = 0; i < servers.nservers; i++) { struct server_entry *entry = &servers.servers[i]; if (entry->hostname) { printf(" host:%s/%d", entry->hostname, entry->port); continue; } switch (entry->family) { case AF_INET: { struct sockaddr_in *s_sin = (struct sockaddr_in *)&entry->addr; printf(" inet:%s/%d", inet_ntoa(s_sin->sin_addr), ntohs(s_sin->sin_port)); } break; case AF_INET6: { struct sockaddr_in6 *s_sin6 = (struct sockaddr_in6 *)&entry->addr; int j; printf(" inet6"); for (j = 0; j < 8; j++) printf(":%x", (s_sin6->sin6_addr.s6_addr[2*j] * 256 + s_sin6->sin6_addr.s6_addr[2*j+1])); printf("/%d", ntohs(s_sin6->sin6_port)); break; } default: printf(" unknown-af-%d", entry->family); break; } } k5_free_serverlist(&servers); printf("\n"); } static void test_get_host_realm(krb5_context ctx, char *host) { char **realms, **cpp; krb5_error_code retval; retval = krb5_get_host_realm(ctx, host, &realms); if (retval) { com_err("krb5_get_host_realm", retval, 0); return; } printf("krb_get_host_realm(%s) returned:", host); if (realms == 0) { printf(" (null)\n"); return; } if (realms[0] == 0) { printf(" (none)\n"); free(realms); return; } for (cpp = realms; *cpp; cpp++) { printf(" '%s'", *cpp); free(*cpp); } free(realms); printf("\n"); } static void test_get_realm_domain(krb5_context ctx, char *realm) { krb5_error_code retval; char *domain; retval = krb5_get_realm_domain(ctx, realm, &domain); if (retval) { com_err("krb5_get_realm_domain", retval, 0); return; } printf("krb5_get_realm_domain(%s) returned '%s'\n", realm, domain); free(domain); } static void usage(char *progname) { fprintf(stderr, "%s: Usage: %s [-dc] [-k realm] [-r host] [-C ccname] [-D realm]\n", progname, progname); exit(1); } int main(int argc, char **argv) { int c; krb5_context ctx; krb5_error_code retval; extern char *optarg; retval = krb5_init_context(&ctx); if (retval) { fprintf(stderr, "krb5_init_context returned error %u\n", retval); exit(1); } while ((c = getopt(argc, argv, "cdr:C:D:l:s:")) != -1) { switch (c) { case 'c': /* Get default ccname */ test_get_default_ccname(ctx); break; case 'd': /* Get default realm */ test_get_default_realm(ctx); break; case 'l': test_locate_kdc(ctx, optarg); break; case 'r': test_get_host_realm(ctx, optarg); break; case 's': test_set_default_realm(ctx, optarg); break; case 'C': test_set_default_ccname(ctx, optarg); break; case 'D': test_get_realm_domain(ctx, optarg); break; default: usage(argv[0]); } } krb5_free_context(ctx); exit(0); } krb5-1.22.1/src/lib/krb5/os/ktdefname.c0000664000175000017500000000670215051422640017271 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/os/ktdefname.c - Return default keytab name */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #define NEED_WINDOWS #include "k5-int.h" #include "os-proto.h" /* this is a an exceedinly gross thing. */ char *krb5_overridekeyname = NULL; static krb5_error_code kt_default_name(krb5_context context, char **name_out) { krb5_error_code ret; char *str; if (krb5_overridekeyname != NULL) { *name_out = strdup(krb5_overridekeyname); return (*name_out == NULL) ? ENOMEM : 0; } else if (context->profile_secure == FALSE && (str = secure_getenv("KRB5_KTNAME")) != NULL) { *name_out = strdup(str); return (*name_out == NULL) ? ENOMEM : 0; } else if (profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_DEFAULT_KEYTAB_NAME, NULL, NULL, &str) == 0 && str != NULL) { ret = k5_expand_path_tokens(context, str, name_out); profile_release_string(str); return ret; } else { return k5_expand_path_tokens(context, DEFKTNAME, name_out); } } krb5_error_code k5_kt_client_default_name(krb5_context context, char **name_out) { krb5_error_code ret; char *str; if (context->profile_secure == FALSE && (str = secure_getenv("KRB5_CLIENT_KTNAME")) != NULL) { *name_out = strdup(str); return (*name_out == NULL) ? ENOMEM : 0; } else if (profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_DEFAULT_CLIENT_KEYTAB_NAME, NULL, NULL, &str) == 0 && str != NULL) { ret = k5_expand_path_tokens(context, str, name_out); profile_release_string(str); return ret; } else { return k5_expand_path_tokens(context, DEFCKTNAME, name_out); } } krb5_error_code KRB5_CALLCONV krb5_kt_default_name(krb5_context context, char *name, int name_size) { krb5_error_code ret; unsigned int namesize = (name_size < 0 ? 0 : name_size); char *ktname; ret = kt_default_name(context, &ktname); if (ret) return ret; if (strlcpy(name, ktname, namesize) >= namesize) ret = KRB5_CONFIG_NOTENUFSPACE; free(ktname); return ret; } krb5-1.22.1/src/lib/krb5/deps0000664000175000017500000000165015051422640015421 0ustar ghudsonghudson# # Generated makefile dependencies follow. # krb5_libinit.so krb5_libinit.po $(OUTPRE)krb5_libinit.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/ccache/cc-int.h $(srcdir)/keytab/kt-int.h \ $(srcdir)/os/os-proto.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ krb5_libinit.c krb5_libinit.h krb5-1.22.1/src/lib/krb5/keytab/0000775000175000017500000000000015051422640016020 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/keytab/Makefile.in0000664000175000017500000000246015051422640020067 0ustar ghudsonghudsonmydir=lib$(S)krb5$(S)keytab BUILDTOP=$(REL)..$(S)..$(S).. ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=keytab ##DOS##OBJFILE=..\$(OUTPRE)$(PREFIXDIR).lst STLIBOBJS= \ ktadd.o \ ktbase.o \ ktdefault.o \ ktfr_entry.o \ ktremove.o \ ktfns.o \ kt_file.o \ kt_memory.o \ read_servi.o OBJS= \ $(OUTPRE)ktadd.$(OBJEXT) \ $(OUTPRE)ktbase.$(OBJEXT) \ $(OUTPRE)ktdefault.$(OBJEXT) \ $(OUTPRE)ktfr_entry.$(OBJEXT) \ $(OUTPRE)ktremove.$(OBJEXT) \ $(OUTPRE)ktfns.$(OBJEXT) \ $(OUTPRE)kt_file.$(OBJEXT) \ $(OUTPRE)kt_memory.$(OBJEXT) \ $(OUTPRE)read_servi.$(OBJEXT) SRCS= \ $(srcdir)/ktadd.c \ $(srcdir)/ktbase.c \ $(srcdir)/ktdefault.c \ $(srcdir)/ktfr_entry.c \ $(srcdir)/ktremove.c \ $(srcdir)/ktfns.c \ $(srcdir)/kt_file.c \ $(srcdir)/kt_memory.c \ $(srcdir)/read_servi.c EXTRADEPSRCS= \ $(srcdir)/t_keytab.c all-windows: $(OBJFILE) ##DOS$(OBJFILE): $(OBJS) ##DOS $(RM) $(OBJFILE) ##WIN32## $(LIBECHO) -p $(PREFIXDIR)\ $(OUTPRE)*.obj > $(OBJFILE) all-unix: all-libobjs clean-unix:: clean-libobjs check-unix: t_keytab $(RUN_TEST) ./t_keytab T_KEYTAB_OBJS = t_keytab.o t_keytab: $(T_KEYTAB_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ $(T_KEYTAB_OBJS) $(KRB5_BASE_LIBS) clean-unix:: $(RM) t_keytab t_keytab.o clean-windows:: @echo Making clean in krb5\keytab $(RM) $(OBJFILE) @libobj_frag@ krb5-1.22.1/src/lib/krb5/keytab/kt_file.c0000664000175000017500000012233715051422640017611 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/kt_file.c */ /* * Copyright 1990,1991,1995,2007,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (c) Hewlett-Packard Company 1991 * Released to the Massachusetts Institute of Technology for inclusion * in the Kerberos source code distribution. * * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef LEAN_CLIENT #include "k5-int.h" #include "../os/os-proto.h" #include /* * Information needed by internal routines of the file-based ticket * cache implementation. */ /* * Constants */ #define KRB5_KT_VNO_1 0x0501 /* krb v5, keytab version 1 (DCE compat) */ #define KRB5_KT_VNO 0x0502 /* krb v5, keytab version 2 (standard) */ #define KRB5_KT_DEFAULT_VNO KRB5_KT_VNO /* * Types */ typedef struct _krb5_ktfile_data { char *name; /* Name of the file */ FILE *openf; /* open file, if any. */ char iobuf[BUFSIZ]; /* so we can zap it later */ int version; /* Version number of keytab */ unsigned int iter_count; /* Number of active iterators */ long start_offset; /* Starting offset after version */ k5_mutex_t lock; /* Protect openf, version */ } krb5_ktfile_data; /* * Some limitations: * * If the file OPENF is left open between calls, we have an iterator * active, and OPENF is opened in read-only mode. So, no changes * can be made via that handle. * * An advisory file lock is used while the file is open. Thus, * multiple handles on the same underlying file cannot be used without * disrupting the locking in effect. * * The start_offset field is only valid if the file is open. It will * almost certainly always be the same constant. It's used so that * if an iterator is active, and we start another one, we don't have * to seek back to the start and re-read the version number to set * the position for the iterator. */ /* * Macros */ #define KTPRIVATE(id) ((krb5_ktfile_data *)(id)->data) #define KTFILENAME(id) (((krb5_ktfile_data *)(id)->data)->name) #define KTFILEP(id) (((krb5_ktfile_data *)(id)->data)->openf) #define KTFILEBUFP(id) (((krb5_ktfile_data *)(id)->data)->iobuf) #define KTVERSION(id) (((krb5_ktfile_data *)(id)->data)->version) #define KTITERS(id) (((krb5_ktfile_data *)(id)->data)->iter_count) #define KTSTARTOFF(id) (((krb5_ktfile_data *)(id)->data)->start_offset) #define KTLOCK(id) k5_mutex_lock(&((krb5_ktfile_data *)(id)->data)->lock) #define KTUNLOCK(id) k5_mutex_unlock(&((krb5_ktfile_data *)(id)->data)->lock) #define KTCHECKLOCK(id) k5_mutex_assert_locked(&((krb5_ktfile_data *)(id)->data)->lock) extern const struct _krb5_kt_ops krb5_ktf_ops; extern const struct _krb5_kt_ops krb5_ktf_writable_ops; static krb5_error_code KRB5_CALLCONV krb5_ktfile_resolve(krb5_context, const char *, krb5_keytab *); static krb5_error_code KRB5_CALLCONV krb5_ktfile_get_name(krb5_context, krb5_keytab, char *, unsigned int); static krb5_error_code KRB5_CALLCONV krb5_ktfile_close(krb5_context, krb5_keytab); static krb5_error_code KRB5_CALLCONV krb5_ktfile_get_entry(krb5_context, krb5_keytab, krb5_const_principal, krb5_kvno, krb5_enctype, krb5_keytab_entry *); static krb5_error_code KRB5_CALLCONV krb5_ktfile_start_seq_get(krb5_context, krb5_keytab, krb5_kt_cursor *); static krb5_error_code KRB5_CALLCONV krb5_ktfile_get_next(krb5_context, krb5_keytab, krb5_keytab_entry *, krb5_kt_cursor *); static krb5_error_code KRB5_CALLCONV krb5_ktfile_end_get(krb5_context, krb5_keytab, krb5_kt_cursor *); /* routines to be included on extended version (write routines) */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_add(krb5_context, krb5_keytab, krb5_keytab_entry *); static krb5_error_code KRB5_CALLCONV krb5_ktfile_remove(krb5_context, krb5_keytab, krb5_keytab_entry *); static krb5_error_code krb5_ktfileint_openr(krb5_context, krb5_keytab); static krb5_error_code krb5_ktfileint_openw(krb5_context, krb5_keytab); static krb5_error_code krb5_ktfileint_close(krb5_context, krb5_keytab); static krb5_error_code krb5_ktfileint_read_entry(krb5_context, krb5_keytab, krb5_keytab_entry *); static krb5_error_code krb5_ktfileint_write_entry(krb5_context, krb5_keytab, krb5_keytab_entry *); static krb5_error_code krb5_ktfileint_delete_entry(krb5_context, krb5_keytab, krb5_int32); static krb5_error_code krb5_ktfileint_internal_read_entry(krb5_context, krb5_keytab, krb5_keytab_entry *, krb5_int32 *); static krb5_error_code krb5_ktfileint_size_entry(krb5_context, krb5_keytab_entry *, krb5_int32 *); static krb5_error_code krb5_ktfileint_find_slot(krb5_context, krb5_keytab, krb5_int32 *, krb5_int32 *); /* * This is an implementation specific resolver. It returns a keytab id * initialized with file keytab routines. */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_resolve(krb5_context context, const char *name, krb5_keytab *id_out) { krb5_ktfile_data *data = NULL; krb5_error_code err = ENOMEM; krb5_keytab id; *id_out = NULL; id = calloc(1, sizeof(*id)); if (id == NULL) return ENOMEM; id->ops = &krb5_ktf_ops; data = calloc(1, sizeof(krb5_ktfile_data)); if (data == NULL) goto cleanup; data->name = strdup(name); if (data->name == NULL) goto cleanup; err = k5_mutex_init(&data->lock); if (err) goto cleanup; data->openf = 0; data->version = 0; data->iter_count = 0; id->data = (krb5_pointer) data; id->magic = KV5M_KEYTAB; *id_out = id; return 0; cleanup: if (data) free(data->name); free(data); free(id); return err; } /* * "Close" a file-based keytab and invalidate the id. This means * free memory hidden in the structures. */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_close(krb5_context context, krb5_keytab id) /* * This routine is responsible for freeing all memory allocated * for this keytab. There are no system resources that need * to be freed nor are there any open files. * * This routine should undo anything done by krb5_ktfile_resolve(). */ { free(KTFILENAME(id)); zap(KTFILEBUFP(id), BUFSIZ); k5_mutex_destroy(&((krb5_ktfile_data *)id->data)->lock); free(id->data); id->ops = 0; free(id); return (0); } /* Return true if k1 is more recent than k2, applying wraparound heuristics. */ static krb5_boolean more_recent(const krb5_keytab_entry *k1, const krb5_keytab_entry *k2) { /* * If a small kvno was written at the same time or later than a large kvno, * the kvno probably wrapped at some boundary, so consider the small kvno * more recent. Wraparound can happen due to pre-1.14 keytab file format * limitations (8-bit kvno storage), pre-1.14 kadmin protocol limitations * (8-bit kvno marshalling), or KDB limitations (16-bit kvno storage). */ if (!ts_after(k2->timestamp, k1->timestamp) && k1->vno < 128 && k2->vno > 240) return TRUE; if (!ts_after(k1->timestamp, k2->timestamp) && k1->vno > 240 && k2->vno < 128) return FALSE; /* Otherwise do a simple version comparison. */ return k1->vno > k2->vno; } /* * This is the get_entry routine for the file based keytab implementation. * It opens the keytab file, and either retrieves the entry or returns * an error. */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_get_entry(krb5_context context, krb5_keytab id, krb5_const_principal principal, krb5_kvno kvno, krb5_enctype enctype, krb5_keytab_entry *entry) { krb5_keytab_entry cur_entry, new_entry; krb5_error_code kerror = 0; int found_wrong_kvno = 0; int was_open; char *princname; KTLOCK(id); if (KTFILEP(id) != NULL) { was_open = 1; if (fseek(KTFILEP(id), KTSTARTOFF(id), SEEK_SET) == -1) { KTUNLOCK(id); return errno; } } else { was_open = 0; /* Open the keyfile for reading */ if ((kerror = krb5_ktfileint_openr(context, id))) { KTUNLOCK(id); return(kerror); } } /* * For efficiency and simplicity, we'll use a while true that * is exited with a break statement. */ cur_entry.principal = 0; cur_entry.vno = 0; cur_entry.key.contents = 0; while (TRUE) { if ((kerror = krb5_ktfileint_read_entry(context, id, &new_entry))) break; /* by the time this loop exits, it must either free cur_entry, and copy new_entry there, or free new_entry. Otherwise, it leaks. */ /* if the principal isn't the one requested, free new_entry and continue to the next. */ if (!krb5_principal_compare(context, principal, new_entry.principal)) { krb5_kt_free_entry(context, &new_entry); continue; } /* If the enctype is not ignored and doesn't match, free new_entry and continue to the next. */ if (enctype != IGNORE_ENCTYPE && enctype != new_entry.key.enctype) { krb5_kt_free_entry(context, &new_entry); continue; } if (kvno == IGNORE_VNO || new_entry.vno == IGNORE_VNO) { /* If this entry is more recent (or the first match), free the * current and keep the new. Otherwise, free the new. */ if (cur_entry.principal == NULL || more_recent(&new_entry, &cur_entry)) { krb5_kt_free_entry(context, &cur_entry); cur_entry = new_entry; } else { krb5_kt_free_entry(context, &new_entry); } } else { /* * If this kvno matches exactly, free the current, keep the new, * and break out. If it matches the low 8 bits of the desired * kvno, remember the first match (because the recorded kvno may * have been truncated due to pre-1.14 keytab format or kadmin * protocol limitations) but keep looking for an exact match. * Otherwise, remember that we were here so we can return the right * error, and free the new. */ if (new_entry.vno == kvno) { krb5_kt_free_entry(context, &cur_entry); cur_entry = new_entry; if (new_entry.vno == kvno) break; } else if (new_entry.vno == (kvno & 0xff) && cur_entry.principal == NULL) { cur_entry = new_entry; } else { found_wrong_kvno++; krb5_kt_free_entry(context, &new_entry); } } } if (kerror == KRB5_KT_END) { if (cur_entry.principal) kerror = 0; else if (found_wrong_kvno) kerror = KRB5_KT_KVNONOTFOUND; else { kerror = KRB5_KT_NOTFOUND; if (krb5_unparse_name(context, principal, &princname) == 0) { k5_setmsg(context, kerror, _("No key table entry found for %s"), princname); free(princname); } } } if (kerror) { if (was_open == 0) (void) krb5_ktfileint_close(context, id); KTUNLOCK(id); krb5_kt_free_entry(context, &cur_entry); return kerror; } if (was_open == 0 && (kerror = krb5_ktfileint_close(context, id)) != 0) { KTUNLOCK(id); krb5_kt_free_entry(context, &cur_entry); return kerror; } KTUNLOCK(id); *entry = cur_entry; return 0; } /* * Get the name of the file containing a file-based keytab. */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_get_name(krb5_context context, krb5_keytab id, char *name, unsigned int len) /* * This routine returns the name of the name of the file associated with * this file-based keytab. name is zeroed and the filename is truncated * to fit in name if necessary. The name is prefixed with PREFIX:, so that * trt will happen if the name is passed back to resolve. */ { int result; memset(name, 0, len); result = snprintf(name, len, "%s:%s", id->ops->prefix, KTFILENAME(id)); if (SNPRINTF_OVERFLOW(result, len)) return(KRB5_KT_NAME_TOOLONG); return(0); } /* * krb5_ktfile_start_seq_get() */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_start_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursorp) { krb5_error_code retval; long *fileoff; KTLOCK(id); if (KTITERS(id) == 0) { if ((retval = krb5_ktfileint_openr(context, id))) { KTUNLOCK(id); return retval; } } if (!(fileoff = (long *)malloc(sizeof(*fileoff)))) { if (KTITERS(id) == 0) krb5_ktfileint_close(context, id); KTUNLOCK(id); return ENOMEM; } *fileoff = KTSTARTOFF(id); KTITERS(id)++; if (KTITERS(id) == 0) { /* Wrapped?! */ KTITERS(id)--; KTUNLOCK(id); free(fileoff); k5_setmsg(context, KRB5_KT_IOERR, "Too many keytab iterators active"); return KRB5_KT_IOERR; /* XXX */ } *cursorp = (krb5_kt_cursor)fileoff; KTUNLOCK(id); return 0; } /* * krb5_ktfile_get_next() */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_get_next(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry, krb5_kt_cursor *cursor) { long *fileoff = (long *)*cursor; krb5_keytab_entry cur_entry; krb5_error_code kerror; KTLOCK(id); if (KTFILEP(id) == NULL) { KTUNLOCK(id); return KRB5_KT_IOERR; } if (fseek(KTFILEP(id), *fileoff, 0) == -1) { KTUNLOCK(id); return KRB5_KT_END; } if ((kerror = krb5_ktfileint_read_entry(context, id, &cur_entry))) { KTUNLOCK(id); return kerror; } *fileoff = ftell(KTFILEP(id)); *entry = cur_entry; KTUNLOCK(id); return 0; } /* * krb5_ktfile_end_get() */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_end_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursor) { krb5_error_code kerror; free(*cursor); KTLOCK(id); KTITERS(id)--; if (KTFILEP(id) != NULL && KTITERS(id) == 0) kerror = krb5_ktfileint_close(context, id); else kerror = 0; KTUNLOCK(id); return kerror; } /* * krb5_ktfile_add() */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_add(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) { krb5_error_code retval; KTLOCK(id); if (KTFILEP(id)) { /* Iterator(s) active -- no changes. */ KTUNLOCK(id); k5_setmsg(context, KRB5_KT_IOERR, _("Cannot change keytab with keytab iterators active")); return KRB5_KT_IOERR; /* XXX */ } if ((retval = krb5_ktfileint_openw(context, id))) { KTUNLOCK(id); return retval; } if (fseek(KTFILEP(id), 0, 2) == -1) { KTUNLOCK(id); return KRB5_KT_END; } retval = krb5_ktfileint_write_entry(context, id, entry); krb5_ktfileint_close(context, id); KTUNLOCK(id); return retval; } /* * krb5_ktfile_remove() */ static krb5_error_code KRB5_CALLCONV krb5_ktfile_remove(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) { krb5_keytab_entry cur_entry; krb5_error_code kerror; krb5_int32 delete_point; KTLOCK(id); if (KTFILEP(id)) { /* Iterator(s) active -- no changes. */ KTUNLOCK(id); k5_setmsg(context, KRB5_KT_IOERR, _("Cannot change keytab with keytab iterators active")); return KRB5_KT_IOERR; /* XXX */ } if ((kerror = krb5_ktfileint_openw(context, id))) { KTUNLOCK(id); return kerror; } /* * For efficiency and simplicity, we'll use a while true that * is exited with a break statement. */ while (TRUE) { if ((kerror = krb5_ktfileint_internal_read_entry(context, id, &cur_entry, &delete_point))) break; if ((entry->vno == cur_entry.vno) && (entry->key.enctype == cur_entry.key.enctype) && krb5_principal_compare(context, entry->principal, cur_entry.principal)) { /* found a match */ krb5_kt_free_entry(context, &cur_entry); break; } krb5_kt_free_entry(context, &cur_entry); } if (kerror == KRB5_KT_END) kerror = KRB5_KT_NOTFOUND; if (kerror) { (void) krb5_ktfileint_close(context, id); KTUNLOCK(id); return kerror; } kerror = krb5_ktfileint_delete_entry(context, id, delete_point); if (kerror) { (void) krb5_ktfileint_close(context, id); } else { kerror = krb5_ktfileint_close(context, id); } KTUNLOCK(id); return kerror; } /* * krb5_ktf_ops */ const struct _krb5_kt_ops krb5_ktf_ops = { 0, "FILE", /* Prefix -- this string should not appear anywhere else! */ krb5_ktfile_resolve, krb5_ktfile_get_name, krb5_ktfile_close, krb5_ktfile_get_entry, krb5_ktfile_start_seq_get, krb5_ktfile_get_next, krb5_ktfile_end_get, krb5_ktfile_add, krb5_ktfile_remove }; /* * krb5_ktf_writable_ops -- this is the same as krb5_ktf_ops except for the * prefix. WRFILE should no longer be needed, but is effectively aliased to * FILE for compatibility. */ const struct _krb5_kt_ops krb5_ktf_writable_ops = { 0, "WRFILE", /* Prefix -- this string should not appear anywhere else! */ krb5_ktfile_resolve, krb5_ktfile_get_name, krb5_ktfile_close, krb5_ktfile_get_entry, krb5_ktfile_start_seq_get, krb5_ktfile_get_next, krb5_ktfile_end_get, krb5_ktfile_add, krb5_ktfile_remove }; /* * krb5_kt_dfl_ops */ const krb5_kt_ops krb5_kt_dfl_ops = { 0, "FILE", /* Prefix -- this string should not appear anywhere else! */ krb5_ktfile_resolve, krb5_ktfile_get_name, krb5_ktfile_close, krb5_ktfile_get_entry, krb5_ktfile_start_seq_get, krb5_ktfile_get_next, krb5_ktfile_end_get, 0, 0 }; /* Formerly lib/krb5/keytab/file/ktf_util.c */ /* * This function contains utilities for the file based implementation of * the keytab. There are no public functions in this file. * * This file is the only one that has knowledge of the format of a * keytab file. * * The format is as follows: * * * * principal timestamp vno key * * principal timestamp vno key * .... * * A length field (sizeof(krb5_int32)) exists between entries. When this * length is positive it indicates an active entry, when negative a hole. * The length indicates the size of the block in the file (this may be * larger than the size of the next record, since we are using a first * fit algorithm for re-using holes and the first fit may be larger than * the entry we are writing). Another (compatible) implementation could * break up holes when allocating them to smaller entries to minimize * wasted space. (Such an implementation should also coalesce adjacent * holes to reduce fragmentation). This implementation does neither. * * There are no separators between fields of an entry. * A principal is a length-encoded array of length-encoded strings. The * length is a krb5_int16 in each case. The specific format, then, is * multiple entries concatenated with no separators. An entry has this * exact format: * * sizeof(krb5_int16) bytes for number of components in the principal; * then, each component listed in ordser. * For each component, sizeof(krb5_int16) bytes for the number of bytes * in the component, followed by the component. * sizeof(krb5_int32) for the principal type (for KEYTAB V2 and higher) * sizeof(krb5_int32) bytes for the timestamp * sizeof(krb5_octet) bytes for the key version number * sizeof(krb5_int16) bytes for the enctype * sizeof(krb5_int16) bytes for the key length, followed by the key */ #ifndef SEEK_SET #define SEEK_SET 0 #define SEEK_CUR 1 #endif typedef krb5_int16 krb5_kt_vno; #define krb5_kt_default_vno ((krb5_kt_vno)KRB5_KT_DEFAULT_VNO) static krb5_error_code krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode) { krb5_error_code kerror; krb5_kt_vno kt_vno; int writevno = 0; KTCHECKLOCK(id); errno = 0; KTFILEP(id) = fopen(KTFILENAME(id), (mode == KRB5_LOCKMODE_EXCLUSIVE) ? "rb+" : "rb"); if (!KTFILEP(id)) { if ((mode == KRB5_LOCKMODE_EXCLUSIVE) && (errno == ENOENT)) { /* try making it first time around */ k5_create_secure_file(context, KTFILENAME(id)); errno = 0; KTFILEP(id) = fopen(KTFILENAME(id), "rb+"); if (!KTFILEP(id)) goto report_errno; writevno = 1; } else { report_errno: switch (errno) { case 0: /* XXX */ return EMFILE; case ENOENT: k5_setmsg(context, ENOENT, _("Key table file '%s' not found"), KTFILENAME(id)); return ENOENT; default: return errno; } } } set_cloexec_file(KTFILEP(id)); if ((kerror = krb5_lock_file(context, fileno(KTFILEP(id)), mode))) { (void) fclose(KTFILEP(id)); KTFILEP(id) = 0; return kerror; } /* assume ANSI or BSD-style stdio */ setbuf(KTFILEP(id), KTFILEBUFP(id)); /* get the vno and verify it */ if (writevno) { kt_vno = htons(krb5_kt_default_vno); KTVERSION(id) = krb5_kt_default_vno; if (!fwrite(&kt_vno, sizeof(kt_vno), 1, KTFILEP(id))) { kerror = errno; (void) krb5_unlock_file(context, fileno(KTFILEP(id))); (void) fclose(KTFILEP(id)); KTFILEP(id) = 0; return kerror; } } else { /* gotta verify it instead... */ if (!fread(&kt_vno, sizeof(kt_vno), 1, KTFILEP(id))) { if (feof(KTFILEP(id))) kerror = KRB5_KEYTAB_BADVNO; else kerror = errno; (void) krb5_unlock_file(context, fileno(KTFILEP(id))); (void) fclose(KTFILEP(id)); KTFILEP(id) = 0; return kerror; } kt_vno = KTVERSION(id) = ntohs(kt_vno); if ((kt_vno != KRB5_KT_VNO) && (kt_vno != KRB5_KT_VNO_1)) { (void) krb5_unlock_file(context, fileno(KTFILEP(id))); (void) fclose(KTFILEP(id)); KTFILEP(id) = 0; return KRB5_KEYTAB_BADVNO; } } KTSTARTOFF(id) = ftell(KTFILEP(id)); return 0; } static krb5_error_code krb5_ktfileint_openr(krb5_context context, krb5_keytab id) { return krb5_ktfileint_open(context, id, KRB5_LOCKMODE_SHARED); } static krb5_error_code krb5_ktfileint_openw(krb5_context context, krb5_keytab id) { return krb5_ktfileint_open(context, id, KRB5_LOCKMODE_EXCLUSIVE); } static krb5_error_code krb5_ktfileint_close(krb5_context context, krb5_keytab id) { krb5_error_code kerror; KTCHECKLOCK(id); if (!KTFILEP(id)) return 0; kerror = krb5_unlock_file(context, fileno(KTFILEP(id))); (void) fclose(KTFILEP(id)); KTFILEP(id) = 0; return kerror; } static krb5_error_code krb5_ktfileint_delete_entry(krb5_context context, krb5_keytab id, krb5_int32 delete_point) { krb5_int32 size; krb5_int32 len; char iobuf[BUFSIZ]; KTCHECKLOCK(id); if (fseek(KTFILEP(id), delete_point, SEEK_SET)) { return errno; } if (!fread(&size, sizeof(size), 1, KTFILEP(id))) { return KRB5_KT_END; } if (KTVERSION(id) != KRB5_KT_VNO_1) size = ntohl(size); if (size > 0) { krb5_int32 minus_size = -size; if (KTVERSION(id) != KRB5_KT_VNO_1) minus_size = htonl(minus_size); if (fseek(KTFILEP(id), delete_point, SEEK_SET)) { return errno; } if (!fwrite(&minus_size, sizeof(minus_size), 1, KTFILEP(id))) { return KRB5_KT_IOERR; } if (size < BUFSIZ) { len = size; } else { len = BUFSIZ; } memset(iobuf, 0, (size_t) len); while (size > 0) { if (!fwrite(iobuf, 1, (size_t) len, KTFILEP(id))) { return KRB5_KT_IOERR; } size -= len; if (size < len) { len = size; } } return k5_sync_disk_file(context, KTFILEP(id)); } return 0; } static krb5_error_code krb5_ktfileint_internal_read_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *ret_entry, krb5_int32 *delete_point) { krb5_octet vno; krb5_int16 count; unsigned int u_count, u_princ_size; krb5_int16 enctype; krb5_int16 princ_size; int i; krb5_int32 size; krb5_int32 start_pos, pos; krb5_error_code error; char *tmpdata; krb5_data *princ; uint32_t vno32; KTCHECKLOCK(id); memset(ret_entry, 0, sizeof(krb5_keytab_entry)); ret_entry->magic = KV5M_KEYTAB_ENTRY; /* fseek to synchronise buffered I/O on the key table. */ if (fseek(KTFILEP(id), 0L, SEEK_CUR) < 0) { return errno; } do { *delete_point = ftell(KTFILEP(id)); if (!fread(&size, sizeof(size), 1, KTFILEP(id))) { return KRB5_KT_END; } if (KTVERSION(id) != KRB5_KT_VNO_1) size = ntohl(size); if (size < 0) { if (size == INT32_MIN) /* INT32_MIN inverts to itself. */ return KRB5_KT_FORMAT; if (fseek(KTFILEP(id), -size, SEEK_CUR)) { return errno; } } } while (size < 0); if (size == 0) { return KRB5_KT_END; } start_pos = ftell(KTFILEP(id)); /* deal with guts of parsing... */ /* first, int16 with #princ components */ if (!fread(&count, sizeof(count), 1, KTFILEP(id))) return KRB5_KT_END; if (KTVERSION(id) == KRB5_KT_VNO_1) { count -= 1; /* V1 includes the realm in the count */ } else { count = ntohs(count); } if (!count || (count < 0)) return KRB5_KT_END; ret_entry->principal = (krb5_principal)malloc(sizeof(krb5_principal_data)); if (!ret_entry->principal) return ENOMEM; u_count = count; ret_entry->principal->magic = KV5M_PRINCIPAL; ret_entry->principal->length = u_count; ret_entry->principal->data = (krb5_data *) calloc(u_count, sizeof(krb5_data)); if (!ret_entry->principal->data) { free(ret_entry->principal); ret_entry->principal = 0; return ENOMEM; } /* Now, get the realm data */ if (!fread(&princ_size, sizeof(princ_size), 1, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } if (KTVERSION(id) != KRB5_KT_VNO_1) princ_size = ntohs(princ_size); if (!princ_size || (princ_size < 0)) { error = KRB5_KT_END; goto fail; } u_princ_size = princ_size; ret_entry->principal->realm.length = u_princ_size; tmpdata = malloc(u_princ_size+1); if (!tmpdata) { error = ENOMEM; goto fail; } if (fread(tmpdata, 1, u_princ_size, KTFILEP(id)) != (size_t) princ_size) { free(tmpdata); error = KRB5_KT_END; goto fail; } tmpdata[princ_size] = 0; /* Some things might be expecting null */ /* termination... ``Be conservative in */ /* what you send out'' */ ret_entry->principal->realm.data = tmpdata; for (i = 0; i < count; i++) { princ = &ret_entry->principal->data[i]; if (!fread(&princ_size, sizeof(princ_size), 1, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } if (KTVERSION(id) != KRB5_KT_VNO_1) princ_size = ntohs(princ_size); if (!princ_size || (princ_size < 0)) { error = KRB5_KT_END; goto fail; } u_princ_size = princ_size; princ->length = u_princ_size; princ->data = malloc(u_princ_size+1); if (!princ->data) { error = ENOMEM; goto fail; } if (!fread(princ->data, sizeof(char), u_princ_size, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } princ->data[princ_size] = 0; /* Null terminate */ } /* read in the principal type, if we can get it */ if (KTVERSION(id) != KRB5_KT_VNO_1) { if (!fread(&ret_entry->principal->type, sizeof(ret_entry->principal->type), 1, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } ret_entry->principal->type = ntohl(ret_entry->principal->type); } /* read in the timestamp */ if (!fread(&ret_entry->timestamp, sizeof(ret_entry->timestamp), 1, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } if (KTVERSION(id) != KRB5_KT_VNO_1) ret_entry->timestamp = ntohl(ret_entry->timestamp); /* read in the version number */ if (!fread(&vno, sizeof(vno), 1, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } ret_entry->vno = (krb5_kvno)vno; /* key type */ if (!fread(&enctype, sizeof(enctype), 1, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } if (KTVERSION(id) != KRB5_KT_VNO_1) enctype = ntohs(enctype); ret_entry->key.enctype = (krb5_enctype)enctype; /* key contents */ ret_entry->key.magic = KV5M_KEYBLOCK; if (!fread(&count, sizeof(count), 1, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } if (KTVERSION(id) != KRB5_KT_VNO_1) count = ntohs(count); if (!count || (count < 0)) { error = KRB5_KT_END; goto fail; } u_count = count; ret_entry->key.length = u_count; ret_entry->key.contents = (krb5_octet *)malloc(u_count); if (!ret_entry->key.contents) { error = ENOMEM; goto fail; } if (!fread(ret_entry->key.contents, sizeof(krb5_octet), count, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } /* Check for a 32-bit kvno extension if four or more bytes remain. */ pos = ftell(KTFILEP(id)); if (pos - start_pos + 4 <= size) { if (!fread(&vno32, sizeof(vno32), 1, KTFILEP(id))) { error = KRB5_KT_END; goto fail; } if (KTVERSION(id) != KRB5_KT_VNO_1) vno32 = ntohl(vno32); /* If the value is 0, the bytes are just zero-fill. */ if (vno32) ret_entry->vno = vno32; } /* * Reposition file pointer to the next inter-record length field. */ if (fseek(KTFILEP(id), start_pos + size, SEEK_SET) == -1) { error = errno; goto fail; } return 0; fail: for (i = 0; i < ret_entry->principal->length; i++) free(ret_entry->principal->data[i].data); free(ret_entry->principal->data); ret_entry->principal->data = 0; free(ret_entry->principal); ret_entry->principal = 0; return error; } static krb5_error_code krb5_ktfileint_read_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entryp) { krb5_int32 delete_point; return krb5_ktfileint_internal_read_entry(context, id, entryp, &delete_point); } static krb5_error_code krb5_ktfileint_write_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) { krb5_octet vno; krb5_data *princ; krb5_int16 count, size, enctype; krb5_error_code retval = 0; krb5_timestamp timestamp; krb5_int32 princ_type; krb5_int32 size_needed; krb5_int32 commit_point = -1; uint32_t vno32; int i; KTCHECKLOCK(id); retval = krb5_ktfileint_size_entry(context, entry, &size_needed); if (retval) return retval; retval = krb5_ktfileint_find_slot(context, id, &size_needed, &commit_point); if (retval) return retval; /* fseek to synchronise buffered I/O on the key table. */ /* XXX Without the weird setbuf crock, can we get rid of this now? */ if (fseek(KTFILEP(id), 0L, SEEK_CUR) < 0) { return errno; } if (KTVERSION(id) == KRB5_KT_VNO_1) { count = (krb5_int16)entry->principal->length + 1; } else { count = htons((u_short)entry->principal->length); } if (!fwrite(&count, sizeof(count), 1, KTFILEP(id))) { abend: return KRB5_KT_IOERR; } size = entry->principal->realm.length; if (KTVERSION(id) != KRB5_KT_VNO_1) size = htons(size); if (!fwrite(&size, sizeof(size), 1, KTFILEP(id))) { goto abend; } if (!fwrite(entry->principal->realm.data, sizeof(char), entry->principal->realm.length, KTFILEP(id))) { goto abend; } count = (krb5_int16)entry->principal->length; for (i = 0; i < count; i++) { princ = &entry->principal->data[i]; size = princ->length; if (KTVERSION(id) != KRB5_KT_VNO_1) size = htons(size); if (!fwrite(&size, sizeof(size), 1, KTFILEP(id))) { goto abend; } if (!fwrite(princ->data, sizeof(char), princ->length, KTFILEP(id))) { goto abend; } } /* * Write out the principal type */ if (KTVERSION(id) != KRB5_KT_VNO_1) { princ_type = htonl(entry->principal->type); if (!fwrite(&princ_type, sizeof(princ_type), 1, KTFILEP(id))) { goto abend; } } /* * Fill in the time of day the entry was written to the keytab. */ if (krb5_timeofday(context, &entry->timestamp)) { entry->timestamp = 0; } if (KTVERSION(id) == KRB5_KT_VNO_1) timestamp = entry->timestamp; else timestamp = htonl(entry->timestamp); if (!fwrite(×tamp, sizeof(timestamp), 1, KTFILEP(id))) { goto abend; } /* key version number */ vno = (krb5_octet)entry->vno; if (!fwrite(&vno, sizeof(vno), 1, KTFILEP(id))) { goto abend; } /* key type */ if (KTVERSION(id) == KRB5_KT_VNO_1) enctype = entry->key.enctype; else enctype = htons(entry->key.enctype); if (!fwrite(&enctype, sizeof(enctype), 1, KTFILEP(id))) { goto abend; } /* key length */ if (KTVERSION(id) == KRB5_KT_VNO_1) size = entry->key.length; else size = htons(entry->key.length); if (!fwrite(&size, sizeof(size), 1, KTFILEP(id))) { goto abend; } if (!fwrite(entry->key.contents, sizeof(krb5_octet), entry->key.length, KTFILEP(id))) { goto abend; } /* 32-bit key version number */ vno32 = entry->vno; if (KTVERSION(id) != KRB5_KT_VNO_1) vno32 = htonl(vno32); if (!fwrite(&vno32, sizeof(vno32), 1, KTFILEP(id))) goto abend; if (fflush(KTFILEP(id))) goto abend; retval = k5_sync_disk_file(context, KTFILEP(id)); if (retval) { return retval; } if (fseek(KTFILEP(id), commit_point, SEEK_SET)) { return errno; } if (KTVERSION(id) != KRB5_KT_VNO_1) size_needed = htonl(size_needed); if (!fwrite(&size_needed, sizeof(size_needed), 1, KTFILEP(id))) { goto abend; } if (fflush(KTFILEP(id))) goto abend; retval = k5_sync_disk_file(context, KTFILEP(id)); return retval; } /* * Determine the size needed for a file entry for the given * keytab entry. */ static krb5_error_code krb5_ktfileint_size_entry(krb5_context context, krb5_keytab_entry *entry, krb5_int32 *size_needed) { krb5_int16 count; krb5_int32 total_size, i; krb5_error_code retval = 0; count = (krb5_int16)entry->principal->length; total_size = sizeof(count); total_size += entry->principal->realm.length + sizeof(krb5_int16); for (i = 0; i < count; i++) total_size += entry->principal->data[i].length + sizeof(krb5_int16); total_size += sizeof(entry->principal->type); total_size += sizeof(entry->timestamp); total_size += sizeof(krb5_octet); total_size += sizeof(krb5_int16); total_size += sizeof(krb5_int16) + entry->key.length; total_size += sizeof(uint32_t); *size_needed = total_size; return retval; } /* * Find and reserve a slot in the file for an entry of the needed size. * The commit point will be set to the position in the file where the * the length (sizeof(krb5_int32) bytes) of this node should be written * when committing the write. The file position left as a result of this * call is the position where the actual data should be written. * * The size_needed argument may be adjusted if we find a hole that is * larger than the size needed. (Recall that size_needed will be used * to commit the write, but that this field must indicate the size of the * block in the file rather than the size of the actual entry) */ static krb5_error_code krb5_ktfileint_find_slot(krb5_context context, krb5_keytab id, krb5_int32 *size_needed, krb5_int32 *commit_point_ptr) { FILE *fp; krb5_int32 size, zero_point, commit_point; krb5_kt_vno kt_vno; KTCHECKLOCK(id); fp = KTFILEP(id); /* Skip over file version number. */ if (fseek(fp, 0, SEEK_SET)) return errno; if (!fread(&kt_vno, sizeof(kt_vno), 1, fp)) return errno; for (;;) { commit_point = ftell(fp); if (commit_point == -1) return errno; if (!fread(&size, sizeof(size), 1, fp)) { /* Hit the end of file, reserve this slot. */ /* Necessary to avoid a later fseek failing on Solaris 10. */ if (fseek(fp, 0, SEEK_CUR)) return errno; /* htonl(0) is 0, so no need to worry about byte order */ size = 0; if (!fwrite(&size, sizeof(size), 1, fp)) return errno; break; } if (KTVERSION(id) != KRB5_KT_VNO_1) size = ntohl(size); if (size > 0) { /* Non-empty record; seek past it. */ if (fseek(fp, size, SEEK_CUR)) return errno; } else if (size < 0) { /* Empty record; use if it's big enough, seek past otherwise. */ if (size == INT32_MIN) /* INT32_MIN inverts to itself. */ return KRB5_KT_FORMAT; size = -size; if (size >= *size_needed) { *size_needed = size; break; } else { if (fseek(fp, size, SEEK_CUR)) return errno; } } else { /* Empty record at end of file; use it. */ /* Ensure the new record will be followed by another 0. */ zero_point = ftell(fp); if (zero_point == -1) return errno; if (fseek(fp, *size_needed, SEEK_CUR)) return errno; /* htonl(0) is 0, so no need to worry about byte order */ if (!fwrite(&size, sizeof(size), 1, fp)) return errno; if (fseek(fp, zero_point, SEEK_SET)) return errno; break; } } *commit_point_ptr = commit_point; return 0; } #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/keytab/ktdefault.c0000664000175000017500000000404315051422640020150 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/ktdefault.c */ /* * Copyright 1990,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * Get a default keytab. */ #include "k5-int.h" #include "../os/os-proto.h" #include #ifndef LEAN_CLIENT krb5_error_code KRB5_CALLCONV krb5_kt_default(krb5_context context, krb5_keytab *id) { char defname[BUFSIZ]; krb5_error_code retval; if ((retval = krb5_kt_default_name(context, defname, sizeof(defname)))) return retval; return krb5_kt_resolve(context, defname, id); } krb5_error_code KRB5_CALLCONV krb5_kt_client_default(krb5_context context, krb5_keytab *keytab_out) { krb5_error_code ret; char *name; ret = k5_kt_client_default_name(context, &name); if (ret) return ret; ret = krb5_kt_resolve(context, name, keytab_out); free(name); return ret; } #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/keytab/read_servi.c0000664000175000017500000000623515051422640020315 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/read_servi.c */ /* * Copyright 1990,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This routine is designed to be passed to krb5_rd_req. * It is a convenience function that reads a key out of a keytab. * It handles all of the opening and closing of the keytab * internally. */ #ifndef LEAN_CLIENT #include "k5-int.h" #define KSUCCESS 0 /* * effects: If keyprocarg is not NULL, it is taken to be the name of a * keytab. Otherwise, the default keytab will be used. This * routine opens the keytab and finds the principal associated with * principal, vno, and enctype and returns the resulting key in *key * or returning an error code if it is not found. * returns: Either KSUCCESS or error code. * errors: error code if not found or keyprocarg is invalid. */ krb5_error_code KRB5_CALLCONV krb5_kt_read_service_key(krb5_context context, krb5_pointer keyprocarg, krb5_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keyblock **key) { krb5_error_code kerror = KSUCCESS; char keytabname[MAX_KEYTAB_NAME_LEN + 1]; /* + 1 for NULL termination */ krb5_keytab id; krb5_keytab_entry entry; /* * Get the name of the file that we should use. */ if (!keyprocarg) { if ((kerror = krb5_kt_default_name(context, (char *)keytabname, sizeof(keytabname) - 1))!= KSUCCESS) return (kerror); } else { memset(keytabname, 0, sizeof(keytabname)); (void) strncpy(keytabname, (char *)keyprocarg, sizeof(keytabname) - 1); } if ((kerror = krb5_kt_resolve(context, (char *)keytabname, &id))) return (kerror); kerror = krb5_kt_get_entry(context, id, principal, vno, enctype, &entry); krb5_kt_close(context, id); if (kerror) return(kerror); krb5_copy_keyblock(context, &entry.key, key); krb5_kt_free_entry(context, &entry); return (KSUCCESS); } #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/keytab/deps0000664000175000017500000001667315051422640016713 0ustar ghudsonghudson# # Generated makefile dependencies follow. # ktadd.so ktadd.po $(OUTPRE)ktadd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ktadd.c ktbase.so ktbase.po $(OUTPRE)ktbase.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kt-int.h ktbase.c ktdefault.so ktdefault.po $(OUTPRE)ktdefault.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../os/os-proto.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ktdefault.c ktfr_entry.so ktfr_entry.po $(OUTPRE)ktfr_entry.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ktfr_entry.c ktremove.so ktremove.po $(OUTPRE)ktremove.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ktremove.c ktfns.so ktfns.po $(OUTPRE)ktfns.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/int-proto.h \ $(srcdir)/../os/os-proto.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ktfns.c kt_file.so kt_file.po $(OUTPRE)kt_file.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../os/os-proto.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h kt_file.c kt_memory.so kt_memory.po $(OUTPRE)kt_memory.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ kt-int.h kt_memory.c read_servi.so read_servi.po $(OUTPRE)read_servi.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ read_servi.c t_keytab.so t_keytab.po $(OUTPRE)t_keytab.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ t_keytab.c krb5-1.22.1/src/lib/krb5/keytab/t_keytab.c0000664000175000017500000003460015051422640017771 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/t_keytab.c - Tests for keytab interface */ /* * Copyright (C) 2007 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "autoconf.h" #include #include #if HAVE_UNISTD_H #include #endif #include int debug=0; extern const krb5_kt_ops krb5_ktf_writable_ops; #define KRB5_OK 0 #define CHECK_ERR(kret,err,msg) \ if (kret != err) { \ com_err(msg, kret, ""); \ fflush(stderr); \ exit(1); \ } else if(debug) printf("%s went ok\n", msg); #define CHECK(kret,msg) CHECK_ERR(kret, 0, msg) #define CHECK_STR(str,msg) \ if (str == 0) { \ com_err(msg, kret, ""); \ exit(1); \ } else if(debug) printf("%s went ok\n", msg); static void test_misc(krb5_context context) { /* Tests for certain error returns */ krb5_error_code kret; krb5_keytab ktid; char defname[BUFSIZ]; char *name; fprintf(stderr, "Testing miscellaneous error conditions\n"); kret = krb5_kt_resolve(context, "unknown_method_ep:/tmp/name", &ktid); CHECK_ERR(kret, KRB5_KT_UNKNOWN_TYPE, "resolve unknown type"); /* Test length limits on krb5_kt_default_name */ kret = krb5_kt_default_name(context, defname, sizeof(defname)); CHECK(kret, "krb5_kt_default_name error"); /* Now allocate space - without the null... */ name = malloc(strlen(defname)); if(!name) { fprintf(stderr, "Out of memory in testing\n"); exit(1); } kret = krb5_kt_default_name(context, name, strlen(defname)); free(name); CHECK_ERR(kret, KRB5_CONFIG_NOTENUFSPACE, "krb5_kt_default_name limited"); } static void kt_test(krb5_context context, const char *name) { krb5_error_code kret; krb5_keytab kt; const char *type; char buf[BUFSIZ]; char *p; krb5_keytab_entry kent, kent2; krb5_principal princ; krb5_kt_cursor cursor, cursor2; int cnt; krb5_enctype e1 = ENCTYPE_AES128_CTS_HMAC_SHA256_128, e2 = ENCTYPE_AES256_CTS_HMAC_SHA384_192; kret = krb5_kt_resolve(context, name, &kt); CHECK(kret, "resolve"); type = krb5_kt_get_type(context, kt); CHECK_STR(type, "getting kt type"); printf(" Type is: %s\n", type); kret = krb5_kt_get_name(context, kt, buf, sizeof(buf)); CHECK(kret, "get_name"); printf(" Name is: %s\n", buf); /* Check that length checks fail */ /* The buffer is allocated too small - to allow for valgrind test of overflows */ p = malloc(strlen(buf)); kret = krb5_kt_get_name(context, kt, p, 1); CHECK_ERR(kret, KRB5_KT_NAME_TOOLONG, "get_name - size 1"); kret = krb5_kt_get_name(context, kt, p, strlen(buf)); CHECK_ERR(kret, KRB5_KT_NAME_TOOLONG, "get_name"); free(p); /* Try to lookup unknown principal - when keytab does not exist*/ kret = krb5_parse_name(context, "test/test2@TEST.MIT.EDU", &princ); CHECK(kret, "parsing principal"); /* This will return ENOENT for FILE because the file doesn't exist, * so accept that or KRB5_KT_NOTFOUND. */ kret = krb5_kt_get_entry(context, kt, princ, 0, 0, &kent); if (kret != ENOENT) { CHECK_ERR(kret, KRB5_KT_NOTFOUND, "Getting non-existent entry"); } kret = krb5_kt_have_content(context, kt); CHECK_ERR(kret, KRB5_KT_NOTFOUND, "Checking for keytab content (empty)"); /* =================== Add entries to keytab ================= */ /* * Add the following for this principal * enctype e1, kvno 1, key = "1" * enctype e2, kvno 1, key = "1" * enctype e1, kvno 2, key = "2" */ memset(&kent, 0, sizeof(kent)); kent.magic = KV5M_KEYTAB_ENTRY; kent.principal = princ; kent.timestamp = 327689; kent.vno = 1; kent.key.magic = KV5M_KEYBLOCK; kent.key.enctype = e1; kent.key.length = 1; kent.key.contents = (krb5_octet *) "1"; kret = krb5_kt_add_entry(context, kt, &kent); CHECK(kret, "Adding initial entry"); kent.key.enctype = e2; kret = krb5_kt_add_entry(context, kt, &kent); CHECK(kret, "Adding second entry"); kent.key.enctype = e1; kent.vno = 2; kent.key.contents = (krb5_octet *) "2"; kret = krb5_kt_add_entry(context, kt, &kent); CHECK(kret, "Adding third entry"); /* Free memory */ krb5_free_principal(context, princ); /* ============== Test iterating over contents of keytab ========= */ kret = krb5_kt_have_content(context, kt); CHECK(kret, "Checking for keytab content (full)"); kret = krb5_kt_start_seq_get(context, kt, &cursor); CHECK(kret, "Start sequence get"); memset(&kent, 0, sizeof(kent)); cnt = 0; while((kret = krb5_kt_next_entry(context, kt, &kent, &cursor)) == 0) { if(((kent.vno != 1) && (kent.vno != 2)) || ((kent.key.enctype != e1) && (kent.key.enctype != e2)) || (kent.key.length != 1) || (kent.key.contents[0] != kent.vno +'0')) { fprintf(stderr, "Error in read contents\n"); exit(1); } if((kent.magic != KV5M_KEYTAB_ENTRY) || (kent.key.magic != KV5M_KEYBLOCK)) { fprintf(stderr, "Magic number in sequence not proper\n"); exit(1); } cnt++; krb5_free_keytab_entry_contents(context, &kent); } CHECK_ERR(kret, KRB5_KT_END, "getting next entry"); if(cnt != 3) { fprintf(stderr, "Mismatch in number of entries in keytab"); } kret = krb5_kt_end_seq_get(context, kt, &cursor); CHECK(kret, "End sequence get"); /* ========================== get_entry tests ============== */ /* Try to lookup unknown principal - now that keytab exists*/ kret = krb5_parse_name(context, "test3/test2@TEST.MIT.EDU", &princ); CHECK(kret, "parsing principal"); kret = krb5_kt_get_entry(context, kt, princ, 0, 0, &kent); CHECK_ERR(kret, KRB5_KT_NOTFOUND, "Getting nonexistent entry"); krb5_free_principal(context, princ); /* Try to lookup known principal */ kret = krb5_parse_name(context, "test/test2@TEST.MIT.EDU", &princ); CHECK(kret, "parsing principal"); kret = krb5_kt_get_entry(context, kt, princ, 0, 0, &kent); CHECK(kret, "looking up principal"); /* Ensure a valid answer - we did not specify an enctype or kvno */ if (!krb5_principal_compare(context, princ, kent.principal) || ((kent.vno != 1) && (kent.vno != 2)) || ((kent.key.enctype != e1) && (kent.key.enctype != e2)) || (kent.key.length != 1) || (kent.key.contents[0] != kent.vno +'0')) { fprintf(stderr, "Retrieved principal does not check\n"); exit(1); } krb5_free_keytab_entry_contents(context, &kent); /* Try to lookup a specific enctype - but unspecified kvno - should give * max kvno */ kret = krb5_kt_get_entry(context, kt, princ, 0, e1, &kent); CHECK(kret, "looking up principal"); /* Ensure a valid answer - we did specified an enctype */ if (!krb5_principal_compare(context, princ, kent.principal) || (kent.vno != 2) || (kent.key.enctype != e1) || (kent.key.length != 1) || (kent.key.contents[0] != kent.vno +'0')) { fprintf(stderr, "Retrieved principal does not check\n"); exit(1); } krb5_free_keytab_entry_contents(context, &kent); /* Try to lookup unspecified enctype, but a specified kvno */ kret = krb5_kt_get_entry(context, kt, princ, 2, 0, &kent); CHECK(kret, "looking up principal"); /* Ensure a valid answer - we did not specify a kvno */ if (!krb5_principal_compare(context, princ, kent.principal) || (kent.vno != 2) || (kent.key.enctype != e1) || (kent.key.length != 1) || (kent.key.contents[0] != kent.vno +'0')) { fprintf(stderr, "Retrieved principal does not check\n"); exit(1); } krb5_free_keytab_entry_contents(context, &kent); /* Try to lookup specified enctype and kvno */ kret = krb5_kt_get_entry(context, kt, princ, 1, e1, &kent); CHECK(kret, "looking up principal"); if (!krb5_principal_compare(context, princ, kent.principal) || (kent.vno != 1) || (kent.key.enctype != e1) || (kent.key.length != 1) || (kent.key.contents[0] != kent.vno +'0')) { fprintf(stderr, "Retrieved principal does not check\n"); exit(1); } krb5_free_keytab_entry_contents(context, &kent); /* Try lookup with active iterators. */ kret = krb5_kt_start_seq_get(context, kt, &cursor); CHECK(kret, "Start sequence get(2)"); kret = krb5_kt_start_seq_get(context, kt, &cursor2); CHECK(kret, "Start sequence get(3)"); kret = krb5_kt_next_entry(context, kt, &kent, &cursor); CHECK(kret, "getting next entry(2)"); krb5_free_keytab_entry_contents(context, &kent); kret = krb5_kt_next_entry(context, kt, &kent, &cursor); CHECK(kret, "getting next entry(3)"); kret = krb5_kt_next_entry(context, kt, &kent2, &cursor2); CHECK(kret, "getting next entry(4)"); krb5_free_keytab_entry_contents(context, &kent2); kret = krb5_kt_get_entry(context, kt, kent.principal, 0, 0, &kent2); CHECK(kret, "looking up principal(2)"); krb5_free_keytab_entry_contents(context, &kent2); kret = krb5_kt_next_entry(context, kt, &kent2, &cursor2); CHECK(kret, "getting next entry(5)"); if (!krb5_principal_compare(context, kent.principal, kent2.principal)) { fprintf(stderr, "iterators not in sync\n"); exit(1); } krb5_free_keytab_entry_contents(context, &kent); krb5_free_keytab_entry_contents(context, &kent2); kret = krb5_kt_next_entry(context, kt, &kent, &cursor); CHECK(kret, "getting next entry(6)"); kret = krb5_kt_next_entry(context, kt, &kent2, &cursor2); CHECK(kret, "getting next entry(7)"); krb5_free_keytab_entry_contents(context, &kent); krb5_free_keytab_entry_contents(context, &kent2); kret = krb5_kt_end_seq_get(context, kt, &cursor); CHECK(kret, "ending sequence get(1)"); kret = krb5_kt_end_seq_get(context, kt, &cursor2); CHECK(kret, "ending sequence get(2)"); /* Try to lookup specified enctype and kvno - that does not exist*/ kret = krb5_kt_get_entry(context, kt, princ, 3, e1, &kent); CHECK_ERR(kret, KRB5_KT_KVNONOTFOUND, "looking up specific principal, kvno, enctype"); krb5_free_principal(context, princ); /* ========================= krb5_kt_remove_entry =========== */ /* Lookup the keytab entry w/ 2 kvno - and delete version 2 - ensure gone */ kret = krb5_parse_name(context, "test/test2@TEST.MIT.EDU", &princ); CHECK(kret, "parsing principal"); kret = krb5_kt_get_entry(context, kt, princ, 0, e1, &kent); CHECK(kret, "looking up principal"); /* Ensure a valid answer - we are looking for max(kvno) and enc=e1 */ if (!krb5_principal_compare(context, princ, kent.principal) || (kent.vno != 2) || (kent.key.enctype != e1) || (kent.key.length != 1) || (kent.key.contents[0] != kent.vno +'0')) { fprintf(stderr, "Retrieved principal does not check\n"); exit(1); } /* Delete it */ kret = krb5_kt_remove_entry(context, kt, &kent); CHECK(kret, "Removing entry"); krb5_free_keytab_entry_contents(context, &kent); /* And ensure gone */ kret = krb5_kt_get_entry(context, kt, princ, 0, e1, &kent); CHECK(kret, "looking up principal"); /* Ensure a valid answer - kvno should now be 1 - we deleted 2 */ if (!krb5_principal_compare(context, princ, kent.principal) || (kent.vno != 1) || (kent.key.enctype != e1) || (kent.key.length != 1) || (kent.key.contents[0] != kent.vno +'0')) { fprintf(stderr, "Delete principal check failed\n"); exit(1); } krb5_free_keytab_entry_contents(context, &kent); krb5_free_principal(context, princ); /* ======================= Finally close ======================= */ kret = krb5_kt_close(context, kt); CHECK(kret, "close"); } static void do_test(krb5_context context, const char *prefix, krb5_boolean delete) { char *name, *filename; if (asprintf(&filename, "/tmp/kttest.%ld", (long) getpid()) < 0) { perror("asprintf"); exit(1); } if (asprintf(&name, "%s%s", prefix, filename) < 0) { perror("asprintf"); exit(1); } printf("Starting test on %s\n", name); kt_test(context, name); printf("Test on %s passed\n", name); if(delete) unlink(filename); free(filename); free(name); } int main(void) { krb5_context context; krb5_error_code kret; if ((kret = krb5_init_context(&context))) { printf("Couldn't initialize krb5 library: %s\n", error_message(kret)); exit(1); } /* All keytab types are registered by default -- test for redundant error */ kret = krb5_kt_register(context, &krb5_ktf_writable_ops); CHECK_ERR(kret, KRB5_KT_TYPE_EXISTS, "register ktf_writable"); test_misc(context); do_test(context, "WRFILE:", FALSE); do_test(context, "MEMORY:", TRUE); krb5_free_context(context); return 0; } krb5-1.22.1/src/lib/krb5/keytab/kt-int.h0000664000175000017500000000325615051422640017405 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/kt-int.h */ /* * Copyright 2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * This file contains constant and function declarations used in the * file-based credential cache routines. */ #ifndef __KRB5_KEYTAB_INT_H__ #define __KRB5_KEYTAB_INT_H__ int krb5int_kt_initialize(void); void krb5int_kt_finalize(void); int krb5int_mkt_initialize(void); void krb5int_mkt_finalize(void); extern const krb5_kt_ops krb5_kt_dfl_ops; #endif /* __KRB5_KEYTAB_INT_H__ */ krb5-1.22.1/src/lib/krb5/keytab/ktremove.c0000664000175000017500000000313515051422640020022 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/ktremove.c */ /* * Copyright 1990,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef LEAN_CLIENT #include "k5-int.h" krb5_error_code KRB5_CALLCONV krb5_kt_remove_entry (krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) { if (id->ops->remove) return (*id->ops->remove)(context, id, entry); else return KRB5_KT_NOWRITE; } #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/keytab/ktadd.c0000664000175000017500000000312015051422640017247 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/ktadd.c */ /* * Copyright 1990,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #ifndef LEAN_CLIENT krb5_error_code KRB5_CALLCONV krb5_kt_add_entry (krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) { if (id->ops->add) return (*id->ops->add)(context, id, entry); else return KRB5_KT_NOWRITE; } #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/keytab/ktfr_entry.c0000664000175000017500000000355715051422640020365 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/ktfr_entry.c */ /* * Copyright 1990, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef LEAN_CLIENT #include "k5-int.h" krb5_error_code KRB5_CALLCONV krb5_free_keytab_entry_contents (krb5_context context, krb5_keytab_entry *entry) { if (!entry) return 0; krb5_free_principal(context, entry->principal); if (entry->key.contents) { zap((char *)entry->key.contents, entry->key.length); free(entry->key.contents); } return 0; } krb5_error_code KRB5_CALLCONV krb5_kt_free_entry (krb5_context context, krb5_keytab_entry *entry) { return krb5_free_keytab_entry_contents (context, entry); } #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/keytab/kt_memory.c0000664000175000017500000004125615051422640020202 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/kt_memory.c */ /* * Copyright 2007 by Secure Endpoints Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "k5-int.h" #include "kt-int.h" #include #ifndef LEAN_CLIENT #define HEIMDAL_COMPATIBLE /* * Information needed by internal routines of the file-based ticket * cache implementation. */ /* * Constants */ /* * Types */ /* From krb5.h: * typedef struct krb5_keytab_entry_st { * krb5_magic magic; * krb5_principal principal; principal of this key * krb5_timestamp timestamp; time entry written to keytable * krb5_kvno vno; key version number * krb5_keyblock key; the secret key *} krb5_keytab_entry; */ /* Individual key entries within a table, in a linked list */ typedef struct _krb5_mkt_link { struct _krb5_mkt_link *next; krb5_keytab_entry *entry; } krb5_mkt_link, *krb5_mkt_cursor; /* Per-keytab data header */ typedef struct _krb5_mkt_data { char *name; /* Name of the keytab */ k5_mutex_t lock; /* Thread-safety - all but link */ krb5_int32 refcount; krb5_mkt_cursor link; } krb5_mkt_data; /* List of memory key tables */ typedef struct _krb5_mkt_list_node { struct _krb5_mkt_list_node *next; krb5_keytab keytab; } krb5_mkt_list_node; /* Iterator over memory key tables */ typedef struct _krb5_mkt_ptcursor_data { struct _krb5_mkt_list_node *cur; } krb5_mkt_ptcursor_data; /* * Globals */ static krb5_mkt_list_node * krb5int_mkt_list = NULL; static k5_mutex_t krb5int_mkt_mutex = K5_MUTEX_PARTIAL_INITIALIZER; /* * Macros */ #define KTLOCK(id) k5_mutex_lock(&(((krb5_mkt_data *)(id)->data)->lock)) #define KTUNLOCK(id) k5_mutex_unlock(&(((krb5_mkt_data *)(id)->data)->lock)) #define KTCHECKLOCK(id) k5_mutex_assert_locked(&(((krb5_mkt_data *)(id)->data)->lock)) #define KTGLOCK k5_mutex_lock(&krb5int_mkt_mutex) #define KTGUNLOCK k5_mutex_unlock(&krb5int_mkt_mutex) #define KTGCHECKLOCK k5_mutex_assert_locked(&krb5int_mkt_mutex) #define KTLINK(id) (((krb5_mkt_data *)(id)->data)->link) #define KTREFCNT(id) (((krb5_mkt_data *)(id)->data)->refcount) #define KTNAME(id) (((krb5_mkt_data *)(id)->data)->name) extern const struct _krb5_kt_ops krb5_mkt_ops; krb5_error_code KRB5_CALLCONV krb5_mkt_resolve(krb5_context, const char *, krb5_keytab *); krb5_error_code KRB5_CALLCONV krb5_mkt_get_name(krb5_context, krb5_keytab, char *, unsigned int); krb5_error_code KRB5_CALLCONV krb5_mkt_close(krb5_context, krb5_keytab); krb5_error_code KRB5_CALLCONV krb5_mkt_get_entry(krb5_context, krb5_keytab, krb5_const_principal, krb5_kvno, krb5_enctype, krb5_keytab_entry *); krb5_error_code KRB5_CALLCONV krb5_mkt_start_seq_get(krb5_context, krb5_keytab, krb5_kt_cursor *); krb5_error_code KRB5_CALLCONV krb5_mkt_get_next(krb5_context, krb5_keytab, krb5_keytab_entry *, krb5_kt_cursor *); krb5_error_code KRB5_CALLCONV krb5_mkt_end_get(krb5_context, krb5_keytab, krb5_kt_cursor *); /* routines to be included on extended version (write routines) */ krb5_error_code KRB5_CALLCONV krb5_mkt_add(krb5_context, krb5_keytab, krb5_keytab_entry *); krb5_error_code KRB5_CALLCONV krb5_mkt_remove(krb5_context, krb5_keytab, krb5_keytab_entry *); int krb5int_mkt_initialize(void) { return k5_mutex_finish_init(&krb5int_mkt_mutex); } void krb5int_mkt_finalize(void) { krb5_mkt_list_node *node, *next_node; krb5_mkt_cursor cursor, next_cursor; k5_mutex_destroy(&krb5int_mkt_mutex); for (node = krb5int_mkt_list; node; node = next_node) { next_node = node->next; /* destroy the contents of node->keytab */ free(KTNAME(node->keytab)); /* free the keytab entries */ for (cursor = KTLINK(node->keytab); cursor; cursor = next_cursor) { next_cursor = cursor->next; /* the call to krb5_kt_free_entry uses a NULL in place of the * krb5_context since we know that the context isn't used by * krb5_kt_free_entry or krb5_free_principal. */ krb5_kt_free_entry(NULL, cursor->entry); free(cursor->entry); free(cursor); } /* destroy the lock */ k5_mutex_destroy(&(((krb5_mkt_data *)node->keytab->data)->lock)); /* free the private data */ free(node->keytab->data); /* and the keytab */ free(node->keytab); /* and finally the node */ free(node); } } static krb5_error_code create_list_node(const char *name, krb5_mkt_list_node **listp) { krb5_mkt_list_node *list; krb5_mkt_data *data = NULL; krb5_error_code err; *listp = NULL; list = calloc(1, sizeof(krb5_mkt_list_node)); if (list == NULL) { err = ENOMEM; goto cleanup; } list->keytab = calloc(1, sizeof(struct _krb5_kt)); if (list->keytab == NULL) { err = ENOMEM; goto cleanup; } list->keytab->ops = &krb5_mkt_ops; data = calloc(1, sizeof(krb5_mkt_data)); if (data == NULL) { err = ENOMEM; goto cleanup; } data->link = NULL; data->refcount = 0; data->name = strdup(name); if (data->name == NULL) { err = ENOMEM; goto cleanup; } err = k5_mutex_init(&data->lock); if (err) goto cleanup; list->keytab->data = data; list->keytab->magic = KV5M_KEYTAB; list->next = NULL; *listp = list; return 0; cleanup: /* data->lock was initialized last, so no need to destroy. */ if (data) free(data->name); free(data); if (list) free(list->keytab); free(list); return err; } /* * This is an implementation specific resolver. It returns a keytab * initialized with memory keytab routines. */ krb5_error_code KRB5_CALLCONV krb5_mkt_resolve(krb5_context context, const char *name, krb5_keytab *id) { krb5_mkt_list_node *list; krb5_error_code err = 0; *id = NULL; /* First determine if a memory keytab of this name already exists */ KTGLOCK; for (list = krb5int_mkt_list; list; list = list->next) { if (strcmp(name,KTNAME(list->keytab)) == 0) break; } if (!list) { /* We will now create the new key table with the specified name. * We do not drop the global lock, therefore the name will indeed * be unique when we add it. */ err = create_list_node(name, &list); if (err) goto done; list->next = krb5int_mkt_list; krb5int_mkt_list = list; } /* Increment the reference count on the keytab we found or created. */ KTLOCK(list->keytab); KTREFCNT(list->keytab)++; KTUNLOCK(list->keytab); *id = list->keytab; done: KTGUNLOCK; return err; } /* * "Close" a memory-based keytab. This is effectively a no-op. * We check to see if the keytab exists and that is about it. * Closing a file keytab does not destroy the contents. Closing * a memory keytab shouldn't either. */ krb5_error_code KRB5_CALLCONV krb5_mkt_close(krb5_context context, krb5_keytab id) { krb5_mkt_list_node **listp; #ifdef HEIMDAL_COMPATIBLE krb5_mkt_list_node *node; krb5_mkt_data * data; #endif krb5_error_code err = 0; /* First determine if a memory keytab of this name already exists */ KTGLOCK; for (listp = &krb5int_mkt_list; *listp; listp = &((*listp)->next)) { if (id == (*listp)->keytab) { /* Found */ break; } } if (*listp == NULL) { /* The specified keytab could not be found */ err = KRB5_KT_NOTFOUND; goto done; } /* reduce the refcount and return */ KTLOCK(id); KTREFCNT(id)--; KTUNLOCK(id); #ifdef HEIMDAL_COMPATIBLE /* In Heimdal if the refcount hits 0, the MEMORY keytab is * destroyed since there is no krb5_kt_destroy function. * There is no need to lock the entry while performing * these operations as the refcount will be 0 and we are * holding the global lock. */ data = (krb5_mkt_data *)id->data; if (data->refcount == 0) { krb5_mkt_cursor cursor, next_cursor; node = *listp; *listp = node->next; /* destroy the contents of node->keytab (aka id) */ free(data->name); /* free the keytab entries */ for (cursor = KTLINK(node->keytab); cursor; cursor = next_cursor) { next_cursor = cursor->next; krb5_kt_free_entry(context, cursor->entry); free(cursor->entry); free(cursor); } /* destroy the lock */ k5_mutex_destroy(&(data->lock)); /* free the private data */ free(data); /* and the keytab */ free(node->keytab); /* and finally the node */ free(node); } #endif /* HEIMDAL_COMPATIBLE */ done: KTGUNLOCK; return(err); } /* * This is the get_entry routine for the memory based keytab implementation. * It either retrieves the entry or returns an error. */ krb5_error_code KRB5_CALLCONV krb5_mkt_get_entry(krb5_context context, krb5_keytab id, krb5_const_principal principal, krb5_kvno kvno, krb5_enctype enctype, krb5_keytab_entry *out_entry) { krb5_mkt_cursor cursor; krb5_keytab_entry *entry, *match = NULL; krb5_error_code err = 0; int found_wrong_kvno = 0; krb5_boolean similar = 0; KTLOCK(id); for (cursor = KTLINK(id); cursor && cursor->entry; cursor = cursor->next) { entry = cursor->entry; /* if the principal isn't the one requested, continue to the next. */ if (!krb5_principal_compare(context, principal, entry->principal)) continue; /* if the enctype is not ignored and doesn't match, and continue to the next */ if (enctype != IGNORE_ENCTYPE) { if ((err = krb5_c_enctype_compare(context, enctype, entry->key.enctype, &similar))) { /* we can't determine the enctype of the entry */ continue; } if (!similar) continue; } if (kvno == IGNORE_VNO || entry->vno == IGNORE_VNO) { if (match == NULL) match = entry; else if (entry->vno > match->vno) match = entry; } else { if (entry->vno == kvno) { match = entry; break; } else { found_wrong_kvno++; } } } /* if we found an entry that matches, ... */ if (match) { out_entry->magic = match->magic; out_entry->timestamp = match->timestamp; out_entry->vno = match->vno; out_entry->key = match->key; err = krb5_copy_keyblock_contents(context, &(match->key), &(out_entry->key)); /* * Coerce the enctype of the output keyblock in case we * got an inexact match on the enctype. */ if(enctype != IGNORE_ENCTYPE) out_entry->key.enctype = enctype; if(!err) { err = krb5_copy_principal(context, match->principal, &(out_entry->principal)); } } else { if (!err) err = found_wrong_kvno ? KRB5_KT_KVNONOTFOUND : KRB5_KT_NOTFOUND; } KTUNLOCK(id); return(err); } /* * Get the name of the memory-based keytab. */ krb5_error_code KRB5_CALLCONV krb5_mkt_get_name(krb5_context context, krb5_keytab id, char *name, unsigned int len) { int result; memset(name, 0, len); result = snprintf(name, len, "%s:%s", id->ops->prefix, KTNAME(id)); if (SNPRINTF_OVERFLOW(result, len)) return(KRB5_KT_NAME_TOOLONG); return(0); } /* * krb5_mkt_start_seq_get() */ krb5_error_code KRB5_CALLCONV krb5_mkt_start_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursorp) { KTLOCK(id); *cursorp = (krb5_kt_cursor)KTLINK(id); KTUNLOCK(id); return(0); } /* * krb5_mkt_get_next() */ krb5_error_code KRB5_CALLCONV krb5_mkt_get_next(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry, krb5_kt_cursor *cursor) { krb5_mkt_cursor mkt_cursor = (krb5_mkt_cursor)*cursor; krb5_error_code err = 0; KTLOCK(id); if (mkt_cursor == NULL) { KTUNLOCK(id); return KRB5_KT_END; } entry->magic = mkt_cursor->entry->magic; entry->timestamp = mkt_cursor->entry->timestamp; entry->vno = mkt_cursor->entry->vno; entry->key = mkt_cursor->entry->key; err = krb5_copy_keyblock_contents(context, &(mkt_cursor->entry->key), &(entry->key)); if (!err) err = krb5_copy_principal(context, mkt_cursor->entry->principal, &(entry->principal)); if (!err) *cursor = (krb5_kt_cursor *)mkt_cursor->next; KTUNLOCK(id); return(err); } /* * krb5_mkt_end_get() */ krb5_error_code KRB5_CALLCONV krb5_mkt_end_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursor) { *cursor = NULL; return(0); } /* * krb5_mkt_add() */ krb5_error_code KRB5_CALLCONV krb5_mkt_add(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) { krb5_error_code err = 0; krb5_mkt_cursor cursor; KTLOCK(id); cursor = (krb5_mkt_cursor)malloc(sizeof(krb5_mkt_link)); if (cursor == NULL) { err = ENOMEM; goto done; } cursor->entry = (krb5_keytab_entry *)malloc(sizeof(krb5_keytab_entry)); if (cursor->entry == NULL) { free(cursor); err = ENOMEM; goto done; } cursor->entry->magic = entry->magic; cursor->entry->timestamp = entry->timestamp; cursor->entry->vno = entry->vno; err = krb5_copy_keyblock_contents(context, &(entry->key), &(cursor->entry->key)); if (err) { free(cursor->entry); free(cursor); goto done; } err = krb5_copy_principal(context, entry->principal, &(cursor->entry->principal)); if (err) { krb5_free_keyblock_contents(context, &(cursor->entry->key)); free(cursor->entry); free(cursor); goto done; } if (KTLINK(id) == NULL) { cursor->next = NULL; KTLINK(id) = cursor; } else { cursor->next = KTLINK(id); KTLINK(id) = cursor; } done: KTUNLOCK(id); return err; } /* * krb5_mkt_remove() */ krb5_error_code KRB5_CALLCONV krb5_mkt_remove(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) { krb5_mkt_cursor *pcursor, next; krb5_error_code err = 0; KTLOCK(id); if ( KTLINK(id) == NULL ) { err = KRB5_KT_NOTFOUND; goto done; } for ( pcursor = &KTLINK(id); *pcursor; pcursor = &(*pcursor)->next ) { if ( (*pcursor)->entry->vno == entry->vno && (*pcursor)->entry->key.enctype == entry->key.enctype && krb5_principal_compare(context, (*pcursor)->entry->principal, entry->principal)) break; } if (!*pcursor) { err = KRB5_KT_NOTFOUND; goto done; } krb5_kt_free_entry(context, (*pcursor)->entry); free((*pcursor)->entry); next = (*pcursor)->next; free(*pcursor); (*pcursor) = next; done: KTUNLOCK(id); return err; } /* * krb5_mkt_ops */ const struct _krb5_kt_ops krb5_mkt_ops = { 0, "MEMORY", /* Prefix -- this string should not appear anywhere else! */ krb5_mkt_resolve, krb5_mkt_get_name, krb5_mkt_close, krb5_mkt_get_entry, krb5_mkt_start_seq_get, krb5_mkt_get_next, krb5_mkt_end_get, krb5_mkt_add, krb5_mkt_remove }; #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/keytab/ktbase.c0000664000175000017500000001521515051422640017441 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/ktbase.c - Registration functions for keytab */ /* * Copyright 1990,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright 2007 by Secure Endpoints Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "k5-int.h" #include "k5-thread.h" #include "kt-int.h" #ifndef LEAN_CLIENT extern const krb5_kt_ops krb5_ktf_ops; extern const krb5_kt_ops krb5_ktf_writable_ops; extern const krb5_kt_ops krb5_mkt_ops; struct krb5_kt_typelist { const krb5_kt_ops *ops; const struct krb5_kt_typelist *next; }; const static struct krb5_kt_typelist krb5_kt_typelist_memory = { &krb5_mkt_ops, NULL }; const static struct krb5_kt_typelist krb5_kt_typelist_wrfile = { &krb5_ktf_writable_ops, &krb5_kt_typelist_memory }; const static struct krb5_kt_typelist krb5_kt_typelist_file = { &krb5_ktf_ops, &krb5_kt_typelist_wrfile }; static const struct krb5_kt_typelist *kt_typehead = &krb5_kt_typelist_file; /* Lock for protecting the type list. */ static k5_mutex_t kt_typehead_lock = K5_MUTEX_PARTIAL_INITIALIZER; int krb5int_kt_initialize(void) { int err; err = k5_mutex_finish_init(&kt_typehead_lock); if (err) goto done; err = krb5int_mkt_initialize(); if (err) goto done; done: return(err); } void krb5int_kt_finalize(void) { const struct krb5_kt_typelist *t, *t_next; k5_mutex_destroy(&kt_typehead_lock); for (t = kt_typehead; t != &krb5_kt_typelist_file; t = t_next) { t_next = t->next; free((struct krb5_kt_typelist *)t); } krb5int_mkt_finalize(); } /* * Register a new key table type * don't replace if it already exists; return an error instead. */ krb5_error_code KRB5_CALLCONV krb5_kt_register(krb5_context context, const krb5_kt_ops *ops) { const struct krb5_kt_typelist *t; struct krb5_kt_typelist *newt; k5_mutex_lock(&kt_typehead_lock); for (t = kt_typehead; t && strcmp(t->ops->prefix,ops->prefix);t = t->next) ; if (t) { k5_mutex_unlock(&kt_typehead_lock); return KRB5_KT_TYPE_EXISTS; } if (!(newt = (struct krb5_kt_typelist *) malloc(sizeof(*t)))) { k5_mutex_unlock(&kt_typehead_lock); return ENOMEM; } newt->next = kt_typehead; newt->ops = ops; kt_typehead = newt; k5_mutex_unlock(&kt_typehead_lock); return 0; } /* * Resolve a key table name into a keytab object. * * The name is currently constrained to be of the form "type:residual"; * * The "type" portion corresponds to one of the registered key table * types, while the "residual" portion is specific to the * particular keytab type. */ #include krb5_error_code KRB5_CALLCONV krb5_kt_resolve (krb5_context context, const char *name, krb5_keytab *ktid) { const struct krb5_kt_typelist *tlist; char *pfx = NULL; unsigned int pfxlen; const char *cp, *resid; krb5_error_code err = 0; krb5_keytab id; *ktid = NULL; cp = strchr (name, ':'); if (!cp) return (*krb5_kt_dfl_ops.resolve)(context, name, ktid); pfxlen = cp - name; if ( pfxlen == 1 && isalpha((unsigned char) name[0]) ) { /* We found a drive letter not a prefix - use FILE */ pfx = strdup("FILE"); if (!pfx) return ENOMEM; resid = name; } else if (name[0] == '/') { pfx = strdup("FILE"); if (!pfx) return ENOMEM; resid = name; } else { resid = name + pfxlen + 1; pfx = k5memdup0(name, pfxlen, &err); if (pfx == NULL) return err; } *ktid = (krb5_keytab) 0; k5_mutex_lock(&kt_typehead_lock); tlist = kt_typehead; /* Don't need to hold the lock, since entries are never modified or removed once they're in the list. Just need to protect access to the list head variable itself. */ k5_mutex_unlock(&kt_typehead_lock); for (; tlist; tlist = tlist->next) { if (strcmp (tlist->ops->prefix, pfx) == 0) { err = (*tlist->ops->resolve)(context, resid, &id); if (!err) *ktid = id; goto cleanup; } } err = KRB5_KT_UNKNOWN_TYPE; cleanup: free(pfx); return err; } krb5_error_code KRB5_CALLCONV krb5_kt_dup(krb5_context context, krb5_keytab in, krb5_keytab *out) { krb5_error_code err; char name[BUFSIZ]; err = in->ops->get_name(context, in, name, sizeof(name)); return err ? err : krb5_kt_resolve(context, name, out); } #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/keytab/ktfns.c0000664000175000017500000001634615051422640017323 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/keytab/ktfns.c */ /* * Copyright 2001,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Dispatch methods for keytab code. */ #ifndef LEAN_CLIENT #include "k5-int.h" #include "../krb/int-proto.h" #include "../os/os-proto.h" const char * KRB5_CALLCONV krb5_kt_get_type (krb5_context context, krb5_keytab keytab) { return keytab->ops->prefix; } krb5_error_code KRB5_CALLCONV krb5_kt_get_name(krb5_context context, krb5_keytab keytab, char *name, unsigned int namelen) { return krb5_x((keytab)->ops->get_name,(context, keytab,name,namelen)); } krb5_error_code KRB5_CALLCONV krb5_kt_close(krb5_context context, krb5_keytab keytab) { return krb5_x((keytab)->ops->close,(context, keytab)); } krb5_error_code KRB5_CALLCONV krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, krb5_const_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keytab_entry *entry) { krb5_error_code err; krb5_principal_data princ_data; if (krb5_is_referral_realm(&principal->realm)) { char *realm; princ_data = *principal; principal = &princ_data; err = krb5_get_default_realm(context, &realm); if (err) return err; princ_data.realm.data = realm; princ_data.realm.length = strlen(realm); } err = krb5_x((keytab)->ops->get,(context, keytab, principal, vno, enctype, entry)); TRACE_KT_GET_ENTRY(context, keytab, principal, vno, enctype, err); if (principal == &princ_data) krb5_free_default_realm(context, princ_data.realm.data); return err; } krb5_error_code KRB5_CALLCONV krb5_kt_start_seq_get(krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor) { return krb5_x((keytab)->ops->start_seq_get,(context, keytab, cursor)); } krb5_error_code KRB5_CALLCONV krb5_kt_next_entry(krb5_context context, krb5_keytab keytab, krb5_keytab_entry *entry, krb5_kt_cursor *cursor) { return krb5_x((keytab)->ops->get_next,(context, keytab, entry, cursor)); } krb5_error_code KRB5_CALLCONV krb5_kt_end_seq_get(krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor) { return krb5_x((keytab)->ops->end_get,(context, keytab, cursor)); } krb5_error_code KRB5_CALLCONV krb5_kt_have_content(krb5_context context, krb5_keytab keytab) { krb5_keytab_entry entry; krb5_kt_cursor cursor; krb5_error_code ret; char name[1024]; /* If the keytab is not iterable, assume that it has content. */ if (keytab->ops->start_seq_get == NULL) return 0; /* See if we can get at least one entry via iteration. */ ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret) goto no_entries; ret = krb5_kt_next_entry(context, keytab, &entry, &cursor); krb5_kt_end_seq_get(context, keytab, &cursor); if (ret) goto no_entries; krb5_kt_free_entry(context, &entry); return 0; no_entries: if (krb5_kt_get_name(context, keytab, name, sizeof(name)) == 0) { k5_setmsg(context, KRB5_KT_NOTFOUND, _("Keytab %s is nonexistent or empty"), name); } return KRB5_KT_NOTFOUND; } static krb5_error_code match_entries(krb5_context context, krb5_keytab keytab, krb5_const_principal mprinc) { krb5_error_code ret; krb5_keytab_entry ent; krb5_kt_cursor cursor; krb5_boolean match; /* Scan the keytab for host-based entries matching accprinc. */ ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret) return ret; while ((ret = krb5_kt_next_entry(context, keytab, &ent, &cursor)) == 0) { match = krb5_sname_match(context, mprinc, ent.principal); (void)krb5_free_keytab_entry_contents(context, &ent); if (match) break; } (void)krb5_kt_end_seq_get(context, keytab, &cursor); if (ret && ret != KRB5_KT_END) return ret; return match ? 0 : KRB5_KT_NOTFOUND; } krb5_error_code k5_kt_have_match(krb5_context context, krb5_keytab keytab, krb5_principal mprinc) { krb5_error_code ret; struct canonprinc iter = { mprinc, .no_hostrealm = TRUE }; krb5_const_principal canonprinc = NULL; /* Don't try to canonicalize if we're going to ignore hostnames. */ if (k5_sname_wildcard_host(context, mprinc)) return match_entries(context, keytab, mprinc); while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 && canonprinc != NULL) { ret = match_entries(context, keytab, canonprinc); if (ret != KRB5_KT_NOTFOUND) break; } free_canonprinc(&iter); return (ret == 0 && canonprinc == NULL) ? KRB5_KT_NOTFOUND : ret; } /* * In a couple of places we need to get a principal name from a keytab: when * verifying credentials against a keytab, and when querying the name of a * default GSS acceptor cred. Keytabs do not have the concept of a default * principal like ccaches do, so for now we just return the first principal * listed in the keytab, or an error if it's not iterable. In the future we * could consider elevating this to a public API and giving keytab types an * operation to return a default principal, and maybe extending the file format * and tools to support it. Returns KRB5_KT_NOTFOUND if the keytab is empty * or non-iterable. */ krb5_error_code k5_kt_get_principal(krb5_context context, krb5_keytab keytab, krb5_principal *princ_out) { krb5_error_code ret; krb5_kt_cursor cursor; krb5_keytab_entry kte; *princ_out = NULL; if (keytab->ops->start_seq_get == NULL) return KRB5_KT_NOTFOUND; ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret) return ret; ret = krb5_kt_next_entry(context, keytab, &kte, &cursor); (void)krb5_kt_end_seq_get(context, keytab, &cursor); if (ret) return (ret == KRB5_KT_END) ? KRB5_KT_NOTFOUND : ret; ret = krb5_copy_principal(context, kte.principal, princ_out); krb5_kt_free_entry(context, &kte); return ret; } #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/unicode/0000775000175000017500000000000015051422640016167 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/unicode/CompositionExclusions.txt0000664000175000017500000001644215051422640023317 0ustar ghudsonghudson# CompositionExclusions-3.2.0.txt # Date: 2002-03-19,23:30:28 GMT [MD] # # This file lists the characters from the UAX #15 Composition Exclusion Table. # # The format of the comments in this file has been updated since the last version, # CompositionExclusions-3.txt. The only substantive change to this file between that # version and this one is the addition of U+2ADC FORKING. # # For more information, see # https://www.unicode.org/unicode/reports/tr15/#Primary Exclusion List Table # ================================================ # (1) Script Specifics # This list of characters cannot be derived from the UnicodeData file. # ================================================ 0958 # DEVANAGARI LETTER QA 0959 # DEVANAGARI LETTER KHHA 095A # DEVANAGARI LETTER GHHA 095B # DEVANAGARI LETTER ZA 095C # DEVANAGARI LETTER DDDHA 095D # DEVANAGARI LETTER RHA 095E # DEVANAGARI LETTER FA 095F # DEVANAGARI LETTER YYA 09DC # BENGALI LETTER RRA 09DD # BENGALI LETTER RHA 09DF # BENGALI LETTER YYA 0A33 # GURMUKHI LETTER LLA 0A36 # GURMUKHI LETTER SHA 0A59 # GURMUKHI LETTER KHHA 0A5A # GURMUKHI LETTER GHHA 0A5B # GURMUKHI LETTER ZA 0A5E # GURMUKHI LETTER FA 0B5C # ORIYA LETTER RRA 0B5D # ORIYA LETTER RHA 0F43 # TIBETAN LETTER GHA 0F4D # TIBETAN LETTER DDHA 0F52 # TIBETAN LETTER DHA 0F57 # TIBETAN LETTER BHA 0F5C # TIBETAN LETTER DZHA 0F69 # TIBETAN LETTER KSSA 0F76 # TIBETAN VOWEL SIGN VOCALIC R 0F78 # TIBETAN VOWEL SIGN VOCALIC L 0F93 # TIBETAN SUBJOINED LETTER GHA 0F9D # TIBETAN SUBJOINED LETTER DDHA 0FA2 # TIBETAN SUBJOINED LETTER DHA 0FA7 # TIBETAN SUBJOINED LETTER BHA 0FAC # TIBETAN SUBJOINED LETTER DZHA 0FB9 # TIBETAN SUBJOINED LETTER KSSA FB1D # HEBREW LETTER YOD WITH HIRIQ FB1F # HEBREW LIGATURE YIDDISH YOD YOD PATAH FB2A # HEBREW LETTER SHIN WITH SHIN DOT FB2B # HEBREW LETTER SHIN WITH SIN DOT FB2C # HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT FB2D # HEBREW LETTER SHIN WITH DAGESH AND SIN DOT FB2E # HEBREW LETTER ALEF WITH PATAH FB2F # HEBREW LETTER ALEF WITH QAMATS FB30 # HEBREW LETTER ALEF WITH MAPIQ FB31 # HEBREW LETTER BET WITH DAGESH FB32 # HEBREW LETTER GIMEL WITH DAGESH FB33 # HEBREW LETTER DALET WITH DAGESH FB34 # HEBREW LETTER HE WITH MAPIQ FB35 # HEBREW LETTER VAV WITH DAGESH FB36 # HEBREW LETTER ZAYIN WITH DAGESH FB38 # HEBREW LETTER TET WITH DAGESH FB39 # HEBREW LETTER YOD WITH DAGESH FB3A # HEBREW LETTER FINAL KAF WITH DAGESH FB3B # HEBREW LETTER KAF WITH DAGESH FB3C # HEBREW LETTER LAMED WITH DAGESH FB3E # HEBREW LETTER MEM WITH DAGESH FB40 # HEBREW LETTER NUN WITH DAGESH FB41 # HEBREW LETTER SAMEKH WITH DAGESH FB43 # HEBREW LETTER FINAL PE WITH DAGESH FB44 # HEBREW LETTER PE WITH DAGESH FB46 # HEBREW LETTER TSADI WITH DAGESH FB47 # HEBREW LETTER QOF WITH DAGESH FB48 # HEBREW LETTER RESH WITH DAGESH FB49 # HEBREW LETTER SHIN WITH DAGESH FB4A # HEBREW LETTER TAV WITH DAGESH FB4B # HEBREW LETTER VAV WITH HOLAM FB4C # HEBREW LETTER BET WITH RAFE FB4D # HEBREW LETTER KAF WITH RAFE FB4E # HEBREW LETTER PE WITH RAFE # Total code points: 67 # ================================================ # (2) Post Composition Version precomposed characters # These characters cannot be derived solely from the UnicodeData.txt file # in this version of Unicode. # ================================================ 2ADC # FORKING 1D15E # MUSICAL SYMBOL HALF NOTE 1D15F # MUSICAL SYMBOL QUARTER NOTE 1D160 # MUSICAL SYMBOL EIGHTH NOTE 1D161 # MUSICAL SYMBOL SIXTEENTH NOTE 1D162 # MUSICAL SYMBOL THIRTY-SECOND NOTE 1D163 # MUSICAL SYMBOL SIXTY-FOURTH NOTE 1D164 # MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE 1D1BB # MUSICAL SYMBOL MINIMA 1D1BC # MUSICAL SYMBOL MINIMA BLACK 1D1BD # MUSICAL SYMBOL SEMIMINIMA WHITE 1D1BE # MUSICAL SYMBOL SEMIMINIMA BLACK 1D1BF # MUSICAL SYMBOL FUSA WHITE 1D1C0 # MUSICAL SYMBOL FUSA BLACK # Total code points: 14 # ================================================ # (3) Singleton Decompositions # These characters can be derived from the UnicodeData file # by including all characters whose canonical decomposition # consists of a single character. # These characters are simply quoted here for reference. # ================================================ # 0340..0341 [2] COMBINING GRAVE TONE MARK..COMBINING ACUTE TONE MARK # 0343 COMBINING GREEK KORONIS # 0374 GREEK NUMERAL SIGN # 037E GREEK QUESTION MARK # 0387 GREEK ANO TELEIA # 1F71 GREEK SMALL LETTER ALPHA WITH OXIA # 1F73 GREEK SMALL LETTER EPSILON WITH OXIA # 1F75 GREEK SMALL LETTER ETA WITH OXIA # 1F77 GREEK SMALL LETTER IOTA WITH OXIA # 1F79 GREEK SMALL LETTER OMICRON WITH OXIA # 1F7B GREEK SMALL LETTER UPSILON WITH OXIA # 1F7D GREEK SMALL LETTER OMEGA WITH OXIA # 1FBB GREEK CAPITAL LETTER ALPHA WITH OXIA # 1FBE GREEK PROSGEGRAMMENI # 1FC9 GREEK CAPITAL LETTER EPSILON WITH OXIA # 1FCB GREEK CAPITAL LETTER ETA WITH OXIA # 1FD3 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA # 1FDB GREEK CAPITAL LETTER IOTA WITH OXIA # 1FE3 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA # 1FEB GREEK CAPITAL LETTER UPSILON WITH OXIA # 1FEE..1FEF [2] GREEK DIALYTIKA AND OXIA..GREEK VARIA # 1FF9 GREEK CAPITAL LETTER OMICRON WITH OXIA # 1FFB GREEK CAPITAL LETTER OMEGA WITH OXIA # 1FFD GREEK OXIA # 2000..2001 [2] EN QUAD..EM QUAD # 2126 OHM SIGN # 212A..212B [2] KELVIN SIGN..ANGSTROM SIGN # 2329 LEFT-POINTING ANGLE BRACKET # 232A RIGHT-POINTING ANGLE BRACKET # F900..FA0D [270] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA0D # FA10 CJK COMPATIBILITY IDEOGRAPH-FA10 # FA12 CJK COMPATIBILITY IDEOGRAPH-FA12 # FA15..FA1E [10] CJK COMPATIBILITY IDEOGRAPH-FA15..CJK COMPATIBILITY IDEOGRAPH-FA1E # FA20 CJK COMPATIBILITY IDEOGRAPH-FA20 # FA22 CJK COMPATIBILITY IDEOGRAPH-FA22 # FA25..FA26 [2] CJK COMPATIBILITY IDEOGRAPH-FA25..CJK COMPATIBILITY IDEOGRAPH-FA26 # FA2A..FA2D [4] CJK COMPATIBILITY IDEOGRAPH-FA2A..CJK COMPATIBILITY IDEOGRAPH-FA2D # FA30..FA6A [59] CJK COMPATIBILITY IDEOGRAPH-FA30..CJK COMPATIBILITY IDEOGRAPH-FA6A # 2F800..2FA1D [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D # Total code points: 924 # ================================================ # (4) Non-Starter Decompositions # These characters can be derived from the UnicodeData file # by including all characters whose canonical decomposition consists # of a sequence of characters, the first of which has a non-zero # combining class. # These characters are simply quoted here for reference. # ================================================ # 0344 COMBINING GREEK DIALYTIKA TONOS # 0F73 TIBETAN VOWEL SIGN II # 0F75 TIBETAN VOWEL SIGN UU # 0F81 TIBETAN VOWEL SIGN REVERSED II # Total code points: 4 krb5-1.22.1/src/lib/krb5/unicode/Makefile.in0000664000175000017500000000247415051422640020243 0ustar ghudsonghudsonmydir=lib$(S)krb5$(S)unicode BUILDTOP=$(REL)..$(S)..$(S).. ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=unicode ##DOS##OBJFILE=..\$(OUTPRE)$(PREFIXDIR).lst XXDIR = $(srcdir)/ucdata/ XXHEADERS = ucdata.h uctable.h XXSRCS = ucdata.c ucgendat.c STLIBOBJS= \ ucdata.o \ ucstr.o OBJS= \ $(OUTPRE)ucdata.$(OBJEXT) \ $(OUTPRE)ucstr.$(OBJEXT) SRCS= \ $(srcdir)/ucstr.c EXTRADEPSRCS = ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs clean-unix:: clean-libobjs shared: mkdir shared uctable.h: $(XXDIR)/uctable.h $(XXDIR)/uctable.h: $(XXDIR)/ucgendat.c $(srcdir)/UnicodeData.txt $(srcdir)/CompositionExclusions.txt $(MAKE) ucgendat ./ucgendat $(srcdir)/UnicodeData.txt -x $(srcdir)/CompositionExclusions.txt ucgendat: ucgendat.o $(CC_LINK) $(ALL_CFLAGS) -o ucgendat ucgendat.o $(LIBS) ##DOS##!if 0 .links : @for i in $(XXSRCS) $(XXHEADERS); do \ $(RM) $$i ; \ ii=`find $(srcdir) -name $$i` ; \ $(LN_S) $$ii . ; \ done touch .links ##DOS##!endif ##DOS##.links: ##DOS## $(CP) $(srcdir)\ucdata\ucdata.h ucdata.h ##DOS## $(CP) $(srcdir)\ucdata\ucdata.c ucdata.c ##DOS## $(CP) $(srcdir)\ucdata\ucgendat.c ucgendat.c ##DOS## $(CP) $(srcdir)\ucdata\uctable.h uctable.h ##DOS## $(CP) nul .links $(XXSRCS) $(XXHEADERS) : .links clean: $(RM) *.dat .links $(XXHEADERS) $(XXSRCS) ucgendat depend: .links @libobj_frag@ krb5-1.22.1/src/lib/krb5/unicode/ucdata/0000775000175000017500000000000015051422640017430 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/unicode/ucdata/ucdata.c0000664000175000017500000010705715051422640021047 0ustar ghudsonghudson/* * Copyright 1998-2008 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in file LICENSE in the * top-level directory of the distribution or, alternatively, at * . */ /* Copyright 2001 Computing Research Labs, New Mexico State University * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * This work is part of OpenLDAP Software . * $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucdata.c,v 1.36 2008/01/07 23:20:05 kurt Exp $ * $Id: ucdata.c,v 1.4 2001/01/02 18:46:20 mleisher Exp $" */ #include "k5-int.h" #include "k5-utf8.h" #include "k5-unicode.h" #include "ucdata.h" #ifndef HARDCODE_DATA #define HARDCODE_DATA 1 #endif #if HARDCODE_DATA #include "uctable.h" #endif /************************************************************************** * * Miscellaneous types, data, and support functions. * **************************************************************************/ typedef struct { krb5_ui_2 bom; krb5_ui_2 cnt; union { krb5_ui_4 bytes; krb5_ui_2 len[2]; } size; } _ucheader_t; /* * A simple array of 32-bit masks for lookup. */ static krb5_ui_4 masks32[32] = { 0x00000001UL, 0x00000002UL, 0x00000004UL, 0x00000008UL, 0x00000010UL, 0x00000020UL, 0x00000040UL, 0x00000080UL, 0x00000100UL, 0x00000200UL, 0x00000400UL, 0x00000800UL, 0x00001000UL, 0x00002000UL, 0x00004000UL, 0x00008000UL, 0x00010000UL, 0x00020000UL, 0x00040000UL, 0x00080000UL, 0x00100000UL, 0x00200000UL, 0x00400000UL, 0x00800000UL, 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL }; #define endian_short(cc) (((cc) >> 8) | (((cc) & 0xff) << 8)) #define endian_long(cc) ((((cc) & 0xff) << 24)|((((cc) >> 8) & 0xff) << 16)|\ ((((cc) >> 16) & 0xff) << 8)|((cc) >> 24)) #if !HARDCODE_DATA static FILE * _ucopenfile(char *paths, char *filename, char *mode) { FILE *f; char *fp, *dp, *pp, path[BUFSIZ]; if (filename == 0 || *filename == 0) return 0; dp = paths; while (dp && *dp) { pp = path; while (*dp && *dp != ':') *pp++ = *dp++; *pp++ = *LDAP_DIRSEP; fp = filename; while (*fp) *pp++ = *fp++; *pp = 0; if ((f = fopen(path, mode)) != 0) return f; if (*dp == ':') dp++; } return 0; } #endif /************************************************************************** * * Support for the character properties. * **************************************************************************/ #if !HARDCODE_DATA static krb5_ui_4 _ucprop_size; static krb5_ui_2 *_ucprop_offsets; static krb5_ui_4 *_ucprop_ranges; /* * Return -1 on error, 0 if okay */ static int _ucprop_load(char *paths, int reload) { FILE *in; krb5_ui_4 size, i; _ucheader_t hdr; if (_ucprop_size > 0) { if (!reload) /* * The character properties have already been loaded. */ return 0; /* * Unload the current character property data in preparation for * loading a new copy. Only the first array has to be deallocated * because all the memory for the arrays is allocated as a single * block. */ free((char *) _ucprop_offsets); _ucprop_size = 0; } if ((in = _ucopenfile(paths, "ctype.dat", "rb")) == 0) return -1; /* * Load the header. */ fread((char *) &hdr, sizeof(_ucheader_t), 1, in); if (hdr.bom == 0xfffe) { hdr.cnt = endian_short(hdr.cnt); hdr.size.bytes = endian_long(hdr.size.bytes); } if ((_ucprop_size = hdr.cnt) == 0) { fclose(in); return -1; } /* * Allocate all the storage needed for the lookup table. */ _ucprop_offsets = (krb5_ui_2 *) malloc(hdr.size.bytes); /* * Calculate the offset into the storage for the ranges. The offsets * array is on a 4-byte boundary and one larger than the value provided in * the header count field. This means the offset to the ranges must be * calculated after aligning the count to a 4-byte boundary. */ if ((size = ((hdr.cnt + 1) * sizeof(krb5_ui_2))) & 3) size += 4 - (size & 3); size >>= 1; _ucprop_ranges = (krb5_ui_4 *) (_ucprop_offsets + size); /* * Load the offset array. */ fread((char *) _ucprop_offsets, sizeof(krb5_ui_2), size, in); /* * Do an endian swap if necessary. Don't forget there is an extra node on * the end with the final index. */ if (hdr.bom == 0xfffe) { for (i = 0; i <= _ucprop_size; i++) _ucprop_offsets[i] = endian_short(_ucprop_offsets[i]); } /* * Load the ranges. The number of elements is in the last array position * of the offsets. */ fread((char *) _ucprop_ranges, sizeof(krb5_ui_4), _ucprop_offsets[_ucprop_size], in); fclose(in); /* * Do an endian swap if necessary. */ if (hdr.bom == 0xfffe) { for (i = 0; i < _ucprop_offsets[_ucprop_size]; i++) _ucprop_ranges[i] = endian_long(_ucprop_ranges[i]); } return 0; } static void _ucprop_unload(void) { if (_ucprop_size == 0) return; /* * Only need to free the offsets because the memory is allocated as a * single block. */ free((char *) _ucprop_offsets); _ucprop_size = 0; } #endif static int _ucprop_lookup(krb5_ui_4 code, krb5_ui_4 n) { long l, r, m; if (_ucprop_size == 0) return 0; /* * There is an extra node on the end of the offsets to allow this routine * to work right. If the index is 0xffff, then there are no nodes for the * property. */ if ((l = _ucprop_offsets[n]) == 0xffff) return 0; /* * Locate the next offset that is not 0xffff. The sentinel at the end of * the array is the max index value. */ for (m = 1; n + m < _ucprop_size && _ucprop_offsets[n + m] == 0xffff; m++) ; r = _ucprop_offsets[n + m] - 1; while (l <= r) { /* * Determine a "mid" point and adjust to make sure the mid point is at * the beginning of a range pair. */ m = (l + r) >> 1; m -= (m & 1); if (code > _ucprop_ranges[m + 1]) l = m + 2; else if (code < _ucprop_ranges[m]) r = m - 2; else if (code >= _ucprop_ranges[m] && code <= _ucprop_ranges[m + 1]) return 1; } return 0; } int ucisprop(krb5_ui_4 code, krb5_ui_4 mask1, krb5_ui_4 mask2) { krb5_ui_4 i; if (mask1 == 0 && mask2 == 0) return 0; for (i = 0; mask1 && i < 32; i++) { if ((mask1 & masks32[i]) && _ucprop_lookup(code, i)) return 1; } for (i = 32; mask2 && i < _ucprop_size; i++) { if ((mask2 & masks32[i & 31]) && _ucprop_lookup(code, i)) return 1; } return 0; } /************************************************************************** * * Support for case mapping. * **************************************************************************/ #if !HARDCODE_DATA /* These record the number of slots in the map. * There are 3 words per slot. */ static krb5_ui_4 _uccase_size; static krb5_ui_2 _uccase_len[2]; static krb5_ui_4 *_uccase_map; /* * Return -1 on error, 0 if okay */ static int _uccase_load(char *paths, int reload) { FILE *in; krb5_ui_4 i; _ucheader_t hdr; if (_uccase_size > 0) { if (!reload) /* * The case mappings have already been loaded. */ return 0; free((char *) _uccase_map); _uccase_size = 0; } if ((in = _ucopenfile(paths, "case.dat", "rb")) == 0) return -1; /* * Load the header. */ fread((char *) &hdr, sizeof(_ucheader_t), 1, in); if (hdr.bom == 0xfffe) { hdr.cnt = endian_short(hdr.cnt); hdr.size.len[0] = endian_short(hdr.size.len[0]); hdr.size.len[1] = endian_short(hdr.size.len[1]); } /* * Set the node count and lengths of the upper and lower case mapping * tables. */ _uccase_size = hdr.cnt; _uccase_len[0] = hdr.size.len[0]; _uccase_len[1] = hdr.size.len[1]; _uccase_map = (krb5_ui_4 *) malloc(_uccase_size * 3 * sizeof(krb5_ui_4)); /* * Load the case mapping table. */ fread((char *) _uccase_map, sizeof(krb5_ui_4), _uccase_size * 3, in); /* * Do an endian swap if necessary. */ if (hdr.bom == 0xfffe) { for (i = 0; i < _uccase_size * 3; i++) _uccase_map[i] = endian_long(_uccase_map[i]); } fclose(in); return 0; } static void _uccase_unload(void) { if (_uccase_size == 0) return; free((char *) _uccase_map); _uccase_size = 0; } #endif static krb5_ui_4 _uccase_lookup(krb5_ui_4 code, long l, long r, int field) { long m; const krb5_ui_4 *tmp; /* * Do the binary search. */ while (l <= r) { /* * Determine a "mid" point and adjust to make sure the mid point is at * the beginning of a case mapping triple. */ m = (l + r) >> 1; tmp = &_uccase_map[m*3]; if (code > *tmp) l = m + 1; else if (code < *tmp) r = m - 1; else if (code == *tmp) return tmp[field]; } return code; } krb5_ui_4 uctoupper(krb5_ui_4 code) { int field; long l, r; if (ucisupper(code)) return code; if (ucislower(code)) { /* * The character is lower case. */ field = 2; l = _uccase_len[0]; r = (l + _uccase_len[1]) - 1; } else { /* * The character is title case. */ field = 1; l = _uccase_len[0] + _uccase_len[1]; r = _uccase_size - 1; } return _uccase_lookup(code, l, r, field); } krb5_ui_4 uctolower(krb5_ui_4 code) { int field; long l, r; if (ucislower(code)) return code; if (ucisupper(code)) { /* * The character is upper case. */ field = 1; l = 0; r = _uccase_len[0] - 1; } else { /* * The character is title case. */ field = 2; l = _uccase_len[0] + _uccase_len[1]; r = _uccase_size - 1; } return _uccase_lookup(code, l, r, field); } krb5_ui_4 uctotitle(krb5_ui_4 code) { int field; long l, r; if (ucistitle(code)) return code; /* * The offset will always be the same for converting to title case. */ field = 2; if (ucisupper(code)) { /* * The character is upper case. */ l = 0; r = _uccase_len[0] - 1; } else { /* * The character is lower case. */ l = _uccase_len[0]; r = (l + _uccase_len[1]) - 1; } return _uccase_lookup(code, l, r, field); } /************************************************************************** * * Support for compositions. * **************************************************************************/ #if !HARDCODE_DATA static krb5_ui_4 _uccomp_size; static krb5_ui_4 *_uccomp_data; /* * Return -1 on error, 0 if okay */ static int _uccomp_load(char *paths, int reload) { FILE *in; krb5_ui_4 size, i; _ucheader_t hdr; if (_uccomp_size > 0) { if (!reload) /* * The compositions have already been loaded. */ return 0; free((char *) _uccomp_data); _uccomp_size = 0; } if ((in = _ucopenfile(paths, "comp.dat", "rb")) == 0) return -1; /* * Load the header. */ fread((char *) &hdr, sizeof(_ucheader_t), 1, in); if (hdr.bom == 0xfffe) { hdr.cnt = endian_short(hdr.cnt); hdr.size.bytes = endian_long(hdr.size.bytes); } _uccomp_size = hdr.cnt; _uccomp_data = (krb5_ui_4 *) malloc(hdr.size.bytes); /* * Read the composition data in. */ size = hdr.size.bytes / sizeof(krb5_ui_4); fread((char *) _uccomp_data, sizeof(krb5_ui_4), size, in); /* * Do an endian swap if necessary. */ if (hdr.bom == 0xfffe) { for (i = 0; i < size; i++) _uccomp_data[i] = endian_long(_uccomp_data[i]); } /* * Assume that the data is ordered on count, so that all compositions * of length 2 come first. Only handling length 2 for now. */ for (i = 1; i < size; i += 4) if (_uccomp_data[i] != 2) break; _uccomp_size = i - 1; fclose(in); return 0; } static void _uccomp_unload(void) { if (_uccomp_size == 0) return; free((char *) _uccomp_data); _uccomp_size = 0; } #endif int uccomp(krb5_ui_4 node1, krb5_ui_4 node2, krb5_ui_4 *comp) { int l, r, m; l = 0; r = _uccomp_size - 1; while (l <= r) { m = ((r + l) >> 1); m -= m & 3; if (node1 > _uccomp_data[m+2]) l = m + 4; else if (node1 < _uccomp_data[m+2]) r = m - 4; else if (node2 > _uccomp_data[m+3]) l = m + 4; else if (node2 < _uccomp_data[m+3]) r = m - 4; else { *comp = _uccomp_data[m]; return 1; } } return 0; } int uccomp_hangul(krb5_ui_4 *str, int len) { const int SBase = 0xAC00, LBase = 0x1100, VBase = 0x1161, TBase = 0x11A7, LCount = 19, VCount = 21, TCount = 28, NCount = VCount * TCount, /* 588 */ SCount = LCount * NCount; /* 11172 */ int i, rlen; krb5_ui_4 ch, last, lindex, sindex; last = str[0]; rlen = 1; for ( i = 1; i < len; i++ ) { ch = str[i]; /* check if two current characters are L and V */ lindex = last - LBase; if (lindex < (krb5_ui_4) LCount) { krb5_ui_4 vindex = ch - VBase; if (vindex < (krb5_ui_4) VCount) { /* make syllable of form LV */ last = SBase + (lindex * VCount + vindex) * TCount; str[rlen-1] = last; /* reset last */ continue; } } /* check if two current characters are LV and T */ sindex = last - SBase; if (sindex < (krb5_ui_4) SCount && (sindex % TCount) == 0) { krb5_ui_4 tindex = ch - TBase; if (tindex <= (krb5_ui_4) TCount) { /* make syllable of form LVT */ last += tindex; str[rlen-1] = last; /* reset last */ continue; } } /* if neither case was true, just add the character */ last = ch; str[rlen] = ch; rlen++; } return rlen; } int uccanoncomp(krb5_ui_4 *str, int len) { int i, stpos, copos; krb5_ui_4 cl, prevcl, st, ch, co; st = str[0]; stpos = 0; copos = 1; prevcl = uccombining_class(st) == 0 ? 0 : 256; for (i = 1; i < len; i++) { ch = str[i]; cl = uccombining_class(ch); if (uccomp(st, ch, &co) && (prevcl < cl || prevcl == 0)) st = str[stpos] = co; else { if (cl == 0) { stpos = copos; st = ch; } prevcl = cl; str[copos++] = ch; } } return uccomp_hangul(str, copos); } /************************************************************************** * * Support for decompositions. * **************************************************************************/ #if !HARDCODE_DATA static krb5_ui_4 _ucdcmp_size; static krb5_ui_4 *_ucdcmp_nodes; static krb5_ui_4 *_ucdcmp_decomp; static krb5_ui_4 _uckdcmp_size; static krb5_ui_4 *_uckdcmp_nodes; static krb5_ui_4 *_uckdcmp_decomp; /* * Return -1 on error, 0 if okay */ static int _ucdcmp_load(char *paths, int reload) { FILE *in; krb5_ui_4 size, i; _ucheader_t hdr; if (_ucdcmp_size > 0) { if (!reload) /* * The decompositions have already been loaded. */ return 0; free((char *) _ucdcmp_nodes); _ucdcmp_size = 0; } if ((in = _ucopenfile(paths, "decomp.dat", "rb")) == 0) return -1; /* * Load the header. */ fread((char *) &hdr, sizeof(_ucheader_t), 1, in); if (hdr.bom == 0xfffe) { hdr.cnt = endian_short(hdr.cnt); hdr.size.bytes = endian_long(hdr.size.bytes); } _ucdcmp_size = hdr.cnt << 1; _ucdcmp_nodes = (krb5_ui_4 *) malloc(hdr.size.bytes); _ucdcmp_decomp = _ucdcmp_nodes + (_ucdcmp_size + 1); /* * Read the decomposition data in. */ size = hdr.size.bytes / sizeof(krb5_ui_4); fread((char *) _ucdcmp_nodes, sizeof(krb5_ui_4), size, in); /* * Do an endian swap if necessary. */ if (hdr.bom == 0xfffe) { for (i = 0; i < size; i++) _ucdcmp_nodes[i] = endian_long(_ucdcmp_nodes[i]); } fclose(in); return 0; } /* * Return -1 on error, 0 if okay */ static int _uckdcmp_load(char *paths, int reload) { FILE *in; krb5_ui_4 size, i; _ucheader_t hdr; if (_uckdcmp_size > 0) { if (!reload) /* * The decompositions have already been loaded. */ return 0; free((char *) _uckdcmp_nodes); _uckdcmp_size = 0; } if ((in = _ucopenfile(paths, "kdecomp.dat", "rb")) == 0) return -1; /* * Load the header. */ fread((char *) &hdr, sizeof(_ucheader_t), 1, in); if (hdr.bom == 0xfffe) { hdr.cnt = endian_short(hdr.cnt); hdr.size.bytes = endian_long(hdr.size.bytes); } _uckdcmp_size = hdr.cnt << 1; _uckdcmp_nodes = (krb5_ui_4 *) malloc(hdr.size.bytes); _uckdcmp_decomp = _uckdcmp_nodes + (_uckdcmp_size + 1); /* * Read the decomposition data in. */ size = hdr.size.bytes / sizeof(krb5_ui_4); fread((char *) _uckdcmp_nodes, sizeof(krb5_ui_4), size, in); /* * Do an endian swap if necessary. */ if (hdr.bom == 0xfffe) { for (i = 0; i < size; i++) _uckdcmp_nodes[i] = endian_long(_uckdcmp_nodes[i]); } fclose(in); return 0; } static void _ucdcmp_unload(void) { if (_ucdcmp_size == 0) return; /* * Only need to free the offsets because the memory is allocated as a * single block. */ free((char *) _ucdcmp_nodes); _ucdcmp_size = 0; } static void _uckdcmp_unload(void) { if (_uckdcmp_size == 0) return; /* * Only need to free the offsets because the memory is allocated as a * single block. */ free((char *) _uckdcmp_nodes); _uckdcmp_size = 0; } #endif int ucdecomp(krb5_ui_4 code, krb5_ui_4 *num, krb5_ui_4 **decomp) { long l, r, m; if (code < _ucdcmp_nodes[0]) { return 0; } l = 0; r = _ucdcmp_nodes[_ucdcmp_size] - 1; while (l <= r) { /* * Determine a "mid" point and adjust to make sure the mid point is at * the beginning of a code+offset pair. */ m = (l + r) >> 1; m -= (m & 1); if (code > _ucdcmp_nodes[m]) l = m + 2; else if (code < _ucdcmp_nodes[m]) r = m - 2; else if (code == _ucdcmp_nodes[m]) { *num = _ucdcmp_nodes[m + 3] - _ucdcmp_nodes[m + 1]; *decomp = (krb5_ui_4*)&_ucdcmp_decomp[_ucdcmp_nodes[m + 1]]; return 1; } } return 0; } int uckdecomp(krb5_ui_4 code, krb5_ui_4 *num, krb5_ui_4 **decomp) { long l, r, m; if (code < _uckdcmp_nodes[0]) { return 0; } l = 0; r = _uckdcmp_nodes[_uckdcmp_size] - 1; while (l <= r) { /* * Determine a "mid" point and adjust to make sure the mid point is at * the beginning of a code+offset pair. */ m = (l + r) >> 1; m -= (m & 1); if (code > _uckdcmp_nodes[m]) l = m + 2; else if (code < _uckdcmp_nodes[m]) r = m - 2; else if (code == _uckdcmp_nodes[m]) { *num = _uckdcmp_nodes[m + 3] - _uckdcmp_nodes[m + 1]; *decomp = (krb5_ui_4*)&_uckdcmp_decomp[_uckdcmp_nodes[m + 1]]; return 1; } } return 0; } int ucdecomp_hangul(krb5_ui_4 code, krb5_ui_4 *num, krb5_ui_4 decomp[]) { if (!ucishangul(code)) return 0; code -= 0xac00; decomp[0] = 0x1100 + (krb5_ui_4) (code / 588); decomp[1] = 0x1161 + (krb5_ui_4) ((code % 588) / 28); decomp[2] = 0x11a7 + (krb5_ui_4) (code % 28); *num = (decomp[2] != 0x11a7) ? 3 : 2; return 1; } /* mode == 0 for canonical, mode == 1 for compatibility */ static int uccanoncompatdecomp(const krb5_ui_4 *in, int inlen, krb5_ui_4 **out, int *outlen, short mode) { int l, size; unsigned i, j, k; krb5_ui_4 num, class, *decomp, hangdecomp[3]; size = inlen * 2; *out = (krb5_ui_4 *) malloc(size * sizeof(**out)); if (*out == NULL) return *outlen = -1; i = 0; for (j = 0; j < (unsigned) inlen; j++) { if (mode ? uckdecomp(in[j], &num, &decomp) : ucdecomp(in[j], &num, &decomp)) { if ( size - i < num) { size = inlen + i - j + num - 1; *out = (krb5_ui_4 *) realloc(*out, size * sizeof(**out)); if (*out == NULL) return *outlen = -1; } for (k = 0; k < num; k++) { class = uccombining_class(decomp[k]); if (class == 0) { (*out)[i] = decomp[k]; } else { for (l = i; l > 0; l--) if (class >= uccombining_class((*out)[l-1])) break; memmove(*out + l + 1, *out + l, (i - l) * sizeof(**out)); (*out)[l] = decomp[k]; } i++; } } else if (ucdecomp_hangul(in[j], &num, hangdecomp)) { if (size - i < num) { size = inlen + i - j + num - 1; *out = (krb5_ui_4 *) realloc(*out, size * sizeof(**out)); if (*out == NULL) return *outlen = -1; } for (k = 0; k < num; k++) { (*out)[i] = hangdecomp[k]; i++; } } else { if (size - i < 1) { size = inlen + i - j; *out = (krb5_ui_4 *) realloc(*out, size * sizeof(**out)); if (*out == NULL) return *outlen = -1; } class = uccombining_class(in[j]); if (class == 0) { (*out)[i] = in[j]; } else { for (l = i; l > 0; l--) if (class >= uccombining_class((*out)[l-1])) break; memmove(*out + l + 1, *out + l, (i - l) * sizeof(**out)); (*out)[l] = in[j]; } i++; } } return *outlen = i; } int uccanondecomp(const krb5_ui_4 *in, int inlen, krb5_ui_4 **out, int *outlen) { return uccanoncompatdecomp(in, inlen, out, outlen, 0); } int uccompatdecomp(const krb5_ui_4 *in, int inlen, krb5_ui_4 **out, int *outlen) { return uccanoncompatdecomp(in, inlen, out, outlen, 1); } /************************************************************************** * * Support for combining classes. * **************************************************************************/ #if !HARDCODE_DATA static krb5_ui_4 _uccmcl_size; static krb5_ui_4 *_uccmcl_nodes; /* * Return -1 on error, 0 if okay */ static int _uccmcl_load(char *paths, int reload) { FILE *in; krb5_ui_4 i; _ucheader_t hdr; if (_uccmcl_size > 0) { if (!reload) /* * The combining classes have already been loaded. */ return 0; free((char *) _uccmcl_nodes); _uccmcl_size = 0; } if ((in = _ucopenfile(paths, "cmbcl.dat", "rb")) == 0) return -1; /* * Load the header. */ fread((char *) &hdr, sizeof(_ucheader_t), 1, in); if (hdr.bom == 0xfffe) { hdr.cnt = endian_short(hdr.cnt); hdr.size.bytes = endian_long(hdr.size.bytes); } _uccmcl_size = hdr.cnt * 3; _uccmcl_nodes = (krb5_ui_4 *) malloc(hdr.size.bytes); /* * Read the combining classes in. */ fread((char *) _uccmcl_nodes, sizeof(krb5_ui_4), _uccmcl_size, in); /* * Do an endian swap if necessary. */ if (hdr.bom == 0xfffe) { for (i = 0; i < _uccmcl_size; i++) _uccmcl_nodes[i] = endian_long(_uccmcl_nodes[i]); } fclose(in); return 0; } static void _uccmcl_unload(void) { if (_uccmcl_size == 0) return; free((char *) _uccmcl_nodes); _uccmcl_size = 0; } #endif krb5_ui_4 uccombining_class(krb5_ui_4 code) { long l, r, m; l = 0; r = _uccmcl_size - 1; while (l <= r) { m = (l + r) >> 1; m -= (m % 3); if (code > _uccmcl_nodes[m + 1]) l = m + 3; else if (code < _uccmcl_nodes[m]) r = m - 3; else if (code >= _uccmcl_nodes[m] && code <= _uccmcl_nodes[m + 1]) return _uccmcl_nodes[m + 2]; } return 0; } /************************************************************************** * * Support for numeric values. * **************************************************************************/ #if !HARDCODE_DATA static krb5_ui_4 *_ucnum_nodes; static krb5_ui_4 _ucnum_size; static short *_ucnum_vals; /* * Return -1 on error, 0 if okay */ static int _ucnumb_load(char *paths, int reload) { FILE *in; krb5_ui_4 size, i; _ucheader_t hdr; if (_ucnum_size > 0) { if (!reload) /* * The numbers have already been loaded. */ return 0; free((char *) _ucnum_nodes); _ucnum_size = 0; } if ((in = _ucopenfile(paths, "num.dat", "rb")) == 0) return -1; /* * Load the header. */ fread((char *) &hdr, sizeof(_ucheader_t), 1, in); if (hdr.bom == 0xfffe) { hdr.cnt = endian_short(hdr.cnt); hdr.size.bytes = endian_long(hdr.size.bytes); } _ucnum_size = hdr.cnt; _ucnum_nodes = (krb5_ui_4 *) malloc(hdr.size.bytes); _ucnum_vals = (short *) (_ucnum_nodes + _ucnum_size); /* * Read the combining classes in. */ fread((char *) _ucnum_nodes, sizeof(unsigned char), hdr.size.bytes, in); /* * Do an endian swap if necessary. */ if (hdr.bom == 0xfffe) { for (i = 0; i < _ucnum_size; i++) _ucnum_nodes[i] = endian_long(_ucnum_nodes[i]); /* * Determine the number of values that have to be adjusted. */ size = (hdr.size.bytes - (_ucnum_size * (sizeof(krb5_ui_4) << 1))) / sizeof(short); for (i = 0; i < size; i++) _ucnum_vals[i] = endian_short(_ucnum_vals[i]); } fclose(in); return 0; } static void _ucnumb_unload(void) { if (_ucnum_size == 0) return; free((char *) _ucnum_nodes); _ucnum_size = 0; } #endif int ucnumber_lookup(krb5_ui_4 code, struct ucnumber *num) { long l, r, m; short *vp; l = 0; r = _ucnum_size - 1; while (l <= r) { /* * Determine a "mid" point and adjust to make sure the mid point is at * the beginning of a code+offset pair. */ m = (l + r) >> 1; m -= (m & 1); if (code > _ucnum_nodes[m]) l = m + 2; else if (code < _ucnum_nodes[m]) r = m - 2; else { vp = (short *)_ucnum_vals + _ucnum_nodes[m + 1]; num->numerator = (int) *vp++; num->denominator = (int) *vp; return 1; } } return 0; } int ucdigit_lookup(krb5_ui_4 code, int *digit) { long l, r, m; short *vp; l = 0; r = _ucnum_size - 1; while (l <= r) { /* * Determine a "mid" point and adjust to make sure the mid point is at * the beginning of a code+offset pair. */ m = (l + r) >> 1; m -= (m & 1); if (code > _ucnum_nodes[m]) l = m + 2; else if (code < _ucnum_nodes[m]) r = m - 2; else { vp = (short *)_ucnum_vals + _ucnum_nodes[m + 1]; if (*vp == *(vp + 1)) { *digit = *vp; return 1; } return 0; } } return 0; } struct ucnumber ucgetnumber(krb5_ui_4 code) { struct ucnumber num; /* * Initialize with some arbitrary value, because the caller simply cannot * tell for sure if the code is a number without calling the ucisnumber() * macro before calling this function. */ num.numerator = num.denominator = -111; (void) ucnumber_lookup(code, &num); return num; } int ucgetdigit(krb5_ui_4 code) { int dig; /* * Initialize with some arbitrary value, because the caller simply cannot * tell for sure if the code is a number without calling the ucisdigit() * macro before calling this function. */ dig = -111; (void) ucdigit_lookup(code, &dig); return dig; } /************************************************************************** * * Setup and cleanup routines. * **************************************************************************/ #if HARDCODE_DATA int ucdata_load(char *paths, int masks) { return 0; } void ucdata_unload(int masks) { } int ucdata_reload(char *paths, int masks) { return 0; } #else /* * Return 0 if okay, negative on error */ int ucdata_load(char *paths, int masks) { int error = 0; if (masks & UCDATA_CTYPE) error |= _ucprop_load(paths, 0) < 0 ? UCDATA_CTYPE : 0; if (masks & UCDATA_CASE) error |= _uccase_load(paths, 0) < 0 ? UCDATA_CASE : 0; if (masks & UCDATA_DECOMP) error |= _ucdcmp_load(paths, 0) < 0 ? UCDATA_DECOMP : 0; if (masks & UCDATA_CMBCL) error |= _uccmcl_load(paths, 0) < 0 ? UCDATA_CMBCL : 0; if (masks & UCDATA_NUM) error |= _ucnumb_load(paths, 0) < 0 ? UCDATA_NUM : 0; if (masks & UCDATA_COMP) error |= _uccomp_load(paths, 0) < 0 ? UCDATA_COMP : 0; if (masks & UCDATA_KDECOMP) error |= _uckdcmp_load(paths, 0) < 0 ? UCDATA_KDECOMP : 0; return -error; } void ucdata_unload(int masks) { if (masks & UCDATA_CTYPE) _ucprop_unload(); if (masks & UCDATA_CASE) _uccase_unload(); if (masks & UCDATA_DECOMP) _ucdcmp_unload(); if (masks & UCDATA_CMBCL) _uccmcl_unload(); if (masks & UCDATA_NUM) _ucnumb_unload(); if (masks & UCDATA_COMP) _uccomp_unload(); if (masks & UCDATA_KDECOMP) _uckdcmp_unload(); } /* * Return 0 if okay, negative on error */ int ucdata_reload(char *paths, int masks) { int error = 0; if (masks & UCDATA_CTYPE) error |= _ucprop_load(paths, 1) < 0 ? UCDATA_CTYPE : 0; if (masks & UCDATA_CASE) error |= _uccase_load(paths, 1) < 0 ? UCDATA_CASE : 0; if (masks & UCDATA_DECOMP) error |= _ucdcmp_load(paths, 1) < 0 ? UCDATA_DECOMP : 0; if (masks & UCDATA_CMBCL) error |= _uccmcl_load(paths, 1) < 0 ? UCDATA_CMBCL : 0; if (masks & UCDATA_NUM) error |= _ucnumb_load(paths, 1) < 0 ? UCDATA_NUM : 0; if (masks & UCDATA_COMP) error |= _uccomp_load(paths, 1) < 0 ? UCDATA_COMP : 0; if (masks & UCDATA_KDECOMP) error |= _uckdcmp_load(paths, 1) < 0 ? UCDATA_KDECOMP : 0; return -error; } #endif #ifdef TEST void main(void) { int dig; krb5_ui_4 i, lo, *dec; struct ucnumber num; /* ucdata_setup("."); */ if (ucisweak(0x30)) printf("WEAK\n"); else printf("NOT WEAK\n"); printf("LOWER 0x%04lX\n", uctolower(0xff3a)); printf("UPPER 0x%04lX\n", uctoupper(0xff5a)); if (ucisalpha(0x1d5)) printf("ALPHA\n"); else printf("NOT ALPHA\n"); if (ucisupper(0x1d5)) { printf("UPPER\n"); lo = uctolower(0x1d5); printf("0x%04lx\n", lo); lo = uctotitle(0x1d5); printf("0x%04lx\n", lo); } else printf("NOT UPPER\n"); if (ucistitle(0x1d5)) printf("TITLE\n"); else printf("NOT TITLE\n"); if (uciscomposite(0x1d5)) printf("COMPOSITE\n"); else printf("NOT COMPOSITE\n"); if (ucdecomp(0x1d5, &lo, &dec)) { for (i = 0; i < lo; i++) printf("0x%04lx ", dec[i]); putchar('\n'); } if ((lo = uccombining_class(0x41)) != 0) printf("0x41 CCL %ld\n", lo); if (ucisxdigit(0xfeff)) printf("0xFEFF HEX DIGIT\n"); else printf("0xFEFF NOT HEX DIGIT\n"); if (ucisdefined(0x10000)) printf("0x10000 DEFINED\n"); else printf("0x10000 NOT DEFINED\n"); if (ucnumber_lookup(0x30, &num)) { if (num.denominator != 1) printf("UCNUMBER: 0x30 = %d/%d\n", num.numerator, num.denominator); else printf("UCNUMBER: 0x30 = %d\n", num.numerator); } else printf("UCNUMBER: 0x30 NOT A NUMBER\n"); if (ucnumber_lookup(0xbc, &num)) { if (num.denominator != 1) printf("UCNUMBER: 0xbc = %d/%d\n", num.numerator, num.denominator); else printf("UCNUMBER: 0xbc = %d\n", num.numerator); } else printf("UCNUMBER: 0xbc NOT A NUMBER\n"); if (ucnumber_lookup(0xff19, &num)) { if (num.denominator != 1) printf("UCNUMBER: 0xff19 = %d/%d\n", num.numerator, num.denominator); else printf("UCNUMBER: 0xff19 = %d\n", num.numerator); } else printf("UCNUMBER: 0xff19 NOT A NUMBER\n"); if (ucnumber_lookup(0x4e00, &num)) { if (num.denominator != 1) printf("UCNUMBER: 0x4e00 = %d/%d\n", num.numerator, num.denominator); else printf("UCNUMBER: 0x4e00 = %d\n", num.numerator); } else printf("UCNUMBER: 0x4e00 NOT A NUMBER\n"); if (ucdigit_lookup(0x06f9, &dig)) printf("UCDIGIT: 0x6f9 = %d\n", dig); else printf("UCDIGIT: 0x6f9 NOT A NUMBER\n"); dig = ucgetdigit(0x0969); printf("UCGETDIGIT: 0x969 = %d\n", dig); num = ucgetnumber(0x30); if (num.denominator != 1) printf("UCGETNUMBER: 0x30 = %d/%d\n", num.numerator, num.denominator); else printf("UCGETNUMBER: 0x30 = %d\n", num.numerator); num = ucgetnumber(0xbc); if (num.denominator != 1) printf("UCGETNUMBER: 0xbc = %d/%d\n", num.numerator, num.denominator); else printf("UCGETNUMBER: 0xbc = %d\n", num.numerator); num = ucgetnumber(0xff19); if (num.denominator != 1) printf("UCGETNUMBER: 0xff19 = %d/%d\n", num.numerator, num.denominator); else printf("UCGETNUMBER: 0xff19 = %d\n", num.numerator); /* ucdata_cleanup(); */ exit(0); } #endif /* TEST */ krb5-1.22.1/src/lib/krb5/unicode/ucdata/README0000664000175000017500000002477615051422640020330 0ustar ghudsonghudson# # $Id: README,v 1.33 2001/01/02 18:46:19 mleisher Exp $ # MUTT UCData Package 2.5 ----------------------- This is a package that supports ctype-like operations for Unicode UCS-2 text (and surrogates), case mapping, decomposition lookup, and provides a bidirectional reordering algorithm. To use it, you will need to get the latest "UnicodeData-*.txt" (or later) file from the Unicode Web or FTP site. The character information portion of the package consists of three parts: 1. A program called "ucgendat" which generates five data files from the UnicodeData-*.txt file. The files are: A. case.dat - the case mappings. B. ctype.dat - the character property tables. C. comp.dat - the character composition pairs. D. decomp.dat - the character decompositions. E. cmbcl.dat - the non-zero combining classes. F. num.dat - the codes representing numbers. 2. The "ucdata.[ch]" files which implement the functions needed to check to see if a character matches groups of properties, to map between upper, lower, and title case, to look up the decomposition of a character, look up the combining class of a character, and get the number value of a character. 3. The UCData.java class which provides the same API (with minor changes for the numbers) and loads the same binary data files as the C code. A short reference to the functions available is in the "api.txt" file. Techie Details ============== The "ucgendat" program parses files from the command line which are all in the Unicode Character Database (UCDB) format. An additional properties file, "MUTTUCData.txt", provides some extra properties for some characters. The program looks for the two character properties fields (2 and 4), the combining class field (3), the decomposition field (5), the numeric value field (8), and the case mapping fields (12, 13, and 14). The decompositions are recursively expanded before being written out. The decomposition table contains all the canonical decompositions. This means all decompositions that do not have tags such as "" or "". The data is almost all stored as unsigned longs (32-bits assumed) and the routines that load the data take care of endian swaps when necessary. This also means that supplementary characters (>= 0x10000) can be placed in the data files the "ucgendat" program parses. The data is written as external files and broken into six parts so it can be selectively updated at runtime if necessary. The data files currently generated from the "ucgendat" program total about 56K in size all together. The format of the binary data files is documented in the "format.txt" file. ========================================================================== The "Pretty Good Bidi Algorithm" -------------------------------- This routine provides an alternative to the Unicode Bidi algorithm. The difference is that this version of the PGBA does not handle the explicit directional codes (LRE, RLE, LRO, RLO, PDF). It should now produce the same results as the Unicode BiDi algorithm for implicit reordering. Included are functions for doing cursor motion in both logical and visual order. This implementation is provided to demonstrate an effective alternate method for implicit reordering. To make this useful for an application, it probably needs some changes to the memory allocation and deallocation, as well as data structure additions for rendering. Mark Leisher 19 November 1999 ----------------------------------------------------------------------------- CHANGES ======= Version 2.5 ----------- 1. Changed the number lookup to set the denominator to 1 in cases of digits. This restores functional compatibility with John Cowan's UCType package. 2. Added support for the AL property. 3. Modified load and reload functions to return error codes. Version 2.4 ----------- 1. Improved some bidi algorithm documentation in the code. 2. Fixed a code mixup that produced a non-working version. Version 2.3 ----------- 1. Fixed a misspelling in the ucpgba.h header file. 2. Fixed a bug which caused trailing weak non-digit sequences to be left out of the reordered string in the bidi algorithm. 3. Fixed a problem with weak sequences containing non-spacing marks in the bidi algorithm. 4. Fixed a problem with text runs of the opposite direction of the string surrounding a weak + neutral text run appearing in the wrong order in the bidi algorithm. 5. Added a default overall direction parameter to the reordering function for cases of strings with no strong directional characters in the bidi algorithm. 6. The bidi API documentation was improved. 7. Added a man page for the bidi API. Version 2.2 ----------- 1. Fixed a problem with the bidi algorithm locating directional section boundaries. 2. Fixed a problem with the bidi algorithm starting the reordering correctly. 3. Fixed a problem with the bidi algorithm determining end boundaries for LTR segments. 4. Fixed a problem with the bidi algorithm reordering weak (digits and number separators) segments. 5. Added automatic switching of symmetrically paired characters when reversing RTL segments. 6. Added a missing symmetric character to the extra character properties in MUTTUCData.txt. 7. Added support for doing logical and visual cursor traversal. Version 2.1 ----------- 1. Updated the ucgendat program to handle the Unicode 3.0 character database properties. The AL and BM bidi properties gets marked as strong RTL and Other Neutral, the NSM, LRE, RLE, PDF, LRO, and RLO controls all get marked as Other Neutral. 2. Fixed some problems with testing against signed values in the UCData.java code and some minor cleanup. 3. Added the "Pretty Good Bidi Algorithm." Version 2.0 ----------- 1. Removed the old Java stuff for a new class that loads directly from the same data files as the C code does. 2. Fixed a problem with choosing the correct field when mapping case. 3. Adjust some search routines to start their search in the correct position. 4. Moved the copyright year to 1999. Version 1.9 ----------- 1. Fixed a problem with an incorrect amount of storage being allocated for the combining class nodes. 2. Fixed an invalid initialization in the number code. 3. Changed the Java template file formatting a bit. 4. Added tables and function for getting decompositions in the Java class. Version 1.8 ----------- 1. Fixed a problem with adding certain ranges. 2. Added two more macros for testing for identifiers. 3. Tested with the UnicodeData-2.1.5.txt file. Version 1.7 ----------- 1. Fixed a problem with looking up decompositions in "ucgendat." Version 1.6 ----------- 1. Added two new properties introduced with UnicodeData-2.1.4.txt. 2. Changed the "ucgendat.c" program a little to automatically align the property data on a 4-byte boundary when new properties are added. 3. Changed the "ucgendat.c" programs to only generate canonical decompositions. 4. Added two new macros ucisinitialpunct() and ucisfinalpunct() to check for initial and final punctuation characters. 5. Minor additions and changes to the documentation. Version 1.5 ----------- 1. Changed all file open calls to include binary mode with "b" for DOS/WIN platforms. 2. Wrapped the unistd.h include so it won't be included when compiled under Win32. 3. Fixed a bad range check for hex digits in ucgendat.c. 4. Fixed a bad endian swap for combining classes. 5. Added code to make a number table and associated lookup functions. Functions added are ucnumber(), ucdigit(), and ucgetnumber(). The last function is to maintain compatibility with John Cowan's "uctype" package. Version 1.4 ----------- 1. Fixed a bug with adding a range. 2. Fixed a bug with inserting a range in order. 3. Fixed incorrectly specified ucisdefined() and ucisundefined() macros. 4. Added the missing unload for the combining class data. 5. Fixed a bad macro placement in ucisweak(). Version 1.3 ----------- 1. Bug with case mapping calculations fixed. 2. Bug with empty character property entries fixed. 3. Bug with incorrect type in the combining class lookup fixed. 4. Some corrections done to api.txt. 5. Bug in certain character property lookups fixed. 6. Added a character property table that records the defined characters. 7. Replaced ucisunknown() with ucisdefined() and ucisundefined(). Version 1.2 ----------- 1. Added code to ucgendat to generate a combining class table. 2. Fixed an endian problem with the byte count of decompositions. 3. Fixed some minor problems in the "format.txt" file. 4. Removed some bogus "Ss" values from MUTTUCData.txt file. 5. Added API function to get combining class. 6. Changed the open mode to "rb" so binary data files will be opened correctly on DOS/WIN as well as other platforms. 7. Added the "api.txt" file. Version 1.1 ----------- 1. Added ucisxdigit() which I overlooked. 2. Added UC_LT to the ucisalpha() macro which I overlooked. 3. Change uciscntrl() to include UC_CF. 4. Added ucisocntrl() and ucfntcntrl() macros. 5. Added a ucisblank() which I overlooked. 6. Added missing properties to ucissymbol() and ucisnumber(). 7. Added ucisgraph() and ucisprint(). 8. Changed the "Mr" property to "Sy" to mark this subset of mirroring characters as symmetric to avoid trampling the Unicode/ISO10646 sense of mirroring. 9. Added another property called "Ss" which includes control characters traditionally seen as spaces in the isspace() macro. 10. Added a bunch of macros to be API compatible with John Cowan's package. ACKNOWLEDGEMENTS ================ Thanks go to John Cowan for pointing out lots of missing things and giving me stuff, particularly a bunch of new macros. Thanks go to Bob Verbrugge for pointing out various bugs. Thanks go to Christophe Pierret for pointing out that file modes need to have "b" for DOS/WIN machines, pointing out unistd.h is not a Win 32 header, and pointing out a problem with ucisalnum(). Thanks go to Kent Johnson for finding a bug that caused incomplete decompositions to be generated by the "ucgendat" program. Thanks go to Valeriy E. Ushakov for spotting an allocation error and an initialization error. Thanks go to Stig Venaas for providing a patch to support return types on load and reload, and for major updates to handle canonical composition and decomposition. krb5-1.22.1/src/lib/krb5/unicode/ucdata/ucdata.h0000664000175000017500000003226015051422640021045 0ustar ghudsonghudson/* * Copyright 1998-2008 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in file LICENSE in the * top-level directory of the distribution or, alternatively, at * . */ /* Copyright 2001 Computing Research Labs, New Mexico State University * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * This work is part of OpenLDAP Software . * $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucdata.h,v 1.21 2008/01/07 23:20:05 kurt Exp $ * $Id: ucdata.h,v 1.6 2001/01/02 18:46:20 mleisher Exp $ */ #ifndef _h_ucdata #define _h_ucdata #define UCDATA_VERSION "2.4" /************************************************************************** * * Masks and macros for character properties. * **************************************************************************/ /* * Values that can appear in the `mask1' parameter of the ucisprop() * function. */ #define UC_MN 0x00000001 /* Mark, Non-Spacing */ #define UC_MC 0x00000002 /* Mark, Spacing Combining */ #define UC_ME 0x00000004 /* Mark, Enclosing */ #define UC_ND 0x00000008 /* Number, Decimal Digit */ #define UC_NL 0x00000010 /* Number, Letter */ #define UC_NO 0x00000020 /* Number, Other */ #define UC_ZS 0x00000040 /* Separator, Space */ #define UC_ZL 0x00000080 /* Separator, Line */ #define UC_ZP 0x00000100 /* Separator, Paragraph */ #define UC_CC 0x00000200 /* Other, Control */ #define UC_CF 0x00000400 /* Other, Format */ #define UC_OS 0x00000800 /* Other, Surrogate */ #define UC_CO 0x00001000 /* Other, Private Use */ #define UC_CN 0x00002000 /* Other, Not Assigned */ #define UC_LU 0x00004000 /* Letter, Uppercase */ #define UC_LL 0x00008000 /* Letter, Lowercase */ #define UC_LT 0x00010000 /* Letter, Titlecase */ #define UC_LM 0x00020000 /* Letter, Modifier */ #define UC_LO 0x00040000 /* Letter, Other */ #define UC_PC 0x00080000 /* Punctuation, Connector */ #define UC_PD 0x00100000 /* Punctuation, Dash */ #define UC_PS 0x00200000 /* Punctuation, Open */ #define UC_PE 0x00400000 /* Punctuation, Close */ #define UC_PO 0x00800000 /* Punctuation, Other */ #define UC_SM 0x01000000 /* Symbol, Math */ #define UC_SC 0x02000000 /* Symbol, Currency */ #define UC_SK 0x04000000 /* Symbol, Modifier */ #define UC_SO 0x08000000 /* Symbol, Other */ #define UC_L 0x10000000 /* Left-To-Right */ #define UC_R 0x20000000 /* Right-To-Left */ #define UC_EN 0x40000000 /* European Number */ #define UC_ES 0x80000000 /* European Number Separator */ /* * Values that can appear in the `mask2' parameter of the ucisprop() * function. */ #define UC_ET 0x00000001 /* European Number Terminator */ #define UC_AN 0x00000002 /* Arabic Number */ #define UC_CS 0x00000004 /* Common Number Separator */ #define UC_B 0x00000008 /* Block Separator */ #define UC_S 0x00000010 /* Segment Separator */ #define UC_WS 0x00000020 /* Whitespace */ #define UC_ON 0x00000040 /* Other Neutrals */ /* * Implementation specific character properties. */ #define UC_CM 0x00000080 /* Composite */ #define UC_NB 0x00000100 /* Non-Breaking */ #define UC_SY 0x00000200 /* Symmetric */ #define UC_HD 0x00000400 /* Hex Digit */ #define UC_QM 0x00000800 /* Quote Mark */ #define UC_MR 0x00001000 /* Mirroring */ #define UC_SS 0x00002000 /* Space, other */ #define UC_CP 0x00004000 /* Defined */ /* * Added for UnicodeData-2.1.3. */ #define UC_PI 0x00008000 /* Punctuation, Initial */ #define UC_PF 0x00010000 /* Punctuation, Final */ /* * This is the primary function for testing to see if a character has some set * of properties. The macros that test for various character properties all * call this function with some set of masks. */ int ucisprop (krb5_ui_4 code, krb5_ui_4 mask1, krb5_ui_4 mask2); #define ucisalpha(cc) ucisprop(cc, UC_LU|UC_LL|UC_LM|UC_LO|UC_LT, 0) #define ucisdigit(cc) ucisprop(cc, UC_ND, 0) #define ucisalnum(cc) ucisprop(cc, UC_LU|UC_LL|UC_LM|UC_LO|UC_LT|UC_ND, 0) #define uciscntrl(cc) ucisprop(cc, UC_CC|UC_CF, 0) #define ucisspace(cc) ucisprop(cc, UC_ZS|UC_SS, 0) #define ucisblank(cc) ucisprop(cc, UC_ZS, 0) #define ucispunct(cc) ucisprop(cc, UC_PD|UC_PS|UC_PE|UC_PO, UC_PI|UC_PF) #define ucisgraph(cc) ucisprop(cc, UC_MN|UC_MC|UC_ME|UC_ND|UC_NL|UC_NO|\ UC_LU|UC_LL|UC_LT|UC_LM|UC_LO|UC_PC|UC_PD|\ UC_PS|UC_PE|UC_PO|UC_SM|UC_SM|UC_SC|UC_SK|\ UC_SO, UC_PI|UC_PF) #define ucisprint(cc) ucisprop(cc, UC_MN|UC_MC|UC_ME|UC_ND|UC_NL|UC_NO|\ UC_LU|UC_LL|UC_LT|UC_LM|UC_LO|UC_PC|UC_PD|\ UC_PS|UC_PE|UC_PO|UC_SM|UC_SM|UC_SC|UC_SK|\ UC_SO|UC_ZS, UC_PI|UC_PF) #define ucisupper(cc) ucisprop(cc, UC_LU, 0) #define ucislower(cc) ucisprop(cc, UC_LL, 0) #define ucistitle(cc) ucisprop(cc, UC_LT, 0) #define ucisxdigit(cc) ucisprop(cc, 0, UC_HD) #define ucisisocntrl(cc) ucisprop(cc, UC_CC, 0) #define ucisfmtcntrl(cc) ucisprop(cc, UC_CF, 0) #define ucissymbol(cc) ucisprop(cc, UC_SM|UC_SC|UC_SO|UC_SK, 0) #define ucisnumber(cc) ucisprop(cc, UC_ND|UC_NO|UC_NL, 0) #define ucisnonspacing(cc) ucisprop(cc, UC_MN, 0) #define ucisopenpunct(cc) ucisprop(cc, UC_PS, 0) #define ucisclosepunct(cc) ucisprop(cc, UC_PE, 0) #define ucisinitialpunct(cc) ucisprop(cc, 0, UC_PI) #define ucisfinalpunct(cc) ucisprop(cc, 0, UC_PF) #define uciscomposite(cc) ucisprop(cc, 0, UC_CM) #define ucishex(cc) ucisprop(cc, 0, UC_HD) #define ucisquote(cc) ucisprop(cc, 0, UC_QM) #define ucissymmetric(cc) ucisprop(cc, 0, UC_SY) #define ucismirroring(cc) ucisprop(cc, 0, UC_MR) #define ucisnonbreaking(cc) ucisprop(cc, 0, UC_NB) /* * Directionality macros. */ #define ucisrtl(cc) ucisprop(cc, UC_R, 0) #define ucisltr(cc) ucisprop(cc, UC_L, 0) #define ucisstrong(cc) ucisprop(cc, UC_L|UC_R, 0) #define ucisweak(cc) ucisprop(cc, UC_EN|UC_ES, UC_ET|UC_AN|UC_CS) #define ucisneutral(cc) ucisprop(cc, 0, UC_B|UC_S|UC_WS|UC_ON) #define ucisseparator(cc) ucisprop(cc, 0, UC_B|UC_S) /* * Other macros inspired by John Cowan. */ #define ucismark(cc) ucisprop(cc, UC_MN|UC_MC|UC_ME, 0) #define ucismodif(cc) ucisprop(cc, UC_LM, 0) #define ucisletnum(cc) ucisprop(cc, UC_NL, 0) #define ucisconnect(cc) ucisprop(cc, UC_PC, 0) #define ucisdash(cc) ucisprop(cc, UC_PD, 0) #define ucismath(cc) ucisprop(cc, UC_SM, 0) #define uciscurrency(cc) ucisprop(cc, UC_SC, 0) #define ucismodifsymbol(cc) ucisprop(cc, UC_SK, 0) #define ucisnsmark(cc) ucisprop(cc, UC_MN, 0) #define ucisspmark(cc) ucisprop(cc, UC_MC, 0) #define ucisenclosing(cc) ucisprop(cc, UC_ME, 0) #define ucisprivate(cc) ucisprop(cc, UC_CO, 0) #define ucissurrogate(cc) ucisprop(cc, UC_OS, 0) #define ucislsep(cc) ucisprop(cc, UC_ZL, 0) #define ucispsep(cc) ucisprop(cc, UC_ZP, 0) #define ucisidentstart(cc) ucisprop(cc, UC_LU|UC_LL|UC_LT|UC_LO|UC_NL, 0) #define ucisidentpart(cc) ucisprop(cc, UC_LU|UC_LL|UC_LT|UC_LO|UC_NL|\ UC_MN|UC_MC|UC_ND|UC_PC|UC_CF, 0) #define ucisdefined(cc) ucisprop(cc, 0, UC_CP) #define ucisundefined(cc) !ucisprop(cc, 0, UC_CP) /* * Other miscellaneous character property macros. */ #define ucishan(cc) (((cc) >= 0x4e00 && (cc) <= 0x9fff) ||\ ((cc) >= 0xf900 && (cc) <= 0xfaff)) #define ucishangul(cc) ((cc) >= 0xac00 && (cc) <= 0xd7ff) /************************************************************************** * * Functions for case conversion. * **************************************************************************/ krb5_ui_4 uctoupper(krb5_ui_4 code); krb5_ui_4 uctolower(krb5_ui_4 code); krb5_ui_4 uctotitle(krb5_ui_4 code); /************************************************************************** * * Functions for getting compositions. * **************************************************************************/ /* * This routine determines if there exists a composition of node1 and node2. * If it returns 0, there is no composition. Any other value indicates a * composition was returned in comp. */ int uccomp(krb5_ui_4 node1, krb5_ui_4 node2, krb5_ui_4 *comp); /* * Does Hangul composition on the string str with length len, and returns * the length of the composed string. */ int uccomp_hangul(krb5_ui_4 *str, int len); /* * Does canonical composition on the string str with length len, and returns * the length of the composed string. */ int uccanoncomp(krb5_ui_4 *str, int len); /************************************************************************** * * Functions for getting decompositions. * **************************************************************************/ /* * This routine determines if the code has a decomposition. If it returns 0, * there is no decomposition. Any other value indicates a decomposition was * returned. */ int ucdecomp(krb5_ui_4 code, krb5_ui_4 *num, krb5_ui_4 **decomp); /* * Equivalent to ucdecomp() except that it includes compatibility * decompositions. */ int uckdecomp(krb5_ui_4 code, krb5_ui_4 *num, krb5_ui_4 **decomp); /* * If the code is a Hangul syllable, this routine decomposes it into the array * passed. The array size should be at least 3. */ int ucdecomp_hangul(krb5_ui_4 code, krb5_ui_4 *num, krb5_ui_4 decomp[]); /* * This routine does canonical decomposition of the string in of length * inlen, and returns the decomposed string in out with length outlen. * The memory for out is allocated by this routine. It returns the length * of the decomposed string if okay, and -1 on error. */ int uccanondecomp (const krb5_ui_4 *in, int inlen, krb5_ui_4 **out, int *outlen); /* * Equivalent to uccanondecomp() except that it includes compatibility * decompositions. */ int uccompatdecomp(const krb5_ui_4 *in, int inlen, krb5_ui_4 **out, int *outlen); /************************************************************************** * * Functions for getting combining classes. * **************************************************************************/ /* * This will return the combining class for a character to be used with the * Canonical Ordering algorithm. */ krb5_ui_4 uccombining_class(krb5_ui_4 code); /************************************************************************** * * Functions for getting numbers and digits. * **************************************************************************/ struct ucnumber { int numerator; int denominator; }; int ucnumber_lookup (krb5_ui_4 code, struct ucnumber *num); int ucdigit_lookup (krb5_ui_4 code, int *digit); /* * For compatibility with John Cowan's "uctype" package. */ struct ucnumber ucgetnumber (krb5_ui_4 code); int ucgetdigit (krb5_ui_4 code); /************************************************************************** * * Functions library initialization and cleanup. * **************************************************************************/ /* * Macros for specifying the data tables to be loaded, unloaded, or reloaded * by the ucdata_load(), ucdata_unload(), and ucdata_reload() routines. */ #define UCDATA_CASE 0x01 #define UCDATA_CTYPE 0x02 #define UCDATA_DECOMP 0x04 #define UCDATA_CMBCL 0x08 #define UCDATA_NUM 0x10 #define UCDATA_COMP 0x20 #define UCDATA_KDECOMP 0x40 #define UCDATA_ALL (UCDATA_CASE|UCDATA_CTYPE|UCDATA_DECOMP|\ UCDATA_CMBCL|UCDATA_NUM|UCDATA_COMP|UCDATA_KDECOMP) /* * Functions to load, unload, and reload specific data files. */ int ucdata_load (char *paths, int mask); void ucdata_unload (int mask); int ucdata_reload (char *paths, int mask); #ifdef UCDATA_DEPRECATED /* * Deprecated functions, now just compatibility macros. */ #define ucdata_setup(p) ucdata_load(p, UCDATA_ALL) #define ucdata_cleanup() ucdata_unload(UCDATA_ALL) #endif #endif /* _h_ucdata */ krb5-1.22.1/src/lib/krb5/unicode/ucdata/MUTTUCData.txt0000664000175000017500000002346615051422640022017 0ustar ghudsonghudson# # $Id: MUTTUCData.txt,v 1.3 1999/10/29 00:04:35 mleisher Exp $ # # Copyright 1999 Computing Research Labs, New Mexico State University # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT # OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR # THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # # Implementation specific character properties. # # # Space, other. # 0009;;Ss;;;;;;;;;;;; 000A;;Ss;;;;;;;;;;;; 000B;;Ss;;;;;;;;;;;; 000C;;Ss;;;;;;;;;;;; 000D;;Ss;;;;;;;;;;;; # # Non-breaking. # 00A0;;Nb;;;;;;;;;;;; 2007;;Nb;;;;;;;;;;;; 2011;;Nb;;;;;;;;;;;; FEFF;;Nb;;;;;;;;;;;; # # Symmetric. # 0028;;Sy;;;;;;;;;;;; 0029;;Sy;;;;;;;;;;;; 005B;;Sy;;;;;;;;;;;; 005D;;Sy;;;;;;;;;;;; 007B;;Sy;;;;;;;;;;;; 007D;;Sy;;;;;;;;;;;; 00AB;;Sy;;;;;;;;;;;; 00BB;;Sy;;;;;;;;;;;; 0F3A;;Sy;;;;;;;;;;;; 0F3B;;Sy;;;;;;;;;;;; 0F3C;;Sy;;;;;;;;;;;; 0F3D;;Sy;;;;;;;;;;;; 0F3E;;Sy;;;;;;;;;;;; 0F3F;;Sy;;;;;;;;;;;; 2018;;Sy;;;;;;;;;;;; 2019;;Sy;;;;;;;;;;;; 201A;;Sy;;;;;;;;;;;; 201B;;Sy;;;;;;;;;;;; 201C;;Sy;;;;;;;;;;;; 201D;;Sy;;;;;;;;;;;; 201E;;Sy;;;;;;;;;;;; 201F;;Sy;;;;;;;;;;;; 2039;;Sy;;;;;;;;;;;; 203A;;Sy;;;;;;;;;;;; 2045;;Sy;;;;;;;;;;;; 2046;;Sy;;;;;;;;;;;; 207D;;Sy;;;;;;;;;;;; 207E;;Sy;;;;;;;;;;;; 208D;;Sy;;;;;;;;;;;; 208E;;Sy;;;;;;;;;;;; 2329;;Sy;;;;;;;;;;;; 232A;;Sy;;;;;;;;;;;; 3008;;Sy;;;;;;;;;;;; 3009;;Sy;;;;;;;;;;;; 300A;;Sy;;;;;;;;;;;; 300B;;Sy;;;;;;;;;;;; 300C;;Sy;;;;;;;;;;;; 300D;;Sy;;;;;;;;;;;; 300E;;Sy;;;;;;;;;;;; 300F;;Sy;;;;;;;;;;;; 3010;;Sy;;;;;;;;;;;; 3011;;Sy;;;;;;;;;;;; 3014;;Sy;;;;;;;;;;;; 3015;;Sy;;;;;;;;;;;; 3016;;Sy;;;;;;;;;;;; 3017;;Sy;;;;;;;;;;;; 3018;;Sy;;;;;;;;;;;; 3019;;Sy;;;;;;;;;;;; 301A;;Sy;;;;;;;;;;;; 301B;;Sy;;;;;;;;;;;; 301D;;Sy;;;;;;;;;;;; 301E;;Sy;;;;;;;;;;;; 301F;;Sy;;;;;;;;;;;; FD3E;;Sy;;;;;;;;;;;; FD3F;;Sy;;;;;;;;;;;; FE35;;Sy;;;;;;;;;;;; FE36;;Sy;;;;;;;;;;;; FE37;;Sy;;;;;;;;;;;; FE38;;Sy;;;;;;;;;;;; FE39;;Sy;;;;;;;;;;;; FE3A;;Sy;;;;;;;;;;;; FE3B;;Sy;;;;;;;;;;;; FE3C;;Sy;;;;;;;;;;;; FE3D;;Sy;;;;;;;;;;;; FE3E;;Sy;;;;;;;;;;;; FE3F;;Sy;;;;;;;;;;;; FE40;;Sy;;;;;;;;;;;; FE41;;Sy;;;;;;;;;;;; FE42;;Sy;;;;;;;;;;;; FE43;;Sy;;;;;;;;;;;; FE44;;Sy;;;;;;;;;;;; FE59;;Sy;;;;;;;;;;;; FE5A;;Sy;;;;;;;;;;;; FE5B;;Sy;;;;;;;;;;;; FE5C;;Sy;;;;;;;;;;;; FE5D;;Sy;;;;;;;;;;;; FE5E;;Sy;;;;;;;;;;;; FF08;;Sy;;;;;;;;;;;; FF09;;Sy;;;;;;;;;;;; FF3B;;Sy;;;;;;;;;;;; FF3D;;Sy;;;;;;;;;;;; FF5B;;Sy;;;;;;;;;;;; FF5D;;Sy;;;;;;;;;;;; FF62;;Sy;;;;;;;;;;;; FF63;;Sy;;;;;;;;;;;; # # Hex digit. # 0030;;Hd;;;;;;;;;;;; 0031;;Hd;;;;;;;;;;;; 0032;;Hd;;;;;;;;;;;; 0033;;Hd;;;;;;;;;;;; 0034;;Hd;;;;;;;;;;;; 0035;;Hd;;;;;;;;;;;; 0036;;Hd;;;;;;;;;;;; 0037;;Hd;;;;;;;;;;;; 0038;;Hd;;;;;;;;;;;; 0039;;Hd;;;;;;;;;;;; 0041;;Hd;;;;;;;;;;;; 0042;;Hd;;;;;;;;;;;; 0043;;Hd;;;;;;;;;;;; 0044;;Hd;;;;;;;;;;;; 0045;;Hd;;;;;;;;;;;; 0046;;Hd;;;;;;;;;;;; 0061;;Hd;;;;;;;;;;;; 0062;;Hd;;;;;;;;;;;; 0063;;Hd;;;;;;;;;;;; 0064;;Hd;;;;;;;;;;;; 0065;;Hd;;;;;;;;;;;; 0066;;Hd;;;;;;;;;;;; FF10;;Hd;;;;;;;;;;;; FF11;;Hd;;;;;;;;;;;; FF12;;Hd;;;;;;;;;;;; FF13;;Hd;;;;;;;;;;;; FF14;;Hd;;;;;;;;;;;; FF15;;Hd;;;;;;;;;;;; FF16;;Hd;;;;;;;;;;;; FF17;;Hd;;;;;;;;;;;; FF18;;Hd;;;;;;;;;;;; FF19;;Hd;;;;;;;;;;;; FF21;;Hd;;;;;;;;;;;; FF22;;Hd;;;;;;;;;;;; FF23;;Hd;;;;;;;;;;;; FF24;;Hd;;;;;;;;;;;; FF25;;Hd;;;;;;;;;;;; FF26;;Hd;;;;;;;;;;;; FF41;;Hd;;;;;;;;;;;; FF42;;Hd;;;;;;;;;;;; FF43;;Hd;;;;;;;;;;;; FF44;;Hd;;;;;;;;;;;; FF45;;Hd;;;;;;;;;;;; FF46;;Hd;;;;;;;;;;;; # # Quote marks. # 0022;;Qm;;;;;;;;;;;; 0027;;Qm;;;;;;;;;;;; 00AB;;Qm;;;;;;;;;;;; 00BB;;Qm;;;;;;;;;;;; 2018;;Qm;;;;;;;;;;;; 2019;;Qm;;;;;;;;;;;; 201A;;Qm;;;;;;;;;;;; 201B;;Qm;;;;;;;;;;;; 201C;;Qm;;;;;;;;;;;; 201D;;Qm;;;;;;;;;;;; 201E;;Qm;;;;;;;;;;;; 201F;;Qm;;;;;;;;;;;; 2039;;Qm;;;;;;;;;;;; 203A;;Qm;;;;;;;;;;;; 300C;;Qm;;;;;;;;;;;; 300D;;Qm;;;;;;;;;;;; 300E;;Qm;;;;;;;;;;;; 300F;;Qm;;;;;;;;;;;; 301D;;Qm;;;;;;;;;;;; 301E;;Qm;;;;;;;;;;;; 301F;;Qm;;;;;;;;;;;; FE41;;Qm;;;;;;;;;;;; FE42;;Qm;;;;;;;;;;;; FE43;;Qm;;;;;;;;;;;; FE44;;Qm;;;;;;;;;;;; FF02;;Qm;;;;;;;;;;;; FF07;;Qm;;;;;;;;;;;; FF62;;Qm;;;;;;;;;;;; FF63;;Qm;;;;;;;;;;;; # # Special Devanagari forms # E900;DEVANAGARI KSHA LIGATURE;Lo;0;L;0915 094D 0937;;;;N;;;;; E901;DEVANAGARI GNYA LIGATURE;Lo;0;L;091C 094D 091E;;;;N;;;;; E902;DEVANAGARI TTA LIGATURE;Lo;0;L;0924 094D 0924;;;;N;;;;; E903;DEVANAGARI TRA LIGATURE;Lo;0;L;0924 094D 0930;;;;N;;;;; E904;DEVANAGARI SHCHA LIGATURE;Lo;0;L;0936 094D 091B;;;;N;;;;; E905;DEVANAGARI SHRA LIGATURE;Lo;0;L;0936 094D 0930;;;;N;;;;; E906;DEVANAGARI SHVA LIGATURE;Lo;0;L;0936 094D 0935;;;;N;;;;; E907;DEVANAGARI KRA LIGATURE;Lo;0;L;;;;;N;;;;; E908;DEVANAGARI JRA LIGATURE;Lo;0;L;;;;;N;;;;; E909;DEVANAGARI ZRA LIGATURE;Lo;0;L;;;;;N;;;;; E90A;DEVANAGARI PHRA LIGATURE;Lo;0;L;;;;;N;;;;; E90B;DEVANAGARI FRA LIGATURE;Lo;0;L;;;;;N;;;;; E90C;DEVANAGARI PRA LIGATURE;Lo;0;L;;;;;N;;;;; E90D;DEVANAGARI SRA LIGATURE;Lo;0;L;;;;;N;;;;; E90E;DEVANAGARI RU LIGATURE;Lo;0;L;;;;;N;;;;; E90F;DEVANAGARI RUU LIGATURE;Lo;0;L;;;;;N;;;;; E915;DEVANAGARI HALF LETTER KA;Lo;0;L;;;;;N;;;;; E916;DEVANAGARI HALF LETTER KHA;Lo;0;L;;;;;N;;;;; E917;DEVANAGARI HALF LETTER GA;Lo;0;L;;;;;N;;;;; E918;DEVANAGARI HALF LETTER GHA;Lo;0;L;;;;;N;;;;; E919;DEVANAGARI HALF LETTER NGA;Lo;0;L;;;;;N;;;;; E91A;DEVANAGARI HALF LETTER CA;Lo;0;L;;;;;N;;;;; E91B;DEVANAGARI HALF LETTER CHA;Lo;0;L;;;;;N;;;;; E91C;DEVANAGARI HALF LETTER JA;Lo;0;L;;;;;N;;;;; E91D;DEVANAGARI HALF LETTER JHA;Lo;0;L;;;;;N;;;;; E91E;DEVANAGARI HALF LETTER NYA;Lo;0;L;;;;;N;;;;; E91F;DEVANAGARI HALF LETTER TTA;Lo;0;L;;;;;N;;;;; E920;DEVANAGARI HALF LETTER TTHA;Lo;0;L;;;;;N;;;;; E921;DEVANAGARI HALF LETTER DDA;Lo;0;L;;;;;N;;;;; E922;DEVANAGARI HALF LETTER DDHA;Lo;0;L;;;;;N;;;;; E923;DEVANAGARI HALF LETTER NNA;Lo;0;L;;;;;N;;;;; E924;DEVANAGARI HALF LETTER TA;Lo;0;L;;;;;N;;;;; E925;DEVANAGARI HALF LETTER THA;Lo;0;L;;;;;N;;;;; E926;DEVANAGARI HALF LETTER DA;Lo;0;L;;;;;N;;;;; E927;DEVANAGARI HALF LETTER DHA;Lo;0;L;;;;;N;;;;; E928;DEVANAGARI HALF LETTER NA;Lo;0;L;;;;;N;;;;; E929;DEVANAGARI HALF LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;; E92A;DEVANAGARI HALF LETTER PA;Lo;0;L;;;;;N;;;;; E92B;DEVANAGARI HALF LETTER PHA;Lo;0;L;;;;;N;;;;; E92C;DEVANAGARI HALF LETTER BA;Lo;0;L;;;;;N;;;;; E92D;DEVANAGARI HALF LETTER BHA;Lo;0;L;;;;;N;;;;; E92E;DEVANAGARI HALF LETTER MA;Lo;0;L;;;;;N;;;;; E92F;DEVANAGARI HALF LETTER YA;Lo;0;L;;;;;N;;;;; E930;DEVANAGARI HALF LETTER RA;Lo;0;L;;;;;N;;;;; E931;DEVANAGARI HALF LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;; E932;DEVANAGARI HALF LETTER LA;Lo;0;L;;;;;N;;;;; E933;DEVANAGARI HALF LETTER LLA;Lo;0;L;;;;;N;;;;; E934;DEVANAGARI HALF LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;; E935;DEVANAGARI HALF LETTER VA;Lo;0;L;;;;;N;;;;; E936;DEVANAGARI HALF LETTER SHA;Lo;0;L;;;;;N;;;;; E937;DEVANAGARI HALF LETTER SSA;Lo;0;L;;;;;N;;;;; E938;DEVANAGARI HALF LETTER SA;Lo;0;L;;;;;N;;;;; E939;DEVANAGARI HALF LETTER HA;Lo;0;L;;;;;N;;;;; E940;DEVANAGARI KKA LIGATURE;Lo;0;L;0915 094D 0915;;;;N;;;;; E941;DEVANAGARI KTA LIGATURE;Lo;0;L;0915 094D 0924;;;;N;;;;; E942;DEVANAGARI NGKA LIGATURE;Lo;0;L;0919 094D 0915;;;;N;;;;; E943;DEVANAGARI NGKHA LIGATURE;Lo;0;L;0919 094D 0916;;;;N;;;;; E944;DEVANAGARI NGGA LIGATURE;Lo;0;L;0919 094D 0917;;;;N;;;;; E945;DEVANAGARI NGGHA LIGATURE;Lo;0;L;0919 094D 0918;;;;N;;;;; E946;DEVANAGARI NYJA LIGATURE;Lo;0;L;091E 094D 091C;;;;N;;;;; E947;DEVANAGARI DGHA LIGATURE;Lo;0;L;0926 094D 0918;;;;N;;;;; E948;DEVANAGARI DDA LIGATURE;Lo;0;L;0926 094D 0926;;;;N;;;;; E949;DEVANAGARI DDHA LIGATURE;Lo;0;L;0926 094D 0927;;;;N;;;;; E94A;DEVANAGARI DBA LIGATURE;Lo;0;L;0926 094D 092C;;;;N;;;;; E94B;DEVANAGARI DBHA LIGATURE;Lo;0;L;0926 094D 092D;;;;N;;;;; E94C;DEVANAGARI DMA LIGATURE;Lo;0;L;0926 094D 092E;;;;N;;;;; E94D;DEVANAGARI DYA LIGATURE;Lo;0;L;0926 094D 092F;;;;N;;;;; E94E;DEVANAGARI DVA LIGATURE;Lo;0;L;0926 094D 0935;;;;N;;;;; E94F;DEVANAGARI TT-TTA LIGATURE;Lo;0;L;091F 094D 091F;;;;N;;;;; E950;DEVANAGARI TT-TTHA LIGATURE;Lo;0;L;091F 094D 0920;;;;N;;;;; E951;DEVANAGARI TTH-TTHA LIGATURE;Lo;0;L;0920 094D 0920;;;;N;;;;; E952;DEVANAGARI DD-GA LIGATURE;Lo;0;L;0921 094D 0917;;;;N;;;;; E953;DEVANAGARI DD-DDA LIGATURE;Lo;0;L;0921 094D 0921;;;;N;;;;; E954;DEVANAGARI DD-DDHA LIGATURE;Lo;0;L;0921 094D 0922;;;;N;;;;; E955;DEVANAGARI NNA LIGATURE;Lo;0;L;0928 094D 0928;;;;N;;;;; E956;DEVANAGARI HMA LIGATURE;Lo;0;L;0939 094D 092E;;;;N;;;;; E957;DEVANAGARI HYA LIGATURE;Lo;0;L;0939 094D 092F;;;;N;;;;; E958;DEVANAGARI HLA LIGATURE;Lo;0;L;0939 094D 0932;;;;N;;;;; E959;DEVANAGARI HVA LIGATURE;Lo;0;L;0939 094D 0935;;;;N;;;;; E95A;DEVANAGARI STRA LIGATURE;Lo;0;L;0938 094D 0924 094D 0930;;;;N;;;;; E970;DEVANAGARI HALF KSHA LIGATURE;Lo;0;L;0915 094D 0937;;;;N;;;;; E971;DEVANAGARI HALF GNYA LIGATURE;Lo;0;L;091C 094D 091E;;;;N;;;;; E972;DEVANAGARI HALF TTA LIGATURE;Lo;0;L;0924 094D 0924;;;;N;;;;; E973;DEVANAGARI HALF TRA LIGATURE;Lo;0;L;0924 094D 0930;;;;N;;;;; E974;DEVANAGARI HALF SHCHA LIGATURE;Lo;0;L;0936 094D 091B;;;;N;;;;; E975;DEVANAGARI HALF SHRA LIGATURE;Lo;0;L;0936 094D 0930;;;;N;;;;; E976;DEVANAGARI HALF SHVA LIGATURE;Lo;0;L;0936 094D 0935;;;;N;;;;; E97B;DEVANAGARI SIGN RRA-REPHA;Mn;36;L;;;;;N;;;;; E97C;DEVANAGARI HAR LIGATURE;Lo;0;L;0939 0943;;;;N;;;;; E97D;DEVANAGARI SIGN EYELASH RA;Lo;0;L;;;;;N;;;;; E97E;DEVANAGARI SIGN REPHA;Mn;36;L;;;;;N;;;;; E97F;DEVANAGARI SIGN SUBJOINED RA;Mn;36;L;;;;;N;;;;; krb5-1.22.1/src/lib/krb5/unicode/ucdata/ucdata.man0000664000175000017500000002774215051422640021402 0ustar ghudsonghudson.\" .\" $Id: ucdata.man,v 1.5 2001/01/02 18:46:20 mleisher Exp $ .\" .TH ucdata 3 "03 January 2001" .SH NAME ucdata \- package for providing Unicode/ISO10646 character information .SH SYNOPSIS #include .sp void ucdata_load(char * paths, int masks) .sp void ucdata_unload(int masks) .sp void ucdata_reload(char * paths, int masks) .sp int ucdecomp(unsigned long code, unsigned long *num, unsigned long **decomp) .sp int uccanondecomp(const unsigned long *in, int inlen, unsigned long **out, int *outlen) .sp int ucdecomp_hangul(unsigned long code, unsigned long *num, unsigned long decomp[]) .sp int uccomp(unsigned long ch1, unsigned long ch2, unsigned long *comp) .sp int uccomp_hangul(unsigned long *str, int len) .sp int uccanoncomp(unsiged long *str, int len) .nf struct ucnumber { int numerator; int denominator; }; .sp int ucnumber_lookup(unsigned long code, struct ucnumber *num) .sp int ucdigit_lookup(unsigned long code, int *digit) .sp struct ucnumber ucgetnumber(unsigned long code) .sp int ucgetdigit(unsigned long code) .sp unsigned long uctoupper(unsigned long code) .sp unsigned long uctolower(unsigned long code) .sp unsigned long uctotitle(unsigned long code) .sp int ucisalpha(unsigned long code) .sp int ucisalnum(unsigned long code) .sp int ucisdigit(unsigned long code) .sp int uciscntrl(unsigned long code) .sp int ucisspace(unsigned long code) .sp int ucisblank(unsigned long code) .sp int ucispunct(unsigned long code) .sp int ucisgraph(unsigned long code) .sp int ucisprint(unsigned long code) .sp int ucisxdigit(unsigned long code) .sp int ucisupper(unsigned long code) .sp int ucislower(unsigned long code) .sp int ucistitle(unsigned long code) .sp int ucisisocntrl(unsigned long code) .sp int ucisfmtcntrl(unsigned long code) .sp int ucissymbol(unsigned long code) .sp int ucisnumber(unsigned long code) .sp int ucisnonspacing(unsigned long code) .sp int ucisopenpunct(unsigned long code) .sp int ucisclosepunct(unsigned long code) .sp int ucisinitialpunct(unsigned long code) .sp int ucisfinalpunct(unsigned long code) .sp int uciscomposite(unsigned long code) .sp int ucisquote(unsigned long code) .sp int ucissymmetric(unsigned long code) .sp int ucismirroring(unsigned long code) .sp int ucisnonbreaking(unsigned long code) .sp int ucisrtl(unsigned long code) .sp int ucisltr(unsigned long code) .sp int ucisstrong(unsigned long code) .sp int ucisweak(unsigned long code) .sp int ucisneutral(unsigned long code) .sp int ucisseparator(unsigned long code) .sp int ucislsep(unsigned long code) .sp int ucispsep(unsigned long code) .sp int ucismark(unsigned long code) .sp int ucisnsmark(unsigned long code) .sp int ucisspmark(unsigned long code) .sp int ucismodif(unsigned long code) .sp int ucismodifsymbol(unsigned long code) .sp int ucisletnum(unsigned long code) .sp int ucisconnect(unsigned long code) .sp int ucisdash(unsigned long code) .sp int ucismath(unsigned long code) .sp int uciscurrency(unsigned long code) .sp int ucisenclosing(unsigned long code) .sp int ucisprivate(unsigned long code) .sp int ucissurrogate(unsigned long code) .sp int ucisidentstart(unsigned long code) .sp int ucisidentpart(unsigned long code) .sp int ucisdefined(unsigned long code) .sp int ucisundefined(unsigned long code) .sp int ucishan(unsigned long code) .sp int ucishangul(unsigned long code) .SH DESCRIPTION .TP 4 .BR Macros .br UCDATA_CASE .br UCDATA_CTYPE .br UCDATA_DECOMP .br UCDATA_CMBCL .br UCDATA_NUM .br UCDATA_ALL .br .TP 4 .BR ucdata_load() This function initializes the UCData library by locating the data files in one of the colon-separated directories in the `paths' parameter. The data files to be loaded are specified in the `masks' parameter as a bitwise combination of the macros listed above. .sp This should be called before using any of the other functions. .TP 4 .BR ucdata_unload() This function unloads the data tables specified in the `masks' parameter. .sp This function should be called when the application is done using the UCData package. .TP 4 .BR ucdata_reload() This function reloads the data files from one of the colon-separated directories in the `paths' parameter. The data files to be reloaded are specified in the `masks' parameter as a bitwise combination of the macros listed above. .TP 4 .BR ucdecomp() This function determines if a character has a decomposition and returns the decomposition information if it exists. .sp If a zero is returned, there is no decomposition. If a non-zero is returned, then the `num' and `decomp' variables are filled in with the appropriate values. .sp Example call: .sp .nf unsigned long i, num, *decomp; if (ucdecomp(0x1d5, &num, &decomp) != 0) { for (i = 0; i < num; i++) printf("0x%08lX,", decomp[i]); putchar('\n'); } .TP 4 .BR uccanondecomp() This function will decompose a string, insuring the characters are in canonical order for comparison. .sp If a decomposed string is returned, the caller is responsible for deallocating the string. .sp If a -1 is returned, memory allocation failed. If a zero is returned, no decomposition was done. Any other value means a decomposition string was created and the values returned in the `out' and `outlen' parameters. .TP 4 .BR ucdecomp_hangul() This function determines if a Hangul syllable has a decomposition and returns the decomposition information. .sp An array of at least size 3 should be passed to the function for the decomposition of the syllable. .sp If a zero is returned, the character is not a Hangul syllable. If a non-zero is returned, the `num' field will be 2 or 3 and the syllable will be decomposed into the `decomp' array arithmetically. .sp Example call: .sp .nf unsigned long i, num, decomp[3]; if (ucdecomp_hangul(0xb1ba, &num, &decomp) != 0) { for (i = 0; i < num; i++) printf("0x%08lX,", decomp[i]); putchar('\n'); } .TP 4 .BR uccomp() This function determines if a pair of characters have a composition, and returns that composition if one exists. .sp A zero is returned is no composition exists for the character pair. Any other value indicates the `comp' field holds the character code representing the composition of the two character codes. .TP 4 .BR uccomp_hangul() This composes the Hangul Jamo in-place in the string. .sp The returned value is the new length of the string. .TP 4 .BR uccanoncomp() This function does a full composition in-place in the string, including the Hangul composition. .sp The returned value is the new length of the string. .TP 4 .BR ucnumber_lookup() This function determines if the code is a number and fills in the `num' field with the numerator and denominator. If the code happens to be a single digit, the numerator and denominator fields will be the same. .sp If the function returns 0, the code is not a number. Any other return value means the code is a number. .TP 4 .BR ucdigit_lookup() This function determines if the code is a digit and fills in the `digit' field with the digit value. .sp If the function returns 0, the code is not a number. Any other return value means the code is a number. .TP 4 .BR ucgetnumber() This is a compatibility function with John Cowan's "uctype" package. It uses ucnumber_lookup(). .TP 4 .BR ucgetdigit() This is a compatibility function with John Cowan's "uctype" package. It uses ucdigit_lookup(). .TP 4 .BR uctoupper() This function returns the code unchanged if it is already upper case or has no upper case equivalent. Otherwise the upper case equivalent is returned. .TP 4 .BR uctolower() This function returns the code unchanged if it is already lower case or has no lower case equivalent. Otherwise the lower case equivalent is returned. .TP 4 .BR uctotitle() This function returns the code unchanged if it is already title case or has no title case equivalent. Otherwise the title case equivalent is returned. .TP 4 .BR ucisalpha() Test if \fIcode\fR is an alpha character. .TP 4 .BR ucisalnum() Test if \fIcode\fR is an alpha or digit character. .TP 4 .BR ucisdigit() Test if \fIcode\fR is a digit character. .TP 4 .BR uciscntrl() Test if \fIcode\fR is a control character. .TP 4 .BR ucisspace() Test if \fIcode\fR is a space character. .TP 4 .BR ucisblank() Test if \fIcode\fR is a blank character. .TP 4 .BR ucispunct() Test if \fIcode\fR is a punctuation character. .TP 4 .BR ucisgraph() Test if \fIcode\fR is a graphical (visible) character. .TP 4 .BR ucisprint() Test if \fIcode\fR is a printable character. .TP 4 .BR ucisxdigit() Test if \fIcode\fR is a hexadecimal digit character. .TP 4 .BR ucisupper() Test if \fIcode\fR is an upper case character. .TP 4 .BR ucislower() Test if \fIcode\fR is a lower case character. .TP 4 .BR ucistitle() Test if \fIcode\fR is a title case character. .TP 4 .BR ucisisocntrl() Is the character a C0 control character (< 32)? .TP 4 .BR ucisfmtcntrl() Is the character a format control character? .TP 4 .BR ucissymbol() Is the character a symbol? .TP 4 .BR ucisnumber() Is the character a number or digit? .TP 4 .BR ucisnonspacing() Is the character non-spacing? .TP 4 .BR ucisopenpunct() Is the character an open/left punctuation (i.e. '[') .TP 4 .BR ucisclosepunct() Is the character an close/right punctuation (i.e. ']') .TP 4 .BR ucisinitialpunct() Is the character an initial punctuation (i.e. U+2018 LEFT SINGLE QUOTATION MARK) .TP 4 .BR ucisfinalpunct() Is the character a final punctuation (i.e. U+2019 RIGHT SINGLE QUOTATION MARK) .TP 4 .BR uciscomposite() Can the character be decomposed into a set of other characters? .TP 4 .BR ucisquote() Is the character one of the many quotation marks? .TP 4 .BR ucissymmetric() Is the character one that has an opposite form (i.e. <>) .TP 4 .BR ucismirroring() Is the character mirroring (superset of symmetric)? .TP 4 .BR ucisnonbreaking() Is the character non-breaking (i.e. non-breaking space)? .TP 4 .BR ucisrtl() Does the character have strong right-to-left directionality (i.e. Arabic letters)? .TP 4 .BR ucisltr() Does the character have strong left-to-right directionality (i.e. Latin letters)? .TP 4 .BR ucisstrong() Does the character have strong directionality? .TP 4 .BR ucisweak() Does the character have weak directionality (i.e. numbers)? .TP 4 .BR ucisneutral() Does the character have neutral directionality (i.e. whitespace)? .TP 4 .BR ucisseparator() Is the character a block or segment separator? .TP 4 .BR ucislsep() Is the character a line separator? .TP 4 .BR ucispsep() Is the character a paragraph separator? .TP 4 .BR ucismark() Is the character a mark of some kind? .TP 4 .BR ucisnsmark() Is the character a non-spacing mark? .TP 4 .BR ucisspmark() Is the character a spacing mark? .TP 4 .BR ucismodif() Is the character a modifier letter? .TP 4 .BR ucismodifsymbol() Is the character a modifier symbol? .TP 4 .BR ucisletnum() Is the character a number represented by a letter? .TP 4 .BR ucisconnect() Is the character connecting punctuation? .TP 4 .BR ucisdash() Is the character dash punctuation? .TP 4 .BR ucismath() Is the character a math character? .TP 4 .BR uciscurrency() Is the character a currency character? .TP 4 .BR ucisenclosing() Is the character enclosing (i.e. enclosing box)? .TP 4 .BR ucisprivate() Is the character from the Private Use Area? .TP 4 .BR ucissurrogate() Is the character one of the surrogate codes? .TP 4 .BR ucisidentstart() Is the character a legal initial character of an identifier? .TP 4 .BR ucisidentpart() Is the character a legal identifier character? .TP 4 .BR ucisdefined() Is the character defined (appeared in one of the data files)? .TP 4 .BR ucisundefined() Is the character not defined (non-Unicode)? .TP 4 .BR ucishan() Is the character a Han ideograph? .TP 4 .BR ucishangul() Is the character a pre-composed Hangul syllable? .SH "SEE ALSO" ctype(3) .SH ACKNOWLEDGMENTS These are people who have helped with patches or alerted me about problems. .sp John Cowan .br Bob Verbrugge .br Christophe Pierret .br Kent Johnson .br Valeriy E. Ushakov .br Stig Venaas .SH AUTHOR Mark Leisher .br Computing Research Lab .br New Mexico State University .br Email: mleisher@crl.nmsu.edu krb5-1.22.1/src/lib/krb5/unicode/ucdata/uctable.h0000664000175000017500000175014515051422640021235 0ustar ghudsonghudsonstatic const krb5_ui_4 _ucprop_size = 50; static const krb5_ui_2 _ucprop_offsets[] = { 0x0000, 0x00d0, 0x0138, 0x0140, 0x016a, 0x0176, 0x019e, 0x01ac, 0x01ae, 0x01b0, 0x01b4, 0x01cc, 0x01ce, 0xffff, 0x01d4, 0x051a, 0x0862, 0x0876, 0x089e, 0x0a32, 0x0a40, 0x0a58, 0x0ad8, 0x0b54, 0x0be0, 0x0c54, 0x0c6a, 0x0c96, 0x0d66, 0x0fee, 0x100a, 0x1020, 0x1024, 0x1054, 0x1058, 0x106e, 0x1078, 0x107e, 0x108e, 0x1240, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x13e8, 0x16e4, 0x16ee, 0x16f6, 0x1720, 0x0000 }; static const krb5_ui_4 _ucprop_ranges[] = { 0x00000300, 0x0000034f, 0x00000360, 0x0000036f, 0x00000483, 0x00000486, 0x00000591, 0x000005a1, 0x000005a3, 0x000005b9, 0x000005bb, 0x000005bd, 0x000005bf, 0x000005bf, 0x000005c1, 0x000005c2, 0x000005c4, 0x000005c4, 0x0000064b, 0x00000655, 0x00000670, 0x00000670, 0x000006d6, 0x000006dc, 0x000006df, 0x000006e4, 0x000006e7, 0x000006e8, 0x000006ea, 0x000006ed, 0x00000711, 0x00000711, 0x00000730, 0x0000074a, 0x000007a6, 0x000007b0, 0x00000901, 0x00000902, 0x0000093c, 0x0000093c, 0x00000941, 0x00000948, 0x0000094d, 0x0000094d, 0x00000951, 0x00000954, 0x00000962, 0x00000963, 0x00000981, 0x00000981, 0x000009bc, 0x000009bc, 0x000009c1, 0x000009c4, 0x000009cd, 0x000009cd, 0x000009e2, 0x000009e3, 0x00000a02, 0x00000a02, 0x00000a3c, 0x00000a3c, 0x00000a41, 0x00000a42, 0x00000a47, 0x00000a48, 0x00000a4b, 0x00000a4d, 0x00000a70, 0x00000a71, 0x00000a81, 0x00000a82, 0x00000abc, 0x00000abc, 0x00000ac1, 0x00000ac5, 0x00000ac7, 0x00000ac8, 0x00000acd, 0x00000acd, 0x00000b01, 0x00000b01, 0x00000b3c, 0x00000b3c, 0x00000b3f, 0x00000b3f, 0x00000b41, 0x00000b43, 0x00000b4d, 0x00000b4d, 0x00000b56, 0x00000b56, 0x00000b82, 0x00000b82, 0x00000bc0, 0x00000bc0, 0x00000bcd, 0x00000bcd, 0x00000c3e, 0x00000c40, 0x00000c46, 0x00000c48, 0x00000c4a, 0x00000c4d, 0x00000c55, 0x00000c56, 0x00000cbf, 0x00000cbf, 0x00000cc6, 0x00000cc6, 0x00000ccc, 0x00000ccd, 0x00000d41, 0x00000d43, 0x00000d4d, 0x00000d4d, 0x00000dca, 0x00000dca, 0x00000dd2, 0x00000dd4, 0x00000dd6, 0x00000dd6, 0x00000e31, 0x00000e31, 0x00000e34, 0x00000e3a, 0x00000e47, 0x00000e4e, 0x00000eb1, 0x00000eb1, 0x00000eb4, 0x00000eb9, 0x00000ebb, 0x00000ebc, 0x00000ec8, 0x00000ecd, 0x00000f18, 0x00000f19, 0x00000f35, 0x00000f35, 0x00000f37, 0x00000f37, 0x00000f39, 0x00000f39, 0x00000f71, 0x00000f7e, 0x00000f80, 0x00000f84, 0x00000f86, 0x00000f87, 0x00000f90, 0x00000f97, 0x00000f99, 0x00000fbc, 0x00000fc6, 0x00000fc6, 0x0000102d, 0x00001030, 0x00001032, 0x00001032, 0x00001036, 0x00001037, 0x00001039, 0x00001039, 0x00001058, 0x00001059, 0x00001712, 0x00001714, 0x00001732, 0x00001734, 0x00001752, 0x00001753, 0x00001772, 0x00001773, 0x000017b7, 0x000017bd, 0x000017c6, 0x000017c6, 0x000017c9, 0x000017d3, 0x0000180b, 0x0000180d, 0x000018a9, 0x000018a9, 0x000020d0, 0x000020dc, 0x000020e1, 0x000020e1, 0x000020e5, 0x000020ea, 0x0000302a, 0x0000302f, 0x00003099, 0x0000309a, 0x0000fb1e, 0x0000fb1e, 0x0000fe00, 0x0000fe0f, 0x0000fe20, 0x0000fe23, 0x0001d167, 0x0001d169, 0x0001d17b, 0x0001d182, 0x0001d185, 0x0001d18b, 0x0001d1aa, 0x0001d1ad, 0x00000903, 0x00000903, 0x0000093e, 0x00000940, 0x00000949, 0x0000094c, 0x00000982, 0x00000983, 0x000009be, 0x000009c0, 0x000009c7, 0x000009c8, 0x000009cb, 0x000009cc, 0x000009d7, 0x000009d7, 0x00000a3e, 0x00000a40, 0x00000a83, 0x00000a83, 0x00000abe, 0x00000ac0, 0x00000ac9, 0x00000ac9, 0x00000acb, 0x00000acc, 0x00000b02, 0x00000b03, 0x00000b3e, 0x00000b3e, 0x00000b40, 0x00000b40, 0x00000b47, 0x00000b48, 0x00000b4b, 0x00000b4c, 0x00000b57, 0x00000b57, 0x00000bbe, 0x00000bbf, 0x00000bc1, 0x00000bc2, 0x00000bc6, 0x00000bc8, 0x00000bca, 0x00000bcc, 0x00000bd7, 0x00000bd7, 0x00000c01, 0x00000c03, 0x00000c41, 0x00000c44, 0x00000c82, 0x00000c83, 0x00000cbe, 0x00000cbe, 0x00000cc0, 0x00000cc4, 0x00000cc7, 0x00000cc8, 0x00000cca, 0x00000ccb, 0x00000cd5, 0x00000cd6, 0x00000d02, 0x00000d03, 0x00000d3e, 0x00000d40, 0x00000d46, 0x00000d48, 0x00000d4a, 0x00000d4c, 0x00000d57, 0x00000d57, 0x00000d82, 0x00000d83, 0x00000dcf, 0x00000dd1, 0x00000dd8, 0x00000ddf, 0x00000df2, 0x00000df3, 0x00000f3e, 0x00000f3f, 0x00000f7f, 0x00000f7f, 0x0000102c, 0x0000102c, 0x00001031, 0x00001031, 0x00001038, 0x00001038, 0x00001056, 0x00001057, 0x000017b4, 0x000017b6, 0x000017be, 0x000017c5, 0x000017c7, 0x000017c8, 0x0001d165, 0x0001d166, 0x0001d16d, 0x0001d172, 0x00000488, 0x00000489, 0x000006de, 0x000006de, 0x000020dd, 0x000020e0, 0x000020e2, 0x000020e4, 0x00000030, 0x00000039, 0x00000660, 0x00000669, 0x000006f0, 0x000006f9, 0x00000966, 0x0000096f, 0x000009e6, 0x000009ef, 0x00000a66, 0x00000a6f, 0x00000ae6, 0x00000aef, 0x00000b66, 0x00000b6f, 0x00000be7, 0x00000bef, 0x00000c66, 0x00000c6f, 0x00000ce6, 0x00000cef, 0x00000d66, 0x00000d6f, 0x00000e50, 0x00000e59, 0x00000ed0, 0x00000ed9, 0x00000f20, 0x00000f29, 0x00001040, 0x00001049, 0x00001369, 0x00001371, 0x000017e0, 0x000017e9, 0x00001810, 0x00001819, 0x0000ff10, 0x0000ff19, 0x0001d7ce, 0x0001d7ff, 0x000016ee, 0x000016f0, 0x00002160, 0x00002183, 0x00003007, 0x00003007, 0x00003021, 0x00003029, 0x00003038, 0x0000303a, 0x0001034a, 0x0001034a, 0x000000b2, 0x000000b3, 0x000000b9, 0x000000b9, 0x000000bc, 0x000000be, 0x000009f4, 0x000009f9, 0x00000bf0, 0x00000bf2, 0x00000f2a, 0x00000f33, 0x00001372, 0x0000137c, 0x00002070, 0x00002070, 0x00002074, 0x00002079, 0x00002080, 0x00002089, 0x00002153, 0x0000215f, 0x00002460, 0x0000249b, 0x000024ea, 0x000024fe, 0x00002776, 0x00002793, 0x00003192, 0x00003195, 0x00003220, 0x00003229, 0x00003251, 0x0000325f, 0x00003280, 0x00003289, 0x000032b1, 0x000032bf, 0x00010320, 0x00010323, 0x00000020, 0x00000020, 0x000000a0, 0x000000a0, 0x00001680, 0x00001680, 0x00002000, 0x0000200b, 0x0000202f, 0x0000202f, 0x0000205f, 0x0000205f, 0x00003000, 0x00003000, 0x00002028, 0x00002028, 0x00002029, 0x00002029, 0x00000000, 0x0000001f, 0x0000007f, 0x0000009f, 0x000006dd, 0x000006dd, 0x0000070f, 0x0000070f, 0x0000180e, 0x0000180e, 0x0000200c, 0x0000200f, 0x0000202a, 0x0000202e, 0x00002060, 0x00002063, 0x0000206a, 0x0000206f, 0x0000feff, 0x0000feff, 0x0000fff9, 0x0000fffb, 0x0001d173, 0x0001d17a, 0x000e0001, 0x000e0001, 0x000e0020, 0x000e007f, 0x00010000, 0x0010ffff, 0x0000e000, 0x0000f8ff, 0x000f0000, 0x000ffffd, 0x00100000, 0x0010fffd, 0x00000041, 0x0000005a, 0x000000c0, 0x000000d6, 0x000000d8, 0x000000de, 0x00000100, 0x00000100, 0x00000102, 0x00000102, 0x00000104, 0x00000104, 0x00000106, 0x00000106, 0x00000108, 0x00000108, 0x0000010a, 0x0000010a, 0x0000010c, 0x0000010c, 0x0000010e, 0x0000010e, 0x00000110, 0x00000110, 0x00000112, 0x00000112, 0x00000114, 0x00000114, 0x00000116, 0x00000116, 0x00000118, 0x00000118, 0x0000011a, 0x0000011a, 0x0000011c, 0x0000011c, 0x0000011e, 0x0000011e, 0x00000120, 0x00000120, 0x00000122, 0x00000122, 0x00000124, 0x00000124, 0x00000126, 0x00000126, 0x00000128, 0x00000128, 0x0000012a, 0x0000012a, 0x0000012c, 0x0000012c, 0x0000012e, 0x0000012e, 0x00000130, 0x00000130, 0x00000132, 0x00000132, 0x00000134, 0x00000134, 0x00000136, 0x00000136, 0x00000139, 0x00000139, 0x0000013b, 0x0000013b, 0x0000013d, 0x0000013d, 0x0000013f, 0x0000013f, 0x00000141, 0x00000141, 0x00000143, 0x00000143, 0x00000145, 0x00000145, 0x00000147, 0x00000147, 0x0000014a, 0x0000014a, 0x0000014c, 0x0000014c, 0x0000014e, 0x0000014e, 0x00000150, 0x00000150, 0x00000152, 0x00000152, 0x00000154, 0x00000154, 0x00000156, 0x00000156, 0x00000158, 0x00000158, 0x0000015a, 0x0000015a, 0x0000015c, 0x0000015c, 0x0000015e, 0x0000015e, 0x00000160, 0x00000160, 0x00000162, 0x00000162, 0x00000164, 0x00000164, 0x00000166, 0x00000166, 0x00000168, 0x00000168, 0x0000016a, 0x0000016a, 0x0000016c, 0x0000016c, 0x0000016e, 0x0000016e, 0x00000170, 0x00000170, 0x00000172, 0x00000172, 0x00000174, 0x00000174, 0x00000176, 0x00000176, 0x00000178, 0x00000179, 0x0000017b, 0x0000017b, 0x0000017d, 0x0000017d, 0x00000181, 0x00000182, 0x00000184, 0x00000184, 0x00000186, 0x00000187, 0x00000189, 0x0000018b, 0x0000018e, 0x00000191, 0x00000193, 0x00000194, 0x00000196, 0x00000198, 0x0000019c, 0x0000019d, 0x0000019f, 0x000001a0, 0x000001a2, 0x000001a2, 0x000001a4, 0x000001a4, 0x000001a6, 0x000001a7, 0x000001a9, 0x000001a9, 0x000001ac, 0x000001ac, 0x000001ae, 0x000001af, 0x000001b1, 0x000001b3, 0x000001b5, 0x000001b5, 0x000001b7, 0x000001b8, 0x000001bc, 0x000001bc, 0x000001c4, 0x000001c4, 0x000001c7, 0x000001c7, 0x000001ca, 0x000001ca, 0x000001cd, 0x000001cd, 0x000001cf, 0x000001cf, 0x000001d1, 0x000001d1, 0x000001d3, 0x000001d3, 0x000001d5, 0x000001d5, 0x000001d7, 0x000001d7, 0x000001d9, 0x000001d9, 0x000001db, 0x000001db, 0x000001de, 0x000001de, 0x000001e0, 0x000001e0, 0x000001e2, 0x000001e2, 0x000001e4, 0x000001e4, 0x000001e6, 0x000001e6, 0x000001e8, 0x000001e8, 0x000001ea, 0x000001ea, 0x000001ec, 0x000001ec, 0x000001ee, 0x000001ee, 0x000001f1, 0x000001f1, 0x000001f4, 0x000001f4, 0x000001f6, 0x000001f8, 0x000001fa, 0x000001fa, 0x000001fc, 0x000001fc, 0x000001fe, 0x000001fe, 0x00000200, 0x00000200, 0x00000202, 0x00000202, 0x00000204, 0x00000204, 0x00000206, 0x00000206, 0x00000208, 0x00000208, 0x0000020a, 0x0000020a, 0x0000020c, 0x0000020c, 0x0000020e, 0x0000020e, 0x00000210, 0x00000210, 0x00000212, 0x00000212, 0x00000214, 0x00000214, 0x00000216, 0x00000216, 0x00000218, 0x00000218, 0x0000021a, 0x0000021a, 0x0000021c, 0x0000021c, 0x0000021e, 0x0000021e, 0x00000220, 0x00000220, 0x00000222, 0x00000222, 0x00000224, 0x00000224, 0x00000226, 0x00000226, 0x00000228, 0x00000228, 0x0000022a, 0x0000022a, 0x0000022c, 0x0000022c, 0x0000022e, 0x0000022e, 0x00000230, 0x00000230, 0x00000232, 0x00000232, 0x00000386, 0x00000386, 0x00000388, 0x0000038a, 0x0000038c, 0x0000038c, 0x0000038e, 0x0000038f, 0x00000391, 0x000003a1, 0x000003a3, 0x000003ab, 0x000003d2, 0x000003d4, 0x000003d8, 0x000003d8, 0x000003da, 0x000003da, 0x000003dc, 0x000003dc, 0x000003de, 0x000003de, 0x000003e0, 0x000003e0, 0x000003e2, 0x000003e2, 0x000003e4, 0x000003e4, 0x000003e6, 0x000003e6, 0x000003e8, 0x000003e8, 0x000003ea, 0x000003ea, 0x000003ec, 0x000003ec, 0x000003ee, 0x000003ee, 0x000003f4, 0x000003f4, 0x00000400, 0x0000042f, 0x00000460, 0x00000460, 0x00000462, 0x00000462, 0x00000464, 0x00000464, 0x00000466, 0x00000466, 0x00000468, 0x00000468, 0x0000046a, 0x0000046a, 0x0000046c, 0x0000046c, 0x0000046e, 0x0000046e, 0x00000470, 0x00000470, 0x00000472, 0x00000472, 0x00000474, 0x00000474, 0x00000476, 0x00000476, 0x00000478, 0x00000478, 0x0000047a, 0x0000047a, 0x0000047c, 0x0000047c, 0x0000047e, 0x0000047e, 0x00000480, 0x00000480, 0x0000048a, 0x0000048a, 0x0000048c, 0x0000048c, 0x0000048e, 0x0000048e, 0x00000490, 0x00000490, 0x00000492, 0x00000492, 0x00000494, 0x00000494, 0x00000496, 0x00000496, 0x00000498, 0x00000498, 0x0000049a, 0x0000049a, 0x0000049c, 0x0000049c, 0x0000049e, 0x0000049e, 0x000004a0, 0x000004a0, 0x000004a2, 0x000004a2, 0x000004a4, 0x000004a4, 0x000004a6, 0x000004a6, 0x000004a8, 0x000004a8, 0x000004aa, 0x000004aa, 0x000004ac, 0x000004ac, 0x000004ae, 0x000004ae, 0x000004b0, 0x000004b0, 0x000004b2, 0x000004b2, 0x000004b4, 0x000004b4, 0x000004b6, 0x000004b6, 0x000004b8, 0x000004b8, 0x000004ba, 0x000004ba, 0x000004bc, 0x000004bc, 0x000004be, 0x000004be, 0x000004c0, 0x000004c1, 0x000004c3, 0x000004c3, 0x000004c5, 0x000004c5, 0x000004c7, 0x000004c7, 0x000004c9, 0x000004c9, 0x000004cb, 0x000004cb, 0x000004cd, 0x000004cd, 0x000004d0, 0x000004d0, 0x000004d2, 0x000004d2, 0x000004d4, 0x000004d4, 0x000004d6, 0x000004d6, 0x000004d8, 0x000004d8, 0x000004da, 0x000004da, 0x000004dc, 0x000004dc, 0x000004de, 0x000004de, 0x000004e0, 0x000004e0, 0x000004e2, 0x000004e2, 0x000004e4, 0x000004e4, 0x000004e6, 0x000004e6, 0x000004e8, 0x000004e8, 0x000004ea, 0x000004ea, 0x000004ec, 0x000004ec, 0x000004ee, 0x000004ee, 0x000004f0, 0x000004f0, 0x000004f2, 0x000004f2, 0x000004f4, 0x000004f4, 0x000004f8, 0x000004f8, 0x00000500, 0x00000500, 0x00000502, 0x00000502, 0x00000504, 0x00000504, 0x00000506, 0x00000506, 0x00000508, 0x00000508, 0x0000050a, 0x0000050a, 0x0000050c, 0x0000050c, 0x0000050e, 0x0000050e, 0x00000531, 0x00000556, 0x000010a0, 0x000010c5, 0x00001e00, 0x00001e00, 0x00001e02, 0x00001e02, 0x00001e04, 0x00001e04, 0x00001e06, 0x00001e06, 0x00001e08, 0x00001e08, 0x00001e0a, 0x00001e0a, 0x00001e0c, 0x00001e0c, 0x00001e0e, 0x00001e0e, 0x00001e10, 0x00001e10, 0x00001e12, 0x00001e12, 0x00001e14, 0x00001e14, 0x00001e16, 0x00001e16, 0x00001e18, 0x00001e18, 0x00001e1a, 0x00001e1a, 0x00001e1c, 0x00001e1c, 0x00001e1e, 0x00001e1e, 0x00001e20, 0x00001e20, 0x00001e22, 0x00001e22, 0x00001e24, 0x00001e24, 0x00001e26, 0x00001e26, 0x00001e28, 0x00001e28, 0x00001e2a, 0x00001e2a, 0x00001e2c, 0x00001e2c, 0x00001e2e, 0x00001e2e, 0x00001e30, 0x00001e30, 0x00001e32, 0x00001e32, 0x00001e34, 0x00001e34, 0x00001e36, 0x00001e36, 0x00001e38, 0x00001e38, 0x00001e3a, 0x00001e3a, 0x00001e3c, 0x00001e3c, 0x00001e3e, 0x00001e3e, 0x00001e40, 0x00001e40, 0x00001e42, 0x00001e42, 0x00001e44, 0x00001e44, 0x00001e46, 0x00001e46, 0x00001e48, 0x00001e48, 0x00001e4a, 0x00001e4a, 0x00001e4c, 0x00001e4c, 0x00001e4e, 0x00001e4e, 0x00001e50, 0x00001e50, 0x00001e52, 0x00001e52, 0x00001e54, 0x00001e54, 0x00001e56, 0x00001e56, 0x00001e58, 0x00001e58, 0x00001e5a, 0x00001e5a, 0x00001e5c, 0x00001e5c, 0x00001e5e, 0x00001e5e, 0x00001e60, 0x00001e60, 0x00001e62, 0x00001e62, 0x00001e64, 0x00001e64, 0x00001e66, 0x00001e66, 0x00001e68, 0x00001e68, 0x00001e6a, 0x00001e6a, 0x00001e6c, 0x00001e6c, 0x00001e6e, 0x00001e6e, 0x00001e70, 0x00001e70, 0x00001e72, 0x00001e72, 0x00001e74, 0x00001e74, 0x00001e76, 0x00001e76, 0x00001e78, 0x00001e78, 0x00001e7a, 0x00001e7a, 0x00001e7c, 0x00001e7c, 0x00001e7e, 0x00001e7e, 0x00001e80, 0x00001e80, 0x00001e82, 0x00001e82, 0x00001e84, 0x00001e84, 0x00001e86, 0x00001e86, 0x00001e88, 0x00001e88, 0x00001e8a, 0x00001e8a, 0x00001e8c, 0x00001e8c, 0x00001e8e, 0x00001e8e, 0x00001e90, 0x00001e90, 0x00001e92, 0x00001e92, 0x00001e94, 0x00001e94, 0x00001ea0, 0x00001ea0, 0x00001ea2, 0x00001ea2, 0x00001ea4, 0x00001ea4, 0x00001ea6, 0x00001ea6, 0x00001ea8, 0x00001ea8, 0x00001eaa, 0x00001eaa, 0x00001eac, 0x00001eac, 0x00001eae, 0x00001eae, 0x00001eb0, 0x00001eb0, 0x00001eb2, 0x00001eb2, 0x00001eb4, 0x00001eb4, 0x00001eb6, 0x00001eb6, 0x00001eb8, 0x00001eb8, 0x00001eba, 0x00001eba, 0x00001ebc, 0x00001ebc, 0x00001ebe, 0x00001ebe, 0x00001ec0, 0x00001ec0, 0x00001ec2, 0x00001ec2, 0x00001ec4, 0x00001ec4, 0x00001ec6, 0x00001ec6, 0x00001ec8, 0x00001ec8, 0x00001eca, 0x00001eca, 0x00001ecc, 0x00001ecc, 0x00001ece, 0x00001ece, 0x00001ed0, 0x00001ed0, 0x00001ed2, 0x00001ed2, 0x00001ed4, 0x00001ed4, 0x00001ed6, 0x00001ed6, 0x00001ed8, 0x00001ed8, 0x00001eda, 0x00001eda, 0x00001edc, 0x00001edc, 0x00001ede, 0x00001ede, 0x00001ee0, 0x00001ee0, 0x00001ee2, 0x00001ee2, 0x00001ee4, 0x00001ee4, 0x00001ee6, 0x00001ee6, 0x00001ee8, 0x00001ee8, 0x00001eea, 0x00001eea, 0x00001eec, 0x00001eec, 0x00001eee, 0x00001eee, 0x00001ef0, 0x00001ef0, 0x00001ef2, 0x00001ef2, 0x00001ef4, 0x00001ef4, 0x00001ef6, 0x00001ef6, 0x00001ef8, 0x00001ef8, 0x00001f08, 0x00001f0f, 0x00001f18, 0x00001f1d, 0x00001f28, 0x00001f2f, 0x00001f38, 0x00001f3f, 0x00001f48, 0x00001f4d, 0x00001f59, 0x00001f59, 0x00001f5b, 0x00001f5b, 0x00001f5d, 0x00001f5d, 0x00001f5f, 0x00001f5f, 0x00001f68, 0x00001f6f, 0x00001fb8, 0x00001fbb, 0x00001fc8, 0x00001fcb, 0x00001fd8, 0x00001fdb, 0x00001fe8, 0x00001fec, 0x00001ff8, 0x00001ffb, 0x00002102, 0x00002102, 0x00002107, 0x00002107, 0x0000210b, 0x0000210d, 0x00002110, 0x00002112, 0x00002115, 0x00002115, 0x00002119, 0x0000211d, 0x00002124, 0x00002124, 0x00002126, 0x00002126, 0x00002128, 0x00002128, 0x0000212a, 0x0000212d, 0x00002130, 0x00002131, 0x00002133, 0x00002133, 0x0000213e, 0x0000213f, 0x00002145, 0x00002145, 0x0000ff21, 0x0000ff3a, 0x00010400, 0x00010425, 0x0001d400, 0x0001d419, 0x0001d434, 0x0001d44d, 0x0001d468, 0x0001d481, 0x0001d49c, 0x0001d49c, 0x0001d49e, 0x0001d49f, 0x0001d4a2, 0x0001d4a2, 0x0001d4a5, 0x0001d4a6, 0x0001d4a9, 0x0001d4ac, 0x0001d4ae, 0x0001d4b5, 0x0001d4d0, 0x0001d4e9, 0x0001d504, 0x0001d505, 0x0001d507, 0x0001d50a, 0x0001d50d, 0x0001d514, 0x0001d516, 0x0001d51c, 0x0001d538, 0x0001d539, 0x0001d53b, 0x0001d53e, 0x0001d540, 0x0001d544, 0x0001d546, 0x0001d546, 0x0001d54a, 0x0001d550, 0x0001d56c, 0x0001d585, 0x0001d5a0, 0x0001d5b9, 0x0001d5d4, 0x0001d5ed, 0x0001d608, 0x0001d621, 0x0001d63c, 0x0001d655, 0x0001d670, 0x0001d689, 0x0001d6a8, 0x0001d6c0, 0x0001d6e2, 0x0001d6fa, 0x0001d71c, 0x0001d734, 0x0001d756, 0x0001d76e, 0x0001d790, 0x0001d7a8, 0x00000061, 0x0000007a, 0x000000aa, 0x000000aa, 0x000000b5, 0x000000b5, 0x000000ba, 0x000000ba, 0x000000df, 0x000000f6, 0x000000f8, 0x000000ff, 0x00000101, 0x00000101, 0x00000103, 0x00000103, 0x00000105, 0x00000105, 0x00000107, 0x00000107, 0x00000109, 0x00000109, 0x0000010b, 0x0000010b, 0x0000010d, 0x0000010d, 0x0000010f, 0x0000010f, 0x00000111, 0x00000111, 0x00000113, 0x00000113, 0x00000115, 0x00000115, 0x00000117, 0x00000117, 0x00000119, 0x00000119, 0x0000011b, 0x0000011b, 0x0000011d, 0x0000011d, 0x0000011f, 0x0000011f, 0x00000121, 0x00000121, 0x00000123, 0x00000123, 0x00000125, 0x00000125, 0x00000127, 0x00000127, 0x00000129, 0x00000129, 0x0000012b, 0x0000012b, 0x0000012d, 0x0000012d, 0x0000012f, 0x0000012f, 0x00000131, 0x00000131, 0x00000133, 0x00000133, 0x00000135, 0x00000135, 0x00000137, 0x00000138, 0x0000013a, 0x0000013a, 0x0000013c, 0x0000013c, 0x0000013e, 0x0000013e, 0x00000140, 0x00000140, 0x00000142, 0x00000142, 0x00000144, 0x00000144, 0x00000146, 0x00000146, 0x00000148, 0x00000149, 0x0000014b, 0x0000014b, 0x0000014d, 0x0000014d, 0x0000014f, 0x0000014f, 0x00000151, 0x00000151, 0x00000153, 0x00000153, 0x00000155, 0x00000155, 0x00000157, 0x00000157, 0x00000159, 0x00000159, 0x0000015b, 0x0000015b, 0x0000015d, 0x0000015d, 0x0000015f, 0x0000015f, 0x00000161, 0x00000161, 0x00000163, 0x00000163, 0x00000165, 0x00000165, 0x00000167, 0x00000167, 0x00000169, 0x00000169, 0x0000016b, 0x0000016b, 0x0000016d, 0x0000016d, 0x0000016f, 0x0000016f, 0x00000171, 0x00000171, 0x00000173, 0x00000173, 0x00000175, 0x00000175, 0x00000177, 0x00000177, 0x0000017a, 0x0000017a, 0x0000017c, 0x0000017c, 0x0000017e, 0x00000180, 0x00000183, 0x00000183, 0x00000185, 0x00000185, 0x00000188, 0x00000188, 0x0000018c, 0x0000018d, 0x00000192, 0x00000192, 0x00000195, 0x00000195, 0x00000199, 0x0000019b, 0x0000019e, 0x0000019e, 0x000001a1, 0x000001a1, 0x000001a3, 0x000001a3, 0x000001a5, 0x000001a5, 0x000001a8, 0x000001a8, 0x000001aa, 0x000001ab, 0x000001ad, 0x000001ad, 0x000001b0, 0x000001b0, 0x000001b4, 0x000001b4, 0x000001b6, 0x000001b6, 0x000001b9, 0x000001ba, 0x000001bd, 0x000001bf, 0x000001c6, 0x000001c6, 0x000001c9, 0x000001c9, 0x000001cc, 0x000001cc, 0x000001ce, 0x000001ce, 0x000001d0, 0x000001d0, 0x000001d2, 0x000001d2, 0x000001d4, 0x000001d4, 0x000001d6, 0x000001d6, 0x000001d8, 0x000001d8, 0x000001da, 0x000001da, 0x000001dc, 0x000001dd, 0x000001df, 0x000001df, 0x000001e1, 0x000001e1, 0x000001e3, 0x000001e3, 0x000001e5, 0x000001e5, 0x000001e7, 0x000001e7, 0x000001e9, 0x000001e9, 0x000001eb, 0x000001eb, 0x000001ed, 0x000001ed, 0x000001ef, 0x000001f0, 0x000001f3, 0x000001f3, 0x000001f5, 0x000001f5, 0x000001f9, 0x000001f9, 0x000001fb, 0x000001fb, 0x000001fd, 0x000001fd, 0x000001ff, 0x000001ff, 0x00000201, 0x00000201, 0x00000203, 0x00000203, 0x00000205, 0x00000205, 0x00000207, 0x00000207, 0x00000209, 0x00000209, 0x0000020b, 0x0000020b, 0x0000020d, 0x0000020d, 0x0000020f, 0x0000020f, 0x00000211, 0x00000211, 0x00000213, 0x00000213, 0x00000215, 0x00000215, 0x00000217, 0x00000217, 0x00000219, 0x00000219, 0x0000021b, 0x0000021b, 0x0000021d, 0x0000021d, 0x0000021f, 0x0000021f, 0x00000223, 0x00000223, 0x00000225, 0x00000225, 0x00000227, 0x00000227, 0x00000229, 0x00000229, 0x0000022b, 0x0000022b, 0x0000022d, 0x0000022d, 0x0000022f, 0x0000022f, 0x00000231, 0x00000231, 0x00000233, 0x00000233, 0x00000250, 0x000002ad, 0x00000390, 0x00000390, 0x000003ac, 0x000003ce, 0x000003d0, 0x000003d1, 0x000003d5, 0x000003d7, 0x000003d9, 0x000003d9, 0x000003db, 0x000003db, 0x000003dd, 0x000003dd, 0x000003df, 0x000003df, 0x000003e1, 0x000003e1, 0x000003e3, 0x000003e3, 0x000003e5, 0x000003e5, 0x000003e7, 0x000003e7, 0x000003e9, 0x000003e9, 0x000003eb, 0x000003eb, 0x000003ed, 0x000003ed, 0x000003ef, 0x000003f3, 0x000003f5, 0x000003f5, 0x00000430, 0x0000045f, 0x00000461, 0x00000461, 0x00000463, 0x00000463, 0x00000465, 0x00000465, 0x00000467, 0x00000467, 0x00000469, 0x00000469, 0x0000046b, 0x0000046b, 0x0000046d, 0x0000046d, 0x0000046f, 0x0000046f, 0x00000471, 0x00000471, 0x00000473, 0x00000473, 0x00000475, 0x00000475, 0x00000477, 0x00000477, 0x00000479, 0x00000479, 0x0000047b, 0x0000047b, 0x0000047d, 0x0000047d, 0x0000047f, 0x0000047f, 0x00000481, 0x00000481, 0x0000048b, 0x0000048b, 0x0000048d, 0x0000048d, 0x0000048f, 0x0000048f, 0x00000491, 0x00000491, 0x00000493, 0x00000493, 0x00000495, 0x00000495, 0x00000497, 0x00000497, 0x00000499, 0x00000499, 0x0000049b, 0x0000049b, 0x0000049d, 0x0000049d, 0x0000049f, 0x0000049f, 0x000004a1, 0x000004a1, 0x000004a3, 0x000004a3, 0x000004a5, 0x000004a5, 0x000004a7, 0x000004a7, 0x000004a9, 0x000004a9, 0x000004ab, 0x000004ab, 0x000004ad, 0x000004ad, 0x000004af, 0x000004af, 0x000004b1, 0x000004b1, 0x000004b3, 0x000004b3, 0x000004b5, 0x000004b5, 0x000004b7, 0x000004b7, 0x000004b9, 0x000004b9, 0x000004bb, 0x000004bb, 0x000004bd, 0x000004bd, 0x000004bf, 0x000004bf, 0x000004c2, 0x000004c2, 0x000004c4, 0x000004c4, 0x000004c6, 0x000004c6, 0x000004c8, 0x000004c8, 0x000004ca, 0x000004ca, 0x000004cc, 0x000004cc, 0x000004ce, 0x000004ce, 0x000004d1, 0x000004d1, 0x000004d3, 0x000004d3, 0x000004d5, 0x000004d5, 0x000004d7, 0x000004d7, 0x000004d9, 0x000004d9, 0x000004db, 0x000004db, 0x000004dd, 0x000004dd, 0x000004df, 0x000004df, 0x000004e1, 0x000004e1, 0x000004e3, 0x000004e3, 0x000004e5, 0x000004e5, 0x000004e7, 0x000004e7, 0x000004e9, 0x000004e9, 0x000004eb, 0x000004eb, 0x000004ed, 0x000004ed, 0x000004ef, 0x000004ef, 0x000004f1, 0x000004f1, 0x000004f3, 0x000004f3, 0x000004f5, 0x000004f5, 0x000004f9, 0x000004f9, 0x00000501, 0x00000501, 0x00000503, 0x00000503, 0x00000505, 0x00000505, 0x00000507, 0x00000507, 0x00000509, 0x00000509, 0x0000050b, 0x0000050b, 0x0000050d, 0x0000050d, 0x0000050f, 0x0000050f, 0x00000561, 0x00000587, 0x00001e01, 0x00001e01, 0x00001e03, 0x00001e03, 0x00001e05, 0x00001e05, 0x00001e07, 0x00001e07, 0x00001e09, 0x00001e09, 0x00001e0b, 0x00001e0b, 0x00001e0d, 0x00001e0d, 0x00001e0f, 0x00001e0f, 0x00001e11, 0x00001e11, 0x00001e13, 0x00001e13, 0x00001e15, 0x00001e15, 0x00001e17, 0x00001e17, 0x00001e19, 0x00001e19, 0x00001e1b, 0x00001e1b, 0x00001e1d, 0x00001e1d, 0x00001e1f, 0x00001e1f, 0x00001e21, 0x00001e21, 0x00001e23, 0x00001e23, 0x00001e25, 0x00001e25, 0x00001e27, 0x00001e27, 0x00001e29, 0x00001e29, 0x00001e2b, 0x00001e2b, 0x00001e2d, 0x00001e2d, 0x00001e2f, 0x00001e2f, 0x00001e31, 0x00001e31, 0x00001e33, 0x00001e33, 0x00001e35, 0x00001e35, 0x00001e37, 0x00001e37, 0x00001e39, 0x00001e39, 0x00001e3b, 0x00001e3b, 0x00001e3d, 0x00001e3d, 0x00001e3f, 0x00001e3f, 0x00001e41, 0x00001e41, 0x00001e43, 0x00001e43, 0x00001e45, 0x00001e45, 0x00001e47, 0x00001e47, 0x00001e49, 0x00001e49, 0x00001e4b, 0x00001e4b, 0x00001e4d, 0x00001e4d, 0x00001e4f, 0x00001e4f, 0x00001e51, 0x00001e51, 0x00001e53, 0x00001e53, 0x00001e55, 0x00001e55, 0x00001e57, 0x00001e57, 0x00001e59, 0x00001e59, 0x00001e5b, 0x00001e5b, 0x00001e5d, 0x00001e5d, 0x00001e5f, 0x00001e5f, 0x00001e61, 0x00001e61, 0x00001e63, 0x00001e63, 0x00001e65, 0x00001e65, 0x00001e67, 0x00001e67, 0x00001e69, 0x00001e69, 0x00001e6b, 0x00001e6b, 0x00001e6d, 0x00001e6d, 0x00001e6f, 0x00001e6f, 0x00001e71, 0x00001e71, 0x00001e73, 0x00001e73, 0x00001e75, 0x00001e75, 0x00001e77, 0x00001e77, 0x00001e79, 0x00001e79, 0x00001e7b, 0x00001e7b, 0x00001e7d, 0x00001e7d, 0x00001e7f, 0x00001e7f, 0x00001e81, 0x00001e81, 0x00001e83, 0x00001e83, 0x00001e85, 0x00001e85, 0x00001e87, 0x00001e87, 0x00001e89, 0x00001e89, 0x00001e8b, 0x00001e8b, 0x00001e8d, 0x00001e8d, 0x00001e8f, 0x00001e8f, 0x00001e91, 0x00001e91, 0x00001e93, 0x00001e93, 0x00001e95, 0x00001e9b, 0x00001ea1, 0x00001ea1, 0x00001ea3, 0x00001ea3, 0x00001ea5, 0x00001ea5, 0x00001ea7, 0x00001ea7, 0x00001ea9, 0x00001ea9, 0x00001eab, 0x00001eab, 0x00001ead, 0x00001ead, 0x00001eaf, 0x00001eaf, 0x00001eb1, 0x00001eb1, 0x00001eb3, 0x00001eb3, 0x00001eb5, 0x00001eb5, 0x00001eb7, 0x00001eb7, 0x00001eb9, 0x00001eb9, 0x00001ebb, 0x00001ebb, 0x00001ebd, 0x00001ebd, 0x00001ebf, 0x00001ebf, 0x00001ec1, 0x00001ec1, 0x00001ec3, 0x00001ec3, 0x00001ec5, 0x00001ec5, 0x00001ec7, 0x00001ec7, 0x00001ec9, 0x00001ec9, 0x00001ecb, 0x00001ecb, 0x00001ecd, 0x00001ecd, 0x00001ecf, 0x00001ecf, 0x00001ed1, 0x00001ed1, 0x00001ed3, 0x00001ed3, 0x00001ed5, 0x00001ed5, 0x00001ed7, 0x00001ed7, 0x00001ed9, 0x00001ed9, 0x00001edb, 0x00001edb, 0x00001edd, 0x00001edd, 0x00001edf, 0x00001edf, 0x00001ee1, 0x00001ee1, 0x00001ee3, 0x00001ee3, 0x00001ee5, 0x00001ee5, 0x00001ee7, 0x00001ee7, 0x00001ee9, 0x00001ee9, 0x00001eeb, 0x00001eeb, 0x00001eed, 0x00001eed, 0x00001eef, 0x00001eef, 0x00001ef1, 0x00001ef1, 0x00001ef3, 0x00001ef3, 0x00001ef5, 0x00001ef5, 0x00001ef7, 0x00001ef7, 0x00001ef9, 0x00001ef9, 0x00001f00, 0x00001f07, 0x00001f10, 0x00001f15, 0x00001f20, 0x00001f27, 0x00001f30, 0x00001f37, 0x00001f40, 0x00001f45, 0x00001f50, 0x00001f57, 0x00001f60, 0x00001f67, 0x00001f70, 0x00001f7d, 0x00001f80, 0x00001f87, 0x00001f90, 0x00001f97, 0x00001fa0, 0x00001fa7, 0x00001fb0, 0x00001fb4, 0x00001fb6, 0x00001fb7, 0x00001fbe, 0x00001fbe, 0x00001fc2, 0x00001fc4, 0x00001fc6, 0x00001fc7, 0x00001fd0, 0x00001fd3, 0x00001fd6, 0x00001fd7, 0x00001fe0, 0x00001fe7, 0x00001ff2, 0x00001ff4, 0x00001ff6, 0x00001ff7, 0x00002071, 0x00002071, 0x0000207f, 0x0000207f, 0x0000210a, 0x0000210a, 0x0000210e, 0x0000210f, 0x00002113, 0x00002113, 0x0000212f, 0x0000212f, 0x00002134, 0x00002134, 0x00002139, 0x00002139, 0x0000213d, 0x0000213d, 0x00002146, 0x00002149, 0x0000fb00, 0x0000fb06, 0x0000fb13, 0x0000fb17, 0x0000ff41, 0x0000ff5a, 0x00010428, 0x0001044d, 0x0001d41a, 0x0001d433, 0x0001d44e, 0x0001d454, 0x0001d456, 0x0001d467, 0x0001d482, 0x0001d49b, 0x0001d4b6, 0x0001d4b9, 0x0001d4bb, 0x0001d4bb, 0x0001d4bd, 0x0001d4c0, 0x0001d4c2, 0x0001d4c3, 0x0001d4c5, 0x0001d4cf, 0x0001d4ea, 0x0001d503, 0x0001d51e, 0x0001d537, 0x0001d552, 0x0001d56b, 0x0001d586, 0x0001d59f, 0x0001d5ba, 0x0001d5d3, 0x0001d5ee, 0x0001d607, 0x0001d622, 0x0001d63b, 0x0001d656, 0x0001d66f, 0x0001d68a, 0x0001d6a3, 0x0001d6c2, 0x0001d6da, 0x0001d6dc, 0x0001d6e1, 0x0001d6fc, 0x0001d714, 0x0001d716, 0x0001d71b, 0x0001d736, 0x0001d74e, 0x0001d750, 0x0001d755, 0x0001d770, 0x0001d788, 0x0001d78a, 0x0001d78f, 0x0001d7aa, 0x0001d7c2, 0x0001d7c4, 0x0001d7c9, 0x000001c5, 0x000001c5, 0x000001c8, 0x000001c8, 0x000001cb, 0x000001cb, 0x000001f2, 0x000001f2, 0x00001f88, 0x00001f8f, 0x00001f98, 0x00001f9f, 0x00001fa8, 0x00001faf, 0x00001fbc, 0x00001fbc, 0x00001fcc, 0x00001fcc, 0x00001ffc, 0x00001ffc, 0x000002b0, 0x000002b8, 0x000002bb, 0x000002c1, 0x000002d0, 0x000002d1, 0x000002e0, 0x000002e4, 0x000002ee, 0x000002ee, 0x0000037a, 0x0000037a, 0x00000559, 0x00000559, 0x00000640, 0x00000640, 0x000006e5, 0x000006e6, 0x00000e46, 0x00000e46, 0x00000ec6, 0x00000ec6, 0x000017d7, 0x000017d7, 0x00001843, 0x00001843, 0x00003005, 0x00003005, 0x00003031, 0x00003035, 0x0000303b, 0x0000303b, 0x0000309d, 0x0000309e, 0x000030fc, 0x000030fe, 0x0000ff70, 0x0000ff70, 0x0000ff9e, 0x0000ff9f, 0x000001bb, 0x000001bb, 0x000001c0, 0x000001c3, 0x000005d0, 0x000005ea, 0x000005f0, 0x000005f2, 0x00000621, 0x0000063a, 0x00000641, 0x0000064a, 0x0000066e, 0x0000066f, 0x00000671, 0x000006d3, 0x000006d5, 0x000006d5, 0x000006fa, 0x000006fc, 0x00000710, 0x00000710, 0x00000712, 0x0000072c, 0x00000780, 0x000007a5, 0x000007b1, 0x000007b1, 0x00000905, 0x00000939, 0x0000093d, 0x0000093d, 0x00000950, 0x00000950, 0x00000958, 0x00000961, 0x00000985, 0x0000098c, 0x0000098f, 0x00000990, 0x00000993, 0x000009a8, 0x000009aa, 0x000009b0, 0x000009b2, 0x000009b2, 0x000009b6, 0x000009b9, 0x000009dc, 0x000009dd, 0x000009df, 0x000009e1, 0x000009f0, 0x000009f1, 0x00000a05, 0x00000a0a, 0x00000a0f, 0x00000a10, 0x00000a13, 0x00000a28, 0x00000a2a, 0x00000a30, 0x00000a32, 0x00000a33, 0x00000a35, 0x00000a36, 0x00000a38, 0x00000a39, 0x00000a59, 0x00000a5c, 0x00000a5e, 0x00000a5e, 0x00000a72, 0x00000a74, 0x00000a85, 0x00000a8b, 0x00000a8d, 0x00000a8d, 0x00000a8f, 0x00000a91, 0x00000a93, 0x00000aa8, 0x00000aaa, 0x00000ab0, 0x00000ab2, 0x00000ab3, 0x00000ab5, 0x00000ab9, 0x00000abd, 0x00000abd, 0x00000ad0, 0x00000ad0, 0x00000ae0, 0x00000ae0, 0x00000b05, 0x00000b0c, 0x00000b0f, 0x00000b10, 0x00000b13, 0x00000b28, 0x00000b2a, 0x00000b30, 0x00000b32, 0x00000b33, 0x00000b36, 0x00000b39, 0x00000b3d, 0x00000b3d, 0x00000b5c, 0x00000b5d, 0x00000b5f, 0x00000b61, 0x00000b83, 0x00000b83, 0x00000b85, 0x00000b8a, 0x00000b8e, 0x00000b90, 0x00000b92, 0x00000b95, 0x00000b99, 0x00000b9a, 0x00000b9c, 0x00000b9c, 0x00000b9e, 0x00000b9f, 0x00000ba3, 0x00000ba4, 0x00000ba8, 0x00000baa, 0x00000bae, 0x00000bb5, 0x00000bb7, 0x00000bb9, 0x00000c05, 0x00000c0c, 0x00000c0e, 0x00000c10, 0x00000c12, 0x00000c28, 0x00000c2a, 0x00000c33, 0x00000c35, 0x00000c39, 0x00000c60, 0x00000c61, 0x00000c85, 0x00000c8c, 0x00000c8e, 0x00000c90, 0x00000c92, 0x00000ca8, 0x00000caa, 0x00000cb3, 0x00000cb5, 0x00000cb9, 0x00000cde, 0x00000cde, 0x00000ce0, 0x00000ce1, 0x00000d05, 0x00000d0c, 0x00000d0e, 0x00000d10, 0x00000d12, 0x00000d28, 0x00000d2a, 0x00000d39, 0x00000d60, 0x00000d61, 0x00000d85, 0x00000d96, 0x00000d9a, 0x00000db1, 0x00000db3, 0x00000dbb, 0x00000dbd, 0x00000dbd, 0x00000dc0, 0x00000dc6, 0x00000e01, 0x00000e30, 0x00000e32, 0x00000e33, 0x00000e40, 0x00000e45, 0x00000e81, 0x00000e82, 0x00000e84, 0x00000e84, 0x00000e87, 0x00000e88, 0x00000e8a, 0x00000e8a, 0x00000e8d, 0x00000e8d, 0x00000e94, 0x00000e97, 0x00000e99, 0x00000e9f, 0x00000ea1, 0x00000ea3, 0x00000ea5, 0x00000ea5, 0x00000ea7, 0x00000ea7, 0x00000eaa, 0x00000eab, 0x00000ead, 0x00000eb0, 0x00000eb2, 0x00000eb3, 0x00000ebd, 0x00000ebd, 0x00000ec0, 0x00000ec4, 0x00000edc, 0x00000edd, 0x00000f00, 0x00000f00, 0x00000f40, 0x00000f47, 0x00000f49, 0x00000f6a, 0x00000f88, 0x00000f8b, 0x00001000, 0x00001021, 0x00001023, 0x00001027, 0x00001029, 0x0000102a, 0x00001050, 0x00001055, 0x000010d0, 0x000010f8, 0x00001100, 0x00001159, 0x0000115f, 0x000011a2, 0x000011a8, 0x000011f9, 0x00001200, 0x00001206, 0x00001208, 0x00001246, 0x00001248, 0x00001248, 0x0000124a, 0x0000124d, 0x00001250, 0x00001256, 0x00001258, 0x00001258, 0x0000125a, 0x0000125d, 0x00001260, 0x00001286, 0x00001288, 0x00001288, 0x0000128a, 0x0000128d, 0x00001290, 0x000012ae, 0x000012b0, 0x000012b0, 0x000012b2, 0x000012b5, 0x000012b8, 0x000012be, 0x000012c0, 0x000012c0, 0x000012c2, 0x000012c5, 0x000012c8, 0x000012ce, 0x000012d0, 0x000012d6, 0x000012d8, 0x000012ee, 0x000012f0, 0x0000130e, 0x00001310, 0x00001310, 0x00001312, 0x00001315, 0x00001318, 0x0000131e, 0x00001320, 0x00001346, 0x00001348, 0x0000135a, 0x000013a0, 0x000013f4, 0x00001401, 0x0000166c, 0x0000166f, 0x00001676, 0x00001681, 0x0000169a, 0x000016a0, 0x000016ea, 0x00001700, 0x0000170c, 0x0000170e, 0x00001711, 0x00001720, 0x00001731, 0x00001740, 0x00001751, 0x00001760, 0x0000176c, 0x0000176e, 0x00001770, 0x00001780, 0x000017b3, 0x000017dc, 0x000017dc, 0x00001820, 0x00001842, 0x00001844, 0x00001877, 0x00001880, 0x000018a8, 0x00002135, 0x00002138, 0x00003006, 0x00003006, 0x0000303c, 0x0000303c, 0x00003041, 0x00003096, 0x0000309f, 0x0000309f, 0x000030a1, 0x000030fa, 0x000030ff, 0x000030ff, 0x00003105, 0x0000312c, 0x00003131, 0x0000318e, 0x000031a0, 0x000031b7, 0x000031f0, 0x000031ff, 0x00003400, 0x00004db5, 0x00004e00, 0x0000a48c, 0x0000ac00, 0x0000d7a3, 0x0000f900, 0x0000faff, 0x0000fb1d, 0x0000fb1d, 0x0000fb1f, 0x0000fb28, 0x0000fb2a, 0x0000fb36, 0x0000fb38, 0x0000fb3c, 0x0000fb3e, 0x0000fb3e, 0x0000fb40, 0x0000fb41, 0x0000fb43, 0x0000fb44, 0x0000fb46, 0x0000fbb1, 0x0000fbd3, 0x0000fd3d, 0x0000fd50, 0x0000fd8f, 0x0000fd92, 0x0000fdc7, 0x0000fdf0, 0x0000fdfb, 0x0000fe70, 0x0000fe74, 0x0000fe76, 0x0000fefc, 0x0000ff66, 0x0000ff6f, 0x0000ff71, 0x0000ff9d, 0x0000ffa0, 0x0000ffbe, 0x0000ffc2, 0x0000ffc7, 0x0000ffca, 0x0000ffcf, 0x0000ffd2, 0x0000ffd7, 0x0000ffda, 0x0000ffdc, 0x00010300, 0x0001031e, 0x00010330, 0x00010349, 0x00020000, 0x0002a6d6, 0x0002f800, 0x0002fa1d, 0x0000005f, 0x0000005f, 0x0000203f, 0x00002040, 0x000030fb, 0x000030fb, 0x0000fe33, 0x0000fe34, 0x0000fe4d, 0x0000fe4f, 0x0000ff3f, 0x0000ff3f, 0x0000ff65, 0x0000ff65, 0x0000002d, 0x0000002d, 0x000000ad, 0x000000ad, 0x0000058a, 0x0000058a, 0x00001806, 0x00001806, 0x00002010, 0x00002015, 0x0000301c, 0x0000301c, 0x00003030, 0x00003030, 0x000030a0, 0x000030a0, 0x0000fe31, 0x0000fe32, 0x0000fe58, 0x0000fe58, 0x0000fe63, 0x0000fe63, 0x0000ff0d, 0x0000ff0d, 0x00000028, 0x00000028, 0x0000005b, 0x0000005b, 0x0000007b, 0x0000007b, 0x00000f3a, 0x00000f3a, 0x00000f3c, 0x00000f3c, 0x0000169b, 0x0000169b, 0x0000201a, 0x0000201a, 0x0000201e, 0x0000201e, 0x00002045, 0x00002045, 0x0000207d, 0x0000207d, 0x0000208d, 0x0000208d, 0x00002329, 0x00002329, 0x000023b4, 0x000023b4, 0x00002768, 0x00002768, 0x0000276a, 0x0000276a, 0x0000276c, 0x0000276c, 0x0000276e, 0x0000276e, 0x00002770, 0x00002770, 0x00002772, 0x00002772, 0x00002774, 0x00002774, 0x000027e6, 0x000027e6, 0x000027e8, 0x000027e8, 0x000027ea, 0x000027ea, 0x00002983, 0x00002983, 0x00002985, 0x00002985, 0x00002987, 0x00002987, 0x00002989, 0x00002989, 0x0000298b, 0x0000298b, 0x0000298d, 0x0000298d, 0x0000298f, 0x0000298f, 0x00002991, 0x00002991, 0x00002993, 0x00002993, 0x00002995, 0x00002995, 0x00002997, 0x00002997, 0x000029d8, 0x000029d8, 0x000029da, 0x000029da, 0x000029fc, 0x000029fc, 0x00003008, 0x00003008, 0x0000300a, 0x0000300a, 0x0000300c, 0x0000300c, 0x0000300e, 0x0000300e, 0x00003010, 0x00003010, 0x00003014, 0x00003014, 0x00003016, 0x00003016, 0x00003018, 0x00003018, 0x0000301a, 0x0000301a, 0x0000301d, 0x0000301d, 0x0000fd3e, 0x0000fd3e, 0x0000fe35, 0x0000fe35, 0x0000fe37, 0x0000fe37, 0x0000fe39, 0x0000fe39, 0x0000fe3b, 0x0000fe3b, 0x0000fe3d, 0x0000fe3d, 0x0000fe3f, 0x0000fe3f, 0x0000fe41, 0x0000fe41, 0x0000fe43, 0x0000fe43, 0x0000fe59, 0x0000fe59, 0x0000fe5b, 0x0000fe5b, 0x0000fe5d, 0x0000fe5d, 0x0000ff08, 0x0000ff08, 0x0000ff3b, 0x0000ff3b, 0x0000ff5b, 0x0000ff5b, 0x0000ff5f, 0x0000ff5f, 0x0000ff62, 0x0000ff62, 0x00000029, 0x00000029, 0x0000005d, 0x0000005d, 0x0000007d, 0x0000007d, 0x00000f3b, 0x00000f3b, 0x00000f3d, 0x00000f3d, 0x0000169c, 0x0000169c, 0x00002046, 0x00002046, 0x0000207e, 0x0000207e, 0x0000208e, 0x0000208e, 0x0000232a, 0x0000232a, 0x000023b5, 0x000023b5, 0x00002769, 0x00002769, 0x0000276b, 0x0000276b, 0x0000276d, 0x0000276d, 0x0000276f, 0x0000276f, 0x00002771, 0x00002771, 0x00002773, 0x00002773, 0x00002775, 0x00002775, 0x000027e7, 0x000027e7, 0x000027e9, 0x000027e9, 0x000027eb, 0x000027eb, 0x00002984, 0x00002984, 0x00002986, 0x00002986, 0x00002988, 0x00002988, 0x0000298a, 0x0000298a, 0x0000298c, 0x0000298c, 0x0000298e, 0x0000298e, 0x00002990, 0x00002990, 0x00002992, 0x00002992, 0x00002994, 0x00002994, 0x00002996, 0x00002996, 0x00002998, 0x00002998, 0x000029d9, 0x000029d9, 0x000029db, 0x000029db, 0x000029fd, 0x000029fd, 0x00003009, 0x00003009, 0x0000300b, 0x0000300b, 0x0000300d, 0x0000300d, 0x0000300f, 0x0000300f, 0x00003011, 0x00003011, 0x00003015, 0x00003015, 0x00003017, 0x00003017, 0x00003019, 0x00003019, 0x0000301b, 0x0000301b, 0x0000301e, 0x0000301f, 0x0000fd3f, 0x0000fd3f, 0x0000fe36, 0x0000fe36, 0x0000fe38, 0x0000fe38, 0x0000fe3a, 0x0000fe3a, 0x0000fe3c, 0x0000fe3c, 0x0000fe3e, 0x0000fe3e, 0x0000fe40, 0x0000fe40, 0x0000fe42, 0x0000fe42, 0x0000fe44, 0x0000fe44, 0x0000fe5a, 0x0000fe5a, 0x0000fe5c, 0x0000fe5c, 0x0000fe5e, 0x0000fe5e, 0x0000ff09, 0x0000ff09, 0x0000ff3d, 0x0000ff3d, 0x0000ff5d, 0x0000ff5d, 0x0000ff60, 0x0000ff60, 0x0000ff63, 0x0000ff63, 0x00000021, 0x00000023, 0x00000025, 0x00000027, 0x0000002a, 0x0000002a, 0x0000002c, 0x0000002c, 0x0000002e, 0x0000002f, 0x0000003a, 0x0000003b, 0x0000003f, 0x00000040, 0x0000005c, 0x0000005c, 0x000000a1, 0x000000a1, 0x000000b7, 0x000000b7, 0x000000bf, 0x000000bf, 0x0000037e, 0x0000037e, 0x00000387, 0x00000387, 0x0000055a, 0x0000055f, 0x00000589, 0x00000589, 0x000005be, 0x000005be, 0x000005c0, 0x000005c0, 0x000005c3, 0x000005c3, 0x000005f3, 0x000005f4, 0x0000060c, 0x0000060c, 0x0000061b, 0x0000061b, 0x0000061f, 0x0000061f, 0x0000066a, 0x0000066d, 0x000006d4, 0x000006d4, 0x00000700, 0x0000070d, 0x00000964, 0x00000965, 0x00000970, 0x00000970, 0x00000df4, 0x00000df4, 0x00000e4f, 0x00000e4f, 0x00000e5a, 0x00000e5b, 0x00000f04, 0x00000f12, 0x00000f85, 0x00000f85, 0x0000104a, 0x0000104f, 0x000010fb, 0x000010fb, 0x00001361, 0x00001368, 0x0000166d, 0x0000166e, 0x000016eb, 0x000016ed, 0x00001735, 0x00001736, 0x000017d4, 0x000017d6, 0x000017d8, 0x000017da, 0x00001800, 0x00001805, 0x00001807, 0x0000180a, 0x00002016, 0x00002017, 0x00002020, 0x00002027, 0x00002030, 0x00002038, 0x0000203b, 0x0000203e, 0x00002041, 0x00002043, 0x00002047, 0x00002051, 0x00002057, 0x00002057, 0x000023b6, 0x000023b6, 0x00003001, 0x00003003, 0x0000303d, 0x0000303d, 0x0000fe30, 0x0000fe30, 0x0000fe45, 0x0000fe46, 0x0000fe49, 0x0000fe4c, 0x0000fe50, 0x0000fe52, 0x0000fe54, 0x0000fe57, 0x0000fe5f, 0x0000fe61, 0x0000fe68, 0x0000fe68, 0x0000fe6a, 0x0000fe6b, 0x0000ff01, 0x0000ff03, 0x0000ff05, 0x0000ff07, 0x0000ff0a, 0x0000ff0a, 0x0000ff0c, 0x0000ff0c, 0x0000ff0e, 0x0000ff0f, 0x0000ff1a, 0x0000ff1b, 0x0000ff1f, 0x0000ff20, 0x0000ff3c, 0x0000ff3c, 0x0000ff61, 0x0000ff61, 0x0000ff64, 0x0000ff64, 0x0000002b, 0x0000002b, 0x0000003c, 0x0000003e, 0x0000007c, 0x0000007c, 0x0000007e, 0x0000007e, 0x000000ac, 0x000000ac, 0x000000b1, 0x000000b1, 0x000000d7, 0x000000d7, 0x000000f7, 0x000000f7, 0x000003f6, 0x000003f6, 0x00002044, 0x00002044, 0x00002052, 0x00002052, 0x0000207a, 0x0000207c, 0x0000208a, 0x0000208c, 0x00002140, 0x00002144, 0x0000214b, 0x0000214b, 0x00002190, 0x00002194, 0x0000219a, 0x0000219b, 0x000021a0, 0x000021a0, 0x000021a3, 0x000021a3, 0x000021a6, 0x000021a6, 0x000021ae, 0x000021ae, 0x000021ce, 0x000021cf, 0x000021d2, 0x000021d2, 0x000021d4, 0x000021d4, 0x000021f4, 0x000022ff, 0x00002308, 0x0000230b, 0x00002320, 0x00002321, 0x0000237c, 0x0000237c, 0x0000239b, 0x000023b3, 0x000025b7, 0x000025b7, 0x000025c1, 0x000025c1, 0x000025f8, 0x000025ff, 0x0000266f, 0x0000266f, 0x000027d0, 0x000027e5, 0x000027f0, 0x000027ff, 0x00002900, 0x00002982, 0x00002999, 0x000029d7, 0x000029dc, 0x000029fb, 0x000029fe, 0x00002aff, 0x0000fb29, 0x0000fb29, 0x0000fe62, 0x0000fe62, 0x0000fe64, 0x0000fe66, 0x0000ff0b, 0x0000ff0b, 0x0000ff1c, 0x0000ff1e, 0x0000ff5c, 0x0000ff5c, 0x0000ff5e, 0x0000ff5e, 0x0000ffe2, 0x0000ffe2, 0x0000ffe9, 0x0000ffec, 0x0001d6c1, 0x0001d6c1, 0x0001d6db, 0x0001d6db, 0x0001d6fb, 0x0001d6fb, 0x0001d715, 0x0001d715, 0x0001d735, 0x0001d735, 0x0001d74f, 0x0001d74f, 0x0001d76f, 0x0001d76f, 0x0001d789, 0x0001d789, 0x0001d7a9, 0x0001d7a9, 0x0001d7c3, 0x0001d7c3, 0x00000024, 0x00000024, 0x000000a2, 0x000000a5, 0x000009f2, 0x000009f3, 0x00000e3f, 0x00000e3f, 0x000017db, 0x000017db, 0x000020a0, 0x000020b1, 0x0000fdfc, 0x0000fdfc, 0x0000fe69, 0x0000fe69, 0x0000ff04, 0x0000ff04, 0x0000ffe0, 0x0000ffe1, 0x0000ffe5, 0x0000ffe6, 0x0000005e, 0x0000005e, 0x00000060, 0x00000060, 0x000000a8, 0x000000a8, 0x000000af, 0x000000af, 0x000000b4, 0x000000b4, 0x000000b8, 0x000000b8, 0x000002b9, 0x000002ba, 0x000002c2, 0x000002cf, 0x000002d2, 0x000002df, 0x000002e5, 0x000002ed, 0x00000374, 0x00000375, 0x00000384, 0x00000385, 0x00001fbd, 0x00001fbd, 0x00001fbf, 0x00001fc1, 0x00001fcd, 0x00001fcf, 0x00001fdd, 0x00001fdf, 0x00001fed, 0x00001fef, 0x00001ffd, 0x00001ffe, 0x0000309b, 0x0000309c, 0x0000ff3e, 0x0000ff3e, 0x0000ff40, 0x0000ff40, 0x0000ffe3, 0x0000ffe3, 0x000000a6, 0x000000a7, 0x000000a9, 0x000000a9, 0x000000ae, 0x000000ae, 0x000000b0, 0x000000b0, 0x000000b6, 0x000000b6, 0x00000482, 0x00000482, 0x000006e9, 0x000006e9, 0x000006fd, 0x000006fe, 0x000009fa, 0x000009fa, 0x00000b70, 0x00000b70, 0x00000f01, 0x00000f03, 0x00000f13, 0x00000f17, 0x00000f1a, 0x00000f1f, 0x00000f34, 0x00000f34, 0x00000f36, 0x00000f36, 0x00000f38, 0x00000f38, 0x00000fbe, 0x00000fc5, 0x00000fc7, 0x00000fcc, 0x00000fcf, 0x00000fcf, 0x00002100, 0x00002101, 0x00002103, 0x00002106, 0x00002108, 0x00002109, 0x00002114, 0x00002114, 0x00002116, 0x00002118, 0x0000211e, 0x00002123, 0x00002125, 0x00002125, 0x00002127, 0x00002127, 0x00002129, 0x00002129, 0x0000212e, 0x0000212e, 0x00002132, 0x00002132, 0x0000213a, 0x0000213a, 0x0000214a, 0x0000214a, 0x00002195, 0x00002199, 0x0000219c, 0x0000219f, 0x000021a1, 0x000021a2, 0x000021a4, 0x000021a5, 0x000021a7, 0x000021ad, 0x000021af, 0x000021cd, 0x000021d0, 0x000021d1, 0x000021d3, 0x000021d3, 0x000021d5, 0x000021f3, 0x00002300, 0x00002307, 0x0000230c, 0x0000231f, 0x00002322, 0x00002328, 0x0000232b, 0x0000237b, 0x0000237d, 0x0000239a, 0x000023b7, 0x000023ce, 0x00002400, 0x00002426, 0x00002440, 0x0000244a, 0x0000249c, 0x000024e9, 0x00002500, 0x000025b6, 0x000025b8, 0x000025c0, 0x000025c2, 0x000025f7, 0x00002600, 0x00002613, 0x00002616, 0x00002617, 0x00002619, 0x0000266e, 0x00002670, 0x0000267d, 0x00002680, 0x00002689, 0x00002701, 0x00002704, 0x00002706, 0x00002709, 0x0000270c, 0x00002727, 0x00002729, 0x0000274b, 0x0000274d, 0x0000274d, 0x0000274f, 0x00002752, 0x00002756, 0x00002756, 0x00002758, 0x0000275e, 0x00002761, 0x00002767, 0x00002794, 0x00002794, 0x00002798, 0x000027af, 0x000027b1, 0x000027be, 0x00002800, 0x000028ff, 0x00002e80, 0x00002e99, 0x00002e9b, 0x00002ef3, 0x00002f00, 0x00002fd5, 0x00002ff0, 0x00002ffb, 0x00003004, 0x00003004, 0x00003012, 0x00003013, 0x00003020, 0x00003020, 0x00003036, 0x00003037, 0x0000303e, 0x0000303f, 0x00003190, 0x00003191, 0x00003196, 0x0000319f, 0x00003200, 0x0000321c, 0x0000322a, 0x00003243, 0x00003260, 0x0000327b, 0x0000327f, 0x0000327f, 0x0000328a, 0x000032b0, 0x000032c0, 0x000032cb, 0x000032d0, 0x000032fe, 0x00003300, 0x00003376, 0x0000337b, 0x000033dd, 0x000033e0, 0x000033fe, 0x0000a490, 0x0000a4c6, 0x0000ffe4, 0x0000ffe4, 0x0000ffe8, 0x0000ffe8, 0x0000ffed, 0x0000ffee, 0x0000fffc, 0x0000fffd, 0x0001d000, 0x0001d0f5, 0x0001d100, 0x0001d126, 0x0001d12a, 0x0001d164, 0x0001d16a, 0x0001d16c, 0x0001d183, 0x0001d184, 0x0001d18c, 0x0001d1a9, 0x0001d1ae, 0x0001d1dd, 0x00000041, 0x0000005a, 0x00000061, 0x0000007a, 0x000000aa, 0x000000aa, 0x000000b5, 0x000000b5, 0x000000ba, 0x000000ba, 0x000000c0, 0x000000d6, 0x000000d8, 0x000000f6, 0x000000f8, 0x00000220, 0x00000222, 0x00000233, 0x00000250, 0x000002ad, 0x000002b0, 0x000002b8, 0x000002bb, 0x000002c1, 0x000002d0, 0x000002d1, 0x000002e0, 0x000002e4, 0x000002ee, 0x000002ee, 0x0000037a, 0x0000037a, 0x00000386, 0x00000386, 0x00000388, 0x0000038a, 0x0000038c, 0x0000038c, 0x0000038e, 0x000003a1, 0x000003a3, 0x000003ce, 0x000003d0, 0x000003f5, 0x00000400, 0x00000482, 0x0000048a, 0x000004ce, 0x000004d0, 0x000004f5, 0x000004f8, 0x000004f9, 0x00000500, 0x0000050f, 0x00000531, 0x00000556, 0x00000559, 0x0000055f, 0x00000561, 0x00000587, 0x00000589, 0x00000589, 0x00000903, 0x00000903, 0x00000905, 0x00000939, 0x0000093d, 0x00000940, 0x00000949, 0x0000094c, 0x00000950, 0x00000950, 0x00000958, 0x00000961, 0x00000964, 0x00000970, 0x00000982, 0x00000983, 0x00000985, 0x0000098c, 0x0000098f, 0x00000990, 0x00000993, 0x000009a8, 0x000009aa, 0x000009b0, 0x000009b2, 0x000009b2, 0x000009b6, 0x000009b9, 0x000009be, 0x000009c0, 0x000009c7, 0x000009c8, 0x000009cb, 0x000009cc, 0x000009d7, 0x000009d7, 0x000009dc, 0x000009dd, 0x000009df, 0x000009e1, 0x000009e6, 0x000009f1, 0x000009f4, 0x000009fa, 0x00000a05, 0x00000a0a, 0x00000a0f, 0x00000a10, 0x00000a13, 0x00000a28, 0x00000a2a, 0x00000a30, 0x00000a32, 0x00000a33, 0x00000a35, 0x00000a36, 0x00000a38, 0x00000a39, 0x00000a3e, 0x00000a40, 0x00000a59, 0x00000a5c, 0x00000a5e, 0x00000a5e, 0x00000a66, 0x00000a6f, 0x00000a72, 0x00000a74, 0x00000a83, 0x00000a83, 0x00000a85, 0x00000a8b, 0x00000a8d, 0x00000a8d, 0x00000a8f, 0x00000a91, 0x00000a93, 0x00000aa8, 0x00000aaa, 0x00000ab0, 0x00000ab2, 0x00000ab3, 0x00000ab5, 0x00000ab9, 0x00000abd, 0x00000ac0, 0x00000ac9, 0x00000ac9, 0x00000acb, 0x00000acc, 0x00000ad0, 0x00000ad0, 0x00000ae0, 0x00000ae0, 0x00000ae6, 0x00000aef, 0x00000b02, 0x00000b03, 0x00000b05, 0x00000b0c, 0x00000b0f, 0x00000b10, 0x00000b13, 0x00000b28, 0x00000b2a, 0x00000b30, 0x00000b32, 0x00000b33, 0x00000b36, 0x00000b39, 0x00000b3d, 0x00000b3e, 0x00000b40, 0x00000b40, 0x00000b47, 0x00000b48, 0x00000b4b, 0x00000b4c, 0x00000b57, 0x00000b57, 0x00000b5c, 0x00000b5d, 0x00000b5f, 0x00000b61, 0x00000b66, 0x00000b70, 0x00000b83, 0x00000b83, 0x00000b85, 0x00000b8a, 0x00000b8e, 0x00000b90, 0x00000b92, 0x00000b95, 0x00000b99, 0x00000b9a, 0x00000b9c, 0x00000b9c, 0x00000b9e, 0x00000b9f, 0x00000ba3, 0x00000ba4, 0x00000ba8, 0x00000baa, 0x00000bae, 0x00000bb5, 0x00000bb7, 0x00000bb9, 0x00000bbe, 0x00000bbf, 0x00000bc1, 0x00000bc2, 0x00000bc6, 0x00000bc8, 0x00000bca, 0x00000bcc, 0x00000bd7, 0x00000bd7, 0x00000be7, 0x00000bf2, 0x00000c01, 0x00000c03, 0x00000c05, 0x00000c0c, 0x00000c0e, 0x00000c10, 0x00000c12, 0x00000c28, 0x00000c2a, 0x00000c33, 0x00000c35, 0x00000c39, 0x00000c41, 0x00000c44, 0x00000c60, 0x00000c61, 0x00000c66, 0x00000c6f, 0x00000c82, 0x00000c83, 0x00000c85, 0x00000c8c, 0x00000c8e, 0x00000c90, 0x00000c92, 0x00000ca8, 0x00000caa, 0x00000cb3, 0x00000cb5, 0x00000cb9, 0x00000cbe, 0x00000cbe, 0x00000cc0, 0x00000cc4, 0x00000cc7, 0x00000cc8, 0x00000cca, 0x00000ccb, 0x00000cd5, 0x00000cd6, 0x00000cde, 0x00000cde, 0x00000ce0, 0x00000ce1, 0x00000ce6, 0x00000cef, 0x00000d02, 0x00000d03, 0x00000d05, 0x00000d0c, 0x00000d0e, 0x00000d10, 0x00000d12, 0x00000d28, 0x00000d2a, 0x00000d39, 0x00000d3e, 0x00000d40, 0x00000d46, 0x00000d48, 0x00000d4a, 0x00000d4c, 0x00000d57, 0x00000d57, 0x00000d60, 0x00000d61, 0x00000d66, 0x00000d6f, 0x00000d82, 0x00000d83, 0x00000d85, 0x00000d96, 0x00000d9a, 0x00000db1, 0x00000db3, 0x00000dbb, 0x00000dbd, 0x00000dbd, 0x00000dc0, 0x00000dc6, 0x00000dcf, 0x00000dd1, 0x00000dd8, 0x00000ddf, 0x00000df2, 0x00000df4, 0x00000e01, 0x00000e30, 0x00000e32, 0x00000e33, 0x00000e40, 0x00000e46, 0x00000e4f, 0x00000e5b, 0x00000e81, 0x00000e82, 0x00000e84, 0x00000e84, 0x00000e87, 0x00000e88, 0x00000e8a, 0x00000e8a, 0x00000e8d, 0x00000e8d, 0x00000e94, 0x00000e97, 0x00000e99, 0x00000e9f, 0x00000ea1, 0x00000ea3, 0x00000ea5, 0x00000ea5, 0x00000ea7, 0x00000ea7, 0x00000eaa, 0x00000eab, 0x00000ead, 0x00000eb0, 0x00000eb2, 0x00000eb3, 0x00000ebd, 0x00000ebd, 0x00000ec0, 0x00000ec4, 0x00000ec6, 0x00000ec6, 0x00000ed0, 0x00000ed9, 0x00000edc, 0x00000edd, 0x00000f00, 0x00000f17, 0x00000f1a, 0x00000f34, 0x00000f36, 0x00000f36, 0x00000f38, 0x00000f38, 0x00000f3e, 0x00000f47, 0x00000f49, 0x00000f6a, 0x00000f7f, 0x00000f7f, 0x00000f85, 0x00000f85, 0x00000f88, 0x00000f8b, 0x00000fbe, 0x00000fc5, 0x00000fc7, 0x00000fcc, 0x00000fcf, 0x00000fcf, 0x00001000, 0x00001021, 0x00001023, 0x00001027, 0x00001029, 0x0000102a, 0x0000102c, 0x0000102c, 0x00001031, 0x00001031, 0x00001038, 0x00001038, 0x00001040, 0x00001057, 0x000010a0, 0x000010c5, 0x000010d0, 0x000010f8, 0x000010fb, 0x000010fb, 0x00001100, 0x00001159, 0x0000115f, 0x000011a2, 0x000011a8, 0x000011f9, 0x00001200, 0x00001206, 0x00001208, 0x00001246, 0x00001248, 0x00001248, 0x0000124a, 0x0000124d, 0x00001250, 0x00001256, 0x00001258, 0x00001258, 0x0000125a, 0x0000125d, 0x00001260, 0x00001286, 0x00001288, 0x00001288, 0x0000128a, 0x0000128d, 0x00001290, 0x000012ae, 0x000012b0, 0x000012b0, 0x000012b2, 0x000012b5, 0x000012b8, 0x000012be, 0x000012c0, 0x000012c0, 0x000012c2, 0x000012c5, 0x000012c8, 0x000012ce, 0x000012d0, 0x000012d6, 0x000012d8, 0x000012ee, 0x000012f0, 0x0000130e, 0x00001310, 0x00001310, 0x00001312, 0x00001315, 0x00001318, 0x0000131e, 0x00001320, 0x00001346, 0x00001348, 0x0000135a, 0x00001361, 0x0000137c, 0x000013a0, 0x000013f4, 0x00001401, 0x00001676, 0x00001681, 0x0000169a, 0x000016a0, 0x000016f0, 0x00001700, 0x0000170c, 0x0000170e, 0x00001711, 0x00001720, 0x00001731, 0x00001735, 0x00001736, 0x00001740, 0x00001751, 0x00001760, 0x0000176c, 0x0000176e, 0x00001770, 0x00001780, 0x000017b6, 0x000017be, 0x000017c5, 0x000017c7, 0x000017c8, 0x000017d4, 0x000017da, 0x000017dc, 0x000017dc, 0x000017e0, 0x000017e9, 0x00001810, 0x00001819, 0x00001820, 0x00001877, 0x00001880, 0x000018a8, 0x00001e00, 0x00001e9b, 0x00001ea0, 0x00001ef9, 0x00001f00, 0x00001f15, 0x00001f18, 0x00001f1d, 0x00001f20, 0x00001f45, 0x00001f48, 0x00001f4d, 0x00001f50, 0x00001f57, 0x00001f59, 0x00001f59, 0x00001f5b, 0x00001f5b, 0x00001f5d, 0x00001f5d, 0x00001f5f, 0x00001f7d, 0x00001f80, 0x00001fb4, 0x00001fb6, 0x00001fbc, 0x00001fbe, 0x00001fbe, 0x00001fc2, 0x00001fc4, 0x00001fc6, 0x00001fcc, 0x00001fd0, 0x00001fd3, 0x00001fd6, 0x00001fdb, 0x00001fe0, 0x00001fec, 0x00001ff2, 0x00001ff4, 0x00001ff6, 0x00001ffc, 0x0000200e, 0x0000200e, 0x00002071, 0x00002071, 0x0000207f, 0x0000207f, 0x00002102, 0x00002102, 0x00002107, 0x00002107, 0x0000210a, 0x00002113, 0x00002115, 0x00002115, 0x00002119, 0x0000211d, 0x00002124, 0x00002124, 0x00002126, 0x00002126, 0x00002128, 0x00002128, 0x0000212a, 0x0000212d, 0x0000212f, 0x00002131, 0x00002133, 0x00002139, 0x0000213d, 0x0000213f, 0x00002145, 0x00002149, 0x00002160, 0x00002183, 0x00002336, 0x0000237a, 0x00002395, 0x00002395, 0x0000249c, 0x000024e9, 0x00003005, 0x00003007, 0x00003021, 0x00003029, 0x00003031, 0x00003035, 0x00003038, 0x0000303c, 0x00003041, 0x00003096, 0x0000309d, 0x0000309f, 0x000030a1, 0x000030fa, 0x000030fc, 0x000030ff, 0x00003105, 0x0000312c, 0x00003131, 0x0000318e, 0x00003190, 0x000031b7, 0x000031f0, 0x0000321c, 0x00003220, 0x00003243, 0x00003260, 0x0000327b, 0x0000327f, 0x000032b0, 0x000032c0, 0x000032cb, 0x000032d0, 0x000032fe, 0x00003300, 0x00003376, 0x0000337b, 0x000033dd, 0x000033e0, 0x000033fe, 0x00003400, 0x00004db5, 0x00004e00, 0x0000a48c, 0x0000ac00, 0x0000d7a3, 0x0000e000, 0x0000fb06, 0x0000fb13, 0x0000fb17, 0x0000ff21, 0x0000ff3a, 0x0000ff41, 0x0000ff5a, 0x0000ff66, 0x0000ffbe, 0x0000ffc2, 0x0000ffc7, 0x0000ffca, 0x0000ffcf, 0x0000ffd2, 0x0000ffd7, 0x0000ffda, 0x0000ffdc, 0x00010000, 0x0002a6d6, 0x0002f800, 0x0002fa1d, 0x000f0000, 0x000ffffd, 0x00100000, 0x0010fffd, 0x000005be, 0x000005be, 0x000005c0, 0x000005c0, 0x000005c3, 0x000005c3, 0x000005d0, 0x000005ea, 0x000005f0, 0x000005f4, 0x0000200f, 0x0000200f, 0x0000fb1d, 0x0000fb1d, 0x0000fb1f, 0x0000fb28, 0x0000fb2a, 0x0000fb36, 0x0000fb38, 0x0000fb3c, 0x0000fb3e, 0x0000fb3e, 0x0000fb40, 0x0000fb41, 0x0000fb43, 0x0000fb44, 0x0000fb46, 0x0000fb4f, 0x00000030, 0x00000039, 0x000000b2, 0x000000b3, 0x000000b9, 0x000000b9, 0x000006f0, 0x000006f9, 0x00002070, 0x00002070, 0x00002074, 0x00002079, 0x00002080, 0x00002089, 0x00002460, 0x0000249b, 0x000024ea, 0x000024ea, 0x0000ff10, 0x0000ff19, 0x0001d7ce, 0x0001d7ff, 0x0000002f, 0x0000002f, 0x0000ff0f, 0x0000ff0f, 0x00000023, 0x00000025, 0x0000002b, 0x0000002b, 0x0000002d, 0x0000002d, 0x000000a2, 0x000000a5, 0x000000b0, 0x000000b1, 0x0000066a, 0x0000066a, 0x000009f2, 0x000009f3, 0x00000e3f, 0x00000e3f, 0x000017db, 0x000017db, 0x00002030, 0x00002034, 0x0000207a, 0x0000207b, 0x0000208a, 0x0000208b, 0x000020a0, 0x000020b1, 0x0000212e, 0x0000212e, 0x00002212, 0x00002213, 0x0000fb29, 0x0000fb29, 0x0000fe5f, 0x0000fe5f, 0x0000fe62, 0x0000fe63, 0x0000fe69, 0x0000fe6a, 0x0000ff03, 0x0000ff05, 0x0000ff0b, 0x0000ff0b, 0x0000ff0d, 0x0000ff0d, 0x0000ffe0, 0x0000ffe1, 0x0000ffe5, 0x0000ffe6, 0x00000660, 0x00000669, 0x0000066b, 0x0000066c, 0x0000002c, 0x0000002c, 0x0000002e, 0x0000002e, 0x0000003a, 0x0000003a, 0x000000a0, 0x000000a0, 0x0000060c, 0x0000060c, 0x0000fe50, 0x0000fe50, 0x0000fe52, 0x0000fe52, 0x0000fe55, 0x0000fe55, 0x0000ff0c, 0x0000ff0c, 0x0000ff0e, 0x0000ff0e, 0x0000ff1a, 0x0000ff1a, 0x0000000a, 0x0000000a, 0x0000000d, 0x0000000d, 0x0000001c, 0x0000001e, 0x00000085, 0x00000085, 0x00002029, 0x00002029, 0x00000009, 0x00000009, 0x0000000b, 0x0000000b, 0x0000001f, 0x0000001f, 0x0000000c, 0x0000000c, 0x00000020, 0x00000020, 0x00001680, 0x00001680, 0x00002000, 0x0000200a, 0x00002028, 0x00002028, 0x0000202f, 0x0000202f, 0x0000205f, 0x0000205f, 0x00003000, 0x00003000, 0x00000000, 0x00000008, 0x0000000e, 0x0000001b, 0x00000021, 0x00000022, 0x00000026, 0x0000002a, 0x0000003b, 0x00000040, 0x0000005b, 0x00000060, 0x0000007b, 0x00000084, 0x00000086, 0x0000009f, 0x000000a1, 0x000000a1, 0x000000a6, 0x000000a9, 0x000000ab, 0x000000af, 0x000000b4, 0x000000b4, 0x000000b6, 0x000000b8, 0x000000bb, 0x000000bf, 0x000000d7, 0x000000d7, 0x000000f7, 0x000000f7, 0x000002b9, 0x000002ba, 0x000002c2, 0x000002cf, 0x000002d2, 0x000002df, 0x000002e5, 0x000002ed, 0x00000300, 0x0000034f, 0x00000360, 0x0000036f, 0x00000374, 0x00000375, 0x0000037e, 0x0000037e, 0x00000384, 0x00000385, 0x00000387, 0x00000387, 0x000003f6, 0x000003f6, 0x00000483, 0x00000486, 0x00000488, 0x00000489, 0x0000058a, 0x0000058a, 0x00000591, 0x000005a1, 0x000005a3, 0x000005b9, 0x000005bb, 0x000005bd, 0x000005bf, 0x000005bf, 0x000005c1, 0x000005c2, 0x000005c4, 0x000005c4, 0x0000064b, 0x00000655, 0x00000670, 0x00000670, 0x000006d6, 0x000006dc, 0x000006de, 0x000006e4, 0x000006e7, 0x000006ed, 0x0000070f, 0x0000070f, 0x00000711, 0x00000711, 0x00000730, 0x0000074a, 0x000007a6, 0x000007b0, 0x00000901, 0x00000902, 0x0000093c, 0x0000093c, 0x00000941, 0x00000948, 0x0000094d, 0x0000094d, 0x00000951, 0x00000954, 0x00000962, 0x00000963, 0x00000981, 0x00000981, 0x000009bc, 0x000009bc, 0x000009c1, 0x000009c4, 0x000009cd, 0x000009cd, 0x000009e2, 0x000009e3, 0x00000a02, 0x00000a02, 0x00000a3c, 0x00000a3c, 0x00000a41, 0x00000a42, 0x00000a47, 0x00000a48, 0x00000a4b, 0x00000a4d, 0x00000a70, 0x00000a71, 0x00000a81, 0x00000a82, 0x00000abc, 0x00000abc, 0x00000ac1, 0x00000ac5, 0x00000ac7, 0x00000ac8, 0x00000acd, 0x00000acd, 0x00000b01, 0x00000b01, 0x00000b3c, 0x00000b3c, 0x00000b3f, 0x00000b3f, 0x00000b41, 0x00000b43, 0x00000b4d, 0x00000b4d, 0x00000b56, 0x00000b56, 0x00000b82, 0x00000b82, 0x00000bc0, 0x00000bc0, 0x00000bcd, 0x00000bcd, 0x00000c3e, 0x00000c40, 0x00000c46, 0x00000c48, 0x00000c4a, 0x00000c4d, 0x00000c55, 0x00000c56, 0x00000cbf, 0x00000cbf, 0x00000cc6, 0x00000cc6, 0x00000ccc, 0x00000ccd, 0x00000d41, 0x00000d43, 0x00000d4d, 0x00000d4d, 0x00000dca, 0x00000dca, 0x00000dd2, 0x00000dd4, 0x00000dd6, 0x00000dd6, 0x00000e31, 0x00000e31, 0x00000e34, 0x00000e3a, 0x00000e47, 0x00000e4e, 0x00000eb1, 0x00000eb1, 0x00000eb4, 0x00000eb9, 0x00000ebb, 0x00000ebc, 0x00000ec8, 0x00000ecd, 0x00000f18, 0x00000f19, 0x00000f35, 0x00000f35, 0x00000f37, 0x00000f37, 0x00000f39, 0x00000f3d, 0x00000f71, 0x00000f7e, 0x00000f80, 0x00000f84, 0x00000f86, 0x00000f87, 0x00000f90, 0x00000f97, 0x00000f99, 0x00000fbc, 0x00000fc6, 0x00000fc6, 0x0000102d, 0x00001030, 0x00001032, 0x00001032, 0x00001036, 0x00001037, 0x00001039, 0x00001039, 0x00001058, 0x00001059, 0x0000169b, 0x0000169c, 0x00001712, 0x00001714, 0x00001732, 0x00001734, 0x00001752, 0x00001753, 0x00001772, 0x00001773, 0x000017b7, 0x000017bd, 0x000017c6, 0x000017c6, 0x000017c9, 0x000017d3, 0x00001800, 0x0000180e, 0x000018a9, 0x000018a9, 0x00001fbd, 0x00001fbd, 0x00001fbf, 0x00001fc1, 0x00001fcd, 0x00001fcf, 0x00001fdd, 0x00001fdf, 0x00001fed, 0x00001fef, 0x00001ffd, 0x00001ffe, 0x0000200b, 0x0000200d, 0x00002010, 0x00002027, 0x0000202a, 0x0000202e, 0x00002035, 0x00002052, 0x00002057, 0x00002057, 0x00002060, 0x00002063, 0x0000206a, 0x0000206f, 0x0000207c, 0x0000207e, 0x0000208c, 0x0000208e, 0x000020d0, 0x000020ea, 0x00002100, 0x00002101, 0x00002103, 0x00002106, 0x00002108, 0x00002109, 0x00002114, 0x00002114, 0x00002116, 0x00002118, 0x0000211e, 0x00002123, 0x00002125, 0x00002125, 0x00002127, 0x00002127, 0x00002129, 0x00002129, 0x00002132, 0x00002132, 0x0000213a, 0x0000213a, 0x00002140, 0x00002144, 0x0000214a, 0x0000214b, 0x00002153, 0x0000215f, 0x00002190, 0x00002211, 0x00002214, 0x00002335, 0x0000237b, 0x00002394, 0x00002396, 0x000023ce, 0x00002400, 0x00002426, 0x00002440, 0x0000244a, 0x000024eb, 0x000024fe, 0x00002500, 0x00002613, 0x00002616, 0x00002617, 0x00002619, 0x0000267d, 0x00002680, 0x00002689, 0x00002701, 0x00002704, 0x00002706, 0x00002709, 0x0000270c, 0x00002727, 0x00002729, 0x0000274b, 0x0000274d, 0x0000274d, 0x0000274f, 0x00002752, 0x00002756, 0x00002756, 0x00002758, 0x0000275e, 0x00002761, 0x00002794, 0x00002798, 0x000027af, 0x000027b1, 0x000027be, 0x000027d0, 0x000027eb, 0x000027f0, 0x00002aff, 0x00002e80, 0x00002e99, 0x00002e9b, 0x00002ef3, 0x00002f00, 0x00002fd5, 0x00002ff0, 0x00002ffb, 0x00003001, 0x00003004, 0x00003008, 0x00003020, 0x0000302a, 0x00003030, 0x00003036, 0x00003037, 0x0000303d, 0x0000303f, 0x00003099, 0x0000309c, 0x000030a0, 0x000030a0, 0x000030fb, 0x000030fb, 0x00003251, 0x0000325f, 0x000032b1, 0x000032bf, 0x0000a490, 0x0000a4c6, 0x0000fb1e, 0x0000fb1e, 0x0000fd3e, 0x0000fd3f, 0x0000fe00, 0x0000fe0f, 0x0000fe20, 0x0000fe23, 0x0000fe30, 0x0000fe46, 0x0000fe49, 0x0000fe4f, 0x0000fe51, 0x0000fe51, 0x0000fe54, 0x0000fe54, 0x0000fe56, 0x0000fe5e, 0x0000fe60, 0x0000fe61, 0x0000fe64, 0x0000fe66, 0x0000fe68, 0x0000fe68, 0x0000fe6b, 0x0000fe6b, 0x0000feff, 0x0000feff, 0x0000ff01, 0x0000ff02, 0x0000ff06, 0x0000ff0a, 0x0000ff1b, 0x0000ff20, 0x0000ff3b, 0x0000ff40, 0x0000ff5b, 0x0000ff65, 0x0000ffe2, 0x0000ffe4, 0x0000ffe8, 0x0000ffee, 0x0000fff9, 0x0000fffd, 0x0001d167, 0x0001d169, 0x0001d173, 0x0001d182, 0x0001d185, 0x0001d18b, 0x0001d1aa, 0x0001d1ad, 0x000e0001, 0x000e0001, 0x000e0020, 0x000e007f, 0x000000c0, 0x000000c5, 0x000000c7, 0x000000cf, 0x000000d1, 0x000000d6, 0x000000d9, 0x000000dd, 0x000000e0, 0x000000e5, 0x000000e7, 0x000000ef, 0x000000f1, 0x000000f6, 0x000000f9, 0x000000fd, 0x000000ff, 0x0000010f, 0x00000112, 0x00000125, 0x00000128, 0x00000130, 0x00000134, 0x00000137, 0x00000139, 0x0000013e, 0x00000143, 0x00000148, 0x0000014c, 0x00000151, 0x00000154, 0x00000165, 0x00000168, 0x0000017e, 0x000001a0, 0x000001a1, 0x000001af, 0x000001b0, 0x000001cd, 0x000001dc, 0x000001de, 0x000001e3, 0x000001e6, 0x000001f0, 0x000001f4, 0x000001f5, 0x000001f8, 0x0000021b, 0x0000021e, 0x0000021f, 0x00000226, 0x00000233, 0x00000340, 0x00000341, 0x00000343, 0x00000344, 0x00000374, 0x00000374, 0x0000037e, 0x0000037e, 0x00000385, 0x0000038a, 0x0000038c, 0x0000038c, 0x0000038e, 0x00000390, 0x000003aa, 0x000003b0, 0x000003ca, 0x000003ce, 0x000003d3, 0x000003d4, 0x00000400, 0x00000401, 0x00000403, 0x00000403, 0x00000407, 0x00000407, 0x0000040c, 0x0000040e, 0x00000419, 0x00000419, 0x00000439, 0x00000439, 0x00000450, 0x00000451, 0x00000453, 0x00000453, 0x00000457, 0x00000457, 0x0000045c, 0x0000045e, 0x00000476, 0x00000477, 0x000004c1, 0x000004c2, 0x000004d0, 0x000004d3, 0x000004d6, 0x000004d7, 0x000004da, 0x000004df, 0x000004e2, 0x000004e7, 0x000004ea, 0x000004f5, 0x000004f8, 0x000004f9, 0x00000622, 0x00000626, 0x000006c0, 0x000006c0, 0x000006c2, 0x000006c2, 0x000006d3, 0x000006d3, 0x00000929, 0x00000929, 0x00000931, 0x00000931, 0x00000934, 0x00000934, 0x00000958, 0x0000095f, 0x000009cb, 0x000009cc, 0x000009dc, 0x000009dd, 0x000009df, 0x000009df, 0x00000a33, 0x00000a33, 0x00000a36, 0x00000a36, 0x00000a59, 0x00000a5b, 0x00000a5e, 0x00000a5e, 0x00000b48, 0x00000b48, 0x00000b4b, 0x00000b4c, 0x00000b5c, 0x00000b5d, 0x00000b94, 0x00000b94, 0x00000bca, 0x00000bcc, 0x00000c48, 0x00000c48, 0x00000cc0, 0x00000cc0, 0x00000cc7, 0x00000cc8, 0x00000cca, 0x00000ccb, 0x00000d4a, 0x00000d4c, 0x00000dda, 0x00000dda, 0x00000ddc, 0x00000dde, 0x00000f43, 0x00000f43, 0x00000f4d, 0x00000f4d, 0x00000f52, 0x00000f52, 0x00000f57, 0x00000f57, 0x00000f5c, 0x00000f5c, 0x00000f69, 0x00000f69, 0x00000f73, 0x00000f73, 0x00000f75, 0x00000f76, 0x00000f78, 0x00000f78, 0x00000f81, 0x00000f81, 0x00000f93, 0x00000f93, 0x00000f9d, 0x00000f9d, 0x00000fa2, 0x00000fa2, 0x00000fa7, 0x00000fa7, 0x00000fac, 0x00000fac, 0x00000fb9, 0x00000fb9, 0x00001026, 0x00001026, 0x00001e00, 0x00001e99, 0x00001e9b, 0x00001e9b, 0x00001ea0, 0x00001ef9, 0x00001f00, 0x00001f15, 0x00001f18, 0x00001f1d, 0x00001f20, 0x00001f45, 0x00001f48, 0x00001f4d, 0x00001f50, 0x00001f57, 0x00001f59, 0x00001f59, 0x00001f5b, 0x00001f5b, 0x00001f5d, 0x00001f5d, 0x00001f5f, 0x00001f7d, 0x00001f80, 0x00001fb4, 0x00001fb6, 0x00001fbc, 0x00001fbe, 0x00001fbe, 0x00001fc1, 0x00001fc4, 0x00001fc6, 0x00001fd3, 0x00001fd6, 0x00001fdb, 0x00001fdd, 0x00001fef, 0x00001ff2, 0x00001ff4, 0x00001ff6, 0x00001ffd, 0x00002000, 0x00002001, 0x00002126, 0x00002126, 0x0000212a, 0x0000212b, 0x0000219a, 0x0000219b, 0x000021ae, 0x000021ae, 0x000021cd, 0x000021cf, 0x00002204, 0x00002204, 0x00002209, 0x00002209, 0x0000220c, 0x0000220c, 0x00002224, 0x00002224, 0x00002226, 0x00002226, 0x00002241, 0x00002241, 0x00002244, 0x00002244, 0x00002247, 0x00002247, 0x00002249, 0x00002249, 0x00002260, 0x00002260, 0x00002262, 0x00002262, 0x0000226d, 0x00002271, 0x00002274, 0x00002275, 0x00002278, 0x00002279, 0x00002280, 0x00002281, 0x00002284, 0x00002285, 0x00002288, 0x00002289, 0x000022ac, 0x000022af, 0x000022e0, 0x000022e3, 0x000022ea, 0x000022ed, 0x00002329, 0x0000232a, 0x00002adc, 0x00002adc, 0x0000304c, 0x0000304c, 0x0000304e, 0x0000304e, 0x00003050, 0x00003050, 0x00003052, 0x00003052, 0x00003054, 0x00003054, 0x00003056, 0x00003056, 0x00003058, 0x00003058, 0x0000305a, 0x0000305a, 0x0000305c, 0x0000305c, 0x0000305e, 0x0000305e, 0x00003060, 0x00003060, 0x00003062, 0x00003062, 0x00003065, 0x00003065, 0x00003067, 0x00003067, 0x00003069, 0x00003069, 0x00003070, 0x00003071, 0x00003073, 0x00003074, 0x00003076, 0x00003077, 0x00003079, 0x0000307a, 0x0000307c, 0x0000307d, 0x00003094, 0x00003094, 0x0000309e, 0x0000309e, 0x000030ac, 0x000030ac, 0x000030ae, 0x000030ae, 0x000030b0, 0x000030b0, 0x000030b2, 0x000030b2, 0x000030b4, 0x000030b4, 0x000030b6, 0x000030b6, 0x000030b8, 0x000030b8, 0x000030ba, 0x000030ba, 0x000030bc, 0x000030bc, 0x000030be, 0x000030be, 0x000030c0, 0x000030c0, 0x000030c2, 0x000030c2, 0x000030c5, 0x000030c5, 0x000030c7, 0x000030c7, 0x000030c9, 0x000030c9, 0x000030d0, 0x000030d1, 0x000030d3, 0x000030d4, 0x000030d6, 0x000030d7, 0x000030d9, 0x000030da, 0x000030dc, 0x000030dd, 0x000030f4, 0x000030f4, 0x000030f7, 0x000030fa, 0x000030fe, 0x000030fe, 0x0000f902, 0x0000fa0d, 0x0000fa10, 0x0000fa10, 0x0000fa12, 0x0000fa12, 0x0000fa15, 0x0000fa1e, 0x0000fa20, 0x0000fa20, 0x0000fa22, 0x0000fa22, 0x0000fa25, 0x0000fa26, 0x0000fa2a, 0x0000fa2d, 0x0000fa30, 0x0000fa6a, 0x0000fb1d, 0x0000fb1d, 0x0000fb1f, 0x0000fb1f, 0x0000fb2a, 0x0000fb36, 0x0000fb38, 0x0000fb3c, 0x0000fb3e, 0x0000fb3e, 0x0000fb40, 0x0000fb41, 0x0000fb43, 0x0000fb44, 0x0000fb46, 0x0000fb4e, 0x0001d15e, 0x0001d164, 0x0001d1bb, 0x0001d1c0, 0x0002f800, 0x0002fa1d, 0x00000000, 0x00000220, 0x00000222, 0x00000233, 0x00000250, 0x000002ad, 0x000002b0, 0x000002ee, 0x00000300, 0x0000034f, 0x00000360, 0x0000036f, 0x00000374, 0x00000375, 0x0000037a, 0x0000037a, 0x0000037e, 0x0000037e, 0x00000384, 0x0000038a, 0x0000038c, 0x0000038c, 0x0000038e, 0x000003a1, 0x000003a3, 0x000003ce, 0x000003d0, 0x000003f6, 0x00000400, 0x00000486, 0x00000488, 0x000004ce, 0x000004d0, 0x000004f5, 0x000004f8, 0x000004f9, 0x00000500, 0x0000050f, 0x00000531, 0x00000556, 0x00000559, 0x0000055f, 0x00000561, 0x00000587, 0x00000589, 0x0000058a, 0x00000591, 0x000005a1, 0x000005a3, 0x000005b9, 0x000005bb, 0x000005c4, 0x000005d0, 0x000005ea, 0x000005f0, 0x000005f4, 0x0000060c, 0x0000060c, 0x0000061b, 0x0000061b, 0x0000061f, 0x0000061f, 0x00000621, 0x0000063a, 0x00000640, 0x00000655, 0x00000660, 0x000006ed, 0x000006f0, 0x000006fe, 0x00000700, 0x0000070d, 0x0000070f, 0x0000072c, 0x00000730, 0x0000074a, 0x00000780, 0x000007b1, 0x00000901, 0x00000903, 0x00000905, 0x00000939, 0x0000093c, 0x0000094d, 0x00000950, 0x00000954, 0x00000958, 0x00000970, 0x00000981, 0x00000983, 0x00000985, 0x0000098c, 0x0000098f, 0x00000990, 0x00000993, 0x000009a8, 0x000009aa, 0x000009b0, 0x000009b2, 0x000009b2, 0x000009b6, 0x000009b9, 0x000009bc, 0x000009bc, 0x000009be, 0x000009c4, 0x000009c7, 0x000009c8, 0x000009cb, 0x000009cd, 0x000009d7, 0x000009d7, 0x000009dc, 0x000009dd, 0x000009df, 0x000009e3, 0x000009e6, 0x000009fa, 0x00000a02, 0x00000a02, 0x00000a05, 0x00000a0a, 0x00000a0f, 0x00000a10, 0x00000a13, 0x00000a28, 0x00000a2a, 0x00000a30, 0x00000a32, 0x00000a33, 0x00000a35, 0x00000a36, 0x00000a38, 0x00000a39, 0x00000a3c, 0x00000a3c, 0x00000a3e, 0x00000a42, 0x00000a47, 0x00000a48, 0x00000a4b, 0x00000a4d, 0x00000a59, 0x00000a5c, 0x00000a5e, 0x00000a5e, 0x00000a66, 0x00000a74, 0x00000a81, 0x00000a83, 0x00000a85, 0x00000a8b, 0x00000a8d, 0x00000a8d, 0x00000a8f, 0x00000a91, 0x00000a93, 0x00000aa8, 0x00000aaa, 0x00000ab0, 0x00000ab2, 0x00000ab3, 0x00000ab5, 0x00000ab9, 0x00000abc, 0x00000ac5, 0x00000ac7, 0x00000ac9, 0x00000acb, 0x00000acd, 0x00000ad0, 0x00000ad0, 0x00000ae0, 0x00000ae0, 0x00000ae6, 0x00000aef, 0x00000b01, 0x00000b03, 0x00000b05, 0x00000b0c, 0x00000b0f, 0x00000b10, 0x00000b13, 0x00000b28, 0x00000b2a, 0x00000b30, 0x00000b32, 0x00000b33, 0x00000b36, 0x00000b39, 0x00000b3c, 0x00000b43, 0x00000b47, 0x00000b48, 0x00000b4b, 0x00000b4d, 0x00000b56, 0x00000b57, 0x00000b5c, 0x00000b5d, 0x00000b5f, 0x00000b61, 0x00000b66, 0x00000b70, 0x00000b82, 0x00000b83, 0x00000b85, 0x00000b8a, 0x00000b8e, 0x00000b90, 0x00000b92, 0x00000b95, 0x00000b99, 0x00000b9a, 0x00000b9c, 0x00000b9c, 0x00000b9e, 0x00000b9f, 0x00000ba3, 0x00000ba4, 0x00000ba8, 0x00000baa, 0x00000bae, 0x00000bb5, 0x00000bb7, 0x00000bb9, 0x00000bbe, 0x00000bc2, 0x00000bc6, 0x00000bc8, 0x00000bca, 0x00000bcd, 0x00000bd7, 0x00000bd7, 0x00000be7, 0x00000bf2, 0x00000c01, 0x00000c03, 0x00000c05, 0x00000c0c, 0x00000c0e, 0x00000c10, 0x00000c12, 0x00000c28, 0x00000c2a, 0x00000c33, 0x00000c35, 0x00000c39, 0x00000c3e, 0x00000c44, 0x00000c46, 0x00000c48, 0x00000c4a, 0x00000c4d, 0x00000c55, 0x00000c56, 0x00000c60, 0x00000c61, 0x00000c66, 0x00000c6f, 0x00000c82, 0x00000c83, 0x00000c85, 0x00000c8c, 0x00000c8e, 0x00000c90, 0x00000c92, 0x00000ca8, 0x00000caa, 0x00000cb3, 0x00000cb5, 0x00000cb9, 0x00000cbe, 0x00000cc4, 0x00000cc6, 0x00000cc8, 0x00000cca, 0x00000ccd, 0x00000cd5, 0x00000cd6, 0x00000cde, 0x00000cde, 0x00000ce0, 0x00000ce1, 0x00000ce6, 0x00000cef, 0x00000d02, 0x00000d03, 0x00000d05, 0x00000d0c, 0x00000d0e, 0x00000d10, 0x00000d12, 0x00000d28, 0x00000d2a, 0x00000d39, 0x00000d3e, 0x00000d43, 0x00000d46, 0x00000d48, 0x00000d4a, 0x00000d4d, 0x00000d57, 0x00000d57, 0x00000d60, 0x00000d61, 0x00000d66, 0x00000d6f, 0x00000d82, 0x00000d83, 0x00000d85, 0x00000d96, 0x00000d9a, 0x00000db1, 0x00000db3, 0x00000dbb, 0x00000dbd, 0x00000dbd, 0x00000dc0, 0x00000dc6, 0x00000dca, 0x00000dca, 0x00000dcf, 0x00000dd4, 0x00000dd6, 0x00000dd6, 0x00000dd8, 0x00000ddf, 0x00000df2, 0x00000df4, 0x00000e01, 0x00000e3a, 0x00000e3f, 0x00000e5b, 0x00000e81, 0x00000e82, 0x00000e84, 0x00000e84, 0x00000e87, 0x00000e88, 0x00000e8a, 0x00000e8a, 0x00000e8d, 0x00000e8d, 0x00000e94, 0x00000e97, 0x00000e99, 0x00000e9f, 0x00000ea1, 0x00000ea3, 0x00000ea5, 0x00000ea5, 0x00000ea7, 0x00000ea7, 0x00000eaa, 0x00000eab, 0x00000ead, 0x00000eb9, 0x00000ebb, 0x00000ebd, 0x00000ec0, 0x00000ec4, 0x00000ec6, 0x00000ec6, 0x00000ec8, 0x00000ecd, 0x00000ed0, 0x00000ed9, 0x00000edc, 0x00000edd, 0x00000f00, 0x00000f47, 0x00000f49, 0x00000f6a, 0x00000f71, 0x00000f8b, 0x00000f90, 0x00000f97, 0x00000f99, 0x00000fbc, 0x00000fbe, 0x00000fcc, 0x00000fcf, 0x00000fcf, 0x00001000, 0x00001021, 0x00001023, 0x00001027, 0x00001029, 0x0000102a, 0x0000102c, 0x00001032, 0x00001036, 0x00001039, 0x00001040, 0x00001059, 0x000010a0, 0x000010c5, 0x000010d0, 0x000010f8, 0x000010fb, 0x000010fb, 0x00001100, 0x00001159, 0x0000115f, 0x000011a2, 0x000011a8, 0x000011f9, 0x00001200, 0x00001206, 0x00001208, 0x00001246, 0x00001248, 0x00001248, 0x0000124a, 0x0000124d, 0x00001250, 0x00001256, 0x00001258, 0x00001258, 0x0000125a, 0x0000125d, 0x00001260, 0x00001286, 0x00001288, 0x00001288, 0x0000128a, 0x0000128d, 0x00001290, 0x000012ae, 0x000012b0, 0x000012b0, 0x000012b2, 0x000012b5, 0x000012b8, 0x000012be, 0x000012c0, 0x000012c0, 0x000012c2, 0x000012c5, 0x000012c8, 0x000012ce, 0x000012d0, 0x000012d6, 0x000012d8, 0x000012ee, 0x000012f0, 0x0000130e, 0x00001310, 0x00001310, 0x00001312, 0x00001315, 0x00001318, 0x0000131e, 0x00001320, 0x00001346, 0x00001348, 0x0000135a, 0x00001361, 0x0000137c, 0x000013a0, 0x000013f4, 0x00001401, 0x00001676, 0x00001680, 0x0000169c, 0x000016a0, 0x000016f0, 0x00001700, 0x0000170c, 0x0000170e, 0x00001714, 0x00001720, 0x00001736, 0x00001740, 0x00001753, 0x00001760, 0x0000176c, 0x0000176e, 0x00001770, 0x00001772, 0x00001773, 0x00001780, 0x000017dc, 0x000017e0, 0x000017e9, 0x00001800, 0x0000180e, 0x00001810, 0x00001819, 0x00001820, 0x00001877, 0x00001880, 0x000018a9, 0x00001e00, 0x00001e9b, 0x00001ea0, 0x00001ef9, 0x00001f00, 0x00001f15, 0x00001f18, 0x00001f1d, 0x00001f20, 0x00001f45, 0x00001f48, 0x00001f4d, 0x00001f50, 0x00001f57, 0x00001f59, 0x00001f59, 0x00001f5b, 0x00001f5b, 0x00001f5d, 0x00001f5d, 0x00001f5f, 0x00001f7d, 0x00001f80, 0x00001fb4, 0x00001fb6, 0x00001fc4, 0x00001fc6, 0x00001fd3, 0x00001fd6, 0x00001fdb, 0x00001fdd, 0x00001fef, 0x00001ff2, 0x00001ff4, 0x00001ff6, 0x00001ffe, 0x00002000, 0x00002052, 0x00002057, 0x00002057, 0x0000205f, 0x00002063, 0x0000206a, 0x00002071, 0x00002074, 0x0000208e, 0x000020a0, 0x000020b1, 0x000020d0, 0x000020ea, 0x00002100, 0x0000213a, 0x0000213d, 0x0000214b, 0x00002153, 0x00002183, 0x00002190, 0x000023ce, 0x00002400, 0x00002426, 0x00002440, 0x0000244a, 0x00002460, 0x000024fe, 0x00002500, 0x00002613, 0x00002616, 0x00002617, 0x00002619, 0x0000267d, 0x00002680, 0x00002689, 0x00002701, 0x00002704, 0x00002706, 0x00002709, 0x0000270c, 0x00002727, 0x00002729, 0x0000274b, 0x0000274d, 0x0000274d, 0x0000274f, 0x00002752, 0x00002756, 0x00002756, 0x00002758, 0x0000275e, 0x00002761, 0x00002794, 0x00002798, 0x000027af, 0x000027b1, 0x000027be, 0x000027d0, 0x000027eb, 0x000027f0, 0x00002aff, 0x00002e80, 0x00002e99, 0x00002e9b, 0x00002ef3, 0x00002f00, 0x00002fd5, 0x00002ff0, 0x00002ffb, 0x00003000, 0x0000303f, 0x00003041, 0x00003096, 0x00003099, 0x000030ff, 0x00003105, 0x0000312c, 0x00003131, 0x0000318e, 0x00003190, 0x000031b7, 0x000031f0, 0x0000321c, 0x00003220, 0x00003243, 0x00003251, 0x0000327b, 0x0000327f, 0x000032cb, 0x000032d0, 0x000032fe, 0x00003300, 0x00003376, 0x0000337b, 0x000033dd, 0x000033e0, 0x000033fe, 0x00003400, 0x00004db5, 0x00004e00, 0x00009fa5, 0x0000a000, 0x0000a48c, 0x0000a490, 0x0000a4c6, 0x0000ac00, 0x0000d7a3, 0x0000f900, 0x0000fb06, 0x0000fb13, 0x0000fb17, 0x0000fb1d, 0x0000fb36, 0x0000fb38, 0x0000fb3c, 0x0000fb3e, 0x0000fb3e, 0x0000fb40, 0x0000fb41, 0x0000fb43, 0x0000fb44, 0x0000fb46, 0x0000fbb1, 0x0000fbd3, 0x0000fd3f, 0x0000fd50, 0x0000fd8f, 0x0000fd92, 0x0000fdc7, 0x0000fdf0, 0x0000fdfc, 0x0000fe00, 0x0000fe0f, 0x0000fe20, 0x0000fe23, 0x0000fe30, 0x0000fe46, 0x0000fe49, 0x0000fe52, 0x0000fe54, 0x0000fe66, 0x0000fe68, 0x0000fe6b, 0x0000fe70, 0x0000fe74, 0x0000fe76, 0x0000fefc, 0x0000feff, 0x0000feff, 0x0000ff01, 0x0000ffbe, 0x0000ffc2, 0x0000ffc7, 0x0000ffca, 0x0000ffcf, 0x0000ffd2, 0x0000ffd7, 0x0000ffda, 0x0000ffdc, 0x0000ffe0, 0x0000ffe6, 0x0000ffe8, 0x0000ffee, 0x0000fff9, 0x0000fffd, 0x00010300, 0x0001031e, 0x00010320, 0x00010323, 0x00010330, 0x0001034a, 0x00010400, 0x00010425, 0x00010428, 0x0001044d, 0x0001d000, 0x0001d0f5, 0x0001d100, 0x0001d126, 0x0001d12a, 0x0001d1dd, 0x0001d400, 0x0001d454, 0x0001d456, 0x0001d49c, 0x0001d49e, 0x0001d49f, 0x0001d4a2, 0x0001d4a2, 0x0001d4a5, 0x0001d4a6, 0x0001d4a9, 0x0001d4ac, 0x0001d4ae, 0x0001d4b9, 0x0001d4bb, 0x0001d4bb, 0x0001d4bd, 0x0001d4c0, 0x0001d4c2, 0x0001d4c3, 0x0001d4c5, 0x0001d505, 0x0001d507, 0x0001d50a, 0x0001d50d, 0x0001d514, 0x0001d516, 0x0001d51c, 0x0001d51e, 0x0001d539, 0x0001d53b, 0x0001d53e, 0x0001d540, 0x0001d544, 0x0001d546, 0x0001d546, 0x0001d54a, 0x0001d550, 0x0001d552, 0x0001d6a3, 0x0001d6a8, 0x0001d7c9, 0x0001d7ce, 0x0001d7ff, 0x00020000, 0x0002a6d6, 0x0002f800, 0x0002fa1d, 0x000e0001, 0x000e0001, 0x000e0020, 0x000e007f, 0x000000ab, 0x000000ab, 0x00002018, 0x00002018, 0x0000201b, 0x0000201c, 0x0000201f, 0x0000201f, 0x00002039, 0x00002039, 0x000000bb, 0x000000bb, 0x00002019, 0x00002019, 0x0000201d, 0x0000201d, 0x0000203a, 0x0000203a, 0x0000061b, 0x0000061b, 0x0000061f, 0x0000061f, 0x00000621, 0x0000063a, 0x00000640, 0x0000064a, 0x0000066d, 0x0000066f, 0x00000671, 0x000006d5, 0x000006dd, 0x000006dd, 0x000006e5, 0x000006e6, 0x000006fa, 0x000006fe, 0x00000700, 0x0000070d, 0x00000710, 0x00000710, 0x00000712, 0x0000072c, 0x00000780, 0x000007a5, 0x000007b1, 0x000007b1, 0x0000fb50, 0x0000fbb1, 0x0000fbd3, 0x0000fd3d, 0x0000fd50, 0x0000fd8f, 0x0000fd92, 0x0000fdc7, 0x0000fdf0, 0x0000fdfc, 0x0000fe70, 0x0000fe74, 0x0000fe76, 0x0000fefc }; static const krb5_ui_4 _uccase_size = 1504; static const krb5_ui_2 _uccase_len[2] = {745, 755}; static const krb5_ui_4 _uccase_map[] = { 0x00000041, 0x00000061, 0x00000041, 0x00000042, 0x00000062, 0x00000042, 0x00000043, 0x00000063, 0x00000043, 0x00000044, 0x00000064, 0x00000044, 0x00000045, 0x00000065, 0x00000045, 0x00000046, 0x00000066, 0x00000046, 0x00000047, 0x00000067, 0x00000047, 0x00000048, 0x00000068, 0x00000048, 0x00000049, 0x00000069, 0x00000049, 0x0000004a, 0x0000006a, 0x0000004a, 0x0000004b, 0x0000006b, 0x0000004b, 0x0000004c, 0x0000006c, 0x0000004c, 0x0000004d, 0x0000006d, 0x0000004d, 0x0000004e, 0x0000006e, 0x0000004e, 0x0000004f, 0x0000006f, 0x0000004f, 0x00000050, 0x00000070, 0x00000050, 0x00000051, 0x00000071, 0x00000051, 0x00000052, 0x00000072, 0x00000052, 0x00000053, 0x00000073, 0x00000053, 0x00000054, 0x00000074, 0x00000054, 0x00000055, 0x00000075, 0x00000055, 0x00000056, 0x00000076, 0x00000056, 0x00000057, 0x00000077, 0x00000057, 0x00000058, 0x00000078, 0x00000058, 0x00000059, 0x00000079, 0x00000059, 0x0000005a, 0x0000007a, 0x0000005a, 0x000000c0, 0x000000e0, 0x000000c0, 0x000000c1, 0x000000e1, 0x000000c1, 0x000000c2, 0x000000e2, 0x000000c2, 0x000000c3, 0x000000e3, 0x000000c3, 0x000000c4, 0x000000e4, 0x000000c4, 0x000000c5, 0x000000e5, 0x000000c5, 0x000000c6, 0x000000e6, 0x000000c6, 0x000000c7, 0x000000e7, 0x000000c7, 0x000000c8, 0x000000e8, 0x000000c8, 0x000000c9, 0x000000e9, 0x000000c9, 0x000000ca, 0x000000ea, 0x000000ca, 0x000000cb, 0x000000eb, 0x000000cb, 0x000000cc, 0x000000ec, 0x000000cc, 0x000000cd, 0x000000ed, 0x000000cd, 0x000000ce, 0x000000ee, 0x000000ce, 0x000000cf, 0x000000ef, 0x000000cf, 0x000000d0, 0x000000f0, 0x000000d0, 0x000000d1, 0x000000f1, 0x000000d1, 0x000000d2, 0x000000f2, 0x000000d2, 0x000000d3, 0x000000f3, 0x000000d3, 0x000000d4, 0x000000f4, 0x000000d4, 0x000000d5, 0x000000f5, 0x000000d5, 0x000000d6, 0x000000f6, 0x000000d6, 0x000000d8, 0x000000f8, 0x000000d8, 0x000000d9, 0x000000f9, 0x000000d9, 0x000000da, 0x000000fa, 0x000000da, 0x000000db, 0x000000fb, 0x000000db, 0x000000dc, 0x000000fc, 0x000000dc, 0x000000dd, 0x000000fd, 0x000000dd, 0x000000de, 0x000000fe, 0x000000de, 0x00000100, 0x00000101, 0x00000100, 0x00000102, 0x00000103, 0x00000102, 0x00000104, 0x00000105, 0x00000104, 0x00000106, 0x00000107, 0x00000106, 0x00000108, 0x00000109, 0x00000108, 0x0000010a, 0x0000010b, 0x0000010a, 0x0000010c, 0x0000010d, 0x0000010c, 0x0000010e, 0x0000010f, 0x0000010e, 0x00000110, 0x00000111, 0x00000110, 0x00000112, 0x00000113, 0x00000112, 0x00000114, 0x00000115, 0x00000114, 0x00000116, 0x00000117, 0x00000116, 0x00000118, 0x00000119, 0x00000118, 0x0000011a, 0x0000011b, 0x0000011a, 0x0000011c, 0x0000011d, 0x0000011c, 0x0000011e, 0x0000011f, 0x0000011e, 0x00000120, 0x00000121, 0x00000120, 0x00000122, 0x00000123, 0x00000122, 0x00000124, 0x00000125, 0x00000124, 0x00000126, 0x00000127, 0x00000126, 0x00000128, 0x00000129, 0x00000128, 0x0000012a, 0x0000012b, 0x0000012a, 0x0000012c, 0x0000012d, 0x0000012c, 0x0000012e, 0x0000012f, 0x0000012e, 0x00000130, 0x00000069, 0x00000130, 0x00000132, 0x00000133, 0x00000132, 0x00000134, 0x00000135, 0x00000134, 0x00000136, 0x00000137, 0x00000136, 0x00000139, 0x0000013a, 0x00000139, 0x0000013b, 0x0000013c, 0x0000013b, 0x0000013d, 0x0000013e, 0x0000013d, 0x0000013f, 0x00000140, 0x0000013f, 0x00000141, 0x00000142, 0x00000141, 0x00000143, 0x00000144, 0x00000143, 0x00000145, 0x00000146, 0x00000145, 0x00000147, 0x00000148, 0x00000147, 0x0000014a, 0x0000014b, 0x0000014a, 0x0000014c, 0x0000014d, 0x0000014c, 0x0000014e, 0x0000014f, 0x0000014e, 0x00000150, 0x00000151, 0x00000150, 0x00000152, 0x00000153, 0x00000152, 0x00000154, 0x00000155, 0x00000154, 0x00000156, 0x00000157, 0x00000156, 0x00000158, 0x00000159, 0x00000158, 0x0000015a, 0x0000015b, 0x0000015a, 0x0000015c, 0x0000015d, 0x0000015c, 0x0000015e, 0x0000015f, 0x0000015e, 0x00000160, 0x00000161, 0x00000160, 0x00000162, 0x00000163, 0x00000162, 0x00000164, 0x00000165, 0x00000164, 0x00000166, 0x00000167, 0x00000166, 0x00000168, 0x00000169, 0x00000168, 0x0000016a, 0x0000016b, 0x0000016a, 0x0000016c, 0x0000016d, 0x0000016c, 0x0000016e, 0x0000016f, 0x0000016e, 0x00000170, 0x00000171, 0x00000170, 0x00000172, 0x00000173, 0x00000172, 0x00000174, 0x00000175, 0x00000174, 0x00000176, 0x00000177, 0x00000176, 0x00000178, 0x000000ff, 0x00000178, 0x00000179, 0x0000017a, 0x00000179, 0x0000017b, 0x0000017c, 0x0000017b, 0x0000017d, 0x0000017e, 0x0000017d, 0x00000181, 0x00000253, 0x00000181, 0x00000182, 0x00000183, 0x00000182, 0x00000184, 0x00000185, 0x00000184, 0x00000186, 0x00000254, 0x00000186, 0x00000187, 0x00000188, 0x00000187, 0x00000189, 0x00000256, 0x00000189, 0x0000018a, 0x00000257, 0x0000018a, 0x0000018b, 0x0000018c, 0x0000018b, 0x0000018e, 0x000001dd, 0x0000018e, 0x0000018f, 0x00000259, 0x0000018f, 0x00000190, 0x0000025b, 0x00000190, 0x00000191, 0x00000192, 0x00000191, 0x00000193, 0x00000260, 0x00000193, 0x00000194, 0x00000263, 0x00000194, 0x00000196, 0x00000269, 0x00000196, 0x00000197, 0x00000268, 0x00000197, 0x00000198, 0x00000199, 0x00000198, 0x0000019c, 0x0000026f, 0x0000019c, 0x0000019d, 0x00000272, 0x0000019d, 0x0000019f, 0x00000275, 0x0000019f, 0x000001a0, 0x000001a1, 0x000001a0, 0x000001a2, 0x000001a3, 0x000001a2, 0x000001a4, 0x000001a5, 0x000001a4, 0x000001a6, 0x00000280, 0x000001a6, 0x000001a7, 0x000001a8, 0x000001a7, 0x000001a9, 0x00000283, 0x000001a9, 0x000001ac, 0x000001ad, 0x000001ac, 0x000001ae, 0x00000288, 0x000001ae, 0x000001af, 0x000001b0, 0x000001af, 0x000001b1, 0x0000028a, 0x000001b1, 0x000001b2, 0x0000028b, 0x000001b2, 0x000001b3, 0x000001b4, 0x000001b3, 0x000001b5, 0x000001b6, 0x000001b5, 0x000001b7, 0x00000292, 0x000001b7, 0x000001b8, 0x000001b9, 0x000001b8, 0x000001bc, 0x000001bd, 0x000001bc, 0x000001c4, 0x000001c6, 0x000001c5, 0x000001c7, 0x000001c9, 0x000001c8, 0x000001ca, 0x000001cc, 0x000001cb, 0x000001cd, 0x000001ce, 0x000001cd, 0x000001cf, 0x000001d0, 0x000001cf, 0x000001d1, 0x000001d2, 0x000001d1, 0x000001d3, 0x000001d4, 0x000001d3, 0x000001d5, 0x000001d6, 0x000001d5, 0x000001d7, 0x000001d8, 0x000001d7, 0x000001d9, 0x000001da, 0x000001d9, 0x000001db, 0x000001dc, 0x000001db, 0x000001de, 0x000001df, 0x000001de, 0x000001e0, 0x000001e1, 0x000001e0, 0x000001e2, 0x000001e3, 0x000001e2, 0x000001e4, 0x000001e5, 0x000001e4, 0x000001e6, 0x000001e7, 0x000001e6, 0x000001e8, 0x000001e9, 0x000001e8, 0x000001ea, 0x000001eb, 0x000001ea, 0x000001ec, 0x000001ed, 0x000001ec, 0x000001ee, 0x000001ef, 0x000001ee, 0x000001f1, 0x000001f3, 0x000001f2, 0x000001f4, 0x000001f5, 0x000001f4, 0x000001f6, 0x00000195, 0x000001f6, 0x000001f7, 0x000001bf, 0x000001f7, 0x000001f8, 0x000001f9, 0x000001f8, 0x000001fa, 0x000001fb, 0x000001fa, 0x000001fc, 0x000001fd, 0x000001fc, 0x000001fe, 0x000001ff, 0x000001fe, 0x00000200, 0x00000201, 0x00000200, 0x00000202, 0x00000203, 0x00000202, 0x00000204, 0x00000205, 0x00000204, 0x00000206, 0x00000207, 0x00000206, 0x00000208, 0x00000209, 0x00000208, 0x0000020a, 0x0000020b, 0x0000020a, 0x0000020c, 0x0000020d, 0x0000020c, 0x0000020e, 0x0000020f, 0x0000020e, 0x00000210, 0x00000211, 0x00000210, 0x00000212, 0x00000213, 0x00000212, 0x00000214, 0x00000215, 0x00000214, 0x00000216, 0x00000217, 0x00000216, 0x00000218, 0x00000219, 0x00000218, 0x0000021a, 0x0000021b, 0x0000021a, 0x0000021c, 0x0000021d, 0x0000021c, 0x0000021e, 0x0000021f, 0x0000021e, 0x00000220, 0x0000019e, 0x00000220, 0x00000222, 0x00000223, 0x00000222, 0x00000224, 0x00000225, 0x00000224, 0x00000226, 0x00000227, 0x00000226, 0x00000228, 0x00000229, 0x00000228, 0x0000022a, 0x0000022b, 0x0000022a, 0x0000022c, 0x0000022d, 0x0000022c, 0x0000022e, 0x0000022f, 0x0000022e, 0x00000230, 0x00000231, 0x00000230, 0x00000232, 0x00000233, 0x00000232, 0x00000386, 0x000003ac, 0x00000386, 0x00000388, 0x000003ad, 0x00000388, 0x00000389, 0x000003ae, 0x00000389, 0x0000038a, 0x000003af, 0x0000038a, 0x0000038c, 0x000003cc, 0x0000038c, 0x0000038e, 0x000003cd, 0x0000038e, 0x0000038f, 0x000003ce, 0x0000038f, 0x00000391, 0x000003b1, 0x00000391, 0x00000392, 0x000003b2, 0x00000392, 0x00000393, 0x000003b3, 0x00000393, 0x00000394, 0x000003b4, 0x00000394, 0x00000395, 0x000003b5, 0x00000395, 0x00000396, 0x000003b6, 0x00000396, 0x00000397, 0x000003b7, 0x00000397, 0x00000398, 0x000003b8, 0x00000398, 0x00000399, 0x000003b9, 0x00000399, 0x0000039a, 0x000003ba, 0x0000039a, 0x0000039b, 0x000003bb, 0x0000039b, 0x0000039c, 0x000003bc, 0x0000039c, 0x0000039d, 0x000003bd, 0x0000039d, 0x0000039e, 0x000003be, 0x0000039e, 0x0000039f, 0x000003bf, 0x0000039f, 0x000003a0, 0x000003c0, 0x000003a0, 0x000003a1, 0x000003c1, 0x000003a1, 0x000003a3, 0x000003c3, 0x000003a3, 0x000003a4, 0x000003c4, 0x000003a4, 0x000003a5, 0x000003c5, 0x000003a5, 0x000003a6, 0x000003c6, 0x000003a6, 0x000003a7, 0x000003c7, 0x000003a7, 0x000003a8, 0x000003c8, 0x000003a8, 0x000003a9, 0x000003c9, 0x000003a9, 0x000003aa, 0x000003ca, 0x000003aa, 0x000003ab, 0x000003cb, 0x000003ab, 0x000003d8, 0x000003d9, 0x000003d8, 0x000003da, 0x000003db, 0x000003da, 0x000003dc, 0x000003dd, 0x000003dc, 0x000003de, 0x000003df, 0x000003de, 0x000003e0, 0x000003e1, 0x000003e0, 0x000003e2, 0x000003e3, 0x000003e2, 0x000003e4, 0x000003e5, 0x000003e4, 0x000003e6, 0x000003e7, 0x000003e6, 0x000003e8, 0x000003e9, 0x000003e8, 0x000003ea, 0x000003eb, 0x000003ea, 0x000003ec, 0x000003ed, 0x000003ec, 0x000003ee, 0x000003ef, 0x000003ee, 0x000003f4, 0x000003b8, 0x000003f4, 0x00000400, 0x00000450, 0x00000400, 0x00000401, 0x00000451, 0x00000401, 0x00000402, 0x00000452, 0x00000402, 0x00000403, 0x00000453, 0x00000403, 0x00000404, 0x00000454, 0x00000404, 0x00000405, 0x00000455, 0x00000405, 0x00000406, 0x00000456, 0x00000406, 0x00000407, 0x00000457, 0x00000407, 0x00000408, 0x00000458, 0x00000408, 0x00000409, 0x00000459, 0x00000409, 0x0000040a, 0x0000045a, 0x0000040a, 0x0000040b, 0x0000045b, 0x0000040b, 0x0000040c, 0x0000045c, 0x0000040c, 0x0000040d, 0x0000045d, 0x0000040d, 0x0000040e, 0x0000045e, 0x0000040e, 0x0000040f, 0x0000045f, 0x0000040f, 0x00000410, 0x00000430, 0x00000410, 0x00000411, 0x00000431, 0x00000411, 0x00000412, 0x00000432, 0x00000412, 0x00000413, 0x00000433, 0x00000413, 0x00000414, 0x00000434, 0x00000414, 0x00000415, 0x00000435, 0x00000415, 0x00000416, 0x00000436, 0x00000416, 0x00000417, 0x00000437, 0x00000417, 0x00000418, 0x00000438, 0x00000418, 0x00000419, 0x00000439, 0x00000419, 0x0000041a, 0x0000043a, 0x0000041a, 0x0000041b, 0x0000043b, 0x0000041b, 0x0000041c, 0x0000043c, 0x0000041c, 0x0000041d, 0x0000043d, 0x0000041d, 0x0000041e, 0x0000043e, 0x0000041e, 0x0000041f, 0x0000043f, 0x0000041f, 0x00000420, 0x00000440, 0x00000420, 0x00000421, 0x00000441, 0x00000421, 0x00000422, 0x00000442, 0x00000422, 0x00000423, 0x00000443, 0x00000423, 0x00000424, 0x00000444, 0x00000424, 0x00000425, 0x00000445, 0x00000425, 0x00000426, 0x00000446, 0x00000426, 0x00000427, 0x00000447, 0x00000427, 0x00000428, 0x00000448, 0x00000428, 0x00000429, 0x00000449, 0x00000429, 0x0000042a, 0x0000044a, 0x0000042a, 0x0000042b, 0x0000044b, 0x0000042b, 0x0000042c, 0x0000044c, 0x0000042c, 0x0000042d, 0x0000044d, 0x0000042d, 0x0000042e, 0x0000044e, 0x0000042e, 0x0000042f, 0x0000044f, 0x0000042f, 0x00000460, 0x00000461, 0x00000460, 0x00000462, 0x00000463, 0x00000462, 0x00000464, 0x00000465, 0x00000464, 0x00000466, 0x00000467, 0x00000466, 0x00000468, 0x00000469, 0x00000468, 0x0000046a, 0x0000046b, 0x0000046a, 0x0000046c, 0x0000046d, 0x0000046c, 0x0000046e, 0x0000046f, 0x0000046e, 0x00000470, 0x00000471, 0x00000470, 0x00000472, 0x00000473, 0x00000472, 0x00000474, 0x00000475, 0x00000474, 0x00000476, 0x00000477, 0x00000476, 0x00000478, 0x00000479, 0x00000478, 0x0000047a, 0x0000047b, 0x0000047a, 0x0000047c, 0x0000047d, 0x0000047c, 0x0000047e, 0x0000047f, 0x0000047e, 0x00000480, 0x00000481, 0x00000480, 0x0000048a, 0x0000048b, 0x0000048a, 0x0000048c, 0x0000048d, 0x0000048c, 0x0000048e, 0x0000048f, 0x0000048e, 0x00000490, 0x00000491, 0x00000490, 0x00000492, 0x00000493, 0x00000492, 0x00000494, 0x00000495, 0x00000494, 0x00000496, 0x00000497, 0x00000496, 0x00000498, 0x00000499, 0x00000498, 0x0000049a, 0x0000049b, 0x0000049a, 0x0000049c, 0x0000049d, 0x0000049c, 0x0000049e, 0x0000049f, 0x0000049e, 0x000004a0, 0x000004a1, 0x000004a0, 0x000004a2, 0x000004a3, 0x000004a2, 0x000004a4, 0x000004a5, 0x000004a4, 0x000004a6, 0x000004a7, 0x000004a6, 0x000004a8, 0x000004a9, 0x000004a8, 0x000004aa, 0x000004ab, 0x000004aa, 0x000004ac, 0x000004ad, 0x000004ac, 0x000004ae, 0x000004af, 0x000004ae, 0x000004b0, 0x000004b1, 0x000004b0, 0x000004b2, 0x000004b3, 0x000004b2, 0x000004b4, 0x000004b5, 0x000004b4, 0x000004b6, 0x000004b7, 0x000004b6, 0x000004b8, 0x000004b9, 0x000004b8, 0x000004ba, 0x000004bb, 0x000004ba, 0x000004bc, 0x000004bd, 0x000004bc, 0x000004be, 0x000004bf, 0x000004be, 0x000004c1, 0x000004c2, 0x000004c1, 0x000004c3, 0x000004c4, 0x000004c3, 0x000004c5, 0x000004c6, 0x000004c5, 0x000004c7, 0x000004c8, 0x000004c7, 0x000004c9, 0x000004ca, 0x000004c9, 0x000004cb, 0x000004cc, 0x000004cb, 0x000004cd, 0x000004ce, 0x000004cd, 0x000004d0, 0x000004d1, 0x000004d0, 0x000004d2, 0x000004d3, 0x000004d2, 0x000004d4, 0x000004d5, 0x000004d4, 0x000004d6, 0x000004d7, 0x000004d6, 0x000004d8, 0x000004d9, 0x000004d8, 0x000004da, 0x000004db, 0x000004da, 0x000004dc, 0x000004dd, 0x000004dc, 0x000004de, 0x000004df, 0x000004de, 0x000004e0, 0x000004e1, 0x000004e0, 0x000004e2, 0x000004e3, 0x000004e2, 0x000004e4, 0x000004e5, 0x000004e4, 0x000004e6, 0x000004e7, 0x000004e6, 0x000004e8, 0x000004e9, 0x000004e8, 0x000004ea, 0x000004eb, 0x000004ea, 0x000004ec, 0x000004ed, 0x000004ec, 0x000004ee, 0x000004ef, 0x000004ee, 0x000004f0, 0x000004f1, 0x000004f0, 0x000004f2, 0x000004f3, 0x000004f2, 0x000004f4, 0x000004f5, 0x000004f4, 0x000004f8, 0x000004f9, 0x000004f8, 0x00000500, 0x00000501, 0x00000500, 0x00000502, 0x00000503, 0x00000502, 0x00000504, 0x00000505, 0x00000504, 0x00000506, 0x00000507, 0x00000506, 0x00000508, 0x00000509, 0x00000508, 0x0000050a, 0x0000050b, 0x0000050a, 0x0000050c, 0x0000050d, 0x0000050c, 0x0000050e, 0x0000050f, 0x0000050e, 0x00000531, 0x00000561, 0x00000531, 0x00000532, 0x00000562, 0x00000532, 0x00000533, 0x00000563, 0x00000533, 0x00000534, 0x00000564, 0x00000534, 0x00000535, 0x00000565, 0x00000535, 0x00000536, 0x00000566, 0x00000536, 0x00000537, 0x00000567, 0x00000537, 0x00000538, 0x00000568, 0x00000538, 0x00000539, 0x00000569, 0x00000539, 0x0000053a, 0x0000056a, 0x0000053a, 0x0000053b, 0x0000056b, 0x0000053b, 0x0000053c, 0x0000056c, 0x0000053c, 0x0000053d, 0x0000056d, 0x0000053d, 0x0000053e, 0x0000056e, 0x0000053e, 0x0000053f, 0x0000056f, 0x0000053f, 0x00000540, 0x00000570, 0x00000540, 0x00000541, 0x00000571, 0x00000541, 0x00000542, 0x00000572, 0x00000542, 0x00000543, 0x00000573, 0x00000543, 0x00000544, 0x00000574, 0x00000544, 0x00000545, 0x00000575, 0x00000545, 0x00000546, 0x00000576, 0x00000546, 0x00000547, 0x00000577, 0x00000547, 0x00000548, 0x00000578, 0x00000548, 0x00000549, 0x00000579, 0x00000549, 0x0000054a, 0x0000057a, 0x0000054a, 0x0000054b, 0x0000057b, 0x0000054b, 0x0000054c, 0x0000057c, 0x0000054c, 0x0000054d, 0x0000057d, 0x0000054d, 0x0000054e, 0x0000057e, 0x0000054e, 0x0000054f, 0x0000057f, 0x0000054f, 0x00000550, 0x00000580, 0x00000550, 0x00000551, 0x00000581, 0x00000551, 0x00000552, 0x00000582, 0x00000552, 0x00000553, 0x00000583, 0x00000553, 0x00000554, 0x00000584, 0x00000554, 0x00000555, 0x00000585, 0x00000555, 0x00000556, 0x00000586, 0x00000556, 0x00001e00, 0x00001e01, 0x00001e00, 0x00001e02, 0x00001e03, 0x00001e02, 0x00001e04, 0x00001e05, 0x00001e04, 0x00001e06, 0x00001e07, 0x00001e06, 0x00001e08, 0x00001e09, 0x00001e08, 0x00001e0a, 0x00001e0b, 0x00001e0a, 0x00001e0c, 0x00001e0d, 0x00001e0c, 0x00001e0e, 0x00001e0f, 0x00001e0e, 0x00001e10, 0x00001e11, 0x00001e10, 0x00001e12, 0x00001e13, 0x00001e12, 0x00001e14, 0x00001e15, 0x00001e14, 0x00001e16, 0x00001e17, 0x00001e16, 0x00001e18, 0x00001e19, 0x00001e18, 0x00001e1a, 0x00001e1b, 0x00001e1a, 0x00001e1c, 0x00001e1d, 0x00001e1c, 0x00001e1e, 0x00001e1f, 0x00001e1e, 0x00001e20, 0x00001e21, 0x00001e20, 0x00001e22, 0x00001e23, 0x00001e22, 0x00001e24, 0x00001e25, 0x00001e24, 0x00001e26, 0x00001e27, 0x00001e26, 0x00001e28, 0x00001e29, 0x00001e28, 0x00001e2a, 0x00001e2b, 0x00001e2a, 0x00001e2c, 0x00001e2d, 0x00001e2c, 0x00001e2e, 0x00001e2f, 0x00001e2e, 0x00001e30, 0x00001e31, 0x00001e30, 0x00001e32, 0x00001e33, 0x00001e32, 0x00001e34, 0x00001e35, 0x00001e34, 0x00001e36, 0x00001e37, 0x00001e36, 0x00001e38, 0x00001e39, 0x00001e38, 0x00001e3a, 0x00001e3b, 0x00001e3a, 0x00001e3c, 0x00001e3d, 0x00001e3c, 0x00001e3e, 0x00001e3f, 0x00001e3e, 0x00001e40, 0x00001e41, 0x00001e40, 0x00001e42, 0x00001e43, 0x00001e42, 0x00001e44, 0x00001e45, 0x00001e44, 0x00001e46, 0x00001e47, 0x00001e46, 0x00001e48, 0x00001e49, 0x00001e48, 0x00001e4a, 0x00001e4b, 0x00001e4a, 0x00001e4c, 0x00001e4d, 0x00001e4c, 0x00001e4e, 0x00001e4f, 0x00001e4e, 0x00001e50, 0x00001e51, 0x00001e50, 0x00001e52, 0x00001e53, 0x00001e52, 0x00001e54, 0x00001e55, 0x00001e54, 0x00001e56, 0x00001e57, 0x00001e56, 0x00001e58, 0x00001e59, 0x00001e58, 0x00001e5a, 0x00001e5b, 0x00001e5a, 0x00001e5c, 0x00001e5d, 0x00001e5c, 0x00001e5e, 0x00001e5f, 0x00001e5e, 0x00001e60, 0x00001e61, 0x00001e60, 0x00001e62, 0x00001e63, 0x00001e62, 0x00001e64, 0x00001e65, 0x00001e64, 0x00001e66, 0x00001e67, 0x00001e66, 0x00001e68, 0x00001e69, 0x00001e68, 0x00001e6a, 0x00001e6b, 0x00001e6a, 0x00001e6c, 0x00001e6d, 0x00001e6c, 0x00001e6e, 0x00001e6f, 0x00001e6e, 0x00001e70, 0x00001e71, 0x00001e70, 0x00001e72, 0x00001e73, 0x00001e72, 0x00001e74, 0x00001e75, 0x00001e74, 0x00001e76, 0x00001e77, 0x00001e76, 0x00001e78, 0x00001e79, 0x00001e78, 0x00001e7a, 0x00001e7b, 0x00001e7a, 0x00001e7c, 0x00001e7d, 0x00001e7c, 0x00001e7e, 0x00001e7f, 0x00001e7e, 0x00001e80, 0x00001e81, 0x00001e80, 0x00001e82, 0x00001e83, 0x00001e82, 0x00001e84, 0x00001e85, 0x00001e84, 0x00001e86, 0x00001e87, 0x00001e86, 0x00001e88, 0x00001e89, 0x00001e88, 0x00001e8a, 0x00001e8b, 0x00001e8a, 0x00001e8c, 0x00001e8d, 0x00001e8c, 0x00001e8e, 0x00001e8f, 0x00001e8e, 0x00001e90, 0x00001e91, 0x00001e90, 0x00001e92, 0x00001e93, 0x00001e92, 0x00001e94, 0x00001e95, 0x00001e94, 0x00001ea0, 0x00001ea1, 0x00001ea0, 0x00001ea2, 0x00001ea3, 0x00001ea2, 0x00001ea4, 0x00001ea5, 0x00001ea4, 0x00001ea6, 0x00001ea7, 0x00001ea6, 0x00001ea8, 0x00001ea9, 0x00001ea8, 0x00001eaa, 0x00001eab, 0x00001eaa, 0x00001eac, 0x00001ead, 0x00001eac, 0x00001eae, 0x00001eaf, 0x00001eae, 0x00001eb0, 0x00001eb1, 0x00001eb0, 0x00001eb2, 0x00001eb3, 0x00001eb2, 0x00001eb4, 0x00001eb5, 0x00001eb4, 0x00001eb6, 0x00001eb7, 0x00001eb6, 0x00001eb8, 0x00001eb9, 0x00001eb8, 0x00001eba, 0x00001ebb, 0x00001eba, 0x00001ebc, 0x00001ebd, 0x00001ebc, 0x00001ebe, 0x00001ebf, 0x00001ebe, 0x00001ec0, 0x00001ec1, 0x00001ec0, 0x00001ec2, 0x00001ec3, 0x00001ec2, 0x00001ec4, 0x00001ec5, 0x00001ec4, 0x00001ec6, 0x00001ec7, 0x00001ec6, 0x00001ec8, 0x00001ec9, 0x00001ec8, 0x00001eca, 0x00001ecb, 0x00001eca, 0x00001ecc, 0x00001ecd, 0x00001ecc, 0x00001ece, 0x00001ecf, 0x00001ece, 0x00001ed0, 0x00001ed1, 0x00001ed0, 0x00001ed2, 0x00001ed3, 0x00001ed2, 0x00001ed4, 0x00001ed5, 0x00001ed4, 0x00001ed6, 0x00001ed7, 0x00001ed6, 0x00001ed8, 0x00001ed9, 0x00001ed8, 0x00001eda, 0x00001edb, 0x00001eda, 0x00001edc, 0x00001edd, 0x00001edc, 0x00001ede, 0x00001edf, 0x00001ede, 0x00001ee0, 0x00001ee1, 0x00001ee0, 0x00001ee2, 0x00001ee3, 0x00001ee2, 0x00001ee4, 0x00001ee5, 0x00001ee4, 0x00001ee6, 0x00001ee7, 0x00001ee6, 0x00001ee8, 0x00001ee9, 0x00001ee8, 0x00001eea, 0x00001eeb, 0x00001eea, 0x00001eec, 0x00001eed, 0x00001eec, 0x00001eee, 0x00001eef, 0x00001eee, 0x00001ef0, 0x00001ef1, 0x00001ef0, 0x00001ef2, 0x00001ef3, 0x00001ef2, 0x00001ef4, 0x00001ef5, 0x00001ef4, 0x00001ef6, 0x00001ef7, 0x00001ef6, 0x00001ef8, 0x00001ef9, 0x00001ef8, 0x00001f08, 0x00001f00, 0x00001f08, 0x00001f09, 0x00001f01, 0x00001f09, 0x00001f0a, 0x00001f02, 0x00001f0a, 0x00001f0b, 0x00001f03, 0x00001f0b, 0x00001f0c, 0x00001f04, 0x00001f0c, 0x00001f0d, 0x00001f05, 0x00001f0d, 0x00001f0e, 0x00001f06, 0x00001f0e, 0x00001f0f, 0x00001f07, 0x00001f0f, 0x00001f18, 0x00001f10, 0x00001f18, 0x00001f19, 0x00001f11, 0x00001f19, 0x00001f1a, 0x00001f12, 0x00001f1a, 0x00001f1b, 0x00001f13, 0x00001f1b, 0x00001f1c, 0x00001f14, 0x00001f1c, 0x00001f1d, 0x00001f15, 0x00001f1d, 0x00001f28, 0x00001f20, 0x00001f28, 0x00001f29, 0x00001f21, 0x00001f29, 0x00001f2a, 0x00001f22, 0x00001f2a, 0x00001f2b, 0x00001f23, 0x00001f2b, 0x00001f2c, 0x00001f24, 0x00001f2c, 0x00001f2d, 0x00001f25, 0x00001f2d, 0x00001f2e, 0x00001f26, 0x00001f2e, 0x00001f2f, 0x00001f27, 0x00001f2f, 0x00001f38, 0x00001f30, 0x00001f38, 0x00001f39, 0x00001f31, 0x00001f39, 0x00001f3a, 0x00001f32, 0x00001f3a, 0x00001f3b, 0x00001f33, 0x00001f3b, 0x00001f3c, 0x00001f34, 0x00001f3c, 0x00001f3d, 0x00001f35, 0x00001f3d, 0x00001f3e, 0x00001f36, 0x00001f3e, 0x00001f3f, 0x00001f37, 0x00001f3f, 0x00001f48, 0x00001f40, 0x00001f48, 0x00001f49, 0x00001f41, 0x00001f49, 0x00001f4a, 0x00001f42, 0x00001f4a, 0x00001f4b, 0x00001f43, 0x00001f4b, 0x00001f4c, 0x00001f44, 0x00001f4c, 0x00001f4d, 0x00001f45, 0x00001f4d, 0x00001f59, 0x00001f51, 0x00001f59, 0x00001f5b, 0x00001f53, 0x00001f5b, 0x00001f5d, 0x00001f55, 0x00001f5d, 0x00001f5f, 0x00001f57, 0x00001f5f, 0x00001f68, 0x00001f60, 0x00001f68, 0x00001f69, 0x00001f61, 0x00001f69, 0x00001f6a, 0x00001f62, 0x00001f6a, 0x00001f6b, 0x00001f63, 0x00001f6b, 0x00001f6c, 0x00001f64, 0x00001f6c, 0x00001f6d, 0x00001f65, 0x00001f6d, 0x00001f6e, 0x00001f66, 0x00001f6e, 0x00001f6f, 0x00001f67, 0x00001f6f, 0x00001f88, 0x00001f80, 0x00001f88, 0x00001f89, 0x00001f81, 0x00001f89, 0x00001f8a, 0x00001f82, 0x00001f8a, 0x00001f8b, 0x00001f83, 0x00001f8b, 0x00001f8c, 0x00001f84, 0x00001f8c, 0x00001f8d, 0x00001f85, 0x00001f8d, 0x00001f8e, 0x00001f86, 0x00001f8e, 0x00001f8f, 0x00001f87, 0x00001f8f, 0x00001f98, 0x00001f90, 0x00001f98, 0x00001f99, 0x00001f91, 0x00001f99, 0x00001f9a, 0x00001f92, 0x00001f9a, 0x00001f9b, 0x00001f93, 0x00001f9b, 0x00001f9c, 0x00001f94, 0x00001f9c, 0x00001f9d, 0x00001f95, 0x00001f9d, 0x00001f9e, 0x00001f96, 0x00001f9e, 0x00001f9f, 0x00001f97, 0x00001f9f, 0x00001fa8, 0x00001fa0, 0x00001fa8, 0x00001fa9, 0x00001fa1, 0x00001fa9, 0x00001faa, 0x00001fa2, 0x00001faa, 0x00001fab, 0x00001fa3, 0x00001fab, 0x00001fac, 0x00001fa4, 0x00001fac, 0x00001fad, 0x00001fa5, 0x00001fad, 0x00001fae, 0x00001fa6, 0x00001fae, 0x00001faf, 0x00001fa7, 0x00001faf, 0x00001fb8, 0x00001fb0, 0x00001fb8, 0x00001fb9, 0x00001fb1, 0x00001fb9, 0x00001fba, 0x00001f70, 0x00001fba, 0x00001fbb, 0x00001f71, 0x00001fbb, 0x00001fbc, 0x00001fb3, 0x00001fbc, 0x00001fc8, 0x00001f72, 0x00001fc8, 0x00001fc9, 0x00001f73, 0x00001fc9, 0x00001fca, 0x00001f74, 0x00001fca, 0x00001fcb, 0x00001f75, 0x00001fcb, 0x00001fcc, 0x00001fc3, 0x00001fcc, 0x00001fd8, 0x00001fd0, 0x00001fd8, 0x00001fd9, 0x00001fd1, 0x00001fd9, 0x00001fda, 0x00001f76, 0x00001fda, 0x00001fdb, 0x00001f77, 0x00001fdb, 0x00001fe8, 0x00001fe0, 0x00001fe8, 0x00001fe9, 0x00001fe1, 0x00001fe9, 0x00001fea, 0x00001f7a, 0x00001fea, 0x00001feb, 0x00001f7b, 0x00001feb, 0x00001fec, 0x00001fe5, 0x00001fec, 0x00001ff8, 0x00001f78, 0x00001ff8, 0x00001ff9, 0x00001f79, 0x00001ff9, 0x00001ffa, 0x00001f7c, 0x00001ffa, 0x00001ffb, 0x00001f7d, 0x00001ffb, 0x00001ffc, 0x00001ff3, 0x00001ffc, 0x00002126, 0x000003c9, 0x00002126, 0x0000212a, 0x0000006b, 0x0000212a, 0x0000212b, 0x000000e5, 0x0000212b, 0x00002160, 0x00002170, 0x00002160, 0x00002161, 0x00002171, 0x00002161, 0x00002162, 0x00002172, 0x00002162, 0x00002163, 0x00002173, 0x00002163, 0x00002164, 0x00002174, 0x00002164, 0x00002165, 0x00002175, 0x00002165, 0x00002166, 0x00002176, 0x00002166, 0x00002167, 0x00002177, 0x00002167, 0x00002168, 0x00002178, 0x00002168, 0x00002169, 0x00002179, 0x00002169, 0x0000216a, 0x0000217a, 0x0000216a, 0x0000216b, 0x0000217b, 0x0000216b, 0x0000216c, 0x0000217c, 0x0000216c, 0x0000216d, 0x0000217d, 0x0000216d, 0x0000216e, 0x0000217e, 0x0000216e, 0x0000216f, 0x0000217f, 0x0000216f, 0x000024b6, 0x000024d0, 0x000024b6, 0x000024b7, 0x000024d1, 0x000024b7, 0x000024b8, 0x000024d2, 0x000024b8, 0x000024b9, 0x000024d3, 0x000024b9, 0x000024ba, 0x000024d4, 0x000024ba, 0x000024bb, 0x000024d5, 0x000024bb, 0x000024bc, 0x000024d6, 0x000024bc, 0x000024bd, 0x000024d7, 0x000024bd, 0x000024be, 0x000024d8, 0x000024be, 0x000024bf, 0x000024d9, 0x000024bf, 0x000024c0, 0x000024da, 0x000024c0, 0x000024c1, 0x000024db, 0x000024c1, 0x000024c2, 0x000024dc, 0x000024c2, 0x000024c3, 0x000024dd, 0x000024c3, 0x000024c4, 0x000024de, 0x000024c4, 0x000024c5, 0x000024df, 0x000024c5, 0x000024c6, 0x000024e0, 0x000024c6, 0x000024c7, 0x000024e1, 0x000024c7, 0x000024c8, 0x000024e2, 0x000024c8, 0x000024c9, 0x000024e3, 0x000024c9, 0x000024ca, 0x000024e4, 0x000024ca, 0x000024cb, 0x000024e5, 0x000024cb, 0x000024cc, 0x000024e6, 0x000024cc, 0x000024cd, 0x000024e7, 0x000024cd, 0x000024ce, 0x000024e8, 0x000024ce, 0x000024cf, 0x000024e9, 0x000024cf, 0x0000ff21, 0x0000ff41, 0x0000ff21, 0x0000ff22, 0x0000ff42, 0x0000ff22, 0x0000ff23, 0x0000ff43, 0x0000ff23, 0x0000ff24, 0x0000ff44, 0x0000ff24, 0x0000ff25, 0x0000ff45, 0x0000ff25, 0x0000ff26, 0x0000ff46, 0x0000ff26, 0x0000ff27, 0x0000ff47, 0x0000ff27, 0x0000ff28, 0x0000ff48, 0x0000ff28, 0x0000ff29, 0x0000ff49, 0x0000ff29, 0x0000ff2a, 0x0000ff4a, 0x0000ff2a, 0x0000ff2b, 0x0000ff4b, 0x0000ff2b, 0x0000ff2c, 0x0000ff4c, 0x0000ff2c, 0x0000ff2d, 0x0000ff4d, 0x0000ff2d, 0x0000ff2e, 0x0000ff4e, 0x0000ff2e, 0x0000ff2f, 0x0000ff4f, 0x0000ff2f, 0x0000ff30, 0x0000ff50, 0x0000ff30, 0x0000ff31, 0x0000ff51, 0x0000ff31, 0x0000ff32, 0x0000ff52, 0x0000ff32, 0x0000ff33, 0x0000ff53, 0x0000ff33, 0x0000ff34, 0x0000ff54, 0x0000ff34, 0x0000ff35, 0x0000ff55, 0x0000ff35, 0x0000ff36, 0x0000ff56, 0x0000ff36, 0x0000ff37, 0x0000ff57, 0x0000ff37, 0x0000ff38, 0x0000ff58, 0x0000ff38, 0x0000ff39, 0x0000ff59, 0x0000ff39, 0x0000ff3a, 0x0000ff5a, 0x0000ff3a, 0x00010400, 0x00010428, 0x00010400, 0x00010401, 0x00010429, 0x00010401, 0x00010402, 0x0001042a, 0x00010402, 0x00010403, 0x0001042b, 0x00010403, 0x00010404, 0x0001042c, 0x00010404, 0x00010405, 0x0001042d, 0x00010405, 0x00010406, 0x0001042e, 0x00010406, 0x00010407, 0x0001042f, 0x00010407, 0x00010408, 0x00010430, 0x00010408, 0x00010409, 0x00010431, 0x00010409, 0x0001040a, 0x00010432, 0x0001040a, 0x0001040b, 0x00010433, 0x0001040b, 0x0001040c, 0x00010434, 0x0001040c, 0x0001040d, 0x00010435, 0x0001040d, 0x0001040e, 0x00010436, 0x0001040e, 0x0001040f, 0x00010437, 0x0001040f, 0x00010410, 0x00010438, 0x00010410, 0x00010411, 0x00010439, 0x00010411, 0x00010412, 0x0001043a, 0x00010412, 0x00010413, 0x0001043b, 0x00010413, 0x00010414, 0x0001043c, 0x00010414, 0x00010415, 0x0001043d, 0x00010415, 0x00010416, 0x0001043e, 0x00010416, 0x00010417, 0x0001043f, 0x00010417, 0x00010418, 0x00010440, 0x00010418, 0x00010419, 0x00010441, 0x00010419, 0x0001041a, 0x00010442, 0x0001041a, 0x0001041b, 0x00010443, 0x0001041b, 0x0001041c, 0x00010444, 0x0001041c, 0x0001041d, 0x00010445, 0x0001041d, 0x0001041e, 0x00010446, 0x0001041e, 0x0001041f, 0x00010447, 0x0001041f, 0x00010420, 0x00010448, 0x00010420, 0x00010421, 0x00010449, 0x00010421, 0x00010422, 0x0001044a, 0x00010422, 0x00010423, 0x0001044b, 0x00010423, 0x00010424, 0x0001044c, 0x00010424, 0x00010425, 0x0001044d, 0x00010425, 0x00000061, 0x00000041, 0x00000041, 0x00000062, 0x00000042, 0x00000042, 0x00000063, 0x00000043, 0x00000043, 0x00000064, 0x00000044, 0x00000044, 0x00000065, 0x00000045, 0x00000045, 0x00000066, 0x00000046, 0x00000046, 0x00000067, 0x00000047, 0x00000047, 0x00000068, 0x00000048, 0x00000048, 0x00000069, 0x00000049, 0x00000049, 0x0000006a, 0x0000004a, 0x0000004a, 0x0000006b, 0x0000004b, 0x0000004b, 0x0000006c, 0x0000004c, 0x0000004c, 0x0000006d, 0x0000004d, 0x0000004d, 0x0000006e, 0x0000004e, 0x0000004e, 0x0000006f, 0x0000004f, 0x0000004f, 0x00000070, 0x00000050, 0x00000050, 0x00000071, 0x00000051, 0x00000051, 0x00000072, 0x00000052, 0x00000052, 0x00000073, 0x00000053, 0x00000053, 0x00000074, 0x00000054, 0x00000054, 0x00000075, 0x00000055, 0x00000055, 0x00000076, 0x00000056, 0x00000056, 0x00000077, 0x00000057, 0x00000057, 0x00000078, 0x00000058, 0x00000058, 0x00000079, 0x00000059, 0x00000059, 0x0000007a, 0x0000005a, 0x0000005a, 0x000000b5, 0x0000039c, 0x0000039c, 0x000000e0, 0x000000c0, 0x000000c0, 0x000000e1, 0x000000c1, 0x000000c1, 0x000000e2, 0x000000c2, 0x000000c2, 0x000000e3, 0x000000c3, 0x000000c3, 0x000000e4, 0x000000c4, 0x000000c4, 0x000000e5, 0x000000c5, 0x000000c5, 0x000000e6, 0x000000c6, 0x000000c6, 0x000000e7, 0x000000c7, 0x000000c7, 0x000000e8, 0x000000c8, 0x000000c8, 0x000000e9, 0x000000c9, 0x000000c9, 0x000000ea, 0x000000ca, 0x000000ca, 0x000000eb, 0x000000cb, 0x000000cb, 0x000000ec, 0x000000cc, 0x000000cc, 0x000000ed, 0x000000cd, 0x000000cd, 0x000000ee, 0x000000ce, 0x000000ce, 0x000000ef, 0x000000cf, 0x000000cf, 0x000000f0, 0x000000d0, 0x000000d0, 0x000000f1, 0x000000d1, 0x000000d1, 0x000000f2, 0x000000d2, 0x000000d2, 0x000000f3, 0x000000d3, 0x000000d3, 0x000000f4, 0x000000d4, 0x000000d4, 0x000000f5, 0x000000d5, 0x000000d5, 0x000000f6, 0x000000d6, 0x000000d6, 0x000000f8, 0x000000d8, 0x000000d8, 0x000000f9, 0x000000d9, 0x000000d9, 0x000000fa, 0x000000da, 0x000000da, 0x000000fb, 0x000000db, 0x000000db, 0x000000fc, 0x000000dc, 0x000000dc, 0x000000fd, 0x000000dd, 0x000000dd, 0x000000fe, 0x000000de, 0x000000de, 0x000000ff, 0x00000178, 0x00000178, 0x00000101, 0x00000100, 0x00000100, 0x00000103, 0x00000102, 0x00000102, 0x00000105, 0x00000104, 0x00000104, 0x00000107, 0x00000106, 0x00000106, 0x00000109, 0x00000108, 0x00000108, 0x0000010b, 0x0000010a, 0x0000010a, 0x0000010d, 0x0000010c, 0x0000010c, 0x0000010f, 0x0000010e, 0x0000010e, 0x00000111, 0x00000110, 0x00000110, 0x00000113, 0x00000112, 0x00000112, 0x00000115, 0x00000114, 0x00000114, 0x00000117, 0x00000116, 0x00000116, 0x00000119, 0x00000118, 0x00000118, 0x0000011b, 0x0000011a, 0x0000011a, 0x0000011d, 0x0000011c, 0x0000011c, 0x0000011f, 0x0000011e, 0x0000011e, 0x00000121, 0x00000120, 0x00000120, 0x00000123, 0x00000122, 0x00000122, 0x00000125, 0x00000124, 0x00000124, 0x00000127, 0x00000126, 0x00000126, 0x00000129, 0x00000128, 0x00000128, 0x0000012b, 0x0000012a, 0x0000012a, 0x0000012d, 0x0000012c, 0x0000012c, 0x0000012f, 0x0000012e, 0x0000012e, 0x00000131, 0x00000049, 0x00000049, 0x00000133, 0x00000132, 0x00000132, 0x00000135, 0x00000134, 0x00000134, 0x00000137, 0x00000136, 0x00000136, 0x0000013a, 0x00000139, 0x00000139, 0x0000013c, 0x0000013b, 0x0000013b, 0x0000013e, 0x0000013d, 0x0000013d, 0x00000140, 0x0000013f, 0x0000013f, 0x00000142, 0x00000141, 0x00000141, 0x00000144, 0x00000143, 0x00000143, 0x00000146, 0x00000145, 0x00000145, 0x00000148, 0x00000147, 0x00000147, 0x0000014b, 0x0000014a, 0x0000014a, 0x0000014d, 0x0000014c, 0x0000014c, 0x0000014f, 0x0000014e, 0x0000014e, 0x00000151, 0x00000150, 0x00000150, 0x00000153, 0x00000152, 0x00000152, 0x00000155, 0x00000154, 0x00000154, 0x00000157, 0x00000156, 0x00000156, 0x00000159, 0x00000158, 0x00000158, 0x0000015b, 0x0000015a, 0x0000015a, 0x0000015d, 0x0000015c, 0x0000015c, 0x0000015f, 0x0000015e, 0x0000015e, 0x00000161, 0x00000160, 0x00000160, 0x00000163, 0x00000162, 0x00000162, 0x00000165, 0x00000164, 0x00000164, 0x00000167, 0x00000166, 0x00000166, 0x00000169, 0x00000168, 0x00000168, 0x0000016b, 0x0000016a, 0x0000016a, 0x0000016d, 0x0000016c, 0x0000016c, 0x0000016f, 0x0000016e, 0x0000016e, 0x00000171, 0x00000170, 0x00000170, 0x00000173, 0x00000172, 0x00000172, 0x00000175, 0x00000174, 0x00000174, 0x00000177, 0x00000176, 0x00000176, 0x0000017a, 0x00000179, 0x00000179, 0x0000017c, 0x0000017b, 0x0000017b, 0x0000017e, 0x0000017d, 0x0000017d, 0x0000017f, 0x00000053, 0x00000053, 0x00000183, 0x00000182, 0x00000182, 0x00000185, 0x00000184, 0x00000184, 0x00000188, 0x00000187, 0x00000187, 0x0000018c, 0x0000018b, 0x0000018b, 0x00000192, 0x00000191, 0x00000191, 0x00000195, 0x000001f6, 0x000001f6, 0x00000199, 0x00000198, 0x00000198, 0x0000019e, 0x00000220, 0x00000220, 0x000001a1, 0x000001a0, 0x000001a0, 0x000001a3, 0x000001a2, 0x000001a2, 0x000001a5, 0x000001a4, 0x000001a4, 0x000001a8, 0x000001a7, 0x000001a7, 0x000001ad, 0x000001ac, 0x000001ac, 0x000001b0, 0x000001af, 0x000001af, 0x000001b4, 0x000001b3, 0x000001b3, 0x000001b6, 0x000001b5, 0x000001b5, 0x000001b9, 0x000001b8, 0x000001b8, 0x000001bd, 0x000001bc, 0x000001bc, 0x000001bf, 0x000001f7, 0x000001f7, 0x000001c6, 0x000001c4, 0x000001c5, 0x000001c9, 0x000001c7, 0x000001c8, 0x000001cc, 0x000001ca, 0x000001cb, 0x000001ce, 0x000001cd, 0x000001cd, 0x000001d0, 0x000001cf, 0x000001cf, 0x000001d2, 0x000001d1, 0x000001d1, 0x000001d4, 0x000001d3, 0x000001d3, 0x000001d6, 0x000001d5, 0x000001d5, 0x000001d8, 0x000001d7, 0x000001d7, 0x000001da, 0x000001d9, 0x000001d9, 0x000001dc, 0x000001db, 0x000001db, 0x000001dd, 0x0000018e, 0x0000018e, 0x000001df, 0x000001de, 0x000001de, 0x000001e1, 0x000001e0, 0x000001e0, 0x000001e3, 0x000001e2, 0x000001e2, 0x000001e5, 0x000001e4, 0x000001e4, 0x000001e7, 0x000001e6, 0x000001e6, 0x000001e9, 0x000001e8, 0x000001e8, 0x000001eb, 0x000001ea, 0x000001ea, 0x000001ed, 0x000001ec, 0x000001ec, 0x000001ef, 0x000001ee, 0x000001ee, 0x000001f3, 0x000001f1, 0x000001f2, 0x000001f5, 0x000001f4, 0x000001f4, 0x000001f9, 0x000001f8, 0x000001f8, 0x000001fb, 0x000001fa, 0x000001fa, 0x000001fd, 0x000001fc, 0x000001fc, 0x000001ff, 0x000001fe, 0x000001fe, 0x00000201, 0x00000200, 0x00000200, 0x00000203, 0x00000202, 0x00000202, 0x00000205, 0x00000204, 0x00000204, 0x00000207, 0x00000206, 0x00000206, 0x00000209, 0x00000208, 0x00000208, 0x0000020b, 0x0000020a, 0x0000020a, 0x0000020d, 0x0000020c, 0x0000020c, 0x0000020f, 0x0000020e, 0x0000020e, 0x00000211, 0x00000210, 0x00000210, 0x00000213, 0x00000212, 0x00000212, 0x00000215, 0x00000214, 0x00000214, 0x00000217, 0x00000216, 0x00000216, 0x00000219, 0x00000218, 0x00000218, 0x0000021b, 0x0000021a, 0x0000021a, 0x0000021d, 0x0000021c, 0x0000021c, 0x0000021f, 0x0000021e, 0x0000021e, 0x00000223, 0x00000222, 0x00000222, 0x00000225, 0x00000224, 0x00000224, 0x00000227, 0x00000226, 0x00000226, 0x00000229, 0x00000228, 0x00000228, 0x0000022b, 0x0000022a, 0x0000022a, 0x0000022d, 0x0000022c, 0x0000022c, 0x0000022f, 0x0000022e, 0x0000022e, 0x00000231, 0x00000230, 0x00000230, 0x00000233, 0x00000232, 0x00000232, 0x00000253, 0x00000181, 0x00000181, 0x00000254, 0x00000186, 0x00000186, 0x00000256, 0x00000189, 0x00000189, 0x00000257, 0x0000018a, 0x0000018a, 0x00000259, 0x0000018f, 0x0000018f, 0x0000025b, 0x00000190, 0x00000190, 0x00000260, 0x00000193, 0x00000193, 0x00000263, 0x00000194, 0x00000194, 0x00000268, 0x00000197, 0x00000197, 0x00000269, 0x00000196, 0x00000196, 0x0000026f, 0x0000019c, 0x0000019c, 0x00000272, 0x0000019d, 0x0000019d, 0x00000275, 0x0000019f, 0x0000019f, 0x00000280, 0x000001a6, 0x000001a6, 0x00000283, 0x000001a9, 0x000001a9, 0x00000288, 0x000001ae, 0x000001ae, 0x0000028a, 0x000001b1, 0x000001b1, 0x0000028b, 0x000001b2, 0x000001b2, 0x00000292, 0x000001b7, 0x000001b7, 0x00000345, 0x00000399, 0x00000399, 0x000003ac, 0x00000386, 0x00000386, 0x000003ad, 0x00000388, 0x00000388, 0x000003ae, 0x00000389, 0x00000389, 0x000003af, 0x0000038a, 0x0000038a, 0x000003b1, 0x00000391, 0x00000391, 0x000003b2, 0x00000392, 0x00000392, 0x000003b3, 0x00000393, 0x00000393, 0x000003b4, 0x00000394, 0x00000394, 0x000003b5, 0x00000395, 0x00000395, 0x000003b6, 0x00000396, 0x00000396, 0x000003b7, 0x00000397, 0x00000397, 0x000003b8, 0x00000398, 0x00000398, 0x000003b9, 0x00000399, 0x00000399, 0x000003ba, 0x0000039a, 0x0000039a, 0x000003bb, 0x0000039b, 0x0000039b, 0x000003bc, 0x0000039c, 0x0000039c, 0x000003bd, 0x0000039d, 0x0000039d, 0x000003be, 0x0000039e, 0x0000039e, 0x000003bf, 0x0000039f, 0x0000039f, 0x000003c0, 0x000003a0, 0x000003a0, 0x000003c1, 0x000003a1, 0x000003a1, 0x000003c2, 0x000003a3, 0x000003a3, 0x000003c3, 0x000003a3, 0x000003a3, 0x000003c4, 0x000003a4, 0x000003a4, 0x000003c5, 0x000003a5, 0x000003a5, 0x000003c6, 0x000003a6, 0x000003a6, 0x000003c7, 0x000003a7, 0x000003a7, 0x000003c8, 0x000003a8, 0x000003a8, 0x000003c9, 0x000003a9, 0x000003a9, 0x000003ca, 0x000003aa, 0x000003aa, 0x000003cb, 0x000003ab, 0x000003ab, 0x000003cc, 0x0000038c, 0x0000038c, 0x000003cd, 0x0000038e, 0x0000038e, 0x000003ce, 0x0000038f, 0x0000038f, 0x000003d0, 0x00000392, 0x00000392, 0x000003d1, 0x00000398, 0x00000398, 0x000003d5, 0x000003a6, 0x000003a6, 0x000003d6, 0x000003a0, 0x000003a0, 0x000003d9, 0x000003d8, 0x000003d8, 0x000003db, 0x000003da, 0x000003da, 0x000003dd, 0x000003dc, 0x000003dc, 0x000003df, 0x000003de, 0x000003de, 0x000003e1, 0x000003e0, 0x000003e0, 0x000003e3, 0x000003e2, 0x000003e2, 0x000003e5, 0x000003e4, 0x000003e4, 0x000003e7, 0x000003e6, 0x000003e6, 0x000003e9, 0x000003e8, 0x000003e8, 0x000003eb, 0x000003ea, 0x000003ea, 0x000003ed, 0x000003ec, 0x000003ec, 0x000003ef, 0x000003ee, 0x000003ee, 0x000003f0, 0x0000039a, 0x0000039a, 0x000003f1, 0x000003a1, 0x000003a1, 0x000003f2, 0x000003a3, 0x000003a3, 0x000003f5, 0x00000395, 0x00000395, 0x00000430, 0x00000410, 0x00000410, 0x00000431, 0x00000411, 0x00000411, 0x00000432, 0x00000412, 0x00000412, 0x00000433, 0x00000413, 0x00000413, 0x00000434, 0x00000414, 0x00000414, 0x00000435, 0x00000415, 0x00000415, 0x00000436, 0x00000416, 0x00000416, 0x00000437, 0x00000417, 0x00000417, 0x00000438, 0x00000418, 0x00000418, 0x00000439, 0x00000419, 0x00000419, 0x0000043a, 0x0000041a, 0x0000041a, 0x0000043b, 0x0000041b, 0x0000041b, 0x0000043c, 0x0000041c, 0x0000041c, 0x0000043d, 0x0000041d, 0x0000041d, 0x0000043e, 0x0000041e, 0x0000041e, 0x0000043f, 0x0000041f, 0x0000041f, 0x00000440, 0x00000420, 0x00000420, 0x00000441, 0x00000421, 0x00000421, 0x00000442, 0x00000422, 0x00000422, 0x00000443, 0x00000423, 0x00000423, 0x00000444, 0x00000424, 0x00000424, 0x00000445, 0x00000425, 0x00000425, 0x00000446, 0x00000426, 0x00000426, 0x00000447, 0x00000427, 0x00000427, 0x00000448, 0x00000428, 0x00000428, 0x00000449, 0x00000429, 0x00000429, 0x0000044a, 0x0000042a, 0x0000042a, 0x0000044b, 0x0000042b, 0x0000042b, 0x0000044c, 0x0000042c, 0x0000042c, 0x0000044d, 0x0000042d, 0x0000042d, 0x0000044e, 0x0000042e, 0x0000042e, 0x0000044f, 0x0000042f, 0x0000042f, 0x00000450, 0x00000400, 0x00000400, 0x00000451, 0x00000401, 0x00000401, 0x00000452, 0x00000402, 0x00000402, 0x00000453, 0x00000403, 0x00000403, 0x00000454, 0x00000404, 0x00000404, 0x00000455, 0x00000405, 0x00000405, 0x00000456, 0x00000406, 0x00000406, 0x00000457, 0x00000407, 0x00000407, 0x00000458, 0x00000408, 0x00000408, 0x00000459, 0x00000409, 0x00000409, 0x0000045a, 0x0000040a, 0x0000040a, 0x0000045b, 0x0000040b, 0x0000040b, 0x0000045c, 0x0000040c, 0x0000040c, 0x0000045d, 0x0000040d, 0x0000040d, 0x0000045e, 0x0000040e, 0x0000040e, 0x0000045f, 0x0000040f, 0x0000040f, 0x00000461, 0x00000460, 0x00000460, 0x00000463, 0x00000462, 0x00000462, 0x00000465, 0x00000464, 0x00000464, 0x00000467, 0x00000466, 0x00000466, 0x00000469, 0x00000468, 0x00000468, 0x0000046b, 0x0000046a, 0x0000046a, 0x0000046d, 0x0000046c, 0x0000046c, 0x0000046f, 0x0000046e, 0x0000046e, 0x00000471, 0x00000470, 0x00000470, 0x00000473, 0x00000472, 0x00000472, 0x00000475, 0x00000474, 0x00000474, 0x00000477, 0x00000476, 0x00000476, 0x00000479, 0x00000478, 0x00000478, 0x0000047b, 0x0000047a, 0x0000047a, 0x0000047d, 0x0000047c, 0x0000047c, 0x0000047f, 0x0000047e, 0x0000047e, 0x00000481, 0x00000480, 0x00000480, 0x0000048b, 0x0000048a, 0x0000048a, 0x0000048d, 0x0000048c, 0x0000048c, 0x0000048f, 0x0000048e, 0x0000048e, 0x00000491, 0x00000490, 0x00000490, 0x00000493, 0x00000492, 0x00000492, 0x00000495, 0x00000494, 0x00000494, 0x00000497, 0x00000496, 0x00000496, 0x00000499, 0x00000498, 0x00000498, 0x0000049b, 0x0000049a, 0x0000049a, 0x0000049d, 0x0000049c, 0x0000049c, 0x0000049f, 0x0000049e, 0x0000049e, 0x000004a1, 0x000004a0, 0x000004a0, 0x000004a3, 0x000004a2, 0x000004a2, 0x000004a5, 0x000004a4, 0x000004a4, 0x000004a7, 0x000004a6, 0x000004a6, 0x000004a9, 0x000004a8, 0x000004a8, 0x000004ab, 0x000004aa, 0x000004aa, 0x000004ad, 0x000004ac, 0x000004ac, 0x000004af, 0x000004ae, 0x000004ae, 0x000004b1, 0x000004b0, 0x000004b0, 0x000004b3, 0x000004b2, 0x000004b2, 0x000004b5, 0x000004b4, 0x000004b4, 0x000004b7, 0x000004b6, 0x000004b6, 0x000004b9, 0x000004b8, 0x000004b8, 0x000004bb, 0x000004ba, 0x000004ba, 0x000004bd, 0x000004bc, 0x000004bc, 0x000004bf, 0x000004be, 0x000004be, 0x000004c2, 0x000004c1, 0x000004c1, 0x000004c4, 0x000004c3, 0x000004c3, 0x000004c6, 0x000004c5, 0x000004c5, 0x000004c8, 0x000004c7, 0x000004c7, 0x000004ca, 0x000004c9, 0x000004c9, 0x000004cc, 0x000004cb, 0x000004cb, 0x000004ce, 0x000004cd, 0x000004cd, 0x000004d1, 0x000004d0, 0x000004d0, 0x000004d3, 0x000004d2, 0x000004d2, 0x000004d5, 0x000004d4, 0x000004d4, 0x000004d7, 0x000004d6, 0x000004d6, 0x000004d9, 0x000004d8, 0x000004d8, 0x000004db, 0x000004da, 0x000004da, 0x000004dd, 0x000004dc, 0x000004dc, 0x000004df, 0x000004de, 0x000004de, 0x000004e1, 0x000004e0, 0x000004e0, 0x000004e3, 0x000004e2, 0x000004e2, 0x000004e5, 0x000004e4, 0x000004e4, 0x000004e7, 0x000004e6, 0x000004e6, 0x000004e9, 0x000004e8, 0x000004e8, 0x000004eb, 0x000004ea, 0x000004ea, 0x000004ed, 0x000004ec, 0x000004ec, 0x000004ef, 0x000004ee, 0x000004ee, 0x000004f1, 0x000004f0, 0x000004f0, 0x000004f3, 0x000004f2, 0x000004f2, 0x000004f5, 0x000004f4, 0x000004f4, 0x000004f9, 0x000004f8, 0x000004f8, 0x00000501, 0x00000500, 0x00000500, 0x00000503, 0x00000502, 0x00000502, 0x00000505, 0x00000504, 0x00000504, 0x00000507, 0x00000506, 0x00000506, 0x00000509, 0x00000508, 0x00000508, 0x0000050b, 0x0000050a, 0x0000050a, 0x0000050d, 0x0000050c, 0x0000050c, 0x0000050f, 0x0000050e, 0x0000050e, 0x00000561, 0x00000531, 0x00000531, 0x00000562, 0x00000532, 0x00000532, 0x00000563, 0x00000533, 0x00000533, 0x00000564, 0x00000534, 0x00000534, 0x00000565, 0x00000535, 0x00000535, 0x00000566, 0x00000536, 0x00000536, 0x00000567, 0x00000537, 0x00000537, 0x00000568, 0x00000538, 0x00000538, 0x00000569, 0x00000539, 0x00000539, 0x0000056a, 0x0000053a, 0x0000053a, 0x0000056b, 0x0000053b, 0x0000053b, 0x0000056c, 0x0000053c, 0x0000053c, 0x0000056d, 0x0000053d, 0x0000053d, 0x0000056e, 0x0000053e, 0x0000053e, 0x0000056f, 0x0000053f, 0x0000053f, 0x00000570, 0x00000540, 0x00000540, 0x00000571, 0x00000541, 0x00000541, 0x00000572, 0x00000542, 0x00000542, 0x00000573, 0x00000543, 0x00000543, 0x00000574, 0x00000544, 0x00000544, 0x00000575, 0x00000545, 0x00000545, 0x00000576, 0x00000546, 0x00000546, 0x00000577, 0x00000547, 0x00000547, 0x00000578, 0x00000548, 0x00000548, 0x00000579, 0x00000549, 0x00000549, 0x0000057a, 0x0000054a, 0x0000054a, 0x0000057b, 0x0000054b, 0x0000054b, 0x0000057c, 0x0000054c, 0x0000054c, 0x0000057d, 0x0000054d, 0x0000054d, 0x0000057e, 0x0000054e, 0x0000054e, 0x0000057f, 0x0000054f, 0x0000054f, 0x00000580, 0x00000550, 0x00000550, 0x00000581, 0x00000551, 0x00000551, 0x00000582, 0x00000552, 0x00000552, 0x00000583, 0x00000553, 0x00000553, 0x00000584, 0x00000554, 0x00000554, 0x00000585, 0x00000555, 0x00000555, 0x00000586, 0x00000556, 0x00000556, 0x00001e01, 0x00001e00, 0x00001e00, 0x00001e03, 0x00001e02, 0x00001e02, 0x00001e05, 0x00001e04, 0x00001e04, 0x00001e07, 0x00001e06, 0x00001e06, 0x00001e09, 0x00001e08, 0x00001e08, 0x00001e0b, 0x00001e0a, 0x00001e0a, 0x00001e0d, 0x00001e0c, 0x00001e0c, 0x00001e0f, 0x00001e0e, 0x00001e0e, 0x00001e11, 0x00001e10, 0x00001e10, 0x00001e13, 0x00001e12, 0x00001e12, 0x00001e15, 0x00001e14, 0x00001e14, 0x00001e17, 0x00001e16, 0x00001e16, 0x00001e19, 0x00001e18, 0x00001e18, 0x00001e1b, 0x00001e1a, 0x00001e1a, 0x00001e1d, 0x00001e1c, 0x00001e1c, 0x00001e1f, 0x00001e1e, 0x00001e1e, 0x00001e21, 0x00001e20, 0x00001e20, 0x00001e23, 0x00001e22, 0x00001e22, 0x00001e25, 0x00001e24, 0x00001e24, 0x00001e27, 0x00001e26, 0x00001e26, 0x00001e29, 0x00001e28, 0x00001e28, 0x00001e2b, 0x00001e2a, 0x00001e2a, 0x00001e2d, 0x00001e2c, 0x00001e2c, 0x00001e2f, 0x00001e2e, 0x00001e2e, 0x00001e31, 0x00001e30, 0x00001e30, 0x00001e33, 0x00001e32, 0x00001e32, 0x00001e35, 0x00001e34, 0x00001e34, 0x00001e37, 0x00001e36, 0x00001e36, 0x00001e39, 0x00001e38, 0x00001e38, 0x00001e3b, 0x00001e3a, 0x00001e3a, 0x00001e3d, 0x00001e3c, 0x00001e3c, 0x00001e3f, 0x00001e3e, 0x00001e3e, 0x00001e41, 0x00001e40, 0x00001e40, 0x00001e43, 0x00001e42, 0x00001e42, 0x00001e45, 0x00001e44, 0x00001e44, 0x00001e47, 0x00001e46, 0x00001e46, 0x00001e49, 0x00001e48, 0x00001e48, 0x00001e4b, 0x00001e4a, 0x00001e4a, 0x00001e4d, 0x00001e4c, 0x00001e4c, 0x00001e4f, 0x00001e4e, 0x00001e4e, 0x00001e51, 0x00001e50, 0x00001e50, 0x00001e53, 0x00001e52, 0x00001e52, 0x00001e55, 0x00001e54, 0x00001e54, 0x00001e57, 0x00001e56, 0x00001e56, 0x00001e59, 0x00001e58, 0x00001e58, 0x00001e5b, 0x00001e5a, 0x00001e5a, 0x00001e5d, 0x00001e5c, 0x00001e5c, 0x00001e5f, 0x00001e5e, 0x00001e5e, 0x00001e61, 0x00001e60, 0x00001e60, 0x00001e63, 0x00001e62, 0x00001e62, 0x00001e65, 0x00001e64, 0x00001e64, 0x00001e67, 0x00001e66, 0x00001e66, 0x00001e69, 0x00001e68, 0x00001e68, 0x00001e6b, 0x00001e6a, 0x00001e6a, 0x00001e6d, 0x00001e6c, 0x00001e6c, 0x00001e6f, 0x00001e6e, 0x00001e6e, 0x00001e71, 0x00001e70, 0x00001e70, 0x00001e73, 0x00001e72, 0x00001e72, 0x00001e75, 0x00001e74, 0x00001e74, 0x00001e77, 0x00001e76, 0x00001e76, 0x00001e79, 0x00001e78, 0x00001e78, 0x00001e7b, 0x00001e7a, 0x00001e7a, 0x00001e7d, 0x00001e7c, 0x00001e7c, 0x00001e7f, 0x00001e7e, 0x00001e7e, 0x00001e81, 0x00001e80, 0x00001e80, 0x00001e83, 0x00001e82, 0x00001e82, 0x00001e85, 0x00001e84, 0x00001e84, 0x00001e87, 0x00001e86, 0x00001e86, 0x00001e89, 0x00001e88, 0x00001e88, 0x00001e8b, 0x00001e8a, 0x00001e8a, 0x00001e8d, 0x00001e8c, 0x00001e8c, 0x00001e8f, 0x00001e8e, 0x00001e8e, 0x00001e91, 0x00001e90, 0x00001e90, 0x00001e93, 0x00001e92, 0x00001e92, 0x00001e95, 0x00001e94, 0x00001e94, 0x00001e9b, 0x00001e60, 0x00001e60, 0x00001ea1, 0x00001ea0, 0x00001ea0, 0x00001ea3, 0x00001ea2, 0x00001ea2, 0x00001ea5, 0x00001ea4, 0x00001ea4, 0x00001ea7, 0x00001ea6, 0x00001ea6, 0x00001ea9, 0x00001ea8, 0x00001ea8, 0x00001eab, 0x00001eaa, 0x00001eaa, 0x00001ead, 0x00001eac, 0x00001eac, 0x00001eaf, 0x00001eae, 0x00001eae, 0x00001eb1, 0x00001eb0, 0x00001eb0, 0x00001eb3, 0x00001eb2, 0x00001eb2, 0x00001eb5, 0x00001eb4, 0x00001eb4, 0x00001eb7, 0x00001eb6, 0x00001eb6, 0x00001eb9, 0x00001eb8, 0x00001eb8, 0x00001ebb, 0x00001eba, 0x00001eba, 0x00001ebd, 0x00001ebc, 0x00001ebc, 0x00001ebf, 0x00001ebe, 0x00001ebe, 0x00001ec1, 0x00001ec0, 0x00001ec0, 0x00001ec3, 0x00001ec2, 0x00001ec2, 0x00001ec5, 0x00001ec4, 0x00001ec4, 0x00001ec7, 0x00001ec6, 0x00001ec6, 0x00001ec9, 0x00001ec8, 0x00001ec8, 0x00001ecb, 0x00001eca, 0x00001eca, 0x00001ecd, 0x00001ecc, 0x00001ecc, 0x00001ecf, 0x00001ece, 0x00001ece, 0x00001ed1, 0x00001ed0, 0x00001ed0, 0x00001ed3, 0x00001ed2, 0x00001ed2, 0x00001ed5, 0x00001ed4, 0x00001ed4, 0x00001ed7, 0x00001ed6, 0x00001ed6, 0x00001ed9, 0x00001ed8, 0x00001ed8, 0x00001edb, 0x00001eda, 0x00001eda, 0x00001edd, 0x00001edc, 0x00001edc, 0x00001edf, 0x00001ede, 0x00001ede, 0x00001ee1, 0x00001ee0, 0x00001ee0, 0x00001ee3, 0x00001ee2, 0x00001ee2, 0x00001ee5, 0x00001ee4, 0x00001ee4, 0x00001ee7, 0x00001ee6, 0x00001ee6, 0x00001ee9, 0x00001ee8, 0x00001ee8, 0x00001eeb, 0x00001eea, 0x00001eea, 0x00001eed, 0x00001eec, 0x00001eec, 0x00001eef, 0x00001eee, 0x00001eee, 0x00001ef1, 0x00001ef0, 0x00001ef0, 0x00001ef3, 0x00001ef2, 0x00001ef2, 0x00001ef5, 0x00001ef4, 0x00001ef4, 0x00001ef7, 0x00001ef6, 0x00001ef6, 0x00001ef9, 0x00001ef8, 0x00001ef8, 0x00001f00, 0x00001f08, 0x00001f08, 0x00001f01, 0x00001f09, 0x00001f09, 0x00001f02, 0x00001f0a, 0x00001f0a, 0x00001f03, 0x00001f0b, 0x00001f0b, 0x00001f04, 0x00001f0c, 0x00001f0c, 0x00001f05, 0x00001f0d, 0x00001f0d, 0x00001f06, 0x00001f0e, 0x00001f0e, 0x00001f07, 0x00001f0f, 0x00001f0f, 0x00001f10, 0x00001f18, 0x00001f18, 0x00001f11, 0x00001f19, 0x00001f19, 0x00001f12, 0x00001f1a, 0x00001f1a, 0x00001f13, 0x00001f1b, 0x00001f1b, 0x00001f14, 0x00001f1c, 0x00001f1c, 0x00001f15, 0x00001f1d, 0x00001f1d, 0x00001f20, 0x00001f28, 0x00001f28, 0x00001f21, 0x00001f29, 0x00001f29, 0x00001f22, 0x00001f2a, 0x00001f2a, 0x00001f23, 0x00001f2b, 0x00001f2b, 0x00001f24, 0x00001f2c, 0x00001f2c, 0x00001f25, 0x00001f2d, 0x00001f2d, 0x00001f26, 0x00001f2e, 0x00001f2e, 0x00001f27, 0x00001f2f, 0x00001f2f, 0x00001f30, 0x00001f38, 0x00001f38, 0x00001f31, 0x00001f39, 0x00001f39, 0x00001f32, 0x00001f3a, 0x00001f3a, 0x00001f33, 0x00001f3b, 0x00001f3b, 0x00001f34, 0x00001f3c, 0x00001f3c, 0x00001f35, 0x00001f3d, 0x00001f3d, 0x00001f36, 0x00001f3e, 0x00001f3e, 0x00001f37, 0x00001f3f, 0x00001f3f, 0x00001f40, 0x00001f48, 0x00001f48, 0x00001f41, 0x00001f49, 0x00001f49, 0x00001f42, 0x00001f4a, 0x00001f4a, 0x00001f43, 0x00001f4b, 0x00001f4b, 0x00001f44, 0x00001f4c, 0x00001f4c, 0x00001f45, 0x00001f4d, 0x00001f4d, 0x00001f51, 0x00001f59, 0x00001f59, 0x00001f53, 0x00001f5b, 0x00001f5b, 0x00001f55, 0x00001f5d, 0x00001f5d, 0x00001f57, 0x00001f5f, 0x00001f5f, 0x00001f60, 0x00001f68, 0x00001f68, 0x00001f61, 0x00001f69, 0x00001f69, 0x00001f62, 0x00001f6a, 0x00001f6a, 0x00001f63, 0x00001f6b, 0x00001f6b, 0x00001f64, 0x00001f6c, 0x00001f6c, 0x00001f65, 0x00001f6d, 0x00001f6d, 0x00001f66, 0x00001f6e, 0x00001f6e, 0x00001f67, 0x00001f6f, 0x00001f6f, 0x00001f70, 0x00001fba, 0x00001fba, 0x00001f71, 0x00001fbb, 0x00001fbb, 0x00001f72, 0x00001fc8, 0x00001fc8, 0x00001f73, 0x00001fc9, 0x00001fc9, 0x00001f74, 0x00001fca, 0x00001fca, 0x00001f75, 0x00001fcb, 0x00001fcb, 0x00001f76, 0x00001fda, 0x00001fda, 0x00001f77, 0x00001fdb, 0x00001fdb, 0x00001f78, 0x00001ff8, 0x00001ff8, 0x00001f79, 0x00001ff9, 0x00001ff9, 0x00001f7a, 0x00001fea, 0x00001fea, 0x00001f7b, 0x00001feb, 0x00001feb, 0x00001f7c, 0x00001ffa, 0x00001ffa, 0x00001f7d, 0x00001ffb, 0x00001ffb, 0x00001f80, 0x00001f88, 0x00001f88, 0x00001f81, 0x00001f89, 0x00001f89, 0x00001f82, 0x00001f8a, 0x00001f8a, 0x00001f83, 0x00001f8b, 0x00001f8b, 0x00001f84, 0x00001f8c, 0x00001f8c, 0x00001f85, 0x00001f8d, 0x00001f8d, 0x00001f86, 0x00001f8e, 0x00001f8e, 0x00001f87, 0x00001f8f, 0x00001f8f, 0x00001f90, 0x00001f98, 0x00001f98, 0x00001f91, 0x00001f99, 0x00001f99, 0x00001f92, 0x00001f9a, 0x00001f9a, 0x00001f93, 0x00001f9b, 0x00001f9b, 0x00001f94, 0x00001f9c, 0x00001f9c, 0x00001f95, 0x00001f9d, 0x00001f9d, 0x00001f96, 0x00001f9e, 0x00001f9e, 0x00001f97, 0x00001f9f, 0x00001f9f, 0x00001fa0, 0x00001fa8, 0x00001fa8, 0x00001fa1, 0x00001fa9, 0x00001fa9, 0x00001fa2, 0x00001faa, 0x00001faa, 0x00001fa3, 0x00001fab, 0x00001fab, 0x00001fa4, 0x00001fac, 0x00001fac, 0x00001fa5, 0x00001fad, 0x00001fad, 0x00001fa6, 0x00001fae, 0x00001fae, 0x00001fa7, 0x00001faf, 0x00001faf, 0x00001fb0, 0x00001fb8, 0x00001fb8, 0x00001fb1, 0x00001fb9, 0x00001fb9, 0x00001fb3, 0x00001fbc, 0x00001fbc, 0x00001fbe, 0x00000399, 0x00000399, 0x00001fc3, 0x00001fcc, 0x00001fcc, 0x00001fd0, 0x00001fd8, 0x00001fd8, 0x00001fd1, 0x00001fd9, 0x00001fd9, 0x00001fe0, 0x00001fe8, 0x00001fe8, 0x00001fe1, 0x00001fe9, 0x00001fe9, 0x00001fe5, 0x00001fec, 0x00001fec, 0x00001ff3, 0x00001ffc, 0x00001ffc, 0x00002170, 0x00002160, 0x00002160, 0x00002171, 0x00002161, 0x00002161, 0x00002172, 0x00002162, 0x00002162, 0x00002173, 0x00002163, 0x00002163, 0x00002174, 0x00002164, 0x00002164, 0x00002175, 0x00002165, 0x00002165, 0x00002176, 0x00002166, 0x00002166, 0x00002177, 0x00002167, 0x00002167, 0x00002178, 0x00002168, 0x00002168, 0x00002179, 0x00002169, 0x00002169, 0x0000217a, 0x0000216a, 0x0000216a, 0x0000217b, 0x0000216b, 0x0000216b, 0x0000217c, 0x0000216c, 0x0000216c, 0x0000217d, 0x0000216d, 0x0000216d, 0x0000217e, 0x0000216e, 0x0000216e, 0x0000217f, 0x0000216f, 0x0000216f, 0x000024d0, 0x000024b6, 0x000024b6, 0x000024d1, 0x000024b7, 0x000024b7, 0x000024d2, 0x000024b8, 0x000024b8, 0x000024d3, 0x000024b9, 0x000024b9, 0x000024d4, 0x000024ba, 0x000024ba, 0x000024d5, 0x000024bb, 0x000024bb, 0x000024d6, 0x000024bc, 0x000024bc, 0x000024d7, 0x000024bd, 0x000024bd, 0x000024d8, 0x000024be, 0x000024be, 0x000024d9, 0x000024bf, 0x000024bf, 0x000024da, 0x000024c0, 0x000024c0, 0x000024db, 0x000024c1, 0x000024c1, 0x000024dc, 0x000024c2, 0x000024c2, 0x000024dd, 0x000024c3, 0x000024c3, 0x000024de, 0x000024c4, 0x000024c4, 0x000024df, 0x000024c5, 0x000024c5, 0x000024e0, 0x000024c6, 0x000024c6, 0x000024e1, 0x000024c7, 0x000024c7, 0x000024e2, 0x000024c8, 0x000024c8, 0x000024e3, 0x000024c9, 0x000024c9, 0x000024e4, 0x000024ca, 0x000024ca, 0x000024e5, 0x000024cb, 0x000024cb, 0x000024e6, 0x000024cc, 0x000024cc, 0x000024e7, 0x000024cd, 0x000024cd, 0x000024e8, 0x000024ce, 0x000024ce, 0x000024e9, 0x000024cf, 0x000024cf, 0x0000ff41, 0x0000ff21, 0x0000ff21, 0x0000ff42, 0x0000ff22, 0x0000ff22, 0x0000ff43, 0x0000ff23, 0x0000ff23, 0x0000ff44, 0x0000ff24, 0x0000ff24, 0x0000ff45, 0x0000ff25, 0x0000ff25, 0x0000ff46, 0x0000ff26, 0x0000ff26, 0x0000ff47, 0x0000ff27, 0x0000ff27, 0x0000ff48, 0x0000ff28, 0x0000ff28, 0x0000ff49, 0x0000ff29, 0x0000ff29, 0x0000ff4a, 0x0000ff2a, 0x0000ff2a, 0x0000ff4b, 0x0000ff2b, 0x0000ff2b, 0x0000ff4c, 0x0000ff2c, 0x0000ff2c, 0x0000ff4d, 0x0000ff2d, 0x0000ff2d, 0x0000ff4e, 0x0000ff2e, 0x0000ff2e, 0x0000ff4f, 0x0000ff2f, 0x0000ff2f, 0x0000ff50, 0x0000ff30, 0x0000ff30, 0x0000ff51, 0x0000ff31, 0x0000ff31, 0x0000ff52, 0x0000ff32, 0x0000ff32, 0x0000ff53, 0x0000ff33, 0x0000ff33, 0x0000ff54, 0x0000ff34, 0x0000ff34, 0x0000ff55, 0x0000ff35, 0x0000ff35, 0x0000ff56, 0x0000ff36, 0x0000ff36, 0x0000ff57, 0x0000ff37, 0x0000ff37, 0x0000ff58, 0x0000ff38, 0x0000ff38, 0x0000ff59, 0x0000ff39, 0x0000ff39, 0x0000ff5a, 0x0000ff3a, 0x0000ff3a, 0x00010428, 0x00010400, 0x00010400, 0x00010429, 0x00010401, 0x00010401, 0x0001042a, 0x00010402, 0x00010402, 0x0001042b, 0x00010403, 0x00010403, 0x0001042c, 0x00010404, 0x00010404, 0x0001042d, 0x00010405, 0x00010405, 0x0001042e, 0x00010406, 0x00010406, 0x0001042f, 0x00010407, 0x00010407, 0x00010430, 0x00010408, 0x00010408, 0x00010431, 0x00010409, 0x00010409, 0x00010432, 0x0001040a, 0x0001040a, 0x00010433, 0x0001040b, 0x0001040b, 0x00010434, 0x0001040c, 0x0001040c, 0x00010435, 0x0001040d, 0x0001040d, 0x00010436, 0x0001040e, 0x0001040e, 0x00010437, 0x0001040f, 0x0001040f, 0x00010438, 0x00010410, 0x00010410, 0x00010439, 0x00010411, 0x00010411, 0x0001043a, 0x00010412, 0x00010412, 0x0001043b, 0x00010413, 0x00010413, 0x0001043c, 0x00010414, 0x00010414, 0x0001043d, 0x00010415, 0x00010415, 0x0001043e, 0x00010416, 0x00010416, 0x0001043f, 0x00010417, 0x00010417, 0x00010440, 0x00010418, 0x00010418, 0x00010441, 0x00010419, 0x00010419, 0x00010442, 0x0001041a, 0x0001041a, 0x00010443, 0x0001041b, 0x0001041b, 0x00010444, 0x0001041c, 0x0001041c, 0x00010445, 0x0001041d, 0x0001041d, 0x00010446, 0x0001041e, 0x0001041e, 0x00010447, 0x0001041f, 0x0001041f, 0x00010448, 0x00010420, 0x00010420, 0x00010449, 0x00010421, 0x00010421, 0x0001044a, 0x00010422, 0x00010422, 0x0001044b, 0x00010423, 0x00010423, 0x0001044c, 0x00010424, 0x00010424, 0x0001044d, 0x00010425, 0x00010425, 0x000001c5, 0x000001c4, 0x000001c6, 0x000001c8, 0x000001c7, 0x000001c9, 0x000001cb, 0x000001ca, 0x000001cc, 0x000001f2, 0x000001f1, 0x000001f3 }; static const krb5_ui_4 _uccomp_size = 3684; static const krb5_ui_4 _uccomp_data[] = { 0x0000226e, 0x00000002, 0x0000003c, 0x00000338, 0x00002260, 0x00000002, 0x0000003d, 0x00000338, 0x0000226f, 0x00000002, 0x0000003e, 0x00000338, 0x000000c0, 0x00000002, 0x00000041, 0x00000300, 0x000000c1, 0x00000002, 0x00000041, 0x00000301, 0x000000c2, 0x00000002, 0x00000041, 0x00000302, 0x000000c3, 0x00000002, 0x00000041, 0x00000303, 0x00000100, 0x00000002, 0x00000041, 0x00000304, 0x00000102, 0x00000002, 0x00000041, 0x00000306, 0x00000226, 0x00000002, 0x00000041, 0x00000307, 0x000000c4, 0x00000002, 0x00000041, 0x00000308, 0x00001ea2, 0x00000002, 0x00000041, 0x00000309, 0x000000c5, 0x00000002, 0x00000041, 0x0000030a, 0x000001cd, 0x00000002, 0x00000041, 0x0000030c, 0x00000200, 0x00000002, 0x00000041, 0x0000030f, 0x00000202, 0x00000002, 0x00000041, 0x00000311, 0x00001ea0, 0x00000002, 0x00000041, 0x00000323, 0x00001e00, 0x00000002, 0x00000041, 0x00000325, 0x00000104, 0x00000002, 0x00000041, 0x00000328, 0x00001e02, 0x00000002, 0x00000042, 0x00000307, 0x00001e04, 0x00000002, 0x00000042, 0x00000323, 0x00001e06, 0x00000002, 0x00000042, 0x00000331, 0x00000106, 0x00000002, 0x00000043, 0x00000301, 0x00000108, 0x00000002, 0x00000043, 0x00000302, 0x0000010a, 0x00000002, 0x00000043, 0x00000307, 0x0000010c, 0x00000002, 0x00000043, 0x0000030c, 0x000000c7, 0x00000002, 0x00000043, 0x00000327, 0x00001e0a, 0x00000002, 0x00000044, 0x00000307, 0x0000010e, 0x00000002, 0x00000044, 0x0000030c, 0x00001e0c, 0x00000002, 0x00000044, 0x00000323, 0x00001e10, 0x00000002, 0x00000044, 0x00000327, 0x00001e12, 0x00000002, 0x00000044, 0x0000032d, 0x00001e0e, 0x00000002, 0x00000044, 0x00000331, 0x000000c8, 0x00000002, 0x00000045, 0x00000300, 0x000000c9, 0x00000002, 0x00000045, 0x00000301, 0x000000ca, 0x00000002, 0x00000045, 0x00000302, 0x00001ebc, 0x00000002, 0x00000045, 0x00000303, 0x00000112, 0x00000002, 0x00000045, 0x00000304, 0x00000114, 0x00000002, 0x00000045, 0x00000306, 0x00000116, 0x00000002, 0x00000045, 0x00000307, 0x000000cb, 0x00000002, 0x00000045, 0x00000308, 0x00001eba, 0x00000002, 0x00000045, 0x00000309, 0x0000011a, 0x00000002, 0x00000045, 0x0000030c, 0x00000204, 0x00000002, 0x00000045, 0x0000030f, 0x00000206, 0x00000002, 0x00000045, 0x00000311, 0x00001eb8, 0x00000002, 0x00000045, 0x00000323, 0x00000228, 0x00000002, 0x00000045, 0x00000327, 0x00000118, 0x00000002, 0x00000045, 0x00000328, 0x00001e18, 0x00000002, 0x00000045, 0x0000032d, 0x00001e1a, 0x00000002, 0x00000045, 0x00000330, 0x00001e1e, 0x00000002, 0x00000046, 0x00000307, 0x000001f4, 0x00000002, 0x00000047, 0x00000301, 0x0000011c, 0x00000002, 0x00000047, 0x00000302, 0x00001e20, 0x00000002, 0x00000047, 0x00000304, 0x0000011e, 0x00000002, 0x00000047, 0x00000306, 0x00000120, 0x00000002, 0x00000047, 0x00000307, 0x000001e6, 0x00000002, 0x00000047, 0x0000030c, 0x00000122, 0x00000002, 0x00000047, 0x00000327, 0x00000124, 0x00000002, 0x00000048, 0x00000302, 0x00001e22, 0x00000002, 0x00000048, 0x00000307, 0x00001e26, 0x00000002, 0x00000048, 0x00000308, 0x0000021e, 0x00000002, 0x00000048, 0x0000030c, 0x00001e24, 0x00000002, 0x00000048, 0x00000323, 0x00001e28, 0x00000002, 0x00000048, 0x00000327, 0x00001e2a, 0x00000002, 0x00000048, 0x0000032e, 0x000000cc, 0x00000002, 0x00000049, 0x00000300, 0x000000cd, 0x00000002, 0x00000049, 0x00000301, 0x000000ce, 0x00000002, 0x00000049, 0x00000302, 0x00000128, 0x00000002, 0x00000049, 0x00000303, 0x0000012a, 0x00000002, 0x00000049, 0x00000304, 0x0000012c, 0x00000002, 0x00000049, 0x00000306, 0x00000130, 0x00000002, 0x00000049, 0x00000307, 0x000000cf, 0x00000002, 0x00000049, 0x00000308, 0x00001ec8, 0x00000002, 0x00000049, 0x00000309, 0x000001cf, 0x00000002, 0x00000049, 0x0000030c, 0x00000208, 0x00000002, 0x00000049, 0x0000030f, 0x0000020a, 0x00000002, 0x00000049, 0x00000311, 0x00001eca, 0x00000002, 0x00000049, 0x00000323, 0x0000012e, 0x00000002, 0x00000049, 0x00000328, 0x00001e2c, 0x00000002, 0x00000049, 0x00000330, 0x00000134, 0x00000002, 0x0000004a, 0x00000302, 0x00001e30, 0x00000002, 0x0000004b, 0x00000301, 0x000001e8, 0x00000002, 0x0000004b, 0x0000030c, 0x00001e32, 0x00000002, 0x0000004b, 0x00000323, 0x00000136, 0x00000002, 0x0000004b, 0x00000327, 0x00001e34, 0x00000002, 0x0000004b, 0x00000331, 0x00000139, 0x00000002, 0x0000004c, 0x00000301, 0x0000013d, 0x00000002, 0x0000004c, 0x0000030c, 0x00001e36, 0x00000002, 0x0000004c, 0x00000323, 0x0000013b, 0x00000002, 0x0000004c, 0x00000327, 0x00001e3c, 0x00000002, 0x0000004c, 0x0000032d, 0x00001e3a, 0x00000002, 0x0000004c, 0x00000331, 0x00001e3e, 0x00000002, 0x0000004d, 0x00000301, 0x00001e40, 0x00000002, 0x0000004d, 0x00000307, 0x00001e42, 0x00000002, 0x0000004d, 0x00000323, 0x000001f8, 0x00000002, 0x0000004e, 0x00000300, 0x00000143, 0x00000002, 0x0000004e, 0x00000301, 0x000000d1, 0x00000002, 0x0000004e, 0x00000303, 0x00001e44, 0x00000002, 0x0000004e, 0x00000307, 0x00000147, 0x00000002, 0x0000004e, 0x0000030c, 0x00001e46, 0x00000002, 0x0000004e, 0x00000323, 0x00000145, 0x00000002, 0x0000004e, 0x00000327, 0x00001e4a, 0x00000002, 0x0000004e, 0x0000032d, 0x00001e48, 0x00000002, 0x0000004e, 0x00000331, 0x000000d2, 0x00000002, 0x0000004f, 0x00000300, 0x000000d3, 0x00000002, 0x0000004f, 0x00000301, 0x000000d4, 0x00000002, 0x0000004f, 0x00000302, 0x000000d5, 0x00000002, 0x0000004f, 0x00000303, 0x0000014c, 0x00000002, 0x0000004f, 0x00000304, 0x0000014e, 0x00000002, 0x0000004f, 0x00000306, 0x0000022e, 0x00000002, 0x0000004f, 0x00000307, 0x000000d6, 0x00000002, 0x0000004f, 0x00000308, 0x00001ece, 0x00000002, 0x0000004f, 0x00000309, 0x00000150, 0x00000002, 0x0000004f, 0x0000030b, 0x000001d1, 0x00000002, 0x0000004f, 0x0000030c, 0x0000020c, 0x00000002, 0x0000004f, 0x0000030f, 0x0000020e, 0x00000002, 0x0000004f, 0x00000311, 0x000001a0, 0x00000002, 0x0000004f, 0x0000031b, 0x00001ecc, 0x00000002, 0x0000004f, 0x00000323, 0x000001ea, 0x00000002, 0x0000004f, 0x00000328, 0x00001e54, 0x00000002, 0x00000050, 0x00000301, 0x00001e56, 0x00000002, 0x00000050, 0x00000307, 0x00000154, 0x00000002, 0x00000052, 0x00000301, 0x00001e58, 0x00000002, 0x00000052, 0x00000307, 0x00000158, 0x00000002, 0x00000052, 0x0000030c, 0x00000210, 0x00000002, 0x00000052, 0x0000030f, 0x00000212, 0x00000002, 0x00000052, 0x00000311, 0x00001e5a, 0x00000002, 0x00000052, 0x00000323, 0x00000156, 0x00000002, 0x00000052, 0x00000327, 0x00001e5e, 0x00000002, 0x00000052, 0x00000331, 0x0000015a, 0x00000002, 0x00000053, 0x00000301, 0x0000015c, 0x00000002, 0x00000053, 0x00000302, 0x00001e60, 0x00000002, 0x00000053, 0x00000307, 0x00000160, 0x00000002, 0x00000053, 0x0000030c, 0x00001e62, 0x00000002, 0x00000053, 0x00000323, 0x00000218, 0x00000002, 0x00000053, 0x00000326, 0x0000015e, 0x00000002, 0x00000053, 0x00000327, 0x00001e6a, 0x00000002, 0x00000054, 0x00000307, 0x00000164, 0x00000002, 0x00000054, 0x0000030c, 0x00001e6c, 0x00000002, 0x00000054, 0x00000323, 0x0000021a, 0x00000002, 0x00000054, 0x00000326, 0x00000162, 0x00000002, 0x00000054, 0x00000327, 0x00001e70, 0x00000002, 0x00000054, 0x0000032d, 0x00001e6e, 0x00000002, 0x00000054, 0x00000331, 0x000000d9, 0x00000002, 0x00000055, 0x00000300, 0x000000da, 0x00000002, 0x00000055, 0x00000301, 0x000000db, 0x00000002, 0x00000055, 0x00000302, 0x00000168, 0x00000002, 0x00000055, 0x00000303, 0x0000016a, 0x00000002, 0x00000055, 0x00000304, 0x0000016c, 0x00000002, 0x00000055, 0x00000306, 0x000000dc, 0x00000002, 0x00000055, 0x00000308, 0x00001ee6, 0x00000002, 0x00000055, 0x00000309, 0x0000016e, 0x00000002, 0x00000055, 0x0000030a, 0x00000170, 0x00000002, 0x00000055, 0x0000030b, 0x000001d3, 0x00000002, 0x00000055, 0x0000030c, 0x00000214, 0x00000002, 0x00000055, 0x0000030f, 0x00000216, 0x00000002, 0x00000055, 0x00000311, 0x000001af, 0x00000002, 0x00000055, 0x0000031b, 0x00001ee4, 0x00000002, 0x00000055, 0x00000323, 0x00001e72, 0x00000002, 0x00000055, 0x00000324, 0x00000172, 0x00000002, 0x00000055, 0x00000328, 0x00001e76, 0x00000002, 0x00000055, 0x0000032d, 0x00001e74, 0x00000002, 0x00000055, 0x00000330, 0x00001e7c, 0x00000002, 0x00000056, 0x00000303, 0x00001e7e, 0x00000002, 0x00000056, 0x00000323, 0x00001e80, 0x00000002, 0x00000057, 0x00000300, 0x00001e82, 0x00000002, 0x00000057, 0x00000301, 0x00000174, 0x00000002, 0x00000057, 0x00000302, 0x00001e86, 0x00000002, 0x00000057, 0x00000307, 0x00001e84, 0x00000002, 0x00000057, 0x00000308, 0x00001e88, 0x00000002, 0x00000057, 0x00000323, 0x00001e8a, 0x00000002, 0x00000058, 0x00000307, 0x00001e8c, 0x00000002, 0x00000058, 0x00000308, 0x00001ef2, 0x00000002, 0x00000059, 0x00000300, 0x000000dd, 0x00000002, 0x00000059, 0x00000301, 0x00000176, 0x00000002, 0x00000059, 0x00000302, 0x00001ef8, 0x00000002, 0x00000059, 0x00000303, 0x00000232, 0x00000002, 0x00000059, 0x00000304, 0x00001e8e, 0x00000002, 0x00000059, 0x00000307, 0x00000178, 0x00000002, 0x00000059, 0x00000308, 0x00001ef6, 0x00000002, 0x00000059, 0x00000309, 0x00001ef4, 0x00000002, 0x00000059, 0x00000323, 0x00000179, 0x00000002, 0x0000005a, 0x00000301, 0x00001e90, 0x00000002, 0x0000005a, 0x00000302, 0x0000017b, 0x00000002, 0x0000005a, 0x00000307, 0x0000017d, 0x00000002, 0x0000005a, 0x0000030c, 0x00001e92, 0x00000002, 0x0000005a, 0x00000323, 0x00001e94, 0x00000002, 0x0000005a, 0x00000331, 0x000000e0, 0x00000002, 0x00000061, 0x00000300, 0x000000e1, 0x00000002, 0x00000061, 0x00000301, 0x000000e2, 0x00000002, 0x00000061, 0x00000302, 0x000000e3, 0x00000002, 0x00000061, 0x00000303, 0x00000101, 0x00000002, 0x00000061, 0x00000304, 0x00000103, 0x00000002, 0x00000061, 0x00000306, 0x00000227, 0x00000002, 0x00000061, 0x00000307, 0x000000e4, 0x00000002, 0x00000061, 0x00000308, 0x00001ea3, 0x00000002, 0x00000061, 0x00000309, 0x000000e5, 0x00000002, 0x00000061, 0x0000030a, 0x000001ce, 0x00000002, 0x00000061, 0x0000030c, 0x00000201, 0x00000002, 0x00000061, 0x0000030f, 0x00000203, 0x00000002, 0x00000061, 0x00000311, 0x00001ea1, 0x00000002, 0x00000061, 0x00000323, 0x00001e01, 0x00000002, 0x00000061, 0x00000325, 0x00000105, 0x00000002, 0x00000061, 0x00000328, 0x00001e03, 0x00000002, 0x00000062, 0x00000307, 0x00001e05, 0x00000002, 0x00000062, 0x00000323, 0x00001e07, 0x00000002, 0x00000062, 0x00000331, 0x00000107, 0x00000002, 0x00000063, 0x00000301, 0x00000109, 0x00000002, 0x00000063, 0x00000302, 0x0000010b, 0x00000002, 0x00000063, 0x00000307, 0x0000010d, 0x00000002, 0x00000063, 0x0000030c, 0x000000e7, 0x00000002, 0x00000063, 0x00000327, 0x00001e0b, 0x00000002, 0x00000064, 0x00000307, 0x0000010f, 0x00000002, 0x00000064, 0x0000030c, 0x00001e0d, 0x00000002, 0x00000064, 0x00000323, 0x00001e11, 0x00000002, 0x00000064, 0x00000327, 0x00001e13, 0x00000002, 0x00000064, 0x0000032d, 0x00001e0f, 0x00000002, 0x00000064, 0x00000331, 0x000000e8, 0x00000002, 0x00000065, 0x00000300, 0x000000e9, 0x00000002, 0x00000065, 0x00000301, 0x000000ea, 0x00000002, 0x00000065, 0x00000302, 0x00001ebd, 0x00000002, 0x00000065, 0x00000303, 0x00000113, 0x00000002, 0x00000065, 0x00000304, 0x00000115, 0x00000002, 0x00000065, 0x00000306, 0x00000117, 0x00000002, 0x00000065, 0x00000307, 0x000000eb, 0x00000002, 0x00000065, 0x00000308, 0x00001ebb, 0x00000002, 0x00000065, 0x00000309, 0x0000011b, 0x00000002, 0x00000065, 0x0000030c, 0x00000205, 0x00000002, 0x00000065, 0x0000030f, 0x00000207, 0x00000002, 0x00000065, 0x00000311, 0x00001eb9, 0x00000002, 0x00000065, 0x00000323, 0x00000229, 0x00000002, 0x00000065, 0x00000327, 0x00000119, 0x00000002, 0x00000065, 0x00000328, 0x00001e19, 0x00000002, 0x00000065, 0x0000032d, 0x00001e1b, 0x00000002, 0x00000065, 0x00000330, 0x00001e1f, 0x00000002, 0x00000066, 0x00000307, 0x000001f5, 0x00000002, 0x00000067, 0x00000301, 0x0000011d, 0x00000002, 0x00000067, 0x00000302, 0x00001e21, 0x00000002, 0x00000067, 0x00000304, 0x0000011f, 0x00000002, 0x00000067, 0x00000306, 0x00000121, 0x00000002, 0x00000067, 0x00000307, 0x000001e7, 0x00000002, 0x00000067, 0x0000030c, 0x00000123, 0x00000002, 0x00000067, 0x00000327, 0x00000125, 0x00000002, 0x00000068, 0x00000302, 0x00001e23, 0x00000002, 0x00000068, 0x00000307, 0x00001e27, 0x00000002, 0x00000068, 0x00000308, 0x0000021f, 0x00000002, 0x00000068, 0x0000030c, 0x00001e25, 0x00000002, 0x00000068, 0x00000323, 0x00001e29, 0x00000002, 0x00000068, 0x00000327, 0x00001e2b, 0x00000002, 0x00000068, 0x0000032e, 0x00001e96, 0x00000002, 0x00000068, 0x00000331, 0x000000ec, 0x00000002, 0x00000069, 0x00000300, 0x000000ed, 0x00000002, 0x00000069, 0x00000301, 0x000000ee, 0x00000002, 0x00000069, 0x00000302, 0x00000129, 0x00000002, 0x00000069, 0x00000303, 0x0000012b, 0x00000002, 0x00000069, 0x00000304, 0x0000012d, 0x00000002, 0x00000069, 0x00000306, 0x000000ef, 0x00000002, 0x00000069, 0x00000308, 0x00001ec9, 0x00000002, 0x00000069, 0x00000309, 0x000001d0, 0x00000002, 0x00000069, 0x0000030c, 0x00000209, 0x00000002, 0x00000069, 0x0000030f, 0x0000020b, 0x00000002, 0x00000069, 0x00000311, 0x00001ecb, 0x00000002, 0x00000069, 0x00000323, 0x0000012f, 0x00000002, 0x00000069, 0x00000328, 0x00001e2d, 0x00000002, 0x00000069, 0x00000330, 0x00000135, 0x00000002, 0x0000006a, 0x00000302, 0x000001f0, 0x00000002, 0x0000006a, 0x0000030c, 0x00001e31, 0x00000002, 0x0000006b, 0x00000301, 0x000001e9, 0x00000002, 0x0000006b, 0x0000030c, 0x00001e33, 0x00000002, 0x0000006b, 0x00000323, 0x00000137, 0x00000002, 0x0000006b, 0x00000327, 0x00001e35, 0x00000002, 0x0000006b, 0x00000331, 0x0000013a, 0x00000002, 0x0000006c, 0x00000301, 0x0000013e, 0x00000002, 0x0000006c, 0x0000030c, 0x00001e37, 0x00000002, 0x0000006c, 0x00000323, 0x0000013c, 0x00000002, 0x0000006c, 0x00000327, 0x00001e3d, 0x00000002, 0x0000006c, 0x0000032d, 0x00001e3b, 0x00000002, 0x0000006c, 0x00000331, 0x00001e3f, 0x00000002, 0x0000006d, 0x00000301, 0x00001e41, 0x00000002, 0x0000006d, 0x00000307, 0x00001e43, 0x00000002, 0x0000006d, 0x00000323, 0x000001f9, 0x00000002, 0x0000006e, 0x00000300, 0x00000144, 0x00000002, 0x0000006e, 0x00000301, 0x000000f1, 0x00000002, 0x0000006e, 0x00000303, 0x00001e45, 0x00000002, 0x0000006e, 0x00000307, 0x00000148, 0x00000002, 0x0000006e, 0x0000030c, 0x00001e47, 0x00000002, 0x0000006e, 0x00000323, 0x00000146, 0x00000002, 0x0000006e, 0x00000327, 0x00001e4b, 0x00000002, 0x0000006e, 0x0000032d, 0x00001e49, 0x00000002, 0x0000006e, 0x00000331, 0x000000f2, 0x00000002, 0x0000006f, 0x00000300, 0x000000f3, 0x00000002, 0x0000006f, 0x00000301, 0x000000f4, 0x00000002, 0x0000006f, 0x00000302, 0x000000f5, 0x00000002, 0x0000006f, 0x00000303, 0x0000014d, 0x00000002, 0x0000006f, 0x00000304, 0x0000014f, 0x00000002, 0x0000006f, 0x00000306, 0x0000022f, 0x00000002, 0x0000006f, 0x00000307, 0x000000f6, 0x00000002, 0x0000006f, 0x00000308, 0x00001ecf, 0x00000002, 0x0000006f, 0x00000309, 0x00000151, 0x00000002, 0x0000006f, 0x0000030b, 0x000001d2, 0x00000002, 0x0000006f, 0x0000030c, 0x0000020d, 0x00000002, 0x0000006f, 0x0000030f, 0x0000020f, 0x00000002, 0x0000006f, 0x00000311, 0x000001a1, 0x00000002, 0x0000006f, 0x0000031b, 0x00001ecd, 0x00000002, 0x0000006f, 0x00000323, 0x000001eb, 0x00000002, 0x0000006f, 0x00000328, 0x00001e55, 0x00000002, 0x00000070, 0x00000301, 0x00001e57, 0x00000002, 0x00000070, 0x00000307, 0x00000155, 0x00000002, 0x00000072, 0x00000301, 0x00001e59, 0x00000002, 0x00000072, 0x00000307, 0x00000159, 0x00000002, 0x00000072, 0x0000030c, 0x00000211, 0x00000002, 0x00000072, 0x0000030f, 0x00000213, 0x00000002, 0x00000072, 0x00000311, 0x00001e5b, 0x00000002, 0x00000072, 0x00000323, 0x00000157, 0x00000002, 0x00000072, 0x00000327, 0x00001e5f, 0x00000002, 0x00000072, 0x00000331, 0x0000015b, 0x00000002, 0x00000073, 0x00000301, 0x0000015d, 0x00000002, 0x00000073, 0x00000302, 0x00001e61, 0x00000002, 0x00000073, 0x00000307, 0x00000161, 0x00000002, 0x00000073, 0x0000030c, 0x00001e63, 0x00000002, 0x00000073, 0x00000323, 0x00000219, 0x00000002, 0x00000073, 0x00000326, 0x0000015f, 0x00000002, 0x00000073, 0x00000327, 0x00001e6b, 0x00000002, 0x00000074, 0x00000307, 0x00001e97, 0x00000002, 0x00000074, 0x00000308, 0x00000165, 0x00000002, 0x00000074, 0x0000030c, 0x00001e6d, 0x00000002, 0x00000074, 0x00000323, 0x0000021b, 0x00000002, 0x00000074, 0x00000326, 0x00000163, 0x00000002, 0x00000074, 0x00000327, 0x00001e71, 0x00000002, 0x00000074, 0x0000032d, 0x00001e6f, 0x00000002, 0x00000074, 0x00000331, 0x000000f9, 0x00000002, 0x00000075, 0x00000300, 0x000000fa, 0x00000002, 0x00000075, 0x00000301, 0x000000fb, 0x00000002, 0x00000075, 0x00000302, 0x00000169, 0x00000002, 0x00000075, 0x00000303, 0x0000016b, 0x00000002, 0x00000075, 0x00000304, 0x0000016d, 0x00000002, 0x00000075, 0x00000306, 0x000000fc, 0x00000002, 0x00000075, 0x00000308, 0x00001ee7, 0x00000002, 0x00000075, 0x00000309, 0x0000016f, 0x00000002, 0x00000075, 0x0000030a, 0x00000171, 0x00000002, 0x00000075, 0x0000030b, 0x000001d4, 0x00000002, 0x00000075, 0x0000030c, 0x00000215, 0x00000002, 0x00000075, 0x0000030f, 0x00000217, 0x00000002, 0x00000075, 0x00000311, 0x000001b0, 0x00000002, 0x00000075, 0x0000031b, 0x00001ee5, 0x00000002, 0x00000075, 0x00000323, 0x00001e73, 0x00000002, 0x00000075, 0x00000324, 0x00000173, 0x00000002, 0x00000075, 0x00000328, 0x00001e77, 0x00000002, 0x00000075, 0x0000032d, 0x00001e75, 0x00000002, 0x00000075, 0x00000330, 0x00001e7d, 0x00000002, 0x00000076, 0x00000303, 0x00001e7f, 0x00000002, 0x00000076, 0x00000323, 0x00001e81, 0x00000002, 0x00000077, 0x00000300, 0x00001e83, 0x00000002, 0x00000077, 0x00000301, 0x00000175, 0x00000002, 0x00000077, 0x00000302, 0x00001e87, 0x00000002, 0x00000077, 0x00000307, 0x00001e85, 0x00000002, 0x00000077, 0x00000308, 0x00001e98, 0x00000002, 0x00000077, 0x0000030a, 0x00001e89, 0x00000002, 0x00000077, 0x00000323, 0x00001e8b, 0x00000002, 0x00000078, 0x00000307, 0x00001e8d, 0x00000002, 0x00000078, 0x00000308, 0x00001ef3, 0x00000002, 0x00000079, 0x00000300, 0x000000fd, 0x00000002, 0x00000079, 0x00000301, 0x00000177, 0x00000002, 0x00000079, 0x00000302, 0x00001ef9, 0x00000002, 0x00000079, 0x00000303, 0x00000233, 0x00000002, 0x00000079, 0x00000304, 0x00001e8f, 0x00000002, 0x00000079, 0x00000307, 0x000000ff, 0x00000002, 0x00000079, 0x00000308, 0x00001ef7, 0x00000002, 0x00000079, 0x00000309, 0x00001e99, 0x00000002, 0x00000079, 0x0000030a, 0x00001ef5, 0x00000002, 0x00000079, 0x00000323, 0x0000017a, 0x00000002, 0x0000007a, 0x00000301, 0x00001e91, 0x00000002, 0x0000007a, 0x00000302, 0x0000017c, 0x00000002, 0x0000007a, 0x00000307, 0x0000017e, 0x00000002, 0x0000007a, 0x0000030c, 0x00001e93, 0x00000002, 0x0000007a, 0x00000323, 0x00001e95, 0x00000002, 0x0000007a, 0x00000331, 0x00001fed, 0x00000002, 0x000000a8, 0x00000300, 0x00000385, 0x00000002, 0x000000a8, 0x00000301, 0x00001fc1, 0x00000002, 0x000000a8, 0x00000342, 0x00001ea6, 0x00000002, 0x000000c2, 0x00000300, 0x00001ea4, 0x00000002, 0x000000c2, 0x00000301, 0x00001eaa, 0x00000002, 0x000000c2, 0x00000303, 0x00001ea8, 0x00000002, 0x000000c2, 0x00000309, 0x000001de, 0x00000002, 0x000000c4, 0x00000304, 0x000001fa, 0x00000002, 0x000000c5, 0x00000301, 0x000001fc, 0x00000002, 0x000000c6, 0x00000301, 0x000001e2, 0x00000002, 0x000000c6, 0x00000304, 0x00001e08, 0x00000002, 0x000000c7, 0x00000301, 0x00001ec0, 0x00000002, 0x000000ca, 0x00000300, 0x00001ebe, 0x00000002, 0x000000ca, 0x00000301, 0x00001ec4, 0x00000002, 0x000000ca, 0x00000303, 0x00001ec2, 0x00000002, 0x000000ca, 0x00000309, 0x00001e2e, 0x00000002, 0x000000cf, 0x00000301, 0x00001ed2, 0x00000002, 0x000000d4, 0x00000300, 0x00001ed0, 0x00000002, 0x000000d4, 0x00000301, 0x00001ed6, 0x00000002, 0x000000d4, 0x00000303, 0x00001ed4, 0x00000002, 0x000000d4, 0x00000309, 0x00001e4c, 0x00000002, 0x000000d5, 0x00000301, 0x0000022c, 0x00000002, 0x000000d5, 0x00000304, 0x00001e4e, 0x00000002, 0x000000d5, 0x00000308, 0x0000022a, 0x00000002, 0x000000d6, 0x00000304, 0x000001fe, 0x00000002, 0x000000d8, 0x00000301, 0x000001db, 0x00000002, 0x000000dc, 0x00000300, 0x000001d7, 0x00000002, 0x000000dc, 0x00000301, 0x000001d5, 0x00000002, 0x000000dc, 0x00000304, 0x000001d9, 0x00000002, 0x000000dc, 0x0000030c, 0x00001ea7, 0x00000002, 0x000000e2, 0x00000300, 0x00001ea5, 0x00000002, 0x000000e2, 0x00000301, 0x00001eab, 0x00000002, 0x000000e2, 0x00000303, 0x00001ea9, 0x00000002, 0x000000e2, 0x00000309, 0x000001df, 0x00000002, 0x000000e4, 0x00000304, 0x000001fb, 0x00000002, 0x000000e5, 0x00000301, 0x000001fd, 0x00000002, 0x000000e6, 0x00000301, 0x000001e3, 0x00000002, 0x000000e6, 0x00000304, 0x00001e09, 0x00000002, 0x000000e7, 0x00000301, 0x00001ec1, 0x00000002, 0x000000ea, 0x00000300, 0x00001ebf, 0x00000002, 0x000000ea, 0x00000301, 0x00001ec5, 0x00000002, 0x000000ea, 0x00000303, 0x00001ec3, 0x00000002, 0x000000ea, 0x00000309, 0x00001e2f, 0x00000002, 0x000000ef, 0x00000301, 0x00001ed3, 0x00000002, 0x000000f4, 0x00000300, 0x00001ed1, 0x00000002, 0x000000f4, 0x00000301, 0x00001ed7, 0x00000002, 0x000000f4, 0x00000303, 0x00001ed5, 0x00000002, 0x000000f4, 0x00000309, 0x00001e4d, 0x00000002, 0x000000f5, 0x00000301, 0x0000022d, 0x00000002, 0x000000f5, 0x00000304, 0x00001e4f, 0x00000002, 0x000000f5, 0x00000308, 0x0000022b, 0x00000002, 0x000000f6, 0x00000304, 0x000001ff, 0x00000002, 0x000000f8, 0x00000301, 0x000001dc, 0x00000002, 0x000000fc, 0x00000300, 0x000001d8, 0x00000002, 0x000000fc, 0x00000301, 0x000001d6, 0x00000002, 0x000000fc, 0x00000304, 0x000001da, 0x00000002, 0x000000fc, 0x0000030c, 0x00001eb0, 0x00000002, 0x00000102, 0x00000300, 0x00001eae, 0x00000002, 0x00000102, 0x00000301, 0x00001eb4, 0x00000002, 0x00000102, 0x00000303, 0x00001eb2, 0x00000002, 0x00000102, 0x00000309, 0x00001eb1, 0x00000002, 0x00000103, 0x00000300, 0x00001eaf, 0x00000002, 0x00000103, 0x00000301, 0x00001eb5, 0x00000002, 0x00000103, 0x00000303, 0x00001eb3, 0x00000002, 0x00000103, 0x00000309, 0x00001e14, 0x00000002, 0x00000112, 0x00000300, 0x00001e16, 0x00000002, 0x00000112, 0x00000301, 0x00001e15, 0x00000002, 0x00000113, 0x00000300, 0x00001e17, 0x00000002, 0x00000113, 0x00000301, 0x00001e50, 0x00000002, 0x0000014c, 0x00000300, 0x00001e52, 0x00000002, 0x0000014c, 0x00000301, 0x00001e51, 0x00000002, 0x0000014d, 0x00000300, 0x00001e53, 0x00000002, 0x0000014d, 0x00000301, 0x00001e64, 0x00000002, 0x0000015a, 0x00000307, 0x00001e65, 0x00000002, 0x0000015b, 0x00000307, 0x00001e66, 0x00000002, 0x00000160, 0x00000307, 0x00001e67, 0x00000002, 0x00000161, 0x00000307, 0x00001e78, 0x00000002, 0x00000168, 0x00000301, 0x00001e79, 0x00000002, 0x00000169, 0x00000301, 0x00001e7a, 0x00000002, 0x0000016a, 0x00000308, 0x00001e7b, 0x00000002, 0x0000016b, 0x00000308, 0x00001e9b, 0x00000002, 0x0000017f, 0x00000307, 0x00001edc, 0x00000002, 0x000001a0, 0x00000300, 0x00001eda, 0x00000002, 0x000001a0, 0x00000301, 0x00001ee0, 0x00000002, 0x000001a0, 0x00000303, 0x00001ede, 0x00000002, 0x000001a0, 0x00000309, 0x00001ee2, 0x00000002, 0x000001a0, 0x00000323, 0x00001edd, 0x00000002, 0x000001a1, 0x00000300, 0x00001edb, 0x00000002, 0x000001a1, 0x00000301, 0x00001ee1, 0x00000002, 0x000001a1, 0x00000303, 0x00001edf, 0x00000002, 0x000001a1, 0x00000309, 0x00001ee3, 0x00000002, 0x000001a1, 0x00000323, 0x00001eea, 0x00000002, 0x000001af, 0x00000300, 0x00001ee8, 0x00000002, 0x000001af, 0x00000301, 0x00001eee, 0x00000002, 0x000001af, 0x00000303, 0x00001eec, 0x00000002, 0x000001af, 0x00000309, 0x00001ef0, 0x00000002, 0x000001af, 0x00000323, 0x00001eeb, 0x00000002, 0x000001b0, 0x00000300, 0x00001ee9, 0x00000002, 0x000001b0, 0x00000301, 0x00001eef, 0x00000002, 0x000001b0, 0x00000303, 0x00001eed, 0x00000002, 0x000001b0, 0x00000309, 0x00001ef1, 0x00000002, 0x000001b0, 0x00000323, 0x000001ee, 0x00000002, 0x000001b7, 0x0000030c, 0x000001ec, 0x00000002, 0x000001ea, 0x00000304, 0x000001ed, 0x00000002, 0x000001eb, 0x00000304, 0x000001e0, 0x00000002, 0x00000226, 0x00000304, 0x000001e1, 0x00000002, 0x00000227, 0x00000304, 0x00001e1c, 0x00000002, 0x00000228, 0x00000306, 0x00001e1d, 0x00000002, 0x00000229, 0x00000306, 0x00000230, 0x00000002, 0x0000022e, 0x00000304, 0x00000231, 0x00000002, 0x0000022f, 0x00000304, 0x000001ef, 0x00000002, 0x00000292, 0x0000030c, 0x00000344, 0x00000002, 0x00000308, 0x00000301, 0x00001fba, 0x00000002, 0x00000391, 0x00000300, 0x00000386, 0x00000002, 0x00000391, 0x00000301, 0x00001fb9, 0x00000002, 0x00000391, 0x00000304, 0x00001fb8, 0x00000002, 0x00000391, 0x00000306, 0x00001f08, 0x00000002, 0x00000391, 0x00000313, 0x00001f09, 0x00000002, 0x00000391, 0x00000314, 0x00001fbc, 0x00000002, 0x00000391, 0x00000345, 0x00001fc8, 0x00000002, 0x00000395, 0x00000300, 0x00000388, 0x00000002, 0x00000395, 0x00000301, 0x00001f18, 0x00000002, 0x00000395, 0x00000313, 0x00001f19, 0x00000002, 0x00000395, 0x00000314, 0x00001fca, 0x00000002, 0x00000397, 0x00000300, 0x00000389, 0x00000002, 0x00000397, 0x00000301, 0x00001f28, 0x00000002, 0x00000397, 0x00000313, 0x00001f29, 0x00000002, 0x00000397, 0x00000314, 0x00001fcc, 0x00000002, 0x00000397, 0x00000345, 0x00001fda, 0x00000002, 0x00000399, 0x00000300, 0x0000038a, 0x00000002, 0x00000399, 0x00000301, 0x00001fd9, 0x00000002, 0x00000399, 0x00000304, 0x00001fd8, 0x00000002, 0x00000399, 0x00000306, 0x000003aa, 0x00000002, 0x00000399, 0x00000308, 0x00001f38, 0x00000002, 0x00000399, 0x00000313, 0x00001f39, 0x00000002, 0x00000399, 0x00000314, 0x00001ff8, 0x00000002, 0x0000039f, 0x00000300, 0x0000038c, 0x00000002, 0x0000039f, 0x00000301, 0x00001f48, 0x00000002, 0x0000039f, 0x00000313, 0x00001f49, 0x00000002, 0x0000039f, 0x00000314, 0x00001fec, 0x00000002, 0x000003a1, 0x00000314, 0x00001fea, 0x00000002, 0x000003a5, 0x00000300, 0x0000038e, 0x00000002, 0x000003a5, 0x00000301, 0x00001fe9, 0x00000002, 0x000003a5, 0x00000304, 0x00001fe8, 0x00000002, 0x000003a5, 0x00000306, 0x000003ab, 0x00000002, 0x000003a5, 0x00000308, 0x00001f59, 0x00000002, 0x000003a5, 0x00000314, 0x00001ffa, 0x00000002, 0x000003a9, 0x00000300, 0x0000038f, 0x00000002, 0x000003a9, 0x00000301, 0x00001f68, 0x00000002, 0x000003a9, 0x00000313, 0x00001f69, 0x00000002, 0x000003a9, 0x00000314, 0x00001ffc, 0x00000002, 0x000003a9, 0x00000345, 0x00001fb4, 0x00000002, 0x000003ac, 0x00000345, 0x00001fc4, 0x00000002, 0x000003ae, 0x00000345, 0x00001f70, 0x00000002, 0x000003b1, 0x00000300, 0x000003ac, 0x00000002, 0x000003b1, 0x00000301, 0x00001fb1, 0x00000002, 0x000003b1, 0x00000304, 0x00001fb0, 0x00000002, 0x000003b1, 0x00000306, 0x00001f00, 0x00000002, 0x000003b1, 0x00000313, 0x00001f01, 0x00000002, 0x000003b1, 0x00000314, 0x00001fb6, 0x00000002, 0x000003b1, 0x00000342, 0x00001fb3, 0x00000002, 0x000003b1, 0x00000345, 0x00001f72, 0x00000002, 0x000003b5, 0x00000300, 0x000003ad, 0x00000002, 0x000003b5, 0x00000301, 0x00001f10, 0x00000002, 0x000003b5, 0x00000313, 0x00001f11, 0x00000002, 0x000003b5, 0x00000314, 0x00001f74, 0x00000002, 0x000003b7, 0x00000300, 0x000003ae, 0x00000002, 0x000003b7, 0x00000301, 0x00001f20, 0x00000002, 0x000003b7, 0x00000313, 0x00001f21, 0x00000002, 0x000003b7, 0x00000314, 0x00001fc6, 0x00000002, 0x000003b7, 0x00000342, 0x00001fc3, 0x00000002, 0x000003b7, 0x00000345, 0x00001f76, 0x00000002, 0x000003b9, 0x00000300, 0x000003af, 0x00000002, 0x000003b9, 0x00000301, 0x00001fd1, 0x00000002, 0x000003b9, 0x00000304, 0x00001fd0, 0x00000002, 0x000003b9, 0x00000306, 0x000003ca, 0x00000002, 0x000003b9, 0x00000308, 0x00001f30, 0x00000002, 0x000003b9, 0x00000313, 0x00001f31, 0x00000002, 0x000003b9, 0x00000314, 0x00001fd6, 0x00000002, 0x000003b9, 0x00000342, 0x00001f78, 0x00000002, 0x000003bf, 0x00000300, 0x000003cc, 0x00000002, 0x000003bf, 0x00000301, 0x00001f40, 0x00000002, 0x000003bf, 0x00000313, 0x00001f41, 0x00000002, 0x000003bf, 0x00000314, 0x00001fe4, 0x00000002, 0x000003c1, 0x00000313, 0x00001fe5, 0x00000002, 0x000003c1, 0x00000314, 0x00001f7a, 0x00000002, 0x000003c5, 0x00000300, 0x000003cd, 0x00000002, 0x000003c5, 0x00000301, 0x00001fe1, 0x00000002, 0x000003c5, 0x00000304, 0x00001fe0, 0x00000002, 0x000003c5, 0x00000306, 0x000003cb, 0x00000002, 0x000003c5, 0x00000308, 0x00001f50, 0x00000002, 0x000003c5, 0x00000313, 0x00001f51, 0x00000002, 0x000003c5, 0x00000314, 0x00001fe6, 0x00000002, 0x000003c5, 0x00000342, 0x00001f7c, 0x00000002, 0x000003c9, 0x00000300, 0x000003ce, 0x00000002, 0x000003c9, 0x00000301, 0x00001f60, 0x00000002, 0x000003c9, 0x00000313, 0x00001f61, 0x00000002, 0x000003c9, 0x00000314, 0x00001ff6, 0x00000002, 0x000003c9, 0x00000342, 0x00001ff3, 0x00000002, 0x000003c9, 0x00000345, 0x00001fd2, 0x00000002, 0x000003ca, 0x00000300, 0x00000390, 0x00000002, 0x000003ca, 0x00000301, 0x00001fd7, 0x00000002, 0x000003ca, 0x00000342, 0x00001fe2, 0x00000002, 0x000003cb, 0x00000300, 0x000003b0, 0x00000002, 0x000003cb, 0x00000301, 0x00001fe7, 0x00000002, 0x000003cb, 0x00000342, 0x00001ff4, 0x00000002, 0x000003ce, 0x00000345, 0x000003d3, 0x00000002, 0x000003d2, 0x00000301, 0x000003d4, 0x00000002, 0x000003d2, 0x00000308, 0x00000407, 0x00000002, 0x00000406, 0x00000308, 0x000004d0, 0x00000002, 0x00000410, 0x00000306, 0x000004d2, 0x00000002, 0x00000410, 0x00000308, 0x00000403, 0x00000002, 0x00000413, 0x00000301, 0x00000400, 0x00000002, 0x00000415, 0x00000300, 0x000004d6, 0x00000002, 0x00000415, 0x00000306, 0x00000401, 0x00000002, 0x00000415, 0x00000308, 0x000004c1, 0x00000002, 0x00000416, 0x00000306, 0x000004dc, 0x00000002, 0x00000416, 0x00000308, 0x000004de, 0x00000002, 0x00000417, 0x00000308, 0x0000040d, 0x00000002, 0x00000418, 0x00000300, 0x000004e2, 0x00000002, 0x00000418, 0x00000304, 0x00000419, 0x00000002, 0x00000418, 0x00000306, 0x000004e4, 0x00000002, 0x00000418, 0x00000308, 0x0000040c, 0x00000002, 0x0000041a, 0x00000301, 0x000004e6, 0x00000002, 0x0000041e, 0x00000308, 0x000004ee, 0x00000002, 0x00000423, 0x00000304, 0x0000040e, 0x00000002, 0x00000423, 0x00000306, 0x000004f0, 0x00000002, 0x00000423, 0x00000308, 0x000004f2, 0x00000002, 0x00000423, 0x0000030b, 0x000004f4, 0x00000002, 0x00000427, 0x00000308, 0x000004f8, 0x00000002, 0x0000042b, 0x00000308, 0x000004ec, 0x00000002, 0x0000042d, 0x00000308, 0x000004d1, 0x00000002, 0x00000430, 0x00000306, 0x000004d3, 0x00000002, 0x00000430, 0x00000308, 0x00000453, 0x00000002, 0x00000433, 0x00000301, 0x00000450, 0x00000002, 0x00000435, 0x00000300, 0x000004d7, 0x00000002, 0x00000435, 0x00000306, 0x00000451, 0x00000002, 0x00000435, 0x00000308, 0x000004c2, 0x00000002, 0x00000436, 0x00000306, 0x000004dd, 0x00000002, 0x00000436, 0x00000308, 0x000004df, 0x00000002, 0x00000437, 0x00000308, 0x0000045d, 0x00000002, 0x00000438, 0x00000300, 0x000004e3, 0x00000002, 0x00000438, 0x00000304, 0x00000439, 0x00000002, 0x00000438, 0x00000306, 0x000004e5, 0x00000002, 0x00000438, 0x00000308, 0x0000045c, 0x00000002, 0x0000043a, 0x00000301, 0x000004e7, 0x00000002, 0x0000043e, 0x00000308, 0x000004ef, 0x00000002, 0x00000443, 0x00000304, 0x0000045e, 0x00000002, 0x00000443, 0x00000306, 0x000004f1, 0x00000002, 0x00000443, 0x00000308, 0x000004f3, 0x00000002, 0x00000443, 0x0000030b, 0x000004f5, 0x00000002, 0x00000447, 0x00000308, 0x000004f9, 0x00000002, 0x0000044b, 0x00000308, 0x000004ed, 0x00000002, 0x0000044d, 0x00000308, 0x00000457, 0x00000002, 0x00000456, 0x00000308, 0x00000476, 0x00000002, 0x00000474, 0x0000030f, 0x00000477, 0x00000002, 0x00000475, 0x0000030f, 0x000004da, 0x00000002, 0x000004d8, 0x00000308, 0x000004db, 0x00000002, 0x000004d9, 0x00000308, 0x000004ea, 0x00000002, 0x000004e8, 0x00000308, 0x000004eb, 0x00000002, 0x000004e9, 0x00000308, 0x00000622, 0x00000002, 0x00000627, 0x00000653, 0x00000623, 0x00000002, 0x00000627, 0x00000654, 0x00000625, 0x00000002, 0x00000627, 0x00000655, 0x00000624, 0x00000002, 0x00000648, 0x00000654, 0x00000626, 0x00000002, 0x0000064a, 0x00000654, 0x000006c2, 0x00000002, 0x000006c1, 0x00000654, 0x000006d3, 0x00000002, 0x000006d2, 0x00000654, 0x000006c0, 0x00000002, 0x000006d5, 0x00000654, 0x00000929, 0x00000002, 0x00000928, 0x0000093c, 0x00000931, 0x00000002, 0x00000930, 0x0000093c, 0x00000934, 0x00000002, 0x00000933, 0x0000093c, 0x000009cb, 0x00000002, 0x000009c7, 0x000009be, 0x000009cc, 0x00000002, 0x000009c7, 0x000009d7, 0x00000b4b, 0x00000002, 0x00000b47, 0x00000b3e, 0x00000b48, 0x00000002, 0x00000b47, 0x00000b56, 0x00000b4c, 0x00000002, 0x00000b47, 0x00000b57, 0x00000b94, 0x00000002, 0x00000b92, 0x00000bd7, 0x00000bca, 0x00000002, 0x00000bc6, 0x00000bbe, 0x00000bcc, 0x00000002, 0x00000bc6, 0x00000bd7, 0x00000bcb, 0x00000002, 0x00000bc7, 0x00000bbe, 0x00000c48, 0x00000002, 0x00000c46, 0x00000c56, 0x00000cc0, 0x00000002, 0x00000cbf, 0x00000cd5, 0x00000cca, 0x00000002, 0x00000cc6, 0x00000cc2, 0x00000cc7, 0x00000002, 0x00000cc6, 0x00000cd5, 0x00000cc8, 0x00000002, 0x00000cc6, 0x00000cd6, 0x00000ccb, 0x00000002, 0x00000cca, 0x00000cd5, 0x00000d4a, 0x00000002, 0x00000d46, 0x00000d3e, 0x00000d4c, 0x00000002, 0x00000d46, 0x00000d57, 0x00000d4b, 0x00000002, 0x00000d47, 0x00000d3e, 0x00000dda, 0x00000002, 0x00000dd9, 0x00000dca, 0x00000ddc, 0x00000002, 0x00000dd9, 0x00000dcf, 0x00000dde, 0x00000002, 0x00000dd9, 0x00000ddf, 0x00000ddd, 0x00000002, 0x00000ddc, 0x00000dca, 0x00000f73, 0x00000002, 0x00000f71, 0x00000f72, 0x00000f75, 0x00000002, 0x00000f71, 0x00000f74, 0x00000f81, 0x00000002, 0x00000f71, 0x00000f80, 0x00001026, 0x00000002, 0x00001025, 0x0000102e, 0x00001e38, 0x00000002, 0x00001e36, 0x00000304, 0x00001e39, 0x00000002, 0x00001e37, 0x00000304, 0x00001e5c, 0x00000002, 0x00001e5a, 0x00000304, 0x00001e5d, 0x00000002, 0x00001e5b, 0x00000304, 0x00001e68, 0x00000002, 0x00001e62, 0x00000307, 0x00001e69, 0x00000002, 0x00001e63, 0x00000307, 0x00001eac, 0x00000002, 0x00001ea0, 0x00000302, 0x00001eb6, 0x00000002, 0x00001ea0, 0x00000306, 0x00001ead, 0x00000002, 0x00001ea1, 0x00000302, 0x00001eb7, 0x00000002, 0x00001ea1, 0x00000306, 0x00001ec6, 0x00000002, 0x00001eb8, 0x00000302, 0x00001ec7, 0x00000002, 0x00001eb9, 0x00000302, 0x00001ed8, 0x00000002, 0x00001ecc, 0x00000302, 0x00001ed9, 0x00000002, 0x00001ecd, 0x00000302, 0x00001f02, 0x00000002, 0x00001f00, 0x00000300, 0x00001f04, 0x00000002, 0x00001f00, 0x00000301, 0x00001f06, 0x00000002, 0x00001f00, 0x00000342, 0x00001f80, 0x00000002, 0x00001f00, 0x00000345, 0x00001f03, 0x00000002, 0x00001f01, 0x00000300, 0x00001f05, 0x00000002, 0x00001f01, 0x00000301, 0x00001f07, 0x00000002, 0x00001f01, 0x00000342, 0x00001f81, 0x00000002, 0x00001f01, 0x00000345, 0x00001f82, 0x00000002, 0x00001f02, 0x00000345, 0x00001f83, 0x00000002, 0x00001f03, 0x00000345, 0x00001f84, 0x00000002, 0x00001f04, 0x00000345, 0x00001f85, 0x00000002, 0x00001f05, 0x00000345, 0x00001f86, 0x00000002, 0x00001f06, 0x00000345, 0x00001f87, 0x00000002, 0x00001f07, 0x00000345, 0x00001f0a, 0x00000002, 0x00001f08, 0x00000300, 0x00001f0c, 0x00000002, 0x00001f08, 0x00000301, 0x00001f0e, 0x00000002, 0x00001f08, 0x00000342, 0x00001f88, 0x00000002, 0x00001f08, 0x00000345, 0x00001f0b, 0x00000002, 0x00001f09, 0x00000300, 0x00001f0d, 0x00000002, 0x00001f09, 0x00000301, 0x00001f0f, 0x00000002, 0x00001f09, 0x00000342, 0x00001f89, 0x00000002, 0x00001f09, 0x00000345, 0x00001f8a, 0x00000002, 0x00001f0a, 0x00000345, 0x00001f8b, 0x00000002, 0x00001f0b, 0x00000345, 0x00001f8c, 0x00000002, 0x00001f0c, 0x00000345, 0x00001f8d, 0x00000002, 0x00001f0d, 0x00000345, 0x00001f8e, 0x00000002, 0x00001f0e, 0x00000345, 0x00001f8f, 0x00000002, 0x00001f0f, 0x00000345, 0x00001f12, 0x00000002, 0x00001f10, 0x00000300, 0x00001f14, 0x00000002, 0x00001f10, 0x00000301, 0x00001f13, 0x00000002, 0x00001f11, 0x00000300, 0x00001f15, 0x00000002, 0x00001f11, 0x00000301, 0x00001f1a, 0x00000002, 0x00001f18, 0x00000300, 0x00001f1c, 0x00000002, 0x00001f18, 0x00000301, 0x00001f1b, 0x00000002, 0x00001f19, 0x00000300, 0x00001f1d, 0x00000002, 0x00001f19, 0x00000301, 0x00001f22, 0x00000002, 0x00001f20, 0x00000300, 0x00001f24, 0x00000002, 0x00001f20, 0x00000301, 0x00001f26, 0x00000002, 0x00001f20, 0x00000342, 0x00001f90, 0x00000002, 0x00001f20, 0x00000345, 0x00001f23, 0x00000002, 0x00001f21, 0x00000300, 0x00001f25, 0x00000002, 0x00001f21, 0x00000301, 0x00001f27, 0x00000002, 0x00001f21, 0x00000342, 0x00001f91, 0x00000002, 0x00001f21, 0x00000345, 0x00001f92, 0x00000002, 0x00001f22, 0x00000345, 0x00001f93, 0x00000002, 0x00001f23, 0x00000345, 0x00001f94, 0x00000002, 0x00001f24, 0x00000345, 0x00001f95, 0x00000002, 0x00001f25, 0x00000345, 0x00001f96, 0x00000002, 0x00001f26, 0x00000345, 0x00001f97, 0x00000002, 0x00001f27, 0x00000345, 0x00001f2a, 0x00000002, 0x00001f28, 0x00000300, 0x00001f2c, 0x00000002, 0x00001f28, 0x00000301, 0x00001f2e, 0x00000002, 0x00001f28, 0x00000342, 0x00001f98, 0x00000002, 0x00001f28, 0x00000345, 0x00001f2b, 0x00000002, 0x00001f29, 0x00000300, 0x00001f2d, 0x00000002, 0x00001f29, 0x00000301, 0x00001f2f, 0x00000002, 0x00001f29, 0x00000342, 0x00001f99, 0x00000002, 0x00001f29, 0x00000345, 0x00001f9a, 0x00000002, 0x00001f2a, 0x00000345, 0x00001f9b, 0x00000002, 0x00001f2b, 0x00000345, 0x00001f9c, 0x00000002, 0x00001f2c, 0x00000345, 0x00001f9d, 0x00000002, 0x00001f2d, 0x00000345, 0x00001f9e, 0x00000002, 0x00001f2e, 0x00000345, 0x00001f9f, 0x00000002, 0x00001f2f, 0x00000345, 0x00001f32, 0x00000002, 0x00001f30, 0x00000300, 0x00001f34, 0x00000002, 0x00001f30, 0x00000301, 0x00001f36, 0x00000002, 0x00001f30, 0x00000342, 0x00001f33, 0x00000002, 0x00001f31, 0x00000300, 0x00001f35, 0x00000002, 0x00001f31, 0x00000301, 0x00001f37, 0x00000002, 0x00001f31, 0x00000342, 0x00001f3a, 0x00000002, 0x00001f38, 0x00000300, 0x00001f3c, 0x00000002, 0x00001f38, 0x00000301, 0x00001f3e, 0x00000002, 0x00001f38, 0x00000342, 0x00001f3b, 0x00000002, 0x00001f39, 0x00000300, 0x00001f3d, 0x00000002, 0x00001f39, 0x00000301, 0x00001f3f, 0x00000002, 0x00001f39, 0x00000342, 0x00001f42, 0x00000002, 0x00001f40, 0x00000300, 0x00001f44, 0x00000002, 0x00001f40, 0x00000301, 0x00001f43, 0x00000002, 0x00001f41, 0x00000300, 0x00001f45, 0x00000002, 0x00001f41, 0x00000301, 0x00001f4a, 0x00000002, 0x00001f48, 0x00000300, 0x00001f4c, 0x00000002, 0x00001f48, 0x00000301, 0x00001f4b, 0x00000002, 0x00001f49, 0x00000300, 0x00001f4d, 0x00000002, 0x00001f49, 0x00000301, 0x00001f52, 0x00000002, 0x00001f50, 0x00000300, 0x00001f54, 0x00000002, 0x00001f50, 0x00000301, 0x00001f56, 0x00000002, 0x00001f50, 0x00000342, 0x00001f53, 0x00000002, 0x00001f51, 0x00000300, 0x00001f55, 0x00000002, 0x00001f51, 0x00000301, 0x00001f57, 0x00000002, 0x00001f51, 0x00000342, 0x00001f5b, 0x00000002, 0x00001f59, 0x00000300, 0x00001f5d, 0x00000002, 0x00001f59, 0x00000301, 0x00001f5f, 0x00000002, 0x00001f59, 0x00000342, 0x00001f62, 0x00000002, 0x00001f60, 0x00000300, 0x00001f64, 0x00000002, 0x00001f60, 0x00000301, 0x00001f66, 0x00000002, 0x00001f60, 0x00000342, 0x00001fa0, 0x00000002, 0x00001f60, 0x00000345, 0x00001f63, 0x00000002, 0x00001f61, 0x00000300, 0x00001f65, 0x00000002, 0x00001f61, 0x00000301, 0x00001f67, 0x00000002, 0x00001f61, 0x00000342, 0x00001fa1, 0x00000002, 0x00001f61, 0x00000345, 0x00001fa2, 0x00000002, 0x00001f62, 0x00000345, 0x00001fa3, 0x00000002, 0x00001f63, 0x00000345, 0x00001fa4, 0x00000002, 0x00001f64, 0x00000345, 0x00001fa5, 0x00000002, 0x00001f65, 0x00000345, 0x00001fa6, 0x00000002, 0x00001f66, 0x00000345, 0x00001fa7, 0x00000002, 0x00001f67, 0x00000345, 0x00001f6a, 0x00000002, 0x00001f68, 0x00000300, 0x00001f6c, 0x00000002, 0x00001f68, 0x00000301, 0x00001f6e, 0x00000002, 0x00001f68, 0x00000342, 0x00001fa8, 0x00000002, 0x00001f68, 0x00000345, 0x00001f6b, 0x00000002, 0x00001f69, 0x00000300, 0x00001f6d, 0x00000002, 0x00001f69, 0x00000301, 0x00001f6f, 0x00000002, 0x00001f69, 0x00000342, 0x00001fa9, 0x00000002, 0x00001f69, 0x00000345, 0x00001faa, 0x00000002, 0x00001f6a, 0x00000345, 0x00001fab, 0x00000002, 0x00001f6b, 0x00000345, 0x00001fac, 0x00000002, 0x00001f6c, 0x00000345, 0x00001fad, 0x00000002, 0x00001f6d, 0x00000345, 0x00001fae, 0x00000002, 0x00001f6e, 0x00000345, 0x00001faf, 0x00000002, 0x00001f6f, 0x00000345, 0x00001fb2, 0x00000002, 0x00001f70, 0x00000345, 0x00001fc2, 0x00000002, 0x00001f74, 0x00000345, 0x00001ff2, 0x00000002, 0x00001f7c, 0x00000345, 0x00001fb7, 0x00000002, 0x00001fb6, 0x00000345, 0x00001fcd, 0x00000002, 0x00001fbf, 0x00000300, 0x00001fce, 0x00000002, 0x00001fbf, 0x00000301, 0x00001fcf, 0x00000002, 0x00001fbf, 0x00000342, 0x00001fc7, 0x00000002, 0x00001fc6, 0x00000345, 0x00001ff7, 0x00000002, 0x00001ff6, 0x00000345, 0x00001fdd, 0x00000002, 0x00001ffe, 0x00000300, 0x00001fde, 0x00000002, 0x00001ffe, 0x00000301, 0x00001fdf, 0x00000002, 0x00001ffe, 0x00000342, 0x0000219a, 0x00000002, 0x00002190, 0x00000338, 0x0000219b, 0x00000002, 0x00002192, 0x00000338, 0x000021ae, 0x00000002, 0x00002194, 0x00000338, 0x000021cd, 0x00000002, 0x000021d0, 0x00000338, 0x000021cf, 0x00000002, 0x000021d2, 0x00000338, 0x000021ce, 0x00000002, 0x000021d4, 0x00000338, 0x00002204, 0x00000002, 0x00002203, 0x00000338, 0x00002209, 0x00000002, 0x00002208, 0x00000338, 0x0000220c, 0x00000002, 0x0000220b, 0x00000338, 0x00002224, 0x00000002, 0x00002223, 0x00000338, 0x00002226, 0x00000002, 0x00002225, 0x00000338, 0x00002241, 0x00000002, 0x0000223c, 0x00000338, 0x00002244, 0x00000002, 0x00002243, 0x00000338, 0x00002247, 0x00000002, 0x00002245, 0x00000338, 0x00002249, 0x00000002, 0x00002248, 0x00000338, 0x0000226d, 0x00000002, 0x0000224d, 0x00000338, 0x00002262, 0x00000002, 0x00002261, 0x00000338, 0x00002270, 0x00000002, 0x00002264, 0x00000338, 0x00002271, 0x00000002, 0x00002265, 0x00000338, 0x00002274, 0x00000002, 0x00002272, 0x00000338, 0x00002275, 0x00000002, 0x00002273, 0x00000338, 0x00002278, 0x00000002, 0x00002276, 0x00000338, 0x00002279, 0x00000002, 0x00002277, 0x00000338, 0x00002280, 0x00000002, 0x0000227a, 0x00000338, 0x00002281, 0x00000002, 0x0000227b, 0x00000338, 0x000022e0, 0x00000002, 0x0000227c, 0x00000338, 0x000022e1, 0x00000002, 0x0000227d, 0x00000338, 0x00002284, 0x00000002, 0x00002282, 0x00000338, 0x00002285, 0x00000002, 0x00002283, 0x00000338, 0x00002288, 0x00000002, 0x00002286, 0x00000338, 0x00002289, 0x00000002, 0x00002287, 0x00000338, 0x000022e2, 0x00000002, 0x00002291, 0x00000338, 0x000022e3, 0x00000002, 0x00002292, 0x00000338, 0x000022ac, 0x00000002, 0x000022a2, 0x00000338, 0x000022ad, 0x00000002, 0x000022a8, 0x00000338, 0x000022ae, 0x00000002, 0x000022a9, 0x00000338, 0x000022af, 0x00000002, 0x000022ab, 0x00000338, 0x000022ea, 0x00000002, 0x000022b2, 0x00000338, 0x000022eb, 0x00000002, 0x000022b3, 0x00000338, 0x000022ec, 0x00000002, 0x000022b4, 0x00000338, 0x000022ed, 0x00000002, 0x000022b5, 0x00000338, 0x00003094, 0x00000002, 0x00003046, 0x00003099, 0x0000304c, 0x00000002, 0x0000304b, 0x00003099, 0x0000304e, 0x00000002, 0x0000304d, 0x00003099, 0x00003050, 0x00000002, 0x0000304f, 0x00003099, 0x00003052, 0x00000002, 0x00003051, 0x00003099, 0x00003054, 0x00000002, 0x00003053, 0x00003099, 0x00003056, 0x00000002, 0x00003055, 0x00003099, 0x00003058, 0x00000002, 0x00003057, 0x00003099, 0x0000305a, 0x00000002, 0x00003059, 0x00003099, 0x0000305c, 0x00000002, 0x0000305b, 0x00003099, 0x0000305e, 0x00000002, 0x0000305d, 0x00003099, 0x00003060, 0x00000002, 0x0000305f, 0x00003099, 0x00003062, 0x00000002, 0x00003061, 0x00003099, 0x00003065, 0x00000002, 0x00003064, 0x00003099, 0x00003067, 0x00000002, 0x00003066, 0x00003099, 0x00003069, 0x00000002, 0x00003068, 0x00003099, 0x00003070, 0x00000002, 0x0000306f, 0x00003099, 0x00003071, 0x00000002, 0x0000306f, 0x0000309a, 0x00003073, 0x00000002, 0x00003072, 0x00003099, 0x00003074, 0x00000002, 0x00003072, 0x0000309a, 0x00003076, 0x00000002, 0x00003075, 0x00003099, 0x00003077, 0x00000002, 0x00003075, 0x0000309a, 0x00003079, 0x00000002, 0x00003078, 0x00003099, 0x0000307a, 0x00000002, 0x00003078, 0x0000309a, 0x0000307c, 0x00000002, 0x0000307b, 0x00003099, 0x0000307d, 0x00000002, 0x0000307b, 0x0000309a, 0x0000309e, 0x00000002, 0x0000309d, 0x00003099, 0x000030f4, 0x00000002, 0x000030a6, 0x00003099, 0x000030ac, 0x00000002, 0x000030ab, 0x00003099, 0x000030ae, 0x00000002, 0x000030ad, 0x00003099, 0x000030b0, 0x00000002, 0x000030af, 0x00003099, 0x000030b2, 0x00000002, 0x000030b1, 0x00003099, 0x000030b4, 0x00000002, 0x000030b3, 0x00003099, 0x000030b6, 0x00000002, 0x000030b5, 0x00003099, 0x000030b8, 0x00000002, 0x000030b7, 0x00003099, 0x000030ba, 0x00000002, 0x000030b9, 0x00003099, 0x000030bc, 0x00000002, 0x000030bb, 0x00003099, 0x000030be, 0x00000002, 0x000030bd, 0x00003099, 0x000030c0, 0x00000002, 0x000030bf, 0x00003099, 0x000030c2, 0x00000002, 0x000030c1, 0x00003099, 0x000030c5, 0x00000002, 0x000030c4, 0x00003099, 0x000030c7, 0x00000002, 0x000030c6, 0x00003099, 0x000030c9, 0x00000002, 0x000030c8, 0x00003099, 0x000030d0, 0x00000002, 0x000030cf, 0x00003099, 0x000030d1, 0x00000002, 0x000030cf, 0x0000309a, 0x000030d3, 0x00000002, 0x000030d2, 0x00003099, 0x000030d4, 0x00000002, 0x000030d2, 0x0000309a, 0x000030d6, 0x00000002, 0x000030d5, 0x00003099, 0x000030d7, 0x00000002, 0x000030d5, 0x0000309a, 0x000030d9, 0x00000002, 0x000030d8, 0x00003099, 0x000030da, 0x00000002, 0x000030d8, 0x0000309a, 0x000030dc, 0x00000002, 0x000030db, 0x00003099, 0x000030dd, 0x00000002, 0x000030db, 0x0000309a, 0x000030f7, 0x00000002, 0x000030ef, 0x00003099, 0x000030f8, 0x00000002, 0x000030f0, 0x00003099, 0x000030f9, 0x00000002, 0x000030f1, 0x00003099, 0x000030fa, 0x00000002, 0x000030f2, 0x00003099, 0x000030fe, 0x00000002, 0x000030fd, 0x00003099 }; static const krb5_ui_4 _ucdcmp_size = 3848; static const krb5_ui_4 _ucdcmp_nodes[] = { 0x000000c0, 0x00000000, 0x000000c1, 0x00000002, 0x000000c2, 0x00000004, 0x000000c3, 0x00000006, 0x000000c4, 0x00000008, 0x000000c5, 0x0000000a, 0x000000c7, 0x0000000c, 0x000000c8, 0x0000000e, 0x000000c9, 0x00000010, 0x000000ca, 0x00000012, 0x000000cb, 0x00000014, 0x000000cc, 0x00000016, 0x000000cd, 0x00000018, 0x000000ce, 0x0000001a, 0x000000cf, 0x0000001c, 0x000000d1, 0x0000001e, 0x000000d2, 0x00000020, 0x000000d3, 0x00000022, 0x000000d4, 0x00000024, 0x000000d5, 0x00000026, 0x000000d6, 0x00000028, 0x000000d9, 0x0000002a, 0x000000da, 0x0000002c, 0x000000db, 0x0000002e, 0x000000dc, 0x00000030, 0x000000dd, 0x00000032, 0x000000e0, 0x00000034, 0x000000e1, 0x00000036, 0x000000e2, 0x00000038, 0x000000e3, 0x0000003a, 0x000000e4, 0x0000003c, 0x000000e5, 0x0000003e, 0x000000e7, 0x00000040, 0x000000e8, 0x00000042, 0x000000e9, 0x00000044, 0x000000ea, 0x00000046, 0x000000eb, 0x00000048, 0x000000ec, 0x0000004a, 0x000000ed, 0x0000004c, 0x000000ee, 0x0000004e, 0x000000ef, 0x00000050, 0x000000f1, 0x00000052, 0x000000f2, 0x00000054, 0x000000f3, 0x00000056, 0x000000f4, 0x00000058, 0x000000f5, 0x0000005a, 0x000000f6, 0x0000005c, 0x000000f9, 0x0000005e, 0x000000fa, 0x00000060, 0x000000fb, 0x00000062, 0x000000fc, 0x00000064, 0x000000fd, 0x00000066, 0x000000ff, 0x00000068, 0x00000100, 0x0000006a, 0x00000101, 0x0000006c, 0x00000102, 0x0000006e, 0x00000103, 0x00000070, 0x00000104, 0x00000072, 0x00000105, 0x00000074, 0x00000106, 0x00000076, 0x00000107, 0x00000078, 0x00000108, 0x0000007a, 0x00000109, 0x0000007c, 0x0000010a, 0x0000007e, 0x0000010b, 0x00000080, 0x0000010c, 0x00000082, 0x0000010d, 0x00000084, 0x0000010e, 0x00000086, 0x0000010f, 0x00000088, 0x00000112, 0x0000008a, 0x00000113, 0x0000008c, 0x00000114, 0x0000008e, 0x00000115, 0x00000090, 0x00000116, 0x00000092, 0x00000117, 0x00000094, 0x00000118, 0x00000096, 0x00000119, 0x00000098, 0x0000011a, 0x0000009a, 0x0000011b, 0x0000009c, 0x0000011c, 0x0000009e, 0x0000011d, 0x000000a0, 0x0000011e, 0x000000a2, 0x0000011f, 0x000000a4, 0x00000120, 0x000000a6, 0x00000121, 0x000000a8, 0x00000122, 0x000000aa, 0x00000123, 0x000000ac, 0x00000124, 0x000000ae, 0x00000125, 0x000000b0, 0x00000128, 0x000000b2, 0x00000129, 0x000000b4, 0x0000012a, 0x000000b6, 0x0000012b, 0x000000b8, 0x0000012c, 0x000000ba, 0x0000012d, 0x000000bc, 0x0000012e, 0x000000be, 0x0000012f, 0x000000c0, 0x00000130, 0x000000c2, 0x00000134, 0x000000c4, 0x00000135, 0x000000c6, 0x00000136, 0x000000c8, 0x00000137, 0x000000ca, 0x00000139, 0x000000cc, 0x0000013a, 0x000000ce, 0x0000013b, 0x000000d0, 0x0000013c, 0x000000d2, 0x0000013d, 0x000000d4, 0x0000013e, 0x000000d6, 0x00000143, 0x000000d8, 0x00000144, 0x000000da, 0x00000145, 0x000000dc, 0x00000146, 0x000000de, 0x00000147, 0x000000e0, 0x00000148, 0x000000e2, 0x0000014c, 0x000000e4, 0x0000014d, 0x000000e6, 0x0000014e, 0x000000e8, 0x0000014f, 0x000000ea, 0x00000150, 0x000000ec, 0x00000151, 0x000000ee, 0x00000154, 0x000000f0, 0x00000155, 0x000000f2, 0x00000156, 0x000000f4, 0x00000157, 0x000000f6, 0x00000158, 0x000000f8, 0x00000159, 0x000000fa, 0x0000015a, 0x000000fc, 0x0000015b, 0x000000fe, 0x0000015c, 0x00000100, 0x0000015d, 0x00000102, 0x0000015e, 0x00000104, 0x0000015f, 0x00000106, 0x00000160, 0x00000108, 0x00000161, 0x0000010a, 0x00000162, 0x0000010c, 0x00000163, 0x0000010e, 0x00000164, 0x00000110, 0x00000165, 0x00000112, 0x00000168, 0x00000114, 0x00000169, 0x00000116, 0x0000016a, 0x00000118, 0x0000016b, 0x0000011a, 0x0000016c, 0x0000011c, 0x0000016d, 0x0000011e, 0x0000016e, 0x00000120, 0x0000016f, 0x00000122, 0x00000170, 0x00000124, 0x00000171, 0x00000126, 0x00000172, 0x00000128, 0x00000173, 0x0000012a, 0x00000174, 0x0000012c, 0x00000175, 0x0000012e, 0x00000176, 0x00000130, 0x00000177, 0x00000132, 0x00000178, 0x00000134, 0x00000179, 0x00000136, 0x0000017a, 0x00000138, 0x0000017b, 0x0000013a, 0x0000017c, 0x0000013c, 0x0000017d, 0x0000013e, 0x0000017e, 0x00000140, 0x000001a0, 0x00000142, 0x000001a1, 0x00000144, 0x000001af, 0x00000146, 0x000001b0, 0x00000148, 0x000001cd, 0x0000014a, 0x000001ce, 0x0000014c, 0x000001cf, 0x0000014e, 0x000001d0, 0x00000150, 0x000001d1, 0x00000152, 0x000001d2, 0x00000154, 0x000001d3, 0x00000156, 0x000001d4, 0x00000158, 0x000001d5, 0x0000015a, 0x000001d6, 0x0000015d, 0x000001d7, 0x00000160, 0x000001d8, 0x00000163, 0x000001d9, 0x00000166, 0x000001da, 0x00000169, 0x000001db, 0x0000016c, 0x000001dc, 0x0000016f, 0x000001de, 0x00000172, 0x000001df, 0x00000175, 0x000001e0, 0x00000178, 0x000001e1, 0x0000017b, 0x000001e2, 0x0000017e, 0x000001e3, 0x00000180, 0x000001e6, 0x00000182, 0x000001e7, 0x00000184, 0x000001e8, 0x00000186, 0x000001e9, 0x00000188, 0x000001ea, 0x0000018a, 0x000001eb, 0x0000018c, 0x000001ec, 0x0000018e, 0x000001ed, 0x00000191, 0x000001ee, 0x00000194, 0x000001ef, 0x00000196, 0x000001f0, 0x00000198, 0x000001f4, 0x0000019a, 0x000001f5, 0x0000019c, 0x000001f8, 0x0000019e, 0x000001f9, 0x000001a0, 0x000001fa, 0x000001a2, 0x000001fb, 0x000001a5, 0x000001fc, 0x000001a8, 0x000001fd, 0x000001aa, 0x000001fe, 0x000001ac, 0x000001ff, 0x000001ae, 0x00000200, 0x000001b0, 0x00000201, 0x000001b2, 0x00000202, 0x000001b4, 0x00000203, 0x000001b6, 0x00000204, 0x000001b8, 0x00000205, 0x000001ba, 0x00000206, 0x000001bc, 0x00000207, 0x000001be, 0x00000208, 0x000001c0, 0x00000209, 0x000001c2, 0x0000020a, 0x000001c4, 0x0000020b, 0x000001c6, 0x0000020c, 0x000001c8, 0x0000020d, 0x000001ca, 0x0000020e, 0x000001cc, 0x0000020f, 0x000001ce, 0x00000210, 0x000001d0, 0x00000211, 0x000001d2, 0x00000212, 0x000001d4, 0x00000213, 0x000001d6, 0x00000214, 0x000001d8, 0x00000215, 0x000001da, 0x00000216, 0x000001dc, 0x00000217, 0x000001de, 0x00000218, 0x000001e0, 0x00000219, 0x000001e2, 0x0000021a, 0x000001e4, 0x0000021b, 0x000001e6, 0x0000021e, 0x000001e8, 0x0000021f, 0x000001ea, 0x00000226, 0x000001ec, 0x00000227, 0x000001ee, 0x00000228, 0x000001f0, 0x00000229, 0x000001f2, 0x0000022a, 0x000001f4, 0x0000022b, 0x000001f7, 0x0000022c, 0x000001fa, 0x0000022d, 0x000001fd, 0x0000022e, 0x00000200, 0x0000022f, 0x00000202, 0x00000230, 0x00000204, 0x00000231, 0x00000207, 0x00000232, 0x0000020a, 0x00000233, 0x0000020c, 0x00000340, 0x0000020e, 0x00000341, 0x0000020f, 0x00000343, 0x00000210, 0x00000344, 0x00000211, 0x00000374, 0x00000213, 0x0000037e, 0x00000214, 0x00000385, 0x00000215, 0x00000386, 0x00000217, 0x00000387, 0x00000219, 0x00000388, 0x0000021a, 0x00000389, 0x0000021c, 0x0000038a, 0x0000021e, 0x0000038c, 0x00000220, 0x0000038e, 0x00000222, 0x0000038f, 0x00000224, 0x00000390, 0x00000226, 0x000003aa, 0x00000229, 0x000003ab, 0x0000022b, 0x000003ac, 0x0000022d, 0x000003ad, 0x0000022f, 0x000003ae, 0x00000231, 0x000003af, 0x00000233, 0x000003b0, 0x00000235, 0x000003ca, 0x00000238, 0x000003cb, 0x0000023a, 0x000003cc, 0x0000023c, 0x000003cd, 0x0000023e, 0x000003ce, 0x00000240, 0x000003d3, 0x00000242, 0x000003d4, 0x00000244, 0x00000400, 0x00000246, 0x00000401, 0x00000248, 0x00000403, 0x0000024a, 0x00000407, 0x0000024c, 0x0000040c, 0x0000024e, 0x0000040d, 0x00000250, 0x0000040e, 0x00000252, 0x00000419, 0x00000254, 0x00000439, 0x00000256, 0x00000450, 0x00000258, 0x00000451, 0x0000025a, 0x00000453, 0x0000025c, 0x00000457, 0x0000025e, 0x0000045c, 0x00000260, 0x0000045d, 0x00000262, 0x0000045e, 0x00000264, 0x00000476, 0x00000266, 0x00000477, 0x00000268, 0x000004c1, 0x0000026a, 0x000004c2, 0x0000026c, 0x000004d0, 0x0000026e, 0x000004d1, 0x00000270, 0x000004d2, 0x00000272, 0x000004d3, 0x00000274, 0x000004d6, 0x00000276, 0x000004d7, 0x00000278, 0x000004da, 0x0000027a, 0x000004db, 0x0000027c, 0x000004dc, 0x0000027e, 0x000004dd, 0x00000280, 0x000004de, 0x00000282, 0x000004df, 0x00000284, 0x000004e2, 0x00000286, 0x000004e3, 0x00000288, 0x000004e4, 0x0000028a, 0x000004e5, 0x0000028c, 0x000004e6, 0x0000028e, 0x000004e7, 0x00000290, 0x000004ea, 0x00000292, 0x000004eb, 0x00000294, 0x000004ec, 0x00000296, 0x000004ed, 0x00000298, 0x000004ee, 0x0000029a, 0x000004ef, 0x0000029c, 0x000004f0, 0x0000029e, 0x000004f1, 0x000002a0, 0x000004f2, 0x000002a2, 0x000004f3, 0x000002a4, 0x000004f4, 0x000002a6, 0x000004f5, 0x000002a8, 0x000004f8, 0x000002aa, 0x000004f9, 0x000002ac, 0x00000622, 0x000002ae, 0x00000623, 0x000002b0, 0x00000624, 0x000002b2, 0x00000625, 0x000002b4, 0x00000626, 0x000002b6, 0x000006c0, 0x000002b8, 0x000006c2, 0x000002ba, 0x000006d3, 0x000002bc, 0x00000929, 0x000002be, 0x00000931, 0x000002c0, 0x00000934, 0x000002c2, 0x00000958, 0x000002c4, 0x00000959, 0x000002c6, 0x0000095a, 0x000002c8, 0x0000095b, 0x000002ca, 0x0000095c, 0x000002cc, 0x0000095d, 0x000002ce, 0x0000095e, 0x000002d0, 0x0000095f, 0x000002d2, 0x000009cb, 0x000002d4, 0x000009cc, 0x000002d6, 0x000009dc, 0x000002d8, 0x000009dd, 0x000002da, 0x000009df, 0x000002dc, 0x00000a33, 0x000002de, 0x00000a36, 0x000002e0, 0x00000a59, 0x000002e2, 0x00000a5a, 0x000002e4, 0x00000a5b, 0x000002e6, 0x00000a5e, 0x000002e8, 0x00000b48, 0x000002ea, 0x00000b4b, 0x000002ec, 0x00000b4c, 0x000002ee, 0x00000b5c, 0x000002f0, 0x00000b5d, 0x000002f2, 0x00000b94, 0x000002f4, 0x00000bca, 0x000002f6, 0x00000bcb, 0x000002f8, 0x00000bcc, 0x000002fa, 0x00000c48, 0x000002fc, 0x00000cc0, 0x000002fe, 0x00000cc7, 0x00000300, 0x00000cc8, 0x00000302, 0x00000cca, 0x00000304, 0x00000ccb, 0x00000306, 0x00000d4a, 0x00000309, 0x00000d4b, 0x0000030b, 0x00000d4c, 0x0000030d, 0x00000dda, 0x0000030f, 0x00000ddc, 0x00000311, 0x00000ddd, 0x00000313, 0x00000dde, 0x00000316, 0x00000f43, 0x00000318, 0x00000f4d, 0x0000031a, 0x00000f52, 0x0000031c, 0x00000f57, 0x0000031e, 0x00000f5c, 0x00000320, 0x00000f69, 0x00000322, 0x00000f73, 0x00000324, 0x00000f75, 0x00000326, 0x00000f76, 0x00000328, 0x00000f78, 0x0000032a, 0x00000f81, 0x0000032c, 0x00000f93, 0x0000032e, 0x00000f9d, 0x00000330, 0x00000fa2, 0x00000332, 0x00000fa7, 0x00000334, 0x00000fac, 0x00000336, 0x00000fb9, 0x00000338, 0x00001026, 0x0000033a, 0x00001e00, 0x0000033c, 0x00001e01, 0x0000033e, 0x00001e02, 0x00000340, 0x00001e03, 0x00000342, 0x00001e04, 0x00000344, 0x00001e05, 0x00000346, 0x00001e06, 0x00000348, 0x00001e07, 0x0000034a, 0x00001e08, 0x0000034c, 0x00001e09, 0x0000034f, 0x00001e0a, 0x00000352, 0x00001e0b, 0x00000354, 0x00001e0c, 0x00000356, 0x00001e0d, 0x00000358, 0x00001e0e, 0x0000035a, 0x00001e0f, 0x0000035c, 0x00001e10, 0x0000035e, 0x00001e11, 0x00000360, 0x00001e12, 0x00000362, 0x00001e13, 0x00000364, 0x00001e14, 0x00000366, 0x00001e15, 0x00000369, 0x00001e16, 0x0000036c, 0x00001e17, 0x0000036f, 0x00001e18, 0x00000372, 0x00001e19, 0x00000374, 0x00001e1a, 0x00000376, 0x00001e1b, 0x00000378, 0x00001e1c, 0x0000037a, 0x00001e1d, 0x0000037d, 0x00001e1e, 0x00000380, 0x00001e1f, 0x00000382, 0x00001e20, 0x00000384, 0x00001e21, 0x00000386, 0x00001e22, 0x00000388, 0x00001e23, 0x0000038a, 0x00001e24, 0x0000038c, 0x00001e25, 0x0000038e, 0x00001e26, 0x00000390, 0x00001e27, 0x00000392, 0x00001e28, 0x00000394, 0x00001e29, 0x00000396, 0x00001e2a, 0x00000398, 0x00001e2b, 0x0000039a, 0x00001e2c, 0x0000039c, 0x00001e2d, 0x0000039e, 0x00001e2e, 0x000003a0, 0x00001e2f, 0x000003a3, 0x00001e30, 0x000003a6, 0x00001e31, 0x000003a8, 0x00001e32, 0x000003aa, 0x00001e33, 0x000003ac, 0x00001e34, 0x000003ae, 0x00001e35, 0x000003b0, 0x00001e36, 0x000003b2, 0x00001e37, 0x000003b4, 0x00001e38, 0x000003b6, 0x00001e39, 0x000003b9, 0x00001e3a, 0x000003bc, 0x00001e3b, 0x000003be, 0x00001e3c, 0x000003c0, 0x00001e3d, 0x000003c2, 0x00001e3e, 0x000003c4, 0x00001e3f, 0x000003c6, 0x00001e40, 0x000003c8, 0x00001e41, 0x000003ca, 0x00001e42, 0x000003cc, 0x00001e43, 0x000003ce, 0x00001e44, 0x000003d0, 0x00001e45, 0x000003d2, 0x00001e46, 0x000003d4, 0x00001e47, 0x000003d6, 0x00001e48, 0x000003d8, 0x00001e49, 0x000003da, 0x00001e4a, 0x000003dc, 0x00001e4b, 0x000003de, 0x00001e4c, 0x000003e0, 0x00001e4d, 0x000003e3, 0x00001e4e, 0x000003e6, 0x00001e4f, 0x000003e9, 0x00001e50, 0x000003ec, 0x00001e51, 0x000003ef, 0x00001e52, 0x000003f2, 0x00001e53, 0x000003f5, 0x00001e54, 0x000003f8, 0x00001e55, 0x000003fa, 0x00001e56, 0x000003fc, 0x00001e57, 0x000003fe, 0x00001e58, 0x00000400, 0x00001e59, 0x00000402, 0x00001e5a, 0x00000404, 0x00001e5b, 0x00000406, 0x00001e5c, 0x00000408, 0x00001e5d, 0x0000040b, 0x00001e5e, 0x0000040e, 0x00001e5f, 0x00000410, 0x00001e60, 0x00000412, 0x00001e61, 0x00000414, 0x00001e62, 0x00000416, 0x00001e63, 0x00000418, 0x00001e64, 0x0000041a, 0x00001e65, 0x0000041d, 0x00001e66, 0x00000420, 0x00001e67, 0x00000423, 0x00001e68, 0x00000426, 0x00001e69, 0x00000429, 0x00001e6a, 0x0000042c, 0x00001e6b, 0x0000042e, 0x00001e6c, 0x00000430, 0x00001e6d, 0x00000432, 0x00001e6e, 0x00000434, 0x00001e6f, 0x00000436, 0x00001e70, 0x00000438, 0x00001e71, 0x0000043a, 0x00001e72, 0x0000043c, 0x00001e73, 0x0000043e, 0x00001e74, 0x00000440, 0x00001e75, 0x00000442, 0x00001e76, 0x00000444, 0x00001e77, 0x00000446, 0x00001e78, 0x00000448, 0x00001e79, 0x0000044b, 0x00001e7a, 0x0000044e, 0x00001e7b, 0x00000451, 0x00001e7c, 0x00000454, 0x00001e7d, 0x00000456, 0x00001e7e, 0x00000458, 0x00001e7f, 0x0000045a, 0x00001e80, 0x0000045c, 0x00001e81, 0x0000045e, 0x00001e82, 0x00000460, 0x00001e83, 0x00000462, 0x00001e84, 0x00000464, 0x00001e85, 0x00000466, 0x00001e86, 0x00000468, 0x00001e87, 0x0000046a, 0x00001e88, 0x0000046c, 0x00001e89, 0x0000046e, 0x00001e8a, 0x00000470, 0x00001e8b, 0x00000472, 0x00001e8c, 0x00000474, 0x00001e8d, 0x00000476, 0x00001e8e, 0x00000478, 0x00001e8f, 0x0000047a, 0x00001e90, 0x0000047c, 0x00001e91, 0x0000047e, 0x00001e92, 0x00000480, 0x00001e93, 0x00000482, 0x00001e94, 0x00000484, 0x00001e95, 0x00000486, 0x00001e96, 0x00000488, 0x00001e97, 0x0000048a, 0x00001e98, 0x0000048c, 0x00001e99, 0x0000048e, 0x00001e9b, 0x00000490, 0x00001ea0, 0x00000492, 0x00001ea1, 0x00000494, 0x00001ea2, 0x00000496, 0x00001ea3, 0x00000498, 0x00001ea4, 0x0000049a, 0x00001ea5, 0x0000049d, 0x00001ea6, 0x000004a0, 0x00001ea7, 0x000004a3, 0x00001ea8, 0x000004a6, 0x00001ea9, 0x000004a9, 0x00001eaa, 0x000004ac, 0x00001eab, 0x000004af, 0x00001eac, 0x000004b2, 0x00001ead, 0x000004b5, 0x00001eae, 0x000004b8, 0x00001eaf, 0x000004bb, 0x00001eb0, 0x000004be, 0x00001eb1, 0x000004c1, 0x00001eb2, 0x000004c4, 0x00001eb3, 0x000004c7, 0x00001eb4, 0x000004ca, 0x00001eb5, 0x000004cd, 0x00001eb6, 0x000004d0, 0x00001eb7, 0x000004d3, 0x00001eb8, 0x000004d6, 0x00001eb9, 0x000004d8, 0x00001eba, 0x000004da, 0x00001ebb, 0x000004dc, 0x00001ebc, 0x000004de, 0x00001ebd, 0x000004e0, 0x00001ebe, 0x000004e2, 0x00001ebf, 0x000004e5, 0x00001ec0, 0x000004e8, 0x00001ec1, 0x000004eb, 0x00001ec2, 0x000004ee, 0x00001ec3, 0x000004f1, 0x00001ec4, 0x000004f4, 0x00001ec5, 0x000004f7, 0x00001ec6, 0x000004fa, 0x00001ec7, 0x000004fd, 0x00001ec8, 0x00000500, 0x00001ec9, 0x00000502, 0x00001eca, 0x00000504, 0x00001ecb, 0x00000506, 0x00001ecc, 0x00000508, 0x00001ecd, 0x0000050a, 0x00001ece, 0x0000050c, 0x00001ecf, 0x0000050e, 0x00001ed0, 0x00000510, 0x00001ed1, 0x00000513, 0x00001ed2, 0x00000516, 0x00001ed3, 0x00000519, 0x00001ed4, 0x0000051c, 0x00001ed5, 0x0000051f, 0x00001ed6, 0x00000522, 0x00001ed7, 0x00000525, 0x00001ed8, 0x00000528, 0x00001ed9, 0x0000052b, 0x00001eda, 0x0000052e, 0x00001edb, 0x00000531, 0x00001edc, 0x00000534, 0x00001edd, 0x00000537, 0x00001ede, 0x0000053a, 0x00001edf, 0x0000053d, 0x00001ee0, 0x00000540, 0x00001ee1, 0x00000543, 0x00001ee2, 0x00000546, 0x00001ee3, 0x00000549, 0x00001ee4, 0x0000054c, 0x00001ee5, 0x0000054e, 0x00001ee6, 0x00000550, 0x00001ee7, 0x00000552, 0x00001ee8, 0x00000554, 0x00001ee9, 0x00000557, 0x00001eea, 0x0000055a, 0x00001eeb, 0x0000055d, 0x00001eec, 0x00000560, 0x00001eed, 0x00000563, 0x00001eee, 0x00000566, 0x00001eef, 0x00000569, 0x00001ef0, 0x0000056c, 0x00001ef1, 0x0000056f, 0x00001ef2, 0x00000572, 0x00001ef3, 0x00000574, 0x00001ef4, 0x00000576, 0x00001ef5, 0x00000578, 0x00001ef6, 0x0000057a, 0x00001ef7, 0x0000057c, 0x00001ef8, 0x0000057e, 0x00001ef9, 0x00000580, 0x00001f00, 0x00000582, 0x00001f01, 0x00000584, 0x00001f02, 0x00000586, 0x00001f03, 0x00000589, 0x00001f04, 0x0000058c, 0x00001f05, 0x0000058f, 0x00001f06, 0x00000592, 0x00001f07, 0x00000595, 0x00001f08, 0x00000598, 0x00001f09, 0x0000059a, 0x00001f0a, 0x0000059c, 0x00001f0b, 0x0000059f, 0x00001f0c, 0x000005a2, 0x00001f0d, 0x000005a5, 0x00001f0e, 0x000005a8, 0x00001f0f, 0x000005ab, 0x00001f10, 0x000005ae, 0x00001f11, 0x000005b0, 0x00001f12, 0x000005b2, 0x00001f13, 0x000005b5, 0x00001f14, 0x000005b8, 0x00001f15, 0x000005bb, 0x00001f18, 0x000005be, 0x00001f19, 0x000005c0, 0x00001f1a, 0x000005c2, 0x00001f1b, 0x000005c5, 0x00001f1c, 0x000005c8, 0x00001f1d, 0x000005cb, 0x00001f20, 0x000005ce, 0x00001f21, 0x000005d0, 0x00001f22, 0x000005d2, 0x00001f23, 0x000005d5, 0x00001f24, 0x000005d8, 0x00001f25, 0x000005db, 0x00001f26, 0x000005de, 0x00001f27, 0x000005e1, 0x00001f28, 0x000005e4, 0x00001f29, 0x000005e6, 0x00001f2a, 0x000005e8, 0x00001f2b, 0x000005eb, 0x00001f2c, 0x000005ee, 0x00001f2d, 0x000005f1, 0x00001f2e, 0x000005f4, 0x00001f2f, 0x000005f7, 0x00001f30, 0x000005fa, 0x00001f31, 0x000005fc, 0x00001f32, 0x000005fe, 0x00001f33, 0x00000601, 0x00001f34, 0x00000604, 0x00001f35, 0x00000607, 0x00001f36, 0x0000060a, 0x00001f37, 0x0000060d, 0x00001f38, 0x00000610, 0x00001f39, 0x00000612, 0x00001f3a, 0x00000614, 0x00001f3b, 0x00000617, 0x00001f3c, 0x0000061a, 0x00001f3d, 0x0000061d, 0x00001f3e, 0x00000620, 0x00001f3f, 0x00000623, 0x00001f40, 0x00000626, 0x00001f41, 0x00000628, 0x00001f42, 0x0000062a, 0x00001f43, 0x0000062d, 0x00001f44, 0x00000630, 0x00001f45, 0x00000633, 0x00001f48, 0x00000636, 0x00001f49, 0x00000638, 0x00001f4a, 0x0000063a, 0x00001f4b, 0x0000063d, 0x00001f4c, 0x00000640, 0x00001f4d, 0x00000643, 0x00001f50, 0x00000646, 0x00001f51, 0x00000648, 0x00001f52, 0x0000064a, 0x00001f53, 0x0000064d, 0x00001f54, 0x00000650, 0x00001f55, 0x00000653, 0x00001f56, 0x00000656, 0x00001f57, 0x00000659, 0x00001f59, 0x0000065c, 0x00001f5b, 0x0000065e, 0x00001f5d, 0x00000661, 0x00001f5f, 0x00000664, 0x00001f60, 0x00000667, 0x00001f61, 0x00000669, 0x00001f62, 0x0000066b, 0x00001f63, 0x0000066e, 0x00001f64, 0x00000671, 0x00001f65, 0x00000674, 0x00001f66, 0x00000677, 0x00001f67, 0x0000067a, 0x00001f68, 0x0000067d, 0x00001f69, 0x0000067f, 0x00001f6a, 0x00000681, 0x00001f6b, 0x00000684, 0x00001f6c, 0x00000687, 0x00001f6d, 0x0000068a, 0x00001f6e, 0x0000068d, 0x00001f6f, 0x00000690, 0x00001f70, 0x00000693, 0x00001f71, 0x00000695, 0x00001f72, 0x00000697, 0x00001f73, 0x00000699, 0x00001f74, 0x0000069b, 0x00001f75, 0x0000069d, 0x00001f76, 0x0000069f, 0x00001f77, 0x000006a1, 0x00001f78, 0x000006a3, 0x00001f79, 0x000006a5, 0x00001f7a, 0x000006a7, 0x00001f7b, 0x000006a9, 0x00001f7c, 0x000006ab, 0x00001f7d, 0x000006ad, 0x00001f80, 0x000006af, 0x00001f81, 0x000006b2, 0x00001f82, 0x000006b5, 0x00001f83, 0x000006b9, 0x00001f84, 0x000006bd, 0x00001f85, 0x000006c1, 0x00001f86, 0x000006c5, 0x00001f87, 0x000006c9, 0x00001f88, 0x000006cd, 0x00001f89, 0x000006d0, 0x00001f8a, 0x000006d3, 0x00001f8b, 0x000006d7, 0x00001f8c, 0x000006db, 0x00001f8d, 0x000006df, 0x00001f8e, 0x000006e3, 0x00001f8f, 0x000006e7, 0x00001f90, 0x000006eb, 0x00001f91, 0x000006ee, 0x00001f92, 0x000006f1, 0x00001f93, 0x000006f5, 0x00001f94, 0x000006f9, 0x00001f95, 0x000006fd, 0x00001f96, 0x00000701, 0x00001f97, 0x00000705, 0x00001f98, 0x00000709, 0x00001f99, 0x0000070c, 0x00001f9a, 0x0000070f, 0x00001f9b, 0x00000713, 0x00001f9c, 0x00000717, 0x00001f9d, 0x0000071b, 0x00001f9e, 0x0000071f, 0x00001f9f, 0x00000723, 0x00001fa0, 0x00000727, 0x00001fa1, 0x0000072a, 0x00001fa2, 0x0000072d, 0x00001fa3, 0x00000731, 0x00001fa4, 0x00000735, 0x00001fa5, 0x00000739, 0x00001fa6, 0x0000073d, 0x00001fa7, 0x00000741, 0x00001fa8, 0x00000745, 0x00001fa9, 0x00000748, 0x00001faa, 0x0000074b, 0x00001fab, 0x0000074f, 0x00001fac, 0x00000753, 0x00001fad, 0x00000757, 0x00001fae, 0x0000075b, 0x00001faf, 0x0000075f, 0x00001fb0, 0x00000763, 0x00001fb1, 0x00000765, 0x00001fb2, 0x00000767, 0x00001fb3, 0x0000076a, 0x00001fb4, 0x0000076c, 0x00001fb6, 0x0000076f, 0x00001fb7, 0x00000771, 0x00001fb8, 0x00000774, 0x00001fb9, 0x00000776, 0x00001fba, 0x00000778, 0x00001fbb, 0x0000077a, 0x00001fbc, 0x0000077c, 0x00001fbe, 0x0000077e, 0x00001fc1, 0x0000077f, 0x00001fc2, 0x00000781, 0x00001fc3, 0x00000784, 0x00001fc4, 0x00000786, 0x00001fc6, 0x00000789, 0x00001fc7, 0x0000078b, 0x00001fc8, 0x0000078e, 0x00001fc9, 0x00000790, 0x00001fca, 0x00000792, 0x00001fcb, 0x00000794, 0x00001fcc, 0x00000796, 0x00001fcd, 0x00000798, 0x00001fce, 0x0000079a, 0x00001fcf, 0x0000079c, 0x00001fd0, 0x0000079e, 0x00001fd1, 0x000007a0, 0x00001fd2, 0x000007a2, 0x00001fd3, 0x000007a5, 0x00001fd6, 0x000007a8, 0x00001fd7, 0x000007aa, 0x00001fd8, 0x000007ad, 0x00001fd9, 0x000007af, 0x00001fda, 0x000007b1, 0x00001fdb, 0x000007b3, 0x00001fdd, 0x000007b5, 0x00001fde, 0x000007b7, 0x00001fdf, 0x000007b9, 0x00001fe0, 0x000007bb, 0x00001fe1, 0x000007bd, 0x00001fe2, 0x000007bf, 0x00001fe3, 0x000007c2, 0x00001fe4, 0x000007c5, 0x00001fe5, 0x000007c7, 0x00001fe6, 0x000007c9, 0x00001fe7, 0x000007cb, 0x00001fe8, 0x000007ce, 0x00001fe9, 0x000007d0, 0x00001fea, 0x000007d2, 0x00001feb, 0x000007d4, 0x00001fec, 0x000007d6, 0x00001fed, 0x000007d8, 0x00001fee, 0x000007da, 0x00001fef, 0x000007dc, 0x00001ff2, 0x000007dd, 0x00001ff3, 0x000007e0, 0x00001ff4, 0x000007e2, 0x00001ff6, 0x000007e5, 0x00001ff7, 0x000007e7, 0x00001ff8, 0x000007ea, 0x00001ff9, 0x000007ec, 0x00001ffa, 0x000007ee, 0x00001ffb, 0x000007f0, 0x00001ffc, 0x000007f2, 0x00001ffd, 0x000007f4, 0x00002000, 0x000007f5, 0x00002001, 0x000007f6, 0x00002126, 0x000007f7, 0x0000212a, 0x000007f8, 0x0000212b, 0x000007f9, 0x0000219a, 0x000007fb, 0x0000219b, 0x000007fd, 0x000021ae, 0x000007ff, 0x000021cd, 0x00000801, 0x000021ce, 0x00000803, 0x000021cf, 0x00000805, 0x00002204, 0x00000807, 0x00002209, 0x00000809, 0x0000220c, 0x0000080b, 0x00002224, 0x0000080d, 0x00002226, 0x0000080f, 0x00002241, 0x00000811, 0x00002244, 0x00000813, 0x00002247, 0x00000815, 0x00002249, 0x00000817, 0x00002260, 0x00000819, 0x00002262, 0x0000081b, 0x0000226d, 0x0000081d, 0x0000226e, 0x0000081f, 0x0000226f, 0x00000821, 0x00002270, 0x00000823, 0x00002271, 0x00000825, 0x00002274, 0x00000827, 0x00002275, 0x00000829, 0x00002278, 0x0000082b, 0x00002279, 0x0000082d, 0x00002280, 0x0000082f, 0x00002281, 0x00000831, 0x00002284, 0x00000833, 0x00002285, 0x00000835, 0x00002288, 0x00000837, 0x00002289, 0x00000839, 0x000022ac, 0x0000083b, 0x000022ad, 0x0000083d, 0x000022ae, 0x0000083f, 0x000022af, 0x00000841, 0x000022e0, 0x00000843, 0x000022e1, 0x00000845, 0x000022e2, 0x00000847, 0x000022e3, 0x00000849, 0x000022ea, 0x0000084b, 0x000022eb, 0x0000084d, 0x000022ec, 0x0000084f, 0x000022ed, 0x00000851, 0x00002329, 0x00000853, 0x0000232a, 0x00000854, 0x00002adc, 0x00000855, 0x0000304c, 0x00000857, 0x0000304e, 0x00000859, 0x00003050, 0x0000085b, 0x00003052, 0x0000085d, 0x00003054, 0x0000085f, 0x00003056, 0x00000861, 0x00003058, 0x00000863, 0x0000305a, 0x00000865, 0x0000305c, 0x00000867, 0x0000305e, 0x00000869, 0x00003060, 0x0000086b, 0x00003062, 0x0000086d, 0x00003065, 0x0000086f, 0x00003067, 0x00000871, 0x00003069, 0x00000873, 0x00003070, 0x00000875, 0x00003071, 0x00000877, 0x00003073, 0x00000879, 0x00003074, 0x0000087b, 0x00003076, 0x0000087d, 0x00003077, 0x0000087f, 0x00003079, 0x00000881, 0x0000307a, 0x00000883, 0x0000307c, 0x00000885, 0x0000307d, 0x00000887, 0x00003094, 0x00000889, 0x0000309e, 0x0000088b, 0x000030ac, 0x0000088d, 0x000030ae, 0x0000088f, 0x000030b0, 0x00000891, 0x000030b2, 0x00000893, 0x000030b4, 0x00000895, 0x000030b6, 0x00000897, 0x000030b8, 0x00000899, 0x000030ba, 0x0000089b, 0x000030bc, 0x0000089d, 0x000030be, 0x0000089f, 0x000030c0, 0x000008a1, 0x000030c2, 0x000008a3, 0x000030c5, 0x000008a5, 0x000030c7, 0x000008a7, 0x000030c9, 0x000008a9, 0x000030d0, 0x000008ab, 0x000030d1, 0x000008ad, 0x000030d3, 0x000008af, 0x000030d4, 0x000008b1, 0x000030d6, 0x000008b3, 0x000030d7, 0x000008b5, 0x000030d9, 0x000008b7, 0x000030da, 0x000008b9, 0x000030dc, 0x000008bb, 0x000030dd, 0x000008bd, 0x000030f4, 0x000008bf, 0x000030f7, 0x000008c1, 0x000030f8, 0x000008c3, 0x000030f9, 0x000008c5, 0x000030fa, 0x000008c7, 0x000030fe, 0x000008c9, 0x0000f902, 0x000008cb, 0x0000f903, 0x000008cc, 0x0000f904, 0x000008cd, 0x0000f905, 0x000008ce, 0x0000f906, 0x000008cf, 0x0000f907, 0x000008d0, 0x0000f908, 0x000008d1, 0x0000f909, 0x000008d2, 0x0000f90a, 0x000008d3, 0x0000f90b, 0x000008d4, 0x0000f90c, 0x000008d5, 0x0000f90d, 0x000008d6, 0x0000f90e, 0x000008d7, 0x0000f90f, 0x000008d8, 0x0000f910, 0x000008d9, 0x0000f911, 0x000008da, 0x0000f912, 0x000008db, 0x0000f913, 0x000008dc, 0x0000f914, 0x000008dd, 0x0000f915, 0x000008de, 0x0000f916, 0x000008df, 0x0000f917, 0x000008e0, 0x0000f918, 0x000008e1, 0x0000f919, 0x000008e2, 0x0000f91a, 0x000008e3, 0x0000f91b, 0x000008e4, 0x0000f91c, 0x000008e5, 0x0000f91d, 0x000008e6, 0x0000f91e, 0x000008e7, 0x0000f91f, 0x000008e8, 0x0000f920, 0x000008e9, 0x0000f921, 0x000008ea, 0x0000f922, 0x000008eb, 0x0000f923, 0x000008ec, 0x0000f924, 0x000008ed, 0x0000f925, 0x000008ee, 0x0000f926, 0x000008ef, 0x0000f927, 0x000008f0, 0x0000f928, 0x000008f1, 0x0000f929, 0x000008f2, 0x0000f92a, 0x000008f3, 0x0000f92b, 0x000008f4, 0x0000f92c, 0x000008f5, 0x0000f92d, 0x000008f6, 0x0000f92e, 0x000008f7, 0x0000f92f, 0x000008f8, 0x0000f930, 0x000008f9, 0x0000f931, 0x000008fa, 0x0000f932, 0x000008fb, 0x0000f933, 0x000008fc, 0x0000f934, 0x000008fd, 0x0000f935, 0x000008fe, 0x0000f936, 0x000008ff, 0x0000f937, 0x00000900, 0x0000f938, 0x00000901, 0x0000f939, 0x00000902, 0x0000f93a, 0x00000903, 0x0000f93b, 0x00000904, 0x0000f93c, 0x00000905, 0x0000f93d, 0x00000906, 0x0000f93e, 0x00000907, 0x0000f93f, 0x00000908, 0x0000f940, 0x00000909, 0x0000f941, 0x0000090a, 0x0000f942, 0x0000090b, 0x0000f943, 0x0000090c, 0x0000f944, 0x0000090d, 0x0000f945, 0x0000090e, 0x0000f946, 0x0000090f, 0x0000f947, 0x00000910, 0x0000f948, 0x00000911, 0x0000f949, 0x00000912, 0x0000f94a, 0x00000913, 0x0000f94b, 0x00000914, 0x0000f94c, 0x00000915, 0x0000f94d, 0x00000916, 0x0000f94e, 0x00000917, 0x0000f94f, 0x00000918, 0x0000f950, 0x00000919, 0x0000f951, 0x0000091a, 0x0000f952, 0x0000091b, 0x0000f953, 0x0000091c, 0x0000f954, 0x0000091d, 0x0000f955, 0x0000091e, 0x0000f956, 0x0000091f, 0x0000f957, 0x00000920, 0x0000f958, 0x00000921, 0x0000f959, 0x00000922, 0x0000f95a, 0x00000923, 0x0000f95b, 0x00000924, 0x0000f95c, 0x00000925, 0x0000f95d, 0x00000926, 0x0000f95e, 0x00000927, 0x0000f95f, 0x00000928, 0x0000f960, 0x00000929, 0x0000f961, 0x0000092a, 0x0000f962, 0x0000092b, 0x0000f963, 0x0000092c, 0x0000f964, 0x0000092d, 0x0000f965, 0x0000092e, 0x0000f966, 0x0000092f, 0x0000f967, 0x00000930, 0x0000f968, 0x00000931, 0x0000f969, 0x00000932, 0x0000f96a, 0x00000933, 0x0000f96b, 0x00000934, 0x0000f96c, 0x00000935, 0x0000f96d, 0x00000936, 0x0000f96e, 0x00000937, 0x0000f96f, 0x00000938, 0x0000f970, 0x00000939, 0x0000f971, 0x0000093a, 0x0000f972, 0x0000093b, 0x0000f973, 0x0000093c, 0x0000f974, 0x0000093d, 0x0000f975, 0x0000093e, 0x0000f976, 0x0000093f, 0x0000f977, 0x00000940, 0x0000f978, 0x00000941, 0x0000f979, 0x00000942, 0x0000f97a, 0x00000943, 0x0000f97b, 0x00000944, 0x0000f97c, 0x00000945, 0x0000f97d, 0x00000946, 0x0000f97e, 0x00000947, 0x0000f97f, 0x00000948, 0x0000f980, 0x00000949, 0x0000f981, 0x0000094a, 0x0000f982, 0x0000094b, 0x0000f983, 0x0000094c, 0x0000f984, 0x0000094d, 0x0000f985, 0x0000094e, 0x0000f986, 0x0000094f, 0x0000f987, 0x00000950, 0x0000f988, 0x00000951, 0x0000f989, 0x00000952, 0x0000f98a, 0x00000953, 0x0000f98b, 0x00000954, 0x0000f98c, 0x00000955, 0x0000f98d, 0x00000956, 0x0000f98e, 0x00000957, 0x0000f98f, 0x00000958, 0x0000f990, 0x00000959, 0x0000f991, 0x0000095a, 0x0000f992, 0x0000095b, 0x0000f993, 0x0000095c, 0x0000f994, 0x0000095d, 0x0000f995, 0x0000095e, 0x0000f996, 0x0000095f, 0x0000f997, 0x00000960, 0x0000f998, 0x00000961, 0x0000f999, 0x00000962, 0x0000f99a, 0x00000963, 0x0000f99b, 0x00000964, 0x0000f99c, 0x00000965, 0x0000f99d, 0x00000966, 0x0000f99e, 0x00000967, 0x0000f99f, 0x00000968, 0x0000f9a0, 0x00000969, 0x0000f9a1, 0x0000096a, 0x0000f9a2, 0x0000096b, 0x0000f9a3, 0x0000096c, 0x0000f9a4, 0x0000096d, 0x0000f9a5, 0x0000096e, 0x0000f9a6, 0x0000096f, 0x0000f9a7, 0x00000970, 0x0000f9a8, 0x00000971, 0x0000f9a9, 0x00000972, 0x0000f9aa, 0x00000973, 0x0000f9ab, 0x00000974, 0x0000f9ac, 0x00000975, 0x0000f9ad, 0x00000976, 0x0000f9ae, 0x00000977, 0x0000f9af, 0x00000978, 0x0000f9b0, 0x00000979, 0x0000f9b1, 0x0000097a, 0x0000f9b2, 0x0000097b, 0x0000f9b3, 0x0000097c, 0x0000f9b4, 0x0000097d, 0x0000f9b5, 0x0000097e, 0x0000f9b6, 0x0000097f, 0x0000f9b7, 0x00000980, 0x0000f9b8, 0x00000981, 0x0000f9b9, 0x00000982, 0x0000f9ba, 0x00000983, 0x0000f9bb, 0x00000984, 0x0000f9bc, 0x00000985, 0x0000f9bd, 0x00000986, 0x0000f9be, 0x00000987, 0x0000f9bf, 0x00000988, 0x0000f9c0, 0x00000989, 0x0000f9c1, 0x0000098a, 0x0000f9c2, 0x0000098b, 0x0000f9c3, 0x0000098c, 0x0000f9c4, 0x0000098d, 0x0000f9c5, 0x0000098e, 0x0000f9c6, 0x0000098f, 0x0000f9c7, 0x00000990, 0x0000f9c8, 0x00000991, 0x0000f9c9, 0x00000992, 0x0000f9ca, 0x00000993, 0x0000f9cb, 0x00000994, 0x0000f9cc, 0x00000995, 0x0000f9cd, 0x00000996, 0x0000f9ce, 0x00000997, 0x0000f9cf, 0x00000998, 0x0000f9d0, 0x00000999, 0x0000f9d1, 0x0000099a, 0x0000f9d2, 0x0000099b, 0x0000f9d3, 0x0000099c, 0x0000f9d4, 0x0000099d, 0x0000f9d5, 0x0000099e, 0x0000f9d6, 0x0000099f, 0x0000f9d7, 0x000009a0, 0x0000f9d8, 0x000009a1, 0x0000f9d9, 0x000009a2, 0x0000f9da, 0x000009a3, 0x0000f9db, 0x000009a4, 0x0000f9dc, 0x000009a5, 0x0000f9dd, 0x000009a6, 0x0000f9de, 0x000009a7, 0x0000f9df, 0x000009a8, 0x0000f9e0, 0x000009a9, 0x0000f9e1, 0x000009aa, 0x0000f9e2, 0x000009ab, 0x0000f9e3, 0x000009ac, 0x0000f9e4, 0x000009ad, 0x0000f9e5, 0x000009ae, 0x0000f9e6, 0x000009af, 0x0000f9e7, 0x000009b0, 0x0000f9e8, 0x000009b1, 0x0000f9e9, 0x000009b2, 0x0000f9ea, 0x000009b3, 0x0000f9eb, 0x000009b4, 0x0000f9ec, 0x000009b5, 0x0000f9ed, 0x000009b6, 0x0000f9ee, 0x000009b7, 0x0000f9ef, 0x000009b8, 0x0000f9f0, 0x000009b9, 0x0000f9f1, 0x000009ba, 0x0000f9f2, 0x000009bb, 0x0000f9f3, 0x000009bc, 0x0000f9f4, 0x000009bd, 0x0000f9f5, 0x000009be, 0x0000f9f6, 0x000009bf, 0x0000f9f7, 0x000009c0, 0x0000f9f8, 0x000009c1, 0x0000f9f9, 0x000009c2, 0x0000f9fa, 0x000009c3, 0x0000f9fb, 0x000009c4, 0x0000f9fc, 0x000009c5, 0x0000f9fd, 0x000009c6, 0x0000f9fe, 0x000009c7, 0x0000f9ff, 0x000009c8, 0x0000fa00, 0x000009c9, 0x0000fa01, 0x000009ca, 0x0000fa02, 0x000009cb, 0x0000fa03, 0x000009cc, 0x0000fa04, 0x000009cd, 0x0000fa05, 0x000009ce, 0x0000fa06, 0x000009cf, 0x0000fa07, 0x000009d0, 0x0000fa08, 0x000009d1, 0x0000fa09, 0x000009d2, 0x0000fa0a, 0x000009d3, 0x0000fa0b, 0x000009d4, 0x0000fa0c, 0x000009d5, 0x0000fa0d, 0x000009d6, 0x0000fa10, 0x000009d7, 0x0000fa12, 0x000009d8, 0x0000fa15, 0x000009d9, 0x0000fa16, 0x000009da, 0x0000fa17, 0x000009db, 0x0000fa18, 0x000009dc, 0x0000fa19, 0x000009dd, 0x0000fa1a, 0x000009de, 0x0000fa1b, 0x000009df, 0x0000fa1c, 0x000009e0, 0x0000fa1d, 0x000009e1, 0x0000fa1e, 0x000009e2, 0x0000fa20, 0x000009e3, 0x0000fa22, 0x000009e4, 0x0000fa25, 0x000009e5, 0x0000fa26, 0x000009e6, 0x0000fa2a, 0x000009e7, 0x0000fa2b, 0x000009e8, 0x0000fa2c, 0x000009e9, 0x0000fa2d, 0x000009ea, 0x0000fa30, 0x000009eb, 0x0000fa31, 0x000009ec, 0x0000fa32, 0x000009ed, 0x0000fa33, 0x000009ee, 0x0000fa34, 0x000009ef, 0x0000fa35, 0x000009f0, 0x0000fa36, 0x000009f1, 0x0000fa37, 0x000009f2, 0x0000fa38, 0x000009f3, 0x0000fa39, 0x000009f4, 0x0000fa3a, 0x000009f5, 0x0000fa3b, 0x000009f6, 0x0000fa3c, 0x000009f7, 0x0000fa3d, 0x000009f8, 0x0000fa3e, 0x000009f9, 0x0000fa3f, 0x000009fa, 0x0000fa40, 0x000009fb, 0x0000fa41, 0x000009fc, 0x0000fa42, 0x000009fd, 0x0000fa43, 0x000009fe, 0x0000fa44, 0x000009ff, 0x0000fa45, 0x00000a00, 0x0000fa46, 0x00000a01, 0x0000fa47, 0x00000a02, 0x0000fa48, 0x00000a03, 0x0000fa49, 0x00000a04, 0x0000fa4a, 0x00000a05, 0x0000fa4b, 0x00000a06, 0x0000fa4c, 0x00000a07, 0x0000fa4d, 0x00000a08, 0x0000fa4e, 0x00000a09, 0x0000fa4f, 0x00000a0a, 0x0000fa50, 0x00000a0b, 0x0000fa51, 0x00000a0c, 0x0000fa52, 0x00000a0d, 0x0000fa53, 0x00000a0e, 0x0000fa54, 0x00000a0f, 0x0000fa55, 0x00000a10, 0x0000fa56, 0x00000a11, 0x0000fa57, 0x00000a12, 0x0000fa58, 0x00000a13, 0x0000fa59, 0x00000a14, 0x0000fa5a, 0x00000a15, 0x0000fa5b, 0x00000a16, 0x0000fa5c, 0x00000a17, 0x0000fa5d, 0x00000a18, 0x0000fa5e, 0x00000a19, 0x0000fa5f, 0x00000a1a, 0x0000fa60, 0x00000a1b, 0x0000fa61, 0x00000a1c, 0x0000fa62, 0x00000a1d, 0x0000fa63, 0x00000a1e, 0x0000fa64, 0x00000a1f, 0x0000fa65, 0x00000a20, 0x0000fa66, 0x00000a21, 0x0000fa67, 0x00000a22, 0x0000fa68, 0x00000a23, 0x0000fa69, 0x00000a24, 0x0000fa6a, 0x00000a25, 0x0000fb1d, 0x00000a26, 0x0000fb1f, 0x00000a28, 0x0000fb2a, 0x00000a2a, 0x0000fb2b, 0x00000a2c, 0x0000fb2c, 0x00000a2e, 0x0000fb2d, 0x00000a31, 0x0000fb2e, 0x00000a34, 0x0000fb2f, 0x00000a36, 0x0000fb30, 0x00000a38, 0x0000fb31, 0x00000a3a, 0x0000fb32, 0x00000a3c, 0x0000fb33, 0x00000a3e, 0x0000fb34, 0x00000a40, 0x0000fb35, 0x00000a42, 0x0000fb36, 0x00000a44, 0x0000fb38, 0x00000a46, 0x0000fb39, 0x00000a48, 0x0000fb3a, 0x00000a4a, 0x0000fb3b, 0x00000a4c, 0x0000fb3c, 0x00000a4e, 0x0000fb3e, 0x00000a50, 0x0000fb40, 0x00000a52, 0x0000fb41, 0x00000a54, 0x0000fb43, 0x00000a56, 0x0000fb44, 0x00000a58, 0x0000fb46, 0x00000a5a, 0x0000fb47, 0x00000a5c, 0x0000fb48, 0x00000a5e, 0x0000fb49, 0x00000a60, 0x0000fb4a, 0x00000a62, 0x0000fb4b, 0x00000a64, 0x0000fb4c, 0x00000a66, 0x0000fb4d, 0x00000a68, 0x0000fb4e, 0x00000a6a, 0x0001d15e, 0x00000a6c, 0x0001d15f, 0x00000a6e, 0x0001d160, 0x00000a70, 0x0001d161, 0x00000a73, 0x0001d162, 0x00000a76, 0x0001d163, 0x00000a79, 0x0001d164, 0x00000a7c, 0x0001d1bb, 0x00000a7f, 0x0001d1bc, 0x00000a81, 0x0001d1bd, 0x00000a83, 0x0001d1be, 0x00000a86, 0x0001d1bf, 0x00000a89, 0x0001d1c0, 0x00000a8c, 0x0002f800, 0x00000a8f, 0x0002f801, 0x00000a90, 0x0002f802, 0x00000a91, 0x0002f803, 0x00000a92, 0x0002f804, 0x00000a93, 0x0002f805, 0x00000a94, 0x0002f806, 0x00000a95, 0x0002f807, 0x00000a96, 0x0002f808, 0x00000a97, 0x0002f809, 0x00000a98, 0x0002f80a, 0x00000a99, 0x0002f80b, 0x00000a9a, 0x0002f80c, 0x00000a9b, 0x0002f80d, 0x00000a9c, 0x0002f80e, 0x00000a9d, 0x0002f80f, 0x00000a9e, 0x0002f810, 0x00000a9f, 0x0002f811, 0x00000aa0, 0x0002f812, 0x00000aa1, 0x0002f813, 0x00000aa2, 0x0002f814, 0x00000aa3, 0x0002f815, 0x00000aa4, 0x0002f816, 0x00000aa5, 0x0002f817, 0x00000aa6, 0x0002f818, 0x00000aa7, 0x0002f819, 0x00000aa8, 0x0002f81a, 0x00000aa9, 0x0002f81b, 0x00000aaa, 0x0002f81c, 0x00000aab, 0x0002f81d, 0x00000aac, 0x0002f81e, 0x00000aad, 0x0002f81f, 0x00000aae, 0x0002f820, 0x00000aaf, 0x0002f821, 0x00000ab0, 0x0002f822, 0x00000ab1, 0x0002f823, 0x00000ab2, 0x0002f824, 0x00000ab3, 0x0002f825, 0x00000ab4, 0x0002f826, 0x00000ab5, 0x0002f827, 0x00000ab6, 0x0002f828, 0x00000ab7, 0x0002f829, 0x00000ab8, 0x0002f82a, 0x00000ab9, 0x0002f82b, 0x00000aba, 0x0002f82c, 0x00000abb, 0x0002f82d, 0x00000abc, 0x0002f82e, 0x00000abd, 0x0002f82f, 0x00000abe, 0x0002f830, 0x00000abf, 0x0002f831, 0x00000ac0, 0x0002f832, 0x00000ac1, 0x0002f833, 0x00000ac2, 0x0002f834, 0x00000ac3, 0x0002f835, 0x00000ac4, 0x0002f836, 0x00000ac5, 0x0002f837, 0x00000ac6, 0x0002f838, 0x00000ac7, 0x0002f839, 0x00000ac8, 0x0002f83a, 0x00000ac9, 0x0002f83b, 0x00000aca, 0x0002f83c, 0x00000acb, 0x0002f83d, 0x00000acc, 0x0002f83e, 0x00000acd, 0x0002f83f, 0x00000ace, 0x0002f840, 0x00000acf, 0x0002f841, 0x00000ad0, 0x0002f842, 0x00000ad1, 0x0002f843, 0x00000ad2, 0x0002f844, 0x00000ad3, 0x0002f845, 0x00000ad4, 0x0002f846, 0x00000ad5, 0x0002f847, 0x00000ad6, 0x0002f848, 0x00000ad7, 0x0002f849, 0x00000ad8, 0x0002f84a, 0x00000ad9, 0x0002f84b, 0x00000ada, 0x0002f84c, 0x00000adb, 0x0002f84d, 0x00000adc, 0x0002f84e, 0x00000add, 0x0002f84f, 0x00000ade, 0x0002f850, 0x00000adf, 0x0002f851, 0x00000ae0, 0x0002f852, 0x00000ae1, 0x0002f853, 0x00000ae2, 0x0002f854, 0x00000ae3, 0x0002f855, 0x00000ae4, 0x0002f856, 0x00000ae5, 0x0002f857, 0x00000ae6, 0x0002f858, 0x00000ae7, 0x0002f859, 0x00000ae8, 0x0002f85a, 0x00000ae9, 0x0002f85b, 0x00000aea, 0x0002f85c, 0x00000aeb, 0x0002f85d, 0x00000aec, 0x0002f85e, 0x00000aed, 0x0002f85f, 0x00000aee, 0x0002f860, 0x00000aef, 0x0002f861, 0x00000af0, 0x0002f862, 0x00000af1, 0x0002f863, 0x00000af2, 0x0002f864, 0x00000af3, 0x0002f865, 0x00000af4, 0x0002f866, 0x00000af5, 0x0002f867, 0x00000af6, 0x0002f868, 0x00000af7, 0x0002f869, 0x00000af8, 0x0002f86a, 0x00000af9, 0x0002f86b, 0x00000afa, 0x0002f86c, 0x00000afb, 0x0002f86d, 0x00000afc, 0x0002f86e, 0x00000afd, 0x0002f86f, 0x00000afe, 0x0002f870, 0x00000aff, 0x0002f871, 0x00000b00, 0x0002f872, 0x00000b01, 0x0002f873, 0x00000b02, 0x0002f874, 0x00000b03, 0x0002f875, 0x00000b04, 0x0002f876, 0x00000b05, 0x0002f877, 0x00000b06, 0x0002f878, 0x00000b07, 0x0002f879, 0x00000b08, 0x0002f87a, 0x00000b09, 0x0002f87b, 0x00000b0a, 0x0002f87c, 0x00000b0b, 0x0002f87d, 0x00000b0c, 0x0002f87e, 0x00000b0d, 0x0002f87f, 0x00000b0e, 0x0002f880, 0x00000b0f, 0x0002f881, 0x00000b10, 0x0002f882, 0x00000b11, 0x0002f883, 0x00000b12, 0x0002f884, 0x00000b13, 0x0002f885, 0x00000b14, 0x0002f886, 0x00000b15, 0x0002f887, 0x00000b16, 0x0002f888, 0x00000b17, 0x0002f889, 0x00000b18, 0x0002f88a, 0x00000b19, 0x0002f88b, 0x00000b1a, 0x0002f88c, 0x00000b1b, 0x0002f88d, 0x00000b1c, 0x0002f88e, 0x00000b1d, 0x0002f88f, 0x00000b1e, 0x0002f890, 0x00000b1f, 0x0002f891, 0x00000b20, 0x0002f892, 0x00000b21, 0x0002f893, 0x00000b22, 0x0002f894, 0x00000b23, 0x0002f895, 0x00000b24, 0x0002f896, 0x00000b25, 0x0002f897, 0x00000b26, 0x0002f898, 0x00000b27, 0x0002f899, 0x00000b28, 0x0002f89a, 0x00000b29, 0x0002f89b, 0x00000b2a, 0x0002f89c, 0x00000b2b, 0x0002f89d, 0x00000b2c, 0x0002f89e, 0x00000b2d, 0x0002f89f, 0x00000b2e, 0x0002f8a0, 0x00000b2f, 0x0002f8a1, 0x00000b30, 0x0002f8a2, 0x00000b31, 0x0002f8a3, 0x00000b32, 0x0002f8a4, 0x00000b33, 0x0002f8a5, 0x00000b34, 0x0002f8a6, 0x00000b35, 0x0002f8a7, 0x00000b36, 0x0002f8a8, 0x00000b37, 0x0002f8a9, 0x00000b38, 0x0002f8aa, 0x00000b39, 0x0002f8ab, 0x00000b3a, 0x0002f8ac, 0x00000b3b, 0x0002f8ad, 0x00000b3c, 0x0002f8ae, 0x00000b3d, 0x0002f8af, 0x00000b3e, 0x0002f8b0, 0x00000b3f, 0x0002f8b1, 0x00000b40, 0x0002f8b2, 0x00000b41, 0x0002f8b3, 0x00000b42, 0x0002f8b4, 0x00000b43, 0x0002f8b5, 0x00000b44, 0x0002f8b6, 0x00000b45, 0x0002f8b7, 0x00000b46, 0x0002f8b8, 0x00000b47, 0x0002f8b9, 0x00000b48, 0x0002f8ba, 0x00000b49, 0x0002f8bb, 0x00000b4a, 0x0002f8bc, 0x00000b4b, 0x0002f8bd, 0x00000b4c, 0x0002f8be, 0x00000b4d, 0x0002f8bf, 0x00000b4e, 0x0002f8c0, 0x00000b4f, 0x0002f8c1, 0x00000b50, 0x0002f8c2, 0x00000b51, 0x0002f8c3, 0x00000b52, 0x0002f8c4, 0x00000b53, 0x0002f8c5, 0x00000b54, 0x0002f8c6, 0x00000b55, 0x0002f8c7, 0x00000b56, 0x0002f8c8, 0x00000b57, 0x0002f8c9, 0x00000b58, 0x0002f8ca, 0x00000b59, 0x0002f8cb, 0x00000b5a, 0x0002f8cc, 0x00000b5b, 0x0002f8cd, 0x00000b5c, 0x0002f8ce, 0x00000b5d, 0x0002f8cf, 0x00000b5e, 0x0002f8d0, 0x00000b5f, 0x0002f8d1, 0x00000b60, 0x0002f8d2, 0x00000b61, 0x0002f8d3, 0x00000b62, 0x0002f8d4, 0x00000b63, 0x0002f8d5, 0x00000b64, 0x0002f8d6, 0x00000b65, 0x0002f8d7, 0x00000b66, 0x0002f8d8, 0x00000b67, 0x0002f8d9, 0x00000b68, 0x0002f8da, 0x00000b69, 0x0002f8db, 0x00000b6a, 0x0002f8dc, 0x00000b6b, 0x0002f8dd, 0x00000b6c, 0x0002f8de, 0x00000b6d, 0x0002f8df, 0x00000b6e, 0x0002f8e0, 0x00000b6f, 0x0002f8e1, 0x00000b70, 0x0002f8e2, 0x00000b71, 0x0002f8e3, 0x00000b72, 0x0002f8e4, 0x00000b73, 0x0002f8e5, 0x00000b74, 0x0002f8e6, 0x00000b75, 0x0002f8e7, 0x00000b76, 0x0002f8e8, 0x00000b77, 0x0002f8e9, 0x00000b78, 0x0002f8ea, 0x00000b79, 0x0002f8eb, 0x00000b7a, 0x0002f8ec, 0x00000b7b, 0x0002f8ed, 0x00000b7c, 0x0002f8ee, 0x00000b7d, 0x0002f8ef, 0x00000b7e, 0x0002f8f0, 0x00000b7f, 0x0002f8f1, 0x00000b80, 0x0002f8f2, 0x00000b81, 0x0002f8f3, 0x00000b82, 0x0002f8f4, 0x00000b83, 0x0002f8f5, 0x00000b84, 0x0002f8f6, 0x00000b85, 0x0002f8f7, 0x00000b86, 0x0002f8f8, 0x00000b87, 0x0002f8f9, 0x00000b88, 0x0002f8fa, 0x00000b89, 0x0002f8fb, 0x00000b8a, 0x0002f8fc, 0x00000b8b, 0x0002f8fd, 0x00000b8c, 0x0002f8fe, 0x00000b8d, 0x0002f8ff, 0x00000b8e, 0x0002f900, 0x00000b8f, 0x0002f901, 0x00000b90, 0x0002f902, 0x00000b91, 0x0002f903, 0x00000b92, 0x0002f904, 0x00000b93, 0x0002f905, 0x00000b94, 0x0002f906, 0x00000b95, 0x0002f907, 0x00000b96, 0x0002f908, 0x00000b97, 0x0002f909, 0x00000b98, 0x0002f90a, 0x00000b99, 0x0002f90b, 0x00000b9a, 0x0002f90c, 0x00000b9b, 0x0002f90d, 0x00000b9c, 0x0002f90e, 0x00000b9d, 0x0002f90f, 0x00000b9e, 0x0002f910, 0x00000b9f, 0x0002f911, 0x00000ba0, 0x0002f912, 0x00000ba1, 0x0002f913, 0x00000ba2, 0x0002f914, 0x00000ba3, 0x0002f915, 0x00000ba4, 0x0002f916, 0x00000ba5, 0x0002f917, 0x00000ba6, 0x0002f918, 0x00000ba7, 0x0002f919, 0x00000ba8, 0x0002f91a, 0x00000ba9, 0x0002f91b, 0x00000baa, 0x0002f91c, 0x00000bab, 0x0002f91d, 0x00000bac, 0x0002f91e, 0x00000bad, 0x0002f91f, 0x00000bae, 0x0002f920, 0x00000baf, 0x0002f921, 0x00000bb0, 0x0002f922, 0x00000bb1, 0x0002f923, 0x00000bb2, 0x0002f924, 0x00000bb3, 0x0002f925, 0x00000bb4, 0x0002f926, 0x00000bb5, 0x0002f927, 0x00000bb6, 0x0002f928, 0x00000bb7, 0x0002f929, 0x00000bb8, 0x0002f92a, 0x00000bb9, 0x0002f92b, 0x00000bba, 0x0002f92c, 0x00000bbb, 0x0002f92d, 0x00000bbc, 0x0002f92e, 0x00000bbd, 0x0002f92f, 0x00000bbe, 0x0002f930, 0x00000bbf, 0x0002f931, 0x00000bc0, 0x0002f932, 0x00000bc1, 0x0002f933, 0x00000bc2, 0x0002f934, 0x00000bc3, 0x0002f935, 0x00000bc4, 0x0002f936, 0x00000bc5, 0x0002f937, 0x00000bc6, 0x0002f938, 0x00000bc7, 0x0002f939, 0x00000bc8, 0x0002f93a, 0x00000bc9, 0x0002f93b, 0x00000bca, 0x0002f93c, 0x00000bcb, 0x0002f93d, 0x00000bcc, 0x0002f93e, 0x00000bcd, 0x0002f93f, 0x00000bce, 0x0002f940, 0x00000bcf, 0x0002f941, 0x00000bd0, 0x0002f942, 0x00000bd1, 0x0002f943, 0x00000bd2, 0x0002f944, 0x00000bd3, 0x0002f945, 0x00000bd4, 0x0002f946, 0x00000bd5, 0x0002f947, 0x00000bd6, 0x0002f948, 0x00000bd7, 0x0002f949, 0x00000bd8, 0x0002f94a, 0x00000bd9, 0x0002f94b, 0x00000bda, 0x0002f94c, 0x00000bdb, 0x0002f94d, 0x00000bdc, 0x0002f94e, 0x00000bdd, 0x0002f94f, 0x00000bde, 0x0002f950, 0x00000bdf, 0x0002f951, 0x00000be0, 0x0002f952, 0x00000be1, 0x0002f953, 0x00000be2, 0x0002f954, 0x00000be3, 0x0002f955, 0x00000be4, 0x0002f956, 0x00000be5, 0x0002f957, 0x00000be6, 0x0002f958, 0x00000be7, 0x0002f959, 0x00000be8, 0x0002f95a, 0x00000be9, 0x0002f95b, 0x00000bea, 0x0002f95c, 0x00000beb, 0x0002f95d, 0x00000bec, 0x0002f95e, 0x00000bed, 0x0002f95f, 0x00000bee, 0x0002f960, 0x00000bef, 0x0002f961, 0x00000bf0, 0x0002f962, 0x00000bf1, 0x0002f963, 0x00000bf2, 0x0002f964, 0x00000bf3, 0x0002f965, 0x00000bf4, 0x0002f966, 0x00000bf5, 0x0002f967, 0x00000bf6, 0x0002f968, 0x00000bf7, 0x0002f969, 0x00000bf8, 0x0002f96a, 0x00000bf9, 0x0002f96b, 0x00000bfa, 0x0002f96c, 0x00000bfb, 0x0002f96d, 0x00000bfc, 0x0002f96e, 0x00000bfd, 0x0002f96f, 0x00000bfe, 0x0002f970, 0x00000bff, 0x0002f971, 0x00000c00, 0x0002f972, 0x00000c01, 0x0002f973, 0x00000c02, 0x0002f974, 0x00000c03, 0x0002f975, 0x00000c04, 0x0002f976, 0x00000c05, 0x0002f977, 0x00000c06, 0x0002f978, 0x00000c07, 0x0002f979, 0x00000c08, 0x0002f97a, 0x00000c09, 0x0002f97b, 0x00000c0a, 0x0002f97c, 0x00000c0b, 0x0002f97d, 0x00000c0c, 0x0002f97e, 0x00000c0d, 0x0002f97f, 0x00000c0e, 0x0002f980, 0x00000c0f, 0x0002f981, 0x00000c10, 0x0002f982, 0x00000c11, 0x0002f983, 0x00000c12, 0x0002f984, 0x00000c13, 0x0002f985, 0x00000c14, 0x0002f986, 0x00000c15, 0x0002f987, 0x00000c16, 0x0002f988, 0x00000c17, 0x0002f989, 0x00000c18, 0x0002f98a, 0x00000c19, 0x0002f98b, 0x00000c1a, 0x0002f98c, 0x00000c1b, 0x0002f98d, 0x00000c1c, 0x0002f98e, 0x00000c1d, 0x0002f98f, 0x00000c1e, 0x0002f990, 0x00000c1f, 0x0002f991, 0x00000c20, 0x0002f992, 0x00000c21, 0x0002f993, 0x00000c22, 0x0002f994, 0x00000c23, 0x0002f995, 0x00000c24, 0x0002f996, 0x00000c25, 0x0002f997, 0x00000c26, 0x0002f998, 0x00000c27, 0x0002f999, 0x00000c28, 0x0002f99a, 0x00000c29, 0x0002f99b, 0x00000c2a, 0x0002f99c, 0x00000c2b, 0x0002f99d, 0x00000c2c, 0x0002f99e, 0x00000c2d, 0x0002f99f, 0x00000c2e, 0x0002f9a0, 0x00000c2f, 0x0002f9a1, 0x00000c30, 0x0002f9a2, 0x00000c31, 0x0002f9a3, 0x00000c32, 0x0002f9a4, 0x00000c33, 0x0002f9a5, 0x00000c34, 0x0002f9a6, 0x00000c35, 0x0002f9a7, 0x00000c36, 0x0002f9a8, 0x00000c37, 0x0002f9a9, 0x00000c38, 0x0002f9aa, 0x00000c39, 0x0002f9ab, 0x00000c3a, 0x0002f9ac, 0x00000c3b, 0x0002f9ad, 0x00000c3c, 0x0002f9ae, 0x00000c3d, 0x0002f9af, 0x00000c3e, 0x0002f9b0, 0x00000c3f, 0x0002f9b1, 0x00000c40, 0x0002f9b2, 0x00000c41, 0x0002f9b3, 0x00000c42, 0x0002f9b4, 0x00000c43, 0x0002f9b5, 0x00000c44, 0x0002f9b6, 0x00000c45, 0x0002f9b7, 0x00000c46, 0x0002f9b8, 0x00000c47, 0x0002f9b9, 0x00000c48, 0x0002f9ba, 0x00000c49, 0x0002f9bb, 0x00000c4a, 0x0002f9bc, 0x00000c4b, 0x0002f9bd, 0x00000c4c, 0x0002f9be, 0x00000c4d, 0x0002f9bf, 0x00000c4e, 0x0002f9c0, 0x00000c4f, 0x0002f9c1, 0x00000c50, 0x0002f9c2, 0x00000c51, 0x0002f9c3, 0x00000c52, 0x0002f9c4, 0x00000c53, 0x0002f9c5, 0x00000c54, 0x0002f9c6, 0x00000c55, 0x0002f9c7, 0x00000c56, 0x0002f9c8, 0x00000c57, 0x0002f9c9, 0x00000c58, 0x0002f9ca, 0x00000c59, 0x0002f9cb, 0x00000c5a, 0x0002f9cc, 0x00000c5b, 0x0002f9cd, 0x00000c5c, 0x0002f9ce, 0x00000c5d, 0x0002f9cf, 0x00000c5e, 0x0002f9d0, 0x00000c5f, 0x0002f9d1, 0x00000c60, 0x0002f9d2, 0x00000c61, 0x0002f9d3, 0x00000c62, 0x0002f9d4, 0x00000c63, 0x0002f9d5, 0x00000c64, 0x0002f9d6, 0x00000c65, 0x0002f9d7, 0x00000c66, 0x0002f9d8, 0x00000c67, 0x0002f9d9, 0x00000c68, 0x0002f9da, 0x00000c69, 0x0002f9db, 0x00000c6a, 0x0002f9dc, 0x00000c6b, 0x0002f9dd, 0x00000c6c, 0x0002f9de, 0x00000c6d, 0x0002f9df, 0x00000c6e, 0x0002f9e0, 0x00000c6f, 0x0002f9e1, 0x00000c70, 0x0002f9e2, 0x00000c71, 0x0002f9e3, 0x00000c72, 0x0002f9e4, 0x00000c73, 0x0002f9e5, 0x00000c74, 0x0002f9e6, 0x00000c75, 0x0002f9e7, 0x00000c76, 0x0002f9e8, 0x00000c77, 0x0002f9e9, 0x00000c78, 0x0002f9ea, 0x00000c79, 0x0002f9eb, 0x00000c7a, 0x0002f9ec, 0x00000c7b, 0x0002f9ed, 0x00000c7c, 0x0002f9ee, 0x00000c7d, 0x0002f9ef, 0x00000c7e, 0x0002f9f0, 0x00000c7f, 0x0002f9f1, 0x00000c80, 0x0002f9f2, 0x00000c81, 0x0002f9f3, 0x00000c82, 0x0002f9f4, 0x00000c83, 0x0002f9f5, 0x00000c84, 0x0002f9f6, 0x00000c85, 0x0002f9f7, 0x00000c86, 0x0002f9f8, 0x00000c87, 0x0002f9f9, 0x00000c88, 0x0002f9fa, 0x00000c89, 0x0002f9fb, 0x00000c8a, 0x0002f9fc, 0x00000c8b, 0x0002f9fd, 0x00000c8c, 0x0002f9fe, 0x00000c8d, 0x0002f9ff, 0x00000c8e, 0x0002fa00, 0x00000c8f, 0x0002fa01, 0x00000c90, 0x0002fa02, 0x00000c91, 0x0002fa03, 0x00000c92, 0x0002fa04, 0x00000c93, 0x0002fa05, 0x00000c94, 0x0002fa06, 0x00000c95, 0x0002fa07, 0x00000c96, 0x0002fa08, 0x00000c97, 0x0002fa09, 0x00000c98, 0x0002fa0a, 0x00000c99, 0x0002fa0b, 0x00000c9a, 0x0002fa0c, 0x00000c9b, 0x0002fa0d, 0x00000c9c, 0x0002fa0e, 0x00000c9d, 0x0002fa0f, 0x00000c9e, 0x0002fa10, 0x00000c9f, 0x0002fa11, 0x00000ca0, 0x0002fa12, 0x00000ca1, 0x0002fa13, 0x00000ca2, 0x0002fa14, 0x00000ca3, 0x0002fa15, 0x00000ca4, 0x0002fa16, 0x00000ca5, 0x0002fa17, 0x00000ca6, 0x0002fa18, 0x00000ca7, 0x0002fa19, 0x00000ca8, 0x0002fa1a, 0x00000ca9, 0x0002fa1b, 0x00000caa, 0x0002fa1c, 0x00000cab, 0x0002fa1d, 0x00000cac, 0x00000cad }; static const krb5_ui_4 _ucdcmp_decomp[] = { 0x00000041, 0x00000300, 0x00000041, 0x00000301, 0x00000041, 0x00000302, 0x00000041, 0x00000303, 0x00000041, 0x00000308, 0x00000041, 0x0000030a, 0x00000043, 0x00000327, 0x00000045, 0x00000300, 0x00000045, 0x00000301, 0x00000045, 0x00000302, 0x00000045, 0x00000308, 0x00000049, 0x00000300, 0x00000049, 0x00000301, 0x00000049, 0x00000302, 0x00000049, 0x00000308, 0x0000004e, 0x00000303, 0x0000004f, 0x00000300, 0x0000004f, 0x00000301, 0x0000004f, 0x00000302, 0x0000004f, 0x00000303, 0x0000004f, 0x00000308, 0x00000055, 0x00000300, 0x00000055, 0x00000301, 0x00000055, 0x00000302, 0x00000055, 0x00000308, 0x00000059, 0x00000301, 0x00000061, 0x00000300, 0x00000061, 0x00000301, 0x00000061, 0x00000302, 0x00000061, 0x00000303, 0x00000061, 0x00000308, 0x00000061, 0x0000030a, 0x00000063, 0x00000327, 0x00000065, 0x00000300, 0x00000065, 0x00000301, 0x00000065, 0x00000302, 0x00000065, 0x00000308, 0x00000069, 0x00000300, 0x00000069, 0x00000301, 0x00000069, 0x00000302, 0x00000069, 0x00000308, 0x0000006e, 0x00000303, 0x0000006f, 0x00000300, 0x0000006f, 0x00000301, 0x0000006f, 0x00000302, 0x0000006f, 0x00000303, 0x0000006f, 0x00000308, 0x00000075, 0x00000300, 0x00000075, 0x00000301, 0x00000075, 0x00000302, 0x00000075, 0x00000308, 0x00000079, 0x00000301, 0x00000079, 0x00000308, 0x00000041, 0x00000304, 0x00000061, 0x00000304, 0x00000041, 0x00000306, 0x00000061, 0x00000306, 0x00000041, 0x00000328, 0x00000061, 0x00000328, 0x00000043, 0x00000301, 0x00000063, 0x00000301, 0x00000043, 0x00000302, 0x00000063, 0x00000302, 0x00000043, 0x00000307, 0x00000063, 0x00000307, 0x00000043, 0x0000030c, 0x00000063, 0x0000030c, 0x00000044, 0x0000030c, 0x00000064, 0x0000030c, 0x00000045, 0x00000304, 0x00000065, 0x00000304, 0x00000045, 0x00000306, 0x00000065, 0x00000306, 0x00000045, 0x00000307, 0x00000065, 0x00000307, 0x00000045, 0x00000328, 0x00000065, 0x00000328, 0x00000045, 0x0000030c, 0x00000065, 0x0000030c, 0x00000047, 0x00000302, 0x00000067, 0x00000302, 0x00000047, 0x00000306, 0x00000067, 0x00000306, 0x00000047, 0x00000307, 0x00000067, 0x00000307, 0x00000047, 0x00000327, 0x00000067, 0x00000327, 0x00000048, 0x00000302, 0x00000068, 0x00000302, 0x00000049, 0x00000303, 0x00000069, 0x00000303, 0x00000049, 0x00000304, 0x00000069, 0x00000304, 0x00000049, 0x00000306, 0x00000069, 0x00000306, 0x00000049, 0x00000328, 0x00000069, 0x00000328, 0x00000049, 0x00000307, 0x0000004a, 0x00000302, 0x0000006a, 0x00000302, 0x0000004b, 0x00000327, 0x0000006b, 0x00000327, 0x0000004c, 0x00000301, 0x0000006c, 0x00000301, 0x0000004c, 0x00000327, 0x0000006c, 0x00000327, 0x0000004c, 0x0000030c, 0x0000006c, 0x0000030c, 0x0000004e, 0x00000301, 0x0000006e, 0x00000301, 0x0000004e, 0x00000327, 0x0000006e, 0x00000327, 0x0000004e, 0x0000030c, 0x0000006e, 0x0000030c, 0x0000004f, 0x00000304, 0x0000006f, 0x00000304, 0x0000004f, 0x00000306, 0x0000006f, 0x00000306, 0x0000004f, 0x0000030b, 0x0000006f, 0x0000030b, 0x00000052, 0x00000301, 0x00000072, 0x00000301, 0x00000052, 0x00000327, 0x00000072, 0x00000327, 0x00000052, 0x0000030c, 0x00000072, 0x0000030c, 0x00000053, 0x00000301, 0x00000073, 0x00000301, 0x00000053, 0x00000302, 0x00000073, 0x00000302, 0x00000053, 0x00000327, 0x00000073, 0x00000327, 0x00000053, 0x0000030c, 0x00000073, 0x0000030c, 0x00000054, 0x00000327, 0x00000074, 0x00000327, 0x00000054, 0x0000030c, 0x00000074, 0x0000030c, 0x00000055, 0x00000303, 0x00000075, 0x00000303, 0x00000055, 0x00000304, 0x00000075, 0x00000304, 0x00000055, 0x00000306, 0x00000075, 0x00000306, 0x00000055, 0x0000030a, 0x00000075, 0x0000030a, 0x00000055, 0x0000030b, 0x00000075, 0x0000030b, 0x00000055, 0x00000328, 0x00000075, 0x00000328, 0x00000057, 0x00000302, 0x00000077, 0x00000302, 0x00000059, 0x00000302, 0x00000079, 0x00000302, 0x00000059, 0x00000308, 0x0000005a, 0x00000301, 0x0000007a, 0x00000301, 0x0000005a, 0x00000307, 0x0000007a, 0x00000307, 0x0000005a, 0x0000030c, 0x0000007a, 0x0000030c, 0x0000004f, 0x0000031b, 0x0000006f, 0x0000031b, 0x00000055, 0x0000031b, 0x00000075, 0x0000031b, 0x00000041, 0x0000030c, 0x00000061, 0x0000030c, 0x00000049, 0x0000030c, 0x00000069, 0x0000030c, 0x0000004f, 0x0000030c, 0x0000006f, 0x0000030c, 0x00000055, 0x0000030c, 0x00000075, 0x0000030c, 0x00000055, 0x00000308, 0x00000304, 0x00000075, 0x00000308, 0x00000304, 0x00000055, 0x00000308, 0x00000301, 0x00000075, 0x00000308, 0x00000301, 0x00000055, 0x00000308, 0x0000030c, 0x00000075, 0x00000308, 0x0000030c, 0x00000055, 0x00000308, 0x00000300, 0x00000075, 0x00000308, 0x00000300, 0x00000041, 0x00000308, 0x00000304, 0x00000061, 0x00000308, 0x00000304, 0x00000041, 0x00000307, 0x00000304, 0x00000061, 0x00000307, 0x00000304, 0x000000c6, 0x00000304, 0x000000e6, 0x00000304, 0x00000047, 0x0000030c, 0x00000067, 0x0000030c, 0x0000004b, 0x0000030c, 0x0000006b, 0x0000030c, 0x0000004f, 0x00000328, 0x0000006f, 0x00000328, 0x0000004f, 0x00000328, 0x00000304, 0x0000006f, 0x00000328, 0x00000304, 0x000001b7, 0x0000030c, 0x00000292, 0x0000030c, 0x0000006a, 0x0000030c, 0x00000047, 0x00000301, 0x00000067, 0x00000301, 0x0000004e, 0x00000300, 0x0000006e, 0x00000300, 0x00000041, 0x0000030a, 0x00000301, 0x00000061, 0x0000030a, 0x00000301, 0x000000c6, 0x00000301, 0x000000e6, 0x00000301, 0x000000d8, 0x00000301, 0x000000f8, 0x00000301, 0x00000041, 0x0000030f, 0x00000061, 0x0000030f, 0x00000041, 0x00000311, 0x00000061, 0x00000311, 0x00000045, 0x0000030f, 0x00000065, 0x0000030f, 0x00000045, 0x00000311, 0x00000065, 0x00000311, 0x00000049, 0x0000030f, 0x00000069, 0x0000030f, 0x00000049, 0x00000311, 0x00000069, 0x00000311, 0x0000004f, 0x0000030f, 0x0000006f, 0x0000030f, 0x0000004f, 0x00000311, 0x0000006f, 0x00000311, 0x00000052, 0x0000030f, 0x00000072, 0x0000030f, 0x00000052, 0x00000311, 0x00000072, 0x00000311, 0x00000055, 0x0000030f, 0x00000075, 0x0000030f, 0x00000055, 0x00000311, 0x00000075, 0x00000311, 0x00000053, 0x00000326, 0x00000073, 0x00000326, 0x00000054, 0x00000326, 0x00000074, 0x00000326, 0x00000048, 0x0000030c, 0x00000068, 0x0000030c, 0x00000041, 0x00000307, 0x00000061, 0x00000307, 0x00000045, 0x00000327, 0x00000065, 0x00000327, 0x0000004f, 0x00000308, 0x00000304, 0x0000006f, 0x00000308, 0x00000304, 0x0000004f, 0x00000303, 0x00000304, 0x0000006f, 0x00000303, 0x00000304, 0x0000004f, 0x00000307, 0x0000006f, 0x00000307, 0x0000004f, 0x00000307, 0x00000304, 0x0000006f, 0x00000307, 0x00000304, 0x00000059, 0x00000304, 0x00000079, 0x00000304, 0x00000300, 0x00000301, 0x00000313, 0x00000308, 0x00000301, 0x000002b9, 0x0000003b, 0x000000a8, 0x00000301, 0x00000391, 0x00000301, 0x000000b7, 0x00000395, 0x00000301, 0x00000397, 0x00000301, 0x00000399, 0x00000301, 0x0000039f, 0x00000301, 0x000003a5, 0x00000301, 0x000003a9, 0x00000301, 0x000003b9, 0x00000308, 0x00000301, 0x00000399, 0x00000308, 0x000003a5, 0x00000308, 0x000003b1, 0x00000301, 0x000003b5, 0x00000301, 0x000003b7, 0x00000301, 0x000003b9, 0x00000301, 0x000003c5, 0x00000308, 0x00000301, 0x000003b9, 0x00000308, 0x000003c5, 0x00000308, 0x000003bf, 0x00000301, 0x000003c5, 0x00000301, 0x000003c9, 0x00000301, 0x000003d2, 0x00000301, 0x000003d2, 0x00000308, 0x00000415, 0x00000300, 0x00000415, 0x00000308, 0x00000413, 0x00000301, 0x00000406, 0x00000308, 0x0000041a, 0x00000301, 0x00000418, 0x00000300, 0x00000423, 0x00000306, 0x00000418, 0x00000306, 0x00000438, 0x00000306, 0x00000435, 0x00000300, 0x00000435, 0x00000308, 0x00000433, 0x00000301, 0x00000456, 0x00000308, 0x0000043a, 0x00000301, 0x00000438, 0x00000300, 0x00000443, 0x00000306, 0x00000474, 0x0000030f, 0x00000475, 0x0000030f, 0x00000416, 0x00000306, 0x00000436, 0x00000306, 0x00000410, 0x00000306, 0x00000430, 0x00000306, 0x00000410, 0x00000308, 0x00000430, 0x00000308, 0x00000415, 0x00000306, 0x00000435, 0x00000306, 0x000004d8, 0x00000308, 0x000004d9, 0x00000308, 0x00000416, 0x00000308, 0x00000436, 0x00000308, 0x00000417, 0x00000308, 0x00000437, 0x00000308, 0x00000418, 0x00000304, 0x00000438, 0x00000304, 0x00000418, 0x00000308, 0x00000438, 0x00000308, 0x0000041e, 0x00000308, 0x0000043e, 0x00000308, 0x000004e8, 0x00000308, 0x000004e9, 0x00000308, 0x0000042d, 0x00000308, 0x0000044d, 0x00000308, 0x00000423, 0x00000304, 0x00000443, 0x00000304, 0x00000423, 0x00000308, 0x00000443, 0x00000308, 0x00000423, 0x0000030b, 0x00000443, 0x0000030b, 0x00000427, 0x00000308, 0x00000447, 0x00000308, 0x0000042b, 0x00000308, 0x0000044b, 0x00000308, 0x00000627, 0x00000653, 0x00000627, 0x00000654, 0x00000648, 0x00000654, 0x00000627, 0x00000655, 0x0000064a, 0x00000654, 0x000006d5, 0x00000654, 0x000006c1, 0x00000654, 0x000006d2, 0x00000654, 0x00000928, 0x0000093c, 0x00000930, 0x0000093c, 0x00000933, 0x0000093c, 0x00000915, 0x0000093c, 0x00000916, 0x0000093c, 0x00000917, 0x0000093c, 0x0000091c, 0x0000093c, 0x00000921, 0x0000093c, 0x00000922, 0x0000093c, 0x0000092b, 0x0000093c, 0x0000092f, 0x0000093c, 0x000009c7, 0x000009be, 0x000009c7, 0x000009d7, 0x000009a1, 0x000009bc, 0x000009a2, 0x000009bc, 0x000009af, 0x000009bc, 0x00000a32, 0x00000a3c, 0x00000a38, 0x00000a3c, 0x00000a16, 0x00000a3c, 0x00000a17, 0x00000a3c, 0x00000a1c, 0x00000a3c, 0x00000a2b, 0x00000a3c, 0x00000b47, 0x00000b56, 0x00000b47, 0x00000b3e, 0x00000b47, 0x00000b57, 0x00000b21, 0x00000b3c, 0x00000b22, 0x00000b3c, 0x00000b92, 0x00000bd7, 0x00000bc6, 0x00000bbe, 0x00000bc7, 0x00000bbe, 0x00000bc6, 0x00000bd7, 0x00000c46, 0x00000c56, 0x00000cbf, 0x00000cd5, 0x00000cc6, 0x00000cd5, 0x00000cc6, 0x00000cd6, 0x00000cc6, 0x00000cc2, 0x00000cc6, 0x00000cc2, 0x00000cd5, 0x00000d46, 0x00000d3e, 0x00000d47, 0x00000d3e, 0x00000d46, 0x00000d57, 0x00000dd9, 0x00000dca, 0x00000dd9, 0x00000dcf, 0x00000dd9, 0x00000dcf, 0x00000dca, 0x00000dd9, 0x00000ddf, 0x00000f42, 0x00000fb7, 0x00000f4c, 0x00000fb7, 0x00000f51, 0x00000fb7, 0x00000f56, 0x00000fb7, 0x00000f5b, 0x00000fb7, 0x00000f40, 0x00000fb5, 0x00000f71, 0x00000f72, 0x00000f71, 0x00000f74, 0x00000fb2, 0x00000f80, 0x00000fb3, 0x00000f80, 0x00000f71, 0x00000f80, 0x00000f92, 0x00000fb7, 0x00000f9c, 0x00000fb7, 0x00000fa1, 0x00000fb7, 0x00000fa6, 0x00000fb7, 0x00000fab, 0x00000fb7, 0x00000f90, 0x00000fb5, 0x00001025, 0x0000102e, 0x00000041, 0x00000325, 0x00000061, 0x00000325, 0x00000042, 0x00000307, 0x00000062, 0x00000307, 0x00000042, 0x00000323, 0x00000062, 0x00000323, 0x00000042, 0x00000331, 0x00000062, 0x00000331, 0x00000043, 0x00000327, 0x00000301, 0x00000063, 0x00000327, 0x00000301, 0x00000044, 0x00000307, 0x00000064, 0x00000307, 0x00000044, 0x00000323, 0x00000064, 0x00000323, 0x00000044, 0x00000331, 0x00000064, 0x00000331, 0x00000044, 0x00000327, 0x00000064, 0x00000327, 0x00000044, 0x0000032d, 0x00000064, 0x0000032d, 0x00000045, 0x00000304, 0x00000300, 0x00000065, 0x00000304, 0x00000300, 0x00000045, 0x00000304, 0x00000301, 0x00000065, 0x00000304, 0x00000301, 0x00000045, 0x0000032d, 0x00000065, 0x0000032d, 0x00000045, 0x00000330, 0x00000065, 0x00000330, 0x00000045, 0x00000327, 0x00000306, 0x00000065, 0x00000327, 0x00000306, 0x00000046, 0x00000307, 0x00000066, 0x00000307, 0x00000047, 0x00000304, 0x00000067, 0x00000304, 0x00000048, 0x00000307, 0x00000068, 0x00000307, 0x00000048, 0x00000323, 0x00000068, 0x00000323, 0x00000048, 0x00000308, 0x00000068, 0x00000308, 0x00000048, 0x00000327, 0x00000068, 0x00000327, 0x00000048, 0x0000032e, 0x00000068, 0x0000032e, 0x00000049, 0x00000330, 0x00000069, 0x00000330, 0x00000049, 0x00000308, 0x00000301, 0x00000069, 0x00000308, 0x00000301, 0x0000004b, 0x00000301, 0x0000006b, 0x00000301, 0x0000004b, 0x00000323, 0x0000006b, 0x00000323, 0x0000004b, 0x00000331, 0x0000006b, 0x00000331, 0x0000004c, 0x00000323, 0x0000006c, 0x00000323, 0x0000004c, 0x00000323, 0x00000304, 0x0000006c, 0x00000323, 0x00000304, 0x0000004c, 0x00000331, 0x0000006c, 0x00000331, 0x0000004c, 0x0000032d, 0x0000006c, 0x0000032d, 0x0000004d, 0x00000301, 0x0000006d, 0x00000301, 0x0000004d, 0x00000307, 0x0000006d, 0x00000307, 0x0000004d, 0x00000323, 0x0000006d, 0x00000323, 0x0000004e, 0x00000307, 0x0000006e, 0x00000307, 0x0000004e, 0x00000323, 0x0000006e, 0x00000323, 0x0000004e, 0x00000331, 0x0000006e, 0x00000331, 0x0000004e, 0x0000032d, 0x0000006e, 0x0000032d, 0x0000004f, 0x00000303, 0x00000301, 0x0000006f, 0x00000303, 0x00000301, 0x0000004f, 0x00000303, 0x00000308, 0x0000006f, 0x00000303, 0x00000308, 0x0000004f, 0x00000304, 0x00000300, 0x0000006f, 0x00000304, 0x00000300, 0x0000004f, 0x00000304, 0x00000301, 0x0000006f, 0x00000304, 0x00000301, 0x00000050, 0x00000301, 0x00000070, 0x00000301, 0x00000050, 0x00000307, 0x00000070, 0x00000307, 0x00000052, 0x00000307, 0x00000072, 0x00000307, 0x00000052, 0x00000323, 0x00000072, 0x00000323, 0x00000052, 0x00000323, 0x00000304, 0x00000072, 0x00000323, 0x00000304, 0x00000052, 0x00000331, 0x00000072, 0x00000331, 0x00000053, 0x00000307, 0x00000073, 0x00000307, 0x00000053, 0x00000323, 0x00000073, 0x00000323, 0x00000053, 0x00000301, 0x00000307, 0x00000073, 0x00000301, 0x00000307, 0x00000053, 0x0000030c, 0x00000307, 0x00000073, 0x0000030c, 0x00000307, 0x00000053, 0x00000323, 0x00000307, 0x00000073, 0x00000323, 0x00000307, 0x00000054, 0x00000307, 0x00000074, 0x00000307, 0x00000054, 0x00000323, 0x00000074, 0x00000323, 0x00000054, 0x00000331, 0x00000074, 0x00000331, 0x00000054, 0x0000032d, 0x00000074, 0x0000032d, 0x00000055, 0x00000324, 0x00000075, 0x00000324, 0x00000055, 0x00000330, 0x00000075, 0x00000330, 0x00000055, 0x0000032d, 0x00000075, 0x0000032d, 0x00000055, 0x00000303, 0x00000301, 0x00000075, 0x00000303, 0x00000301, 0x00000055, 0x00000304, 0x00000308, 0x00000075, 0x00000304, 0x00000308, 0x00000056, 0x00000303, 0x00000076, 0x00000303, 0x00000056, 0x00000323, 0x00000076, 0x00000323, 0x00000057, 0x00000300, 0x00000077, 0x00000300, 0x00000057, 0x00000301, 0x00000077, 0x00000301, 0x00000057, 0x00000308, 0x00000077, 0x00000308, 0x00000057, 0x00000307, 0x00000077, 0x00000307, 0x00000057, 0x00000323, 0x00000077, 0x00000323, 0x00000058, 0x00000307, 0x00000078, 0x00000307, 0x00000058, 0x00000308, 0x00000078, 0x00000308, 0x00000059, 0x00000307, 0x00000079, 0x00000307, 0x0000005a, 0x00000302, 0x0000007a, 0x00000302, 0x0000005a, 0x00000323, 0x0000007a, 0x00000323, 0x0000005a, 0x00000331, 0x0000007a, 0x00000331, 0x00000068, 0x00000331, 0x00000074, 0x00000308, 0x00000077, 0x0000030a, 0x00000079, 0x0000030a, 0x0000017f, 0x00000307, 0x00000041, 0x00000323, 0x00000061, 0x00000323, 0x00000041, 0x00000309, 0x00000061, 0x00000309, 0x00000041, 0x00000302, 0x00000301, 0x00000061, 0x00000302, 0x00000301, 0x00000041, 0x00000302, 0x00000300, 0x00000061, 0x00000302, 0x00000300, 0x00000041, 0x00000302, 0x00000309, 0x00000061, 0x00000302, 0x00000309, 0x00000041, 0x00000302, 0x00000303, 0x00000061, 0x00000302, 0x00000303, 0x00000041, 0x00000323, 0x00000302, 0x00000061, 0x00000323, 0x00000302, 0x00000041, 0x00000306, 0x00000301, 0x00000061, 0x00000306, 0x00000301, 0x00000041, 0x00000306, 0x00000300, 0x00000061, 0x00000306, 0x00000300, 0x00000041, 0x00000306, 0x00000309, 0x00000061, 0x00000306, 0x00000309, 0x00000041, 0x00000306, 0x00000303, 0x00000061, 0x00000306, 0x00000303, 0x00000041, 0x00000323, 0x00000306, 0x00000061, 0x00000323, 0x00000306, 0x00000045, 0x00000323, 0x00000065, 0x00000323, 0x00000045, 0x00000309, 0x00000065, 0x00000309, 0x00000045, 0x00000303, 0x00000065, 0x00000303, 0x00000045, 0x00000302, 0x00000301, 0x00000065, 0x00000302, 0x00000301, 0x00000045, 0x00000302, 0x00000300, 0x00000065, 0x00000302, 0x00000300, 0x00000045, 0x00000302, 0x00000309, 0x00000065, 0x00000302, 0x00000309, 0x00000045, 0x00000302, 0x00000303, 0x00000065, 0x00000302, 0x00000303, 0x00000045, 0x00000323, 0x00000302, 0x00000065, 0x00000323, 0x00000302, 0x00000049, 0x00000309, 0x00000069, 0x00000309, 0x00000049, 0x00000323, 0x00000069, 0x00000323, 0x0000004f, 0x00000323, 0x0000006f, 0x00000323, 0x0000004f, 0x00000309, 0x0000006f, 0x00000309, 0x0000004f, 0x00000302, 0x00000301, 0x0000006f, 0x00000302, 0x00000301, 0x0000004f, 0x00000302, 0x00000300, 0x0000006f, 0x00000302, 0x00000300, 0x0000004f, 0x00000302, 0x00000309, 0x0000006f, 0x00000302, 0x00000309, 0x0000004f, 0x00000302, 0x00000303, 0x0000006f, 0x00000302, 0x00000303, 0x0000004f, 0x00000323, 0x00000302, 0x0000006f, 0x00000323, 0x00000302, 0x0000004f, 0x0000031b, 0x00000301, 0x0000006f, 0x0000031b, 0x00000301, 0x0000004f, 0x0000031b, 0x00000300, 0x0000006f, 0x0000031b, 0x00000300, 0x0000004f, 0x0000031b, 0x00000309, 0x0000006f, 0x0000031b, 0x00000309, 0x0000004f, 0x0000031b, 0x00000303, 0x0000006f, 0x0000031b, 0x00000303, 0x0000004f, 0x0000031b, 0x00000323, 0x0000006f, 0x0000031b, 0x00000323, 0x00000055, 0x00000323, 0x00000075, 0x00000323, 0x00000055, 0x00000309, 0x00000075, 0x00000309, 0x00000055, 0x0000031b, 0x00000301, 0x00000075, 0x0000031b, 0x00000301, 0x00000055, 0x0000031b, 0x00000300, 0x00000075, 0x0000031b, 0x00000300, 0x00000055, 0x0000031b, 0x00000309, 0x00000075, 0x0000031b, 0x00000309, 0x00000055, 0x0000031b, 0x00000303, 0x00000075, 0x0000031b, 0x00000303, 0x00000055, 0x0000031b, 0x00000323, 0x00000075, 0x0000031b, 0x00000323, 0x00000059, 0x00000300, 0x00000079, 0x00000300, 0x00000059, 0x00000323, 0x00000079, 0x00000323, 0x00000059, 0x00000309, 0x00000079, 0x00000309, 0x00000059, 0x00000303, 0x00000079, 0x00000303, 0x000003b1, 0x00000313, 0x000003b1, 0x00000314, 0x000003b1, 0x00000313, 0x00000300, 0x000003b1, 0x00000314, 0x00000300, 0x000003b1, 0x00000313, 0x00000301, 0x000003b1, 0x00000314, 0x00000301, 0x000003b1, 0x00000313, 0x00000342, 0x000003b1, 0x00000314, 0x00000342, 0x00000391, 0x00000313, 0x00000391, 0x00000314, 0x00000391, 0x00000313, 0x00000300, 0x00000391, 0x00000314, 0x00000300, 0x00000391, 0x00000313, 0x00000301, 0x00000391, 0x00000314, 0x00000301, 0x00000391, 0x00000313, 0x00000342, 0x00000391, 0x00000314, 0x00000342, 0x000003b5, 0x00000313, 0x000003b5, 0x00000314, 0x000003b5, 0x00000313, 0x00000300, 0x000003b5, 0x00000314, 0x00000300, 0x000003b5, 0x00000313, 0x00000301, 0x000003b5, 0x00000314, 0x00000301, 0x00000395, 0x00000313, 0x00000395, 0x00000314, 0x00000395, 0x00000313, 0x00000300, 0x00000395, 0x00000314, 0x00000300, 0x00000395, 0x00000313, 0x00000301, 0x00000395, 0x00000314, 0x00000301, 0x000003b7, 0x00000313, 0x000003b7, 0x00000314, 0x000003b7, 0x00000313, 0x00000300, 0x000003b7, 0x00000314, 0x00000300, 0x000003b7, 0x00000313, 0x00000301, 0x000003b7, 0x00000314, 0x00000301, 0x000003b7, 0x00000313, 0x00000342, 0x000003b7, 0x00000314, 0x00000342, 0x00000397, 0x00000313, 0x00000397, 0x00000314, 0x00000397, 0x00000313, 0x00000300, 0x00000397, 0x00000314, 0x00000300, 0x00000397, 0x00000313, 0x00000301, 0x00000397, 0x00000314, 0x00000301, 0x00000397, 0x00000313, 0x00000342, 0x00000397, 0x00000314, 0x00000342, 0x000003b9, 0x00000313, 0x000003b9, 0x00000314, 0x000003b9, 0x00000313, 0x00000300, 0x000003b9, 0x00000314, 0x00000300, 0x000003b9, 0x00000313, 0x00000301, 0x000003b9, 0x00000314, 0x00000301, 0x000003b9, 0x00000313, 0x00000342, 0x000003b9, 0x00000314, 0x00000342, 0x00000399, 0x00000313, 0x00000399, 0x00000314, 0x00000399, 0x00000313, 0x00000300, 0x00000399, 0x00000314, 0x00000300, 0x00000399, 0x00000313, 0x00000301, 0x00000399, 0x00000314, 0x00000301, 0x00000399, 0x00000313, 0x00000342, 0x00000399, 0x00000314, 0x00000342, 0x000003bf, 0x00000313, 0x000003bf, 0x00000314, 0x000003bf, 0x00000313, 0x00000300, 0x000003bf, 0x00000314, 0x00000300, 0x000003bf, 0x00000313, 0x00000301, 0x000003bf, 0x00000314, 0x00000301, 0x0000039f, 0x00000313, 0x0000039f, 0x00000314, 0x0000039f, 0x00000313, 0x00000300, 0x0000039f, 0x00000314, 0x00000300, 0x0000039f, 0x00000313, 0x00000301, 0x0000039f, 0x00000314, 0x00000301, 0x000003c5, 0x00000313, 0x000003c5, 0x00000314, 0x000003c5, 0x00000313, 0x00000300, 0x000003c5, 0x00000314, 0x00000300, 0x000003c5, 0x00000313, 0x00000301, 0x000003c5, 0x00000314, 0x00000301, 0x000003c5, 0x00000313, 0x00000342, 0x000003c5, 0x00000314, 0x00000342, 0x000003a5, 0x00000314, 0x000003a5, 0x00000314, 0x00000300, 0x000003a5, 0x00000314, 0x00000301, 0x000003a5, 0x00000314, 0x00000342, 0x000003c9, 0x00000313, 0x000003c9, 0x00000314, 0x000003c9, 0x00000313, 0x00000300, 0x000003c9, 0x00000314, 0x00000300, 0x000003c9, 0x00000313, 0x00000301, 0x000003c9, 0x00000314, 0x00000301, 0x000003c9, 0x00000313, 0x00000342, 0x000003c9, 0x00000314, 0x00000342, 0x000003a9, 0x00000313, 0x000003a9, 0x00000314, 0x000003a9, 0x00000313, 0x00000300, 0x000003a9, 0x00000314, 0x00000300, 0x000003a9, 0x00000313, 0x00000301, 0x000003a9, 0x00000314, 0x00000301, 0x000003a9, 0x00000313, 0x00000342, 0x000003a9, 0x00000314, 0x00000342, 0x000003b1, 0x00000300, 0x000003b1, 0x00000301, 0x000003b5, 0x00000300, 0x000003b5, 0x00000301, 0x000003b7, 0x00000300, 0x000003b7, 0x00000301, 0x000003b9, 0x00000300, 0x000003b9, 0x00000301, 0x000003bf, 0x00000300, 0x000003bf, 0x00000301, 0x000003c5, 0x00000300, 0x000003c5, 0x00000301, 0x000003c9, 0x00000300, 0x000003c9, 0x00000301, 0x000003b1, 0x00000313, 0x00000345, 0x000003b1, 0x00000314, 0x00000345, 0x000003b1, 0x00000313, 0x00000300, 0x00000345, 0x000003b1, 0x00000314, 0x00000300, 0x00000345, 0x000003b1, 0x00000313, 0x00000301, 0x00000345, 0x000003b1, 0x00000314, 0x00000301, 0x00000345, 0x000003b1, 0x00000313, 0x00000342, 0x00000345, 0x000003b1, 0x00000314, 0x00000342, 0x00000345, 0x00000391, 0x00000313, 0x00000345, 0x00000391, 0x00000314, 0x00000345, 0x00000391, 0x00000313, 0x00000300, 0x00000345, 0x00000391, 0x00000314, 0x00000300, 0x00000345, 0x00000391, 0x00000313, 0x00000301, 0x00000345, 0x00000391, 0x00000314, 0x00000301, 0x00000345, 0x00000391, 0x00000313, 0x00000342, 0x00000345, 0x00000391, 0x00000314, 0x00000342, 0x00000345, 0x000003b7, 0x00000313, 0x00000345, 0x000003b7, 0x00000314, 0x00000345, 0x000003b7, 0x00000313, 0x00000300, 0x00000345, 0x000003b7, 0x00000314, 0x00000300, 0x00000345, 0x000003b7, 0x00000313, 0x00000301, 0x00000345, 0x000003b7, 0x00000314, 0x00000301, 0x00000345, 0x000003b7, 0x00000313, 0x00000342, 0x00000345, 0x000003b7, 0x00000314, 0x00000342, 0x00000345, 0x00000397, 0x00000313, 0x00000345, 0x00000397, 0x00000314, 0x00000345, 0x00000397, 0x00000313, 0x00000300, 0x00000345, 0x00000397, 0x00000314, 0x00000300, 0x00000345, 0x00000397, 0x00000313, 0x00000301, 0x00000345, 0x00000397, 0x00000314, 0x00000301, 0x00000345, 0x00000397, 0x00000313, 0x00000342, 0x00000345, 0x00000397, 0x00000314, 0x00000342, 0x00000345, 0x000003c9, 0x00000313, 0x00000345, 0x000003c9, 0x00000314, 0x00000345, 0x000003c9, 0x00000313, 0x00000300, 0x00000345, 0x000003c9, 0x00000314, 0x00000300, 0x00000345, 0x000003c9, 0x00000313, 0x00000301, 0x00000345, 0x000003c9, 0x00000314, 0x00000301, 0x00000345, 0x000003c9, 0x00000313, 0x00000342, 0x00000345, 0x000003c9, 0x00000314, 0x00000342, 0x00000345, 0x000003a9, 0x00000313, 0x00000345, 0x000003a9, 0x00000314, 0x00000345, 0x000003a9, 0x00000313, 0x00000300, 0x00000345, 0x000003a9, 0x00000314, 0x00000300, 0x00000345, 0x000003a9, 0x00000313, 0x00000301, 0x00000345, 0x000003a9, 0x00000314, 0x00000301, 0x00000345, 0x000003a9, 0x00000313, 0x00000342, 0x00000345, 0x000003a9, 0x00000314, 0x00000342, 0x00000345, 0x000003b1, 0x00000306, 0x000003b1, 0x00000304, 0x000003b1, 0x00000300, 0x00000345, 0x000003b1, 0x00000345, 0x000003b1, 0x00000301, 0x00000345, 0x000003b1, 0x00000342, 0x000003b1, 0x00000342, 0x00000345, 0x00000391, 0x00000306, 0x00000391, 0x00000304, 0x00000391, 0x00000300, 0x00000391, 0x00000301, 0x00000391, 0x00000345, 0x000003b9, 0x000000a8, 0x00000342, 0x000003b7, 0x00000300, 0x00000345, 0x000003b7, 0x00000345, 0x000003b7, 0x00000301, 0x00000345, 0x000003b7, 0x00000342, 0x000003b7, 0x00000342, 0x00000345, 0x00000395, 0x00000300, 0x00000395, 0x00000301, 0x00000397, 0x00000300, 0x00000397, 0x00000301, 0x00000397, 0x00000345, 0x00001fbf, 0x00000300, 0x00001fbf, 0x00000301, 0x00001fbf, 0x00000342, 0x000003b9, 0x00000306, 0x000003b9, 0x00000304, 0x000003b9, 0x00000308, 0x00000300, 0x000003b9, 0x00000308, 0x00000301, 0x000003b9, 0x00000342, 0x000003b9, 0x00000308, 0x00000342, 0x00000399, 0x00000306, 0x00000399, 0x00000304, 0x00000399, 0x00000300, 0x00000399, 0x00000301, 0x00001ffe, 0x00000300, 0x00001ffe, 0x00000301, 0x00001ffe, 0x00000342, 0x000003c5, 0x00000306, 0x000003c5, 0x00000304, 0x000003c5, 0x00000308, 0x00000300, 0x000003c5, 0x00000308, 0x00000301, 0x000003c1, 0x00000313, 0x000003c1, 0x00000314, 0x000003c5, 0x00000342, 0x000003c5, 0x00000308, 0x00000342, 0x000003a5, 0x00000306, 0x000003a5, 0x00000304, 0x000003a5, 0x00000300, 0x000003a5, 0x00000301, 0x000003a1, 0x00000314, 0x000000a8, 0x00000300, 0x000000a8, 0x00000301, 0x00000060, 0x000003c9, 0x00000300, 0x00000345, 0x000003c9, 0x00000345, 0x000003c9, 0x00000301, 0x00000345, 0x000003c9, 0x00000342, 0x000003c9, 0x00000342, 0x00000345, 0x0000039f, 0x00000300, 0x0000039f, 0x00000301, 0x000003a9, 0x00000300, 0x000003a9, 0x00000301, 0x000003a9, 0x00000345, 0x000000b4, 0x00002002, 0x00002003, 0x000003a9, 0x0000004b, 0x00000041, 0x0000030a, 0x00002190, 0x00000338, 0x00002192, 0x00000338, 0x00002194, 0x00000338, 0x000021d0, 0x00000338, 0x000021d4, 0x00000338, 0x000021d2, 0x00000338, 0x00002203, 0x00000338, 0x00002208, 0x00000338, 0x0000220b, 0x00000338, 0x00002223, 0x00000338, 0x00002225, 0x00000338, 0x0000223c, 0x00000338, 0x00002243, 0x00000338, 0x00002245, 0x00000338, 0x00002248, 0x00000338, 0x0000003d, 0x00000338, 0x00002261, 0x00000338, 0x0000224d, 0x00000338, 0x0000003c, 0x00000338, 0x0000003e, 0x00000338, 0x00002264, 0x00000338, 0x00002265, 0x00000338, 0x00002272, 0x00000338, 0x00002273, 0x00000338, 0x00002276, 0x00000338, 0x00002277, 0x00000338, 0x0000227a, 0x00000338, 0x0000227b, 0x00000338, 0x00002282, 0x00000338, 0x00002283, 0x00000338, 0x00002286, 0x00000338, 0x00002287, 0x00000338, 0x000022a2, 0x00000338, 0x000022a8, 0x00000338, 0x000022a9, 0x00000338, 0x000022ab, 0x00000338, 0x0000227c, 0x00000338, 0x0000227d, 0x00000338, 0x00002291, 0x00000338, 0x00002292, 0x00000338, 0x000022b2, 0x00000338, 0x000022b3, 0x00000338, 0x000022b4, 0x00000338, 0x000022b5, 0x00000338, 0x00003008, 0x00003009, 0x00002add, 0x00000338, 0x0000304b, 0x00003099, 0x0000304d, 0x00003099, 0x0000304f, 0x00003099, 0x00003051, 0x00003099, 0x00003053, 0x00003099, 0x00003055, 0x00003099, 0x00003057, 0x00003099, 0x00003059, 0x00003099, 0x0000305b, 0x00003099, 0x0000305d, 0x00003099, 0x0000305f, 0x00003099, 0x00003061, 0x00003099, 0x00003064, 0x00003099, 0x00003066, 0x00003099, 0x00003068, 0x00003099, 0x0000306f, 0x00003099, 0x0000306f, 0x0000309a, 0x00003072, 0x00003099, 0x00003072, 0x0000309a, 0x00003075, 0x00003099, 0x00003075, 0x0000309a, 0x00003078, 0x00003099, 0x00003078, 0x0000309a, 0x0000307b, 0x00003099, 0x0000307b, 0x0000309a, 0x00003046, 0x00003099, 0x0000309d, 0x00003099, 0x000030ab, 0x00003099, 0x000030ad, 0x00003099, 0x000030af, 0x00003099, 0x000030b1, 0x00003099, 0x000030b3, 0x00003099, 0x000030b5, 0x00003099, 0x000030b7, 0x00003099, 0x000030b9, 0x00003099, 0x000030bb, 0x00003099, 0x000030bd, 0x00003099, 0x000030bf, 0x00003099, 0x000030c1, 0x00003099, 0x000030c4, 0x00003099, 0x000030c6, 0x00003099, 0x000030c8, 0x00003099, 0x000030cf, 0x00003099, 0x000030cf, 0x0000309a, 0x000030d2, 0x00003099, 0x000030d2, 0x0000309a, 0x000030d5, 0x00003099, 0x000030d5, 0x0000309a, 0x000030d8, 0x00003099, 0x000030d8, 0x0000309a, 0x000030db, 0x00003099, 0x000030db, 0x0000309a, 0x000030a6, 0x00003099, 0x000030ef, 0x00003099, 0x000030f0, 0x00003099, 0x000030f1, 0x00003099, 0x000030f2, 0x00003099, 0x000030fd, 0x00003099, 0x00008eca, 0x00008cc8, 0x00006ed1, 0x00004e32, 0x000053e5, 0x00009f9c, 0x00009f9c, 0x00005951, 0x000091d1, 0x00005587, 0x00005948, 0x000061f6, 0x00007669, 0x00007f85, 0x0000863f, 0x000087ba, 0x000088f8, 0x0000908f, 0x00006a02, 0x00006d1b, 0x000070d9, 0x000073de, 0x0000843d, 0x0000916a, 0x000099f1, 0x00004e82, 0x00005375, 0x00006b04, 0x0000721b, 0x0000862d, 0x00009e1e, 0x00005d50, 0x00006feb, 0x000085cd, 0x00008964, 0x000062c9, 0x000081d8, 0x0000881f, 0x00005eca, 0x00006717, 0x00006d6a, 0x000072fc, 0x000090ce, 0x00004f86, 0x000051b7, 0x000052de, 0x000064c4, 0x00006ad3, 0x00007210, 0x000076e7, 0x00008001, 0x00008606, 0x0000865c, 0x00008def, 0x00009732, 0x00009b6f, 0x00009dfa, 0x0000788c, 0x0000797f, 0x00007da0, 0x000083c9, 0x00009304, 0x00009e7f, 0x00008ad6, 0x000058df, 0x00005f04, 0x00007c60, 0x0000807e, 0x00007262, 0x000078ca, 0x00008cc2, 0x000096f7, 0x000058d8, 0x00005c62, 0x00006a13, 0x00006dda, 0x00006f0f, 0x00007d2f, 0x00007e37, 0x0000964b, 0x000052d2, 0x0000808b, 0x000051dc, 0x000051cc, 0x00007a1c, 0x00007dbe, 0x000083f1, 0x00009675, 0x00008b80, 0x000062cf, 0x00006a02, 0x00008afe, 0x00004e39, 0x00005be7, 0x00006012, 0x00007387, 0x00007570, 0x00005317, 0x000078fb, 0x00004fbf, 0x00005fa9, 0x00004e0d, 0x00006ccc, 0x00006578, 0x00007d22, 0x000053c3, 0x0000585e, 0x00007701, 0x00008449, 0x00008aaa, 0x00006bba, 0x00008fb0, 0x00006c88, 0x000062fe, 0x000082e5, 0x000063a0, 0x00007565, 0x00004eae, 0x00005169, 0x000051c9, 0x00006881, 0x00007ce7, 0x0000826f, 0x00008ad2, 0x000091cf, 0x000052f5, 0x00005442, 0x00005973, 0x00005eec, 0x000065c5, 0x00006ffe, 0x0000792a, 0x000095ad, 0x00009a6a, 0x00009e97, 0x00009ece, 0x0000529b, 0x000066c6, 0x00006b77, 0x00008f62, 0x00005e74, 0x00006190, 0x00006200, 0x0000649a, 0x00006f23, 0x00007149, 0x00007489, 0x000079ca, 0x00007df4, 0x0000806f, 0x00008f26, 0x000084ee, 0x00009023, 0x0000934a, 0x00005217, 0x000052a3, 0x000054bd, 0x000070c8, 0x000088c2, 0x00008aaa, 0x00005ec9, 0x00005ff5, 0x0000637b, 0x00006bae, 0x00007c3e, 0x00007375, 0x00004ee4, 0x000056f9, 0x00005be7, 0x00005dba, 0x0000601c, 0x000073b2, 0x00007469, 0x00007f9a, 0x00008046, 0x00009234, 0x000096f6, 0x00009748, 0x00009818, 0x00004f8b, 0x000079ae, 0x000091b4, 0x000096b8, 0x000060e1, 0x00004e86, 0x000050da, 0x00005bee, 0x00005c3f, 0x00006599, 0x00006a02, 0x000071ce, 0x00007642, 0x000084fc, 0x0000907c, 0x00009f8d, 0x00006688, 0x0000962e, 0x00005289, 0x0000677b, 0x000067f3, 0x00006d41, 0x00006e9c, 0x00007409, 0x00007559, 0x0000786b, 0x00007d10, 0x0000985e, 0x0000516d, 0x0000622e, 0x00009678, 0x0000502b, 0x00005d19, 0x00006dea, 0x00008f2a, 0x00005f8b, 0x00006144, 0x00006817, 0x00007387, 0x00009686, 0x00005229, 0x0000540f, 0x00005c65, 0x00006613, 0x0000674e, 0x000068a8, 0x00006ce5, 0x00007406, 0x000075e2, 0x00007f79, 0x000088cf, 0x000088e1, 0x000091cc, 0x000096e2, 0x0000533f, 0x00006eba, 0x0000541d, 0x000071d0, 0x00007498, 0x000085fa, 0x000096a3, 0x00009c57, 0x00009e9f, 0x00006797, 0x00006dcb, 0x000081e8, 0x00007acb, 0x00007b20, 0x00007c92, 0x000072c0, 0x00007099, 0x00008b58, 0x00004ec0, 0x00008336, 0x0000523a, 0x00005207, 0x00005ea6, 0x000062d3, 0x00007cd6, 0x00005b85, 0x00006d1e, 0x000066b4, 0x00008f3b, 0x0000884c, 0x0000964d, 0x0000898b, 0x00005ed3, 0x00005140, 0x000055c0, 0x0000585a, 0x00006674, 0x000051de, 0x0000732a, 0x000076ca, 0x0000793c, 0x0000795e, 0x00007965, 0x0000798f, 0x00009756, 0x00007cbe, 0x00007fbd, 0x00008612, 0x00008af8, 0x00009038, 0x000090fd, 0x000098ef, 0x000098fc, 0x00009928, 0x00009db4, 0x00004fae, 0x000050e7, 0x0000514d, 0x000052c9, 0x000052e4, 0x00005351, 0x0000559d, 0x00005606, 0x00005668, 0x00005840, 0x000058a8, 0x00005c64, 0x00005c6e, 0x00006094, 0x00006168, 0x0000618e, 0x000061f2, 0x0000654f, 0x000065e2, 0x00006691, 0x00006885, 0x00006d77, 0x00006e1a, 0x00006f22, 0x0000716e, 0x0000722b, 0x00007422, 0x00007891, 0x0000793e, 0x00007949, 0x00007948, 0x00007950, 0x00007956, 0x0000795d, 0x0000798d, 0x0000798e, 0x00007a40, 0x00007a81, 0x00007bc0, 0x00007df4, 0x00007e09, 0x00007e41, 0x00007f72, 0x00008005, 0x000081ed, 0x00008279, 0x00008279, 0x00008457, 0x00008910, 0x00008996, 0x00008b01, 0x00008b39, 0x00008cd3, 0x00008d08, 0x00008fb6, 0x00009038, 0x000096e3, 0x000097ff, 0x0000983b, 0x000005d9, 0x000005b4, 0x000005f2, 0x000005b7, 0x000005e9, 0x000005c1, 0x000005e9, 0x000005c2, 0x000005e9, 0x000005bc, 0x000005c1, 0x000005e9, 0x000005bc, 0x000005c2, 0x000005d0, 0x000005b7, 0x000005d0, 0x000005b8, 0x000005d0, 0x000005bc, 0x000005d1, 0x000005bc, 0x000005d2, 0x000005bc, 0x000005d3, 0x000005bc, 0x000005d4, 0x000005bc, 0x000005d5, 0x000005bc, 0x000005d6, 0x000005bc, 0x000005d8, 0x000005bc, 0x000005d9, 0x000005bc, 0x000005da, 0x000005bc, 0x000005db, 0x000005bc, 0x000005dc, 0x000005bc, 0x000005de, 0x000005bc, 0x000005e0, 0x000005bc, 0x000005e1, 0x000005bc, 0x000005e3, 0x000005bc, 0x000005e4, 0x000005bc, 0x000005e6, 0x000005bc, 0x000005e7, 0x000005bc, 0x000005e8, 0x000005bc, 0x000005e9, 0x000005bc, 0x000005ea, 0x000005bc, 0x000005d5, 0x000005b9, 0x000005d1, 0x000005bf, 0x000005db, 0x000005bf, 0x000005e4, 0x000005bf, 0x0001d157, 0x0001d165, 0x0001d158, 0x0001d165, 0x0001d158, 0x0001d165, 0x0001d16e, 0x0001d158, 0x0001d165, 0x0001d16f, 0x0001d158, 0x0001d165, 0x0001d170, 0x0001d158, 0x0001d165, 0x0001d171, 0x0001d158, 0x0001d165, 0x0001d172, 0x0001d1b9, 0x0001d165, 0x0001d1ba, 0x0001d165, 0x0001d1b9, 0x0001d165, 0x0001d16e, 0x0001d1ba, 0x0001d165, 0x0001d16e, 0x0001d1b9, 0x0001d165, 0x0001d16f, 0x0001d1ba, 0x0001d165, 0x0001d16f, 0x00004e3d, 0x00004e38, 0x00004e41, 0x00020122, 0x00004f60, 0x00004fae, 0x00004fbb, 0x00005002, 0x0000507a, 0x00005099, 0x000050e7, 0x000050cf, 0x0000349e, 0x0002063a, 0x0000514d, 0x00005154, 0x00005164, 0x00005177, 0x0002051c, 0x000034b9, 0x00005167, 0x0000518d, 0x0002054b, 0x00005197, 0x000051a4, 0x00004ecc, 0x000051ac, 0x000051b5, 0x000291df, 0x000051f5, 0x00005203, 0x000034df, 0x0000523b, 0x00005246, 0x00005272, 0x00005277, 0x00003515, 0x000052c7, 0x000052c9, 0x000052e4, 0x000052fa, 0x00005305, 0x00005306, 0x00005317, 0x00005349, 0x00005351, 0x0000535a, 0x00005373, 0x0000537d, 0x0000537f, 0x0000537f, 0x0000537f, 0x00020a2c, 0x00007070, 0x000053ca, 0x000053df, 0x00020b63, 0x000053eb, 0x000053f1, 0x00005406, 0x0000549e, 0x00005438, 0x00005448, 0x00005468, 0x000054a2, 0x000054f6, 0x00005510, 0x00005553, 0x00005563, 0x00005584, 0x00005584, 0x00005599, 0x000055ab, 0x000055b3, 0x000055c2, 0x00005716, 0x00005606, 0x00005717, 0x00005651, 0x00005674, 0x00005207, 0x000058ee, 0x000057ce, 0x000057f4, 0x0000580d, 0x0000578b, 0x00005832, 0x00005831, 0x000058ac, 0x000214e4, 0x000058f2, 0x000058f7, 0x00005906, 0x0000591a, 0x00005922, 0x00005962, 0x000216a8, 0x000216ea, 0x000059ec, 0x00005a1b, 0x00005a27, 0x000059d8, 0x00005a66, 0x000036ee, 0x0002136a, 0x00005b08, 0x00005b3e, 0x00005b3e, 0x000219c8, 0x00005bc3, 0x00005bd8, 0x00005be7, 0x00005bf3, 0x00021b18, 0x00005bff, 0x00005c06, 0x00005f33, 0x00005c22, 0x00003781, 0x00005c60, 0x00005c6e, 0x00005cc0, 0x00005c8d, 0x00021de4, 0x00005d43, 0x00021de6, 0x00005d6e, 0x00005d6b, 0x00005d7c, 0x00005de1, 0x00005de2, 0x0000382f, 0x00005dfd, 0x00005e28, 0x00005e3d, 0x00005e69, 0x00003862, 0x00022183, 0x0000387c, 0x00005eb0, 0x00005eb3, 0x00005eb6, 0x00005eca, 0x0002a392, 0x00005efe, 0x00022331, 0x00022331, 0x00008201, 0x00005f22, 0x00005f22, 0x000038c7, 0x000232b8, 0x000261da, 0x00005f62, 0x00005f6b, 0x000038e3, 0x00005f9a, 0x00005fcd, 0x00005fd7, 0x00005ff9, 0x00006081, 0x0000393a, 0x0000391c, 0x00006094, 0x000226d4, 0x000060c7, 0x00006148, 0x0000614c, 0x0000614e, 0x0000614c, 0x0000617a, 0x0000618e, 0x000061b2, 0x000061a4, 0x000061af, 0x000061de, 0x000061f2, 0x000061f6, 0x00006210, 0x0000621b, 0x0000625d, 0x000062b1, 0x000062d4, 0x00006350, 0x00022b0c, 0x0000633d, 0x000062fc, 0x00006368, 0x00006383, 0x000063e4, 0x00022bf1, 0x00006422, 0x000063c5, 0x000063a9, 0x00003a2e, 0x00006469, 0x0000647e, 0x0000649d, 0x00006477, 0x00003a6c, 0x0000654f, 0x0000656c, 0x0002300a, 0x000065e3, 0x000066f8, 0x00006649, 0x00003b19, 0x00006691, 0x00003b08, 0x00003ae4, 0x00005192, 0x00005195, 0x00006700, 0x0000669c, 0x000080ad, 0x000043d9, 0x00006717, 0x0000671b, 0x00006721, 0x0000675e, 0x00006753, 0x000233c3, 0x00003b49, 0x000067fa, 0x00006785, 0x00006852, 0x00006885, 0x0002346d, 0x0000688e, 0x0000681f, 0x00006914, 0x00003b9d, 0x00006942, 0x000069a3, 0x000069ea, 0x00006aa8, 0x000236a3, 0x00006adb, 0x00003c18, 0x00006b21, 0x000238a7, 0x00006b54, 0x00003c4e, 0x00006b72, 0x00006b9f, 0x00006bba, 0x00006bbb, 0x00023a8d, 0x00021d0b, 0x00023afa, 0x00006c4e, 0x00023cbc, 0x00006cbf, 0x00006ccd, 0x00006c67, 0x00006d16, 0x00006d3e, 0x00006d77, 0x00006d41, 0x00006d69, 0x00006d78, 0x00006d85, 0x00023d1e, 0x00006d34, 0x00006e2f, 0x00006e6e, 0x00003d33, 0x00006ecb, 0x00006ec7, 0x00023ed1, 0x00006df9, 0x00006f6e, 0x00023f5e, 0x00023f8e, 0x00006fc6, 0x00007039, 0x0000701e, 0x0000701b, 0x00003d96, 0x0000704a, 0x0000707d, 0x00007077, 0x000070ad, 0x00020525, 0x00007145, 0x00024263, 0x0000719c, 0x000043ab, 0x00007228, 0x00007235, 0x00007250, 0x00024608, 0x00007280, 0x00007295, 0x00024735, 0x00024814, 0x0000737a, 0x0000738b, 0x00003eac, 0x000073a5, 0x00003eb8, 0x00003eb8, 0x00007447, 0x0000745c, 0x00007471, 0x00007485, 0x000074ca, 0x00003f1b, 0x00007524, 0x00024c36, 0x0000753e, 0x00024c92, 0x00007570, 0x0002219f, 0x00007610, 0x00024fa1, 0x00024fb8, 0x00025044, 0x00003ffc, 0x00004008, 0x000076f4, 0x000250f3, 0x000250f2, 0x00025119, 0x00025133, 0x0000771e, 0x0000771f, 0x0000771f, 0x0000774a, 0x00004039, 0x0000778b, 0x00004046, 0x00004096, 0x0002541d, 0x0000784e, 0x0000788c, 0x000078cc, 0x000040e3, 0x00025626, 0x00007956, 0x0002569a, 0x000256c5, 0x0000798f, 0x000079eb, 0x0000412f, 0x00007a40, 0x00007a4a, 0x00007a4f, 0x0002597c, 0x00025aa7, 0x00025aa7, 0x00007aae, 0x00004202, 0x00025bab, 0x00007bc6, 0x00007bc9, 0x00004227, 0x00025c80, 0x00007cd2, 0x000042a0, 0x00007ce8, 0x00007ce3, 0x00007d00, 0x00025f86, 0x00007d63, 0x00004301, 0x00007dc7, 0x00007e02, 0x00007e45, 0x00004334, 0x00026228, 0x00026247, 0x00004359, 0x000262d9, 0x00007f7a, 0x0002633e, 0x00007f95, 0x00007ffa, 0x00008005, 0x000264da, 0x00026523, 0x00008060, 0x000265a8, 0x00008070, 0x0002335f, 0x000043d5, 0x000080b2, 0x00008103, 0x0000440b, 0x0000813e, 0x00005ab5, 0x000267a7, 0x000267b5, 0x00023393, 0x0002339c, 0x00008201, 0x00008204, 0x00008f9e, 0x0000446b, 0x00008291, 0x0000828b, 0x0000829d, 0x000052b3, 0x000082b1, 0x000082b3, 0x000082bd, 0x000082e6, 0x00026b3c, 0x000082e5, 0x0000831d, 0x00008363, 0x000083ad, 0x00008323, 0x000083bd, 0x000083e7, 0x00008457, 0x00008353, 0x000083ca, 0x000083cc, 0x000083dc, 0x00026c36, 0x00026d6b, 0x00026cd5, 0x0000452b, 0x000084f1, 0x000084f3, 0x00008516, 0x000273ca, 0x00008564, 0x00026f2c, 0x0000455d, 0x00004561, 0x00026fb1, 0x000270d2, 0x0000456b, 0x00008650, 0x0000865c, 0x00008667, 0x00008669, 0x000086a9, 0x00008688, 0x0000870e, 0x000086e2, 0x00008779, 0x00008728, 0x0000876b, 0x00008786, 0x00004d57, 0x000087e1, 0x00008801, 0x000045f9, 0x00008860, 0x00008863, 0x00027667, 0x000088d7, 0x000088de, 0x00004635, 0x000088fa, 0x000034bb, 0x000278ae, 0x00027966, 0x000046be, 0x000046c7, 0x00008aa0, 0x00008aed, 0x00008b8a, 0x00008c55, 0x00027ca8, 0x00008cab, 0x00008cc1, 0x00008d1b, 0x00008d77, 0x00027f2f, 0x00020804, 0x00008dcb, 0x00008dbc, 0x00008df0, 0x000208de, 0x00008ed4, 0x00008f38, 0x000285d2, 0x000285ed, 0x00009094, 0x000090f1, 0x00009111, 0x0002872e, 0x0000911b, 0x00009238, 0x000092d7, 0x000092d8, 0x0000927c, 0x000093f9, 0x00009415, 0x00028bfa, 0x0000958b, 0x00004995, 0x000095b7, 0x00028d77, 0x000049e6, 0x000096c3, 0x00005db2, 0x00009723, 0x00029145, 0x0002921a, 0x00004a6e, 0x00004a76, 0x000097e0, 0x0002940a, 0x00004ab2, 0x00029496, 0x0000980b, 0x0000980b, 0x00009829, 0x000295b6, 0x000098e2, 0x00004b33, 0x00009929, 0x000099a7, 0x000099c2, 0x000099fe, 0x00004bce, 0x00029b30, 0x00009b12, 0x00009c40, 0x00009cfd, 0x00004cce, 0x00004ced, 0x00009d67, 0x0002a0ce, 0x00004cf8, 0x0002a105, 0x0002a20e, 0x0002a291, 0x00009ebb, 0x00004d56, 0x00009ef9, 0x00009efe, 0x00009f05, 0x00009f0f, 0x00009f16, 0x00009f3b, 0x0002a600 }; static const krb5_ui_4 _uckdcmp_size = 10282; static const krb5_ui_4 _uckdcmp_nodes[] = { 0x000000a0, 0x00000000, 0x000000a8, 0x00000001, 0x000000aa, 0x00000003, 0x000000af, 0x00000004, 0x000000b2, 0x00000006, 0x000000b3, 0x00000007, 0x000000b4, 0x00000008, 0x000000b5, 0x0000000a, 0x000000b8, 0x0000000b, 0x000000b9, 0x0000000d, 0x000000ba, 0x0000000e, 0x000000bc, 0x0000000f, 0x000000bd, 0x00000012, 0x000000be, 0x00000015, 0x000000c0, 0x00000018, 0x000000c1, 0x0000001a, 0x000000c2, 0x0000001c, 0x000000c3, 0x0000001e, 0x000000c4, 0x00000020, 0x000000c5, 0x00000022, 0x000000c7, 0x00000024, 0x000000c8, 0x00000026, 0x000000c9, 0x00000028, 0x000000ca, 0x0000002a, 0x000000cb, 0x0000002c, 0x000000cc, 0x0000002e, 0x000000cd, 0x00000030, 0x000000ce, 0x00000032, 0x000000cf, 0x00000034, 0x000000d1, 0x00000036, 0x000000d2, 0x00000038, 0x000000d3, 0x0000003a, 0x000000d4, 0x0000003c, 0x000000d5, 0x0000003e, 0x000000d6, 0x00000040, 0x000000d9, 0x00000042, 0x000000da, 0x00000044, 0x000000db, 0x00000046, 0x000000dc, 0x00000048, 0x000000dd, 0x0000004a, 0x000000e0, 0x0000004c, 0x000000e1, 0x0000004e, 0x000000e2, 0x00000050, 0x000000e3, 0x00000052, 0x000000e4, 0x00000054, 0x000000e5, 0x00000056, 0x000000e7, 0x00000058, 0x000000e8, 0x0000005a, 0x000000e9, 0x0000005c, 0x000000ea, 0x0000005e, 0x000000eb, 0x00000060, 0x000000ec, 0x00000062, 0x000000ed, 0x00000064, 0x000000ee, 0x00000066, 0x000000ef, 0x00000068, 0x000000f1, 0x0000006a, 0x000000f2, 0x0000006c, 0x000000f3, 0x0000006e, 0x000000f4, 0x00000070, 0x000000f5, 0x00000072, 0x000000f6, 0x00000074, 0x000000f9, 0x00000076, 0x000000fa, 0x00000078, 0x000000fb, 0x0000007a, 0x000000fc, 0x0000007c, 0x000000fd, 0x0000007e, 0x000000ff, 0x00000080, 0x00000100, 0x00000082, 0x00000101, 0x00000084, 0x00000102, 0x00000086, 0x00000103, 0x00000088, 0x00000104, 0x0000008a, 0x00000105, 0x0000008c, 0x00000106, 0x0000008e, 0x00000107, 0x00000090, 0x00000108, 0x00000092, 0x00000109, 0x00000094, 0x0000010a, 0x00000096, 0x0000010b, 0x00000098, 0x0000010c, 0x0000009a, 0x0000010d, 0x0000009c, 0x0000010e, 0x0000009e, 0x0000010f, 0x000000a0, 0x00000112, 0x000000a2, 0x00000113, 0x000000a4, 0x00000114, 0x000000a6, 0x00000115, 0x000000a8, 0x00000116, 0x000000aa, 0x00000117, 0x000000ac, 0x00000118, 0x000000ae, 0x00000119, 0x000000b0, 0x0000011a, 0x000000b2, 0x0000011b, 0x000000b4, 0x0000011c, 0x000000b6, 0x0000011d, 0x000000b8, 0x0000011e, 0x000000ba, 0x0000011f, 0x000000bc, 0x00000120, 0x000000be, 0x00000121, 0x000000c0, 0x00000122, 0x000000c2, 0x00000123, 0x000000c4, 0x00000124, 0x000000c6, 0x00000125, 0x000000c8, 0x00000128, 0x000000ca, 0x00000129, 0x000000cc, 0x0000012a, 0x000000ce, 0x0000012b, 0x000000d0, 0x0000012c, 0x000000d2, 0x0000012d, 0x000000d4, 0x0000012e, 0x000000d6, 0x0000012f, 0x000000d8, 0x00000130, 0x000000da, 0x00000132, 0x000000dc, 0x00000133, 0x000000de, 0x00000134, 0x000000e0, 0x00000135, 0x000000e2, 0x00000136, 0x000000e4, 0x00000137, 0x000000e6, 0x00000139, 0x000000e8, 0x0000013a, 0x000000ea, 0x0000013b, 0x000000ec, 0x0000013c, 0x000000ee, 0x0000013d, 0x000000f0, 0x0000013e, 0x000000f2, 0x0000013f, 0x000000f4, 0x00000140, 0x000000f6, 0x00000143, 0x000000f8, 0x00000144, 0x000000fa, 0x00000145, 0x000000fc, 0x00000146, 0x000000fe, 0x00000147, 0x00000100, 0x00000148, 0x00000102, 0x00000149, 0x00000104, 0x0000014c, 0x00000106, 0x0000014d, 0x00000108, 0x0000014e, 0x0000010a, 0x0000014f, 0x0000010c, 0x00000150, 0x0000010e, 0x00000151, 0x00000110, 0x00000154, 0x00000112, 0x00000155, 0x00000114, 0x00000156, 0x00000116, 0x00000157, 0x00000118, 0x00000158, 0x0000011a, 0x00000159, 0x0000011c, 0x0000015a, 0x0000011e, 0x0000015b, 0x00000120, 0x0000015c, 0x00000122, 0x0000015d, 0x00000124, 0x0000015e, 0x00000126, 0x0000015f, 0x00000128, 0x00000160, 0x0000012a, 0x00000161, 0x0000012c, 0x00000162, 0x0000012e, 0x00000163, 0x00000130, 0x00000164, 0x00000132, 0x00000165, 0x00000134, 0x00000168, 0x00000136, 0x00000169, 0x00000138, 0x0000016a, 0x0000013a, 0x0000016b, 0x0000013c, 0x0000016c, 0x0000013e, 0x0000016d, 0x00000140, 0x0000016e, 0x00000142, 0x0000016f, 0x00000144, 0x00000170, 0x00000146, 0x00000171, 0x00000148, 0x00000172, 0x0000014a, 0x00000173, 0x0000014c, 0x00000174, 0x0000014e, 0x00000175, 0x00000150, 0x00000176, 0x00000152, 0x00000177, 0x00000154, 0x00000178, 0x00000156, 0x00000179, 0x00000158, 0x0000017a, 0x0000015a, 0x0000017b, 0x0000015c, 0x0000017c, 0x0000015e, 0x0000017d, 0x00000160, 0x0000017e, 0x00000162, 0x0000017f, 0x00000164, 0x000001a0, 0x00000165, 0x000001a1, 0x00000167, 0x000001af, 0x00000169, 0x000001b0, 0x0000016b, 0x000001c4, 0x0000016d, 0x000001c5, 0x00000170, 0x000001c6, 0x00000173, 0x000001c7, 0x00000176, 0x000001c8, 0x00000178, 0x000001c9, 0x0000017a, 0x000001ca, 0x0000017c, 0x000001cb, 0x0000017e, 0x000001cc, 0x00000180, 0x000001cd, 0x00000182, 0x000001ce, 0x00000184, 0x000001cf, 0x00000186, 0x000001d0, 0x00000188, 0x000001d1, 0x0000018a, 0x000001d2, 0x0000018c, 0x000001d3, 0x0000018e, 0x000001d4, 0x00000190, 0x000001d5, 0x00000192, 0x000001d6, 0x00000195, 0x000001d7, 0x00000198, 0x000001d8, 0x0000019b, 0x000001d9, 0x0000019e, 0x000001da, 0x000001a1, 0x000001db, 0x000001a4, 0x000001dc, 0x000001a7, 0x000001de, 0x000001aa, 0x000001df, 0x000001ad, 0x000001e0, 0x000001b0, 0x000001e1, 0x000001b3, 0x000001e2, 0x000001b6, 0x000001e3, 0x000001b8, 0x000001e6, 0x000001ba, 0x000001e7, 0x000001bc, 0x000001e8, 0x000001be, 0x000001e9, 0x000001c0, 0x000001ea, 0x000001c2, 0x000001eb, 0x000001c4, 0x000001ec, 0x000001c6, 0x000001ed, 0x000001c9, 0x000001ee, 0x000001cc, 0x000001ef, 0x000001ce, 0x000001f0, 0x000001d0, 0x000001f1, 0x000001d2, 0x000001f2, 0x000001d4, 0x000001f3, 0x000001d6, 0x000001f4, 0x000001d8, 0x000001f5, 0x000001da, 0x000001f8, 0x000001dc, 0x000001f9, 0x000001de, 0x000001fa, 0x000001e0, 0x000001fb, 0x000001e3, 0x000001fc, 0x000001e6, 0x000001fd, 0x000001e8, 0x000001fe, 0x000001ea, 0x000001ff, 0x000001ec, 0x00000200, 0x000001ee, 0x00000201, 0x000001f0, 0x00000202, 0x000001f2, 0x00000203, 0x000001f4, 0x00000204, 0x000001f6, 0x00000205, 0x000001f8, 0x00000206, 0x000001fa, 0x00000207, 0x000001fc, 0x00000208, 0x000001fe, 0x00000209, 0x00000200, 0x0000020a, 0x00000202, 0x0000020b, 0x00000204, 0x0000020c, 0x00000206, 0x0000020d, 0x00000208, 0x0000020e, 0x0000020a, 0x0000020f, 0x0000020c, 0x00000210, 0x0000020e, 0x00000211, 0x00000210, 0x00000212, 0x00000212, 0x00000213, 0x00000214, 0x00000214, 0x00000216, 0x00000215, 0x00000218, 0x00000216, 0x0000021a, 0x00000217, 0x0000021c, 0x00000218, 0x0000021e, 0x00000219, 0x00000220, 0x0000021a, 0x00000222, 0x0000021b, 0x00000224, 0x0000021e, 0x00000226, 0x0000021f, 0x00000228, 0x00000226, 0x0000022a, 0x00000227, 0x0000022c, 0x00000228, 0x0000022e, 0x00000229, 0x00000230, 0x0000022a, 0x00000232, 0x0000022b, 0x00000235, 0x0000022c, 0x00000238, 0x0000022d, 0x0000023b, 0x0000022e, 0x0000023e, 0x0000022f, 0x00000240, 0x00000230, 0x00000242, 0x00000231, 0x00000245, 0x00000232, 0x00000248, 0x00000233, 0x0000024a, 0x000002b0, 0x0000024c, 0x000002b1, 0x0000024d, 0x000002b2, 0x0000024e, 0x000002b3, 0x0000024f, 0x000002b4, 0x00000250, 0x000002b5, 0x00000251, 0x000002b6, 0x00000252, 0x000002b7, 0x00000253, 0x000002b8, 0x00000254, 0x000002d8, 0x00000255, 0x000002d9, 0x00000257, 0x000002da, 0x00000259, 0x000002db, 0x0000025b, 0x000002dc, 0x0000025d, 0x000002dd, 0x0000025f, 0x000002e0, 0x00000261, 0x000002e1, 0x00000262, 0x000002e2, 0x00000263, 0x000002e3, 0x00000264, 0x000002e4, 0x00000265, 0x00000340, 0x00000266, 0x00000341, 0x00000267, 0x00000343, 0x00000268, 0x00000344, 0x00000269, 0x00000374, 0x0000026b, 0x0000037a, 0x0000026c, 0x0000037e, 0x0000026e, 0x00000384, 0x0000026f, 0x00000385, 0x00000271, 0x00000386, 0x00000274, 0x00000387, 0x00000276, 0x00000388, 0x00000277, 0x00000389, 0x00000279, 0x0000038a, 0x0000027b, 0x0000038c, 0x0000027d, 0x0000038e, 0x0000027f, 0x0000038f, 0x00000281, 0x00000390, 0x00000283, 0x000003aa, 0x00000286, 0x000003ab, 0x00000288, 0x000003ac, 0x0000028a, 0x000003ad, 0x0000028c, 0x000003ae, 0x0000028e, 0x000003af, 0x00000290, 0x000003b0, 0x00000292, 0x000003ca, 0x00000295, 0x000003cb, 0x00000297, 0x000003cc, 0x00000299, 0x000003cd, 0x0000029b, 0x000003ce, 0x0000029d, 0x000003d0, 0x0000029f, 0x000003d1, 0x000002a0, 0x000003d2, 0x000002a1, 0x000003d3, 0x000002a2, 0x000003d4, 0x000002a4, 0x000003d5, 0x000002a6, 0x000003d6, 0x000002a7, 0x000003f0, 0x000002a8, 0x000003f1, 0x000002a9, 0x000003f2, 0x000002aa, 0x000003f4, 0x000002ab, 0x000003f5, 0x000002ac, 0x00000400, 0x000002ad, 0x00000401, 0x000002af, 0x00000403, 0x000002b1, 0x00000407, 0x000002b3, 0x0000040c, 0x000002b5, 0x0000040d, 0x000002b7, 0x0000040e, 0x000002b9, 0x00000419, 0x000002bb, 0x00000439, 0x000002bd, 0x00000450, 0x000002bf, 0x00000451, 0x000002c1, 0x00000453, 0x000002c3, 0x00000457, 0x000002c5, 0x0000045c, 0x000002c7, 0x0000045d, 0x000002c9, 0x0000045e, 0x000002cb, 0x00000476, 0x000002cd, 0x00000477, 0x000002cf, 0x000004c1, 0x000002d1, 0x000004c2, 0x000002d3, 0x000004d0, 0x000002d5, 0x000004d1, 0x000002d7, 0x000004d2, 0x000002d9, 0x000004d3, 0x000002db, 0x000004d6, 0x000002dd, 0x000004d7, 0x000002df, 0x000004da, 0x000002e1, 0x000004db, 0x000002e3, 0x000004dc, 0x000002e5, 0x000004dd, 0x000002e7, 0x000004de, 0x000002e9, 0x000004df, 0x000002eb, 0x000004e2, 0x000002ed, 0x000004e3, 0x000002ef, 0x000004e4, 0x000002f1, 0x000004e5, 0x000002f3, 0x000004e6, 0x000002f5, 0x000004e7, 0x000002f7, 0x000004ea, 0x000002f9, 0x000004eb, 0x000002fb, 0x000004ec, 0x000002fd, 0x000004ed, 0x000002ff, 0x000004ee, 0x00000301, 0x000004ef, 0x00000303, 0x000004f0, 0x00000305, 0x000004f1, 0x00000307, 0x000004f2, 0x00000309, 0x000004f3, 0x0000030b, 0x000004f4, 0x0000030d, 0x000004f5, 0x0000030f, 0x000004f8, 0x00000311, 0x000004f9, 0x00000313, 0x00000587, 0x00000315, 0x00000622, 0x00000317, 0x00000623, 0x00000319, 0x00000624, 0x0000031b, 0x00000625, 0x0000031d, 0x00000626, 0x0000031f, 0x00000675, 0x00000321, 0x00000676, 0x00000323, 0x00000677, 0x00000325, 0x00000678, 0x00000327, 0x000006c0, 0x00000329, 0x000006c2, 0x0000032b, 0x000006d3, 0x0000032d, 0x00000929, 0x0000032f, 0x00000931, 0x00000331, 0x00000934, 0x00000333, 0x00000958, 0x00000335, 0x00000959, 0x00000337, 0x0000095a, 0x00000339, 0x0000095b, 0x0000033b, 0x0000095c, 0x0000033d, 0x0000095d, 0x0000033f, 0x0000095e, 0x00000341, 0x0000095f, 0x00000343, 0x000009cb, 0x00000345, 0x000009cc, 0x00000347, 0x000009dc, 0x00000349, 0x000009dd, 0x0000034b, 0x000009df, 0x0000034d, 0x00000a33, 0x0000034f, 0x00000a36, 0x00000351, 0x00000a59, 0x00000353, 0x00000a5a, 0x00000355, 0x00000a5b, 0x00000357, 0x00000a5e, 0x00000359, 0x00000b48, 0x0000035b, 0x00000b4b, 0x0000035d, 0x00000b4c, 0x0000035f, 0x00000b5c, 0x00000361, 0x00000b5d, 0x00000363, 0x00000b94, 0x00000365, 0x00000bca, 0x00000367, 0x00000bcb, 0x00000369, 0x00000bcc, 0x0000036b, 0x00000c48, 0x0000036d, 0x00000cc0, 0x0000036f, 0x00000cc7, 0x00000371, 0x00000cc8, 0x00000373, 0x00000cca, 0x00000375, 0x00000ccb, 0x00000377, 0x00000d4a, 0x0000037a, 0x00000d4b, 0x0000037c, 0x00000d4c, 0x0000037e, 0x00000dda, 0x00000380, 0x00000ddc, 0x00000382, 0x00000ddd, 0x00000384, 0x00000dde, 0x00000387, 0x00000e33, 0x00000389, 0x00000eb3, 0x0000038b, 0x00000edc, 0x0000038d, 0x00000edd, 0x0000038f, 0x00000f0c, 0x00000391, 0x00000f43, 0x00000392, 0x00000f4d, 0x00000394, 0x00000f52, 0x00000396, 0x00000f57, 0x00000398, 0x00000f5c, 0x0000039a, 0x00000f69, 0x0000039c, 0x00000f73, 0x0000039e, 0x00000f75, 0x000003a0, 0x00000f76, 0x000003a2, 0x00000f77, 0x000003a4, 0x00000f78, 0x000003a7, 0x00000f79, 0x000003a9, 0x00000f81, 0x000003ac, 0x00000f93, 0x000003ae, 0x00000f9d, 0x000003b0, 0x00000fa2, 0x000003b2, 0x00000fa7, 0x000003b4, 0x00000fac, 0x000003b6, 0x00000fb9, 0x000003b8, 0x00001026, 0x000003ba, 0x00001e00, 0x000003bc, 0x00001e01, 0x000003be, 0x00001e02, 0x000003c0, 0x00001e03, 0x000003c2, 0x00001e04, 0x000003c4, 0x00001e05, 0x000003c6, 0x00001e06, 0x000003c8, 0x00001e07, 0x000003ca, 0x00001e08, 0x000003cc, 0x00001e09, 0x000003cf, 0x00001e0a, 0x000003d2, 0x00001e0b, 0x000003d4, 0x00001e0c, 0x000003d6, 0x00001e0d, 0x000003d8, 0x00001e0e, 0x000003da, 0x00001e0f, 0x000003dc, 0x00001e10, 0x000003de, 0x00001e11, 0x000003e0, 0x00001e12, 0x000003e2, 0x00001e13, 0x000003e4, 0x00001e14, 0x000003e6, 0x00001e15, 0x000003e9, 0x00001e16, 0x000003ec, 0x00001e17, 0x000003ef, 0x00001e18, 0x000003f2, 0x00001e19, 0x000003f4, 0x00001e1a, 0x000003f6, 0x00001e1b, 0x000003f8, 0x00001e1c, 0x000003fa, 0x00001e1d, 0x000003fd, 0x00001e1e, 0x00000400, 0x00001e1f, 0x00000402, 0x00001e20, 0x00000404, 0x00001e21, 0x00000406, 0x00001e22, 0x00000408, 0x00001e23, 0x0000040a, 0x00001e24, 0x0000040c, 0x00001e25, 0x0000040e, 0x00001e26, 0x00000410, 0x00001e27, 0x00000412, 0x00001e28, 0x00000414, 0x00001e29, 0x00000416, 0x00001e2a, 0x00000418, 0x00001e2b, 0x0000041a, 0x00001e2c, 0x0000041c, 0x00001e2d, 0x0000041e, 0x00001e2e, 0x00000420, 0x00001e2f, 0x00000423, 0x00001e30, 0x00000426, 0x00001e31, 0x00000428, 0x00001e32, 0x0000042a, 0x00001e33, 0x0000042c, 0x00001e34, 0x0000042e, 0x00001e35, 0x00000430, 0x00001e36, 0x00000432, 0x00001e37, 0x00000434, 0x00001e38, 0x00000436, 0x00001e39, 0x00000439, 0x00001e3a, 0x0000043c, 0x00001e3b, 0x0000043e, 0x00001e3c, 0x00000440, 0x00001e3d, 0x00000442, 0x00001e3e, 0x00000444, 0x00001e3f, 0x00000446, 0x00001e40, 0x00000448, 0x00001e41, 0x0000044a, 0x00001e42, 0x0000044c, 0x00001e43, 0x0000044e, 0x00001e44, 0x00000450, 0x00001e45, 0x00000452, 0x00001e46, 0x00000454, 0x00001e47, 0x00000456, 0x00001e48, 0x00000458, 0x00001e49, 0x0000045a, 0x00001e4a, 0x0000045c, 0x00001e4b, 0x0000045e, 0x00001e4c, 0x00000460, 0x00001e4d, 0x00000463, 0x00001e4e, 0x00000466, 0x00001e4f, 0x00000469, 0x00001e50, 0x0000046c, 0x00001e51, 0x0000046f, 0x00001e52, 0x00000472, 0x00001e53, 0x00000475, 0x00001e54, 0x00000478, 0x00001e55, 0x0000047a, 0x00001e56, 0x0000047c, 0x00001e57, 0x0000047e, 0x00001e58, 0x00000480, 0x00001e59, 0x00000482, 0x00001e5a, 0x00000484, 0x00001e5b, 0x00000486, 0x00001e5c, 0x00000488, 0x00001e5d, 0x0000048b, 0x00001e5e, 0x0000048e, 0x00001e5f, 0x00000490, 0x00001e60, 0x00000492, 0x00001e61, 0x00000494, 0x00001e62, 0x00000496, 0x00001e63, 0x00000498, 0x00001e64, 0x0000049a, 0x00001e65, 0x0000049d, 0x00001e66, 0x000004a0, 0x00001e67, 0x000004a3, 0x00001e68, 0x000004a6, 0x00001e69, 0x000004a9, 0x00001e6a, 0x000004ac, 0x00001e6b, 0x000004ae, 0x00001e6c, 0x000004b0, 0x00001e6d, 0x000004b2, 0x00001e6e, 0x000004b4, 0x00001e6f, 0x000004b6, 0x00001e70, 0x000004b8, 0x00001e71, 0x000004ba, 0x00001e72, 0x000004bc, 0x00001e73, 0x000004be, 0x00001e74, 0x000004c0, 0x00001e75, 0x000004c2, 0x00001e76, 0x000004c4, 0x00001e77, 0x000004c6, 0x00001e78, 0x000004c8, 0x00001e79, 0x000004cb, 0x00001e7a, 0x000004ce, 0x00001e7b, 0x000004d1, 0x00001e7c, 0x000004d4, 0x00001e7d, 0x000004d6, 0x00001e7e, 0x000004d8, 0x00001e7f, 0x000004da, 0x00001e80, 0x000004dc, 0x00001e81, 0x000004de, 0x00001e82, 0x000004e0, 0x00001e83, 0x000004e2, 0x00001e84, 0x000004e4, 0x00001e85, 0x000004e6, 0x00001e86, 0x000004e8, 0x00001e87, 0x000004ea, 0x00001e88, 0x000004ec, 0x00001e89, 0x000004ee, 0x00001e8a, 0x000004f0, 0x00001e8b, 0x000004f2, 0x00001e8c, 0x000004f4, 0x00001e8d, 0x000004f6, 0x00001e8e, 0x000004f8, 0x00001e8f, 0x000004fa, 0x00001e90, 0x000004fc, 0x00001e91, 0x000004fe, 0x00001e92, 0x00000500, 0x00001e93, 0x00000502, 0x00001e94, 0x00000504, 0x00001e95, 0x00000506, 0x00001e96, 0x00000508, 0x00001e97, 0x0000050a, 0x00001e98, 0x0000050c, 0x00001e99, 0x0000050e, 0x00001e9a, 0x00000510, 0x00001e9b, 0x00000512, 0x00001ea0, 0x00000514, 0x00001ea1, 0x00000516, 0x00001ea2, 0x00000518, 0x00001ea3, 0x0000051a, 0x00001ea4, 0x0000051c, 0x00001ea5, 0x0000051f, 0x00001ea6, 0x00000522, 0x00001ea7, 0x00000525, 0x00001ea8, 0x00000528, 0x00001ea9, 0x0000052b, 0x00001eaa, 0x0000052e, 0x00001eab, 0x00000531, 0x00001eac, 0x00000534, 0x00001ead, 0x00000537, 0x00001eae, 0x0000053a, 0x00001eaf, 0x0000053d, 0x00001eb0, 0x00000540, 0x00001eb1, 0x00000543, 0x00001eb2, 0x00000546, 0x00001eb3, 0x00000549, 0x00001eb4, 0x0000054c, 0x00001eb5, 0x0000054f, 0x00001eb6, 0x00000552, 0x00001eb7, 0x00000555, 0x00001eb8, 0x00000558, 0x00001eb9, 0x0000055a, 0x00001eba, 0x0000055c, 0x00001ebb, 0x0000055e, 0x00001ebc, 0x00000560, 0x00001ebd, 0x00000562, 0x00001ebe, 0x00000564, 0x00001ebf, 0x00000567, 0x00001ec0, 0x0000056a, 0x00001ec1, 0x0000056d, 0x00001ec2, 0x00000570, 0x00001ec3, 0x00000573, 0x00001ec4, 0x00000576, 0x00001ec5, 0x00000579, 0x00001ec6, 0x0000057c, 0x00001ec7, 0x0000057f, 0x00001ec8, 0x00000582, 0x00001ec9, 0x00000584, 0x00001eca, 0x00000586, 0x00001ecb, 0x00000588, 0x00001ecc, 0x0000058a, 0x00001ecd, 0x0000058c, 0x00001ece, 0x0000058e, 0x00001ecf, 0x00000590, 0x00001ed0, 0x00000592, 0x00001ed1, 0x00000595, 0x00001ed2, 0x00000598, 0x00001ed3, 0x0000059b, 0x00001ed4, 0x0000059e, 0x00001ed5, 0x000005a1, 0x00001ed6, 0x000005a4, 0x00001ed7, 0x000005a7, 0x00001ed8, 0x000005aa, 0x00001ed9, 0x000005ad, 0x00001eda, 0x000005b0, 0x00001edb, 0x000005b3, 0x00001edc, 0x000005b6, 0x00001edd, 0x000005b9, 0x00001ede, 0x000005bc, 0x00001edf, 0x000005bf, 0x00001ee0, 0x000005c2, 0x00001ee1, 0x000005c5, 0x00001ee2, 0x000005c8, 0x00001ee3, 0x000005cb, 0x00001ee4, 0x000005ce, 0x00001ee5, 0x000005d0, 0x00001ee6, 0x000005d2, 0x00001ee7, 0x000005d4, 0x00001ee8, 0x000005d6, 0x00001ee9, 0x000005d9, 0x00001eea, 0x000005dc, 0x00001eeb, 0x000005df, 0x00001eec, 0x000005e2, 0x00001eed, 0x000005e5, 0x00001eee, 0x000005e8, 0x00001eef, 0x000005eb, 0x00001ef0, 0x000005ee, 0x00001ef1, 0x000005f1, 0x00001ef2, 0x000005f4, 0x00001ef3, 0x000005f6, 0x00001ef4, 0x000005f8, 0x00001ef5, 0x000005fa, 0x00001ef6, 0x000005fc, 0x00001ef7, 0x000005fe, 0x00001ef8, 0x00000600, 0x00001ef9, 0x00000602, 0x00001f00, 0x00000604, 0x00001f01, 0x00000606, 0x00001f02, 0x00000608, 0x00001f03, 0x0000060b, 0x00001f04, 0x0000060e, 0x00001f05, 0x00000611, 0x00001f06, 0x00000614, 0x00001f07, 0x00000617, 0x00001f08, 0x0000061a, 0x00001f09, 0x0000061c, 0x00001f0a, 0x0000061e, 0x00001f0b, 0x00000621, 0x00001f0c, 0x00000624, 0x00001f0d, 0x00000627, 0x00001f0e, 0x0000062a, 0x00001f0f, 0x0000062d, 0x00001f10, 0x00000630, 0x00001f11, 0x00000632, 0x00001f12, 0x00000634, 0x00001f13, 0x00000637, 0x00001f14, 0x0000063a, 0x00001f15, 0x0000063d, 0x00001f18, 0x00000640, 0x00001f19, 0x00000642, 0x00001f1a, 0x00000644, 0x00001f1b, 0x00000647, 0x00001f1c, 0x0000064a, 0x00001f1d, 0x0000064d, 0x00001f20, 0x00000650, 0x00001f21, 0x00000652, 0x00001f22, 0x00000654, 0x00001f23, 0x00000657, 0x00001f24, 0x0000065a, 0x00001f25, 0x0000065d, 0x00001f26, 0x00000660, 0x00001f27, 0x00000663, 0x00001f28, 0x00000666, 0x00001f29, 0x00000668, 0x00001f2a, 0x0000066a, 0x00001f2b, 0x0000066d, 0x00001f2c, 0x00000670, 0x00001f2d, 0x00000673, 0x00001f2e, 0x00000676, 0x00001f2f, 0x00000679, 0x00001f30, 0x0000067c, 0x00001f31, 0x0000067e, 0x00001f32, 0x00000680, 0x00001f33, 0x00000683, 0x00001f34, 0x00000686, 0x00001f35, 0x00000689, 0x00001f36, 0x0000068c, 0x00001f37, 0x0000068f, 0x00001f38, 0x00000692, 0x00001f39, 0x00000694, 0x00001f3a, 0x00000696, 0x00001f3b, 0x00000699, 0x00001f3c, 0x0000069c, 0x00001f3d, 0x0000069f, 0x00001f3e, 0x000006a2, 0x00001f3f, 0x000006a5, 0x00001f40, 0x000006a8, 0x00001f41, 0x000006aa, 0x00001f42, 0x000006ac, 0x00001f43, 0x000006af, 0x00001f44, 0x000006b2, 0x00001f45, 0x000006b5, 0x00001f48, 0x000006b8, 0x00001f49, 0x000006ba, 0x00001f4a, 0x000006bc, 0x00001f4b, 0x000006bf, 0x00001f4c, 0x000006c2, 0x00001f4d, 0x000006c5, 0x00001f50, 0x000006c8, 0x00001f51, 0x000006ca, 0x00001f52, 0x000006cc, 0x00001f53, 0x000006cf, 0x00001f54, 0x000006d2, 0x00001f55, 0x000006d5, 0x00001f56, 0x000006d8, 0x00001f57, 0x000006db, 0x00001f59, 0x000006de, 0x00001f5b, 0x000006e0, 0x00001f5d, 0x000006e3, 0x00001f5f, 0x000006e6, 0x00001f60, 0x000006e9, 0x00001f61, 0x000006eb, 0x00001f62, 0x000006ed, 0x00001f63, 0x000006f0, 0x00001f64, 0x000006f3, 0x00001f65, 0x000006f6, 0x00001f66, 0x000006f9, 0x00001f67, 0x000006fc, 0x00001f68, 0x000006ff, 0x00001f69, 0x00000701, 0x00001f6a, 0x00000703, 0x00001f6b, 0x00000706, 0x00001f6c, 0x00000709, 0x00001f6d, 0x0000070c, 0x00001f6e, 0x0000070f, 0x00001f6f, 0x00000712, 0x00001f70, 0x00000715, 0x00001f71, 0x00000717, 0x00001f72, 0x00000719, 0x00001f73, 0x0000071b, 0x00001f74, 0x0000071d, 0x00001f75, 0x0000071f, 0x00001f76, 0x00000721, 0x00001f77, 0x00000723, 0x00001f78, 0x00000725, 0x00001f79, 0x00000727, 0x00001f7a, 0x00000729, 0x00001f7b, 0x0000072b, 0x00001f7c, 0x0000072d, 0x00001f7d, 0x0000072f, 0x00001f80, 0x00000731, 0x00001f81, 0x00000734, 0x00001f82, 0x00000737, 0x00001f83, 0x0000073b, 0x00001f84, 0x0000073f, 0x00001f85, 0x00000743, 0x00001f86, 0x00000747, 0x00001f87, 0x0000074b, 0x00001f88, 0x0000074f, 0x00001f89, 0x00000752, 0x00001f8a, 0x00000755, 0x00001f8b, 0x00000759, 0x00001f8c, 0x0000075d, 0x00001f8d, 0x00000761, 0x00001f8e, 0x00000765, 0x00001f8f, 0x00000769, 0x00001f90, 0x0000076d, 0x00001f91, 0x00000770, 0x00001f92, 0x00000773, 0x00001f93, 0x00000777, 0x00001f94, 0x0000077b, 0x00001f95, 0x0000077f, 0x00001f96, 0x00000783, 0x00001f97, 0x00000787, 0x00001f98, 0x0000078b, 0x00001f99, 0x0000078e, 0x00001f9a, 0x00000791, 0x00001f9b, 0x00000795, 0x00001f9c, 0x00000799, 0x00001f9d, 0x0000079d, 0x00001f9e, 0x000007a1, 0x00001f9f, 0x000007a5, 0x00001fa0, 0x000007a9, 0x00001fa1, 0x000007ac, 0x00001fa2, 0x000007af, 0x00001fa3, 0x000007b3, 0x00001fa4, 0x000007b7, 0x00001fa5, 0x000007bb, 0x00001fa6, 0x000007bf, 0x00001fa7, 0x000007c3, 0x00001fa8, 0x000007c7, 0x00001fa9, 0x000007ca, 0x00001faa, 0x000007cd, 0x00001fab, 0x000007d1, 0x00001fac, 0x000007d5, 0x00001fad, 0x000007d9, 0x00001fae, 0x000007dd, 0x00001faf, 0x000007e1, 0x00001fb0, 0x000007e5, 0x00001fb1, 0x000007e7, 0x00001fb2, 0x000007e9, 0x00001fb3, 0x000007ec, 0x00001fb4, 0x000007ee, 0x00001fb6, 0x000007f1, 0x00001fb7, 0x000007f3, 0x00001fb8, 0x000007f6, 0x00001fb9, 0x000007f8, 0x00001fba, 0x000007fa, 0x00001fbb, 0x000007fc, 0x00001fbc, 0x000007fe, 0x00001fbd, 0x00000800, 0x00001fbe, 0x00000802, 0x00001fbf, 0x00000803, 0x00001fc0, 0x00000805, 0x00001fc1, 0x00000807, 0x00001fc2, 0x0000080a, 0x00001fc3, 0x0000080d, 0x00001fc4, 0x0000080f, 0x00001fc6, 0x00000812, 0x00001fc7, 0x00000814, 0x00001fc8, 0x00000817, 0x00001fc9, 0x00000819, 0x00001fca, 0x0000081b, 0x00001fcb, 0x0000081d, 0x00001fcc, 0x0000081f, 0x00001fcd, 0x00000821, 0x00001fce, 0x00000824, 0x00001fcf, 0x00000827, 0x00001fd0, 0x0000082a, 0x00001fd1, 0x0000082c, 0x00001fd2, 0x0000082e, 0x00001fd3, 0x00000831, 0x00001fd6, 0x00000834, 0x00001fd7, 0x00000836, 0x00001fd8, 0x00000839, 0x00001fd9, 0x0000083b, 0x00001fda, 0x0000083d, 0x00001fdb, 0x0000083f, 0x00001fdd, 0x00000841, 0x00001fde, 0x00000844, 0x00001fdf, 0x00000847, 0x00001fe0, 0x0000084a, 0x00001fe1, 0x0000084c, 0x00001fe2, 0x0000084e, 0x00001fe3, 0x00000851, 0x00001fe4, 0x00000854, 0x00001fe5, 0x00000856, 0x00001fe6, 0x00000858, 0x00001fe7, 0x0000085a, 0x00001fe8, 0x0000085d, 0x00001fe9, 0x0000085f, 0x00001fea, 0x00000861, 0x00001feb, 0x00000863, 0x00001fec, 0x00000865, 0x00001fed, 0x00000867, 0x00001fee, 0x0000086a, 0x00001fef, 0x0000086d, 0x00001ff2, 0x0000086e, 0x00001ff3, 0x00000871, 0x00001ff4, 0x00000873, 0x00001ff6, 0x00000876, 0x00001ff7, 0x00000878, 0x00001ff8, 0x0000087b, 0x00001ff9, 0x0000087d, 0x00001ffa, 0x0000087f, 0x00001ffb, 0x00000881, 0x00001ffc, 0x00000883, 0x00001ffd, 0x00000885, 0x00001ffe, 0x00000887, 0x00002000, 0x00000889, 0x00002001, 0x0000088a, 0x00002002, 0x0000088b, 0x00002003, 0x0000088c, 0x00002004, 0x0000088d, 0x00002005, 0x0000088e, 0x00002006, 0x0000088f, 0x00002007, 0x00000890, 0x00002008, 0x00000891, 0x00002009, 0x00000892, 0x0000200a, 0x00000893, 0x00002011, 0x00000894, 0x00002017, 0x00000895, 0x00002024, 0x00000897, 0x00002025, 0x00000898, 0x00002026, 0x0000089a, 0x0000202f, 0x0000089d, 0x00002033, 0x0000089e, 0x00002034, 0x000008a0, 0x00002036, 0x000008a3, 0x00002037, 0x000008a5, 0x0000203c, 0x000008a8, 0x0000203e, 0x000008aa, 0x00002047, 0x000008ac, 0x00002048, 0x000008ae, 0x00002049, 0x000008b0, 0x00002057, 0x000008b2, 0x0000205f, 0x000008b6, 0x00002070, 0x000008b7, 0x00002071, 0x000008b8, 0x00002074, 0x000008b9, 0x00002075, 0x000008ba, 0x00002076, 0x000008bb, 0x00002077, 0x000008bc, 0x00002078, 0x000008bd, 0x00002079, 0x000008be, 0x0000207a, 0x000008bf, 0x0000207b, 0x000008c0, 0x0000207c, 0x000008c1, 0x0000207d, 0x000008c2, 0x0000207e, 0x000008c3, 0x0000207f, 0x000008c4, 0x00002080, 0x000008c5, 0x00002081, 0x000008c6, 0x00002082, 0x000008c7, 0x00002083, 0x000008c8, 0x00002084, 0x000008c9, 0x00002085, 0x000008ca, 0x00002086, 0x000008cb, 0x00002087, 0x000008cc, 0x00002088, 0x000008cd, 0x00002089, 0x000008ce, 0x0000208a, 0x000008cf, 0x0000208b, 0x000008d0, 0x0000208c, 0x000008d1, 0x0000208d, 0x000008d2, 0x0000208e, 0x000008d3, 0x000020a8, 0x000008d4, 0x00002100, 0x000008d6, 0x00002101, 0x000008d9, 0x00002102, 0x000008dc, 0x00002103, 0x000008dd, 0x00002105, 0x000008df, 0x00002106, 0x000008e2, 0x00002107, 0x000008e5, 0x00002109, 0x000008e6, 0x0000210a, 0x000008e8, 0x0000210b, 0x000008e9, 0x0000210c, 0x000008ea, 0x0000210d, 0x000008eb, 0x0000210e, 0x000008ec, 0x0000210f, 0x000008ed, 0x00002110, 0x000008ee, 0x00002111, 0x000008ef, 0x00002112, 0x000008f0, 0x00002113, 0x000008f1, 0x00002115, 0x000008f2, 0x00002116, 0x000008f3, 0x00002119, 0x000008f5, 0x0000211a, 0x000008f6, 0x0000211b, 0x000008f7, 0x0000211c, 0x000008f8, 0x0000211d, 0x000008f9, 0x00002120, 0x000008fa, 0x00002121, 0x000008fc, 0x00002122, 0x000008ff, 0x00002124, 0x00000901, 0x00002126, 0x00000902, 0x00002128, 0x00000903, 0x0000212a, 0x00000904, 0x0000212b, 0x00000905, 0x0000212c, 0x00000907, 0x0000212d, 0x00000908, 0x0000212f, 0x00000909, 0x00002130, 0x0000090a, 0x00002131, 0x0000090b, 0x00002133, 0x0000090c, 0x00002134, 0x0000090d, 0x00002135, 0x0000090e, 0x00002136, 0x0000090f, 0x00002137, 0x00000910, 0x00002138, 0x00000911, 0x00002139, 0x00000912, 0x0000213d, 0x00000913, 0x0000213e, 0x00000914, 0x0000213f, 0x00000915, 0x00002140, 0x00000916, 0x00002145, 0x00000917, 0x00002146, 0x00000918, 0x00002147, 0x00000919, 0x00002148, 0x0000091a, 0x00002149, 0x0000091b, 0x00002153, 0x0000091c, 0x00002154, 0x0000091f, 0x00002155, 0x00000922, 0x00002156, 0x00000925, 0x00002157, 0x00000928, 0x00002158, 0x0000092b, 0x00002159, 0x0000092e, 0x0000215a, 0x00000931, 0x0000215b, 0x00000934, 0x0000215c, 0x00000937, 0x0000215d, 0x0000093a, 0x0000215e, 0x0000093d, 0x0000215f, 0x00000940, 0x00002160, 0x00000942, 0x00002161, 0x00000943, 0x00002162, 0x00000945, 0x00002163, 0x00000948, 0x00002164, 0x0000094a, 0x00002165, 0x0000094b, 0x00002166, 0x0000094d, 0x00002167, 0x00000950, 0x00002168, 0x00000954, 0x00002169, 0x00000956, 0x0000216a, 0x00000957, 0x0000216b, 0x00000959, 0x0000216c, 0x0000095c, 0x0000216d, 0x0000095d, 0x0000216e, 0x0000095e, 0x0000216f, 0x0000095f, 0x00002170, 0x00000960, 0x00002171, 0x00000961, 0x00002172, 0x00000963, 0x00002173, 0x00000966, 0x00002174, 0x00000968, 0x00002175, 0x00000969, 0x00002176, 0x0000096b, 0x00002177, 0x0000096e, 0x00002178, 0x00000972, 0x00002179, 0x00000974, 0x0000217a, 0x00000975, 0x0000217b, 0x00000977, 0x0000217c, 0x0000097a, 0x0000217d, 0x0000097b, 0x0000217e, 0x0000097c, 0x0000217f, 0x0000097d, 0x0000219a, 0x0000097e, 0x0000219b, 0x00000980, 0x000021ae, 0x00000982, 0x000021cd, 0x00000984, 0x000021ce, 0x00000986, 0x000021cf, 0x00000988, 0x00002204, 0x0000098a, 0x00002209, 0x0000098c, 0x0000220c, 0x0000098e, 0x00002224, 0x00000990, 0x00002226, 0x00000992, 0x0000222c, 0x00000994, 0x0000222d, 0x00000996, 0x0000222f, 0x00000999, 0x00002230, 0x0000099b, 0x00002241, 0x0000099e, 0x00002244, 0x000009a0, 0x00002247, 0x000009a2, 0x00002249, 0x000009a4, 0x00002260, 0x000009a6, 0x00002262, 0x000009a8, 0x0000226d, 0x000009aa, 0x0000226e, 0x000009ac, 0x0000226f, 0x000009ae, 0x00002270, 0x000009b0, 0x00002271, 0x000009b2, 0x00002274, 0x000009b4, 0x00002275, 0x000009b6, 0x00002278, 0x000009b8, 0x00002279, 0x000009ba, 0x00002280, 0x000009bc, 0x00002281, 0x000009be, 0x00002284, 0x000009c0, 0x00002285, 0x000009c2, 0x00002288, 0x000009c4, 0x00002289, 0x000009c6, 0x000022ac, 0x000009c8, 0x000022ad, 0x000009ca, 0x000022ae, 0x000009cc, 0x000022af, 0x000009ce, 0x000022e0, 0x000009d0, 0x000022e1, 0x000009d2, 0x000022e2, 0x000009d4, 0x000022e3, 0x000009d6, 0x000022ea, 0x000009d8, 0x000022eb, 0x000009da, 0x000022ec, 0x000009dc, 0x000022ed, 0x000009de, 0x00002329, 0x000009e0, 0x0000232a, 0x000009e1, 0x00002460, 0x000009e2, 0x00002461, 0x000009e3, 0x00002462, 0x000009e4, 0x00002463, 0x000009e5, 0x00002464, 0x000009e6, 0x00002465, 0x000009e7, 0x00002466, 0x000009e8, 0x00002467, 0x000009e9, 0x00002468, 0x000009ea, 0x00002469, 0x000009eb, 0x0000246a, 0x000009ed, 0x0000246b, 0x000009ef, 0x0000246c, 0x000009f1, 0x0000246d, 0x000009f3, 0x0000246e, 0x000009f5, 0x0000246f, 0x000009f7, 0x00002470, 0x000009f9, 0x00002471, 0x000009fb, 0x00002472, 0x000009fd, 0x00002473, 0x000009ff, 0x00002474, 0x00000a01, 0x00002475, 0x00000a04, 0x00002476, 0x00000a07, 0x00002477, 0x00000a0a, 0x00002478, 0x00000a0d, 0x00002479, 0x00000a10, 0x0000247a, 0x00000a13, 0x0000247b, 0x00000a16, 0x0000247c, 0x00000a19, 0x0000247d, 0x00000a1c, 0x0000247e, 0x00000a20, 0x0000247f, 0x00000a24, 0x00002480, 0x00000a28, 0x00002481, 0x00000a2c, 0x00002482, 0x00000a30, 0x00002483, 0x00000a34, 0x00002484, 0x00000a38, 0x00002485, 0x00000a3c, 0x00002486, 0x00000a40, 0x00002487, 0x00000a44, 0x00002488, 0x00000a48, 0x00002489, 0x00000a4a, 0x0000248a, 0x00000a4c, 0x0000248b, 0x00000a4e, 0x0000248c, 0x00000a50, 0x0000248d, 0x00000a52, 0x0000248e, 0x00000a54, 0x0000248f, 0x00000a56, 0x00002490, 0x00000a58, 0x00002491, 0x00000a5a, 0x00002492, 0x00000a5d, 0x00002493, 0x00000a60, 0x00002494, 0x00000a63, 0x00002495, 0x00000a66, 0x00002496, 0x00000a69, 0x00002497, 0x00000a6c, 0x00002498, 0x00000a6f, 0x00002499, 0x00000a72, 0x0000249a, 0x00000a75, 0x0000249b, 0x00000a78, 0x0000249c, 0x00000a7b, 0x0000249d, 0x00000a7e, 0x0000249e, 0x00000a81, 0x0000249f, 0x00000a84, 0x000024a0, 0x00000a87, 0x000024a1, 0x00000a8a, 0x000024a2, 0x00000a8d, 0x000024a3, 0x00000a90, 0x000024a4, 0x00000a93, 0x000024a5, 0x00000a96, 0x000024a6, 0x00000a99, 0x000024a7, 0x00000a9c, 0x000024a8, 0x00000a9f, 0x000024a9, 0x00000aa2, 0x000024aa, 0x00000aa5, 0x000024ab, 0x00000aa8, 0x000024ac, 0x00000aab, 0x000024ad, 0x00000aae, 0x000024ae, 0x00000ab1, 0x000024af, 0x00000ab4, 0x000024b0, 0x00000ab7, 0x000024b1, 0x00000aba, 0x000024b2, 0x00000abd, 0x000024b3, 0x00000ac0, 0x000024b4, 0x00000ac3, 0x000024b5, 0x00000ac6, 0x000024b6, 0x00000ac9, 0x000024b7, 0x00000aca, 0x000024b8, 0x00000acb, 0x000024b9, 0x00000acc, 0x000024ba, 0x00000acd, 0x000024bb, 0x00000ace, 0x000024bc, 0x00000acf, 0x000024bd, 0x00000ad0, 0x000024be, 0x00000ad1, 0x000024bf, 0x00000ad2, 0x000024c0, 0x00000ad3, 0x000024c1, 0x00000ad4, 0x000024c2, 0x00000ad5, 0x000024c3, 0x00000ad6, 0x000024c4, 0x00000ad7, 0x000024c5, 0x00000ad8, 0x000024c6, 0x00000ad9, 0x000024c7, 0x00000ada, 0x000024c8, 0x00000adb, 0x000024c9, 0x00000adc, 0x000024ca, 0x00000add, 0x000024cb, 0x00000ade, 0x000024cc, 0x00000adf, 0x000024cd, 0x00000ae0, 0x000024ce, 0x00000ae1, 0x000024cf, 0x00000ae2, 0x000024d0, 0x00000ae3, 0x000024d1, 0x00000ae4, 0x000024d2, 0x00000ae5, 0x000024d3, 0x00000ae6, 0x000024d4, 0x00000ae7, 0x000024d5, 0x00000ae8, 0x000024d6, 0x00000ae9, 0x000024d7, 0x00000aea, 0x000024d8, 0x00000aeb, 0x000024d9, 0x00000aec, 0x000024da, 0x00000aed, 0x000024db, 0x00000aee, 0x000024dc, 0x00000aef, 0x000024dd, 0x00000af0, 0x000024de, 0x00000af1, 0x000024df, 0x00000af2, 0x000024e0, 0x00000af3, 0x000024e1, 0x00000af4, 0x000024e2, 0x00000af5, 0x000024e3, 0x00000af6, 0x000024e4, 0x00000af7, 0x000024e5, 0x00000af8, 0x000024e6, 0x00000af9, 0x000024e7, 0x00000afa, 0x000024e8, 0x00000afb, 0x000024e9, 0x00000afc, 0x000024ea, 0x00000afd, 0x00002a0c, 0x00000afe, 0x00002a74, 0x00000b02, 0x00002a75, 0x00000b05, 0x00002a76, 0x00000b07, 0x00002adc, 0x00000b0a, 0x00002e9f, 0x00000b0c, 0x00002ef3, 0x00000b0d, 0x00002f00, 0x00000b0e, 0x00002f01, 0x00000b0f, 0x00002f02, 0x00000b10, 0x00002f03, 0x00000b11, 0x00002f04, 0x00000b12, 0x00002f05, 0x00000b13, 0x00002f06, 0x00000b14, 0x00002f07, 0x00000b15, 0x00002f08, 0x00000b16, 0x00002f09, 0x00000b17, 0x00002f0a, 0x00000b18, 0x00002f0b, 0x00000b19, 0x00002f0c, 0x00000b1a, 0x00002f0d, 0x00000b1b, 0x00002f0e, 0x00000b1c, 0x00002f0f, 0x00000b1d, 0x00002f10, 0x00000b1e, 0x00002f11, 0x00000b1f, 0x00002f12, 0x00000b20, 0x00002f13, 0x00000b21, 0x00002f14, 0x00000b22, 0x00002f15, 0x00000b23, 0x00002f16, 0x00000b24, 0x00002f17, 0x00000b25, 0x00002f18, 0x00000b26, 0x00002f19, 0x00000b27, 0x00002f1a, 0x00000b28, 0x00002f1b, 0x00000b29, 0x00002f1c, 0x00000b2a, 0x00002f1d, 0x00000b2b, 0x00002f1e, 0x00000b2c, 0x00002f1f, 0x00000b2d, 0x00002f20, 0x00000b2e, 0x00002f21, 0x00000b2f, 0x00002f22, 0x00000b30, 0x00002f23, 0x00000b31, 0x00002f24, 0x00000b32, 0x00002f25, 0x00000b33, 0x00002f26, 0x00000b34, 0x00002f27, 0x00000b35, 0x00002f28, 0x00000b36, 0x00002f29, 0x00000b37, 0x00002f2a, 0x00000b38, 0x00002f2b, 0x00000b39, 0x00002f2c, 0x00000b3a, 0x00002f2d, 0x00000b3b, 0x00002f2e, 0x00000b3c, 0x00002f2f, 0x00000b3d, 0x00002f30, 0x00000b3e, 0x00002f31, 0x00000b3f, 0x00002f32, 0x00000b40, 0x00002f33, 0x00000b41, 0x00002f34, 0x00000b42, 0x00002f35, 0x00000b43, 0x00002f36, 0x00000b44, 0x00002f37, 0x00000b45, 0x00002f38, 0x00000b46, 0x00002f39, 0x00000b47, 0x00002f3a, 0x00000b48, 0x00002f3b, 0x00000b49, 0x00002f3c, 0x00000b4a, 0x00002f3d, 0x00000b4b, 0x00002f3e, 0x00000b4c, 0x00002f3f, 0x00000b4d, 0x00002f40, 0x00000b4e, 0x00002f41, 0x00000b4f, 0x00002f42, 0x00000b50, 0x00002f43, 0x00000b51, 0x00002f44, 0x00000b52, 0x00002f45, 0x00000b53, 0x00002f46, 0x00000b54, 0x00002f47, 0x00000b55, 0x00002f48, 0x00000b56, 0x00002f49, 0x00000b57, 0x00002f4a, 0x00000b58, 0x00002f4b, 0x00000b59, 0x00002f4c, 0x00000b5a, 0x00002f4d, 0x00000b5b, 0x00002f4e, 0x00000b5c, 0x00002f4f, 0x00000b5d, 0x00002f50, 0x00000b5e, 0x00002f51, 0x00000b5f, 0x00002f52, 0x00000b60, 0x00002f53, 0x00000b61, 0x00002f54, 0x00000b62, 0x00002f55, 0x00000b63, 0x00002f56, 0x00000b64, 0x00002f57, 0x00000b65, 0x00002f58, 0x00000b66, 0x00002f59, 0x00000b67, 0x00002f5a, 0x00000b68, 0x00002f5b, 0x00000b69, 0x00002f5c, 0x00000b6a, 0x00002f5d, 0x00000b6b, 0x00002f5e, 0x00000b6c, 0x00002f5f, 0x00000b6d, 0x00002f60, 0x00000b6e, 0x00002f61, 0x00000b6f, 0x00002f62, 0x00000b70, 0x00002f63, 0x00000b71, 0x00002f64, 0x00000b72, 0x00002f65, 0x00000b73, 0x00002f66, 0x00000b74, 0x00002f67, 0x00000b75, 0x00002f68, 0x00000b76, 0x00002f69, 0x00000b77, 0x00002f6a, 0x00000b78, 0x00002f6b, 0x00000b79, 0x00002f6c, 0x00000b7a, 0x00002f6d, 0x00000b7b, 0x00002f6e, 0x00000b7c, 0x00002f6f, 0x00000b7d, 0x00002f70, 0x00000b7e, 0x00002f71, 0x00000b7f, 0x00002f72, 0x00000b80, 0x00002f73, 0x00000b81, 0x00002f74, 0x00000b82, 0x00002f75, 0x00000b83, 0x00002f76, 0x00000b84, 0x00002f77, 0x00000b85, 0x00002f78, 0x00000b86, 0x00002f79, 0x00000b87, 0x00002f7a, 0x00000b88, 0x00002f7b, 0x00000b89, 0x00002f7c, 0x00000b8a, 0x00002f7d, 0x00000b8b, 0x00002f7e, 0x00000b8c, 0x00002f7f, 0x00000b8d, 0x00002f80, 0x00000b8e, 0x00002f81, 0x00000b8f, 0x00002f82, 0x00000b90, 0x00002f83, 0x00000b91, 0x00002f84, 0x00000b92, 0x00002f85, 0x00000b93, 0x00002f86, 0x00000b94, 0x00002f87, 0x00000b95, 0x00002f88, 0x00000b96, 0x00002f89, 0x00000b97, 0x00002f8a, 0x00000b98, 0x00002f8b, 0x00000b99, 0x00002f8c, 0x00000b9a, 0x00002f8d, 0x00000b9b, 0x00002f8e, 0x00000b9c, 0x00002f8f, 0x00000b9d, 0x00002f90, 0x00000b9e, 0x00002f91, 0x00000b9f, 0x00002f92, 0x00000ba0, 0x00002f93, 0x00000ba1, 0x00002f94, 0x00000ba2, 0x00002f95, 0x00000ba3, 0x00002f96, 0x00000ba4, 0x00002f97, 0x00000ba5, 0x00002f98, 0x00000ba6, 0x00002f99, 0x00000ba7, 0x00002f9a, 0x00000ba8, 0x00002f9b, 0x00000ba9, 0x00002f9c, 0x00000baa, 0x00002f9d, 0x00000bab, 0x00002f9e, 0x00000bac, 0x00002f9f, 0x00000bad, 0x00002fa0, 0x00000bae, 0x00002fa1, 0x00000baf, 0x00002fa2, 0x00000bb0, 0x00002fa3, 0x00000bb1, 0x00002fa4, 0x00000bb2, 0x00002fa5, 0x00000bb3, 0x00002fa6, 0x00000bb4, 0x00002fa7, 0x00000bb5, 0x00002fa8, 0x00000bb6, 0x00002fa9, 0x00000bb7, 0x00002faa, 0x00000bb8, 0x00002fab, 0x00000bb9, 0x00002fac, 0x00000bba, 0x00002fad, 0x00000bbb, 0x00002fae, 0x00000bbc, 0x00002faf, 0x00000bbd, 0x00002fb0, 0x00000bbe, 0x00002fb1, 0x00000bbf, 0x00002fb2, 0x00000bc0, 0x00002fb3, 0x00000bc1, 0x00002fb4, 0x00000bc2, 0x00002fb5, 0x00000bc3, 0x00002fb6, 0x00000bc4, 0x00002fb7, 0x00000bc5, 0x00002fb8, 0x00000bc6, 0x00002fb9, 0x00000bc7, 0x00002fba, 0x00000bc8, 0x00002fbb, 0x00000bc9, 0x00002fbc, 0x00000bca, 0x00002fbd, 0x00000bcb, 0x00002fbe, 0x00000bcc, 0x00002fbf, 0x00000bcd, 0x00002fc0, 0x00000bce, 0x00002fc1, 0x00000bcf, 0x00002fc2, 0x00000bd0, 0x00002fc3, 0x00000bd1, 0x00002fc4, 0x00000bd2, 0x00002fc5, 0x00000bd3, 0x00002fc6, 0x00000bd4, 0x00002fc7, 0x00000bd5, 0x00002fc8, 0x00000bd6, 0x00002fc9, 0x00000bd7, 0x00002fca, 0x00000bd8, 0x00002fcb, 0x00000bd9, 0x00002fcc, 0x00000bda, 0x00002fcd, 0x00000bdb, 0x00002fce, 0x00000bdc, 0x00002fcf, 0x00000bdd, 0x00002fd0, 0x00000bde, 0x00002fd1, 0x00000bdf, 0x00002fd2, 0x00000be0, 0x00002fd3, 0x00000be1, 0x00002fd4, 0x00000be2, 0x00002fd5, 0x00000be3, 0x00003000, 0x00000be4, 0x00003036, 0x00000be5, 0x00003038, 0x00000be6, 0x00003039, 0x00000be7, 0x0000303a, 0x00000be8, 0x0000304c, 0x00000be9, 0x0000304e, 0x00000beb, 0x00003050, 0x00000bed, 0x00003052, 0x00000bef, 0x00003054, 0x00000bf1, 0x00003056, 0x00000bf3, 0x00003058, 0x00000bf5, 0x0000305a, 0x00000bf7, 0x0000305c, 0x00000bf9, 0x0000305e, 0x00000bfb, 0x00003060, 0x00000bfd, 0x00003062, 0x00000bff, 0x00003065, 0x00000c01, 0x00003067, 0x00000c03, 0x00003069, 0x00000c05, 0x00003070, 0x00000c07, 0x00003071, 0x00000c09, 0x00003073, 0x00000c0b, 0x00003074, 0x00000c0d, 0x00003076, 0x00000c0f, 0x00003077, 0x00000c11, 0x00003079, 0x00000c13, 0x0000307a, 0x00000c15, 0x0000307c, 0x00000c17, 0x0000307d, 0x00000c19, 0x00003094, 0x00000c1b, 0x0000309b, 0x00000c1d, 0x0000309c, 0x00000c1f, 0x0000309e, 0x00000c21, 0x0000309f, 0x00000c23, 0x000030ac, 0x00000c25, 0x000030ae, 0x00000c27, 0x000030b0, 0x00000c29, 0x000030b2, 0x00000c2b, 0x000030b4, 0x00000c2d, 0x000030b6, 0x00000c2f, 0x000030b8, 0x00000c31, 0x000030ba, 0x00000c33, 0x000030bc, 0x00000c35, 0x000030be, 0x00000c37, 0x000030c0, 0x00000c39, 0x000030c2, 0x00000c3b, 0x000030c5, 0x00000c3d, 0x000030c7, 0x00000c3f, 0x000030c9, 0x00000c41, 0x000030d0, 0x00000c43, 0x000030d1, 0x00000c45, 0x000030d3, 0x00000c47, 0x000030d4, 0x00000c49, 0x000030d6, 0x00000c4b, 0x000030d7, 0x00000c4d, 0x000030d9, 0x00000c4f, 0x000030da, 0x00000c51, 0x000030dc, 0x00000c53, 0x000030dd, 0x00000c55, 0x000030f4, 0x00000c57, 0x000030f7, 0x00000c59, 0x000030f8, 0x00000c5b, 0x000030f9, 0x00000c5d, 0x000030fa, 0x00000c5f, 0x000030fe, 0x00000c61, 0x000030ff, 0x00000c63, 0x00003131, 0x00000c65, 0x00003132, 0x00000c66, 0x00003133, 0x00000c67, 0x00003134, 0x00000c68, 0x00003135, 0x00000c69, 0x00003136, 0x00000c6a, 0x00003137, 0x00000c6b, 0x00003138, 0x00000c6c, 0x00003139, 0x00000c6d, 0x0000313a, 0x00000c6e, 0x0000313b, 0x00000c6f, 0x0000313c, 0x00000c70, 0x0000313d, 0x00000c71, 0x0000313e, 0x00000c72, 0x0000313f, 0x00000c73, 0x00003140, 0x00000c74, 0x00003141, 0x00000c75, 0x00003142, 0x00000c76, 0x00003143, 0x00000c77, 0x00003144, 0x00000c78, 0x00003145, 0x00000c79, 0x00003146, 0x00000c7a, 0x00003147, 0x00000c7b, 0x00003148, 0x00000c7c, 0x00003149, 0x00000c7d, 0x0000314a, 0x00000c7e, 0x0000314b, 0x00000c7f, 0x0000314c, 0x00000c80, 0x0000314d, 0x00000c81, 0x0000314e, 0x00000c82, 0x0000314f, 0x00000c83, 0x00003150, 0x00000c84, 0x00003151, 0x00000c85, 0x00003152, 0x00000c86, 0x00003153, 0x00000c87, 0x00003154, 0x00000c88, 0x00003155, 0x00000c89, 0x00003156, 0x00000c8a, 0x00003157, 0x00000c8b, 0x00003158, 0x00000c8c, 0x00003159, 0x00000c8d, 0x0000315a, 0x00000c8e, 0x0000315b, 0x00000c8f, 0x0000315c, 0x00000c90, 0x0000315d, 0x00000c91, 0x0000315e, 0x00000c92, 0x0000315f, 0x00000c93, 0x00003160, 0x00000c94, 0x00003161, 0x00000c95, 0x00003162, 0x00000c96, 0x00003163, 0x00000c97, 0x00003164, 0x00000c98, 0x00003165, 0x00000c99, 0x00003166, 0x00000c9a, 0x00003167, 0x00000c9b, 0x00003168, 0x00000c9c, 0x00003169, 0x00000c9d, 0x0000316a, 0x00000c9e, 0x0000316b, 0x00000c9f, 0x0000316c, 0x00000ca0, 0x0000316d, 0x00000ca1, 0x0000316e, 0x00000ca2, 0x0000316f, 0x00000ca3, 0x00003170, 0x00000ca4, 0x00003171, 0x00000ca5, 0x00003172, 0x00000ca6, 0x00003173, 0x00000ca7, 0x00003174, 0x00000ca8, 0x00003175, 0x00000ca9, 0x00003176, 0x00000caa, 0x00003177, 0x00000cab, 0x00003178, 0x00000cac, 0x00003179, 0x00000cad, 0x0000317a, 0x00000cae, 0x0000317b, 0x00000caf, 0x0000317c, 0x00000cb0, 0x0000317d, 0x00000cb1, 0x0000317e, 0x00000cb2, 0x0000317f, 0x00000cb3, 0x00003180, 0x00000cb4, 0x00003181, 0x00000cb5, 0x00003182, 0x00000cb6, 0x00003183, 0x00000cb7, 0x00003184, 0x00000cb8, 0x00003185, 0x00000cb9, 0x00003186, 0x00000cba, 0x00003187, 0x00000cbb, 0x00003188, 0x00000cbc, 0x00003189, 0x00000cbd, 0x0000318a, 0x00000cbe, 0x0000318b, 0x00000cbf, 0x0000318c, 0x00000cc0, 0x0000318d, 0x00000cc1, 0x0000318e, 0x00000cc2, 0x00003192, 0x00000cc3, 0x00003193, 0x00000cc4, 0x00003194, 0x00000cc5, 0x00003195, 0x00000cc6, 0x00003196, 0x00000cc7, 0x00003197, 0x00000cc8, 0x00003198, 0x00000cc9, 0x00003199, 0x00000cca, 0x0000319a, 0x00000ccb, 0x0000319b, 0x00000ccc, 0x0000319c, 0x00000ccd, 0x0000319d, 0x00000cce, 0x0000319e, 0x00000ccf, 0x0000319f, 0x00000cd0, 0x00003200, 0x00000cd1, 0x00003201, 0x00000cd4, 0x00003202, 0x00000cd7, 0x00003203, 0x00000cda, 0x00003204, 0x00000cdd, 0x00003205, 0x00000ce0, 0x00003206, 0x00000ce3, 0x00003207, 0x00000ce6, 0x00003208, 0x00000ce9, 0x00003209, 0x00000cec, 0x0000320a, 0x00000cef, 0x0000320b, 0x00000cf2, 0x0000320c, 0x00000cf5, 0x0000320d, 0x00000cf8, 0x0000320e, 0x00000cfb, 0x0000320f, 0x00000cff, 0x00003210, 0x00000d03, 0x00003211, 0x00000d07, 0x00003212, 0x00000d0b, 0x00003213, 0x00000d0f, 0x00003214, 0x00000d13, 0x00003215, 0x00000d17, 0x00003216, 0x00000d1b, 0x00003217, 0x00000d1f, 0x00003218, 0x00000d23, 0x00003219, 0x00000d27, 0x0000321a, 0x00000d2b, 0x0000321b, 0x00000d2f, 0x0000321c, 0x00000d33, 0x00003220, 0x00000d37, 0x00003221, 0x00000d3a, 0x00003222, 0x00000d3d, 0x00003223, 0x00000d40, 0x00003224, 0x00000d43, 0x00003225, 0x00000d46, 0x00003226, 0x00000d49, 0x00003227, 0x00000d4c, 0x00003228, 0x00000d4f, 0x00003229, 0x00000d52, 0x0000322a, 0x00000d55, 0x0000322b, 0x00000d58, 0x0000322c, 0x00000d5b, 0x0000322d, 0x00000d5e, 0x0000322e, 0x00000d61, 0x0000322f, 0x00000d64, 0x00003230, 0x00000d67, 0x00003231, 0x00000d6a, 0x00003232, 0x00000d6d, 0x00003233, 0x00000d70, 0x00003234, 0x00000d73, 0x00003235, 0x00000d76, 0x00003236, 0x00000d79, 0x00003237, 0x00000d7c, 0x00003238, 0x00000d7f, 0x00003239, 0x00000d82, 0x0000323a, 0x00000d85, 0x0000323b, 0x00000d88, 0x0000323c, 0x00000d8b, 0x0000323d, 0x00000d8e, 0x0000323e, 0x00000d91, 0x0000323f, 0x00000d94, 0x00003240, 0x00000d97, 0x00003241, 0x00000d9a, 0x00003242, 0x00000d9d, 0x00003243, 0x00000da0, 0x00003251, 0x00000da3, 0x00003252, 0x00000da5, 0x00003253, 0x00000da7, 0x00003254, 0x00000da9, 0x00003255, 0x00000dab, 0x00003256, 0x00000dad, 0x00003257, 0x00000daf, 0x00003258, 0x00000db1, 0x00003259, 0x00000db3, 0x0000325a, 0x00000db5, 0x0000325b, 0x00000db7, 0x0000325c, 0x00000db9, 0x0000325d, 0x00000dbb, 0x0000325e, 0x00000dbd, 0x0000325f, 0x00000dbf, 0x00003260, 0x00000dc1, 0x00003261, 0x00000dc2, 0x00003262, 0x00000dc3, 0x00003263, 0x00000dc4, 0x00003264, 0x00000dc5, 0x00003265, 0x00000dc6, 0x00003266, 0x00000dc7, 0x00003267, 0x00000dc8, 0x00003268, 0x00000dc9, 0x00003269, 0x00000dca, 0x0000326a, 0x00000dcb, 0x0000326b, 0x00000dcc, 0x0000326c, 0x00000dcd, 0x0000326d, 0x00000dce, 0x0000326e, 0x00000dcf, 0x0000326f, 0x00000dd1, 0x00003270, 0x00000dd3, 0x00003271, 0x00000dd5, 0x00003272, 0x00000dd7, 0x00003273, 0x00000dd9, 0x00003274, 0x00000ddb, 0x00003275, 0x00000ddd, 0x00003276, 0x00000ddf, 0x00003277, 0x00000de1, 0x00003278, 0x00000de3, 0x00003279, 0x00000de5, 0x0000327a, 0x00000de7, 0x0000327b, 0x00000de9, 0x00003280, 0x00000deb, 0x00003281, 0x00000dec, 0x00003282, 0x00000ded, 0x00003283, 0x00000dee, 0x00003284, 0x00000def, 0x00003285, 0x00000df0, 0x00003286, 0x00000df1, 0x00003287, 0x00000df2, 0x00003288, 0x00000df3, 0x00003289, 0x00000df4, 0x0000328a, 0x00000df5, 0x0000328b, 0x00000df6, 0x0000328c, 0x00000df7, 0x0000328d, 0x00000df8, 0x0000328e, 0x00000df9, 0x0000328f, 0x00000dfa, 0x00003290, 0x00000dfb, 0x00003291, 0x00000dfc, 0x00003292, 0x00000dfd, 0x00003293, 0x00000dfe, 0x00003294, 0x00000dff, 0x00003295, 0x00000e00, 0x00003296, 0x00000e01, 0x00003297, 0x00000e02, 0x00003298, 0x00000e03, 0x00003299, 0x00000e04, 0x0000329a, 0x00000e05, 0x0000329b, 0x00000e06, 0x0000329c, 0x00000e07, 0x0000329d, 0x00000e08, 0x0000329e, 0x00000e09, 0x0000329f, 0x00000e0a, 0x000032a0, 0x00000e0b, 0x000032a1, 0x00000e0c, 0x000032a2, 0x00000e0d, 0x000032a3, 0x00000e0e, 0x000032a4, 0x00000e0f, 0x000032a5, 0x00000e10, 0x000032a6, 0x00000e11, 0x000032a7, 0x00000e12, 0x000032a8, 0x00000e13, 0x000032a9, 0x00000e14, 0x000032aa, 0x00000e15, 0x000032ab, 0x00000e16, 0x000032ac, 0x00000e17, 0x000032ad, 0x00000e18, 0x000032ae, 0x00000e19, 0x000032af, 0x00000e1a, 0x000032b0, 0x00000e1b, 0x000032b1, 0x00000e1c, 0x000032b2, 0x00000e1e, 0x000032b3, 0x00000e20, 0x000032b4, 0x00000e22, 0x000032b5, 0x00000e24, 0x000032b6, 0x00000e26, 0x000032b7, 0x00000e28, 0x000032b8, 0x00000e2a, 0x000032b9, 0x00000e2c, 0x000032ba, 0x00000e2e, 0x000032bb, 0x00000e30, 0x000032bc, 0x00000e32, 0x000032bd, 0x00000e34, 0x000032be, 0x00000e36, 0x000032bf, 0x00000e38, 0x000032c0, 0x00000e3a, 0x000032c1, 0x00000e3c, 0x000032c2, 0x00000e3e, 0x000032c3, 0x00000e40, 0x000032c4, 0x00000e42, 0x000032c5, 0x00000e44, 0x000032c6, 0x00000e46, 0x000032c7, 0x00000e48, 0x000032c8, 0x00000e4a, 0x000032c9, 0x00000e4c, 0x000032ca, 0x00000e4f, 0x000032cb, 0x00000e52, 0x000032d0, 0x00000e55, 0x000032d1, 0x00000e56, 0x000032d2, 0x00000e57, 0x000032d3, 0x00000e58, 0x000032d4, 0x00000e59, 0x000032d5, 0x00000e5a, 0x000032d6, 0x00000e5b, 0x000032d7, 0x00000e5c, 0x000032d8, 0x00000e5d, 0x000032d9, 0x00000e5e, 0x000032da, 0x00000e5f, 0x000032db, 0x00000e60, 0x000032dc, 0x00000e61, 0x000032dd, 0x00000e62, 0x000032de, 0x00000e63, 0x000032df, 0x00000e64, 0x000032e0, 0x00000e65, 0x000032e1, 0x00000e66, 0x000032e2, 0x00000e67, 0x000032e3, 0x00000e68, 0x000032e4, 0x00000e69, 0x000032e5, 0x00000e6a, 0x000032e6, 0x00000e6b, 0x000032e7, 0x00000e6c, 0x000032e8, 0x00000e6d, 0x000032e9, 0x00000e6e, 0x000032ea, 0x00000e6f, 0x000032eb, 0x00000e70, 0x000032ec, 0x00000e71, 0x000032ed, 0x00000e72, 0x000032ee, 0x00000e73, 0x000032ef, 0x00000e74, 0x000032f0, 0x00000e75, 0x000032f1, 0x00000e76, 0x000032f2, 0x00000e77, 0x000032f3, 0x00000e78, 0x000032f4, 0x00000e79, 0x000032f5, 0x00000e7a, 0x000032f6, 0x00000e7b, 0x000032f7, 0x00000e7c, 0x000032f8, 0x00000e7d, 0x000032f9, 0x00000e7e, 0x000032fa, 0x00000e7f, 0x000032fb, 0x00000e80, 0x000032fc, 0x00000e81, 0x000032fd, 0x00000e82, 0x000032fe, 0x00000e83, 0x00003300, 0x00000e84, 0x00003301, 0x00000e89, 0x00003302, 0x00000e8d, 0x00003303, 0x00000e92, 0x00003304, 0x00000e95, 0x00003305, 0x00000e9a, 0x00003306, 0x00000e9d, 0x00003307, 0x00000ea0, 0x00003308, 0x00000ea6, 0x00003309, 0x00000eaa, 0x0000330a, 0x00000ead, 0x0000330b, 0x00000eb0, 0x0000330c, 0x00000eb3, 0x0000330d, 0x00000eb7, 0x0000330e, 0x00000ebb, 0x0000330f, 0x00000ebf, 0x00003310, 0x00000ec3, 0x00003311, 0x00000ec7, 0x00003312, 0x00000ecb, 0x00003313, 0x00000ecf, 0x00003314, 0x00000ed5, 0x00003315, 0x00000ed7, 0x00003316, 0x00000edd, 0x00003317, 0x00000ee3, 0x00003318, 0x00000ee8, 0x00003319, 0x00000eec, 0x0000331a, 0x00000ef2, 0x0000331b, 0x00000ef8, 0x0000331c, 0x00000efc, 0x0000331d, 0x00000eff, 0x0000331e, 0x00000f02, 0x0000331f, 0x00000f06, 0x00003320, 0x00000f0a, 0x00003321, 0x00000f0f, 0x00003322, 0x00000f14, 0x00003323, 0x00000f17, 0x00003324, 0x00000f1a, 0x00003325, 0x00000f1e, 0x00003326, 0x00000f21, 0x00003327, 0x00000f24, 0x00003328, 0x00000f26, 0x00003329, 0x00000f28, 0x0000332a, 0x00000f2b, 0x0000332b, 0x00000f2e, 0x0000332c, 0x00000f34, 0x0000332d, 0x00000f38, 0x0000332e, 0x00000f3d, 0x0000332f, 0x00000f43, 0x00003330, 0x00000f47, 0x00003331, 0x00000f4a, 0x00003332, 0x00000f4d, 0x00003333, 0x00000f53, 0x00003334, 0x00000f57, 0x00003335, 0x00000f5d, 0x00003336, 0x00000f60, 0x00003337, 0x00000f65, 0x00003338, 0x00000f68, 0x00003339, 0x00000f6c, 0x0000333a, 0x00000f6f, 0x0000333b, 0x00000f73, 0x0000333c, 0x00000f78, 0x0000333d, 0x00000f7c, 0x0000333e, 0x00000f81, 0x0000333f, 0x00000f85, 0x00003340, 0x00000f87, 0x00003341, 0x00000f8c, 0x00003342, 0x00000f8f, 0x00003343, 0x00000f92, 0x00003344, 0x00000f96, 0x00003345, 0x00000f99, 0x00003346, 0x00000f9c, 0x00003347, 0x00000f9f, 0x00003348, 0x00000fa4, 0x00003349, 0x00000fa8, 0x0000334a, 0x00000faa, 0x0000334b, 0x00000fb0, 0x0000334c, 0x00000fb3, 0x0000334d, 0x00000fb8, 0x0000334e, 0x00000fbc, 0x0000334f, 0x00000fc0, 0x00003350, 0x00000fc3, 0x00003351, 0x00000fc6, 0x00003352, 0x00000fca, 0x00003353, 0x00000fcc, 0x00003354, 0x00000fd0, 0x00003355, 0x00000fd5, 0x00003356, 0x00000fd7, 0x00003357, 0x00000fdd, 0x00003358, 0x00000fe0, 0x00003359, 0x00000fe2, 0x0000335a, 0x00000fe4, 0x0000335b, 0x00000fe6, 0x0000335c, 0x00000fe8, 0x0000335d, 0x00000fea, 0x0000335e, 0x00000fec, 0x0000335f, 0x00000fee, 0x00003360, 0x00000ff0, 0x00003361, 0x00000ff2, 0x00003362, 0x00000ff4, 0x00003363, 0x00000ff7, 0x00003364, 0x00000ffa, 0x00003365, 0x00000ffd, 0x00003366, 0x00001000, 0x00003367, 0x00001003, 0x00003368, 0x00001006, 0x00003369, 0x00001009, 0x0000336a, 0x0000100c, 0x0000336b, 0x0000100f, 0x0000336c, 0x00001012, 0x0000336d, 0x00001015, 0x0000336e, 0x00001018, 0x0000336f, 0x0000101b, 0x00003370, 0x0000101e, 0x00003371, 0x00001021, 0x00003372, 0x00001024, 0x00003373, 0x00001026, 0x00003374, 0x00001028, 0x00003375, 0x0000102b, 0x00003376, 0x0000102d, 0x0000337b, 0x0000102f, 0x0000337c, 0x00001031, 0x0000337d, 0x00001033, 0x0000337e, 0x00001035, 0x0000337f, 0x00001037, 0x00003380, 0x0000103b, 0x00003381, 0x0000103d, 0x00003382, 0x0000103f, 0x00003383, 0x00001041, 0x00003384, 0x00001043, 0x00003385, 0x00001045, 0x00003386, 0x00001047, 0x00003387, 0x00001049, 0x00003388, 0x0000104b, 0x00003389, 0x0000104e, 0x0000338a, 0x00001052, 0x0000338b, 0x00001054, 0x0000338c, 0x00001056, 0x0000338d, 0x00001058, 0x0000338e, 0x0000105a, 0x0000338f, 0x0000105c, 0x00003390, 0x0000105e, 0x00003391, 0x00001060, 0x00003392, 0x00001063, 0x00003393, 0x00001066, 0x00003394, 0x00001069, 0x00003395, 0x0000106c, 0x00003396, 0x0000106e, 0x00003397, 0x00001070, 0x00003398, 0x00001072, 0x00003399, 0x00001074, 0x0000339a, 0x00001076, 0x0000339b, 0x00001078, 0x0000339c, 0x0000107a, 0x0000339d, 0x0000107c, 0x0000339e, 0x0000107e, 0x0000339f, 0x00001080, 0x000033a0, 0x00001083, 0x000033a1, 0x00001086, 0x000033a2, 0x00001088, 0x000033a3, 0x0000108b, 0x000033a4, 0x0000108e, 0x000033a5, 0x00001091, 0x000033a6, 0x00001093, 0x000033a7, 0x00001096, 0x000033a8, 0x00001099, 0x000033a9, 0x0000109d, 0x000033aa, 0x0000109f, 0x000033ab, 0x000010a2, 0x000033ac, 0x000010a5, 0x000033ad, 0x000010a8, 0x000033ae, 0x000010ab, 0x000033af, 0x000010b0, 0x000033b0, 0x000010b6, 0x000033b1, 0x000010b8, 0x000033b2, 0x000010ba, 0x000033b3, 0x000010bc, 0x000033b4, 0x000010be, 0x000033b5, 0x000010c0, 0x000033b6, 0x000010c2, 0x000033b7, 0x000010c4, 0x000033b8, 0x000010c6, 0x000033b9, 0x000010c8, 0x000033ba, 0x000010ca, 0x000033bb, 0x000010cc, 0x000033bc, 0x000010ce, 0x000033bd, 0x000010d0, 0x000033be, 0x000010d2, 0x000033bf, 0x000010d4, 0x000033c0, 0x000010d6, 0x000033c1, 0x000010d8, 0x000033c2, 0x000010da, 0x000033c3, 0x000010de, 0x000033c4, 0x000010e0, 0x000033c5, 0x000010e2, 0x000033c6, 0x000010e4, 0x000033c7, 0x000010e8, 0x000033c8, 0x000010eb, 0x000033c9, 0x000010ed, 0x000033ca, 0x000010ef, 0x000033cb, 0x000010f1, 0x000033cc, 0x000010f3, 0x000033cd, 0x000010f5, 0x000033ce, 0x000010f7, 0x000033cf, 0x000010f9, 0x000033d0, 0x000010fb, 0x000033d1, 0x000010fd, 0x000033d2, 0x000010ff, 0x000033d3, 0x00001102, 0x000033d4, 0x00001104, 0x000033d5, 0x00001106, 0x000033d6, 0x00001109, 0x000033d7, 0x0000110c, 0x000033d8, 0x0000110e, 0x000033d9, 0x00001112, 0x000033da, 0x00001115, 0x000033db, 0x00001117, 0x000033dc, 0x00001119, 0x000033dd, 0x0000111b, 0x000033e0, 0x0000111d, 0x000033e1, 0x0000111f, 0x000033e2, 0x00001121, 0x000033e3, 0x00001123, 0x000033e4, 0x00001125, 0x000033e5, 0x00001127, 0x000033e6, 0x00001129, 0x000033e7, 0x0000112b, 0x000033e8, 0x0000112d, 0x000033e9, 0x0000112f, 0x000033ea, 0x00001132, 0x000033eb, 0x00001135, 0x000033ec, 0x00001138, 0x000033ed, 0x0000113b, 0x000033ee, 0x0000113e, 0x000033ef, 0x00001141, 0x000033f0, 0x00001144, 0x000033f1, 0x00001147, 0x000033f2, 0x0000114a, 0x000033f3, 0x0000114d, 0x000033f4, 0x00001150, 0x000033f5, 0x00001153, 0x000033f6, 0x00001156, 0x000033f7, 0x00001159, 0x000033f8, 0x0000115c, 0x000033f9, 0x0000115f, 0x000033fa, 0x00001162, 0x000033fb, 0x00001165, 0x000033fc, 0x00001168, 0x000033fd, 0x0000116b, 0x000033fe, 0x0000116e, 0x0000f902, 0x00001171, 0x0000f903, 0x00001172, 0x0000f904, 0x00001173, 0x0000f905, 0x00001174, 0x0000f906, 0x00001175, 0x0000f907, 0x00001176, 0x0000f908, 0x00001177, 0x0000f909, 0x00001178, 0x0000f90a, 0x00001179, 0x0000f90b, 0x0000117a, 0x0000f90c, 0x0000117b, 0x0000f90d, 0x0000117c, 0x0000f90e, 0x0000117d, 0x0000f90f, 0x0000117e, 0x0000f910, 0x0000117f, 0x0000f911, 0x00001180, 0x0000f912, 0x00001181, 0x0000f913, 0x00001182, 0x0000f914, 0x00001183, 0x0000f915, 0x00001184, 0x0000f916, 0x00001185, 0x0000f917, 0x00001186, 0x0000f918, 0x00001187, 0x0000f919, 0x00001188, 0x0000f91a, 0x00001189, 0x0000f91b, 0x0000118a, 0x0000f91c, 0x0000118b, 0x0000f91d, 0x0000118c, 0x0000f91e, 0x0000118d, 0x0000f91f, 0x0000118e, 0x0000f920, 0x0000118f, 0x0000f921, 0x00001190, 0x0000f922, 0x00001191, 0x0000f923, 0x00001192, 0x0000f924, 0x00001193, 0x0000f925, 0x00001194, 0x0000f926, 0x00001195, 0x0000f927, 0x00001196, 0x0000f928, 0x00001197, 0x0000f929, 0x00001198, 0x0000f92a, 0x00001199, 0x0000f92b, 0x0000119a, 0x0000f92c, 0x0000119b, 0x0000f92d, 0x0000119c, 0x0000f92e, 0x0000119d, 0x0000f92f, 0x0000119e, 0x0000f930, 0x0000119f, 0x0000f931, 0x000011a0, 0x0000f932, 0x000011a1, 0x0000f933, 0x000011a2, 0x0000f934, 0x000011a3, 0x0000f935, 0x000011a4, 0x0000f936, 0x000011a5, 0x0000f937, 0x000011a6, 0x0000f938, 0x000011a7, 0x0000f939, 0x000011a8, 0x0000f93a, 0x000011a9, 0x0000f93b, 0x000011aa, 0x0000f93c, 0x000011ab, 0x0000f93d, 0x000011ac, 0x0000f93e, 0x000011ad, 0x0000f93f, 0x000011ae, 0x0000f940, 0x000011af, 0x0000f941, 0x000011b0, 0x0000f942, 0x000011b1, 0x0000f943, 0x000011b2, 0x0000f944, 0x000011b3, 0x0000f945, 0x000011b4, 0x0000f946, 0x000011b5, 0x0000f947, 0x000011b6, 0x0000f948, 0x000011b7, 0x0000f949, 0x000011b8, 0x0000f94a, 0x000011b9, 0x0000f94b, 0x000011ba, 0x0000f94c, 0x000011bb, 0x0000f94d, 0x000011bc, 0x0000f94e, 0x000011bd, 0x0000f94f, 0x000011be, 0x0000f950, 0x000011bf, 0x0000f951, 0x000011c0, 0x0000f952, 0x000011c1, 0x0000f953, 0x000011c2, 0x0000f954, 0x000011c3, 0x0000f955, 0x000011c4, 0x0000f956, 0x000011c5, 0x0000f957, 0x000011c6, 0x0000f958, 0x000011c7, 0x0000f959, 0x000011c8, 0x0000f95a, 0x000011c9, 0x0000f95b, 0x000011ca, 0x0000f95c, 0x000011cb, 0x0000f95d, 0x000011cc, 0x0000f95e, 0x000011cd, 0x0000f95f, 0x000011ce, 0x0000f960, 0x000011cf, 0x0000f961, 0x000011d0, 0x0000f962, 0x000011d1, 0x0000f963, 0x000011d2, 0x0000f964, 0x000011d3, 0x0000f965, 0x000011d4, 0x0000f966, 0x000011d5, 0x0000f967, 0x000011d6, 0x0000f968, 0x000011d7, 0x0000f969, 0x000011d8, 0x0000f96a, 0x000011d9, 0x0000f96b, 0x000011da, 0x0000f96c, 0x000011db, 0x0000f96d, 0x000011dc, 0x0000f96e, 0x000011dd, 0x0000f96f, 0x000011de, 0x0000f970, 0x000011df, 0x0000f971, 0x000011e0, 0x0000f972, 0x000011e1, 0x0000f973, 0x000011e2, 0x0000f974, 0x000011e3, 0x0000f975, 0x000011e4, 0x0000f976, 0x000011e5, 0x0000f977, 0x000011e6, 0x0000f978, 0x000011e7, 0x0000f979, 0x000011e8, 0x0000f97a, 0x000011e9, 0x0000f97b, 0x000011ea, 0x0000f97c, 0x000011eb, 0x0000f97d, 0x000011ec, 0x0000f97e, 0x000011ed, 0x0000f97f, 0x000011ee, 0x0000f980, 0x000011ef, 0x0000f981, 0x000011f0, 0x0000f982, 0x000011f1, 0x0000f983, 0x000011f2, 0x0000f984, 0x000011f3, 0x0000f985, 0x000011f4, 0x0000f986, 0x000011f5, 0x0000f987, 0x000011f6, 0x0000f988, 0x000011f7, 0x0000f989, 0x000011f8, 0x0000f98a, 0x000011f9, 0x0000f98b, 0x000011fa, 0x0000f98c, 0x000011fb, 0x0000f98d, 0x000011fc, 0x0000f98e, 0x000011fd, 0x0000f98f, 0x000011fe, 0x0000f990, 0x000011ff, 0x0000f991, 0x00001200, 0x0000f992, 0x00001201, 0x0000f993, 0x00001202, 0x0000f994, 0x00001203, 0x0000f995, 0x00001204, 0x0000f996, 0x00001205, 0x0000f997, 0x00001206, 0x0000f998, 0x00001207, 0x0000f999, 0x00001208, 0x0000f99a, 0x00001209, 0x0000f99b, 0x0000120a, 0x0000f99c, 0x0000120b, 0x0000f99d, 0x0000120c, 0x0000f99e, 0x0000120d, 0x0000f99f, 0x0000120e, 0x0000f9a0, 0x0000120f, 0x0000f9a1, 0x00001210, 0x0000f9a2, 0x00001211, 0x0000f9a3, 0x00001212, 0x0000f9a4, 0x00001213, 0x0000f9a5, 0x00001214, 0x0000f9a6, 0x00001215, 0x0000f9a7, 0x00001216, 0x0000f9a8, 0x00001217, 0x0000f9a9, 0x00001218, 0x0000f9aa, 0x00001219, 0x0000f9ab, 0x0000121a, 0x0000f9ac, 0x0000121b, 0x0000f9ad, 0x0000121c, 0x0000f9ae, 0x0000121d, 0x0000f9af, 0x0000121e, 0x0000f9b0, 0x0000121f, 0x0000f9b1, 0x00001220, 0x0000f9b2, 0x00001221, 0x0000f9b3, 0x00001222, 0x0000f9b4, 0x00001223, 0x0000f9b5, 0x00001224, 0x0000f9b6, 0x00001225, 0x0000f9b7, 0x00001226, 0x0000f9b8, 0x00001227, 0x0000f9b9, 0x00001228, 0x0000f9ba, 0x00001229, 0x0000f9bb, 0x0000122a, 0x0000f9bc, 0x0000122b, 0x0000f9bd, 0x0000122c, 0x0000f9be, 0x0000122d, 0x0000f9bf, 0x0000122e, 0x0000f9c0, 0x0000122f, 0x0000f9c1, 0x00001230, 0x0000f9c2, 0x00001231, 0x0000f9c3, 0x00001232, 0x0000f9c4, 0x00001233, 0x0000f9c5, 0x00001234, 0x0000f9c6, 0x00001235, 0x0000f9c7, 0x00001236, 0x0000f9c8, 0x00001237, 0x0000f9c9, 0x00001238, 0x0000f9ca, 0x00001239, 0x0000f9cb, 0x0000123a, 0x0000f9cc, 0x0000123b, 0x0000f9cd, 0x0000123c, 0x0000f9ce, 0x0000123d, 0x0000f9cf, 0x0000123e, 0x0000f9d0, 0x0000123f, 0x0000f9d1, 0x00001240, 0x0000f9d2, 0x00001241, 0x0000f9d3, 0x00001242, 0x0000f9d4, 0x00001243, 0x0000f9d5, 0x00001244, 0x0000f9d6, 0x00001245, 0x0000f9d7, 0x00001246, 0x0000f9d8, 0x00001247, 0x0000f9d9, 0x00001248, 0x0000f9da, 0x00001249, 0x0000f9db, 0x0000124a, 0x0000f9dc, 0x0000124b, 0x0000f9dd, 0x0000124c, 0x0000f9de, 0x0000124d, 0x0000f9df, 0x0000124e, 0x0000f9e0, 0x0000124f, 0x0000f9e1, 0x00001250, 0x0000f9e2, 0x00001251, 0x0000f9e3, 0x00001252, 0x0000f9e4, 0x00001253, 0x0000f9e5, 0x00001254, 0x0000f9e6, 0x00001255, 0x0000f9e7, 0x00001256, 0x0000f9e8, 0x00001257, 0x0000f9e9, 0x00001258, 0x0000f9ea, 0x00001259, 0x0000f9eb, 0x0000125a, 0x0000f9ec, 0x0000125b, 0x0000f9ed, 0x0000125c, 0x0000f9ee, 0x0000125d, 0x0000f9ef, 0x0000125e, 0x0000f9f0, 0x0000125f, 0x0000f9f1, 0x00001260, 0x0000f9f2, 0x00001261, 0x0000f9f3, 0x00001262, 0x0000f9f4, 0x00001263, 0x0000f9f5, 0x00001264, 0x0000f9f6, 0x00001265, 0x0000f9f7, 0x00001266, 0x0000f9f8, 0x00001267, 0x0000f9f9, 0x00001268, 0x0000f9fa, 0x00001269, 0x0000f9fb, 0x0000126a, 0x0000f9fc, 0x0000126b, 0x0000f9fd, 0x0000126c, 0x0000f9fe, 0x0000126d, 0x0000f9ff, 0x0000126e, 0x0000fa00, 0x0000126f, 0x0000fa01, 0x00001270, 0x0000fa02, 0x00001271, 0x0000fa03, 0x00001272, 0x0000fa04, 0x00001273, 0x0000fa05, 0x00001274, 0x0000fa06, 0x00001275, 0x0000fa07, 0x00001276, 0x0000fa08, 0x00001277, 0x0000fa09, 0x00001278, 0x0000fa0a, 0x00001279, 0x0000fa0b, 0x0000127a, 0x0000fa0c, 0x0000127b, 0x0000fa0d, 0x0000127c, 0x0000fa10, 0x0000127d, 0x0000fa12, 0x0000127e, 0x0000fa15, 0x0000127f, 0x0000fa16, 0x00001280, 0x0000fa17, 0x00001281, 0x0000fa18, 0x00001282, 0x0000fa19, 0x00001283, 0x0000fa1a, 0x00001284, 0x0000fa1b, 0x00001285, 0x0000fa1c, 0x00001286, 0x0000fa1d, 0x00001287, 0x0000fa1e, 0x00001288, 0x0000fa20, 0x00001289, 0x0000fa22, 0x0000128a, 0x0000fa25, 0x0000128b, 0x0000fa26, 0x0000128c, 0x0000fa2a, 0x0000128d, 0x0000fa2b, 0x0000128e, 0x0000fa2c, 0x0000128f, 0x0000fa2d, 0x00001290, 0x0000fa30, 0x00001291, 0x0000fa31, 0x00001292, 0x0000fa32, 0x00001293, 0x0000fa33, 0x00001294, 0x0000fa34, 0x00001295, 0x0000fa35, 0x00001296, 0x0000fa36, 0x00001297, 0x0000fa37, 0x00001298, 0x0000fa38, 0x00001299, 0x0000fa39, 0x0000129a, 0x0000fa3a, 0x0000129b, 0x0000fa3b, 0x0000129c, 0x0000fa3c, 0x0000129d, 0x0000fa3d, 0x0000129e, 0x0000fa3e, 0x0000129f, 0x0000fa3f, 0x000012a0, 0x0000fa40, 0x000012a1, 0x0000fa41, 0x000012a2, 0x0000fa42, 0x000012a3, 0x0000fa43, 0x000012a4, 0x0000fa44, 0x000012a5, 0x0000fa45, 0x000012a6, 0x0000fa46, 0x000012a7, 0x0000fa47, 0x000012a8, 0x0000fa48, 0x000012a9, 0x0000fa49, 0x000012aa, 0x0000fa4a, 0x000012ab, 0x0000fa4b, 0x000012ac, 0x0000fa4c, 0x000012ad, 0x0000fa4d, 0x000012ae, 0x0000fa4e, 0x000012af, 0x0000fa4f, 0x000012b0, 0x0000fa50, 0x000012b1, 0x0000fa51, 0x000012b2, 0x0000fa52, 0x000012b3, 0x0000fa53, 0x000012b4, 0x0000fa54, 0x000012b5, 0x0000fa55, 0x000012b6, 0x0000fa56, 0x000012b7, 0x0000fa57, 0x000012b8, 0x0000fa58, 0x000012b9, 0x0000fa59, 0x000012ba, 0x0000fa5a, 0x000012bb, 0x0000fa5b, 0x000012bc, 0x0000fa5c, 0x000012bd, 0x0000fa5d, 0x000012be, 0x0000fa5e, 0x000012bf, 0x0000fa5f, 0x000012c0, 0x0000fa60, 0x000012c1, 0x0000fa61, 0x000012c2, 0x0000fa62, 0x000012c3, 0x0000fa63, 0x000012c4, 0x0000fa64, 0x000012c5, 0x0000fa65, 0x000012c6, 0x0000fa66, 0x000012c7, 0x0000fa67, 0x000012c8, 0x0000fa68, 0x000012c9, 0x0000fa69, 0x000012ca, 0x0000fa6a, 0x000012cb, 0x0000fb00, 0x000012cc, 0x0000fb01, 0x000012ce, 0x0000fb02, 0x000012d0, 0x0000fb03, 0x000012d2, 0x0000fb04, 0x000012d5, 0x0000fb05, 0x000012d8, 0x0000fb06, 0x000012da, 0x0000fb13, 0x000012dc, 0x0000fb14, 0x000012de, 0x0000fb15, 0x000012e0, 0x0000fb16, 0x000012e2, 0x0000fb17, 0x000012e4, 0x0000fb1d, 0x000012e6, 0x0000fb1f, 0x000012e8, 0x0000fb20, 0x000012ea, 0x0000fb21, 0x000012eb, 0x0000fb22, 0x000012ec, 0x0000fb23, 0x000012ed, 0x0000fb24, 0x000012ee, 0x0000fb25, 0x000012ef, 0x0000fb26, 0x000012f0, 0x0000fb27, 0x000012f1, 0x0000fb28, 0x000012f2, 0x0000fb29, 0x000012f3, 0x0000fb2a, 0x000012f4, 0x0000fb2b, 0x000012f6, 0x0000fb2c, 0x000012f8, 0x0000fb2d, 0x000012fb, 0x0000fb2e, 0x000012fe, 0x0000fb2f, 0x00001300, 0x0000fb30, 0x00001302, 0x0000fb31, 0x00001304, 0x0000fb32, 0x00001306, 0x0000fb33, 0x00001308, 0x0000fb34, 0x0000130a, 0x0000fb35, 0x0000130c, 0x0000fb36, 0x0000130e, 0x0000fb38, 0x00001310, 0x0000fb39, 0x00001312, 0x0000fb3a, 0x00001314, 0x0000fb3b, 0x00001316, 0x0000fb3c, 0x00001318, 0x0000fb3e, 0x0000131a, 0x0000fb40, 0x0000131c, 0x0000fb41, 0x0000131e, 0x0000fb43, 0x00001320, 0x0000fb44, 0x00001322, 0x0000fb46, 0x00001324, 0x0000fb47, 0x00001326, 0x0000fb48, 0x00001328, 0x0000fb49, 0x0000132a, 0x0000fb4a, 0x0000132c, 0x0000fb4b, 0x0000132e, 0x0000fb4c, 0x00001330, 0x0000fb4d, 0x00001332, 0x0000fb4e, 0x00001334, 0x0000fb4f, 0x00001336, 0x0000fb50, 0x00001338, 0x0000fb51, 0x00001339, 0x0000fb52, 0x0000133a, 0x0000fb53, 0x0000133b, 0x0000fb54, 0x0000133c, 0x0000fb55, 0x0000133d, 0x0000fb56, 0x0000133e, 0x0000fb57, 0x0000133f, 0x0000fb58, 0x00001340, 0x0000fb59, 0x00001341, 0x0000fb5a, 0x00001342, 0x0000fb5b, 0x00001343, 0x0000fb5c, 0x00001344, 0x0000fb5d, 0x00001345, 0x0000fb5e, 0x00001346, 0x0000fb5f, 0x00001347, 0x0000fb60, 0x00001348, 0x0000fb61, 0x00001349, 0x0000fb62, 0x0000134a, 0x0000fb63, 0x0000134b, 0x0000fb64, 0x0000134c, 0x0000fb65, 0x0000134d, 0x0000fb66, 0x0000134e, 0x0000fb67, 0x0000134f, 0x0000fb68, 0x00001350, 0x0000fb69, 0x00001351, 0x0000fb6a, 0x00001352, 0x0000fb6b, 0x00001353, 0x0000fb6c, 0x00001354, 0x0000fb6d, 0x00001355, 0x0000fb6e, 0x00001356, 0x0000fb6f, 0x00001357, 0x0000fb70, 0x00001358, 0x0000fb71, 0x00001359, 0x0000fb72, 0x0000135a, 0x0000fb73, 0x0000135b, 0x0000fb74, 0x0000135c, 0x0000fb75, 0x0000135d, 0x0000fb76, 0x0000135e, 0x0000fb77, 0x0000135f, 0x0000fb78, 0x00001360, 0x0000fb79, 0x00001361, 0x0000fb7a, 0x00001362, 0x0000fb7b, 0x00001363, 0x0000fb7c, 0x00001364, 0x0000fb7d, 0x00001365, 0x0000fb7e, 0x00001366, 0x0000fb7f, 0x00001367, 0x0000fb80, 0x00001368, 0x0000fb81, 0x00001369, 0x0000fb82, 0x0000136a, 0x0000fb83, 0x0000136b, 0x0000fb84, 0x0000136c, 0x0000fb85, 0x0000136d, 0x0000fb86, 0x0000136e, 0x0000fb87, 0x0000136f, 0x0000fb88, 0x00001370, 0x0000fb89, 0x00001371, 0x0000fb8a, 0x00001372, 0x0000fb8b, 0x00001373, 0x0000fb8c, 0x00001374, 0x0000fb8d, 0x00001375, 0x0000fb8e, 0x00001376, 0x0000fb8f, 0x00001377, 0x0000fb90, 0x00001378, 0x0000fb91, 0x00001379, 0x0000fb92, 0x0000137a, 0x0000fb93, 0x0000137b, 0x0000fb94, 0x0000137c, 0x0000fb95, 0x0000137d, 0x0000fb96, 0x0000137e, 0x0000fb97, 0x0000137f, 0x0000fb98, 0x00001380, 0x0000fb99, 0x00001381, 0x0000fb9a, 0x00001382, 0x0000fb9b, 0x00001383, 0x0000fb9c, 0x00001384, 0x0000fb9d, 0x00001385, 0x0000fb9e, 0x00001386, 0x0000fb9f, 0x00001387, 0x0000fba0, 0x00001388, 0x0000fba1, 0x00001389, 0x0000fba2, 0x0000138a, 0x0000fba3, 0x0000138b, 0x0000fba4, 0x0000138c, 0x0000fba5, 0x0000138e, 0x0000fba6, 0x00001390, 0x0000fba7, 0x00001391, 0x0000fba8, 0x00001392, 0x0000fba9, 0x00001393, 0x0000fbaa, 0x00001394, 0x0000fbab, 0x00001395, 0x0000fbac, 0x00001396, 0x0000fbad, 0x00001397, 0x0000fbae, 0x00001398, 0x0000fbaf, 0x00001399, 0x0000fbb0, 0x0000139a, 0x0000fbb1, 0x0000139c, 0x0000fbd3, 0x0000139e, 0x0000fbd4, 0x0000139f, 0x0000fbd5, 0x000013a0, 0x0000fbd6, 0x000013a1, 0x0000fbd7, 0x000013a2, 0x0000fbd8, 0x000013a3, 0x0000fbd9, 0x000013a4, 0x0000fbda, 0x000013a5, 0x0000fbdb, 0x000013a6, 0x0000fbdc, 0x000013a7, 0x0000fbdd, 0x000013a8, 0x0000fbde, 0x000013aa, 0x0000fbdf, 0x000013ab, 0x0000fbe0, 0x000013ac, 0x0000fbe1, 0x000013ad, 0x0000fbe2, 0x000013ae, 0x0000fbe3, 0x000013af, 0x0000fbe4, 0x000013b0, 0x0000fbe5, 0x000013b1, 0x0000fbe6, 0x000013b2, 0x0000fbe7, 0x000013b3, 0x0000fbe8, 0x000013b4, 0x0000fbe9, 0x000013b5, 0x0000fbea, 0x000013b6, 0x0000fbeb, 0x000013b9, 0x0000fbec, 0x000013bc, 0x0000fbed, 0x000013bf, 0x0000fbee, 0x000013c2, 0x0000fbef, 0x000013c5, 0x0000fbf0, 0x000013c8, 0x0000fbf1, 0x000013cb, 0x0000fbf2, 0x000013ce, 0x0000fbf3, 0x000013d1, 0x0000fbf4, 0x000013d4, 0x0000fbf5, 0x000013d7, 0x0000fbf6, 0x000013da, 0x0000fbf7, 0x000013dd, 0x0000fbf8, 0x000013e0, 0x0000fbf9, 0x000013e3, 0x0000fbfa, 0x000013e6, 0x0000fbfb, 0x000013e9, 0x0000fbfc, 0x000013ec, 0x0000fbfd, 0x000013ed, 0x0000fbfe, 0x000013ee, 0x0000fbff, 0x000013ef, 0x0000fc00, 0x000013f0, 0x0000fc01, 0x000013f3, 0x0000fc02, 0x000013f6, 0x0000fc03, 0x000013f9, 0x0000fc04, 0x000013fc, 0x0000fc05, 0x000013ff, 0x0000fc06, 0x00001401, 0x0000fc07, 0x00001403, 0x0000fc08, 0x00001405, 0x0000fc09, 0x00001407, 0x0000fc0a, 0x00001409, 0x0000fc0b, 0x0000140b, 0x0000fc0c, 0x0000140d, 0x0000fc0d, 0x0000140f, 0x0000fc0e, 0x00001411, 0x0000fc0f, 0x00001413, 0x0000fc10, 0x00001415, 0x0000fc11, 0x00001417, 0x0000fc12, 0x00001419, 0x0000fc13, 0x0000141b, 0x0000fc14, 0x0000141d, 0x0000fc15, 0x0000141f, 0x0000fc16, 0x00001421, 0x0000fc17, 0x00001423, 0x0000fc18, 0x00001425, 0x0000fc19, 0x00001427, 0x0000fc1a, 0x00001429, 0x0000fc1b, 0x0000142b, 0x0000fc1c, 0x0000142d, 0x0000fc1d, 0x0000142f, 0x0000fc1e, 0x00001431, 0x0000fc1f, 0x00001433, 0x0000fc20, 0x00001435, 0x0000fc21, 0x00001437, 0x0000fc22, 0x00001439, 0x0000fc23, 0x0000143b, 0x0000fc24, 0x0000143d, 0x0000fc25, 0x0000143f, 0x0000fc26, 0x00001441, 0x0000fc27, 0x00001443, 0x0000fc28, 0x00001445, 0x0000fc29, 0x00001447, 0x0000fc2a, 0x00001449, 0x0000fc2b, 0x0000144b, 0x0000fc2c, 0x0000144d, 0x0000fc2d, 0x0000144f, 0x0000fc2e, 0x00001451, 0x0000fc2f, 0x00001453, 0x0000fc30, 0x00001455, 0x0000fc31, 0x00001457, 0x0000fc32, 0x00001459, 0x0000fc33, 0x0000145b, 0x0000fc34, 0x0000145d, 0x0000fc35, 0x0000145f, 0x0000fc36, 0x00001461, 0x0000fc37, 0x00001463, 0x0000fc38, 0x00001465, 0x0000fc39, 0x00001467, 0x0000fc3a, 0x00001469, 0x0000fc3b, 0x0000146b, 0x0000fc3c, 0x0000146d, 0x0000fc3d, 0x0000146f, 0x0000fc3e, 0x00001471, 0x0000fc3f, 0x00001473, 0x0000fc40, 0x00001475, 0x0000fc41, 0x00001477, 0x0000fc42, 0x00001479, 0x0000fc43, 0x0000147b, 0x0000fc44, 0x0000147d, 0x0000fc45, 0x0000147f, 0x0000fc46, 0x00001481, 0x0000fc47, 0x00001483, 0x0000fc48, 0x00001485, 0x0000fc49, 0x00001487, 0x0000fc4a, 0x00001489, 0x0000fc4b, 0x0000148b, 0x0000fc4c, 0x0000148d, 0x0000fc4d, 0x0000148f, 0x0000fc4e, 0x00001491, 0x0000fc4f, 0x00001493, 0x0000fc50, 0x00001495, 0x0000fc51, 0x00001497, 0x0000fc52, 0x00001499, 0x0000fc53, 0x0000149b, 0x0000fc54, 0x0000149d, 0x0000fc55, 0x0000149f, 0x0000fc56, 0x000014a1, 0x0000fc57, 0x000014a3, 0x0000fc58, 0x000014a5, 0x0000fc59, 0x000014a7, 0x0000fc5a, 0x000014a9, 0x0000fc5b, 0x000014ab, 0x0000fc5c, 0x000014ad, 0x0000fc5d, 0x000014af, 0x0000fc5e, 0x000014b1, 0x0000fc5f, 0x000014b4, 0x0000fc60, 0x000014b7, 0x0000fc61, 0x000014ba, 0x0000fc62, 0x000014bd, 0x0000fc63, 0x000014c0, 0x0000fc64, 0x000014c3, 0x0000fc65, 0x000014c6, 0x0000fc66, 0x000014c9, 0x0000fc67, 0x000014cc, 0x0000fc68, 0x000014cf, 0x0000fc69, 0x000014d2, 0x0000fc6a, 0x000014d5, 0x0000fc6b, 0x000014d7, 0x0000fc6c, 0x000014d9, 0x0000fc6d, 0x000014db, 0x0000fc6e, 0x000014dd, 0x0000fc6f, 0x000014df, 0x0000fc70, 0x000014e1, 0x0000fc71, 0x000014e3, 0x0000fc72, 0x000014e5, 0x0000fc73, 0x000014e7, 0x0000fc74, 0x000014e9, 0x0000fc75, 0x000014eb, 0x0000fc76, 0x000014ed, 0x0000fc77, 0x000014ef, 0x0000fc78, 0x000014f1, 0x0000fc79, 0x000014f3, 0x0000fc7a, 0x000014f5, 0x0000fc7b, 0x000014f7, 0x0000fc7c, 0x000014f9, 0x0000fc7d, 0x000014fb, 0x0000fc7e, 0x000014fd, 0x0000fc7f, 0x000014ff, 0x0000fc80, 0x00001501, 0x0000fc81, 0x00001503, 0x0000fc82, 0x00001505, 0x0000fc83, 0x00001507, 0x0000fc84, 0x00001509, 0x0000fc85, 0x0000150b, 0x0000fc86, 0x0000150d, 0x0000fc87, 0x0000150f, 0x0000fc88, 0x00001511, 0x0000fc89, 0x00001513, 0x0000fc8a, 0x00001515, 0x0000fc8b, 0x00001517, 0x0000fc8c, 0x00001519, 0x0000fc8d, 0x0000151b, 0x0000fc8e, 0x0000151d, 0x0000fc8f, 0x0000151f, 0x0000fc90, 0x00001521, 0x0000fc91, 0x00001523, 0x0000fc92, 0x00001525, 0x0000fc93, 0x00001527, 0x0000fc94, 0x00001529, 0x0000fc95, 0x0000152b, 0x0000fc96, 0x0000152d, 0x0000fc97, 0x0000152f, 0x0000fc98, 0x00001532, 0x0000fc99, 0x00001535, 0x0000fc9a, 0x00001538, 0x0000fc9b, 0x0000153b, 0x0000fc9c, 0x0000153e, 0x0000fc9d, 0x00001540, 0x0000fc9e, 0x00001542, 0x0000fc9f, 0x00001544, 0x0000fca0, 0x00001546, 0x0000fca1, 0x00001548, 0x0000fca2, 0x0000154a, 0x0000fca3, 0x0000154c, 0x0000fca4, 0x0000154e, 0x0000fca5, 0x00001550, 0x0000fca6, 0x00001552, 0x0000fca7, 0x00001554, 0x0000fca8, 0x00001556, 0x0000fca9, 0x00001558, 0x0000fcaa, 0x0000155a, 0x0000fcab, 0x0000155c, 0x0000fcac, 0x0000155e, 0x0000fcad, 0x00001560, 0x0000fcae, 0x00001562, 0x0000fcaf, 0x00001564, 0x0000fcb0, 0x00001566, 0x0000fcb1, 0x00001568, 0x0000fcb2, 0x0000156a, 0x0000fcb3, 0x0000156c, 0x0000fcb4, 0x0000156e, 0x0000fcb5, 0x00001570, 0x0000fcb6, 0x00001572, 0x0000fcb7, 0x00001574, 0x0000fcb8, 0x00001576, 0x0000fcb9, 0x00001578, 0x0000fcba, 0x0000157a, 0x0000fcbb, 0x0000157c, 0x0000fcbc, 0x0000157e, 0x0000fcbd, 0x00001580, 0x0000fcbe, 0x00001582, 0x0000fcbf, 0x00001584, 0x0000fcc0, 0x00001586, 0x0000fcc1, 0x00001588, 0x0000fcc2, 0x0000158a, 0x0000fcc3, 0x0000158c, 0x0000fcc4, 0x0000158e, 0x0000fcc5, 0x00001590, 0x0000fcc6, 0x00001592, 0x0000fcc7, 0x00001594, 0x0000fcc8, 0x00001596, 0x0000fcc9, 0x00001598, 0x0000fcca, 0x0000159a, 0x0000fccb, 0x0000159c, 0x0000fccc, 0x0000159e, 0x0000fccd, 0x000015a0, 0x0000fcce, 0x000015a2, 0x0000fccf, 0x000015a4, 0x0000fcd0, 0x000015a6, 0x0000fcd1, 0x000015a8, 0x0000fcd2, 0x000015aa, 0x0000fcd3, 0x000015ac, 0x0000fcd4, 0x000015ae, 0x0000fcd5, 0x000015b0, 0x0000fcd6, 0x000015b2, 0x0000fcd7, 0x000015b4, 0x0000fcd8, 0x000015b6, 0x0000fcd9, 0x000015b8, 0x0000fcda, 0x000015ba, 0x0000fcdb, 0x000015bc, 0x0000fcdc, 0x000015be, 0x0000fcdd, 0x000015c0, 0x0000fcde, 0x000015c2, 0x0000fcdf, 0x000015c4, 0x0000fce0, 0x000015c7, 0x0000fce1, 0x000015ca, 0x0000fce2, 0x000015cc, 0x0000fce3, 0x000015ce, 0x0000fce4, 0x000015d0, 0x0000fce5, 0x000015d2, 0x0000fce6, 0x000015d4, 0x0000fce7, 0x000015d6, 0x0000fce8, 0x000015d8, 0x0000fce9, 0x000015da, 0x0000fcea, 0x000015dc, 0x0000fceb, 0x000015de, 0x0000fcec, 0x000015e0, 0x0000fced, 0x000015e2, 0x0000fcee, 0x000015e4, 0x0000fcef, 0x000015e6, 0x0000fcf0, 0x000015e8, 0x0000fcf1, 0x000015ea, 0x0000fcf2, 0x000015ec, 0x0000fcf3, 0x000015ef, 0x0000fcf4, 0x000015f2, 0x0000fcf5, 0x000015f5, 0x0000fcf6, 0x000015f7, 0x0000fcf7, 0x000015f9, 0x0000fcf8, 0x000015fb, 0x0000fcf9, 0x000015fd, 0x0000fcfa, 0x000015ff, 0x0000fcfb, 0x00001601, 0x0000fcfc, 0x00001603, 0x0000fcfd, 0x00001605, 0x0000fcfe, 0x00001607, 0x0000fcff, 0x00001609, 0x0000fd00, 0x0000160b, 0x0000fd01, 0x0000160d, 0x0000fd02, 0x0000160f, 0x0000fd03, 0x00001611, 0x0000fd04, 0x00001613, 0x0000fd05, 0x00001615, 0x0000fd06, 0x00001617, 0x0000fd07, 0x00001619, 0x0000fd08, 0x0000161b, 0x0000fd09, 0x0000161d, 0x0000fd0a, 0x0000161f, 0x0000fd0b, 0x00001621, 0x0000fd0c, 0x00001623, 0x0000fd0d, 0x00001625, 0x0000fd0e, 0x00001627, 0x0000fd0f, 0x00001629, 0x0000fd10, 0x0000162b, 0x0000fd11, 0x0000162d, 0x0000fd12, 0x0000162f, 0x0000fd13, 0x00001631, 0x0000fd14, 0x00001633, 0x0000fd15, 0x00001635, 0x0000fd16, 0x00001637, 0x0000fd17, 0x00001639, 0x0000fd18, 0x0000163b, 0x0000fd19, 0x0000163d, 0x0000fd1a, 0x0000163f, 0x0000fd1b, 0x00001641, 0x0000fd1c, 0x00001643, 0x0000fd1d, 0x00001645, 0x0000fd1e, 0x00001647, 0x0000fd1f, 0x00001649, 0x0000fd20, 0x0000164b, 0x0000fd21, 0x0000164d, 0x0000fd22, 0x0000164f, 0x0000fd23, 0x00001651, 0x0000fd24, 0x00001653, 0x0000fd25, 0x00001655, 0x0000fd26, 0x00001657, 0x0000fd27, 0x00001659, 0x0000fd28, 0x0000165b, 0x0000fd29, 0x0000165d, 0x0000fd2a, 0x0000165f, 0x0000fd2b, 0x00001661, 0x0000fd2c, 0x00001663, 0x0000fd2d, 0x00001665, 0x0000fd2e, 0x00001667, 0x0000fd2f, 0x00001669, 0x0000fd30, 0x0000166b, 0x0000fd31, 0x0000166d, 0x0000fd32, 0x0000166f, 0x0000fd33, 0x00001671, 0x0000fd34, 0x00001673, 0x0000fd35, 0x00001675, 0x0000fd36, 0x00001677, 0x0000fd37, 0x00001679, 0x0000fd38, 0x0000167b, 0x0000fd39, 0x0000167d, 0x0000fd3a, 0x0000167f, 0x0000fd3b, 0x00001681, 0x0000fd3c, 0x00001683, 0x0000fd3d, 0x00001685, 0x0000fd50, 0x00001687, 0x0000fd51, 0x0000168a, 0x0000fd52, 0x0000168d, 0x0000fd53, 0x00001690, 0x0000fd54, 0x00001693, 0x0000fd55, 0x00001696, 0x0000fd56, 0x00001699, 0x0000fd57, 0x0000169c, 0x0000fd58, 0x0000169f, 0x0000fd59, 0x000016a2, 0x0000fd5a, 0x000016a5, 0x0000fd5b, 0x000016a8, 0x0000fd5c, 0x000016ab, 0x0000fd5d, 0x000016ae, 0x0000fd5e, 0x000016b1, 0x0000fd5f, 0x000016b4, 0x0000fd60, 0x000016b7, 0x0000fd61, 0x000016ba, 0x0000fd62, 0x000016bd, 0x0000fd63, 0x000016c0, 0x0000fd64, 0x000016c3, 0x0000fd65, 0x000016c6, 0x0000fd66, 0x000016c9, 0x0000fd67, 0x000016cc, 0x0000fd68, 0x000016cf, 0x0000fd69, 0x000016d2, 0x0000fd6a, 0x000016d5, 0x0000fd6b, 0x000016d8, 0x0000fd6c, 0x000016db, 0x0000fd6d, 0x000016de, 0x0000fd6e, 0x000016e1, 0x0000fd6f, 0x000016e4, 0x0000fd70, 0x000016e7, 0x0000fd71, 0x000016ea, 0x0000fd72, 0x000016ed, 0x0000fd73, 0x000016f0, 0x0000fd74, 0x000016f3, 0x0000fd75, 0x000016f6, 0x0000fd76, 0x000016f9, 0x0000fd77, 0x000016fc, 0x0000fd78, 0x000016ff, 0x0000fd79, 0x00001702, 0x0000fd7a, 0x00001705, 0x0000fd7b, 0x00001708, 0x0000fd7c, 0x0000170b, 0x0000fd7d, 0x0000170e, 0x0000fd7e, 0x00001711, 0x0000fd7f, 0x00001714, 0x0000fd80, 0x00001717, 0x0000fd81, 0x0000171a, 0x0000fd82, 0x0000171d, 0x0000fd83, 0x00001720, 0x0000fd84, 0x00001723, 0x0000fd85, 0x00001726, 0x0000fd86, 0x00001729, 0x0000fd87, 0x0000172c, 0x0000fd88, 0x0000172f, 0x0000fd89, 0x00001732, 0x0000fd8a, 0x00001735, 0x0000fd8b, 0x00001738, 0x0000fd8c, 0x0000173b, 0x0000fd8d, 0x0000173e, 0x0000fd8e, 0x00001741, 0x0000fd8f, 0x00001744, 0x0000fd92, 0x00001747, 0x0000fd93, 0x0000174a, 0x0000fd94, 0x0000174d, 0x0000fd95, 0x00001750, 0x0000fd96, 0x00001753, 0x0000fd97, 0x00001756, 0x0000fd98, 0x00001759, 0x0000fd99, 0x0000175c, 0x0000fd9a, 0x0000175f, 0x0000fd9b, 0x00001762, 0x0000fd9c, 0x00001765, 0x0000fd9d, 0x00001768, 0x0000fd9e, 0x0000176b, 0x0000fd9f, 0x0000176e, 0x0000fda0, 0x00001771, 0x0000fda1, 0x00001774, 0x0000fda2, 0x00001777, 0x0000fda3, 0x0000177a, 0x0000fda4, 0x0000177d, 0x0000fda5, 0x00001780, 0x0000fda6, 0x00001783, 0x0000fda7, 0x00001786, 0x0000fda8, 0x00001789, 0x0000fda9, 0x0000178c, 0x0000fdaa, 0x0000178f, 0x0000fdab, 0x00001792, 0x0000fdac, 0x00001795, 0x0000fdad, 0x00001798, 0x0000fdae, 0x0000179b, 0x0000fdaf, 0x0000179e, 0x0000fdb0, 0x000017a1, 0x0000fdb1, 0x000017a4, 0x0000fdb2, 0x000017a7, 0x0000fdb3, 0x000017aa, 0x0000fdb4, 0x000017ad, 0x0000fdb5, 0x000017b0, 0x0000fdb6, 0x000017b3, 0x0000fdb7, 0x000017b6, 0x0000fdb8, 0x000017b9, 0x0000fdb9, 0x000017bc, 0x0000fdba, 0x000017bf, 0x0000fdbb, 0x000017c2, 0x0000fdbc, 0x000017c5, 0x0000fdbd, 0x000017c8, 0x0000fdbe, 0x000017cb, 0x0000fdbf, 0x000017ce, 0x0000fdc0, 0x000017d1, 0x0000fdc1, 0x000017d4, 0x0000fdc2, 0x000017d7, 0x0000fdc3, 0x000017da, 0x0000fdc4, 0x000017dd, 0x0000fdc5, 0x000017e0, 0x0000fdc6, 0x000017e3, 0x0000fdc7, 0x000017e6, 0x0000fdf0, 0x000017e9, 0x0000fdf1, 0x000017ec, 0x0000fdf2, 0x000017ef, 0x0000fdf3, 0x000017f3, 0x0000fdf4, 0x000017f7, 0x0000fdf5, 0x000017fb, 0x0000fdf6, 0x000017ff, 0x0000fdf7, 0x00001803, 0x0000fdf8, 0x00001807, 0x0000fdf9, 0x0000180b, 0x0000fdfa, 0x0000180e, 0x0000fdfb, 0x00001820, 0x0000fdfc, 0x00001828, 0x0000fe30, 0x0000182c, 0x0000fe31, 0x0000182e, 0x0000fe32, 0x0000182f, 0x0000fe33, 0x00001830, 0x0000fe34, 0x00001831, 0x0000fe35, 0x00001832, 0x0000fe36, 0x00001833, 0x0000fe37, 0x00001834, 0x0000fe38, 0x00001835, 0x0000fe39, 0x00001836, 0x0000fe3a, 0x00001837, 0x0000fe3b, 0x00001838, 0x0000fe3c, 0x00001839, 0x0000fe3d, 0x0000183a, 0x0000fe3e, 0x0000183b, 0x0000fe3f, 0x0000183c, 0x0000fe40, 0x0000183d, 0x0000fe41, 0x0000183e, 0x0000fe42, 0x0000183f, 0x0000fe43, 0x00001840, 0x0000fe44, 0x00001841, 0x0000fe49, 0x00001842, 0x0000fe4a, 0x00001844, 0x0000fe4b, 0x00001846, 0x0000fe4c, 0x00001848, 0x0000fe4d, 0x0000184a, 0x0000fe4e, 0x0000184b, 0x0000fe4f, 0x0000184c, 0x0000fe50, 0x0000184d, 0x0000fe51, 0x0000184e, 0x0000fe52, 0x0000184f, 0x0000fe54, 0x00001850, 0x0000fe55, 0x00001851, 0x0000fe56, 0x00001852, 0x0000fe57, 0x00001853, 0x0000fe58, 0x00001854, 0x0000fe59, 0x00001855, 0x0000fe5a, 0x00001856, 0x0000fe5b, 0x00001857, 0x0000fe5c, 0x00001858, 0x0000fe5d, 0x00001859, 0x0000fe5e, 0x0000185a, 0x0000fe5f, 0x0000185b, 0x0000fe60, 0x0000185c, 0x0000fe61, 0x0000185d, 0x0000fe62, 0x0000185e, 0x0000fe63, 0x0000185f, 0x0000fe64, 0x00001860, 0x0000fe65, 0x00001861, 0x0000fe66, 0x00001862, 0x0000fe68, 0x00001863, 0x0000fe69, 0x00001864, 0x0000fe6a, 0x00001865, 0x0000fe6b, 0x00001866, 0x0000fe70, 0x00001867, 0x0000fe71, 0x00001869, 0x0000fe72, 0x0000186b, 0x0000fe74, 0x0000186d, 0x0000fe76, 0x0000186f, 0x0000fe77, 0x00001871, 0x0000fe78, 0x00001873, 0x0000fe79, 0x00001875, 0x0000fe7a, 0x00001877, 0x0000fe7b, 0x00001879, 0x0000fe7c, 0x0000187b, 0x0000fe7d, 0x0000187d, 0x0000fe7e, 0x0000187f, 0x0000fe7f, 0x00001881, 0x0000fe80, 0x00001883, 0x0000fe81, 0x00001884, 0x0000fe82, 0x00001886, 0x0000fe83, 0x00001888, 0x0000fe84, 0x0000188a, 0x0000fe85, 0x0000188c, 0x0000fe86, 0x0000188e, 0x0000fe87, 0x00001890, 0x0000fe88, 0x00001892, 0x0000fe89, 0x00001894, 0x0000fe8a, 0x00001896, 0x0000fe8b, 0x00001898, 0x0000fe8c, 0x0000189a, 0x0000fe8d, 0x0000189c, 0x0000fe8e, 0x0000189d, 0x0000fe8f, 0x0000189e, 0x0000fe90, 0x0000189f, 0x0000fe91, 0x000018a0, 0x0000fe92, 0x000018a1, 0x0000fe93, 0x000018a2, 0x0000fe94, 0x000018a3, 0x0000fe95, 0x000018a4, 0x0000fe96, 0x000018a5, 0x0000fe97, 0x000018a6, 0x0000fe98, 0x000018a7, 0x0000fe99, 0x000018a8, 0x0000fe9a, 0x000018a9, 0x0000fe9b, 0x000018aa, 0x0000fe9c, 0x000018ab, 0x0000fe9d, 0x000018ac, 0x0000fe9e, 0x000018ad, 0x0000fe9f, 0x000018ae, 0x0000fea0, 0x000018af, 0x0000fea1, 0x000018b0, 0x0000fea2, 0x000018b1, 0x0000fea3, 0x000018b2, 0x0000fea4, 0x000018b3, 0x0000fea5, 0x000018b4, 0x0000fea6, 0x000018b5, 0x0000fea7, 0x000018b6, 0x0000fea8, 0x000018b7, 0x0000fea9, 0x000018b8, 0x0000feaa, 0x000018b9, 0x0000feab, 0x000018ba, 0x0000feac, 0x000018bb, 0x0000fead, 0x000018bc, 0x0000feae, 0x000018bd, 0x0000feaf, 0x000018be, 0x0000feb0, 0x000018bf, 0x0000feb1, 0x000018c0, 0x0000feb2, 0x000018c1, 0x0000feb3, 0x000018c2, 0x0000feb4, 0x000018c3, 0x0000feb5, 0x000018c4, 0x0000feb6, 0x000018c5, 0x0000feb7, 0x000018c6, 0x0000feb8, 0x000018c7, 0x0000feb9, 0x000018c8, 0x0000feba, 0x000018c9, 0x0000febb, 0x000018ca, 0x0000febc, 0x000018cb, 0x0000febd, 0x000018cc, 0x0000febe, 0x000018cd, 0x0000febf, 0x000018ce, 0x0000fec0, 0x000018cf, 0x0000fec1, 0x000018d0, 0x0000fec2, 0x000018d1, 0x0000fec3, 0x000018d2, 0x0000fec4, 0x000018d3, 0x0000fec5, 0x000018d4, 0x0000fec6, 0x000018d5, 0x0000fec7, 0x000018d6, 0x0000fec8, 0x000018d7, 0x0000fec9, 0x000018d8, 0x0000feca, 0x000018d9, 0x0000fecb, 0x000018da, 0x0000fecc, 0x000018db, 0x0000fecd, 0x000018dc, 0x0000fece, 0x000018dd, 0x0000fecf, 0x000018de, 0x0000fed0, 0x000018df, 0x0000fed1, 0x000018e0, 0x0000fed2, 0x000018e1, 0x0000fed3, 0x000018e2, 0x0000fed4, 0x000018e3, 0x0000fed5, 0x000018e4, 0x0000fed6, 0x000018e5, 0x0000fed7, 0x000018e6, 0x0000fed8, 0x000018e7, 0x0000fed9, 0x000018e8, 0x0000feda, 0x000018e9, 0x0000fedb, 0x000018ea, 0x0000fedc, 0x000018eb, 0x0000fedd, 0x000018ec, 0x0000fede, 0x000018ed, 0x0000fedf, 0x000018ee, 0x0000fee0, 0x000018ef, 0x0000fee1, 0x000018f0, 0x0000fee2, 0x000018f1, 0x0000fee3, 0x000018f2, 0x0000fee4, 0x000018f3, 0x0000fee5, 0x000018f4, 0x0000fee6, 0x000018f5, 0x0000fee7, 0x000018f6, 0x0000fee8, 0x000018f7, 0x0000fee9, 0x000018f8, 0x0000feea, 0x000018f9, 0x0000feeb, 0x000018fa, 0x0000feec, 0x000018fb, 0x0000feed, 0x000018fc, 0x0000feee, 0x000018fd, 0x0000feef, 0x000018fe, 0x0000fef0, 0x000018ff, 0x0000fef1, 0x00001900, 0x0000fef2, 0x00001901, 0x0000fef3, 0x00001902, 0x0000fef4, 0x00001903, 0x0000fef5, 0x00001904, 0x0000fef6, 0x00001907, 0x0000fef7, 0x0000190a, 0x0000fef8, 0x0000190d, 0x0000fef9, 0x00001910, 0x0000fefa, 0x00001913, 0x0000fefb, 0x00001916, 0x0000fefc, 0x00001918, 0x0000ff01, 0x0000191a, 0x0000ff02, 0x0000191b, 0x0000ff03, 0x0000191c, 0x0000ff04, 0x0000191d, 0x0000ff05, 0x0000191e, 0x0000ff06, 0x0000191f, 0x0000ff07, 0x00001920, 0x0000ff08, 0x00001921, 0x0000ff09, 0x00001922, 0x0000ff0a, 0x00001923, 0x0000ff0b, 0x00001924, 0x0000ff0c, 0x00001925, 0x0000ff0d, 0x00001926, 0x0000ff0e, 0x00001927, 0x0000ff0f, 0x00001928, 0x0000ff10, 0x00001929, 0x0000ff11, 0x0000192a, 0x0000ff12, 0x0000192b, 0x0000ff13, 0x0000192c, 0x0000ff14, 0x0000192d, 0x0000ff15, 0x0000192e, 0x0000ff16, 0x0000192f, 0x0000ff17, 0x00001930, 0x0000ff18, 0x00001931, 0x0000ff19, 0x00001932, 0x0000ff1a, 0x00001933, 0x0000ff1b, 0x00001934, 0x0000ff1c, 0x00001935, 0x0000ff1d, 0x00001936, 0x0000ff1e, 0x00001937, 0x0000ff1f, 0x00001938, 0x0000ff20, 0x00001939, 0x0000ff21, 0x0000193a, 0x0000ff22, 0x0000193b, 0x0000ff23, 0x0000193c, 0x0000ff24, 0x0000193d, 0x0000ff25, 0x0000193e, 0x0000ff26, 0x0000193f, 0x0000ff27, 0x00001940, 0x0000ff28, 0x00001941, 0x0000ff29, 0x00001942, 0x0000ff2a, 0x00001943, 0x0000ff2b, 0x00001944, 0x0000ff2c, 0x00001945, 0x0000ff2d, 0x00001946, 0x0000ff2e, 0x00001947, 0x0000ff2f, 0x00001948, 0x0000ff30, 0x00001949, 0x0000ff31, 0x0000194a, 0x0000ff32, 0x0000194b, 0x0000ff33, 0x0000194c, 0x0000ff34, 0x0000194d, 0x0000ff35, 0x0000194e, 0x0000ff36, 0x0000194f, 0x0000ff37, 0x00001950, 0x0000ff38, 0x00001951, 0x0000ff39, 0x00001952, 0x0000ff3a, 0x00001953, 0x0000ff3b, 0x00001954, 0x0000ff3c, 0x00001955, 0x0000ff3d, 0x00001956, 0x0000ff3e, 0x00001957, 0x0000ff3f, 0x00001958, 0x0000ff40, 0x00001959, 0x0000ff41, 0x0000195a, 0x0000ff42, 0x0000195b, 0x0000ff43, 0x0000195c, 0x0000ff44, 0x0000195d, 0x0000ff45, 0x0000195e, 0x0000ff46, 0x0000195f, 0x0000ff47, 0x00001960, 0x0000ff48, 0x00001961, 0x0000ff49, 0x00001962, 0x0000ff4a, 0x00001963, 0x0000ff4b, 0x00001964, 0x0000ff4c, 0x00001965, 0x0000ff4d, 0x00001966, 0x0000ff4e, 0x00001967, 0x0000ff4f, 0x00001968, 0x0000ff50, 0x00001969, 0x0000ff51, 0x0000196a, 0x0000ff52, 0x0000196b, 0x0000ff53, 0x0000196c, 0x0000ff54, 0x0000196d, 0x0000ff55, 0x0000196e, 0x0000ff56, 0x0000196f, 0x0000ff57, 0x00001970, 0x0000ff58, 0x00001971, 0x0000ff59, 0x00001972, 0x0000ff5a, 0x00001973, 0x0000ff5b, 0x00001974, 0x0000ff5c, 0x00001975, 0x0000ff5d, 0x00001976, 0x0000ff5e, 0x00001977, 0x0000ff5f, 0x00001978, 0x0000ff60, 0x00001979, 0x0000ff61, 0x0000197a, 0x0000ff62, 0x0000197b, 0x0000ff63, 0x0000197c, 0x0000ff64, 0x0000197d, 0x0000ff65, 0x0000197e, 0x0000ff66, 0x0000197f, 0x0000ff67, 0x00001980, 0x0000ff68, 0x00001981, 0x0000ff69, 0x00001982, 0x0000ff6a, 0x00001983, 0x0000ff6b, 0x00001984, 0x0000ff6c, 0x00001985, 0x0000ff6d, 0x00001986, 0x0000ff6e, 0x00001987, 0x0000ff6f, 0x00001988, 0x0000ff70, 0x00001989, 0x0000ff71, 0x0000198a, 0x0000ff72, 0x0000198b, 0x0000ff73, 0x0000198c, 0x0000ff74, 0x0000198d, 0x0000ff75, 0x0000198e, 0x0000ff76, 0x0000198f, 0x0000ff77, 0x00001990, 0x0000ff78, 0x00001991, 0x0000ff79, 0x00001992, 0x0000ff7a, 0x00001993, 0x0000ff7b, 0x00001994, 0x0000ff7c, 0x00001995, 0x0000ff7d, 0x00001996, 0x0000ff7e, 0x00001997, 0x0000ff7f, 0x00001998, 0x0000ff80, 0x00001999, 0x0000ff81, 0x0000199a, 0x0000ff82, 0x0000199b, 0x0000ff83, 0x0000199c, 0x0000ff84, 0x0000199d, 0x0000ff85, 0x0000199e, 0x0000ff86, 0x0000199f, 0x0000ff87, 0x000019a0, 0x0000ff88, 0x000019a1, 0x0000ff89, 0x000019a2, 0x0000ff8a, 0x000019a3, 0x0000ff8b, 0x000019a4, 0x0000ff8c, 0x000019a5, 0x0000ff8d, 0x000019a6, 0x0000ff8e, 0x000019a7, 0x0000ff8f, 0x000019a8, 0x0000ff90, 0x000019a9, 0x0000ff91, 0x000019aa, 0x0000ff92, 0x000019ab, 0x0000ff93, 0x000019ac, 0x0000ff94, 0x000019ad, 0x0000ff95, 0x000019ae, 0x0000ff96, 0x000019af, 0x0000ff97, 0x000019b0, 0x0000ff98, 0x000019b1, 0x0000ff99, 0x000019b2, 0x0000ff9a, 0x000019b3, 0x0000ff9b, 0x000019b4, 0x0000ff9c, 0x000019b5, 0x0000ff9d, 0x000019b6, 0x0000ff9e, 0x000019b7, 0x0000ff9f, 0x000019b8, 0x0000ffa0, 0x000019b9, 0x0000ffa1, 0x000019ba, 0x0000ffa2, 0x000019bb, 0x0000ffa3, 0x000019bc, 0x0000ffa4, 0x000019bd, 0x0000ffa5, 0x000019be, 0x0000ffa6, 0x000019bf, 0x0000ffa7, 0x000019c0, 0x0000ffa8, 0x000019c1, 0x0000ffa9, 0x000019c2, 0x0000ffaa, 0x000019c3, 0x0000ffab, 0x000019c4, 0x0000ffac, 0x000019c5, 0x0000ffad, 0x000019c6, 0x0000ffae, 0x000019c7, 0x0000ffaf, 0x000019c8, 0x0000ffb0, 0x000019c9, 0x0000ffb1, 0x000019ca, 0x0000ffb2, 0x000019cb, 0x0000ffb3, 0x000019cc, 0x0000ffb4, 0x000019cd, 0x0000ffb5, 0x000019ce, 0x0000ffb6, 0x000019cf, 0x0000ffb7, 0x000019d0, 0x0000ffb8, 0x000019d1, 0x0000ffb9, 0x000019d2, 0x0000ffba, 0x000019d3, 0x0000ffbb, 0x000019d4, 0x0000ffbc, 0x000019d5, 0x0000ffbd, 0x000019d6, 0x0000ffbe, 0x000019d7, 0x0000ffc2, 0x000019d8, 0x0000ffc3, 0x000019d9, 0x0000ffc4, 0x000019da, 0x0000ffc5, 0x000019db, 0x0000ffc6, 0x000019dc, 0x0000ffc7, 0x000019dd, 0x0000ffca, 0x000019de, 0x0000ffcb, 0x000019df, 0x0000ffcc, 0x000019e0, 0x0000ffcd, 0x000019e1, 0x0000ffce, 0x000019e2, 0x0000ffcf, 0x000019e3, 0x0000ffd2, 0x000019e4, 0x0000ffd3, 0x000019e5, 0x0000ffd4, 0x000019e6, 0x0000ffd5, 0x000019e7, 0x0000ffd6, 0x000019e8, 0x0000ffd7, 0x000019e9, 0x0000ffda, 0x000019ea, 0x0000ffdb, 0x000019eb, 0x0000ffdc, 0x000019ec, 0x0000ffe0, 0x000019ed, 0x0000ffe1, 0x000019ee, 0x0000ffe2, 0x000019ef, 0x0000ffe3, 0x000019f0, 0x0000ffe4, 0x000019f2, 0x0000ffe5, 0x000019f3, 0x0000ffe6, 0x000019f4, 0x0000ffe8, 0x000019f5, 0x0000ffe9, 0x000019f6, 0x0000ffea, 0x000019f7, 0x0000ffeb, 0x000019f8, 0x0000ffec, 0x000019f9, 0x0000ffed, 0x000019fa, 0x0000ffee, 0x000019fb, 0x0001d15e, 0x000019fc, 0x0001d15f, 0x000019fe, 0x0001d160, 0x00001a00, 0x0001d161, 0x00001a03, 0x0001d162, 0x00001a06, 0x0001d163, 0x00001a09, 0x0001d164, 0x00001a0c, 0x0001d1bb, 0x00001a0f, 0x0001d1bc, 0x00001a11, 0x0001d1bd, 0x00001a13, 0x0001d1be, 0x00001a16, 0x0001d1bf, 0x00001a19, 0x0001d1c0, 0x00001a1c, 0x0001d400, 0x00001a1f, 0x0001d401, 0x00001a20, 0x0001d402, 0x00001a21, 0x0001d403, 0x00001a22, 0x0001d404, 0x00001a23, 0x0001d405, 0x00001a24, 0x0001d406, 0x00001a25, 0x0001d407, 0x00001a26, 0x0001d408, 0x00001a27, 0x0001d409, 0x00001a28, 0x0001d40a, 0x00001a29, 0x0001d40b, 0x00001a2a, 0x0001d40c, 0x00001a2b, 0x0001d40d, 0x00001a2c, 0x0001d40e, 0x00001a2d, 0x0001d40f, 0x00001a2e, 0x0001d410, 0x00001a2f, 0x0001d411, 0x00001a30, 0x0001d412, 0x00001a31, 0x0001d413, 0x00001a32, 0x0001d414, 0x00001a33, 0x0001d415, 0x00001a34, 0x0001d416, 0x00001a35, 0x0001d417, 0x00001a36, 0x0001d418, 0x00001a37, 0x0001d419, 0x00001a38, 0x0001d41a, 0x00001a39, 0x0001d41b, 0x00001a3a, 0x0001d41c, 0x00001a3b, 0x0001d41d, 0x00001a3c, 0x0001d41e, 0x00001a3d, 0x0001d41f, 0x00001a3e, 0x0001d420, 0x00001a3f, 0x0001d421, 0x00001a40, 0x0001d422, 0x00001a41, 0x0001d423, 0x00001a42, 0x0001d424, 0x00001a43, 0x0001d425, 0x00001a44, 0x0001d426, 0x00001a45, 0x0001d427, 0x00001a46, 0x0001d428, 0x00001a47, 0x0001d429, 0x00001a48, 0x0001d42a, 0x00001a49, 0x0001d42b, 0x00001a4a, 0x0001d42c, 0x00001a4b, 0x0001d42d, 0x00001a4c, 0x0001d42e, 0x00001a4d, 0x0001d42f, 0x00001a4e, 0x0001d430, 0x00001a4f, 0x0001d431, 0x00001a50, 0x0001d432, 0x00001a51, 0x0001d433, 0x00001a52, 0x0001d434, 0x00001a53, 0x0001d435, 0x00001a54, 0x0001d436, 0x00001a55, 0x0001d437, 0x00001a56, 0x0001d438, 0x00001a57, 0x0001d439, 0x00001a58, 0x0001d43a, 0x00001a59, 0x0001d43b, 0x00001a5a, 0x0001d43c, 0x00001a5b, 0x0001d43d, 0x00001a5c, 0x0001d43e, 0x00001a5d, 0x0001d43f, 0x00001a5e, 0x0001d440, 0x00001a5f, 0x0001d441, 0x00001a60, 0x0001d442, 0x00001a61, 0x0001d443, 0x00001a62, 0x0001d444, 0x00001a63, 0x0001d445, 0x00001a64, 0x0001d446, 0x00001a65, 0x0001d447, 0x00001a66, 0x0001d448, 0x00001a67, 0x0001d449, 0x00001a68, 0x0001d44a, 0x00001a69, 0x0001d44b, 0x00001a6a, 0x0001d44c, 0x00001a6b, 0x0001d44d, 0x00001a6c, 0x0001d44e, 0x00001a6d, 0x0001d44f, 0x00001a6e, 0x0001d450, 0x00001a6f, 0x0001d451, 0x00001a70, 0x0001d452, 0x00001a71, 0x0001d453, 0x00001a72, 0x0001d454, 0x00001a73, 0x0001d456, 0x00001a74, 0x0001d457, 0x00001a75, 0x0001d458, 0x00001a76, 0x0001d459, 0x00001a77, 0x0001d45a, 0x00001a78, 0x0001d45b, 0x00001a79, 0x0001d45c, 0x00001a7a, 0x0001d45d, 0x00001a7b, 0x0001d45e, 0x00001a7c, 0x0001d45f, 0x00001a7d, 0x0001d460, 0x00001a7e, 0x0001d461, 0x00001a7f, 0x0001d462, 0x00001a80, 0x0001d463, 0x00001a81, 0x0001d464, 0x00001a82, 0x0001d465, 0x00001a83, 0x0001d466, 0x00001a84, 0x0001d467, 0x00001a85, 0x0001d468, 0x00001a86, 0x0001d469, 0x00001a87, 0x0001d46a, 0x00001a88, 0x0001d46b, 0x00001a89, 0x0001d46c, 0x00001a8a, 0x0001d46d, 0x00001a8b, 0x0001d46e, 0x00001a8c, 0x0001d46f, 0x00001a8d, 0x0001d470, 0x00001a8e, 0x0001d471, 0x00001a8f, 0x0001d472, 0x00001a90, 0x0001d473, 0x00001a91, 0x0001d474, 0x00001a92, 0x0001d475, 0x00001a93, 0x0001d476, 0x00001a94, 0x0001d477, 0x00001a95, 0x0001d478, 0x00001a96, 0x0001d479, 0x00001a97, 0x0001d47a, 0x00001a98, 0x0001d47b, 0x00001a99, 0x0001d47c, 0x00001a9a, 0x0001d47d, 0x00001a9b, 0x0001d47e, 0x00001a9c, 0x0001d47f, 0x00001a9d, 0x0001d480, 0x00001a9e, 0x0001d481, 0x00001a9f, 0x0001d482, 0x00001aa0, 0x0001d483, 0x00001aa1, 0x0001d484, 0x00001aa2, 0x0001d485, 0x00001aa3, 0x0001d486, 0x00001aa4, 0x0001d487, 0x00001aa5, 0x0001d488, 0x00001aa6, 0x0001d489, 0x00001aa7, 0x0001d48a, 0x00001aa8, 0x0001d48b, 0x00001aa9, 0x0001d48c, 0x00001aaa, 0x0001d48d, 0x00001aab, 0x0001d48e, 0x00001aac, 0x0001d48f, 0x00001aad, 0x0001d490, 0x00001aae, 0x0001d491, 0x00001aaf, 0x0001d492, 0x00001ab0, 0x0001d493, 0x00001ab1, 0x0001d494, 0x00001ab2, 0x0001d495, 0x00001ab3, 0x0001d496, 0x00001ab4, 0x0001d497, 0x00001ab5, 0x0001d498, 0x00001ab6, 0x0001d499, 0x00001ab7, 0x0001d49a, 0x00001ab8, 0x0001d49b, 0x00001ab9, 0x0001d49c, 0x00001aba, 0x0001d49e, 0x00001abb, 0x0001d49f, 0x00001abc, 0x0001d4a2, 0x00001abd, 0x0001d4a5, 0x00001abe, 0x0001d4a6, 0x00001abf, 0x0001d4a9, 0x00001ac0, 0x0001d4aa, 0x00001ac1, 0x0001d4ab, 0x00001ac2, 0x0001d4ac, 0x00001ac3, 0x0001d4ae, 0x00001ac4, 0x0001d4af, 0x00001ac5, 0x0001d4b0, 0x00001ac6, 0x0001d4b1, 0x00001ac7, 0x0001d4b2, 0x00001ac8, 0x0001d4b3, 0x00001ac9, 0x0001d4b4, 0x00001aca, 0x0001d4b5, 0x00001acb, 0x0001d4b6, 0x00001acc, 0x0001d4b7, 0x00001acd, 0x0001d4b8, 0x00001ace, 0x0001d4b9, 0x00001acf, 0x0001d4bb, 0x00001ad0, 0x0001d4bd, 0x00001ad1, 0x0001d4be, 0x00001ad2, 0x0001d4bf, 0x00001ad3, 0x0001d4c0, 0x00001ad4, 0x0001d4c2, 0x00001ad5, 0x0001d4c3, 0x00001ad6, 0x0001d4c5, 0x00001ad7, 0x0001d4c6, 0x00001ad8, 0x0001d4c7, 0x00001ad9, 0x0001d4c8, 0x00001ada, 0x0001d4c9, 0x00001adb, 0x0001d4ca, 0x00001adc, 0x0001d4cb, 0x00001add, 0x0001d4cc, 0x00001ade, 0x0001d4cd, 0x00001adf, 0x0001d4ce, 0x00001ae0, 0x0001d4cf, 0x00001ae1, 0x0001d4d0, 0x00001ae2, 0x0001d4d1, 0x00001ae3, 0x0001d4d2, 0x00001ae4, 0x0001d4d3, 0x00001ae5, 0x0001d4d4, 0x00001ae6, 0x0001d4d5, 0x00001ae7, 0x0001d4d6, 0x00001ae8, 0x0001d4d7, 0x00001ae9, 0x0001d4d8, 0x00001aea, 0x0001d4d9, 0x00001aeb, 0x0001d4da, 0x00001aec, 0x0001d4db, 0x00001aed, 0x0001d4dc, 0x00001aee, 0x0001d4dd, 0x00001aef, 0x0001d4de, 0x00001af0, 0x0001d4df, 0x00001af1, 0x0001d4e0, 0x00001af2, 0x0001d4e1, 0x00001af3, 0x0001d4e2, 0x00001af4, 0x0001d4e3, 0x00001af5, 0x0001d4e4, 0x00001af6, 0x0001d4e5, 0x00001af7, 0x0001d4e6, 0x00001af8, 0x0001d4e7, 0x00001af9, 0x0001d4e8, 0x00001afa, 0x0001d4e9, 0x00001afb, 0x0001d4ea, 0x00001afc, 0x0001d4eb, 0x00001afd, 0x0001d4ec, 0x00001afe, 0x0001d4ed, 0x00001aff, 0x0001d4ee, 0x00001b00, 0x0001d4ef, 0x00001b01, 0x0001d4f0, 0x00001b02, 0x0001d4f1, 0x00001b03, 0x0001d4f2, 0x00001b04, 0x0001d4f3, 0x00001b05, 0x0001d4f4, 0x00001b06, 0x0001d4f5, 0x00001b07, 0x0001d4f6, 0x00001b08, 0x0001d4f7, 0x00001b09, 0x0001d4f8, 0x00001b0a, 0x0001d4f9, 0x00001b0b, 0x0001d4fa, 0x00001b0c, 0x0001d4fb, 0x00001b0d, 0x0001d4fc, 0x00001b0e, 0x0001d4fd, 0x00001b0f, 0x0001d4fe, 0x00001b10, 0x0001d4ff, 0x00001b11, 0x0001d500, 0x00001b12, 0x0001d501, 0x00001b13, 0x0001d502, 0x00001b14, 0x0001d503, 0x00001b15, 0x0001d504, 0x00001b16, 0x0001d505, 0x00001b17, 0x0001d507, 0x00001b18, 0x0001d508, 0x00001b19, 0x0001d509, 0x00001b1a, 0x0001d50a, 0x00001b1b, 0x0001d50d, 0x00001b1c, 0x0001d50e, 0x00001b1d, 0x0001d50f, 0x00001b1e, 0x0001d510, 0x00001b1f, 0x0001d511, 0x00001b20, 0x0001d512, 0x00001b21, 0x0001d513, 0x00001b22, 0x0001d514, 0x00001b23, 0x0001d516, 0x00001b24, 0x0001d517, 0x00001b25, 0x0001d518, 0x00001b26, 0x0001d519, 0x00001b27, 0x0001d51a, 0x00001b28, 0x0001d51b, 0x00001b29, 0x0001d51c, 0x00001b2a, 0x0001d51e, 0x00001b2b, 0x0001d51f, 0x00001b2c, 0x0001d520, 0x00001b2d, 0x0001d521, 0x00001b2e, 0x0001d522, 0x00001b2f, 0x0001d523, 0x00001b30, 0x0001d524, 0x00001b31, 0x0001d525, 0x00001b32, 0x0001d526, 0x00001b33, 0x0001d527, 0x00001b34, 0x0001d528, 0x00001b35, 0x0001d529, 0x00001b36, 0x0001d52a, 0x00001b37, 0x0001d52b, 0x00001b38, 0x0001d52c, 0x00001b39, 0x0001d52d, 0x00001b3a, 0x0001d52e, 0x00001b3b, 0x0001d52f, 0x00001b3c, 0x0001d530, 0x00001b3d, 0x0001d531, 0x00001b3e, 0x0001d532, 0x00001b3f, 0x0001d533, 0x00001b40, 0x0001d534, 0x00001b41, 0x0001d535, 0x00001b42, 0x0001d536, 0x00001b43, 0x0001d537, 0x00001b44, 0x0001d538, 0x00001b45, 0x0001d539, 0x00001b46, 0x0001d53b, 0x00001b47, 0x0001d53c, 0x00001b48, 0x0001d53d, 0x00001b49, 0x0001d53e, 0x00001b4a, 0x0001d540, 0x00001b4b, 0x0001d541, 0x00001b4c, 0x0001d542, 0x00001b4d, 0x0001d543, 0x00001b4e, 0x0001d544, 0x00001b4f, 0x0001d546, 0x00001b50, 0x0001d54a, 0x00001b51, 0x0001d54b, 0x00001b52, 0x0001d54c, 0x00001b53, 0x0001d54d, 0x00001b54, 0x0001d54e, 0x00001b55, 0x0001d54f, 0x00001b56, 0x0001d550, 0x00001b57, 0x0001d552, 0x00001b58, 0x0001d553, 0x00001b59, 0x0001d554, 0x00001b5a, 0x0001d555, 0x00001b5b, 0x0001d556, 0x00001b5c, 0x0001d557, 0x00001b5d, 0x0001d558, 0x00001b5e, 0x0001d559, 0x00001b5f, 0x0001d55a, 0x00001b60, 0x0001d55b, 0x00001b61, 0x0001d55c, 0x00001b62, 0x0001d55d, 0x00001b63, 0x0001d55e, 0x00001b64, 0x0001d55f, 0x00001b65, 0x0001d560, 0x00001b66, 0x0001d561, 0x00001b67, 0x0001d562, 0x00001b68, 0x0001d563, 0x00001b69, 0x0001d564, 0x00001b6a, 0x0001d565, 0x00001b6b, 0x0001d566, 0x00001b6c, 0x0001d567, 0x00001b6d, 0x0001d568, 0x00001b6e, 0x0001d569, 0x00001b6f, 0x0001d56a, 0x00001b70, 0x0001d56b, 0x00001b71, 0x0001d56c, 0x00001b72, 0x0001d56d, 0x00001b73, 0x0001d56e, 0x00001b74, 0x0001d56f, 0x00001b75, 0x0001d570, 0x00001b76, 0x0001d571, 0x00001b77, 0x0001d572, 0x00001b78, 0x0001d573, 0x00001b79, 0x0001d574, 0x00001b7a, 0x0001d575, 0x00001b7b, 0x0001d576, 0x00001b7c, 0x0001d577, 0x00001b7d, 0x0001d578, 0x00001b7e, 0x0001d579, 0x00001b7f, 0x0001d57a, 0x00001b80, 0x0001d57b, 0x00001b81, 0x0001d57c, 0x00001b82, 0x0001d57d, 0x00001b83, 0x0001d57e, 0x00001b84, 0x0001d57f, 0x00001b85, 0x0001d580, 0x00001b86, 0x0001d581, 0x00001b87, 0x0001d582, 0x00001b88, 0x0001d583, 0x00001b89, 0x0001d584, 0x00001b8a, 0x0001d585, 0x00001b8b, 0x0001d586, 0x00001b8c, 0x0001d587, 0x00001b8d, 0x0001d588, 0x00001b8e, 0x0001d589, 0x00001b8f, 0x0001d58a, 0x00001b90, 0x0001d58b, 0x00001b91, 0x0001d58c, 0x00001b92, 0x0001d58d, 0x00001b93, 0x0001d58e, 0x00001b94, 0x0001d58f, 0x00001b95, 0x0001d590, 0x00001b96, 0x0001d591, 0x00001b97, 0x0001d592, 0x00001b98, 0x0001d593, 0x00001b99, 0x0001d594, 0x00001b9a, 0x0001d595, 0x00001b9b, 0x0001d596, 0x00001b9c, 0x0001d597, 0x00001b9d, 0x0001d598, 0x00001b9e, 0x0001d599, 0x00001b9f, 0x0001d59a, 0x00001ba0, 0x0001d59b, 0x00001ba1, 0x0001d59c, 0x00001ba2, 0x0001d59d, 0x00001ba3, 0x0001d59e, 0x00001ba4, 0x0001d59f, 0x00001ba5, 0x0001d5a0, 0x00001ba6, 0x0001d5a1, 0x00001ba7, 0x0001d5a2, 0x00001ba8, 0x0001d5a3, 0x00001ba9, 0x0001d5a4, 0x00001baa, 0x0001d5a5, 0x00001bab, 0x0001d5a6, 0x00001bac, 0x0001d5a7, 0x00001bad, 0x0001d5a8, 0x00001bae, 0x0001d5a9, 0x00001baf, 0x0001d5aa, 0x00001bb0, 0x0001d5ab, 0x00001bb1, 0x0001d5ac, 0x00001bb2, 0x0001d5ad, 0x00001bb3, 0x0001d5ae, 0x00001bb4, 0x0001d5af, 0x00001bb5, 0x0001d5b0, 0x00001bb6, 0x0001d5b1, 0x00001bb7, 0x0001d5b2, 0x00001bb8, 0x0001d5b3, 0x00001bb9, 0x0001d5b4, 0x00001bba, 0x0001d5b5, 0x00001bbb, 0x0001d5b6, 0x00001bbc, 0x0001d5b7, 0x00001bbd, 0x0001d5b8, 0x00001bbe, 0x0001d5b9, 0x00001bbf, 0x0001d5ba, 0x00001bc0, 0x0001d5bb, 0x00001bc1, 0x0001d5bc, 0x00001bc2, 0x0001d5bd, 0x00001bc3, 0x0001d5be, 0x00001bc4, 0x0001d5bf, 0x00001bc5, 0x0001d5c0, 0x00001bc6, 0x0001d5c1, 0x00001bc7, 0x0001d5c2, 0x00001bc8, 0x0001d5c3, 0x00001bc9, 0x0001d5c4, 0x00001bca, 0x0001d5c5, 0x00001bcb, 0x0001d5c6, 0x00001bcc, 0x0001d5c7, 0x00001bcd, 0x0001d5c8, 0x00001bce, 0x0001d5c9, 0x00001bcf, 0x0001d5ca, 0x00001bd0, 0x0001d5cb, 0x00001bd1, 0x0001d5cc, 0x00001bd2, 0x0001d5cd, 0x00001bd3, 0x0001d5ce, 0x00001bd4, 0x0001d5cf, 0x00001bd5, 0x0001d5d0, 0x00001bd6, 0x0001d5d1, 0x00001bd7, 0x0001d5d2, 0x00001bd8, 0x0001d5d3, 0x00001bd9, 0x0001d5d4, 0x00001bda, 0x0001d5d5, 0x00001bdb, 0x0001d5d6, 0x00001bdc, 0x0001d5d7, 0x00001bdd, 0x0001d5d8, 0x00001bde, 0x0001d5d9, 0x00001bdf, 0x0001d5da, 0x00001be0, 0x0001d5db, 0x00001be1, 0x0001d5dc, 0x00001be2, 0x0001d5dd, 0x00001be3, 0x0001d5de, 0x00001be4, 0x0001d5df, 0x00001be5, 0x0001d5e0, 0x00001be6, 0x0001d5e1, 0x00001be7, 0x0001d5e2, 0x00001be8, 0x0001d5e3, 0x00001be9, 0x0001d5e4, 0x00001bea, 0x0001d5e5, 0x00001beb, 0x0001d5e6, 0x00001bec, 0x0001d5e7, 0x00001bed, 0x0001d5e8, 0x00001bee, 0x0001d5e9, 0x00001bef, 0x0001d5ea, 0x00001bf0, 0x0001d5eb, 0x00001bf1, 0x0001d5ec, 0x00001bf2, 0x0001d5ed, 0x00001bf3, 0x0001d5ee, 0x00001bf4, 0x0001d5ef, 0x00001bf5, 0x0001d5f0, 0x00001bf6, 0x0001d5f1, 0x00001bf7, 0x0001d5f2, 0x00001bf8, 0x0001d5f3, 0x00001bf9, 0x0001d5f4, 0x00001bfa, 0x0001d5f5, 0x00001bfb, 0x0001d5f6, 0x00001bfc, 0x0001d5f7, 0x00001bfd, 0x0001d5f8, 0x00001bfe, 0x0001d5f9, 0x00001bff, 0x0001d5fa, 0x00001c00, 0x0001d5fb, 0x00001c01, 0x0001d5fc, 0x00001c02, 0x0001d5fd, 0x00001c03, 0x0001d5fe, 0x00001c04, 0x0001d5ff, 0x00001c05, 0x0001d600, 0x00001c06, 0x0001d601, 0x00001c07, 0x0001d602, 0x00001c08, 0x0001d603, 0x00001c09, 0x0001d604, 0x00001c0a, 0x0001d605, 0x00001c0b, 0x0001d606, 0x00001c0c, 0x0001d607, 0x00001c0d, 0x0001d608, 0x00001c0e, 0x0001d609, 0x00001c0f, 0x0001d60a, 0x00001c10, 0x0001d60b, 0x00001c11, 0x0001d60c, 0x00001c12, 0x0001d60d, 0x00001c13, 0x0001d60e, 0x00001c14, 0x0001d60f, 0x00001c15, 0x0001d610, 0x00001c16, 0x0001d611, 0x00001c17, 0x0001d612, 0x00001c18, 0x0001d613, 0x00001c19, 0x0001d614, 0x00001c1a, 0x0001d615, 0x00001c1b, 0x0001d616, 0x00001c1c, 0x0001d617, 0x00001c1d, 0x0001d618, 0x00001c1e, 0x0001d619, 0x00001c1f, 0x0001d61a, 0x00001c20, 0x0001d61b, 0x00001c21, 0x0001d61c, 0x00001c22, 0x0001d61d, 0x00001c23, 0x0001d61e, 0x00001c24, 0x0001d61f, 0x00001c25, 0x0001d620, 0x00001c26, 0x0001d621, 0x00001c27, 0x0001d622, 0x00001c28, 0x0001d623, 0x00001c29, 0x0001d624, 0x00001c2a, 0x0001d625, 0x00001c2b, 0x0001d626, 0x00001c2c, 0x0001d627, 0x00001c2d, 0x0001d628, 0x00001c2e, 0x0001d629, 0x00001c2f, 0x0001d62a, 0x00001c30, 0x0001d62b, 0x00001c31, 0x0001d62c, 0x00001c32, 0x0001d62d, 0x00001c33, 0x0001d62e, 0x00001c34, 0x0001d62f, 0x00001c35, 0x0001d630, 0x00001c36, 0x0001d631, 0x00001c37, 0x0001d632, 0x00001c38, 0x0001d633, 0x00001c39, 0x0001d634, 0x00001c3a, 0x0001d635, 0x00001c3b, 0x0001d636, 0x00001c3c, 0x0001d637, 0x00001c3d, 0x0001d638, 0x00001c3e, 0x0001d639, 0x00001c3f, 0x0001d63a, 0x00001c40, 0x0001d63b, 0x00001c41, 0x0001d63c, 0x00001c42, 0x0001d63d, 0x00001c43, 0x0001d63e, 0x00001c44, 0x0001d63f, 0x00001c45, 0x0001d640, 0x00001c46, 0x0001d641, 0x00001c47, 0x0001d642, 0x00001c48, 0x0001d643, 0x00001c49, 0x0001d644, 0x00001c4a, 0x0001d645, 0x00001c4b, 0x0001d646, 0x00001c4c, 0x0001d647, 0x00001c4d, 0x0001d648, 0x00001c4e, 0x0001d649, 0x00001c4f, 0x0001d64a, 0x00001c50, 0x0001d64b, 0x00001c51, 0x0001d64c, 0x00001c52, 0x0001d64d, 0x00001c53, 0x0001d64e, 0x00001c54, 0x0001d64f, 0x00001c55, 0x0001d650, 0x00001c56, 0x0001d651, 0x00001c57, 0x0001d652, 0x00001c58, 0x0001d653, 0x00001c59, 0x0001d654, 0x00001c5a, 0x0001d655, 0x00001c5b, 0x0001d656, 0x00001c5c, 0x0001d657, 0x00001c5d, 0x0001d658, 0x00001c5e, 0x0001d659, 0x00001c5f, 0x0001d65a, 0x00001c60, 0x0001d65b, 0x00001c61, 0x0001d65c, 0x00001c62, 0x0001d65d, 0x00001c63, 0x0001d65e, 0x00001c64, 0x0001d65f, 0x00001c65, 0x0001d660, 0x00001c66, 0x0001d661, 0x00001c67, 0x0001d662, 0x00001c68, 0x0001d663, 0x00001c69, 0x0001d664, 0x00001c6a, 0x0001d665, 0x00001c6b, 0x0001d666, 0x00001c6c, 0x0001d667, 0x00001c6d, 0x0001d668, 0x00001c6e, 0x0001d669, 0x00001c6f, 0x0001d66a, 0x00001c70, 0x0001d66b, 0x00001c71, 0x0001d66c, 0x00001c72, 0x0001d66d, 0x00001c73, 0x0001d66e, 0x00001c74, 0x0001d66f, 0x00001c75, 0x0001d670, 0x00001c76, 0x0001d671, 0x00001c77, 0x0001d672, 0x00001c78, 0x0001d673, 0x00001c79, 0x0001d674, 0x00001c7a, 0x0001d675, 0x00001c7b, 0x0001d676, 0x00001c7c, 0x0001d677, 0x00001c7d, 0x0001d678, 0x00001c7e, 0x0001d679, 0x00001c7f, 0x0001d67a, 0x00001c80, 0x0001d67b, 0x00001c81, 0x0001d67c, 0x00001c82, 0x0001d67d, 0x00001c83, 0x0001d67e, 0x00001c84, 0x0001d67f, 0x00001c85, 0x0001d680, 0x00001c86, 0x0001d681, 0x00001c87, 0x0001d682, 0x00001c88, 0x0001d683, 0x00001c89, 0x0001d684, 0x00001c8a, 0x0001d685, 0x00001c8b, 0x0001d686, 0x00001c8c, 0x0001d687, 0x00001c8d, 0x0001d688, 0x00001c8e, 0x0001d689, 0x00001c8f, 0x0001d68a, 0x00001c90, 0x0001d68b, 0x00001c91, 0x0001d68c, 0x00001c92, 0x0001d68d, 0x00001c93, 0x0001d68e, 0x00001c94, 0x0001d68f, 0x00001c95, 0x0001d690, 0x00001c96, 0x0001d691, 0x00001c97, 0x0001d692, 0x00001c98, 0x0001d693, 0x00001c99, 0x0001d694, 0x00001c9a, 0x0001d695, 0x00001c9b, 0x0001d696, 0x00001c9c, 0x0001d697, 0x00001c9d, 0x0001d698, 0x00001c9e, 0x0001d699, 0x00001c9f, 0x0001d69a, 0x00001ca0, 0x0001d69b, 0x00001ca1, 0x0001d69c, 0x00001ca2, 0x0001d69d, 0x00001ca3, 0x0001d69e, 0x00001ca4, 0x0001d69f, 0x00001ca5, 0x0001d6a0, 0x00001ca6, 0x0001d6a1, 0x00001ca7, 0x0001d6a2, 0x00001ca8, 0x0001d6a3, 0x00001ca9, 0x0001d6a8, 0x00001caa, 0x0001d6a9, 0x00001cab, 0x0001d6aa, 0x00001cac, 0x0001d6ab, 0x00001cad, 0x0001d6ac, 0x00001cae, 0x0001d6ad, 0x00001caf, 0x0001d6ae, 0x00001cb0, 0x0001d6af, 0x00001cb1, 0x0001d6b0, 0x00001cb2, 0x0001d6b1, 0x00001cb3, 0x0001d6b2, 0x00001cb4, 0x0001d6b3, 0x00001cb5, 0x0001d6b4, 0x00001cb6, 0x0001d6b5, 0x00001cb7, 0x0001d6b6, 0x00001cb8, 0x0001d6b7, 0x00001cb9, 0x0001d6b8, 0x00001cba, 0x0001d6b9, 0x00001cbb, 0x0001d6ba, 0x00001cbc, 0x0001d6bb, 0x00001cbd, 0x0001d6bc, 0x00001cbe, 0x0001d6bd, 0x00001cbf, 0x0001d6be, 0x00001cc0, 0x0001d6bf, 0x00001cc1, 0x0001d6c0, 0x00001cc2, 0x0001d6c1, 0x00001cc3, 0x0001d6c2, 0x00001cc4, 0x0001d6c3, 0x00001cc5, 0x0001d6c4, 0x00001cc6, 0x0001d6c5, 0x00001cc7, 0x0001d6c6, 0x00001cc8, 0x0001d6c7, 0x00001cc9, 0x0001d6c8, 0x00001cca, 0x0001d6c9, 0x00001ccb, 0x0001d6ca, 0x00001ccc, 0x0001d6cb, 0x00001ccd, 0x0001d6cc, 0x00001cce, 0x0001d6cd, 0x00001ccf, 0x0001d6ce, 0x00001cd0, 0x0001d6cf, 0x00001cd1, 0x0001d6d0, 0x00001cd2, 0x0001d6d1, 0x00001cd3, 0x0001d6d2, 0x00001cd4, 0x0001d6d3, 0x00001cd5, 0x0001d6d4, 0x00001cd6, 0x0001d6d5, 0x00001cd7, 0x0001d6d6, 0x00001cd8, 0x0001d6d7, 0x00001cd9, 0x0001d6d8, 0x00001cda, 0x0001d6d9, 0x00001cdb, 0x0001d6da, 0x00001cdc, 0x0001d6db, 0x00001cdd, 0x0001d6dc, 0x00001cde, 0x0001d6dd, 0x00001cdf, 0x0001d6de, 0x00001ce0, 0x0001d6df, 0x00001ce1, 0x0001d6e0, 0x00001ce2, 0x0001d6e1, 0x00001ce3, 0x0001d6e2, 0x00001ce4, 0x0001d6e3, 0x00001ce5, 0x0001d6e4, 0x00001ce6, 0x0001d6e5, 0x00001ce7, 0x0001d6e6, 0x00001ce8, 0x0001d6e7, 0x00001ce9, 0x0001d6e8, 0x00001cea, 0x0001d6e9, 0x00001ceb, 0x0001d6ea, 0x00001cec, 0x0001d6eb, 0x00001ced, 0x0001d6ec, 0x00001cee, 0x0001d6ed, 0x00001cef, 0x0001d6ee, 0x00001cf0, 0x0001d6ef, 0x00001cf1, 0x0001d6f0, 0x00001cf2, 0x0001d6f1, 0x00001cf3, 0x0001d6f2, 0x00001cf4, 0x0001d6f3, 0x00001cf5, 0x0001d6f4, 0x00001cf6, 0x0001d6f5, 0x00001cf7, 0x0001d6f6, 0x00001cf8, 0x0001d6f7, 0x00001cf9, 0x0001d6f8, 0x00001cfa, 0x0001d6f9, 0x00001cfb, 0x0001d6fa, 0x00001cfc, 0x0001d6fb, 0x00001cfd, 0x0001d6fc, 0x00001cfe, 0x0001d6fd, 0x00001cff, 0x0001d6fe, 0x00001d00, 0x0001d6ff, 0x00001d01, 0x0001d700, 0x00001d02, 0x0001d701, 0x00001d03, 0x0001d702, 0x00001d04, 0x0001d703, 0x00001d05, 0x0001d704, 0x00001d06, 0x0001d705, 0x00001d07, 0x0001d706, 0x00001d08, 0x0001d707, 0x00001d09, 0x0001d708, 0x00001d0a, 0x0001d709, 0x00001d0b, 0x0001d70a, 0x00001d0c, 0x0001d70b, 0x00001d0d, 0x0001d70c, 0x00001d0e, 0x0001d70d, 0x00001d0f, 0x0001d70e, 0x00001d10, 0x0001d70f, 0x00001d11, 0x0001d710, 0x00001d12, 0x0001d711, 0x00001d13, 0x0001d712, 0x00001d14, 0x0001d713, 0x00001d15, 0x0001d714, 0x00001d16, 0x0001d715, 0x00001d17, 0x0001d716, 0x00001d18, 0x0001d717, 0x00001d19, 0x0001d718, 0x00001d1a, 0x0001d719, 0x00001d1b, 0x0001d71a, 0x00001d1c, 0x0001d71b, 0x00001d1d, 0x0001d71c, 0x00001d1e, 0x0001d71d, 0x00001d1f, 0x0001d71e, 0x00001d20, 0x0001d71f, 0x00001d21, 0x0001d720, 0x00001d22, 0x0001d721, 0x00001d23, 0x0001d722, 0x00001d24, 0x0001d723, 0x00001d25, 0x0001d724, 0x00001d26, 0x0001d725, 0x00001d27, 0x0001d726, 0x00001d28, 0x0001d727, 0x00001d29, 0x0001d728, 0x00001d2a, 0x0001d729, 0x00001d2b, 0x0001d72a, 0x00001d2c, 0x0001d72b, 0x00001d2d, 0x0001d72c, 0x00001d2e, 0x0001d72d, 0x00001d2f, 0x0001d72e, 0x00001d30, 0x0001d72f, 0x00001d31, 0x0001d730, 0x00001d32, 0x0001d731, 0x00001d33, 0x0001d732, 0x00001d34, 0x0001d733, 0x00001d35, 0x0001d734, 0x00001d36, 0x0001d735, 0x00001d37, 0x0001d736, 0x00001d38, 0x0001d737, 0x00001d39, 0x0001d738, 0x00001d3a, 0x0001d739, 0x00001d3b, 0x0001d73a, 0x00001d3c, 0x0001d73b, 0x00001d3d, 0x0001d73c, 0x00001d3e, 0x0001d73d, 0x00001d3f, 0x0001d73e, 0x00001d40, 0x0001d73f, 0x00001d41, 0x0001d740, 0x00001d42, 0x0001d741, 0x00001d43, 0x0001d742, 0x00001d44, 0x0001d743, 0x00001d45, 0x0001d744, 0x00001d46, 0x0001d745, 0x00001d47, 0x0001d746, 0x00001d48, 0x0001d747, 0x00001d49, 0x0001d748, 0x00001d4a, 0x0001d749, 0x00001d4b, 0x0001d74a, 0x00001d4c, 0x0001d74b, 0x00001d4d, 0x0001d74c, 0x00001d4e, 0x0001d74d, 0x00001d4f, 0x0001d74e, 0x00001d50, 0x0001d74f, 0x00001d51, 0x0001d750, 0x00001d52, 0x0001d751, 0x00001d53, 0x0001d752, 0x00001d54, 0x0001d753, 0x00001d55, 0x0001d754, 0x00001d56, 0x0001d755, 0x00001d57, 0x0001d756, 0x00001d58, 0x0001d757, 0x00001d59, 0x0001d758, 0x00001d5a, 0x0001d759, 0x00001d5b, 0x0001d75a, 0x00001d5c, 0x0001d75b, 0x00001d5d, 0x0001d75c, 0x00001d5e, 0x0001d75d, 0x00001d5f, 0x0001d75e, 0x00001d60, 0x0001d75f, 0x00001d61, 0x0001d760, 0x00001d62, 0x0001d761, 0x00001d63, 0x0001d762, 0x00001d64, 0x0001d763, 0x00001d65, 0x0001d764, 0x00001d66, 0x0001d765, 0x00001d67, 0x0001d766, 0x00001d68, 0x0001d767, 0x00001d69, 0x0001d768, 0x00001d6a, 0x0001d769, 0x00001d6b, 0x0001d76a, 0x00001d6c, 0x0001d76b, 0x00001d6d, 0x0001d76c, 0x00001d6e, 0x0001d76d, 0x00001d6f, 0x0001d76e, 0x00001d70, 0x0001d76f, 0x00001d71, 0x0001d770, 0x00001d72, 0x0001d771, 0x00001d73, 0x0001d772, 0x00001d74, 0x0001d773, 0x00001d75, 0x0001d774, 0x00001d76, 0x0001d775, 0x00001d77, 0x0001d776, 0x00001d78, 0x0001d777, 0x00001d79, 0x0001d778, 0x00001d7a, 0x0001d779, 0x00001d7b, 0x0001d77a, 0x00001d7c, 0x0001d77b, 0x00001d7d, 0x0001d77c, 0x00001d7e, 0x0001d77d, 0x00001d7f, 0x0001d77e, 0x00001d80, 0x0001d77f, 0x00001d81, 0x0001d780, 0x00001d82, 0x0001d781, 0x00001d83, 0x0001d782, 0x00001d84, 0x0001d783, 0x00001d85, 0x0001d784, 0x00001d86, 0x0001d785, 0x00001d87, 0x0001d786, 0x00001d88, 0x0001d787, 0x00001d89, 0x0001d788, 0x00001d8a, 0x0001d789, 0x00001d8b, 0x0001d78a, 0x00001d8c, 0x0001d78b, 0x00001d8d, 0x0001d78c, 0x00001d8e, 0x0001d78d, 0x00001d8f, 0x0001d78e, 0x00001d90, 0x0001d78f, 0x00001d91, 0x0001d790, 0x00001d92, 0x0001d791, 0x00001d93, 0x0001d792, 0x00001d94, 0x0001d793, 0x00001d95, 0x0001d794, 0x00001d96, 0x0001d795, 0x00001d97, 0x0001d796, 0x00001d98, 0x0001d797, 0x00001d99, 0x0001d798, 0x00001d9a, 0x0001d799, 0x00001d9b, 0x0001d79a, 0x00001d9c, 0x0001d79b, 0x00001d9d, 0x0001d79c, 0x00001d9e, 0x0001d79d, 0x00001d9f, 0x0001d79e, 0x00001da0, 0x0001d79f, 0x00001da1, 0x0001d7a0, 0x00001da2, 0x0001d7a1, 0x00001da3, 0x0001d7a2, 0x00001da4, 0x0001d7a3, 0x00001da5, 0x0001d7a4, 0x00001da6, 0x0001d7a5, 0x00001da7, 0x0001d7a6, 0x00001da8, 0x0001d7a7, 0x00001da9, 0x0001d7a8, 0x00001daa, 0x0001d7a9, 0x00001dab, 0x0001d7aa, 0x00001dac, 0x0001d7ab, 0x00001dad, 0x0001d7ac, 0x00001dae, 0x0001d7ad, 0x00001daf, 0x0001d7ae, 0x00001db0, 0x0001d7af, 0x00001db1, 0x0001d7b0, 0x00001db2, 0x0001d7b1, 0x00001db3, 0x0001d7b2, 0x00001db4, 0x0001d7b3, 0x00001db5, 0x0001d7b4, 0x00001db6, 0x0001d7b5, 0x00001db7, 0x0001d7b6, 0x00001db8, 0x0001d7b7, 0x00001db9, 0x0001d7b8, 0x00001dba, 0x0001d7b9, 0x00001dbb, 0x0001d7ba, 0x00001dbc, 0x0001d7bb, 0x00001dbd, 0x0001d7bc, 0x00001dbe, 0x0001d7bd, 0x00001dbf, 0x0001d7be, 0x00001dc0, 0x0001d7bf, 0x00001dc1, 0x0001d7c0, 0x00001dc2, 0x0001d7c1, 0x00001dc3, 0x0001d7c2, 0x00001dc4, 0x0001d7c3, 0x00001dc5, 0x0001d7c4, 0x00001dc6, 0x0001d7c5, 0x00001dc7, 0x0001d7c6, 0x00001dc8, 0x0001d7c7, 0x00001dc9, 0x0001d7c8, 0x00001dca, 0x0001d7c9, 0x00001dcb, 0x0001d7ce, 0x00001dcc, 0x0001d7cf, 0x00001dcd, 0x0001d7d0, 0x00001dce, 0x0001d7d1, 0x00001dcf, 0x0001d7d2, 0x00001dd0, 0x0001d7d3, 0x00001dd1, 0x0001d7d4, 0x00001dd2, 0x0001d7d5, 0x00001dd3, 0x0001d7d6, 0x00001dd4, 0x0001d7d7, 0x00001dd5, 0x0001d7d8, 0x00001dd6, 0x0001d7d9, 0x00001dd7, 0x0001d7da, 0x00001dd8, 0x0001d7db, 0x00001dd9, 0x0001d7dc, 0x00001dda, 0x0001d7dd, 0x00001ddb, 0x0001d7de, 0x00001ddc, 0x0001d7df, 0x00001ddd, 0x0001d7e0, 0x00001dde, 0x0001d7e1, 0x00001ddf, 0x0001d7e2, 0x00001de0, 0x0001d7e3, 0x00001de1, 0x0001d7e4, 0x00001de2, 0x0001d7e5, 0x00001de3, 0x0001d7e6, 0x00001de4, 0x0001d7e7, 0x00001de5, 0x0001d7e8, 0x00001de6, 0x0001d7e9, 0x00001de7, 0x0001d7ea, 0x00001de8, 0x0001d7eb, 0x00001de9, 0x0001d7ec, 0x00001dea, 0x0001d7ed, 0x00001deb, 0x0001d7ee, 0x00001dec, 0x0001d7ef, 0x00001ded, 0x0001d7f0, 0x00001dee, 0x0001d7f1, 0x00001def, 0x0001d7f2, 0x00001df0, 0x0001d7f3, 0x00001df1, 0x0001d7f4, 0x00001df2, 0x0001d7f5, 0x00001df3, 0x0001d7f6, 0x00001df4, 0x0001d7f7, 0x00001df5, 0x0001d7f8, 0x00001df6, 0x0001d7f9, 0x00001df7, 0x0001d7fa, 0x00001df8, 0x0001d7fb, 0x00001df9, 0x0001d7fc, 0x00001dfa, 0x0001d7fd, 0x00001dfb, 0x0001d7fe, 0x00001dfc, 0x0001d7ff, 0x00001dfd, 0x0002f800, 0x00001dfe, 0x0002f801, 0x00001dff, 0x0002f802, 0x00001e00, 0x0002f803, 0x00001e01, 0x0002f804, 0x00001e02, 0x0002f805, 0x00001e03, 0x0002f806, 0x00001e04, 0x0002f807, 0x00001e05, 0x0002f808, 0x00001e06, 0x0002f809, 0x00001e07, 0x0002f80a, 0x00001e08, 0x0002f80b, 0x00001e09, 0x0002f80c, 0x00001e0a, 0x0002f80d, 0x00001e0b, 0x0002f80e, 0x00001e0c, 0x0002f80f, 0x00001e0d, 0x0002f810, 0x00001e0e, 0x0002f811, 0x00001e0f, 0x0002f812, 0x00001e10, 0x0002f813, 0x00001e11, 0x0002f814, 0x00001e12, 0x0002f815, 0x00001e13, 0x0002f816, 0x00001e14, 0x0002f817, 0x00001e15, 0x0002f818, 0x00001e16, 0x0002f819, 0x00001e17, 0x0002f81a, 0x00001e18, 0x0002f81b, 0x00001e19, 0x0002f81c, 0x00001e1a, 0x0002f81d, 0x00001e1b, 0x0002f81e, 0x00001e1c, 0x0002f81f, 0x00001e1d, 0x0002f820, 0x00001e1e, 0x0002f821, 0x00001e1f, 0x0002f822, 0x00001e20, 0x0002f823, 0x00001e21, 0x0002f824, 0x00001e22, 0x0002f825, 0x00001e23, 0x0002f826, 0x00001e24, 0x0002f827, 0x00001e25, 0x0002f828, 0x00001e26, 0x0002f829, 0x00001e27, 0x0002f82a, 0x00001e28, 0x0002f82b, 0x00001e29, 0x0002f82c, 0x00001e2a, 0x0002f82d, 0x00001e2b, 0x0002f82e, 0x00001e2c, 0x0002f82f, 0x00001e2d, 0x0002f830, 0x00001e2e, 0x0002f831, 0x00001e2f, 0x0002f832, 0x00001e30, 0x0002f833, 0x00001e31, 0x0002f834, 0x00001e32, 0x0002f835, 0x00001e33, 0x0002f836, 0x00001e34, 0x0002f837, 0x00001e35, 0x0002f838, 0x00001e36, 0x0002f839, 0x00001e37, 0x0002f83a, 0x00001e38, 0x0002f83b, 0x00001e39, 0x0002f83c, 0x00001e3a, 0x0002f83d, 0x00001e3b, 0x0002f83e, 0x00001e3c, 0x0002f83f, 0x00001e3d, 0x0002f840, 0x00001e3e, 0x0002f841, 0x00001e3f, 0x0002f842, 0x00001e40, 0x0002f843, 0x00001e41, 0x0002f844, 0x00001e42, 0x0002f845, 0x00001e43, 0x0002f846, 0x00001e44, 0x0002f847, 0x00001e45, 0x0002f848, 0x00001e46, 0x0002f849, 0x00001e47, 0x0002f84a, 0x00001e48, 0x0002f84b, 0x00001e49, 0x0002f84c, 0x00001e4a, 0x0002f84d, 0x00001e4b, 0x0002f84e, 0x00001e4c, 0x0002f84f, 0x00001e4d, 0x0002f850, 0x00001e4e, 0x0002f851, 0x00001e4f, 0x0002f852, 0x00001e50, 0x0002f853, 0x00001e51, 0x0002f854, 0x00001e52, 0x0002f855, 0x00001e53, 0x0002f856, 0x00001e54, 0x0002f857, 0x00001e55, 0x0002f858, 0x00001e56, 0x0002f859, 0x00001e57, 0x0002f85a, 0x00001e58, 0x0002f85b, 0x00001e59, 0x0002f85c, 0x00001e5a, 0x0002f85d, 0x00001e5b, 0x0002f85e, 0x00001e5c, 0x0002f85f, 0x00001e5d, 0x0002f860, 0x00001e5e, 0x0002f861, 0x00001e5f, 0x0002f862, 0x00001e60, 0x0002f863, 0x00001e61, 0x0002f864, 0x00001e62, 0x0002f865, 0x00001e63, 0x0002f866, 0x00001e64, 0x0002f867, 0x00001e65, 0x0002f868, 0x00001e66, 0x0002f869, 0x00001e67, 0x0002f86a, 0x00001e68, 0x0002f86b, 0x00001e69, 0x0002f86c, 0x00001e6a, 0x0002f86d, 0x00001e6b, 0x0002f86e, 0x00001e6c, 0x0002f86f, 0x00001e6d, 0x0002f870, 0x00001e6e, 0x0002f871, 0x00001e6f, 0x0002f872, 0x00001e70, 0x0002f873, 0x00001e71, 0x0002f874, 0x00001e72, 0x0002f875, 0x00001e73, 0x0002f876, 0x00001e74, 0x0002f877, 0x00001e75, 0x0002f878, 0x00001e76, 0x0002f879, 0x00001e77, 0x0002f87a, 0x00001e78, 0x0002f87b, 0x00001e79, 0x0002f87c, 0x00001e7a, 0x0002f87d, 0x00001e7b, 0x0002f87e, 0x00001e7c, 0x0002f87f, 0x00001e7d, 0x0002f880, 0x00001e7e, 0x0002f881, 0x00001e7f, 0x0002f882, 0x00001e80, 0x0002f883, 0x00001e81, 0x0002f884, 0x00001e82, 0x0002f885, 0x00001e83, 0x0002f886, 0x00001e84, 0x0002f887, 0x00001e85, 0x0002f888, 0x00001e86, 0x0002f889, 0x00001e87, 0x0002f88a, 0x00001e88, 0x0002f88b, 0x00001e89, 0x0002f88c, 0x00001e8a, 0x0002f88d, 0x00001e8b, 0x0002f88e, 0x00001e8c, 0x0002f88f, 0x00001e8d, 0x0002f890, 0x00001e8e, 0x0002f891, 0x00001e8f, 0x0002f892, 0x00001e90, 0x0002f893, 0x00001e91, 0x0002f894, 0x00001e92, 0x0002f895, 0x00001e93, 0x0002f896, 0x00001e94, 0x0002f897, 0x00001e95, 0x0002f898, 0x00001e96, 0x0002f899, 0x00001e97, 0x0002f89a, 0x00001e98, 0x0002f89b, 0x00001e99, 0x0002f89c, 0x00001e9a, 0x0002f89d, 0x00001e9b, 0x0002f89e, 0x00001e9c, 0x0002f89f, 0x00001e9d, 0x0002f8a0, 0x00001e9e, 0x0002f8a1, 0x00001e9f, 0x0002f8a2, 0x00001ea0, 0x0002f8a3, 0x00001ea1, 0x0002f8a4, 0x00001ea2, 0x0002f8a5, 0x00001ea3, 0x0002f8a6, 0x00001ea4, 0x0002f8a7, 0x00001ea5, 0x0002f8a8, 0x00001ea6, 0x0002f8a9, 0x00001ea7, 0x0002f8aa, 0x00001ea8, 0x0002f8ab, 0x00001ea9, 0x0002f8ac, 0x00001eaa, 0x0002f8ad, 0x00001eab, 0x0002f8ae, 0x00001eac, 0x0002f8af, 0x00001ead, 0x0002f8b0, 0x00001eae, 0x0002f8b1, 0x00001eaf, 0x0002f8b2, 0x00001eb0, 0x0002f8b3, 0x00001eb1, 0x0002f8b4, 0x00001eb2, 0x0002f8b5, 0x00001eb3, 0x0002f8b6, 0x00001eb4, 0x0002f8b7, 0x00001eb5, 0x0002f8b8, 0x00001eb6, 0x0002f8b9, 0x00001eb7, 0x0002f8ba, 0x00001eb8, 0x0002f8bb, 0x00001eb9, 0x0002f8bc, 0x00001eba, 0x0002f8bd, 0x00001ebb, 0x0002f8be, 0x00001ebc, 0x0002f8bf, 0x00001ebd, 0x0002f8c0, 0x00001ebe, 0x0002f8c1, 0x00001ebf, 0x0002f8c2, 0x00001ec0, 0x0002f8c3, 0x00001ec1, 0x0002f8c4, 0x00001ec2, 0x0002f8c5, 0x00001ec3, 0x0002f8c6, 0x00001ec4, 0x0002f8c7, 0x00001ec5, 0x0002f8c8, 0x00001ec6, 0x0002f8c9, 0x00001ec7, 0x0002f8ca, 0x00001ec8, 0x0002f8cb, 0x00001ec9, 0x0002f8cc, 0x00001eca, 0x0002f8cd, 0x00001ecb, 0x0002f8ce, 0x00001ecc, 0x0002f8cf, 0x00001ecd, 0x0002f8d0, 0x00001ece, 0x0002f8d1, 0x00001ecf, 0x0002f8d2, 0x00001ed0, 0x0002f8d3, 0x00001ed1, 0x0002f8d4, 0x00001ed2, 0x0002f8d5, 0x00001ed3, 0x0002f8d6, 0x00001ed4, 0x0002f8d7, 0x00001ed5, 0x0002f8d8, 0x00001ed6, 0x0002f8d9, 0x00001ed7, 0x0002f8da, 0x00001ed8, 0x0002f8db, 0x00001ed9, 0x0002f8dc, 0x00001eda, 0x0002f8dd, 0x00001edb, 0x0002f8de, 0x00001edc, 0x0002f8df, 0x00001edd, 0x0002f8e0, 0x00001ede, 0x0002f8e1, 0x00001edf, 0x0002f8e2, 0x00001ee0, 0x0002f8e3, 0x00001ee1, 0x0002f8e4, 0x00001ee2, 0x0002f8e5, 0x00001ee3, 0x0002f8e6, 0x00001ee4, 0x0002f8e7, 0x00001ee5, 0x0002f8e8, 0x00001ee6, 0x0002f8e9, 0x00001ee7, 0x0002f8ea, 0x00001ee8, 0x0002f8eb, 0x00001ee9, 0x0002f8ec, 0x00001eea, 0x0002f8ed, 0x00001eeb, 0x0002f8ee, 0x00001eec, 0x0002f8ef, 0x00001eed, 0x0002f8f0, 0x00001eee, 0x0002f8f1, 0x00001eef, 0x0002f8f2, 0x00001ef0, 0x0002f8f3, 0x00001ef1, 0x0002f8f4, 0x00001ef2, 0x0002f8f5, 0x00001ef3, 0x0002f8f6, 0x00001ef4, 0x0002f8f7, 0x00001ef5, 0x0002f8f8, 0x00001ef6, 0x0002f8f9, 0x00001ef7, 0x0002f8fa, 0x00001ef8, 0x0002f8fb, 0x00001ef9, 0x0002f8fc, 0x00001efa, 0x0002f8fd, 0x00001efb, 0x0002f8fe, 0x00001efc, 0x0002f8ff, 0x00001efd, 0x0002f900, 0x00001efe, 0x0002f901, 0x00001eff, 0x0002f902, 0x00001f00, 0x0002f903, 0x00001f01, 0x0002f904, 0x00001f02, 0x0002f905, 0x00001f03, 0x0002f906, 0x00001f04, 0x0002f907, 0x00001f05, 0x0002f908, 0x00001f06, 0x0002f909, 0x00001f07, 0x0002f90a, 0x00001f08, 0x0002f90b, 0x00001f09, 0x0002f90c, 0x00001f0a, 0x0002f90d, 0x00001f0b, 0x0002f90e, 0x00001f0c, 0x0002f90f, 0x00001f0d, 0x0002f910, 0x00001f0e, 0x0002f911, 0x00001f0f, 0x0002f912, 0x00001f10, 0x0002f913, 0x00001f11, 0x0002f914, 0x00001f12, 0x0002f915, 0x00001f13, 0x0002f916, 0x00001f14, 0x0002f917, 0x00001f15, 0x0002f918, 0x00001f16, 0x0002f919, 0x00001f17, 0x0002f91a, 0x00001f18, 0x0002f91b, 0x00001f19, 0x0002f91c, 0x00001f1a, 0x0002f91d, 0x00001f1b, 0x0002f91e, 0x00001f1c, 0x0002f91f, 0x00001f1d, 0x0002f920, 0x00001f1e, 0x0002f921, 0x00001f1f, 0x0002f922, 0x00001f20, 0x0002f923, 0x00001f21, 0x0002f924, 0x00001f22, 0x0002f925, 0x00001f23, 0x0002f926, 0x00001f24, 0x0002f927, 0x00001f25, 0x0002f928, 0x00001f26, 0x0002f929, 0x00001f27, 0x0002f92a, 0x00001f28, 0x0002f92b, 0x00001f29, 0x0002f92c, 0x00001f2a, 0x0002f92d, 0x00001f2b, 0x0002f92e, 0x00001f2c, 0x0002f92f, 0x00001f2d, 0x0002f930, 0x00001f2e, 0x0002f931, 0x00001f2f, 0x0002f932, 0x00001f30, 0x0002f933, 0x00001f31, 0x0002f934, 0x00001f32, 0x0002f935, 0x00001f33, 0x0002f936, 0x00001f34, 0x0002f937, 0x00001f35, 0x0002f938, 0x00001f36, 0x0002f939, 0x00001f37, 0x0002f93a, 0x00001f38, 0x0002f93b, 0x00001f39, 0x0002f93c, 0x00001f3a, 0x0002f93d, 0x00001f3b, 0x0002f93e, 0x00001f3c, 0x0002f93f, 0x00001f3d, 0x0002f940, 0x00001f3e, 0x0002f941, 0x00001f3f, 0x0002f942, 0x00001f40, 0x0002f943, 0x00001f41, 0x0002f944, 0x00001f42, 0x0002f945, 0x00001f43, 0x0002f946, 0x00001f44, 0x0002f947, 0x00001f45, 0x0002f948, 0x00001f46, 0x0002f949, 0x00001f47, 0x0002f94a, 0x00001f48, 0x0002f94b, 0x00001f49, 0x0002f94c, 0x00001f4a, 0x0002f94d, 0x00001f4b, 0x0002f94e, 0x00001f4c, 0x0002f94f, 0x00001f4d, 0x0002f950, 0x00001f4e, 0x0002f951, 0x00001f4f, 0x0002f952, 0x00001f50, 0x0002f953, 0x00001f51, 0x0002f954, 0x00001f52, 0x0002f955, 0x00001f53, 0x0002f956, 0x00001f54, 0x0002f957, 0x00001f55, 0x0002f958, 0x00001f56, 0x0002f959, 0x00001f57, 0x0002f95a, 0x00001f58, 0x0002f95b, 0x00001f59, 0x0002f95c, 0x00001f5a, 0x0002f95d, 0x00001f5b, 0x0002f95e, 0x00001f5c, 0x0002f95f, 0x00001f5d, 0x0002f960, 0x00001f5e, 0x0002f961, 0x00001f5f, 0x0002f962, 0x00001f60, 0x0002f963, 0x00001f61, 0x0002f964, 0x00001f62, 0x0002f965, 0x00001f63, 0x0002f966, 0x00001f64, 0x0002f967, 0x00001f65, 0x0002f968, 0x00001f66, 0x0002f969, 0x00001f67, 0x0002f96a, 0x00001f68, 0x0002f96b, 0x00001f69, 0x0002f96c, 0x00001f6a, 0x0002f96d, 0x00001f6b, 0x0002f96e, 0x00001f6c, 0x0002f96f, 0x00001f6d, 0x0002f970, 0x00001f6e, 0x0002f971, 0x00001f6f, 0x0002f972, 0x00001f70, 0x0002f973, 0x00001f71, 0x0002f974, 0x00001f72, 0x0002f975, 0x00001f73, 0x0002f976, 0x00001f74, 0x0002f977, 0x00001f75, 0x0002f978, 0x00001f76, 0x0002f979, 0x00001f77, 0x0002f97a, 0x00001f78, 0x0002f97b, 0x00001f79, 0x0002f97c, 0x00001f7a, 0x0002f97d, 0x00001f7b, 0x0002f97e, 0x00001f7c, 0x0002f97f, 0x00001f7d, 0x0002f980, 0x00001f7e, 0x0002f981, 0x00001f7f, 0x0002f982, 0x00001f80, 0x0002f983, 0x00001f81, 0x0002f984, 0x00001f82, 0x0002f985, 0x00001f83, 0x0002f986, 0x00001f84, 0x0002f987, 0x00001f85, 0x0002f988, 0x00001f86, 0x0002f989, 0x00001f87, 0x0002f98a, 0x00001f88, 0x0002f98b, 0x00001f89, 0x0002f98c, 0x00001f8a, 0x0002f98d, 0x00001f8b, 0x0002f98e, 0x00001f8c, 0x0002f98f, 0x00001f8d, 0x0002f990, 0x00001f8e, 0x0002f991, 0x00001f8f, 0x0002f992, 0x00001f90, 0x0002f993, 0x00001f91, 0x0002f994, 0x00001f92, 0x0002f995, 0x00001f93, 0x0002f996, 0x00001f94, 0x0002f997, 0x00001f95, 0x0002f998, 0x00001f96, 0x0002f999, 0x00001f97, 0x0002f99a, 0x00001f98, 0x0002f99b, 0x00001f99, 0x0002f99c, 0x00001f9a, 0x0002f99d, 0x00001f9b, 0x0002f99e, 0x00001f9c, 0x0002f99f, 0x00001f9d, 0x0002f9a0, 0x00001f9e, 0x0002f9a1, 0x00001f9f, 0x0002f9a2, 0x00001fa0, 0x0002f9a3, 0x00001fa1, 0x0002f9a4, 0x00001fa2, 0x0002f9a5, 0x00001fa3, 0x0002f9a6, 0x00001fa4, 0x0002f9a7, 0x00001fa5, 0x0002f9a8, 0x00001fa6, 0x0002f9a9, 0x00001fa7, 0x0002f9aa, 0x00001fa8, 0x0002f9ab, 0x00001fa9, 0x0002f9ac, 0x00001faa, 0x0002f9ad, 0x00001fab, 0x0002f9ae, 0x00001fac, 0x0002f9af, 0x00001fad, 0x0002f9b0, 0x00001fae, 0x0002f9b1, 0x00001faf, 0x0002f9b2, 0x00001fb0, 0x0002f9b3, 0x00001fb1, 0x0002f9b4, 0x00001fb2, 0x0002f9b5, 0x00001fb3, 0x0002f9b6, 0x00001fb4, 0x0002f9b7, 0x00001fb5, 0x0002f9b8, 0x00001fb6, 0x0002f9b9, 0x00001fb7, 0x0002f9ba, 0x00001fb8, 0x0002f9bb, 0x00001fb9, 0x0002f9bc, 0x00001fba, 0x0002f9bd, 0x00001fbb, 0x0002f9be, 0x00001fbc, 0x0002f9bf, 0x00001fbd, 0x0002f9c0, 0x00001fbe, 0x0002f9c1, 0x00001fbf, 0x0002f9c2, 0x00001fc0, 0x0002f9c3, 0x00001fc1, 0x0002f9c4, 0x00001fc2, 0x0002f9c5, 0x00001fc3, 0x0002f9c6, 0x00001fc4, 0x0002f9c7, 0x00001fc5, 0x0002f9c8, 0x00001fc6, 0x0002f9c9, 0x00001fc7, 0x0002f9ca, 0x00001fc8, 0x0002f9cb, 0x00001fc9, 0x0002f9cc, 0x00001fca, 0x0002f9cd, 0x00001fcb, 0x0002f9ce, 0x00001fcc, 0x0002f9cf, 0x00001fcd, 0x0002f9d0, 0x00001fce, 0x0002f9d1, 0x00001fcf, 0x0002f9d2, 0x00001fd0, 0x0002f9d3, 0x00001fd1, 0x0002f9d4, 0x00001fd2, 0x0002f9d5, 0x00001fd3, 0x0002f9d6, 0x00001fd4, 0x0002f9d7, 0x00001fd5, 0x0002f9d8, 0x00001fd6, 0x0002f9d9, 0x00001fd7, 0x0002f9da, 0x00001fd8, 0x0002f9db, 0x00001fd9, 0x0002f9dc, 0x00001fda, 0x0002f9dd, 0x00001fdb, 0x0002f9de, 0x00001fdc, 0x0002f9df, 0x00001fdd, 0x0002f9e0, 0x00001fde, 0x0002f9e1, 0x00001fdf, 0x0002f9e2, 0x00001fe0, 0x0002f9e3, 0x00001fe1, 0x0002f9e4, 0x00001fe2, 0x0002f9e5, 0x00001fe3, 0x0002f9e6, 0x00001fe4, 0x0002f9e7, 0x00001fe5, 0x0002f9e8, 0x00001fe6, 0x0002f9e9, 0x00001fe7, 0x0002f9ea, 0x00001fe8, 0x0002f9eb, 0x00001fe9, 0x0002f9ec, 0x00001fea, 0x0002f9ed, 0x00001feb, 0x0002f9ee, 0x00001fec, 0x0002f9ef, 0x00001fed, 0x0002f9f0, 0x00001fee, 0x0002f9f1, 0x00001fef, 0x0002f9f2, 0x00001ff0, 0x0002f9f3, 0x00001ff1, 0x0002f9f4, 0x00001ff2, 0x0002f9f5, 0x00001ff3, 0x0002f9f6, 0x00001ff4, 0x0002f9f7, 0x00001ff5, 0x0002f9f8, 0x00001ff6, 0x0002f9f9, 0x00001ff7, 0x0002f9fa, 0x00001ff8, 0x0002f9fb, 0x00001ff9, 0x0002f9fc, 0x00001ffa, 0x0002f9fd, 0x00001ffb, 0x0002f9fe, 0x00001ffc, 0x0002f9ff, 0x00001ffd, 0x0002fa00, 0x00001ffe, 0x0002fa01, 0x00001fff, 0x0002fa02, 0x00002000, 0x0002fa03, 0x00002001, 0x0002fa04, 0x00002002, 0x0002fa05, 0x00002003, 0x0002fa06, 0x00002004, 0x0002fa07, 0x00002005, 0x0002fa08, 0x00002006, 0x0002fa09, 0x00002007, 0x0002fa0a, 0x00002008, 0x0002fa0b, 0x00002009, 0x0002fa0c, 0x0000200a, 0x0002fa0d, 0x0000200b, 0x0002fa0e, 0x0000200c, 0x0002fa0f, 0x0000200d, 0x0002fa10, 0x0000200e, 0x0002fa11, 0x0000200f, 0x0002fa12, 0x00002010, 0x0002fa13, 0x00002011, 0x0002fa14, 0x00002012, 0x0002fa15, 0x00002013, 0x0002fa16, 0x00002014, 0x0002fa17, 0x00002015, 0x0002fa18, 0x00002016, 0x0002fa19, 0x00002017, 0x0002fa1a, 0x00002018, 0x0002fa1b, 0x00002019, 0x0002fa1c, 0x0000201a, 0x0002fa1d, 0x0000201b, 0x0000201c }; static const krb5_ui_4 _uckdcmp_decomp[] = { 0x00000020, 0x00000020, 0x00000308, 0x00000061, 0x00000020, 0x00000304, 0x00000032, 0x00000033, 0x00000020, 0x00000301, 0x000003bc, 0x00000020, 0x00000327, 0x00000031, 0x0000006f, 0x00000031, 0x00002044, 0x00000034, 0x00000031, 0x00002044, 0x00000032, 0x00000033, 0x00002044, 0x00000034, 0x00000041, 0x00000300, 0x00000041, 0x00000301, 0x00000041, 0x00000302, 0x00000041, 0x00000303, 0x00000041, 0x00000308, 0x00000041, 0x0000030a, 0x00000043, 0x00000327, 0x00000045, 0x00000300, 0x00000045, 0x00000301, 0x00000045, 0x00000302, 0x00000045, 0x00000308, 0x00000049, 0x00000300, 0x00000049, 0x00000301, 0x00000049, 0x00000302, 0x00000049, 0x00000308, 0x0000004e, 0x00000303, 0x0000004f, 0x00000300, 0x0000004f, 0x00000301, 0x0000004f, 0x00000302, 0x0000004f, 0x00000303, 0x0000004f, 0x00000308, 0x00000055, 0x00000300, 0x00000055, 0x00000301, 0x00000055, 0x00000302, 0x00000055, 0x00000308, 0x00000059, 0x00000301, 0x00000061, 0x00000300, 0x00000061, 0x00000301, 0x00000061, 0x00000302, 0x00000061, 0x00000303, 0x00000061, 0x00000308, 0x00000061, 0x0000030a, 0x00000063, 0x00000327, 0x00000065, 0x00000300, 0x00000065, 0x00000301, 0x00000065, 0x00000302, 0x00000065, 0x00000308, 0x00000069, 0x00000300, 0x00000069, 0x00000301, 0x00000069, 0x00000302, 0x00000069, 0x00000308, 0x0000006e, 0x00000303, 0x0000006f, 0x00000300, 0x0000006f, 0x00000301, 0x0000006f, 0x00000302, 0x0000006f, 0x00000303, 0x0000006f, 0x00000308, 0x00000075, 0x00000300, 0x00000075, 0x00000301, 0x00000075, 0x00000302, 0x00000075, 0x00000308, 0x00000079, 0x00000301, 0x00000079, 0x00000308, 0x00000041, 0x00000304, 0x00000061, 0x00000304, 0x00000041, 0x00000306, 0x00000061, 0x00000306, 0x00000041, 0x00000328, 0x00000061, 0x00000328, 0x00000043, 0x00000301, 0x00000063, 0x00000301, 0x00000043, 0x00000302, 0x00000063, 0x00000302, 0x00000043, 0x00000307, 0x00000063, 0x00000307, 0x00000043, 0x0000030c, 0x00000063, 0x0000030c, 0x00000044, 0x0000030c, 0x00000064, 0x0000030c, 0x00000045, 0x00000304, 0x00000065, 0x00000304, 0x00000045, 0x00000306, 0x00000065, 0x00000306, 0x00000045, 0x00000307, 0x00000065, 0x00000307, 0x00000045, 0x00000328, 0x00000065, 0x00000328, 0x00000045, 0x0000030c, 0x00000065, 0x0000030c, 0x00000047, 0x00000302, 0x00000067, 0x00000302, 0x00000047, 0x00000306, 0x00000067, 0x00000306, 0x00000047, 0x00000307, 0x00000067, 0x00000307, 0x00000047, 0x00000327, 0x00000067, 0x00000327, 0x00000048, 0x00000302, 0x00000068, 0x00000302, 0x00000049, 0x00000303, 0x00000069, 0x00000303, 0x00000049, 0x00000304, 0x00000069, 0x00000304, 0x00000049, 0x00000306, 0x00000069, 0x00000306, 0x00000049, 0x00000328, 0x00000069, 0x00000328, 0x00000049, 0x00000307, 0x00000049, 0x0000004a, 0x00000069, 0x0000006a, 0x0000004a, 0x00000302, 0x0000006a, 0x00000302, 0x0000004b, 0x00000327, 0x0000006b, 0x00000327, 0x0000004c, 0x00000301, 0x0000006c, 0x00000301, 0x0000004c, 0x00000327, 0x0000006c, 0x00000327, 0x0000004c, 0x0000030c, 0x0000006c, 0x0000030c, 0x0000004c, 0x000000b7, 0x0000006c, 0x000000b7, 0x0000004e, 0x00000301, 0x0000006e, 0x00000301, 0x0000004e, 0x00000327, 0x0000006e, 0x00000327, 0x0000004e, 0x0000030c, 0x0000006e, 0x0000030c, 0x000002bc, 0x0000006e, 0x0000004f, 0x00000304, 0x0000006f, 0x00000304, 0x0000004f, 0x00000306, 0x0000006f, 0x00000306, 0x0000004f, 0x0000030b, 0x0000006f, 0x0000030b, 0x00000052, 0x00000301, 0x00000072, 0x00000301, 0x00000052, 0x00000327, 0x00000072, 0x00000327, 0x00000052, 0x0000030c, 0x00000072, 0x0000030c, 0x00000053, 0x00000301, 0x00000073, 0x00000301, 0x00000053, 0x00000302, 0x00000073, 0x00000302, 0x00000053, 0x00000327, 0x00000073, 0x00000327, 0x00000053, 0x0000030c, 0x00000073, 0x0000030c, 0x00000054, 0x00000327, 0x00000074, 0x00000327, 0x00000054, 0x0000030c, 0x00000074, 0x0000030c, 0x00000055, 0x00000303, 0x00000075, 0x00000303, 0x00000055, 0x00000304, 0x00000075, 0x00000304, 0x00000055, 0x00000306, 0x00000075, 0x00000306, 0x00000055, 0x0000030a, 0x00000075, 0x0000030a, 0x00000055, 0x0000030b, 0x00000075, 0x0000030b, 0x00000055, 0x00000328, 0x00000075, 0x00000328, 0x00000057, 0x00000302, 0x00000077, 0x00000302, 0x00000059, 0x00000302, 0x00000079, 0x00000302, 0x00000059, 0x00000308, 0x0000005a, 0x00000301, 0x0000007a, 0x00000301, 0x0000005a, 0x00000307, 0x0000007a, 0x00000307, 0x0000005a, 0x0000030c, 0x0000007a, 0x0000030c, 0x00000073, 0x0000004f, 0x0000031b, 0x0000006f, 0x0000031b, 0x00000055, 0x0000031b, 0x00000075, 0x0000031b, 0x00000044, 0x0000005a, 0x0000030c, 0x00000044, 0x0000007a, 0x0000030c, 0x00000064, 0x0000007a, 0x0000030c, 0x0000004c, 0x0000004a, 0x0000004c, 0x0000006a, 0x0000006c, 0x0000006a, 0x0000004e, 0x0000004a, 0x0000004e, 0x0000006a, 0x0000006e, 0x0000006a, 0x00000041, 0x0000030c, 0x00000061, 0x0000030c, 0x00000049, 0x0000030c, 0x00000069, 0x0000030c, 0x0000004f, 0x0000030c, 0x0000006f, 0x0000030c, 0x00000055, 0x0000030c, 0x00000075, 0x0000030c, 0x00000055, 0x00000308, 0x00000304, 0x00000075, 0x00000308, 0x00000304, 0x00000055, 0x00000308, 0x00000301, 0x00000075, 0x00000308, 0x00000301, 0x00000055, 0x00000308, 0x0000030c, 0x00000075, 0x00000308, 0x0000030c, 0x00000055, 0x00000308, 0x00000300, 0x00000075, 0x00000308, 0x00000300, 0x00000041, 0x00000308, 0x00000304, 0x00000061, 0x00000308, 0x00000304, 0x00000041, 0x00000307, 0x00000304, 0x00000061, 0x00000307, 0x00000304, 0x000000c6, 0x00000304, 0x000000e6, 0x00000304, 0x00000047, 0x0000030c, 0x00000067, 0x0000030c, 0x0000004b, 0x0000030c, 0x0000006b, 0x0000030c, 0x0000004f, 0x00000328, 0x0000006f, 0x00000328, 0x0000004f, 0x00000328, 0x00000304, 0x0000006f, 0x00000328, 0x00000304, 0x000001b7, 0x0000030c, 0x00000292, 0x0000030c, 0x0000006a, 0x0000030c, 0x00000044, 0x0000005a, 0x00000044, 0x0000007a, 0x00000064, 0x0000007a, 0x00000047, 0x00000301, 0x00000067, 0x00000301, 0x0000004e, 0x00000300, 0x0000006e, 0x00000300, 0x00000041, 0x0000030a, 0x00000301, 0x00000061, 0x0000030a, 0x00000301, 0x000000c6, 0x00000301, 0x000000e6, 0x00000301, 0x000000d8, 0x00000301, 0x000000f8, 0x00000301, 0x00000041, 0x0000030f, 0x00000061, 0x0000030f, 0x00000041, 0x00000311, 0x00000061, 0x00000311, 0x00000045, 0x0000030f, 0x00000065, 0x0000030f, 0x00000045, 0x00000311, 0x00000065, 0x00000311, 0x00000049, 0x0000030f, 0x00000069, 0x0000030f, 0x00000049, 0x00000311, 0x00000069, 0x00000311, 0x0000004f, 0x0000030f, 0x0000006f, 0x0000030f, 0x0000004f, 0x00000311, 0x0000006f, 0x00000311, 0x00000052, 0x0000030f, 0x00000072, 0x0000030f, 0x00000052, 0x00000311, 0x00000072, 0x00000311, 0x00000055, 0x0000030f, 0x00000075, 0x0000030f, 0x00000055, 0x00000311, 0x00000075, 0x00000311, 0x00000053, 0x00000326, 0x00000073, 0x00000326, 0x00000054, 0x00000326, 0x00000074, 0x00000326, 0x00000048, 0x0000030c, 0x00000068, 0x0000030c, 0x00000041, 0x00000307, 0x00000061, 0x00000307, 0x00000045, 0x00000327, 0x00000065, 0x00000327, 0x0000004f, 0x00000308, 0x00000304, 0x0000006f, 0x00000308, 0x00000304, 0x0000004f, 0x00000303, 0x00000304, 0x0000006f, 0x00000303, 0x00000304, 0x0000004f, 0x00000307, 0x0000006f, 0x00000307, 0x0000004f, 0x00000307, 0x00000304, 0x0000006f, 0x00000307, 0x00000304, 0x00000059, 0x00000304, 0x00000079, 0x00000304, 0x00000068, 0x00000266, 0x0000006a, 0x00000072, 0x00000279, 0x0000027b, 0x00000281, 0x00000077, 0x00000079, 0x00000020, 0x00000306, 0x00000020, 0x00000307, 0x00000020, 0x0000030a, 0x00000020, 0x00000328, 0x00000020, 0x00000303, 0x00000020, 0x0000030b, 0x00000263, 0x0000006c, 0x00000073, 0x00000078, 0x00000295, 0x00000300, 0x00000301, 0x00000313, 0x00000308, 0x00000301, 0x000002b9, 0x00000020, 0x00000345, 0x0000003b, 0x00000020, 0x00000301, 0x00000020, 0x00000308, 0x00000301, 0x00000391, 0x00000301, 0x000000b7, 0x00000395, 0x00000301, 0x00000397, 0x00000301, 0x00000399, 0x00000301, 0x0000039f, 0x00000301, 0x000003a5, 0x00000301, 0x000003a9, 0x00000301, 0x000003b9, 0x00000308, 0x00000301, 0x00000399, 0x00000308, 0x000003a5, 0x00000308, 0x000003b1, 0x00000301, 0x000003b5, 0x00000301, 0x000003b7, 0x00000301, 0x000003b9, 0x00000301, 0x000003c5, 0x00000308, 0x00000301, 0x000003b9, 0x00000308, 0x000003c5, 0x00000308, 0x000003bf, 0x00000301, 0x000003c5, 0x00000301, 0x000003c9, 0x00000301, 0x000003b2, 0x000003b8, 0x000003a5, 0x000003a5, 0x00000301, 0x000003a5, 0x00000308, 0x000003c6, 0x000003c0, 0x000003ba, 0x000003c1, 0x000003c2, 0x00000398, 0x000003b5, 0x00000415, 0x00000300, 0x00000415, 0x00000308, 0x00000413, 0x00000301, 0x00000406, 0x00000308, 0x0000041a, 0x00000301, 0x00000418, 0x00000300, 0x00000423, 0x00000306, 0x00000418, 0x00000306, 0x00000438, 0x00000306, 0x00000435, 0x00000300, 0x00000435, 0x00000308, 0x00000433, 0x00000301, 0x00000456, 0x00000308, 0x0000043a, 0x00000301, 0x00000438, 0x00000300, 0x00000443, 0x00000306, 0x00000474, 0x0000030f, 0x00000475, 0x0000030f, 0x00000416, 0x00000306, 0x00000436, 0x00000306, 0x00000410, 0x00000306, 0x00000430, 0x00000306, 0x00000410, 0x00000308, 0x00000430, 0x00000308, 0x00000415, 0x00000306, 0x00000435, 0x00000306, 0x000004d8, 0x00000308, 0x000004d9, 0x00000308, 0x00000416, 0x00000308, 0x00000436, 0x00000308, 0x00000417, 0x00000308, 0x00000437, 0x00000308, 0x00000418, 0x00000304, 0x00000438, 0x00000304, 0x00000418, 0x00000308, 0x00000438, 0x00000308, 0x0000041e, 0x00000308, 0x0000043e, 0x00000308, 0x000004e8, 0x00000308, 0x000004e9, 0x00000308, 0x0000042d, 0x00000308, 0x0000044d, 0x00000308, 0x00000423, 0x00000304, 0x00000443, 0x00000304, 0x00000423, 0x00000308, 0x00000443, 0x00000308, 0x00000423, 0x0000030b, 0x00000443, 0x0000030b, 0x00000427, 0x00000308, 0x00000447, 0x00000308, 0x0000042b, 0x00000308, 0x0000044b, 0x00000308, 0x00000565, 0x00000582, 0x00000627, 0x00000653, 0x00000627, 0x00000654, 0x00000648, 0x00000654, 0x00000627, 0x00000655, 0x0000064a, 0x00000654, 0x00000627, 0x00000674, 0x00000648, 0x00000674, 0x000006c7, 0x00000674, 0x0000064a, 0x00000674, 0x000006d5, 0x00000654, 0x000006c1, 0x00000654, 0x000006d2, 0x00000654, 0x00000928, 0x0000093c, 0x00000930, 0x0000093c, 0x00000933, 0x0000093c, 0x00000915, 0x0000093c, 0x00000916, 0x0000093c, 0x00000917, 0x0000093c, 0x0000091c, 0x0000093c, 0x00000921, 0x0000093c, 0x00000922, 0x0000093c, 0x0000092b, 0x0000093c, 0x0000092f, 0x0000093c, 0x000009c7, 0x000009be, 0x000009c7, 0x000009d7, 0x000009a1, 0x000009bc, 0x000009a2, 0x000009bc, 0x000009af, 0x000009bc, 0x00000a32, 0x00000a3c, 0x00000a38, 0x00000a3c, 0x00000a16, 0x00000a3c, 0x00000a17, 0x00000a3c, 0x00000a1c, 0x00000a3c, 0x00000a2b, 0x00000a3c, 0x00000b47, 0x00000b56, 0x00000b47, 0x00000b3e, 0x00000b47, 0x00000b57, 0x00000b21, 0x00000b3c, 0x00000b22, 0x00000b3c, 0x00000b92, 0x00000bd7, 0x00000bc6, 0x00000bbe, 0x00000bc7, 0x00000bbe, 0x00000bc6, 0x00000bd7, 0x00000c46, 0x00000c56, 0x00000cbf, 0x00000cd5, 0x00000cc6, 0x00000cd5, 0x00000cc6, 0x00000cd6, 0x00000cc6, 0x00000cc2, 0x00000cc6, 0x00000cc2, 0x00000cd5, 0x00000d46, 0x00000d3e, 0x00000d47, 0x00000d3e, 0x00000d46, 0x00000d57, 0x00000dd9, 0x00000dca, 0x00000dd9, 0x00000dcf, 0x00000dd9, 0x00000dcf, 0x00000dca, 0x00000dd9, 0x00000ddf, 0x00000e4d, 0x00000e32, 0x00000ecd, 0x00000eb2, 0x00000eab, 0x00000e99, 0x00000eab, 0x00000ea1, 0x00000f0b, 0x00000f42, 0x00000fb7, 0x00000f4c, 0x00000fb7, 0x00000f51, 0x00000fb7, 0x00000f56, 0x00000fb7, 0x00000f5b, 0x00000fb7, 0x00000f40, 0x00000fb5, 0x00000f71, 0x00000f72, 0x00000f71, 0x00000f74, 0x00000fb2, 0x00000f80, 0x00000fb2, 0x00000f71, 0x00000f80, 0x00000fb3, 0x00000f80, 0x00000fb3, 0x00000f71, 0x00000f80, 0x00000f71, 0x00000f80, 0x00000f92, 0x00000fb7, 0x00000f9c, 0x00000fb7, 0x00000fa1, 0x00000fb7, 0x00000fa6, 0x00000fb7, 0x00000fab, 0x00000fb7, 0x00000f90, 0x00000fb5, 0x00001025, 0x0000102e, 0x00000041, 0x00000325, 0x00000061, 0x00000325, 0x00000042, 0x00000307, 0x00000062, 0x00000307, 0x00000042, 0x00000323, 0x00000062, 0x00000323, 0x00000042, 0x00000331, 0x00000062, 0x00000331, 0x00000043, 0x00000327, 0x00000301, 0x00000063, 0x00000327, 0x00000301, 0x00000044, 0x00000307, 0x00000064, 0x00000307, 0x00000044, 0x00000323, 0x00000064, 0x00000323, 0x00000044, 0x00000331, 0x00000064, 0x00000331, 0x00000044, 0x00000327, 0x00000064, 0x00000327, 0x00000044, 0x0000032d, 0x00000064, 0x0000032d, 0x00000045, 0x00000304, 0x00000300, 0x00000065, 0x00000304, 0x00000300, 0x00000045, 0x00000304, 0x00000301, 0x00000065, 0x00000304, 0x00000301, 0x00000045, 0x0000032d, 0x00000065, 0x0000032d, 0x00000045, 0x00000330, 0x00000065, 0x00000330, 0x00000045, 0x00000327, 0x00000306, 0x00000065, 0x00000327, 0x00000306, 0x00000046, 0x00000307, 0x00000066, 0x00000307, 0x00000047, 0x00000304, 0x00000067, 0x00000304, 0x00000048, 0x00000307, 0x00000068, 0x00000307, 0x00000048, 0x00000323, 0x00000068, 0x00000323, 0x00000048, 0x00000308, 0x00000068, 0x00000308, 0x00000048, 0x00000327, 0x00000068, 0x00000327, 0x00000048, 0x0000032e, 0x00000068, 0x0000032e, 0x00000049, 0x00000330, 0x00000069, 0x00000330, 0x00000049, 0x00000308, 0x00000301, 0x00000069, 0x00000308, 0x00000301, 0x0000004b, 0x00000301, 0x0000006b, 0x00000301, 0x0000004b, 0x00000323, 0x0000006b, 0x00000323, 0x0000004b, 0x00000331, 0x0000006b, 0x00000331, 0x0000004c, 0x00000323, 0x0000006c, 0x00000323, 0x0000004c, 0x00000323, 0x00000304, 0x0000006c, 0x00000323, 0x00000304, 0x0000004c, 0x00000331, 0x0000006c, 0x00000331, 0x0000004c, 0x0000032d, 0x0000006c, 0x0000032d, 0x0000004d, 0x00000301, 0x0000006d, 0x00000301, 0x0000004d, 0x00000307, 0x0000006d, 0x00000307, 0x0000004d, 0x00000323, 0x0000006d, 0x00000323, 0x0000004e, 0x00000307, 0x0000006e, 0x00000307, 0x0000004e, 0x00000323, 0x0000006e, 0x00000323, 0x0000004e, 0x00000331, 0x0000006e, 0x00000331, 0x0000004e, 0x0000032d, 0x0000006e, 0x0000032d, 0x0000004f, 0x00000303, 0x00000301, 0x0000006f, 0x00000303, 0x00000301, 0x0000004f, 0x00000303, 0x00000308, 0x0000006f, 0x00000303, 0x00000308, 0x0000004f, 0x00000304, 0x00000300, 0x0000006f, 0x00000304, 0x00000300, 0x0000004f, 0x00000304, 0x00000301, 0x0000006f, 0x00000304, 0x00000301, 0x00000050, 0x00000301, 0x00000070, 0x00000301, 0x00000050, 0x00000307, 0x00000070, 0x00000307, 0x00000052, 0x00000307, 0x00000072, 0x00000307, 0x00000052, 0x00000323, 0x00000072, 0x00000323, 0x00000052, 0x00000323, 0x00000304, 0x00000072, 0x00000323, 0x00000304, 0x00000052, 0x00000331, 0x00000072, 0x00000331, 0x00000053, 0x00000307, 0x00000073, 0x00000307, 0x00000053, 0x00000323, 0x00000073, 0x00000323, 0x00000053, 0x00000301, 0x00000307, 0x00000073, 0x00000301, 0x00000307, 0x00000053, 0x0000030c, 0x00000307, 0x00000073, 0x0000030c, 0x00000307, 0x00000053, 0x00000323, 0x00000307, 0x00000073, 0x00000323, 0x00000307, 0x00000054, 0x00000307, 0x00000074, 0x00000307, 0x00000054, 0x00000323, 0x00000074, 0x00000323, 0x00000054, 0x00000331, 0x00000074, 0x00000331, 0x00000054, 0x0000032d, 0x00000074, 0x0000032d, 0x00000055, 0x00000324, 0x00000075, 0x00000324, 0x00000055, 0x00000330, 0x00000075, 0x00000330, 0x00000055, 0x0000032d, 0x00000075, 0x0000032d, 0x00000055, 0x00000303, 0x00000301, 0x00000075, 0x00000303, 0x00000301, 0x00000055, 0x00000304, 0x00000308, 0x00000075, 0x00000304, 0x00000308, 0x00000056, 0x00000303, 0x00000076, 0x00000303, 0x00000056, 0x00000323, 0x00000076, 0x00000323, 0x00000057, 0x00000300, 0x00000077, 0x00000300, 0x00000057, 0x00000301, 0x00000077, 0x00000301, 0x00000057, 0x00000308, 0x00000077, 0x00000308, 0x00000057, 0x00000307, 0x00000077, 0x00000307, 0x00000057, 0x00000323, 0x00000077, 0x00000323, 0x00000058, 0x00000307, 0x00000078, 0x00000307, 0x00000058, 0x00000308, 0x00000078, 0x00000308, 0x00000059, 0x00000307, 0x00000079, 0x00000307, 0x0000005a, 0x00000302, 0x0000007a, 0x00000302, 0x0000005a, 0x00000323, 0x0000007a, 0x00000323, 0x0000005a, 0x00000331, 0x0000007a, 0x00000331, 0x00000068, 0x00000331, 0x00000074, 0x00000308, 0x00000077, 0x0000030a, 0x00000079, 0x0000030a, 0x00000061, 0x000002be, 0x00000073, 0x00000307, 0x00000041, 0x00000323, 0x00000061, 0x00000323, 0x00000041, 0x00000309, 0x00000061, 0x00000309, 0x00000041, 0x00000302, 0x00000301, 0x00000061, 0x00000302, 0x00000301, 0x00000041, 0x00000302, 0x00000300, 0x00000061, 0x00000302, 0x00000300, 0x00000041, 0x00000302, 0x00000309, 0x00000061, 0x00000302, 0x00000309, 0x00000041, 0x00000302, 0x00000303, 0x00000061, 0x00000302, 0x00000303, 0x00000041, 0x00000323, 0x00000302, 0x00000061, 0x00000323, 0x00000302, 0x00000041, 0x00000306, 0x00000301, 0x00000061, 0x00000306, 0x00000301, 0x00000041, 0x00000306, 0x00000300, 0x00000061, 0x00000306, 0x00000300, 0x00000041, 0x00000306, 0x00000309, 0x00000061, 0x00000306, 0x00000309, 0x00000041, 0x00000306, 0x00000303, 0x00000061, 0x00000306, 0x00000303, 0x00000041, 0x00000323, 0x00000306, 0x00000061, 0x00000323, 0x00000306, 0x00000045, 0x00000323, 0x00000065, 0x00000323, 0x00000045, 0x00000309, 0x00000065, 0x00000309, 0x00000045, 0x00000303, 0x00000065, 0x00000303, 0x00000045, 0x00000302, 0x00000301, 0x00000065, 0x00000302, 0x00000301, 0x00000045, 0x00000302, 0x00000300, 0x00000065, 0x00000302, 0x00000300, 0x00000045, 0x00000302, 0x00000309, 0x00000065, 0x00000302, 0x00000309, 0x00000045, 0x00000302, 0x00000303, 0x00000065, 0x00000302, 0x00000303, 0x00000045, 0x00000323, 0x00000302, 0x00000065, 0x00000323, 0x00000302, 0x00000049, 0x00000309, 0x00000069, 0x00000309, 0x00000049, 0x00000323, 0x00000069, 0x00000323, 0x0000004f, 0x00000323, 0x0000006f, 0x00000323, 0x0000004f, 0x00000309, 0x0000006f, 0x00000309, 0x0000004f, 0x00000302, 0x00000301, 0x0000006f, 0x00000302, 0x00000301, 0x0000004f, 0x00000302, 0x00000300, 0x0000006f, 0x00000302, 0x00000300, 0x0000004f, 0x00000302, 0x00000309, 0x0000006f, 0x00000302, 0x00000309, 0x0000004f, 0x00000302, 0x00000303, 0x0000006f, 0x00000302, 0x00000303, 0x0000004f, 0x00000323, 0x00000302, 0x0000006f, 0x00000323, 0x00000302, 0x0000004f, 0x0000031b, 0x00000301, 0x0000006f, 0x0000031b, 0x00000301, 0x0000004f, 0x0000031b, 0x00000300, 0x0000006f, 0x0000031b, 0x00000300, 0x0000004f, 0x0000031b, 0x00000309, 0x0000006f, 0x0000031b, 0x00000309, 0x0000004f, 0x0000031b, 0x00000303, 0x0000006f, 0x0000031b, 0x00000303, 0x0000004f, 0x0000031b, 0x00000323, 0x0000006f, 0x0000031b, 0x00000323, 0x00000055, 0x00000323, 0x00000075, 0x00000323, 0x00000055, 0x00000309, 0x00000075, 0x00000309, 0x00000055, 0x0000031b, 0x00000301, 0x00000075, 0x0000031b, 0x00000301, 0x00000055, 0x0000031b, 0x00000300, 0x00000075, 0x0000031b, 0x00000300, 0x00000055, 0x0000031b, 0x00000309, 0x00000075, 0x0000031b, 0x00000309, 0x00000055, 0x0000031b, 0x00000303, 0x00000075, 0x0000031b, 0x00000303, 0x00000055, 0x0000031b, 0x00000323, 0x00000075, 0x0000031b, 0x00000323, 0x00000059, 0x00000300, 0x00000079, 0x00000300, 0x00000059, 0x00000323, 0x00000079, 0x00000323, 0x00000059, 0x00000309, 0x00000079, 0x00000309, 0x00000059, 0x00000303, 0x00000079, 0x00000303, 0x000003b1, 0x00000313, 0x000003b1, 0x00000314, 0x000003b1, 0x00000313, 0x00000300, 0x000003b1, 0x00000314, 0x00000300, 0x000003b1, 0x00000313, 0x00000301, 0x000003b1, 0x00000314, 0x00000301, 0x000003b1, 0x00000313, 0x00000342, 0x000003b1, 0x00000314, 0x00000342, 0x00000391, 0x00000313, 0x00000391, 0x00000314, 0x00000391, 0x00000313, 0x00000300, 0x00000391, 0x00000314, 0x00000300, 0x00000391, 0x00000313, 0x00000301, 0x00000391, 0x00000314, 0x00000301, 0x00000391, 0x00000313, 0x00000342, 0x00000391, 0x00000314, 0x00000342, 0x000003b5, 0x00000313, 0x000003b5, 0x00000314, 0x000003b5, 0x00000313, 0x00000300, 0x000003b5, 0x00000314, 0x00000300, 0x000003b5, 0x00000313, 0x00000301, 0x000003b5, 0x00000314, 0x00000301, 0x00000395, 0x00000313, 0x00000395, 0x00000314, 0x00000395, 0x00000313, 0x00000300, 0x00000395, 0x00000314, 0x00000300, 0x00000395, 0x00000313, 0x00000301, 0x00000395, 0x00000314, 0x00000301, 0x000003b7, 0x00000313, 0x000003b7, 0x00000314, 0x000003b7, 0x00000313, 0x00000300, 0x000003b7, 0x00000314, 0x00000300, 0x000003b7, 0x00000313, 0x00000301, 0x000003b7, 0x00000314, 0x00000301, 0x000003b7, 0x00000313, 0x00000342, 0x000003b7, 0x00000314, 0x00000342, 0x00000397, 0x00000313, 0x00000397, 0x00000314, 0x00000397, 0x00000313, 0x00000300, 0x00000397, 0x00000314, 0x00000300, 0x00000397, 0x00000313, 0x00000301, 0x00000397, 0x00000314, 0x00000301, 0x00000397, 0x00000313, 0x00000342, 0x00000397, 0x00000314, 0x00000342, 0x000003b9, 0x00000313, 0x000003b9, 0x00000314, 0x000003b9, 0x00000313, 0x00000300, 0x000003b9, 0x00000314, 0x00000300, 0x000003b9, 0x00000313, 0x00000301, 0x000003b9, 0x00000314, 0x00000301, 0x000003b9, 0x00000313, 0x00000342, 0x000003b9, 0x00000314, 0x00000342, 0x00000399, 0x00000313, 0x00000399, 0x00000314, 0x00000399, 0x00000313, 0x00000300, 0x00000399, 0x00000314, 0x00000300, 0x00000399, 0x00000313, 0x00000301, 0x00000399, 0x00000314, 0x00000301, 0x00000399, 0x00000313, 0x00000342, 0x00000399, 0x00000314, 0x00000342, 0x000003bf, 0x00000313, 0x000003bf, 0x00000314, 0x000003bf, 0x00000313, 0x00000300, 0x000003bf, 0x00000314, 0x00000300, 0x000003bf, 0x00000313, 0x00000301, 0x000003bf, 0x00000314, 0x00000301, 0x0000039f, 0x00000313, 0x0000039f, 0x00000314, 0x0000039f, 0x00000313, 0x00000300, 0x0000039f, 0x00000314, 0x00000300, 0x0000039f, 0x00000313, 0x00000301, 0x0000039f, 0x00000314, 0x00000301, 0x000003c5, 0x00000313, 0x000003c5, 0x00000314, 0x000003c5, 0x00000313, 0x00000300, 0x000003c5, 0x00000314, 0x00000300, 0x000003c5, 0x00000313, 0x00000301, 0x000003c5, 0x00000314, 0x00000301, 0x000003c5, 0x00000313, 0x00000342, 0x000003c5, 0x00000314, 0x00000342, 0x000003a5, 0x00000314, 0x000003a5, 0x00000314, 0x00000300, 0x000003a5, 0x00000314, 0x00000301, 0x000003a5, 0x00000314, 0x00000342, 0x000003c9, 0x00000313, 0x000003c9, 0x00000314, 0x000003c9, 0x00000313, 0x00000300, 0x000003c9, 0x00000314, 0x00000300, 0x000003c9, 0x00000313, 0x00000301, 0x000003c9, 0x00000314, 0x00000301, 0x000003c9, 0x00000313, 0x00000342, 0x000003c9, 0x00000314, 0x00000342, 0x000003a9, 0x00000313, 0x000003a9, 0x00000314, 0x000003a9, 0x00000313, 0x00000300, 0x000003a9, 0x00000314, 0x00000300, 0x000003a9, 0x00000313, 0x00000301, 0x000003a9, 0x00000314, 0x00000301, 0x000003a9, 0x00000313, 0x00000342, 0x000003a9, 0x00000314, 0x00000342, 0x000003b1, 0x00000300, 0x000003b1, 0x00000301, 0x000003b5, 0x00000300, 0x000003b5, 0x00000301, 0x000003b7, 0x00000300, 0x000003b7, 0x00000301, 0x000003b9, 0x00000300, 0x000003b9, 0x00000301, 0x000003bf, 0x00000300, 0x000003bf, 0x00000301, 0x000003c5, 0x00000300, 0x000003c5, 0x00000301, 0x000003c9, 0x00000300, 0x000003c9, 0x00000301, 0x000003b1, 0x00000313, 0x00000345, 0x000003b1, 0x00000314, 0x00000345, 0x000003b1, 0x00000313, 0x00000300, 0x00000345, 0x000003b1, 0x00000314, 0x00000300, 0x00000345, 0x000003b1, 0x00000313, 0x00000301, 0x00000345, 0x000003b1, 0x00000314, 0x00000301, 0x00000345, 0x000003b1, 0x00000313, 0x00000342, 0x00000345, 0x000003b1, 0x00000314, 0x00000342, 0x00000345, 0x00000391, 0x00000313, 0x00000345, 0x00000391, 0x00000314, 0x00000345, 0x00000391, 0x00000313, 0x00000300, 0x00000345, 0x00000391, 0x00000314, 0x00000300, 0x00000345, 0x00000391, 0x00000313, 0x00000301, 0x00000345, 0x00000391, 0x00000314, 0x00000301, 0x00000345, 0x00000391, 0x00000313, 0x00000342, 0x00000345, 0x00000391, 0x00000314, 0x00000342, 0x00000345, 0x000003b7, 0x00000313, 0x00000345, 0x000003b7, 0x00000314, 0x00000345, 0x000003b7, 0x00000313, 0x00000300, 0x00000345, 0x000003b7, 0x00000314, 0x00000300, 0x00000345, 0x000003b7, 0x00000313, 0x00000301, 0x00000345, 0x000003b7, 0x00000314, 0x00000301, 0x00000345, 0x000003b7, 0x00000313, 0x00000342, 0x00000345, 0x000003b7, 0x00000314, 0x00000342, 0x00000345, 0x00000397, 0x00000313, 0x00000345, 0x00000397, 0x00000314, 0x00000345, 0x00000397, 0x00000313, 0x00000300, 0x00000345, 0x00000397, 0x00000314, 0x00000300, 0x00000345, 0x00000397, 0x00000313, 0x00000301, 0x00000345, 0x00000397, 0x00000314, 0x00000301, 0x00000345, 0x00000397, 0x00000313, 0x00000342, 0x00000345, 0x00000397, 0x00000314, 0x00000342, 0x00000345, 0x000003c9, 0x00000313, 0x00000345, 0x000003c9, 0x00000314, 0x00000345, 0x000003c9, 0x00000313, 0x00000300, 0x00000345, 0x000003c9, 0x00000314, 0x00000300, 0x00000345, 0x000003c9, 0x00000313, 0x00000301, 0x00000345, 0x000003c9, 0x00000314, 0x00000301, 0x00000345, 0x000003c9, 0x00000313, 0x00000342, 0x00000345, 0x000003c9, 0x00000314, 0x00000342, 0x00000345, 0x000003a9, 0x00000313, 0x00000345, 0x000003a9, 0x00000314, 0x00000345, 0x000003a9, 0x00000313, 0x00000300, 0x00000345, 0x000003a9, 0x00000314, 0x00000300, 0x00000345, 0x000003a9, 0x00000313, 0x00000301, 0x00000345, 0x000003a9, 0x00000314, 0x00000301, 0x00000345, 0x000003a9, 0x00000313, 0x00000342, 0x00000345, 0x000003a9, 0x00000314, 0x00000342, 0x00000345, 0x000003b1, 0x00000306, 0x000003b1, 0x00000304, 0x000003b1, 0x00000300, 0x00000345, 0x000003b1, 0x00000345, 0x000003b1, 0x00000301, 0x00000345, 0x000003b1, 0x00000342, 0x000003b1, 0x00000342, 0x00000345, 0x00000391, 0x00000306, 0x00000391, 0x00000304, 0x00000391, 0x00000300, 0x00000391, 0x00000301, 0x00000391, 0x00000345, 0x00000020, 0x00000313, 0x000003b9, 0x00000020, 0x00000313, 0x00000020, 0x00000342, 0x00000020, 0x00000308, 0x00000342, 0x000003b7, 0x00000300, 0x00000345, 0x000003b7, 0x00000345, 0x000003b7, 0x00000301, 0x00000345, 0x000003b7, 0x00000342, 0x000003b7, 0x00000342, 0x00000345, 0x00000395, 0x00000300, 0x00000395, 0x00000301, 0x00000397, 0x00000300, 0x00000397, 0x00000301, 0x00000397, 0x00000345, 0x00000020, 0x00000313, 0x00000300, 0x00000020, 0x00000313, 0x00000301, 0x00000020, 0x00000313, 0x00000342, 0x000003b9, 0x00000306, 0x000003b9, 0x00000304, 0x000003b9, 0x00000308, 0x00000300, 0x000003b9, 0x00000308, 0x00000301, 0x000003b9, 0x00000342, 0x000003b9, 0x00000308, 0x00000342, 0x00000399, 0x00000306, 0x00000399, 0x00000304, 0x00000399, 0x00000300, 0x00000399, 0x00000301, 0x00000020, 0x00000314, 0x00000300, 0x00000020, 0x00000314, 0x00000301, 0x00000020, 0x00000314, 0x00000342, 0x000003c5, 0x00000306, 0x000003c5, 0x00000304, 0x000003c5, 0x00000308, 0x00000300, 0x000003c5, 0x00000308, 0x00000301, 0x000003c1, 0x00000313, 0x000003c1, 0x00000314, 0x000003c5, 0x00000342, 0x000003c5, 0x00000308, 0x00000342, 0x000003a5, 0x00000306, 0x000003a5, 0x00000304, 0x000003a5, 0x00000300, 0x000003a5, 0x00000301, 0x000003a1, 0x00000314, 0x00000020, 0x00000308, 0x00000300, 0x00000020, 0x00000308, 0x00000301, 0x00000060, 0x000003c9, 0x00000300, 0x00000345, 0x000003c9, 0x00000345, 0x000003c9, 0x00000301, 0x00000345, 0x000003c9, 0x00000342, 0x000003c9, 0x00000342, 0x00000345, 0x0000039f, 0x00000300, 0x0000039f, 0x00000301, 0x000003a9, 0x00000300, 0x000003a9, 0x00000301, 0x000003a9, 0x00000345, 0x00000020, 0x00000301, 0x00000020, 0x00000314, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00002010, 0x00000020, 0x00000333, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x00000020, 0x00002032, 0x00002032, 0x00002032, 0x00002032, 0x00002032, 0x00002035, 0x00002035, 0x00002035, 0x00002035, 0x00002035, 0x00000021, 0x00000021, 0x00000020, 0x00000305, 0x0000003f, 0x0000003f, 0x0000003f, 0x00000021, 0x00000021, 0x0000003f, 0x00002032, 0x00002032, 0x00002032, 0x00002032, 0x00000020, 0x00000030, 0x00000069, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x0000002b, 0x00002212, 0x0000003d, 0x00000028, 0x00000029, 0x0000006e, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x0000002b, 0x00002212, 0x0000003d, 0x00000028, 0x00000029, 0x00000052, 0x00000073, 0x00000061, 0x0000002f, 0x00000063, 0x00000061, 0x0000002f, 0x00000073, 0x00000043, 0x000000b0, 0x00000043, 0x00000063, 0x0000002f, 0x0000006f, 0x00000063, 0x0000002f, 0x00000075, 0x00000190, 0x000000b0, 0x00000046, 0x00000067, 0x00000048, 0x00000048, 0x00000048, 0x00000068, 0x00000127, 0x00000049, 0x00000049, 0x0000004c, 0x0000006c, 0x0000004e, 0x0000004e, 0x0000006f, 0x00000050, 0x00000051, 0x00000052, 0x00000052, 0x00000052, 0x00000053, 0x0000004d, 0x00000054, 0x00000045, 0x0000004c, 0x00000054, 0x0000004d, 0x0000005a, 0x000003a9, 0x0000005a, 0x0000004b, 0x00000041, 0x0000030a, 0x00000042, 0x00000043, 0x00000065, 0x00000045, 0x00000046, 0x0000004d, 0x0000006f, 0x000005d0, 0x000005d1, 0x000005d2, 0x000005d3, 0x00000069, 0x000003b3, 0x00000393, 0x000003a0, 0x00002211, 0x00000044, 0x00000064, 0x00000065, 0x00000069, 0x0000006a, 0x00000031, 0x00002044, 0x00000033, 0x00000032, 0x00002044, 0x00000033, 0x00000031, 0x00002044, 0x00000035, 0x00000032, 0x00002044, 0x00000035, 0x00000033, 0x00002044, 0x00000035, 0x00000034, 0x00002044, 0x00000035, 0x00000031, 0x00002044, 0x00000036, 0x00000035, 0x00002044, 0x00000036, 0x00000031, 0x00002044, 0x00000038, 0x00000033, 0x00002044, 0x00000038, 0x00000035, 0x00002044, 0x00000038, 0x00000037, 0x00002044, 0x00000038, 0x00000031, 0x00002044, 0x00000049, 0x00000049, 0x00000049, 0x00000049, 0x00000049, 0x00000049, 0x00000049, 0x00000056, 0x00000056, 0x00000056, 0x00000049, 0x00000056, 0x00000049, 0x00000049, 0x00000056, 0x00000049, 0x00000049, 0x00000049, 0x00000049, 0x00000058, 0x00000058, 0x00000058, 0x00000049, 0x00000058, 0x00000049, 0x00000049, 0x0000004c, 0x00000043, 0x00000044, 0x0000004d, 0x00000069, 0x00000069, 0x00000069, 0x00000069, 0x00000069, 0x00000069, 0x00000069, 0x00000076, 0x00000076, 0x00000076, 0x00000069, 0x00000076, 0x00000069, 0x00000069, 0x00000076, 0x00000069, 0x00000069, 0x00000069, 0x00000069, 0x00000078, 0x00000078, 0x00000078, 0x00000069, 0x00000078, 0x00000069, 0x00000069, 0x0000006c, 0x00000063, 0x00000064, 0x0000006d, 0x00002190, 0x00000338, 0x00002192, 0x00000338, 0x00002194, 0x00000338, 0x000021d0, 0x00000338, 0x000021d4, 0x00000338, 0x000021d2, 0x00000338, 0x00002203, 0x00000338, 0x00002208, 0x00000338, 0x0000220b, 0x00000338, 0x00002223, 0x00000338, 0x00002225, 0x00000338, 0x0000222b, 0x0000222b, 0x0000222b, 0x0000222b, 0x0000222b, 0x0000222e, 0x0000222e, 0x0000222e, 0x0000222e, 0x0000222e, 0x0000223c, 0x00000338, 0x00002243, 0x00000338, 0x00002245, 0x00000338, 0x00002248, 0x00000338, 0x0000003d, 0x00000338, 0x00002261, 0x00000338, 0x0000224d, 0x00000338, 0x0000003c, 0x00000338, 0x0000003e, 0x00000338, 0x00002264, 0x00000338, 0x00002265, 0x00000338, 0x00002272, 0x00000338, 0x00002273, 0x00000338, 0x00002276, 0x00000338, 0x00002277, 0x00000338, 0x0000227a, 0x00000338, 0x0000227b, 0x00000338, 0x00002282, 0x00000338, 0x00002283, 0x00000338, 0x00002286, 0x00000338, 0x00002287, 0x00000338, 0x000022a2, 0x00000338, 0x000022a8, 0x00000338, 0x000022a9, 0x00000338, 0x000022ab, 0x00000338, 0x0000227c, 0x00000338, 0x0000227d, 0x00000338, 0x00002291, 0x00000338, 0x00002292, 0x00000338, 0x000022b2, 0x00000338, 0x000022b3, 0x00000338, 0x000022b4, 0x00000338, 0x000022b5, 0x00000338, 0x00003008, 0x00003009, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x00000031, 0x00000030, 0x00000031, 0x00000031, 0x00000031, 0x00000032, 0x00000031, 0x00000033, 0x00000031, 0x00000034, 0x00000031, 0x00000035, 0x00000031, 0x00000036, 0x00000031, 0x00000037, 0x00000031, 0x00000038, 0x00000031, 0x00000039, 0x00000032, 0x00000030, 0x00000028, 0x00000031, 0x00000029, 0x00000028, 0x00000032, 0x00000029, 0x00000028, 0x00000033, 0x00000029, 0x00000028, 0x00000034, 0x00000029, 0x00000028, 0x00000035, 0x00000029, 0x00000028, 0x00000036, 0x00000029, 0x00000028, 0x00000037, 0x00000029, 0x00000028, 0x00000038, 0x00000029, 0x00000028, 0x00000039, 0x00000029, 0x00000028, 0x00000031, 0x00000030, 0x00000029, 0x00000028, 0x00000031, 0x00000031, 0x00000029, 0x00000028, 0x00000031, 0x00000032, 0x00000029, 0x00000028, 0x00000031, 0x00000033, 0x00000029, 0x00000028, 0x00000031, 0x00000034, 0x00000029, 0x00000028, 0x00000031, 0x00000035, 0x00000029, 0x00000028, 0x00000031, 0x00000036, 0x00000029, 0x00000028, 0x00000031, 0x00000037, 0x00000029, 0x00000028, 0x00000031, 0x00000038, 0x00000029, 0x00000028, 0x00000031, 0x00000039, 0x00000029, 0x00000028, 0x00000032, 0x00000030, 0x00000029, 0x00000031, 0x0000002e, 0x00000032, 0x0000002e, 0x00000033, 0x0000002e, 0x00000034, 0x0000002e, 0x00000035, 0x0000002e, 0x00000036, 0x0000002e, 0x00000037, 0x0000002e, 0x00000038, 0x0000002e, 0x00000039, 0x0000002e, 0x00000031, 0x00000030, 0x0000002e, 0x00000031, 0x00000031, 0x0000002e, 0x00000031, 0x00000032, 0x0000002e, 0x00000031, 0x00000033, 0x0000002e, 0x00000031, 0x00000034, 0x0000002e, 0x00000031, 0x00000035, 0x0000002e, 0x00000031, 0x00000036, 0x0000002e, 0x00000031, 0x00000037, 0x0000002e, 0x00000031, 0x00000038, 0x0000002e, 0x00000031, 0x00000039, 0x0000002e, 0x00000032, 0x00000030, 0x0000002e, 0x00000028, 0x00000061, 0x00000029, 0x00000028, 0x00000062, 0x00000029, 0x00000028, 0x00000063, 0x00000029, 0x00000028, 0x00000064, 0x00000029, 0x00000028, 0x00000065, 0x00000029, 0x00000028, 0x00000066, 0x00000029, 0x00000028, 0x00000067, 0x00000029, 0x00000028, 0x00000068, 0x00000029, 0x00000028, 0x00000069, 0x00000029, 0x00000028, 0x0000006a, 0x00000029, 0x00000028, 0x0000006b, 0x00000029, 0x00000028, 0x0000006c, 0x00000029, 0x00000028, 0x0000006d, 0x00000029, 0x00000028, 0x0000006e, 0x00000029, 0x00000028, 0x0000006f, 0x00000029, 0x00000028, 0x00000070, 0x00000029, 0x00000028, 0x00000071, 0x00000029, 0x00000028, 0x00000072, 0x00000029, 0x00000028, 0x00000073, 0x00000029, 0x00000028, 0x00000074, 0x00000029, 0x00000028, 0x00000075, 0x00000029, 0x00000028, 0x00000076, 0x00000029, 0x00000028, 0x00000077, 0x00000029, 0x00000028, 0x00000078, 0x00000029, 0x00000028, 0x00000079, 0x00000029, 0x00000028, 0x0000007a, 0x00000029, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000030, 0x0000222b, 0x0000222b, 0x0000222b, 0x0000222b, 0x0000003a, 0x0000003a, 0x0000003d, 0x0000003d, 0x0000003d, 0x0000003d, 0x0000003d, 0x0000003d, 0x00002add, 0x00000338, 0x00006bcd, 0x00009f9f, 0x00004e00, 0x00004e28, 0x00004e36, 0x00004e3f, 0x00004e59, 0x00004e85, 0x00004e8c, 0x00004ea0, 0x00004eba, 0x0000513f, 0x00005165, 0x0000516b, 0x00005182, 0x00005196, 0x000051ab, 0x000051e0, 0x000051f5, 0x00005200, 0x0000529b, 0x000052f9, 0x00005315, 0x0000531a, 0x00005338, 0x00005341, 0x0000535c, 0x00005369, 0x00005382, 0x000053b6, 0x000053c8, 0x000053e3, 0x000056d7, 0x0000571f, 0x000058eb, 0x00005902, 0x0000590a, 0x00005915, 0x00005927, 0x00005973, 0x00005b50, 0x00005b80, 0x00005bf8, 0x00005c0f, 0x00005c22, 0x00005c38, 0x00005c6e, 0x00005c71, 0x00005ddb, 0x00005de5, 0x00005df1, 0x00005dfe, 0x00005e72, 0x00005e7a, 0x00005e7f, 0x00005ef4, 0x00005efe, 0x00005f0b, 0x00005f13, 0x00005f50, 0x00005f61, 0x00005f73, 0x00005fc3, 0x00006208, 0x00006236, 0x0000624b, 0x0000652f, 0x00006534, 0x00006587, 0x00006597, 0x000065a4, 0x000065b9, 0x000065e0, 0x000065e5, 0x000066f0, 0x00006708, 0x00006728, 0x00006b20, 0x00006b62, 0x00006b79, 0x00006bb3, 0x00006bcb, 0x00006bd4, 0x00006bdb, 0x00006c0f, 0x00006c14, 0x00006c34, 0x0000706b, 0x0000722a, 0x00007236, 0x0000723b, 0x0000723f, 0x00007247, 0x00007259, 0x0000725b, 0x000072ac, 0x00007384, 0x00007389, 0x000074dc, 0x000074e6, 0x00007518, 0x0000751f, 0x00007528, 0x00007530, 0x0000758b, 0x00007592, 0x00007676, 0x0000767d, 0x000076ae, 0x000076bf, 0x000076ee, 0x000077db, 0x000077e2, 0x000077f3, 0x0000793a, 0x000079b8, 0x000079be, 0x00007a74, 0x00007acb, 0x00007af9, 0x00007c73, 0x00007cf8, 0x00007f36, 0x00007f51, 0x00007f8a, 0x00007fbd, 0x00008001, 0x0000800c, 0x00008012, 0x00008033, 0x0000807f, 0x00008089, 0x000081e3, 0x000081ea, 0x000081f3, 0x000081fc, 0x0000820c, 0x0000821b, 0x0000821f, 0x0000826e, 0x00008272, 0x00008278, 0x0000864d, 0x0000866b, 0x00008840, 0x0000884c, 0x00008863, 0x0000897e, 0x0000898b, 0x000089d2, 0x00008a00, 0x00008c37, 0x00008c46, 0x00008c55, 0x00008c78, 0x00008c9d, 0x00008d64, 0x00008d70, 0x00008db3, 0x00008eab, 0x00008eca, 0x00008f9b, 0x00008fb0, 0x00008fb5, 0x00009091, 0x00009149, 0x000091c6, 0x000091cc, 0x000091d1, 0x00009577, 0x00009580, 0x0000961c, 0x000096b6, 0x000096b9, 0x000096e8, 0x00009751, 0x0000975e, 0x00009762, 0x00009769, 0x000097cb, 0x000097ed, 0x000097f3, 0x00009801, 0x000098a8, 0x000098db, 0x000098df, 0x00009996, 0x00009999, 0x000099ac, 0x00009aa8, 0x00009ad8, 0x00009adf, 0x00009b25, 0x00009b2f, 0x00009b32, 0x00009b3c, 0x00009b5a, 0x00009ce5, 0x00009e75, 0x00009e7f, 0x00009ea5, 0x00009ebb, 0x00009ec3, 0x00009ecd, 0x00009ed1, 0x00009ef9, 0x00009efd, 0x00009f0e, 0x00009f13, 0x00009f20, 0x00009f3b, 0x00009f4a, 0x00009f52, 0x00009f8d, 0x00009f9c, 0x00009fa0, 0x00000020, 0x00003012, 0x00005341, 0x00005344, 0x00005345, 0x0000304b, 0x00003099, 0x0000304d, 0x00003099, 0x0000304f, 0x00003099, 0x00003051, 0x00003099, 0x00003053, 0x00003099, 0x00003055, 0x00003099, 0x00003057, 0x00003099, 0x00003059, 0x00003099, 0x0000305b, 0x00003099, 0x0000305d, 0x00003099, 0x0000305f, 0x00003099, 0x00003061, 0x00003099, 0x00003064, 0x00003099, 0x00003066, 0x00003099, 0x00003068, 0x00003099, 0x0000306f, 0x00003099, 0x0000306f, 0x0000309a, 0x00003072, 0x00003099, 0x00003072, 0x0000309a, 0x00003075, 0x00003099, 0x00003075, 0x0000309a, 0x00003078, 0x00003099, 0x00003078, 0x0000309a, 0x0000307b, 0x00003099, 0x0000307b, 0x0000309a, 0x00003046, 0x00003099, 0x00000020, 0x00003099, 0x00000020, 0x0000309a, 0x0000309d, 0x00003099, 0x00003088, 0x0000308a, 0x000030ab, 0x00003099, 0x000030ad, 0x00003099, 0x000030af, 0x00003099, 0x000030b1, 0x00003099, 0x000030b3, 0x00003099, 0x000030b5, 0x00003099, 0x000030b7, 0x00003099, 0x000030b9, 0x00003099, 0x000030bb, 0x00003099, 0x000030bd, 0x00003099, 0x000030bf, 0x00003099, 0x000030c1, 0x00003099, 0x000030c4, 0x00003099, 0x000030c6, 0x00003099, 0x000030c8, 0x00003099, 0x000030cf, 0x00003099, 0x000030cf, 0x0000309a, 0x000030d2, 0x00003099, 0x000030d2, 0x0000309a, 0x000030d5, 0x00003099, 0x000030d5, 0x0000309a, 0x000030d8, 0x00003099, 0x000030d8, 0x0000309a, 0x000030db, 0x00003099, 0x000030db, 0x0000309a, 0x000030a6, 0x00003099, 0x000030ef, 0x00003099, 0x000030f0, 0x00003099, 0x000030f1, 0x00003099, 0x000030f2, 0x00003099, 0x000030fd, 0x00003099, 0x000030b3, 0x000030c8, 0x00001100, 0x00001101, 0x000011aa, 0x00001102, 0x000011ac, 0x000011ad, 0x00001103, 0x00001104, 0x00001105, 0x000011b0, 0x000011b1, 0x000011b2, 0x000011b3, 0x000011b4, 0x000011b5, 0x0000111a, 0x00001106, 0x00001107, 0x00001108, 0x00001121, 0x00001109, 0x0000110a, 0x0000110b, 0x0000110c, 0x0000110d, 0x0000110e, 0x0000110f, 0x00001110, 0x00001111, 0x00001112, 0x00001161, 0x00001162, 0x00001163, 0x00001164, 0x00001165, 0x00001166, 0x00001167, 0x00001168, 0x00001169, 0x0000116a, 0x0000116b, 0x0000116c, 0x0000116d, 0x0000116e, 0x0000116f, 0x00001170, 0x00001171, 0x00001172, 0x00001173, 0x00001174, 0x00001175, 0x00001160, 0x00001114, 0x00001115, 0x000011c7, 0x000011c8, 0x000011cc, 0x000011ce, 0x000011d3, 0x000011d7, 0x000011d9, 0x0000111c, 0x000011dd, 0x000011df, 0x0000111d, 0x0000111e, 0x00001120, 0x00001122, 0x00001123, 0x00001127, 0x00001129, 0x0000112b, 0x0000112c, 0x0000112d, 0x0000112e, 0x0000112f, 0x00001132, 0x00001136, 0x00001140, 0x00001147, 0x0000114c, 0x000011f1, 0x000011f2, 0x00001157, 0x00001158, 0x00001159, 0x00001184, 0x00001185, 0x00001188, 0x00001191, 0x00001192, 0x00001194, 0x0000119e, 0x000011a1, 0x00004e00, 0x00004e8c, 0x00004e09, 0x000056db, 0x00004e0a, 0x00004e2d, 0x00004e0b, 0x00007532, 0x00004e59, 0x00004e19, 0x00004e01, 0x00005929, 0x00005730, 0x00004eba, 0x00000028, 0x00001100, 0x00000029, 0x00000028, 0x00001102, 0x00000029, 0x00000028, 0x00001103, 0x00000029, 0x00000028, 0x00001105, 0x00000029, 0x00000028, 0x00001106, 0x00000029, 0x00000028, 0x00001107, 0x00000029, 0x00000028, 0x00001109, 0x00000029, 0x00000028, 0x0000110b, 0x00000029, 0x00000028, 0x0000110c, 0x00000029, 0x00000028, 0x0000110e, 0x00000029, 0x00000028, 0x0000110f, 0x00000029, 0x00000028, 0x00001110, 0x00000029, 0x00000028, 0x00001111, 0x00000029, 0x00000028, 0x00001112, 0x00000029, 0x00000028, 0x00001100, 0x00001161, 0x00000029, 0x00000028, 0x00001102, 0x00001161, 0x00000029, 0x00000028, 0x00001103, 0x00001161, 0x00000029, 0x00000028, 0x00001105, 0x00001161, 0x00000029, 0x00000028, 0x00001106, 0x00001161, 0x00000029, 0x00000028, 0x00001107, 0x00001161, 0x00000029, 0x00000028, 0x00001109, 0x00001161, 0x00000029, 0x00000028, 0x0000110b, 0x00001161, 0x00000029, 0x00000028, 0x0000110c, 0x00001161, 0x00000029, 0x00000028, 0x0000110e, 0x00001161, 0x00000029, 0x00000028, 0x0000110f, 0x00001161, 0x00000029, 0x00000028, 0x00001110, 0x00001161, 0x00000029, 0x00000028, 0x00001111, 0x00001161, 0x00000029, 0x00000028, 0x00001112, 0x00001161, 0x00000029, 0x00000028, 0x0000110c, 0x0000116e, 0x00000029, 0x00000028, 0x00004e00, 0x00000029, 0x00000028, 0x00004e8c, 0x00000029, 0x00000028, 0x00004e09, 0x00000029, 0x00000028, 0x000056db, 0x00000029, 0x00000028, 0x00004e94, 0x00000029, 0x00000028, 0x0000516d, 0x00000029, 0x00000028, 0x00004e03, 0x00000029, 0x00000028, 0x0000516b, 0x00000029, 0x00000028, 0x00004e5d, 0x00000029, 0x00000028, 0x00005341, 0x00000029, 0x00000028, 0x00006708, 0x00000029, 0x00000028, 0x0000706b, 0x00000029, 0x00000028, 0x00006c34, 0x00000029, 0x00000028, 0x00006728, 0x00000029, 0x00000028, 0x000091d1, 0x00000029, 0x00000028, 0x0000571f, 0x00000029, 0x00000028, 0x000065e5, 0x00000029, 0x00000028, 0x0000682a, 0x00000029, 0x00000028, 0x00006709, 0x00000029, 0x00000028, 0x0000793e, 0x00000029, 0x00000028, 0x0000540d, 0x00000029, 0x00000028, 0x00007279, 0x00000029, 0x00000028, 0x00008ca1, 0x00000029, 0x00000028, 0x0000795d, 0x00000029, 0x00000028, 0x000052b4, 0x00000029, 0x00000028, 0x00004ee3, 0x00000029, 0x00000028, 0x0000547c, 0x00000029, 0x00000028, 0x00005b66, 0x00000029, 0x00000028, 0x000076e3, 0x00000029, 0x00000028, 0x00004f01, 0x00000029, 0x00000028, 0x00008cc7, 0x00000029, 0x00000028, 0x00005354, 0x00000029, 0x00000028, 0x0000796d, 0x00000029, 0x00000028, 0x00004f11, 0x00000029, 0x00000028, 0x000081ea, 0x00000029, 0x00000028, 0x000081f3, 0x00000029, 0x00000032, 0x00000031, 0x00000032, 0x00000032, 0x00000032, 0x00000033, 0x00000032, 0x00000034, 0x00000032, 0x00000035, 0x00000032, 0x00000036, 0x00000032, 0x00000037, 0x00000032, 0x00000038, 0x00000032, 0x00000039, 0x00000033, 0x00000030, 0x00000033, 0x00000031, 0x00000033, 0x00000032, 0x00000033, 0x00000033, 0x00000033, 0x00000034, 0x00000033, 0x00000035, 0x00001100, 0x00001102, 0x00001103, 0x00001105, 0x00001106, 0x00001107, 0x00001109, 0x0000110b, 0x0000110c, 0x0000110e, 0x0000110f, 0x00001110, 0x00001111, 0x00001112, 0x00001100, 0x00001161, 0x00001102, 0x00001161, 0x00001103, 0x00001161, 0x00001105, 0x00001161, 0x00001106, 0x00001161, 0x00001107, 0x00001161, 0x00001109, 0x00001161, 0x0000110b, 0x00001161, 0x0000110c, 0x00001161, 0x0000110e, 0x00001161, 0x0000110f, 0x00001161, 0x00001110, 0x00001161, 0x00001111, 0x00001161, 0x00001112, 0x00001161, 0x00004e00, 0x00004e8c, 0x00004e09, 0x000056db, 0x00004e94, 0x0000516d, 0x00004e03, 0x0000516b, 0x00004e5d, 0x00005341, 0x00006708, 0x0000706b, 0x00006c34, 0x00006728, 0x000091d1, 0x0000571f, 0x000065e5, 0x0000682a, 0x00006709, 0x0000793e, 0x0000540d, 0x00007279, 0x00008ca1, 0x0000795d, 0x000052b4, 0x000079d8, 0x00007537, 0x00005973, 0x00009069, 0x0000512a, 0x00005370, 0x00006ce8, 0x00009805, 0x00004f11, 0x00005199, 0x00006b63, 0x00004e0a, 0x00004e2d, 0x00004e0b, 0x00005de6, 0x000053f3, 0x0000533b, 0x00005b97, 0x00005b66, 0x000076e3, 0x00004f01, 0x00008cc7, 0x00005354, 0x0000591c, 0x00000033, 0x00000036, 0x00000033, 0x00000037, 0x00000033, 0x00000038, 0x00000033, 0x00000039, 0x00000034, 0x00000030, 0x00000034, 0x00000031, 0x00000034, 0x00000032, 0x00000034, 0x00000033, 0x00000034, 0x00000034, 0x00000034, 0x00000035, 0x00000034, 0x00000036, 0x00000034, 0x00000037, 0x00000034, 0x00000038, 0x00000034, 0x00000039, 0x00000035, 0x00000030, 0x00000031, 0x00006708, 0x00000032, 0x00006708, 0x00000033, 0x00006708, 0x00000034, 0x00006708, 0x00000035, 0x00006708, 0x00000036, 0x00006708, 0x00000037, 0x00006708, 0x00000038, 0x00006708, 0x00000039, 0x00006708, 0x00000031, 0x00000030, 0x00006708, 0x00000031, 0x00000031, 0x00006708, 0x00000031, 0x00000032, 0x00006708, 0x000030a2, 0x000030a4, 0x000030a6, 0x000030a8, 0x000030aa, 0x000030ab, 0x000030ad, 0x000030af, 0x000030b1, 0x000030b3, 0x000030b5, 0x000030b7, 0x000030b9, 0x000030bb, 0x000030bd, 0x000030bf, 0x000030c1, 0x000030c4, 0x000030c6, 0x000030c8, 0x000030ca, 0x000030cb, 0x000030cc, 0x000030cd, 0x000030ce, 0x000030cf, 0x000030d2, 0x000030d5, 0x000030d8, 0x000030db, 0x000030de, 0x000030df, 0x000030e0, 0x000030e1, 0x000030e2, 0x000030e4, 0x000030e6, 0x000030e8, 0x000030e9, 0x000030ea, 0x000030eb, 0x000030ec, 0x000030ed, 0x000030ef, 0x000030f0, 0x000030f1, 0x000030f2, 0x000030a2, 0x000030cf, 0x0000309a, 0x000030fc, 0x000030c8, 0x000030a2, 0x000030eb, 0x000030d5, 0x000030a1, 0x000030a2, 0x000030f3, 0x000030d8, 0x0000309a, 0x000030a2, 0x000030a2, 0x000030fc, 0x000030eb, 0x000030a4, 0x000030cb, 0x000030f3, 0x000030af, 0x00003099, 0x000030a4, 0x000030f3, 0x000030c1, 0x000030a6, 0x000030a9, 0x000030f3, 0x000030a8, 0x000030b9, 0x000030af, 0x000030fc, 0x000030c8, 0x00003099, 0x000030a8, 0x000030fc, 0x000030ab, 0x000030fc, 0x000030aa, 0x000030f3, 0x000030b9, 0x000030aa, 0x000030fc, 0x000030e0, 0x000030ab, 0x000030a4, 0x000030ea, 0x000030ab, 0x000030e9, 0x000030c3, 0x000030c8, 0x000030ab, 0x000030ed, 0x000030ea, 0x000030fc, 0x000030ab, 0x00003099, 0x000030ed, 0x000030f3, 0x000030ab, 0x00003099, 0x000030f3, 0x000030de, 0x000030ad, 0x00003099, 0x000030ab, 0x00003099, 0x000030ad, 0x00003099, 0x000030cb, 0x000030fc, 0x000030ad, 0x000030e5, 0x000030ea, 0x000030fc, 0x000030ad, 0x00003099, 0x000030eb, 0x000030bf, 0x00003099, 0x000030fc, 0x000030ad, 0x000030ed, 0x000030ad, 0x000030ed, 0x000030af, 0x00003099, 0x000030e9, 0x000030e0, 0x000030ad, 0x000030ed, 0x000030e1, 0x000030fc, 0x000030c8, 0x000030eb, 0x000030ad, 0x000030ed, 0x000030ef, 0x000030c3, 0x000030c8, 0x000030af, 0x00003099, 0x000030e9, 0x000030e0, 0x000030af, 0x00003099, 0x000030e9, 0x000030e0, 0x000030c8, 0x000030f3, 0x000030af, 0x000030eb, 0x000030bb, 0x00003099, 0x000030a4, 0x000030ed, 0x000030af, 0x000030ed, 0x000030fc, 0x000030cd, 0x000030b1, 0x000030fc, 0x000030b9, 0x000030b3, 0x000030eb, 0x000030ca, 0x000030b3, 0x000030fc, 0x000030db, 0x0000309a, 0x000030b5, 0x000030a4, 0x000030af, 0x000030eb, 0x000030b5, 0x000030f3, 0x000030c1, 0x000030fc, 0x000030e0, 0x000030b7, 0x000030ea, 0x000030f3, 0x000030af, 0x00003099, 0x000030bb, 0x000030f3, 0x000030c1, 0x000030bb, 0x000030f3, 0x000030c8, 0x000030bf, 0x00003099, 0x000030fc, 0x000030b9, 0x000030c6, 0x00003099, 0x000030b7, 0x000030c8, 0x00003099, 0x000030eb, 0x000030c8, 0x000030f3, 0x000030ca, 0x000030ce, 0x000030ce, 0x000030c3, 0x000030c8, 0x000030cf, 0x000030a4, 0x000030c4, 0x000030cf, 0x0000309a, 0x000030fc, 0x000030bb, 0x000030f3, 0x000030c8, 0x000030cf, 0x0000309a, 0x000030fc, 0x000030c4, 0x000030cf, 0x00003099, 0x000030fc, 0x000030ec, 0x000030eb, 0x000030d2, 0x0000309a, 0x000030a2, 0x000030b9, 0x000030c8, 0x000030eb, 0x000030d2, 0x0000309a, 0x000030af, 0x000030eb, 0x000030d2, 0x0000309a, 0x000030b3, 0x000030d2, 0x00003099, 0x000030eb, 0x000030d5, 0x000030a1, 0x000030e9, 0x000030c3, 0x000030c8, 0x00003099, 0x000030d5, 0x000030a3, 0x000030fc, 0x000030c8, 0x000030d5, 0x00003099, 0x000030c3, 0x000030b7, 0x000030a7, 0x000030eb, 0x000030d5, 0x000030e9, 0x000030f3, 0x000030d8, 0x000030af, 0x000030bf, 0x000030fc, 0x000030eb, 0x000030d8, 0x0000309a, 0x000030bd, 0x000030d8, 0x0000309a, 0x000030cb, 0x000030d2, 0x000030d8, 0x000030eb, 0x000030c4, 0x000030d8, 0x0000309a, 0x000030f3, 0x000030b9, 0x000030d8, 0x0000309a, 0x000030fc, 0x000030b7, 0x00003099, 0x000030d8, 0x00003099, 0x000030fc, 0x000030bf, 0x000030db, 0x0000309a, 0x000030a4, 0x000030f3, 0x000030c8, 0x000030db, 0x00003099, 0x000030eb, 0x000030c8, 0x000030db, 0x000030f3, 0x000030db, 0x0000309a, 0x000030f3, 0x000030c8, 0x00003099, 0x000030db, 0x000030fc, 0x000030eb, 0x000030db, 0x000030fc, 0x000030f3, 0x000030de, 0x000030a4, 0x000030af, 0x000030ed, 0x000030de, 0x000030a4, 0x000030eb, 0x000030de, 0x000030c3, 0x000030cf, 0x000030de, 0x000030eb, 0x000030af, 0x000030de, 0x000030f3, 0x000030b7, 0x000030e7, 0x000030f3, 0x000030df, 0x000030af, 0x000030ed, 0x000030f3, 0x000030df, 0x000030ea, 0x000030df, 0x000030ea, 0x000030cf, 0x00003099, 0x000030fc, 0x000030eb, 0x000030e1, 0x000030ab, 0x00003099, 0x000030e1, 0x000030ab, 0x00003099, 0x000030c8, 0x000030f3, 0x000030e1, 0x000030fc, 0x000030c8, 0x000030eb, 0x000030e4, 0x000030fc, 0x000030c8, 0x00003099, 0x000030e4, 0x000030fc, 0x000030eb, 0x000030e6, 0x000030a2, 0x000030f3, 0x000030ea, 0x000030c3, 0x000030c8, 0x000030eb, 0x000030ea, 0x000030e9, 0x000030eb, 0x000030d2, 0x0000309a, 0x000030fc, 0x000030eb, 0x000030fc, 0x000030d5, 0x00003099, 0x000030eb, 0x000030ec, 0x000030e0, 0x000030ec, 0x000030f3, 0x000030c8, 0x000030b1, 0x00003099, 0x000030f3, 0x000030ef, 0x000030c3, 0x000030c8, 0x00000030, 0x000070b9, 0x00000031, 0x000070b9, 0x00000032, 0x000070b9, 0x00000033, 0x000070b9, 0x00000034, 0x000070b9, 0x00000035, 0x000070b9, 0x00000036, 0x000070b9, 0x00000037, 0x000070b9, 0x00000038, 0x000070b9, 0x00000039, 0x000070b9, 0x00000031, 0x00000030, 0x000070b9, 0x00000031, 0x00000031, 0x000070b9, 0x00000031, 0x00000032, 0x000070b9, 0x00000031, 0x00000033, 0x000070b9, 0x00000031, 0x00000034, 0x000070b9, 0x00000031, 0x00000035, 0x000070b9, 0x00000031, 0x00000036, 0x000070b9, 0x00000031, 0x00000037, 0x000070b9, 0x00000031, 0x00000038, 0x000070b9, 0x00000031, 0x00000039, 0x000070b9, 0x00000032, 0x00000030, 0x000070b9, 0x00000032, 0x00000031, 0x000070b9, 0x00000032, 0x00000032, 0x000070b9, 0x00000032, 0x00000033, 0x000070b9, 0x00000032, 0x00000034, 0x000070b9, 0x00000068, 0x00000050, 0x00000061, 0x00000064, 0x00000061, 0x00000041, 0x00000055, 0x00000062, 0x00000061, 0x00000072, 0x0000006f, 0x00000056, 0x00000070, 0x00000063, 0x00005e73, 0x00006210, 0x0000662d, 0x0000548c, 0x00005927, 0x00006b63, 0x0000660e, 0x00006cbb, 0x0000682a, 0x00005f0f, 0x00004f1a, 0x0000793e, 0x00000070, 0x00000041, 0x0000006e, 0x00000041, 0x000003bc, 0x00000041, 0x0000006d, 0x00000041, 0x0000006b, 0x00000041, 0x0000004b, 0x00000042, 0x0000004d, 0x00000042, 0x00000047, 0x00000042, 0x00000063, 0x00000061, 0x0000006c, 0x0000006b, 0x00000063, 0x00000061, 0x0000006c, 0x00000070, 0x00000046, 0x0000006e, 0x00000046, 0x000003bc, 0x00000046, 0x000003bc, 0x00000067, 0x0000006d, 0x00000067, 0x0000006b, 0x00000067, 0x00000048, 0x0000007a, 0x0000006b, 0x00000048, 0x0000007a, 0x0000004d, 0x00000048, 0x0000007a, 0x00000047, 0x00000048, 0x0000007a, 0x00000054, 0x00000048, 0x0000007a, 0x000003bc, 0x0000006c, 0x0000006d, 0x0000006c, 0x00000064, 0x0000006c, 0x0000006b, 0x0000006c, 0x00000066, 0x0000006d, 0x0000006e, 0x0000006d, 0x000003bc, 0x0000006d, 0x0000006d, 0x0000006d, 0x00000063, 0x0000006d, 0x0000006b, 0x0000006d, 0x0000006d, 0x0000006d, 0x00000032, 0x00000063, 0x0000006d, 0x00000032, 0x0000006d, 0x00000032, 0x0000006b, 0x0000006d, 0x00000032, 0x0000006d, 0x0000006d, 0x00000033, 0x00000063, 0x0000006d, 0x00000033, 0x0000006d, 0x00000033, 0x0000006b, 0x0000006d, 0x00000033, 0x0000006d, 0x00002215, 0x00000073, 0x0000006d, 0x00002215, 0x00000073, 0x00000032, 0x00000050, 0x00000061, 0x0000006b, 0x00000050, 0x00000061, 0x0000004d, 0x00000050, 0x00000061, 0x00000047, 0x00000050, 0x00000061, 0x00000072, 0x00000061, 0x00000064, 0x00000072, 0x00000061, 0x00000064, 0x00002215, 0x00000073, 0x00000072, 0x00000061, 0x00000064, 0x00002215, 0x00000073, 0x00000032, 0x00000070, 0x00000073, 0x0000006e, 0x00000073, 0x000003bc, 0x00000073, 0x0000006d, 0x00000073, 0x00000070, 0x00000056, 0x0000006e, 0x00000056, 0x000003bc, 0x00000056, 0x0000006d, 0x00000056, 0x0000006b, 0x00000056, 0x0000004d, 0x00000056, 0x00000070, 0x00000057, 0x0000006e, 0x00000057, 0x000003bc, 0x00000057, 0x0000006d, 0x00000057, 0x0000006b, 0x00000057, 0x0000004d, 0x00000057, 0x0000006b, 0x000003a9, 0x0000004d, 0x000003a9, 0x00000061, 0x0000002e, 0x0000006d, 0x0000002e, 0x00000042, 0x00000071, 0x00000063, 0x00000063, 0x00000063, 0x00000064, 0x00000043, 0x00002215, 0x0000006b, 0x00000067, 0x00000043, 0x0000006f, 0x0000002e, 0x00000064, 0x00000042, 0x00000047, 0x00000079, 0x00000068, 0x00000061, 0x00000048, 0x00000050, 0x00000069, 0x0000006e, 0x0000004b, 0x0000004b, 0x0000004b, 0x0000004d, 0x0000006b, 0x00000074, 0x0000006c, 0x0000006d, 0x0000006c, 0x0000006e, 0x0000006c, 0x0000006f, 0x00000067, 0x0000006c, 0x00000078, 0x0000006d, 0x00000062, 0x0000006d, 0x00000069, 0x0000006c, 0x0000006d, 0x0000006f, 0x0000006c, 0x00000050, 0x00000048, 0x00000070, 0x0000002e, 0x0000006d, 0x0000002e, 0x00000050, 0x00000050, 0x0000004d, 0x00000050, 0x00000052, 0x00000073, 0x00000072, 0x00000053, 0x00000076, 0x00000057, 0x00000062, 0x00000031, 0x000065e5, 0x00000032, 0x000065e5, 0x00000033, 0x000065e5, 0x00000034, 0x000065e5, 0x00000035, 0x000065e5, 0x00000036, 0x000065e5, 0x00000037, 0x000065e5, 0x00000038, 0x000065e5, 0x00000039, 0x000065e5, 0x00000031, 0x00000030, 0x000065e5, 0x00000031, 0x00000031, 0x000065e5, 0x00000031, 0x00000032, 0x000065e5, 0x00000031, 0x00000033, 0x000065e5, 0x00000031, 0x00000034, 0x000065e5, 0x00000031, 0x00000035, 0x000065e5, 0x00000031, 0x00000036, 0x000065e5, 0x00000031, 0x00000037, 0x000065e5, 0x00000031, 0x00000038, 0x000065e5, 0x00000031, 0x00000039, 0x000065e5, 0x00000032, 0x00000030, 0x000065e5, 0x00000032, 0x00000031, 0x000065e5, 0x00000032, 0x00000032, 0x000065e5, 0x00000032, 0x00000033, 0x000065e5, 0x00000032, 0x00000034, 0x000065e5, 0x00000032, 0x00000035, 0x000065e5, 0x00000032, 0x00000036, 0x000065e5, 0x00000032, 0x00000037, 0x000065e5, 0x00000032, 0x00000038, 0x000065e5, 0x00000032, 0x00000039, 0x000065e5, 0x00000033, 0x00000030, 0x000065e5, 0x00000033, 0x00000031, 0x000065e5, 0x00008eca, 0x00008cc8, 0x00006ed1, 0x00004e32, 0x000053e5, 0x00009f9c, 0x00009f9c, 0x00005951, 0x000091d1, 0x00005587, 0x00005948, 0x000061f6, 0x00007669, 0x00007f85, 0x0000863f, 0x000087ba, 0x000088f8, 0x0000908f, 0x00006a02, 0x00006d1b, 0x000070d9, 0x000073de, 0x0000843d, 0x0000916a, 0x000099f1, 0x00004e82, 0x00005375, 0x00006b04, 0x0000721b, 0x0000862d, 0x00009e1e, 0x00005d50, 0x00006feb, 0x000085cd, 0x00008964, 0x000062c9, 0x000081d8, 0x0000881f, 0x00005eca, 0x00006717, 0x00006d6a, 0x000072fc, 0x000090ce, 0x00004f86, 0x000051b7, 0x000052de, 0x000064c4, 0x00006ad3, 0x00007210, 0x000076e7, 0x00008001, 0x00008606, 0x0000865c, 0x00008def, 0x00009732, 0x00009b6f, 0x00009dfa, 0x0000788c, 0x0000797f, 0x00007da0, 0x000083c9, 0x00009304, 0x00009e7f, 0x00008ad6, 0x000058df, 0x00005f04, 0x00007c60, 0x0000807e, 0x00007262, 0x000078ca, 0x00008cc2, 0x000096f7, 0x000058d8, 0x00005c62, 0x00006a13, 0x00006dda, 0x00006f0f, 0x00007d2f, 0x00007e37, 0x0000964b, 0x000052d2, 0x0000808b, 0x000051dc, 0x000051cc, 0x00007a1c, 0x00007dbe, 0x000083f1, 0x00009675, 0x00008b80, 0x000062cf, 0x00006a02, 0x00008afe, 0x00004e39, 0x00005be7, 0x00006012, 0x00007387, 0x00007570, 0x00005317, 0x000078fb, 0x00004fbf, 0x00005fa9, 0x00004e0d, 0x00006ccc, 0x00006578, 0x00007d22, 0x000053c3, 0x0000585e, 0x00007701, 0x00008449, 0x00008aaa, 0x00006bba, 0x00008fb0, 0x00006c88, 0x000062fe, 0x000082e5, 0x000063a0, 0x00007565, 0x00004eae, 0x00005169, 0x000051c9, 0x00006881, 0x00007ce7, 0x0000826f, 0x00008ad2, 0x000091cf, 0x000052f5, 0x00005442, 0x00005973, 0x00005eec, 0x000065c5, 0x00006ffe, 0x0000792a, 0x000095ad, 0x00009a6a, 0x00009e97, 0x00009ece, 0x0000529b, 0x000066c6, 0x00006b77, 0x00008f62, 0x00005e74, 0x00006190, 0x00006200, 0x0000649a, 0x00006f23, 0x00007149, 0x00007489, 0x000079ca, 0x00007df4, 0x0000806f, 0x00008f26, 0x000084ee, 0x00009023, 0x0000934a, 0x00005217, 0x000052a3, 0x000054bd, 0x000070c8, 0x000088c2, 0x00008aaa, 0x00005ec9, 0x00005ff5, 0x0000637b, 0x00006bae, 0x00007c3e, 0x00007375, 0x00004ee4, 0x000056f9, 0x00005be7, 0x00005dba, 0x0000601c, 0x000073b2, 0x00007469, 0x00007f9a, 0x00008046, 0x00009234, 0x000096f6, 0x00009748, 0x00009818, 0x00004f8b, 0x000079ae, 0x000091b4, 0x000096b8, 0x000060e1, 0x00004e86, 0x000050da, 0x00005bee, 0x00005c3f, 0x00006599, 0x00006a02, 0x000071ce, 0x00007642, 0x000084fc, 0x0000907c, 0x00009f8d, 0x00006688, 0x0000962e, 0x00005289, 0x0000677b, 0x000067f3, 0x00006d41, 0x00006e9c, 0x00007409, 0x00007559, 0x0000786b, 0x00007d10, 0x0000985e, 0x0000516d, 0x0000622e, 0x00009678, 0x0000502b, 0x00005d19, 0x00006dea, 0x00008f2a, 0x00005f8b, 0x00006144, 0x00006817, 0x00007387, 0x00009686, 0x00005229, 0x0000540f, 0x00005c65, 0x00006613, 0x0000674e, 0x000068a8, 0x00006ce5, 0x00007406, 0x000075e2, 0x00007f79, 0x000088cf, 0x000088e1, 0x000091cc, 0x000096e2, 0x0000533f, 0x00006eba, 0x0000541d, 0x000071d0, 0x00007498, 0x000085fa, 0x000096a3, 0x00009c57, 0x00009e9f, 0x00006797, 0x00006dcb, 0x000081e8, 0x00007acb, 0x00007b20, 0x00007c92, 0x000072c0, 0x00007099, 0x00008b58, 0x00004ec0, 0x00008336, 0x0000523a, 0x00005207, 0x00005ea6, 0x000062d3, 0x00007cd6, 0x00005b85, 0x00006d1e, 0x000066b4, 0x00008f3b, 0x0000884c, 0x0000964d, 0x0000898b, 0x00005ed3, 0x00005140, 0x000055c0, 0x0000585a, 0x00006674, 0x000051de, 0x0000732a, 0x000076ca, 0x0000793c, 0x0000795e, 0x00007965, 0x0000798f, 0x00009756, 0x00007cbe, 0x00007fbd, 0x00008612, 0x00008af8, 0x00009038, 0x000090fd, 0x000098ef, 0x000098fc, 0x00009928, 0x00009db4, 0x00004fae, 0x000050e7, 0x0000514d, 0x000052c9, 0x000052e4, 0x00005351, 0x0000559d, 0x00005606, 0x00005668, 0x00005840, 0x000058a8, 0x00005c64, 0x00005c6e, 0x00006094, 0x00006168, 0x0000618e, 0x000061f2, 0x0000654f, 0x000065e2, 0x00006691, 0x00006885, 0x00006d77, 0x00006e1a, 0x00006f22, 0x0000716e, 0x0000722b, 0x00007422, 0x00007891, 0x0000793e, 0x00007949, 0x00007948, 0x00007950, 0x00007956, 0x0000795d, 0x0000798d, 0x0000798e, 0x00007a40, 0x00007a81, 0x00007bc0, 0x00007df4, 0x00007e09, 0x00007e41, 0x00007f72, 0x00008005, 0x000081ed, 0x00008279, 0x00008279, 0x00008457, 0x00008910, 0x00008996, 0x00008b01, 0x00008b39, 0x00008cd3, 0x00008d08, 0x00008fb6, 0x00009038, 0x000096e3, 0x000097ff, 0x0000983b, 0x00000066, 0x00000066, 0x00000066, 0x00000069, 0x00000066, 0x0000006c, 0x00000066, 0x00000066, 0x00000069, 0x00000066, 0x00000066, 0x0000006c, 0x00000073, 0x00000074, 0x00000073, 0x00000074, 0x00000574, 0x00000576, 0x00000574, 0x00000565, 0x00000574, 0x0000056b, 0x0000057e, 0x00000576, 0x00000574, 0x0000056d, 0x000005d9, 0x000005b4, 0x000005f2, 0x000005b7, 0x000005e2, 0x000005d0, 0x000005d3, 0x000005d4, 0x000005db, 0x000005dc, 0x000005dd, 0x000005e8, 0x000005ea, 0x0000002b, 0x000005e9, 0x000005c1, 0x000005e9, 0x000005c2, 0x000005e9, 0x000005bc, 0x000005c1, 0x000005e9, 0x000005bc, 0x000005c2, 0x000005d0, 0x000005b7, 0x000005d0, 0x000005b8, 0x000005d0, 0x000005bc, 0x000005d1, 0x000005bc, 0x000005d2, 0x000005bc, 0x000005d3, 0x000005bc, 0x000005d4, 0x000005bc, 0x000005d5, 0x000005bc, 0x000005d6, 0x000005bc, 0x000005d8, 0x000005bc, 0x000005d9, 0x000005bc, 0x000005da, 0x000005bc, 0x000005db, 0x000005bc, 0x000005dc, 0x000005bc, 0x000005de, 0x000005bc, 0x000005e0, 0x000005bc, 0x000005e1, 0x000005bc, 0x000005e3, 0x000005bc, 0x000005e4, 0x000005bc, 0x000005e6, 0x000005bc, 0x000005e7, 0x000005bc, 0x000005e8, 0x000005bc, 0x000005e9, 0x000005bc, 0x000005ea, 0x000005bc, 0x000005d5, 0x000005b9, 0x000005d1, 0x000005bf, 0x000005db, 0x000005bf, 0x000005e4, 0x000005bf, 0x000005d0, 0x000005dc, 0x00000671, 0x00000671, 0x0000067b, 0x0000067b, 0x0000067b, 0x0000067b, 0x0000067e, 0x0000067e, 0x0000067e, 0x0000067e, 0x00000680, 0x00000680, 0x00000680, 0x00000680, 0x0000067a, 0x0000067a, 0x0000067a, 0x0000067a, 0x0000067f, 0x0000067f, 0x0000067f, 0x0000067f, 0x00000679, 0x00000679, 0x00000679, 0x00000679, 0x000006a4, 0x000006a4, 0x000006a4, 0x000006a4, 0x000006a6, 0x000006a6, 0x000006a6, 0x000006a6, 0x00000684, 0x00000684, 0x00000684, 0x00000684, 0x00000683, 0x00000683, 0x00000683, 0x00000683, 0x00000686, 0x00000686, 0x00000686, 0x00000686, 0x00000687, 0x00000687, 0x00000687, 0x00000687, 0x0000068d, 0x0000068d, 0x0000068c, 0x0000068c, 0x0000068e, 0x0000068e, 0x00000688, 0x00000688, 0x00000698, 0x00000698, 0x00000691, 0x00000691, 0x000006a9, 0x000006a9, 0x000006a9, 0x000006a9, 0x000006af, 0x000006af, 0x000006af, 0x000006af, 0x000006b3, 0x000006b3, 0x000006b3, 0x000006b3, 0x000006b1, 0x000006b1, 0x000006b1, 0x000006b1, 0x000006ba, 0x000006ba, 0x000006bb, 0x000006bb, 0x000006bb, 0x000006bb, 0x000006d5, 0x00000654, 0x000006d5, 0x00000654, 0x000006c1, 0x000006c1, 0x000006c1, 0x000006c1, 0x000006be, 0x000006be, 0x000006be, 0x000006be, 0x000006d2, 0x000006d2, 0x000006d2, 0x00000654, 0x000006d2, 0x00000654, 0x000006ad, 0x000006ad, 0x000006ad, 0x000006ad, 0x000006c7, 0x000006c7, 0x000006c6, 0x000006c6, 0x000006c8, 0x000006c8, 0x000006c7, 0x00000674, 0x000006cb, 0x000006cb, 0x000006c5, 0x000006c5, 0x000006c9, 0x000006c9, 0x000006d0, 0x000006d0, 0x000006d0, 0x000006d0, 0x00000649, 0x00000649, 0x0000064a, 0x00000654, 0x00000627, 0x0000064a, 0x00000654, 0x00000627, 0x0000064a, 0x00000654, 0x000006d5, 0x0000064a, 0x00000654, 0x000006d5, 0x0000064a, 0x00000654, 0x00000648, 0x0000064a, 0x00000654, 0x00000648, 0x0000064a, 0x00000654, 0x000006c7, 0x0000064a, 0x00000654, 0x000006c7, 0x0000064a, 0x00000654, 0x000006c6, 0x0000064a, 0x00000654, 0x000006c6, 0x0000064a, 0x00000654, 0x000006c8, 0x0000064a, 0x00000654, 0x000006c8, 0x0000064a, 0x00000654, 0x000006d0, 0x0000064a, 0x00000654, 0x000006d0, 0x0000064a, 0x00000654, 0x000006d0, 0x0000064a, 0x00000654, 0x00000649, 0x0000064a, 0x00000654, 0x00000649, 0x0000064a, 0x00000654, 0x00000649, 0x000006cc, 0x000006cc, 0x000006cc, 0x000006cc, 0x0000064a, 0x00000654, 0x0000062c, 0x0000064a, 0x00000654, 0x0000062d, 0x0000064a, 0x00000654, 0x00000645, 0x0000064a, 0x00000654, 0x00000649, 0x0000064a, 0x00000654, 0x0000064a, 0x00000628, 0x0000062c, 0x00000628, 0x0000062d, 0x00000628, 0x0000062e, 0x00000628, 0x00000645, 0x00000628, 0x00000649, 0x00000628, 0x0000064a, 0x0000062a, 0x0000062c, 0x0000062a, 0x0000062d, 0x0000062a, 0x0000062e, 0x0000062a, 0x00000645, 0x0000062a, 0x00000649, 0x0000062a, 0x0000064a, 0x0000062b, 0x0000062c, 0x0000062b, 0x00000645, 0x0000062b, 0x00000649, 0x0000062b, 0x0000064a, 0x0000062c, 0x0000062d, 0x0000062c, 0x00000645, 0x0000062d, 0x0000062c, 0x0000062d, 0x00000645, 0x0000062e, 0x0000062c, 0x0000062e, 0x0000062d, 0x0000062e, 0x00000645, 0x00000633, 0x0000062c, 0x00000633, 0x0000062d, 0x00000633, 0x0000062e, 0x00000633, 0x00000645, 0x00000635, 0x0000062d, 0x00000635, 0x00000645, 0x00000636, 0x0000062c, 0x00000636, 0x0000062d, 0x00000636, 0x0000062e, 0x00000636, 0x00000645, 0x00000637, 0x0000062d, 0x00000637, 0x00000645, 0x00000638, 0x00000645, 0x00000639, 0x0000062c, 0x00000639, 0x00000645, 0x0000063a, 0x0000062c, 0x0000063a, 0x00000645, 0x00000641, 0x0000062c, 0x00000641, 0x0000062d, 0x00000641, 0x0000062e, 0x00000641, 0x00000645, 0x00000641, 0x00000649, 0x00000641, 0x0000064a, 0x00000642, 0x0000062d, 0x00000642, 0x00000645, 0x00000642, 0x00000649, 0x00000642, 0x0000064a, 0x00000643, 0x00000627, 0x00000643, 0x0000062c, 0x00000643, 0x0000062d, 0x00000643, 0x0000062e, 0x00000643, 0x00000644, 0x00000643, 0x00000645, 0x00000643, 0x00000649, 0x00000643, 0x0000064a, 0x00000644, 0x0000062c, 0x00000644, 0x0000062d, 0x00000644, 0x0000062e, 0x00000644, 0x00000645, 0x00000644, 0x00000649, 0x00000644, 0x0000064a, 0x00000645, 0x0000062c, 0x00000645, 0x0000062d, 0x00000645, 0x0000062e, 0x00000645, 0x00000645, 0x00000645, 0x00000649, 0x00000645, 0x0000064a, 0x00000646, 0x0000062c, 0x00000646, 0x0000062d, 0x00000646, 0x0000062e, 0x00000646, 0x00000645, 0x00000646, 0x00000649, 0x00000646, 0x0000064a, 0x00000647, 0x0000062c, 0x00000647, 0x00000645, 0x00000647, 0x00000649, 0x00000647, 0x0000064a, 0x0000064a, 0x0000062c, 0x0000064a, 0x0000062d, 0x0000064a, 0x0000062e, 0x0000064a, 0x00000645, 0x0000064a, 0x00000649, 0x0000064a, 0x0000064a, 0x00000630, 0x00000670, 0x00000631, 0x00000670, 0x00000649, 0x00000670, 0x00000020, 0x0000064c, 0x00000651, 0x00000020, 0x0000064d, 0x00000651, 0x00000020, 0x0000064e, 0x00000651, 0x00000020, 0x0000064f, 0x00000651, 0x00000020, 0x00000650, 0x00000651, 0x00000020, 0x00000651, 0x00000670, 0x0000064a, 0x00000654, 0x00000631, 0x0000064a, 0x00000654, 0x00000632, 0x0000064a, 0x00000654, 0x00000645, 0x0000064a, 0x00000654, 0x00000646, 0x0000064a, 0x00000654, 0x00000649, 0x0000064a, 0x00000654, 0x0000064a, 0x00000628, 0x00000631, 0x00000628, 0x00000632, 0x00000628, 0x00000645, 0x00000628, 0x00000646, 0x00000628, 0x00000649, 0x00000628, 0x0000064a, 0x0000062a, 0x00000631, 0x0000062a, 0x00000632, 0x0000062a, 0x00000645, 0x0000062a, 0x00000646, 0x0000062a, 0x00000649, 0x0000062a, 0x0000064a, 0x0000062b, 0x00000631, 0x0000062b, 0x00000632, 0x0000062b, 0x00000645, 0x0000062b, 0x00000646, 0x0000062b, 0x00000649, 0x0000062b, 0x0000064a, 0x00000641, 0x00000649, 0x00000641, 0x0000064a, 0x00000642, 0x00000649, 0x00000642, 0x0000064a, 0x00000643, 0x00000627, 0x00000643, 0x00000644, 0x00000643, 0x00000645, 0x00000643, 0x00000649, 0x00000643, 0x0000064a, 0x00000644, 0x00000645, 0x00000644, 0x00000649, 0x00000644, 0x0000064a, 0x00000645, 0x00000627, 0x00000645, 0x00000645, 0x00000646, 0x00000631, 0x00000646, 0x00000632, 0x00000646, 0x00000645, 0x00000646, 0x00000646, 0x00000646, 0x00000649, 0x00000646, 0x0000064a, 0x00000649, 0x00000670, 0x0000064a, 0x00000631, 0x0000064a, 0x00000632, 0x0000064a, 0x00000645, 0x0000064a, 0x00000646, 0x0000064a, 0x00000649, 0x0000064a, 0x0000064a, 0x0000064a, 0x00000654, 0x0000062c, 0x0000064a, 0x00000654, 0x0000062d, 0x0000064a, 0x00000654, 0x0000062e, 0x0000064a, 0x00000654, 0x00000645, 0x0000064a, 0x00000654, 0x00000647, 0x00000628, 0x0000062c, 0x00000628, 0x0000062d, 0x00000628, 0x0000062e, 0x00000628, 0x00000645, 0x00000628, 0x00000647, 0x0000062a, 0x0000062c, 0x0000062a, 0x0000062d, 0x0000062a, 0x0000062e, 0x0000062a, 0x00000645, 0x0000062a, 0x00000647, 0x0000062b, 0x00000645, 0x0000062c, 0x0000062d, 0x0000062c, 0x00000645, 0x0000062d, 0x0000062c, 0x0000062d, 0x00000645, 0x0000062e, 0x0000062c, 0x0000062e, 0x00000645, 0x00000633, 0x0000062c, 0x00000633, 0x0000062d, 0x00000633, 0x0000062e, 0x00000633, 0x00000645, 0x00000635, 0x0000062d, 0x00000635, 0x0000062e, 0x00000635, 0x00000645, 0x00000636, 0x0000062c, 0x00000636, 0x0000062d, 0x00000636, 0x0000062e, 0x00000636, 0x00000645, 0x00000637, 0x0000062d, 0x00000638, 0x00000645, 0x00000639, 0x0000062c, 0x00000639, 0x00000645, 0x0000063a, 0x0000062c, 0x0000063a, 0x00000645, 0x00000641, 0x0000062c, 0x00000641, 0x0000062d, 0x00000641, 0x0000062e, 0x00000641, 0x00000645, 0x00000642, 0x0000062d, 0x00000642, 0x00000645, 0x00000643, 0x0000062c, 0x00000643, 0x0000062d, 0x00000643, 0x0000062e, 0x00000643, 0x00000644, 0x00000643, 0x00000645, 0x00000644, 0x0000062c, 0x00000644, 0x0000062d, 0x00000644, 0x0000062e, 0x00000644, 0x00000645, 0x00000644, 0x00000647, 0x00000645, 0x0000062c, 0x00000645, 0x0000062d, 0x00000645, 0x0000062e, 0x00000645, 0x00000645, 0x00000646, 0x0000062c, 0x00000646, 0x0000062d, 0x00000646, 0x0000062e, 0x00000646, 0x00000645, 0x00000646, 0x00000647, 0x00000647, 0x0000062c, 0x00000647, 0x00000645, 0x00000647, 0x00000670, 0x0000064a, 0x0000062c, 0x0000064a, 0x0000062d, 0x0000064a, 0x0000062e, 0x0000064a, 0x00000645, 0x0000064a, 0x00000647, 0x0000064a, 0x00000654, 0x00000645, 0x0000064a, 0x00000654, 0x00000647, 0x00000628, 0x00000645, 0x00000628, 0x00000647, 0x0000062a, 0x00000645, 0x0000062a, 0x00000647, 0x0000062b, 0x00000645, 0x0000062b, 0x00000647, 0x00000633, 0x00000645, 0x00000633, 0x00000647, 0x00000634, 0x00000645, 0x00000634, 0x00000647, 0x00000643, 0x00000644, 0x00000643, 0x00000645, 0x00000644, 0x00000645, 0x00000646, 0x00000645, 0x00000646, 0x00000647, 0x0000064a, 0x00000645, 0x0000064a, 0x00000647, 0x00000640, 0x0000064e, 0x00000651, 0x00000640, 0x0000064f, 0x00000651, 0x00000640, 0x00000650, 0x00000651, 0x00000637, 0x00000649, 0x00000637, 0x0000064a, 0x00000639, 0x00000649, 0x00000639, 0x0000064a, 0x0000063a, 0x00000649, 0x0000063a, 0x0000064a, 0x00000633, 0x00000649, 0x00000633, 0x0000064a, 0x00000634, 0x00000649, 0x00000634, 0x0000064a, 0x0000062d, 0x00000649, 0x0000062d, 0x0000064a, 0x0000062c, 0x00000649, 0x0000062c, 0x0000064a, 0x0000062e, 0x00000649, 0x0000062e, 0x0000064a, 0x00000635, 0x00000649, 0x00000635, 0x0000064a, 0x00000636, 0x00000649, 0x00000636, 0x0000064a, 0x00000634, 0x0000062c, 0x00000634, 0x0000062d, 0x00000634, 0x0000062e, 0x00000634, 0x00000645, 0x00000634, 0x00000631, 0x00000633, 0x00000631, 0x00000635, 0x00000631, 0x00000636, 0x00000631, 0x00000637, 0x00000649, 0x00000637, 0x0000064a, 0x00000639, 0x00000649, 0x00000639, 0x0000064a, 0x0000063a, 0x00000649, 0x0000063a, 0x0000064a, 0x00000633, 0x00000649, 0x00000633, 0x0000064a, 0x00000634, 0x00000649, 0x00000634, 0x0000064a, 0x0000062d, 0x00000649, 0x0000062d, 0x0000064a, 0x0000062c, 0x00000649, 0x0000062c, 0x0000064a, 0x0000062e, 0x00000649, 0x0000062e, 0x0000064a, 0x00000635, 0x00000649, 0x00000635, 0x0000064a, 0x00000636, 0x00000649, 0x00000636, 0x0000064a, 0x00000634, 0x0000062c, 0x00000634, 0x0000062d, 0x00000634, 0x0000062e, 0x00000634, 0x00000645, 0x00000634, 0x00000631, 0x00000633, 0x00000631, 0x00000635, 0x00000631, 0x00000636, 0x00000631, 0x00000634, 0x0000062c, 0x00000634, 0x0000062d, 0x00000634, 0x0000062e, 0x00000634, 0x00000645, 0x00000633, 0x00000647, 0x00000634, 0x00000647, 0x00000637, 0x00000645, 0x00000633, 0x0000062c, 0x00000633, 0x0000062d, 0x00000633, 0x0000062e, 0x00000634, 0x0000062c, 0x00000634, 0x0000062d, 0x00000634, 0x0000062e, 0x00000637, 0x00000645, 0x00000638, 0x00000645, 0x00000627, 0x0000064b, 0x00000627, 0x0000064b, 0x0000062a, 0x0000062c, 0x00000645, 0x0000062a, 0x0000062d, 0x0000062c, 0x0000062a, 0x0000062d, 0x0000062c, 0x0000062a, 0x0000062d, 0x00000645, 0x0000062a, 0x0000062e, 0x00000645, 0x0000062a, 0x00000645, 0x0000062c, 0x0000062a, 0x00000645, 0x0000062d, 0x0000062a, 0x00000645, 0x0000062e, 0x0000062c, 0x00000645, 0x0000062d, 0x0000062c, 0x00000645, 0x0000062d, 0x0000062d, 0x00000645, 0x0000064a, 0x0000062d, 0x00000645, 0x00000649, 0x00000633, 0x0000062d, 0x0000062c, 0x00000633, 0x0000062c, 0x0000062d, 0x00000633, 0x0000062c, 0x00000649, 0x00000633, 0x00000645, 0x0000062d, 0x00000633, 0x00000645, 0x0000062d, 0x00000633, 0x00000645, 0x0000062c, 0x00000633, 0x00000645, 0x00000645, 0x00000633, 0x00000645, 0x00000645, 0x00000635, 0x0000062d, 0x0000062d, 0x00000635, 0x0000062d, 0x0000062d, 0x00000635, 0x00000645, 0x00000645, 0x00000634, 0x0000062d, 0x00000645, 0x00000634, 0x0000062d, 0x00000645, 0x00000634, 0x0000062c, 0x0000064a, 0x00000634, 0x00000645, 0x0000062e, 0x00000634, 0x00000645, 0x0000062e, 0x00000634, 0x00000645, 0x00000645, 0x00000634, 0x00000645, 0x00000645, 0x00000636, 0x0000062d, 0x00000649, 0x00000636, 0x0000062e, 0x00000645, 0x00000636, 0x0000062e, 0x00000645, 0x00000637, 0x00000645, 0x0000062d, 0x00000637, 0x00000645, 0x0000062d, 0x00000637, 0x00000645, 0x00000645, 0x00000637, 0x00000645, 0x0000064a, 0x00000639, 0x0000062c, 0x00000645, 0x00000639, 0x00000645, 0x00000645, 0x00000639, 0x00000645, 0x00000645, 0x00000639, 0x00000645, 0x00000649, 0x0000063a, 0x00000645, 0x00000645, 0x0000063a, 0x00000645, 0x0000064a, 0x0000063a, 0x00000645, 0x00000649, 0x00000641, 0x0000062e, 0x00000645, 0x00000641, 0x0000062e, 0x00000645, 0x00000642, 0x00000645, 0x0000062d, 0x00000642, 0x00000645, 0x00000645, 0x00000644, 0x0000062d, 0x00000645, 0x00000644, 0x0000062d, 0x0000064a, 0x00000644, 0x0000062d, 0x00000649, 0x00000644, 0x0000062c, 0x0000062c, 0x00000644, 0x0000062c, 0x0000062c, 0x00000644, 0x0000062e, 0x00000645, 0x00000644, 0x0000062e, 0x00000645, 0x00000644, 0x00000645, 0x0000062d, 0x00000644, 0x00000645, 0x0000062d, 0x00000645, 0x0000062d, 0x0000062c, 0x00000645, 0x0000062d, 0x00000645, 0x00000645, 0x0000062d, 0x0000064a, 0x00000645, 0x0000062c, 0x0000062d, 0x00000645, 0x0000062c, 0x00000645, 0x00000645, 0x0000062e, 0x0000062c, 0x00000645, 0x0000062e, 0x00000645, 0x00000645, 0x0000062c, 0x0000062e, 0x00000647, 0x00000645, 0x0000062c, 0x00000647, 0x00000645, 0x00000645, 0x00000646, 0x0000062d, 0x00000645, 0x00000646, 0x0000062d, 0x00000649, 0x00000646, 0x0000062c, 0x00000645, 0x00000646, 0x0000062c, 0x00000645, 0x00000646, 0x0000062c, 0x00000649, 0x00000646, 0x00000645, 0x0000064a, 0x00000646, 0x00000645, 0x00000649, 0x0000064a, 0x00000645, 0x00000645, 0x0000064a, 0x00000645, 0x00000645, 0x00000628, 0x0000062e, 0x0000064a, 0x0000062a, 0x0000062c, 0x0000064a, 0x0000062a, 0x0000062c, 0x00000649, 0x0000062a, 0x0000062e, 0x0000064a, 0x0000062a, 0x0000062e, 0x00000649, 0x0000062a, 0x00000645, 0x0000064a, 0x0000062a, 0x00000645, 0x00000649, 0x0000062c, 0x00000645, 0x0000064a, 0x0000062c, 0x0000062d, 0x00000649, 0x0000062c, 0x00000645, 0x00000649, 0x00000633, 0x0000062e, 0x00000649, 0x00000635, 0x0000062d, 0x0000064a, 0x00000634, 0x0000062d, 0x0000064a, 0x00000636, 0x0000062d, 0x0000064a, 0x00000644, 0x0000062c, 0x0000064a, 0x00000644, 0x00000645, 0x0000064a, 0x0000064a, 0x0000062d, 0x0000064a, 0x0000064a, 0x0000062c, 0x0000064a, 0x0000064a, 0x00000645, 0x0000064a, 0x00000645, 0x00000645, 0x0000064a, 0x00000642, 0x00000645, 0x0000064a, 0x00000646, 0x0000062d, 0x0000064a, 0x00000642, 0x00000645, 0x0000062d, 0x00000644, 0x0000062d, 0x00000645, 0x00000639, 0x00000645, 0x0000064a, 0x00000643, 0x00000645, 0x0000064a, 0x00000646, 0x0000062c, 0x0000062d, 0x00000645, 0x0000062e, 0x0000064a, 0x00000644, 0x0000062c, 0x00000645, 0x00000643, 0x00000645, 0x00000645, 0x00000644, 0x0000062c, 0x00000645, 0x00000646, 0x0000062c, 0x0000062d, 0x0000062c, 0x0000062d, 0x0000064a, 0x0000062d, 0x0000062c, 0x0000064a, 0x00000645, 0x0000062c, 0x0000064a, 0x00000641, 0x00000645, 0x0000064a, 0x00000628, 0x0000062d, 0x0000064a, 0x00000643, 0x00000645, 0x00000645, 0x00000639, 0x0000062c, 0x00000645, 0x00000635, 0x00000645, 0x00000645, 0x00000633, 0x0000062e, 0x0000064a, 0x00000646, 0x0000062c, 0x0000064a, 0x00000635, 0x00000644, 0x000006d2, 0x00000642, 0x00000644, 0x000006d2, 0x00000627, 0x00000644, 0x00000644, 0x00000647, 0x00000627, 0x00000643, 0x00000628, 0x00000631, 0x00000645, 0x0000062d, 0x00000645, 0x0000062f, 0x00000635, 0x00000644, 0x00000639, 0x00000645, 0x00000631, 0x00000633, 0x00000648, 0x00000644, 0x00000639, 0x00000644, 0x0000064a, 0x00000647, 0x00000648, 0x00000633, 0x00000644, 0x00000645, 0x00000635, 0x00000644, 0x00000649, 0x00000635, 0x00000644, 0x00000649, 0x00000020, 0x00000627, 0x00000644, 0x00000644, 0x00000647, 0x00000020, 0x00000639, 0x00000644, 0x0000064a, 0x00000647, 0x00000020, 0x00000648, 0x00000633, 0x00000644, 0x00000645, 0x0000062c, 0x00000644, 0x00000020, 0x0000062c, 0x00000644, 0x00000627, 0x00000644, 0x00000647, 0x00000631, 0x000006cc, 0x00000627, 0x00000644, 0x0000002e, 0x0000002e, 0x00002014, 0x00002013, 0x0000005f, 0x0000005f, 0x00000028, 0x00000029, 0x0000007b, 0x0000007d, 0x00003014, 0x00003015, 0x00003010, 0x00003011, 0x0000300a, 0x0000300b, 0x00003008, 0x00003009, 0x0000300c, 0x0000300d, 0x0000300e, 0x0000300f, 0x00000020, 0x00000305, 0x00000020, 0x00000305, 0x00000020, 0x00000305, 0x00000020, 0x00000305, 0x0000005f, 0x0000005f, 0x0000005f, 0x0000002c, 0x00003001, 0x0000002e, 0x0000003b, 0x0000003a, 0x0000003f, 0x00000021, 0x00002014, 0x00000028, 0x00000029, 0x0000007b, 0x0000007d, 0x00003014, 0x00003015, 0x00000023, 0x00000026, 0x0000002a, 0x0000002b, 0x0000002d, 0x0000003c, 0x0000003e, 0x0000003d, 0x0000005c, 0x00000024, 0x00000025, 0x00000040, 0x00000020, 0x0000064b, 0x00000640, 0x0000064b, 0x00000020, 0x0000064c, 0x00000020, 0x0000064d, 0x00000020, 0x0000064e, 0x00000640, 0x0000064e, 0x00000020, 0x0000064f, 0x00000640, 0x0000064f, 0x00000020, 0x00000650, 0x00000640, 0x00000650, 0x00000020, 0x00000651, 0x00000640, 0x00000651, 0x00000020, 0x00000652, 0x00000640, 0x00000652, 0x00000621, 0x00000627, 0x00000653, 0x00000627, 0x00000653, 0x00000627, 0x00000654, 0x00000627, 0x00000654, 0x00000648, 0x00000654, 0x00000648, 0x00000654, 0x00000627, 0x00000655, 0x00000627, 0x00000655, 0x0000064a, 0x00000654, 0x0000064a, 0x00000654, 0x0000064a, 0x00000654, 0x0000064a, 0x00000654, 0x00000627, 0x00000627, 0x00000628, 0x00000628, 0x00000628, 0x00000628, 0x00000629, 0x00000629, 0x0000062a, 0x0000062a, 0x0000062a, 0x0000062a, 0x0000062b, 0x0000062b, 0x0000062b, 0x0000062b, 0x0000062c, 0x0000062c, 0x0000062c, 0x0000062c, 0x0000062d, 0x0000062d, 0x0000062d, 0x0000062d, 0x0000062e, 0x0000062e, 0x0000062e, 0x0000062e, 0x0000062f, 0x0000062f, 0x00000630, 0x00000630, 0x00000631, 0x00000631, 0x00000632, 0x00000632, 0x00000633, 0x00000633, 0x00000633, 0x00000633, 0x00000634, 0x00000634, 0x00000634, 0x00000634, 0x00000635, 0x00000635, 0x00000635, 0x00000635, 0x00000636, 0x00000636, 0x00000636, 0x00000636, 0x00000637, 0x00000637, 0x00000637, 0x00000637, 0x00000638, 0x00000638, 0x00000638, 0x00000638, 0x00000639, 0x00000639, 0x00000639, 0x00000639, 0x0000063a, 0x0000063a, 0x0000063a, 0x0000063a, 0x00000641, 0x00000641, 0x00000641, 0x00000641, 0x00000642, 0x00000642, 0x00000642, 0x00000642, 0x00000643, 0x00000643, 0x00000643, 0x00000643, 0x00000644, 0x00000644, 0x00000644, 0x00000644, 0x00000645, 0x00000645, 0x00000645, 0x00000645, 0x00000646, 0x00000646, 0x00000646, 0x00000646, 0x00000647, 0x00000647, 0x00000647, 0x00000647, 0x00000648, 0x00000648, 0x00000649, 0x00000649, 0x0000064a, 0x0000064a, 0x0000064a, 0x0000064a, 0x00000644, 0x00000627, 0x00000653, 0x00000644, 0x00000627, 0x00000653, 0x00000644, 0x00000627, 0x00000654, 0x00000644, 0x00000627, 0x00000654, 0x00000644, 0x00000627, 0x00000655, 0x00000644, 0x00000627, 0x00000655, 0x00000644, 0x00000627, 0x00000644, 0x00000627, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000026, 0x00000027, 0x00000028, 0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d, 0x0000002e, 0x0000002f, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x0000003a, 0x0000003b, 0x0000003c, 0x0000003d, 0x0000003e, 0x0000003f, 0x00000040, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x0000005b, 0x0000005c, 0x0000005d, 0x0000005e, 0x0000005f, 0x00000060, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x0000007b, 0x0000007c, 0x0000007d, 0x0000007e, 0x00002985, 0x00002986, 0x00003002, 0x0000300c, 0x0000300d, 0x00003001, 0x000030fb, 0x000030f2, 0x000030a1, 0x000030a3, 0x000030a5, 0x000030a7, 0x000030a9, 0x000030e3, 0x000030e5, 0x000030e7, 0x000030c3, 0x000030fc, 0x000030a2, 0x000030a4, 0x000030a6, 0x000030a8, 0x000030aa, 0x000030ab, 0x000030ad, 0x000030af, 0x000030b1, 0x000030b3, 0x000030b5, 0x000030b7, 0x000030b9, 0x000030bb, 0x000030bd, 0x000030bf, 0x000030c1, 0x000030c4, 0x000030c6, 0x000030c8, 0x000030ca, 0x000030cb, 0x000030cc, 0x000030cd, 0x000030ce, 0x000030cf, 0x000030d2, 0x000030d5, 0x000030d8, 0x000030db, 0x000030de, 0x000030df, 0x000030e0, 0x000030e1, 0x000030e2, 0x000030e4, 0x000030e6, 0x000030e8, 0x000030e9, 0x000030ea, 0x000030eb, 0x000030ec, 0x000030ed, 0x000030ef, 0x000030f3, 0x00003099, 0x0000309a, 0x00001160, 0x00001100, 0x00001101, 0x000011aa, 0x00001102, 0x000011ac, 0x000011ad, 0x00001103, 0x00001104, 0x00001105, 0x000011b0, 0x000011b1, 0x000011b2, 0x000011b3, 0x000011b4, 0x000011b5, 0x0000111a, 0x00001106, 0x00001107, 0x00001108, 0x00001121, 0x00001109, 0x0000110a, 0x0000110b, 0x0000110c, 0x0000110d, 0x0000110e, 0x0000110f, 0x00001110, 0x00001111, 0x00001112, 0x00001161, 0x00001162, 0x00001163, 0x00001164, 0x00001165, 0x00001166, 0x00001167, 0x00001168, 0x00001169, 0x0000116a, 0x0000116b, 0x0000116c, 0x0000116d, 0x0000116e, 0x0000116f, 0x00001170, 0x00001171, 0x00001172, 0x00001173, 0x00001174, 0x00001175, 0x000000a2, 0x000000a3, 0x000000ac, 0x00000020, 0x00000304, 0x000000a6, 0x000000a5, 0x000020a9, 0x00002502, 0x00002190, 0x00002191, 0x00002192, 0x00002193, 0x000025a0, 0x000025cb, 0x0001d157, 0x0001d165, 0x0001d158, 0x0001d165, 0x0001d158, 0x0001d165, 0x0001d16e, 0x0001d158, 0x0001d165, 0x0001d16f, 0x0001d158, 0x0001d165, 0x0001d170, 0x0001d158, 0x0001d165, 0x0001d171, 0x0001d158, 0x0001d165, 0x0001d172, 0x0001d1b9, 0x0001d165, 0x0001d1ba, 0x0001d165, 0x0001d1b9, 0x0001d165, 0x0001d16e, 0x0001d1ba, 0x0001d165, 0x0001d16e, 0x0001d1b9, 0x0001d165, 0x0001d16f, 0x0001d1ba, 0x0001d165, 0x0001d16f, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000043, 0x00000044, 0x00000047, 0x0000004a, 0x0000004b, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000066, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006d, 0x0000006e, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004f, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 0x00000048, 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c, 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 0x00000058, 0x00000059, 0x0000005a, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006a, 0x0000006b, 0x0000006c, 0x0000006d, 0x0000006e, 0x0000006f, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007a, 0x00000391, 0x00000392, 0x00000393, 0x00000394, 0x00000395, 0x00000396, 0x00000397, 0x00000398, 0x00000399, 0x0000039a, 0x0000039b, 0x0000039c, 0x0000039d, 0x0000039e, 0x0000039f, 0x000003a0, 0x000003a1, 0x00000398, 0x000003a3, 0x000003a4, 0x000003a5, 0x000003a6, 0x000003a7, 0x000003a8, 0x000003a9, 0x00002207, 0x000003b1, 0x000003b2, 0x000003b3, 0x000003b4, 0x000003b5, 0x000003b6, 0x000003b7, 0x000003b8, 0x000003b9, 0x000003ba, 0x000003bb, 0x000003bc, 0x000003bd, 0x000003be, 0x000003bf, 0x000003c0, 0x000003c1, 0x000003c2, 0x000003c3, 0x000003c4, 0x000003c5, 0x000003c6, 0x000003c7, 0x000003c8, 0x000003c9, 0x00002202, 0x000003b5, 0x000003b8, 0x000003ba, 0x000003c6, 0x000003c1, 0x000003c0, 0x00000391, 0x00000392, 0x00000393, 0x00000394, 0x00000395, 0x00000396, 0x00000397, 0x00000398, 0x00000399, 0x0000039a, 0x0000039b, 0x0000039c, 0x0000039d, 0x0000039e, 0x0000039f, 0x000003a0, 0x000003a1, 0x00000398, 0x000003a3, 0x000003a4, 0x000003a5, 0x000003a6, 0x000003a7, 0x000003a8, 0x000003a9, 0x00002207, 0x000003b1, 0x000003b2, 0x000003b3, 0x000003b4, 0x000003b5, 0x000003b6, 0x000003b7, 0x000003b8, 0x000003b9, 0x000003ba, 0x000003bb, 0x000003bc, 0x000003bd, 0x000003be, 0x000003bf, 0x000003c0, 0x000003c1, 0x000003c2, 0x000003c3, 0x000003c4, 0x000003c5, 0x000003c6, 0x000003c7, 0x000003c8, 0x000003c9, 0x00002202, 0x000003b5, 0x000003b8, 0x000003ba, 0x000003c6, 0x000003c1, 0x000003c0, 0x00000391, 0x00000392, 0x00000393, 0x00000394, 0x00000395, 0x00000396, 0x00000397, 0x00000398, 0x00000399, 0x0000039a, 0x0000039b, 0x0000039c, 0x0000039d, 0x0000039e, 0x0000039f, 0x000003a0, 0x000003a1, 0x00000398, 0x000003a3, 0x000003a4, 0x000003a5, 0x000003a6, 0x000003a7, 0x000003a8, 0x000003a9, 0x00002207, 0x000003b1, 0x000003b2, 0x000003b3, 0x000003b4, 0x000003b5, 0x000003b6, 0x000003b7, 0x000003b8, 0x000003b9, 0x000003ba, 0x000003bb, 0x000003bc, 0x000003bd, 0x000003be, 0x000003bf, 0x000003c0, 0x000003c1, 0x000003c2, 0x000003c3, 0x000003c4, 0x000003c5, 0x000003c6, 0x000003c7, 0x000003c8, 0x000003c9, 0x00002202, 0x000003b5, 0x000003b8, 0x000003ba, 0x000003c6, 0x000003c1, 0x000003c0, 0x00000391, 0x00000392, 0x00000393, 0x00000394, 0x00000395, 0x00000396, 0x00000397, 0x00000398, 0x00000399, 0x0000039a, 0x0000039b, 0x0000039c, 0x0000039d, 0x0000039e, 0x0000039f, 0x000003a0, 0x000003a1, 0x00000398, 0x000003a3, 0x000003a4, 0x000003a5, 0x000003a6, 0x000003a7, 0x000003a8, 0x000003a9, 0x00002207, 0x000003b1, 0x000003b2, 0x000003b3, 0x000003b4, 0x000003b5, 0x000003b6, 0x000003b7, 0x000003b8, 0x000003b9, 0x000003ba, 0x000003bb, 0x000003bc, 0x000003bd, 0x000003be, 0x000003bf, 0x000003c0, 0x000003c1, 0x000003c2, 0x000003c3, 0x000003c4, 0x000003c5, 0x000003c6, 0x000003c7, 0x000003c8, 0x000003c9, 0x00002202, 0x000003b5, 0x000003b8, 0x000003ba, 0x000003c6, 0x000003c1, 0x000003c0, 0x00000391, 0x00000392, 0x00000393, 0x00000394, 0x00000395, 0x00000396, 0x00000397, 0x00000398, 0x00000399, 0x0000039a, 0x0000039b, 0x0000039c, 0x0000039d, 0x0000039e, 0x0000039f, 0x000003a0, 0x000003a1, 0x00000398, 0x000003a3, 0x000003a4, 0x000003a5, 0x000003a6, 0x000003a7, 0x000003a8, 0x000003a9, 0x00002207, 0x000003b1, 0x000003b2, 0x000003b3, 0x000003b4, 0x000003b5, 0x000003b6, 0x000003b7, 0x000003b8, 0x000003b9, 0x000003ba, 0x000003bb, 0x000003bc, 0x000003bd, 0x000003be, 0x000003bf, 0x000003c0, 0x000003c1, 0x000003c2, 0x000003c3, 0x000003c4, 0x000003c5, 0x000003c6, 0x000003c7, 0x000003c8, 0x000003c9, 0x00002202, 0x000003b5, 0x000003b8, 0x000003ba, 0x000003c6, 0x000003c1, 0x000003c0, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 0x00000038, 0x00000039, 0x00004e3d, 0x00004e38, 0x00004e41, 0x00020122, 0x00004f60, 0x00004fae, 0x00004fbb, 0x00005002, 0x0000507a, 0x00005099, 0x000050e7, 0x000050cf, 0x0000349e, 0x0002063a, 0x0000514d, 0x00005154, 0x00005164, 0x00005177, 0x0002051c, 0x000034b9, 0x00005167, 0x0000518d, 0x0002054b, 0x00005197, 0x000051a4, 0x00004ecc, 0x000051ac, 0x000051b5, 0x000291df, 0x000051f5, 0x00005203, 0x000034df, 0x0000523b, 0x00005246, 0x00005272, 0x00005277, 0x00003515, 0x000052c7, 0x000052c9, 0x000052e4, 0x000052fa, 0x00005305, 0x00005306, 0x00005317, 0x00005349, 0x00005351, 0x0000535a, 0x00005373, 0x0000537d, 0x0000537f, 0x0000537f, 0x0000537f, 0x00020a2c, 0x00007070, 0x000053ca, 0x000053df, 0x00020b63, 0x000053eb, 0x000053f1, 0x00005406, 0x0000549e, 0x00005438, 0x00005448, 0x00005468, 0x000054a2, 0x000054f6, 0x00005510, 0x00005553, 0x00005563, 0x00005584, 0x00005584, 0x00005599, 0x000055ab, 0x000055b3, 0x000055c2, 0x00005716, 0x00005606, 0x00005717, 0x00005651, 0x00005674, 0x00005207, 0x000058ee, 0x000057ce, 0x000057f4, 0x0000580d, 0x0000578b, 0x00005832, 0x00005831, 0x000058ac, 0x000214e4, 0x000058f2, 0x000058f7, 0x00005906, 0x0000591a, 0x00005922, 0x00005962, 0x000216a8, 0x000216ea, 0x000059ec, 0x00005a1b, 0x00005a27, 0x000059d8, 0x00005a66, 0x000036ee, 0x0002136a, 0x00005b08, 0x00005b3e, 0x00005b3e, 0x000219c8, 0x00005bc3, 0x00005bd8, 0x00005be7, 0x00005bf3, 0x00021b18, 0x00005bff, 0x00005c06, 0x00005f33, 0x00005c22, 0x00003781, 0x00005c60, 0x00005c6e, 0x00005cc0, 0x00005c8d, 0x00021de4, 0x00005d43, 0x00021de6, 0x00005d6e, 0x00005d6b, 0x00005d7c, 0x00005de1, 0x00005de2, 0x0000382f, 0x00005dfd, 0x00005e28, 0x00005e3d, 0x00005e69, 0x00003862, 0x00022183, 0x0000387c, 0x00005eb0, 0x00005eb3, 0x00005eb6, 0x00005eca, 0x0002a392, 0x00005efe, 0x00022331, 0x00022331, 0x00008201, 0x00005f22, 0x00005f22, 0x000038c7, 0x000232b8, 0x000261da, 0x00005f62, 0x00005f6b, 0x000038e3, 0x00005f9a, 0x00005fcd, 0x00005fd7, 0x00005ff9, 0x00006081, 0x0000393a, 0x0000391c, 0x00006094, 0x000226d4, 0x000060c7, 0x00006148, 0x0000614c, 0x0000614e, 0x0000614c, 0x0000617a, 0x0000618e, 0x000061b2, 0x000061a4, 0x000061af, 0x000061de, 0x000061f2, 0x000061f6, 0x00006210, 0x0000621b, 0x0000625d, 0x000062b1, 0x000062d4, 0x00006350, 0x00022b0c, 0x0000633d, 0x000062fc, 0x00006368, 0x00006383, 0x000063e4, 0x00022bf1, 0x00006422, 0x000063c5, 0x000063a9, 0x00003a2e, 0x00006469, 0x0000647e, 0x0000649d, 0x00006477, 0x00003a6c, 0x0000654f, 0x0000656c, 0x0002300a, 0x000065e3, 0x000066f8, 0x00006649, 0x00003b19, 0x00006691, 0x00003b08, 0x00003ae4, 0x00005192, 0x00005195, 0x00006700, 0x0000669c, 0x000080ad, 0x000043d9, 0x00006717, 0x0000671b, 0x00006721, 0x0000675e, 0x00006753, 0x000233c3, 0x00003b49, 0x000067fa, 0x00006785, 0x00006852, 0x00006885, 0x0002346d, 0x0000688e, 0x0000681f, 0x00006914, 0x00003b9d, 0x00006942, 0x000069a3, 0x000069ea, 0x00006aa8, 0x000236a3, 0x00006adb, 0x00003c18, 0x00006b21, 0x000238a7, 0x00006b54, 0x00003c4e, 0x00006b72, 0x00006b9f, 0x00006bba, 0x00006bbb, 0x00023a8d, 0x00021d0b, 0x00023afa, 0x00006c4e, 0x00023cbc, 0x00006cbf, 0x00006ccd, 0x00006c67, 0x00006d16, 0x00006d3e, 0x00006d77, 0x00006d41, 0x00006d69, 0x00006d78, 0x00006d85, 0x00023d1e, 0x00006d34, 0x00006e2f, 0x00006e6e, 0x00003d33, 0x00006ecb, 0x00006ec7, 0x00023ed1, 0x00006df9, 0x00006f6e, 0x00023f5e, 0x00023f8e, 0x00006fc6, 0x00007039, 0x0000701e, 0x0000701b, 0x00003d96, 0x0000704a, 0x0000707d, 0x00007077, 0x000070ad, 0x00020525, 0x00007145, 0x00024263, 0x0000719c, 0x000043ab, 0x00007228, 0x00007235, 0x00007250, 0x00024608, 0x00007280, 0x00007295, 0x00024735, 0x00024814, 0x0000737a, 0x0000738b, 0x00003eac, 0x000073a5, 0x00003eb8, 0x00003eb8, 0x00007447, 0x0000745c, 0x00007471, 0x00007485, 0x000074ca, 0x00003f1b, 0x00007524, 0x00024c36, 0x0000753e, 0x00024c92, 0x00007570, 0x0002219f, 0x00007610, 0x00024fa1, 0x00024fb8, 0x00025044, 0x00003ffc, 0x00004008, 0x000076f4, 0x000250f3, 0x000250f2, 0x00025119, 0x00025133, 0x0000771e, 0x0000771f, 0x0000771f, 0x0000774a, 0x00004039, 0x0000778b, 0x00004046, 0x00004096, 0x0002541d, 0x0000784e, 0x0000788c, 0x000078cc, 0x000040e3, 0x00025626, 0x00007956, 0x0002569a, 0x000256c5, 0x0000798f, 0x000079eb, 0x0000412f, 0x00007a40, 0x00007a4a, 0x00007a4f, 0x0002597c, 0x00025aa7, 0x00025aa7, 0x00007aae, 0x00004202, 0x00025bab, 0x00007bc6, 0x00007bc9, 0x00004227, 0x00025c80, 0x00007cd2, 0x000042a0, 0x00007ce8, 0x00007ce3, 0x00007d00, 0x00025f86, 0x00007d63, 0x00004301, 0x00007dc7, 0x00007e02, 0x00007e45, 0x00004334, 0x00026228, 0x00026247, 0x00004359, 0x000262d9, 0x00007f7a, 0x0002633e, 0x00007f95, 0x00007ffa, 0x00008005, 0x000264da, 0x00026523, 0x00008060, 0x000265a8, 0x00008070, 0x0002335f, 0x000043d5, 0x000080b2, 0x00008103, 0x0000440b, 0x0000813e, 0x00005ab5, 0x000267a7, 0x000267b5, 0x00023393, 0x0002339c, 0x00008201, 0x00008204, 0x00008f9e, 0x0000446b, 0x00008291, 0x0000828b, 0x0000829d, 0x000052b3, 0x000082b1, 0x000082b3, 0x000082bd, 0x000082e6, 0x00026b3c, 0x000082e5, 0x0000831d, 0x00008363, 0x000083ad, 0x00008323, 0x000083bd, 0x000083e7, 0x00008457, 0x00008353, 0x000083ca, 0x000083cc, 0x000083dc, 0x00026c36, 0x00026d6b, 0x00026cd5, 0x0000452b, 0x000084f1, 0x000084f3, 0x00008516, 0x000273ca, 0x00008564, 0x00026f2c, 0x0000455d, 0x00004561, 0x00026fb1, 0x000270d2, 0x0000456b, 0x00008650, 0x0000865c, 0x00008667, 0x00008669, 0x000086a9, 0x00008688, 0x0000870e, 0x000086e2, 0x00008779, 0x00008728, 0x0000876b, 0x00008786, 0x00004d57, 0x000087e1, 0x00008801, 0x000045f9, 0x00008860, 0x00008863, 0x00027667, 0x000088d7, 0x000088de, 0x00004635, 0x000088fa, 0x000034bb, 0x000278ae, 0x00027966, 0x000046be, 0x000046c7, 0x00008aa0, 0x00008aed, 0x00008b8a, 0x00008c55, 0x00027ca8, 0x00008cab, 0x00008cc1, 0x00008d1b, 0x00008d77, 0x00027f2f, 0x00020804, 0x00008dcb, 0x00008dbc, 0x00008df0, 0x000208de, 0x00008ed4, 0x00008f38, 0x000285d2, 0x000285ed, 0x00009094, 0x000090f1, 0x00009111, 0x0002872e, 0x0000911b, 0x00009238, 0x000092d7, 0x000092d8, 0x0000927c, 0x000093f9, 0x00009415, 0x00028bfa, 0x0000958b, 0x00004995, 0x000095b7, 0x00028d77, 0x000049e6, 0x000096c3, 0x00005db2, 0x00009723, 0x00029145, 0x0002921a, 0x00004a6e, 0x00004a76, 0x000097e0, 0x0002940a, 0x00004ab2, 0x00029496, 0x0000980b, 0x0000980b, 0x00009829, 0x000295b6, 0x000098e2, 0x00004b33, 0x00009929, 0x000099a7, 0x000099c2, 0x000099fe, 0x00004bce, 0x00029b30, 0x00009b12, 0x00009c40, 0x00009cfd, 0x00004cce, 0x00004ced, 0x00009d67, 0x0002a0ce, 0x00004cf8, 0x0002a105, 0x0002a20e, 0x0002a291, 0x00009ebb, 0x00004d56, 0x00009ef9, 0x00009efe, 0x00009f05, 0x00009f0f, 0x00009f16, 0x00009f3b, 0x0002a600 }; static const krb5_ui_4 _uccmcl_size = 489; static const krb5_ui_4 _uccmcl_nodes[] = { 0x00000300, 0x00000314, 0x000000e6, 0x00000315, 0x00000315, 0x000000e8, 0x00000316, 0x00000319, 0x000000dc, 0x0000031a, 0x0000031a, 0x000000e8, 0x0000031b, 0x0000031b, 0x000000d8, 0x0000031c, 0x00000320, 0x000000dc, 0x00000321, 0x00000322, 0x000000ca, 0x00000323, 0x00000326, 0x000000dc, 0x00000327, 0x00000328, 0x000000ca, 0x00000329, 0x00000333, 0x000000dc, 0x00000334, 0x00000338, 0x00000001, 0x00000339, 0x0000033c, 0x000000dc, 0x0000033d, 0x00000344, 0x000000e6, 0x00000345, 0x00000345, 0x000000f0, 0x00000346, 0x00000346, 0x000000e6, 0x00000347, 0x00000349, 0x000000dc, 0x0000034a, 0x0000034c, 0x000000e6, 0x0000034d, 0x0000034e, 0x000000dc, 0x00000360, 0x00000361, 0x000000ea, 0x00000362, 0x00000362, 0x000000e9, 0x00000363, 0x0000036f, 0x000000e6, 0x00000483, 0x00000486, 0x000000e6, 0x00000591, 0x00000591, 0x000000dc, 0x00000592, 0x00000595, 0x000000e6, 0x00000596, 0x00000596, 0x000000dc, 0x00000597, 0x00000599, 0x000000e6, 0x0000059a, 0x0000059a, 0x000000de, 0x0000059b, 0x0000059b, 0x000000dc, 0x0000059c, 0x000005a1, 0x000000e6, 0x000005a3, 0x000005a7, 0x000000dc, 0x000005a8, 0x000005a9, 0x000000e6, 0x000005aa, 0x000005aa, 0x000000dc, 0x000005ab, 0x000005ac, 0x000000e6, 0x000005ad, 0x000005ad, 0x000000de, 0x000005ae, 0x000005ae, 0x000000e4, 0x000005af, 0x000005af, 0x000000e6, 0x000005b0, 0x000005b0, 0x0000000a, 0x000005b1, 0x000005b1, 0x0000000b, 0x000005b2, 0x000005b2, 0x0000000c, 0x000005b3, 0x000005b3, 0x0000000d, 0x000005b4, 0x000005b4, 0x0000000e, 0x000005b5, 0x000005b5, 0x0000000f, 0x000005b6, 0x000005b6, 0x00000010, 0x000005b7, 0x000005b7, 0x00000011, 0x000005b8, 0x000005b8, 0x00000012, 0x000005b9, 0x000005b9, 0x00000013, 0x000005bb, 0x000005bb, 0x00000014, 0x000005bc, 0x000005bc, 0x00000015, 0x000005bd, 0x000005bd, 0x00000016, 0x000005bf, 0x000005bf, 0x00000017, 0x000005c1, 0x000005c1, 0x00000018, 0x000005c2, 0x000005c2, 0x00000019, 0x000005c4, 0x000005c4, 0x000000e6, 0x0000064b, 0x0000064b, 0x0000001b, 0x0000064c, 0x0000064c, 0x0000001c, 0x0000064d, 0x0000064d, 0x0000001d, 0x0000064e, 0x0000064e, 0x0000001e, 0x0000064f, 0x0000064f, 0x0000001f, 0x00000650, 0x00000650, 0x00000020, 0x00000651, 0x00000651, 0x00000021, 0x00000652, 0x00000652, 0x00000022, 0x00000653, 0x00000654, 0x000000e6, 0x00000655, 0x00000655, 0x000000dc, 0x00000670, 0x00000670, 0x00000023, 0x000006d6, 0x000006dc, 0x000000e6, 0x000006df, 0x000006e2, 0x000000e6, 0x000006e3, 0x000006e3, 0x000000dc, 0x000006e4, 0x000006e4, 0x000000e6, 0x000006e7, 0x000006e8, 0x000000e6, 0x000006ea, 0x000006ea, 0x000000dc, 0x000006eb, 0x000006ec, 0x000000e6, 0x000006ed, 0x000006ed, 0x000000dc, 0x00000711, 0x00000711, 0x00000024, 0x00000730, 0x00000730, 0x000000e6, 0x00000731, 0x00000731, 0x000000dc, 0x00000732, 0x00000733, 0x000000e6, 0x00000734, 0x00000734, 0x000000dc, 0x00000735, 0x00000736, 0x000000e6, 0x00000737, 0x00000739, 0x000000dc, 0x0000073a, 0x0000073a, 0x000000e6, 0x0000073b, 0x0000073c, 0x000000dc, 0x0000073d, 0x0000073d, 0x000000e6, 0x0000073e, 0x0000073e, 0x000000dc, 0x0000073f, 0x00000741, 0x000000e6, 0x00000742, 0x00000742, 0x000000dc, 0x00000743, 0x00000743, 0x000000e6, 0x00000744, 0x00000744, 0x000000dc, 0x00000745, 0x00000745, 0x000000e6, 0x00000746, 0x00000746, 0x000000dc, 0x00000747, 0x00000747, 0x000000e6, 0x00000748, 0x00000748, 0x000000dc, 0x00000749, 0x0000074a, 0x000000e6, 0x0000093c, 0x0000093c, 0x00000007, 0x0000094d, 0x0000094d, 0x00000009, 0x00000951, 0x00000951, 0x000000e6, 0x00000952, 0x00000952, 0x000000dc, 0x00000953, 0x00000954, 0x000000e6, 0x000009bc, 0x000009bc, 0x00000007, 0x000009cd, 0x000009cd, 0x00000009, 0x00000a3c, 0x00000a3c, 0x00000007, 0x00000a4d, 0x00000a4d, 0x00000009, 0x00000abc, 0x00000abc, 0x00000007, 0x00000acd, 0x00000acd, 0x00000009, 0x00000b3c, 0x00000b3c, 0x00000007, 0x00000b4d, 0x00000b4d, 0x00000009, 0x00000bcd, 0x00000bcd, 0x00000009, 0x00000c4d, 0x00000c4d, 0x00000009, 0x00000c55, 0x00000c55, 0x00000054, 0x00000c56, 0x00000c56, 0x0000005b, 0x00000ccd, 0x00000ccd, 0x00000009, 0x00000d4d, 0x00000d4d, 0x00000009, 0x00000dca, 0x00000dca, 0x00000009, 0x00000e38, 0x00000e39, 0x00000067, 0x00000e3a, 0x00000e3a, 0x00000009, 0x00000e48, 0x00000e4b, 0x0000006b, 0x00000eb8, 0x00000eb9, 0x00000076, 0x00000ec8, 0x00000ecb, 0x0000007a, 0x00000f18, 0x00000f19, 0x000000dc, 0x00000f35, 0x00000f35, 0x000000dc, 0x00000f37, 0x00000f37, 0x000000dc, 0x00000f39, 0x00000f39, 0x000000d8, 0x00000f71, 0x00000f71, 0x00000081, 0x00000f72, 0x00000f72, 0x00000082, 0x00000f74, 0x00000f74, 0x00000084, 0x00000f7a, 0x00000f7d, 0x00000082, 0x00000f80, 0x00000f80, 0x00000082, 0x00000f82, 0x00000f83, 0x000000e6, 0x00000f84, 0x00000f84, 0x00000009, 0x00000f86, 0x00000f87, 0x000000e6, 0x00000fc6, 0x00000fc6, 0x000000dc, 0x00001037, 0x00001037, 0x00000007, 0x00001039, 0x00001039, 0x00000009, 0x00001714, 0x00001714, 0x00000009, 0x00001734, 0x00001734, 0x00000009, 0x000017d2, 0x000017d2, 0x00000009, 0x000018a9, 0x000018a9, 0x000000e4, 0x000020d0, 0x000020d1, 0x000000e6, 0x000020d2, 0x000020d3, 0x00000001, 0x000020d4, 0x000020d7, 0x000000e6, 0x000020d8, 0x000020da, 0x00000001, 0x000020db, 0x000020dc, 0x000000e6, 0x000020e1, 0x000020e1, 0x000000e6, 0x000020e5, 0x000020e6, 0x00000001, 0x000020e7, 0x000020e7, 0x000000e6, 0x000020e8, 0x000020e8, 0x000000dc, 0x000020e9, 0x000020e9, 0x000000e6, 0x000020ea, 0x000020ea, 0x00000001, 0x0000302a, 0x0000302a, 0x000000da, 0x0000302b, 0x0000302b, 0x000000e4, 0x0000302c, 0x0000302c, 0x000000e8, 0x0000302d, 0x0000302d, 0x000000de, 0x0000302e, 0x0000302f, 0x000000e0, 0x00003099, 0x0000309a, 0x00000008, 0x0000fb1e, 0x0000fb1e, 0x0000001a, 0x0000fe20, 0x0000fe23, 0x000000e6, 0x0001d165, 0x0001d166, 0x000000d8, 0x0001d167, 0x0001d169, 0x00000001, 0x0001d16d, 0x0001d16d, 0x000000e2, 0x0001d16e, 0x0001d172, 0x000000d8, 0x0001d17b, 0x0001d182, 0x000000dc, 0x0001d185, 0x0001d189, 0x000000e6, 0x0001d18a, 0x0001d18b, 0x000000dc, 0x0001d1aa, 0x0001d1ad, 0x000000e6 }; static const krb5_ui_4 _ucnum_size = 1066; static const krb5_ui_4 _ucnum_nodes[] = { 0x00000030, 0x00000000, 0x00000031, 0x00000002, 0x00000032, 0x00000004, 0x00000033, 0x00000006, 0x00000034, 0x00000008, 0x00000035, 0x0000000a, 0x00000036, 0x0000000c, 0x00000037, 0x0000000e, 0x00000038, 0x00000010, 0x00000039, 0x00000012, 0x000000b2, 0x00000004, 0x000000b3, 0x00000006, 0x000000b9, 0x00000002, 0x000000bc, 0x00000014, 0x000000bd, 0x00000016, 0x000000be, 0x00000018, 0x00000660, 0x00000000, 0x00000661, 0x00000002, 0x00000662, 0x00000004, 0x00000663, 0x00000006, 0x00000664, 0x00000008, 0x00000665, 0x0000000a, 0x00000666, 0x0000000c, 0x00000667, 0x0000000e, 0x00000668, 0x00000010, 0x00000669, 0x00000012, 0x000006f0, 0x00000000, 0x000006f1, 0x00000002, 0x000006f2, 0x00000004, 0x000006f3, 0x00000006, 0x000006f4, 0x00000008, 0x000006f5, 0x0000000a, 0x000006f6, 0x0000000c, 0x000006f7, 0x0000000e, 0x000006f8, 0x00000010, 0x000006f9, 0x00000012, 0x00000966, 0x00000000, 0x00000967, 0x00000002, 0x00000968, 0x00000004, 0x00000969, 0x00000006, 0x0000096a, 0x00000008, 0x0000096b, 0x0000000a, 0x0000096c, 0x0000000c, 0x0000096d, 0x0000000e, 0x0000096e, 0x00000010, 0x0000096f, 0x00000012, 0x000009e6, 0x00000000, 0x000009e7, 0x00000002, 0x000009e8, 0x00000004, 0x000009e9, 0x00000006, 0x000009ea, 0x00000008, 0x000009eb, 0x0000000a, 0x000009ec, 0x0000000c, 0x000009ed, 0x0000000e, 0x000009ee, 0x00000010, 0x000009ef, 0x00000012, 0x000009f4, 0x00000002, 0x000009f5, 0x00000004, 0x000009f6, 0x00000006, 0x000009f7, 0x00000008, 0x000009f9, 0x0000001a, 0x00000a66, 0x00000000, 0x00000a67, 0x00000002, 0x00000a68, 0x00000004, 0x00000a69, 0x00000006, 0x00000a6a, 0x00000008, 0x00000a6b, 0x0000000a, 0x00000a6c, 0x0000000c, 0x00000a6d, 0x0000000e, 0x00000a6e, 0x00000010, 0x00000a6f, 0x00000012, 0x00000ae6, 0x00000000, 0x00000ae7, 0x00000002, 0x00000ae8, 0x00000004, 0x00000ae9, 0x00000006, 0x00000aea, 0x00000008, 0x00000aeb, 0x0000000a, 0x00000aec, 0x0000000c, 0x00000aed, 0x0000000e, 0x00000aee, 0x00000010, 0x00000aef, 0x00000012, 0x00000b66, 0x00000000, 0x00000b67, 0x00000002, 0x00000b68, 0x00000004, 0x00000b69, 0x00000006, 0x00000b6a, 0x00000008, 0x00000b6b, 0x0000000a, 0x00000b6c, 0x0000000c, 0x00000b6d, 0x0000000e, 0x00000b6e, 0x00000010, 0x00000b6f, 0x00000012, 0x00000be7, 0x00000002, 0x00000be8, 0x00000004, 0x00000be9, 0x00000006, 0x00000bea, 0x00000008, 0x00000beb, 0x0000000a, 0x00000bec, 0x0000000c, 0x00000bed, 0x0000000e, 0x00000bee, 0x00000010, 0x00000bef, 0x00000012, 0x00000bf0, 0x0000001c, 0x00000bf1, 0x0000001e, 0x00000bf2, 0x00000020, 0x00000c66, 0x00000000, 0x00000c67, 0x00000002, 0x00000c68, 0x00000004, 0x00000c69, 0x00000006, 0x00000c6a, 0x00000008, 0x00000c6b, 0x0000000a, 0x00000c6c, 0x0000000c, 0x00000c6d, 0x0000000e, 0x00000c6e, 0x00000010, 0x00000c6f, 0x00000012, 0x00000ce6, 0x00000000, 0x00000ce7, 0x00000002, 0x00000ce8, 0x00000004, 0x00000ce9, 0x00000006, 0x00000cea, 0x00000008, 0x00000ceb, 0x0000000a, 0x00000cec, 0x0000000c, 0x00000ced, 0x0000000e, 0x00000cee, 0x00000010, 0x00000cef, 0x00000012, 0x00000d66, 0x00000000, 0x00000d67, 0x00000002, 0x00000d68, 0x00000004, 0x00000d69, 0x00000006, 0x00000d6a, 0x00000008, 0x00000d6b, 0x0000000a, 0x00000d6c, 0x0000000c, 0x00000d6d, 0x0000000e, 0x00000d6e, 0x00000010, 0x00000d6f, 0x00000012, 0x00000e50, 0x00000000, 0x00000e51, 0x00000002, 0x00000e52, 0x00000004, 0x00000e53, 0x00000006, 0x00000e54, 0x00000008, 0x00000e55, 0x0000000a, 0x00000e56, 0x0000000c, 0x00000e57, 0x0000000e, 0x00000e58, 0x00000010, 0x00000e59, 0x00000012, 0x00000ed0, 0x00000000, 0x00000ed1, 0x00000002, 0x00000ed2, 0x00000004, 0x00000ed3, 0x00000006, 0x00000ed4, 0x00000008, 0x00000ed5, 0x0000000a, 0x00000ed6, 0x0000000c, 0x00000ed7, 0x0000000e, 0x00000ed8, 0x00000010, 0x00000ed9, 0x00000012, 0x00000f20, 0x00000000, 0x00000f21, 0x00000002, 0x00000f22, 0x00000004, 0x00000f23, 0x00000006, 0x00000f24, 0x00000008, 0x00000f25, 0x0000000a, 0x00000f26, 0x0000000c, 0x00000f27, 0x0000000e, 0x00000f28, 0x00000010, 0x00000f29, 0x00000012, 0x00000f2a, 0x00000016, 0x00000f2b, 0x00000022, 0x00000f2c, 0x00000024, 0x00000f2d, 0x00000026, 0x00000f2e, 0x00000028, 0x00000f2f, 0x0000002a, 0x00000f30, 0x0000002c, 0x00000f31, 0x0000002e, 0x00000f32, 0x00000030, 0x00000f33, 0x00000032, 0x00001040, 0x00000000, 0x00001041, 0x00000002, 0x00001042, 0x00000004, 0x00001043, 0x00000006, 0x00001044, 0x00000008, 0x00001045, 0x0000000a, 0x00001046, 0x0000000c, 0x00001047, 0x0000000e, 0x00001048, 0x00000010, 0x00001049, 0x00000012, 0x00001369, 0x00000002, 0x0000136a, 0x00000004, 0x0000136b, 0x00000006, 0x0000136c, 0x00000008, 0x0000136d, 0x0000000a, 0x0000136e, 0x0000000c, 0x0000136f, 0x0000000e, 0x00001370, 0x00000010, 0x00001371, 0x00000012, 0x00001372, 0x0000001c, 0x00001373, 0x00000034, 0x00001374, 0x00000036, 0x00001375, 0x00000038, 0x00001376, 0x0000003a, 0x00001377, 0x0000003c, 0x00001378, 0x0000003e, 0x00001379, 0x00000040, 0x0000137a, 0x00000042, 0x0000137b, 0x0000001e, 0x0000137c, 0x00000044, 0x000016ee, 0x00000046, 0x000016ef, 0x00000048, 0x000016f0, 0x0000004a, 0x000017e0, 0x00000000, 0x000017e1, 0x00000002, 0x000017e2, 0x00000004, 0x000017e3, 0x00000006, 0x000017e4, 0x00000008, 0x000017e5, 0x0000000a, 0x000017e6, 0x0000000c, 0x000017e7, 0x0000000e, 0x000017e8, 0x00000010, 0x000017e9, 0x00000012, 0x00001810, 0x00000000, 0x00001811, 0x00000002, 0x00001812, 0x00000004, 0x00001813, 0x00000006, 0x00001814, 0x00000008, 0x00001815, 0x0000000a, 0x00001816, 0x0000000c, 0x00001817, 0x0000000e, 0x00001818, 0x00000010, 0x00001819, 0x00000012, 0x00002070, 0x00000000, 0x00002074, 0x00000008, 0x00002075, 0x0000000a, 0x00002076, 0x0000000c, 0x00002077, 0x0000000e, 0x00002078, 0x00000010, 0x00002079, 0x00000012, 0x00002080, 0x00000000, 0x00002081, 0x00000002, 0x00002082, 0x00000004, 0x00002083, 0x00000006, 0x00002084, 0x00000008, 0x00002085, 0x0000000a, 0x00002086, 0x0000000c, 0x00002087, 0x0000000e, 0x00002088, 0x00000010, 0x00002089, 0x00000012, 0x00002153, 0x0000004c, 0x00002154, 0x0000004e, 0x00002155, 0x00000050, 0x00002156, 0x00000052, 0x00002157, 0x00000054, 0x00002158, 0x00000056, 0x00002159, 0x00000058, 0x0000215a, 0x0000005a, 0x0000215b, 0x0000005c, 0x0000215c, 0x0000005e, 0x0000215d, 0x00000060, 0x0000215e, 0x00000062, 0x0000215f, 0x00000002, 0x00002160, 0x00000002, 0x00002161, 0x00000004, 0x00002162, 0x00000006, 0x00002163, 0x00000008, 0x00002164, 0x0000000a, 0x00002165, 0x0000000c, 0x00002166, 0x0000000e, 0x00002167, 0x00000010, 0x00002168, 0x00000012, 0x00002169, 0x0000001c, 0x0000216a, 0x00000064, 0x0000216b, 0x00000066, 0x0000216c, 0x0000003a, 0x0000216d, 0x0000001e, 0x0000216e, 0x00000068, 0x0000216f, 0x00000020, 0x00002170, 0x00000002, 0x00002171, 0x00000004, 0x00002172, 0x00000006, 0x00002173, 0x00000008, 0x00002174, 0x0000000a, 0x00002175, 0x0000000c, 0x00002176, 0x0000000e, 0x00002177, 0x00000010, 0x00002178, 0x00000012, 0x00002179, 0x0000001c, 0x0000217a, 0x00000064, 0x0000217b, 0x00000066, 0x0000217c, 0x0000003a, 0x0000217d, 0x0000001e, 0x0000217e, 0x00000068, 0x0000217f, 0x00000020, 0x00002180, 0x00000020, 0x00002181, 0x0000006a, 0x00002182, 0x00000044, 0x00002460, 0x00000002, 0x00002461, 0x00000004, 0x00002462, 0x00000006, 0x00002463, 0x00000008, 0x00002464, 0x0000000a, 0x00002465, 0x0000000c, 0x00002466, 0x0000000e, 0x00002467, 0x00000010, 0x00002468, 0x00000012, 0x00002469, 0x0000001c, 0x0000246a, 0x00000064, 0x0000246b, 0x00000066, 0x0000246c, 0x0000006c, 0x0000246d, 0x0000006e, 0x0000246e, 0x00000070, 0x0000246f, 0x0000001a, 0x00002470, 0x00000046, 0x00002471, 0x00000048, 0x00002472, 0x0000004a, 0x00002473, 0x00000034, 0x00002474, 0x00000002, 0x00002475, 0x00000004, 0x00002476, 0x00000006, 0x00002477, 0x00000008, 0x00002478, 0x0000000a, 0x00002479, 0x0000000c, 0x0000247a, 0x0000000e, 0x0000247b, 0x00000010, 0x0000247c, 0x00000012, 0x0000247d, 0x0000001c, 0x0000247e, 0x00000064, 0x0000247f, 0x00000066, 0x00002480, 0x0000006c, 0x00002481, 0x0000006e, 0x00002482, 0x00000070, 0x00002483, 0x0000001a, 0x00002484, 0x00000046, 0x00002485, 0x00000048, 0x00002486, 0x0000004a, 0x00002487, 0x00000034, 0x00002488, 0x00000002, 0x00002489, 0x00000004, 0x0000248a, 0x00000006, 0x0000248b, 0x00000008, 0x0000248c, 0x0000000a, 0x0000248d, 0x0000000c, 0x0000248e, 0x0000000e, 0x0000248f, 0x00000010, 0x00002490, 0x00000012, 0x00002491, 0x0000001c, 0x00002492, 0x00000064, 0x00002493, 0x00000066, 0x00002494, 0x0000006c, 0x00002495, 0x0000006e, 0x00002496, 0x00000070, 0x00002497, 0x0000001a, 0x00002498, 0x00000046, 0x00002499, 0x00000048, 0x0000249a, 0x0000004a, 0x0000249b, 0x00000034, 0x000024ea, 0x00000000, 0x000024eb, 0x00000064, 0x000024ec, 0x00000066, 0x000024ed, 0x0000006c, 0x000024ee, 0x0000006e, 0x000024ef, 0x00000070, 0x000024f0, 0x0000001a, 0x000024f1, 0x00000046, 0x000024f2, 0x00000048, 0x000024f3, 0x0000004a, 0x000024f4, 0x00000034, 0x000024f5, 0x00000002, 0x000024f6, 0x00000004, 0x000024f7, 0x00000006, 0x000024f8, 0x00000008, 0x000024f9, 0x0000000a, 0x000024fa, 0x0000000c, 0x000024fb, 0x0000000e, 0x000024fc, 0x00000010, 0x000024fd, 0x00000012, 0x000024fe, 0x0000001c, 0x00002776, 0x00000002, 0x00002777, 0x00000004, 0x00002778, 0x00000006, 0x00002779, 0x00000008, 0x0000277a, 0x0000000a, 0x0000277b, 0x0000000c, 0x0000277c, 0x0000000e, 0x0000277d, 0x00000010, 0x0000277e, 0x00000012, 0x0000277f, 0x0000001c, 0x00002780, 0x00000002, 0x00002781, 0x00000004, 0x00002782, 0x00000006, 0x00002783, 0x00000008, 0x00002784, 0x0000000a, 0x00002785, 0x0000000c, 0x00002786, 0x0000000e, 0x00002787, 0x00000010, 0x00002788, 0x00000012, 0x00002789, 0x0000001c, 0x0000278a, 0x00000002, 0x0000278b, 0x00000004, 0x0000278c, 0x00000006, 0x0000278d, 0x00000008, 0x0000278e, 0x0000000a, 0x0000278f, 0x0000000c, 0x00002790, 0x0000000e, 0x00002791, 0x00000010, 0x00002792, 0x00000012, 0x00002793, 0x0000001c, 0x00003007, 0x00000000, 0x00003021, 0x00000002, 0x00003022, 0x00000004, 0x00003023, 0x00000006, 0x00003024, 0x00000008, 0x00003025, 0x0000000a, 0x00003026, 0x0000000c, 0x00003027, 0x0000000e, 0x00003028, 0x00000010, 0x00003029, 0x00000012, 0x00003038, 0x0000001c, 0x00003039, 0x00000034, 0x0000303a, 0x00000036, 0x00003192, 0x00000002, 0x00003193, 0x00000004, 0x00003194, 0x00000006, 0x00003195, 0x00000008, 0x00003220, 0x00000002, 0x00003221, 0x00000004, 0x00003222, 0x00000006, 0x00003223, 0x00000008, 0x00003224, 0x0000000a, 0x00003225, 0x0000000c, 0x00003226, 0x0000000e, 0x00003227, 0x00000010, 0x00003228, 0x00000012, 0x00003229, 0x0000001c, 0x00003251, 0x00000072, 0x00003252, 0x00000074, 0x00003253, 0x00000076, 0x00003254, 0x00000078, 0x00003255, 0x0000007a, 0x00003256, 0x0000007c, 0x00003257, 0x0000007e, 0x00003258, 0x00000080, 0x00003259, 0x00000082, 0x0000325a, 0x00000036, 0x0000325b, 0x00000084, 0x0000325c, 0x00000086, 0x0000325d, 0x00000088, 0x0000325e, 0x0000008a, 0x0000325f, 0x0000008c, 0x00003280, 0x00000002, 0x00003281, 0x00000004, 0x00003282, 0x00000006, 0x00003283, 0x00000008, 0x00003284, 0x0000000a, 0x00003285, 0x0000000c, 0x00003286, 0x0000000e, 0x00003287, 0x00000010, 0x00003288, 0x00000012, 0x00003289, 0x0000001c, 0x000032b1, 0x0000008e, 0x000032b2, 0x00000090, 0x000032b3, 0x00000092, 0x000032b4, 0x00000094, 0x000032b5, 0x00000038, 0x000032b6, 0x00000096, 0x000032b7, 0x00000098, 0x000032b8, 0x0000009a, 0x000032b9, 0x0000009c, 0x000032ba, 0x0000009e, 0x000032bb, 0x000000a0, 0x000032bc, 0x000000a2, 0x000032bd, 0x000000a4, 0x000032be, 0x000000a6, 0x000032bf, 0x0000003a, 0x0000ff10, 0x00000000, 0x0000ff11, 0x00000002, 0x0000ff12, 0x00000004, 0x0000ff13, 0x00000006, 0x0000ff14, 0x00000008, 0x0000ff15, 0x0000000a, 0x0000ff16, 0x0000000c, 0x0000ff17, 0x0000000e, 0x0000ff18, 0x00000010, 0x0000ff19, 0x00000012, 0x00010320, 0x00000002, 0x00010321, 0x0000000a, 0x00010322, 0x0000001c, 0x00010323, 0x0000003a, 0x0001d7ce, 0x00000000, 0x0001d7cf, 0x00000002, 0x0001d7d0, 0x00000004, 0x0001d7d1, 0x00000006, 0x0001d7d2, 0x00000008, 0x0001d7d3, 0x0000000a, 0x0001d7d4, 0x0000000c, 0x0001d7d5, 0x0000000e, 0x0001d7d6, 0x00000010, 0x0001d7d7, 0x00000012, 0x0001d7d8, 0x00000000, 0x0001d7d9, 0x00000002, 0x0001d7da, 0x00000004, 0x0001d7db, 0x00000006, 0x0001d7dc, 0x00000008, 0x0001d7dd, 0x0000000a, 0x0001d7de, 0x0000000c, 0x0001d7df, 0x0000000e, 0x0001d7e0, 0x00000010, 0x0001d7e1, 0x00000012, 0x0001d7e2, 0x00000000, 0x0001d7e3, 0x00000002, 0x0001d7e4, 0x00000004, 0x0001d7e5, 0x00000006, 0x0001d7e6, 0x00000008, 0x0001d7e7, 0x0000000a, 0x0001d7e8, 0x0000000c, 0x0001d7e9, 0x0000000e, 0x0001d7ea, 0x00000010, 0x0001d7eb, 0x00000012, 0x0001d7ec, 0x00000000, 0x0001d7ed, 0x00000002, 0x0001d7ee, 0x00000004, 0x0001d7ef, 0x00000006, 0x0001d7f0, 0x00000008, 0x0001d7f1, 0x0000000a, 0x0001d7f2, 0x0000000c, 0x0001d7f3, 0x0000000e, 0x0001d7f4, 0x00000010, 0x0001d7f5, 0x00000012, 0x0001d7f6, 0x00000000, 0x0001d7f7, 0x00000002, 0x0001d7f8, 0x00000004, 0x0001d7f9, 0x00000006, 0x0001d7fa, 0x00000008, 0x0001d7fb, 0x0000000a, 0x0001d7fc, 0x0000000c, 0x0001d7fd, 0x0000000e, 0x0001d7fe, 0x00000010, 0x0001d7ff, 0x00000012 }; static const short _ucnum_vals[] = { 0x0000, 0x0001, 0x0001, 0x0001, 0x0002, 0x0001, 0x0003, 0x0001, 0x0004, 0x0001, 0x0005, 0x0001, 0x0006, 0x0001, 0x0007, 0x0001, 0x0008, 0x0001, 0x0009, 0x0001, 0x0001, 0x0004, 0x0001, 0x0002, 0x0003, 0x0004, 0x0010, 0x0001, 0x000a, 0x0001, 0x0064, 0x0001, 0x03e8, 0x0001, 0x0003, 0x0002, 0x0005, 0x0002, 0x0007, 0x0002, 0x0009, 0x0002, 0x000b, 0x0002, 0x000d, 0x0002, 0x000f, 0x0002, 0x0011, 0x0002, -1, 0x0002, 0x0014, 0x0001, 0x001e, 0x0001, 0x0028, 0x0001, 0x0032, 0x0001, 0x003c, 0x0001, 0x0046, 0x0001, 0x0050, 0x0001, 0x005a, 0x0001, 0x2710, 0x0001, 0x0011, 0x0001, 0x0012, 0x0001, 0x0013, 0x0001, 0x0001, 0x0003, 0x0002, 0x0003, 0x0001, 0x0005, 0x0002, 0x0005, 0x0003, 0x0005, 0x0004, 0x0005, 0x0001, 0x0006, 0x0005, 0x0006, 0x0001, 0x0008, 0x0003, 0x0008, 0x0005, 0x0008, 0x0007, 0x0008, 0x000b, 0x0001, 0x000c, 0x0001, 0x01f4, 0x0001, 0x1388, 0x0001, 0x000d, 0x0001, 0x000e, 0x0001, 0x000f, 0x0001, 0x0015, 0x0001, 0x0016, 0x0001, 0x0017, 0x0001, 0x0018, 0x0001, 0x0019, 0x0001, 0x001a, 0x0001, 0x001b, 0x0001, 0x001c, 0x0001, 0x001d, 0x0001, 0x001f, 0x0001, 0x0020, 0x0001, 0x0021, 0x0001, 0x0022, 0x0001, 0x0023, 0x0001, 0x0024, 0x0001, 0x0025, 0x0001, 0x0026, 0x0001, 0x0027, 0x0001, 0x0029, 0x0001, 0x002a, 0x0001, 0x002b, 0x0001, 0x002c, 0x0001, 0x002d, 0x0001, 0x002e, 0x0001, 0x002f, 0x0001, 0x0030, 0x0001, 0x0031, 0x0001 }; krb5-1.22.1/src/lib/krb5/unicode/ucdata/format.txt0000664000175000017500000002232715051422640021467 0ustar ghudsonghudson# # $Id: format.txt,v 1.2 2001/01/02 18:46:20 mleisher Exp $ # CHARACTER DATA ============== This package generates some data files that contain character properties useful for text processing. CHARACTER PROPERTIES ==================== The first data file is called "ctype.dat" and contains a compressed form of the character properties found in the Unicode Character Database (UCDB). Additional properties can be specified in limited UCDB format in another file to avoid modifying the original UCDB. The following is a property name and code table to be used with the character data: NAME CODE DESCRIPTION --------------------- Mn 0 Mark, Non-Spacing Mc 1 Mark, Spacing Combining Me 2 Mark, Enclosing Nd 3 Number, Decimal Digit Nl 4 Number, Letter No 5 Number, Other Zs 6 Separator, Space Zl 7 Separator, Line Zp 8 Separator, Paragraph Cc 9 Other, Control Cf 10 Other, Format Cs 11 Other, Surrogate Co 12 Other, Private Use Cn 13 Other, Not Assigned Lu 14 Letter, Uppercase Ll 15 Letter, Lowercase Lt 16 Letter, Titlecase Lm 17 Letter, Modifier Lo 18 Letter, Other Pc 19 Punctuation, Connector Pd 20 Punctuation, Dash Ps 21 Punctuation, Open Pe 22 Punctuation, Close Po 23 Punctuation, Other Sm 24 Symbol, Math Sc 25 Symbol, Currency Sk 26 Symbol, Modifier So 27 Symbol, Other L 28 Left-To-Right R 29 Right-To-Left EN 30 European Number ES 31 European Number Separator ET 32 European Number Terminator AN 33 Arabic Number CS 34 Common Number Separator B 35 Block Separator S 36 Segment Separator WS 37 Whitespace ON 38 Other Neutrals Pi 47 Punctuation, Initial Pf 48 Punctuation, Final # # Implementation specific properties. # Cm 39 Composite Nb 40 Non-Breaking Sy 41 Symmetric (characters which are part of open/close pairs) Hd 42 Hex Digit Qm 43 Quote Mark Mr 44 Mirroring Ss 45 Space, Other (controls viewed as spaces in ctype isspace()) Cp 46 Defined character The actual binary data is formatted as follows: Assumptions: unsigned short is at least 16-bits in size and unsigned long is at least 32-bits in size. unsigned short ByteOrderMark unsigned short OffsetArraySize unsigned long Bytes unsigned short Offsets[OffsetArraySize + 1] unsigned long Ranges[N], N = value of Offsets[OffsetArraySize] The Bytes field provides the total byte count used for the Offsets[] and Ranges[] arrays. The Offsets[] array is aligned on a 4-byte boundary and there is always one extra node on the end to hold the final index of the Ranges[] array. The Ranges[] array contains pairs of 4-byte values representing a range of Unicode characters. The pairs are arranged in increasing order by the first character code in the range. Determining if a particular character is in the property list requires a simple binary search to determine if a character is in any of the ranges for the property. If the ByteOrderMark is equal to 0xFFFE, then the data was generated on a machine with a different endian order and the values must be byte-swapped. To swap a 16-bit value: c = (c >> 8) | ((c & 0xff) << 8) To swap a 32-bit value: c = ((c & 0xff) << 24) | (((c >> 8) & 0xff) << 16) | (((c >> 16) & 0xff) << 8) | (c >> 24) CASE MAPPINGS ============= The next data file is called "case.dat" and contains three case mapping tables in the following order: upper, lower, and title case. Each table is in increasing order by character code and each mapping contains 3 unsigned longs which represent the possible mappings. The format for the binary form of these tables is: unsigned short ByteOrderMark unsigned short NumMappingNodes, count of all mapping nodes unsigned short CaseTableSizes[2], upper and lower mapping node counts unsigned long CaseTables[NumMappingNodes] The starting indexes of the case tables are calculated as following: UpperIndex = 0; LowerIndex = CaseTableSizes[0] * 3; TitleIndex = LowerIndex + CaseTableSizes[1] * 3; The order of the fields for the three tables are: Upper case ---------- unsigned long upper; unsigned long lower; unsigned long title; Lower case ---------- unsigned long lower; unsigned long upper; unsigned long title; Title case ---------- unsigned long title; unsigned long upper; unsigned long lower; If the ByteOrderMark is equal to 0xFFFE, endian swapping is required in the same way as described in the CHARACTER PROPERTIES section. Because the tables are in increasing order by character code, locating a mapping requires a simple binary search on one of the 3 codes that make up each node. It is important to note that there can only be 65536 mapping nodes which divided into 3 portions allows 21845 nodes for each case mapping table. The distribution of mappings may be more or less than 21845 per table, but only 65536 are allowed. COMPOSITIONS ============ This data file is called "comp.dat" and contains data that tracks character pairs that have a single Unicode value representing the combination of the two characters. The format for the binary form of this table is: unsigned short ByteOrderMark unsigned short NumCompositionNodes, count of composition nodes unsigned long Bytes, total number of bytes used for composition nodes unsigned long CompositionNodes[NumCompositionNodes * 4] If the ByteOrderMark is equal to 0xFFFE, endian swapping is required in the same way as described in the CHARACTER PROPERTIES section. The CompositionNodes[] array consists of groups of 4 unsigned longs. The first of these is the character code representing the combination of two other character codes, the second records the number of character codes that make up the composition (not currently used), and the last two are the pair of character codes whose combination is represented by the character code in the first field. DECOMPOSITIONS ============== The next data file is called "decomp.dat" and contains the decomposition data for all characters with decompositions containing more than one character and are *not* compatibility decompositions. Compatibility decompositions are signaled in the UCDB format by the use of the tag in the decomposition field. Each list of character codes represents a full decomposition of a composite character. The nodes are arranged in increasing order by character code. The format for the binary form of this table is: unsigned short ByteOrderMark unsigned short NumDecompNodes, count of all decomposition nodes unsigned long Bytes unsigned long DecompNodes[(NumDecompNodes * 2) + 1] unsigned long Decomp[N], N = sum of all counts in DecompNodes[] If the ByteOrderMark is equal to 0xFFFE, endian swapping is required in the same way as described in the CHARACTER PROPERTIES section. The DecompNodes[] array consists of pairs of unsigned longs, the first of which is the character code and the second is the initial index of the list of character codes representing the decomposition. Locating the decomposition of a composite character requires a binary search for a character code in the DecompNodes[] array and using its index to locate the start of the decomposition. The length of the decomposition list is the index in the following element in DecompNode[] minus the current index. COMBINING CLASSES ================= The fourth data file is called "cmbcl.dat" and contains the characters with non-zero combining classes. The format for the binary form of this table is: unsigned short ByteOrderMark unsigned short NumCCLNodes unsigned long Bytes unsigned long CCLNodes[NumCCLNodes * 3] If the ByteOrderMark is equal to 0xFFFE, endian swapping is required in the same way as described in the CHARACTER PROPERTIES section. The CCLNodes[] array consists of groups of three unsigned longs. The first and second are the beginning and ending of a range and the third is the combining class of that range. If a character is not found in this table, then the combining class is assumed to be 0. It is important to note that only 65536 distinct ranges plus combining class can be specified because the NumCCLNodes is usually a 16-bit number. NUMBER TABLE ============ The final data file is called "num.dat" and contains the characters that have a numeric value associated with them. The format for the binary form of the table is: unsigned short ByteOrderMark unsigned short NumNumberNodes unsigned long Bytes unsigned long NumberNodes[NumNumberNodes] unsigned short ValueNodes[(Bytes - (NumNumberNodes * sizeof(unsigned long))) / sizeof(short)] If the ByteOrderMark is equal to 0xFFFE, endian swapping is required in the same way as described in the CHARACTER PROPERTIES section. The NumberNodes array contains pairs of values, the first of which is the character code and the second an index into the ValueNodes array. The ValueNodes array contains pairs of integers which represent the numerator and denominator of the numeric value of the character. If the character happens to map to an integer, both the values in ValueNodes will be the same. krb5-1.22.1/src/lib/krb5/unicode/ucdata/ucgendat.c0000664000175000017500000014070415051422640021374 0ustar ghudsonghudson/* * Copyright 1998-2008 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in file LICENSE in the * top-level directory of the distribution or, alternatively, at * . */ /* Copyright 2001 Computing Research Labs, New Mexico State University * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * This work is part of OpenLDAP Software . * $OpenLDAP: pkg/ldap/libraries/liblunicode/ucdata/ucgendat.c,v 1.43 2008/01/07 23:20:05 kurt Exp $ * $Id: ucgendat.c,v 1.4 2001/01/02 18:46:20 mleisher Exp $" */ #include "k5-int.h" #include "k5-utf8.h" #include "k5-unicode.h" #ifndef HARDCODE_DATA #define HARDCODE_DATA 1 #endif #undef ishdigit #define ishdigit(cc) (((cc) >= '0' && (cc) <= '9') ||\ ((cc) >= 'A' && (cc) <= 'F') ||\ ((cc) >= 'a' && (cc) <= 'f')) /* * A header written to the output file with the byte-order-mark and the number * of property nodes. */ static krb5_ui_2 hdr[2] = {0xfeff, 0}; #define NUMPROPS 50 #define NEEDPROPS (NUMPROPS + (4 - (NUMPROPS & 3))) typedef struct { char *name; int len; } _prop_t; /* * List of properties expected to be found in the Unicode Character Database * including some implementation specific properties. * * The implementation specific properties are: * Cm = Composed (can be decomposed) * Nb = Non-breaking * Sy = Symmetric (has left and right forms) * Hd = Hex digit * Qm = Quote marks * Mr = Mirroring * Ss = Space, other * Cp = Defined character */ static _prop_t props[NUMPROPS] = { {"Mn", 2}, {"Mc", 2}, {"Me", 2}, {"Nd", 2}, {"Nl", 2}, {"No", 2}, {"Zs", 2}, {"Zl", 2}, {"Zp", 2}, {"Cc", 2}, {"Cf", 2}, {"Cs", 2}, {"Co", 2}, {"Cn", 2}, {"Lu", 2}, {"Ll", 2}, {"Lt", 2}, {"Lm", 2}, {"Lo", 2}, {"Pc", 2}, {"Pd", 2}, {"Ps", 2}, {"Pe", 2}, {"Po", 2}, {"Sm", 2}, {"Sc", 2}, {"Sk", 2}, {"So", 2}, {"L", 1}, {"R", 1}, {"EN", 2}, {"ES", 2}, {"ET", 2}, {"AN", 2}, {"CS", 2}, {"B", 1}, {"S", 1}, {"WS", 2}, {"ON", 2}, {"Cm", 2}, {"Nb", 2}, {"Sy", 2}, {"Hd", 2}, {"Qm", 2}, {"Mr", 2}, {"Ss", 2}, {"Cp", 2}, {"Pi", 2}, {"Pf", 2}, {"AL", 2} }; typedef struct { krb5_ui_4 *ranges; krb5_ui_2 used; krb5_ui_2 size; } _ranges_t; static _ranges_t proptbl[NUMPROPS]; /* * Make sure this array is sized to be on a 4-byte boundary at compile time. */ static krb5_ui_2 propcnt[NEEDPROPS]; /* * Array used to collect a decomposition before adding it to the decomposition * table. */ static krb5_ui_4 dectmp[64]; static krb5_ui_4 dectmp_size; typedef struct { krb5_ui_4 code; krb5_ui_2 size; krb5_ui_2 used; krb5_ui_4 *decomp; } _decomp_t; /* * List of decomposition. Created and expanded in order as the characters are * encountered. First list contains canonical mappings, second also includes * compatibility mappings. */ static _decomp_t *decomps; static krb5_ui_4 decomps_used; static krb5_ui_4 decomps_size; static _decomp_t *kdecomps; static krb5_ui_4 kdecomps_used; static krb5_ui_4 kdecomps_size; /* * Composition exclusion table stuff. */ #define COMPEX_SET(c) (compexs[(c) >> 5] |= (1 << ((c) & 31))) #define COMPEX_TEST(c) (compexs[(c) >> 5] & (1 << ((c) & 31))) static krb5_ui_4 compexs[8192]; /* * Struct for holding a composition pair, and array of composition pairs */ typedef struct { krb5_ui_4 comp; krb5_ui_4 count; krb5_ui_4 code1; krb5_ui_4 code2; } _comp_t; static _comp_t *comps; static krb5_ui_4 comps_used; /* * Types and lists for handling lists of case mappings. */ typedef struct { krb5_ui_4 key; krb5_ui_4 other1; krb5_ui_4 other2; } _case_t; static _case_t *upper; static _case_t *lower; static _case_t *title; static krb5_ui_4 upper_used; static krb5_ui_4 upper_size; static krb5_ui_4 lower_used; static krb5_ui_4 lower_size; static krb5_ui_4 title_used; static krb5_ui_4 title_size; /* * Array used to collect case mappings before adding them to a list. */ static krb5_ui_4 cases[3]; /* * An array to hold ranges for combining classes. */ static krb5_ui_4 *ccl; static krb5_ui_4 ccl_used; static krb5_ui_4 ccl_size; /* * Structures for handling numbers. */ typedef struct { krb5_ui_4 code; krb5_ui_4 idx; } _codeidx_t; typedef struct { short numerator; short denominator; } _num_t; /* * Arrays to hold the mapping of codes to numbers. */ static _codeidx_t *ncodes; static krb5_ui_4 ncodes_used; static krb5_ui_4 ncodes_size; static _num_t *nums; static krb5_ui_4 nums_used; static krb5_ui_4 nums_size; /* * Array for holding numbers. */ static _num_t *nums; static krb5_ui_4 nums_used; static krb5_ui_4 nums_size; static void add_range(krb5_ui_4 start, krb5_ui_4 end, char *p1, char *p2) { int i, j, k, len; _ranges_t *rlp; char *name; for (k = 0; k < 2; k++) { if (k == 0) { name = p1; len = 2; } else { if (p2 == 0) break; name = p2; len = 1; } for (i = 0; i < NUMPROPS; i++) { if (props[i].len == len && memcmp(props[i].name, name, len) == 0) break; } if (i == NUMPROPS) continue; rlp = &proptbl[i]; /* * Resize the range list if necessary. */ if (rlp->used == rlp->size) { if (rlp->size == 0) rlp->ranges = (krb5_ui_4 *) malloc(sizeof(krb5_ui_4) << 3); else rlp->ranges = (krb5_ui_4 *) realloc((char *) rlp->ranges, sizeof(krb5_ui_4) * (rlp->size + 8)); rlp->size += 8; } /* * If this is the first code for this property list, just add it * and return. */ if (rlp->used == 0) { rlp->ranges[0] = start; rlp->ranges[1] = end; rlp->used += 2; continue; } /* * Optimize the case of adding the range to the end. */ j = rlp->used - 1; if (start > rlp->ranges[j]) { j = rlp->used; rlp->ranges[j++] = start; rlp->ranges[j++] = end; rlp->used = j; continue; } /* * Need to locate the insertion point. */ for (i = 0; i < rlp->used && start > rlp->ranges[i + 1] + 1; i += 2) ; /* * If the start value lies in the current range, then simply set the * new end point of the range to the end value passed as a parameter. */ if (rlp->ranges[i] <= start && start <= rlp->ranges[i + 1] + 1) { rlp->ranges[i + 1] = end; return; } /* * Shift following values up by two. */ for (j = rlp->used; j > i; j -= 2) { rlp->ranges[j] = rlp->ranges[j - 2]; rlp->ranges[j + 1] = rlp->ranges[j - 1]; } /* * Add the new range at the insertion point. */ rlp->ranges[i] = start; rlp->ranges[i + 1] = end; rlp->used += 2; } } static void ordered_range_insert(krb5_ui_4 c, char *name, int len) { int i, j; krb5_ui_4 s, e; _ranges_t *rlp; if (len == 0) return; /* * Deal with directionality codes introduced in Unicode 3.0. */ if ((len == 2 && memcmp(name, "BN", 2) == 0) || (len == 3 && (memcmp(name, "NSM", 3) == 0 || memcmp(name, "PDF", 3) == 0 || memcmp(name, "LRE", 3) == 0 || memcmp(name, "LRO", 3) == 0 || memcmp(name, "RLE", 3) == 0 || memcmp(name, "RLO", 3) == 0))) { /* * Mark all of these as Other Neutral to preserve compatibility with * older versions. */ len = 2; name = "ON"; } for (i = 0; i < NUMPROPS; i++) { if (props[i].len == len && memcmp(props[i].name, name, len) == 0) break; } if (i == NUMPROPS) return; /* * Have a match, so insert the code in order. */ rlp = &proptbl[i]; /* * Resize the range list if necessary. */ if (rlp->used == rlp->size) { if (rlp->size == 0) rlp->ranges = (krb5_ui_4 *) malloc(sizeof(krb5_ui_4) << 3); else rlp->ranges = (krb5_ui_4 *) realloc((char *) rlp->ranges, sizeof(krb5_ui_4) * (rlp->size + 8)); rlp->size += 8; } /* * If this is the first code for this property list, just add it * and return. */ if (rlp->used == 0) { rlp->ranges[0] = rlp->ranges[1] = c; rlp->used += 2; return; } /* * Optimize the cases of extending the last range and adding new ranges to * the end. */ j = rlp->used - 1; e = rlp->ranges[j]; s = rlp->ranges[j - 1]; if (c == e + 1) { /* * Extend the last range. */ rlp->ranges[j] = c; return; } if (c > e + 1) { /* * Start another range on the end. */ j = rlp->used; rlp->ranges[j] = rlp->ranges[j + 1] = c; rlp->used += 2; return; } if (c >= s) /* * The code is a duplicate of a code in the last range, so just return. */ return; /* * The code should be inserted somewhere before the last range in the * list. Locate the insertion point. */ for (i = 0; i < rlp->used && c > rlp->ranges[i + 1] + 1; i += 2) ; s = rlp->ranges[i]; e = rlp->ranges[i + 1]; if (c == e + 1) /* * Simply extend the current range. */ rlp->ranges[i + 1] = c; else if (c < s) { /* * Add a new entry before the current location. Shift all entries * before the current one up by one to make room. */ for (j = rlp->used; j > i; j -= 2) { rlp->ranges[j] = rlp->ranges[j - 2]; rlp->ranges[j + 1] = rlp->ranges[j - 1]; } rlp->ranges[i] = rlp->ranges[i + 1] = c; rlp->used += 2; } } static void add_decomp(krb5_ui_4 code, short compat) { krb5_ui_4 i, j, size; _decomp_t **pdecomps; krb5_ui_4 *pdecomps_used; krb5_ui_4 *pdecomps_size; if (compat) { pdecomps = &kdecomps; pdecomps_used = &kdecomps_used; pdecomps_size = &kdecomps_size; } else { pdecomps = &decomps; pdecomps_used = &decomps_used; pdecomps_size = &decomps_size; } /* * Add the code to the composite property. */ if (!compat) { ordered_range_insert(code, "Cm", 2); } /* * Locate the insertion point for the code. */ for (i = 0; i < *pdecomps_used && code > (*pdecomps)[i].code; i++) ; /* * Allocate space for a new decomposition. */ if (*pdecomps_used == *pdecomps_size) { if (*pdecomps_size == 0) *pdecomps = (_decomp_t *) malloc(sizeof(_decomp_t) << 3); else *pdecomps = (_decomp_t *) realloc((char *) *pdecomps, sizeof(_decomp_t) * (*pdecomps_size + 8)); (void) memset((char *) (*pdecomps + *pdecomps_size), '\0', sizeof(_decomp_t) << 3); *pdecomps_size += 8; } if (i < *pdecomps_used && code != (*pdecomps)[i].code) { /* * Shift the decomps up by one if the codes don't match. */ for (j = *pdecomps_used; j > i; j--) (void) memmove((char *) &(*pdecomps)[j], (char *) &(*pdecomps)[j - 1], sizeof(_decomp_t)); } /* * Insert or replace a decomposition. */ size = dectmp_size + (4 - (dectmp_size & 3)); if ((*pdecomps)[i].size < size) { if ((*pdecomps)[i].size == 0) (*pdecomps)[i].decomp = (krb5_ui_4 *) malloc(sizeof(krb5_ui_4) * size); else (*pdecomps)[i].decomp = (krb5_ui_4 *) realloc((char *) (*pdecomps)[i].decomp, sizeof(krb5_ui_4) * size); (*pdecomps)[i].size = size; } if ((*pdecomps)[i].code != code) (*pdecomps_used)++; (*pdecomps)[i].code = code; (*pdecomps)[i].used = dectmp_size; (void) memmove((char *) (*pdecomps)[i].decomp, (char *) dectmp, sizeof(krb5_ui_4) * dectmp_size); /* * NOTICE: This needs changing later so it is more general than simply * pairs. This calculation is done here to simplify allocation elsewhere. */ if (!compat && dectmp_size == 2) comps_used++; } static void add_title(krb5_ui_4 code) { krb5_ui_4 i, j; /* * Always map the code to itself. */ cases[2] = code; if (title_used == title_size) { if (title_size == 0) title = (_case_t *) malloc(sizeof(_case_t) << 3); else title = (_case_t *) realloc((char *) title, sizeof(_case_t) * (title_size + 8)); title_size += 8; } /* * Locate the insertion point. */ for (i = 0; i < title_used && code > title[i].key; i++) ; if (i < title_used) { /* * Shift the array up by one. */ for (j = title_used; j > i; j--) (void) memmove((char *) &title[j], (char *) &title[j - 1], sizeof(_case_t)); } title[i].key = cases[2]; /* Title */ title[i].other1 = cases[0]; /* Upper */ title[i].other2 = cases[1]; /* Lower */ title_used++; } static void add_upper(krb5_ui_4 code) { krb5_ui_4 i, j; /* * Always map the code to itself. */ cases[0] = code; /* * If the title case character is not present, then make it the same as * the upper case. */ if (cases[2] == 0) cases[2] = code; if (upper_used == upper_size) { if (upper_size == 0) upper = (_case_t *) malloc(sizeof(_case_t) << 3); else upper = (_case_t *) realloc((char *) upper, sizeof(_case_t) * (upper_size + 8)); upper_size += 8; } /* * Locate the insertion point. */ for (i = 0; i < upper_used && code > upper[i].key; i++) ; if (i < upper_used) { /* * Shift the array up by one. */ for (j = upper_used; j > i; j--) (void) memmove((char *) &upper[j], (char *) &upper[j - 1], sizeof(_case_t)); } upper[i].key = cases[0]; /* Upper */ upper[i].other1 = cases[1]; /* Lower */ upper[i].other2 = cases[2]; /* Title */ upper_used++; } static void add_lower(krb5_ui_4 code) { krb5_ui_4 i, j; /* * Always map the code to itself. */ cases[1] = code; /* * If the title case character is empty, then make it the same as the * upper case. */ if (cases[2] == 0) cases[2] = cases[0]; if (lower_used == lower_size) { if (lower_size == 0) lower = (_case_t *) malloc(sizeof(_case_t) << 3); else lower = (_case_t *) realloc((char *) lower, sizeof(_case_t) * (lower_size + 8)); lower_size += 8; } /* * Locate the insertion point. */ for (i = 0; i < lower_used && code > lower[i].key; i++) ; if (i < lower_used) { /* * Shift the array up by one. */ for (j = lower_used; j > i; j--) (void) memmove((char *) &lower[j], (char *) &lower[j - 1], sizeof(_case_t)); } lower[i].key = cases[1]; /* Lower */ lower[i].other1 = cases[0]; /* Upper */ lower[i].other2 = cases[2]; /* Title */ lower_used++; } static void ordered_ccl_insert(krb5_ui_4 c, krb5_ui_4 ccl_code) { krb5_ui_4 i, j; if (ccl_used == ccl_size) { if (ccl_size == 0) ccl = (krb5_ui_4 *) malloc(sizeof(krb5_ui_4) * 24); else ccl = (krb5_ui_4 *) realloc((char *) ccl, sizeof(krb5_ui_4) * (ccl_size + 24)); ccl_size += 24; } /* * Optimize adding the first item. */ if (ccl_used == 0) { ccl[0] = ccl[1] = c; ccl[2] = ccl_code; ccl_used += 3; return; } /* * Handle the special case of extending the range on the end. This * requires that the combining class codes are the same. */ if (ccl_code == ccl[ccl_used - 1] && c == ccl[ccl_used - 2] + 1) { ccl[ccl_used - 2] = c; return; } /* * Handle the special case of adding another range on the end. */ if (c > ccl[ccl_used - 2] + 1 || (c == ccl[ccl_used - 2] + 1 && ccl_code != ccl[ccl_used - 1])) { ccl[ccl_used++] = c; ccl[ccl_used++] = c; ccl[ccl_used++] = ccl_code; return; } /* * Locate either the insertion point or range for the code. */ for (i = 0; i < ccl_used && c > ccl[i + 1] + 1; i += 3) ; if (ccl_code == ccl[i + 2] && c == ccl[i + 1] + 1) { /* * Extend an existing range. */ ccl[i + 1] = c; return; } else if (c < ccl[i]) { /* * Start a new range before the current location. */ for (j = ccl_used; j > i; j -= 3) { ccl[j] = ccl[j - 3]; ccl[j - 1] = ccl[j - 4]; ccl[j - 2] = ccl[j - 5]; } ccl[i] = ccl[i + 1] = c; ccl[i + 2] = ccl_code; } } /* * Adds a number if it does not already exist and returns an index value * multiplied by 2. */ static krb5_ui_4 make_number(short num, short denom) { krb5_ui_4 n; /* * Determine if the number already exists. */ for (n = 0; n < nums_used; n++) { if (nums[n].numerator == num && nums[n].denominator == denom) return n << 1; } if (nums_used == nums_size) { if (nums_size == 0) nums = (_num_t *) malloc(sizeof(_num_t) << 3); else nums = (_num_t *) realloc((char *) nums, sizeof(_num_t) * (nums_size + 8)); nums_size += 8; } n = nums_used++; nums[n].numerator = num; nums[n].denominator = denom; return n << 1; } static void add_number(krb5_ui_4 code, short num, short denom) { krb5_ui_4 i, j; /* * Insert the code in order. */ for (i = 0; i < ncodes_used && code > ncodes[i].code; i++) ; /* * Handle the case of the codes matching and simply replace the number * that was there before. */ if (i < ncodes_used && code == ncodes[i].code) { ncodes[i].idx = make_number(num, denom); return; } /* * Resize the array if necessary. */ if (ncodes_used == ncodes_size) { if (ncodes_size == 0) ncodes = (_codeidx_t *) malloc(sizeof(_codeidx_t) << 3); else ncodes = (_codeidx_t *) realloc((char *) ncodes, sizeof(_codeidx_t) * (ncodes_size + 8)); ncodes_size += 8; } /* * Shift things around to insert the code if necessary. */ if (i < ncodes_used) { for (j = ncodes_used; j > i; j--) { ncodes[j].code = ncodes[j - 1].code; ncodes[j].idx = ncodes[j - 1].idx; } } ncodes[i].code = code; ncodes[i].idx = make_number(num, denom); ncodes_used++; } /* * This routine assumes that the line is a valid Unicode Character Database * entry. */ static void read_cdata(FILE *in) { krb5_ui_4 i, lineno, skip, code, ccl_code; short wnum, neg, number[2], compat; char line[512], *s, *e; lineno = skip = 0; while (fgets(line, sizeof(line), in)) { if( (s=strchr(line, '\n')) ) *s = '\0'; lineno++; /* * Skip blank lines and lines that start with a '#'. */ if (line[0] == 0 || line[0] == '#') continue; /* * If lines need to be skipped, do it here. */ if (skip) { skip--; continue; } /* * Collect the code. The code can be up to 6 hex digits in length to * allow surrogates to be specified. */ for (s = line, i = code = 0; *s != ';' && i < 6; i++, s++) { code <<= 4; if (*s >= '0' && *s <= '9') code += *s - '0'; else if (*s >= 'A' && *s <= 'F') code += (*s - 'A') + 10; else if (*s >= 'a' && *s <= 'f') code += (*s - 'a') + 10; } /* * Handle the following special cases: * 1. 4E00-9FA5 CJK Ideographs. * 2. AC00-D7A3 Hangul Syllables. * 3. D800-DFFF Surrogates. * 4. E000-F8FF Private Use Area. * 5. F900-FA2D Han compatibility. * ...Plus additional ranges in newer Unicode versions... */ switch (code) { case 0x3400: /* CJK Ideograph Extension A */ add_range(0x3400, 0x4db5, "Lo", "L"); add_range(0x3400, 0x4db5, "Cp", 0); skip = 1; break; case 0x4e00: /* * The Han ideographs. */ add_range(0x4e00, 0x9fff, "Lo", "L"); /* * Add the characters to the defined category. */ add_range(0x4e00, 0x9fa5, "Cp", 0); skip = 1; break; case 0xac00: /* * The Hangul syllables. */ add_range(0xac00, 0xd7a3, "Lo", "L"); /* * Add the characters to the defined category. */ add_range(0xac00, 0xd7a3, "Cp", 0); skip = 1; break; case 0xd800: /* * Make a range of all surrogates and assume some default * properties. */ add_range(0x010000, 0x10ffff, "Cs", "L"); skip = 5; break; case 0xe000: /* * The Private Use area. Add with a default set of properties. */ add_range(0xe000, 0xf8ff, "Co", "L"); skip = 1; break; case 0xf900: /* * The CJK compatibility area. */ add_range(0xf900, 0xfaff, "Lo", "L"); /* * Add the characters to the defined category. */ add_range(0xf900, 0xfaff, "Cp", 0); skip = 1; break; case 0x20000: /* CJK Ideograph Extension B */ add_range(0x20000, 0x2a6d6, "Lo", "L"); add_range(0x20000, 0x2a6d6, "Cp", 0); skip = 1; break; case 0xf0000: /* Plane 15 private use */ add_range(0xf0000, 0xffffd, "Co", "L"); skip = 1; break; case 0x100000: /* Plane 16 private use */ add_range(0x100000, 0x10fffd, "Co", "L"); skip = 1; break; } if (skip) continue; /* * Add the code to the defined category. */ ordered_range_insert(code, "Cp", 2); /* * Locate the first character property field. */ for (i = 0; *s != 0 && i < 2; s++) { if (*s == ';') i++; } for (e = s; *e && *e != ';'; e++) ; ordered_range_insert(code, s, e - s); /* * Locate the combining class code. */ for (s = e; *s != 0 && i < 3; s++) { if (*s == ';') i++; } /* * Convert the combining class code from decimal. */ for (ccl_code = 0, e = s; *e && *e != ';'; e++) ccl_code = (ccl_code * 10) + (*e - '0'); /* * Add the code if it not 0. */ if (ccl_code != 0) ordered_ccl_insert(code, ccl_code); /* * Locate the second character property field. */ for (s = e; *s != 0 && i < 4; s++) { if (*s == ';') i++; } for (e = s; *e && *e != ';'; e++) ; ordered_range_insert(code, s, e - s); /* * Check for a decomposition. */ s = ++e; if (*s != ';') { compat = *s == '<'; if (compat) { /* * Skip compatibility formatting tag. */ while (*s++ != '>'); } /* * Collect the codes of the decomposition. */ for (dectmp_size = 0; *s != ';'; ) { /* * Skip all leading non-hex digits. */ while (!ishdigit(*s)) s++; for (dectmp[dectmp_size] = 0; ishdigit(*s); s++) { dectmp[dectmp_size] <<= 4; if (*s >= '0' && *s <= '9') dectmp[dectmp_size] += *s - '0'; else if (*s >= 'A' && *s <= 'F') dectmp[dectmp_size] += (*s - 'A') + 10; else if (*s >= 'a' && *s <= 'f') dectmp[dectmp_size] += (*s - 'a') + 10; } dectmp_size++; } /* * If there are any codes in the temporary decomposition array, * then add the character with its decomposition. */ if (dectmp_size > 0) { if (!compat) { add_decomp(code, 0); } add_decomp(code, 1); } } /* * Skip to the number field. */ for (i = 0; i < 3 && *s; s++) { if (*s == ';') i++; } /* * Scan the number in. */ number[0] = number[1] = 0; for (e = s, neg = wnum = 0; *e && *e != ';'; e++) { if (*e == '-') { neg = 1; continue; } if (*e == '/') { /* * Move the the denominator of the fraction. */ if (neg) number[wnum] *= -1; neg = 0; e++; wnum++; } number[wnum] = (number[wnum] * 10) + (*e - '0'); } if (e > s) { /* * Adjust the denominator in case of integers and add the number. */ if (wnum == 0) number[1] = 1; add_number(code, number[0], number[1]); } /* * Skip to the start of the possible case mappings. */ for (s = e, i = 0; i < 4 && *s; s++) { if (*s == ';') i++; } /* * Collect the case mappings. */ cases[0] = cases[1] = cases[2] = 0; for (i = 0; i < 3; i++) { while (ishdigit(*s)) { cases[i] <<= 4; if (*s >= '0' && *s <= '9') cases[i] += *s - '0'; else if (*s >= 'A' && *s <= 'F') cases[i] += (*s - 'A') + 10; else if (*s >= 'a' && *s <= 'f') cases[i] += (*s - 'a') + 10; s++; } if (*s == ';') s++; } if (cases[0] && cases[1]) /* * Add the upper and lower mappings for a title case character. */ add_title(code); else if (cases[1]) /* * Add the lower and title case mappings for the upper case * character. */ add_upper(code); else if (cases[0]) /* * Add the upper and title case mappings for the lower case * character. */ add_lower(code); } } static _decomp_t * find_decomp(krb5_ui_4 code, short compat) { long l, r, m; _decomp_t *decs; l = 0; r = (compat ? kdecomps_used : decomps_used) - 1; decs = compat ? kdecomps : decomps; while (l <= r) { m = (l + r) >> 1; if (code > decs[m].code) l = m + 1; else if (code < decs[m].code) r = m - 1; else return &decs[m]; } return 0; } static void decomp_it(_decomp_t *d, short compat) { krb5_ui_4 i; _decomp_t *dp; for (i = 0; i < d->used; i++) { if ((dp = find_decomp(d->decomp[i], compat)) != 0) decomp_it(dp, compat); else dectmp[dectmp_size++] = d->decomp[i]; } } /* * Expand all decompositions by recursively decomposing each character * in the decomposition. */ static void expand_decomp(void) { krb5_ui_4 i; for (i = 0; i < decomps_used; i++) { dectmp_size = 0; decomp_it(&decomps[i], 0); if (dectmp_size > 0) add_decomp(decomps[i].code, 0); } for (i = 0; i < kdecomps_used; i++) { dectmp_size = 0; decomp_it(&kdecomps[i], 1); if (dectmp_size > 0) add_decomp(kdecomps[i].code, 1); } } static int cmpcomps(const void *v_comp1, const void *v_comp2) { const _comp_t *comp1 = v_comp1, *comp2 = v_comp2; long diff = comp1->code1 - comp2->code1; if (!diff) diff = comp1->code2 - comp2->code2; return (int) diff; } /* * Load composition exclusion data */ static void read_compexdata(FILE *in) { krb5_ui_2 i; krb5_ui_4 code; char line[512], *s; (void) memset((char *) compexs, 0, sizeof(compexs)); while (fgets(line, sizeof(line), in)) { if( (s=strchr(line, '\n')) ) *s = '\0'; /* * Skip blank lines and lines that start with a '#'. */ if (line[0] == 0 || line[0] == '#') continue; /* * Collect the code. Assume max 6 digits */ for (s = line, i = code = 0; *s != '#' && i < 6; i++, s++) { if (isspace((unsigned char)*s)) break; code <<= 4; if (*s >= '0' && *s <= '9') code += *s - '0'; else if (*s >= 'A' && *s <= 'F') code += (*s - 'A') + 10; else if (*s >= 'a' && *s <= 'f') code += (*s - 'a') + 10; } COMPEX_SET(code); } } /* * Creates array of compositions from decomposition array */ static void create_comps(void) { krb5_ui_4 i, cu; comps = (_comp_t *) malloc(comps_used * sizeof(_comp_t)); for (i = cu = 0; i < decomps_used; i++) { if (decomps[i].used != 2 || COMPEX_TEST(decomps[i].code)) continue; comps[cu].comp = decomps[i].code; comps[cu].count = 2; comps[cu].code1 = decomps[i].decomp[0]; comps[cu].code2 = decomps[i].decomp[1]; cu++; } comps_used = cu; qsort(comps, comps_used, sizeof(_comp_t), cmpcomps); } #if HARDCODE_DATA static void write_case(FILE *out, _case_t *tab, int num, int first) { int i; for (i=0; i 0) { for (j=0; j 0) fwrite((char *) proptbl[i].ranges, sizeof(krb5_ui_4), proptbl[i].used, out); } fclose(out); #endif /***************************************************************** * * Generate the case mapping data. * *****************************************************************/ #if HARDCODE_DATA fprintf(out, PREF "krb5_ui_4 _uccase_size = %ld;\n\n", (long) (upper_used + lower_used + title_used)); fprintf(out, PREF "krb5_ui_2 _uccase_len[2] = {%ld, %ld};\n\n", (long) upper_used, (long) lower_used); fprintf(out, PREF "krb5_ui_4 _uccase_map[] = {"); if (upper_used > 0) /* * Write the upper case table. */ write_case(out, upper, upper_used, 1); if (lower_used > 0) /* * Write the lower case table. */ write_case(out, lower, lower_used, !upper_used); if (title_used > 0) /* * Write the title case table. */ write_case(out, title, title_used, !(upper_used||lower_used)); if (!(upper_used || lower_used || title_used)) fprintf(out, "\t0"); fprintf(out, "\n};\n\n"); #else /* * Open the case.dat file. */ snprintf(path, sizeof path, "%s" LDAP_DIRSEP "case.dat", opath); if ((out = fopen(path, "wb")) == 0) return; /* * Write the case mapping tables. */ hdr[1] = upper_used + lower_used + title_used; casecnt[0] = upper_used; casecnt[1] = lower_used; /* * Write the header. */ fwrite((char *) hdr, sizeof(krb5_ui_2), 2, out); /* * Write the upper and lower case table sizes. */ fwrite((char *) casecnt, sizeof(krb5_ui_2), 2, out); if (upper_used > 0) /* * Write the upper case table. */ fwrite((char *) upper, sizeof(_case_t), upper_used, out); if (lower_used > 0) /* * Write the lower case table. */ fwrite((char *) lower, sizeof(_case_t), lower_used, out); if (title_used > 0) /* * Write the title case table. */ fwrite((char *) title, sizeof(_case_t), title_used, out); fclose(out); #endif /***************************************************************** * * Generate the composition data. * *****************************************************************/ /* * Create compositions from decomposition data */ create_comps(); #if HARDCODE_DATA fprintf(out, PREF "krb5_ui_4 _uccomp_size = %ld;\n\n", comps_used * 4L); fprintf(out, PREF "krb5_ui_4 _uccomp_data[] = {"); /* * Now, if comps exist, write them out. */ if (comps_used > 0) { for (i=0; i 0) fwrite((char *) comps, sizeof(_comp_t), comps_used, out); fclose(out); #endif /***************************************************************** * * Generate the decomposition data. * *****************************************************************/ /* * Fully expand all decompositions before generating the output file. */ expand_decomp(); #if HARDCODE_DATA fprintf(out, PREF "krb5_ui_4 _ucdcmp_size = %ld;\n\n", decomps_used * 2L); fprintf(out, PREF "krb5_ui_4 _ucdcmp_nodes[] = {"); if (decomps_used) { /* * Write the list of decomp nodes. */ for (i = idx = 0; i < decomps_used; i++) { fprintf(out, "\n\t0x%08lx, 0x%08lx,", (unsigned long) decomps[i].code, (unsigned long) idx); idx += decomps[i].used; } /* * Write the sentinel index as the last decomp node. */ fprintf(out, "\n\t0x%08lx\n};\n\n", (unsigned long) idx); fprintf(out, PREF "krb5_ui_4 _ucdcmp_decomp[] = {"); /* * Write the decompositions themselves. */ k = 0; for (i = 0; i < decomps_used; i++) for (j=0; j 0) { /* * Write the combining class ranges out. */ for (i = 0; i 0) /* * Write the combining class ranges out. */ fwrite((char *) ccl, sizeof(krb5_ui_4), ccl_used, out); fclose(out); #endif /***************************************************************** * * Generate the number data. * *****************************************************************/ #if HARDCODE_DATA fprintf(out, PREF "krb5_ui_4 _ucnum_size = %lu;\n\n", (unsigned long)ncodes_used<<1); fprintf(out, PREF "krb5_ui_4 _ucnum_nodes[] = {"); /* * Now, if number mappings exist, write them out. */ if (ncodes_used > 0) { for (i = 0; i 0) { fwrite((char *) ncodes, sizeof(_codeidx_t), ncodes_used, out); fwrite((char *) nums, sizeof(_num_t), nums_used, out); } #endif fclose(out); } static void usage(char *prog) { fprintf(stderr, "Usage: %s [-o output-directory|-x composition-exclusions]", prog); fprintf(stderr, " datafile1 datafile2 ...\n\n"); fprintf(stderr, "-o output-directory\n\t\tWrite the output files to a different"); fprintf(stderr, " directory (default: .).\n"); fprintf(stderr, "-x composition-exclusion\n\t\tFile of composition codes"); fprintf(stderr, " that should be excluded.\n"); exit(1); } int main(int argc, char *argv[]) { FILE *in; char *prog, *opath; prog = lutil_progname( "ucgendat", argc, argv ); opath = 0; in = stdin; argc--; argv++; while (argc > 0) { if (argv[0][0] == '-') { switch (argv[0][1]) { case 'o': argc--; argv++; opath = argv[0]; break; case 'x': argc--; argv++; if ((in = fopen(argv[0], "r")) == 0) fprintf(stderr, "%s: unable to open composition exclusion file %s\n", prog, argv[0]); else { read_compexdata(in); fclose(in); in = 0; } break; default: usage(prog); } } else { if (in != stdin && in != NULL) fclose(in); if ((in = fopen(argv[0], "r")) == 0) fprintf(stderr, "%s: unable to open ctype file %s\n", prog, argv[0]); else { read_cdata(in); fclose(in); in = 0; } } argc--; argv++; } if (opath == 0) opath = "."; write_cdata(opath); return 0; } krb5-1.22.1/src/lib/krb5/unicode/ucdata/api.txt0000664000175000017500000002723115051422640020747 0ustar ghudsonghudson# # $Id: api.txt,v 1.3 2001/01/02 18:46:20 mleisher Exp $ # The MUTT UCData API ------------------- #### NOTE: This library has been customized for use with OpenLDAP. The character data tables are hardcoded into the library and the load/unload/reload functions are no-ops. Also, the MUTT API claimed to be compatible with John Cowan's library but its ucnumber behavior was broken. This has been fixed in the OpenLDAP release. By default, the implementation specific properties in MUTTUCData.txt are not incorporated into the OpenLDAP build. You can supply them to ucgendat and recreate uctable.h if you need them. -- hyc@openldap.org #### ----------------------------------------------------------------------------- Macros that combine to select data tables for ucdata_load(), ucdata_unload(), and ucdata_reload(). #define UCDATA_CASE 0x01 #define UCDATA_CTYPE 0x02 #define UCDATA_DECOMP 0x04 #define UCDATA_CMBCL 0x08 #define UCDATA_NUM 0x10 #define UCDATA_COMP 0x20 #define UCATA_ALL (UCDATA_CASE|UCDATA_CTYPE|UCDATA_DECOMP|\ UCDATA_CMBCL|UCDATA_NUM|UCDATA_COMP) ----------------------------------------------------------------------------- void ucdata_load(char *paths, int masks) This function initializes the UCData library by locating the data files in one of the colon-separated directories in the `paths' parameter. The data files to be loaded are specified in the `masks' parameter as a bitwise combination of the macros listed above. This should be called before using any of the other functions. NOTE: the ucdata_setup(char *paths) function is now a macro that expands into this function at compile time. ----------------------------------------------------------------------------- void ucdata_unload(int masks) This function unloads the data tables specified in the `masks' parameter. This function should be called when the application is done using the UCData package. NOTE: the ucdata_cleanup() function is now a macro that expands into this function at compile time. ----------------------------------------------------------------------------- void ucdata_reload(char *paths, int masks) This function reloads the data files from one of the colon-separated directories in the `paths' parameter. The data files to be reloaded are specified in the `masks' parameter as a bitwise combination of the macros listed above. If the data files have already been loaded, they are unloaded before the data files are loaded again. ----------------------------------------------------------------------------- int ucdecomp(unsigned long code, unsigned long *num, unsigned long **decomp) This function determines if a character has a decomposition and returns the decomposition information if it exists. If a zero is returned, there is no decomposition. If a non-zero is returned, then the `num' and `decomp' variables are filled in with the appropriate values. Example call: unsigned long i, num, *decomp; if (ucdecomp(0x1d5, &num, &decomp) != 0) { for (i = 0; i < num; i++) printf("0x%08lX,", decomp[i]); putchar('\n'); } int uccanondecomp(const unsigned long *in, int inlen, unsigned long **out, int *outlen) This function decomposes an input string and does canonical reordering of the characters at the same time. If a -1 is returned, memory allocation was not successful. If a zero is returned, no decomposition occured. Any other value means the output string contains the fully decomposed string in canonical order. If the "outlen" parameter comes back with a value > 0, then the string returned in the "out" parameter needs to be deallocated by the caller. ----------------------------------------------------------------------------- int ucdecomp_hangul(unsigned long code, unsigned long *num, unsigned long decomp[]) This function determines if a Hangul syllable has a decomposition and returns the decomposition information. An array of at least size 3 should be passed to the function for the decomposition of the syllable. If a zero is returned, the character is not a Hangul syllable. If a non-zero is returned, the `num' field will be 2 or 3 and the syllable will be decomposed into the `decomp' array arithmetically. Example call: unsigned long i, num, decomp[3]; if (ucdecomp_hangul(0xb1ba, &num, &decomp) != 0) { for (i = 0; i < num; i++) printf("0x%08lX,", decomp[i]); putchar('\n'); } ----------------------------------------------------------------------------- int uccomp(unsigned long ch1, unsigned long ch2, unsigned long *comp) This function takes a pair of characters and determines if they combine to form another character. If a zero is returned, no composition is formed by the character pair. Any other value indicates the "comp" parameter has a value. int uccomp_hangul(unsigned long *str, int len) This function composes the Hangul Jamo in the string. The composition is done in-place. The return value provides the new length of the string. This will be smaller than "len" if compositions occured. int uccanoncomp(unsigned long *str, int len) This function does a canonical composition of characters in the string. The return value is the new length of the string. ----------------------------------------------------------------------------- struct ucnumber { int numerator; int denominator; }; int ucnumber_lookup(unsigned long code, struct ucnumber *num) This function determines if the code is a number and fills in the `num' field with the numerator and denominator. If the code happens to be a single digit, the denominator field will be 1. #### The original code would set numerator = denominator for regular digits. However, the Readme also claimed to be compatible with John Cowan's uctype library, but this behavior is both nonsensical and incompatible with the Cowan library. As such, it has been fixed here as described above. -- hyc@openldap.org #### If the function returns 0, the code is not a number. Any other return value means the code is a number. int ucdigit_lookup(unsigned long code, int *digit) This function determines if the code is a digit and fills in the `digit' field with the digit value. If the function returns 0, the code is not a number. Any other return value means the code is a number. struct ucnumber ucgetnumber(unsigned long code) This is a compatibility function with John Cowan's "uctype" package. It uses ucnumber_lookup(). int ucgetdigit(unsigned long code) This is a compatibility function with John Cowan's "uctype" package. It uses ucdigit_lookup(). ----------------------------------------------------------------------------- unsigned long uctoupper(unsigned long code) This function returns the code unchanged if it is already upper case or has no upper case equivalent. Otherwise the upper case equivalent is returned. ----------------------------------------------------------------------------- unsigned long uctolower(unsigned long code) This function returns the code unchanged if it is already lower case or has no lower case equivalent. Otherwise the lower case equivalent is returned. ----------------------------------------------------------------------------- unsigned long uctotitle(unsigned long code) This function returns the code unchanged if it is already title case or has no title case equivalent. Otherwise the title case equivalent is returned. ----------------------------------------------------------------------------- int ucisalpha(unsigned long code) int ucisalnum(unsigned long code) int ucisdigit(unsigned long code) int uciscntrl(unsigned long code) int ucisspace(unsigned long code) int ucisblank(unsigned long code) int ucispunct(unsigned long code) int ucisgraph(unsigned long code) int ucisprint(unsigned long code) int ucisxdigit(unsigned long code) int ucisupper(unsigned long code) int ucislower(unsigned long code) int ucistitle(unsigned long code) These functions (actually macros) determine if a character has these properties. These behave in a fashion very similar to the venerable ctype package. ----------------------------------------------------------------------------- int ucisisocntrl(unsigned long code) Is the character a C0 control character (< 32) ? int ucisfmtcntrl(unsigned long code) Is the character a format control character? int ucissymbol(unsigned long code) Is the character a symbol? int ucisnumber(unsigned long code) Is the character a number or digit? int ucisnonspacing(unsigned long code) Is the character non-spacing? int ucisopenpunct(unsigned long code) Is the character an open/left punctuation (i.e. '[') int ucisclosepunct(unsigned long code) Is the character an close/right punctuation (i.e. ']') int ucisinitialpunct(unsigned long code) Is the character an initial punctuation (i.e. U+2018 LEFT SINGLE QUOTATION MARK) int ucisfinalpunct(unsigned long code) Is the character a final punctuation (i.e. U+2019 RIGHT SINGLE QUOTATION MARK) int uciscomposite(unsigned long code) Can the character be decomposed into a set of other characters? int ucisquote(unsigned long code) Is the character one of the many quotation marks? int ucissymmetric(unsigned long code) Is the character one that has an opposite form (i.e. <>) int ucismirroring(unsigned long code) Is the character mirroring (superset of symmetric)? int ucisnonbreaking(unsigned long code) Is the character non-breaking (i.e. non-breaking space)? int ucisrtl(unsigned long code) Does the character have strong right-to-left directionality (i.e. Arabic letters)? int ucisltr(unsigned long code) Does the character have strong left-to-right directionality (i.e. Latin letters)? int ucisstrong(unsigned long code) Does the character have strong directionality? int ucisweak(unsigned long code) Does the character have weak directionality (i.e. numbers)? int ucisneutral(unsigned long code) Does the character have neutral directionality (i.e. whitespace)? int ucisseparator(unsigned long code) Is the character a block or segment separator? int ucislsep(unsigned long code) Is the character a line separator? int ucispsep(unsigned long code) Is the character a paragraph separator? int ucismark(unsigned long code) Is the character a mark of some kind? int ucisnsmark(unsigned long code) Is the character a non-spacing mark? int ucisspmark(unsigned long code) Is the character a spacing mark? int ucismodif(unsigned long code) Is the character a modifier letter? int ucismodifsymbol(unsigned long code) Is the character a modifier symbol? int ucisletnum(unsigned long code) Is the character a number represented by a letter? int ucisconnect(unsigned long code) Is the character connecting punctuation? int ucisdash(unsigned long code) Is the character dash punctuation? int ucismath(unsigned long code) Is the character a math character? int uciscurrency(unsigned long code) Is the character a currency character? int ucisenclosing(unsigned long code) Is the character enclosing (i.e. enclosing box)? int ucisprivate(unsigned long code) Is the character from the Private Use Area? int ucissurrogate(unsigned long code) Is the character one of the surrogate codes? int ucisdefined(unsigned long code) Is the character defined (appeared in one of the data files)? int ucisundefined(unsigned long code) Is the character not defined (non-Unicode)? int ucishan(unsigned long code) Is the character a Han ideograph? int ucishangul(unsigned long code) Is the character a pre-composed Hangul syllable? krb5-1.22.1/src/lib/krb5/unicode/ucstr.c0000664000175000017500000001236215051422640017477 0ustar ghudsonghudson/* * Copyright 1998-2008 The OpenLDAP Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP Public * License. * * A copy of this license is available in file LICENSE in the top-level * directory of the distribution or, alternatively, at * . */ /* * This work is part of OpenLDAP Software . * $OpenLDAP: pkg/ldap/libraries/liblunicode/ucstr.c,v 1.40 2008/03/04 06:24:05 hyc Exp $ */ #include "k5-int.h" #include "k5-utf8.h" #include "k5-unicode.h" #include "k5-input.h" #include "ucdata/ucdata.h" #include static int krb5int_ucstrncmp( const krb5_unicode * u1, const krb5_unicode * u2, size_t n) { for (; 0 < n; ++u1, ++u2, --n) { if (*u1 != *u2) { return *u1 < *u2 ? -1 : +1; } if (*u1 == 0) { return 0; } } return 0; } static int krb5int_ucstrncasecmp( const krb5_unicode * u1, const krb5_unicode * u2, size_t n) { for (; 0 < n; ++u1, ++u2, --n) { krb5_unicode uu1 = uctolower(*u1); krb5_unicode uu2 = uctolower(*u2); if (uu1 != uu2) { return uu1 < uu2 ? -1 : +1; } if (uu1 == 0) { return 0; } } return 0; } /* Return true if data contains valid UTF-8 sequences. */ krb5_boolean k5_utf8_validate(const krb5_data *data) { struct k5input in; int len, tmplen, i; const uint8_t *bytes; k5_input_init(&in, data->data, data->length); while (!in.status && in.len > 0) { len = KRB5_UTF8_CHARLEN(in.ptr); if (len < 1 || len > 4) return FALSE; bytes = k5_input_get_bytes(&in, len); if (bytes == NULL) return FALSE; if (KRB5_UTF8_CHARLEN2(bytes, tmplen) != len) return FALSE; for (i = 1; i < len; i++) { if ((bytes[i] & 0xc0) != 0x80) return FALSE; } } return !in.status; } #define TOLOWER(c) (isupper(c) ? tolower(c) : (c)) /* compare UTF8-strings, optionally ignore casing */ /* slow, should be optimized */ int krb5int_utf8_normcmp( const krb5_data * data1, const krb5_data * data2, unsigned flags) { int i, l1, l2, len, ulen, res = 0; char *s1, *s2, *done; krb5_ucs4 *ucs, *ucsout1, *ucsout2; unsigned casefold = flags & KRB5_UTF8_CASEFOLD; unsigned norm1 = flags & KRB5_UTF8_ARG1NFC; unsigned norm2 = flags & KRB5_UTF8_ARG2NFC; if (data1 == NULL) { return data2 == NULL ? 0 : -1; } else if (data2 == NULL) { return 1; } l1 = data1->length; l2 = data2->length; len = (l1 < l2) ? l1 : l2; if (len == 0) { return l1 == 0 ? (l2 == 0 ? 0 : -1) : 1; } s1 = data1->data; s2 = data2->data; done = s1 + len; while ((s1 < done) && KRB5_UTF8_ISASCII(s1) && KRB5_UTF8_ISASCII(s2)) { if (casefold) { char c1 = TOLOWER(*s1); char c2 = TOLOWER(*s2); res = c1 - c2; } else { res = *s1 - *s2; } s1++; s2++; if (res) { /* done unless next character in s1 or s2 is non-ascii */ if (s1 < done) { if (!KRB5_UTF8_ISASCII(s1) || !KRB5_UTF8_ISASCII(s2)) { break; } } else if (((len < l1) && !KRB5_UTF8_ISASCII(s1)) || ((len < l2) && !KRB5_UTF8_ISASCII(s2))) { break; } return res; } } /* We have encountered non-ascii or strings equal up to len */ /* set i to number of iterations */ i = s1 - done + len; /* passed through loop at least once? */ if (i > 0) { if (!res && (s1 == done) && ((len == l1) || KRB5_UTF8_ISASCII(s1)) && ((len == l2) || KRB5_UTF8_ISASCII(s2))) { /* all ascii and equal up to len */ return l1 - l2; } /* rewind one char, and do normalized compare from there */ s1--; s2--; l1 -= i - 1; l2 -= i - 1; } /* * Should first check to see if strings are already in proper normalized * form. */ ucs = malloc(((norm1 || l1 > l2) ? l1 : l2) * sizeof(*ucs)); if (ucs == NULL) { return l1 > l2 ? 1 : -1;/* what to do??? */ } /* * XXYYZ: we convert to ucs4 even though -llunicode * expects ucs2 in an ac_uint4 */ /* convert and normalize 1st string */ for (i = 0, ulen = 0; i < l1; i += len, ulen++) { if (krb5int_utf8_to_ucs4(s1 + i, &ucs[ulen]) == -1) { free(ucs); return -1; /* what to do??? */ } len = KRB5_UTF8_CHARLEN(s1 + i); } if (norm1) { ucsout1 = ucs; l1 = ulen; ucs = malloc(l2 * sizeof(*ucs)); if (ucs == NULL) { free(ucsout1); return l1 > l2 ? 1 : -1; /* what to do??? */ } } else { uccompatdecomp(ucs, ulen, &ucsout1, &l1); l1 = uccanoncomp(ucsout1, l1); } /* convert and normalize 2nd string */ for (i = 0, ulen = 0; i < l2; i += len, ulen++) { if (krb5int_utf8_to_ucs4(s2 + i, &ucs[ulen]) == -1) { free(ucsout1); free(ucs); return 1; /* what to do??? */ } len = KRB5_UTF8_CHARLEN(s2 + i); } if (norm2) { ucsout2 = ucs; l2 = ulen; } else { uccompatdecomp(ucs, ulen, &ucsout2, &l2); l2 = uccanoncomp(ucsout2, l2); free(ucs); } res = casefold ? krb5int_ucstrncasecmp(ucsout1, ucsout2, l1 < l2 ? l1 : l2) : krb5int_ucstrncmp(ucsout1, ucsout2, l1 < l2 ? l1 : l2); free(ucsout1); free(ucsout2); if (res != 0) { return res; } if (l1 == l2) { return 0; } return l1 > l2 ? 1 : -1; } krb5-1.22.1/src/lib/krb5/unicode/deps0000664000175000017500000000160015051422640017042 0ustar ghudsonghudson# # Generated makefile dependencies follow. # ucstr.so ucstr.po $(OUTPRE)ucstr.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/ucdata/ucdata.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-input.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/k5-unicode.h $(top_srcdir)/include/k5-utf8.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h ucstr.c krb5-1.22.1/src/lib/krb5/unicode/UCD-Terms0000664000175000017500000000244115051422640017616 0ustar ghudsonghudsonUCD Terms of Use (https://www.unicode.org/Public/UNIDATA/UCD.html) Disclaimer The Unicode Character Database is provided as is by Unicode, Inc. No claims are made as to fitness for any particular purpose. No warranties of any kind are expressed or implied. The recipient agrees to determine applicability of information provided. If this file has been purchased on magnetic or optical media from Unicode, Inc., the sole remedy for any claim will be exchange of defective media within 90 days of receipt. This disclaimer is applicable for all other data files accompanying the Unicode Character Database, some of which have been compiled by the Unicode Consortium, and some of which have been supplied by other sources. Limitations on Rights to Redistribute This Data Recipient is granted the right to make copies in any form for internal distribution and to freely use the information supplied in the creation of products supporting the Unicode (TM) Standard. The files in the Unicode Character Database can be redistributed to third parties or other organizations (whether for profit or not) as long as this notice and the disclaimer notice are retained. Information can be extracted from these files and used in documentation or programs, as long as there is an accompanying notice indicating the source. krb5-1.22.1/src/lib/krb5/unicode/UnicodeData.txt0000664000175000017500000314257515051422640021131 0ustar ghudsonghudson0000;;Cc;0;BN;;;;;N;NULL;;;; 0001;;Cc;0;BN;;;;;N;START OF HEADING;;;; 0002;;Cc;0;BN;;;;;N;START OF TEXT;;;; 0003;;Cc;0;BN;;;;;N;END OF TEXT;;;; 0004;;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;; 0005;;Cc;0;BN;;;;;N;ENQUIRY;;;; 0006;;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;; 0007;;Cc;0;BN;;;;;N;BELL;;;; 0008;;Cc;0;BN;;;;;N;BACKSPACE;;;; 0009;;Cc;0;S;;;;;N;CHARACTER TABULATION;;;; 000A;;Cc;0;B;;;;;N;LINE FEED (LF);;;; 000B;;Cc;0;S;;;;;N;LINE TABULATION;;;; 000C;;Cc;0;WS;;;;;N;FORM FEED (FF);;;; 000D;;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;; 000E;;Cc;0;BN;;;;;N;SHIFT OUT;;;; 000F;;Cc;0;BN;;;;;N;SHIFT IN;;;; 0010;;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;; 0011;;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;; 0012;;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;; 0013;;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;; 0014;;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;; 0015;;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;; 0016;;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;; 0017;;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;; 0018;;Cc;0;BN;;;;;N;CANCEL;;;; 0019;;Cc;0;BN;;;;;N;END OF MEDIUM;;;; 001A;;Cc;0;BN;;;;;N;SUBSTITUTE;;;; 001B;;Cc;0;BN;;;;;N;ESCAPE;;;; 001C;;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;; 001D;;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;; 001E;;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;; 001F;;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;; 0020;SPACE;Zs;0;WS;;;;;N;;;;; 0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; 0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;; 0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;; 0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;; 0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;; 0026;AMPERSAND;Po;0;ON;;;;;N;;;;; 0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;; 0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;; 0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;; 002A;ASTERISK;Po;0;ON;;;;;N;;;;; 002B;PLUS SIGN;Sm;0;ET;;;;;N;;;;; 002C;COMMA;Po;0;CS;;;;;N;;;;; 002D;HYPHEN-MINUS;Pd;0;ET;;;;;N;;;;; 002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;; 002F;SOLIDUS;Po;0;ES;;;;;N;SLASH;;;; 0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;; 0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;; 0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;; 0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;; 0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;; 0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;; 0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;; 0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;; 0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;; 0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;; 003A;COLON;Po;0;CS;;;;;N;;;;; 003B;SEMICOLON;Po;0;ON;;;;;N;;;;; 003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;; 003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;; 003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;; 003F;QUESTION MARK;Po;0;ON;;;;;N;;;;; 0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;; 0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061; 0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062; 0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063; 0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064; 0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065; 0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066; 0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067; 0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068; 0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069; 004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A; 004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B; 004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C; 004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D; 004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E; 004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F; 0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070; 0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071; 0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072; 0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073; 0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074; 0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075; 0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076; 0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077; 0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078; 0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079; 005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A; 005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;; 005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;; 005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;; 005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;; 005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;; 0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;; 0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041 0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042 0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043 0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044 0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045 0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046 0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047 0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048 0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049 006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A 006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B 006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C 006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D 006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E 006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F 0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050 0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051 0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052 0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053 0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054 0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055 0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056 0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057 0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058 0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059 007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A 007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;; 007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;; 007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;; 007E;TILDE;Sm;0;ON;;;;;N;;;;; 007F;;Cc;0;BN;;;;;N;DELETE;;;; 0080;;Cc;0;BN;;;;;N;;;;; 0081;;Cc;0;BN;;;;;N;;;;; 0082;;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;; 0083;;Cc;0;BN;;;;;N;NO BREAK HERE;;;; 0084;;Cc;0;BN;;;;;N;;;;; 0085;;Cc;0;B;;;;;N;NEXT LINE (NEL);;;; 0086;;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;; 0087;;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;; 0088;;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;; 0089;;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;; 008A;;Cc;0;BN;;;;;N;LINE TABULATION SET;;;; 008B;;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;; 008C;;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;; 008D;;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;; 008E;;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;; 008F;;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;; 0090;;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;; 0091;;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;; 0092;;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;; 0093;;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;; 0094;;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;; 0095;;Cc;0;BN;;;;;N;MESSAGE WAITING;;;; 0096;;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;; 0097;;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;; 0098;;Cc;0;BN;;;;;N;START OF STRING;;;; 0099;;Cc;0;BN;;;;;N;;;;; 009A;;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;; 009B;;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;; 009C;;Cc;0;BN;;;;;N;STRING TERMINATOR;;;; 009D;;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;; 009E;;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;; 009F;;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;; 00A0;NO-BREAK SPACE;Zs;0;CS; 0020;;;;N;NON-BREAKING SPACE;;;; 00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; 00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;; 00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;; 00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; 00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;; 00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;; 00A7;SECTION SIGN;So;0;ON;;;;;N;;;;; 00A8;DIAERESIS;Sk;0;ON; 0020 0308;;;;N;SPACING DIAERESIS;;;; 00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;; 00AA;FEMININE ORDINAL INDICATOR;Ll;0;L; 0061;;;;N;;;;; 00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;*;;; 00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;; 00AD;SOFT HYPHEN;Pd;0;ON;;;;;N;;;;; 00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;; 00AF;MACRON;Sk;0;ON; 0020 0304;;;;N;SPACING MACRON;;;; 00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;; 00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;; 00B2;SUPERSCRIPT TWO;No;0;EN; 0032;2;2;2;N;SUPERSCRIPT DIGIT TWO;;;; 00B3;SUPERSCRIPT THREE;No;0;EN; 0033;3;3;3;N;SUPERSCRIPT DIGIT THREE;;;; 00B4;ACUTE ACCENT;Sk;0;ON; 0020 0301;;;;N;SPACING ACUTE;;;; 00B5;MICRO SIGN;Ll;0;L; 03BC;;;;N;;;039C;;039C 00B6;PILCROW SIGN;So;0;ON;;;;;N;PARAGRAPH SIGN;;;; 00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;; 00B8;CEDILLA;Sk;0;ON; 0020 0327;;;;N;SPACING CEDILLA;;;; 00B9;SUPERSCRIPT ONE;No;0;EN; 0031;1;1;1;N;SUPERSCRIPT DIGIT ONE;;;; 00BA;MASCULINE ORDINAL INDICATOR;Ll;0;L; 006F;;;;N;;;;; 00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;*;;; 00BC;VULGAR FRACTION ONE QUARTER;No;0;ON; 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;; 00BD;VULGAR FRACTION ONE HALF;No;0;ON; 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;; 00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON; 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;; 00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;; 00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0; 00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1; 00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2; 00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3; 00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4; 00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5; 00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;ash *;;00E6; 00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7; 00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8; 00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9; 00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA; 00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB; 00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC; 00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED; 00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE; 00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF; 00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;Icelandic;;00F0; 00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1; 00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2; 00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3; 00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4; 00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5; 00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6; 00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;; 00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8; 00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9; 00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA; 00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB; 00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC; 00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD; 00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;Icelandic;;00FE; 00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;German;;; 00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0 00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1 00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2 00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3 00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4 00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5 00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;ash *;00C6;;00C6 00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7 00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8 00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9 00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA 00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB 00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC 00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD 00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE 00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF 00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;Icelandic;00D0;;00D0 00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1 00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2 00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3 00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4 00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5 00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6 00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;; 00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8 00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9 00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA 00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB 00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC 00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD 00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;Icelandic;00DE;;00DE 00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178 0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101; 0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100 0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103; 0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102 0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105; 0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104 0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107; 0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106 0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109; 0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108 010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B; 010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A 010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D; 010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C 010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F; 010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E 0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111; 0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110 0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113; 0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112 0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115; 0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114 0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117; 0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116 0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119; 0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118 011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B; 011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A 011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D; 011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C 011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F; 011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E 0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121; 0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120 0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123; 0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122 0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125; 0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124 0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127; 0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126 0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129; 0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128 012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B; 012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A 012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D; 012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C 012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F; 012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E 0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069; 0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049 0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L; 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133; 0133;LATIN SMALL LIGATURE IJ;Ll;0;L; 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132 0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135; 0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134 0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137; 0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136 0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;Greenlandic;;; 0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A; 013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139 013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C; 013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B 013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E; 013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D 013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L; 004C 00B7;;;;N;;;;0140; 0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L; 006C 00B7;;;;N;;;013F;;013F 0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142; 0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141 0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144; 0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143 0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146; 0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145 0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148; 0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147 0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L; 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;; 014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;Sami;;014B; 014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;Sami;014A;;014A 014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D; 014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C 014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F; 014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E 0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151; 0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150 0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153; 0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152 0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155; 0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154 0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157; 0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156 0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159; 0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158 015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B; 015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A 015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D; 015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C 015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;*;;015F; 015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;*;015E;;015E 0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161; 0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160 0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;*;;0163; 0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;*;0162;;0162 0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165; 0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164 0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167; 0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166 0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169; 0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168 016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B; 016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A 016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D; 016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C 016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F; 016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E 0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171; 0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170 0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173; 0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172 0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175; 0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174 0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177; 0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176 0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF; 0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A; 017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179 017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C; 017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B 017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E; 017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D 017F;LATIN SMALL LETTER LONG S;Ll;0;L; 0073;;;;N;;;0053;;0053 0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;;; 0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253; 0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183; 0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182 0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185; 0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184 0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254; 0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188; 0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187 0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;*;;0256; 018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257; 018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C; 018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B 018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;; 018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD; 018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259; 0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B; 0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192; 0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191 0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260; 0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263; 0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;hwair;01F6;;01F6 0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269; 0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268; 0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199; 0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198 019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;;; 019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;; 019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F; 019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272; 019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220 019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;*;;0275; 01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1; 01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0 01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;gha;;01A3; 01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;gha;01A2;;01A2 01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5; 01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4 01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;*;;0280; 01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8; 01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7 01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283; 01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;; 01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;; 01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD; 01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC 01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288; 01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0; 01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF 01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A; 01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B; 01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4; 01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3 01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6; 01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5 01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292; 01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9; 01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8 01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;; 01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;; 01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD; 01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC 01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;; 01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7 01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;; 01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;; 01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;; 01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;; 01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L; 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5 01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L; 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6; 01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L; 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5 01C7;LATIN CAPITAL LETTER LJ;Lu;0;L; 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8 01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L; 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9; 01C9;LATIN SMALL LETTER LJ;Ll;0;L; 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8 01CA;LATIN CAPITAL LETTER NJ;Lu;0;L; 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB 01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L; 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC; 01CC;LATIN SMALL LETTER NJ;Ll;0;L; 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB 01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE; 01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD 01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0; 01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF 01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2; 01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1 01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4; 01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3 01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6; 01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5 01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8; 01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7 01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA; 01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9 01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC; 01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB 01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E 01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF; 01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE 01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1; 01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0 01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;ash *;;01E3; 01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;ash *;01E2;;01E2 01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5; 01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4 01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7; 01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6 01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9; 01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8 01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB; 01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA 01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED; 01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC 01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF; 01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE 01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;; 01F1;LATIN CAPITAL LETTER DZ;Lu;0;L; 0044 005A;;;;N;;;;01F3;01F2 01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L; 0044 007A;;;;N;;;01F1;01F3; 01F3;LATIN SMALL LETTER DZ;Ll;0;L; 0064 007A;;;;N;;;01F1;;01F2 01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5; 01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4 01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195; 01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF; 01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9; 01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8 01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB; 01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA 01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;ash *;;01FD; 01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;ash *;01FC;;01FC 01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF; 01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE 0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201; 0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200 0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203; 0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202 0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205; 0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204 0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207; 0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206 0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209; 0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208 020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B; 020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A 020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D; 020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C 020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F; 020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E 0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211; 0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210 0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213; 0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212 0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215; 0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214 0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217; 0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216 0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;*;;0219; 0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;*;0218;;0218 021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;*;;021B; 021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;*;021A;;021A 021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D; 021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C 021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F; 021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E 0220;LATIN CAPITAL LETTER N WITH LONG RIGHT LEG;Lu;0;L;;;;;N;;;;019E; 0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223; 0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222 0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225; 0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224 0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227; 0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226 0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229; 0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228 022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B; 022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A 022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D; 022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C 022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F; 022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E 0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231; 0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230 0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233; 0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232 0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;;; 0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;;; 0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;;; 0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181 0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186 0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;; 0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189 0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A 0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;; 0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F 025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;; 025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190 025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;;; 025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;; 025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;; 025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;; 0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193 0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;;; 0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;; 0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194 0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;; 0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;;; 0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;;; 0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;; 0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197 0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196 026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;;; 026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; 026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;;; 026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;; 026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;; 026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C 0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;; 0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;;; 0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D 0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;; 0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;; 0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F 0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;; 0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;; 0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;; 0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;; 027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;; 027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;; 027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;; 027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;;; 027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;; 027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;; 0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;*;01A6;;01A6 0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;; 0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;; 0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9 0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;; 0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;; 0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;; 0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;;; 0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE 0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;;; 028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1 028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2 028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;;; 028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;; 028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;; 028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;; 0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;; 0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;; 0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7 0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;; 0294;LATIN LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;;; 0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;; 0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;; 0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;; 0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;; 0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;; 029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;; 029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;; 029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;; 029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;;; 029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;;; 029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;; 02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;; 02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;; 02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;; 02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;; 02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;; 02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;; 02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;; 02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;; 02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;; 02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;; 02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;; 02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;; 02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; 02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;; 02B0;MODIFIER LETTER SMALL H;Lm;0;L; 0068;;;;N;;;;; 02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L; 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;; 02B2;MODIFIER LETTER SMALL J;Lm;0;L; 006A;;;;N;;;;; 02B3;MODIFIER LETTER SMALL R;Lm;0;L; 0072;;;;N;;;;; 02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L; 0279;;;;N;;;;; 02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L; 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;; 02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L; 0281;;;;N;;;;; 02B7;MODIFIER LETTER SMALL W;Lm;0;L; 0077;;;;N;;;;; 02B8;MODIFIER LETTER SMALL Y;Lm;0;L; 0079;;;;N;;;;; 02B9;MODIFIER LETTER PRIME;Sk;0;ON;;;;;N;;;;; 02BA;MODIFIER LETTER DOUBLE PRIME;Sk;0;ON;;;;;N;;;;; 02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;; 02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;; 02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;; 02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;; 02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; 02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;; 02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;; 02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;; 02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;; 02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;; 02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;; 02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;; 02C7;CARON;Sk;0;ON;;;;;N;MODIFIER LETTER HACEK;Mandarin Chinese third tone;;; 02C8;MODIFIER LETTER VERTICAL LINE;Sk;0;ON;;;;;N;;;;; 02C9;MODIFIER LETTER MACRON;Sk;0;ON;;;;;N;;Mandarin Chinese first tone;;; 02CA;MODIFIER LETTER ACUTE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER ACUTE;Mandarin Chinese second tone;;; 02CB;MODIFIER LETTER GRAVE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER GRAVE;Mandarin Chinese fourth tone;;; 02CC;MODIFIER LETTER LOW VERTICAL LINE;Sk;0;ON;;;;;N;;;;; 02CD;MODIFIER LETTER LOW MACRON;Sk;0;ON;;;;;N;;;;; 02CE;MODIFIER LETTER LOW GRAVE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;; 02CF;MODIFIER LETTER LOW ACUTE ACCENT;Sk;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;; 02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; 02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;; 02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;; 02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;; 02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;; 02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;; 02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;; 02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;; 02D8;BREVE;Sk;0;ON; 0020 0306;;;;N;SPACING BREVE;;;; 02D9;DOT ABOVE;Sk;0;ON; 0020 0307;;;;N;SPACING DOT ABOVE;Mandarin Chinese light tone;;; 02DA;RING ABOVE;Sk;0;ON; 0020 030A;;;;N;SPACING RING ABOVE;;;; 02DB;OGONEK;Sk;0;ON; 0020 0328;;;;N;SPACING OGONEK;;;; 02DC;SMALL TILDE;Sk;0;ON; 0020 0303;;;;N;SPACING TILDE;;;; 02DD;DOUBLE ACUTE ACCENT;Sk;0;ON; 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;; 02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;; 02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;; 02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L; 0263;;;;N;;;;; 02E1;MODIFIER LETTER SMALL L;Lm;0;L; 006C;;;;N;;;;; 02E2;MODIFIER LETTER SMALL S;Lm;0;L; 0073;;;;N;;;;; 02E3;MODIFIER LETTER SMALL X;Lm;0;L; 0078;;;;N;;;;; 02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L; 0295;;;;N;;;;; 02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; 02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;; 02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;; 02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;; 02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;; 02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; 02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;; 02EC;MODIFIER LETTER VOICING;Sk;0;ON;;;;;N;;;;; 02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;; 02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;; 0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;Varia;;; 0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;Oxia, Tonos;;; 0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;; 0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;; 0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;; 0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;; 0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;Vrachy;;; 0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;; 0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;Dialytika;;; 0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;; 030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;; 030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;; 030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;; 030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;;;; 030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;; 030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;; 0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;; 0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;; 0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;; 0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;Psili;;; 0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;Dasia;;; 0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;; 0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;; 0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;; 0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;; 0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;; 031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;; 031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;; 031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;; 031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;; 031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;; 031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;; 0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;; 0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;; 0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;; 0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;; 0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;; 0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;; 0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;; 0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;; 0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;; 0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;; 032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;; 032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;; 032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;; 032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;; 032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;; 032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;; 0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;; 0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;; 0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;; 0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;; 0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;; 0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;; 0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;; 0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;; 0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;; 0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;; 033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;; 033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;; 033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;; 033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;; 033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;; 033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;; 0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;Vietnamese;;; 0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;Vietnamese;;; 0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;; 0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;; 0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;; 0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399 0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; 0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;; 0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;; 0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;; 034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;; 034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;; 034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;; 034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;; 034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;; 034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;; 0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;; 0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;; 0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;; 0363;COMBINING LATIN SMALL LETTER A;Mn;230;NSM;;;;;N;;;;; 0364;COMBINING LATIN SMALL LETTER E;Mn;230;NSM;;;;;N;;;;; 0365;COMBINING LATIN SMALL LETTER I;Mn;230;NSM;;;;;N;;;;; 0366;COMBINING LATIN SMALL LETTER O;Mn;230;NSM;;;;;N;;;;; 0367;COMBINING LATIN SMALL LETTER U;Mn;230;NSM;;;;;N;;;;; 0368;COMBINING LATIN SMALL LETTER C;Mn;230;NSM;;;;;N;;;;; 0369;COMBINING LATIN SMALL LETTER D;Mn;230;NSM;;;;;N;;;;; 036A;COMBINING LATIN SMALL LETTER H;Mn;230;NSM;;;;;N;;;;; 036B;COMBINING LATIN SMALL LETTER M;Mn;230;NSM;;;;;N;;;;; 036C;COMBINING LATIN SMALL LETTER R;Mn;230;NSM;;;;;N;;;;; 036D;COMBINING LATIN SMALL LETTER T;Mn;230;NSM;;;;;N;;;;; 036E;COMBINING LATIN SMALL LETTER V;Mn;230;NSM;;;;;N;;;;; 036F;COMBINING LATIN SMALL LETTER X;Mn;230;NSM;;;;;N;;;;; 0374;GREEK NUMERAL SIGN;Sk;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;Dexia keraia;;; 0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;Aristeri keraia;;; 037A;GREEK YPOGEGRAMMENI;Lm;0;L; 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;; 037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;Erotimatiko;;; 0384;GREEK TONOS;Sk;0;ON; 0020 0301;;;;N;GREEK SPACING TONOS;;;; 0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;; 0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC; 0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;; 0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD; 0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE; 038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF; 038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC; 038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD; 038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE; 0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;; 0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1; 0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2; 0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3; 0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4; 0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5; 0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6; 0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7; 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8; 0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9; 039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA; 039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB; 039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC; 039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD; 039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE; 039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF; 03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0; 03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1; 03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3; 03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4; 03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5; 03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6; 03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7; 03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8; 03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9; 03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA; 03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB; 03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386 03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388 03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389 03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A 03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;; 03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391 03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392 03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393 03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394 03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395 03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396 03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398 03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399 03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A 03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B 03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C 03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D 03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E 03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F 03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0 03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1 03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3 03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4 03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5 03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6 03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7 03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8 03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9 03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA 03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB 03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C 03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E 03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F 03D0;GREEK BETA SYMBOL;Ll;0;L; 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392 03D1;GREEK THETA SYMBOL;Ll;0;L; 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398 03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L; 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;; 03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;; 03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;; 03D5;GREEK PHI SYMBOL;Ll;0;L; 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6 03D6;GREEK PI SYMBOL;Ll;0;L; 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0 03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;;; 03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;*;;03D9; 03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;*;03D8;;03D8 03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB; 03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA 03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD; 03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC 03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF; 03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE 03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1; 03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0 03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3; 03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2 03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5; 03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4 03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7; 03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6 03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9; 03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8 03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB; 03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA 03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED; 03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC 03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF; 03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE 03F0;GREEK KAPPA SYMBOL;Ll;0;L; 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A 03F1;GREEK RHO SYMBOL;Ll;0;L; 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1 03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L; 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03A3;;03A3 03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;;; 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L; 0398;;;;N;;;;03B8; 03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L; 03B5;;;;N;;;0395;;0395 03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;; 0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450; 0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451; 0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;Serbocroatian;;0452; 0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453; 0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454; 0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455; 0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456; 0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;Ukrainian;;0457; 0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458; 0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459; 040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A; 040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;Serbocroatian;;045B; 040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C; 040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D; 040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;Byelorussian;;045E; 040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F; 0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430; 0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431; 0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432; 0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433; 0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434; 0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435; 0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436; 0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437; 0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438; 0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439; 041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A; 041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B; 041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C; 041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D; 041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E; 041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F; 0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440; 0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441; 0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442; 0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443; 0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444; 0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445; 0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446; 0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447; 0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448; 0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449; 042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A; 042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B; 042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C; 042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D; 042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E; 042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F; 0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410 0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411 0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412 0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413 0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414 0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415 0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416 0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417 0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418 0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419 043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A 043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B 043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C 043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D 043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E 043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F 0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420 0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421 0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422 0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423 0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424 0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425 0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426 0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427 0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428 0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429 044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A 044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B 044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C 044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D 044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E 044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F 0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400 0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401 0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;Serbocroatian;0402;;0402 0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403 0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404 0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405 0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406 0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;Ukrainian;0407;;0407 0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408 0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409 045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A 045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;Serbocroatian;040B;;040B 045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C 045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D 045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;Byelorussian;040E;;040E 045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F 0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461; 0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460 0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463; 0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462 0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465; 0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464 0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467; 0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466 0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469; 0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468 046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B; 046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A 046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D; 046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C 046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F; 046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E 0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471; 0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470 0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473; 0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472 0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475; 0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474 0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477; 0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476 0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479; 0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478 047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B; 047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A 047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D; 047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C 047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F; 047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E 0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481; 0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480 0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;; 0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;; 0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;; 0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;; 0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;; 0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;; 0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;; 048A;CYRILLIC CAPITAL LETTER SHORT I WITH TAIL;Lu;0;L;;;;;N;;;;048B; 048B;CYRILLIC SMALL LETTER SHORT I WITH TAIL;Ll;0;L;;;;;N;;;048A;;048A 048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D; 048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C 048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F; 048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E 0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491; 0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490 0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493; 0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492 0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495; 0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494 0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497; 0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496 0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499; 0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498 049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B; 049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A 049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D; 049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C 049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F; 049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E 04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1; 04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0 04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3; 04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2 04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5; 04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4 04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;Abkhasian;;04A7; 04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;Abkhasian;04A6;;04A6 04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9; 04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8 04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB; 04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA 04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD; 04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC 04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF; 04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE 04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1; 04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0 04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3; 04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2 04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;Abkhasian;;04B5; 04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;Abkhasian;04B4;;04B4 04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7; 04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6 04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9; 04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8 04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB; 04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA 04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD; 04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC 04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF; 04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE 04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;; 04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2; 04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1 04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4; 04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3 04C5;CYRILLIC CAPITAL LETTER EL WITH TAIL;Lu;0;L;;;;;N;;;;04C6; 04C6;CYRILLIC SMALL LETTER EL WITH TAIL;Ll;0;L;;;;;N;;;04C5;;04C5 04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8; 04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7 04C9;CYRILLIC CAPITAL LETTER EN WITH TAIL;Lu;0;L;;;;;N;;;;04CA; 04CA;CYRILLIC SMALL LETTER EN WITH TAIL;Ll;0;L;;;;;N;;;04C9;;04C9 04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC; 04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB 04CD;CYRILLIC CAPITAL LETTER EM WITH TAIL;Lu;0;L;;;;;N;;;;04CE; 04CE;CYRILLIC SMALL LETTER EM WITH TAIL;Ll;0;L;;;;;N;;;04CD;;04CD 04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1; 04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0 04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3; 04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2 04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5; 04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4 04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7; 04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6 04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9; 04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8 04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB; 04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA 04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD; 04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC 04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF; 04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE 04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1; 04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0 04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3; 04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2 04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5; 04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4 04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7; 04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6 04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9; 04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8 04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB; 04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA 04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED; 04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC 04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF; 04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE 04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1; 04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0 04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3; 04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2 04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5; 04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4 04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9; 04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8 0500;CYRILLIC CAPITAL LETTER KOMI DE;Lu;0;L;;;;;N;;;;0501; 0501;CYRILLIC SMALL LETTER KOMI DE;Ll;0;L;;;;;N;;;0500;;0500 0502;CYRILLIC CAPITAL LETTER KOMI DJE;Lu;0;L;;;;;N;;;;0503; 0503;CYRILLIC SMALL LETTER KOMI DJE;Ll;0;L;;;;;N;;;0502;;0502 0504;CYRILLIC CAPITAL LETTER KOMI ZJE;Lu;0;L;;;;;N;;;;0505; 0505;CYRILLIC SMALL LETTER KOMI ZJE;Ll;0;L;;;;;N;;;0504;;0504 0506;CYRILLIC CAPITAL LETTER KOMI DZJE;Lu;0;L;;;;;N;;;;0507; 0507;CYRILLIC SMALL LETTER KOMI DZJE;Ll;0;L;;;;;N;;;0506;;0506 0508;CYRILLIC CAPITAL LETTER KOMI LJE;Lu;0;L;;;;;N;;;;0509; 0509;CYRILLIC SMALL LETTER KOMI LJE;Ll;0;L;;;;;N;;;0508;;0508 050A;CYRILLIC CAPITAL LETTER KOMI NJE;Lu;0;L;;;;;N;;;;050B; 050B;CYRILLIC SMALL LETTER KOMI NJE;Ll;0;L;;;;;N;;;050A;;050A 050C;CYRILLIC CAPITAL LETTER KOMI SJE;Lu;0;L;;;;;N;;;;050D; 050D;CYRILLIC SMALL LETTER KOMI SJE;Ll;0;L;;;;;N;;;050C;;050C 050E;CYRILLIC CAPITAL LETTER KOMI TJE;Lu;0;L;;;;;N;;;;050F; 050F;CYRILLIC SMALL LETTER KOMI TJE;Ll;0;L;;;;;N;;;050E;;050E 0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561; 0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562; 0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563; 0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564; 0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565; 0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566; 0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567; 0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568; 0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569; 053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A; 053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B; 053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C; 053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D; 053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E; 053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F; 0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570; 0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571; 0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572; 0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573; 0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574; 0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575; 0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576; 0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577; 0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578; 0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579; 054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A; 054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B; 054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C; 054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D; 054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E; 054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F; 0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580; 0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581; 0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582; 0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583; 0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584; 0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585; 0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586; 0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;; 055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;; 055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;; 055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;; 055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;; 055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;; 055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;; 0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531 0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532 0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533 0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534 0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535 0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536 0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537 0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538 0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539 056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A 056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B 056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C 056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D 056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E 056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F 0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540 0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541 0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542 0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543 0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544 0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545 0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546 0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547 0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548 0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549 057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A 057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B 057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C 057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D 057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E 057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F 0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550 0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551 0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552 0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553 0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554 0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555 0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556 0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L; 0565 0582;;;;N;;;;; 0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;; 058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;; 0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;; 0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;; 0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;; 0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;; 0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;; 0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;*;;; 0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;; 0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;*;;; 0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;; 059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;; 059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;; 059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;; 059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;; 059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;; 059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;; 05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;; 05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;; 05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;; 05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;; 05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;*;;; 05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;; 05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;; 05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;*;;; 05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;; 05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;*;;; 05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;; 05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;; 05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;; 05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;; 05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;; 05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;; 05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;; 05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;; 05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;; 05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;; 05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;; 05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;; 05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;; 05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;; 05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;; 05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;; 05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;or shuruq;;; 05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;*;;; 05BE;HEBREW PUNCTUATION MAQAF;Po;0;R;;;;;N;;;;; 05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;; 05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;*;;; 05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;; 05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;; 05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;*;;; 05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;; 05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;; 05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;; 05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;; 05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;; 05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;; 05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;; 05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;; 05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;; 05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;; 05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;; 05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;; 05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;; 05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;; 05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;; 05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;; 05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;; 05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;; 05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;; 05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;; 05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;; 05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;; 05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;; 05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;; 05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;; 05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;; 05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;; 05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;; 05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;; 05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;; 05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;; 05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;; 05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;; 060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;; 061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;; 061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;; 0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;; 0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;; 0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;; 0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;; 0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;; 0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;; 0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;; 0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;; 0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;; 062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;; 062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;; 062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;; 062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;; 062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;; 062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;; 0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;; 0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;; 0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; 0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;; 0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;; 0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;; 0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;; 0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;; 0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;; 0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;; 063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;; 0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;; 0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;; 0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;; 0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;; 0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;; 0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;; 0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;; 0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;; 0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;; 0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;; 064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;; 064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;; 064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;; 064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;; 064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;; 064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;; 0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;; 0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;; 0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;; 0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;; 0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;; 0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;; 0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;; 0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;; 0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;; 0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;; 0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;; 0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;; 0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;; 0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;; 0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;; 0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;; 066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;; 066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;; 066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;; 066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;; 066E;ARABIC LETTER DOTLESS BEH;Lo;0;AL;;;;;N;;;;; 066F;ARABIC LETTER DOTLESS QAF;Lo;0;AL;;;;;N;;;;; 0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;; 0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;; 0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;; 0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;; 0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;; 0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL; 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;; 0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL; 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;; 0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL; 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;; 0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL; 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;; 0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;; 067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;; 067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;; 067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;; 067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;; 067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;; 067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;; 0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;; 0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;; 0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;; 0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;; 0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;; 0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;; 0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;; 0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;; 0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;; 0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;; 068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; 068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;; 068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;; 068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;; 068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;; 068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;; 0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;; 0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;; 0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;; 0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;; 0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;; 0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;; 0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;; 0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;; 0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;; 069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;; 069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; 069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; 069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;; 06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;; 06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;; 06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;; 06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;; 06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;; 06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; 06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;; 06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;; 06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;; 06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;; 06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;; 06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;; 06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;*;;; 06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;; 06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;; 06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;; 06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;; 06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;; 06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; 06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; 06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; 06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;; 06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;; 06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;; 06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;; 06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; 06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;; 06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;; 06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;; 06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;; 06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;; 06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;; 06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;; 06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;; 06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;; 06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;; 06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; 06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;; 06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;; 06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;; 06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;; 06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;; 06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;*;;; 06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;; 06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;; 06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;; 06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;; 06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;; 06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; 06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;; 06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;; 06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;; 06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;; 06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;; 06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;; 06DD;ARABIC END OF AYAH;Cf;0;AL;;;;;N;;;;; 06DE;ARABIC START OF RUB EL HIZB;Me;0;NSM;;;;;N;;;;; 06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;; 06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;; 06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;; 06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;; 06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;; 06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;; 06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;; 06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;; 06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;; 06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;; 06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;; 06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;; 06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;; 06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;; 06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;; 06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;; 06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;; 06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;; 06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;; 06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;; 06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;; 06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;; 06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;; 06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;; 06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;; 06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; 06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; 06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;; 06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;; 06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;; 0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;; 0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;; 0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;; 0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;; 0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;; 0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;; 0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; 0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; 0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;; 0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;; 070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;; 070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;; 070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;; 070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;; 070F;SYRIAC ABBREVIATION MARK;Cf;0;BN;;;;;N;;;;; 0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;; 0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;; 0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;; 0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;; 0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;; 0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;; 0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;; 0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;; 0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;; 0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;; 071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;; 071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;; 071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;; 071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;; 071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;; 071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;; 0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;; 0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;; 0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;; 0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;; 0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;; 0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;; 0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;; 0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;; 0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;; 0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;; 072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;; 072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;; 072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;; 0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;; 0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;; 0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;; 0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;; 0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;; 0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;; 0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;; 0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;; 0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;; 0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;; 073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;; 073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;; 073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;; 073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;; 073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;; 073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;; 0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;; 0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;; 0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;; 0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; 0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;; 0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; 0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;; 0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;; 0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;; 0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;; 074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;; 0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;; 0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;; 0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;; 0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;; 0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;; 0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;; 0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;; 0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;; 0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;; 0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;; 078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;; 078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;; 078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;; 078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;; 078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;; 078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;; 0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;; 0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;; 0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;; 0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;; 0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;; 0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;; 0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;; 0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;; 0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;; 0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;; 079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;; 079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;; 079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;; 079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;; 079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;; 079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;; 07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;; 07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;; 07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;; 07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;; 07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;; 07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;; 07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;; 07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;; 07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;; 07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;; 07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;; 07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;; 07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;; 07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;; 07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;; 07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;; 07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;; 07B1;THAANA LETTER NAA;Lo;0;AL;;;;;N;;;;; 0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; 0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; 0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;; 0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;; 0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;; 0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;; 0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;; 090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;; 090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; 090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; 090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;; 090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;; 090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;; 0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;; 0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;; 0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;; 0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;; 0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;; 0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;; 0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;; 0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;; 0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;; 0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;; 091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;; 091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;; 091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;; 091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;; 091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;; 091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;; 0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;; 0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;; 0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;; 0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;; 0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;; 0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;; 0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;; 0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;; 0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;; 0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;; 092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;; 092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;; 092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;; 092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;; 092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;; 092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;; 0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;; 0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;; 0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;; 0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;; 0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;; 0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;; 0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;; 0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;; 0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;; 0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;; 093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; 093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; 093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; 0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; 0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; 0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; 0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; 0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; 0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;; 0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; 0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; 0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; 094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;; 094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; 094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; 094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;; 0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;; 0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;; 0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;; 0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;; 0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;; 0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;; 095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;; 095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;; 095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;; 095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;; 095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;; 095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;; 0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; 0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; 0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; 0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;; 0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;; 0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;; 0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;; 0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;; 0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;; 0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;; 0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;; 098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;; 098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; 098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; 098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;; 0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;; 0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;; 0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;; 0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;; 0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;; 0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;; 0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;; 0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;; 099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;; 099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;; 099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;; 099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;; 099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;; 099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;; 09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;; 09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;; 09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;; 09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;; 09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;; 09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;; 09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;; 09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;; 09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;; 09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;; 09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;; 09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;; 09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;; 09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;; 09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;; 09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;; 09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;; 09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;; 09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;; 09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;; 09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;; 09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; 09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; 09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; 09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; 09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; 09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; 09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;; 09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; 09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;; 09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;; 09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;; 09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;; 09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;; 09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;; 09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; 09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; 09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; 09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;Assamese;;; 09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;Assamese;;; 09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;; 09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; 09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1;N;;;;; 09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;2;N;;;;; 09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3;N;;;;; 09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;4;N;;;;; 09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;;N;;;;; 09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;; 09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;; 0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;; 0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;; 0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;; 0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;; 0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;; 0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;; 0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;; 0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;; 0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;; 0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;; 0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;; 0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;; 0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;; 0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;; 0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;; 0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;; 0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;; 0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;; 0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;; 0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;; 0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;; 0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;; 0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;; 0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;; 0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;; 0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;; 0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;; 0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;; 0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;; 0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;; 0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;; 0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;; 0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;; 0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;; 0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;; 0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;; 0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;; 0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;; 0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;; 0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;; 0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;; 0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;; 0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;; 0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;; 0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; 0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; 0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; 0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; 0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; 0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; 0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; 0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; 0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;; 0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;; 0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;; 0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;; 0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;; 0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;; 0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;; 0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;; 0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;; 0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;; 0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; 0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;; 0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;; 0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;; 0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;; 0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;; 0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;; 0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;; 0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; 0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;; 0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;; 0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;; 0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;; 0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;; 0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;; 0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;; 0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;; 0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;; 0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;; 0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;; 0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;; 0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;; 0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;; 0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;; 0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;; 0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;; 0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;; 0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;; 0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;; 0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;; 0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;; 0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;; 0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;; 0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;; 0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;; 0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;; 0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;; 0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;; 0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;; 0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;; 0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;; 0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;; 0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;; 0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;; 0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;; 0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;; 0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;; 0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;; 0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;; 0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; 0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; 0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; 0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; 0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; 0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; 0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; 0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;; 0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; 0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; 0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;; 0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; 0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; 0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;; 0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;; 0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;; 0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;; 0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;; 0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;; 0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;; 0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;; 0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; 0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; 0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;; 0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;; 0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;; 0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;; 0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;; 0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;; 0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;; 0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;; 0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;; 0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;; 0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;; 0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;; 0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;; 0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;; 0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;; 0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;; 0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;; 0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;; 0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;; 0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;; 0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;; 0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;; 0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;; 0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;; 0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;; 0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;; 0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;; 0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;; 0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;; 0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;; 0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;; 0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;; 0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;; 0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;; 0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;; 0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;; 0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;; 0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; 0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; 0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; 0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; 0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; 0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;; 0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;; 0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;; 0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;; 0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;; 0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;; 0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;; 0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;; 0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;; 0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; 0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;; 0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; 0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;; 0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;; 0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;; 0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;; 0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;; 0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;; 0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;; 0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;; 0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;; 0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;; 0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;; 0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;; 0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;; 0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;; 0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;; 0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;; 0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;; 0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;; 0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;; 0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;; 0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;; 0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;; 0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;; 0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;; 0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;; 0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;; 0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;; 0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;; 0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;; 0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;; 0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;; 0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;; 0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;; 0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;; 0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;; 0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;; 0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; 0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;; 0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; 0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;; 0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; 0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; 0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;; 0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;; 0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;; 0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;; 0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;; 0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;; 0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;; 0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; 0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;; 0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;; 0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;; 0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;; 0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;; 0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;; 0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;; 0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; 0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; 0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;; 0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;; 0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;; 0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;; 0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;; 0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;; 0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;; 0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;; 0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;; 0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;; 0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;; 0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;; 0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;; 0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;; 0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;; 0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;; 0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;; 0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;; 0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;; 0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;; 0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;; 0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;; 0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;; 0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;; 0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;; 0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;; 0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;; 0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;; 0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;; 0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;; 0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;; 0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;; 0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;; 0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;; 0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;; 0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;; 0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;; 0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;; 0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;; 0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;; 0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;; 0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; 0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; 0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;; 0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; 0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; 0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; 0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; 0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; 0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;; 0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; 0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;; 0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; 0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;; 0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;; 0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; 0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;; 0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;; 0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;; 0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;; 0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;; 0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;; 0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;; 0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; 0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; 0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;; 0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;; 0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;; 0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;; 0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;; 0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;; 0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;; 0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;; 0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;; 0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;; 0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;; 0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;; 0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;; 0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;; 0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;; 0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;; 0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;; 0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;; 0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;; 0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;; 0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;; 0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;; 0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;; 0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;; 0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;; 0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;; 0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;; 0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;; 0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;; 0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;; 0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;; 0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;; 0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;; 0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;; 0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;; 0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;; 0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;; 0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;; 0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;; 0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;; 0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;; 0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 0CBF;KANNADA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;; 0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;; 0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; 0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; 0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; 0CC6;KANNADA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; 0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;; 0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;; 0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;; 0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;; 0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; 0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;; 0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;; 0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;; 0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; 0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;; 0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;; 0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;; 0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;; 0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;; 0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;; 0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;; 0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; 0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; 0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;; 0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;; 0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;; 0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;; 0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;; 0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;; 0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;; 0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;; 0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;; 0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;; 0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;; 0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;; 0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;; 0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;; 0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;; 0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;; 0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;; 0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;; 0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;; 0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;; 0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;; 0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;; 0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;; 0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;; 0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;; 0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;; 0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;; 0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;; 0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;; 0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;; 0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;; 0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;; 0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;; 0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;; 0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;; 0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;; 0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;; 0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;; 0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;; 0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;; 0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;; 0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;; 0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;; 0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;; 0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; 0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; 0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;; 0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; 0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; 0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;; 0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;; 0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;; 0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;; 0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; 0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;; 0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;; 0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;; 0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;; 0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;; 0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;; 0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;; 0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;; 0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;; 0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;; 0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;; 0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;; 0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;; 0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;; 0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;; 0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;; 0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;; 0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;; 0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;; 0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;; 0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; 0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;; 0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; 0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;; 0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; 0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;; 0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; 0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;; 0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; 0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;; 0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;; 0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;; 0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;; 0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; 0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;; 0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; 0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;; 0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;; 0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;; 0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; 0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;; 0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; 0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;; 0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;; 0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;; 0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; 0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;; 0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; 0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;; 0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;; 0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;; 0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;; 0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;; 0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;; 0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;; 0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;; 0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;; 0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;; 0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;; 0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;; 0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;; 0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;; 0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;; 0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;; 0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;; 0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;; 0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;; 0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;; 0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;; 0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;; 0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;; 0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;; 0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;; 0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;; 0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;; 0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;; 0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;; 0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;; 0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;; 0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;; 0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;; 0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;; 0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;; 0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;; 0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;; 0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;; 0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;; 0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;; 0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;; 0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;; 0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;; 0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;; 0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;; 0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;; 0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;; 0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;; 0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;; 0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;; 0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;; 0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;; 0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;; 0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;; 0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;; 0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;; 0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;; 0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;; 0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;; 0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;; 0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;; 0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;; 0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;; 0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;; 0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;; 0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;; 0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;; 0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;; 0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;; 0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;; 0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;; 0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;; 0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;; 0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;; 0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;; 0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;; 0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;; 0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;; 0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;paiyan noi;;; 0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;; 0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;; 0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;; 0E33;THAI CHARACTER SARA AM;Lo;0;L; 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;; 0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;; 0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;; 0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;; 0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;sara uue;;; 0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;; 0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;; 0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;; 0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;; 0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;; 0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;; 0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;; 0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;sara ai mai muan;;; 0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;sara ai mai malai;;; 0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;lakkhang yao;;; 0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;mai yamok;;; 0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;mai taikhu;;; 0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;; 0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;; 0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;; 0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;; 0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;; 0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;nikkhahit;;; 0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;; 0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;; 0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;; 0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;; 0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;; 0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;; 0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;; 0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;; 0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;; 0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;; 0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;; 0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;; 0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;; 0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;; 0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;; 0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;; 0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;; 0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;; 0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;; 0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;; 0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;; 0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;; 0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;; 0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;; 0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;; 0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;; 0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;; 0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;; 0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;; 0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;; 0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;; 0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;; 0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;; 0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;; 0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;; 0EB3;LAO VOWEL SIGN AM;Lo;0;L; 0ECD 0EB2;;;;N;;;;; 0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; 0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; 0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; 0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;; 0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;; 0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;; 0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;; 0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;; 0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;; 0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;; 0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;; 0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;; 0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;; 0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;; 0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;; 0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;; 0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;; 0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;; 0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;; 0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;; 0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0EDC;LAO HO NO;Lo;0;L; 0EAB 0E99;;;;N;;;;; 0EDD;LAO HO MO;Lo;0;L; 0EAB 0EA1;;;;N;;;;; 0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;; 0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;ter yik go a thung;;; 0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;ter yik go wum nam chey ma;;; 0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;ter yik go wum ter tsek ma;;; 0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;yik go dun ma;;; 0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;yik go kab ma;;; 0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;yik go pur shey ma;;; 0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;yik go tsek shey ma;;; 0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;drul shey;;; 0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;kur yik go;;; 0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;ka sho yik go;;; 0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;tsek;;; 0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L; 0F0B;;;;N;;tsek tar;;; 0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;shey;;; 0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;nyi shey;;; 0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;tsek shey;;; 0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;nyi tsek shey;;; 0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;rinchen pung shey;;; 0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;gya tram shey;;; 0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;dzu ta me long chen;;; 0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;ter tsek;;; 0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;che ta;;; 0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;hlak ta;;; 0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;trachen char ta;;; 0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;kyu pa;;; 0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;dong tsu;;; 0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;deka chig;;; 0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;deka nyi;;; 0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;deka sum;;; 0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;dena chig;;; 0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;dena nyi;;; 0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;deka dena;;; 0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;1/2;N;;;;; 0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;3/2;N;;;;; 0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;5/2;N;;;;; 0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;7/2;N;;;;; 0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;9/2;N;;;;; 0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;11/2;N;;;;; 0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;13/2;N;;;;; 0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;; 0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;; 0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;; 0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;du ta;;; 0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;nge zung nyi da;;; 0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;dzu ta shi mig chen;;; 0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;nge zung gor ta;;; 0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;che go;;; 0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;tsa tru;;; 0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;N;;gug ta yun;;; 0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;N;;gug ta ye;;; 0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;N;TIBETAN LEFT BRACE;ang kang yun;;; 0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;N;TIBETAN RIGHT BRACE;ang kang ye;;; 0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;yar tse;;; 0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;mar tse;;; 0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;; 0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;; 0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;; 0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;; 0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;; 0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;; 0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;; 0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;; 0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;; 0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;; 0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;; 0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;; 0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;; 0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;; 0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;; 0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;; 0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;; 0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;; 0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;; 0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;; 0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;; 0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;; 0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;; 0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;; 0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;; 0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;; 0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;; 0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;; 0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;; 0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;; 0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;; 0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;; 0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;; 0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;*;;; 0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;; 0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;; 0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;; 0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;; 0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;; 0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;; 0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;; 0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;*;;; 0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;; 0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;; 0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;; 0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;; 0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;; 0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;; 0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM; 0FB2 0F81;;;;N;;;;; 0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;; 0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM; 0FB3 0F81;;;;N;;;;; 0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;; 0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;; 0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;; 0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;; 0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;je su nga ro;;; 0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;nam chey;;; 0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;; 0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;; 0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;nyi da na da;;; 0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;nan de;;; 0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;; 0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;; 0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;ji ta;;; 0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;yang ta;;; 0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;che tsa chen;;; 0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;chu chen;;; 0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;tru chen ging;;; 0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;tru me ging;;; 0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;; 0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;; 0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;; 0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;; 0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;; 0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;; 0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;; 0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;; 0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;; 0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;; 0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;; 0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;; 0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;; 0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;; 0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;; 0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;; 0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;; 0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;; 0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;; 0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;; 0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;; 0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;; 0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;; 0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;; 0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;; 0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;; 0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;; 0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;; 0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;*;;; 0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;; 0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;; 0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;; 0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;*;;; 0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;*;;; 0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;; 0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;; 0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;; 0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;; 0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;; 0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;; 0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;; 0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;*;;; 0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;*;;; 0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;*;;; 0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;kuruka;;; 0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;kuruka shi mik chen;;; 0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;; 0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;; 0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;chang tyu;;; 0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;bub chey;;; 0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;drilbu;;; 0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;dorje;;; 0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;pema den;;; 0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;dorje gya dram;;; 0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;phurba;;; 0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;norbu;;; 0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;norbu nyi khyi;;; 0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;norbu sum khyi;;; 0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;norbu shi khyi;;; 0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;dena sum;;; 1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;; 1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;; 1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;; 1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;; 1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;; 1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;; 1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;; 1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;; 1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;; 1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;; 100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;; 100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;; 100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;; 100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;; 100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;; 100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;; 1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;; 1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;; 1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;; 1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;; 1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;; 1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;; 1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;; 1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;; 1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;; 1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;; 101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;; 101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;; 101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;; 101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;; 101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;; 101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;; 1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;; 1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;; 1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;; 1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;; 1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;; 1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;; 1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;; 1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;; 102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;; 102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; 102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; 1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;; 1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; 1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; 1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;; 1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;; 1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;; 104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;; 104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;; 104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;; 104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;; 104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;; 1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;; 1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;; 1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; 1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; 1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; 1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; 1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;; 1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;; 1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; 1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; 10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;Khutsuri;;; 10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;Khutsuri;;; 10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;Khutsuri;;; 10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;Khutsuri;;; 10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;Khutsuri;;; 10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;Khutsuri;;; 10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;Khutsuri;;; 10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;Khutsuri;;; 10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;Khutsuri;;; 10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;Khutsuri;;; 10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;Khutsuri;;; 10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;Khutsuri;;; 10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;Khutsuri;;; 10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;Khutsuri;;; 10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;Khutsuri;;; 10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;Khutsuri;;; 10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;Khutsuri;;; 10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;Khutsuri;;; 10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;Khutsuri;;; 10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;Khutsuri;;; 10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;Khutsuri;;; 10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;Khutsuri;;; 10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;Khutsuri;;; 10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;Khutsuri;;; 10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;Khutsuri;;; 10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;Khutsuri;;; 10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;Khutsuri;;; 10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;Khutsuri;;; 10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;Khutsuri;;; 10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;Khutsuri;;; 10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;Khutsuri;;; 10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;Khutsuri;;; 10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;Khutsuri;;; 10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;Khutsuri;;; 10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;Khutsuri;;; 10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;Khutsuri;;; 10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;Khutsuri;;; 10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;Khutsuri;;; 10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;; 10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;; 10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;; 10D3;GEORGIAN LETTER DON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;;; 10D4;GEORGIAN LETTER EN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;;; 10D5;GEORGIAN LETTER VIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;;; 10D6;GEORGIAN LETTER ZEN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;;; 10D7;GEORGIAN LETTER TAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;;; 10D8;GEORGIAN LETTER IN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;;; 10D9;GEORGIAN LETTER KAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;;; 10DA;GEORGIAN LETTER LAS;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;;; 10DB;GEORGIAN LETTER MAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;;; 10DC;GEORGIAN LETTER NAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;;; 10DD;GEORGIAN LETTER ON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;;; 10DE;GEORGIAN LETTER PAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;;; 10DF;GEORGIAN LETTER ZHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;;; 10E0;GEORGIAN LETTER RAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;;; 10E1;GEORGIAN LETTER SAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;;; 10E2;GEORGIAN LETTER TAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;;; 10E3;GEORGIAN LETTER UN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;;; 10E4;GEORGIAN LETTER PHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;;; 10E5;GEORGIAN LETTER KHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;;; 10E6;GEORGIAN LETTER GHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;;; 10E7;GEORGIAN LETTER QAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;;; 10E8;GEORGIAN LETTER SHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;;; 10E9;GEORGIAN LETTER CHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;;; 10EA;GEORGIAN LETTER CAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;;; 10EB;GEORGIAN LETTER JIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;;; 10EC;GEORGIAN LETTER CIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;;; 10ED;GEORGIAN LETTER CHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;;; 10EE;GEORGIAN LETTER XAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;;; 10EF;GEORGIAN LETTER JHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;;; 10F0;GEORGIAN LETTER HAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;;; 10F1;GEORGIAN LETTER HE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;;; 10F2;GEORGIAN LETTER HIE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;;; 10F3;GEORGIAN LETTER WE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;;; 10F4;GEORGIAN LETTER HAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;;; 10F5;GEORGIAN LETTER HOE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;;; 10F6;GEORGIAN LETTER FI;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;;; 10F7;GEORGIAN LETTER YN;Lo;0;L;;;;;N;;;;; 10F8;GEORGIAN LETTER ELIFI;Lo;0;L;;;;;N;;;;; 10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; 1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;; 1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;; 1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;n *;;; 1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;; 1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;dd *;;; 1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;r *;;; 1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;m *;;; 1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;b *;;; 1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;bb *;;; 1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;s *;;; 110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;; 110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;; 110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;j *;;; 110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;jj *;;; 110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;; 110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;; 1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;; 1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;; 1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;h *;;; 1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; 1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;; 1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; 1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;; 1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; 1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; 1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; 111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;; 111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;; 111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; 111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; 111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; 111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;; 1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;; 1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;; 1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; 1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; 1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;; 1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;; 1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;; 1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;; 1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;; 1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;; 112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; 112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; 112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;; 112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; 112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;; 112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; 1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; 1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;; 1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; 1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;; 1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;; 1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;; 1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;; 1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;; 1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;; 1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;; 113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;; 113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;; 113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;; 113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; 113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;; 113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;; 1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;; 1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; 1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;; 1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;; 1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;; 1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;; 1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; 1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; 1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;; 1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;; 114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;; 114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;; 114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; 114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;; 114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;; 114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; 1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;; 1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;; 1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;; 1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;; 1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;; 1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;; 1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; 1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; 1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;; 1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; 115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;; 1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;; 1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;; 1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;; 1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;; 1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;; 1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;; 1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;; 1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;; 1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;; 1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;; 116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;; 116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;; 116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;; 116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;; 116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;; 116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;; 1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;; 1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;; 1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;; 1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;; 1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;; 1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;; 1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;; 1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;; 1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;; 1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;; 117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;; 117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;; 117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;; 117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;; 117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;; 117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;; 1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;; 1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;; 1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;; 1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;; 1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;; 1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;; 1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;; 1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;; 1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;; 1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;; 118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;; 118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;; 118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;; 118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;; 118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;; 118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;; 1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;; 1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;; 1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;; 1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;; 1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;; 1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;; 1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;; 1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;; 1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;; 1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;; 119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;; 119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;; 119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;; 119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;; 119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;; 119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;; 11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;; 11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;; 11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;; 11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;; 11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;; 11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;gs *;;; 11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;n *;;; 11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;nj *;;; 11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;nh *;;; 11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;; 11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;l *;;; 11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;lg *;;; 11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;lm *;;; 11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;lb *;;; 11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;ls *;;; 11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;lt *;;; 11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;lp *;;; 11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;lh *;;; 11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;m *;;; 11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;b *;;; 11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;bs *;;; 11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;s *;;; 11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;; 11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;ng *;;; 11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;j *;;; 11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;; 11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;; 11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;; 11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;; 11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;h *;;; 11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;; 11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; 11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;; 11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;; 11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;; 11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;; 11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;; 11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;; 11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;; 11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;; 11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;; 11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;; 11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;; 11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;; 11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; 11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;; 11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;; 11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; 11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; 11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;; 11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;; 11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;; 11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;; 11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;; 11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;; 11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;; 11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;; 11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;; 11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;; 11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;; 11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;; 11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;; 11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;; 11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;; 11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;; 11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;; 11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;; 11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;; 11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;; 11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;; 11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;; 11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;; 11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;; 11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;; 11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;; 11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;; 11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;; 11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;; 11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;; 11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;; 11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;; 11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;; 11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;; 11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;; 11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;; 1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;; 1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;; 1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;; 1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;; 1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;; 1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;; 1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;; 1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;; 1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;; 120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;; 120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;; 120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;; 120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;; 120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;; 120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;; 1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;; 1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;; 1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;; 1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;; 1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;; 1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;; 1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;; 1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;; 1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;; 1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;; 121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;; 121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;; 121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;; 121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;; 121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;; 121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;; 1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;; 1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;; 1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;; 1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;; 1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;; 1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;; 1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;; 1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;; 1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;; 1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;; 122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;; 122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;; 122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;; 122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;; 122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;; 122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;; 1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;; 1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;; 1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;; 1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;; 1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;; 1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;; 1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;; 1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;; 1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;; 1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;; 123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;; 123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;; 123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;; 123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;; 123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;; 123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;; 1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;; 1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;; 1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;; 1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;; 1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;; 1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;; 1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;; 1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;; 124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;; 124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;; 124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;; 124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;; 1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;; 1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;; 1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;; 1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;; 1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;; 1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;; 1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;; 1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;; 125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;; 125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;; 125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;; 125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;; 1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;; 1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;; 1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;; 1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;; 1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;; 1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;; 1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;; 1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;; 1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;; 1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;; 126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;; 126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;; 126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;; 126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;; 126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;; 126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;; 1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;; 1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;; 1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;; 1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;; 1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;; 1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;; 1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;; 1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;; 1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;; 1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;; 127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;; 127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;; 127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;; 127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;; 127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;; 127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;; 1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;; 1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;; 1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;; 1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;; 1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;; 1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;; 1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;; 1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;; 128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;; 128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;; 128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;; 128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;; 1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;; 1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;; 1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;; 1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;; 1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;; 1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;; 1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;; 1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;; 1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;; 1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;; 129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;; 129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;; 129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;; 129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;; 129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;; 129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;; 12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;; 12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;; 12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;; 12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;; 12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;; 12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;; 12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;; 12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;; 12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;; 12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;; 12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;; 12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;; 12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;; 12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;; 12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;; 12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;; 12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;; 12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;; 12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;; 12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;; 12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;; 12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;; 12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;; 12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;; 12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;; 12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;; 12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;; 12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;; 12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;; 12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;; 12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;; 12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;; 12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;; 12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;; 12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;; 12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;; 12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;; 12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;; 12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;; 12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;; 12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;; 12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;; 12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;; 12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;; 12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;; 12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;; 12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;; 12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;; 12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;; 12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;; 12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;; 12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;; 12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;; 12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;; 12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; 12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; 12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;; 12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;; 12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;; 12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; 12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; 12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;; 12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;; 12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;; 12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;; 12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;; 12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;; 12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;; 12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;; 12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;; 12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;; 12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;; 12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;; 12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;; 12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;; 12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;; 12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;; 12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;; 12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;; 12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;; 12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;; 12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;; 12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;; 12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;; 12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;; 1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;; 1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;; 1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;; 1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;; 1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;; 1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;; 1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;; 1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;; 1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;; 1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;; 130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;; 130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;; 130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;; 130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;; 130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;; 1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;; 1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;; 1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;; 1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;; 1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;; 1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;; 1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;; 131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;; 131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;; 131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;; 131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;; 131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;; 1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;; 1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;; 1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;; 1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;; 1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;; 1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;; 1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;; 1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;; 1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;; 1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;; 132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;; 132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;; 132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;; 132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;; 132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;; 132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;; 1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;; 1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;; 1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;; 1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;; 1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;; 1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;; 1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;; 1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;; 1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;; 1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;; 133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;; 133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;; 133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;; 133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;; 133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;; 133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;; 1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;; 1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;; 1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;; 1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;; 1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;; 1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;; 1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;; 1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;; 1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;; 134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;; 134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;; 134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;; 134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;; 134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;; 134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;; 1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;; 1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;; 1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;; 1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;; 1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;; 1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;; 1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;; 1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;; 1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;; 1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;; 135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;; 1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;; 1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;; 1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;; 1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;; 1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;; 1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;; 1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;; 1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; 1369;ETHIOPIC DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 136A;ETHIOPIC DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 136B;ETHIOPIC DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 136C;ETHIOPIC DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 136D;ETHIOPIC DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 136E;ETHIOPIC DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 136F;ETHIOPIC DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 1370;ETHIOPIC DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 1371;ETHIOPIC DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;; 1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;; 1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;; 1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;; 1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;; 1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;; 1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;; 1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;; 137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;; 137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;; 137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;; 13A0;CHEROKEE LETTER A;Lo;0;L;;;;;N;;;;; 13A1;CHEROKEE LETTER E;Lo;0;L;;;;;N;;;;; 13A2;CHEROKEE LETTER I;Lo;0;L;;;;;N;;;;; 13A3;CHEROKEE LETTER O;Lo;0;L;;;;;N;;;;; 13A4;CHEROKEE LETTER U;Lo;0;L;;;;;N;;;;; 13A5;CHEROKEE LETTER V;Lo;0;L;;;;;N;;;;; 13A6;CHEROKEE LETTER GA;Lo;0;L;;;;;N;;;;; 13A7;CHEROKEE LETTER KA;Lo;0;L;;;;;N;;;;; 13A8;CHEROKEE LETTER GE;Lo;0;L;;;;;N;;;;; 13A9;CHEROKEE LETTER GI;Lo;0;L;;;;;N;;;;; 13AA;CHEROKEE LETTER GO;Lo;0;L;;;;;N;;;;; 13AB;CHEROKEE LETTER GU;Lo;0;L;;;;;N;;;;; 13AC;CHEROKEE LETTER GV;Lo;0;L;;;;;N;;;;; 13AD;CHEROKEE LETTER HA;Lo;0;L;;;;;N;;;;; 13AE;CHEROKEE LETTER HE;Lo;0;L;;;;;N;;;;; 13AF;CHEROKEE LETTER HI;Lo;0;L;;;;;N;;;;; 13B0;CHEROKEE LETTER HO;Lo;0;L;;;;;N;;;;; 13B1;CHEROKEE LETTER HU;Lo;0;L;;;;;N;;;;; 13B2;CHEROKEE LETTER HV;Lo;0;L;;;;;N;;;;; 13B3;CHEROKEE LETTER LA;Lo;0;L;;;;;N;;;;; 13B4;CHEROKEE LETTER LE;Lo;0;L;;;;;N;;;;; 13B5;CHEROKEE LETTER LI;Lo;0;L;;;;;N;;;;; 13B6;CHEROKEE LETTER LO;Lo;0;L;;;;;N;;;;; 13B7;CHEROKEE LETTER LU;Lo;0;L;;;;;N;;;;; 13B8;CHEROKEE LETTER LV;Lo;0;L;;;;;N;;;;; 13B9;CHEROKEE LETTER MA;Lo;0;L;;;;;N;;;;; 13BA;CHEROKEE LETTER ME;Lo;0;L;;;;;N;;;;; 13BB;CHEROKEE LETTER MI;Lo;0;L;;;;;N;;;;; 13BC;CHEROKEE LETTER MO;Lo;0;L;;;;;N;;;;; 13BD;CHEROKEE LETTER MU;Lo;0;L;;;;;N;;;;; 13BE;CHEROKEE LETTER NA;Lo;0;L;;;;;N;;;;; 13BF;CHEROKEE LETTER HNA;Lo;0;L;;;;;N;;;;; 13C0;CHEROKEE LETTER NAH;Lo;0;L;;;;;N;;;;; 13C1;CHEROKEE LETTER NE;Lo;0;L;;;;;N;;;;; 13C2;CHEROKEE LETTER NI;Lo;0;L;;;;;N;;;;; 13C3;CHEROKEE LETTER NO;Lo;0;L;;;;;N;;;;; 13C4;CHEROKEE LETTER NU;Lo;0;L;;;;;N;;;;; 13C5;CHEROKEE LETTER NV;Lo;0;L;;;;;N;;;;; 13C6;CHEROKEE LETTER QUA;Lo;0;L;;;;;N;;;;; 13C7;CHEROKEE LETTER QUE;Lo;0;L;;;;;N;;;;; 13C8;CHEROKEE LETTER QUI;Lo;0;L;;;;;N;;;;; 13C9;CHEROKEE LETTER QUO;Lo;0;L;;;;;N;;;;; 13CA;CHEROKEE LETTER QUU;Lo;0;L;;;;;N;;;;; 13CB;CHEROKEE LETTER QUV;Lo;0;L;;;;;N;;;;; 13CC;CHEROKEE LETTER SA;Lo;0;L;;;;;N;;;;; 13CD;CHEROKEE LETTER S;Lo;0;L;;;;;N;;;;; 13CE;CHEROKEE LETTER SE;Lo;0;L;;;;;N;;;;; 13CF;CHEROKEE LETTER SI;Lo;0;L;;;;;N;;;;; 13D0;CHEROKEE LETTER SO;Lo;0;L;;;;;N;;;;; 13D1;CHEROKEE LETTER SU;Lo;0;L;;;;;N;;;;; 13D2;CHEROKEE LETTER SV;Lo;0;L;;;;;N;;;;; 13D3;CHEROKEE LETTER DA;Lo;0;L;;;;;N;;;;; 13D4;CHEROKEE LETTER TA;Lo;0;L;;;;;N;;;;; 13D5;CHEROKEE LETTER DE;Lo;0;L;;;;;N;;;;; 13D6;CHEROKEE LETTER TE;Lo;0;L;;;;;N;;;;; 13D7;CHEROKEE LETTER DI;Lo;0;L;;;;;N;;;;; 13D8;CHEROKEE LETTER TI;Lo;0;L;;;;;N;;;;; 13D9;CHEROKEE LETTER DO;Lo;0;L;;;;;N;;;;; 13DA;CHEROKEE LETTER DU;Lo;0;L;;;;;N;;;;; 13DB;CHEROKEE LETTER DV;Lo;0;L;;;;;N;;;;; 13DC;CHEROKEE LETTER DLA;Lo;0;L;;;;;N;;;;; 13DD;CHEROKEE LETTER TLA;Lo;0;L;;;;;N;;;;; 13DE;CHEROKEE LETTER TLE;Lo;0;L;;;;;N;;;;; 13DF;CHEROKEE LETTER TLI;Lo;0;L;;;;;N;;;;; 13E0;CHEROKEE LETTER TLO;Lo;0;L;;;;;N;;;;; 13E1;CHEROKEE LETTER TLU;Lo;0;L;;;;;N;;;;; 13E2;CHEROKEE LETTER TLV;Lo;0;L;;;;;N;;;;; 13E3;CHEROKEE LETTER TSA;Lo;0;L;;;;;N;;;;; 13E4;CHEROKEE LETTER TSE;Lo;0;L;;;;;N;;;;; 13E5;CHEROKEE LETTER TSI;Lo;0;L;;;;;N;;;;; 13E6;CHEROKEE LETTER TSO;Lo;0;L;;;;;N;;;;; 13E7;CHEROKEE LETTER TSU;Lo;0;L;;;;;N;;;;; 13E8;CHEROKEE LETTER TSV;Lo;0;L;;;;;N;;;;; 13E9;CHEROKEE LETTER WA;Lo;0;L;;;;;N;;;;; 13EA;CHEROKEE LETTER WE;Lo;0;L;;;;;N;;;;; 13EB;CHEROKEE LETTER WI;Lo;0;L;;;;;N;;;;; 13EC;CHEROKEE LETTER WO;Lo;0;L;;;;;N;;;;; 13ED;CHEROKEE LETTER WU;Lo;0;L;;;;;N;;;;; 13EE;CHEROKEE LETTER WV;Lo;0;L;;;;;N;;;;; 13EF;CHEROKEE LETTER YA;Lo;0;L;;;;;N;;;;; 13F0;CHEROKEE LETTER YE;Lo;0;L;;;;;N;;;;; 13F1;CHEROKEE LETTER YI;Lo;0;L;;;;;N;;;;; 13F2;CHEROKEE LETTER YO;Lo;0;L;;;;;N;;;;; 13F3;CHEROKEE LETTER YU;Lo;0;L;;;;;N;;;;; 13F4;CHEROKEE LETTER YV;Lo;0;L;;;;;N;;;;; 1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;; 1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;; 1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;; 1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;; 1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;; 1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;; 1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;; 1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;; 1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;; 140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;; 140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;; 140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;; 140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;; 140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;; 140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;; 1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;; 1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;; 1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;; 1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;; 1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;; 1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;; 1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;; 1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;; 1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;; 1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;; 141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;; 141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;; 141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;; 141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;; 141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;; 141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;; 1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;; 1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;; 1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;; 1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;; 1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;; 1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;; 1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;; 1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;; 1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;; 1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;; 142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;; 142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;; 142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;; 142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;; 142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;; 142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;; 1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;; 1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;; 1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;; 1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;; 1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;; 1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;; 1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;; 1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;; 1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;; 1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;; 143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;; 143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;; 143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;; 143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;; 143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;; 143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;; 1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;; 1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;; 1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;; 1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;; 1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;; 1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;; 1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;; 1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;; 1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;; 1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;; 144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;; 144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;; 144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;; 144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;; 144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;; 144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;; 1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;; 1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;; 1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;; 1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;; 1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;; 1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;; 1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;; 1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;; 1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;; 1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;; 145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;; 145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;; 145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;; 145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;; 145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;; 145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;; 1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;; 1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;; 1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;; 1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;; 1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;; 1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;; 1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;; 1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;; 1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;; 1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;; 146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;; 146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;; 146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;; 146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;; 146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;; 146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;; 1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;; 1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;; 1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;; 1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;; 1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;; 1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;; 1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;; 1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;; 1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;; 1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;; 147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;; 147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;; 147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;; 147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;; 147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;; 147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;; 1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;; 1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;; 1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;; 1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;; 1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;; 1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;; 1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;; 1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;; 1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;; 1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;; 148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;; 148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;; 148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;; 148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;; 148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;; 148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;; 1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;; 1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;; 1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;; 1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;; 1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;; 1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;; 1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;; 1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;; 1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;; 1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;; 149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;; 149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;; 149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;; 149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;; 149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;; 149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;; 14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;; 14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;; 14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;; 14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;; 14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;; 14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;; 14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;; 14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;; 14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;; 14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;; 14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;; 14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;; 14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;; 14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;; 14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;; 14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;; 14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;; 14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;; 14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;; 14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;; 14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;; 14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;; 14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;; 14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;; 14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;; 14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;; 14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;; 14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;; 14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;; 14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;; 14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;; 14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;; 14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;; 14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;; 14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;; 14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;; 14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;; 14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;; 14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;; 14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;; 14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;; 14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;; 14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;; 14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;; 14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;; 14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;; 14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;; 14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;; 14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;; 14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;; 14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;; 14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;; 14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;; 14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;; 14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;; 14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;; 14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;; 14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;; 14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;; 14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;; 14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;; 14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;; 14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;; 14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;; 14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;; 14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;; 14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;; 14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;; 14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;; 14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;; 14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;; 14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;; 14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;; 14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;; 14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;; 14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;; 14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;; 14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;; 14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;; 14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;; 14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;; 14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;; 14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;; 14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;; 14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;; 14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;; 14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;; 14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;; 14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;; 14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;; 14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;; 14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;; 14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;; 14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;; 14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;; 14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;; 1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;; 1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;; 1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;; 1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;; 1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;; 1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;; 1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;; 1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;; 1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;; 1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;; 150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;; 150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;; 150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;; 150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;; 150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;; 150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;; 1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;; 1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;; 1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;; 1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;; 1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;; 1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;; 1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;; 1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;; 1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;; 1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;; 151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;; 151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;; 151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;; 151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;; 151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;; 151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;; 1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;; 1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;; 1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;; 1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;; 1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;; 1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;; 1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;; 1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;; 1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;; 1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;; 152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;; 152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;; 152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;; 152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;; 152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;; 152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;; 1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;; 1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;; 1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;; 1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;; 1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;; 1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;; 1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;; 1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;; 1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;; 1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;; 153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;; 153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;; 153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;; 153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;; 153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;; 153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;; 1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;; 1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;; 1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;; 1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;; 1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;; 1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;; 1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;; 1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;; 1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;; 1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;; 154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;; 154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;; 154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;; 154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;; 154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;; 154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;; 1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;; 1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;; 1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;; 1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;; 1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;; 1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;; 1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;; 1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;; 1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;; 1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;; 155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;; 155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;; 155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;; 155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;; 155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;; 155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;; 1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;; 1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;; 1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;; 1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;; 1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;; 1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;; 1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;; 1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;; 1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;; 1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;; 156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;; 156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;; 156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;; 156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;; 156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;; 156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;; 1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;; 1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;; 1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;; 1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;; 1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;; 1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;; 1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;; 1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;; 1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;; 1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;; 157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;; 157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;; 157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;; 157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;; 157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;; 157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;; 1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;; 1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;; 1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;; 1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;; 1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;; 1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;; 1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;; 1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;; 1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;; 1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;; 158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;; 158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;; 158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;; 158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;; 158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;; 158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;; 1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;; 1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;; 1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;; 1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;; 1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;; 1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;; 1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;; 1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;; 1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;; 1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;; 159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;; 159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;; 159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;; 159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;; 159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;; 159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;; 15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;; 15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;; 15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;; 15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;; 15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;; 15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;; 15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;; 15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;; 15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;; 15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;; 15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;; 15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;; 15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;; 15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;; 15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;; 15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;; 15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;; 15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;; 15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;; 15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;; 15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;; 15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;; 15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;; 15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;; 15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;; 15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;; 15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;; 15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;; 15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;; 15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;; 15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;; 15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;; 15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;; 15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;; 15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;; 15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;; 15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;; 15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;; 15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;; 15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;; 15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;; 15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;; 15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;; 15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;; 15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;; 15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;; 15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;; 15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;; 15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;; 15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;; 15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;; 15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;; 15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;; 15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;; 15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;; 15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;; 15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;; 15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;; 15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;; 15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;; 15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;; 15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;; 15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;; 15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;; 15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;; 15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;; 15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;; 15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;; 15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;; 15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;; 15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;; 15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;; 15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;; 15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;; 15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;; 15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;; 15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;; 15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;; 15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;; 15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;; 15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;; 15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;; 15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;; 15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;; 15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;; 15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;; 15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;; 15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;; 15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;; 15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;; 15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;; 15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;; 15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;; 15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;; 15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;; 15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;; 1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;; 1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;; 1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;; 1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;; 1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;; 1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;; 1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;; 1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;; 1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;; 1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;; 160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;; 160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;; 160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;; 160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;; 160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;; 160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;; 1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;; 1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;; 1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;; 1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;; 1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;; 1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;; 1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;; 1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;; 1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;; 1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;; 161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;; 161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;; 161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;; 161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;; 161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;; 161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;; 1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;; 1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;; 1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;; 1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;; 1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;; 1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;; 1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;; 1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;; 1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;; 1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;; 162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;; 162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;; 162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;; 162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;; 162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;; 162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;; 1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;; 1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;; 1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;; 1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;; 1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;; 1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;; 1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;; 1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;; 1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;; 1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;; 163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;; 163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;; 163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;; 163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;; 163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;; 163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;; 1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;; 1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;; 1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;; 1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;; 1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;; 1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;; 1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;; 1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;; 1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;; 1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;; 164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;; 164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;; 164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;; 164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;; 164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;; 164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;; 1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;; 1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;; 1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;; 1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;; 1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;; 1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;; 1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;; 1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;; 1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;; 1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;; 165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;; 165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;; 165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;; 165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;; 165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;; 165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;; 1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;; 1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;; 1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;; 1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;; 1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;; 1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;; 1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;; 1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;; 1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;; 1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;; 166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;; 166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;; 166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;; 166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;; 166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;; 166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;; 1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;; 1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;; 1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;; 1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;; 1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;; 1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;; 1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;; 1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;; 1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;; 1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;; 1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;; 1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;; 1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;; 1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;; 1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;; 1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;; 1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;; 168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;; 168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;; 168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;; 168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;; 168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;; 168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;; 1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;; 1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;; 1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;; 1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;; 1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;; 1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;; 1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;; 1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;; 1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;; 1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;; 169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;; 169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;N;;;;; 169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;N;;;;; 16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;; 16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;; 16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;; 16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;; 16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;; 16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;; 16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;; 16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;; 16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;; 16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;; 16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;; 16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;; 16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;; 16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;; 16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;; 16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;; 16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;; 16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;; 16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;; 16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;; 16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;; 16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;; 16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;; 16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;; 16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;; 16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;; 16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;; 16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;; 16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;; 16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;; 16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;; 16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;; 16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;; 16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;; 16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;; 16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;; 16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;; 16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;; 16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;; 16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;; 16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;; 16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;; 16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;; 16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;; 16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;; 16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;; 16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;; 16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;; 16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;; 16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;; 16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;; 16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;; 16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;; 16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;; 16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;; 16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;; 16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;; 16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;; 16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;; 16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;; 16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;; 16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;; 16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;; 16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;; 16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;; 16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;; 16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;; 16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;; 16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;; 16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;; 16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;; 16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;; 16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;; 16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;; 16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;; 16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; 16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;; 16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;; 16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;golden number 17;;; 16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;golden number 18;;; 16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;golden number 19;;; 1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;; 1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;; 1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;; 1703;TAGALOG LETTER KA;Lo;0;L;;;;;N;;;;; 1704;TAGALOG LETTER GA;Lo;0;L;;;;;N;;;;; 1705;TAGALOG LETTER NGA;Lo;0;L;;;;;N;;;;; 1706;TAGALOG LETTER TA;Lo;0;L;;;;;N;;;;; 1707;TAGALOG LETTER DA;Lo;0;L;;;;;N;;;;; 1708;TAGALOG LETTER NA;Lo;0;L;;;;;N;;;;; 1709;TAGALOG LETTER PA;Lo;0;L;;;;;N;;;;; 170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;; 170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;; 170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;; 170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;; 170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;; 1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;; 1711;TAGALOG LETTER HA;Lo;0;L;;;;;N;;;;; 1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; 1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;; 1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;; 1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;; 1723;HANUNOO LETTER KA;Lo;0;L;;;;;N;;;;; 1724;HANUNOO LETTER GA;Lo;0;L;;;;;N;;;;; 1725;HANUNOO LETTER NGA;Lo;0;L;;;;;N;;;;; 1726;HANUNOO LETTER TA;Lo;0;L;;;;;N;;;;; 1727;HANUNOO LETTER DA;Lo;0;L;;;;;N;;;;; 1728;HANUNOO LETTER NA;Lo;0;L;;;;;N;;;;; 1729;HANUNOO LETTER PA;Lo;0;L;;;;;N;;;;; 172A;HANUNOO LETTER BA;Lo;0;L;;;;;N;;;;; 172B;HANUNOO LETTER MA;Lo;0;L;;;;;N;;;;; 172C;HANUNOO LETTER YA;Lo;0;L;;;;;N;;;;; 172D;HANUNOO LETTER RA;Lo;0;L;;;;;N;;;;; 172E;HANUNOO LETTER LA;Lo;0;L;;;;;N;;;;; 172F;HANUNOO LETTER WA;Lo;0;L;;;;;N;;;;; 1730;HANUNOO LETTER SA;Lo;0;L;;;;;N;;;;; 1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;; 1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;; 1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;; 1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;; 1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;; 1741;BUHID LETTER I;Lo;0;L;;;;;N;;;;; 1742;BUHID LETTER U;Lo;0;L;;;;;N;;;;; 1743;BUHID LETTER KA;Lo;0;L;;;;;N;;;;; 1744;BUHID LETTER GA;Lo;0;L;;;;;N;;;;; 1745;BUHID LETTER NGA;Lo;0;L;;;;;N;;;;; 1746;BUHID LETTER TA;Lo;0;L;;;;;N;;;;; 1747;BUHID LETTER DA;Lo;0;L;;;;;N;;;;; 1748;BUHID LETTER NA;Lo;0;L;;;;;N;;;;; 1749;BUHID LETTER PA;Lo;0;L;;;;;N;;;;; 174A;BUHID LETTER BA;Lo;0;L;;;;;N;;;;; 174B;BUHID LETTER MA;Lo;0;L;;;;;N;;;;; 174C;BUHID LETTER YA;Lo;0;L;;;;;N;;;;; 174D;BUHID LETTER RA;Lo;0;L;;;;;N;;;;; 174E;BUHID LETTER LA;Lo;0;L;;;;;N;;;;; 174F;BUHID LETTER WA;Lo;0;L;;;;;N;;;;; 1750;BUHID LETTER SA;Lo;0;L;;;;;N;;;;; 1751;BUHID LETTER HA;Lo;0;L;;;;;N;;;;; 1752;BUHID VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 1753;BUHID VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 1760;TAGBANWA LETTER A;Lo;0;L;;;;;N;;;;; 1761;TAGBANWA LETTER I;Lo;0;L;;;;;N;;;;; 1762;TAGBANWA LETTER U;Lo;0;L;;;;;N;;;;; 1763;TAGBANWA LETTER KA;Lo;0;L;;;;;N;;;;; 1764;TAGBANWA LETTER GA;Lo;0;L;;;;;N;;;;; 1765;TAGBANWA LETTER NGA;Lo;0;L;;;;;N;;;;; 1766;TAGBANWA LETTER TA;Lo;0;L;;;;;N;;;;; 1767;TAGBANWA LETTER DA;Lo;0;L;;;;;N;;;;; 1768;TAGBANWA LETTER NA;Lo;0;L;;;;;N;;;;; 1769;TAGBANWA LETTER PA;Lo;0;L;;;;;N;;;;; 176A;TAGBANWA LETTER BA;Lo;0;L;;;;;N;;;;; 176B;TAGBANWA LETTER MA;Lo;0;L;;;;;N;;;;; 176C;TAGBANWA LETTER YA;Lo;0;L;;;;;N;;;;; 176E;TAGBANWA LETTER LA;Lo;0;L;;;;;N;;;;; 176F;TAGBANWA LETTER WA;Lo;0;L;;;;;N;;;;; 1770;TAGBANWA LETTER SA;Lo;0;L;;;;;N;;;;; 1772;TAGBANWA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 1773;TAGBANWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;; 1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;; 1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;; 1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;; 1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;; 1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;; 1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;; 1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;; 1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;; 1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;; 178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;; 178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;; 178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;; 178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;; 178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;; 178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;; 1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;; 1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;; 1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;; 1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;; 1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;; 1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;; 1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;; 1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;; 1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;; 1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;; 179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;; 179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;; 179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;; 179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;; 179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;; 179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;; 17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;; 17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;; 17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;; 17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;;;; 17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;;;; 17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;; 17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;; 17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;; 17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;; 17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;; 17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;; 17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;; 17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;; 17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;; 17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;; 17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;; 17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;; 17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;; 17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;; 17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;; 17B4;KHMER VOWEL INHERENT AQ;Mc;0;L;;;;;N;;;;; 17B5;KHMER VOWEL INHERENT AA;Mc;0;L;;;;;N;;;;; 17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; 17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; 17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;; 17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; 17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; 17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; 17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;; 17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;; 17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;; 17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;; 17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;; 17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;; 17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; 17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; 17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; 17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;; 17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;; 17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;; 17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;; 17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;; 17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;; 17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;; 17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;; 17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;; 17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;; 17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;; 17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;; 17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;; 17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;;;; 17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;; 17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;; 17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;; 17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;; 17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;;;; 17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;; 17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;; 17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;; 17DC;KHMER SIGN AVAKRAHASANYA;Lo;0;L;;;;;N;;;;; 17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;; 1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;; 1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;; 1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;; 1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;; 1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;; 1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;; 1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;; 1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;; 1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;; 180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;; 180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;; 180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;; 180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;; 180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;; 1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; 1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; 1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; 1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; 1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; 1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;; 1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;; 1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;; 1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;; 1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;; 1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;; 1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;; 1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;; 1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;; 1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;; 182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;; 182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;; 182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;; 182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;; 182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;; 182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;; 1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;; 1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;; 1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;; 1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;; 1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;; 1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;; 1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;; 1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;; 1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;; 1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;; 183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;; 183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;; 183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;; 183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;; 183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;; 183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;; 1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;; 1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;; 1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;; 1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;; 1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;; 1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;; 1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;; 1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;; 1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;; 1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;; 184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;; 184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;; 184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;; 184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;; 184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;; 184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;; 1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;; 1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;; 1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;; 1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;; 1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;; 1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;; 1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;; 1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;; 1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;; 1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;; 185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;; 185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;; 185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;; 185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;; 185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;; 185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;; 1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;; 1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;; 1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;; 1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;; 1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;; 1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;; 1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;; 1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;; 1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;; 1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;; 186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;; 186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;; 186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;; 186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;; 186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;; 186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;; 1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;; 1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;; 1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;; 1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;; 1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;; 1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;; 1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;; 1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;; 1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;; 1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;; 1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;; 1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;; 1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;; 1885;MONGOLIAN LETTER ALI GALI BALUDA;Lo;0;L;;;;;N;;;;; 1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Lo;0;L;;;;;N;;;;; 1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;; 1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;; 1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;; 188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;; 188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;; 188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;; 188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;; 188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;; 188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;; 1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;; 1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;; 1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;; 1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;; 1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;; 1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;; 1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;; 1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;; 1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;; 1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;; 189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;; 189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;; 189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;; 189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;; 189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;; 189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;; 18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;; 18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;; 18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;; 18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;; 18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;; 18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;; 18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;; 18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;; 18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;; 18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;; 1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01; 1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00 1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03; 1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02 1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05; 1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04 1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07; 1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06 1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09; 1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08 1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B; 1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A 1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D; 1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C 1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F; 1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E 1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11; 1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10 1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13; 1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12 1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15; 1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14 1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17; 1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16 1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19; 1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18 1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B; 1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A 1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D; 1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C 1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F; 1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E 1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21; 1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20 1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23; 1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22 1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25; 1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24 1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27; 1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26 1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29; 1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28 1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B; 1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A 1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D; 1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C 1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F; 1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E 1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31; 1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30 1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33; 1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32 1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35; 1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34 1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37; 1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36 1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39; 1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38 1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B; 1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A 1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D; 1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C 1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F; 1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E 1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41; 1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40 1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43; 1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42 1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45; 1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44 1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47; 1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46 1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49; 1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48 1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B; 1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A 1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D; 1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C 1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F; 1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E 1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51; 1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50 1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53; 1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52 1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55; 1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54 1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57; 1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56 1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59; 1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58 1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B; 1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A 1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D; 1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C 1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F; 1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E 1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61; 1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60 1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63; 1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62 1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65; 1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64 1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67; 1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66 1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69; 1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68 1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B; 1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A 1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D; 1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C 1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F; 1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E 1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71; 1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70 1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73; 1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72 1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75; 1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74 1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77; 1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76 1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79; 1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78 1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B; 1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A 1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D; 1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C 1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F; 1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E 1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81; 1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80 1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83; 1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82 1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85; 1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84 1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87; 1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86 1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89; 1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88 1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B; 1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A 1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D; 1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C 1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F; 1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E 1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91; 1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90 1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93; 1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92 1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95; 1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94 1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;; 1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;; 1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;; 1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;; 1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L; 0061 02BE;;;;N;;;;; 1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60 1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1; 1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0 1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3; 1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2 1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5; 1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4 1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7; 1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6 1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9; 1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8 1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB; 1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA 1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD; 1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC 1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF; 1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE 1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1; 1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0 1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3; 1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2 1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5; 1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4 1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7; 1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6 1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9; 1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8 1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB; 1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA 1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD; 1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC 1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF; 1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE 1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1; 1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0 1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3; 1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2 1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5; 1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4 1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7; 1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6 1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9; 1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8 1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB; 1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA 1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD; 1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC 1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF; 1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE 1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1; 1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0 1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3; 1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2 1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5; 1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4 1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7; 1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6 1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9; 1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8 1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB; 1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA 1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD; 1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC 1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF; 1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE 1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1; 1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0 1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3; 1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2 1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5; 1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4 1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7; 1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6 1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9; 1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8 1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB; 1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA 1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED; 1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC 1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF; 1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE 1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1; 1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0 1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3; 1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2 1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5; 1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4 1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7; 1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6 1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9; 1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8 1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08 1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09 1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A 1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B 1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C 1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D 1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E 1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F 1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00; 1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01; 1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02; 1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03; 1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04; 1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05; 1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06; 1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07; 1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18 1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19 1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A 1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B 1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C 1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D 1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10; 1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11; 1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12; 1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13; 1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14; 1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15; 1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28 1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29 1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A 1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B 1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C 1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D 1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E 1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F 1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20; 1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21; 1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22; 1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23; 1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24; 1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25; 1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26; 1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27; 1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38 1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39 1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A 1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B 1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C 1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D 1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E 1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F 1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30; 1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31; 1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32; 1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33; 1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34; 1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35; 1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36; 1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37; 1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48 1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49 1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A 1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B 1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C 1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D 1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40; 1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41; 1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42; 1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43; 1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44; 1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45; 1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;; 1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59 1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;; 1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B 1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;; 1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D 1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;; 1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F 1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51; 1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53; 1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55; 1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57; 1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68 1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69 1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A 1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B 1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C 1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D 1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E 1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F 1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60; 1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61; 1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62; 1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63; 1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64; 1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65; 1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66; 1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67; 1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA 1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB 1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8 1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9 1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA 1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB 1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA 1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB 1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8 1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9 1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA 1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB 1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA 1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB 1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88 1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89 1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A 1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B 1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C 1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D 1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E 1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F 1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80; 1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81; 1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82; 1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83; 1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84; 1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85; 1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86; 1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87; 1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98 1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99 1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A 1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B 1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C 1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D 1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E 1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F 1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90; 1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91; 1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92; 1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93; 1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94; 1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95; 1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96; 1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97; 1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8 1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9 1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA 1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB 1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC 1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD 1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE 1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF 1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0; 1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1; 1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2; 1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3; 1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4; 1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5; 1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6; 1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7; 1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8 1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9 1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;; 1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC 1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;; 1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;; 1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;; 1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0; 1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1; 1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70; 1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71; 1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3; 1FBD;GREEK KORONIS;Sk;0;ON; 0020 0313;;;;N;;;;; 1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399 1FBF;GREEK PSILI;Sk;0;ON; 0020 0313;;;;N;;;;; 1FC0;GREEK PERISPOMENI;Sk;0;ON; 0020 0342;;;;N;;;;; 1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;; 1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;; 1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC 1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;; 1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;; 1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;; 1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72; 1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73; 1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74; 1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75; 1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3; 1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;; 1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;; 1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;; 1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8 1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9 1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;; 1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;; 1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;; 1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;; 1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0; 1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1; 1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76; 1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77; 1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;; 1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;; 1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;; 1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8 1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9 1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;; 1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;; 1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;; 1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC 1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;; 1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;; 1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0; 1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1; 1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A; 1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B; 1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5; 1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;; 1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;; 1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;; 1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;; 1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC 1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;; 1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;; 1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;; 1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78; 1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79; 1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C; 1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D; 1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3; 1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;; 1FFE;GREEK DASIA;Sk;0;ON; 0020 0314;;;;N;;;;; 2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;; 2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;; 2002;EN SPACE;Zs;0;WS; 0020;;;;N;;;;; 2003;EM SPACE;Zs;0;WS; 0020;;;;N;;;;; 2004;THREE-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; 2005;FOUR-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; 2006;SIX-PER-EM SPACE;Zs;0;WS; 0020;;;;N;;;;; 2007;FIGURE SPACE;Zs;0;WS; 0020;;;;N;;;;; 2008;PUNCTUATION SPACE;Zs;0;WS; 0020;;;;N;;;;; 2009;THIN SPACE;Zs;0;WS; 0020;;;;N;;;;; 200A;HAIR SPACE;Zs;0;WS; 0020;;;;N;;;;; 200B;ZERO WIDTH SPACE;Zs;0;BN;;;;;N;;;;; 200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;; 200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;; 200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;; 200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;; 2010;HYPHEN;Pd;0;ON;;;;;N;;;;; 2011;NON-BREAKING HYPHEN;Pd;0;ON; 2010;;;;N;;;;; 2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;; 2013;EN DASH;Pd;0;ON;;;;;N;;;;; 2014;EM DASH;Pd;0;ON;;;;;N;;;;; 2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;; 2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;; 2017;DOUBLE LOW LINE;Po;0;ON; 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;; 2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;; 2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;; 201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;; 201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;; 201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;; 201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;; 201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;; 201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;; 2020;DAGGER;Po;0;ON;;;;;N;;;;; 2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;; 2022;BULLET;Po;0;ON;;;;;N;;;;; 2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;; 2024;ONE DOT LEADER;Po;0;ON; 002E;;;;N;;;;; 2025;TWO DOT LEADER;Po;0;ON; 002E 002E;;;;N;;;;; 2026;HORIZONTAL ELLIPSIS;Po;0;ON; 002E 002E 002E;;;;N;;;;; 2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;; 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; 202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;; 202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;; 202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;; 202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;; 202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;; 202F;NARROW NO-BREAK SPACE;Zs;0;WS; 0020;;;;N;;;;; 2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;; 2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;; 2032;PRIME;Po;0;ET;;;;;N;;;;; 2033;DOUBLE PRIME;Po;0;ET; 2032 2032;;;;N;;;;; 2034;TRIPLE PRIME;Po;0;ET; 2032 2032 2032;;;;N;;;;; 2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;; 2036;REVERSED DOUBLE PRIME;Po;0;ON; 2035 2035;;;;N;;;;; 2037;REVERSED TRIPLE PRIME;Po;0;ON; 2035 2035 2035;;;;N;;;;; 2038;CARET;Po;0;ON;;;;;N;;;;; 2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;; 203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;; 203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;; 203C;DOUBLE EXCLAMATION MARK;Po;0;ON; 0021 0021;;;;N;;;;; 203D;INTERROBANG;Po;0;ON;;;;;N;;;;; 203E;OVERLINE;Po;0;ON; 0020 0305;;;;N;SPACING OVERSCORE;;;; 203F;UNDERTIE;Pc;0;ON;;;;;N;;Enotikon;;; 2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;; 2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;; 2042;ASTERISM;Po;0;ON;;;;;N;;;;; 2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;; 2044;FRACTION SLASH;Sm;0;ON;;;;;N;;;;; 2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;; 2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;; 2047;DOUBLE QUESTION MARK;Po;0;ON; 003F 003F;;;;N;;;;; 2048;QUESTION EXCLAMATION MARK;Po;0;ON; 003F 0021;;;;N;;;;; 2049;EXCLAMATION QUESTION MARK;Po;0;ON; 0021 003F;;;;N;;;;; 204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;; 204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;; 204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;; 204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;; 204E;LOW ASTERISK;Po;0;ON;;;;;N;;;;; 204F;REVERSED SEMICOLON;Po;0;ON;;;;;N;;;;; 2050;CLOSE UP;Po;0;ON;;;;;N;;;;; 2051;TWO ASTERISKS ALIGNED VERTICALLY;Po;0;ON;;;;;N;;;;; 2052;COMMERCIAL MINUS SIGN;Sm;0;ON;;;;;N;;;;; 2057;QUADRUPLE PRIME;Po;0;ON; 2032 2032 2032 2032;;;;N;;;;; 205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS; 0020;;;;N;;;;; 2060;WORD JOINER;Cf;0;BN;;;;;N;;;;; 2061;FUNCTION APPLICATION;Cf;0;BN;;;;;N;;;;; 2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;; 2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;; 206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; 206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;; 206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; 206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;; 206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; 206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;; 2070;SUPERSCRIPT ZERO;No;0;EN; 0030;0;0;0;N;SUPERSCRIPT DIGIT ZERO;;;; 2071;SUPERSCRIPT LATIN SMALL LETTER I;Ll;0;L; 0069;;;;N;;;;; 2074;SUPERSCRIPT FOUR;No;0;EN; 0034;4;4;4;N;SUPERSCRIPT DIGIT FOUR;;;; 2075;SUPERSCRIPT FIVE;No;0;EN; 0035;5;5;5;N;SUPERSCRIPT DIGIT FIVE;;;; 2076;SUPERSCRIPT SIX;No;0;EN; 0036;6;6;6;N;SUPERSCRIPT DIGIT SIX;;;; 2077;SUPERSCRIPT SEVEN;No;0;EN; 0037;7;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;; 2078;SUPERSCRIPT EIGHT;No;0;EN; 0038;8;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;; 2079;SUPERSCRIPT NINE;No;0;EN; 0039;9;9;9;N;SUPERSCRIPT DIGIT NINE;;;; 207A;SUPERSCRIPT PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; 207B;SUPERSCRIPT MINUS;Sm;0;ET; 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;; 207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; 207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;; 207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;; 207F;SUPERSCRIPT LATIN SMALL LETTER N;Ll;0;L; 006E;;;;N;;;;; 2080;SUBSCRIPT ZERO;No;0;EN; 0030;0;0;0;N;SUBSCRIPT DIGIT ZERO;;;; 2081;SUBSCRIPT ONE;No;0;EN; 0031;1;1;1;N;SUBSCRIPT DIGIT ONE;;;; 2082;SUBSCRIPT TWO;No;0;EN; 0032;2;2;2;N;SUBSCRIPT DIGIT TWO;;;; 2083;SUBSCRIPT THREE;No;0;EN; 0033;3;3;3;N;SUBSCRIPT DIGIT THREE;;;; 2084;SUBSCRIPT FOUR;No;0;EN; 0034;4;4;4;N;SUBSCRIPT DIGIT FOUR;;;; 2085;SUBSCRIPT FIVE;No;0;EN; 0035;5;5;5;N;SUBSCRIPT DIGIT FIVE;;;; 2086;SUBSCRIPT SIX;No;0;EN; 0036;6;6;6;N;SUBSCRIPT DIGIT SIX;;;; 2087;SUBSCRIPT SEVEN;No;0;EN; 0037;7;7;7;N;SUBSCRIPT DIGIT SEVEN;;;; 2088;SUBSCRIPT EIGHT;No;0;EN; 0038;8;8;8;N;SUBSCRIPT DIGIT EIGHT;;;; 2089;SUBSCRIPT NINE;No;0;EN; 0039;9;9;9;N;SUBSCRIPT DIGIT NINE;;;; 208A;SUBSCRIPT PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; 208B;SUBSCRIPT MINUS;Sm;0;ET; 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;; 208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; 208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;; 208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;; 20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;; 20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;; 20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;; 20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;; 20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;; 20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;; 20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;; 20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;; 20A8;RUPEE SIGN;Sc;0;ET; 0052 0073;;;;N;;;;; 20A9;WON SIGN;Sc;0;ET;;;;;N;;;;; 20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;; 20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;; 20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;; 20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;; 20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;; 20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;; 20B0;GERMAN PENNY SIGN;Sc;0;ET;;;;;N;;;;; 20B1;PESO SIGN;Sc;0;ET;;;;;N;;;;; 20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;; 20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;; 20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;; 20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;; 20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;; 20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;; 20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;; 20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;; 20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;; 20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;; 20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;; 20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;; 20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;; 20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;; 20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;; 20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;; 20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;; 20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;; 20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;; 20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;; 20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;; 20E5;COMBINING REVERSE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;; 20E6;COMBINING DOUBLE VERTICAL STROKE OVERLAY;Mn;1;NSM;;;;;N;;;;; 20E7;COMBINING ANNUITY SYMBOL;Mn;230;NSM;;;;;N;;;;; 20E8;COMBINING TRIPLE UNDERDOT;Mn;220;NSM;;;;;N;;;;; 20E9;COMBINING WIDE BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;; 20EA;COMBINING LEFTWARDS ARROW OVERLAY;Mn;1;NSM;;;;;N;;;;; 2100;ACCOUNT OF;So;0;ON; 0061 002F 0063;;;;N;;;;; 2101;ADDRESSED TO THE SUBJECT;So;0;ON; 0061 002F 0073;;;;N;;;;; 2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L; 0043;;;;N;DOUBLE-STRUCK C;;;; 2103;DEGREE CELSIUS;So;0;ON; 00B0 0043;;;;N;DEGREES CENTIGRADE;;;; 2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;; 2105;CARE OF;So;0;ON; 0063 002F 006F;;;;N;;;;; 2106;CADA UNA;So;0;ON; 0063 002F 0075;;;;N;;;;; 2107;EULER CONSTANT;Lu;0;L; 0190;;;;N;EULERS;;;; 2108;SCRUPLE;So;0;ON;;;;;N;;;;; 2109;DEGREE FAHRENHEIT;So;0;ON; 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;; 210A;SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; 210B;SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;SCRIPT H;;;; 210C;BLACK-LETTER CAPITAL H;Lu;0;L; 0048;;;;N;BLACK-LETTER H;;;; 210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L; 0048;;;;N;DOUBLE-STRUCK H;;;; 210E;PLANCK CONSTANT;Ll;0;L; 0068;;;;N;;;;; 210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L; 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;; 2110;SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;SCRIPT I;;;; 2111;BLACK-LETTER CAPITAL I;Lu;0;L; 0049;;;;N;BLACK-LETTER I;;;; 2112;SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;SCRIPT L;;;; 2113;SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; 2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;; 2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L; 004E;;;;N;DOUBLE-STRUCK N;;;; 2116;NUMERO SIGN;So;0;ON; 004E 006F;;;;N;NUMERO;;;; 2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;; 2118;SCRIPT CAPITAL P;So;0;ON;;;;;N;SCRIPT P;;;; 2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L; 0050;;;;N;DOUBLE-STRUCK P;;;; 211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L; 0051;;;;N;DOUBLE-STRUCK Q;;;; 211B;SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;SCRIPT R;;;; 211C;BLACK-LETTER CAPITAL R;Lu;0;L; 0052;;;;N;BLACK-LETTER R;;;; 211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L; 0052;;;;N;DOUBLE-STRUCK R;;;; 211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;; 211F;RESPONSE;So;0;ON;;;;;N;;;;; 2120;SERVICE MARK;So;0;ON; 0053 004D;;;;N;;;;; 2121;TELEPHONE SIGN;So;0;ON; 0054 0045 004C;;;;N;T E L SYMBOL;;;; 2122;TRADE MARK SIGN;So;0;ON; 0054 004D;;;;N;TRADEMARK;;;; 2123;VERSICLE;So;0;ON;;;;;N;;;;; 2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L; 005A;;;;N;DOUBLE-STRUCK Z;;;; 2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;; 2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9; 2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;; 2128;BLACK-LETTER CAPITAL Z;Lu;0;L; 005A;;;;N;BLACK-LETTER Z;;;; 2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;; 212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B; 212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5; 212C;SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;SCRIPT B;;;; 212D;BLACK-LETTER CAPITAL C;Lu;0;L; 0043;;;;N;BLACK-LETTER C;;;; 212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;; 212F;SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; 2130;SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;SCRIPT E;;;; 2131;SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;SCRIPT F;;;; 2132;TURNED CAPITAL F;So;0;ON;;;;;N;TURNED F;;;; 2133;SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;SCRIPT M;;;; 2134;SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; 2135;ALEF SYMBOL;Lo;0;L; 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;; 2136;BET SYMBOL;Lo;0;L; 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;; 2137;GIMEL SYMBOL;Lo;0;L; 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;; 2138;DALET SYMBOL;Lo;0;L; 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;; 2139;INFORMATION SOURCE;Ll;0;L; 0069;;;;N;;;;; 213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;; 213D;DOUBLE-STRUCK SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; 213E;DOUBLE-STRUCK CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; 213F;DOUBLE-STRUCK CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; 2140;DOUBLE-STRUCK N-ARY SUMMATION;Sm;0;ON; 2211;;;;Y;;;;; 2141;TURNED SANS-SERIF CAPITAL G;Sm;0;ON;;;;;N;;;;; 2142;TURNED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; 2143;REVERSED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;; 2144;TURNED SANS-SERIF CAPITAL Y;Sm;0;ON;;;;;N;;;;; 2145;DOUBLE-STRUCK ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 2146;DOUBLE-STRUCK ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; 2147;DOUBLE-STRUCK ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; 2148;DOUBLE-STRUCK ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; 2149;DOUBLE-STRUCK ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; 214A;PROPERTY LINE;So;0;ON;;;;;N;;;;; 214B;TURNED AMPERSAND;Sm;0;ON;;;;;N;;;;; 2153;VULGAR FRACTION ONE THIRD;No;0;ON; 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;; 2154;VULGAR FRACTION TWO THIRDS;No;0;ON; 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;; 2155;VULGAR FRACTION ONE FIFTH;No;0;ON; 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;; 2156;VULGAR FRACTION TWO FIFTHS;No;0;ON; 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;; 2157;VULGAR FRACTION THREE FIFTHS;No;0;ON; 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;; 2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON; 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;; 2159;VULGAR FRACTION ONE SIXTH;No;0;ON; 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;; 215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON; 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;; 215B;VULGAR FRACTION ONE EIGHTH;No;0;ON; 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;; 215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON; 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;; 215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON; 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;; 215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON; 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;; 215F;FRACTION NUMERATOR ONE;No;0;ON; 0031 2044;;;1;N;;;;; 2160;ROMAN NUMERAL ONE;Nl;0;L; 0049;;;1;N;;;;2170; 2161;ROMAN NUMERAL TWO;Nl;0;L; 0049 0049;;;2;N;;;;2171; 2162;ROMAN NUMERAL THREE;Nl;0;L; 0049 0049 0049;;;3;N;;;;2172; 2163;ROMAN NUMERAL FOUR;Nl;0;L; 0049 0056;;;4;N;;;;2173; 2164;ROMAN NUMERAL FIVE;Nl;0;L; 0056;;;5;N;;;;2174; 2165;ROMAN NUMERAL SIX;Nl;0;L; 0056 0049;;;6;N;;;;2175; 2166;ROMAN NUMERAL SEVEN;Nl;0;L; 0056 0049 0049;;;7;N;;;;2176; 2167;ROMAN NUMERAL EIGHT;Nl;0;L; 0056 0049 0049 0049;;;8;N;;;;2177; 2168;ROMAN NUMERAL NINE;Nl;0;L; 0049 0058;;;9;N;;;;2178; 2169;ROMAN NUMERAL TEN;Nl;0;L; 0058;;;10;N;;;;2179; 216A;ROMAN NUMERAL ELEVEN;Nl;0;L; 0058 0049;;;11;N;;;;217A; 216B;ROMAN NUMERAL TWELVE;Nl;0;L; 0058 0049 0049;;;12;N;;;;217B; 216C;ROMAN NUMERAL FIFTY;Nl;0;L; 004C;;;50;N;;;;217C; 216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0043;;;100;N;;;;217D; 216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0044;;;500;N;;;;217E; 216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 004D;;;1000;N;;;;217F; 2170;SMALL ROMAN NUMERAL ONE;Nl;0;L; 0069;;;1;N;;;2160;;2160 2171;SMALL ROMAN NUMERAL TWO;Nl;0;L; 0069 0069;;;2;N;;;2161;;2161 2172;SMALL ROMAN NUMERAL THREE;Nl;0;L; 0069 0069 0069;;;3;N;;;2162;;2162 2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L; 0069 0076;;;4;N;;;2163;;2163 2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L; 0076;;;5;N;;;2164;;2164 2175;SMALL ROMAN NUMERAL SIX;Nl;0;L; 0076 0069;;;6;N;;;2165;;2165 2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L; 0076 0069 0069;;;7;N;;;2166;;2166 2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L; 0076 0069 0069 0069;;;8;N;;;2167;;2167 2178;SMALL ROMAN NUMERAL NINE;Nl;0;L; 0069 0078;;;9;N;;;2168;;2168 2179;SMALL ROMAN NUMERAL TEN;Nl;0;L; 0078;;;10;N;;;2169;;2169 217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L; 0078 0069;;;11;N;;;216A;;216A 217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L; 0078 0069 0069;;;12;N;;;216B;;216B 217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L; 006C;;;50;N;;;216C;;216C 217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L; 0063;;;100;N;;;216D;;216D 217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L; 0064;;;500;N;;;216E;;216E 217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L; 006D;;;1000;N;;;216F;;216F 2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;; 2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;; 2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;; 2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Nl;0;L;;;;;N;;;;; 2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;; 2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;; 2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;; 2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;; 2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; 2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;; 2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;; 2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;; 2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;; 2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;; 219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;; 219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;; 219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;; 219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;; 219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;; 219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;; 21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;; 21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;; 21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;; 21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;; 21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;; 21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;; 21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;; 21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;; 21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;; 21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;; 21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;; 21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;; 21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;; 21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;; 21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;; 21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;; 21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;; 21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;; 21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;; 21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;; 21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;; 21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;; 21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; 21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;; 21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;; 21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;; 21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; 21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;; 21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;; 21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;; 21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;; 21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;; 21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;; 21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;; 21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;; 21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;; 21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;; 21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;; 21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;; 21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;; 21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;; 21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;; 21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;; 21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;; 21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;; 21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;; 21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;; 21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;; 21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;; 21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;; 21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;; 21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;; 21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; 21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;; 21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;; 21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;; 21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;; 21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;; 21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;; 21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;; 21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;; 21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;; 21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;; 21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;; 21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;; 21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;; 21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;; 21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;; 21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;; 21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;; 21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;; 21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;; 21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;; 21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;; 21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;; 21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; 21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;; 21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;; 21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;; 21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;; 21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;; 21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;; 21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;; 21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;; 21F4;RIGHT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; 21F5;DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW;Sm;0;ON;;;;;N;;;;; 21F6;THREE RIGHTWARDS ARROWS;Sm;0;ON;;;;;N;;;;; 21F7;LEFTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 21F8;RIGHTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 21F9;LEFT RIGHT ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 21FA;LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 21FB;RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 21FC;LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 21FD;LEFTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; 21FE;RIGHTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; 21FF;LEFT RIGHT OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;; 2200;FOR ALL;Sm;0;ON;;;;;N;;;;; 2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;; 2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;; 2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;; 2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;; 2205;EMPTY SET;Sm;0;ON;;;;;N;;;;; 2206;INCREMENT;Sm;0;ON;;;;;N;;;;; 2207;NABLA;Sm;0;ON;;;;;N;;;;; 2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;; 2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;; 220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;; 220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; 220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;; 220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;; 220E;END OF PROOF;Sm;0;ON;;;;;N;;;;; 220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;; 2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;; 2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;; 2212;MINUS SIGN;Sm;0;ET;;;;;N;;;;; 2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;; 2214;DOT PLUS;Sm;0;ON;;;;;N;;;;; 2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; 2216;SET MINUS;Sm;0;ON;;;;;Y;;;;; 2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; 2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;; 2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;; 221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;; 221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;; 221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;; 221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;; 221E;INFINITY;Sm;0;ON;;;;;N;;;;; 221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;; 2220;ANGLE;Sm;0;ON;;;;;Y;;;;; 2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;; 2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;; 2223;DIVIDES;Sm;0;ON;;;;;N;;;;; 2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;; 2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;; 2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;; 2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;; 2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;; 2229;INTERSECTION;Sm;0;ON;;;;;N;;;;; 222A;UNION;Sm;0;ON;;;;;N;;;;; 222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;; 222C;DOUBLE INTEGRAL;Sm;0;ON; 222B 222B;;;;Y;;;;; 222D;TRIPLE INTEGRAL;Sm;0;ON; 222B 222B 222B;;;;Y;;;;; 222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; 222F;SURFACE INTEGRAL;Sm;0;ON; 222E 222E;;;;Y;;;;; 2230;VOLUME INTEGRAL;Sm;0;ON; 222E 222E 222E;;;;Y;;;;; 2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;; 2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; 2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;; 2234;THEREFORE;Sm;0;ON;;;;;N;;;;; 2235;BECAUSE;Sm;0;ON;;;;;N;;;;; 2236;RATIO;Sm;0;ON;;;;;N;;;;; 2237;PROPORTION;Sm;0;ON;;;;;N;;;;; 2238;DOT MINUS;Sm;0;ON;;;;;N;;;;; 2239;EXCESS;Sm;0;ON;;;;;Y;;;;; 223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;; 223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;; 223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; 223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;lazy S;;; 223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;; 223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;; 2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;; 2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;; 2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;; 2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;; 2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;; 2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;; 224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;; 224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;; 224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; 224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; 224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;; 2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;; 2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;; 2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;; 2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;; 2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;; 2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;; 2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;; 2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;; 2259;ESTIMATES;Sm;0;ON;;;;;N;;;;; 225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;; 225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;; 225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;; 225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;; 225E;MEASURED BY;Sm;0;ON;;;;;N;;;;; 225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;; 2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;; 2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;; 2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;; 2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;; 2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;; 2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;; 2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;; 2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;; 2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;; 226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;; 226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;; 226C;BETWEEN;Sm;0;ON;;;;;N;;;;; 226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;; 226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;; 226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;; 2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;; 2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;; 2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;; 2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;; 2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;; 2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;; 2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;; 2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;; 2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;; 2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;; 227A;PRECEDES;Sm;0;ON;;;;;Y;;;;; 227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;; 227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; 227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; 2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;; 2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;; 2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;; 2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;; 2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;; 2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;; 2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;; 2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;; 228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;; 228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;; 228C;MULTISET;Sm;0;ON;;;;;Y;;;;; 228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;; 228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;; 228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;; 2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; 2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;; 2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;; 2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; 2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;; 2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;; 2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;; 2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; 229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;; 229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;; 229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;; 229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;; 229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;; 229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;; 22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;; 22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; 22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;; 22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;; 22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;; 22A5;UP TACK;Sm;0;ON;;;;;N;;;;; 22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;; 22A7;MODELS;Sm;0;ON;;;;;Y;;;;; 22A8;TRUE;Sm;0;ON;;;;;Y;;;;; 22A9;FORCES;Sm;0;ON;;;;;Y;;;;; 22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; 22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; 22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;; 22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;; 22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;; 22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;; 22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;; 22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;; 22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;; 22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;; 22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;; 22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;; 22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;; 22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;; 22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;; 22BB;XOR;Sm;0;ON;;;;;N;;;;; 22BC;NAND;Sm;0;ON;;;;;N;;;;; 22BD;NOR;Sm;0;ON;;;;;N;;;;; 22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;; 22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; 22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;; 22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;; 22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;; 22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;; 22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;; 22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;; 22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;; 22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;; 22C8;BOWTIE;Sm;0;ON;;;;;N;;;;; 22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; 22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; 22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; 22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;; 22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;; 22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;; 22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;; 22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;; 22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;; 22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;; 22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;; 22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;; 22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;; 22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;; 22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;; 22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;; 22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;; 22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;; 22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;; 22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;; 22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;; 22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;; 22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;; 22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;; 22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;; 22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;; 22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;; 22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;; 22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;; 22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; 22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;; 22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;; 22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;; 22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;; 22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;; 22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; 22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;; 22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; 22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;; 22F2;ELEMENT OF WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; 22F3;ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; 22F4;SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; 22F5;ELEMENT OF WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; 22F6;ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; 22F7;SMALL ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; 22F8;ELEMENT OF WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; 22F9;ELEMENT OF WITH TWO HORIZONTAL STROKES;Sm;0;ON;;;;;Y;;;;; 22FA;CONTAINS WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; 22FB;CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; 22FC;SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; 22FD;CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; 22FE;SMALL CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; 22FF;Z NOTATION BAG MEMBERSHIP;Sm;0;ON;;;;;Y;;;;; 2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;; 2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;; 2302;HOUSE;So;0;ON;;;;;N;;;;; 2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;; 2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;; 2305;PROJECTIVE;So;0;ON;;;;;N;;;;; 2306;PERSPECTIVE;So;0;ON;;;;;N;;;;; 2307;WAVY LINE;So;0;ON;;;;;N;;;;; 2308;LEFT CEILING;Sm;0;ON;;;;;Y;;;;; 2309;RIGHT CEILING;Sm;0;ON;;;;;Y;;;;; 230A;LEFT FLOOR;Sm;0;ON;;;;;Y;;;;; 230B;RIGHT FLOOR;Sm;0;ON;;;;;Y;;;;; 230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;; 230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;; 230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;; 230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;; 2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;; 2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;; 2312;ARC;So;0;ON;;;;;N;;;;; 2313;SEGMENT;So;0;ON;;;;;N;;;;; 2314;SECTOR;So;0;ON;;;;;N;;;;; 2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;; 2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;; 2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;; 2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;; 2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;; 231A;WATCH;So;0;ON;;;;;N;;;;; 231B;HOURGLASS;So;0;ON;;;;;N;;;;; 231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;; 231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;; 231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;; 231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;; 2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; 2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;; 2322;FROWN;So;0;ON;;;;;N;;;;; 2323;SMILE;So;0;ON;;;;;N;;;;; 2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;; 2325;OPTION KEY;So;0;ON;;;;;N;;;;; 2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;; 2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;; 2328;KEYBOARD;So;0;ON;;;;;N;;;;; 2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;; 232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;; 232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;; 232C;BENZENE RING;So;0;ON;;;;;N;;;;; 232D;CYLINDRICITY;So;0;ON;;;;;N;;;;; 232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;; 232F;SYMMETRY;So;0;ON;;;;;N;;;;; 2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;; 2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;; 2332;CONICAL TAPER;So;0;ON;;;;;N;;;;; 2333;SLOPE;So;0;ON;;;;;N;;;;; 2334;COUNTERBORE;So;0;ON;;;;;N;;;;; 2335;COUNTERSINK;So;0;ON;;;;;N;;;;; 2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;; 2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;; 2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;; 2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;; 233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;; 233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;; 233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;; 233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;; 233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;; 233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;; 2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;; 2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;; 2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;; 2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;; 2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;; 2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;; 2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;; 2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;; 2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;; 2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;; 234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;*;;; 234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;; 234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;; 234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;; 234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;*;;; 234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;; 2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;; 2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;*;;; 2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;; 2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;; 2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;; 2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;*;;; 2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;; 2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;; 2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;; 2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;; 235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;; 235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;; 235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;; 235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;; 235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;; 235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;; 2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;; 2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;*;;; 2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;; 2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;; 2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;; 2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;; 2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;; 2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;; 2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;; 2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;; 236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;; 236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;; 236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;; 236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;; 236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;; 236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;; 2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;; 2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;; 2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;; 2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;; 2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;; 2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;; 2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;; 2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;; 2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;; 2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;; 237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;; 237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;; 237C;RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW;Sm;0;ON;;;;;N;;;;; 237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;; 237E;BELL SYMBOL;So;0;ON;;;;;N;;;;; 237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;; 2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;; 2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; 2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;; 2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;; 2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;; 2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;; 2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;; 2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;; 2388;HELM SYMBOL;So;0;ON;;;;;N;;;;; 2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;pause;;; 238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;break;;; 238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;escape;;; 238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;; 238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;; 238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;; 238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;; 2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;; 2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; 2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;; 2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;; 2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;; 2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;; 2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;; 2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;; 2398;NEXT PAGE;So;0;ON;;;;;N;;;;; 2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;; 239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;; 239B;LEFT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; 239C;LEFT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; 239D;LEFT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; 239E;RIGHT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;; 239F;RIGHT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;; 23A0;RIGHT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;; 23A1;LEFT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; 23A2;LEFT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; 23A3;LEFT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; 23A4;RIGHT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;; 23A5;RIGHT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; 23A6;RIGHT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;; 23A7;LEFT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; 23A8;LEFT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; 23A9;LEFT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; 23AA;CURLY BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;; 23AB;RIGHT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;; 23AC;RIGHT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;; 23AD;RIGHT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;; 23AE;INTEGRAL EXTENSION;Sm;0;ON;;;;;N;;;;; 23AF;HORIZONTAL LINE EXTENSION;Sm;0;ON;;;;;N;;;;; 23B0;UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; 23B1;UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;; 23B2;SUMMATION TOP;Sm;0;ON;;;;;N;;;;; 23B3;SUMMATION BOTTOM;Sm;0;ON;;;;;N;;;;; 23B4;TOP SQUARE BRACKET;Ps;0;ON;;;;;N;;;;; 23B5;BOTTOM SQUARE BRACKET;Pe;0;ON;;;;;N;;;;; 23B6;BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET;Po;0;ON;;;;;N;;;;; 23B7;RADICAL SYMBOL BOTTOM;So;0;ON;;;;;N;;;;; 23B8;LEFT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; 23B9;RIGHT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;; 23BA;HORIZONTAL SCAN LINE-1;So;0;ON;;;;;N;;;;; 23BB;HORIZONTAL SCAN LINE-3;So;0;ON;;;;;N;;;;; 23BC;HORIZONTAL SCAN LINE-7;So;0;ON;;;;;N;;;;; 23BD;HORIZONTAL SCAN LINE-9;So;0;ON;;;;;N;;;;; 23BE;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;; 23BF;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;; 23C0;DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE;So;0;ON;;;;;N;;;;; 23C1;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; 23C2;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;; 23C3;DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; 23C4;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; 23C5;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;; 23C6;DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE;So;0;ON;;;;;N;;;;; 23C7;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; 23C8;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;; 23C9;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;;;;; 23CA;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;;;;; 23CB;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;; 23CC;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;; 23CD;SQUARE FOOT;So;0;ON;;;;;N;;;;; 23CE;RETURN SYMBOL;So;0;ON;;;;;N;;;;; 2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;; 2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;; 2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;; 2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;; 2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;; 2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;; 2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;; 2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;; 2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;; 2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;; 240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;; 240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;; 240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;; 240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;; 240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;; 240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;; 2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;; 2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;; 2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;; 2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;; 2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;; 2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;; 2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;; 2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;; 2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;; 2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;; 241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;; 241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;; 241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;; 241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;; 241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;; 241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;; 2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;; 2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;; 2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;; 2423;OPEN BOX;So;0;ON;;;;;N;;;;; 2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;; 2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;; 2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;; 2440;OCR HOOK;So;0;ON;;;;;N;;;;; 2441;OCR CHAIR;So;0;ON;;;;;N;;;;; 2442;OCR FORK;So;0;ON;;;;;N;;;;; 2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;; 2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;; 2445;OCR BOW TIE;So;0;ON;;;;;N;;;;; 2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;; 2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;; 2448;OCR DASH;So;0;ON;;;;;N;;;;; 2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;; 244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;; 2460;CIRCLED DIGIT ONE;No;0;EN; 0031;;1;1;N;;;;; 2461;CIRCLED DIGIT TWO;No;0;EN; 0032;;2;2;N;;;;; 2462;CIRCLED DIGIT THREE;No;0;EN; 0033;;3;3;N;;;;; 2463;CIRCLED DIGIT FOUR;No;0;EN; 0034;;4;4;N;;;;; 2464;CIRCLED DIGIT FIVE;No;0;EN; 0035;;5;5;N;;;;; 2465;CIRCLED DIGIT SIX;No;0;EN; 0036;;6;6;N;;;;; 2466;CIRCLED DIGIT SEVEN;No;0;EN; 0037;;7;7;N;;;;; 2467;CIRCLED DIGIT EIGHT;No;0;EN; 0038;;8;8;N;;;;; 2468;CIRCLED DIGIT NINE;No;0;EN; 0039;;9;9;N;;;;; 2469;CIRCLED NUMBER TEN;No;0;EN; 0031 0030;;;10;N;;;;; 246A;CIRCLED NUMBER ELEVEN;No;0;EN; 0031 0031;;;11;N;;;;; 246B;CIRCLED NUMBER TWELVE;No;0;EN; 0031 0032;;;12;N;;;;; 246C;CIRCLED NUMBER THIRTEEN;No;0;EN; 0031 0033;;;13;N;;;;; 246D;CIRCLED NUMBER FOURTEEN;No;0;EN; 0031 0034;;;14;N;;;;; 246E;CIRCLED NUMBER FIFTEEN;No;0;EN; 0031 0035;;;15;N;;;;; 246F;CIRCLED NUMBER SIXTEEN;No;0;EN; 0031 0036;;;16;N;;;;; 2470;CIRCLED NUMBER SEVENTEEN;No;0;EN; 0031 0037;;;17;N;;;;; 2471;CIRCLED NUMBER EIGHTEEN;No;0;EN; 0031 0038;;;18;N;;;;; 2472;CIRCLED NUMBER NINETEEN;No;0;EN; 0031 0039;;;19;N;;;;; 2473;CIRCLED NUMBER TWENTY;No;0;EN; 0032 0030;;;20;N;;;;; 2474;PARENTHESIZED DIGIT ONE;No;0;EN; 0028 0031 0029;;1;1;N;;;;; 2475;PARENTHESIZED DIGIT TWO;No;0;EN; 0028 0032 0029;;2;2;N;;;;; 2476;PARENTHESIZED DIGIT THREE;No;0;EN; 0028 0033 0029;;3;3;N;;;;; 2477;PARENTHESIZED DIGIT FOUR;No;0;EN; 0028 0034 0029;;4;4;N;;;;; 2478;PARENTHESIZED DIGIT FIVE;No;0;EN; 0028 0035 0029;;5;5;N;;;;; 2479;PARENTHESIZED DIGIT SIX;No;0;EN; 0028 0036 0029;;6;6;N;;;;; 247A;PARENTHESIZED DIGIT SEVEN;No;0;EN; 0028 0037 0029;;7;7;N;;;;; 247B;PARENTHESIZED DIGIT EIGHT;No;0;EN; 0028 0038 0029;;8;8;N;;;;; 247C;PARENTHESIZED DIGIT NINE;No;0;EN; 0028 0039 0029;;9;9;N;;;;; 247D;PARENTHESIZED NUMBER TEN;No;0;EN; 0028 0031 0030 0029;;;10;N;;;;; 247E;PARENTHESIZED NUMBER ELEVEN;No;0;EN; 0028 0031 0031 0029;;;11;N;;;;; 247F;PARENTHESIZED NUMBER TWELVE;No;0;EN; 0028 0031 0032 0029;;;12;N;;;;; 2480;PARENTHESIZED NUMBER THIRTEEN;No;0;EN; 0028 0031 0033 0029;;;13;N;;;;; 2481;PARENTHESIZED NUMBER FOURTEEN;No;0;EN; 0028 0031 0034 0029;;;14;N;;;;; 2482;PARENTHESIZED NUMBER FIFTEEN;No;0;EN; 0028 0031 0035 0029;;;15;N;;;;; 2483;PARENTHESIZED NUMBER SIXTEEN;No;0;EN; 0028 0031 0036 0029;;;16;N;;;;; 2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;EN; 0028 0031 0037 0029;;;17;N;;;;; 2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;EN; 0028 0031 0038 0029;;;18;N;;;;; 2486;PARENTHESIZED NUMBER NINETEEN;No;0;EN; 0028 0031 0039 0029;;;19;N;;;;; 2487;PARENTHESIZED NUMBER TWENTY;No;0;EN; 0028 0032 0030 0029;;;20;N;;;;; 2488;DIGIT ONE FULL STOP;No;0;EN; 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;; 2489;DIGIT TWO FULL STOP;No;0;EN; 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;; 248A;DIGIT THREE FULL STOP;No;0;EN; 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;; 248B;DIGIT FOUR FULL STOP;No;0;EN; 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;; 248C;DIGIT FIVE FULL STOP;No;0;EN; 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;; 248D;DIGIT SIX FULL STOP;No;0;EN; 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;; 248E;DIGIT SEVEN FULL STOP;No;0;EN; 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;; 248F;DIGIT EIGHT FULL STOP;No;0;EN; 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;; 2490;DIGIT NINE FULL STOP;No;0;EN; 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;; 2491;NUMBER TEN FULL STOP;No;0;EN; 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;; 2492;NUMBER ELEVEN FULL STOP;No;0;EN; 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;; 2493;NUMBER TWELVE FULL STOP;No;0;EN; 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;; 2494;NUMBER THIRTEEN FULL STOP;No;0;EN; 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;; 2495;NUMBER FOURTEEN FULL STOP;No;0;EN; 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;; 2496;NUMBER FIFTEEN FULL STOP;No;0;EN; 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;; 2497;NUMBER SIXTEEN FULL STOP;No;0;EN; 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;; 2498;NUMBER SEVENTEEN FULL STOP;No;0;EN; 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;; 2499;NUMBER EIGHTEEN FULL STOP;No;0;EN; 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;; 249A;NUMBER NINETEEN FULL STOP;No;0;EN; 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;; 249B;NUMBER TWENTY FULL STOP;No;0;EN; 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;; 249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L; 0028 0061 0029;;;;N;;;;; 249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L; 0028 0062 0029;;;;N;;;;; 249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L; 0028 0063 0029;;;;N;;;;; 249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L; 0028 0064 0029;;;;N;;;;; 24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L; 0028 0065 0029;;;;N;;;;; 24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L; 0028 0066 0029;;;;N;;;;; 24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L; 0028 0067 0029;;;;N;;;;; 24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L; 0028 0068 0029;;;;N;;;;; 24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L; 0028 0069 0029;;;;N;;;;; 24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L; 0028 006A 0029;;;;N;;;;; 24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L; 0028 006B 0029;;;;N;;;;; 24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L; 0028 006C 0029;;;;N;;;;; 24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L; 0028 006D 0029;;;;N;;;;; 24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L; 0028 006E 0029;;;;N;;;;; 24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L; 0028 006F 0029;;;;N;;;;; 24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L; 0028 0070 0029;;;;N;;;;; 24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L; 0028 0071 0029;;;;N;;;;; 24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L; 0028 0072 0029;;;;N;;;;; 24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L; 0028 0073 0029;;;;N;;;;; 24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L; 0028 0074 0029;;;;N;;;;; 24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L; 0028 0075 0029;;;;N;;;;; 24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L; 0028 0076 0029;;;;N;;;;; 24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L; 0028 0077 0029;;;;N;;;;; 24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L; 0028 0078 0029;;;;N;;;;; 24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L; 0028 0079 0029;;;;N;;;;; 24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L; 0028 007A 0029;;;;N;;;;; 24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L; 0041;;;;N;;;;24D0; 24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L; 0042;;;;N;;;;24D1; 24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;24D2; 24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L; 0044;;;;N;;;;24D3; 24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L; 0045;;;;N;;;;24D4; 24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L; 0046;;;;N;;;;24D5; 24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L; 0047;;;;N;;;;24D6; 24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L; 0048;;;;N;;;;24D7; 24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L; 0049;;;;N;;;;24D8; 24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L; 004A;;;;N;;;;24D9; 24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L; 004B;;;;N;;;;24DA; 24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L; 004C;;;;N;;;;24DB; 24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L; 004D;;;;N;;;;24DC; 24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L; 004E;;;;N;;;;24DD; 24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L; 004F;;;;N;;;;24DE; 24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L; 0050;;;;N;;;;24DF; 24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L; 0051;;;;N;;;;24E0; 24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;24E1; 24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L; 0053;;;;N;;;;24E2; 24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L; 0054;;;;N;;;;24E3; 24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L; 0055;;;;N;;;;24E4; 24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L; 0056;;;;N;;;;24E5; 24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L; 0057;;;;N;;;;24E6; 24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L; 0058;;;;N;;;;24E7; 24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L; 0059;;;;N;;;;24E8; 24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L; 005A;;;;N;;;;24E9; 24D0;CIRCLED LATIN SMALL LETTER A;So;0;L; 0061;;;;N;;;24B6;;24B6 24D1;CIRCLED LATIN SMALL LETTER B;So;0;L; 0062;;;;N;;;24B7;;24B7 24D2;CIRCLED LATIN SMALL LETTER C;So;0;L; 0063;;;;N;;;24B8;;24B8 24D3;CIRCLED LATIN SMALL LETTER D;So;0;L; 0064;;;;N;;;24B9;;24B9 24D4;CIRCLED LATIN SMALL LETTER E;So;0;L; 0065;;;;N;;;24BA;;24BA 24D5;CIRCLED LATIN SMALL LETTER F;So;0;L; 0066;;;;N;;;24BB;;24BB 24D6;CIRCLED LATIN SMALL LETTER G;So;0;L; 0067;;;;N;;;24BC;;24BC 24D7;CIRCLED LATIN SMALL LETTER H;So;0;L; 0068;;;;N;;;24BD;;24BD 24D8;CIRCLED LATIN SMALL LETTER I;So;0;L; 0069;;;;N;;;24BE;;24BE 24D9;CIRCLED LATIN SMALL LETTER J;So;0;L; 006A;;;;N;;;24BF;;24BF 24DA;CIRCLED LATIN SMALL LETTER K;So;0;L; 006B;;;;N;;;24C0;;24C0 24DB;CIRCLED LATIN SMALL LETTER L;So;0;L; 006C;;;;N;;;24C1;;24C1 24DC;CIRCLED LATIN SMALL LETTER M;So;0;L; 006D;;;;N;;;24C2;;24C2 24DD;CIRCLED LATIN SMALL LETTER N;So;0;L; 006E;;;;N;;;24C3;;24C3 24DE;CIRCLED LATIN SMALL LETTER O;So;0;L; 006F;;;;N;;;24C4;;24C4 24DF;CIRCLED LATIN SMALL LETTER P;So;0;L; 0070;;;;N;;;24C5;;24C5 24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L; 0071;;;;N;;;24C6;;24C6 24E1;CIRCLED LATIN SMALL LETTER R;So;0;L; 0072;;;;N;;;24C7;;24C7 24E2;CIRCLED LATIN SMALL LETTER S;So;0;L; 0073;;;;N;;;24C8;;24C8 24E3;CIRCLED LATIN SMALL LETTER T;So;0;L; 0074;;;;N;;;24C9;;24C9 24E4;CIRCLED LATIN SMALL LETTER U;So;0;L; 0075;;;;N;;;24CA;;24CA 24E5;CIRCLED LATIN SMALL LETTER V;So;0;L; 0076;;;;N;;;24CB;;24CB 24E6;CIRCLED LATIN SMALL LETTER W;So;0;L; 0077;;;;N;;;24CC;;24CC 24E7;CIRCLED LATIN SMALL LETTER X;So;0;L; 0078;;;;N;;;24CD;;24CD 24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L; 0079;;;;N;;;24CE;;24CE 24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L; 007A;;;;N;;;24CF;;24CF 24EA;CIRCLED DIGIT ZERO;No;0;EN; 0030;;0;0;N;;;;; 24EB;NEGATIVE CIRCLED NUMBER ELEVEN;No;0;ON;;;;11;N;;;;; 24EC;NEGATIVE CIRCLED NUMBER TWELVE;No;0;ON;;;;12;N;;;;; 24ED;NEGATIVE CIRCLED NUMBER THIRTEEN;No;0;ON;;;;13;N;;;;; 24EE;NEGATIVE CIRCLED NUMBER FOURTEEN;No;0;ON;;;;14;N;;;;; 24EF;NEGATIVE CIRCLED NUMBER FIFTEEN;No;0;ON;;;;15;N;;;;; 24F0;NEGATIVE CIRCLED NUMBER SIXTEEN;No;0;ON;;;;16;N;;;;; 24F1;NEGATIVE CIRCLED NUMBER SEVENTEEN;No;0;ON;;;;17;N;;;;; 24F2;NEGATIVE CIRCLED NUMBER EIGHTEEN;No;0;ON;;;;18;N;;;;; 24F3;NEGATIVE CIRCLED NUMBER NINETEEN;No;0;ON;;;;19;N;;;;; 24F4;NEGATIVE CIRCLED NUMBER TWENTY;No;0;ON;;;;20;N;;;;; 24F5;DOUBLE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;;;;; 24F6;DOUBLE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;;;;; 24F7;DOUBLE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;;;;; 24F8;DOUBLE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;;;;; 24F9;DOUBLE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;;;;; 24FA;DOUBLE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;;;;; 24FB;DOUBLE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;;;;; 24FC;DOUBLE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;;;;; 24FD;DOUBLE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;;;;; 24FE;DOUBLE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;;;;; 2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;; 2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;; 2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;; 2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;; 2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;; 2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;; 2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;; 2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;; 2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;; 2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;; 250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;; 250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;; 250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;; 250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;; 250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;; 250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;; 2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;; 2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;; 2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;; 2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;; 2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;; 2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;; 2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;; 2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;; 2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;; 2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;; 251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;; 251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;; 251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;; 251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;; 251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;; 251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;; 2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;; 2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;; 2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;; 2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;; 2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;; 2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;; 2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;; 2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;; 2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;; 2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;; 252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;; 252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;; 252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;; 252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;; 252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;; 252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;; 2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;; 2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;; 2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;; 2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;; 2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;; 2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;; 2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;; 2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;; 2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;; 2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;; 253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;; 253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;; 253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;; 253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;; 253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;; 253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;; 2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;; 2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;; 2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;; 2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;; 2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;; 2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;; 2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;; 2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;; 2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;; 2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;; 254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;; 254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;; 254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;; 254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;; 254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;; 254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;; 2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;; 2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;; 2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;; 2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;; 2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;; 2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;; 2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;; 2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;; 2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;; 2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;; 255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;; 255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;; 255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;; 255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;; 255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;; 255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;; 2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;; 2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;; 2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;; 2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;; 2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;; 2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;; 2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;; 2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;; 2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;; 2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;; 256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;; 256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;; 256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;; 256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;; 256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;; 256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;; 2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;; 2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;; 2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;; 2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;; 2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;; 2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;; 2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;; 2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;; 2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;; 2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;; 257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;; 257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;; 257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;; 257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;; 257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;; 257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;; 2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;; 2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; 2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; 2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; 2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;; 2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; 2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;; 2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; 2588;FULL BLOCK;So;0;ON;;;;;N;;;;; 2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; 258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;; 258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; 258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;; 258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; 258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; 258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; 2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;; 2591;LIGHT SHADE;So;0;ON;;;;;N;;;;; 2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;; 2593;DARK SHADE;So;0;ON;;;;;N;;;;; 2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; 2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; 2596;QUADRANT LOWER LEFT;So;0;ON;;;;;N;;;;; 2597;QUADRANT LOWER RIGHT;So;0;ON;;;;;N;;;;; 2598;QUADRANT UPPER LEFT;So;0;ON;;;;;N;;;;; 2599;QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; 259A;QUADRANT UPPER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; 259B;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; 259C;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; 259D;QUADRANT UPPER RIGHT;So;0;ON;;;;;N;;;;; 259E;QUADRANT UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;; 259F;QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; 25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;; 25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;; 25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;; 25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; 25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;; 25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; 25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; 25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;; 25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;; 25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; 25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; 25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;; 25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;; 25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;; 25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; 25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;; 25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;; 25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;; 25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;; 25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;; 25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;; 25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;; 25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;; 25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;; 25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;; 25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;; 25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;; 25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;; 25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;; 25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;; 25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;; 25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;; 25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;; 25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;; 25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;; 25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;; 25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;; 25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;; 25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;; 25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;; 25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;; 25C9;FISHEYE;So;0;ON;;;;;N;;;;; 25CA;LOZENGE;So;0;ON;;;;;N;;;;; 25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;; 25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;; 25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;; 25CE;BULLSEYE;So;0;ON;;;;;N;;;;; 25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;; 25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; 25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; 25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;; 25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;; 25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;; 25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;; 25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; 25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; 25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;; 25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; 25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; 25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;; 25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; 25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; 25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; 25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;; 25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;; 25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;; 25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; 25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; 25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;; 25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;; 25E6;WHITE BULLET;So;0;ON;;;;;N;;;;; 25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; 25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; 25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; 25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;; 25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;; 25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;; 25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;; 25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;; 25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;; 25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; 25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; 25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; 25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; 25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;; 25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;; 25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; 25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;; 25F8;UPPER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; 25F9;UPPER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; 25FA;LOWER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;; 25FB;WHITE MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; 25FC;BLACK MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;; 25FD;WHITE MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; 25FE;BLACK MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;; 25FF;LOWER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;; 2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;; 2601;CLOUD;So;0;ON;;;;;N;;;;; 2602;UMBRELLA;So;0;ON;;;;;N;;;;; 2603;SNOWMAN;So;0;ON;;;;;N;;;;; 2604;COMET;So;0;ON;;;;;N;;;;; 2605;BLACK STAR;So;0;ON;;;;;N;;;;; 2606;WHITE STAR;So;0;ON;;;;;N;;;;; 2607;LIGHTNING;So;0;ON;;;;;N;;;;; 2608;THUNDERSTORM;So;0;ON;;;;;N;;;;; 2609;SUN;So;0;ON;;;;;N;;;;; 260A;ASCENDING NODE;So;0;ON;;;;;N;;;;; 260B;DESCENDING NODE;So;0;ON;;;;;N;;;;; 260C;CONJUNCTION;So;0;ON;;;;;N;;;;; 260D;OPPOSITION;So;0;ON;;;;;N;;;;; 260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;; 260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;; 2610;BALLOT BOX;So;0;ON;;;;;N;;;;; 2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;; 2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;; 2613;SALTIRE;So;0;ON;;;;;N;;;;; 2616;WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;; 2617;BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;; 2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; 261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; 261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; 261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;; 261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;; 261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; 261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;; 2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;; 2621;CAUTION SIGN;So;0;ON;;;;;N;;;;; 2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;; 2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;; 2624;CADUCEUS;So;0;ON;;;;;N;;;;; 2625;ANKH;So;0;ON;;;;;N;;;;; 2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;; 2627;CHI RHO;So;0;ON;;;;;N;;;;; 2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;; 2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;; 262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;; 262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;; 262C;ADI SHAKTI;So;0;ON;;;;;N;;;;; 262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;; 262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;; 262F;YIN YANG;So;0;ON;;;;;N;;;;; 2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;; 2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;; 2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;; 2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;; 2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;; 2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;; 2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;; 2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;; 2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;; 2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;; 263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;; 263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;; 263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;; 263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;; 263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;; 263F;MERCURY;So;0;ON;;;;;N;;;;; 2640;FEMALE SIGN;So;0;ON;;;;;N;;;;; 2641;EARTH;So;0;ON;;;;;N;;;;; 2642;MALE SIGN;So;0;ON;;;;;N;;;;; 2643;JUPITER;So;0;ON;;;;;N;;;;; 2644;SATURN;So;0;ON;;;;;N;;;;; 2645;URANUS;So;0;ON;;;;;N;;;;; 2646;NEPTUNE;So;0;ON;;;;;N;;;;; 2647;PLUTO;So;0;ON;;;;;N;;;;; 2648;ARIES;So;0;ON;;;;;N;;;;; 2649;TAURUS;So;0;ON;;;;;N;;;;; 264A;GEMINI;So;0;ON;;;;;N;;;;; 264B;CANCER;So;0;ON;;;;;N;;;;; 264C;LEO;So;0;ON;;;;;N;;;;; 264D;VIRGO;So;0;ON;;;;;N;;;;; 264E;LIBRA;So;0;ON;;;;;N;;;;; 264F;SCORPIUS;So;0;ON;;;;;N;;;;; 2650;SAGITTARIUS;So;0;ON;;;;;N;;;;; 2651;CAPRICORN;So;0;ON;;;;;N;;;;; 2652;AQUARIUS;So;0;ON;;;;;N;;;;; 2653;PISCES;So;0;ON;;;;;N;;;;; 2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;; 2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;; 2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;; 2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;; 2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;; 2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;; 265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;; 265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;; 265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;; 265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;; 265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;; 265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;; 2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;; 2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;; 2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;; 2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;; 2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;; 2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;; 2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;; 2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;; 2668;HOT SPRINGS;So;0;ON;;;;;N;;;;; 2669;QUARTER NOTE;So;0;ON;;;;;N;;;;; 266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;; 266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;; 266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;; 266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;; 266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;; 266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;; 2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;; 2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;; 2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; 2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;pete;;; 2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;hdpe;;; 2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;pvc;;; 2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;ldpe;;; 2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;pp;;; 2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;ps;;; 2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;other;;; 267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;; 267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;; 267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; 267D;PARTIALLY-RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;; 2680;DIE FACE-1;So;0;ON;;;;;N;;;;; 2681;DIE FACE-2;So;0;ON;;;;;N;;;;; 2682;DIE FACE-3;So;0;ON;;;;;N;;;;; 2683;DIE FACE-4;So;0;ON;;;;;N;;;;; 2684;DIE FACE-5;So;0;ON;;;;;N;;;;; 2685;DIE FACE-6;So;0;ON;;;;;N;;;;; 2686;WHITE CIRCLE WITH DOT RIGHT;So;0;ON;;;;;N;;;;; 2687;WHITE CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;; 2688;BLACK CIRCLE WITH WHITE DOT RIGHT;So;0;ON;;;;;N;;;;; 2689;BLACK CIRCLE WITH TWO WHITE DOTS;So;0;ON;;;;;N;;;;; 2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;; 2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;; 2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;; 2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;; 2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;; 2707;TAPE DRIVE;So;0;ON;;;;;N;;;;; 2708;AIRPLANE;So;0;ON;;;;;N;;;;; 2709;ENVELOPE;So;0;ON;;;;;N;;;;; 270C;VICTORY HAND;So;0;ON;;;;;N;;;;; 270D;WRITING HAND;So;0;ON;;;;;N;;;;; 270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;; 270F;PENCIL;So;0;ON;;;;;N;;;;; 2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;; 2711;WHITE NIB;So;0;ON;;;;;N;;;;; 2712;BLACK NIB;So;0;ON;;;;;N;;;;; 2713;CHECK MARK;So;0;ON;;;;;N;;;;; 2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;; 2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;; 2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;; 2717;BALLOT X;So;0;ON;;;;;N;;;;; 2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;; 2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;; 271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;; 271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;; 271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;; 271D;LATIN CROSS;So;0;ON;;;;;N;;;;; 271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;; 271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;; 2720;MALTESE CROSS;So;0;ON;;;;;N;;;;; 2721;STAR OF DAVID;So;0;ON;;;;;N;;;;; 2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; 2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; 2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; 2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; 2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;; 2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;; 2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;; 272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;; 272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;; 272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;; 272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; 272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;; 272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;; 2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;; 2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;; 2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;; 2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;; 2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;; 2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; 2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;; 2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; 2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;; 2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; 273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;; 273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; 273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;; 273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; 273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;; 273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;; 2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;; 2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;; 2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;; 2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;; 2744;SNOWFLAKE;So;0;ON;;;;;N;;;;; 2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;; 2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;; 2747;SPARKLE;So;0;ON;;;;;N;;;;; 2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;; 2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;; 274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; 274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;; 274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;; 274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; 2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; 2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; 2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;; 2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;; 2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;; 2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;; 275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;; 275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; 275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; 275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; 275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; 2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;; 2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; 2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;; 2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;; 2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;; 2766;FLORAL HEART;So;0;ON;;;;;N;;;;; 2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;; 2768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; 2769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; 276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;; 276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;; 276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; 276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; 276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps;0;ON;;;;;Y;;;;; 276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe;0;ON;;;;;Y;;;;; 2770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; 2771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; 2772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; 2773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; 2774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;; 2775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;; 2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;; 2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;; 2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;; 2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;; 277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;; 277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;; 277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;; 277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;; 277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;; 277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;; 2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;; 2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;; 2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;; 2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;; 2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;; 2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;; 2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;; 2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;; 2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;; 2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;; 278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;; 278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;; 278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;; 278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;; 278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;; 278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;; 2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;; 2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;; 2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;; 2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;; 2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;; 2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;; 2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;; 279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;; 279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;; 279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;; 279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;; 279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;; 279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;; 27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;; 27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;; 27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;; 27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;; 27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;; 27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;; 27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;; 27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;; 27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;; 27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;; 27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;; 27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;; 27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;; 27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; 27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; 27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; 27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;; 27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;; 27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;; 27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;; 27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;; 27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;; 27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;; 27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;; 27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;; 27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;; 27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;; 27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;; 27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;; 27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;; 27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;; 27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;; 27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;; 27D3;LOWER RIGHT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; 27D4;UPPER LEFT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;; 27D5;LEFT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; 27D6;RIGHT OUTER JOIN;Sm;0;ON;;;;;Y;;;;; 27D7;FULL OUTER JOIN;Sm;0;ON;;;;;N;;;;; 27D8;LARGE UP TACK;Sm;0;ON;;;;;N;;;;; 27D9;LARGE DOWN TACK;Sm;0;ON;;;;;N;;;;; 27DA;LEFT AND RIGHT DOUBLE TURNSTILE;Sm;0;ON;;;;;N;;;;; 27DB;LEFT AND RIGHT TACK;Sm;0;ON;;;;;N;;;;; 27DC;LEFT MULTIMAP;Sm;0;ON;;;;;Y;;;;; 27DD;LONG RIGHT TACK;Sm;0;ON;;;;;Y;;;;; 27DE;LONG LEFT TACK;Sm;0;ON;;;;;Y;;;;; 27DF;UP TACK WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; 27E0;LOZENGE DIVIDED BY HORIZONTAL RULE;Sm;0;ON;;;;;N;;;;; 27E1;WHITE CONCAVE-SIDED DIAMOND;Sm;0;ON;;;;;N;;;;; 27E2;WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; 27E3;WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; 27E4;WHITE SQUARE WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;; 27E5;WHITE SQUARE WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;; 27E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;;;;; 27E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;;;;; 27E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; 27E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; 27EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; 27EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; 27F0;UPWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; 27F1;DOWNWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;; 27F2;ANTICLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; 27F3;CLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; 27F4;RIGHT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;; 27F5;LONG LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 27F6;LONG RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 27F7;LONG LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;; 27F8;LONG LEFTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; 27F9;LONG RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; 27FA;LONG LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;; 27FB;LONG LEFTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; 27FC;LONG RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; 27FD;LONG LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; 27FE;LONG RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; 27FF;LONG RIGHTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;; 2800;BRAILLE PATTERN BLANK;So;0;ON;;;;;N;;;;; 2801;BRAILLE PATTERN DOTS-1;So;0;ON;;;;;N;;;;; 2802;BRAILLE PATTERN DOTS-2;So;0;ON;;;;;N;;;;; 2803;BRAILLE PATTERN DOTS-12;So;0;ON;;;;;N;;;;; 2804;BRAILLE PATTERN DOTS-3;So;0;ON;;;;;N;;;;; 2805;BRAILLE PATTERN DOTS-13;So;0;ON;;;;;N;;;;; 2806;BRAILLE PATTERN DOTS-23;So;0;ON;;;;;N;;;;; 2807;BRAILLE PATTERN DOTS-123;So;0;ON;;;;;N;;;;; 2808;BRAILLE PATTERN DOTS-4;So;0;ON;;;;;N;;;;; 2809;BRAILLE PATTERN DOTS-14;So;0;ON;;;;;N;;;;; 280A;BRAILLE PATTERN DOTS-24;So;0;ON;;;;;N;;;;; 280B;BRAILLE PATTERN DOTS-124;So;0;ON;;;;;N;;;;; 280C;BRAILLE PATTERN DOTS-34;So;0;ON;;;;;N;;;;; 280D;BRAILLE PATTERN DOTS-134;So;0;ON;;;;;N;;;;; 280E;BRAILLE PATTERN DOTS-234;So;0;ON;;;;;N;;;;; 280F;BRAILLE PATTERN DOTS-1234;So;0;ON;;;;;N;;;;; 2810;BRAILLE PATTERN DOTS-5;So;0;ON;;;;;N;;;;; 2811;BRAILLE PATTERN DOTS-15;So;0;ON;;;;;N;;;;; 2812;BRAILLE PATTERN DOTS-25;So;0;ON;;;;;N;;;;; 2813;BRAILLE PATTERN DOTS-125;So;0;ON;;;;;N;;;;; 2814;BRAILLE PATTERN DOTS-35;So;0;ON;;;;;N;;;;; 2815;BRAILLE PATTERN DOTS-135;So;0;ON;;;;;N;;;;; 2816;BRAILLE PATTERN DOTS-235;So;0;ON;;;;;N;;;;; 2817;BRAILLE PATTERN DOTS-1235;So;0;ON;;;;;N;;;;; 2818;BRAILLE PATTERN DOTS-45;So;0;ON;;;;;N;;;;; 2819;BRAILLE PATTERN DOTS-145;So;0;ON;;;;;N;;;;; 281A;BRAILLE PATTERN DOTS-245;So;0;ON;;;;;N;;;;; 281B;BRAILLE PATTERN DOTS-1245;So;0;ON;;;;;N;;;;; 281C;BRAILLE PATTERN DOTS-345;So;0;ON;;;;;N;;;;; 281D;BRAILLE PATTERN DOTS-1345;So;0;ON;;;;;N;;;;; 281E;BRAILLE PATTERN DOTS-2345;So;0;ON;;;;;N;;;;; 281F;BRAILLE PATTERN DOTS-12345;So;0;ON;;;;;N;;;;; 2820;BRAILLE PATTERN DOTS-6;So;0;ON;;;;;N;;;;; 2821;BRAILLE PATTERN DOTS-16;So;0;ON;;;;;N;;;;; 2822;BRAILLE PATTERN DOTS-26;So;0;ON;;;;;N;;;;; 2823;BRAILLE PATTERN DOTS-126;So;0;ON;;;;;N;;;;; 2824;BRAILLE PATTERN DOTS-36;So;0;ON;;;;;N;;;;; 2825;BRAILLE PATTERN DOTS-136;So;0;ON;;;;;N;;;;; 2826;BRAILLE PATTERN DOTS-236;So;0;ON;;;;;N;;;;; 2827;BRAILLE PATTERN DOTS-1236;So;0;ON;;;;;N;;;;; 2828;BRAILLE PATTERN DOTS-46;So;0;ON;;;;;N;;;;; 2829;BRAILLE PATTERN DOTS-146;So;0;ON;;;;;N;;;;; 282A;BRAILLE PATTERN DOTS-246;So;0;ON;;;;;N;;;;; 282B;BRAILLE PATTERN DOTS-1246;So;0;ON;;;;;N;;;;; 282C;BRAILLE PATTERN DOTS-346;So;0;ON;;;;;N;;;;; 282D;BRAILLE PATTERN DOTS-1346;So;0;ON;;;;;N;;;;; 282E;BRAILLE PATTERN DOTS-2346;So;0;ON;;;;;N;;;;; 282F;BRAILLE PATTERN DOTS-12346;So;0;ON;;;;;N;;;;; 2830;BRAILLE PATTERN DOTS-56;So;0;ON;;;;;N;;;;; 2831;BRAILLE PATTERN DOTS-156;So;0;ON;;;;;N;;;;; 2832;BRAILLE PATTERN DOTS-256;So;0;ON;;;;;N;;;;; 2833;BRAILLE PATTERN DOTS-1256;So;0;ON;;;;;N;;;;; 2834;BRAILLE PATTERN DOTS-356;So;0;ON;;;;;N;;;;; 2835;BRAILLE PATTERN DOTS-1356;So;0;ON;;;;;N;;;;; 2836;BRAILLE PATTERN DOTS-2356;So;0;ON;;;;;N;;;;; 2837;BRAILLE PATTERN DOTS-12356;So;0;ON;;;;;N;;;;; 2838;BRAILLE PATTERN DOTS-456;So;0;ON;;;;;N;;;;; 2839;BRAILLE PATTERN DOTS-1456;So;0;ON;;;;;N;;;;; 283A;BRAILLE PATTERN DOTS-2456;So;0;ON;;;;;N;;;;; 283B;BRAILLE PATTERN DOTS-12456;So;0;ON;;;;;N;;;;; 283C;BRAILLE PATTERN DOTS-3456;So;0;ON;;;;;N;;;;; 283D;BRAILLE PATTERN DOTS-13456;So;0;ON;;;;;N;;;;; 283E;BRAILLE PATTERN DOTS-23456;So;0;ON;;;;;N;;;;; 283F;BRAILLE PATTERN DOTS-123456;So;0;ON;;;;;N;;;;; 2840;BRAILLE PATTERN DOTS-7;So;0;ON;;;;;N;;;;; 2841;BRAILLE PATTERN DOTS-17;So;0;ON;;;;;N;;;;; 2842;BRAILLE PATTERN DOTS-27;So;0;ON;;;;;N;;;;; 2843;BRAILLE PATTERN DOTS-127;So;0;ON;;;;;N;;;;; 2844;BRAILLE PATTERN DOTS-37;So;0;ON;;;;;N;;;;; 2845;BRAILLE PATTERN DOTS-137;So;0;ON;;;;;N;;;;; 2846;BRAILLE PATTERN DOTS-237;So;0;ON;;;;;N;;;;; 2847;BRAILLE PATTERN DOTS-1237;So;0;ON;;;;;N;;;;; 2848;BRAILLE PATTERN DOTS-47;So;0;ON;;;;;N;;;;; 2849;BRAILLE PATTERN DOTS-147;So;0;ON;;;;;N;;;;; 284A;BRAILLE PATTERN DOTS-247;So;0;ON;;;;;N;;;;; 284B;BRAILLE PATTERN DOTS-1247;So;0;ON;;;;;N;;;;; 284C;BRAILLE PATTERN DOTS-347;So;0;ON;;;;;N;;;;; 284D;BRAILLE PATTERN DOTS-1347;So;0;ON;;;;;N;;;;; 284E;BRAILLE PATTERN DOTS-2347;So;0;ON;;;;;N;;;;; 284F;BRAILLE PATTERN DOTS-12347;So;0;ON;;;;;N;;;;; 2850;BRAILLE PATTERN DOTS-57;So;0;ON;;;;;N;;;;; 2851;BRAILLE PATTERN DOTS-157;So;0;ON;;;;;N;;;;; 2852;BRAILLE PATTERN DOTS-257;So;0;ON;;;;;N;;;;; 2853;BRAILLE PATTERN DOTS-1257;So;0;ON;;;;;N;;;;; 2854;BRAILLE PATTERN DOTS-357;So;0;ON;;;;;N;;;;; 2855;BRAILLE PATTERN DOTS-1357;So;0;ON;;;;;N;;;;; 2856;BRAILLE PATTERN DOTS-2357;So;0;ON;;;;;N;;;;; 2857;BRAILLE PATTERN DOTS-12357;So;0;ON;;;;;N;;;;; 2858;BRAILLE PATTERN DOTS-457;So;0;ON;;;;;N;;;;; 2859;BRAILLE PATTERN DOTS-1457;So;0;ON;;;;;N;;;;; 285A;BRAILLE PATTERN DOTS-2457;So;0;ON;;;;;N;;;;; 285B;BRAILLE PATTERN DOTS-12457;So;0;ON;;;;;N;;;;; 285C;BRAILLE PATTERN DOTS-3457;So;0;ON;;;;;N;;;;; 285D;BRAILLE PATTERN DOTS-13457;So;0;ON;;;;;N;;;;; 285E;BRAILLE PATTERN DOTS-23457;So;0;ON;;;;;N;;;;; 285F;BRAILLE PATTERN DOTS-123457;So;0;ON;;;;;N;;;;; 2860;BRAILLE PATTERN DOTS-67;So;0;ON;;;;;N;;;;; 2861;BRAILLE PATTERN DOTS-167;So;0;ON;;;;;N;;;;; 2862;BRAILLE PATTERN DOTS-267;So;0;ON;;;;;N;;;;; 2863;BRAILLE PATTERN DOTS-1267;So;0;ON;;;;;N;;;;; 2864;BRAILLE PATTERN DOTS-367;So;0;ON;;;;;N;;;;; 2865;BRAILLE PATTERN DOTS-1367;So;0;ON;;;;;N;;;;; 2866;BRAILLE PATTERN DOTS-2367;So;0;ON;;;;;N;;;;; 2867;BRAILLE PATTERN DOTS-12367;So;0;ON;;;;;N;;;;; 2868;BRAILLE PATTERN DOTS-467;So;0;ON;;;;;N;;;;; 2869;BRAILLE PATTERN DOTS-1467;So;0;ON;;;;;N;;;;; 286A;BRAILLE PATTERN DOTS-2467;So;0;ON;;;;;N;;;;; 286B;BRAILLE PATTERN DOTS-12467;So;0;ON;;;;;N;;;;; 286C;BRAILLE PATTERN DOTS-3467;So;0;ON;;;;;N;;;;; 286D;BRAILLE PATTERN DOTS-13467;So;0;ON;;;;;N;;;;; 286E;BRAILLE PATTERN DOTS-23467;So;0;ON;;;;;N;;;;; 286F;BRAILLE PATTERN DOTS-123467;So;0;ON;;;;;N;;;;; 2870;BRAILLE PATTERN DOTS-567;So;0;ON;;;;;N;;;;; 2871;BRAILLE PATTERN DOTS-1567;So;0;ON;;;;;N;;;;; 2872;BRAILLE PATTERN DOTS-2567;So;0;ON;;;;;N;;;;; 2873;BRAILLE PATTERN DOTS-12567;So;0;ON;;;;;N;;;;; 2874;BRAILLE PATTERN DOTS-3567;So;0;ON;;;;;N;;;;; 2875;BRAILLE PATTERN DOTS-13567;So;0;ON;;;;;N;;;;; 2876;BRAILLE PATTERN DOTS-23567;So;0;ON;;;;;N;;;;; 2877;BRAILLE PATTERN DOTS-123567;So;0;ON;;;;;N;;;;; 2878;BRAILLE PATTERN DOTS-4567;So;0;ON;;;;;N;;;;; 2879;BRAILLE PATTERN DOTS-14567;So;0;ON;;;;;N;;;;; 287A;BRAILLE PATTERN DOTS-24567;So;0;ON;;;;;N;;;;; 287B;BRAILLE PATTERN DOTS-124567;So;0;ON;;;;;N;;;;; 287C;BRAILLE PATTERN DOTS-34567;So;0;ON;;;;;N;;;;; 287D;BRAILLE PATTERN DOTS-134567;So;0;ON;;;;;N;;;;; 287E;BRAILLE PATTERN DOTS-234567;So;0;ON;;;;;N;;;;; 287F;BRAILLE PATTERN DOTS-1234567;So;0;ON;;;;;N;;;;; 2880;BRAILLE PATTERN DOTS-8;So;0;ON;;;;;N;;;;; 2881;BRAILLE PATTERN DOTS-18;So;0;ON;;;;;N;;;;; 2882;BRAILLE PATTERN DOTS-28;So;0;ON;;;;;N;;;;; 2883;BRAILLE PATTERN DOTS-128;So;0;ON;;;;;N;;;;; 2884;BRAILLE PATTERN DOTS-38;So;0;ON;;;;;N;;;;; 2885;BRAILLE PATTERN DOTS-138;So;0;ON;;;;;N;;;;; 2886;BRAILLE PATTERN DOTS-238;So;0;ON;;;;;N;;;;; 2887;BRAILLE PATTERN DOTS-1238;So;0;ON;;;;;N;;;;; 2888;BRAILLE PATTERN DOTS-48;So;0;ON;;;;;N;;;;; 2889;BRAILLE PATTERN DOTS-148;So;0;ON;;;;;N;;;;; 288A;BRAILLE PATTERN DOTS-248;So;0;ON;;;;;N;;;;; 288B;BRAILLE PATTERN DOTS-1248;So;0;ON;;;;;N;;;;; 288C;BRAILLE PATTERN DOTS-348;So;0;ON;;;;;N;;;;; 288D;BRAILLE PATTERN DOTS-1348;So;0;ON;;;;;N;;;;; 288E;BRAILLE PATTERN DOTS-2348;So;0;ON;;;;;N;;;;; 288F;BRAILLE PATTERN DOTS-12348;So;0;ON;;;;;N;;;;; 2890;BRAILLE PATTERN DOTS-58;So;0;ON;;;;;N;;;;; 2891;BRAILLE PATTERN DOTS-158;So;0;ON;;;;;N;;;;; 2892;BRAILLE PATTERN DOTS-258;So;0;ON;;;;;N;;;;; 2893;BRAILLE PATTERN DOTS-1258;So;0;ON;;;;;N;;;;; 2894;BRAILLE PATTERN DOTS-358;So;0;ON;;;;;N;;;;; 2895;BRAILLE PATTERN DOTS-1358;So;0;ON;;;;;N;;;;; 2896;BRAILLE PATTERN DOTS-2358;So;0;ON;;;;;N;;;;; 2897;BRAILLE PATTERN DOTS-12358;So;0;ON;;;;;N;;;;; 2898;BRAILLE PATTERN DOTS-458;So;0;ON;;;;;N;;;;; 2899;BRAILLE PATTERN DOTS-1458;So;0;ON;;;;;N;;;;; 289A;BRAILLE PATTERN DOTS-2458;So;0;ON;;;;;N;;;;; 289B;BRAILLE PATTERN DOTS-12458;So;0;ON;;;;;N;;;;; 289C;BRAILLE PATTERN DOTS-3458;So;0;ON;;;;;N;;;;; 289D;BRAILLE PATTERN DOTS-13458;So;0;ON;;;;;N;;;;; 289E;BRAILLE PATTERN DOTS-23458;So;0;ON;;;;;N;;;;; 289F;BRAILLE PATTERN DOTS-123458;So;0;ON;;;;;N;;;;; 28A0;BRAILLE PATTERN DOTS-68;So;0;ON;;;;;N;;;;; 28A1;BRAILLE PATTERN DOTS-168;So;0;ON;;;;;N;;;;; 28A2;BRAILLE PATTERN DOTS-268;So;0;ON;;;;;N;;;;; 28A3;BRAILLE PATTERN DOTS-1268;So;0;ON;;;;;N;;;;; 28A4;BRAILLE PATTERN DOTS-368;So;0;ON;;;;;N;;;;; 28A5;BRAILLE PATTERN DOTS-1368;So;0;ON;;;;;N;;;;; 28A6;BRAILLE PATTERN DOTS-2368;So;0;ON;;;;;N;;;;; 28A7;BRAILLE PATTERN DOTS-12368;So;0;ON;;;;;N;;;;; 28A8;BRAILLE PATTERN DOTS-468;So;0;ON;;;;;N;;;;; 28A9;BRAILLE PATTERN DOTS-1468;So;0;ON;;;;;N;;;;; 28AA;BRAILLE PATTERN DOTS-2468;So;0;ON;;;;;N;;;;; 28AB;BRAILLE PATTERN DOTS-12468;So;0;ON;;;;;N;;;;; 28AC;BRAILLE PATTERN DOTS-3468;So;0;ON;;;;;N;;;;; 28AD;BRAILLE PATTERN DOTS-13468;So;0;ON;;;;;N;;;;; 28AE;BRAILLE PATTERN DOTS-23468;So;0;ON;;;;;N;;;;; 28AF;BRAILLE PATTERN DOTS-123468;So;0;ON;;;;;N;;;;; 28B0;BRAILLE PATTERN DOTS-568;So;0;ON;;;;;N;;;;; 28B1;BRAILLE PATTERN DOTS-1568;So;0;ON;;;;;N;;;;; 28B2;BRAILLE PATTERN DOTS-2568;So;0;ON;;;;;N;;;;; 28B3;BRAILLE PATTERN DOTS-12568;So;0;ON;;;;;N;;;;; 28B4;BRAILLE PATTERN DOTS-3568;So;0;ON;;;;;N;;;;; 28B5;BRAILLE PATTERN DOTS-13568;So;0;ON;;;;;N;;;;; 28B6;BRAILLE PATTERN DOTS-23568;So;0;ON;;;;;N;;;;; 28B7;BRAILLE PATTERN DOTS-123568;So;0;ON;;;;;N;;;;; 28B8;BRAILLE PATTERN DOTS-4568;So;0;ON;;;;;N;;;;; 28B9;BRAILLE PATTERN DOTS-14568;So;0;ON;;;;;N;;;;; 28BA;BRAILLE PATTERN DOTS-24568;So;0;ON;;;;;N;;;;; 28BB;BRAILLE PATTERN DOTS-124568;So;0;ON;;;;;N;;;;; 28BC;BRAILLE PATTERN DOTS-34568;So;0;ON;;;;;N;;;;; 28BD;BRAILLE PATTERN DOTS-134568;So;0;ON;;;;;N;;;;; 28BE;BRAILLE PATTERN DOTS-234568;So;0;ON;;;;;N;;;;; 28BF;BRAILLE PATTERN DOTS-1234568;So;0;ON;;;;;N;;;;; 28C0;BRAILLE PATTERN DOTS-78;So;0;ON;;;;;N;;;;; 28C1;BRAILLE PATTERN DOTS-178;So;0;ON;;;;;N;;;;; 28C2;BRAILLE PATTERN DOTS-278;So;0;ON;;;;;N;;;;; 28C3;BRAILLE PATTERN DOTS-1278;So;0;ON;;;;;N;;;;; 28C4;BRAILLE PATTERN DOTS-378;So;0;ON;;;;;N;;;;; 28C5;BRAILLE PATTERN DOTS-1378;So;0;ON;;;;;N;;;;; 28C6;BRAILLE PATTERN DOTS-2378;So;0;ON;;;;;N;;;;; 28C7;BRAILLE PATTERN DOTS-12378;So;0;ON;;;;;N;;;;; 28C8;BRAILLE PATTERN DOTS-478;So;0;ON;;;;;N;;;;; 28C9;BRAILLE PATTERN DOTS-1478;So;0;ON;;;;;N;;;;; 28CA;BRAILLE PATTERN DOTS-2478;So;0;ON;;;;;N;;;;; 28CB;BRAILLE PATTERN DOTS-12478;So;0;ON;;;;;N;;;;; 28CC;BRAILLE PATTERN DOTS-3478;So;0;ON;;;;;N;;;;; 28CD;BRAILLE PATTERN DOTS-13478;So;0;ON;;;;;N;;;;; 28CE;BRAILLE PATTERN DOTS-23478;So;0;ON;;;;;N;;;;; 28CF;BRAILLE PATTERN DOTS-123478;So;0;ON;;;;;N;;;;; 28D0;BRAILLE PATTERN DOTS-578;So;0;ON;;;;;N;;;;; 28D1;BRAILLE PATTERN DOTS-1578;So;0;ON;;;;;N;;;;; 28D2;BRAILLE PATTERN DOTS-2578;So;0;ON;;;;;N;;;;; 28D3;BRAILLE PATTERN DOTS-12578;So;0;ON;;;;;N;;;;; 28D4;BRAILLE PATTERN DOTS-3578;So;0;ON;;;;;N;;;;; 28D5;BRAILLE PATTERN DOTS-13578;So;0;ON;;;;;N;;;;; 28D6;BRAILLE PATTERN DOTS-23578;So;0;ON;;;;;N;;;;; 28D7;BRAILLE PATTERN DOTS-123578;So;0;ON;;;;;N;;;;; 28D8;BRAILLE PATTERN DOTS-4578;So;0;ON;;;;;N;;;;; 28D9;BRAILLE PATTERN DOTS-14578;So;0;ON;;;;;N;;;;; 28DA;BRAILLE PATTERN DOTS-24578;So;0;ON;;;;;N;;;;; 28DB;BRAILLE PATTERN DOTS-124578;So;0;ON;;;;;N;;;;; 28DC;BRAILLE PATTERN DOTS-34578;So;0;ON;;;;;N;;;;; 28DD;BRAILLE PATTERN DOTS-134578;So;0;ON;;;;;N;;;;; 28DE;BRAILLE PATTERN DOTS-234578;So;0;ON;;;;;N;;;;; 28DF;BRAILLE PATTERN DOTS-1234578;So;0;ON;;;;;N;;;;; 28E0;BRAILLE PATTERN DOTS-678;So;0;ON;;;;;N;;;;; 28E1;BRAILLE PATTERN DOTS-1678;So;0;ON;;;;;N;;;;; 28E2;BRAILLE PATTERN DOTS-2678;So;0;ON;;;;;N;;;;; 28E3;BRAILLE PATTERN DOTS-12678;So;0;ON;;;;;N;;;;; 28E4;BRAILLE PATTERN DOTS-3678;So;0;ON;;;;;N;;;;; 28E5;BRAILLE PATTERN DOTS-13678;So;0;ON;;;;;N;;;;; 28E6;BRAILLE PATTERN DOTS-23678;So;0;ON;;;;;N;;;;; 28E7;BRAILLE PATTERN DOTS-123678;So;0;ON;;;;;N;;;;; 28E8;BRAILLE PATTERN DOTS-4678;So;0;ON;;;;;N;;;;; 28E9;BRAILLE PATTERN DOTS-14678;So;0;ON;;;;;N;;;;; 28EA;BRAILLE PATTERN DOTS-24678;So;0;ON;;;;;N;;;;; 28EB;BRAILLE PATTERN DOTS-124678;So;0;ON;;;;;N;;;;; 28EC;BRAILLE PATTERN DOTS-34678;So;0;ON;;;;;N;;;;; 28ED;BRAILLE PATTERN DOTS-134678;So;0;ON;;;;;N;;;;; 28EE;BRAILLE PATTERN DOTS-234678;So;0;ON;;;;;N;;;;; 28EF;BRAILLE PATTERN DOTS-1234678;So;0;ON;;;;;N;;;;; 28F0;BRAILLE PATTERN DOTS-5678;So;0;ON;;;;;N;;;;; 28F1;BRAILLE PATTERN DOTS-15678;So;0;ON;;;;;N;;;;; 28F2;BRAILLE PATTERN DOTS-25678;So;0;ON;;;;;N;;;;; 28F3;BRAILLE PATTERN DOTS-125678;So;0;ON;;;;;N;;;;; 28F4;BRAILLE PATTERN DOTS-35678;So;0;ON;;;;;N;;;;; 28F5;BRAILLE PATTERN DOTS-135678;So;0;ON;;;;;N;;;;; 28F6;BRAILLE PATTERN DOTS-235678;So;0;ON;;;;;N;;;;; 28F7;BRAILLE PATTERN DOTS-1235678;So;0;ON;;;;;N;;;;; 28F8;BRAILLE PATTERN DOTS-45678;So;0;ON;;;;;N;;;;; 28F9;BRAILLE PATTERN DOTS-145678;So;0;ON;;;;;N;;;;; 28FA;BRAILLE PATTERN DOTS-245678;So;0;ON;;;;;N;;;;; 28FB;BRAILLE PATTERN DOTS-1245678;So;0;ON;;;;;N;;;;; 28FC;BRAILLE PATTERN DOTS-345678;So;0;ON;;;;;N;;;;; 28FD;BRAILLE PATTERN DOTS-1345678;So;0;ON;;;;;N;;;;; 28FE;BRAILLE PATTERN DOTS-2345678;So;0;ON;;;;;N;;;;; 28FF;BRAILLE PATTERN DOTS-12345678;So;0;ON;;;;;N;;;;; 2900;RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2901;RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2902;LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2903;RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2904;LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2905;RIGHTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; 2906;LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; 2907;RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;; 2908;DOWNWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; 2909;UPWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; 290A;UPWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; 290B;DOWNWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;; 290C;LEFTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; 290D;RIGHTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;; 290E;LEFTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; 290F;RIGHTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; 2910;RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;; 2911;RIGHTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;; 2912;UPWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; 2913;DOWNWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;; 2914;RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2915;RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2916;RIGHTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;; 2917;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2918;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2919;LEFTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; 291A;RIGHTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;; 291B;LEFTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; 291C;RIGHTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;; 291D;LEFTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; 291E;RIGHTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; 291F;LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; 2920;RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; 2921;NORTH WEST AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; 2922;NORTH EAST AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; 2923;NORTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; 2924;NORTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; 2925;SOUTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; 2926;SOUTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;; 2927;NORTH WEST ARROW AND NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; 2928;NORTH EAST ARROW AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; 2929;SOUTH EAST ARROW AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;; 292A;SOUTH WEST ARROW AND NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; 292B;RISING DIAGONAL CROSSING FALLING DIAGONAL;Sm;0;ON;;;;;N;;;;; 292C;FALLING DIAGONAL CROSSING RISING DIAGONAL;Sm;0;ON;;;;;N;;;;; 292D;SOUTH EAST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; 292E;NORTH EAST ARROW CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; 292F;FALLING DIAGONAL CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; 2930;RISING DIAGONAL CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;; 2931;NORTH EAST ARROW CROSSING NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;; 2932;NORTH WEST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;; 2933;WAVE ARROW POINTING DIRECTLY RIGHT;Sm;0;ON;;;;;N;;;;; 2934;ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS;Sm;0;ON;;;;;N;;;;; 2935;ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS;Sm;0;ON;;;;;N;;;;; 2936;ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS;Sm;0;ON;;;;;N;;;;; 2937;ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS;Sm;0;ON;;;;;N;;;;; 2938;RIGHT-SIDE ARC CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; 2939;LEFT-SIDE ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; 293A;TOP ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; 293B;BOTTOM ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; 293C;TOP ARC CLOCKWISE ARROW WITH MINUS;Sm;0;ON;;;;;N;;;;; 293D;TOP ARC ANTICLOCKWISE ARROW WITH PLUS;Sm;0;ON;;;;;N;;;;; 293E;LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; 293F;LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;; 2940;ANTICLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; 2941;CLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;; 2942;RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 2943;LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 2944;SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 2945;RIGHTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; 2946;LEFTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;; 2947;RIGHTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;; 2948;LEFT RIGHT ARROW THROUGH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; 2949;UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; 294A;LEFT BARB UP RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; 294B;LEFT BARB DOWN RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; 294C;UP BARB RIGHT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; 294D;UP BARB LEFT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; 294E;LEFT BARB UP RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;; 294F;UP BARB RIGHT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;; 2950;LEFT BARB DOWN RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;; 2951;UP BARB LEFT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;; 2952;LEFTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; 2953;RIGHTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;; 2954;UPWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; 2955;DOWNWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;; 2956;LEFTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; 2957;RIGHTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;; 2958;UPWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; 2959;DOWNWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;; 295A;LEFTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; 295B;RIGHTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;; 295C;UPWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; 295D;DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;; 295E;LEFTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; 295F;RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;; 2960;UPWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; 2961;DOWNWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;; 2962;LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; 2963;UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; 2964;RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; 2965;DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; 2966;LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; 2967;LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; 2968;RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;; 2969;RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;; 296A;LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; 296B;LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; 296C;RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;; 296D;RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;; 296E;UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; 296F;DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;; 2970;RIGHT DOUBLE ARROW WITH ROUNDED HEAD;Sm;0;ON;;;;;N;;;;; 2971;EQUALS SIGN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 2972;TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 2973;LEFTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; 2974;RIGHTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;; 2975;RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;; 2976;LESS-THAN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 2977;LEFTWARDS ARROW THROUGH LESS-THAN;Sm;0;ON;;;;;N;;;;; 2978;GREATER-THAN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 2979;SUBSET ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 297A;LEFTWARDS ARROW THROUGH SUBSET;Sm;0;ON;;;;;N;;;;; 297B;SUPERSET ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;; 297C;LEFT FISH TAIL;Sm;0;ON;;;;;N;;;;; 297D;RIGHT FISH TAIL;Sm;0;ON;;;;;N;;;;; 297E;UP FISH TAIL;Sm;0;ON;;;;;N;;;;; 297F;DOWN FISH TAIL;Sm;0;ON;;;;;N;;;;; 2980;TRIPLE VERTICAL BAR DELIMITER;Sm;0;ON;;;;;N;;;;; 2981;Z NOTATION SPOT;Sm;0;ON;;;;;N;;;;; 2982;Z NOTATION TYPE COLON;Sm;0;ON;;;;;N;;;;; 2983;LEFT WHITE CURLY BRACKET;Ps;0;ON;;;;;Y;;;;; 2984;RIGHT WHITE CURLY BRACKET;Pe;0;ON;;;;;Y;;;;; 2985;LEFT WHITE PARENTHESIS;Ps;0;ON;;;;;Y;;;;; 2986;RIGHT WHITE PARENTHESIS;Pe;0;ON;;;;;Y;;;;; 2987;Z NOTATION LEFT IMAGE BRACKET;Ps;0;ON;;;;;Y;;;;; 2988;Z NOTATION RIGHT IMAGE BRACKET;Pe;0;ON;;;;;Y;;;;; 2989;Z NOTATION LEFT BINDING BRACKET;Ps;0;ON;;;;;Y;;;;; 298A;Z NOTATION RIGHT BINDING BRACKET;Pe;0;ON;;;;;Y;;;;; 298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps;0;ON;;;;;Y;;;;; 298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe;0;ON;;;;;Y;;;;; 298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps;0;ON;;;;;Y;;;;; 298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe;0;ON;;;;;Y;;;;; 298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps;0;ON;;;;;Y;;;;; 2990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe;0;ON;;;;;Y;;;;; 2991;LEFT ANGLE BRACKET WITH DOT;Ps;0;ON;;;;;Y;;;;; 2992;RIGHT ANGLE BRACKET WITH DOT;Pe;0;ON;;;;;Y;;;;; 2993;LEFT ARC LESS-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; 2994;RIGHT ARC GREATER-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; 2995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps;0;ON;;;;;Y;;;;; 2996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe;0;ON;;;;;Y;;;;; 2997;LEFT BLACK TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;; 2998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;; 2999;DOTTED FENCE;Sm;0;ON;;;;;N;;;;; 299A;VERTICAL ZIGZAG LINE;Sm;0;ON;;;;;N;;;;; 299B;MEASURED ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; 299C;RIGHT ANGLE VARIANT WITH SQUARE;Sm;0;ON;;;;;Y;;;;; 299D;MEASURED RIGHT ANGLE WITH DOT;Sm;0;ON;;;;;Y;;;;; 299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;; 299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;; 29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; 29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; 29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;; 29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;; 29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; 29A5;REVERSED ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; 29A6;OBLIQUE ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; 29A7;OBLIQUE ANGLE OPENING DOWN;Sm;0;ON;;;;;Y;;;;; 29A8;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT;Sm;0;ON;;;;;Y;;;;; 29A9;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT;Sm;0;ON;;;;;Y;;;;; 29AA;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT;Sm;0;ON;;;;;Y;;;;; 29AB;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT;Sm;0;ON;;;;;Y;;;;; 29AC;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP;Sm;0;ON;;;;;Y;;;;; 29AD;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP;Sm;0;ON;;;;;Y;;;;; 29AE;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN;Sm;0;ON;;;;;Y;;;;; 29AF;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN;Sm;0;ON;;;;;Y;;;;; 29B0;REVERSED EMPTY SET;Sm;0;ON;;;;;N;;;;; 29B1;EMPTY SET WITH OVERBAR;Sm;0;ON;;;;;N;;;;; 29B2;EMPTY SET WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; 29B3;EMPTY SET WITH RIGHT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; 29B4;EMPTY SET WITH LEFT ARROW ABOVE;Sm;0;ON;;;;;N;;;;; 29B5;CIRCLE WITH HORIZONTAL BAR;Sm;0;ON;;;;;N;;;;; 29B6;CIRCLED VERTICAL BAR;Sm;0;ON;;;;;N;;;;; 29B7;CIRCLED PARALLEL;Sm;0;ON;;;;;N;;;;; 29B8;CIRCLED REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; 29B9;CIRCLED PERPENDICULAR;Sm;0;ON;;;;;N;;;;; 29BA;CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR;Sm;0;ON;;;;;N;;;;; 29BB;CIRCLE WITH SUPERIMPOSED X;Sm;0;ON;;;;;N;;;;; 29BC;CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; 29BD;UP ARROW THROUGH CIRCLE;Sm;0;ON;;;;;N;;;;; 29BE;CIRCLED WHITE BULLET;Sm;0;ON;;;;;N;;;;; 29BF;CIRCLED BULLET;Sm;0;ON;;;;;N;;;;; 29C0;CIRCLED LESS-THAN;Sm;0;ON;;;;;Y;;;;; 29C1;CIRCLED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; 29C2;CIRCLE WITH SMALL CIRCLE TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; 29C3;CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT;Sm;0;ON;;;;;Y;;;;; 29C4;SQUARED RISING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; 29C5;SQUARED FALLING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;; 29C6;SQUARED ASTERISK;Sm;0;ON;;;;;N;;;;; 29C7;SQUARED SMALL CIRCLE;Sm;0;ON;;;;;N;;;;; 29C8;SQUARED SQUARE;Sm;0;ON;;;;;N;;;;; 29C9;TWO JOINED SQUARES;Sm;0;ON;;;;;Y;;;;; 29CA;TRIANGLE WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; 29CB;TRIANGLE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; 29CC;S IN TRIANGLE;Sm;0;ON;;;;;N;;;;; 29CD;TRIANGLE WITH SERIFS AT BOTTOM;Sm;0;ON;;;;;N;;;;; 29CE;RIGHT TRIANGLE ABOVE LEFT TRIANGLE;Sm;0;ON;;;;;Y;;;;; 29CF;LEFT TRIANGLE BESIDE VERTICAL BAR;Sm;0;ON;;;;;Y;;;;; 29D0;VERTICAL BAR BESIDE RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;; 29D1;BOWTIE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; 29D2;BOWTIE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; 29D3;BLACK BOWTIE;Sm;0;ON;;;;;N;;;;; 29D4;TIMES WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; 29D5;TIMES WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; 29D6;WHITE HOURGLASS;Sm;0;ON;;;;;N;;;;; 29D7;BLACK HOURGLASS;Sm;0;ON;;;;;N;;;;; 29D8;LEFT WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; 29D9;RIGHT WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; 29DA;LEFT DOUBLE WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;; 29DB;RIGHT DOUBLE WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;; 29DC;INCOMPLETE INFINITY;Sm;0;ON;;;;;Y;;;;; 29DD;TIE OVER INFINITY;Sm;0;ON;;;;;N;;;;; 29DE;INFINITY NEGATED WITH VERTICAL BAR;Sm;0;ON;;;;;N;;;;; 29DF;DOUBLE-ENDED MULTIMAP;Sm;0;ON;;;;;N;;;;; 29E0;SQUARE WITH CONTOURED OUTLINE;Sm;0;ON;;;;;N;;;;; 29E1;INCREASES AS;Sm;0;ON;;;;;Y;;;;; 29E2;SHUFFLE PRODUCT;Sm;0;ON;;;;;N;;;;; 29E3;EQUALS SIGN AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; 29E4;EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; 29E5;IDENTICAL TO AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;; 29E6;GLEICH STARK;Sm;0;ON;;;;;N;;;;; 29E7;THERMODYNAMIC;Sm;0;ON;;;;;N;;;;; 29E8;DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;; 29E9;DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;; 29EA;BLACK DIAMOND WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; 29EB;BLACK LOZENGE;Sm;0;ON;;;;;N;;;;; 29EC;WHITE CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; 29ED;BLACK CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;; 29EE;ERROR-BARRED WHITE SQUARE;Sm;0;ON;;;;;N;;;;; 29EF;ERROR-BARRED BLACK SQUARE;Sm;0;ON;;;;;N;;;;; 29F0;ERROR-BARRED WHITE DIAMOND;Sm;0;ON;;;;;N;;;;; 29F1;ERROR-BARRED BLACK DIAMOND;Sm;0;ON;;;;;N;;;;; 29F2;ERROR-BARRED WHITE CIRCLE;Sm;0;ON;;;;;N;;;;; 29F3;ERROR-BARRED BLACK CIRCLE;Sm;0;ON;;;;;N;;;;; 29F4;RULE-DELAYED;Sm;0;ON;;;;;Y;;;;; 29F5;REVERSE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; 29F6;SOLIDUS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; 29F7;REVERSE SOLIDUS WITH HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;; 29F8;BIG SOLIDUS;Sm;0;ON;;;;;Y;;;;; 29F9;BIG REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;; 29FA;DOUBLE PLUS;Sm;0;ON;;;;;N;;;;; 29FB;TRIPLE PLUS;Sm;0;ON;;;;;N;;;;; 29FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;; 29FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;; 29FE;TINY;Sm;0;ON;;;;;N;;;;; 29FF;MINY;Sm;0;ON;;;;;N;;;;; 2A00;N-ARY CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;; 2A01;N-ARY CIRCLED PLUS OPERATOR;Sm;0;ON;;;;;N;;;;; 2A02;N-ARY CIRCLED TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; 2A03;N-ARY UNION OPERATOR WITH DOT;Sm;0;ON;;;;;N;;;;; 2A04;N-ARY UNION OPERATOR WITH PLUS;Sm;0;ON;;;;;N;;;;; 2A05;N-ARY SQUARE INTERSECTION OPERATOR;Sm;0;ON;;;;;N;;;;; 2A06;N-ARY SQUARE UNION OPERATOR;Sm;0;ON;;;;;N;;;;; 2A07;TWO LOGICAL AND OPERATOR;Sm;0;ON;;;;;N;;;;; 2A08;TWO LOGICAL OR OPERATOR;Sm;0;ON;;;;;N;;;;; 2A09;N-ARY TIMES OPERATOR;Sm;0;ON;;;;;N;;;;; 2A0A;MODULO TWO SUM;Sm;0;ON;;;;;Y;;;;; 2A0B;SUMMATION WITH INTEGRAL;Sm;0;ON;;;;;Y;;;;; 2A0C;QUADRUPLE INTEGRAL OPERATOR;Sm;0;ON; 222B 222B 222B 222B;;;;Y;;;;; 2A0D;FINITE PART INTEGRAL;Sm;0;ON;;;;;Y;;;;; 2A0E;INTEGRAL WITH DOUBLE STROKE;Sm;0;ON;;;;;Y;;;;; 2A0F;INTEGRAL AVERAGE WITH SLASH;Sm;0;ON;;;;;Y;;;;; 2A10;CIRCULATION FUNCTION;Sm;0;ON;;;;;Y;;;;; 2A11;ANTICLOCKWISE INTEGRATION;Sm;0;ON;;;;;Y;;;;; 2A12;LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; 2A13;LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;; 2A14;LINE INTEGRATION NOT INCLUDING THE POLE;Sm;0;ON;;;;;Y;;;;; 2A15;INTEGRAL AROUND A POINT OPERATOR;Sm;0;ON;;;;;Y;;;;; 2A16;QUATERNION INTEGRAL OPERATOR;Sm;0;ON;;;;;Y;;;;; 2A17;INTEGRAL WITH LEFTWARDS ARROW WITH HOOK;Sm;0;ON;;;;;Y;;;;; 2A18;INTEGRAL WITH TIMES SIGN;Sm;0;ON;;;;;Y;;;;; 2A19;INTEGRAL WITH INTERSECTION;Sm;0;ON;;;;;Y;;;;; 2A1A;INTEGRAL WITH UNION;Sm;0;ON;;;;;Y;;;;; 2A1B;INTEGRAL WITH OVERBAR;Sm;0;ON;;;;;Y;;;;; 2A1C;INTEGRAL WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; 2A1D;JOIN;Sm;0;ON;;;;;N;;;;; 2A1E;LARGE LEFT TRIANGLE OPERATOR;Sm;0;ON;;;;;Y;;;;; 2A1F;Z NOTATION SCHEMA COMPOSITION;Sm;0;ON;;;;;Y;;;;; 2A20;Z NOTATION SCHEMA PIPING;Sm;0;ON;;;;;Y;;;;; 2A21;Z NOTATION SCHEMA PROJECTION;Sm;0;ON;;;;;Y;;;;; 2A22;PLUS SIGN WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; 2A23;PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE;Sm;0;ON;;;;;N;;;;; 2A24;PLUS SIGN WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;; 2A25;PLUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; 2A26;PLUS SIGN WITH TILDE BELOW;Sm;0;ON;;;;;Y;;;;; 2A27;PLUS SIGN WITH SUBSCRIPT TWO;Sm;0;ON;;;;;N;;;;; 2A28;PLUS SIGN WITH BLACK TRIANGLE;Sm;0;ON;;;;;N;;;;; 2A29;MINUS SIGN WITH COMMA ABOVE;Sm;0;ON;;;;;Y;;;;; 2A2A;MINUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; 2A2B;MINUS SIGN WITH FALLING DOTS;Sm;0;ON;;;;;Y;;;;; 2A2C;MINUS SIGN WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; 2A2D;PLUS SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; 2A2E;PLUS SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; 2A2F;VECTOR OR CROSS PRODUCT;Sm;0;ON;;;;;N;;;;; 2A30;MULTIPLICATION SIGN WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; 2A31;MULTIPLICATION SIGN WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; 2A32;SEMIDIRECT PRODUCT WITH BOTTOM CLOSED;Sm;0;ON;;;;;N;;;;; 2A33;SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; 2A34;MULTIPLICATION SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; 2A35;MULTIPLICATION SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;; 2A36;CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;N;;;;; 2A37;MULTIPLICATION SIGN IN DOUBLE CIRCLE;Sm;0;ON;;;;;N;;;;; 2A38;CIRCLED DIVISION SIGN;Sm;0;ON;;;;;N;;;;; 2A39;PLUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; 2A3A;MINUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; 2A3B;MULTIPLICATION SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;; 2A3C;INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; 2A3D;RIGHTHAND INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;; 2A3E;Z NOTATION RELATIONAL COMPOSITION;Sm;0;ON;;;;;Y;;;;; 2A3F;AMALGAMATION OR COPRODUCT;Sm;0;ON;;;;;N;;;;; 2A40;INTERSECTION WITH DOT;Sm;0;ON;;;;;N;;;;; 2A41;UNION WITH MINUS SIGN;Sm;0;ON;;;;;N;;;;; 2A42;UNION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; 2A43;INTERSECTION WITH OVERBAR;Sm;0;ON;;;;;N;;;;; 2A44;INTERSECTION WITH LOGICAL AND;Sm;0;ON;;;;;N;;;;; 2A45;UNION WITH LOGICAL OR;Sm;0;ON;;;;;N;;;;; 2A46;UNION ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; 2A47;INTERSECTION ABOVE UNION;Sm;0;ON;;;;;N;;;;; 2A48;UNION ABOVE BAR ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;; 2A49;INTERSECTION ABOVE BAR ABOVE UNION;Sm;0;ON;;;;;N;;;;; 2A4A;UNION BESIDE AND JOINED WITH UNION;Sm;0;ON;;;;;N;;;;; 2A4B;INTERSECTION BESIDE AND JOINED WITH INTERSECTION;Sm;0;ON;;;;;N;;;;; 2A4C;CLOSED UNION WITH SERIFS;Sm;0;ON;;;;;N;;;;; 2A4D;CLOSED INTERSECTION WITH SERIFS;Sm;0;ON;;;;;N;;;;; 2A4E;DOUBLE SQUARE INTERSECTION;Sm;0;ON;;;;;N;;;;; 2A4F;DOUBLE SQUARE UNION;Sm;0;ON;;;;;N;;;;; 2A50;CLOSED UNION WITH SERIFS AND SMASH PRODUCT;Sm;0;ON;;;;;N;;;;; 2A51;LOGICAL AND WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; 2A52;LOGICAL OR WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; 2A53;DOUBLE LOGICAL AND;Sm;0;ON;;;;;N;;;;; 2A54;DOUBLE LOGICAL OR;Sm;0;ON;;;;;N;;;;; 2A55;TWO INTERSECTING LOGICAL AND;Sm;0;ON;;;;;N;;;;; 2A56;TWO INTERSECTING LOGICAL OR;Sm;0;ON;;;;;N;;;;; 2A57;SLOPING LARGE OR;Sm;0;ON;;;;;Y;;;;; 2A58;SLOPING LARGE AND;Sm;0;ON;;;;;Y;;;;; 2A59;LOGICAL OR OVERLAPPING LOGICAL AND;Sm;0;ON;;;;;N;;;;; 2A5A;LOGICAL AND WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; 2A5B;LOGICAL OR WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;; 2A5C;LOGICAL AND WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; 2A5D;LOGICAL OR WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;; 2A5E;LOGICAL AND WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; 2A5F;LOGICAL AND WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; 2A60;LOGICAL AND WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; 2A61;SMALL VEE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; 2A62;LOGICAL OR WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;; 2A63;LOGICAL OR WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;; 2A64;Z NOTATION DOMAIN ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; 2A65;Z NOTATION RANGE ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;; 2A66;EQUALS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;; 2A67;IDENTICAL WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;; 2A68;TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2A69;TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;; 2A6A;TILDE OPERATOR WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; 2A6B;TILDE OPERATOR WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;; 2A6C;SIMILAR MINUS SIMILAR;Sm;0;ON;;;;;Y;;;;; 2A6D;CONGRUENT WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; 2A6E;EQUALS WITH ASTERISK;Sm;0;ON;;;;;N;;;;; 2A6F;ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;Y;;;;; 2A70;APPROXIMATELY EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2A71;EQUALS SIGN ABOVE PLUS SIGN;Sm;0;ON;;;;;N;;;;; 2A72;PLUS SIGN ABOVE EQUALS SIGN;Sm;0;ON;;;;;N;;;;; 2A73;EQUALS SIGN ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; 2A74;DOUBLE COLON EQUAL;Sm;0;ON; 003A 003A 003D;;;;Y;;;;; 2A75;TWO CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D;;;;N;;;;; 2A76;THREE CONSECUTIVE EQUALS SIGNS;Sm;0;ON; 003D 003D 003D;;;;N;;;;; 2A77;EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW;Sm;0;ON;;;;;N;;;;; 2A78;EQUIVALENT WITH FOUR DOTS ABOVE;Sm;0;ON;;;;;N;;;;; 2A79;LESS-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; 2A7A;GREATER-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;; 2A7B;LESS-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; 2A7C;GREATER-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;; 2A7D;LESS-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2A7E;GREATER-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2A7F;LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; 2A80;GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; 2A81;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; 2A82;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; 2A83;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT;Sm;0;ON;;;;;Y;;;;; 2A84;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT;Sm;0;ON;;;;;Y;;;;; 2A85;LESS-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; 2A86;GREATER-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;; 2A87;LESS-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2A88;GREATER-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2A89;LESS-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; 2A8A;GREATER-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;; 2A8B;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; 2A8C;GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; 2A8D;LESS-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; 2A8E;GREATER-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;; 2A8F;LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;; 2A90;GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;; 2A91;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; 2A92;GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;; 2A93;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; 2A94;GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; 2A95;SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; 2A96;SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; 2A97;SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; 2A98;SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;; 2A99;DOUBLE-LINE EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; 2A9A;DOUBLE-LINE EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; 2A9B;DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; 2A9C;DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; 2A9D;SIMILAR OR LESS-THAN;Sm;0;ON;;;;;Y;;;;; 2A9E;SIMILAR OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;; 2A9F;SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; 2AA0;SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; 2AA1;DOUBLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; 2AA2;DOUBLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; 2AA3;DOUBLE NESTED LESS-THAN WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; 2AA4;GREATER-THAN OVERLAPPING LESS-THAN;Sm;0;ON;;;;;N;;;;; 2AA5;GREATER-THAN BESIDE LESS-THAN;Sm;0;ON;;;;;N;;;;; 2AA6;LESS-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; 2AA7;GREATER-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;; 2AA8;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; 2AA9;GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;; 2AAA;SMALLER THAN;Sm;0;ON;;;;;Y;;;;; 2AAB;LARGER THAN;Sm;0;ON;;;;;Y;;;;; 2AAC;SMALLER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AAD;LARGER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AAE;EQUALS SIGN WITH BUMPY ABOVE;Sm;0;ON;;;;;N;;;;; 2AAF;PRECEDES ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; 2AB0;SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; 2AB1;PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AB2;SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AB3;PRECEDES ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; 2AB4;SUCCEEDS ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; 2AB5;PRECEDES ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AB6;SUCCEEDS ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AB7;PRECEDES ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AB8;SUCCEEDS ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AB9;PRECEDES ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2ABA;SUCCEEDS ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2ABB;DOUBLE PRECEDES;Sm;0;ON;;;;;Y;;;;; 2ABC;DOUBLE SUCCEEDS;Sm;0;ON;;;;;Y;;;;; 2ABD;SUBSET WITH DOT;Sm;0;ON;;;;;Y;;;;; 2ABE;SUPERSET WITH DOT;Sm;0;ON;;;;;Y;;;;; 2ABF;SUBSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; 2AC0;SUPERSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;; 2AC1;SUBSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; 2AC2;SUPERSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;; 2AC3;SUBSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; 2AC4;SUPERSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;; 2AC5;SUBSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; 2AC6;SUPERSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;; 2AC7;SUBSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; 2AC8;SUPERSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; 2AC9;SUBSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2ACA;SUPERSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2ACB;SUBSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2ACC;SUPERSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2ACD;SQUARE LEFT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; 2ACE;SQUARE RIGHT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;; 2ACF;CLOSED SUBSET;Sm;0;ON;;;;;Y;;;;; 2AD0;CLOSED SUPERSET;Sm;0;ON;;;;;Y;;;;; 2AD1;CLOSED SUBSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AD2;CLOSED SUPERSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AD3;SUBSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; 2AD4;SUPERSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; 2AD5;SUBSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;; 2AD6;SUPERSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;; 2AD7;SUPERSET BESIDE SUBSET;Sm;0;ON;;;;;N;;;;; 2AD8;SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET;Sm;0;ON;;;;;N;;;;; 2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;; 2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;; 2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;; 2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;not independent;;; 2ADD;NONFORKING;Sm;0;ON;;;;;N;;independent;;; 2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;; 2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; 2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;; 2AE1;PERPENDICULAR WITH S;Sm;0;ON;;;;;N;;;;; 2AE2;VERTICAL BAR TRIPLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;; 2AE3;DOUBLE VERTICAL BAR LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; 2AE4;VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; 2AE5;DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;; 2AE6;LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL;Sm;0;ON;;;;;Y;;;;; 2AE7;SHORT DOWN TACK WITH OVERBAR;Sm;0;ON;;;;;N;;;;; 2AE8;SHORT UP TACK WITH UNDERBAR;Sm;0;ON;;;;;N;;;;; 2AE9;SHORT UP TACK ABOVE SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;; 2AEA;DOUBLE DOWN TACK;Sm;0;ON;;;;;N;;;;; 2AEB;DOUBLE UP TACK;Sm;0;ON;;;;;N;;;;; 2AEC;DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; 2AED;REVERSED DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;; 2AEE;DOES NOT DIVIDE WITH REVERSED NEGATION SLASH;Sm;0;ON;;;;;Y;;;;; 2AEF;VERTICAL LINE WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;; 2AF0;VERTICAL LINE WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; 2AF1;DOWN TACK WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;; 2AF2;PARALLEL WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; 2AF3;PARALLEL WITH TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;; 2AF4;TRIPLE VERTICAL BAR BINARY RELATION;Sm;0;ON;;;;;N;;;;; 2AF5;TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;; 2AF6;TRIPLE COLON OPERATOR;Sm;0;ON;;;;;N;;;;; 2AF7;TRIPLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;; 2AF8;TRIPLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;; 2AF9;DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AFA;DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;; 2AFB;TRIPLE SOLIDUS BINARY RELATION;Sm;0;ON;;;;;Y;;;;; 2AFC;LARGE TRIPLE VERTICAL BAR OPERATOR;Sm;0;ON;;;;;N;;;;; 2AFD;DOUBLE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;; 2AFE;WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; 2AFF;N-ARY WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;; 2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;; 2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;; 2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;; 2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;; 2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;; 2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;; 2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;; 2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;; 2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;; 2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;; 2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;; 2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;; 2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;; 2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;; 2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;; 2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;; 2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;; 2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;; 2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;; 2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;; 2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;; 2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;; 2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;; 2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;; 2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;; 2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;; 2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;; 2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;; 2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;; 2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;; 2E9F;CJK RADICAL MOTHER;So;0;ON; 6BCD;;;;N;;;;; 2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;; 2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;; 2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;; 2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;; 2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;; 2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;; 2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;; 2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;; 2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;; 2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;; 2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;; 2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;; 2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;; 2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;; 2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;; 2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;; 2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;; 2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;; 2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;; 2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;; 2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;; 2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;; 2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;; 2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;; 2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;; 2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;; 2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;; 2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;; 2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;; 2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;; 2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;; 2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;; 2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;; 2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;; 2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;; 2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;; 2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;; 2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;; 2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;; 2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;; 2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;; 2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;; 2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;; 2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;; 2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;; 2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;; 2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;; 2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;; 2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;; 2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;; 2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;; 2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;; 2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;; 2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;; 2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;; 2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;; 2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;; 2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;; 2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;; 2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;; 2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;; 2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;; 2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;; 2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;; 2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;; 2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;; 2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;; 2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;; 2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;; 2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;; 2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;; 2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;; 2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;; 2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;; 2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;; 2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; 2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;; 2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; 2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;; 2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; 2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;; 2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;; 2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;; 2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON; 9F9F;;;;N;;;;; 2F00;KANGXI RADICAL ONE;So;0;ON; 4E00;;;;N;;;;; 2F01;KANGXI RADICAL LINE;So;0;ON; 4E28;;;;N;;;;; 2F02;KANGXI RADICAL DOT;So;0;ON; 4E36;;;;N;;;;; 2F03;KANGXI RADICAL SLASH;So;0;ON; 4E3F;;;;N;;;;; 2F04;KANGXI RADICAL SECOND;So;0;ON; 4E59;;;;N;;;;; 2F05;KANGXI RADICAL HOOK;So;0;ON; 4E85;;;;N;;;;; 2F06;KANGXI RADICAL TWO;So;0;ON; 4E8C;;;;N;;;;; 2F07;KANGXI RADICAL LID;So;0;ON; 4EA0;;;;N;;;;; 2F08;KANGXI RADICAL MAN;So;0;ON; 4EBA;;;;N;;;;; 2F09;KANGXI RADICAL LEGS;So;0;ON; 513F;;;;N;;;;; 2F0A;KANGXI RADICAL ENTER;So;0;ON; 5165;;;;N;;;;; 2F0B;KANGXI RADICAL EIGHT;So;0;ON; 516B;;;;N;;;;; 2F0C;KANGXI RADICAL DOWN BOX;So;0;ON; 5182;;;;N;;;;; 2F0D;KANGXI RADICAL COVER;So;0;ON; 5196;;;;N;;;;; 2F0E;KANGXI RADICAL ICE;So;0;ON; 51AB;;;;N;;;;; 2F0F;KANGXI RADICAL TABLE;So;0;ON; 51E0;;;;N;;;;; 2F10;KANGXI RADICAL OPEN BOX;So;0;ON; 51F5;;;;N;;;;; 2F11;KANGXI RADICAL KNIFE;So;0;ON; 5200;;;;N;;;;; 2F12;KANGXI RADICAL POWER;So;0;ON; 529B;;;;N;;;;; 2F13;KANGXI RADICAL WRAP;So;0;ON; 52F9;;;;N;;;;; 2F14;KANGXI RADICAL SPOON;So;0;ON; 5315;;;;N;;;;; 2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON; 531A;;;;N;;;;; 2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON; 5338;;;;N;;;;; 2F17;KANGXI RADICAL TEN;So;0;ON; 5341;;;;N;;;;; 2F18;KANGXI RADICAL DIVINATION;So;0;ON; 535C;;;;N;;;;; 2F19;KANGXI RADICAL SEAL;So;0;ON; 5369;;;;N;;;;; 2F1A;KANGXI RADICAL CLIFF;So;0;ON; 5382;;;;N;;;;; 2F1B;KANGXI RADICAL PRIVATE;So;0;ON; 53B6;;;;N;;;;; 2F1C;KANGXI RADICAL AGAIN;So;0;ON; 53C8;;;;N;;;;; 2F1D;KANGXI RADICAL MOUTH;So;0;ON; 53E3;;;;N;;;;; 2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON; 56D7;;;;N;;;;; 2F1F;KANGXI RADICAL EARTH;So;0;ON; 571F;;;;N;;;;; 2F20;KANGXI RADICAL SCHOLAR;So;0;ON; 58EB;;;;N;;;;; 2F21;KANGXI RADICAL GO;So;0;ON; 5902;;;;N;;;;; 2F22;KANGXI RADICAL GO SLOWLY;So;0;ON; 590A;;;;N;;;;; 2F23;KANGXI RADICAL EVENING;So;0;ON; 5915;;;;N;;;;; 2F24;KANGXI RADICAL BIG;So;0;ON; 5927;;;;N;;;;; 2F25;KANGXI RADICAL WOMAN;So;0;ON; 5973;;;;N;;;;; 2F26;KANGXI RADICAL CHILD;So;0;ON; 5B50;;;;N;;;;; 2F27;KANGXI RADICAL ROOF;So;0;ON; 5B80;;;;N;;;;; 2F28;KANGXI RADICAL INCH;So;0;ON; 5BF8;;;;N;;;;; 2F29;KANGXI RADICAL SMALL;So;0;ON; 5C0F;;;;N;;;;; 2F2A;KANGXI RADICAL LAME;So;0;ON; 5C22;;;;N;;;;; 2F2B;KANGXI RADICAL CORPSE;So;0;ON; 5C38;;;;N;;;;; 2F2C;KANGXI RADICAL SPROUT;So;0;ON; 5C6E;;;;N;;;;; 2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON; 5C71;;;;N;;;;; 2F2E;KANGXI RADICAL RIVER;So;0;ON; 5DDB;;;;N;;;;; 2F2F;KANGXI RADICAL WORK;So;0;ON; 5DE5;;;;N;;;;; 2F30;KANGXI RADICAL ONESELF;So;0;ON; 5DF1;;;;N;;;;; 2F31;KANGXI RADICAL TURBAN;So;0;ON; 5DFE;;;;N;;;;; 2F32;KANGXI RADICAL DRY;So;0;ON; 5E72;;;;N;;;;; 2F33;KANGXI RADICAL SHORT THREAD;So;0;ON; 5E7A;;;;N;;;;; 2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON; 5E7F;;;;N;;;;; 2F35;KANGXI RADICAL LONG STRIDE;So;0;ON; 5EF4;;;;N;;;;; 2F36;KANGXI RADICAL TWO HANDS;So;0;ON; 5EFE;;;;N;;;;; 2F37;KANGXI RADICAL SHOOT;So;0;ON; 5F0B;;;;N;;;;; 2F38;KANGXI RADICAL BOW;So;0;ON; 5F13;;;;N;;;;; 2F39;KANGXI RADICAL SNOUT;So;0;ON; 5F50;;;;N;;;;; 2F3A;KANGXI RADICAL BRISTLE;So;0;ON; 5F61;;;;N;;;;; 2F3B;KANGXI RADICAL STEP;So;0;ON; 5F73;;;;N;;;;; 2F3C;KANGXI RADICAL HEART;So;0;ON; 5FC3;;;;N;;;;; 2F3D;KANGXI RADICAL HALBERD;So;0;ON; 6208;;;;N;;;;; 2F3E;KANGXI RADICAL DOOR;So;0;ON; 6236;;;;N;;;;; 2F3F;KANGXI RADICAL HAND;So;0;ON; 624B;;;;N;;;;; 2F40;KANGXI RADICAL BRANCH;So;0;ON; 652F;;;;N;;;;; 2F41;KANGXI RADICAL RAP;So;0;ON; 6534;;;;N;;;;; 2F42;KANGXI RADICAL SCRIPT;So;0;ON; 6587;;;;N;;;;; 2F43;KANGXI RADICAL DIPPER;So;0;ON; 6597;;;;N;;;;; 2F44;KANGXI RADICAL AXE;So;0;ON; 65A4;;;;N;;;;; 2F45;KANGXI RADICAL SQUARE;So;0;ON; 65B9;;;;N;;;;; 2F46;KANGXI RADICAL NOT;So;0;ON; 65E0;;;;N;;;;; 2F47;KANGXI RADICAL SUN;So;0;ON; 65E5;;;;N;;;;; 2F48;KANGXI RADICAL SAY;So;0;ON; 66F0;;;;N;;;;; 2F49;KANGXI RADICAL MOON;So;0;ON; 6708;;;;N;;;;; 2F4A;KANGXI RADICAL TREE;So;0;ON; 6728;;;;N;;;;; 2F4B;KANGXI RADICAL LACK;So;0;ON; 6B20;;;;N;;;;; 2F4C;KANGXI RADICAL STOP;So;0;ON; 6B62;;;;N;;;;; 2F4D;KANGXI RADICAL DEATH;So;0;ON; 6B79;;;;N;;;;; 2F4E;KANGXI RADICAL WEAPON;So;0;ON; 6BB3;;;;N;;;;; 2F4F;KANGXI RADICAL DO NOT;So;0;ON; 6BCB;;;;N;;;;; 2F50;KANGXI RADICAL COMPARE;So;0;ON; 6BD4;;;;N;;;;; 2F51;KANGXI RADICAL FUR;So;0;ON; 6BDB;;;;N;;;;; 2F52;KANGXI RADICAL CLAN;So;0;ON; 6C0F;;;;N;;;;; 2F53;KANGXI RADICAL STEAM;So;0;ON; 6C14;;;;N;;;;; 2F54;KANGXI RADICAL WATER;So;0;ON; 6C34;;;;N;;;;; 2F55;KANGXI RADICAL FIRE;So;0;ON; 706B;;;;N;;;;; 2F56;KANGXI RADICAL CLAW;So;0;ON; 722A;;;;N;;;;; 2F57;KANGXI RADICAL FATHER;So;0;ON; 7236;;;;N;;;;; 2F58;KANGXI RADICAL DOUBLE X;So;0;ON; 723B;;;;N;;;;; 2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON; 723F;;;;N;;;;; 2F5A;KANGXI RADICAL SLICE;So;0;ON; 7247;;;;N;;;;; 2F5B;KANGXI RADICAL FANG;So;0;ON; 7259;;;;N;;;;; 2F5C;KANGXI RADICAL COW;So;0;ON; 725B;;;;N;;;;; 2F5D;KANGXI RADICAL DOG;So;0;ON; 72AC;;;;N;;;;; 2F5E;KANGXI RADICAL PROFOUND;So;0;ON; 7384;;;;N;;;;; 2F5F;KANGXI RADICAL JADE;So;0;ON; 7389;;;;N;;;;; 2F60;KANGXI RADICAL MELON;So;0;ON; 74DC;;;;N;;;;; 2F61;KANGXI RADICAL TILE;So;0;ON; 74E6;;;;N;;;;; 2F62;KANGXI RADICAL SWEET;So;0;ON; 7518;;;;N;;;;; 2F63;KANGXI RADICAL LIFE;So;0;ON; 751F;;;;N;;;;; 2F64;KANGXI RADICAL USE;So;0;ON; 7528;;;;N;;;;; 2F65;KANGXI RADICAL FIELD;So;0;ON; 7530;;;;N;;;;; 2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON; 758B;;;;N;;;;; 2F67;KANGXI RADICAL SICKNESS;So;0;ON; 7592;;;;N;;;;; 2F68;KANGXI RADICAL DOTTED TENT;So;0;ON; 7676;;;;N;;;;; 2F69;KANGXI RADICAL WHITE;So;0;ON; 767D;;;;N;;;;; 2F6A;KANGXI RADICAL SKIN;So;0;ON; 76AE;;;;N;;;;; 2F6B;KANGXI RADICAL DISH;So;0;ON; 76BF;;;;N;;;;; 2F6C;KANGXI RADICAL EYE;So;0;ON; 76EE;;;;N;;;;; 2F6D;KANGXI RADICAL SPEAR;So;0;ON; 77DB;;;;N;;;;; 2F6E;KANGXI RADICAL ARROW;So;0;ON; 77E2;;;;N;;;;; 2F6F;KANGXI RADICAL STONE;So;0;ON; 77F3;;;;N;;;;; 2F70;KANGXI RADICAL SPIRIT;So;0;ON; 793A;;;;N;;;;; 2F71;KANGXI RADICAL TRACK;So;0;ON; 79B8;;;;N;;;;; 2F72;KANGXI RADICAL GRAIN;So;0;ON; 79BE;;;;N;;;;; 2F73;KANGXI RADICAL CAVE;So;0;ON; 7A74;;;;N;;;;; 2F74;KANGXI RADICAL STAND;So;0;ON; 7ACB;;;;N;;;;; 2F75;KANGXI RADICAL BAMBOO;So;0;ON; 7AF9;;;;N;;;;; 2F76;KANGXI RADICAL RICE;So;0;ON; 7C73;;;;N;;;;; 2F77;KANGXI RADICAL SILK;So;0;ON; 7CF8;;;;N;;;;; 2F78;KANGXI RADICAL JAR;So;0;ON; 7F36;;;;N;;;;; 2F79;KANGXI RADICAL NET;So;0;ON; 7F51;;;;N;;;;; 2F7A;KANGXI RADICAL SHEEP;So;0;ON; 7F8A;;;;N;;;;; 2F7B;KANGXI RADICAL FEATHER;So;0;ON; 7FBD;;;;N;;;;; 2F7C;KANGXI RADICAL OLD;So;0;ON; 8001;;;;N;;;;; 2F7D;KANGXI RADICAL AND;So;0;ON; 800C;;;;N;;;;; 2F7E;KANGXI RADICAL PLOW;So;0;ON; 8012;;;;N;;;;; 2F7F;KANGXI RADICAL EAR;So;0;ON; 8033;;;;N;;;;; 2F80;KANGXI RADICAL BRUSH;So;0;ON; 807F;;;;N;;;;; 2F81;KANGXI RADICAL MEAT;So;0;ON; 8089;;;;N;;;;; 2F82;KANGXI RADICAL MINISTER;So;0;ON; 81E3;;;;N;;;;; 2F83;KANGXI RADICAL SELF;So;0;ON; 81EA;;;;N;;;;; 2F84;KANGXI RADICAL ARRIVE;So;0;ON; 81F3;;;;N;;;;; 2F85;KANGXI RADICAL MORTAR;So;0;ON; 81FC;;;;N;;;;; 2F86;KANGXI RADICAL TONGUE;So;0;ON; 820C;;;;N;;;;; 2F87;KANGXI RADICAL OPPOSE;So;0;ON; 821B;;;;N;;;;; 2F88;KANGXI RADICAL BOAT;So;0;ON; 821F;;;;N;;;;; 2F89;KANGXI RADICAL STOPPING;So;0;ON; 826E;;;;N;;;;; 2F8A;KANGXI RADICAL COLOR;So;0;ON; 8272;;;;N;;;;; 2F8B;KANGXI RADICAL GRASS;So;0;ON; 8278;;;;N;;;;; 2F8C;KANGXI RADICAL TIGER;So;0;ON; 864D;;;;N;;;;; 2F8D;KANGXI RADICAL INSECT;So;0;ON; 866B;;;;N;;;;; 2F8E;KANGXI RADICAL BLOOD;So;0;ON; 8840;;;;N;;;;; 2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON; 884C;;;;N;;;;; 2F90;KANGXI RADICAL CLOTHES;So;0;ON; 8863;;;;N;;;;; 2F91;KANGXI RADICAL WEST;So;0;ON; 897E;;;;N;;;;; 2F92;KANGXI RADICAL SEE;So;0;ON; 898B;;;;N;;;;; 2F93;KANGXI RADICAL HORN;So;0;ON; 89D2;;;;N;;;;; 2F94;KANGXI RADICAL SPEECH;So;0;ON; 8A00;;;;N;;;;; 2F95;KANGXI RADICAL VALLEY;So;0;ON; 8C37;;;;N;;;;; 2F96;KANGXI RADICAL BEAN;So;0;ON; 8C46;;;;N;;;;; 2F97;KANGXI RADICAL PIG;So;0;ON; 8C55;;;;N;;;;; 2F98;KANGXI RADICAL BADGER;So;0;ON; 8C78;;;;N;;;;; 2F99;KANGXI RADICAL SHELL;So;0;ON; 8C9D;;;;N;;;;; 2F9A;KANGXI RADICAL RED;So;0;ON; 8D64;;;;N;;;;; 2F9B;KANGXI RADICAL RUN;So;0;ON; 8D70;;;;N;;;;; 2F9C;KANGXI RADICAL FOOT;So;0;ON; 8DB3;;;;N;;;;; 2F9D;KANGXI RADICAL BODY;So;0;ON; 8EAB;;;;N;;;;; 2F9E;KANGXI RADICAL CART;So;0;ON; 8ECA;;;;N;;;;; 2F9F;KANGXI RADICAL BITTER;So;0;ON; 8F9B;;;;N;;;;; 2FA0;KANGXI RADICAL MORNING;So;0;ON; 8FB0;;;;N;;;;; 2FA1;KANGXI RADICAL WALK;So;0;ON; 8FB5;;;;N;;;;; 2FA2;KANGXI RADICAL CITY;So;0;ON; 9091;;;;N;;;;; 2FA3;KANGXI RADICAL WINE;So;0;ON; 9149;;;;N;;;;; 2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON; 91C6;;;;N;;;;; 2FA5;KANGXI RADICAL VILLAGE;So;0;ON; 91CC;;;;N;;;;; 2FA6;KANGXI RADICAL GOLD;So;0;ON; 91D1;;;;N;;;;; 2FA7;KANGXI RADICAL LONG;So;0;ON; 9577;;;;N;;;;; 2FA8;KANGXI RADICAL GATE;So;0;ON; 9580;;;;N;;;;; 2FA9;KANGXI RADICAL MOUND;So;0;ON; 961C;;;;N;;;;; 2FAA;KANGXI RADICAL SLAVE;So;0;ON; 96B6;;;;N;;;;; 2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON; 96B9;;;;N;;;;; 2FAC;KANGXI RADICAL RAIN;So;0;ON; 96E8;;;;N;;;;; 2FAD;KANGXI RADICAL BLUE;So;0;ON; 9751;;;;N;;;;; 2FAE;KANGXI RADICAL WRONG;So;0;ON; 975E;;;;N;;;;; 2FAF;KANGXI RADICAL FACE;So;0;ON; 9762;;;;N;;;;; 2FB0;KANGXI RADICAL LEATHER;So;0;ON; 9769;;;;N;;;;; 2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON; 97CB;;;;N;;;;; 2FB2;KANGXI RADICAL LEEK;So;0;ON; 97ED;;;;N;;;;; 2FB3;KANGXI RADICAL SOUND;So;0;ON; 97F3;;;;N;;;;; 2FB4;KANGXI RADICAL LEAF;So;0;ON; 9801;;;;N;;;;; 2FB5;KANGXI RADICAL WIND;So;0;ON; 98A8;;;;N;;;;; 2FB6;KANGXI RADICAL FLY;So;0;ON; 98DB;;;;N;;;;; 2FB7;KANGXI RADICAL EAT;So;0;ON; 98DF;;;;N;;;;; 2FB8;KANGXI RADICAL HEAD;So;0;ON; 9996;;;;N;;;;; 2FB9;KANGXI RADICAL FRAGRANT;So;0;ON; 9999;;;;N;;;;; 2FBA;KANGXI RADICAL HORSE;So;0;ON; 99AC;;;;N;;;;; 2FBB;KANGXI RADICAL BONE;So;0;ON; 9AA8;;;;N;;;;; 2FBC;KANGXI RADICAL TALL;So;0;ON; 9AD8;;;;N;;;;; 2FBD;KANGXI RADICAL HAIR;So;0;ON; 9ADF;;;;N;;;;; 2FBE;KANGXI RADICAL FIGHT;So;0;ON; 9B25;;;;N;;;;; 2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON; 9B2F;;;;N;;;;; 2FC0;KANGXI RADICAL CAULDRON;So;0;ON; 9B32;;;;N;;;;; 2FC1;KANGXI RADICAL GHOST;So;0;ON; 9B3C;;;;N;;;;; 2FC2;KANGXI RADICAL FISH;So;0;ON; 9B5A;;;;N;;;;; 2FC3;KANGXI RADICAL BIRD;So;0;ON; 9CE5;;;;N;;;;; 2FC4;KANGXI RADICAL SALT;So;0;ON; 9E75;;;;N;;;;; 2FC5;KANGXI RADICAL DEER;So;0;ON; 9E7F;;;;N;;;;; 2FC6;KANGXI RADICAL WHEAT;So;0;ON; 9EA5;;;;N;;;;; 2FC7;KANGXI RADICAL HEMP;So;0;ON; 9EBB;;;;N;;;;; 2FC8;KANGXI RADICAL YELLOW;So;0;ON; 9EC3;;;;N;;;;; 2FC9;KANGXI RADICAL MILLET;So;0;ON; 9ECD;;;;N;;;;; 2FCA;KANGXI RADICAL BLACK;So;0;ON; 9ED1;;;;N;;;;; 2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON; 9EF9;;;;N;;;;; 2FCC;KANGXI RADICAL FROG;So;0;ON; 9EFD;;;;N;;;;; 2FCD;KANGXI RADICAL TRIPOD;So;0;ON; 9F0E;;;;N;;;;; 2FCE;KANGXI RADICAL DRUM;So;0;ON; 9F13;;;;N;;;;; 2FCF;KANGXI RADICAL RAT;So;0;ON; 9F20;;;;N;;;;; 2FD0;KANGXI RADICAL NOSE;So;0;ON; 9F3B;;;;N;;;;; 2FD1;KANGXI RADICAL EVEN;So;0;ON; 9F4A;;;;N;;;;; 2FD2;KANGXI RADICAL TOOTH;So;0;ON; 9F52;;;;N;;;;; 2FD3;KANGXI RADICAL DRAGON;So;0;ON; 9F8D;;;;N;;;;; 2FD4;KANGXI RADICAL TURTLE;So;0;ON; 9F9C;;;;N;;;;; 2FD5;KANGXI RADICAL FLUTE;So;0;ON; 9FA0;;;;N;;;;; 2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;; 2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;; 2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;; 2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;; 2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;; 2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;; 2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;; 2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;; 2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;; 2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;; 2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;; 2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;; 3000;IDEOGRAPHIC SPACE;Zs;0;WS; 0020;;;;N;;;;; 3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;; 3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;; 3003;DITTO MARK;Po;0;ON;;;;;N;;;;; 3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;; 3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; 3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;; 3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;; 3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;; 3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;; 300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;; 300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;; 300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;; 300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;; 300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;; 300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;; 3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;; 3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;; 3012;POSTAL MARK;So;0;ON;;;;;N;;;;; 3013;GETA MARK;So;0;ON;;;;;N;;;;; 3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;; 3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;; 3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;; 3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;; 3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;; 3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;; 301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;; 301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;; 301C;WAVE DASH;Pd;0;ON;;;;;N;;;;; 301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;; 301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; 301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;; 3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;; 3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;; 3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;; 3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;; 3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;; 3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;; 3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;; 3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;; 3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;; 3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;; 302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;; 302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;; 302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;; 302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;; 302E;HANGUL SINGLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;; 302F;HANGUL DOUBLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;; 3030;WAVY DASH;Pd;0;ON;;;;;N;;;;; 3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;; 3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;; 3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;; 3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;; 3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;; 3036;CIRCLED POSTAL MARK;So;0;ON; 3012;;;;N;;;;; 3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;; 3038;HANGZHOU NUMERAL TEN;Nl;0;L; 5341;;;10;N;;;;; 3039;HANGZHOU NUMERAL TWENTY;Nl;0;L; 5344;;;20;N;;;;; 303A;HANGZHOU NUMERAL THIRTY;Nl;0;L; 5345;;;30;N;;;;; 303B;VERTICAL IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;; 303C;MASU MARK;Lo;0;L;;;;;N;;;;; 303D;PART ALTERNATION MARK;Po;0;ON;;;;;N;;;;; 303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;; 303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;; 3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; 3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;; 3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; 3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;; 3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; 3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;; 3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; 3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;; 3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; 304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;; 304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;; 304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;; 304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;; 304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;; 304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;; 3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;; 3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;; 3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;; 3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;; 3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;; 3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;; 3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;; 3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;; 3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;; 3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;; 305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;; 305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;; 305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;; 305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;; 305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;; 305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;; 3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;; 3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;; 3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;; 3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; 3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;; 3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;; 3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;; 3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;; 3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;; 3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;; 306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;; 306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;; 306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;; 306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;; 306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;; 306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;; 3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;; 3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;; 3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;; 3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;; 3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;; 3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;; 3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;; 3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;; 3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;; 3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;; 307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;; 307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;; 307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;; 307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;; 307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;; 307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;; 3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;; 3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;; 3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;; 3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; 3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;; 3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; 3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;; 3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; 3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;; 3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;; 308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;; 308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;; 308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;; 308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;; 308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; 308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;; 3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;; 3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;; 3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;; 3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;; 3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;; 3095;HIRAGANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; 3096;HIRAGANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; 3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;; 309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;; 309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON; 0020 3099;;;;N;;;;; 309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON; 0020 309A;;;;N;;;;; 309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;; 309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;; 309F;HIRAGANA DIGRAPH YORI;Lo;0;L; 3088 308A;;;;N;;;;; 30A0;KATAKANA-HIRAGANA DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;; 30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;; 30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;; 30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;; 30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;; 30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;; 30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;; 30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;; 30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;; 30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;; 30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;; 30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;; 30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;; 30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;; 30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;; 30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;; 30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;; 30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;; 30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;; 30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;; 30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;; 30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;; 30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;; 30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;; 30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;; 30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;; 30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;; 30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;; 30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;; 30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;; 30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;; 30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;; 30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;; 30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;; 30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;; 30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;; 30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;; 30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;; 30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;; 30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;; 30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;; 30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;; 30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;; 30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;; 30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;; 30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;; 30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;; 30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;; 30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;; 30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;; 30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;; 30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;; 30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;; 30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;; 30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;; 30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;; 30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;; 30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;; 30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;; 30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;; 30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;; 30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;; 30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;; 30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;; 30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;; 30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;; 30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;; 30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;; 30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;; 30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;; 30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;; 30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;; 30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;; 30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;; 30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;; 30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;; 30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;; 30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;; 30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;; 30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;; 30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;; 30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;; 30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;; 30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;; 30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;; 30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;; 30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;; 30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;; 30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;; 30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;; 30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;; 30FB;KATAKANA MIDDLE DOT;Pc;0;ON;;;;;N;;;;; 30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;; 30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;; 30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;; 30FF;KATAKANA DIGRAPH KOTO;Lo;0;L; 30B3 30C8;;;;N;;;;; 3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;; 3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;; 3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;; 3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;; 3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;; 310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;; 310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;; 310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;; 310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;; 310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;; 310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;; 3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;; 3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;; 3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;; 3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;; 3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;; 3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;; 3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;; 3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;; 3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;; 3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;; 311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;; 311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;; 311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;; 311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;; 311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;; 311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;; 3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;; 3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;; 3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;; 3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;; 3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;; 3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;; 3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;; 3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;; 3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;; 3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;; 312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;; 312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;; 312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;; 3131;HANGUL LETTER KIYEOK;Lo;0;L; 1100;;;;N;HANGUL LETTER GIYEOG;;;; 3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L; 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;; 3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;; 3134;HANGUL LETTER NIEUN;Lo;0;L; 1102;;;;N;;;;; 3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;; 3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;; 3137;HANGUL LETTER TIKEUT;Lo;0;L; 1103;;;;N;HANGUL LETTER DIGEUD;;;; 3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L; 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;; 3139;HANGUL LETTER RIEUL;Lo;0;L; 1105;;;;N;HANGUL LETTER LIEUL;;;; 313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;; 313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;; 313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;; 313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L; 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;; 313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;; 313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;; 3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;; 3141;HANGUL LETTER MIEUM;Lo;0;L; 1106;;;;N;;;;; 3142;HANGUL LETTER PIEUP;Lo;0;L; 1107;;;;N;HANGUL LETTER BIEUB;;;; 3143;HANGUL LETTER SSANGPIEUP;Lo;0;L; 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;; 3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L; 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;; 3145;HANGUL LETTER SIOS;Lo;0;L; 1109;;;;N;;;;; 3146;HANGUL LETTER SSANGSIOS;Lo;0;L; 110A;;;;N;HANGUL LETTER SSANG SIOS;;;; 3147;HANGUL LETTER IEUNG;Lo;0;L; 110B;;;;N;;;;; 3148;HANGUL LETTER CIEUC;Lo;0;L; 110C;;;;N;HANGUL LETTER JIEUJ;;;; 3149;HANGUL LETTER SSANGCIEUC;Lo;0;L; 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;; 314A;HANGUL LETTER CHIEUCH;Lo;0;L; 110E;;;;N;HANGUL LETTER CIEUC;;;; 314B;HANGUL LETTER KHIEUKH;Lo;0;L; 110F;;;;N;HANGUL LETTER KIYEOK;;;; 314C;HANGUL LETTER THIEUTH;Lo;0;L; 1110;;;;N;HANGUL LETTER TIEUT;;;; 314D;HANGUL LETTER PHIEUPH;Lo;0;L; 1111;;;;N;HANGUL LETTER PIEUP;;;; 314E;HANGUL LETTER HIEUH;Lo;0;L; 1112;;;;N;;;;; 314F;HANGUL LETTER A;Lo;0;L; 1161;;;;N;;;;; 3150;HANGUL LETTER AE;Lo;0;L; 1162;;;;N;;;;; 3151;HANGUL LETTER YA;Lo;0;L; 1163;;;;N;;;;; 3152;HANGUL LETTER YAE;Lo;0;L; 1164;;;;N;;;;; 3153;HANGUL LETTER EO;Lo;0;L; 1165;;;;N;;;;; 3154;HANGUL LETTER E;Lo;0;L; 1166;;;;N;;;;; 3155;HANGUL LETTER YEO;Lo;0;L; 1167;;;;N;;;;; 3156;HANGUL LETTER YE;Lo;0;L; 1168;;;;N;;;;; 3157;HANGUL LETTER O;Lo;0;L; 1169;;;;N;;;;; 3158;HANGUL LETTER WA;Lo;0;L; 116A;;;;N;;;;; 3159;HANGUL LETTER WAE;Lo;0;L; 116B;;;;N;;;;; 315A;HANGUL LETTER OE;Lo;0;L; 116C;;;;N;;;;; 315B;HANGUL LETTER YO;Lo;0;L; 116D;;;;N;;;;; 315C;HANGUL LETTER U;Lo;0;L; 116E;;;;N;;;;; 315D;HANGUL LETTER WEO;Lo;0;L; 116F;;;;N;;;;; 315E;HANGUL LETTER WE;Lo;0;L; 1170;;;;N;;;;; 315F;HANGUL LETTER WI;Lo;0;L; 1171;;;;N;;;;; 3160;HANGUL LETTER YU;Lo;0;L; 1172;;;;N;;;;; 3161;HANGUL LETTER EU;Lo;0;L; 1173;;;;N;;;;; 3162;HANGUL LETTER YI;Lo;0;L; 1174;;;;N;;;;; 3163;HANGUL LETTER I;Lo;0;L; 1175;;;;N;;;;; 3164;HANGUL FILLER;Lo;0;L; 1160;;;;N;HANGUL CAE OM;;;; 3165;HANGUL LETTER SSANGNIEUN;Lo;0;L; 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;; 3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L; 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;; 3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L; 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;; 3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L; 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;; 3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L; 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;; 316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L; 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;; 316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L; 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;; 316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L; 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;; 316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L; 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;; 316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L; 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;; 316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L; 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;; 3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L; 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;; 3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L; 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;; 3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L; 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;; 3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L; 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;; 3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L; 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;; 3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L; 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;; 3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L; 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;; 3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L; 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;; 3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L; 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;; 3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L; 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;; 317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L; 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;; 317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L; 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;; 317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L; 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;; 317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L; 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;; 317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L; 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;; 317F;HANGUL LETTER PANSIOS;Lo;0;L; 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;; 3180;HANGUL LETTER SSANGIEUNG;Lo;0;L; 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;; 3181;HANGUL LETTER YESIEUNG;Lo;0;L; 114C;;;;N;HANGUL LETTER NGIEUNG;;;; 3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L; 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;; 3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L; 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;; 3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L; 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;; 3185;HANGUL LETTER SSANGHIEUH;Lo;0;L; 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;; 3186;HANGUL LETTER YEORINHIEUH;Lo;0;L; 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;; 3187;HANGUL LETTER YO-YA;Lo;0;L; 1184;;;;N;HANGUL LETTER YOYA;;;; 3188;HANGUL LETTER YO-YAE;Lo;0;L; 1185;;;;N;HANGUL LETTER YOYAE;;;; 3189;HANGUL LETTER YO-I;Lo;0;L; 1188;;;;N;HANGUL LETTER YOI;;;; 318A;HANGUL LETTER YU-YEO;Lo;0;L; 1191;;;;N;HANGUL LETTER YUYEO;;;; 318B;HANGUL LETTER YU-YE;Lo;0;L; 1192;;;;N;HANGUL LETTER YUYE;;;; 318C;HANGUL LETTER YU-I;Lo;0;L; 1194;;;;N;HANGUL LETTER YUI;;;; 318D;HANGUL LETTER ARAEA;Lo;0;L; 119E;;;;N;HANGUL LETTER ALAE A;;;; 318E;HANGUL LETTER ARAEAE;Lo;0;L; 11A1;;;;N;HANGUL LETTER ALAE AE;;;; 3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;Kanbun Tateten;;; 3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;Kaeriten;;; 3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L; 4E00;;;1;N;KAERITEN ITI;Kaeriten;;; 3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L; 4E8C;;;2;N;KAERITEN NI;Kaeriten;;; 3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L; 4E09;;;3;N;KAERITEN SAN;Kaeriten;;; 3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L; 56DB;;;4;N;KAERITEN SI;Kaeriten;;; 3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L; 4E0A;;;;N;KAERITEN ZYOU;Kaeriten;;; 3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L; 4E2D;;;;N;KAERITEN TYUU;Kaeriten;;; 3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L; 4E0B;;;;N;KAERITEN GE;Kaeriten;;; 3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L; 7532;;;;N;KAERITEN KOU;Kaeriten;;; 319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L; 4E59;;;;N;KAERITEN OTU;Kaeriten;;; 319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L; 4E19;;;;N;KAERITEN HEI;Kaeriten;;; 319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L; 4E01;;;;N;KAERITEN TEI;Kaeriten;;; 319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L; 5929;;;;N;KAERITEN TEN;Kaeriten;;; 319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L; 5730;;;;N;KAERITEN TI;Kaeriten;;; 319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L; 4EBA;;;;N;KAERITEN ZIN;Kaeriten;;; 31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;; 31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;; 31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;; 31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;; 31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;; 31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;; 31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;; 31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;; 31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;; 31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;; 31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;; 31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;; 31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;; 31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;; 31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;; 31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;; 31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;; 31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;; 31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;; 31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;; 31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;; 31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;; 31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;; 31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;; 31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;; 31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;; 31F2;KATAKANA LETTER SMALL SU;Lo;0;L;;;;;N;;;;; 31F3;KATAKANA LETTER SMALL TO;Lo;0;L;;;;;N;;;;; 31F4;KATAKANA LETTER SMALL NU;Lo;0;L;;;;;N;;;;; 31F5;KATAKANA LETTER SMALL HA;Lo;0;L;;;;;N;;;;; 31F6;KATAKANA LETTER SMALL HI;Lo;0;L;;;;;N;;;;; 31F7;KATAKANA LETTER SMALL HU;Lo;0;L;;;;;N;;;;; 31F8;KATAKANA LETTER SMALL HE;Lo;0;L;;;;;N;;;;; 31F9;KATAKANA LETTER SMALL HO;Lo;0;L;;;;;N;;;;; 31FA;KATAKANA LETTER SMALL MU;Lo;0;L;;;;;N;;;;; 31FB;KATAKANA LETTER SMALL RA;Lo;0;L;;;;;N;;;;; 31FC;KATAKANA LETTER SMALL RI;Lo;0;L;;;;;N;;;;; 31FD;KATAKANA LETTER SMALL RU;Lo;0;L;;;;;N;;;;; 31FE;KATAKANA LETTER SMALL RE;Lo;0;L;;;;;N;;;;; 31FF;KATAKANA LETTER SMALL RO;Lo;0;L;;;;;N;;;;; 3200;PARENTHESIZED HANGUL KIYEOK;So;0;L; 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;; 3201;PARENTHESIZED HANGUL NIEUN;So;0;L; 0028 1102 0029;;;;N;;;;; 3202;PARENTHESIZED HANGUL TIKEUT;So;0;L; 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;; 3203;PARENTHESIZED HANGUL RIEUL;So;0;L; 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;; 3204;PARENTHESIZED HANGUL MIEUM;So;0;L; 0028 1106 0029;;;;N;;;;; 3205;PARENTHESIZED HANGUL PIEUP;So;0;L; 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;; 3206;PARENTHESIZED HANGUL SIOS;So;0;L; 0028 1109 0029;;;;N;;;;; 3207;PARENTHESIZED HANGUL IEUNG;So;0;L; 0028 110B 0029;;;;N;;;;; 3208;PARENTHESIZED HANGUL CIEUC;So;0;L; 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;; 3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L; 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;; 320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L; 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;; 320B;PARENTHESIZED HANGUL THIEUTH;So;0;L; 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;; 320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L; 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;; 320D;PARENTHESIZED HANGUL HIEUH;So;0;L; 0028 1112 0029;;;;N;;;;; 320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L; 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;; 320F;PARENTHESIZED HANGUL NIEUN A;So;0;L; 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;; 3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L; 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;; 3211;PARENTHESIZED HANGUL RIEUL A;So;0;L; 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;; 3212;PARENTHESIZED HANGUL MIEUM A;So;0;L; 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;; 3213;PARENTHESIZED HANGUL PIEUP A;So;0;L; 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;; 3214;PARENTHESIZED HANGUL SIOS A;So;0;L; 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;; 3215;PARENTHESIZED HANGUL IEUNG A;So;0;L; 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;; 3216;PARENTHESIZED HANGUL CIEUC A;So;0;L; 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;; 3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L; 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;; 3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L; 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;; 3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L; 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;; 321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L; 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;; 321B;PARENTHESIZED HANGUL HIEUH A;So;0;L; 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;; 321C;PARENTHESIZED HANGUL CIEUC U;So;0;L; 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;; 3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L; 0028 4E00 0029;;;1;N;;;;; 3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L; 0028 4E8C 0029;;;2;N;;;;; 3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L; 0028 4E09 0029;;;3;N;;;;; 3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L; 0028 56DB 0029;;;4;N;;;;; 3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L; 0028 4E94 0029;;;5;N;;;;; 3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L; 0028 516D 0029;;;6;N;;;;; 3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L; 0028 4E03 0029;;;7;N;;;;; 3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L; 0028 516B 0029;;;8;N;;;;; 3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L; 0028 4E5D 0029;;;9;N;;;;; 3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L; 0028 5341 0029;;;10;N;;;;; 322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L; 0028 6708 0029;;;;N;;;;; 322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L; 0028 706B 0029;;;;N;;;;; 322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L; 0028 6C34 0029;;;;N;;;;; 322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L; 0028 6728 0029;;;;N;;;;; 322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L; 0028 91D1 0029;;;;N;;;;; 322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L; 0028 571F 0029;;;;N;;;;; 3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L; 0028 65E5 0029;;;;N;;;;; 3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L; 0028 682A 0029;;;;N;;;;; 3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L; 0028 6709 0029;;;;N;;;;; 3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L; 0028 793E 0029;;;;N;;;;; 3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L; 0028 540D 0029;;;;N;;;;; 3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L; 0028 7279 0029;;;;N;;;;; 3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L; 0028 8CA1 0029;;;;N;;;;; 3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L; 0028 795D 0029;;;;N;;;;; 3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L; 0028 52B4 0029;;;;N;;;;; 3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L; 0028 4EE3 0029;;;;N;;;;; 323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L; 0028 547C 0029;;;;N;;;;; 323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L; 0028 5B66 0029;;;;N;;;;; 323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L; 0028 76E3 0029;;;;N;;;;; 323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L; 0028 4F01 0029;;;;N;;;;; 323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L; 0028 8CC7 0029;;;;N;;;;; 323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L; 0028 5354 0029;;;;N;;;;; 3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L; 0028 796D 0029;;;;N;;;;; 3241;PARENTHESIZED IDEOGRAPH REST;So;0;L; 0028 4F11 0029;;;;N;;;;; 3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L; 0028 81EA 0029;;;;N;;;;; 3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L; 0028 81F3 0029;;;;N;;;;; 3251;CIRCLED NUMBER TWENTY ONE;No;0;ON; 0032 0031;;;21;N;;;;; 3252;CIRCLED NUMBER TWENTY TWO;No;0;ON; 0032 0032;;;22;N;;;;; 3253;CIRCLED NUMBER TWENTY THREE;No;0;ON; 0032 0033;;;23;N;;;;; 3254;CIRCLED NUMBER TWENTY FOUR;No;0;ON; 0032 0034;;;24;N;;;;; 3255;CIRCLED NUMBER TWENTY FIVE;No;0;ON; 0032 0035;;;25;N;;;;; 3256;CIRCLED NUMBER TWENTY SIX;No;0;ON; 0032 0036;;;26;N;;;;; 3257;CIRCLED NUMBER TWENTY SEVEN;No;0;ON; 0032 0037;;;27;N;;;;; 3258;CIRCLED NUMBER TWENTY EIGHT;No;0;ON; 0032 0038;;;28;N;;;;; 3259;CIRCLED NUMBER TWENTY NINE;No;0;ON; 0032 0039;;;29;N;;;;; 325A;CIRCLED NUMBER THIRTY;No;0;ON; 0033 0030;;;30;N;;;;; 325B;CIRCLED NUMBER THIRTY ONE;No;0;ON; 0033 0031;;;31;N;;;;; 325C;CIRCLED NUMBER THIRTY TWO;No;0;ON; 0033 0032;;;32;N;;;;; 325D;CIRCLED NUMBER THIRTY THREE;No;0;ON; 0033 0033;;;33;N;;;;; 325E;CIRCLED NUMBER THIRTY FOUR;No;0;ON; 0033 0034;;;34;N;;;;; 325F;CIRCLED NUMBER THIRTY FIVE;No;0;ON; 0033 0035;;;35;N;;;;; 3260;CIRCLED HANGUL KIYEOK;So;0;L; 1100;;;;N;CIRCLED HANGUL GIYEOG;;;; 3261;CIRCLED HANGUL NIEUN;So;0;L; 1102;;;;N;;;;; 3262;CIRCLED HANGUL TIKEUT;So;0;L; 1103;;;;N;CIRCLED HANGUL DIGEUD;;;; 3263;CIRCLED HANGUL RIEUL;So;0;L; 1105;;;;N;CIRCLED HANGUL LIEUL;;;; 3264;CIRCLED HANGUL MIEUM;So;0;L; 1106;;;;N;;;;; 3265;CIRCLED HANGUL PIEUP;So;0;L; 1107;;;;N;CIRCLED HANGUL BIEUB;;;; 3266;CIRCLED HANGUL SIOS;So;0;L; 1109;;;;N;;;;; 3267;CIRCLED HANGUL IEUNG;So;0;L; 110B;;;;N;;;;; 3268;CIRCLED HANGUL CIEUC;So;0;L; 110C;;;;N;CIRCLED HANGUL JIEUJ;;;; 3269;CIRCLED HANGUL CHIEUCH;So;0;L; 110E;;;;N;CIRCLED HANGUL CIEUC;;;; 326A;CIRCLED HANGUL KHIEUKH;So;0;L; 110F;;;;N;CIRCLED HANGUL KIYEOK;;;; 326B;CIRCLED HANGUL THIEUTH;So;0;L; 1110;;;;N;CIRCLED HANGUL TIEUT;;;; 326C;CIRCLED HANGUL PHIEUPH;So;0;L; 1111;;;;N;CIRCLED HANGUL PIEUP;;;; 326D;CIRCLED HANGUL HIEUH;So;0;L; 1112;;;;N;;;;; 326E;CIRCLED HANGUL KIYEOK A;So;0;L; 1100 1161;;;;N;CIRCLED HANGUL GA;;;; 326F;CIRCLED HANGUL NIEUN A;So;0;L; 1102 1161;;;;N;CIRCLED HANGUL NA;;;; 3270;CIRCLED HANGUL TIKEUT A;So;0;L; 1103 1161;;;;N;CIRCLED HANGUL DA;;;; 3271;CIRCLED HANGUL RIEUL A;So;0;L; 1105 1161;;;;N;CIRCLED HANGUL LA;;;; 3272;CIRCLED HANGUL MIEUM A;So;0;L; 1106 1161;;;;N;CIRCLED HANGUL MA;;;; 3273;CIRCLED HANGUL PIEUP A;So;0;L; 1107 1161;;;;N;CIRCLED HANGUL BA;;;; 3274;CIRCLED HANGUL SIOS A;So;0;L; 1109 1161;;;;N;CIRCLED HANGUL SA;;;; 3275;CIRCLED HANGUL IEUNG A;So;0;L; 110B 1161;;;;N;CIRCLED HANGUL A;;;; 3276;CIRCLED HANGUL CIEUC A;So;0;L; 110C 1161;;;;N;CIRCLED HANGUL JA;;;; 3277;CIRCLED HANGUL CHIEUCH A;So;0;L; 110E 1161;;;;N;CIRCLED HANGUL CA;;;; 3278;CIRCLED HANGUL KHIEUKH A;So;0;L; 110F 1161;;;;N;CIRCLED HANGUL KA;;;; 3279;CIRCLED HANGUL THIEUTH A;So;0;L; 1110 1161;;;;N;CIRCLED HANGUL TA;;;; 327A;CIRCLED HANGUL PHIEUPH A;So;0;L; 1111 1161;;;;N;CIRCLED HANGUL PA;;;; 327B;CIRCLED HANGUL HIEUH A;So;0;L; 1112 1161;;;;N;CIRCLED HANGUL HA;;;; 327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;; 3280;CIRCLED IDEOGRAPH ONE;No;0;L; 4E00;;;1;N;;;;; 3281;CIRCLED IDEOGRAPH TWO;No;0;L; 4E8C;;;2;N;;;;; 3282;CIRCLED IDEOGRAPH THREE;No;0;L; 4E09;;;3;N;;;;; 3283;CIRCLED IDEOGRAPH FOUR;No;0;L; 56DB;;;4;N;;;;; 3284;CIRCLED IDEOGRAPH FIVE;No;0;L; 4E94;;;5;N;;;;; 3285;CIRCLED IDEOGRAPH SIX;No;0;L; 516D;;;6;N;;;;; 3286;CIRCLED IDEOGRAPH SEVEN;No;0;L; 4E03;;;7;N;;;;; 3287;CIRCLED IDEOGRAPH EIGHT;No;0;L; 516B;;;8;N;;;;; 3288;CIRCLED IDEOGRAPH NINE;No;0;L; 4E5D;;;9;N;;;;; 3289;CIRCLED IDEOGRAPH TEN;No;0;L; 5341;;;10;N;;;;; 328A;CIRCLED IDEOGRAPH MOON;So;0;L; 6708;;;;N;;;;; 328B;CIRCLED IDEOGRAPH FIRE;So;0;L; 706B;;;;N;;;;; 328C;CIRCLED IDEOGRAPH WATER;So;0;L; 6C34;;;;N;;;;; 328D;CIRCLED IDEOGRAPH WOOD;So;0;L; 6728;;;;N;;;;; 328E;CIRCLED IDEOGRAPH METAL;So;0;L; 91D1;;;;N;;;;; 328F;CIRCLED IDEOGRAPH EARTH;So;0;L; 571F;;;;N;;;;; 3290;CIRCLED IDEOGRAPH SUN;So;0;L; 65E5;;;;N;;;;; 3291;CIRCLED IDEOGRAPH STOCK;So;0;L; 682A;;;;N;;;;; 3292;CIRCLED IDEOGRAPH HAVE;So;0;L; 6709;;;;N;;;;; 3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L; 793E;;;;N;;;;; 3294;CIRCLED IDEOGRAPH NAME;So;0;L; 540D;;;;N;;;;; 3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L; 7279;;;;N;;;;; 3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L; 8CA1;;;;N;;;;; 3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L; 795D;;;;N;;;;; 3298;CIRCLED IDEOGRAPH LABOR;So;0;L; 52B4;;;;N;;;;; 3299;CIRCLED IDEOGRAPH SECRET;So;0;L; 79D8;;;;N;;;;; 329A;CIRCLED IDEOGRAPH MALE;So;0;L; 7537;;;;N;;;;; 329B;CIRCLED IDEOGRAPH FEMALE;So;0;L; 5973;;;;N;;;;; 329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L; 9069;;;;N;;;;; 329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L; 512A;;;;N;;;;; 329E;CIRCLED IDEOGRAPH PRINT;So;0;L; 5370;;;;N;;;;; 329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L; 6CE8;;;;N;;;;; 32A0;CIRCLED IDEOGRAPH ITEM;So;0;L; 9805;;;;N;;;;; 32A1;CIRCLED IDEOGRAPH REST;So;0;L; 4F11;;;;N;;;;; 32A2;CIRCLED IDEOGRAPH COPY;So;0;L; 5199;;;;N;;;;; 32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L; 6B63;;;;N;;;;; 32A4;CIRCLED IDEOGRAPH HIGH;So;0;L; 4E0A;;;;N;;;;; 32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L; 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;; 32A6;CIRCLED IDEOGRAPH LOW;So;0;L; 4E0B;;;;N;;;;; 32A7;CIRCLED IDEOGRAPH LEFT;So;0;L; 5DE6;;;;N;;;;; 32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L; 53F3;;;;N;;;;; 32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L; 533B;;;;N;;;;; 32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L; 5B97;;;;N;;;;; 32AB;CIRCLED IDEOGRAPH STUDY;So;0;L; 5B66;;;;N;;;;; 32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L; 76E3;;;;N;;;;; 32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L; 4F01;;;;N;;;;; 32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L; 8CC7;;;;N;;;;; 32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L; 5354;;;;N;;;;; 32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L; 591C;;;;N;;;;; 32B1;CIRCLED NUMBER THIRTY SIX;No;0;ON; 0033 0036;;;36;N;;;;; 32B2;CIRCLED NUMBER THIRTY SEVEN;No;0;ON; 0033 0037;;;37;N;;;;; 32B3;CIRCLED NUMBER THIRTY EIGHT;No;0;ON; 0033 0038;;;38;N;;;;; 32B4;CIRCLED NUMBER THIRTY NINE;No;0;ON; 0033 0039;;;39;N;;;;; 32B5;CIRCLED NUMBER FORTY;No;0;ON; 0034 0030;;;40;N;;;;; 32B6;CIRCLED NUMBER FORTY ONE;No;0;ON; 0034 0031;;;41;N;;;;; 32B7;CIRCLED NUMBER FORTY TWO;No;0;ON; 0034 0032;;;42;N;;;;; 32B8;CIRCLED NUMBER FORTY THREE;No;0;ON; 0034 0033;;;43;N;;;;; 32B9;CIRCLED NUMBER FORTY FOUR;No;0;ON; 0034 0034;;;44;N;;;;; 32BA;CIRCLED NUMBER FORTY FIVE;No;0;ON; 0034 0035;;;45;N;;;;; 32BB;CIRCLED NUMBER FORTY SIX;No;0;ON; 0034 0036;;;46;N;;;;; 32BC;CIRCLED NUMBER FORTY SEVEN;No;0;ON; 0034 0037;;;47;N;;;;; 32BD;CIRCLED NUMBER FORTY EIGHT;No;0;ON; 0034 0038;;;48;N;;;;; 32BE;CIRCLED NUMBER FORTY NINE;No;0;ON; 0034 0039;;;49;N;;;;; 32BF;CIRCLED NUMBER FIFTY;No;0;ON; 0035 0030;;;50;N;;;;; 32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L; 0031 6708;;;;N;;;;; 32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L; 0032 6708;;;;N;;;;; 32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L; 0033 6708;;;;N;;;;; 32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L; 0034 6708;;;;N;;;;; 32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L; 0035 6708;;;;N;;;;; 32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L; 0036 6708;;;;N;;;;; 32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L; 0037 6708;;;;N;;;;; 32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L; 0038 6708;;;;N;;;;; 32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L; 0039 6708;;;;N;;;;; 32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L; 0031 0030 6708;;;;N;;;;; 32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L; 0031 0031 6708;;;;N;;;;; 32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L; 0031 0032 6708;;;;N;;;;; 32D0;CIRCLED KATAKANA A;So;0;L; 30A2;;;;N;;;;; 32D1;CIRCLED KATAKANA I;So;0;L; 30A4;;;;N;;;;; 32D2;CIRCLED KATAKANA U;So;0;L; 30A6;;;;N;;;;; 32D3;CIRCLED KATAKANA E;So;0;L; 30A8;;;;N;;;;; 32D4;CIRCLED KATAKANA O;So;0;L; 30AA;;;;N;;;;; 32D5;CIRCLED KATAKANA KA;So;0;L; 30AB;;;;N;;;;; 32D6;CIRCLED KATAKANA KI;So;0;L; 30AD;;;;N;;;;; 32D7;CIRCLED KATAKANA KU;So;0;L; 30AF;;;;N;;;;; 32D8;CIRCLED KATAKANA KE;So;0;L; 30B1;;;;N;;;;; 32D9;CIRCLED KATAKANA KO;So;0;L; 30B3;;;;N;;;;; 32DA;CIRCLED KATAKANA SA;So;0;L; 30B5;;;;N;;;;; 32DB;CIRCLED KATAKANA SI;So;0;L; 30B7;;;;N;;;;; 32DC;CIRCLED KATAKANA SU;So;0;L; 30B9;;;;N;;;;; 32DD;CIRCLED KATAKANA SE;So;0;L; 30BB;;;;N;;;;; 32DE;CIRCLED KATAKANA SO;So;0;L; 30BD;;;;N;;;;; 32DF;CIRCLED KATAKANA TA;So;0;L; 30BF;;;;N;;;;; 32E0;CIRCLED KATAKANA TI;So;0;L; 30C1;;;;N;;;;; 32E1;CIRCLED KATAKANA TU;So;0;L; 30C4;;;;N;;;;; 32E2;CIRCLED KATAKANA TE;So;0;L; 30C6;;;;N;;;;; 32E3;CIRCLED KATAKANA TO;So;0;L; 30C8;;;;N;;;;; 32E4;CIRCLED KATAKANA NA;So;0;L; 30CA;;;;N;;;;; 32E5;CIRCLED KATAKANA NI;So;0;L; 30CB;;;;N;;;;; 32E6;CIRCLED KATAKANA NU;So;0;L; 30CC;;;;N;;;;; 32E7;CIRCLED KATAKANA NE;So;0;L; 30CD;;;;N;;;;; 32E8;CIRCLED KATAKANA NO;So;0;L; 30CE;;;;N;;;;; 32E9;CIRCLED KATAKANA HA;So;0;L; 30CF;;;;N;;;;; 32EA;CIRCLED KATAKANA HI;So;0;L; 30D2;;;;N;;;;; 32EB;CIRCLED KATAKANA HU;So;0;L; 30D5;;;;N;;;;; 32EC;CIRCLED KATAKANA HE;So;0;L; 30D8;;;;N;;;;; 32ED;CIRCLED KATAKANA HO;So;0;L; 30DB;;;;N;;;;; 32EE;CIRCLED KATAKANA MA;So;0;L; 30DE;;;;N;;;;; 32EF;CIRCLED KATAKANA MI;So;0;L; 30DF;;;;N;;;;; 32F0;CIRCLED KATAKANA MU;So;0;L; 30E0;;;;N;;;;; 32F1;CIRCLED KATAKANA ME;So;0;L; 30E1;;;;N;;;;; 32F2;CIRCLED KATAKANA MO;So;0;L; 30E2;;;;N;;;;; 32F3;CIRCLED KATAKANA YA;So;0;L; 30E4;;;;N;;;;; 32F4;CIRCLED KATAKANA YU;So;0;L; 30E6;;;;N;;;;; 32F5;CIRCLED KATAKANA YO;So;0;L; 30E8;;;;N;;;;; 32F6;CIRCLED KATAKANA RA;So;0;L; 30E9;;;;N;;;;; 32F7;CIRCLED KATAKANA RI;So;0;L; 30EA;;;;N;;;;; 32F8;CIRCLED KATAKANA RU;So;0;L; 30EB;;;;N;;;;; 32F9;CIRCLED KATAKANA RE;So;0;L; 30EC;;;;N;;;;; 32FA;CIRCLED KATAKANA RO;So;0;L; 30ED;;;;N;;;;; 32FB;CIRCLED KATAKANA WA;So;0;L; 30EF;;;;N;;;;; 32FC;CIRCLED KATAKANA WI;So;0;L; 30F0;;;;N;;;;; 32FD;CIRCLED KATAKANA WE;So;0;L; 30F1;;;;N;;;;; 32FE;CIRCLED KATAKANA WO;So;0;L; 30F2;;;;N;;;;; 3300;SQUARE APAATO;So;0;L; 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;; 3301;SQUARE ARUHUA;So;0;L; 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;; 3302;SQUARE ANPEA;So;0;L; 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;; 3303;SQUARE AARU;So;0;L; 30A2 30FC 30EB;;;;N;SQUARED AARU;;;; 3304;SQUARE ININGU;So;0;L; 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;; 3305;SQUARE INTI;So;0;L; 30A4 30F3 30C1;;;;N;SQUARED INTI;;;; 3306;SQUARE UON;So;0;L; 30A6 30A9 30F3;;;;N;SQUARED UON;;;; 3307;SQUARE ESUKUUDO;So;0;L; 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;; 3308;SQUARE EEKAA;So;0;L; 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;; 3309;SQUARE ONSU;So;0;L; 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;; 330A;SQUARE OOMU;So;0;L; 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;; 330B;SQUARE KAIRI;So;0;L; 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;; 330C;SQUARE KARATTO;So;0;L; 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;; 330D;SQUARE KARORII;So;0;L; 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;; 330E;SQUARE GARON;So;0;L; 30AC 30ED 30F3;;;;N;SQUARED GARON;;;; 330F;SQUARE GANMA;So;0;L; 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;; 3310;SQUARE GIGA;So;0;L; 30AE 30AC;;;;N;SQUARED GIGA;;;; 3311;SQUARE GINII;So;0;L; 30AE 30CB 30FC;;;;N;SQUARED GINII;;;; 3312;SQUARE KYURII;So;0;L; 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;; 3313;SQUARE GIRUDAA;So;0;L; 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;; 3314;SQUARE KIRO;So;0;L; 30AD 30ED;;;;N;SQUARED KIRO;;;; 3315;SQUARE KIROGURAMU;So;0;L; 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;; 3316;SQUARE KIROMEETORU;So;0;L; 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;; 3317;SQUARE KIROWATTO;So;0;L; 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;; 3318;SQUARE GURAMU;So;0;L; 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;; 3319;SQUARE GURAMUTON;So;0;L; 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;; 331A;SQUARE KURUZEIRO;So;0;L; 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;; 331B;SQUARE KUROONE;So;0;L; 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;; 331C;SQUARE KEESU;So;0;L; 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;; 331D;SQUARE KORUNA;So;0;L; 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;; 331E;SQUARE KOOPO;So;0;L; 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;; 331F;SQUARE SAIKURU;So;0;L; 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;; 3320;SQUARE SANTIIMU;So;0;L; 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;; 3321;SQUARE SIRINGU;So;0;L; 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;; 3322;SQUARE SENTI;So;0;L; 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;; 3323;SQUARE SENTO;So;0;L; 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;; 3324;SQUARE DAASU;So;0;L; 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;; 3325;SQUARE DESI;So;0;L; 30C7 30B7;;;;N;SQUARED DESI;;;; 3326;SQUARE DORU;So;0;L; 30C9 30EB;;;;N;SQUARED DORU;;;; 3327;SQUARE TON;So;0;L; 30C8 30F3;;;;N;SQUARED TON;;;; 3328;SQUARE NANO;So;0;L; 30CA 30CE;;;;N;SQUARED NANO;;;; 3329;SQUARE NOTTO;So;0;L; 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;; 332A;SQUARE HAITU;So;0;L; 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;; 332B;SQUARE PAASENTO;So;0;L; 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;; 332C;SQUARE PAATU;So;0;L; 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;; 332D;SQUARE BAARERU;So;0;L; 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;; 332E;SQUARE PIASUTORU;So;0;L; 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;; 332F;SQUARE PIKURU;So;0;L; 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;; 3330;SQUARE PIKO;So;0;L; 30D4 30B3;;;;N;SQUARED PIKO;;;; 3331;SQUARE BIRU;So;0;L; 30D3 30EB;;;;N;SQUARED BIRU;;;; 3332;SQUARE HUARADDO;So;0;L; 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;; 3333;SQUARE HUIITO;So;0;L; 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;; 3334;SQUARE BUSSYERU;So;0;L; 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;; 3335;SQUARE HURAN;So;0;L; 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;; 3336;SQUARE HEKUTAARU;So;0;L; 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;; 3337;SQUARE PESO;So;0;L; 30DA 30BD;;;;N;SQUARED PESO;;;; 3338;SQUARE PENIHI;So;0;L; 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;; 3339;SQUARE HERUTU;So;0;L; 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;; 333A;SQUARE PENSU;So;0;L; 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;; 333B;SQUARE PEEZI;So;0;L; 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;; 333C;SQUARE BEETA;So;0;L; 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;; 333D;SQUARE POINTO;So;0;L; 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;; 333E;SQUARE BORUTO;So;0;L; 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;; 333F;SQUARE HON;So;0;L; 30DB 30F3;;;;N;SQUARED HON;;;; 3340;SQUARE PONDO;So;0;L; 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;; 3341;SQUARE HOORU;So;0;L; 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;; 3342;SQUARE HOON;So;0;L; 30DB 30FC 30F3;;;;N;SQUARED HOON;;;; 3343;SQUARE MAIKURO;So;0;L; 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;; 3344;SQUARE MAIRU;So;0;L; 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;; 3345;SQUARE MAHHA;So;0;L; 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;; 3346;SQUARE MARUKU;So;0;L; 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;; 3347;SQUARE MANSYON;So;0;L; 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;; 3348;SQUARE MIKURON;So;0;L; 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;; 3349;SQUARE MIRI;So;0;L; 30DF 30EA;;;;N;SQUARED MIRI;;;; 334A;SQUARE MIRIBAARU;So;0;L; 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;; 334B;SQUARE MEGA;So;0;L; 30E1 30AC;;;;N;SQUARED MEGA;;;; 334C;SQUARE MEGATON;So;0;L; 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;; 334D;SQUARE MEETORU;So;0;L; 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;; 334E;SQUARE YAADO;So;0;L; 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;; 334F;SQUARE YAARU;So;0;L; 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;; 3350;SQUARE YUAN;So;0;L; 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;; 3351;SQUARE RITTORU;So;0;L; 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;; 3352;SQUARE RIRA;So;0;L; 30EA 30E9;;;;N;SQUARED RIRA;;;; 3353;SQUARE RUPII;So;0;L; 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;; 3354;SQUARE RUUBURU;So;0;L; 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;; 3355;SQUARE REMU;So;0;L; 30EC 30E0;;;;N;SQUARED REMU;;;; 3356;SQUARE RENTOGEN;So;0;L; 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;; 3357;SQUARE WATTO;So;0;L; 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;; 3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L; 0030 70B9;;;;N;;;;; 3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L; 0031 70B9;;;;N;;;;; 335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L; 0032 70B9;;;;N;;;;; 335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L; 0033 70B9;;;;N;;;;; 335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L; 0034 70B9;;;;N;;;;; 335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L; 0035 70B9;;;;N;;;;; 335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L; 0036 70B9;;;;N;;;;; 335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L; 0037 70B9;;;;N;;;;; 3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L; 0038 70B9;;;;N;;;;; 3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L; 0039 70B9;;;;N;;;;; 3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L; 0031 0030 70B9;;;;N;;;;; 3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L; 0031 0031 70B9;;;;N;;;;; 3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L; 0031 0032 70B9;;;;N;;;;; 3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L; 0031 0033 70B9;;;;N;;;;; 3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L; 0031 0034 70B9;;;;N;;;;; 3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L; 0031 0035 70B9;;;;N;;;;; 3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L; 0031 0036 70B9;;;;N;;;;; 3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L; 0031 0037 70B9;;;;N;;;;; 336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L; 0031 0038 70B9;;;;N;;;;; 336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L; 0031 0039 70B9;;;;N;;;;; 336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L; 0032 0030 70B9;;;;N;;;;; 336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L; 0032 0031 70B9;;;;N;;;;; 336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L; 0032 0032 70B9;;;;N;;;;; 336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L; 0032 0033 70B9;;;;N;;;;; 3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L; 0032 0034 70B9;;;;N;;;;; 3371;SQUARE HPA;So;0;L; 0068 0050 0061;;;;N;;;;; 3372;SQUARE DA;So;0;L; 0064 0061;;;;N;;;;; 3373;SQUARE AU;So;0;L; 0041 0055;;;;N;;;;; 3374;SQUARE BAR;So;0;L; 0062 0061 0072;;;;N;;;;; 3375;SQUARE OV;So;0;L; 006F 0056;;;;N;;;;; 3376;SQUARE PC;So;0;L; 0070 0063;;;;N;;;;; 337B;SQUARE ERA NAME HEISEI;So;0;L; 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;; 337C;SQUARE ERA NAME SYOUWA;So;0;L; 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;; 337D;SQUARE ERA NAME TAISYOU;So;0;L; 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;; 337E;SQUARE ERA NAME MEIZI;So;0;L; 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;; 337F;SQUARE CORPORATION;So;0;L; 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;; 3380;SQUARE PA AMPS;So;0;L; 0070 0041;;;;N;SQUARED PA AMPS;;;; 3381;SQUARE NA;So;0;L; 006E 0041;;;;N;SQUARED NA;;;; 3382;SQUARE MU A;So;0;L; 03BC 0041;;;;N;SQUARED MU A;;;; 3383;SQUARE MA;So;0;L; 006D 0041;;;;N;SQUARED MA;;;; 3384;SQUARE KA;So;0;L; 006B 0041;;;;N;SQUARED KA;;;; 3385;SQUARE KB;So;0;L; 004B 0042;;;;N;SQUARED KB;;;; 3386;SQUARE MB;So;0;L; 004D 0042;;;;N;SQUARED MB;;;; 3387;SQUARE GB;So;0;L; 0047 0042;;;;N;SQUARED GB;;;; 3388;SQUARE CAL;So;0;L; 0063 0061 006C;;;;N;SQUARED CAL;;;; 3389;SQUARE KCAL;So;0;L; 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;; 338A;SQUARE PF;So;0;L; 0070 0046;;;;N;SQUARED PF;;;; 338B;SQUARE NF;So;0;L; 006E 0046;;;;N;SQUARED NF;;;; 338C;SQUARE MU F;So;0;L; 03BC 0046;;;;N;SQUARED MU F;;;; 338D;SQUARE MU G;So;0;L; 03BC 0067;;;;N;SQUARED MU G;;;; 338E;SQUARE MG;So;0;L; 006D 0067;;;;N;SQUARED MG;;;; 338F;SQUARE KG;So;0;L; 006B 0067;;;;N;SQUARED KG;;;; 3390;SQUARE HZ;So;0;L; 0048 007A;;;;N;SQUARED HZ;;;; 3391;SQUARE KHZ;So;0;L; 006B 0048 007A;;;;N;SQUARED KHZ;;;; 3392;SQUARE MHZ;So;0;L; 004D 0048 007A;;;;N;SQUARED MHZ;;;; 3393;SQUARE GHZ;So;0;L; 0047 0048 007A;;;;N;SQUARED GHZ;;;; 3394;SQUARE THZ;So;0;L; 0054 0048 007A;;;;N;SQUARED THZ;;;; 3395;SQUARE MU L;So;0;L; 03BC 2113;;;;N;SQUARED MU L;;;; 3396;SQUARE ML;So;0;L; 006D 2113;;;;N;SQUARED ML;;;; 3397;SQUARE DL;So;0;L; 0064 2113;;;;N;SQUARED DL;;;; 3398;SQUARE KL;So;0;L; 006B 2113;;;;N;SQUARED KL;;;; 3399;SQUARE FM;So;0;L; 0066 006D;;;;N;SQUARED FM;;;; 339A;SQUARE NM;So;0;L; 006E 006D;;;;N;SQUARED NM;;;; 339B;SQUARE MU M;So;0;L; 03BC 006D;;;;N;SQUARED MU M;;;; 339C;SQUARE MM;So;0;L; 006D 006D;;;;N;SQUARED MM;;;; 339D;SQUARE CM;So;0;L; 0063 006D;;;;N;SQUARED CM;;;; 339E;SQUARE KM;So;0;L; 006B 006D;;;;N;SQUARED KM;;;; 339F;SQUARE MM SQUARED;So;0;L; 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;; 33A0;SQUARE CM SQUARED;So;0;L; 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;; 33A1;SQUARE M SQUARED;So;0;L; 006D 00B2;;;;N;SQUARED M SQUARED;;;; 33A2;SQUARE KM SQUARED;So;0;L; 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;; 33A3;SQUARE MM CUBED;So;0;L; 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;; 33A4;SQUARE CM CUBED;So;0;L; 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;; 33A5;SQUARE M CUBED;So;0;L; 006D 00B3;;;;N;SQUARED M CUBED;;;; 33A6;SQUARE KM CUBED;So;0;L; 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;; 33A7;SQUARE M OVER S;So;0;L; 006D 2215 0073;;;;N;SQUARED M OVER S;;;; 33A8;SQUARE M OVER S SQUARED;So;0;L; 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;; 33A9;SQUARE PA;So;0;L; 0050 0061;;;;N;SQUARED PA;;;; 33AA;SQUARE KPA;So;0;L; 006B 0050 0061;;;;N;SQUARED KPA;;;; 33AB;SQUARE MPA;So;0;L; 004D 0050 0061;;;;N;SQUARED MPA;;;; 33AC;SQUARE GPA;So;0;L; 0047 0050 0061;;;;N;SQUARED GPA;;;; 33AD;SQUARE RAD;So;0;L; 0072 0061 0064;;;;N;SQUARED RAD;;;; 33AE;SQUARE RAD OVER S;So;0;L; 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;; 33AF;SQUARE RAD OVER S SQUARED;So;0;L; 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;; 33B0;SQUARE PS;So;0;L; 0070 0073;;;;N;SQUARED PS;;;; 33B1;SQUARE NS;So;0;L; 006E 0073;;;;N;SQUARED NS;;;; 33B2;SQUARE MU S;So;0;L; 03BC 0073;;;;N;SQUARED MU S;;;; 33B3;SQUARE MS;So;0;L; 006D 0073;;;;N;SQUARED MS;;;; 33B4;SQUARE PV;So;0;L; 0070 0056;;;;N;SQUARED PV;;;; 33B5;SQUARE NV;So;0;L; 006E 0056;;;;N;SQUARED NV;;;; 33B6;SQUARE MU V;So;0;L; 03BC 0056;;;;N;SQUARED MU V;;;; 33B7;SQUARE MV;So;0;L; 006D 0056;;;;N;SQUARED MV;;;; 33B8;SQUARE KV;So;0;L; 006B 0056;;;;N;SQUARED KV;;;; 33B9;SQUARE MV MEGA;So;0;L; 004D 0056;;;;N;SQUARED MV MEGA;;;; 33BA;SQUARE PW;So;0;L; 0070 0057;;;;N;SQUARED PW;;;; 33BB;SQUARE NW;So;0;L; 006E 0057;;;;N;SQUARED NW;;;; 33BC;SQUARE MU W;So;0;L; 03BC 0057;;;;N;SQUARED MU W;;;; 33BD;SQUARE MW;So;0;L; 006D 0057;;;;N;SQUARED MW;;;; 33BE;SQUARE KW;So;0;L; 006B 0057;;;;N;SQUARED KW;;;; 33BF;SQUARE MW MEGA;So;0;L; 004D 0057;;;;N;SQUARED MW MEGA;;;; 33C0;SQUARE K OHM;So;0;L; 006B 03A9;;;;N;SQUARED K OHM;;;; 33C1;SQUARE M OHM;So;0;L; 004D 03A9;;;;N;SQUARED M OHM;;;; 33C2;SQUARE AM;So;0;L; 0061 002E 006D 002E;;;;N;SQUARED AM;;;; 33C3;SQUARE BQ;So;0;L; 0042 0071;;;;N;SQUARED BQ;;;; 33C4;SQUARE CC;So;0;L; 0063 0063;;;;N;SQUARED CC;;;; 33C5;SQUARE CD;So;0;L; 0063 0064;;;;N;SQUARED CD;;;; 33C6;SQUARE C OVER KG;So;0;L; 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;; 33C7;SQUARE CO;So;0;L; 0043 006F 002E;;;;N;SQUARED CO;;;; 33C8;SQUARE DB;So;0;L; 0064 0042;;;;N;SQUARED DB;;;; 33C9;SQUARE GY;So;0;L; 0047 0079;;;;N;SQUARED GY;;;; 33CA;SQUARE HA;So;0;L; 0068 0061;;;;N;SQUARED HA;;;; 33CB;SQUARE HP;So;0;L; 0048 0050;;;;N;SQUARED HP;;;; 33CC;SQUARE IN;So;0;L; 0069 006E;;;;N;SQUARED IN;;;; 33CD;SQUARE KK;So;0;L; 004B 004B;;;;N;SQUARED KK;;;; 33CE;SQUARE KM CAPITAL;So;0;L; 004B 004D;;;;N;SQUARED KM CAPITAL;;;; 33CF;SQUARE KT;So;0;L; 006B 0074;;;;N;SQUARED KT;;;; 33D0;SQUARE LM;So;0;L; 006C 006D;;;;N;SQUARED LM;;;; 33D1;SQUARE LN;So;0;L; 006C 006E;;;;N;SQUARED LN;;;; 33D2;SQUARE LOG;So;0;L; 006C 006F 0067;;;;N;SQUARED LOG;;;; 33D3;SQUARE LX;So;0;L; 006C 0078;;;;N;SQUARED LX;;;; 33D4;SQUARE MB SMALL;So;0;L; 006D 0062;;;;N;SQUARED MB SMALL;;;; 33D5;SQUARE MIL;So;0;L; 006D 0069 006C;;;;N;SQUARED MIL;;;; 33D6;SQUARE MOL;So;0;L; 006D 006F 006C;;;;N;SQUARED MOL;;;; 33D7;SQUARE PH;So;0;L; 0050 0048;;;;N;SQUARED PH;;;; 33D8;SQUARE PM;So;0;L; 0070 002E 006D 002E;;;;N;SQUARED PM;;;; 33D9;SQUARE PPM;So;0;L; 0050 0050 004D;;;;N;SQUARED PPM;;;; 33DA;SQUARE PR;So;0;L; 0050 0052;;;;N;SQUARED PR;;;; 33DB;SQUARE SR;So;0;L; 0073 0072;;;;N;SQUARED SR;;;; 33DC;SQUARE SV;So;0;L; 0053 0076;;;;N;SQUARED SV;;;; 33DD;SQUARE WB;So;0;L; 0057 0062;;;;N;SQUARED WB;;;; 33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L; 0031 65E5;;;;N;;;;; 33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L; 0032 65E5;;;;N;;;;; 33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L; 0033 65E5;;;;N;;;;; 33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L; 0034 65E5;;;;N;;;;; 33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L; 0035 65E5;;;;N;;;;; 33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L; 0036 65E5;;;;N;;;;; 33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L; 0037 65E5;;;;N;;;;; 33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L; 0038 65E5;;;;N;;;;; 33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L; 0039 65E5;;;;N;;;;; 33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L; 0031 0030 65E5;;;;N;;;;; 33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L; 0031 0031 65E5;;;;N;;;;; 33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L; 0031 0032 65E5;;;;N;;;;; 33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L; 0031 0033 65E5;;;;N;;;;; 33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L; 0031 0034 65E5;;;;N;;;;; 33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L; 0031 0035 65E5;;;;N;;;;; 33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L; 0031 0036 65E5;;;;N;;;;; 33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L; 0031 0037 65E5;;;;N;;;;; 33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L; 0031 0038 65E5;;;;N;;;;; 33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L; 0031 0039 65E5;;;;N;;;;; 33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L; 0032 0030 65E5;;;;N;;;;; 33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L; 0032 0031 65E5;;;;N;;;;; 33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L; 0032 0032 65E5;;;;N;;;;; 33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L; 0032 0033 65E5;;;;N;;;;; 33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L; 0032 0034 65E5;;;;N;;;;; 33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L; 0032 0035 65E5;;;;N;;;;; 33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L; 0032 0036 65E5;;;;N;;;;; 33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L; 0032 0037 65E5;;;;N;;;;; 33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L; 0032 0038 65E5;;;;N;;;;; 33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L; 0032 0039 65E5;;;;N;;;;; 33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L; 0033 0030 65E5;;;;N;;;;; 33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L; 0033 0031 65E5;;;;N;;;;; 3400;;Lo;0;L;;;;;N;;;;; 4DB5;;Lo;0;L;;;;;N;;;;; 4E00;;Lo;0;L;;;;;N;;;;; 9FA5;;Lo;0;L;;;;;N;;;;; A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;; A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;; A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;; A003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;; A004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;; A005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;; A006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;; A007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;; A008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;; A009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;; A00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;; A00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;; A00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;; A00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;; A00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;; A00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;; A010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;; A011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;; A012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;; A013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;; A014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;; A015;YI SYLLABLE WU;Lo;0;L;;;;;N;;;;; A016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;; A017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;; A018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;; A019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;; A01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;; A01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;; A01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;; A01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;; A01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;; A01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;; A020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;; A021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;; A022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;; A023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;; A024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;; A025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;; A026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;; A027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;; A028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;; A029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;; A02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;; A02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;; A02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;; A02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;; A02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;; A02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;; A030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;; A031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;; A032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;; A033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;; A034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;; A035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;; A036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;; A037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;; A038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;; A039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;; A03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;; A03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;; A03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;; A03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;; A03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;; A03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;; A040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;; A041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;; A042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;; A043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;; A044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;; A045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;; A046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;; A047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;; A048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;; A049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;; A04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;; A04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;; A04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;; A04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;; A04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;; A04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;; A050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;; A051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;; A052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;; A053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;; A054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;; A055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;; A056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;; A057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;; A058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;; A059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;; A05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;; A05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;; A05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;; A05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;; A05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;; A05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;; A060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;; A061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;; A062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;; A063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;; A064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;; A065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;; A066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;; A067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;; A068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;; A069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;; A06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;; A06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;; A06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;; A06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;; A06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;; A06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;; A070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;; A071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;; A072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;; A073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;; A074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;; A075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;; A076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;; A077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;; A078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;; A079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;; A07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;; A07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;; A07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;; A07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;; A07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;; A07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;; A080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;; A081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;; A082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;; A083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;; A084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;; A085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;; A086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;; A087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;; A088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;; A089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;; A08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;; A08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;; A08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;; A08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;; A08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;; A08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;; A090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;; A091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;; A092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;; A093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;; A094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;; A095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;; A096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;; A097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;; A098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;; A099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;; A09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;; A09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;; A09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;; A09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;; A09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;; A09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;; A0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;; A0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;; A0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;; A0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;; A0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;; A0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;; A0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;; A0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;; A0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;; A0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;; A0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;; A0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;; A0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;; A0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;; A0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;; A0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;; A0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;; A0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;; A0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;; A0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;; A0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;; A0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;; A0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;; A0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;; A0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;; A0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;; A0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;; A0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;; A0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;; A0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;; A0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;; A0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;; A0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;; A0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;; A0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;; A0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;; A0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;; A0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;; A0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;; A0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;; A0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;; A0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;; A0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;; A0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;; A0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;; A0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;; A0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;; A0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;; A0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;; A0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;; A0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;; A0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;; A0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;; A0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;; A0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;; A0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;; A0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;; A0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;; A0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;; A0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;; A0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;; A0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;; A0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;; A0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;; A0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;; A0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;; A0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;; A0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;; A0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;; A0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;; A0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;; A0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;; A0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;; A0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;; A0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;; A0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;; A0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;; A0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;; A0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;; A0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;; A0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;; A0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;; A0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;; A0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;; A0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;; A0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;; A0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;; A0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;; A0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;; A0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;; A0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;; A0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;; A0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;; A0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;; A0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;; A0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;; A100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;; A101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;; A102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;; A103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;; A104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;; A105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;; A106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;; A107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;; A108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;; A109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;; A10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;; A10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;; A10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;; A10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;; A10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;; A10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;; A110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;; A111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;; A112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;; A113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;; A114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;; A115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;; A116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;; A117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;; A118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;; A119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;; A11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;; A11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;; A11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;; A11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;; A11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;; A11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;; A120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;; A121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;; A122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;; A123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;; A124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;; A125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;; A126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;; A127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;; A128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;; A129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;; A12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;; A12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;; A12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;; A12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;; A12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;; A12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;; A130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;; A131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;; A132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;; A133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;; A134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;; A135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;; A136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;; A137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;; A138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;; A139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;; A13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;; A13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;; A13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;; A13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;; A13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;; A13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;; A140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;; A141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;; A142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;; A143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;; A144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;; A145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;; A146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;; A147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;; A148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;; A149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;; A14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;; A14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;; A14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;; A14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;; A14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;; A14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;; A150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;; A151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;; A152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;; A153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;; A154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;; A155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;; A156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;; A157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;; A158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;; A159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;; A15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;; A15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;; A15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;; A15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;; A15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;; A15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;; A160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;; A161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;; A162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;; A163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;; A164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;; A165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;; A166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;; A167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;; A168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;; A169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;; A16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;; A16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;; A16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;; A16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;; A16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;; A16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;; A170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;; A171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;; A172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;; A173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;; A174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;; A175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;; A176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;; A177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;; A178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;; A179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;; A17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;; A17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;; A17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;; A17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;; A17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;; A17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;; A180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;; A181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;; A182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;; A183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;; A184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;; A185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;; A186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;; A187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;; A188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;; A189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;; A18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;; A18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;; A18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;; A18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;; A18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;; A18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;; A190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;; A191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;; A192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;; A193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;; A194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;; A195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;; A196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;; A197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;; A198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;; A199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;; A19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;; A19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;; A19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;; A19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;; A19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;; A19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;; A1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;; A1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;; A1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;; A1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;; A1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;; A1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;; A1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;; A1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;; A1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;; A1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;; A1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;; A1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;; A1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;; A1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;; A1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;; A1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;; A1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;; A1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;; A1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;; A1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;; A1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;; A1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;; A1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;; A1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;; A1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;; A1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;; A1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;; A1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;; A1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;; A1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;; A1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;; A1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;; A1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;; A1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;; A1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;; A1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;; A1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;; A1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;; A1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;; A1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;; A1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;; A1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;; A1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;; A1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;; A1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;; A1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;; A1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;; A1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;; A1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;; A1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;; A1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;; A1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;; A1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;; A1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;; A1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;; A1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;; A1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;; A1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;; A1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;; A1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;; A1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;; A1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;; A1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;; A1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;; A1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;; A1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;; A1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;; A1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;; A1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;; A1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;; A1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;; A1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;; A1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;; A1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;; A1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;; A1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;; A1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;; A1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;; A1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;; A1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;; A1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;; A1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;; A1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;; A1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;; A1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;; A1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;; A1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;; A1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;; A1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;; A1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;; A1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;; A1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;; A1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;; A1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;; A1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;; A1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;; A200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;; A201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;; A202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;; A203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;; A204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;; A205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;; A206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;; A207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;; A208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;; A209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;; A20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;; A20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;; A20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;; A20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;; A20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;; A20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;; A210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;; A211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;; A212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;; A213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;; A214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;; A215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;; A216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;; A217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;; A218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;; A219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;; A21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;; A21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;; A21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;; A21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;; A21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;; A21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;; A220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;; A221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;; A222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;; A223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;; A224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;; A225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;; A226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;; A227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;; A228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;; A229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;; A22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;; A22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;; A22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;; A22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;; A22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;; A22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;; A230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;; A231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;; A232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;; A233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;; A234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;; A235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;; A236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;; A237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;; A238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;; A239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;; A23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;; A23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;; A23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;; A23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;; A23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;; A23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;; A240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;; A241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;; A242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;; A243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;; A244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;; A245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;; A246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;; A247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;; A248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;; A249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;; A24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;; A24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;; A24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;; A24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;; A24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;; A24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;; A250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;; A251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;; A252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;; A253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;; A254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;; A255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;; A256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;; A257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;; A258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;; A259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;; A25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;; A25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;; A25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;; A25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;; A25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;; A25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;; A260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;; A261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;; A262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;; A263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;; A264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;; A265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;; A266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;; A267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;; A268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;; A269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;; A26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;; A26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;; A26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;; A26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;; A26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;; A26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;; A270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;; A271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;; A272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;; A273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;; A274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;; A275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;; A276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;; A277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;; A278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;; A279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;; A27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;; A27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;; A27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;; A27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;; A27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;; A27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;; A280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;; A281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;; A282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;; A283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;; A284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;; A285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;; A286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;; A287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;; A288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;; A289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;; A28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;; A28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;; A28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;; A28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;; A28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;; A28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;; A290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;; A291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;; A292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;; A293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;; A294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;; A295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;; A296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;; A297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;; A298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;; A299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;; A29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;; A29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;; A29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;; A29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;; A29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;; A29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;; A2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;; A2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;; A2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;; A2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;; A2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;; A2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;; A2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;; A2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;; A2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;; A2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;; A2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;; A2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;; A2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;; A2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;; A2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;; A2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;; A2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;; A2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;; A2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;; A2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;; A2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;; A2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;; A2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;; A2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;; A2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;; A2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;; A2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;; A2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;; A2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;; A2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;; A2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;; A2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;; A2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;; A2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;; A2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;; A2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;; A2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;; A2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;; A2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;; A2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;; A2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;; A2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;; A2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;; A2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;; A2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;; A2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;; A2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;; A2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;; A2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;; A2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;; A2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;; A2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;; A2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;; A2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;; A2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;; A2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;; A2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;; A2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;; A2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;; A2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;; A2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;; A2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;; A2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;; A2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;; A2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;; A2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;; A2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;; A2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;; A2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;; A2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;; A2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;; A2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;; A2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;; A2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;; A2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;; A2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;; A2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;; A2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;; A2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;; A2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;; A2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;; A2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;; A2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;; A2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;; A2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;; A2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;; A2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;; A2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;; A2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;; A2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;; A2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;; A2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;; A2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;; A2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;; A2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;; A2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;; A300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;; A301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;; A302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;; A303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;; A304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;; A305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;; A306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;; A307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;; A308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;; A309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;; A30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;; A30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;; A30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;; A30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;; A30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;; A30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;; A310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;; A311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;; A312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;; A313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;; A314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;; A315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;; A316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;; A317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;; A318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;; A319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;; A31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;; A31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;; A31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;; A31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;; A31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;; A31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;; A320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;; A321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;; A322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;; A323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;; A324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;; A325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;; A326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;; A327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;; A328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;; A329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;; A32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;; A32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;; A32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;; A32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;; A32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;; A32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;; A330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;; A331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;; A332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;; A333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;; A334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;; A335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;; A336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;; A337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;; A338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;; A339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;; A33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;; A33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;; A33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;; A33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;; A33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;; A33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;; A340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;; A341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;; A342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;; A343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;; A344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;; A345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;; A346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;; A347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;; A348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;; A349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;; A34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;; A34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;; A34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;; A34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;; A34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;; A34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;; A350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;; A351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;; A352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;; A353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;; A354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;; A355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;; A356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;; A357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;; A358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;; A359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;; A35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;; A35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;; A35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;; A35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;; A35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;; A35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;; A360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;; A361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;; A362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;; A363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;; A364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;; A365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;; A366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;; A367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;; A368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;; A369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;; A36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;; A36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;; A36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;; A36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;; A36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;; A36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;; A370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;; A371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;; A372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;; A373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;; A374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;; A375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;; A376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;; A377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;; A378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;; A379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;; A37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;; A37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;; A37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;; A37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;; A37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;; A37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;; A380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;; A381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;; A382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;; A383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;; A384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;; A385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;; A386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;; A387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;; A388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;; A389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;; A38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;; A38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;; A38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;; A38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;; A38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;; A38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;; A390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;; A391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;; A392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;; A393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;; A394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;; A395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;; A396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;; A397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;; A398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;; A399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;; A39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;; A39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;; A39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;; A39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;; A39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;; A39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;; A3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;; A3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;; A3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;; A3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;; A3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;; A3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;; A3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;; A3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;; A3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;; A3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;; A3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;; A3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;; A3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;; A3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;; A3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;; A3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;; A3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;; A3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;; A3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;; A3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;; A3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;; A3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;; A3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;; A3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;; A3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;; A3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;; A3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;; A3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;; A3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;; A3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;; A3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;; A3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;; A3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;; A3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;; A3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;; A3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;; A3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;; A3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;; A3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;; A3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;; A3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;; A3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;; A3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;; A3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;; A3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;; A3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;; A3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;; A3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;; A3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;; A3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;; A3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;; A3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;; A3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;; A3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;; A3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;; A3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;; A3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;; A3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;; A3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;; A3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;; A3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;; A3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;; A3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;; A3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;; A3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;; A3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;; A3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;; A3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;; A3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;; A3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;; A3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;; A3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;; A3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;; A3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;; A3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;; A3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;; A3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;; A3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;; A3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;; A3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;; A3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;; A3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;; A3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;; A3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;; A3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;; A3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;; A3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;; A3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;; A3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;; A3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;; A3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;; A3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;; A3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;; A3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;; A3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;; A3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;; A400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;; A401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;; A402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;; A403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;; A404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;; A405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;; A406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;; A407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;; A408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;; A409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;; A40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;; A40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;; A40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;; A40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;; A40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;; A40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;; A410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;; A411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;; A412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;; A413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;; A414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;; A415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;; A416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;; A417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;; A418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;; A419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;; A41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;; A41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;; A41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;; A41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;; A41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;; A41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;; A420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;; A421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;; A422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;; A423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;; A424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;; A425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;; A426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;; A427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;; A428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;; A429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;; A42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;; A42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;; A42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;; A42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;; A42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;; A42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;; A430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;; A431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;; A432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;; A433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;; A434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;; A435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;; A436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;; A437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;; A438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;; A439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;; A43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;; A43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;; A43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;; A43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;; A43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;; A43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;; A440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;; A441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;; A442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;; A443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;; A444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;; A445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;; A446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;; A447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;; A448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;; A449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;; A44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;; A44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;; A44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;; A44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;; A44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;; A44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;; A450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;; A451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;; A452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;; A453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;; A454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;; A455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;; A456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;; A457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;; A458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;; A459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;; A45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;; A45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;; A45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;; A45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;; A45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;; A45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;; A460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;; A461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;; A462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;; A463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;; A464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;; A465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;; A466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;; A467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;; A468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;; A469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;; A46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;; A46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;; A46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;; A46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;; A46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;; A46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;; A470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;; A471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;; A472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;; A473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;; A474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;; A475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;; A476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;; A477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;; A478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;; A479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;; A47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;; A47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;; A47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;; A47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;; A47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;; A47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;; A480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;; A481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;; A482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;; A483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;; A484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;; A485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;; A486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;; A487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;; A488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;; A489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;; A48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;; A48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;; A48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;; A490;YI RADICAL QOT;So;0;ON;;;;;N;;;;; A491;YI RADICAL LI;So;0;ON;;;;;N;;;;; A492;YI RADICAL KIT;So;0;ON;;;;;N;;;;; A493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;; A494;YI RADICAL CYP;So;0;ON;;;;;N;;;;; A495;YI RADICAL SSI;So;0;ON;;;;;N;;;;; A496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;; A497;YI RADICAL GEP;So;0;ON;;;;;N;;;;; A498;YI RADICAL MI;So;0;ON;;;;;N;;;;; A499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;; A49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;; A49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;; A49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;; A49D;YI RADICAL YO;So;0;ON;;;;;N;;;;; A49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;; A49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;; A4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;; A4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;; A4A2;YI RADICAL ZUP;So;0;ON;;;;;N;;;;; A4A3;YI RADICAL CYT;So;0;ON;;;;;N;;;;; A4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;; A4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;; A4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;; A4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;; A4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;; A4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;; A4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;; A4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;; A4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;; A4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;; A4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;; A4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;; A4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;; A4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;; A4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;; A4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;; A4B4;YI RADICAL NZUP;So;0;ON;;;;;N;;;;; A4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;; A4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;; A4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;; A4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;; A4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;; A4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;; A4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;; A4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;; A4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;; A4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;; A4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;; A4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;; A4C1;YI RADICAL ZUR;So;0;ON;;;;;N;;;;; A4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;; A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;; A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;; A4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;; A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;; AC00;;Lo;0;L;;;;;N;;;;; D7A3;;Lo;0;L;;;;;N;;;;; D800;;Cs;0;L;;;;;N;;;;; DB7F;;Cs;0;L;;;;;N;;;;; DB80;;Cs;0;L;;;;;N;;;;; DBFF;;Cs;0;L;;;;;N;;;;; DC00;;Cs;0;L;;;;;N;;;;; DFFF;;Cs;0;L;;;;;N;;;;; E000;;Co;0;L;;;;;N;;;;; F8FF;;Co;0;L;;;;;N;;;;; F900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;; F901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;; F902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;; F903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;; F904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;; F905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;; F906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;; F907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;; F908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;; F909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;; F90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;; F90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;; F90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;; F90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;; F90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;; F90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;; F910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;; F911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;; F912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;; F913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;; F914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;; F915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;; F916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;; F917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;; F918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;; F919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;; F91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;; F91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;; F91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;; F91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;; F91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;; F91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;; F920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;; F921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;; F922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;; F923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;; F924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;; F925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;; F926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;; F927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;; F928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;; F929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;; F92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;; F92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;; F92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;; F92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;; F92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;; F92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;; F930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;; F931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;; F932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;; F933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;; F934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;; F935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;; F936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;; F937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;; F938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;; F939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;; F93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;; F93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;; F93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;; F93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;; F93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;; F93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;; F940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;; F941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;; F942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;; F943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;; F944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;; F945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;; F946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;; F947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;; F948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;; F949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;; F94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;; F94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;; F94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;; F94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;; F94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;; F94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;; F950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;; F951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;964B;;;;N;;;;; F952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;; F953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;; F954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;; F955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;; F956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;; F957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;; F958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;; F959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;; F95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;; F95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;; F95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;; F95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;; F95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;; F95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;; F960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;; F961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;; F962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;; F963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;; F964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;; F965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;; F966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;; F967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;; F968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;; F969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;; F96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;; F96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;;N;;;;; F96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;; F96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;; F96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;; F96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;; F970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;; F971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;; F972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;; F973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;;N;;;;; F974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;; F975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;; F976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;; F977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;; F978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;;N;;;;; F979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;; F97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;; F97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;; F97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;; F97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;; F97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;; F97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;; F980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;; F981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;; F982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;; F983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;; F984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;; F985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;; F986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;; F987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;; F988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;; F989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;; F98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;; F98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;; F98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;; F98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;; F98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;; F98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;; F990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;; F991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;; F992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;; F993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;; F994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;; F995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;; F996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;; F997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;; F998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;; F999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;; F99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;; F99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;; F99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;; F99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;; F99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;; F99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;; F9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;; F9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;; F9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;; F9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;; F9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;; F9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;; F9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;; F9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;; F9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;; F9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;; F9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;; F9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;; F9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;; F9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;; F9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;; F9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;; F9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;; F9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;; F9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;;N;;;;; F9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;; F9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;; F9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;; F9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;; F9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;; F9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;; F9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;; F9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;; F9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;; F9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;; F9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;; F9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;; F9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;; F9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;; F9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;; F9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;; F9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;; F9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;; F9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;; F9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;; F9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;; F9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;; F9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;; F9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;; F9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;; F9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;; F9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;; F9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;; F9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;; F9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;; F9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;;N;;;;; F9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;; F9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;;N;;;;; F9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;; F9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;; F9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;; F9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;; F9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;; F9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;; F9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;; F9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;; F9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;; F9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;; F9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;; F9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;; F9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;; F9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;; F9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;; F9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;; F9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;; F9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;; F9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;; F9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;; F9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;; F9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;; F9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;; F9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;; F9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;; F9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;; F9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;; F9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;; F9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;; F9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;; F9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;; F9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;; F9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;; F9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;; F9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;; F9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;; F9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;; F9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;; F9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;; F9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;; F9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;; F9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;;N;;;;; F9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;; F9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;; FA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;; FA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;; FA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;; FA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;; FA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;; FA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;; FA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;; FA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;; FA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;; FA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;; FA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;; FA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;; FA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;; FA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;; FA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;; FA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;; FA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;; FA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;; FA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;; FA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;; FA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;; FA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;; FA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;; FA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;; FA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;; FA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;; FA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;; FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;; FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;; FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;; FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;; FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;*;;; FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;; FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;; FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;; FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;*;;; FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;; FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;; FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;; FA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;; FA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;; FA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;; FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;; FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;; FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;; FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;; FA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;; FA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;; FA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;; FA33;CJK COMPATIBILITY IDEOGRAPH-FA33;Lo;0;L;52C9;;;;N;;;;; FA34;CJK COMPATIBILITY IDEOGRAPH-FA34;Lo;0;L;52E4;;;;N;;;;; FA35;CJK COMPATIBILITY IDEOGRAPH-FA35;Lo;0;L;5351;;;;N;;;;; FA36;CJK COMPATIBILITY IDEOGRAPH-FA36;Lo;0;L;559D;;;;N;;;;; FA37;CJK COMPATIBILITY IDEOGRAPH-FA37;Lo;0;L;5606;;;;N;;;;; FA38;CJK COMPATIBILITY IDEOGRAPH-FA38;Lo;0;L;5668;;;;N;;;;; FA39;CJK COMPATIBILITY IDEOGRAPH-FA39;Lo;0;L;5840;;;;N;;;;; FA3A;CJK COMPATIBILITY IDEOGRAPH-FA3A;Lo;0;L;58A8;;;;N;;;;; FA3B;CJK COMPATIBILITY IDEOGRAPH-FA3B;Lo;0;L;5C64;;;;N;;;;; FA3C;CJK COMPATIBILITY IDEOGRAPH-FA3C;Lo;0;L;5C6E;;;;N;;;;; FA3D;CJK COMPATIBILITY IDEOGRAPH-FA3D;Lo;0;L;6094;;;;N;;;;; FA3E;CJK COMPATIBILITY IDEOGRAPH-FA3E;Lo;0;L;6168;;;;N;;;;; FA3F;CJK COMPATIBILITY IDEOGRAPH-FA3F;Lo;0;L;618E;;;;N;;;;; FA40;CJK COMPATIBILITY IDEOGRAPH-FA40;Lo;0;L;61F2;;;;N;;;;; FA41;CJK COMPATIBILITY IDEOGRAPH-FA41;Lo;0;L;654F;;;;N;;;;; FA42;CJK COMPATIBILITY IDEOGRAPH-FA42;Lo;0;L;65E2;;;;N;;;;; FA43;CJK COMPATIBILITY IDEOGRAPH-FA43;Lo;0;L;6691;;;;N;;;;; FA44;CJK COMPATIBILITY IDEOGRAPH-FA44;Lo;0;L;6885;;;;N;;;;; FA45;CJK COMPATIBILITY IDEOGRAPH-FA45;Lo;0;L;6D77;;;;N;;;;; FA46;CJK COMPATIBILITY IDEOGRAPH-FA46;Lo;0;L;6E1A;;;;N;;;;; FA47;CJK COMPATIBILITY IDEOGRAPH-FA47;Lo;0;L;6F22;;;;N;;;;; FA48;CJK COMPATIBILITY IDEOGRAPH-FA48;Lo;0;L;716E;;;;N;;;;; FA49;CJK COMPATIBILITY IDEOGRAPH-FA49;Lo;0;L;722B;;;;N;;;;; FA4A;CJK COMPATIBILITY IDEOGRAPH-FA4A;Lo;0;L;7422;;;;N;;;;; FA4B;CJK COMPATIBILITY IDEOGRAPH-FA4B;Lo;0;L;7891;;;;N;;;;; FA4C;CJK COMPATIBILITY IDEOGRAPH-FA4C;Lo;0;L;793E;;;;N;;;;; FA4D;CJK COMPATIBILITY IDEOGRAPH-FA4D;Lo;0;L;7949;;;;N;;;;; FA4E;CJK COMPATIBILITY IDEOGRAPH-FA4E;Lo;0;L;7948;;;;N;;;;; FA4F;CJK COMPATIBILITY IDEOGRAPH-FA4F;Lo;0;L;7950;;;;N;;;;; FA50;CJK COMPATIBILITY IDEOGRAPH-FA50;Lo;0;L;7956;;;;N;;;;; FA51;CJK COMPATIBILITY IDEOGRAPH-FA51;Lo;0;L;795D;;;;N;;;;; FA52;CJK COMPATIBILITY IDEOGRAPH-FA52;Lo;0;L;798D;;;;N;;;;; FA53;CJK COMPATIBILITY IDEOGRAPH-FA53;Lo;0;L;798E;;;;N;;;;; FA54;CJK COMPATIBILITY IDEOGRAPH-FA54;Lo;0;L;7A40;;;;N;;;;; FA55;CJK COMPATIBILITY IDEOGRAPH-FA55;Lo;0;L;7A81;;;;N;;;;; FA56;CJK COMPATIBILITY IDEOGRAPH-FA56;Lo;0;L;7BC0;;;;N;;;;; FA57;CJK COMPATIBILITY IDEOGRAPH-FA57;Lo;0;L;7DF4;;;;N;;;;; FA58;CJK COMPATIBILITY IDEOGRAPH-FA58;Lo;0;L;7E09;;;;N;;;;; FA59;CJK COMPATIBILITY IDEOGRAPH-FA59;Lo;0;L;7E41;;;;N;;;;; FA5A;CJK COMPATIBILITY IDEOGRAPH-FA5A;Lo;0;L;7F72;;;;N;;;;; FA5B;CJK COMPATIBILITY IDEOGRAPH-FA5B;Lo;0;L;8005;;;;N;;;;; FA5C;CJK COMPATIBILITY IDEOGRAPH-FA5C;Lo;0;L;81ED;;;;N;;;;; FA5D;CJK COMPATIBILITY IDEOGRAPH-FA5D;Lo;0;L;8279;;;;N;;;;; FA5E;CJK COMPATIBILITY IDEOGRAPH-FA5E;Lo;0;L;8279;;;;N;;;;; FA5F;CJK COMPATIBILITY IDEOGRAPH-FA5F;Lo;0;L;8457;;;;N;;;;; FA60;CJK COMPATIBILITY IDEOGRAPH-FA60;Lo;0;L;8910;;;;N;;;;; FA61;CJK COMPATIBILITY IDEOGRAPH-FA61;Lo;0;L;8996;;;;N;;;;; FA62;CJK COMPATIBILITY IDEOGRAPH-FA62;Lo;0;L;8B01;;;;N;;;;; FA63;CJK COMPATIBILITY IDEOGRAPH-FA63;Lo;0;L;8B39;;;;N;;;;; FA64;CJK COMPATIBILITY IDEOGRAPH-FA64;Lo;0;L;8CD3;;;;N;;;;; FA65;CJK COMPATIBILITY IDEOGRAPH-FA65;Lo;0;L;8D08;;;;N;;;;; FA66;CJK COMPATIBILITY IDEOGRAPH-FA66;Lo;0;L;8FB6;;;;N;;;;; FA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;; FA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;; FA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;; FA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;; FB00;LATIN SMALL LIGATURE FF;Ll;0;L; 0066 0066;;;;N;;;;; FB01;LATIN SMALL LIGATURE FI;Ll;0;L; 0066 0069;;;;N;;;;; FB02;LATIN SMALL LIGATURE FL;Ll;0;L; 0066 006C;;;;N;;;;; FB03;LATIN SMALL LIGATURE FFI;Ll;0;L; 0066 0066 0069;;;;N;;;;; FB04;LATIN SMALL LIGATURE FFL;Ll;0;L; 0066 0066 006C;;;;N;;;;; FB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L; 017F 0074;;;;N;;;;; FB06;LATIN SMALL LIGATURE ST;Ll;0;L; 0073 0074;;;;N;;;;; FB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L; 0574 0576;;;;N;;;;; FB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L; 0574 0565;;;;N;;;;; FB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L; 0574 056B;;;;N;;;;; FB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L; 057E 0576;;;;N;;;;; FB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L; 0574 056D;;;;N;;;;; FB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;; FB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;; FB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;; FB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R; 05E2;;;;N;;;;; FB21;HEBREW LETTER WIDE ALEF;Lo;0;R; 05D0;;;;N;;;;; FB22;HEBREW LETTER WIDE DALET;Lo;0;R; 05D3;;;;N;;;;; FB23;HEBREW LETTER WIDE HE;Lo;0;R; 05D4;;;;N;;;;; FB24;HEBREW LETTER WIDE KAF;Lo;0;R; 05DB;;;;N;;;;; FB25;HEBREW LETTER WIDE LAMED;Lo;0;R; 05DC;;;;N;;;;; FB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R; 05DD;;;;N;;;;; FB27;HEBREW LETTER WIDE RESH;Lo;0;R; 05E8;;;;N;;;;; FB28;HEBREW LETTER WIDE TAV;Lo;0;R; 05EA;;;;N;;;;; FB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; FB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;; FB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;; FB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;; FB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;; FB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;; FB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;; FB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;; FB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;; FB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;; FB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;; FB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;; FB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;; FB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;; FB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;; FB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;; FB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;; FB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;; FB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;; FB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;; FB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;; FB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;; FB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;; FB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;; FB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;; FB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;; FB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;; FB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;; FB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;; FB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;; FB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;; FB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;; FB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;; FB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R; 05D0 05DC;;;;N;;;;; FB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL; 0671;;;;N;;;;; FB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL; 0671;;;;N;;;;; FB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL; 067B;;;;N;;;;; FB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL; 067B;;;;N;;;;; FB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL; 067B;;;;N;;;;; FB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL; 067B;;;;N;;;;; FB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL; 067E;;;;N;;;;; FB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL; 067E;;;;N;;;;; FB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL; 067E;;;;N;;;;; FB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL; 067E;;;;N;;;;; FB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL; 0680;;;;N;;;;; FB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL; 0680;;;;N;;;;; FB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL; 0680;;;;N;;;;; FB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL; 0680;;;;N;;;;; FB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL; 067A;;;;N;;;;; FB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL; 067A;;;;N;;;;; FB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL; 067A;;;;N;;;;; FB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL; 067A;;;;N;;;;; FB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL; 067F;;;;N;;;;; FB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL; 067F;;;;N;;;;; FB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL; 067F;;;;N;;;;; FB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL; 067F;;;;N;;;;; FB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL; 0679;;;;N;;;;; FB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL; 0679;;;;N;;;;; FB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL; 0679;;;;N;;;;; FB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL; 0679;;;;N;;;;; FB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL; 06A4;;;;N;;;;; FB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL; 06A4;;;;N;;;;; FB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; FB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL; 06A4;;;;N;;;;; FB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL; 06A6;;;;N;;;;; FB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL; 06A6;;;;N;;;;; FB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; FB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL; 06A6;;;;N;;;;; FB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL; 0684;;;;N;;;;; FB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL; 0684;;;;N;;;;; FB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL; 0684;;;;N;;;;; FB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL; 0684;;;;N;;;;; FB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL; 0683;;;;N;;;;; FB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL; 0683;;;;N;;;;; FB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL; 0683;;;;N;;;;; FB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL; 0683;;;;N;;;;; FB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL; 0686;;;;N;;;;; FB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL; 0686;;;;N;;;;; FB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL; 0686;;;;N;;;;; FB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL; 0686;;;;N;;;;; FB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL; 0687;;;;N;;;;; FB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL; 0687;;;;N;;;;; FB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL; 0687;;;;N;;;;; FB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL; 0687;;;;N;;;;; FB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL; 068D;;;;N;;;;; FB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL; 068D;;;;N;;;;; FB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL; 068C;;;;N;;;;; FB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL; 068C;;;;N;;;;; FB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL; 068E;;;;N;;;;; FB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL; 068E;;;;N;;;;; FB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL; 0688;;;;N;;;;; FB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL; 0688;;;;N;;;;; FB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL; 0698;;;;N;;;;; FB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL; 0698;;;;N;;;;; FB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL; 0691;;;;N;;;;; FB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL; 0691;;;;N;;;;; FB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL; 06A9;;;;N;;;;; FB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL; 06A9;;;;N;;;;; FB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; FB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL; 06A9;;;;N;;;;; FB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL; 06AF;;;;N;;;;; FB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL; 06AF;;;;N;;;;; FB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; FB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL; 06AF;;;;N;;;;; FB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL; 06B3;;;;N;;;;; FB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL; 06B3;;;;N;;;;; FB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; FB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL; 06B3;;;;N;;;;; FB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL; 06B1;;;;N;;;;; FB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL; 06B1;;;;N;;;;; FB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; FB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL; 06B1;;;;N;;;;; FB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL; 06BA;;;;N;;;;; FB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL; 06BA;;;;N;;;;; FBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL; 06BB;;;;N;;;;; FBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL; 06BB;;;;N;;;;; FBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; FBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL; 06BB;;;;N;;;;; FBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL; 06C0;;;;N;;;;; FBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL; 06C0;;;;N;;;;; FBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL; 06C1;;;;N;;;;; FBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL; 06C1;;;;N;;;;; FBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; FBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL; 06C1;;;;N;;;;; FBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL; 06BE;;;;N;;;;; FBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL; 06BE;;;;N;;;;; FBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; FBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL; 06BE;;;;N;;;;; FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL; 06D2;;;;N;;;;; FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL; 06D2;;;;N;;;;; FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 06D3;;;;N;;;;; FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 06D3;;;;N;;;;; FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL; 06AD;;;;N;;;;; FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL; 06AD;;;;N;;;;; FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; FBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL; 06AD;;;;N;;;;; FBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL; 06C7;;;;N;;;;; FBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL; 06C7;;;;N;;;;; FBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL; 06C6;;;;N;;;;; FBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL; 06C6;;;;N;;;;; FBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL; 06C8;;;;N;;;;; FBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL; 06C8;;;;N;;;;; FBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0677;;;;N;;;;; FBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL; 06CB;;;;N;;;;; FBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL; 06CB;;;;N;;;;; FBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL; 06C5;;;;N;;;;; FBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL; 06C5;;;;N;;;;; FBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL; 06C9;;;;N;;;;; FBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL; 06C9;;;;N;;;;; FBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL; 06D0;;;;N;;;;; FBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL; 06D0;;;;N;;;;; FBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; FBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL; 06D0;;;;N;;;;; FBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0649;;;;N;;;;; FBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL; 0649;;;;N;;;;; FBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL; 0626 0627;;;;N;;;;; FBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL; 0626 0627;;;;N;;;;; FBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; FBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL; 0626 06D5;;;;N;;;;; FBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL; 0626 0648;;;;N;;;;; FBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL; 0626 0648;;;;N;;;;; FBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; FBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL; 0626 06C7;;;;N;;;;; FBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; FBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL; 0626 06C6;;;;N;;;;; FBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; FBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL; 0626 06C8;;;;N;;;;; FBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; FBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; FBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL; 0626 06D0;;;;N;;;;; FBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; FBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; FBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; FBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL; 06CC;;;;N;;;;; FBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL; 06CC;;;;N;;;;; FBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; FBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL; 06CC;;;;N;;;;; FC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL; 0626 062C;;;;N;;;;; FC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL; 0626 062D;;;;N;;;;; FC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL; 0626 0645;;;;N;;;;; FC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0626 0649;;;;N;;;;; FC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL; 0626 064A;;;;N;;;;; FC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0628 062C;;;;N;;;;; FC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL; 0628 062D;;;;N;;;;; FC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0628 062E;;;;N;;;;; FC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0628 0645;;;;N;;;;; FC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0628 0649;;;;N;;;;; FC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL; 0628 064A;;;;N;;;;; FC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062A 062C;;;;N;;;;; FC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL; 062A 062D;;;;N;;;;; FC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL; 062A 062E;;;;N;;;;; FC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062A 0645;;;;N;;;;; FC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062A 0649;;;;N;;;;; FC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL; 062A 064A;;;;N;;;;; FC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL; 062B 062C;;;;N;;;;; FC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL; 062B 0645;;;;N;;;;; FC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062B 0649;;;;N;;;;; FC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL; 062B 064A;;;;N;;;;; FC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL; 062C 062D;;;;N;;;;; FC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 062C 0645;;;;N;;;;; FC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062D 062C;;;;N;;;;; FC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062D 0645;;;;N;;;;; FC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL; 062E 062C;;;;N;;;;; FC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL; 062E 062D;;;;N;;;;; FC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL; 062E 0645;;;;N;;;;; FC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0633 062C;;;;N;;;;; FC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0633 062D;;;;N;;;;; FC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0633 062E;;;;N;;;;; FC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0633 0645;;;;N;;;;; FC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL; 0635 062D;;;;N;;;;; FC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0635 0645;;;;N;;;;; FC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL; 0636 062C;;;;N;;;;; FC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL; 0636 062D;;;;N;;;;; FC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL; 0636 062E;;;;N;;;;; FC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL; 0636 0645;;;;N;;;;; FC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL; 0637 062D;;;;N;;;;; FC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0637 0645;;;;N;;;;; FC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL; 0638 0645;;;;N;;;;; FC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL; 0639 062C;;;;N;;;;; FC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL; 0639 0645;;;;N;;;;; FC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL; 063A 062C;;;;N;;;;; FC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL; 063A 0645;;;;N;;;;; FC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0641 062C;;;;N;;;;; FC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL; 0641 062D;;;;N;;;;; FC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL; 0641 062E;;;;N;;;;; FC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0641 0645;;;;N;;;;; FC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0641 0649;;;;N;;;;; FC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL; 0641 064A;;;;N;;;;; FC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL; 0642 062D;;;;N;;;;; FC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0642 0645;;;;N;;;;; FC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0642 0649;;;;N;;;;; FC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL; 0642 064A;;;;N;;;;; FC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL; 0643 0627;;;;N;;;;; FC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL; 0643 062C;;;;N;;;;; FC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL; 0643 062D;;;;N;;;;; FC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL; 0643 062E;;;;N;;;;; FC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL; 0643 0644;;;;N;;;;; FC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL; 0643 0645;;;;N;;;;; FC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0643 0649;;;;N;;;;; FC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL; 0643 064A;;;;N;;;;; FC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL; 0644 062C;;;;N;;;;; FC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL; 0644 062D;;;;N;;;;; FC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL; 0644 062E;;;;N;;;;; FC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL; 0644 0645;;;;N;;;;; FC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0644 0649;;;;N;;;;; FC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL; 0644 064A;;;;N;;;;; FC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL; 0645 062C;;;;N;;;;; FC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL; 0645 062D;;;;N;;;;; FC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL; 0645 062E;;;;N;;;;; FC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL; 0645 0645;;;;N;;;;; FC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0645 0649;;;;N;;;;; FC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL; 0645 064A;;;;N;;;;; FC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL; 0646 062C;;;;N;;;;; FC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL; 0646 062D;;;;N;;;;; FC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL; 0646 062E;;;;N;;;;; FC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL; 0646 0645;;;;N;;;;; FC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0646 0649;;;;N;;;;; FC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL; 0646 064A;;;;N;;;;; FC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL; 0647 062C;;;;N;;;;; FC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL; 0647 0645;;;;N;;;;; FC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0647 0649;;;;N;;;;; FC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL; 0647 064A;;;;N;;;;; FC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL; 064A 062C;;;;N;;;;; FC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL; 064A 062D;;;;N;;;;; FC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL; 064A 062E;;;;N;;;;; FC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL; 064A 0645;;;;N;;;;; FC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 064A 0649;;;;N;;;;; FC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL; 064A 064A;;;;N;;;;; FC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0630 0670;;;;N;;;;; FC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0631 0670;;;;N;;;;; FC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0649 0670;;;;N;;;;; FC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C 0651;;;;N;;;;; FC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D 0651;;;;N;;;;; FC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL; 0020 064E 0651;;;;N;;;;; FC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F 0651;;;;N;;;;; FC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL; 0020 0650 0651;;;;N;;;;; FC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL; 0020 0651 0670;;;;N;;;;; FC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL; 0626 0631;;;;N;;;;; FC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL; 0626 0632;;;;N;;;;; FC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; FC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL; 0626 0646;;;;N;;;;; FC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0626 0649;;;;N;;;;; FC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL; 0626 064A;;;;N;;;;; FC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL; 0628 0631;;;;N;;;;; FC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL; 0628 0632;;;;N;;;;; FC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; FC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL; 0628 0646;;;;N;;;;; FC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0628 0649;;;;N;;;;; FC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL; 0628 064A;;;;N;;;;; FC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL; 062A 0631;;;;N;;;;; FC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL; 062A 0632;;;;N;;;;; FC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; FC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL; 062A 0646;;;;N;;;;; FC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0649;;;;N;;;;; FC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL; 062A 064A;;;;N;;;;; FC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL; 062B 0631;;;;N;;;;; FC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL; 062B 0632;;;;N;;;;; FC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; FC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL; 062B 0646;;;;N;;;;; FC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062B 0649;;;;N;;;;; FC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL; 062B 064A;;;;N;;;;; FC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0641 0649;;;;N;;;;; FC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL; 0641 064A;;;;N;;;;; FC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0642 0649;;;;N;;;;; FC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL; 0642 064A;;;;N;;;;; FC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL; 0643 0627;;;;N;;;;; FC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; FC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; FC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0643 0649;;;;N;;;;; FC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL; 0643 064A;;;;N;;;;; FC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; FC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 0649;;;;N;;;;; FC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL; 0644 064A;;;;N;;;;; FC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL; 0645 0627;;;;N;;;;; FC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; FC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL; 0646 0631;;;;N;;;;; FC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL; 0646 0632;;;;N;;;;; FC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; FC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL; 0646 0646;;;;N;;;;; FC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0649;;;;N;;;;; FC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL; 0646 064A;;;;N;;;;; FC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL; 0649 0670;;;;N;;;;; FC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL; 064A 0631;;;;N;;;;; FC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL; 064A 0632;;;;N;;;;; FC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; FC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL; 064A 0646;;;;N;;;;; FC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 064A 0649;;;;N;;;;; FC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL; 064A 064A;;;;N;;;;; FC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL; 0626 062C;;;;N;;;;; FC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL; 0626 062D;;;;N;;;;; FC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL; 0626 062E;;;;N;;;;; FC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; FC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; FC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL; 0628 062C;;;;N;;;;; FC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL; 0628 062D;;;;N;;;;; FC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL; 0628 062E;;;;N;;;;; FC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; FCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; FCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062C;;;;N;;;;; FCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL; 062A 062D;;;;N;;;;; FCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL; 062A 062E;;;;N;;;;; FCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; FCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; FCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; FCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 062D;;;;N;;;;; FCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062C 0645;;;;N;;;;; FCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062D 062C;;;;N;;;;; FCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062D 0645;;;;N;;;;; FCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 062E 062C;;;;N;;;;; FCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062E 0645;;;;N;;;;; FCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; FCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; FCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; FCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; FCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D;;;;N;;;;; FCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL; 0635 062E;;;;N;;;;; FCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645;;;;N;;;;; FCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL; 0636 062C;;;;N;;;;; FCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL; 0636 062D;;;;N;;;;; FCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL; 0636 062E;;;;N;;;;; FCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL; 0636 0645;;;;N;;;;; FCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL; 0637 062D;;;;N;;;;; FCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; FCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL; 0639 062C;;;;N;;;;; FCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645;;;;N;;;;; FCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL; 063A 062C;;;;N;;;;; FCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL; 063A 0645;;;;N;;;;; FCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL; 0641 062C;;;;N;;;;; FCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL; 0641 062D;;;;N;;;;; FCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL; 0641 062E;;;;N;;;;; FCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 0645;;;;N;;;;; FCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL; 0642 062D;;;;N;;;;; FCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL; 0642 0645;;;;N;;;;; FCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL; 0643 062C;;;;N;;;;; FCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL; 0643 062D;;;;N;;;;; FCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL; 0643 062E;;;;N;;;;; FCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; FCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; FCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C;;;;N;;;;; FCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL; 0644 062D;;;;N;;;;; FCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL; 0644 062E;;;;N;;;;; FCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; FCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL; 0644 0647;;;;N;;;;; FCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062C;;;;N;;;;; FCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062D;;;;N;;;;; FCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062E;;;;N;;;;; FCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 0645;;;;N;;;;; FCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL; 0646 062C;;;;N;;;;; FCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL; 0646 062D;;;;N;;;;; FCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL; 0646 062E;;;;N;;;;; FCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; FCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; FCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL; 0647 062C;;;;N;;;;; FCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645;;;;N;;;;; FCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL; 0647 0670;;;;N;;;;; FCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL; 064A 062C;;;;N;;;;; FCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL; 064A 062D;;;;N;;;;; FCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL; 064A 062E;;;;N;;;;; FCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; FCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; FCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL; 0626 0645;;;;N;;;;; FCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL; 0626 0647;;;;N;;;;; FCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL; 0628 0645;;;;N;;;;; FCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL; 0628 0647;;;;N;;;;; FCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062A 0645;;;;N;;;;; FCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL; 062A 0647;;;;N;;;;; FCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL; 062B 0645;;;;N;;;;; FCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL; 062B 0647;;;;N;;;;; FCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0633 0645;;;;N;;;;; FCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; FCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; FCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; FCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL; 0643 0644;;;;N;;;;; FCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL; 0643 0645;;;;N;;;;; FCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL; 0644 0645;;;;N;;;;; FCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL; 0646 0645;;;;N;;;;; FCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL; 0646 0647;;;;N;;;;; FCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL; 064A 0645;;;;N;;;;; FCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL; 064A 0647;;;;N;;;;; FCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL; 0640 064E 0651;;;;N;;;;; FCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F 0651;;;;N;;;;; FCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL; 0640 0650 0651;;;;N;;;;; FCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0637 0649;;;;N;;;;; FCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL; 0637 064A;;;;N;;;;; FCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0639 0649;;;;N;;;;; FCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL; 0639 064A;;;;N;;;;; FCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 063A 0649;;;;N;;;;; FCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL; 063A 064A;;;;N;;;;; FCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0633 0649;;;;N;;;;; FCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0633 064A;;;;N;;;;; FCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0634 0649;;;;N;;;;; FCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL; 0634 064A;;;;N;;;;; FCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062D 0649;;;;N;;;;; FD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL; 062D 064A;;;;N;;;;; FD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062C 0649;;;;N;;;;; FD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL; 062C 064A;;;;N;;;;; FD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 062E 0649;;;;N;;;;; FD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL; 062E 064A;;;;N;;;;; FD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0635 0649;;;;N;;;;; FD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL; 0635 064A;;;;N;;;;; FD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0636 0649;;;;N;;;;; FD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL; 0636 064A;;;;N;;;;; FD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL; 0634 062C;;;;N;;;;; FD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL; 0634 062D;;;;N;;;;; FD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL; 0634 062E;;;;N;;;;; FD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL; 0634 0645;;;;N;;;;; FD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL; 0634 0631;;;;N;;;;; FD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL; 0633 0631;;;;N;;;;; FD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL; 0635 0631;;;;N;;;;; FD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL; 0636 0631;;;;N;;;;; FD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0637 0649;;;;N;;;;; FD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL; 0637 064A;;;;N;;;;; FD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0649;;;;N;;;;; FD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL; 0639 064A;;;;N;;;;; FD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0649;;;;N;;;;; FD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL; 063A 064A;;;;N;;;;; FD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 0649;;;;N;;;;; FD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL; 0633 064A;;;;N;;;;; FD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0634 0649;;;;N;;;;; FD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL; 0634 064A;;;;N;;;;; FD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0649;;;;N;;;;; FD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL; 062D 064A;;;;N;;;;; FD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0649;;;;N;;;;; FD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 064A;;;;N;;;;; FD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062E 0649;;;;N;;;;; FD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL; 062E 064A;;;;N;;;;; FD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0635 0649;;;;N;;;;; FD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL; 0635 064A;;;;N;;;;; FD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 0649;;;;N;;;;; FD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL; 0636 064A;;;;N;;;;; FD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; FD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; FD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; FD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; FD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL; 0634 0631;;;;N;;;;; FD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL; 0633 0631;;;;N;;;;; FD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL; 0635 0631;;;;N;;;;; FD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL; 0636 0631;;;;N;;;;; FD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; FD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; FD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; FD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645;;;;N;;;;; FD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL; 0633 0647;;;;N;;;;; FD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL; 0634 0647;;;;N;;;;; FD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; FD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0633 062C;;;;N;;;;; FD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0633 062D;;;;N;;;;; FD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0633 062E;;;;N;;;;; FD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL; 0634 062C;;;;N;;;;; FD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL; 0634 062D;;;;N;;;;; FD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL; 0634 062E;;;;N;;;;; FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0637 0645;;;;N;;;;; FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL; 0638 0645;;;;N;;;;; FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL; 0627 064B;;;;N;;;;; FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL; 0627 064B;;;;N;;;;; FD3E;ORNATE LEFT PARENTHESIS;Ps;0;ON;;;;;N;;;;; FD3F;ORNATE RIGHT PARENTHESIS;Pe;0;ON;;;;;N;;;;; FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062C 0645;;;;N;;;;; FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 062A 062D 062C;;;;N;;;;; FD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062D 0645;;;;N;;;;; FD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 062A 062E 0645;;;;N;;;;; FD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 062A 0645 062C;;;;N;;;;; FD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062A 0645 062D;;;;N;;;;; FD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 062A 0645 062E;;;;N;;;;; FD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; FD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 062C 0645 062D;;;;N;;;;; FD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 0645 064A;;;;N;;;;; FD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062D 0645 0649;;;;N;;;;; FD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0633 062D 062C;;;;N;;;;; FD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 062C 062D;;;;N;;;;; FD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062C 0649;;;;N;;;;; FD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; FD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0633 0645 062D;;;;N;;;;; FD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0633 0645 062C;;;;N;;;;; FD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; FD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0633 0645 0645;;;;N;;;;; FD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; FD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL; 0635 062D 062D;;;;N;;;;; FD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; FD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; FD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0634 062D 0645;;;;N;;;;; FD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0634 062C 064A;;;;N;;;;; FD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; FD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0634 0645 062E;;;;N;;;;; FD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; FD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0634 0645 0645;;;;N;;;;; FD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0636 062D 0649;;;;N;;;;; FD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; FD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0636 062E 0645;;;;N;;;;; FD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; FD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0637 0645 062D;;;;N;;;;; FD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0637 0645 0645;;;;N;;;;; FD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0637 0645 064A;;;;N;;;;; FD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; FD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; FD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 0645 0645;;;;N;;;;; FD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0639 0645 0649;;;;N;;;;; FD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 063A 0645 0645;;;;N;;;;; FD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 063A 0645 064A;;;;N;;;;; FD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 063A 0645 0649;;;;N;;;;; FD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; FD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0641 062E 0645;;;;N;;;;; FD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; FD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0642 0645 0645;;;;N;;;;; FD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; FD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0644 062D 064A;;;;N;;;;; FD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0644 062D 0649;;;;N;;;;; FD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; FD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL; 0644 062C 062C;;;;N;;;;; FD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; FD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062E 0645;;;;N;;;;; FD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; FD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0644 0645 062D;;;;N;;;;; FD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062D 062C;;;;N;;;;; FD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062D 0645;;;;N;;;;; FD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062D 064A;;;;N;;;;; FD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0645 062C 062D;;;;N;;;;; FD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062C 0645;;;;N;;;;; FD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL; 0645 062E 062C;;;;N;;;;; FD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL; 0645 062E 0645;;;;N;;;;; FD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL; 0645 062C 062E;;;;N;;;;; FD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL; 0647 0645 062C;;;;N;;;;; FD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0647 0645 0645;;;;N;;;;; FD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062D 0645;;;;N;;;;; FD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062D 0649;;;;N;;;;; FD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; FD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0646 062C 0645;;;;N;;;;; FD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 062C 0649;;;;N;;;;; FD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 0645 064A;;;;N;;;;; FD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0646 0645 0649;;;;N;;;;; FD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; FD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 064A 0645 0645;;;;N;;;;; FD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062E 064A;;;;N;;;;; FD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 062C 064A;;;;N;;;;; FDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062C 0649;;;;N;;;;; FDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 062A 062E 064A;;;;N;;;;; FDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 062E 0649;;;;N;;;;; FDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062A 0645 064A;;;;N;;;;; FDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062A 0645 0649;;;;N;;;;; FDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 062C 0645 064A;;;;N;;;;; FDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 062D 0649;;;;N;;;;; FDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 062C 0645 0649;;;;N;;;;; FDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL; 0633 062E 0649;;;;N;;;;; FDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0635 062D 064A;;;;N;;;;; FDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0634 062D 064A;;;;N;;;;; FDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0636 062D 064A;;;;N;;;;; FDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 062C 064A;;;;N;;;;; FDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0644 0645 064A;;;;N;;;;; FDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 064A 062D 064A;;;;N;;;;; FDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 062C 064A;;;;N;;;;; FDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 064A 0645 064A;;;;N;;;;; FDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 0645 064A;;;;N;;;;; FDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0642 0645 064A;;;;N;;;;; FDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0646 062D 064A;;;;N;;;;; FDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL; 0642 0645 062D;;;;N;;;;; FDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062D 0645;;;;N;;;;; FDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0639 0645 064A;;;;N;;;;; FDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0643 0645 064A;;;;N;;;;; FDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; FDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0645 062E 064A;;;;N;;;;; FDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; FDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; FDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL; 0644 062C 0645;;;;N;;;;; FDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL; 0646 062C 062D;;;;N;;;;; FDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 062C 062D 064A;;;;N;;;;; FDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 062D 062C 064A;;;;N;;;;; FDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0645 062C 064A;;;;N;;;;; FDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL; 0641 0645 064A;;;;N;;;;; FDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL; 0628 062D 064A;;;;N;;;;; FDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0643 0645 0645;;;;N;;;;; FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0639 062C 0645;;;;N;;;;; FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL; 0635 0645 0645;;;;N;;;;; FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL; 0633 062E 064A;;;;N;;;;; FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL; 0646 062C 064A;;;;N;;;;; FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0635 0644 06D2;;;;N;;;;; FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL; 0642 0644 06D2;;;;N;;;;; FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL; 0627 0644 0644 0647;;;;N;;;;; FDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL; 0627 0643 0628 0631;;;;N;;;;; FDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL; 0645 062D 0645 062F;;;;N;;;;; FDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL; 0635 0644 0639 0645;;;;N;;;;; FDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL; 0631 0633 0648 0644;;;;N;;;;; FDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL; 0639 0644 064A 0647;;;;N;;;;; FDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL; 0648 0633 0644 0645;;;;N;;;;; FDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL; 0635 0644 0649;;;;N;;;;; FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL; 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;; FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL; 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;; FDFC;RIAL SIGN;Sc;0;AL; 0631 06CC 0627 0644;;;;N;;;;; FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;; FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;; FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;; FE03;VARIATION SELECTOR-4;Mn;0;NSM;;;;;N;;;;; FE04;VARIATION SELECTOR-5;Mn;0;NSM;;;;;N;;;;; FE05;VARIATION SELECTOR-6;Mn;0;NSM;;;;;N;;;;; FE06;VARIATION SELECTOR-7;Mn;0;NSM;;;;;N;;;;; FE07;VARIATION SELECTOR-8;Mn;0;NSM;;;;;N;;;;; FE08;VARIATION SELECTOR-9;Mn;0;NSM;;;;;N;;;;; FE09;VARIATION SELECTOR-10;Mn;0;NSM;;;;;N;;;;; FE0A;VARIATION SELECTOR-11;Mn;0;NSM;;;;;N;;;;; FE0B;VARIATION SELECTOR-12;Mn;0;NSM;;;;;N;;;;; FE0C;VARIATION SELECTOR-13;Mn;0;NSM;;;;;N;;;;; FE0D;VARIATION SELECTOR-14;Mn;0;NSM;;;;;N;;;;; FE0E;VARIATION SELECTOR-15;Mn;0;NSM;;;;;N;;;;; FE0F;VARIATION SELECTOR-16;Mn;0;NSM;;;;;N;;;;; FE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;; FE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; FE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;; FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;; FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON; 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;; FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON; 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;; FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON; 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;; FE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;; FE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON; 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;; FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;; FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;; FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;; FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;; FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;; FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;; FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON; 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;; FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON; 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;; FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON; 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;; FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON; 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;; FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON; 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;; FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON; 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;; FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;; FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;; FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON; 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;; FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON; 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;; FE45;SESAME DOT;Po;0;ON;;;;;N;;;;; FE46;WHITE SESAME DOT;Po;0;ON;;;;;N;;;;; FE49;DASHED OVERLINE;Po;0;ON; 203E;;;;N;SPACING DASHED OVERSCORE;;;; FE4A;CENTRELINE OVERLINE;Po;0;ON; 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;; FE4B;WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING WAVY OVERSCORE;;;; FE4C;DOUBLE WAVY OVERLINE;Po;0;ON; 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;; FE4D;DASHED LOW LINE;Pc;0;ON; 005F;;;;N;SPACING DASHED UNDERSCORE;;;; FE4E;CENTRELINE LOW LINE;Pc;0;ON; 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;; FE4F;WAVY LOW LINE;Pc;0;ON; 005F;;;;N;SPACING WAVY UNDERSCORE;;;; FE50;SMALL COMMA;Po;0;CS; 002C;;;;N;;;;; FE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; FE52;SMALL FULL STOP;Po;0;CS; 002E;;;;N;SMALL PERIOD;;;; FE54;SMALL SEMICOLON;Po;0;ON; 003B;;;;N;;;;; FE55;SMALL COLON;Po;0;CS; 003A;;;;N;;;;; FE56;SMALL QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; FE57;SMALL EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; FE58;SMALL EM DASH;Pd;0;ON; 2014;;;;N;;;;; FE59;SMALL LEFT PARENTHESIS;Ps;0;ON; 0028;;;;N;SMALL OPENING PARENTHESIS;;;; FE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;N;SMALL CLOSING PARENTHESIS;;;; FE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;N;SMALL OPENING CURLY BRACKET;;;; FE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;N;SMALL CLOSING CURLY BRACKET;;;; FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON; 3014;;;;N;SMALL OPENING TORTOISE SHELL BRACKET;;;; FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON; 3015;;;;N;SMALL CLOSING TORTOISE SHELL BRACKET;;;; FE5F;SMALL NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; FE60;SMALL AMPERSAND;Po;0;ON; 0026;;;;N;;;;; FE61;SMALL ASTERISK;Po;0;ON; 002A;;;;N;;;;; FE62;SMALL PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; FE63;SMALL HYPHEN-MINUS;Pd;0;ET; 002D;;;;N;;;;; FE64;SMALL LESS-THAN SIGN;Sm;0;ON; 003C;;;;N;;;;; FE65;SMALL GREATER-THAN SIGN;Sm;0;ON; 003E;;;;N;;;;; FE66;SMALL EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; FE68;SMALL REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;SMALL BACKSLASH;;;; FE69;SMALL DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; FE6A;SMALL PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; FE6B;SMALL COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; FE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL; 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;; FE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL; 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;; FE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL; 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;; FE73;ARABIC TAIL FRAGMENT;Lo;0;AL;;;;;N;;;;; FE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL; 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;; FE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL; 0020 064E;;;;N;ARABIC SPACING FATHAH;;;; FE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL; 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;; FE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL; 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;; FE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL; 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;; FE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL; 0020 0650;;;;N;ARABIC SPACING KASRAH;;;; FE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL; 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;; FE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL; 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;; FE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL; 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;; FE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL; 0020 0652;;;;N;ARABIC SPACING SUKUN;;;; FE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL; 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;; FE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL; 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;; FE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;; FE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;; FE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;; FE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;; FE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;; FE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;; FE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;; FE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;; FE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;; FE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;; FE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;; FE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL; 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;; FE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;; FE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL; 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;; FE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;; FE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;; FE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;; FE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL; 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;; FE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;; FE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL; 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;; FE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;; FE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;; FE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;; FE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL; 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;; FE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;; FE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;; FE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;; FE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL; 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;; FE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;; FE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;; FE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;; FEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL; 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;; FEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;; FEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;; FEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;; FEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL; 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;; FEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;; FEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;; FEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;; FEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL; 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;; FEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;; FEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL; 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;; FEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;; FEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL; 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;; FEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;; FEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL; 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;; FEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;; FEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL; 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;; FEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;; FEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;; FEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;; FEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL; 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;; FEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;; FEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;; FEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;; FEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL; 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;; FEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;; FEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;; FEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;; FEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL; 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;; FEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;; FEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;; FEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;; FEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL; 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;; FEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;; FEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;; FEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;; FEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL; 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;; FEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;; FEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;; FEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;; FEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL; 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;; FEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;; FECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;; FECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;; FECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL; 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;; FECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;; FECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;; FECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;; FED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL; 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;; FED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;; FED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;; FED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;; FED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL; 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;; FED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;; FED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;; FED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;; FED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL; 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;; FED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;; FEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;; FEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;; FEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL; 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;; FEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;; FEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;; FEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;; FEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL; 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;; FEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;; FEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;; FEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;; FEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL; 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;; FEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;; FEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;; FEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;; FEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL; 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;; FEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;; FEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;; FEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;; FEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL; 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;; FEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;; FEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL; 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;; FEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;; FEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL; 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;; FEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;; FEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;; FEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;; FEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL; 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;; FEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;; FEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL; 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;; FEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; FEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL; 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;; FEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; FEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL; 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;; FEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;; FEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL; 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;; FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; FF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON; 0021;;;;N;;;;; FF02;FULLWIDTH QUOTATION MARK;Po;0;ON; 0022;;;;N;;;;; FF03;FULLWIDTH NUMBER SIGN;Po;0;ET; 0023;;;;N;;;;; FF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET; 0024;;;;N;;;;; FF05;FULLWIDTH PERCENT SIGN;Po;0;ET; 0025;;;;N;;;;; FF06;FULLWIDTH AMPERSAND;Po;0;ON; 0026;;;;N;;;;; FF07;FULLWIDTH APOSTROPHE;Po;0;ON; 0027;;;;N;;;;; FF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON; 0028;;;;Y;FULLWIDTH OPENING PARENTHESIS;;;; FF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON; 0029;;;;Y;FULLWIDTH CLOSING PARENTHESIS;;;; FF0A;FULLWIDTH ASTERISK;Po;0;ON; 002A;;;;N;;;;; FF0B;FULLWIDTH PLUS SIGN;Sm;0;ET; 002B;;;;N;;;;; FF0C;FULLWIDTH COMMA;Po;0;CS; 002C;;;;N;;;;; FF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ET; 002D;;;;N;;;;; FF0E;FULLWIDTH FULL STOP;Po;0;CS; 002E;;;;N;FULLWIDTH PERIOD;;;; FF0F;FULLWIDTH SOLIDUS;Po;0;ES; 002F;;;;N;FULLWIDTH SLASH;;;; FF10;FULLWIDTH DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; FF11;FULLWIDTH DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; FF12;FULLWIDTH DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; FF13;FULLWIDTH DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; FF14;FULLWIDTH DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; FF15;FULLWIDTH DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; FF16;FULLWIDTH DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; FF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; FF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; FF19;FULLWIDTH DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; FF1A;FULLWIDTH COLON;Po;0;CS; 003A;;;;N;;;;; FF1B;FULLWIDTH SEMICOLON;Po;0;ON; 003B;;;;N;;;;; FF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON; 003C;;;;Y;;;;; FF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON; 003D;;;;N;;;;; FF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON; 003E;;;;Y;;;;; FF1F;FULLWIDTH QUESTION MARK;Po;0;ON; 003F;;;;N;;;;; FF20;FULLWIDTH COMMERCIAL AT;Po;0;ON; 0040;;;;N;;;;; FF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L; 0041;;;;N;;;;FF41; FF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L; 0042;;;;N;;;;FF42; FF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L; 0043;;;;N;;;;FF43; FF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L; 0044;;;;N;;;;FF44; FF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L; 0045;;;;N;;;;FF45; FF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L; 0046;;;;N;;;;FF46; FF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L; 0047;;;;N;;;;FF47; FF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L; 0048;;;;N;;;;FF48; FF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L; 0049;;;;N;;;;FF49; FF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L; 004A;;;;N;;;;FF4A; FF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L; 004B;;;;N;;;;FF4B; FF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L; 004C;;;;N;;;;FF4C; FF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L; 004D;;;;N;;;;FF4D; FF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L; 004E;;;;N;;;;FF4E; FF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L; 004F;;;;N;;;;FF4F; FF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L; 0050;;;;N;;;;FF50; FF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L; 0051;;;;N;;;;FF51; FF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L; 0052;;;;N;;;;FF52; FF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L; 0053;;;;N;;;;FF53; FF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L; 0054;;;;N;;;;FF54; FF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L; 0055;;;;N;;;;FF55; FF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L; 0056;;;;N;;;;FF56; FF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L; 0057;;;;N;;;;FF57; FF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L; 0058;;;;N;;;;FF58; FF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L; 0059;;;;N;;;;FF59; FF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L; 005A;;;;N;;;;FF5A; FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON; 005B;;;;Y;FULLWIDTH OPENING SQUARE BRACKET;;;; FF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON; 005C;;;;N;FULLWIDTH BACKSLASH;;;; FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON; 005D;;;;Y;FULLWIDTH CLOSING SQUARE BRACKET;;;; FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON; 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;; FF3F;FULLWIDTH LOW LINE;Pc;0;ON; 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;; FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON; 0060;;;;N;FULLWIDTH SPACING GRAVE;;;; FF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L; 0061;;;;N;;;FF21;;FF21 FF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L; 0062;;;;N;;;FF22;;FF22 FF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L; 0063;;;;N;;;FF23;;FF23 FF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L; 0064;;;;N;;;FF24;;FF24 FF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L; 0065;;;;N;;;FF25;;FF25 FF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L; 0066;;;;N;;;FF26;;FF26 FF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L; 0067;;;;N;;;FF27;;FF27 FF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L; 0068;;;;N;;;FF28;;FF28 FF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L; 0069;;;;N;;;FF29;;FF29 FF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L; 006A;;;;N;;;FF2A;;FF2A FF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L; 006B;;;;N;;;FF2B;;FF2B FF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L; 006C;;;;N;;;FF2C;;FF2C FF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L; 006D;;;;N;;;FF2D;;FF2D FF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L; 006E;;;;N;;;FF2E;;FF2E FF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L; 006F;;;;N;;;FF2F;;FF2F FF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L; 0070;;;;N;;;FF30;;FF30 FF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L; 0071;;;;N;;;FF31;;FF31 FF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L; 0072;;;;N;;;FF32;;FF32 FF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L; 0073;;;;N;;;FF33;;FF33 FF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L; 0074;;;;N;;;FF34;;FF34 FF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L; 0075;;;;N;;;FF35;;FF35 FF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L; 0076;;;;N;;;FF36;;FF36 FF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L; 0077;;;;N;;;FF37;;FF37 FF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L; 0078;;;;N;;;FF38;;FF38 FF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L; 0079;;;;N;;;FF39;;FF39 FF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L; 007A;;;;N;;;FF3A;;FF3A FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON; 007B;;;;Y;FULLWIDTH OPENING CURLY BRACKET;;;; FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON; 007C;;;;N;FULLWIDTH VERTICAL BAR;;;; FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON; 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;; FF5E;FULLWIDTH TILDE;Sm;0;ON; 007E;;;;N;FULLWIDTH SPACING TILDE;;;; FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON; 2985;;;;Y;;*;;; FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON; 2986;;;;Y;;*;;; FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON; 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;; FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON; 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;; FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON; 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;; FF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON; 3001;;;;N;;;;; FF65;HALFWIDTH KATAKANA MIDDLE DOT;Pc;0;ON; 30FB;;;;N;;;;; FF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L; 30F2;;;;N;;;;; FF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L; 30A1;;;;N;;;;; FF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L; 30A3;;;;N;;;;; FF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L; 30A5;;;;N;;;;; FF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L; 30A7;;;;N;;;;; FF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L; 30A9;;;;N;;;;; FF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L; 30E3;;;;N;;;;; FF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L; 30E5;;;;N;;;;; FF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L; 30E7;;;;N;;;;; FF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L; 30C3;;;;N;;;;; FF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L; 30FC;;;;N;;;;; FF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L; 30A2;;;;N;;;;; FF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L; 30A4;;;;N;;;;; FF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L; 30A6;;;;N;;;;; FF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L; 30A8;;;;N;;;;; FF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L; 30AA;;;;N;;;;; FF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L; 30AB;;;;N;;;;; FF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L; 30AD;;;;N;;;;; FF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L; 30AF;;;;N;;;;; FF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L; 30B1;;;;N;;;;; FF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L; 30B3;;;;N;;;;; FF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L; 30B5;;;;N;;;;; FF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L; 30B7;;;;N;;;;; FF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L; 30B9;;;;N;;;;; FF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L; 30BB;;;;N;;;;; FF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L; 30BD;;;;N;;;;; FF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L; 30BF;;;;N;;;;; FF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L; 30C1;;;;N;;;;; FF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L; 30C4;;;;N;;;;; FF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L; 30C6;;;;N;;;;; FF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L; 30C8;;;;N;;;;; FF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L; 30CA;;;;N;;;;; FF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L; 30CB;;;;N;;;;; FF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L; 30CC;;;;N;;;;; FF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L; 30CD;;;;N;;;;; FF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L; 30CE;;;;N;;;;; FF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L; 30CF;;;;N;;;;; FF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L; 30D2;;;;N;;;;; FF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L; 30D5;;;;N;;;;; FF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L; 30D8;;;;N;;;;; FF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L; 30DB;;;;N;;;;; FF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L; 30DE;;;;N;;;;; FF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L; 30DF;;;;N;;;;; FF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L; 30E0;;;;N;;;;; FF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L; 30E1;;;;N;;;;; FF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L; 30E2;;;;N;;;;; FF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L; 30E4;;;;N;;;;; FF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L; 30E6;;;;N;;;;; FF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L; 30E8;;;;N;;;;; FF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L; 30E9;;;;N;;;;; FF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L; 30EA;;;;N;;;;; FF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L; 30EB;;;;N;;;;; FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L; 30EC;;;;N;;;;; FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L; 30ED;;;;N;;;;; FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L; 30EF;;;;N;;;;; FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L; 30F3;;;;N;;;;; FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L; 3099;;;;N;;halfwidth katakana-hiragana voiced sound mark;;; FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L; 309A;;;;N;;halfwidth katakana-hiragana semi-voiced sound mark;;; FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L; 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;; FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L; 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;; FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L; 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;; FFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;; FFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L; 3134;;;;N;;;;; FFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L; 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;; FFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L; 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;; FFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L; 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;; FFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L; 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;; FFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L; 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;; FFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L; 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;; FFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L; 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;; FFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L; 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;; FFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L; 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;; FFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L; 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;; FFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L; 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;; FFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L; 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;; FFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L; 3141;;;;N;;;;; FFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L; 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;; FFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L; 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;; FFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L; 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;; FFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L; 3145;;;;N;;;;; FFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L; 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;; FFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L; 3147;;;;N;;;;; FFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L; 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;; FFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L; 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;; FFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L; 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;; FFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L; 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;; FFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L; 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;; FFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L; 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;; FFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L; 314E;;;;N;;;;; FFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L; 314F;;;;N;;;;; FFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L; 3150;;;;N;;;;; FFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L; 3151;;;;N;;;;; FFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L; 3152;;;;N;;;;; FFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L; 3153;;;;N;;;;; FFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L; 3154;;;;N;;;;; FFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L; 3155;;;;N;;;;; FFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L; 3156;;;;N;;;;; FFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L; 3157;;;;N;;;;; FFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L; 3158;;;;N;;;;; FFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L; 3159;;;;N;;;;; FFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L; 315A;;;;N;;;;; FFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L; 315B;;;;N;;;;; FFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L; 315C;;;;N;;;;; FFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L; 315D;;;;N;;;;; FFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L; 315E;;;;N;;;;; FFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L; 315F;;;;N;;;;; FFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L; 3160;;;;N;;;;; FFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L; 3161;;;;N;;;;; FFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L; 3162;;;;N;;;;; FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L; 3163;;;;N;;;;; FFE0;FULLWIDTH CENT SIGN;Sc;0;ET; 00A2;;;;N;;;;; FFE1;FULLWIDTH POUND SIGN;Sc;0;ET; 00A3;;;;N;;;;; FFE2;FULLWIDTH NOT SIGN;Sm;0;ON; 00AC;;;;N;;;;; FFE3;FULLWIDTH MACRON;Sk;0;ON; 00AF;;;;N;FULLWIDTH SPACING MACRON;*;;; FFE4;FULLWIDTH BROKEN BAR;So;0;ON; 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;; FFE5;FULLWIDTH YEN SIGN;Sc;0;ET; 00A5;;;;N;;;;; FFE6;FULLWIDTH WON SIGN;Sc;0;ET; 20A9;;;;N;;;;; FFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON; 2502;;;;N;;;;; FFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON; 2190;;;;N;;;;; FFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON; 2191;;;;N;;;;; FFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON; 2192;;;;N;;;;; FFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON; 2193;;;;N;;;;; FFED;HALFWIDTH BLACK SQUARE;So;0;ON; 25A0;;;;N;;;;; FFEE;HALFWIDTH WHITE CIRCLE;So;0;ON; 25CB;;;;N;;;;; FFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;BN;;;;;N;;;;; FFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;BN;;;;;N;;;;; FFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;BN;;;;;N;;;;; FFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;; 10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;; 10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;; 10303;OLD ITALIC LETTER DE;Lo;0;L;;;;;N;;;;; 10304;OLD ITALIC LETTER E;Lo;0;L;;;;;N;;;;; 10305;OLD ITALIC LETTER VE;Lo;0;L;;;;;N;;;;; 10306;OLD ITALIC LETTER ZE;Lo;0;L;;;;;N;;;;; 10307;OLD ITALIC LETTER HE;Lo;0;L;;;;;N;;;;; 10308;OLD ITALIC LETTER THE;Lo;0;L;;;;;N;;;;; 10309;OLD ITALIC LETTER I;Lo;0;L;;;;;N;;;;; 1030A;OLD ITALIC LETTER KA;Lo;0;L;;;;;N;;;;; 1030B;OLD ITALIC LETTER EL;Lo;0;L;;;;;N;;;;; 1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;; 1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;; 1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;; 1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;Faliscan;;; 10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;; 10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;; 10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;; 10313;OLD ITALIC LETTER ER;Lo;0;L;;;;;N;;;;; 10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;; 10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;; 10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;; 10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;Faliscan;;; 10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;; 10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;; 1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;; 1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;Umbrian;;; 1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;Umbrian;;; 1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;Oscan;;; 1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;Oscan;;; 10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;; 10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;; 10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;; 10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;; 10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;; 10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;; 10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;; 10333;GOTHIC LETTER DAGS;Lo;0;L;;;;;N;;;;; 10334;GOTHIC LETTER AIHVUS;Lo;0;L;;;;;N;;;;; 10335;GOTHIC LETTER QAIRTHRA;Lo;0;L;;;;;N;;;;; 10336;GOTHIC LETTER IUJA;Lo;0;L;;;;;N;;;;; 10337;GOTHIC LETTER HAGL;Lo;0;L;;;;;N;;;;; 10338;GOTHIC LETTER THIUTH;Lo;0;L;;;;;N;;;;; 10339;GOTHIC LETTER EIS;Lo;0;L;;;;;N;;;;; 1033A;GOTHIC LETTER KUSMA;Lo;0;L;;;;;N;;;;; 1033B;GOTHIC LETTER LAGUS;Lo;0;L;;;;;N;;;;; 1033C;GOTHIC LETTER MANNA;Lo;0;L;;;;;N;;;;; 1033D;GOTHIC LETTER NAUTHS;Lo;0;L;;;;;N;;;;; 1033E;GOTHIC LETTER JER;Lo;0;L;;;;;N;;;;; 1033F;GOTHIC LETTER URUS;Lo;0;L;;;;;N;;;;; 10340;GOTHIC LETTER PAIRTHRA;Lo;0;L;;;;;N;;;;; 10341;GOTHIC LETTER NINETY;Lo;0;L;;;;;N;;;;; 10342;GOTHIC LETTER RAIDA;Lo;0;L;;;;;N;;;;; 10343;GOTHIC LETTER SAUIL;Lo;0;L;;;;;N;;;;; 10344;GOTHIC LETTER TEIWS;Lo;0;L;;;;;N;;;;; 10345;GOTHIC LETTER WINJA;Lo;0;L;;;;;N;;;;; 10346;GOTHIC LETTER FAIHU;Lo;0;L;;;;;N;;;;; 10347;GOTHIC LETTER IGGWS;Lo;0;L;;;;;N;;;;; 10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;; 10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;; 1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;;N;;;;; 10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428; 10401;DESERET CAPITAL LETTER LONG E;Lu;0;L;;;;;N;;;;10429; 10402;DESERET CAPITAL LETTER LONG A;Lu;0;L;;;;;N;;;;1042A; 10403;DESERET CAPITAL LETTER LONG AH;Lu;0;L;;;;;N;;;;1042B; 10404;DESERET CAPITAL LETTER LONG O;Lu;0;L;;;;;N;;;;1042C; 10405;DESERET CAPITAL LETTER LONG OO;Lu;0;L;;;;;N;;;;1042D; 10406;DESERET CAPITAL LETTER SHORT I;Lu;0;L;;;;;N;;;;1042E; 10407;DESERET CAPITAL LETTER SHORT E;Lu;0;L;;;;;N;;;;1042F; 10408;DESERET CAPITAL LETTER SHORT A;Lu;0;L;;;;;N;;;;10430; 10409;DESERET CAPITAL LETTER SHORT AH;Lu;0;L;;;;;N;;;;10431; 1040A;DESERET CAPITAL LETTER SHORT O;Lu;0;L;;;;;N;;;;10432; 1040B;DESERET CAPITAL LETTER SHORT OO;Lu;0;L;;;;;N;;;;10433; 1040C;DESERET CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;10434; 1040D;DESERET CAPITAL LETTER OW;Lu;0;L;;;;;N;;;;10435; 1040E;DESERET CAPITAL LETTER WU;Lu;0;L;;;;;N;;;;10436; 1040F;DESERET CAPITAL LETTER YEE;Lu;0;L;;;;;N;;;;10437; 10410;DESERET CAPITAL LETTER H;Lu;0;L;;;;;N;;;;10438; 10411;DESERET CAPITAL LETTER PEE;Lu;0;L;;;;;N;;;;10439; 10412;DESERET CAPITAL LETTER BEE;Lu;0;L;;;;;N;;;;1043A; 10413;DESERET CAPITAL LETTER TEE;Lu;0;L;;;;;N;;;;1043B; 10414;DESERET CAPITAL LETTER DEE;Lu;0;L;;;;;N;;;;1043C; 10415;DESERET CAPITAL LETTER CHEE;Lu;0;L;;;;;N;;;;1043D; 10416;DESERET CAPITAL LETTER JEE;Lu;0;L;;;;;N;;;;1043E; 10417;DESERET CAPITAL LETTER KAY;Lu;0;L;;;;;N;;;;1043F; 10418;DESERET CAPITAL LETTER GAY;Lu;0;L;;;;;N;;;;10440; 10419;DESERET CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;10441; 1041A;DESERET CAPITAL LETTER VEE;Lu;0;L;;;;;N;;;;10442; 1041B;DESERET CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;10443; 1041C;DESERET CAPITAL LETTER THEE;Lu;0;L;;;;;N;;;;10444; 1041D;DESERET CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;10445; 1041E;DESERET CAPITAL LETTER ZEE;Lu;0;L;;;;;N;;;;10446; 1041F;DESERET CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;10447; 10420;DESERET CAPITAL LETTER ZHEE;Lu;0;L;;;;;N;;;;10448; 10421;DESERET CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;10449; 10422;DESERET CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;1044A; 10423;DESERET CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;1044B; 10424;DESERET CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;1044C; 10425;DESERET CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;1044D; 10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400 10429;DESERET SMALL LETTER LONG E;Ll;0;L;;;;;N;;;10401;;10401 1042A;DESERET SMALL LETTER LONG A;Ll;0;L;;;;;N;;;10402;;10402 1042B;DESERET SMALL LETTER LONG AH;Ll;0;L;;;;;N;;;10403;;10403 1042C;DESERET SMALL LETTER LONG O;Ll;0;L;;;;;N;;;10404;;10404 1042D;DESERET SMALL LETTER LONG OO;Ll;0;L;;;;;N;;;10405;;10405 1042E;DESERET SMALL LETTER SHORT I;Ll;0;L;;;;;N;;;10406;;10406 1042F;DESERET SMALL LETTER SHORT E;Ll;0;L;;;;;N;;;10407;;10407 10430;DESERET SMALL LETTER SHORT A;Ll;0;L;;;;;N;;;10408;;10408 10431;DESERET SMALL LETTER SHORT AH;Ll;0;L;;;;;N;;;10409;;10409 10432;DESERET SMALL LETTER SHORT O;Ll;0;L;;;;;N;;;1040A;;1040A 10433;DESERET SMALL LETTER SHORT OO;Ll;0;L;;;;;N;;;1040B;;1040B 10434;DESERET SMALL LETTER AY;Ll;0;L;;;;;N;;;1040C;;1040C 10435;DESERET SMALL LETTER OW;Ll;0;L;;;;;N;;;1040D;;1040D 10436;DESERET SMALL LETTER WU;Ll;0;L;;;;;N;;;1040E;;1040E 10437;DESERET SMALL LETTER YEE;Ll;0;L;;;;;N;;;1040F;;1040F 10438;DESERET SMALL LETTER H;Ll;0;L;;;;;N;;;10410;;10410 10439;DESERET SMALL LETTER PEE;Ll;0;L;;;;;N;;;10411;;10411 1043A;DESERET SMALL LETTER BEE;Ll;0;L;;;;;N;;;10412;;10412 1043B;DESERET SMALL LETTER TEE;Ll;0;L;;;;;N;;;10413;;10413 1043C;DESERET SMALL LETTER DEE;Ll;0;L;;;;;N;;;10414;;10414 1043D;DESERET SMALL LETTER CHEE;Ll;0;L;;;;;N;;;10415;;10415 1043E;DESERET SMALL LETTER JEE;Ll;0;L;;;;;N;;;10416;;10416 1043F;DESERET SMALL LETTER KAY;Ll;0;L;;;;;N;;;10417;;10417 10440;DESERET SMALL LETTER GAY;Ll;0;L;;;;;N;;;10418;;10418 10441;DESERET SMALL LETTER EF;Ll;0;L;;;;;N;;;10419;;10419 10442;DESERET SMALL LETTER VEE;Ll;0;L;;;;;N;;;1041A;;1041A 10443;DESERET SMALL LETTER ETH;Ll;0;L;;;;;N;;;1041B;;1041B 10444;DESERET SMALL LETTER THEE;Ll;0;L;;;;;N;;;1041C;;1041C 10445;DESERET SMALL LETTER ES;Ll;0;L;;;;;N;;;1041D;;1041D 10446;DESERET SMALL LETTER ZEE;Ll;0;L;;;;;N;;;1041E;;1041E 10447;DESERET SMALL LETTER ESH;Ll;0;L;;;;;N;;;1041F;;1041F 10448;DESERET SMALL LETTER ZHEE;Ll;0;L;;;;;N;;;10420;;10420 10449;DESERET SMALL LETTER ER;Ll;0;L;;;;;N;;;10421;;10421 1044A;DESERET SMALL LETTER EL;Ll;0;L;;;;;N;;;10422;;10422 1044B;DESERET SMALL LETTER EM;Ll;0;L;;;;;N;;;10423;;10423 1044C;DESERET SMALL LETTER EN;Ll;0;L;;;;;N;;;10424;;10424 1044D;DESERET SMALL LETTER ENG;Ll;0;L;;;;;N;;;10425;;10425 1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;; 1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;; 1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;; 1D003;BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON;So;0;L;;;;;N;;;;; 1D004;BYZANTINE MUSICAL SYMBOL OXEIA DIPLI;So;0;L;;;;;N;;;;; 1D005;BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON;So;0;L;;;;;N;;;;; 1D006;BYZANTINE MUSICAL SYMBOL VAREIA DIPLI;So;0;L;;;;;N;;;;; 1D007;BYZANTINE MUSICAL SYMBOL KATHISTI;So;0;L;;;;;N;;;;; 1D008;BYZANTINE MUSICAL SYMBOL SYRMATIKI;So;0;L;;;;;N;;;;; 1D009;BYZANTINE MUSICAL SYMBOL PARAKLITIKI;So;0;L;;;;;N;;;;; 1D00A;BYZANTINE MUSICAL SYMBOL YPOKRISIS;So;0;L;;;;;N;;;;; 1D00B;BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI;So;0;L;;;;;N;;;;; 1D00C;BYZANTINE MUSICAL SYMBOL KREMASTI;So;0;L;;;;;N;;;;; 1D00D;BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON;So;0;L;;;;;N;;;;; 1D00E;BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON;So;0;L;;;;;N;;;;; 1D00F;BYZANTINE MUSICAL SYMBOL TELEIA;So;0;L;;;;;N;;;;; 1D010;BYZANTINE MUSICAL SYMBOL KENTIMATA;So;0;L;;;;;N;;;;; 1D011;BYZANTINE MUSICAL SYMBOL APOSTROFOS;So;0;L;;;;;N;;;;; 1D012;BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI;So;0;L;;;;;N;;;;; 1D013;BYZANTINE MUSICAL SYMBOL SYNEVMA;So;0;L;;;;;N;;;;; 1D014;BYZANTINE MUSICAL SYMBOL THITA;So;0;L;;;;;N;;;;; 1D015;BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION;So;0;L;;;;;N;;;;; 1D016;BYZANTINE MUSICAL SYMBOL GORGON ARCHAION;So;0;L;;;;;N;;;;; 1D017;BYZANTINE MUSICAL SYMBOL PSILON;So;0;L;;;;;N;;;;; 1D018;BYZANTINE MUSICAL SYMBOL CHAMILON;So;0;L;;;;;N;;;;; 1D019;BYZANTINE MUSICAL SYMBOL VATHY;So;0;L;;;;;N;;;;; 1D01A;BYZANTINE MUSICAL SYMBOL ISON ARCHAION;So;0;L;;;;;N;;;;; 1D01B;BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION;So;0;L;;;;;N;;;;; 1D01C;BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION;So;0;L;;;;;N;;;;; 1D01D;BYZANTINE MUSICAL SYMBOL SAXIMATA;So;0;L;;;;;N;;;;; 1D01E;BYZANTINE MUSICAL SYMBOL PARICHON;So;0;L;;;;;N;;;;; 1D01F;BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA;So;0;L;;;;;N;;;;; 1D020;BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION;So;0;L;;;;;N;;;;; 1D021;BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION;So;0;L;;;;;N;;;;; 1D022;BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION;So;0;L;;;;;N;;;;; 1D023;BYZANTINE MUSICAL SYMBOL APOTHEMA;So;0;L;;;;;N;;;;; 1D024;BYZANTINE MUSICAL SYMBOL KLASMA;So;0;L;;;;;N;;;;; 1D025;BYZANTINE MUSICAL SYMBOL REVMA;So;0;L;;;;;N;;;;; 1D026;BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION;So;0;L;;;;;N;;;;; 1D027;BYZANTINE MUSICAL SYMBOL TINAGMA;So;0;L;;;;;N;;;;; 1D028;BYZANTINE MUSICAL SYMBOL ANATRICHISMA;So;0;L;;;;;N;;;;; 1D029;BYZANTINE MUSICAL SYMBOL SEISMA;So;0;L;;;;;N;;;;; 1D02A;BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION;So;0;L;;;;;N;;;;; 1D02B;BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU;So;0;L;;;;;N;;;;; 1D02C;BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION;So;0;L;;;;;N;;;;; 1D02D;BYZANTINE MUSICAL SYMBOL THEMA;So;0;L;;;;;N;;;;; 1D02E;BYZANTINE MUSICAL SYMBOL LEMOI;So;0;L;;;;;N;;;;; 1D02F;BYZANTINE MUSICAL SYMBOL DYO;So;0;L;;;;;N;;;;; 1D030;BYZANTINE MUSICAL SYMBOL TRIA;So;0;L;;;;;N;;;;; 1D031;BYZANTINE MUSICAL SYMBOL TESSERA;So;0;L;;;;;N;;;;; 1D032;BYZANTINE MUSICAL SYMBOL KRATIMATA;So;0;L;;;;;N;;;;; 1D033;BYZANTINE MUSICAL SYMBOL APESO EXO NEO;So;0;L;;;;;N;;;;; 1D034;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION;So;0;L;;;;;N;;;;; 1D035;BYZANTINE MUSICAL SYMBOL IMIFTHORA;So;0;L;;;;;N;;;;; 1D036;BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION;So;0;L;;;;;N;;;;; 1D037;BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON;So;0;L;;;;;N;;;;; 1D038;BYZANTINE MUSICAL SYMBOL PELASTON;So;0;L;;;;;N;;;;; 1D039;BYZANTINE MUSICAL SYMBOL PSIFISTON;So;0;L;;;;;N;;;;; 1D03A;BYZANTINE MUSICAL SYMBOL KONTEVMA;So;0;L;;;;;N;;;;; 1D03B;BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION;So;0;L;;;;;N;;;;; 1D03C;BYZANTINE MUSICAL SYMBOL RAPISMA;So;0;L;;;;;N;;;;; 1D03D;BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION;So;0;L;;;;;N;;;;; 1D03E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION;So;0;L;;;;;N;;;;; 1D03F;BYZANTINE MUSICAL SYMBOL ICHADIN;So;0;L;;;;;N;;;;; 1D040;BYZANTINE MUSICAL SYMBOL NANA;So;0;L;;;;;N;;;;; 1D041;BYZANTINE MUSICAL SYMBOL PETASMA;So;0;L;;;;;N;;;;; 1D042;BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO;So;0;L;;;;;N;;;;; 1D043;BYZANTINE MUSICAL SYMBOL TROMIKON ALLO;So;0;L;;;;;N;;;;; 1D044;BYZANTINE MUSICAL SYMBOL STRAGGISMATA;So;0;L;;;;;N;;;;; 1D045;BYZANTINE MUSICAL SYMBOL GRONTHISMATA;So;0;L;;;;;N;;;;; 1D046;BYZANTINE MUSICAL SYMBOL ISON NEO;So;0;L;;;;;N;;;;; 1D047;BYZANTINE MUSICAL SYMBOL OLIGON NEO;So;0;L;;;;;N;;;;; 1D048;BYZANTINE MUSICAL SYMBOL OXEIA NEO;So;0;L;;;;;N;;;;; 1D049;BYZANTINE MUSICAL SYMBOL PETASTI;So;0;L;;;;;N;;;;; 1D04A;BYZANTINE MUSICAL SYMBOL KOUFISMA;So;0;L;;;;;N;;;;; 1D04B;BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA;So;0;L;;;;;N;;;;; 1D04C;BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA;So;0;L;;;;;N;;;;; 1D04D;BYZANTINE MUSICAL SYMBOL PELASTON NEO;So;0;L;;;;;N;;;;; 1D04E;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO;So;0;L;;;;;N;;;;; 1D04F;BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO;So;0;L;;;;;N;;;;; 1D050;BYZANTINE MUSICAL SYMBOL YPSILI;So;0;L;;;;;N;;;;; 1D051;BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO;So;0;L;;;;;N;;;;; 1D052;BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO;So;0;L;;;;;N;;;;; 1D053;BYZANTINE MUSICAL SYMBOL YPORROI;So;0;L;;;;;N;;;;; 1D054;BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON;So;0;L;;;;;N;;;;; 1D055;BYZANTINE MUSICAL SYMBOL ELAFRON;So;0;L;;;;;N;;;;; 1D056;BYZANTINE MUSICAL SYMBOL CHAMILI;So;0;L;;;;;N;;;;; 1D057;BYZANTINE MUSICAL SYMBOL MIKRON ISON;So;0;L;;;;;N;;;;; 1D058;BYZANTINE MUSICAL SYMBOL VAREIA NEO;So;0;L;;;;;N;;;;; 1D059;BYZANTINE MUSICAL SYMBOL PIASMA NEO;So;0;L;;;;;N;;;;; 1D05A;BYZANTINE MUSICAL SYMBOL PSIFISTON NEO;So;0;L;;;;;N;;;;; 1D05B;BYZANTINE MUSICAL SYMBOL OMALON;So;0;L;;;;;N;;;;; 1D05C;BYZANTINE MUSICAL SYMBOL ANTIKENOMA;So;0;L;;;;;N;;;;; 1D05D;BYZANTINE MUSICAL SYMBOL LYGISMA;So;0;L;;;;;N;;;;; 1D05E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO;So;0;L;;;;;N;;;;; 1D05F;BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO;So;0;L;;;;;N;;;;; 1D060;BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA;So;0;L;;;;;N;;;;; 1D061;BYZANTINE MUSICAL SYMBOL KYLISMA;So;0;L;;;;;N;;;;; 1D062;BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA;So;0;L;;;;;N;;;;; 1D063;BYZANTINE MUSICAL SYMBOL TROMIKON NEO;So;0;L;;;;;N;;;;; 1D064;BYZANTINE MUSICAL SYMBOL EKSTREPTON;So;0;L;;;;;N;;;;; 1D065;BYZANTINE MUSICAL SYMBOL SYNAGMA NEO;So;0;L;;;;;N;;;;; 1D066;BYZANTINE MUSICAL SYMBOL SYRMA;So;0;L;;;;;N;;;;; 1D067;BYZANTINE MUSICAL SYMBOL CHOREVMA NEO;So;0;L;;;;;N;;;;; 1D068;BYZANTINE MUSICAL SYMBOL EPEGERMA;So;0;L;;;;;N;;;;; 1D069;BYZANTINE MUSICAL SYMBOL SEISMA NEO;So;0;L;;;;;N;;;;; 1D06A;BYZANTINE MUSICAL SYMBOL XIRON KLASMA;So;0;L;;;;;N;;;;; 1D06B;BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON;So;0;L;;;;;N;;;;; 1D06C;BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA;So;0;L;;;;;N;;;;; 1D06D;BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA;So;0;L;;;;;N;;;;; 1D06E;BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA;So;0;L;;;;;N;;;;; 1D06F;BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA;So;0;L;;;;;N;;;;; 1D070;BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA;So;0;L;;;;;N;;;;; 1D071;BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA;So;0;L;;;;;N;;;;; 1D072;BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON;So;0;L;;;;;N;;;;; 1D073;BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON;So;0;L;;;;;N;;;;; 1D074;BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON;So;0;L;;;;;N;;;;; 1D075;BYZANTINE MUSICAL SYMBOL OYRANISMA NEO;So;0;L;;;;;N;;;;; 1D076;BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO;So;0;L;;;;;N;;;;; 1D077;BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO;So;0;L;;;;;N;;;;; 1D078;BYZANTINE MUSICAL SYMBOL THEMA APLOUN;So;0;L;;;;;N;;;;; 1D079;BYZANTINE MUSICAL SYMBOL THES KAI APOTHES;So;0;L;;;;;N;;;;; 1D07A;BYZANTINE MUSICAL SYMBOL KATAVASMA;So;0;L;;;;;N;;;;; 1D07B;BYZANTINE MUSICAL SYMBOL ENDOFONON;So;0;L;;;;;N;;;;; 1D07C;BYZANTINE MUSICAL SYMBOL YFEN KATO;So;0;L;;;;;N;;;;; 1D07D;BYZANTINE MUSICAL SYMBOL YFEN ANO;So;0;L;;;;;N;;;;; 1D07E;BYZANTINE MUSICAL SYMBOL STAVROS;So;0;L;;;;;N;;;;; 1D07F;BYZANTINE MUSICAL SYMBOL KLASMA ANO;So;0;L;;;;;N;;;;; 1D080;BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION;So;0;L;;;;;N;;;;; 1D081;BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION;So;0;L;;;;;N;;;;; 1D082;BYZANTINE MUSICAL SYMBOL KRATIMA ALLO;So;0;L;;;;;N;;;;; 1D083;BYZANTINE MUSICAL SYMBOL KRATIMA NEO;So;0;L;;;;;N;;;;; 1D084;BYZANTINE MUSICAL SYMBOL APODERMA NEO;So;0;L;;;;;N;;;;; 1D085;BYZANTINE MUSICAL SYMBOL APLI;So;0;L;;;;;N;;;;; 1D086;BYZANTINE MUSICAL SYMBOL DIPLI;So;0;L;;;;;N;;;;; 1D087;BYZANTINE MUSICAL SYMBOL TRIPLI;So;0;L;;;;;N;;;;; 1D088;BYZANTINE MUSICAL SYMBOL TETRAPLI;So;0;L;;;;;N;;;;; 1D089;BYZANTINE MUSICAL SYMBOL KORONIS;So;0;L;;;;;N;;;;; 1D08A;BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU;So;0;L;;;;;N;;;;; 1D08B;BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON;So;0;L;;;;;N;;;;; 1D08C;BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON;So;0;L;;;;;N;;;;; 1D08D;BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON;So;0;L;;;;;N;;;;; 1D08E;BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU;So;0;L;;;;;N;;;;; 1D08F;BYZANTINE MUSICAL SYMBOL GORGON NEO ANO;So;0;L;;;;;N;;;;; 1D090;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA;So;0;L;;;;;N;;;;; 1D091;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; 1D092;BYZANTINE MUSICAL SYMBOL DIGORGON;So;0;L;;;;;N;;;;; 1D093;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO;So;0;L;;;;;N;;;;; 1D094;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO;So;0;L;;;;;N;;;;; 1D095;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;; 1D096;BYZANTINE MUSICAL SYMBOL TRIGORGON;So;0;L;;;;;N;;;;; 1D097;BYZANTINE MUSICAL SYMBOL ARGON;So;0;L;;;;;N;;;;; 1D098;BYZANTINE MUSICAL SYMBOL IMIDIARGON;So;0;L;;;;;N;;;;; 1D099;BYZANTINE MUSICAL SYMBOL DIARGON;So;0;L;;;;;N;;;;; 1D09A;BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI;So;0;L;;;;;N;;;;; 1D09B;BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI;So;0;L;;;;;N;;;;; 1D09C;BYZANTINE MUSICAL SYMBOL AGOGI ARGI;So;0;L;;;;;N;;;;; 1D09D;BYZANTINE MUSICAL SYMBOL AGOGI METRIA;So;0;L;;;;;N;;;;; 1D09E;BYZANTINE MUSICAL SYMBOL AGOGI MESI;So;0;L;;;;;N;;;;; 1D09F;BYZANTINE MUSICAL SYMBOL AGOGI GORGI;So;0;L;;;;;N;;;;; 1D0A0;BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI;So;0;L;;;;;N;;;;; 1D0A1;BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI;So;0;L;;;;;N;;;;; 1D0A2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS;So;0;L;;;;;N;;;;; 1D0A3;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS;So;0;L;;;;;N;;;;; 1D0A4;BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS;So;0;L;;;;;N;;;;; 1D0A5;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS;So;0;L;;;;;N;;;;; 1D0A6;BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS;So;0;L;;;;;N;;;;; 1D0A7;BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS;So;0;L;;;;;N;;;;; 1D0A8;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS;So;0;L;;;;;N;;;;; 1D0A9;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS;So;0;L;;;;;N;;;;; 1D0AA;BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS;So;0;L;;;;;N;;;;; 1D0AB;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS;So;0;L;;;;;N;;;;; 1D0AC;BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; 1D0AD;BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS;So;0;L;;;;;N;;;;; 1D0AE;BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS;So;0;L;;;;;N;;;;; 1D0AF;BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS;So;0;L;;;;;N;;;;; 1D0B0;BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS;So;0;L;;;;;N;;;;; 1D0B1;BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS;So;0;L;;;;;N;;;;; 1D0B2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS;So;0;L;;;;;N;;;;; 1D0B3;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS;So;0;L;;;;;N;;;;; 1D0B4;BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN;So;0;L;;;;;N;;;;; 1D0B5;BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN;So;0;L;;;;;N;;;;; 1D0B6;BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU;So;0;L;;;;;N;;;;; 1D0B7;BYZANTINE MUSICAL SYMBOL IMIFONON;So;0;L;;;;;N;;;;; 1D0B8;BYZANTINE MUSICAL SYMBOL IMIFTHORON;So;0;L;;;;;N;;;;; 1D0B9;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU;So;0;L;;;;;N;;;;; 1D0BA;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA;So;0;L;;;;;N;;;;; 1D0BB;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA;So;0;L;;;;;N;;;;; 1D0BC;BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS;So;0;L;;;;;N;;;;; 1D0BD;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI;So;0;L;;;;;N;;;;; 1D0BE;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI;So;0;L;;;;;N;;;;; 1D0BF;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE;So;0;L;;;;;N;;;;; 1D0C0;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO;So;0;L;;;;;N;;;;; 1D0C1;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO;So;0;L;;;;;N;;;;; 1D0C2;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO;So;0;L;;;;;N;;;;; 1D0C3;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS;So;0;L;;;;;N;;;;; 1D0C4;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS;So;0;L;;;;;N;;;;; 1D0C5;BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS;So;0;L;;;;;N;;;;; 1D0C6;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI;So;0;L;;;;;N;;;;; 1D0C7;BYZANTINE MUSICAL SYMBOL FTHORA NENANO;So;0;L;;;;;N;;;;; 1D0C8;BYZANTINE MUSICAL SYMBOL CHROA ZYGOS;So;0;L;;;;;N;;;;; 1D0C9;BYZANTINE MUSICAL SYMBOL CHROA KLITON;So;0;L;;;;;N;;;;; 1D0CA;BYZANTINE MUSICAL SYMBOL CHROA SPATHI;So;0;L;;;;;N;;;;; 1D0CB;BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION;So;0;L;;;;;N;;;;; 1D0CC;BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA;So;0;L;;;;;N;;;;; 1D0CD;BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION;So;0;L;;;;;N;;;;; 1D0CE;BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION;So;0;L;;;;;N;;;;; 1D0CF;BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION;So;0;L;;;;;N;;;;; 1D0D0;BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; 1D0D1;BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; 1D0D2;BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; 1D0D3;BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; 1D0D4;BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;; 1D0D5;BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;; 1D0D6;BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;; 1D0D7;BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;; 1D0D8;BYZANTINE MUSICAL SYMBOL GENIKI DIESIS;So;0;L;;;;;N;;;;; 1D0D9;BYZANTINE MUSICAL SYMBOL GENIKI YFESIS;So;0;L;;;;;N;;;;; 1D0DA;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI;So;0;L;;;;;N;;;;; 1D0DB;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI;So;0;L;;;;;N;;;;; 1D0DC;BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI;So;0;L;;;;;N;;;;; 1D0DD;BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS;So;0;L;;;;;N;;;;; 1D0DE;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS;So;0;L;;;;;N;;;;; 1D0DF;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU;So;0;L;;;;;N;;;;; 1D0E0;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU;So;0;L;;;;;N;;;;; 1D0E1;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU;So;0;L;;;;;N;;;;; 1D0E2;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS;So;0;L;;;;;N;;;;; 1D0E3;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU;So;0;L;;;;;N;;;;; 1D0E4;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU;So;0;L;;;;;N;;;;; 1D0E5;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU;So;0;L;;;;;N;;;;; 1D0E6;BYZANTINE MUSICAL SYMBOL DIGRAMMA GG;So;0;L;;;;;N;;;;; 1D0E7;BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU;So;0;L;;;;;N;;;;; 1D0E8;BYZANTINE MUSICAL SYMBOL STIGMA;So;0;L;;;;;N;;;;; 1D0E9;BYZANTINE MUSICAL SYMBOL ARKTIKO PA;So;0;L;;;;;N;;;;; 1D0EA;BYZANTINE MUSICAL SYMBOL ARKTIKO VOU;So;0;L;;;;;N;;;;; 1D0EB;BYZANTINE MUSICAL SYMBOL ARKTIKO GA;So;0;L;;;;;N;;;;; 1D0EC;BYZANTINE MUSICAL SYMBOL ARKTIKO DI;So;0;L;;;;;N;;;;; 1D0ED;BYZANTINE MUSICAL SYMBOL ARKTIKO KE;So;0;L;;;;;N;;;;; 1D0EE;BYZANTINE MUSICAL SYMBOL ARKTIKO ZO;So;0;L;;;;;N;;;;; 1D0EF;BYZANTINE MUSICAL SYMBOL ARKTIKO NI;So;0;L;;;;;N;;;;; 1D0F0;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO;So;0;L;;;;;N;;;;; 1D0F1;BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO;So;0;L;;;;;N;;;;; 1D0F2;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO;So;0;L;;;;;N;;;;; 1D0F3;BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO;So;0;L;;;;;N;;;;; 1D0F4;BYZANTINE MUSICAL SYMBOL KLASMA KATO;So;0;L;;;;;N;;;;; 1D0F5;BYZANTINE MUSICAL SYMBOL GORGON NEO KATO;So;0;L;;;;;N;;;;; 1D100;MUSICAL SYMBOL SINGLE BARLINE;So;0;L;;;;;N;;;;; 1D101;MUSICAL SYMBOL DOUBLE BARLINE;So;0;L;;;;;N;;;;; 1D102;MUSICAL SYMBOL FINAL BARLINE;So;0;L;;;;;N;;;;; 1D103;MUSICAL SYMBOL REVERSE FINAL BARLINE;So;0;L;;;;;N;;;;; 1D104;MUSICAL SYMBOL DASHED BARLINE;So;0;L;;;;;N;;;;; 1D105;MUSICAL SYMBOL SHORT BARLINE;So;0;L;;;;;N;;;;; 1D106;MUSICAL SYMBOL LEFT REPEAT SIGN;So;0;L;;;;;N;;;;; 1D107;MUSICAL SYMBOL RIGHT REPEAT SIGN;So;0;L;;;;;N;;;;; 1D108;MUSICAL SYMBOL REPEAT DOTS;So;0;L;;;;;N;;;;; 1D109;MUSICAL SYMBOL DAL SEGNO;So;0;L;;;;;N;;;;; 1D10A;MUSICAL SYMBOL DA CAPO;So;0;L;;;;;N;;;;; 1D10B;MUSICAL SYMBOL SEGNO;So;0;L;;;;;N;;;;; 1D10C;MUSICAL SYMBOL CODA;So;0;L;;;;;N;;;;; 1D10D;MUSICAL SYMBOL REPEATED FIGURE-1;So;0;L;;;;;N;;;;; 1D10E;MUSICAL SYMBOL REPEATED FIGURE-2;So;0;L;;;;;N;;;;; 1D10F;MUSICAL SYMBOL REPEATED FIGURE-3;So;0;L;;;;;N;;;;; 1D110;MUSICAL SYMBOL FERMATA;So;0;L;;;;;N;;;;; 1D111;MUSICAL SYMBOL FERMATA BELOW;So;0;L;;;;;N;;;;; 1D112;MUSICAL SYMBOL BREATH MARK;So;0;L;;;;;N;;;;; 1D113;MUSICAL SYMBOL CAESURA;So;0;L;;;;;N;;;;; 1D114;MUSICAL SYMBOL BRACE;So;0;L;;;;;N;;;;; 1D115;MUSICAL SYMBOL BRACKET;So;0;L;;;;;N;;;;; 1D116;MUSICAL SYMBOL ONE-LINE STAFF;So;0;L;;;;;N;;;;; 1D117;MUSICAL SYMBOL TWO-LINE STAFF;So;0;L;;;;;N;;;;; 1D118;MUSICAL SYMBOL THREE-LINE STAFF;So;0;L;;;;;N;;;;; 1D119;MUSICAL SYMBOL FOUR-LINE STAFF;So;0;L;;;;;N;;;;; 1D11A;MUSICAL SYMBOL FIVE-LINE STAFF;So;0;L;;;;;N;;;;; 1D11B;MUSICAL SYMBOL SIX-LINE STAFF;So;0;L;;;;;N;;;;; 1D11C;MUSICAL SYMBOL SIX-STRING FRETBOARD;So;0;L;;;;;N;;;;; 1D11D;MUSICAL SYMBOL FOUR-STRING FRETBOARD;So;0;L;;;;;N;;;;; 1D11E;MUSICAL SYMBOL G CLEF;So;0;L;;;;;N;;;;; 1D11F;MUSICAL SYMBOL G CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; 1D120;MUSICAL SYMBOL G CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; 1D121;MUSICAL SYMBOL C CLEF;So;0;L;;;;;N;;;;; 1D122;MUSICAL SYMBOL F CLEF;So;0;L;;;;;N;;;;; 1D123;MUSICAL SYMBOL F CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;; 1D124;MUSICAL SYMBOL F CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;; 1D125;MUSICAL SYMBOL DRUM CLEF-1;So;0;L;;;;;N;;;;; 1D126;MUSICAL SYMBOL DRUM CLEF-2;So;0;L;;;;;N;;;;; 1D12A;MUSICAL SYMBOL DOUBLE SHARP;So;0;L;;;;;N;;;;; 1D12B;MUSICAL SYMBOL DOUBLE FLAT;So;0;L;;;;;N;;;;; 1D12C;MUSICAL SYMBOL FLAT UP;So;0;L;;;;;N;;;;; 1D12D;MUSICAL SYMBOL FLAT DOWN;So;0;L;;;;;N;;;;; 1D12E;MUSICAL SYMBOL NATURAL UP;So;0;L;;;;;N;;;;; 1D12F;MUSICAL SYMBOL NATURAL DOWN;So;0;L;;;;;N;;;;; 1D130;MUSICAL SYMBOL SHARP UP;So;0;L;;;;;N;;;;; 1D131;MUSICAL SYMBOL SHARP DOWN;So;0;L;;;;;N;;;;; 1D132;MUSICAL SYMBOL QUARTER TONE SHARP;So;0;L;;;;;N;;;;; 1D133;MUSICAL SYMBOL QUARTER TONE FLAT;So;0;L;;;;;N;;;;; 1D134;MUSICAL SYMBOL COMMON TIME;So;0;L;;;;;N;;;;; 1D135;MUSICAL SYMBOL CUT TIME;So;0;L;;;;;N;;;;; 1D136;MUSICAL SYMBOL OTTAVA ALTA;So;0;L;;;;;N;;;;; 1D137;MUSICAL SYMBOL OTTAVA BASSA;So;0;L;;;;;N;;;;; 1D138;MUSICAL SYMBOL QUINDICESIMA ALTA;So;0;L;;;;;N;;;;; 1D139;MUSICAL SYMBOL QUINDICESIMA BASSA;So;0;L;;;;;N;;;;; 1D13A;MUSICAL SYMBOL MULTI REST;So;0;L;;;;;N;;;;; 1D13B;MUSICAL SYMBOL WHOLE REST;So;0;L;;;;;N;;;;; 1D13C;MUSICAL SYMBOL HALF REST;So;0;L;;;;;N;;;;; 1D13D;MUSICAL SYMBOL QUARTER REST;So;0;L;;;;;N;;;;; 1D13E;MUSICAL SYMBOL EIGHTH REST;So;0;L;;;;;N;;;;; 1D13F;MUSICAL SYMBOL SIXTEENTH REST;So;0;L;;;;;N;;;;; 1D140;MUSICAL SYMBOL THIRTY-SECOND REST;So;0;L;;;;;N;;;;; 1D141;MUSICAL SYMBOL SIXTY-FOURTH REST;So;0;L;;;;;N;;;;; 1D142;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST;So;0;L;;;;;N;;;;; 1D143;MUSICAL SYMBOL X NOTEHEAD;So;0;L;;;;;N;;;;; 1D144;MUSICAL SYMBOL PLUS NOTEHEAD;So;0;L;;;;;N;;;;; 1D145;MUSICAL SYMBOL CIRCLE X NOTEHEAD;So;0;L;;;;;N;;;;; 1D146;MUSICAL SYMBOL SQUARE NOTEHEAD WHITE;So;0;L;;;;;N;;;;; 1D147;MUSICAL SYMBOL SQUARE NOTEHEAD BLACK;So;0;L;;;;;N;;;;; 1D148;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE;So;0;L;;;;;N;;;;; 1D149;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK;So;0;L;;;;;N;;;;; 1D14A;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE;So;0;L;;;;;N;;;;; 1D14B;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK;So;0;L;;;;;N;;;;; 1D14C;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE;So;0;L;;;;;N;;;;; 1D14D;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK;So;0;L;;;;;N;;;;; 1D14E;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; 1D14F;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; 1D150;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE;So;0;L;;;;;N;;;;; 1D151;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK;So;0;L;;;;;N;;;;; 1D152;MUSICAL SYMBOL MOON NOTEHEAD WHITE;So;0;L;;;;;N;;;;; 1D153;MUSICAL SYMBOL MOON NOTEHEAD BLACK;So;0;L;;;;;N;;;;; 1D154;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;; 1D155;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;; 1D156;MUSICAL SYMBOL PARENTHESIS NOTEHEAD;So;0;L;;;;;N;;;;; 1D157;MUSICAL SYMBOL VOID NOTEHEAD;So;0;L;;;;;N;;;;; 1D158;MUSICAL SYMBOL NOTEHEAD BLACK;So;0;L;;;;;N;;;;; 1D159;MUSICAL SYMBOL NULL NOTEHEAD;So;0;L;;;;;N;;;;; 1D15A;MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE;So;0;L;;;;;N;;;;; 1D15B;MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK;So;0;L;;;;;N;;;;; 1D15C;MUSICAL SYMBOL BREVE;So;0;L;;;;;N;;;;; 1D15D;MUSICAL SYMBOL WHOLE NOTE;So;0;L;;;;;N;;;;; 1D15E;MUSICAL SYMBOL HALF NOTE;So;0;L;1D157 1D165;;;;N;;;;; 1D15F;MUSICAL SYMBOL QUARTER NOTE;So;0;L;1D158 1D165;;;;N;;;;; 1D160;MUSICAL SYMBOL EIGHTH NOTE;So;0;L;1D15F 1D16E;;;;N;;;;; 1D161;MUSICAL SYMBOL SIXTEENTH NOTE;So;0;L;1D15F 1D16F;;;;N;;;;; 1D162;MUSICAL SYMBOL THIRTY-SECOND NOTE;So;0;L;1D15F 1D170;;;;N;;;;; 1D163;MUSICAL SYMBOL SIXTY-FOURTH NOTE;So;0;L;1D15F 1D171;;;;N;;;;; 1D164;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE;So;0;L;1D15F 1D172;;;;N;;;;; 1D165;MUSICAL SYMBOL COMBINING STEM;Mc;216;L;;;;;N;;;;; 1D166;MUSICAL SYMBOL COMBINING SPRECHGESANG STEM;Mc;216;L;;;;;N;;;;; 1D167;MUSICAL SYMBOL COMBINING TREMOLO-1;Mn;1;NSM;;;;;N;;;;; 1D168;MUSICAL SYMBOL COMBINING TREMOLO-2;Mn;1;NSM;;;;;N;;;;; 1D169;MUSICAL SYMBOL COMBINING TREMOLO-3;Mn;1;NSM;;;;;N;;;;; 1D16A;MUSICAL SYMBOL FINGERED TREMOLO-1;So;0;L;;;;;N;;;;; 1D16B;MUSICAL SYMBOL FINGERED TREMOLO-2;So;0;L;;;;;N;;;;; 1D16C;MUSICAL SYMBOL FINGERED TREMOLO-3;So;0;L;;;;;N;;;;; 1D16D;MUSICAL SYMBOL COMBINING AUGMENTATION DOT;Mc;226;L;;;;;N;;;;; 1D16E;MUSICAL SYMBOL COMBINING FLAG-1;Mc;216;L;;;;;N;;;;; 1D16F;MUSICAL SYMBOL COMBINING FLAG-2;Mc;216;L;;;;;N;;;;; 1D170;MUSICAL SYMBOL COMBINING FLAG-3;Mc;216;L;;;;;N;;;;; 1D171;MUSICAL SYMBOL COMBINING FLAG-4;Mc;216;L;;;;;N;;;;; 1D172;MUSICAL SYMBOL COMBINING FLAG-5;Mc;216;L;;;;;N;;;;; 1D173;MUSICAL SYMBOL BEGIN BEAM;Cf;0;BN;;;;;N;;;;; 1D174;MUSICAL SYMBOL END BEAM;Cf;0;BN;;;;;N;;;;; 1D175;MUSICAL SYMBOL BEGIN TIE;Cf;0;BN;;;;;N;;;;; 1D176;MUSICAL SYMBOL END TIE;Cf;0;BN;;;;;N;;;;; 1D177;MUSICAL SYMBOL BEGIN SLUR;Cf;0;BN;;;;;N;;;;; 1D178;MUSICAL SYMBOL END SLUR;Cf;0;BN;;;;;N;;;;; 1D179;MUSICAL SYMBOL BEGIN PHRASE;Cf;0;BN;;;;;N;;;;; 1D17A;MUSICAL SYMBOL END PHRASE;Cf;0;BN;;;;;N;;;;; 1D17B;MUSICAL SYMBOL COMBINING ACCENT;Mn;220;NSM;;;;;N;;;;; 1D17C;MUSICAL SYMBOL COMBINING STACCATO;Mn;220;NSM;;;;;N;;;;; 1D17D;MUSICAL SYMBOL COMBINING TENUTO;Mn;220;NSM;;;;;N;;;;; 1D17E;MUSICAL SYMBOL COMBINING STACCATISSIMO;Mn;220;NSM;;;;;N;;;;; 1D17F;MUSICAL SYMBOL COMBINING MARCATO;Mn;220;NSM;;;;;N;;;;; 1D180;MUSICAL SYMBOL COMBINING MARCATO-STACCATO;Mn;220;NSM;;;;;N;;;;; 1D181;MUSICAL SYMBOL COMBINING ACCENT-STACCATO;Mn;220;NSM;;;;;N;;;;; 1D182;MUSICAL SYMBOL COMBINING LOURE;Mn;220;NSM;;;;;N;;;;; 1D183;MUSICAL SYMBOL ARPEGGIATO UP;So;0;L;;;;;N;;;;; 1D184;MUSICAL SYMBOL ARPEGGIATO DOWN;So;0;L;;;;;N;;;;; 1D185;MUSICAL SYMBOL COMBINING DOIT;Mn;230;NSM;;;;;N;;;;; 1D186;MUSICAL SYMBOL COMBINING RIP;Mn;230;NSM;;;;;N;;;;; 1D187;MUSICAL SYMBOL COMBINING FLIP;Mn;230;NSM;;;;;N;;;;; 1D188;MUSICAL SYMBOL COMBINING SMEAR;Mn;230;NSM;;;;;N;;;;; 1D189;MUSICAL SYMBOL COMBINING BEND;Mn;230;NSM;;;;;N;;;;; 1D18A;MUSICAL SYMBOL COMBINING DOUBLE TONGUE;Mn;220;NSM;;;;;N;;;;; 1D18B;MUSICAL SYMBOL COMBINING TRIPLE TONGUE;Mn;220;NSM;;;;;N;;;;; 1D18C;MUSICAL SYMBOL RINFORZANDO;So;0;L;;;;;N;;;;; 1D18D;MUSICAL SYMBOL SUBITO;So;0;L;;;;;N;;;;; 1D18E;MUSICAL SYMBOL Z;So;0;L;;;;;N;;;;; 1D18F;MUSICAL SYMBOL PIANO;So;0;L;;;;;N;;;;; 1D190;MUSICAL SYMBOL MEZZO;So;0;L;;;;;N;;;;; 1D191;MUSICAL SYMBOL FORTE;So;0;L;;;;;N;;;;; 1D192;MUSICAL SYMBOL CRESCENDO;So;0;L;;;;;N;;;;; 1D193;MUSICAL SYMBOL DECRESCENDO;So;0;L;;;;;N;;;;; 1D194;MUSICAL SYMBOL GRACE NOTE SLASH;So;0;L;;;;;N;;;;; 1D195;MUSICAL SYMBOL GRACE NOTE NO SLASH;So;0;L;;;;;N;;;;; 1D196;MUSICAL SYMBOL TR;So;0;L;;;;;N;;;;; 1D197;MUSICAL SYMBOL TURN;So;0;L;;;;;N;;;;; 1D198;MUSICAL SYMBOL INVERTED TURN;So;0;L;;;;;N;;;;; 1D199;MUSICAL SYMBOL TURN SLASH;So;0;L;;;;;N;;;;; 1D19A;MUSICAL SYMBOL TURN UP;So;0;L;;;;;N;;;;; 1D19B;MUSICAL SYMBOL ORNAMENT STROKE-1;So;0;L;;;;;N;;;;; 1D19C;MUSICAL SYMBOL ORNAMENT STROKE-2;So;0;L;;;;;N;;;;; 1D19D;MUSICAL SYMBOL ORNAMENT STROKE-3;So;0;L;;;;;N;;;;; 1D19E;MUSICAL SYMBOL ORNAMENT STROKE-4;So;0;L;;;;;N;;;;; 1D19F;MUSICAL SYMBOL ORNAMENT STROKE-5;So;0;L;;;;;N;;;;; 1D1A0;MUSICAL SYMBOL ORNAMENT STROKE-6;So;0;L;;;;;N;;;;; 1D1A1;MUSICAL SYMBOL ORNAMENT STROKE-7;So;0;L;;;;;N;;;;; 1D1A2;MUSICAL SYMBOL ORNAMENT STROKE-8;So;0;L;;;;;N;;;;; 1D1A3;MUSICAL SYMBOL ORNAMENT STROKE-9;So;0;L;;;;;N;;;;; 1D1A4;MUSICAL SYMBOL ORNAMENT STROKE-10;So;0;L;;;;;N;;;;; 1D1A5;MUSICAL SYMBOL ORNAMENT STROKE-11;So;0;L;;;;;N;;;;; 1D1A6;MUSICAL SYMBOL HAUPTSTIMME;So;0;L;;;;;N;;;;; 1D1A7;MUSICAL SYMBOL NEBENSTIMME;So;0;L;;;;;N;;;;; 1D1A8;MUSICAL SYMBOL END OF STIMME;So;0;L;;;;;N;;;;; 1D1A9;MUSICAL SYMBOL DEGREE SLASH;So;0;L;;;;;N;;;;; 1D1AA;MUSICAL SYMBOL COMBINING DOWN BOW;Mn;230;NSM;;;;;N;;;;; 1D1AB;MUSICAL SYMBOL COMBINING UP BOW;Mn;230;NSM;;;;;N;;;;; 1D1AC;MUSICAL SYMBOL COMBINING HARMONIC;Mn;230;NSM;;;;;N;;;;; 1D1AD;MUSICAL SYMBOL COMBINING SNAP PIZZICATO;Mn;230;NSM;;;;;N;;;;; 1D1AE;MUSICAL SYMBOL PEDAL MARK;So;0;L;;;;;N;;;;; 1D1AF;MUSICAL SYMBOL PEDAL UP MARK;So;0;L;;;;;N;;;;; 1D1B0;MUSICAL SYMBOL HALF PEDAL MARK;So;0;L;;;;;N;;;;; 1D1B1;MUSICAL SYMBOL GLISSANDO UP;So;0;L;;;;;N;;;;; 1D1B2;MUSICAL SYMBOL GLISSANDO DOWN;So;0;L;;;;;N;;;;; 1D1B3;MUSICAL SYMBOL WITH FINGERNAILS;So;0;L;;;;;N;;;;; 1D1B4;MUSICAL SYMBOL DAMP;So;0;L;;;;;N;;;;; 1D1B5;MUSICAL SYMBOL DAMP ALL;So;0;L;;;;;N;;;;; 1D1B6;MUSICAL SYMBOL MAXIMA;So;0;L;;;;;N;;;;; 1D1B7;MUSICAL SYMBOL LONGA;So;0;L;;;;;N;;;;; 1D1B8;MUSICAL SYMBOL BREVIS;So;0;L;;;;;N;;;;; 1D1B9;MUSICAL SYMBOL SEMIBREVIS WHITE;So;0;L;;;;;N;;;;; 1D1BA;MUSICAL SYMBOL SEMIBREVIS BLACK;So;0;L;;;;;N;;;;; 1D1BB;MUSICAL SYMBOL MINIMA;So;0;L;1D1B9 1D165;;;;N;;;;; 1D1BC;MUSICAL SYMBOL MINIMA BLACK;So;0;L;1D1BA 1D165;;;;N;;;;; 1D1BD;MUSICAL SYMBOL SEMIMINIMA WHITE;So;0;L;1D1BB 1D16E;;;;N;;;;; 1D1BE;MUSICAL SYMBOL SEMIMINIMA BLACK;So;0;L;1D1BC 1D16E;;;;N;;;;; 1D1BF;MUSICAL SYMBOL FUSA WHITE;So;0;L;1D1BB 1D16F;;;;N;;;;; 1D1C0;MUSICAL SYMBOL FUSA BLACK;So;0;L;1D1BC 1D16F;;;;N;;;;; 1D1C1;MUSICAL SYMBOL LONGA PERFECTA REST;So;0;L;;;;;N;;;;; 1D1C2;MUSICAL SYMBOL LONGA IMPERFECTA REST;So;0;L;;;;;N;;;;; 1D1C3;MUSICAL SYMBOL BREVIS REST;So;0;L;;;;;N;;;;; 1D1C4;MUSICAL SYMBOL SEMIBREVIS REST;So;0;L;;;;;N;;;;; 1D1C5;MUSICAL SYMBOL MINIMA REST;So;0;L;;;;;N;;;;; 1D1C6;MUSICAL SYMBOL SEMIMINIMA REST;So;0;L;;;;;N;;;;; 1D1C7;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; 1D1C8;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; 1D1C9;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; 1D1CA;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;; 1D1CB;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;; 1D1CC;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;; 1D1CD;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2;So;0;L;;;;;N;;;;; 1D1CE;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3;So;0;L;;;;;N;;;;; 1D1CF;MUSICAL SYMBOL CROIX;So;0;L;;;;;N;;;;; 1D1D0;MUSICAL SYMBOL GREGORIAN C CLEF;So;0;L;;;;;N;;;;; 1D1D1;MUSICAL SYMBOL GREGORIAN F CLEF;So;0;L;;;;;N;;;;; 1D1D2;MUSICAL SYMBOL SQUARE B;So;0;L;;;;;N;;;;; 1D1D3;MUSICAL SYMBOL VIRGA;So;0;L;;;;;N;;;;; 1D1D4;MUSICAL SYMBOL PODATUS;So;0;L;;;;;N;;;;; 1D1D5;MUSICAL SYMBOL CLIVIS;So;0;L;;;;;N;;;;; 1D1D6;MUSICAL SYMBOL SCANDICUS;So;0;L;;;;;N;;;;; 1D1D7;MUSICAL SYMBOL CLIMACUS;So;0;L;;;;;N;;;;; 1D1D8;MUSICAL SYMBOL TORCULUS;So;0;L;;;;;N;;;;; 1D1D9;MUSICAL SYMBOL PORRECTUS;So;0;L;;;;;N;;;;; 1D1DA;MUSICAL SYMBOL PORRECTUS FLEXUS;So;0;L;;;;;N;;;;; 1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;; 1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;; 1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;; 1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D403;MATHEMATICAL BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D404;MATHEMATICAL BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D405;MATHEMATICAL BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D406;MATHEMATICAL BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D407;MATHEMATICAL BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D408;MATHEMATICAL BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D409;MATHEMATICAL BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D40A;MATHEMATICAL BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D40B;MATHEMATICAL BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D40C;MATHEMATICAL BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D40D;MATHEMATICAL BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D40E;MATHEMATICAL BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D40F;MATHEMATICAL BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D410;MATHEMATICAL BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D411;MATHEMATICAL BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D412;MATHEMATICAL BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D413;MATHEMATICAL BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D414;MATHEMATICAL BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D415;MATHEMATICAL BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D416;MATHEMATICAL BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D417;MATHEMATICAL BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D418;MATHEMATICAL BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D419;MATHEMATICAL BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D41A;MATHEMATICAL BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D41B;MATHEMATICAL BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D41C;MATHEMATICAL BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D41D;MATHEMATICAL BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D41E;MATHEMATICAL BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D41F;MATHEMATICAL BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D420;MATHEMATICAL BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D421;MATHEMATICAL BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D422;MATHEMATICAL BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D423;MATHEMATICAL BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D424;MATHEMATICAL BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D425;MATHEMATICAL BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D426;MATHEMATICAL BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D427;MATHEMATICAL BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D428;MATHEMATICAL BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D429;MATHEMATICAL BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D42A;MATHEMATICAL BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D42B;MATHEMATICAL BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D42C;MATHEMATICAL BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D42D;MATHEMATICAL BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D42E;MATHEMATICAL BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D42F;MATHEMATICAL BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D430;MATHEMATICAL BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D431;MATHEMATICAL BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D432;MATHEMATICAL BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D433;MATHEMATICAL BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D434;MATHEMATICAL ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D435;MATHEMATICAL ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D436;MATHEMATICAL ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D437;MATHEMATICAL ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D438;MATHEMATICAL ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D439;MATHEMATICAL ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D43A;MATHEMATICAL ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D43B;MATHEMATICAL ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D43C;MATHEMATICAL ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D43D;MATHEMATICAL ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D43E;MATHEMATICAL ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D43F;MATHEMATICAL ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D440;MATHEMATICAL ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D441;MATHEMATICAL ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D442;MATHEMATICAL ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D443;MATHEMATICAL ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D444;MATHEMATICAL ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D445;MATHEMATICAL ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D446;MATHEMATICAL ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D447;MATHEMATICAL ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D448;MATHEMATICAL ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D449;MATHEMATICAL ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D44A;MATHEMATICAL ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D44B;MATHEMATICAL ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D44C;MATHEMATICAL ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D44D;MATHEMATICAL ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D44E;MATHEMATICAL ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D44F;MATHEMATICAL ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D450;MATHEMATICAL ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D451;MATHEMATICAL ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D452;MATHEMATICAL ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D453;MATHEMATICAL ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D454;MATHEMATICAL ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D456;MATHEMATICAL ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D457;MATHEMATICAL ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D458;MATHEMATICAL ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D459;MATHEMATICAL ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D45A;MATHEMATICAL ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D45B;MATHEMATICAL ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D45C;MATHEMATICAL ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D45D;MATHEMATICAL ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D45E;MATHEMATICAL ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D45F;MATHEMATICAL ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D460;MATHEMATICAL ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D461;MATHEMATICAL ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D462;MATHEMATICAL ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D463;MATHEMATICAL ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D464;MATHEMATICAL ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D465;MATHEMATICAL ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D466;MATHEMATICAL ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D467;MATHEMATICAL ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D468;MATHEMATICAL BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D469;MATHEMATICAL BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D46A;MATHEMATICAL BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D46B;MATHEMATICAL BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D46C;MATHEMATICAL BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D46D;MATHEMATICAL BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D46E;MATHEMATICAL BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D46F;MATHEMATICAL BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D470;MATHEMATICAL BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D471;MATHEMATICAL BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D472;MATHEMATICAL BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D473;MATHEMATICAL BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D474;MATHEMATICAL BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D475;MATHEMATICAL BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D476;MATHEMATICAL BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D477;MATHEMATICAL BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D478;MATHEMATICAL BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D479;MATHEMATICAL BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D47A;MATHEMATICAL BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D47B;MATHEMATICAL BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D47C;MATHEMATICAL BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D47D;MATHEMATICAL BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D47E;MATHEMATICAL BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D47F;MATHEMATICAL BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D480;MATHEMATICAL BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D481;MATHEMATICAL BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D482;MATHEMATICAL BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D483;MATHEMATICAL BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D484;MATHEMATICAL BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D485;MATHEMATICAL BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D486;MATHEMATICAL BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D487;MATHEMATICAL BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D488;MATHEMATICAL BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D489;MATHEMATICAL BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D48A;MATHEMATICAL BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D48B;MATHEMATICAL BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D48C;MATHEMATICAL BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D48D;MATHEMATICAL BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D48E;MATHEMATICAL BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D48F;MATHEMATICAL BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D490;MATHEMATICAL BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D491;MATHEMATICAL BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D492;MATHEMATICAL BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D493;MATHEMATICAL BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D494;MATHEMATICAL BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D495;MATHEMATICAL BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D496;MATHEMATICAL BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D497;MATHEMATICAL BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D498;MATHEMATICAL BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D499;MATHEMATICAL BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D49A;MATHEMATICAL BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D49B;MATHEMATICAL BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D49C;MATHEMATICAL SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D49E;MATHEMATICAL SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D49F;MATHEMATICAL SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D4A2;MATHEMATICAL SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D4A5;MATHEMATICAL SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D4A6;MATHEMATICAL SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D4A9;MATHEMATICAL SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D4AA;MATHEMATICAL SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D4AB;MATHEMATICAL SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D4AC;MATHEMATICAL SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D4AE;MATHEMATICAL SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D4AF;MATHEMATICAL SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D4B0;MATHEMATICAL SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D4B1;MATHEMATICAL SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D4B2;MATHEMATICAL SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D4B3;MATHEMATICAL SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D4B4;MATHEMATICAL SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D4B5;MATHEMATICAL SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D4B6;MATHEMATICAL SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D4B7;MATHEMATICAL SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D4B8;MATHEMATICAL SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D4B9;MATHEMATICAL SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D4BB;MATHEMATICAL SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D4BD;MATHEMATICAL SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D4BE;MATHEMATICAL SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D4BF;MATHEMATICAL SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D4C0;MATHEMATICAL SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D4C2;MATHEMATICAL SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D4C3;MATHEMATICAL SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D4C5;MATHEMATICAL SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D4C6;MATHEMATICAL SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D4C7;MATHEMATICAL SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D4C8;MATHEMATICAL SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D4C9;MATHEMATICAL SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D4CA;MATHEMATICAL SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D4CB;MATHEMATICAL SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D4CC;MATHEMATICAL SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D4CD;MATHEMATICAL SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D4CE;MATHEMATICAL SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D4CF;MATHEMATICAL SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D4D0;MATHEMATICAL BOLD SCRIPT CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D4D1;MATHEMATICAL BOLD SCRIPT CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D4D2;MATHEMATICAL BOLD SCRIPT CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D4D3;MATHEMATICAL BOLD SCRIPT CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D4D4;MATHEMATICAL BOLD SCRIPT CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D4D5;MATHEMATICAL BOLD SCRIPT CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D4D6;MATHEMATICAL BOLD SCRIPT CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D4D7;MATHEMATICAL BOLD SCRIPT CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D4D8;MATHEMATICAL BOLD SCRIPT CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D4D9;MATHEMATICAL BOLD SCRIPT CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D4DA;MATHEMATICAL BOLD SCRIPT CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D4DB;MATHEMATICAL BOLD SCRIPT CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D4DC;MATHEMATICAL BOLD SCRIPT CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D4DD;MATHEMATICAL BOLD SCRIPT CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D4DE;MATHEMATICAL BOLD SCRIPT CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D4DF;MATHEMATICAL BOLD SCRIPT CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D4E0;MATHEMATICAL BOLD SCRIPT CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D4E1;MATHEMATICAL BOLD SCRIPT CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D4E2;MATHEMATICAL BOLD SCRIPT CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D4E3;MATHEMATICAL BOLD SCRIPT CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D4E4;MATHEMATICAL BOLD SCRIPT CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D4E5;MATHEMATICAL BOLD SCRIPT CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D4E6;MATHEMATICAL BOLD SCRIPT CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D4E7;MATHEMATICAL BOLD SCRIPT CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D4E8;MATHEMATICAL BOLD SCRIPT CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D4E9;MATHEMATICAL BOLD SCRIPT CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D4EA;MATHEMATICAL BOLD SCRIPT SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D4EB;MATHEMATICAL BOLD SCRIPT SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D4EC;MATHEMATICAL BOLD SCRIPT SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D4ED;MATHEMATICAL BOLD SCRIPT SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D4EE;MATHEMATICAL BOLD SCRIPT SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D4EF;MATHEMATICAL BOLD SCRIPT SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D4F0;MATHEMATICAL BOLD SCRIPT SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D4F1;MATHEMATICAL BOLD SCRIPT SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D4F2;MATHEMATICAL BOLD SCRIPT SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D4F3;MATHEMATICAL BOLD SCRIPT SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D4F4;MATHEMATICAL BOLD SCRIPT SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D4F5;MATHEMATICAL BOLD SCRIPT SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D4F6;MATHEMATICAL BOLD SCRIPT SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D4F7;MATHEMATICAL BOLD SCRIPT SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D4F8;MATHEMATICAL BOLD SCRIPT SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D4F9;MATHEMATICAL BOLD SCRIPT SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D4FA;MATHEMATICAL BOLD SCRIPT SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D4FB;MATHEMATICAL BOLD SCRIPT SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D4FC;MATHEMATICAL BOLD SCRIPT SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D4FD;MATHEMATICAL BOLD SCRIPT SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D4FE;MATHEMATICAL BOLD SCRIPT SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D4FF;MATHEMATICAL BOLD SCRIPT SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D500;MATHEMATICAL BOLD SCRIPT SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D501;MATHEMATICAL BOLD SCRIPT SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D502;MATHEMATICAL BOLD SCRIPT SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D503;MATHEMATICAL BOLD SCRIPT SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D504;MATHEMATICAL FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D505;MATHEMATICAL FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D507;MATHEMATICAL FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D508;MATHEMATICAL FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D509;MATHEMATICAL FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D50A;MATHEMATICAL FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D50D;MATHEMATICAL FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D50E;MATHEMATICAL FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D50F;MATHEMATICAL FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D510;MATHEMATICAL FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D511;MATHEMATICAL FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D512;MATHEMATICAL FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D513;MATHEMATICAL FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D514;MATHEMATICAL FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D516;MATHEMATICAL FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D517;MATHEMATICAL FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D518;MATHEMATICAL FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D519;MATHEMATICAL FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D51A;MATHEMATICAL FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D51B;MATHEMATICAL FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D51C;MATHEMATICAL FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D51E;MATHEMATICAL FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D51F;MATHEMATICAL FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D520;MATHEMATICAL FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D521;MATHEMATICAL FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D522;MATHEMATICAL FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D523;MATHEMATICAL FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D524;MATHEMATICAL FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D525;MATHEMATICAL FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D526;MATHEMATICAL FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D527;MATHEMATICAL FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D528;MATHEMATICAL FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D529;MATHEMATICAL FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D52A;MATHEMATICAL FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D52B;MATHEMATICAL FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D52C;MATHEMATICAL FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D52D;MATHEMATICAL FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D52E;MATHEMATICAL FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D52F;MATHEMATICAL FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D530;MATHEMATICAL FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D531;MATHEMATICAL FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D532;MATHEMATICAL FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D533;MATHEMATICAL FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D534;MATHEMATICAL FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D535;MATHEMATICAL FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D536;MATHEMATICAL FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D537;MATHEMATICAL FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D538;MATHEMATICAL DOUBLE-STRUCK CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D539;MATHEMATICAL DOUBLE-STRUCK CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D53B;MATHEMATICAL DOUBLE-STRUCK CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D53C;MATHEMATICAL DOUBLE-STRUCK CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D53D;MATHEMATICAL DOUBLE-STRUCK CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D53E;MATHEMATICAL DOUBLE-STRUCK CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D540;MATHEMATICAL DOUBLE-STRUCK CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D541;MATHEMATICAL DOUBLE-STRUCK CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D542;MATHEMATICAL DOUBLE-STRUCK CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D543;MATHEMATICAL DOUBLE-STRUCK CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D544;MATHEMATICAL DOUBLE-STRUCK CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D546;MATHEMATICAL DOUBLE-STRUCK CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D54A;MATHEMATICAL DOUBLE-STRUCK CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D54B;MATHEMATICAL DOUBLE-STRUCK CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D54C;MATHEMATICAL DOUBLE-STRUCK CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D54D;MATHEMATICAL DOUBLE-STRUCK CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D54E;MATHEMATICAL DOUBLE-STRUCK CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D54F;MATHEMATICAL DOUBLE-STRUCK CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D550;MATHEMATICAL DOUBLE-STRUCK CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D552;MATHEMATICAL DOUBLE-STRUCK SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D553;MATHEMATICAL DOUBLE-STRUCK SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D554;MATHEMATICAL DOUBLE-STRUCK SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D555;MATHEMATICAL DOUBLE-STRUCK SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D556;MATHEMATICAL DOUBLE-STRUCK SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D557;MATHEMATICAL DOUBLE-STRUCK SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D558;MATHEMATICAL DOUBLE-STRUCK SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D559;MATHEMATICAL DOUBLE-STRUCK SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D55A;MATHEMATICAL DOUBLE-STRUCK SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D55B;MATHEMATICAL DOUBLE-STRUCK SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D55C;MATHEMATICAL DOUBLE-STRUCK SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D55D;MATHEMATICAL DOUBLE-STRUCK SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D55E;MATHEMATICAL DOUBLE-STRUCK SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D55F;MATHEMATICAL DOUBLE-STRUCK SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D560;MATHEMATICAL DOUBLE-STRUCK SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D561;MATHEMATICAL DOUBLE-STRUCK SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D562;MATHEMATICAL DOUBLE-STRUCK SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D563;MATHEMATICAL DOUBLE-STRUCK SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D564;MATHEMATICAL DOUBLE-STRUCK SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D565;MATHEMATICAL DOUBLE-STRUCK SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D566;MATHEMATICAL DOUBLE-STRUCK SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D567;MATHEMATICAL DOUBLE-STRUCK SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D568;MATHEMATICAL DOUBLE-STRUCK SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D569;MATHEMATICAL DOUBLE-STRUCK SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D56A;MATHEMATICAL DOUBLE-STRUCK SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D56B;MATHEMATICAL DOUBLE-STRUCK SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D56C;MATHEMATICAL BOLD FRAKTUR CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D56D;MATHEMATICAL BOLD FRAKTUR CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D56E;MATHEMATICAL BOLD FRAKTUR CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D56F;MATHEMATICAL BOLD FRAKTUR CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D570;MATHEMATICAL BOLD FRAKTUR CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D571;MATHEMATICAL BOLD FRAKTUR CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D572;MATHEMATICAL BOLD FRAKTUR CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D573;MATHEMATICAL BOLD FRAKTUR CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D574;MATHEMATICAL BOLD FRAKTUR CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D575;MATHEMATICAL BOLD FRAKTUR CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D576;MATHEMATICAL BOLD FRAKTUR CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D577;MATHEMATICAL BOLD FRAKTUR CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D578;MATHEMATICAL BOLD FRAKTUR CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D579;MATHEMATICAL BOLD FRAKTUR CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D57A;MATHEMATICAL BOLD FRAKTUR CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D57B;MATHEMATICAL BOLD FRAKTUR CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D57C;MATHEMATICAL BOLD FRAKTUR CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D57D;MATHEMATICAL BOLD FRAKTUR CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D57E;MATHEMATICAL BOLD FRAKTUR CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D57F;MATHEMATICAL BOLD FRAKTUR CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D580;MATHEMATICAL BOLD FRAKTUR CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D581;MATHEMATICAL BOLD FRAKTUR CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D582;MATHEMATICAL BOLD FRAKTUR CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D583;MATHEMATICAL BOLD FRAKTUR CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D584;MATHEMATICAL BOLD FRAKTUR CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D585;MATHEMATICAL BOLD FRAKTUR CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D586;MATHEMATICAL BOLD FRAKTUR SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D587;MATHEMATICAL BOLD FRAKTUR SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D588;MATHEMATICAL BOLD FRAKTUR SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D589;MATHEMATICAL BOLD FRAKTUR SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D58A;MATHEMATICAL BOLD FRAKTUR SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D58B;MATHEMATICAL BOLD FRAKTUR SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D58C;MATHEMATICAL BOLD FRAKTUR SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D58D;MATHEMATICAL BOLD FRAKTUR SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D58E;MATHEMATICAL BOLD FRAKTUR SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D58F;MATHEMATICAL BOLD FRAKTUR SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D590;MATHEMATICAL BOLD FRAKTUR SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D591;MATHEMATICAL BOLD FRAKTUR SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D592;MATHEMATICAL BOLD FRAKTUR SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D593;MATHEMATICAL BOLD FRAKTUR SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D594;MATHEMATICAL BOLD FRAKTUR SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D595;MATHEMATICAL BOLD FRAKTUR SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D596;MATHEMATICAL BOLD FRAKTUR SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D597;MATHEMATICAL BOLD FRAKTUR SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D598;MATHEMATICAL BOLD FRAKTUR SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D599;MATHEMATICAL BOLD FRAKTUR SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D59A;MATHEMATICAL BOLD FRAKTUR SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D59B;MATHEMATICAL BOLD FRAKTUR SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D59C;MATHEMATICAL BOLD FRAKTUR SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D59D;MATHEMATICAL BOLD FRAKTUR SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D59E;MATHEMATICAL BOLD FRAKTUR SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D59F;MATHEMATICAL BOLD FRAKTUR SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D5A0;MATHEMATICAL SANS-SERIF CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D5A1;MATHEMATICAL SANS-SERIF CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D5A2;MATHEMATICAL SANS-SERIF CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D5A3;MATHEMATICAL SANS-SERIF CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D5A4;MATHEMATICAL SANS-SERIF CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D5A5;MATHEMATICAL SANS-SERIF CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D5A6;MATHEMATICAL SANS-SERIF CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D5A7;MATHEMATICAL SANS-SERIF CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D5A8;MATHEMATICAL SANS-SERIF CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D5A9;MATHEMATICAL SANS-SERIF CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D5AA;MATHEMATICAL SANS-SERIF CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D5AB;MATHEMATICAL SANS-SERIF CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D5AC;MATHEMATICAL SANS-SERIF CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D5AD;MATHEMATICAL SANS-SERIF CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D5AE;MATHEMATICAL SANS-SERIF CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D5AF;MATHEMATICAL SANS-SERIF CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D5B0;MATHEMATICAL SANS-SERIF CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D5B1;MATHEMATICAL SANS-SERIF CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D5B2;MATHEMATICAL SANS-SERIF CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D5B3;MATHEMATICAL SANS-SERIF CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D5B4;MATHEMATICAL SANS-SERIF CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D5B5;MATHEMATICAL SANS-SERIF CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D5B6;MATHEMATICAL SANS-SERIF CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D5B7;MATHEMATICAL SANS-SERIF CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D5B8;MATHEMATICAL SANS-SERIF CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D5B9;MATHEMATICAL SANS-SERIF CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D5BA;MATHEMATICAL SANS-SERIF SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D5BB;MATHEMATICAL SANS-SERIF SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D5BC;MATHEMATICAL SANS-SERIF SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D5BD;MATHEMATICAL SANS-SERIF SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D5BE;MATHEMATICAL SANS-SERIF SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D5BF;MATHEMATICAL SANS-SERIF SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D5C0;MATHEMATICAL SANS-SERIF SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D5C1;MATHEMATICAL SANS-SERIF SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D5C2;MATHEMATICAL SANS-SERIF SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D5C3;MATHEMATICAL SANS-SERIF SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D5C4;MATHEMATICAL SANS-SERIF SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D5C5;MATHEMATICAL SANS-SERIF SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D5C6;MATHEMATICAL SANS-SERIF SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D5C7;MATHEMATICAL SANS-SERIF SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D5C8;MATHEMATICAL SANS-SERIF SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D5C9;MATHEMATICAL SANS-SERIF SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D5CA;MATHEMATICAL SANS-SERIF SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D5CB;MATHEMATICAL SANS-SERIF SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D5CC;MATHEMATICAL SANS-SERIF SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D5CD;MATHEMATICAL SANS-SERIF SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D5CE;MATHEMATICAL SANS-SERIF SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D5CF;MATHEMATICAL SANS-SERIF SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D5D0;MATHEMATICAL SANS-SERIF SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D5D1;MATHEMATICAL SANS-SERIF SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D5D2;MATHEMATICAL SANS-SERIF SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D5D3;MATHEMATICAL SANS-SERIF SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D5D4;MATHEMATICAL SANS-SERIF BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D5D5;MATHEMATICAL SANS-SERIF BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D5D6;MATHEMATICAL SANS-SERIF BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D5D7;MATHEMATICAL SANS-SERIF BOLD CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D5D8;MATHEMATICAL SANS-SERIF BOLD CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D5D9;MATHEMATICAL SANS-SERIF BOLD CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D5DA;MATHEMATICAL SANS-SERIF BOLD CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D5DB;MATHEMATICAL SANS-SERIF BOLD CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D5DC;MATHEMATICAL SANS-SERIF BOLD CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D5DD;MATHEMATICAL SANS-SERIF BOLD CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D5DE;MATHEMATICAL SANS-SERIF BOLD CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D5DF;MATHEMATICAL SANS-SERIF BOLD CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D5E0;MATHEMATICAL SANS-SERIF BOLD CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D5E1;MATHEMATICAL SANS-SERIF BOLD CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D5E2;MATHEMATICAL SANS-SERIF BOLD CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D5E3;MATHEMATICAL SANS-SERIF BOLD CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D5E4;MATHEMATICAL SANS-SERIF BOLD CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D5E5;MATHEMATICAL SANS-SERIF BOLD CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D5E6;MATHEMATICAL SANS-SERIF BOLD CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D5E7;MATHEMATICAL SANS-SERIF BOLD CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D5E8;MATHEMATICAL SANS-SERIF BOLD CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D5E9;MATHEMATICAL SANS-SERIF BOLD CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D5EA;MATHEMATICAL SANS-SERIF BOLD CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D5EB;MATHEMATICAL SANS-SERIF BOLD CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D5EC;MATHEMATICAL SANS-SERIF BOLD CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D5ED;MATHEMATICAL SANS-SERIF BOLD CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D5EE;MATHEMATICAL SANS-SERIF BOLD SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D5EF;MATHEMATICAL SANS-SERIF BOLD SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D5F0;MATHEMATICAL SANS-SERIF BOLD SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D5F1;MATHEMATICAL SANS-SERIF BOLD SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D5F2;MATHEMATICAL SANS-SERIF BOLD SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D5F3;MATHEMATICAL SANS-SERIF BOLD SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D5F4;MATHEMATICAL SANS-SERIF BOLD SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D5F5;MATHEMATICAL SANS-SERIF BOLD SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D5F6;MATHEMATICAL SANS-SERIF BOLD SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D5F7;MATHEMATICAL SANS-SERIF BOLD SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D5F8;MATHEMATICAL SANS-SERIF BOLD SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D5F9;MATHEMATICAL SANS-SERIF BOLD SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D5FA;MATHEMATICAL SANS-SERIF BOLD SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D5FB;MATHEMATICAL SANS-SERIF BOLD SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D5FC;MATHEMATICAL SANS-SERIF BOLD SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D5FD;MATHEMATICAL SANS-SERIF BOLD SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D5FE;MATHEMATICAL SANS-SERIF BOLD SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D5FF;MATHEMATICAL SANS-SERIF BOLD SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D600;MATHEMATICAL SANS-SERIF BOLD SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D601;MATHEMATICAL SANS-SERIF BOLD SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D602;MATHEMATICAL SANS-SERIF BOLD SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D603;MATHEMATICAL SANS-SERIF BOLD SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D604;MATHEMATICAL SANS-SERIF BOLD SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D605;MATHEMATICAL SANS-SERIF BOLD SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D606;MATHEMATICAL SANS-SERIF BOLD SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D607;MATHEMATICAL SANS-SERIF BOLD SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D608;MATHEMATICAL SANS-SERIF ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D609;MATHEMATICAL SANS-SERIF ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D60A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D60B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D60C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D60D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D60E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D60F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D610;MATHEMATICAL SANS-SERIF ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D611;MATHEMATICAL SANS-SERIF ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D612;MATHEMATICAL SANS-SERIF ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D613;MATHEMATICAL SANS-SERIF ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D614;MATHEMATICAL SANS-SERIF ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D615;MATHEMATICAL SANS-SERIF ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D616;MATHEMATICAL SANS-SERIF ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D617;MATHEMATICAL SANS-SERIF ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D618;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D619;MATHEMATICAL SANS-SERIF ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D61A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D61B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D61C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D61D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D61E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D61F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D620;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D621;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D622;MATHEMATICAL SANS-SERIF ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D623;MATHEMATICAL SANS-SERIF ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D624;MATHEMATICAL SANS-SERIF ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D625;MATHEMATICAL SANS-SERIF ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D626;MATHEMATICAL SANS-SERIF ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D627;MATHEMATICAL SANS-SERIF ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D628;MATHEMATICAL SANS-SERIF ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D629;MATHEMATICAL SANS-SERIF ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D62A;MATHEMATICAL SANS-SERIF ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D62B;MATHEMATICAL SANS-SERIF ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D62C;MATHEMATICAL SANS-SERIF ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D62D;MATHEMATICAL SANS-SERIF ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D62E;MATHEMATICAL SANS-SERIF ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D62F;MATHEMATICAL SANS-SERIF ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D630;MATHEMATICAL SANS-SERIF ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D631;MATHEMATICAL SANS-SERIF ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D632;MATHEMATICAL SANS-SERIF ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D633;MATHEMATICAL SANS-SERIF ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D634;MATHEMATICAL SANS-SERIF ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D635;MATHEMATICAL SANS-SERIF ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D636;MATHEMATICAL SANS-SERIF ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D637;MATHEMATICAL SANS-SERIF ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D638;MATHEMATICAL SANS-SERIF ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D639;MATHEMATICAL SANS-SERIF ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D63A;MATHEMATICAL SANS-SERIF ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D63B;MATHEMATICAL SANS-SERIF ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D63C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D63D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D63E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D63F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D640;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D641;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D642;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D643;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D644;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D645;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D646;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D647;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D648;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D649;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D64A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D64B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D64C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D64D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D64E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D64F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D650;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D651;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D652;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D653;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D654;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D655;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D656;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D657;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D658;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D659;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D65A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D65B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D65C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D65D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D65E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D65F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D660;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D661;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D662;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D663;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D664;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D665;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D666;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D667;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D668;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D669;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D66A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D66B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D66C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D66D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D66E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D66F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D670;MATHEMATICAL MONOSPACE CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D671;MATHEMATICAL MONOSPACE CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D672;MATHEMATICAL MONOSPACE CAPITAL C;Lu;0;L; 0043;;;;N;;;;; 1D673;MATHEMATICAL MONOSPACE CAPITAL D;Lu;0;L; 0044;;;;N;;;;; 1D674;MATHEMATICAL MONOSPACE CAPITAL E;Lu;0;L; 0045;;;;N;;;;; 1D675;MATHEMATICAL MONOSPACE CAPITAL F;Lu;0;L; 0046;;;;N;;;;; 1D676;MATHEMATICAL MONOSPACE CAPITAL G;Lu;0;L; 0047;;;;N;;;;; 1D677;MATHEMATICAL MONOSPACE CAPITAL H;Lu;0;L; 0048;;;;N;;;;; 1D678;MATHEMATICAL MONOSPACE CAPITAL I;Lu;0;L; 0049;;;;N;;;;; 1D679;MATHEMATICAL MONOSPACE CAPITAL J;Lu;0;L; 004A;;;;N;;;;; 1D67A;MATHEMATICAL MONOSPACE CAPITAL K;Lu;0;L; 004B;;;;N;;;;; 1D67B;MATHEMATICAL MONOSPACE CAPITAL L;Lu;0;L; 004C;;;;N;;;;; 1D67C;MATHEMATICAL MONOSPACE CAPITAL M;Lu;0;L; 004D;;;;N;;;;; 1D67D;MATHEMATICAL MONOSPACE CAPITAL N;Lu;0;L; 004E;;;;N;;;;; 1D67E;MATHEMATICAL MONOSPACE CAPITAL O;Lu;0;L; 004F;;;;N;;;;; 1D67F;MATHEMATICAL MONOSPACE CAPITAL P;Lu;0;L; 0050;;;;N;;;;; 1D680;MATHEMATICAL MONOSPACE CAPITAL Q;Lu;0;L; 0051;;;;N;;;;; 1D681;MATHEMATICAL MONOSPACE CAPITAL R;Lu;0;L; 0052;;;;N;;;;; 1D682;MATHEMATICAL MONOSPACE CAPITAL S;Lu;0;L; 0053;;;;N;;;;; 1D683;MATHEMATICAL MONOSPACE CAPITAL T;Lu;0;L; 0054;;;;N;;;;; 1D684;MATHEMATICAL MONOSPACE CAPITAL U;Lu;0;L; 0055;;;;N;;;;; 1D685;MATHEMATICAL MONOSPACE CAPITAL V;Lu;0;L; 0056;;;;N;;;;; 1D686;MATHEMATICAL MONOSPACE CAPITAL W;Lu;0;L; 0057;;;;N;;;;; 1D687;MATHEMATICAL MONOSPACE CAPITAL X;Lu;0;L; 0058;;;;N;;;;; 1D688;MATHEMATICAL MONOSPACE CAPITAL Y;Lu;0;L; 0059;;;;N;;;;; 1D689;MATHEMATICAL MONOSPACE CAPITAL Z;Lu;0;L; 005A;;;;N;;;;; 1D68A;MATHEMATICAL MONOSPACE SMALL A;Ll;0;L; 0061;;;;N;;;;; 1D68B;MATHEMATICAL MONOSPACE SMALL B;Ll;0;L; 0062;;;;N;;;;; 1D68C;MATHEMATICAL MONOSPACE SMALL C;Ll;0;L; 0063;;;;N;;;;; 1D68D;MATHEMATICAL MONOSPACE SMALL D;Ll;0;L; 0064;;;;N;;;;; 1D68E;MATHEMATICAL MONOSPACE SMALL E;Ll;0;L; 0065;;;;N;;;;; 1D68F;MATHEMATICAL MONOSPACE SMALL F;Ll;0;L; 0066;;;;N;;;;; 1D690;MATHEMATICAL MONOSPACE SMALL G;Ll;0;L; 0067;;;;N;;;;; 1D691;MATHEMATICAL MONOSPACE SMALL H;Ll;0;L; 0068;;;;N;;;;; 1D692;MATHEMATICAL MONOSPACE SMALL I;Ll;0;L; 0069;;;;N;;;;; 1D693;MATHEMATICAL MONOSPACE SMALL J;Ll;0;L; 006A;;;;N;;;;; 1D694;MATHEMATICAL MONOSPACE SMALL K;Ll;0;L; 006B;;;;N;;;;; 1D695;MATHEMATICAL MONOSPACE SMALL L;Ll;0;L; 006C;;;;N;;;;; 1D696;MATHEMATICAL MONOSPACE SMALL M;Ll;0;L; 006D;;;;N;;;;; 1D697;MATHEMATICAL MONOSPACE SMALL N;Ll;0;L; 006E;;;;N;;;;; 1D698;MATHEMATICAL MONOSPACE SMALL O;Ll;0;L; 006F;;;;N;;;;; 1D699;MATHEMATICAL MONOSPACE SMALL P;Ll;0;L; 0070;;;;N;;;;; 1D69A;MATHEMATICAL MONOSPACE SMALL Q;Ll;0;L; 0071;;;;N;;;;; 1D69B;MATHEMATICAL MONOSPACE SMALL R;Ll;0;L; 0072;;;;N;;;;; 1D69C;MATHEMATICAL MONOSPACE SMALL S;Ll;0;L; 0073;;;;N;;;;; 1D69D;MATHEMATICAL MONOSPACE SMALL T;Ll;0;L; 0074;;;;N;;;;; 1D69E;MATHEMATICAL MONOSPACE SMALL U;Ll;0;L; 0075;;;;N;;;;; 1D69F;MATHEMATICAL MONOSPACE SMALL V;Ll;0;L; 0076;;;;N;;;;; 1D6A0;MATHEMATICAL MONOSPACE SMALL W;Ll;0;L; 0077;;;;N;;;;; 1D6A1;MATHEMATICAL MONOSPACE SMALL X;Ll;0;L; 0078;;;;N;;;;; 1D6A2;MATHEMATICAL MONOSPACE SMALL Y;Ll;0;L; 0079;;;;N;;;;; 1D6A3;MATHEMATICAL MONOSPACE SMALL Z;Ll;0;L; 007A;;;;N;;;;; 1D6A8;MATHEMATICAL BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; 1D6A9;MATHEMATICAL BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; 1D6AA;MATHEMATICAL BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; 1D6AB;MATHEMATICAL BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; 1D6AC;MATHEMATICAL BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; 1D6AD;MATHEMATICAL BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; 1D6AE;MATHEMATICAL BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; 1D6AF;MATHEMATICAL BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; 1D6B0;MATHEMATICAL BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; 1D6B1;MATHEMATICAL BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; 1D6B2;MATHEMATICAL BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; 1D6B3;MATHEMATICAL BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; 1D6B4;MATHEMATICAL BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; 1D6B5;MATHEMATICAL BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; 1D6B6;MATHEMATICAL BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; 1D6B7;MATHEMATICAL BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; 1D6B8;MATHEMATICAL BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; 1D6B9;MATHEMATICAL BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; 1D6BA;MATHEMATICAL BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; 1D6BB;MATHEMATICAL BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; 1D6BC;MATHEMATICAL BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; 1D6BD;MATHEMATICAL BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; 1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; 1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; 1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; 1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; 1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; 1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; 1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; 1D6C5;MATHEMATICAL BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; 1D6C6;MATHEMATICAL BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; 1D6C7;MATHEMATICAL BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; 1D6C8;MATHEMATICAL BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; 1D6C9;MATHEMATICAL BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; 1D6CA;MATHEMATICAL BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; 1D6CB;MATHEMATICAL BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; 1D6CC;MATHEMATICAL BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; 1D6CD;MATHEMATICAL BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; 1D6CE;MATHEMATICAL BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; 1D6CF;MATHEMATICAL BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; 1D6D0;MATHEMATICAL BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; 1D6D1;MATHEMATICAL BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; 1D6D2;MATHEMATICAL BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; 1D6D3;MATHEMATICAL BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; 1D6D4;MATHEMATICAL BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; 1D6D5;MATHEMATICAL BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; 1D6D6;MATHEMATICAL BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; 1D6D7;MATHEMATICAL BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; 1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; 1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; 1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; 1D6DF;MATHEMATICAL BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; 1D6E0;MATHEMATICAL BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; 1D6E1;MATHEMATICAL BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; 1D6E2;MATHEMATICAL ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; 1D6E3;MATHEMATICAL ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; 1D6E4;MATHEMATICAL ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; 1D6E5;MATHEMATICAL ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; 1D6E6;MATHEMATICAL ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; 1D6E7;MATHEMATICAL ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; 1D6E8;MATHEMATICAL ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; 1D6E9;MATHEMATICAL ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; 1D6EA;MATHEMATICAL ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; 1D6EB;MATHEMATICAL ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; 1D6EC;MATHEMATICAL ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; 1D6ED;MATHEMATICAL ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; 1D6EE;MATHEMATICAL ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; 1D6EF;MATHEMATICAL ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; 1D6F0;MATHEMATICAL ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; 1D6F1;MATHEMATICAL ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; 1D6F2;MATHEMATICAL ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; 1D6F3;MATHEMATICAL ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; 1D6F4;MATHEMATICAL ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; 1D6F5;MATHEMATICAL ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; 1D6F6;MATHEMATICAL ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; 1D6F7;MATHEMATICAL ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; 1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; 1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; 1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; 1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; 1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; 1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; 1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; 1D6FF;MATHEMATICAL ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; 1D700;MATHEMATICAL ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; 1D701;MATHEMATICAL ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; 1D702;MATHEMATICAL ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; 1D703;MATHEMATICAL ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; 1D704;MATHEMATICAL ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; 1D705;MATHEMATICAL ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; 1D706;MATHEMATICAL ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; 1D707;MATHEMATICAL ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; 1D708;MATHEMATICAL ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; 1D709;MATHEMATICAL ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; 1D70A;MATHEMATICAL ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; 1D70B;MATHEMATICAL ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; 1D70C;MATHEMATICAL ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; 1D70D;MATHEMATICAL ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; 1D70E;MATHEMATICAL ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; 1D70F;MATHEMATICAL ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; 1D710;MATHEMATICAL ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; 1D711;MATHEMATICAL ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; 1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; 1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; 1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; 1D719;MATHEMATICAL ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; 1D71A;MATHEMATICAL ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; 1D71B;MATHEMATICAL ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; 1D71C;MATHEMATICAL BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; 1D71D;MATHEMATICAL BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; 1D71E;MATHEMATICAL BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; 1D71F;MATHEMATICAL BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; 1D720;MATHEMATICAL BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; 1D721;MATHEMATICAL BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; 1D722;MATHEMATICAL BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; 1D723;MATHEMATICAL BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; 1D724;MATHEMATICAL BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; 1D725;MATHEMATICAL BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; 1D726;MATHEMATICAL BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; 1D727;MATHEMATICAL BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; 1D728;MATHEMATICAL BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; 1D729;MATHEMATICAL BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; 1D72A;MATHEMATICAL BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; 1D72B;MATHEMATICAL BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; 1D72C;MATHEMATICAL BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; 1D72D;MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; 1D72E;MATHEMATICAL BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; 1D72F;MATHEMATICAL BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; 1D730;MATHEMATICAL BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; 1D731;MATHEMATICAL BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; 1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; 1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; 1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; 1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; 1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; 1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; 1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; 1D739;MATHEMATICAL BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; 1D73A;MATHEMATICAL BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; 1D73B;MATHEMATICAL BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; 1D73C;MATHEMATICAL BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; 1D73D;MATHEMATICAL BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; 1D73E;MATHEMATICAL BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; 1D73F;MATHEMATICAL BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; 1D740;MATHEMATICAL BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; 1D741;MATHEMATICAL BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; 1D742;MATHEMATICAL BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; 1D743;MATHEMATICAL BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; 1D744;MATHEMATICAL BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; 1D745;MATHEMATICAL BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; 1D746;MATHEMATICAL BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; 1D747;MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; 1D748;MATHEMATICAL BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; 1D749;MATHEMATICAL BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; 1D74A;MATHEMATICAL BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; 1D74B;MATHEMATICAL BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; 1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; 1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; 1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; 1D753;MATHEMATICAL BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; 1D754;MATHEMATICAL BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; 1D755;MATHEMATICAL BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; 1D756;MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; 1D757;MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; 1D758;MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; 1D759;MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; 1D75A;MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; 1D75B;MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; 1D75C;MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; 1D75D;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; 1D75E;MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; 1D75F;MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; 1D760;MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; 1D761;MATHEMATICAL SANS-SERIF BOLD CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; 1D762;MATHEMATICAL SANS-SERIF BOLD CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; 1D763;MATHEMATICAL SANS-SERIF BOLD CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; 1D764;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; 1D765;MATHEMATICAL SANS-SERIF BOLD CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; 1D766;MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; 1D767;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; 1D768;MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; 1D769;MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; 1D76A;MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; 1D76B;MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; 1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; 1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; 1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; 1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L; 2207;;;;N;;;;; 1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; 1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; 1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; 1D773;MATHEMATICAL SANS-SERIF BOLD SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; 1D774;MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; 1D775;MATHEMATICAL SANS-SERIF BOLD SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; 1D776;MATHEMATICAL SANS-SERIF BOLD SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; 1D777;MATHEMATICAL SANS-SERIF BOLD SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; 1D778;MATHEMATICAL SANS-SERIF BOLD SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; 1D779;MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; 1D77A;MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; 1D77B;MATHEMATICAL SANS-SERIF BOLD SMALL MU;Ll;0;L; 03BC;;;;N;;;;; 1D77C;MATHEMATICAL SANS-SERIF BOLD SMALL NU;Ll;0;L; 03BD;;;;N;;;;; 1D77D;MATHEMATICAL SANS-SERIF BOLD SMALL XI;Ll;0;L; 03BE;;;;N;;;;; 1D77E;MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; 1D77F;MATHEMATICAL SANS-SERIF BOLD SMALL PI;Ll;0;L; 03C0;;;;N;;;;; 1D780;MATHEMATICAL SANS-SERIF BOLD SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; 1D781;MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; 1D782;MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; 1D783;MATHEMATICAL SANS-SERIF BOLD SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; 1D784;MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; 1D785;MATHEMATICAL SANS-SERIF BOLD SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; 1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; 1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; 1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; 1D78D;MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; 1D78E;MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; 1D78F;MATHEMATICAL SANS-SERIF BOLD PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; 1D790;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA;Lu;0;L; 0391;;;;N;;;;; 1D791;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA;Lu;0;L; 0392;;;;N;;;;; 1D792;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA;Lu;0;L; 0393;;;;N;;;;; 1D793;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA;Lu;0;L; 0394;;;;N;;;;; 1D794;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON;Lu;0;L; 0395;;;;N;;;;; 1D795;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA;Lu;0;L; 0396;;;;N;;;;; 1D796;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA;Lu;0;L; 0397;;;;N;;;;; 1D797;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA;Lu;0;L; 0398;;;;N;;;;; 1D798;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA;Lu;0;L; 0399;;;;N;;;;; 1D799;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA;Lu;0;L; 039A;;;;N;;;;; 1D79A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA;Lu;0;L; 039B;;;;N;;;;; 1D79B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU;Lu;0;L; 039C;;;;N;;;;; 1D79C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU;Lu;0;L; 039D;;;;N;;;;; 1D79D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI;Lu;0;L; 039E;;;;N;;;;; 1D79E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON;Lu;0;L; 039F;;;;N;;;;; 1D79F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI;Lu;0;L; 03A0;;;;N;;;;; 1D7A0;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO;Lu;0;L; 03A1;;;;N;;;;; 1D7A1;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L; 03F4;;;;N;;;;; 1D7A2;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA;Lu;0;L; 03A3;;;;N;;;;; 1D7A3;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU;Lu;0;L; 03A4;;;;N;;;;; 1D7A4;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON;Lu;0;L; 03A5;;;;N;;;;; 1D7A5;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI;Lu;0;L; 03A6;;;;N;;;;; 1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L; 03A7;;;;N;;;;; 1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L; 03A8;;;;N;;;;; 1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L; 03A9;;;;N;;;;; 1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L; 2207;;;;N;;;;; 1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L; 03B1;;;;N;;;;; 1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L; 03B2;;;;N;;;;; 1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L; 03B3;;;;N;;;;; 1D7AD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA;Ll;0;L; 03B4;;;;N;;;;; 1D7AE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON;Ll;0;L; 03B5;;;;N;;;;; 1D7AF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA;Ll;0;L; 03B6;;;;N;;;;; 1D7B0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA;Ll;0;L; 03B7;;;;N;;;;; 1D7B1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA;Ll;0;L; 03B8;;;;N;;;;; 1D7B2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA;Ll;0;L; 03B9;;;;N;;;;; 1D7B3;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA;Ll;0;L; 03BA;;;;N;;;;; 1D7B4;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA;Ll;0;L; 03BB;;;;N;;;;; 1D7B5;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU;Ll;0;L; 03BC;;;;N;;;;; 1D7B6;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU;Ll;0;L; 03BD;;;;N;;;;; 1D7B7;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI;Ll;0;L; 03BE;;;;N;;;;; 1D7B8;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON;Ll;0;L; 03BF;;;;N;;;;; 1D7B9;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI;Ll;0;L; 03C0;;;;N;;;;; 1D7BA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO;Ll;0;L; 03C1;;;;N;;;;; 1D7BB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L; 03C2;;;;N;;;;; 1D7BC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA;Ll;0;L; 03C3;;;;N;;;;; 1D7BD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU;Ll;0;L; 03C4;;;;N;;;;; 1D7BE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON;Ll;0;L; 03C5;;;;N;;;;; 1D7BF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI;Ll;0;L; 03C6;;;;N;;;;; 1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L; 03C7;;;;N;;;;; 1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L; 03C8;;;;N;;;;; 1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L; 03C9;;;;N;;;;; 1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L; 2202;;;;N;;;;; 1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L; 03F5;;;;N;;;;; 1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L; 03D1;;;;N;;;;; 1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L; 03F0;;;;N;;;;; 1D7C7;MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL;Ll;0;L; 03D5;;;;N;;;;; 1D7C8;MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL;Ll;0;L; 03F1;;;;N;;;;; 1D7C9;MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL;Ll;0;L; 03D6;;;;N;;;;; 1D7CE;MATHEMATICAL BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; 1D7CF;MATHEMATICAL BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; 1D7D0;MATHEMATICAL BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; 1D7D1;MATHEMATICAL BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; 1D7D2;MATHEMATICAL BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; 1D7D3;MATHEMATICAL BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; 1D7D4;MATHEMATICAL BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; 1D7D5;MATHEMATICAL BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; 1D7D6;MATHEMATICAL BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; 1D7D7;MATHEMATICAL BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; 1D7D8;MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; 1D7D9;MATHEMATICAL DOUBLE-STRUCK DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; 1D7DA;MATHEMATICAL DOUBLE-STRUCK DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; 1D7DB;MATHEMATICAL DOUBLE-STRUCK DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; 1D7DC;MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; 1D7DD;MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; 1D7DE;MATHEMATICAL DOUBLE-STRUCK DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; 1D7DF;MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; 1D7E0;MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; 1D7E1;MATHEMATICAL DOUBLE-STRUCK DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; 1D7E2;MATHEMATICAL SANS-SERIF DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; 1D7E3;MATHEMATICAL SANS-SERIF DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; 1D7E4;MATHEMATICAL SANS-SERIF DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; 1D7E5;MATHEMATICAL SANS-SERIF DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; 1D7E6;MATHEMATICAL SANS-SERIF DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; 1D7E7;MATHEMATICAL SANS-SERIF DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; 1D7E8;MATHEMATICAL SANS-SERIF DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; 1D7E9;MATHEMATICAL SANS-SERIF DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; 1D7EA;MATHEMATICAL SANS-SERIF DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; 1D7EB;MATHEMATICAL SANS-SERIF DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; 1D7EC;MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; 1D7ED;MATHEMATICAL SANS-SERIF BOLD DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; 1D7EE;MATHEMATICAL SANS-SERIF BOLD DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; 1D7EF;MATHEMATICAL SANS-SERIF BOLD DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; 1D7F0;MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; 1D7F1;MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; 1D7F2;MATHEMATICAL SANS-SERIF BOLD DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; 1D7F3;MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; 1D7F4;MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; 1D7F5;MATHEMATICAL SANS-SERIF BOLD DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; 1D7F6;MATHEMATICAL MONOSPACE DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; 1D7F7;MATHEMATICAL MONOSPACE DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; 1D7F8;MATHEMATICAL MONOSPACE DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; 1D7F9;MATHEMATICAL MONOSPACE DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; 1D7FA;MATHEMATICAL MONOSPACE DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; 1D7FB;MATHEMATICAL MONOSPACE DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; 1D7FC;MATHEMATICAL MONOSPACE DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; 1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; 1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; 1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; 20000;;Lo;0;L;;;;;N;;;;; 2A6D6;;Lo;0;L;;;;;N;;;;; 2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;; 2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;; 2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;; 2F803;CJK COMPATIBILITY IDEOGRAPH-2F803;Lo;0;L;20122;;;;N;;;;; 2F804;CJK COMPATIBILITY IDEOGRAPH-2F804;Lo;0;L;4F60;;;;N;;;;; 2F805;CJK COMPATIBILITY IDEOGRAPH-2F805;Lo;0;L;4FAE;;;;N;;;;; 2F806;CJK COMPATIBILITY IDEOGRAPH-2F806;Lo;0;L;4FBB;;;;N;;;;; 2F807;CJK COMPATIBILITY IDEOGRAPH-2F807;Lo;0;L;5002;;;;N;;;;; 2F808;CJK COMPATIBILITY IDEOGRAPH-2F808;Lo;0;L;507A;;;;N;;;;; 2F809;CJK COMPATIBILITY IDEOGRAPH-2F809;Lo;0;L;5099;;;;N;;;;; 2F80A;CJK COMPATIBILITY IDEOGRAPH-2F80A;Lo;0;L;50E7;;;;N;;;;; 2F80B;CJK COMPATIBILITY IDEOGRAPH-2F80B;Lo;0;L;50CF;;;;N;;;;; 2F80C;CJK COMPATIBILITY IDEOGRAPH-2F80C;Lo;0;L;349E;;;;N;;;;; 2F80D;CJK COMPATIBILITY IDEOGRAPH-2F80D;Lo;0;L;2063A;;;;N;;;;; 2F80E;CJK COMPATIBILITY IDEOGRAPH-2F80E;Lo;0;L;514D;;;;N;;;;; 2F80F;CJK COMPATIBILITY IDEOGRAPH-2F80F;Lo;0;L;5154;;;;N;;;;; 2F810;CJK COMPATIBILITY IDEOGRAPH-2F810;Lo;0;L;5164;;;;N;;;;; 2F811;CJK COMPATIBILITY IDEOGRAPH-2F811;Lo;0;L;5177;;;;N;;;;; 2F812;CJK COMPATIBILITY IDEOGRAPH-2F812;Lo;0;L;2051C;;;;N;;;;; 2F813;CJK COMPATIBILITY IDEOGRAPH-2F813;Lo;0;L;34B9;;;;N;;;;; 2F814;CJK COMPATIBILITY IDEOGRAPH-2F814;Lo;0;L;5167;;;;N;;;;; 2F815;CJK COMPATIBILITY IDEOGRAPH-2F815;Lo;0;L;518D;;;;N;;;;; 2F816;CJK COMPATIBILITY IDEOGRAPH-2F816;Lo;0;L;2054B;;;;N;;;;; 2F817;CJK COMPATIBILITY IDEOGRAPH-2F817;Lo;0;L;5197;;;;N;;;;; 2F818;CJK COMPATIBILITY IDEOGRAPH-2F818;Lo;0;L;51A4;;;;N;;;;; 2F819;CJK COMPATIBILITY IDEOGRAPH-2F819;Lo;0;L;4ECC;;;;N;;;;; 2F81A;CJK COMPATIBILITY IDEOGRAPH-2F81A;Lo;0;L;51AC;;;;N;;;;; 2F81B;CJK COMPATIBILITY IDEOGRAPH-2F81B;Lo;0;L;51B5;;;;N;;;;; 2F81C;CJK COMPATIBILITY IDEOGRAPH-2F81C;Lo;0;L;291DF;;;;N;;;;; 2F81D;CJK COMPATIBILITY IDEOGRAPH-2F81D;Lo;0;L;51F5;;;;N;;;;; 2F81E;CJK COMPATIBILITY IDEOGRAPH-2F81E;Lo;0;L;5203;;;;N;;;;; 2F81F;CJK COMPATIBILITY IDEOGRAPH-2F81F;Lo;0;L;34DF;;;;N;;;;; 2F820;CJK COMPATIBILITY IDEOGRAPH-2F820;Lo;0;L;523B;;;;N;;;;; 2F821;CJK COMPATIBILITY IDEOGRAPH-2F821;Lo;0;L;5246;;;;N;;;;; 2F822;CJK COMPATIBILITY IDEOGRAPH-2F822;Lo;0;L;5272;;;;N;;;;; 2F823;CJK COMPATIBILITY IDEOGRAPH-2F823;Lo;0;L;5277;;;;N;;;;; 2F824;CJK COMPATIBILITY IDEOGRAPH-2F824;Lo;0;L;3515;;;;N;;;;; 2F825;CJK COMPATIBILITY IDEOGRAPH-2F825;Lo;0;L;52C7;;;;N;;;;; 2F826;CJK COMPATIBILITY IDEOGRAPH-2F826;Lo;0;L;52C9;;;;N;;;;; 2F827;CJK COMPATIBILITY IDEOGRAPH-2F827;Lo;0;L;52E4;;;;N;;;;; 2F828;CJK COMPATIBILITY IDEOGRAPH-2F828;Lo;0;L;52FA;;;;N;;;;; 2F829;CJK COMPATIBILITY IDEOGRAPH-2F829;Lo;0;L;5305;;;;N;;;;; 2F82A;CJK COMPATIBILITY IDEOGRAPH-2F82A;Lo;0;L;5306;;;;N;;;;; 2F82B;CJK COMPATIBILITY IDEOGRAPH-2F82B;Lo;0;L;5317;;;;N;;;;; 2F82C;CJK COMPATIBILITY IDEOGRAPH-2F82C;Lo;0;L;5349;;;;N;;;;; 2F82D;CJK COMPATIBILITY IDEOGRAPH-2F82D;Lo;0;L;5351;;;;N;;;;; 2F82E;CJK COMPATIBILITY IDEOGRAPH-2F82E;Lo;0;L;535A;;;;N;;;;; 2F82F;CJK COMPATIBILITY IDEOGRAPH-2F82F;Lo;0;L;5373;;;;N;;;;; 2F830;CJK COMPATIBILITY IDEOGRAPH-2F830;Lo;0;L;537D;;;;N;;;;; 2F831;CJK COMPATIBILITY IDEOGRAPH-2F831;Lo;0;L;537F;;;;N;;;;; 2F832;CJK COMPATIBILITY IDEOGRAPH-2F832;Lo;0;L;537F;;;;N;;;;; 2F833;CJK COMPATIBILITY IDEOGRAPH-2F833;Lo;0;L;537F;;;;N;;;;; 2F834;CJK COMPATIBILITY IDEOGRAPH-2F834;Lo;0;L;20A2C;;;;N;;;;; 2F835;CJK COMPATIBILITY IDEOGRAPH-2F835;Lo;0;L;7070;;;;N;;;;; 2F836;CJK COMPATIBILITY IDEOGRAPH-2F836;Lo;0;L;53CA;;;;N;;;;; 2F837;CJK COMPATIBILITY IDEOGRAPH-2F837;Lo;0;L;53DF;;;;N;;;;; 2F838;CJK COMPATIBILITY IDEOGRAPH-2F838;Lo;0;L;20B63;;;;N;;;;; 2F839;CJK COMPATIBILITY IDEOGRAPH-2F839;Lo;0;L;53EB;;;;N;;;;; 2F83A;CJK COMPATIBILITY IDEOGRAPH-2F83A;Lo;0;L;53F1;;;;N;;;;; 2F83B;CJK COMPATIBILITY IDEOGRAPH-2F83B;Lo;0;L;5406;;;;N;;;;; 2F83C;CJK COMPATIBILITY IDEOGRAPH-2F83C;Lo;0;L;549E;;;;N;;;;; 2F83D;CJK COMPATIBILITY IDEOGRAPH-2F83D;Lo;0;L;5438;;;;N;;;;; 2F83E;CJK COMPATIBILITY IDEOGRAPH-2F83E;Lo;0;L;5448;;;;N;;;;; 2F83F;CJK COMPATIBILITY IDEOGRAPH-2F83F;Lo;0;L;5468;;;;N;;;;; 2F840;CJK COMPATIBILITY IDEOGRAPH-2F840;Lo;0;L;54A2;;;;N;;;;; 2F841;CJK COMPATIBILITY IDEOGRAPH-2F841;Lo;0;L;54F6;;;;N;;;;; 2F842;CJK COMPATIBILITY IDEOGRAPH-2F842;Lo;0;L;5510;;;;N;;;;; 2F843;CJK COMPATIBILITY IDEOGRAPH-2F843;Lo;0;L;5553;;;;N;;;;; 2F844;CJK COMPATIBILITY IDEOGRAPH-2F844;Lo;0;L;5563;;;;N;;;;; 2F845;CJK COMPATIBILITY IDEOGRAPH-2F845;Lo;0;L;5584;;;;N;;;;; 2F846;CJK COMPATIBILITY IDEOGRAPH-2F846;Lo;0;L;5584;;;;N;;;;; 2F847;CJK COMPATIBILITY IDEOGRAPH-2F847;Lo;0;L;5599;;;;N;;;;; 2F848;CJK COMPATIBILITY IDEOGRAPH-2F848;Lo;0;L;55AB;;;;N;;;;; 2F849;CJK COMPATIBILITY IDEOGRAPH-2F849;Lo;0;L;55B3;;;;N;;;;; 2F84A;CJK COMPATIBILITY IDEOGRAPH-2F84A;Lo;0;L;55C2;;;;N;;;;; 2F84B;CJK COMPATIBILITY IDEOGRAPH-2F84B;Lo;0;L;5716;;;;N;;;;; 2F84C;CJK COMPATIBILITY IDEOGRAPH-2F84C;Lo;0;L;5606;;;;N;;;;; 2F84D;CJK COMPATIBILITY IDEOGRAPH-2F84D;Lo;0;L;5717;;;;N;;;;; 2F84E;CJK COMPATIBILITY IDEOGRAPH-2F84E;Lo;0;L;5651;;;;N;;;;; 2F84F;CJK COMPATIBILITY IDEOGRAPH-2F84F;Lo;0;L;5674;;;;N;;;;; 2F850;CJK COMPATIBILITY IDEOGRAPH-2F850;Lo;0;L;5207;;;;N;;;;; 2F851;CJK COMPATIBILITY IDEOGRAPH-2F851;Lo;0;L;58EE;;;;N;;;;; 2F852;CJK COMPATIBILITY IDEOGRAPH-2F852;Lo;0;L;57CE;;;;N;;;;; 2F853;CJK COMPATIBILITY IDEOGRAPH-2F853;Lo;0;L;57F4;;;;N;;;;; 2F854;CJK COMPATIBILITY IDEOGRAPH-2F854;Lo;0;L;580D;;;;N;;;;; 2F855;CJK COMPATIBILITY IDEOGRAPH-2F855;Lo;0;L;578B;;;;N;;;;; 2F856;CJK COMPATIBILITY IDEOGRAPH-2F856;Lo;0;L;5832;;;;N;;;;; 2F857;CJK COMPATIBILITY IDEOGRAPH-2F857;Lo;0;L;5831;;;;N;;;;; 2F858;CJK COMPATIBILITY IDEOGRAPH-2F858;Lo;0;L;58AC;;;;N;;;;; 2F859;CJK COMPATIBILITY IDEOGRAPH-2F859;Lo;0;L;214E4;;;;N;;;;; 2F85A;CJK COMPATIBILITY IDEOGRAPH-2F85A;Lo;0;L;58F2;;;;N;;;;; 2F85B;CJK COMPATIBILITY IDEOGRAPH-2F85B;Lo;0;L;58F7;;;;N;;;;; 2F85C;CJK COMPATIBILITY IDEOGRAPH-2F85C;Lo;0;L;5906;;;;N;;;;; 2F85D;CJK COMPATIBILITY IDEOGRAPH-2F85D;Lo;0;L;591A;;;;N;;;;; 2F85E;CJK COMPATIBILITY IDEOGRAPH-2F85E;Lo;0;L;5922;;;;N;;;;; 2F85F;CJK COMPATIBILITY IDEOGRAPH-2F85F;Lo;0;L;5962;;;;N;;;;; 2F860;CJK COMPATIBILITY IDEOGRAPH-2F860;Lo;0;L;216A8;;;;N;;;;; 2F861;CJK COMPATIBILITY IDEOGRAPH-2F861;Lo;0;L;216EA;;;;N;;;;; 2F862;CJK COMPATIBILITY IDEOGRAPH-2F862;Lo;0;L;59EC;;;;N;;;;; 2F863;CJK COMPATIBILITY IDEOGRAPH-2F863;Lo;0;L;5A1B;;;;N;;;;; 2F864;CJK COMPATIBILITY IDEOGRAPH-2F864;Lo;0;L;5A27;;;;N;;;;; 2F865;CJK COMPATIBILITY IDEOGRAPH-2F865;Lo;0;L;59D8;;;;N;;;;; 2F866;CJK COMPATIBILITY IDEOGRAPH-2F866;Lo;0;L;5A66;;;;N;;;;; 2F867;CJK COMPATIBILITY IDEOGRAPH-2F867;Lo;0;L;36EE;;;;N;;;;; 2F868;CJK COMPATIBILITY IDEOGRAPH-2F868;Lo;0;L;2136A;;;;N;;;;; 2F869;CJK COMPATIBILITY IDEOGRAPH-2F869;Lo;0;L;5B08;;;;N;;;;; 2F86A;CJK COMPATIBILITY IDEOGRAPH-2F86A;Lo;0;L;5B3E;;;;N;;;;; 2F86B;CJK COMPATIBILITY IDEOGRAPH-2F86B;Lo;0;L;5B3E;;;;N;;;;; 2F86C;CJK COMPATIBILITY IDEOGRAPH-2F86C;Lo;0;L;219C8;;;;N;;;;; 2F86D;CJK COMPATIBILITY IDEOGRAPH-2F86D;Lo;0;L;5BC3;;;;N;;;;; 2F86E;CJK COMPATIBILITY IDEOGRAPH-2F86E;Lo;0;L;5BD8;;;;N;;;;; 2F86F;CJK COMPATIBILITY IDEOGRAPH-2F86F;Lo;0;L;5BE7;;;;N;;;;; 2F870;CJK COMPATIBILITY IDEOGRAPH-2F870;Lo;0;L;5BF3;;;;N;;;;; 2F871;CJK COMPATIBILITY IDEOGRAPH-2F871;Lo;0;L;21B18;;;;N;;;;; 2F872;CJK COMPATIBILITY IDEOGRAPH-2F872;Lo;0;L;5BFF;;;;N;;;;; 2F873;CJK COMPATIBILITY IDEOGRAPH-2F873;Lo;0;L;5C06;;;;N;;;;; 2F874;CJK COMPATIBILITY IDEOGRAPH-2F874;Lo;0;L;5F33;;;;N;;;;; 2F875;CJK COMPATIBILITY IDEOGRAPH-2F875;Lo;0;L;5C22;;;;N;;;;; 2F876;CJK COMPATIBILITY IDEOGRAPH-2F876;Lo;0;L;3781;;;;N;;;;; 2F877;CJK COMPATIBILITY IDEOGRAPH-2F877;Lo;0;L;5C60;;;;N;;;;; 2F878;CJK COMPATIBILITY IDEOGRAPH-2F878;Lo;0;L;5C6E;;;;N;;;;; 2F879;CJK COMPATIBILITY IDEOGRAPH-2F879;Lo;0;L;5CC0;;;;N;;;;; 2F87A;CJK COMPATIBILITY IDEOGRAPH-2F87A;Lo;0;L;5C8D;;;;N;;;;; 2F87B;CJK COMPATIBILITY IDEOGRAPH-2F87B;Lo;0;L;21DE4;;;;N;;;;; 2F87C;CJK COMPATIBILITY IDEOGRAPH-2F87C;Lo;0;L;5D43;;;;N;;;;; 2F87D;CJK COMPATIBILITY IDEOGRAPH-2F87D;Lo;0;L;21DE6;;;;N;;;;; 2F87E;CJK COMPATIBILITY IDEOGRAPH-2F87E;Lo;0;L;5D6E;;;;N;;;;; 2F87F;CJK COMPATIBILITY IDEOGRAPH-2F87F;Lo;0;L;5D6B;;;;N;;;;; 2F880;CJK COMPATIBILITY IDEOGRAPH-2F880;Lo;0;L;5D7C;;;;N;;;;; 2F881;CJK COMPATIBILITY IDEOGRAPH-2F881;Lo;0;L;5DE1;;;;N;;;;; 2F882;CJK COMPATIBILITY IDEOGRAPH-2F882;Lo;0;L;5DE2;;;;N;;;;; 2F883;CJK COMPATIBILITY IDEOGRAPH-2F883;Lo;0;L;382F;;;;N;;;;; 2F884;CJK COMPATIBILITY IDEOGRAPH-2F884;Lo;0;L;5DFD;;;;N;;;;; 2F885;CJK COMPATIBILITY IDEOGRAPH-2F885;Lo;0;L;5E28;;;;N;;;;; 2F886;CJK COMPATIBILITY IDEOGRAPH-2F886;Lo;0;L;5E3D;;;;N;;;;; 2F887;CJK COMPATIBILITY IDEOGRAPH-2F887;Lo;0;L;5E69;;;;N;;;;; 2F888;CJK COMPATIBILITY IDEOGRAPH-2F888;Lo;0;L;3862;;;;N;;;;; 2F889;CJK COMPATIBILITY IDEOGRAPH-2F889;Lo;0;L;22183;;;;N;;;;; 2F88A;CJK COMPATIBILITY IDEOGRAPH-2F88A;Lo;0;L;387C;;;;N;;;;; 2F88B;CJK COMPATIBILITY IDEOGRAPH-2F88B;Lo;0;L;5EB0;;;;N;;;;; 2F88C;CJK COMPATIBILITY IDEOGRAPH-2F88C;Lo;0;L;5EB3;;;;N;;;;; 2F88D;CJK COMPATIBILITY IDEOGRAPH-2F88D;Lo;0;L;5EB6;;;;N;;;;; 2F88E;CJK COMPATIBILITY IDEOGRAPH-2F88E;Lo;0;L;5ECA;;;;N;;;;; 2F88F;CJK COMPATIBILITY IDEOGRAPH-2F88F;Lo;0;L;2A392;;;;N;;;;; 2F890;CJK COMPATIBILITY IDEOGRAPH-2F890;Lo;0;L;5EFE;;;;N;;;;; 2F891;CJK COMPATIBILITY IDEOGRAPH-2F891;Lo;0;L;22331;;;;N;;;;; 2F892;CJK COMPATIBILITY IDEOGRAPH-2F892;Lo;0;L;22331;;;;N;;;;; 2F893;CJK COMPATIBILITY IDEOGRAPH-2F893;Lo;0;L;8201;;;;N;;;;; 2F894;CJK COMPATIBILITY IDEOGRAPH-2F894;Lo;0;L;5F22;;;;N;;;;; 2F895;CJK COMPATIBILITY IDEOGRAPH-2F895;Lo;0;L;5F22;;;;N;;;;; 2F896;CJK COMPATIBILITY IDEOGRAPH-2F896;Lo;0;L;38C7;;;;N;;;;; 2F897;CJK COMPATIBILITY IDEOGRAPH-2F897;Lo;0;L;232B8;;;;N;;;;; 2F898;CJK COMPATIBILITY IDEOGRAPH-2F898;Lo;0;L;261DA;;;;N;;;;; 2F899;CJK COMPATIBILITY IDEOGRAPH-2F899;Lo;0;L;5F62;;;;N;;;;; 2F89A;CJK COMPATIBILITY IDEOGRAPH-2F89A;Lo;0;L;5F6B;;;;N;;;;; 2F89B;CJK COMPATIBILITY IDEOGRAPH-2F89B;Lo;0;L;38E3;;;;N;;;;; 2F89C;CJK COMPATIBILITY IDEOGRAPH-2F89C;Lo;0;L;5F9A;;;;N;;;;; 2F89D;CJK COMPATIBILITY IDEOGRAPH-2F89D;Lo;0;L;5FCD;;;;N;;;;; 2F89E;CJK COMPATIBILITY IDEOGRAPH-2F89E;Lo;0;L;5FD7;;;;N;;;;; 2F89F;CJK COMPATIBILITY IDEOGRAPH-2F89F;Lo;0;L;5FF9;;;;N;;;;; 2F8A0;CJK COMPATIBILITY IDEOGRAPH-2F8A0;Lo;0;L;6081;;;;N;;;;; 2F8A1;CJK COMPATIBILITY IDEOGRAPH-2F8A1;Lo;0;L;393A;;;;N;;;;; 2F8A2;CJK COMPATIBILITY IDEOGRAPH-2F8A2;Lo;0;L;391C;;;;N;;;;; 2F8A3;CJK COMPATIBILITY IDEOGRAPH-2F8A3;Lo;0;L;6094;;;;N;;;;; 2F8A4;CJK COMPATIBILITY IDEOGRAPH-2F8A4;Lo;0;L;226D4;;;;N;;;;; 2F8A5;CJK COMPATIBILITY IDEOGRAPH-2F8A5;Lo;0;L;60C7;;;;N;;;;; 2F8A6;CJK COMPATIBILITY IDEOGRAPH-2F8A6;Lo;0;L;6148;;;;N;;;;; 2F8A7;CJK COMPATIBILITY IDEOGRAPH-2F8A7;Lo;0;L;614C;;;;N;;;;; 2F8A8;CJK COMPATIBILITY IDEOGRAPH-2F8A8;Lo;0;L;614E;;;;N;;;;; 2F8A9;CJK COMPATIBILITY IDEOGRAPH-2F8A9;Lo;0;L;614C;;;;N;;;;; 2F8AA;CJK COMPATIBILITY IDEOGRAPH-2F8AA;Lo;0;L;617A;;;;N;;;;; 2F8AB;CJK COMPATIBILITY IDEOGRAPH-2F8AB;Lo;0;L;618E;;;;N;;;;; 2F8AC;CJK COMPATIBILITY IDEOGRAPH-2F8AC;Lo;0;L;61B2;;;;N;;;;; 2F8AD;CJK COMPATIBILITY IDEOGRAPH-2F8AD;Lo;0;L;61A4;;;;N;;;;; 2F8AE;CJK COMPATIBILITY IDEOGRAPH-2F8AE;Lo;0;L;61AF;;;;N;;;;; 2F8AF;CJK COMPATIBILITY IDEOGRAPH-2F8AF;Lo;0;L;61DE;;;;N;;;;; 2F8B0;CJK COMPATIBILITY IDEOGRAPH-2F8B0;Lo;0;L;61F2;;;;N;;;;; 2F8B1;CJK COMPATIBILITY IDEOGRAPH-2F8B1;Lo;0;L;61F6;;;;N;;;;; 2F8B2;CJK COMPATIBILITY IDEOGRAPH-2F8B2;Lo;0;L;6210;;;;N;;;;; 2F8B3;CJK COMPATIBILITY IDEOGRAPH-2F8B3;Lo;0;L;621B;;;;N;;;;; 2F8B4;CJK COMPATIBILITY IDEOGRAPH-2F8B4;Lo;0;L;625D;;;;N;;;;; 2F8B5;CJK COMPATIBILITY IDEOGRAPH-2F8B5;Lo;0;L;62B1;;;;N;;;;; 2F8B6;CJK COMPATIBILITY IDEOGRAPH-2F8B6;Lo;0;L;62D4;;;;N;;;;; 2F8B7;CJK COMPATIBILITY IDEOGRAPH-2F8B7;Lo;0;L;6350;;;;N;;;;; 2F8B8;CJK COMPATIBILITY IDEOGRAPH-2F8B8;Lo;0;L;22B0C;;;;N;;;;; 2F8B9;CJK COMPATIBILITY IDEOGRAPH-2F8B9;Lo;0;L;633D;;;;N;;;;; 2F8BA;CJK COMPATIBILITY IDEOGRAPH-2F8BA;Lo;0;L;62FC;;;;N;;;;; 2F8BB;CJK COMPATIBILITY IDEOGRAPH-2F8BB;Lo;0;L;6368;;;;N;;;;; 2F8BC;CJK COMPATIBILITY IDEOGRAPH-2F8BC;Lo;0;L;6383;;;;N;;;;; 2F8BD;CJK COMPATIBILITY IDEOGRAPH-2F8BD;Lo;0;L;63E4;;;;N;;;;; 2F8BE;CJK COMPATIBILITY IDEOGRAPH-2F8BE;Lo;0;L;22BF1;;;;N;;;;; 2F8BF;CJK COMPATIBILITY IDEOGRAPH-2F8BF;Lo;0;L;6422;;;;N;;;;; 2F8C0;CJK COMPATIBILITY IDEOGRAPH-2F8C0;Lo;0;L;63C5;;;;N;;;;; 2F8C1;CJK COMPATIBILITY IDEOGRAPH-2F8C1;Lo;0;L;63A9;;;;N;;;;; 2F8C2;CJK COMPATIBILITY IDEOGRAPH-2F8C2;Lo;0;L;3A2E;;;;N;;;;; 2F8C3;CJK COMPATIBILITY IDEOGRAPH-2F8C3;Lo;0;L;6469;;;;N;;;;; 2F8C4;CJK COMPATIBILITY IDEOGRAPH-2F8C4;Lo;0;L;647E;;;;N;;;;; 2F8C5;CJK COMPATIBILITY IDEOGRAPH-2F8C5;Lo;0;L;649D;;;;N;;;;; 2F8C6;CJK COMPATIBILITY IDEOGRAPH-2F8C6;Lo;0;L;6477;;;;N;;;;; 2F8C7;CJK COMPATIBILITY IDEOGRAPH-2F8C7;Lo;0;L;3A6C;;;;N;;;;; 2F8C8;CJK COMPATIBILITY IDEOGRAPH-2F8C8;Lo;0;L;654F;;;;N;;;;; 2F8C9;CJK COMPATIBILITY IDEOGRAPH-2F8C9;Lo;0;L;656C;;;;N;;;;; 2F8CA;CJK COMPATIBILITY IDEOGRAPH-2F8CA;Lo;0;L;2300A;;;;N;;;;; 2F8CB;CJK COMPATIBILITY IDEOGRAPH-2F8CB;Lo;0;L;65E3;;;;N;;;;; 2F8CC;CJK COMPATIBILITY IDEOGRAPH-2F8CC;Lo;0;L;66F8;;;;N;;;;; 2F8CD;CJK COMPATIBILITY IDEOGRAPH-2F8CD;Lo;0;L;6649;;;;N;;;;; 2F8CE;CJK COMPATIBILITY IDEOGRAPH-2F8CE;Lo;0;L;3B19;;;;N;;;;; 2F8CF;CJK COMPATIBILITY IDEOGRAPH-2F8CF;Lo;0;L;6691;;;;N;;;;; 2F8D0;CJK COMPATIBILITY IDEOGRAPH-2F8D0;Lo;0;L;3B08;;;;N;;;;; 2F8D1;CJK COMPATIBILITY IDEOGRAPH-2F8D1;Lo;0;L;3AE4;;;;N;;;;; 2F8D2;CJK COMPATIBILITY IDEOGRAPH-2F8D2;Lo;0;L;5192;;;;N;;;;; 2F8D3;CJK COMPATIBILITY IDEOGRAPH-2F8D3;Lo;0;L;5195;;;;N;;;;; 2F8D4;CJK COMPATIBILITY IDEOGRAPH-2F8D4;Lo;0;L;6700;;;;N;;;;; 2F8D5;CJK COMPATIBILITY IDEOGRAPH-2F8D5;Lo;0;L;669C;;;;N;;;;; 2F8D6;CJK COMPATIBILITY IDEOGRAPH-2F8D6;Lo;0;L;80AD;;;;N;;;;; 2F8D7;CJK COMPATIBILITY IDEOGRAPH-2F8D7;Lo;0;L;43D9;;;;N;;;;; 2F8D8;CJK COMPATIBILITY IDEOGRAPH-2F8D8;Lo;0;L;6717;;;;N;;;;; 2F8D9;CJK COMPATIBILITY IDEOGRAPH-2F8D9;Lo;0;L;671B;;;;N;;;;; 2F8DA;CJK COMPATIBILITY IDEOGRAPH-2F8DA;Lo;0;L;6721;;;;N;;;;; 2F8DB;CJK COMPATIBILITY IDEOGRAPH-2F8DB;Lo;0;L;675E;;;;N;;;;; 2F8DC;CJK COMPATIBILITY IDEOGRAPH-2F8DC;Lo;0;L;6753;;;;N;;;;; 2F8DD;CJK COMPATIBILITY IDEOGRAPH-2F8DD;Lo;0;L;233C3;;;;N;;;;; 2F8DE;CJK COMPATIBILITY IDEOGRAPH-2F8DE;Lo;0;L;3B49;;;;N;;;;; 2F8DF;CJK COMPATIBILITY IDEOGRAPH-2F8DF;Lo;0;L;67FA;;;;N;;;;; 2F8E0;CJK COMPATIBILITY IDEOGRAPH-2F8E0;Lo;0;L;6785;;;;N;;;;; 2F8E1;CJK COMPATIBILITY IDEOGRAPH-2F8E1;Lo;0;L;6852;;;;N;;;;; 2F8E2;CJK COMPATIBILITY IDEOGRAPH-2F8E2;Lo;0;L;6885;;;;N;;;;; 2F8E3;CJK COMPATIBILITY IDEOGRAPH-2F8E3;Lo;0;L;2346D;;;;N;;;;; 2F8E4;CJK COMPATIBILITY IDEOGRAPH-2F8E4;Lo;0;L;688E;;;;N;;;;; 2F8E5;CJK COMPATIBILITY IDEOGRAPH-2F8E5;Lo;0;L;681F;;;;N;;;;; 2F8E6;CJK COMPATIBILITY IDEOGRAPH-2F8E6;Lo;0;L;6914;;;;N;;;;; 2F8E7;CJK COMPATIBILITY IDEOGRAPH-2F8E7;Lo;0;L;3B9D;;;;N;;;;; 2F8E8;CJK COMPATIBILITY IDEOGRAPH-2F8E8;Lo;0;L;6942;;;;N;;;;; 2F8E9;CJK COMPATIBILITY IDEOGRAPH-2F8E9;Lo;0;L;69A3;;;;N;;;;; 2F8EA;CJK COMPATIBILITY IDEOGRAPH-2F8EA;Lo;0;L;69EA;;;;N;;;;; 2F8EB;CJK COMPATIBILITY IDEOGRAPH-2F8EB;Lo;0;L;6AA8;;;;N;;;;; 2F8EC;CJK COMPATIBILITY IDEOGRAPH-2F8EC;Lo;0;L;236A3;;;;N;;;;; 2F8ED;CJK COMPATIBILITY IDEOGRAPH-2F8ED;Lo;0;L;6ADB;;;;N;;;;; 2F8EE;CJK COMPATIBILITY IDEOGRAPH-2F8EE;Lo;0;L;3C18;;;;N;;;;; 2F8EF;CJK COMPATIBILITY IDEOGRAPH-2F8EF;Lo;0;L;6B21;;;;N;;;;; 2F8F0;CJK COMPATIBILITY IDEOGRAPH-2F8F0;Lo;0;L;238A7;;;;N;;;;; 2F8F1;CJK COMPATIBILITY IDEOGRAPH-2F8F1;Lo;0;L;6B54;;;;N;;;;; 2F8F2;CJK COMPATIBILITY IDEOGRAPH-2F8F2;Lo;0;L;3C4E;;;;N;;;;; 2F8F3;CJK COMPATIBILITY IDEOGRAPH-2F8F3;Lo;0;L;6B72;;;;N;;;;; 2F8F4;CJK COMPATIBILITY IDEOGRAPH-2F8F4;Lo;0;L;6B9F;;;;N;;;;; 2F8F5;CJK COMPATIBILITY IDEOGRAPH-2F8F5;Lo;0;L;6BBA;;;;N;;;;; 2F8F6;CJK COMPATIBILITY IDEOGRAPH-2F8F6;Lo;0;L;6BBB;;;;N;;;;; 2F8F7;CJK COMPATIBILITY IDEOGRAPH-2F8F7;Lo;0;L;23A8D;;;;N;;;;; 2F8F8;CJK COMPATIBILITY IDEOGRAPH-2F8F8;Lo;0;L;21D0B;;;;N;;;;; 2F8F9;CJK COMPATIBILITY IDEOGRAPH-2F8F9;Lo;0;L;23AFA;;;;N;;;;; 2F8FA;CJK COMPATIBILITY IDEOGRAPH-2F8FA;Lo;0;L;6C4E;;;;N;;;;; 2F8FB;CJK COMPATIBILITY IDEOGRAPH-2F8FB;Lo;0;L;23CBC;;;;N;;;;; 2F8FC;CJK COMPATIBILITY IDEOGRAPH-2F8FC;Lo;0;L;6CBF;;;;N;;;;; 2F8FD;CJK COMPATIBILITY IDEOGRAPH-2F8FD;Lo;0;L;6CCD;;;;N;;;;; 2F8FE;CJK COMPATIBILITY IDEOGRAPH-2F8FE;Lo;0;L;6C67;;;;N;;;;; 2F8FF;CJK COMPATIBILITY IDEOGRAPH-2F8FF;Lo;0;L;6D16;;;;N;;;;; 2F900;CJK COMPATIBILITY IDEOGRAPH-2F900;Lo;0;L;6D3E;;;;N;;;;; 2F901;CJK COMPATIBILITY IDEOGRAPH-2F901;Lo;0;L;6D77;;;;N;;;;; 2F902;CJK COMPATIBILITY IDEOGRAPH-2F902;Lo;0;L;6D41;;;;N;;;;; 2F903;CJK COMPATIBILITY IDEOGRAPH-2F903;Lo;0;L;6D69;;;;N;;;;; 2F904;CJK COMPATIBILITY IDEOGRAPH-2F904;Lo;0;L;6D78;;;;N;;;;; 2F905;CJK COMPATIBILITY IDEOGRAPH-2F905;Lo;0;L;6D85;;;;N;;;;; 2F906;CJK COMPATIBILITY IDEOGRAPH-2F906;Lo;0;L;23D1E;;;;N;;;;; 2F907;CJK COMPATIBILITY IDEOGRAPH-2F907;Lo;0;L;6D34;;;;N;;;;; 2F908;CJK COMPATIBILITY IDEOGRAPH-2F908;Lo;0;L;6E2F;;;;N;;;;; 2F909;CJK COMPATIBILITY IDEOGRAPH-2F909;Lo;0;L;6E6E;;;;N;;;;; 2F90A;CJK COMPATIBILITY IDEOGRAPH-2F90A;Lo;0;L;3D33;;;;N;;;;; 2F90B;CJK COMPATIBILITY IDEOGRAPH-2F90B;Lo;0;L;6ECB;;;;N;;;;; 2F90C;CJK COMPATIBILITY IDEOGRAPH-2F90C;Lo;0;L;6EC7;;;;N;;;;; 2F90D;CJK COMPATIBILITY IDEOGRAPH-2F90D;Lo;0;L;23ED1;;;;N;;;;; 2F90E;CJK COMPATIBILITY IDEOGRAPH-2F90E;Lo;0;L;6DF9;;;;N;;;;; 2F90F;CJK COMPATIBILITY IDEOGRAPH-2F90F;Lo;0;L;6F6E;;;;N;;;;; 2F910;CJK COMPATIBILITY IDEOGRAPH-2F910;Lo;0;L;23F5E;;;;N;;;;; 2F911;CJK COMPATIBILITY IDEOGRAPH-2F911;Lo;0;L;23F8E;;;;N;;;;; 2F912;CJK COMPATIBILITY IDEOGRAPH-2F912;Lo;0;L;6FC6;;;;N;;;;; 2F913;CJK COMPATIBILITY IDEOGRAPH-2F913;Lo;0;L;7039;;;;N;;;;; 2F914;CJK COMPATIBILITY IDEOGRAPH-2F914;Lo;0;L;701E;;;;N;;;;; 2F915;CJK COMPATIBILITY IDEOGRAPH-2F915;Lo;0;L;701B;;;;N;;;;; 2F916;CJK COMPATIBILITY IDEOGRAPH-2F916;Lo;0;L;3D96;;;;N;;;;; 2F917;CJK COMPATIBILITY IDEOGRAPH-2F917;Lo;0;L;704A;;;;N;;;;; 2F918;CJK COMPATIBILITY IDEOGRAPH-2F918;Lo;0;L;707D;;;;N;;;;; 2F919;CJK COMPATIBILITY IDEOGRAPH-2F919;Lo;0;L;7077;;;;N;;;;; 2F91A;CJK COMPATIBILITY IDEOGRAPH-2F91A;Lo;0;L;70AD;;;;N;;;;; 2F91B;CJK COMPATIBILITY IDEOGRAPH-2F91B;Lo;0;L;20525;;;;N;;;;; 2F91C;CJK COMPATIBILITY IDEOGRAPH-2F91C;Lo;0;L;7145;;;;N;;;;; 2F91D;CJK COMPATIBILITY IDEOGRAPH-2F91D;Lo;0;L;24263;;;;N;;;;; 2F91E;CJK COMPATIBILITY IDEOGRAPH-2F91E;Lo;0;L;719C;;;;N;;;;; 2F91F;CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo;0;L;43AB;;;;N;;;;; 2F920;CJK COMPATIBILITY IDEOGRAPH-2F920;Lo;0;L;7228;;;;N;;;;; 2F921;CJK COMPATIBILITY IDEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;; 2F922;CJK COMPATIBILITY IDEOGRAPH-2F922;Lo;0;L;7250;;;;N;;;;; 2F923;CJK COMPATIBILITY IDEOGRAPH-2F923;Lo;0;L;24608;;;;N;;;;; 2F924;CJK COMPATIBILITY IDEOGRAPH-2F924;Lo;0;L;7280;;;;N;;;;; 2F925;CJK COMPATIBILITY IDEOGRAPH-2F925;Lo;0;L;7295;;;;N;;;;; 2F926;CJK COMPATIBILITY IDEOGRAPH-2F926;Lo;0;L;24735;;;;N;;;;; 2F927;CJK COMPATIBILITY IDEOGRAPH-2F927;Lo;0;L;24814;;;;N;;;;; 2F928;CJK COMPATIBILITY IDEOGRAPH-2F928;Lo;0;L;737A;;;;N;;;;; 2F929;CJK COMPATIBILITY IDEOGRAPH-2F929;Lo;0;L;738B;;;;N;;;;; 2F92A;CJK COMPATIBILITY IDEOGRAPH-2F92A;Lo;0;L;3EAC;;;;N;;;;; 2F92B;CJK COMPATIBILITY IDEOGRAPH-2F92B;Lo;0;L;73A5;;;;N;;;;; 2F92C;CJK COMPATIBILITY IDEOGRAPH-2F92C;Lo;0;L;3EB8;;;;N;;;;; 2F92D;CJK COMPATIBILITY IDEOGRAPH-2F92D;Lo;0;L;3EB8;;;;N;;;;; 2F92E;CJK COMPATIBILITY IDEOGRAPH-2F92E;Lo;0;L;7447;;;;N;;;;; 2F92F;CJK COMPATIBILITY IDEOGRAPH-2F92F;Lo;0;L;745C;;;;N;;;;; 2F930;CJK COMPATIBILITY IDEOGRAPH-2F930;Lo;0;L;7471;;;;N;;;;; 2F931;CJK COMPATIBILITY IDEOGRAPH-2F931;Lo;0;L;7485;;;;N;;;;; 2F932;CJK COMPATIBILITY IDEOGRAPH-2F932;Lo;0;L;74CA;;;;N;;;;; 2F933;CJK COMPATIBILITY IDEOGRAPH-2F933;Lo;0;L;3F1B;;;;N;;;;; 2F934;CJK COMPATIBILITY IDEOGRAPH-2F934;Lo;0;L;7524;;;;N;;;;; 2F935;CJK COMPATIBILITY IDEOGRAPH-2F935;Lo;0;L;24C36;;;;N;;;;; 2F936;CJK COMPATIBILITY IDEOGRAPH-2F936;Lo;0;L;753E;;;;N;;;;; 2F937;CJK COMPATIBILITY IDEOGRAPH-2F937;Lo;0;L;24C92;;;;N;;;;; 2F938;CJK COMPATIBILITY IDEOGRAPH-2F938;Lo;0;L;7570;;;;N;;;;; 2F939;CJK COMPATIBILITY IDEOGRAPH-2F939;Lo;0;L;2219F;;;;N;;;;; 2F93A;CJK COMPATIBILITY IDEOGRAPH-2F93A;Lo;0;L;7610;;;;N;;;;; 2F93B;CJK COMPATIBILITY IDEOGRAPH-2F93B;Lo;0;L;24FA1;;;;N;;;;; 2F93C;CJK COMPATIBILITY IDEOGRAPH-2F93C;Lo;0;L;24FB8;;;;N;;;;; 2F93D;CJK COMPATIBILITY IDEOGRAPH-2F93D;Lo;0;L;25044;;;;N;;;;; 2F93E;CJK COMPATIBILITY IDEOGRAPH-2F93E;Lo;0;L;3FFC;;;;N;;;;; 2F93F;CJK COMPATIBILITY IDEOGRAPH-2F93F;Lo;0;L;4008;;;;N;;;;; 2F940;CJK COMPATIBILITY IDEOGRAPH-2F940;Lo;0;L;76F4;;;;N;;;;; 2F941;CJK COMPATIBILITY IDEOGRAPH-2F941;Lo;0;L;250F3;;;;N;;;;; 2F942;CJK COMPATIBILITY IDEOGRAPH-2F942;Lo;0;L;250F2;;;;N;;;;; 2F943;CJK COMPATIBILITY IDEOGRAPH-2F943;Lo;0;L;25119;;;;N;;;;; 2F944;CJK COMPATIBILITY IDEOGRAPH-2F944;Lo;0;L;25133;;;;N;;;;; 2F945;CJK COMPATIBILITY IDEOGRAPH-2F945;Lo;0;L;771E;;;;N;;;;; 2F946;CJK COMPATIBILITY IDEOGRAPH-2F946;Lo;0;L;771F;;;;N;;;;; 2F947;CJK COMPATIBILITY IDEOGRAPH-2F947;Lo;0;L;771F;;;;N;;;;; 2F948;CJK COMPATIBILITY IDEOGRAPH-2F948;Lo;0;L;774A;;;;N;;;;; 2F949;CJK COMPATIBILITY IDEOGRAPH-2F949;Lo;0;L;4039;;;;N;;;;; 2F94A;CJK COMPATIBILITY IDEOGRAPH-2F94A;Lo;0;L;778B;;;;N;;;;; 2F94B;CJK COMPATIBILITY IDEOGRAPH-2F94B;Lo;0;L;4046;;;;N;;;;; 2F94C;CJK COMPATIBILITY IDEOGRAPH-2F94C;Lo;0;L;4096;;;;N;;;;; 2F94D;CJK COMPATIBILITY IDEOGRAPH-2F94D;Lo;0;L;2541D;;;;N;;;;; 2F94E;CJK COMPATIBILITY IDEOGRAPH-2F94E;Lo;0;L;784E;;;;N;;;;; 2F94F;CJK COMPATIBILITY IDEOGRAPH-2F94F;Lo;0;L;788C;;;;N;;;;; 2F950;CJK COMPATIBILITY IDEOGRAPH-2F950;Lo;0;L;78CC;;;;N;;;;; 2F951;CJK COMPATIBILITY IDEOGRAPH-2F951;Lo;0;L;40E3;;;;N;;;;; 2F952;CJK COMPATIBILITY IDEOGRAPH-2F952;Lo;0;L;25626;;;;N;;;;; 2F953;CJK COMPATIBILITY IDEOGRAPH-2F953;Lo;0;L;7956;;;;N;;;;; 2F954;CJK COMPATIBILITY IDEOGRAPH-2F954;Lo;0;L;2569A;;;;N;;;;; 2F955;CJK COMPATIBILITY IDEOGRAPH-2F955;Lo;0;L;256C5;;;;N;;;;; 2F956;CJK COMPATIBILITY IDEOGRAPH-2F956;Lo;0;L;798F;;;;N;;;;; 2F957;CJK COMPATIBILITY IDEOGRAPH-2F957;Lo;0;L;79EB;;;;N;;;;; 2F958;CJK COMPATIBILITY IDEOGRAPH-2F958;Lo;0;L;412F;;;;N;;;;; 2F959;CJK COMPATIBILITY IDEOGRAPH-2F959;Lo;0;L;7A40;;;;N;;;;; 2F95A;CJK COMPATIBILITY IDEOGRAPH-2F95A;Lo;0;L;7A4A;;;;N;;;;; 2F95B;CJK COMPATIBILITY IDEOGRAPH-2F95B;Lo;0;L;7A4F;;;;N;;;;; 2F95C;CJK COMPATIBILITY IDEOGRAPH-2F95C;Lo;0;L;2597C;;;;N;;;;; 2F95D;CJK COMPATIBILITY IDEOGRAPH-2F95D;Lo;0;L;25AA7;;;;N;;;;; 2F95E;CJK COMPATIBILITY IDEOGRAPH-2F95E;Lo;0;L;25AA7;;;;N;;;;; 2F95F;CJK COMPATIBILITY IDEOGRAPH-2F95F;Lo;0;L;7AAE;;;;N;;;;; 2F960;CJK COMPATIBILITY IDEOGRAPH-2F960;Lo;0;L;4202;;;;N;;;;; 2F961;CJK COMPATIBILITY IDEOGRAPH-2F961;Lo;0;L;25BAB;;;;N;;;;; 2F962;CJK COMPATIBILITY IDEOGRAPH-2F962;Lo;0;L;7BC6;;;;N;;;;; 2F963;CJK COMPATIBILITY IDEOGRAPH-2F963;Lo;0;L;7BC9;;;;N;;;;; 2F964;CJK COMPATIBILITY IDEOGRAPH-2F964;Lo;0;L;4227;;;;N;;;;; 2F965;CJK COMPATIBILITY IDEOGRAPH-2F965;Lo;0;L;25C80;;;;N;;;;; 2F966;CJK COMPATIBILITY IDEOGRAPH-2F966;Lo;0;L;7CD2;;;;N;;;;; 2F967;CJK COMPATIBILITY IDEOGRAPH-2F967;Lo;0;L;42A0;;;;N;;;;; 2F968;CJK COMPATIBILITY IDEOGRAPH-2F968;Lo;0;L;7CE8;;;;N;;;;; 2F969;CJK COMPATIBILITY IDEOGRAPH-2F969;Lo;0;L;7CE3;;;;N;;;;; 2F96A;CJK COMPATIBILITY IDEOGRAPH-2F96A;Lo;0;L;7D00;;;;N;;;;; 2F96B;CJK COMPATIBILITY IDEOGRAPH-2F96B;Lo;0;L;25F86;;;;N;;;;; 2F96C;CJK COMPATIBILITY IDEOGRAPH-2F96C;Lo;0;L;7D63;;;;N;;;;; 2F96D;CJK COMPATIBILITY IDEOGRAPH-2F96D;Lo;0;L;4301;;;;N;;;;; 2F96E;CJK COMPATIBILITY IDEOGRAPH-2F96E;Lo;0;L;7DC7;;;;N;;;;; 2F96F;CJK COMPATIBILITY IDEOGRAPH-2F96F;Lo;0;L;7E02;;;;N;;;;; 2F970;CJK COMPATIBILITY IDEOGRAPH-2F970;Lo;0;L;7E45;;;;N;;;;; 2F971;CJK COMPATIBILITY IDEOGRAPH-2F971;Lo;0;L;4334;;;;N;;;;; 2F972;CJK COMPATIBILITY IDEOGRAPH-2F972;Lo;0;L;26228;;;;N;;;;; 2F973;CJK COMPATIBILITY IDEOGRAPH-2F973;Lo;0;L;26247;;;;N;;;;; 2F974;CJK COMPATIBILITY IDEOGRAPH-2F974;Lo;0;L;4359;;;;N;;;;; 2F975;CJK COMPATIBILITY IDEOGRAPH-2F975;Lo;0;L;262D9;;;;N;;;;; 2F976;CJK COMPATIBILITY IDEOGRAPH-2F976;Lo;0;L;7F7A;;;;N;;;;; 2F977;CJK COMPATIBILITY IDEOGRAPH-2F977;Lo;0;L;2633E;;;;N;;;;; 2F978;CJK COMPATIBILITY IDEOGRAPH-2F978;Lo;0;L;7F95;;;;N;;;;; 2F979;CJK COMPATIBILITY IDEOGRAPH-2F979;Lo;0;L;7FFA;;;;N;;;;; 2F97A;CJK COMPATIBILITY IDEOGRAPH-2F97A;Lo;0;L;8005;;;;N;;;;; 2F97B;CJK COMPATIBILITY IDEOGRAPH-2F97B;Lo;0;L;264DA;;;;N;;;;; 2F97C;CJK COMPATIBILITY IDEOGRAPH-2F97C;Lo;0;L;26523;;;;N;;;;; 2F97D;CJK COMPATIBILITY IDEOGRAPH-2F97D;Lo;0;L;8060;;;;N;;;;; 2F97E;CJK COMPATIBILITY IDEOGRAPH-2F97E;Lo;0;L;265A8;;;;N;;;;; 2F97F;CJK COMPATIBILITY IDEOGRAPH-2F97F;Lo;0;L;8070;;;;N;;;;; 2F980;CJK COMPATIBILITY IDEOGRAPH-2F980;Lo;0;L;2335F;;;;N;;;;; 2F981;CJK COMPATIBILITY IDEOGRAPH-2F981;Lo;0;L;43D5;;;;N;;;;; 2F982;CJK COMPATIBILITY IDEOGRAPH-2F982;Lo;0;L;80B2;;;;N;;;;; 2F983;CJK COMPATIBILITY IDEOGRAPH-2F983;Lo;0;L;8103;;;;N;;;;; 2F984;CJK COMPATIBILITY IDEOGRAPH-2F984;Lo;0;L;440B;;;;N;;;;; 2F985;CJK COMPATIBILITY IDEOGRAPH-2F985;Lo;0;L;813E;;;;N;;;;; 2F986;CJK COMPATIBILITY IDEOGRAPH-2F986;Lo;0;L;5AB5;;;;N;;;;; 2F987;CJK COMPATIBILITY IDEOGRAPH-2F987;Lo;0;L;267A7;;;;N;;;;; 2F988;CJK COMPATIBILITY IDEOGRAPH-2F988;Lo;0;L;267B5;;;;N;;;;; 2F989;CJK COMPATIBILITY IDEOGRAPH-2F989;Lo;0;L;23393;;;;N;;;;; 2F98A;CJK COMPATIBILITY IDEOGRAPH-2F98A;Lo;0;L;2339C;;;;N;;;;; 2F98B;CJK COMPATIBILITY IDEOGRAPH-2F98B;Lo;0;L;8201;;;;N;;;;; 2F98C;CJK COMPATIBILITY IDEOGRAPH-2F98C;Lo;0;L;8204;;;;N;;;;; 2F98D;CJK COMPATIBILITY IDEOGRAPH-2F98D;Lo;0;L;8F9E;;;;N;;;;; 2F98E;CJK COMPATIBILITY IDEOGRAPH-2F98E;Lo;0;L;446B;;;;N;;;;; 2F98F;CJK COMPATIBILITY IDEOGRAPH-2F98F;Lo;0;L;8291;;;;N;;;;; 2F990;CJK COMPATIBILITY IDEOGRAPH-2F990;Lo;0;L;828B;;;;N;;;;; 2F991;CJK COMPATIBILITY IDEOGRAPH-2F991;Lo;0;L;829D;;;;N;;;;; 2F992;CJK COMPATIBILITY IDEOGRAPH-2F992;Lo;0;L;52B3;;;;N;;;;; 2F993;CJK COMPATIBILITY IDEOGRAPH-2F993;Lo;0;L;82B1;;;;N;;;;; 2F994;CJK COMPATIBILITY IDEOGRAPH-2F994;Lo;0;L;82B3;;;;N;;;;; 2F995;CJK COMPATIBILITY IDEOGRAPH-2F995;Lo;0;L;82BD;;;;N;;;;; 2F996;CJK COMPATIBILITY IDEOGRAPH-2F996;Lo;0;L;82E6;;;;N;;;;; 2F997;CJK COMPATIBILITY IDEOGRAPH-2F997;Lo;0;L;26B3C;;;;N;;;;; 2F998;CJK COMPATIBILITY IDEOGRAPH-2F998;Lo;0;L;82E5;;;;N;;;;; 2F999;CJK COMPATIBILITY IDEOGRAPH-2F999;Lo;0;L;831D;;;;N;;;;; 2F99A;CJK COMPATIBILITY IDEOGRAPH-2F99A;Lo;0;L;8363;;;;N;;;;; 2F99B;CJK COMPATIBILITY IDEOGRAPH-2F99B;Lo;0;L;83AD;;;;N;;;;; 2F99C;CJK COMPATIBILITY IDEOGRAPH-2F99C;Lo;0;L;8323;;;;N;;;;; 2F99D;CJK COMPATIBILITY IDEOGRAPH-2F99D;Lo;0;L;83BD;;;;N;;;;; 2F99E;CJK COMPATIBILITY IDEOGRAPH-2F99E;Lo;0;L;83E7;;;;N;;;;; 2F99F;CJK COMPATIBILITY IDEOGRAPH-2F99F;Lo;0;L;8457;;;;N;;;;; 2F9A0;CJK COMPATIBILITY IDEOGRAPH-2F9A0;Lo;0;L;8353;;;;N;;;;; 2F9A1;CJK COMPATIBILITY IDEOGRAPH-2F9A1;Lo;0;L;83CA;;;;N;;;;; 2F9A2;CJK COMPATIBILITY IDEOGRAPH-2F9A2;Lo;0;L;83CC;;;;N;;;;; 2F9A3;CJK COMPATIBILITY IDEOGRAPH-2F9A3;Lo;0;L;83DC;;;;N;;;;; 2F9A4;CJK COMPATIBILITY IDEOGRAPH-2F9A4;Lo;0;L;26C36;;;;N;;;;; 2F9A5;CJK COMPATIBILITY IDEOGRAPH-2F9A5;Lo;0;L;26D6B;;;;N;;;;; 2F9A6;CJK COMPATIBILITY IDEOGRAPH-2F9A6;Lo;0;L;26CD5;;;;N;;;;; 2F9A7;CJK COMPATIBILITY IDEOGRAPH-2F9A7;Lo;0;L;452B;;;;N;;;;; 2F9A8;CJK COMPATIBILITY IDEOGRAPH-2F9A8;Lo;0;L;84F1;;;;N;;;;; 2F9A9;CJK COMPATIBILITY IDEOGRAPH-2F9A9;Lo;0;L;84F3;;;;N;;;;; 2F9AA;CJK COMPATIBILITY IDEOGRAPH-2F9AA;Lo;0;L;8516;;;;N;;;;; 2F9AB;CJK COMPATIBILITY IDEOGRAPH-2F9AB;Lo;0;L;273CA;;;;N;;;;; 2F9AC;CJK COMPATIBILITY IDEOGRAPH-2F9AC;Lo;0;L;8564;;;;N;;;;; 2F9AD;CJK COMPATIBILITY IDEOGRAPH-2F9AD;Lo;0;L;26F2C;;;;N;;;;; 2F9AE;CJK COMPATIBILITY IDEOGRAPH-2F9AE;Lo;0;L;455D;;;;N;;;;; 2F9AF;CJK COMPATIBILITY IDEOGRAPH-2F9AF;Lo;0;L;4561;;;;N;;;;; 2F9B0;CJK COMPATIBILITY IDEOGRAPH-2F9B0;Lo;0;L;26FB1;;;;N;;;;; 2F9B1;CJK COMPATIBILITY IDEOGRAPH-2F9B1;Lo;0;L;270D2;;;;N;;;;; 2F9B2;CJK COMPATIBILITY IDEOGRAPH-2F9B2;Lo;0;L;456B;;;;N;;;;; 2F9B3;CJK COMPATIBILITY IDEOGRAPH-2F9B3;Lo;0;L;8650;;;;N;;;;; 2F9B4;CJK COMPATIBILITY IDEOGRAPH-2F9B4;Lo;0;L;865C;;;;N;;;;; 2F9B5;CJK COMPATIBILITY IDEOGRAPH-2F9B5;Lo;0;L;8667;;;;N;;;;; 2F9B6;CJK COMPATIBILITY IDEOGRAPH-2F9B6;Lo;0;L;8669;;;;N;;;;; 2F9B7;CJK COMPATIBILITY IDEOGRAPH-2F9B7;Lo;0;L;86A9;;;;N;;;;; 2F9B8;CJK COMPATIBILITY IDEOGRAPH-2F9B8;Lo;0;L;8688;;;;N;;;;; 2F9B9;CJK COMPATIBILITY IDEOGRAPH-2F9B9;Lo;0;L;870E;;;;N;;;;; 2F9BA;CJK COMPATIBILITY IDEOGRAPH-2F9BA;Lo;0;L;86E2;;;;N;;;;; 2F9BB;CJK COMPATIBILITY IDEOGRAPH-2F9BB;Lo;0;L;8779;;;;N;;;;; 2F9BC;CJK COMPATIBILITY IDEOGRAPH-2F9BC;Lo;0;L;8728;;;;N;;;;; 2F9BD;CJK COMPATIBILITY IDEOGRAPH-2F9BD;Lo;0;L;876B;;;;N;;;;; 2F9BE;CJK COMPATIBILITY IDEOGRAPH-2F9BE;Lo;0;L;8786;;;;N;;;;; 2F9BF;CJK COMPATIBILITY IDEOGRAPH-2F9BF;Lo;0;L;4D57;;;;N;;;;; 2F9C0;CJK COMPATIBILITY IDEOGRAPH-2F9C0;Lo;0;L;87E1;;;;N;;;;; 2F9C1;CJK COMPATIBILITY IDEOGRAPH-2F9C1;Lo;0;L;8801;;;;N;;;;; 2F9C2;CJK COMPATIBILITY IDEOGRAPH-2F9C2;Lo;0;L;45F9;;;;N;;;;; 2F9C3;CJK COMPATIBILITY IDEOGRAPH-2F9C3;Lo;0;L;8860;;;;N;;;;; 2F9C4;CJK COMPATIBILITY IDEOGRAPH-2F9C4;Lo;0;L;8863;;;;N;;;;; 2F9C5;CJK COMPATIBILITY IDEOGRAPH-2F9C5;Lo;0;L;27667;;;;N;;;;; 2F9C6;CJK COMPATIBILITY IDEOGRAPH-2F9C6;Lo;0;L;88D7;;;;N;;;;; 2F9C7;CJK COMPATIBILITY IDEOGRAPH-2F9C7;Lo;0;L;88DE;;;;N;;;;; 2F9C8;CJK COMPATIBILITY IDEOGRAPH-2F9C8;Lo;0;L;4635;;;;N;;;;; 2F9C9;CJK COMPATIBILITY IDEOGRAPH-2F9C9;Lo;0;L;88FA;;;;N;;;;; 2F9CA;CJK COMPATIBILITY IDEOGRAPH-2F9CA;Lo;0;L;34BB;;;;N;;;;; 2F9CB;CJK COMPATIBILITY IDEOGRAPH-2F9CB;Lo;0;L;278AE;;;;N;;;;; 2F9CC;CJK COMPATIBILITY IDEOGRAPH-2F9CC;Lo;0;L;27966;;;;N;;;;; 2F9CD;CJK COMPATIBILITY IDEOGRAPH-2F9CD;Lo;0;L;46BE;;;;N;;;;; 2F9CE;CJK COMPATIBILITY IDEOGRAPH-2F9CE;Lo;0;L;46C7;;;;N;;;;; 2F9CF;CJK COMPATIBILITY IDEOGRAPH-2F9CF;Lo;0;L;8AA0;;;;N;;;;; 2F9D0;CJK COMPATIBILITY IDEOGRAPH-2F9D0;Lo;0;L;8AED;;;;N;;;;; 2F9D1;CJK COMPATIBILITY IDEOGRAPH-2F9D1;Lo;0;L;8B8A;;;;N;;;;; 2F9D2;CJK COMPATIBILITY IDEOGRAPH-2F9D2;Lo;0;L;8C55;;;;N;;;;; 2F9D3;CJK COMPATIBILITY IDEOGRAPH-2F9D3;Lo;0;L;27CA8;;;;N;;;;; 2F9D4;CJK COMPATIBILITY IDEOGRAPH-2F9D4;Lo;0;L;8CAB;;;;N;;;;; 2F9D5;CJK COMPATIBILITY IDEOGRAPH-2F9D5;Lo;0;L;8CC1;;;;N;;;;; 2F9D6;CJK COMPATIBILITY IDEOGRAPH-2F9D6;Lo;0;L;8D1B;;;;N;;;;; 2F9D7;CJK COMPATIBILITY IDEOGRAPH-2F9D7;Lo;0;L;8D77;;;;N;;;;; 2F9D8;CJK COMPATIBILITY IDEOGRAPH-2F9D8;Lo;0;L;27F2F;;;;N;;;;; 2F9D9;CJK COMPATIBILITY IDEOGRAPH-2F9D9;Lo;0;L;20804;;;;N;;;;; 2F9DA;CJK COMPATIBILITY IDEOGRAPH-2F9DA;Lo;0;L;8DCB;;;;N;;;;; 2F9DB;CJK COMPATIBILITY IDEOGRAPH-2F9DB;Lo;0;L;8DBC;;;;N;;;;; 2F9DC;CJK COMPATIBILITY IDEOGRAPH-2F9DC;Lo;0;L;8DF0;;;;N;;;;; 2F9DD;CJK COMPATIBILITY IDEOGRAPH-2F9DD;Lo;0;L;208DE;;;;N;;;;; 2F9DE;CJK COMPATIBILITY IDEOGRAPH-2F9DE;Lo;0;L;8ED4;;;;N;;;;; 2F9DF;CJK COMPATIBILITY IDEOGRAPH-2F9DF;Lo;0;L;8F38;;;;N;;;;; 2F9E0;CJK COMPATIBILITY IDEOGRAPH-2F9E0;Lo;0;L;285D2;;;;N;;;;; 2F9E1;CJK COMPATIBILITY IDEOGRAPH-2F9E1;Lo;0;L;285ED;;;;N;;;;; 2F9E2;CJK COMPATIBILITY IDEOGRAPH-2F9E2;Lo;0;L;9094;;;;N;;;;; 2F9E3;CJK COMPATIBILITY IDEOGRAPH-2F9E3;Lo;0;L;90F1;;;;N;;;;; 2F9E4;CJK COMPATIBILITY IDEOGRAPH-2F9E4;Lo;0;L;9111;;;;N;;;;; 2F9E5;CJK COMPATIBILITY IDEOGRAPH-2F9E5;Lo;0;L;2872E;;;;N;;;;; 2F9E6;CJK COMPATIBILITY IDEOGRAPH-2F9E6;Lo;0;L;911B;;;;N;;;;; 2F9E7;CJK COMPATIBILITY IDEOGRAPH-2F9E7;Lo;0;L;9238;;;;N;;;;; 2F9E8;CJK COMPATIBILITY IDEOGRAPH-2F9E8;Lo;0;L;92D7;;;;N;;;;; 2F9E9;CJK COMPATIBILITY IDEOGRAPH-2F9E9;Lo;0;L;92D8;;;;N;;;;; 2F9EA;CJK COMPATIBILITY IDEOGRAPH-2F9EA;Lo;0;L;927C;;;;N;;;;; 2F9EB;CJK COMPATIBILITY IDEOGRAPH-2F9EB;Lo;0;L;93F9;;;;N;;;;; 2F9EC;CJK COMPATIBILITY IDEOGRAPH-2F9EC;Lo;0;L;9415;;;;N;;;;; 2F9ED;CJK COMPATIBILITY IDEOGRAPH-2F9ED;Lo;0;L;28BFA;;;;N;;;;; 2F9EE;CJK COMPATIBILITY IDEOGRAPH-2F9EE;Lo;0;L;958B;;;;N;;;;; 2F9EF;CJK COMPATIBILITY IDEOGRAPH-2F9EF;Lo;0;L;4995;;;;N;;;;; 2F9F0;CJK COMPATIBILITY IDEOGRAPH-2F9F0;Lo;0;L;95B7;;;;N;;;;; 2F9F1;CJK COMPATIBILITY IDEOGRAPH-2F9F1;Lo;0;L;28D77;;;;N;;;;; 2F9F2;CJK COMPATIBILITY IDEOGRAPH-2F9F2;Lo;0;L;49E6;;;;N;;;;; 2F9F3;CJK COMPATIBILITY IDEOGRAPH-2F9F3;Lo;0;L;96C3;;;;N;;;;; 2F9F4;CJK COMPATIBILITY IDEOGRAPH-2F9F4;Lo;0;L;5DB2;;;;N;;;;; 2F9F5;CJK COMPATIBILITY IDEOGRAPH-2F9F5;Lo;0;L;9723;;;;N;;;;; 2F9F6;CJK COMPATIBILITY IDEOGRAPH-2F9F6;Lo;0;L;29145;;;;N;;;;; 2F9F7;CJK COMPATIBILITY IDEOGRAPH-2F9F7;Lo;0;L;2921A;;;;N;;;;; 2F9F8;CJK COMPATIBILITY IDEOGRAPH-2F9F8;Lo;0;L;4A6E;;;;N;;;;; 2F9F9;CJK COMPATIBILITY IDEOGRAPH-2F9F9;Lo;0;L;4A76;;;;N;;;;; 2F9FA;CJK COMPATIBILITY IDEOGRAPH-2F9FA;Lo;0;L;97E0;;;;N;;;;; 2F9FB;CJK COMPATIBILITY IDEOGRAPH-2F9FB;Lo;0;L;2940A;;;;N;;;;; 2F9FC;CJK COMPATIBILITY IDEOGRAPH-2F9FC;Lo;0;L;4AB2;;;;N;;;;; 2F9FD;CJK COMPATIBILITY IDEOGRAPH-2F9FD;Lo;0;L;29496;;;;N;;;;; 2F9FE;CJK COMPATIBILITY IDEOGRAPH-2F9FE;Lo;0;L;980B;;;;N;;;;; 2F9FF;CJK COMPATIBILITY IDEOGRAPH-2F9FF;Lo;0;L;980B;;;;N;;;;; 2FA00;CJK COMPATIBILITY IDEOGRAPH-2FA00;Lo;0;L;9829;;;;N;;;;; 2FA01;CJK COMPATIBILITY IDEOGRAPH-2FA01;Lo;0;L;295B6;;;;N;;;;; 2FA02;CJK COMPATIBILITY IDEOGRAPH-2FA02;Lo;0;L;98E2;;;;N;;;;; 2FA03;CJK COMPATIBILITY IDEOGRAPH-2FA03;Lo;0;L;4B33;;;;N;;;;; 2FA04;CJK COMPATIBILITY IDEOGRAPH-2FA04;Lo;0;L;9929;;;;N;;;;; 2FA05;CJK COMPATIBILITY IDEOGRAPH-2FA05;Lo;0;L;99A7;;;;N;;;;; 2FA06;CJK COMPATIBILITY IDEOGRAPH-2FA06;Lo;0;L;99C2;;;;N;;;;; 2FA07;CJK COMPATIBILITY IDEOGRAPH-2FA07;Lo;0;L;99FE;;;;N;;;;; 2FA08;CJK COMPATIBILITY IDEOGRAPH-2FA08;Lo;0;L;4BCE;;;;N;;;;; 2FA09;CJK COMPATIBILITY IDEOGRAPH-2FA09;Lo;0;L;29B30;;;;N;;;;; 2FA0A;CJK COMPATIBILITY IDEOGRAPH-2FA0A;Lo;0;L;9B12;;;;N;;;;; 2FA0B;CJK COMPATIBILITY IDEOGRAPH-2FA0B;Lo;0;L;9C40;;;;N;;;;; 2FA0C;CJK COMPATIBILITY IDEOGRAPH-2FA0C;Lo;0;L;9CFD;;;;N;;;;; 2FA0D;CJK COMPATIBILITY IDEOGRAPH-2FA0D;Lo;0;L;4CCE;;;;N;;;;; 2FA0E;CJK COMPATIBILITY IDEOGRAPH-2FA0E;Lo;0;L;4CED;;;;N;;;;; 2FA0F;CJK COMPATIBILITY IDEOGRAPH-2FA0F;Lo;0;L;9D67;;;;N;;;;; 2FA10;CJK COMPATIBILITY IDEOGRAPH-2FA10;Lo;0;L;2A0CE;;;;N;;;;; 2FA11;CJK COMPATIBILITY IDEOGRAPH-2FA11;Lo;0;L;4CF8;;;;N;;;;; 2FA12;CJK COMPATIBILITY IDEOGRAPH-2FA12;Lo;0;L;2A105;;;;N;;;;; 2FA13;CJK COMPATIBILITY IDEOGRAPH-2FA13;Lo;0;L;2A20E;;;;N;;;;; 2FA14;CJK COMPATIBILITY IDEOGRAPH-2FA14;Lo;0;L;2A291;;;;N;;;;; 2FA15;CJK COMPATIBILITY IDEOGRAPH-2FA15;Lo;0;L;9EBB;;;;N;;;;; 2FA16;CJK COMPATIBILITY IDEOGRAPH-2FA16;Lo;0;L;4D56;;;;N;;;;; 2FA17;CJK COMPATIBILITY IDEOGRAPH-2FA17;Lo;0;L;9EF9;;;;N;;;;; 2FA18;CJK COMPATIBILITY IDEOGRAPH-2FA18;Lo;0;L;9EFE;;;;N;;;;; 2FA19;CJK COMPATIBILITY IDEOGRAPH-2FA19;Lo;0;L;9F05;;;;N;;;;; 2FA1A;CJK COMPATIBILITY IDEOGRAPH-2FA1A;Lo;0;L;9F0F;;;;N;;;;; 2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;; 2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;; 2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;; E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;; E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;; E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;; E0022;TAG QUOTATION MARK;Cf;0;BN;;;;;N;;;;; E0023;TAG NUMBER SIGN;Cf;0;BN;;;;;N;;;;; E0024;TAG DOLLAR SIGN;Cf;0;BN;;;;;N;;;;; E0025;TAG PERCENT SIGN;Cf;0;BN;;;;;N;;;;; E0026;TAG AMPERSAND;Cf;0;BN;;;;;N;;;;; E0027;TAG APOSTROPHE;Cf;0;BN;;;;;N;;;;; E0028;TAG LEFT PARENTHESIS;Cf;0;BN;;;;;N;;;;; E0029;TAG RIGHT PARENTHESIS;Cf;0;BN;;;;;N;;;;; E002A;TAG ASTERISK;Cf;0;BN;;;;;N;;;;; E002B;TAG PLUS SIGN;Cf;0;BN;;;;;N;;;;; E002C;TAG COMMA;Cf;0;BN;;;;;N;;;;; E002D;TAG HYPHEN-MINUS;Cf;0;BN;;;;;N;;;;; E002E;TAG FULL STOP;Cf;0;BN;;;;;N;;;;; E002F;TAG SOLIDUS;Cf;0;BN;;;;;N;;;;; E0030;TAG DIGIT ZERO;Cf;0;BN;;;;;N;;;;; E0031;TAG DIGIT ONE;Cf;0;BN;;;;;N;;;;; E0032;TAG DIGIT TWO;Cf;0;BN;;;;;N;;;;; E0033;TAG DIGIT THREE;Cf;0;BN;;;;;N;;;;; E0034;TAG DIGIT FOUR;Cf;0;BN;;;;;N;;;;; E0035;TAG DIGIT FIVE;Cf;0;BN;;;;;N;;;;; E0036;TAG DIGIT SIX;Cf;0;BN;;;;;N;;;;; E0037;TAG DIGIT SEVEN;Cf;0;BN;;;;;N;;;;; E0038;TAG DIGIT EIGHT;Cf;0;BN;;;;;N;;;;; E0039;TAG DIGIT NINE;Cf;0;BN;;;;;N;;;;; E003A;TAG COLON;Cf;0;BN;;;;;N;;;;; E003B;TAG SEMICOLON;Cf;0;BN;;;;;N;;;;; E003C;TAG LESS-THAN SIGN;Cf;0;BN;;;;;N;;;;; E003D;TAG EQUALS SIGN;Cf;0;BN;;;;;N;;;;; E003E;TAG GREATER-THAN SIGN;Cf;0;BN;;;;;N;;;;; E003F;TAG QUESTION MARK;Cf;0;BN;;;;;N;;;;; E0040;TAG COMMERCIAL AT;Cf;0;BN;;;;;N;;;;; E0041;TAG LATIN CAPITAL LETTER A;Cf;0;BN;;;;;N;;;;; E0042;TAG LATIN CAPITAL LETTER B;Cf;0;BN;;;;;N;;;;; E0043;TAG LATIN CAPITAL LETTER C;Cf;0;BN;;;;;N;;;;; E0044;TAG LATIN CAPITAL LETTER D;Cf;0;BN;;;;;N;;;;; E0045;TAG LATIN CAPITAL LETTER E;Cf;0;BN;;;;;N;;;;; E0046;TAG LATIN CAPITAL LETTER F;Cf;0;BN;;;;;N;;;;; E0047;TAG LATIN CAPITAL LETTER G;Cf;0;BN;;;;;N;;;;; E0048;TAG LATIN CAPITAL LETTER H;Cf;0;BN;;;;;N;;;;; E0049;TAG LATIN CAPITAL LETTER I;Cf;0;BN;;;;;N;;;;; E004A;TAG LATIN CAPITAL LETTER J;Cf;0;BN;;;;;N;;;;; E004B;TAG LATIN CAPITAL LETTER K;Cf;0;BN;;;;;N;;;;; E004C;TAG LATIN CAPITAL LETTER L;Cf;0;BN;;;;;N;;;;; E004D;TAG LATIN CAPITAL LETTER M;Cf;0;BN;;;;;N;;;;; E004E;TAG LATIN CAPITAL LETTER N;Cf;0;BN;;;;;N;;;;; E004F;TAG LATIN CAPITAL LETTER O;Cf;0;BN;;;;;N;;;;; E0050;TAG LATIN CAPITAL LETTER P;Cf;0;BN;;;;;N;;;;; E0051;TAG LATIN CAPITAL LETTER Q;Cf;0;BN;;;;;N;;;;; E0052;TAG LATIN CAPITAL LETTER R;Cf;0;BN;;;;;N;;;;; E0053;TAG LATIN CAPITAL LETTER S;Cf;0;BN;;;;;N;;;;; E0054;TAG LATIN CAPITAL LETTER T;Cf;0;BN;;;;;N;;;;; E0055;TAG LATIN CAPITAL LETTER U;Cf;0;BN;;;;;N;;;;; E0056;TAG LATIN CAPITAL LETTER V;Cf;0;BN;;;;;N;;;;; E0057;TAG LATIN CAPITAL LETTER W;Cf;0;BN;;;;;N;;;;; E0058;TAG LATIN CAPITAL LETTER X;Cf;0;BN;;;;;N;;;;; E0059;TAG LATIN CAPITAL LETTER Y;Cf;0;BN;;;;;N;;;;; E005A;TAG LATIN CAPITAL LETTER Z;Cf;0;BN;;;;;N;;;;; E005B;TAG LEFT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; E005C;TAG REVERSE SOLIDUS;Cf;0;BN;;;;;N;;;;; E005D;TAG RIGHT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;; E005E;TAG CIRCUMFLEX ACCENT;Cf;0;BN;;;;;N;;;;; E005F;TAG LOW LINE;Cf;0;BN;;;;;N;;;;; E0060;TAG GRAVE ACCENT;Cf;0;BN;;;;;N;;;;; E0061;TAG LATIN SMALL LETTER A;Cf;0;BN;;;;;N;;;;; E0062;TAG LATIN SMALL LETTER B;Cf;0;BN;;;;;N;;;;; E0063;TAG LATIN SMALL LETTER C;Cf;0;BN;;;;;N;;;;; E0064;TAG LATIN SMALL LETTER D;Cf;0;BN;;;;;N;;;;; E0065;TAG LATIN SMALL LETTER E;Cf;0;BN;;;;;N;;;;; E0066;TAG LATIN SMALL LETTER F;Cf;0;BN;;;;;N;;;;; E0067;TAG LATIN SMALL LETTER G;Cf;0;BN;;;;;N;;;;; E0068;TAG LATIN SMALL LETTER H;Cf;0;BN;;;;;N;;;;; E0069;TAG LATIN SMALL LETTER I;Cf;0;BN;;;;;N;;;;; E006A;TAG LATIN SMALL LETTER J;Cf;0;BN;;;;;N;;;;; E006B;TAG LATIN SMALL LETTER K;Cf;0;BN;;;;;N;;;;; E006C;TAG LATIN SMALL LETTER L;Cf;0;BN;;;;;N;;;;; E006D;TAG LATIN SMALL LETTER M;Cf;0;BN;;;;;N;;;;; E006E;TAG LATIN SMALL LETTER N;Cf;0;BN;;;;;N;;;;; E006F;TAG LATIN SMALL LETTER O;Cf;0;BN;;;;;N;;;;; E0070;TAG LATIN SMALL LETTER P;Cf;0;BN;;;;;N;;;;; E0071;TAG LATIN SMALL LETTER Q;Cf;0;BN;;;;;N;;;;; E0072;TAG LATIN SMALL LETTER R;Cf;0;BN;;;;;N;;;;; E0073;TAG LATIN SMALL LETTER S;Cf;0;BN;;;;;N;;;;; E0074;TAG LATIN SMALL LETTER T;Cf;0;BN;;;;;N;;;;; E0075;TAG LATIN SMALL LETTER U;Cf;0;BN;;;;;N;;;;; E0076;TAG LATIN SMALL LETTER V;Cf;0;BN;;;;;N;;;;; E0077;TAG LATIN SMALL LETTER W;Cf;0;BN;;;;;N;;;;; E0078;TAG LATIN SMALL LETTER X;Cf;0;BN;;;;;N;;;;; E0079;TAG LATIN SMALL LETTER Y;Cf;0;BN;;;;;N;;;;; E007A;TAG LATIN SMALL LETTER Z;Cf;0;BN;;;;;N;;;;; E007B;TAG LEFT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; E007C;TAG VERTICAL LINE;Cf;0;BN;;;;;N;;;;; E007D;TAG RIGHT CURLY BRACKET;Cf;0;BN;;;;;N;;;;; E007E;TAG TILDE;Cf;0;BN;;;;;N;;;;; E007F;CANCEL TAG;Cf;0;BN;;;;;N;;;;; F0000;;Co;0;L;;;;;N;;;;; FFFFD;;Co;0;L;;;;;N;;;;; 100000;;Co;0;L;;;;;N;;;;; 10FFFD;;Co;0;L;;;;;N;;;;; krb5-1.22.1/src/lib/krb5/krb5_libinit.h0000664000175000017500000000036715051422640017275 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #ifndef KRB5_LIBINIT_H #define KRB5_LIBINIT_H #include "krb5.h" krb5_error_code krb5int_initialize_library (void); void krb5int_cleanup_library (void); #endif /* KRB5_LIBINIT_H */ krb5-1.22.1/src/lib/krb5/libkrb5.exports0000664000175000017500000003572615051422640017536 0ustar ghudsonghudson_krb5_conf_boolean decode_krb5_ad_kdcissued decode_krb5_ap_rep decode_krb5_ap_rep_enc_part decode_krb5_ap_req decode_krb5_as_rep decode_krb5_as_req decode_krb5_authdata decode_krb5_authenticator decode_krb5_cammac decode_krb5_cred decode_krb5_enc_cred_part decode_krb5_enc_data decode_krb5_enc_kdc_rep_part decode_krb5_enc_priv_part decode_krb5_enc_sam_response_enc_2 decode_krb5_enc_tkt_part decode_krb5_encryption_key decode_krb5_error decode_krb5_etype_info decode_krb5_etype_info2 decode_krb5_fast_req decode_krb5_fast_response decode_krb5_iakerb_finished decode_krb5_iakerb_header decode_krb5_kdc_req_body decode_krb5_otp_tokeninfo decode_krb5_kkdcp_message decode_krb5_pa_enc_ts decode_krb5_pa_for_user decode_krb5_pa_fx_fast_reply decode_krb5_pa_fx_fast_request decode_krb5_pa_otp_challenge decode_krb5_pa_otp_req decode_krb5_pa_otp_enc_req decode_krb5_pa_pac_options decode_krb5_pa_pac_req decode_krb5_pa_s4u_x509_user decode_krb5_pa_spake decode_krb5_padata_sequence decode_krb5_priv decode_krb5_safe decode_krb5_sam_challenge_2 decode_krb5_sam_challenge_2_body decode_krb5_sam_response_2 decode_krb5_secure_cookie decode_krb5_setpw_req decode_krb5_spake_factor decode_krb5_tgs_rep decode_krb5_tgs_req decode_krb5_ticket decode_krb5_typed_data decode_utf8_strings encode_krb5_ad_kdcissued encode_krb5_ap_rep encode_krb5_ap_rep_enc_part encode_krb5_ap_req encode_krb5_as_rep encode_krb5_as_req encode_krb5_authdata encode_krb5_authenticator encode_krb5_cammac encode_krb5_checksum encode_krb5_cred encode_krb5_enc_cred_part encode_krb5_enc_data encode_krb5_enc_kdc_rep_part encode_krb5_enc_priv_part encode_krb5_enc_sam_response_enc_2 encode_krb5_enc_tkt_part encode_krb5_encryption_key encode_krb5_error encode_krb5_etype_info encode_krb5_etype_info2 encode_krb5_fast_response encode_krb5_iakerb_finished encode_krb5_iakerb_header encode_krb5_kdc_req_body encode_krb5_otp_tokeninfo encode_krb5_kkdcp_message encode_krb5_pa_enc_ts encode_krb5_pa_for_user encode_krb5_pa_fx_fast_reply encode_krb5_pa_otp_challenge encode_krb5_pa_otp_req encode_krb5_pa_otp_enc_req encode_krb5_pa_pac_options encode_krb5_pa_s4u_x509_user encode_krb5_pa_spake encode_krb5_padata_sequence encode_krb5_pkinit_supp_pub_info encode_krb5_priv encode_krb5_s4u_userid encode_krb5_safe encode_krb5_sam_challenge_2 encode_krb5_sam_challenge_2_body encode_krb5_sam_response_2 encode_krb5_secure_cookie encode_krb5_sp80056a_other_info encode_krb5_spake_factor encode_krb5_tgs_rep encode_krb5_tgs_req encode_krb5_ticket encode_krb5_typed_data encode_utf8_strings et_asn1_error_table et_k524_error_table et_kdb5_error_table et_krb5_error_table et_kv5m_error_table et_prof_error_table initialize_asn1_error_table initialize_k524_error_table initialize_kdb5_error_table initialize_krb5_error_table initialize_k5e1_error_table initialize_kv5m_error_table initialize_prof_error_table k5_add_empty_pa_data k5_add_pa_data_element k5_add_pa_data_from_data k5_addr_directional_accept k5_addr_directional_init k5_alloc_pa_data k5_authind_decode k5_build_conf_principals k5_cc_store_primary_cred k5_ccselect_free_context k5_change_error_message_code k5_etypes_contains k5_expand_path_tokens k5_expand_path_tokens_extra k5_externalize_auth_context k5_externalize_authdata k5_externalize_authdata_context k5_externalize_context k5_externalize_keyblock k5_externalize_principal k5_free_algorithm_identifier k5_free_cammac k5_free_data_ptr_list k5_free_otp_tokeninfo k5_free_kkdcp_message k5_free_pa_data_element k5_free_pa_otp_challenge k5_free_pa_otp_req k5_free_secure_cookie k5_free_pa_spake k5_free_serverlist k5_free_spake_factor k5_hostrealm_free_context k5_init_trace k5_internalize_auth_context k5_internalize_authdata k5_internalize_authdata_context k5_internalize_context k5_internalize_keyblock k5_internalize_principal k5_is_string_numeric k5_kt_get_principal k5_kt_have_match k5_localauth_free_context k5_locate_kdc k5_marshal_cred k5_marshal_princ k5_os_free_context k5_os_init_context k5_parse_host_string k5_plugin_free_modules k5_plugin_load k5_plugin_load_all k5_plugin_register k5_plugin_register_dyn k5_print_addr k5_print_addr_port k5_rc_close k5_rc_get_name k5_rc_resolve k5_rc_store k5_size_auth_context k5_size_authdata k5_size_authdata_context k5_size_context k5_size_keyblock k5_size_principal k5_sname_compare k5_sockaddr_to_address k5_unmarshal_cred k5_unmarshal_princ k5_unwrap_cammac_svc k5_zapfree_pa_data krb524_convert_creds_kdc krb524_init_ets krb5_425_conv_principal krb5_524_conv_principal krb5_524_convert_creds krb5_address_compare krb5_address_order krb5_address_search krb5_allow_weak_crypto krb5_aname_to_localname krb5_anonymous_principal krb5_anonymous_realm krb5_appdefault_boolean krb5_appdefault_string krb5_auth_con_free krb5_auth_con_genaddrs krb5_auth_con_get_checksum_func krb5_auth_con_get_authdata_context krb5_auth_con_getaddrs krb5_auth_con_getauthenticator krb5_auth_con_getflags krb5_auth_con_getivector krb5_auth_con_getkey krb5_auth_con_getkey_k krb5_auth_con_getlocalseqnumber krb5_auth_con_getlocalsubkey krb5_auth_con_getpermetypes krb5_auth_con_getrcache krb5_auth_con_getrecvsubkey krb5_auth_con_getrecvsubkey_k krb5_auth_con_getremoteseqnumber krb5_auth_con_getremotesubkey krb5_auth_con_getsendsubkey krb5_auth_con_getsendsubkey_k krb5_auth_con_init krb5_auth_con_initivector krb5_auth_con_set_authdata_context krb5_auth_con_set_checksum_func krb5_auth_con_set_req_cksumtype krb5_auth_con_set_safe_cksumtype krb5_auth_con_setaddrs krb5_auth_con_setflags krb5_auth_con_setivector krb5_auth_con_setpermetypes krb5_auth_con_setports krb5_auth_con_setrcache krb5_auth_con_setrecvsubkey krb5_auth_con_setrecvsubkey_k krb5_auth_con_setsendsubkey krb5_auth_con_setsendsubkey_k krb5_auth_con_setuseruserkey krb5_authdata_context_copy krb5_authdata_context_free krb5_authdata_context_init krb5_authdata_delete_attribute krb5_authdata_get_attribute_types krb5_authdata_get_attribute krb5_authdata_set_attribute krb5_authdata_export_attributes krb5_authdata_export_authdata krb5_authdata_export_internal krb5_authdata_free_internal krb5_authdata_import_attributes krb5_build_principal krb5_build_principal_alloc_va krb5_build_principal_ext krb5_build_principal_va krb5_cc_cache_match krb5_cc_close krb5_cc_copy_creds krb5_cc_default krb5_cc_default_name krb5_cc_destroy krb5_cc_dfl_ops krb5_cc_dup krb5_cc_end_seq_get krb5_cc_file_ops krb5_cc_gen_new krb5_cc_get_config krb5_cc_get_full_name krb5_cc_get_name krb5_cc_get_principal krb5_cc_get_type krb5_cc_move krb5_cc_initialize krb5_cc_new_unique krb5_cc_next_cred krb5_cc_register krb5_cc_remove_cred krb5_cc_resolve krb5_cc_retrieve_cred krb5_cc_select krb5_cc_set_config krb5_cc_set_default_name krb5_cc_set_flags krb5_cc_start_seq_get krb5_cc_store_cred krb5_cc_support_switch krb5_cc_switch krb5_cccol_cursor_free krb5_cccol_cursor_new krb5_cccol_cursor_next krb5_cccol_have_content krb5_change_cache krb5_change_password krb5_check_clockskew krb5_check_transited_list krb5_chpw_message krb5_chpw_result_code_string krb5_clear_error_message krb5_copy_addr krb5_copy_addresses krb5_copy_authdata krb5_copy_authenticator krb5_copy_checksum krb5_copy_context krb5_copy_creds krb5_copy_data krb5_copy_error_message krb5_copy_keyblock krb5_copy_keyblock_contents krb5_copy_principal krb5_copy_ticket krb5_crypto_us_timeofday krb5_decode_authdata_container krb5_decode_ticket krb5_decrypt_tkt_part krb5_deltat_to_string krb5_encode_authdata_container krb5_encode_kdc_rep krb5_encrypt_helper krb5_encrypt_tkt_part krb5_expand_hostname krb5_fcc_ops krb5_find_authdata krb5_free_ad_kdcissued krb5_free_address krb5_free_addresses krb5_free_ap_rep krb5_free_ap_rep_enc_part krb5_free_ap_req krb5_free_authdata krb5_free_authenticator krb5_free_authenticator_contents krb5_free_checksum krb5_free_checksum_contents krb5_free_config_files krb5_free_context krb5_free_cred krb5_free_cred_contents krb5_free_cred_enc_part krb5_free_creds krb5_free_data krb5_free_data_contents krb5_free_default_realm krb5_free_enc_data krb5_free_enc_kdc_rep_part krb5_free_enc_sam_response_enc_2 krb5_free_enc_sam_response_enc_2_contents krb5_free_enc_tkt_part krb5_free_enctypes krb5_free_error krb5_free_error_message krb5_free_etype_info krb5_free_fast_armored_req krb5_free_fast_req krb5_free_fast_response krb5_free_host_realm krb5_free_iakerb_finished krb5_free_iakerb_header krb5_free_kdc_rep krb5_free_kdc_req krb5_free_keyblock krb5_free_keyblock_contents krb5_free_keytab_entry_contents krb5_free_last_req krb5_free_octet_data krb5_free_pa_data krb5_free_pa_enc_ts krb5_free_pa_for_user krb5_free_pa_pac_req krb5_free_pa_s4u_x509_user krb5_free_principal krb5_free_priv krb5_free_priv_enc_part krb5_free_realm_tree krb5_free_safe krb5_free_sam_challenge_2 krb5_free_sam_challenge_2_body krb5_free_sam_challenge_2_body_contents krb5_free_sam_challenge_2_contents krb5_free_sam_response_2 krb5_free_sam_response_2_contents krb5_free_string krb5_free_tgt_creds krb5_free_ticket krb5_free_tickets krb5_free_tkt_authent krb5_free_unparsed_name krb5_fwd_tgt_creds krb5_gen_portaddr krb5_gen_replay_name krb5_generate_seq_number krb5_generate_subkey krb5_get_cred_via_tkt krb5_get_credentials krb5_get_credentials_for_proxy krb5_get_credentials_for_user krb5_get_credentials_renew krb5_get_credentials_validate krb5_get_default_config_files krb5_get_default_in_tkt_ktypes krb5_get_default_realm krb5_get_error_message krb5_get_etype_info krb5_get_fallback_host_realm krb5_get_host_realm krb5_get_in_tkt_with_keytab krb5_get_in_tkt_with_password krb5_get_in_tkt_with_skey krb5_get_init_creds_keytab krb5_get_init_creds_opt_alloc krb5_get_init_creds_opt_free krb5_get_init_creds_opt_free_pa krb5_get_init_creds_opt_get_fast_flags krb5_get_init_creds_opt_get_pa krb5_get_init_creds_opt_init krb5_get_init_creds_opt_set_address_list krb5_get_init_creds_opt_set_anonymous krb5_get_init_creds_opt_set_canonicalize krb5_get_init_creds_opt_set_change_password_prompt krb5_get_init_creds_opt_set_etype_list krb5_get_init_creds_opt_set_expire_callback krb5_get_init_creds_opt_set_fast_ccache krb5_get_init_creds_opt_set_fast_ccache_name krb5_get_init_creds_opt_set_fast_flags krb5_get_init_creds_opt_set_forwardable krb5_get_init_creds_opt_set_in_ccache krb5_get_init_creds_opt_set_out_ccache krb5_get_init_creds_opt_set_pa krb5_get_init_creds_opt_set_pac_request krb5_get_init_creds_opt_set_preauth_list krb5_get_init_creds_opt_set_proxiable krb5_get_init_creds_opt_set_renew_life krb5_get_init_creds_opt_set_responder krb5_get_init_creds_opt_set_salt krb5_get_init_creds_opt_set_tkt_life krb5_get_init_creds_password krb5_get_notification_message krb5_get_permitted_enctypes krb5_get_profile krb5_get_prompt_types krb5_get_realm_domain krb5_get_renewed_creds krb5_get_server_rcache krb5_get_tgs_ktypes krb5_get_time_offsets krb5_get_validated_creds krb5_init_context krb5_init_context_profile krb5_init_creds_free krb5_init_creds_get krb5_init_creds_get_creds krb5_init_creds_get_error krb5_init_creds_get_times krb5_init_creds_init krb5_init_creds_set_keytab krb5_init_creds_set_password krb5_init_creds_set_service krb5_init_creds_step krb5_init_keyblock krb5_init_secure_context krb5_is_config_principal krb5_is_permitted_enctype krb5_is_referral_realm krb5_is_thread_safe krb5_kdc_rep_decrypt_proc krb5_kdc_sign_ticket krb5_kdc_verify_ticket krb5_kt_add_entry krb5_kt_client_default krb5_kt_close krb5_kt_default krb5_kt_default_name krb5_kt_dfl_ops krb5_kt_dup krb5_kt_end_seq_get krb5_kt_free_entry krb5_kt_get_entry krb5_kt_get_name krb5_kt_get_type krb5_kt_have_content krb5_kt_next_entry krb5_kt_read_service_key krb5_kt_register krb5_kt_remove_entry krb5_kt_resolve krb5_kt_start_seq_get krb5_ktf_ops krb5_ktf_writable_ops krb5_kuserok krb5_lock_file krb5_make_authdata_kdc_issued krb5_make_full_ipaddr krb5_make_fulladdr krb5_marshal_credentials krb5_mcc_ops krb5_merge_authdata krb5_mk_1cred krb5_mk_error krb5_mk_ncred krb5_mk_priv krb5_mk_rep krb5_mk_rep_dce krb5_mk_req krb5_mk_req_extended krb5_mk_safe krb5_net_read krb5_net_write krb5_os_localaddr krb5_overridekeyname krb5_pac_add_buffer krb5_pac_free krb5_pac_get_buffer krb5_pac_get_types krb5_pac_init krb5_pac_parse krb5_pac_sign krb5_pac_sign_ext krb5_pac_verify krb5_pac_verify_ext krb5_pac_get_client_info krb5_parse_name krb5_parse_name_flags krb5_prepend_error_message krb5_principal2salt krb5_principal2salt_norealm krb5_principal_compare krb5_principal_compare_any_realm krb5_principal_compare_flags krb5_prompter_posix krb5_rc_default krb5_rc_destroy krb5_rc_get_lifespan krb5_rc_initialize krb5_rd_cred krb5_rd_error krb5_rd_priv krb5_rd_rep krb5_rd_rep_dce krb5_rd_req krb5_rd_req_decoded krb5_rd_req_decoded_anyflag krb5_rd_safe krb5_read_message krb5_read_password krb5_realm_compare krb5_recvauth krb5_recvauth_version krb5_responder_get_challenge krb5_responder_list_questions krb5_responder_set_answer krb5_responder_otp_get_challenge krb5_responder_otp_set_answer krb5_responder_otp_challenge_free krb5_responder_pkinit_get_challenge krb5_responder_pkinit_set_answer krb5_responder_pkinit_challenge_free krb5_salttype_to_string krb5_sendauth krb5_sendto_kdc krb5_ser_pack_bytes krb5_ser_pack_int32 krb5_ser_pack_int64 krb5_ser_unpack_bytes krb5_ser_unpack_int32 krb5_ser_unpack_int64 krb5_server_decrypt_ticket_keytab krb5_set_config_files krb5_set_debugging_time krb5_set_default_realm krb5_set_default_tgs_enctypes krb5_set_default_tgs_ktypes krb5_set_error_message krb5_set_password krb5_set_password_using_ccache krb5_set_principal_realm krb5_set_real_time krb5_set_kdc_send_hook krb5_set_kdc_recv_hook krb5_set_time_offsets krb5_set_trace_callback krb5_set_trace_filename krb5_sname_match krb5_sname_to_principal krb5_string_to_deltat krb5_string_to_salttype krb5_string_to_timestamp krb5int_tgtname krb5_tkt_creds_free krb5_tkt_creds_get krb5_tkt_creds_get_creds krb5_tkt_creds_get_times krb5_tkt_creds_init krb5_tkt_creds_step krb5_timeofday krb5_timestamp_to_sfstring krb5_timestamp_to_string krb5_unlock_file krb5_unmarshal_credentials krb5_unpack_full_ipaddr krb5_unparse_name krb5_unparse_name_ext krb5_unparse_name_flags krb5_unparse_name_flags_ext krb5_us_timeofday krb5_use_natural_time krb5_verify_authdata_kdc_issued krb5_verify_init_creds krb5_verify_init_creds_opt_init krb5_verify_init_creds_opt_set_ap_req_nofail krb5_vprepend_error_message krb5_vset_error_message krb5_vwrap_error_message krb5_walk_realm_tree krb5_wrap_error_message krb5_write_message krb5int_accessor krb5int_cc_default krb5int_cleanup_library krb5int_copy_data_contents krb5int_copy_data_contents_add0 krb5int_find_pa_data krb5int_foreach_localaddr krb5int_free_data_list krb5int_get_authdata_containee_types krb5int_init_context_kdc krb5int_initialize_library krb5int_parse_enctype_list krb5int_random_string krb5int_trace profile_abandon profile_add_relation profile_clear_relation profile_flush profile_flush_to_buffer profile_flush_to_file profile_free_buffer profile_free_list profile_get_boolean profile_get_integer profile_get_relation_names profile_get_string profile_get_subsection_names profile_get_values profile_init profile_init_flags profile_init_path profile_init_vtable profile_iterator profile_iterator_create profile_iterator_free profile_release profile_release_string profile_rename_section profile_ser_externalize profile_ser_internalize profile_ser_size profile_update_relation krb5-1.22.1/src/lib/krb5/asn.1/0000775000175000017500000000000015051422640015461 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/asn.1/Makefile.in0000664000175000017500000000103415051422640017524 0ustar ghudsonghudsonmydir=lib$(S)krb5$(S)asn.1 BUILDTOP=$(REL)..$(S)..$(S).. ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=asn.1 ##DOS##OBJFILE=..\$(OUTPRE)asn1.lst EHDRDIR=$(BUILDTOP)/include/krb5/asn.1 STLIBOBJS= \ asn1_encode.o\ asn1_k_encode.o\ ldap_key_seq.o SRCS= \ $(srcdir)/asn1_encode.c\ $(srcdir)/asn1_k_encode.c\ $(srcdir)/ldap_key_seq.c OBJS= \ $(OUTPRE)asn1_encode.$(OBJEXT)\ $(OUTPRE)asn1_k_encode.$(OBJEXT)\ $(OUTPRE)ldap_key_seq.$(OBJEXT) ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/krb5/asn.1/asn1_encode.h0000664000175000017500000006365515051422640020030 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/asn.1/asn1_encode.h */ /* * Copyright 1994, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef __ASN1_ENCODE_H__ #define __ASN1_ENCODE_H__ #include "k5-int.h" #include "krbasn1.h" #include typedef struct asn1buf_st asn1buf; typedef struct { asn1_class asn1class; asn1_construction construction; asn1_tagnum tagnum; /* When decoding, stores the leading length of a tag. Used by * store_der(). */ size_t tag_len; } taginfo; /* These functions are referenced by encoder structures. They handle the * encoding of primitive ASN.1 types. */ void k5_asn1_encode_bool(asn1buf *buf, intmax_t val); void k5_asn1_encode_int(asn1buf *buf, intmax_t val); void k5_asn1_encode_uint(asn1buf *buf, uintmax_t val); krb5_error_code k5_asn1_encode_bytestring(asn1buf *buf, uint8_t *const *val, size_t len); krb5_error_code k5_asn1_encode_bitstring(asn1buf *buf, uint8_t *const *val, size_t len); krb5_error_code k5_asn1_encode_generaltime(asn1buf *buf, time_t val); /* These functions are referenced by encoder structures. They handle the * decoding of primitive ASN.1 types. */ krb5_error_code k5_asn1_decode_bool(const uint8_t *asn1, size_t len, intmax_t *val); krb5_error_code k5_asn1_decode_int(const uint8_t *asn1, size_t len, intmax_t *val); krb5_error_code k5_asn1_decode_uint(const uint8_t *asn1, size_t len, uintmax_t *val); krb5_error_code k5_asn1_decode_generaltime(const uint8_t *asn1, size_t len, time_t *time_out); krb5_error_code k5_asn1_decode_bytestring(const uint8_t *asn1, size_t len, uint8_t **str_out, size_t *len_out); krb5_error_code k5_asn1_decode_bitstring(const uint8_t *asn1, size_t len, uint8_t **bits_out, size_t *len_out); /* * An atype_info structure specifies how to map a C object to an ASN.1 value. * * We wind up with a lot of load-time relocations being done, which is * a bit annoying. Be careful about "fixing" that at the cost of too * much run-time performance. It might work to have a master "module" * descriptor with pointers to various arrays (type descriptors, * strings, field descriptors, functions) most of which don't need * relocation themselves, and replace most of the pointers with table * indices. * * It's a work in progress. */ enum atype_type { /* For bounds checking only. By starting with 2, we guarantee that * zero-initialized storage will be recognized as invalid. */ atype_min = 1, /* Use a function table to handle encoding or decoding. tinfo is a struct * fn_info *. */ atype_fn, /* C object is a pointer to the object to be encoded or decoded. tinfo is * a struct ptr_info *. */ atype_ptr, /* C object to be encoded or decoded is at an offset from the original * pointer. tinfo is a struct offset_info *. */ atype_offset, /* * Indicates a sequence field which may or may not be present in the C * object or ASN.1 sequence. tinfo is a struct optional_info *. Must be * used within a sequence, although the optional type may be nested within * offset, ptr, and/or tag types. */ atype_optional, /* * C object contains an integer and another C object at specified offsets, * to be combined and encoded or decoded as specified by a cntype_info * structure. tinfo is a struct counted_info *. */ atype_counted, /* Sequence. tinfo is a struct seq_info *. */ atype_sequence, /* * Sequence-of, with pointer to base type descriptor, represented as a * null-terminated array of pointers (and thus the "base" type descriptor * is actually an atype_ptr node). tinfo is a struct atype_info * giving * the base type. */ atype_nullterm_sequence_of, atype_nonempty_nullterm_sequence_of, /* Tagged version of another type. tinfo is a struct tagged_info *. */ atype_tagged_thing, /* Boolean value. tinfo is NULL (size field determines C type width). */ atype_bool, /* Signed or unsigned integer. tinfo is NULL. */ atype_int, atype_uint, /* * Integer value taken from the type info, not from the object being * encoded. tinfo is a struct immediate_info * giving the integer value * and error code to return if a decoded object doesn't match it (or 0 if * the value shouldn't be checked on decode). */ atype_int_immediate, /* Unused except for bounds checking. */ atype_max }; struct atype_info { enum atype_type type; size_t size; /* Used for sequence-of processing */ const void *tinfo; /* Points to type-specific structure */ }; struct fn_info { krb5_error_code (*enc)(asn1buf *, const void *, taginfo *); krb5_error_code (*dec)(const taginfo *, const uint8_t *, size_t, void *); int (*check_tag)(const taginfo *); void (*free_func)(void *); }; struct ptr_info { void *(*loadptr)(const void *); void (*storeptr)(void *, void *); const struct atype_info *basetype; }; struct offset_info { unsigned int dataoff : 9; const struct atype_info *basetype; }; struct optional_info { int (*is_present)(const void *); void (*init)(void *); const struct atype_info *basetype; }; struct counted_info { unsigned int dataoff : 9; unsigned int lenoff : 9; unsigned int lensigned : 1; unsigned int lensize : 5; const struct cntype_info *basetype; }; struct tagged_info { unsigned int tagval : 16, tagtype : 8, construction : 6, implicit : 1; const struct atype_info *basetype; }; struct immediate_info { intmax_t val; krb5_error_code err; }; /* A cntype_info structure specifies how to map a C object and count (length or * union distinguisher) to an ASN.1 value. */ enum cntype_type { cntype_min = 1, /* * Apply an encoder function (contents only) and wrap it in a universal * primitive tag. The C object must be a char * or uint8_t *. tinfo * is a struct string_info *. */ cntype_string, /* * The C object is a DER encoding (with tag), to be simply inserted on * encode or stored on decode. The C object must be a char * or unsigned * char *. tinfo is NULL. */ cntype_der, /* An ASN.1 sequence-of value, represtened in C as a counted array. struct * atype_info * giving the base type, which must be of type atype_ptr. */ cntype_seqof, /* An ASN.1 choice, represented in C as a distinguisher and union. tinfo * is a struct choice_info *. */ cntype_choice, cntype_max }; struct cntype_info { enum cntype_type type; const void *tinfo; }; struct string_info { krb5_error_code (*enc)(asn1buf *, uint8_t *const *, size_t); krb5_error_code (*dec)(const uint8_t *, size_t, uint8_t **, size_t *); unsigned int tagval : 5; }; struct choice_info { const struct atype_info **options; size_t n_options; }; struct seq_info { const struct atype_info **fields; size_t n_fields; /* Currently all sequences are assumed to be extensible. */ }; /* * The various DEF*TYPE macros must: * * + Define a type named aux_type_##DESCNAME, for use in any types derived from * the type being defined. * * + Define an atype_info struct named k5_atype_##DESCNAME * * + Define a type-specific structure, referenced by the tinfo field * of the atype_info structure. * * + Define any extra stuff needed in the type descriptor, like * pointer-load functions. * * + Accept a following semicolon syntactically, to keep Emacs parsing * (and indentation calculating) code happy. * * Nothing else should directly define the atype_info structures. */ /* Define a type using a function table. */ #define DEFFNTYPE(DESCNAME, CTYPENAME, ENCFN, DECFN, CHECKFN, FREEFN) \ typedef CTYPENAME aux_type_##DESCNAME; \ static const struct fn_info aux_info_##DESCNAME = { \ ENCFN, DECFN, CHECKFN, FREEFN \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_fn, sizeof(CTYPENAME), &aux_info_##DESCNAME \ } /* A sequence, defined by the indicated series of types, and an optional * function indicating which fields are not present. */ #define DEFSEQTYPE(DESCNAME, CTYPENAME, FIELDS) \ typedef CTYPENAME aux_type_##DESCNAME; \ static const struct seq_info aux_seqinfo_##DESCNAME = { \ FIELDS, sizeof(FIELDS)/sizeof(FIELDS[0]) \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_sequence, sizeof(CTYPENAME), &aux_seqinfo_##DESCNAME \ } /* A boolean type. */ #define DEFBOOLTYPE(DESCNAME, CTYPENAME) \ typedef CTYPENAME aux_type_##DESCNAME; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_bool, sizeof(CTYPENAME), NULL \ } /* Integer types. */ #define DEFINTTYPE(DESCNAME, CTYPENAME) \ typedef CTYPENAME aux_type_##DESCNAME; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_int, sizeof(CTYPENAME), NULL \ } #define DEFUINTTYPE(DESCNAME, CTYPENAME) \ typedef CTYPENAME aux_type_##DESCNAME; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_uint, sizeof(CTYPENAME), NULL \ } #define DEFINT_IMMEDIATE(DESCNAME, VAL, ERR) \ typedef int aux_type_##DESCNAME; \ static const struct immediate_info aux_info_##DESCNAME = { \ VAL, ERR \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_int_immediate, 0, &aux_info_##DESCNAME \ } /* Pointers to other types, to be encoded as those other types. */ #ifdef POINTERS_ARE_ALL_THE_SAME #define DEFPTRTYPE(DESCNAME,BASEDESCNAME) \ typedef aux_type_##BASEDESCNAME *aux_type_##DESCNAME; \ static const struct ptr_info aux_info_##DESCNAME = { \ NULL, NULL, &k5_atype_##BASEDESCNAME \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_ptr, sizeof(aux_type_##DESCNAME), \ &aux_info_##DESCNAME \ } #else #define DEFPTRTYPE(DESCNAME,BASEDESCNAME) \ typedef aux_type_##BASEDESCNAME *aux_type_##DESCNAME; \ static void * \ aux_loadptr_##DESCNAME(const void *p) \ { \ return *(aux_type_##DESCNAME *)p; \ } \ static void \ aux_storeptr_##DESCNAME(void *ptr, void *val) \ { \ *(aux_type_##DESCNAME *)val = ptr; \ } \ static const struct ptr_info aux_info_##DESCNAME = { \ aux_loadptr_##DESCNAME, aux_storeptr_##DESCNAME, \ &k5_atype_##BASEDESCNAME \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_ptr, sizeof(aux_type_##DESCNAME), \ &aux_info_##DESCNAME \ } #endif #define DEFOFFSETTYPE(DESCNAME, STYPE, FIELDNAME, BASEDESC) \ typedef STYPE aux_type_##DESCNAME; \ static const struct offset_info aux_info_##DESCNAME = { \ OFFOF(STYPE, FIELDNAME, aux_type_##BASEDESC), \ &k5_atype_##BASEDESC \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_offset, sizeof(aux_type_##DESCNAME), \ &aux_info_##DESCNAME \ } #define DEFCOUNTEDTYPE_base(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, SIGNED, \ CDESC) \ typedef STYPE aux_type_##DESCNAME; \ const struct counted_info aux_info_##DESCNAME = { \ OFFOF(STYPE, DATAFIELD, aux_ptrtype_##CDESC), \ OFFOF(STYPE, COUNTFIELD, aux_counttype_##CDESC), \ SIGNED, sizeof(((STYPE*)0)->COUNTFIELD), \ &k5_cntype_##CDESC \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_counted, sizeof(STYPE), \ &aux_info_##DESCNAME \ } #define DEFCOUNTEDTYPE(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, CDESC) \ DEFCOUNTEDTYPE_base(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, 0, CDESC) #define DEFCOUNTEDTYPE_SIGNED(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, CDESC) \ DEFCOUNTEDTYPE_base(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, 1, CDESC) /* Optional sequence fields. The basic form allows arbitrary test and * initializer functions to be used. INIT may be null. */ #define DEFOPTIONALTYPE(DESCNAME, PRESENT, INIT, BASEDESC) \ typedef aux_type_##BASEDESC aux_type_##DESCNAME; \ static const struct optional_info aux_info_##DESCNAME = { \ PRESENT, INIT, &k5_atype_##BASEDESC \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_optional, sizeof(aux_type_##DESCNAME), \ &aux_info_##DESCNAME \ } /* This form defines an is_present function for a zero-valued integer or null * pointer of the base type's C type. */ #define DEFOPTIONALZEROTYPE(DESCNAME, BASEDESC) \ static int \ aux_present_##DESCNAME(const void *p) \ { \ return *(aux_type_##BASEDESC *)p != 0; \ } \ DEFOPTIONALTYPE(DESCNAME, aux_present_##DESCNAME, NULL, BASEDESC) /* This form defines an is_present function for a null or empty null-terminated * array of the base type's C type. */ #define DEFOPTIONALEMPTYTYPE(DESCNAME, BASEDESC) \ static int \ aux_present_##DESCNAME(const void *p) \ { \ const aux_type_##BASEDESC *val = p; \ return (*val != NULL && **val != NULL); \ } \ DEFOPTIONALTYPE(DESCNAME, aux_present_##DESCNAME, NULL, BASEDESC) /* * This encodes a pointer-to-pointer-to-thing where the passed-in * value points to a null-terminated list of pointers to objects to be * encoded, and encodes a (possibly empty) SEQUENCE OF these objects. * * BASEDESCNAME is a descriptor name for the pointer-to-thing * type. * * When dealing with a structure containing a * pointer-to-pointer-to-thing field, make a DEFPTRTYPE of this type, * and use that type for the structure field. */ #define DEFNULLTERMSEQOFTYPE(DESCNAME,BASEDESCNAME) \ typedef aux_type_##BASEDESCNAME aux_type_##DESCNAME; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_nullterm_sequence_of, sizeof(aux_type_##DESCNAME), \ &k5_atype_##BASEDESCNAME \ } #define DEFNONEMPTYNULLTERMSEQOFTYPE(DESCNAME,BASEDESCNAME) \ typedef aux_type_##BASEDESCNAME aux_type_##DESCNAME; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_nonempty_nullterm_sequence_of, \ sizeof(aux_type_##DESCNAME), \ &k5_atype_##BASEDESCNAME \ } /* Objects with an explicit or implicit tag. (Implicit tags will ignore the * construction field.) */ #define DEFTAGGEDTYPE(DESCNAME, CLASS, CONSTRUCTION, TAG, IMPLICIT, BASEDESC) \ typedef aux_type_##BASEDESC aux_type_##DESCNAME; \ static const struct tagged_info aux_info_##DESCNAME = { \ TAG, CLASS, CONSTRUCTION, IMPLICIT, &k5_atype_##BASEDESC \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_tagged_thing, sizeof(aux_type_##DESCNAME), \ &aux_info_##DESCNAME \ } /* Objects with an explicit APPLICATION tag added. */ #define DEFAPPTAGGEDTYPE(DESCNAME, TAG, BASEDESC) \ DEFTAGGEDTYPE(DESCNAME, APPLICATION, CONSTRUCTED, TAG, 0, BASEDESC) /* Object with a context-specific tag added */ #define DEFCTAGGEDTYPE(DESCNAME, TAG, BASEDESC) \ DEFTAGGEDTYPE(DESCNAME, CONTEXT_SPECIFIC, CONSTRUCTED, TAG, 0, BASEDESC) #define DEFCTAGGEDTYPE_IMPLICIT(DESCNAME, TAG, BASEDESC) \ DEFTAGGEDTYPE(DESCNAME, CONTEXT_SPECIFIC, CONSTRUCTED, TAG, 1, BASEDESC) /* Define an offset type with an explicit context tag wrapper (the usual case * for an RFC 4120 sequence field). */ #define DEFFIELD(NAME, STYPE, FIELDNAME, TAG, DESC) \ DEFOFFSETTYPE(NAME##_untagged, STYPE, FIELDNAME, DESC); \ DEFCTAGGEDTYPE(NAME, TAG, NAME##_untagged) /* Define a counted type with an explicit context tag wrapper. */ #define DEFCNFIELD(NAME, STYPE, DATAFIELD, LENFIELD, TAG, CDESC) \ DEFCOUNTEDTYPE(NAME##_untagged, STYPE, DATAFIELD, LENFIELD, CDESC); \ DEFCTAGGEDTYPE(NAME, TAG, NAME##_untagged) /* Like DEFFIELD but with an implicit context tag. */ #define DEFFIELD_IMPLICIT(NAME, STYPE, FIELDNAME, TAG, DESC) \ DEFOFFSETTYPE(NAME##_untagged, STYPE, FIELDNAME, DESC); \ DEFCTAGGEDTYPE_IMPLICIT(NAME, TAG, NAME##_untagged) /* * DEFCOUNTED*TYPE macros must: * * + Define types named aux_ptrtype_##DESCNAME and aux_counttype_##DESCNAME, to * allow type checking when the counted type is referenced with structure * field offsets in DEFCOUNTEDTYPE. * * + Define a cntype_info struct named k5_cntype_##DESCNAME * * + Define a type-specific structure, referenced by the tinfo field of the * cntype_info structure. * * + Accept a following semicolon syntactically. */ #define DEFCOUNTEDSTRINGTYPE(DESCNAME, DTYPE, LTYPE, ENCFN, DECFN, TAGVAL) \ typedef DTYPE aux_ptrtype_##DESCNAME; \ typedef LTYPE aux_counttype_##DESCNAME; \ static const struct string_info aux_info_##DESCNAME = { \ ENCFN, DECFN, TAGVAL \ }; \ const struct cntype_info k5_cntype_##DESCNAME = { \ cntype_string, &aux_info_##DESCNAME \ } #define DEFCOUNTEDDERTYPE(DESCNAME, DTYPE, LTYPE) \ typedef DTYPE aux_ptrtype_##DESCNAME; \ typedef LTYPE aux_counttype_##DESCNAME; \ const struct cntype_info k5_cntype_##DESCNAME = { \ cntype_der, NULL \ } #define DEFCOUNTEDSEQOFTYPE(DESCNAME, LTYPE, BASEDESC) \ typedef aux_type_##BASEDESC aux_ptrtype_##DESCNAME; \ typedef LTYPE aux_counttype_##DESCNAME; \ const struct cntype_info k5_cntype_##DESCNAME = { \ cntype_seqof, &k5_atype_##BASEDESC \ } #define DEFCHOICETYPE(DESCNAME, UTYPE, DTYPE, FIELDS) \ typedef UTYPE aux_ptrtype_##DESCNAME; \ typedef DTYPE aux_counttype_##DESCNAME; \ static const struct choice_info aux_info_##DESCNAME = { \ FIELDS, sizeof(FIELDS) / sizeof(FIELDS[0]) \ }; \ const struct cntype_info k5_cntype_##DESCNAME = { \ cntype_choice, &aux_info_##DESCNAME \ } /* * Declare an externally-defined type. This is a hack we should do * away with once we move to generating code from a script. For now, * this macro is unfortunately not compatible with the defining macros * above, since you can't do the typedefs twice and we need the * declarations to produce typedefs. (We could eliminate the typedefs * from the DEF* macros, but then every DEF* macro use, even the ones * for internal type nodes we only use to build other types, would * need an accompanying declaration which explicitly lists the * type.) */ #define IMPORT_TYPE(DESCNAME, CTYPENAME) \ typedef CTYPENAME aux_type_##DESCNAME; \ extern const struct atype_info k5_atype_##DESCNAME /* Partially encode the contents of a type and return its tag information. * Used only by kdc_req_body. */ krb5_error_code k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a, taginfo *tag_out); /* Decode the tag and contents of a type, storing the result in the * caller-allocated C object val. Used only by kdc_req_body. */ krb5_error_code k5_asn1_decode_atype(const taginfo *t, const uint8_t *asn1, size_t len, const struct atype_info *a, void *val); /* Returns a completed encoding, with tag and in the correct byte order, in an * allocated krb5_data. */ extern krb5_error_code k5_asn1_full_encode(const void *rep, const struct atype_info *a, krb5_data **code_out); krb5_error_code k5_asn1_full_decode(const krb5_data *code, const struct atype_info *a, void **rep_out); #define MAKE_ENCODER(FNAME, DESC) \ krb5_error_code \ FNAME(const aux_type_##DESC *rep, krb5_data **code_out) \ { \ return k5_asn1_full_encode(rep, &k5_atype_##DESC, code_out); \ } \ extern int dummy /* gobble semicolon */ #define MAKE_DECODER(FNAME, DESC) \ krb5_error_code \ FNAME(const krb5_data *code, aux_type_##DESC **rep_out) \ { \ krb5_error_code ret; \ void *rep; \ *rep_out = NULL; \ ret = k5_asn1_full_decode(code, &k5_atype_##DESC, &rep); \ if (ret) \ return ret; \ *rep_out = rep; \ return 0; \ } \ extern int dummy /* gobble semicolon */ #include /* * Ugly hack! * Like "offsetof", but with type checking. */ #define WARN_IF_TYPE_MISMATCH(LVALUE, TYPE) \ (sizeof(0 ? (TYPE *) 0 : &(LVALUE))) #define OFFOF(TYPE,FIELD,FTYPE) \ (offsetof(TYPE, FIELD) \ + 0 * WARN_IF_TYPE_MISMATCH(((TYPE*)0)->FIELD, FTYPE)) #endif krb5-1.22.1/src/lib/krb5/asn.1/ldap_key_seq.c0000664000175000017500000000737715051422640020303 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* ... copyright ... */ /* * Novell key-format scheme: * * KrbKeySet ::= SEQUENCE { * attribute-major-vno [0] UInt16, * attribute-minor-vno [1] UInt16, * kvno [2] UInt32, * mkvno [3] UInt32 OPTIONAL, * keys [4] SEQUENCE OF KrbKey, * ... * } * * KrbKey ::= SEQUENCE { * salt [0] KrbSalt OPTIONAL, * key [1] EncryptionKey, * s2kparams [2] OCTET STRING OPTIONAL, * ... * } * * KrbSalt ::= SEQUENCE { * type [0] Int32, * salt [1] OCTET STRING OPTIONAL * } * * EncryptionKey ::= SEQUENCE { * keytype [0] Int32, * keyvalue [1] OCTET STRING * } * */ #include #include #include "krbasn1.h" #include "asn1_encode.h" #ifdef ENABLE_LDAP /************************************************************************/ /* Encode the Principal's keys */ /************************************************************************/ /* * Imports from asn1_k_encode.c. * XXX Must be manually synchronized for now. */ IMPORT_TYPE(int32, int32_t); DEFINTTYPE(int16, int16_t); DEFINTTYPE(uint16, uint16_t); DEFCOUNTEDSTRINGTYPE(ui2_octetstring, uint8_t *, uint16_t, k5_asn1_encode_bytestring, k5_asn1_decode_bytestring, ASN1_OCTETSTRING); static int is_value_present(const void *p) { const krb5_key_data *val = p; return (val->key_data_length[1] != 0); } DEFCOUNTEDTYPE(krbsalt_salt, krb5_key_data, key_data_contents[1], key_data_length[1], ui2_octetstring); DEFOPTIONALTYPE(krbsalt_salt_if_present, is_value_present, NULL, krbsalt_salt); DEFFIELD(krbsalt_0, krb5_key_data, key_data_type[1], 0, int16); DEFCTAGGEDTYPE(krbsalt_1, 1, krbsalt_salt_if_present); static const struct atype_info *krbsalt_fields[] = { &k5_atype_krbsalt_0, &k5_atype_krbsalt_1 }; DEFSEQTYPE(krbsalt, krb5_key_data, krbsalt_fields); DEFFIELD(encryptionkey_0, krb5_key_data, key_data_type[0], 0, int16); DEFCNFIELD(encryptionkey_1, krb5_key_data, key_data_contents[0], key_data_length[0], 1, ui2_octetstring); static const struct atype_info *encryptionkey_fields[] = { &k5_atype_encryptionkey_0, &k5_atype_encryptionkey_1 }; DEFSEQTYPE(encryptionkey, krb5_key_data, encryptionkey_fields); static int is_salt_present(const void *p) { const krb5_key_data *val = p; return val->key_data_ver > 1; } static void no_salt(void *p) { krb5_key_data *val = p; val->key_data_ver = 1; } DEFOPTIONALTYPE(key_data_salt_if_present, is_salt_present, no_salt, krbsalt); DEFCTAGGEDTYPE(key_data_0, 0, key_data_salt_if_present); DEFCTAGGEDTYPE(key_data_1, 1, encryptionkey); static const struct atype_info *key_data_fields[] = { &k5_atype_key_data_0, &k5_atype_key_data_1 }; DEFSEQTYPE(key_data, krb5_key_data, key_data_fields); DEFPTRTYPE(ptr_key_data, key_data); DEFCOUNTEDSEQOFTYPE(cseqof_key_data, int16_t, ptr_key_data); DEFINT_IMMEDIATE(one, 1, ASN1_BAD_FORMAT); DEFCTAGGEDTYPE(ldap_key_seq_0, 0, one); DEFCTAGGEDTYPE(ldap_key_seq_1, 1, one); DEFFIELD(ldap_key_seq_2, ldap_seqof_key_data, kvno, 2, uint16); DEFFIELD(ldap_key_seq_3, ldap_seqof_key_data, mkvno, 3, int32); DEFCNFIELD(ldap_key_seq_4, ldap_seqof_key_data, key_data, n_key_data, 4, cseqof_key_data); static const struct atype_info *ldap_key_seq_fields[] = { &k5_atype_ldap_key_seq_0, &k5_atype_ldap_key_seq_1, &k5_atype_ldap_key_seq_2, &k5_atype_ldap_key_seq_3, &k5_atype_ldap_key_seq_4 }; DEFSEQTYPE(ldap_key_seq, ldap_seqof_key_data, ldap_key_seq_fields); /* Export a function to do the whole encoding. */ MAKE_ENCODER(krb5int_ldap_encode_sequence_of_keys, ldap_key_seq); MAKE_DECODER(krb5int_ldap_decode_sequence_of_keys, ldap_key_seq); #endif krb5-1.22.1/src/lib/krb5/asn.1/krbasn1.h0000664000175000017500000000307715051422640017202 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #ifndef __KRBASN1_H__ #define __KRBASN1_H__ #include "k5-int.h" #include #include #include /* For INT_MAX */ #ifdef HAVE_STDLIB_H #include #endif typedef krb5_error_code asn1_error_code; typedef enum { PRIMITIVE = 0x00, CONSTRUCTED = 0x20 } asn1_construction; typedef enum { UNIVERSAL = 0x00, APPLICATION = 0x40, CONTEXT_SPECIFIC = 0x80, PRIVATE = 0xC0 } asn1_class; typedef int asn1_tagnum; #define ASN1_TAGNUM_CEILING INT_MAX #define ASN1_TAGNUM_MAX (ASN1_TAGNUM_CEILING-1) /* This is Kerberos Version 5 */ #define KVNO 5 /* Universal Tag Numbers */ #define ASN1_BOOLEAN 1 #define ASN1_INTEGER 2 #define ASN1_BITSTRING 3 #define ASN1_OCTETSTRING 4 #define ASN1_NULL 5 #define ASN1_OBJECTIDENTIFIER 6 #define ASN1_ENUMERATED 10 #define ASN1_UTF8STRING 12 #define ASN1_SEQUENCE 16 #define ASN1_SET 17 #define ASN1_PRINTABLESTRING 19 #define ASN1_IA5STRING 22 #define ASN1_UTCTIME 23 #define ASN1_GENERALTIME 24 #define ASN1_GENERALSTRING 27 /* Kerberos Message Types */ #define ASN1_KRB_AS_REQ 10 #define ASN1_KRB_AS_REP 11 #define ASN1_KRB_TGS_REQ 12 #define ASN1_KRB_TGS_REP 13 #define ASN1_KRB_AP_REQ 14 #define ASN1_KRB_AP_REP 15 #define ASN1_KRB_SAFE 20 #define ASN1_KRB_PRIV 21 #define ASN1_KRB_CRED 22 #define ASN1_KRB_ERROR 30 #endif krb5-1.22.1/src/lib/krb5/asn.1/deps0000664000175000017500000000457715051422640016354 0ustar ghudsonghudson# # Generated makefile dependencies follow. # asn1_encode.so asn1_encode.po $(OUTPRE)asn1_encode.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ asn1_encode.c asn1_encode.h krbasn1.h asn1_k_encode.so asn1_k_encode.po $(OUTPRE)asn1_k_encode.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-spake.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h asn1_encode.h \ asn1_k_encode.c krbasn1.h ldap_key_seq.so ldap_key_seq.po $(OUTPRE)ldap_key_seq.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/kdb.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h asn1_encode.h \ krbasn1.h ldap_key_seq.c krb5-1.22.1/src/lib/krb5/asn.1/TODO.asn10000664000175000017500000000663115051422640017020 0ustar ghudsonghudson-*- text -*- Stuff that should still be done on the ASN.1 encoder conversion: * Make offsetof uses conforming. Currently we may use foo.bar or foo[0] as fields. * Script to generate the tables. Then each type or field entry can generate multiple bits of code, instead of forcing us to bury the type consistency checking into the structure initializer expression. For example, we might generate these bits of code from one field descriptor: * Field table entry. * Type-checking code: Create a pointer of the expected type and a pointer of the actual type (address of field of automatic struct), and verify consistency with comparison, assignment, or conditional expr. Plenty of comments to indicate what's being compared and what a compiler complain means. * Range-checking code for bitfields: Create an automatic field info struct, fill in the computed offset or whatever, read it back, make sure it matches. Also with comments. * Possibly header declarations describing the types that could be imported, with correct handles *and* C types. * Static declarations for non-exported types to keep symbol table sizes down. Then similar bits of code (e.g., all the field table entries) can be pulled together into the appropriate places. * Some kind of "module" system for exporting and importing encoders, better than relying on the "type_*" variable names. Probably use meaningful strings that indicate both the ASN.1 type and the associated C type. Find a way to fit "imported type" into this scheme so that we can cleanly move the PKINIT types into the PKINIT plugin, the LDAP types into the LDAP plugin, etc., and still let them use the encoders in the code. Only a subset of types would be exported probably. * More compact encoding: For struct atype and struct cntype, we could use structures with a common base type (similar to Xlib events) instead of a base structure with a void pointer, to save the cost of a pointer for each type. Doing this might not be strictly correct C. * Pie in the sky: A verbose mode that can tell you "missing field KDC-REP.cname.name-string[1].data" or some such. This would require tracking the stack of pending encodes and adding strings with type and field names. * For ALL_POINTERS_ARE_THE_SAME mode (which is not strictly conforming with the C standard, and thus not default currently, but makes things a little smaller and faster), eliminate the loadptr structure entry. (Note that if this infrastructure becomes exposed to plugins, ALL_POINTERS_ARE_THE_SAME changes the ABI.) * Maybe: Reorganize the data of a "module" so everything needing relocation is put in some tables, referenced by index from other structures without relocations. E.g., for krb5_data, here's the offset for the data pointer, here's the offset for the length value, here's the index into the pointer reader function table, here's the index into the length reader function table, here's an index into the string-type encoder table. Using an index into a set of pointer types, with a single function taking an integer parameter used to switch between various ptr-to-ptr-to-type code paths, will be a lot smaller -- with a good compiler the function will probably collapse to a simple fetch-a-pointer function ignoring the integer argument, while at the C level it's strictly conforming by using the correct types for access. krb5-1.22.1/src/lib/krb5/asn.1/asn1_encode.c0000664000175000017500000013400515051422640020007 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/asn.1/asn1_encode.c */ /* * Copyright 1994, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "asn1_encode.h" struct asn1buf_st { uint8_t *ptr; /* Position, moving backwards; may be NULL */ size_t count; /* Count of bytes written so far */ }; /**** Functions for encoding primitive types ****/ /* Insert one byte into buf going backwards. */ static inline void insert_byte(asn1buf *buf, uint8_t o) { if (buf->ptr != NULL) { buf->ptr--; *buf->ptr = o; } buf->count++; } /* Insert a block of bytes into buf going backwards (but without reversing * bytes). */ static inline void insert_bytes(asn1buf *buf, const void *bytes, size_t len) { if (buf->ptr != NULL) { memcpy(buf->ptr - len, bytes, len); buf->ptr -= len; } buf->count += len; } void k5_asn1_encode_bool(asn1buf *buf, intmax_t val) { insert_byte(buf, val ? 0xFF : 0x00); } void k5_asn1_encode_int(asn1buf *buf, intmax_t val) { long valcopy; int digit; valcopy = val; do { digit = valcopy & 0xFF; insert_byte(buf, digit); valcopy = valcopy >> 8; } while (valcopy != 0 && valcopy != ~0); /* Make sure the high bit is of the proper signed-ness. */ if (val > 0 && (digit & 0x80) == 0x80) insert_byte(buf, 0); else if (val < 0 && (digit & 0x80) != 0x80) insert_byte(buf, 0xFF); } void k5_asn1_encode_uint(asn1buf *buf, uintmax_t val) { uintmax_t valcopy; int digit; valcopy = val; do { digit = valcopy & 0xFF; insert_byte(buf, digit); valcopy = valcopy >> 8; } while (valcopy != 0); /* Make sure the high bit is of the proper signed-ness. */ if (digit & 0x80) insert_byte(buf, 0); } krb5_error_code k5_asn1_encode_bytestring(asn1buf *buf, uint8_t *const *val, size_t len) { if (len > 0 && val == NULL) return ASN1_MISSING_FIELD; insert_bytes(buf, *val, len); return 0; } krb5_error_code k5_asn1_encode_generaltime(asn1buf *buf, time_t val) { struct tm *gtime, gtimebuf; char s[16], *sp; time_t gmt_time = val; int len; /* * Time encoding: YYYYMMDDhhmmssZ */ if (gmt_time == 0) { sp = "19700101000000Z"; } else { /* * Sanity check this just to be paranoid, as gmtime can return NULL, * and some bogus implementations might overrun on the sprintf. */ #ifdef HAVE_GMTIME_R #ifdef GMTIME_R_RETURNS_INT if (gmtime_r(&gmt_time, >imebuf) != 0) return ASN1_BAD_GMTIME; #else if (gmtime_r(&gmt_time, >imebuf) == NULL) return ASN1_BAD_GMTIME; #endif #else /* HAVE_GMTIME_R */ gtime = gmtime(&gmt_time); if (gtime == NULL) return ASN1_BAD_GMTIME; memcpy(>imebuf, gtime, sizeof(gtimebuf)); #endif /* HAVE_GMTIME_R */ gtime = >imebuf; if (gtime->tm_year > 8099 || gtime->tm_mon > 11 || gtime->tm_mday > 31 || gtime->tm_hour > 23 || gtime->tm_min > 59 || gtime->tm_sec > 59) return ASN1_BAD_GMTIME; len = snprintf(s, sizeof(s), "%04d%02d%02d%02d%02d%02dZ", 1900 + gtime->tm_year, gtime->tm_mon + 1, gtime->tm_mday, gtime->tm_hour, gtime->tm_min, gtime->tm_sec); if (SNPRINTF_OVERFLOW(len, sizeof(s))) /* Shouldn't be possible given above tests. */ return ASN1_BAD_GMTIME; sp = s; } insert_bytes(buf, sp, 15); return 0; } krb5_error_code k5_asn1_encode_bitstring(asn1buf *buf, uint8_t *const *val, size_t len) { insert_bytes(buf, *val, len); insert_byte(buf, 0); return 0; } /**** Functions for decoding primitive types ****/ krb5_error_code k5_asn1_decode_bool(const uint8_t *asn1, size_t len, intmax_t *val) { if (len != 1) return ASN1_BAD_LENGTH; *val = (*asn1 != 0); return 0; } /* Decode asn1/len as the contents of a DER integer, placing the signed result * in val. */ krb5_error_code k5_asn1_decode_int(const uint8_t *asn1, size_t len, intmax_t *val) { intmax_t n; size_t i; if (len == 0) return ASN1_BAD_LENGTH; n = (asn1[0] & 0x80) ? -1 : 0; /* Check length. */ if (len > sizeof(intmax_t)) return ASN1_OVERFLOW; for (i = 0; i < len; i++) n = n * 256 + asn1[i]; *val = n; return 0; } /* Decode asn1/len as the contents of a DER integer, placing the unsigned * result in val. */ krb5_error_code k5_asn1_decode_uint(const uint8_t *asn1, size_t len, uintmax_t *val) { uintmax_t n; size_t i; if (len == 0) return ASN1_BAD_LENGTH; /* Check for negative values and check length. */ if ((asn1[0] & 0x80) || len > sizeof(uintmax_t) + (asn1[0] == 0)) return ASN1_OVERFLOW; for (i = 0, n = 0; i < len; i++) n = (n << 8) | asn1[i]; *val = n; return 0; } krb5_error_code k5_asn1_decode_bytestring(const uint8_t *asn1, size_t len, uint8_t **str_out, size_t *len_out) { uint8_t *str; *str_out = NULL; *len_out = 0; if (len == 0) return 0; str = malloc(len); if (str == NULL) return ENOMEM; memcpy(str, asn1, len); *str_out = str; *len_out = len; return 0; } krb5_error_code k5_asn1_decode_generaltime(const uint8_t *asn1, size_t len, time_t *time_out) { const char *s = (char *)asn1; struct tm ts; time_t t; size_t i; *time_out = 0; if (len != 15) return ASN1_BAD_LENGTH; /* Time encoding: YYYYMMDDhhmmssZ */ if (s[14] != 'Z') return ASN1_BAD_FORMAT; if (memcmp(s, "19700101000000Z", 15) == 0) { *time_out = 0; return 0; } #define c2i(c) ((c) - '0') for (i = 0; i < 14; ++i) { if ((uint8_t)c2i(s[i]) > 9) return ASN1_BAD_TIMEFORMAT; } ts.tm_year = 1000 * c2i(s[0]) + 100 * c2i(s[1]) + 10 * c2i(s[2]) + c2i(s[3]) - 1900; ts.tm_mon = 10 * c2i(s[4]) + c2i(s[5]) - 1; ts.tm_mday = 10 * c2i(s[6]) + c2i(s[7]); ts.tm_hour = 10 * c2i(s[8]) + c2i(s[9]); ts.tm_min = 10 * c2i(s[10]) + c2i(s[11]); ts.tm_sec = 10 * c2i(s[12]) + c2i(s[13]); ts.tm_isdst = -1; t = krb5int_gmt_mktime(&ts); if (t == -1) return ASN1_BAD_TIMEFORMAT; *time_out = t; return 0; } /* * Note: we return the number of bytes, not bits, in the bit string. If the * number of bits is not a multiple of 8 we effectively round up to the next * multiple of 8. */ krb5_error_code k5_asn1_decode_bitstring(const uint8_t *asn1, size_t len, uint8_t **bits_out, size_t *len_out) { uint8_t unused, *bits; *bits_out = NULL; *len_out = 0; if (len == 0) return ASN1_BAD_LENGTH; unused = *asn1++; len--; if (unused > 7) return ASN1_BAD_FORMAT; bits = malloc(len); if (bits == NULL) return ENOMEM; memcpy(bits, asn1, len); if (len > 1) bits[len - 1] &= (0xff << unused); *bits_out = bits; *len_out = len; return 0; } /**** Functions for encoding and decoding tags ****/ /* Encode a DER tag into buf with the tag parameters in t and the content * length len. Place the length of the encoded tag in *retlen. */ static krb5_error_code make_tag(asn1buf *buf, const taginfo *t, size_t len) { asn1_tagnum tag_copy; size_t len_copy, oldcount; if (t->tagnum > ASN1_TAGNUM_MAX) return ASN1_OVERFLOW; /* Encode the length of the content within the tag. */ if (len < 128) { insert_byte(buf, len & 0x7F); } else { oldcount = buf->count; for (len_copy = len; len_copy != 0; len_copy >>= 8) insert_byte(buf, len_copy & 0xFF); insert_byte(buf, 0x80 | ((buf->count - oldcount) & 0x7F)); } /* Encode the tag and construction bit. */ if (t->tagnum < 31) { insert_byte(buf, t->asn1class | t->construction | t->tagnum); } else { tag_copy = t->tagnum; insert_byte(buf, tag_copy & 0x7F); tag_copy >>= 7; for (; tag_copy != 0; tag_copy >>= 7) insert_byte(buf, 0x80 | (tag_copy & 0x7F)); insert_byte(buf, t->asn1class | t->construction | 0x1F); } return 0; } /* * Read a DER tag and length from asn1/len. Place the tag parameters in * tag_out. Set contents_out/clen_out to the octet range of the tag's * contents, and remainder_out/rlen_out to the octet range after the end of the * DER encoding. */ static krb5_error_code get_tag(const uint8_t *asn1, size_t len, taginfo *tag_out, const uint8_t **contents_out, size_t *clen_out, const uint8_t **remainder_out, size_t *rlen_out) { uint8_t o; const uint8_t *tag_start = asn1; size_t clen, llen, i; *contents_out = *remainder_out = NULL; *clen_out = *rlen_out = 0; if (len == 0) return ASN1_OVERRUN; o = *asn1++; len--; tag_out->asn1class = o & 0xC0; tag_out->construction = o & 0x20; if ((o & 0x1F) != 0x1F) { tag_out->tagnum = o & 0x1F; } else { tag_out->tagnum = 0; do { if (len == 0) return ASN1_OVERRUN; if (tag_out->tagnum > (ASN1_TAGNUM_MAX >> 7)) return ASN1_OVERFLOW; o = *asn1++; len--; tag_out->tagnum = (tag_out->tagnum << 7) | (o & 0x7F); } while (o & 0x80); /* Check for overly large tag values */ if (tag_out->tagnum > ASN1_TAGNUM_MAX) return ASN1_OVERFLOW; } if (len == 0) return ASN1_OVERRUN; o = *asn1++; len--; if ((o & 0x80) == 0) { /* Short form (first octet gives content length). */ if (o > len) return ASN1_OVERRUN; *contents_out = asn1; *clen_out = o; *remainder_out = asn1 + *clen_out; *rlen_out = len - (*remainder_out - asn1); } else { /* Long form (first octet gives number of base-256 length octets). */ llen = o & 0x7F; if (llen > len) return ASN1_OVERRUN; if (llen > sizeof(*clen_out)) return ASN1_OVERFLOW; if (llen == 0) return ASN1_INDEF; for (i = 0, clen = 0; i < llen; i++) clen = (clen << 8) | asn1[i]; if (clen > len - llen) return ASN1_OVERRUN; *contents_out = asn1 + llen; *clen_out = clen; *remainder_out = *contents_out + clen; *rlen_out = len - (*remainder_out - asn1); } tag_out->tag_len = *contents_out - tag_start; return 0; } #ifdef POINTERS_ARE_ALL_THE_SAME #define LOADPTR(PTR, TYPE) (*(const void *const *)(PTR)) #define STOREPTR(PTR, TYPE, VAL) (*(void **)(VAL) = (PTR)) #else #define LOADPTR(PTR, PTRINFO) \ (assert((PTRINFO)->loadptr != NULL), (PTRINFO)->loadptr(PTR)) #define STOREPTR(PTR, PTRINFO, VAL) \ (assert((PTRINFO)->storeptr != NULL), (PTRINFO)->storeptr(PTR, VAL)) #endif static size_t get_nullterm_sequence_len(const void *valp, const struct atype_info *seq) { size_t i; const struct atype_info *a; const struct ptr_info *ptr; const void *elt, *eltptr; a = seq; i = 0; assert(a->type == atype_ptr); assert(seq->size != 0); ptr = a->tinfo; while (1) { eltptr = (const char *)valp + i * seq->size; elt = LOADPTR(eltptr, ptr); if (elt == NULL) break; i++; } return i; } static krb5_error_code encode_sequence_of(asn1buf *buf, size_t seqlen, const void *val, const struct atype_info *eltinfo); static krb5_error_code encode_nullterm_sequence_of(asn1buf *buf, const void *val, const struct atype_info *type, int can_be_empty) { size_t len = get_nullterm_sequence_len(val, type); if (!can_be_empty && len == 0) return ASN1_MISSING_FIELD; return encode_sequence_of(buf, len, val, type); } static intmax_t load_int(const void *val, size_t size) { switch (size) { case 1: return *(int8_t *)val; case 2: return *(int16_t *)val; case 4: return *(int32_t *)val; case 8: return *(int64_t *)val; default: abort(); } } static uintmax_t load_uint(const void *val, size_t size) { switch (size) { case 1: return *(uint8_t *)val; case 2: return *(uint16_t *)val; case 4: return *(uint32_t *)val; case 8: return *(uint64_t *)val; default: abort(); } } static krb5_error_code load_count(const void *val, const struct counted_info *counted, size_t *count_out) { const void *countptr = (const char *)val + counted->lenoff; assert(sizeof(size_t) <= sizeof(uintmax_t)); if (counted->lensigned) { intmax_t xlen = load_int(countptr, counted->lensize); if (xlen < 0 || (uintmax_t)xlen > SIZE_MAX) return EINVAL; *count_out = xlen; } else { uintmax_t xlen = load_uint(countptr, counted->lensize); if ((size_t)xlen != xlen || xlen > SIZE_MAX) return EINVAL; *count_out = xlen; } return 0; } static krb5_error_code store_int(intmax_t intval, size_t size, void *val) { switch (size) { case 1: if ((int8_t)intval != intval) return ASN1_OVERFLOW; *(int8_t *)val = intval; return 0; case 2: if ((int16_t)intval != intval) return ASN1_OVERFLOW; *(int16_t *)val = intval; return 0; case 4: if ((int32_t)intval != intval) return ASN1_OVERFLOW; *(int32_t *)val = intval; return 0; case 8: if ((int64_t)intval != intval) return ASN1_OVERFLOW; *(int64_t *)val = intval; return 0; default: abort(); } } static krb5_error_code store_uint(uintmax_t intval, size_t size, void *val) { switch (size) { case 1: if ((uint8_t)intval != intval) return ASN1_OVERFLOW; *(uint8_t *)val = intval; return 0; case 2: if ((uint16_t)intval != intval) return ASN1_OVERFLOW; *(uint16_t *)val = intval; return 0; case 4: if ((uint32_t)intval != intval) return ASN1_OVERFLOW; *(uint32_t *)val = intval; return 0; case 8: if ((uint64_t)intval != intval) return ASN1_OVERFLOW; *(uint64_t *)val = intval; return 0; default: abort(); } } /* Store a count value in an integer field of a structure. If count is * SIZE_MAX and the target is a signed field, store -1. */ static krb5_error_code store_count(size_t count, const struct counted_info *counted, void *val) { void *countptr = (char *)val + counted->lenoff; if (counted->lensigned) { if (count == SIZE_MAX) return store_int(-1, counted->lensize, countptr); else if ((intmax_t)count < 0) return ASN1_OVERFLOW; else return store_int(count, counted->lensize, countptr); } else return store_uint(count, counted->lensize, countptr); } /* Split a DER encoding into tag and contents. Insert the contents into buf, * then return the length of the contents and the tag. */ static krb5_error_code split_der(asn1buf *buf, uint8_t *const *der, size_t len, taginfo *tag_out) { krb5_error_code ret; const uint8_t *contents, *remainder; size_t clen, rlen; ret = get_tag(*der, len, tag_out, &contents, &clen, &remainder, &rlen); if (ret) return ret; if (rlen != 0) return ASN1_BAD_LENGTH; insert_bytes(buf, contents, clen); return 0; } /* * Store the DER encoding given by t and asn1/len into the char * or * uint8_t * pointed to by val. Set *count_out to the length of the * DER encoding. */ static krb5_error_code store_der(const taginfo *t, const uint8_t *asn1, size_t len, void *val, size_t *count_out) { uint8_t *der; size_t der_len; *count_out = 0; der_len = t->tag_len + len; der = malloc(der_len); if (der == NULL) return ENOMEM; memcpy(der, asn1 - t->tag_len, der_len); *(uint8_t **)val = der; *count_out = der_len; return 0; } static krb5_error_code encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq); static krb5_error_code encode_cntype(asn1buf *buf, const void *val, size_t len, const struct cntype_info *c, taginfo *tag_out); /* Encode a value (contents only, no outer tag) according to a type, and return * its encoded tag information. */ static krb5_error_code encode_atype(asn1buf *buf, const void *val, const struct atype_info *a, taginfo *tag_out) { krb5_error_code ret; if (val == NULL) return ASN1_MISSING_FIELD; switch (a->type) { case atype_fn: { const struct fn_info *fn = a->tinfo; assert(fn->enc != NULL); return fn->enc(buf, val, tag_out); } case atype_sequence: assert(a->tinfo != NULL); ret = encode_sequence(buf, val, a->tinfo); if (ret) return ret; tag_out->asn1class = UNIVERSAL; tag_out->construction = CONSTRUCTED; tag_out->tagnum = ASN1_SEQUENCE; break; case atype_ptr: { const struct ptr_info *ptr = a->tinfo; assert(ptr->basetype != NULL); return encode_atype(buf, LOADPTR(val, ptr), ptr->basetype, tag_out); } case atype_offset: { const struct offset_info *off = a->tinfo; assert(off->basetype != NULL); return encode_atype(buf, (const char *)val + off->dataoff, off->basetype, tag_out); } case atype_optional: { const struct optional_info *opt = a->tinfo; assert(opt->is_present != NULL); if (opt->is_present(val)) return encode_atype(buf, val, opt->basetype, tag_out); else return ASN1_OMITTED; } case atype_counted: { const struct counted_info *counted = a->tinfo; const void *dataptr = (const char *)val + counted->dataoff; size_t count; assert(counted->basetype != NULL); ret = load_count(val, counted, &count); if (ret) return ret; return encode_cntype(buf, dataptr, count, counted->basetype, tag_out); } case atype_nullterm_sequence_of: case atype_nonempty_nullterm_sequence_of: assert(a->tinfo != NULL); ret = encode_nullterm_sequence_of(buf, val, a->tinfo, a->type == atype_nullterm_sequence_of); if (ret) return ret; tag_out->asn1class = UNIVERSAL; tag_out->construction = CONSTRUCTED; tag_out->tagnum = ASN1_SEQUENCE; break; case atype_tagged_thing: { const struct tagged_info *tag = a->tinfo; size_t oldcount = buf->count; ret = encode_atype(buf, val, tag->basetype, tag_out); if (ret) return ret; if (!tag->implicit) { ret = make_tag(buf, tag_out, buf->count - oldcount); if (ret) return ret; tag_out->construction = tag->construction; } tag_out->asn1class = tag->tagtype; tag_out->tagnum = tag->tagval; break; } case atype_bool: k5_asn1_encode_bool(buf, load_int(val, a->size)); tag_out->asn1class = UNIVERSAL; tag_out->construction = PRIMITIVE; tag_out->tagnum = ASN1_BOOLEAN; break; case atype_int: k5_asn1_encode_int(buf, load_int(val, a->size)); tag_out->asn1class = UNIVERSAL; tag_out->construction = PRIMITIVE; tag_out->tagnum = ASN1_INTEGER; break; case atype_uint: k5_asn1_encode_uint(buf, load_uint(val, a->size)); tag_out->asn1class = UNIVERSAL; tag_out->construction = PRIMITIVE; tag_out->tagnum = ASN1_INTEGER; break; case atype_int_immediate: { const struct immediate_info *imm = a->tinfo; k5_asn1_encode_int(buf, imm->val); tag_out->asn1class = UNIVERSAL; tag_out->construction = PRIMITIVE; tag_out->tagnum = ASN1_INTEGER; break; } default: assert(a->type > atype_min); assert(a->type < atype_max); abort(); } return 0; } static krb5_error_code encode_atype_and_tag(asn1buf *buf, const void *val, const struct atype_info *a) { taginfo t; krb5_error_code ret; size_t oldcount = buf->count; ret = encode_atype(buf, val, a, &t); if (ret) return ret; ret = make_tag(buf, &t, buf->count - oldcount); if (ret) return ret; return 0; } /* * Encode an object and count according to a cntype_info structure. val is a * pointer to the object being encoded, which in most cases is itself a * pointer (but is a union in the cntype_choice case). */ static krb5_error_code encode_cntype(asn1buf *buf, const void *val, size_t count, const struct cntype_info *c, taginfo *tag_out) { krb5_error_code ret; switch (c->type) { case cntype_string: { const struct string_info *string = c->tinfo; assert(string->enc != NULL); ret = string->enc(buf, val, count); if (ret) return ret; tag_out->asn1class = UNIVERSAL; tag_out->construction = PRIMITIVE; tag_out->tagnum = string->tagval; break; } case cntype_der: return split_der(buf, val, count, tag_out); case cntype_seqof: { const struct atype_info *a = c->tinfo; const struct ptr_info *ptr = a->tinfo; assert(a->type == atype_ptr); val = LOADPTR(val, ptr); ret = encode_sequence_of(buf, count, val, ptr->basetype); if (ret) return ret; tag_out->asn1class = UNIVERSAL; tag_out->construction = CONSTRUCTED; tag_out->tagnum = ASN1_SEQUENCE; break; } case cntype_choice: { const struct choice_info *choice = c->tinfo; if (count >= choice->n_options) return ASN1_MISSING_FIELD; return encode_atype(buf, val, choice->options[count], tag_out); } default: assert(c->type > cntype_min); assert(c->type < cntype_max); abort(); } return 0; } static krb5_error_code encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq) { krb5_error_code ret; size_t i; for (i = seq->n_fields; i > 0; i--) { ret = encode_atype_and_tag(buf, val, seq->fields[i - 1]); if (ret == ASN1_OMITTED) continue; else if (ret != 0) return ret; } return 0; } static krb5_error_code encode_sequence_of(asn1buf *buf, size_t seqlen, const void *val, const struct atype_info *eltinfo) { krb5_error_code ret; size_t i; const void *eltptr; assert(eltinfo->size != 0); for (i = seqlen; i > 0; i--) { eltptr = (const char *)val + (i - 1) * eltinfo->size; ret = encode_atype_and_tag(buf, eltptr, eltinfo); if (ret) return ret; } return 0; } /**** Functions for freeing C objects based on type info ****/ static void free_atype_ptr(const struct atype_info *a, void *val); static void free_sequence(const struct seq_info *seq, void *val); static void free_sequence_of(const struct atype_info *eltinfo, void *val, size_t count); static void free_cntype(const struct cntype_info *a, void *val, size_t count); /* * Free a C object according to a type description. Do not free pointers at * the first level; they may be referenced by other fields of a sequence, and * will be freed by free_atype_ptr in a second pass. */ static void free_atype(const struct atype_info *a, void *val) { switch (a->type) { case atype_fn: { const struct fn_info *fn = a->tinfo; if (fn->free_func != NULL) fn->free_func(val); break; } case atype_sequence: free_sequence(a->tinfo, val); break; case atype_ptr: { const struct ptr_info *ptrinfo = a->tinfo; void *ptr = LOADPTR(val, ptrinfo); if (ptr != NULL) { free_atype(ptrinfo->basetype, ptr); free_atype_ptr(ptrinfo->basetype, ptr); } break; } case atype_offset: { const struct offset_info *off = a->tinfo; assert(off->basetype != NULL); free_atype(off->basetype, (char *)val + off->dataoff); break; } case atype_optional: { const struct optional_info *opt = a->tinfo; free_atype(opt->basetype, val); break; } case atype_counted: { const struct counted_info *counted = a->tinfo; void *dataptr = (char *)val + counted->dataoff; size_t count; if (load_count(val, counted, &count) == 0) free_cntype(counted->basetype, dataptr, count); break; } case atype_nullterm_sequence_of: case atype_nonempty_nullterm_sequence_of: { size_t count = get_nullterm_sequence_len(val, a->tinfo); free_sequence_of(a->tinfo, val, count); break; } case atype_tagged_thing: { const struct tagged_info *tag = a->tinfo; free_atype(tag->basetype, val); break; } case atype_bool: case atype_int: case atype_uint: case atype_int_immediate: break; default: abort(); } } static void free_atype_ptr(const struct atype_info *a, void *val) { switch (a->type) { case atype_fn: case atype_sequence: case atype_counted: case atype_nullterm_sequence_of: case atype_nonempty_nullterm_sequence_of: case atype_bool: case atype_int: case atype_uint: case atype_int_immediate: break; case atype_ptr: { const struct ptr_info *ptrinfo = a->tinfo; void *ptr = LOADPTR(val, ptrinfo); free(ptr); STOREPTR(NULL, ptrinfo, val); break; } case atype_offset: { const struct offset_info *off = a->tinfo; assert(off->basetype != NULL); free_atype_ptr(off->basetype, (char *)val + off->dataoff); break; } case atype_optional: { const struct optional_info *opt = a->tinfo; free_atype_ptr(opt->basetype, val); break; } case atype_tagged_thing: { const struct tagged_info *tag = a->tinfo; free_atype_ptr(tag->basetype, val); break; } default: abort(); } } static void free_cntype(const struct cntype_info *c, void *val, size_t count) { switch (c->type) { case cntype_string: case cntype_der: free(*(char **)val); *(char **)val = NULL; break; case cntype_seqof: { const struct atype_info *a = c->tinfo; const struct ptr_info *ptrinfo = a->tinfo; void *seqptr = LOADPTR(val, ptrinfo); free_sequence_of(ptrinfo->basetype, seqptr, count); free(seqptr); STOREPTR(NULL, ptrinfo, val); break; } case cntype_choice: { const struct choice_info *choice = c->tinfo; if (count < choice->n_options) { free_atype(choice->options[count], val); free_atype_ptr(choice->options[count], val); } break; } default: abort(); } } static void free_sequence(const struct seq_info *seq, void *val) { size_t i; for (i = 0; i < seq->n_fields; i++) free_atype(seq->fields[i], val); for (i = 0; i < seq->n_fields; i++) free_atype_ptr(seq->fields[i], val); } static void free_sequence_of(const struct atype_info *eltinfo, void *val, size_t count) { void *eltptr; assert(eltinfo->size != 0); while (count-- > 0) { eltptr = (char *)val + count * eltinfo->size; free_atype(eltinfo, eltptr); free_atype_ptr(eltinfo, eltptr); } } /**** Functions for decoding objects based on type info ****/ /* Return nonzero if t is an expected tag for an ASN.1 object of type a. */ static int check_atype_tag(const struct atype_info *a, const taginfo *t) { switch (a->type) { case atype_fn: { const struct fn_info *fn = a->tinfo; assert(fn->check_tag != NULL); return fn->check_tag(t); } case atype_sequence: case atype_nullterm_sequence_of: case atype_nonempty_nullterm_sequence_of: return (t->asn1class == UNIVERSAL && t->construction == CONSTRUCTED && t->tagnum == ASN1_SEQUENCE); case atype_ptr: { const struct ptr_info *ptrinfo = a->tinfo; return check_atype_tag(ptrinfo->basetype, t); } case atype_offset: { const struct offset_info *off = a->tinfo; return check_atype_tag(off->basetype, t); } case atype_optional: { const struct optional_info *opt = a->tinfo; return check_atype_tag(opt->basetype, t); } case atype_counted: { const struct counted_info *counted = a->tinfo; switch (counted->basetype->type) { case cntype_string: { const struct string_info *string = counted->basetype->tinfo; return (t->asn1class == UNIVERSAL && t->construction == PRIMITIVE && t->tagnum == string->tagval); } case cntype_seqof: return (t->asn1class == UNIVERSAL && t->construction == CONSTRUCTED && t->tagnum == ASN1_SEQUENCE); case cntype_der: /* * We treat any tag as matching a stored DER encoding. In some * cases we know what the tag should be; in others, we truly want * to accept any tag. If it ever becomes an issue, we could add * optional tag info to the type and check it here. */ return 1; case cntype_choice: /* * ASN.1 choices may or may not be extensible. For now, we treat * all choices as extensible and match any tag. We should consider * modeling whether choices are extensible before making the * encoder visible to plugins. */ return 1; default: abort(); } } case atype_tagged_thing: { const struct tagged_info *tag = a->tinfo; /* NOTE: Doesn't check construction bit for implicit tags. */ if (!tag->implicit && t->construction != tag->construction) return 0; return (t->asn1class == tag->tagtype && t->tagnum == tag->tagval); } case atype_bool: return (t->asn1class == UNIVERSAL && t->construction == PRIMITIVE && t->tagnum == ASN1_BOOLEAN); case atype_int: case atype_uint: case atype_int_immediate: return (t->asn1class == UNIVERSAL && t->construction == PRIMITIVE && t->tagnum == ASN1_INTEGER); default: abort(); } } static krb5_error_code decode_cntype(const taginfo *t, const uint8_t *asn1, size_t len, const struct cntype_info *c, void *val, size_t *count_out); static krb5_error_code decode_atype_to_ptr(const taginfo *t, const uint8_t *asn1, size_t len, const struct atype_info *basetype, void **ptr_out); static krb5_error_code decode_sequence(const uint8_t *asn1, size_t len, const struct seq_info *seq, void *val); static krb5_error_code decode_sequence_of(const uint8_t *asn1, size_t len, const struct atype_info *elemtype, void **seq_out, size_t *count_out); /* Given the enclosing tag t, decode from asn1/len the contents of the ASN.1 * type specified by a, placing the result into val (caller-allocated). */ static krb5_error_code decode_atype(const taginfo *t, const uint8_t *asn1, size_t len, const struct atype_info *a, void *val) { krb5_error_code ret; switch (a->type) { case atype_fn: { const struct fn_info *fn = a->tinfo; assert(fn->dec != NULL); return fn->dec(t, asn1, len, val); } case atype_sequence: return decode_sequence(asn1, len, a->tinfo, val); case atype_ptr: { const struct ptr_info *ptrinfo = a->tinfo; void *ptr = LOADPTR(val, ptrinfo); assert(ptrinfo->basetype != NULL); if (ptr != NULL) { /* Container was already allocated by a previous sequence field. */ return decode_atype(t, asn1, len, ptrinfo->basetype, ptr); } else { ret = decode_atype_to_ptr(t, asn1, len, ptrinfo->basetype, &ptr); if (ret) return ret; STOREPTR(ptr, ptrinfo, val); break; } } case atype_offset: { const struct offset_info *off = a->tinfo; assert(off->basetype != NULL); return decode_atype(t, asn1, len, off->basetype, (char *)val + off->dataoff); } case atype_optional: { const struct optional_info *opt = a->tinfo; return decode_atype(t, asn1, len, opt->basetype, val); } case atype_counted: { const struct counted_info *counted = a->tinfo; void *dataptr = (char *)val + counted->dataoff; size_t count; assert(counted->basetype != NULL); ret = decode_cntype(t, asn1, len, counted->basetype, dataptr, &count); if (ret) return ret; return store_count(count, counted, val); } case atype_tagged_thing: { const struct tagged_info *tag = a->tinfo; taginfo inner_tag; const taginfo *tp = t; const uint8_t *rem; size_t rlen; if (!tag->implicit) { ret = get_tag(asn1, len, &inner_tag, &asn1, &len, &rem, &rlen); if (ret) return ret; if (rlen) return ASN1_BAD_LENGTH; tp = &inner_tag; if (!check_atype_tag(tag->basetype, tp)) return ASN1_BAD_ID; } return decode_atype(tp, asn1, len, tag->basetype, val); } case atype_bool: { intmax_t intval; ret = k5_asn1_decode_bool(asn1, len, &intval); if (ret) return ret; return store_int(intval, a->size, val); } case atype_int: { intmax_t intval; ret = k5_asn1_decode_int(asn1, len, &intval); if (ret) return ret; return store_int(intval, a->size, val); } case atype_uint: { uintmax_t intval; ret = k5_asn1_decode_uint(asn1, len, &intval); if (ret) return ret; return store_uint(intval, a->size, val); } case atype_int_immediate: { const struct immediate_info *imm = a->tinfo; intmax_t intval; ret = k5_asn1_decode_int(asn1, len, &intval); if (ret) return ret; if (intval != imm->val && imm->err != 0) return imm->err; break; } default: /* Null-terminated sequence types are handled in decode_atype_to_ptr, * since they create variable-sized objects. */ assert(a->type != atype_nullterm_sequence_of); assert(a->type != atype_nonempty_nullterm_sequence_of); assert(a->type > atype_min); assert(a->type < atype_max); abort(); } return 0; } /* * Given the enclosing tag t, decode from asn1/len the contents of the * ASN.1 type described by c, placing the counted result into val/count_out. * If the resulting count should be -1 (for an unknown union distinguisher), * set *count_out to SIZE_MAX. */ static krb5_error_code decode_cntype(const taginfo *t, const uint8_t *asn1, size_t len, const struct cntype_info *c, void *val, size_t *count_out) { krb5_error_code ret; switch (c->type) { case cntype_string: { const struct string_info *string = c->tinfo; assert(string->dec != NULL); return string->dec(asn1, len, val, count_out); } case cntype_der: return store_der(t, asn1, len, val, count_out); case cntype_seqof: { const struct atype_info *a = c->tinfo; const struct ptr_info *ptrinfo = a->tinfo; void *seq; assert(a->type == atype_ptr); ret = decode_sequence_of(asn1, len, ptrinfo->basetype, &seq, count_out); if (ret) return ret; STOREPTR(seq, ptrinfo, val); break; } case cntype_choice: { const struct choice_info *choice = c->tinfo; size_t i; for (i = 0; i < choice->n_options; i++) { if (check_atype_tag(choice->options[i], t)) { ret = decode_atype(t, asn1, len, choice->options[i], val); if (ret) return ret; *count_out = i; return 0; } } /* SIZE_MAX will be stored as -1 in the distinguisher. If we start * modeling non-extensible choices we should check that here. */ *count_out = SIZE_MAX; break; } default: assert(c->type > cntype_min); assert(c->type < cntype_max); abort(); } return 0; } /* Add a null pointer to the end of a sequence. ptr is consumed on success * (to be replaced by *ptr_out), left alone on failure. */ static krb5_error_code null_terminate(const struct atype_info *eltinfo, void *ptr, size_t count, void **ptr_out) { const struct ptr_info *ptrinfo = eltinfo->tinfo; void *endptr; assert(eltinfo->type == atype_ptr); ptr = realloc(ptr, (count + 1) * eltinfo->size); if (ptr == NULL) return ENOMEM; endptr = (char *)ptr + count * eltinfo->size; STOREPTR(NULL, ptrinfo, endptr); *ptr_out = ptr; return 0; } static krb5_error_code decode_atype_to_ptr(const taginfo *t, const uint8_t *asn1, size_t len, const struct atype_info *a, void **ptr_out) { krb5_error_code ret; void *ptr; size_t count; *ptr_out = NULL; switch (a->type) { case atype_nullterm_sequence_of: case atype_nonempty_nullterm_sequence_of: ret = decode_sequence_of(asn1, len, a->tinfo, &ptr, &count); if (ret) return ret; ret = null_terminate(a->tinfo, ptr, count, &ptr); if (ret) { free_sequence_of(a->tinfo, ptr, count); return ret; } /* Historically we do not enforce non-emptiness of sequences when * decoding, even when it is required by the ASN.1 type. */ break; default: ptr = calloc(a->size, 1); if (ptr == NULL) return ENOMEM; ret = decode_atype(t, asn1, len, a, ptr); if (ret) { free(ptr); return ret; } break; } *ptr_out = ptr; return 0; } /* Initialize a C object when the corresponding ASN.1 type was omitted within a * sequence. If the ASN.1 type is not optional, return ASN1_MISSING_FIELD. */ static krb5_error_code omit_atype(const struct atype_info *a, void *val) { switch (a->type) { case atype_fn: case atype_sequence: case atype_nullterm_sequence_of: case atype_nonempty_nullterm_sequence_of: case atype_counted: case atype_bool: case atype_int: case atype_uint: case atype_int_immediate: return ASN1_MISSING_FIELD; case atype_ptr: { const struct ptr_info *ptrinfo = a->tinfo; return omit_atype(ptrinfo->basetype, val); } case atype_offset: { const struct offset_info *off = a->tinfo; return omit_atype(off->basetype, (char *)val + off->dataoff); } case atype_tagged_thing: { const struct tagged_info *tag = a->tinfo; return omit_atype(tag->basetype, val); } case atype_optional: { const struct optional_info *opt = a->tinfo; if (opt->init != NULL) opt->init(val); return 0; } default: abort(); } } /* Decode an ASN.1 sequence into a C object. */ static krb5_error_code decode_sequence(const uint8_t *asn1, size_t len, const struct seq_info *seq, void *val) { krb5_error_code ret; const uint8_t *contents; size_t i, j, clen; taginfo t; assert(seq->n_fields > 0); for (i = 0; i < seq->n_fields; i++) { if (len == 0) break; ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len); if (ret) goto error; /* * Find the applicable sequence field. This logic is a little * oversimplified; we could match an element to an optional extensible * choice or optional stored-DER type when we ought to match a * subsequent non-optional field. But it's unwise and (hopefully) very * rare for ASN.1 modules to require such precision. */ for (; i < seq->n_fields; i++) { if (check_atype_tag(seq->fields[i], &t)) break; ret = omit_atype(seq->fields[i], val); if (ret) goto error; } /* We currently model all sequences as extensible. We should consider * changing this before making the encoder visible to plugins. */ if (i == seq->n_fields) break; ret = decode_atype(&t, contents, clen, seq->fields[i], val); if (ret) goto error; } /* Initialize any fields in the C object which were not accounted for in * the sequence. Error out if any of them aren't optional. */ for (; i < seq->n_fields; i++) { ret = omit_atype(seq->fields[i], val); if (ret) goto error; } return 0; error: /* Free what we've decoded so far. Free pointers in a second pass in * case multiple fields refer to the same pointer. */ for (j = 0; j < i; j++) free_atype(seq->fields[j], val); for (j = 0; j < i; j++) free_atype_ptr(seq->fields[j], val); return ret; } static krb5_error_code decode_sequence_of(const uint8_t *asn1, size_t len, const struct atype_info *elemtype, void **seq_out, size_t *count_out) { krb5_error_code ret; void *seq = NULL, *elem, *newseq; const uint8_t *contents; size_t clen, count = 0; taginfo t; *seq_out = NULL; *count_out = 0; while (len > 0) { ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len); if (ret) goto error; if (!check_atype_tag(elemtype, &t)) { ret = ASN1_BAD_ID; goto error; } newseq = realloc(seq, (count + 1) * elemtype->size); if (newseq == NULL) { ret = ENOMEM; goto error; } seq = newseq; elem = (char *)seq + count * elemtype->size; memset(elem, 0, elemtype->size); ret = decode_atype(&t, contents, clen, elemtype, elem); if (ret) goto error; count++; } *seq_out = seq; *count_out = count; return 0; error: free_sequence_of(elemtype, seq, count); free(seq); return ret; } /* These three entry points are only needed for the kdc_req_body hack and may * go away at some point. Define them here so we can use short names above. */ krb5_error_code k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a, taginfo *tag_out) { return encode_atype(buf, val, a, tag_out); } krb5_error_code k5_asn1_decode_atype(const taginfo *t, const uint8_t *asn1, size_t len, const struct atype_info *a, void *val) { return decode_atype(t, asn1, len, a, val); } krb5_error_code k5_asn1_full_encode(const void *rep, const struct atype_info *a, krb5_data **code_out) { krb5_error_code ret; asn1buf buf; krb5_data *d; uint8_t *bytes; *code_out = NULL; if (rep == NULL) return ASN1_MISSING_FIELD; /* Make a first pass over rep to count the encoding size. */ buf.ptr = NULL; buf.count = 0; ret = encode_atype_and_tag(&buf, rep, a); if (ret) return ret; /* Allocate space for the encoding. */ bytes = malloc(buf.count + 1); if (bytes == NULL) return ENOMEM; bytes[buf.count] = 0; /* Make a second pass over rep to encode it. buf.ptr moves backwards as we * encode, and will always exactly return to the base. */ buf.ptr = bytes + buf.count; buf.count = 0; ret = encode_atype_and_tag(&buf, rep, a); if (ret) { free(bytes); return ret; } assert(buf.ptr == bytes); /* Create the output data object. */ *code_out = malloc(sizeof(*d)); if (*code_out == NULL) { free(bytes); return ENOMEM; } **code_out = make_data(bytes, buf.count); return 0; } krb5_error_code k5_asn1_full_decode(const krb5_data *code, const struct atype_info *a, void **retrep) { krb5_error_code ret; const uint8_t *contents, *remainder; size_t clen, rlen; taginfo t; *retrep = NULL; ret = get_tag((uint8_t *)code->data, code->length, &t, &contents, &clen, &remainder, &rlen); if (ret) return ret; /* rlen should be 0, but we don't check it (and due to padding in * non-length-preserving enctypes, it will sometimes be nonzero). */ if (!check_atype_tag(a, &t)) return ASN1_BAD_ID; return decode_atype_to_ptr(&t, contents, clen, a, retrep); } krb5-1.22.1/src/lib/krb5/asn.1/asn1_k_encode.c0000664000175000017500000022411115051422640020317 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/asn.1/asn1_k_encode.c */ /* * Copyright 1994, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "asn1_encode.h" #include "k5-spake.h" DEFINT_IMMEDIATE(krb5_version, KVNO, KRB5KDC_ERR_BAD_PVNO); static int int32_not_minus1(const void *p) { return *(int32_t *)p != -1; } static void init_int32_minus1(void *p) { *(int32_t *)p = -1; } DEFBOOLTYPE(boolean, krb5_boolean); DEFINTTYPE(int32, int32_t); DEFPTRTYPE(int32_ptr, int32); DEFCOUNTEDSEQOFTYPE(cseqof_int32, int32_t, int32_ptr); DEFOPTIONALZEROTYPE(opt_int32, int32); DEFOPTIONALTYPE(opt_int32_minus1, int32_not_minus1, init_int32_minus1, int32); DEFUINTTYPE(uint, unsigned int); DEFUINTTYPE(octet, krb5_octet); DEFUINTTYPE(uint32, uint32_t); DEFOPTIONALZEROTYPE(opt_uint, uint); static int nonempty_data(const void *p) { const krb5_data *val = p; return (val->data != NULL && val->length != 0); } DEFCOUNTEDDERTYPE(der, char *, unsigned int); DEFCOUNTEDTYPE(der_data, krb5_data, data, length, der); DEFOPTIONALTYPE(opt_der_data, nonempty_data, NULL, der_data); DEFCOUNTEDSTRINGTYPE(octetstring, uint8_t *, unsigned int, k5_asn1_encode_bytestring, k5_asn1_decode_bytestring, ASN1_OCTETSTRING); DEFCOUNTEDSTRINGTYPE(s_octetstring, char *, unsigned int, k5_asn1_encode_bytestring, k5_asn1_decode_bytestring, ASN1_OCTETSTRING); DEFCOUNTEDTYPE(ostring_data, krb5_data, data, length, s_octetstring); DEFPTRTYPE(ostring_data_ptr, ostring_data); DEFOPTIONALTYPE(opt_ostring_data, nonempty_data, NULL, ostring_data); DEFOPTIONALZEROTYPE(opt_ostring_data_ptr, ostring_data_ptr); DEFCOUNTEDSTRINGTYPE(generalstring, char *, unsigned int, k5_asn1_encode_bytestring, k5_asn1_decode_bytestring, ASN1_GENERALSTRING); DEFCOUNTEDSTRINGTYPE(u_generalstring, uint8_t *, unsigned int, k5_asn1_encode_bytestring, k5_asn1_decode_bytestring, ASN1_GENERALSTRING); DEFCOUNTEDTYPE(gstring_data, krb5_data, data, length, generalstring); DEFOPTIONALTYPE(opt_gstring_data, nonempty_data, NULL, gstring_data); DEFPTRTYPE(gstring_data_ptr, gstring_data); DEFCOUNTEDSEQOFTYPE(cseqof_gstring_data, int32_t, gstring_data_ptr); DEFCOUNTEDSTRINGTYPE(utf8string, char *, unsigned int, k5_asn1_encode_bytestring, k5_asn1_decode_bytestring, ASN1_UTF8STRING); DEFCOUNTEDTYPE(utf8_data, krb5_data, data, length, utf8string); DEFOPTIONALTYPE(opt_utf8_data, nonempty_data, NULL, utf8_data); DEFPTRTYPE(utf8_data_ptr, utf8_data); DEFNULLTERMSEQOFTYPE(seqof_utf8_data, utf8_data_ptr); DEFCOUNTEDSTRINGTYPE(object_identifier, char *, unsigned int, k5_asn1_encode_bytestring, k5_asn1_decode_bytestring, ASN1_OBJECTIDENTIFIER); DEFCOUNTEDTYPE(oid_data, krb5_data, data, length, object_identifier); DEFPTRTYPE(oid_data_ptr, oid_data); DEFOFFSETTYPE(realm_of_principal_data, krb5_principal_data, realm, gstring_data); DEFPTRTYPE(realm_of_principal, realm_of_principal_data); DEFOPTIONALZEROTYPE(opt_realm_of_principal, realm_of_principal); DEFFIELD(princname_0, krb5_principal_data, type, 0, int32); DEFCNFIELD(princname_1, krb5_principal_data, data, length, 1, cseqof_gstring_data); static const struct atype_info *princname_fields[] = { &k5_atype_princname_0, &k5_atype_princname_1 }; DEFSEQTYPE(principal_data, krb5_principal_data, princname_fields); DEFPTRTYPE(principal, principal_data); DEFOPTIONALZEROTYPE(opt_principal, principal); /* * Define the seqno type, which is an ASN.1 integer represented in a uint32_t. * When decoding, negative 32-bit numbers are accepted for interoperability * with old implementations. */ static krb5_error_code encode_seqno(asn1buf *buf, const void *p, taginfo *rettag) { uint32_t val = *(uint32_t *)p; rettag->asn1class = UNIVERSAL; rettag->construction = PRIMITIVE; rettag->tagnum = ASN1_INTEGER; k5_asn1_encode_uint(buf, val); return 0; } static krb5_error_code decode_seqno(const taginfo *t, const uint8_t *asn1, size_t len, void *p) { krb5_error_code ret; intmax_t val; ret = k5_asn1_decode_int(asn1, len, &val); if (ret) return ret; if (val < INT32_MIN || val > 0xFFFFFFFF) return ASN1_OVERFLOW; /* Negative values will cast correctly to uint32_t. */ *(uint32_t *)p = val; return 0; } static int check_seqno(const taginfo *t) { return (t->asn1class == UNIVERSAL && t->construction == PRIMITIVE && t->tagnum == ASN1_INTEGER); } DEFFNTYPE(seqno, uint32_t, encode_seqno, decode_seqno, check_seqno, NULL); DEFOPTIONALZEROTYPE(opt_seqno, seqno); /* Define the kerberos_time type, which is an ASN.1 generaltime represented in * a krb5_timestamp. */ static krb5_error_code encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag) { time_t val = ts2tt(*(krb5_timestamp *)p); rettag->asn1class = UNIVERSAL; rettag->construction = PRIMITIVE; rettag->tagnum = ASN1_GENERALTIME; return k5_asn1_encode_generaltime(buf, val); } static krb5_error_code decode_kerberos_time(const taginfo *t, const uint8_t *asn1, size_t len, void *p) { krb5_error_code ret; time_t val; ret = k5_asn1_decode_generaltime(asn1, len, &val); if (ret) return ret; *(krb5_timestamp *)p = val; return 0; } static int check_kerberos_time(const taginfo *t) { return (t->asn1class == UNIVERSAL && t->construction == PRIMITIVE && t->tagnum == ASN1_GENERALTIME); } DEFFNTYPE(kerberos_time, krb5_timestamp, encode_kerberos_time, decode_kerberos_time, check_kerberos_time, NULL); DEFOPTIONALZEROTYPE(opt_kerberos_time, kerberos_time); DEFFIELD(address_0, krb5_address, addrtype, 0, int32); DEFCNFIELD(address_1, krb5_address, contents, length, 1, octetstring); const static struct atype_info *address_fields[] = { &k5_atype_address_0, &k5_atype_address_1 }; DEFSEQTYPE(address, krb5_address, address_fields); DEFPTRTYPE(address_ptr, address); DEFOPTIONALZEROTYPE(opt_address_ptr, address_ptr); DEFNULLTERMSEQOFTYPE(seqof_host_addresses, address_ptr); DEFPTRTYPE(ptr_seqof_host_addresses, seqof_host_addresses); DEFOPTIONALEMPTYTYPE(opt_ptr_seqof_host_addresses, ptr_seqof_host_addresses); /* * krb5_kvno is defined as unsigned int, but historically (MIT krb5 through 1.6 * in the encoder, and through 1.10 in the decoder) we treat it as signed, in * violation of RFC 4120. kvno values large enough to be problematic are only * likely to be seen with Windows read-only domain controllers, which overload * the high 16-bits of kvno values for krbtgt principals. Since Windows * encodes kvnos as signed 32-bit values, for interoperability it's best if we * do the same. */ DEFINTTYPE(kvno, krb5_kvno); DEFOPTIONALZEROTYPE(opt_kvno, kvno); DEFFIELD(enc_data_0, krb5_enc_data, enctype, 0, int32); DEFFIELD(enc_data_1, krb5_enc_data, kvno, 1, opt_kvno); DEFFIELD(enc_data_2, krb5_enc_data, ciphertext, 2, ostring_data); static const struct atype_info *encrypted_data_fields[] = { &k5_atype_enc_data_0, &k5_atype_enc_data_1, &k5_atype_enc_data_2 }; DEFSEQTYPE(encrypted_data, krb5_enc_data, encrypted_data_fields); static int nonempty_enc_data(const void *p) { const krb5_enc_data *val = p; return (val->ciphertext.data != NULL); } DEFOPTIONALTYPE(opt_encrypted_data, nonempty_enc_data, NULL, encrypted_data); /* Define the krb5_flags type, which is an ASN.1 bit string represented in a * 32-bit integer. */ static krb5_error_code encode_krb5_flags(asn1buf *buf, const void *p, taginfo *rettag) { uint8_t cbuf[4], *cptr = cbuf; store_32_be((uint32_t)*(const krb5_flags *)p, cbuf); rettag->asn1class = UNIVERSAL; rettag->construction = PRIMITIVE; rettag->tagnum = ASN1_BITSTRING; return k5_asn1_encode_bitstring(buf, &cptr, 4); } static krb5_error_code decode_krb5_flags(const taginfo *t, const uint8_t *asn1, size_t len, void *val) { krb5_error_code ret; size_t i, blen; krb5_flags f = 0; uint8_t *bits; ret = k5_asn1_decode_bitstring(asn1, len, &bits, &blen); if (ret) return ret; /* Copy up to 32 bits into f, starting at the most significant byte. */ for (i = 0; i < blen && i < 4; i++) f |= (uint32_t)bits[i] << (8 * (3 - i)); *(krb5_flags *)val = f; free(bits); return 0; } static int check_krb5_flags(const taginfo *t) { return (t->asn1class == UNIVERSAL && t->construction == PRIMITIVE && t->tagnum == ASN1_BITSTRING); } DEFFNTYPE(krb5_flags, krb5_flags, encode_krb5_flags, decode_krb5_flags, check_krb5_flags, NULL); DEFOPTIONALZEROTYPE(opt_krb5_flags, krb5_flags); DEFFIELD(authdata_0, krb5_authdata, ad_type, 0, int32); DEFCNFIELD(authdata_1, krb5_authdata, contents, length, 1, octetstring); static const struct atype_info *authdata_elt_fields[] = { &k5_atype_authdata_0, &k5_atype_authdata_1 }; DEFSEQTYPE(authdata_elt, krb5_authdata, authdata_elt_fields); DEFPTRTYPE(authdata_elt_ptr, authdata_elt); DEFNONEMPTYNULLTERMSEQOFTYPE(auth_data, authdata_elt_ptr); DEFPTRTYPE(auth_data_ptr, auth_data); DEFOPTIONALEMPTYTYPE(opt_auth_data_ptr, auth_data_ptr); /* authdata_types retrieves just the types of authdata elements in an array. */ DEFCTAGGEDTYPE(authdata_elt_type_0, 0, int32); static const struct atype_info *authdata_elt_type_fields[] = { &k5_atype_authdata_elt_type_0 }; DEFSEQTYPE(authdata_elt_type, krb5_authdatatype, authdata_elt_type_fields); DEFPTRTYPE(ptr_authdata_elt_type, authdata_elt_type); DEFCOUNTEDSEQOFTYPE(cseqof_authdata_elt_type, unsigned int, ptr_authdata_elt_type); struct authdata_types { krb5_authdatatype *types; unsigned int ntypes; }; DEFCOUNTEDTYPE(authdata_types, struct authdata_types, types, ntypes, cseqof_authdata_elt_type); DEFFIELD(keyblock_0, krb5_keyblock, enctype, 0, int32); DEFCNFIELD(keyblock_1, krb5_keyblock, contents, length, 1, octetstring); static const struct atype_info *encryption_key_fields[] = { &k5_atype_keyblock_0, &k5_atype_keyblock_1 }; DEFSEQTYPE(encryption_key, krb5_keyblock, encryption_key_fields); DEFPTRTYPE(ptr_encryption_key, encryption_key); DEFOPTIONALZEROTYPE(opt_ptr_encryption_key, ptr_encryption_key); DEFFIELD(checksum_0, krb5_checksum, checksum_type, 0, int32); DEFCNFIELD(checksum_1, krb5_checksum, contents, length, 1, octetstring); static const struct atype_info *checksum_fields[] = { &k5_atype_checksum_0, &k5_atype_checksum_1 }; DEFSEQTYPE(checksum, krb5_checksum, checksum_fields); DEFPTRTYPE(checksum_ptr, checksum); DEFNULLTERMSEQOFTYPE(seqof_checksum, checksum_ptr); DEFPTRTYPE(ptr_seqof_checksum, seqof_checksum); DEFOPTIONALZEROTYPE(opt_checksum_ptr, checksum_ptr); /* Define the last_req_type type, which is an int32_t with some massaging on * decode for backward compatibility. */ static krb5_error_code encode_lr_type(asn1buf *buf, const void *p, taginfo *rettag) { int32_t val = *(int32_t *)p; rettag->asn1class = UNIVERSAL; rettag->construction = PRIMITIVE; rettag->tagnum = ASN1_INTEGER; k5_asn1_encode_int(buf, val); return 0; } static krb5_error_code decode_lr_type(const taginfo *t, const uint8_t *asn1, size_t len, void *p) { krb5_error_code ret; intmax_t val; ret = k5_asn1_decode_int(asn1, len, &val); if (ret) return ret; if (val > INT32_MAX || val < INT32_MIN) return ASN1_OVERFLOW; *(int32_t *)p = val; return 0; } static int check_lr_type(const taginfo *t) { return (t->asn1class == UNIVERSAL && t->construction == PRIMITIVE && t->tagnum == ASN1_INTEGER); } DEFFNTYPE(last_req_type, int32_t, encode_lr_type, decode_lr_type, check_lr_type, NULL); DEFFIELD(last_req_0, krb5_last_req_entry, lr_type, 0, last_req_type); DEFFIELD(last_req_1, krb5_last_req_entry, value, 1, kerberos_time); static const struct atype_info *lr_fields[] = { &k5_atype_last_req_0, &k5_atype_last_req_1 }; DEFSEQTYPE(last_req_ent, krb5_last_req_entry, lr_fields); DEFPTRTYPE(last_req_ent_ptr, last_req_ent); DEFNONEMPTYNULLTERMSEQOFTYPE(last_req, last_req_ent_ptr); DEFPTRTYPE(last_req_ptr, last_req); DEFCTAGGEDTYPE(ticket_0, 0, krb5_version); DEFFIELD(ticket_1, krb5_ticket, server, 1, realm_of_principal); DEFFIELD(ticket_2, krb5_ticket, server, 2, principal); DEFFIELD(ticket_3, krb5_ticket, enc_part, 3, encrypted_data); static const struct atype_info *ticket_fields[] = { &k5_atype_ticket_0, &k5_atype_ticket_1, &k5_atype_ticket_2, &k5_atype_ticket_3 }; DEFSEQTYPE(untagged_ticket, krb5_ticket, ticket_fields); DEFAPPTAGGEDTYPE(ticket, 1, untagged_ticket); /* First context tag is 1, not 0. */ DEFFIELD(pa_data_1, krb5_pa_data, pa_type, 1, int32); DEFCNFIELD(pa_data_2, krb5_pa_data, contents, length, 2, octetstring); static const struct atype_info *pa_data_fields[] = { &k5_atype_pa_data_1, &k5_atype_pa_data_2 }; DEFSEQTYPE(pa_data, krb5_pa_data, pa_data_fields); DEFPTRTYPE(pa_data_ptr, pa_data); DEFNULLTERMSEQOFTYPE(seqof_pa_data, pa_data_ptr); DEFPTRTYPE(ptr_seqof_pa_data, seqof_pa_data); DEFOPTIONALEMPTYTYPE(opt_ptr_seqof_pa_data, ptr_seqof_pa_data); DEFPTRTYPE(ticket_ptr, ticket); DEFNONEMPTYNULLTERMSEQOFTYPE(seqof_ticket,ticket_ptr); DEFPTRTYPE(ptr_seqof_ticket, seqof_ticket); DEFOPTIONALEMPTYTYPE(opt_ptr_seqof_ticket, ptr_seqof_ticket); static int is_enc_kdc_rep_start_set(const void *p) { const krb5_enc_kdc_rep_part *val = p; return (val->times.starttime != 0); } static void init_enc_kdc_rep_start(void *p) { krb5_enc_kdc_rep_part *val = p; val->times.starttime = val->times.authtime; } static int is_renewable_flag_set(const void *p) { const krb5_enc_kdc_rep_part *val = p; return (val->flags & TKT_FLG_RENEWABLE); } DEFFIELD(enc_kdc_rep_0, krb5_enc_kdc_rep_part, session, 0, ptr_encryption_key); DEFFIELD(enc_kdc_rep_1, krb5_enc_kdc_rep_part, last_req, 1, last_req_ptr); DEFFIELD(enc_kdc_rep_2, krb5_enc_kdc_rep_part, nonce, 2, int32); DEFFIELD(enc_kdc_rep_3, krb5_enc_kdc_rep_part, key_exp, 3, opt_kerberos_time); DEFFIELD(enc_kdc_rep_4, krb5_enc_kdc_rep_part, flags, 4, krb5_flags); DEFFIELD(enc_kdc_rep_5, krb5_enc_kdc_rep_part, times.authtime, 5, kerberos_time); DEFFIELD(enc_kdc_rep_6_def, krb5_enc_kdc_rep_part, times.starttime, 6, kerberos_time); DEFOPTIONALTYPE(enc_kdc_rep_6, is_enc_kdc_rep_start_set, init_enc_kdc_rep_start, enc_kdc_rep_6_def); DEFFIELD(enc_kdc_rep_7, krb5_enc_kdc_rep_part, times.endtime, 7, kerberos_time); DEFFIELD(enc_kdc_rep_8_def, krb5_enc_kdc_rep_part, times.renew_till, 8, kerberos_time); DEFOPTIONALTYPE(enc_kdc_rep_8, is_renewable_flag_set, NULL, enc_kdc_rep_8_def); DEFFIELD(enc_kdc_rep_9, krb5_enc_kdc_rep_part, server, 9, realm_of_principal); DEFFIELD(enc_kdc_rep_10, krb5_enc_kdc_rep_part, server, 10, principal); DEFFIELD(enc_kdc_rep_11, krb5_enc_kdc_rep_part, caddrs, 11, opt_ptr_seqof_host_addresses); DEFFIELD(enc_kdc_rep_12, krb5_enc_kdc_rep_part, enc_padata, 12, opt_ptr_seqof_pa_data); static const struct atype_info *enc_kdc_rep_part_fields[] = { &k5_atype_enc_kdc_rep_0, &k5_atype_enc_kdc_rep_1, &k5_atype_enc_kdc_rep_2, &k5_atype_enc_kdc_rep_3, &k5_atype_enc_kdc_rep_4, &k5_atype_enc_kdc_rep_5, &k5_atype_enc_kdc_rep_6, &k5_atype_enc_kdc_rep_7, &k5_atype_enc_kdc_rep_8, &k5_atype_enc_kdc_rep_9, &k5_atype_enc_kdc_rep_10, &k5_atype_enc_kdc_rep_11, &k5_atype_enc_kdc_rep_12 }; DEFSEQTYPE(enc_kdc_rep_part, krb5_enc_kdc_rep_part, enc_kdc_rep_part_fields); /* * Yuck! Eventually push this *up* above the encoder API and make the * rest of the library put the realm name in one consistent place. At * the same time, might as well add the msg-type field and encode both * AS-REQ and TGS-REQ through the same descriptor. */ typedef struct kdc_req_hack { krb5_kdc_req v; krb5_data server_realm; } kdc_req_hack; DEFFIELD(req_body_0, kdc_req_hack, v.kdc_options, 0, krb5_flags); DEFFIELD(req_body_1, kdc_req_hack, v.client, 1, opt_principal); DEFFIELD(req_body_2, kdc_req_hack, server_realm, 2, gstring_data); DEFFIELD(req_body_3, kdc_req_hack, v.server, 3, opt_principal); DEFFIELD(req_body_4, kdc_req_hack, v.from, 4, opt_kerberos_time); DEFFIELD(req_body_5, kdc_req_hack, v.till, 5, kerberos_time); DEFFIELD(req_body_6, kdc_req_hack, v.rtime, 6, opt_kerberos_time); DEFFIELD(req_body_7, kdc_req_hack, v.nonce, 7, int32); DEFCNFIELD(req_body_8, kdc_req_hack, v.ktype, v.nktypes, 8, cseqof_int32); DEFFIELD(req_body_9, kdc_req_hack, v.addresses, 9, opt_ptr_seqof_host_addresses); DEFFIELD(req_body_10, kdc_req_hack, v.authorization_data, 10, opt_encrypted_data); DEFFIELD(req_body_11, kdc_req_hack, v.second_ticket, 11, opt_ptr_seqof_ticket); static const struct atype_info *kdc_req_hack_fields[] = { &k5_atype_req_body_0, &k5_atype_req_body_1, &k5_atype_req_body_2, &k5_atype_req_body_3, &k5_atype_req_body_4, &k5_atype_req_body_5, &k5_atype_req_body_6, &k5_atype_req_body_7, &k5_atype_req_body_8, &k5_atype_req_body_9, &k5_atype_req_body_10, &k5_atype_req_body_11 }; DEFSEQTYPE(kdc_req_body_hack, kdc_req_hack, kdc_req_hack_fields); static krb5_error_code encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out) { const krb5_kdc_req *val = p; kdc_req_hack h; h.v = *val; if (val->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY) { if (val->second_ticket != NULL && val->second_ticket[0] != NULL) h.server_realm = val->second_ticket[0]->server->realm; else return ASN1_MISSING_FIELD; } else if (val->server != NULL) h.server_realm = val->server->realm; else return ASN1_MISSING_FIELD; return k5_asn1_encode_atype(buf, &h, &k5_atype_kdc_req_body_hack, tag_out); } static void free_kdc_req_body(void *val) { krb5_kdc_req *req = val; krb5_free_principal(NULL, req->client); krb5_free_principal(NULL, req->server); free(req->ktype); krb5_free_addresses(NULL, req->addresses); free(req->authorization_data.ciphertext.data); krb5_free_tickets(NULL, req->second_ticket); } static krb5_error_code decode_kdc_req_body(const taginfo *t, const uint8_t *asn1, size_t len, void *val) { krb5_error_code ret; kdc_req_hack h; krb5_kdc_req *b = val; memset(&h, 0, sizeof(h)); ret = k5_asn1_decode_atype(t, asn1, len, &k5_atype_kdc_req_body_hack, &h); if (ret) return ret; b->kdc_options = h.v.kdc_options; b->client = h.v.client; b->server = h.v.server; b->from = h.v.from; b->till = h.v.till; b->rtime = h.v.rtime; b->nonce = h.v.nonce; b->ktype = h.v.ktype; b->nktypes = h.v.nktypes; b->addresses = h.v.addresses; b->authorization_data = h.v.authorization_data; b->second_ticket = h.v.second_ticket; if (b->client != NULL && b->server != NULL) { ret = krb5int_copy_data_contents(NULL, &h.server_realm, &b->client->realm); if (ret) { free_kdc_req_body(b); free(h.server_realm.data); return ret; } b->server->realm = h.server_realm; } else if (b->client != NULL) b->client->realm = h.server_realm; else if (b->server != NULL) b->server->realm = h.server_realm; else free(h.server_realm.data); return 0; } static int check_kdc_req_body(const taginfo *t) { return (t->asn1class == UNIVERSAL && t->construction == CONSTRUCTED && t->tagnum == ASN1_SEQUENCE); } DEFFNTYPE(kdc_req_body, krb5_kdc_req, encode_kdc_req_body, decode_kdc_req_body, check_kdc_req_body, free_kdc_req_body); /* end ugly hack */ DEFFIELD(transited_0, krb5_transited, tr_type, 0, octet); DEFFIELD(transited_1, krb5_transited, tr_contents, 1, ostring_data); static const struct atype_info *transited_fields[] = { &k5_atype_transited_0, &k5_atype_transited_1 }; DEFSEQTYPE(transited, krb5_transited, transited_fields); static int is_safe_timestamp_set(const void *p) { const krb5_safe *val = p; return (val->timestamp != 0); } DEFFIELD(safe_body_0, krb5_safe, user_data, 0, ostring_data); DEFFIELD(safe_body_1, krb5_safe, timestamp, 1, opt_kerberos_time); DEFFIELD(safe_body_2_def, krb5_safe, usec, 2, int32); DEFOPTIONALTYPE(safe_body_2, is_safe_timestamp_set, NULL, safe_body_2_def); DEFFIELD(safe_body_3, krb5_safe, seq_number, 3, opt_seqno); DEFFIELD(safe_body_4, krb5_safe, s_address, 4, address_ptr); DEFFIELD(safe_body_5, krb5_safe, r_address, 5, opt_address_ptr); static const struct atype_info *safe_body_fields[] = { &k5_atype_safe_body_0, &k5_atype_safe_body_1, &k5_atype_safe_body_2, &k5_atype_safe_body_3, &k5_atype_safe_body_4, &k5_atype_safe_body_5 }; DEFSEQTYPE(safe_body, krb5_safe, safe_body_fields); DEFFIELD(cred_info_0, krb5_cred_info, session, 0, ptr_encryption_key); DEFFIELD(cred_info_1, krb5_cred_info, client, 1, opt_realm_of_principal); DEFFIELD(cred_info_2, krb5_cred_info, client, 2, opt_principal); DEFFIELD(cred_info_3, krb5_cred_info, flags, 3, opt_krb5_flags); DEFFIELD(cred_info_4, krb5_cred_info, times.authtime, 4, opt_kerberos_time); DEFFIELD(cred_info_5, krb5_cred_info, times.starttime, 5, opt_kerberos_time); DEFFIELD(cred_info_6, krb5_cred_info, times.endtime, 6, opt_kerberos_time); DEFFIELD(cred_info_7, krb5_cred_info, times.renew_till, 7, opt_kerberos_time); DEFFIELD(cred_info_8, krb5_cred_info, server, 8, opt_realm_of_principal); DEFFIELD(cred_info_9, krb5_cred_info, server, 9, opt_principal); DEFFIELD(cred_info_10, krb5_cred_info, caddrs, 10, opt_ptr_seqof_host_addresses); static const struct atype_info *krb_cred_info_fields[] = { &k5_atype_cred_info_0, &k5_atype_cred_info_1, &k5_atype_cred_info_2, &k5_atype_cred_info_3, &k5_atype_cred_info_4, &k5_atype_cred_info_5, &k5_atype_cred_info_6, &k5_atype_cred_info_7, &k5_atype_cred_info_8, &k5_atype_cred_info_9, &k5_atype_cred_info_10 }; DEFSEQTYPE(cred_info, krb5_cred_info, krb_cred_info_fields); DEFPTRTYPE(cred_info_ptr, cred_info); DEFNULLTERMSEQOFTYPE(seqof_cred_info, cred_info_ptr); DEFPTRTYPE(ptrseqof_cred_info, seqof_cred_info); static int is_salt_present(const void *p) { const krb5_etype_info_entry *val = p; return (val->length != KRB5_ETYPE_NO_SALT); } static void init_no_salt(void *p) { krb5_etype_info_entry *val = p; val->length = KRB5_ETYPE_NO_SALT; } DEFFIELD(etype_info_0, krb5_etype_info_entry, etype, 0, int32); DEFCNFIELD(etype_info_1_def, krb5_etype_info_entry, salt, length, 1, octetstring); DEFOPTIONALTYPE(etype_info_1, is_salt_present, init_no_salt, etype_info_1_def); static const struct atype_info *etype_info_entry_fields[] = { &k5_atype_etype_info_0, &k5_atype_etype_info_1 }; DEFSEQTYPE(etype_info_entry, krb5_etype_info_entry, etype_info_entry_fields); /* First field is the same as etype-info. */ DEFCNFIELD(etype_info2_1_def, krb5_etype_info_entry, salt, length, 1, u_generalstring); DEFOPTIONALTYPE(etype_info2_1, is_salt_present, init_no_salt, etype_info2_1_def); DEFFIELD(etype_info2_2, krb5_etype_info_entry, s2kparams, 2, opt_ostring_data); static const struct atype_info *etype_info2_entry_fields[] = { &k5_atype_etype_info_0, &k5_atype_etype_info2_1, &k5_atype_etype_info2_2 }; DEFSEQTYPE(etype_info2_entry, krb5_etype_info_entry, etype_info2_entry_fields); DEFPTRTYPE(etype_info_entry_ptr, etype_info_entry); DEFNULLTERMSEQOFTYPE(etype_info, etype_info_entry_ptr); DEFPTRTYPE(etype_info2_entry_ptr, etype_info2_entry); DEFNULLTERMSEQOFTYPE(etype_info2, etype_info2_entry_ptr); DEFFIELD(sch_0, krb5_sam_challenge_2, sam_challenge_2_body, 0, der_data); DEFFIELD(sch_1, krb5_sam_challenge_2, sam_cksum, 1, ptr_seqof_checksum); static const struct atype_info *sam_challenge_2_fields[] = { &k5_atype_sch_0, &k5_atype_sch_1 }; DEFSEQTYPE(sam_challenge_2, krb5_sam_challenge_2, sam_challenge_2_fields); DEFFIELD(schb_0, krb5_sam_challenge_2_body, sam_type, 0, int32); DEFFIELD(schb_1, krb5_sam_challenge_2_body, sam_flags, 1, krb5_flags); DEFFIELD(schb_2, krb5_sam_challenge_2_body, sam_type_name, 2, opt_ostring_data); DEFFIELD(schb_3, krb5_sam_challenge_2_body, sam_track_id, 3, opt_ostring_data); DEFFIELD(schb_4, krb5_sam_challenge_2_body, sam_challenge_label, 4, opt_ostring_data); DEFFIELD(schb_5, krb5_sam_challenge_2_body, sam_challenge, 5, opt_ostring_data); DEFFIELD(schb_6, krb5_sam_challenge_2_body, sam_response_prompt, 6, opt_ostring_data); DEFFIELD(schb_7, krb5_sam_challenge_2_body, sam_pk_for_sad, 7, opt_ostring_data); DEFFIELD(schb_8, krb5_sam_challenge_2_body, sam_nonce, 8, int32); DEFFIELD(schb_9, krb5_sam_challenge_2_body, sam_etype, 9, int32); static const struct atype_info *sam_challenge_2_body_fields[] = { &k5_atype_schb_0, &k5_atype_schb_1, &k5_atype_schb_2, &k5_atype_schb_3, &k5_atype_schb_4, &k5_atype_schb_5, &k5_atype_schb_6, &k5_atype_schb_7, &k5_atype_schb_8, &k5_atype_schb_9 }; DEFSEQTYPE(sam_challenge_2_body,krb5_sam_challenge_2_body, sam_challenge_2_body_fields); DEFFIELD(esre_0, krb5_enc_sam_response_enc_2, sam_nonce, 0, int32); DEFFIELD(esre_1, krb5_enc_sam_response_enc_2, sam_sad, 1, opt_ostring_data); static const struct atype_info *enc_sam_response_enc_2_fields[] = { &k5_atype_esre_0, &k5_atype_esre_1 }; DEFSEQTYPE(enc_sam_response_enc_2, krb5_enc_sam_response_enc_2, enc_sam_response_enc_2_fields); DEFFIELD(sam_resp_0, krb5_sam_response_2, sam_type, 0, int32); DEFFIELD(sam_resp_1, krb5_sam_response_2, sam_flags, 1, krb5_flags); DEFFIELD(sam_resp_2, krb5_sam_response_2, sam_track_id, 2, opt_ostring_data); DEFFIELD(sam_resp_3, krb5_sam_response_2, sam_enc_nonce_or_sad, 3, encrypted_data); DEFFIELD(sam_resp_4, krb5_sam_response_2, sam_nonce, 4, int32); static const struct atype_info *sam_response_2_fields[] = { &k5_atype_sam_resp_0, &k5_atype_sam_resp_1, &k5_atype_sam_resp_2, &k5_atype_sam_resp_3, &k5_atype_sam_resp_4 }; DEFSEQTYPE(sam_response_2, krb5_sam_response_2, sam_response_2_fields); DEFCTAGGEDTYPE(authenticator_0, 0, krb5_version); DEFFIELD(authenticator_1, krb5_authenticator, client, 1, realm_of_principal); DEFFIELD(authenticator_2, krb5_authenticator, client, 2, principal); DEFFIELD(authenticator_3, krb5_authenticator, checksum, 3, opt_checksum_ptr); DEFFIELD(authenticator_4, krb5_authenticator, cusec, 4, int32); DEFFIELD(authenticator_5, krb5_authenticator, ctime, 5, kerberos_time); DEFFIELD(authenticator_6, krb5_authenticator, subkey, 6, opt_ptr_encryption_key); DEFFIELD(authenticator_7, krb5_authenticator, seq_number, 7, opt_seqno); DEFFIELD(authenticator_8, krb5_authenticator, authorization_data, 8, opt_auth_data_ptr); static const struct atype_info *authenticator_fields[] = { &k5_atype_authenticator_0, &k5_atype_authenticator_1, &k5_atype_authenticator_2, &k5_atype_authenticator_3, &k5_atype_authenticator_4, &k5_atype_authenticator_5, &k5_atype_authenticator_6, &k5_atype_authenticator_7, &k5_atype_authenticator_8 }; DEFSEQTYPE(untagged_authenticator, krb5_authenticator, authenticator_fields); DEFAPPTAGGEDTYPE(authenticator, 2, untagged_authenticator); DEFFIELD(enc_tkt_0, krb5_enc_tkt_part, flags, 0, krb5_flags); DEFFIELD(enc_tkt_1, krb5_enc_tkt_part, session, 1, ptr_encryption_key); DEFFIELD(enc_tkt_2, krb5_enc_tkt_part, client, 2, realm_of_principal); DEFFIELD(enc_tkt_3, krb5_enc_tkt_part, client, 3, principal); DEFFIELD(enc_tkt_4, krb5_enc_tkt_part, transited, 4, transited); DEFFIELD(enc_tkt_5, krb5_enc_tkt_part, times.authtime, 5, kerberos_time); DEFFIELD(enc_tkt_6, krb5_enc_tkt_part, times.starttime, 6, opt_kerberos_time); DEFFIELD(enc_tkt_7, krb5_enc_tkt_part, times.endtime, 7, kerberos_time); DEFFIELD(enc_tkt_8, krb5_enc_tkt_part, times.renew_till, 8, opt_kerberos_time); DEFFIELD(enc_tkt_9, krb5_enc_tkt_part, caddrs, 9, opt_ptr_seqof_host_addresses); DEFFIELD(enc_tkt_10, krb5_enc_tkt_part, authorization_data, 10, opt_auth_data_ptr); static const struct atype_info *enc_tkt_part_fields[] = { &k5_atype_enc_tkt_0, &k5_atype_enc_tkt_1, &k5_atype_enc_tkt_2, &k5_atype_enc_tkt_3, &k5_atype_enc_tkt_4, &k5_atype_enc_tkt_5, &k5_atype_enc_tkt_6, &k5_atype_enc_tkt_7, &k5_atype_enc_tkt_8, &k5_atype_enc_tkt_9, &k5_atype_enc_tkt_10 }; DEFSEQTYPE(untagged_enc_tkt_part, krb5_enc_tkt_part, enc_tkt_part_fields); DEFAPPTAGGEDTYPE(enc_tkt_part, 3, untagged_enc_tkt_part); DEFAPPTAGGEDTYPE(enc_as_rep_part, 25, enc_kdc_rep_part); DEFAPPTAGGEDTYPE(enc_tgs_rep_part, 26, enc_kdc_rep_part); DEFCTAGGEDTYPE(kdc_rep_0, 0, krb5_version); DEFFIELD(kdc_rep_1, krb5_kdc_rep, msg_type, 1, uint); DEFFIELD(kdc_rep_2, krb5_kdc_rep, padata, 2, opt_ptr_seqof_pa_data); DEFFIELD(kdc_rep_3, krb5_kdc_rep, client, 3, realm_of_principal); DEFFIELD(kdc_rep_4, krb5_kdc_rep, client, 4, principal); DEFFIELD(kdc_rep_5, krb5_kdc_rep, ticket, 5, ticket_ptr); DEFFIELD(kdc_rep_6, krb5_kdc_rep, enc_part, 6, encrypted_data); static const struct atype_info *kdc_rep_fields[] = { &k5_atype_kdc_rep_0, &k5_atype_kdc_rep_1, &k5_atype_kdc_rep_2, &k5_atype_kdc_rep_3, &k5_atype_kdc_rep_4, &k5_atype_kdc_rep_5, &k5_atype_kdc_rep_6 }; DEFSEQTYPE(kdc_rep, krb5_kdc_rep, kdc_rep_fields); DEFAPPTAGGEDTYPE(as_rep, 11, kdc_rep); DEFAPPTAGGEDTYPE(tgs_rep, 13, kdc_rep); DEFINT_IMMEDIATE(ap_req_msg_type, ASN1_KRB_AP_REQ, 0); DEFCTAGGEDTYPE(ap_req_0, 0, krb5_version); DEFCTAGGEDTYPE(ap_req_1, 1, ap_req_msg_type); DEFFIELD(ap_req_2, krb5_ap_req, ap_options, 2, krb5_flags); DEFFIELD(ap_req_3, krb5_ap_req, ticket, 3, ticket_ptr); DEFFIELD(ap_req_4, krb5_ap_req, authenticator, 4, encrypted_data); static const struct atype_info *ap_req_fields[] = { &k5_atype_ap_req_0, &k5_atype_ap_req_1, &k5_atype_ap_req_2, &k5_atype_ap_req_3, &k5_atype_ap_req_4 }; DEFSEQTYPE(untagged_ap_req, krb5_ap_req, ap_req_fields); DEFAPPTAGGEDTYPE(ap_req, 14, untagged_ap_req); DEFINT_IMMEDIATE(ap_rep_msg_type, ASN1_KRB_AP_REP, 0); DEFCTAGGEDTYPE(ap_rep_0, 0, krb5_version); DEFCTAGGEDTYPE(ap_rep_1, 1, ap_rep_msg_type); DEFFIELD(ap_rep_2, krb5_ap_rep, enc_part, 2, encrypted_data); static const struct atype_info *ap_rep_fields[] = { &k5_atype_ap_rep_0, &k5_atype_ap_rep_1, &k5_atype_ap_rep_2 }; DEFSEQTYPE(untagged_ap_rep, krb5_ap_rep, ap_rep_fields); DEFAPPTAGGEDTYPE(ap_rep, 15, untagged_ap_rep); DEFFIELD(ap_rep_enc_part_0, krb5_ap_rep_enc_part, ctime, 0, kerberos_time); DEFFIELD(ap_rep_enc_part_1, krb5_ap_rep_enc_part, cusec, 1, int32); DEFFIELD(ap_rep_enc_part_2, krb5_ap_rep_enc_part, subkey, 2, opt_ptr_encryption_key); DEFFIELD(ap_rep_enc_part_3, krb5_ap_rep_enc_part, seq_number, 3, opt_seqno); static const struct atype_info *ap_rep_enc_part_fields[] = { &k5_atype_ap_rep_enc_part_0, &k5_atype_ap_rep_enc_part_1, &k5_atype_ap_rep_enc_part_2, &k5_atype_ap_rep_enc_part_3 }; DEFSEQTYPE(untagged_ap_rep_enc_part, krb5_ap_rep_enc_part, ap_rep_enc_part_fields); DEFAPPTAGGEDTYPE(ap_rep_enc_part, 27, untagged_ap_rep_enc_part); /* First context tag is 1. Fourth field is the encoding of the krb5_kdc_req * structure as a KDC-REQ-BODY. */ DEFCTAGGEDTYPE(kdc_req_1, 1, krb5_version); DEFFIELD(kdc_req_2, krb5_kdc_req, msg_type, 2, uint); DEFFIELD(kdc_req_3, krb5_kdc_req, padata, 3, opt_ptr_seqof_pa_data); DEFCTAGGEDTYPE(kdc_req_4, 4, kdc_req_body); static const struct atype_info *kdc_req_fields[] = { &k5_atype_kdc_req_1, &k5_atype_kdc_req_2, &k5_atype_kdc_req_3, &k5_atype_kdc_req_4 }; DEFSEQTYPE(kdc_req, krb5_kdc_req, kdc_req_fields); DEFAPPTAGGEDTYPE(as_req, 10, kdc_req); DEFAPPTAGGEDTYPE(tgs_req, 12, kdc_req); /* This is only needed because libkrb5 doesn't set msg_type when encoding * krb5_kdc_reqs. If we fix that, we can use the above types for encoding. */ DEFINT_IMMEDIATE(as_req_msg_type, KRB5_AS_REQ, 0); DEFCTAGGEDTYPE(as_req_2, 2, as_req_msg_type); DEFINT_IMMEDIATE(tgs_req_msg_type, KRB5_TGS_REQ, 0); DEFCTAGGEDTYPE(tgs_req_2, 2, tgs_req_msg_type); static const struct atype_info *as_req_fields[] = { &k5_atype_kdc_req_1, &k5_atype_as_req_2, &k5_atype_kdc_req_3, &k5_atype_kdc_req_4 }; static const struct atype_info *tgs_req_fields[] = { &k5_atype_kdc_req_1, &k5_atype_tgs_req_2, &k5_atype_kdc_req_3, &k5_atype_kdc_req_4 }; DEFSEQTYPE(untagged_as_req, krb5_kdc_req, as_req_fields); DEFAPPTAGGEDTYPE(as_req_encode, 10, untagged_as_req); DEFSEQTYPE(untagged_tgs_req, krb5_kdc_req, tgs_req_fields); DEFAPPTAGGEDTYPE(tgs_req_encode, 12, untagged_tgs_req); DEFINT_IMMEDIATE(safe_msg_type, ASN1_KRB_SAFE, 0); DEFCTAGGEDTYPE(safe_0, 0, krb5_version); DEFCTAGGEDTYPE(safe_1, 1, safe_msg_type); DEFCTAGGEDTYPE(safe_2, 2, safe_body); DEFFIELD(safe_3, krb5_safe, checksum, 3, checksum_ptr); static const struct atype_info *safe_fields[] = { &k5_atype_safe_0, &k5_atype_safe_1, &k5_atype_safe_2, &k5_atype_safe_3 }; DEFSEQTYPE(untagged_safe, krb5_safe, safe_fields); DEFAPPTAGGEDTYPE(safe, 20, untagged_safe); /* Hack to encode a KRB-SAFE with a pre-specified body encoding. The integer- * immediate fields are borrowed from krb5_safe_fields above. */ DEFPTRTYPE(saved_safe_body_ptr, der_data); DEFOFFSETTYPE(safe_checksum_only, krb5_safe, checksum, checksum_ptr); DEFPTRTYPE(safe_checksum_only_ptr, safe_checksum_only); DEFFIELD(safe_with_body_2, struct krb5_safe_with_body, body, 2, saved_safe_body_ptr); DEFFIELD(safe_with_body_3, struct krb5_safe_with_body, safe, 3, safe_checksum_only_ptr); static const struct atype_info *safe_with_body_fields[] = { &k5_atype_safe_0, &k5_atype_safe_1, &k5_atype_safe_with_body_2, &k5_atype_safe_with_body_3 }; DEFSEQTYPE(untagged_safe_with_body, struct krb5_safe_with_body, safe_with_body_fields); DEFAPPTAGGEDTYPE(safe_with_body, 20, untagged_safe_with_body); /* Third tag is [3] instead of [2]. */ DEFINT_IMMEDIATE(priv_msg_type, ASN1_KRB_PRIV, 0); DEFCTAGGEDTYPE(priv_0, 0, krb5_version); DEFCTAGGEDTYPE(priv_1, 1, priv_msg_type); DEFFIELD(priv_3, krb5_priv, enc_part, 3, encrypted_data); static const struct atype_info *priv_fields[] = { &k5_atype_priv_0, &k5_atype_priv_1, &k5_atype_priv_3 }; DEFSEQTYPE(untagged_priv, krb5_priv, priv_fields); DEFAPPTAGGEDTYPE(priv, 21, untagged_priv); static int is_priv_timestamp_set(const void *p) { const krb5_priv_enc_part *val = p; return (val->timestamp != 0); } DEFFIELD(priv_enc_part_0, krb5_priv_enc_part, user_data, 0, ostring_data); DEFFIELD(priv_enc_part_1, krb5_priv_enc_part, timestamp, 1, opt_kerberos_time); DEFFIELD(priv_enc_part_2_def, krb5_priv_enc_part, usec, 2, int32); DEFOPTIONALTYPE(priv_enc_part_2, is_priv_timestamp_set, NULL, priv_enc_part_2_def); DEFFIELD(priv_enc_part_3, krb5_priv_enc_part, seq_number, 3, opt_seqno); DEFFIELD(priv_enc_part_4, krb5_priv_enc_part, s_address, 4, address_ptr); DEFFIELD(priv_enc_part_5, krb5_priv_enc_part, r_address, 5, opt_address_ptr); static const struct atype_info *priv_enc_part_fields[] = { &k5_atype_priv_enc_part_0, &k5_atype_priv_enc_part_1, &k5_atype_priv_enc_part_2, &k5_atype_priv_enc_part_3, &k5_atype_priv_enc_part_4, &k5_atype_priv_enc_part_5 }; DEFSEQTYPE(untagged_priv_enc_part, krb5_priv_enc_part, priv_enc_part_fields); DEFAPPTAGGEDTYPE(priv_enc_part, 28, untagged_priv_enc_part); DEFINT_IMMEDIATE(cred_msg_type, ASN1_KRB_CRED, 0); DEFCTAGGEDTYPE(cred_0, 0, krb5_version); DEFCTAGGEDTYPE(cred_1, 1, cred_msg_type); DEFFIELD(cred_2, krb5_cred, tickets, 2, ptr_seqof_ticket); DEFFIELD(cred_3, krb5_cred, enc_part, 3, encrypted_data); static const struct atype_info *cred_fields[] = { &k5_atype_cred_0, &k5_atype_cred_1, &k5_atype_cred_2, &k5_atype_cred_3 }; DEFSEQTYPE(untagged_cred, krb5_cred, cred_fields); DEFAPPTAGGEDTYPE(krb5_cred, 22, untagged_cred); static int is_cred_timestamp_set(const void *p) { const krb5_cred_enc_part *val = p; return (val->timestamp != 0); } DEFFIELD(enc_cred_part_0, krb5_cred_enc_part, ticket_info, 0, ptrseqof_cred_info); DEFFIELD(enc_cred_part_1, krb5_cred_enc_part, nonce, 1, opt_int32); DEFFIELD(enc_cred_part_2, krb5_cred_enc_part, timestamp, 2, opt_kerberos_time); DEFFIELD(enc_cred_part_3_def, krb5_cred_enc_part, usec, 3, int32); DEFOPTIONALTYPE(enc_cred_part_3, is_cred_timestamp_set, NULL, enc_cred_part_3_def); DEFFIELD(enc_cred_part_4, krb5_cred_enc_part, s_address, 4, opt_address_ptr); DEFFIELD(enc_cred_part_5, krb5_cred_enc_part, r_address, 5, opt_address_ptr); static const struct atype_info *enc_cred_part_fields[] = { &k5_atype_enc_cred_part_0, &k5_atype_enc_cred_part_1, &k5_atype_enc_cred_part_2, &k5_atype_enc_cred_part_3, &k5_atype_enc_cred_part_4, &k5_atype_enc_cred_part_5 }; DEFSEQTYPE(untagged_enc_cred_part, krb5_cred_enc_part, enc_cred_part_fields); DEFAPPTAGGEDTYPE(enc_cred_part, 29, untagged_enc_cred_part); DEFINT_IMMEDIATE(error_msg_type, ASN1_KRB_ERROR, 0); DEFCTAGGEDTYPE(error_0, 0, krb5_version); DEFCTAGGEDTYPE(error_1, 1, error_msg_type); DEFFIELD(error_2, krb5_error, ctime, 2, opt_kerberos_time); DEFFIELD(error_3, krb5_error, cusec, 3, opt_int32); DEFFIELD(error_4, krb5_error, stime, 4, kerberos_time); DEFFIELD(error_5, krb5_error, susec, 5, int32); DEFFIELD(error_6, krb5_error, error, 6, uint32); DEFFIELD(error_7, krb5_error, client, 7, opt_realm_of_principal); DEFFIELD(error_8, krb5_error, client, 8, opt_principal); DEFFIELD(error_9, krb5_error, server, 9, realm_of_principal); DEFFIELD(error_10, krb5_error, server, 10, principal); DEFFIELD(error_11, krb5_error, text, 11, opt_gstring_data); DEFFIELD(error_12, krb5_error, e_data, 12, opt_ostring_data); static const struct atype_info *error_fields[] = { &k5_atype_error_0, &k5_atype_error_1, &k5_atype_error_2, &k5_atype_error_3, &k5_atype_error_4, &k5_atype_error_5, &k5_atype_error_6, &k5_atype_error_7, &k5_atype_error_8, &k5_atype_error_9, &k5_atype_error_10, &k5_atype_error_11, &k5_atype_error_12 }; DEFSEQTYPE(untagged_krb5_error, krb5_error, error_fields); DEFAPPTAGGEDTYPE(krb5_error, 30, untagged_krb5_error); DEFFIELD(pa_enc_ts_0, krb5_pa_enc_ts, patimestamp, 0, kerberos_time); DEFFIELD(pa_enc_ts_1, krb5_pa_enc_ts, pausec, 1, opt_int32); static const struct atype_info *pa_enc_ts_fields[] = { &k5_atype_pa_enc_ts_0, &k5_atype_pa_enc_ts_1 }; DEFSEQTYPE(pa_enc_ts, krb5_pa_enc_ts, pa_enc_ts_fields); DEFFIELD(setpw_0, struct krb5_setpw_req, password, 0, ostring_data); DEFFIELD(setpw_1, struct krb5_setpw_req, target, 1, principal); DEFFIELD(setpw_2, struct krb5_setpw_req, target, 2, realm_of_principal); static const struct atype_info *setpw_req_fields[] = { &k5_atype_setpw_0, &k5_atype_setpw_1, &k5_atype_setpw_2 }; DEFSEQTYPE(setpw_req, struct krb5_setpw_req, setpw_req_fields); /* [MS-SFU] Section 2.2.1. */ DEFFIELD(pa_for_user_0, krb5_pa_for_user, user, 0, principal); DEFFIELD(pa_for_user_1, krb5_pa_for_user, user, 1, realm_of_principal); DEFFIELD(pa_for_user_2, krb5_pa_for_user, cksum, 2, checksum); DEFFIELD(pa_for_user_3, krb5_pa_for_user, auth_package, 3, gstring_data); static const struct atype_info *pa_for_user_fields[] = { &k5_atype_pa_for_user_0, &k5_atype_pa_for_user_1, &k5_atype_pa_for_user_2, &k5_atype_pa_for_user_3, }; DEFSEQTYPE(pa_for_user, krb5_pa_for_user, pa_for_user_fields); /* [MS-SFU] Section 2.2.2. */ /* The user principal name may be absent, but the realm is required. */ static int is_s4u_principal_present(const void *p) { krb5_const_principal val = *(krb5_const_principal *)p; return (val->length != 0); } DEFOPTIONALTYPE(opt_s4u_principal, is_s4u_principal_present, NULL, principal); DEFFIELD(s4u_userid_0, krb5_s4u_userid, nonce, 0, int32); DEFFIELD(s4u_userid_1, krb5_s4u_userid, user, 1, opt_s4u_principal); DEFFIELD(s4u_userid_2, krb5_s4u_userid, user, 2, realm_of_principal); DEFFIELD(s4u_userid_3, krb5_s4u_userid, subject_cert, 3, opt_ostring_data); DEFFIELD(s4u_userid_4, krb5_s4u_userid, options, 4, opt_krb5_flags); static const struct atype_info *s4u_userid_fields[] = { &k5_atype_s4u_userid_0, &k5_atype_s4u_userid_1, &k5_atype_s4u_userid_2, &k5_atype_s4u_userid_3, &k5_atype_s4u_userid_4 }; DEFSEQTYPE(s4u_userid, krb5_s4u_userid, s4u_userid_fields); DEFFIELD(pa_s4u_x509_user_0, krb5_pa_s4u_x509_user, user_id, 0, s4u_userid); DEFFIELD(pa_s4u_x509_user_1, krb5_pa_s4u_x509_user, cksum, 1, checksum); static const struct atype_info *pa_s4u_x509_user_fields[] = { &k5_atype_pa_s4u_x509_user_0, &k5_atype_pa_s4u_x509_user_1 }; DEFSEQTYPE(pa_s4u_x509_user, krb5_pa_s4u_x509_user, pa_s4u_x509_user_fields); DEFFIELD(pa_pac_req_0, krb5_pa_pac_req, include_pac, 0, boolean); static const struct atype_info *pa_pac_req_fields[] = { &k5_atype_pa_pac_req_0 }; DEFSEQTYPE(pa_pac_req, krb5_pa_pac_req, pa_pac_req_fields); /* RFC 4537 */ DEFCOUNTEDTYPE(etype_list, krb5_etype_list, etypes, length, cseqof_int32); /* draft-ietf-krb-wg-preauth-framework-09 */ DEFFIELD(fast_armor_0, krb5_fast_armor, armor_type, 0, int32); DEFFIELD(fast_armor_1, krb5_fast_armor, armor_value, 1, ostring_data); static const struct atype_info *fast_armor_fields[] = { &k5_atype_fast_armor_0, &k5_atype_fast_armor_1 }; DEFSEQTYPE(fast_armor, krb5_fast_armor, fast_armor_fields); DEFPTRTYPE(ptr_fast_armor, fast_armor); DEFOPTIONALZEROTYPE(opt_ptr_fast_armor, ptr_fast_armor); DEFFIELD(fast_armored_req_0, krb5_fast_armored_req, armor, 0, opt_ptr_fast_armor); DEFFIELD(fast_armored_req_1, krb5_fast_armored_req, req_checksum, 1, checksum); DEFFIELD(fast_armored_req_2, krb5_fast_armored_req, enc_part, 2, encrypted_data); static const struct atype_info *fast_armored_req_fields[] = { &k5_atype_fast_armored_req_0, &k5_atype_fast_armored_req_1, &k5_atype_fast_armored_req_2 }; DEFSEQTYPE(fast_armored_req, krb5_fast_armored_req, fast_armored_req_fields); /* This is a CHOICE type with only one choice (so far) and we're not using a * distinguisher/union for it. */ DEFTAGGEDTYPE(pa_fx_fast_request, CONTEXT_SPECIFIC, CONSTRUCTED, 0, 0, fast_armored_req); DEFOFFSETTYPE(fast_req_padata, krb5_kdc_req, padata, ptr_seqof_pa_data); DEFPTRTYPE(ptr_fast_req_padata, fast_req_padata); DEFPTRTYPE(ptr_kdc_req_body, kdc_req_body); DEFFIELD(fast_req_0, krb5_fast_req, fast_options, 0, krb5_flags); DEFFIELD(fast_req_1, krb5_fast_req, req_body, 1, ptr_fast_req_padata); DEFFIELD(fast_req_2, krb5_fast_req, req_body, 2, ptr_kdc_req_body); static const struct atype_info *fast_req_fields[] = { &k5_atype_fast_req_0, &k5_atype_fast_req_1, &k5_atype_fast_req_2 }; DEFSEQTYPE(fast_req, krb5_fast_req, fast_req_fields); DEFFIELD(fast_finished_0, krb5_fast_finished, timestamp, 0, kerberos_time); DEFFIELD(fast_finished_1, krb5_fast_finished, usec, 1, int32); DEFFIELD(fast_finished_2, krb5_fast_finished, client, 2, realm_of_principal); DEFFIELD(fast_finished_3, krb5_fast_finished, client, 3, principal); DEFFIELD(fast_finished_4, krb5_fast_finished, ticket_checksum, 4, checksum); static const struct atype_info *fast_finished_fields[] = { &k5_atype_fast_finished_0, &k5_atype_fast_finished_1, &k5_atype_fast_finished_2, &k5_atype_fast_finished_3, &k5_atype_fast_finished_4 }; DEFSEQTYPE(fast_finished, krb5_fast_finished, fast_finished_fields); DEFPTRTYPE(ptr_fast_finished, fast_finished); DEFOPTIONALZEROTYPE(opt_ptr_fast_finished, ptr_fast_finished); DEFFIELD(fast_response_0, krb5_fast_response, padata, 0, ptr_seqof_pa_data); DEFFIELD(fast_response_1, krb5_fast_response, strengthen_key, 1, opt_ptr_encryption_key); DEFFIELD(fast_response_2, krb5_fast_response, finished, 2, opt_ptr_fast_finished); DEFFIELD(fast_response_3, krb5_fast_response, nonce, 3, int32); static const struct atype_info *fast_response_fields[] = { &k5_atype_fast_response_0, &k5_atype_fast_response_1, &k5_atype_fast_response_2, &k5_atype_fast_response_3 }; DEFSEQTYPE(fast_response, krb5_fast_response, fast_response_fields); DEFCTAGGEDTYPE(fast_rep_0, 0, encrypted_data); static const struct atype_info *fast_rep_fields[] = { &k5_atype_fast_rep_0 }; DEFSEQTYPE(fast_rep, krb5_enc_data, fast_rep_fields); /* This is a CHOICE type with only one choice (so far) and we're not using a * distinguisher/union for it. */ DEFTAGGEDTYPE(pa_fx_fast_reply, CONTEXT_SPECIFIC, CONSTRUCTED, 0, 0, fast_rep); DEFFIELD(ad_kdcissued_0, krb5_ad_kdcissued, ad_checksum, 0, checksum); DEFFIELD(ad_kdcissued_1, krb5_ad_kdcissued, i_principal, 1, opt_realm_of_principal); DEFFIELD(ad_kdcissued_2, krb5_ad_kdcissued, i_principal, 2, opt_principal); DEFFIELD(ad_kdcissued_3, krb5_ad_kdcissued, elements, 3, auth_data_ptr); static const struct atype_info *ad_kdcissued_fields[] = { &k5_atype_ad_kdcissued_0, &k5_atype_ad_kdcissued_1, &k5_atype_ad_kdcissued_2, &k5_atype_ad_kdcissued_3 }; DEFSEQTYPE(ad_kdc_issued, krb5_ad_kdcissued, ad_kdcissued_fields); DEFCTAGGEDTYPE(princ_plus_realm_0, 0, principal_data); DEFCTAGGEDTYPE(princ_plus_realm_1, 1, realm_of_principal_data); static const struct atype_info *princ_plus_realm_fields[] = { &k5_atype_princ_plus_realm_0, &k5_atype_princ_plus_realm_1 }; DEFSEQTYPE(princ_plus_realm_data, krb5_principal_data, princ_plus_realm_fields); DEFPTRTYPE(princ_plus_realm, princ_plus_realm_data); DEFNULLTERMSEQOFTYPE(seqof_princ_plus_realm, princ_plus_realm); DEFPTRTYPE(ptr_seqof_princ_plus_realm, seqof_princ_plus_realm); DEFOPTIONALEMPTYTYPE(opt_ptr_seqof_princ_plus_realm, ptr_seqof_princ_plus_realm); /* First context tag is 1, not 0. */ DEFFIELD(iakerb_header_1, krb5_iakerb_header, target_realm, 1, utf8_data); DEFFIELD(iakerb_header_2, krb5_iakerb_header, cookie, 2, opt_ostring_data_ptr); static const struct atype_info *iakerb_header_fields[] = { &k5_atype_iakerb_header_1, &k5_atype_iakerb_header_2 }; DEFSEQTYPE(iakerb_header, krb5_iakerb_header, iakerb_header_fields); /* First context tag is 1, not 0. */ DEFFIELD(iakerb_finished_0, krb5_iakerb_finished, checksum, 1, checksum); static const struct atype_info *iakerb_finished_fields[] = { &k5_atype_iakerb_finished_0 }; DEFSEQTYPE(iakerb_finished, krb5_iakerb_finished, iakerb_finished_fields); /* Exported complete encoders -- these produce a krb5_data with the encoding in the correct byte order. */ MAKE_ENCODER(encode_krb5_authenticator, authenticator); MAKE_DECODER(decode_krb5_authenticator, authenticator); MAKE_ENCODER(encode_krb5_ticket, ticket); MAKE_DECODER(decode_krb5_ticket, ticket); MAKE_ENCODER(encode_krb5_encryption_key, encryption_key); MAKE_DECODER(decode_krb5_encryption_key, encryption_key); MAKE_ENCODER(encode_krb5_enc_tkt_part, enc_tkt_part); MAKE_DECODER(decode_krb5_enc_tkt_part, enc_tkt_part); krb5_error_code KRB5_CALLCONV krb5_decode_ticket(const krb5_data *code, krb5_ticket **repptr) { return decode_krb5_ticket(code, repptr); } /* * For backwards compatibility, we encode both EncASRepPart and EncTGSRepPart * with application tag 26. On decode, we accept either app tag and set the * msg_type field of the resulting structure. This could be simplified and * pushed up into libkrb5. */ MAKE_ENCODER(encode_krb5_enc_kdc_rep_part, enc_tgs_rep_part); krb5_error_code decode_krb5_enc_kdc_rep_part(const krb5_data *code, krb5_enc_kdc_rep_part **rep_out) { krb5_error_code ret; krb5_enc_kdc_rep_part *rep; void *rep_ptr; krb5_msgtype msg_type = KRB5_TGS_REP; *rep_out = NULL; ret = k5_asn1_full_decode(code, &k5_atype_enc_tgs_rep_part, &rep_ptr); if (ret == ASN1_BAD_ID) { msg_type = KRB5_AS_REP; ret = k5_asn1_full_decode(code, &k5_atype_enc_as_rep_part, &rep_ptr); } if (ret) return ret; rep = rep_ptr; rep->msg_type = msg_type; *rep_out = rep; return 0; } MAKE_ENCODER(encode_krb5_as_rep, as_rep); MAKE_DECODER(decode_krb5_as_rep, as_rep); MAKE_ENCODER(encode_krb5_tgs_rep, tgs_rep); MAKE_DECODER(decode_krb5_tgs_rep, tgs_rep); MAKE_ENCODER(encode_krb5_ap_req, ap_req); MAKE_DECODER(decode_krb5_ap_req, ap_req); MAKE_ENCODER(encode_krb5_ap_rep, ap_rep); MAKE_DECODER(decode_krb5_ap_rep, ap_rep); MAKE_ENCODER(encode_krb5_ap_rep_enc_part, ap_rep_enc_part); MAKE_DECODER(decode_krb5_ap_rep_enc_part, ap_rep_enc_part); MAKE_ENCODER(encode_krb5_as_req, as_req_encode); MAKE_DECODER(decode_krb5_as_req, as_req); MAKE_ENCODER(encode_krb5_tgs_req, tgs_req_encode); MAKE_DECODER(decode_krb5_tgs_req, tgs_req); MAKE_ENCODER(encode_krb5_kdc_req_body, kdc_req_body); MAKE_DECODER(decode_krb5_kdc_req_body, kdc_req_body); MAKE_ENCODER(encode_krb5_safe, safe); MAKE_DECODER(decode_krb5_safe, safe); /* encode_krb5_safe_with_body takes a saved KRB-SAFE-BODY encoding to avoid * mismatches from re-encoding if the sender isn't quite DER-compliant. */ MAKE_ENCODER(encode_krb5_safe_with_body, safe_with_body); /* * decode_krb5_safe_with_body fully decodes a KRB-SAFE, but also returns * the KRB-SAFE-BODY encoding. This interface was designed for an earlier * generation of decoder and should probably be re-thought. */ krb5_error_code decode_krb5_safe_with_body(const krb5_data *code, krb5_safe **rep_out, krb5_data **body_out) { krb5_error_code ret; void *swb_ptr, *safe_ptr; struct krb5_safe_with_body *swb; krb5_safe *safe; ret = k5_asn1_full_decode(code, &k5_atype_safe_with_body, &swb_ptr); if (ret) return ret; swb = swb_ptr; ret = k5_asn1_full_decode(swb->body, &k5_atype_safe_body, &safe_ptr); if (ret) { krb5_free_safe(NULL, swb->safe); krb5_free_data(NULL, swb->body); free(swb); return ret; } safe = safe_ptr; safe->checksum = swb->safe->checksum; free(swb->safe); *rep_out = safe; *body_out = swb->body; free(swb); return 0; } MAKE_ENCODER(encode_krb5_priv, priv); MAKE_DECODER(decode_krb5_priv, priv); MAKE_ENCODER(encode_krb5_enc_priv_part, priv_enc_part); MAKE_DECODER(decode_krb5_enc_priv_part, priv_enc_part); MAKE_ENCODER(encode_krb5_checksum, checksum); MAKE_DECODER(decode_krb5_checksum, checksum); MAKE_ENCODER(encode_krb5_cred, krb5_cred); MAKE_DECODER(decode_krb5_cred, krb5_cred); MAKE_ENCODER(encode_krb5_enc_cred_part, enc_cred_part); MAKE_DECODER(decode_krb5_enc_cred_part, enc_cred_part); MAKE_ENCODER(encode_krb5_error, krb5_error); MAKE_DECODER(decode_krb5_error, krb5_error); MAKE_ENCODER(encode_krb5_authdata, auth_data); MAKE_DECODER(decode_krb5_authdata, auth_data); MAKE_ENCODER(encode_krb5_etype_info, etype_info); MAKE_DECODER(decode_krb5_etype_info, etype_info); MAKE_ENCODER(encode_krb5_etype_info2, etype_info2); MAKE_DECODER(decode_krb5_etype_info2, etype_info2); MAKE_ENCODER(encode_krb5_enc_data, encrypted_data); MAKE_DECODER(decode_krb5_enc_data, encrypted_data); MAKE_ENCODER(encode_krb5_pa_enc_ts, pa_enc_ts); MAKE_DECODER(decode_krb5_pa_enc_ts, pa_enc_ts); MAKE_ENCODER(encode_krb5_padata_sequence, seqof_pa_data); MAKE_DECODER(decode_krb5_padata_sequence, seqof_pa_data); /* sam preauth additions */ MAKE_ENCODER(encode_krb5_sam_challenge_2, sam_challenge_2); MAKE_DECODER(decode_krb5_sam_challenge_2, sam_challenge_2); MAKE_ENCODER(encode_krb5_sam_challenge_2_body, sam_challenge_2_body); MAKE_DECODER(decode_krb5_sam_challenge_2_body, sam_challenge_2_body); MAKE_ENCODER(encode_krb5_enc_sam_response_enc_2, enc_sam_response_enc_2); MAKE_DECODER(decode_krb5_enc_sam_response_enc_2, enc_sam_response_enc_2); MAKE_ENCODER(encode_krb5_sam_response_2, sam_response_2); MAKE_DECODER(decode_krb5_sam_response_2, sam_response_2); /* setpw_req has an odd decoder interface which should probably be * normalized. */ MAKE_ENCODER(encode_krb5_setpw_req, setpw_req); krb5_error_code decode_krb5_setpw_req(const krb5_data *code, krb5_data **password_out, krb5_principal *target_out) { krb5_error_code ret; void *req_ptr; struct krb5_setpw_req *req; krb5_data *data; *password_out = NULL; *target_out = NULL; data = malloc(sizeof(*data)); if (data == NULL) return ENOMEM; ret = k5_asn1_full_decode(code, &k5_atype_setpw_req, &req_ptr); if (ret) { free(data); return ret; } req = req_ptr; *data = req->password; *password_out = data; *target_out = req->target; return 0; } MAKE_ENCODER(encode_krb5_pa_for_user, pa_for_user); MAKE_DECODER(decode_krb5_pa_for_user, pa_for_user); MAKE_ENCODER(encode_krb5_s4u_userid, s4u_userid); MAKE_ENCODER(encode_krb5_pa_s4u_x509_user, pa_s4u_x509_user); MAKE_DECODER(decode_krb5_pa_s4u_x509_user, pa_s4u_x509_user); MAKE_ENCODER(encode_krb5_pa_pac_req, pa_pac_req); MAKE_DECODER(decode_krb5_pa_pac_req, pa_pac_req); MAKE_ENCODER(encode_krb5_etype_list, etype_list); MAKE_DECODER(decode_krb5_etype_list, etype_list); MAKE_ENCODER(encode_krb5_pa_fx_fast_request, pa_fx_fast_request); MAKE_DECODER(decode_krb5_pa_fx_fast_request, pa_fx_fast_request); MAKE_ENCODER(encode_krb5_fast_req, fast_req); MAKE_DECODER(decode_krb5_fast_req, fast_req); MAKE_ENCODER(encode_krb5_pa_fx_fast_reply, pa_fx_fast_reply); MAKE_DECODER(decode_krb5_pa_fx_fast_reply, pa_fx_fast_reply); MAKE_ENCODER(encode_krb5_fast_response, fast_response); MAKE_DECODER(decode_krb5_fast_response, fast_response); MAKE_ENCODER(encode_krb5_ad_kdcissued, ad_kdc_issued); MAKE_DECODER(decode_krb5_ad_kdcissued, ad_kdc_issued); MAKE_ENCODER(encode_krb5_iakerb_header, iakerb_header); MAKE_DECODER(decode_krb5_iakerb_header, iakerb_header); MAKE_ENCODER(encode_krb5_iakerb_finished, iakerb_finished); MAKE_DECODER(decode_krb5_iakerb_finished, iakerb_finished); krb5_error_code KRB5_CALLCONV krb5int_get_authdata_containee_types(krb5_context context, const krb5_authdata *authdata, unsigned int *num_out, krb5_authdatatype **types_out) { krb5_error_code ret; struct authdata_types *atypes; void *atypes_ptr; krb5_data d = make_data(authdata->contents, authdata->length); ret = k5_asn1_full_decode(&d, &k5_atype_authdata_types, &atypes_ptr); if (ret) return ret; atypes = atypes_ptr; *num_out = atypes->ntypes; *types_out = atypes->types; free(atypes); return 0; } /* RFC 3280. No context tags. */ DEFOFFSETTYPE(algid_0, krb5_algorithm_identifier, algorithm, oid_data); DEFOFFSETTYPE(algid_1, krb5_algorithm_identifier, parameters, opt_der_data); static const struct atype_info *algorithm_identifier_fields[] = { &k5_atype_algid_0, &k5_atype_algid_1 }; DEFSEQTYPE(algorithm_identifier, krb5_algorithm_identifier, algorithm_identifier_fields); DEFPTRTYPE(ptr_algorithm_identifier, algorithm_identifier); DEFOPTIONALZEROTYPE(opt_ptr_algorithm_identifier, ptr_algorithm_identifier); DEFNULLTERMSEQOFTYPE(seqof_algorithm_identifier, ptr_algorithm_identifier); DEFPTRTYPE(ptr_seqof_algorithm_identifier, seqof_algorithm_identifier); DEFOPTIONALEMPTYTYPE(opt_ptr_seqof_algorithm_identifier, ptr_seqof_algorithm_identifier); /* * PKINIT */ #ifndef DISABLE_PKINIT DEFCTAGGEDTYPE(kdf_alg_id_0, 0, oid_data); static const struct atype_info *kdf_alg_id_fields[] = { &k5_atype_kdf_alg_id_0 }; DEFSEQTYPE(kdf_alg_id, krb5_data, kdf_alg_id_fields); DEFPTRTYPE(ptr_kdf_alg_id, kdf_alg_id); DEFNONEMPTYNULLTERMSEQOFTYPE(supported_kdfs, ptr_kdf_alg_id); DEFPTRTYPE(ptr_supported_kdfs, supported_kdfs); DEFOPTIONALZEROTYPE(opt_ptr_kdf_alg_id, ptr_kdf_alg_id); DEFOPTIONALZEROTYPE(opt_ptr_supported_kdfs, ptr_supported_kdfs); /* KRB5PrincipalName from RFC 4556 (*not* PrincipalName from RFC 4120) */ DEFCTAGGEDTYPE(pkinit_princ_0, 0, realm_of_principal_data); DEFCTAGGEDTYPE(pkinit_princ_1, 1, principal_data); static const struct atype_info *pkinit_krb5_principal_name_fields[] = { &k5_atype_pkinit_princ_0, &k5_atype_pkinit_princ_1 }; DEFSEQTYPE(pkinit_krb5_principal_name_data, krb5_principal_data, pkinit_krb5_principal_name_fields); DEFPTRTYPE(pkinit_krb5_principal_name, pkinit_krb5_principal_name_data); /* SP80056A OtherInfo, for pkinit agility. No context tag on first field. */ DEFTAGGEDTYPE(pkinit_krb5_principal_name_wrapped, UNIVERSAL, PRIMITIVE, ASN1_OCTETSTRING, 0, pkinit_krb5_principal_name); DEFOFFSETTYPE(oinfo_notag, krb5_sp80056a_other_info, algorithm_identifier, algorithm_identifier); DEFFIELD(oinfo_0, krb5_sp80056a_other_info, party_u_info, 0, pkinit_krb5_principal_name_wrapped); DEFFIELD(oinfo_1, krb5_sp80056a_other_info, party_v_info, 1, pkinit_krb5_principal_name_wrapped); DEFFIELD(oinfo_2, krb5_sp80056a_other_info, supp_pub_info, 2, ostring_data); static const struct atype_info *sp80056a_other_info_fields[] = { &k5_atype_oinfo_notag, &k5_atype_oinfo_0, &k5_atype_oinfo_1, &k5_atype_oinfo_2 }; DEFSEQTYPE(sp80056a_other_info, krb5_sp80056a_other_info, sp80056a_other_info_fields); /* For PkinitSuppPubInfo, for pkinit agility */ DEFFIELD(supp_pub_0, krb5_pkinit_supp_pub_info, enctype, 0, int32); DEFFIELD(supp_pub_1, krb5_pkinit_supp_pub_info, as_req, 1, ostring_data); DEFFIELD(supp_pub_2, krb5_pkinit_supp_pub_info, pk_as_rep, 2, ostring_data); static const struct atype_info *pkinit_supp_pub_info_fields[] = { &k5_atype_supp_pub_0, &k5_atype_supp_pub_1, &k5_atype_supp_pub_2 }; DEFSEQTYPE(pkinit_supp_pub_info, krb5_pkinit_supp_pub_info, pkinit_supp_pub_info_fields); MAKE_ENCODER(encode_krb5_pkinit_supp_pub_info, pkinit_supp_pub_info); MAKE_ENCODER(encode_krb5_sp80056a_other_info, sp80056a_other_info); DEFFIELD(pachecksum2_0, krb5_pachecksum2, checksum, 0, ostring_data); DEFFIELD(pachecksum2_1, krb5_pachecksum2, algorithmIdentifier, 1, algorithm_identifier); static const struct atype_info *pachecksum2_fields[] = { &k5_atype_pachecksum2_0, &k5_atype_pachecksum2_1 }; DEFSEQTYPE(pachecksum2, krb5_pachecksum2, pachecksum2_fields); DEFPTRTYPE(pachecksum2_ptr, pachecksum2); DEFOPTIONALZEROTYPE(opt_pachecksum2_ptr, pachecksum2_ptr); DEFFIELD(pk_authenticator_0, krb5_pk_authenticator, cusec, 0, int32); DEFFIELD(pk_authenticator_1, krb5_pk_authenticator, ctime, 1, kerberos_time); DEFFIELD(pk_authenticator_2, krb5_pk_authenticator, nonce, 2, int32); DEFFIELD(pk_authenticator_3, krb5_pk_authenticator, paChecksum, 3, ostring_data); DEFFIELD(pk_authenticator_4, krb5_pk_authenticator, freshnessToken, 4, opt_ostring_data_ptr); DEFFIELD(pk_authenticator_5, krb5_pk_authenticator, paChecksum2, 5, opt_pachecksum2_ptr); static const struct atype_info *pk_authenticator_fields[] = { &k5_atype_pk_authenticator_0, &k5_atype_pk_authenticator_1, &k5_atype_pk_authenticator_2, &k5_atype_pk_authenticator_3, &k5_atype_pk_authenticator_4, &k5_atype_pk_authenticator_5 }; DEFSEQTYPE(pk_authenticator, krb5_pk_authenticator, pk_authenticator_fields); DEFCOUNTEDSTRINGTYPE(s_bitstring, char *, unsigned int, k5_asn1_encode_bitstring, k5_asn1_decode_bitstring, ASN1_BITSTRING); DEFCOUNTEDTYPE(bitstring_data, krb5_data, data, length, s_bitstring); DEFFIELD(auth_pack_0, krb5_auth_pack, pkAuthenticator, 0, pk_authenticator); DEFFIELD(auth_pack_1, krb5_auth_pack, clientPublicValue, 1, opt_der_data); DEFFIELD(auth_pack_2, krb5_auth_pack, supportedCMSTypes, 2, opt_ptr_seqof_algorithm_identifier); DEFFIELD(auth_pack_3, krb5_auth_pack, clientDHNonce, 3, opt_ostring_data); DEFFIELD(auth_pack_4, krb5_auth_pack, supportedKDFs, 4, opt_ptr_supported_kdfs); static const struct atype_info *auth_pack_fields[] = { &k5_atype_auth_pack_0, &k5_atype_auth_pack_1, &k5_atype_auth_pack_2, &k5_atype_auth_pack_3, &k5_atype_auth_pack_4 }; DEFSEQTYPE(auth_pack, krb5_auth_pack, auth_pack_fields); DEFFIELD_IMPLICIT(extprinc_0, krb5_external_principal_identifier, subjectName, 0, opt_ostring_data); DEFFIELD_IMPLICIT(extprinc_1, krb5_external_principal_identifier, issuerAndSerialNumber, 1, opt_ostring_data); DEFFIELD_IMPLICIT(extprinc_2, krb5_external_principal_identifier, subjectKeyIdentifier, 2, opt_ostring_data); static const struct atype_info *external_principal_identifier_fields[] = { &k5_atype_extprinc_0, &k5_atype_extprinc_1, &k5_atype_extprinc_2 }; DEFSEQTYPE(external_principal_identifier, krb5_external_principal_identifier, external_principal_identifier_fields); DEFPTRTYPE(external_principal_identifier_ptr, external_principal_identifier); DEFNULLTERMSEQOFTYPE(seqof_external_principal_identifier, external_principal_identifier_ptr); DEFPTRTYPE(ptr_seqof_external_principal_identifier, seqof_external_principal_identifier); DEFOPTIONALZEROTYPE(opt_ptr_seqof_external_principal_identifier, ptr_seqof_external_principal_identifier); DEFFIELD_IMPLICIT(pa_pk_as_req_0, krb5_pa_pk_as_req, signedAuthPack, 0, ostring_data); DEFFIELD(pa_pk_as_req_1, krb5_pa_pk_as_req, trustedCertifiers, 1, opt_ptr_seqof_external_principal_identifier); DEFFIELD_IMPLICIT(pa_pk_as_req_2, krb5_pa_pk_as_req, kdcPkId, 2, opt_ostring_data); static const struct atype_info *pa_pk_as_req_fields[] = { &k5_atype_pa_pk_as_req_0, &k5_atype_pa_pk_as_req_1, &k5_atype_pa_pk_as_req_2 }; DEFSEQTYPE(pa_pk_as_req, krb5_pa_pk_as_req, pa_pk_as_req_fields); DEFFIELD_IMPLICIT(dh_rep_info_0, krb5_dh_rep_info, dhSignedData, 0, ostring_data); DEFFIELD(dh_rep_info_1, krb5_dh_rep_info, serverDHNonce, 1, opt_ostring_data); DEFFIELD(dh_rep_info_2, krb5_dh_rep_info, kdfID, 2, opt_ptr_kdf_alg_id); static const struct atype_info *dh_rep_info_fields[] = { &k5_atype_dh_rep_info_0, &k5_atype_dh_rep_info_1, &k5_atype_dh_rep_info_2 }; DEFSEQTYPE(dh_rep_info, krb5_dh_rep_info, dh_rep_info_fields); DEFFIELD(dh_key_0, krb5_kdc_dh_key_info, subjectPublicKey, 0, bitstring_data); DEFFIELD(dh_key_1, krb5_kdc_dh_key_info, nonce, 1, int32); DEFFIELD(dh_key_2, krb5_kdc_dh_key_info, dhKeyExpiration, 2, opt_kerberos_time); static const struct atype_info *kdc_dh_key_info_fields[] = { &k5_atype_dh_key_0, &k5_atype_dh_key_1, &k5_atype_dh_key_2 }; DEFSEQTYPE(kdc_dh_key_info, krb5_kdc_dh_key_info, kdc_dh_key_info_fields); DEFFIELD(reply_key_pack_0, krb5_reply_key_pack, replyKey, 0, encryption_key); DEFFIELD(reply_key_pack_1, krb5_reply_key_pack, asChecksum, 1, checksum); static const struct atype_info *reply_key_pack_fields[] = { &k5_atype_reply_key_pack_0, &k5_atype_reply_key_pack_1 }; DEFSEQTYPE(reply_key_pack, krb5_reply_key_pack, reply_key_pack_fields); DEFCTAGGEDTYPE(pa_pk_as_rep_0, 0, dh_rep_info); DEFCTAGGEDTYPE_IMPLICIT(pa_pk_as_rep_1, 1, ostring_data); static const struct atype_info *pa_pk_as_rep_alternatives[] = { &k5_atype_pa_pk_as_rep_0, &k5_atype_pa_pk_as_rep_1 }; DEFCHOICETYPE(pa_pk_as_rep_choice, union krb5_pa_pk_as_rep_choices, enum krb5_pa_pk_as_rep_selection, pa_pk_as_rep_alternatives); DEFCOUNTEDTYPE_SIGNED(pa_pk_as_rep, krb5_pa_pk_as_rep, u, choice, pa_pk_as_rep_choice); MAKE_ENCODER(encode_krb5_pa_pk_as_req, pa_pk_as_req); MAKE_DECODER(decode_krb5_pa_pk_as_req, pa_pk_as_req); MAKE_ENCODER(encode_krb5_pa_pk_as_rep, pa_pk_as_rep); MAKE_DECODER(decode_krb5_pa_pk_as_rep, pa_pk_as_rep); MAKE_ENCODER(encode_krb5_auth_pack, auth_pack); MAKE_DECODER(decode_krb5_auth_pack, auth_pack); MAKE_ENCODER(encode_krb5_kdc_dh_key_info, kdc_dh_key_info); MAKE_DECODER(decode_krb5_kdc_dh_key_info, kdc_dh_key_info); MAKE_ENCODER(encode_krb5_reply_key_pack, reply_key_pack); MAKE_DECODER(decode_krb5_reply_key_pack, reply_key_pack); MAKE_ENCODER(encode_krb5_td_trusted_certifiers, seqof_external_principal_identifier); MAKE_DECODER(decode_krb5_td_trusted_certifiers, seqof_external_principal_identifier); MAKE_ENCODER(encode_krb5_td_dh_parameters, seqof_algorithm_identifier); MAKE_DECODER(decode_krb5_td_dh_parameters, seqof_algorithm_identifier); MAKE_DECODER(decode_krb5_principal_name, pkinit_krb5_principal_name_data); #else /* DISABLE_PKINIT */ /* Stubs for exported pkinit encoder functions. */ krb5_error_code encode_krb5_sp80056a_other_info(const krb5_sp80056a_other_info *rep, krb5_data **code) { return EINVAL; } krb5_error_code encode_krb5_pkinit_supp_pub_info(const krb5_pkinit_supp_pub_info *rep, krb5_data **code) { return EINVAL; } #endif /* not DISABLE_PKINIT */ DEFFIELD(typed_data_0, krb5_pa_data, pa_type, 0, int32); DEFCNFIELD(typed_data_1, krb5_pa_data, contents, length, 1, octetstring); static const struct atype_info *typed_data_fields[] = { &k5_atype_typed_data_0, &k5_atype_typed_data_1 }; DEFSEQTYPE(typed_data, krb5_pa_data, typed_data_fields); DEFPTRTYPE(typed_data_ptr, typed_data); DEFNULLTERMSEQOFTYPE(seqof_typed_data, typed_data_ptr); MAKE_ENCODER(encode_krb5_typed_data, seqof_typed_data); MAKE_DECODER(decode_krb5_typed_data, seqof_typed_data); /* Definitions for OTP preauth (RFC 6560) */ DEFFIELD_IMPLICIT(tokinfo_0, krb5_otp_tokeninfo, flags, 0, krb5_flags); DEFFIELD_IMPLICIT(tokinfo_1, krb5_otp_tokeninfo, vendor, 1, opt_utf8_data); DEFFIELD_IMPLICIT(tokinfo_2, krb5_otp_tokeninfo, challenge, 2, opt_ostring_data); DEFFIELD_IMPLICIT(tokinfo_3, krb5_otp_tokeninfo, length, 3, opt_int32_minus1); DEFFIELD_IMPLICIT(tokinfo_4, krb5_otp_tokeninfo, format, 4, opt_int32_minus1); DEFFIELD_IMPLICIT(tokinfo_5, krb5_otp_tokeninfo, token_id, 5, opt_ostring_data); DEFFIELD_IMPLICIT(tokinfo_6, krb5_otp_tokeninfo, alg_id, 6, opt_utf8_data); DEFFIELD_IMPLICIT(tokinfo_7, krb5_otp_tokeninfo, supported_hash_alg, 7, opt_ptr_seqof_algorithm_identifier); DEFFIELD_IMPLICIT(tokinfo_8, krb5_otp_tokeninfo, iteration_count, 8, opt_int32_minus1); static const struct atype_info *otp_tokeninfo_fields[] = { &k5_atype_tokinfo_0, &k5_atype_tokinfo_1, &k5_atype_tokinfo_2, &k5_atype_tokinfo_3, &k5_atype_tokinfo_4, &k5_atype_tokinfo_5, &k5_atype_tokinfo_6, &k5_atype_tokinfo_7, &k5_atype_tokinfo_8 }; DEFSEQTYPE(otp_tokeninfo, krb5_otp_tokeninfo, otp_tokeninfo_fields); MAKE_ENCODER(encode_krb5_otp_tokeninfo, otp_tokeninfo); MAKE_DECODER(decode_krb5_otp_tokeninfo, otp_tokeninfo); DEFPTRTYPE(otp_tokeninfo_ptr, otp_tokeninfo); DEFNONEMPTYNULLTERMSEQOFTYPE(seqof_otp_tokeninfo, otp_tokeninfo_ptr); DEFPTRTYPE(ptr_seqof_otp_tokeninfo, seqof_otp_tokeninfo); DEFFIELD_IMPLICIT(otp_ch_0, krb5_pa_otp_challenge, nonce, 0, ostring_data); DEFFIELD_IMPLICIT(otp_ch_1, krb5_pa_otp_challenge, service, 1, opt_utf8_data); DEFFIELD_IMPLICIT(otp_ch_2, krb5_pa_otp_challenge, tokeninfo, 2, ptr_seqof_otp_tokeninfo); DEFFIELD_IMPLICIT(otp_ch_3, krb5_pa_otp_challenge, salt, 3, opt_gstring_data); DEFFIELD_IMPLICIT(otp_ch_4, krb5_pa_otp_challenge, s2kparams, 4, opt_ostring_data); static const struct atype_info *pa_otp_challenge_fields[] = { &k5_atype_otp_ch_0, &k5_atype_otp_ch_1, &k5_atype_otp_ch_2, &k5_atype_otp_ch_3, &k5_atype_otp_ch_4 }; DEFSEQTYPE(pa_otp_challenge, krb5_pa_otp_challenge, pa_otp_challenge_fields); MAKE_ENCODER(encode_krb5_pa_otp_challenge, pa_otp_challenge); MAKE_DECODER(decode_krb5_pa_otp_challenge, pa_otp_challenge); DEFFIELD_IMPLICIT(otp_req_0, krb5_pa_otp_req, flags, 0, krb5_flags); DEFFIELD_IMPLICIT(otp_req_1, krb5_pa_otp_req, nonce, 1, opt_ostring_data); DEFFIELD_IMPLICIT(otp_req_2, krb5_pa_otp_req, enc_data, 2, encrypted_data); DEFFIELD_IMPLICIT(otp_req_3, krb5_pa_otp_req, hash_alg, 3, opt_ptr_algorithm_identifier); DEFFIELD_IMPLICIT(otp_req_4, krb5_pa_otp_req, iteration_count, 4, opt_int32_minus1); DEFFIELD_IMPLICIT(otp_req_5, krb5_pa_otp_req, otp_value, 5, opt_ostring_data); DEFFIELD_IMPLICIT(otp_req_6, krb5_pa_otp_req, pin, 6, opt_utf8_data); DEFFIELD_IMPLICIT(otp_req_7, krb5_pa_otp_req, challenge, 7, opt_ostring_data); DEFFIELD_IMPLICIT(otp_req_8, krb5_pa_otp_req, time, 8, opt_kerberos_time); DEFFIELD_IMPLICIT(otp_req_9, krb5_pa_otp_req, counter, 9, opt_ostring_data); DEFFIELD_IMPLICIT(otp_req_10, krb5_pa_otp_req, format, 10, opt_int32_minus1); DEFFIELD_IMPLICIT(otp_req_11, krb5_pa_otp_req, token_id, 11, opt_ostring_data); DEFFIELD_IMPLICIT(otp_req_12, krb5_pa_otp_req, alg_id, 12, opt_utf8_data); DEFFIELD_IMPLICIT(otp_req_13, krb5_pa_otp_req, vendor, 13, opt_utf8_data); static const struct atype_info *pa_otp_req_fields[] = { &k5_atype_otp_req_0, &k5_atype_otp_req_1, &k5_atype_otp_req_2, &k5_atype_otp_req_3, &k5_atype_otp_req_4, &k5_atype_otp_req_5, &k5_atype_otp_req_6, &k5_atype_otp_req_7, &k5_atype_otp_req_8, &k5_atype_otp_req_9, &k5_atype_otp_req_10, &k5_atype_otp_req_11, &k5_atype_otp_req_12, &k5_atype_otp_req_13 }; DEFSEQTYPE(pa_otp_req, krb5_pa_otp_req, pa_otp_req_fields); MAKE_ENCODER(encode_krb5_pa_otp_req, pa_otp_req); MAKE_DECODER(decode_krb5_pa_otp_req, pa_otp_req); DEFCTAGGEDTYPE_IMPLICIT(pa_otp_enc_req_0, 0, ostring_data); static const struct atype_info *pa_otp_enc_req_fields[] = { &k5_atype_pa_otp_enc_req_0 }; DEFSEQTYPE(pa_otp_enc_req, krb5_data, pa_otp_enc_req_fields); MAKE_ENCODER(encode_krb5_pa_otp_enc_req, pa_otp_enc_req); MAKE_DECODER(decode_krb5_pa_otp_enc_req, pa_otp_enc_req); DEFFIELD(kkdcp_message_0, krb5_kkdcp_message, kerb_message, 0, ostring_data); DEFFIELD(kkdcp_message_1, krb5_kkdcp_message, target_domain, 1, opt_gstring_data); DEFFIELD(kkdcp_message_2, krb5_kkdcp_message, dclocator_hint, 2, opt_int32); static const struct atype_info *kkdcp_message_fields[] = { &k5_atype_kkdcp_message_0, &k5_atype_kkdcp_message_1, &k5_atype_kkdcp_message_2 }; DEFSEQTYPE(kkdcp_message, krb5_kkdcp_message, kkdcp_message_fields); MAKE_ENCODER(encode_krb5_kkdcp_message, kkdcp_message); MAKE_DECODER(decode_krb5_kkdcp_message, kkdcp_message); DEFFIELD(vmac_0, krb5_verifier_mac, princ, 0, opt_principal); DEFFIELD(vmac_1, krb5_verifier_mac, kvno, 1, opt_kvno); DEFFIELD(vmac_2, krb5_verifier_mac, enctype, 2, opt_int32); DEFFIELD(vmac_3, krb5_verifier_mac, checksum, 3, checksum); static const struct atype_info *vmac_fields[] = { &k5_atype_vmac_0, &k5_atype_vmac_1, &k5_atype_vmac_2, &k5_atype_vmac_3 }; DEFSEQTYPE(vmac, krb5_verifier_mac, vmac_fields); DEFPTRTYPE(vmac_ptr, vmac); DEFOPTIONALZEROTYPE(opt_vmac_ptr, vmac_ptr); DEFNONEMPTYNULLTERMSEQOFTYPE(vmacs, vmac_ptr); DEFPTRTYPE(vmacs_ptr, vmacs); DEFOPTIONALEMPTYTYPE(opt_vmacs_ptr, vmacs_ptr); DEFFIELD(cammac_0, krb5_cammac, elements, 0, auth_data_ptr); DEFFIELD(cammac_1, krb5_cammac, kdc_verifier, 1, opt_vmac_ptr); DEFFIELD(cammac_2, krb5_cammac, svc_verifier, 2, opt_vmac_ptr); DEFFIELD(cammac_3, krb5_cammac, other_verifiers, 3, opt_vmacs_ptr); static const struct atype_info *cammac_fields[] = { &k5_atype_cammac_0, &k5_atype_cammac_1, &k5_atype_cammac_2, &k5_atype_cammac_3 }; DEFSEQTYPE(cammac, krb5_cammac, cammac_fields); MAKE_ENCODER(encode_krb5_cammac, cammac); MAKE_DECODER(decode_krb5_cammac, cammac); MAKE_ENCODER(encode_utf8_strings, seqof_utf8_data); MAKE_DECODER(decode_utf8_strings, seqof_utf8_data); /* * SecureCookie ::= SEQUENCE { * time INTEGER, * data SEQUENCE OF PA-DATA, * ... * } */ DEFINTTYPE(inttime, time_t); DEFOFFSETTYPE(secure_cookie_0, krb5_secure_cookie, time, inttime); DEFOFFSETTYPE(secure_cookie_1, krb5_secure_cookie, data, ptr_seqof_pa_data); static const struct atype_info *secure_cookie_fields[] = { &k5_atype_secure_cookie_0, &k5_atype_secure_cookie_1 }; DEFSEQTYPE(secure_cookie, krb5_secure_cookie, secure_cookie_fields); MAKE_ENCODER(encode_krb5_secure_cookie, secure_cookie); MAKE_DECODER(decode_krb5_secure_cookie, secure_cookie); /* * -- based on MS-KILE and MS-SFU * PAC-OPTIONS-FLAGS ::= BIT STRING { * claims(0), * branch-aware(1), * forward-to-full-dc(2), * resource-based-constrained-delegation(3) * } * * PA-PAC-OPTIONS ::= SEQUENCE { * flags [0] PAC-OPTIONS-FLAGS * } */ DEFFIELD(pa_pac_options_0, krb5_pa_pac_options, options, 0, krb5_flags); static const struct atype_info *pa_pac_options_fields[] = { &k5_atype_pa_pac_options_0 }; DEFSEQTYPE(pa_pac_options, krb5_pa_pac_options, pa_pac_options_fields); MAKE_ENCODER(encode_krb5_pa_pac_options, pa_pac_options); MAKE_DECODER(decode_krb5_pa_pac_options, pa_pac_options); DEFFIELD(spake_factor_0, krb5_spake_factor, type, 0, int32); DEFFIELD(spake_factor_1, krb5_spake_factor, data, 1, opt_ostring_data_ptr); static const struct atype_info *spake_factor_fields[] = { &k5_atype_spake_factor_0, &k5_atype_spake_factor_1 }; DEFSEQTYPE(spake_factor, krb5_spake_factor, spake_factor_fields); DEFPTRTYPE(spake_factor_ptr, spake_factor); DEFNULLTERMSEQOFTYPE(seqof_spake_factor, spake_factor_ptr); DEFPTRTYPE(ptr_seqof_spake_factor, seqof_spake_factor); MAKE_ENCODER(encode_krb5_spake_factor, spake_factor); MAKE_DECODER(decode_krb5_spake_factor, spake_factor); DEFCNFIELD(spake_support_0, krb5_spake_support, groups, ngroups, 0, cseqof_int32); static const struct atype_info *spake_support_fields[] = { &k5_atype_spake_support_0 }; DEFSEQTYPE(spake_support, krb5_spake_support, spake_support_fields); DEFFIELD(spake_challenge_0, krb5_spake_challenge, group, 0, int32); DEFFIELD(spake_challenge_1, krb5_spake_challenge, pubkey, 1, ostring_data); DEFFIELD(spake_challenge_2, krb5_spake_challenge, factors, 2, ptr_seqof_spake_factor); static const struct atype_info *spake_challenge_fields[] = { &k5_atype_spake_challenge_0, &k5_atype_spake_challenge_1, &k5_atype_spake_challenge_2 }; DEFSEQTYPE(spake_challenge, krb5_spake_challenge, spake_challenge_fields); DEFFIELD(spake_response_0, krb5_spake_response, pubkey, 0, ostring_data); DEFFIELD(spake_response_1, krb5_spake_response, factor, 1, encrypted_data); static const struct atype_info *spake_response_fields[] = { &k5_atype_spake_response_0, &k5_atype_spake_response_1, }; DEFSEQTYPE(spake_response, krb5_spake_response, spake_response_fields); DEFCTAGGEDTYPE(pa_spake_0, 0, spake_support); DEFCTAGGEDTYPE(pa_spake_1, 1, spake_challenge); DEFCTAGGEDTYPE(pa_spake_2, 2, spake_response); DEFCTAGGEDTYPE(pa_spake_3, 3, encrypted_data); static const struct atype_info *pa_spake_alternatives[] = { &k5_atype_pa_spake_0, &k5_atype_pa_spake_1, &k5_atype_pa_spake_2, &k5_atype_pa_spake_3 }; DEFCHOICETYPE(pa_spake_choice, union krb5_spake_message_choices, enum krb5_spake_msgtype, pa_spake_alternatives); DEFCOUNTEDTYPE_SIGNED(pa_spake, krb5_pa_spake, u, choice, pa_spake_choice); MAKE_ENCODER(encode_krb5_pa_spake, pa_spake); MAKE_DECODER(decode_krb5_pa_spake, pa_spake); krb5-1.22.1/src/lib/krb5/asn.1/README.asn10000664000175000017500000005661715051422640017221 0ustar ghudsonghudsonThese notes attempt to explain how to use the ASN.1 infrastructure to add new ASN.1 types. ASN.1 is complicated and easy to get wrong, so it is best to verify your results against another tool (such as asn1c) if at all possible. These notes are up to date as of 2012-02-13. If you are trying to debug a problem that shows up in the ASN.1 encoder or decoder, skip to the last section. General ------- For the moment, a developer must hand-translate the ASN.1 module into macro invocations that generate data structures used by the encoder and decoder. Ideally we would have a tool to compile an ASN.1 module (and probably some additional information about C identifier mappings) and generate the macro invocations. Currently the ASN.1 infrastructure is not visible to applications or plugins. For plugin modules shipped as part of the krb5 tree, the types can be added to asn1_k_encode.c and exported from libkrb5. Plugin modules built separately from the krb5 tree must use another tool (such as asn1c) for now if they need to do ASN.1 encoding or decoding. Tags ---- Before you start writing macro invocations, it is important to understand a little bit about ASN.1 tags. You will most commonly see tag notation in a sequence definition, like: TypeName ::= SEQUENCE { field-name [0] IMPLICIT OCTET STRING OPTIONAL } Contrary to intuition, the tag notation "[0] IMPLICIT" is not a property of the sequence field; instead, it specifies a type that wraps the type to the right (OCTET STRING). The right way to think about the above definition is: TypeName is defined as a sequence type which has an optional field named field-name whose type is a tagged type the tag's class is context-specific (by default) the tag's number is 0 it is an implicit tag the tagged type wraps OCTET STRING The other case you are likely to see tag notation is something like: AS-REQ ::= [APPLICATION 10] KDC-REQ This example defines AS-REQ to be a tagged type whose class is application, whose tag number is 10, and whose base type is KDC-REQ. The tag may be implicit or explicit depending on the module's tag environment, which we will get to in a moment. Tags can have one of four classes: universal, application, private, and context-specific. Universal tags are used for built-in ASN.1 types. Application and context-specific tags are the most common to see in ASN.1 modules; private is rarely used. If no tag class is specified, the default is context-specific. Tags can be explicit or implicit, and the distinction is important to the wire encoding. If a tag's closing bracket is followed by the word IMPLICIT or EXPLICIT, then it is clear which kind of tag it is, but usually there will be no such annotation. If not, the default depends on the header of the ASN.1 module. Look at the top of the module for the word DEFINITIONS. It may be followed by one of three phrases: * EXPLICIT TAGS -- in this case, tags default to explicit * IMPLICIT TAGS -- in this case, tags default to implicit (usually) * AUTOMATIC TAGS -- tags default to implicit (usually) and are also automatically added to sequence fields (usually) If none of those phrases appear, the default is explicit tags. Even if a module defaults to implicit tags, a tag defaults to explicit if its base type is a choice type or ANY type (or the information object equivalent of an ANY type). If the module's default is AUTOMATIC TAGS, sequence and set fields should have ascending context-specific tags wrapped around the field types, starting from 0, unless one of the fields of the sequence or set is already a tagged type. See ITU X.680 section 24.2 for details, particularly if COMPONENTS OF is used in the sequence definition. Basic types ----------- In our infrastructure, a type descriptor specifies a mapping between an ASN.1 type and a C type. The first step is to ensure that type descriptors are defined for the basic types used by your ASN.1 module, as mapped to the C types used in your structures, in asn1_k_encode.c. If not, you will need to create it. For a BOOLEAN or INTEGER ASN.1 type, you will use one of these macros: DEFBOOLTYPE(descname, ctype) DEFINTTYPE(descname, ctype) DEFUINTTYPE(descname, ctype) where "descname" is an identifier you make up and "ctype" is the integer type of the C object you want to map the ASN.1 value to. For integers, use DEFINTTYPE if the C type is a signed integer type and DEFUINTTYPE if it is an unsigned type. (For booleans, the distinction is unimportant since all integer types can hold the values 0 and 1.) We don't generally define integer mappings for every typedef name of an integer type. For example, we use the type descriptor int32, which maps an ASN.1 INTEGER to an int32_t, for krb5_enctype values. String types are a little more complicated. Our practice is to store strings in a krb5_data structure (rather than a zero-terminated C string), so our infrastructure currently assumes that all strings are represented as "counted types", meaning the C representation is a combination of a pointer and an integer type. So, first you must declare a counted type descriptor (we will describe those in more detail later) with something like: DEFCOUNTEDSTRINGTYPE(generalstring, char *, unsigned int, k5_asn1_encode_bytestring, k5_asn1_decode_bytestring, ASN1_GENERALSTRING); The first parameter is an identifier you make up. The second and third parameters are the C types of the pointer and integer holding the string; for a krb5_data object, those should be the types in the example. The pointer type must be char * or uint8_t *. The fourth and fifth parameters reference primitive encoder and decoder functions; these should almost always be the ones in the example, unless the ASN.1 type is BIT STRING. The sixth parameter is the universal tag number of the ASN.1 type, as defined in krbasn1.h. Once you have defined the counted type, you can define a normal type descriptor to wrap it in a krb5_data structure with something like: DEFCOUNTEDTYPE(gstring_data, krb5_data, data, length, generalstring); Sequences --------- In our infrastructure, we model ASN.1 sequences using an array of normal type descriptors. Each type descriptor is applied in turn to the C object to generate (or consume) an encoding of an ASN.1 value. Of course, each value needs to be stored in a different place within the C object, or they would just overwrite each other. To address this, you must create an offset type wrapper for each sequence field: DEFOFFSETTYPE(descname, structuretype, fieldname, basedesc) where "descname" is an identifier you make up, "structuretype" and "fieldtype" are used to compute the offset and type-check the structure field, and "basedesc" is the type of the ASN.1 object to be stored at that offset. If your C structure contains a pointer to another C object, you will need to first define a pointer wrapper, which is very simple: DEFPTRTYPE(descname, basedesc) Then wrap the defined pointer type in an offset type as described above. Once a pointer descriptor is defined for a base descriptor, it can be reused many times, so pointer descriptors are usually defined right after the types they wrap. When decoding, pointer wrappers cause a pointer to be allocated with a block of memory equal to the size of the C type corresponding to the base type. (For offset types, the corresponding C type is the structure type inside which the offset is computed.) It is okay for several fields of a sequence to reference the same pointer field within a structure, as long as the pointer types all wrap base types with the same corresponding C type. If the sequence field has a context tag attached to its type, you will also need to create a tag wrapper for it: DEFCTAGGEDTYPE(descname, tagnum, basedesc) DEFCTAGGEDTYPE_IMPLICIT(descname, tagnum, basedesc) Use the first macro for explicit context tags and the second for implicit context tags. "tagnum" is the number of the context-specific tag, and "basedesc" is the name you chose for the offset type above. You don't actually need to separately write out DEFOFFSETTYPE and DEFCTAGGEDTYPE for each field. The combination of offset and context tag is so common that we have a macro to combine them: DEFFIELD(descname, structuretype, fieldname, tagnum, basedesc) DEFFIELD_IMPLICIT(descname, structuretype, fieldname, tagnum, basedesc) Once you have defined tag and offset wrappers for each sequence field, combine them together in an array and use the DEFSEQTYPE macro to define the sequence type descriptor: static const struct atype_info *my_sequence_fields[] = { &k5_atype_my_sequence_0, &k5_atype_my_sequence_1, }; DEFSEQTYPE(my_sequence, structuretype, my_sequence_fields) Each field name must by prefixed by "&k5_atype_" to get a pointer to the actual variable used to hold the type descriptor. ASN.1 sequence types may or may not be defined to be extensible, and may group extensions together in blocks which must appear together. Our model does not distinguish these cases. Our decoder treats all sequence types as extensible. Extension blocks must be modeled by making all of the extension fields optional, and the decoder will not enforce that they appear together. If your ASN.1 sequence contains optional fields, keep reading. Optional sequence fields ------------------------ ASN.1 sequence fields can be annotated with OPTIONAL or, less commonly, with DEFAULT VALUE. (Be aware that if DEFAULT VALUE is specified for a sequence field, DER mandates that fields with that value not be encoded within the sequence. Most standards in the Kerberos ecosystem avoid the use of DEFAULT VALUE for this reason.) Although optionality is a property of sequence or set fields, not types, we still model optional sequence fields using type wrappers. Optional type wrappers must only be used as members of a sequence, although they can be nested in offset or pointer wrappers first. The simplest way to represent an optional value in a C structure is with a pointer which takes the value NULL if the field is not present. In this case, you can just use DEFOPTIONALZEROTYPE to wrap the pointer type: DEFPTRTYPE(ptr_basetype, basetype); DEFOPTIONALZEROTYPE(opt_ptr_basetype, ptr_basetype); and then use opt_ptr_basetype in the DEFFIELD invocation for the sequence field. DEFOPTIONALZEROTYPE can also be used for integer types, if it is okay for the value 0 to represent that the corresponding ASN.1 value is omitted. Optional-zero wrappers, like pointer wrappers, are usually defined just after the types they wrap. For null-terminated sequences, you can use a wrapper like this: DEFOPTIONALEMPTYTYPE(opt_seqof_basetype, seqof_basetype) to omit the sequence if it is either NULL or of zero length. A more general way to wrap optional types is: DEFOPTIONALTYPE(descname, predicatefn, initfn, basedesc); where "predicatefn" has the signature "int (*fn)(const void *p)" and is used by the encoder to test whether the ASN.1 value is present in the C object. "initfn" has the signature "void (*fn)(void *p)" and is used by the decoder to initialize the C object field if the corresponding ASN.1 value is omitted in the wire encoding. "initfn" can be NULL, in which case the C object will simply be left alone. All C objects are initialized to zero-filled memory when they are allocated by the decoder. An optional string type, represented in a krb5_data structure, can be wrapped using the nonempty_data function already defined in asn1_k_encode.c, like so: DEFOPTIONALTYPE(opt_ostring_data, nonempty_data, NULL, ostring_data); Sequence-of types ----------------- ASN.1 sequence-of types can be represented as C types in two ways. The simplest is to use an array of pointers terminated in a null pointer. A descriptor for a sequence-of represented this way is defined in three steps: DEFPTRTYPE(ptr_basetype, basetype); DEFNULLTERMSEQOFTYPE(seqof_basetype, ptr_basetype); DEFPTRTYPE(ptr_seqof_basetype, seqof_basetype); If the C type corresponding to basetype is "ctype", then the C type corresponding to ptr_seqof_basetype will be "ctype **". The middle type sort of corresponds to "ctype *", but not exactly, as it describes an object of variable size. You can also use DEFNONEMPTYNULLTERMSEQOFTYPE in the second step. In this case, the encoder will throw an error if the sequence is empty. For historical reasons, the decoder will *not* throw an error if the sequence is empty, so the calling code must check before assuming a first element is present. The other way of representing sequences is through a combination of pointer and count. This pattern is most often used for compactness when the base type is an integer type. A descriptor for a sequence-of represented this way is defined using a counted type descriptor: DEFCOUNTEDSEQOFTYPE(descname, lentype, basedesc) where "lentype" is the C type of the length and "basedesc" is a pointer wrapper for the sequence element type (*not* the element type itself). For example, an array of 32-bit signed integers is defined as: DEFINTTYPE(int32, int32_t); DEFPTRTYPE(int32_ptr, int32); DEFCOUNTEDSEQOFTYPE(cseqof_int32, int32_t, int32_ptr); To use a counted sequence-of type in a sequence, use DEFCOUNTEDTYPE: DEFCOUNTEDTYPE(descname, structuretype, ptrfield, lenfield, cdesc) where "structuretype", "ptrfield", and "lenfield" are used to compute the field offsets and type-check the structure fields, and "cdesc" is the name of the counted type descriptor. The combination of DEFCOUNTEDTYPE and DEFCTAGGEDTYPE can be abbreviated using DEFCNFIELD: DEFCNFIELD(descname, structuretype, ptrfield, lenfield, tagnum, cdesc) Tag wrappers ------------ We've previously covered DEFCTAGGEDTYPE and DEFCTAGGEDTYPE_IMPLICIT, which are used to define context-specific tag wrappers. There are two other macros for creating tag wrappers. The first is: DEFAPPTAGGEDTYPE(descname, tagnum, basedesc) Use this macro to model an "[APPLICATION tagnum]" tag wrapper in an ASN.1 module. There is also a general tag wrapper macro: DEFTAGGEDTYPE(descname, class, construction, tag, implicit, basedesc) where "class" is one of UNIVERSAL, APPLICATION, CONTEXT_SPECIFIC, or PRIVATE, "construction" is one of PRIMITIVE or CONSTRUCTED, "tag" is the tag number, "implicit" is 1 for an implicit tag and 0 for an explicit tag, and "basedesc" is the wrapped type. Note that that primitive vs. constructed is not a concept within the abstract ASN.1 type model, but is instead a concept used in DER. In general, all explicit tags should be constructed (but see the section on "Dirty tricks" below). The construction parameter is ignored for implicit tags. Choice types ------------ ASN.1 CHOICE types are represented in C using a signed integer distinguisher and a union. Modeling a choice type happens in three steps: 1. Define type descriptors for each alternative of the choice, typically using DEFCTAGGEDTYPE to create a tag wrapper for an existing type. There is no need to create offset type wrappers, as union fields always have an offset of 0. For example: DEFCTAGGEDTYPE(my_choice_0, 0, firstbasedesc); DEFCTAGGEDTYPE(my_choice_1, 1, secondbasedesc); 2. Assemble them into an array, similar to how you would for a sequence, and use DEFCHOICETYPE to create a counted type descriptor: static const struct atype_info *my_choice_alternatives[] = { &k5_atype_my_choice_0, &k5_atype_my_choice_1 }; DEFCHOICETYPE(my_choice, union my_choice_choices, enum my_choice_selector, my_choice_alternatives); The second and third parameters to DEFCHOICETYPE are the C types of the union and distinguisher fields. 3. Wrap the counted type descriptor in a type descriptor for the structure containing the distinguisher and union: DEFCOUNTEDTYPE_SIGNED(descname, structuretype, u, choice, my_choice); The third and fourth parameters to DEFCOUNTEDTYPE_SIGNED are the field names of the union and distinguisher fields within structuretype. ASN.1 choice types may be defined to be extensible, or may not be. Our model does not distinguish between the two cases. Our decoder treats all choice types as extensible. Our encoder will throw an error if the distinguisher is not within the range of valid offsets of the alternatives array. Our decoder will set the distinguisher to -1 if the tag of the ASN.1 value is not matched by any of the alternatives, and will leave the union zero-filled in that case. Counted type descriptors ------------------------ Several times in earlier sections we've referred to the notion of "counted type descriptors" without defining what they are. Counted type descriptors live in a separate namespace from normal type descriptors, and specify a mapping between an ASN.1 type and two C objects, one of them having integer type. There are four kinds of counted type descriptors, defined using the following macros: DEFCOUNTEDSTRINGTYPE(descname, ptrtype, lentype, encfn, decfn, tagnum) DEFCOUNTEDDERTYPE(descname, ptrtype, lentype) DEFCOUNTEDSEQOFTYPE(descname, lentype, baseptrdesc) DEFCHOICETYPE(descname, uniontype, distinguishertype, fields) DEFCOUNTEDDERTYPE is described in the "Dirty tricks" section below. The other three kinds of counted types have been covered previously. Counted types are always used by wrapping them in a normal type descriptor with one of these macros: DEFCOUNTEDTYPE(descname, structuretype, datafield, countfield, cdesc) DEFCOUNTEDTYPE_SIGNED(descname, structuretype, datafield, countfield, cdesc) These macros are similar in concept to an offset type, only with two offsets. Use DEFCOUNTEDTYPE if the count field is unsigned, DEFCOUNTEDTYPE_SIGNED if it is signed. Defining encoder and decoder functions -------------------------------------- After you have created a type descriptor for your types, you need to create encoder or decoder functions for the ones you want calling code to be able to process. Do this with one of the following macros: MAKE_ENCODER(funcname, desc) MAKE_DECODER(funcname, desc) MAKE_CODEC(typename, desc) MAKE_ENCODER and MAKE_DECODER allow you to choose function names. MAKE_CODEC defines encoder and decoder functions with the names "encode_typename" and "decode_typename". If you are defining functions for a null-terminated sequence, use the descriptor created with DEFNULLTERMSEQOFTYPE or DEFNONEMPTYNULLTERMSEQOFTYPE, rather than the pointer to it. This is because encoder and decoder functions implicitly traffic in pointers to the C object being encoded or decoded. Encoder and decoder functions must be prototyped separately, either in k5-int.h or in a subsidiary included by it. Encoder functions have the prototype: krb5_error_code encode_typename(const ctype *rep, krb5_data **code_out); where "ctype" is the C type corresponding to desc. Decoder functions have the prototype: krb5_error_code decode_typename(const krb5_data *code, ctype **rep_out); Decoder functions allocate a container for the C type of the object being decoded and return a pointer to it in *rep_out. Writing test cases ------------------ New ASN.1 types in libkrb5 will typically only be accepted with test cases. Our current test framework lives in src/tests/asn.1. Adding new types to this framework involves the following steps: 1. Define an initializer for a sample value of the type in ktest.c, named ktest_make_sample_typename(). Also define a contents-destructor for it, named ktest_empty_typename(). Prototype these functions in ktest.h. 2. Define an equality test for the type in ktest_equal.c. Prototype this in ktest_equal.h. (This step is not necessary if the type has no decoder.) 3. Add a test case to krb5_encode_test.c, following the examples of existing test cases there. Update reference_encode.out and trval_reference.out to contain the output generated by your test case. 4. Add a test case to krb5_decode_test.c, following the examples of existing test cases there, and using the output generated by your encode test. 5. Add a test case to krb5_decode_leak.c, following the examples of existing test cases there. Following these steps will not ensure the correctness of your translation of the ASN.1 module to macro invocations; it only lets us detect unintentional changes to the encodings after they are defined. To ensure that your translations are correct, you should extend tests/asn.1/make-vectors.c and use "make test-vectors" to create vectors using asn1c. Dirty tricks ------------ In rare cases you may want to represent the raw DER encoding of a value in the C structure. If so, you can use DEFCOUNTEDDERTYPE (or more likely, the existing der_data type descriptor). The encoder and decoder will throw errors if the wire encoding doesn't have a valid outermost tag, so be sure to use valid DER encodings in your test cases (see ktest_make_sample_algorithm_identifier for an example). Conversely, the ASN.1 module may define an OCTET STRING wrapper around a DER encoding which you want to represent as the decoded value. (The existing example of this is in PKINIT hash agility, where the PartyUInfo and PartyVInfo fields of OtherInfo are defined as octet strings which contain the DER encodings of KRB5PrincipalName values.) In this case you can use a DEFTAGGEDTYPE wrapper like so: DEFTAGGEDTYPE(descname, UNIVERSAL, PRIMITIVE, ASN1_OCTETSTRING, 0, basedesc) Limitations ----------- We cannot currently encode or decode SET or SET OF types. We cannot model self-referential types (like "MATHSET ::= SET OF MATHSET"). If a sequence uses an optional field that is a choice field (without a context tag wrapper), or an optional field that uses a stored DER encoding (again, without a context tag wrapper), our decoder may assign a value to the choice or stored-DER field when the correct behavior is to skip that field and assign the value to a subsequent field. It should be very rare for ASN.1 modules to use choice or open types this way. Debugging --------- If you are looking at a stack trace with a bunch of ASN.1 encoder or decoder calls at the top, here are some notes that might help with debugging: 1. You may have noticed that the entry point into the encoder is defined by a macro like MAKE_CODEC. Don't worry about this; those macros just define thin wrappers around k5_asn1_full_encode and k5_asn1_full_decode. If you are stepping through code and hit a wrapper function, just enter "step" to get into the actual encoder or decoder function. 2. If you are in the encoder, look for stack frames in encode_sequence(), and print the value of i within those stack frames. You should be able to subtract 1 from those values and match them up with the sequence field offsets in asn1_k_encode.c for the type being encoded. For example, if an as-req is being encoded and the i values (starting with the one closest to encode_krb5_as_req) are 4, 2, and 2, you could match those up as following: * as_req_encode wraps untagged_as_req, whose field at offset 3 is the descriptor for kdc_req_4, which wraps kdc_req_body. * kdc_req_body is a function wrapper around kdc_req_hack, whose field at offset 1 is the descriptor for req_body_1, which wraps opt_principal. * opt_principal wraps principal, which wraps principal_data, whose field at offset 1 is the descriptor for princname_1. * princname_1 is a sequence of general strings represented in the data and length fields of the krb5_principal_data structure. So the problem would likely be in the data components of the client principal in the kdc_req structure. 3. If you are in the decoder, look for stacks frames in decode_sequence(), and again print the values of i. You can match these up just as above, except without subtracting 1 from the i values. krb5-1.22.1/src/lib/krb5/ccache/0000775000175000017500000000000015051422640015747 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/ccache/t_cccol.py0000775000175000017500000001103615051422640017733 0ustar ghudsonghudsonfrom k5test import * realm = K5Realm(create_kdb=False) keyctl = which('keyctl') out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1) test_keyring = (keyctl is not None and 'Unknown credential cache type' not in out) if not test_keyring: skipped('keyring collection tests', 'keyring support not built') # Run the collection test program against each collection-enabled type. realm.run(['./t_cccol', 'DIR:' + os.path.join(realm.testdir, 'cc')]) if test_keyring: def cleanup_keyring(anchor, name): out = realm.run(['keyctl', 'list', anchor]) if ('keyring: ' + name + '\n') in out: keyid = realm.run(['keyctl', 'search', anchor, 'keyring', name]) realm.run(['keyctl', 'unlink', keyid.strip(), anchor]) # Use the test directory as the collection name to avoid colliding # with other build trees. cname = realm.testdir col_ringname = '_krb_' + cname # Remove any keys left behind by previous failed test runs. cleanup_keyring('@s', cname) cleanup_keyring('@s', col_ringname) cleanup_keyring('@u', col_ringname) # Run test program over each subtype, cleaning up as we go. Don't # test the persistent subtype, since it supports only one # collection and might be in actual use. realm.run(['./t_cccol', 'KEYRING:' + cname]) cleanup_keyring('@s', col_ringname) realm.run(['./t_cccol', 'KEYRING:legacy:' + cname]) cleanup_keyring('@s', col_ringname) realm.run(['./t_cccol', 'KEYRING:session:' + cname]) cleanup_keyring('@s', col_ringname) realm.run(['./t_cccol', 'KEYRING:user:' + cname]) cleanup_keyring('@u', col_ringname) realm.run(['./t_cccol', 'KEYRING:process:abcd']) realm.run(['./t_cccol', 'KEYRING:thread:abcd']) realm.stop() # Test cursor semantics using real ccaches. realm = K5Realm(create_host=False) realm.addprinc('alice', password('alice')) realm.addprinc('bob', password('bob')) ccdir = os.path.join(realm.testdir, 'cc') dccname = 'DIR:%s' % ccdir duser = 'DIR::%s/tkt1' % ccdir dalice = 'DIR::%s/tkt2' % ccdir dbob = 'DIR::%s/tkt3' % ccdir dnoent = 'DIR::%s/noent' % ccdir realm.kinit('user', password('user'), flags=['-c', duser]) realm.kinit('alice', password('alice'), flags=['-c', dalice]) realm.kinit('bob', password('bob'), flags=['-c', dbob]) if test_keyring: cleanup_keyring('@s', col_ringname) krccname = 'KEYRING:session:' + cname kruser = '%s:tkt1' % krccname kralice = '%s:tkt2' % krccname krbob = '%s:tkt3' % krccname krnoent = '%s:noent' % krccname realm.kinit('user', password('user'), flags=['-c', kruser]) realm.kinit('alice', password('alice'), flags=['-c', kralice]) realm.kinit('bob', password('bob'), flags=['-c', krbob]) def cursor_test(testname, args, expected): outlines = realm.run(['./t_cccursor'] + args).splitlines() outlines.sort() expected.sort() if outlines != expected: fail('Output not expected for %s\n' % testname + 'Expected output:\n\n' + '\n'.join(expected) + '\n\n' + 'Actual output:\n\n' + '\n'.join(outlines)) mark('FILE cursor') fccname = 'FILE:%s' % realm.ccache cursor_test('file-default', [], [fccname]) cursor_test('file-default2', [realm.ccache], [fccname]) cursor_test('file-default3', [fccname], [fccname]) mark('DIR cursor') cursor_test('dir', [dccname], [duser, dalice, dbob]) cursor_test('dir-subsidiary', [duser], [duser]) cursor_test('dir-nofile', [dnoent], []) if test_keyring: mark('KEYRING cursor') cursor_test('keyring', [krccname], [kruser, kralice, krbob]) cursor_test('keyring-subsidiary', [kruser], [kruser]) cursor_test('keyring-noent', [krnoent], []) mark('MEMORY cursor') mfoo = 'MEMORY:foo' mbar = 'MEMORY:bar' cursor_test('filemem', [fccname, mfoo], [fccname]) cursor_test('dirmem', [dccname, mfoo], [duser, dalice, dbob]) cursor_test('mem', [mfoo, mbar], [mfoo]) if test_keyring: cursor_test('keyringmem', [krccname, mfoo], [kruser, kralice, krbob]) # Test krb5_cccol_have_content. mark('krb5_cccol_have_content') realm.run(['./t_cccursor', dccname, 'CONTENT']) realm.run(['./t_cccursor', fccname, 'CONTENT']) realm.run(['./t_cccursor', realm.ccache, 'CONTENT']) realm.run(['./t_cccursor', mfoo, 'CONTENT'], expected_code=1) if test_keyring: realm.run(['./t_cccursor', krccname, 'CONTENT']) cleanup_keyring('@s', col_ringname) # Make sure FILE doesn't yield a nonexistent default cache. mark('FILE nonexistent') realm.run([kdestroy]) cursor_test('noexist', [], []) realm.run(['./t_cccursor', fccname, 'CONTENT'], expected_code=1) success('Renewing credentials') krb5-1.22.1/src/lib/krb5/ccache/ccselect_realm.c0000664000175000017500000000620615051422640021064 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccselect_realm.c - realm ccselect module */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "cc-int.h" #include static krb5_error_code realm_init(krb5_context context, krb5_ccselect_moddata *data_out, int *priority_out) { *data_out = NULL; *priority_out = KRB5_CCSELECT_PRIORITY_HEURISTIC; return 0; } static krb5_error_code realm_choose(krb5_context context, krb5_ccselect_moddata data, krb5_principal server, krb5_ccache *cache_out, krb5_principal *princ_out) { krb5_error_code ret; krb5_cccol_cursor cursor; krb5_ccache cache; krb5_principal princ; *cache_out = NULL; *princ_out = NULL; if (krb5_is_referral_realm(&server->realm)) return KRB5_PLUGIN_NO_HANDLE; /* Scan the collection for a cache with a client principal in the same * realm as the server principal. */ ret = krb5_cccol_cursor_new(context, &cursor); if (ret) return ret; while ((ret = krb5_cccol_cursor_next(context, cursor, &cache)) == 0 && cache != NULL) { ret = krb5_cc_get_principal(context, cache, &princ); if (ret == 0) { if (data_eq(princ->realm, server->realm)) break; krb5_free_principal(context, princ); } krb5_cc_close(context, cache); } krb5_cccol_cursor_free(context, &cursor); if (ret) return ret; if (cache == NULL) return KRB5_PLUGIN_NO_HANDLE; *cache_out = cache; *princ_out = princ; return 0; } krb5_error_code ccselect_realm_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_ccselect_vtable vt; if (maj_ver != 1) return KRB5_PLUGIN_VER_NOTSUPP; vt = (krb5_ccselect_vtable)vtable; vt->name = "realm"; vt->init = realm_init; vt->choose = realm_choose; return 0; } krb5-1.22.1/src/lib/krb5/ccache/cc_mslsa.c0000664000175000017500000021304315051422640017702 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cc_mslsa.c */ /* * Copyright 2007 Secure Endpoints Inc. * * Copyright 2003,2004 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * Copyright 2000 by Carnegie Mellon University * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Carnegie Mellon * University not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Implementation of microsoft windows lsa credentials cache */ #ifdef _WIN32 #define UNICODE #define _UNICODE #include #define WIN32_NO_STATUS #include "k5-int.h" #include "com_err.h" #include "cc-int.h" #include #include #include #include #include #define SECURITY_WIN32 #include #ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif #define _WIN32_WINNT 0x0600 #include #define MAX_MSG_SIZE 256 #define MAX_MSPRINC_SIZE 1024 /* THREAD SAFETY * The function does_query_ticket_cache_ex2() * contains static variables to cache the responses of the tests being * performed. There is no harm in the test being performed more than * once since the result will always be the same. */ typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); static VOID ShowWinError(LPSTR szAPI, DWORD dwError) { // TODO - Write errors to event log so that scripts that don't // check for errors will still get something in the event log // This code is completely unsafe for use on non-English systems // Any call to this function will result in the FormatMessage // call failing and the program terminating. This might have // been acceptable when this code was part of ms2mit.exe as // a standalone executable but it is not appropriate for a library #ifdef COMMENT WCHAR szMsgBuf[MAX_MSG_SIZE]; DWORD dwRes; printf("Error calling function %s: %lu\n", szAPI, dwError); dwRes = FormatMessage ( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), szMsgBuf, MAX_MSG_SIZE, NULL); if (0 == dwRes) { printf("FormatMessage failed with %d\n", GetLastError()); ExitProcess(EXIT_FAILURE); } printf("%S",szMsgBuf); #endif /* COMMENT */ } static VOID ShowLsaError(LPSTR szAPI, NTSTATUS Status) { // // Convert the NTSTATUS to Winerror. Then call ShowWinError(). // ShowWinError(szAPI, LsaNtStatusToWinError(Status)); } static BOOL WINAPI UnicodeToANSI(LPTSTR lpInputString, LPSTR lpszOutputString, int nOutStringLen) { CPINFO CodePageInfo; GetCPInfo(CP_ACP, &CodePageInfo); if (CodePageInfo.MaxCharSize > 1) { // Only supporting non-Unicode strings int reqLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) lpInputString, -1, NULL, 0, NULL, NULL); if ( reqLen > nOutStringLen) { return FALSE; } else { if (WideCharToMultiByte(CP_ACP, /* WC_NO_BEST_FIT_CHARS | */ WC_COMPOSITECHECK, (LPCWSTR) lpInputString, -1, lpszOutputString, nOutStringLen, NULL, NULL) == 0) return FALSE; } } else { // Looks like unicode, better translate it if (WideCharToMultiByte(CP_ACP, /* WC_NO_BEST_FIT_CHARS | */ WC_COMPOSITECHECK, (LPCWSTR) lpInputString, -1, lpszOutputString, nOutStringLen, NULL, NULL) == 0) return FALSE; } return TRUE; } // UnicodeToANSI static VOID WINAPI ANSIToUnicode(LPCSTR lpInputString, LPWSTR lpszOutputString, int nOutStringLen) { CPINFO CodePageInfo; GetCPInfo(CP_ACP, &CodePageInfo); MultiByteToWideChar(CP_ACP, 0, lpInputString, -1, lpszOutputString, nOutStringLen); } // ANSIToUnicode static void MITPrincToMSPrinc(krb5_context context, krb5_principal principal, UNICODE_STRING * msprinc) { char *aname = NULL; if (!krb5_unparse_name(context, principal, &aname)) { msprinc->Length = strlen(aname) * sizeof(WCHAR); if ( msprinc->Length <= msprinc->MaximumLength ) ANSIToUnicode(aname, msprinc->Buffer, msprinc->MaximumLength); else msprinc->Length = 0; krb5_free_unparsed_name(context,aname); } } static BOOL UnicodeStringToMITPrinc(UNICODE_STRING *service, UNICODE_STRING *realm, krb5_context context, krb5_principal *principal) { WCHAR princbuf[512]; WCHAR realmbuf[512]; char aname[512]; /* Convert the realm to a wchar string. */ realmbuf[0] = '\0'; wcsncpy(realmbuf, realm->Buffer, realm->Length / sizeof(WCHAR)); realmbuf[realm->Length / sizeof(WCHAR)] = 0; /* Convert the principal components to a wchar string. */ princbuf[0]=0; wcsncpy(princbuf, service->Buffer, service->Length/sizeof(WCHAR)); princbuf[service->Length/sizeof(WCHAR)]=0; wcscat(princbuf, L"@"); wcscat(princbuf, realmbuf); if (UnicodeToANSI(princbuf, aname, sizeof(aname))) { if (krb5_parse_name(context, aname, principal) == 0) return TRUE; } return FALSE; } static BOOL KerbExternalNameToMITPrinc(KERB_EXTERNAL_NAME *msprinc, WCHAR *realm, krb5_context context, krb5_principal *principal) { WCHAR princbuf[512],tmpbuf[128]; char aname[512]; USHORT i; princbuf[0]=0; for (i=0;iNameCount;i++) { wcsncpy(tmpbuf, msprinc->Names[i].Buffer, msprinc->Names[i].Length/sizeof(WCHAR)); tmpbuf[msprinc->Names[i].Length/sizeof(WCHAR)]=0; if (princbuf[0]) wcscat(princbuf, L"/"); wcscat(princbuf, tmpbuf); } wcscat(princbuf, L"@"); wcscat(princbuf, realm); if (UnicodeToANSI(princbuf, aname, sizeof(aname))) { if (krb5_parse_name(context, aname, principal) == 0) return TRUE; } return FALSE; } static time_t FileTimeToUnixTime(LARGE_INTEGER *ltime) { FILETIME filetime, localfiletime; SYSTEMTIME systime; struct tm utime; filetime.dwLowDateTime=ltime->LowPart; filetime.dwHighDateTime=ltime->HighPart; FileTimeToLocalFileTime(&filetime, &localfiletime); FileTimeToSystemTime(&localfiletime, &systime); utime.tm_sec=systime.wSecond; utime.tm_min=systime.wMinute; utime.tm_hour=systime.wHour; utime.tm_mday=systime.wDay; utime.tm_mon=systime.wMonth-1; utime.tm_year=systime.wYear-1900; utime.tm_isdst=-1; return(mktime(&utime)); } static void MSSessionKeyToMITKeyblock(KERB_CRYPTO_KEY *mskey, krb5_context context, krb5_keyblock *keyblock) { krb5_keyblock tmpblock; tmpblock.magic=KV5M_KEYBLOCK; tmpblock.enctype=mskey->KeyType; tmpblock.length=mskey->Length; tmpblock.contents=mskey->Value; krb5_copy_keyblock_contents(context, &tmpblock, keyblock); } static BOOL IsMSSessionKeyNull(KERB_CRYPTO_KEY *mskey) { DWORD i; if (mskey->KeyType == KERB_ETYPE_NULL) return TRUE; for ( i=0; iLength; i++ ) { if (mskey->Value[i]) return FALSE; } return TRUE; } static void MSFlagsToMITFlags(ULONG msflags, ULONG *mitflags) { *mitflags=msflags; } static BOOL MSTicketToMITTicket(KERB_EXTERNAL_TICKET *msticket, krb5_context context, krb5_data *ticket) { krb5_data tmpdata, *newdata = 0; krb5_error_code rc; tmpdata.magic=KV5M_DATA; tmpdata.length=msticket->EncodedTicketSize; tmpdata.data=msticket->EncodedTicket; // this is ugly and will break krb5_free_data() // now that this is being done within the library it won't break krb5_free_data() rc = krb5_copy_data(context, &tmpdata, &newdata); if (rc) return FALSE; memcpy(ticket, newdata, sizeof(krb5_data)); free(newdata); return TRUE; } static BOOL MSCredToMITCred(KERB_EXTERNAL_TICKET *msticket, UNICODE_STRING ClientRealm, krb5_context context, krb5_creds *creds) { WCHAR wrealm[128]; ZeroMemory(creds, sizeof(krb5_creds)); creds->magic=KV5M_CREDS; // construct Client Principal wcsncpy(wrealm, ClientRealm.Buffer, ClientRealm.Length/sizeof(WCHAR)); wrealm[ClientRealm.Length/sizeof(WCHAR)]=0; if (!KerbExternalNameToMITPrinc(msticket->ClientName, wrealm, context, &creds->client)) return FALSE; // construct Service Principal wcsncpy(wrealm, msticket->DomainName.Buffer, msticket->DomainName.Length/sizeof(WCHAR)); wrealm[msticket->DomainName.Length/sizeof(WCHAR)]=0; if (!KerbExternalNameToMITPrinc(msticket->ServiceName, wrealm, context, &creds->server)) return FALSE; MSSessionKeyToMITKeyblock(&msticket->SessionKey, context, &creds->keyblock); MSFlagsToMITFlags(msticket->TicketFlags, &creds->ticket_flags); creds->times.starttime=FileTimeToUnixTime(&msticket->StartTime); creds->times.endtime=FileTimeToUnixTime(&msticket->EndTime); creds->times.renew_till=FileTimeToUnixTime(&msticket->RenewUntil); creds->addresses = NULL; return MSTicketToMITTicket(msticket, context, &creds->ticket); } /* CacheInfoEx2ToMITCred is used when we do not need the real ticket */ static BOOL CacheInfoEx2ToMITCred(KERB_TICKET_CACHE_INFO_EX2 *info, krb5_context context, krb5_creds *creds) { ZeroMemory(creds, sizeof(krb5_creds)); creds->magic=KV5M_CREDS; // construct Client Principal if (!UnicodeStringToMITPrinc(&info->ClientName, &info->ClientRealm, context, &creds->client)) return FALSE; // construct Service Principal if (!UnicodeStringToMITPrinc(&info->ServerName, &info->ServerRealm, context, &creds->server)) return FALSE; creds->keyblock.magic = KV5M_KEYBLOCK; creds->keyblock.enctype = info->SessionKeyType; creds->ticket_flags = info->TicketFlags; MSFlagsToMITFlags(info->TicketFlags, &creds->ticket_flags); creds->times.starttime=FileTimeToUnixTime(&info->StartTime); creds->times.endtime=FileTimeToUnixTime(&info->EndTime); creds->times.renew_till=FileTimeToUnixTime(&info->RenewTime); /* MS Tickets are addressless. MIT requires an empty address * not a NULL list of addresses. */ creds->addresses = (krb5_address **)malloc(sizeof(krb5_address *)); if (creds->addresses == NULL) return FALSE; memset(creds->addresses, 0, sizeof(krb5_address *)); return TRUE; } static BOOL PackageConnectLookup(HANDLE *pLogonHandle, ULONG *pPackageId) { LSA_STRING Name; NTSTATUS Status; Status = LsaConnectUntrusted( pLogonHandle ); if (FAILED(Status)) { ShowLsaError("LsaConnectUntrusted", Status); return FALSE; } Name.Buffer = MICROSOFT_KERBEROS_NAME_A; Name.Length = strlen(Name.Buffer); Name.MaximumLength = Name.Length + 1; Status = LsaLookupAuthenticationPackage( *pLogonHandle, &Name, pPackageId ); if (FAILED(Status)) { ShowLsaError("LsaLookupAuthenticationPackage", Status); return FALSE; } return TRUE; } /* * This runtime check is only needed on Windows XP and Server 2003. * It can safely be removed when we no longer wish to support any * versions of those platforms. */ static BOOL does_query_ticket_cache_ex2 (void) { static BOOL fChecked = FALSE; static BOOL fEx2Response = FALSE; if (!fChecked) { NTSTATUS Status = 0; NTSTATUS SubStatus = 0; HANDLE LogonHandle; ULONG PackageId; ULONG RequestSize; PKERB_QUERY_TKT_CACHE_REQUEST pCacheRequest = NULL; PKERB_QUERY_TKT_CACHE_EX2_RESPONSE pCacheResponse = NULL; ULONG ResponseSize; RequestSize = sizeof(*pCacheRequest) + 1; if (!PackageConnectLookup(&LogonHandle, &PackageId)) return FALSE; pCacheRequest = (PKERB_QUERY_TKT_CACHE_REQUEST) LocalAlloc(LMEM_ZEROINIT, RequestSize); if (!pCacheRequest) { LsaDeregisterLogonProcess(LogonHandle); return FALSE; } pCacheRequest->MessageType = KerbQueryTicketCacheEx2Message; pCacheRequest->LogonId.LowPart = 0; pCacheRequest->LogonId.HighPart = 0; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pCacheRequest, RequestSize, &pCacheResponse, &ResponseSize, &SubStatus ); LocalFree(pCacheRequest); LsaDeregisterLogonProcess(LogonHandle); if (!(FAILED(Status) || FAILED(SubStatus))) { LsaFreeReturnBuffer(pCacheResponse); fEx2Response = TRUE; } fChecked = TRUE; } return fEx2Response; } static DWORD ConcatenateUnicodeStrings(UNICODE_STRING *pTarget, UNICODE_STRING Source1, UNICODE_STRING Source2) { // // The buffers for Source1 and Source2 cannot overlap pTarget's // buffer. Source1.Length + Source2.Length must be <= 0xFFFF, // otherwise we overflow... // USHORT TotalSize = Source1.Length + Source2.Length; PBYTE buffer = (PBYTE) pTarget->Buffer; if (TotalSize > pTarget->MaximumLength) return ERROR_INSUFFICIENT_BUFFER; if ( pTarget->Buffer != Source1.Buffer ) memcpy(buffer, Source1.Buffer, Source1.Length); memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length); pTarget->Length = TotalSize; return ERROR_SUCCESS; } static BOOL get_STRING_from_registry(HKEY hBaseKey, char * key, char * value, char * outbuf, DWORD outlen) { HKEY hKey; DWORD dwCount; LONG rc; if (!outbuf || outlen == 0) return FALSE; rc = RegOpenKeyExA(hBaseKey, key, 0, KEY_QUERY_VALUE, &hKey); if (rc) return FALSE; dwCount = outlen; rc = RegQueryValueExA(hKey, value, 0, 0, (LPBYTE) outbuf, &dwCount); RegCloseKey(hKey); return rc?FALSE:TRUE; } static BOOL GetSecurityLogonSessionData(PSECURITY_LOGON_SESSION_DATA * ppSessionData) { NTSTATUS Status = 0; HANDLE TokenHandle; TOKEN_STATISTICS Stats; DWORD ReqLen; BOOL Success; if (!ppSessionData) return FALSE; *ppSessionData = NULL; Success = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &TokenHandle ); if ( !Success ) return FALSE; Success = GetTokenInformation( TokenHandle, TokenStatistics, &Stats, sizeof(TOKEN_STATISTICS), &ReqLen ); CloseHandle( TokenHandle ); if ( !Success ) return FALSE; Status = LsaGetLogonSessionData( &Stats.AuthenticationId, ppSessionData ); if ( FAILED(Status) || !ppSessionData ) return FALSE; return TRUE; } static DWORD ConstructTicketRequest(UNICODE_STRING DomainName, PKERB_RETRIEVE_TKT_REQUEST * outRequest, ULONG * outSize) { DWORD Error; UNICODE_STRING TargetPrefix; USHORT TargetSize; ULONG RequestSize; PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; *outRequest = NULL; *outSize = 0; // // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we // can easily concatenate it later. // TargetPrefix.Buffer = L"krbtgt/"; TargetPrefix.Length = wcslen(TargetPrefix.Buffer) * sizeof(WCHAR); TargetPrefix.MaximumLength = TargetPrefix.Length; // // We will need to concatenate the "krbtgt/" prefix and the // Logon Session's DnsDomainName into our request's target name. // // Therefore, first compute the necessary buffer size for that. // // Note that we might theoretically have integer overflow. // TargetSize = TargetPrefix.Length + DomainName.Length; // // The ticket request buffer needs to be a single buffer. That buffer // needs to include the buffer for the target name. // RequestSize = sizeof(*pTicketRequest) + TargetSize; // // Allocate the request buffer and make sure it's zero-filled. // pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LMEM_ZEROINIT, RequestSize); if (!pTicketRequest) return GetLastError(); // // Concatenate the target prefix with the previous reponse's // target domain. // pTicketRequest->TargetName.Length = 0; pTicketRequest->TargetName.MaximumLength = TargetSize; pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1); Error = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName), TargetPrefix, DomainName); *outRequest = pTicketRequest; *outSize = RequestSize; return Error; } static BOOL PurgeAllTickets(HANDLE LogonHandle, ULONG PackageId) { NTSTATUS Status = 0; NTSTATUS SubStatus = 0; KERB_PURGE_TKT_CACHE_REQUEST PurgeRequest; PurgeRequest.MessageType = KerbPurgeTicketCacheMessage; PurgeRequest.LogonId.LowPart = 0; PurgeRequest.LogonId.HighPart = 0; PurgeRequest.ServerName.Buffer = L""; PurgeRequest.ServerName.Length = 0; PurgeRequest.ServerName.MaximumLength = 0; PurgeRequest.RealmName.Buffer = L""; PurgeRequest.RealmName.Length = 0; PurgeRequest.RealmName.MaximumLength = 0; Status = LsaCallAuthenticationPackage(LogonHandle, PackageId, &PurgeRequest, sizeof(PurgeRequest), NULL, NULL, &SubStatus ); if (FAILED(Status) || FAILED(SubStatus)) return FALSE; return TRUE; } static BOOL PurgeTicketEx(HANDLE LogonHandle, ULONG PackageId, krb5_context context, krb5_flags flags, krb5_creds *cred) { NTSTATUS Status = 0; NTSTATUS SubStatus = 0; KERB_PURGE_TKT_CACHE_EX_REQUEST * pPurgeRequest; DWORD dwRequestLen = sizeof(KERB_PURGE_TKT_CACHE_EX_REQUEST) + 4096; char * cname = NULL, * crealm = NULL; char * sname = NULL, * srealm = NULL; if (krb5_unparse_name(context, cred->client, &cname)) return FALSE; if (krb5_unparse_name(context, cred->server, &sname)) { krb5_free_unparsed_name(context, cname); return FALSE; } pPurgeRequest = malloc(dwRequestLen); if ( pPurgeRequest == NULL ) return FALSE; memset(pPurgeRequest, 0, dwRequestLen); crealm = strrchr(cname, '@'); *crealm = '\0'; crealm++; srealm = strrchr(sname, '@'); *srealm = '\0'; srealm++; pPurgeRequest->MessageType = KerbPurgeTicketCacheExMessage; pPurgeRequest->LogonId.LowPart = 0; pPurgeRequest->LogonId.HighPart = 0; pPurgeRequest->Flags = 0; pPurgeRequest->TicketTemplate.ClientName.Buffer = (PWSTR)((CHAR *)pPurgeRequest + sizeof(KERB_PURGE_TKT_CACHE_EX_REQUEST)); pPurgeRequest->TicketTemplate.ClientName.Length = strlen(cname)*sizeof(WCHAR); pPurgeRequest->TicketTemplate.ClientName.MaximumLength = 256; ANSIToUnicode(cname, pPurgeRequest->TicketTemplate.ClientName.Buffer, pPurgeRequest->TicketTemplate.ClientName.MaximumLength); pPurgeRequest->TicketTemplate.ClientRealm.Buffer = (PWSTR)(((CHAR *)pPurgeRequest)+sizeof(KERB_PURGE_TKT_CACHE_EX_REQUEST) + 512); pPurgeRequest->TicketTemplate.ClientRealm.Length = strlen(crealm)*sizeof(WCHAR); pPurgeRequest->TicketTemplate.ClientRealm.MaximumLength = 256; ANSIToUnicode(crealm, pPurgeRequest->TicketTemplate.ClientRealm.Buffer, pPurgeRequest->TicketTemplate.ClientRealm.MaximumLength); pPurgeRequest->TicketTemplate.ServerName.Buffer = (PWSTR)(((CHAR *)pPurgeRequest)+sizeof(KERB_PURGE_TKT_CACHE_EX_REQUEST) + 1024); pPurgeRequest->TicketTemplate.ServerName.Length = strlen(sname)*sizeof(WCHAR); pPurgeRequest->TicketTemplate.ServerName.MaximumLength = 256; ANSIToUnicode(sname, pPurgeRequest->TicketTemplate.ServerName.Buffer, pPurgeRequest->TicketTemplate.ServerName.MaximumLength); pPurgeRequest->TicketTemplate.ServerRealm.Buffer = (PWSTR)(((CHAR *)pPurgeRequest)+sizeof(KERB_PURGE_TKT_CACHE_EX_REQUEST) + 1536); pPurgeRequest->TicketTemplate.ServerRealm.Length = strlen(srealm)*sizeof(WCHAR); pPurgeRequest->TicketTemplate.ServerRealm.MaximumLength = 256; ANSIToUnicode(srealm, pPurgeRequest->TicketTemplate.ServerRealm.Buffer, pPurgeRequest->TicketTemplate.ServerRealm.MaximumLength); pPurgeRequest->TicketTemplate.StartTime; pPurgeRequest->TicketTemplate.EndTime; pPurgeRequest->TicketTemplate.RenewTime; pPurgeRequest->TicketTemplate.EncryptionType = cred->keyblock.enctype; pPurgeRequest->TicketTemplate.TicketFlags = flags; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pPurgeRequest, dwRequestLen, NULL, NULL, &SubStatus ); free(pPurgeRequest); krb5_free_unparsed_name(context,cname); krb5_free_unparsed_name(context,sname); if (FAILED(Status) || FAILED(SubStatus)) return FALSE; return TRUE; } static BOOL KerbSubmitTicket( HANDLE LogonHandle, ULONG PackageId, krb5_context context, krb5_creds *cred) { NTSTATUS Status = 0; NTSTATUS SubStatus = 0; KERB_SUBMIT_TKT_REQUEST * pSubmitRequest = NULL; DWORD dwRequestLen; krb5_auth_context auth_context = NULL; krb5_keyblock * keyblock = 0; krb5_replay_data replaydata; krb5_data * krb_cred = 0; krb5_error_code rc; BOOL rv = FALSE; if (krb5_auth_con_init(context, &auth_context)) { return FALSE; } if (krb5_auth_con_setflags(context, auth_context, KRB5_AUTH_CONTEXT_RET_TIME)) { return FALSE; } krb5_auth_con_getsendsubkey(context, auth_context, &keyblock); if (keyblock == NULL) krb5_auth_con_getkey(context, auth_context, &keyblock); /* make up a key, any key, that can be used to generate the * encrypted KRB_CRED pdu. The Vista release LSA requires * that an enctype other than NULL be used. */ if (keyblock == NULL) { keyblock = (krb5_keyblock *)malloc(sizeof(krb5_keyblock)); if (keyblock == NULL) return FALSE; keyblock->enctype = ENCTYPE_ARCFOUR_HMAC; keyblock->length = 16; keyblock->contents = (krb5_octet *)malloc(16); if (keyblock->contents == NULL) goto cleanup; keyblock->contents[0] = 0xde; keyblock->contents[1] = 0xad; keyblock->contents[2] = 0xbe; keyblock->contents[3] = 0xef; keyblock->contents[4] = 0xfe; keyblock->contents[5] = 0xed; keyblock->contents[6] = 0xf0; keyblock->contents[7] = 0xd; keyblock->contents[8] = 0xde; keyblock->contents[9] = 0xad; keyblock->contents[10] = 0xbe; keyblock->contents[11] = 0xef; keyblock->contents[12] = 0xfe; keyblock->contents[13] = 0xed; keyblock->contents[14] = 0xf0; keyblock->contents[15] = 0xd; krb5_auth_con_setsendsubkey(context, auth_context, keyblock); } rc = krb5_mk_1cred(context, auth_context, cred, &krb_cred, &replaydata); if (rc) goto cleanup; dwRequestLen = sizeof(KERB_SUBMIT_TKT_REQUEST) + krb_cred->length + (keyblock ? keyblock->length : 0); pSubmitRequest = (PKERB_SUBMIT_TKT_REQUEST)malloc(dwRequestLen); if (pSubmitRequest == NULL) goto cleanup; memset(pSubmitRequest, 0, dwRequestLen); pSubmitRequest->MessageType = KerbSubmitTicketMessage; pSubmitRequest->LogonId.LowPart = 0; pSubmitRequest->LogonId.HighPart = 0; pSubmitRequest->Flags = 0; if (keyblock) { pSubmitRequest->Key.KeyType = keyblock->enctype; pSubmitRequest->Key.Length = keyblock->length; pSubmitRequest->Key.Offset = sizeof(KERB_SUBMIT_TKT_REQUEST)+krb_cred->length; } else { pSubmitRequest->Key.KeyType = ENCTYPE_NULL; pSubmitRequest->Key.Length = 0; pSubmitRequest->Key.Offset = 0; } pSubmitRequest->KerbCredSize = krb_cred->length; pSubmitRequest->KerbCredOffset = sizeof(KERB_SUBMIT_TKT_REQUEST); memcpy(((CHAR *)pSubmitRequest)+sizeof(KERB_SUBMIT_TKT_REQUEST), krb_cred->data, krb_cred->length); if (keyblock) memcpy(((CHAR *)pSubmitRequest)+sizeof(KERB_SUBMIT_TKT_REQUEST)+krb_cred->length, keyblock->contents, keyblock->length); Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pSubmitRequest, dwRequestLen, NULL, NULL, &SubStatus ); rv = (!FAILED(Status) && !FAILED(SubStatus)); cleanup: free(pSubmitRequest); krb5_free_keyblock(context, keyblock); krb5_free_data(context, krb_cred); krb5_auth_con_free(context, auth_context); return rv; } /* * A simple function to determine if there is an exact match between two tickets * We rely on the fact that the external tickets contain the raw Kerberos ticket. * If the EncodedTicket fields match, the KERB_EXTERNAL_TICKETs must be the same. */ static BOOL KerbExternalTicketMatch( PKERB_EXTERNAL_TICKET one, PKERB_EXTERNAL_TICKET two ) { if ( one->EncodedTicketSize != two->EncodedTicketSize ) return FALSE; if ( memcmp(one->EncodedTicket, two->EncodedTicket, one->EncodedTicketSize) ) return FALSE; return TRUE; } krb5_boolean krb5_is_permitted_tgs_enctype(krb5_context context, krb5_const_principal princ, krb5_enctype etype) { krb5_enctype *list, *ptr; krb5_boolean ret; if (krb5_get_tgs_ktypes(context, princ, &list)) return(0); ret = 0; for (ptr = list; *ptr; ptr++) if (*ptr == etype) ret = 1; krb5_free_enctypes(context, list); return(ret); } // to allow the purging of expired tickets from LSA cache. This is necessary // to force the retrieval of new TGTs. Microsoft does not appear to retrieve // new tickets when they expire. Instead they continue to accept the expired // tickets. This is safe to do because the LSA purges its cache when it // retrieves a new TGT (ms calls this renew) but not when it renews the TGT // (ms calls this refresh). // UAC-limited processes are not allowed to obtain a copy of the MSTGT // session key. We used to check for UAC-limited processes and refuse all // access to the TGT, but this makes the MSLSA ccache completely unusable. // Instead we ought to just flag that the tgt session key is not valid. static BOOL GetMSTGT(krb5_context context, HANDLE LogonHandle, ULONG PackageId, KERB_EXTERNAL_TICKET **ticket, BOOL enforce_tgs_enctypes) { // // INVARIANTS: // // (FAILED(Status) || FAILED(SubStatus)) ==> error // bIsLsaError ==> LsaCallAuthenticationPackage() error // BOOL bIsLsaError = FALSE; NTSTATUS Status = 0; NTSTATUS SubStatus = 0; DWORD Error; KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; ULONG RequestSize; ULONG ResponseSize; int purge_cache = 0; int ignore_cache = 0; krb5_enctype *etype_list = NULL, *ptr = NULL, etype = 0; memset(&CacheRequest, 0, sizeof(KERB_QUERY_TKT_CACHE_REQUEST)); CacheRequest.MessageType = KerbRetrieveTicketMessage; CacheRequest.LogonId.LowPart = 0; CacheRequest.LogonId.HighPart = 0; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, &CacheRequest, sizeof(CacheRequest), &pTicketResponse, &ResponseSize, &SubStatus ); if (FAILED(Status)) { // if the call to LsaCallAuthenticationPackage failed we cannot // perform any queries most likely because the Kerberos package // is not available or we do not have access bIsLsaError = TRUE; goto cleanup; } if (FAILED(SubStatus)) { PSECURITY_LOGON_SESSION_DATA pSessionData = NULL; BOOL Success = FALSE; OSVERSIONINFOEX verinfo; int supported = 0; // SubStatus 0x8009030E is not documented. However, it appears // to mean there is no TGT if (SubStatus != 0x8009030E) { bIsLsaError = TRUE; goto cleanup; } verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); GetVersionEx((OSVERSIONINFO *)&verinfo); supported = (verinfo.dwMajorVersion > 5) || (verinfo.dwMajorVersion == 5 && verinfo.dwMinorVersion >= 1); // If we could not get a TGT from the cache we won't know what the // Kerberos Domain should have been. On Windows XP and 2003 Server // we can extract it from the Security Logon Session Data. However, // the required fields are not supported on Windows 2000. :( if ( supported && GetSecurityLogonSessionData(&pSessionData) ) { if ( pSessionData->DnsDomainName.Buffer ) { Error = ConstructTicketRequest(pSessionData->DnsDomainName, &pTicketRequest, &RequestSize); LsaFreeReturnBuffer(pSessionData); if ( Error ) goto cleanup; } else { LsaFreeReturnBuffer(pSessionData); bIsLsaError = TRUE; goto cleanup; } } else { CHAR UserDnsDomain[256]; WCHAR UnicodeUserDnsDomain[256]; UNICODE_STRING wrapper; if ( !get_STRING_from_registry(HKEY_CURRENT_USER, "Volatile Environment", "USERDNSDOMAIN", UserDnsDomain, sizeof(UserDnsDomain) ) ) { goto cleanup; } ANSIToUnicode(UserDnsDomain,UnicodeUserDnsDomain,256); wrapper.Buffer = UnicodeUserDnsDomain; wrapper.Length = wcslen(UnicodeUserDnsDomain) * sizeof(WCHAR); wrapper.MaximumLength = 256; Error = ConstructTicketRequest(wrapper, &pTicketRequest, &RequestSize); if ( Error ) goto cleanup; } } else { /* We have succeeded in obtaining a credential from the cache. * Assuming the enctype is one that we support and the ticket * has not expired and is not marked invalid we will use it. * Otherwise, we must create a new ticket request and obtain * a credential we can use. */ /* Check Supported Enctypes */ if ( !enforce_tgs_enctypes || IsMSSessionKeyNull(&pTicketResponse->Ticket.SessionKey) || krb5_is_permitted_tgs_enctype(context, NULL, pTicketResponse->Ticket.SessionKey.KeyType) ) { FILETIME Now, MinLife, EndTime, LocalEndTime; __int64 temp; // FILETIME is in units of 100 nano-seconds // If obtained tickets are either expired or have a lifetime // less than 20 minutes, retry ... GetSystemTimeAsFileTime(&Now); EndTime.dwLowDateTime=pTicketResponse->Ticket.EndTime.LowPart; EndTime.dwHighDateTime=pTicketResponse->Ticket.EndTime.HighPart; FileTimeToLocalFileTime(&EndTime, &LocalEndTime); temp = Now.dwHighDateTime; temp <<= 32; temp = Now.dwLowDateTime; temp += 1200 * 10000; MinLife.dwHighDateTime = (DWORD)((temp >> 32) & 0xFFFFFFFF); MinLife.dwLowDateTime = (DWORD)(temp & 0xFFFFFFFF); if (CompareFileTime(&MinLife, &LocalEndTime) >= 0) { purge_cache = 1; } if (pTicketResponse->Ticket.TicketFlags & KERB_TICKET_FLAGS_invalid) { ignore_cache = 1; // invalid, need to attempt a TGT request } goto cleanup; // we have a valid ticket, all done } else { // not supported ignore_cache = 1; } Error = ConstructTicketRequest(pTicketResponse->Ticket.TargetDomainName, &pTicketRequest, &RequestSize); if ( Error ) { goto cleanup; } // // Free the previous response buffer so we can get the new response. // if ( pTicketResponse ) { memset(pTicketResponse,0,sizeof(KERB_RETRIEVE_TKT_RESPONSE)); LsaFreeReturnBuffer(pTicketResponse); pTicketResponse = NULL; } if ( purge_cache ) { // // Purge the existing tickets which we cannot use so new ones can // be requested. It is not possible to purge just the TGT. All // service tickets must be purged. // PurgeAllTickets(LogonHandle, PackageId); } } // // Initialize the request of the request. // pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage; pTicketRequest->LogonId.LowPart = 0; pTicketRequest->LogonId.HighPart = 0; // Note: pTicketRequest->TargetName set up above pTicketRequest->CacheOptions = ((ignore_cache || !purge_cache) ? KERB_RETRIEVE_TICKET_DONT_USE_CACHE : 0L); pTicketRequest->TicketFlags = 0L; pTicketRequest->EncryptionType = 0L; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pTicketRequest, RequestSize, &pTicketResponse, &ResponseSize, &SubStatus ); if (FAILED(Status) || FAILED(SubStatus)) { bIsLsaError = TRUE; goto cleanup; } // // Check to make sure the new tickets we received are of a type we support // /* Check Supported Enctypes */ if ( !enforce_tgs_enctypes || krb5_is_permitted_tgs_enctype(context, NULL, pTicketResponse->Ticket.SessionKey.KeyType) ) { goto cleanup; // we have a valid ticket, all done } if (krb5_get_tgs_ktypes(context, NULL, &etype_list)) { /* No enctypes - nothing we can do. */ bIsLsaError = TRUE; goto cleanup; } ptr = etype_list + 1; etype = *etype_list; while ( etype ) { // Try once more but this time specify the Encryption Type // (This will not store the retrieved tickets in the LSA cache unless // 0 is supported.) pTicketRequest->EncryptionType = etype; pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_CACHE_TICKET; if ( pTicketResponse ) { memset(pTicketResponse,0,sizeof(KERB_RETRIEVE_TKT_RESPONSE)); LsaFreeReturnBuffer(pTicketResponse); pTicketResponse = NULL; } Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pTicketRequest, RequestSize, &pTicketResponse, &ResponseSize, &SubStatus ); if (FAILED(Status) || FAILED(SubStatus)) { bIsLsaError = TRUE; goto cleanup; } if ( pTicketResponse->Ticket.SessionKey.KeyType == etype && (!enforce_tgs_enctypes || krb5_is_permitted_tgs_enctype(context, NULL, pTicketResponse->Ticket.SessionKey.KeyType)) ) { goto cleanup; // we have a valid ticket, all done } if ( ptr ) { etype = *ptr++; } else { etype = 0; } } cleanup: if ( etype_list ) krb5_free_enctypes(context, etype_list); if ( pTicketRequest ) LocalFree(pTicketRequest); if (FAILED(Status) || FAILED(SubStatus)) { if (bIsLsaError) { // XXX - Will be fixed later if (FAILED(Status)) ShowLsaError("LsaCallAuthenticationPackage", Status); if (FAILED(SubStatus)) ShowLsaError("LsaCallAuthenticationPackage", SubStatus); } else { ShowWinError("GetMSTGT", Status); } if (pTicketResponse) { memset(pTicketResponse,0,sizeof(KERB_RETRIEVE_TKT_RESPONSE)); LsaFreeReturnBuffer(pTicketResponse); pTicketResponse = NULL; } return(FALSE); } *ticket = &(pTicketResponse->Ticket); return(TRUE); } static BOOL GetQueryTktCacheResponseEx(HANDLE LogonHandle, ULONG PackageId, PKERB_QUERY_TKT_CACHE_EX_RESPONSE * ppResponse) { NTSTATUS Status = 0; NTSTATUS SubStatus = 0; KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; PKERB_QUERY_TKT_CACHE_EX_RESPONSE pQueryResponse = NULL; ULONG ResponseSize; CacheRequest.MessageType = KerbQueryTicketCacheExMessage; CacheRequest.LogonId.LowPart = 0; CacheRequest.LogonId.HighPart = 0; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, &CacheRequest, sizeof(CacheRequest), &pQueryResponse, &ResponseSize, &SubStatus ); if ( !(FAILED(Status) || FAILED(SubStatus)) ) { *ppResponse = pQueryResponse; return TRUE; } return FALSE; } static BOOL GetQueryTktCacheResponseEx2(HANDLE LogonHandle, ULONG PackageId, PKERB_QUERY_TKT_CACHE_EX2_RESPONSE * ppResponse) { NTSTATUS Status = 0; NTSTATUS SubStatus = 0; KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; PKERB_QUERY_TKT_CACHE_EX2_RESPONSE pQueryResponse = NULL; ULONG ResponseSize; CacheRequest.MessageType = KerbQueryTicketCacheEx2Message; CacheRequest.LogonId.LowPart = 0; CacheRequest.LogonId.HighPart = 0; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, &CacheRequest, sizeof(CacheRequest), &pQueryResponse, &ResponseSize, &SubStatus ); if ( !(FAILED(Status) || FAILED(SubStatus)) ) { *ppResponse = pQueryResponse; return TRUE; } return FALSE; } static BOOL GetMSCacheTicketFromMITCred( HANDLE LogonHandle, ULONG PackageId, krb5_context context, krb5_creds *creds, PKERB_EXTERNAL_TICKET *ticket) { NTSTATUS Status = 0; NTSTATUS SubStatus = 0; ULONG RequestSize; PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; ULONG ResponseSize; RequestSize = sizeof(*pTicketRequest) + MAX_MSPRINC_SIZE; pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LMEM_ZEROINIT, RequestSize); if (!pTicketRequest) return FALSE; pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage; pTicketRequest->LogonId.LowPart = 0; pTicketRequest->LogonId.HighPart = 0; pTicketRequest->TargetName.Length = 0; pTicketRequest->TargetName.MaximumLength = MAX_MSPRINC_SIZE; pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1); MITPrincToMSPrinc(context, creds->server, &pTicketRequest->TargetName); pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_CACHE_TICKET; pTicketRequest->TicketFlags = creds->ticket_flags; pTicketRequest->EncryptionType = creds->keyblock.enctype; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pTicketRequest, RequestSize, &pTicketResponse, &ResponseSize, &SubStatus ); LocalFree(pTicketRequest); if (FAILED(Status) || FAILED(SubStatus)) return(FALSE); /* otherwise return ticket */ *ticket = &(pTicketResponse->Ticket); return(TRUE); } static BOOL GetMSCacheTicketFromCacheInfoEx(HANDLE LogonHandle, ULONG PackageId, PKERB_TICKET_CACHE_INFO_EX tktinfo, PKERB_EXTERNAL_TICKET *ticket) { NTSTATUS Status = 0; NTSTATUS SubStatus = 0; ULONG RequestSize; PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; ULONG ResponseSize; RequestSize = sizeof(*pTicketRequest) + tktinfo->ServerName.Length; pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LMEM_ZEROINIT, RequestSize); if (!pTicketRequest) return FALSE; pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage; pTicketRequest->LogonId.LowPart = 0; pTicketRequest->LogonId.HighPart = 0; pTicketRequest->TargetName.Length = tktinfo->ServerName.Length; pTicketRequest->TargetName.MaximumLength = tktinfo->ServerName.Length; pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1); memcpy(pTicketRequest->TargetName.Buffer,tktinfo->ServerName.Buffer, tktinfo->ServerName.Length); pTicketRequest->CacheOptions = 0; pTicketRequest->EncryptionType = tktinfo->EncryptionType; pTicketRequest->TicketFlags = 0; if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_forwardable ) pTicketRequest->TicketFlags |= KDC_OPT_FORWARDABLE; if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_forwarded ) pTicketRequest->TicketFlags |= KDC_OPT_FORWARDED; if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_proxiable ) pTicketRequest->TicketFlags |= KDC_OPT_PROXIABLE; if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_renewable ) pTicketRequest->TicketFlags |= KDC_OPT_RENEWABLE; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pTicketRequest, RequestSize, &pTicketResponse, &ResponseSize, &SubStatus ); LocalFree(pTicketRequest); if (FAILED(Status) || FAILED(SubStatus)) return(FALSE); /* otherwise return ticket */ *ticket = &(pTicketResponse->Ticket); /* set the initial flag if we were attempting to retrieve one * because Windows won't necessarily return the initial ticket * to us. */ if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_initial ) (*ticket)->TicketFlags |= KERB_TICKET_FLAGS_initial; return(TRUE); } static BOOL GetMSCacheTicketFromCacheInfoEx2(HANDLE LogonHandle, ULONG PackageId, PKERB_TICKET_CACHE_INFO_EX2 tktinfo, PKERB_EXTERNAL_TICKET *ticket) { NTSTATUS Status = 0; NTSTATUS SubStatus = 0; ULONG RequestSize; PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; ULONG ResponseSize; RequestSize = sizeof(*pTicketRequest) + tktinfo->ServerName.Length; pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) LocalAlloc(LMEM_ZEROINIT, RequestSize); if (!pTicketRequest) return FALSE; pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage; pTicketRequest->LogonId.LowPart = 0; pTicketRequest->LogonId.HighPart = 0; pTicketRequest->TargetName.Length = tktinfo->ServerName.Length; pTicketRequest->TargetName.MaximumLength = tktinfo->ServerName.Length; pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1); memcpy(pTicketRequest->TargetName.Buffer,tktinfo->ServerName.Buffer, tktinfo->ServerName.Length); pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_CACHE_TICKET; pTicketRequest->EncryptionType = tktinfo->SessionKeyType; pTicketRequest->TicketFlags = 0; if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_forwardable ) pTicketRequest->TicketFlags |= KDC_OPT_FORWARDABLE; if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_forwarded ) pTicketRequest->TicketFlags |= KDC_OPT_FORWARDED; if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_proxiable ) pTicketRequest->TicketFlags |= KDC_OPT_PROXIABLE; if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_renewable ) pTicketRequest->TicketFlags |= KDC_OPT_RENEWABLE; Status = LsaCallAuthenticationPackage( LogonHandle, PackageId, pTicketRequest, RequestSize, &pTicketResponse, &ResponseSize, &SubStatus ); LocalFree(pTicketRequest); if (FAILED(Status) || FAILED(SubStatus)) return(FALSE); /* otherwise return ticket */ *ticket = &(pTicketResponse->Ticket); /* set the initial flag if we were attempting to retrieve one * because Windows won't necessarily return the initial ticket * to us. */ if ( tktinfo->TicketFlags & KERB_TICKET_FLAGS_initial ) (*ticket)->TicketFlags |= KERB_TICKET_FLAGS_initial; return(TRUE); } static krb5_error_code KRB5_CALLCONV krb5_lcc_close (krb5_context, krb5_ccache id); static krb5_error_code KRB5_CALLCONV krb5_lcc_destroy (krb5_context, krb5_ccache id); static krb5_error_code KRB5_CALLCONV krb5_lcc_end_seq_get (krb5_context, krb5_ccache id, krb5_cc_cursor *cursor); static krb5_error_code KRB5_CALLCONV krb5_lcc_generate_new (krb5_context, krb5_ccache *id); static const char * KRB5_CALLCONV krb5_lcc_get_name (krb5_context, krb5_ccache id); static krb5_error_code KRB5_CALLCONV krb5_lcc_get_principal (krb5_context, krb5_ccache id, krb5_principal *princ); static krb5_error_code KRB5_CALLCONV krb5_lcc_initialize (krb5_context, krb5_ccache id, krb5_principal princ); static krb5_error_code KRB5_CALLCONV krb5_lcc_next_cred (krb5_context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds); static krb5_error_code KRB5_CALLCONV krb5_lcc_resolve (krb5_context, krb5_ccache *id, const char *residual); static krb5_error_code KRB5_CALLCONV krb5_lcc_retrieve (krb5_context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds); static krb5_error_code KRB5_CALLCONV krb5_lcc_start_seq_get (krb5_context, krb5_ccache id, krb5_cc_cursor *cursor); static krb5_error_code KRB5_CALLCONV krb5_lcc_store (krb5_context, krb5_ccache id, krb5_creds *creds); static krb5_error_code KRB5_CALLCONV krb5_lcc_set_flags (krb5_context, krb5_ccache id, krb5_flags flags); static krb5_error_code KRB5_CALLCONV krb5_lcc_get_flags (krb5_context, krb5_ccache id, krb5_flags *flags); extern const krb5_cc_ops krb5_lcc_ops; krb5_error_code krb5_change_cache (void); krb5_boolean krb5int_cc_creds_match_request(krb5_context, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds); #define KRB5_OK 0 typedef struct _krb5_lcc_data { HANDLE LogonHandle; ULONG PackageId; char * cc_name; krb5_principal princ; krb5_flags flags; } krb5_lcc_data; typedef struct _krb5_lcc_cursor { union { PKERB_QUERY_TKT_CACHE_RESPONSE w2k; PKERB_QUERY_TKT_CACHE_EX_RESPONSE xp; PKERB_QUERY_TKT_CACHE_EX2_RESPONSE ex2; } response; unsigned int index; PKERB_EXTERNAL_TICKET mstgt; } krb5_lcc_cursor; /* * Requires: * residual is ignored * * Modifies: * id * * Effects: * Access the MS Kerberos LSA cache in the current logon session * Ignore the residual. * * Returns: * A filled in krb5_ccache structure "id". * * Errors: * KRB5_CC_NOMEM - there was insufficient memory to allocate the * * krb5_ccache. id is undefined. * permission errors */ static krb5_error_code KRB5_CALLCONV krb5_lcc_resolve (krb5_context context, krb5_ccache *id, const char *residual) { krb5_ccache lid; krb5_lcc_data *data; HANDLE LogonHandle; ULONG PackageId, i; PKERB_QUERY_TKT_CACHE_EX_RESPONSE pResponse; if (!PackageConnectLookup(&LogonHandle, &PackageId)) return KRB5_FCC_NOFILE; lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)); if (lid == NULL) { LsaDeregisterLogonProcess(LogonHandle); return KRB5_CC_NOMEM; } lid->ops = &krb5_lcc_ops; lid->data = (krb5_pointer) malloc(sizeof(krb5_lcc_data)); if (lid->data == NULL) { free(lid); LsaDeregisterLogonProcess(LogonHandle); return KRB5_CC_NOMEM; } lid->magic = KV5M_CCACHE; data = (krb5_lcc_data *)lid->data; data->LogonHandle = LogonHandle; data->PackageId = PackageId; data->princ = NULL; data->flags = 0; data->cc_name = (char *)malloc(strlen(residual)+1); if (data->cc_name == NULL) { free(lid->data); free(lid); LsaDeregisterLogonProcess(LogonHandle); return KRB5_CC_NOMEM; } strcpy(data->cc_name, residual); /* If there are already tickets present, grab a client principal name. */ if (GetQueryTktCacheResponseEx(LogonHandle, PackageId, &pResponse)) { /* Take the first client principal we find; they should all be the * same anyway. */ for (i = 0; i < pResponse->CountOfTickets; i++) { if (UnicodeStringToMITPrinc(&pResponse->Tickets[i].ClientName, &pResponse->Tickets[i].ClientRealm, context, &data->princ)) break; } LsaFreeReturnBuffer(pResponse); } /* * other routines will get errors on open, and callers must expect them, * if cache is non-existent/unusable */ *id = lid; return KRB5_OK; } /* * return success although we do not do anything * We should delete all tickets belonging to the specified principal */ static krb5_error_code KRB5_CALLCONV krb5_lcc_remove_cred(krb5_context context, krb5_ccache id, krb5_flags flags, krb5_creds *creds); static krb5_error_code KRB5_CALLCONV krb5_lcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ) { krb5_cc_cursor cursor; krb5_error_code code; krb5_creds cred; code = krb5_cc_start_seq_get(context, id, &cursor); if (code) { if (code == KRB5_CC_NOTFOUND) return KRB5_OK; return code; } while ( !(code = krb5_cc_next_cred(context, id, &cursor, &cred)) ) { if ( krb5_principal_compare(context, princ, cred.client) ) { code = krb5_lcc_remove_cred(context, id, 0, &cred); } krb5_free_cred_contents(context, &cred); } if (code == KRB5_CC_END || code == KRB5_CC_NOTFOUND) { krb5_cc_end_seq_get(context, id, &cursor); return KRB5_OK; } return code; } /* * Modifies: * id * * Effects: * Closes the microsoft lsa cache, invalidates the id, and frees any resources * associated with the cache. */ static krb5_error_code KRB5_CALLCONV krb5_lcc_close(krb5_context context, krb5_ccache id) { int closeval = KRB5_OK; krb5_lcc_data *data; if (id) { data = (krb5_lcc_data *) id->data; if (data) { LsaDeregisterLogonProcess(data->LogonHandle); if (data->cc_name) free(data->cc_name); free(data); } free(id); } return closeval; } /* * Effects: * Destroys the contents of id. * * Errors: * system errors */ static krb5_error_code KRB5_CALLCONV krb5_lcc_destroy(krb5_context context, krb5_ccache id) { krb5_lcc_data *data; if (id) { data = (krb5_lcc_data *) id->data; return PurgeAllTickets(data->LogonHandle, data->PackageId) ? KRB5_OK : KRB5_FCC_INTERNAL; } return KRB5_FCC_INTERNAL; } /* * Effects: * Prepares for a sequential search of the credentials cache. * Returns a krb5_cc_cursor to be used with krb5_lcc_next_cred and * krb5_lcc_end_seq_get. * * If the cache is modified between the time of this call and the time * of the final krb5_lcc_end_seq_get, the results are undefined. * * Errors: * KRB5_CC_NOMEM * KRB5_FCC_INTERNAL - system errors */ static krb5_error_code KRB5_CALLCONV krb5_lcc_start_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { krb5_lcc_cursor *lcursor; krb5_lcc_data *data = (krb5_lcc_data *)id->data; lcursor = (krb5_lcc_cursor *) malloc(sizeof(krb5_lcc_cursor)); if (lcursor == NULL) { *cursor = 0; return KRB5_CC_NOMEM; } /* * obtain a tgt to refresh the ccache in case the ticket is expired */ if (!GetMSTGT(context, data->LogonHandle, data->PackageId, &lcursor->mstgt, TRUE)) { free(lcursor); *cursor = 0; return KRB5_CC_NOTFOUND; } if ( does_query_ticket_cache_ex2() ) { if (!GetQueryTktCacheResponseEx2(data->LogonHandle, data->PackageId, &lcursor->response.ex2)) { LsaFreeReturnBuffer(lcursor->mstgt); free(lcursor); *cursor = 0; return KRB5_FCC_INTERNAL; } } else if (!GetQueryTktCacheResponseEx(data->LogonHandle, data->PackageId, &lcursor->response.xp)) { LsaFreeReturnBuffer(lcursor->mstgt); free(lcursor); *cursor = 0; return KRB5_FCC_INTERNAL; } lcursor->index = 0; *cursor = (krb5_cc_cursor) lcursor; return KRB5_OK; } /* * Requires: * cursor is a krb5_cc_cursor originally obtained from * krb5_lcc_start_seq_get. * * Modifies: * cursor * * Effects: * Fills in creds with the TGT obtained from the MS LSA * * The cursor is updated to indicate TGT retrieval * * Errors: * KRB5_CC_END * KRB5_FCC_INTERNAL - system errors */ static krb5_error_code KRB5_CALLCONV krb5_lcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_lcc_cursor *lcursor = (krb5_lcc_cursor *) *cursor; krb5_lcc_data *data; KERB_EXTERNAL_TICKET *msticket; krb5_error_code retval = KRB5_OK; data = (krb5_lcc_data *)id->data; next_cred: if ( does_query_ticket_cache_ex2() ) { if ( lcursor->index >= lcursor->response.ex2->CountOfTickets ) { if (retval == KRB5_OK) return KRB5_CC_END; else { LsaFreeReturnBuffer(lcursor->mstgt); LsaFreeReturnBuffer(lcursor->response.ex2); free(*cursor); *cursor = 0; return retval; } } if ( data->flags & KRB5_TC_NOTICKET ) { if (!CacheInfoEx2ToMITCred( &lcursor->response.ex2->Tickets[lcursor->index++], context, creds)) { retval = KRB5_FCC_INTERNAL; goto next_cred; } return KRB5_OK; } else { if (!GetMSCacheTicketFromCacheInfoEx2(data->LogonHandle, data->PackageId, &lcursor->response.ex2->Tickets[lcursor->index++],&msticket)) { retval = KRB5_FCC_INTERNAL; goto next_cred; } } } else { if (lcursor->index >= lcursor->response.xp->CountOfTickets) { if (retval == KRB5_OK) { return KRB5_CC_END; } else { LsaFreeReturnBuffer(lcursor->mstgt); LsaFreeReturnBuffer(lcursor->response.xp); free(*cursor); *cursor = 0; return retval; } } if (!GetMSCacheTicketFromCacheInfoEx(data->LogonHandle, data->PackageId, &lcursor->response.xp->Tickets[lcursor->index++], &msticket)) { retval = KRB5_FCC_INTERNAL; goto next_cred; } } /* Don't return tickets with NULL Session Keys */ if ( IsMSSessionKeyNull(&msticket->SessionKey) ) { LsaFreeReturnBuffer(msticket); goto next_cred; } /* convert the ticket */ if ( does_query_ticket_cache_ex2() ) { if (!MSCredToMITCred(msticket, lcursor->response.ex2->Tickets[lcursor->index-1].ClientRealm, context, creds)) retval = KRB5_FCC_INTERNAL; } else { if (!MSCredToMITCred(msticket, lcursor->response.xp->Tickets[lcursor->index - 1].ClientRealm, context, creds)) retval = KRB5_FCC_INTERNAL; } LsaFreeReturnBuffer(msticket); return retval; } /* * Requires: * cursor is a krb5_cc_cursor originally obtained from * krb5_lcc_start_seq_get. * * Modifies: * id, cursor * * Effects: * Finishes sequential processing of the file credentials ccache id, * and invalidates the cursor (it must never be used after this call). */ /* ARGSUSED */ static krb5_error_code KRB5_CALLCONV krb5_lcc_end_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { krb5_lcc_cursor *lcursor = (krb5_lcc_cursor *) *cursor; if ( lcursor ) { LsaFreeReturnBuffer(lcursor->mstgt); if ( does_query_ticket_cache_ex2() ) LsaFreeReturnBuffer(lcursor->response.ex2); else LsaFreeReturnBuffer(lcursor->response.xp); free(*cursor); } *cursor = 0; return KRB5_OK; } /* * Errors: * KRB5_CC_READONLY - not supported */ static krb5_error_code KRB5_CALLCONV krb5_lcc_generate_new (krb5_context context, krb5_ccache *id) { return KRB5_CC_READONLY; } /* * Requires: * id is a ms lsa credential cache * * Returns: * The ccname specified during the krb5_lcc_resolve call */ static const char * KRB5_CALLCONV krb5_lcc_get_name (krb5_context context, krb5_ccache id) { if ( !id ) return ""; return (char *) ((krb5_lcc_data *) id->data)->cc_name; } /* * Modifies: * id, princ * * Effects: * Retrieves the primary principal from id, as set with * krb5_lcc_initialize. The principal is returned is allocated * storage that must be freed by the caller via krb5_free_principal. * * Errors: * system errors * KRB5_CC_NOT_KTYPE */ static krb5_error_code KRB5_CALLCONV krb5_lcc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *princ) { PKERB_QUERY_TKT_CACHE_EX_RESPONSE pResponse; krb5_lcc_data *data = (krb5_lcc_data *)id->data; ULONG i; /* obtain principal */ if (data->princ) return krb5_copy_principal(context, data->princ, princ); else { if (GetQueryTktCacheResponseEx(data->LogonHandle, data->PackageId, &pResponse)) { /* Take the first client principal we find; they should all be the * same anyway. */ for (i = 0; i < pResponse->CountOfTickets; i++) { if (UnicodeStringToMITPrinc(&pResponse->Tickets[i].ClientName, &pResponse->Tickets[i].ClientRealm, context, &data->princ)) break; } LsaFreeReturnBuffer(pResponse); if (data->princ) return krb5_copy_principal(context, data->princ, princ); } } return KRB5_CC_NOTFOUND; } static krb5_error_code KRB5_CALLCONV krb5_lcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds) { krb5_error_code kret = KRB5_OK; krb5_lcc_data *data = (krb5_lcc_data *)id->data; KERB_EXTERNAL_TICKET *msticket = 0, *mstgt = 0, *mstmp = 0; krb5_creds * mcreds_noflags = 0; krb5_creds fetchcreds; PKERB_QUERY_TKT_CACHE_EX_RESPONSE pResponse = 0; unsigned int i; memset(&fetchcreds, 0, sizeof(krb5_creds)); /* first try to find out if we have an existing ticket which meets the requirements */ kret = k5_cc_retrieve_cred_default(context, id, whichfields, mcreds, creds); /* This sometimes returns a zero-length ticket; work around it. */ if ( !kret && creds->ticket.length > 0 ) return KRB5_OK; /* if not, we must try to get a ticket without specifying any flags or etypes */ kret = krb5_copy_creds(context, mcreds, &mcreds_noflags); if (kret) goto cleanup; mcreds_noflags->ticket_flags = 0; mcreds_noflags->keyblock.enctype = 0; if (!GetMSCacheTicketFromMITCred(data->LogonHandle, data->PackageId, context, mcreds_noflags, &msticket)) { kret = KRB5_CC_NOTFOUND; goto cleanup; } /* try again to find out if we have an existing ticket which meets the requirements */ kret = k5_cc_retrieve_cred_default(context, id, whichfields, mcreds, creds); /* This sometimes returns a zero-length ticket; work around it. */ if ( !kret && creds->ticket.length > 0 ) goto cleanup; /* if not, obtain a ticket using the request flags and enctype even though it may not * be stored in the LSA cache for future use. */ if ( msticket ) { LsaFreeReturnBuffer(msticket); msticket = 0; } if (!GetMSCacheTicketFromMITCred(data->LogonHandle, data->PackageId, context, mcreds, &msticket)) { kret = KRB5_CC_NOTFOUND; goto cleanup; } /* convert the ticket */ /* * We can obtain the correct client realm for a ticket by walking the * cache contents until we find the matching service ticket. */ if (!GetQueryTktCacheResponseEx(data->LogonHandle, data->PackageId, &pResponse)) { kret = KRB5_FCC_INTERNAL; goto cleanup; } for (i = 0; i < pResponse->CountOfTickets; i++) { if (!GetMSCacheTicketFromCacheInfoEx(data->LogonHandle, data->PackageId, &pResponse->Tickets[i], &mstmp)) { continue; } if (KerbExternalTicketMatch(msticket,mstmp)) break; LsaFreeReturnBuffer(mstmp); mstmp = 0; } if (!MSCredToMITCred(msticket, mstmp ? pResponse->Tickets[i].ClientRealm : msticket->DomainName, context, &fetchcreds)) { LsaFreeReturnBuffer(pResponse); kret = KRB5_FCC_INTERNAL; goto cleanup; } LsaFreeReturnBuffer(pResponse); /* check to see if this ticket matches the request using logic from * k5_cc_retrieve_cred_default() */ if ( krb5int_cc_creds_match_request(context, whichfields, mcreds, &fetchcreds) ) { *creds = fetchcreds; } else { krb5_free_cred_contents(context, &fetchcreds); kret = KRB5_CC_NOTFOUND; } cleanup: if ( mstmp ) LsaFreeReturnBuffer(mstmp); if ( mstgt ) LsaFreeReturnBuffer(mstgt); if ( msticket ) LsaFreeReturnBuffer(msticket); if ( mcreds_noflags ) krb5_free_creds(context, mcreds_noflags); return kret; } /* * We can't write to the MS LSA cache. So we request the cache to obtain a ticket for the same * principal in the hope that next time the application requires a ticket for the service it * is attempt to store, the retrieved ticket will be good enough. * * Errors: * KRB5_CC_READONLY - not supported */ static krb5_error_code KRB5_CALLCONV krb5_lcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) { krb5_error_code kret = KRB5_OK; krb5_lcc_data *data = (krb5_lcc_data *)id->data; KERB_EXTERNAL_TICKET *msticket = 0, *msticket2 = 0; krb5_creds * creds_noflags = 0; if (krb5_is_config_principal(context, creds->server)) { /* mslsa cannot store config creds, so we have to bail. * The 'right' thing to do would be to return an appropriate error, * but that would require modifying the calling code to check * for that error and ignore it. */ return KRB5_OK; } if (KerbSubmitTicket( data->LogonHandle, data->PackageId, context, creds )) return KRB5_OK; /* If not, lets try to obtain a matching ticket from the KDC */ if ( creds->ticket_flags != 0 && creds->keyblock.enctype != 0 ) { /* if not, we must try to get a ticket without specifying any flags or etypes */ kret = krb5_copy_creds(context, creds, &creds_noflags); if (kret == 0) { creds_noflags->ticket_flags = 0; creds_noflags->keyblock.enctype = 0; GetMSCacheTicketFromMITCred(data->LogonHandle, data->PackageId, context, creds_noflags, &msticket2); krb5_free_creds(context, creds_noflags); } } GetMSCacheTicketFromMITCred(data->LogonHandle, data->PackageId, context, creds, &msticket); if (msticket || msticket2) { if (msticket) LsaFreeReturnBuffer(msticket); if (msticket2) LsaFreeReturnBuffer(msticket2); return KRB5_OK; } return KRB5_CC_READONLY; } /* * Individual credentials can be implemented differently depending * on the operating system version. (undocumented.) * * Errors: * KRB5_CC_READONLY: */ static krb5_error_code KRB5_CALLCONV krb5_lcc_remove_cred(krb5_context context, krb5_ccache id, krb5_flags flags, krb5_creds *creds) { krb5_lcc_data *data = (krb5_lcc_data *)id->data; if (PurgeTicketEx(data->LogonHandle, data->PackageId, context, flags, creds)) return KRB5_OK; return KRB5_CC_READONLY; } /* * Effects: * Set */ static krb5_error_code KRB5_CALLCONV krb5_lcc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags) { krb5_lcc_data *data = (krb5_lcc_data *)id->data; data->flags = flags; return KRB5_OK; } static krb5_error_code KRB5_CALLCONV krb5_lcc_get_flags(krb5_context context, krb5_ccache id, krb5_flags *flags) { krb5_lcc_data *data = (krb5_lcc_data *)id->data; *flags = data->flags; return KRB5_OK; } static krb5_error_code KRB5_CALLCONV krb5_lcc_ptcursor_new(krb5_context context, krb5_cc_ptcursor *cursor) { krb5_cc_ptcursor new_cursor = (krb5_cc_ptcursor )malloc(sizeof(*new_cursor)); if (!new_cursor) return ENOMEM; new_cursor->ops = &krb5_lcc_ops; new_cursor->data = (krb5_pointer)(1); *cursor = new_cursor; new_cursor = NULL; return 0; } static krb5_error_code KRB5_CALLCONV krb5_lcc_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor, krb5_ccache *ccache) { krb5_error_code code = 0; *ccache = 0; if (cursor->data == NULL) return 0; cursor->data = NULL; if ((code = krb5_lcc_resolve(context, ccache, ""))) { if (code != KRB5_FCC_NOFILE) /* Note that we only want to return serious errors. * Any non-zero return code will prevent the cccol iterator * from advancing to the next ccache collection. */ return code; } return 0; } static krb5_error_code KRB5_CALLCONV krb5_lcc_ptcursor_free(krb5_context context, krb5_cc_ptcursor *cursor) { if (*cursor) { free(*cursor); *cursor = NULL; } return 0; } const krb5_cc_ops krb5_lcc_ops = { 0, "MSLSA", krb5_lcc_get_name, krb5_lcc_resolve, krb5_lcc_generate_new, krb5_lcc_initialize, krb5_lcc_destroy, krb5_lcc_close, krb5_lcc_store, krb5_lcc_retrieve, krb5_lcc_get_principal, krb5_lcc_start_seq_get, krb5_lcc_next_cred, krb5_lcc_end_seq_get, krb5_lcc_remove_cred, krb5_lcc_set_flags, krb5_lcc_get_flags, krb5_lcc_ptcursor_new, krb5_lcc_ptcursor_next, krb5_lcc_ptcursor_free, NULL, /* move */ NULL, /* wasdefault */ NULL, /* lock */ NULL, /* unlock */ NULL, /* switch_to */ }; #endif /* _WIN32 */ krb5-1.22.1/src/lib/krb5/ccache/ccbase.c0000664000175000017500000003745015051422640017344 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccbase.c - Registration functions for ccache */ /* * Copyright 1990,2004,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "k5-thread.h" #include "fcc.h" #include "cc-int.h" struct krb5_cc_typelist { const krb5_cc_ops *ops; struct krb5_cc_typelist *next; }; struct krb5_cc_typecursor { struct krb5_cc_typelist *tptr; }; /* typedef krb5_cc_typecursor in k5-int.h */ extern const krb5_cc_ops krb5_mcc_ops; #define NEXT NULL #ifdef _WIN32 extern const krb5_cc_ops krb5_lcc_ops; static struct krb5_cc_typelist cc_lcc_entry = { &krb5_lcc_ops, NEXT }; #undef NEXT #define NEXT &cc_lcc_entry #endif #ifdef USE_CCAPI extern const krb5_cc_ops krb5_cc_stdcc_ops; static struct krb5_cc_typelist cc_stdcc_entry = { &krb5_cc_stdcc_ops, NEXT }; #undef NEXT #define NEXT &cc_stdcc_entry #endif static struct krb5_cc_typelist cc_mcc_entry = { &krb5_mcc_ops, NEXT }; #undef NEXT #define NEXT &cc_mcc_entry #ifndef NO_FILE_CCACHE static struct krb5_cc_typelist cc_fcc_entry = { &krb5_cc_file_ops, NEXT }; #undef NEXT #define NEXT &cc_fcc_entry #endif #ifdef USE_KEYRING_CCACHE extern const krb5_cc_ops krb5_krcc_ops; static struct krb5_cc_typelist cc_krcc_entry = { &krb5_krcc_ops, NEXT }; #undef NEXT #define NEXT &cc_krcc_entry #endif /* USE_KEYRING_CCACHE */ #ifndef _WIN32 extern const krb5_cc_ops krb5_dcc_ops; static struct krb5_cc_typelist cc_dcc_entry = { &krb5_dcc_ops, NEXT }; #undef NEXT #define NEXT &cc_dcc_entry extern const krb5_cc_ops krb5_kcm_ops; static struct krb5_cc_typelist cc_kcm_entry = { &krb5_kcm_ops, NEXT }; #undef NEXT #define NEXT &cc_kcm_entry #endif /* not _WIN32 */ #ifdef USE_CCAPI_MACOS extern const krb5_cc_ops krb5_api_macos_ops; static struct krb5_cc_typelist cc_macos_entry = { &krb5_api_macos_ops, NEXT }; #undef NEXT #define NEXT &cc_macos_entry #endif /* USE_CCAPI_MACOS */ #define INITIAL_TYPEHEAD (NEXT) static struct krb5_cc_typelist *cc_typehead = INITIAL_TYPEHEAD; static k5_mutex_t cc_typelist_lock = K5_MUTEX_PARTIAL_INITIALIZER; /* mutex for krb5_cccol_[un]lock */ static k5_cc_mutex cccol_lock = K5_CC_MUTEX_PARTIAL_INITIALIZER; static krb5_error_code krb5int_cc_getops(krb5_context, const char *, const krb5_cc_ops **); int krb5int_cc_initialize(void) { int err; err = k5_cc_mutex_finish_init(&cccol_lock); if (err) return err; err = k5_cc_mutex_finish_init(&krb5int_mcc_mutex); if (err) return err; err = k5_mutex_finish_init(&cc_typelist_lock); if (err) return err; #ifndef NO_FILE_CCACHE err = k5_cc_mutex_finish_init(&krb5int_cc_file_mutex); if (err) return err; #endif #ifdef USE_KEYRING_CCACHE err = k5_cc_mutex_finish_init(&krb5int_krcc_mutex); if (err) return err; #endif return 0; } void krb5int_cc_finalize(void) { struct krb5_cc_typelist *t, *t_next; k5_cccol_force_unlock(); k5_cc_mutex_destroy(&cccol_lock); k5_mutex_destroy(&cc_typelist_lock); #ifndef NO_FILE_CCACHE k5_cc_mutex_destroy(&krb5int_cc_file_mutex); #endif k5_cc_mutex_destroy(&krb5int_mcc_mutex); #ifdef USE_KEYRING_CCACHE k5_cc_mutex_destroy(&krb5int_krcc_mutex); #endif for (t = cc_typehead; t != INITIAL_TYPEHEAD; t = t_next) { t_next = t->next; free(t); } } /* * Register a new credentials cache type * If override is set, replace any existing ccache with that type tag */ krb5_error_code KRB5_CALLCONV krb5_cc_register(krb5_context context, const krb5_cc_ops *ops, krb5_boolean override) { struct krb5_cc_typelist *t; k5_mutex_lock(&cc_typelist_lock); for (t = cc_typehead;t && strcmp(t->ops->prefix,ops->prefix);t = t->next) ; if (t) { if (override) { t->ops = ops; k5_mutex_unlock(&cc_typelist_lock); return 0; } else { k5_mutex_unlock(&cc_typelist_lock); return KRB5_CC_TYPE_EXISTS; } } if (!(t = (struct krb5_cc_typelist *) malloc(sizeof(*t)))) { k5_mutex_unlock(&cc_typelist_lock); return ENOMEM; } t->next = cc_typehead; t->ops = ops; cc_typehead = t; k5_mutex_unlock(&cc_typelist_lock); return 0; } /* * Resolve a credential cache name into a cred. cache object. * * The name is currently constrained to be of the form "type:residual"; * * The "type" portion corresponds to one of the predefined credential * cache types, while the "residual" portion is specific to the * particular cache type. */ #include krb5_error_code KRB5_CALLCONV krb5_cc_resolve (krb5_context context, const char *name, krb5_ccache *cache) { char *pfx, *cp; const char *resid; unsigned int pfxlen; krb5_error_code err; const krb5_cc_ops *ops; if (name == NULL) return KRB5_CC_BADNAME; pfx = NULL; cp = strchr (name, ':'); if (!cp) { if (krb5_cc_dfl_ops) return (*krb5_cc_dfl_ops->resolve)(context, cache, name); else return KRB5_CC_BADNAME; } pfxlen = cp - name; if ( pfxlen == 1 && isalpha((unsigned char) name[0]) ) { /* We found a drive letter not a prefix - use FILE */ pfx = strdup("FILE"); if (!pfx) return ENOMEM; resid = name; } else { resid = name + pfxlen + 1; pfx = k5memdup0(name, pfxlen, &err); if (pfx == NULL) return err; } *cache = (krb5_ccache) 0; err = krb5int_cc_getops(context, pfx, &ops); if (pfx != NULL) free(pfx); if (err) return err; return ops->resolve(context, cache, resid); } krb5_error_code KRB5_CALLCONV krb5_cc_dup(krb5_context context, krb5_ccache in, krb5_ccache *out) { return in->ops->resolve(context, out, in->ops->get_name(context, in)); } /* * cc_getops * * Internal function to return the ops vector for a given ccache * prefix string. */ static krb5_error_code krb5int_cc_getops(krb5_context context, const char *pfx, const krb5_cc_ops **ops) { struct krb5_cc_typelist *tlist; k5_mutex_lock(&cc_typelist_lock); for (tlist = cc_typehead; tlist; tlist = tlist->next) { if (strcmp (tlist->ops->prefix, pfx) == 0) { *ops = tlist->ops; k5_mutex_unlock(&cc_typelist_lock); return 0; } } k5_mutex_unlock(&cc_typelist_lock); if (krb5_cc_dfl_ops && !strcmp (pfx, krb5_cc_dfl_ops->prefix)) { *ops = krb5_cc_dfl_ops; return 0; } return KRB5_CC_UNKNOWN_TYPE; } /* * cc_new_unique * * Generate a new unique ccache, given a ccache type and a hint * string. Ignores the hint string for now. */ krb5_error_code KRB5_CALLCONV krb5_cc_new_unique( krb5_context context, const char *type, const char *hint, krb5_ccache *id) { const krb5_cc_ops *ops; krb5_error_code err; *id = NULL; TRACE_CC_NEW_UNIQUE(context, type); err = krb5int_cc_getops(context, type, &ops); if (err) return err; return ops->gen_new(context, id); } /* * cc_typecursor * * Note: to avoid copying the typelist at cursor creation time, among * other things, we assume that the only additions ever occur to the * typelist. */ krb5_error_code krb5int_cc_typecursor_new(krb5_context context, krb5_cc_typecursor *t) { krb5_cc_typecursor n = NULL; *t = NULL; n = malloc(sizeof(*n)); if (n == NULL) return ENOMEM; k5_mutex_lock(&cc_typelist_lock); n->tptr = cc_typehead; k5_mutex_unlock(&cc_typelist_lock); *t = n; return 0; } krb5_error_code krb5int_cc_typecursor_next(krb5_context context, krb5_cc_typecursor t, const krb5_cc_ops **ops) { *ops = NULL; if (t->tptr == NULL) return 0; k5_mutex_lock(&cc_typelist_lock); *ops = t->tptr->ops; t->tptr = t->tptr->next; k5_mutex_unlock(&cc_typelist_lock); return 0; } krb5_error_code krb5int_cc_typecursor_free(krb5_context context, krb5_cc_typecursor *t) { free(*t); *t = NULL; return 0; } krb5_error_code k5_nonatomic_replace(krb5_context context, krb5_ccache ccache, krb5_principal princ, krb5_creds **creds) { krb5_error_code ret; int i; ret = krb5_cc_initialize(context, ccache, princ); for (i = 0; !ret && creds[i] != NULL; creds++) ret = krb5_cc_store_cred(context, ccache, creds[i]); return ret; } static krb5_error_code read_creds(krb5_context context, krb5_ccache ccache, krb5_creds ***creds_out) { krb5_error_code ret; krb5_cc_cursor cur = NULL; krb5_creds **list = NULL, *cred = NULL, **newptr; int i; *creds_out = NULL; ret = krb5_cc_start_seq_get(context, ccache, &cur); if (ret) goto cleanup; /* Allocate one extra entry so that list remains valid for freeing after * we add the next entry and before we reallocate it. */ list = k5calloc(2, sizeof(*list), &ret); if (list == NULL) goto cleanup; i = 0; for (;;) { cred = k5alloc(sizeof(*cred), &ret); if (cred == NULL) goto cleanup; ret = krb5_cc_next_cred(context, ccache, &cur, cred); if (ret == KRB5_CC_END) break; if (ret) goto cleanup; list[i++] = cred; list[i] = NULL; cred = NULL; newptr = realloc(list, (i + 2) * sizeof(*list)); if (newptr == NULL) { ret = ENOMEM; goto cleanup; } list = newptr; list[i + 1] = NULL; } ret = 0; *creds_out = list; list = NULL; cleanup: if (cur != NULL) (void)krb5_cc_end_seq_get(context, ccache, &cur); krb5_free_tgt_creds(context, list); free(cred); return ret; } krb5_error_code KRB5_CALLCONV krb5_cc_move(krb5_context context, krb5_ccache src, krb5_ccache dst) { krb5_error_code ret; krb5_principal princ = NULL; krb5_creds **creds = NULL; TRACE_CC_MOVE(context, src, dst); ret = krb5_cc_get_principal(context, src, &princ); if (ret) goto cleanup; ret = read_creds(context, src, &creds); if (ret) goto cleanup; if (dst->ops->replace == NULL) ret = k5_nonatomic_replace(context, dst, princ, creds); else ret = dst->ops->replace(context, dst, princ, creds); if (ret) goto cleanup; ret = krb5_cc_destroy(context, src); cleanup: krb5_free_principal(context, princ); krb5_free_tgt_creds(context, creds); return ret; } krb5_boolean KRB5_CALLCONV krb5_cc_support_switch(krb5_context context, const char *type) { const krb5_cc_ops *ops; krb5_error_code err; err = krb5int_cc_getops(context, type, &ops); return (err ? FALSE : (ops->switch_to != NULL)); } krb5_error_code k5_cc_mutex_init(k5_cc_mutex *m) { krb5_error_code ret = 0; ret = k5_mutex_init(&m->lock); if (ret) return ret; m->owner = NULL; m->refcount = 0; return ret; } krb5_error_code k5_cc_mutex_finish_init(k5_cc_mutex *m) { krb5_error_code ret = 0; ret = k5_mutex_finish_init(&m->lock); if (ret) return ret; m->owner = NULL; m->refcount = 0; return ret; } void k5_cc_mutex_assert_locked(krb5_context context, k5_cc_mutex *m) { #ifdef DEBUG_THREADS assert(m->refcount > 0); assert(m->owner == context); #endif k5_assert_locked(&m->lock); } void k5_cc_mutex_assert_unlocked(krb5_context context, k5_cc_mutex *m) { #ifdef DEBUG_THREADS assert(m->refcount == 0); assert(m->owner == NULL); #endif k5_assert_unlocked(&m->lock); } void k5_cc_mutex_lock(krb5_context context, k5_cc_mutex *m) { /* not locked or already locked by another context */ if (m->owner != context) { /* acquire lock, blocking until available */ k5_mutex_lock(&m->lock); m->owner = context; m->refcount = 1; } /* already locked by this context, just increase refcount */ else { m->refcount++; } } void k5_cc_mutex_unlock(krb5_context context, k5_cc_mutex *m) { /* verify owner and sanity check refcount */ if ((m->owner != context) || (m->refcount < 1)) { return; } /* decrement & unlock when count reaches zero */ m->refcount--; if (m->refcount == 0) { m->owner = NULL; k5_mutex_unlock(&m->lock); } } /* necessary to make reentrant locks play nice with krb5int_cc_finalize */ void k5_cc_mutex_force_unlock(k5_cc_mutex *m) { m->refcount = 0; m->owner = NULL; if (m->refcount > 0) { k5_mutex_unlock(&m->lock); } } /* * holds on to all pertype global locks as well as typelist lock */ krb5_error_code k5_cccol_lock(krb5_context context) { krb5_error_code ret = 0; k5_cc_mutex_lock(context, &cccol_lock); k5_mutex_lock(&cc_typelist_lock); k5_cc_mutex_lock(context, &krb5int_cc_file_mutex); k5_cc_mutex_lock(context, &krb5int_mcc_mutex); #ifdef USE_KEYRING_CCACHE k5_cc_mutex_lock(context, &krb5int_krcc_mutex); #endif #ifdef USE_CCAPI ret = krb5_stdccv3_context_lock(context); if (ret) { k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); k5_cc_mutex_unlock(context, &krb5int_cc_file_mutex); k5_mutex_unlock(&cc_typelist_lock); k5_cc_mutex_unlock(context, &cccol_lock); return ret; } #endif k5_mutex_unlock(&cc_typelist_lock); return ret; } krb5_error_code k5_cccol_unlock(krb5_context context) { krb5_error_code ret = 0; /* sanity check */ k5_cc_mutex_assert_locked(context, &cccol_lock); k5_mutex_lock(&cc_typelist_lock); /* unlock each type in the opposite order */ #ifdef USE_CCAPI krb5_stdccv3_context_unlock(context); #endif #ifdef USE_KEYRING_CCACHE k5_cc_mutex_assert_locked(context, &krb5int_krcc_mutex); k5_cc_mutex_unlock(context, &krb5int_krcc_mutex); #endif k5_cc_mutex_assert_locked(context, &krb5int_mcc_mutex); k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); k5_cc_mutex_assert_locked(context, &krb5int_cc_file_mutex); k5_cc_mutex_unlock(context, &krb5int_cc_file_mutex); k5_mutex_assert_locked(&cc_typelist_lock); k5_mutex_unlock(&cc_typelist_lock); k5_cc_mutex_unlock(context, &cccol_lock); return ret; } /* necessary to make reentrant locks play nice with krb5int_cc_finalize */ void k5_cccol_force_unlock(void) { /* sanity check */ if ((&cccol_lock)->refcount == 0) { return; } k5_mutex_lock(&cc_typelist_lock); /* unlock each type in the opposite order */ #ifdef USE_KEYRING_CCACHE k5_cc_mutex_force_unlock(&krb5int_krcc_mutex); #endif #ifdef USE_CCAPI krb5_stdccv3_context_unlock(NULL); #endif k5_cc_mutex_force_unlock(&krb5int_mcc_mutex); k5_cc_mutex_force_unlock(&krb5int_cc_file_mutex); k5_mutex_unlock(&cc_typelist_lock); k5_cc_mutex_force_unlock(&cccol_lock); } krb5-1.22.1/src/lib/krb5/ccache/kcmrpc.defs0000664000175000017500000000474615051422640020104 0ustar ghudsonghudson/* * Copyright (c) 2009 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Portions Copyright (c) 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include type k5_kcm_inband_msg = array [ * : 2048 ] of char; type k5_kcm_outband_msg = array [] of char; import "kcmrpc_types.h"; subsystem mheim_ipc 1; userprefix k5_kcmrpc_; serverprefix k5_kcmrpc_server_; routine call( server_port : mach_port_t; ServerAuditToken client_creds : audit_token_t; sreplyport reply_port : mach_port_make_send_once_t; in requestin : k5_kcm_inband_msg; in requestout : k5_kcm_outband_msg; out returnvalue : int; out replyin : k5_kcm_inband_msg; out replyout : k5_kcm_outband_msg, dealloc); krb5-1.22.1/src/lib/krb5/ccache/Makefile.in0000664000175000017500000000761215051422640020022 0ustar ghudsonghudsonmydir=lib$(S)krb5$(S)ccache BUILDTOP=$(REL)..$(S)..$(S).. SUBDIRS = # ccapi WINSUBDIRS = ccapi ##WIN32##DEFINES = -DUSE_CCAPI LOCALINCLUDES = -I$(srcdir)$(S)ccapi -I$(srcdir) -I. ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=ccache ##DOS##OBJFILE=..\$(OUTPRE)$(PREFIXDIR).lst ##WIN32##MSLSA_OBJ = $(OUTPRE)cc_mslsa.$(OBJEXT) ##WIN32##MSLSA_SRC = $(srcdir)/cc_mslsa.c ##WIN32##!if 0 KCMRPC_DEPS-osx = kcmrpc.h kcmrpc_types.h KCMRPC_OBJ-osx = kcmrpc.o KCMRPC_DEPS-no = # empty KCMRPC_OBJ-no = # empty KCMRPC_DEPS = $(KCMRPC_DEPS-@OSX@) KCMRPC_OBJ = $(KCMRPC_OBJ-@OSX@) ##WIN32##!endif STLIBOBJS= \ ccapi_util.o \ ccbase.o \ cccopy.o \ cccursor.o \ ccdefault.o \ ccdefops.o \ ccmarshal.o \ ccselect.o \ ccselect_hostname.o \ ccselect_k5identity.o \ ccselect_realm.o \ cc_api_macos.o \ cc_dir.o \ cc_retr.o \ cc_file.o \ cc_kcm.o \ cc_memory.o \ cc_keyring.o \ ccfns.o \ $(KCMRPC_OBJ) OBJS= $(OUTPRE)ccapi_util.$(OBJEXT) \ $(OUTPRE)ccbase.$(OBJEXT) \ $(OUTPRE)cccopy.$(OBJEXT) \ $(OUTPRE)cccursor.$(OBJEXT) \ $(OUTPRE)ccdefault.$(OBJEXT) \ $(OUTPRE)ccdefops.$(OBJEXT) \ $(OUTPRE)ccmarshal.$(OBJEXT) \ $(OUTPRE)ccselect.$(OBJEXT) \ $(OUTPRE)ccselect_hostname.$(OBJEXT) \ $(OUTPRE)ccselect_k5identity.$(OBJEXT) \ $(OUTPRE)ccselect_realm.$(OBJEXT) \ $(OUTPRE)cc_api_macos.$(OBJEXT) \ $(OUTPRE)cc_dir.$(OBJEXT) \ $(OUTPRE)cc_retr.$(OBJEXT) \ $(OUTPRE)cc_file.$(OBJEXT) \ $(OUTPRE)cc_kcm.$(OBJEXT) \ $(OUTPRE)cc_memory.$(OBJEXT) \ $(OUTPRE)cc_keyring.$(OBJEXT) \ $(OUTPRE)ccfns.$(OBJEXT) \ $(MSLSA_OBJ) SRCS= $(srcdir)/ccapi_util.c \ $(srcdir)/ccbase.c \ $(srcdir)/cccopy.c \ $(srcdir)/cccursor.c \ $(srcdir)/ccdefault.c \ $(srcdir)/ccdefops.c \ $(srcdir)/ccmarshal.c \ $(srcdir)/ccselect.c \ $(srcdir)/ccselect_hostname.c \ $(srcdir)/ccselect_k5identity.c \ $(srcdir)/ccselect_realm.c \ $(srcdir)/cc_api_macos.c \ $(srcdir)/cc_dir.c \ $(srcdir)/cc_retr.c \ $(srcdir)/cc_file.c \ $(srcdir)/cc_kcm.c \ $(srcdir)/cc_memory.c \ $(srcdir)/cc_keyring.c \ $(srcdir)/ccfns.c \ $(MSLSA_SRC) EXTRADEPSRCS= \ $(srcdir)/t_cc.c \ $(srcdir)/t_cccol.c \ $(srcdir)/t_cccursor.c \ $(srcdir)/t_marshal.c ##DOS##OBJS=$(OBJS) $(OUTPRE)ccfns.$(OBJEXT) all-unix: all-libobjs all-windows: subdirs $(OBJFILE) ##DOS##subdirs: ccapi\$(OUTPRE)file.lst ##DOS##ccapi\$(OUTPRE)file.lst: ##DOS## cd ccapi ##DOS## @echo Making in krb5\ccache\ccapi ##DOS## $(MAKE) -$(MFLAGS) ##DOS## cd .. ##DOS##$(OBJFILE): $(OBJS) ccapi\$(OUTPRE)file.lst ##DOS## $(RM) $(OBJFILE) ##WIN32## $(LIBECHO) -p $(PREFIXDIR)\ $(OUTPRE)*.obj \ ##WIN32## ccapi\$(OUTPRE)*.obj > $(OBJFILE) kcmrpc.h kcmrpc.c: kcmrpc.defs mig -header kcmrpc.h -user kcmrpc.c -sheader /dev/null \ -server /dev/null -I$(srcdir) $(srcdir)/kcmrpc.defs clean-unix:: clean-libobjs clean-windows:: cd ccapi @echo Making clean in krb5\ccache\ccapi $(MAKE) -$(MFLAGS) clean cd .. @echo Making clean in krb5\ccache $(RM) $(OBJFILE) T_CC_OBJS=t_cc.o t_cc: $(T_CC_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_cc $(T_CC_OBJS) $(KRB5_BASE_LIBS) T_CCCOL_OBJS = t_cccol.o t_cccol: $(T_CCCOL_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ $(T_CCCOL_OBJS) $(KRB5_BASE_LIBS) T_CCCURSOR_OBJS = t_cccursor.o t_cccursor: $(T_CCCURSOR_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ $(T_CCCURSOR_OBJS) $(KRB5_BASE_LIBS) T_MARSHAL_OBJS = t_marshal.o t_marshal: $(T_MARSHAL_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ $(T_MARSHAL_OBJS) $(KRB5_BASE_LIBS) check-unix: t_cc t_marshal $(RUN_TEST) ./t_cc $(RUN_TEST) ./t_marshal testcache check-pytests: t_cccursor t_cccol $(RUNPYTEST) $(srcdir)/t_cccol.py $(PYTESTFLAGS) clean-unix:: $(RM) t_cc t_cc.o t_cccursor t_cccursor.o t_cccol t_cccol.o $(RM) t_marshal t_marshal.o testcache kcmrpc.c kcmrpc.h depend: $(KCMRPC_DEPS) ##WIN32##$(OUTPRE)cc_mslsa.$(OBJEXT): cc_mslsa.c $(top_srcdir)/include/k5-int.h $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) cc_kcm.so cc_kcm.o: $(KCMRPC_DEPS) kcmrpc.so kcmrpc.o: kcmrpc.h kcmrpc_types.h @libobj_frag@ krb5-1.22.1/src/lib/krb5/ccache/t_marshal.c0000664000175000017500000004310415051422640020067 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/t_marshal.c - test program for cred marshalling */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cc-int.h" #include #include #include #include /* * Versions 1 and 2 of the ccache format use native byte order representations * of integers. The test data below is from a little-endian platform. Skip * those tests on big-endian platforms by starting at version 3. */ #ifdef K5_BE #define FIRST_VERSION 3 #else #define FIRST_VERSION 1 #endif /* Each test contains the expected binary representation of a credential cache * divided into the header, the default principal, and two credentials. */ const struct test { size_t headerlen; const unsigned char header[256]; size_t princlen; const unsigned char princ[256]; size_t cred1len; const unsigned char cred1[256]; size_t cred2len; const unsigned char cred2[256]; } tests[4] = { { /* Version 1 header */ 2, "\x05\x01", /* Version 1 principal */ 33, "\x02\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54\x45\x53\x54\x2E" "\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63\x6C\x69\x65\x6E" "\x74", /* Version 1 cred 1 */ 165, "\x02\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54\x45\x53\x54\x2E" "\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63\x6C\x69\x65\x6E" "\x74\x03\x00\x00\x00\x0B\x00\x00\x00\x45\x58\x41\x4D\x50\x4C\x45" "\x2E\x43\x4F\x4D\x04\x00\x00\x00\x74\x65\x73\x74\x04\x00\x00\x00" "\x68\x6F\x73\x74\x11\x00\x10\x00\x00\x00\x00\x01\x02\x03\x04\x05" "\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x0B\x00\x00\x00\xDE\x00" "\x00\x00\x05\x0D\x00\x00\x00\xCA\x9A\x3B\x00\x00\x00\x80\x40\x01" "\x00\x00\x00\x02\x00\x04\x00\x00\x00\x0A\x00\x00\x01\x02\x00\x00" "\x00\x00\x02\x0A\x00\x00\x00\x73\x69\x67\x6E\x74\x69\x63\x6B\x65" "\x74\x9C\xFF\x00\x00\x00\x00\x06\x00\x00\x00\x74\x69\x63\x6B\x65" "\x74\x00\x00\x00\x00", /* Version 1 cred 2 */ 113, "\x02\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54\x45\x53\x54\x2E" "\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63\x6C\x69\x65\x6E" "\x74\x01\x00\x00\x00\x00\x00\x00\x00\x17\x00\x10\x00\x00\x00\x0F" "\x0E\x0D\x0C\x0B\x0A\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00" "\x74\x69\x63\x6B\x65\x74\x07\x00\x00\x00\x32\x74\x69\x63\x6B\x65" "\x74" }, { /* Version 2 header */ 2, "\x05\x02", /* Version 2 principal */ 37, "\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54" "\x45\x53\x54\x2E\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63" "\x6C\x69\x65\x6E\x74", /* Version 2 cred 1 */ 173, "\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54" "\x45\x53\x54\x2E\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63" "\x6C\x69\x65\x6E\x74\x01\x00\x00\x00\x02\x00\x00\x00\x0B\x00\x00" "\x00\x45\x58\x41\x4D\x50\x4C\x45\x2E\x43\x4F\x4D\x04\x00\x00\x00" "\x74\x65\x73\x74\x04\x00\x00\x00\x68\x6F\x73\x74\x11\x00\x10\x00" "\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D" "\x0E\x0F\x0B\x00\x00\x00\xDE\x00\x00\x00\x05\x0D\x00\x00\x00\xCA" "\x9A\x3B\x00\x00\x00\x80\x40\x01\x00\x00\x00\x02\x00\x04\x00\x00" "\x00\x0A\x00\x00\x01\x02\x00\x00\x00\x00\x02\x0A\x00\x00\x00\x73" "\x69\x67\x6E\x74\x69\x63\x6B\x65\x74\x9C\xFF\x00\x00\x00\x00\x06" "\x00\x00\x00\x74\x69\x63\x6B\x65\x74\x00\x00\x00\x00", /* Version 2 cred 2 */ 121, "\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x00\x00\x00\x4B\x52\x42\x54" "\x45\x53\x54\x2E\x43\x4F\x4D\x0A\x00\x00\x00\x74\x65\x73\x74\x63" "\x6C\x69\x65\x6E\x74\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x17\x00\x10\x00\x00\x00\x0F\x0E\x0D\x0C\x0B\x0A\x09\x08\x07" "\x06\x05\x04\x03\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x06\x00\x00\x00\x74\x69\x63\x6B\x65\x74\x07\x00" "\x00\x00\x32\x74\x69\x63\x6B\x65\x74" }, { /* Version 3 header */ 2, "\x05\x03", /* Version 3 principal */ 37, "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54" "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63" "\x6C\x69\x65\x6E\x74", /* Version 3 cred 1 */ 175, "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54" "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63" "\x6C\x69\x65\x6E\x74\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00" "\x0B\x45\x58\x41\x4D\x50\x4C\x45\x2E\x43\x4F\x4D\x00\x00\x00\x04" "\x74\x65\x73\x74\x00\x00\x00\x04\x68\x6F\x73\x74\x00\x11\x00\x11" "\x00\x00\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B" "\x0C\x0D\x0E\x0F\x00\x00\x00\x0B\x00\x00\x00\xDE\x00\x00\x0D\x05" "\x3B\x9A\xCA\x00\x00\x40\x80\x00\x00\x00\x00\x00\x01\x00\x02\x00" "\x00\x00\x04\x0A\x00\x00\x01\x00\x00\x00\x02\x02\x00\x00\x00\x00" "\x0A\x73\x69\x67\x6E\x74\x69\x63\x6B\x65\x74\xFF\x9C\x00\x00\x00" "\x00\x00\x00\x00\x06\x74\x69\x63\x6B\x65\x74\x00\x00\x00\x00", /* Version 3 cred 2 */ 123, "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54" "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63" "\x6C\x69\x65\x6E\x74\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x17\x00\x17\x00\x00\x00\x10\x0F\x0E\x0D\x0C\x0B\x0A\x09" "\x08\x07\x06\x05\x04\x03\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x74\x69\x63\x6B\x65\x74" "\x00\x00\x00\x07\x32\x74\x69\x63\x6B\x65\x74" }, { /* Version 4 header */ 16, "\x05\x04\x00\x0C\x00\x01\x00\x08\x00\x00\x01\x2C\x00\x00\xD4\x31", /* Version 4 principal */ 37, "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54" "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63" "\x6C\x69\x65\x6E\x74", /* Version 4 cred 1 */ 173, "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54" "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63" "\x6C\x69\x65\x6E\x74\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00" "\x0B\x45\x58\x41\x4D\x50\x4C\x45\x2E\x43\x4F\x4D\x00\x00\x00\x04" "\x74\x65\x73\x74\x00\x00\x00\x04\x68\x6F\x73\x74\x00\x11\x00\x00" "\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D" "\x0E\x0F\x00\x00\x00\x0B\x00\x00\x00\xDE\x00\x00\x0D\x05\x3B\x9A" "\xCA\x00\x00\x40\x80\x00\x00\x00\x00\x00\x01\x00\x02\x00\x00\x00" "\x04\x0A\x00\x00\x01\x00\x00\x00\x02\x02\x00\x00\x00\x00\x0A\x73" "\x69\x67\x6E\x74\x69\x63\x6B\x65\x74\xFF\x9C\x00\x00\x00\x00\x00" "\x00\x00\x06\x74\x69\x63\x6B\x65\x74\x00\x00\x00\x00", /* Version 4 cred 2 */ 121, "\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0B\x4B\x52\x42\x54" "\x45\x53\x54\x2E\x43\x4F\x4D\x00\x00\x00\x0A\x74\x65\x73\x74\x63" "\x6C\x69\x65\x6E\x74\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x17\x00\x00\x00\x10\x0F\x0E\x0D\x0C\x0B\x0A\x09\x08\x07" "\x06\x05\x04\x03\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x06\x74\x69\x63\x6B\x65\x74\x00\x00" "\x00\x07\x32\x74\x69\x63\x6B\x65\x74" } }; static void verify_princ(krb5_principal p) { assert(p->length == 1); assert(data_eq_string(p->realm, "KRBTEST.COM")); assert(data_eq_string(p->data[0], "testclient")); } static void verify_cred1(const krb5_creds *c) { uint32_t ipaddr = ntohl(0x0A000001); verify_princ(c->client); assert(c->server->length == 2); assert(data_eq_string(c->server->realm, "EXAMPLE.COM")); assert(data_eq_string(c->server->data[0], "test")); assert(data_eq_string(c->server->data[1], "host")); assert(c->keyblock.enctype == ENCTYPE_AES128_CTS_HMAC_SHA1_96); assert(c->keyblock.length == 16); assert(memcmp(c->keyblock.contents, "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF", 16) == 0); assert(c->times.authtime == 11); assert(c->times.starttime == 222); assert(c->times.endtime == 3333); assert(c->times.renew_till == 1000000000); assert(c->is_skey == FALSE); assert(c->ticket_flags == (TKT_FLG_FORWARDABLE | TKT_FLG_RENEWABLE)); assert(c->addresses != NULL && c->addresses[0] != NULL); assert(c->addresses[0]->addrtype == ADDRTYPE_INET); assert(c->addresses[0]->length == 4); assert(memcmp(c->addresses[0]->contents, &ipaddr, 4) == 0); assert(c->addresses[1] == NULL); assert(c->authdata != NULL && c->authdata[0] != NULL); assert(c->authdata[0]->ad_type == KRB5_AUTHDATA_SIGNTICKET); assert(c->authdata[0]->length == 10); assert(memcmp(c->authdata[0]->contents, "signticket", 10) == 0); assert(c->authdata[1] != NULL); assert(c->authdata[1]->ad_type == -100); assert(c->authdata[1]->length == 0); assert(c->authdata[2] == NULL); assert(data_eq_string(c->ticket, "ticket")); assert(c->second_ticket.length == 0); } static void verify_cred2(const krb5_creds *c) { verify_princ(c->client); assert(c->server->length == 0); assert(c->server->realm.length == 0); assert(c->keyblock.enctype == ENCTYPE_ARCFOUR_HMAC); assert(c->keyblock.length == 16); assert(memcmp(c->keyblock.contents, "\xF\xE\xD\xC\xB\xA\x9\x8\x7\x6\x5\x4\x3\x2\x1\x0", 16) == 0); assert(c->times.authtime == 0); assert(c->times.starttime == 0); assert(c->times.endtime == 0); assert(c->times.renew_till == 0); assert(c->is_skey == TRUE); assert(c->ticket_flags == 0); assert(c->addresses == NULL || c->addresses[0] == NULL); assert(c->authdata == NULL || c->authdata[0] == NULL); assert(data_eq_string(c->ticket, "ticket")); assert(data_eq_string(c->second_ticket, "2ticket")); } int main(int argc, char **argv) { krb5_context context; krb5_ccache cache; krb5_principal princ; krb5_creds cred1, cred2, *alloc_cred; krb5_cc_cursor cursor; const char *filename; char *ccname, filebuf[256]; int version, fd; const struct test *t; struct k5buf buf; krb5_data ser_data, *alloc_data; if (argc != 2) abort(); filename = argv[1]; if (asprintf(&ccname, "FILE:%s", filename) == -1) abort(); if (krb5_init_context(&context) != 0) abort(); /* Test public functions for unmarshalling and marshalling. */ ser_data = make_data((char *)tests[3].cred1, tests[3].cred1len); if (krb5_unmarshal_credentials(context, &ser_data, &alloc_cred) != 0) abort(); verify_cred1(alloc_cred); if (krb5_marshal_credentials(context, alloc_cred, &alloc_data) != 0) abort(); assert(alloc_data->length == tests[3].cred1len); assert(memcmp(tests[3].cred1, alloc_data->data, alloc_data->length) == 0); krb5_free_data(context, alloc_data); krb5_free_creds(context, alloc_cred); for (version = FIRST_VERSION; version <= 4; version++) { t = &tests[version - 1]; /* Test principal unmarshalling and marshalling. */ if (k5_unmarshal_princ(t->princ, t->princlen, version, &princ) != 0) abort(); verify_princ(princ); k5_buf_init_dynamic(&buf); k5_marshal_princ(&buf, version, princ); assert(buf.len == t->princlen); assert(memcmp(t->princ, buf.data, buf.len) == 0); k5_buf_free(&buf); /* Test cred1 unmarshalling and marshalling. */ if (k5_unmarshal_cred(t->cred1, t->cred1len, version, &cred1) != 0) abort(); verify_cred1(&cred1); k5_buf_init_dynamic(&buf); k5_marshal_cred(&buf, version, &cred1); assert(buf.len == t->cred1len); assert(memcmp(t->cred1, buf.data, buf.len) == 0); k5_buf_free(&buf); /* Test cred2 unmarshalling and marshalling. */ if (k5_unmarshal_cred(t->cred2, t->cred2len, version, &cred2) != 0) abort(); verify_cred2(&cred2); k5_buf_init_dynamic(&buf); k5_marshal_cred(&buf, version, &cred2); assert(buf.len == t->cred2len); assert(memcmp(t->cred2, buf.data, buf.len) == 0); k5_buf_free(&buf); /* Write a ccache containing the principal and creds. Use the same * time offset as the version 4 test data used. */ context->fcc_default_format = 0x0500 + version; context->os_context.time_offset = 300; context->os_context.usec_offset = 54321; context->os_context.os_flags = KRB5_OS_TOFFSET_VALID; if (krb5_cc_resolve(context, ccname, &cache) != 0) abort(); if (krb5_cc_initialize(context, cache, princ) != 0) abort(); if (krb5_cc_store_cred(context, cache, &cred1) != 0) abort(); if (krb5_cc_store_cred(context, cache, &cred2) != 0) abort(); if (krb5_cc_close(context, cache) != 0) abort(); /* Verify the cache representation against the test data. */ fd = open(filename, O_RDONLY); if (fd == -1) abort(); if (read(fd, filebuf, t->headerlen) != (ssize_t)t->headerlen) abort(); assert(memcmp(filebuf, t->header, t->headerlen) == 0); if (read(fd, filebuf, t->princlen) != (ssize_t)t->princlen) abort(); assert(memcmp(filebuf, t->princ, t->princlen) == 0); if (read(fd, filebuf, t->cred1len) != (ssize_t)t->cred1len) abort(); assert(memcmp(filebuf, t->cred1, t->cred1len) == 0); if (read(fd, filebuf, t->cred2len) != (ssize_t)t->cred2len) abort(); assert(memcmp(filebuf, t->cred2, t->cred2len) == 0); close(fd); krb5_free_principal(context, princ); krb5_free_cred_contents(context, &cred1); krb5_free_cred_contents(context, &cred2); /* Write a cache containing the test data. */ fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0700); if (fd == -1) abort(); if (write(fd, t->header, t->headerlen) != (ssize_t)t->headerlen) abort(); if (write(fd, t->princ, t->princlen) != (ssize_t)t->princlen) abort(); if (write(fd, t->cred1, t->cred1len) != (ssize_t)t->cred1len) abort(); if (write(fd, t->cred2, t->cred2len) != (ssize_t)t->cred2len) abort(); close(fd); /* Read the cache and verify that it matches. */ if (krb5_cc_resolve(context, ccname, &cache) != 0) abort(); if (krb5_cc_get_principal(context, cache, &princ) != 0) abort(); /* Not every version stores the time offset, but at least it shouldn't * have changed from when we set it before. */ assert(context->os_context.time_offset == 300); assert(context->os_context.usec_offset == 54321); verify_princ(princ); if (krb5_cc_start_seq_get(context, cache, &cursor) != 0) abort(); if (krb5_cc_next_cred(context, cache, &cursor, &cred1) != 0) abort(); verify_cred1(&cred1); krb5_free_cred_contents(context, &cred1); if (krb5_cc_next_cred(context, cache, &cursor, &cred2) != 0) abort(); verify_cred2(&cred2); krb5_free_cred_contents(context, &cred2); if (krb5_cc_next_cred(context, cache, &cursor, &cred2) != KRB5_CC_END) abort(); if (krb5_cc_end_seq_get(context, cache, &cursor) != 0) abort(); if (krb5_cc_close(context, cache) != 0) abort(); krb5_free_principal(context, princ); } (void)unlink(filename); free(ccname); krb5_free_context(context); return 0; } krb5-1.22.1/src/lib/krb5/ccache/ccapi_util.c0000664000175000017500000002775415051422640020246 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccapi_util.c - conversion functions for CCAPI creds */ /* * Copyright (C) 2022 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cc-int.h" #include "ccapi_util.h" #if defined(USE_CCAPI) || defined(USE_CCAPI_MACOS) static void free_cc_data_list(cc_data **list) { size_t i; for (i = 0; list != NULL && list[i] != NULL; i++) { free(list[i]->data); free(list[i]); } free(list); } static krb5_error_code cc_data_list_to_addresses(krb5_context context, cc_data **list, krb5_address ***addrs_out) { krb5_error_code ret; size_t count, i; krb5_address **addrs = NULL; *addrs_out = NULL; if (list == NULL) return 0; for (count = 0; list[count]; count++); addrs = k5calloc(count + 1, sizeof(*addrs), &ret); if (addrs == NULL) return ret; for (i = 0; i < count; i++) { addrs[i] = k5alloc(sizeof(*addrs[i]), &ret); if (addrs[i] == NULL) goto cleanup; addrs[i]->contents = k5memdup(list[i]->data, list[i]->length, &ret); if (addrs[i]->contents == NULL) goto cleanup; addrs[i]->length = list[i]->length; addrs[i]->addrtype = list[i]->type; addrs[i]->magic = KV5M_ADDRESS; } *addrs_out = addrs; addrs = NULL; cleanup: krb5_free_addresses(context, addrs); return ret; } static krb5_error_code cc_data_list_to_authdata(krb5_context context, cc_data **list, krb5_authdata ***authdata_out) { krb5_error_code ret; size_t count, i; krb5_authdata **authdata = NULL; *authdata_out = NULL; if (list == NULL) return 0; for (count = 0; list[count]; count++); authdata = k5calloc(count + 1, sizeof(*authdata), &ret); if (authdata == NULL) return ret; for (i = 0; i < count; i++) { authdata[i] = k5alloc(sizeof(*authdata[i]), &ret); if (authdata[i] == NULL) goto cleanup; authdata[i]->contents = k5memdup(list[i]->data, list[i]->length, &ret); if (authdata[i]->contents == NULL) goto cleanup; authdata[i]->length = list[i]->length; authdata[i]->ad_type = list[i]->type; authdata[i]->magic = KV5M_AUTHDATA; } *authdata_out = authdata; authdata = NULL; cleanup: krb5_free_authdata(context, authdata); return ret; } static krb5_error_code addresses_to_cc_data_list(krb5_context context, krb5_address **addrs, cc_data ***list_out) { krb5_error_code ret; size_t count, i; cc_data **list = NULL; *list_out = NULL; if (addrs == NULL) return 0; for (count = 0; addrs[count]; count++); list = k5calloc(count + 1, sizeof(*list), &ret); if (list == NULL) return ret; for (i = 0; i < count; i++) { list[i] = k5alloc(sizeof(*list[i]), &ret); if (list[i] == NULL) goto cleanup; list[i]->data = k5memdup(addrs[i]->contents, addrs[i]->length, &ret); if (list[i]->data == NULL) goto cleanup; list[i]->length = addrs[i]->length; list[i]->type = addrs[i]->addrtype; } *list_out = list; list = NULL; cleanup: free_cc_data_list(list); return ret; } static krb5_error_code authdata_to_cc_data_list(krb5_context context, krb5_authdata **authdata, cc_data ***list_out) { krb5_error_code ret; size_t count, i; cc_data **list = NULL; *list_out = NULL; if (authdata == NULL) return 0; for (count = 0; authdata[count]; count++); list = k5calloc(count + 1, sizeof(*list), &ret); if (list == NULL) return ret; for (i = 0; i < count; i++) { list[i] = k5alloc(sizeof(*list[i]), &ret); if (list[i] == NULL) goto cleanup; list[i]->data = k5memdup(authdata[i]->contents, authdata[i]->length, &ret); if (list[i]->data == NULL) goto cleanup; list[i]->length = authdata[i]->length; list[i]->type = authdata[i]->ad_type; } *list_out = list; list = NULL; cleanup: free_cc_data_list(list); return ret; } krb5_error_code k5_ccapi_to_krb5_creds(krb5_context context, const cc_credentials_union *ccapi_cred, krb5_creds *cred_out) { krb5_error_code ret; cc_credentials_v5_t *cv5 = NULL; krb5_principal client = NULL; krb5_principal server = NULL; char *ticket_data = NULL; char *second_ticket_data = NULL; uint8_t *keyblock_contents = NULL; krb5_address **addresses = NULL; krb5_authdata **authdata = NULL; if (ccapi_cred->version != cc_credentials_v5) return KRB5_CC_NOT_KTYPE; cv5 = ccapi_cred->credentials.credentials_v5; ret = krb5_parse_name(context, cv5->client, &client); if (ret) goto cleanup; ret = krb5_parse_name(context, cv5->server, &server); if (ret) goto cleanup; if (cv5->keyblock.length > 0) { keyblock_contents = k5memdup(cv5->keyblock.data, cv5->keyblock.length, &ret); if (keyblock_contents == NULL) goto cleanup; } if (cv5->ticket.length > 0) { ticket_data = k5memdup(cv5->ticket.data, cv5->ticket.length, &ret); if (ticket_data == NULL) goto cleanup; } if (cv5->second_ticket.length > 0) { second_ticket_data = k5memdup(cv5->second_ticket.data, cv5->second_ticket.length, &ret); if (second_ticket_data == NULL) goto cleanup; } ret = cc_data_list_to_addresses(context, cv5->addresses, &addresses); if (ret) goto cleanup; ret = cc_data_list_to_authdata(context, cv5->authdata, &authdata); if (ret) goto cleanup; cred_out->client = client; cred_out->server = server; client = server = NULL; cred_out->keyblock.magic = KV5M_KEYBLOCK; cred_out->keyblock.enctype = cv5->keyblock.type; cred_out->keyblock.length = cv5->keyblock.length; cred_out->keyblock.contents = keyblock_contents; keyblock_contents = NULL; cred_out->times.authtime = cv5->authtime; cred_out->times.starttime = cv5->starttime; cred_out->times.endtime = cv5->endtime; cred_out->times.renew_till = cv5->renew_till; cred_out->is_skey = cv5->is_skey; cred_out->ticket_flags = cv5->ticket_flags; cred_out->ticket = make_data(ticket_data, cv5->ticket.length); cred_out->second_ticket = make_data(second_ticket_data, cv5->second_ticket.length); ticket_data = second_ticket_data = NULL; cred_out->addresses = addresses; addresses = NULL; cred_out->authdata = authdata; authdata = NULL; cred_out->magic = KV5M_CREDS; cleanup: krb5_free_principal(context, client); krb5_free_principal(context, server); krb5_free_addresses(context, addresses); krb5_free_authdata(context, authdata); free(keyblock_contents); free(ticket_data); free(second_ticket_data); return ret; } krb5_error_code k5_krb5_to_ccapi_creds(krb5_context context, krb5_creds *cred, cc_credentials_union **ccapi_cred_out) { krb5_error_code ret; cc_credentials_union *cred_union = NULL; cc_credentials_v5_t *cv5 = NULL; char *client = NULL, *server = NULL; uint8_t *ticket_data = NULL, *second_ticket_data = NULL; uint8_t *keyblock_data = NULL; cc_data **addr_list = NULL, **authdata_list = NULL; cred_union = k5alloc(sizeof(*cred_union), &ret); if (cred_union == NULL) goto cleanup; cv5 = k5alloc(sizeof(*cv5), &ret); if (cv5 == NULL) goto cleanup; ret = krb5_unparse_name(context, cred->client, &client); if (ret) goto cleanup; ret = krb5_unparse_name(context, cred->server, &server); if (ret) goto cleanup; if (cred->keyblock.length > 0) { keyblock_data = k5memdup(cred->keyblock.contents, cred->keyblock.length, &ret); if (keyblock_data == NULL) goto cleanup; } if (cred->ticket.length > 0) { ticket_data = k5memdup0(cred->ticket.data, cred->ticket.length, &ret); if (ticket_data == NULL) goto cleanup; } if (cred->second_ticket.length > 0) { second_ticket_data = k5memdup0(cred->second_ticket.data, cred->second_ticket.length, &ret); if (second_ticket_data == NULL) goto cleanup; } ret = addresses_to_cc_data_list(context, cred->addresses, &addr_list); if (ret) goto cleanup; ret = authdata_to_cc_data_list(context, cred->authdata, &authdata_list); if (ret) goto cleanup; cv5->client = client; cv5->server = server; client = server = NULL; cv5->keyblock.type = cred->keyblock.enctype; cv5->keyblock.length = cred->keyblock.length; cv5->keyblock.data = keyblock_data; keyblock_data = NULL; cv5->authtime = cred->times.authtime; cv5->starttime = cred->times.starttime; cv5->endtime = cred->times.endtime; cv5->renew_till = cred->times.renew_till; cv5->is_skey = cred->is_skey; cv5->ticket_flags = cred->ticket_flags; cv5->ticket.length = cred->ticket.length; cv5->ticket.data = ticket_data; cv5->second_ticket.length = cred->second_ticket.length; cv5->second_ticket.data = second_ticket_data; ticket_data = second_ticket_data = NULL; cv5->addresses = addr_list; addr_list = NULL; cv5->authdata = authdata_list; authdata_list = NULL; cred_union->version = cc_credentials_v5; cred_union->credentials.credentials_v5 = cv5; cv5 = NULL; *ccapi_cred_out = cred_union; cred_union = NULL; cleanup: free_cc_data_list(addr_list); free_cc_data_list(authdata_list); free(keyblock_data); free(ticket_data); free(second_ticket_data); krb5_free_unparsed_name(context, client); krb5_free_unparsed_name(context, server); free(cv5); free(cred_union); return ret; } void k5_release_ccapi_cred(cc_credentials_union *ccapi_cred) { cc_credentials_v5_t *cv5; if (ccapi_cred == NULL) return; if (ccapi_cred->version != cc_credentials_v5) return; if (ccapi_cred->credentials.credentials_v5 == NULL) return; cv5 = ccapi_cred->credentials.credentials_v5; free(cv5->client); free(cv5->server); free(cv5->keyblock.data); free(cv5->ticket.data); free(cv5->second_ticket.data); free_cc_data_list(cv5->addresses); free_cc_data_list(cv5->authdata); free(cv5); free(ccapi_cred); } #endif /* defined(USE_CCAPI) */ krb5-1.22.1/src/lib/krb5/ccache/ccselect.c0000664000175000017500000001530615051422640017705 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccselect.c - krb5_cc_select API and module loader */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "cc-int.h" #include #include "../krb/int-proto.h" struct ccselect_module_handle { struct krb5_ccselect_vtable_st vt; krb5_ccselect_moddata data; int priority; }; static void free_handles(krb5_context context, struct ccselect_module_handle **handles) { struct ccselect_module_handle *h, **hp; if (handles == NULL) return; for (hp = handles; *hp != NULL; hp++) { h = *hp; if (h->vt.fini) h->vt.fini(context, h->data); free(h); } free(handles); } static krb5_error_code load_modules(krb5_context context) { krb5_error_code ret; struct ccselect_module_handle **list = NULL, *handle; krb5_plugin_initvt_fn *modules = NULL, *mod; size_t count; #ifndef _WIN32 ret = k5_plugin_register(context, PLUGIN_INTERFACE_CCSELECT, "k5identity", ccselect_k5identity_initvt); if (ret != 0) goto cleanup; #endif ret = k5_plugin_register(context, PLUGIN_INTERFACE_CCSELECT, "realm", ccselect_realm_initvt); if (ret != 0) goto cleanup; ret = k5_plugin_register(context, PLUGIN_INTERFACE_CCSELECT, "hostname", ccselect_hostname_initvt); if (ret != 0) goto cleanup; ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_CCSELECT, &modules); if (ret != 0) goto cleanup; /* Allocate a large enough list of handles. */ for (count = 0; modules[count] != NULL; count++); list = k5calloc(count + 1, sizeof(*list), &ret); if (list == NULL) goto cleanup; /* Initialize each module, ignoring ones that fail. */ count = 0; for (mod = modules; *mod != NULL; mod++) { handle = k5alloc(sizeof(*handle), &ret); if (handle == NULL) goto cleanup; ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&handle->vt); if (ret != 0) { /* Failed vtable init is non-fatal. */ TRACE_CCSELECT_VTINIT_FAIL(context, ret); free(handle); continue; } handle->data = NULL; ret = handle->vt.init(context, &handle->data, &handle->priority); if (ret != 0) { /* Failed initialization is non-fatal. */ TRACE_CCSELECT_INIT_FAIL(context, handle->vt.name, ret); free(handle); continue; } list[count++] = handle; list[count] = NULL; } list[count] = NULL; ret = 0; context->ccselect_handles = list; list = NULL; cleanup: k5_plugin_free_modules(context, modules); free_handles(context, list); return ret; } krb5_error_code KRB5_CALLCONV krb5_cc_select(krb5_context context, krb5_principal server, krb5_ccache *cache_out, krb5_principal *princ_out) { krb5_error_code ret; int priority; struct ccselect_module_handle **hp, *h; krb5_ccache cache; krb5_principal princ; krb5_principal srvcp = NULL; char **fbrealms = NULL; *cache_out = NULL; *princ_out = NULL; if (context->ccselect_handles == NULL) { ret = load_modules(context); if (ret) goto cleanup; } /* Try to use the fallback host realm for the server if there is no * authoritative realm. */ if (krb5_is_referral_realm(&server->realm) && server->type == KRB5_NT_SRV_HST && server->length == 2) { ret = krb5_get_fallback_host_realm(context, &server->data[1], &fbrealms); /* Continue without realm if we failed due to no default realm. */ if (ret && ret != KRB5_CONFIG_NODEFREALM) goto cleanup; if (!ret) { /* Make a copy with the first fallback realm. */ ret = krb5_copy_principal(context, server, &srvcp); if (ret) goto cleanup; ret = krb5_set_principal_realm(context, srvcp, fbrealms[0]); if (ret) goto cleanup; server = srvcp; } } /* Consult authoritative modules first, then heuristic ones. */ for (priority = KRB5_CCSELECT_PRIORITY_AUTHORITATIVE; priority >= KRB5_CCSELECT_PRIORITY_HEURISTIC; priority--) { for (hp = context->ccselect_handles; *hp != NULL; hp++) { h = *hp; if (h->priority != priority) continue; ret = h->vt.choose(context, h->data, server, &cache, &princ); if (ret == 0) { TRACE_CCSELECT_MODCHOICE(context, h->vt.name, server, cache, princ); *cache_out = cache; *princ_out = princ; goto cleanup; } else if (ret == KRB5_CC_NOTFOUND) { TRACE_CCSELECT_MODNOTFOUND(context, h->vt.name, server, princ); *princ_out = princ; goto cleanup; } else if (ret != KRB5_PLUGIN_NO_HANDLE) { TRACE_CCSELECT_MODFAIL(context, h->vt.name, ret, server); goto cleanup; } } } TRACE_CCSELECT_NOTFOUND(context, server); ret = KRB5_CC_NOTFOUND; cleanup: krb5_free_principal(context, srvcp); krb5_free_host_realm(context, fbrealms); return ret; } void k5_ccselect_free_context(krb5_context context) { free_handles(context, context->ccselect_handles); context->ccselect_handles = NULL; } krb5-1.22.1/src/lib/krb5/ccache/cc_retr.c0000664000175000017500000002203315051422640017534 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cc_retr.c */ /* * Copyright 1990,1991,1999,2007,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "cc-int.h" #include "../krb/int-proto.h" #define KRB5_OK 0 static int times_match_exact(const krb5_ticket_times *t1, const krb5_ticket_times *t2) { return (t1->authtime == t2->authtime && t1->starttime == t2->starttime && t1->endtime == t2->endtime && t1->renew_till == t2->renew_till); } static krb5_boolean times_match(const krb5_ticket_times *t1, const krb5_ticket_times *t2) { if (t1->renew_till) { if (ts_after(t1->renew_till, t2->renew_till)) return FALSE; /* this one expires too late */ } if (t1->endtime) { if (ts_after(t1->endtime, t2->endtime)) return FALSE; /* this one expires too late */ } /* only care about expiration on a times_match */ return TRUE; } static krb5_boolean princs_match(krb5_context context, krb5_flags whichfields, const krb5_creds *mcreds, const krb5_creds *creds) { if (mcreds->client != NULL && !krb5_principal_compare(context, mcreds->client, creds->client)) return FALSE; if (mcreds->server == NULL) return TRUE; if (whichfields & KRB5_TC_MATCH_SRV_NAMEONLY) { return krb5_principal_compare_any_realm(context, mcreds->server, creds->server); } else { return krb5_principal_compare(context, mcreds->server, creds->server); } } static krb5_boolean authdata_match(krb5_authdata *const *mdata, krb5_authdata *const *data) { const krb5_authdata *mdatap, *datap; if (mdata == data) return TRUE; if (mdata == NULL) return *data == NULL; if (data == NULL) return *mdata == NULL; while ((mdatap = *mdata) && (datap = *data)) { if ((mdatap->ad_type != datap->ad_type) || (mdatap->length != datap->length) || (memcmp ((char *)mdatap->contents, (char *)datap->contents, (unsigned) mdatap->length) != 0)) return FALSE; mdata++; data++; } return (*mdata == NULL) && (*data == NULL); } static krb5_boolean data_match(const krb5_data *data1, const krb5_data *data2) { if (!data1) { if (!data2) return TRUE; else return FALSE; } if (!data2) return FALSE; return data_eq(*data1, *data2) ? TRUE : FALSE; } static int pref (krb5_enctype my_ktype, int nktypes, krb5_enctype *ktypes) { int i; for (i = 0; i < nktypes; i++) if (my_ktype == ktypes[i]) return i; return -1; } /* * Effects: * Searches the credentials cache for a credential matching mcreds, * with the fields specified by whichfields. If one if found, it is * returned in creds, which should be freed by the caller with * krb5_free_credentials(). * * The fields are interpreted in the following way (all constants are * preceded by KRB5_TC_). MATCH_IS_SKEY requires the is_skey field to * match exactly. MATCH_TIMES requires the requested lifetime to be * at least as great as that specified; MATCH_TIMES_EXACT requires the * requested lifetime to be exactly that specified. MATCH_FLAGS * requires only the set bits in mcreds be set in creds; * MATCH_FLAGS_EXACT requires all bits to match. * * Flag SUPPORTED_KTYPES means check all matching entries that have * any supported enctype (according to tgs_enctypes) and return the one * with the enctype listed earliest. Return CC_NOT_KTYPE if a match * is found *except* for having a supported enctype. * * Errors: * system errors * permission errors * KRB5_CC_NOMEM * KRB5_CC_NOT_KTYPE */ krb5_boolean krb5int_cc_creds_match_request(krb5_context context, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds) { krb5_boolean is_skey; if (!princs_match(context, whichfields, mcreds, creds)) return FALSE; /* Only match a user-to-user credential if explicitly asked for, since the * ticket won't work as a regular service ticket. */ is_skey = (whichfields & KRB5_TC_MATCH_IS_SKEY) ? mcreds->is_skey : FALSE; if (creds->is_skey != is_skey) return FALSE; if ((whichfields & KRB5_TC_MATCH_FLAGS_EXACT) && mcreds->ticket_flags != creds->ticket_flags) return FALSE; if ((whichfields & KRB5_TC_MATCH_FLAGS) && (creds->ticket_flags & mcreds->ticket_flags) != mcreds->ticket_flags) return FALSE; if ((whichfields & KRB5_TC_MATCH_TIMES_EXACT) && !times_match_exact(&mcreds->times, &creds->times)) return FALSE; if ((whichfields & KRB5_TC_MATCH_TIMES) && !times_match(&mcreds->times, &creds->times)) return FALSE; if ((whichfields & KRB5_TC_MATCH_AUTHDATA) && !authdata_match(mcreds->authdata, creds->authdata)) return FALSE; if ((whichfields & KRB5_TC_MATCH_2ND_TKT) && !data_match(&mcreds->second_ticket, &creds->second_ticket)) return FALSE; if ((whichfields & KRB5_TC_MATCH_KTYPE) && mcreds->keyblock.enctype != creds->keyblock.enctype) return FALSE; return TRUE; } static krb5_error_code krb5_cc_retrieve_cred_seq (krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds, int nktypes, krb5_enctype *ktypes) { /* This function could be considerably faster if it kept indexing */ /* information.. sounds like a "next version" idea to me. :-) */ krb5_cc_cursor cursor; krb5_error_code kret; krb5_error_code nomatch_err = KRB5_CC_NOTFOUND; struct { krb5_creds creds; int pref; } fetched, best; int have_creds = 0; #define fetchcreds (fetched.creds) kret = krb5_cc_start_seq_get(context, id, &cursor); if (kret != KRB5_OK) return kret; while (krb5_cc_next_cred(context, id, &cursor, &fetchcreds) == KRB5_OK) { if (krb5int_cc_creds_match_request(context, whichfields, mcreds, &fetchcreds)) { if (ktypes) { fetched.pref = pref (fetchcreds.keyblock.enctype, nktypes, ktypes); if (fetched.pref < 0) nomatch_err = KRB5_CC_NOT_KTYPE; else if (!have_creds || fetched.pref < best.pref) { if (have_creds) krb5_free_cred_contents (context, &best.creds); else have_creds = 1; best = fetched; continue; } } else { krb5_cc_end_seq_get(context, id, &cursor); *creds = fetchcreds; return KRB5_OK; } } /* This one doesn't match */ krb5_free_cred_contents(context, &fetchcreds); } /* If we get here, a match wasn't found */ krb5_cc_end_seq_get(context, id, &cursor); if (have_creds) { *creds = best.creds; return KRB5_OK; } else return nomatch_err; } krb5_error_code k5_cc_retrieve_cred_default(krb5_context context, krb5_ccache id, krb5_flags flags, krb5_creds *mcreds, krb5_creds *creds) { krb5_enctype *ktypes; int nktypes; krb5_error_code ret; if (flags & KRB5_TC_SUPPORTED_KTYPES) { ret = krb5_get_tgs_ktypes (context, mcreds->server, &ktypes); if (ret) return ret; nktypes = k5_count_etypes (ktypes); ret = krb5_cc_retrieve_cred_seq (context, id, flags, mcreds, creds, nktypes, ktypes); free (ktypes); return ret; } else { return krb5_cc_retrieve_cred_seq (context, id, flags, mcreds, creds, 0, 0); } } krb5-1.22.1/src/lib/krb5/ccache/ccapi/0000775000175000017500000000000015051422640017026 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/ccache/ccapi/Makefile.in0000664000175000017500000000077715051422640021106 0ustar ghudsonghudsonmydir=lib$(S)krb5$(S)ccache$(S)ccapi BUILDTOP=$(REL)..$(S)..$(S)..$(S).. LOCALINCLUDES = $(WIN_INCLUDES) DEFINES= -DUSE_CCAPI ##DOS##WIN_INCLUDES = -I$(top_srcdir)\windows\lib ##DOS##BUILDTOP = ..\..\..\.. ##DOS##PREFIXDIR = ccache\file ##DOS##OBJFILE = $(OUTPRE)file.lst STLIBOBJS = \ stdcc.o \ winccld.o OBJS = $(OUTPRE)stdcc.$(OBJEXT) $(OUTPRE)winccld.$(OBJEXT) SRCS = $(srcdir)/stdcc.c $(srcdir)/winccld.c ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs clean-unix:: clean-libobjs @libobj_frag@ krb5-1.22.1/src/lib/krb5/ccache/ccapi/deps0000664000175000017500000000151515051422640017706 0ustar ghudsonghudson# # Generated makefile dependencies follow. # stdcc.so stdcc.po $(OUTPRE)stdcc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h stdcc.c stdcc.h winccld.so winccld.po $(OUTPRE)winccld.$(OBJEXT): winccld.c krb5-1.22.1/src/lib/krb5/ccache/ccapi/winccld.h0000664000175000017500000000175015051422640020625 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * winccld.h -- the dynamic loaded version of the ccache DLL */ #ifndef KRB5_WINCCLD_H_ #define KRB5_WINCCLD_H_ #include typedef CCACHE_API cc_int32 (*FP_cc_initialize) ( cc_context_t* outContext, cc_int32 inVersion, cc_int32* outSupportedVersion, char const** outVendor); #ifdef KRB5_WINCCLD_C_ typedef struct _FUNC_INFO { void** func_ptr_var; char* func_name; } FUNC_INFO; #define DECL_FUNC_PTR(x) FP_##x p##x #define MAKE_FUNC_INFO(x) { (void**) &p##x, #x } #define END_FUNC_INFO { 0, 0 } #else #define DECL_FUNC_PTR(x) extern FP_##x p##x #endif DECL_FUNC_PTR(cc_initialize); #ifdef KRB5_WINCCLD_C_ FUNC_INFO krbcc_fi[] = { MAKE_FUNC_INFO(cc_initialize), END_FUNC_INFO }; #undef MAKE_FUNC_INFO #undef END_FUNC_INFO #else #define cc_initialize pcc_initialize #endif #undef DECL_FUNC_PTR #endif /* KRB5_WINCCLD_H_ */ krb5-1.22.1/src/lib/krb5/ccache/ccapi/stdcc.c0000664000175000017500000006504415051422640020303 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccapi/stdcc.c - ccache API support functions */ /* * Copyright 1998, 1999, 2006, 2008 by the Massachusetts Institute of * Technology. All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Written by Frank Dabek July 1998 * Updated by Jeffrey Altman June 2006 */ #if defined(_WIN32) || defined(USE_CCAPI) #include "k5-int.h" #include "../cc-int.h" #include "../ccapi_util.h" #include "stdcc.h" #include "string.h" #include #if defined(_WIN32) #include "winccld.h" #endif #ifndef CC_API_VER2 #define CC_API_VER2 #endif #ifdef DEBUG #if defined(_WIN32) #include #define SHOW_DEBUG(buf) MessageBox((HWND)NULL, (buf), "ccapi debug", MB_OK) #endif /* XXX need macintosh debugging statement if we want to debug */ /* on the mac */ #else #define SHOW_DEBUG(buf) #endif cc_context_t gCntrlBlock = NULL; cc_int32 gCCVersion = 0; /* * declare our global object wanna-be * must be installed in ccdefops.c */ krb5_cc_ops krb5_cc_stdcc_ops = { 0, "API", krb5_stdccv3_get_name, krb5_stdccv3_resolve, krb5_stdccv3_generate_new, krb5_stdccv3_initialize, krb5_stdccv3_destroy, krb5_stdccv3_close, krb5_stdccv3_store, krb5_stdccv3_retrieve, krb5_stdccv3_get_principal, krb5_stdccv3_start_seq_get, krb5_stdccv3_next_cred, krb5_stdccv3_end_seq_get, krb5_stdccv3_remove, krb5_stdccv3_set_flags, krb5_stdccv3_get_flags, krb5_stdccv3_ptcursor_new, krb5_stdccv3_ptcursor_next, krb5_stdccv3_ptcursor_free, NULL, /* move */ NULL, /* wasdefault */ krb5_stdccv3_lock, krb5_stdccv3_unlock, krb5_stdccv3_switch_to, }; #if defined(_WIN32) /* * cache_changed be called after the cache changes. * A notification message is is posted out to all top level * windows so that they may recheck the cache based on the * changes made. We register a unique message type with which * we'll communicate to all other processes. */ static void cache_changed(void) { static unsigned int message = 0; if (message == 0) message = RegisterWindowMessage(WM_KERBEROS5_CHANGED); PostMessage(HWND_BROADCAST, message, 0, 0); } #else /* _WIN32 */ static void cache_changed(void) { return; } #endif /* _WIN32 */ struct err_xlate { int cc_err; krb5_error_code krb5_err; }; static const struct err_xlate err_xlate_table[] = { { ccIteratorEnd, KRB5_CC_END }, { ccErrBadParam, KRB5_FCC_INTERNAL }, { ccErrNoMem, KRB5_CC_NOMEM }, { ccErrInvalidContext, KRB5_FCC_NOFILE }, { ccErrInvalidCCache, KRB5_FCC_NOFILE }, { ccErrInvalidString, KRB5_FCC_INTERNAL }, { ccErrInvalidCredentials, KRB5_FCC_INTERNAL }, { ccErrInvalidCCacheIterator, KRB5_FCC_INTERNAL }, { ccErrInvalidCredentialsIterator, KRB5_FCC_INTERNAL }, { ccErrInvalidLock, KRB5_FCC_INTERNAL }, { ccErrBadName, KRB5_CC_BADNAME }, { ccErrBadCredentialsVersion, KRB5_FCC_INTERNAL }, { ccErrBadAPIVersion, KRB5_FCC_INTERNAL }, { ccErrContextLocked, KRB5_FCC_INTERNAL }, { ccErrContextUnlocked, KRB5_FCC_INTERNAL }, { ccErrCCacheLocked, KRB5_FCC_INTERNAL }, { ccErrCCacheUnlocked, KRB5_FCC_INTERNAL }, { ccErrBadLockType, KRB5_FCC_INTERNAL }, { ccErrNeverDefault, KRB5_FCC_INTERNAL }, { ccErrCredentialsNotFound, KRB5_CC_NOTFOUND }, { ccErrCCacheNotFound, KRB5_FCC_NOFILE }, { ccErrContextNotFound, KRB5_FCC_NOFILE }, { ccErrServerUnavailable, KRB5_CC_IO }, { ccErrServerInsecure, KRB5_CC_IO }, { ccErrServerCantBecomeUID, KRB5_CC_IO }, { ccErrTimeOffsetNotSet, KRB5_FCC_INTERNAL }, { ccErrBadInternalMessage, KRB5_FCC_INTERNAL }, { ccErrNotImplemented, KRB5_FCC_INTERNAL }, { 0, 0 } }; /* Note: cc_err_xlate is NOT idempotent. Don't call it multiple times. */ static krb5_error_code cc_err_xlate(int err) { const struct err_xlate *p; if (err == ccNoError) return 0; for (p = err_xlate_table; p->cc_err; p++) { if (err == p->cc_err) return p->krb5_err; } return KRB5_FCC_INTERNAL; } static krb5_error_code stdccv3_get_timeoffset (krb5_context in_context, cc_ccache_t in_ccache) { krb5_error_code err = 0; if (gCCVersion >= ccapi_version_5) { krb5_os_context os_ctx = (krb5_os_context) &in_context->os_context; cc_time_t time_offset = 0; err = cc_ccache_get_kdc_time_offset (in_ccache, cc_credentials_v5, &time_offset); if (!err) { os_ctx->time_offset = time_offset; os_ctx->usec_offset = 0; os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) | KRB5_OS_TOFFSET_VALID); } if (err == ccErrTimeOffsetNotSet) { err = 0; /* okay if there is no time offset */ } } return err; /* Don't translate. Callers will translate for us */ } static krb5_error_code stdccv3_set_timeoffset (krb5_context in_context, cc_ccache_t in_ccache) { krb5_error_code err = 0; if (gCCVersion >= ccapi_version_5) { krb5_os_context os_ctx = (krb5_os_context) &in_context->os_context; if (!err && os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) { err = cc_ccache_set_kdc_time_offset (in_ccache, cc_credentials_v5, os_ctx->time_offset); } } return err; /* Don't translate. Callers will translate for us */ } static krb5_error_code stdccv3_setup (krb5_context context, stdccCacheDataPtr ccapi_data) { krb5_error_code err = 0; if (!err && !gCntrlBlock) { err = cc_initialize (&gCntrlBlock, ccapi_version_max, &gCCVersion, NULL); } if (!err && ccapi_data && !ccapi_data->NamedCache) { /* ccache has not been opened yet. open it. */ err = cc_context_open_ccache (gCntrlBlock, ccapi_data->cache_name, &ccapi_data->NamedCache); } if (!err && ccapi_data && ccapi_data->NamedCache) { err = stdccv3_get_timeoffset (context, ccapi_data->NamedCache); } return err; /* Don't translate. Callers will translate for us */ } /* krb5_stdcc_shutdown is exported; use the old name */ void krb5_stdcc_shutdown(void) { if (gCntrlBlock) { cc_context_release(gCntrlBlock); } gCntrlBlock = NULL; gCCVersion = 0; } /* * -- generate_new -------------------------------- * * create a new cache with a unique name, corresponds to creating a * named cache initialize the API here if we have to. */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_generate_new (krb5_context context, krb5_ccache *id ) { krb5_error_code err = 0; krb5_ccache newCache = NULL; stdccCacheDataPtr ccapi_data = NULL; cc_ccache_t ccache = NULL; cc_string_t ccstring = NULL; char *name = NULL; if (!err) { err = stdccv3_setup(context, NULL); } if (!err) { newCache = (krb5_ccache) malloc (sizeof (*newCache)); if (!newCache) { err = KRB5_CC_NOMEM; } } if (!err) { ccapi_data = (stdccCacheDataPtr) malloc (sizeof (*ccapi_data)); if (!ccapi_data) { err = KRB5_CC_NOMEM; } } if (!err) { err = cc_context_create_new_ccache (gCntrlBlock, cc_credentials_v5, "", &ccache); } if (!err) { err = stdccv3_set_timeoffset (context, ccache); } if (!err) { err = cc_ccache_get_name (ccache, &ccstring); } if (!err) { name = strdup (ccstring->data); if (!name) { err = KRB5_CC_NOMEM; } } if (!err) { ccapi_data->cache_name = name; name = NULL; /* take ownership */ ccapi_data->NamedCache = ccache; ccache = NULL; /* take ownership */ newCache->ops = &krb5_cc_stdcc_ops; newCache->data = ccapi_data; ccapi_data = NULL; /* take ownership */ /* return a pointer to the new cache */ *id = newCache; newCache = NULL; } if (ccstring) { cc_string_release (ccstring); } if (name) { free (name); } if (ccache) { cc_ccache_release (ccache); } if (ccapi_data) { free (ccapi_data); } if (newCache) { free (newCache); } return cc_err_xlate (err); } /* * resolve * * create a new cache with the name stored in residual */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_resolve (krb5_context context, krb5_ccache *id , const char *residual ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = NULL; krb5_ccache ccache = NULL; char *name = NULL; cc_string_t defname = NULL; if (id == NULL) { err = KRB5_CC_NOMEM; } if (!err) { err = stdccv3_setup (context, NULL); } if (!err) { ccapi_data = (stdccCacheDataPtr) malloc (sizeof (*ccapi_data)); if (!ccapi_data) { err = KRB5_CC_NOMEM; } } if (!err) { ccache = (krb5_ccache ) malloc (sizeof (*ccache)); if (!ccache) { err = KRB5_CC_NOMEM; } } if (!err) { if ((residual == NULL) || (strlen(residual) == 0)) { err = cc_context_get_default_ccache_name(gCntrlBlock, &defname); if (defname) residual = defname->data; } } if (!err) { name = strdup (residual); if (!name) { err = KRB5_CC_NOMEM; } } if (!err) { err = cc_context_open_ccache (gCntrlBlock, residual, &ccapi_data->NamedCache); if (err == ccErrCCacheNotFound) { ccapi_data->NamedCache = NULL; err = 0; /* ccache just doesn't exist yet */ } } if (!err) { ccapi_data->cache_name = name; name = NULL; /* take ownership */ ccache->ops = &krb5_cc_stdcc_ops; ccache->data = ccapi_data; ccapi_data = NULL; /* take ownership */ *id = ccache; ccache = NULL; /* take ownership */ } if (ccache) { free (ccache); } if (ccapi_data) { free (ccapi_data); } if (name) { free (name); } if (defname) { cc_string_release(defname); } return cc_err_xlate (err); } /* * initialize * * initialize the cache, check to see if one already exists for this * principal if not set our principal to this principal. This * searching enables ticket sharing */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_initialize (krb5_context context, krb5_ccache id, krb5_principal princ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; char *name = NULL; cc_ccache_t ccache = NULL; if (id == NULL) { err = KRB5_CC_NOMEM; } if (!err) { err = stdccv3_setup (context, NULL); } if (!err) { err = krb5_unparse_name(context, princ, &name); } if (!err) { err = cc_context_create_ccache (gCntrlBlock, ccapi_data->cache_name, cc_credentials_v5, name, &ccache); } if (!err) { err = stdccv3_set_timeoffset (context, ccache); } if (!err) { if (ccapi_data->NamedCache) { err = cc_ccache_release (ccapi_data->NamedCache); } ccapi_data->NamedCache = ccache; ccache = NULL; /* take ownership */ cache_changed (); } if (ccache) { cc_ccache_release (ccache); } if (name ) { krb5_free_unparsed_name(context, name); } return cc_err_xlate(err); } /* * store * * store some credentials in our cache */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_store (krb5_context context, krb5_ccache id, krb5_creds *creds ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_union *cred_union = NULL; if (!err) { err = stdccv3_setup (context, ccapi_data); } if (!err) { /* copy the fields from the almost identical structures */ err = k5_krb5_to_ccapi_creds (context, creds, &cred_union); } if (!err) { err = cc_ccache_store_credentials (ccapi_data->NamedCache, cred_union); } if (!err) { cache_changed(); } if (cred_union) { k5_release_ccapi_cred (cred_union); } return cc_err_xlate (err); } /* * start_seq_get * * begin an iterator call to get all of the credentials in the cache */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_start_seq_get (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_iterator_t iterator = NULL; if (!err) { err = stdccv3_setup (context, ccapi_data); } if (!err) { err = cc_ccache_new_credentials_iterator(ccapi_data->NamedCache, &iterator); } if (!err) { *cursor = iterator; } return cc_err_xlate (err); } /* * next cred * * - get the next credential in the cache as part of an iterator call * - this maps to call to cc_seq_fetch_creds */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_next_cred (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_t credentials = NULL; cc_credentials_iterator_t iterator = *cursor; if (!iterator) { err = KRB5_CC_END; } if (!err) { err = stdccv3_setup (context, ccapi_data); } while (!err) { err = cc_credentials_iterator_next (iterator, &credentials); if (!err && (credentials->data->version == cc_credentials_v5)) { err = k5_ccapi_to_krb5_creds (context, credentials->data, creds); break; } } if (credentials) { cc_credentials_release (credentials); } if (err == ccIteratorEnd) { cc_credentials_iterator_release (iterator); *cursor = 0; } return cc_err_xlate (err); } /* * retrieve * * - try to find a matching credential in the cache */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_retrieve (krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds) { return k5_cc_retrieve_cred_default(context, id, whichfields, mcreds, creds); } /* * end seq * * just free up the storage associated with the cursor (if we can) */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_end_seq_get (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_iterator_t iterator = *cursor; if (!iterator) { return 0; } if (!err) { err = stdccv3_setup (context, ccapi_data); } if (!err) { err = cc_credentials_iterator_release(iterator); } return cc_err_xlate(err); } /* * close * * - free our pointers to the NC */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_close(krb5_context context, krb5_ccache id) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; if (!err) { err = stdccv3_setup (context, NULL); } if (!err) { if (ccapi_data) { if (ccapi_data->cache_name) { free (ccapi_data->cache_name); } if (ccapi_data->NamedCache) { err = cc_ccache_release (ccapi_data->NamedCache); } free (ccapi_data); id->data = NULL; } free (id); } return cc_err_xlate(err); } /* * destroy * * - free our storage and the cache */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_destroy (krb5_context context, krb5_ccache id) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { if (ccapi_data) { if (ccapi_data->cache_name) { free(ccapi_data->cache_name); } if (ccapi_data->NamedCache) { /* destroy the named cache */ err = cc_ccache_destroy(ccapi_data->NamedCache); if (err == ccErrCCacheNotFound) { err = 0; /* ccache maybe already destroyed */ } cache_changed(); } free(ccapi_data); id->data = NULL; } free(id); } return cc_err_xlate(err); } /* * getname * * - return the name of the named cache */ const char * KRB5_CALLCONV krb5_stdccv3_get_name (krb5_context context, krb5_ccache id ) { stdccCacheDataPtr ccapi_data = id->data; if (!ccapi_data) { return NULL; } else { return (ccapi_data->cache_name); } } /* get_principal * * - return the principal associated with the named cache */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_principal (krb5_context context, krb5_ccache id , krb5_principal *princ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_string_t name = NULL; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { err = cc_ccache_get_principal (ccapi_data->NamedCache, cc_credentials_v5, &name); } if (!err) { err = krb5_parse_name (context, name->data, princ); } else { err = cc_err_xlate (err); } if (name) { cc_string_release (name); } return err; } /* * set_flags * * - currently a NOP since we don't store any flags in the NC */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_set_flags (krb5_context context, krb5_ccache id, krb5_flags flags) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; err = stdccv3_setup (context, ccapi_data); return cc_err_xlate (err); } /* * get_flags * * - currently a NOP since we don't store any flags in the NC */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_flags (krb5_context context, krb5_ccache id, krb5_flags *flags) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; err = stdccv3_setup (context, ccapi_data); return cc_err_xlate (err); } /* * remove * * - remove the specified credentials from the NC */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_remove (krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *in_creds) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_iterator_t iterator = NULL; int found = 0; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { err = cc_ccache_new_credentials_iterator(ccapi_data->NamedCache, &iterator); } while (!err && !found) { cc_credentials_t credentials = NULL; err = cc_credentials_iterator_next (iterator, &credentials); if (!err && (credentials->data->version == cc_credentials_v5)) { krb5_creds creds; err = k5_ccapi_to_krb5_creds (context, credentials->data, &creds); if (!err) { found = krb5int_cc_creds_match_request(context, whichfields, in_creds, &creds); krb5_free_cred_contents (context, &creds); } if (!err && found) { err = cc_ccache_remove_credentials (ccapi_data->NamedCache, credentials); } } if (credentials) { cc_credentials_release (credentials); } } if (err == ccIteratorEnd) { err = ccErrCredentialsNotFound; } if (iterator) { err = cc_credentials_iterator_release(iterator); } if (!err) { cache_changed (); } return cc_err_xlate (err); } krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_new(krb5_context context, krb5_cc_ptcursor *cursor) { krb5_error_code err = 0; krb5_cc_ptcursor ptcursor = NULL; cc_ccache_iterator_t iterator = NULL; ptcursor = malloc(sizeof(*ptcursor)); if (ptcursor == NULL) { err = ccErrNoMem; } else { memset(ptcursor, 0, sizeof(*ptcursor)); } if (!err) { err = stdccv3_setup(context, NULL); } if (!err) { ptcursor->ops = &krb5_cc_stdcc_ops; err = cc_context_new_ccache_iterator(gCntrlBlock, &iterator); } if (!err) { ptcursor->data = iterator; } if (err) { if (ptcursor) { krb5_stdccv3_ptcursor_free(context, &ptcursor); } // krb5_stdccv3_ptcursor_free sets ptcursor to NULL for us } *cursor = ptcursor; return cc_err_xlate(err); } krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_next( krb5_context context, krb5_cc_ptcursor cursor, krb5_ccache *ccache) { krb5_error_code err = 0; cc_ccache_iterator_t iterator = NULL; krb5_ccache newCache = NULL; stdccCacheDataPtr ccapi_data = NULL; cc_ccache_t ccCache = NULL; cc_string_t ccstring = NULL; char *name = NULL; if (!cursor || !cursor->data) { err = ccErrInvalidContext; } *ccache = NULL; if (!err) { newCache = (krb5_ccache) malloc (sizeof (*newCache)); if (!newCache) { err = ccErrNoMem; } } if (!err) { ccapi_data = (stdccCacheDataPtr) malloc (sizeof (*ccapi_data)); if (!ccapi_data) { err = ccErrNoMem; } } if (!err) { iterator = cursor->data; err = cc_ccache_iterator_next(iterator, &ccCache); } if (!err) { err = cc_ccache_get_name (ccCache, &ccstring); } if (!err) { name = strdup (ccstring->data); if (!name) { err = ccErrNoMem; } } if (!err) { ccapi_data->cache_name = name; name = NULL; /* take ownership */ ccapi_data->NamedCache = ccCache; ccCache = NULL; /* take ownership */ newCache->ops = &krb5_cc_stdcc_ops; newCache->data = ccapi_data; ccapi_data = NULL; /* take ownership */ /* return a pointer to the new cache */ *ccache = newCache; newCache = NULL; } if (name) { free (name); } if (ccstring) { cc_string_release (ccstring); } if (ccCache) { cc_ccache_release (ccCache); } if (ccapi_data) { free (ccapi_data); } if (newCache) { free (newCache); } if (err == ccIteratorEnd) { err = ccNoError; } return cc_err_xlate(err); } krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_free( krb5_context context, krb5_cc_ptcursor *cursor) { if (*cursor != NULL) { if ((*cursor)->data != NULL) { cc_ccache_iterator_release((cc_ccache_iterator_t)((*cursor)->data)); } free(*cursor); *cursor = NULL; } return 0; } krb5_error_code KRB5_CALLCONV krb5_stdccv3_lock (krb5_context context, krb5_ccache id) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { err = cc_ccache_lock(ccapi_data->NamedCache, cc_lock_write, cc_lock_block); } return cc_err_xlate(err); } krb5_error_code KRB5_CALLCONV krb5_stdccv3_unlock (krb5_context context, krb5_ccache id) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { err = cc_ccache_unlock(ccapi_data->NamedCache); } return cc_err_xlate(err); } krb5_error_code KRB5_CALLCONV krb5_stdccv3_context_lock (krb5_context context) { krb5_error_code err = 0; if (!err && !gCntrlBlock) { err = cc_initialize (&gCntrlBlock, ccapi_version_max, &gCCVersion, NULL); } if (!err) { err = cc_context_lock(gCntrlBlock, cc_lock_write, cc_lock_block); } return cc_err_xlate(err); } krb5_error_code KRB5_CALLCONV krb5_stdccv3_context_unlock (krb5_context context) { krb5_error_code err = 0; if (!err && !gCntrlBlock) { err = cc_initialize (&gCntrlBlock, ccapi_version_max, &gCCVersion, NULL); } if (!err) { err = cc_context_unlock(gCntrlBlock); } return cc_err_xlate(err); } krb5_error_code KRB5_CALLCONV krb5_stdccv3_switch_to (krb5_context context, krb5_ccache id) { krb5_error_code retval; stdccCacheDataPtr ccapi_data = id->data; int err; retval = stdccv3_setup(context, ccapi_data); if (retval) return cc_err_xlate(retval); err = cc_ccache_set_default(ccapi_data->NamedCache); return cc_err_xlate(err); } #endif /* defined(_WIN32) || defined(USE_CCAPI) */ krb5-1.22.1/src/lib/krb5/ccache/ccapi/winccld.c0000664000175000017500000000443115051422640020617 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #if defined(_WIN32) /* * winccld.c --- routine for dynamically loading the ccache DLL if * it's present. */ #include #include #include "k5-int.h" #include "stdcc.h" /* from fcc-proto.h */ extern const krb5_cc_ops krb5_fcc_ops; #define KRB5_WINCCLD_C_ #include "winccld.h" static int krb5_win_ccdll_loaded = 0; extern void krb5_win_ccdll_load(krb5_context context); extern int krb5_is_ccdll_loaded(void); /* * return codes */ #define LF_OK 0 #define LF_NODLL 1 #define LF_NOFUNC 2 #ifdef _WIN64 #define KRBCC_DLL "krbcc64.dll" #else #define KRBCC_DLL "krbcc32.dll" #endif static int LoadFuncs(const char* dll_name, FUNC_INFO fi[], HINSTANCE* ph, int debug); static int LoadFuncs(const char* dll_name, FUNC_INFO fi[], HINSTANCE* ph, int debug) { HINSTANCE h; int i, n; int error = 0; if (ph) *ph = 0; for (n = 0; fi[n].func_ptr_var; n++) { *(fi[n].func_ptr_var) = 0; } if (!(h = LoadLibrary(dll_name))) { /* Get error for source debugging purposes. */ error = (int)GetLastError(); return LF_NODLL; } if (debug) printf("Loaded %s\n", dll_name); for (i = 0; !error && (i < n); i++) { void* p = (void*)GetProcAddress(h, fi[i].func_name); if (!p) { if (debug) printf("Could not get function: %s\n", fi[i].func_name); error = 1; } else { *(fi[i].func_ptr_var) = p; if (debug) printf("Loaded function %s at 0x%08X\n", fi[i].func_name, p); } } if (error) { for (i = 0; i < n; i++) { *(fi[i].func_ptr_var) = 0; } FreeLibrary(h); return LF_NOFUNC; } if (ph) *ph = h; return LF_OK; } void krb5_win_ccdll_load(krb5_context context) { krb5_cc_register(context, &krb5_fcc_ops, 0); if (krb5_win_ccdll_loaded) return; if (LoadFuncs(KRBCC_DLL, krbcc_fi, 0, 0)) return; /* Error, give up */ krb5_win_ccdll_loaded = 1; krb5_cc_dfl_ops = &krb5_cc_stdcc_ops; /* Use stdcc! */ } int krb5_is_ccdll_loaded(void) { return krb5_win_ccdll_loaded; } #endif /* Windows */ krb5-1.22.1/src/lib/krb5/ccache/ccapi/stdcc.h0000664000175000017500000000575515051422640020313 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #ifndef __KRB5_STDCC_H__ #define __KRB5_STDCC_H__ #if defined(_WIN32) || defined(USE_CCAPI) #include "k5-int.h" /* loads krb5.h */ #include "../cc-int.h" #include #define kStringLiteralLen 255 /* globals to be exported */ extern krb5_cc_ops krb5_cc_stdcc_ops; /* * structure to stash in the cache's data field */ typedef struct _stdccCacheData { char *cache_name; cc_ccache_t NamedCache; } stdccCacheData, *stdccCacheDataPtr; /* function prototypes */ void krb5_stdcc_shutdown(void); krb5_error_code KRB5_CALLCONV krb5_stdccv3_close (krb5_context, krb5_ccache id ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_destroy (krb5_context, krb5_ccache id ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_end_seq_get (krb5_context, krb5_ccache id , krb5_cc_cursor *cursor ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_generate_new (krb5_context, krb5_ccache *id ); const char * KRB5_CALLCONV krb5_stdccv3_get_name (krb5_context, krb5_ccache id ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_principal (krb5_context, krb5_ccache id , krb5_principal *princ ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_initialize (krb5_context, krb5_ccache id , krb5_principal princ ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_next_cred (krb5_context, krb5_ccache id , krb5_cc_cursor *cursor , krb5_creds *creds ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_resolve (krb5_context, krb5_ccache *id , const char *residual ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_retrieve (krb5_context, krb5_ccache id , krb5_flags whichfields , krb5_creds *mcreds , krb5_creds *creds ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_start_seq_get (krb5_context, krb5_ccache id , krb5_cc_cursor *cursor ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_store (krb5_context, krb5_ccache id , krb5_creds *creds ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_set_flags (krb5_context, krb5_ccache id , krb5_flags flags ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_flags (krb5_context, krb5_ccache id , krb5_flags *flags ); krb5_error_code KRB5_CALLCONV krb5_stdccv3_remove (krb5_context, krb5_ccache id , krb5_flags flags, krb5_creds *creds); krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_new (krb5_context context, krb5_cc_ptcursor *cursor); krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_next (krb5_context context, krb5_cc_ptcursor cursor, krb5_ccache *ccache); krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_free (krb5_context context, krb5_cc_ptcursor *cursor); krb5_error_code KRB5_CALLCONV krb5_stdccv3_lock (krb5_context, krb5_ccache id); krb5_error_code KRB5_CALLCONV krb5_stdccv3_unlock (krb5_context, krb5_ccache id); krb5_error_code KRB5_CALLCONV krb5_stdccv3_context_lock (krb5_context context); krb5_error_code KRB5_CALLCONV krb5_stdccv3_context_unlock (krb5_context context); krb5_error_code KRB5_CALLCONV krb5_stdccv3_switch_to (krb5_context context, krb5_ccache id); #endif /* defined(_WIN32) || defined(USE_CCAPI) */ #endif krb5-1.22.1/src/lib/krb5/ccache/ccmarshal.c0000664000175000017500000004127115051422640020055 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccmarshal.c - Functions for serializing creds */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This file implements marshalling and unmarshalling of krb5 credentials and * principals in versions 1 through 4 of the FILE ccache format. Version 4 is * also used for the KEYRING ccache type. * * The FILE credential cache format uses fixed 16-bit or 32-bit representations * of integers. In versions 1 and 2 these are in host byte order; in later * versions they are in big-endian byte order. Variable-length fields are * represented with a 32-bit length followed by the field value. There is no * type tagging; field representations are simply concatenated together. * * A psuedo-BNF grammar for the credential and principal formats is: * * credential ::= * client (principal) * server (principal) * keyblock (keyblock) * authtime (32 bits) * starttime (32 bits) * endtime (32 bits) * renew_till (32 bits) * is_skey (1 byte, 0 or 1) * ticket_flags (32 bits) * addresses (addresses) * authdata (authdata) * ticket (data) * second_ticket (data) * * principal ::= * name type (32 bits) [omitted in version 1] * count of components (32 bits) [includes realm in version 1] * realm (data) * component1 (data) * component2 (data) * ... * * keyblock ::= * enctype (16 bits) [repeated twice in version 3; see below] * data * * addresses ::= * count (32 bits) * address1 * address2 * ... * * address ::= * addrtype (16 bits) * data * * authdata ::= * count (32 bits) * authdata1 * authdata2 * ... * * authdata ::= * ad_type (16 bits) * data * * data ::= * length (32 bits) * value (length bytes) * * When version 3 was current (before release 1.0), the keyblock had separate * key type and enctype fields, and both were recorded. At present we record * the enctype field twice when writing the version 3 format and ignore the * second value when reading it. */ #include "cc-int.h" #include "k5-input.h" /* Read a 16-bit integer in host byte order for versions 1 and 2, or in * big-endian byte order for later versions.*/ static uint16_t get16(struct k5input *in, int version) { return (version < 3) ? k5_input_get_uint16_n(in) : k5_input_get_uint16_be(in); } /* Read a 32-bit integer in host byte order for versions 1 and 2, or in * big-endian byte order for later versions.*/ static uint32_t get32(struct k5input *in, int version) { return (version < 3) ? k5_input_get_uint32_n(in) : k5_input_get_uint32_be(in); } /* Read a 32-bit length and make a copy of that many bytes. Return NULL on * error. */ static void * get_len_bytes(struct k5input *in, int version, unsigned int *len_out) { krb5_error_code ret; unsigned int len = get32(in, version); const void *bytes = k5_input_get_bytes(in, len); void *copy; *len_out = 0; if (bytes == NULL) return NULL; copy = k5memdup0(bytes, len, &ret); if (copy == NULL) { k5_input_set_status(in, ret); return NULL; } *len_out = len; return copy; } /* Like get_len_bytes, but put the result in data. */ static void get_data(struct k5input *in, int version, krb5_data *data) { unsigned int len; void *bytes = get_len_bytes(in, version, &len); *data = (bytes == NULL) ? empty_data() : make_data(bytes, len); } static krb5_principal unmarshal_princ(struct k5input *in, int version) { krb5_error_code ret; krb5_principal princ; uint32_t i, ncomps; princ = k5alloc(sizeof(krb5_principal_data), &ret); if (princ == NULL) { k5_input_set_status(in, ret); return NULL; } princ->magic = KV5M_PRINCIPAL; /* Version 1 does not store the principal name type, and counts the realm * in the number of components. */ princ->type = (version == 1) ? KRB5_NT_UNKNOWN : get32(in, version); ncomps = get32(in, version); if (version == 1) ncomps--; if (ncomps > in->len) { /* Sanity check to avoid large allocations */ ret = EINVAL; goto error; } if (ncomps != 0) { princ->data = k5calloc(ncomps, sizeof(krb5_data), &ret); if (princ->data == NULL) goto error; princ->length = ncomps; } get_data(in, version, &princ->realm); for (i = 0; i < ncomps; i++) get_data(in, version, &princ->data[i]); return princ; error: k5_input_set_status(in, ret); krb5_free_principal(NULL, princ); return NULL; } static void unmarshal_keyblock(struct k5input *in, int version, krb5_keyblock *kb) { memset(kb, 0, sizeof(*kb)); kb->magic = KV5M_KEYBLOCK; /* enctypes can be negative, so sign-extend the 16-bit result. */ kb->enctype = (int16_t)get16(in, version); /* Version 3 stores the enctype twice. */ if (version == 3) (void)get16(in, version); kb->contents = get_len_bytes(in, version, &kb->length); } static krb5_address * unmarshal_addr(struct k5input *in, int version) { krb5_address *addr; addr = calloc(1, sizeof(*addr)); if (addr == NULL) { k5_input_set_status(in, ENOMEM); return NULL; } addr->magic = KV5M_ADDRESS; addr->addrtype = get16(in, version); addr->contents = get_len_bytes(in, version, &addr->length); return addr; } static krb5_address ** unmarshal_addrs(struct k5input *in, int version) { krb5_address **addrs; size_t i, count; count = get32(in, version); if (count > in->len) { /* Sanity check to avoid large allocations */ k5_input_set_status(in, EINVAL); return NULL; } addrs = calloc(count + 1, sizeof(*addrs)); if (addrs == NULL) { k5_input_set_status(in, ENOMEM); return NULL; } for (i = 0; i < count; i++) addrs[i] = unmarshal_addr(in, version); return addrs; } static krb5_authdata * unmarshal_authdatum(struct k5input *in, int version) { krb5_authdata *ad; ad = calloc(1, sizeof(*ad)); if (ad == NULL) { k5_input_set_status(in, ENOMEM); return NULL; } ad->magic = KV5M_ADDRESS; /* Authdata types can be negative, so sign-extend the get16 result. */ ad->ad_type = (int16_t)get16(in, version); ad->contents = get_len_bytes(in, version, &ad->length); return ad; } static krb5_authdata ** unmarshal_authdata(struct k5input *in, int version) { krb5_authdata **authdata; size_t i, count; count = get32(in, version); if (count > in->len) { /* Sanity check to avoid large allocations */ k5_input_set_status(in, EINVAL); return NULL; } authdata = calloc(count + 1, sizeof(*authdata)); if (authdata == NULL) { k5_input_set_status(in, ENOMEM); return NULL; } for (i = 0; i < count; i++) authdata[i] = unmarshal_authdatum(in, version); return authdata; } /* Unmarshal a credential using the specified file ccache version (expressed as * an integer from 1 to 4). Does not check for trailing garbage. */ krb5_error_code k5_unmarshal_cred(const unsigned char *data, size_t len, int version, krb5_creds *creds) { struct k5input in; k5_input_init(&in, data, len); creds->client = unmarshal_princ(&in, version); creds->server = unmarshal_princ(&in, version); unmarshal_keyblock(&in, version, &creds->keyblock); creds->times.authtime = get32(&in, version); creds->times.starttime = get32(&in, version); creds->times.endtime = get32(&in, version); creds->times.renew_till = get32(&in, version); creds->is_skey = k5_input_get_byte(&in); creds->ticket_flags = get32(&in, version); creds->addresses = unmarshal_addrs(&in, version); creds->authdata = unmarshal_authdata(&in, version); get_data(&in, version, &creds->ticket); get_data(&in, version, &creds->second_ticket); if (in.status) { krb5_free_cred_contents(NULL, creds); memset(creds, 0, sizeof(*creds)); } return (in.status == EINVAL) ? KRB5_CC_FORMAT : in.status; } /* Unmarshal a principal using the specified file ccache version (expressed as * an integer from 1 to 4). Does not check for trailing garbage. */ krb5_error_code k5_unmarshal_princ(const unsigned char *data, size_t len, int version, krb5_principal *princ_out) { struct k5input in; krb5_principal princ; *princ_out = NULL; k5_input_init(&in, data, len); princ = unmarshal_princ(&in, version); if (in.status) krb5_free_principal(NULL, princ); else *princ_out = princ; return (in.status == EINVAL) ? KRB5_CC_FORMAT : in.status; } /* Store a 16-bit integer in host byte order for versions 1 and 2, or in * big-endian byte order for later versions.*/ static void put16(struct k5buf *buf, int version, uint16_t num) { char n[2]; if (version < 3) store_16_n(num, n); else store_16_be(num, n); k5_buf_add_len(buf, n, 2); } /* Store a 32-bit integer in host byte order for versions 1 and 2, or in * big-endian byte order for later versions.*/ static void put32(struct k5buf *buf, int version, uint32_t num) { char n[4]; if (version < 3) store_32_n(num, n); else store_32_be(num, n); k5_buf_add_len(buf, n, 4); } static void put_len_bytes(struct k5buf *buf, int version, const void *bytes, unsigned int len) { put32(buf, version, len); k5_buf_add_len(buf, bytes, len); } static void put_data(struct k5buf *buf, int version, krb5_data *data) { put_len_bytes(buf, version, data->data, data->length); } void k5_marshal_princ(struct k5buf *buf, int version, krb5_principal princ) { int32_t i, ncomps; /* Version 1 does not store the principal name type, and counts the realm * in the number of components. */ if (version != 1) put32(buf, version, princ->type); ncomps = princ->length + ((version == 1) ? 1 : 0); put32(buf, version, ncomps); put_data(buf, version, &princ->realm); for (i = 0; i < princ->length; i++) put_data(buf, version, &princ->data[i]); } static void marshal_keyblock(struct k5buf *buf, int version, krb5_keyblock *kb) { put16(buf, version, kb->enctype); /* Version 3 stores the enctype twice. */ if (version == 3) put16(buf, version, kb->enctype); put_len_bytes(buf, version, kb->contents, kb->length); } static void marshal_addrs(struct k5buf *buf, int version, krb5_address **addrs) { size_t i, count; for (count = 0; addrs != NULL && addrs[count] != NULL; count++); put32(buf, version, count); for (i = 0; i < count; i++) { put16(buf, version, addrs[i]->addrtype); put_len_bytes(buf, version, addrs[i]->contents, addrs[i]->length); } } static void marshal_authdata(struct k5buf *buf, int version, krb5_authdata **authdata) { size_t i, count; for (count = 0; authdata != NULL && authdata[count] != NULL; count++); put32(buf, version, count); for (i = 0; i < count; i++) { put16(buf, version, authdata[i]->ad_type); put_len_bytes(buf, version, authdata[i]->contents, authdata[i]->length); } } /* Marshal a credential using the specified file ccache version (expressed as * an integer from 1 to 4). */ void k5_marshal_cred(struct k5buf *buf, int version, krb5_creds *creds) { char is_skey; k5_marshal_princ(buf, version, creds->client); k5_marshal_princ(buf, version, creds->server); marshal_keyblock(buf, version, &creds->keyblock); put32(buf, version, creds->times.authtime); put32(buf, version, creds->times.starttime); put32(buf, version, creds->times.endtime); put32(buf, version, creds->times.renew_till); is_skey = creds->is_skey; k5_buf_add_len(buf, &is_skey, 1); put32(buf, version, creds->ticket_flags); marshal_addrs(buf, version, creds->addresses); marshal_authdata(buf, version, creds->authdata); put_data(buf, version, &creds->ticket); put_data(buf, version, &creds->second_ticket); } #define SC_CLIENT_PRINCIPAL 0x0001 #define SC_SERVER_PRINCIPAL 0x0002 #define SC_SESSION_KEY 0x0004 #define SC_TICKET 0x0008 #define SC_SECOND_TICKET 0x0010 #define SC_AUTHDATA 0x0020 #define SC_ADDRESSES 0x0040 /* Construct the header flags field for a matching credential for the Heimdal * KCM format. */ static uint32_t mcred_header(krb5_creds *mcred) { uint32_t header = 0; if (mcred->client != NULL) header |= SC_CLIENT_PRINCIPAL; if (mcred->server != NULL) header |= SC_SERVER_PRINCIPAL; if (mcred->keyblock.enctype != ENCTYPE_NULL) header |= SC_SESSION_KEY; if (mcred->ticket.length > 0) header |= SC_TICKET; if (mcred->second_ticket.length > 0) header |= SC_SECOND_TICKET; if (mcred->authdata != NULL && *mcred->authdata != NULL) header |= SC_AUTHDATA; if (mcred->addresses != NULL && *mcred->addresses != NULL) header |= SC_ADDRESSES; return header; } /* * Marshal a matching credential in the Heimdal KCM format. Matching * credentials are used to identify an existing credential to retrieve or * remove from a cache. */ void k5_marshal_mcred(struct k5buf *buf, krb5_creds *mcred) { const int version = 4; /* subfields use v4 file format */ uint32_t header; char is_skey; header = mcred_header(mcred); put32(buf, version, header); if (mcred->client != NULL) k5_marshal_princ(buf, version, mcred->client); if (mcred->server != NULL) k5_marshal_princ(buf, version, mcred->server); if (mcred->keyblock.enctype != ENCTYPE_NULL) marshal_keyblock(buf, version, &mcred->keyblock); put32(buf, version, mcred->times.authtime); put32(buf, version, mcred->times.starttime); put32(buf, version, mcred->times.endtime); put32(buf, version, mcred->times.renew_till); is_skey = mcred->is_skey; k5_buf_add_len(buf, &is_skey, 1); put32(buf, version, mcred->ticket_flags); if (mcred->addresses != NULL && *mcred->addresses != NULL) marshal_addrs(buf, version, mcred->addresses); if (mcred->authdata != NULL && *mcred->authdata != NULL) marshal_authdata(buf, version, mcred->authdata); if (mcred->ticket.length > 0) put_data(buf, version, &mcred->ticket); if (mcred->second_ticket.length > 0) put_data(buf, version, &mcred->second_ticket); } krb5_error_code KRB5_CALLCONV krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds, krb5_data **data_out) { krb5_error_code ret; krb5_data *data; struct k5buf buf; *data_out = NULL; data = k5alloc(sizeof(krb5_data), &ret); if (ret) return ret; k5_buf_init_dynamic(&buf); k5_marshal_cred(&buf, 4, in_creds); ret = k5_buf_status(&buf); if (ret) { free(data); return ret; } /* Steal payload from buf. */ *data = make_data(buf.data, buf.len); *data_out = data; return 0; } krb5_error_code KRB5_CALLCONV krb5_unmarshal_credentials(krb5_context context, const krb5_data *data, krb5_creds **creds_out) { krb5_error_code ret; krb5_creds *creds; *creds_out = NULL; creds = k5alloc(sizeof(krb5_creds), &ret); if (ret) return ret; ret = k5_unmarshal_cred((unsigned char *)data->data, data->length, 4, creds); if (ret) { free(creds); return ret; } *creds_out = creds; return 0; } krb5-1.22.1/src/lib/krb5/ccache/t_cccursor.c0000664000175000017500000000563515051422640020272 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/t_cccursor.c - Simple test harness for cccol API */ /* * Copyright 2011 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Displays a list of caches returned by the cccol cursor. The first argument, * if given, is set to the default cache name for the context before iterating. * Any remaining arguments are resolved as caches and kept open during the * iteration. If the argument "CONTENT" is given as one of the cache names, * immediately exit with status 0 if the collection contains credentials and 1 * if it does not. */ #include "k5-int.h" int main(int argc, char **argv) { krb5_error_code ret; krb5_context ctx; krb5_cccol_cursor cursor; krb5_ccache cache, hold[64]; int i; char *name; assert(krb5_init_context(&ctx) == 0); if (argc > 1) assert(krb5_cc_set_default_name(ctx, argv[1]) == 0); if (argc > 2) { assert(argc < 60); for (i = 2; i < argc; i++) { if (strcmp(argv[i], "CONTENT") == 0) { ret = krb5_cccol_have_content(ctx); krb5_free_context(ctx); return ret != 0; } assert(krb5_cc_resolve(ctx, argv[i], &hold[i - 2]) == 0); } } assert(krb5_cccol_cursor_new(ctx, &cursor) == 0); while (1) { assert(krb5_cccol_cursor_next(ctx, cursor, &cache) == 0); if (cache == NULL) break; assert(krb5_cc_get_full_name(ctx, cache, &name) == 0); printf("%s\n", name); krb5_free_string(ctx, name); krb5_cc_close(ctx, cache); } assert(krb5_cccol_cursor_free(ctx, &cursor) == 0); for (i = 2; i < argc; i++) krb5_cc_close(ctx, hold[i - 2]); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/lib/krb5/ccache/ccdefault.c0000664000175000017500000000703215051422640020047 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccdefault.c - Find default credential cache */ /* * Copyright 1990, 2007, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #ifdef USE_LEASH static void (*pLeash_AcquireInitialTicketsIfNeeded)(krb5_context,krb5_principal,char*,int) = NULL; static HANDLE hLeashDLL = INVALID_HANDLE_VALUE; #ifdef _WIN64 #define LEASH_DLL "leashw64.dll" #else #define LEASH_DLL "leashw32.dll" #endif #endif krb5_error_code KRB5_CALLCONV krb5_cc_default(krb5_context context, krb5_ccache *ccache) { const char *default_name; if (!context || context->magic != KV5M_CONTEXT) return KV5M_CONTEXT; default_name = krb5_cc_default_name(context); if (default_name == NULL) { /* Could be a bogus context, or an allocation failure, or other things. Unfortunately the API doesn't allow us to find out any specifics. */ return KRB5_FCC_INTERNAL; } return krb5_cc_resolve(context, default_name, ccache); } /* This is the internal function which opens the default ccache. On platforms supporting the login library's automatic popup dialog to get tickets, this function also updated the library's internal view of the current principal associated with this cache. All krb5 and GSS functions which need to open a cache to get a tgt to obtain service tickets should call this function, not krb5_cc_default(). */ krb5_error_code KRB5_CALLCONV krb5int_cc_default(krb5_context context, krb5_ccache *ccache) { if (!context || context->magic != KV5M_CONTEXT) { return KV5M_CONTEXT; } #ifdef USE_LEASH if ( hLeashDLL == INVALID_HANDLE_VALUE ) { hLeashDLL = LoadLibrary(LEASH_DLL); if ( hLeashDLL != INVALID_HANDLE_VALUE ) { (FARPROC) pLeash_AcquireInitialTicketsIfNeeded = GetProcAddress(hLeashDLL, "not_an_API_Leash_AcquireInitialTicketsIfNeeded"); } } if ( pLeash_AcquireInitialTicketsIfNeeded ) { char ccname[256]=""; pLeash_AcquireInitialTicketsIfNeeded(context, NULL, ccname, sizeof(ccname)); if (ccname[0]) { char * ccdefname = krb5_cc_default_name (context); if (!ccdefname || strcmp (ccdefname, ccname) != 0) { krb5_cc_set_default_name (context, ccname); } } } #endif return krb5_cc_default (context, ccache); } krb5-1.22.1/src/lib/krb5/ccache/deps0000664000175000017500000004156315051422640016636 0ustar ghudsonghudson# # Generated makefile dependencies follow. # ccapi_util.so ccapi_util.po $(OUTPRE)ccapi_util.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cc-int.h ccapi_util.c ccapi_util.h ccbase.so ccbase.po $(OUTPRE)ccbase.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h ccbase.c \ fcc.h cccopy.so cccopy.po $(OUTPRE)cccopy.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cccopy.c cccursor.so cccursor.po $(OUTPRE)cccursor.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../krb/int-proto.h $(srcdir)/../os/os-proto.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h cccursor.c ccdefault.so ccdefault.po $(OUTPRE)ccdefault.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ccdefault.c ccdefops.so ccdefops.po $(OUTPRE)ccdefops.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ccdefops.c fcc.h ccmarshal.so ccmarshal.po $(OUTPRE)ccmarshal.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-input.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h ccmarshal.c ccselect.so ccselect.po $(OUTPRE)ccselect.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../krb/int-proto.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/ccselect_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cc-int.h ccselect.c ccselect_hostname.so ccselect_hostname.po $(OUTPRE)ccselect_hostname.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/ccselect_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h ccselect_hostname.c ccselect_k5identity.so ccselect_k5identity.po $(OUTPRE)ccselect_k5identity.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/ccselect_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h ccselect_k5identity.c ccselect_realm.so ccselect_realm.po $(OUTPRE)ccselect_realm.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/ccselect_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h ccselect_realm.c cc_api_macos.so cc_api_macos.po $(OUTPRE)cc_api_macos.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/CredentialsCache.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cc-int.h cc_api_macos.c ccapi_util.h cc_dir.so cc_dir.po $(OUTPRE)cc_dir.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h cc_dir.c cc_retr.so cc_retr.po $(OUTPRE)cc_retr.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/int-proto.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cc-int.h cc_retr.c cc_file.so cc_file.po $(OUTPRE)cc_file.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h cc_file.c cc_kcm.so cc_kcm.po $(OUTPRE)cc_kcm.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../os/os-proto.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-input.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/kcm.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h cc_kcm.c cc_memory.so cc_memory.po $(OUTPRE)cc_memory.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(srcdir)/../krb/int-proto.h $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-hashtab.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cc-int.h cc_memory.c cc_keyring.so cc_keyring.po $(OUTPRE)cc_keyring.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cc-int.h cc_keyring.c ccfns.so ccfns.po $(OUTPRE)ccfns.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../krb/int-proto.h \ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cc-int.h ccfns.c t_cc.so t_cc.po $(OUTPRE)t_cc.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ $(top_srcdir)/include/socket-utils.h cc-int.h t_cc.c t_cccol.so t_cccol.po $(OUTPRE)t_cccol.$(OBJEXT): $(BUILDTOP)/include/krb5/krb5.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h t_cccol.c t_cccursor.so t_cccursor.po $(OUTPRE)t_cccursor.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ t_cccursor.c t_marshal.so t_marshal.po $(OUTPRE)t_marshal.$(OBJEXT): \ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ cc-int.h t_marshal.c krb5-1.22.1/src/lib/krb5/ccache/cc-int.h0000664000175000017500000001775215051422640017311 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cc-int.h */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* This file contains constant and function declarations used in the * file-based credential cache routines. */ #ifndef __KRB5_CCACHE_H__ #define __KRB5_CCACHE_H__ #include "k5-int.h" struct _krb5_ccache { krb5_magic magic; const struct _krb5_cc_ops *ops; krb5_pointer data; }; krb5_error_code k5_cc_retrieve_cred_default(krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *); krb5_boolean krb5int_cc_creds_match_request(krb5_context, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds); int krb5int_cc_initialize(void); void krb5int_cc_finalize(void); krb5_error_code k5_nonatomic_replace(krb5_context context, krb5_ccache ccache, krb5_principal princ, krb5_creds **creds); /* * Cursor for iterating over ccache types */ struct krb5_cc_typecursor; typedef struct krb5_cc_typecursor *krb5_cc_typecursor; krb5_error_code krb5int_cc_typecursor_new(krb5_context context, krb5_cc_typecursor *cursor); krb5_error_code krb5int_cc_typecursor_next( krb5_context context, krb5_cc_typecursor cursor, const struct _krb5_cc_ops **ops); krb5_error_code krb5int_cc_typecursor_free( krb5_context context, krb5_cc_typecursor *cursor); /* reentrant mutex used by krb5_cc_* functions */ typedef struct _k5_cc_mutex { k5_mutex_t lock; krb5_context owner; krb5_int32 refcount; } k5_cc_mutex; #define K5_CC_MUTEX_PARTIAL_INITIALIZER \ { K5_MUTEX_PARTIAL_INITIALIZER, NULL, 0 } krb5_error_code k5_cc_mutex_init(k5_cc_mutex *m); krb5_error_code k5_cc_mutex_finish_init(k5_cc_mutex *m); #define k5_cc_mutex_destroy(M) \ k5_mutex_destroy(&(M)->lock); void k5_cc_mutex_assert_locked(krb5_context context, k5_cc_mutex *m); void k5_cc_mutex_assert_unlocked(krb5_context context, k5_cc_mutex *m); void k5_cc_mutex_lock(krb5_context context, k5_cc_mutex *m); void k5_cc_mutex_unlock(krb5_context context, k5_cc_mutex *m); extern k5_cc_mutex krb5int_mcc_mutex; extern k5_cc_mutex krb5int_krcc_mutex; extern k5_cc_mutex krb5int_cc_file_mutex; extern krb5_error_code KRB5_CALLCONV krb5_stdccv3_context_lock (krb5_context context); extern krb5_error_code KRB5_CALLCONV krb5_stdccv3_context_unlock (krb5_context context); krb5_error_code k5_cc_lock(krb5_context context, krb5_ccache ccache); krb5_error_code k5_cc_unlock(krb5_context context, krb5_ccache ccache); krb5_error_code k5_cccol_lock(krb5_context context); krb5_error_code k5_cccol_unlock(krb5_context context); void k5_cc_mutex_force_unlock(k5_cc_mutex *m); void k5_cccol_force_unlock(void); krb5_error_code krb5int_fcc_new_unique(krb5_context context, char *template, krb5_ccache *id); krb5_error_code ccselect_hostname_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code ccselect_realm_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code ccselect_k5identity_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code k5_unmarshal_cred(const unsigned char *data, size_t len, int version, krb5_creds *creds); krb5_error_code k5_unmarshal_princ(const unsigned char *data, size_t len, int version, krb5_principal *princ_out); void k5_marshal_cred(struct k5buf *buf, int version, krb5_creds *creds); void k5_marshal_mcred(struct k5buf *buf, krb5_creds *mcred); void k5_marshal_princ(struct k5buf *buf, int version, krb5_principal princ); krb5_error_code k5_kcm_primary_name(krb5_context context, char **name_out); /* * Per-type ccache cursor. */ struct krb5_cc_ptcursor_s { const struct _krb5_cc_ops *ops; krb5_pointer data; }; typedef struct krb5_cc_ptcursor_s *krb5_cc_ptcursor; struct _krb5_cc_ops { krb5_magic magic; char *prefix; const char * (KRB5_CALLCONV *get_name)(krb5_context, krb5_ccache); krb5_error_code (KRB5_CALLCONV *resolve)(krb5_context, krb5_ccache *, const char *); krb5_error_code (KRB5_CALLCONV *gen_new)(krb5_context, krb5_ccache *); krb5_error_code (KRB5_CALLCONV *init)(krb5_context, krb5_ccache, krb5_principal); krb5_error_code (KRB5_CALLCONV *destroy)(krb5_context, krb5_ccache); krb5_error_code (KRB5_CALLCONV *close)(krb5_context, krb5_ccache); krb5_error_code (KRB5_CALLCONV *store)(krb5_context, krb5_ccache, krb5_creds *); krb5_error_code (KRB5_CALLCONV *retrieve)(krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *); krb5_error_code (KRB5_CALLCONV *get_princ)(krb5_context, krb5_ccache, krb5_principal *); krb5_error_code (KRB5_CALLCONV *get_first)(krb5_context, krb5_ccache, krb5_cc_cursor *); krb5_error_code (KRB5_CALLCONV *get_next)(krb5_context, krb5_ccache, krb5_cc_cursor *, krb5_creds *); krb5_error_code (KRB5_CALLCONV *end_get)(krb5_context, krb5_ccache, krb5_cc_cursor *); krb5_error_code (KRB5_CALLCONV *remove_cred)(krb5_context, krb5_ccache, krb5_flags, krb5_creds *); krb5_error_code (KRB5_CALLCONV *set_flags)(krb5_context, krb5_ccache, krb5_flags); krb5_error_code (KRB5_CALLCONV *get_flags)(krb5_context, krb5_ccache, krb5_flags *); krb5_error_code (KRB5_CALLCONV *ptcursor_new)(krb5_context, krb5_cc_ptcursor *); krb5_error_code (KRB5_CALLCONV *ptcursor_next)(krb5_context, krb5_cc_ptcursor, krb5_ccache *); krb5_error_code (KRB5_CALLCONV *ptcursor_free)(krb5_context, krb5_cc_ptcursor *); krb5_error_code (KRB5_CALLCONV *replace)(krb5_context, krb5_ccache, krb5_principal, krb5_creds **); krb5_error_code (KRB5_CALLCONV *wasdefault)(krb5_context, krb5_ccache, krb5_timestamp *); krb5_error_code (KRB5_CALLCONV *lock)(krb5_context, krb5_ccache); krb5_error_code (KRB5_CALLCONV *unlock)(krb5_context, krb5_ccache); krb5_error_code (KRB5_CALLCONV *switch_to)(krb5_context, krb5_ccache); }; extern const krb5_cc_ops *krb5_cc_dfl_ops; #endif /* __KRB5_CCACHE_H__ */ krb5-1.22.1/src/lib/krb5/ccache/ccselect_hostname.c0000664000175000017500000001133615051422640021602 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccselect_hostname.c - hostname ccselect module */ /* * Copyright (C) 2017 by Red Hat, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "cc-int.h" #include #include /* Swap a and b, using tmp as an intermediate. */ #define SWAP(a, b, tmp) \ tmp = a; \ a = b; \ b = tmp; static krb5_error_code hostname_init(krb5_context context, krb5_ccselect_moddata *data_out, int *priority_out) { *data_out = NULL; *priority_out = KRB5_CCSELECT_PRIORITY_HEURISTIC; return 0; } static krb5_error_code hostname_choose(krb5_context context, krb5_ccselect_moddata data, krb5_principal server, krb5_ccache *ccache_out, krb5_principal *princ_out) { krb5_error_code ret; char *p, *host = NULL; size_t hostlen; krb5_cccol_cursor col_cursor; krb5_ccache ccache, tmp_ccache, best_ccache = NULL; krb5_principal princ, tmp_princ, best_princ = NULL; krb5_data domain; *ccache_out = NULL; *princ_out = NULL; if (server->type != KRB5_NT_SRV_HST || server->length < 2) return KRB5_PLUGIN_NO_HANDLE; /* Compute upper-case hostname. */ hostlen = server->data[1].length; host = k5memdup0(server->data[1].data, hostlen, &ret); if (host == NULL) return ret; for (p = host; *p != '\0'; p++) { if (islower(*p)) *p = toupper(*p); } /* Scan the collection for a cache with a client principal whose realm is * the longest tail of the server hostname. */ ret = krb5_cccol_cursor_new(context, &col_cursor); if (ret) goto done; for (ret = krb5_cccol_cursor_next(context, col_cursor, &ccache); ret == 0 && ccache != NULL; ret = krb5_cccol_cursor_next(context, col_cursor, &ccache)) { ret = krb5_cc_get_principal(context, ccache, &princ); if (ret) { krb5_cc_close(context, ccache); break; } /* Check for a longer match than we have. */ domain = make_data(host, hostlen); while (best_princ == NULL || best_princ->realm.length < domain.length) { if (data_eq(princ->realm, domain)) { SWAP(best_ccache, ccache, tmp_ccache); SWAP(best_princ, princ, tmp_princ); break; } /* Try the next parent domain. */ p = memchr(domain.data, '.', domain.length); if (p == NULL) break; domain = make_data(p + 1, hostlen - (p + 1 - host)); } if (ccache != NULL) krb5_cc_close(context, ccache); krb5_free_principal(context, princ); } krb5_cccol_cursor_free(context, &col_cursor); if (best_ccache != NULL) { *ccache_out = best_ccache; *princ_out = best_princ; } else { ret = KRB5_PLUGIN_NO_HANDLE; } done: free(host); return ret; } krb5_error_code ccselect_hostname_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_ccselect_vtable vt; if (maj_ver != 1) return KRB5_PLUGIN_VER_NOTSUPP; vt = (krb5_ccselect_vtable)vtable; vt->name = "hostname"; vt->init = hostname_init; vt->choose = hostname_choose; return 0; } krb5-1.22.1/src/lib/krb5/ccache/kcmrpc_types.h0000664000175000017500000000317115051422640020625 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/kcmrpc_types.h - KCM RPC type definitions */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef KCMRPC_H #define KCMRPC_H typedef char k5_kcm_inband_msg[2048]; typedef char *k5_kcm_outband_msg; #endif krb5-1.22.1/src/lib/krb5/ccache/fcc.h0000664000175000017500000000325415051422640016657 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/fcc.h */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * This file contains constant and function declarations used in the * file-based credential cache routines. */ #ifndef __KRB5_FILE_CCACHE__ #define __KRB5_FILE_CCACHE__ extern const krb5_cc_ops krb5_cc_file_ops; krb5_error_code krb5int_fcc_new_unique(krb5_context context, char *template, krb5_ccache *id); #endif /* __KRB5_FILE_CCACHE__ */ krb5-1.22.1/src/lib/krb5/ccache/ccdefops.c0000664000175000017500000000422115051422640017700 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccdefops.c */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* Default credentials cache determination. This is a separate file * so that the user can more easily override it. */ #include "k5-int.h" #if defined(USE_CCAPI) /* * Macs use the shared, memory based credentials cache * Windows may also use the ccapi cache, but only if the Krbcc32.dll * can be found; otherwise it falls back to using the old * file-based ccache. */ #include "stdcc.h" /* from ccapi subdir */ const krb5_cc_ops *krb5_cc_dfl_ops = &krb5_cc_stdcc_ops; #elif defined(NO_FILE_CCACHE) /* Note that this version isn't likely to work very well for multiple processes. It's mostly a placeholder so we can experiment with building the NO_FILE_CCACHE code on UNIX. */ extern const krb5_cc_ops krb5_mcc_ops; const krb5_cc_ops *krb5_cc_dfl_ops = &krb5_mcc_ops; #else #include "fcc.h" const krb5_cc_ops *krb5_cc_dfl_ops = &krb5_cc_file_ops; #endif krb5-1.22.1/src/lib/krb5/ccache/t_cccol.c0000664000175000017500000003146115051422640017526 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/t_cccol.py - Test ccache collection via API */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include static krb5_context ctx; /* Check that code is 0. Display an error message first if it is not. */ static void check(krb5_error_code code) { const char *errmsg; if (code != 0) { errmsg = krb5_get_error_message(ctx, code); fprintf(stderr, "%s\n", errmsg); krb5_free_error_message(ctx, errmsg); } assert(code == 0); } /* Construct a list of the names of each credential cache in the collection. */ static void get_collection_names(char ***list_out, size_t *count_out) { krb5_cccol_cursor cursor; krb5_ccache cache; char **list = NULL; size_t count = 0; char *name; check(krb5_cccol_cursor_new(ctx, &cursor)); while (1) { check(krb5_cccol_cursor_next(ctx, cursor, &cache)); if (cache == NULL) break; check(krb5_cc_get_full_name(ctx, cache, &name)); krb5_cc_close(ctx, cache); list = realloc(list, (count + 1) * sizeof(*list)); assert(list != NULL); list[count++] = name; } krb5_cccol_cursor_free(ctx, &cursor); *list_out = list; *count_out = count; } /* Return true if list contains name. */ static krb5_boolean in_list(char **list, size_t count, const char *name) { size_t i; for (i = 0; i < count; i++) { if (strcmp(list[i], name) == 0) return TRUE; } return FALSE; } /* Release the memory for a list of credential cache names. */ static void free_list(char **list, size_t count) { size_t i; for (i = 0; i < count; i++) krb5_free_string(ctx, list[i]); free(list); } /* * Check that the cache names within the current collection begin with first * (unless first is NULL), that the other elements match the remaining * arguments in some order. others must be the number of additional cache * names. */ static void check_collection(const char *first, size_t others, ...) { va_list ap; char **list; size_t count, i; const char *name; get_collection_names(&list, &count); if (first != NULL) { assert(strcmp(first, list[0]) == 0); assert(count == others + 1); } else { assert(count == others); } va_start(ap, others); for (i = 0; i < others; i++) { name = va_arg(ap, const char *); assert(in_list(list, count, name)); } va_end(ap); free_list(list, count); } /* Check that the name of cache matches expected_name. */ static void check_name(krb5_ccache cache, const char *expected_name) { char *name; check(krb5_cc_get_full_name(ctx, cache, &name)); assert(strcmp(name, expected_name) == 0); krb5_free_string(ctx, name); } /* Check that when collection_name is resolved, the resulting cache's name * matches expected_name. */ static void check_primary_name(const char *collection_name, const char *expected_name) { krb5_ccache cache; check(krb5_cc_resolve(ctx, collection_name, &cache)); check_name(cache, expected_name); krb5_cc_close(ctx, cache); } /* Check that when name is resolved, the resulting cache's principal matches * expected_princ, or has no principal if expected_princ is NULL. */ static void check_princ(const char *name, krb5_principal expected_princ) { krb5_ccache cache; krb5_principal princ; check(krb5_cc_resolve(ctx, name, &cache)); if (expected_princ != NULL) { check(krb5_cc_get_principal(ctx, cache, &princ)); assert(krb5_principal_compare(ctx, princ, expected_princ)); krb5_free_principal(ctx, princ); } else { assert(krb5_cc_get_principal(ctx, cache, &princ) != 0); } krb5_cc_close(ctx, cache); } /* Check that krb5_cc_cache_match on princ returns a cache whose name matches * expected_name, or that the match fails if expected_name is NULL. */ static void check_match(krb5_principal princ, const char *expected_name) { krb5_ccache cache; if (expected_name != NULL) { check(krb5_cc_cache_match(ctx, princ, &cache)); check_name(cache, expected_name); krb5_cc_close(ctx, cache); } else { assert(krb5_cc_cache_match(ctx, princ, &cache) != 0); } } int main(int argc, char **argv) { krb5_ccache ccinitial, ccu1, ccu2; krb5_principal princ1, princ2, princ3; const char *collection_name, *typename; char *initial_primary_name, *unique1_name, *unique2_name; /* * Get the collection name from the command line. This is a ccache name * with collection semantics, like DIR:/path/to/directory. This test * program assumes that the collection is empty to start with. */ assert(argc == 2); collection_name = argv[1]; /* * Set the default ccache for the context to be the collection name, so the * library can find the collection. */ check(krb5_init_context(&ctx)); check(krb5_cc_set_default_name(ctx, collection_name)); /* * Resolve the collection name. Since the collection is empty, this should * generate a subsidiary name of an uninitialized cache. Getting the name * of the resulting cache should give us the subsidiary name, not the * collection name. This resulting subsidiary name should be consistent if * we resolve the collection name again, and the collection should still be * empty since we haven't initialized the cache. */ check(krb5_cc_resolve(ctx, collection_name, &ccinitial)); check(krb5_cc_get_full_name(ctx, ccinitial, &initial_primary_name)); assert(strcmp(initial_primary_name, collection_name) != 0); check_primary_name(collection_name, initial_primary_name); check_collection(NULL, 0); check_princ(collection_name, NULL); check_princ(initial_primary_name, NULL); /* * Before initializing the primary ccache, generate and initialize two * unique caches of the collection's type. Check that the cache names * resolve to the generated caches and appear in the collection. (They * might appear before being initialized; that's not currently considered * important). The primary cache for the collection should remain as the * uninitialized cache from the previous step. */ typename = krb5_cc_get_type(ctx, ccinitial); check(krb5_cc_new_unique(ctx, typename, NULL, &ccu1)); check(krb5_cc_get_full_name(ctx, ccu1, &unique1_name)); check(krb5_parse_name(ctx, "princ1@X", &princ1)); check(krb5_cc_initialize(ctx, ccu1, princ1)); check_princ(unique1_name, princ1); check_match(princ1, unique1_name); check_collection(NULL, 1, unique1_name); check(krb5_cc_new_unique(ctx, typename, NULL, &ccu2)); check(krb5_cc_get_full_name(ctx, ccu2, &unique2_name)); check(krb5_parse_name(ctx, "princ2@X", &princ2)); check(krb5_cc_initialize(ctx, ccu2, princ2)); check_princ(unique2_name, princ2); check_match(princ1, unique1_name); check_match(princ2, unique2_name); check_collection(NULL, 2, unique1_name, unique2_name); assert(strcmp(unique1_name, initial_primary_name) != 0); assert(strcmp(unique1_name, collection_name) != 0); assert(strcmp(unique2_name, initial_primary_name) != 0); assert(strcmp(unique2_name, collection_name) != 0); assert(strcmp(unique2_name, unique1_name) != 0); check_primary_name(collection_name, initial_primary_name); /* * Initialize the initial primary cache. Make sure it didn't change names, * that the previously retrieved name and the collection name both resolve * to the initialized cache, and that it now appears first in the * collection. */ check(krb5_parse_name(ctx, "princ3@X", &princ3)); check(krb5_cc_initialize(ctx, ccinitial, princ3)); check_name(ccinitial, initial_primary_name); check_princ(initial_primary_name, princ3); check_princ(collection_name, princ3); check_match(princ3, initial_primary_name); check_collection(initial_primary_name, 2, unique1_name, unique2_name); /* * Switch the primary cache to each cache we have open. One each switch, * check the primary name, check that the collection resolves to the * expected cache, and check that the new primary name appears first in the * collection. */ check(krb5_cc_switch(ctx, ccu1)); check_primary_name(collection_name, unique1_name); check_princ(collection_name, princ1); check_collection(unique1_name, 2, initial_primary_name, unique2_name); check(krb5_cc_switch(ctx, ccu2)); check_primary_name(collection_name, unique2_name); check_princ(collection_name, princ2); check_collection(unique2_name, 2, initial_primary_name, unique1_name); check(krb5_cc_switch(ctx, ccinitial)); check_primary_name(collection_name, initial_primary_name); check_princ(collection_name, princ3); check_collection(initial_primary_name, 2, unique1_name, unique2_name); /* * Temporarily set the context default ccache to a subsidiary name, and * check that iterating over the collection yields that subsidiary cache * and no others. */ check(krb5_cc_set_default_name(ctx, unique1_name)); check_collection(unique1_name, 0); check(krb5_cc_set_default_name(ctx, collection_name)); /* * Destroy the primary cache. Make sure this causes both the initial * primary name and the collection name to resolve to an uninitialized * cache. Make sure the primary name doesn't change and doesn't appear in * the collection any more. */ check(krb5_cc_destroy(ctx, ccinitial)); check_princ(initial_primary_name, NULL); check_princ(collection_name, NULL); check_primary_name(collection_name, initial_primary_name); check_match(princ1, unique1_name); check_match(princ2, unique2_name); check_match(princ3, NULL); check_collection(NULL, 2, unique1_name, unique2_name); /* * Switch to the first unique cache after destroying the primary cache. * Check that the collection name resolves to this cache and that the new * primary name appears first in the collection. */ check(krb5_cc_switch(ctx, ccu1)); check_primary_name(collection_name, unique1_name); check_princ(collection_name, princ1); check_collection(unique1_name, 1, unique2_name); /* * Destroy the second unique cache (which is not the current primary), * check that it is on longer initialized, and check that it no longer * appears in the collection. Check that destroying the non-primary cache * doesn't affect the primary name. */ check(krb5_cc_destroy(ctx, ccu2)); check_princ(unique2_name, NULL); check_match(princ2, NULL); check_collection(unique1_name, 0); check_primary_name(collection_name, unique1_name); check_match(princ1, unique1_name); check_princ(collection_name, princ1); /* * Destroy the first unique cache. Check that the collection is empty and * still has the same primary name. */ check(krb5_cc_destroy(ctx, ccu1)); check_princ(unique1_name, NULL); check_princ(collection_name, NULL); check_primary_name(collection_name, unique1_name); check_match(princ1, NULL); check_collection(NULL, 0); krb5_free_string(ctx, initial_primary_name); krb5_free_string(ctx, unique1_name); krb5_free_string(ctx, unique2_name); krb5_free_principal(ctx, princ1); krb5_free_principal(ctx, princ2); krb5_free_principal(ctx, princ3); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/lib/krb5/ccache/cccopy.c0000664000175000017500000000160315051422640017373 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "k5-int.h" krb5_error_code KRB5_CALLCONV krb5_cc_copy_creds(krb5_context context, krb5_ccache incc, krb5_ccache outcc) { krb5_error_code code; krb5_cc_cursor cur = 0; krb5_creds creds; if ((code = krb5_cc_start_seq_get(context, incc, &cur))) goto cleanup; while (!(code = krb5_cc_next_cred(context, incc, &cur, &creds))) { code = krb5_cc_store_cred(context, outcc, &creds); krb5_free_cred_contents(context, &creds); if (code) goto cleanup; } if (code != KRB5_CC_END) goto cleanup; code = krb5_cc_end_seq_get(context, incc, &cur); cur = 0; if (code) goto cleanup; code = 0; cleanup: /* If set then we are in an error pathway */ if (cur) krb5_cc_end_seq_get(context, incc, &cur); return(code); } krb5-1.22.1/src/lib/krb5/ccache/cc_api_macos.c0000664000175000017500000004570615051422640020527 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cc_api_macos.c - Native MacOS X ccache code */ /* * Copyright (C) 2022 United States Government as represented by the * Secretary of the Navy. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This ccache module provides compatibility with the default native ccache * type for macOS, by linking against the native Kerberos framework and calling * the CCAPI stubs. Due to workarounds for specific behaviors of the CCAPI * stubs, this implementation is separate from the API ccache implementation * used on Windows. */ #include "k5-int.h" #include "cc-int.h" #include "ccapi_util.h" #include #ifdef USE_CCAPI_MACOS #include #include const krb5_cc_ops krb5_api_macos_ops; struct api_macos_cache_data { char *residual; cc_context_t cc_context; cc_ccache_t cache; }; struct api_macos_ptcursor { krb5_boolean first; char *primary; cc_context_t cc_context; cc_ccache_iterator_t iter; }; /* Map a CCAPI error code to a com_err code. */ static krb5_error_code ccerr2mit(uint32_t err) { switch (err) { case ccNoError: return 0; case ccIteratorEnd: return KRB5_CC_END; case ccErrNoMem: return ENOMEM; case ccErrCCacheNotFound: return KRB5_FCC_NOFILE; default: return KRB5_FCC_INTERNAL; } } /* Construct a ccache handle for residual. Use cc_context if it is not null, * or initialize a new one if it is. */ static krb5_error_code make_cache(const char *residual, cc_context_t cc_context, krb5_ccache *ccache_out) { krb5_ccache cache = NULL; char *residual_copy = NULL; struct api_macos_cache_data *data = NULL; uint32_t err; *ccache_out = NULL; if (cc_context == NULL) { err = cc_initialize(&cc_context, ccapi_version_max, NULL, NULL); if (err != ccNoError) return KRB5_FCC_INTERNAL; } cache = malloc(sizeof(*cache)); if (cache == NULL) goto oom; data = calloc(1, sizeof(*data)); if (data == NULL) goto oom; residual_copy = strdup(residual); if (residual_copy == NULL) goto oom; data->residual = residual_copy; data->cc_context = cc_context; cache->ops = &krb5_api_macos_ops; cache->data = data; cache->magic = KV5M_CCACHE; *ccache_out = cache; return 0; oom: free(cache); free(data); free(residual_copy); if (cc_context) cc_context_release(cc_context); return ENOMEM; } static uint32_t open_cache(struct api_macos_cache_data *data) { if (data->cache != NULL) return ccNoError; return cc_context_open_ccache(data->cc_context, data->residual, &data->cache); } static const char * api_macos_get_name(krb5_context context, krb5_ccache ccache) { struct api_macos_cache_data *data = ccache->data; return data->residual; } /* * We would like to use cc_context_get_default_ccache_name() for this, but that * doesn't work on macOS if the default cache name is set by the environment or * configuration. So we have to do what the underlying macOS Heimdal API cache * type does to fetch the primary name. * * For macOS 11 (Darwin 20) and later, implement just enough of the XCACHE * protocol to fetch the primary UUID. For earlier versions, query the KCM * daemon. */ static krb5_error_code get_primary_name(krb5_context context, char **name_out) { krb5_error_code ret; xpc_connection_t conn = NULL; xpc_object_t request = NULL, reply = NULL; const uint8_t *uuid; uint64_t flags = XPC_CONNECTION_MACH_SERVICE_PRIVILEGED; char uuidstr[37], *end; struct utsname un; long release; *name_out = NULL; if (uname(&un) == 0) { release = strtol(un.release, &end, 10); if (end != un.release && release < 20) { /* Query the KCM daemon for macOS 10 and earlier. */ ret = k5_kcm_primary_name(context, name_out); goto cleanup; } } conn = xpc_connection_create_mach_service("com.apple.GSSCred", NULL, flags); if (conn == NULL) { ret = ENOMEM; goto cleanup; } xpc_connection_set_event_handler(conn, ^(xpc_object_t o){ ; }); xpc_connection_resume(conn); request = xpc_dictionary_create(NULL, NULL, 0); if (request == NULL) { ret = ENOMEM; goto cleanup; } xpc_dictionary_set_string(request, "command", "default"); xpc_dictionary_set_string(request, "mech", "kHEIMTypeKerberos"); reply = xpc_connection_send_message_with_reply_sync(conn, request); if (reply == NULL || xpc_get_type(reply) == XPC_TYPE_ERROR) { ret = KRB5_CC_IO; goto cleanup; } uuid = xpc_dictionary_get_uuid(reply, "default"); if (uuid == NULL) { ret = KRB5_CC_IO; goto cleanup; } uuid_unparse(uuid, uuidstr); *name_out = strdup(uuidstr); ret = (*name_out == NULL) ? ENOMEM : 0; cleanup: if (request != NULL) xpc_release(request); if (reply != NULL) xpc_release(reply); if (conn != NULL) xpc_release(conn); return ret; } static krb5_error_code api_macos_resolve(krb5_context context, krb5_ccache *cache_out, const char *residual) { krb5_error_code ret; char *primary = NULL; if (*residual == '\0') { ret = get_primary_name(context, &primary); if (ret) return ret; residual = primary; } ret = make_cache(residual, NULL, cache_out); free(primary); return ret; } static krb5_error_code api_macos_gen_new(krb5_context context, krb5_ccache *cache_out) { krb5_error_code ret; uint32_t err; cc_context_t cc_context = NULL; cc_ccache_t cc_ccache = NULL; cc_string_t cachename = NULL; struct api_macos_cache_data *data; *cache_out = NULL; err = cc_initialize(&cc_context, ccapi_version_max, NULL, NULL); if (err) goto cleanup; err = cc_context_create_new_ccache(cc_context, cc_credentials_v5, "", &cc_ccache); if (err) goto cleanup; err = cc_ccache_get_name(cc_ccache, &cachename); if (err) goto cleanup; ret = make_cache(cachename->data, cc_context, cache_out); cc_context = NULL; if (!ret) { data = (*cache_out)->data; data->cache = cc_ccache; cc_ccache = NULL; } cleanup: if (cc_context != NULL) cc_context_release(cc_context); if (cc_ccache != NULL) cc_ccache_release(cc_ccache); return err ? KRB5_FCC_INTERNAL : 0; } static krb5_error_code api_macos_initialize(krb5_context context, krb5_ccache cache, krb5_principal princ) { krb5_error_code ret; struct api_macos_cache_data *data = cache->data; uint32_t err; char *princstr = NULL, *prefix_name = NULL; /* Apple's cc_context_create_ccache() requires a name with type prefix. */ if (asprintf(&prefix_name, "API:%s", data->residual) < 0) return ENOMEM; ret = krb5_unparse_name(context, princ, &princstr); if (ret) { free(prefix_name); return ret; } if (data->cache != NULL) { cc_ccache_release(data->cache); data->cache = NULL; } err = cc_context_create_ccache(data->cc_context, prefix_name, cc_credentials_v5, princstr, &data->cache); krb5_free_unparsed_name(context, princstr); free(prefix_name); return ccerr2mit(err); } static krb5_error_code api_macos_close(krb5_context context, krb5_ccache cache) { struct api_macos_cache_data *data = cache->data; if (data->cache != NULL) cc_ccache_release(data->cache); cc_context_release(data->cc_context); free(data->residual); free(data); free(cache); return 0; } static krb5_error_code api_macos_destroy(krb5_context context, krb5_ccache cache) { struct api_macos_cache_data *data = cache->data; open_cache(data); if (data->cache != NULL) { cc_ccache_destroy(data->cache); data->cache = NULL; } return api_macos_close(context, cache); } static krb5_error_code api_macos_store(krb5_context context, krb5_ccache cache, krb5_creds *creds) { struct api_macos_cache_data *data = cache->data; cc_credentials_union *c_un = NULL; krb5_error_code ret; uint32_t err; err = open_cache(data); if (err) return ccerr2mit(err); ret = k5_krb5_to_ccapi_creds(context, creds, &c_un); if (ret) return ret; err = cc_ccache_store_credentials(data->cache, c_un); k5_release_ccapi_cred(c_un); return ccerr2mit(err); } static krb5_error_code api_macos_retrieve(krb5_context context, krb5_ccache cache, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds) { return k5_cc_retrieve_cred_default(context, cache, whichfields, mcreds, creds); } static krb5_error_code api_macos_get_princ(krb5_context context, krb5_ccache cache, krb5_principal *princ) { struct api_macos_cache_data *data = cache->data; krb5_error_code ret; uint32_t err; cc_string_t outprinc; err = open_cache(data); if (err) return ccerr2mit(err); err = cc_ccache_get_principal(data->cache, cc_credentials_v5, &outprinc); if (err) return ccerr2mit(err); ret = krb5_parse_name(context, outprinc->data, princ); cc_string_release(outprinc); return ret; } static krb5_error_code api_macos_start_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor) { struct api_macos_cache_data *data = cache->data; uint32_t err; cc_credentials_iterator_t iter; err = open_cache(data); if (err) return ccerr2mit(err); err = cc_ccache_new_credentials_iterator(data->cache, &iter); if (err) return ccerr2mit(err); *cursor = (krb5_cc_cursor)iter; return 0; } static krb5_error_code api_macos_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, krb5_creds *creds) { struct api_macos_cache_data *data = cache->data; uint32_t err; krb5_error_code ret; cc_credentials_iterator_t iter = (cc_credentials_iterator_t) *cursor; cc_credentials_t acreds; err = open_cache(data); if (err) return ccerr2mit(err); err = cc_credentials_iterator_next(iter, &acreds); if (!err) { ret = k5_ccapi_to_krb5_creds(context, acreds->data, creds); cc_credentials_release(acreds); } else { ret = ccerr2mit(err); } return ret; } static krb5_error_code api_macos_end_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor) { cc_credentials_iterator_t iter = *cursor; cc_credentials_iterator_release(iter); *cursor = NULL; return 0; } static krb5_error_code api_macos_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *creds) { struct api_macos_cache_data *data = cache->data; uint32_t err; krb5_error_code ret = 0; cc_credentials_iterator_t iter = NULL; cc_credentials_t acreds; krb5_creds mcreds; krb5_boolean match; err = open_cache(data); if (err) return ccerr2mit(err); err = cc_ccache_new_credentials_iterator(data->cache, &iter); if (err) return ccerr2mit(err); for (;;) { err = cc_credentials_iterator_next(iter, &acreds); if (err) break; ret = k5_ccapi_to_krb5_creds(context, acreds->data, &mcreds); if (ret) { cc_credentials_release(acreds); break; } match = krb5int_cc_creds_match_request(context, flags, creds, &mcreds); krb5_free_cred_contents(context, &mcreds); if (match) err = cc_ccache_remove_credentials(data->cache, acreds); cc_credentials_release(acreds); if (err) break; } cc_credentials_iterator_release(iter); if (ret) return ret; if (err != ccIteratorEnd) return ccerr2mit(err); return 0; } static krb5_error_code api_macos_set_flags(krb5_context context, krb5_ccache cache, krb5_flags flags) { return 0; } static krb5_error_code api_macos_get_flags(krb5_context context, krb5_ccache cache, krb5_flags *flags) { *flags = 0; return 0; } static krb5_error_code api_macos_ptcursor_new(krb5_context context, krb5_cc_ptcursor *ptcursor_out) { krb5_cc_ptcursor ptcursor = NULL; struct api_macos_ptcursor *apt = NULL; apt = malloc(sizeof(*apt)); if (apt == NULL) return ENOMEM; apt->first = TRUE; apt->primary = NULL; apt->cc_context = NULL; apt->iter = NULL; ptcursor = malloc(sizeof(*ptcursor)); if (ptcursor == NULL) { free(apt); return ENOMEM; } ptcursor->ops = &krb5_api_macos_ops; ptcursor->data = apt; *ptcursor_out = ptcursor; return 0; } /* Create a cache object and open it to ensure that it exists in the * collection. If it does not, return success but set *cache_out to NULL. */ static krb5_error_code make_open_cache(const char *residual, krb5_ccache *cache_out) { krb5_error_code ret; krb5_ccache cache; uint32_t err; *cache_out = NULL; ret = make_cache(residual, NULL, &cache); if (ret) return ret; err = open_cache(cache->data); if (err) { api_macos_close(NULL, cache); return (err == ccErrCCacheNotFound) ? 0 : ccerr2mit(err); } *cache_out = cache; return 0; } static krb5_error_code api_macos_ptcursor_next(krb5_context context, krb5_cc_ptcursor ptcursor, krb5_ccache *cache_out) { krb5_error_code ret; uint32_t err; struct api_macos_ptcursor *apt = ptcursor->data; const char *defname, *defresidual; cc_ccache_t cache; cc_string_t residual; struct api_macos_cache_data *data; *cache_out = NULL; defname = krb5_cc_default_name(context); if (defname == NULL || strncmp(defname, "API:", 4) != 0) return 0; defresidual = defname + 4; /* If the default cache name is a subsidiary cache, yield that cache if it * exists and stop. */ if (*defresidual != '\0') { if (!apt->first) return 0; apt->first = FALSE; return make_open_cache(defresidual, cache_out); } if (apt->first) { apt->first = FALSE; /* Prepare to iterate over the collection. */ err = cc_initialize(&apt->cc_context, ccapi_version_max, NULL, NULL); if (err) return KRB5_FCC_INTERNAL; err = cc_context_new_ccache_iterator(apt->cc_context, &apt->iter); if (err) return KRB5_FCC_INTERNAL; /* Yield the primary cache first if it exists. */ ret = get_primary_name(context, &apt->primary); if (ret) return ret; ret = make_open_cache(apt->primary, cache_out); if (ret || *cache_out != NULL) return ret; } for (;;) { err = cc_ccache_iterator_next(apt->iter, &cache); if (err) return (err == ccIteratorEnd) ? 0 : ccerr2mit(err); err = cc_ccache_get_name(cache, &residual); if (err) { cc_ccache_release(cache); return ccerr2mit(err); } /* Skip the primary cache since we yielded it first. */ if (strcmp(residual->data, apt->primary) != 0) break; } ret = make_cache(residual->data, NULL, cache_out); cc_string_release(residual); if (ret) { cc_ccache_release(cache); return ret; } data = (*cache_out)->data; data->cache = cache; return 0; } static krb5_error_code api_macos_ptcursor_free(krb5_context context, krb5_cc_ptcursor *ptcursor) { struct api_macos_ptcursor *apt = (*ptcursor)->data; if (apt != NULL) { if (apt->iter != NULL) cc_ccache_iterator_release(apt->iter); if (apt->cc_context != NULL) cc_context_release(apt->cc_context); free(apt->primary); free(apt); } free(*ptcursor); *ptcursor = NULL; return 0; } static krb5_error_code api_macos_lock(krb5_context context, krb5_ccache cache) { struct api_macos_cache_data *data = cache->data; uint32_t err; err = open_cache(data); if (err) return ccerr2mit(err); err = cc_ccache_lock(data->cache, cc_lock_write, cc_lock_block); return ccerr2mit(err); } static krb5_error_code api_macos_unlock(krb5_context context, krb5_ccache cache) { struct api_macos_cache_data *data = cache->data; uint32_t err; err = open_cache(data); if (err) return ccerr2mit(err); err = cc_ccache_unlock(data->cache); return ccerr2mit(err); } static krb5_error_code api_macos_switch_to(krb5_context context, krb5_ccache cache) { struct api_macos_cache_data *data = cache->data; uint32_t err; err = open_cache(data); if (err) return ccerr2mit(err); err = cc_ccache_set_default(data->cache); return ccerr2mit(err); } const krb5_cc_ops krb5_api_macos_ops = { 0, "API", api_macos_get_name, api_macos_resolve, api_macos_gen_new, api_macos_initialize, api_macos_destroy, api_macos_close, api_macos_store, api_macos_retrieve, api_macos_get_princ, api_macos_start_seq_get, api_macos_next_cred, api_macos_end_seq_get, api_macos_remove_cred, api_macos_set_flags, api_macos_get_flags, api_macos_ptcursor_new, api_macos_ptcursor_next, api_macos_ptcursor_free, NULL, /* move */ NULL, /* wasdefault */ api_macos_lock, api_macos_unlock, api_macos_switch_to, }; #endif /* TARGET_OS_MAC */ krb5-1.22.1/src/lib/krb5/ccache/cc_memory.c0000664000175000017500000005345615051422640020105 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cc_memory.c - Memory-based credential cache */ /* * Copyright 1990,1991,2000,2004,2008 by the Massachusetts Institute of * Technology. All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "cc-int.h" #include "../krb/int-proto.h" #include "k5-hashtab.h" #include static krb5_error_code KRB5_CALLCONV krb5_mcc_close (krb5_context, krb5_ccache id ); static krb5_error_code KRB5_CALLCONV krb5_mcc_destroy (krb5_context, krb5_ccache id ); static krb5_error_code KRB5_CALLCONV krb5_mcc_end_seq_get (krb5_context, krb5_ccache id , krb5_cc_cursor *cursor ); static krb5_error_code KRB5_CALLCONV krb5_mcc_generate_new (krb5_context, krb5_ccache *id ); static const char * KRB5_CALLCONV krb5_mcc_get_name (krb5_context, krb5_ccache id ); static krb5_error_code KRB5_CALLCONV krb5_mcc_get_principal (krb5_context, krb5_ccache id , krb5_principal *princ ); static krb5_error_code KRB5_CALLCONV krb5_mcc_initialize (krb5_context, krb5_ccache id , krb5_principal princ ); static krb5_error_code KRB5_CALLCONV krb5_mcc_next_cred (krb5_context, krb5_ccache id , krb5_cc_cursor *cursor , krb5_creds *creds ); static krb5_error_code KRB5_CALLCONV krb5_mcc_resolve (krb5_context, krb5_ccache *id , const char *residual ); static krb5_error_code KRB5_CALLCONV krb5_mcc_retrieve (krb5_context, krb5_ccache id , krb5_flags whichfields , krb5_creds *mcreds , krb5_creds *creds ); static krb5_error_code KRB5_CALLCONV krb5_mcc_start_seq_get (krb5_context, krb5_ccache id , krb5_cc_cursor *cursor ); static krb5_error_code KRB5_CALLCONV krb5_mcc_store (krb5_context, krb5_ccache id , krb5_creds *creds ); static krb5_error_code KRB5_CALLCONV krb5_mcc_set_flags (krb5_context, krb5_ccache id , krb5_flags flags ); static krb5_error_code KRB5_CALLCONV krb5_mcc_ptcursor_new (krb5_context, krb5_cc_ptcursor *); static krb5_error_code KRB5_CALLCONV krb5_mcc_ptcursor_next (krb5_context, krb5_cc_ptcursor, krb5_ccache *); static krb5_error_code KRB5_CALLCONV krb5_mcc_ptcursor_free (krb5_context, krb5_cc_ptcursor *); static krb5_error_code KRB5_CALLCONV krb5_mcc_lock (krb5_context context, krb5_ccache id); static krb5_error_code KRB5_CALLCONV krb5_mcc_unlock (krb5_context context, krb5_ccache id); extern const krb5_cc_ops krb5_mcc_ops; extern krb5_error_code krb5_change_cache (void); #define KRB5_OK 0 /* Individual credentials within a cache, in a linked list. */ typedef struct _krb5_mcc_link { struct _krb5_mcc_link *next; krb5_creds *creds; } krb5_mcc_link; /* Per-cache data header. */ typedef struct _krb5_mcc_data { char *name; k5_cc_mutex lock; krb5_principal prin; krb5_mcc_link *link; krb5_mcc_link **tail; /* Where to store next added cred */ /* Time offsets for clock-skewed clients. */ krb5_int32 time_offset; krb5_int32 usec_offset; int refcount; /* One for the table slot, one per handle */ int generation; /* Incremented at each initialize */ } krb5_mcc_data; /* Iterator over credentials in a memory cache. */ struct mcc_cursor { int generation; krb5_mcc_link *next_link; }; /* Iterator over memory caches. */ struct krb5_mcc_ptcursor_data { krb5_boolean first; }; k5_cc_mutex krb5int_mcc_mutex = K5_CC_MUTEX_PARTIAL_INITIALIZER; static struct k5_hashtab *mcc_hashtab = NULL; /* Ensure that mcc_hashtab is initialized. Call with krb5int_mcc_mutex * locked. */ static krb5_error_code init_table(krb5_context context) { krb5_error_code ret; uint8_t seed[K5_HASH_SEED_LEN]; krb5_data d = make_data(seed, sizeof(seed)); if (mcc_hashtab != NULL) return 0; ret = krb5_c_random_make_octets(context, &d); if (ret) return ret; return k5_hashtab_create(seed, 64, &mcc_hashtab); } /* Remove creds from d, invalidate any existing cursors, and unset the client * principal. The caller is responsible for locking. */ static void empty_mcc_cache(krb5_context context, krb5_mcc_data *d) { krb5_mcc_link *curr, *next; for (curr = d->link; curr != NULL; curr = next) { next = curr->next; krb5_free_creds(context, curr->creds); free(curr); } d->link = NULL; d->tail = &d->link; d->generation++; krb5_free_principal(context, d->prin); d->prin = NULL; } /* Remove all creds from d and initialize it with princ as the default client * principal. The caller is responsible for locking. */ static krb5_error_code init_mcc_cache(krb5_context context, krb5_mcc_data *d, krb5_principal princ) { krb5_os_context os_ctx = &context->os_context; empty_mcc_cache(context, d); if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) { /* Store client time offsets in the cache. */ d->time_offset = os_ctx->time_offset; d->usec_offset = os_ctx->usec_offset; } return krb5_copy_principal(context, princ, &d->prin); } /* Add cred to d. The caller is responsible for locking. */ static krb5_error_code store_cred(krb5_context context, krb5_mcc_data *d, krb5_creds *cred) { krb5_error_code ret; krb5_mcc_link *new_node; new_node = malloc(sizeof(*new_node)); if (new_node == NULL) return ENOMEM; new_node->next = NULL; ret = krb5_copy_creds(context, cred, &new_node->creds); if (ret) { free(new_node); return ret; } /* Place the new node at the tail of the list. */ *d->tail = new_node; d->tail = &new_node->next; return 0; } /* * Modifies: * id * * Effects: * Creates/refreshes the memory cred cache id. If the cache exists, its * contents are destroyed. * * Errors: * system errors */ krb5_error_code KRB5_CALLCONV krb5_mcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ) { krb5_error_code ret; krb5_mcc_data *d = id->data; k5_cc_mutex_lock(context, &d->lock); ret = init_mcc_cache(context, d, princ); k5_cc_mutex_unlock(context, &d->lock); if (ret == KRB5_OK) krb5_change_cache(); return ret; } /* * Modifies: * id * * Effects: * Invalidates the id, and frees any resources associated with accessing * the cache. */ krb5_error_code KRB5_CALLCONV krb5_mcc_close(krb5_context context, krb5_ccache id) { krb5_mcc_data *d = id->data; int count; free(id); k5_cc_mutex_lock(context, &d->lock); count = --d->refcount; k5_cc_mutex_unlock(context, &d->lock); if (count == 0) { /* This is the last active handle referencing d and d has been removed * from the table, so we can release it. */ empty_mcc_cache(context, d); free(d->name); k5_cc_mutex_destroy(&d->lock); free(d); } return KRB5_OK; } /* * Effects: * Destroys the contents of id. id is invalid after call. */ krb5_error_code KRB5_CALLCONV krb5_mcc_destroy(krb5_context context, krb5_ccache id) { krb5_mcc_data *d = id->data; krb5_boolean removed_from_table = FALSE; /* Remove this node from the table if it is still present. */ k5_cc_mutex_lock(context, &krb5int_mcc_mutex); if (k5_hashtab_remove(mcc_hashtab, d->name, strlen(d->name))) removed_from_table = TRUE; k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); /* Empty the cache and remove the reference for the table slot. There will * always be at least one reference left for the handle being destroyed. */ k5_cc_mutex_lock(context, &d->lock); empty_mcc_cache(context, d); if (removed_from_table) d->refcount--; k5_cc_mutex_unlock(context, &d->lock); /* Invalidate the handle, possibly removing the last reference to d and * freeing it. */ krb5_mcc_close(context, id); krb5_change_cache (); return KRB5_OK; } /* * Requires: * residual is a legal path name, and a null-terminated string * * Modifies: * id * * Effects: * creates or accesses a memory-based cred cache that is referenced by * residual. * * Returns: * A filled in krb5_ccache structure "id". * * Errors: * KRB5_CC_NOMEM - there was insufficient memory to allocate the * krb5_ccache. id is undefined. * system errors (mutex locks related) */ static krb5_error_code new_mcc_data (const char *, krb5_mcc_data **); krb5_error_code KRB5_CALLCONV krb5_mcc_resolve (krb5_context context, krb5_ccache *id, const char *residual) { krb5_os_context os_ctx = &context->os_context; krb5_ccache lid; krb5_error_code err; krb5_mcc_data *d; k5_cc_mutex_lock(context, &krb5int_mcc_mutex); init_table(context); d = k5_hashtab_get(mcc_hashtab, residual, strlen(residual)); if (d != NULL) { k5_cc_mutex_lock(context, &d->lock); d->refcount++; k5_cc_mutex_unlock(context, &d->lock); } else { err = new_mcc_data(residual, &d); if (err) { k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); return err; } } k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)); if (lid == NULL) return KRB5_CC_NOMEM; if ((context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) && !(os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)) { /* Use the time offset from the cache entry */ os_ctx->time_offset = d->time_offset; os_ctx->usec_offset = d->usec_offset; os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) | KRB5_OS_TOFFSET_VALID); } lid->ops = &krb5_mcc_ops; lid->data = d; *id = lid; return KRB5_OK; } /* * Effects: * Prepares for a sequential search of the credentials cache. * Returns a krb5_cc_cursor to be used with krb5_mcc_next_cred and * krb5_mcc_end_seq_get. * * If the cache is modified between the time of this call and the time * of the final krb5_mcc_end_seq_get, the results are undefined. * * Errors: * KRB5_CC_NOMEM * system errors */ krb5_error_code KRB5_CALLCONV krb5_mcc_start_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { struct mcc_cursor *mcursor; krb5_mcc_data *d; mcursor = malloc(sizeof(*mcursor)); if (mcursor == NULL) return KRB5_CC_NOMEM; d = id->data; k5_cc_mutex_lock(context, &d->lock); mcursor->generation = d->generation; mcursor->next_link = d->link; k5_cc_mutex_unlock(context, &d->lock); *cursor = mcursor; return KRB5_OK; } /* * Requires: * cursor is a krb5_cc_cursor originally obtained from * krb5_mcc_start_seq_get. * * Modifies: * cursor, creds * * Effects: * Fills in creds with the "next" credentals structure from the cache * id. The actual order the creds are returned in is arbitrary. * Space is allocated for the variable length fields in the * credentials structure, so the object returned must be passed to * krb5_destroy_credential. * * The cursor is updated for the next call to krb5_mcc_next_cred. * * Errors: * system errors */ krb5_error_code KRB5_CALLCONV krb5_mcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { struct mcc_cursor *mcursor; krb5_error_code retval; krb5_mcc_data *d = id->data; memset(creds, 0, sizeof(krb5_creds)); mcursor = *cursor; if (mcursor->next_link == NULL) return KRB5_CC_END; /* * Check the cursor generation against the cache generation in case the * cache has been reinitialized or destroyed, freeing the pointer in the * cursor. Keep the cache locked while we copy the creds and advance the * pointer, in case another thread reinitializes the cache after we check * the generation. */ k5_cc_mutex_lock(context, &d->lock); if (mcursor->generation != d->generation) { retval = KRB5_CC_END; goto done; } /* Skip over removed creds. */ while (mcursor->next_link != NULL && mcursor->next_link->creds == NULL) mcursor->next_link = mcursor->next_link->next; if (mcursor->next_link == NULL) { retval = KRB5_CC_END; goto done; } retval = k5_copy_creds_contents(context, mcursor->next_link->creds, creds); if (retval == 0) mcursor->next_link = mcursor->next_link->next; done: k5_cc_mutex_unlock(context, &d->lock); return retval; } /* * Requires: * cursor is a krb5_cc_cursor originally obtained from * krb5_mcc_start_seq_get. * * Modifies: * id, cursor * * Effects: * Finishes sequential processing of the memory credentials ccache id, * and invalidates the cursor (it must never be used after this call). */ /* ARGSUSED */ krb5_error_code KRB5_CALLCONV krb5_mcc_end_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { free(*cursor); *cursor = NULL; return KRB5_OK; } /* * Utility routine: Creates the back-end data for a memory cache, and adds it * to the global table. Give the new object two references, one for the table * slot and one for the caller's handle. * * Call with the global table lock held. */ static krb5_error_code new_mcc_data (const char *name, krb5_mcc_data **dataptr) { krb5_error_code err; krb5_mcc_data *d; d = malloc(sizeof(krb5_mcc_data)); if (d == NULL) return KRB5_CC_NOMEM; err = k5_cc_mutex_init(&d->lock); if (err) { free(d); return err; } d->name = strdup(name); if (d->name == NULL) { k5_cc_mutex_destroy(&d->lock); free(d); return KRB5_CC_NOMEM; } d->link = NULL; d->tail = &d->link; d->prin = NULL; d->time_offset = 0; d->usec_offset = 0; d->refcount = 2; d->generation = 0; if (k5_hashtab_add(mcc_hashtab, d->name, strlen(d->name), d) != 0) { free(d->name); k5_cc_mutex_destroy(&d->lock); free(d); return KRB5_CC_NOMEM; } *dataptr = d; return 0; } /* * Effects: * Creates a new memory cred cache whose name is guaranteed to be * unique. The name begins with the string TKT_ROOT (from mcc.h). * * Returns: * The filled in krb5_ccache id. * * Errors: * KRB5_CC_NOMEM - there was insufficient memory to allocate the * krb5_ccache. id is undefined. * system errors (from open, mutex locking) */ krb5_error_code KRB5_CALLCONV krb5_mcc_generate_new (krb5_context context, krb5_ccache *id) { krb5_ccache lid; char uniquename[8]; krb5_error_code err; krb5_mcc_data *d; /* Allocate memory */ lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)); if (lid == NULL) return KRB5_CC_NOMEM; lid->ops = &krb5_mcc_ops; k5_cc_mutex_lock(context, &krb5int_mcc_mutex); init_table(context); /* Check for uniqueness with mutex locked to avoid race conditions */ while (1) { err = krb5int_random_string (context, uniquename, sizeof (uniquename)); if (err) { k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); free(lid); return err; } if (k5_hashtab_get(mcc_hashtab, uniquename, strlen(uniquename)) == NULL) break; } err = new_mcc_data(uniquename, &d); k5_cc_mutex_unlock(context, &krb5int_mcc_mutex); if (err) { free(lid); return err; } lid->data = d; *id = lid; krb5_change_cache (); return KRB5_OK; } /* * Requires: * id is a file credential cache * * Returns: * A pointer to the name of the file cred cache id. */ const char * KRB5_CALLCONV krb5_mcc_get_name (krb5_context context, krb5_ccache id) { return (char *) ((krb5_mcc_data *) id->data)->name; } /* * Modifies: * id, princ * * Effects: * Retrieves the primary principal from id, as set with * krb5_mcc_initialize. The principal is returned is allocated * storage that must be freed by the caller via krb5_free_principal. * * Errors: * system errors * ENOMEM */ krb5_error_code KRB5_CALLCONV krb5_mcc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *princ) { krb5_error_code ret; krb5_mcc_data *d = id->data; *princ = NULL; k5_cc_mutex_lock(context, &d->lock); if (d->prin == NULL) ret = KRB5_FCC_NOFILE; else ret = krb5_copy_principal(context, d->prin, princ); k5_cc_mutex_unlock(context, &d->lock); return ret; } krb5_error_code KRB5_CALLCONV krb5_mcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds) { return k5_cc_retrieve_cred_default(context, id, whichfields, mcreds, creds); } /* * Modifies: * the memory cache * * Effects: * Remove the given creds from the ccache. */ static krb5_error_code KRB5_CALLCONV krb5_mcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *creds) { krb5_mcc_data *data = (krb5_mcc_data *)cache->data; krb5_mcc_link *l; k5_cc_mutex_lock(context, &data->lock); for (l = data->link; l != NULL; l = l->next) { if (l->creds != NULL && krb5int_cc_creds_match_request(context, flags, creds, l->creds)) { krb5_free_creds(context, l->creds); l->creds = NULL; } } k5_cc_mutex_unlock(context, &data->lock); return 0; } /* * Requires: * id is a cred cache returned by krb5_mcc_resolve or * krb5_mcc_generate_new. * * Modifies: * id * * Effects: * Sets the operational flags of id to flags. */ krb5_error_code KRB5_CALLCONV krb5_mcc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags) { return KRB5_OK; } static krb5_error_code KRB5_CALLCONV krb5_mcc_get_flags(krb5_context context, krb5_ccache id, krb5_flags *flags) { *flags = 0; return KRB5_OK; } /* * Modifies: * the memory cache * * Effects: * Save away creds in the ccache. * * Errors: * ENOMEM */ krb5_error_code KRB5_CALLCONV krb5_mcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) { krb5_error_code ret; krb5_mcc_data *d = id->data; /* Place the new node at the tail of the list. */ k5_cc_mutex_lock(context, &d->lock); ret = store_cred(context, d, creds); k5_cc_mutex_unlock(context, &d->lock); return ret; } static krb5_error_code KRB5_CALLCONV krb5_mcc_ptcursor_new( krb5_context context, krb5_cc_ptcursor *cursor) { krb5_cc_ptcursor n = NULL; struct krb5_mcc_ptcursor_data *cdata = NULL; *cursor = NULL; n = malloc(sizeof(*n)); if (n == NULL) return ENOMEM; n->ops = &krb5_mcc_ops; cdata = malloc(sizeof(struct krb5_mcc_ptcursor_data)); if (cdata == NULL) { free(n); return ENOMEM; } n->data = cdata; cdata->first = TRUE; *cursor = n; return 0; } static krb5_error_code KRB5_CALLCONV krb5_mcc_ptcursor_next( krb5_context context, krb5_cc_ptcursor cursor, krb5_ccache *ccache) { struct krb5_mcc_ptcursor_data *cdata = NULL; const char *defname; *ccache = NULL; cdata = cursor->data; if (!cdata->first) return 0; cdata->first = FALSE; defname = krb5_cc_default_name(context); if (defname == NULL || strncmp(defname, "MEMORY:", 7) != 0) return 0; return krb5_cc_resolve(context, defname, ccache); } static krb5_error_code KRB5_CALLCONV krb5_mcc_ptcursor_free( krb5_context context, krb5_cc_ptcursor *cursor) { if (*cursor == NULL) return 0; if ((*cursor)->data != NULL) free((*cursor)->data); free(*cursor); *cursor = NULL; return 0; } static krb5_error_code KRB5_CALLCONV krb5_mcc_replace(krb5_context context, krb5_ccache id, krb5_principal princ, krb5_creds **creds) { krb5_error_code ret; krb5_mcc_data *d = id->data; int i; k5_cc_mutex_lock(context, &d->lock); ret = init_mcc_cache(context, d, princ); for (i = 0; !ret && creds[i] != NULL; i++) ret = store_cred(context, d, creds[i]); k5_cc_mutex_unlock(context, &d->lock); if (!ret) krb5_change_cache(); return ret; } static krb5_error_code KRB5_CALLCONV krb5_mcc_lock(krb5_context context, krb5_ccache id) { krb5_mcc_data *data = (krb5_mcc_data *) id->data; k5_cc_mutex_lock(context, &data->lock); return 0; } static krb5_error_code KRB5_CALLCONV krb5_mcc_unlock(krb5_context context, krb5_ccache id) { krb5_mcc_data *data = (krb5_mcc_data *) id->data; k5_cc_mutex_unlock(context, &data->lock); return 0; } const krb5_cc_ops krb5_mcc_ops = { 0, "MEMORY", krb5_mcc_get_name, krb5_mcc_resolve, krb5_mcc_generate_new, krb5_mcc_initialize, krb5_mcc_destroy, krb5_mcc_close, krb5_mcc_store, krb5_mcc_retrieve, krb5_mcc_get_principal, krb5_mcc_start_seq_get, krb5_mcc_next_cred, krb5_mcc_end_seq_get, krb5_mcc_remove_cred, krb5_mcc_set_flags, krb5_mcc_get_flags, krb5_mcc_ptcursor_new, krb5_mcc_ptcursor_next, krb5_mcc_ptcursor_free, krb5_mcc_replace, NULL, /* wasdefault */ krb5_mcc_lock, krb5_mcc_unlock, NULL, /* switch_to */ }; krb5-1.22.1/src/lib/krb5/ccache/ccfns.c0000664000175000017500000002263215051422640017214 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccfns.c - Dispatch methods for credentials cache code.*/ /* * Copyright 2000, 2007, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "cc-int.h" #include "../krb/int-proto.h" const char * KRB5_CALLCONV krb5_cc_get_name(krb5_context context, krb5_ccache cache) { return cache->ops->get_name(context, cache); } krb5_error_code KRB5_CALLCONV krb5_cc_get_full_name(krb5_context context, krb5_ccache cache, char **fullname_out) { char *name; *fullname_out = NULL; if (asprintf(&name, "%s:%s", cache->ops->prefix, cache->ops->get_name(context, cache)) < 0) return ENOMEM; *fullname_out = name; return 0; } krb5_error_code KRB5_CALLCONV krb5_cc_gen_new(krb5_context context, krb5_ccache *cache) { TRACE_CC_GEN_NEW(context, cache); return (*cache)->ops->gen_new(context, cache); } krb5_error_code KRB5_CALLCONV krb5_cc_initialize(krb5_context context, krb5_ccache cache, krb5_principal principal) { TRACE_CC_INIT(context, cache, principal); return cache->ops->init(context, cache, principal); } krb5_error_code KRB5_CALLCONV krb5_cc_destroy(krb5_context context, krb5_ccache cache) { TRACE_CC_DESTROY(context, cache); return cache->ops->destroy(context, cache); } krb5_error_code KRB5_CALLCONV krb5_cc_close(krb5_context context, krb5_ccache cache) { return cache->ops->close(context, cache); } krb5_error_code KRB5_CALLCONV krb5_cc_store_cred(krb5_context context, krb5_ccache cache, krb5_creds *creds) { TRACE_CC_STORE(context, cache, creds); return cache->ops->store(context, cache, creds); } krb5_error_code KRB5_CALLCONV krb5_cc_retrieve_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *mcreds, krb5_creds *creds) { krb5_error_code ret; krb5_data tmprealm; ret = cache->ops->retrieve(context, cache, flags, mcreds, creds); TRACE_CC_RETRIEVE(context, cache, mcreds, ret); if (ret != KRB5_CC_NOTFOUND) return ret; if (mcreds->client == NULL || mcreds->server == NULL || !krb5_is_referral_realm(&mcreds->server->realm)) return ret; /* * Retry using client's realm if service has referral realm. */ tmprealm = mcreds->server->realm; mcreds->server->realm = mcreds->client->realm; ret = cache->ops->retrieve(context, cache, flags, mcreds, creds); TRACE_CC_RETRIEVE_REF(context, cache, mcreds, ret); mcreds->server->realm = tmprealm; return ret; } krb5_error_code KRB5_CALLCONV krb5_cc_get_principal(krb5_context context, krb5_ccache cache, krb5_principal *principal) { return cache->ops->get_princ(context, cache, principal); } krb5_error_code KRB5_CALLCONV krb5_cc_start_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor) { return cache->ops->get_first(context, cache, cursor); } krb5_error_code KRB5_CALLCONV krb5_cc_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, krb5_creds *creds) { return cache->ops->get_next(context, cache, cursor, creds); } krb5_error_code KRB5_CALLCONV krb5_cc_end_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor) { return cache->ops->end_get(context, cache, cursor); } krb5_error_code KRB5_CALLCONV krb5_cc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *creds) { TRACE_CC_REMOVE(context, cache, creds); return cache->ops->remove_cred(context, cache, flags, creds); } krb5_error_code KRB5_CALLCONV krb5_cc_set_flags(krb5_context context, krb5_ccache cache, krb5_flags flags) { return cache->ops->set_flags(context, cache, flags); } krb5_error_code KRB5_CALLCONV krb5_cc_get_flags(krb5_context context, krb5_ccache cache, krb5_flags *flags) { return cache->ops->get_flags(context, cache, flags); } const char * KRB5_CALLCONV krb5_cc_get_type(krb5_context context, krb5_ccache cache) { return cache->ops->prefix; } krb5_error_code k5_cc_lock(krb5_context context, krb5_ccache ccache) { return ccache->ops->lock(context, ccache); } krb5_error_code k5_cc_unlock(krb5_context context, krb5_ccache ccache) { return ccache->ops->unlock(context, ccache); } static const char conf_realm[] = "X-CACHECONF:"; static const char conf_name[] = "krb5_ccache_conf_data"; krb5_error_code k5_build_conf_principals(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *name, krb5_creds *cred) { krb5_principal client; krb5_error_code ret; char *pname = NULL; memset(cred, 0, sizeof(*cred)); ret = krb5_cc_get_principal(context, id, &client); if (ret) return ret; if (principal) { ret = krb5_unparse_name(context, principal, &pname); if (ret) goto cleanup; } ret = krb5_build_principal(context, &cred->server, sizeof(conf_realm) - 1, conf_realm, conf_name, name, pname, (char *)NULL); if (ret) goto cleanup; ret = krb5_copy_principal(context, client, &cred->client); cleanup: krb5_free_unparsed_name(context, pname); krb5_free_principal(context, client); return ret; } krb5_boolean KRB5_CALLCONV krb5_is_config_principal(krb5_context context, krb5_const_principal principal) { const krb5_data *realm = &principal->realm; if (realm->length != sizeof(conf_realm) - 1 || memcmp(realm->data, conf_realm, sizeof(conf_realm) - 1) != 0) return FALSE; if (principal->length == 0 || principal->data[0].length != (sizeof(conf_name) - 1) || memcmp(principal->data[0].data, conf_name, sizeof(conf_name) - 1) != 0) return FALSE; return TRUE; } krb5_error_code KRB5_CALLCONV krb5_cc_set_config(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *key, krb5_data *data) { krb5_error_code ret; krb5_creds cred; memset(&cred, 0, sizeof(cred)); TRACE_CC_SET_CONFIG(context, id, principal, key, data); ret = k5_build_conf_principals(context, id, principal, key, &cred); if (ret) goto out; if (data == NULL) { ret = krb5_cc_remove_cred(context, id, 0, &cred); } else { ret = krb5int_copy_data_contents(context, data, &cred.ticket); if (ret) goto out; ret = krb5_cc_store_cred(context, id, &cred); } out: krb5_free_cred_contents(context, &cred); return ret; } krb5_error_code KRB5_CALLCONV krb5_cc_get_config(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *key, krb5_data *data) { krb5_creds mcred, cred; krb5_error_code ret; memset(&cred, 0, sizeof(cred)); memset(data, 0, sizeof(*data)); ret = k5_build_conf_principals(context, id, principal, key, &mcred); if (ret) goto out; ret = krb5_cc_retrieve_cred(context, id, 0, &mcred, &cred); if (ret) goto out; ret = krb5int_copy_data_contents(context, &cred.ticket, data); if (ret) goto out; TRACE_CC_GET_CONFIG(context, id, principal, key, data); out: krb5_free_cred_contents(context, &cred); krb5_free_cred_contents(context, &mcred); return ret; } krb5_error_code KRB5_CALLCONV krb5_cc_switch(krb5_context context, krb5_ccache cache) { if (cache->ops->switch_to == NULL) return 0; return cache->ops->switch_to(context, cache); } krb5_error_code k5_cc_store_primary_cred(krb5_context context, krb5_ccache cache, krb5_creds *creds) { krb5_error_code ret; /* Write a start realm if we're writing a TGT and the client realm isn't * the same as the TGS realm. */ if (IS_TGS_PRINC(creds->server) && !data_eq(creds->client->realm, creds->server->data[1])) { ret = krb5_cc_set_config(context, cache, NULL, KRB5_CC_CONF_START_REALM, &creds->server->data[1]); if (ret) return ret; } return krb5_cc_store_cred(context, cache, creds); } krb5-1.22.1/src/lib/krb5/ccache/cccursor.c0000664000175000017500000001770715051422640017752 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cccursor.c */ /* * Copyright 2006, 2007 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * cursor for sequential traversal of ccaches */ #include "cc-int.h" #include "../krb/int-proto.h" #include "../os/os-proto.h" #include struct _krb5_cccol_cursor { krb5_cc_typecursor typecursor; const krb5_cc_ops *ops; krb5_cc_ptcursor ptcursor; }; /* typedef of krb5_cccol_cursor is in krb5.h */ krb5_error_code KRB5_CALLCONV krb5_cccol_cursor_new(krb5_context context, krb5_cccol_cursor *cursor) { krb5_error_code ret = 0; krb5_cccol_cursor n = NULL; *cursor = NULL; n = malloc(sizeof(*n)); if (n == NULL) return ENOMEM; n->typecursor = NULL; n->ptcursor = NULL; n->ops = NULL; ret = krb5int_cc_typecursor_new(context, &n->typecursor); if (ret) goto errout; do { /* Find first backend with ptcursor functionality. */ ret = krb5int_cc_typecursor_next(context, n->typecursor, &n->ops); if (ret || n->ops == NULL) goto errout; } while (n->ops->ptcursor_new == NULL); ret = n->ops->ptcursor_new(context, &n->ptcursor); if (ret) goto errout; errout: if (ret) { krb5_cccol_cursor_free(context, &n); } *cursor = n; return ret; } krb5_error_code KRB5_CALLCONV krb5_cccol_cursor_next(krb5_context context, krb5_cccol_cursor cursor, krb5_ccache *ccache_out) { krb5_error_code ret = 0; krb5_ccache ccache; *ccache_out = NULL; /* Are we out of backends? */ if (cursor->ops == NULL) return 0; while (1) { ret = cursor->ops->ptcursor_next(context, cursor->ptcursor, &ccache); if (ret) return ret; if (ccache != NULL) { *ccache_out = ccache; return 0; } ret = cursor->ops->ptcursor_free(context, &cursor->ptcursor); if (ret) return ret; do { /* Find next type with ptcursor functionality. */ ret = krb5int_cc_typecursor_next(context, cursor->typecursor, &cursor->ops); if (ret) return ret; if (cursor->ops == NULL) return 0; } while (cursor->ops->ptcursor_new == NULL); ret = cursor->ops->ptcursor_new(context, &cursor->ptcursor); if (ret) return ret; } } krb5_error_code KRB5_CALLCONV krb5_cccol_cursor_free(krb5_context context, krb5_cccol_cursor *cursor) { krb5_cccol_cursor c = *cursor; if (c == NULL) return 0; if (c->ptcursor != NULL) c->ops->ptcursor_free(context, &c->ptcursor); if (c->typecursor != NULL) krb5int_cc_typecursor_free(context, &c->typecursor); free(c); *cursor = NULL; return 0; } static krb5_error_code match_caches(krb5_context context, krb5_const_principal client, krb5_ccache *cache_out) { krb5_error_code ret; krb5_cccol_cursor cursor; krb5_ccache cache = NULL; krb5_principal princ; krb5_boolean eq; *cache_out = NULL; ret = krb5_cccol_cursor_new(context, &cursor); if (ret) return ret; while ((ret = krb5_cccol_cursor_next(context, cursor, &cache)) == 0 && cache != NULL) { ret = krb5_cc_get_principal(context, cache, &princ); if (ret == 0) { eq = krb5_principal_compare(context, princ, client); krb5_free_principal(context, princ); if (eq) break; } krb5_cc_close(context, cache); } krb5_cccol_cursor_free(context, &cursor); if (ret) return ret; if (cache == NULL) return KRB5_CC_NOTFOUND; *cache_out = cache; return 0; } krb5_error_code KRB5_CALLCONV krb5_cc_cache_match(krb5_context context, krb5_principal client, krb5_ccache *cache_out) { krb5_error_code ret; struct canonprinc iter = { client, .subst_defrealm = TRUE }; krb5_const_principal canonprinc = NULL; krb5_ccache cache = NULL; char *name; *cache_out = NULL; while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 && canonprinc != NULL) { ret = match_caches(context, canonprinc, &cache); if (ret != KRB5_CC_NOTFOUND) break; } free_canonprinc(&iter); if (ret == 0 && canonprinc == NULL) { ret = KRB5_CC_NOTFOUND; if (krb5_unparse_name(context, client, &name) == 0) { k5_setmsg(context, ret, _("Can't find client principal %s in cache collection"), name); krb5_free_unparsed_name(context, name); } } TRACE_CC_CACHE_MATCH(context, client, ret); if (ret) return ret; *cache_out = cache; return 0; } /* Store the error state for code from context into errsave, but only if code * indicates an error and errsave is empty. */ static void save_first_error(krb5_context context, krb5_error_code code, struct errinfo *errsave) { if (code && code != KRB5_FCC_NOFILE && !errsave->code) k5_save_ctx_error(context, code, errsave); } krb5_error_code KRB5_CALLCONV krb5_cccol_have_content(krb5_context context) { krb5_error_code ret; krb5_cccol_cursor col_cursor; krb5_ccache cache; krb5_principal princ; krb5_boolean found = FALSE; struct errinfo errsave = EMPTY_ERRINFO; const char *defname; ret = krb5_cccol_cursor_new(context, &col_cursor); save_first_error(context, ret, &errsave); if (ret) goto no_entries; while (!found) { ret = krb5_cccol_cursor_next(context, col_cursor, &cache); save_first_error(context, ret, &errsave); if (ret || cache == NULL) break; princ = NULL; ret = krb5_cc_get_principal(context, cache, &princ); save_first_error(context, ret, &errsave); if (!ret) found = TRUE; krb5_free_principal(context, princ); krb5_cc_close(context, cache); } krb5_cccol_cursor_free(context, &col_cursor); if (found) { k5_clear_error(&errsave); return 0; } no_entries: if (errsave.code) { /* Report the first error we encountered. */ ret = k5_restore_ctx_error(context, &errsave); k5_wrapmsg(context, ret, KRB5_CC_NOTFOUND, _("No Kerberos credentials available")); } else { /* Report the default cache name. */ defname = krb5_cc_default_name(context); if (defname != NULL) { k5_setmsg(context, KRB5_CC_NOTFOUND, _("No Kerberos credentials available " "(default cache: %s)"), defname); } } return KRB5_CC_NOTFOUND; } krb5-1.22.1/src/lib/krb5/ccache/cc_file.c0000664000175000017500000011660515051422640017510 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cc_file.c - File-based credential cache */ /* * Copyright 1990,1991,1992,1993,1994,2000,2004,2007 Massachusetts Institute of Technology. * All Rights Reserved. * * Original stdio support copyright 1995 by Cygnus Support. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * A psuedo-BNF grammar for the FILE credential cache format is: * * file ::= * version (2 bytes; 05 01 for version 1 through 05 04 for version 4) * header [not present before version 4] * principal * credential1 * credential2 * ... * * header ::= * headerlen (16 bits) * header1tag (16 bits) * header1len (16 bits) * header1val (header1len bytes) * * See ccmarshal.c for the principal and credential formats. Although versions * 1 and 2 of the FILE format use native byte order for integer representations * within principals and credentials, the integer fields in the grammar above * are always in big-endian byte order. * * Only one header tag is currently defined. The tag value is 1 * (FCC_TAG_DELTATIME), and its contents are two 32-bit integers giving the * seconds and microseconds of the time offset of the KDC relative to the * client. * * Each of the file ccache functions opens and closes the file whenever it * needs to access it. * * This module depends on UNIX-like file descriptors, and UNIX-like behavior * from the functions: open, close, read, write, lseek. */ #include "k5-int.h" #include "cc-int.h" #include #include #if HAVE_UNISTD_H #include #endif #ifndef O_CLOEXEC #define O_CLOEXEC 0 #endif extern const krb5_cc_ops krb5_cc_file_ops; krb5_error_code krb5_change_cache(void); static krb5_error_code interpret_errno(krb5_context, int); /* The cache format version is a positive integer, represented in the cache * file as a two-byte big endian number with 0x0500 added to it. */ #define FVNO_BASE 0x0500 #define FCC_TAG_DELTATIME 1 #ifndef TKT_ROOT #ifdef MSDOS_FILESYSTEM #define TKT_ROOT "\\tkt" #else #define TKT_ROOT "/tmp/tkt" #endif #endif typedef struct fcc_data_st { k5_cc_mutex lock; char *filename; } fcc_data; /* Iterator over file caches. */ struct krb5_fcc_ptcursor_data { krb5_boolean first; }; /* Iterator over a cache. */ typedef struct _krb5_fcc_cursor { FILE *fp; int version; } krb5_fcc_cursor; k5_cc_mutex krb5int_cc_file_mutex = K5_CC_MUTEX_PARTIAL_INITIALIZER; /* Add fname to the standard error message for ret. */ static krb5_error_code set_errmsg_filename(krb5_context context, krb5_error_code ret, const char *fname) { if (!ret) return 0; k5_setmsg(context, ret, "%s (filename: %s)", error_message(ret), fname); return ret; } /* Get the size of the cache file as a size_t, or SIZE_MAX if it is too * large to be represented as a size_t. */ static krb5_error_code get_size(krb5_context context, FILE *fp, size_t *size_out) { struct stat sb; *size_out = 0; if (fstat(fileno(fp), &sb) == -1) return interpret_errno(context, errno); if (sizeof(off_t) > sizeof(size_t) && sb.st_size > (off_t)SIZE_MAX) *size_out = SIZE_MAX; else *size_out = sb.st_size; return 0; } /* Read len bytes from fp, storing them in buf. Return KRB5_CC_END * if not enough bytes are present. */ static krb5_error_code read_bytes(krb5_context context, FILE *fp, void *buf, size_t len) { size_t nread; nread = fread(buf, 1, len, fp); if (nread < len) return ferror(fp) ? errno : KRB5_CC_END; return 0; } /* Load four bytes from the cache file. Add them to buf (if set) and return * their value as a 32-bit unsigned integer according to the file format. */ static krb5_error_code read32(krb5_context context, FILE *fp, int version, struct k5buf *buf, uint32_t *out) { krb5_error_code ret; char bytes[4]; ret = read_bytes(context, fp, bytes, 4); if (ret) return ret; if (buf != NULL) k5_buf_add_len(buf, bytes, 4); *out = (version < 3) ? load_32_n(bytes) : load_32_be(bytes); return 0; } /* Load two bytes from the cache file and return their value as a 16-bit * unsigned integer according to the file format. */ static krb5_error_code read16(krb5_context context, FILE *fp, int version, uint16_t *out) { krb5_error_code ret; char bytes[2]; ret = read_bytes(context, fp, bytes, 2); if (ret) return ret; *out = (version < 3) ? load_16_n(bytes) : load_16_be(bytes); return 0; } /* Read len bytes from the cache file and add them to buf. */ static krb5_error_code load_bytes(krb5_context context, FILE *fp, size_t len, struct k5buf *buf) { void *ptr; ptr = k5_buf_get_space(buf, len); return (ptr == NULL) ? KRB5_CC_NOMEM : read_bytes(context, fp, ptr, len); } /* Load a 32-bit length and data from the cache file into buf, but not more * than maxsize bytes. */ static krb5_error_code load_data(krb5_context context, FILE *fp, int version, size_t maxsize, struct k5buf *buf) { krb5_error_code ret; uint32_t count; ret = read32(context, fp, version, buf, &count); if (ret) return ret; if (count > maxsize) return KRB5_CC_FORMAT; return load_bytes(context, fp, count, buf); } /* Load a marshalled principal from the cache file into buf, without * unmarshalling it. */ static krb5_error_code load_principal(krb5_context context, FILE *fp, int version, size_t maxsize, struct k5buf *buf) { krb5_error_code ret; uint32_t count; if (version > 1) { ret = load_bytes(context, fp, 4, buf); if (ret) return ret; } ret = read32(context, fp, version, buf, &count); if (ret) return ret; /* Add one for the realm (except in version 1 which already counts it). */ if (version != 1) count++; while (count-- > 0) { ret = load_data(context, fp, version, maxsize, buf); if (ret) return ret; } return 0; } /* Load a marshalled credential from the cache file into buf, without * unmarshalling it. */ static krb5_error_code load_cred(krb5_context context, FILE *fp, int version, size_t maxsize, struct k5buf *buf) { krb5_error_code ret; uint32_t count, i; /* client and server */ ret = load_principal(context, fp, version, maxsize, buf); if (ret) return ret; ret = load_principal(context, fp, version, maxsize, buf); if (ret) return ret; /* keyblock (enctype, enctype again for version 3, length, value) */ ret = load_bytes(context, fp, (version == 3) ? 4 : 2, buf); if (ret) return ret; ret = load_data(context, fp, version, maxsize, buf); if (ret) return ret; /* times (4*4 bytes), is_skey (1 byte), ticket flags (4 bytes) */ ret = load_bytes(context, fp, 4 * 4 + 1 + 4, buf); if (ret) return ret; /* addresses and authdata, both lists of {type, length, data} */ for (i = 0; i < 2; i++) { ret = read32(context, fp, version, buf, &count); if (ret) return ret; while (count-- > 0) { ret = load_bytes(context, fp, 2, buf); if (ret) return ret; ret = load_data(context, fp, version, maxsize, buf); if (ret) return ret; } } /* ticket and second_ticket */ ret = load_data(context, fp, version, maxsize, buf); if (ret) return ret; return load_data(context, fp, version, maxsize, buf); } static krb5_error_code read_principal(krb5_context context, FILE *fp, int version, krb5_principal *princ) { krb5_error_code ret; struct k5buf buf; size_t maxsize; *princ = NULL; k5_buf_init_dynamic(&buf); /* Read the principal representation into memory. */ ret = get_size(context, fp, &maxsize); if (ret) goto cleanup; ret = load_principal(context, fp, version, maxsize, &buf); if (ret) goto cleanup; ret = k5_buf_status(&buf); if (ret) goto cleanup; /* Unmarshal it from buf into princ. */ ret = k5_unmarshal_princ(buf.data, buf.len, version, princ); cleanup: k5_buf_free(&buf); return ret; } /* * Open and lock an existing cache file. If writable is true, open it for * writing (with O_APPEND) and get an exclusive lock; otherwise open it for * reading and get a shared lock. */ static krb5_error_code open_cache_file(krb5_context context, const char *filename, krb5_boolean writable, FILE **fp_out) { krb5_error_code ret; int fd, flags, lockmode; FILE *fp; *fp_out = NULL; flags = writable ? (O_RDWR | O_APPEND) : O_RDONLY; fd = open(filename, flags | O_BINARY | O_CLOEXEC, 0600); if (fd == -1) return interpret_errno(context, errno); set_cloexec_fd(fd); lockmode = writable ? KRB5_LOCKMODE_EXCLUSIVE : KRB5_LOCKMODE_SHARED; ret = krb5_lock_file(context, fd, lockmode); if (ret) { (void)close(fd); return ret; } fp = fdopen(fd, writable ? "r+b" : "rb"); if (fp == NULL) { (void)krb5_unlock_file(context, fd); (void)close(fd); return KRB5_CC_NOMEM; } *fp_out = fp; return 0; } /* Unlock and close the cache file. Do nothing if fp is NULL. */ static krb5_error_code close_cache_file(krb5_context context, FILE *fp) { int st; krb5_error_code ret; if (fp == NULL) return 0; ret = krb5_unlock_file(context, fileno(fp)); st = fclose(fp); if (ret) return ret; return st ? interpret_errno(context, errno) : 0; } /* Read the cache file header. Set time offsets in context from the header if * appropriate. Set *version_out to the cache file format version. */ static krb5_error_code read_header(krb5_context context, FILE *fp, int *version_out) { krb5_error_code ret; krb5_os_context os_ctx = &context->os_context; uint16_t fields_len, tag, flen; uint32_t time_offset, usec_offset; char i16buf[2]; int version; *version_out = 0; /* Get the file format version. */ ret = read_bytes(context, fp, i16buf, 2); if (ret) return KRB5_CC_FORMAT; version = load_16_be(i16buf) - FVNO_BASE; if (version < 1 || version > 4) return KRB5_CCACHE_BADVNO; *version_out = version; /* Tagged header fields begin with version 4. */ if (version < 4) return 0; if (read16(context, fp, version, &fields_len)) return KRB5_CC_FORMAT; while (fields_len) { if (fields_len < 4 || read16(context, fp, version, &tag) || read16(context, fp, version, &flen) || flen > fields_len - 4) return KRB5_CC_FORMAT; switch (tag) { case FCC_TAG_DELTATIME: if (flen != 8 || read32(context, fp, version, NULL, &time_offset) || read32(context, fp, version, NULL, &usec_offset)) return KRB5_CC_FORMAT; if (!(context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) || (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)) break; os_ctx->time_offset = time_offset; os_ctx->usec_offset = usec_offset; os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) | KRB5_OS_TOFFSET_VALID); break; default: if (flen && fseek(fp, flen, SEEK_CUR) != 0) return KRB5_CC_FORMAT; break; } fields_len -= (4 + flen); } return 0; } static void marshal_header(krb5_context context, struct k5buf *buf, krb5_principal princ) { krb5_os_context os_ctx = &context->os_context; int version = context->fcc_default_format - FVNO_BASE; uint16_t fields_len; version = context->fcc_default_format - FVNO_BASE; k5_buf_add_uint16_be(buf, FVNO_BASE + version); if (version >= 4) { /* Add tagged header fields. */ fields_len = 0; if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) fields_len += 12; k5_buf_add_uint16_be(buf, fields_len); if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) { /* Add time offset tag. */ k5_buf_add_uint16_be(buf, FCC_TAG_DELTATIME); k5_buf_add_uint16_be(buf, 8); k5_buf_add_uint32_be(buf, os_ctx->time_offset); k5_buf_add_uint32_be(buf, os_ctx->usec_offset); } } k5_marshal_princ(buf, version, princ); } /* Create or overwrite the cache file with a header and default principal. */ static krb5_error_code KRB5_CALLCONV fcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ) { krb5_error_code ret; fcc_data *data = id->data; ssize_t nwritten; int st, flags, fd = -1; struct k5buf buf = EMPTY_K5BUF; krb5_boolean file_locked = FALSE; k5_cc_mutex_lock(context, &data->lock); unlink(data->filename); flags = O_CREAT | O_EXCL | O_RDWR | O_BINARY | O_CLOEXEC; fd = open(data->filename, flags, 0600); if (fd == -1) { ret = interpret_errno(context, errno); goto cleanup; } set_cloexec_fd(fd); #if defined(HAVE_FCHMOD) || defined(HAVE_CHMOD) #ifdef HAVE_FCHMOD st = fchmod(fd, S_IRUSR | S_IWUSR); #else st = chmod(data->filename, S_IRUSR | S_IWUSR); #endif if (st == -1) { ret = interpret_errno(context, errno); goto cleanup; } #endif ret = krb5_lock_file(context, fd, KRB5_LOCKMODE_EXCLUSIVE); if (ret) goto cleanup; file_locked = TRUE; /* Prepare the header and principal in buf. */ k5_buf_init_dynamic(&buf); marshal_header(context, &buf, princ); ret = k5_buf_status(&buf); if (ret) goto cleanup; /* Write the header and principal. */ nwritten = write(fd, buf.data, buf.len); if (nwritten == -1) ret = interpret_errno(context, errno); if ((size_t)nwritten != buf.len) ret = KRB5_CC_IO; cleanup: k5_buf_free(&buf); if (file_locked) krb5_unlock_file(context, fd); if (fd != -1) close(fd); k5_cc_mutex_unlock(context, &data->lock); krb5_change_cache(); return set_errmsg_filename(context, ret, data->filename); } /* Release an fcc_data object. */ static void free_fccdata(krb5_context context, fcc_data *data) { k5_cc_mutex_assert_unlocked(context, &data->lock); free(data->filename); k5_cc_mutex_destroy(&data->lock); free(data); } /* Release the ccache handle. */ static krb5_error_code KRB5_CALLCONV fcc_close(krb5_context context, krb5_ccache id) { free_fccdata(context, id->data); free(id); return 0; } /* Destroy the cache file and release the handle. */ static krb5_error_code KRB5_CALLCONV fcc_destroy(krb5_context context, krb5_ccache id) { krb5_error_code ret = 0; fcc_data *data = id->data; int st, fd; struct stat buf; unsigned long i, size; unsigned int wlen; char zeros[BUFSIZ]; k5_cc_mutex_lock(context, &data->lock); fd = open(data->filename, O_RDWR | O_BINARY | O_CLOEXEC, 0); if (fd < 0) { ret = interpret_errno(context, errno); goto cleanup; } set_cloexec_fd(fd); #ifdef MSDOS_FILESYSTEM /* * "Disgusting bit of UNIX trivia" - that's how the writers of NFS describe * the ability of UNIX to still write to a file which has been unlinked. * Naturally, the PC can't do this. As a result, we have to delete the * file after we wipe it clean, but that throws off all the error handling * code. So we have do the work ourselves. */ st = fstat(fd, &buf); if (st == -1) { ret = interpret_errno(context, errno); size = 0; /* Nothing to wipe clean */ } else { size = (unsigned long)buf.st_size; } memset(zeros, 0, BUFSIZ); while (size > 0) { wlen = (int)((size > BUFSIZ) ? BUFSIZ : size); /* How much to write */ i = write(fd, zeros, wlen); if (i < 0) { ret = interpret_errno(context, errno); /* Don't jump to cleanup--we still want to delete the file. */ break; } size -= i; } (void)close(fd); st = unlink(data->filename); if (st < 0) { ret = interpret_errno(context, errno); goto cleanup; } #else /* MSDOS_FILESYSTEM */ st = unlink(data->filename); if (st < 0) { ret = interpret_errno(context, errno); (void)close(fd); goto cleanup; } st = fstat(fd, &buf); if (st < 0) { ret = interpret_errno(context, errno); (void)close(fd); goto cleanup; } /* XXX This may not be legal XXX */ size = (unsigned long)buf.st_size; memset(zeros, 0, BUFSIZ); for (i = 0; i < size / BUFSIZ; i++) { if (write(fd, zeros, BUFSIZ) < 0) { ret = interpret_errno(context, errno); (void)close(fd); goto cleanup; } } wlen = size % BUFSIZ; if (write(fd, zeros, wlen) < 0) { ret = interpret_errno(context, errno); (void)close(fd); goto cleanup; } st = close(fd); if (st) ret = interpret_errno(context, errno); #endif /* MSDOS_FILESYSTEM */ cleanup: (void)set_errmsg_filename(context, ret, data->filename); k5_cc_mutex_unlock(context, &data->lock); free_fccdata(context, data); free(id); krb5_change_cache(); return ret; } extern const krb5_cc_ops krb5_fcc_ops; /* Create a file ccache handle for the pathname given by residual. */ static krb5_error_code KRB5_CALLCONV fcc_resolve(krb5_context context, krb5_ccache *id, const char *residual) { krb5_ccache lid; krb5_error_code ret; fcc_data *data; data = malloc(sizeof(fcc_data)); if (data == NULL) return KRB5_CC_NOMEM; data->filename = strdup(residual); if (data->filename == NULL) { free(data); return KRB5_CC_NOMEM; } ret = k5_cc_mutex_init(&data->lock); if (ret) { free(data->filename); free(data); return ret; } lid = malloc(sizeof(struct _krb5_ccache)); if (lid == NULL) { free_fccdata(context, data); return KRB5_CC_NOMEM; } lid->ops = &krb5_fcc_ops; lid->data = data; lid->magic = KV5M_CCACHE; /* Other routines will get errors on open, and callers must expect them, if * cache is non-existent/unusable. */ *id = lid; return 0; } /* Prepare for a sequential iteration over the cache file. */ static krb5_error_code KRB5_CALLCONV fcc_start_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { krb5_fcc_cursor *fcursor = NULL; krb5_error_code ret; krb5_principal princ = NULL; fcc_data *data = id->data; FILE *fp = NULL; int version; k5_cc_mutex_lock(context, &data->lock); fcursor = malloc(sizeof(krb5_fcc_cursor)); if (fcursor == NULL) { ret = KRB5_CC_NOMEM; goto cleanup; } /* Open the cache file and read the header. */ ret = open_cache_file(context, data->filename, FALSE, &fp); if (ret) goto cleanup; ret = read_header(context, fp, &version); if (ret) goto cleanup; /* Read past the default client principal name. */ ret = read_principal(context, fp, version, &princ); if (ret) goto cleanup; /* Drop the shared file lock but retain the file handle. */ (void)krb5_unlock_file(context, fileno(fp)); fcursor->fp = fp; fp = NULL; fcursor->version = version; *cursor = (krb5_cc_cursor)fcursor; fcursor = NULL; cleanup: (void)close_cache_file(context, fp); free(fcursor); krb5_free_principal(context, princ); k5_cc_mutex_unlock(context, &data->lock); return set_errmsg_filename(context, ret, data->filename); } /* * Return true if cred is a removed entry. We assume that any active entry * with endtime=0 (such as a config entry or gssproxy encrypted credential) * will also have authtime=0. */ static inline krb5_boolean cred_removed(krb5_creds *c) { return c->times.endtime == 0 && c->times.authtime != 0; } /* Get the next credential from the cache file. */ static krb5_error_code KRB5_CALLCONV fcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_error_code ret; krb5_fcc_cursor *fcursor = *cursor; fcc_data *data = id->data; struct k5buf buf; size_t maxsize; krb5_boolean file_locked = FALSE; memset(creds, 0, sizeof(*creds)); k5_cc_mutex_lock(context, &data->lock); k5_buf_init_dynamic_zap(&buf); ret = krb5_lock_file(context, fileno(fcursor->fp), KRB5_LOCKMODE_SHARED); if (ret) goto cleanup; file_locked = TRUE; for (;;) { /* Load a marshalled cred into memory. */ ret = get_size(context, fcursor->fp, &maxsize); if (ret) goto cleanup; ret = load_cred(context, fcursor->fp, fcursor->version, maxsize, &buf); if (ret) goto cleanup; ret = k5_buf_status(&buf); if (ret) goto cleanup; /* Unmarshal it from buf into creds. */ ret = k5_unmarshal_cred(buf.data, buf.len, fcursor->version, creds); if (ret) goto cleanup; /* Keep going if this entry has been removed; otherwise stop. */ if (!cred_removed(creds)) break; k5_buf_truncate(&buf, 0); krb5_free_cred_contents(context, creds); } cleanup: if (file_locked) (void)krb5_unlock_file(context, fileno(fcursor->fp)); k5_cc_mutex_unlock(context, &data->lock); k5_buf_free(&buf); return set_errmsg_filename(context, ret, data->filename); } /* Release an iteration cursor. */ static krb5_error_code KRB5_CALLCONV fcc_end_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { krb5_fcc_cursor *fcursor = *cursor; (void)fclose(fcursor->fp); free(fcursor); *cursor = NULL; return 0; } /* Generate a unique file ccache using the given template (which will be * modified to contain the actual name of the file). */ krb5_error_code krb5int_fcc_new_unique(krb5_context context, char *template, krb5_ccache *id) { krb5_ccache lid; int fd; krb5_error_code ret; fcc_data *data; char fcc_fvno[2]; int16_t fcc_flen = 0; int errsave, cnt; fd = mkstemp(template); if (fd == -1) return interpret_errno(context, errno); set_cloexec_fd(fd); /* Allocate memory */ data = malloc(sizeof(fcc_data)); if (data == NULL) { close(fd); unlink(template); return KRB5_CC_NOMEM; } data->filename = strdup(template); if (data->filename == NULL) { free(data); close(fd); unlink(template); return KRB5_CC_NOMEM; } ret = k5_cc_mutex_init(&data->lock); if (ret) { free(data->filename); free(data); close(fd); unlink(template); return ret; } k5_cc_mutex_lock(context, &data->lock); /* Ignore user's umask, set mode = 0600 */ #ifndef HAVE_FCHMOD #ifdef HAVE_CHMOD chmod(data->filename, S_IRUSR | S_IWUSR); #endif #else fchmod(fd, S_IRUSR | S_IWUSR); #endif store_16_be(context->fcc_default_format, fcc_fvno); cnt = write(fd, &fcc_fvno, 2); if (cnt != 2) { errsave = errno; (void)close(fd); (void)unlink(data->filename); ret = (cnt == -1) ? interpret_errno(context, errsave) : KRB5_CC_IO; goto err_out; } /* For version 4 we save a length for the rest of the header */ if (context->fcc_default_format == FVNO_BASE + 4) { cnt = write(fd, &fcc_flen, sizeof(fcc_flen)); if (cnt != sizeof(fcc_flen)) { errsave = errno; (void)close(fd); (void)unlink(data->filename); ret = (cnt == -1) ? interpret_errno(context, errsave) : KRB5_CC_IO; goto err_out; } } if (close(fd) == -1) { errsave = errno; (void)unlink(data->filename); ret = interpret_errno(context, errsave); goto err_out; } k5_cc_mutex_assert_locked(context, &data->lock); k5_cc_mutex_unlock(context, &data->lock); lid = malloc(sizeof(*lid)); if (lid == NULL) { free_fccdata(context, data); return KRB5_CC_NOMEM; } lid->ops = &krb5_fcc_ops; lid->data = data; lid->magic = KV5M_CCACHE; *id = lid; krb5_change_cache(); return 0; err_out: (void)set_errmsg_filename(context, ret, data->filename); k5_cc_mutex_unlock(context, &data->lock); k5_cc_mutex_destroy(&data->lock); free(data->filename); free(data); return ret; } /* * Create a new file cred cache whose name is guaranteed to be unique. The * name begins with the string TKT_ROOT (from fcc.h). The cache file is not * opened, but the new filename is reserved. */ static krb5_error_code KRB5_CALLCONV fcc_generate_new(krb5_context context, krb5_ccache *id) { char scratch[sizeof(TKT_ROOT) + 7]; /* Room for XXXXXX and terminator */ (void)snprintf(scratch, sizeof(scratch), "%sXXXXXX", TKT_ROOT); return krb5int_fcc_new_unique(context, scratch, id); } /* Return an alias to the pathname of the cache file. */ static const char * KRB5_CALLCONV fcc_get_name(krb5_context context, krb5_ccache id) { return ((fcc_data *)id->data)->filename; } /* Retrieve a copy of the default principal, if the cache is initialized. */ static krb5_error_code KRB5_CALLCONV fcc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *princ) { krb5_error_code ret; fcc_data *data = id->data; FILE *fp = NULL; int version; k5_cc_mutex_lock(context, &data->lock); ret = open_cache_file(context, data->filename, FALSE, &fp); if (ret) goto cleanup; ret = read_header(context, fp, &version); if (ret) goto cleanup; ret = read_principal(context, fp, version, princ); cleanup: (void)close_cache_file(context, fp); k5_cc_mutex_unlock(context, &data->lock); return set_errmsg_filename(context, ret, data->filename); } /* Search for a credential within the cache file. */ static krb5_error_code KRB5_CALLCONV fcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds) { krb5_error_code ret; ret = k5_cc_retrieve_cred_default(context, id, whichfields, mcreds, creds); return set_errmsg_filename(context, ret, ((fcc_data *)id->data)->filename); } /* Store a credential in the cache file. */ static krb5_error_code KRB5_CALLCONV fcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) { krb5_error_code ret, ret2; fcc_data *data = id->data; FILE *fp = NULL; int version; struct k5buf buf = EMPTY_K5BUF; ssize_t nwritten; k5_cc_mutex_lock(context, &data->lock); /* Open the cache file for O_APPEND writing. */ ret = open_cache_file(context, data->filename, TRUE, &fp); if (ret) goto cleanup; ret = read_header(context, fp, &version); if (ret) goto cleanup; /* Marshal the cred and write it to the file with a single append write. */ k5_buf_init_dynamic_zap(&buf); k5_marshal_cred(&buf, version, creds); ret = k5_buf_status(&buf); if (ret) goto cleanup; nwritten = write(fileno(fp), buf.data, buf.len); if (nwritten == -1) ret = interpret_errno(context, errno); if ((size_t)nwritten != buf.len) ret = KRB5_CC_IO; krb5_change_cache(); cleanup: k5_buf_free(&buf); ret2 = close_cache_file(context, fp); k5_cc_mutex_unlock(context, &data->lock); return set_errmsg_filename(context, ret ? ret : ret2, data->filename); } /* * Overwrite cred in the ccache file with an entry that should not match any * reasonable search. Deletion is not guaranteed. This method is originally * from Heimdal, with the addition of setting authtime to -1. */ static krb5_error_code delete_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, krb5_creds *cred) { krb5_error_code ret; krb5_fcc_cursor *fcursor = *cursor; fcc_data *data = cache->data; struct k5buf expected = EMPTY_K5BUF, overwrite = EMPTY_K5BUF; int fd = -1; uint8_t *on_disk = NULL; ssize_t rwret; off_t start_offset; k5_buf_init_dynamic_zap(&expected); k5_buf_init_dynamic_zap(&overwrite); /* Re-marshal cred to get its byte representation in the file. */ k5_marshal_cred(&expected, fcursor->version, cred); ret = k5_buf_status(&expected); if (ret) goto cleanup; /* * Mark the cred expired so that it will be skipped over by any future * match checks. Heimdal only sets endtime, but we also set authtime to * distinguish from gssproxy's creds. */ cred->times.endtime = 0; cred->times.authtime = -1; /* For config entries, also change the realm so that other implementations * won't match them. */ if (data_eq_string(cred->server->realm, "X-CACHECONF:")) memcpy(cred->server->realm.data, "X-RMED-CONF:", 12); k5_marshal_cred(&overwrite, fcursor->version, cred); ret = k5_buf_status(&overwrite); if (ret) goto cleanup; if (expected.len != overwrite.len) { ret = KRB5_CC_FORMAT; goto cleanup; } /* Get a non-O_APPEND handle to the raw file. */ fd = open(data->filename, O_RDWR | O_BINARY | O_CLOEXEC); if (fd == -1) { ret = interpret_errno(context, errno); goto cleanup; } start_offset = ftell(fcursor->fp); if (start_offset == -1) { ret = interpret_errno(context, errno); goto cleanup; } start_offset -= expected.len; /* Read the bytes at the entry to be overwritten. */ if (lseek(fd, start_offset, SEEK_SET) == -1) { ret = interpret_errno(context, errno); goto cleanup; } on_disk = k5alloc(expected.len, &ret); if (ret != 0) goto cleanup; rwret = read(fd, on_disk, expected.len); if (rwret < 0) { ret = interpret_errno(context, errno); goto cleanup; } else if ((size_t)rwret != expected.len) { ret = KRB5_CC_FORMAT; goto cleanup; } /* * If the bytes have changed, either someone else removed the same cred or * the cache was reinitialized. Either way the cred is no longer present, * so return successfully. */ if (memcmp(on_disk, expected.data, expected.len) != 0) goto cleanup; /* Write out the altered entry. */ if (lseek(fd, start_offset, SEEK_SET) == -1) { ret = interpret_errno(context, errno); goto cleanup; } rwret = write(fd, overwrite.data, overwrite.len); if (rwret < 0) { ret = interpret_errno(context, errno); goto cleanup; } cleanup: if (fd >= 0) close(fd); zapfree(on_disk, expected.len); k5_buf_free(&expected); k5_buf_free(&overwrite); return ret; } /* Remove the given creds from the ccache file. */ static krb5_error_code KRB5_CALLCONV fcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *creds) { krb5_error_code ret; krb5_cc_cursor cursor; krb5_creds cur; ret = krb5_cc_start_seq_get(context, cache, &cursor); if (ret) return ret; for (;;) { ret = krb5_cc_next_cred(context, cache, &cursor, &cur); if (ret) break; if (krb5int_cc_creds_match_request(context, flags, creds, &cur)) ret = delete_cred(context, cache, &cursor, &cur); krb5_free_cred_contents(context, &cur); if (ret) break; } krb5_cc_end_seq_get(context, cache, &cursor); return (ret == KRB5_CC_END) ? 0 : ret; } static krb5_error_code KRB5_CALLCONV fcc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags) { return 0; } static krb5_error_code KRB5_CALLCONV fcc_get_flags(krb5_context context, krb5_ccache id, krb5_flags *flags) { *flags = 0; return 0; } /* Prepare to iterate over the caches in the per-type collection. */ static krb5_error_code KRB5_CALLCONV fcc_ptcursor_new(krb5_context context, krb5_cc_ptcursor *cursor) { krb5_cc_ptcursor n = NULL; struct krb5_fcc_ptcursor_data *cdata = NULL; *cursor = NULL; n = malloc(sizeof(*n)); if (n == NULL) return ENOMEM; n->ops = &krb5_fcc_ops; cdata = malloc(sizeof(*cdata)); if (cdata == NULL) { free(n); return ENOMEM; } cdata->first = TRUE; n->data = cdata; *cursor = n; return 0; } /* Get the next cache in the per-type collection. The FILE per-type collection * contains only the context's default cache if it is a file cache. */ static krb5_error_code KRB5_CALLCONV fcc_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor, krb5_ccache *cache_out) { krb5_error_code ret; struct krb5_fcc_ptcursor_data *cdata = cursor->data; const char *defname, *residual; krb5_ccache cache; struct stat sb; *cache_out = NULL; if (!cdata->first) return 0; cdata->first = FALSE; defname = krb5_cc_default_name(context); if (!defname) return 0; /* Check if the default has type FILE or no type; find the residual. */ if (strncmp(defname, "FILE:", 5) == 0) residual = defname + 5; else if (strchr(defname + 2, ':') == NULL) /* Skip drive prefix if any. */ residual = defname; else return 0; /* Don't yield a nonexistent default file cache. */ if (stat(residual, &sb) != 0) return 0; ret = krb5_cc_resolve(context, defname, &cache); if (ret) return set_errmsg_filename(context, ret, defname); *cache_out = cache; return 0; } /* Release a per-type collection iteration cursor. */ static krb5_error_code KRB5_CALLCONV fcc_ptcursor_free(krb5_context context, krb5_cc_ptcursor *cursor) { if (*cursor == NULL) return 0; free((*cursor)->data); free(*cursor); *cursor = NULL; return 0; } /* Lock the cache handle against other threads. (This does not lock the cache * file against other processes.) */ static krb5_error_code KRB5_CALLCONV fcc_lock(krb5_context context, krb5_ccache id) { fcc_data *data = id->data; k5_cc_mutex_lock(context, &data->lock); return 0; } /* Unlock the cache handle. */ static krb5_error_code KRB5_CALLCONV fcc_unlock(krb5_context context, krb5_ccache id) { fcc_data *data = id->data; k5_cc_mutex_unlock(context, &data->lock); return 0; } static krb5_error_code KRB5_CALLCONV fcc_replace(krb5_context context, krb5_ccache id, krb5_principal princ, krb5_creds **creds) { krb5_error_code ret; fcc_data *data = id->data; char *tmpname = NULL; int i, st, fd = -1, version = context->fcc_default_format - FVNO_BASE; ssize_t nwritten; struct k5buf buf = EMPTY_K5BUF; krb5_boolean tmpfile_exists = FALSE; if (asprintf(&tmpname, "%s.XXXXXX", data->filename) < 0) return ENOMEM; fd = mkstemp(tmpname); if (fd < 0) goto errno_cleanup; tmpfile_exists = TRUE; k5_buf_init_dynamic_zap(&buf); marshal_header(context, &buf, princ); for (i = 0; creds[i] != NULL; i++) k5_marshal_cred(&buf, version, creds[i]); ret = k5_buf_status(&buf); if (ret) goto cleanup; nwritten = write(fd, buf.data, buf.len); if (nwritten == -1) goto errno_cleanup; if ((size_t)nwritten != buf.len) { ret = KRB5_CC_IO; goto cleanup; } st = close(fd); fd = -1; if (st != 0) goto errno_cleanup; st = rename(tmpname, data->filename); if (st != 0) goto errno_cleanup; tmpfile_exists = FALSE; cleanup: k5_buf_free(&buf); if (fd != -1) close(fd); if (tmpfile_exists) unlink(tmpname); free(tmpname); return ret; errno_cleanup: ret = interpret_errno(context, errno); goto cleanup; } /* Translate a system errno value to a Kerberos com_err code. */ static krb5_error_code interpret_errno(krb5_context context, int errnum) { krb5_error_code ret; switch (errnum) { case ENOENT: case ENOTDIR: #ifdef ELOOP case ELOOP: #endif #ifdef ENAMETOOLONG case ENAMETOOLONG: #endif ret = KRB5_FCC_NOFILE; break; case EPERM: case EACCES: #ifdef EISDIR case EISDIR: /* Mac doesn't have EISDIR */ #endif case EROFS: ret = KRB5_FCC_PERM; break; case EINVAL: case EEXIST: case EFAULT: case EBADF: #ifdef EWOULDBLOCK case EWOULDBLOCK: #endif ret = KRB5_FCC_INTERNAL; break; /* * The rest all map to KRB5_CC_IO. These errnos are listed to * document that they've been considered explicitly: * * - EDQUOT * - ENOSPC * - EIO * - ENFILE * - EMFILE * - ENXIO * - EBUSY * - ETXTBSY */ default: ret = KRB5_CC_IO; break; } return ret; } const krb5_cc_ops krb5_fcc_ops = { 0, "FILE", fcc_get_name, fcc_resolve, fcc_generate_new, fcc_initialize, fcc_destroy, fcc_close, fcc_store, fcc_retrieve, fcc_get_principal, fcc_start_seq_get, fcc_next_cred, fcc_end_seq_get, fcc_remove_cred, fcc_set_flags, fcc_get_flags, fcc_ptcursor_new, fcc_ptcursor_next, fcc_ptcursor_free, fcc_replace, NULL, /* wasdefault */ fcc_lock, fcc_unlock, NULL, /* switch_to */ }; #if defined(_WIN32) /* * krb5_change_cache should be called after the cache changes. * A notification message is is posted out to all top level * windows so that they may recheck the cache based on the * changes made. We register a unique message type with which * we'll communicate to all other processes. */ krb5_error_code krb5_change_cache(void) { PostMessage(HWND_BROADCAST, krb5_get_notification_message(), 0, 0); return 0; } unsigned int KRB5_CALLCONV krb5_get_notification_message(void) { static unsigned int message = 0; if (message == 0) message = RegisterWindowMessage(WM_KERBEROS5_CHANGED); return message; } #else /* _WIN32 */ krb5_error_code krb5_change_cache(void) { return 0; } unsigned int krb5_get_notification_message(void) { return 0; } #endif /* _WIN32 */ const krb5_cc_ops krb5_cc_file_ops = { 0, "FILE", fcc_get_name, fcc_resolve, fcc_generate_new, fcc_initialize, fcc_destroy, fcc_close, fcc_store, fcc_retrieve, fcc_get_principal, fcc_start_seq_get, fcc_next_cred, fcc_end_seq_get, fcc_remove_cred, fcc_set_flags, fcc_get_flags, fcc_ptcursor_new, fcc_ptcursor_next, fcc_ptcursor_free, fcc_replace, NULL, /* wasdefault */ fcc_lock, fcc_unlock, NULL, /* switch_to */ }; krb5-1.22.1/src/lib/krb5/ccache/cc_keyring.c0000664000175000017500000015167615051422640020250 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cc_keyring.c */ /* * Copyright (c) 2006 * The Regents of the University of Michigan * ALL RIGHTS RESERVED * * Permission is granted to use, copy, create derivative works * and redistribute this software and such derivative works * for any purpose, so long as the name of The University of * Michigan is not used in any advertising or publicity * pertaining to the use of distribution of this software * without specific, written prior authorization. If the * above copyright notice or any other identification of the * University of Michigan is included in any copy of any * portion of this software, then the disclaimer below must * also be included. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF * SUCH DAMAGES. */ /* * Copyright 1990,1991,1992,1993,1994,2000,2004 Massachusetts Institute of * Technology. All Rights Reserved. * * Original stdio support copyright 1995 by Cygnus Support. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This file implements a collection-enabled credential cache type where the * credentials are stored in the Linux keyring facility. * * A residual of this type can have three forms: * anchor:collection:subsidiary * anchor:collection * collection * * The anchor name is "process", "thread", or "legacy" and determines where we * search for keyring collections. In the third form, the anchor name is * presumed to be "legacy". The anchor keyring for legacy caches is the * session keyring. * * If the subsidiary name is present, the residual identifies a single cache * within a collection. Otherwise, the residual identifies the collection * itself. When a residual identifying a collection is resolved, the * collection's primary key is looked up (or initialized, using the collection * name as the subsidiary name), and the resulting cache's name will use the * first name form and will identify the primary cache. * * Keyring collections are named "_krb_" and are linked from the * anchor keyring. The keys within a keyring collection are links to cache * keyrings, plus a link to one user key named "krb_ccache:primary" which * contains a serialized representation of the collection version (currently 1) * and the primary name of the collection. * * Cache keyrings contain one user key per credential which contains a * serialized representation of the credential. There is also one user key * named "__krb5_princ__" which contains a serialized representation of the * cache's default principal. * * If the anchor name is "legacy", then the initial primary cache (the one * named with the collection name) is also linked to the session keyring, and * we look for a cache in that location when initializing the collection. This * extra link allows that cache to be visible to old versions of the KEYRING * cache type, and allows us to see caches created by that code. */ #include "cc-int.h" #ifdef USE_KEYRING_CCACHE #include #include #ifdef DEBUG #define KRCC_DEBUG 1 #endif #if KRCC_DEBUG void debug_print(char *fmt, ...); /* prototype to silence warning */ #include #define DEBUG_PRINT(x) debug_print x void debug_print(char *fmt, ...) { va_list ap; va_start(ap, fmt); #ifdef DEBUG_STDERR vfprintf(stderr, fmt, ap); #else vsyslog(LOG_ERR, fmt, ap); #endif va_end(ap); } #else #define DEBUG_PRINT(x) #endif /* * We try to use the big_key key type for credentials except in legacy caches. * We fall back to the user key type if the kernel does not support big_key. * If the library doesn't support keyctl_get_persistent(), we don't even try * big_key since the two features were added at the same time. */ #ifdef HAVE_PERSISTENT_KEYRING #define KRCC_CRED_KEY_TYPE "big_key" #else #define KRCC_CRED_KEY_TYPE "user" #endif /* * We use the "user" key type for collection primary names, for cache principal * names, and for credentials in legacy caches. */ #define KRCC_KEY_TYPE_USER "user" /* * We create ccaches as separate keyrings */ #define KRCC_KEY_TYPE_KEYRING "keyring" /* * Special name of the key within a ccache keyring * holding principal information */ #define KRCC_SPEC_PRINC_KEYNAME "__krb5_princ__" /* * Special name for the key to communicate the name(s) * of credentials caches to be used for requests. * This should currently contain a single name, but * in the future may contain a list that may be * intelligently chosen from. */ #define KRCC_SPEC_CCACHE_SET_KEYNAME "__krb5_cc_set__" /* * This name identifies the key containing the name of the current primary * cache within a collection. */ #define KRCC_COLLECTION_PRIMARY "krb_ccache:primary" /* * If the library context does not specify a keyring collection, unique ccaches * will be created within this collection. */ #define KRCC_DEFAULT_UNIQUE_COLLECTION "session:__krb5_unique__" /* * Collection keyring names begin with this prefix. We use a prefix so that a * cache keyring with the collection name itself can be linked directly into * the anchor, for legacy session keyring compatibility. */ #define KRCC_CCCOL_PREFIX "_krb_" /* * For the "persistent" anchor type, we look up or create this fixed keyring * name within the per-UID persistent keyring. */ #define KRCC_PERSISTENT_KEYRING_NAME "_krb" /* * Name of the key holding time offsets for the individual cache */ #define KRCC_TIME_OFFSETS "__krb5_time_offsets__" /* * Keyring name prefix and length of random name part */ #define KRCC_NAME_PREFIX "krb_ccache_" #define KRCC_NAME_RAND_CHARS 8 #define KRCC_COLLECTION_VERSION 1 #define KRCC_PERSISTENT_ANCHOR "persistent" #define KRCC_PROCESS_ANCHOR "process" #define KRCC_THREAD_ANCHOR "thread" #define KRCC_SESSION_ANCHOR "session" #define KRCC_USER_ANCHOR "user" #define KRCC_LEGACY_ANCHOR "legacy" typedef struct _krcc_cursor { int numkeys; int currkey; key_serial_t princ_id; key_serial_t offsets_id; key_serial_t *keys; } *krcc_cursor; /* * This represents a credentials cache "file" * where cache_id is the keyring serial number for * this credentials cache "file". Each key * in the keyring contains a separate key. */ typedef struct _krcc_data { char *name; /* Name for this credentials cache */ k5_cc_mutex lock; /* synchronization */ key_serial_t collection_id; /* collection containing this cache keyring */ key_serial_t cache_id; /* keyring representing ccache */ key_serial_t princ_id; /* key holding principal info */ krb5_boolean is_legacy_type; } krcc_data; /* Global mutex */ k5_cc_mutex krb5int_krcc_mutex = K5_CC_MUTEX_PARTIAL_INITIALIZER; extern const krb5_cc_ops krb5_krcc_ops; static const char *KRB5_CALLCONV krcc_get_name(krb5_context context, krb5_ccache id); static krb5_error_code KRB5_CALLCONV krcc_start_seq_get(krb5_context, krb5_ccache id, krb5_cc_cursor *cursor); static krb5_error_code KRB5_CALLCONV krcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds); static krb5_error_code KRB5_CALLCONV krcc_end_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor); static krb5_error_code KRB5_CALLCONV krcc_ptcursor_free(krb5_context context, krb5_cc_ptcursor *cursor); static krb5_error_code clear_cache_keyring(krb5_context context, krb5_ccache id); static krb5_error_code make_krcc_data(const char *anchor_name, const char *collection_name, const char *subsidiary_name, key_serial_t cache_id, key_serial_t collection_id, krcc_data **datapp); static krb5_error_code save_principal(krb5_context context, krb5_ccache id, krb5_principal princ); static krb5_error_code save_time_offsets(krb5_context context, krb5_ccache id, int32_t time_offset, int32_t usec_offset); static krb5_error_code get_time_offsets(krb5_context context, krb5_ccache id, int32_t *time_offset, int32_t *usec_offset); /* Note the following is a stub function for Linux */ extern krb5_error_code krb5_change_cache(void); /* * GET_PERSISTENT(uid) acquires the persistent keyring for uid, or falls back * to the user keyring if uid matches the current effective uid. */ static key_serial_t get_persistent_fallback(uid_t uid) { return (uid == geteuid()) ? KEY_SPEC_USER_KEYRING : -1; } #ifdef HAVE_PERSISTENT_KEYRING #define GET_PERSISTENT get_persistent_real static key_serial_t get_persistent_real(uid_t uid) { key_serial_t key; key = keyctl_get_persistent(uid, KEY_SPEC_PROCESS_KEYRING); return (key == -1 && errno == ENOTSUP) ? get_persistent_fallback(uid) : key; } #else #define GET_PERSISTENT get_persistent_fallback #endif /* * If a process has no explicitly set session keyring, KEY_SPEC_SESSION_KEYRING * will resolve to the user session keyring for ID lookup and reading, but in * some kernel versions, writing to that special keyring will instead create a * new empty session keyring for the process. We do not want that; the keys we * create would be invisible to other processes. We can work around that * behavior by explicitly writing to the user session keyring when it matches * the session keyring. This function returns the keyring we should write to * for the session anchor. */ static key_serial_t session_write_anchor(void) { key_serial_t s, u; s = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0); u = keyctl_get_keyring_ID(KEY_SPEC_USER_SESSION_KEYRING, 0); return (s == u) ? KEY_SPEC_USER_SESSION_KEYRING : KEY_SPEC_SESSION_KEYRING; } /* * Find or create a keyring within parent with the given name. If possess is * nonzero, also make sure the key is linked from possess. This is necessary * to ensure that we have possession rights on the key when the parent is the * user or persistent keyring. */ static krb5_error_code find_or_create_keyring(key_serial_t parent, key_serial_t possess, const char *name, key_serial_t *key_out) { key_serial_t key; *key_out = -1; key = keyctl_search(parent, KRCC_KEY_TYPE_KEYRING, name, possess); if (key == -1) { if (possess != 0) { key = add_key(KRCC_KEY_TYPE_KEYRING, name, NULL, 0, possess); if (key == -1) return errno; if (keyctl_link(key, parent) == -1) return errno; } else { key = add_key(KRCC_KEY_TYPE_KEYRING, name, NULL, 0, parent); if (key == -1) return errno; } } *key_out = key; return 0; } /* Parse a residual name into an anchor name, a collection name, and possibly a * subsidiary name. */ static krb5_error_code parse_residual(const char *residual, char **anchor_name_out, char **collection_name_out, char **subsidiary_name_out) { krb5_error_code ret; char *anchor_name = NULL, *collection_name = NULL, *subsidiary_name = NULL; const char *sep; *anchor_name_out = 0; *collection_name_out = NULL; *subsidiary_name_out = NULL; /* Parse out the anchor name. Use the legacy anchor if not present. */ sep = strchr(residual, ':'); if (sep == NULL) { anchor_name = strdup(KRCC_LEGACY_ANCHOR); if (anchor_name == NULL) goto oom; } else { anchor_name = k5memdup0(residual, sep - residual, &ret); if (anchor_name == NULL) goto oom; residual = sep + 1; } /* Parse out the collection and subsidiary name. */ sep = strchr(residual, ':'); if (sep == NULL) { collection_name = strdup(residual); if (collection_name == NULL) goto oom; subsidiary_name = NULL; } else { collection_name = k5memdup0(residual, sep - residual, &ret); if (collection_name == NULL) goto oom; subsidiary_name = strdup(sep + 1); if (subsidiary_name == NULL) goto oom; } *anchor_name_out = anchor_name; *collection_name_out = collection_name; *subsidiary_name_out = subsidiary_name; return 0; oom: free(anchor_name); free(collection_name); free(subsidiary_name); return ENOMEM; } /* * Return true if residual identifies a subsidiary cache which should be linked * into the anchor so it can be visible to old code. This is the case if the * residual has the legacy anchor and the subsidiary name matches the * collection name. */ static krb5_boolean is_legacy_cache_name(const char *residual) { const char *sep, *aname, *cname, *sname; size_t alen, clen, legacy_len = sizeof(KRCC_LEGACY_ANCHOR) - 1; /* Get pointers to the anchor, collection, and subsidiary names. */ aname = residual; sep = strchr(residual, ':'); if (sep == NULL) return FALSE; alen = sep - aname; cname = sep + 1; sep = strchr(cname, ':'); if (sep == NULL) return FALSE; clen = sep - cname; sname = sep + 1; return alen == legacy_len && clen == strlen(sname) && strncmp(aname, KRCC_LEGACY_ANCHOR, alen) == 0 && strncmp(cname, sname, clen) == 0; } /* If the default cache name for context is a KEYRING cache, parse its residual * string. Otherwise set all outputs to NULL. */ static krb5_error_code get_default(krb5_context context, char **anchor_name_out, char **collection_name_out, char **subsidiary_name_out) { const char *defname; *anchor_name_out = *collection_name_out = *subsidiary_name_out = NULL; defname = krb5_cc_default_name(context); if (defname == NULL || strncmp(defname, "KEYRING:", 8) != 0) return 0; return parse_residual(defname + 8, anchor_name_out, collection_name_out, subsidiary_name_out); } /* Create a residual identifying a subsidiary cache. */ static krb5_error_code make_subsidiary_residual(const char *anchor_name, const char *collection_name, const char *subsidiary_name, char **residual_out) { if (asprintf(residual_out, "%s:%s:%s", anchor_name, collection_name, subsidiary_name) < 0) { *residual_out = NULL; return ENOMEM; } return 0; } /* Retrieve or create a keyring for collection_name within the anchor, and set * *collection_id_out to its serial number. */ static krb5_error_code get_collection(const char *anchor_name, const char *collection_name, key_serial_t *collection_id_out) { krb5_error_code ret; key_serial_t persistent_id, anchor_id, possess_id = 0; char *ckname, *cnend; long uidnum; *collection_id_out = 0; if (strcmp(anchor_name, KRCC_PERSISTENT_ANCHOR) == 0) { /* * The collection name is a uid (or empty for the current effective * uid), and we look up a fixed keyring name within the persistent * keyring for that uid. We link it to the process keyring to ensure * that we have possession rights on the collection key. */ if (*collection_name != '\0') { errno = 0; uidnum = strtol(collection_name, &cnend, 10); if (errno || *cnend != '\0') return KRB5_KCC_INVALID_UID; } else { uidnum = geteuid(); } persistent_id = GET_PERSISTENT(uidnum); if (persistent_id == -1) return KRB5_KCC_INVALID_UID; return find_or_create_keyring(persistent_id, KEY_SPEC_PROCESS_KEYRING, KRCC_PERSISTENT_KEYRING_NAME, collection_id_out); } if (strcmp(anchor_name, KRCC_PROCESS_ANCHOR) == 0) { anchor_id = KEY_SPEC_PROCESS_KEYRING; } else if (strcmp(anchor_name, KRCC_THREAD_ANCHOR) == 0) { anchor_id = KEY_SPEC_THREAD_KEYRING; } else if (strcmp(anchor_name, KRCC_SESSION_ANCHOR) == 0) { anchor_id = session_write_anchor(); } else if (strcmp(anchor_name, KRCC_USER_ANCHOR) == 0) { /* The user keyring does not confer possession, so we need to link the * collection to the process keyring to maintain possession rights. */ anchor_id = KEY_SPEC_USER_KEYRING; possess_id = KEY_SPEC_PROCESS_KEYRING; } else if (strcmp(anchor_name, KRCC_LEGACY_ANCHOR) == 0) { anchor_id = session_write_anchor(); } else { return KRB5_KCC_INVALID_ANCHOR; } /* Look up the collection keyring name within the anchor keyring. */ if (asprintf(&ckname, "%s%s", KRCC_CCCOL_PREFIX, collection_name) == -1) return ENOMEM; ret = find_or_create_keyring(anchor_id, possess_id, ckname, collection_id_out); free(ckname); return ret; } /* Store subsidiary_name into the primary index key for collection_id. */ static krb5_error_code set_primary_name(krb5_context context, key_serial_t collection_id, const char *subsidiary_name) { key_serial_t key; uint32_t len = strlen(subsidiary_name), plen = 8 + len; unsigned char *payload; payload = malloc(plen); if (payload == NULL) return ENOMEM; store_32_be(KRCC_COLLECTION_VERSION, payload); store_32_be(len, payload + 4); memcpy(payload + 8, subsidiary_name, len); key = add_key(KRCC_KEY_TYPE_USER, KRCC_COLLECTION_PRIMARY, payload, plen, collection_id); free(payload); return (key == -1) ? errno : 0; } static krb5_error_code parse_index(krb5_context context, int32_t *version, char **primary, const unsigned char *payload, size_t psize) { krb5_error_code ret; uint32_t len; if (psize < 8) return KRB5_CC_END; *version = load_32_be(payload); len = load_32_be(payload + 4); if (len > psize - 8) return KRB5_CC_END; *primary = k5memdup0(payload + 8, len, &ret); return (*primary == NULL) ? ret : 0; } /* * Get or initialize the primary name within collection_id and set * *subsidiary_out to its value. If initializing a legacy collection, look * for a legacy cache and add it to the collection. */ static krb5_error_code get_primary_name(krb5_context context, const char *anchor_name, const char *collection_name, key_serial_t collection_id, char **subsidiary_out) { krb5_error_code ret; key_serial_t primary_id, legacy; void *payload = NULL; int payloadlen; int32_t version; char *subsidiary_name = NULL; *subsidiary_out = NULL; primary_id = keyctl_search(collection_id, KRCC_KEY_TYPE_USER, KRCC_COLLECTION_PRIMARY, 0); if (primary_id == -1) { /* Initialize the primary key using the collection name. We can't name * a key with the empty string, so map that to an arbitrary string. */ subsidiary_name = strdup((*collection_name == '\0') ? "tkt" : collection_name); if (subsidiary_name == NULL) { ret = ENOMEM; goto cleanup; } ret = set_primary_name(context, collection_id, subsidiary_name); if (ret) goto cleanup; if (strcmp(anchor_name, KRCC_LEGACY_ANCHOR) == 0) { /* Look for a cache created by old code. If we find one, add it to * the collection. */ legacy = keyctl_search(KEY_SPEC_SESSION_KEYRING, KRCC_KEY_TYPE_KEYRING, subsidiary_name, 0); if (legacy != -1 && keyctl_link(legacy, collection_id) == -1) { ret = errno; goto cleanup; } } } else { /* Read, parse, and free the primary key's payload. */ payloadlen = keyctl_read_alloc(primary_id, &payload); if (payloadlen == -1) { ret = errno; goto cleanup; } ret = parse_index(context, &version, &subsidiary_name, payload, payloadlen); if (ret) goto cleanup; if (version != KRCC_COLLECTION_VERSION) { ret = KRB5_KCC_UNKNOWN_VERSION; goto cleanup; } } *subsidiary_out = subsidiary_name; subsidiary_name = NULL; cleanup: free(payload); free(subsidiary_name); return ret; } /* * Create a keyring with a unique random name within collection_id. Set * *subsidiary to its name and *cache_id_out to its key serial number. */ static krb5_error_code unique_keyring(krb5_context context, key_serial_t collection_id, char **subsidiary_out, key_serial_t *cache_id_out) { key_serial_t key; krb5_error_code ret; char uniquename[sizeof(KRCC_NAME_PREFIX) + KRCC_NAME_RAND_CHARS]; int prefixlen = sizeof(KRCC_NAME_PREFIX) - 1; int tries; *subsidiary_out = NULL; *cache_id_out = 0; memcpy(uniquename, KRCC_NAME_PREFIX, sizeof(KRCC_NAME_PREFIX)); k5_cc_mutex_lock(context, &krb5int_krcc_mutex); /* Loop until we successfully create a new ccache keyring with * a unique name, or we get an error. Limit to 100 tries. */ tries = 100; while (tries-- > 0) { ret = krb5int_random_string(context, uniquename + prefixlen, KRCC_NAME_RAND_CHARS); if (ret) goto cleanup; key = keyctl_search(collection_id, KRCC_KEY_TYPE_KEYRING, uniquename, 0); if (key < 0) { /* Name does not already exist. Create it to reserve the name. */ key = add_key(KRCC_KEY_TYPE_KEYRING, uniquename, NULL, 0, collection_id); if (key < 0) { ret = errno; goto cleanup; } break; } } if (tries <= 0) { ret = KRB5_CC_BADNAME; goto cleanup; } *subsidiary_out = strdup(uniquename); if (*subsidiary_out == NULL) { ret = ENOMEM; goto cleanup; } *cache_id_out = key; ret = 0; cleanup: k5_cc_mutex_unlock(context, &krb5int_krcc_mutex); return ret; } static krb5_error_code add_cred_key(const char *name, const void *payload, size_t plen, key_serial_t cache_id, krb5_boolean legacy_type, key_serial_t *key_out) { key_serial_t key; *key_out = -1; if (!legacy_type) { /* Try the preferred cred key type; fall back if no kernel support. */ key = add_key(KRCC_CRED_KEY_TYPE, name, payload, plen, cache_id); if (key != -1) { *key_out = key; return 0; } else if (errno != EINVAL && errno != ENODEV) { return errno; } } /* Use the user key type. */ key = add_key(KRCC_KEY_TYPE_USER, name, payload, plen, cache_id); if (key == -1) return errno; *key_out = key; return 0; } static void update_keyring_expiration(krb5_context context, krb5_ccache id) { krcc_data *data = id->data; krb5_cc_cursor cursor; krb5_creds creds; krb5_timestamp now, endtime = 0; unsigned int timeout; /* * We have no way to know what is the actual timeout set on the keyring. * We also cannot keep track of it in a local variable as another process * can always modify the keyring independently, so just always enumerate * all keys and find out the highest endtime time. */ /* Find the maximum endtime of all creds in the cache. */ if (krcc_start_seq_get(context, id, &cursor) != 0) return; for (;;) { if (krcc_next_cred(context, id, &cursor, &creds) != 0) break; if (ts_after(creds.times.endtime, endtime)) endtime = creds.times.endtime; krb5_free_cred_contents(context, &creds); } (void)krcc_end_seq_get(context, id, &cursor); if (endtime == 0) /* No creds with end times */ return; if (krb5_timeofday(context, &now) != 0) return; /* Setting the timeout to zero would reset the timeout, so we set it to one * second instead if creds are already expired. */ timeout = ts_after(endtime, now) ? ts_interval(now, endtime) : 1; (void)keyctl_set_timeout(data->cache_id, timeout); } /* Create or overwrite the cache keyring, and set the default principal. */ static krb5_error_code KRB5_CALLCONV krcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ) { krcc_data *data = (krcc_data *)id->data; krb5_os_context os_ctx = &context->os_context; krb5_error_code ret; const char *cache_name, *p; k5_cc_mutex_lock(context, &data->lock); ret = clear_cache_keyring(context, id); if (ret) goto out; if (!data->cache_id) { /* The key didn't exist at resolve time. Check again and create the * key if it still isn't there. */ p = strrchr(data->name, ':'); cache_name = (p != NULL) ? p + 1 : data->name; ret = find_or_create_keyring(data->collection_id, 0, cache_name, &data->cache_id); if (ret) goto out; } /* If this is the legacy cache in a legacy session collection, link it * directly to the session keyring so that old code can see it. */ if (is_legacy_cache_name(data->name)) (void)keyctl_link(data->cache_id, session_write_anchor()); ret = save_principal(context, id, princ); /* Save time offset if it is valid and this is not a legacy cache. Legacy * applications would fail to parse the new key in the cache keyring. */ if (!is_legacy_cache_name(data->name) && (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)) { ret = save_time_offsets(context, id, os_ctx->time_offset, os_ctx->usec_offset); } if (ret == 0) krb5_change_cache(); out: k5_cc_mutex_unlock(context, &data->lock); return ret; } /* Release the ccache handle. */ static krb5_error_code KRB5_CALLCONV krcc_close(krb5_context context, krb5_ccache id) { krcc_data *data = id->data; k5_cc_mutex_destroy(&data->lock); free(data->name); free(data); free(id); return 0; } /* Clear out a ccache keyring, unlinking all keys within it. Call with the * mutex locked. */ static krb5_error_code clear_cache_keyring(krb5_context context, krb5_ccache id) { krcc_data *data = id->data; int res; k5_cc_mutex_assert_locked(context, &data->lock); DEBUG_PRINT(("clear_cache_keyring: cache_id %d, princ_id %d\n", data->cache_id, data->princ_id)); if (data->cache_id) { res = keyctl_clear(data->cache_id); if (res != 0) return errno; } data->princ_id = 0; return 0; } /* Destroy the cache keyring and release the handle. */ static krb5_error_code KRB5_CALLCONV krcc_destroy(krb5_context context, krb5_ccache id) { krb5_error_code ret = 0; krcc_data *data = id->data; int res; k5_cc_mutex_lock(context, &data->lock); clear_cache_keyring(context, id); if (data->cache_id) { res = keyctl_unlink(data->cache_id, data->collection_id); if (res < 0) { ret = errno; DEBUG_PRINT(("unlinking key %d from ring %d: %s", data->cache_id, data->collection_id, error_message(errno))); } /* If this is a legacy cache, unlink it from the session anchor. */ if (is_legacy_cache_name(data->name)) (void)keyctl_unlink(data->cache_id, session_write_anchor()); } k5_cc_mutex_unlock(context, &data->lock); k5_cc_mutex_destroy(&data->lock); free(data->name); free(data); free(id); krb5_change_cache(); return ret; } /* Create a cache handle for a cache ID. */ static krb5_error_code make_cache(krb5_context context, key_serial_t collection_id, key_serial_t cache_id, const char *anchor_name, const char *collection_name, const char *subsidiary_name, krb5_ccache *cache_out) { krb5_error_code ret; krb5_os_context os_ctx = &context->os_context; krb5_ccache ccache = NULL; krcc_data *data; key_serial_t pkey = 0; /* Determine the key containing principal information, if present. */ pkey = keyctl_search(cache_id, KRCC_KEY_TYPE_USER, KRCC_SPEC_PRINC_KEYNAME, 0); if (pkey < 0) pkey = 0; ccache = malloc(sizeof(struct _krb5_ccache)); if (!ccache) return ENOMEM; ret = make_krcc_data(anchor_name, collection_name, subsidiary_name, cache_id, collection_id, &data); if (ret) { free(ccache); return ret; } data->princ_id = pkey; ccache->ops = &krb5_krcc_ops; ccache->data = data; ccache->magic = KV5M_CCACHE; *cache_out = ccache; /* Look up time offsets if necessary. */ if ((context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) && !(os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)) { if (get_time_offsets(context, ccache, &os_ctx->time_offset, &os_ctx->usec_offset) == 0) { os_ctx->os_flags &= ~KRB5_OS_TOFFSET_TIME; os_ctx->os_flags |= KRB5_OS_TOFFSET_VALID; } } return 0; } /* Create a keyring ccache handle for the given residual string. */ static krb5_error_code KRB5_CALLCONV krcc_resolve(krb5_context context, krb5_ccache *id, const char *residual) { krb5_error_code ret; key_serial_t collection_id, cache_id; char *anchor_name = NULL, *collection_name = NULL, *subsidiary_name = NULL; ret = parse_residual(residual, &anchor_name, &collection_name, &subsidiary_name); if (ret) goto cleanup; ret = get_collection(anchor_name, collection_name, &collection_id); if (ret) goto cleanup; if (subsidiary_name == NULL) { /* Retrieve or initialize the primary name for the collection. */ ret = get_primary_name(context, anchor_name, collection_name, collection_id, &subsidiary_name); if (ret) goto cleanup; } /* Look up the cache keyring ID, if the cache is already initialized. */ cache_id = keyctl_search(collection_id, KRCC_KEY_TYPE_KEYRING, subsidiary_name, 0); if (cache_id < 0) cache_id = 0; ret = make_cache(context, collection_id, cache_id, anchor_name, collection_name, subsidiary_name, id); if (ret) goto cleanup; cleanup: free(anchor_name); free(collection_name); free(subsidiary_name); return ret; } /* Prepare for a sequential iteration over the cache keyring. */ static krb5_error_code KRB5_CALLCONV krcc_start_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { krcc_cursor krcursor; krcc_data *data = id->data; void *keys; long size; k5_cc_mutex_lock(context, &data->lock); if (!data->cache_id) { k5_cc_mutex_unlock(context, &data->lock); return KRB5_FCC_NOFILE; } size = keyctl_read_alloc(data->cache_id, &keys); if (size == -1) { DEBUG_PRINT(("Error getting from keyring: %s\n", strerror(errno))); k5_cc_mutex_unlock(context, &data->lock); return KRB5_CC_IO; } krcursor = calloc(1, sizeof(*krcursor)); if (krcursor == NULL) { free(keys); k5_cc_mutex_unlock(context, &data->lock); return KRB5_CC_NOMEM; } krcursor->princ_id = data->princ_id; krcursor->offsets_id = keyctl_search(data->cache_id, KRCC_KEY_TYPE_USER, KRCC_TIME_OFFSETS, 0); krcursor->numkeys = size / sizeof(key_serial_t); krcursor->keys = keys; k5_cc_mutex_unlock(context, &data->lock); *cursor = krcursor; return 0; } /* Get the next credential from the cache keyring. */ static krb5_error_code KRB5_CALLCONV krcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krcc_cursor krcursor; krb5_error_code ret; int psize; void *payload = NULL; memset(creds, 0, sizeof(krb5_creds)); /* The cursor has the entire list of keys. */ krcursor = *cursor; if (krcursor == NULL) return KRB5_CC_END; while (krcursor->currkey < krcursor->numkeys) { /* If we're pointing at the entry with the principal, or at the key * with the time offsets, skip it. */ if (krcursor->keys[krcursor->currkey] == krcursor->princ_id || krcursor->keys[krcursor->currkey] == krcursor->offsets_id) { krcursor->currkey++; continue; } /* Read the key; the right size buffer will be allocated and * returned. */ psize = keyctl_read_alloc(krcursor->keys[krcursor->currkey], &payload); if (psize != -1) { krcursor->currkey++; /* Unmarshal the cred using the file ccache version 4 format. */ ret = k5_unmarshal_cred(payload, psize, 4, creds); free(payload); return ret; } else if (errno != ENOKEY && errno != EACCES) { DEBUG_PRINT(("Error reading key %d: %s\n", krcursor->keys[krcursor->currkey], strerror(errno))); return KRB5_FCC_NOFILE; } /* The current key was unlinked, probably by a remove_cred call; move * on to the next one. */ krcursor->currkey++; } /* No more keys in keyring. */ return KRB5_CC_END; } /* Release an iteration cursor. */ static krb5_error_code KRB5_CALLCONV krcc_end_seq_get(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { krcc_cursor krcursor = *cursor; if (krcursor != NULL) { free(krcursor->keys); free(krcursor); } *cursor = NULL; return 0; } /* Create keyring data for a credential cache. */ static krb5_error_code make_krcc_data(const char *anchor_name, const char *collection_name, const char *subsidiary_name, key_serial_t cache_id, key_serial_t collection_id, krcc_data **data_out) { krb5_error_code ret; krcc_data *data; *data_out = NULL; data = malloc(sizeof(krcc_data)); if (data == NULL) return KRB5_CC_NOMEM; ret = k5_cc_mutex_init(&data->lock); if (ret) { free(data); return ret; } ret = make_subsidiary_residual(anchor_name, collection_name, subsidiary_name, &data->name); if (ret) { k5_cc_mutex_destroy(&data->lock); free(data); return ret; } data->princ_id = 0; data->cache_id = cache_id; data->collection_id = collection_id; data->is_legacy_type = (strcmp(anchor_name, KRCC_LEGACY_ANCHOR) == 0); *data_out = data; return 0; } /* Create a new keyring cache with a unique name. */ static krb5_error_code KRB5_CALLCONV krcc_generate_new(krb5_context context, krb5_ccache *id_out) { krb5_ccache id = NULL; krb5_error_code ret; char *anchor_name = NULL, *collection_name = NULL, *subsidiary_name = NULL; char *new_subsidiary_name = NULL, *new_residual = NULL; krcc_data *data; key_serial_t collection_id; key_serial_t cache_id = 0; *id_out = NULL; /* Determine the collection in which we will create the cache.*/ ret = get_default(context, &anchor_name, &collection_name, &subsidiary_name); if (ret) return ret; if (anchor_name == NULL) { ret = parse_residual(KRCC_DEFAULT_UNIQUE_COLLECTION, &anchor_name, &collection_name, &subsidiary_name); if (ret) return ret; } if (subsidiary_name != NULL) { k5_setmsg(context, KRB5_DCC_CANNOT_CREATE, _("Can't create new subsidiary cache because default cache " "is already a subsidiary")); ret = KRB5_DCC_CANNOT_CREATE; goto cleanup; } /* Allocate memory */ id = malloc(sizeof(struct _krb5_ccache)); if (id == NULL) { ret = ENOMEM; goto cleanup; } id->ops = &krb5_krcc_ops; /* Make a unique keyring within the chosen collection. */ ret = get_collection(anchor_name, collection_name, &collection_id); if (ret) goto cleanup; ret = unique_keyring(context, collection_id, &new_subsidiary_name, &cache_id); if (ret) goto cleanup; ret = make_krcc_data(anchor_name, collection_name, new_subsidiary_name, cache_id, collection_id, &data); if (ret) goto cleanup; id->data = data; krb5_change_cache(); cleanup: free(anchor_name); free(collection_name); free(subsidiary_name); free(new_subsidiary_name); free(new_residual); if (ret) { free(id); return ret; } *id_out = id; return 0; } /* Return an alias to the residual string of the cache. */ static const char *KRB5_CALLCONV krcc_get_name(krb5_context context, krb5_ccache id) { return ((krcc_data *)id->data)->name; } /* Retrieve a copy of the default principal, if the cache is initialized. */ static krb5_error_code KRB5_CALLCONV krcc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *princ_out) { krcc_data *data = id->data; krb5_error_code ret; void *payload = NULL; int psize; *princ_out = NULL; k5_cc_mutex_lock(context, &data->lock); if (!data->cache_id || !data->princ_id) { ret = KRB5_FCC_NOFILE; k5_setmsg(context, ret, _("Credentials cache keyring '%s' not found"), data->name); goto errout; } psize = keyctl_read_alloc(data->princ_id, &payload); if (psize == -1) { DEBUG_PRINT(("Reading principal key %d: %s\n", data->princ_id, strerror(errno))); ret = KRB5_CC_IO; goto errout; } /* Unmarshal the principal using the file ccache version 4 format. */ ret = k5_unmarshal_princ(payload, psize, 4, princ_out); errout: free(payload); k5_cc_mutex_unlock(context, &data->lock); return ret; } /* Search for a credential within the cache keyring. */ static krb5_error_code KRB5_CALLCONV krcc_retrieve(krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds) { return k5_cc_retrieve_cred_default(context, id, whichfields, mcreds, creds); } /* Remove a credential from the cache keyring. */ static krb5_error_code KRB5_CALLCONV krcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *creds) { krb5_error_code ret; krcc_data *data = cache->data; krb5_cc_cursor cursor; krb5_creds c; krcc_cursor krcursor; key_serial_t key; krb5_boolean match; ret = krcc_start_seq_get(context, cache, &cursor); if (ret) return ret; for (;;) { ret = krcc_next_cred(context, cache, &cursor, &c); if (ret) break; match = krb5int_cc_creds_match_request(context, flags, creds, &c); krb5_free_cred_contents(context, &c); if (match) { krcursor = cursor; key = krcursor->keys[krcursor->currkey - 1]; if (keyctl_unlink(key, data->cache_id) == -1) { ret = errno; break; } } } krcc_end_seq_get(context, cache, &cursor); return (ret == KRB5_CC_END) ? 0 : ret; } /* Set flags on the cache. (We don't care about any flags.) */ static krb5_error_code KRB5_CALLCONV krcc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags) { return 0; } /* Get the current operational flags (of which we have none) for the cache. */ static krb5_error_code KRB5_CALLCONV krcc_get_flags(krb5_context context, krb5_ccache id, krb5_flags *flags_out) { *flags_out = 0; return 0; } /* Store a credential in the cache keyring. */ static krb5_error_code KRB5_CALLCONV krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) { krb5_error_code ret; krcc_data *data = id->data; struct k5buf buf = EMPTY_K5BUF; char *keyname = NULL; key_serial_t cred_key; krb5_timestamp now; k5_cc_mutex_lock(context, &data->lock); if (!data->cache_id) { k5_cc_mutex_unlock(context, &data->lock); return KRB5_FCC_NOFILE; } /* Get the service principal name and use it as the key name */ ret = krb5_unparse_name(context, creds->server, &keyname); if (ret) goto errout; /* Serialize credential using the file ccache version 4 format. */ k5_buf_init_dynamic_zap(&buf); k5_marshal_cred(&buf, 4, creds); ret = k5_buf_status(&buf); if (ret) goto errout; /* Add new key (credentials) into keyring */ DEBUG_PRINT(("krcc_store: adding new key '%s' to keyring %d\n", keyname, data->cache_id)); ret = add_cred_key(keyname, buf.data, buf.len, data->cache_id, data->is_legacy_type, &cred_key); if (ret) goto errout; /* Set appropriate timeouts on cache keys. */ ret = krb5_timeofday(context, &now); if (ret) goto errout; if (ts_after(creds->times.endtime, now)) { (void)keyctl_set_timeout(cred_key, ts_interval(now, creds->times.endtime)); } update_keyring_expiration(context, id); errout: k5_buf_free(&buf); krb5_free_unparsed_name(context, keyname); k5_cc_mutex_unlock(context, &data->lock); return ret; } /* Lock the cache handle against other threads. (This does not lock the cache * keyring against other processes.) */ static krb5_error_code KRB5_CALLCONV krcc_lock(krb5_context context, krb5_ccache id) { krcc_data *data = id->data; k5_cc_mutex_lock(context, &data->lock); return 0; } /* Unlock the cache handle. */ static krb5_error_code KRB5_CALLCONV krcc_unlock(krb5_context context, krb5_ccache id) { krcc_data *data = id->data; k5_cc_mutex_unlock(context, &data->lock); return 0; } static krb5_error_code save_principal(krb5_context context, krb5_ccache id, krb5_principal princ) { krcc_data *data = id->data; krb5_error_code ret; struct k5buf buf; key_serial_t newkey; k5_cc_mutex_assert_locked(context, &data->lock); /* Serialize princ using the file ccache version 4 format. */ k5_buf_init_dynamic(&buf); k5_marshal_princ(&buf, 4, princ); if (k5_buf_status(&buf) != 0) return ENOMEM; /* Add new key into keyring */ #ifdef KRCC_DEBUG { krb5_error_code rc; char *princname = NULL; rc = krb5_unparse_name(context, princ, &princname); DEBUG_PRINT(("save_principal: adding new key '%s' " "to keyring %d for principal '%s'\n", KRCC_SPEC_PRINC_KEYNAME, data->cache_id, rc ? "" : princname)); if (rc == 0) krb5_free_unparsed_name(context, princname); } #endif newkey = add_key(KRCC_KEY_TYPE_USER, KRCC_SPEC_PRINC_KEYNAME, buf.data, buf.len, data->cache_id); if (newkey < 0) { ret = errno; DEBUG_PRINT(("Error adding principal key: %s\n", strerror(ret))); } else { data->princ_id = newkey; ret = 0; } k5_buf_free(&buf); return ret; } /* Add a key to the cache keyring containing the given time offsets. */ static krb5_error_code save_time_offsets(krb5_context context, krb5_ccache id, int32_t time_offset, int32_t usec_offset) { krcc_data *data = id->data; key_serial_t newkey; unsigned char payload[8]; k5_cc_mutex_assert_locked(context, &data->lock); /* Prepare the payload. */ store_32_be(time_offset, payload); store_32_be(usec_offset, payload + 4); /* Add new key into keyring. */ newkey = add_key(KRCC_KEY_TYPE_USER, KRCC_TIME_OFFSETS, payload, 8, data->cache_id); if (newkey == -1) return errno; return 0; } /* Retrieve and parse the key in the cache keyring containing time offsets. */ static krb5_error_code get_time_offsets(krb5_context context, krb5_ccache id, int32_t *time_offset, int32_t *usec_offset) { krcc_data *data = id->data; krb5_error_code ret = 0; key_serial_t key; void *payload = NULL; int psize; k5_cc_mutex_lock(context, &data->lock); if (!data->cache_id) { ret = KRB5_FCC_NOFILE; goto errout; } key = keyctl_search(data->cache_id, KRCC_KEY_TYPE_USER, KRCC_TIME_OFFSETS, 0); if (key == -1) { ret = ENOENT; goto errout; } psize = keyctl_read_alloc(key, &payload); if (psize == -1) { DEBUG_PRINT(("Reading time offsets key %d: %s\n", key, strerror(errno))); ret = KRB5_CC_IO; goto errout; } if (psize < 8) { ret = KRB5_CC_END; goto errout; } *time_offset = load_32_be(payload); *usec_offset = load_32_be((char *)payload + 4); errout: free(payload); k5_cc_mutex_unlock(context, &data->lock); return ret; } struct krcc_ptcursor_data { key_serial_t collection_id; char *anchor_name; char *collection_name; char *subsidiary_name; char *primary_name; krb5_boolean first; long num_keys; long next_key; key_serial_t *keys; }; static krb5_error_code KRB5_CALLCONV krcc_ptcursor_new(krb5_context context, krb5_cc_ptcursor *cursor_out) { struct krcc_ptcursor_data *ptd; krb5_cc_ptcursor cursor; krb5_error_code ret; void *keys; long size; *cursor_out = NULL; cursor = k5alloc(sizeof(*cursor), &ret); if (cursor == NULL) return ENOMEM; ptd = k5alloc(sizeof(*ptd), &ret); if (ptd == NULL) goto error; cursor->ops = &krb5_krcc_ops; cursor->data = ptd; ptd->first = TRUE; ret = get_default(context, &ptd->anchor_name, &ptd->collection_name, &ptd->subsidiary_name); if (ret) goto error; /* If there is no default collection, return an empty cursor. */ if (ptd->anchor_name == NULL) { *cursor_out = cursor; return 0; } ret = get_collection(ptd->anchor_name, ptd->collection_name, &ptd->collection_id); if (ret) goto error; if (ptd->subsidiary_name == NULL) { ret = get_primary_name(context, ptd->anchor_name, ptd->collection_name, ptd->collection_id, &ptd->primary_name); if (ret) goto error; size = keyctl_read_alloc(ptd->collection_id, &keys); if (size == -1) { ret = errno; goto error; } ptd->keys = keys; ptd->num_keys = size / sizeof(key_serial_t); } *cursor_out = cursor; return 0; error: krcc_ptcursor_free(context, &cursor); return ret; } static krb5_error_code KRB5_CALLCONV krcc_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor, krb5_ccache *cache_out) { krb5_error_code ret; struct krcc_ptcursor_data *ptd = cursor->data; key_serial_t key, cache_id = 0; const char *first_name, *keytype, *sep, *subsidiary_name; size_t keytypelen; char *description = NULL; *cache_out = NULL; /* No keyring available */ if (ptd->collection_id == 0) return 0; if (ptd->first) { /* Look for the primary cache for a collection cursor, or the * subsidiary cache for a subsidiary cursor. */ ptd->first = FALSE; first_name = (ptd->primary_name != NULL) ? ptd->primary_name : ptd->subsidiary_name; cache_id = keyctl_search(ptd->collection_id, KRCC_KEY_TYPE_KEYRING, first_name, 0); if (cache_id != -1) { return make_cache(context, ptd->collection_id, cache_id, ptd->anchor_name, ptd->collection_name, first_name, cache_out); } } /* A subsidiary cursor yields at most the first cache. */ if (ptd->subsidiary_name != NULL) return 0; keytype = KRCC_KEY_TYPE_KEYRING ";"; keytypelen = strlen(keytype); for (; ptd->next_key < ptd->num_keys; ptd->next_key++) { /* Free any previously retrieved key description. */ free(description); description = NULL; /* * Get the key description, which should have the form: * typename;UID;GID;permissions;description */ key = ptd->keys[ptd->next_key]; if (keyctl_describe_alloc(key, &description) < 0) continue; sep = strrchr(description, ';'); if (sep == NULL) continue; subsidiary_name = sep + 1; /* Skip this key if it isn't a keyring. */ if (strncmp(description, keytype, keytypelen) != 0) continue; /* Don't repeat the primary cache. */ if (strcmp(subsidiary_name, ptd->primary_name) == 0) continue; /* We found a valid key */ ptd->next_key++; ret = make_cache(context, ptd->collection_id, key, ptd->anchor_name, ptd->collection_name, subsidiary_name, cache_out); free(description); return ret; } free(description); return 0; } static krb5_error_code KRB5_CALLCONV krcc_ptcursor_free(krb5_context context, krb5_cc_ptcursor *cursor) { struct krcc_ptcursor_data *ptd = (*cursor)->data; if (ptd != NULL) { free(ptd->anchor_name); free(ptd->collection_name); free(ptd->subsidiary_name); free(ptd->primary_name); free(ptd->keys); free(ptd); } free(*cursor); *cursor = NULL; return 0; } static krb5_error_code KRB5_CALLCONV krcc_switch_to(krb5_context context, krb5_ccache cache) { krcc_data *data = cache->data; krb5_error_code ret; char *anchor_name = NULL, *collection_name = NULL, *subsidiary_name = NULL; key_serial_t collection_id; ret = parse_residual(data->name, &anchor_name, &collection_name, &subsidiary_name); if (ret) goto cleanup; ret = get_collection(anchor_name, collection_name, &collection_id); if (ret) goto cleanup; ret = set_primary_name(context, collection_id, subsidiary_name); cleanup: free(anchor_name); free(collection_name); free(subsidiary_name); return ret; } /* * ccache implementation storing credentials in the Linux keyring facility * The default is to put them at the session keyring level. * If "KEYRING:process:" or "KEYRING:thread:" is specified, then they will * be stored at the process or thread level respectively. */ const krb5_cc_ops krb5_krcc_ops = { 0, "KEYRING", krcc_get_name, krcc_resolve, krcc_generate_new, krcc_initialize, krcc_destroy, krcc_close, krcc_store, krcc_retrieve, krcc_get_principal, krcc_start_seq_get, krcc_next_cred, krcc_end_seq_get, krcc_remove_cred, krcc_set_flags, krcc_get_flags, /* added after 1.4 release */ krcc_ptcursor_new, krcc_ptcursor_next, krcc_ptcursor_free, NULL, /* move */ NULL, /* wasdefault */ krcc_lock, krcc_unlock, krcc_switch_to, }; #else /* !USE_KEYRING_CCACHE */ /* * Export this, but it shouldn't be used. */ const krb5_cc_ops krb5_krcc_ops = { 0, "KEYRING", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* added after 1.4 release */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; #endif /* USE_KEYRING_CCACHE */ krb5-1.22.1/src/lib/krb5/ccache/ccselect_k5identity.c0000664000175000017500000001511115051422640022050 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccselect_k5identity.c - k5identity ccselect module */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "cc-int.h" #include #include #ifndef _WIN32 #include static krb5_error_code k5identity_init(krb5_context context, krb5_ccselect_moddata *data_out, int *priority_out) { *data_out = NULL; *priority_out = KRB5_CCSELECT_PRIORITY_AUTHORITATIVE; return 0; } /* Match data (folded to lowercase if fold_case is set) against pattern. */ static krb5_boolean fnmatch_data(const char *pattern, krb5_data *data, krb5_boolean fold_case) { krb5_error_code ret; char *str, *p; int res; str = k5memdup0(data->data, data->length, &ret); if (str == NULL) return FALSE; if (fold_case) { for (p = str; *p != '\0'; p++) { if (isupper((unsigned char)*p)) *p = tolower((unsigned char)*p); } } res = fnmatch(pattern, str, 0); free(str); return (res == 0); } /* Return true if server satisfies the constraint given by name and value. */ static krb5_boolean check_constraint(krb5_context context, const char *name, const char *value, krb5_principal server) { if (strcmp(name, "realm") == 0) { return fnmatch_data(value, &server->realm, FALSE); } else if (strcmp(name, "service") == 0) { return (server->type == KRB5_NT_SRV_HST && server->length >= 2 && fnmatch_data(value, &server->data[0], FALSE)); } else if (strcmp(name, "host") == 0) { return (server->type == KRB5_NT_SRV_HST && server->length >= 2 && fnmatch_data(value, &server->data[1], TRUE)); } /* Assume unrecognized constraints are critical. */ return FALSE; } /* * If line begins with a valid principal and server matches the constraints * listed afterwards, set *princ_out to the client principal described in line * and return true. Otherwise return false. May destructively affect line. */ static krb5_boolean parse_line(krb5_context context, char *line, krb5_principal server, krb5_principal *princ_out) { const char *whitespace = " \t\r\n"; char *princ, *princ_end, *field, *field_end, *sep; *princ_out = NULL; /* Find the bounds of the principal. */ princ = line + strspn(line, whitespace); if (*princ == '#') return FALSE; princ_end = princ + strcspn(princ, whitespace); if (princ_end == princ) return FALSE; /* Check all constraints. */ field = princ_end + strspn(princ_end, whitespace); while (*field != '\0') { field_end = field + strcspn(field, whitespace); if (*field_end != '\0') *field_end++ = '\0'; sep = strchr(field, '='); if (sep == NULL) /* Malformed line. */ return FALSE; *sep = '\0'; if (!check_constraint(context, field, sep + 1, server)) return FALSE; field = field_end + strspn(field_end, whitespace); } *princ_end = '\0'; return (krb5_parse_name(context, princ, princ_out) == 0); } /* Determine the current user's homedir. Allow HOME to override the result for * non-secure profiles; otherwise, use the euid's homedir from passwd. */ static char * get_homedir(krb5_context context) { const char *homedir = NULL; char pwbuf[BUFSIZ]; struct passwd pwx, *pwd; if (!context->profile_secure) homedir = secure_getenv("HOME"); if (homedir == NULL) { if (k5_getpwuid_r(geteuid(), &pwx, pwbuf, sizeof(pwbuf), &pwd) != 0) return NULL; homedir = pwd->pw_dir; } return strdup(homedir); } static krb5_error_code k5identity_choose(krb5_context context, krb5_ccselect_moddata data, krb5_principal server, krb5_ccache *cache_out, krb5_principal *princ_out) { krb5_error_code ret; krb5_principal princ = NULL; char *filename, *homedir; FILE *fp; char buf[256]; *cache_out = NULL; *princ_out = NULL; /* Open the .k5identity file. */ homedir = get_homedir(context); if (homedir == NULL) return KRB5_PLUGIN_NO_HANDLE; ret = k5_path_join(homedir, ".k5identity", &filename); free(homedir); if (ret) return ret; fp = fopen(filename, "r"); free(filename); if (fp == NULL) return KRB5_PLUGIN_NO_HANDLE; /* Look for a line with constraints matched by server. */ while (fgets(buf, sizeof(buf), fp) != NULL) { if (parse_line(context, buf, server, &princ)) break; } fclose(fp); if (princ == NULL) return KRB5_PLUGIN_NO_HANDLE; /* Look for a ccache with the appropriate client principal. If we don't * find out, set *princ_out to indicate the desired client principal. */ ret = krb5_cc_cache_match(context, princ, cache_out); if (ret == 0 || ret == KRB5_CC_NOTFOUND) *princ_out = princ; else krb5_free_principal(context, princ); return ret; } krb5_error_code ccselect_k5identity_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable) { krb5_ccselect_vtable vt; if (maj_ver != 1) return KRB5_PLUGIN_VER_NOTSUPP; vt = (krb5_ccselect_vtable)vtable; vt->name = "k5identity"; vt->init = k5identity_init; vt->choose = k5identity_choose; return 0; } #endif /* not _WIN32 */ krb5-1.22.1/src/lib/krb5/ccache/cc_dir.c0000664000175000017500000005117615051422640017350 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cc_dir.c - Directory-based credential cache collection */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * This credential cache type represents a set of file-based caches with a * switchable primary cache. An alternate form of the type represents a * subsidiary file cache within the directory. * * A cache name of the form DIR:dirname identifies a directory containing the * cache set. Resolving a name of this form results in dirname's primary * cache. If a context's default cache is of this form, the global cache * collection will contain dirname's cache set, and new unique caches of type * DIR will be created within dirname. * * A cache name of the form DIR::filepath represents a single cache within the * directory. Switching to a ccache of this type causes the directory's * primary cache to be set to the named cache. * * Within the directory, cache names begin with 'tkt'. The file "primary" * contains a single line naming the primary cache. The directory must already * exist when the DIR ccache is resolved, but the primary file will be created * automatically if it does not exist. */ #include "k5-int.h" #include "cc-int.h" #if HAVE_UNISTD_H #include #endif #if HAVE_SYS_STAT_H #include #endif /* This is Unix-only for now. To work on Windows, we will need opendir/readdir * replacements and possibly more flexible newline handling. */ #ifndef _WIN32 #include extern const krb5_cc_ops krb5_dcc_ops; extern const krb5_cc_ops krb5_fcc_ops; /* Fields are not modified after creation, so no lock is necessary. */ typedef struct dcc_data_st { char *residual; /* dirname or :filename */ krb5_ccache fcc; /* File cache for actual cache ops */ } dcc_data; static inline krb5_boolean filename_is_cache(const char *filename) { return (strncmp(filename, "tkt", 3) == 0); } /* Compose the pathname of the primary file within a cache directory. */ static inline krb5_error_code primary_pathname(const char *dirname, char **path_out) { return k5_path_join(dirname, "primary", path_out); } /* Compose a residual string for a subsidiary path with the specified directory * name and filename. */ static krb5_error_code subsidiary_residual(const char *dirname, const char *filename, char **out) { krb5_error_code ret; char *path, *residual; *out = NULL; ret = k5_path_join(dirname, filename, &path); if (ret) return ret; ret = asprintf(&residual, ":%s", path); free(path); if (ret < 0) return ENOMEM; *out = residual; return 0; } static inline krb5_error_code split_path(krb5_context context, const char *path, char **dirname_out, char **filename_out) { krb5_error_code ret; char *dirname, *filename; *dirname_out = NULL; *filename_out = NULL; ret = k5_path_split(path, &dirname, &filename); if (ret) return ret; if (*dirname == '\0') { ret = KRB5_CC_BADNAME; k5_setmsg(context, ret, _("Subsidiary cache path %s has no parent directory"), path); goto error; } if (!filename_is_cache(filename)) { ret = KRB5_CC_BADNAME; k5_setmsg(context, ret, _("Subsidiary cache path %s filename does not begin with " "\"tkt\""), path); goto error; } *dirname_out = dirname; *filename_out = filename; return 0; error: free(dirname); free(filename); return ret; } /* Read the primary file and compose the residual string for the primary * subsidiary cache file. */ static krb5_error_code read_primary_file(krb5_context context, const char *primary_path, const char *dirname, char **residual_out) { FILE *fp; char buf[64], *ret; size_t len; *residual_out = NULL; /* Open the file and read its first line. */ fp = fopen(primary_path, "r"); if (fp == NULL) return ENOENT; ret = fgets(buf, sizeof(buf), fp); fclose(fp); if (ret == NULL) return KRB5_CC_IO; len = strlen(buf); /* Check if line is too long, doesn't look like a subsidiary cache * filename, or isn't a single-component filename. */ if (buf[len - 1] != '\n' || !filename_is_cache(buf) || strchr(buf, '/') || strchr(buf, '\\')) { k5_setmsg(context, KRB5_CC_FORMAT, _("%s contains invalid filename"), primary_path); return KRB5_CC_FORMAT; } buf[len - 1] = '\0'; return subsidiary_residual(dirname, buf, residual_out); } /* Create or update the primary file with a line containing contents. */ static krb5_error_code write_primary_file(const char *primary_path, const char *contents) { krb5_error_code ret = KRB5_CC_IO; char *newpath = NULL; FILE *fp = NULL; int fd = -1, status; if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0) return ENOMEM; fd = mkstemp(newpath); if (fd < 0) goto cleanup; #ifdef HAVE_CHMOD chmod(newpath, S_IRUSR | S_IWUSR); #endif fp = fdopen(fd, "w"); if (fp == NULL) goto cleanup; fd = -1; if (fprintf(fp, "%s\n", contents) < 0) goto cleanup; status = fclose(fp); fp = NULL; if (status == EOF) goto cleanup; fp = NULL; if (rename(newpath, primary_path) != 0) goto cleanup; ret = 0; cleanup: if (fd >= 0) close(fd); if (fp != NULL) fclose(fp); free(newpath); return ret; } /* Verify or create a cache directory path. */ static krb5_error_code verify_dir(krb5_context context, const char *dirname) { struct stat st; if (stat(dirname, &st) < 0) { if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0) return 0; k5_setmsg(context, KRB5_FCC_NOFILE, _("Credential cache directory %s does not exist"), dirname); return KRB5_FCC_NOFILE; } if (!S_ISDIR(st.st_mode)) { k5_setmsg(context, KRB5_CC_FORMAT, _("Credential cache directory %s exists but is not a " "directory"), dirname); return KRB5_CC_FORMAT; } return 0; } /* * If the default ccache name for context is a directory collection, set * *dirname_out to the directory name for that collection. Otherwise set * *dirname_out to NULL. */ static krb5_error_code get_context_default_dir(krb5_context context, char **dirname_out) { const char *defname; char *dirname; *dirname_out = NULL; defname = krb5_cc_default_name(context); if (defname == NULL) return 0; if (strncmp(defname, "DIR:", 4) != 0 || defname[4] == ':' || defname[4] == '\0') return 0; dirname = strdup(defname + 4); if (dirname == NULL) return ENOMEM; *dirname_out = dirname; return 0; } /* * If the default ccache name for context is a subsidiary file in a directory * collection, set *subsidiary_out to the residual value. Otherwise set * *subsidiary_out to NULL. */ static krb5_error_code get_context_subsidiary_file(krb5_context context, char **subsidiary_out) { const char *defname; char *residual; *subsidiary_out = NULL; defname = krb5_cc_default_name(context); if (defname == NULL || strncmp(defname, "DIR::", 5) != 0) return 0; residual = strdup(defname + 4); if (residual == NULL) return ENOMEM; *subsidiary_out = residual; return 0; } static const char * KRB5_CALLCONV dcc_get_name(krb5_context context, krb5_ccache cache) { dcc_data *data = cache->data; return data->residual; } /* Construct a cache object given a residual string and file ccache. Take * ownership of fcc on success. */ static krb5_error_code make_cache(const char *residual, krb5_ccache fcc, krb5_ccache *cache_out) { krb5_ccache cache = NULL; dcc_data *data = NULL; char *residual_copy = NULL; cache = malloc(sizeof(*cache)); if (cache == NULL) goto oom; data = malloc(sizeof(*data)); if (data == NULL) goto oom; residual_copy = strdup(residual); if (residual_copy == NULL) goto oom; data->residual = residual_copy; data->fcc = fcc; cache->ops = &krb5_dcc_ops; cache->data = data; cache->magic = KV5M_CCACHE; *cache_out = cache; return 0; oom: free(cache); free(data); free(residual_copy); return ENOMEM; } static krb5_error_code KRB5_CALLCONV dcc_resolve(krb5_context context, krb5_ccache *cache_out, const char *residual) { krb5_error_code ret; krb5_ccache fcc; char *primary_path = NULL, *sresidual = NULL, *dirname, *filename; *cache_out = NULL; if (*residual == ':') { /* This is a subsidiary cache within the directory. */ ret = split_path(context, residual + 1, &dirname, &filename); if (ret) return ret; ret = verify_dir(context, dirname); free(dirname); free(filename); if (ret) return ret; } else { /* This is the directory itself; resolve to the primary cache. */ ret = verify_dir(context, residual); if (ret) return ret; ret = primary_pathname(residual, &primary_path); if (ret) goto cleanup; ret = read_primary_file(context, primary_path, residual, &sresidual); if (ret == ENOENT) { /* Create an initial primary file. */ ret = write_primary_file(primary_path, "tkt"); if (ret) goto cleanup; ret = subsidiary_residual(residual, "tkt", &sresidual); } if (ret) goto cleanup; residual = sresidual; } ret = krb5_fcc_ops.resolve(context, &fcc, residual + 1); if (ret) goto cleanup; ret = make_cache(residual, fcc, cache_out); if (ret) krb5_fcc_ops.close(context, fcc); cleanup: free(primary_path); free(sresidual); return ret; } static krb5_error_code KRB5_CALLCONV dcc_gen_new(krb5_context context, krb5_ccache *cache_out) { krb5_error_code ret; char *dirname = NULL, *template = NULL, *residual = NULL; krb5_ccache fcc = NULL; *cache_out = NULL; ret = get_context_default_dir(context, &dirname); if (ret) return ret; if (dirname == NULL) { k5_setmsg(context, KRB5_DCC_CANNOT_CREATE, _("Can't create new subsidiary cache because default cache " "is not a directory collection")); return KRB5_DCC_CANNOT_CREATE; } ret = verify_dir(context, dirname); if (ret) goto cleanup; ret = k5_path_join(dirname, "tktXXXXXX", &template); if (ret) goto cleanup; ret = krb5int_fcc_new_unique(context, template, &fcc); if (ret) goto cleanup; if (asprintf(&residual, ":%s", template) < 0) { ret = ENOMEM; goto cleanup; } ret = make_cache(residual, fcc, cache_out); if (ret) goto cleanup; fcc = NULL; cleanup: if (fcc != NULL) krb5_fcc_ops.destroy(context, fcc); free(dirname); free(template); free(residual); return ret; } static krb5_error_code KRB5_CALLCONV dcc_init(krb5_context context, krb5_ccache cache, krb5_principal princ) { dcc_data *data = cache->data; return krb5_fcc_ops.init(context, data->fcc, princ); } static krb5_error_code KRB5_CALLCONV dcc_destroy(krb5_context context, krb5_ccache cache) { dcc_data *data = cache->data; krb5_error_code ret; ret = krb5_fcc_ops.destroy(context, data->fcc); free(data->residual); free(data); free(cache); return ret; } static krb5_error_code KRB5_CALLCONV dcc_close(krb5_context context, krb5_ccache cache) { dcc_data *data = cache->data; krb5_error_code ret; ret = krb5_fcc_ops.close(context, data->fcc); free(data->residual); free(data); free(cache); return ret; } static krb5_error_code KRB5_CALLCONV dcc_store(krb5_context context, krb5_ccache cache, krb5_creds *creds) { dcc_data *data = cache->data; return krb5_fcc_ops.store(context, data->fcc, creds); } static krb5_error_code KRB5_CALLCONV dcc_retrieve(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *mcreds, krb5_creds *creds) { dcc_data *data = cache->data; return krb5_fcc_ops.retrieve(context, data->fcc, flags, mcreds, creds); } static krb5_error_code KRB5_CALLCONV dcc_get_princ(krb5_context context, krb5_ccache cache, krb5_principal *princ_out) { dcc_data *data = cache->data; return krb5_fcc_ops.get_princ(context, data->fcc, princ_out); } static krb5_error_code KRB5_CALLCONV dcc_get_first(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor) { dcc_data *data = cache->data; return krb5_fcc_ops.get_first(context, data->fcc, cursor); } static krb5_error_code KRB5_CALLCONV dcc_get_next(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, krb5_creds *creds) { dcc_data *data = cache->data; return krb5_fcc_ops.get_next(context, data->fcc, cursor, creds); } static krb5_error_code KRB5_CALLCONV dcc_end_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor) { dcc_data *data = cache->data; return krb5_fcc_ops.end_get(context, data->fcc, cursor); } static krb5_error_code KRB5_CALLCONV dcc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *creds) { dcc_data *data = cache->data; return krb5_fcc_ops.remove_cred(context, data->fcc, flags, creds); } static krb5_error_code KRB5_CALLCONV dcc_set_flags(krb5_context context, krb5_ccache cache, krb5_flags flags) { dcc_data *data = cache->data; return krb5_fcc_ops.set_flags(context, data->fcc, flags); } static krb5_error_code KRB5_CALLCONV dcc_get_flags(krb5_context context, krb5_ccache cache, krb5_flags *flags_out) { dcc_data *data = cache->data; return krb5_fcc_ops.get_flags(context, data->fcc, flags_out); } struct dcc_ptcursor_data { char *primary; char *dirname; DIR *dir; krb5_boolean first; }; /* Construct a cursor, taking ownership of dirname, primary, and dir on * success. */ static krb5_error_code make_cursor(char *dirname, char *primary, DIR *dir, krb5_cc_ptcursor *cursor_out) { krb5_cc_ptcursor cursor; struct dcc_ptcursor_data *data; *cursor_out = NULL; data = malloc(sizeof(*data)); if (data == NULL) return ENOMEM; cursor = malloc(sizeof(*cursor)); if (cursor == NULL) { free(data); return ENOMEM; } data->dirname = dirname; data->primary = primary; data->dir = dir; data->first = TRUE; cursor->ops = &krb5_dcc_ops; cursor->data = data; *cursor_out = cursor; return 0; } static krb5_error_code KRB5_CALLCONV dcc_ptcursor_new(krb5_context context, krb5_cc_ptcursor *cursor_out) { krb5_error_code ret; char *dirname = NULL, *primary_path = NULL, *primary = NULL; DIR *dir = NULL; *cursor_out = NULL; /* If the default cache is a subsidiary file, make a cursor with the * specified file as the primary but with no directory collection. */ ret = get_context_subsidiary_file(context, &primary); if (ret) goto cleanup; if (primary != NULL) { ret = make_cursor(NULL, primary, NULL, cursor_out); if (ret) free(primary); return ret; } /* Open the directory for the context's default cache. */ ret = get_context_default_dir(context, &dirname); if (ret || dirname == NULL) goto cleanup; dir = opendir(dirname); if (dir == NULL) goto cleanup; /* Fetch the primary cache name if possible. */ ret = primary_pathname(dirname, &primary_path); if (ret) goto cleanup; ret = read_primary_file(context, primary_path, dirname, &primary); if (ret) krb5_clear_error_message(context); ret = make_cursor(dirname, primary, dir, cursor_out); if (ret) goto cleanup; dirname = primary = NULL; dir = NULL; cleanup: free(dirname); free(primary_path); free(primary); if (dir) closedir(dir); /* Return an empty cursor if we fail for any reason. */ if (*cursor_out == NULL) return make_cursor(NULL, NULL, NULL, cursor_out); return 0; } static krb5_error_code KRB5_CALLCONV dcc_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor, krb5_ccache *cache_out) { struct dcc_ptcursor_data *data = cursor->data; struct dirent *ent; char *residual; krb5_error_code ret; struct stat sb; *cache_out = NULL; /* Return the primary or specified subsidiary cache if we haven't yet. */ if (data->first) { data->first = FALSE; if (data->primary != NULL && stat(data->primary + 1, &sb) == 0) return dcc_resolve(context, cache_out, data->primary); } if (data->dir == NULL) /* No directory collection */ return 0; /* Look for the next filename of the correct form, without repeating the * primary cache. */ while ((ent = readdir(data->dir)) != NULL) { if (!filename_is_cache(ent->d_name)) continue; ret = subsidiary_residual(data->dirname, ent->d_name, &residual); if (ret) return ret; if (data->primary != NULL && strcmp(residual, data->primary) == 0) { free(residual); continue; } ret = dcc_resolve(context, cache_out, residual); free(residual); return ret; } /* We exhausted the directory without finding a cache to yield. */ closedir(data->dir); data->dir = NULL; return 0; } static krb5_error_code KRB5_CALLCONV dcc_ptcursor_free(krb5_context context, krb5_cc_ptcursor *cursor) { struct dcc_ptcursor_data *data = (*cursor)->data; if (data->dir) closedir(data->dir); free(data->dirname); free(data->primary); free(data); free(*cursor); *cursor = NULL; return 0; } static krb5_error_code KRB5_CALLCONV dcc_replace(krb5_context context, krb5_ccache cache, krb5_principal princ, krb5_creds **creds) { dcc_data *data = cache->data; return krb5_fcc_ops.replace(context, data->fcc, princ, creds); } static krb5_error_code KRB5_CALLCONV dcc_lock(krb5_context context, krb5_ccache cache) { dcc_data *data = cache->data; return krb5_fcc_ops.lock(context, data->fcc); } static krb5_error_code KRB5_CALLCONV dcc_unlock(krb5_context context, krb5_ccache cache) { dcc_data *data = cache->data; return krb5_fcc_ops.unlock(context, data->fcc); } static krb5_error_code KRB5_CALLCONV dcc_switch_to(krb5_context context, krb5_ccache cache) { dcc_data *data = cache->data; char *primary_path = NULL, *dirname = NULL, *filename = NULL; krb5_error_code ret; ret = split_path(context, data->residual + 1, &dirname, &filename); if (ret) return ret; ret = primary_pathname(dirname, &primary_path); if (ret) goto cleanup; ret = write_primary_file(primary_path, filename); cleanup: free(primary_path); free(dirname); free(filename); return ret; } const krb5_cc_ops krb5_dcc_ops = { 0, "DIR", dcc_get_name, dcc_resolve, dcc_gen_new, dcc_init, dcc_destroy, dcc_close, dcc_store, dcc_retrieve, dcc_get_princ, dcc_get_first, dcc_get_next, dcc_end_get, dcc_remove_cred, dcc_set_flags, dcc_get_flags, dcc_ptcursor_new, dcc_ptcursor_next, dcc_ptcursor_free, dcc_replace, NULL, /* wasdefault */ dcc_lock, dcc_unlock, dcc_switch_to, }; #endif /* not _WIN32 */ krb5-1.22.1/src/lib/krb5/ccache/cc_kcm.c0000664000175000017500000011302315051422640017332 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/cc_kcm.c - KCM cache type (client side) */ /* * Copyright (C) 2014 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This cache type contacts a daemon for each cache operation, using Heimdal's * KCM protocol. On macOS, the preferred transport is Mach RPC; on other * Unix-like platforms or if the daemon is not available via RPC, Unix domain * sockets are used instead. */ #ifndef _WIN32 #include "k5-int.h" #include "k5-input.h" #include "cc-int.h" #include "kcm.h" #include "../os/os-proto.h" #include #include #ifdef __APPLE__ #include #include #include "kcmrpc.h" #endif #define MAX_REPLY_SIZE (10 * 1024 * 1024) const krb5_cc_ops krb5_kcm_ops; struct uuid_list { unsigned char *uuidbytes; /* all of the uuids concatenated together */ size_t count; size_t pos; }; struct cred_list { krb5_creds *creds; size_t count; size_t pos; }; struct kcm_cursor { struct uuid_list *uuids; struct cred_list *creds; }; struct kcmio { SOCKET fd; #ifdef __APPLE__ mach_port_t mport; #endif }; /* This structure bundles together a KCM request and reply, to minimize how * much we have to declare and clean up in each method. */ struct kcmreq { struct k5buf reqbuf; struct k5input reply; void *reply_mem; }; #define EMPTY_KCMREQ { EMPTY_K5BUF } struct kcm_cache_data { char *residual; /* immutable; may be accessed without lock */ k5_cc_mutex lock; /* protects io */ struct kcmio *io; }; struct kcm_ptcursor { char *residual; /* primary or singleton subsidiary */ struct uuid_list *uuids; /* NULL for singleton subsidiary */ struct kcmio *io; krb5_boolean first; }; /* Map EINVAL or KRB5_CC_FORMAT to KRB5_KCM_MALFORMED_REPLY; pass through all * other codes. */ static inline krb5_error_code map_invalid(krb5_error_code code) { return (code == EINVAL || code == KRB5_CC_FORMAT) ? KRB5_KCM_MALFORMED_REPLY : code; } /* * Map an MIT krb5 KRB5_TC flag word to the equivalent Heimdal flag word. Note * that there is no MIT krb5 equivalent for Heimdal's KRB5_TC_DONT_MATCH_REALM * (which is like KRB5_TC_MATCH_SRV_NAMEONLY but also applies to the client * principal) and no Heimdal equivalent for MIT krb5's KRB5_TC_SUPPORTED_KTYPES * (which matches against enctypes from the krb5_context rather than the * matching cred). */ static inline krb5_flags map_tcflags(krb5_flags mitflags) { krb5_flags heimflags = 0; if (mitflags & KRB5_TC_MATCH_TIMES) heimflags |= KCM_TC_MATCH_TIMES; if (mitflags & KRB5_TC_MATCH_IS_SKEY) heimflags |= KCM_TC_MATCH_IS_SKEY; if (mitflags & KRB5_TC_MATCH_FLAGS) heimflags |= KCM_TC_MATCH_FLAGS; if (mitflags & KRB5_TC_MATCH_TIMES_EXACT) heimflags |= KCM_TC_MATCH_TIMES_EXACT; if (mitflags & KRB5_TC_MATCH_FLAGS_EXACT) heimflags |= KCM_TC_MATCH_FLAGS_EXACT; if (mitflags & KRB5_TC_MATCH_AUTHDATA) heimflags |= KCM_TC_MATCH_AUTHDATA; if (mitflags & KRB5_TC_MATCH_SRV_NAMEONLY) heimflags |= KCM_TC_MATCH_SRV_NAMEONLY; if (mitflags & KRB5_TC_MATCH_2ND_TKT) heimflags |= KCM_TC_MATCH_2ND_TKT; if (mitflags & KRB5_TC_MATCH_KTYPE) heimflags |= KCM_TC_MATCH_KEYTYPE; return heimflags; } /* * Return true if code could indicate an unsupported operation. Heimdal's KCM * returns KRB5_FCC_INTERNAL. sssd's KCM daemon (as of sssd 2.4) returns * KRB5_CC_NO_SUPP if it recognizes the operation but does not implement it, * and KRB5_CC_IO if it doesn't recognize the operation (which is unfortunate * since it could also indicate a communication failure). */ static krb5_boolean unsupported_op_error(krb5_error_code code) { return code == KRB5_FCC_INTERNAL || code == KRB5_CC_IO || code == KRB5_CC_NOSUPP; } /* Begin a request for the given opcode. If cache is non-null, supply the * cache name as a request parameter. */ static void kcmreq_init(struct kcmreq *req, kcm_opcode opcode, krb5_ccache cache) { unsigned char bytes[4]; const char *name; memset(req, 0, sizeof(*req)); bytes[0] = KCM_PROTOCOL_VERSION_MAJOR; bytes[1] = KCM_PROTOCOL_VERSION_MINOR; store_16_be(opcode, bytes + 2); k5_buf_init_dynamic(&req->reqbuf); k5_buf_add_len(&req->reqbuf, bytes, 4); if (cache != NULL) { name = ((struct kcm_cache_data *)cache->data)->residual; k5_buf_add_len(&req->reqbuf, name, strlen(name) + 1); } } #ifdef __APPLE__ /* The maximum length of an in-band request or reply as defined by the RPC * protocol. */ #define MAX_INBAND_SIZE 2048 /* Connect or reconnect to the KCM daemon via Mach RPC, if possible. */ static krb5_error_code kcmio_mach_connect(krb5_context context, struct kcmio *io) { krb5_error_code ret; kern_return_t st; mach_port_t mport; char *service; ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_KCM_MACH_SERVICE, NULL, DEFAULT_KCM_MACH_SERVICE, &service); if (ret) return ret; if (strcmp(service, "-") == 0) { profile_release_string(service); return KRB5_KCM_NO_SERVER; } st = bootstrap_look_up(bootstrap_port, service, &mport); profile_release_string(service); if (st) return KRB5_KCM_NO_SERVER; if (io->mport != MACH_PORT_NULL) mach_port_deallocate(mach_task_self(), io->mport); io->mport = mport; return 0; } /* Invoke the Mach RPC to get a reply from the KCM daemon. */ static krb5_error_code kcmio_mach_call(krb5_context context, struct kcmio *io, void *data, size_t len, void **reply_out, size_t *len_out) { krb5_error_code ret; size_t inband_req_len = 0, outband_req_len = 0, reply_len; char *inband_req = NULL, *outband_req = NULL, *outband_reply, *copy; char inband_reply[MAX_INBAND_SIZE]; mach_msg_type_number_t inband_reply_len, outband_reply_len; const void *reply; kern_return_t st; int code; *reply_out = NULL; *len_out = 0; /* Use the in-band or out-of-band request buffer depending on len. */ if (len <= MAX_INBAND_SIZE) { inband_req = data; inband_req_len = len; } else { outband_req = data; outband_req_len = len; } st = k5_kcmrpc_call(io->mport, inband_req, inband_req_len, outband_req, outband_req_len, &code, inband_reply, &inband_reply_len, &outband_reply, &outband_reply_len); if (st == MACH_SEND_INVALID_DEST) { /* Get a new port and try again. */ st = kcmio_mach_connect(context, io); if (st) return KRB5_KCM_RPC_ERROR; st = k5_kcmrpc_call(io->mport, inband_req, inband_req_len, outband_req, outband_req_len, &code, inband_reply, &inband_reply_len, &outband_reply, &outband_reply_len); } if (st) return KRB5_KCM_RPC_ERROR; if (code) { ret = code; goto cleanup; } /* The reply could be in the in-band or out-of-band reply buffer. */ reply = outband_reply_len ? outband_reply : inband_reply; reply_len = outband_reply_len ? outband_reply_len : inband_reply_len; copy = k5memdup(reply, reply_len, &ret); if (copy == NULL) goto cleanup; *reply_out = copy; *len_out = reply_len; cleanup: if (outband_reply_len) { vm_deallocate(mach_task_self(), (vm_address_t)outband_reply, outband_reply_len); } return ret; } /* Release any Mach RPC state within io. */ static void kcmio_mach_close(struct kcmio *io) { if (io->mport != MACH_PORT_NULL) mach_port_deallocate(mach_task_self(), io->mport); } #else /* __APPLE__ */ #define kcmio_mach_connect(context, io) EINVAL #define kcmio_mach_call(context, io, data, len, reply_out, len_out) EINVAL #define kcmio_mach_close(io) #endif /* Connect to the KCM daemon via a Unix domain socket. */ static krb5_error_code kcmio_unix_socket_connect(krb5_context context, struct kcmio *io) { krb5_error_code ret; SOCKET fd = INVALID_SOCKET; struct sockaddr_un addr; char *path = NULL; ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, KRB5_CONF_KCM_SOCKET, NULL, DEFAULT_KCM_SOCKET_PATH, &path); if (ret) goto cleanup; if (strcmp(path, "-") == 0) { ret = KRB5_KCM_NO_SERVER; goto cleanup; } fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == INVALID_SOCKET) { ret = SOCKET_ERRNO; goto cleanup; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); if (SOCKET_CONNECT(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { ret = (SOCKET_ERRNO == ENOENT) ? KRB5_KCM_NO_SERVER : SOCKET_ERRNO; goto cleanup; } io->fd = fd; fd = INVALID_SOCKET; cleanup: if (fd != INVALID_SOCKET) closesocket(fd); profile_release_string(path); return ret; } /* Write a KCM request: 4-byte big-endian length, then the marshalled * request. */ static krb5_error_code kcmio_unix_socket_write(krb5_context context, struct kcmio *io, void *request, size_t len) { char lenbytes[4]; sg_buf sg[2]; int ret; krb5_boolean reconnected = FALSE; SG_SET(&sg[0], lenbytes, sizeof(lenbytes)); SG_SET(&sg[1], request, len); store_32_be(len, lenbytes); for (;;) { ret = krb5int_net_writev(context, io->fd, sg, 2); if (ret >= 0) return 0; ret = errno; if (ret != EPIPE || reconnected) return ret; /* * Try once to reconnect on an EPIPE, in case the server has an idle * timeout (like sssd does) and we went too long between ccache * operations. Reconnecting might also help if the server was * restarted for an upgrade--although the server must be designed to * always listen for connections on the socket during upgrades, or a * single reconnect attempt won't be robust. */ close(io->fd); ret = kcmio_unix_socket_connect(context, io); if (ret) return ret; reconnected = TRUE; } } /* Read a KCM reply: 4-byte big-endian length, 4-byte big-endian status code, * then the marshalled reply. */ static krb5_error_code kcmio_unix_socket_read(krb5_context context, struct kcmio *io, void **reply_out, size_t *len_out) { krb5_error_code code; char lenbytes[4], codebytes[4], *reply; size_t len; int st; *reply_out = NULL; *len_out = 0; st = krb5_net_read(context, io->fd, lenbytes, 4); if (st != 4) return (st == -1) ? errno : KRB5_CC_IO; len = load_32_be(lenbytes); if (len > MAX_REPLY_SIZE) return KRB5_KCM_REPLY_TOO_BIG; st = krb5_net_read(context, io->fd, codebytes, 4); if (st != 4) return (st == -1) ? errno : KRB5_CC_IO; code = load_32_be(codebytes); if (code != 0) return code; reply = malloc(len); if (reply == NULL) return ENOMEM; st = krb5_net_read(context, io->fd, reply, len); if (st == -1 || (size_t)st != len) { free(reply); return (st < 0) ? errno : KRB5_CC_IO; } *reply_out = reply; *len_out = len; return 0; } static krb5_error_code kcmio_connect(krb5_context context, struct kcmio **io_out) { krb5_error_code ret; struct kcmio *io; *io_out = NULL; io = calloc(1, sizeof(*io)); if (io == NULL) return ENOMEM; io->fd = INVALID_SOCKET; /* Try Mach RPC (macOS only), then fall back to Unix domain sockets */ ret = kcmio_mach_connect(context, io); if (ret) ret = kcmio_unix_socket_connect(context, io); if (ret) { free(io); return ret; } *io_out = io; return 0; } /* Check req->reqbuf for an error condition and return it. Otherwise, send the * request to the KCM daemon and get a response. */ static krb5_error_code kcmio_call(krb5_context context, struct kcmio *io, struct kcmreq *req) { krb5_error_code ret; size_t reply_len = 0; if (k5_buf_status(&req->reqbuf) != 0) return ENOMEM; if (io->fd != INVALID_SOCKET) { ret = kcmio_unix_socket_write(context, io, req->reqbuf.data, req->reqbuf.len); if (ret) return ret; ret = kcmio_unix_socket_read(context, io, &req->reply_mem, &reply_len); if (ret) return ret; } else { /* We must be using Mach RPC. */ ret = kcmio_mach_call(context, io, req->reqbuf.data, req->reqbuf.len, &req->reply_mem, &reply_len); if (ret) return ret; } /* Read the status code from the marshalled reply. */ k5_input_init(&req->reply, req->reply_mem, reply_len); ret = k5_input_get_uint32_be(&req->reply); return req->reply.status ? KRB5_KCM_MALFORMED_REPLY : ret; } static void kcmio_close(struct kcmio *io) { if (io != NULL) { kcmio_mach_close(io); if (io->fd != INVALID_SOCKET) closesocket(io->fd); free(io); } } /* Fetch a zero-terminated name string from req->reply. The returned pointer * is an alias and must not be freed by the caller. */ static krb5_error_code kcmreq_get_name(struct kcmreq *req, const char **name_out) { const unsigned char *end; struct k5input *in = &req->reply; *name_out = NULL; end = memchr(in->ptr, '\0', in->len); if (end == NULL) return KRB5_KCM_MALFORMED_REPLY; *name_out = (const char *)in->ptr; (void)k5_input_get_bytes(in, end + 1 - in->ptr); return 0; } /* Fetch a UUID list from req->reply. UUID lists are not delimited, so we * consume the rest of the input. */ static krb5_error_code kcmreq_get_uuid_list(struct kcmreq *req, struct uuid_list **uuids_out) { struct uuid_list *uuids; *uuids_out = NULL; if (req->reply.len % KCM_UUID_LEN != 0) return KRB5_KCM_MALFORMED_REPLY; uuids = malloc(sizeof(*uuids)); if (uuids == NULL) return ENOMEM; uuids->count = req->reply.len / KCM_UUID_LEN; uuids->pos = 0; if (req->reply.len > 0) { uuids->uuidbytes = malloc(req->reply.len); if (uuids->uuidbytes == NULL) { free(uuids); return ENOMEM; } memcpy(uuids->uuidbytes, req->reply.ptr, req->reply.len); (void)k5_input_get_bytes(&req->reply, req->reply.len); } else { uuids->uuidbytes = NULL; } *uuids_out = uuids; return 0; } static void free_uuid_list(struct uuid_list *uuids) { if (uuids != NULL) free(uuids->uuidbytes); free(uuids); } static void free_cred_list(struct cred_list *list) { size_t i; if (list == NULL) return; /* Creds are transferred to the caller as list->pos is incremented, so we * can start freeing there. */ for (i = list->pos; i < list->count; i++) krb5_free_cred_contents(NULL, &list->creds[i]); free(list->creds); free(list); } /* Fetch a cred list from req->reply. */ static krb5_error_code kcmreq_get_cred_list(struct kcmreq *req, struct cred_list **creds_out) { struct cred_list *list; const unsigned char *data; krb5_error_code ret = 0; size_t count, len, i; *creds_out = NULL; /* Check a rough bound on the count to prevent very large allocations. */ count = k5_input_get_uint32_be(&req->reply); if (count > req->reply.len / 4) return KRB5_KCM_MALFORMED_REPLY; list = malloc(sizeof(*list)); if (list == NULL) return ENOMEM; list->creds = NULL; list->count = count; list->pos = 0; list->creds = k5calloc(count, sizeof(*list->creds), &ret); if (list->creds == NULL) { free(list); return ret; } for (i = 0; i < count; i++) { len = k5_input_get_uint32_be(&req->reply); data = k5_input_get_bytes(&req->reply, len); if (data == NULL) break; ret = k5_unmarshal_cred(data, len, 4, &list->creds[i]); if (ret) break; } if (i < count) { free_cred_list(list); return (ret == ENOMEM) ? ENOMEM : KRB5_KCM_MALFORMED_REPLY; } *creds_out = list; return 0; } static void kcmreq_free(struct kcmreq *req) { k5_buf_free(&req->reqbuf); free(req->reply_mem); } /* Create a krb5_ccache structure. If io is NULL, make a new connection for * the cache. Otherwise, always take ownership of io. */ static krb5_error_code make_cache(krb5_context context, const char *residual, struct kcmio *io, krb5_ccache *cache_out) { krb5_error_code ret; krb5_ccache cache = NULL; struct kcm_cache_data *data = NULL; char *residual_copy = NULL; *cache_out = NULL; if (io == NULL) { ret = kcmio_connect(context, &io); if (ret) return ret; } cache = malloc(sizeof(*cache)); if (cache == NULL) goto oom; data = calloc(1, sizeof(*data)); if (data == NULL) goto oom; residual_copy = strdup(residual); if (residual_copy == NULL) goto oom; if (k5_cc_mutex_init(&data->lock) != 0) goto oom; data->residual = residual_copy; data->io = io; cache->ops = &krb5_kcm_ops; cache->data = data; cache->magic = KV5M_CCACHE; *cache_out = cache; return 0; oom: free(cache); free(data); free(residual_copy); kcmio_close(io); return ENOMEM; } /* Lock cache's I/O structure and use it to call the KCM daemon. */ static krb5_error_code cache_call(krb5_context context, krb5_ccache cache, struct kcmreq *req) { krb5_error_code ret; struct kcm_cache_data *data = cache->data; k5_cc_mutex_lock(context, &data->lock); ret = kcmio_call(context, data->io, req); k5_cc_mutex_unlock(context, &data->lock); return ret; } /* Try to propagate the KDC time offset from the cache to the krb5 context. */ static void get_kdc_offset(krb5_context context, krb5_ccache cache) { struct kcmreq req = EMPTY_KCMREQ; int32_t time_offset; kcmreq_init(&req, KCM_OP_GET_KDC_OFFSET, cache); if (cache_call(context, cache, &req) != 0) goto cleanup; time_offset = k5_input_get_uint32_be(&req.reply); if (req.reply.status) goto cleanup; context->os_context.time_offset = time_offset; context->os_context.usec_offset = 0; context->os_context.os_flags &= ~KRB5_OS_TOFFSET_TIME; context->os_context.os_flags |= KRB5_OS_TOFFSET_VALID; cleanup: kcmreq_free(&req); } /* Try to propagate the KDC offset from the krb5 context to the cache. */ static void set_kdc_offset(krb5_context context, krb5_ccache cache) { struct kcmreq req; if (context->os_context.os_flags & KRB5_OS_TOFFSET_VALID) { kcmreq_init(&req, KCM_OP_SET_KDC_OFFSET, cache); k5_buf_add_uint32_be(&req.reqbuf, context->os_context.time_offset); (void)cache_call(context, cache, &req); kcmreq_free(&req); } } static const char * KRB5_CALLCONV kcm_get_name(krb5_context context, krb5_ccache cache) { return ((struct kcm_cache_data *)cache->data)->residual; } /* Fetch the primary name within the collection. The result is only valid for * the lifetime of req and should not be freed. */ static krb5_error_code get_primary_name(krb5_context context, struct kcmreq *req, struct kcmio *io, const char **name_out) { krb5_error_code ret; *name_out = NULL; kcmreq_init(req, KCM_OP_GET_DEFAULT_CACHE, NULL); ret = kcmio_call(context, io, req); if (ret) return ret; return kcmreq_get_name(req, name_out); } static krb5_error_code KRB5_CALLCONV kcm_resolve(krb5_context context, krb5_ccache *cache_out, const char *residual) { krb5_error_code ret; struct kcmreq req = EMPTY_KCMREQ; struct kcmio *io = NULL; const char *defname = NULL; *cache_out = NULL; ret = kcmio_connect(context, &io); if (ret) goto cleanup; if (*residual == '\0') { ret = get_primary_name(context, &req, io, &defname); if (ret) goto cleanup; residual = defname; } ret = make_cache(context, residual, io, cache_out); io = NULL; cleanup: kcmio_close(io); kcmreq_free(&req); return ret; } krb5_error_code k5_kcm_primary_name(krb5_context context, char **name_out) { krb5_error_code ret; struct kcmreq req = EMPTY_KCMREQ; struct kcmio *io = NULL; const char *name; *name_out = NULL; ret = kcmio_connect(context, &io); if (ret) goto cleanup; ret = get_primary_name(context, &req, io, &name); if (ret) goto cleanup; *name_out = strdup(name); ret = (*name_out == NULL) ? ENOMEM : 0; cleanup: kcmio_close(io); kcmreq_free(&req); return ret; } static krb5_error_code KRB5_CALLCONV kcm_gen_new(krb5_context context, krb5_ccache *cache_out) { krb5_error_code ret; struct kcmreq req = EMPTY_KCMREQ; struct kcmio *io = NULL; const char *name; *cache_out = NULL; ret = kcmio_connect(context, &io); if (ret) goto cleanup; kcmreq_init(&req, KCM_OP_GEN_NEW, NULL); ret = kcmio_call(context, io, &req); if (ret) goto cleanup; ret = kcmreq_get_name(&req, &name); if (ret) goto cleanup; ret = make_cache(context, name, io, cache_out); io = NULL; cleanup: kcmreq_free(&req); kcmio_close(io); return ret; } static krb5_error_code KRB5_CALLCONV kcm_initialize(krb5_context context, krb5_ccache cache, krb5_principal princ) { krb5_error_code ret; struct kcmreq req; kcmreq_init(&req, KCM_OP_INITIALIZE, cache); k5_marshal_princ(&req.reqbuf, 4, princ); ret = cache_call(context, cache, &req); kcmreq_free(&req); set_kdc_offset(context, cache); return ret; } static krb5_error_code KRB5_CALLCONV kcm_close(krb5_context context, krb5_ccache cache) { struct kcm_cache_data *data = cache->data; k5_cc_mutex_destroy(&data->lock); kcmio_close(data->io); free(data->residual); free(data); free(cache); return 0; } static krb5_error_code KRB5_CALLCONV kcm_destroy(krb5_context context, krb5_ccache cache) { krb5_error_code ret; struct kcmreq req; kcmreq_init(&req, KCM_OP_DESTROY, cache); ret = cache_call(context, cache, &req); kcmreq_free(&req); (void)kcm_close(context, cache); return ret; } static krb5_error_code KRB5_CALLCONV kcm_store(krb5_context context, krb5_ccache cache, krb5_creds *cred) { krb5_error_code ret; struct kcmreq req; kcmreq_init(&req, KCM_OP_STORE, cache); k5_marshal_cred(&req.reqbuf, 4, cred); ret = cache_call(context, cache, &req); kcmreq_free(&req); return ret; } static krb5_error_code KRB5_CALLCONV kcm_retrieve(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *mcred, krb5_creds *cred_out) { krb5_error_code ret; struct kcmreq req = EMPTY_KCMREQ; krb5_creds cred; krb5_enctype *enctypes = NULL; memset(&cred, 0, sizeof(cred)); /* Include KCM_GC_CACHED in flags to prevent Heimdal's sssd from making a * TGS request itself. */ kcmreq_init(&req, KCM_OP_RETRIEVE, cache); k5_buf_add_uint32_be(&req.reqbuf, map_tcflags(flags) | KCM_GC_CACHED); k5_marshal_mcred(&req.reqbuf, mcred); ret = cache_call(context, cache, &req); /* Fall back to iteration if the server does not support retrieval. */ if (unsupported_op_error(ret)) { ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred, cred_out); goto cleanup; } if (ret) goto cleanup; ret = k5_unmarshal_cred(req.reply.ptr, req.reply.len, 4, &cred); if (ret) goto cleanup; /* In rare cases we might retrieve a credential with a session key this * context can't support, in which case we must retry using iteration. */ if (flags & KRB5_TC_SUPPORTED_KTYPES) { ret = krb5_get_tgs_ktypes(context, cred.server, &enctypes); if (ret) goto cleanup; if (!k5_etypes_contains(enctypes, cred.keyblock.enctype)) { ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred, cred_out); goto cleanup; } } *cred_out = cred; memset(&cred, 0, sizeof(cred)); cleanup: kcmreq_free(&req); krb5_free_cred_contents(context, &cred); free(enctypes); /* Heimdal's KCM returns KRB5_CC_END if no cred is found. */ return (ret == KRB5_CC_END) ? KRB5_CC_NOTFOUND : map_invalid(ret); } static krb5_error_code KRB5_CALLCONV kcm_get_princ(krb5_context context, krb5_ccache cache, krb5_principal *princ_out) { krb5_error_code ret; struct kcmreq req; struct kcm_cache_data *data = cache->data; kcmreq_init(&req, KCM_OP_GET_PRINCIPAL, cache); ret = cache_call(context, cache, &req); /* Heimdal KCM can respond with code 0 and no principal. */ if (!ret && req.reply.len == 0) ret = KRB5_FCC_NOFILE; if (ret == KRB5_FCC_NOFILE) { k5_setmsg(context, ret, _("Credentials cache 'KCM:%s' not found"), data->residual); } if (!ret) ret = k5_unmarshal_princ(req.reply.ptr, req.reply.len, 4, princ_out); kcmreq_free(&req); return map_invalid(ret); } static krb5_error_code KRB5_CALLCONV kcm_start_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor_out) { krb5_error_code ret; struct kcmreq req = EMPTY_KCMREQ; struct uuid_list *uuids = NULL; struct cred_list *creds = NULL; struct kcm_cursor *cursor; *cursor_out = NULL; get_kdc_offset(context, cache); kcmreq_init(&req, KCM_OP_GET_CRED_LIST, cache); ret = cache_call(context, cache, &req); if (ret == 0) { /* GET_CRED_LIST is available. */ ret = kcmreq_get_cred_list(&req, &creds); if (ret) goto cleanup; } else if (unsupported_op_error(ret)) { /* Fall back to GET_CRED_UUID_LIST. */ kcmreq_free(&req); kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache); ret = cache_call(context, cache, &req); if (ret) goto cleanup; ret = kcmreq_get_uuid_list(&req, &uuids); if (ret) goto cleanup; } else { goto cleanup; } cursor = k5alloc(sizeof(*cursor), &ret); if (cursor == NULL) goto cleanup; cursor->uuids = uuids; uuids = NULL; cursor->creds = creds; creds = NULL; *cursor_out = (krb5_cc_cursor)cursor; cleanup: free_cred_list(creds); free_uuid_list(uuids); kcmreq_free(&req); return ret; } static krb5_error_code next_cred_by_uuid(krb5_context context, krb5_ccache cache, struct uuid_list *uuids, krb5_creds *cred_out) { krb5_error_code ret; struct kcmreq req; memset(cred_out, 0, sizeof(*cred_out)); if (uuids->pos >= uuids->count) return KRB5_CC_END; kcmreq_init(&req, KCM_OP_GET_CRED_BY_UUID, cache); k5_buf_add_len(&req.reqbuf, uuids->uuidbytes + (uuids->pos * KCM_UUID_LEN), KCM_UUID_LEN); uuids->pos++; ret = cache_call(context, cache, &req); if (!ret) ret = k5_unmarshal_cred(req.reply.ptr, req.reply.len, 4, cred_out); kcmreq_free(&req); return map_invalid(ret); } static krb5_error_code KRB5_CALLCONV kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, krb5_creds *cred_out) { struct kcm_cursor *c = (struct kcm_cursor *)*cursor; struct cred_list *list; if (c->uuids != NULL) return next_cred_by_uuid(context, cache, c->uuids, cred_out); list = c->creds; if (list->pos >= list->count) return KRB5_CC_END; /* Transfer memory ownership of one cred to the caller. */ *cred_out = list->creds[list->pos]; memset(&list->creds[list->pos], 0, sizeof(*list->creds)); list->pos++; return 0; } static krb5_error_code KRB5_CALLCONV kcm_end_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor) { struct kcm_cursor *c = *cursor; if (c == NULL) return 0; free_uuid_list(c->uuids); free_cred_list(c->creds); free(c); *cursor = NULL; return 0; } static krb5_error_code KRB5_CALLCONV kcm_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *mcred) { krb5_error_code ret; struct kcmreq req; kcmreq_init(&req, KCM_OP_REMOVE_CRED, cache); k5_buf_add_uint32_be(&req.reqbuf, map_tcflags(flags)); k5_marshal_mcred(&req.reqbuf, mcred); ret = cache_call(context, cache, &req); kcmreq_free(&req); return ret; } static krb5_error_code KRB5_CALLCONV kcm_set_flags(krb5_context context, krb5_ccache cache, krb5_flags flags) { /* We don't currently care about any flags for this type. */ return 0; } static krb5_error_code KRB5_CALLCONV kcm_get_flags(krb5_context context, krb5_ccache cache, krb5_flags *flags_out) { /* We don't currently have any operational flags for this type. */ *flags_out = 0; return 0; } /* Construct a per-type cursor, always taking ownership of io and uuids. */ static krb5_error_code make_ptcursor(const char *residual, struct uuid_list *uuids, struct kcmio *io, krb5_cc_ptcursor *cursor_out) { krb5_cc_ptcursor cursor = NULL; struct kcm_ptcursor *data = NULL; char *residual_copy = NULL; *cursor_out = NULL; if (residual != NULL) { residual_copy = strdup(residual); if (residual_copy == NULL) goto oom; } cursor = malloc(sizeof(*cursor)); if (cursor == NULL) goto oom; data = malloc(sizeof(*data)); if (data == NULL) goto oom; data->residual = residual_copy; data->uuids = uuids; data->io = io; data->first = TRUE; cursor->ops = &krb5_kcm_ops; cursor->data = data; *cursor_out = cursor; return 0; oom: kcmio_close(io); free_uuid_list(uuids); free(residual_copy); free(data); free(cursor); return ENOMEM; } static krb5_error_code KRB5_CALLCONV kcm_ptcursor_new(krb5_context context, krb5_cc_ptcursor *cursor_out) { krb5_error_code ret; struct kcmreq req = EMPTY_KCMREQ; struct kcmio *io = NULL; struct uuid_list *uuids = NULL; const char *defname, *primary; *cursor_out = NULL; /* Don't try to use KCM for the cache collection unless the default cache * name has the KCM type. */ defname = krb5_cc_default_name(context); if (defname == NULL || strncmp(defname, "KCM:", 4) != 0) return make_ptcursor(NULL, NULL, NULL, cursor_out); ret = kcmio_connect(context, &io); if (ret) return ret; /* If defname is a subsidiary cache, return a singleton cursor. */ if (strlen(defname) > 4) return make_ptcursor(defname + 4, NULL, io, cursor_out); kcmreq_init(&req, KCM_OP_GET_CACHE_UUID_LIST, NULL); ret = kcmio_call(context, io, &req); if (ret == KRB5_FCC_NOFILE) { /* There are no accessible caches; return an empty cursor. */ ret = make_ptcursor(NULL, NULL, NULL, cursor_out); goto cleanup; } if (ret) goto cleanup; ret = kcmreq_get_uuid_list(&req, &uuids); if (ret) goto cleanup; kcmreq_free(&req); kcmreq_init(&req, KCM_OP_GET_DEFAULT_CACHE, NULL); ret = kcmio_call(context, io, &req); if (ret) goto cleanup; ret = kcmreq_get_name(&req, &primary); if (ret) goto cleanup; ret = make_ptcursor(primary, uuids, io, cursor_out); uuids = NULL; io = NULL; cleanup: free_uuid_list(uuids); kcmio_close(io); kcmreq_free(&req); return ret; } /* Return true if name is an initialized cache. */ static krb5_boolean name_exists(krb5_context context, struct kcmio *io, const char *name) { krb5_error_code ret; struct kcmreq req; kcmreq_init(&req, KCM_OP_GET_PRINCIPAL, NULL); k5_buf_add_len(&req.reqbuf, name, strlen(name) + 1); ret = kcmio_call(context, io, &req); kcmreq_free(&req); return ret == 0; } static krb5_error_code KRB5_CALLCONV kcm_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor, krb5_ccache *cache_out) { krb5_error_code ret = 0; struct kcmreq req = EMPTY_KCMREQ; struct kcm_ptcursor *data = cursor->data; struct uuid_list *uuids; const unsigned char *id; const char *name; *cache_out = NULL; /* Return the primary or specified subsidiary cache if we haven't yet. */ if (data->first && data->residual != NULL) { data->first = FALSE; if (name_exists(context, data->io, data->residual)) return make_cache(context, data->residual, NULL, cache_out); } uuids = data->uuids; if (uuids == NULL) return 0; while (uuids->pos < uuids->count) { /* Get the name of the next cache. */ id = &uuids->uuidbytes[KCM_UUID_LEN * uuids->pos++]; kcmreq_free(&req); kcmreq_init(&req, KCM_OP_GET_CACHE_BY_UUID, NULL); k5_buf_add_len(&req.reqbuf, id, KCM_UUID_LEN); ret = kcmio_call(context, data->io, &req); /* Continue if the cache has been deleted. */ if (ret == KRB5_CC_END || ret == KRB5_FCC_NOFILE) { ret = 0; continue; } if (ret) goto cleanup; ret = kcmreq_get_name(&req, &name); if (ret) goto cleanup; /* Don't yield the primary cache twice. */ if (strcmp(name, data->residual) == 0) continue; ret = make_cache(context, name, NULL, cache_out); break; } cleanup: kcmreq_free(&req); return ret; } static krb5_error_code KRB5_CALLCONV kcm_ptcursor_free(krb5_context context, krb5_cc_ptcursor *cursor) { struct kcm_ptcursor *data = (*cursor)->data; free(data->residual); free_uuid_list(data->uuids); kcmio_close(data->io); free(data); free(*cursor); *cursor = NULL; return 0; } static krb5_error_code KRB5_CALLCONV kcm_replace(krb5_context context, krb5_ccache cache, krb5_principal princ, krb5_creds **creds) { krb5_error_code ret; struct kcmreq req = EMPTY_KCMREQ; size_t pos; uint8_t *lenptr; int ncreds, i; krb5_os_context octx = &context->os_context; int32_t offset; kcmreq_init(&req, KCM_OP_REPLACE, cache); offset = (octx->os_flags & KRB5_OS_TOFFSET_VALID) ? octx->time_offset : 0; k5_buf_add_uint32_be(&req.reqbuf, offset); k5_marshal_princ(&req.reqbuf, 4, princ); for (ncreds = 0; creds[ncreds] != NULL; ncreds++); k5_buf_add_uint32_be(&req.reqbuf, ncreds); for (i = 0; creds[i] != NULL; i++) { /* Store a dummy length, then fix it up after marshalling the cred. */ pos = req.reqbuf.len; k5_buf_add_uint32_be(&req.reqbuf, 0); k5_marshal_cred(&req.reqbuf, 4, creds[i]); if (k5_buf_status(&req.reqbuf) == 0) { lenptr = (uint8_t *)req.reqbuf.data + pos; store_32_be(req.reqbuf.len - (pos + 4), lenptr); } } ret = cache_call(context, cache, &req); kcmreq_free(&req); if (unsupported_op_error(ret)) return k5_nonatomic_replace(context, cache, princ, creds); return ret; } static krb5_error_code KRB5_CALLCONV kcm_lock(krb5_context context, krb5_ccache cache) { k5_cc_mutex_lock(context, &((struct kcm_cache_data *)cache->data)->lock); return 0; } static krb5_error_code KRB5_CALLCONV kcm_unlock(krb5_context context, krb5_ccache cache) { k5_cc_mutex_unlock(context, &((struct kcm_cache_data *)cache->data)->lock); return 0; } static krb5_error_code KRB5_CALLCONV kcm_switch_to(krb5_context context, krb5_ccache cache) { krb5_error_code ret; struct kcmreq req; kcmreq_init(&req, KCM_OP_SET_DEFAULT_CACHE, cache); ret = cache_call(context, cache, &req); kcmreq_free(&req); return ret; } const krb5_cc_ops krb5_kcm_ops = { 0, "KCM", kcm_get_name, kcm_resolve, kcm_gen_new, kcm_initialize, kcm_destroy, kcm_close, kcm_store, kcm_retrieve, kcm_get_princ, kcm_start_seq_get, kcm_next_cred, kcm_end_seq_get, kcm_remove_cred, kcm_set_flags, kcm_get_flags, kcm_ptcursor_new, kcm_ptcursor_next, kcm_ptcursor_free, kcm_replace, NULL, /* wasdefault */ kcm_lock, kcm_unlock, kcm_switch_to, }; #endif /* not _WIN32 */ krb5-1.22.1/src/lib/krb5/ccache/t_cc.c0000664000175000017500000004764315051422640017041 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/t_cc.c */ /* * Copyright 2000 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "cc-int.h" #include #include #include "autoconf.h" #ifdef HAVE_UNISTD_H #include #endif #include "com_err.h" #define KRB5_OK 0 krb5_creds test_creds, test_creds2; int debug=0; static void init_structs(void) { static int add=0x12345; static krb5_address addr; static krb5_address *addrs[] = { &addr, 0, }; addr.magic = KV5M_ADDRESS; addr.addrtype = ADDRTYPE_INET; addr.length = 4; addr.contents = (krb5_octet *) &add; test_creds.magic = KV5M_CREDS; test_creds.client = NULL; test_creds.server = NULL; test_creds.keyblock.magic = KV5M_KEYBLOCK; test_creds.keyblock.contents = 0; test_creds.keyblock.enctype = 1; test_creds.keyblock.length = 1; test_creds.keyblock.contents = (unsigned char *) "1"; test_creds.times.authtime = 1111; test_creds.times.starttime = 2222; test_creds.times.endtime = 3333; test_creds.times.renew_till = 4444; test_creds.is_skey = 1; test_creds.ticket_flags = 5555; test_creds.addresses = addrs; #define SET_TICKET(ent, str) {ent.magic = KV5M_DATA; ent.length = sizeof(str); ent.data = str;} SET_TICKET(test_creds.ticket, "This is ticket 1"); SET_TICKET(test_creds.second_ticket, "This is ticket 2"); test_creds.authdata = NULL; } static krb5_error_code init_test_cred(krb5_context context) { krb5_error_code kret; unsigned int i; krb5_authdata *a; #define REALM "REALM" kret = krb5_build_principal(context, &test_creds.client, sizeof(REALM), REALM, "client-comp1", "client-comp2", NULL); if(kret) return kret; kret = krb5_build_principal(context, &test_creds.server, sizeof(REALM), REALM, "server-comp1", "server-comp2", NULL); if(kret) { krb5_free_principal(context, test_creds.client); test_creds.client = 0; goto cleanup; } test_creds.authdata = malloc (3 * sizeof(krb5_authdata *)); if (!test_creds.authdata) { kret = ENOMEM; goto cleanup; } for (i = 0 ; i <= 2 ; i++) { test_creds.authdata[i] = 0; } a = (krb5_authdata *) malloc(sizeof(krb5_authdata)); if(!a) { kret = ENOMEM; goto cleanup; } a->magic = KV5M_AUTHDATA; a->ad_type = KRB5_AUTHDATA_IF_RELEVANT; a->contents = (krb5_octet * ) malloc(1); if(!a->contents) { free(a); kret = ENOMEM; goto cleanup; } a->contents[0]=5; a->length = 1; test_creds.authdata[0] = a; a = (krb5_authdata *) malloc(sizeof(krb5_authdata)); if(!a) { kret = ENOMEM; goto cleanup; } a->magic = KV5M_AUTHDATA; a->ad_type = KRB5_AUTHDATA_KDC_ISSUED; a->contents = (krb5_octet * ) malloc(2); if(!a->contents) { free(a); kret = ENOMEM; goto cleanup; } a->contents[0]=4; a->contents[1]=6; a->length = 2; test_creds.authdata[1] = a; memcpy(&test_creds2, &test_creds, sizeof(test_creds)); kret = krb5_build_principal(context, &test_creds2.server, sizeof(REALM), REALM, "server-comp1", "server-comp3", NULL); cleanup: if(kret) { if (test_creds.client) { krb5_free_principal(context, test_creds.client); test_creds.client = 0; } if (test_creds.server) { krb5_free_principal(context, test_creds.server); test_creds.server = 0; } if (test_creds.authdata) { krb5_free_authdata(context, test_creds.authdata); test_creds.authdata = 0; } } return kret; } static void free_test_cred(krb5_context context) { krb5_free_principal(context, test_creds.client); krb5_free_principal(context, test_creds.server); krb5_free_principal(context, test_creds2.server); if(test_creds.authdata) { krb5_free_authdata(context, test_creds.authdata); test_creds.authdata = 0; } } #define CHECK(kret,msg) \ if (kret != KRB5_OK) { \ com_err(msg, kret, ""); \ fflush(stderr); \ exit(1); \ } else if(debug) printf("%s went ok\n", msg); #define CHECK_STR(str,msg) \ if (str == 0) { \ com_err(msg, kret, ""); \ exit(1); \ } else if(debug) printf("%s went ok\n", msg); #define CHECK_BOOL(expr,errstr,msg) \ if (expr) { \ fprintf(stderr, "%s %s\n", msg, errstr); \ exit(1); \ } else if(debug) printf("%s went ok\n", msg); #define CHECK_FAIL(experr, kret, msg) \ if (experr != kret) { CHECK(kret, msg);} static void check_num_entries(krb5_context context, krb5_ccache cache, int expected, unsigned linenum) { krb5_error_code ret; krb5_cc_cursor cursor; krb5_creds creds; int count = 0; ret = krb5_cc_start_seq_get(context, cache, &cursor); if (ret != 0) { com_err("", ret, "(on line %d) - krb5_cc_start_seq_get", linenum); fflush(stderr); exit(1); } while (1) { ret = krb5_cc_next_cred(context, cache, &cursor, &creds); if (ret) break; count++; krb5_free_cred_contents(context, &creds); } krb5_cc_end_seq_get(context, cache, &cursor); if (ret != KRB5_CC_END) { CHECK(ret, "counting entries in ccache"); } if (count != expected) { com_err("", KRB5_FCC_INTERNAL, "(on line %d) - count didn't match (expected %d, got %d)", linenum, expected, count); fflush(stderr); exit(1); } } static void cc_test(krb5_context context, const char *name, krb5_flags flags) { krb5_ccache id, id2; krb5_creds creds; krb5_error_code kret; krb5_cc_cursor cursor; krb5_principal tmp; krb5_flags matchflags = KRB5_TC_MATCH_IS_SKEY; const char *c_name; char newcache[300]; char *save_type; kret = init_test_cred(context); CHECK(kret, "init_creds"); kret = krb5_cc_resolve(context, name, &id); CHECK(kret, "resolve"); kret = krb5_cc_initialize(context, id, test_creds.client); CHECK(kret, "initialize"); c_name = krb5_cc_get_name(context, id); CHECK_STR(c_name, "get_name"); c_name = krb5_cc_get_type(context, id); CHECK_STR(c_name, "get_type"); save_type=strdup(c_name); CHECK_STR(save_type, "copying type"); kret = krb5_cc_store_cred(context, id, &test_creds); CHECK(kret, "store"); kret = krb5_cc_get_principal(context, id, &tmp); CHECK(kret, "get_principal"); CHECK_BOOL(krb5_realm_compare(context, tmp, test_creds.client) != TRUE, "realms do not match", "realm_compare"); CHECK_BOOL(krb5_principal_compare(context, tmp, test_creds.client) != TRUE, "principals do not match", "principal_compare"); krb5_free_principal(context, tmp); kret = krb5_cc_set_flags (context, id, flags); CHECK(kret, "set_flags"); kret = krb5_cc_start_seq_get(context, id, &cursor); CHECK(kret, "start_seq_get"); kret = 0; while (kret != KRB5_CC_END) { if(debug) printf("Calling next_cred\n"); kret = krb5_cc_next_cred(context, id, &cursor, &creds); if(kret == KRB5_CC_END) { if(debug) printf("next_cred: ok at end\n"); } else { CHECK(kret, "next_cred"); krb5_free_cred_contents(context, &creds); } } kret = krb5_cc_end_seq_get(context, id, &cursor); CHECK(kret, "end_seq_get"); kret = krb5_cc_close(context, id); CHECK(kret, "close"); /* ------------------------------------------------- */ kret = krb5_cc_resolve(context, name, &id); CHECK(kret, "resolve2"); { /* Copy the cache test*/ snprintf(newcache, sizeof(newcache), "%s.new", name); kret = krb5_cc_resolve(context, newcache, &id2); CHECK(kret, "resolve of new cache"); /* This should fail as the new creds are not initialized */ kret = krb5_cc_copy_creds(context, id, id2); CHECK_FAIL(KRB5_FCC_NOFILE, kret, "copy_creds"); kret = krb5_cc_initialize(context, id2, test_creds.client); CHECK(kret, "initialize of id2"); kret = krb5_cc_copy_creds(context, id, id2); CHECK(kret, "copy_creds"); kret = krb5_cc_destroy(context, id2); CHECK(kret, "destroy new cache"); } /* Destroy the first cache */ kret = krb5_cc_destroy(context, id); CHECK(kret, "destroy"); /* ----------------------------------------------------- */ /* Tests the generate new code */ kret = krb5_cc_new_unique(context, save_type, NULL, &id2); CHECK(kret, "new_unique"); kret = krb5_cc_initialize(context, id2, test_creds.client); CHECK(kret, "initialize"); kret = krb5_cc_store_cred(context, id2, &test_creds); CHECK(kret, "store"); kret = krb5_cc_destroy(context, id2); CHECK(kret, "destroy id2"); /* ----------------------------------------------------- */ /* Test credential removal */ kret = krb5_cc_resolve(context, name, &id); CHECK(kret, "resolving for remove"); kret = krb5_cc_initialize(context, id, test_creds.client); CHECK(kret, "initialize for remove"); check_num_entries(context, id, 0, __LINE__); kret = krb5_cc_store_cred(context, id, &test_creds); CHECK(kret, "store for remove (first pass)"); check_num_entries(context, id, 1, __LINE__); /* 1 */ kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds); CHECK(kret, "removing credential (first pass)"); check_num_entries(context, id, 0, __LINE__); /* empty */ kret = krb5_cc_store_cred(context, id, &test_creds); CHECK(kret, "first store for remove (second pass)"); check_num_entries(context, id, 1, __LINE__); /* 1 */ kret = krb5_cc_store_cred(context, id, &test_creds2); CHECK(kret, "second store for remove (second pass)"); check_num_entries(context, id, 2, __LINE__); /* 1, 2 */ kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds2); CHECK(kret, "first remove (second pass)"); check_num_entries(context, id, 1, __LINE__); /* 1 */ kret = krb5_cc_store_cred(context, id, &test_creds2); CHECK(kret, "third store for remove (second pass)"); check_num_entries(context, id, 2, __LINE__); /* 1, 2 */ kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds); CHECK(kret, "second remove (second pass)"); check_num_entries(context, id, 1, __LINE__); /* 2 */ kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds2); CHECK(kret, "third remove (second pass)"); check_num_entries(context, id, 0, __LINE__); /* empty */ kret = krb5_cc_destroy(context, id); CHECK(kret, "destruction for remove"); /* Test removal with iteration. */ kret = krb5_cc_resolve(context, name, &id); CHECK(kret, "resolving for remove-iter"); kret = krb5_cc_initialize(context, id, test_creds.client); CHECK(kret, "initialize for remove-iter"); kret = krb5_cc_store_cred(context, id, &test_creds); CHECK(kret, "first store for remove-iter"); kret = krb5_cc_store_cred(context, id, &test_creds2); CHECK(kret, "second store for remove-iter"); kret = krb5_cc_start_seq_get(context, id, &cursor); CHECK(kret, "start_seq_get for remove-iter"); kret = krb5_cc_remove_cred(context, id, matchflags, &test_creds); CHECK(kret, "remove for remove-iter"); while (1) { /* The removed credential may or may not be present in the cache - * either behavior is technically correct. */ kret = krb5_cc_next_cred(context, id, &cursor, &creds); if (kret == KRB5_CC_END) break; CHECK(kret, "next_cred for remove-iter: %s"); CHECK(creds.times.endtime == 0, "no-lifetime cred"); krb5_free_cred_contents(context, &creds); } kret = krb5_cc_end_seq_get(context, id, &cursor); CHECK(kret, "end_seq_get for remove-iter"); kret = krb5_cc_destroy(context, id); CHECK(kret, "destruction for remove-iter"); free(save_type); free_test_cred(context); } /* * Checks if a credential type is registered with the library */ static int check_registered(krb5_context context, const char *prefix) { char name[300]; krb5_error_code kret; krb5_ccache id; snprintf(name, sizeof(name), "%s/tmp/cctest.%ld", prefix, (long) getpid()); kret = krb5_cc_resolve(context, name, &id); if(kret != KRB5_OK) { if(kret == KRB5_CC_UNKNOWN_TYPE) return 0; com_err("Checking on credential type", kret, "%s", prefix); fflush(stderr); return 0; } kret = krb5_cc_close(context, id); if(kret != KRB5_OK) { com_err("Checking on credential type - closing", kret, "%s", prefix); fflush(stderr); } return 1; } static void do_test(krb5_context context, const char *prefix) { char name[300]; snprintf(name, sizeof(name), "%s/tmp/cctest.%ld", prefix, (long) getpid()); printf("Starting test on %s\n", name); cc_test (context, name, 0); cc_test (context, name, !0); printf("Test on %s passed\n", name); } static void test_misc(krb5_context context) { /* Tests for certain error returns */ krb5_error_code kret; krb5_ccache id; const krb5_cc_ops *ops_save; fprintf(stderr, "Testing miscellaneous error conditions\n"); kret = krb5_cc_resolve(context, "unknown_method_ep:/tmp/name", &id); if (kret != KRB5_CC_UNKNOWN_TYPE) { CHECK(kret, "resolve unknown type"); } /* Test for not specifying a cache type with no defaults */ ops_save = krb5_cc_dfl_ops; krb5_cc_dfl_ops = 0; kret = krb5_cc_resolve(context, "/tmp/e", &id); if (kret != KRB5_CC_BADNAME) { CHECK(kret, "resolve no builtin type"); } krb5_cc_dfl_ops = ops_save; } /* * Regression tests for #8202. Because memory ccaches share objects between * different handles to the same cache and between iterators and caches, * historically there have been some bugs when those objects are released. */ static void test_memory_concurrent(krb5_context context) { krb5_error_code kret; krb5_ccache id1, id2; krb5_cc_cursor cursor; krb5_creds creds; /* Create two handles to the same memory ccache and destroy them. */ kret = krb5_cc_resolve(context, "MEMORY:x", &id1); CHECK(kret, "resolve 1"); kret = krb5_cc_resolve(context, "MEMORY:x", &id2); CHECK(kret, "resolve 2"); kret = krb5_cc_destroy(context, id1); CHECK(kret, "destroy 1"); kret = krb5_cc_destroy(context, id2); CHECK(kret, "destroy 2"); kret = init_test_cred(context); CHECK(kret, "init_creds"); /* Reinitialize the cache after creating an iterator for it, and verify * that the iterator ends gracefully. */ kret = krb5_cc_resolve(context, "MEMORY:x", &id1); CHECK(kret, "resolve"); kret = krb5_cc_initialize(context, id1, test_creds.client); CHECK(kret, "initialize"); kret = krb5_cc_store_cred(context, id1, &test_creds); CHECK(kret, "store"); kret = krb5_cc_start_seq_get(context, id1, &cursor); CHECK(kret, "start_seq_get"); kret = krb5_cc_initialize(context, id1, test_creds.client); CHECK(kret, "initialize again"); kret = krb5_cc_next_cred(context, id1, &cursor, &creds); CHECK_BOOL(kret != KRB5_CC_END, "iterator should end", "next_cred"); kret = krb5_cc_end_seq_get(context, id1, &cursor); CHECK(kret, "end_seq_get"); kret = krb5_cc_destroy(context, id1); CHECK(kret, "destroy"); free_test_cred(context); } /* Check that order is preserved during iteration. Not all cache types have * this property. */ static void test_order(krb5_context context, const char *name) { krb5_error_code kret; krb5_ccache id; krb5_cc_cursor cursor; krb5_creds creds; kret = init_test_cred(context); CHECK(kret, "init_creds"); kret = krb5_cc_resolve(context, name, &id); CHECK(kret, "resolve"); kret = krb5_cc_initialize(context, id, test_creds.client); CHECK(kret, "initialize"); kret = krb5_cc_store_cred(context, id, &test_creds); CHECK(kret, "store 1"); kret = krb5_cc_store_cred(context, id, &test_creds2); CHECK(kret, "store 2"); kret = krb5_cc_start_seq_get(context, id, &cursor); CHECK(kret, "start_seq_get"); kret = krb5_cc_next_cred(context, id, &cursor, &creds); CHECK(kret, "next_cred 1"); CHECK_BOOL(krb5_principal_compare(context, creds.server, test_creds.server) != TRUE, "first cred does not match", "principal_compare"); krb5_free_cred_contents(context, &creds); kret = krb5_cc_next_cred(context, id, &cursor, &creds); CHECK(kret, "next_cred 2"); CHECK_BOOL(krb5_principal_compare(context, creds.server, test_creds2.server) != TRUE, "second cred does not match", "principal_compare"); krb5_free_cred_contents(context, &creds); krb5_cc_end_seq_get(context, id, &cursor); krb5_cc_close(context, id); free_test_cred(context); } extern const krb5_cc_ops krb5_mcc_ops; extern const krb5_cc_ops krb5_fcc_ops; int main(void) { krb5_context context; krb5_error_code kret; if ((kret = krb5_init_context(&context))) { printf("Couldn't initialize krb5 library: %s\n", error_message(kret)); exit(1); } kret = krb5_cc_register(context, &krb5_mcc_ops,0); if(kret && kret != KRB5_CC_TYPE_EXISTS) { CHECK(kret, "register_mem"); } kret = krb5_cc_register(context, &krb5_fcc_ops,0); if(kret && kret != KRB5_CC_TYPE_EXISTS) { CHECK(kret, "register_mem"); } /* Registering a second time tests for error return */ kret = krb5_cc_register(context, &krb5_fcc_ops,0); if(kret != KRB5_CC_TYPE_EXISTS) { CHECK(kret, "register_mem"); } /* Registering with override should work */ kret = krb5_cc_register(context, &krb5_fcc_ops,1); CHECK(kret, "register_mem override"); init_structs(); test_misc(context); do_test(context, ""); if (check_registered(context, "KEYRING:process:")) do_test(context, "KEYRING:process:"); else printf("Skipping KEYRING: test - unregistered type\n"); do_test(context, "MEMORY:"); do_test(context, "FILE:"); test_memory_concurrent(context); test_order(context, "MEMORY:order"); krb5_free_context(context); return 0; } krb5-1.22.1/src/lib/krb5/ccache/ccapi_util.h0000664000175000017500000000376015051422640020242 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/ccache/ccapi_util.c - conversion declarations for CCAPI creds */ /* * Copyright (C) 2021 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CCAPI_UTIL_H #define CCAPI_UTIL_H #include krb5_error_code k5_ccapi_to_krb5_creds(krb5_context context, const cc_credentials_union *ccapi_cred, krb5_creds *cred_out); krb5_error_code k5_krb5_to_ccapi_creds(krb5_context context, krb5_creds *cred, cc_credentials_union **ccapi_cred_out); void k5_release_ccapi_cred(cc_credentials_union *ccapi_cred); #endif /* CCAPI_UTIL_H */ krb5-1.22.1/src/lib/krb5/krb/0000775000175000017500000000000015051422640015317 5ustar ghudsonghudsonkrb5-1.22.1/src/lib/krb5/krb/copy_key.c0000664000175000017500000000306115051422640017305 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/copy_key.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" /* Copy a keyblock, including alloc'ed storage. */ krb5_error_code KRB5_CALLCONV krb5_copy_keyblock(krb5_context context, const krb5_keyblock *from, krb5_keyblock **to) { return krb5int_c_copy_keyblock(context, from, to); } krb5-1.22.1/src/lib/krb5/krb/s4u_creds.c0000664000175000017500000012326615051422640017370 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/s4u_creds.c */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "int-proto.h" #include "os-proto.h" /* Convert ticket flags to necessary KDC options */ #define FLAGS2OPTS(flags) (flags & KDC_TKT_COMMON_MASK) /* * Implements S4U2Self, by which a service can request a ticket to * itself on behalf of an arbitrary principal. */ static krb5_error_code s4u_identify_user(krb5_context context, krb5_creds *in_creds, krb5_data *subject_cert, krb5_principal *canon_user) { krb5_principal_data client; krb5_data empty_name = empty_data(); *canon_user = NULL; if (in_creds->client == NULL && subject_cert == NULL) { return EINVAL; } if (in_creds->client != NULL && in_creds->client->type != KRB5_NT_ENTERPRISE_PRINCIPAL) { int anonymous; anonymous = krb5_principal_compare(context, in_creds->client, krb5_anonymous_principal()); return krb5_copy_principal(context, anonymous ? in_creds->server : in_creds->client, canon_user); } if (in_creds->client != NULL) { client = *in_creds->client; client.realm = in_creds->server->realm; /* Don't send subject_cert if we have an enterprise principal. */ return k5_identify_realm(context, &client, NULL, canon_user); } client.magic = KV5M_PRINCIPAL; client.realm = in_creds->server->realm; /* * Windows clients send the certificate subject as the client name. * However, Windows KDC seem to be happy with an empty string as long as * the name-type is NT-X500-PRINCIPAL. */ client.data = &empty_name; client.length = 1; client.type = KRB5_NT_X500_PRINCIPAL; return k5_identify_realm(context, &client, subject_cert, canon_user); } static krb5_error_code make_pa_for_user_checksum(krb5_context context, krb5_keyblock *key, krb5_pa_for_user *req, krb5_checksum *cksum) { krb5_error_code code; int i; char *p; krb5_data data; data.length = 4; for (i = 0; i < req->user->length; i++) data.length += req->user->data[i].length; data.length += req->user->realm.length; data.length += req->auth_package.length; p = data.data = malloc(data.length); if (data.data == NULL) return ENOMEM; p[0] = (req->user->type >> 0) & 0xFF; p[1] = (req->user->type >> 8) & 0xFF; p[2] = (req->user->type >> 16) & 0xFF; p[3] = (req->user->type >> 24) & 0xFF; p += 4; for (i = 0; i < req->user->length; i++) { if (req->user->data[i].length > 0) memcpy(p, req->user->data[i].data, req->user->data[i].length); p += req->user->data[i].length; } if (req->user->realm.length > 0) memcpy(p, req->user->realm.data, req->user->realm.length); p += req->user->realm.length; if (req->auth_package.length > 0) memcpy(p, req->auth_package.data, req->auth_package.length); /* Per spec, use hmac-md5 checksum regardless of key type. */ code = krb5_c_make_checksum(context, CKSUMTYPE_HMAC_MD5_ARCFOUR, key, KRB5_KEYUSAGE_APP_DATA_CKSUM, &data, cksum); free(data.data); return code; } static krb5_error_code build_pa_for_user(krb5_context context, krb5_creds *tgt, krb5_s4u_userid *userid, krb5_pa_data **out_padata) { krb5_error_code code; krb5_pa_data *padata; krb5_pa_for_user for_user; krb5_data *for_user_data = NULL; char package[] = "Kerberos"; if (userid->user == NULL) return EINVAL; memset(&for_user, 0, sizeof(for_user)); for_user.user = userid->user; for_user.auth_package.data = package; for_user.auth_package.length = sizeof(package) - 1; code = make_pa_for_user_checksum(context, &tgt->keyblock, &for_user, &for_user.cksum); if (code != 0) goto cleanup; code = encode_krb5_pa_for_user(&for_user, &for_user_data); if (code != 0) goto cleanup; padata = malloc(sizeof(*padata)); if (padata == NULL) { code = ENOMEM; goto cleanup; } padata->magic = KV5M_PA_DATA; padata->pa_type = KRB5_PADATA_FOR_USER; padata->length = for_user_data->length; padata->contents = (krb5_octet *)for_user_data->data; free(for_user_data); for_user_data = NULL; *out_padata = padata; cleanup: if (for_user.cksum.contents != NULL) krb5_free_checksum_contents(context, &for_user.cksum); krb5_free_data(context, for_user_data); return code; } /* * This function is invoked by krb5int_make_tgs_request_ext() just before the * request is encoded; it gives us access to the nonce and subkey without * requiring them to be generated by the caller. */ static krb5_error_code build_pa_s4u_x509_user(krb5_context context, krb5_keyblock *subkey, krb5_kdc_req *tgsreq, void *gcvt_data) { krb5_error_code code; krb5_pa_s4u_x509_user *s4u_user = (krb5_pa_s4u_x509_user *)gcvt_data; krb5_data *data = NULL; krb5_cksumtype cksumtype; size_t i; assert(s4u_user->cksum.contents == NULL); s4u_user->user_id.nonce = tgsreq->nonce; code = encode_krb5_s4u_userid(&s4u_user->user_id, &data); if (code != 0) goto cleanup; /* [MS-SFU] 2.2.2: unusual to say the least, but enc_padata secures it */ if (subkey->enctype == ENCTYPE_ARCFOUR_HMAC || subkey->enctype == ENCTYPE_ARCFOUR_HMAC_EXP) { cksumtype = CKSUMTYPE_RSA_MD4; } else { code = krb5int_c_mandatory_cksumtype(context, subkey->enctype, &cksumtype); } if (code != 0) goto cleanup; code = krb5_c_make_checksum(context, cksumtype, subkey, KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST, data, &s4u_user->cksum); if (code != 0) goto cleanup; krb5_free_data(context, data); data = NULL; code = encode_krb5_pa_s4u_x509_user(s4u_user, &data); if (code != 0) goto cleanup; /* Find the empty PA-S4U-X509-USER element placed in the TGS request padata * by krb5_get_self_cred_from_kdc() and replace it with the encoding. */ assert(tgsreq->padata != NULL); for (i = 0; tgsreq->padata[i] != NULL; i++) { if (tgsreq->padata[i]->pa_type == KRB5_PADATA_S4U_X509_USER) break; } assert(tgsreq->padata[i] != NULL); free(tgsreq->padata[i]->contents); tgsreq->padata[i]->length = data->length; tgsreq->padata[i]->contents = (krb5_octet *)data->data; free(data); data = NULL; cleanup: if (code != 0 && s4u_user->cksum.contents != NULL) { krb5_free_checksum_contents(context, &s4u_user->cksum); s4u_user->cksum.contents = NULL; } krb5_free_data(context, data); return code; } /* * Validate the S4U2Self padata in the KDC reply. If update_req_user is true * and the KDC sent S4U-X509-USER padata, replace req_s4u_user->user_id.user * with the checksum-protected client name from the KDC. If update_req_user is * false, verify that the client name has not changed. */ static krb5_error_code verify_s4u2self_reply(krb5_context context, krb5_keyblock *subkey, krb5_pa_s4u_x509_user *req_s4u_user, krb5_pa_data **rep_padata, krb5_pa_data **enc_padata, krb5_boolean update_req_user) { krb5_error_code code; krb5_pa_data *rep_s4u_padata, *enc_s4u_padata; krb5_pa_s4u_x509_user *rep_s4u_user = NULL; krb5_data data, *datap = NULL; krb5_keyusage usage; krb5_boolean valid; krb5_boolean not_newer; assert(req_s4u_user != NULL); switch (subkey->enctype) { case ENCTYPE_DES3_CBC_SHA1: case ENCTYPE_DES3_CBC_RAW: case ENCTYPE_ARCFOUR_HMAC: case ENCTYPE_ARCFOUR_HMAC_EXP : not_newer = TRUE; break; default: not_newer = FALSE; break; } enc_s4u_padata = krb5int_find_pa_data(context, enc_padata, KRB5_PADATA_S4U_X509_USER); rep_s4u_padata = krb5int_find_pa_data(context, rep_padata, KRB5_PADATA_S4U_X509_USER); if (rep_s4u_padata == NULL) return (enc_s4u_padata != NULL) ? KRB5_KDCREP_MODIFIED : 0; data.length = rep_s4u_padata->length; data.data = (char *)rep_s4u_padata->contents; code = decode_krb5_pa_s4u_x509_user(&data, &rep_s4u_user); if (code != 0) goto cleanup; if (rep_s4u_user->user_id.nonce != req_s4u_user->user_id.nonce) { code = KRB5_KDCREP_MODIFIED; goto cleanup; } code = encode_krb5_s4u_userid(&rep_s4u_user->user_id, &datap); if (code != 0) goto cleanup; if (rep_s4u_user->user_id.options & KRB5_S4U_OPTS_USE_REPLY_KEY_USAGE) usage = KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY; else usage = KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST; code = krb5_c_verify_checksum(context, subkey, usage, datap, &rep_s4u_user->cksum, &valid); if (code != 0) goto cleanup; if (valid == FALSE) { code = KRB5_KDCREP_MODIFIED; goto cleanup; } if (rep_s4u_user->user_id.user == NULL || rep_s4u_user->user_id.user->length == 0) { code = KRB5_KDCREP_MODIFIED; goto cleanup; } if (update_req_user) { krb5_free_principal(context, req_s4u_user->user_id.user); code = krb5_copy_principal(context, rep_s4u_user->user_id.user, &req_s4u_user->user_id.user); if (code != 0) goto cleanup; } else if (!krb5_principal_compare(context, rep_s4u_user->user_id.user, req_s4u_user->user_id.user)) { code = KRB5_KDCREP_MODIFIED; goto cleanup; } /* * KDCs that support KRB5_S4U_OPTS_USE_REPLY_KEY_USAGE also return * S4U enc_padata for older (pre-AES) encryption types only. */ if (not_newer) { if (enc_s4u_padata == NULL) { if (rep_s4u_user->user_id.options & KRB5_S4U_OPTS_USE_REPLY_KEY_USAGE) { code = KRB5_KDCREP_MODIFIED; goto cleanup; } } else { if (enc_s4u_padata->length != req_s4u_user->cksum.length + rep_s4u_user->cksum.length) { code = KRB5_KDCREP_MODIFIED; goto cleanup; } if (memcmp(enc_s4u_padata->contents, req_s4u_user->cksum.contents, req_s4u_user->cksum.length) || memcmp(&enc_s4u_padata->contents[req_s4u_user->cksum.length], rep_s4u_user->cksum.contents, rep_s4u_user->cksum.length)) { code = KRB5_KDCREP_MODIFIED; goto cleanup; } } } else if (!krb5_c_is_keyed_cksum(rep_s4u_user->cksum.checksum_type)) { code = KRB5KRB_AP_ERR_INAPP_CKSUM; goto cleanup; } cleanup: krb5_free_pa_s4u_x509_user(context, rep_s4u_user); krb5_free_data(context, datap); return code; } /* Unparse princ and re-parse it as an enterprise principal. */ static krb5_error_code convert_to_enterprise(krb5_context context, krb5_principal princ, krb5_principal *eprinc_out) { krb5_error_code code; char *str; *eprinc_out = NULL; code = krb5_unparse_name(context, princ, &str); if (code != 0) return code; code = krb5_parse_name_flags(context, str, KRB5_PRINCIPAL_PARSE_ENTERPRISE | KRB5_PRINCIPAL_PARSE_IGNORE_REALM, eprinc_out); krb5_free_unparsed_name(context, str); return code; } static krb5_error_code krb5_get_self_cred_from_kdc(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_data *subject_cert, krb5_data *user_realm, krb5_creds **out_creds) { krb5_error_code code; krb5_principal tgs = NULL, eprinc = NULL; krb5_principal_data sprinc; krb5_creds tgtq, s4u_creds, *tgt = NULL, *tgtptr; krb5_creds *referral_tgts[KRB5_REFERRAL_MAXHOPS]; krb5_pa_s4u_x509_user s4u_user; int referral_count = 0, i; krb5_flags kdcopt; memset(&tgtq, 0, sizeof(tgtq)); memset(referral_tgts, 0, sizeof(referral_tgts)); *out_creds = NULL; memset(&s4u_user, 0, sizeof(s4u_user)); if (in_creds->client != NULL && in_creds->client->length > 0) { if (in_creds->client->type == KRB5_NT_ENTERPRISE_PRINCIPAL) { code = krb5_build_principal_ext(context, &s4u_user.user_id.user, user_realm->length, user_realm->data, in_creds->client->data[0].length, in_creds->client->data[0].data, 0); if (code != 0) goto cleanup; s4u_user.user_id.user->type = KRB5_NT_ENTERPRISE_PRINCIPAL; } else { code = krb5_copy_principal(context, in_creds->client, &s4u_user.user_id.user); if (code != 0) goto cleanup; } } else { code = krb5_build_principal_ext(context, &s4u_user.user_id.user, user_realm->length, user_realm->data, 0); if (code != 0) goto cleanup; } if (subject_cert != NULL) s4u_user.user_id.subject_cert = *subject_cert; s4u_user.user_id.options = KRB5_S4U_OPTS_USE_REPLY_KEY_USAGE; /* First, acquire a TGT to the user's realm. */ code = krb5int_tgtname(context, user_realm, &in_creds->server->realm, &tgs); if (code != 0) goto cleanup; tgtq.client = in_creds->server; tgtq.server = tgs; code = krb5_get_credentials(context, options, ccache, &tgtq, &tgt); if (code != 0) goto cleanup; tgtptr = tgt; /* Convert the server principal to an enterprise principal, for use with * foreign realms. */ code = convert_to_enterprise(context, in_creds->server, &eprinc); if (code != 0) goto cleanup; /* Make a shallow copy of in_creds with client pointing to the server * principal. We will set s4u_creds.server for each request. */ s4u_creds = *in_creds; s4u_creds.client = in_creds->server; /* Then, walk back the referral path to S4U2Self for user */ kdcopt = 0; if (options & KRB5_GC_CANONICALIZE) kdcopt |= KDC_OPT_CANONICALIZE; if (options & KRB5_GC_FORWARDABLE) kdcopt |= KDC_OPT_FORWARDABLE; if (options & KRB5_GC_NO_TRANSIT_CHECK) kdcopt |= KDC_OPT_DISABLE_TRANSITED_CHECK; for (referral_count = 0; referral_count < KRB5_REFERRAL_MAXHOPS; referral_count++) { krb5_pa_data **in_padata = NULL; krb5_pa_data **out_padata = NULL; krb5_pa_data **enc_padata = NULL; krb5_keyblock *subkey = NULL; in_padata = k5calloc(3, sizeof(krb5_pa_data *), &code); if (in_padata == NULL) goto cleanup; in_padata[0] = k5alloc(sizeof(krb5_pa_data), &code); if (in_padata[0] == NULL) { krb5_free_pa_data(context, in_padata); goto cleanup; } in_padata[0]->magic = KV5M_PA_DATA; in_padata[0]->pa_type = KRB5_PADATA_S4U_X509_USER; in_padata[0]->length = 0; in_padata[0]->contents = NULL; if (s4u_user.user_id.user != NULL && s4u_user.user_id.user->length) { code = build_pa_for_user(context, tgtptr, &s4u_user.user_id, &in_padata[1]); /* * If we couldn't compute the hmac-md5 checksum, send only the * KRB5_PADATA_S4U_X509_USER; this will still work against modern * Windows and MIT KDCs. */ if (code == KRB5_CRYPTO_INTERNAL) code = 0; if (code != 0) { krb5_free_pa_data(context, in_padata); goto cleanup; } } if (data_eq(tgtptr->server->data[1], in_creds->server->realm)) { /* When asking the server realm, use the real principal. */ s4u_creds.server = in_creds->server; } else { /* When asking a foreign realm, use the enterprise principal, with * the realm set to the TGS realm. */ sprinc = *eprinc; sprinc.realm = tgtptr->server->data[1]; s4u_creds.server = &sprinc; } code = krb5_get_cred_via_tkt_ext(context, tgtptr, KDC_OPT_CANONICALIZE | FLAGS2OPTS(tgtptr->ticket_flags) | kdcopt, tgtptr->addresses, in_padata, &s4u_creds, build_pa_s4u_x509_user, &s4u_user, &out_padata, &enc_padata, out_creds, &subkey); if (code != 0) { krb5_free_checksum_contents(context, &s4u_user.cksum); krb5_free_pa_data(context, in_padata); goto cleanup; } /* Update s4u_user.user_id.user if this is the initial request to the * client realm; otherwise verify that it doesn't change. */ code = verify_s4u2self_reply(context, subkey, &s4u_user, out_padata, enc_padata, referral_count == 0); krb5_free_checksum_contents(context, &s4u_user.cksum); krb5_free_pa_data(context, in_padata); krb5_free_pa_data(context, out_padata); krb5_free_pa_data(context, enc_padata); krb5_free_keyblock(context, subkey); if (code != 0) goto cleanup; /* The authdata in this referral TGT will be copied into the final * credentials, so we don't need to request it again. */ s4u_creds.authdata = NULL; /* Only include a cert in the initial request to the client realm. */ s4u_user.user_id.subject_cert = empty_data(); if (krb5_principal_compare_any_realm(context, in_creds->server, (*out_creds)->server)) { /* Verify that the unprotected client name in the reply matches the * checksum-protected one from the client realm's KDC padata. */ if (!krb5_principal_compare(context, (*out_creds)->client, s4u_user.user_id.user)) code = KRB5_KDCREP_MODIFIED; goto cleanup; } else if (IS_TGS_PRINC((*out_creds)->server)) { krb5_data *r1 = &tgtptr->server->data[1]; krb5_data *r2 = &(*out_creds)->server->data[1]; if (data_eq(*r1, *r2)) { krb5_free_creds(context, *out_creds); *out_creds = NULL; code = KRB5_ERR_HOST_REALM_UNKNOWN; break; } for (i = 0; i < referral_count; i++) { if (krb5_principal_compare(context, (*out_creds)->server, referral_tgts[i]->server)) { code = KRB5_KDC_UNREACH; goto cleanup; } } tgtptr = *out_creds; referral_tgts[referral_count] = *out_creds; *out_creds = NULL; } else { krb5_free_creds(context, *out_creds); *out_creds = NULL; code = KRB5KRB_AP_WRONG_PRINC; /* XXX */ break; } } cleanup: for (i = 0; i < KRB5_REFERRAL_MAXHOPS; i++) { if (referral_tgts[i] != NULL) krb5_free_creds(context, referral_tgts[i]); } krb5_free_principal(context, tgs); krb5_free_principal(context, eprinc); krb5_free_creds(context, tgt); krb5_free_principal(context, s4u_user.user_id.user); krb5_free_checksum_contents(context, &s4u_user.cksum); return code; } krb5_error_code KRB5_CALLCONV krb5_get_credentials_for_user(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_data *subject_cert, krb5_creds **out_creds) { krb5_error_code code; krb5_principal realm = NULL; *out_creds = NULL; if (options & KRB5_GC_CONSTRAINED_DELEGATION) { code = EINVAL; goto cleanup; } if (in_creds->client != NULL) { /* Uncanonicalised check */ code = krb5_get_credentials(context, options | KRB5_GC_CACHED, ccache, in_creds, out_creds); if ((code != KRB5_CC_NOTFOUND && code != KRB5_CC_NOT_KTYPE) || (options & KRB5_GC_CACHED)) goto cleanup; } else if (options & KRB5_GC_CACHED) { /* Fail immediately, since we can't check the cache by certificate. */ code = KRB5_CC_NOTFOUND; goto cleanup; } code = s4u_identify_user(context, in_creds, subject_cert, &realm); if (code != 0) goto cleanup; if (in_creds->client != NULL && in_creds->client->type == KRB5_NT_ENTERPRISE_PRINCIPAL) { /* Post-canonicalisation check for enterprise principals */ krb5_creds mcreds = *in_creds; mcreds.client = realm; code = krb5_get_credentials(context, options | KRB5_GC_CACHED, ccache, &mcreds, out_creds); if (code != KRB5_CC_NOTFOUND && code != KRB5_CC_NOT_KTYPE) goto cleanup; } code = krb5_get_self_cred_from_kdc(context, options, ccache, in_creds, subject_cert, &realm->realm, out_creds); if (code != 0) goto cleanup; assert(*out_creds != NULL); /* If we canonicalized the client name or discovered it using subject_cert, * check if we had cached credentials and return them if found. */ if (in_creds->client == NULL || !krb5_principal_compare(context, in_creds->client, (*out_creds)->client)) { krb5_creds *old_creds; krb5_creds mcreds = *in_creds; mcreds.client = (*out_creds)->client; code = krb5_get_credentials(context, options | KRB5_GC_CACHED, ccache, &mcreds, &old_creds); if (code == 0) { krb5_free_creds(context, *out_creds); *out_creds = old_creds; options |= KRB5_GC_NO_STORE; } else if (code != KRB5_CC_NOTFOUND && code != KRB5_CC_NOT_KTYPE) { goto cleanup; } } /* Note the authdata we asked for in the output creds. */ code = krb5_copy_authdata(context, in_creds->authdata, &(*out_creds)->authdata); if (code) goto cleanup; if ((options & KRB5_GC_NO_STORE) == 0) { code = krb5_cc_store_cred(context, ccache, *out_creds); if (code != 0) goto cleanup; } cleanup: if (code != 0 && *out_creds != NULL) { krb5_free_creds(context, *out_creds); *out_creds = NULL; } krb5_free_principal(context, realm); return code; } static krb5_error_code check_rbcd_support(krb5_context context, krb5_pa_data **padata) { krb5_error_code code; krb5_pa_data *pa; krb5_pa_pac_options *pac_options; krb5_data der_pac_options; pa = krb5int_find_pa_data(context, padata, KRB5_PADATA_PAC_OPTIONS); if (pa == NULL) return KRB5KDC_ERR_PADATA_TYPE_NOSUPP; der_pac_options = make_data(pa->contents, pa->length); code = decode_krb5_pa_pac_options(&der_pac_options, &pac_options); if (code) return code; if (!(pac_options->options & KRB5_PA_PAC_OPTIONS_RBCD)) code = KRB5KDC_ERR_PADATA_TYPE_NOSUPP; free(pac_options); return code; } static krb5_error_code add_rbcd_padata(krb5_context context, krb5_pa_data ***in_padata) { krb5_error_code code; krb5_pa_pac_options pac_options; krb5_data *der_pac_options = NULL; memset(&pac_options, 0, sizeof(pac_options)); pac_options.options |= KRB5_PA_PAC_OPTIONS_RBCD; code = encode_krb5_pa_pac_options(&pac_options, &der_pac_options); if (code) return code; code = k5_add_pa_data_from_data(in_padata, KRB5_PADATA_PAC_OPTIONS, der_pac_options); krb5_free_data(context, der_pac_options); return code; } /* Set *tgt_out to a local TGT for the client realm retrieved from ccache. */ static krb5_error_code get_client_tgt(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_principal client, krb5_creds **tgt_out) { krb5_error_code code; krb5_principal tgs; krb5_creds mcreds; *tgt_out = NULL; code = krb5int_tgtname(context, &client->realm, &client->realm, &tgs); if (code) return code; memset(&mcreds, 0, sizeof(mcreds)); mcreds.client = client; mcreds.server = tgs; code = krb5_get_credentials(context, options, ccache, &mcreds, tgt_out); krb5_free_principal(context, tgs); return code; } /* * Copy req_server to *out_server. If req_server has the referral realm, set * the realm of *out_server to realm. Otherwise the S4U2Proxy request will * fail unless the specified realm is the same as the TGT (or an alias to it). */ static krb5_error_code normalize_server_princ(krb5_context context, const krb5_data *realm, krb5_principal req_server, krb5_principal *out_server) { krb5_error_code code; krb5_principal server; *out_server = NULL; code = krb5_copy_principal(context, req_server, &server); if (code) return code; if (krb5_is_referral_realm(&server->realm)) { krb5_free_data_contents(context, &server->realm); code = krb5int_copy_data_contents(context, realm, &server->realm); if (code) { krb5_free_principal(context, server); return code; } } *out_server = server; return 0; } /* Return an error if server is present in referral_list. */ static krb5_error_code check_referral_path(krb5_context context, krb5_principal server, krb5_creds **referral_list, int referral_count) { int i; for (i = 0; i < referral_count; i++) { if (krb5_principal_compare(context, server, referral_list[i]->server)) return KRB5_KDC_UNREACH; } return 0; } /* * Make TGS requests for in_creds using *tgt_inout, following referrals until * the requested service ticket is issued. Replace *tgt_inout with the final * TGT used, or free it and set it to NULL on error. Place the final creds * received in *creds_out. */ static krb5_error_code chase_referrals(krb5_context context, krb5_creds *in_creds, krb5_flags kdcopt, krb5_creds **tgt_inout, krb5_creds **creds_out) { krb5_error_code code; krb5_creds *referral_tgts[KRB5_REFERRAL_MAXHOPS] = { NULL }; krb5_creds mcreds, *tgt, *tkt = NULL; krb5_principal_data server; int referral_count = 0, i; tgt = *tgt_inout; *tgt_inout = NULL; *creds_out = NULL; mcreds = *in_creds; server = *in_creds->server; mcreds.server = &server; for (referral_count = 0; referral_count < KRB5_REFERRAL_MAXHOPS; referral_count++) { code = krb5_get_cred_via_tkt(context, tgt, kdcopt, tgt->addresses, &mcreds, &tkt); if (code) goto cleanup; if (krb5_principal_compare_any_realm(context, mcreds.server, tkt->server)) { *creds_out = tkt; *tgt_inout = tgt; tkt = tgt = NULL; goto cleanup; } if (!IS_TGS_PRINC(tkt->server)) { code = KRB5KRB_AP_WRONG_PRINC; goto cleanup; } if (data_eq(tgt->server->data[1], tkt->server->data[1])) { code = KRB5_ERR_HOST_REALM_UNKNOWN; goto cleanup; } code = check_referral_path(context, tkt->server, referral_tgts, referral_count); if (code) goto cleanup; referral_tgts[referral_count] = tgt; tgt = tkt; tkt = NULL; server.realm = tgt->server->data[1]; } /* Max hop count exceeded. */ code = KRB5_KDCREP_MODIFIED; cleanup: for (i = 0; i < KRB5_REFERRAL_MAXHOPS; i++) krb5_free_creds(context, referral_tgts[i]); krb5_free_creds(context, tkt); krb5_free_creds(context, tgt); return code; } /* * Make non-S4U2Proxy TGS requests for in_creds using *tgt_inout, following * referrals until the requested service ticket is returned. Discard the * service ticket, but replace *tgt_inout with the final referral TGT. */ static krb5_error_code get_tgt_to_target_realm(krb5_context context, krb5_creds *in_creds, krb5_flags req_kdcopt, krb5_creds **tgt_inout) { krb5_error_code code; krb5_flags kdcopt; krb5_creds mcreds, *out; mcreds = *in_creds; mcreds.second_ticket = empty_data(); kdcopt = FLAGS2OPTS((*tgt_inout)->ticket_flags) | req_kdcopt; code = chase_referrals(context, &mcreds, kdcopt, tgt_inout, &out); krb5_free_creds(context, out); return code; } /* * Make TGS requests for a cross-TGT to realm using *tgt_inout, following * alternate TGS replies until the requested TGT is issued. Replace *tgt_inout * with the result. Do nothing if *tgt_inout is already a cross-TGT for realm. */ static krb5_error_code get_target_realm_proxy_tgt(krb5_context context, const krb5_data *realm, krb5_flags req_kdcopt, krb5_creds **tgt_inout) { krb5_error_code code; krb5_creds mcreds, *out; krb5_principal tgs; krb5_flags flags; if (data_eq(*realm, (*tgt_inout)->server->data[1])) return 0; code = krb5int_tgtname(context, realm, &(*tgt_inout)->server->data[1], &tgs); if (code) return code; memset(&mcreds, 0, sizeof(mcreds)); mcreds.client = (*tgt_inout)->client; mcreds.server = tgs; flags = req_kdcopt | FLAGS2OPTS((*tgt_inout)->ticket_flags); code = chase_referrals(context, &mcreds, flags, tgt_inout, &out); krb5_free_principal(context, tgs); if (code) return code; krb5_free_creds(context, *tgt_inout); *tgt_inout = out; return 0; } static krb5_error_code get_proxy_cred_from_kdc(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **out_creds) { krb5_error_code code; krb5_flags flags, req_kdcopt = 0; krb5_principal server = NULL; krb5_pa_data **in_padata = NULL; krb5_pa_data **enc_padata = NULL; krb5_creds mcreds, *tgt = NULL, *tkt = NULL; *out_creds = NULL; if (in_creds->second_ticket.length == 0 || (options & KRB5_GC_CONSTRAINED_DELEGATION) == 0) return EINVAL; options &= ~KRB5_GC_CONSTRAINED_DELEGATION; code = get_client_tgt(context, options, ccache, in_creds->client, &tgt); if (code) goto cleanup; code = normalize_server_princ(context, &in_creds->client->realm, in_creds->server, &server); if (code) goto cleanup; code = add_rbcd_padata(context, &in_padata); if (code) goto cleanup; if (options & KRB5_GC_CANONICALIZE) req_kdcopt |= KDC_OPT_CANONICALIZE; if (options & KRB5_GC_FORWARDABLE) req_kdcopt |= KDC_OPT_FORWARDABLE; if (options & KRB5_GC_NO_TRANSIT_CHECK) req_kdcopt |= KDC_OPT_DISABLE_TRANSITED_CHECK; mcreds = *in_creds; mcreds.server = server; flags = req_kdcopt | FLAGS2OPTS(tgt->ticket_flags) | KDC_OPT_CNAME_IN_ADDL_TKT | KDC_OPT_CANONICALIZE; code = krb5_get_cred_via_tkt_ext(context, tgt, flags, tgt->addresses, in_padata, &mcreds, NULL, NULL, NULL, &enc_padata, &tkt, NULL); /* * If the server principal name included a foreign realm which wasn't an * alias for the local realm, the KDC won't be able to decrypt the TGT. * Windows KDCs will return a BAD_INTEGRITY error in this case, while MIT * KDCs will return S_PRINCIPAL_UNKNOWN. We cannot distinguish the latter * error from the service principal actually being unknown in the realm, * but set a comprehensible error message for the BAD_INTEGRITY error. */ if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY && !krb5_realm_compare(context, in_creds->client, server)) { k5_setmsg(context, code, _("Realm specified but S4U2Proxy must use " "referral realm")); } if (code) goto cleanup; if (!krb5_principal_compare_any_realm(context, server, tkt->server)) { /* Make sure we got a referral. */ if (!IS_TGS_PRINC(tkt->server)) { code = KRB5KRB_AP_WRONG_PRINC; goto cleanup; } /* The authdata in this referral TGT will be copied into the final * credentials, so we don't need to request it again. */ mcreds.authdata = NULL; /* * Make sure the KDC supports S4U and resource-based constrained * delegation; otherwise we might have gotten a regular TGT referral * rather than a proxy TGT referral. */ code = check_rbcd_support(context, enc_padata); if (code) goto cleanup; krb5_free_pa_data(context, enc_padata); enc_padata = NULL; /* * Replace tgt with a regular (not proxy) TGT to the target realm, by * making a normal TGS request and following referrals. Per [MS-SFU] * 3.1.5.2.2, we need this TGT to make the final TGS request. */ code = get_tgt_to_target_realm(context, &mcreds, req_kdcopt, &tgt); if (code) goto cleanup; /* * Replace tkt with a proxy TGT (meaning, one obtained using the * referral TGT we got from the first S4U2Proxy request) to the target * realm, if it isn't already one. */ code = get_target_realm_proxy_tgt(context, &tgt->server->data[1], req_kdcopt, &tkt); if (code) goto cleanup; krb5_free_data_contents(context, &server->realm); code = krb5int_copy_data_contents(context, &tgt->server->data[1], &server->realm); if (code) goto cleanup; /* Make an S4U2Proxy request to the target realm using the regular TGT, * with the proxy TGT as the evidence ticket. */ mcreds.second_ticket = tkt->ticket; tkt->ticket = empty_data(); krb5_free_creds(context, tkt); tkt = NULL; flags = req_kdcopt | FLAGS2OPTS(tgt->ticket_flags) | KDC_OPT_CNAME_IN_ADDL_TKT | KDC_OPT_CANONICALIZE; code = krb5_get_cred_via_tkt_ext(context, tgt, flags, tgt->addresses, in_padata, &mcreds, NULL, NULL, NULL, &enc_padata, &tkt, NULL); free(mcreds.second_ticket.data); if (code) goto cleanup; code = check_rbcd_support(context, enc_padata); if (code) goto cleanup; if (!krb5_principal_compare(context, server, tkt->server)) { code = KRB5KRB_AP_WRONG_PRINC; goto cleanup; } /* Put the original evidence ticket in the output creds. */ krb5_free_data_contents(context, &tkt->second_ticket); code = krb5int_copy_data_contents(context, &in_creds->second_ticket, &tkt->second_ticket); if (code) goto cleanup; } /* Note the authdata we asked for in the output creds. */ code = krb5_copy_authdata(context, in_creds->authdata, &tkt->authdata); if (code) goto cleanup; *out_creds = tkt; tkt = NULL; cleanup: krb5_free_creds(context, tgt); krb5_free_creds(context, tkt); krb5_free_principal(context, server); krb5_free_pa_data(context, in_padata); krb5_free_pa_data(context, enc_padata); return code; } krb5_error_code k5_get_proxy_cred_from_kdc(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **out_creds) { krb5_error_code code; krb5_const_principal canonprinc; krb5_creds copy, *creds; struct canonprinc iter = { in_creds->server, .no_hostrealm = TRUE }; *out_creds = NULL; code = k5_get_cached_cred(context, options, ccache, in_creds, out_creds); if ((code != KRB5_CC_NOTFOUND && code != KRB5_CC_NOT_KTYPE) || options & KRB5_GC_CACHED) return code; copy = *in_creds; while ((code = k5_canonprinc(context, &iter, &canonprinc)) == 0 && canonprinc != NULL) { copy.server = (krb5_principal)canonprinc; code = get_proxy_cred_from_kdc(context, options, ccache, ©, &creds); if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) break; } if (!code && canonprinc == NULL) code = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; free_canonprinc(&iter); if (code) return code; krb5_free_principal(context, creds->server); creds->server = NULL; code = krb5_copy_principal(context, in_creds->server, &creds->server); if (code) { krb5_free_creds(context, creds); return code; } if (!(options & KRB5_GC_NO_STORE)) (void)krb5_cc_store_cred(context, ccache, creds); *out_creds = creds; return 0; } /* * Exported API for constrained delegation (S4U2Proxy). * * This is preferable to using krb5_get_credentials directly because * it can perform some additional checks. */ krb5_error_code KRB5_CALLCONV krb5_get_credentials_for_proxy(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_ticket *evidence_tkt, krb5_creds **out_creds) { krb5_error_code code; krb5_data *evidence_tkt_data = NULL; krb5_creds s4u_creds; *out_creds = NULL; if (in_creds == NULL || in_creds->client == NULL || evidence_tkt == NULL) { code = EINVAL; goto cleanup; } /* * Caller should have set in_creds->client to match evidence * ticket client. If we can, verify it before issuing the request. */ if (evidence_tkt->enc_part2 != NULL && !krb5_principal_compare(context, evidence_tkt->enc_part2->client, in_creds->client)) { code = EINVAL; goto cleanup; } code = encode_krb5_ticket(evidence_tkt, &evidence_tkt_data); if (code != 0) goto cleanup; s4u_creds = *in_creds; s4u_creds.client = evidence_tkt->server; s4u_creds.second_ticket = *evidence_tkt_data; code = k5_get_proxy_cred_from_kdc(context, options | KRB5_GC_CONSTRAINED_DELEGATION, ccache, &s4u_creds, out_creds); if (code != 0) goto cleanup; /* * Check client name because we couldn't compare that inside * krb5_get_credentials() (enc_part2 is unavailable in clear) */ if (!krb5_principal_compare(context, in_creds->client, (*out_creds)->client)) { code = KRB5_KDCREP_MODIFIED; goto cleanup; } cleanup: if (*out_creds != NULL && code != 0) { krb5_free_creds(context, *out_creds); *out_creds = NULL; } if (evidence_tkt_data != NULL) krb5_free_data(context, evidence_tkt_data); return code; } krb5-1.22.1/src/lib/krb5/krb/parse_host_string.c0000664000175000017500000000770115051422640021225 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/parse_host_string.c - Parse host strings into host and port */ /* * Copyright (C) 2016 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include /* Return true if s is composed solely of digits. */ krb5_boolean k5_is_string_numeric(const char *s) { if (*s == '\0') return FALSE; for (; *s != '\0'; s++) { if (!isdigit(*s)) return FALSE; } return TRUE; } /* * Parse a string containing a host specifier. The expected format for the * string is: * * host[:port] or port * * host and port are optional, though one must be present. host may have * brackets around it for IPv6 addresses. * * Arguments: * address - The address string that should be parsed. * default_port - The default port to use if no port is found. * host_out - An output pointer for the parsed host, or NULL if no host was * specified or an error occurred. Must be freed. * port_out - An output pointer for the parsed port. Will be 0 on error. * * Returns 0 on success, otherwise an error. */ krb5_error_code k5_parse_host_string(const char *address, int default_port, char **host_out, int *port_out) { krb5_error_code ret; int port_num; const char *p, *host = NULL, *port = NULL; char *endptr, *hostname = NULL; size_t hostlen = 0; unsigned long l; *host_out = NULL; *port_out = 0; if (address == NULL || *address == '\0' || *address == ':') return EINVAL; if (default_port < 0 || default_port > 65535) return EINVAL; /* Find the bounds of the host string and the start of the port string. */ if (k5_is_string_numeric(address)) { port = address; } else if (*address == '[' && (p = strchr(address, ']')) != NULL) { host = address + 1; hostlen = p - host; if (*(p + 1) == ':') port = p + 2; } else { host = address; hostlen = strcspn(host, " \t:"); if (host[hostlen] == ':') port = host + hostlen + 1; } /* Parse the port number, or use the default port. */ if (port != NULL) { errno = 0; l = strtoul(port, &endptr, 10); if (errno || endptr == port || *endptr != '\0' || l > 65535) return EINVAL; port_num = l; } else { port_num = default_port; } /* Copy the host if it was specified. */ if (host != NULL) { hostname = k5memdup0(host, hostlen, &ret); if (hostname == NULL) return ENOMEM; } *host_out = hostname; *port_out = port_num; return 0; } krb5-1.22.1/src/lib/krb5/krb/mk_safe.c0000664000175000017500000001430215051422640017070 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/mk_safe.c - definition of krb5_mk_safe() */ /* * Copyright 1990,1991,2019 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "int-proto.h" #include "auth_con.h" /* * Marshal a KRB-SAFE message into der_out, with a keyed checksum of type * sumtype. Store the checksum in cksum_out. Use the timestamp and sequence * number from rdata and the addresses from local_addr and remote_addr (the * second of which may be NULL). der_out and cksum_out should be freed by the * caller when finished. */ static krb5_error_code create_krbsafe(krb5_context context, const krb5_data *userdata, krb5_key key, const krb5_replay_data *rdata, krb5_address *local_addr, krb5_address *remote_addr, krb5_cksumtype sumtype, krb5_data *der_out, krb5_checksum *cksum_out) { krb5_error_code ret; krb5_safe safemsg; krb5_octet zero_octet = 0; krb5_checksum safe_checksum; krb5_data *der_krbsafe; if (sumtype && !krb5_c_valid_cksumtype(sumtype)) return KRB5_PROG_SUMTYPE_NOSUPP; if (sumtype && !krb5_c_is_keyed_cksum(sumtype)) return KRB5KRB_AP_ERR_INAPP_CKSUM; safemsg.user_data = *userdata; safemsg.s_address = local_addr; safemsg.r_address = remote_addr; safemsg.timestamp = rdata->timestamp; safemsg.usec = rdata->usec; safemsg.seq_number = rdata->seq; /* Encode the message with a zero-length zero-type checksum. */ safe_checksum.length = 0; safe_checksum.checksum_type = 0; safe_checksum.contents = &zero_octet; safemsg.checksum = &safe_checksum; ret = encode_krb5_safe(&safemsg, &der_krbsafe); if (ret) return ret; /* Checksum the encoding. */ ret = krb5_k_make_checksum(context, sumtype, key, KRB5_KEYUSAGE_KRB_SAFE_CKSUM, der_krbsafe, &safe_checksum); zapfreedata(der_krbsafe); if (ret) return ret; /* Encode the message again with the real checksum. */ safemsg.checksum = &safe_checksum; ret = encode_krb5_safe(&safemsg, &der_krbsafe); if (ret) { krb5_free_checksum_contents(context, &safe_checksum); return ret; } *der_out = *der_krbsafe; free(der_krbsafe); *cksum_out = safe_checksum; return 0; } /* Return the checksum type for the KRB-SAFE message, or 0 to use the enctype's * mandatory checksum. */ static krb5_cksumtype safe_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_enctype enctype) { krb5_error_code ret; unsigned int nsumtypes, i; krb5_cksumtype *sumtypes; /* Use the auth context's safe_cksumtype if it is valid for the enctype. * Otherwise return 0 for the mandatory checksum. */ ret = krb5_c_keyed_checksum_types(context, enctype, &nsumtypes, &sumtypes); if (ret != 0) return 0; for (i = 0; i < nsumtypes; i++) { if (auth_context->safe_cksumtype == sumtypes[i]) break; } krb5_free_cksumtypes(context, sumtypes); return (i == nsumtypes) ? 0 : auth_context->safe_cksumtype; } krb5_error_code KRB5_CALLCONV krb5_mk_safe(krb5_context context, krb5_auth_context authcon, const krb5_data *userdata, krb5_data *der_out, krb5_replay_data *rdata_out) { krb5_error_code ret; krb5_key key; krb5_replay_data rdata; krb5_data der_krbsafe = empty_data(); krb5_checksum cksum; krb5_address *local_addr, *remote_addr, lstorage, rstorage; krb5_cksumtype sumtype; *der_out = empty_data(); memset(&cksum, 0, sizeof(cksum)); memset(&lstorage, 0, sizeof(lstorage)); memset(&rstorage, 0, sizeof(rstorage)); if (authcon->local_addr == NULL) return KRB5_LOCAL_ADDR_REQUIRED; ret = k5_privsafe_gen_rdata(context, authcon, &rdata, rdata_out); if (ret) goto cleanup; ret = k5_privsafe_gen_addrs(context, authcon, &lstorage, &rstorage, &local_addr, &remote_addr); if (ret) goto cleanup; key = (authcon->send_subkey != NULL) ? authcon->send_subkey : authcon->key; sumtype = safe_cksumtype(context, authcon, key->keyblock.enctype); ret = create_krbsafe(context, userdata, key, &rdata, local_addr, remote_addr, sumtype, &der_krbsafe, &cksum); if (ret) goto cleanup; ret = k5_privsafe_check_replay(context, authcon, NULL, NULL, &cksum); if (ret) goto cleanup; *der_out = der_krbsafe; der_krbsafe = empty_data(); if ((authcon->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) || (authcon->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) authcon->local_seq_number++; cleanup: krb5_free_data_contents(context, &der_krbsafe); krb5_free_checksum_contents(context, &cksum); free(lstorage.contents); free(rstorage.contents); return ret; } krb5-1.22.1/src/lib/krb5/krb/etype_list.c0000664000175000017500000000432415051422640017647 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/etype_list.c */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * Helper functions related to zero-terminated lists of enctypes. */ #include "k5-int.h" #include "int-proto.h" size_t k5_count_etypes(const krb5_enctype *list) { size_t count; for (count = 0; list[count]; count++); return count; } /* Copy the zero-terminated enctype list old_list into *new_list. */ krb5_error_code k5_copy_etypes(const krb5_enctype *old_list, krb5_enctype **new_list) { size_t count; krb5_enctype *list; *new_list = NULL; if (old_list == NULL) return 0; count = k5_count_etypes(old_list); list = malloc(sizeof(krb5_enctype) * (count + 1)); if (list == NULL) return ENOMEM; memcpy(list, old_list, sizeof(krb5_enctype) * (count + 1)); *new_list = list; return 0; } krb5_boolean k5_etypes_contains(const krb5_enctype *list, krb5_enctype etype) { size_t i; for (i = 0; list[i] && list[i] != etype; i++); return (list[i] == etype); } krb5-1.22.1/src/lib/krb5/krb/gic_keytab.c0000664000175000017500000003125115051422640017566 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/gic_keytab.c */ /* * Copyright (C) 2002, 2003, 2008 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef LEAN_CLIENT #include "k5-int.h" #include "int-proto.h" #include "os-proto.h" #include "init_creds_ctx.h" static krb5_error_code get_as_key_keytab(krb5_context context, krb5_principal client, krb5_enctype etype, krb5_prompter_fct prompter, void *prompter_data, krb5_data *salt, krb5_data *params, krb5_keyblock *as_key, void *gak_data, k5_response_items *ritems) { krb5_keytab keytab = (krb5_keytab) gak_data; krb5_error_code ret; krb5_keytab_entry kt_ent; /* We don't need the password from the responder to create the AS key. */ if (as_key == NULL) return 0; /* if there's already a key of the correct etype, we're done. if the etype is wrong, free the existing key, and make a new one. */ if (as_key->length) { if (as_key->enctype == etype) return(0); krb5_free_keyblock_contents(context, as_key); as_key->length = 0; } if (!krb5_c_valid_enctype(etype)) return(KRB5_PROG_ETYPE_NOSUPP); if ((ret = krb5_kt_get_entry(context, keytab, client, 0, /* don't have vno available */ etype, &kt_ent))) return(ret); /* Steal the keyblock from kt_ent for the caller. */ *as_key = kt_ent.key; memset(&kt_ent.key, 0, sizeof(kt_ent.key)); (void) krb5_kt_free_entry(context, &kt_ent); return 0; } /* Return the list of etypes available for client in keytab. */ static krb5_error_code lookup_etypes_for_keytab(krb5_context context, krb5_keytab keytab, krb5_const_principal client, krb5_enctype **etypes_out) { krb5_kt_cursor cursor; krb5_keytab_entry entry; krb5_enctype *p, *etypes = NULL, etype; krb5_kvno max_kvno = 0, vno; krb5_error_code ret; krb5_boolean match; size_t count = 0; *etypes_out = NULL; if (keytab->ops->start_seq_get == NULL) return EINVAL; ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret != 0) return ret; while (!(ret = krb5_kt_next_entry(context, keytab, &entry, &cursor))) { /* Extract what we need from the entry and free it. */ etype = entry.key.enctype; vno = entry.vno; match = krb5_principal_compare(context, entry.principal, client); krb5_free_keytab_entry_contents(context, &entry); /* Filter out old or non-matching entries and invalid enctypes. */ if (vno < max_kvno || !match || !krb5_c_valid_enctype(etype)) continue; /* Update max_kvno and reset the list if we find a newer kvno. */ if (vno > max_kvno) { max_kvno = vno; free(etypes); etypes = NULL; count = 0; } /* Leave room for the terminator and possibly a second entry. */ p = realloc(etypes, (count + 3) * sizeof(*etypes)); if (p == NULL) { ret = ENOMEM; goto cleanup; } etypes = p; etypes[count++] = etype; etypes[count] = 0; } if (ret != KRB5_KT_END) goto cleanup; ret = 0; *etypes_out = etypes; etypes = NULL; cleanup: krb5_kt_end_seq_get(context, keytab, &cursor); free(etypes); return ret; } /* Move the entries in keytab_list (zero-terminated) to the front of req_list * (of length req_len), preserving order otherwise. */ static krb5_error_code sort_enctypes(krb5_enctype *req_list, int req_len, krb5_enctype *keytab_list) { krb5_enctype *save_list; int save_pos, req_pos, i; save_list = malloc(req_len * sizeof(*save_list)); if (save_list == NULL) return ENOMEM; /* Sort req_list entries into the front of req_list or into save_list. */ req_pos = save_pos = 0; for (i = 0; i < req_len; i++) { if (k5_etypes_contains(keytab_list, req_list[i])) req_list[req_pos++] = req_list[i]; else save_list[save_pos++] = req_list[i]; } /* Put the entries we saved back in at the end, in order. */ for (i = 0; i < save_pos; i++) req_list[req_pos++] = save_list[i]; assert(req_pos == req_len); free(save_list); return 0; } krb5_error_code KRB5_CALLCONV krb5_init_creds_set_keytab(krb5_context context, krb5_init_creds_context ctx, krb5_keytab keytab) { krb5_enctype *etype_list = NULL; krb5_error_code ret; struct canonprinc iter = { ctx->request->client, .subst_defrealm = TRUE }; krb5_const_principal canonprinc; krb5_principal copy; char *name; ctx->gak_fct = get_as_key_keytab; ctx->gak_data = keytab; /* We may be authenticating as a host-based principal. If so, look for * each canonicalization candidate in the keytab. */ while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 && canonprinc != NULL) { ret = lookup_etypes_for_keytab(context, keytab, canonprinc, &etype_list); if (ret || etype_list != NULL) break; } if (!ret && canonprinc != NULL) { /* Authenticate as the principal we found in the keytab. */ ret = krb5_copy_principal(context, canonprinc, ©); if (!ret) { krb5_free_principal(context, ctx->request->client); ctx->request->client = copy; } } free_canonprinc(&iter); if (ret) { TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(context, ret); free(etype_list); return 0; } TRACE_INIT_CREDS_KEYTAB_LOOKUP(context, ctx->request->client, etype_list); /* Error out if we have no keys for the client principal. */ if (etype_list == NULL) { ret = krb5_unparse_name(context, ctx->request->client, &name); if (ret == 0) { k5_setmsg(context, KRB5_KT_NOTFOUND, _("Keytab contains no suitable keys for %s"), name); } krb5_free_unparsed_name(context, name); return KRB5_KT_NOTFOUND; } /* Sort the request enctypes so the ones in the keytab appear first. */ ret = sort_enctypes(ctx->request->ktype, ctx->request->nktypes, etype_list); free(etype_list); return ret; } static krb5_error_code get_init_creds_keytab(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_keytab keytab, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *options, krb5_boolean use_primary, struct kdclist *kdcs) { krb5_error_code ret; krb5_init_creds_context ctx = NULL; ret = krb5_init_creds_init(context, client, NULL, NULL, start_time, options, &ctx); if (ret != 0) goto cleanup; if (in_tkt_service) { ret = krb5_init_creds_set_service(context, ctx, in_tkt_service); if (ret != 0) goto cleanup; } ret = krb5_init_creds_set_keytab(context, ctx, keytab); if (ret != 0) goto cleanup; ret = k5_init_creds_get(context, ctx, use_primary, kdcs); if (ret != 0) goto cleanup; ret = krb5_init_creds_get_creds(context, ctx, creds); if (ret != 0) goto cleanup; cleanup: krb5_init_creds_free(context, ctx); return ret; } krb5_error_code KRB5_CALLCONV krb5_get_init_creds_keytab(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_keytab arg_keytab, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *options) { krb5_error_code ret; krb5_keytab keytab; struct errinfo errsave = EMPTY_ERRINFO; struct kdclist *kdcs = NULL; if (arg_keytab == NULL) { if ((ret = krb5_kt_default(context, &keytab))) return ret; } else { keytab = arg_keytab; } ret = k5_kdclist_create(&kdcs); if (ret) goto cleanup; /* first try: get the requested tkt from any kdc */ ret = get_init_creds_keytab(context, creds, client, keytab, start_time, in_tkt_service, options, FALSE, kdcs); /* check for success */ if (ret == 0) goto cleanup; /* If all the kdc's are unavailable fail */ if ((ret == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE)) goto cleanup; /* If the reply did not come from the primary kdc, try again with * the primary kdc. */ if (!k5_kdclist_any_replicas(context, kdcs)) { k5_save_ctx_error(context, ret, &errsave); ret = get_init_creds_keytab(context, creds, client, keytab, start_time, in_tkt_service, options, TRUE, NULL); if (ret == 0) goto cleanup; /* If the primary is unreachable, return the error from the replica we * were able to contact. */ if (ret == KRB5_KDC_UNREACH || ret == KRB5_REALM_CANT_RESOLVE || ret == KRB5_REALM_UNKNOWN) ret = k5_restore_ctx_error(context, &errsave); } /* at this point, we have a response from the primary. Since we don't do any prompting or changing for keytabs, that's it. */ cleanup: if (arg_keytab == NULL) krb5_kt_close(context, keytab); k5_kdclist_free(kdcs); k5_clear_error(&errsave); return(ret); } krb5_error_code KRB5_CALLCONV krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options, krb5_address *const *addrs, krb5_enctype *ktypes, krb5_preauthtype *pre_auth_types, krb5_keytab arg_keytab, krb5_ccache ccache, krb5_creds *creds, krb5_kdc_rep **ret_as_reply) { krb5_error_code retval; krb5_get_init_creds_opt *opts; char * server = NULL; krb5_keytab keytab; krb5_principal client_princ, server_princ; retval = k5_populate_gic_opt(context, &opts, options, addrs, ktypes, pre_auth_types, creds); if (retval) return retval; if (arg_keytab == NULL) { retval = krb5_kt_default(context, &keytab); if (retval) goto cleanup; } else keytab = arg_keytab; retval = krb5_unparse_name( context, creds->server, &server); if (retval) goto cleanup; server_princ = creds->server; client_princ = creds->client; retval = k5_get_init_creds(context, creds, creds->client, krb5_prompter_posix, NULL, 0, server, opts, get_as_key_keytab, (void *)keytab, ret_as_reply); krb5_free_unparsed_name( context, server); if (retval) { goto cleanup; } krb5_free_principal(context, creds->server); krb5_free_principal(context, creds->client); creds->client = client_princ; creds->server = server_princ; /* store it in the ccache! */ if (ccache) if ((retval = krb5_cc_store_cred(context, ccache, creds))) goto cleanup; cleanup: krb5_get_init_creds_opt_free(context, opts); if (arg_keytab == NULL) krb5_kt_close(context, keytab); return retval; } #endif /* LEAN_CLIENT */ krb5-1.22.1/src/lib/krb5/krb/walk_rtree.c0000664000175000017500000004310515051422640017625 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/walk_rtree.c */ /* * Copyright 1990,1991,2008,2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * krb5_walk_realm_tree() * krb5_free_realm_tree() * * internal function, used by krb5_get_cred_from_kdc() */ #include "k5-int.h" #include "int-proto.h" /* * Structure to help with finding the common suffix between client and * server realm during hierarchical traversal. */ struct hstate { char *str; size_t len; char *tail; char *dot; }; static krb5_error_code rtree_capath_tree(krb5_context context, const krb5_data *client, const krb5_data *server, char **vals, krb5_principal **tree); static krb5_error_code rtree_capath_vals(krb5_context context, const krb5_data *client, const krb5_data *server, char ***vals); static krb5_error_code rtree_hier_tree(krb5_context context, const krb5_data *client, const krb5_data *server, krb5_principal **rettree, int sep); static krb5_error_code rtree_hier_realms(krb5_context context, const krb5_data *client, const krb5_data *server, krb5_data **realms, size_t *nrealms, int sep); static void free_realmlist(krb5_context context, krb5_data *realms, size_t nrealms); static krb5_error_code rtree_hier_tweens(krb5_context context, struct hstate *realm, krb5_data **tweens, size_t *ntweens, int dotail, int sep); static void adjtail(struct hstate *c, struct hstate *s, int sep); static void comtail(struct hstate *c, struct hstate *s, int sep); krb5_error_code krb5_walk_realm_tree( krb5_context context, const krb5_data *client, const krb5_data *server, krb5_principal **tree, int realm_sep) { krb5_error_code retval = 0; char **capvals; if (client->data == NULL || server->data == NULL) return KRB5_NO_TKT_IN_RLM; if (data_eq(*client, *server)) return KRB5_NO_TKT_IN_RLM; retval = rtree_capath_vals(context, client, server, &capvals); if (retval) return retval; if (capvals != NULL) { retval = rtree_capath_tree(context, client, server, capvals, tree); return retval; } retval = rtree_hier_tree(context, client, server, tree, realm_sep); return retval; } krb5_error_code k5_client_realm_path(krb5_context context, const krb5_data *client, const krb5_data *server, krb5_data **rpath_out) { krb5_error_code retval; char **capvals = NULL; size_t i; krb5_data *rpath = NULL, d; retval = rtree_capath_vals(context, client, server, &capvals); if (retval) return retval; /* A capaths value of "." means no intermediates. */ if (capvals != NULL && capvals[0] != NULL && *capvals[0] == '.') { profile_free_list(capvals); capvals = NULL; } /* Count capaths (if any) and allocate space. Leave room for the client * realm, server realm, and terminator. */ for (i = 0; capvals != NULL && capvals[i] != NULL; i++); rpath = calloc(i + 3, sizeof(*rpath)); if (rpath == NULL) return ENOMEM; /* Populate rpath with the client realm, capaths, and server realm. */ retval = krb5int_copy_data_contents(context, client, &rpath[0]); if (retval) goto cleanup; for (i = 0; capvals != NULL && capvals[i] != NULL; i++) { d = make_data(capvals[i], strcspn(capvals[i], "\t ")); retval = krb5int_copy_data_contents(context, &d, &rpath[i + 1]); if (retval) goto cleanup; } retval = krb5int_copy_data_contents(context, server, &rpath[i + 1]); if (retval) goto cleanup; /* Terminate rpath and return it. */ rpath[i + 2] = empty_data(); *rpath_out = rpath; rpath = NULL; cleanup: profile_free_list(capvals); krb5int_free_data_list(context, rpath); return retval; } /* ANL - Modified to allow Configurable Authentication Paths. * This modification removes the restriction on the choice of realm * names, i.e. they nolonger have to be hierarchical. This * is allowed by RFC 1510: "If a hierarchical organization is not used * it may be necessary to consult some database in order to construct * an authentication path between realms." The database is contained * in the [capaths] section of the krb5.conf file. * Client to server paths are defined. There are n**2 possible * entries, but only those entries which are needed by the client * or server need be present in its krb5.conf file. (n entries or 2*n * entries if the same krb5.conf is used for clients and servers) * * for example: ESnet will be running a KDC which will share * inter-realm keys with its many organizations which include among * other ANL, NERSC and PNL. Each of these organizations wants to * use its DNS name in the realm, ANL.GOV. In addition ANL wants * to authenticatite to HAL.COM via a K5.MOON and K5.JUPITER * A [capaths] section of the krb5.conf file for the ANL.GOV clients * and servers would look like: * * [capaths] * ANL.GOV = { * NERSC.GOV = ES.NET * PNL.GOV = ES.NET * ES.NET = . * HAL.COM = K5.MOON * HAL.COM = K5.JUPITER * } * NERSC.GOV = { * ANL.GOV = ES.NET * } * PNL.GOV = { * ANL.GOV = ES.NET * } * ES.NET = { * ANL.GOV = . * } * HAL.COM = { * ANL.GOV = K5.JUPITER * ANL.GOV = K5.MOON * } * * In the above a "." is used to mean directly connected since the * the profile routines cannot handle a null entry. * * If no client-to-server path is found, the default hierarchical path * is still generated. * * This version of the Configurable Authentication Path modification * differs from the previous versions prior to K5 beta 5 in that * the profile routines are used, and the explicit path from client's * realm to server's realm must be given. The modifications will work * together. * DEE - 5/23/95 */ /* * Build a tree given a set of profile values retrieved by * walk_rtree_capath_vals(). */ static krb5_error_code rtree_capath_tree(krb5_context context, const krb5_data *client, const krb5_data *server, char **vals, krb5_principal **rettree) { krb5_error_code retval = 0; unsigned int nvals, nlinks, nprincs, i; krb5_data srcrealm, dstrealm; krb5_principal *tree, *pprinc; *rettree = NULL; tree = pprinc = NULL; for (nvals = 0; vals[nvals] != NULL; nvals++) ; if (vals[0] != NULL && *vals[0] == '.') { nlinks = 0; } else { nlinks = nvals; } nprincs = nlinks + 2; tree = calloc(nprincs + 1, sizeof(krb5_principal)); if (tree == NULL) { retval = ENOMEM; goto error; } for (i = 0; i < nprincs + 1; i++) tree[i] = NULL; /* Invariant: PPRINC points one past end of list. */ pprinc = &tree[0]; /* Local TGS name */ retval = krb5int_tgtname(context, client, client, pprinc++); if (retval) goto error; srcrealm = *client; for (i = 0; i < nlinks; i++) { dstrealm.data = vals[i]; dstrealm.length = strcspn(vals[i], "\t "); retval = krb5int_tgtname(context, &dstrealm, &srcrealm, pprinc++); if (retval) goto error; srcrealm = dstrealm; } retval = krb5int_tgtname(context, server, &srcrealm, pprinc++); if (retval) goto error; *rettree = tree; error: profile_free_list(vals); if (retval) { while (pprinc != NULL && pprinc > &tree[0]) { /* krb5_free_principal() correctly handles null input */ krb5_free_principal(context, *--pprinc); *pprinc = NULL; } free(tree); } return retval; } /* * Get realm list from "capaths" section of the profile. Deliberately * returns success but leaves VALS null if profile_get_values() fails * by not finding anything. */ static krb5_error_code rtree_capath_vals(krb5_context context, const krb5_data *client, const krb5_data *server, char ***vals) { krb5_error_code retval = 0; /* null-terminated realm names */ char *clientz = NULL, *serverz = NULL; const char *key[4]; *vals = NULL; clientz = k5memdup0(client->data, client->length, &retval); if (clientz == NULL) goto error; serverz = k5memdup0(server->data, server->length, &retval); if (serverz == NULL) goto error; key[0] = "capaths"; key[1] = clientz; key[2] = serverz; key[3] = NULL; retval = profile_get_values(context->profile, key, vals); switch (retval) { case PROF_NO_SECTION: case PROF_NO_RELATION: /* * Not found; don't return an error. */ retval = 0; break; default: break; } error: free(clientz); free(serverz); return retval; } /* * Build tree by hierarchical traversal. */ static krb5_error_code rtree_hier_tree(krb5_context context, const krb5_data *client, const krb5_data *server, krb5_principal **rettree, int sep) { krb5_error_code retval; krb5_data *realms; const krb5_data *dstrealm, *srcrealm; krb5_principal *tree, *pprinc; size_t nrealms, nprincs, i; *rettree = NULL; retval = rtree_hier_realms(context, client, server, &realms, &nrealms, sep); if (retval) return retval; nprincs = nrealms; pprinc = tree = calloc(nprincs + 1, sizeof(krb5_principal)); if (tree == NULL) { retval = ENOMEM; goto error; } for (i = 0; i < nrealms; i++) tree[i] = NULL; srcrealm = client; for (i = 0; i < nrealms; i++) { dstrealm = &realms[i]; retval = krb5int_tgtname(context, dstrealm, srcrealm, pprinc++); if (retval) goto error; srcrealm = dstrealm; } *rettree = tree; free_realmlist(context, realms, nrealms); return 0; error: while (pprinc != NULL && pprinc > tree) { krb5_free_principal(context, *--pprinc); *pprinc = NULL; } free_realmlist(context, realms, nrealms); free(tree); return retval; } /* * Construct list of realms between client and server. */ static krb5_error_code rtree_hier_realms(krb5_context context, const krb5_data *client, const krb5_data *server, krb5_data **realms, size_t *nrealms, int sep) { krb5_error_code retval; struct hstate c, s; krb5_data *ctweens = NULL, *stweens = NULL, *twp, *r, *rp; size_t nctween, nstween; *realms = NULL; *nrealms = 0; r = rp = NULL; c.str = client->data; c.len = client->length; c.dot = c.tail = NULL; s.str = server->data; s.len = server->length; s.dot = s.tail = NULL; comtail(&c, &s, sep); adjtail(&c, &s, sep); retval = rtree_hier_tweens(context, &c, &ctweens, &nctween, 1, sep); if (retval) goto error; retval = rtree_hier_tweens(context, &s, &stweens, &nstween, 0, sep); if (retval) goto error; rp = r = calloc(nctween + nstween, sizeof(krb5_data)); if (r == NULL) { retval = ENOMEM; goto error; } /* Copy client realm "tweens" forward. */ for (twp = ctweens; twp < &ctweens[nctween]; twp++) { retval = krb5int_copy_data_contents(context, twp, rp); if (retval) goto error; rp++; } /* Copy server realm "tweens" backward. */ for (twp = &stweens[nstween]; twp-- > stweens;) { retval = krb5int_copy_data_contents(context, twp, rp); if (retval) goto error; rp++; } error: free(ctweens); free(stweens); if (retval) { free_realmlist(context, r, rp - r); return retval; } *realms = r; *nrealms = rp - r; return 0; } static void free_realmlist(krb5_context context, krb5_data *realms, size_t nrealms) { size_t i; for (i = 0; i < nrealms; i++) krb5_free_data_contents(context, &realms[i]); free(realms); } /* * Build a list of realms between a given realm and the common * suffix. The original realm is included, but the "tail" is only * included if DOTAIL is true. * * Warning: This function intentionally aliases memory. Caller must * make copies as needed and not call krb5_free_data_contents, etc. */ static krb5_error_code rtree_hier_tweens(krb5_context context, struct hstate *realm, krb5_data **tweens, size_t *ntweens, int dotail, int sep) { char *p, *r, *rtail, *lp; size_t rlen, n; krb5_data *tws, *ntws; r = realm->str; rlen = realm->len; rtail = realm->tail; *tweens = ntws = tws = NULL; *ntweens = n = 0; for (lp = p = r; p < &r[rlen]; p++) { if (*p != sep && &p[1] != &r[rlen]) continue; if (lp == rtail && !dotail) break; ntws = realloc(tws, (n + 1) * sizeof(krb5_data)); if (ntws == NULL) { free(tws); return ENOMEM; } tws = ntws; tws[n].data = lp; tws[n].length = &r[rlen] - lp; n++; if (lp == rtail) break; lp = &p[1]; } *tweens = tws; *ntweens = n; return 0; } /* * Adjust suffixes that each starts at the beginning of a component, * to avoid the problem where "BC.EXAMPLE.COM" is erroneously reported * as a parent of "ABC.EXAMPLE.COM". */ static void adjtail(struct hstate *c, struct hstate *s, int sep) { int cfull, sfull; char *cp, *sp; cp = c->tail; sp = s->tail; if (cp == NULL || sp == NULL) return; /* * Is it a full component? Yes, if it's the beginning of the * string or there's a separator to the left. * * The index of -1 is valid because it only gets evaluated if the * pointer is not at the beginning of the string. */ cfull = (cp == c->str || cp[-1] == sep); sfull = (sp == s->str || sp[-1] == sep); /* * If they're both full components, we're done. */ if (cfull && sfull) { return; } else if (c->dot != NULL && s->dot != NULL) { cp = c->dot + 1; sp = s->dot + 1; /* * Out of bounds? Can only happen if there are trailing dots. */ if (cp >= &c->str[c->len] || sp >= &s->str[s->len]) { cp = sp = NULL; } } else { cp = sp = NULL; } c->tail = cp; s->tail = sp; } /* * Find common suffix of C and S. * * C->TAIL and S->TAIL will point to the respective suffixes. C->DOT * and S->DOT will point to the nearest instances of SEP to the right * of the start of each suffix. Caller must initialize TAIL and DOT * pointers to null. */ static void comtail(struct hstate *c, struct hstate *s, int sep) { char *cp, *sp, *cdot, *sdot; if (c->len == 0 || s->len == 0) return; cdot = sdot = NULL; /* * ANSI/ISO C allows a pointer one past the end but not one * before the beginning of an array. */ cp = &c->str[c->len]; sp = &s->str[s->len]; /* * Set CP and SP to point to the common suffix of each string. * When we run into separators (dots, unless someone has a X.500 * style realm), keep pointers to the latest pair. */ while (cp > c->str && sp > s->str) { if (*--cp != *--sp) { /* * Didn't match, so most recent match is one byte to the * right (or not at all). */ cp++; sp++; break; } /* * Keep track of matching dots. */ if (*cp == sep) { cdot = cp; sdot = sp; } } /* No match found at all. */ if (cp == &c->str[c->len]) return; c->tail = cp; s->tail = sp; c->dot = cdot; s->dot = sdot; } void krb5_free_realm_tree(krb5_context context, krb5_principal *realms) { krb5_principal *nrealms = realms; if (realms == NULL) return; while (*nrealms) { krb5_free_principal(context, *nrealms); nrealms++; } free(realms); } krb5-1.22.1/src/lib/krb5/krb/copy_addrs.c0000664000175000017500000000504315051422640017614 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/copy_addrs.c */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" krb5_error_code KRB5_CALLCONV krb5_copy_addr(krb5_context context, const krb5_address *inad, krb5_address **outad) { krb5_address *tmpad; if (!(tmpad = (krb5_address *)malloc(sizeof(*tmpad)))) return ENOMEM; *tmpad = *inad; if (!(tmpad->contents = (krb5_octet *)malloc(inad->length))) { free(tmpad); return ENOMEM; } memcpy(tmpad->contents, inad->contents, inad->length); *outad = tmpad; return 0; } /* * Copy an address array, with fresh allocation. */ krb5_error_code KRB5_CALLCONV krb5_copy_addresses(krb5_context context, krb5_address *const *inaddr, krb5_address ***outaddr) { krb5_error_code retval; krb5_address ** tempaddr; size_t nelems = 0; if (!inaddr) { *outaddr = 0; return 0; } while (inaddr[nelems]) nelems++; /* one more for a null terminated list */ if (!(tempaddr = (krb5_address **) calloc(nelems+1, sizeof(*tempaddr)))) return ENOMEM; for (nelems = 0; inaddr[nelems]; nelems++) { retval = krb5_copy_addr(context, inaddr[nelems], &tempaddr[nelems]); if (retval) { krb5_free_addresses(context, tempaddr); return retval; } } *outaddr = tempaddr; return 0; } krb5-1.22.1/src/lib/krb5/krb/t_expire_warn.py0000775000175000017500000000640315051422640020545 0ustar ghudsonghudson# Copyright (C) 2010 by the Massachusetts Institute of Technology. # All rights reserved. # # Export of this software from the United States of America may # require a specific license from the United States Government. # It is the responsibility of any person or organization contemplating # export to obtain such a license before exporting. # # WITHIN THAT CONSTRAINT, permission to use, copy, modify, and # distribute this software and its documentation for any purpose and # without fee is hereby granted, provided that the above copyright # notice appear in all copies and that both that copyright notice and # this permission notice appear in supporting documentation, and that # the name of M.I.T. not be used in advertising or publicity pertaining # to distribution of the software without specific, written prior # permission. Furthermore if you modify this software you must label # your software as modified software and not distribute it in such a # fashion that it might be confused with the original M.I.T. software. # M.I.T. makes no representations about the suitability of # this software for any purpose. It is provided "as is" without express # or implied warranty. from k5test import * # Create a bare-bones KDC. realm = K5Realm(create_user=False, create_host=False) # Create principals with various password expirations. realm.run([kadminl, 'addprinc', '-pw', 'pass', 'noexpire']) realm.run([kadminl, 'addprinc', '-pw', 'pass', '-pwexpire', '30 minutes', 'minutes']) realm.run([kadminl, 'addprinc', '-pw', 'pass', '-pwexpire', '12 hours', 'hours']) realm.run([kadminl, 'addprinc', '-pw', 'pass', '-pwexpire', '3 days', 'days']) # Check for expected prompter warnings when no expire callback is used. output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '0', '0']) if output: fail('Unexpected output for noexpire') realm.run(['./t_expire_warn', 'minutes', 'pass', '0', '0'], expected_msg=' less than one hour on ') realm.run(['./t_expire_warn', 'hours', 'pass', '0', '0'], expected_msg=' hours on ') realm.run(['./t_expire_warn', 'days', 'pass', '0', '0'], expected_msg=' days on ') # Try one case with the stepwise interface. realm.run(['./t_expire_warn', 'days', 'pass', '0', '1'], expected_msg=' days on ') # Check for expected expire callback behavior. These tests are # carefully agnostic about whether the KDC supports last_req fields, # and could be made more specific if last_req support is added. output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '1', '0']) if 'password_expiration = 0\n' not in output or \ 'account_expiration = 0\n' not in output or \ 'is_last_req = ' not in output: fail('Expected callback output not seen for noexpire') output = realm.run(['./t_expire_warn', 'days', 'pass', '1', '0']) if 'password_expiration = ' not in output or \ 'password_expiration = 0\n' in output: fail('Expected non-zero password expiration not seen for days') # Try one case with the stepwise interface. output = realm.run(['./t_expire_warn', 'days', 'pass', '1', '1']) if 'password_expiration = ' not in output or \ 'password_expiration = 0\n' in output: fail('Expected non-zero password expiration not seen for days') success('Password expiration warning tests') krb5-1.22.1/src/lib/krb5/krb/copy_cksum.c0000664000175000017500000000343215051422640017641 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/copy_cksum.c */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" krb5_error_code KRB5_CALLCONV krb5_copy_checksum(krb5_context context, const krb5_checksum *ckfrom, krb5_checksum **ckto) { krb5_checksum *tempto; if (!(tempto = (krb5_checksum *)malloc(sizeof(*tempto)))) return ENOMEM; *tempto = *ckfrom; if (!(tempto->contents = (krb5_octet *)malloc(tempto->length))) { free(tempto); return ENOMEM; } memcpy(tempto->contents, ckfrom->contents, ckfrom->length); *ckto = tempto; return 0; } krb5-1.22.1/src/lib/krb5/krb/gic_pwd.c0000664000175000017500000003402115051422640017077 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #include "k5-int.h" #include "com_err.h" #include "init_creds_ctx.h" #include "int-proto.h" #include "os-proto.h" krb5_error_code krb5_get_as_key_password(krb5_context context, krb5_principal client, krb5_enctype etype, krb5_prompter_fct prompter, void *prompter_data, krb5_data *salt, krb5_data *params, krb5_keyblock *as_key, void *gak_data, k5_response_items *ritems) { struct gak_password *gp = gak_data; krb5_error_code ret; krb5_data defsalt; char *clientstr; char promptstr[1024], pwbuf[1024]; krb5_data pw; krb5_prompt prompt; krb5_prompt_type prompt_type; const char *rpass; /* If we need to get the AS key via the responder, ask for it. */ if (as_key == NULL) { if (gp->password != NULL) return 0; return k5_response_items_ask_question(ritems, KRB5_RESPONDER_QUESTION_PASSWORD, ""); } /* If there's already a key of the correct etype, we're done. If the etype is wrong, free the existing key, and make a new one. XXX This was the old behavior, and was wrong in hw preauth cases. Is this new behavior -- always asking -- correct in all cases? */ if (as_key->length) { if (as_key->enctype != etype) { krb5_free_keyblock_contents (context, as_key); as_key->length = 0; } } if (gp->password == NULL) { /* Check the responder for the password. */ rpass = k5_response_items_get_answer(ritems, KRB5_RESPONDER_QUESTION_PASSWORD); if (rpass != NULL) { ret = alloc_data(&gp->storage, strlen(rpass)); if (ret) return ret; memcpy(gp->storage.data, rpass, strlen(rpass)); gp->password = &gp->storage; } } if (gp->password == NULL) { if (prompter == NULL) return(EIO); if ((ret = krb5_unparse_name(context, client, &clientstr))) return(ret); snprintf(promptstr, sizeof(promptstr), _("Password for %s"), clientstr); free(clientstr); pw = make_data(pwbuf, sizeof(pwbuf)); prompt.prompt = promptstr; prompt.hidden = 1; prompt.reply = &pw; prompt_type = KRB5_PROMPT_TYPE_PASSWORD; /* PROMPTER_INVOCATION */ k5_set_prompt_types(context, &prompt_type); ret = (*prompter)(context, prompter_data, NULL, NULL, 1, &prompt); k5_set_prompt_types(context, 0); if (ret) return(ret); ret = krb5int_copy_data_contents(context, &pw, &gp->storage); zap(pw.data, pw.length); if (ret) return ret; gp->password = &gp->storage; } if (salt == NULL) { if ((ret = krb5_principal2salt(context, client, &defsalt))) return(ret); salt = &defsalt; } else { defsalt.length = 0; } ret = krb5_c_string_to_key_with_params(context, etype, gp->password, salt, params->data?params:NULL, as_key); if (defsalt.length) free(defsalt.data); return(ret); } krb5_error_code KRB5_CALLCONV krb5_init_creds_set_password(krb5_context context, krb5_init_creds_context ctx, const char *password) { char *s; s = strdup(password); if (s == NULL) return ENOMEM; zapfree(ctx->gakpw.storage.data, ctx->gakpw.storage.length); ctx->gakpw.storage = string2data(s); ctx->gakpw.password = &ctx->gakpw.storage; ctx->gak_fct = krb5_get_as_key_password; ctx->gak_data = &ctx->gakpw; return 0; } /* * Create a temporary options structure for getting a kadmin/changepw ticket, * based on the appplication-specified options. Propagate all application * options which affect preauthentication, but not options which affect the * resulting ticket or how it is stored. Set lifetime and flags appropriate * for a ticket which we will use immediately and then discard. * * The caller should free the result with free(). */ static krb5_error_code make_chpw_options(krb5_context context, krb5_get_init_creds_opt *in, krb5_get_init_creds_opt **out) { krb5_get_init_creds_opt *opt; *out = NULL; opt = k5_gic_opt_shallow_copy(in); if (opt == NULL) return ENOMEM; /* Get a non-forwardable, non-proxiable, short-lifetime ticket. */ krb5_get_init_creds_opt_set_tkt_life(opt, 5 * 60); krb5_get_init_creds_opt_set_renew_life(opt, 0); krb5_get_init_creds_opt_set_forwardable(opt, 0); krb5_get_init_creds_opt_set_proxiable(opt, 0); /* Unset options which should only apply to the actual ticket. */ opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST; opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ANONYMOUS; /* The output ccache should only be used for the actual ticket. */ krb5_get_init_creds_opt_set_out_ccache(context, opt, NULL); *out = opt; return 0; } krb5_error_code KRB5_CALLCONV krb5_get_init_creds_password(krb5_context context, krb5_creds *creds, krb5_principal client, const char *password, krb5_prompter_fct prompter, void *data, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *options) { krb5_error_code ret; krb5_kdc_rep *as_reply; int tries; krb5_creds chpw_creds; krb5_get_init_creds_opt *chpw_opts = NULL; struct gak_password gakpw; krb5_data pw0, pw1; char banner[1024], pw0array[1024], pw1array[1024]; krb5_prompt prompt[2]; krb5_prompt_type prompt_types[sizeof(prompt)/sizeof(prompt[0])]; char *message; as_reply = NULL; memset(&chpw_creds, 0, sizeof(chpw_creds)); memset(&gakpw, 0, sizeof(gakpw)); if (password != NULL) { pw0 = string2data((char *)password); gakpw.password = &pw0; } ret = k5_get_init_creds(context, creds, client, prompter, data, start_time, in_tkt_service, options, krb5_get_as_key_password, &gakpw, &as_reply); if (!ret) goto cleanup; /* If the error is not password expired, or if it is but there's no * prompter, return this error. */ if (ret != KRB5KDC_ERR_KEY_EXP || prompter == NULL) goto cleanup; /* historically the default has been to prompt for password change. * if the change password prompt option has not been set, we continue * to prompt. Prompting is only disabled if the option has been set * and the value has been set to false. */ if (options && !(options->flags & KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT)) goto cleanup; TRACE_GIC_PWD_EXPIRED(context); /* ok, we have an expired password. Give the user a few chances to change it */ ret = make_chpw_options(context, options, &chpw_opts); if (ret) goto cleanup; ret = k5_get_init_creds(context, &chpw_creds, client, prompter, data, start_time, "kadmin/changepw", chpw_opts, krb5_get_as_key_password, &gakpw, NULL); if (ret) goto cleanup; pw0.data = pw0array; pw0.data[0] = '\0'; pw0.length = sizeof(pw0array); prompt[0].prompt = _("Enter new password"); prompt[0].hidden = 1; prompt[0].reply = &pw0; prompt_types[0] = KRB5_PROMPT_TYPE_NEW_PASSWORD; pw1.data = pw1array; pw1.data[0] = '\0'; pw1.length = sizeof(pw1array); prompt[1].prompt = _("Enter it again"); prompt[1].hidden = 1; prompt[1].reply = &pw1; prompt_types[1] = KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN; strlcpy(banner, _("Password expired. You must change it now."), sizeof(banner)); for (tries = 3; tries; tries--) { TRACE_GIC_PWD_CHANGEPW(context, tries); pw0.length = sizeof(pw0array); pw1.length = sizeof(pw1array); /* PROMPTER_INVOCATION */ k5_set_prompt_types(context, prompt_types); ret = (*prompter)(context, data, 0, banner, sizeof(prompt)/sizeof(prompt[0]), prompt); k5_set_prompt_types(context, 0); if (ret) goto cleanup; if (strcmp(pw0.data, pw1.data) != 0) { ret = KRB5_LIBOS_BADPWDMATCH; snprintf(banner, sizeof(banner), _("%s. Please try again."), error_message(ret)); } else if (pw0.length == 0) { ret = KRB5_CHPW_PWDNULL; snprintf(banner, sizeof(banner), _("%s. Please try again."), error_message(ret)); } else { int result_code; krb5_data code_string; krb5_data result_string; if ((ret = krb5_change_password(context, &chpw_creds, pw0array, &result_code, &code_string, &result_string))) goto cleanup; /* the change succeeded. go on */ if (result_code == 0) { free(code_string.data); free(result_string.data); break; } /* set this in case the retry loop falls through */ ret = KRB5_CHPW_FAIL; if (result_code != KRB5_KPASSWD_SOFTERROR) { free(code_string.data); free(result_string.data); goto cleanup; } /* the error was soft, so try again */ if (krb5_chpw_message(context, &result_string, &message) != 0) message = NULL; /* 100 is I happen to know that no code_string will be longer than 100 chars */ if (message != NULL && strlen(message) > (sizeof(banner) - 100)) message[sizeof(banner) - 100] = '\0'; snprintf(banner, sizeof(banner), _("%.*s%s%s. Please try again.\n"), (int) code_string.length, code_string.data, message ? ": " : "", message ? message : ""); free(message); free(code_string.data); free(result_string.data); } } if (ret) goto cleanup; /* The password change was successful. Try one last time to get an initial * ticket. */ TRACE_GIC_PWD_CHANGED(context); gakpw.password = &pw0; ret = k5_get_init_creds(context, creds, client, prompter, data, start_time, in_tkt_service, options, krb5_get_as_key_password, &gakpw, &as_reply); if (ret) goto cleanup; cleanup: free(chpw_opts); zapfree(gakpw.storage.data, gakpw.storage.length); memset(pw0array, 0, sizeof(pw0array)); memset(pw1array, 0, sizeof(pw1array)); krb5_free_cred_contents(context, &chpw_creds); if (as_reply) krb5_free_kdc_rep(context, as_reply); return(ret); } /* Rewrites get_in_tkt in terms of newer get_init_creds API. Attempts to get an initial ticket for creds->client to use server creds->server, (realm is taken from creds->client), with options options, and using creds->times.starttime, creds->times.endtime, creds->times.renew_till as from, till, and rtime. creds->times.renew_till is ignored unless the RENEWABLE option is requested. If addrs is non-NULL, it is used for the addresses requested. If it is null, the system standard addresses are used. If password is non-NULL, it is converted using the cryptosystem entry point for a string conversion routine, seeded with the client's name. If password is passed as NULL, the password is read from the terminal, and then converted into a key. A successful call will place the ticket in the credentials cache ccache. returns system errors, encryption errors */ krb5_error_code KRB5_CALLCONV krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options, krb5_address *const *addrs, krb5_enctype *ktypes, krb5_preauthtype *pre_auth_types, const char *password, krb5_ccache ccache, krb5_creds *creds, krb5_kdc_rep **ret_as_reply) { krb5_error_code retval; struct gak_password gakpw; krb5_data pw; char * server; krb5_principal server_princ, client_princ; krb5_get_init_creds_opt *opts = NULL; memset(&gakpw, 0, sizeof(gakpw)); if (password != NULL) { pw = string2data((char *)password); gakpw.password = &pw; } retval = k5_populate_gic_opt(context, &opts, options, addrs, ktypes, pre_auth_types, creds); if (retval) return (retval); retval = krb5_unparse_name( context, creds->server, &server); if (retval) { krb5_get_init_creds_opt_free(context, opts); return (retval); } server_princ = creds->server; client_princ = creds->client; retval = k5_get_init_creds(context, creds, creds->client, krb5_prompter_posix, NULL, 0, server, opts, krb5_get_as_key_password, &gakpw, ret_as_reply); krb5_free_unparsed_name( context, server); krb5_get_init_creds_opt_free(context, opts); zapfree(gakpw.storage.data, gakpw.storage.length); if (retval) { return (retval); } krb5_free_principal( context, creds->server); krb5_free_principal( context, creds->client); creds->client = client_princ; creds->server = server_princ; /* store it in the ccache! */ if (ccache) if ((retval = krb5_cc_store_cred(context, ccache, creds))) return (retval); return retval; } krb5-1.22.1/src/lib/krb5/krb/valid_times.c0000664000175000017500000000423015051422640017762 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/valid_times.c */ /* * Copyright 1995 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "int-proto.h" /* * This is an internal routine which validates the krb5_timestamps * field in a krb5_ticket. */ krb5_error_code krb5int_validate_times(krb5_context context, krb5_ticket_times *times) { krb5_timestamp currenttime, starttime; krb5_error_code retval; if ((retval = krb5_timeofday(context, ¤ttime))) return retval; /* if starttime is not in ticket, then treat it as authtime */ if (times->starttime != 0) starttime = times->starttime; else starttime = times->authtime; if (ts_after(starttime, ts_incr(currenttime, context->clockskew))) return KRB5KRB_AP_ERR_TKT_NYV; /* ticket not yet valid */ if (ts_after(currenttime, ts_incr(times->endtime, context->clockskew))) return KRB5KRB_AP_ERR_TKT_EXPIRED; /* ticket expired */ return 0; } krb5-1.22.1/src/lib/krb5/krb/t_ser.c0000664000175000017500000002240215051422640016577 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/t_ser.c - Test serialization */ /* * Copyright 1995, 2019 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "com_err.h" #include "auth_con.h" #include static const char stuff[]="You can't take a pointer to a function and convert \ it to a pointer to char; ANSI doesn't say it'll work, and in fact on the HPPA \ you can lose some bits of the function pointer, and get a pointer that you \ can't safely dereference. This test file used to make this mistake, often."; static void check(krb5_error_code code) { if (code != 0) { com_err("t_ser", code, NULL); abort(); } } static void * ealloc(size_t size) { void *ptr = calloc(1, size); if (ptr == NULL) abort(); return ptr; } static void ser_context(krb5_context ctx) { uint8_t *erep, *erep2, *bp; size_t elen = 0, elen2 = 0, blen; krb5_context ctx2; check(k5_size_context(ctx, &elen)); erep = ealloc(elen); bp = erep; blen = elen; check(k5_externalize_context(ctx, &bp, &blen)); assert(bp == erep + elen && blen == 0); bp = erep; blen = elen; check(k5_internalize_context(&ctx2, &bp, &blen)); assert(bp == erep + elen && blen == 0); check(k5_size_context(ctx2, &elen2)); assert(elen2 == elen); erep2 = ealloc(elen2); bp = erep2; blen = elen2; check(k5_externalize_context(ctx2, &bp, &blen)); assert(bp == erep2 + elen2 && blen == 0); assert(memcmp(erep, erep2, elen) == 0); free(erep); free(erep2); krb5_free_context(ctx2); } static void ser_auth_context(krb5_auth_context actx) { uint8_t *erep, *erep2, *bp; size_t elen = 0, elen2 = 0, blen; krb5_auth_context actx2; check(k5_size_auth_context(actx, &elen)); erep = ealloc(elen); bp = erep; blen = elen; check(k5_externalize_auth_context(actx, &bp, &blen)); assert(bp == erep + elen && blen == 0); bp = erep; blen = elen; check(k5_internalize_auth_context(&actx2, &bp, &blen)); assert(bp == erep + elen && blen == 0); check(k5_size_auth_context(actx2, &elen2)); assert(elen2 == elen); erep2 = ealloc(elen2); bp = erep2; blen = elen2; check(k5_externalize_auth_context(actx2, &bp, &blen)); assert(bp == erep2 + elen2 && blen == 0); assert(memcmp(erep, erep2, elen) == 0); free(erep); free(erep2); krb5_auth_con_free(NULL, actx2); } static void ser_principal(krb5_principal princ) { uint8_t *erep, *erep2, *bp; size_t elen = 0, elen2 = 0, blen; krb5_principal princ2; check(k5_size_principal(princ, &elen)); erep = ealloc(elen); bp = erep; blen = elen; check(k5_externalize_principal(princ, &bp, &blen)); assert(bp == erep + elen && blen == 0); bp = erep; blen = elen; check(k5_internalize_principal(&princ2, &bp, &blen)); assert(bp == erep + elen && blen == 0); check(k5_size_principal(princ2, &elen2)); assert(elen2 == elen); erep2 = ealloc(elen2); bp = erep2; blen = elen2; check(k5_externalize_principal(princ2, &bp, &blen)); assert(bp == erep2 + elen2 && blen == 0); assert(memcmp(erep, erep2, elen) == 0); free(erep); free(erep2); krb5_free_principal(NULL, princ2); } static void ser_checksum(krb5_checksum *cksum) { uint8_t *erep, *erep2, *bp; size_t elen = 0, elen2 = 0, blen; krb5_checksum *cksum2; check(k5_size_checksum(cksum, &elen)); erep = ealloc(elen); bp = erep; blen = elen; check(k5_externalize_checksum(cksum, &bp, &blen)); assert(bp == erep + elen && blen == 0); bp = erep; blen = elen; check(k5_internalize_checksum(&cksum2, &bp, &blen)); assert(bp == erep + elen && blen == 0); check(k5_size_checksum(cksum2, &elen2)); assert(elen2 == elen); erep2 = ealloc(elen2); bp = erep2; blen = elen2; check(k5_externalize_checksum(cksum2, &bp, &blen)); assert(bp == erep2 + elen2 && blen == 0); assert(memcmp(erep, erep2, elen) == 0); free(erep); free(erep2); krb5_free_checksum(NULL, cksum2); } static void ser_context_test(void) { krb5_context context; profile_t sprofile; check(krb5_init_context(&context)); sprofile = context->profile; context->profile = NULL; ser_context(context); context->profile = sprofile; ser_context(context); check(krb5_set_default_realm(context, "this.is.a.test")); ser_context(context); krb5_free_context(context); } static void ser_acontext_test(void) { krb5_auth_context actx; krb5_address local_address; krb5_address remote_address; krb5_octet laddr_bytes[16]; krb5_octet raddr_bytes[16]; krb5_keyblock ukeyblock; krb5_octet keydata[8]; krb5_authenticator aent; char clname[128]; krb5_authdata *adatalist[3]; krb5_authdata adataent; check(krb5_auth_con_init(NULL, &actx)); ser_auth_context(actx); memset(&local_address, 0, sizeof(local_address)); memset(&remote_address, 0, sizeof(remote_address)); memset(laddr_bytes, 0, sizeof(laddr_bytes)); memset(raddr_bytes, 0, sizeof(raddr_bytes)); local_address.addrtype = ADDRTYPE_INET; local_address.length = sizeof(laddr_bytes); local_address.contents = laddr_bytes; laddr_bytes[0] = 6; laddr_bytes[1] = 2; laddr_bytes[2] = 69; laddr_bytes[3] = 16; laddr_bytes[4] = 1; laddr_bytes[5] = 0; laddr_bytes[6] = 0; laddr_bytes[7] = 127; remote_address.addrtype = ADDRTYPE_INET; remote_address.length = sizeof(raddr_bytes); remote_address.contents = raddr_bytes; raddr_bytes[0] = 6; raddr_bytes[1] = 2; raddr_bytes[2] = 70; raddr_bytes[3] = 16; raddr_bytes[4] = 1; raddr_bytes[5] = 0; raddr_bytes[6] = 0; raddr_bytes[7] = 127; check(krb5_auth_con_setaddrs(NULL, actx, &local_address, &remote_address)); check(krb5_auth_con_setports(NULL, actx, &local_address, &remote_address)); ser_auth_context(actx); memset(&ukeyblock, 0, sizeof(ukeyblock)); memset(keydata, 0, sizeof(keydata)); ukeyblock.enctype = ENCTYPE_AES128_CTS_HMAC_SHA256_128; ukeyblock.length = sizeof(keydata); ukeyblock.contents = keydata; keydata[0] = 0xde; keydata[1] = 0xad; keydata[2] = 0xbe; keydata[3] = 0xef; keydata[4] = 0xfe; keydata[5] = 0xed; keydata[6] = 0xf0; keydata[7] = 0xd; check(krb5_auth_con_setuseruserkey(NULL, actx, &ukeyblock)); ser_auth_context(actx); check(krb5_auth_con_initivector(NULL, actx)); ser_auth_context(actx); memset(&aent, 0, sizeof(aent)); aent.magic = KV5M_AUTHENTICATOR; snprintf(clname, sizeof(clname), "help/me/%d@this.is.a.test", (int)getpid()); actx->authentp = &aent; check(krb5_parse_name(NULL, clname, &aent.client)); ser_auth_context(actx); adataent.magic = KV5M_AUTHDATA; adataent.ad_type = 123; adataent.length = 128; adataent.contents = (uint8_t *)stuff; adatalist[0] = &adataent; adatalist[1] = &adataent; adatalist[2] = NULL; aent.authorization_data = adatalist; ser_auth_context(actx); krb5_free_principal(NULL, aent.client); actx->authentp = NULL; krb5_auth_con_free(NULL, actx); } static void ser_princ_test(void) { krb5_principal princ; char pname[1024]; snprintf(pname, sizeof(pname), "the/quick/brown/fox/jumped/over/the/lazy/dog/%d@this.is.a.test", (int) getpid()); check(krb5_parse_name(NULL, pname, &princ)); ser_principal(princ); krb5_free_principal(NULL, princ); } static void ser_cksum_test(void) { krb5_checksum checksum; krb5_octet ckdata[24]; memset(&checksum, 0, sizeof(krb5_checksum)); checksum.magic = KV5M_CHECKSUM; ser_checksum(&checksum); checksum.checksum_type = 123; checksum.length = sizeof(ckdata); checksum.contents = ckdata; memcpy(ckdata, &stuff, sizeof(ckdata)); ser_checksum(&checksum); } int main(int argc, char **argv) { ser_context_test(); ser_acontext_test(); ser_princ_test(); ser_cksum_test(); return 0; } krb5-1.22.1/src/lib/krb5/krb/serialize.c0000664000175000017500000000746715051422640017470 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/serialize.c - Base serialization routines */ /* * Copyright 1995 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" /* * krb5_ser_pack_int32() - Pack a 4-byte integer if space is available. * Update buffer pointer and remaining space. */ krb5_error_code KRB5_CALLCONV krb5_ser_pack_int32(krb5_int32 iarg, krb5_octet **bufp, size_t *remainp) { if (*remainp >= sizeof(krb5_int32)) { store_32_be(iarg, *bufp); *bufp += sizeof(krb5_int32); *remainp -= sizeof(krb5_int32); return(0); } else return(ENOMEM); } /* * krb5_ser_pack_int64() - Pack an 8-byte integer if space is available. * Update buffer pointer and remaining space. */ krb5_error_code KRB5_CALLCONV krb5_ser_pack_int64(int64_t iarg, krb5_octet **bufp, size_t *remainp) { if (*remainp >= sizeof(int64_t)) { store_64_be(iarg, (unsigned char *)*bufp); *bufp += sizeof(int64_t); *remainp -= sizeof(int64_t); return(0); } else return(ENOMEM); } /* * krb5_ser_pack_bytes() - Pack a string of bytes. */ krb5_error_code KRB5_CALLCONV krb5_ser_pack_bytes(krb5_octet *ostring, size_t osize, krb5_octet **bufp, size_t *remainp) { if (*remainp >= osize) { memcpy(*bufp, ostring, osize); *bufp += osize; *remainp -= osize; return(0); } else return(ENOMEM); } /* * krb5_ser_unpack_int32() - Unpack a 4-byte integer if it's there. */ krb5_error_code KRB5_CALLCONV krb5_ser_unpack_int32(krb5_int32 *intp, krb5_octet **bufp, size_t *remainp) { if (*remainp >= sizeof(krb5_int32)) { *intp = load_32_be(*bufp); *bufp += sizeof(krb5_int32); *remainp -= sizeof(krb5_int32); return(0); } else return(ENOMEM); } /* * krb5_ser_unpack_int64() - Unpack an 8-byte integer if it's there. */ krb5_error_code KRB5_CALLCONV krb5_ser_unpack_int64(int64_t *intp, krb5_octet **bufp, size_t *remainp) { if (*remainp >= sizeof(int64_t)) { *intp = load_64_be((unsigned char *)*bufp); *bufp += sizeof(int64_t); *remainp -= sizeof(int64_t); return(0); } else return(ENOMEM); } /* * krb5_ser_unpack_bytes() - Unpack a byte string if it's there. */ krb5_error_code KRB5_CALLCONV krb5_ser_unpack_bytes(krb5_octet *istring, size_t isize, krb5_octet **bufp, size_t *remainp) { if (*remainp >= isize) { memcpy(istring, *bufp, isize); *bufp += isize; *remainp -= isize; return(0); } else return(ENOMEM); } krb5-1.22.1/src/lib/krb5/krb/t_copy_context.c0000664000175000017500000001332215051422640020525 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/t_copy_context.C - Test program for krb5_copy_context */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include static void trace(krb5_context ctx, const krb5_trace_info *info, void *data) { } static void check(int cond) { if (!cond) abort(); } static void compare_string(const char *str1, const char *str2) { check((str1 == NULL) == (str2 == NULL)); if (str1 != NULL) check(strcmp(str1, str2) == 0); } static void compare_etypes(krb5_enctype *list1, krb5_enctype *list2) { check((list1 == NULL) == (list2 == NULL)); if (list1 == NULL) return; while (*list1 != ENCTYPE_NULL && *list1 == *list2) list1++, list2++; check(*list1 == *list2); } /* Check that the context c is a valid copy of the reference context r. */ static void check_context(krb5_context c, krb5_context r) { int i; /* Check fields which should have been propagated from r. */ compare_etypes(c->tgs_etypes, r->tgs_etypes); check(c->os_context.time_offset == r->os_context.time_offset); check(c->os_context.usec_offset == r->os_context.usec_offset); check(c->os_context.os_flags == r->os_context.os_flags); compare_string(c->os_context.default_ccname, r->os_context.default_ccname); check(c->clockskew == r->clockskew); check(c->kdc_default_options == r->kdc_default_options); check(c->library_options == r->library_options); check(c->profile_secure == r->profile_secure); check(c->fcc_default_format == r->fcc_default_format); check(c->udp_pref_limit == r->udp_pref_limit); check(c->use_conf_ktypes == r->use_conf_ktypes); check(c->allow_weak_crypto == r->allow_weak_crypto); check(c->ignore_acceptor_hostname == r->ignore_acceptor_hostname); check(c->enforce_ok_as_delegate == r->enforce_ok_as_delegate); check(c->dns_canonicalize_hostname == r->dns_canonicalize_hostname); compare_string(c->plugin_base_dir, r->plugin_base_dir); /* Check fields which don't propagate. */ check(c->dal_handle == NULL); check(c->prompt_types == NULL); check(c->libkrb5_plugins.files == NULL); check(c->preauth_context == NULL); check(c->ccselect_handles == NULL); check(c->localauth_handles == NULL); check(c->hostrealm_handles == NULL); check(c->err.code == 0); check(c->err.msg == NULL); check(c->kdblog_context == NULL); check(c->trace_callback == NULL); check(c->trace_callback_data == NULL); for (i = 0; i < PLUGIN_NUM_INTERFACES; i++) { check(c->plugins[i].modules == NULL); check(!c->plugins[i].configured); } } int main(int argc, char **argv) { krb5_context ctx, ctx2; krb5_plugin_initvt_fn *mods; const krb5_enctype etypes[] = { ENCTYPE_AES128_CTS_HMAC_SHA1_96, ENCTYPE_AES256_CTS_HMAC_SHA1_96, 0 }; krb5_prompt_type ptypes[] = { KRB5_PROMPT_TYPE_PASSWORD }; /* Copy a default context and verify the result. */ check(krb5_init_context(&ctx) == 0); check(krb5_copy_context(ctx, &ctx2) == 0); check_context(ctx2, ctx); krb5_free_context(ctx2); /* Set non-default values for all of the propagated fields in ctx. */ ctx->allow_weak_crypto = TRUE; check(krb5_set_default_tgs_enctypes(ctx, etypes) == 0); check(krb5_set_debugging_time(ctx, 1234, 5678) == 0); check(krb5_cc_set_default_name(ctx, "defccname") == 0); check(krb5_set_default_realm(ctx, "defrealm") == 0); ctx->clockskew = 18; ctx->kdc_default_options = KDC_OPT_FORWARDABLE; ctx->library_options = 0; ctx->profile_secure = TRUE; ctx->udp_pref_limit = 2345; ctx->use_conf_ktypes = TRUE; ctx->ignore_acceptor_hostname = TRUE; ctx->enforce_ok_as_delegate = TRUE; ctx->dns_canonicalize_hostname = CANONHOST_FALSE; free(ctx->plugin_base_dir); check((ctx->plugin_base_dir = strdup("/a/b/c/d")) != NULL); /* Also set some of the non-propagated fields. */ ctx->prompt_types = ptypes; check(k5_plugin_load_all(ctx, PLUGIN_INTERFACE_PWQUAL, &mods) == 0); k5_plugin_free_modules(ctx, mods); k5_setmsg(ctx, ENOMEM, "nooooooooo"); krb5_set_trace_callback(ctx, trace, ctx); /* Copy the intentionally messy context and verify the result. */ check(krb5_copy_context(ctx, &ctx2) == 0); check_context(ctx2, ctx); krb5_free_context(ctx2); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/lib/krb5/krb/copy_ctx.c0000664000175000017500000001056315051422640017320 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/copy_ctx.c */ /* * Copyright 1994,1999,2000, 2002, 2003, 2007, 2008, 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "k5-int.h" #include "int-proto.h" #include krb5_error_code KRB5_CALLCONV krb5_copy_context(krb5_context ctx, krb5_context *nctx_out) { krb5_error_code ret; krb5_context nctx; *nctx_out = NULL; if (ctx == NULL) return EINVAL; /* XXX */ nctx = malloc(sizeof(*nctx)); if (nctx == NULL) return ENOMEM; *nctx = *ctx; nctx->tgs_etypes = NULL; nctx->default_realm = NULL; nctx->profile = NULL; nctx->dal_handle = NULL; nctx->prompt_types = NULL; nctx->preauth_context = NULL; nctx->ccselect_handles = NULL; nctx->localauth_handles = NULL; nctx->hostrealm_handles = NULL; nctx->tls = NULL; nctx->kdblog_context = NULL; nctx->trace_callback = NULL; nctx->trace_callback_data = NULL; nctx->err_fmt = NULL; if (ctx->err_fmt != NULL) nctx->err_fmt = strdup(ctx->err_fmt); /* It's OK if this fails */ nctx->plugin_base_dir = NULL; nctx->os_context.default_ccname = NULL; memset(&nctx->libkrb5_plugins, 0, sizeof(nctx->libkrb5_plugins)); memset(&nctx->err, 0, sizeof(nctx->err)); memset(&nctx->plugins, 0, sizeof(nctx->plugins)); ret = k5_copy_etypes(ctx->tgs_etypes, &nctx->tgs_etypes); if (ret) goto errout; if (ctx->os_context.default_ccname != NULL) { nctx->os_context.default_ccname = strdup(ctx->os_context.default_ccname); if (nctx->os_context.default_ccname == NULL) { ret = ENOMEM; goto errout; } } ret = krb5_get_profile(ctx, &nctx->profile); if (ret) goto errout; nctx->plugin_base_dir = strdup(ctx->plugin_base_dir); if (nctx->plugin_base_dir == NULL) { ret = ENOMEM; goto errout; } errout: if (ret) { krb5_free_context(nctx); } else { *nctx_out = nctx; } return ret; } krb5-1.22.1/src/lib/krb5/krb/kfree.c0000664000175000017500000005531015051422640016563 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/kfree.c */ /* * Copyright 1990-1998, 2009 by the Massachusetts Institute of Technology. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (c) 2006-2008, Novell, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * The copyright holder's name is not used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "k5-spake.h" #include void KRB5_CALLCONV krb5_free_address(krb5_context context, krb5_address *val) { if (val == NULL) return; free(val->contents); free(val); } void KRB5_CALLCONV krb5_free_addresses(krb5_context context, krb5_address **val) { krb5_address **temp; if (val == NULL) return; for (temp = val; *temp; temp++) { free((*temp)->contents); free(*temp); } free(val); } void KRB5_CALLCONV krb5_free_ap_rep(krb5_context context, krb5_ap_rep *val) { if (val == NULL) return; free(val->enc_part.ciphertext.data); free(val); } void KRB5_CALLCONV krb5_free_ap_req(krb5_context context, krb5_ap_req *val) { if (val == NULL) return; krb5_free_ticket(context, val->ticket); free(val->authenticator.ciphertext.data); free(val); } void KRB5_CALLCONV krb5_free_ap_rep_enc_part(krb5_context context, krb5_ap_rep_enc_part *val) { if (val == NULL) return; krb5_free_keyblock(context, val->subkey); free(val); } void KRB5_CALLCONV krb5_free_authenticator_contents(krb5_context context, krb5_authenticator *val) { if (val == NULL) return; krb5_free_checksum(context, val->checksum); val->checksum = 0; krb5_free_principal(context, val->client); val->client = 0; krb5_free_keyblock(context, val->subkey); val->subkey = 0; krb5_free_authdata(context, val->authorization_data); val->authorization_data = 0; } void KRB5_CALLCONV krb5_free_authenticator(krb5_context context, krb5_authenticator *val) { if (val == NULL) return; krb5_free_authenticator_contents(context, val); free(val); } void KRB5_CALLCONV krb5_free_checksum(krb5_context context, krb5_checksum *val) { if (val == NULL) return; krb5_free_checksum_contents(context, val); free(val); } void KRB5_CALLCONV krb5_free_checksum_contents(krb5_context context, krb5_checksum *val) { if (val == NULL) return; free(val->contents); val->contents = NULL; val->length = 0; } void KRB5_CALLCONV krb5_free_cred(krb5_context context, krb5_cred *val) { if (val == NULL) return; krb5_free_tickets(context, val->tickets); free(val->enc_part.ciphertext.data); free(val); } /* * krb5_free_cred_contents zeros out the session key, and then frees * the credentials structures */ void KRB5_CALLCONV krb5_free_cred_contents(krb5_context context, krb5_creds *val) { if (val == NULL) return; krb5_free_principal(context, val->client); val->client = 0; krb5_free_principal(context, val->server); val->server = 0; krb5_free_keyblock_contents(context, &val->keyblock); free(val->ticket.data); val->ticket.data = 0; free(val->second_ticket.data); val->second_ticket.data = 0; krb5_free_addresses(context, val->addresses); val->addresses = 0; krb5_free_authdata(context, val->authdata); val->authdata = 0; } void KRB5_CALLCONV krb5_free_cred_enc_part(krb5_context context, krb5_cred_enc_part *val) { krb5_cred_info **temp; if (val == NULL) return; krb5_free_address(context, val->r_address); val->r_address = 0; krb5_free_address(context, val->s_address); val->s_address = 0; if (val->ticket_info) { for (temp = val->ticket_info; *temp; temp++) { krb5_free_keyblock(context, (*temp)->session); krb5_free_principal(context, (*temp)->client); krb5_free_principal(context, (*temp)->server); krb5_free_addresses(context, (*temp)->caddrs); free(*temp); } free(val->ticket_info); val->ticket_info = 0; } } void KRB5_CALLCONV krb5_free_creds(krb5_context context, krb5_creds *val) { if (val == NULL) return; krb5_free_cred_contents(context, val); free(val); } void KRB5_CALLCONV krb5_free_data(krb5_context context, krb5_data *val) { if (val == NULL) return; free(val->data); free(val); } void KRB5_CALLCONV krb5_free_octet_data(krb5_context context, krb5_octet_data *val) { if (val == NULL) return; free(val->data); free(val); } void KRB5_CALLCONV krb5_free_data_contents(krb5_context context, krb5_data *val) { if (val == NULL) return; free(val->data); val->data = NULL; val->length = 0; } void KRB5_CALLCONV krb5_free_enc_data(krb5_context context, krb5_enc_data *val) { if (val == NULL) return; krb5_free_data_contents(context, &val->ciphertext); free(val); } void krb5_free_etype_info(krb5_context context, krb5_etype_info info) { size_t i; if (info == NULL) return; for (i=0; info[i] != NULL; i++) { free(info[i]->salt); krb5_free_data_contents(context, &info[i]->s2kparams); free(info[i]); } free(info); } void KRB5_CALLCONV krb5_free_enc_kdc_rep_part(krb5_context context, krb5_enc_kdc_rep_part *val) { if (val == NULL) return; krb5_free_keyblock(context, val->session); krb5_free_last_req(context, val->last_req); krb5_free_principal(context, val->server); krb5_free_addresses(context, val->caddrs); krb5_free_pa_data(context, val->enc_padata); free(val); } void KRB5_CALLCONV krb5_free_enc_tkt_part(krb5_context context, krb5_enc_tkt_part *val) { if (val == NULL) return; krb5_free_keyblock(context, val->session); krb5_free_principal(context, val->client); free(val->transited.tr_contents.data); krb5_free_addresses(context, val->caddrs); krb5_free_authdata(context, val->authorization_data); free(val); } void KRB5_CALLCONV krb5_free_error(krb5_context context, krb5_error *val) { if (val == NULL) return; krb5_free_principal(context, val->client); krb5_free_principal(context, val->server); free(val->text.data); free(val->e_data.data); free(val); } void KRB5_CALLCONV krb5_free_kdc_rep(krb5_context context, krb5_kdc_rep *val) { if (val == NULL) return; krb5_free_pa_data(context, val->padata); krb5_free_principal(context, val->client); krb5_free_ticket(context, val->ticket); free(val->enc_part.ciphertext.data); krb5_free_enc_kdc_rep_part(context, val->enc_part2); free(val); } void KRB5_CALLCONV krb5_free_kdc_req(krb5_context context, krb5_kdc_req *val) { if (val == NULL) return; krb5_free_pa_data(context, val->padata); krb5_free_principal(context, val->client); krb5_free_principal(context, val->server); free(val->ktype); krb5_free_addresses(context, val->addresses); free(val->authorization_data.ciphertext.data); krb5_free_authdata(context, val->unenc_authdata); krb5_free_tickets(context, val->second_ticket); free(val); } void KRB5_CALLCONV krb5_free_keyblock_contents(krb5_context context, krb5_keyblock *key) { krb5int_c_free_keyblock_contents (context, key); } void KRB5_CALLCONV krb5_free_keyblock(krb5_context context, krb5_keyblock *val) { krb5int_c_free_keyblock (context, val); } void KRB5_CALLCONV krb5_free_last_req(krb5_context context, krb5_last_req_entry **val) { krb5_last_req_entry **temp; if (val == NULL) return; for (temp = val; *temp; temp++) free(*temp); free(val); } void k5_zapfree_pa_data(krb5_pa_data **val) { krb5_pa_data **pa; if (val == NULL) return; for (pa = val; *pa != NULL; pa++) { zapfree((*pa)->contents, (*pa)->length); zapfree(*pa, sizeof(**pa)); } free(val); } void KRB5_CALLCONV krb5_free_pa_data(krb5_context context, krb5_pa_data **val) { krb5_pa_data **temp; if (val == NULL) return; for (temp = val; *temp; temp++) { free((*temp)->contents); free(*temp); } free(val); } void KRB5_CALLCONV krb5_free_principal(krb5_context context, krb5_principal val) { krb5_int32 i; if (!val) return; if (val->data) { i = val->length; while(--i >= 0) free(val->data[i].data); free(val->data); } free(val->realm.data); free(val); } void KRB5_CALLCONV krb5_free_priv(krb5_context context, krb5_priv *val) { if (val == NULL) return; free(val->enc_part.ciphertext.data); free(val); } void KRB5_CALLCONV krb5_free_priv_enc_part(krb5_context context, krb5_priv_enc_part *val) { if (val == NULL) return; free(val->user_data.data); krb5_free_address(context, val->r_address); krb5_free_address(context, val->s_address); free(val); } void KRB5_CALLCONV krb5_free_safe(krb5_context context, krb5_safe *val) { if (val == NULL) return; free(val->user_data.data); krb5_free_address(context, val->r_address); krb5_free_address(context, val->s_address); krb5_free_checksum(context, val->checksum); free(val); } void KRB5_CALLCONV krb5_free_ticket(krb5_context context, krb5_ticket *val) { if (val == NULL) return; krb5_free_principal(context, val->server); free(val->enc_part.ciphertext.data); krb5_free_enc_tkt_part(context, val->enc_part2); free(val); } void KRB5_CALLCONV krb5_free_tickets(krb5_context context, krb5_ticket **val) { krb5_ticket **temp; if (val == NULL) return; for (temp = val; *temp; temp++) krb5_free_ticket(context, *temp); free(val); } void KRB5_CALLCONV krb5_free_tgt_creds(krb5_context context, krb5_creds **tgts) { krb5_creds **tgtpp; if (tgts == NULL) return; for (tgtpp = tgts; *tgtpp; tgtpp++) krb5_free_creds(context, *tgtpp); free(tgts); } void KRB5_CALLCONV krb5_free_tkt_authent(krb5_context context, krb5_tkt_authent *val) { if (val == NULL) return; krb5_free_ticket(context, val->ticket); krb5_free_authenticator(context, val->authenticator); free(val); } void KRB5_CALLCONV krb5_free_unparsed_name(krb5_context context, char *val) { if (val != NULL) free(val); } void KRB5_CALLCONV krb5_free_string(krb5_context context, char *val) { free(val); } void KRB5_CALLCONV krb5_free_sam_challenge_2(krb5_context ctx, krb5_sam_challenge_2 *sc2) { if (!sc2) return; krb5_free_sam_challenge_2_contents(ctx, sc2); free(sc2); } void KRB5_CALLCONV krb5_free_sam_challenge_2_contents(krb5_context ctx, krb5_sam_challenge_2 *sc2) { krb5_checksum **cksump; if (!sc2) return; if (sc2->sam_challenge_2_body.data) krb5_free_data_contents(ctx, &sc2->sam_challenge_2_body); if (sc2->sam_cksum) { cksump = sc2->sam_cksum; while (*cksump) { krb5_free_checksum(ctx, *cksump); cksump++; } free(sc2->sam_cksum); sc2->sam_cksum = 0; } } void KRB5_CALLCONV krb5_free_sam_challenge_2_body(krb5_context ctx, krb5_sam_challenge_2_body *sc2) { if (!sc2) return; krb5_free_sam_challenge_2_body_contents(ctx, sc2); free(sc2); } void KRB5_CALLCONV krb5_free_sam_challenge_2_body_contents(krb5_context ctx, krb5_sam_challenge_2_body *sc2) { if (!sc2) return; if (sc2->sam_type_name.data) krb5_free_data_contents(ctx, &sc2->sam_type_name); if (sc2->sam_track_id.data) krb5_free_data_contents(ctx, &sc2->sam_track_id); if (sc2->sam_challenge_label.data) krb5_free_data_contents(ctx, &sc2->sam_challenge_label); if (sc2->sam_challenge.data) krb5_free_data_contents(ctx, &sc2->sam_challenge); if (sc2->sam_response_prompt.data) krb5_free_data_contents(ctx, &sc2->sam_response_prompt); if (sc2->sam_pk_for_sad.data) krb5_free_data_contents(ctx, &sc2->sam_pk_for_sad); } void KRB5_CALLCONV krb5_free_sam_response_2(krb5_context ctx, krb5_sam_response_2 *sr2) { if (!sr2) return; krb5_free_sam_response_2_contents(ctx, sr2); free(sr2); } void KRB5_CALLCONV krb5_free_sam_response_2_contents(krb5_context ctx, krb5_sam_response_2 *sr2) { if (!sr2) return; if (sr2->sam_track_id.data) krb5_free_data_contents(ctx, &sr2->sam_track_id); if (sr2->sam_enc_nonce_or_sad.ciphertext.data) krb5_free_data_contents(ctx, &sr2->sam_enc_nonce_or_sad.ciphertext); } void KRB5_CALLCONV krb5_free_enc_sam_response_enc_2(krb5_context ctx, krb5_enc_sam_response_enc_2 *esre2) { if (!esre2) return; krb5_free_enc_sam_response_enc_2_contents(ctx, esre2); free(esre2); } void KRB5_CALLCONV krb5_free_enc_sam_response_enc_2_contents(krb5_context ctx, krb5_enc_sam_response_enc_2 *esre2) { if (!esre2) return; if (esre2->sam_sad.data) krb5_free_data_contents(ctx, &esre2->sam_sad); } void KRB5_CALLCONV krb5_free_pa_enc_ts(krb5_context ctx, krb5_pa_enc_ts *pa_enc_ts) { if (!pa_enc_ts) return; free(pa_enc_ts); } void KRB5_CALLCONV krb5_free_pa_for_user(krb5_context context, krb5_pa_for_user *req) { if (req == NULL) return; krb5_free_principal(context, req->user); req->user = NULL; krb5_free_checksum_contents(context, &req->cksum); krb5_free_data_contents(context, &req->auth_package); free(req); } void KRB5_CALLCONV krb5_free_s4u_userid_contents(krb5_context context, krb5_s4u_userid *user_id) { if (user_id == NULL) return; user_id->nonce = 0; krb5_free_principal(context, user_id->user); user_id->user = NULL; krb5_free_data_contents(context, &user_id->subject_cert); user_id->subject_cert.length = 0; user_id->subject_cert.data = NULL; user_id->options = 0; } void KRB5_CALLCONV krb5_free_pa_s4u_x509_user(krb5_context context, krb5_pa_s4u_x509_user *req) { if (req == NULL) return; krb5_free_s4u_userid_contents(context, &req->user_id); krb5_free_checksum_contents(context, &req->cksum); free(req); } void KRB5_CALLCONV krb5_free_pa_pac_req(krb5_context context, krb5_pa_pac_req *req) { free(req); } void KRB5_CALLCONV krb5_free_fast_req(krb5_context context, krb5_fast_req *val) { if (val == NULL) return; krb5_free_kdc_req(context, val->req_body); free(val); } void KRB5_CALLCONV krb5_free_fast_armor(krb5_context context, krb5_fast_armor *val) { if (val == NULL) return; krb5_free_data_contents(context, &val->armor_value); free(val); } void KRB5_CALLCONV krb5_free_fast_response(krb5_context context, krb5_fast_response *val) { if (!val) return; krb5_free_pa_data(context, val->padata); krb5_free_fast_finished(context, val->finished); krb5_free_keyblock(context, val->strengthen_key); free(val); } void KRB5_CALLCONV krb5_free_fast_finished(krb5_context context, krb5_fast_finished *val) { if (!val) return; krb5_free_principal(context, val->client); krb5_free_checksum_contents(context, &val->ticket_checksum); free(val); } void KRB5_CALLCONV krb5_free_fast_armored_req(krb5_context context, krb5_fast_armored_req *val) { if (val == NULL) return; if (val->armor) krb5_free_fast_armor(context, val->armor); krb5_free_data_contents(context, &val->enc_part.ciphertext); if (val->req_checksum.contents) krb5_free_checksum_contents(context, &val->req_checksum); free(val); } void k5_free_data_ptr_list(krb5_data **list) { size_t i; for (i = 0; list != NULL && list[i] != NULL; i++) krb5_free_data(NULL, list[i]); free(list); } void KRB5_CALLCONV krb5int_free_data_list(krb5_context context, krb5_data *data) { size_t i; if (data == NULL) return; for (i = 0; data[i].data != NULL; i++) free(data[i].data); free(data); } void KRB5_CALLCONV krb5_free_ad_kdcissued(krb5_context context, krb5_ad_kdcissued *val) { if (val == NULL) return; krb5_free_checksum_contents(context, &val->ad_checksum); krb5_free_principal(context, val->i_principal); krb5_free_authdata(context, val->elements); free(val); } void KRB5_CALLCONV krb5_free_iakerb_header(krb5_context context, krb5_iakerb_header *val) { if (val == NULL) return ; krb5_free_data_contents(context, &val->target_realm); krb5_free_data(context, val->cookie); free(val); } void KRB5_CALLCONV krb5_free_iakerb_finished(krb5_context context, krb5_iakerb_finished *val) { if (val == NULL) return ; krb5_free_checksum_contents(context, &val->checksum); free(val); } void k5_free_algorithm_identifier(krb5_context context, krb5_algorithm_identifier *val) { if (val == NULL) return; free(val->algorithm.data); free(val->parameters.data); free(val); } void k5_free_otp_tokeninfo(krb5_context context, krb5_otp_tokeninfo *val) { krb5_algorithm_identifier **alg; if (val == NULL) return; free(val->vendor.data); free(val->challenge.data); free(val->token_id.data); free(val->alg_id.data); for (alg = val->supported_hash_alg; alg != NULL && *alg != NULL; alg++) k5_free_algorithm_identifier(context, *alg); free(val->supported_hash_alg); free(val); } void k5_free_pa_otp_challenge(krb5_context context, krb5_pa_otp_challenge *val) { krb5_otp_tokeninfo **ti; if (val == NULL) return; free(val->nonce.data); free(val->service.data); for (ti = val->tokeninfo; *ti != NULL; ti++) k5_free_otp_tokeninfo(context, *ti); free(val->tokeninfo); free(val->salt.data); free(val->s2kparams.data); free(val); } void k5_free_pa_otp_req(krb5_context context, krb5_pa_otp_req *val) { if (val == NULL) return; val->flags = 0; free(val->nonce.data); free(val->enc_data.ciphertext.data); if (val->hash_alg != NULL) k5_free_algorithm_identifier(context, val->hash_alg); free(val->otp_value.data); free(val->pin.data); free(val->challenge.data); free(val->counter.data); free(val->token_id.data); free(val->alg_id.data); free(val->vendor.data); free(val); } void k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val) { if (val == NULL) return; free(val->target_domain.data); free(val->kerb_message.data); free(val); } static void free_vmac(krb5_context context, krb5_verifier_mac *val) { if (val == NULL) return; krb5_free_principal(context, val->princ); krb5_free_checksum_contents(context, &val->checksum); free(val); } void k5_free_cammac(krb5_context context, krb5_cammac *val) { krb5_verifier_mac **vp; if (val == NULL) return; krb5_free_authdata(context, val->elements); free_vmac(context, val->kdc_verifier); free_vmac(context, val->svc_verifier); for (vp = val->other_verifiers; vp != NULL && *vp != NULL; vp++) free_vmac(context, *vp); free(val->other_verifiers); free(val); } void k5_free_secure_cookie(krb5_context context, krb5_secure_cookie *val) { if (val == NULL) return; k5_zapfree_pa_data(val->data); free(val); } void k5_free_spake_factor(krb5_context context, krb5_spake_factor *val) { if (val == NULL) return; if (val->data != NULL) zapfree(val->data->data, val->data->length); free(val->data); free(val); } void k5_free_pa_spake(krb5_context context, krb5_pa_spake *val) { krb5_spake_factor **f; if (val == NULL) return; switch (val->choice) { case SPAKE_MSGTYPE_SUPPORT: free(val->u.support.groups); break; case SPAKE_MSGTYPE_CHALLENGE: krb5_free_data_contents(context, &val->u.challenge.pubkey); for (f = val->u.challenge.factors; f != NULL && *f != NULL; f++) k5_free_spake_factor(context, *f); free(val->u.challenge.factors); break; case SPAKE_MSGTYPE_RESPONSE: krb5_free_data_contents(context, &val->u.response.pubkey); krb5_free_data_contents(context, &val->u.response.factor.ciphertext); break; case SPAKE_MSGTYPE_ENCDATA: krb5_free_data_contents(context, &val->u.encdata.ciphertext); break; default: break; } free(val); } krb5-1.22.1/src/lib/krb5/krb/t_ref_kerb.out0000664000175000017500000000341115051422640020151 0ustar ghudsonghudsonparsed (and unparsed) principal(tytso): 'tytso@ATHENA.MIT.EDU' parsed (and unparsed) principal(tytso@SHAZAAM): MATCH parsed (and unparsed) principal(tytso/root@VEGGIE.COM): MATCH parsed (and unparsed) principal(tytso/tuber/carrot@VEGGIE.COM): MATCH parsed (and unparsed) principal(tytso/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t): 'tytso/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t@ATHENA.MIT.EDU' parsed (and unparsed) principal(tytso/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t@FOO): MATCH parsed (and unparsed) principal(tytso\\0/\0@B\n\t\\GAG): MATCH parsed (and unparsed) principal(tytso/\n/\b\t@B\0hacky-test): MATCH parsed (and unparsed) principal(\/slash/\@atsign/octa\/thorpe@\/slash\@at\/sign): MATCH name_type principal(host/www.krb5.test@KRB5.TEST): 1 name_type principal(krbtg/KRB5.TEST@KRB5.TEST): 1 name_type principal(krbtgt/KRB5.TEST@KRB5.TEST): 2 name_type principal(WELLKNOWN/ANONYMOUS@KRB5.TEST): 11 425_converted principal(rcmd, e40-po, ATHENA.MIT.EDU): 'host/e40-po.mit.edu@ATHENA.MIT.EDU' 425_converted principal(rcmd, mit, ATHENA.MIT.EDU): 'host/mit.edu@ATHENA.MIT.EDU' 425_converted principal(rcmd, lithium, ATHENA.MIT.EDU): 'host/lithium.lcs.mit.edu@ATHENA.MIT.EDU' 425_converted principal(rcmd, tweedledumb, CYGNUS.COM): 'host/tweedledumb.cygnus.com@CYGNUS.COM' 425_converted principal(rcmd, uunet, UU.NET): 'host/uunet.uu.net@UU.NET' 425_converted principal(zephyr, zephyr, ATHENA.MIT.EDU): 'zephyr/zephyr@ATHENA.MIT.EDU' 425_converted principal(kadmin, ATHENA.MIT.EDU, ATHENA.MIT.EDU): 'kadmin/ATHENA.MIT.EDU@ATHENA.MIT.EDU' 524_converted_principal(host/e40-po.mit.edu@ATHENA.MIT.EDU): 'rcmd' 'e40-po' 'ATHENA.MIT.EDU' 524_converted_principal(host/foobar.stanford.edu@stanford.edu): 'rcmd' 'foobar' 'IR.STANFORD.EDU' old principal: marc@MIT.EDU, modified principal: marc@CYGNUS.COM krb5-1.22.1/src/lib/krb5/krb/Makefile.in0000664000175000017500000003670215051422640017374 0ustar ghudsonghudsonmydir=lib$(S)krb5$(S)krb BUILDTOP=$(REL)..$(S)..$(S).. LOCALINCLUDES = -I$(srcdir)/../os -I$(top_srcdir) DEFINES=-DLIBDIR=\"$(KRB5_LIBDIR)\" -DDYNOBJEXT=\"$(DYNOBJEXT)\" # Like RUN_TEST, but use t_krb5.conf from this directory. RUN_TEST_LOCAL_CONF=$(RUN_SETUP) KRB5_CONFIG=$(srcdir)/t_krb5.conf LC_ALL=C \ $(VALGRIND) ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=krb ##DOS##OBJFILE=..\$(OUTPRE)$(PREFIXDIR).lst STLIBOBJS= \ addr_comp.o \ addr_order.o \ addr_srch.o \ allow_weak.o \ appdefault.o \ ai_authdata.o \ auth_con.o \ cammac_util.o \ authdata.o \ authdata_exp.o \ authdata_enc.o \ authdata_dec.o \ bld_pr_ext.o \ bld_princ.o \ chk_trans.o \ chpw.o \ conv_creds.o \ conv_princ.o \ copy_addrs.o \ copy_auth.o \ copy_athctr.o \ copy_cksum.o \ copy_creds.o \ copy_data.o \ copy_key.o \ copy_princ.o \ copy_tick.o \ cp_key_cnt.o \ decode_kdc.o \ decrypt_tk.o \ deltat.o \ enc_helper.o \ enc_keyhelper.o \ encode_kdc.o \ encrypt_tk.o \ etype_list.o \ fast.o \ fwd_tgt.o \ gc_via_tkt.o \ gen_seqnum.o \ gen_subkey.o \ gen_save_subkey.o \ get_creds.o \ get_etype_info.o \ get_in_tkt.o \ gic_keytab.o \ gic_opt.o \ gic_pwd.o \ in_tkt_sky.o \ init_ctx.o \ copy_ctx.o \ init_keyblock.o \ kdc_rep_dc.o \ kerrs.o \ kfree.o \ libdef_parse.o \ mk_cred.o \ mk_error.o \ mk_priv.o \ mk_rep.o \ mk_req.o \ mk_req_ext.o \ mk_safe.o \ pac.o \ pac_sign.o \ padata.o \ parse.o \ parse_host_string.o \ plugin.o \ pr_to_salt.o \ preauth2.o \ preauth_ec.o \ preauth_encts.o \ preauth_otp.o \ preauth_pkinit.o \ preauth_sam2.o \ princ_comp.o \ privsafe.o \ random_str.o \ rd_cred.o \ rd_error.o \ rd_priv.o \ rd_rep.o \ rd_req.o \ rd_req_dec.o \ rd_safe.o \ recvauth.o \ response_items.o \ s4u_creds.o \ sendauth.o \ send_tgs.o \ ser_actx.o \ ser_adata.o \ ser_addr.o \ ser_auth.o \ ser_cksum.o \ ser_ctx.o \ ser_key.o \ ser_princ.o \ serialize.o \ set_realm.o \ sname_match.o \ srv_dec_tkt.o \ srv_rcache.o \ str_conv.o \ tgtname.o \ unparse.o \ val_renew.o \ valid_times.o \ vfy_increds.o \ vic_opt.o \ walk_rtree.o OBJS= $(OUTPRE)addr_comp.$(OBJEXT) \ $(OUTPRE)addr_order.$(OBJEXT) \ $(OUTPRE)addr_srch.$(OBJEXT) \ $(OUTPRE)allow_weak.$(OBJEXT) \ $(OUTPRE)appdefault.$(OBJEXT) \ $(OUTPRE)ai_authdata.$(OBJEXT) \ $(OUTPRE)auth_con.$(OBJEXT) \ $(OUTPRE)cammac_util.$(OBJEXT) \ $(OUTPRE)authdata.$(OBJEXT) \ $(OUTPRE)authdata_exp.$(OBJEXT) \ $(OUTPRE)authdata_enc.$(OBJEXT) \ $(OUTPRE)authdata_dec.$(OBJEXT) \ $(OUTPRE)bld_pr_ext.$(OBJEXT) \ $(OUTPRE)bld_princ.$(OBJEXT) \ $(OUTPRE)chk_trans.$(OBJEXT) \ $(OUTPRE)chpw.$(OBJEXT) \ $(OUTPRE)conv_creds.$(OBJEXT) \ $(OUTPRE)conv_princ.$(OBJEXT) \ $(OUTPRE)copy_addrs.$(OBJEXT) \ $(OUTPRE)copy_auth.$(OBJEXT) \ $(OUTPRE)copy_athctr.$(OBJEXT) \ $(OUTPRE)copy_cksum.$(OBJEXT) \ $(OUTPRE)copy_creds.$(OBJEXT) \ $(OUTPRE)copy_data.$(OBJEXT) \ $(OUTPRE)copy_key.$(OBJEXT) \ $(OUTPRE)copy_princ.$(OBJEXT) \ $(OUTPRE)copy_tick.$(OBJEXT) \ $(OUTPRE)cp_key_cnt.$(OBJEXT) \ $(OUTPRE)decode_kdc.$(OBJEXT) \ $(OUTPRE)decrypt_tk.$(OBJEXT) \ $(OUTPRE)deltat.$(OBJEXT) \ $(OUTPRE)enc_helper.$(OBJEXT) \ $(OUTPRE)enc_keyhelper.$(OBJEXT) \ $(OUTPRE)encode_kdc.$(OBJEXT) \ $(OUTPRE)encrypt_tk.$(OBJEXT) \ $(OUTPRE)etype_list.$(OBJEXT) \ $(OUTPRE)fast.$(OBJEXT) \ $(OUTPRE)fwd_tgt.$(OBJEXT) \ $(OUTPRE)gc_via_tkt.$(OBJEXT) \ $(OUTPRE)gen_seqnum.$(OBJEXT) \ $(OUTPRE)gen_subkey.$(OBJEXT) \ $(OUTPRE)gen_save_subkey.$(OBJEXT) \ $(OUTPRE)get_creds.$(OBJEXT) \ $(OUTPRE)get_etype_info.$(OBJEXT) \ $(OUTPRE)get_in_tkt.$(OBJEXT) \ $(OUTPRE)gic_keytab.$(OBJEXT) \ $(OUTPRE)gic_opt.$(OBJEXT) \ $(OUTPRE)gic_pwd.$(OBJEXT) \ $(OUTPRE)in_tkt_sky.$(OBJEXT) \ $(OUTPRE)init_ctx.$(OBJEXT) \ $(OUTPRE)copy_ctx.$(OBJEXT) \ $(OUTPRE)init_keyblock.$(OBJEXT) \ $(OUTPRE)kdc_rep_dc.$(OBJEXT) \ $(OUTPRE)kerrs.$(OBJEXT) \ $(OUTPRE)kfree.$(OBJEXT) \ $(OUTPRE)libdef_parse.$(OBJEXT) \ $(OUTPRE)mk_cred.$(OBJEXT) \ $(OUTPRE)mk_error.$(OBJEXT) \ $(OUTPRE)mk_priv.$(OBJEXT) \ $(OUTPRE)mk_rep.$(OBJEXT) \ $(OUTPRE)mk_req.$(OBJEXT) \ $(OUTPRE)mk_req_ext.$(OBJEXT) \ $(OUTPRE)mk_safe.$(OBJEXT) \ $(OUTPRE)pac.$(OBJEXT) \ $(OUTPRE)pac_sign.$(OBJEXT) \ $(OUTPRE)padata.$(OBJEXT) \ $(OUTPRE)parse.$(OBJEXT) \ $(OUTPRE)parse_host_string.$(OBJEXT) \ $(OUTPRE)plugin.$(OBJEXT) \ $(OUTPRE)pr_to_salt.$(OBJEXT) \ $(OUTPRE)preauth2.$(OBJEXT) \ $(OUTPRE)preauth_ec.$(OBJEXT) \ $(OUTPRE)preauth_encts.$(OBJEXT) \ $(OUTPRE)preauth_otp.$(OBJEXT) \ $(OUTPRE)preauth_pkinit.$(OBJEXT) \ $(OUTPRE)preauth_sam2.$(OBJEXT) \ $(OUTPRE)princ_comp.$(OBJEXT) \ $(OUTPRE)privsafe.$(OBJEXT) \ $(OUTPRE)random_str.$(OBJEXT) \ $(OUTPRE)rd_cred.$(OBJEXT) \ $(OUTPRE)rd_error.$(OBJEXT) \ $(OUTPRE)rd_priv.$(OBJEXT) \ $(OUTPRE)rd_rep.$(OBJEXT) \ $(OUTPRE)rd_req.$(OBJEXT) \ $(OUTPRE)rd_req_dec.$(OBJEXT) \ $(OUTPRE)rd_safe.$(OBJEXT) \ $(OUTPRE)recvauth.$(OBJEXT) \ $(OUTPRE)response_items.$(OBJEXT) \ $(OUTPRE)s4u_creds.$(OBJEXT) \ $(OUTPRE)sendauth.$(OBJEXT) \ $(OUTPRE)send_tgs.$(OBJEXT) \ $(OUTPRE)ser_actx.$(OBJEXT) \ $(OUTPRE)ser_adata.$(OBJEXT) \ $(OUTPRE)ser_addr.$(OBJEXT) \ $(OUTPRE)ser_auth.$(OBJEXT) \ $(OUTPRE)ser_cksum.$(OBJEXT) \ $(OUTPRE)ser_ctx.$(OBJEXT) \ $(OUTPRE)ser_key.$(OBJEXT) \ $(OUTPRE)ser_princ.$(OBJEXT) \ $(OUTPRE)serialize.$(OBJEXT) \ $(OUTPRE)set_realm.$(OBJEXT) \ $(OUTPRE)sname_match.$(OBJEXT) \ $(OUTPRE)srv_dec_tkt.$(OBJEXT) \ $(OUTPRE)srv_rcache.$(OBJEXT) \ $(OUTPRE)str_conv.$(OBJEXT) \ $(OUTPRE)tgtname.$(OBJEXT) \ $(OUTPRE)unparse.$(OBJEXT) \ $(OUTPRE)val_renew.$(OBJEXT) \ $(OUTPRE)valid_times.$(OBJEXT) \ $(OUTPRE)vfy_increds.$(OBJEXT) \ $(OUTPRE)vic_opt.$(OBJEXT) \ $(OUTPRE)walk_rtree.$(OBJEXT) SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/addr_order.c \ $(srcdir)/addr_srch.c \ $(srcdir)/appdefault.c \ $(srcdir)/auth_con.c \ $(srcdir)/cammac_util.c \ $(srcdir)/ai_authdata.c \ $(srcdir)/authdata.c \ $(srcdir)/authdata_exp.c \ $(srcdir)/authdata_enc.c \ $(srcdir)/authdata_dec.c \ $(srcdir)/bld_pr_ext.c \ $(srcdir)/bld_princ.c \ $(srcdir)/brand.c \ $(srcdir)/chk_trans.c \ $(srcdir)/chpw.c \ $(srcdir)/conv_creds.c \ $(srcdir)/conv_princ.c \ $(srcdir)/copy_addrs.c \ $(srcdir)/copy_auth.c \ $(srcdir)/copy_athctr.c \ $(srcdir)/copy_cksum.c \ $(srcdir)/copy_creds.c \ $(srcdir)/copy_data.c \ $(srcdir)/copy_key.c \ $(srcdir)/copy_princ.c \ $(srcdir)/copy_tick.c \ $(srcdir)/cp_key_cnt.c \ $(srcdir)/decode_kdc.c \ $(srcdir)/decrypt_tk.c \ $(srcdir)/deltat.c \ $(srcdir)/enc_helper.c \ $(srcdir)/enc_keyhelper.c \ $(srcdir)/encode_kdc.c \ $(srcdir)/encrypt_tk.c \ $(srcdir)/etype_list.c \ $(srcdir)/fast.c \ $(srcdir)/fwd_tgt.c \ $(srcdir)/gc_via_tkt.c \ $(srcdir)/gen_seqnum.c \ $(srcdir)/gen_subkey.c \ $(srcdir)/gen_save_subkey.c \ $(srcdir)/get_creds.c \ $(srcdir)/get_etype_info.c \ $(srcdir)/get_in_tkt.c \ $(srcdir)/gic_keytab.c \ $(srcdir)/gic_opt.c \ $(srcdir)/gic_pwd.c \ $(srcdir)/in_tkt_sky.c \ $(srcdir)/init_ctx.c \ $(srcdir)/copy_ctx.c \ $(srcdir)/init_keyblock.c \ $(srcdir)/kdc_rep_dc.c \ $(srcdir)/kerrs.c \ $(srcdir)/kfree.c \ $(srcdir)/libdef_parse.c \ $(srcdir)/mk_cred.c \ $(srcdir)/mk_error.c \ $(srcdir)/mk_priv.c \ $(srcdir)/mk_rep.c \ $(srcdir)/mk_req.c \ $(srcdir)/mk_req_ext.c \ $(srcdir)/mk_safe.c \ $(srcdir)/pac.c \ $(srcdir)/pac_sign.c \ $(srcdir)/padata.c \ $(srcdir)/parse.c \ $(srcdir)/parse_host_string.c \ $(srcdir)/plugin.c \ $(srcdir)/pr_to_salt.c \ $(srcdir)/preauth2.c \ $(srcdir)/preauth_ec.c \ $(srcdir)/preauth_encts.c \ $(srcdir)/preauth_otp.c \ $(srcdir)/preauth_pkinit.c \ $(srcdir)/preauth_sam2.c \ $(srcdir)/princ_comp.c \ $(srcdir)/privsafe.c \ $(srcdir)/random_str.c \ $(srcdir)/rd_cred.c \ $(srcdir)/rd_error.c \ $(srcdir)/rd_priv.c \ $(srcdir)/rd_rep.c \ $(srcdir)/rd_req.c \ $(srcdir)/rd_req_dec.c \ $(srcdir)/rd_safe.c \ $(srcdir)/recvauth.c \ $(srcdir)/response_items.c \ $(srcdir)/s4u_creds.c \ $(srcdir)/sendauth.c \ $(srcdir)/send_tgs.c \ $(srcdir)/ser_actx.c \ $(srcdir)/ser_adata.c \ $(srcdir)/ser_addr.c \ $(srcdir)/ser_auth.c \ $(srcdir)/ser_cksum.c \ $(srcdir)/ser_ctx.c \ $(srcdir)/ser_key.c \ $(srcdir)/ser_princ.c \ $(srcdir)/serialize.c \ $(srcdir)/set_realm.c \ $(srcdir)/sname_match.c \ $(srcdir)/srv_dec_tkt.c \ $(srcdir)/srv_rcache.c \ $(srcdir)/str_conv.c \ $(srcdir)/t_ad_fx_armor.c \ $(srcdir)/tgtname.c \ $(srcdir)/unparse.c \ $(srcdir)/val_renew.c \ $(srcdir)/valid_times.c \ $(srcdir)/vfy_increds.c \ $(srcdir)/vic_opt.c \ $(srcdir)/walk_rtree.c \ $(srcdir)/t_walk_rtree.c \ $(srcdir)/t_kerb.c \ $(srcdir)/t_ser.c \ $(srcdir)/t_deltat.c \ $(srcdir)/t_expand.c \ $(srcdir)/t_get_etype_info.c \ $(srcdir)/t_pac.c \ $(srcdir)/t_parse_host_string.c \ $(srcdir)/t_princ.c \ $(srcdir)/t_etypes.c \ $(srcdir)/t_expire_warn.c \ $(srcdir)/t_authdata.c \ $(srcdir)/t_cc_config.c \ $(srcdir)/t_copy_context.c \ $(srcdir)/t_in_ccache.c \ $(srcdir)/t_response_items.c \ $(srcdir)/t_sname_match.c \ $(srcdir)/t_valid_times.c \ $(srcdir)/t_vfy_increds.c # Someday, when we have a "maintainer mode", do this right: BISON=bison BISONFLAGS= # -v -> .output; -d -> .h DELTAT_DEP=@MAINT@ x-deltat.y ##WIN32##DELTAT_DEP= $(srcdir)/deltat.c : $(DELTAT_DEP) (cd $(srcdir) && $(BISON) $(BISONFLAGS) -o deltat.c x-deltat.y) ##DOS##LIBOBJS = $(OBJS) all-unix: all-libobjs clean-unix:: clean-libobjs COMERRLIB=$(TOPLIBD)/libcom_err.a T_WALK_RTREE_OBJS= t_walk_rtree.o T_KERB_OBJS= t_kerb.o conv_princ.o unparse.o set_realm.o str_conv.o T_SER_OBJS= t_ser.o ser_actx.o ser_adata.o ser_addr.o ser_auth.o ser_cksum.o \ ser_ctx.o ser_key.o ser_princ.o serialize.o authdata.o pac.o \ pac_sign.o ai_authdata.o authdata_exp.o copy_data.o etype_list.o T_DELTAT_OBJS= t_deltat.o deltat.o T_PAC_OBJS= t_pac.o pac.o pac_sign.o copy_data.o T_PRINC_OBJS= t_princ.o T_ETYPES_OBJS= t_etypes.o init_ctx.o etype_list.o plugin.o T_PARSE_HOST_STRING_OBJS= t_parse_host_string.o parse_host_string.o t_walk_rtree: $(T_WALK_RTREE_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_walk_rtree $(T_WALK_RTREE_OBJS) $(KRB5_BASE_LIBS) t_ad_fx_armor: t_ad_fx_armor.o $(CC_LINK) -o $@ t_ad_fx_armor.o $(KRB5_BASE_LIBS) t_authdata: t_authdata.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_authdata.o $(KRB5_BASE_LIBS) t_kerb: $(T_KERB_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_kerb $(T_KERB_OBJS) $(KRB5_BASE_LIBS) t_ser: $(T_SER_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_ser $(T_SER_OBJS) $(KRB5_BASE_LIBS) t_deltat : $(T_DELTAT_OBJS) $(SUPPORT_DEPLIB) $(CC_LINK) -o t_deltat $(T_DELTAT_OBJS) $(SUPPORT_LIB) T_EXPAND_OBJS=t_expand.o t_expand.o : t_expand.c t_expand : $(T_EXPAND_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_expand $(T_EXPAND_OBJS) $(KRB5_BASE_LIBS) t_pac: $(T_PAC_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_pac $(T_PAC_OBJS) $(KRB5_BASE_LIBS) t_princ: $(T_PRINC_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_princ $(T_PRINC_OBJS) $(KRB5_BASE_LIBS) t_etypes: $(T_ETYPES_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o t_etypes $(T_ETYPES_OBJS) $(KRB5_BASE_LIBS) t_parse_host_string: $(T_PARSE_HOST_STRING_OBJS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ $(T_PARSE_HOST_STRING_OBJS) $(CMOCKA_LIBS) \ $(KRB5_BASE_LIBS) t_expire_warn: t_expire_warn.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_expire_warn.o $(KRB5_BASE_LIBS) t_vfy_increds: t_vfy_increds.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_vfy_increds.o $(KRB5_BASE_LIBS) t_in_ccache: t_in_ccache.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_in_ccache.o $(KRB5_BASE_LIBS) t_cc_config: t_cc_config.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_cc_config.o $(KRB5_BASE_LIBS) t_copy_context: t_copy_context.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_copy_context.o $(KRB5_BASE_LIBS) t_response_items: t_response_items.o response_items.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_response_items.o response_items.o $(KRB5_BASE_LIBS) t_sname_match: t_sname_match.o sname_match.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_sname_match.o sname_match.o $(KRB5_BASE_LIBS) t_valid_times: t_valid_times.o valid_times.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_valid_times.o valid_times.o $(KRB5_BASE_LIBS) t_get_etype_info: t_get_etype_info.o $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ t_get_etype_info.o $(KRB5_BASE_LIBS) TEST_PROGS= t_walk_rtree t_kerb t_ser t_deltat t_expand t_authdata t_pac \ t_in_ccache t_cc_config t_copy_context t_princ t_etypes t_vfy_increds \ t_response_items t_sname_match t_valid_times t_get_etype_info check-unix: $(TEST_PROGS) runenv.sh $(RUN_TEST_LOCAL_CONF) ./t_kerb \ parse_name tytso \ parse_name tytso@SHAZAAM \ parse_name tytso/root@VEGGIE.COM \ parse_name tytso/tuber/carrot@VEGGIE.COM \ parse_name tytso/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t \ parse_name tytso/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t@FOO \ parse_name tytso\\\\0/\\0@B\\n\\t\\\\GAG \ parse_name tytso/\\n/\\b\\t@B\\0hacky-test \ parse_name \\/slash/\\@atsign/octa\\/thorpe@\\/slash\\@at\\/sign \ name_type host/www.krb5.test@KRB5.TEST \ name_type krbtg/KRB5.TEST@KRB5.TEST \ name_type krbtgt/KRB5.TEST@KRB5.TEST \ name_type WELLKNOWN/ANONYMOUS@KRB5.TEST \ 425_conv_principal rcmd e40-po ATHENA.MIT.EDU \ 425_conv_principal rcmd mit ATHENA.MIT.EDU \ 425_conv_principal rcmd lithium ATHENA.MIT.EDU \ 425_conv_principal rcmd tweedledumb CYGNUS.COM \ 425_conv_principal rcmd uunet UU.NET \ 425_conv_principal zephyr zephyr ATHENA.MIT.EDU \ 425_conv_principal kadmin ATHENA.MIT.EDU ATHENA.MIT.EDU \ 524_conv_principal host/e40-po.mit.edu@ATHENA.MIT.EDU \ 524_conv_principal host/foobar.stanford.edu@stanford.edu \ set_realm marc@MIT.EDU CYGNUS.COM \ > test.out cmp test.out $(srcdir)/t_ref_kerb.out $(RM) test.out $(RUN_TEST) ./t_ser $(RUN_TEST) ./t_deltat $(RUN_TEST) sh $(srcdir)/transit-tests $(RUN_TEST_LOCAL_CONF) sh $(srcdir)/walktree-tests $(RUN_TEST) ./t_authdata $(RUN_TEST) ./t_pac $(RUN_TEST) ./t_princ $(RUN_TEST) ./t_etypes $(RUN_TEST) ./t_response_items $(RUN_TEST) ./t_copy_context $(RUN_TEST) ./t_sname_match $(RUN_TEST) ./t_valid_times check-pytests: t_expire_warn t_get_etype_info t_vfy_increds $(RUNPYTEST) $(srcdir)/t_expire_warn.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_vfy_increds.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_in_ccache_patypes.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_get_etype_info.py $(PYTESTFLAGS) check-cmocka: t_parse_host_string $(RUN_TEST) ./t_parse_host_string > /dev/null clean: $(RM) $(OUTPRE)t_walk_rtree$(EXEEXT) $(OUTPRE)t_walk_rtree.$(OBJEXT) \ $(OUTPRE)t_kerb$(EXEEXT) $(OUTPRE)t_kerb.$(OBJEXT) \ $(OUTPRE)t_ser$(EXEEXT) $(OUTPRE)t_ser.$(OBJEXT) \ $(OUTPRE)t_deltat$(EXEEXT) $(OUTPRE)t_deltat.$(OBJEXT) \ $(OUTPRE)t_expand$(EXEEXT) $(OUTPRE)t_expand.$(OBJEXT) \ $(OUTPRE)t_expire_warn$(EXEEXT) $(OUTPRE)t_expire_warn.$(OBJEXT) \ $(OUTPRE)t_etypes$(EXEEXT) $(OUTPRE)t_etypes.$(OBJEXT) \ $(OUTPRE)t_pac$(EXEEXT) $(OUTPRE)t_pac.$(OBJEXT) \ $(OUTPRE)t_princ$(EXEEXT) $(OUTPRE)t_princ.$(OBJEXT) \ $(OUTPRE)t_authdata$(EXEEXT) $(OUTPRE)t_authdata.$(OBJEXT) \ $(OUTPRE)t_cc_config$(EXEEXT) $(OUTPRE)t_cc_config.$(OBJEXT) \ $(OUTPRE)t_copy_context$(EXEEXT) $(OUTPRE)t_copy_context.$(OBJEXT) \ $(OUTPRE)t_in_ccache$(EXEEXT) $(OUTPRE)t_in_ccache.$(OBJEXT) \ $(OUTPRE)t_ad_fx_armor$(EXEEXT) $(OUTPRE)t_ad_fx_armor.$(OBJEXT) \ $(OUTPRE)t_vfy_increds$(EXEEXT) $(OUTPRE)t_vfy_increds.$(OBJEXT) \ $(OUTPRE)t_response_items$(EXEEXT) \ $(OUTPRE)t_response_items.$(OBJEXT) \ $(OUTPRE)t_sname_match$(EXEEXT) $(OUTPRE)t_sname_match.$(OBJEXT) \ $(OUTPRE)t_valid_times$(EXEEXT) $(OUTPRE)t_valid_times.$(OBJEXT) \ $(OUTPRE)t_get_etype_info$(EXEEXT) \ $(OUTPRE)t_get_etype_info.$(OBJEXT) \ $(OUTPRE)t_parse_host_string$(EXEEXT) \ $(OUTPRE)t_parse_host_string.$(OBJEXT) @libobj_frag@ krb5-1.22.1/src/lib/krb5/krb/gc_via_tkt.c0000664000175000017500000003631515051422640017605 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/gc_via_tkt.c */ /* * Copyright 1990,1991,2007-2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Given a tkt, and a target cred, get it. * Assumes that the kdc_rep has been decrypted. */ #include "k5-int.h" #include "int-proto.h" #include "os-proto.h" #include "fast.h" static krb5_error_code kdcrep2creds(krb5_context context, krb5_kdc_rep *pkdcrep, krb5_address *const *address, krb5_boolean is_skey, krb5_data *psectkt, krb5_creds **ppcreds) { krb5_error_code retval; krb5_data *pdata; if ((*ppcreds = (krb5_creds *)calloc(1,sizeof(krb5_creds))) == NULL) { return ENOMEM; } if ((retval = krb5_copy_principal(context, pkdcrep->client, &(*ppcreds)->client))) goto cleanup; if ((retval = krb5_copy_principal(context, pkdcrep->enc_part2->server, &(*ppcreds)->server))) goto cleanup; if ((retval = krb5_copy_keyblock_contents(context, pkdcrep->enc_part2->session, &(*ppcreds)->keyblock))) goto cleanup; TRACE_TGS_REPLY(context, (*ppcreds)->client, (*ppcreds)->server, &(*ppcreds)->keyblock); if ((retval = krb5_copy_data(context, psectkt, &pdata))) goto cleanup_keyblock; (*ppcreds)->second_ticket = *pdata; free(pdata); (*ppcreds)->ticket_flags = pkdcrep->enc_part2->flags; (*ppcreds)->times = pkdcrep->enc_part2->times; (*ppcreds)->magic = KV5M_CREDS; (*ppcreds)->authdata = NULL; /* not used */ (*ppcreds)->is_skey = is_skey; if (pkdcrep->enc_part2->caddrs) { if ((retval = krb5_copy_addresses(context, pkdcrep->enc_part2->caddrs, &(*ppcreds)->addresses))) goto cleanup_keyblock; } else { /* no addresses in the list means we got what we had */ if ((retval = krb5_copy_addresses(context, address, &(*ppcreds)->addresses))) goto cleanup_keyblock; } if ((retval = encode_krb5_ticket(pkdcrep->ticket, &pdata))) goto cleanup_keyblock; (*ppcreds)->ticket = *pdata; free(pdata); return 0; cleanup_keyblock: krb5_free_keyblock_contents(context, &(*ppcreds)->keyblock); cleanup: free (*ppcreds); *ppcreds = NULL; return retval; } static krb5_error_code check_reply_server(krb5_context context, krb5_flags kdcoptions, krb5_creds *in_cred, krb5_kdc_rep *dec_rep) { if (!krb5_principal_compare(context, dec_rep->ticket->server, dec_rep->enc_part2->server)) return KRB5_KDCREP_MODIFIED; /* Reply is self-consistent. */ if (krb5_principal_compare(context, dec_rep->ticket->server, in_cred->server)) return 0; /* Server in reply differs from what we requested. */ if (kdcoptions & KDC_OPT_CANONICALIZE) { /* in_cred server differs from ticket returned, but ticket returned is consistent and we requested canonicalization. */ TRACE_CHECK_REPLY_SERVER_DIFFERS(context, in_cred->server, dec_rep->enc_part2->server); return 0; } /* We didn't request canonicalization. */ if (!IS_TGS_PRINC(in_cred->server) || !IS_TGS_PRINC(dec_rep->ticket->server)) { /* Canonicalization not requested, and not a TGS referral. */ return KRB5_KDCREP_MODIFIED; } return 0; } /* Return true if a TGS credential is for the client's local realm. */ static inline int tgt_is_local_realm(krb5_creds *tgt) { return (tgt->server->length == 2 && data_eq_string(tgt->server->data[0], KRB5_TGS_NAME) && data_eq(tgt->server->data[1], tgt->client->realm) && data_eq(tgt->server->realm, tgt->client->realm)); } krb5_error_code krb5_get_cred_via_tkt(krb5_context context, krb5_creds *tkt, krb5_flags kdcoptions, krb5_address *const *address, krb5_creds *in_cred, krb5_creds **out_cred) { return krb5_get_cred_via_tkt_ext (context, tkt, kdcoptions, address, NULL, in_cred, NULL, NULL, NULL, NULL, out_cred, NULL); } krb5_error_code krb5int_process_tgs_reply(krb5_context context, struct krb5int_fast_request_state *fast_state, krb5_data *response_data, krb5_creds *tkt, krb5_flags kdcoptions, krb5_address *const *address, krb5_pa_data **in_padata, krb5_creds *in_cred, krb5_timestamp timestamp, krb5_int32 nonce, krb5_keyblock *subkey, krb5_pa_data ***out_padata, krb5_pa_data ***out_enc_padata, krb5_creds **out_cred) { krb5_error_code retval; krb5_kdc_rep *dec_rep = NULL; krb5_error *err_reply = NULL; krb5_boolean s4u2self, is_skey; s4u2self = krb5int_find_pa_data(context, in_padata, KRB5_PADATA_S4U_X509_USER) || krb5int_find_pa_data(context, in_padata, KRB5_PADATA_FOR_USER); if (krb5_is_krb_error(response_data)) { retval = decode_krb5_error(response_data, &err_reply); if (retval != 0) goto cleanup; retval = krb5int_fast_process_error(context, fast_state, &err_reply, NULL, NULL); if (retval) goto cleanup; retval = (krb5_error_code) err_reply->error + ERROR_TABLE_BASE_krb5; if (err_reply->text.length > 0) { switch (err_reply->error) { case KRB_ERR_GENERIC: k5_setmsg(context, retval, _("KDC returned error string: %.*s"), err_reply->text.length, err_reply->text.data); break; case KDC_ERR_S_PRINCIPAL_UNKNOWN: { char *s_name; if (err_reply->server && krb5_unparse_name(context, err_reply->server, &s_name) == 0) { k5_setmsg(context, retval, _("Server %s not found in Kerberos database"), s_name); krb5_free_unparsed_name(context, s_name); } else /* In case there's a stale S_PRINCIPAL_UNKNOWN report already noted. */ krb5_clear_error_message(context); } break; } } krb5_free_error(context, err_reply); goto cleanup; } else if (!krb5_is_tgs_rep(response_data)) { retval = KRB5KRB_AP_ERR_MSG_TYPE; goto cleanup; } /* Unfortunately, Heimdal at least up through 1.2 encrypts using the session key not the subsession key. So we try both. */ retval = krb5int_decode_tgs_rep(context, fast_state, response_data, subkey, KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY, &dec_rep); if (retval) { TRACE_TGS_REPLY_DECODE_SESSION(context, &tkt->keyblock); if ((krb5int_decode_tgs_rep(context, fast_state, response_data, &tkt->keyblock, KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY, &dec_rep)) == 0) retval = 0; else goto cleanup; } if (dec_rep->msg_type != KRB5_TGS_REP) { retval = KRB5KRB_AP_ERR_MSG_TYPE; goto cleanup; } /* * Don't trust the ok-as-delegate flag from foreign KDCs unless the * cross-realm TGT also had the ok-as-delegate flag set. */ if (!tgt_is_local_realm(tkt) && !(tkt->ticket_flags & TKT_FLG_OK_AS_DELEGATE)) dec_rep->enc_part2->flags &= ~TKT_FLG_OK_AS_DELEGATE; /* make sure the response hasn't been tampered with..... */ retval = 0; if (s4u2self && !IS_TGS_PRINC(dec_rep->ticket->server)) { /* Final hop, check whether KDC supports S4U2Self */ if (krb5_principal_compare(context, dec_rep->client, in_cred->server)) retval = KRB5KDC_ERR_PADATA_TYPE_NOSUPP; } else if ((kdcoptions & KDC_OPT_CNAME_IN_ADDL_TKT) == 0 || IS_TGS_PRINC(dec_rep->ticket->server)) { /* * For constrained delegation this check must be performed by caller, * as we can't decrypt the evidence ticket. However, if it is a * referral the client should match the TGT client like normal. */ if (!krb5_principal_compare(context, dec_rep->client, tkt->client)) retval = KRB5_KDCREP_MODIFIED; } if (retval == 0) retval = check_reply_server(context, kdcoptions, in_cred, dec_rep); if (dec_rep->enc_part2->nonce != nonce) retval = KRB5_KDCREP_MODIFIED; if ((kdcoptions & KDC_OPT_POSTDATED) && (in_cred->times.starttime != 0) && (in_cred->times.starttime != dec_rep->enc_part2->times.starttime)) retval = KRB5_KDCREP_MODIFIED; if ((in_cred->times.endtime != 0) && ts_after(dec_rep->enc_part2->times.endtime, in_cred->times.endtime)) retval = KRB5_KDCREP_MODIFIED; if ((kdcoptions & KDC_OPT_RENEWABLE) && (in_cred->times.renew_till != 0) && ts_after(dec_rep->enc_part2->times.renew_till, in_cred->times.renew_till)) retval = KRB5_KDCREP_MODIFIED; if ((kdcoptions & KDC_OPT_RENEWABLE_OK) && (dec_rep->enc_part2->flags & KDC_OPT_RENEWABLE) && (in_cred->times.endtime != 0) && ts_after(dec_rep->enc_part2->times.renew_till, in_cred->times.endtime)) retval = KRB5_KDCREP_MODIFIED; if (retval != 0) goto cleanup; if (!in_cred->times.starttime && !ts_within(dec_rep->enc_part2->times.starttime, timestamp, context->clockskew)) { retval = KRB5_KDCREP_SKEW; goto cleanup; } if (out_padata != NULL) { *out_padata = dec_rep->padata; dec_rep->padata = NULL; } if (out_enc_padata != NULL) { *out_enc_padata = dec_rep->enc_part2->enc_padata; dec_rep->enc_part2->enc_padata = NULL; } is_skey = (kdcoptions & KDC_OPT_ENC_TKT_IN_SKEY); retval = kdcrep2creds(context, dec_rep, address, is_skey, &in_cred->second_ticket, out_cred); if (retval != 0) goto cleanup; cleanup: if (dec_rep != NULL) { memset(dec_rep->enc_part2->session->contents, 0, dec_rep->enc_part2->session->length); krb5_free_kdc_rep(context, dec_rep); } return retval; } krb5_error_code krb5_get_cred_via_tkt_ext(krb5_context context, krb5_creds *tkt, krb5_flags kdcoptions, krb5_address *const *address, krb5_pa_data **in_padata, krb5_creds *in_cred, k5_pacb_fn pacb_fn, void *pacb_data, krb5_pa_data ***out_padata, krb5_pa_data ***out_enc_padata, krb5_creds **out_cred, krb5_keyblock **out_subkey) { krb5_error_code retval; krb5_data request_data; krb5_data response_data; krb5_timestamp timestamp; krb5_int32 nonce; krb5_keyblock *subkey = NULL; int no_udp = 0; struct krb5int_fast_request_state *fast_state = NULL; request_data.data = NULL; request_data.length = 0; response_data.data = NULL; response_data.length = 0; retval = krb5int_fast_make_state(context, &fast_state); if (retval) goto cleanup; TRACE_GET_CRED_VIA_TKT_EXT(context, in_cred->server, tkt->server, kdcoptions); retval = k5_make_tgs_req(context, fast_state, tkt, kdcoptions, address, in_padata, in_cred, pacb_fn, pacb_data, &request_data, ×tamp, &nonce, &subkey); if (retval != 0) goto cleanup; send_again: retval = k5_sendto_kdc(context, &request_data, &in_cred->server->realm, FALSE, no_udp, &response_data, NULL); if (retval == 0) { if (krb5_is_krb_error(&response_data)) { if (!no_udp) { krb5_error *err_reply; retval = decode_krb5_error(&response_data, &err_reply); if (retval != 0) goto cleanup; retval = krb5int_fast_process_error(context, fast_state, &err_reply, NULL, NULL); if (retval) goto cleanup; if (err_reply->error == KRB_ERR_RESPONSE_TOO_BIG) { no_udp = 1; krb5_free_error(context, err_reply); krb5_free_data_contents(context, &response_data); goto send_again; } krb5_free_error(context, err_reply); } } } else goto cleanup; retval = krb5int_process_tgs_reply(context, fast_state, &response_data, tkt, kdcoptions, address, in_padata, in_cred, timestamp, nonce, subkey, out_padata, out_enc_padata, out_cred); if (retval != 0) goto cleanup; cleanup: krb5int_fast_free_state(context, fast_state); TRACE_GET_CRED_VIA_TKT_EXT_RETURN(context, retval); krb5_free_data_contents(context, &request_data); krb5_free_data_contents(context, &response_data); if (subkey != NULL) { if (retval == 0 && out_subkey != NULL) *out_subkey = subkey; else krb5_free_keyblock(context, subkey); } return retval; } krb5-1.22.1/src/lib/krb5/krb/kerrs.c0000664000175000017500000001565115051422640016621 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/kerrs.c - Error message functions */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "int-proto.h" #ifdef DEBUG static int error_message_debug = 0; #ifndef ERROR_MESSAGE_DEBUG #define ERROR_MESSAGE_DEBUG() (error_message_debug != 0) #endif #endif void KRB5_CALLCONV_C krb5_set_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, ...) { va_list args; if (ctx == NULL) return; va_start(args, fmt); #ifdef DEBUG if (ERROR_MESSAGE_DEBUG()) { fprintf(stderr, "krb5_set_error_message(ctx=%p/err=%p, code=%ld, ...)\n", ctx, &ctx->err, (long)code); } #endif k5_vset_error(&ctx->err, code, fmt, args); #ifdef DEBUG if (ERROR_MESSAGE_DEBUG()) fprintf(stderr, "->%s\n", ctx->err.msg); #endif va_end(args); } void KRB5_CALLCONV krb5_vset_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, va_list args) { #ifdef DEBUG if (ERROR_MESSAGE_DEBUG()) { fprintf(stderr, "krb5_vset_error_message(ctx=%p, code=%ld, ...)\n", ctx, (long)code); } #endif if (ctx == NULL) return; k5_vset_error(&ctx->err, code, fmt, args); #ifdef DEBUG if (ERROR_MESSAGE_DEBUG()) fprintf(stderr, "->%s\n", ctx->err.msg); #endif } void KRB5_CALLCONV krb5_prepend_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); krb5_vwrap_error_message(ctx, code, code, fmt, ap); va_end(ap); } void KRB5_CALLCONV krb5_vprepend_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, va_list ap) { krb5_wrap_error_message(ctx, code, code, fmt, ap); } void KRB5_CALLCONV krb5_wrap_error_message(krb5_context ctx, krb5_error_code old_code, krb5_error_code code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); krb5_vwrap_error_message(ctx, old_code, code, fmt, ap); va_end(ap); } void KRB5_CALLCONV krb5_vwrap_error_message(krb5_context ctx, krb5_error_code old_code, krb5_error_code code, const char *fmt, va_list ap) { const char *prev_msg; char *prepend; if (ctx == NULL || vasprintf(&prepend, fmt, ap) < 0) return; prev_msg = k5_get_error(&ctx->err, old_code); k5_set_error(&ctx->err, code, "%s: %s", prepend, prev_msg); k5_free_error(&ctx->err, prev_msg); free(prepend); } /* Set the error message state of dest_ctx to that of src_ctx. */ void KRB5_CALLCONV krb5_copy_error_message(krb5_context dest_ctx, krb5_context src_ctx) { if (dest_ctx == src_ctx) return; if (src_ctx->err.msg != NULL) { k5_set_error(&dest_ctx->err, src_ctx->err.code, "%s", src_ctx->err.msg); } else { k5_clear_error(&dest_ctx->err); } } /* Re-format msg using the format string err_fmt. Return an allocated result, * or NULL if err_fmt is NULL or on allocation failure. */ static char * err_fmt_fmt(const char *err_fmt, long code, const char *msg) { struct k5buf buf; const char *p, *s; if (err_fmt == NULL) return NULL; k5_buf_init_dynamic(&buf); s = err_fmt; while ((p = strchr(s, '%')) != NULL) { k5_buf_add_len(&buf, s, p - s); s = p; if (p[1] == '\0') break; else if (p[1] == 'M') k5_buf_add(&buf, msg); else if (p[1] == 'C') k5_buf_add_fmt(&buf, "%ld", code); else if (p[1] == '%') k5_buf_add(&buf, "%"); else k5_buf_add_fmt(&buf, "%%%c", p[1]); s += 2; } k5_buf_add(&buf, s); /* Remainder after last token */ return k5_buf_cstring(&buf); } const char * KRB5_CALLCONV krb5_get_error_message(krb5_context ctx, krb5_error_code code) { const char *std, *custom; #ifdef DEBUG if (ERROR_MESSAGE_DEBUG()) fprintf(stderr, "krb5_get_error_message(%p, %ld)\n", ctx, (long)code); #endif if (ctx == NULL) return error_message(code); std = k5_get_error(&ctx->err, code); custom = err_fmt_fmt(ctx->err_fmt, code, std); if (custom != NULL) { free((char *)std); return custom; } return std; } void KRB5_CALLCONV krb5_free_error_message(krb5_context ctx, const char *msg) { #ifdef DEBUG if (ERROR_MESSAGE_DEBUG()) fprintf(stderr, "krb5_free_error_message(%p, %p)\n", ctx, msg); #endif if (ctx == NULL) return; k5_free_error(&ctx->err, msg); } void KRB5_CALLCONV krb5_clear_error_message(krb5_context ctx) { #ifdef DEBUG if (ERROR_MESSAGE_DEBUG()) fprintf(stderr, "krb5_clear_error_message(%p)\n", ctx); #endif if (ctx == NULL) return; k5_clear_error(&ctx->err); } void k5_save_ctx_error(krb5_context ctx, krb5_error_code code, struct errinfo *out) { out->code = code; out->msg = NULL; if (ctx != NULL && ctx->err.code == code) { out->msg = ctx->err.msg; ctx->err.code = 0; ctx->err.msg = NULL; } } krb5_error_code k5_restore_ctx_error(krb5_context ctx, struct errinfo *in) { krb5_error_code code = in->code; if (ctx != NULL) { k5_clear_error(&ctx->err); ctx->err.code = in->code; ctx->err.msg = in->msg; in->msg = NULL; } else { k5_clear_error(in); } return code; } /* If ctx contains an extended error message for oldcode, change it to be an * extended error message for newcode. */ void k5_change_error_message_code(krb5_context ctx, krb5_error_code oldcode, krb5_error_code newcode) { if (ctx != NULL && ctx->err.msg != NULL && ctx->err.code == oldcode) ctx->err.code = newcode; } krb5-1.22.1/src/lib/krb5/krb/srv_rcache.c0000664000175000017500000000341615051422640017606 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/srv_rcache.c - Acquire default replay cache for a server */ /* * Copyright 1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include #include krb5_error_code KRB5_CALLCONV krb5_get_server_rcache(krb5_context context, const krb5_data *piece, krb5_rcache *rcptr) { /* * This function used to compose a name based on the first component of the * server principal, but now ignores the piece argument and resolves the * default replay cache. */ return k5_rc_default(context, rcptr); } krb5-1.22.1/src/lib/krb5/krb/gen_save_subkey.c0000664000175000017500000000424715051422640020643 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/gen_save_subkey.c */ /* * Copyright 2009 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "int-proto.h" #include "auth_con.h" krb5_error_code k5_generate_and_save_subkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock, krb5_enctype enctype) { krb5_error_code retval; krb5_keyblock *kb = NULL; retval = krb5_generate_subkey_extended(context, keyblock, enctype, &kb); if (retval) return retval; retval = krb5_auth_con_setsendsubkey(context, auth_context, kb); if (retval) goto cleanup; retval = krb5_auth_con_setrecvsubkey(context, auth_context, kb); if (retval) goto cleanup; cleanup: if (retval) { (void) krb5_auth_con_setsendsubkey(context, auth_context, NULL); (void) krb5_auth_con_setrecvsubkey(context, auth_context, NULL); } krb5_free_keyblock(context, kb); return retval; } krb5-1.22.1/src/lib/krb5/krb/auth_con.h0000664000175000017500000000267415051422640017301 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #ifndef KRB5_AUTH_CONTEXT #define KRB5_AUTH_CONTEXT #include "../rcache/memrcache.h" struct _krb5_auth_context { krb5_magic magic; krb5_address * remote_addr; krb5_address * remote_port; krb5_address * local_addr; krb5_address * local_port; krb5_key key; krb5_key send_subkey; krb5_key recv_subkey; krb5_int32 auth_context_flags; krb5_ui_4 remote_seq_number; krb5_ui_4 local_seq_number; krb5_authenticator *authentp; /* mk_req, rd_req, mk_rep, ...*/ krb5_cksumtype req_cksumtype; /* mk_safe, ... */ krb5_cksumtype safe_cksumtype; /* mk_safe, ... */ krb5_data cstate; /* mk_priv, rd_priv only */ krb5_rcache rcache; k5_memrcache memrcache; krb5_enctype * permitted_etypes; /* rd_req */ krb5_mk_req_checksum_func checksum_func; void *checksum_func_data; krb5_enctype negotiated_etype; krb5_authdata_context ad_context; }; /* Internal auth_context_flags */ #define KRB5_AUTH_CONN_INITIALIZED 0x00010000 #define KRB5_AUTH_CONN_USED_W_MK_REQ 0x00020000 #define KRB5_AUTH_CONN_USED_W_RD_REQ 0x00040000 #define KRB5_AUTH_CONN_SANE_SEQ 0x00080000 #define KRB5_AUTH_CONN_HEIMDAL_SEQ 0x00100000 #endif krb5-1.22.1/src/lib/krb5/krb/ser_cksum.c0000664000175000017500000001234415051422640017462 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/ser_cksum.c - Serialize krb5_checksum structure */ /* * Copyright 1995, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "int-proto.h" krb5_error_code k5_size_checksum(krb5_checksum *checksum, size_t *sizep) { krb5_error_code kret; /* * krb5_checksum requires: * krb5_int32 for KV5M_CHECKSUM * krb5_int32 for checksum_type * krb5_int32 for length * krb5_int32 for KV5M_CHECKSUM * checksum->length for contents */ kret = EINVAL; if (checksum != NULL) { *sizep += (sizeof(krb5_int32) + sizeof(krb5_int32) + sizeof(krb5_int32) + sizeof(krb5_int32) + (size_t) checksum->length); kret = 0; } return(kret); } krb5_error_code k5_externalize_checksum(krb5_checksum *checksum, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; size_t required; krb5_octet *bp; size_t remain; required = 0; bp = *buffer; remain = *lenremain; kret = EINVAL; if (checksum != NULL) { kret = ENOMEM; if (!k5_size_checksum(checksum, &required) && required <= remain) { /* Our identifier */ (void) krb5_ser_pack_int32(KV5M_CHECKSUM, &bp, &remain); /* Our checksum_type */ (void) krb5_ser_pack_int32((krb5_int32) checksum->checksum_type, &bp, &remain); /* Our length */ (void) krb5_ser_pack_int32((krb5_int32) checksum->length, &bp, &remain); /* Our contents */ (void) krb5_ser_pack_bytes(checksum->contents, (size_t) checksum->length, &bp, &remain); /* Finally, our trailer */ (void) krb5_ser_pack_int32(KV5M_CHECKSUM, &bp, &remain); kret = 0; *buffer = bp; *lenremain = remain; } } return(kret); } krb5_error_code k5_internalize_checksum(krb5_checksum **argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_checksum *checksum; krb5_int32 ibuf; krb5_octet *bp; size_t remain; bp = *buffer; remain = *lenremain; kret = EINVAL; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) ibuf = 0; if (ibuf == KV5M_CHECKSUM) { kret = ENOMEM; /* Get a checksum */ if ((remain >= (2*sizeof(krb5_int32))) && (checksum = (krb5_checksum *) calloc(1, sizeof(krb5_checksum)))) { /* Get the checksum_type */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); checksum->checksum_type = (krb5_cksumtype) ibuf; /* Get the length */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); checksum->length = (int) ibuf; /* Get the string */ if (!ibuf || ((checksum->contents = (krb5_octet *) malloc((size_t) (ibuf))) && !(kret = krb5_ser_unpack_bytes(checksum->contents, (size_t) ibuf, &bp, &remain)))) { /* Get the trailer */ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (!kret && (ibuf == KV5M_CHECKSUM)) { checksum->magic = KV5M_CHECKSUM; *buffer = bp; *lenremain = remain; *argp = checksum; } else kret = EINVAL; } if (kret) { if (checksum->contents) free(checksum->contents); free(checksum); } } } return(kret); } krb5-1.22.1/src/lib/krb5/krb/send_tgs.c0000664000175000017500000002432015051422640017272 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/send_tgs.c - Construct a TGS request */ /* * Copyright 1990,1991,2009,2013 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "int-proto.h" #include "fast.h" /* Choose a random nonce for an AS or TGS request. */ krb5_error_code k5_generate_nonce(krb5_context context, int32_t *out) { krb5_error_code ret; unsigned char random_buf[4]; krb5_data random_data = make_data(random_buf, 4); *out = 0; /* We and Heimdal incorrectly encode nonces as signed, so make sure we use * a non-negative value to avoid interoperability issues. */ ret = krb5_c_random_make_octets(context, &random_data); if (ret) return ret; *out = 0x7FFFFFFF & load_32_n(random_buf); return 0; } /* Construct an AP-REQ message for a TGS request. */ static krb5_error_code tgs_construct_ap_req(krb5_context context, krb5_data *checksum_data, krb5_creds *tgt, krb5_keyblock *subkey, krb5_data **ap_req_asn1_out) { krb5_error_code ret; krb5_checksum checksum; krb5_authenticator authent; krb5_ap_req ap_req; krb5_data *authent_asn1 = NULL; krb5_ticket *ticket = NULL; krb5_enc_data authent_enc; *ap_req_asn1_out = NULL; memset(&checksum, 0, sizeof(checksum)); memset(&ap_req, 0, sizeof(ap_req)); memset(&authent_enc, 0, sizeof(authent_enc)); /* Generate checksum. */ ret = krb5_c_make_checksum(context, 0, &tgt->keyblock, KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM, checksum_data, &checksum); if (ret) goto cleanup; /* Construct, encode, and encrypt an authenticator. */ authent.subkey = subkey; authent.seq_number = 0; authent.checksum = &checksum; authent.client = tgt->client; authent.authorization_data = tgt->authdata; ret = krb5_us_timeofday(context, &authent.ctime, &authent.cusec); if (ret) goto cleanup; ret = encode_krb5_authenticator(&authent, &authent_asn1); if (ret) goto cleanup; ret = krb5_encrypt_helper(context, &tgt->keyblock, KRB5_KEYUSAGE_TGS_REQ_AUTH, authent_asn1, &authent_enc); if (ret) goto cleanup; ret = decode_krb5_ticket(&tgt->ticket, &ticket); if (ret) goto cleanup; /* Encode the AP-REQ. */ ap_req.authenticator = authent_enc; ap_req.ticket = ticket; ret = encode_krb5_ap_req(&ap_req, ap_req_asn1_out); cleanup: free(checksum.contents); krb5_free_ticket(context, ticket); krb5_free_data_contents(context, &authent_enc.ciphertext); if (authent_asn1 != NULL) zapfree(authent_asn1->data, authent_asn1->length); free(authent_asn1); return ret; } /* * Construct a TGS request and return its ASN.1 encoding as well as the * timestamp, nonce, and subkey used. The pacb_fn callback allows the caller * to amend the request padata after the nonce and subkey are determined. */ krb5_error_code k5_make_tgs_req(krb5_context context, struct krb5int_fast_request_state *fast_state, krb5_creds *tgt, krb5_flags kdcoptions, krb5_address *const *addrs, krb5_pa_data **in_padata, krb5_creds *desired, k5_pacb_fn pacb_fn, void *pacb_data, krb5_data *req_asn1_out, krb5_timestamp *timestamp_out, krb5_int32 *nonce_out, krb5_keyblock **subkey_out) { krb5_error_code ret; krb5_kdc_req req; krb5_data *authdata_asn1 = NULL, *req_body_asn1 = NULL; krb5_data *ap_req_asn1 = NULL, *tgs_req_asn1 = NULL; krb5_ticket *sec_ticket = NULL; krb5_ticket *sec_ticket_arr[2]; krb5_timestamp time_now; krb5_pa_data **padata = NULL, *pa; krb5_keyblock *subkey = NULL; krb5_enc_data authdata_enc; krb5_enctype enctypes[2], *defenctypes = NULL; size_t count, i; *req_asn1_out = empty_data(); *timestamp_out = 0; *nonce_out = 0; *subkey_out = NULL; memset(&req, 0, sizeof(req)); memset(&authdata_enc, 0, sizeof(authdata_enc)); /* tgt's client principal must match the desired client principal. */ if (!krb5_principal_compare(context, tgt->client, desired->client)) return KRB5_PRINC_NOMATCH; /* tgt must be an actual credential, not a template. */ if (!tgt->ticket.length) return KRB5_NO_TKT_SUPPLIED; req.kdc_options = kdcoptions; req.server = desired->server; req.from = desired->times.starttime; req.till = desired->times.endtime ? desired->times.endtime : tgt->times.endtime; req.rtime = desired->times.renew_till; ret = k5_generate_nonce(context, &req.nonce); if (ret) return ret; *nonce_out = req.nonce; ret = krb5_timeofday(context, &time_now); if (ret) return ret; *timestamp_out = time_now; req.addresses = (krb5_address **)addrs; /* Generate subkey. */ ret = krb5_generate_subkey(context, &tgt->keyblock, &subkey); if (ret) return ret; TRACE_SEND_TGS_SUBKEY(context, subkey); ret = krb5int_fast_tgs_armor(context, fast_state, subkey, &tgt->keyblock, NULL, NULL); if (ret) goto cleanup; if (desired->authdata != NULL) { ret = encode_krb5_authdata(desired->authdata, &authdata_asn1); if (ret) goto cleanup; ret = krb5_encrypt_helper(context, subkey, KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY, authdata_asn1, &authdata_enc); if (ret) goto cleanup; req.authorization_data = authdata_enc; } if (desired->keyblock.enctype != ENCTYPE_NULL) { if (!krb5_c_valid_enctype(desired->keyblock.enctype)) { ret = KRB5_PROG_ETYPE_NOSUPP; goto cleanup; } enctypes[0] = desired->keyblock.enctype; enctypes[1] = ENCTYPE_NULL; req.ktype = enctypes; req.nktypes = 1; } else { /* Get the default TGS enctypes. */ ret = krb5_get_tgs_ktypes(context, desired->server, &defenctypes); if (ret) goto cleanup; for (count = 0; defenctypes[count]; count++); req.ktype = defenctypes; req.nktypes = count; } TRACE_SEND_TGS_ETYPES(context, req.ktype); if (kdcoptions & (KDC_OPT_ENC_TKT_IN_SKEY | KDC_OPT_CNAME_IN_ADDL_TKT)) { if (desired->second_ticket.length == 0) { ret = KRB5_NO_2ND_TKT; goto cleanup; } ret = decode_krb5_ticket(&desired->second_ticket, &sec_ticket); if (ret) goto cleanup; sec_ticket_arr[0] = sec_ticket; sec_ticket_arr[1] = NULL; req.second_ticket = sec_ticket_arr; } /* Encode the request body. */ ret = krb5int_fast_prep_req_body(context, fast_state, &req, &req_body_asn1); if (ret) goto cleanup; ret = tgs_construct_ap_req(context, req_body_asn1, tgt, subkey, &ap_req_asn1); if (ret) goto cleanup; for (count = 0; in_padata != NULL && in_padata[count] != NULL; count++); /* Construct a padata array for the request, beginning with the ap-req. */ padata = k5calloc(count + 2, sizeof(krb5_pa_data *), &ret); if (padata == NULL) goto cleanup; padata[0] = k5alloc(sizeof(krb5_pa_data), &ret); if (padata[0] == NULL) goto cleanup; padata[0]->pa_type = KRB5_PADATA_AP_REQ; padata[0]->contents = k5memdup(ap_req_asn1->data, ap_req_asn1->length, &ret); if (padata[0] == NULL) goto cleanup; padata[0]->length = ap_req_asn1->length; /* Append copies of any other supplied padata. */ for (i = 0; in_padata != NULL && in_padata[i] != NULL; i++) { pa = k5alloc(sizeof(krb5_pa_data), &ret); if (pa == NULL) goto cleanup; pa->pa_type = in_padata[i]->pa_type; pa->length = in_padata[i]->length; pa->contents = k5memdup(in_padata[i]->contents, in_padata[i]->length, &ret); if (pa->contents == NULL) { free(pa); goto cleanup; } padata[i + 1] = pa; } req.padata = padata; if (pacb_fn != NULL) { ret = (*pacb_fn)(context, subkey, &req, pacb_data); if (ret) goto cleanup; } /* Encode the TGS-REQ. Discard the krb5_data container. */ ret = krb5int_fast_prep_req(context, fast_state, &req, ap_req_asn1, encode_krb5_tgs_req, &tgs_req_asn1); if (ret) goto cleanup; *req_asn1_out = *tgs_req_asn1; free(tgs_req_asn1); tgs_req_asn1 = NULL; *subkey_out = subkey; subkey = NULL; cleanup: krb5_free_data(context, authdata_asn1); krb5_free_data(context, req_body_asn1); krb5_free_data(context, ap_req_asn1); krb5_free_pa_data(context, padata); krb5_free_ticket(context, sec_ticket); krb5_free_data_contents(context, &authdata_enc.ciphertext); krb5_free_keyblock(context, subkey); free(defenctypes); return ret; } krb5-1.22.1/src/lib/krb5/krb/encode_kdc.c0000664000175000017500000001063215051422640017543 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/encode_kdc.c */ /* * Copyright 1990 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" /* Takes KDC rep parts in *rep and *encpart, and formats it into *enc_rep, using message type type and encryption key client_key and encryption type etype. The string *enc_rep will be allocated before formatting; the caller should free when finished. returns system errors dec_rep->enc_part.ciphertext is allocated and filled in. */ /* due to argument promotion rules, we need to use the DECLARG/OLDDECLARG stuff... */ krb5_error_code krb5_encode_kdc_rep(krb5_context context, krb5_msgtype type, const krb5_enc_kdc_rep_part *encpart, int using_subkey, const krb5_keyblock *client_key, krb5_kdc_rep *dec_rep, krb5_data **enc_rep) { krb5_data *scratch; krb5_error_code retval; krb5_enc_kdc_rep_part tmp_encpart; krb5_keyusage usage; if (!krb5_c_valid_enctype(dec_rep->enc_part.enctype)) return KRB5_PROG_ETYPE_NOSUPP; switch (type) { case KRB5_AS_REP: usage = KRB5_KEYUSAGE_AS_REP_ENCPART; break; case KRB5_TGS_REP: if (using_subkey) usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY; else usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY; break; default: return KRB5_BADMSGTYPE; } /* * We don't want to modify encpart, but we need to be able to pass * in the message type to the encoder, so it can set the ASN.1 * type correct. * * Although note that it may be doing nothing with the message * type, to be compatible with old versions of Kerberos that always * encode this as a TGS_REP regardly of what it really should be; * also note that the reason why we are passing it in a structure * instead of as an argument to encode_krb5_enc_kdc_rep_part (the * way we should) is for compatibility with the ISODE version of * this function. Ah, compatibility.... */ tmp_encpart = *encpart; tmp_encpart.msg_type = type; retval = encode_krb5_enc_kdc_rep_part(&tmp_encpart, &scratch); if (retval) { return retval; } memset(&tmp_encpart, 0, sizeof(tmp_encpart)); #define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); \ krb5_free_data(context, scratch); } retval = krb5_encrypt_helper(context, client_key, usage, scratch, &dec_rep->enc_part); #define cleanup_encpart() { \ (void) memset(dec_rep->enc_part.ciphertext.data, 0, \ dec_rep->enc_part.ciphertext.length); \ free(dec_rep->enc_part.ciphertext.data); \ dec_rep->enc_part.ciphertext.length = 0; \ dec_rep->enc_part.ciphertext.data = 0;} cleanup_scratch(); if (retval) return(retval); /* now it's ready to be encoded for the wire! */ switch (type) { case KRB5_AS_REP: retval = encode_krb5_as_rep(dec_rep, enc_rep); break; case KRB5_TGS_REP: retval = encode_krb5_tgs_rep(dec_rep, enc_rep); break; } if (retval) cleanup_encpart(); return retval; } krb5-1.22.1/src/lib/krb5/krb/ser_actx.c0000664000175000017500000003600715051422640017301 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/ser_actx.c - Serialize krb5_auth_context structure */ /* * Copyright 1995, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "int-proto.h" #include "auth_con.h" #define TOKEN_RADDR 950916 #define TOKEN_RPORT 950917 #define TOKEN_LADDR 950918 #define TOKEN_LPORT 950919 #define TOKEN_KEYBLOCK 950920 #define TOKEN_LSKBLOCK 950921 #define TOKEN_RSKBLOCK 950922 krb5_error_code k5_size_auth_context(krb5_auth_context auth_context, size_t *sizep) { krb5_error_code kret; size_t required; /* * krb5_auth_context requires at minimum: * krb5_int32 for KV5M_AUTH_CONTEXT * krb5_int32 for auth_context_flags * krb5_int32 for remote_seq_number * krb5_int32 for local_seq_number * krb5_int32 for req_cksumtype * krb5_int32 for safe_cksumtype * krb5_int32 for size of i_vector * krb5_int32 for KV5M_AUTH_CONTEXT */ kret = EINVAL; if (auth_context != NULL) { kret = 0; required = auth_context->cstate.length; required += sizeof(krb5_int32)*8; /* Calculate size required by remote_addr, if appropriate */ if (!kret && auth_context->remote_addr) { kret = k5_size_address(auth_context->remote_addr, &required); if (!kret) required += sizeof(krb5_int32); } /* Calculate size required by remote_port, if appropriate */ if (!kret && auth_context->remote_port) { kret = k5_size_address(auth_context->remote_port, &required); if (!kret) required += sizeof(krb5_int32); } /* Calculate size required by local_addr, if appropriate */ if (!kret && auth_context->local_addr) { kret = k5_size_address(auth_context->local_addr, &required); if (!kret) required += sizeof(krb5_int32); } /* Calculate size required by local_port, if appropriate */ if (!kret && auth_context->local_port) { kret = k5_size_address(auth_context->local_port, &required); if (!kret) required += sizeof(krb5_int32); } /* Calculate size required by key, if appropriate */ if (!kret && auth_context->key) { kret = k5_size_keyblock(&auth_context->key->keyblock, &required); if (!kret) required += sizeof(krb5_int32); } /* Calculate size required by send_subkey, if appropriate */ if (!kret && auth_context->send_subkey) { kret = k5_size_keyblock(&auth_context->send_subkey->keyblock, &required); if (!kret) required += sizeof(krb5_int32); } /* Calculate size required by recv_subkey, if appropriate */ if (!kret && auth_context->recv_subkey) { kret = k5_size_keyblock(&auth_context->recv_subkey->keyblock, &required); if (!kret) required += sizeof(krb5_int32); } /* Calculate size required by authentp, if appropriate */ if (!kret && auth_context->authentp) kret = k5_size_authenticator(auth_context->authentp, &required); } if (!kret) *sizep += required; return(kret); } krb5_error_code k5_externalize_auth_context(krb5_auth_context auth_context, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; size_t required; krb5_octet *bp; size_t remain; required = 0; bp = *buffer; remain = *lenremain; kret = EINVAL; if (auth_context != NULL) { kret = ENOMEM; if (!k5_size_auth_context(auth_context, &required) && required <= remain) { /* Write fixed portion */ (void) krb5_ser_pack_int32(KV5M_AUTH_CONTEXT, &bp, &remain); (void) krb5_ser_pack_int32(auth_context->auth_context_flags, &bp, &remain); (void) krb5_ser_pack_int32(auth_context->remote_seq_number, &bp, &remain); (void) krb5_ser_pack_int32(auth_context->local_seq_number, &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) auth_context->req_cksumtype, &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) auth_context->safe_cksumtype, &bp, &remain); /* Write the cipher state */ (void) krb5_ser_pack_int32(auth_context->cstate.length, &bp, &remain); (void) krb5_ser_pack_bytes((krb5_octet *)auth_context->cstate.data, auth_context->cstate.length, &bp, &remain); kret = 0; /* Now handle remote_addr, if appropriate */ if (!kret && auth_context->remote_addr) { (void) krb5_ser_pack_int32(TOKEN_RADDR, &bp, &remain); kret = k5_externalize_address(auth_context->remote_addr, &bp, &remain); } /* Now handle remote_port, if appropriate */ if (!kret && auth_context->remote_port) { (void) krb5_ser_pack_int32(TOKEN_RPORT, &bp, &remain); kret = k5_externalize_address(auth_context->remote_port, &bp, &remain); } /* Now handle local_addr, if appropriate */ if (!kret && auth_context->local_addr) { (void) krb5_ser_pack_int32(TOKEN_LADDR, &bp, &remain); kret = k5_externalize_address(auth_context->local_addr, &bp, &remain); } /* Now handle local_port, if appropriate */ if (!kret && auth_context->local_port) { (void) krb5_ser_pack_int32(TOKEN_LPORT, &bp, &remain); kret = k5_externalize_address(auth_context->local_addr, &bp, &remain); } /* Now handle keyblock, if appropriate */ if (!kret && auth_context->key) { (void) krb5_ser_pack_int32(TOKEN_KEYBLOCK, &bp, &remain); kret = k5_externalize_keyblock(&auth_context->key->keyblock, &bp, &remain); } /* Now handle subkey, if appropriate */ if (!kret && auth_context->send_subkey) { (void) krb5_ser_pack_int32(TOKEN_LSKBLOCK, &bp, &remain); kret = k5_externalize_keyblock(&auth_context-> send_subkey->keyblock, &bp, &remain); } /* Now handle subkey, if appropriate */ if (!kret && auth_context->recv_subkey) { (void) krb5_ser_pack_int32(TOKEN_RSKBLOCK, &bp, &remain); kret = k5_externalize_keyblock(&auth_context-> recv_subkey->keyblock, &bp, &remain); } /* Now handle authentp, if appropriate */ if (!kret && auth_context->authentp) kret = k5_externalize_authenticator(auth_context->authentp, &bp, &remain); /* * If we were successful, write trailer then update the pointer and * remaining length; */ if (!kret) { /* Write our trailer */ (void) krb5_ser_pack_int32(KV5M_AUTH_CONTEXT, &bp, &remain); *buffer = bp; *lenremain = remain; } } } return(kret); } /* Internalize a keyblock and convert it to a key. */ static krb5_error_code intern_key(krb5_key *key, krb5_octet **bp, size_t *sp) { krb5_keyblock *keyblock; krb5_error_code ret; ret = k5_internalize_keyblock(&keyblock, bp, sp); if (ret != 0) return ret; ret = krb5_k_create_key(NULL, keyblock, key); krb5_free_keyblock(NULL, keyblock); return ret; } krb5_error_code k5_internalize_auth_context(krb5_auth_context *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_auth_context auth_context; krb5_int32 ibuf; krb5_octet *bp; size_t remain; krb5_int32 cstate_len; krb5_int32 tag; bp = *buffer; remain = *lenremain; kret = EINVAL; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) ibuf = 0; if (ibuf == KV5M_AUTH_CONTEXT) { kret = ENOMEM; /* Get memory for the auth_context */ if ((remain >= (5*sizeof(krb5_int32))) && (auth_context = (krb5_auth_context) calloc(1, sizeof(struct _krb5_auth_context)))) { /* Get auth_context_flags */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->auth_context_flags = ibuf; /* Get remote_seq_number */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->remote_seq_number = ibuf; /* Get local_seq_number */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->local_seq_number = ibuf; /* Get req_cksumtype */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->req_cksumtype = (krb5_cksumtype) ibuf; /* Get safe_cksumtype */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->safe_cksumtype = (krb5_cksumtype) ibuf; /* Get length of cstate */ (void) krb5_ser_unpack_int32(&cstate_len, &bp, &remain); if (cstate_len) { kret = alloc_data(&auth_context->cstate, cstate_len); if (!kret) { kret = krb5_ser_unpack_bytes((krb5_octet *) auth_context->cstate.data, cstate_len, &bp, &remain); } } else kret = 0; /* Peek at next token */ tag = 0; if (!kret) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); /* This is the remote_addr */ if (!kret && (tag == TOKEN_RADDR)) { if (!(kret = k5_internalize_address(&auth_context->remote_addr, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the remote_port */ if (!kret && (tag == TOKEN_RPORT)) { if (!(kret = k5_internalize_address(&auth_context->remote_port, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the local_addr */ if (!kret && (tag == TOKEN_LADDR)) { if (!(kret = k5_internalize_address(&auth_context->local_addr, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the local_port */ if (!kret && (tag == TOKEN_LPORT)) { if (!(kret = k5_internalize_address(&auth_context->local_port, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the keyblock */ if (!kret && (tag == TOKEN_KEYBLOCK)) { if (!(kret = intern_key(&auth_context->key, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the send_subkey */ if (!kret && (tag == TOKEN_LSKBLOCK)) { if (!(kret = intern_key(&auth_context->send_subkey, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the recv_subkey */ if (!kret) { if (tag == TOKEN_RSKBLOCK) { kret = intern_key(&auth_context->recv_subkey, &bp, &remain); } else { /* * We read the next tag, but it's not of any use here, so * we effectively 'unget' it here. */ bp -= sizeof(krb5_int32); remain += sizeof(krb5_int32); } } /* Now find the authentp */ if (!kret) { kret = k5_internalize_authenticator(&auth_context->authentp, &bp, &remain); if (kret == EINVAL) kret = 0; } /* Finally, find the trailer */ if (!kret) { kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (!kret && (ibuf != KV5M_AUTH_CONTEXT)) kret = EINVAL; } if (!kret) { *buffer = bp; *lenremain = remain; auth_context->magic = KV5M_AUTH_CONTEXT; *argp = auth_context; } else krb5_auth_con_free(NULL, auth_context); } } return(kret); } krb5-1.22.1/src/lib/krb5/krb/t_authdata.c0000664000175000017500000000742015051422640017604 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/t_authdata.c - Test authorization data search */ /* * Copyright (C) 2009 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include #include #include #include krb5_authdata ad1 = { KV5M_AUTHDATA, 22, 4, (unsigned char *) "abcd"}; krb5_authdata ad2 = { KV5M_AUTHDATA, 23, 5, (unsigned char *) "abcde" }; krb5_authdata ad3= { KV5M_AUTHDATA, 22, 3, (unsigned char *) "ab" }; /* We want three results in the return from krb5_find_authdata so it has to * grow its list. */ krb5_authdata ad4 = { KV5M_AUTHDATA, 22, 5, (unsigned char *)"abcd" }; krb5_authdata *adseq1[] = {&ad1, &ad2, &ad4, NULL}; krb5_authdata *adseq2[] = {&ad3, NULL}; krb5_keyblock key = { KV5M_KEYBLOCK, ENCTYPE_AES128_CTS_HMAC_SHA1_96, 16, (unsigned char *)"1234567890ABCDEF" }; static void compare_authdata(const krb5_authdata *adc1, krb5_authdata *adc2) { assert(adc1->ad_type == adc2->ad_type); assert(adc1->length == adc2->length); assert(memcmp(adc1->contents, adc2->contents, adc1->length) == 0); } int main(void) { krb5_context context; krb5_authdata **results; krb5_authdata *container[2]; krb5_authdata **container_out; krb5_authdata **kdci; assert(krb5_init_context(&context) == 0); assert(krb5_merge_authdata(context, adseq1, adseq2, &results) == 0); compare_authdata(results[0], &ad1); compare_authdata( results[1], &ad2); compare_authdata(results[2], &ad4); compare_authdata( results[3], &ad3); assert(results[4] == NULL); krb5_free_authdata(context, results); container[0] = &ad3; container[1] = NULL; assert(krb5_encode_authdata_container( context, KRB5_AUTHDATA_IF_RELEVANT, container, &container_out) == 0); assert(krb5_find_authdata(context, adseq1, container_out, 22, &results) == 0); compare_authdata(&ad1, results[0]); compare_authdata( results[1], &ad4); compare_authdata( results[2], &ad3); assert( results[3] == NULL); krb5_free_authdata(context, container_out); assert(krb5_make_authdata_kdc_issued(context, &key, NULL, results, &kdci) == 0); assert(krb5_verify_authdata_kdc_issued(context, &key, kdci[0], NULL, &container_out) == 0); compare_authdata(container_out[0], results[0]); compare_authdata(container_out[1], results[1]); compare_authdata(container_out[2], results[2]); krb5_free_authdata(context, kdci); krb5_free_authdata(context, results); krb5_free_authdata(context, container_out); krb5_free_context(context); return 0; } krb5-1.22.1/src/lib/krb5/krb/appdefault.c0000664000175000017500000000747115051422640017621 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * appdefault - routines designed to be called from applications to * handle the [appdefaults] profile section */ #include "k5-int.h" /*xxx Duplicating this is annoying; try to work on a better way.*/ static const char *const conf_yes[] = { "y", "yes", "true", "t", "1", "on", 0, }; static const char *const conf_no[] = { "n", "no", "false", "nil", "0", "off", 0, }; static int conf_boolean(char *s) { const char * const *p; for(p=conf_yes; *p; p++) { if (!strcasecmp(*p,s)) return 1; } for(p=conf_no; *p; p++) { if (!strcasecmp(*p,s)) return 0; } /* Default to "no" */ return 0; } static krb5_error_code appdefault_get(krb5_context context, const char *appname, const krb5_data *realm, const char *option, char **ret_value) { profile_t profile; const char *names[5]; char **nameval = NULL; krb5_error_code retval; const char * realmstr = realm?realm->data:NULL; *ret_value = NULL; if (!context || (context->magic != KV5M_CONTEXT)) return KV5M_CONTEXT; profile = context->profile; /* * Try number one: * * [appdefaults] * app = { * SOME.REALM = { * option = * } * } */ names[0] = "appdefaults"; names[1] = appname; if (realmstr) { names[2] = realmstr; names[3] = option; names[4] = 0; retval = profile_get_values(profile, names, &nameval); if (retval == 0 && nameval && nameval[0]) { *ret_value = strdup(nameval[0]); goto goodbye; } } /* * Try number two: * * [appdefaults] * app = { * option = * } */ names[2] = option; names[3] = 0; retval = profile_get_values(profile, names, &nameval); if (retval == 0 && nameval && nameval[0]) { *ret_value = strdup(nameval[0]); goto goodbye; } /* * Try number three: * * [appdefaults] * realm = { * option = */ if (realmstr) { names[1] = realmstr; names[2] = option; names[3] = 0; retval = profile_get_values(profile, names, &nameval); if (retval == 0 && nameval && nameval[0]) { *ret_value = strdup(nameval[0]); goto goodbye; } } /* * Try number four: * * [appdefaults] * option = */ names[1] = option; names[2] = 0; retval = profile_get_values(profile, names, &nameval); if (retval == 0 && nameval && nameval[0]) { *ret_value = strdup(nameval[0]); } else { return retval; } goodbye: if (nameval) { char **cpp; for (cpp = nameval; *cpp; cpp++) free(*cpp); free(nameval); } return 0; } void KRB5_CALLCONV krb5_appdefault_boolean(krb5_context context, const char *appname, const krb5_data *realm, const char *option, int default_value, int *ret_value) { char *string = NULL; krb5_error_code retval; retval = appdefault_get(context, appname, realm, option, &string); if (! retval && string) { *ret_value = conf_boolean(string); free(string); } else *ret_value = default_value; } void KRB5_CALLCONV krb5_appdefault_string(krb5_context context, const char *appname, const krb5_data *realm, const char *option, const char *default_value, char **ret_value) { krb5_error_code retval; char *string; retval = appdefault_get(context, appname, realm, option, &string); if (! retval && string) { *ret_value = string; } else { *ret_value = strdup(default_value); } } krb5-1.22.1/src/lib/krb5/krb/mk_req.c0000664000175000017500000000633315051422640016746 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/mk_req.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "auth_con.h" /* Formats a KRB_AP_REQ message into outbuf. server specifies the principal of the server to receive the message; if credentials are not present in the credentials cache for this server, the TGS request with default parameters is used in an attempt to obtain such credentials, and they are stored in ccache. kdc_options specifies the options requested for the ap_req_options specifies the KRB_AP_REQ options desired. checksum specifies the checksum to be used in the authenticator. The outbuf buffer storage is allocated, and should be freed by the caller when finished. returns system errors */ krb5_error_code KRB5_CALLCONV krb5_mk_req(krb5_context context, krb5_auth_context *auth_context, krb5_flags ap_req_options, const char *service, const char *hostname, krb5_data *in_data, krb5_ccache ccache, krb5_data *outbuf) { krb5_error_code retval; krb5_principal server; krb5_creds * credsp; krb5_creds creds; retval = krb5_sname_to_principal(context, hostname, service, KRB5_NT_SRV_HST, &server); if (retval) return retval; /* obtain ticket & session key */ memset(&creds, 0, sizeof(creds)); if ((retval = krb5_copy_principal(context, server, &creds.server))) goto cleanup_princ; if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) goto cleanup_creds; if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) goto cleanup_creds; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, credsp, outbuf); krb5_free_creds(context, credsp); cleanup_creds: krb5_free_cred_contents(context, &creds); cleanup_princ: krb5_free_principal(context, server); return retval; } krb5-1.22.1/src/lib/krb5/krb/rd_req.c0000664000175000017500000000744615051422640016752 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/rd_req.c */ /* * Copyright 1990,1991, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "auth_con.h" /* * Parses a KRB_AP_REQ message, returning its contents. * * server specifies the expected server's name for the ticket. * * keyproc specifies a procedure to generate a decryption key for the * ticket. If keyproc is non-NULL, keyprocarg is passed to it, and the result * used as a decryption key. If keyproc is NULL, then fetchfrom is checked; * if it is non-NULL, it specifies a parameter name from which to retrieve the * decryption key. If fetchfrom is NULL, then the default key store is * consulted. * * returns system errors, encryption errors, replay errors */ krb5_error_code KRB5_CALLCONV krb5_rd_req(krb5_context context, krb5_auth_context *auth_context, const krb5_data *inbuf, krb5_const_principal server, krb5_keytab keytab, krb5_flags *ap_req_options, krb5_ticket **ticket) { krb5_error_code retval; krb5_ap_req * request; krb5_auth_context new_auth_context; krb5_keytab new_keytab = NULL; if (!krb5_is_ap_req(inbuf)) return KRB5KRB_AP_ERR_MSG_TYPE; #ifndef LEAN_CLIENT if ((retval = decode_krb5_ap_req(inbuf, &request))) { switch (retval) { case KRB5_BADMSGTYPE: return KRB5KRB_AP_ERR_BADVERSION; default: return(retval); } } #endif /* LEAN_CLIENT */ /* Get an auth context if necessary. */ new_auth_context = NULL; if (*auth_context == NULL) { if ((retval = krb5_auth_con_init(context, &new_auth_context))) goto cleanup_request; *auth_context = new_auth_context; } #ifndef LEAN_CLIENT /* Get a keytab if necessary. */ if (keytab == NULL) { if ((retval = krb5_kt_default(context, &new_keytab))) goto cleanup_auth_context; keytab = new_keytab; } #endif /* LEAN_CLIENT */ retval = krb5_rd_req_decoded(context, auth_context, request, server, keytab, ap_req_options, NULL); if (!retval && ticket != NULL) { /* Steal the ticket pointer for the caller. */ *ticket = request->ticket; request->ticket = NULL; } #ifndef LEAN_CLIENT if (new_keytab != NULL) (void) krb5_kt_close(context, new_keytab); #endif /* LEAN_CLIENT */ cleanup_auth_context: if (new_auth_context && retval) { krb5_auth_con_free(context, new_auth_context); *auth_context = NULL; } cleanup_request: krb5_free_ap_req(context, request); return retval; } krb5-1.22.1/src/lib/krb5/krb/copy_creds.c0000664000175000017500000000762715051422640017631 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/copy_creds.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" #include "int-proto.h" /* * Copy credentials, allocating fresh storage where needed. */ krb5_error_code KRB5_CALLCONV krb5_copy_creds(krb5_context context, const krb5_creds *incred, krb5_creds **outcred) { krb5_creds *tempcred; krb5_error_code retval; if (!(tempcred = (krb5_creds *)malloc(sizeof(*tempcred)))) return ENOMEM; retval = k5_copy_creds_contents(context, incred, tempcred); if (retval) free(tempcred); else *outcred = tempcred; return retval; } /* * Copy contents of input credentials structure to supplied * destination, allocating storage for indirect fields as needed. On * success, the output is a deep copy of the input. On error, the * output structure is garbage and its contents should be ignored. */ krb5_error_code k5_copy_creds_contents(krb5_context context, const krb5_creds *incred, krb5_creds *tempcred) { krb5_error_code retval; krb5_data *scratch; *tempcred = *incred; retval = krb5_copy_principal(context, incred->client, &tempcred->client); if (retval) goto cleanlast; retval = krb5_copy_principal(context, incred->server, &tempcred->server); if (retval) goto cleanclient; retval = krb5_copy_keyblock_contents(context, &incred->keyblock, &tempcred->keyblock); if (retval) goto cleanserver; retval = krb5_copy_addresses(context, incred->addresses, &tempcred->addresses); if (retval) goto cleanblock; retval = krb5_copy_data(context, &incred->ticket, &scratch); if (retval) goto cleanaddrs; tempcred->ticket = *scratch; free(scratch); retval = krb5_copy_data(context, &incred->second_ticket, &scratch); if (retval) goto clearticket; tempcred->second_ticket = *scratch; free(scratch); retval = krb5_copy_authdata(context, incred->authdata,&tempcred->authdata); if (retval) goto clearsecondticket; return 0; clearsecondticket: memset(tempcred->second_ticket.data,0,tempcred->second_ticket.length); free(tempcred->second_ticket.data); clearticket: memset(tempcred->ticket.data,0,tempcred->ticket.length); free(tempcred->ticket.data); cleanaddrs: krb5_free_addresses(context, tempcred->addresses); cleanblock: free(tempcred->keyblock.contents); cleanserver: krb5_free_principal(context, tempcred->server); cleanclient: krb5_free_principal(context, tempcred->client); cleanlast: /* Do not free tempcred - we did not allocate it - its contents are garbage - but we should not free it */ return retval; } krb5-1.22.1/src/lib/krb5/krb/rd_req_dec.c0000664000175000017500000010747615051422640017571 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/rd_req_dec.c */ /* * Copyright (c) 1994 CyberSAFE Corporation. * Copyright 1990,1991,2007,2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * Neither M.I.T., the Open Computing Security Group, nor * CyberSAFE Corporation make any representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * * krb5_rd_req_decoded() */ #include "k5-int.h" #include "auth_con.h" #include "authdata.h" #include "int-proto.h" #include "os-proto.h" /* * essentially the same as krb_rd_req, but uses a decoded AP_REQ as * the input rather than an encoded input. */ /* * Parses a KRB_AP_REQ message, returning its contents. * * server specifies the expected server's name for the ticket; if NULL, then * any server will be accepted if the key can be found, and the caller should * verify that the principal is something it trusts. With the exception of the * kdb keytab, the ticket's server field need not match the name passed in for * server. All that is required is that the ticket be encrypted with a key * from the keytab associated with the specified server principal. This * permits the KDC to have a set of aliases for the server without keeping * this information consistent with the server. So, when server is non-null, * the principal expected by the application needs to be consistent with the * local keytab, but not with the informational name in the ticket. * * rcache specifies a replay detection cache used to store authenticators and * server names * * keyproc specifies a procedure to generate a decryption key for the * ticket. If keyproc is non-NULL, keyprocarg is passed to it, and the result * used as a decryption key. If keyproc is NULL, then fetchfrom is checked; * if it is non-NULL, it specifies a parameter name from which to retrieve the * decryption key. If fetchfrom is NULL, then the default key store is * consulted. * * authdat is set to point at allocated storage structures; the caller * should free them when finished. * * returns system errors, encryption errors, replay errors */ static krb5_error_code decrypt_authenticator(krb5_context, const krb5_ap_req *, krb5_authenticator **, int); static krb5_error_code decode_etype_list(krb5_context context, const krb5_authenticator *authp, krb5_enctype **desired_etypes, int *desired_etypes_len); static krb5_error_code negotiate_etype(krb5_context context, const krb5_enctype *desired_etypes, int desired_etypes_len, int mandatory_etypes_index, const krb5_enctype *permitted_etypes, int permitted_etypes_len, krb5_enctype *negotiated_etype); /* Unparse the specified server principal (which may be NULL) and the ticket * server principal. */ static krb5_error_code unparse_princs(krb5_context context, krb5_const_principal server, krb5_const_principal tkt_server, char **sname_out, char **tsname_out) { krb5_error_code ret; char *sname = NULL, *tsname; *sname_out = *tsname_out = NULL; if (server != NULL) { ret = krb5_unparse_name(context, server, &sname); if (ret) return ret; } ret = krb5_unparse_name(context, tkt_server, &tsname); if (ret) { krb5_free_unparsed_name(context, sname); return ret; } *sname_out = sname; *tsname_out = tsname; return 0; } /* Return a helpful code and error when we cannot look up the keytab entry for * an explicit server principal using the ticket's kvno and enctype. */ static krb5_error_code keytab_fetch_error(krb5_context context, krb5_error_code code, krb5_const_principal princ, krb5_const_principal tkt_server, krb5_kvno tkt_kvno, krb5_boolean explicit_server) { krb5_error_code ret; char *sname = NULL, *tsname = NULL; if (code == ENOENT || code == EPERM || code == EACCES) { k5_change_error_message_code(context, code, KRB5KRB_AP_ERR_NOKEY); return KRB5KRB_AP_ERR_NOKEY; } if (code == KRB5_KT_NOTFOUND) { ret = explicit_server ? KRB5KRB_AP_ERR_NOKEY : KRB5KRB_AP_ERR_NOT_US; k5_change_error_message_code(context, code, ret); return ret; } if (code != KRB5_KT_KVNONOTFOUND) return code; assert(princ != NULL); ret = unparse_princs(context, princ, tkt_server, &sname, &tsname); if (ret) return ret; if (krb5_principal_compare(context, princ, tkt_server)) { ret = KRB5KRB_AP_ERR_BADKEYVER; k5_setmsg(context, ret, _("Cannot find key for %s kvno %d in keytab"), sname, (int)tkt_kvno); } else { ret = KRB5KRB_AP_ERR_NOT_US; k5_setmsg(context, ret, _("Cannot find key for %s kvno %d in keytab (request ticket " "server %s)"), sname, (int)tkt_kvno, tsname); } krb5_free_unparsed_name(context, sname); krb5_free_unparsed_name(context, tsname); return ret; } /* Return a helpful code and error when ticket decryption fails using the key * for an explicit server principal. */ static krb5_error_code integrity_error(krb5_context context, krb5_const_principal server, krb5_const_principal tkt_server) { krb5_error_code ret; char *sname = NULL, *tsname = NULL; assert(server != NULL); ret = unparse_princs(context, server, tkt_server, &sname, &tsname); if (ret) return ret; ret = krb5_principal_compare(context, server, tkt_server) ? KRB5KRB_AP_ERR_BAD_INTEGRITY : KRB5KRB_AP_ERR_NOT_US; k5_setmsg(context, ret, _("Cannot decrypt ticket for %s using keytab key for %s"), tsname, sname); krb5_free_unparsed_name(context, sname); krb5_free_unparsed_name(context, tsname); return ret; } /* Return a helpful code and error when we cannot iterate over the keytab and * the specified server does not match the ticket server. */ static krb5_error_code nomatch_error(krb5_context context, krb5_const_principal server, krb5_const_principal tkt_server) { krb5_error_code ret; char *sname = NULL, *tsname = NULL; assert(server != NULL); ret = unparse_princs(context, server, tkt_server, &sname, &tsname); if (ret) return ret; k5_setmsg(context, KRB5KRB_AP_ERR_NOT_US, _("Server principal %s does not match request ticket server %s"), sname, tsname); krb5_free_unparsed_name(context, sname); krb5_free_unparsed_name(context, tsname); return KRB5KRB_AP_ERR_NOT_US; } /* Return a helpful error code and message when we fail to find a key after * iterating over the keytab. */ static krb5_error_code iteration_error(krb5_context context, krb5_const_principal server, krb5_const_principal tkt_server, krb5_kvno tkt_kvno, krb5_enctype tkt_etype, krb5_boolean tkt_server_mismatch, krb5_boolean found_server_match, krb5_boolean found_tkt_server, krb5_boolean found_kvno, krb5_boolean found_higher_kvno, krb5_boolean found_enctype) { krb5_error_code ret; char *sname = NULL, *tsname = NULL, encname[128]; ret = unparse_princs(context, server, tkt_server, &sname, &tsname); if (ret) return ret; if (krb5_enctype_to_name(tkt_etype, TRUE, encname, sizeof(encname)) != 0) (void)snprintf(encname, sizeof(encname), "%d", (int)tkt_etype); if (!found_server_match) { ret = KRB5KRB_AP_ERR_NOKEY; if (sname == NULL) { k5_setmsg(context, ret, _("No keys in keytab")); } else { k5_setmsg(context, ret, _("Server principal %s does not match any keys in " "keytab"), sname); } } else if (tkt_server_mismatch) { assert(sname != NULL); /* Null server princ would match anything. */ ret = KRB5KRB_AP_ERR_NOT_US; k5_setmsg(context, ret, _("Request ticket server %s found in keytab but does not " "match server principal %s"), tsname, sname); } else if (!found_tkt_server) { ret = KRB5KRB_AP_ERR_NOT_US; k5_setmsg(context, ret, _("Request ticket server %s not found in keytab (ticket " "kvno %d)"), tsname, (int)tkt_kvno); } else if (!found_kvno) { ret = KRB5KRB_AP_ERR_BADKEYVER; if (found_higher_kvno) { k5_setmsg(context, ret, _("Request ticket server %s kvno %d not found in " "keytab; ticket is likely out of date"), tsname, (int)tkt_kvno); } else { k5_setmsg(context, ret, _("Request ticket server %s kvno %d not found in " "keytab; keytab is likely out of date"), tsname, (int)tkt_kvno); } } else if (!found_enctype) { /* There's no defined error for having the key version but not the * enctype. */ ret = KRB5KRB_AP_ERR_BADKEYVER; k5_setmsg(context, ret, _("Request ticket server %s kvno %d found in keytab but not " "with enctype %s"), tsname, (int)tkt_kvno, encname); } else { ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; k5_setmsg(context, ret, _("Request ticket server %s kvno %d enctype %s found in " "keytab but cannot decrypt ticket"), tsname, (int)tkt_kvno, encname); } krb5_free_unparsed_name(context, sname); krb5_free_unparsed_name(context, tsname); return ret; } /* Return true if princ might match multiple principals. */ static inline krb5_boolean is_matching(krb5_context context, krb5_const_principal princ) { if (princ == NULL) return TRUE; return (princ->type == KRB5_NT_SRV_HST && princ->length == 2 && (princ->realm.length == 0 || princ->data[1].length == 0 || context->ignore_acceptor_hostname)); } /* Decrypt the ticket in req using the key in ent. */ static krb5_error_code try_one_entry(krb5_context context, const krb5_ap_req *req, krb5_keytab_entry *ent, krb5_keyblock *keyblock_out) { krb5_error_code ret; krb5_principal tmp = NULL; /* Try decrypting the ticket with this entry's key. */ ret = krb5_decrypt_tkt_part(context, &ent->key, req->ticket); if (ret) return ret; /* Make a copy of the principal for the ticket server field. */ ret = krb5_copy_principal(context, ent->principal, &tmp); if (ret) return ret; /* Make a copy of the decrypting key if requested by the caller. */ if (keyblock_out != NULL) { ret = krb5_copy_keyblock_contents(context, &ent->key, keyblock_out); if (ret) { krb5_free_principal(context, tmp); return ret; } } /* Make req->ticket->server indicate the actual server principal. */ krb5_free_principal(context, req->ticket->server); req->ticket->server = tmp; return 0; } /* Decrypt the ticket in req using a principal looked up from keytab. * explicit_server should be true if this is the only usable principal. */ static krb5_error_code try_one_princ(krb5_context context, const krb5_ap_req *req, krb5_const_principal princ, krb5_keytab keytab, krb5_boolean explicit_server, krb5_keyblock *keyblock_out) { krb5_error_code ret; krb5_keytab_entry ent; krb5_kvno tkt_kvno = req->ticket->enc_part.kvno; krb5_enctype tkt_etype = req->ticket->enc_part.enctype; krb5_principal tkt_server = req->ticket->server; ret = krb5_kt_get_entry(context, keytab, princ, tkt_kvno, tkt_etype, &ent); if (ret) { return keytab_fetch_error(context, ret, princ, tkt_server, tkt_kvno, explicit_server); } ret = try_one_entry(context, req, &ent, keyblock_out); if (ret == 0) TRACE_RD_REQ_DECRYPT_SPECIFIC(context, ent.principal, &ent.key); (void)krb5_free_keytab_entry_contents(context, &ent); if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) return integrity_error(context, princ, req->ticket->server); return ret; } /* * Decrypt the ticket in req using an entry in keytab matching server (if * given). Set req->ticket->server to the principal of the keytab entry used. * Store the decrypting key in *keyblock_out if it is not NULL. */ static krb5_error_code decrypt_try_server(krb5_context context, const krb5_ap_req *req, krb5_const_principal server, krb5_keytab keytab, krb5_keyblock *keyblock_out) { krb5_error_code ret; krb5_keytab_entry ent; krb5_kt_cursor cursor; krb5_principal tkt_server = req->ticket->server; krb5_kvno tkt_kvno = req->ticket->enc_part.kvno; krb5_enctype tkt_etype = req->ticket->enc_part.enctype; krb5_boolean similar_enctype; krb5_boolean tkt_server_mismatch = FALSE, found_server_match = FALSE; krb5_boolean found_tkt_server = FALSE, found_enctype = FALSE; krb5_boolean found_kvno = FALSE, found_higher_kvno = FALSE; #ifdef LEAN_CLIENT return KRB5KRB_AP_WRONG_PRINC; #else /* If we have an explicit server principal, try just that one. */ if (!is_matching(context, server)) { return try_one_princ(context, req, server, keytab, TRUE, keyblock_out); } if (keytab->ops->start_seq_get == NULL) { /* We can't iterate over the keytab. Try the principal asserted by the * client if it's allowed by the server parameter. */ if (!krb5_sname_match(context, server, tkt_server)) return nomatch_error(context, server, tkt_server); return try_one_princ(context, req, tkt_server, keytab, FALSE, keyblock_out); } /* Scan all keys in the keytab, in case the ticket server is an alias for * one of the principals in the keytab. */ ret = krb5_kt_start_seq_get(context, keytab, &cursor); if (ret) { k5_change_error_message_code(context, ret, KRB5KRB_AP_ERR_NOKEY); return KRB5KRB_AP_ERR_NOKEY; } while ((ret = krb5_kt_next_entry(context, keytab, &ent, &cursor)) == 0) { /* Only try keys which match the server principal. */ if (!krb5_sname_match(context, server, ent.principal)) { if (krb5_principal_compare(context, ent.principal, tkt_server)) tkt_server_mismatch = TRUE; (void)krb5_free_keytab_entry_contents(context, &ent); continue; } found_server_match = TRUE; if (krb5_c_enctype_compare(context, ent.key.enctype, tkt_etype, &similar_enctype) != 0) similar_enctype = FALSE; if (krb5_principal_compare(context, ent.principal, tkt_server)) { found_tkt_server = TRUE; if (ent.vno == tkt_kvno) { found_kvno = TRUE; if (similar_enctype) found_enctype = TRUE; } else if (ent.vno > tkt_kvno) { found_higher_kvno = TRUE; } } /* Only try keys with similar enctypes to the ticket enctype. */ if (similar_enctype) { /* Coerce inexact matches to the request enctype. */ ent.key.enctype = tkt_etype; if (try_one_entry(context, req, &ent, keyblock_out) == 0) { TRACE_RD_REQ_DECRYPT_ANY(context, ent.principal, &ent.key); (void)krb5_free_keytab_entry_contents(context, &ent); break; } } (void)krb5_free_keytab_entry_contents(context, &ent); } (void)krb5_kt_end_seq_get(context, keytab, &cursor); if (ret != KRB5_KT_END) return ret; return iteration_error(context, server, tkt_server, tkt_kvno, tkt_etype, tkt_server_mismatch, found_server_match, found_tkt_server, found_kvno, found_higher_kvno, found_enctype); #endif /* LEAN_CLIENT */ } static krb5_error_code decrypt_ticket(krb5_context context, const krb5_ap_req *req, krb5_const_principal server, krb5_keytab keytab, krb5_keyblock *keyblock_out) { krb5_error_code ret, dret = 0; struct canonprinc iter = { server, .no_hostrealm = TRUE }; krb5_const_principal canonprinc; /* Don't try to canonicalize if we're going to ignore hostnames. */ if (k5_sname_wildcard_host(context, server)) return decrypt_try_server(context, req, server, keytab, keyblock_out); /* Try each canonicalization candidate for server. If they all fail, * return the error from the last attempt. */ while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 && canonprinc != NULL) { dret = decrypt_try_server(context, req, canonprinc, keytab, keyblock_out); /* Only continue if we found no keytab entries matching canonprinc. */ if (dret != KRB5KRB_AP_ERR_NOKEY) break; } free_canonprinc(&iter); return (ret != 0) ? ret : dret; } static krb5_error_code rd_req_decoded_opt(krb5_context context, krb5_auth_context *auth_context, const krb5_ap_req *req, krb5_const_principal server, krb5_keytab keytab, krb5_flags *ap_req_options, krb5_ticket **ticket, int check_valid_flag) { krb5_error_code retval = 0; krb5_enctype *desired_etypes = NULL; int desired_etypes_len = 0; int rfc4537_etypes_len = 0; krb5_enctype *permitted_etypes = NULL; int permitted_etypes_len = 0; krb5_keyblock decrypt_key; decrypt_key.enctype = ENCTYPE_NULL; decrypt_key.contents = NULL; req->ticket->enc_part2 = NULL; /* if (req->ap_options & AP_OPTS_USE_SESSION_KEY) do we need special processing here ? */ /* decrypt the ticket */ if ((*auth_context)->key) { /* User to User authentication */ if ((retval = krb5_decrypt_tkt_part(context, &(*auth_context)->key->keyblock, req->ticket))) goto cleanup; if (check_valid_flag) { decrypt_key = (*auth_context)->key->keyblock; (*auth_context)->key->keyblock.contents = NULL; } krb5_k_free_key(context, (*auth_context)->key); (*auth_context)->key = NULL; if (server == NULL) server = req->ticket->server; } else { retval = decrypt_ticket(context, req, server, keytab, check_valid_flag ? &decrypt_key : NULL); if (retval) { TRACE_RD_REQ_DECRYPT_FAIL(context, retval); goto cleanup; } /* decrypt_ticket placed the principal of the keytab key in * req->ticket->server; always use this for later steps. */ server = req->ticket->server; } TRACE_RD_REQ_TICKET(context, req->ticket->enc_part2->client, req->ticket->server, req->ticket->enc_part2->session); /* XXX this is an evil hack. check_valid_flag is set iff the call is not from inside the kdc. we can use this to determine which key usage to use */ #ifndef LEAN_CLIENT if ((retval = decrypt_authenticator(context, req, &((*auth_context)->authentp), check_valid_flag))) goto cleanup; #endif if (!krb5_principal_compare(context, (*auth_context)->authentp->client, req->ticket->enc_part2->client)) { retval = KRB5KRB_AP_ERR_BADMATCH; goto cleanup; } if ((*auth_context)->remote_addr && !krb5_address_search(context, (*auth_context)->remote_addr, req->ticket->enc_part2->caddrs)) { retval = KRB5KRB_AP_ERR_BADADDR; goto cleanup; } /* Get an rcache if necessary. */ if (((*auth_context)->rcache == NULL) && ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME)) { retval = k5_rc_default(context, &(*auth_context)->rcache); if (retval) goto cleanup; } /* okay, now check cross-realm policy */ #if defined(_SINGLE_HOP_ONLY) /* Single hop cross-realm tickets only */ { krb5_transited *trans = &(req->ticket->enc_part2->transited); /* If the transited list is empty, then we have at most one hop */ if (trans->tr_contents.length > 0 && trans->tr_contents.data[0]) retval = KRB5KRB_AP_ERR_ILL_CR_TKT; } #elif defined(_NO_CROSS_REALM) /* No cross-realm tickets */ { char * lrealm; krb5_data * realm; krb5_transited * trans; realm = &req->ticket->enc_part2->client->realm; trans = &(req->ticket->enc_part2->transited); /* * If the transited list is empty, then we have at most one hop * So we also have to check that the client's realm is the local one */ krb5_get_default_realm(context, &lrealm); if ((trans->tr_contents.length > 0 && trans->tr_contents.data[0]) || !data_eq_string(*realm, lrealm)) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; } free(lrealm); } #else /* Hierarchical Cross-Realm */ { krb5_data * realm; krb5_transited * trans; krb5_flags flags; realm = &req->ticket->enc_part2->client->realm; trans = &(req->ticket->enc_part2->transited); flags = req->ticket->enc_part2->flags; /* * If the transited list is not empty and the KDC hasn't checked it, * then check that all realms transited are within the hierarchy * between the client's realm and the local realm. */ if (!(flags & TKT_FLG_TRANSIT_POLICY_CHECKED) && trans->tr_contents.length > 0 && trans->tr_contents.data[0]) { retval = krb5_check_transited_list(context, &(trans->tr_contents), realm, &server->realm); } } #endif if (retval) goto cleanup; /* only check rcache if sender has provided one---some services may not be able to use replay caches (such as datagram servers) */ if ((*auth_context)->rcache != NULL) { retval = k5_rc_store(context, (*auth_context)->rcache, &req->authenticator); if (retval) goto cleanup; } retval = krb5int_validate_times(context, &req->ticket->enc_part2->times); if (retval != 0) goto cleanup; if ((retval = krb5_check_clockskew(context, (*auth_context)->authentp->ctime))) goto cleanup; if (check_valid_flag) { if (req->ticket->enc_part2->flags & TKT_FLG_INVALID) { retval = KRB5KRB_AP_ERR_TKT_INVALID; goto cleanup; } if ((retval = krb5_authdata_context_init(context, &(*auth_context)->ad_context))) goto cleanup; if ((retval = krb5int_authdata_verify(context, (*auth_context)->ad_context, AD_USAGE_MASK, auth_context, &decrypt_key, req))) goto cleanup; } /* read RFC 4537 etype list from sender */ retval = decode_etype_list(context, (*auth_context)->authentp, &desired_etypes, &rfc4537_etypes_len); if (retval != 0) goto cleanup; if (desired_etypes == NULL) desired_etypes = (krb5_enctype *)calloc(4, sizeof(krb5_enctype)); else desired_etypes = (krb5_enctype *)realloc(desired_etypes, (rfc4537_etypes_len + 4) * sizeof(krb5_enctype)); if (desired_etypes == NULL) { retval = ENOMEM; goto cleanup; } desired_etypes_len = rfc4537_etypes_len; /* * RFC 4537: * * If the EtypeList is present and the server prefers an enctype from * the client's enctype list over that of the AP-REQ authenticator * subkey (if that is present) or the service ticket session key, the * server MUST create a subkey using that enctype. This negotiated * subkey is sent in the subkey field of AP-REP message, and it is then * used as the protocol key or base key [RFC3961] for subsequent * communication. * * If the enctype of the ticket session key is included in the enctype * list sent by the client, it SHOULD be the last on the list; * otherwise, this enctype MUST NOT be negotiated if it was not included * in the list. * * The second paragraph does appear to contradict the first with respect * to whether it is legal to negotiate the ticket session key type if it * is absent in the EtypeList. A literal reading suggests that we can use * the AP-REQ subkey enctype. Also a client has no way of distinguishing * a server that does not RFC 4537 from one that has chosen the same * enctype as the ticket session key for the acceptor subkey, surely. */ if ((*auth_context)->authentp->subkey != NULL) { desired_etypes[desired_etypes_len++] = (*auth_context)->authentp->subkey->enctype; } desired_etypes[desired_etypes_len++] = req->ticket->enc_part2->session->enctype; desired_etypes[desired_etypes_len] = ENCTYPE_NULL; if (((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_PERMIT_ALL) == 0) { if ((*auth_context)->permitted_etypes != NULL) { permitted_etypes = (*auth_context)->permitted_etypes; } else { retval = krb5_get_permitted_enctypes(context, &permitted_etypes); if (retval != 0) goto cleanup; } permitted_etypes_len = k5_count_etypes(permitted_etypes); } else { permitted_etypes = NULL; permitted_etypes_len = 0; } /* check if the various etypes are permitted */ retval = negotiate_etype(context, desired_etypes, desired_etypes_len, rfc4537_etypes_len, permitted_etypes, permitted_etypes_len, &(*auth_context)->negotiated_etype); if (retval != 0) goto cleanup; TRACE_RD_REQ_NEGOTIATED_ETYPE(context, (*auth_context)->negotiated_etype); assert((*auth_context)->negotiated_etype != ENCTYPE_NULL); (*auth_context)->remote_seq_number = (*auth_context)->authentp->seq_number; if ((*auth_context)->authentp->subkey) { TRACE_RD_REQ_SUBKEY(context, (*auth_context)->authentp->subkey); if ((retval = krb5_k_create_key(context, (*auth_context)->authentp->subkey, &((*auth_context)->recv_subkey)))) goto cleanup; retval = krb5_k_create_key(context, (*auth_context)->authentp->subkey, &((*auth_context)->send_subkey)); if (retval) { krb5_k_free_key(context, (*auth_context)->recv_subkey); (*auth_context)->recv_subkey = NULL; goto cleanup; } } else { (*auth_context)->recv_subkey = 0; (*auth_context)->send_subkey = 0; } if ((retval = krb5_k_create_key(context, req->ticket->enc_part2->session, &((*auth_context)->key)))) goto cleanup; /* * If not AP_OPTS_MUTUAL_REQUIRED then and sequence numbers are used * then the default sequence number is the one's complement of the * sequence number sent ot us. */ if ((!(req->ap_options & AP_OPTS_MUTUAL_REQUIRED)) && (*auth_context)->remote_seq_number) { (*auth_context)->local_seq_number ^= (*auth_context)->remote_seq_number; } if (ticket) if ((retval = krb5_copy_ticket(context, req->ticket, ticket))) goto cleanup; if (ap_req_options) { *ap_req_options = req->ap_options & AP_OPTS_WIRE_MASK; if (rfc4537_etypes_len != 0) *ap_req_options |= AP_OPTS_ETYPE_NEGOTIATION; if ((*auth_context)->negotiated_etype != krb5_k_key_enctype(context, (*auth_context)->key)) *ap_req_options |= AP_OPTS_USE_SUBKEY; } retval = 0; cleanup: if (desired_etypes != NULL) free(desired_etypes); if (permitted_etypes != NULL && permitted_etypes != (*auth_context)->permitted_etypes) free(permitted_etypes); if (check_valid_flag) krb5_free_keyblock_contents(context, &decrypt_key); return retval; } krb5_error_code krb5_rd_req_decoded(krb5_context context, krb5_auth_context *auth_context, const krb5_ap_req *req, krb5_const_principal server, krb5_keytab keytab, krb5_flags *ap_req_options, krb5_ticket **ticket) { krb5_error_code retval; retval = rd_req_decoded_opt(context, auth_context, req, server, keytab, ap_req_options, ticket, 1); /* check_valid_flag */ return retval; } krb5_error_code krb5_rd_req_decoded_anyflag(krb5_context context, krb5_auth_context *auth_context, const krb5_ap_req *req, krb5_const_principal server, krb5_keytab keytab, krb5_flags *ap_req_options, krb5_ticket **ticket) { krb5_error_code retval; retval = rd_req_decoded_opt(context, auth_context, req, server, keytab, ap_req_options, ticket, 0); /* don't check_valid_flag */ return retval; } #ifndef LEAN_CLIENT static krb5_error_code decrypt_authenticator(krb5_context context, const krb5_ap_req *request, krb5_authenticator **authpp, int is_ap_req) { krb5_authenticator *local_auth; krb5_error_code retval; krb5_data scratch; krb5_keyblock *sesskey; sesskey = request->ticket->enc_part2->session; scratch.length = request->authenticator.ciphertext.length; if (!(scratch.data = malloc(scratch.length))) return(ENOMEM); if ((retval = krb5_c_decrypt(context, sesskey, is_ap_req?KRB5_KEYUSAGE_AP_REQ_AUTH: KRB5_KEYUSAGE_TGS_REQ_AUTH, 0, &request->authenticator, &scratch))) { free(scratch.data); return(retval); } #define clean_scratch() {memset(scratch.data, 0, scratch.length); \ free(scratch.data);} /* now decode the decrypted stuff */ if (!(retval = decode_krb5_authenticator(&scratch, &local_auth))) *authpp = local_auth; clean_scratch(); return retval; } #endif static krb5_error_code negotiate_etype(krb5_context context, const krb5_enctype *desired_etypes, int desired_etypes_len, int mandatory_etypes_index, const krb5_enctype *permitted_etypes, int permitted_etypes_len, krb5_enctype *negotiated_etype) { int i, j; *negotiated_etype = ENCTYPE_NULL; /* mandatory segment of desired_etypes must be permitted */ for (i = mandatory_etypes_index; i < desired_etypes_len; i++) { krb5_boolean permitted = FALSE; for (j = 0; j < permitted_etypes_len; j++) { if (desired_etypes[i] == permitted_etypes[j]) { permitted = TRUE; break; } } if (permitted == FALSE) { char enctype_name[30]; if (krb5_enctype_to_name(desired_etypes[i], FALSE, enctype_name, sizeof(enctype_name)) == 0) k5_setmsg(context, KRB5_NOPERM_ETYPE, _("Encryption type %s not permitted"), enctype_name); return KRB5_NOPERM_ETYPE; } } /* * permitted_etypes is ordered from most to least preferred; * find first desired_etype that matches. */ for (j = 0; j < permitted_etypes_len; j++) { for (i = 0; i < desired_etypes_len; i++) { if (desired_etypes[i] == permitted_etypes[j]) { *negotiated_etype = permitted_etypes[j]; return 0; } } } /*NOTREACHED*/ return KRB5_NOPERM_ETYPE; } static krb5_error_code decode_etype_list(krb5_context context, const krb5_authenticator *authp, krb5_enctype **desired_etypes, int *desired_etypes_len) { krb5_error_code code; krb5_authdata **ad_if_relevant = NULL; krb5_authdata *etype_adata = NULL; krb5_etype_list *etype_list = NULL; int i, j; krb5_data data; *desired_etypes = NULL; if (authp->authorization_data == NULL) return 0; /* * RFC 4537 says that ETYPE_NEGOTIATION auth data should be wrapped * in AD_IF_RELEVANT, but we handle the case where it is mandatory. */ for (i = 0; authp->authorization_data[i] != NULL; i++) { switch (authp->authorization_data[i]->ad_type) { case KRB5_AUTHDATA_IF_RELEVANT: code = krb5_decode_authdata_container(context, KRB5_AUTHDATA_IF_RELEVANT, authp->authorization_data[i], &ad_if_relevant); if (code != 0) continue; for (j = 0; ad_if_relevant[j] != NULL; j++) { if (ad_if_relevant[j]->ad_type == KRB5_AUTHDATA_ETYPE_NEGOTIATION) { etype_adata = ad_if_relevant[j]; break; } } if (etype_adata == NULL) { krb5_free_authdata(context, ad_if_relevant); ad_if_relevant = NULL; } break; case KRB5_AUTHDATA_ETYPE_NEGOTIATION: etype_adata = authp->authorization_data[i]; break; default: break; } if (etype_adata != NULL) break; } if (etype_adata == NULL) return 0; data.data = (char *)etype_adata->contents; data.length = etype_adata->length; code = decode_krb5_etype_list(&data, &etype_list); if (code == 0) { *desired_etypes = etype_list->etypes; *desired_etypes_len = etype_list->length; free(etype_list); } if (ad_if_relevant != NULL) krb5_free_authdata(context, ad_if_relevant); return code; } krb5-1.22.1/src/lib/krb5/krb/t_parse_host_string.c0000664000175000017500000001546415051422640021555 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/t_parse_host_string.c - k5_parse_host_string() unit tests */ /* * Copyright (C) 2015 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "k5-cmocka.h" /* Call k5_parse_host_string() and check the result against the expected code, * hostname, and port. */ static void call_k5_parse_host_string(const char *host, int default_port, krb5_error_code e_code, const char *e_host, int e_port) { krb5_error_code code; char *host_out = NULL; int port_out = -1; code = k5_parse_host_string(host, default_port, &host_out, &port_out); assert_int_equal(code, e_code); /* Only check the port if the function was expected to be successful. */ if (!e_code) assert_int_equal(port_out, e_port); /* If the expected code is a failure then host_out should be NULL. */ if (e_code != 0 || e_host == NULL) assert_null(host_out); else assert_string_equal(e_host, host_out); free(host_out); } /* k5_parse_host_string() tests */ static void test_named_host_only(void **state) { call_k5_parse_host_string("test.example", 50, 0, "test.example", 50); } static void test_named_host_w_port(void **state) { call_k5_parse_host_string("test.example:75", 0, 0, "test.example", 75); } static void test_ipv4_only(void **state) { call_k5_parse_host_string("192.168.1.1", 100, 0, "192.168.1.1", 100); } static void test_ipv4_w_port(void **state) { call_k5_parse_host_string("192.168.1.1:150", 0, 0, "192.168.1.1", 150); } static void test_ipv6_only(void **state) { call_k5_parse_host_string("[BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE]", 200, 0, "BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE", 200); } static void test_ipv6_w_port(void **state) { call_k5_parse_host_string("[BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE]:250", 0, 0, "BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE", 250); } static void test_ipv6_w_zone(void **state) { call_k5_parse_host_string("[BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE%eth0]", 275, 0, "BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE%eth0", 275); } static void test_invalid_ipv6(void **state) { call_k5_parse_host_string("BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE", 1, EINVAL, NULL, 0); } static void test_no_host_port(void **state) { call_k5_parse_host_string(":300", 0, EINVAL, NULL, 300); } static void test_port_only(void **state) { call_k5_parse_host_string("350", 0, 0, NULL, 350); } static void test_null_host(void **state) { call_k5_parse_host_string(NULL, 400, EINVAL, NULL, 400); } static void test_empty_host(void **state) { call_k5_parse_host_string("", 450, EINVAL, NULL, 450); } static void test_port_out_of_range(void **state) { call_k5_parse_host_string("70000", 1, EINVAL, NULL, 0); } static void test_port_invalid_characters(void **state) { call_k5_parse_host_string("test.example:F101", 1, EINVAL, NULL, 0); } static void test_invalid_default_port(void **state) { call_k5_parse_host_string("test.example", 70000, EINVAL, NULL, 0); } /* k5_is_string_numeric() tests */ static void test_numeric_single_digit(void **state) { assert_true(k5_is_string_numeric("0")); } static void test_numeric_all_digits(void **state) { assert_true(k5_is_string_numeric("0123456789")); } static void test_numeric_alpha(void **state) { assert_false(k5_is_string_numeric("012345F6789")); } static void test_numeric_period(void **state) { assert_false(k5_is_string_numeric("123.456")); } static void test_numeric_negative(void **state) { assert_false(k5_is_string_numeric("-123")); } static void test_numeric_empty(void **state) { assert_false(k5_is_string_numeric("")); } static void test_numeric_whitespace(void **state) { assert_false(k5_is_string_numeric("123 456")); } int main(void) { int ret; const struct CMUnitTest k5_parse_host_string_tests[] = { cmocka_unit_test(test_named_host_only), cmocka_unit_test(test_named_host_w_port), cmocka_unit_test(test_ipv4_only), cmocka_unit_test(test_ipv4_w_port), cmocka_unit_test(test_ipv6_only), cmocka_unit_test(test_ipv6_w_port), cmocka_unit_test(test_ipv6_w_zone), cmocka_unit_test(test_invalid_ipv6), cmocka_unit_test(test_no_host_port), cmocka_unit_test(test_port_only), cmocka_unit_test(test_null_host), cmocka_unit_test(test_empty_host), cmocka_unit_test(test_port_out_of_range), cmocka_unit_test(test_port_invalid_characters), cmocka_unit_test(test_invalid_default_port) }; const struct CMUnitTest k5_is_string_numeric_tests[] = { cmocka_unit_test(test_numeric_single_digit), cmocka_unit_test(test_numeric_all_digits), cmocka_unit_test(test_numeric_alpha), cmocka_unit_test(test_numeric_period), cmocka_unit_test(test_numeric_negative), cmocka_unit_test(test_numeric_empty), cmocka_unit_test(test_numeric_whitespace) }; ret = cmocka_run_group_tests_name("k5_parse_host_string", k5_parse_host_string_tests, NULL, NULL); ret += cmocka_run_group_tests_name("k5_is_string_numeric", k5_is_string_numeric_tests, NULL, NULL); return ret; } krb5-1.22.1/src/lib/krb5/krb/copy_tick.c0000664000175000017500000001053115051422640017447 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/copy_tick.c */ /* * Copyright 1990,1991 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" static krb5_error_code copy_enc_tkt_part(krb5_context context, const krb5_enc_tkt_part *partfrom, krb5_enc_tkt_part **partto) { krb5_error_code retval; krb5_enc_tkt_part *tempto; if (!(tempto = (krb5_enc_tkt_part *)malloc(sizeof(*tempto)))) return ENOMEM; *tempto = *partfrom; retval = krb5_copy_keyblock(context, partfrom->session, &tempto->session); if (retval) { free(tempto); return retval; } retval = krb5_copy_principal(context, partfrom->client, &tempto->client); if (retval) { krb5_free_keyblock(context, tempto->session); free(tempto); return retval; } tempto->transited = partfrom->transited; if (tempto->transited.tr_contents.length == 0) { tempto->transited.tr_contents.data = 0; } else { tempto->transited.tr_contents.data = k5memdup(partfrom->transited.tr_contents.data, partfrom->transited.tr_contents.length, &retval); if (!tempto->transited.tr_contents.data) { krb5_free_principal(context, tempto->client); krb5_free_keyblock(context, tempto->session); free(tempto); return ENOMEM; } } retval = krb5_copy_addresses(context, partfrom->caddrs, &tempto->caddrs); if (retval) { free(tempto->transited.tr_contents.data); krb5_free_principal(context, tempto->client); krb5_free_keyblock(context, tempto->session); free(tempto); return retval; } if (partfrom->authorization_data) { retval = krb5_copy_authdata(context, partfrom->authorization_data, &tempto->authorization_data); if (retval) { krb5_free_addresses(context, tempto->caddrs); free(tempto->transited.tr_contents.data); krb5_free_principal(context, tempto->client); krb5_free_keyblock(context, tempto->session); free(tempto); return retval; } } *partto = tempto; return 0; } krb5_error_code KRB5_CALLCONV krb5_copy_ticket(krb5_context context, const krb5_ticket *from, krb5_ticket **pto) { krb5_error_code retval; krb5_ticket *tempto; krb5_data *scratch; if (!(tempto = (krb5_ticket *)malloc(sizeof(*tempto)))) return ENOMEM; *tempto = *from; retval = krb5_copy_principal(context, from->server, &tempto->server); if (retval) { free(tempto); return retval; } retval = krb5_copy_data(context, &from->enc_part.ciphertext, &scratch); if (retval) { krb5_free_principal(context, tempto->server); free(tempto); return retval; } tempto->enc_part.ciphertext = *scratch; free(scratch); retval = copy_enc_tkt_part(context, from->enc_part2, &tempto->enc_part2); if (retval) { free(tempto->enc_part.ciphertext.data); krb5_free_principal(context, tempto->server); free(tempto); return retval; } *pto = tempto; return 0; } krb5-1.22.1/src/lib/krb5/krb/conv_creds.c0000664000175000017500000000432515051422640017614 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1994 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation, and that the name of OpenVision not be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #include "k5-int.h" #include #include #include #include "port-sockets.h" #include "socket-utils.h" krb5_error_code KRB5_CALLCONV krb5_524_convert_creds(krb5_context context, krb5_creds *v5creds, struct credentials *v4creds) { return KRB524_KRB4_DISABLED; } /* These may be needed for object-level backwards compatibility on Mac OS and UNIX, but Windows should be okay. */ #ifndef _WIN32 #undef krb524_convert_creds_kdc #undef krb524_init_ets /* Declarations ahead of the definitions will suppress some gcc warnings. */ void KRB5_CALLCONV krb524_init_ets (void); krb5_error_code KRB5_CALLCONV krb524_convert_creds_kdc(krb5_context context, krb5_creds *v5creds, struct credentials *v4creds); krb5_error_code KRB5_CALLCONV krb524_convert_creds_kdc(krb5_context context, krb5_creds *v5creds, struct credentials *v4creds) { return KRB524_KRB4_DISABLED; } void KRB5_CALLCONV krb524_init_ets (void) { } #endif krb5-1.22.1/src/lib/krb5/krb/preauth2.c0000664000175000017500000010432615051422640017223 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 1995, 2003, 2008, 2012 by the Massachusetts Institute of Technology. All * Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * */ /* * This file contains routines for establishing, verifying, and any other * necessary functions, for utilizing the pre-authentication field of the * kerberos kdc request, with various hardware/software verification devices. */ #include "k5-int.h" #include "k5-json.h" #include "osconf.h" #include #include "int-proto.h" #include "os-proto.h" #include "fast.h" #include "init_creds_ctx.h" #if !defined(_WIN32) #include #endif typedef struct { struct krb5_clpreauth_vtable_st vt; krb5_clpreauth_moddata data; } *clpreauth_handle; struct krb5_preauth_context_st { clpreauth_handle *handles; }; struct krb5_preauth_req_context_st { krb5_context orig_context; krb5_preauthtype *failed; krb5_clpreauth_modreq *modreqs; }; /* Release the memory used by a list of handles. */ static void free_handles(krb5_context context, clpreauth_handle *handles) { clpreauth_handle *hp, h; if (handles == NULL) return; for (hp = handles; *hp != NULL; hp++) { h = *hp; if (h->vt.fini != NULL) h->vt.fini(context, h->data); free(h); } free(handles); } /* Return an index into handles which can process pa_type, or -1 if none is * found found. */ static int search_module_list(clpreauth_handle *handles, krb5_preauthtype pa_type) { clpreauth_handle h; int i, j; for (i = 0; handles[i] != NULL; i++) { h = handles[i]; for (j = 0; h->vt.pa_type_list[j] != 0; j++) { if (h->vt.pa_type_list[j] == pa_type) return i; } } return -1; } /* Find the handle which can process pa_type, or NULL if none is found. On * success, set *modreq_out to the corresponding per-request module data. */ static clpreauth_handle find_module(krb5_context context, krb5_init_creds_context ctx, krb5_preauthtype pa_type, krb5_clpreauth_modreq *modreq_out) { krb5_preauth_context pctx = context->preauth_context; krb5_preauth_req_context reqctx = ctx->preauth_reqctx; int i; *modreq_out = NULL; if (pctx == NULL || reqctx == NULL) return NULL; i = search_module_list(pctx->handles, pa_type); if (i == -1) return NULL; *modreq_out = reqctx->modreqs[i]; return pctx->handles[i]; } /* Initialize the preauth state for a krb5 context. */ void k5_init_preauth_context(krb5_context context) { krb5_plugin_initvt_fn *modules = NULL, *mod; clpreauth_handle *list = NULL, h; int i; size_t count; krb5_preauthtype *tp; /* Only do this once for each krb5_context */ if (context->preauth_context != NULL) return; /* Auto-register built-in modules. */ k5_plugin_register_dyn(context, PLUGIN_INTERFACE_CLPREAUTH, "pkinit", "preauth"); k5_plugin_register_dyn(context, PLUGIN_INTERFACE_CLPREAUTH, "spake", "preauth"); k5_plugin_register(context, PLUGIN_INTERFACE_CLPREAUTH, "encrypted_challenge", clpreauth_encrypted_challenge_initvt); k5_plugin_register(context, PLUGIN_INTERFACE_CLPREAUTH, "encrypted_timestamp", clpreauth_encrypted_timestamp_initvt); k5_plugin_register(context, PLUGIN_INTERFACE_CLPREAUTH, "sam2", clpreauth_sam2_initvt); k5_plugin_register(context, PLUGIN_INTERFACE_CLPREAUTH, "otp", clpreauth_otp_initvt); /* Get all available clpreauth vtables. */ if (k5_plugin_load_all(context, PLUGIN_INTERFACE_CLPREAUTH, &modules)) return; /* Allocate a large enough list of handles. */ for (count = 0; modules[count] != NULL; count++); list = calloc(count + 1, sizeof(*list)); if (list == NULL) goto cleanup; /* Create a handle for each module we can successfully initialize. */ count = 0; for (mod = modules; *mod != NULL; mod++) { h = calloc(1, sizeof(*h)); if (h == NULL) goto cleanup; /* Initialize the handle vtable. */ if ((*mod)(context, 1, 1, (krb5_plugin_vtable)&h->vt) != 0) { free(h); continue; } /* Check for a preauth type conflict with an existing module. */ for (tp = h->vt.pa_type_list; *tp != 0; tp++) { i = search_module_list(list, *tp); if (i != -1) { TRACE_PREAUTH_CONFLICT(context, h->vt.name, list[i]->vt.name, *tp); break; } } if (*tp != 0) continue; /* Initialize the module data. */ h->data = NULL; if (h->vt.init != NULL && h->vt.init(context, &h->data) != 0) { free(h); continue; } list[count++] = h; list[count] = NULL; } list[count] = NULL; /* Place the constructed preauth context into the krb5 context. */ context->preauth_context = malloc(sizeof(*context->preauth_context)); if (context->preauth_context == NULL) goto cleanup; context->preauth_context->handles = list; list = NULL; cleanup: k5_plugin_free_modules(context, modules); free_handles(context, list); } /* Add pa_type to the list of types which has previously failed. */ krb5_error_code k5_preauth_note_failed(krb5_init_creds_context ctx, krb5_preauthtype pa_type) { krb5_preauth_req_context reqctx = ctx->preauth_reqctx; krb5_preauthtype *newptr; size_t i; for (i = 0; reqctx->failed != NULL && reqctx->failed[i] != 0; i++); newptr = realloc(reqctx->failed, (i + 2) * sizeof(*newptr)); if (newptr == NULL) return ENOMEM; reqctx->failed = newptr; reqctx->failed[i] = pa_type; reqctx->failed[i + 1] = 0; return 0; } /* Free the per-krb5_context preauth_context. This means clearing any * plugin-specific context which may have been created, and then * freeing the context itself. */ void k5_free_preauth_context(krb5_context context) { krb5_preauth_context pctx = context->preauth_context; if (pctx == NULL) return; free_handles(context, pctx->handles); free(pctx); context->preauth_context = NULL; } /* Initialize the per-AS-REQ context. This means calling the client_req_init * function to give the plugin a chance to allocate a per-request context. */ void k5_preauth_request_context_init(krb5_context context, krb5_init_creds_context ctx) { krb5_preauth_context pctx = context->preauth_context; clpreauth_handle h; krb5_preauth_req_context reqctx; size_t count, i; if (pctx == NULL) { k5_init_preauth_context(context); pctx = context->preauth_context; if (pctx == NULL) return; } reqctx = calloc(1, sizeof(*reqctx)); if (reqctx == NULL) return; reqctx->orig_context = context; /* Create an array of per-request module data objects corresponding to the * preauth context's array of handles. */ for (count = 0; pctx->handles[count] != NULL; count++); reqctx->modreqs = calloc(count, sizeof(*reqctx->modreqs)); if (reqctx->modreqs == NULL) { free(reqctx); return; } for (i = 0; i < count; i++) { h = pctx->handles[i]; if (h->vt.request_init != NULL) h->vt.request_init(context, h->data, &reqctx->modreqs[i]); } ctx->preauth_reqctx = reqctx; } /* Free the per-AS-REQ context. This means clearing any request-specific * context which the plugin may have created. */ void k5_preauth_request_context_fini(krb5_context context, krb5_init_creds_context ctx) { krb5_preauth_context pctx = context->preauth_context; krb5_preauth_req_context reqctx = ctx->preauth_reqctx; size_t i; clpreauth_handle h; if (reqctx == NULL) return; if (reqctx->orig_context == context && pctx != NULL) { for (i = 0; pctx->handles[i] != NULL; i++) { h = pctx->handles[i]; if (reqctx->modreqs[i] != NULL && h->vt.request_fini != NULL) h->vt.request_fini(context, h->data, reqctx->modreqs[i]); } } else { TRACE_PREAUTH_WRONG_CONTEXT(context); } free(reqctx->modreqs); free(reqctx->failed); free(reqctx); ctx->preauth_reqctx = NULL; } krb5_error_code k5_preauth_check_context(krb5_context context, krb5_init_creds_context ctx) { krb5_preauth_req_context reqctx = ctx->preauth_reqctx; if (reqctx != NULL && reqctx->orig_context != context) { k5_setmsg(context, EINVAL, _("krb5_init_creds calls must use same library context")); return EINVAL; } return 0; } /* Return 1 if pa_type is a real preauthentication mechanism according to the * module h. Return 0 if it is not. */ static int clpreauth_is_real(krb5_context context, clpreauth_handle h, krb5_preauthtype pa_type) { if (h->vt.flags == NULL) return 1; return (h->vt.flags(context, pa_type) & PA_REAL) != 0; } static krb5_error_code clpreauth_prep_questions(krb5_context context, clpreauth_handle h, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *req, krb5_data *req_body, krb5_data *prev_req, krb5_pa_data *pa_data) { if (h->vt.prep_questions == NULL) return 0; return h->vt.prep_questions(context, h->data, modreq, opt, cb, rock, req, req_body, prev_req, pa_data); } static krb5_error_code clpreauth_process(krb5_context context, clpreauth_handle h, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *req, krb5_data *req_body, krb5_data *prev_req, krb5_pa_data *pa_data, krb5_prompter_fct prompter, void *prompter_data, krb5_pa_data ***pa_data_out) { return h->vt.process(context, h->data, modreq, opt, cb, rock, req, req_body, prev_req, pa_data, prompter, prompter_data, pa_data_out); } static krb5_error_code clpreauth_tryagain(krb5_context context, clpreauth_handle h, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *req, krb5_data *req_body, krb5_data *prev_req, krb5_preauthtype pa_type, krb5_error *error, krb5_pa_data **error_padata, krb5_prompter_fct prompter, void *prompter_data, krb5_pa_data ***pa_data_out) { if (h->vt.tryagain == NULL) return 0; return h->vt.tryagain(context, h->data, modreq, opt, cb, rock, req, req_body, prev_req, pa_type, error, error_padata, prompter, prompter_data, pa_data_out); } static krb5_error_code clpreauth_gic_opts(krb5_context context, clpreauth_handle h, krb5_get_init_creds_opt *opt, const char *attr, const char *value) { if (h->vt.gic_opts == NULL) return 0; return h->vt.gic_opts(context, h->data, opt, attr, value); } /* Add the named encryption type to the existing list of ktypes. */ static void grow_ktypes(krb5_enctype **out_ktypes, int *out_nktypes, krb5_enctype ktype) { int i; krb5_enctype *ktypes; for (i = 0; i < *out_nktypes; i++) { if ((*out_ktypes)[i] == ktype) return; } ktypes = realloc(*out_ktypes, (*out_nktypes + 2) * sizeof(ktype)); if (ktypes != NULL) { *out_ktypes = ktypes; ktypes[(*out_nktypes)++] = ktype; ktypes[*out_nktypes] = 0; } } /* Add a list of new pa_data items to an existing list. */ static int grow_pa_list(krb5_pa_data ***out_pa_list, int *out_pa_list_size, krb5_pa_data **addition, int num_addition) { krb5_pa_data **pa_list; int i; /* Allocate space for new entries and a null terminator. */ pa_list = realloc(*out_pa_list, (*out_pa_list_size + num_addition + 1) * sizeof(*pa_list)); if (pa_list == NULL) return ENOMEM; *out_pa_list = pa_list; for (i = 0; i < num_addition; i++) pa_list[(*out_pa_list_size)++] = addition[i]; pa_list[*out_pa_list_size] = NULL; return 0; } static krb5_enctype get_etype(krb5_context context, krb5_clpreauth_rock rock) { krb5_init_creds_context ctx = (krb5_init_creds_context)rock; if (ctx->reply != NULL) return ctx->reply->enc_part.enctype; return ctx->etype; } static krb5_keyblock * fast_armor(krb5_context context, krb5_clpreauth_rock rock) { return ((krb5_init_creds_context)rock)->fast_state->armor_key; } static krb5_error_code get_as_key(krb5_context context, krb5_clpreauth_rock rock, krb5_keyblock **keyblock) { krb5_init_creds_context ctx = (krb5_init_creds_context)rock; krb5_error_code ret; krb5_data *salt; if (ctx->as_key.length == 0) { salt = ctx->default_salt ? NULL : &ctx->salt; ret = ctx->gak_fct(context, ctx->request->client, ctx->etype, ctx->prompter, ctx->prompter_data, salt, &ctx->s2kparams, &ctx->as_key, ctx->gak_data, ctx->rctx.items); if (ret) return ret; } *keyblock = &ctx->as_key; return 0; } static krb5_error_code set_as_key(krb5_context context, krb5_clpreauth_rock rock, const krb5_keyblock *keyblock) { krb5_init_creds_context ctx = (krb5_init_creds_context)rock; krb5_free_keyblock_contents(context, &ctx->as_key); return krb5_copy_keyblock_contents(context, keyblock, &ctx->as_key); } static krb5_error_code get_preauth_time(krb5_context context, krb5_clpreauth_rock rock, krb5_boolean allow_unauth_time, krb5_timestamp *time_out, krb5_int32 *usec_out) { return k5_init_creds_current_time(context, (krb5_init_creds_context)rock, allow_unauth_time, time_out, usec_out); } static krb5_error_code responder_ask_question(krb5_context context, krb5_clpreauth_rock rock, const char *question, const char *challenge) { krb5_init_creds_context ctx = (krb5_init_creds_context)rock; /* Force plugins to use need_as_key(). */ if (strcmp(KRB5_RESPONDER_QUESTION_PASSWORD, question) == 0) return EINVAL; return k5_response_items_ask_question(ctx->rctx.items, question, challenge); } static const char * responder_get_answer(krb5_context context, krb5_clpreauth_rock rock, const char *question) { krb5_init_creds_context ctx = (krb5_init_creds_context)rock; /* Don't let plugins get the raw password. */ if (strcmp(KRB5_RESPONDER_QUESTION_PASSWORD, question) == 0) return NULL; return k5_response_items_get_answer(ctx->rctx.items, question); } static void need_as_key(krb5_context context, krb5_clpreauth_rock rock) { krb5_init_creds_context ctx = (krb5_init_creds_context)rock; /* Calling gac_fct() with NULL as_key indicates desire for the AS key. */ ctx->gak_fct(context, ctx->request->client, ctx->etype, NULL, NULL, NULL, NULL, NULL, ctx->gak_data, ctx->rctx.items); } static const char * get_cc_config(krb5_context context, krb5_clpreauth_rock rock, const char *key) { krb5_init_creds_context ctx = (krb5_init_creds_context)rock; k5_json_value value; if (ctx->cc_config_in == NULL) return NULL; value = k5_json_object_get(ctx->cc_config_in, key); if (value == NULL) return NULL; if (k5_json_get_tid(value) != K5_JSON_TID_STRING) return NULL; return k5_json_string_utf8(value); } static krb5_error_code set_cc_config(krb5_context context, krb5_clpreauth_rock rock, const char *key, const char *data) { krb5_init_creds_context ctx = (krb5_init_creds_context)rock; krb5_error_code ret; k5_json_string str; if (ctx->cc_config_out == NULL) return ENOENT; ret = k5_json_string_create(data, &str); if (ret) return ret; ret = k5_json_object_set(ctx->cc_config_out, key, str); k5_json_release(str); return ret; } static void disable_fallback(krb5_context context, krb5_clpreauth_rock rock) { ((krb5_init_creds_context)rock)->fallback_disabled = TRUE; } static struct krb5_clpreauth_callbacks_st callbacks = { 3, get_etype, fast_armor, get_as_key, set_as_key, get_preauth_time, responder_ask_question, responder_get_answer, need_as_key, get_cc_config, set_cc_config, disable_fallback }; /* Tweak the request body, for now adding any enctypes which the module claims * to add support for to the list, but in the future perhaps doing more * involved things. */ void k5_preauth_prepare_request(krb5_context context, krb5_get_init_creds_opt *opt, krb5_kdc_req *req) { krb5_preauth_context pctx = context->preauth_context; clpreauth_handle *hp, h; krb5_enctype *ep; if (pctx == NULL) return; /* Don't modify the enctype list if it's specified in the gic opts. */ if (opt != NULL && (opt->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST)) return; for (hp = pctx->handles; *hp != NULL; hp++) { h = *hp; if (h->vt.enctype_list == NULL) continue; for (ep = h->vt.enctype_list; *ep != ENCTYPE_NULL; ep++) grow_ktypes(&req->ktype, &req->nktypes, *ep); } } const char * const * KRB5_CALLCONV krb5_responder_list_questions(krb5_context ctx, krb5_responder_context rctx) { return k5_response_items_list_questions(rctx->items); } const char * KRB5_CALLCONV krb5_responder_get_challenge(krb5_context ctx, krb5_responder_context rctx, const char *question) { if (rctx == NULL) return NULL; return k5_response_items_get_challenge(rctx->items, question); } krb5_error_code KRB5_CALLCONV krb5_responder_set_answer(krb5_context ctx, krb5_responder_context rctx, const char *question, const char *answer) { if (rctx == NULL) return EINVAL; return k5_response_items_set_answer(rctx->items, question, answer); } /* Return true if pa_type matches the specific preauth type allowed for this * authentication, or if there is no specific allowed type. */ static inline krb5_boolean pa_type_allowed(krb5_init_creds_context ctx, krb5_preauthtype pa_type) { return ctx->allowed_preauth_type == KRB5_PADATA_NONE || pa_type == ctx->allowed_preauth_type; } /* Return true if pa_type previously failed during this authentication. */ static krb5_boolean previously_failed(krb5_init_creds_context ctx, krb5_preauthtype pa_type) { krb5_preauth_req_context reqctx = ctx->preauth_reqctx; size_t i; for (i = 0; reqctx->failed != NULL && reqctx->failed[i] != 0; i++) { if (reqctx->failed[i] == pa_type) return TRUE; } return FALSE; } /* Allow clpreauth modules to process in_pa_list and produce output padata. */ static krb5_error_code process_pa_data(krb5_context context, krb5_init_creds_context ctx, krb5_pa_data **in_pa_list, krb5_boolean must_preauth, krb5_pa_data ***out_pa_list, int *out_pa_list_size, krb5_preauthtype *out_type) { struct errinfo save = EMPTY_ERRINFO; krb5_pa_data *pa, **pa_ptr, **mod_pa; krb5_error_code ret = 0; krb5_clpreauth_modreq modreq; clpreauth_handle h; int real, i; /* Process all informational padata types, then the first real preauth type * we succeed on. */ for (real = 0; real <= 1; real++) { for (pa_ptr = in_pa_list; *pa_ptr != NULL; pa_ptr++) { pa = *pa_ptr; /* Restrict real mechanisms to the chosen one if we have one. */ if (real && !pa_type_allowed(ctx, pa->pa_type)) continue; h = find_module(context, ctx, pa->pa_type, &modreq); if (h == NULL) continue; /* Make sure this type is for the current pass. */ if (clpreauth_is_real(context, h, pa->pa_type) != real) continue; /* Don't try a real mechanism again after failure. */ if (real && previously_failed(ctx, pa->pa_type)) continue; mod_pa = NULL; ret = clpreauth_process(context, h, modreq, ctx->opt, &callbacks, (krb5_clpreauth_rock)ctx, ctx->request, ctx->inner_request_body, ctx->encoded_previous_request, pa, ctx->prompter, ctx->prompter_data, &mod_pa); TRACE_PREAUTH_PROCESS(context, h->vt.name, pa->pa_type, real, ret); if (mod_pa != NULL) { for (i = 0; mod_pa[i] != NULL; i++); ret = grow_pa_list(out_pa_list, out_pa_list_size, mod_pa, i); if (ret) { krb5_free_pa_data(context, mod_pa); goto cleanup; } free(mod_pa); } /* Don't continue to try mechanisms after a keyboard interrupt. */ if (ret == KRB5_LIBOS_PWDINTR) goto cleanup; if (ret == 0 && real) { /* Stop now and record which real padata type we answered. */ *out_type = pa->pa_type; goto cleanup; } else if (real && save.code == 0) { /* Save the first error we get from a real preauth type. */ k5_save_ctx_error(context, ret, &save); } if (real && ret) { /* Don't try this mechanism again for this authentication. */ ret = k5_preauth_note_failed(ctx, pa->pa_type); if (ret) goto cleanup; } } } if (must_preauth) { /* No real preauth types succeeded and we needed to preauthenticate. */ if (save.code != 0) { ret = k5_restore_ctx_error(context, &save); k5_wrapmsg(context, ret, KRB5_PREAUTH_FAILED, _("Pre-authentication failed")); } ret = KRB5_PREAUTH_FAILED; } cleanup: k5_clear_error(&save); return ret; } static inline krb5_data padata2data(krb5_pa_data p) { krb5_data d; d.magic = KV5M_DATA; d.length = p.length; d.data = (char *) p.contents; return d; } /* Set salt in rock based on pw-salt or afs3-salt elements in padata. */ static krb5_error_code get_salt(krb5_context context, krb5_init_creds_context ctx, krb5_pa_data **padata) { krb5_error_code ret; krb5_pa_data *pa; krb5_data d; const char *p; /* Look for a pw-salt or afs3-salt element. */ pa = krb5int_find_pa_data(context, padata, KRB5_PADATA_PW_SALT); if (pa == NULL) pa = krb5int_find_pa_data(context, padata, KRB5_PADATA_AFS3_SALT); if (pa == NULL) return 0; /* Set ctx->salt based on the element we found. */ krb5_free_data_contents(context, &ctx->salt); d = padata2data(*pa); ret = krb5int_copy_data_contents(context, &d, &ctx->salt); if (ret) return ret; /* Adjust the salt if we got it from an afs3-salt element. */ if (pa->pa_type == KRB5_PADATA_AFS3_SALT) { /* Work around a (possible) old Heimdal KDC foible. */ p = memchr(ctx->salt.data, '@', ctx->salt.length); if (p != NULL) ctx->salt.length = p - ctx->salt.data; /* Tolerate extra null in MIT KDC afs3-salt value. */ if (ctx->salt.length > 0 && ctx->salt.data[ctx->salt.length - 1] == '\0') ctx->salt.length--; /* Set an s2kparams value to indicate AFS string-to-key. */ krb5_free_data_contents(context, &ctx->s2kparams); ret = alloc_data(&ctx->s2kparams, 1); if (ret) return ret; ctx->s2kparams.data[0] = '\1'; } ctx->default_salt = FALSE; TRACE_PREAUTH_SALT(context, &ctx->salt, pa->pa_type); return 0; } /* Set etype info parameters in rock based on padata. */ krb5_error_code k5_get_etype_info(krb5_context context, krb5_init_creds_context ctx, krb5_pa_data **padata) { krb5_error_code ret = 0; krb5_pa_data *pa; krb5_data d; krb5_etype_info etype_info = NULL, e; krb5_etype_info_entry *entry; krb5_boolean valid_found; int i; /* Find an etype-info2 or etype-info element in padata. */ pa = krb5int_find_pa_data(context, padata, KRB5_PADATA_ETYPE_INFO2); if (pa != NULL) { d = padata2data(*pa); (void)decode_krb5_etype_info2(&d, &etype_info); } else { pa = krb5int_find_pa_data(context, padata, KRB5_PADATA_ETYPE_INFO); if (pa != NULL) { d = padata2data(*pa); (void)decode_krb5_etype_info(&d, &etype_info); } } /* Fall back to pw-salt/afs3-salt if no etype-info element is present. */ if (etype_info == NULL) return get_salt(context, ctx, padata); /* Search entries in order of the request's enctype preference. */ entry = NULL; valid_found = FALSE; for (i = 0; i < ctx->request->nktypes && entry == NULL; i++) { for (e = etype_info; *e != NULL && entry == NULL; e++) { if ((*e)->etype == ctx->request->ktype[i]) entry = *e; if (krb5_c_valid_enctype((*e)->etype)) valid_found = TRUE; } } if (entry == NULL) { ret = (valid_found) ? KRB5_CONFIG_ETYPE_NOSUPP : KRB5_PROG_ETYPE_NOSUPP; goto cleanup; } /* Set etype/salt/s2kparams fields based on the entry we selected. */ ctx->etype = entry->etype; krb5_free_data_contents(context, &ctx->salt); if (entry->length != KRB5_ETYPE_NO_SALT) { ctx->salt = make_data(entry->salt, entry->length); entry->salt = NULL; ctx->default_salt = FALSE; } else { ctx->salt = empty_data(); ctx->default_salt = TRUE; } krb5_free_data_contents(context, &ctx->s2kparams); ctx->s2kparams = entry->s2kparams; entry->s2kparams = empty_data(); TRACE_PREAUTH_ETYPE_INFO(context, ctx->etype, &ctx->salt, &ctx->s2kparams); cleanup: krb5_free_etype_info(context, etype_info); return ret; } /* Look for an fx-cookie element in in_padata and add it to out_pa_list. */ static krb5_error_code copy_cookie(krb5_context context, krb5_pa_data **in_padata, krb5_pa_data ***out_pa_list, int *out_pa_list_size) { krb5_error_code ret; krb5_pa_data *cookie, *pa = NULL; cookie = krb5int_find_pa_data(context, in_padata, KRB5_PADATA_FX_COOKIE); if (cookie == NULL) return 0; TRACE_PREAUTH_COOKIE(context, cookie->length, cookie->contents); pa = k5alloc(sizeof(*pa), &ret); if (pa == NULL) return ret; *pa = *cookie; pa->contents = k5memdup(cookie->contents, cookie->length, &ret); if (pa->contents == NULL) goto error; ret = grow_pa_list(out_pa_list, out_pa_list_size, &pa, 1); if (ret) goto error; return 0; error: free(pa->contents); free(pa); return ENOMEM; } /* * If the module for pa_type can adjust its AS_REQ data using the contents of * err and err_padata, return 0 with *padata_out set to a padata list for the * next request. If it's the sort of correction which requires that we ask the * user another question, we let the calling application deal with it. */ krb5_error_code k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, krb5_preauthtype pa_type, krb5_error *err, krb5_pa_data **err_padata, krb5_pa_data ***padata_out) { krb5_error_code ret; krb5_pa_data **mod_pa; krb5_clpreauth_modreq modreq; clpreauth_handle h; int count; *padata_out = NULL; TRACE_PREAUTH_TRYAGAIN_INPUT(context, pa_type, err_padata); h = find_module(context, ctx, pa_type, &modreq); if (h == NULL) return KRB5KRB_ERR_GENERIC; mod_pa = NULL; ret = clpreauth_tryagain(context, h, modreq, ctx->opt, &callbacks, (krb5_clpreauth_rock)ctx, ctx->request, ctx->inner_request_body, ctx->encoded_previous_request, pa_type, err, err_padata, ctx->prompter, ctx->prompter_data, &mod_pa); TRACE_PREAUTH_TRYAGAIN(context, h->vt.name, pa_type, ret); if (!ret && mod_pa == NULL) ret = KRB5KRB_ERR_GENERIC; if (ret) { k5_preauth_note_failed(ctx, pa_type); return ret; } for (count = 0; mod_pa[count] != NULL; count++); ret = copy_cookie(context, err_padata, &mod_pa, &count); if (ret) { krb5_free_pa_data(context, mod_pa); return ret; } TRACE_PREAUTH_TRYAGAIN_OUTPUT(context, mod_pa); *padata_out = mod_pa; return 0; } /* Compile the set of response items for in_padata by invoke each module's * prep_questions method. */ static krb5_error_code fill_response_items(krb5_context context, krb5_init_creds_context ctx, krb5_pa_data **in_padata) { krb5_error_code ret; krb5_pa_data *pa; krb5_clpreauth_modreq modreq; clpreauth_handle h; int i; k5_response_items_reset(ctx->rctx.items); for (i = 0; in_padata[i] != NULL; i++) { pa = in_padata[i]; if (!pa_type_allowed(ctx, pa->pa_type)) continue; h = find_module(context, ctx, pa->pa_type, &modreq); if (h == NULL) continue; ret = clpreauth_prep_questions(context, h, modreq, ctx->opt, &callbacks, (krb5_clpreauth_rock)ctx, ctx->request, ctx->inner_request_body, ctx->encoded_previous_request, pa); if (ret) return ret; } return 0; } krb5_error_code k5_preauth(krb5_context context, krb5_init_creds_context ctx, krb5_pa_data **in_padata, krb5_boolean must_preauth, krb5_pa_data ***padata_out, krb5_preauthtype *pa_type_out) { int out_pa_list_size = 0; krb5_pa_data **out_pa_list = NULL; krb5_error_code ret; krb5_responder_fn responder; void *responder_data; *padata_out = NULL; *pa_type_out = KRB5_PADATA_NONE; /* We should never invoke preauth modules when identifying the realm. */ if (in_padata == NULL || ctx->identify_realm) return 0; TRACE_PREAUTH_INPUT(context, in_padata); /* Scan the padata list and process etype-info or salt elements. */ ret = k5_get_etype_info(context, ctx, in_padata); if (ret) return ret; /* Copy the cookie if there is one. */ ret = copy_cookie(context, in_padata, &out_pa_list, &out_pa_list_size); if (ret) goto error; /* If we can't initialize the preauth context, stop with what we have. */ k5_init_preauth_context(context); if (context->preauth_context == NULL) { *padata_out = out_pa_list; out_pa_list = NULL; goto error; } /* Get a list of response items for in_padata from the preauth modules. */ ret = fill_response_items(context, ctx, in_padata); if (ret) goto error; /* Call the responder to answer response items. */ k5_gic_opt_get_responder(ctx->opt, &responder, &responder_data); if (responder != NULL && !k5_response_items_empty(ctx->rctx.items)) { ret = (*responder)(context, responder_data, &ctx->rctx); if (ret) goto error; } ret = process_pa_data(context, ctx, in_padata, must_preauth, &out_pa_list, &out_pa_list_size, pa_type_out); if (ret) goto error; TRACE_PREAUTH_OUTPUT(context, out_pa_list); *padata_out = out_pa_list; return 0; error: krb5_free_pa_data(context, out_pa_list); return ret; } /* * Give all the preauth plugins a look at the preauth option which * has just been set */ krb5_error_code krb5_preauth_supply_preauth_data(krb5_context context, krb5_get_init_creds_opt *opt, const char *attr, const char *value) { krb5_preauth_context pctx = context->preauth_context; clpreauth_handle *hp, h; krb5_error_code ret; if (pctx == NULL) { k5_init_preauth_context(context); pctx = context->preauth_context; if (pctx == NULL) { k5_setmsg(context, EINVAL, _("Unable to initialize preauth context")); return EINVAL; } } /* * Go down the list of preauth modules, and supply them with the * attribute/value pair. */ for (hp = pctx->handles; *hp != NULL; hp++) { h = *hp; ret = clpreauth_gic_opts(context, h, opt, attr, value); if (ret) { k5_prependmsg(context, ret, _("Preauth module %s"), h->vt.name); return ret; } } return 0; } krb5-1.22.1/src/lib/krb5/krb/strptime.c0000664000175000017500000002175215051422640017341 0ustar ghudsonghudson/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */ /* lib/krb5/krb/strptime.c */ /* * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code was contributed to The NetBSD Foundation by Klaus Klein. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the NetBSD * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: strptime.c,v 1.18 1999/04/29 02:58:30 tv Exp $"); #endif #include #include #include #undef _ctloc #define _ctloc(x) _CurrentTimeLocale->x /* * We do not implement alternate representations. However, we always * check whether a given modifier is allowed for a certain conversion. */ #define ALT_E 0x01 #define ALT_O 0x02 #define LEGAL_ALT(x) { if (alt_format & ~(x)) return (0); } static int conv_num __P((const char **, int *, int, int)); static char * strptime(buf, fmt, tm) const char *buf, *fmt; struct tm *tm; { char c; const char *bp; size_t len = 0; int alt_format, i, split_year = 0; bp = buf; while ((c = *fmt) != '\0') { /* Clear `alternate' modifier prior to new conversion. */ alt_format = 0; /* Eat up white-space. */ if (isspace(c)) { while (isspace(*bp)) bp++; fmt++; continue; } if ((c = *fmt++) != '%') goto literal; again: switch (c = *fmt++) { case '%': /* "%%" is converted to "%". */ literal: if (c != *bp++) return (0); break; /* * "Alternative" modifiers. Just set the appropriate flag * and start over again. */ case 'E': /* "%E?" alternative conversion modifier. */ LEGAL_ALT(0); alt_format |= ALT_E; goto again; case 'O': /* "%O?" alternative conversion modifier. */ LEGAL_ALT(0); alt_format |= ALT_O; goto again; /* * "Complex" conversion rules, implemented through recursion. */ case 'c': /* Date and time, using the locale's format. */ LEGAL_ALT(ALT_E); if (!(bp = strptime(bp, _ctloc(d_t_fmt), tm))) return (0); break; case 'D': /* The date as "%m/%d/%y". */ LEGAL_ALT(0); if (!(bp = strptime(bp, "%m/%d/%y", tm))) return (0); break; case 'R': /* The time as "%H:%M". */ LEGAL_ALT(0); if (!(bp = strptime(bp, "%H:%M", tm))) return (0); break; case 'r': /* The time in 12-hour clock representation. */ LEGAL_ALT(0); if (!(bp = strptime(bp, _ctloc(t_fmt_ampm), tm))) return (0); break; case 'T': /* The time as "%H:%M:%S". */ LEGAL_ALT(0); if (!(bp = strptime(bp, "%H:%M:%S", tm))) return (0); break; case 'X': /* The time, using the locale's format. */ LEGAL_ALT(ALT_E); if (!(bp = strptime(bp, _ctloc(t_fmt), tm))) return (0); break; case 'x': /* The date, using the locale's format. */ LEGAL_ALT(ALT_E); if (!(bp = strptime(bp, _ctloc(d_fmt), tm))) return (0); break; /* * "Elementary" conversion rules. */ case 'A': /* The day of week, using the locale's form. */ case 'a': LEGAL_ALT(0); for (i = 0; i < 7; i++) { /* Full name. */ len = strlen(_ctloc(day[i])); if (strncasecmp(_ctloc(day[i]), bp, len) == 0) break; /* Abbreviated name. */ len = strlen(_ctloc(abday[i])); if (strncasecmp(_ctloc(abday[i]), bp, len) == 0) break; } /* Nothing matched. */ if (i == 7) return (0); tm->tm_wday = i; bp += len; break; case 'B': /* The month, using the locale's form. */ case 'b': case 'h': LEGAL_ALT(0); for (i = 0; i < 12; i++) { /* Full name. */ len = strlen(_ctloc(mon[i])); if (strncasecmp(_ctloc(mon[i]), bp, len) == 0) break; /* Abbreviated name. */ len = strlen(_ctloc(abmon[i])); if (strncasecmp(_ctloc(abmon[i]), bp, len) == 0) break; } /* Nothing matched. */ if (i == 12) return (0); tm->tm_mon = i; bp += len; break; case 'C': /* The century number. */ LEGAL_ALT(ALT_E); if (!(conv_num(&bp, &i, 0, 99))) return (0); if (split_year) { tm->tm_year = (tm->tm_year % 100) + (i * 100); } else { tm->tm_year = i * 100; split_year = 1; } break; case 'd': /* The day of month. */ case 'e': LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_mday, 1, 31))) return (0); break; case 'k': /* The hour (24-hour clock representation). */ LEGAL_ALT(0); /* FALLTHROUGH */ case 'H': LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_hour, 0, 23))) return (0); break; case 'l': /* The hour (12-hour clock representation). */ LEGAL_ALT(0); /* FALLTHROUGH */ case 'I': LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_hour, 1, 12))) return (0); if (tm->tm_hour == 12) tm->tm_hour = 0; break; case 'j': /* The day of year. */ LEGAL_ALT(0); if (!(conv_num(&bp, &i, 1, 366))) return (0); tm->tm_yday = i - 1; break; case 'M': /* The minute. */ LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_min, 0, 59))) return (0); break; case 'm': /* The month. */ LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &i, 1, 12))) return (0); tm->tm_mon = i - 1; break; case 'p': /* The locale's equivalent of AM/PM. */ LEGAL_ALT(0); /* AM? */ if (strcasecmp(_ctloc(am_pm[0]), bp) == 0) { if (tm->tm_hour > 11) return (0); bp += strlen(_ctloc(am_pm[0])); break; } /* PM? */ else if (strcasecmp(_ctloc(am_pm[1]), bp) == 0) { if (tm->tm_hour > 11) return (0); tm->tm_hour += 12; bp += strlen(_ctloc(am_pm[1])); break; } /* Nothing matched. */ return (0); case 'S': /* The seconds. */ LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_sec, 0, 61))) return (0); break; case 'U': /* The week of year, beginning on sunday. */ case 'W': /* The week of year, beginning on monday. */ LEGAL_ALT(ALT_O); /* * XXX This is bogus, as we can not assume any valid * information present in the tm structure at this * point to calculate a real value, so just check the * range for now. */ if (!(conv_num(&bp, &i, 0, 53))) return (0); break; case 'w': /* The day of week, beginning on sunday. */ LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &tm->tm_wday, 0, 6))) return (0); break; case 'Y': /* The year. */ LEGAL_ALT(ALT_E); if (!(conv_num(&bp, &i, 0, 9999))) return (0); tm->tm_year = i - TM_YEAR_BASE; break; case 'y': /* The year within 100 years of the epoch. */ LEGAL_ALT(ALT_E | ALT_O); if (!(conv_num(&bp, &i, 0, 99))) return (0); if (split_year) { tm->tm_year = ((tm->tm_year / 100) * 100) + i; break; } split_year = 1; if (i <= 68) tm->tm_year = i + 2000 - TM_YEAR_BASE; else tm->tm_year = i + 1900 - TM_YEAR_BASE; break; /* * Miscellaneous conversions. */ case 'n': /* Any kind of white-space. */ case 't': LEGAL_ALT(0); while (isspace(*bp)) bp++; break; default: /* Unknown/unsupported conversion. */ return (0); } } /* LINTED functional specification */ return ((char *)bp); } static int conv_num(buf, dest, llim, ulim) const char **buf; int *dest; int llim, ulim; { int result = 0; /* The limit also determines the number of valid digits. */ int rulim = ulim; if (**buf < '0' || **buf > '9') return (0); do { result *= 10; result += *(*buf)++ - '0'; rulim /= 10; } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9'); if (result < llim || result > ulim) return (0); *dest = result; return (1); } krb5-1.22.1/src/lib/krb5/krb/int-proto.h0000664000175000017500000003630215051422640017427 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/int-proto.h - Prototypes for libkrb5 internal functions */ /* * Copyright 1990,1991 the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef KRB5_INT_FUNC_PROTO__ #define KRB5_INT_FUNC_PROTO__ struct krb5int_fast_request_state; struct kdclist; typedef struct k5_response_items_st k5_response_items; typedef krb5_error_code (*get_as_key_fn)(krb5_context, krb5_principal, krb5_enctype, krb5_prompter_fct, void *prompter_data, krb5_data *salt, krb5_data *s2kparams, krb5_keyblock *as_key, void *gak_data, k5_response_items *ritems); krb5_error_code krb5int_tgtname(krb5_context context, const krb5_data *, const krb5_data *, krb5_principal *); krb5_error_code krb5int_libdefault_boolean(krb5_context, const krb5_data *, const char *, int *); krb5_error_code krb5int_libdefault_string(krb5_context context, const krb5_data *realm, const char *option, char **ret_value); krb5_error_code krb5_ser_authdata_init (krb5_context); krb5_error_code krb5_ser_address_init (krb5_context); krb5_error_code krb5_ser_authenticator_init (krb5_context); krb5_error_code krb5_ser_checksum_init (krb5_context); krb5_error_code krb5_ser_keyblock_init (krb5_context); krb5_error_code krb5_ser_principal_init (krb5_context); krb5_error_code krb5_ser_authdata_context_init (krb5_context); krb5_error_code krb5_preauth_supply_preauth_data(krb5_context context, krb5_get_init_creds_opt *opt, const char *attr, const char *value); krb5_error_code clpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code clpreauth_encrypted_timestamp_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code clpreauth_sam2_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code clpreauth_otp_initvt(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); krb5_error_code k5_get_cached_cred(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **creds_out); #define IS_TGS_PRINC(p) ((p)->length == 2 && \ data_eq_string((p)->data[0], KRB5_TGS_NAME)) typedef krb5_error_code (*k5_pacb_fn)(krb5_context context, krb5_keyblock *subkey, krb5_kdc_req *req, void *arg); krb5_error_code krb5_get_cred_via_tkt_ext(krb5_context context, krb5_creds *tkt, krb5_flags kdcoptions, krb5_address *const *address, krb5_pa_data **in_padata, krb5_creds *in_cred, k5_pacb_fn pacb_fn, void *pacb_data, krb5_pa_data ***out_padata, krb5_pa_data ***enc_padata, krb5_creds **out_cred, krb5_keyblock **out_subkey); krb5_error_code k5_generate_nonce(krb5_context context, int32_t *out); krb5_error_code k5_make_tgs_req(krb5_context context, struct krb5int_fast_request_state *, krb5_creds *tkt, krb5_flags kdcoptions, krb5_address *const *address, krb5_pa_data **in_padata, krb5_creds *in_cred, k5_pacb_fn pacb_fn, void *pacb_data, krb5_data *req_asn1_out, krb5_timestamp *timestamp_out, krb5_int32 *nonce_out, krb5_keyblock **subkey_out); krb5_error_code krb5int_process_tgs_reply(krb5_context context, struct krb5int_fast_request_state *, krb5_data *response_data, krb5_creds *tkt, krb5_flags kdcoptions, krb5_address *const *address, krb5_pa_data **in_padata, krb5_creds *in_cred, krb5_timestamp timestamp, krb5_int32 nonce, krb5_keyblock *subkey, krb5_pa_data ***out_padata, krb5_pa_data ***out_enc_padata, krb5_creds **out_cred); /* The subkey field is an output parameter; if a * tgs-rep is received then the subkey will be filled * in with the subkey needed to decrypt the TGS * response. Otherwise it will be set to null. */ krb5_error_code krb5int_decode_tgs_rep(krb5_context, struct krb5int_fast_request_state *, krb5_data *, const krb5_keyblock *, krb5_keyusage, krb5_kdc_rep ** ); krb5_error_code krb5int_validate_times(krb5_context, krb5_ticket_times *); krb5_error_code krb5int_copy_authdatum(krb5_context, const krb5_authdata *, krb5_authdata **); /* Set replay data fields in rdata and caller_rdata according to the flags in * authcon. */ krb5_error_code k5_privsafe_gen_rdata(krb5_context context, krb5_auth_context authcon, krb5_replay_data *rdata, krb5_replay_data *caller_rdata); /* * Set *local_out and *remote_out to addresses based on authcon. The resulting * pointers should not be freed, but addresses may be placed into *lstorage and * *rstorage which the caller must free, even on error. */ krb5_error_code k5_privsafe_gen_addrs(krb5_context context, krb5_auth_context authcon, krb5_address *lstorage, krb5_address *rstorage, krb5_address **local_out, krb5_address **remote_out); /* * If the DO_TIME flag is set in authcon, store a replay record in a memory * replay cache (initializing one if necessary). Either enc or cksum must be * non-null. If rdata is not null, also check that its timestamp is within * clock skew. */ krb5_error_code k5_privsafe_check_replay(krb5_context context, krb5_auth_context authcon, const krb5_replay_data *rdata, const krb5_enc_data *enc, const krb5_checksum *cksum); krb5_boolean k5_privsafe_check_seqnum(krb5_context ctx, krb5_auth_context ac, krb5_ui_4 in_seq); krb5_error_code k5_privsafe_check_addrs(krb5_context context, krb5_auth_context ac, krb5_address *msg_s_addr, krb5_address *msg_r_addr); krb5_error_code krb5int_mk_chpw_req(krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, const char *passwd, krb5_data *packet); krb5_error_code krb5int_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context, krb5_data *packet, int *result_code, krb5_data *result_data); krb5_error_code KRB5_CALLCONV krb5_chpw_result_code_string(krb5_context context, int result_code, char **result_codestr); krb5_error_code krb5int_mk_setpw_req(krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, krb5_principal targetprinc, const char *passwd, krb5_data *packet); void k5_ccselect_free_context(krb5_context context); krb5_error_code k5_init_creds_get(krb5_context context, krb5_init_creds_context ctx, krb5_boolean use_primary, struct kdclist *kdcs); krb5_error_code k5_init_creds_current_time(krb5_context context, krb5_init_creds_context ctx, krb5_boolean allow_unauth, krb5_timestamp *time_out, krb5_int32 *usec_out); krb5_error_code k5_preauth(krb5_context context, krb5_init_creds_context ctx, krb5_pa_data **in_padata, krb5_boolean must_preauth, krb5_pa_data ***padata_out, krb5_preauthtype *pa_type_out); krb5_error_code k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx, krb5_preauthtype pa_type, krb5_error *err, krb5_pa_data **err_padata, krb5_pa_data ***padata_out); void k5_init_preauth_context(krb5_context context); void k5_free_preauth_context(krb5_context context); krb5_error_code k5_preauth_note_failed(krb5_init_creds_context ctx, krb5_preauthtype pa_type); void k5_preauth_prepare_request(krb5_context context, krb5_get_init_creds_opt *opt, krb5_kdc_req *request); void k5_preauth_request_context_init(krb5_context context, krb5_init_creds_context ctx); void k5_preauth_request_context_fini(krb5_context context, krb5_init_creds_context ctx); krb5_error_code k5_preauth_check_context(krb5_context context, krb5_init_creds_context ctx); krb5_error_code k5_response_items_new(k5_response_items **ri_out); void k5_response_items_free(k5_response_items *ri); void k5_response_items_reset(k5_response_items *ri); krb5_boolean k5_response_items_empty(const k5_response_items *ri); const char * const * k5_response_items_list_questions(const k5_response_items *ri); krb5_error_code k5_response_items_ask_question(k5_response_items *ri, const char *question, const char *challenge); const char * k5_response_items_get_challenge(const k5_response_items *ri, const char *question); krb5_error_code k5_response_items_set_answer(k5_response_items *ri, const char *question, const char *answer); const char * k5_response_items_get_answer(const k5_response_items *ri, const char *question); /* Save code and its extended message (if any) in out. */ void k5_save_ctx_error(krb5_context ctx, krb5_error_code code, struct errinfo *out); /* Return the code from in and restore its extended message (if any). */ krb5_error_code k5_restore_ctx_error(krb5_context ctx, struct errinfo *in); krb5_error_code k5_encrypt_keyhelper(krb5_context context, krb5_key key, krb5_keyusage keyusage, const krb5_data *plain, krb5_enc_data *cipher); krb5_error_code k5_get_init_creds(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_prompter_fct prompter, void *prompter_data, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *options, get_as_key_fn gak, void *gak_data, krb5_kdc_rep **as_reply); /* * Make AS requests with the canonicalize flag set, stopping when we get a * message indicating which realm the client principal is in. Set *client_out * to a copy of client with the canonical realm. If subject_cert is non-null, * include PA_S4U_X509_USER pa-data with the subject certificate each request. * (See [MS-SFU] 3.1.5.1.1.1 and 3.1.5.1.1.2.) */ krb5_error_code k5_identify_realm(krb5_context context, krb5_principal client, const krb5_data *subject_cert, krb5_principal *client_out); krb5_error_code k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **opt, krb5_flags options, krb5_address *const *addrs, krb5_enctype *ktypes, krb5_preauthtype *pre_auth_types, krb5_creds *creds); krb5_error_code k5_copy_creds_contents(krb5_context, const krb5_creds *, krb5_creds *); krb5_error_code k5_build_conf_principals(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *name, krb5_creds *cred); krb5_error_code k5_generate_and_save_subkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock, krb5_enctype enctype); krb5_error_code k5_client_realm_path(krb5_context context, const krb5_data *client, const krb5_data *server, krb5_data **rpath_out); size_t k5_count_etypes(const krb5_enctype *list); krb5_error_code k5_copy_etypes(const krb5_enctype *old_list, krb5_enctype **new_list); krb5_ccache k5_gic_opt_get_in_ccache(krb5_get_init_creds_opt *opt); krb5_ccache k5_gic_opt_get_out_ccache(krb5_get_init_creds_opt *opt); const char * k5_gic_opt_get_fast_ccache_name(krb5_get_init_creds_opt *opt); krb5_flags k5_gic_opt_get_fast_flags(krb5_get_init_creds_opt *opt); void k5_gic_opt_get_expire_cb(krb5_get_init_creds_opt *opt, krb5_expire_callback_func *cb_out, void **data_out); void k5_gic_opt_get_responder(krb5_get_init_creds_opt *opt, krb5_responder_fn *responder_out, void **data_out); /* * Make a shallow copy of opt, with all pointer fields aliased, or NULL on an * out-of-memory failure. The caller must free the result with free, and must * not use it with the following functions: * * krb5_get_init_creds_opt_free * krb5_get_init_creds_opt_set_pa * krb5_get_init_creds_opt_set_fast_ccache * krb5_get_init_creds_opt_set_fast_ccache_name */ krb5_get_init_creds_opt * k5_gic_opt_shallow_copy(krb5_get_init_creds_opt *opt); /* Return -1 if no PAC request option was specified, or the option value as a * boolean (0 or 1). */ int k5_gic_opt_pac_request(krb5_get_init_creds_opt *opt); krb5_error_code k5_get_etype_info(krb5_context context, krb5_init_creds_context ctx, krb5_pa_data **padata); /* * Make an S4U2Proxy (constrained delegation) request. in_creds->client is the * impersonator principal, and in_creds->second_ticket is the evidence * ticket. */ krb5_error_code k5_get_proxy_cred_from_kdc(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **out_creds); /* Return true if mprinc will match any hostname in a host-based principal name * (possibly due to ignore_acceptor_hostname) with krb5_sname_match(). */ krb5_boolean k5_sname_wildcard_host(krb5_context context, krb5_const_principal mprinc); /* Guess the appropriate name-type for a principal based on the name. */ krb5_int32 k5_infer_principal_type(krb5_principal princ); krb5_boolean k5_pac_should_have_ticket_signature(krb5_const_principal sprinc); #endif /* KRB5_INT_FUNC_PROTO__ */ krb5-1.22.1/src/lib/krb5/krb/t_valid_times.c0000664000175000017500000000771315051422640020316 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/t_valid_times.c - test program for krb5int_validate_times() */ /* * Copyright (C) 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "k5-int.h" #include "int-proto.h" #define BOUNDARY (uint32_t)INT32_MIN int main(void) { krb5_error_code ret; krb5_context context; krb5_ticket_times times = { 0, 0, 0, 0 }; ret = krb5_init_context(&context); assert(!ret); /* Current time is within authtime and end time. */ ret = krb5_set_debugging_time(context, 1000, 0); times.authtime = 500; times.endtime = 1500; ret = krb5int_validate_times(context, ×); assert(!ret); /* Current time is before starttime, but within clock skew. */ times.starttime = 1100; ret = krb5int_validate_times(context, ×); assert(!ret); /* Current time is before starttime by more than clock skew. */ times.starttime = 1400; ret = krb5int_validate_times(context, ×); assert(ret == KRB5KRB_AP_ERR_TKT_NYV); /* Current time is after end time, but within clock skew. */ times.starttime = 500; times.endtime = 800; ret = krb5int_validate_times(context, ×); assert(!ret); /* Current time is after end time by more than clock skew. */ times.endtime = 600; ret = krb5int_validate_times(context, ×); assert(ret == KRB5KRB_AP_ERR_TKT_EXPIRED); /* Current time is within starttime and endtime; current time and * endtime are across y2038 boundary. */ ret = krb5_set_debugging_time(context, BOUNDARY - 100, 0); assert(!ret); times.starttime = BOUNDARY - 200; times.endtime = BOUNDARY + 500; ret = krb5int_validate_times(context, ×); assert(!ret); /* Current time is before starttime, but by less than clock skew. */ times.starttime = BOUNDARY + 100; ret = krb5int_validate_times(context, ×); assert(!ret); /* Current time is before starttime by more than clock skew. */ times.starttime = BOUNDARY + 250; ret = krb5int_validate_times(context, ×); assert(ret == KRB5KRB_AP_ERR_TKT_NYV); /* Current time is after endtime, but by less than clock skew. */ ret = krb5_set_debugging_time(context, BOUNDARY + 100, 0); assert(!ret); times.starttime = BOUNDARY - 1000; times.endtime = BOUNDARY - 100; ret = krb5int_validate_times(context, ×); assert(!ret); /* Current time is after endtime by more than clock skew. */ times.endtime = BOUNDARY - 300; ret = krb5int_validate_times(context, ×); assert(ret == KRB5KRB_AP_ERR_TKT_EXPIRED); krb5_free_context(context); return 0; } krb5-1.22.1/src/lib/krb5/krb/t_expire_warn.c0000664000175000017500000000740515051422640020337 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/krb5/krb/t_expire_warn.c - Test harness for password expiry warnings */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #include "k5-int.h" static int exp_dummy, prompt_dummy; static void check(krb5_error_code code) { if (code != 0) abort(); } static krb5_error_code prompter_cb(krb5_context ctx, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]) { /* Not expecting any actual prompts, only banners. */ assert(num_prompts == 0); assert(banner != NULL); printf("Prompter: %s\n", banner); return 0; } static void expire_cb(krb5_context ctx, void *data, krb5_timestamp password_expiration, krb5_timestamp account_expiration, krb5_boolean is_last_req) { printf("password_expiration = %ld\n", (long)password_expiration); printf("account_expiration = %ld\n", (long)account_expiration); printf("is_last_req = %d\n", (int)is_last_req); } int main(int argc, char **argv) { krb5_context ctx; krb5_init_creds_context icctx; krb5_get_init_creds_opt *opt; char *user, *password, *service = NULL; krb5_boolean use_cb, stepwise; krb5_principal client; krb5_creds creds; if (argc < 5) { fprintf(stderr, "Usage: %s username password {1|0} {1|0} [service]\n", argv[0]); return 1; } user = argv[1]; password = argv[2]; use_cb = atoi(argv[3]); stepwise = atoi(argv[4]); if (argc >= 6) service = argv[5]; check(krb5_init_context(&ctx)); check(krb5_get_init_creds_opt_alloc(ctx, &opt)); if (use_cb) { check(krb5_get_init_creds_opt_set_expire_callback(ctx, opt, expire_cb, &exp_dummy)); } check(krb5_parse_name(ctx, user, &client)); if (stepwise) { check(krb5_init_creds_init(ctx, client, prompter_cb, &prompt_dummy, 0, opt, &icctx)); krb5_init_creds_set_password(ctx, icctx, password); if (service != NULL) check(krb5_init_creds_set_service(ctx, icctx, service)); check(krb5_init_creds_get(ctx, icctx)); krb5_init_creds_free(ctx, icctx); } else { check(krb5_get_init_creds_password(ctx, &creds, client, password, prompter_cb, &prompt_dummy, 0, service, opt)); krb5_free_cred_contents(ctx, &creds); } krb5_get_init_creds_opt_free(ctx, opt); krb5_free_principal(ctx, client); krb5_free_context(ctx); return 0; } krb5-1.22.1/src/lib/krb5/krb/t_kerb.c0000664000175000017500000001546215051422640016741 0ustar ghudsonghudson/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * This driver routine is used to test many of the standard Kerberos library * routines. */ #include "autoconf.h" #include "k5-int.h" #include #include "com_err.h" void test_string_to_timestamp (krb5_context, char *); void test_425_conv_principal (krb5_context, char *, char*, char *); void test_524_conv_principal (krb5_context, char *); void test_parse_name (krb5_context, const char *); void test_name_type (krb5_context, const char *); void test_set_realm (krb5_context, const char *, const char *); void usage (char *); void test_string_to_timestamp(krb5_context ctx, char *ktime) { krb5_timestamp timestamp; time_t t; krb5_error_code retval; retval = krb5_string_to_timestamp(ktime, ×tamp); if (retval) { com_err("krb5_string_to_timestamp", retval, 0); return; } t = ts2tt(timestamp); printf("Parsed time was %s", ctime(&t)); } void test_425_conv_principal(krb5_context ctx, char *name, char *inst, char *realm) { krb5_error_code retval; krb5_principal princ; char *out_name; retval = krb5_425_conv_principal(ctx, name, inst, realm, &princ); if (retval) { com_err("krb5_425_conv_principal", retval, 0); return; } retval = krb5_unparse_name(ctx, princ, &out_name); if (retval) { com_err("krb5_unparse_name", retval, 0); return; } printf("425_converted principal(%s, %s, %s): '%s'\n", name, inst, realm, out_name); free(out_name); krb5_free_principal(ctx, princ); } void test_524_conv_principal(krb5_context ctx, char *name) { krb5_principal princ = 0; krb5_error_code retval; #define ANAME_SZ 40 #define INST_SZ 40 #define REALM_SZ 40 char aname[ANAME_SZ+1], inst[INST_SZ+1], realm[REALM_SZ+1]; aname[ANAME_SZ] = inst[INST_SZ] = realm[REALM_SZ] = 0; retval = krb5_parse_name(ctx, name, &princ); if (retval) { com_err("krb5_parse_name", retval, 0); goto fail; } retval = krb5_524_conv_principal(ctx, princ, aname, inst, realm); if (retval) { com_err("krb5_524_conv_principal", retval, 0); goto fail; } printf("524_converted_principal(%s): '%s' '%s' '%s'\n", name, aname, inst, realm); fail: if (princ) krb5_free_principal (ctx, princ); } void test_parse_name(krb5_context ctx, const char *name) { krb5_error_code retval; krb5_principal princ = 0, princ2 = 0; char *outname = 0; retval = krb5_parse_name(ctx, name, &princ); if (retval) { com_err("krb5_parse_name", retval, 0); goto fail; } retval = krb5_copy_principal(ctx, princ, &princ2); if (retval) { com_err("krb5_copy_principal", retval, 0); goto fail; } retval = krb5_unparse_name(ctx, princ2, &outname); if (retval) { com_err("krb5_unparse_name", retval, 0); goto fail; } printf("parsed (and unparsed) principal(%s): ", name); if (strcmp(name, outname) == 0) printf("MATCH\n"); else printf("'%s'\n", outname); fail: if (outname) free(outname); if (princ) krb5_free_principal(ctx, princ); if (princ2) krb5_free_principal(ctx, princ2); } void test_name_type(krb5_context ctx, const char *name) { krb5_error_code retval; krb5_principal princ = 0; retval = krb5_parse_name(ctx, name, &princ); if (retval) { com_err("krb5_parse_name", retval, 0); return; } printf("name_type principal(%s): %d\n", name, krb5_princ_type(ctx, princ)); krb5_free_principal(ctx, princ); } void test_set_realm(krb5_context ctx, const char *name, const char *realm) { krb5_error_code retval; krb5_principal princ = 0; char *outname = 0; retval = krb5_parse_name(ctx, name, &princ); if (retval) { com_err("krb5_parse_name", retval, 0); goto fail; } retval = krb5_set_principal_realm(ctx, princ, realm); if (retval) { com_err("krb5_set_principal_realm", retval, 0); goto fail; } retval = krb5_unparse_name(ctx, princ, &outname); if (retval) { com_err("krb5_unparse_name", retval, 0); goto fail; } printf("old principal: %s, modified principal: %s\n", name, outname); fail: if (outname) free(outname); if (princ) krb5_free_principal(ctx, princ); } void usage(char *progname) { fprintf(stderr, "%s: Usage: %s 425_conv_principal \n", progname, progname); fprintf(stderr, "\t%s 524_conv_principal \n", progname); fprintf(stderr, "\t%s parse_name \n", progname); fprintf(stderr, "\t%s name_type \n", progname); fprintf(stderr, "\t%s set_realm \n", progname); fprintf(stderr, "\t%s string_to_timestamp

>«½*ŠžÀM¥Ü‘3JÕºÕBOÆÑ3¹)ž-¼¦ 1ŽÇf;Þ˜¢Œ÷g~&ÈGÝ`"i0j_‚uü:ržíÌPèHçÙø˜ó<dHê­Òÿ%vëìÖ3°[îÚXñîøŽ˜ŠJ™üE&‘©ºÔ2ôë¬Ð?ЏQE ¼– Ýhè׎°Ïõà·[ ®ŸOd… së¹þ£ÄÚÃÌ×z±Ý7¸s˜¨czŽù€“þ¤ t¦GO¼Ñ†pHãËß pCÞCr =Ùæ Ëh ` .Ç*¸†1³uÙéGCC³7K‘sæxgL`&âuF(ÐÃÌÌÚ¹Õ¨ÆÍG³²P¼2$PÑ­÷zÈZd~±P¤ãñU/ G›PçNeFs¡°Óž ‰/³`%ði„¡28=6ƒÓc2¸ƒÄ±¥õó»š2¾Çi_í½YÙ’úÓBÒ† üô®Ï±}žÓÛ·kõÈÃÖ²mêÜÚÔ°µ)"›ÍRö$㣾hUÚ}ÃTF«RŸ9;%ƒuÇ7‰&å4E5>3”ìÕŸ³L¹̇ÁÆ'yÜctDûš¥Û“Äò?ëj4; endstream endobj 2164 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚ=OÃ0†wÿŠm‰˜³ãx,ŠÊÔ[é6¦Dj’’¤þ=n%˜îSwïû ìaN®<¹¼UwFð/`%XUpårð¬è=“š†~ún`™´1¡iÕÔm=Œ=Ë4-ǺkÓl~¬«p‘ò§°åR!¸”\°µ_OÞˆˆïDz§¸E Û†¬ÖUì/yî xÿÞj@™"Æ=,É#Á“ôsüuK+.Í¿Oýé^EB&ó1Ê7ÒYzýZ˜¦#›hœ> stream xÚÝZ[oÛ:~ϯÐÃ>Ø@Íò¦ »(°==i›ÓÝ6§ñè) EVbmmË•ädóïw†CQ»Þt[Áö!$‡—á\øÍŒ\\ÙªÈ7 õÓ7°ÎpGïêbsíf©©§"œ4U dNòЍÛ*Ow3Tè}&3¡3¿?²(Q­&ë<Ã3–馨×DªwD¢QZ[»s&9˜‘©XÃ_DAN»GüðìE=%ÁÔèöçoÏÞÍéHçö#›©ˆq!Ûõeõƒì‹Áþî´÷óóc¬…a`Ìv1#Ì—¹õ ím Ê«¡²3cµ²fâŸ\òžõ¼ª‹ÍÇeU³© q™ ‰ 48ÆM‘åÖj3a ¼Y34Þ–V›¬Ø¦+¸ òHë‘–0ðHœAÄ™*ÿ:|²+ªœ&¶)ž¢sîVÔO&ã›ãÂîæ´¦pô²Zän11·Î4Ë´!JÝ“• “/6‡Üuÿ.¼» oÐñÓÕ.§¡Swêà`2ĉ;¸çâÔxí¶Xg/ë¼ÝÙÛ`_&v,Øóëž „×ø«_Yµ,ÛΦ¤Þã¬Î›Ñ…Á Z‘cf”"‘çSÃ'¸OJxïxûz€ÉM`ÍmÑ,iÆ=1Kµj:¾ 'OˆŠR‘ 4ÝsZA‚Ã Ž”²å›­v‹öbãËÐðvi•iÏI‹û‚’ˆÌ”D.WÓèd>ãÉ+Sd‰óNèØÊèRE±‘!R½§ÈÁ¸ö0³ýVm>wrìÇ’X0µëɊΓÒË•ãUl~ ­4„ÂP´L¾,2–¹:Š–!ÛAÖX3éï¡26©c¦¥al8°å½ÈX`ÄÒ¹UŒÞD¡°¥ßmÝÄ"GG[€3 ·Æ1ù0LÕÛ<+®îÜtÒèŒX0{,!ðf,›íñDÄtç;‚,¼Ä„¯´n/_gnêÒ¢¯½ß03™ÄýfyWˆSð¦”Á>!z]3e"Š‘aÜó:âIR3ÃãΓìYŽx¢„Å¡`¢‚²"l/Ý2@ƒÚ¦:´–Ú6œÀ|»~NüI 3 öc Q†aÒ!Á/|Ð-¤‰&ñ¯B™P²%³ƒÏx“~‚y¥ö÷½ehZÊå®q^sÃb)‡6²Ð®"çÛЊâ&ËÑ¢¾¦a؈~yHЇqÏ`G¥™œ]ÑÔÝTƒ]w4¸-ê%ílB†SbÞrKÃrãN,Ývà|ƒKòª½íàuönß^'Ͳ| .šI…QÂGö`°Þ­šb»ÊçµÛ™CÆCéô8Ð×Û4ûFDö`*šä(Þ¿QƒéØ>q¹>MB„[­©›•»Õ‚ºVTK$fÆ99´äœF9›Bg/à›aŒ…%};J:»j€rK¤»P =Ÿ@£)¶Mý]Ž'`(+jÊ!6ÑiÕÚ4žVlºÌéëЉGàîVëúÓÑxhû|¿Þ]Öy†:|æn#d¨M0níOÁÍ æm+Þ(aP§B+mq| ¨Þ•‘æ´l4ÌÖ¢B8V, CK^ÁB·»u¹ µ’’=‚ ²þtáþÙíž3F±éN‰[Öqô¤ ŽôƒUËÐSxwïØe0P°šûõÔp+Yö/ßUð{ÎcBt:l^{/6‰ûû½î¹\^:ui¦A8iõº¯¯–@úòÓ¡S´F, £¤w–Hzl`@Úéë…pÛP!÷UÅÿòŽøè{WÛ¶ªœEP hñyi?*ÙFÑ %€Ù5˜í›©;\P£âÛ?ö^ \'ø8 CŸàÄkú¨²ï¹Ë‰¢öK•ƒÀAbk¾QèÆJÓ…^y:®Ö¹+—ù¸ZïÕ¢¡áø;ªåŸ ‡PLÈ‚e|. ,Á…â{páIø üÀ? OáÝq¼c÷PpøX廚‡‡CàP&c8T¼ÇFq§¾^P I ‡pÞ£€C(Ô4»%±ûXÿ—©Å¯/ö;õ!?«±Áþ²¬›§ËâzÉn×Mîæqm¨Ò¡ O î§u} õ­»*ÝX'?µ¬ÿööÃ/óÓ‹9{ùþÏΆÞí²ÜCµ6wŸº çsZ¤bj¾°î#DYËË&mÓT—Â?ÏíÊÖ"Õ|ÿÒÿ\`…š‚•|p`¶ûÀ£Åx´ÜO§åþy ïŽã»‡ÖÇ*ßcVeÀªùXµì±i§¯dÇ[`UæQ+>/ü‰ô[È*c¨T“hˆ¬˜mRwöµ„Ü|Fèú\,ªš»ç¯Îþ~úìéúîi–W Ûæë'8ø’ßa¿ÃÊC5wËç>8‚Ù¶^9„âÑáÏ©G :¦Ã/wÍ3¿«Ý¶-F ÕÕâ poÊæç‚¨Ð!¨H=8ˆFêÈDád ÖƒŒ'á3òÿ˜<…wÇñŽÝCèc•ï±ë‘€h¤Ç E=60 íôõ‚jÐ-ˆFêQ€¨ÐSáåPlèø[ ú-<’aîå–?BqIûÓ'v¶åªÈîÚ$ù_y†ÿ£Í˜óÚ r»,0ÓÄîuûE”öŠö'ûVä,8Ó‘ø^?ôS\{R®__\ ®¾8?%®ôÞaòv»rß êÑèÅ?´7÷ø´P·)rUî®—£|wÎÆK7éºü6ŸbÆÿÕ(ÔLFñøáS¾ßˆ ¥bÊæ*LIZ\ŒyþuÕ0 endstream endobj 2178 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚÍN!…÷<Å]Bâ P`©F›Ô•Ê®éb,hI:3:Cãë C›hâÂÕýͽç| ÞÁÝ:tý 9Xj[Ñ‚{-@KC¥]ó°ÅD(¦×03i„6ø†p…}‡8§‰4 w)ŽC­Oч«š?‡cèæP N… œìÜÝ;ô‰x~Ï€×w’j¦aߣíŽÏý 0º²¾–­dkr< zBì,ýÝR’Šöß§þt/³N.ªyÎD‘Ï Çw‡îƒ(œH¡qöd(iZi †Oé†÷?hÄÁ—ºLÇ…Ô¼¸(Ï ¾ÛÞ[o endstream endobj 2183 0 obj << /Length 2597 /Filter /FlateDecode >> stream xÚ­ÛnÛ:ò=_¡G¨Þ%í>uÛ´'ç’tŸiP(’Òµ%W²›èÇïC]C§I·/‘4Îs¥Cƒ ÞQ÷ü|ÄàID<ˆ%Jè Û]]Ó øï%I¢ƒ{‹µ ¤Žá¹.þ}ô¯ÕÑñÉ‚„$šë`uÈ„‘˜²@'œ0ª‚U\…¯KþöòÝêäbq½úÝna’©¹Ù³äð.<IÃ=g§g'«““3³áèd5S«ˆDB>WÌOÁc"h&ˆDŽ/_ÿuzvz¹Páêâå"¦áêôül±äQ¾»èùÛ‹—]Zy:ÛQÂ@mJ¸ðWh4°ðxñö”SÚr\jA"í´d aSŠÏ§|µT”†ŸÒ|SVÿ'-´#‰RÖJ4X øŠGÒþ*y/R…ÿû2ž¿»<öø l¼Š¢hçOƒ®ÇoD<šè8"ÚbL( "XÔ!,Ï=4@}ª“廇X$á=3 ˆ¢¸Ã¸^,EÂ¼ÒØh=©Æ¡è©81ëi5 AÃ"]o®œDJu(Û¦¬²r›®ý&‹>]×Ï~®±è¹~^€kì‹HÒð›Oa®ù@a/oAbÅzÞ™ßÎQÔËÒÌXú®øP¥›ÂÃ[&̽¨×ß}\c¢ùàkŸ|~PõtÝù§p{»~*¾íÒŸ±4¡Úõõ÷ ì °Þ~â°ï}rK@é ¾MÛöÞ˜¼¶.žû<-&Lñç3oý§M‡Nó¥Á –RIåe‰)!Ó|h~±á×øüA‘åÕ?<,Áþqoº-¨i2ßÎçaZ'%HÑð*«7›´Êñ+mL…[T¸ §kM–:†”$@µˆ$ é(’uyCЬRϽ³ñ{§<üYé‹ËÄËŠKÏ^ ê<û©ìõSþxîbDröó¹ëiÚæ8Óžs~s cA!W’?WÕ¦‚÷gZT™Ï‰M+×ûŽ/ Â e¶M×BA 9″/…^E84+j°ÝÆ_ì#ªŸ} _ýVI†›ß|€åbÔwœ(&ælŸá¿ ¿[ŠX^/}JÚ<þkÚ¼×'—¯.NßÙVzÚàM âoð` à!Z^&Ù lTà’³Ür]VRV;}p· 0Xš-.ìj÷¼s˜˜S*𛢩[$ûå8~ekÎaפ»²vµß I„8Á£pôl¬[”mS/„ ¿”¹ãRèk³Õ&£ó¸Îjµ+­nBÈðv_e†eº.weÑþ ‘B©¿çå{*DÑ@ô¸µ+»»t‡©ÁpWSd;'ƒÅI3°L[ô{±?^¿r;Rh'Ò¶xŸJ…÷wåÚIБAß‚­¡_úôº]H[ÕÍYl xÖ°ÁÔ}ïÛ²úˆþA8EРkt°9Ðúò$ü‘<´A¶ºZ óÇüNHx•££¤O¾š³ËŠí¥K”…ݮˬlÈYXÕ»"wŠQÕû&"°jé(€“âË6ýhøu_®×Hjß:Ð{Ê)ZÞÂŒëšgSÜIluA°m^˜ DCw†Öw±|<š™ÞÅìiÕÏj5„,<Ö„¦£ƒƒe xÙ¤&´ªÔúA«oqaG–¤µ„«¾í ]§§€tîðjcÒ¢CÀ€xëLù¥ÌóO <Œ3#Vz³.ZŸÛ½§ŠŽÐ±#=®éƒ8⮬ÛË,»³4ïñàßÏÖ%'¾ï1Zcª±Y³'+éìe£yWŒW"G5G4t{\ïD˜*m°¦ft•gâĉ r{‘Åñ¡Yk‡ê]7‚Ð'MlêJŽ®½&ùíürå uMú2iŽàâÁ×C@72ô]‘ÔЩÓÓ’ê•â&×.áÏÛ.H™¥IÀ½«1UÛ¾ÈBŒËN¨tG °Þþ.è3K-Yx:Ý%¬)lÎßv%£ôÔÍ( ìmüp ¥ªÚA™ª‘"<Åøúë—†ð„ºrÛm´që/­yÂÌÔFEˆéë8œ°šOÄóK &z¯)ûa¦R½uµ¸•-ÂÚm‘¹Spa]²=ÐV»}6ºrg—Ö¸HHÏŒ: 0§cëºìîÁr“á îÏçù˜K~À"LsBGcãÖß.rÕ£¤Uî¥C’ˆ?>ö›Ž½'ƒækQ li$í 1ÒÌšôö›Þ9½»Ôd0f)XÎS0ba˜UËLÔ65²e¬“‰±]ã$–›Î+Ù@äÍÔ30Š_30žÛYñÒKÌ󫀂¯éõSLg×OŒ ×O|¸~:40Id2+7·Þ{ˆÞ˜?énKï:Óù¹å©ûµ;õ±Ë™~¨’Ç~1·{’ÇÓ®¶«`Sƒ˜«±áÒÜBªqkyÐ*‚(=í%&£kÎG®Þ$xÁpƒnûcñ Öhê©áBóÑô™tã“Ù½Ý}QžˆŸ$Dê¾älŽa4¿ÍÍ„rc±?ËÀ]A30×m›í6%íÚpZè×yœL]lâBÄaÖwYVeÚIC@Äõ~L_ćÚ19ñ¿/»ß`§zÃa H…ÍG_ʦ®68÷ô\¦fìrb™ud$3Õ¸ãêLã ÏúÆô¾¶1‡/[ìûíý¾Ì-Yâñ€`°?›Ž££å¡Üø Ïm?›+‘Ç£…ÃÔO£iùÅFíû÷;fIÔÄ&Óia¶nÁ3/2ç1æRÁ®Ü¹ÝX–¨>Û-<6#‚½`²VQx ¾ŽÑ Žæst½ÒK2±M5dIxZulm§ o6œu%’ƳDd™ÍgÏy‰Ãàs5îaàñdü‹ԶݱùsàŽZà 9àEÓémŸ.—K—A«®¯š›^ÑñâJ©u·.ñúw:¾m^ú.¤a¾äÃÆýEO³úQZ÷‰9±Ÿ}š®|ê¿óPJg4ÿï‘ÄOü' ÅP¹$'Œ¹jÁ¨˜óü¬Ûlù endstream endobj 2192 0 obj << /Length 2998 /Filter /FlateDecode >> stream xÚÅZIwÛ8¾ûWè6Ô{C—žËx²µ;´;VŸ’S¤BRq»ýT¡p-;Îa.XÄRU¨å«¢½ÙÍÌ›½;ûïòìåÛП¥nÑl¹™ÅÁ,7LÙl¹ž}vÞÏîÈz%몙/‚8qÎç>wÖ»¼Ì›¶ž/¸#Ú¼*éÝ»C¾–/hüIR4’|7\þuùÛÙ›åÙ·3Ž÷f>º±ϲÝÙç¯Þl ôßfžËÒdv§fífa”Ào1»:ûóÌÓ¬{}"6Á÷\Å$¢Ås_¾M¼Þ¤à°šq+ï[±RÜ™m_¾eIoºÏ]î³…ï»)ç´ê/NmEý™±›&ÁñΣ Ò±žÖV &î9k™JϹ߷Di·’ï_¿¢A-›}U6Ò/cÎr›7ô"% ª²À[»§§•ÞàÐÈ5îòvÛíN"ô„ÜYj˜[ÜNðŠÓØL©öhîHƒƒM DŽütbÚ¼å)­¡›‚e ´þIä·¹Ém±Eù#ß%˜!Ýíªƒ&íë*“M“—7¨­(r–°Ž;wsÆŠ¦´÷{©gW›©kÉË,ß‹ÂXK4‡ý¾ÂÀŒ\ë£ÞÎa¢ÂŒÍ¡°wS'¼Ç鲞‡ÜY N@¹•‚k1;YU~ñXxs@ÈrùþâãÅ’Æè‹ø«,‡±ˆ,)¢\Ó ¿~âúýÈåahîv ®Þ^‹2Ceo«º™0‡(vCß7Kò1 Y‘˲E‰ÿ…6ténà%èé1œå†I4«Á ŽˆŸ”)õ]Œ'.·®s[¯¸ mNKÝ(´ìÁñ$Ï‘šÏC£ùœö‡K xÁxp!dºc·À‰lè°µk§Ã‘ Ÿ¡I -Iq0ØÌCmDž³Ó¬ ÎW :ÅÿçÓ›óß?LðÅBP™õè/÷„æKîöíýÕb7`¥(*tž;¼KŒ'øf¥LyÀyYaÑä7ú²¼NöZŠB‰*M}7‰ÙP·x*0é£+…±sŽÉ¹³—ZyÛR0ãöð€‡&Xr4ù4¢˜È<Hmž¡ÏÝ*Çki‡»ü”öÕ[Õ²=Щ%¹6ðsN¯ v§Ù^”Ú«Ú<ñhMÌ›)¿Æ–^€‚ªÌšpRåBâ¥ü½¯(Æ'S'q ÙY¿ÞêPÊ6G À'Årÿµv\‡Îêб¬Úéiw¬ÊB–ô¢¡Z—ë)» ñB_ìˆÄ>Øä:0÷²Ž5c˜À—A5“ÎÀ¢—Šr2BC_Ù:Ÿ°®,ãE*+DÒðFˆÖ¹€‰z¾±ÂiêôF¥[bJ”òÐè‘ S%Éq"ÈÀ‰?4–Zî ‘)`aç&#qllÌÚx0¯¡ùÊ$à·¶pV€Ë¢±Øì˘p¢Nd12®¡ îÕ6Ô£>¬Ÿ&ÙØs&œ£‚ˆ ‡Gô‘G6 }L<6šCQ”‡@ҿ΄ò)Ê"EŒ´Ñ‘"ÃÞal|3‡Îˆ™›Æ6ËTž—ê«€AVÛm4APîV˜ÑW™oô‚›mu(ÖúUU¶9>ý^Çßïy¦WÅP u¡Ðï#Ì!úMܸ‡’Ö/Õß q!ÿ½éèîë©á¹„á¾ç¯?\|üõ«åÄÞ @ÝõãÝVÖSפnìÛ’áÔžC›EÆò>€›ºÚM˜~ùõ‚F¢Ôe]ÕR×_¹.ÙòÒ<넘4µÀUÕB—yºrë9èDZ»©8Æ\ŸÙ8¶M£¸ Öî'×ïÆñÓÂWâ2N×SéØsÓ®æÎKÒŸë>öˆÐt’BÉFä.šàœR*<‘*žÔôKXsJ¸1Ó ½V‰4¤@‰˜§¥W;a$;5À6‘‘ ö¯ ¶ªô0§&/—ïTajc娚o”ók ìˆö=£Yº|¥‡"§é?`"6‘oS&ð!°ü·ƒ4yÊ8@Ž¡m\RH­=ÂÀ};w&‚ößX×jUi†#º–¼}†c¬Ú³R¯W*Àž–˜¾²‚4#u°ÆëÞ<Ô¼Y‹V¬ÄD󦋅0©2{ëhšÙïû=Ó/²üþzqçürx =Æ>ω,Ídß,J¬Ó«€|ÝK?ªƒq\@óÈõ:¤óù—‰}#7b6o+Xˆàab/àÐë Þ¯§.o…P.$O½?›^¼qFÕm³mNQšoûó pÂ`ŽÀ){ŽÁî~´v±1­= —–+·¨2Q¼°QdgÚ‰‹ö%Ù‹ÐqIO@•áú±»gðP´¬-+&ªÜJî'NÑhEâe<Ë>U÷ ×Þ”«s—ùÙÉ2›2¦Ðe‰5»)»d°‰(0I?íw—|ðÔáðèŸ4Õ¸*•íÓ÷‚,”´0} ;ð"°¹Aϯèw¥—éÎ/Ìë®È¢4é:Ì4q-†²Bèöf{òçºxÑe *ïñ¯‘‹‘\⻺ aØAø¼ü9¶`dyº]g·cÈ£‰Y1TpO}9¹ Pi4ùªÐWôõ, À³4Ñ#ŠF>r„?~4pènLÖ}úqe‚Ùùì¯å¯×ï®®0œ_^hW>`Ž(-º¼ŽÌ¤úNÑb´g¸õÇ•æê5PëÒF:¥Ñb%4Ú$Îÿ‡\O7R/íðȵ¨ošGIúô”6 ìƒeZVUÜv p£ ºõÖkMfÌ:Å ²É¸-Ö¡²éi­\áå´B¯S¹ƒùa¯YgûNHö]?Ä–ƒBvC$ÅprVív"E^ê‰TËjl¨VàF¥9$ÛfZCzè0m¸PWµŒ¢¢ÞN¡;Œ˜– 9UW¡ß0 Û„_¶á—ô®@UvÐט&`ó”FÊoñ×ôÃèÑLÌËV–ku)a? ÀC£?8æûVO&®øØvV/õÛ5“5¨ÓRÜ“r|h» ™:´ ”ÓúËúè€Wçɵ(º/ž`vÍ/cŸ‹G­a6úºø%ð½SΔ¸adïÏq12´"YO* ºé¾?ô«­, ü²¾?SôS-ˆ»ç tQ 2eJ¥‘©´"Ìø&õ‚n@ÝAÕ)nTi×èµF[èæp!þÎ:oÈwkúÔ9¹Övdõ@«í^}XPHŽ{Ò¥oµÌÚé1àb ”e‘Åm7W(\ïkÓ[ŸèËEnà÷Z}>…¥¥Ç=ó!È Uûh>§¯s0Ý@@k]?ý2ƒg\æ+údÛ¿Ë>º(p'\¬Mãž0]ªÍ‚…J)NmËr±éºEÙT:€"¬=dCzÿíï¥ù~Iå/訊pþ¨¾ó¦9yÌY¦ ˆíÉÓê<À~ÉÏxÓÒø¶éH j™öp$‡a¼¬ÊÅ?²®¬ú‡¡bªBØ%/N%Îåä§j?ˆkñ«iüŒ;|¼ûÆaû7}ðiŠY0È “ùŽÊNÏm¹ý…]žÈ)ð^’ÈdƒçØä˜~LZ¥Íˆ¢[_êÆ#ݺ²R<+õãBkz@”˜qh§¬bî¢Ó€Ôƒ:õ¢à1öšiý^N&Ê.ý'ŽI{€[VyÙóêî_tÄÃf’»Š„ll>Âw}KÿÝ zòÿ`MþÛX¸¾¯C›ï…êÖ“Àyµû9V?º‘‚ÿ –B\ˆÂôä¿’á¢íš1ëÿáŽ¸Ý endstream endobj 2198 0 obj << /Length 1971 /Filter /FlateDecode >> stream xÚÅÛrÓ8ô½_áG‡!Â’ï»Ãlå¶´Ì>°LG±ÕÆSǶÓ_¿çèHŽíšl¹îK,Iç~“â9Žç<9zxztïqÀ”¥‘ˆœÓsÇç KâÔ‰ƒ„©ïœæÎ;÷Ï…]Õ¬TS·‹¥ˆ÷Á‚‡n¾)ª¢íšÅ2teWÔ­=Ù¹ºKã7ªT²U4áLÆïOŸ=:=úpÄÏáN,€\Àb/v²ÍÑ»÷ž“ü™ã1?Mœk½kãQßÒ99úëÈ3ü÷_Æ}‰ÈÇSwX¸|³—˜s–†¡@‘‘<÷˜çÇ$-OgfóÛé8ï–¡ç¹Ç ?e%ž{ºH`ôpá{G¤W¯OŸ¾zy2"uﱟ ìá9KÒx;–\‘BCÏ­·¨õ–&™¬h°2«»Vå4êj³¹¹ÂÕ ÄÅ_ÏsÑzn°/Û­ÊŠ¡à Cá]ŠêÃ)2ºÃÓ8»^ÚÑ`PÈK³‚@f˜ÆÖ´¶5䪬ØÊ¼<ðR÷t]´´LßЉ†1A++µ–ÞWhô„)0îj×Yö,Š‚* ǰœt휔6zeYê¾6ñ^o6 Žq‘¢R·‹q먒>ïòEbûž­ê:ЉòÇÈVÑw´¡¨ºNd6è “vš>ÕÄ3î»Ãïªãò"¹ EëdÞh¶4Û'3˜ ü0Œý ˜‘Ê”Ìi—V;œÅ#ó0 Æõž§ØÇÜlö±1GYÙˆü£lê,ƒˆ%"ï ÂóãE…ñõÏ­ ëºíî#²{oØîŒ'؇èÝe.·;ÌF ŸC^·äª}pÛª1±Uä0ƒÝW謮*•ucà ³Ê§QØŽQ¾}óôÛƒmUTy^Í)¬œúUî;Ë«ƒz!ón_M_~©QAZcÈ-•  ïÓÄö:ŸSE~"b«Š­lÛk4 x3öÁu⃯ð*á‰oj% f(MN]má{¢;É“ç4kU֍ޯ¤>¦¦/©oé ìÕGhfÔ·ô9wßRY¥³…aÓÖ-o¤ñJœPÛÖíl®"Ûy|"ðŒya¥¦6‡ NÓÒªNo·ÀÜŸ°äšÔº¡Å«BNvm›:SmKÐÒ”ÖßaÊãž UjÍKay91}ƒôãô„õT¶ë©‰D3¢ïLwb‡FSMqéôÂpX\TucIçô•¦g|p*Ö÷vŸyMWð÷(ŒŠëŸÖ×iË]·ÎŠÙ,¥Ì‹zçÖ—«Cf bƃƒU8²¡ -ÒŶ(ë»Aîšû¬£ìvÑMaz5A–âXÀ7«:¢*ºµ!N€opd˜»s¦+¦}ÝŒ-õa9cýž±j]©ÿ蟑Q“ÄèH·6 øgkØ$¶†…ư02†…ÑÞ°‰©CœÃÂì¦aáŒ1,2@Ÿaa6²›3ì/3Lƒ¾¡d¹™5 gqÐgîFßš`ëá\š²Ä?ØÏı½ûÃý^ãÓ0Ó¦Àˆ £Þ¸W÷*ûÃñ°Wå†Ð¨´!p$i× Mà$–<å:¦FdÆ154Vd‹ø/Š,1yÊR«ÝÅlc.Xö—u…l¨òpgîéâ>2\õA._]ø"q_mUµW;.eeY“Æe±²¯2Ÿ¢Y¤£pmöå¡d¦Õö<õY&³|O¯õ‚y }³³0\âóR‚Ûªº 'iÃ~Mß•¢/n ›èºdt;ôÅÅ2 R÷’ØÂH BÎüDXa¸Nyúõw³ endstream endobj 2203 0 obj << /Length 2194 /Filter /FlateDecode >> stream xÚ½ZIsÛ8¾ûWðÖT¥‰`'9·Lf’^½Œªæ¤R´D[,K¤BJ±SÝýßûaå"P–Ì\,÷¾·}£ÛGo¯þ¹¼zù†“(G¹¤2ZÞD)Rž!ž³h¹ŽÞÅ?/¨ˆËöºl›n‘Ð4‹_-ˆˆ×»ª®ºC»HD\ª¦6coÕºüÞ´/·eÑ•æ JY|XþtõïåÕ§+Û㈘í8Jq­vWï>àh ý?E±<‹îõ¬]Äe¿Ûè?W¿]a+:F$ƈJ¦fKµ0pÒùûœ’#ÌR£d±^Ü·U½ªöÅV éw™ü¾|+÷ QŽr=_&ÅÌb/ß°lðŽ¤ˆ1ÒÌ~gfH9˜Á#©›ÐìÞ â.°Íå~±ÅÊpæ&Ôå½-°RB¨@’ph¤(gÖü¯Û²8”Êòy6`M†q¼»StmšI$雲ጸ‰à8ŒPX½ÙíU}kw½¯Vvß›ÇqÓšþÂÊRtÝý‚ è_£EÂ3ÿxc†êÆÌN±/5ÛjõÅŒVéëöåªz/×fà¾:lÌRÜ(94>#‰ÞP‰]4-g`&’´åB8Ã*£*Aä¢V’ a1††‘ ×Å„2 &àw{ ÖåMqÜp îçia €¥º­K·sc6ë%[Y÷U7ö÷`~Kë,¨|´ü%OãÕ ˆc‡ôñY=–­2žUw¥ÜJ[XË1ÕXÌjœÉ| å¼â|N¼ƒÝW[¥#àÓ(އf²¬ Y¿Øn i60hy 5p©¾ÖèX5Çn¸Â£ªž=ÄT&R/;8vemE]µÙúZ{c”XåFPtÇ=HÔuÚ‰¶N¬Za'Î"Â'd9»ud©+e}fRŒŒ,„1$h>ÎF/µùªÙí´«‡¶ü´ 8>VmÙ“€b”øý ±d"d-7ÅÁû¹Ú–·ºr9ñ Qf”Å{µ­ @uÿŶ@¼mØy6ƒe(ì};] JDŸâŠú.” Ò¬0‘î ¯‘n®þ`û µæWÄñþj¾Ò Å…*,s'M©œóa¿†?Ùe"T:ö³÷X`ƒðA¿®ÍhœÝ¹ø-Ì!f`¹±3LT€€Ž4@_ÿ~sÓ»ƒnŒÃƒ"qµxˆa²×yÿQX€‚áͽt8$GJð·@g\¨Îáõ (vÅÃÒ7›qŒ<л©›+âGt§@?ø©îëãP`]±á÷ˆ€ ÕnQ­”!ïÔŸò`ú¼˜ú©'ßÔ‹@ ã:u©ð»WbŸÁžÄb€e«%¤Þ¸X0‡Ì³ÿ°­W Ö)®·e[œ#+tÿSàï>‡;˜J”e>‹¹Ió^ x’¾<pŒ9TŠÝ¨£“Bâ‹é°Ì¥óˆ×Ç…ÐzN2ÔÕqðÄ„çËý´Y$â\4bBNÙ®êñÄJÆÇ®´½×VOÕ¶G͘,‘Âj4¬ èÙ€+kFÇk”ñPI9>ªd,òËȪÈÇdu(xe¥1TN8¨éS±r¬·@„Hœpñ$¼žÄ}¯¡‚ì¼S¤PG³‰OL6³¸÷§À¿¶v]»H’Øû¯?稅c•i]—æp¥fû#€&‹›²ñ° ²‘”tÆ~ì0Ò^3ë±èa(§b ÕÉŸ/þŒ©7*ÝÜÜ7NzëÑjA°’™·&¤õŠÂAtS]WORFÓ“ÑÞæúP@ZqÃvÚ3Í–¡Š˜S•ãúhyq¡øpž¦¾Škß: ŠÛóà˜!ÎÒG  K`ÓšºÑê‹!]>žbŽ3kL´Ë8ò,`’ « Éä‰uÔ¨±ŽXGøÂåÊ_k¶×“/1PjNvz‚^¥i>µšWJ`”E$I§ŒàqS†*QÀ’c~ãhÀSì8»ÂÔG%¤wŠ1îÝ”bŒûãããaÃÉeq–!‘Š€ý.Ö ò$æFÊ\sÙé!0”ô´/5J¬‡êÉV ¾=Õˆ!ÂÅ7΂mcÊtO//Ì‚8g¡,x‰ ,¿>²Žx‚ïŠß) ìÈò­Zmi ðAOå‡d?qÐý€Šæ=xñ4k ”÷x'ˆ¤sÞg²Ô' G{¿Ñéà€†²þã>øâ’%¦‹"Ì|XNïór¯aH¹¾:5ceu.î´4×¥uRÿlóHn¢Íß.¯Ç Þ©Ó\Ð@0õ%6y†Ê “‹¦×`Þ¬’;¥¥ðf…c¼Œÿ&Õ9F²—è¹FÈĈmƒŽBû9t®nrz¿¯¾ÚÉÔžÝaôç½6/šKsÕjjwÁ­&T]w,Ãkó“Ks ›R”’ÉuÑäæ pg…“ì*7ÕôÂpµ­Ô}9øÆ0 ŒùÓœ¨>º¾»db·RÃË=ÇnPÒÊñZ_AÄ‚æß±¾"ŠÇ+Lý£Tdá VßálmÐ_ä&µØïzlˆ‚º Ì¡¤Æ ó³^m©pizÖö»ÉÊ>ƒÞ<÷kLƒÞ  ½Êª1Bc>pígóÀYÐà„•g'\¦®”ªVþy:þáÁ±áYÖcý…­ÛÚD?4Ìy ¿é…SJÑŸºè‡QýÐÐÑ?ô¾éç{ÁäK¿Þ¿ÅsбŸ0–ZðŒÆ¯7Å~g …þxhþ ןó³ÿ„LåÖôíº©èr×rX endstream endobj 2209 0 obj << /Length 2526 /Filter /FlateDecode >> stream xÚ­ZÝsÜ6÷_±o§½d‘¢¾2s¹¤Í¥édzµï©íx¸m묕¶’6Næ®ÿ{‚ÔêËkÇî‹Å@€ku½òWïÏþyqöê{ÉW)K#­.®VOX§«X&L¦Áê"_ýâ}\‹ÐÓÍV7u»Þˆ8ñÞ¬yè廢*Ú®YoBOuE]ÑÜûC‘ë—ÔþY—Zµš:œ Áøú·‹ξ»8ûýŒƒ þНbÛIûñ*Ûýò›¿Êaü‡•Ï‚4YݪÝJF |ËÕùÙ¿Ïü¡üA2?X |bî3?ˆIüº*ñ_×›@Ä^ѶÍÄk5È.|ïs‘išìŠl ·øGw-‘]­¥ïÕ¥¸Qµ¦«oOE•{UÚí®h®»±[de¡«nøÞßÖ2ôZKV]AkO€ºY¬V‘à ¬D{»u/´w:'ÊC[T×–*4µáœ¥aHê¸QMNÜ4Lè{¹Æ.û]Mß}£¢hfLçtÿêû((~#¤Ñü†Ç, ,pþ·ùÿ‹?֛ȫo/U{™®9ÀlÄkÕ/ÈùbyÑÄà±`pêÓšÖMÈØèÛP¤ €"vÔõ­B|¥ʬL¼‡6äÌOCÇâW?Õ510 f ÂI»œîŠîÆIYØù)vN Îb†c`â@xo œ,áN!®¾«ƒ!Bòp¬ÔƒqÆ(q;Géñ‘Ý¿4uSR-¹êh,ktŽˆP¥¥moêC™S{«‰ˆt’‚íÔàÈ2À»º¦r‘uÃutÔKÂébhZ;l–[5ÒI1ªi-ôI-Ð"µ<óª,kôÏ»Ëösó0Ü73ú‰ð2fQ Ü÷M}Sl £ÂÔ†h ÎT•Ù^}EßI¬Â³HƒÇH9Uà𛼦?T4Ù¸ÎxL-UåÔ(Á ò…+!H"D`ƒ^·éêi°ÚÃ42ÚXgæY0؇± ßeiÇQŸA‘| U©ÛÞÖK!‚G“Iïà³ä‡ýe{‹,uïfóh”ñ,8ÀfVà66ºB¬ZvHz/DEb ä?ÊèBb¹»n/›5þþM˜ž¬›œ" Ozl·{ ´Ô@ßEŸÀ10áÀ"`†ÍûFUOà| xùÕý‹÷çðáĪI@žƒ&ÜÕÑü„6›]ôþ4ÂÏVº¸ŽÃ³œÆ`΀ޞz¤²ªîìåkwÝÄÐ%¤„)“| )èR¤(}>bxÈÍÕû bŠ/߆¢Ÿâ\2K'µUö¶È¾lýÌÅ?ìaü3^W‘ÇÞEŽ©ÔHÓÐ7·‚ð/›aù Dºð/pXPcܧþJ듃s1?êÁ½SÍm{ÚE¬¿¹ÛÎ’Œá#38˜ qzß/˜óD8òY âÞ¤«/DO+DN,žª KÏ#ÀŽYˆ0ÅžˆdŸ{˹îp֤€øŒî§Âä701¬öl—«migçQ­ç%=ÈuyeÙ4õŽZ h×(âø•vÅ”¬}I9¸ÛÊ {®…r,eK´l]Ñ…Ú¨¢ri× ï}†CTÖ9& Õ_t°%¨ÊtòÇĺG3šÚâ}t €P#›âÙ¤…¶“ÞOëÔ÷Þ¬ÃÐ{KÆlð}ónsþáý§ïÞ).þ…Sà”ªSDd-­­¦ š*Ï©~´V…ïÄaää7Rº¤´aÏ1RË·8ÜI;•5 ’Ó]X]ófã ›èQ<æ ¸/ÄýÆÁô‹´3`£é8ó;¿‘}pÜÈçsŸwRïÞRãs¡ˆöVáƒdr›3XGH‘#¤M:Má {6*ëÈböl#%Õ&Ÿ27pÅ« ò¾`˜ÛH ÉÁBÔ–½÷7*’w¥Ü:óè gIøÆÈŒëzqhºpRK1 /|`HÓw¶f“.û 9ï´¯eåpë³"›.;Þ Ÿ¥ÂJËc…:M´$2Ç2 R;;8Ò&5v¥­ÚxrÔ+§·=³ÚBº‘¶h¶°Ì Þà PKEÔpF5 MkÅ ÏN•EVÔ‡véUOÑk¬¼±¶èC ´½/UFáDLíßMYXšÞm³í®»W§žãH0¦ÑÀAÆ–r™;ÒÖÆæ"°9ŸXœÿâ¦X>åT¿xᨊÛ>°%”q½QuPéÎæ!·.è»:«Ë—–Å¡›0=>·hôΚìäÞèᛤ$ì)Qtƒ5yh0¼¥ÈyÞW5ýÁ‡®1ªŒzŠ¥4Î=[5¢XN¨[“€”‡'¼ oªú‡{« éh¿Axg³¬Ñö5r”¯Tõ\Cqè™çÕÀû„Õ#ëËÊ!Àý²θx‚öwtƒ%þ0¿€k¹O¸mâ컼ý”² ® –§®ÄJg•½I’eÆö}vÈçøFcÙØÐc—^Ó EYhäµ¶’Pˆ7ÛÔ»}GƒÇ Í%kHàû mTwú5'å½Ã%¶YõÞÝFGÓY4·7Ú=¶™•{oÝß=¤›]ÄûÚYûˆºYYã0WM㢂v¾¤gÐÚ5§w÷-PTÖ?Z–6Æ?nz m> îফléET² é_Ú_/p XÀ“þõN•Ý=\ÒžËK°(ÆÍèsØxŠPȱaÿc‚@ #›rÉx Iœ™æ(˜™pJ¤Þ1óC&º³¯ˆGÖÑRÊ£æuÝý>ƒó‡rH?ε­1™ðüQŸ±˜6pÜÙàÏÆšÑ0 ¦’…~¯ºF–¯øwr"ÀL{J‘¡`ÒïßÐÀž%XCø=tnóŒAéwujÿB[˜LžŽH~E𦾢ÄpÃâ(”*uÛTý¯£ö ŽñeÙ1R¿%Í·—h[ l{©šë“zæKÓd,î‡*7?¢Z7Æbo ÷Ǧmfc„ X­½~.\ °Ã‹o•–äÇwë(ôÞü4ÞÀƳ:?8UARûú”Žü™vˆaõ5 pMÙC3¯NúqÈ"1±âùð©ÿÄqêíuÖ9Õ¹[ÜEp€^§Ši|%WéÿqážDÁÙÇaŒ¡é?+„’‰èÑÿ«0ÿ `!ã\ xÊ8† éJDzrˆº}%Ëýx*ÓŸl¢6 endstream endobj 2213 0 obj << /Length 2360 /Filter /FlateDecode >> stream xÚíÛŽÛ¸õ}¾Bè“ Ä o¢¤) tÚ\šm7ÝÍNž’ PdzFYr,y'ùûžÃ‹$ÊòÜ’‡¢hŒDŠ<<÷M£«ˆF/Ïþvyöô…dQF2ÅUt¹‰%2%2Ñå:z·øç’Ç ½ÿ¤÷M»\ñ$]\,Y¼Xo˺l»ýr/ò®ljûíå¡\ë'öý®tÞj;`„s–.:{~yöåŒÁñ4bö8IšDÅöìÝ­aþ§ˆ‘¥ÑYµ¤JáYE¿ýzFêtL‚#2E2€—0J¨H,«¯€GLUY^×ADž¾Héh`Á”fýº6¸úCž¾éhí ˆá2‰VŒ‘,Ží–ßvº(ßS!ukÏꮵ}ù׳¥Š¿ØQóéw]tnIcŸ7×el½žì¬õRÀ×¥ˆ â›.ö:ïôÚ@Bt$!˜ÙX`®¬‹r—Wǧޔ•›Ý5eÝ‘ ©3WHdHjB2!BnM ]äe­÷F/fy«’f±ç-î2>ÞÁe“,IïËåì1Á‡zí§Oqú~\,ÛPnŸt Çs²ûÜ횪,¾Í±/Õ…vì³ëneœ[ËB¾]´mS”€¤£ wç7€ÈφúÎ+…9 ôÞ|ò,Àÿû«È¾¼yZ½³PÅ)Q\L-_Ž-_ BÁM­ÿ¤Õ+ ΋¥–è×(éf Úéó©l’Ñf&ˆ”™ ·›ßsFoã2œcÜ’Y| ü1‚ pb)¡JŒõ~j-vS¤My/í¼^ÏN°òk¬S›%(áY¿¬Ù¡£vR+òºnºP‹ÛÞ¶ÖÞQt#;™A,T‰‰Óœà¬UIâ@n“ÅŠ§ á` ¡+UˆŒ2 ¢˜¤á¤‘pÐj˜"%)ào`n›u¹ùöqrþDÔâ\štd g©Óð¦·÷<ßÍ5(³t(Z±ia ×c`<ƒR oò}˜zFÓc<µbò<(Ž‚†ÌÏ@ïü ûòVM«åx®Î¶í—×W®zV@¼0{«µƒ›·G`Ér¥Xfº±õ½ÆöñWüSè68_l–Ò‚³SÍ é¹ê=Ðj?#Ó“þ6×nJ¡ÒëI~24 éUdµ»™+µd‡ Û ™m‚q™oMÏc„žÙI „Ëtñª¶¬À~ Î?·T`Þ®žcŒ`$îcɪ¨t¾Ò¡i•ÕïÐ&²w„nvÙWw"[SªC^wNº)'iªÂTiÜŸm6A;w¦k\×ÈŠ.¯}Ûi‰/ý¿`µ}(÷ãÆú\Û‹A8î[cÖÉÌ{ƒ„ÉÁØ-^”•¾27JÄåž’‚œ4Å/ª2oÏç$ž6¸#8Û– 3Ä­ Àþ{Üÿ|Ocêû^Ž[ÞsVe§P#»>…ƒ„Ú+'ºDzó[o ˜Ì v°É5Á¡®ש¿¥ êÃÀؼEkíw#õ41ê&öôQ¨:î$Á:dVSk;ß Àð:oíÆ½.tù‡qkû©kûjf}†mPrÐwb~V×]Yø‹DD°ëôv×9t±Ö:;Ðus¸r‡wåVÏÕ‡Ÿtwƒ'j=´¸\+1/ H:M K»ìüu¦¥H¦¦£û”œëÀõ ’w~sßT÷Mº¢Ðm»9Tãk»¡š|_î°ò¢Ø®µD›ËX]ç[ýã’ˆ=:…˜ÓD"lÕ4‘§‰Õ…Ó˜;bÎo ±HïK4Õ8ºš g[è›w¤Ф" äãŸdŒïÂûg!‚<ã£Ldˆ~!J3q!¿×‘>…˜Ü0Ð!þÖwã!—×Rç쑈ÞÙã`·o¬q!UC*`–™&±õÛÜÇÅX,ÀF™ñÎyv!¯°5ŒF`º.ì×­WίÔaDŽhbÑ8#>—H`çø!wrk]i{ñ8§Þ „†ätpl}tL$á‰zTtt–‹Üï#ToùÓß`ÄpŽº÷O0f5"9œîLˆÑ­§|ñ÷ë|·„„u‰¿"q¿É0–Ù­¿$½²sÛvŠú‰9Wƒ endstream endobj 2219 0 obj << /Length 2191 /Filter /FlateDecode >> stream xÚåYKsÜ6¾ëWð8SåAð&©Ó桸*ÙMG99®5ÄH,sÈ1IYÑ¿O7‚á8#É»‡«,’ ØèÇ×_704ºhôúâ›ë‹¯¾—,JIª¹Ž®w‘` Iâ4ŠeBd*¢ë[ ºzt‹ßx[·(õ.+*“»Y¿SE»»¬s¯‹öÕ‚’L2¢…z†–Š¡B']kÊSâfˆȈ6’r¢% …1’*5ò<¨ËtupWp«½fî’›Cwçnë»v­X:…Àõ]Ѻ Ûz¿ÏªÜ=4æãšø¢1þuwg¼SÆ€f g.ò|Á~àÍ ÿÁoŧ¢4·–(œüÝZ‚²Í‚ã#JÇgBL¦öÖ,ë. ž<赯ób÷¸ Rp"‡è=S}ýÀmA!RI(ç>ˆÜ½Cøþ„ BëÁiTT}({NE §Zø,`Á'Îå’¯‘lÇ{g3êŒN7^â¢xJÍAÓ5xþç•â•ÏæW=’ Xîf2gÞŽ¡qò»%¨vý„Í] ¯oÍ‚•èõÁ²4 ¥]ŠHJ¸T_(Ë%¸*Í]ß:Û ¸#Ù›‘©y(õ m e$ŽÏÒ@@z }f±«7!]GUnÜkTã¢s¬T±ë§ z³”*…~1DdÓ@}° 祅ÊH‰ÖɈœ–ÒŠÐd`ëÃɾ$dSŸÄ#íK®†½ ,·Ô7‰t”õð0Ëz9•õ”Ä:tS/*‹;žätê#gJæbcWÅf¶_ßÞôßøð;uíÐ}UÙþœ‹d<½vùÚd{7R´3‰m¶÷w¶(L¿ž,æhI)¢d:ígoŒ[ésp”““-ÊßóØvÑ…—¦œtpeY#ô‚V®Jxpdé±Ðü„ŠfE™Ý”ærBd3åfF,!|ôé¼°œ7öÙ¯¦›“Á ¿±·ý]Ìük@µlQW½m彫)§ ÛõF”’-¡§’ÍÓÓô)hÂE<-Ìà„»öÖÁÍŒwðU=›2îŒÜ€%öÞ-·–ïøê·Ö…Þ~j!w¾U°÷…¿f^ÊÖK8xÂþ êôç¡nÍÙ ×–&íí}kš^ƒ*¤Ã !ºí#ÆËYdúÙê­k©à¡,Üô'¸Ç¯YŠ/t‰›~G3e=(ÜIè¿.¤LJo›•Ý )C÷ âÆÀöpù ”Ð ÅåÔ‡¿¹³‚>8BÆS¨à›qz¡ŸQ1û¢w¢{ åÑ 1?öDKr£˜­øM˜6ÍV°Ms°7¾1ãØRg&D‚Gmc6´Ù¤à°yT4¸îG«Ë#þY˜i?çH{blŠêejaLt>ä[²­«ÝçÖÇWœŒÜnÓ=9 ŒëŒp÷¬mÙ²³-€ÂgÄ×>#1©›C]æO%u s°•”÷•”{ñÖø2-`„s-5?ïÈxš±p«ìÖ忾oï³²Dqn ª;c62‡ÉG'Áé…¶æàçLs—õLOD¦}f {ÿÐ5hnºÛn©…Ýjªæ=K‰Ö7göt”Íâpõ'B8ÛB]†] ¶ó«ßÐ,½˜^]‡3gGXHN¦%ž;G#˜›¢®’ºi³Çí>î(:D)e‡KxR°á³,'a/â^0"$ÔÏa@DÛÑ“$NáŸý< *"•ŽÓA¢Ö~Ú°bÚ‚ÈðPö †:ˆ£Ãr[x0›öóý…Z˶ÿ÷öí¢_"€—×î×÷÷©pà$å¹w—„d` ·þRþMðW?àüÕ?iáí%Ð!¤Ø øuXœwÆ~A7øÏÐ!çºâ9ytj{ß»r£ñ¤®˜^Jsô§ýfÂ1¨¤ É÷mdøƒÒåz£€±°á·7ícÛ™¶[j–®ª+œe»¯pú@(Kb‚·¶LFlÅŠÇ+NK¡þ8–—Š Û8;Þ€Ïõ½À*þXE&#ÇŠ$ I‡3â}óï««7Ó#(ÔÑðÇÊœŒ¼=ÒW@ä19wâðDâçÿ\:îå,…ž^O½ü¶ïQþ~]¬˜séæË š&ã|„"Pp§AzóB×Êx|X~ŽkÃ!í })4bþ¿ö¥'<œ0ùSð=¶a4îf{"Ïœÿà­$áúìß»½–œ0æ·è¸ 72õ«[¬H…ŽÎe4ëôÞ¼›™ endstream endobj 2223 0 obj << /Length 1915 /Filter /FlateDecode >> stream xÚíZYoÛF~÷¯à£„›½Iú©ië=Ò&­>¸A@S+›5…¤âèïìAŠd)U‡Ûhõ r™ùæÚ] {wö^]|y}ñü%'^„"I¥w½ô꥛,û2IÄ¡ÃÍ.³…ªç€Só^Ïßè÷òýÐOˆ‚¼"hißMp(ÄQ;aU¥E’®â)­|  †ÀÌ'Š˜óÍ7ëJéθ¨öNL€‹ÒÍi¹®3ý¶ÑýxV©&N µ°³@ûò`ŒÓ3‹éý ¬ÐÒž .«2Ÿ2äHМDËrÖÞïWq]?jpK#¤[¯Ã[K0a=B‘ xËä –®'B@*‘ ù!2‰àæf¢¹ÏH0ûf9¥–@XÈ=2vÚ(íìÔX¯T’þŠW‹gšÈó9%ˆó þ'\t4÷J'Žœ¨èŒF:j††…–‚™isïÆA>×™•ZæG=WUv´ÃLàGBŠpáßaR.èHDCùW‘+Q°’ ËIŸaÜ‚cšÏlbHià÷.œ°×÷jBZ`AC[í–šõ\¹Z °Õž…ìÑuºÁª+Ð ÷uÇnæ×÷-«¤Ìó¸X´,>hó¬ÓJ¹áfRZPÒ›—‹t¹™ŠŠøÖœ+í8 ïÇ4S4dkÁÁegTs|ÂÄ6ñ òPè «:s7ˆÞsjŽM@Ö÷¥"E‡œFUµšàCuÉyš4OÀþl5°ÿ+Õô l^â¦qö¹]7­ùË¥}¶¦³ËèTÇØìíý6YìöÉßzÊn…µ“Ò¡Ï?s2¬›Õºׄm¶p­Ø=­×–r~ÜÄ·~­Vqw]µ¶Õ°¸«Ûàˆ0 B1Rö¢CŠqtÀðîèY§LZ|ÐkÙÜ8æD˜0$v‰†AFºæ¹5ãÆÊcM]CëØ>Ûµ. Pv4ݽ +m´Tqî†J;r;žZǹë2˜÷Ù•…rXBáb ÷ ÇÝ*+˜ K­t®Ôxˆú‹,ëË iš8_eÊ®bòŽà‘7~ºì359öÚíN[†&²(†ZDõfÛûàÁÔHËÁ±5j&¹Çìþ;£ aº3h H¨FIH7@ã綃yI¯Ee€‚>†~Û …FHHøO`7q»è¶/¶ÛVÖ®ºíÂ=ž¸·j-¸%ql4Lþ3z.½·øR$t9ÑWƒØ#—ý>Ö=( @ê`ÓYvV7áF:ÜÚ‹[Û âmÜUÀ±oË ”ï­¤[¥> Gk€9’SÂkW‘n!õÁF˜ÀSG$Ws•áð4Ê%¸… 6øb}º¾„£5dÔ;å2‡i5ÙfíÒ×öh¿Œ˜ƒX=ì% Ã°îZ/õ½iËòåS¯˜Ù¹/ÃaÐc6KÁ`_Ž#¨J]ýâËï¯®Þ ÷Eˆ5Âö],¤ÛýúHà¯~|Ý–}[1„çêÓ*­ÜE‡†gÅÚ!uS¨ªz7ê÷qÝØIæ4XV ÛJô1±¥Ýò|±¾kS½FhEX»¿ì÷Ä ¡#P§äcý/X|FäYä<‘™®¾¾>ÈHCV­ ¤óëðê$3¾Ž?¥ù:w‘&ÊY5K—êòX‘ñ”ê‹xS­;>ËøiÉ÷aV©B=Æ·™:¶à©`ÃÿfضÜSSµø?KüYÂöë{¾ÛßâzŸ¯Ö1 ÇlIÿéZgîM½cŒ£€ó]ŽX¯“DÕõrÙv¼Ö7PM=¦.c8'.ŽäâòøËí°˜ÆM£òUSŸ›ˆGbÿ°Îoõí¡ž©oôóAmŽ_†ì]æ;µqÊ»ûÕ3XßÌž9HTM…<Æ¥ý1§¤©Ï¢¿Ïãä,õ}ÌB~:‹CSTD÷×±§4Ј÷‹¦©ìÖåä–¼ÌÒdÓ…FY¨.2(Cœ+öÇÍÐý ~{÷eÀ¦›){C'¥>{Û÷vù‡‘ˆ@ÌØ)哌g!–ñIÔ€—˜‡'’ëÅÉñ”¾ àŒ/†FBQ)˜8uF9¡ŒŸÌ$Àú³7œ>ï‘UPÄ0ÿ7û²ñ© ”àøt[œî#ëù!C2ýÊÔ&³þÌñGæ^ç°ÿ LþúÏ)"Ä]·8Gù4 !}u¯ôo1sa8Ô\ˆÐÜ—<Úû·}7mûòz,ú­R˜[ endstream endobj 2230 0 obj << /Length 2476 /Filter /FlateDecode >> stream xÚí]sܸíÝ¿BÚN–!ERéC›æœL’¹$oû’Ëxd‰¶Õh%EÒÚçþúüÐJZù#öÝL§s~X‰ €€ ©wáQïÍÑ?6GÏ_ æ%$ ƒÐÛœ{œÅ$Ž/1 ÷6¹÷Å¿ ¤¯Ú3ÕÖÝjD±ÿrŤŸo‹ªèúvµ–~ÚueæÞìŠ\=3ïŸU©ÒN™#A@ØêëæÝÑñæèû¨Ç¼(v‚D4ò²íÑ—¯ÔËþΣ„'±w­±¶žcx–ÞÉÑ/GÔÊO ±) BŽØ!óZ˜8~^Z)re”P™E–°”Ó¦-ª¬hÒ²Ób|fÏç¯öžT H¯áÉCy+¹ç¯y<ú* HÌÐÓø_ FŽAÀAýÖ´+N}Õu¨êCz"tæÐ¿"†·fˆ€h," ·æü¬Í‰v ¨_(]­8€Ð¸!ز,ÍKÝšgWoÑ„¡ðû‘Y•™­Ò­êÈ‚øL†$J‚‡/Ô(vᄱ"\ª²\wèvý R)•™¸(ë3#›Â5K_Ïö—ioÞ²Ô‚²ºêÓb˜·d®‹2_gi›[$dt™¶+!ýµÑd@‰Dªd ¦µršõªµÆ Çk $ñ°˜¿-¬V’€»ùg `C$ƒ5ÿr/uÀ™ŸVù’,Œ„{?úòulÜÈjÍÁ)^j?ÂC«L[ݼnÓÞ諨. Ĩ^l°´Õ“Ñžl¯rËòí¹¥^ßþ}Ñ9©jœ½‚h“»õß"±6`ûÉ©ýì*8ŒXø2KF‰‹snÖ…8s¹–׎TU÷æeð5Í Z² —„ÒÄiþï ¶‰‰ä‚sLíx+AÑò\òeâR˜¤­e>GuYjM_ëÝ››™3ܘ÷A-e¡àk«Òrk´VtÆœ†$Ž“ÙjUåH5ÔïkûÔ/SEë(âNÂÙæR{ gõv‹[@Zõ}Ũ¿+ZÕí‰%ƒ7i6ì$ŒÛKöó>”9¹*Ju¡£)±á6€GåTÀ—e‘v/Xaû‰œuÂXJ‰I<ì` uë¿/ a”¡{«¨sB"`]%ÿ†_¥Û¦T/Ln…4-EâÍŸ6ƒ/MA‡ÂÁ• a a{"¡$Õ@éà}÷7AA5h³a¶õ¸©&"N¤”\‚©1…ˆB;Á<€ÇhŸD üéÏ`D„ ¡~(F±EÛs@¥c8@èžݳË`À›:|û zeÙÿýúν_"ºXrš©î¯0aÅ–R¯¶!ÞYªÀÅ}úõ¹C<äis)¯ ìpîÅ„-–eªÑÊ…Eþ ǰh …\¯K9Wo‡»0) ÐÙ]ζ\eäriͪ*ëoÕ=ÉÕàxê|Ÿû@јô¦±·K8«yèW !úŠ–¹™ÚÝÐ6†™o&×L½gU•A¶lî8¤qb|Ž]5·ßÕvÊ¡8ÞÖõÍJ»ãF'JÙDPÝ­ˆ–rqhÝhJÏp¶çG <ÖjÂu5:ÙSÿ^sÀ?áÁ¾"xšX Ä@í[žˆÛçwñç “¡ý<25ZÔ-½&[kÏ¢£sþY^íÈ^Ì2fíÉÚô4Ôy«ô¬4÷fÜÿXéˤÀß «æÎŒûŸp”vÝ5zBÝæ÷æÇÍ'½ç4 iÕ<º"x¯ œXV€¶Úƒ0$BÄJí~0€Ã¼ ÀVìe—xYÏR7ªfȲ•K§:´é({:?©Ïþ­²¾{f¯R—–pt©?¸èÕ:Æ8MMŽz,‘„Åêp[-/]ìOØË7qàq4kqðL««ÂÅ«P¾7ŽŽŽe~[sŠNýºùVTEš©¶?îéžV PmP|L/þrp/F¹½ƒÅ·\!‘ÊPq×Fϔ⚉-ÍAMIù¼Ž £b¸9¢fÜÉÀ–¥ðf“ùB5Áfòg~¾;1 }zÿöÃÛ½œìfbò¶))avvkÊéáe'`é-ÄmÒæ.ôÁDgŽœŽE¢–wçðëÎ~a‹À¡Òèòa‘N·zÑü:‘’$ü»nö¹è©É…Ç„%Ñå[{&ïÏ. ÅäN›ó«ˆÂÊhþ+Bcøàÿ[Yü/ÈFŒÙs3KIC‘Ø&öHÑÇCl“ü\¦ÿÖ ˜4 endstream endobj 2235 0 obj << /Length 2205 /Filter /FlateDecode >> stream xÚíZIoÜÆ¾ëW9qMv³¹øÇŽ,NÝlÃà=ÂÜÌE²ððþû«êêæ%åØ‚è ’ÕÕµ|U]½k]X®õòì§ó³Ç/|ÏŠ8`u¾·Bf…~äø1·Î3ëýÛ† [¶;ÙÖÝfËÂÈ~ºñ„•y•w}»Ù ;é󺢶—CžÉGôþZ2é$}xcŽ·ywþëÙÏçgÏ=b@ãH‚$ÎÆe·meR”ÔbÂFpИ¥ÚÆÈcc¢E=EŸÒ>§RÛó¼•i_Ï::Bûê uç¡Ãx®ø Ö£é $w)p¸#ªBžgx1qÆ&Îð>q#¶£ÔmÇ!:1×ÅꜲº¤uY&UF­ü¸ñ\{§º£F²(8À<®(ieåûkâ›UÎ_D†­3»ªZj =Ÿ;AèÍM|ZäI÷dE9 Ï…BÝ‹{¬°7õo5ïLðÏŸ°GR6…|B¥Íñ˜ðckùl/¬Ûš^¿Äêljs9 !àª>[-àÑß%¶ÅgZZœJvÈ!„"ð%Y垺Ás¸ÏÙ„À­tòN†1ü©î#1èƒ0>Jä®f;jI)ˆ? £p¤¸GqîQ] ¸]ï®ò,ýÇû··þ´ ybS#>^ŽA³2þ¿8˜‚ñLÃå;>8Ç^B·Œxáe¾X¨ÖŸšYܨá®FgŠ Â »! §BqŸq´\¦˜§rÄŽëÁSÀ‹ˆ'-e¢ùRFD¡Ä) ý{¨ jPju×ëÁî#øæŸ²mF“ ÿãÙ¢ûºþ’þβ™÷_Õ_fyÒÁ S¯YœuD…YÄcÑ—hØ.5¤°¨Y™Ÿ–H¸Ž!=PQÿ”žå5®Ã`¥G™)Ý?¾xõjfÄ)–/âÎ`1ÏH¼Ú³Wÿ!«ë¾ÑF3²|øh£gŽêòöS:ÚoîÓé¿÷éôÃwëtcðà,|ò°Í;ŒÙ÷P-|ô°ÍÚS%å¿Yø5`Ãð íûß»¿C•ó0j <³ø˜Õ<2;ÍÙÆ±ÃCØ%ñȉ@ƒšN2Y˜©o¦dñ\îOô~ ž<k’ ÃtVôaËŽ›¤¼JóFíîÂØþ ×öUÛ}ZìéžËBöfߖУÃs½'¤ólë e7ôzC©Înšæ1æ°Ð»iÜÊ^VæœÏfb°Oœ®ÿ-7Ÿ-måŠQ°–çQøù (D=¸×ö´ë­çWäžÙ¥rωôQ\’eÈÓë¯M½¹¤>>¬­ÃqAöf%¸Ã½ÀºQùËÏn ìØa¾0¼ïV„ H†xŒÆmFÁò“9\,²F¾dÙ<¿›¤ë®ð8¦nui©ê§Œl5«|Ö`‹±Ú§f‡0YÒ'»¤“HVß2Ó!’+Fzxøðù ‡àD̘Ǿ(ÇA/@têñʹ‡ÎЊ¢Æø\Õ§n((Œ­4ñä®>ãË‹d7ͬç¹;W¹-“OE¾GÆÈ¦0X)Fˆú¼¼óD ‚4öç› ·®p³¡5ø‚ñI(÷ rµäBOþR§Æ³ »óO¯Õ™z€²Ð@Ò±¿5Ù»àY=òÛ–yuHÂñãðt\GÄߣ¼ú¾Éê¢?¬ „µÒ‹Æ‘íVŒ@ƒÇ }ÖAûm\K !»ß¬¨ÆBW åÎìñosM8!ç«®±X»Æ§®U‹U Ê5 Ñ=NÒ&i¯š¤T|“J™Qs^QKBŸsP¶œº Þô˜³úS”Q1ª.Yj¨hƒS¨óÖŽG†¦‘:͉‡fåk§¿š¡JûA M§‚«Ck¶&Iåã¡BûL¯z¬‚ZðÔði¨¯Ûëõa'D~¬&5w=}Û/&ØÜ¥`# b¥Æ=}ݼé8RÍs¼†qUÄ•ZˆBÌý(ЭR¦/¦5×B«ZËë ZT”`¹˜Q‡«ÇÛÌøßŸoa?ýƒ¾Ô¥#¾˜ù~- Ê: yŸa™|Ú#*0í -æúZqÌñŽ èrÊ ÆÃõ!jn ;ŽJ Ò¨dv2@sÕç©©åж×só@kàÚI¹95æºSQOnQiÄú´´;Igb”ÕU×Z5 ‰ØµïrÃha!Þå†xW—Ó@#žIé¡ö¦•s`Ðz7¦zƒ=Òz¨TeAnu™F£ê–è°ù’e£î•’Nšwu] .}&ûQVB”nHñu?šƒDÝv‘ªêÌÑ`º¢åöÍqÈaãÁWók‘V.0nV'—²Ó Ë¥.Ž‹eIH Eœî³¼Ã*×—šDœ †~>˜–?†>ì©Nþ-ÄêÏ7|Už^ à n¸YÄìg‡¤Ù`™TýñG1€øñ?éhÚú‚he·4ýÿõ6  endstream endobj 2241 0 obj << /Length 2206 /Filter /FlateDecode >> stream xÚÝYYoÜF~ׯ ü¶úäá—…›Åb7±Þ#¦HŽDˆÇxHz¢¿U}ðêˆÆêAdWwWW}]'‡z·õÞ]üýêâò­d^B’‡ÞÕÞ,&q”x‘Œ‰L„w•{×þ¿v\ùÅñ¦8¶Ý.àQì¿Ù1åçuÙ”]ÜÊOû²mÌÜ»¡Ì‹ïÍûÏEU¤]aŒpNØîÃÕ?\]|º` õ˜q8N’ˆF^V_\ ^ô=JD{'½ªödóòÞ_ütA­üt®G(fz OF ‘Q!Ø£ÄiY Ç£~‘µCÓ—M_?£ri…b]¾éŒGB‰J€¿f°×Ëô~ûû².´&N„Ë·"ží BEÂXxc$QÊðø…*šÇ+á·Gó¼Õ÷yچС¸-V6·°“™‰÷Eß™·þN¯å |Õî„òOZěʲÐ"ê·›¢?íH]ØcÓ6ƒþÙL”IÁ¢#»@Rîÿso—¿lâX,T¾K‡¢A‰Uè§{ÀÛ†3°TH(UH£Ì‹ö d©ˆŠ™Ûw—ÚcŠ*=tEŽƒÈïÊ&+ Ý/Îø\¶ƒÝ2Ó-WÅÓâf¨Áð ³voY±da™–Ù„¢·"´¤€Q¢‡K¬À.„ç:‡ˆS"#ñe±Ñˆ­­Z5jÕ¡>54O«6õóÂ2T½5> ÖEjî’‚X Ñú# “•S,œ2Š“´ŽH"lp ª6C—º× ‡~ts‡Œ¼Ž à>Püö<ë2!T…OzcÂŒ7&tå0±í°Òz#,1ÀiÉÒÂd¦Nw¥ùn±…=ZÎYy€H¤×––ïˆFÜÌímmfç†ØÜÚ{˾mÍK þ fò°åŸç.¯-9Jü6ˆ£™<•ý n6Å~w(²ò*¤vÌÂ^¡®yÕaWkìb¯&k·-0ø0L1š:—‰±X Ró˜,æÖ»¡íÌ~GC?hÇ¢NK·òì”¶Só‚YÄn*-©´ûR“逯K*”ñÁmÞâÛ0·aÉ“rnóĆä Íê~#ÄòPèv=ížRP2µòO^ÀŠOZþü^?ŒAÁÉ]Z <á{\’2ûâÞæ‚X gHðbÐÜ/‘5R¿•[Ú ‡ƒv(€UC&â™—Á j›ÛÀYX}ÆV m¨§;áÐÖ€ì_M›Ûq&5¥É|·“–câÒ®Ó8µÇür}(Y˜dh¡(lä"œÆXòDþK¸²#ÀyFüYßÚ<3°PWNt,ÕàÌüïà~…V&ÿä=)J˜ ¥l¾R*¨½¢ÑXïóŒdm³ê|ÅgåÖx£ÂÀnÕ€[7# „+ƒpU–kbJu&tú7ƒÝØ´}ᶦ–¶evbfv¯‡ùá7–CWRðmw¨s]¼bI¤’K³ÏÚºN»)Ù~ü~§”ÿÝ”_ÛÆ†‡Hù¶¸ÚAHoÍtÅôq¾¦âOL!dCŒtmUf.ôtn¿y« F7ÆÐÀ>?ü†f•Ö€Òkk.Œ+ —¸zj£ÙžÓfÀµa H€-Æ$I¶Þ'Ö&h%’še«aV{ÂtP(¥4¹‚‘"œ1ldÚ F„é'‚ð²ÙˆG$JàOo‰ Üd=ÑȤY68’2`9*wàH¡;:—Á@ÀjêÖÛÕšeÿ÷úí½Ÿ<0žDahÀÇ»Ñ"Lˆÿ“ßmœD <·pC‚r\ã¥ì̈—#¼ÜˆGh;ëT”'^‚ÎŽÔ¢3Ça°Û—Bñ%~´îŠÝÓA„P3x*šž§iœãeã¬àÞëâ÷ºŠymªŒ4ϵAÄx»DôÝ?-Ü‚2yצ>YD~,_Òߪr?¦>…0›@Ab2Ìœ2ñyµàó²>7ÒçéC÷%Û×g~…ÒeSÍ­ÉxÉpåDá>ÁìÝÎ)'µâ¤‰·ÛLJ_—¹îÒ\HQ1lœˆÝA+¢Îà‹/AÀSÄ$,\½Yî×ÿˆ¹­ªJ—8à)Bõ³U-rØ#]-p½Ñ h,zÚƒé€Û¦Û`‰O…͇­ï$Æ‚Æ,xT¨0#èô‹òøß ÊXÉ.úŠY)xž›´†d}. “€9åÏ ƒhÊd*ëu­ðŸƒÁÀ$ö£Ëðëè»Ì®7®Ppe–d~mŒƒ‘„ã K×_d€TB—=HHÌÃ%ZWw®;ÒµP“»~ëVCyœÃ¸!X9gbÖm$8ä éF­ÖŸËª0­½‘IhŽ"¶ñMU¦ÝëÃ!*št;ö_mõu.X–`$¶*ó¢*vXg‚˜·i–Xÿ_¡ŠH<{½¡þÂã‚=—`8àwY±mŸJÄÏ9]ò§ƒþFÄryGÿz4ÁìgÁÖ‡SÎãðýq Ôï÷8ºÿ÷ØÖ‡Þ 2ö,( ´;lj?aછbüt¦Çx;8k9^9mFÁE§²ªÜ!æÃŠY„ßzƤ#È\|ÕwÌó¿²Y57¦Q5!£™ –ÝýÓüz2Ø­{ˆÀ¢ç}’W¸lW^èÙpºõìµ-:wkþ§õ@,Q Í¿¼Rl£GPbÝ#(yÖ#Œ$¬‚ÇÁX :±£ÓqUô­ê÷­ö@Š-z Å×=’³c``Йã‚0p׿o¡B÷Š#ñhÄ!~&7º ˆ.>V‡Ûo{o0Æã’‡v0/ÝpF:¥ø]ßúv< èí2Üðe~â+sä«¿mÿøaé¡è.›¿+Y™ðl£`‘Zÿ4 fÍÃÿ2{þ‹2°⦠Â,!ø;W({º–K‚›ˆx,{k™þ—XL\ endstream endobj 2245 0 obj << /Length 1857 /Filter /FlateDecode >> stream xÚåYIsÛ6¾ûWðHe"+IäÒI³M“¶“¸žéÁõth’9¡HE¤ìøß÷aá*Ê‘ÔÔM§>˜ ðv<>¼ÂÞÒÃÞÛ³/Ξ½áÄ“H4ð.^H½GˆKæ]¤Þ¥ÿ~F…¯6×jSV³9 #ÿÅŒ?]eEVÕ›Ù\øq•…]{»ÍRõÔŽÏU®âJÙ‚(EdvuñîìõÅÙç3ê±G¬:ŽBzÉêìò {)Ì¿ó0b2òî ÕÊãAÏÜûíìãv¦cDÀbŒhÀ4u@¼ ,ìLžïs’`„Yh\Îæûj&üúÏu™gɽ±´U5z>{â;i”# öÏáÉÑH¤Z HíK|ö†E=F.gD–KK1-P„£†`^« ÄsW —Ù•“쓳×B„ã0‘d.^eÕ:g û÷: Œë¥ĿՓq¾Un¡\ °¿Ž«ênÆ„_nRËâ 0«E¼Ré„ŇˆrñU›uÐyë‚| ¹ÿ»NѬ¾é,Ù -PDˆmˆHH²?0ñœ ðt[¯·ue}jÝ®òÔE#vÏÏ:¶e­\*m¡þ| M²bYiÍÞœaDD!þIáR©RëxN Z¯íN˜q_WȰâáž]Üd•%IÊÕ*.ïFY;²rËÓ±! ŸÖxŸµ¹À63ŸÉn”ƒ]è6Ëùu›åjiê‡5rNàS"r¶RKý"Ïâêù„:ôÝõ¾(H†©ìuôƒ@¼þ¢9âÕ:WV‡©‚KoütÕcj j­¦d 6œSFL—-ï³´R±%½&+ÙJ2ˆ€0Ó9¼ ˆ³ñ‘‡[ JˆM7:úË¢çû¨\Yþ%þ’­¶+KeÎ8s¾é·<[¨¶ØèFD±¦CéÏ€ëÞ¥a"4n:ï«cEá±$ÿk¾5û8nÐ8~˸ýgUŲ¾9ÚÝàp}Åvm»ë®l׆ä:‹¤nˆ’V{çä¡6ÑmúuÂŒ2w|RÞn´®Ö,¦5»ù\-ÔF‰rî•Ûâx$ÜÑA’äá c•p-­ùg” f:%óqÚvôá Ô.ê ´?pBR<ÊÛ -ãIœ”`<ÊÝc8éÉœâdΉïG¿ÙùÝF(¨!¡ëÅ5242 øÜ´Ã ‡šÔ”jSÖ‰¥ÔÍ»~Ö kó)kZ°`®é²‹$[ǹãØV€&æ`­_;j›—¡Ð)©¯éçW³@ø/>Ø·÷¯^ÚAÖ0h^›°*Óm®q>‹¢BŒã³zi±xi‡%Ù—«¥[]©¸?Ûµ=ûaXôÁ&FPäv"Ï*÷fª:á{„²@诂1¸ïC\ÀL$lÔØO@vªªômÊÄer2ùpJ…Z4T6Çp©ôÛ­Ù fXÏí ÜØgU®”5ý‘kdnÑåÈn¦;ÜrˆZÄ[0ÙXátߨ<Ÿ[8|¯ÅäΔe^^Û‘ÒÆƒ§ÀÌAr×v”Än*)‹:ÎÚu'æ.ËÓyëÏiEÍ©ç¶-ÞD!ÂÐìN’¦6Ñ6O'$ Ä£–àɤ“èj‘Nˆ‚]–-º¾¼šEà@ z· \pÖzŸ%îvUÚû½¾â¸¶á0%C/Ú¨I¼r 7n±-<µJªŸNz¹Ÿßl¼a/õêm–ª´ñº±Ôòe6œY¤wùý¿DLða©i|‚Êac#ÿñ+] ¦¶’@үߋЅXLÜ‹¨É›b»Ò¡uCˆ¦Š•(’Ñ8K×`HFdâŽå¡Ò¨PŠð©ûÍ‘ìÒ×E0Á'öH÷9°„B*ÿ>ºÉ‰{°f|Ï¡“d|ÏÑÎß¾u8¾Â=™¸§õÑîs¾s?ºÏ‘ÿÂ}eÃûhBÆ÷9ðõîsàÍEi ÞÞçPö]Üçè³öÞçPž FhË‘~ÝwŸµ²õø@¶ ÀÜ3ðcCÈ-R0üƒ™ó]Ü™fI=‚§Qùý”w¥n©ÿŽwñéÜäÒo¡éøô 7è4þ¢\ß5±ôÃ3Hü(ƒŸ<ŠûãÔû®Âº.·äã_‚0wðÁ“?ë4!Ä5P„pýã3¨ÿò&^ë_wgº_¤¥Â\>ø{6ôªK;·ªÆ¦ÿå endstream endobj 2161 0 obj << /Type /ObjStm /N 100 /First 959 /Length 1805 /Filter /FlateDecode >> stream xÚÕZKo7¾ëWðØæÀåHعs .¾AMš|óª²&È[¶þ4)Ô·¯ªø&o]@- Š«c¨qv ,I]ªéÕ‹¢‚c0ΣÇ2ö–.Ó°FüÌÙ ?´OY±½áÔZú¦`Í Ô@•~ÃfõJ8ôkäªY ’²8 EÍ×âàÂÒ×Ö R;¥0cr`‘¢¾_ÃÚê ¸ø­›½• -±{æN¤NiP"h)¹PNN¹¡9YP¡²G©ö.s­ºjåæŸUPÕW`'5sØ…•ࣜ˜@4¥¿£)¹,8%s®@`·#ü‹`sk§ ö-8P®XU 8WµP`Á\Í…>2w)þ„ܺ~îTœ-‡B©- ìRH‹¿Ã6Ýì ݤݭ`ÓÜW÷9U¡²ø[é‚s¨P‚˜80¶–Ðuj .`(Œ÷n!üW©øfðWåŒ8,Õ@àŸx`6ìUö~e iU»…¿µtWI  ‚¬ºBð´%쉵Tv1¢9t!ñãAŒQu;Âq°ë ˜bߊ3™ªë€ÔÒâéÓÅðúŸÓežœ¬.ëËß/úóïOþ^ ß®ÎþXž½IHñôvø~øaxþ†úÃbøyùî"¼A&Çßp­1Ã8ÚZÌ fQ3ƒïYxú4 ¯ÂðÝêõ* /ÂWç—¿ŸcñûÕIäH‘¾ß|³À_׿Exƒ¨¨ñs~ùõ7X/TÈ0XèäòÇ·ŸfÄ;£L*)Ì´Áx´:¹èz)`ƒ‘d}ÉÌOžãWO€'<Éú©¿+ý Û /ÏVï^-a“0¼|q†×ËáF•™_ÿ¹\ Ï!myrqî°Ö%¹5ÏW—gï–çW¸Ø?ûiùÇûãoWCw@AšÕæ}y|†ÕΘ:ãíÃ7ÝîÃî}„*wPéaG¸Š¿sîEÀõéEàš°5Ñ®‰š×D_¿­ã¾ÑÌI¢d Šr,ßâÑíÕ‰¢´ÝÑüî¯ãÓ‹åY¤8>PÈKk=*i?IžOiÔ€÷Í«rÇk·¶ ½tJvϨ` ЇV(ø¨÷±ýÔrDÝ4£TøÆmQ46 0LḮUbI§§“yq‡:Þ*iF¦‹—x¨%;õ8=>;þóìøô¯'QíêVžˆºŒ;Pw/0<±Í ­ÕvàRÙZk}thµÐj@«ÍŠ–@êè]zO¤Ú, 'PgZäÝèp Ô6‘¡[ئF ñ„º¿Å”‘ YÛFQ€l™À˜jLðó(£ªEo}GÑ¿EItÄÛÔ&f3·¦¶4Ñ7ª™å°n|7„[: „×M­›ksµŠÁû ² c*²“ €û¤îg¬¿E„’É3Kîø)9"Û>©ÍBOДÏÙh$ Àku0'¢]¢Qu>ÕôÈn´/¬nGöíx}Hœ£ÏÄS>0ÎwT›6±Úpºç×gìcþœnÆ|¦èà8G-YðŠwtR¢JÃl½"`#»WIÑ?a¼Í%¶bSbIîÆÒÔÁ±M·˜úp@´W¯sOœÞŽÌ}£ªÝ‰>¿ÒyPôÝ:ºßM2ä&ãzÁ/Y“Ð:ï°VÝ;Wý¢¬çªß“͘«Ò0mÀ©0ú«†61þ 7ú+{lô׌ ÈôŸ:˜<üúmLûÐßo÷FÿGÎ1Ú‘ct@ŽÑԣ͓&gtÀÊL³—Ò[åòþdõKv©‡š}G²ÒÉJëd¥Ï’¬ì½zÓu²²–ˆ¦õK%ë:×É:¦Î½ÉJ65bm¼¼n3e34Ø6Îè/‰ë>a½¬›a½…ó2ïÀ>?x*~ð„iy›©¤«ÕÏ[Ìg1«¤fµ‰f¾ƒ¼Æ.k¢Î -GŒD‚ЍËV"~ìF‰*#ÎÊ: ¬IRGÕ¹·QÒ41è7ý2°ó)àÚ¿ôeìföx·iûGïÜÑpG§âŽêØßb’†Âd·@ç_ª¯½] endstream endobj 2252 0 obj << /Length 2430 /Filter /FlateDecode >> stream xÚíZ[oãº~ϯÐ[e æò"ê’¾t‹“Ýî9½àìñAr…"ѱYr,y³[ôÇw†ݬxhÑEó`Q#r8óq83†zwõÞ_üquñæ]À¼„$!½ÕÚ,&q”xQ“ Þ*÷nüŸ\új«öu³Xò(öß.˜ôómQM»_,¥Ÿ¶E]™oïE®.Mû£*UÚ(óÂç„->­~¼¸^]<\0zÌ‹8LˆF^¶½¸ùD½è?z”ˆ$öu¯­„1­ìS)‘½–àºþÑYJ33qÈIÜ‹˜ÕÛ-@E,(‘ A ÇfºÚVoÛÙ‚¢°ÓÅÞÁ2/€9ël³¨p}aŽVsf$ˆ:q¾¦¡ýþ4“‚ý¢MìçàHœð~a ÄŸ‹RÝé0àÖüïȪh7'ç09Ÿqcg3tÎbpÖí¥]ÖÖµG\¶:òE§DîF æþ¡hvejŒAOÑ¿q‚}p¨åôÈ¿ëSà d¬jÌZî5w3ñseÆ8¹_Õ­itY¾2kÂ@ŸZ:1¬ÛŸùn¨&ô>ÅÞÐ,9'á܇-œ¨ì³ÒŠ@9Tƒ` #s=µpIô0!Ç´³´êt¹µ² ½šcà’%ÈUn‹Êà$zçÓQ=‰ ]TŸËLÆNÕjÃ(œD‚O|œtWUkLAl°-ðc—ðâ›ö6Â-• OdÀØåP&]Pn›9~u±ýºS¶¿X賑Ê1N‰À/îªÚMpgºm!T»Ò2±Ña9”³I·Ê¦rÌ,JeÖâö`ãbŽk*Ô°2ëö¤Õt|†—EÚ\Í,&œôX¹¾Ì&HKÛiL¯¿ ¤é°¹œ»exÓ§=’Ï}/z½êêaLBHgp4ˆ±à=xÐ7A9jºM^³­'Lyr)¥&—ð&!•ÖzQh?@F€ô=AxÙà-„ÃqzxG„ÜP†QÒs„³´éÖÏØ‘2`Ù½”nÂŽB{v´Ÿ.ƒ½©ëoTk–}÷ú­½Ÿ=0ȬÑPàñ¾³S2¿Ï5ð2 <·p$可KÚ/^Ž`ðro¡°@Û×€„2Œ¼ ü÷ÓÀ‹Agˆ Â`‡! çBñ’}ôTÊA¹ B÷Ÿ+·Î¨‘8•p× CJï—ÄTöKWä¶‚=ؘêõYÞYêÙit8žIÓSÕp¾Êeî|üÂñ›mš½ŠA³IÙËœ·V~·¹½qXx×ñ­+|M½Ù»¾¾z•ùNb–1pØ:’r‰‚;œw+7¹’ÔELbØö†J_-ªmªÏxöS'/çN]Æ…=O¬¦ÏÀÕ'æŠà,‰Ÿ}-'ϺyJˆèëÜ7s¼†EDç’¦Õ ˆ®Ë¿fx@r÷5ÚrN&OäÙLê2‚IÜ1ùd-ƒäà”Gź|€ i‡³1K‡ýÂQºã>¾è36&uŒiÝM_ý±³V &ëz®÷õÖLšÇ¸àŒå&¬ôÃÛì K£Ÿ;[ÐÞ v,Pî7 ƒrZvL^›ÑÌT4¸Æ°}R˜9mì̓œ=Žù¸ì›fæâmxÈ·HÀ’HÙR4LUiX¶âo”S0 x0CÐåìÝãŒz$¡¹ÅOã¥BJ_™Ñ¦­i‹0†f®ì ±YAþ{¼h”~q¶Ô`‰ß–::Gê¹J‹Ñ!JŽuˆb4 éÁŸLíl¿vS»m°eM´¤Mq·Q]¾è ­[è3/vY2sO‡=ß®¸kxKþð]ã‚Z¤ûÆÑRKK+ó,ªÖÞmíËahoÝJÓ˜À‰•ÂMWÙµÚIÚ_“»bÚºâo?«»&s×yfŒûÿ7mÿ 7mÿÝ[„ùë‚3kŸ]jðÍ ¨xªjÕþw“ í9ûŸ›fÿU fwKƒ…ƒÄ¦]Zõ@ŽN͌ɩLÿ¨ˆïA endstream endobj 2257 0 obj << /Length 1731 /Filter /FlateDecode >> stream xÚÝYYSÛH~÷¯Ð¾ÙUx2·¤¼lå0Yr@ÞT¥Š–•eÉH2¿=‡Î(¶¶jyV\ä3[r¿Hb¡ÐÛ˜ƒµ [±T’›)ƒ]`WVÍØÁ‘ßœ;>Ü9w‘2oClpËÙ²¸ƒé mž]ÎæQlÔ^clzpÑË nšÜjô‹nΨGîõ&;‡V\T1Ñi>.‘’|g¼î9K ÜýuHH5áºwðŒ a[ªc#’>”aŒ!OZˆ’] £5©ƒãé_'31]*ÇŽÕ6þ2"äK—4ÛÃ¥è›Ñ&º0¬wî2NUifySͲeYIçjcÚÑå̇ݸ1_fì?3”¦ïÃÁRqûžíµÚ‚Ô´ã´ŒŒü mÌ*2ãefÆMzAÇÑ6J?+4âÂ^ˆ‰º>ãöõ™šR+.æu¶µÎÇ2¯îÒ?l…§É < îÓdÃâðóÁ1äÃÑá‡ÅárD&œDv{®[X}ûð „XˆŠ•û¶A-³lÑ^<©&ë8ÏÒM”Z¾1ÜmÅ(/þM¨½§úd±°ÿŠyr4éõ6(ŠÛPaK¶{–ü)Ö7_WÇÜ“F}¿S»(Û%³€K öëB^çªÎîð>›ä ÞúÇÜæÒð 'àlbºj„£ªŠ}šX¬<~šä–×X‹ÈåÎŒQê`}< ï]TØÏ‹Ÿ–¯½ rUG}‚}:-á W_çwvFç©þCQ&áùlKÈŠËb@£HúH=…$òù Z5—ºy>¤ÃUBTSrEQltR†0÷Æê’žºXŽ•”µ1Í‚ÄÖâ}P€`Æ ÝjiÙVßCÔ‰9[Æz›ååÜN®Ûü#CQ:$b9OwØüÚÉH¬öC‘¦ˆ7ÿ¥ØÆáÙ7Ì8”ì¡ö‘ç=Ká7>gµÛ”Ûëð\œÁµ09ÛBñž_ h—°s½–Ëú:Í%GÒcÝzá×íÝI ¹M"¯!¨JûLâPJrÞH{M=Vûzî»Ú«\VOÆkßÖîùõvw›íϳ€ùíºý´C”ý‚Û>øÆàgOªó‰H]-ztúê*ØBYUÎÔgû1Ň«‘äþ½ŸbTùhú6Eßô>-⇠endstream endobj 2268 0 obj << /Length 2812 /Filter /FlateDecode >> stream xÚ­Z[sœÆ~ׯط°UZ<0\O^¢XNJ±rì#ë%e§\,°%°Véߟîéžá²¬lËyÑCOOO_¿i$Vw+±úýì×Û³W¿yÎ*¶ãÀ V·»•t"; ãUèE¶ËÕm¶úh½]»¾•·Û¼­»õÆ #ëbíøV¶/ª¢ëÛõÆ·’¾¨+z÷û¡Èòsßäežt9=8¶ëÚÎúïÛ?ÎÞÜžýsæ€ bå¬B¶óìP„«töño±Ê`þ•°e­Õ~åü–«gÿ;,¿ùµ_Øn qUà¬Zxq4y3œØqìØ÷]<2nï[ÈNëĶk»JÌ—ï³ú¸ñ…°.ß|x}sõþöêÝ' _ý&£‘ÖÅjãz°Ô' Tm¶ÞHßµ:TuŸ€–Á}G“ý}N0Lƒ3 ™E­jÙ,ŠOŽ,„õe-јk_XözÈxº]ÿÔiR–hò'œr,Zw¨xÍÐÈÐA±OhðtJ´¹ž°ÀO$¸Æã}‘¢Ä÷¨%TÙ‡ÔAg©Û/àAÛÖÛË×4“%}²?³‘›°®vB÷˜ÖºK׺¾\¾uñžöuv(•/ä¡YÒ0RÏGĨØ%aŽéŽ^å¹Z[UÝÓ@[ƒžjþeî±Õ%{íRiQ)½Äb04¾NÒ4oúŽ™æûºÏõøŸµ;ätB¦ØµõžFM[ß­7@Ñ&{~ÙØzĹ#_·]aD„üõ¢€‚e>yƒÑãºvCHq4¨Í”èÏÅ„Üâè5‰>åC“tÝcöIøÂ?*û¬6žðm!Öu@kúCLLÌ«,s¤^Õݶ&+ìµõÕCÚ1ñà–Ú´¡KwäH©u^“£ôSö[-D½£ß´®> éÝÚÑö8SêÅú([¤Ë{š©°u›iîùð}?eôˆ.Z·ÿ™¦Åï°p$¦ùN©‚ëËC–Úp¨ÝbΙòd …b%·Ê:‘Ï¡y *‚·¤"AŸ˜ÒøiNî25ó‘N @Ï›ûì|8P>«†³Xï "=ŽœhT:ZÊyßÕÊêJ2üö÷Ϙs¹ æÊ:MT@+JL32ÎhÅçÆ,9nÂc† ì"ó´Ï™b»–*Óë @nc9H²8MH¦åg–TÑN­ÛQiÒón€^Y‘ö§™I ´Þ73c|nê¶_à8¶çÅn@SèCݾâ(†“F`ƒi´[´ôjM3 E‘;FCTÞ‰´#WNKÛÅîCãDUªï¨!`ˆWAÆ8ŸäæÐwz¦ËËÝö`n€ý€Å‚ kõA§'“§²¢tT§ä©® ùhÖ@Œøãù,qIùœR¨(ÁB&"UÞœI†€vTfhšC­.ibà…‚¢Mr‡'UaŽ‘ ã«ù¢­²‹KÙ•”7%Ü~èê¹sd¯Å­Ò’DðœæâD4KqDD€ASÃvODxh26¼[ßÄhšai’Ñ" ͶdxÜÊ’²Ã¾ažD±“ÀÄøÖÅÿ–.WÁœeÑóÆh·…d¹eÔ‘W˜2ð x:˽<ö¸ˆƒ~¿/syžÔ+Ƹˆ’/Š·œ|½Øö†, õ\7Ÿéd )ÀláêÆøŸÇþQgit½„Éìw5št祑%žp2gÀL t˜ÄæØ2šU÷÷7W^ÜüõÉ‘Þ/7o.®ÿ\8UØŽ úâñ>Wõ8v™Á:ô­¿hBùK¬¯¶±\êà{ˆ$ƒ)àœ©®°É@÷595=aíŦ€&0GÒªx+T—”ûa ¢ÄÔ~ ê'%ðY&:hM? r—ïÏuâ,8ÃÅ+¦?}';ô5ÞFý•Aô’áJwg.‘úeQé •ÉÔôæŽø‚FÓ¼› ø«ÚÐÌ’ÿN3ëêc}8.'á„ -@ÿ~LRlZòµ †u î‡{«î&hÓgâÛñl/ž™tÀYÝLµÚEÔ\Âtrí~,Êr©&ÿÌæÚM‹¯öêÅàªãÏí:@¢#iôEÞB`´ Ü3{jäÉ[[|ó¬—`šp#,rômÖûî¨Ï£ÂA”`W…z/¬éwËëwJ‘=¡ýœ‰QŒ÷yPvWXr['šfžmÎP€÷4KŽñL20‚‘08®fÛ`øÖf©ÐÒùÔ ŒÕ©äÝk߸“*2lÙ„1Æ&eo*p©À(éaé&ëÙnìL‹ ߯Уàª2€Ë¤š£¶dÜbÏ« ò{xÞµœñµ8N{¦„ÛSàÎ\óýæsm˜[SSd“× ÐçÚ‘7kµN]2õ÷¯`¨v8YÓïØí0ÿþê’f Æíø@>·:¢»¯%¿ØòòG¶SO)¨îöÀK…qáüó-¾<4˜#©ïÜ05Èp—d´“J‡§ºèd£bÇ÷ÈlC¶™à],I(~Çý¦Y5ÅL·„Rcâ.e-4ý,åñgÛfVfSŽÆÂW_¹”¢_’ý–\ ®¾ÞÐÜ϶þçõ36vŸu3 ™ïY/3_Y#Õ%æ©zöÖìHi½ßó×ÈÈ:&Sñ\lÔúƒh`ööòW•þ8‹µ¼Ë§ü¸ßCôćÜbôG‹©›p[çXèí’a$¤Ê¡_aZ,_5 ÜÓá"ùLIrµú¥Ð–qÙ2R{ž‹ß‚é„RŒ¬¢ ]m)ÌD—S£Nh»ñÐPÈtù¦'e))Æ– 302–’b:õ1ÿgÊHðÍÿ+sü?>ÀÂÃåî¨E°ÞÞðŸ è(ž=$Ó2wœp.ÔÿÏh@Q endstream endobj 2279 0 obj << /Length 2141 /Filter /FlateDecode >> stream xÚµÛrœÆò]_Á#[¥ÅÀp}t,)Gq"ùxU9uÊq©fa¤¥Ä-ÀJÑߟî醄×ѱò²Ì63}Ÿ¾a÷†mü|òÓÍÉ» Ï1b+ÜÀ¸¹3B×½ÈòbaܤÆóãÊõMÕlUSµ«µFæû•ã›i‘•YÛ5«µoÊ.«Jz÷ó>KÕ)­?«\ÉVÑÇr]ËY}½ùåäüæäÏÈÛ†Cä<+´C#)N¾|µà¿¶%âÈxÒ» à "xæÆæäß'6³nEÄLǶl’ë¤ûî"²G›d ƒÞòP7(UUßÖÈäØf§y퉼»Ñø°°@ikÀû>ahk•dØÂS¨&;0»¢…ÆJìèïv%ló™ÖO»,Aº»Ù`§ªùtS%ªpJÆ’1¤­%â{*UúýƒD3é¡™Te©’®ÇTÍH6ªÎ³DŽè§hG`.+ X5©jP+ ‘‰è—*kdÙÞ­ú C4vX¤û¢¦ª( ¸Ï ÷%=3––wû<§U£Úç2é×®ÀH{P6pØY3cMÜaízV þµvB+ìÖë‹eŸˆb¿÷ äù–Ù=î ¶ãsá°"„{€µìvÕÈ–wí[mN€Ü­<ÛÔ`äˆt5Fùñì'‚hCUWeËT·Û+ ƒ"õÞ‰"™Ý§b\½%}K UÊm®ÒÿCç-é܆ñ óí­lîÛïè;†ÐpDßèY²“[>ëá ;ŽÔ÷ü~_¨²k­ÕZanØrí#OèÁ¯F¼~ÖÒc–BÇÑLΘ8Q¼®µf!D+ô¬À|LùcÁ&Ï¢›Žh:cA€F‡3ÇÚ}=D1í™/59Æk[`À'€ÏÀ!¶ç@Í6ÄQ²¤«ýFàuŠ ¶ aE;Ž[®åMI¼š”ñeíÛ¶y~õûåç•o^_ýv~usL¶öb°¡—hÁV²8#þaûv?«±Ò$»¢js5'J€Vwôü8BF¸yÁ³¦*Qµ|Ä,, ^?Ò¸ŽÄ£öqx!a÷"¸Ý}  ¦àS‚ÀÇÆmé}ûŒô($¨¢ßW%È,‰ßL&]F¼±hpø1“ô’"@~½Üà¡›ó«ÛO—g|²'?zyq¶¡s,$%€s3aü Ša^z„ê$EH4äI\kFq["ós‹=ÉÏoXC[†V|BjÅs¿o{hæ+¯ìÑÉ4…³­b†Ðq´¢zú:2Nb¨gCÅäJ²Ù- ´´â¯ëþÀDOU³€]4*~dÛ>Á„Và 1ú¥æ1Œ’ßã“3 ûEŽánˆ€$ÒoB‘ÙX¾d˜›p…ŸÙ}Y5˜dÖ~è™ïËÑæ™¶2Ó6k[Sú WiEϲ"¯Z‡±^3ÕÙ cëZ†«öÏ7×S¯Òrî|$épµåÂÒñŸ»¥³Cæ÷ ÷3Z,Þ*îÚ ×›€»9?ç¾á×Íõ+â-{%^ýçôÇ2¢?©3þfFtcËý™d ¢Èè§[ÿvßeùÑ| ‘ÝýçÈ穬¿ËC`ÃÕþzø–LŽòà9Vp0Ýé±,ü#·|Ï ¨ q…†‡¢^DXõwB¼ÍX6þÛ\bG«x`ØrÞèc¼ûï•6Ùõ§ ¤ì#Åÿü"Å›‚¸ ›öËBª–8äÀuŸÌfµn8xhƒ‰BɼX æBié ~ôü( i­?´ët‰¦c…apèZJY¨Š`ÿP†‡¢7P|X¦ÅâA=wÏõ"ÍвçÕR><. ¬ÈÆD¿Â{w½dJl9¼WËúÛYß „3&û ýz.XT¼ZÖ%ç@‹ÚÁ«QµwKü{ §m±êd»£Þÿ¢øžåˆðÕêû´Dš%1lÁ4º¦ZÇóØO‹§ÕnX-]æ"óÁw™/>¦­þü¢Î[}t&j÷ç^ õ‡3²ìKl¾Ù_IUØQ,¸ÞÔxa‚oEFt[M»öy³îârÂÝ[4¿N ÷Íw_ÔbÂrß&ŒŸo>|¾ütsy}õšJlàk×  ¤ÏuÙûD=¢žêÁ¾£¹°Ö]#;]G㺢׵¢¶áÐ'ÛfA[ ™•PÀË2Q¼Ÿ)ù-ý×å/âÚñ†gÒ{pœãºÃø…YKzÞ¶|.i”ìTzºÔU¦<ƒÂÞÆg™z*w¬n¬ÇpŠ×Z2xjaà™W2íßÝ5UA«÷›——´¤  GOn0Q-¼$^q¡y¤µ¤ÇlRBrۣǃ}IÔÏa½†È3&=åwÙ" šÉ¡Amðüµb'x{û¡Æ0öpèO9 }sq†ñ={n4VþžŸÄä¾³/4³ŽÀ²ëTQw¼I·æM¸m°±ty(oƼijcí飺͇EU÷ ‡G.çù/¾X{à­èµ:Õ\FˆØ7ÿÒ’=õrˆzÙ.+qúº òFÝ#O²Isú*Ó*†Žøi§€™†üĦV¿»ÀÛ}‚ßô¸{æS c%ƒÁÁ^.tùçщÜÓ'œ…M.dïq|–7ëG(xŒnS7e™GƒèÁ3Ï}48Ð5ÔCÇN¾QwS×â^×.U§z/•]ßy £˜2 3Í*Ýçýly <‘rïÞwýckh^uŠ™ÍLç_Å pƒ¿ýQlñ;ž‡ã ¾{q"T¸¹æ‡¬WÈ%_\ü:ƒ#^|ôÛä{‚íœõÿFÕï endstream endobj 2289 0 obj << /Length 1909 /Filter /FlateDecode >> stream xÚÕYKsÛȾëWàVcÌ@íi³»Þòn,o,%98.H ED À µú÷é™é¢7RrÈEÌ£§_¿†qpÄÁÏWº½zûNÐ #™b*¸Ýœ¦$M² )n‹àsøëŠÉP·kÝ6Ý*bI~¿¢2,öe]v}»Šd˜÷eS»µŸe¡ß¸ñ']é¼ÓîƒÆ]}¹ýåê§Û«]Qà!h0¸N$N‚Íþêó—8(`þ— &îÊA÷n¶ù`Öã°¬7å!¯Üœ—Õ}•H¿3Çû¦ÕÅw0Áy¸^ñ8|Â#zk¼)?V½»o¸`™X¿Ë{7ªJGX¸£vz ,N ðEª&瓟¬ ÔHS"–à`«ö¡ØMSo/)—KG×°"!b¢b6Uú­‡Ã!ïºÇ—aÓ8ÓTåæi ÷•׸¥j6sîËØ®ò¨Ì[¿¹ê$¢Ñ4_Í=ilÛfï¡Yâá¯VõÕñ%à|xœÙÎýƒ~êŸß‚'DŸ øL"ÖñnžêΖmçò6LÔÇýÚ¢g)ªOà%ã¼dìൔ¾›ÏOàeN"g€È!Z^ÒM¯ý¹÷ÅÓíuÓû@P5F–GÃ.^àÚ– ]B?à[™'#Jˆ©öç9C0†IÇŒ¶+‚¶æƒ;ý˜Ù±¦Í÷DÓfÂhzrbäÈ©ÈÂ÷[·ndÖO¦€²L(y:ê™áV­–˜î1œBugb©™\®_vuX!Š<=B'uó­Ìƒ€WìLŸŠÎòlð°{]„º3aÿ+§*!TðÜ.–f@ŸÍŠz§PÞ­`jâ ð=ʬê, Ãz·kŽUáV×HÊ:\Åä9¾`„Ãu“{2mZ¿5¯ñ¸µnïê(}F3w.¯»qcíhêݱàEÙ=¼ÀŸ»í’Cs’òÁn]Ÿw»;äàR¾†£²‹•²O©0p&ÊîÓ‘Ç*SbÒ–ò´UÕ¤R£™Ø(©õm³„ÁOÍ|›ÉäD|~{‰Üžy¸™’¹|.™{Ó(t•‘wÀ ³N4:÷fèþ’ÿsgV„J5†Xûm j @#=U4£ õ¦k¾7FRÁ.Á{øÀ`>é àk–†íÊúÞ)‘\sÀÞÝRô8pÖ•áï‡ÆîE³Ô -Œ0Iï'žðúZ泺áÐ6Ýaò÷½Ð¼Á~_n¡³8;5™wy{ß}£ŒÏ²tÊòYíÍ +¬®¬Æ;¬wn´~eÍ*3X?áÞ9£y¹}`}83”"†½îx8¸16›c–'ø9dþæ1(pi•CXVlôò"þÛ//7¯áùì)½±¯^Ò°ñ“EŽ—Aé1 ÿ¹’1jmú¥ÀÉ ªO‡BôóR›E8BkÔ-õS ëÄW™)€ð4oþÐl³ÇlŽNhXÛÿèæF…&ÏR—Œ’ç*BÊ8DãË|ÁȯQº†“Γ[â“lgZøJ 8Uz ÜŒ6V0³]¿cÓì÷îÍ!1Õ¸ÉIe…w—#á&Â;íQÀ­JfuZ^™ "=1N9_˜¿‡¨FG,ŒZ›î¸1¡n{¬Þ¸]gMÕx?O]{GýçÑ݈½î(ñÞçwyá›§e:eÙ|ÜézÆ4„â{dÚ|¿T¶=ZUv§×›vÌ“KûÇcÉ+üBXж…îú¶1%êÓ‹½QH~›•ŽÜ> stream xÚÍYÝoÜ6 Ï_á·ù€YÕ§?öÖ®kÑ Ã°6omøÎ¾ÆÈ}³} ì)Ê>Ëç[“ìC€H–(Šä")¾q¥wåÒf†imÊÏHDiÂÒD‘HX¦ÀV’‡}Ó–¯2IØß–ØIÃ}Þ!Ò}ÙÒÄZ ­êMuÈw߬´ Ý’;dQ®Ð[:Z_Õ4›SCÌÐ2ö“g«(6&¼¾-¬!Á`:Ñs{xj (Š$oq“/Ç}Y÷´Í&¯IšuIÇ®,œ¢ Í4+eÂßñj ò;=‹òds „‰YòH(2Æù¨Fw(7Òr€¬×1ÉStZÔ˜é4&ž¾·~8•$ÒN¸tÆÈŒóÄ»bÃ6M½õ}èa@#°ÖŸr(¢*·û½uàE… ~.“ápڛ⸱n _vKh[*黆Ü®5œì-T#ð÷WE# Sà\V}rè+T¸ªÁ •ÒTâÁÈÚÍØ’ôDªgÈᔡF0E3ëààbÈm‚RyˆYÞÄLªb83"æI÷"–> ¯ô„WúÏãÿñöOlV">+D¢6¢@Ç¥Km™o0¼ßúâSÝ@c”²q²ÙU›_¯u9[ØöÉÝÞ•³^å¾)ù>Ã_+lŸb€rèQ"™LÀ–1Þ}qÌ•·ô1½W#ÍôöœØrII3Dó§,¶÷ÕnG=kL ¡/ŽX3CÛ–QYoÈÆ‡žÈÎÀ’É9w¬€ˆÜ&A9Ôk’Ê ¡ Z8×·åe§8@p~¶ïÊÝ 7îTDlzßqÈûr(TðÕê9~ñÕ›Hʧ7‘”qc.ÜE.¹P¤:õící(2ãUoøG ÛœšÉ3ʉ}FÐ3Šz ~{8⢇mo½ì"_ꓽ±·v#äR–ACí™K÷òÂþäG'IâícýÈ÷M ä›êY šîÿ¶ÿÌnŽO #…»IãN—³¢ Cb*i²i ¤µ¡B¡qÏ*®ÝÌž¶€Â?}Qö·6)ÁtÑPK†‘z¨‚íÐÀÀzðý°‚Ò/2sâÈ”$`áýmÙ:y'ÖGšfúÊv0ãåûYU‹’½«áª1»»9á¨>·V„Š@q†´dX£¬û¶t«šš&‡òCŽåLŽ8ãÇθÍÎ$’-ˆP&'²Åé/•.Q.ðtDºêÜ»,#Í u0ÌÀ°`0ˆ•…ïη°¥´Ýq,5`ñ'&Å8»t²­ Ѓì½Î×N»…»z[÷ßÉa$ŸÜ7íbVX>‰D ÏCøTzJ_{uʘŠÇç˜QÐ(XFÂà/-Ê^ùþÑüéß)©°4ßQUûÞ.~ÂqsC‘JÙ´/f‘v{¬7(X¾«ú¿6\¶L5ã©~ìY”öMàWR0-µè}Å•$ÅÕüE PÎêm£é"T€úÙãÅœPÁÆ´§æ…hÚ;zW!Ž5]þa®-hytf—øf¤ÎirrBiÀ…l«­+r·c³¼DÚ§=ï¨ç¸“åkóIyÜå;?üÎÐ3šÉøÑ¿ç-þ:§%Üpœ÷ ÉñN¦ñ<¬@¡•KhøÃb†¿!éì/–„#þ…ÆöÝ\ô?¥1P endstream endobj 2306 0 obj << /Length 2494 /Filter /FlateDecode >> stream xÚÍÛnÜ6öÝ_1o;xÞtë>%›¤Ø¶Øl[ïS²¤ñÖHSI×À~üžÃCJ”Fvìº ,Š<<<÷ 5|u³â«ï/Þ\]¼z¯Å*aI(ÃÕÕn¥DÌâ(YE:f:Q««|õqýãF뢽.Ú¦Ûle¯_oD°Îe]v}»Ùë´/›šÖ¾?•yqIã_ŠªH»‚^“’‰Íç«.Þ]]üv!€¾«HÂqšEëë¾›äÀY|ºÅ&*z×m†ô¥ìQÓ¡ $;ŵ'$3ÝÐóÚ®¢Eyà%|,J$ …7Z!Ž"š?‹¸ö‰ü—ü6¿¾œú²¢iô¢/d¬¸Õšfgü×5ì°W€™hðÓ«}iù¸C{K=¦–l̆p¾aBN~ÊLt†·¦v 45Tç`ÈAÌÞÀE`ŽÅü=¦¼í _…¶Lx¥´J‘~Ø0Ó¨C©H‡ðntÏ™ê`& ‡`Šç*ƒÉ%•Á´¯28lª2Äí©,ЉS¬Œ*y°¡jAyÿ•ÅHañ_IañŸ¯°ð¯«0@ÿ|¹²÷9*£TÕ…É8´&üTÓ&ÏÂÓaÖgLc–I‚u¹£U—³FŒáúí¹„º¿?b.ÔÚ†f‹I*:”†Hƒ%±nzZìŽEVbš/r{üpÖpÄ‚ºîJ¨Ï¶R%Æü$œ;!§yÃ-Ì_÷mQÐÔŒ]“¼¹µ\Õ6#ªQëYs8uN„jil AÝã„X±«¥ÞÓÖRy[›BçÎn{òùmMFæ¶&$§c?Ö42+ªÆ•ÎRë¬<¦U÷ ã”Ë]Ô“lÔœž—* ÓòoíèY¤Šo¿DñŒ±cS•ÙýÔé®ç¬öÎyS{vÙO+Œ¶Öyž,Æ*ëyÑ4g:7¡\k&lxÂ)›ô…;3“m\šç†!˜3,ÃÓ<‰žœàŒÍ 5â=+jé4¯Œq}p[Y—©9¥0?` ~o½•–êòesõzJ‡ŠÛ”ÉéL+e=³”±;Vϸ¦‚µÛYÓmƒ^wo,ØÂœŽ.¤w§,ƒ>mw²F®~¬ ŒÖ2ž|w4»8lGAö³—Gi{ûÒ»£´Ežn—o[´Òߺ>š€m±p9!€5ôE-ß0%#šï°H…CÃÙ¥U¿„xJ†Þ÷ìP€YLK×')¸<¶.B,´´‚ƒDæiö5sN7(¾mbÝ‚Qщc)C=#PÒEä3™As>‰$•0¨D$™¾ €¾&_µÓ)žþÕ”2e•^WȧÌÀM #ƒæt€lÆlò\lë²)3~-†œ rlzš–öåÍÞzÒ¹lÎ(0£Ðšñ,Z²Èï)‰OâvÑÙDèrÛa_-v¾`Ì»[êy§¶<ÞRq¯ò˜§¥ªõRSe÷’!'4P uËi R`>oé&ùp4D~f|/DÚÿ ÓP”ç_·Èlÿîÿp\ 'øPsDø¹BtÈ$ÿÔe”Rà6=’ϾÙíPEL$jr§ 2•hÚjZxÁ Ü”£j¡²=¤d`ÆÔã`æK1]h˜§«…¿¹cZ*™RZ¯¯O½-¥›Â’3ÞLCfTZ ÔQœõö"Kz¨HßM ³ùarllYë߀º-þÙR%ÿ€gG, 䣞 £³ÛPÉ“™_sw·ÌãÆU432ŽîÃ:ƒÙ Ëð>cùïX-©uWØ’ŒHh³{™£h-Y0~ι…¸,ñ äÑFQúŸQ­ftéš'SÓK¯/í½€1)¨ë|“RîXG/†+À£@qç¹@qÖéÆ×vÛØ\ÂË]ÙïghÇK»…tŽ€G‰tøý ûñů»‚ÖÐ4à… X¦;MÖê¬pÇÒÆÀ|q´´c£LCC‘£‚Ù‡,êêü¯)¸íð9dpžy)gÒ'ns÷ CÒtÞÛïçÇ<"$J&Âá“1Šß¬£ ‹ƒ3Qùf6ÿáD ¡B|òï&ÖYÅœ) Ý„:™²¶Ò`*rIs²þ­Ž endstream endobj 2312 0 obj << /Length 2554 /Filter /FlateDecode >> stream xÚÕÙ’Û¸ñ}¾BRÊÂâ xäm³Én²ÙŠ+ëɾx].J„$ÖðZ‘ôØŸn4Àkè9lWªò"’@£Ñè»â›ó†o~ºùËíÍw?b“°$”áæö´‰ä& b$js›mÞnÿ¹“zk®s­ÛÝ^FñöûÐ̫۬¼í®»½Þ¦]^W4÷SŸgæ½ÿj “¶†>“’‰Ý»ÛŸoþv{óÇ€íùFÐv‹x´9–7oßñMã?o8SI¼¹·På&cx›77ÿ¾áŽtÎPÌ™ B‡bs…‰ƒ¿~î‚3®":dßš÷åžËàÏ'Kç°ÑâùÝ€|Ä%–õ{xªPÏð)ħ8áƒeádY Xk@h”wæÓoÿÚI¾}M°*žÂJ©Àþ]Á¦˜±èòÒ¬`:ô@ïb³ Ĉ%ÊIüéPÒI°í.†^Òc—@Eð¢ÆIÜžէx™¶ÈÆÎ\éûæ8aÚÆóß¹ LF‡Ï±IJÎÂø™lélj‡e„ùuuô‡x&qs¬KÓNOŽ‚­V\oóŽ&îó¢ððô¡gÄTr‡ °U°D;èj‹“­©Ž¸3l× ª8ÞVv÷{Ü¥@&"ÀãÕ¤eÀ4´&¯Žy“0¥–µpâ ˆ·ÿ8ÑtU¯ðSÄ!‹µzBU$Ú†‡I¯È¯s_šª#ÌyKDk*´ø$v €¤÷H®Þ^Ý’ØkËd1²Ë®ð´oóêì =’©’[9Ы9[gâÔ|!N ¯-). XAÀ“äLé;/K“åÀ~'H£>)¥¶·rÚ|[“XÊ´›®(r(˜“§l4aa0بe`=[Üe@ Б½Jœ™ãO ^Vè¹5"Ö„Ò@(u³c3öÁäœ}0ZÌάA†Ú ×eý¾ïòÂ}æ!EÈ"=ø¯¾Áƒ¼o® ÌïÑ>5;bA­pü´ÖÂ/bʴʈ¶cZÑîÖaÀš ±BÆ‘Æq ©/ b”’[ž+Ò [(ZØRè9µh»?*W6¯.#×5Ti­ªÙøóì·ˆnN(Xìb[azÜžäK#\8Ç:†8é°.ä·÷«­RJZýKNçÇÓK+û2g‹zÀþWvºÖ¥[Pxx›#ù˜!É­ïHŠÜä+%ñH/žåÖréFäB=Ѐ¥ßúåuß5½ÛÚExk/52èžööºûPÕŽPîSÖ„zÉç IjnµM‹Î9X€¥·ÑûÀ‡IHü¿"’ÚÁF1p}µy™©[aÙ3xlx€ï'§’Ǩd˜. âôo9hõoîê„„td0ٻݶO1cœiÝBË Á”Ï-:ÓÐ/XG±¢YJ31&=ü¢’Sò?‹ÄGK÷§L1ãÎÄÙ¢ ÑQX¦XWÏr‘/ÄÛÌTuGùÂÀÐh]!ßÃ5Ó÷=Κ–áçéšþz¶2ßÐKè néP?é*4”\,Ó\µHs#°?­àˆXÉ1ǵÜ[ÔŸ¦jU)’0|1¦«˜/ón™°(PóXýW¨˜0X¡¹NUŒi%!¹Bœ·Š÷pá"!BÈe C î‚ ΦW‡”šF(¨Z¨šžÍþèTn¾À©¸É¼%à!|#° ß8z0kþÏóIÀ½šÒZåÔTê"{ÚfÆØíb A¸·¡%öØžªÃ$ÉLçA~<Ï3åu“âsõØŸÀóœÝÇÙ ³Ú¸CXiºC”M·LaáãXW˜l -¤c7ìjjI/!±1´ã,ng\Í\vå”À~ô¶æÀTø2uÔÏÖRx|³uWÝ{5òI¸.[öØÔ;s›únÁNðÜ=ê”+Û& ‚Y£æ Xüá¥,öeš;zY{…v¥Ñ¡n½1Ù,à+ÃË@õ$ÈØ4|›MÒ~!÷×CêÿU-—WÒOÅšøÿ=ÖÌ0…ŸÃd™¶oÒ®³ñ$5:µbB‰E(“AÀ¸Z”ÿA÷µ—ð9¾Pý.LBâ^_³–>~çš[?Àu5X–ÀdU`ºÞQÊKV&(“_k ~ÉA5“c~.êí‚KÃo©‘iã“=Ç~ÑݾÄjQRÀ p'¥7ßþÊŸØ…`>rQLEZj²ÂàÌõÁìÃB@ªx›ŸhwrÄÀZŠr0ü š…IOL§4’agF×àñI›ÅíCõ L'$kBB¸éi)6G‚ì€ñ+ëÓb¦ê˃?•)ˬa‘P÷™œC†5‚H¨AÅ•™Ú˜àè]‚G-¼ÇD=êfl€Û–M”¸-zd1𯽣‰1àøJð%¨ƒqp†IÀ)9ÏŽ¤¹z¦ËÔÉÜŽ’‰¤1Û±-ZWÜ™ˆÕ£Îø,Ǿ ;¶UÖ L«p^Õ`[ÏI‰ú™ä “£iä|>®eàb±€ˆß]†ëz.Y~ô¼ÃñE¿æþb@ä.-È}$7&ó{Z5â¶OŒ@”“ÞßCÎçx?êà-ŽŸæÜ7JŠ&~s-EšRèNêªõìɧ2ZäE—Å4ó>ã›\NëªoZ˜vönéõ%¾4_› tÔ†°ø„÷¼@L$/H þ¾.i¡ãÇòãj~¿‘YG|³<%z&¦ûÕ{ÎFgi'z¿bõ*E9¿µZ Ò,æC_¤ÛX?²•n$¸8á²îÆE¶m¡§ ¿ìåC‘¹ÚƒÕʆÆà‹_¹+fSW§‡Þ¶ÛðãÁ]ݫϨpåö‚SWÓÔSOÄhnØ™a;O†>$Û­®i–£!S5/(ùªònÚ Ñ~ì|õ_ï×â&ú^ç °{Z­ËoÀÕÖ®)š—s²ìXEî‰.ROÎxö´Ö{Æc³Ôå=Z¬Ý¡Hwë!‘ƒûÖ4éÕÝ‚iâAo"û¢C ]OØ“H®uZ‘Ij:¬zŠ^&ýopåo5–óh`>¥T‹¶ÆwëÆ¬„SÊ"1¢}YÙ³ƒ´èìŠ}V9([zw›(òï0p1iæqye<ÖªKóÊecÜk¨##-í‘«BAÙEå¶oš+ Û‡IËt5`ÅÔh]Plgqc%aR`JB=î ƒdÿÜ­•Ðx1&ç·«Ù> stream xÚÍXKoã6¾ûWèV ˆRoõ¶}d»ÛC Š›E@KL,D¯•¨õúßwÈ¡dIvœ(AÑ^l‰ä g¾ùf81 b¼_ýp³º¼ò¨ÛqàÆÍ½áÒÈŽÂØ½Èöb׸IO毖㛼Ùð¦j­µFæ;‹úfZdeÖŠÆZû&YUâÜû.Kù>ÿÉsÎZŽ/Ôv›ZŸo>®~¾Y}YQ°ÔØÎ³CI±úô™)Œ4ˆíÆ‘±S« à "øÏëÕ+¢í'c?wä‡ÔI‰MÜ]Xÿ¢öí.¯Üh´Úñìv_SjǾmW× o¥Ã>1wà¥CÌLd厈-LJ[âzݨ蒒:‘mqŠé=x™ˆ}Íõ+SÔ †øìAo.óÚ¶Ö^HÍwy["_ÑàAüDdÇõ,ÈrüþÛõ‡¿’wZÛ!w_NåÁåUDF+¡`FN :Ô0\†"?ËêÙ$ŒÎó¨”iWÔz¨šMµ58¬"ŸæÍ8Oò^¥F´LY3U%#v‹ŸfI|L¢Eey{ib}bè4O²º1*ÒÎJ–£_ï‰àÎМúóåAwö„lž!ðË]ýZVK];Úצˆ §9\£ÏÙ¥öœÌŠþÍ ’¬/Üla·Ôú–åâ5øI¹7€¦Ä_½å¿ Ó3%\ÖSø¯þÛ ~(Ň#»¯‰34tm?Ú¯§N¢™ù®oGß ±M%Å0aeIÖ§‡Æ~ž"gÉâz¶Ò)úu¨Ýaëܾ÷ØÜTUΙ12™è‰±é„jÈÝ€˜W¹jÓañpýŽºN!öñS¼‹uQÓÒÙ=Êb}*—ĶëD=êëòD`À/ßó†fz M¬OàHõ¼WS÷½2Tà ^?¤Á¹6LßCTÿê:У‡Î ¶ªÍ¤z­—5à‰ÁEõ`ÐçúÓF¬®ÈÜm9xÛèÁËJ€è¹1Ú¢åB†>ÜŸ ‚ûÁó89ý’›aßÑÅ@Dgzœ"ó±Täß•ØPâÞBjt†à!ie²°q¿4å¤Î§Íp£+‡»èx­x¦Æl›~2š7± ÚqkëªLÇ_ù¡¡“¡øt`óo{¾g;Á‹?í’žcSª/R(x±ù˜nü»zXYϧ¶ L¢Ž;7ë 3,ê endstream endobj 2321 0 obj << /Length 887 /Filter /FlateDecode >> stream xÚÍWKs›0¾ûWèV˜‰‰/sl;MfÒS[ß’ŒGÙV€"‘Ôÿ¾Žq°H;Íʼn}|»ß®V¬דOóÉå•ï‚Ø‰C‚ù DDþÌñcÌSpk}µQ`‘jIª‚ÛSͬ¶X)£9墲§…-r½w]Ó”\èÿßIF0'úÅur\û~~3ù2Ÿüš¸Ò<®6ç;Œ@Â&·÷¤rý@Ç‹gà±ùŠ?œÉg~L¾M qB½qèÄR_äBz‘†q½¯û­àå•7;B®»˜ºò©)  •cFŽä;V§{‘{&z*z8«ÉPËË¢Ñ˵é'-Íë ÔW¶­¢Ò/‰”¨ÔÂ…~o×Ýžo9R{:3äw•Í“EV$6‚Ö¶ÑX‹³àü&p\1H`aðÐüÉ5h±–Nr§æ$íq^TXÛ§¹INEJ"õ™KÌù£íR`/®"H³º"üfhÐ"íhOÎOg.l#ÔÀa¢%ÎÆpÇÏ0 ^' á|¨‚2\kVN¬ô“z£ _BróßX\ÕÆw\‹Ü¤‰ÎË(+eK†_&h`¼H›ó–cæ·IQçb(-Ôñü™BV >²&eœ\¨â ñЊì#-#§Xà×Ô‹7¢^‚¿U/Æ8+ҥ껡4Ö:©‘¤= UŸ‡¢hé—ÒÕάm(áýˆZ9Q%]@Êiy´ù#+A•tù˜þ3÷ž·ïDín°ìöjìpYd4L #¥]þ$‰x 9·y1Ôƒ­:äˆí)N›AÀSÃßyÍädÖ ¦ìr&Í&ªíÏÔ‰ 6˜HžhÊîT:Ëæ¶Xü„Æ—úEol¤!±øñQU|Ìà±%rB¬_{ ž‰fLë8}ÈÁ\FêÀ¢âãæ³Ö‘õþx2+ËZþ4Š ¿<šTKL+þÒœùžf®mC Å>tãó†ßÎxpJÙ&¡C&‰­xE÷ì›(dÙÉF1í=<©¹>(â´Mÿ Ûª"¹hïIV§{2ü›²šV“ÑU“B}ؼƒÉåø¶ø _}Ùí½Ÿûò&íš,¹ÈWl4CÖç .muˆªhnݱcOC?>{g/«b­×?vý7lö endstream endobj 2326 0 obj << /Length 1411 /Filter /FlateDecode >> stream xÚåXÛnÜ6}߯àCŠ®Šˆæ]R MÛµs³ØFÑÂ1 YÒ&‚WÒZÒfí·w(ruÙ(¾ÔN_ês‡ž9gHô´7ùùd²³+( p ˜B'sÄ©}/@žð±8:‰Ñéô•Ãä4)/’²¨—yþô™Cå4ÎÒ<­êÒqå4¬Ó"7c{«4NžšßGÉ" «Ä3†©svòr2;™\M(p ˆ"9=â¡(›œžCÿKD0|´n´2$”íOÞNˆåOúëP¼·Ž@áðV”#A<ÌáüÀ¹AWt½JAŒÚ–eˆ›£äq,¥lº IÌ(Õ§KxÊPÌÐï:8ŠúÃÅ^Íü®—c!¤“zÂ*vF»¾`;i±±Úu‘&éY@â0´SLCšFÿ›uÎÑ[ÁHêºÙk#ÄdOý?¸wx0ìÁ ˜u›À–È¿I;ÒúmÓaüÖ{Ôz|#3¬$dð ß³¤%ë¥oعcîê’s¾¶ËʦݸÔU&Z}ì<Í%³¥§Ÿ_à8JPô”ÍŸO >B"¹Œ/äùªNF¬Ã‹x•-àV'ù”æó××õ £I-d˜Z-lÖŸÏQÏCÈP®`„Í8¹Þˆs0Ï(Ñy4ª?-X…‹ÚHšÇ€_íìÿ4ûýÙþ›×3üËá> )˜L—+ON©mäbR¹Q]¹²0r«!÷…K 2i^”™.«”€àÒ1K󢸛%Êü%êʬéV.ÂòkZQƒÝ«®ið1fèG£‡³"NÚÀ©n×O³eQÖ÷ªJ··ÈÎùÎ4ó²È† °þ”–ß †éeSwv=Ù/ÁRaæëÝýÖ¨ NäUN7 6z¾û‚߆´ÿÁiN|,v—@¦_!‡[uµJëB$\_Ú$±ûàå¿£\Ô#(pKŠv(½10*± ZÅ'Âhþmšë›#þiše™æ6†þ3Í$–,¸iCvÛy.åÔ`ù_mfW p(( =”Y`h«Ë°óhϼ± ;¦DtÁ>·M W†!ö½m SWB–žüöâÈ‘ÓÃýÙÁÉM×` Á̶$Ž{Í5÷[óØ{Ëöà5CsGx`!´OФŠìËhÙ=4йi_õÀì³$×WëiYäY’ÛkôÇæ¦maô»Âçjα¯XÏÕêq\}<›ÙÇðëãÃ-ºŒ4W/}ÁÂWj»³¡ þÿâž\êÀ›†ú}ãƒ&À] xzÓ.>ħÀK(fÞbA—û8èü*Ç«Í5i‡KsWzæX4€äw¤1}¤`p„œþqÐlØá›ãÇ7=f7ÛlsÕçKÞÚ`<æmvøÔ¦È>"Çœ¶åÔýÕjôC‹rLH›DWURžÇùˆ-. 2ÒÛlµdÜõ¸-ÚïæÓD> stream xÚÍZQo¹ ~ß_¡Ç^´¢H‘pwAÚ-p¸äáZ#¹Ü¢z° Ç®ÿ¾µ#»^gÆ›±q€as4Ÿ$J$?‘×*œJªµQ"ªÄS•h‘žØ9^qjµ%ãžšj2ôÐ2^”¤"! Õ‡ ©Þ@ðDE`ƒà5Ù~†Ð ¨@è‰jÁÀÊc(ÀÕ-™Ì5€YÀRz &rµ¼6¼µÐ¼jIäC¥TK·Šu‘ js±møÕ|´aP«}c±l³‚E¡Ù÷x…4f0üê3@K&m5qu ‰ …v€pkÑ*²ö˜Ë4ö46ÈKâŽÖ)I!,)À[ïº'Ç& qŒ…¡…ÐÅ‹'©5Ìc)ÖXmlaì³´ê1<ºª{!>,똠·PÜ5µ2ê¶åšÑê 5&Ì¥ÃÆŽù÷˜ª%\7^Âïh4f7Hcü®á)pæc&O­Ã^CØ¿ìp$,Ò¡€–ð$.p©â +€zJU£ RmæBI9 Î=6x£ÂêîjÝ0œ&õ}‡„ÖŽ9f)lƒw!^™à§c;¸ôd•B¬È¸ac`sx>”Ä\ÛÞ.°½cV¸50Û[øES O°­•П`S/cP‰8‰‰°¥Ö%zTôHÁÛö­ÑÖb÷£/ÆÃp5¢Á%ÀˆåÍ‹›í««Ë›ôâEھ»]ÒOxŠˆ‚CÞ>a+ˆ¥Nï4žxzït<}ûífûãõÕû×»›t‘¶?¾|•¶ov¿ß¤·¼ŠùÞüï¿;¼x÷ïÝfûæÞ]Þ|Œðco¶?í>^}º~¿û¸'‡ÑöݯÞ}õ{ºˆ˜ ¯o1Ñ»kôo;wyy…Ñ.öú  áhþÜl_úåf<ÿýÃå6ÛﯮÝ]YÊÛí_·ÛþpAã!{%q×,ØG¸pFD'Í v‚Ófª ¸ïÆf¾NÛ¿\½¹JÛ—éO?ý?èÿáêòϹµob›VQGše3Ý©Ó%k³Yuöºäš)×ϵy™.ÃþüÏ%ø¨aÿ]~úí··axä,!–‚ðøõ>b#°Ð ܾ²@¥Ú ÿlçûg“5Ý’*å J%;Ü‘šÃfAû”­Èi?¸uê§|@—ú€˜Wé €Í{. Õy ·\ˆæÒzøÈ,A" tÙf^€Ãs¦²H`/ ÖBX‹/ ’ý^È„ÓçtvX¨ß Õ…aaå~Xô[ÚÖ2 4 uxdÚšÁ$ S¤!ÃI¬å8aUá^çB‰Ö#w£\"Ã(=óH†{F‰Læ¢æöU”Av–á«D-GŠŠ/Ñ…×ÓÉMŽ”µ1ç'`­ ”"¹0?óÎ…™î´ Â2Õ/k3©RÖÜT79Ê&Ql7#Ø-²”Vá1õ™÷5ËІºçQÓ¬„ç ?®RÏËMÔžKÀ‡r“#T¹x=D»ÈFiwlÙú}Ú5;Ÿvm"Y›HÖ&’µ‰d­M‚®É¶0BŽÊ.h|”¾È°Q¯1ÂÇgÝ$(7ËŠÜÒàxˆâ;uœs”ö_TçIèÊéPŽçÞ§ÞgàÊÝsj‚ü†Q®ßi‚4¦âïBMÖd¸î@(Mš ;ÈQ¦/ÔdE?AòíN.·Ñä 'âà#ó…ìvDn‚´¿Ê “.²ç¸j™x)˱­Ol뫲-Jï ¡ØÂ3Žg‘ój¾ôN¬ë§=•‚Pòy`0w|)›‚Ƽ·§¼i=×w¸è=߉)çúN|Õ§e|Ô¹xÕkP…W옣¢Æ±)„ìOÚ¨mYmѵÿŠÉgªã“ç¤ÒàŽ¢eN§9â¼lŠE†7¥8À³Øìá ÇqéÉ¢8;>g÷@ÅÙ15z6TÁ³Àª%ëÊavv`ÑýÏhñAñüÀZõëRˆ_5#£Òøç„‘±+3%tŸ]—¹ -øTu j£ñ‚Ñ ‡5žråȲç#ù3;Ç©ÙúÈÅV¸{B2tÂÅr7Óþ{ÁÁÒ„û9ñ´ÊAUéÄbûù‹­å){þòNز>Ò–ŸÓEå'Èá£ò‰ªÈëY¶G}öx¶¨K–zt þŒâÿb@À$ endstream endobj 2337 0 obj << /Length 2362 /Filter /FlateDecode >> stream xÚÍZësÛ¸ÿî¿‚¥™!|å>åâäêëÅNc]g:>J‰´ÅŠ"U’Šë™ûã»À| ’•GgúE$A,v±ûÛÅîR®óè¸Î/?Ï/^Ô‰Hä3ß™?8sqgž8w“¿N™7I«eZ•õtÆ‚pòvJ½I²ÍЬnªéÌ›ÄMVøî—}–¤¯ðþsš§qâ%Œ:½Ÿÿzñ~~ñï ì]‡";A7pVÛ‹»{×I`üWÇ%< '5kë?„kîÜ^üíÂÕ¢·WBAr—0ŸK*Ÿ:¼8üÜm–Ry3»¥.qy€»¥„)1¿s7ó\wrùþöÝç«Oó«›ëÁ‚¯?ð°§p×™1¤J°I–Þ"OâÝbßd9(Ïs'qž—SîMž¤-j=Vè+ZBÚ¤©â¦¬p¸)ñº‹øQ™Ÿ«4ηõ+|Ûº=ÛÂHJzwò%[¥-£D/™­äü"jplWæÙ*Kk2TÙÙªÛ”Á9 }Þ3ÿ1æx7õ&7?¾½¾œývuýay£Ìskåðú¬2´“‚F(Ú¬’D¯?„no@IP m5¥Rš}Ÿ2?àk¾3C% áí.]e¸\4ë¾ù†^êWå.û§ÚXeAF\›‘‹Àçf4 ×Úž]ڶĉë¶[Ú@IqrC°÷Ô†8¸!ys©¡›û¬^Kñ9ç“k Ùx«'ýázîå5üR|.F«ìn%áӺġu¬YÕ{`ìH‹áÙãº1”H»Óà˜ P ÞoGœPË*Þ©Ç¢{:‘ éïû·Ë©ïMÞ~9—ôe¸‡¡o0Ò“ÝH”·FÚÅuý”¼`£ 8tj=)sYt= ¾??'~dƒÊˆ;gÄ"3 òçë¬6@Öç Ü›±¢lŒ¬Êí6-’49­;ê» ÍXy±+Ï­82ôîÁNÊì2/… 3-ÖØxS¥o6êøN¤~Cµ t« ¯Æ §ÜìõŸ‡òH(µŒÐS÷¹vÕÇ …,œºñš´ª[é¿ËŠò;ÑÅ »dÙT}ʘD#ÖR~· 0©ƒÆ&Y½ &—5ñèǤ23itÀ˜%£?:£¹ý™¦8+•ݧq3•é£Ud{ð5±Jåµ~»•ÙP“ÚNi³âwÚ úKJÌ„Y½_6¸xñáI$ z6Nær2œG‹\fà1| ¹X{ÜOg‚Vic=³º^Apµ¡²é ’Æ•ôˆ•f½è ÝΣ üz)æ¹akqÁÕc;§á`Œüv}I¥¨£õ‹÷Å*µŸà‘ !_/"FZ9oèGÃH»±f$ ­=¶›ô¹y¶ªŒÄõiOÏõìòPâC¥eäÙ|±q…s û\ÿ~-3ù c!+ÎeÜ"|öÑÆ7 ®…<>,,!{ê|åü½nÿœ}²p…SO 3GiúR ±©:$œ&øÓÆÔ×í´¶¦Š>„ðv³èq½–YEžÙ·' Ç ¾~ßµe­€ÐèlvðÝÆÿi6Mž¡Xö5ã„PÏÚ@¶Å3mRUí,†k ƒŒÔ}HÉÓÙ&\„½“ ]¾HåÊO’Ï I}F|·U’”P»|ªš ñ2O¿Bfêúà€ìˆÐþ1¡G Àü^üh³—€¥ #÷:aEܦÄïªT§vÃjÙ$gID£‹»çià™úãFUõ›SE…«y±£ÇР°´¿YœÌzÇPs*)†0j‚¤o+0¤ÒT:GÅ$×u4«*®ŠgŠ“… õPjˆ½ÉN—ÄÅ*ÛŹžmÖˆñ¢t)uÅ(Ôjš°Ïµ]¿­~y=Z±}£ÅÓ2/ÿ¥vK]§2[m{K šg¼_•¹©e­×Wd(“ÆöycMŸï—/–p*q1‚Ý €’?— S*S6HŽ¢¢-NU™Õú  àPË©±®‡!ÇëJ²]£íû4‡¶‡·{¨¯«ñâh, ÈÓôe]g-pö<ò½-®ô4ŠÏF¢²ÐÒhí¬äX¯äÒ¯lh`º’ÖõÈÕÙßþe3Z{+'R¨Q½¨_1ôS(†)”ª Ù …:jbH¹KO5Ì× (¸¹¼Æ«êõ_´Rè÷Êð^?y}Zgƒéú b¼èXª–Éòï–†·Šº `çlru\4‹9+£/©«#]X@*ãq_™Ðá[–Ô½pÿj\çàqýî©ÞÁ‘J¾wt{ù¶öÝÆÖ’uG`ËsvŸ¸ÌÚN„ßtvü@wìMДožwú• ÉÝÜ2ŒèÊým´J7ýÕ“¸‰—q­CèëÀàûI01Órõ;ðØFs˜¢Û¨ãÚûDˆN?q â-6jE¼8R’œ6öblÒp Ž©F(q=>TæÿWb ¬˜{ãÈÔ2Cdæ¼q-Ãu-sL¨DtngS·Àê¶e[ì·KÓë:èvàå¹#xÙ\ÏÀë§ñø^½ AIû hRCëyî‘Ó}d“Inò ®ýÑf;.‡eÝ1íËΦ8yâ3s(³QtñÛŽp×Kz4ÀóÐ0 lЧè»x©ø®)ÕÁM¯%¬¿ý¶¤0™–=IÝ=ÝBMppÙco:GêÆ ‚PÉŽÒý”Ÿ°ö¿òw ¢h·“Ÿ[€?!„q _˜hîâ¿hMO£/A0R¯u«î—zœ– ®öP•Û1™ÏU‚õ=5†U+M¡É”UÌUR½z·VŒìà}©)|‡K²z3TñøOhØ?û?Ö¿M¹º. ¡îS`ÙäÝ:ÞMe¤¿È?CD2SÑÉ¿RìªòǶõXôÿ¼C endstream endobj 2345 0 obj << /Length 2227 /Filter /FlateDecode >> stream xÚíZ[Û¶~ß_!ô¥63¤(ê iw“¦E’6qÒÀe²äJr7é¯ï /²(k {݃´g,‘"‡3ßÌÙ¥ÞG½WßÌ/ž¾ ˜—$ôCo~íq“8J¼(ˆIpo¾ò>N~˜úb"륬«f:ó£xòbÊÄdµÎ˼iëéLLÒ6¯JýíÕ6_É'úý½,dÚHÝ`Ä÷ ›~šq5¿øí‚Ôc^äÃr‰häe닟¨·‚þï=Jx{÷jÔÚ Âž…÷áâ§ jø§}9BÞ“i2J(´³qݧ/cÚÄ|BCÔMÚ4÷SN'U­¤SŒÚž¾ä±;3|oÆI„Ðó?ld–ÿBy $A'í­Ô/ë´AŠ­¬u{•¶éRÃ-³®€uWd:ãœOæ·¹¡Qm °ðnûʪÕ/µÌªõZ–+ ]n0f~@@wÆ"’p£ÔYs= '1-$M›6·(R!Ët-"ÂËäXD4@\7õFâë3Ð;„C2u3Ë”¶ÇKguØVú¹4ýY-Óö$5úF‚uú¹½k‹üMWލ4H÷;+‡á‹6ÏÃ;Ù.Ô<19¨Z\7`±Á!Ôt~¡‚Þ¨}¡…8‚£ž@ÒòÆ0ýa5`#_o× àfÜá4`vŒ©Öõ4P~©UnÈòMZ‚yi•`!D‹õã… 8)%Bz2€7ôIHxk%G)ïžtYÈ“ç “ÿ"àu'›áp óÎí4±B,GÒéÍy>+rSTË´ÐïCãÃ>»Žjt¢ªÑèã"`V˜ói2yQ"×ÃsLZ›ÞU•maÓo×mªGÈ&3ˆšÝ{Qv˜²BÇ”©k,éjµØÔF!z¸ƒ-ç¡5Z µ„~b')ÂÜ`` WŸÑ7Óõ¦Ï £ÌÌ<»ãŸ€i@lø«0î4¹| A¼ß<› sÕÃÍlíq•Dœ!Tw-A|Æðü ¢Ð|`„Àý®ƒ{Y¯•$$JàOMïæPFB Ö‘dÔ7wkîú2 ºkvÑ]íѤ»E3hpO»úA•|Ù¿DÊkï' )høxÕY‡Bñ79Ù4€+À7 á!Êb_¡&Ì—5Û¡Q³-ƒW7šR ˆƒwÄ@ôÞBØ29è(\Ì\„åX@ãYÃØÜ>- ³0!”Á.Š¢ªã÷Øßƒ$†øÝ¸ýÝj)Å*Ý,¶m^Ç|û£¸rz€ïãLÀ–üüŽÆtô#^á¢hV¤Š4†2pþ«ÛDýØ&ˆ¸ S®!(týã==4,9q2é[‚_Lƒ·ò¹Ù‡žwXžFá«!žÏ4‚!„]p:¾.ó6O‹ü¸mhÀ»ëø#1eLÆz0„Ûpõì#᤺;R_Ÿ«J`:ËÐ>OÀo úÞé”F!òwõ×‡à ” ±?¸ÿü§Új]ÝçE¡ß–Æ]6uµÞàUä±Ú£I?atŒö˜¬/<}R­7i£r=ø>pØÇl3Æ)„GƒÔÔëöÑ ¸”t2äÍ!yc×›ªnÓ²Õ²éľ}±úyûn®_^¾{ÿêjnÇåf§Ýüh«wn‹Weø—ߎédÝÓÉü¢7êBú^žÈS™0èTú D~ýew% ѯÀ r™ YÝN¥['û ñ˜Ä |Ì©V@ÓußÁsp ·ÙxòP © .½œ“]öùãÈ¥žÎ";`¦N]•˜’ìœMp¥g»Ì­Œ)+¹X•‹Lf¶c©F:&>Mg<¢£¼0ê2£Ü}6x¹2­1'’!+·‹Þ$‡HDɱ\tÔgY…΄ù€¼”µçz„© o—ì([5|¡ñщ=ý^fˆÖƒI»\p:ƒú L&ÇÇò¶®BCØŠ¢aÞßI•õ[¸s]¥ª Y_ÌìŒñ›ôÇ‘útaÅÔgè¦>ùHêó8žCÿ¦ÃÓݲƒz)Âý|3wä•j8È€¿;U7à±£e‹´µ¹Öå¶µ_mž4u²œªŽóNåïìl|ˠÊĞ›»Ù|Ö^ö{nÞL,³¼ó`•ATâ²`¢v hën%'›ÌíÄþªýf@ýòí€b÷Űgx^þ*³¶;®¹IëTeaU!è‹)ÆT…­¹aÖÝX`È3¡Ý†õllKë…ƒ˜–ß«ìõÄTV³)ÒlÏà$f•?›‘ãÞÔÃÅ †{QÍ«·;†§ínÜ 7nßÙ¸´¬˜°Ã†%˜‹MÌ} _{…¦VUÉþ[#«¿›3Rd`“m¹’õ¸±O…xdì TM“›Z›ü®v¨bkySéy|aúaYªJÓ–`þ¨`Ì¡ª%ª÷ɘ‰ùfƒ0e`lgT–Km'×-œ|ŽVE¢SöûgŸ¯Ï>,ìëzUïìixC鿇‹º—o÷+¸7#ˆ„\0; -åÀnEéþVW„në–¡ÆvgCF]†Î+Âò¿©+þ©EXþ?Z„ÿÖ",ÿöä"¬øÇaùCEXCqø]nƒáÑÿÖµÿïhXò!²0U ‚ºÃ )yp2z̆¼ý FÉEÔ endstream endobj 2350 0 obj << /Length 1711 /Filter /FlateDecode >> stream xÚíZmOÛ:þÞ_!M·Õ¥Æ¯y™4Ml-ŒÁöM(´.DK›.IÇø÷÷8v^ \º2TMãŽOìããããã穃­K [ûW£ÎÎ'–‡<›ÚÖhj9Ôr¸‹¸Ç¬ÑÄ:ë¾ëQÑ•ñ…Œ£¤×§ŽÛÝíÑÌ‚y¤q¯/º~DsýnLä¶~>‘¡ô©+QŠHïëèmg8ê|ï[DÇ‘ƒk<ëœ}ÅÖäo-Œ˜çZ×Y«™ÅmÊÐ:í|ì`c:F„ îYÍ2¾´îzu²_Œk»È&̲m‚8UC[ß-hç)7p¬[5ªã™Å´5CBˆLBM Jˆ2;¶yAãŒVÌWj‚ ǃ¿¬{!dˆ ÛñJ‚›f刅h *‹J˜XHp©—á 5ÎÛ›g3ÿñó›Z-O¨RE:àôÿUÃ"Œ§Æ]q˜Íü%Ì›Â_¹@û+¯ bmªÙB¾Ô%xe¨hïTý¢Ü`º)‡<Ô¿²‡ŠØ(sWöma¢JØ].Éü™%°­žh0GTx:Ñ$W2 ³WÞÎÿeÆÔ$`tx¦›Á­³¾€Lõmr!ÎÉ¿8_¦Á*ê²Þý†Ê®Êo ß½í®bjjz0Z«ÿpðiíÙ ôlÆóU,yÑÔâ«Ü¿­¥#Š/מÍ%°(lK ±Fìg¡CI­ò|wjÊ©“w•QoM)‘ñ“µe¤kõ—“¥“Y4 ¦7«.Ó¿·¶ü¾ b™œ/bé/Ó«lÕúmËöÁO’ë(ž˜!q¦›«ÌÃô5 ¹³çØ•ŒÂ„•Ý2mÓ(n,*ywÛ(¬I2…µ•Is…[+«ƒNãù ³_^1¿š†­¦CŸkÚœG¢îÁ5s¨Êñ¶²‡“Ð&ùAPfŽªFlõ™‹\0<3ãG {¢{]×Ý(ÁÕ¬êjŽ<À€}(™m—jÖzvöXueúy{^`ª‚dúªË­ ® ÜM¯¤~ðSW)îËTš·ÑÔ¼Ô„h8˶„šS¦œjåß=Íf‹Pæ™åWÎN¿ ÊGfõÔ”PÖÒÀÐ&Jƒå¿ÓJ™B"e­$¥WtâʨO…E7}ž¤ÞÓcR˜A ”Ør TªC9’ª/Õü“yƒçÐT©Ýlª¶‡t{6@‚…g2Ñ#£Ê? ‡eò¿ kMÐõàþmØiÙKf œç×ÑßïC' ¼hWù3€)Æ]3HU±÷ty‘Æ2·3Z®•É–°“ÇɆ¿ÕNmÛRsNJ?_Ž£EníñѰmJïýŸÁli‚% Æßdj²x0-ñ­üBÂr&P•”Gnû%fâß$++"­áþ@]Œµû}>‹å\^û¡Ü·¼ÁnU¢kú—‰‰ÌÁÁéîááñçó½ã“Ï»'ƒÝW‡CýædøñÓÁÉðôüÃç×ovö‡ßz r:‘IG=ªXâš5S¥nC¢Z]ƒ§2 „çgÈ™nQÓËÀ‘nÞ ?mÑá ÀØy‹¯&ý{гÔê8-Ø¢&ÇëØŸëè´èþ t³`~Yã¼}ÆX÷x¡îrr×î \gÝÚæJãšñO¯DÄáÜÉBŽƒ/˜q9ÙÖ’ë õÓn@…ô¡#·ê–l=oƒ€JÛU—wƒ×fL?õ/²Ûø ÚsÆßû@xùIó9¬ªî…-ÆHÞ á³Û aÿQEiî×—¿ßÖ¦ù±±ñ&2îJ–±|iœE vyƒö|Á§7 ÙbƒPpéƒgt#“6¿d{ä>% º7H#6Ñ|Ä3°Ž¼43Òê!”aÓÙ¼>‹ãwÛytTpó× !tÏ☠ø˜. ’t]ä–ë¸÷ZÁàªC˜š÷ sàØ[„ JÙr>ÉAJÑb"õƒ9È¡R¿f¸”˜I5¿š|öàfZ¿óáb&I¨«>Ô¡.í¾¾ò=˜oO}÷c¾ÞñÚÜ»÷Û@j—Z6Kš¦ÿ˜Âì( endstream endobj 2361 0 obj << /Length 2379 /Filter /FlateDecode >> stream xÚåZÝoÛ8Ï_!,p€ Ô )Š”x@ÒMÚínw·Û枺…¡Hr¢‹my%¹Ùþ÷;CR”'Ž‹"¸ËCDÈ™á|qøK¨wíQïÍɫ˓Ó×óQÒ—ÞåÂã,"Q¨¼0ˆH ¸w™zŸ&¿L}1ÉÊ«¬,ªéÌ£ÉÙ”‰IºÊ×yU—Ó™˜Äu^¬Í·7Û<Í^˜ñ‡l™ÅUf^ñ}¦Ÿ/>¹¸<ùë„Ôc^胸€„4ô’ÕɧÏÔKþ³G W‘w§g­¼@Fð\zOþ8¡VJ˜/å Ÿåµwß§oZ¹2"’qOú‚ lï/&*4F@Í´Ák²ò¸Q'ä°JhòÞñC ƒPÚŒð€û=÷’Þ[’PÁ^Þ „´µÓ:‰-)–í˲ØRhÇŽvâxá0›6óíƒê%ÿóû[xx9J`ᣋqø[> Ayßš+ lÎ×ööKk¯†`ìÕ¼E¡5´}…èó/E{bµÖéÛÍ`—¡AkЧ$Q›‚ƒgcÊ™T„2|Bz)ÁÑžºÜ€n]¹ÁÔ§ñ…2•¦ºÉ–K]!( ÐÚÍ/­ŒC`Á¿Ìd+Üû4PªnÓ+1_¦ñf¾­óCØéÕ³ËÉùTÓ“õ!нr‰±\¾(ŽâQ”×Gïæ'$x>²Þa œ#ŒñÑbÕ¿QðÔaþ¤EVî!Rw¶Teå—¬d‡ð C«¼>j}–nízª'˜,ܬw(k–pxºlfcnyWÕ]Q¦fú:”½ BBCÌwÍmQ”§ù¢Y.-C‡¢:I«•ô†?Ì%ë—6^¶1}‡†Ð å&„ -\ ž]þtñÛÙQîýõíåQë/Îÿ£õ£V3i4ûýýÅoïÎÏÞ?+ݬÕ~½8{vT^¾;{õ7vä!ƒ‡ Ä „X„VA²æ¤t‰:oœÞÔàÐ]C5jÝ8W7tÐ>|ÙܹrOÈBÞÏ€(è˜gðäRt,5<-»Ó×¼Ÿ»”óY“»ŸÌ ‡/'\÷yzÂlagô Š53þ¤%Ó9Öž5£ï—‡ìÝ®¹ÏÞ>U6€` ¹éZØùÔ¦ ”§»›¢²äAÊ%o˜æyeg¶I›b25y»°%ܧúÊb{DÒv ¢ébú•Ç—>ª±ímy%nÓdŸ-8ÜSºº×´QOÏàsÔr»5u @ºWèå‚°Y—Ö8I±F‡\oÁ<†ÒU.´]Žy`‚‡°hÐb^Ø|} M„i¡›b»LÍX;"jÊR[ª`á6‡3ÕγA#]‚ày—Ãq«G¦:Á ¶®sS^ÖVVÁ¯fŒrvO'_ 0«l, /yà·yº;ì¢] øx¹ìŒÆYÎଅ{­tÛ¸/º˜’ÇWºðK‰gÂQ1€¨H´1’&½Ø°5+0SÀcoFã9˜ãG  @°[¶ZWæã ¨àKTðòwöñyëETM½ œ“Æ­½3 ;ŸFq7[4R£±õs†@iÐFîNx›Ë‘€&U¸%ýâï)–Ìøæ.ÿ|çârˆ“rì¿?L*ØŒ(øF„£r#¶$ÊÚ—.k)´cG;qß &}®û{L}˜T0&þ&… G'q}m¾]Ð ~“¿ç“bv…<º&努æ(pN&UuÿÚwD¸8”äwS4}å1A¸•ÙÝQ,ð¬œßf_¹í}ÆÀµ#A]ÛÂ…’Àaóm`áÿ+øÐZ~¦­÷=@ÄÇyú¼db¶lŽôˆ  9¿µGØ3öÈÓ17p!4Ѱ[zKô߬³¸žÂïù¦XæÉ×'co²å }ðì3ôu’&åãÑ·Uüw}[/ó6±Ù|ƈèn‘0}Ý4N¾ÍôÝlî®u•ÑÇTÎÍ‚0Õ ïH]ƒŒJ™­®3d}‡‚ö¨(u0ªXê©ëLCwØÎ 4£ÜéߣµjÝb' p±ñu5"®Ç*’û ËYÀpKÊ-Æçóû Ì1ðåÇ£Å^[b{E=¡Ë¿Å_™½ìØp2 õ´Kó2K ĉ÷œP<¥ó÷Ä›"Šð.fšx“ÞfÖmb²PBC,r¯ÏRA¯õÿ˜Ôi OZÔ\zÖ×0‡™.þP#_mW÷°UL¿u·X´m# É7ñ²"û¬å:Ñt:8”ÐxRᦃ?’‡Ø”‡Dªø-mZ¶{³Ž™UC~;¨·ùèeÏ>½D~2†É¥*õ`?H³B ±¤bNá-È£bcÀz7´u‹C°y+*}µ~udøŠ ƒ2s¼•t" ø£+«tÕhÚ²n·¶õC—†‘¿A:Ié¼ÛXÖT§²)7E²]a/“ÞW²*±*[«8Á1êù¡vMk¦é|SÚð;¸|Ây[¢“bµ2F1ê…¸Áµvõ­‡Êî 0„‚:Ìm_4s%áÞÉÝ28:žŽÅ÷ýÐaf}Û?tÆ´12šw»Ð’Õtøï|¡òGÿ7ßî!‹À'ŒY100&_ FþµÇ ëCéÌWCÝþ¢Žm endstream endobj 2368 0 obj << /Length 1803 /Filter /FlateDecode >> stream xÚíZKoÛ8¾çW{’Ñš!Ҥ=¤Í£íö™¸è![ŠD'ÚÈ–+Éuòïw(ê;±ãÀ ÎÁ‡äÌðãœ/6. lœì½ìí3b¸È–0#ö ›9ˆ¹ÔƹùwÏâ¦L.d§½¾e;æAp3‡“0Í’^Ÿ›^Æ]w2 ùR¿ŸÊHz©Ô‚, ‘ÞÏÁ‡½£ÁÞ¯=æ±A´9†llþxïü'600¢®cÌóVcƒ ž‘q¶÷m®cD,Î\£ûL.eU§'•]á A¨!˜‹˜àʶñË€†®ÂaݬSôÇÕîØqÎsq%Ž,B”‡ÌEA”Q«! †ß( Šlþòî•#Æ…íÖ…(šÕ+‘*«BT¬$¸V‡ks>(´Æeûâó‘ùÿûñŒoDŽËU©G:âôïºá`!œ· ¸b08+Ç‹5^¥@ãU–-€.Š 1_ë¢a &. †¢›dU(³ˆª%Øy–Pö…‹0QOX^Žòe¬wð­½Ó`†,îêæ:¸àÃ(ð¦ÃYFùVS°—?¹W- 8cœ÷9lQ}Ý¡ðÔör¹?YC“ùº«ÅSÝËx#qr¹ñhÞéÑ(xÒWëx³ßÒô¨N Pv×±zÇÿT&¿eBÖѺ:Æa¶QÌVïoÁj· „ m‚ë½3ªDÏÊÁàÝÑçƒ|ûô~°Qÿ£ÃïE¼'ÒËäpG¡»qؽ›ì:‹Â‘,TY\õaðË:WÕ’ÔªþêÄÝ*M¢Çx·éý×ú¡Ž˜`"'r¾mæR^o ‚%3ïEQ<‡0J³â)X7’^tõM¤ ü+or)WWõÐìhGq2÷’À»ˆ¤"¶£ßZÉB«úê¥é¨—è R&nô©ƒ0•máè¶µA-I'"Ú„ˆ!hBžTð%ÊöiV¡ÚV°žë-­Ñ<µÕVíw=ŠMY4oN<ÇÈvª‰‡æÃ,ôUãk©hQ6l÷m;“§Peߟ½>uÅBŸFÜaM§’©TÏ•¡{\„1cÁš.&ySØÆ—Sëd §  ÎZâµèz] ¯cáL¹w™.0ìÏuD­ÿ®â># ÒH·½è9N¼ñ"·ûe´AZpÙO-à“ŠÉrlfWR¿x™b²6ËYVÖÆ£¢²h ‚×êGfZVÄÍá@îSJÍ/SÅ… ^R¨O•ZTTz $ æÞ‚(±I…·¯g¾}¤wÆÊ¢Ô-{ ½ëQ8æ¤ ÀÑÒæ§‘¬—öúù?0øfñ;®µãÑ;½ãÑOÏ£™ ­»”FsØì„#v4z­6ÇEÜnǬ·Å¬—LÍ3äÒ RÕ'"•Û$Õ£ 'yróGiåö u1ú«x–¤æ¿ /ž˜[ß]:ò×,Ld:œ&Ò›eW;üüiðïPö¸9"¬´)jØ" mâj!\sÊȤš®Ûá‡a:> stream xÚíYÛnÛ8}÷W}Y©¨Þ%(Šlã¶é%Icï‹´l‹Iµ¾È•å¤ùûŠ´n•›(ÉÓ¢~0EŠ<3Î )ì\9ØyÛûsÔÛ{É¢PRéŒ.Fø¡ãóñ9£È9w?xT¸*¨4Y{}êîG„-âe¼ÎR¯/Üq'Kóîí&ŽÔ ó|¦æj¼V¦B¥ˆx_Gï{ƒQï{€Ø!ŽOAG>öé¢wþ;´¿w0baàÜä½—”sgØûÜÃVŒ;à9¡ÐN¤‹Ò#ŒÇéÿîî@‘ÊSk.Ž8LŽæööMa¯mƒ±×¶æ kh[•H ðùË*b b¬Sµ‹6ƒ¦ r_S<$ˆŠl”[Söeˆ0Ñ%„WˆmÏ<Ý€neºÑ¡9¢"4™fMÄÅ<¯.6Y<‡Ä‰§hÊéòåX§œÉË$½²ïÞ™RYïïí鲿VéµJ ZÄRÑF'‡ÂÂQІXqa„õS3ø`ônp|€>Ðàð/Ó)HlÉíÅ*™ÇÓ[Ó–Í2[Õˆý6ÈÓñz}“¤‘p™X Ïêº?ÛÏp}ìè[¼6Ýoâù|«Æ\eÊŠÿfª:%“Õ4Óp{o`ÁKË’€!,õ2çà˜.5ãCïksk@qaŸßé…QlœZmo“yXoRõÊšŽc$BßÎ_š_°ÀÙíJµhÀÀoó`ú¥dÛáV­Û," ɯ@F\I¬Û%ËË8]€vä•‘׆`”¼¾ŠÏŸwX¤ @!‘÷ž×‹Äîœ]e<+Bùv¬ãÔ@T; bÐ˽¾AúD$ˆ¼sƒ=VpQjº3W€‚¬F9$ _{H­P{oXuJýí9†Y¶òÂØI¦©ŠÀnO=ŠÝ™þS™iËcµFEVÆ~x»ãÅj®ö ëtO@qDƒ -Eþ&¿‰Æo¢ñôDƒ‹1&v ÉB²•h˜0çÚìÛ¿\«Z (ãœÚQKkWP”HîË&Š¥ÂÐÔè±³©‘ª.ÚìÕÓýCéœr»HýIK»` &ÇG·Äó~ã[Ùi±ÆV¥0ÝG/Xrcw¾ƒ‘8Çæ:Ä™YkÉ9†/w2Í©ëNFÅv¸´€µ–°– r% 6ù¬3 jœE€ð¬iÔ}Ë)#ÀVQ³`ýàë´9[¬Z^Ú‘…6"ÖïDªmøÀÝf…“q$ÚIÞ½eè4„±;8þûèÌîÉñ§Áñ¨†Ù }ØrD«ÄP)Cë Ç3÷Tú4ákÒn^]z»ú8¦+cSÀoª[°¯ìõ´&—¦üP3-jé1ì^Çi²\¨¥¥’×^~Ø10ãÉܒʧ15c(´bjù4¦öïãð¤é½8'&úÀ‡8l—Æ&¨äî5™y}M¢uŒüj%)Lªzrܽб)èÅ%5†\ >­„¥]ŸÈgéDÌ¢é#ÁÚÜjA©-"Oäî?ÇùJœ†•ªÎpý\V™kcIõAÛ5=·Ñ*CŒú?lª3ÁôI™¡£É8ÅÕºME‚>ôUû5i; ±Q»XIËòd9^¨6‰ N;KœµKô 3u[Þ4Ã$Ag‰ŸÚ$ ‡¤m—ÈÜ1KN~À,Wí³åÍÃJ§ap¹l¹Y´Y—Ác÷¹¶AiëbÙ*m›lÝ´¸KõF Æó6¡”ÝÂÎB—-P¤dwõoÚÔ‡˜ã…ú`ø=X"Àíò¢-¶8€«±•3.õ9ŠÕYÈÝq~Ú¦ø˜,ÔZÅÑÅÌø|W5·€­¢ÝyƳRGíR¹(o>ã…ºH@.[«üިͰWéi6x0 xPµæ>/}š 8¾>;:wàSÛÜž›8Þ^£}S»xѵÇôçÁuA¡„)´m`à2‹§ã’a •¡K×ñÔbŽ—Q\»5 ‡ö2Ϭɦ„y ¸Ê2:͆{_k²Pg`Ío‚ƒ­îý©ñçO¤¹‘êzy}ÉÃê¦èpQ»³&Œ4•ú#6 endstream endobj 2388 0 obj << /Length 3238 /Filter /FlateDecode >> stream xÚÝkoܸñ»…¾u¸U(RÔ£ý”»<šKÒøP w´’Ö¬•öVÚøòï;ÃRUÜ8nQ þ`‘Ã!9œ÷+¼kOx//~¼ºxò" ¼ÔO#yW;/–^&~˜*ïªð>®^¯¥^•Çmyl»õFÆÉêé:Ыb_5U××½Êúªmhìå©*ʨý¾¬Ë¬+©øRúÁú÷«Ÿ/ž_]üqÀö h»ÐEìåû‹¿ ¯øÏžðUšxwkï…QßÚûpñË…`ÒÝ×€ráËHá¬(ðŽ0p|?6üTkiO_¨˜N¤¾ö•!óû÷ñ>n´«w—W¯ÞýãÃd±'/T2b¶ð62„išv¿º)ûÉ Xm@ ? _gsd”hŒìÕ©E9®•X•Y½'ÌÉŽ2òU[Ìö@¢SJ¯ºC™W¿ –z ÑêhÖ2°Ý:«öH»›*G]¸™àÃJ% H±ú¼V¨: ¼iOuAíñšϠ+´ƒ›Qå¥*•$À‹Šé¹Ïðl_hÖ¶œS^à‰½Ž|­coC‚¦£îOu_j£ŽÑª¯ö¥QçxÕ·šRM°ñ¤˜øÐ}a W¯v„Ò´‹"Ó~RÉl" P»(VsIà’Sv]- T¢ˆÁˆP”;´Ê ¨#K'ý&´È:>Òˆ1´rCÚèK‘ ¾Æ!ü“ˆTy|ú:Õ³4ñeêtñö¸Õ~Þ6»ût\¥~º)@^@´ÜUuM$oK[¨B_ÎÄ6•JáL0› öS¥î5›ØOéDP|ÅlÐ| ¥Ø6Ù¾\”R~¢å™¤”œÚ HDÐ0KA+XšÂœ€#ƒ™ èŒU“W‡¬&X‘õÙ–Ü'ôòŒwÜ2€ ÖuT2fsÁýÆô­%¬i{jd‡CÊó…xI8æ”åÆ ´`ò ñæÙ:Ò«§—Ô³„=L©tîis», 9k¸-¿ô_‹²c‘ g粈,{ãÕí˜[²ã0#¸¶jwôe\°x°PO";›Ëî‚öËp}™ÙÍ)«™¿fؘ"~ áuݪr{,hàî¦lX¦tJ—8ž-ùò ôEZ”Šwr^ãoƒU…áLÄV´SOX…ˆo¤h'¿¬ì¤Ž6yßmnöY¾én²`“FKJp*©;i è Ð-âoRHD’!ô½]Rð´Ê4ç+V YFº`ÅéÜŠSk˜é‚a¦Î²S9ÃÉœ‰AªA¨šÙŒ‘©Cø©Ôè\*ˆü8rFðúÉÛ%Þ'¾Ã8Ûñõ³Ÿþ²!r²Š€&…ÉTELHAoý0;¤º_gA•ôYþ!E4“‚@ûÍzÛBº…žòFœgÆ…krÒí-cíŒuôäˆKÜÛýl¯‘ܶmfW‘ø–”8OAäÕuÇM£cÐ0,7–¾wìpzF6PãòÕ3†4}»Da¹Sð$f;â›ÙŒ¾¬¼…/p:˜LCÚL@””@cËÔž:cO£ó@†ßôÕî Ÿî¦4ÖcD(5$hòk‰8CÉ|‰(Ê¡K|:5MÕ\Äè—É[8jÊŒ;^¨©8Æu9sùÐwÓ)´I{˜%@yK¼8–9/L^vÝÓÑt¨ËZÄ.ÌpS0¡¾9-9R3ñ!RóDÈÖ Ð˜F{®~}vI#ÄHŽƒ!(ï’{ƒ‘Ü–æÓ-x#-ü$X{Áöö¤ {‡‰Àú‚åÂ0WßßIûë²›î;ñM@˜…3¥Á@©c?¯@heš?wDéBun^dùá ½Q]—5: Áœ£"@—V­kQ¦†“íæ8 ‡»›¶+y¬*¨Qñ8D/HŒK åý{»¡Ãç¼°vLÍ¢>)0ë4ÑóÔiž“&ƒ_r9鈮¬îZ‚8#¢["eyoј›J‡~œ¤Snf„Óî&±‰¾Æ_ç(fº‹"&Õ^½üû¯—„ÔU×XvV<cLƒ ªxÙî´uŠgbRÈYðdËqÞÚ—÷/kM}ì§Ý&ìv³ì¥š¹ ›Z¤ÉÞœ@‘ª+\ rýÍù‘G‰uJDøö{X™G®@Üü¹œ'ECª[l?Aª $\/¹#£«‹Aý‚YI[LNb‚‚…3ãd®O{Èe1,è0Z}(°¥ÀËNàž¹JIyw l·mºûb$Ä ¡ÆUþã.w…Ÿ†Žó·&ùÌðçÞ0-¡äw²žÁ§ƒóšäuÇÊ Ûr+Åó›zbóC¢š]]-kLÉ2ÈV«‘ÅKO$ ¢dr~E1¿(UûÒ¼&P‹—î àPÙ‰àz›¢cè8}66Ø„¯Æq=pVÆ)à8Ý$“OSA¼zÕ’1lü6È ºÒ Ïv÷b|W…;r|ÂÚ‰L”/Õ,ß8‘èPHßñ6nyâez¤F¯máæµíù?Ÿ¾½|óü¯mP|ØZCV©‚É› ŸEwÕ1bü`d&àƒµ1:ï³?«ý kµ' ’cDºm3õ€£mX‡.m)¨O%•uùJP©C%&9Íèži$âKzÚÅ‹À}AŠBÖøŽ:| -ªö#Mé6¦¯K8±±sc :Hµœž÷YÅK<„á2sÖ½a-„ïê{ ë4P1‚Û•xqÜïÊ‚ß-+"bÅvá  vVÒMoïÉñ Me9ƒpg;ºÆ!ÃÁ© “´Ñ ŒT6ÀR|IJ=(Í_ÙR‡©7ÿ²þ/ <¿rOêQáQA }™j|V÷þð7E;¡ÍºùÞSôÒ+_kmÀ5ô  t†añ@૎3”—‡!â¦ðg¦;`ì‡:ŠÓaEŒómØÑrO Únè bXN ÛåÐQ€->}„9Yþ¾÷‹ÊGEÏK§ôc úÿPu€zˆ—Ì®ÐápÒðKóˆã—¿Ü°fFs7ò#%£µ‚d´ tˆ;c¾à!x2ä[Yñ=vt‡økY¹‰R_X›ƒyá•ðÓü®dòBI)äwtå·EÎö"¿í?CÎÂ1 œÚfÍ0([ñO#¾²q VB³Øýý»ã}þþùÓ7oƒÿÉYäå,òÑg¯¦RJÊ®êNĸ6ý&­ÃÈãî4ŠrôžUÙ 5v¸–®nŠ’ïzV×͘©1‚}óï2JJ?8õ LµËD®~ºÉkô;,4ühŠ–¦÷þ¼ôpl¯ ¶ïæ¤ÿ eàz endstream endobj 2399 0 obj << /Length 1682 /Filter /FlateDecode >> stream xÚµÛNã8ô½_‘ÇTš;vnÚ'v(#fX`i5ÒŠ¡´14"M:I âï÷8ǹ6- 0/‰sbŸûÕÔ¸7¨ñeô÷|tt*˜áß±c~gpæÏõ WxDøÜ˜‡ÆùmlÙ¦Ì2KóñÄr=óxÌl3\GI”Ùxb›A¥ þû²Bù ××2–A.ñƒË"lüsþu4~ð@ f¸Ä¥®±\n~R#øWƒî{ÆS¹kmǃwlÌFÿލæ¿~ìSb9\r˜‘Áàu#1cÄ·mK‰¬È3J(wQZæ›Ø%›o§cÜLlJÍéÅ÷³ë±m^^ü3½˜wpr¯¥xjL,§mdb&•Òlj>Œ-Zéþµ© †¿îÆ‚ši†¾B™/„šÑF› é¾¿µ!D&cNÍÇ(K“µL >*{M°ˆeNëŠGæŸk·8V8ŽØáÕÆ†elåŽk>d û!\"<ßn6ȳYèóù³¢—+—*ä:ÔÀt©˜Eñ „Ë"BÞ´h{Œ\+Mùül¦ͧ·Wg'údvŽ' Œs{z2Cx_•¸¥› ¸CZ™pË5gV•P€j“¥cnÆP*Òœ™ Eá×È,|/ƒ8–×[Ô~-µ–2™oÒDã(R},M~P.î·Y…=Ž´“ ]†p6—š!å<¨,MD<:Ÿm¿þë ¼lv h%îíø«€ñœjëŽnJN·á@WJ,Î-Sþ3jnµAcP:z6ç¼Þ£ØD¥©¯§(ŽñÿB"$ºORÐØÁö¨yœÔ›yOCjsWC ÒÒ:R¬‚„)¾“´¨°õŒQr—êŸhCa›“ŽÕ|(ßq7”K­:èµ\úCïND¨¨ïG„Ú¯Ñns¥™N{uúêçHƒsâ9¼•"I‘³éT×”óÙe]‹z†vI"ÀÛJT}`É®ãìÏ¥á¾ÝQ|(ÿrHl¯üùn}+‚øk…o¼;HÝF¬€:$ß—ÉûÄÖŸt‡ÁæE8”8¬¥‚Õï=> ~!œÒ§'Ìóç\ÛÛמýA~ý¹`óNTCaÈJõÖÌöAa¨ò×P©yy5ƒ2ÙµU§Pôl“©ÌŠâöÌjŽº¤Ü U™[m˜dzGÛ£ ;¬v©LeyÄë!jœPáW;¢ õAvMôn€¨ZÕù@•’XdÐÑ6ó‚u¹œ„¨À =¼ÓÕ¾,B—íXµbß%Ìq~›h>¨/Ç«õõ Ÿ‹`1d ‡PÊ‚»xlâ5™m½‰£ep»‚žµãb ZN„eíT6‡XR'ÓÙç볫ùÙåÅotþ˜7&–ç`%‡·ªä¸*û?Ï5s¹„Æ&V•ÿÿ¨SÁ½J—A!à«×ôä»ï0#aÇ®¾¶ë b×Þ^Bï²t­i¯dE û¼µnøž÷ÑÉ%nxT=Q¹®EÐܹÐQ•Öj–v§•>B˜t¡xZEK•ƒVÝ(ßÈe¤Ä©š)݄Č ÞÐÍ>ÇëwÁ>d¦:ìç+ÝÆiÚ´Ñ(¬[m~«å[f ·ÃåÛË0jëâW5AV#ÎE÷ ! Fÿ˜H»,ƒl6ˆl tÁPbûÝzãÑõÆjêÍ>ÍA_!ú“άv>íEåY‰®3š×ÿ†¢kÀõD•h•S|êv'öªÐu¤ÝSèHê qHR§šoaø’`]~à ·’™ìíQaRz>¬+é“e´ b<ÓJS5F\G¹w.4oF¶IøÞ@Ô£·¢&ïÊi{ùhÑlç%§££N¢IRd| ³ fåw¯c·i+Î/?«Œq|^’˜Í• ”7póéÉÙuß ÚÆrm"šÆþHßÄé¤{«¤,² ɇZ5»ûù`Ç×|è×Îfu[“nh©ÖÄlMö:œE<á•¡U_.ixZÃ]ŒDLÏÍé÷%[[FkE«†ØR qx0Û2B›‰g·XªììdŽuZèuY—@Òl£î6­~"8ÈX:Z¿ª³ºµåb{%÷:’æ:R…ºxC‚Ê”ã‰ÝÎr¯¿À,mñ×úKœ.ƒÝ‹Òú7 eúPd[ż+\ÿBüÏkï³wïᅀтµÆRè.á7s¥!lF ´Všaœ÷Yú· ©$ endstream endobj 2413 0 obj << /Length 2968 /Filter /FlateDecode >> stream xÚÝÛnܺñÝ_¡·j,MŠº¶(Ð4qŸœ“äÄn‹" ­¤k¥¤=FþþÌpHê²Z#ŽÓ—úÁâeHç>Ãå·;¯Ïþy}vþÊNÂ’Ð ë­yNäÇÌO¤s;Ý7+/p‹vS´M·Z{Qì>_‰ÀÍwe]v}»ZnÚ—MMs¯e^<£ö‡¢*Ò® Ž`žÇÄêóõ/g×g_ÏÏAÇù,â‘“íÎ>~æNã¿8œÉ$vîÔÎñþ•suöûרÛ/€9g^(qU(œ&Ž? —‚%Aà™Û θŒè¶"a!óš?~Žóqpî^¼ý÷å‡Uà¾{ûÛÅÛëÉžç¯d<¢9wÖž«Bâª@¢ܽ[yÜÐþxÿMmW>w›–:)}ò¢Ëp„»å^³F›-}ߌ6£‘¢^IîþQ¶M½+êžÿ@~§z›tS›’ã»É0§5ÜRJ‡rDêàçúêâBËæ¯WïfèzKbaöºË7ÁÍ¡/«‡Ž—K<ù?9¾Ýwyöàá ß£«? ÀO'`‰*qZ Ô3µ–1\Û UôsD >göÏQèŲLü$ Xùûß·+ ŠûîýÕåÕŒU°äX¶ÃA¶…•í9[}ÆEhøú‘ &»I&EdÖ­†‹XX?ô H‹V§H«ÝÂiždÜO äg”¢`ñЄ‰È­Ÿ/ [öÐÖMW€aC›§Phæ%òѤKƹgȪ›O\úU±tí„ÉǺ]&õˆ]Dê}UféM~ØíO"FÌ´÷»1xµ|íÄ·[íÛ²ÎÊ}ZÝäiŸn08>=ŠÀ=žëûåÓ}~l5o´ùþ²twÁD"†ÓÂYƒ¼²0ãBÚû°ôÛÛ®ß/¡ä1>Hÿ6(i¿€‰s†:ðStð,Ü'îû2_Ÿd.¨p2íï (,özPRã8z,Šë—K·å,âÑ[-)pâÑt[w ”€ $¶¼º+¾Ìž&†/™â‰äü'±ö óð(\ý9ÎâåÅÕ‹—ï¯/ß½}DXz}[,I7ä  ¦aÒ\A7KܬÙíÒ:f%±Kñæ¡ÆÈ4‰\»Âp[èy2b4ûæå UæÜSæs”p­Ö~º—=ATe‡®­/hçx7ÃF‡=%{Âר塠|—æÁnД~ÐzRl%}r¿sª=[ÐÌ*˜24#mº3WÞjËåQ<µ\`„Ûƒü´"íÀè&ý‚áY:¤ ¥M 0ðÏuWêÌ`¯©]69°¢ªåo4µ@<\8?”è­g·m³£qY!Eìtþ¡w~«Ld"µJüç¶Pi§¯w€Æ '‘„NV”$M§ôQ±Y0ÁœjÔÆ£*Êm¨¨–¦YVìûn¶}o‘S›¤@­C$Ôj=¿¯ÒÌà[ööÞf"]$¥}žKæé™SÛ@£'â@kЭ'Él" %O•ø°—´Kú†ð©š4'Ì5ãå@‘fÊš–€Ó¬×\Õ‹G <÷þ¶Ì•·z}GǮЄъü$Z×™ù‰ïËŽ *+}µì´Ò‚AÀ¸eÂgбïyš÷(¡Hl,è O³|™IÚ¦¡ï¡{¢%„ÙÞ#-YÈ„c±  Iß±ìõ‘·´°Z¿pßhx‘û/dû-بk×m±A$!Ñ” 91¡6r;”T¬á"ÆÌHùX3GÀƒZ¬Êñ ïËJÛÐÛt%ͤ®þÔÆº®ûf­=ÚR§Œh«ktS{ ÇN¡t°nzj j)KŽ,á‡~¾©­·PçØ+4T!ÐKšƒÞRXA}Ž…ƒXW¾`,Õû¦ «"i©—[–YÞQĤj¯›š7µ&›uôHÚlLJã2èH€æž>\Ý,û¿¿ßÖùÝáI4Üøym%‚ òôÿ±âà±÷4¹ÀÓÁå¡ÄP-:Ÿøm8õеØäx}Õ@ªð¤º ø‹§l`œ’ºàPÖ]Lvލn œA¦<,4Òªk¨ebj=Þé/}(•€H<­È«HôÁxAt“Òw7i†fû3Æ5‡Z»‰WWT[½g­±0.ÎB ©,âØÔu‘¡—Ö¸4·==©Ôºç>uгš (<™,Xp“ݾÈJôMè²% 0éo±ŽÜà¸âb^›Ö<z64nôÓn^nië/:Þ¯1 ÀxŽK÷ )8"2Âïš\·ÐÙãJ“Þ•­AØRM#„ŸE<ê,ßœ¥é¢€À¥F³Õ*„Œ#|™ û3Œø¥+éAÆwè›3Ê¥q8/z`dGûÛèŠØzJÄÕ ’ 1H"ö(sUÀkèƒê| «—*üUj1•WœÓ¤D¨­þêÓiaÄHž pß›º€Æ£±èh2TR›X’x'äLd4Ï×WËrÇÌÊEÑŸsFTêpDµ1WJ=vŠ(ƒf(T¬EƒÃÁÒl‚R"¿*  ùóC@ms-B‚ElMd¢è=Èʦ¬Ê^§›ƒ.Ìä©©OnA<ýËItb{Ý£ ¥&ü…Φ ¯®Q‡4[Ëœ ¸ÙáA¨4K7´ËÒ› >[Z^=@ÓaÖ üès¦d‰2ö<³qøÉ”= m‡”]$XeÓèL¨.SS劀kb­”’…á<Ï7Å6)´öÂQ–Éë©ÒÀ훪ê¨i×.ÕÑ¡•§S×GK»„™–¹òºYMN£»X‹;ª¨µøcƒá§S»ƒ­õ£µoEgUÖ'jv`7ÿ‚¿´èÆ¿oQªÞ§›qÑï‰ê;óÝß­¾1ó×›™Ê ¹£)‚µ+í 2 °=˜2£¾ðð6t¯ßðÇeôzrü`4ý¥Øüw~ϼð»æ·øËD0?B˜ŸúHÌb"/öÜ·é~…ÕSü½af ô“­ˆ¯h4¶ëæ¨ÿ 0JîŒ endstream endobj 2329 0 obj << /Type /ObjStm /N 100 /First 956 /Length 1999 /Filter /FlateDecode >> stream xÚÕZÝo$· ß¿BM´¢DŠ$p\[ ‚Ü=´1îÁ¹é¡}°}@úß÷G펓]û<ãÍØ@ߨŽDñã'’ÓšJ2í‰)™¬©¶j‰j ‚uÑzª^‚(‰Y‚ $¦AÔ¤u5L ߺjò) Å 銌—øžâEc «ÄŽÆ:RñAŒ¼íF•oZïc-ÌfC»P^óÒñØ<¶ÛŸºÙÆ¡b.56¯ φb¢Ø¶»Å” ÆæU·¡hmaâx }²˜ãS°õ»RÌÛ•6±b6‡]XC‘P+ær Øà°iø”ÉNAÁg¤ÈxæIv®¿“¼JŠCApDéÃHÖ’¨‡† C‰m€’Ô‹ÊS¯„Å`ƒ`Ãy Ã¾Û“[ê;¿…÷N†àŽ]‡$`î6L ñµ ‡Â‚JCv—¤Æ,=)‡L gÒp‡I´ca´w,XR-}ãØ•*¬â[ŽÃ$µ±c,¦ûU†c©c ̉ð U“E¤BL1ŒŠ]%<´–ËæÕ«ÍöÛt†(Äð÷iûÏý€P„‡µ\°×ËO¿üònóå—Ÿe¬ÊÁµ€±õ¬²„±xn¯¯.oÓ«Wiû:·B±ã“×ðw ¨Ù*"ž÷ïÆ¨ïG05½{0±c„%¶ß]_½sq›ÎÒö»o_§íÛ‹_oÓÝêoÿûñ/ξØl¿$—·7+ßo¶ß_Ü\}º~q³Ãšñì?}8ÿúê×tVð  ÕwXèü_ƒ‘lÇøÕååf;ÛábÈ3pqOÔ‰h±Ûù‘hc’ÍöͧoÇøï.ÿ³Ù~}uýÓÅõ ¼Ûþuû·í7g4!ó{ì “+\q•ÃQá?Ù+â§Ô\”Á÷ÕÐú›´ýËÕÛ«ƒýéæÓ7øøÃÕe®Ÿ} \E®5 ‚ +â_[ÖÀ /Àÿ 0ϯϾ>ÿøï?gö%1ÎB6I"•²Òã’©¥®' •žiÉÆéq–å8gÈQÔ_XšZK.@"~ h®1®’ÉO–f@@뿃,j6œn÷±â€1’†2ÏÔ»gém#Ã}Á²@Ó\Õ06Í‘ Ì3\8¿ôŽ`îq`ÀWÚ0‡‘ÆH€Ç“!å>îÖ; yB¾ýöVÂ9dn0p ÇZ—qdæ} sf³‡vï±äkbÜ$ °‘•í%!jÙDŸ$Ép$æ…¡sÀˆÞ[æ& »@Gí”óøÐÜöÐ5Ïêx§í“ûdG•ò€£ÚÓõ@I¾Tí~„1 m.a„µL—Žø8ðØ|žj†çÉ-w]°4 ¨¬È–yÆ#~,‹[Åúî[_|¡õ»Üƒ)‘=LIŸ[5AËHˆ:Ò‘¶3a›+B²ÑXÈŠ àŠø7I˜‘ ¡ØX(ÉšÙVvQ!Š68¡aŒ…²ÔN†¸òC«â™Q)3RŽ(‰È@½øt4ïe!¬0Zà!gà ØežJŽ"rž±XŽ‚öYQàð´øý¹r:&Ø}Lèýi˜p ]j:=4]8®.`,šEež‘…‚ðÆj¹”2V„=£ô˜g ¯Qþ¿sí÷Aùôb¿•N%˜‰’6Î[BuÖÀyœ+ÑÓQFe¡«êak¦×\À(.yÉ„ŒRÖÝç[ÀVYÂX9kÑyÆjš-a$`|?É£[N%9‡¾¿FsÊ€7ëÀ£}ŸàØÔ¥²©V³©KeS—Êx"dÍ8`”"½µÔq¼ ŽY"Vh«ef{évUôcPÜ3Â0Ô-SfM5ÕÙ~•®˜C×Ño``!A¤hFC)¹Õ—ΊPÅçðæ&-+*¦žkT’ óÍ6¬²2¯ÙV„±ß‰ƒdMUçyŠ ³à¸âŒÐH€Ÿ L#x55{é>òe…T5.  [ ‚ñÒžÖdz¥9é‚>ÞSE]êdzÒ#û|ëád´u¿¶®§£­O ëÈú²>¬O ëS5êý² °…)ˆoеˆîÙNU[ÝÚÚ;IàºãÇ$y¾v<¢·À¶wÒ ×Ñq“½Xš!%š5‘pí…©B´¥6Zd VZâ"9)ð–xîÕ^Ò[Är·q…ŽvÜqÇ¥ êÔš[y\'µ¬)I•Ôa”ø À`£¸IÖHßç4¢÷ÀÕm!¸0~\˜:ìÌ2ŠtÔKÃÁ¬Í3r‡alž/º_Ålmü?º1Yá4`j÷N&:ù4ˆ[ýðÑÙm"x"d"úDèDØDìsx¦ò EGéíDŽG[ƒTžäæôž4.mÛ$G\íÀä åX€¢ÅÊr/ 8þY(Çš=[ä•-îшVuÜ^·¨W:Ô^góÞ¾¢Fáá»QÄŸ,5 8îÓ+ ÌÚbÛüGȵ endstream endobj 2425 0 obj << /Length 1895 /Filter /FlateDecode >> stream xÚµÉrÛ6ôî¯à‘š)!lܦÓCZÇ7™$uK;J„lÖÜ*’qó÷}ÀW+Šb·ËÃÃÛˆ:wu~½øys±¾’̉IðÀÙìÁ"…±ʈÈX8›Ôùä¾YqßU‡­:TÍÊãaä¾Z1ßM‹¬Ìšö°ò|7i³ªÄ½_»,U?àø£ÊUÒ(œ0Â9a«?7¿]¼Þ\ü}Á€ê0'äp$! ]qñéOꤰþ›C‰ˆ#çÑ@Ž "øæÎÍÅïÔÒ?| ò)áЧæ`ãÉâÇ‘cÆHìû\³¬¯g”P"·,&!†Ìçßã|ò|JÝ÷6×ïßÝE¶¾‚£ä©ãqˆŠ‘ ï ­¯":2%Ób3 ‡§®Jòb†~}%¢é z ƃ7µÚeP!•V§OÝö^áà`Йaµ_ìÕ h¸0+|ÁåFáôóJh#YÁY4ãÓã’Ä j…$Ö¼WǸ„ÒÛD›Ûíä6ªo;Å9pLÏæ|ÉîVøÝZ ]U¶É®U)N÷+ r²°Y¹;¨B@Ž ]&­j~´(4ÁVd©ÚkJº¼ýᘬ¢™¨šÛt{Ò¶ 0>ö“ö~î­ƒ3½1rÈ[Úó&æB­®¬ f6Þ•U»@31Šg¸U}Š©áÄ„©Wy^iÝ>êK5Ý‘oiA‡î¯—*ü6Ú¿öÚ~#9ÂÕ ëYX½ý"‹dQL"?Ô—nýÛ®ÍòSnS¹š]õݾž~¯N6«l)Õ„F­ì7UÛî‡ZOÀ¸|Ô8»e†ÌØZ];Ar—•="Õ4É©æ ÐõG-ˆõ·Yf57T58® ·YO"ê=%rúa÷Ì)¡÷Ù§YQç™jÐsf²g4 þà°èO’@°±pñÙim2 tò¥‹}x~膌È&õ!L’Ò~óÖVp%”‡¸Vcéj­qî–]±U‡#8íÃØÄtøæ™u‹¿*Hwƒ~Ký·*s­û/8ƒºïr aïªb›•½Šaá13ÙU߇¹c!9 U ‡*Á»9¦ F ·U­‘ŸÖ†„”A岚HŽ7D±Œ‡a—ßžQ¤ PXt:ç² B3Õ̹,ÌõÊsgpµ©DÌReáû-TqŽTBþcñX€êYþ;Š=´¹O¯½4÷ ~þ&¦F„.*·‰@žŒÏ‰ ç¦Æp6·”?(÷ë,õúRbËOGlŒ,«k8p†íxÌ'¡ÏŽ$VÝ™?„ ˜äUiC\Ÿbaøh#m«žô|Õ3N®/¿Ò~§‰*ª²ï5ÁÂÐçý‚ ¾޳´ _PÈEçV÷qD„XHÙkŽö‹“ÊèA}rŽGú„sqNiŸàçÁöÆmà†9Hר#Ýy²û[W]6Mwf}§ê¶‡‚>…’%KòæÙÿŸ¯(:¨t{›îšoE§x.m*öš¾—ÞYêMët×ég‡F‡}!ÜõÒ_$Œ‡ÿrÖ2½¯‘C?ÉE½#º<¬½^@É!›?Æ‘$чC3chºzȸý[ÎB”³»³_ý–O‹úٓȼ!-†äÄš•Ê&5º@Ù­Qšç·¬4ÑEP¼eOž®ô¦Žðú› È}…ù±©Ò£Çû¬'PƒY”ÔÈÌb*, š8„õ¸A>V¤zúfz^DôÊXæë™_2-ó5¶ÏYò2ÿ¥Or¿Vuúe„CüJ °ü÷À—àgÿyðôO@!9aŒOüsårh‹µÆ%ô"¬‡ IÓ¿vð# endstream endobj 2435 0 obj << /Length 2385 /Filter /FlateDecode >> stream xÚÍ]oܸñÝ¿B@_´@VGŠ¢>î©iâ |¹Ø9{{×"gZI¶ïJIk7ýõáÔÇÊ®û€¾ˆäÎ÷ )æ\;Ìùpô·ÕÑ?ÜI¼$ôCguåD¾±$ÂYåÎ÷ã—nѬ‹¦nK?ŠÝ· .Ý|[VeÛ5‹¥tÓ®¬+šû°/óâ õÏ‹M‘¶ ¸çû_\®~>:^}=âp3²ÿƒIÁ‡ÓÔÕ"`nÝÐ ¥&/Ú !Ì-wZ%­¯¨ý8@F¢ZæÞ•M]m‹ª#àê;ÕhÒõ¦h½±8ž,†©¬K!¼8Q‡¯#ê‹ãcm›¿\œMÈõYŒë£¾Aª)P‘†ëäv× `êÝczO@I[ÞÐÒï% ð’˜\·ùZþkß•›ÇŽ‘—øâO9¾YËÛ<{ôppï¸?ûaûÕseUt9ceÔ/11PS*[r&<&°´da -~3#¨w›úú…ØæFqO®Ç_É/tÿyº¹¸gŸ/N.&„-‡öÏÑâ5Ã}Ñ™4 ÿB+Fø„'z‹XÞÌàñȬ¸$»˜Ã”‹ö¨e¡W ­b¸¾YRí·3§ñÈCAO[Þ]Îè ÏÖ“ž'‰åùå+Ì%—'©ãæÀœ=ÿuìãýñÅ»ó“Ï«“³Ó§ä'm«ÈO‚E½?À(t³z»M«œ¦ò²ÝmRÌ/ß0n¶íÌά®:H9-íÄ5šþøþÍäi—®Uàýƺoíj´¨£HMC½ïvû΃… ÷¤Ó'§í[¤m¡×&rKJÐÚWA¬ØÁ‰Û5i†€[ªäÄͲ¦À$šnh‚Hmõ¦Z·È.ßéüZeåÎì0¬½B2®5LãÅ4vþ`"Øh Ê2-«vrÆì¾-,ÄÅÈ2Ž×¤¡¶Ï‹„å$´nq«bPŠecþ?rX$í.°¯¬h‘³ ™ŠZâ:FŠ[]®|C0'ãÁù¶ øÝB` K@e¡ÍËŒb…þ0J¨ áqþ8DÅäiü5ÅnSféã\Ay¶ |áþ~SèýÆôP©K?„¼ÌøX·u–í, u¥Ž' ’_äCñ§jvVs­ªÿœ&”c{S¶´‚Ì)Àd³_·ÅרyްÁceÑ Í@{ö`FŒÈ®÷ &.Lý ½ÁÒûr³185 hZkzjá(H°ÇԾ肺¼nê-õHrÞÚ°¬VìHcX’õŽG»K]¤“BÇú.ôïËîÆl72’lÀD3èöt$¸­g9bOˆA@F#é2Žl@Æ‘LÙ­1¯TÏ¥™±BNJÆÖà´ì@_£fÅû¡ ­8«Õ½aôŸ ÁkG§EYè3ëÊZ ŒzÅÉÐöÏݲ›S&aÜWZfu5+¨“+2øª¦¶V÷$}¯Õv™dWd%rXäè ±Êæ6µšv¿ZrEh‰•h™¡HQŠ<Ò´E`êêV†Þ]SîÉ5žª÷VÕ9´ÈPº³§›v6·Íp™1UjÔyÙ7y–rèÕˆ9‹'ÄLͳ€+}áí#ÀHÁЙ†m§øˆ)¬ f‰Øœ qO”bY k¦¶hß̉éþ¦Ì0žÜ˜«K¶ÙçÆ=m€0t—*FÊÐuÑŒoávõ&µ!j3š"+Jb>Ÿ„»;mÛ:+a‹™(·† *ƒ¶»gœûçÝðcO¼N¥z¦ŠÔ‹Yd3÷ #}]8ôÆE ‹ÆÚ>W9¯-”ˆ¤‘œèHj·PA­(LÇ­¬0ã½ò#‰¦ýV‘5uUþG=˜©ý1ù boI—ÚI’šÍÆIˆ˜ÊôÒnfŽÁ iݺèî‘ÛÂlÄ*B]|âÐc±Kçðêôl­Ý½(¬Põ—we¾7UBÚù­÷¶æß[5 ZEä·:ªHÿ¿1n‚w™«ÄUÓóõéWM_2Œþ ÔÕ¡YÃŽõ ™û2Hœi«SöÜ$îã•ýÉ“OÂ¥7±À}:Û9_Xš ÜF«&Ãlk~ýHîI@I?€út‚1_~à PAp¸œ;2€%A›8ÌA7ñ@ø4bv;#Ì™:~óÿAÄ•ó«ZH$š6¬hñ?Y¢äõ<¡2pù@íÜ F’‡¾*n‚ă4y‰Ì´ádÈÒ®·!S¾Ç’ŠGÝ,Á¾ƒÏ[S¿ú¡o&¡òM>pí›×aL‚©ƒáÓC—^˜˜“ðp%D,ñõÛ‘J%JZš‡£!DÉÑ0¬DÂóûÇì¿Ê© ¦ñhÈÀRïE—!]õÝ[…Æηy>— ‡w}ˆl„XÔi&…ªÇõG19‚“£§1H~bÿÿzü·Ÿ>ÿr<¹f($óQhGóÜ‹û,?ŽÞxwöé0:CðŽÀü‘¨8òxè“Ìÿ@ájYí‹v\åVfuÝ¥CÿVévú[\ÚŸüW{öG|à{œ›gª'®Øwßݤ»¦rýª‰¿×H!\Gû9·çk‚mÛ @úöH»a endstream endobj 2440 0 obj << /Length 1451 /Filter /FlateDecode >> stream xÚÅXKoÛ8¾ûWð(5Ë·ÄÞ²m¤m½iŠÄ$BlÉ•äÙ_¿C‘r$E5’ÆÀ^,‰Îãã73¤ ºAMþZLÞ~i¬Shq8pjŠ ÍÑ"E—Áç)“)¯LYTÓ £à`Je®²<«êr:“A\gEîæŽ6YjÞ¸÷ ³4qeÜÅŒa:ý±ø49\L~N(ø@E!s‡$DÉjrùƒ Æ?!‚¹ŽÐ}#µBBEð\¢ùäë„xÿI7¡ëP‡à«F(ÁŠ….ŽïD’¤Èë,ߘ|’$¸.‹•{[—Ɔù++6•‰ošÀa™ózkS&…FÃgyƒ~7uqdcn#ÖKª‘Œ(¯lÔè'Ym·A'6øLVˆ; `k$ètpI0£4´_BR?C1œu8JºÓLa‹Iç»o·Ð?Hc2ùÿ _£¯àÖÒ"oG[ -;´çÈK qîh‡ÐX@º‰ƒø™m퀋c; Ùâ£xn B™–pmÌ3 ަšÉˆa®„ ¼á>äÆcSʰT”VXrå¸ÿ÷:kHD Œ®²ýÛ;ÇkLÁU,-dœzŸº#à ºl&z©?3 ,–ò©™¤X­²º¶©ÖµE¬R!œÆVol½ýªN`´¸vÏÏenÄäSN ½—E¾2yíÙ{5ñÕÒTxOxC”œãHñÔr?PÏý)ìËülà.#‘•m1‘rª†ƒ»Jý~OîÖ¥¦X§»6’AD,jëò›]»øLÁ/¡‡½Å°f[`õ~`½«7u¶|¥®1ØÄ£Þbº'L… þ9Î( ÎÎçÇóaWä;6x$Ö=R]c¶Ÿ?Îß_Ÿ/ŽÏN_PR·PR8Sm˜ðîN#qžº‰Ìƒ)’;ÆVN*vóa µq%âº)‰×îîVâþ6KìèÖMĹWænHv¦.ãÚ°F¹›WAiâÒ† ÜûT?Ð ›4«ý[^{¡ÖÙÌëmf.,æC_aä¼¹=-ß„{VNÿ/wß Kã¥âÒê¼pÏe‘» ’/ÌÕf½vE:€C~uâïfßÃÞÛžurrpúaþgû\”à¹v¾.á†<îéx¢5\„ŸU_Ç€õTµõ÷ÒIô”q8@mγ1 ¬‰Vâ‡ÛÇ1MÚEî5ÝhÒpŒW/ÖdF4…8ôQ“åö,’8„óŒÂŸ{|Ȫõ2nnih“‚« n’Ÿ‡A²q\,›no§:)a–>5!7¤fÁñõˆ·”iÜ\ wA¨¸|ì‚Ou(Ld¸»G¶ÈŠHú²idS%¦ŠîDR‡>2£I\µ6IfsÚ¤­‘eU8´Ò˜]•¿/ÑÀ7¦fmØCÓ^@¡ÌëÊën*·u+©Öîœ;£:ÄJ³~©²U©4Ö»:kj²YÚ }°ok›Ýyßô–Y\½Á†…˜Ò푤ßà†ÿ9Iyü쿜žþU*sƒ0I Ýé®Í_ö–â=¢ƒ»øô> stream xÚµXKoã6¾ûWè(k._¢¨öP¤Ù§¦A{Hƒ@¶èDˆ^‘ä ‚mÿ{‡ɶL'ASÉá7ß|…ƒë_f¿žÏ>~æ$HP"¨Î×ALƒ˜KÄœgÁEømN£PµKÕÖÝ|AcžÌIfe^å]ßÎQ˜öy]Ù¾/›»›XÄ.ÇQŒã`UÎ..qÁû¯F,‘Á½U\Hh‹àÏÙ3ì cD1FT0=Z …Žƒ—gÇœ$a['*Í®n{q\cÒ~ü v·f(G _@ËD4˜"xÇÌ;3X„$ŒÄvì­zèÓ¥Æäΰ…À( £„¹Hœ™H¤á°¿Qö„woþŠl{kzæ ‡fóîÌx¡<ÈãHЧ¡Q« 7,¯úz‚gµiõCتª?À¡Š¼Ó ê‘¶. †‘û¾žyÚýä`îQ›Áx$; ‡˜=[1,œÍ#H:AÜ·y?¶ß@Ú”:¢‰bÊŸ¡†#û ý=ç‘Ö-P ö_Ûé‰â©Š‚\"ÁžV•@Óa˜S8LŽ^¤Œû÷PÅ Z{ܽZû–¦ñfìú}ªg¼n«á1i ¾=—œs­@½Ë¿õäáµÄ³{kôÁ£É(‚Ä?J²+j»uÄx< iÚ¼ZåMZxl±1,w¼õã[Æn¿Wµ/‘ʘ ƒ.|+!FFH o)Ša£ U­ú‡FyÖbq:º´š÷-™X5º%×S1â1}*|[®;ê ¹Í*iáÝÃÉ(Ú"6û¤œ¤û­´,ó©P·’äHL÷ùÇ1¤ú„âŒÈpÓåÕõá8ÓJ5;ÒÍÔÍL„¿¯m—NEê„V2”¹`#1PND©ÃøÌò]£V¹®3T÷ ƸåØôåÕzαA Kwѳïó¢°c–ʾY›}ܯ´×7*³6›î¸y„1”˜²B¹„òíÓéϰ†d6ÅCÛßh€TÒpeï:æ™ ÎèTø,DrÊ‚6Y¦.z¥¥[§.ó¾7tЄXï5²þ‘)ݦiŠ\»m€Ö¶uì­”œÚ·­7Â>_mŠÔYw»Ï1?î1ÓYQˆ§Oeâsy൪{µ$æÑ~Döe1œ‡‡XàЇóî)öwÒÎL–›ÝjyéÎÛÃ¥Ójz9ËÔZßÚÒMá&[Ñê'+Í]ƒ›N¹ù›ªP«»k-ØïFµî|·E–©j°Ôß<æ;ƒƒV:Í^{Îëì5nѺÑ;È• S¸‹¾¨JH5Æw¨tÝ|eïìwúw£º¾{q± öŒêÛûŽöhôÑꜺ²0ïšÂm8‘ ]j›!ÇšÜjBºúaÂw#¼H—ÅPÈÕe RêŽWíÊK>‹ß­Eë=çÈöûà-z’mÑó˧Óï6p;£âÙŸm¼a8…Ø: “úS‘Þò§7i3Ü Z÷ý(”#xòè×§¦­¯í»²›Bÿª‡Ž¹ endstream endobj 2450 0 obj << /Length 2028 /Filter /FlateDecode >> stream xÚíZ[oÛ6~ϯÐÛd fy•Ä>­íÜ"]š¤M6lh‹B±˜D°,9’Ü,ÿ~‡É’¬xIc Ö<˜yxn<ç;$ì]yØ{{ðêüàùN<‰d@ïüÒc$BQ(½GˆKæ'Þ'ÿ× ¾*/TYT“) #ÿå„?Y¦yZÕåd*ü¸N‹Ü޽]§‰zfŸ?ªLÅ•²/QŠÈäËù»ƒÙùÁͰG¼‚8ŽBzóåÁ§/ØK ÿ‡“‘wk¨–"h3ïìàÃvúcD@mŒhÀ4u@¼¶:?ŽYª¥Œ0 ­‘7ÚŒuZýZƒöù`ºáA9’ õZˆ†iù<âù´¡'!’Ì9÷Ðj¯ ì/êufHÏi=ª—Y ~¬^X®=%˜@œ„0Áª Åþ_£â‰@–Ô>aêE¤!¸é{âÁ®6~&I!¨±ZHâMCQ@-sB÷õƒ%yŸ¦cöÇË÷§G³-u—Þ°u¬Æ†€!„e”’!A¤ÇeÃR¦wã­Ô¾âØ’ ^çKÙX¥0x ±œ‚ã õ§!ˆqF;Ì›wÞ¤D¡„?3¿ƒ â"€üÜð$˜:ÊÔMߨnÞ²Fê¦ w˜âÔ9¼0 Çí Û`cáücç¥÷Áƒ`Y:p yÛFˆ†'é@ê±áZs‡&a`Ü&ÜH붦ú­ysk©1F„Ü0Ó;‚ô›óQÏ;Æ/n®vËCò=Ùu¨ÛÆÁSÈAI"oª“PPS Ž]T“ÁTE(Œ¤E ¤/&S‚Vã$ùªòº¼³¸^™æÇ¨ÜëqÀ%oÚƒ໊«ê¶(“§3š˜þ8KçÊ1cØÜaÖë1À ËÚs Q´ÅóŸ_Íf§üg Þd°ÜQË õ~}òþɶ/¢-šž5ßíÙp 6ê>ÑÆ×P†1V$ Âš*emUEhôë¶ÙÏ¡?eþõ2ž?‰Au“ïgð°%ñeÐ îD’’¾7Oû™‚Xnƽžíàæ!Âa‡—EÙ“9Z§€#~RRA "‚þÛ9õÂÆ% %d´tž ~`Ù,ûn,£"øe?°ì?‚eb ËnË´V_õ6~7D·V‘q‘mìð_¹ê–ÏÓUœ=Tµ± ÉPQSo]QÖ Ûªœ©Úô¼È§]I]„îjn*|Y,{å½/ „ûàkâM åºY@-ìÂi\䪿¨¯UwÒLš_½Ø…rS'¬§ ÄL½³š6Z:>?rqV Ôwbšïp¡[°êº5¡Ù1ý¡¬j·Pùz åÓqÊû0Œ"Cˆ†vºaìÛÑ\tƒx£Ý#ò[¥t¬7¾`\ú »O1«²¨‹y‘9’¶ëU׎ÚNu!s.ìqïo$õðŠ/ÌÂVÐm²:Kð[±t™¥ÂWækd®JT2._g~(ŒÇG’Ïš 5`¡SFl`µá2}ذƒ…m—qmWÁ‘F2ÿðÒöÇ[SÒuÞiÐ ÝÑ–ŸªÊu¾˜õ@Î@·œBßQªQŸ;CêxÁÃ`­BâWÊ¡¾•¢Ç[3`B³”à{Ž™f”Ûy-K*î;±~½M³Ì>]¬Ñ_>§Œ¬Ûœ.Ûµ›F x´só!QÄIgË â+Ë2uÊ^¥ÖŠÜhK·KZO?È„åªv÷-2‚]÷à\Û©ÄŸ¹Þ¥X~ËÆ`Jr„MöüÐ*nׯ» ѬƒŠ;ïPrŸw0GT´ÎYŒ}¦öÑ@ýFAã`ÝõcMžA‘%–Â`™îéR2ZH[?Âø…c“¤Õ*‹-–“ ç[ .¢¾oOÊ$Í›c¥ƒ@˜3J4 Þ!s"iÈm5‚v–¨¾¶ƒ¶ÀC¢l(®³ÚҨ܋ïšs±&¿[©Ê>ZLû{3böŠHG÷ϯSG?sKßèe H“Q¦¸[C“D9iFÍ.²ÿwBÀŠþ׉Ñ„àÒ=…éLÔå`ëåq¡o€Ú[%ÂäP¹¿nÁî endstream endobj 2460 0 obj << /Length 2719 /Filter /FlateDecode >> stream xÚí]sܸíÝ¿BÚ/MJÔWŸš^œÔwç.Þi§“Ëth­lk¢•6’öÜû÷’úXÙ—Øž>tâ‹AâC˽[{oOþ¶99{#…—±,bosã%—È”É,ô6[ï£ÿÓ*ˆü¢½.Ú¦[­ƒ$õ_­Däowe]v}»ZG¾ê˦¦¹·‡r[œÒøCQª+èE° `bõióãÉùæäˉ€í¹'h;Éžxùîäã'îmþ£ÇY˜¥Þ½ÆÚy2NáYyW'¿žð1ëa:b=‹YtÁb¿¿+pÓ³7q8Â’¥YÐ8kƒ2!&ˆƒÒìQF¶Z‡Q迯¶ T”øŸW÷‹UÈý?PK¨Ÿ(öU[Ðt[ôª¬ ƒ\Ö4ÍW÷êš`]c‘TO@ˆüÿ”*½/ë[‚öeŽ«‰Do6Λ0†|ßÐó 4íg<•(õ¯ý‚Bˆ³DVÜmQ5 ä±V‚”ÅÒbuwÍÁªâZëÐ[K.Y o-Ë¢ˆ)ûê¦/Zv‡eº£·¸‘}_¶Ú¤«¡çT ÿ狺7´û^³\Ýâ)Ï õs¿© OóSdÚJ­™Íµ¤6²µHX†su–MõfW´òü£/×/™RÈ­ÀˆŒ*Èüºéí\Aƒ]ã䃷¶ÈI#0&ý´¹'nÚfGdÜê©¢…‰¿¹+;ÂköEkýpÜ‘ÃøÚP0§‹³ÍÎÀúÒŽèÄÑ6øT|…÷É6Þ3oš:õEÛ5(‰eP57ɱõ%;ƒKø’'%K†;–]w( ᛕ„m R :MT\æ­¹S+§òñ†h¾[Ôk&ý‹›Ì±JãÔ9áº\pÀ”¥¡Eø‡‘2b€Xä0À‘'ª¾-§œ:¨íG‘ãЗÁî˪²nÖìöÆo5À Ü4°¹¤¥;{Ts¬B=|OØe—{U=ÉÉŠ•æ‹§;²¡4wxî‡JµËWAËzveL}åÔb…©¼7:®Àcý™KûQåŒH"ŸÑa.©áÂ0¥ì!åc»Ó§ÛâùP‡ª_bÝpnä®çC]]giÙyû9éМèvkÍéš$p¼Ûx€,‰‹«ë›×£yä%…¤°ZN²d Q7áℳ€§˜U$¾˜Lc¯û9~жOò!&ÇïçÕLPaöó˜†`}Ë/À nõºVí¦q¬Ø–ý£665Ä}¥òbê9œ Ø-ƒ yµ\s – ò÷ÚÁÛ’Ø8ö~Ä„žs è61ùP1·Ù:LY&²áXÅËjçÒ Œ”G=ƒê’= ­âqöB¬_­däÿëRÛÌû_®.® øÖÒLÀF±mœ9aÀéNùãB‰Xʇ³7cÃ9CéPöx`j±Tf,Žb‹ù‰ljiS  ÇÖúê¡]ÊçBßð‹E–ßË[Æn©m…RP4ø?&•ÌXÊa‹— ))ùàtÍ…c³ ^Ƭ^Ÿ_ýðáâ—ÍÅû˯‰'#ƒ2~d²‘$¾ª·8Hý.¯J¸þñv`ô4–\8­è½+wûÊ€¶PŠ˜²ÒV*ˆBtÎv*û}UæÊöxêÿS§á# ‘¦®‹KœÂTAï>' Ñn8‘~ÙêÞ` ‘’ónR{ÅCígó€uÀÚ 7|ê*$=ᬩ`t¬P„¶E p­é÷ß hÈ<´ÿ´H Øý]éRe y¯Ã³Á7©+Œ¡Üa©È‹ç†þ…IvŠbG7É1n›ÆdËXSŒ ª(ϸSfp]ØT¹;ä9äÚ7‡j\1Ø^d÷6'·YŒ²L‘2Êš2A-¦Ã&©ØPaÏ+T€ÔjgF¶d‡ŒW*@éôq:3óí9@×8¡Ð1të õÿ^Ô¹nׄÙM} £¶ø‚Ý¡l _¶ß¡»dxmžŠG 2À€%ÚHK’ŒŒH-ùÀD?t·ÎRø„»ÜƒD<»kºµÈ¶ÍN•5Ãñ_?œ¿úù»|õî|1|¤,‰ÜM«•˜þ ŽæÒ ÌÎQK¤Æ^‚®&qøìÊFÈ„Å\~ki°8L–J-’™6@ÓŠà,Îâ©Ã-•7ØJ¨ŠyMzPæª{¦BÎÒ ³²¼>󓶈Í%2iÎó!=D™Îüܹj‘EÆŸWì›åtÊøPåÚtaj;“$¥U4 ]Œßº‹õP º Á“êGÚàtõÃí[yCV/¦7Í‚w°¶h~Œ®KÖ3öš;ôÓj .¸~‹!9Å|jÍÂuSŒˆà9ÒÇn@&"ÒÈ*ñ¬èó3M™A˜]j>¤ —ï —zÕ4¶¯\•F®Oòcˆ"ðæO“Ò,MQžoÜÇ8…|.ôD’Aîã2'9¡Í^óÒ7’$dQipo „@ë‘Il&Оàô@èåãéˆ%üéå˜0ÅI6PË%´aGʤ{©ì†Âr|Ø.‡—°¹Ã§×’åÿ÷òÝx¿z`Þ:‹0¡ôÿo5(“€ùÀ¨K‚ÿ Ý\FAiÆéËH_n:2Š6¯1VB鈖HGÛÀ ig¬Â,C…|­*žâGG¥…yZU®ãŒq¡ï0(éb‰úÔß'÷E‚\Ç,㸠ïÙ¾-°‡ã>ßÓ nîæß8n›¦7ă±ÿ4߈©g`ÍÙ$Æèoeí7Ð8^_5¹ªžE¡»¶ÀS `ùŽñ@kͼß´Ü5¸©çIÿR"8BÓDl©+²»¼£ÈÂ¥(D`,™2©K;xß7棽n LIô—[|] ,P¢²DLâ J Éd·À] q3‹Æ)ŽÌ`Ä>Ð&”ãh’ú `úe !º(Dö·†E#Cƒ±À3d|iôÕL¯%Çt&šfpãrìÁb¸v¾ÇÅïqñ{\|ù¸Œ§‡Eüí‡+žÝ5Œ\a›.B•‡¶7†¸`Ç}Š0š5Ÿc0ÿiH¡[ †ºAÛŠÂ;X¤ÃŒS¦3!¨$m]wG}ÝæžàG3ÂWfÓIWà¥S™€Y£¦¶ Ê2ÕéŠÈ†îŒáYoãŠoý˜9û £ÕFM!¡w*žhrQ]º Ó€ePÕN  ;¨jyÔ>“bþ äAƒräp¾0ü\ÖåÐÊÕ-=(æ«®1ËÊÂø…èç5 ;Ôµ£G§%Ũ‡)ùü›®4}:Iu)`OKo€ß ?Ó‘®èžÐŸ×Óã3™ÿh.’P"~õoææ'¨tí§HɱפÿÃÚ¯OSÓã÷2Pc,³Gú‡!Ø®›³þ_Ô¬á endstream endobj 2465 0 obj << /Length 2293 /Filter /FlateDecode >> stream xÚíZKsÛF¾ëW rY²*Íì%^¯¢òCrEÒîÖ–“DŒD¬@À¨ôïÓ=/ EK²×V¹Äi º{zýu÷ ®#üãâàðÉ¢Œd1£‹«H°”¤I%2%2ÑE}½s5ÒÍ¥níx“tôjÌÔ¨˜—uÙvÍx¢FyW.jûìxUúG{¦+·Ú6ᜰñïoŽ.þ8` X”p'IB“h:?øø;  ¿(YÝš^óHÆ)\«èüà׺©¿H7ôG^Œ*«zÙl‘Žn˪²w—Ú^§‹ºÖÓ®¬¯m»[ Î’…íªqwÝ,wl.ÝÌÞÍÀ`ƒ "²Ñ, :ús,ÀP¶C^Û«®ÑBœŽîl»tôCÝM[mŸýYNukéWcIG‹ÆKöÊäóe¥­¬nº´Ä¥éJÍ)ˆ,† ;2Ðhz°Û„1’)e xà?Õ«ù¥Ñ îËÖ]k{uƒ‡»ß¨•nI`˜L¸ÅòŸ™výïÌHV¶aǹrÚiU‚avôkg‹UU¸{­ÝÍb®»™*hVå͘¹‡ð ýɬ*JW2‹†×æ:ºïÑÙ1®E¿ã”ÄLD1O‰’WcôG}3\^’Únƒæt »@A”R†\AKήY™Äî#B ¾A›­Œ$üÌëž(‘*†O2p”Üu[K ¤)° *ôºfG×â¦Ø€ÞÔ÷wjF6ýîÇwýÁâɺ¼‡a}ýìr¥@yîÌ%‰„Áqc/åž{y‚µWheÎж))‰xÁ5/É7Ä@ÃZgÓ.(ν†y¨)žòy§<¼zSNâŒP†Wø¼2@°§qàñÀÇ*#’;ÞêºÈWèxx©v5j]èâGÛnô²ºsß>ŹUVÕ4<ü%‰7D1¡ˆY3)ZËÇi=P 0Eƾ«ñ6àõd k­ïN§PôÑŒ¢¹)Û<¦DaoÁœÙ7)ëWï½ 8˼uàa­g:ýÿ¢·Å^9BÞÔÕuYÍs§(Íÿù=ʶ-SAâ4èç·oNÞ †$ÍØÝŸaÙ£œm™œÇ„)îY’á8OÞ\8e?Íy×ûGÿü×Ðè —›AÆÞî¢Ñ¯5'GE'Œf$…0dŸZê#–è#ú2- §™ÒÑë±}89ùpj#©£³3$œÙÖÉÑù9âá+Œ>ŽÎwŠÄI ÞAؒܪ`¿QÅf2Òo ÎsXÝène¡¼n=ü:¶aèY4_3ðþ,‹”ËǺ_`ð´A£T±%1p¥˜{â½d ÷Z#4á' ¯m(ÿD†så½|½èö¡0‡©åÌw¾Z¬ áy¢\±HEÿz/øCº¾ ‰0¾È»ü3Ü'ª‘IÂdâyßÎÊJïÓÄh0ñZw&5чOŽïÐã4•yåB‚"§Û&Ô ÂDÄüp 8ßæý‹™Oç:_{ü|WæV”Eí¿eH'AdÞ9|È]î×Kˆ¡½Nx×]kåóã³×^2`çICqqs2€ü ƒ¥–²~¶Êïü^†ú POÆ a”}ÔÞ… `²!&°t  ½^hß(tÍ®å}5Ô{¶#|®¨ÇTõXÕ¸ŠU}S/nk—ˆêkv®a‹sÈF‡ÙH7]þÝy陞Þ<‚—yi‹Ÿî¦Ÿ¥ß.  Ÿ‹-„N÷à„÷ü; §C þ9N‘h §pŠžñl!‚ÂU¾ Ä Bô"{Aˆ/…ð…e"ÛŒÂ×(­¯p›J>3r[L‹ÚW+¯ ¢-öøÔxèS—Íâ2¿¬pînËË~2üÖ…¯Û§YÖº+èxå¢sçPÒ‰ˆñá "¿_H£íNXÞÛH2²œC¿êü–*¶qÖê<Ä Ëçꆤó”¿Ô§^êS/õ©ÿ“ÆOLòýõ)!᪜³p>Áùásfáëb‰¦¿µñ•+Tü*ö KT«öžU<ØÞÛQ‚uJ± …J= •¹l‰èì §žJ©$± <›Îm‡e¥Ÿßxýê=9;zõþd‡ O¦¤ixy#ï°"o8s§ ®C-4ž‘¨ìMs¯ŸéدZ™7Ü4A(ǃ+Öjèžë—õÂ! æÎ³ÀÕ–Ú 1[›&œS³àKXÈf·D»ýÖ›v¨æñfŽNḳÌF-æÎ[¤(1í]4wOðÃ>œ¸ ð))}pÈTDŸ¨Üo%Þ&Â(Î \ÃqMq†£7îí·ìÖÉD26Kwé}Uéâž=8x}éuõvu¥ÛD ŽÞ|Æ9Wv†a4›Çlä—9fstúï7ædÍéÉÑéž9¦ý£3çºg~׎ÓÄ€ùv<;cévêÂŒ¥;A¥—«û¶6umb²YÔó ØÐñÁø£í[|xØZIüƒÏZoŸOÌKÆøæ Œ'±Ì6—/3Ë£&D´”<ÉP½¿ <2ó endstream endobj 2475 0 obj << /Length 338 /Filter /FlateDecode >> stream xÚRANÃ0¼û{´%âî:vµ• ‚æVz()MZ’ßÇiRh BˆKÏØÞÙ™EX˜]¤l0ÒVÚHE>B¬ Ö‰Ô6„4ƒ¿ÊpW=¸jS‹@Å ?dxVäe^7• _4ù¦ì¸ñkž¹³îÿέݢv݆¤R’Ä<°aÊ^ùòÔ•Ó2Æ–›Í2Oehxß*@G‰_×0e· {韫$¯¥ŠÂöVDPyâx÷Õ,‘´Æ¨}·„ø떬ô¬Ùéü!˜‘O‡ÃÞ±ëéÍÑ“ƒQ˜xŽ(í/›ND½\ç®lîÑ ùµ~äÏBá>‰–‹¸Úù$<ý–/ÝŽ4d^º&kÁ¤„œfa´ïäÏQü8=ÚçLª·S«Ö•(~ù´Ø ÃÑNS?VŠ Òö׉ÚV›U‡õ©ôÑþ¢L endstream endobj 2507 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ]Í¡Â@„a¿O1̲»·½ÞY’BRGX×TÑ€¡¢Š×ç‚@T}ÉŸIFð‚àJ²s#m ½¡s¶Üã±Ò4 ––G§ZðùVx.Í7ît£sÐéâŠÊ5[F<ÑYâT n¬jˆÓA=çÿ‡CСq< endstream endobj 2415 0 obj << /Type /ObjStm /N 100 /First 984 /Length 1840 /Filter /FlateDecode >> stream xÚÅYMo7 ½ï¯Ð±½hDQ$% (4p[ ‚&‡¶Aiº(‚ÞÂv€öß÷QëIíµ‘×Èg–)òñ‰Òä’4¤K²@\]À?&.´PÈ P "þ†JЖCÃ_cÆÿÌR ”R¨D.”P%o ´Pû „\ð{Q¥25—ܨôw5Pi®‡H™|¦6uŸ2ænÔßåSiHFU0)ÁNÆ#$¸›ÕÍfüÃÉçëÆÙ—˜1•T_H†q£zùCá&[u¯8¦¬°Á8«;˜“[Ë©d—¤Ê Þ/ ’º^ÁI¾6ÿUŠG’1Â’¯ÃõjN°ázMÌG`æÖªK}‚2%¸†ŒxŒ¡RÈ‘” ©{Cˆ’{ ¹|æ ©¯²`,âï6 'Éç3¼ñù óIu»óiv»VT](F®‡,÷‹.†ÜC¯µyL‘PIT݆¡(Knî_Ã;Æò ©äXÁB‚8* 5H=B¥4×CEØßa©"Ö­Õ J ‚Æž# “–Ù^ôðœ€eÀCe?ä™$ßgöO`<ñüRb0öåS×Ôþ„I§g»w/·ÈK˜^–A/[“üåÿÑ“\qì)£ž´/“J‹Is¿˜W‚~yâ__ÐÐ ñ#Æ$£u¬ìqÜõ/2Ê=[Y6ºú˜l8’Šß§Ի+THlýÛ!6÷ I'!%g9ìiŸ4 è·ã‰—‹o3iÀ4H2úgãEEFv*þc:ÐO4%«\é-F:zadù‡êºWì-ÅZDxbóoõç}Ð"'o>íþ0ÓÑó¾žÐKԤˊ‚í=)(’—l[Vô»ŽÖlY‘«ï!>æê—Ëz„¨‹”Ïyr:·v nힸ½ºt†-\ÄçØUã\~cÕ’äÞ«þ û_. endstream endobj 2512 0 obj << /Length 2010 /Filter /FlateDecode >> stream xÚ½ZÛrÛ8|×Wð‘ªZB¸˜7[VØ+kjk*;•b(ÚVE/©d*?¼ØD‰eï“lJúôi4bïÑÃÞåà|6}àÄÓHK*½ÙƒR/ä qͼÙÜûâ_©ð“ô[’n²a@CåŸ ‰ðç«Åz‘mÓa üh»Ø¬‹ï.,æÉ¿Š¿§É2‰²¤ø‡ Jþ5û}0™ þ7 0<öH1G!½x5øòöæðüw#¦•÷wþ«•Ç¥‚Ï¥w?ø÷—Ðí>F‚I·­ec»asMÂÄ“`bQÄ>6Ñ}<»›M¦yÞ„pĸ¤¦M@(Òœ{eHR´™A¼ÂÿÏä3ü<ýÙ²! ?nml&(¢,ô$aˆ#ºš\_O¦ç€Xø·÷ыɇ¡8†ý?n†Z”¿ϱU|bD€ Œ¨d†}I¼¾Øy8½@À 磒¡P–‘S\&ø¥Çã{þŒýËdÊZÌ“‡èÇr›YÝ»¤ Jç;¤†:¬“Š0d÷EKHIÓ›ùp%ˆBDhÓ›yVµ¤H©ÐKï¡&ŽÝ¤AY&kªêHRÄ@¨¹dÜ~ò<3]Ÿ!Ò¡òÖH邿‹$‹ÓÅ3¤7Ÿv9#Öø/„q„!S Æ¡CÚá.ÂC‚}“—6\1$!Ï!!_´+®4 m“µ±¢Ÿ‹Èجhå^%ëVxmÓ^2æf<ÚNC¦vDÇmórD§iŽ>ÜÞ FúJP‹èöt“‹N ÄYØ]tjWt&¹Kª¿)öc ¿¶Ñ·¯ó俘ñõ¢’ K»ùv™”Ä×q6‹ÓF{PœàXÇ-ÏÍÜL܇Ó20)dlEæx .ƒýÙgãÙ§‰c‹{á¿ÈÚ†ß*kh²#k Òõô\|½vð TŽCíè7Ï8ÕH„ÄÉ8 wÙ=å°.aXxŠÕo¹('›Ý“İ/Š1ØTbhŽäMÔPÔ06ѵHb_/’°ƒ(%q š¨Ë51¾¹‚¢Aû$šKƒiX¥±``d³ÐîŸNô½–T;ûù’z1þz75ëÖ퇫›ŽæÉ`PvšwÂîqZ"¹¼ÏweJÓØPú5®°»^ÁHÓîzm÷>+–÷_Y­¸O2±Ç,_O=ÌŠ´Ÿ…¹Yûúi2þx¬Q %¼'ê‡ $̾¿ò±ºdñxA)fŽ[TòmŸÌ±½|qNáƒt­Çœþª©GûæNôœ.Öñâ9Zvµ"'þƒZ:¸'£!GDð“V4 Ò”ºLù§(3LlÍY‰R¤^–7© øq”=íì]¼ÃAÿîë‘雫}¨8Ò³—À²~)»RCe-W]]ÇáèЪe ÏU •  W)<Æ ìJCU˜ý™3ÛFa¯? ­ðwƒ»œ …ðÇ@?Q„¿K=]c?š¯Šâå±Å’CX%ÎfÆÞDurß¾Z²yèàQvü¥ðö…È£0…5æQ>e™×ÛÙÝ0ŒùÙ&6öTxTã©Â|‘&ñvShñWg_²¿¿/Õ£›šTÿñù˜”K–7wRÞÙaìh{; ¦ §å™hÈ@•¼»åGp—@råï+CšÜ6·¨ïž`+¬›«ó–|2‚„­|Žžs2²®³×‰°%©û'/,=Hâ“ ¼¼QJã¨Ø¢$­g|ý&¯ƒ¸ýV¢ñ,ÆÂ<ú¥£íê¹ëŒr ôÚiZÌN3÷…±¹9=ÂNoüñÕZö „(îܹ_ \"Êx¯*qž<ÜùµN $÷“uܸAÝþzî|¦ëDÕ÷ÐÍŠ+J2*do³àiÅAö‘@ËΓΆԿ¬»Pô´›BÌ hí^­JÀ›TXe•ò=ùe2ŸE&±f/¸\dæo{ì ªpß9[yO*[oÒ•¹†$#TíýMÇÙncï½|Be…wÔ¬Ï .ÊÃý»â%‹Ü> stream xÚ½[ÛnÛH}÷Wðe°0n±¯$÷ÍqìA&gm‹Ef`ЖH-I% öß·ª»)5)Y¤Äl^¬/Õ§«NUWU˾÷Åó½ßÎ^MÏ&ׂz‰SÞôÑã4$ay‰ˆ¸7{ŸGoÇLŽ’â!)òr|΂pt1¦r4_¦YZVÅø\Žâ*Í3sï·u:O~5ãÛd‘Äeb¾P¡ã?§¿Ÿ]MÏþ}FƒïQ/`0 x³åÙç?}o×÷|£Ðû¦ŸZzB…ð¹ðîÎþqæ[ü›OB¾O˜âø–¢^7v.ÞnWLáB1\2NïDˆÀ¬–Á+äé³xŸÏ¥ïÃêW‹t›Õ¿}}i«"_Å_ZJ›'ñzQ•‰'×*á)NïyUà¼ùêК˜a¢~%Îæ!(`ï.‚ù!œŸ†õ;`° õGE¼,É.Y#I8¼®^‰6aƒ(Ø–Q™ܒ–d\|ü¶G¢TÚó@"^¯ßf$ ¯H¼G—÷/‹b(JHâ3^‹¢L_)òȶ,íöIä°Î­f:8÷¢(Í9M¾ Žá\¸sàJŠÿBô0A,† gvü¶^Úëø\,ê¸åÜÏÇ&ÈÃ|ì„ôrqhÃ\w9ïn.‘6ïº?º›b Öéôêõ›ÛVˆR®vˆ’‚Õ!jò\<ÈçùlR˜ýå•SqVvéaãM=ôqá^»CÈ¥” ¶;XHE‘cw»CUÉr•q¡uöý°ùœûÍßÄúÌï®ê‡›ÿ±È—÷˸¬’¢KÃ75Ðeøƒï Båp‡‡Ô+6Ñ|ž?Èûu•.Œuù,v¶›n÷nBú öuÁß½zó¡Ã< j›íL¶Ëíë·Íñ[1Xë`¿• .ÃxÝ6]—k¶àüÿM×~‚éôR{z]kqC¼N†°N¡›-ä$ä|7Ü^Œ¥]¾;esmAû &tñã«Ñ ‰g½½³¥€AÞ©BÂ":ØÌd–Á®wÂŽŠƒQÕÛ=›xú$òá>‹¹x)z;Psú|¸'ƒoÌþöãíXÈÑÍÇû7·H–i›3K¥ˆ Ôi)<¾Lƒð¨²ñõ8$ƒúRF›ÿ1=Ž×¦qa[qõd;DºJÓ4ƒ/Ÿ°Û‘¥ÿ9_¤Ïè“¶!T~Ç/eUT²<¦õqƒ]EA.÷7rÁísäêö‡ô±Ä^”£2_Úû5LÚVŒ6­¿35 f4OVIfͳZN/H¿¬°Îø”—‰½WVô:]ØW«t™ñ9Wjtˆµ†ðQ+amPçKçÍ_Q3¨Kx­‚ê)ÑÕ›åÀÐéõà’Ìrý0O‹dVå&“NûFþˆÒ[!‘Jévr&ë²˜àŽ¾0Ï6L#T´›×Rÿù¤u#£JXUÂH·­[šUIÝk©´ðfVCŽ­„|•Àý4ûbWÒ0.Ú–Eºwåèõ« ˆd´©¶¸°%äÝÓÌ@ôbC[Z4LˆåGn>—qenm{ezà‚Ãö[Üß0”î^Ú¼oS¥Ø0O€´uEööGD)u0n@ŒôiÔÙnÒÒÀfÛ&„}ñ¨N„Ò«–›] ð¨og%H±PHjéI}&*¨cw€D #Ù¿ßé…}»äîûò!‡êÚDª ü¼³éBF©äŽVX@XôozE°•@>Ò@s q·kŒ©K©*&쎑š]ý0ʬäAÅí´‰o Ȁëc„Ætsw6d%am³²c_µïIE¶Åv|c’­¥A:ÈDOçxAŒvÌ‘TtŒs„{œŒC¥2ZþT&…MàÜ.uW~ºñ’&¢^îó‘[7¨jÏh©¤›x]iã.‚íÞ4yH;;†¤v „—ÒHC˜IQ1”¶i[þ¤u“Ìlí@’8³EÝj±þ’n»ƒ/!Ûð¤ îTž8àÞ¼rXòb­Q³¤¥›SY²ßáÈ"}è,:jŽ ÃQs¤ c à%’j†pP»’ƒÃ‡Ï¡$µ¹ÏGL8!Ê*›»<šOs2‰Ù‹ÎK ³mÖ´èZZhO¥Œ‹ z†ýžb_B7'œz¾;â´µx*—\`›¾ÆE߈3IͦgúƒÑ†  ¶¹Ä°ŒîM%º`Ñ.“¤e’¬™„‰Ö–;ûª‡Z]ѨÞR«'öšY.ø[dѧ‡hÕ¢Ú µÆ|Ô^V¹ š¤šë¬o˜†ÅòªÅ™üpˆR*>0Dq`1¢§¾ÀJÈü¬D‡",­¾bs&ö´`ž›\˜wÇ¥=m=„\]Ê#ÒžHj²´”}Ó.a)<ʉ)º$‹*1Ñ&Ûl\Øj ³<{ÜÙÇ:ƒMà©\qÞ!§ÿ…€»K¬ßn>\iZ;•;."‡_/ú‡®&ÂSyä"ܺóúè ÖRÙ©„rå«$+gç«çY rʼw¨†¥æÒ(¾',ìøÆ(÷¨/Ž94ØÃAæÁš‰Œdý«cØ ¥>sˆ(Í©)ñܬÞðšoúÉ?|éã· 7p…š§*ÓD®ÏdZ3•ö¡|Ï¡…úaTŸD¯m–Uè¿p))ÌNq^¿ÒØ0~ù+Á­bbÖã¸{›üjñÍÙ£>¿L” §y|À=ÍÃ˺eOÆçŠPêèK™Sáà+¶«·¾¥ }±¥¼¹.í ±ùŽç^æÂ·§´>©jJùª•¸ù!Æ9›åÅO¯´:슌6l[³>;þÄ«y®µi9í9mäu|µ9m´möoÐ=èöœÑ=-n»Œ„©ÞÿM°û_xÀôå6ÿ€fÑI?é?g Ïr©mÐÿw§øª endstream endobj 2532 0 obj << /Length 230 /Filter /FlateDecode >> stream xÚP;OÃ0Þý+n´%bl÷üKU*ŠoU‡€Ý)é#IÅßÇÔt@t`º»ïN÷=lAÀ‚Ür{<÷F° ,:Ž~!Š>2¥iêßR¿X¥¬£S&5]³k†±g•¦õØìwe·851Ý”þ%µ©R$WŠK¶K2äHd¦ r+,¼wdµ3¾Á'ÞÁçùª4.×^É3?Ò/õ×/\™¿ºê³N©Šy‰&Ëw }Ô¦éȾÓ(ž”à¬2èéÓC(Èß°bÚÔ§vÎÎ/’s_-aXÇ endstream endobj 2536 0 obj << /Length 308 /Filter /FlateDecode >> stream xÚ•QMO1½÷W̱=líô»G0«Bui09(¬b6Ñ¿ow‹ rÒ˼v2ïÍðΉØãÁ„œ‡‚ea¾"Ó™€EÊAð,|uU+ÐÖ'|‡1¹%ýHNÎ4BàÁJ ñt@î‚ ’£00¥§¬0ô¢wËŠÍâ°kAÍ•¶²í)´âRk(¤â1÷DVHCïÊQz ¡÷Ìz=*Û~RÆß¬­qÜ)ý_Ö”öCš„ŠëL Mk—^u$¤ótœ ½jÐë_–ã,Eùõ©ÈvsŠ–‘ßOŠË×m«FÐy³ÞÕë]þ,÷ÙUÔ¡Ÿm¨9µk2¾1)h½yª7ÍöAáR@ÞáÇ¿ãcÍ¥uÇ·PÁÿÑA“\P^‚N¢Ì P»ãß]€† endstream endobj 2541 0 obj << /Length 238 /Filter /FlateDecode >> stream xÚP»N1ìý[Úgì=Ûg—€B¤PœK÷ß~'&ÕìK³3#à¬É­'×÷J‚ãΠÿ B£,W®ßÁ–>0Ô4¤}HÓÌ*l,½aRÓnˆcœ—Ä*MÛ%NcÙ­?c®JýúÐΡ4’#rÉv~CVž|™ß åâhà0íN@—ç¼v¾ÎW(c3öðL‰ø‘~Á_\Zq4ÿ¦úÓ½Ê:%óRÙ,ßêéÝ[ûÎ4]Ø)â %g•QŽ®F†‚cšÆ!ŒKÙO1µ)¶û>ÌgãÅ9€oö³Y% endstream endobj 2548 0 obj << /Length 1968 /Filter /FlateDecode >> stream xÚíZmoÛ6þž_¡/d`fH‘ÔK€ k³$}O›¸†´d‰I„È’+ËIûïwäQ¯I;I±bk>Xä‘<Ÿ;ÇPç¡ÎѵßO; ¾ÔaNà9£DrßI;g©“ý…CIùÎéµp„Â7wNwÞí<íì æD$ò=ß™;"b$¤Ìñ#0*Yꜹû“©tŸ=y;;8™|œ½0C˜ \øž3> îL=N"ÆpÌl2õ¤ûÇÁ(0éþ UÚ'P<ÖœvfCù}€‹måï Ã#(ËÐñ'Šr2‘îñû§¯NŸëÉgÏ߀TÔ=2B4HRÂJ<ŸÃ/÷™SAÃ-âÉÑŽ3åžg¦™úœ¾]3ÐØãöœÏ¦’j êVö8QZºyyq‘þ»‡<ì)‚ BIÅy]®&} ãEä.«òÂ,ºŠ+M ÝõJ34­¯ŸÏvUÍ%’‰°PVؔǵª”ÄÒæ ‹8UH©Ëv¾ —îu–Ú.Yq>¹QPg¥eÏËuÝtÂ9¨[ÄùX¢<›W1¶~±¢-Ue­4.bKk·v}܋ܺ2@ꢒº¤# [TÏsÛ«¾ÌV?C&Y©º¡)´ÐX‡: "BÁ@)Núòä©ükvòdHwÿû´ä£ŠlwUL8”ª²X¨ÂNt=mbWšõd²rÆøù@¹ÈAæ…n&se¶Ýqüº(:pŽÆ•Páê[Ѹ{¬5ÄBЖS£ÎZÔí@uõE‹‹¶¦5êz.ÓÜÁëƒáQA¤ »©ºÞ]Õ©¶‡ÛÈɈŒ7}ÑacƒL›³J‘blPK¦Š†‚ú×Ýš„KY×Kc{ýQf%q‘ÆUjáòñä.JZà HÄ96– ³ký[»Hi‰ß¢¬±pY°)î0,Á6·+Iü@4ÝFÞ*=TXž«$Œ°¢Õc5 µ–¼Rɺ²åÑvJRÂöÔ»úsmóJª· Ö.´!¨¬#ÏuÑ‹—ËZ™õïÏTe{üáãguYZx°Ž*›”ñb™«¶“&ßXáh'4í M»-å΃ëÙ ;;º0Í­L·®ž[ÆÍB®®‹R k”@Çø–t58¥ˆœñ×–w5Á‘ 1DA€k…sßápöû°• Šp>9?À¦ØmTMÇÀ"àDJiÈ9Ô$ñÓ±†|ÛÀ Ìô;ÌÑ«EàŸ"ø3ÃÛ1”!ý êX2êÙŽÝœ-®]-o&íH´Ç“v“&PáП¶#ðCÍú’ÿÉ*ÏwR$uˆ¤?G­u@…æ7ÚÚ4@*X€gAà—YèÔ¤miQkˆZS³xµ½)%¾„£°cKïM¤k£:;Vò) ÷ÙY·ÂXûmúù@À?å€Sˆ¿U’ŽxëœòN ÛZ]*8p¿ yóc„PL@ìþ4ˆyu„lN™ë‰)4ç"ž‰›òüeùo4hw$ˆ ÑÊ6“Þo#³ím©š×õƒ(³ƒÓÙ6<ȘÇþñë»‚ê³ÆUë[‹Ô,xséSiÄx8æûq ÆÁvD! =Řãâv¤j Ju%©T ñtç+$À_Ù™¹¹pÙ3ó€r¢/VßR}F$‹šØê·¼[ØÐhg¸k‹6žýš6T Yäô>fýëpb¸CzD@à9Pû÷e”÷Qb$Á¿ Ck~i&qÒ\Ä—pæ ¡>|þê`ïAHãUëÞÃÍû! æë,OÄ¡Và³êA<ú8ÃU*òØ÷åÉxȾâÉNT]e꺵˜ù.8›EwÃþ¯û.ØOÜ~ø®GÕ!5,¶á< Üu`Öå¸Î«r1’•J½A  ì–PLŽ•ù¬ÚÞŠµså@G %ØèíÌ?ÜècºÑûX*±ÍbÝdõå?ª 'jÕW©Õ:¯÷¶u³ôQ‚û÷ÅUQÞöÌ.Sõ01´o‚®Îßô(¾i¯woÚò¨ßþ6?Àø¼së鬉ÿ„$a$Úg$ïqž‘^e«_L.¾ªªJó®´z”•CöìÛ‡ZØ-á±ÞÂuÎÔȬ>éß5\ëò/¸œ•RÅF åÊÜp¤~±Uøv'22² šl‘Ωú(瘈–ëy·yø—¿ïc¦ó2¶IÚ¢´ Øõr©EfÔm³«¼Ë®ª"’ÎE/M¾¸M«Ö_–6Ÿzs™5ÙÜ‹‰|LǺÍÜfE¦/À6ÓZiîÝ¥x”¦v)ƒ· ï›À4”%¾6¤*ÓHý¼ò¹yƒ¥§{úá‹+Œï‹ÿ&íÇ¬ŠµI}‹X\kšµ‚D Öšè—qVXœÚæÒÞÐ:õy™Ye܉ÀøÉ^ صÁøÅ^gZ7ûéqÂCÏà0˜}Ù`"Ì sþ Ù×c7 endstream endobj 2561 0 obj << /Length 2380 /Filter /FlateDecode >> stream xÚÅYY“ÛÆ~ß_·€U"ŒÁIº*‰,+²ËŠ¢ÝøÎÆr|/Ünœ;¢::Q²oé\_ýëÊч¯§@rß ’W%Êi`âlðí¨¬RÞ6Ž«­ò=?LY[þHÌ?¿ónû¾û¢ij²Ø­5F¬´[¾{Ïm–l/îøÝáfr2*ð¢8tÖAÅ,¯òæ+½Àß  iÿ£MÂ2.ß"ï$Yò†iæúéÔà©×§ïWë0 Ý×Ôycß噾C'0<mßNçà% ‡¨w—¥euU™¬+ªÛóE­;…¾ûÛ þAû ÆX‹Äk•zÛP|5ø&Öx.šÏ“EPêCßšýÿEëð›h}½v¢ú@CrÑ_÷¤fnª®Èôh¨÷~ìïûf0Fkª½¥åó{†s $0„ê̦KöŸkÛ%þ$aìÅÛ'ÃÏgÃÍ [ãmì)ÄÂÖž3äZ0¢ª+úÓ Á#àP‚‘i×pÇT€{ZÅî¿ÝýIðÖÚ š`XjPŒƒ€Þ]¡KîdSfÕ匞{¾`SÂÚ͹òN¿‘Ÿ4Å{?Œ²IÞ8hw®–ª¯d–©R‹°òç z“-J»GD³÷‚À`>ëªÄ°¸çù\ŸN¦â»ñ ;ñž¬S]ÍßÓ!Rh°¨²â„&"6E—skºWäþð⚇?aö0èØ÷8ÝBºü˜ÌX76ûb#ï—W7Lð©ÙÅ<¬¼Tv¢A;pnd;”º3„ ¸T†ÖÀX w_´zWš–'I:Þ±`4¸7”P÷eçÁFAjÉB{T@z’s‚µ…0Ôl¡ŽhPpgŠbýI6î £UiY'ëŠJïͯè=ˆÎcSku[üaDšW¦¹_EàD½l®«ªî.ÙãXp(5Ä\m y#ß;ÒQvÀÑCS¹E’a«"_{á0ìÅÆ¬M…æä.™ » [½s( „ðžºp¦TÅz벬ï>ÞÍ>f ˜,ƒ”åO×ô†y, ŒÔ‹üÐòÀE¸o—KðüÙÄ„^’lß•Ånâí‡Ç"3V^’ K[I»x6ë(ÜzišÌ¨>|™¨P ¦Û!B xà‹‡Ç$)’HÙ%’ŠŸŒ™‹u£…ÊY‡ÊÛ¤Šy>G‡´EÕˆÖº[q†CfŠY®‹JÀt˜²˜;®àÕ`Œü~*°?*‰#oc±øhÚVßÒåÁfœ=¦k#ô]®EÚ7?¿zØDÕpßÍË‚xtÌR=›L÷ö^ÎÉ:—,œš#u¦àÛÄcfyŠ_WæÔ©5r[à1jy¢¨”mq[ µ ©¶DzW¯Â«•±¨ÎÍQJj-, Nã1™½77) Îbkh°ºñ%uy\Xo§¬Ñ îO'/O0ééFfY…óM·nYßòîYá««ýbÁprо+Ê’[ÉL1±–¸¾÷ÿMcØQÖ—Îhâ=µ£÷ÀJÅc_³b2¹:}#ù˜¼9ÃlÇdŠƒÊS •‰ÑÆXih°Ò‘/Js{nÁ©•©ûÖfyœm‹Öò üöwȉéQJ¡{ÔL´˜hpÉ4ö7è“>Á³¥[gâgâ/ÏÄç3aù^šJªv×ÁÊ$xm,iï0L†½q5įæÏCDwÁ©‘ˆœ:$!§NÆ©85ÎÍŽ¹m§íè¸]T_–RB–'CV¥k•ÎÌGp•[I榿·Ýv)ܺO½†k ü–ò輊K51xÈ3N”ax(fžÀu­¶$\R)G³ÚL­ƒ{$ 銿3Ô‡þÜÓ•­…pŠää&SCHC¡•Yzjj[^ÉŠiÁ ]fKµžš^`` BS×z]Kå]ÉÉ\’rŽh¢¤¼…ø?/ f=Djì±d}Û Ã 6Ò)e]=]Å2£,ïJ•½R,RB%B”uu»î$%o,ï _X›øR• Ïü4%Æk:6¹¢5ø64$ýáNŽåFÝvg—ÓÙÉbA+úÈ¥ñ)e‰\=Ñ¢ü:ŒÜiqÑÁ-’+J…vB¢ N%äîÒcCŽ˜Ü *V²²æ/I¢º„=ðÍjñGP) 9+Î%„@¢Í¨1ãm£,…×Ît|;öÎ/ú´õª£ž9’dã‰û ÊÒ4\#P±»Üg‹0û=‰^âÙi}5—›½Á¡×Qåjß྅‹QÚŠ¥ÀÆè%Ða/‰ùJKߪ3Õ¥£Eµ¬¡ÍûŠ{¤ PÔôØ8X¦£4†µõèÞ0#îM²ènB=—Ì€^tÛ7K)t–™“,Ä;ÏG”ã’«xØG©I…NehÅ0‰#;Ã߯ÌS‘å”é= v<¢ùsýêå?þýfÎ "§†JàáÉg@Ûrˆñ¨0•ƒ"1ÛtÍxnŠBôRBo üãáÚÊáMkÑ´Úëï’TølÇHÄ}3”þÚ&ûmç[bôÕbëz“£—^yè}à¶6{䥣GÞ|zÓÄ=òÒˤ<1Í£vÊû¹ñ29œ›ýûŸá'—i½ºøÉE~ì¹±øÙG3?´ö¾â2Ê}pYñ‘p_,‚êBд üGYÊ{Ôì¥öI_|¶Ími/טئžÖ&Sau‘"ï JØØè¤F¿²ÌÊzú›ÁYí$Ú?®sø¸Î3 µ”>+›:½;·ÂÙÅ~ò˜uI€¡.úÃÕ__z½KR/ †×;ª”Îßç‚ЋÔp¸T'èq±y ¥ÃÜ_ðg•vòST>Þ£¿@" Ÿú ÉÅß=¢nÍò³‡Š}DÛHEîó\ÓSýjDšvD[÷f•úXNâ#s^ó Øò¾’þC¯Á endstream endobj 2576 0 obj << /Length 2687 /Filter /FlateDecode >> stream xÚµYÝsÛ6÷_ÁGj&b‚_ê›/qš6Ó\Îѵs“ôa‹cŠTI*>ÿ÷·‹] Åøš^n 89©¢/IÈ ~:±~ú%ŽáG¥~χ„S¬ÉaˆÀTc¨Ê|TA¤0º‰ðK1Áx €Å‹ ÿ±ìD»;Wµ&"Ò˜ªªÈÿ(ZüCôì’§ s0çŒoMœ÷…LC½ )Ô_Óù_Ð.‡’M€€4ºÐõAY<ñÞØ¤¬5³:Mí3¦‡Ç9ÆÆð;9%N• aªDã(„2h^ÿ<ëàF¤På¿å¨0–'^ŠB“†©_è úO6‰À™M.% ˆ-›u˼ƒ¤ß]Þiîî[Sºȹ© “5Cក×ÌwÄ…a@£ Œ ½×]—3ÌÙñ4@^— Œ²AðpÛØ¾ãµD½*Æß‚Oa&çò"¦#6gÞ'/Že]òyo¹”PÀ:{M‚> 6ŠCì/?mÑ÷å%$$BbMÝÏBÅùý½9öÁ„­Þ“ʱ¯ç5û§“84É$Øju¥ÁnØ ÑÍS¾T6èá„£A ]ÐDŽ¾Ò¸ª•â E¤Ï  ”r©Ãö¨!Ø>3 ^Q‚©CûJô˜*Îp4SþŒƒ'††Õº5(òf;tv1,[›ÁíÜÛÉ©ìü#O9h»Ó±¼7u?á û^IW,¤Ûðû¤Ûí*CD'…¢ß8ü> R5þ{ÂÝâfPª¤N6– T2§d¶åçPŠç2xDÉP§Pœ¡läÀžô9çË–Fg5àˆ%Lƈè!θY@‚#ºâöß§†ê4ÁVh9 AÓÞ©®á`zà)m­çðpýŒæ4ýaIvC8æ6”TKDÍWjî²PG‡iàGõ±ßlíLG­ˆUW­ñ\4Ç)  6N 7~¸ƒ ³\%ïè¶ž¸³Ä\´ÙÄï^þB“&(—Yhçì }g²ý¹êƒŽ&ØÃøt< šß„>*µºîÁá}]Xà a3ãü‚ðƒ$ôOBL°Ñ¦† a^uD¼ðäèè³ûÖ¤&þ²,wms¤VÎ{;ò›\Ã=Sד9µaþx¹€(e·˜;uÿb†»w¯_Ùª)T™Ùh{î&‰•µr^íî\ï{NúNȽGn¾„(ëÆ$Ñ™dSœOÒvÈûiR 3=.ÂÉ_‡Ö»Qn öÍ¢%Eàü×§SUîmóºIÐñcYìèk|*¹g£h´¿ ^v'ªSc7oy%Nh,À¨ ÃÌܘQ’) àÄ ”)M&®Ñ€ n2ÖV0jbйˆ4Uª²‹SÆ"Ìs1ÃK†cËEç‚E&éÉt ¾F”=WI8×€“4ºt­tŽ’Gy±ttWÇ4[=”3N(0Z;>1`<Ÿà½ì'1_S—bµõ™ü±@ôÿ¯3|„b¤–ËÑÈ[.©dÆ Zw°ÅãÚ¦Ì#MY²j:BA‡Ì2Z+³ØIÑ2ÓNmƒw º ìª NcK•AÙ LÎkšÈÀY§•Þ÷ÖnÂsÃ+¹ÖS‘N5þlôeà•}^š(¥ü|–1£hÕQæ¢z„˜|_ǦsR6á#G§‘Õidu 1øÂp7X>Z4nR3[ÒøËKTÃXw´õ’Z\¨ËB±3׌¨Ú¾É‰ â4ÂG¸,á7¹‘ÞäÎ LÚ % =?à&'¾[ ¾[=ã 4Š-ÈׄP J —kÃêð?Šœ*óÉ„·z0—s'}N>Q¨ì¢ñ®J%Ù^³l ‰;M×82T8lŒög ¤ìig/¡2‹á*:¨}­— Idc±  ƒÜŸñ ƒ\)R"ˆC9{¸Ï9îôPÐÌ®ûn=FÍñág®òÖÆa.0LV‰ÅàE\?9g.«É3‹á!â²Ârª`·Ðª ÙXˆóöŸð’=âøâK]´É?xYD˜_3 /Ê~øy:n0"öú‡“ˆ”‚?£[r|R6þ*¹19 _û˜,•ƒNu“Äøh¥}GÁ©ó Óê†öÑþUº ¤2÷y£q$ÚÌnT8TÖüxTUœr‘ÚÔ³…óhe0Ç øj%öQ Z­Þër¸DöŒ ¼Ë=Svô1 ¥íùsÇøòlS¹ ­¥p›Ø˜NoІ§ÝÎ)Ç ç„ñgEšÕæÃÌOüAŠAŠà\Eáþö9˜ºçzÖ“iä±¾r>™ì#7‰ûæ†]ä‹¿”=:êp^Ǧû>ƒøBZNA ŠSR©¦Å=ü®F]†Ï™ð@½Sûœ´<F×ÝÙ.¤û‡Ü¤3áØdÓÜ1wè8 B(Ìfþ¬¾âÏ—_Þã/Ì!~*’’}YÆr¾çzáð endstream endobj 2582 0 obj << /Length 2288 /Filter /FlateDecode >> stream xÚíZÝoÜ6÷_¡Ã½hˆæ§>pmã×´=Ôu_Î1­–Þ]xWÚHZû‡ûßoÈ!µ’,·¾$5ÒÀû°‡äÌp8üÍ – Þœ|{qrúZ² #YÌãàâ:HxÈ”ÈL‹à2|;ã*Ôõ\×U3‹x’†ß̘ Ûu¹nÚz©0o×U‰moöë…~Ïçz£óFc…Î ›]]|rvqòá„x0'IB“ Øž\^Ñ`ôïJD–w¶×6q å&øåäçÚW]¤#Õ%T$¨ºUJÅa¾ÛmÖ…×R%a£AoNÃÛ™0sÃ^Û¼0[­KݸqµÆ‡¢*ßQ!—ûZ/C[aK³ßí*Ë l‘Rê™ áùCÎI¨Ëåv^‡8l;/g®¯g’†•w3ƒ¾–ÍÁ¿A.Õµ¸ª=”5)L vŠ#™RhN&õs£aQë¼ÅiÑp]bÙ®\ë[«J·ú@Yäm>Çe…šSܪ<}ÂÂ4Ü!m]ë]¾iˆõj—¸^øpþæžÄ%qvàÖ*x˽`e±Ì´u¢mLCïƒÕ‹H›ïÛ‰že娸Å]Lô­¿#f€†/á8gŒK¦š0üùà§$f")@ÅL >Ð73—»ªÅ6A”R–¼š"œ1³:2‰]Ä2)x ‚¢WK’dð³Ã;"¬ŸŠ“ìÈÂ3v;JìH°ì*/°£Ð#;zW@E@oêû»‚Ú™_ýü®ƒŸpžL™mfŠ7G`Zlþ³ÿÛ8I@yîÌ%‰„Éqk/åZ:{yÚË×ÒÄÚUÁ;d^G^í‰É¨³Nß.Æ n˜1ÈcMñ1ûè^‚æJoÊ(ÎePÊ”ªŒ9mŽJeDøxriƒFseÁL2’J1„2AÝæ—f1üŸÕu@±™`H€ }?e¼‰Ú)€°¿xXâœâåÇë÷tƒ€p5•mó¦Õõû}xo‚èg1ÕcñcÆŠóâÓÆ×ÅTî31| ³}YVõÖ¤ÛNŸ{õ[9hóÙá@$ó‡N`üŽJ:}´{pÔékad)Di@‹È ¤P{áò4Þëhº1Ÿ(ýeRèˆb’t™•™^.õͯ{4 €( ñ@‹ÿNd‹‘ßÝp’Ìh28IfÉèf¿Á4(sW™Oƒàa"5ÏúPÁ4>ÍÆ'ÿ8ú„çO+GŽ…WÄ&‹PBFuG¸X™sŠ€cõ¾ÜèÆIhvºX›››¢—Î[Aƒs–ç¼oŒÐOJ™GhscSÂÜ\–ýVâÌ!Iè²v‚‰2Ò"–L¸«¸o{÷D,ÉB—׺#²5˜![{²$í¥¤P„ö^ŽeWÅ´C"Ûàw]åøâbí˲c‰ÇsóÄcž[†wC†¬ËÖ-»vb:ç°ÚW[×ñåtµ^®¢.ñ ö±çL@ºWþó&Ýpj!)ÞJ>iÒÍR1‘•²TÓR‡½q^z¤™ÔëXë2°#‰öxÒžÔ§J¾¿ôy>* OŸ> ‡ ²p–Êq“ïI25g¥}¬5¤ÏÅ Û/!ç<˜}8—¸*á³ñªjÝ®ö†ÕýYe ÕIªASÜ£îß‹¼YW#1àB×ß âÍ¢¸òáBe^ùXѧ ôþíŽ ½ŽÛ_1ŠßØHA6Uá“™¨ÆÒ_ÌÙK9lù€Ý»:®,IH*:¶úì5Í` t}–ºÝÕ¯NƒzÞ.ÛÓ¸ 12†ÅÆb²\$%q*¿¢cÄOûí\»µ17zÖvúÐt1HøÕþE@ŸrL±ÙPÜHÌ[}x‰ÌoËêY›Lô‹Ià!AŸ8±ü©]âŒ>;Y N»ôyÌŸfÀ?}4 ‰Lš°gzZR_. Mnã?¥CÄÏô‡bP±ÊË¥ÞÝM‰€ƒ¢âÙã“!€­$æÏ0ô´0$ŸaèsˆÉoSz7ŠÚ½ÞN;“¨TôÐÜ;ÎϾùáÇ Ž±$Iw{7§Ü¼!ÖyÝ`ÅÞB¹ÊM|ÿŽ”RÏŽoä‘ä¾f'üø v¹ýÞmÄpÀ ¶Ÿà[|¨½£Š®['ñÆø#<1üH( ÚÍ5g¯É¬–ö6Ôh¸ªµãÚûš jƒ3{ ˜r"ÔèmùhbŠö¿d9¾EÇŽÀ9#ã`–Ð7[¢FK9þèJIÂãG“7ù¡ä„A|°:C`™E‚ñ˜…ß­òÝÌ|.çV!IÍgU³(–™û´ðÖüç%ÞøBsk.k«ÝºhÆ*ÿßÿ>þ endstream endobj 2590 0 obj << /Length 3848 /Filter /FlateDecode >> stream xÚí\mܶþ~¿bá¨ðʤHêÅ@‹¸±ã&ÎKc_¾Ô6 ­–·+xwµ–´¾^Šþ÷ÎpH‰ÒÊö½$'pœÈ9œ’£á3\³ÙjÆfOOþ~vòà+ÉgY˜ÅQ<;;Ÿ ž†i’Í™†2³³åìeðì4R®º®šÓy”¤Á£S®‚å¶Ü•M[ŸÎU·eµ£wOåRß§òs½Ñy£©ÂÃ( ùéë³oNžœ¼=á ›ñYÁp2LX2+¶'/_³ÙèßÌX(²tvaZmg2Ná¹™½8ùñ„YùYÈAlF±ÀÖ1ŸÕðâˆø|JS•³‰„”<[[1ßÔ‹vÕÚ2ê©ñÏ%òÝ’ ÏyÜþ4F?'àƒ¯DêÉfóH‚HІü'ÙuïѬ2 Z#åje^6ȳ%bSîV='’Þ±ÜîëêT¨àþÑ[½³­Kœ)zž.0W Êö’HÕùhÜBo6¶» Ä`A^îôÒJv*X`»“$µÞ­€Á¤q{ƒ}µ×ÆódjËÛPÃv޶C#qfÊ ˜rÔù®¥2Ô„ôxWš({«Ø®(÷ùæ>òyðU웞³4Œ'#®4Éž?yôíwÔz0Qq&±t_±(.Ïi¤vm,s4æ_N%N¾y3Ô;³Æ„gQálmËF/aƒªTÃd(À<–µ-×:ßlÃÓ¹TiðÆÓ}[4Øœ'<”<Ú­3’Y¦ “µÎqy0\”f¦¶†5½ÑDY{ f¨¡fç§’Udz´ä¡Eè­{GŠ6Pʶћst+–ØP+ð—¶cE”Õ!ÇE µãGš(ÛUuÉ`a‡*ªÝ+&äêPÃêõ—VL&2¬Á:Ía¿7ÚÐVJ¾s³'$LEAŠ]î­—ƒíå^7T¼Xƒ`'¬©º-WkËÆ"Ь]´z s(¢4ø‡Ù°8„Æ]î¦ŒŠæ©µP—ú[ä‡eIæ¨ä:GïJ#º‘C[á X1v»@mg–âUüµYw5ÞrfbFög­·ž‹±ïŒ„1ªÍ’(cΨJ ¬Í/GupJcèwFÇM¹Ì[Ë>7s†*øOI®†TÂÑV%òjšƒ¶|sç·:jd6k¤û #)8²¥v/V#5Ïž"óÓä=6+rÒÒ âÞOB¹Ø”°ªp14 .ѝ­€:G©$È©Y?iP:ä˜ïì0ÚpÆÝØe»¦‰š¥cV ´n{7çäLOc+(M̾?š3°™6(ÙÖP°ÕùaWؤXpO·¡"ˆ[ÖTlœ9RË-…}i7#_1Å­é«F,Åo~®;”iLáÀ˜ø¿Ëqìb&à@­¿ÿ\âÊj BÂ÷‡ìÈúàËúòCû,Yä}C­”²æ’Hð42öRöMg/G {¹Z¢¬¡m5†8 B¯žW’zÃ@…¬ãÛÍ`»¡A®jŠ›ì£îè0z:SÎã,dž¸½TÆÑžæð0ˆ&áð 2f2¢Ýý²®ªÖînaŽöf@1Þ'ñ½O‡\EÎQ|QäMYË`p¦â‘ɪ7Ëâµó€↠'\9÷çShtáq“¾[Æ*#ÃNå{×f×C¾ËýbàoÀóÞT´„n¹Ú–?ë[L‰9;˜¶æ:ˆ {Å2øecè^~º§˜Z cj™%¡`Ö }@…‡ïV?œÀh‡Õׯ ¾ÏXœCÀ" {‡D³ðÅ{`ðH2í]1Œ…°ÒŒ  íëjoa'BbàAÐ2DÐöð§D|öøË†Èåv«—%4ß vI¯ÛÇ"0@`OÔÑA]8¾'W 8}Áqk°‘êµÍ=%³¢JªdU‚ç¡!ì%%E€b¦â+Ê&”•åÙ›€†$, ž›~ò->i›Dt!DârÞÉQZ=§Ê"Žœ0ó6ÈôxÒJºë½8¢G{O9ç>%@­·&;je.w­¦]ÖyÚm2XlXµ&ì2oÞo u›ªŽÜ…Yö…Û$Ì„½|ôèÜJæµ~ïÞzÄD”VÚ mg“ðÀáá/š—‹x‚Qï߬*÷ƒ¤õ–ºÁÕÐî¶x­ˆÓ0U€-*j[£ØU[8½t¹|?· "¥Â(I‡¦†©Õ&ÅÉJ²1 Õ²æÌz‡²0&m{XÝü¤Ë¹|g»ÒVŽò|¨²ÈÃvY4Bïç;en«ñäò¨ÿ¹zƒ5Ž/ E†w=d • ˆ5o-ÛíPC Îå&,ª§°i%læ AÄ>W1†ýí¸æn{ìôæ—½ŠŸdøöÊŽMØvØ YЇrH!#œÆ[J†ÒôLSèSc]oFŒ 3úæ“áãHÙµMª(™«©!ò¥Ž€/åã^Êiâë²w˜—âc~Uh«_^“Èx¨âøóMôÏ7Ñ?ßD¿áMôÏ׿g׿í>|ã_î½ýõà\¶„ŠI˜%ðQÂùLAfo²Æ²û ƒˆŽÝ ó ;:ÏÚ«eæÒ8?üÕàähG·0eÅWþ÷&ÿ5…œÛß3E"伯2 žëSŒTkº^—¤&ÿ»E·\¤Ý’åJ $ ÿÐþyƒ endstream endobj 2509 0 obj << /Type /ObjStm /N 100 /First 987 /Length 2111 /Filter /FlateDecode >> stream xÚÅZßo7~ß¿Bm4I‘ÒÁ(¶ð]; HrÀ]±Ú†³0üôÃi^®þ؆«ï^þïr…?,߬Ã÷±ºØ~ð%ÿ~1<_}XÜœ¯ú»´{÷¯ÕëwËïÖ„3¯‚-éZnð5r‰í?~vq±†´³]¦r<=Sí  ‰2:6u$ÚŽð,µ'òHÐHðHì$ßе£Z />þ²íÏÿ|wñÛbøn½y½ÚtÒ«áÃÃ÷g¹?¸Îa¾Ì-"BÜ)¥HϵFå¾g}^„áïë—ë€}ûê¾|·¾ˆ”"í»1/’BQ<É'æ)K%=&˜Â‰>Â{)jöÄ*±I;Žãã/WPbŽy>,(FÑ< g!² #eäñË#¥åØŠ—¦­g>ì–?W¨›yŠUh~_ᚢÁ:^H¸qLZŸÀk¹h¬È†¹µî½(á°Ï“ Øæ=ÀhæHŸ Õâ¾q…„šE!{üH&*—î蕎Øb1â´…Y±®™Å8¢ |Š ÊÙÛ±TbB[ávÒ¦O€=bô › 97¡ÕI9¢Ó|WAñŽ–2àˆ0Ì­~rå*ß`#¯CéÍMλ FtÃîhÀ&tBÃ){ ‹O}ò¡ýºY<ñøµ˜êøÔ9õËú©´Ã~ŠôÁý”R»'ï›&¤öÄØÑØÑÈLeΆˆ°õXL )ÇÆGJуC^d­Òòe ù2†|»ù¢#a#QçÏZ)ª_ÃøQŒŸÞc¦ÃVLóø:wü)ú1õÓDŸµ1×x;/6 L› ¦?Ýå>v+·ð44%͇FŠý~i„ Â[ÆœbmèÉIè(žËåfùf³¼|û XæƒRs´Éâî ‘ýŒ ˆj¤j|ÚÛ XEå€ç"W‹Pì·…ÈÙLwwÐtˆ£ç$M“õãmÉú“zxÑŒ|ðI¥2QKÔ›½ûQFñ³s™À˜¼Ýþþ~ØüzŽZÔ¢?|=ßùmŽä¿·¸íÎm ý‘ûV»åêüíòr ˆyÎÃ2tŽ i|ÄÁ ñ—ïÆqí°ìÓÔiS'N+Rç ¦ÛûÜŒâ·H(÷22X3¡Ý4ÿ[9Ú|ÎÒnÖ#§5}ATÖ1Ûœ­¤¸C¥‚Œ_±ñ¥w(~¼VPÍêm¯Ù}§e€ô-šïP"”T R0dÐç;wz3Qo&Ô W›ÁÉnMöÃ)ùO¶Êè€æñt|ú1—©{„§ýWEõ ?Z:âœu¢s¶O/4ê8ùÔqò©6ëe£Ÿ÷ÛŠì§™Œ4 èx‚RF‡t·cÈœ7ì]s•þ“ ÿUœxC…­ÁØåž«Mô 3FŠ ˆº/g¥ÈhnŠ_ibœÍˆgJ:Éÿ†´Ä‘ endstream endobj 2597 0 obj << /Length 2636 /Filter /FlateDecode >> stream xÚí]sÛ¸ñÝ¿‚Mû ÍD0 ™™vré9™\¿æw:Ó$ [K¢BRöù:ýïÝÅ‚Iɱe¥¶“£DrA,öØ%`×9w\çÍѫӣã×w")¡œÓ3'Nà…Ì‹¤sš:F ¤‹©.òr<A8úaÌýQºÈ–YYã‰?Š«,_RÛ›u–êçtÿNÏu\jzàLÆÇŸN::9=ú|Äax×á4œÇ7p’ÅчO®“ü'Çe2 +óÖÂñT×¹óþèç#×’î¶Y¡°(p9²àɈ© ÜeJÄÇG×w“|Ye˵N&ßù‚îV…F6/³|]ZH|n‡nDu3,ãÂ÷"§-ΛšÞ½AžkŽUÈ—Ž B…\;Ÿx7B x.½Ö{LŽ$A’ù¾oÀsxò™àeãÊ6p&=)Zé$­§t ]ÝÍ4¿¶›½¸f¼ä‘F=s~v@Б2ÇË›Fzdøí-:Á FX&<æÂpáÛ–†‹@\ÔOAhy¸+÷1•ÚÐjŽ'*b.Ç«„·BÙ66>Ñq[´¥"sÿa]Í4X{ι<' f.JÇóp4ITt 0øñë@µ±‚¶|dœqÙñ„Üg*âõ»«"[&Ù*žC€?*ò¼²DxfHûcˆè@€è~Ü ÇÆ€c1Hél~ †d› îzLA„±´½ü÷?þ~ÒsêÛ©ê±+㾨Q²>½{{º¿[ýO~üç}•æÌ dMÙUV;¤6ä#jøXÅey•é´OD2€Ár¾ëÛiD_ß—-Ã:Ë‹žê„_wWa²Cuˆ°aùÙÞè Ó…±Çcók̉ÂY£´ý=ë)Ÿ<&^¦ù"ûU¤ ³Ð“]U|h9ãÞ®Ô5û—I\fù—ÌK*˜íš÷/Š©‘&ŸìèF>2Af#B£Ë¶i;Ûï)¶.؃è꺣×c[^gV˜‹¼Àì^òh”Q¯˜úºLЧK#¿¬,€ƒN:r±Ý¥ôÑ('€Ðx[ý" «IlËmKËVªxJmmû±"—4‚‚öl™âü¦KBQÍâŠ6w cÐ~•Íçê$_h‚fËx…Yò鲬äÆö°¹cš»Ä@VDàmzWJ Æc‚Ìni}€õ4è†Þ¯IzÔ¸*òé\/JzJâ%ÝLm}&Õ•Nª½#‡qkkAroF6¢Â»±W¶NbwÊZ€SB˜²Å *a¥ ©eUäõý¶iü¹Æ[ôªÐ¬ÐãÕjnAuÕ«Q¨éjjbå—"¦kb¥T6¼ÒV,h`”%̯¤:²ze<oè‰|d=¯¨¥V:=5òŇ¥±›+zh’0l!:|Hô¶“‰ H„Ñ.‰¥=zLä2;ü"¶±±M-©.³m©}Š›¸‰Oëà‘qj™D×Þ¡}pþôlAU жJö<È4™5‰i4²BPÃ?>$ù¢­w¾.jÅÁ«Ó–äñ%ŒÇÙjEv¡DJ¶TB ;nØR:¡ ÜÑ)¹ 4÷&^`§B6e_X—v\²€5†ìšM[2ûNÇ´8.W›… ¸1 z¾^˜€…uÍfÁ+\SF pÉà…uúÕÒ:§½pòá¥V>gtØZGï¶wð¼ÍrЄ. „â†% ãXÇ´X›Ü‹Æõ¿Fá,äу^y(YÁŸé¿ú˜Ñ'•}q3è†5ÙÍÓ¼©?6 ·…Ómšˆ,«âÞŸÄ$$…¡¸é“Ø?w Áã› —˼®®Ý!2êõú´?o’Üâš¾TÝ•‹—7ä§-?^~z{H*2[;‰Îã„”o4“&E§©¶ËZ,›ìªµû×»×oÿzòâ ˆò›ÌU†Yc˜5~‹³Æ£V5÷5üaÖfaÖfaÖxÄYãq?ä|Ss† ùC"ð‡üU#ðc½¾%&›cÄžÛ5®_þï5£Û£ô›$6÷CÔ‘º}╦ ¥Ù׎wõ&ÈB/Z[pmÛÌÞäs{P}{ïn÷øzÓ£»3¹Û¸|n϶›Ý³p3m¶äÒ!xÜihöU·[òÈgR=üvKµk¢ÚÚ„¨¶÷ ªöDµµQm6 ªÍþCõÐÛ,Ÿ*Oõì¾êî®T[›+U{o¥RV:m¹ š}•êil«D÷ Txã¶JplÆ•÷îÀòËâr]eõ±ß³;lêHõãêïíšRÃaÕ=lÐ6h )û<¾‰”]î<ø ™ÆesêûÀ‰Ë¤]}¹fþºY`©ë@,užêxÖ ~(X´‘×Á‰êíqÇã¸56| qgH©7bêÿ£8ßcBÝùÿÄíü×vž`¥FÔÜ÷ð<¶P|ôçY¼c"Lç`ñL¯l> stream xÚík“Û¶ñûý v:“J3Œ'žéL\÷’8iâÆ¾63M2ŠâYìI¤BR¾^;ÓßÞ]¤HJgŸgŸm܇#¹Ä‹Åb_ê½ö¨÷õÙŸ.Î%™‘Èç¾wqé ’0ˆ¼@†DF»˜y?¾s5JËiZÕxƒpôtÌÔh¶Ìò¬ªËñDâ:+róîëu6K™û—é"«Ô<0Â9aã_/¾=;¿8ûíŒ Ôc^À¡9IxÉòìç_©7ø·%" ½k]jéI?„ëÂ{uöãµôS€lJ¸/°´Ï¼^l_îê)¶Ê(¡"04]šeùkC-t¬hî¯ð]ŠÿnðŸeÂtÌ)ôý,½Œ×‹Zw®¡îñW"ì4H½ —@2í½Èà‹rTÏíÍ<{=Ÿ¼Éªlš-²úÆ« ½É’´²åâ±ÀX Q2MÓÜܕ钕b‰]bc!”eµ)‘ÙZVe1§ [ÛT¼ØÊ4—ÅuC^a® v}OPLO §!29ð_†¾áÿøyáû]1ó%¡ @óâj–¤È/߯>%TƒÑeˆÉÓ²%·Û}ŽcuzI9Q@Ê„1);×Y=‡Î²À gá(טךæ‰aÆÍÊŠ7½Yá8`á©iEƒA°9„p>º˜g¶\šŸ R°O=8¥Æf.!‡kèJQZLì&¾ïw!B±¤%+t ºÌNJ`¥ô[æwÆ•Žlùç' ByÕzšËeœÏïᨸYc Ø’×;Ò#†+;ð&‰s ™YˆÑup³Q!ð03bg3ãJFÞðjÍì®W0³Áº7¶fµÏ„§|N@9£}÷~ó l„ÓWRSlð˜,=aL~ ˆRJƒð¤g ½øö#B Þ/é<)F‚þ4z  1|prÚ•´Å6-¶ ªlMƒ-„nª£›æxPš6åí…êž%Ÿ|ÿ.½=žH¡ÎÆË×­D¯ÿG{‹'Ï-»$‘Ð9®ù¥ì›–_ Àð«y—cÑ}äÄWàWnêR²Ó <îtù‚l°hÈ»²âyÔº¹ƒkÃʉÊàŠÓ+ù©]?ì;º>U„íÕÊâgP®‹eõ«V$’‘Pо6ùÇ‹Îíì—8Í?Ml4ByÒ3ÏøþùÅQøçþÛøúêƒ:4ð¿·v±Z¯VE Ö短ëtŠã´âÊß§ï“aß“º: ¾Œ“£*¨æ1;¼^ŒºM8Ö…¤È6û$/Ê%:–Œ‡Ÿ3͇²æF»Ëô7‰B`':å!#Ô÷ûâ#ë½óNA,Öúú¿ Ö»)Ûg`ŠÇ'AØ4üŽŸ¥•8n¸§ÇÖi):‰ Iú  ÔHçxüÑs¨Šóh€û \lñp+í·K“K„ P4Í]–[¡[,š¤*@«y±^ÌLUZ<á:H‘|½.µ`rÍÄÇZ.9²¾!{–ZD-ŠXÌ\ÆnÑ^‘‘õlÀë8åE>ùóù«ÛbF{•™ "°~3}ÏužYiÆrqFmü¶Ý©!p#ѪެµüVlÀ…^èÜò7Þ4Z¥5ò¦é닼ÉÇ`]×ó4ÙýIƒ…²jX=ŒIúHè8W}ŽëA“&A°ªÍýfD´#Û‚EZ‘ 1²?`·ßy¬y½œjŠ¥UƒRçvJAJm}†C"êd$½…ŽnæÒ¢ÿBµiÉ~‚W‚!»@“üÓÆ/A½j²A“¦dO_|a ðfé¢XÌv؈(ló@;mʃQI¸âï=å!D´#' $„ä[Y ßÍSÿn@´S'í´ú¾R½Ÿ5=èå@„¤Ã$t¾Ó>Y.õø£9C›LVûR!8í¬Ï¹3"…„‚ÖÆ—Ea—ìˆÐ‹…öŸ¦¥ÑF*è)cÄÛÀêËY¹wh5 Ž)âG¼©pËûƵ›'û8ðÿP–ņkª1Å]ˆébo¡ÈdN,E¿ß©_7z¹c…{ýš!NŸ¾¶~º£”×Y7žH5ùÒD–šÀd{ lÍ–À¸zš½íx­ÊvÅ{1/ªzÖ>ŽN3ü†VzpÊ™ýûÍò(üeV…ŸÎÖ‡Î$ BýVξÜäŸLÜ'Lµ“é3”{ˬ  ÚÎêµÚ·H-öc£®Ò›:žî›ªÜÖ´NŽví<̾w§¶ 6.ï-·õ–¼ÕÞÊ ¤íµóó¼.o V5lEâ²(ß*?h¥¸ÓzNë}ÄZïM^4¡Ù´h‹!íŒÈ㦠»_ã®=±5b¶¡?>·ê3OJº³ôZPpÂüA”»¯|·†{zþêÞ—{ÚE±þrÙ³‹WfT–Å,=T²ÂDÌ¿U²X·èKß`åâP]7ÅíwØ×Wß<½w~³]Üþæû§ÏìòÚL§µTÖ«7vNßÿôò«ç9r”eø°.Æi 7WEÎr;Ëí,·³ÜŸ§ån·a8Ëí,·³ÜÎr;Ëí,÷çb¹ýû²Üe¶Z¤†;z_¯¤L“ãmª^þ¢Áaƒ®íÌ1ºIïyt†êî†J2Â}g§œrvÊÙ©‡ažÖ6ù‰"uØ8?{ùìÞc/Áw~Óá,ÙV9Áïa_ Þ^ÃO½½†=üí5‹¬²ù†‰õ'WöjáA^㘓î¸í±ù滎üæñ2}òIŠòpC÷wÿá…éèE¶L«:^®ÆÀó_[×çÎ-¶EOŽÏ4=4$#rŸ^¿’CrÑ!9$‡ä’CrHÉ!9$‡´oÎÐæ”z©~@êQ»øŒBõãƒv™¼Ç¦çG°õ“!{dúGT…®¢]É`·*öWŸPDl~"òcYÓ‚ƒß¼Ÿx¥ŸS£ð#ZNÑÙß}N$ ƒm\â`uÂ?œÎ{êU¥; 9õêÔëiÕëÇþ!“Þ ÄövèwïL’CGùq;NóíîÃØ¸½ŸÑS„ gðœÁsϼ‡`ðîóûŸOÑàùÎà9ƒç ž3xÎàÞàÝãg3Ê'c·Û¢·˜ƒ­o*6Zþ;½¥âDúü¾wzŸäÓ§ùæwšßi~·troK'`¸ ûÎâÄ?cºù™h÷3¦NǺ6ÝϘºŸ1}?c*öùTÝi=§õ>³OÕw~‘\¦ËâM:;ÊÛh?þ,‹å©õŸ4Õ*!P'Ét´OÌ'eq²ãëô[Ôå>äÖwo¾3ÑsEêCÏ#jîúI#Ì1ºx©ÀmÆ”žØ:'WÛ‡ c)}|9–žÇúÜ#Ñ9ßï—ëEmÒ„úMœà±4ælš|6h¨=Y Ëú”-Šx6™Æ‹8Ošf€v<‘:+‹Ãy4žHÊ̹ꀿŒ;TLw\<<§™Ûc‘yHG•9= T1ÒŽofÒwã©Æ¢O/ ñ,ßm, íAÁøbU¬Öí±QöXå^A¯ðݪ(ÝÒxHÒLs¨C ëÂÍ ä›:79w…aû(8Âý`x|™¸åø2}r‡dƒ“;8aŒÛMÖ‚02žø2½LÇx(T©ÏsæA¨3ÃúÜOÕû1¦ÔÂÿf¿»’ endstream endobj 2609 0 obj << /Length 3254 /Filter /FlateDecode >> stream xÚí[ësܶÿ®¿‚u?ônêƒ|¹“LÔDq7Nc«_êx<Ò±â‘g’'EéLÿöîbÉ£m½œÑ´¶gDâµXì ¿qÜ;ó¸÷ìà¯ÇO¾UÂKXú¡w|êE¾©˜©DzÇKïõìùÜfº>ÑuÕÌ~Ïç"˜-×y™7m=_³´Í«’Úžmó¥~Lï/u¡ÓFSA0ßgbþæø‡ƒ£ãƒw¦çž é‹xäeëƒ×o¸·„ú<Îd{—¦×ÚSa ÏÂ{uðóï³.ãë‚3.#bý|îó™žK>»jÓà#à³¶¢gZô²‚eÁzÚ†Šyiû­4½lªÊö¼ÌÛ½áÚש­n4&ºÈ3íh´¦.˜QËvƒbfñœ `–3?”¸ÆPx5,g¯òå³±^¸·‚¾Ok{©×jæ"/ÏHÂß½¢—s\Æ?WøÇjí´®Öô¶mR"P4†#+Ï‘0a>_/!Íw¼Ê‘³&o·NãÒŸÕzæ¥k«Öº]KÐVRuJV“¨wíµm¨ÓÈV$®+j¤¾ikÌI‚•Ù9J£ÑKêD‹†Úž®Q,¶oZë>±Ü(êOtÇÙ±ïR×0ÓÒMU.©ß¥áÃJE–IeÛhÓ3šåf©1ˆãÝD»µKuÍ'Ä™yO鑹.[6_H?™Ï>«¨aÚÅ‚ëŠÖÍ6uEz«uÓPUV ;+Î  ÉêÞÈ”Mï´XãßU>ÿækÙ¬ªmáØµYUþÂ¥:ÛÖ´ýgBeÕ’é÷¥iÝc›¡$¬çL¨ j;éÀûRŸbKº-Zë1& —˜ÿàã ŸÀÊ(€¨ëð¸A 98` hY/ó õÙê§ÈÌÈGÀ!…—¥Þ‡èq á°M3\'-¶¦ÚMÕ’°GcŸô K°ï©¥’¯7…^wõ¶ë‰(FºP>ƒ.«:Ó{SSù Æ?ѤÈRâx “>QÛ»ìµlhú¼ÌòMZ )%1™>4¶«´5Ʊ°r˜Èh13ñ$¶Êd‘P‘mmð´‹³_xÀWùÙÊ:Õâü¢¬ NPÿ=ÊENýÀ·”¯\肆¡xøÌÕWe6wEµ ©&?)´eó”?0É“Ê)ö’ EvùöQ§ço³újcì¦"*_é¶Þê ;B2%ŽžcK—)°±¤¡ol•P,ÉP¸$;?DoføÍ^éÖZ¨ÆöýUÄóyg¾®‘a _Ál›S¡y»¡—t {ß>ã±€;t T©Ñl>;( ‡ê:Ûm¨kKz‚–žýŠž&,!ÑÒMRä¥yL±{½ <0¤)L ¼D31.i¤’Z¡Š0d wB {BÅà ¶‘ô‡>fZ¡­î2o\œæÂı¼H-aW\6w”÷B@Ð_ƳïzüšÞ˜V2ƒJ•ð°&’(<¤é´€µ¨3‡PÆzÁ:"SP7£‹K³”^ØžØÒåEÞàZÿâp‘A)ðçÝOX‹ ‘ÏcÄ=‘¨‡‰Æ•é¹ ™€˜íÜp¹suKù´ æïÂö.ڙݧ5×Ýy0|ÞfçCW€v,T¾ƒ[VfÄ]a­—ªi׆—Ýí0™AªÝ~`c¦øÓ=ùi‡b•xã§Å²SM$='»0f¡žU¨X¡ü¼wôMP ŠS·Q1[{’DIÜïMu%cB ”UÚ ÏÒïUH/땈[ ü3ûJÂAa¸£(Ûm7cW•É®P¸ »¾#ÇwÓePЛ»þöÁÍʲÿùõz?{`°Èç(n¹¶5¿ãðÒ”¡ê>î/ã%#ÁÎVݘÜöãäWƒ y š¦BÙjÿ¦ï ’v]¸#<_±„ÛK?‡§öòMc¯Ó_óõÖ¡æ¼÷ÅÍ‚ú"?5ؼÍ×vÈ*µ8 ‰.†ô)š Â|IÛô„n9M|áê’'ü ¢§²%»Wí+@wü÷GÙ2™@¡ ž Uþ íªgu…mu5|GŽï¦û½PöC]ßCEÙ2 lÅÇ([ù½i @Òé˧ãeËäA lt¯~Êöa}2Ž?£l@Ùæ¬4ÝÃ/QÄâ݇w¼UA½sc‚ÙõÙlë3 ؼ™÷ðñ“ñ5ž’Ô0ãyÞ'º…’K„zÐȳgKyî’ŒÛãΡ…Æ;Üé'1‘ÚãO.%5Þp/+#Ð)téïÛãõ“;J´4,5æ!iÁ¦LBR% ñÅ|ìÀÀŽëw~:ý9{|‡\;îl€®H$}À¹¶cÝX¶ùŽP[Ö†_Uì:Ì©¿yÙ˜ã~º•„ãëø†¼ùVB÷Éð^2 ƒ¡Ù«L÷‹¼£[¯´ì§ˆKò²¾djT0NÊbMGõ€&•GÑ[¥¨Èw$¸¥Ÿ.ŠÅËÇíE Àl`}9*«1FÅeì@*–ìŠë1KP¨"ÙÑZ>)"Ý™Ý$ _f~bãPV•-@šfqQ.u½Øàï.jýô?_ÚŸ¸Ýf~«J žÙî…ÝñÝßÝŽg†ážòþñOñ÷ à…¯5ýD;vg­në|35ËÑn@©/‡€j¢FT÷:}ŒjÞÚ;&gi^"ŸKoD2œG†áÑ&ùãÉ?ª‚l×DÚQ0ø±ÝÁП&¾‚ãv1ÿL·fw*n‚lN?Dv!Í×ÇÑý“׌±Iù¿Ø®O:;8Ýá›§ô*§Æ<×W¶ù¢¬è%y<ïݳZd S¼f±À« ºbr3*Â'© ·}Øê#7˜}Å n·®P¹¼#à¨ã¼Üj»¹ º¸ƒ³_[wÄD[šùIÃØØçþµcæ‡×þÁÜäoü”Ï„°—EÎB™˜}½J7s¼hÐ-ù(žAxž/B•Øßý]àß´ÌÌç{hnñHµÉ³an,ÿ1ß×# endstream endobj 2615 0 obj << /Length 3231 /Filter /FlateDecode >> stream xÚíkoÜÆñ»~ È Ð­¹Üå+@Ѝñ£Žã¦±¨m¹Ò±â‘g’gUùÐßÞ™Y¾î,ËFôC¿ÜÎξffç¹<ß»ö|ïÙÉŸ/N=ÕÒKE‘wqå)™ˆ$N½X'B§Ê»(¼7«§A¸2í¥i›îtÄÉêüT†«b[Öe×·§ëp•õeSÓØ³}Y˜3‚_™Êd¡ŽA ä黋Ož\œ|8‘@ƒïI/à8-b?öòíÉ›w¾WþGÏ*M¼[;këé(¶ò^Ÿürâ3ýþ”•x±Hc_"Z¥"J#}1ññÖý¼©û²Þ›h ýÕUÛl ÚµÙüX6ûŽ1Ùµe–ÕñB¡N½eÛ^{Ÿzõ yvG‰ˆ¤òÂ0~"×Þæ¦x Ú§i‹n¾õ "V" C‹® Š@J”Ž#BiLÊ˧á/4¬õ'¢>-䯷'æ¿Û¹WÞ/; QîØ<$Hº¿é‹/10Zh`#°|„<2ðáÄÇ0úŽ‹‡òð5 ãÔÍñ¼ŽRáKhQot¨‘q«ù`£ƒ5E)H\El¼æî[°PTíº! =£¶0Zç—ùºÛdVÃᘵ” éÖ¾B¼s©düMVìo¾¿®š®kª¬*3ÚðßïþHŒƒs x½p°æ?ÿõ‰xùüB»äá¸öÑÓ8œHIªô6´}C3frõVnü¦ÏŠbNÓ';Âäáᮢø¾Ó× ­&‰ç÷q¾ï7üWî¶¾¦³ŽÚ][Öy¹Ëªû¥}[öž±${Ê8¦Oê¾½£WMûµÇj¨X M·w; Øïïv†y3]Fë¼ïÖ›mFzºž¹b² °#Àj= RO‹4‹²÷?çâŒÄö=̒¤»?Ì=·‹ ŠDœ¸iÄä…a5é›C!ÿýÕÓç?=ùö²^C¤Ò@Äï.q$ÿ-‰Gÿ—øg%>w®îºMg´TpÿSÆñÅ÷b3¹‰'t·E>gr?×9ˆOÅj•U;¸¬À_ñMu„Üd§Ê_}ënÚØšG£ Š½½j$¡oÒÝ1á5á÷V=šË1s&™zÒ%™¸"ðƒÑ¨u£s„µô5t:ë›¶#ü~6k¦L¾G™óàüb¬!†Áêó­ËAí`U³ïAym£!eŒ8S6ŒY)`¥‹ìÑEý',ÆÚ@”Vàjb º¤êXû¶ÛƒÎF9Æã!/SvImC15rQ·à¸$SèÎ3Â$â¸!?ùY-ð4w£¸c=éºêÈŸy è.\uDé÷i°‘BÒÛšƒbœ“tdÒl9ïË­«ãlœu¡l\B…á¬isV9ß]ŒÏ:mQœtã¡,ïó6¦ÚÁ%ÞÌöc‚rTqðEè 2pAÀY±‚xñ§¶@ Hð¿ê<ø ïÍ:ôÙ`Šþý8‰ËáSÜˬëO]=—ð>¼À»‡dð|y”æjíÚ*Æ}Ë—]4†¨êBªðß¹¥L…ކ:öÅ£—ß¿zrþÓË#i‡Ž…÷0¨ÿ\ia뻉nßà\r÷‰EÛ¬wÊ„¯}Ö ëÅI/ì¢ák( ¹¬}N$m)Á²qÍë)ëˆðëÌ¢à_Pâ²Á†Bº˜šð¬¡nBÖm¨K ìÔ–sÉ7@Ž*:¾¸£W¹¡• °?Á»§ŸË9G÷´™|Ïbì™î’E…”ô Ûç`©•Ys5ŠÃYà¡iH┟N4èØ#¢›5‹ÔöjghY…\K×åø —À42|Æ6¼t¡0JÎÔÌÞL/ë#”CvûÊeŒß1'/y>IZ("ã‘. ç8Ç4¢ ²Q^oÆø¢ì» D—ªÂW—µ b[¦[ækÒ^€èpñ€Øƒ EjèÞ¬£ä§R(é$ F1™¦‹b¡:^8reµLÏÞdÔª*éÌ1HT¤0ëž3ƒ¹1¨‰%Ѷ¤õ•U‘këº0“liÆÂPO‰w“êÒ=ðí6CÁ)GÛ;5÷'cøxqt=„^;Á–YöÚÂÕyG8—éžÑ-îwnY1V†3„âNVŸÖÉñíÓÊ3 S¢I†Bÿ!ìô^éô¡’ÉÝ×÷D\…B ôA÷t¼L!8,sà^»¥™9!ߦÄc= \(»Ïí{EJtÈdµkº®¼´ZXË!`'Òs#ô†’€àò½¥¹õŽ`hL&ͤ3%ÇÊõŠÑ6‘$c V¿v|k_ÿÔ­d ‚pø:sS\†ï÷PãÞ÷Hjüþ ¾tG^˜5|'ÊŠâýö†LÐJáH@W"RñÐ<‰1àƒ?»!¤N2œfXQQ²ØêÇD$ÉâÁ‰Š÷ö{ß{údg_APc½Å‚ýdü°ÝÂaö½_'Vu ÅR{K™–@®%°ˆ\&ŒX­†–?pZ°v@Ž5 ²F.R'Ò±{Y §«Μ…°³ñ,JV˜Çy ã²dz½çZcH¶¡dáýL7䨣GæY—ß»<|Øt¤:3‰-žùãp5Ï—ÿ* 5„ªÿ©ìðÏp°…„”Á$7‡"r¡Wæ9n‰gL±!sAéP • ½2Œ—þ6å endstream endobj 2619 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚ=OÃ0†wÿŠm‰ŸãÏT*­êÆ,5IIü}ܺXî[wïsÞ@ÀŠÜ6äúA!xî4м‚•`•ãÊ×ÐØÐG&5Ó.NãÌ*i½a¨ièÓæeb•¦í’Æ¡ôVŸ)Ä«?Ç}lçXäRrdÛfMîòA0Ÿ€åœâVXèz²Ù ¹¾Ákïàû4Õƒ2.û=¼'"ÎÒ/þ×.­¸4ÿ^õ'½Ê:QxÔŽU5Jƒôî½=0MvüFa’5g•Qþü‘¯£m‡.†Ò^ :R7Ÿ°/z3þ.W1 endstream endobj 2630 0 obj << /Length 842 /Filter /FlateDecode >> stream xÚÍVÛn7}×Wè ÆÒ¼ïnPZ9µS8‰µŽ8A°·XDV»ê^¬æï;©Ø’“ nõЗ%5Ï™3C‘¢DÑ‹ õã_#E EEŒ%4*–“ë•`?C”$‰Fë×IÃX£ùäÍäy:9>‘ %$Ñ\£ô’ #1eH'œ0ªPZ¢kü[*üÇôu:»>¤g›-L!5·{B%ˆ€ÃC.H˜ۓ!Wøjv¦ð»“¾¯.7&³t¶V‰„|,ì{$O•ÒLé¼ "Ч§¯.ç€%ŠñŸ§ç/Añ|ƒa›?JP§„k_¡ê`áñâÅ…pÚSB-H¤=S. ÛøøÈס¢_-Ì(\­²UÕÙœ÷ߌ{|"â{’1N¤ý˜$Š;LŒìqäÌ*Ebc‡dßx‡d1 «þÉñqŠ8ÅU—W]Û“¶³BÞ¸•¾ý4¬Ð9ë*gY‡¿'‹aYÿÇÄ<(µ-Ydù×üóÃä?µ3£¸íLV*ý>ü‰ <Ö¶oMkûƒâ S&ëJã~>uû!×®TëõÚr ‘lðaP~(€ð¯ÿeÏüP@–|UPPÁ®óºêmk>˜ææÑFkóÙ¦è3bêÚ4­éIUŽn­4ýªÎle|q†Ótî&WV;Ó”m Þ×½¼§îQ¨û”¿K>!‹H"„OúA¹ùºë®’Æ<¯ÜìK)LšjØ–_ùbë“,wÆùåùUSœeåÒ[l*ÞRÙ™ÂÓßmô·Ú-®xôý»eŸ¦8$Ͳ-l;eE]‘¢õX‹Ò3–p%B¸·)¦ÌÙb¦A*ùvsZ9³w}+ËóïŸç%Îki ¨'¸î¨Uƒ9ö>ó]e+n¯±w+·6\ö¦m¼Ïà÷d]aKwaœ‹[Ìs©ÓÑ{ªèí³¡r.PðØØ¿u$/öËì¹-ðétwy› ߨêÙÈÇ›žÔÙØ8t«¬¼«ß1›Á7íQߎ]á™Õ&_eKG}Q™e™ÕÞ ÂùbЊÇßwÿ=¤à/MGûÏ!‘Ä?ùŠSð1‡Wal{—©dçl8ó,£_ñ endstream endobj 2642 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚP»NÄ0ìý[Ú1¶³¶ãœtT€Esº"y@’¿ßHWí{vf¼ƒ€ ¹öäò%8îŒ2àßÀ*°Xqt%øvôž)MÃøÆab…²½bRÓ¦‹}œæ‘šÖsú<Ûb.rþÚPO!’+Å%Ûû-¹õä›Èô^€Ìï[aáµ#»½€&õ· xé*øY·:@S¥ØÂy âHýÿ`iäÊœ õ¯zL<¥Ê⥠e(Qs'–õ}óQ1Mg¶8“õ)ä¬0èè3ÃäȇÃÑ®6öŸL :­âO¬“ ¿2*XØ endstream endobj 2655 0 obj << /Length 310 /Filter /FlateDecode >> stream xÚ½”?OÃ0ÅwŠƒDßùîl¯@Sщ’¡RÔ‰ :ÀÂ×Çiªþ ª„a‰#û½w¿ó)qð æÆ Ö›ÆT5# [ÏJм'µ(T’ ÍÚâþán¶ºZ7‹ƒ±ª}:u•L¼³•ÉY¡÷-;OUk„d“’vJeö…´WÔ·0 HòÚ$r<+…¤ ß'ùÓ$FÙçÀúºç³ä"d„ÀùÉQá#Û\Î ´%‰+H}Á–û¸B¤©¸8üœK\,¢“Ý—žqòñ¯‚Òø G7ÕM¡ŽçRå4—àx° Ó}ŠÁz÷? òÒ:kÌ»Áüê![ÒÏ[Ó®lòö¢+"|îD[àÜ ƒ7x2‡?ñ‘]È[ ˜,"õ žÏ.×ü’†81 endstream endobj 2675 0 obj << /Length1 1396 /Length2 5927 /Length3 0 /Length 6885 /Filter /FlateDecode >> stream xÚTT”k·¦;UâH×ÐÝÝ ’20ŒÀ 14Ò‚ˆ4Ò’¢ÒHJ‡¤t‡ƒ Ü1þÿÜó߻ֽkÖúæÛ{?{¿{¿ûy>V&}#^0Ü¢ ‡!xø€’% (Ä °²C.?nVSˆ‡'“üo%ò)ƒ(œÐôrD%Ä$@€ (ñ/ ÜC  ò†‚:|M8 âIÀªwóó€::!PÇüëÀaÏ ãù•Pp…x@íA0€áqEhrÁí¡„ß?JpH;!n’üü>>>| WO>¸‡£,'ÀŠpB—û“ý³ö+dowuÁü 0G€ÔÐSÕæCø"x ø'äâ G僼AP ð«s@UÁB øgJ f8À=~®YXÀÊ‚û8ÁáÎ.ÄÏ0Á?ް÷òð@õð‹¨óÿeÿÒ9â ±'˜›†ÛK…?ª ‹¬Q õáÝ‘Æ>ÊB>ä)²ÁCô¨Œ?\M5Ê}>¯õJu®[@ÕæÑ{]Ewä‹¥™¯ëõŒ ~Â缌ªÛŽŒvÉÓ·çè“itÌÓ¤ÍhùfŠ ’¥=húôqdðåÀŽ=F¬¤ìu]³i>l÷ÊTÅ4#Þê¾ûPSö\›’NÂtÿ‹!¢Å®ßxCä5{Þפ°µx«˜LÝlf-éw—©>Õd+}ý äÝôqO4½C7ŽïG"ÈU¤úé”…q«M H®óJ½÷²ïةݕß÷T,sf ëtOÖO÷¬™¸Ü»_4Qwãík«¥>ÎÎOH•N©ùšb5][ºç+0ò^6„Å46~%,E¾©ƒñØÀ°ãóxü†ðÑEǤWþyÅÌé¡ä+ÓÅÉ%œ˜ððĦP=µ×Aò$ÜgõeBEÕ…gÉc3Ý#±c'¢ û;[¯ñ<æ+&×\ŽÍdÖÌõȤ ƒØÎïì&Ø –>-îE~Š­èêz£îAËùqEìê*pÜÍÊLJ)Poå5Ðÿ+`Á§Î·qÚð)G˜Ùq‘œàBÍZ\t4´JWè„,Öõl vœxS ×\á•„†Õ!fpFêdê‡Ø˜,ç#-¯ð OøØ+ºj ûÔY=â]÷þÂ-üÖâ] ÒøaSÁè$䋉Ѳ\ËOCÒúèíøûõÌÒ¡¸SK‚u—z/ò@5-­¼’Ô)Îy[T—X–ld‡#îlÀ=ùæßTFjÔ0NûÔâô¦ORÞ ÖÉ E¬¹ŒÈ„[P©>£ÞÍ}’;šPŸýx@†-t„E€ýRÖ»ãV5Á&°£o`t+‚戸д)4ù®+Ùõ*푬’—H;l9úð°,iøÜx„€ö­bNbü©$ å'•šÑ™êþú¤Imak'ãs©s¼%R‡gîkH?êÊ«bYqâ"ò—=ñ–œÍo)k´™\pjæ¿å,Ó*šü¯‰Ðžœžûd#Õß~%䇥°MJ¢iªæÍŽ“S=|gDeècÖfFäÀ²ãQ> Î„1Á¾ÁO‹ñ s·W0xâ÷ö¶OÜ+žvÛ­hès“Êõ—ík|»%;•gTȵQÓ8j½Ñ·‚´”Ñ”R„«²~»áÓ¤±ßñ7+¾!ãüÁŠï‡cs1…0'”'1•ó''VMîi뼫¬ì W©Ò/bh×>¡äPq¼¶MèK½G0²·6WöP»¦ÖVßÂÆ´á¡Ó•"Æð „/¡×Ý¥«íZ,ÂÂ}b>Á™#ëãR~å¹ÿ-¼¸ñSó2§câ“7øãزÈvÂa®g±šíLî§ë·ä…úÕ!ù¶o.¶vÒl‰”4Яˆ¿ÌwmQƒD^1bñðž4-uKµþ ½_œ¬4ßÓõ½ó°pÖËÌÚO3ݱ„ÕÔr‰)½¿–5—ÒØÚa DÀYJ¶vS6¢‰òEPÕ÷It‡ÚïÂ?Bs˜ïE–‰UÏbÚP8ì£uàή6˜y¦¿x¢—:¼o𢻤a·ˆvÖdÙ˪d!s¼[rÒå‚ÁóRÚ»à5§®£_¨¢Qqúl6š{&–ä>ÕAÕ3½ÊoÓ|¶y)¬«ƒrl±!lÏVU¦>Ùx«·aŠéÙY˜;/QÔ Ê˜%²Îž¹ñè’÷¬<÷ñ;,¿ {È“ë4•ÏrþŠ¥ßì@ y~³Yï}r=¾Һè9ýÆ£3¬­|æ–÷æäÒ6å-Mxàk-u -Å®ÜÂ.1Ö„Q7 çhOZKãßu©‹¥Ùú‹·âœô5esBF1ÊÅ"ø³ »½ ÛkQ6-TÏ»ÃúzWúDiñ8ä…5ÈL2؉õ¤¦Qð®¦,&ù°1–j‘©xæhgk@fÖ/pÍ‚óà&ˆ=rRÁ®dpåB¥ùµXw¾à F¹É“³ ],NîÝó)¶gw3£Ø‘èv¶ÆtØ Ë߆<IJ­o«¯˜v[dê´cá{o\ÑF¤žÃ1…¦4z6<†ÏÃÃÝ´m|bÿ¶T|{.©÷PÎ]< Ð&,Ó»ÕúÐE¥ß n+ãÿ9{‡¿œf¯mŸxØ!‹j2ÒÀz€KnyÔ¨.'7Oq·7¥á,é°ÌnF4DÐÁ=4²ÔÈr(ûð%ÂKšÕƒôÄÝ üT†“7Õ;Úb@ò×—3–YZúøo†¼‰Þqº)vÊ/Ú);º EÃ7¯Ibzú“ –¿¦Èu\©¹õî.jEJˆbhìv 0yê¥LÞx-Äpæ8=®ö}/Ö™*Q†´Nà´­õÉÒrNì)Ó0î…nš2wO©­Vš·Ü6³ Sh¸.\ù<¢´TI(>w¢­ûÐè<}ƒRFóÎ,¥â­6«¥ŽŽéËwþ†ê­Ë6^ñ;¶ÃCØï $ó·I¦ó z,˜”- ;/3ëMç4OÄD{'j@²ß†3J"n=è 샮Üdï=þ ±o |¡¸í«ªâOç¥-ïEW2ìLäVC)Õ±’¬ýŵbØ‘óÜk¶lÐ ú'˜b°„ð–ÿB/ykÊk- 1&iÛQžd#ó¸é,˜Ê×ÒúÜ“Z&uXj©úyúgŒFs—;Çö¯ßMT<û’bÒÛ^vkNÎóôßùÉ®ª´Ü>÷¤ÊÝ”¿æyÓ N‰?l²Óžep°ä3V k¸‚¤{¦ÁAFJŸu0MñXR£nË2ìiƒ}žrÛåEGø“n´”­º˜E$9Æ¥EH•a{d´ÀÞw½fµðÀ–$a“As³Ó•—gv¢*Ÿßô˜jÇ‘ÁØ7­HeËh64×ëзº¯ÂÀ7Fg ¥#IaÚçê…Lð~Oõw¹4N?ÆØ@ pUà‚ª¯? ‹vÜv9‡?\f Süû”`y4,Q„µÙz" \¹¯MÄèf¼é¶êhÝ~mZC,(7HÏ®| úN¹ ÊŠR(ü«ÖT«• ?C/£-¾b]Ì¡ÔþŒCÃØT“.² ¢ÜsV¹¼2óàs¤ÝõåMüÔeWݳxSÕ¤)^ä¡moš… 3CUŸ»®ð®{ßâËÉû”,IÜj­=tÑ®gtP‹Ë~ÿH-u©úB›cã79¬/gó›'L;õÀsol(»ˆÐïB>2`†xI|ˆŒŠž:#L3úÄ0²úNôYó¯œiçueEýy϶f[ä}ˆ›Ó1wXë­Ð÷9<Ç49ñX®üŨ³ƒZ«†pü4ÒØ9¶sÊéתsŽÝZ>¿Ç˜ô‹Ç¿âǦH±ÊÚ ~™Þ–•t¯f¡ºÜŽO—ä}ŸÓ,vDå2Çlqgã!ÿÖ«sþ«ä3(Ró™ëqÇ”‡C·è:^’,wKCpf 6—û¨•Früýü_ZW1÷fÖf&g¸(H§og²¹åþîÍxÍí§Uªp÷ÖþšÊÈ;À¶/ ¦L_.¸âÌ‘7eŒ±h–sRy£ 2C#ÜŽøX¶ç‚ìtîfíÇ–ˆ¼)»k'.Ð#ñFoãeߦpÉ‚¾ìQ&Ei`u¦Xfiñêä!ÊÍ$}è…óúM¶/žÚÑž¿V£~Ì{v8ëÄ_“Ô~ÏPf±¥œZ꩸(tzøU^lÚ¶éîG<_×dflÚPC6ãì…\c5ÖÆÍqPÃv5¾ÐkFÒÑ>M ­Â³Û®Ho¦Š‚Å“‘F“ú}A¶•ZæLØî³$C…c» ͱåé6µÙJ/vŒ)°Sü"åH/ ¾Þ»‹ÿ­¤¯3\hý\ãíÔ|‰‚ÏìîôÀÁ¡‡ïÉtªE‰:ÝïFB,Ù.'4f£ë¹–Ì LI§R5©T ø¡~Îas¢’±wKŠùV·RÚ©÷äÅEM„'¯†:?Ö#“a÷Ìc¾âh'ðÜì>sI< Þ‹ªÛc™pøl—B$²ñ‡´å²E¿oѪ$ðÓ ûJòÎhKOõ§ŸJ”âkppn>LÓI¦^}dëîת»-*yÇ[±zg€w>þ¤XUÅÿøI%‘|¢¹Lñ@—ðÁÎ!ûœ`KñÂXú4…)î"@<“¤)”©\Û°]¤rrM¶1_.MÅ¡„lÀã]ÑWw1«LtìG¼gÑ~ÌÎæ…(ì]|WðÓ-°ÚÊl×çPÕá™´4 ÓÒ<Š;nÙêÝ_ªÜ~•\äŸvîTŽoó0ŸüÑKÄfˆŽ@TïèlˆU(˼lÇÒ+ ’ÃS"å|CüC~¹'/`üîD„ûÖûè<ŽÇ*O3iÂlm “²[Ɇ,ËQ÷±uçç°Ïü¨¯ {õ2 ´´.rJ_xK3ô¹©Ö³Ýä·–¶žÞ½s‘@ÉZšxŸ!ìþù“|lSäzén®ÈI„‘4È;æÒìÁO Ÿ×sÎÜ¡5‡'וî…56 QýÖ¿4íðzvÝjÝäxÜÞ“¯½ã¯)M½«;2ì\/ïŠéOb#Ó"M˯ªÍ²®# ¸5‰“2¯“ÓØSóXZN\г¤b‘kz×!ÍNÌ.¦7:alÎËˬZŒ~[,]ƒA³Ã8»cÇ|ù_òÌ´Å>O?VžB±Æ‰é6wµTå&»g`Ø&‘Ì(åžâ5Å€‘Íû/½TIù BÜ7ß47  ötiûÆÓla%ég…©‘þfg9†ëñ…›Ák†âSoôË;c»ªvd·åØeHË©¸¬g´»–dž¬rð\‡6ççïù)¤D¥H¬PÖ,î…«¶¢÷Zˆ¨M;Ö„=´Æêœ ép©ÿdõ‘ 2°âã‘G@Q7³0¡Q¤Ç¦ì5aÛ³"[·ˆ˜¡<¹Ê®Cÿózãuª•tpÚqñÌWZÎÐ^°h·‘ÁWë¸îÅëB«ÓçSkK䱯JÑð`>—<‡4tÞ§bpcüÐôÄÖ‰¸´|†áùÇܼBqf¯· ƒiç5¤ D¦Ÿ"*DHç©bªgC#«¥[Â"/ÞÞÓÂXj~J (©Çá'RTÞ}«Ÿ*”Œ£GáWÙµ¤B3Õ|ÊKuÒ]êL¬ã„^åÇ3°†–sjäTOûhJ Þ.u›i~¤*{¶•HÖôŒfÉõŽ$ún:^~HDTy"Ó§E/š)Šmö$\ómëX<åä¶$þJT<Žì.XF K7Z­½ o ^ü^VÒ³‹e_fè^¢4FçÛG ùý0¼ýþ‹E¬}2ì‚— ˆÉ¨Ù¯Ûçy1vüDˆ©ùú——nx•#ˆ‘ŘOŽhª\Çí»IOØN²Šõy×¶ã) ŠŽ\¢².†;0ªiøco.Ü´‹l‰…é×­Åû᥶Ôm[ì“>12á'f¸Z÷;dÔŸô-Ç.ÜÝ{9›©r”Ö‚õˆ˜¢µsÛTŽrªVÿ äöÐ=> KûºôÃ|åaØßI²3Íýâg=‰Ï›ww ÂX‹í>‹*^ãÜ6P^9_nÌŒ ¤öê_ÏŒ!üú(alÑÞAnÀqˆyñ&ŒÄï–MëZóS0ôo}’†ûV–a ‡dP¾SR,Æ ÄÝR¤­.­1k<+CgbÕU®µHÀ ÉtPôn‰` yÜÚåÿ¦äàŽ¯†ýÚŠÍÓL+2‹äKfqâj ¥`{‰"xQÓ[x¬|ñ±‹ºž§¥ß§=ÝÙ‚1—€=¢@™þ¾ä¢†Hôœ¹µñÏ4‰ÓÖ$…ê!ArÞäÆÃûжñêÍŸÒIš™š*‡ÝùÞ·8ßå‹ 4qØÛB£Éßë& T-ÓØ‡ÍÜÆPÓHDnZ•ö92“|Ö(˜¯õ¡¯á1Üè4P•D±)‡G:f¼AB БBNÜ=’ŒóÙ ph}y•­iŽõLE¾•]ºbWlr÷ÿ Ú­gÞ endstream endobj 2677 0 obj << /Length1 1376 /Length2 5980 /Length3 0 /Length 6926 /Filter /FlateDecode >> stream xÚvTTïö6Hw£”$†¡C”ÉAºf€!fˆ¡»”’””¤Eº%DBZAJ:T@i”ÿ÷Þÿï~ßZß·f­3çÝûÙûÝûÝÏsÎáæÐ ÈÃÑÖ4 # †HŠšPc1C ¤ÜÜúHŒ⯙”ÛáæŽD£¤ÿ@Ñ Ã`mJ0 §‰FêN€ $.-$! ˆԿ€h7i@ 扄š`@B¸“r+¢]|Üvöì6ÿºxmø!)) Ðïp@Þᆴ¡MÆáŒÝÑæ@Ñ6HÆç)xeì1iAA///0ÌÙŒv³»Ë¼{@áŽpóDÀ_ Z0gÄŸÎÀ¤Ü€¾=ÒýжÅxÁÜÖà„´A Ü±(8 Àn@ÕîÚ.Ôðý?ð÷l!°Ð¿Óýþ•‰ú ³±A;»ÀP>H”`‹tBÚ*÷Áo €¡à¿€0'w46æ C:Á¬±€ß•Ãy]†mðo{î6nHŒ;Øéô«EÁ_i°§¬Œ‚+¢(Œ;é¯ú”nì±ûþ™¬# í…òû»°E¢à¶¿š€{¸>@!]=jJ!Xélv ‘®ÂÛÆ^ðWz}Äo§Ð/3¶ƒ?´ `‹m€´E`ÿHýÜažãæðûߎ®H…„8ÒX#ì(ÒÿdÇš¶ÖØá»!½S–{Bä×ïßwæXzÁÑ('ŸÿÀÏWPÞÈHCzëOÇÿö)( ½?a!@@JT•$¤„€€fÑ!ÿVùO¨Ê Hý){Jÿ*Øóïüyÿjƒøg.-4–´€÷?7ƒˆAl°¡ÿo¦ÿù¿üW–ÿÇÿ» '§ßnÞßþÿà sF:ùü`9ëÁò_Uê¿¡†ˆ?šÕDÀ‘ÎÿíUÃÀ°:GÙa¹, $ †ˆþ±#ÝUÞ¸ccÿ‡1ì~)Í ‰Bè Ý‘¿-Ø(ä¿|XyÙ8bîXZþv!°êùç¾Ê(4ü—Ì„ÅĘ›̇‚e“°˜à'„Õ#áý›È€ …Æ`Cl€-Úô×XEDAlÚëϰ°>Òä·ñpsÃÊì7 °›ÿký[Ó„7†ôÃ4Úæv¸C]xëI<‹—ÀÚ0áâr{T‚qo¤†g&ÏÏþ>Q¦ê¸«‚¼òÚÛ4÷¥ǦýYø¿œŒx›ue…,¤ÞËÅà(÷®(ì <{sú­ËqŽf¶•H‹Z¡ùš¨ËFeeŠoz3Ùpú"B¢[d£jýùv÷ ©À(:¢æHeÁ<–Ïiß¹cÌÁµŒ46£Ž£u3M÷ÐW{0úãJ 2îX¡5–éÔgÅ4.cp~~ «¯7Mä _£§Z¼ò!½¯:GÎÛ¤~&†Ä,õw±#ÅÒ”„L…Îyð¬$Î'òûZûE<êí´CÈ´‡^y¼d& Õ+ûSÆÁˆî‚Ö„ ù©:yÂxqÏc$,IZ¿'¸*Pï‰p3‰+æ5º|¨Å…´.ÂäË qú«©”…ËŒO’ó+©¿Æ‚Ë}ó3„jì#®Ik$Py*r(æÚ><Üýp³­Ïê 8ýÛártÕë%ï¯46RÜiÎóç$AåKM±ëׯ¢½R>ð\æ²cÕîSëÍ‘°pLŒht ÒÉ죿é¬Lî6̵ÂÑ|ª¡ÜÇ’Â{=VÓoù)î«lê…è }â`!®³÷¨Í“‹©æ™úÓ¡ïpuÊÀ×çÍù½ ùWgä*Cz]ÀVÚŸ*Éí³wLÏØz·ß# ¦eÍq¡÷¶És×NHà±Ø<üñêÛíé÷zjäëÒ)ƒÛ¦×MÅu&i6»$ºî+Kú·§f@gLªuëÌù-æ©Õ kSwg+ô¸ï¸¬<¥m‘¸K2GiCHUõorô8ÿ{ʽ^®KG{<âH“kÉÍ,qJ,Ä_;µ¨eØÏ_!˜4Y|Á¸»çõ º½”¼Ê"¾R‡ÒÓ‘{Ënü$áo'Ïâ&ÄØ˜utÏødÌÊÏ&¨n|‘™¬«Õ‹Ñɱu»ý`ÎPW/nôy X‚-Ï_bâñ—½oÜAPFû#pÏÙ« 4‰è>-$=7lˆ«”H£©–çL÷§*Ï—ö:.Ñy:ÝÀ#ýW³Ýù½•zY³ÞÜã™-ºy.ÑÞÿÒ<³˜âièç}þNšQB¶G*ô?eÒ¤½)Mˆ<ÇП›"Ÿß€÷Ü´…¿½þˆ`3PìyH×Ä@TÑ“~ºùM?ÿ³Kf"ÙŠQèUÿúRÔÙ‘2‚ð^`»õéh0»G8DÄ7Ѹ\;k9;];s%…•ÇÀU ¬ò|TU¾Ÿ¯"Àÿ ¼1öcQ8²™ªzsØàŽ•¿¤r·ÙSʱ~k¨mžüX”Nöe;뀤f±c¥•M‘P.ˆ«£ÜÐ6䉿]i3ý¾¯û·Ôê¶f*‹y2?­½½‚7?-ü 1(ëÜc¯"âxÝ{ºVð>tØÝHþ*‹æØ`³‘òk/Z)4« t¦i²£jõJ~ŒJff³ïˆìñÛ¦>*'ù6Ú¦>CI•@ªo? UâWÒó,â+ßï¡ ðÓ4§¬|¥|‘¾$´ó­e‘—\0="íßpŒ§']uÝ#—Ë+~­Ñj‘} ÷;«a»Lñ¨Ôc}0úæªRÆÓû<±âÍÉÞJþo{¹ƒª}E@'¶Ä$ ÓÛ™ÙÈqǺÅéï“Ó©‡¬ïŽü^JïCj`€=ß¾búJ•ïôž|ÉaìÁã}†þÇIU·ÛoèêÉ¡”³G¬_ ²ô÷ˆéÝ#ÑÌCp\FŸÓ*Ù®QâñûÝžC³2Õú_jMø]n¼”´f&òÆ÷È1zæF}Ø Îf0Q<€»´×RãìŽ?*VMr¯ªŸ¨ØÕ _XÂÚn·ŽµXT®%±ì­E°­š?&CnԚܫV ½Ý¯®Jåà,Ñk‘z;Ž\+3£Ò&qü䄹cGË©µc”S]í3o»ï|ÅG×&‰êé*ûøvØ¡µÉ¢òƒ¦-! ¦(«8zDØú.R/Po”†É%KæÁ‹Ås½Tí¬>?Ãý fÞ±’nœ¹VŒÚF^È…[’ѯ¥ GÙÏÇÊYI‘߯Ò'QQ­p¸–ô2Â<ç ÕåAÜ˦ÑOEl|œsúb<“³²tOY’—”`OÀ‰“¯ ‚jBJ`–jU,áÃöÙ8õÉÂüV¢x„?ð%/Ä@F 'Rááè!YU…Dï>¾e½ =éÒ¡©ŠNL†m…IÆ`е¸¯qI­HÀ P›ŠT®3<'=žsÛÕ©\1’{Õ¿ í“§ý‡[ï5ú|g"Y@šä Ò:ÇÂ{lÄßæ¶[ؿƥ!"}İp|[¼àRÄĪN%ËLI6ÁDêxBÙh-*2bÅQÓÁ~°Þûi°¶*åxepà äL¡(fE/§ûª÷ÚöýPoÉæxH’|‰6Õ˜õî’e{!{ÿØ"zÊ*=;÷¡Ù!÷šƒü¸v”ñCÎ1ðýP‡–ÙÅZ‘UOš×–Þ¾ÓMjr²\í3cÜy×Ðm/â!%Kq¼ ÜZšx—PHPð=üx.¶€éQ í5y$l\56ž:6ž¨ÚtŽ_hY9nÏ¥"8Ðrj×ãl>S´eh||ùqÙ2fü Yr?»T?†°ÏŠ’±›ÚO<ªÎI¸k=/ɬ¤õv¨Êvš®)ÙÓÒ©~êêLZ·3ª<:”Ñ8ºÖ¸-–2JÿrÉiÖ}G¨c딎‚mmb¶¨´"zV[ž_Cƾԉ—'? ðâ³fañZ3Ÿ\bx-ÂjôV­úB@V÷›m4®§Ôý]é!Ì£ñÑç·T»ã´t4õ÷›—¹tqc%ܺ†³ÎxÌ»M'¦’™o^ŒðÜ~ ºT&®Ž\Áä׳U3£ïiÌ|Œû*éeˆåµS¦Ù§p¶bêñmgg±GFõŽv.¥C¢¢ŸÏ>*ãï¯P,󜔚诫7j º>f4¼S ¤i!>þÔ§å¶™Çä=hTQ¸ZB²¹H —“J0*÷s&ˆaÕwöfyhyÞÜž¥ µÇh~ñO²Aâ -ê®Hw djx~©v¸9\ v7â®ÿë]?[«‡÷žn jÖIΊj­ÈÌ‘, Üî ÑŽŒÞ¶ñôú¬ßããòYîÙÌLòá¼ØMDì.k¬´Ç¦¢›IM¥…p3É”„fUøä)浇Ê`%û­¹þ¨¨2Uâ4Í(¾Ó8¶Etè¤7ÿ0P¤o}wJØòiùWrí ¹¡bQ%Â?DP±-*>RÜ&ÕÂÏW×Þ)õ]‡8gBF¥,e#¤ÅXL<àü|`à ›i—ŠÿÎ>Ùšò°~%°§Ü¡Ø"­È‹,;>,YëºËld ñëôKh¦‚-T(Ì3aí¨ZÏ6îÌ£6CoJwü/ðZhHh§ü¯hs¦+K­mËiÛ°CF©¬&ˆýÔ¾Ïyw£êšÊ…æõêTwôöSÃv$ÍhªÖˆ"bQ….ÛÐÇ“ßò…Þnaó™µeï!À{‡’žy>tðRlÌ®P–àz}6î§€i²HtI1¨õ $.ÓôŎ鉭SÖ¹&⹈{Ô¾_ŽB4ŒàÒdĹêoW;ãˆ_Ãàú‘ŽÓ-ÉœYÝT´ 'v‡QE<‚)‚˜48ÜHÓìÝ?õ&yJÞŠMÜ‚\·Gù‡M ãÃæzt?¸ <ê]“÷†öwѰÓ?#s[Ëñõi³º?be6æ}¹2¨â7®]NC\W*J‘S>åºj|~zðÎÞNCÖªœb&2ÊŒ B÷sÆQ®ýÕ ÿÓtÏ›n &ï£ô¤D=T¹KÔò'ôu]ƹv¿)%­òܽ 6›€û‘õšõ0ãuL~}ºâ÷’µ‘s^¼Ib>“yš¹©"\÷âݶ¶ßï~¿¬4Š‚fy Çyî¶,“HÓâ=»†+üH#I(yèjô~û|ìJ_«œ}§Ä8· k=mξȮ}½ŒjÛc'¾ÛG¹2²»‹KžE[-6ͼWèvÚm¯~V»xòižéX2€žkÕ{}4âÅ©–Z‹ÛÜÕ ]v®·Â²6© ¿tkR8a¤:¥w'ßyÃ<Üü°Ëgì–X‰ÃÑ´ÂTì; š‘˜‘U7£í“A£þ*E±° ƒGô”F9È¢áÍVÝàºgkp{H',I?;ÙE¸ ©÷}ûÚä]XŸê—¯Úãûyo˜T=+¯Jî>#UO‘pŠÆ²9?äª+¡H¼/ÌAΪû X‚ÝyÕý)û=â”σ/7ºÅF]CI˜ÿ=4÷Æà9PӴǵ“^|ÜÇ¥—* À[ï¤n-ž%çŠ=£tÔY*“cÔ3 ¡¦ãì<ïZªO?ºðð1MÔî©Jñ¹Ø53²QWè{»â ¥°>~þæ%ÓF¬òãÀhNO¹T£ó¯ØºMjŠ‚ªÃÊúÙRzêW³H‹s&3&áïƒ÷جo4_àOÑfÕÇv³ää§ó!pùŸÂ­ë …ù"WB¹¨§>¤_²ØEŠóµ×-sYMsRqTéåàÀÿÍAm‰±ª^1…šñnnÚø š®¿©:ÎÑ©”H¹6ð,ÓÒ‘²ŠØs-ƇìÀNJJ{hýAEroŶÆ:(°åöQ&k”/JÓ|9ömºÒ3w­¸íYÔ°)ÉK¶ÁO £rNdeÇ6éüDl:ŸøgÂGhµ–Â4ðRZž+àÈ®˜.(”á +.Î÷\'P‰¶Ó<Œr=e{ú,5ÂáŠYŒJeQ[cKVª¹Çe¤á–£‰o¢äýµÓùhM6ûEt·öí/­²8–N:s“VùuÅÍq'y^,íׯ{Òô*»9$S/oò–Ï÷úª1/UÞz’Ü éäóÊÅ!ŽìíMöŽâÆï­»‘ÂÇþ»î-¹P 6»hñf"¢Å ¸fÀE}88˜©Š®â”x¶‘G‘è{±š©è ²ɾñÛ2é/ôÇV¸:ŒS Yœ… ½‚1¾~à65‡÷Tfœƒž!‘Y:¬á#¤ýldÔQ=ÏkOc_Xk(Þ™î{`B&;ÞÞêk&²}‚^rÍøö”C«â„b9­`Íϲ9@ö~+Wd’7áÚþ/ìE![«u«‡ƒ*&/ŒDWÞE }à T"à{®3º6¼Ûæ57êÒÍZ õø@Ãý¡¡kÿ+\r½àÉ^óH‘‚¹¿Æ ¢þ&²¤“44 õMõx?µ»ÉPßìù “OÔ´’»6«D¡¾ ¡ˆtÐòã{aÞ´SîĉsóäjéÔ®5Ïû¥û³JœôJâ•ìœd¥»ì±uË-—ŸêeËæVkåúù殟…ºÀwÏ‘¡¸õÌMw#ÖV$+![ÞÔ;MÛÕ6·®H¼Úð.øtÏ…@&'„¥d^aj²¹÷ʣڶΟDÉŒø{ZR.¯¹ã /¯¿wÀBÒé’|@bO†4¨~ÛhØÙJg ¼oi&o¥¶H´Ûœ0Q¸ûô’ü}'~6¶j¾¡¼ÿQv4r£ÍxWˆañv¬+‰ÚÙZßs=·¥ò92/Ð…Ñ8‡ÿzW¦Þ~ÅÕ¹² ‚˜¹¢2ívqçZ“ô´íIżð7“¯âßð^›wÞqH¢ñŒÕð~˜îF¿J&¢¥–%g«ú9þÌ6º^Î[,]EaµÅ|›ïÚ¦T€†ÜÈÊj¢›`Qx³Éo5p,sn(‡:ŒTçlûì9¯á§.­Ù'ü¬E¢®#¡–e®·IäÓý% #Ù²¥YÓ(û¦ `ÛE¹F›`Ù‹ƒ«çŸU.ß$~Ëú.X‹<ò¾‹Oq1(ø2é<]h£÷ªè­V£rSÍû»8ʇQ“#ßüí¼Äç›f±¸xCFø1ô+€‘d,k’¶ªw}eŒxŒ¡ééȈ–|ç¸w®ý)[ž=º‡vsô.͘…Õuœ—¼)•7 ߟ,á÷¯•vá¥ÛÏå[xf(Ð0}]g ~æ+,ø9§¦ŒG´àIusBE™Ó›!º¯3¢òpÒ§3pƒ©~ðÞóÁ¼ò[7ëj§R¾6ÞíÙŠ"~öÉ{÷V¼QËûÆó$oµ–„®6sp‡ÇRU{hÑ·îh<Œ]îc­:¾8mÐÍŠcÙâ»íŠ{ô-†&•ºNøDu9ŒP ]±ÝÍ7tn{è’¯=–í/Õ6–ô7BŽpK:¿~Ò`aò:ÂÛ~eè Gª Žî¬ñD "wZ6ηšò™à{§êGНybÂQ.z8¢,"´™±‚àëóˆgІ¥IÖk§-Ö’¸k:ŒwÓœqäêËó0¡¨ãõ–nÙ,' ®õ£ó;ËáxE[—ì úNë ]¯›·¨—Qù.ÍS5°Sß>Ø­s Ù´ZÈ20TiCqfªn´~ÇùZVö)#ÔõÀ=³H“–°Ü¸÷G›£>\&y´ö`‡.Kàoe‚䯕•íÆ+$c¢|®5¥Jüêo¡¡©'Å0ÓMÎ\.gŽÈÙÊLÖàRK1ºøªt×Ï1"GcñV­êKZ‘eMúi2g,÷ž0ŽZ‘çÁcÉÉÍâµã«ÓºóŸg‹__Ç{®”‡ä™*Ÿ_ˆänpRhiÎî=ÔÚkF×y H¿.ÍV2 ¾Œ§DO‡WA¿Fȵ+Û]˜5Ü3ÝêLu Q°{þf0†f°GïH…ö^ÎÅ{Êù‘~+êðýz«¯9cK ¶B”> stream xÚÌ·eP\ÑÒŠ»»3¸»»»[pgpww BpHp'H®ÁÝ]‚; ú&¹’Üûݪ÷~¾š:5³º{÷jÛûì¡¡P×b‘°r¶Ê:ƒL~{WY;þ!Gò/Õ?§þ÷IÆ>ƬœAŽ¾à‰µFbSuöÏ ýÿßÏ¡ÿŠZÖÓÑQì€þÿtç¿ Íì}ÿéYé¥Nÿ?ÖÛ¹ËÚù­Ôí<,mÿÑ¥È<ÌÁûKdãwø·Hç׉ãÞàƒÞî׋ÀÂÁùß:ðŒ[:€€îî^ß* ¸xÿ2¸‘¿°½R×6ÐWdú¿øÛNdéle²7/ÀÜÍÍ܉¦~ þóTSÿuMøýöcÿsÌýóFøky¸9;uí¬À÷ê¿LTÌÁÅÇüêâËÁŸý2þš?oÝ¿VKJ:ûø³ðpqX¸ÀãÆÁÅ#ðkxÿc­å?®2¿_›àóø_ø×-ú-‘–œ-…"ìӣʃd §*`iXO«ðDõßÂ,gMµHçmSÅŠB›C²i‹œ•åƒRCA%z4¸ŽÏ_[R>N^Yiˆï˜©£ÉHŒæ¾bÕ ËVY ©è¤d8RÌ-Ð/åžÉn}ÛJÐ=–hïúù†sâó"Ò¨¢u-Ö»xŽ£ ÇÍËg ƒ¨ƒxiªÒãå'Nb¼yÄ2ã¬YAÞ¨"œË—.ì½)×[© sÌÍÞ™m¨•ŽBï–L¬D¥‚î9MBa¥…“/öR"Dq Û(سp[¸,â÷‘%ÂѤEÄ<;Ëa#8hrGènÎò'õû«m\Å·¦J"]±Û^‘±ÈÉ^ôfŸNUÔÇ=p“ òƒÏm·@íÁÊfs¸—7çuµ¨q15‰D Ù8hc¯™Qd”mç›øn¾ `ã[±Xå™S(B½o"#µ?ȱKéîlº3“ÐgÁ«Iøè2OÁûT~‹>Óö-oªncJ¶Iû„ªŒ«ÿÂhåÔj=MPÑjþ+k'ÿ¾>ÊRÜjÓûÎý½<5^F6½Y Ä ë×'ZVÏ䆆w/÷xµÖ¿~›§¯œÉ…®Îóò"‚šw‡Û‡ß°?‘¯¨ùPŸ -¿´è®;é O÷j%ôk™Î uµÚäî&`ç9LPUì§à­æZÑ´cĦåð)Úué÷á!z¾´òÔŸ÷Õ#e{-¨ ë|KšèÍZ—Y%Ôúvîçhüt>)¼}¹¶>(ùx‡*E„=}çr-ŒÏÅ»uJQ.™Au¾´.ÞËõM®¿Ì˜ólìùK.)£DJY6òVÉm·Þ&-úg˜WP·±5°U"²¤=‚ã”9l"†PÐG÷øï»ÑR ©dGº¤hNõß{ê…h”"¡U®èW™›>æ`hø£R `Ƶy EopmLÚë*æâl®]úWN=]4çBÿ”x Úyll"*ªË á w€ÌË ¼£¢¢¬Í¦rá¾²ÀÉ 3<Ý4Áf!)!-dy›nÊŒ!~o7÷ò~¨s@vŽkó Ú£üã'º“n[§¾…;Ãp]Jg/ï å§„Èwü(‘h¶íH‹,/Ž®šÒù Óù¡æÆ–éqóFi8å—ŽÉ ®áG#9{ =÷ú̱™W‡b|m»ýLMߘnâ”IyË`Dï•Vx¥×DñI°o†’Þ;Í ŽÙê¯ókžHx É¡Øçlyˆðó™Ì?ƨrF9l••ãAýlÇgKé÷âÇyʽiËiv¬÷3®Ê4BmtD¶lÄqYqeJqêBûš›/§®vXbŽUŽ43‘³UI#ë•ÔÔFY0]¡u×Âo0„jWÆDTë)q°×¨ÇíṋöXVtõ¦ï€ÆcB»-q°òZª4}ß=ÀÙ ÕO<åŸ)ß­CY‘Pfî—Tn½«:¿fÏGjã@V±ÙüÐðC ¯Nd%Ïþmêæ{Sr©¨ä~ÈAúkŽ”ã¾†Oo@¢F¤—I‰§QwG œn.öâçí ½I ¹É$$BÄâc/=êscmYÖë¾AÛí·Ÿ™³“é²EòÇ™ÍIÅgç²,ý©©œj6kR ðÃÉÓ¾ÃßÕ¾'|BŽáuNþ¸ÆŠ\¯–óÎçúû¤_KˆêþÅ{ˆ^š‡/†Ù^ðt»„ø+w<´š…ÝÔÛþ1QpÐäëì8󢜮ïBß9ÖºYTÂ:Ò•™o®W–à)T)åSùëè–{׌‡MöÄÎ5_ ñ®WðT #â±Æ© ŒËIÔÇðŽê¿ÿG10Ö¬eÿpo©?Cå´¸´Œv4t®²¾KèiŒà'&¢‰·TÁƒ÷Zšrª\ Ù.†·ÇΛÌ[ZQ[’ŸÛq˜(!‰øþÐ{÷DÿòÚ–Y-b2¹oŒü8{Ìt±_ý\ g¢Ù÷œÉ„ˆò9DðÂõÙ@TïÓƒ¾®Í\ø^f—@Ä92E"'·ÙSátæ|ƒ¦õ|n¦¹õÜfH²u ¾pè )ê»MùðŒ×‚ŠLnùŸ g>ĈF8÷|Ùeúr¨â".ªìÇZäÒ’á¼Í Ÿ__.fDKàÒ“&r”tìÉÐFÁ‘ó‡b£Dì±ÝöÉ" 5þèÑLÀÒ(ÿù³û‚Ü ×¬¨•2^5RìlíHMg‹vkuª¶Fô~ÔUç“çmÓGJÉÿhèÌ™g_ƒàBæRPr’R3`¢Þüd®R[FÔ^Ù?Ø:§ Æ[ú‹ê çÆ„Ù AY&h|Íœ_î5ý„q+îÑT]ƒ×îHºndG >¥úe¦Þm@ºUO|¨—„À ôx19FÿœZ¤As¯Çí]¸I®\8 S˜"ˆä c¸iŒ·á"/ÚêùòSƒü _.9= X1¿¾“.(DÙ!?˜á­[• ¢XÏÒ×$ûc/ÒÖôL´é±ð5áôøw±&GÌ6FÃ8"Gd·>¾y¡5cÒÅ_¼Ö¯Ï.ºÙtŸWÎåBixµ¥ùÚ˺Aßrq}1÷‘…ìo‹uTµ K¹Ü‰«É'ªœº{snè_|V2¸âK[ õY CôQmQLrã"òµ0FlÄãÒX§ÐCE ‘o¡~-ÈàYÔn³:æ ÁûDNöÆÑ|mìZ6ǺÎV^ ü¢YmÏk®¶ûæ[Ûihü%„FSßÜõõBw.Ä}~ƒ¬“•åe܆/_هݠšìw—Љ˜·˜Í ° R oqXÌÍ@89—ÁÕ°c)§¹”ª%ª‘8²Ã*Æ“«ÙãÔ{Ê„áÌšoû7ÖÝ„"º®h”?~ÆP×\ Ùjçì(®_èlòå–A“˜çÙåÈ}eäþv©ýÕ-!%BQo⾌æWR>{YYrd¯õŒ¡•""ÛŸÓ<ÅÓ$å»öôæ&^ë(+_µŸ¾ù”KÛ¯Œ’cTã,}€Fˆµ˜ò¢Óú‘¿0Áý½ê1I`'Ìæ+NzCúú:òösq7±Ï8’UTIïÛ2¢š¥±1•>µA`2FŠÈ$%g(ÝÚ{ÖZ${~dx%5Òàÿ¾¿+£Îaªqû –ô•] Åbv†*~PŽ»Ù‘°bqÍ*U¨N4ŠCá^­ULJæÈ½´ £¯]ß—mU:Æ·ýƒ¨œøÛ”¶¥"¬" S!Å?.».˸bòÆ~ñÄÇH£8M5¢á¬+‹Ð„ã¾ ŒbÀU ¾rÏ"%ÜÍð -ØfÁéÎêÔ !æo^8yqW¦ãù¹…"ß/î{›—J…œÎ>ð QuÌ{’OožÝ`«¶R™ê %A*=FsJP*¾&XùÄ1ÈähuŽeÿÉÀ¨ ÚP~€¤“Qù±ëb_ ù§|’¥Ø)*¶žýüŽk nÖ‘läN?—ƒ•K:‚ã;"sèbHØ~+$xÆ"z’ ÄSÙ®»«ÁG«î‘¢¼™)a]2yÐÍ„-ÔhвCR5°÷‡„äéÈ7`“¥'¸‡¶/ÃÕl4c¿ì“*Lê™lÝ¿cÈLš§虜Êa+~‡FEOzÚ_‘” M-c !í=ñÉT¹{5ò€=ÜcË`)kÉ}%Y†µGlµ9[OóEÇûe'ûÛ'KÙq•+ÛNI’~ŽãÝúqj÷aßiÌÎ üé«èä(m£a&xbÇBëüêÒ`*Š@qu1Bym05æo;³¤‰¢\iØ«èÏßñe •~ÄRûçÊôWgXy{a1Ò 8e¨|ÜŽÕ>·½có˜äŸ&þYxX»‡€D˜ÒdûÁ¤áNü*ѳ5^]»n:‹ÔòI4“´ø]ÜÂe2š3é(Kh®L7Üë6fŒø]—¦rqM Ü]>ÊötaòéÎNaϱZF[#4Z\$QbÒ_‘W$—,“V¾‹’Ì ËÈZå7\…¥„;—ÈÑÙqPºhßK„çO'ˆ,Õ¿YsSÙè ôf² Ñx-G"œÇ üpIrí²w—O`FƾR,<ЧˆîÇãqèæÒ_=L¹‘%5Y ÂQØ1ÿü„DTzÔX(‚AkÞå›÷£'X{y é[cØY[šlþ«:lLˆ£’A)F}›«óC„TJêP≉æ¨k+öÝçÞ9iËý:Š-e ­Cï:‹wMý[v$NqÜmNY=%ÄŒXí©Ôw ×W*ug¬ö£Æe…«§lìÏݺß^½Å²]½nq´´.§š&™礪 Äp&s )­ãWèÀÒÆ—opö®4ºÂ-1Ž¢ ãgRÎTT*ÛÏ›‹b”;ßíôm'Eì&¤KH£EPímŒ›ÞvQ|ç°ÿ–Ð#t{Ú˜ß+ñf²Ù‚h$’»l~œë©r]4Èu}rU/ÐB%Ò 2öŽÀåMÉX•#žÀ Îkš ný™L{Ÿ´Qª§¡4ÒMò)ÏcS_ƒ'C€‡–2¤ÆZ ŽôÖ”ÉzÚÊüùK<ÜN¢zhªä”:Dßà ö×[BûL°Ý©¨®,’zW†ˆ\ßžŠsÝ%t–\÷å¿ œ±»ÞpSŸq1¬RÓ]YlÕ†e½19„ ¥wž ySYA2JWÌ+ÑbÂûæQ¹dΞóìM®h·Â)‰ƒ·µ²Ú³L²Ù(»T©îžïûu&#ú€¯ä7XkQþ¦XÇõàšàuw;9MiÖætÅgÙ5šføËÖšW‹¬lev—r‹ßÍåÍ„_®ü¬¤çèøùz«¾ÖÙ,€÷MÏÃ'vQÓ/©…^Ÿæ§`Íq Œ¶fôò¦É͹àÕ6‚͈Ñx ýï¥påר æUŠ¡+abØÓ‰ AðncW‡„©.ð£Õ¡+ßš!ÏqôµÑˆ[÷ qßFk{{¦•“uôOïÐôýpÏ–e#Ìøt_WCëô1nW1Šâõ«%¸È8½¤rÚÀñÍ–×GÖ]M¯§x,ÖA‡ü‹«\£ŸÃs&>°´AÖŒù‘J^) iʼnV) ÄÁãoÓ‘Ø‹¹1±92ÝÔ¿›FÑÄíå® bóžìåû h†Ü;óª<ûxÛ¬l²äbQÌÞàòúór/±9 Ï¥ç›WãD¢"6xL™Ö]7ãÃ7äVùWÚÜ#Ò?Ý`edD{Uáš~ŽÜ¾'%‚åyÆû*€¸‚É ä0ž¥ÑömqúºÇ­sET«ùƒD/–w°Mð)÷¸¸"£ömõDThæû€ø³È/å·JʘեŸb¦#.²ªŒè”û:|è‹®œŸu&†^1ô"x†öÁUäØrX`¶Cl¹g’×N‘§&Û6!6#PëB’³‹T0LHÙu‡eôïâ—Ô\’¸%ï¿§:z¢‹Ÿ¿°‰)Ý[’s:ÜÆiJ}NqÌ«„ñ\qW†XÎÄê—îà¸ËûN_uæ"š,¿9‡}N¤¶cŒÀ È8—+keŠ ¢ž‰ ŒÈ"eÊYàt Ñ¥-sìú”(¸“1ö8k:i°'Fk®ñ¦b _Ê=0"x¡@2y0Ǹ¦uã_O¯vuÅ>ÚÖyhʼciCYÏ@È™Ãxrv’–¬¤Ê ¥y½¹ ´2è¶¶æÅ]/¾Ò›U! ž…š%'°2 r¿4ÜÖ½àG+–ŽY \¶ÆWöË*?®7~šážÚ@yh“~Â*ÓD­hE4̱ 4 ;Iå!€ÈÌ“sêdª`Æ¿¶ƒù ˆ™ÆÙçލ'3¡úʳcöéè k.OŽÞ5‡ññÁ"4RöíˆòÚÈ$ÔKö³z¼ '†.‡ãÓ?A•Ô¹y‚„L¢•ì0-†ù?I ãOOÓƒs|®ÛÝ‚Úá¦Ã¡,æ &› 2k¿VFE…TÍÙÃ<Ì%T%=ŽŸKìÍÈN!S²Ar£[³ïñbêãè¢oKòáÖ™úÏÒKŠ!™îÄŸ@6è5PB6|–DoK`¥ƒû”V5YÕ«¨"®¬¾± #ì ,[ËÅk²’P(âœ^»o ßÿùU Ã±× 7Œc„íCtKbþ˜‰ÕcJ¿…¡dü}0·¯…–|¬À ¹ÊÁ­OdfÅå‹ì„ÁS>ú^×®OÈÏŠP™ü0®VÂ4žq´õ•ŽÅ}¸>ýòt­zn­ïÝæA3Py7‰Zˆ~,ßiÅÔ3ã‡åˆaC*½Å;37Â|ahšÀøÙˆË óhw‰ÇÐ4FgK7Ž©b­ÿ§¦ ïv_o,»€::E‘¼r ŸVt1`@ÈЫêDh„&Æ„õ™kq…ÜR¸2YÔŸQ·3)Ôǯ°auJÆ]”¼8‰1~î´§Ïœ ‹ßz)ÿLè‡Òþþ³>ô Ç}X†cõ*ÄÕ™üà©ñéùJ‚æ=2’ÜyP¨— ü6úS×›‘qoqìó‹É)­Õù®ÆU«œR®ýÞwW!ÛLr(ÆðHÛe›+xÐi¹o0d³P[»´ÐÉK?²Æ¡6¤Zƒ$$5>³ÁŸo;Y‘*4* #vá5O'¥­+ØÅ"¦Q ‹+Þn¡{½T.üÆÿò&ñGìGB"ThÞ±qÁËðgk{Ñå/Õ“í‚3üÜÞS:2µŠ:U€EÐæÌC~ŽKÄM„‚¥YÂL‡^ gPû<‰~Ñ Ezþ«jô×óÙR’/'AÆA3u…H"ÄÊ‘ôÀ+üãJâñ‡÷+xAÄÊ{_fŽ^¿á–>á9ácÇ—BË%˜û"vÍý´8±öÖwRk ©@¢å–äöä‘ 4{ 2r®'È©×9ûW‡=ЂÏNEØùѰhØ\'Dý]í)f|/#e 97”h•©ÞLt„UÛ#pã|7ü®4{›‘hîÙx/›;[{ÞKpöFù‹‡¢:ˆ30%j1æñZ´# _So*A T3òƒ‘fï\n,Âý”qh÷S_ÕY³UÈ}’Ûî^`òah`Ký‚)lÍJ‰ÝÚMž|ÐßÈÉGjj\¿'A<î]ÄFálZÊ <– !ìceð2c–jÓ3Ü-š§EƆý\{ö:GL±>ݧCöEÏBŽXÅ!Š„9áTs¼÷iê3vJOU¢…ù™·–œÒt 4¨úâj´îo>5—ìÁ¾Þ¼¥]íL@T Å©’c‡,9¤¨ÿÈœÓßSÀ•“M²:£‘¶¾ÃEFõíÀ¬í˜Â{4–”™Óu3&†3—BÕÂ4o\R¾Î á_7•+0NÆþ:Ù-š²„ÓŠ˜z/!äŒ_Ñ R^ÐðCt] @­ ®(ÿHÊAäB5pà#¶¿§ëqÈ9µIðmÄ€ÂQ Zµy…å(¹Ÿ‚]-þ­Ù»+Ew¬õM¸ºT»!1ÒŸ"R•Íg+Xóï÷ʶ j„8£=w>+l–ã±UK^ ;ÆMz|ÎáàÕŠ°”ÍÀ‘ÓͬȌ|ot<Êm[f± Š†m 2ˆ­å)Ú%ß<õè ÛZqݬ÷~¨Ÿ^snóìu¼%Ãû«â²@²Ï½âSrp¤m_‰¯?C¿^¸ Œv:˜CÛÔVÑNî+T¿ññkg¦(7”Âî“ËÐРî~.m±2üõ¿b4Šd{c½¯šÆÂíêXK!Ô“U£ûÙÓÝy¨±ÖÀ –7½UK£‹¹K£eñK€;´Ù$è“P7ü5Wh¨op-² íìÈ^ûlz+ùZ‘Èsä:•L0.ïõaþîì]m¢‡éƒÚ‡WÃÚºãÒ~£‰l›×$#"m,ß*ἓ#¾uKZä¼ÁcøŸ?ÆBþ1Ô“Ô°§ü4vûG:^(q¡é±Áú oJÿ*§ó—$ |Ö¼Ë9ãËî³´óv Oˆé;hu$¬sð«W‡"Ÿ×á–yû}ÝEÜ\¨…yýšÌ w8ÆÙ=Š~vÈ£­ÍJ¹Ü’g?s¡pNa~:ìz Å¤â¥ÁÏĦ:hÚ[+ÑTª×ÜÚÚ¤¿zÿ6!ÉWR¾º¾`Ê7™¯F޽^þe!ºoš'À®f[‘°ÏÔ¯›ÕöÑH¾!TbðÐ"‘¦ûîí˜Jâ{kÐ {´Û­u¨WºÂhkôcȼÉÝæ„ã#Ì}wTÅ ú*véçLO‘ã͵ôâñMȶé~Í×ôá«*â»Ô™ß\B®f”“8sWè mÈ…e!O}y1€wod`òÉS ÁMîF3ßí®̶ùjŸQs-ô}ö§Ý×BèM5²³ülõZï©uBÈݤL‚© R 4T”ëì# =üKþږN<+- ÷ênîÈÚSþ$gùQÈš¯¬«`A£ßWÄâ˜:ÏÍÊï(ù}m Ù±¢Î+Väãž½Þ³ýƒ´þg[ýŒf’®^‹P×Ïfl #Ù’¯Ÿ[ý‚Qˆ|Ãnˆoû™¶«qýó,kXó•P<÷–‚¹#ÝÚØ”^¥?#{I–nÔg¸¯p„E·/[\C«×b~,yîiЉ0¾ð;Ÿ¦¦üŒÀÊ‘všMÃS&"£NËÂcÇIJ)Ýd“øimûˆ¾pîôíŸåùÅ$áu`Î%3ãäÿ„ño"Û‘0™6ú²¡ªkd`óGPˆÌØu_÷ãêze¢H¼ÔðÒ‚Öë`í Y䢃ê.KõÍsˆ6–(åà̜¼ =+©7nÚý¿å`N^, ‡Âb±ª@‰q°5ÃeéW¯¦YÆz©î’‘zC©(›»„¬ðÅÌ({ŠcïûØ…D©wý¸µ¥ØË?>Ù(®Èž„aÝã,v'ví0H! 橼mîþ\Ky²TûQ¾+½Å-9?ŠuC³ª¿‚7­È`'o¸Ô‘uKwƒ\ZzÀ[r5*¾'-`…8Ò¢oM¬°½}\ت;3]uÿf²BøÓ*M6¿QØÔç’p¡ªÃ©¸M²WéeYf2åî"%o(<>»#ÊYzCžµ±µ²[Ê‹}ˆ4[·¯›D%búNFM€¬ûÃÅÖ}Ø^‹<¸,0ºö =ò°«[ÈëÄ]®§µí]u%4ÆÕÌ‹¼q©®Æ¯°Æ=ñÄ¢MúÝ$YJÂlËöTYïZûŸ=”cƒ#½5 "ßæ1ë?’¾"g¼žÆØT ¦H[™L¯]r¾hÈ>.s¾™U™¤hÿlÖÄF©¿óqlr¤ýÜ8MÅKm4‰¶<yÕ2‚‘•dÊœ=ïí]M *3kÔn§Ã >óeä€Z–eÔ¡‚ÑÎŽaô×l hm½õÆÉ»nÙÓpXe¨1öÍX£qF!ë–Ft2Û?¦(5èö’kÀ…Ÿçñ”¾C?¥ë€EöùõÕa¯ÚOÆ&“·‰ßËÔÓt‘¿[!’%½çˆ‡ÛÐÆ¬pú¦´Ñá~ÿ™~ˆôc)Œ3ò,Ðßtû¿<–šOÒˆÓðÚsr¦èçqÕ@•ìã‚óØNêÊÞ‘}ùÆ,¹u[ùñð"OùñÜ@ìt¿v»;E|”ž.£+ìOÉ5’O TؘÕºèë3#OpÀõA¶C>£·ËÐz^nz-G°‡Ûëq ¡dN-‡íáÉÍ)(2qva-æÉ›ÝqÖÓ;b׊ |: †Vǃϛ9„ª kÖ[ÄuÓì앆¸Ì·ð Á·C9,yÖ kfÄ+0|”& ùFů¸‡ùG«°ãW96QW¸OkLA ¥ÞÓÆe¡H½Ï²çÛ9¦¶Åß‹FçÓ»‡*½'s&†ÉdÏ|Ÿú'IoY(=/#ý>?ûMtó®Öw\¸j<.ŠW5¡˜· cbŠ¿ncŽŠ‚êl(0¸ÂŽ@ÀÔ“~*/XfKw™Â¦¥_ÙŠwý9^ìéÊ gúž8Õ¶ðí»ó4!-Þ2Ç5CÃØÁ¦;ßRìG׎Dj»\Ê`ÏRæŽþP¬ª‚«[)ç"‡âœšXÉÌíQÐð£‘p奇­Ï–¸QÐu¸àÚ…ï—3› )ƒe^ï&ØöP5V™H…îÆ“%n—$í°g|ɘÓÜT‰fO/¹¤ÙÛ~é%_H©¦¡—µöש?š}»M!—óÈ\<}‘É0åYtÓ”ã¹Z¼7JdX‘+` G­Ö÷éé¢K¯äã¹<2í¹;‘Ñ ï3—£å[ =LÉøàŒ|?¦l¦Ù j®_m¹õarnìW2>ÏzÿD:ýá¥Ú¥ósÑy#ÓàAµÑD$ñOÍGá±/TÅ´ƒà~jF/)—œL)UU’ôqË)V¸mâ°8—ñ’Á(vôü¢kÔPÜtG±~Uéµ*¹·¤à㱦åA¶oó@f—ÀY³ qe6¬Kœë’ðY‡m½œ­oŒ3ÉÞ±²À-ëOLïaÖ(E$c cC¡ÓÛ¿6ôµ<ާ<–ú8¶•d$Ínà~L"°‰wгÐV'öòãž2{£ì¼×+‡¡E®0fŠOÄôÎ:Q¬Ë¿O/ý×T1î”ÑÌQ@n¹`ÓÊo㊻¦¦¬z—pnlPc‹m¨µd¯‡$ņÀqÖëK;‘S q­ãÔ¤µs …àô ±wŠ-y³xu„ÿµ+âCÙý²G×}GåjÐ]ÃNAbø™°œhóÎb&Š ¥t¶—_aù «]Ò]q IKŽ­î»’‰Ö笷¼½›®µÈLjC­JÅq´µP!Ϻ7’Õæ¼°VÝÕfëÝ+²ŸE8»ï‹­¬` .æ!úR.§ï)1XŠpák‘íë/8Å•öÈŽ£¡’lwäNŸOë·Ÿ“ü-µÑdBîç&9UßJaçê¨ë+1VAðÇÜ䓲_û`¶ô'—_ —~BÖtBÔÑkR—ða¢i©Bl¦Nã©y³ƒ–Ù8®ýQ™ü É73Œd H_yx>›½O&Ì^À¦åONü9l©ù W¹³xÑÁ|[¸£^^ ê/…&Ñ ýÉ— hÖ>61w*“o6yÌXë=)üoºGÔŽ¥‹î²SÏÎXmàÃ}ÍÂÕ½ cÖ×02Õa]Û¤òо9"ŠÁüh[áûLýÑ-8ÜäS%‘85“‚‚yZV>G0Nìk&?3ü\€Rœ/±¡öÞÑòëùú2Pšj‚TY÷4 rzt@‰q D™ærb¿Ä§pAǤ2øJ­Æ‘2;…ŠCå!nKÕ©ý1.êòó£$¥§~!²î²TÓÓ² še§ãY G­° Ÿ´sàŠ_0H_üG-£c1>Çñ®¨fI¥M„[KR´5F‘º,íÚ„»•¾»·{j†ýf¾êÐøTÏŒ±4)X@1¼]é9!€±¡}%ª^¶×>¨ñ.’\‚×'!ø‡YzÂuc¶hyƒÇ°hp+•$‹ùx ÉôUÙk_(ÉÆ6rÂ.ÞòѶ•Q"±’*Xè`øîÍ{˨‚°%gPy³ÅÇ’*4£©k"B³gÎ1­r»—t¤;:âSAD‡æ|,}Ô}^U‘¹¥+-ëJxƒÌÏÁûv¸w®åC8©?Þî`¶â5Ä;ûï&=ÔJRÂiË.±ec‰ ‚Ͼßb7Ù„«Ä³CRÕöJÉ1YJ,ðUÑ@wá8 ¼Î=dÀÌRœøuRb"‚ÂZfQØ'¨÷ºÁEUç(‡ ¬+ró´£LüoVnœç¾´ÕÎPÝ[ÌÛÊOЂL'*èšžq‰ÝmZ¾o£¿ðfu¥ÂVR›b8}$^ÄžçaB¥qúá—” áøºé)§"¯ UhÔè³ÂáWˆÀª¹î¹‚²¾²ùP)À›$QþÜ‚ ­”Žå~]±íâUp#â¸åß·ôêØ ÿúm„Z«ñšg'ÝO÷ ŽÎú°ºˆ3JÍV4•ϤëþBw¹L ‹|Óü*›ÉG¯‡ß ꀢ³R1Ç 0u k2-M_»%4¹[²SÔÿÔä¹È$;Q´é Å$­¾z5ñ:rïy!Öi(>â@¦`Ö ö±ë+;qÈ_—˜-à¶Z)_ötI ÊK­òXv'ãUm`èF”ÐÁdü¶¹ÖMvö1š6%u}×ÝÖ‹iÈñ»C£ÞwxtÚoXûãJn¨§â8cª^r&ÅÌh§ÓßNënôÖ˜z±²-á’Ï a"bIÚ“„È͵3Ãæ­qâAï|=Ä{q ‚°/§e£…›åoës¼2ž3:â'„4-Kqâ] DV}&W°ð÷HãäøÝ„å¶(A=â_¶:¦è:ÒwB0_â4¾ï¢3+ôÞòî…æ›r2§Úr·õ9ù8Wº F¢&Ì·›|èã—pRãêéæÌ¹@•# ŒÕ;²úŸ*"2Vå]îG«:¯U*vd¥D땪²cyö݄йf=!T1'¦CK£V ¥9µÙã ]v€ã¹4[ ú©ÃwÁ}oI~á’u!‘ýΰĄÐσ£&¼ævª*çoÖrÈÉòÄ6ÎRß»½ùŽ2ÊgIÊoßZ檣¼ø®)Á¢KRŠþ¥ÔòÜV’¬¼26Áˆ]3`ì§\tCªu`ysÍH¨ÅÍþñ²Ò°Íˆ+¶D5G ÕåÚÒÚÅì"örÇq•'“ŸÔrm|'o˜? kå~¹[ìè<­2}!Åy¢½)šH Ñ–Ðþ.feb·Eæ®VGhŸo\BÕÖÚˆÑé>×Q å¬5›K‘í#Å!ÃSB·AYÎl¼©F‚•ó|¦²F»©á”!Ùw©÷€ʆ8‡µÀ =ƒœˆœ=E®!; WÈ<êÑ,ó(XöüÞý®ò t£¾ýú¸óÓ͉¤Ã^VåNs£½±ñщ¸M8F÷¥èçX'˜}â·BŽǑô¾öÊe%êW[ìª=#EÉ]™˜<‚f~†EPY›?u>,$°ì»†éY­•âÕf ´ó@ ‚ÒkÊžsŒÑàÒT9’9¾¢I].ÖÄøfÅl}@¯Vüv¨~%RñÒú”*·QËmPì¿LQ‚ð€¦1>rnÐD•ÿ¹H›îî;VîJæJ*‹©ZaćúËží-¯[óᥪ8âÏì“ÆÐqY«託ô’s.VM®¯3¤p)]£dðr|§—Žë&,›xd›¶4¢ë/©×V'~¥——¤Fžºü5 BÖæsÂÖ‹}U O‚Í—¨«zFKÏUþÁµ ަUtñ!¼ŸÜÌç¯æQŒôãØ?B±ËÜe† ^‰oÿD~ãã…z¦l0ûîË@¤¾„ñkGI8 ãá¹U)' u‘DOT˜–ªîF¦it}€VðüŒvD}£D7ÁíÌá³RŸàãݹÅthY†¡åkþ§²Ž¹¯ä¸":$ãî4Ðôd‡$²óøœŠ&Î?°¿–†ZJQ·ôÿQ‚’J„P‹ME§k½YƬˬlDXƒe<ñ3w ÂŽyu*JýÞw""(# ©wHâ;¯ N²ÓÅúS$A¯w»,âÉÒÝq¥±2yï«)P~É))ó±˜Äqöd‚ ýÊÄÆ‰ïHAaæýLÔºÿ¿è)˜ëì„Nè-œ ›{áûÁ´ˆå®>Ó“Þ¥ÐÜä*zƒCæ~ Úq•"Ÿ§qÐÙBèõ·zîi«n_à["Ö@f¥v†ßIø×F㢠j+œFÍtìfðžÞ*z†ž¿É{­¾EÒ}Píù0 l䤟’E¹c c­n!‹h…8ój7¬Ë>fñ/{ÛMtˆlCÏÑ5 Q&¼Ãƒa/o*DŠBÁðáåEÔ¨×bA¸+fVp.á~NƒBƒnVýÌIn¼@ûHÒ0ΖCFÓãúZäÖ.⎗–ñyn>ÕÓF‰Q®Û¶^u~k\]œÝEdþkÄCãƒÍ|Ð:/,y~)N AR~ˆ%@secjÊfÂG>W<¿3¡dL®„îùkOk£ïlFôÑÅKoöÏ”#=Þû2t9z–t15>¤¬í —§û‰7]˜*Œ*N/FŽ´’f9’–\øpͶÈEG¯)YÅÓ)môBp¶{ó Þ­†Y'Nª$íþè¢K°%qÿUÓ"[ªÀ®’šÈÊ?[˜BÍEr¸Ž/P¼m¾Š˜ª÷ ä}Tù&6ölj6„ɸÙZu @è.î>3þVÅ&S¡g,o—•»î‹EŸ…”\_é*LŸéB/lÐ3áü% Oë¹'¡CbÎÇ9Ý—“¶)Ï®æ‰6 µ¦sªìQÊb²Ÿcç¼Ù[±‚à|gÄ=Fô96ÝMá×e±aÉ.u4"2_Tž·¢(;­¯,®ðq¿û.¿fÃ})¥#½¤×ž75–·ú¼!¨Mw‚ =®8‘pßýÁ:ë‹Ã´z¡U¨ØÿFUÒ-ÞñãKEËÅŸH¼ÊéJ¼°a‘)\ü:;F¼®p•â:.º;7M˜áè»J¼"%d´…÷%çr.jß+TkgS±t'gŽ$ˆL.qßç9ieJŠ«›n²T«Zõ 9®A ^ÂÌBi —_H™+ǸsDn?κ¡ÖøfªÙ\¸ï b8í !§S<¿Ÿš6—¨®Rª7 |A?~`À%¤Tïa+D°Xµ·ËæHŠÌl¿—ž­Î@ìO$4Ž3-”ªWŸ½ fˆ‘¹xlÇ †"ŽÞ ¡FH1ÿ™;`¬ö*w2sßÿç™ã`æÕÙHÑóDMëõ›–+’ †NÂ[ÇÍðcéªØØÃ€ 8¢GïΖÞ“"jˆüœLÊÏ ^ª`Ïúþ‡Uü9©Ï'ã¡…" ßüç´½#z·.SˆÚ1¹¹1\ ÍÒeG€cÀøÆ‹kÀr–Þ~•GO—¡àx;,) ®ãýÛâÏž%_uºLJu.Oòj8i 8…ö`Z¨pÆaz½µñdëzy‹3TEse¢ÀYÙ·•Ó¾¬É”„=›š§hÝÝ1AÛÍ*ù}ó?Gx… 1â@$è‡ïXAÀÀÓ[eѤT†oÊü­Óꋹ¼bbýþ}=jÁͰq$WãLú2÷à9‰•¦IŠ]Êþi-©&ü ²»ÝLªÄt~ V;!…Ø ×È]öþ/Ρ[Â:y ÂÉTAd§QzýXaÐ??`uŒ°Lie/(?z~У² Gn ¦Hlæ;¨SÃÙš¼¯Âþ‰{a4{©{õ $„ƒp„•ÉŒa·+r6-Æ“¾<œ3·ÄMÿuº3Uºao3CʇBIÚúÛ¼^µßÑøìÔ®ã`¡Ûçþ^M#Y‹ª‘c½[¬Nð,Pí•<¥Æ_™¾LˆYYÔÒÑ”ÖÆ }m>½ÚUx‹®Ä䉺a™úíi÷yöÜàC"l6OVÎýúWX;+2ÍfÑl÷‡$xá—ØÞ©Ñ”,#âñáã|ÒJ¤µq|ެÞgͤl vç-¤ýLõúòc(ð\AgF÷÷VX7‹Å/8xOs+ •&EŸL9ßDZjè>˜Ö@(J]pÆë­ ²Ò)d,Mñm$•«‰°"X¿¹®¬u‹ü*h’kmpW\Zu ¤–Ä85Y¹ÒTìI'¹oìý\’“÷ýÝ-ä&&i9Î#ŸÜ£ð/ÍÄSBîo¦€œoÖ8cH Ãò'HŒ²Ljª4h¶aSýÒ}l/d3&”…ôÜAëØ”š¡Óƒ"/4 c,$Ùó5ºz²1§YTˆÉÉ”‚lïêÑDýœWFÕEáI§±×Îä ¤Ÿ®çOÑC¼Sß7…­72[«;ðë¾(S[²sº'Zå(’-²mþ¼j¹J"M¡)òç”ü9ß—>÷mÜ9ì@Ãçmì GQµ¬GÚõN˜³Tm‚NRß7—ÚA¥ÒÔ ‹Øá2Ô«¤·º˜û¦d†úš_`]ÅÕ!Þ5£à•ÄëßéÏñ1{U©<ÒoæÅJw‘"ó3͟Ή»hÅ£€P$¢)?^ø~ýÕĺERšÊIhQ‡=¦ÂÑÖÛ?+ÃHšJ9mo£«¢\›ñyF+-Í}ã®râÙØ nSp@=3NÜMO¾‹Ò3»NÌû8&‚ÝIg9At>~ð)hÆ%laÑ$ÓÔÔ¯1#p.4®—¦±<ÓÎt« Wi–D%9#b°3®-Ýìk%miC‹(Q/>Q³&-£Ss}RôI0Ц„«6zvÂÎ'îšÛ6G5I ’Ο6t•¡0îúcIø~»Ú‹F¨êbÕGc;Ã(Ýfˆ5 ÙŸsR‡³[÷Ï|;&ê§Ï$¼ï¹-‚ΫXˆ.;•Lé04Í&™W¾ŸLÓǼÐÎÒ !3Mºàf¿¢˜õˆN°lpß…O´ÒÝK€‡d÷8{x“i§?äËòÛ(ب¾g¸¹80 Ç(§©ù–“Åܹº%ù®_ÒI]e]1•Aºàf"ð WÕᮿ<*ñWÎÓÀå¸[8Ò‘Ë¡¯<×NÊ•ó¯  ¨¤ÖH̃n_I£G£5MWJÓ0”_`CZ ¡êí¨I⎄ã4Y9r›«Ý LE!‘€ñ'¸#0ÄôبéÓÌ;ll˜aBÝß jž\åêö ŠÚ½ø’‚ îÆ\¯{ÿŸ+!ÔÞ¼EØÝ8ÿ4Á=ì–:^ôóÍü¯¸?”#@6,<š§9¸M'æWÝ>ÜBCAv\b[ÞvŸRF¯ª`G¤ [ï7ɧÓZtÕœ¤2e$ýuÏA™X––àq0r¾Z’….c›uÞ^èÀ3qxxP^¨zÉØ±Ö÷ íbb:d-f ¡Â00áûˆŒÄq„múLÑ¢¥rÃô¿`ÄÐpH¼óHy¶ƒ²„`(|ÉÆöÀp¡éw—­ÏdÊrkEcŸ F«Ùþ8±™‚sê^øî.8öÜ䂞þC‚ä0-³íæ©dû¹ŸŠñp¥ý}ĆÃP%¿ø´yÊ´ƒ³ 4ÛP™gÆ;@å`L•€‘gB¬@§Ë>ç?¡å˜ØÇoÆå*œ%ø I0¦:;ßõÎèþZÀ (½DMѰïÚög©iØf˜’5"∠eÃå…ê ™6;@(2EBïÞŠè¯t;Ü%èGÑ9ƒ0"‹×ûȹmâqïºõÂkÌ[ƒ‰_ Õ+ܳ„qiÁÃsâhïšÂ¶gáJ`æÿOdDÂíH$/®Š®¬N4wÙ”s¢×’3TŒ7&›qäŽ1â¡bDö\S^ɰÈÝåæ!µˆ{‘j².h§ì*Æx#¯î !‘#î–D'u ñ %hÊ\ÚÏÈ^Ÿ\¯˜§Ð­´±š•Ì*þhnUØŽG%|â¸Þzi‹ìi]%NäC„Í¿rL߇™„6`|Êú!6d6Ru@•°­ý˜ý^‰¡êðøp¯LçMÐ[2q(ä |®T˜|™›ˆXŽ;Þ¨4£°öE’ÄŒ¦¥j;-è0@±kÿ»ës…!™¸ÑÉ ;Ý ïëÍå¿/ñ¥LòÀËxâ>²ðÐeTÔ¤Ó™Ê5à/õæqtÂ[œD†ª[LB?eæOz½J!À8•M½,!-,pŽœ–aX|ަÕK’Ù;¥Ò 䊴9éÐÐH›…ðø½kx¯ó +ÄÀèE~ÂqUá£ÎÓÖ‚—sûàÍf Kiëç W[OÍ»(BÓcù‘; Ê´Ý9ä¾ðùŸh^7ŠùH‚Oµ€±T}»Fµ¼‡æ0˾]Ô@aå,Öµ¥Œ'w(3‘Ÿ]Ò=Ð(›Y*—¸$F?íûM‡ˆ–Oõå?%([T/10¶¬„©œM‘,ß-Òý|Éåç²2Í•pÞÔ-¨yÛE¦]ÆR3š8×¼…)ý(µu ±ï;UvÆZG­á½ çΨu+X¦Ÿ!f„¤ob™Þì)nϽ—VÉ`ÍÈ;q'ÂÙ?uO¯áî;Avw{„o3ñÃìÝ’‹ó)ïÁœ\#•¬}êc¨æM” AcM½òëe†™iòe48²ÇÖ¹y4-’‰x–,xDG77äíÝÝz⢌ñ¢{s‘9ÖäFÀ; Ñ»,ðÝ©×ÃR’ŒHTQxÊÊ™æKŽº€òuš™yϰ¨w±[ЬR>kN“õâEâ”àXó±û[…ú9´L€ï‰nšÂhU«žï6eüb ™÷?MYäE&vDdd+”@€Œ6ðŸð¢„69úŽÉ'“ †ìr’[|/ßÍR ‰Wì¿E§éáxfBJŸƒˆ—ã˜×(Vè}:¸3bi8õi9(=£{6:°†$ÕóÃ0srsÿ¶BŸ=åR½Öò‡ýmZ&‘´‚`5EN¹sÕêÚ‚a"¤™r"3² lú¬¨À‡´À¼Âªáöq™2E¯¢J’™»—«{ÞÁ›i‚¹û¼ø±õª’7”$¼ñØý‰ŸŽoò’NIÕ—¦³ã”ÇûO¶˜òÞ%ÔëqrìÝOÊÊï P+$¸×õ¯#ZÜk®YQ2G¤‰C$X‡iÞp»úa^d5œÃr¹ó6à8¡6ø%k}Ì ×P:PpB®,~càs]6@ÿhGÒ%µ—àÔuóàÑJÊü°€8iq‹Õ'ׂ Žtg+ê5]Ñ3ÙÖf8ý¨½ÔÞ=UÍs%)Ï«üW0äx6ž/ÈŸ/(Áh湈÷høœË2„¬Üàÿo~Ͷ«0iè s-;dZJš Ò©r[!odc>ÜAý …ÑÁ‘Æiøø_Üï*‰¬njŽqS/f‘P3q'Æ‹œy¤­\‘÷—|ž­[ØÝÓùÀÇuÂZÿOPj_ûiÔ‹ùÞa“ˆ§y!ÑS³¦°ë¸0$†þÃÂ5÷Úº vŠ"£4’Á*ËL¬ÈîbKhGŒ¦n¸Žêˆã®e[¹…ÁÿÆê×1+ëzðnjÃK¤Ü ¡µMUú•½³£Õy„Éi‘™ ¤Ýôžçp=þ0ü?ÓS²O€¿aŸ¦Ã'0Œ³lO"pu¢æ[WÙ‡òÏL“¦½IÞå"í(ÅË)g¦AŠ?£÷DÉ$¤†·’²‰÷_Z†½QJ[†â™0¡Ú¿Pa%Cþ^ìªJ¥^R~d¹ú‡¶Ë¹­–Ï ì`³Cë¦ê¼läÏ®Ðá xE;mO{8æëÿ±¯±ØÜ²¶¤6f˜™tT;4¾Akþ¼‡š:s!úÚ)’wØÐžŒî‚8eZÄÎŽeYîD~™ì®É=^>ô rq­¶0Œ›í/E’ÓÓŽ¤ “ÊF§öŸÈˆ^­,«&Dñâ]õöï[^Õ.—hÒÔM7l‡ö0‚iÿø,·{ µ:ù ‹7ÿ†"=­‚#²µûã911éG"Ëø¢×˜î rû› Ûk¿[ž´'—íG— w[áP Ì,ÌÛ¯J¤W©É–EDïffÁc8Ÿ}œK/ît Ïf§»Üñ™ϪÔÍ­¶kG ±D’°@SZù+lWOPd—œÀ ôŠV«ÓA6G’”þgþ$ýöŃ¢ƒfëœc6òÿôWB.ξg’öÑzƒ~y¢p õD_­ýß·^è%ÇHt›Tëe/vc:b¶:5b¥ADÇR²±)yjßÇéXä4@-{5ü2ÁNòÿޱw÷$Óê ÈV}aiû håö'ÓþŒ»%coHæ¤ ]¨âè´šWú5dÖx¾Zîžþ‡a£‚çP*”  Ú¼—´²©DŒTQXŸæ³xÜ_:ÆQ¦€êÜI–<ß=oÐÃØ fœcÁ°çÉüܧ}“ëÀKyZuƒÃب*°fQîré¶!½…Ãiø"eG0o:9´;þåØË :ƒxÒ¿·zÑ9~™ #5l\TmîTæ°BMÚp¹€óYi¾ #§–º 7~ñ›úÄ!ëê¯&—ÀÎé/§Ýºk êþH‰î_3ôÁ c;˜fìþÌ‹…ÿè$ULtg›%Y ´ÃÓZxY‹æÇ™¬ pÒÚõdwÃvÏ›×CK/¦fð¢éˆü ñF¿,–µÐñp1aô{¢†Š¯=î1—€Š¥’M9ÁÝmŽ0âpY¼cÛ0¿Ò)æ¡â%T¯2mÜ}ø_+h¡°–“«õ!¾Ú.ö’*lŸHÿ›äçøìŰØ´i—óÛŒÍÞEµ¦ç(à²0…ðüI­ ¡á™D~ Qo-Gx$3PR´>B¨Ùº¼=Ú{T¾h˜Í½ßlYUBØó.–-A!>kg¥ƒ³²y2­Ä†½œÁ0ÙK½C‡/ë HÚíò•ÉÍ9Ù}÷Š™Ф6@«¯kr|xáÄDå‰p:U}jì3ëÇo:Hœ£™ÕT)I–ÄnicèÚï-íÂâÔÚ‰Œ}ü@ˆŠJ7`\*ƒš“8D¾gNKÎèØN¥}´Ã@ÐGùš…w…¿àÕþaF³­ßdë …Å»|ÜZ'ñÁûI§9,¤GFjh²ªäΣÏüw>5(=µæX}¦z#¹¯ÁeFî0â¼Ô¢ü) fÿòPÏù6•±Ú¢a$|Mx¡ÕîSšåGjê걩1•<°íóýEÃAÑ%Ú:ÿSK7\Þ<¦ÝqB H¸·©ÞfAÁtèõpàA ScÜû\Ì¡£Œ¯•m?ü**¼PYhÄ+–º „w}Ã%3ѱT8£¬Ýº.^gowóþš³³zSÅya9G§Œç½IôÁRIsŒ}PÁ#ˆ?à‚3~’æ*ºè(úÝw¿ÂìÜV-¯Vg–ßeËS籉kðªÓw÷ô3/º\¬¹waÞsIz;H"žëšÅäð%¦,¡¡@”ÿš—Ÿ™®7ï šM«#Í[ÇjJ1¡ _¡\·Ìnæ½þUMš)|;iá©“P_i|À¬ÞŒÍe›TNÃkMA¯o»—4\^E¨ô~c¢KÃv3è47›4wÚ(ÍšœZœyAÌëÑÚ]Uˆ’Oýž”·on9†,lNðÇÚaªú×ÓØÃ^»¼‰õgWRjÙ&Ýh ¢xà&t9ºÆ™­"*æ†W£Ì-Ш·!oq·F‰ëgB§l×Zxâ˜&Mœ"ñn@J6—Ãhäàš!U3r0«7À.9¡º·I:ã8Sñãé" œ¿Ï´Ï=§Ò2ÈZ¹ÿ·(ºÂÅ.‚â„Ë 6(ë1>I4Ôü£¿ÌŒ$Åf‚LŠéœÏ¥‰÷XEò;øÔ³¼^%h«/d[_Â<†¸fÌVÜ—³1–Áùãy-ïÇäý‰jkùÁ¸oÀܨsvµ8«ôxÓÝ0´©n§¯÷#y®qHù(Ýœ—€F'=¡BŠ–µÃÙÍç[ß>œ'OÁðõz†ÖþK5ç.`eoÙ>õ¤–©D@=A³Ç”A(¬^”V›¯6µ‰pé ÆéèkU}kU Ùàc´€}×&‹gÈ5å4la_^0§Ÿ.ôjùô;#í'Ê:šQ:WêÚ)¨"¾ÎZÄd»;Tz7yF˜*Ÿ;¿‹•kêÝôV#Я~!¥‰ì÷>Š¾ÃÆ•”sމFyê(Ñòé–Ui¡@¦b©ŒÓåxLFXg#ÄmAÚCK¬Èì¬n«ÞŸÜÝ8ùäë<¯ŽÇÚ.VµÐ9?âÌm"Æ”KýÕîmïæn¤ ãš9·üm `BN`núL»p4Õˆ‹»]˜-n²JÎÒ°´[“54À´ÅÜP¾7»nB¸þí »@`±¢} ½¾Z¾ÔJo ‘þ[ò4;•GŠPmP6'Ef Z ¬Dê²MðzMà}æ›ûÈeQªc¬J[â$P,³º&-"Ѿy¡rVO,6Ò@ÅÜø#}I°ÎçþÝzñ^i¶âµzç yQ¥§îE¾¨¥syk´ÒÎ9Æ]<‹‚ᵤ./…~ .‹zŒ`(×DÜ  ™ÖÈú©b`Õ°kÑR©\_U=cÀg.ű\ °ôHmæUõöŽÏ À¯Xí¡Y$L#ôÚe®m,Ã#ˆµLã¤ÇV~]ú Ã0Yþ«CV›íР¾Š÷TpË™¶¯Ex€:,¡JË®¦5U}!’Oœþš«zÅMÏŸœ 1%`ð/ï{f¥ |{s=T§¡‘¿5^ÚÉc.²û‘×ë%DâŒËÝ?ï¸ØººT¾Ø(é \xQ¹ ·,d/$<íg–Y_G„£]^ßoT!<¨£onžbþÀßÊ©¥><ĈÚ5“Ó”óþN‚g’~ÄgS¤y?×öéæ©qPŠW´f`ÍÙl¯e¬ÅÃ%×=¹)-Ó+~*êW*ÙI—!ãš!ñÑ—ûdÂ-œC—p„‹Wg„"Êôö)–’äÿï!ôG©U†‘јïw«ù-€Ÿømcœ|l,ä‰Ñ€ìø>ÒÙuB2¡¹T3Š®Í=̼W;û8¼(í-¸U¥‚XæÊ¥òº´¶ûS™72H—寓(üÿ>„·Ü}…m%aû†IBT¼§ÖwŸ¸# h‰4ìe6w!‚¡ûn_ ½ŽÄæ)zä<*ùiùÄýW°‰º.ÙîcW\Uxqý Õ™Qˆ^„ëg‘ @f_ŒYÁ¢/#ÙÞž®{%’¾%$ ¿M>ùUŒ PÆû„” ”è< §b—€2…9o'²I-âòc8%‹E~‚1*¦¡¬V–áÄ>8j»†õŽvâD½ZIÖuæ(W*äÔ> Dþ@]ªì€K¤Ñ—gÒÝnx¡÷Ñ¢ˆED¼Ì‰Då=t¨æûägŸ_pQð·²tÿ¶ò ºS M2¼{ç×}[µ.>ÒÎ|¯ƒÆC¸ËlítêG .ƒ‰ ¤å90»{À²;§PcP ¿¯˜é¢„]3W.ç-]´¶m‹.^8S–ÿ|ýLù‡Ê&TŒ$­ ia(ÃÁ.¢3‰Àá»*R¸˜ÒÌÖ¨‹ g‰B3ᔂÅC‚ù^@qrìÝOÊÊï ¥çÏÿÒ ë2©rÃ4­hŠgÖk­dV0ÖWaˤ«<l—Øèsn§zû`|‡é¿Ì- Q­è9Îèôpù…³³œ¥Ã<> T¤ìç4g8̉ÜZˆëPî€K1ÿòö¾)7V3#5GîÞêîçËJgÐ1L:|üiõƒo%îû4\Õ >{¶£p»x©æ}ØÜ|8Á±ŽIÀCx›Ä^¢ö{ïÆžïðá+ÝSÛDž)­ßÄ2K76c¼Š¯ž~Ñ 5@@|xp9T(©U‚4ÅiöU‚¤¸ÛOXHïÕ.Rãç3Ryü‘¯ÑÕó²áM*Š®nä”|Êc@Õ}uÄMë†qsãqQæ,çš%«°ðÖ·¤·AÙó ™zá ÐîOÆÍÕ¹£Ë„ú#кJÉz±ó¥Z$ŒÅÛáS¯9Wýf.f&ß:LnK~âWbÐ-ú丬`t$f GáF:ºûÀí ‰áºæ»Lˆ——ëáÚ!‚{íd>Úƒqªúßȼè]*~ꀡ£m6¡ˆô Ö(\€‘"ý¤áu6MŒ·"¬"C $Ö–-aŒFÄ­®©7%J'q boY ŒÖÇSrWË¿ë=É™þ)GbòÜâÐ/w$—tD'¨ã˜Œhùù«ân(™èºŽ$v¢ðz'Kb¹Y~ TöšÈE¿l£,UPâÆ%¯« ù¤»¨|m[»  ÓíWS:;¸ACCf³ÁÅ.lgÿù¶°÷Ë«?&@,g…W Ìóîâjžcºë:…Õ1)Ò:0IÓXõ½òkoM] kk'¦ÏØ/Suo¶í×y{;Ñèþ˜2ÂcbòPã ú:Ð0àp?œf÷ãâ`€IeË¥ HÄÑV›Lü±x8ˆqc0Œ$håUQ°ÅœŸlÇähT`Ù›s§d¢¢vd7ÛW1û¿µd@¬_¸®¼d ÿŒ%(No7•ÓNhû¸¥šéû~Í!c‚OYÂ`ÒSbì¥XK8Ž|,¤<(©Û³ðÃL   w¿h7õ À´Ïˆ cNeï@!ÂËRÓŽ“7î’ïTÓãÒ0w"K¹Û¿f}J€¿Öܰrý2ò,ᇓæÈ#óû»Ù”{Ũ›ˆís²'œWï˜ÄÉ((xm¡}'cáá0ÙÎæ7z|æ5yãi^ ë0BmêábµÓís{> r€Ñ޵Úú–h«çòÔ˳ údä$.—À 쇊hãæþ6UÖ·{Wë. ¯ âD8I,E–³8Þpeã ¥rR%;ëwÓ“ÆËi¬·ìONîg endstream endobj 2681 0 obj << /Length1 2145 /Length2 12651 /Length3 0 /Length 13950 /Filter /FlateDecode >> stream xÚ͹eP\á²6ŠCÐàwwîîî283¸[pw<—àÜ=ÁÝ‚»»ÃG²÷9ûì}¿S÷þ¼5µj­î~»ûi]µj(I•ÕEÌÁ¦@I0È…‘•‰… Ô–òtJÀÎŒ¢`;s;k3 "%¥˜ÐÄÅ 7qòØY\¬Jf.o&œl,,¼ˆ”) èô&5˜z€.&êž@VÉ_BììÂhjâü&‚,­A@Ú71°ƒ§“µ¥•ËÜŒ ,ÀNÀþ =\€ ç7·ÎŒŠ2dMÌlÁîζÖ9@–I  vcZhÀ €)ÐÊÄζøkBCMBU ¥ª¤¡¬FËдº€LìÎ@€™•‰“‰™ ÐÉà|ócbnþÜÒ& €ºðí2Y1½ATsup;ý3*15u )€¸ˆ¢º¨ÉÒPSg(ª¿1ÿJþ€z{Ȁ̭Mþ¨+H¨‹¨ë(K°2ÿÉ€àöæÓúÒÿ‡ê-À¿¢ySµpÛÿu ±rqqàcfvwwg²tuva;Y29ØÑþq neýØÉðvwÚÿ¦ØdþV—·@þøSf€¼µÙ[.ƒÿ De$%ÔÔ߲Ÿ'áŒëÏäâáò7U q‰ÿ‹ôWgÙ_ÞÛ4'ûGÊ1W'§?¡)ü—Èé¿£û¯bˆ‚ßÂÑ·óö5qÿ϶5¹:{ýjÿ{!ÍÞÚÝÚÙÅùÿÌ´Ýë­²Ö ÿ×Êý9ÿÇ¢ˆ¸<€›“Àöv±¼Í°È\ loÿ†ÛñOKˆ[¿ÈìäÉü¿M¿-ìòþ_ÅÖ ó?阻:0k€¬]2âÿTzc!þ‹g t°€ŽomfÅüÇùßyøÃfýÃ~K‹¯·Ø`abç ôµ¶¾Ý½MÜÞ:ÕÉèëý?ÿN!²rÌ­Í\Þ¦ÿm± þµ.²xÿÁ~Cò_¢v"Íß­Fû¶ÒÌÁ ;Ï·îµ@dV»¼õ ÍÿßwÒ –tµ³S|3@ó¿Ôè?›Ø[Ûyþ?þã”ðOhþXù‰µ³¤µÐ\ÙÚÅÌêµúÿÎD@–v@#+Û?˜¶ÝÛp¼-ë?/?"–ÿ½õ½™-èì àâý+¾%ñ?@¿ôd³†Š¦¨”ýÿÖOK€ÌÀæÖ Ë·¶ç˜89™x"²¼5''À›õm~Ì»ÀÌ»¼©\]|ÿÔñO§ð°˜Uÿ°þR¼Üf“ÿ¦XYXÌÀÿAò˜íþ›äà0ƒAÿsp˜€NÖ`ói°r˜ÿ›|›Kfwð_úßCVþ³WþŽË¿rðÏWÈ_ZÍÅ l Ô²6{ÿ# &.NÖz,oýÍúÆûýדÁ¿9 ü×hþmQQ°‡7#'+€‘…ÀÊñÖû¬¬lì¾ÿ¦köÝ÷w¶ÞŠõ_ôŸµ=€fˆ ³`3þ`›/ ¡%~y㥰”¼LGßqµe`ÒÇ[ ñÄs6È€BùŸ2¨òÁòÒ|~)Ÿ@…Ú”ÁØv/¿›’ËÇ®ÌU„7MüüQ%D~~ÕdÒÌP˜(m'£Ý—ýš«SÄ1™ÑœÐü ñó@Œ·µã>†môýâ3™~ióò7X÷‚iÖXNvóï ÚçÇÛ ]^ï±â¢MºE覌sCq~ÊÂ9tu`n;ÞŠ•š ¯õLn @,¶uã»7¥aÄɽâuN«â”›=ì² ˆ݆žYÁ¥f…¦~ #Î'äÜ\ÁB•ÚGsò·IÖî,µ°ÜÉ ˆt|,Øp ‰@Jt£1ö­9RPqÁNÌýæowfµŽâª”5šÀ½ÆœUWù ¶f®Žo«—»Rh«Cs­ú^¯(Œïì‹<æá¤=ÛõÎN*¨R*ìÙäz°Yu§Ž3ZÔ›%/»í%]B‡ßõw¡dØìþܬÞ2«Û¥>Ì8ŠåU b§]>O›_9$dû Ð,Åa°ÊØ(aÞ‘ÈxäXÓ1acbiÖn.y÷}ÚTVÝâ z.]ïø(­rB¡ VŠí–´Š ¯Òmh²–O9åRBc)ÿM&eÂIÑ<­™KŒ4ôr¿]Kÿ¤‰€W"©jˆÌŽ•¢¹Gω÷‰˜Ew׃pŠÄ¤QÂ"§"ã÷¼ t›5<{÷øØ²çè8mÝÞÕ8ì"ÈMôk‚ˆ›E7¦?ÃÓ'­‚’*4L¤Ê¨´‘NB†‹Îx˜ÃSèr«¯æÄŠ+{q5ñÊä1l´¶Žî"YÙߣ~¯«”Ÿ­|osÕˆ_[XÙ‘›Zœ0’Ð#°‰¥pþ­D#>YzáfOq}ꃬ4×áUÆNƒÙZGáˆrÉEÏ_}'Æ„ªÊØßFñ=:^ÍÙ($b£ ¯ðÃÀNºl™‚¾9÷fÞÍ>íLlwhD•Õ &-»/fQIuHy­ —äzc,¡½6×Y©rßÙÉ!{H5ºuê¢?s"a„ÉU~{%¹Å¤®4Á·gò–æ5š¯uäóûÖôU˜ûùú ÓT¶T+ã{%…誰f-SV¨ DüoW=iªÕÔÚÉÒgÃ6cô]¡ñÜùÎI×Fk¥»ªÜÂÃdâq‹O=Yü_E"ït6í%>•eÛÿSŒ2XRPæ‰÷På° ×Þù®vù©–%ë›D.ƒ¥ÙÚ|k$Ò…i„©å&m0ŠÕYù•P…¨„™#Šúâ ö}éÒ"ÀTúûÑ}N“®ˆ¥þ‰“Wóšf°/;gbý‘xŸ.c¬~4FúÎÊ`/M {©”/|Ëšk("çû­ÀÆóÛ–¬žh38æ±AùX%A\³(ˆpYIN„3)Ô×¹¹æc›×Í‘m4·¤™üÙÛâ÷?Ê<>(öÕð—æ…A°ùi4æíßY{‹ü>VNý®Ã¢®gVšM2 ¦‚²¨p#øè VZÞjæ ‰š?6 R>Œ›IxǪ¡iøÚZµ½RZ'±€ä¢my‰9Ìè‹Uz¼4Ñôàâ´k»Æëªï‘+ ×ÏCv1„‚­$/%5— «§ü¨€ÀC?»pÑèXY³ž²1½€’\¨);'ÿÓÞ¹¶”© '(²| ð¡3µK|ÑÆ?È;³±íÓ':³yË98îú†-垌bé,âj@ ”õGx Jr›ƒ x ÖÖ€Ì=[Ó<•oá“qºqM›}•="ÇZ›d.(ºx-J%#y( çwÁÒ-CiC/Ë—†Iº&ÂÖ‚°öSÊy£¿Åiï½H0¨<J±¸ÆÄZ·ª>¸öÅHë³uX8¦øHQì"°U' ö>ð% /z{5y?…tºX ¼1•_tæ~‚¾W¤S`‡XŸó¶: _.hEHønŸWˆ$ßRíì.K’à}(!7ODâ‰"PPSŸáJèÓõ!'–<ýW‹ú)ÂÕYp‡ Â>0û+0Å8!]\Žì¾v ééÑD”¬TpÜV]ðú¦E‰â‘Ùé5ÕYl»’nVL“JèÆ¹E¥œdy!ŸÕí%õdeD¹ôöÓ™]TTâ¤I `®hÌsc’ŒÅâ¤ÈF?{ØuÓ¬Ø.f(…/“)°}v—¿É©J-Ò¬¬2P·¿‰ISæâñûrI›÷XС'4ç%õÉTÉ…"+'Š÷§Xä©ÕÊÅÅ+fy ¼¯HO“@rÿÝĺê r »42Øk­Ö–…È*Ä[˜·XÎÂ-yý­Ž¦®ØWôú,ðÃǯï«ÂЕJü.¿Ämdר^ÁضT>Þ͵הµ+¿{*ÁAvE­œióõÀäxc:'Õ@üû}îU†}è¢ÞÙ®N´0 LJù Èi‚¡$ºòÅJ÷DßiGVˆ·¦ŽŠ(Gb{B¸iþÃ>âwÚ DV—)z›Àžá_iÛG‰Má83Ç=-z‹\øû0ZP¡•Š¿(äÃ̺úÔÁÓ¿KésßmHzoÿ´ã:”%–´TÑ£Náqíµîv§hÔO+ØÒ—ˆ / Q`ƾ-ÿô ¾µA¹Iy¦·^X³#ÕO¯±‰ìÉ­"…R3àañaqœy4}˜:Ððù®pª@tó‚ [O›6m{㘗ØÞŒ,ºé }Baƒ-óço2zyÖ×£˜+þ¤uÐ\Ú{¦‘Åí9œ>¯KËVÚÓÒ\iê‰ýªT2Ô’Ò “x'º_ 7›ë9¸ˆ—ȵõ›DÔ`’ŠEÃ[™Êû‘È 2†Ã=ɪqQ=HH‹Ô·0û ´0‡¦ŽU¥\Ìv7ïnOCdŒ‡WÝÞ½sê«Ö·ȡ«e?þ„ ÷ËˆŠ¼cñÚÒÊÝà2ÕñjwRê  ƒðHm2ë©•%­ì§²þ–¿ßY™ÏîμªìÒA\½‹ÝhäZP¥@d®êÓS„§=wÀðïì‚èž§§õû½ˆcöeîXí6ö+7€ì«Èã±7™† }ùF–e”Àâcgô€ÅŽØ†­ø§[o¼–®“:6ˆ%(,¥©ÐO¡(t5ÏœôƒÐ-ŽF¿á®r7ŒÖN‚\%ïû¬uà ú`ÐÍ£/B.k(º³±'Ä¿øµ~„³e(ÓWíò›.w«Ç/9Y¬lî±ëXÏ¥uŸO¹6q&ŒQüMi¾N†®xw)èz…Ã\gĶC¯cù%’ÌúHk.ypMÌb튼«óF‹S¸·ÎæÞ‡Ž>í%üæ«Øë†UmèHººëÚ 'Ãñ¨†ÄYž q =îRfD¦ð¨vó„¨7„ÏXB@ýއ)¿ÍöÃî†ç" Eé…χâqªÌRS"ŒƒêbSJËýx—ç¦iÃÙŒ'áˆ@¼žíBp• 2Užäø‚6ªy±õ-ÂIÀV3Ò’›«Qy¸d1Ý=‰x¢es¿ûÇÈñâ÷bµ¨8)N÷OkÄ?æ³ ÊH°–»vuyx[ë…†1ü×÷$$Á÷òrXl¥Ò l«Õ.±PÜSÎOð%‹Ðÿ (u†ÿ6äq…%—î×éW&Ú]a RŒ5aê3¯äŽPg/²vÌѽº¤­íÀ÷'Z‹Tål*Ÿ2RÇ-…Þ[Ïñ`Pë'4Y3Ç‚J#¸úOù<‡Î,«»f†ö±u˜ýË®Ùkäo-»¸/¤UoMšfN‰G˜juäBº.`”³T!ÕdԮњ1¨‚:ŒÄ–k3zkF›ýUÖÂ[W7iíʈ@Y éJ;5|7„ôtýÁ_I®÷ë9VûýŠÝ®^гpT|Ðc×2Q^øù‘ÐMÚeöíkSºÛýÓŒÖ/'*ðƒçb/x³CéÛÖZ‰Þ´gvyô•ìi*FD8ü×áÄsÛã{ìs­nëc•š}iz-; Æ7©—{¹ãàÓÈð÷žÄ¡˜Å² 1T± ŠJ1åw¿užå”l²• &voœ–<_ï2-l+q>¿lµuÕRµ¼-®¸‚¼H:ïcŸ}‚Ú $+€%ÎüW$C+ÊTä2ÍéwÔÑæïí*~U:€±ßÇN;þ®è“ýMñŠ€3\4£f0Õ®šˆu¡;Ó+ï–rÛAo…Í^~Ò}æÆÔêY*¥ 5¡hõ´»Þ«:I’ ×&vi…€,ærw̱¼C¸äf,·Â¾{—èÚñ{Ö v¦Ü]ÍQäxÌÅù}(œ*ñOˆqÄÖ4ÇkÆ÷q©‹á!uÙ‡pÞÏörDsîƒ1÷ØÆm ‘YMðŽx9¢‡ª‡Ô W¨ÅâL„€SZYÝ2i>½ì°j_Þ*FœƶB3åh*Õžó Uß]ÎÖ(±¥gáS>Q-bŒ¸ñƒ×&C×¶è(ì†YmôfÑèy'ÊWšç¥ÆÔÕœêBuü|=4˜®sSùˆÉ†ïO@Mö3¥ ïl™@ ú×,f¡ôÕ1!S½0ÎØ€f\ï½a ÒK¾Ðf,)É|jO=V¯vt¬B jTcY?IѤG¦cÒ] už–ª‘Ìu¨Ÿ¡UÑ(‚J¶Ñqªù"“(Þ±{&øöpO³sƒV䤄p=Fɹ&xÍ!ü0ŸÒ³ *ŠÇ[³§÷d°¿IµžžyÔÉ“¾~DW!•g*6OïTÞ…xQÓ¬5ËV‰F<öhË50`ÒÆi‡Û_` ;•<ùíw™¬¸X烣Z¯š8LÊxsïÙ[Ã&܇ãI´ÖôŠëæiW%ƒºxhpW`…‘y6]x”B¶Ï2hi³0j£ª.X;¯Sšð}M"±‰ÿ!¬ÑÒÕ }ØÛæké¤têˆßÝ[V©‚øX %œ'>„þŠ£c,fõ['Y¾äÃ7f_—í£ÏÃðúð >7CŸ ®'y›\iœŒ×ÖP1­oËväRð0†É0…÷“$Óy¡¿ˆ‘%Mq|~ûdׂOwÉÅ{‡4èyÏ­ðªÈæ›{‡³±Õm·Åõ3Œe…XÁðáúÁFŠˆbÌ€=—xÍ.3ÇïT–‰ôÛyµ±+VdÙœ có;ILˆ¤·Šäæi¿ÎžVNäQ™–©J?U‘k ®Ö„OýçHéQUŒ‘æe ©Âú¾<{Š™Ç½˜"’àô Þü!ëïIæ1 ÷°#“cßÌp1D³Œ‰soQŽá¹rñ.”= bîœ}rëþÆX¦ðFÿ•@)*Gï™6d[NÉy ÎŽ>ÓàFh±%e­D%Å{RìT3ß½vµu°ÒÜàg QÕqqbh8¸O’»õ˜ E3 Œ;YL÷ƒôÅ‚Œ?ÔŒFÔŠ~Dñ˜Ú¢0û¦ÉM£¬òJÁ–Tˆ#Ôjåv±döè½³¿®ê&’Á(XLˆÌ/€^Äx Ñ|i•&çW÷BôC,S‰ŠWß+A6{¹ª§&/þ¿I‘Î|›oÓê5×¾¯e„¥Lƒ{‘lo,†ÎÓʇ˜$á§<'gøç1Q8²CŽºÍFÛ9_Ñéss»I’3±"ÂʼxedùMt9PRïmD¨tWضh¾þÂ*:äT1šA{B=û/ÿõý)¾},¤#½Wß à‰ý»†°¢æ¢+h¥{ ¡¢©Y€†¨Šî· CÔ¯Å|R‡3ƶѶ³¥+zZÒ°½\¯…“·lç¹bEŸ=¨ž…SÞ©ázÈÖ\Ôµ††œ—Ãìo6A¥çyµù¬,l–!>ª‘Æ˜Ìøn?zØ¿a_×Pgs0zbñÁnl>–ó·búÏéù”ݲHÁˆÛóa`û®k[bcï=@S„0=í)ÊÀˆ[örrfopG!‘q£·» á!$7˜°^©ÃØ2ÍÍÏ!ó÷Wš5ñ_«^ñàÐ%šXrž– 1ØÎ!'‘åì)CðˆÕÏ/m‚ù¿` àtùLÞñy;¬Ôܹ!õ e‰xò´1#0ã¸~sÅøZLp}Ç)ž¤¬†=?±sæv r#Á ž=§3æË]>J2õf=´dd]üøgPC÷ã=µ—rÎWgȱrgéñ/Yv<iÝ·¨ëF©ùÈù{F.8_2'Í¥Ój­KXψ§I~åpeá›*Žø[> ·XäK!.ùædk”R—cïӚ©‹Ý ((Pû~sí@²–7Áh’ ¬BúñÅ#Xª]%’ûJ]êðxÅ;¢ô’#˜pVññrã&Ù/‘˜XM§$Â…ç&ºÈð™¡Â_ž.æóÛë­66¶D¡unVë‹ÇìsuÌlEî–í¹ ßêX,C??äœ2Žßz¯qyÝå,ßßqMˆãŠi~`øÎÄFåƒ0‘˜7{˧'y]×Lu´“­Í•1[éi¬ &¯வV02¥-~ìM—%ùÓ:ý Ÿ \÷B=#‚¶’ ÇË ä,î7õ¤SŒÓ"+9w»9ÒžýÏ*khÄμäÓùŸ=]®ø[àÀ´ Š–qLB6iFa2]¢L‡Æ«›ø„´ÖôYüJVqÍmv{¦¥ {éÊÉÊA¦^è§oÈAVÒ|æØIyÙ’Š’üÞœeüQ–¼Ò\k”aC,ª´é§²!ˆqôÙÝ»Nnaï%ŸỎ¾JüzUÁÊ•Á†i‹Ò%íÏ\V¿ì«Œ˜•R_8Ci¬;7UíB^Ô<ÝAg§ãļÅJ%/S¦ß_6~¦þ¤×_ÊYš+!}Ì/ÚÖGîEƒ´§BKTª] =+ŽjrËÀ–f5ç0gØ­û9!޼·.ìVÀc¡/"ž¾ÎÐB°vPŠ˜å[5l£lÒÚž©}´ë s­Ku) Ùˆë È)%Wýåõ4Kú°œtæž”·íœøHY°]½uëL…àƒL¬Òo¶TDOgåÙmT´Š³ßæÕæòqù®žVՉׯOï1¸X1©ìÓLè»l(k³ $„ýöñç;Á刵ÏGS³7×G$:'d~J6œt{õ.avëcë:äPö|B0®žÏ4-¯Ñ}LMáK¦êcspÁïæ:!1’¤8½ÎX¾!¶°")Xb"îÂò1yŸ‹‹~+ÇÖÔÑ!!]†‘Ì•áÖ§ÿµé–¼«þ¸ümCPªõbÈ&S{›WyIg‹ÞXx#2Ê~¥^s’‘¿Þ“-Vva¦GJ5ë§q\LÊjóÄ7ejÏžÕ¤_E!+ÙÍ|ñÕ}b7äÑã PcF§û£×/Êk‰Äè½lÃokÀº®DÍwt2Ìš¶ ¢ºtÀN_¥Ö–¸&¹5ƒWú8áû(† Gù‘übF*×þ\΢éÁ*lö[v]Û¾Ó5Å!pí·Ù}šš xÔœµV¢27w®«5¥[$°uµèX¯4^Ó:Ò5dFAmÒª`Í€›BïoŒ.V"g»˜Ð¼WÎh§íëžš€Gï F&i]¾º»…dž{v›ÈÜ(QÀ*!Ô¡TTœx}ÇŸ4ÅcŒ—ÌúáëÊ7Œ¸ÖÌ Q¹Zé’ŨÂ}–Ç™T¯éÿÌ;,Ü®ØéÒèçÛœâ÷K”ƒñN†'…:©SÈ$%&ÅWwŠp.yD÷1gfS×-¯ÙÛ˜'Ì)7'z™î•CÅâ‡B€ìh«‘žtoªTéÑ™¹_Œrƒu¡˜Å‹zjÝË5yü“Ùzín mÉ0£1 ™¿ç•“¸ë@”[¯QSÝ;pÂRêÅàsˆfo˜Ñ–fQ:)·Ä“÷€G­›(Q‚!UÊ&¢÷|LÑgÚ&‡4¹,Ÿù·/ÚšV¥…i¯Ô U3èPÌGÒÔçSzÃʱžÓ¶-Î9ø#\9Üêgˆöé?ص…é I㼺µñàäLÖß?ÿˆ)¸ $â.&ìó„˜vÃÓÍÂë Ñ—éh†ø†øë•#­¥³´?мæ]D :MS±ÏF|"Ð1µª!òºAŠDlžñ䛓¤fC8¦t¾ep{ÆêDiÔ:èˆ"[Ú;i6õ*BÃ5ä nùƉÏ*´V5õ¥£•äï¡ð«ÇøHÞ-XnѪë[²ŠØ¢fÐä@;Œ eŸØÚ røõ\qÑö´™È&I±jY~h³ÛÌ2–H/š iEo€8ñÍÛvÎhB½3Ïk¿yðýÚÜDDM!†ÄOÏL n“¨üüÍ©T_PƒÕI§Õ’±Wó„Ùîh8ªð‘Ùû«‚ò—‡ËYV·æsí¨QiÝ ‚øW24;Z–"•¤½ NÙžIÓÓóôdüX°Å‘†Iš§ †•ªÆšy–fA?aõª™i…PÔ¨Ó:;ÄæÙïÄ–|…ìÓ/:Ñ HÌ‚T.?W’2Ê~•úJ{ÜýànMý,‡Äì’²ÙÿMmP„G‘80’™ é Íã¸ìz»Æô‹—>üiÐ6$vB˜º»ëçJvÄà‚×õ«]¾ª¬!7tú¬dÄŒd%¾¥Qøkyµ¾!jc;s%`î×s´j‘B”EéR EŒ ZVá(Î%ч>9æØN<0®£#5Xh–໸êɇ¬n Éóp^*„×™5ÿaêW´¯’ŽIèmE%x™BÏ=Yy³ê©¬f|ŽÅìÆ,JÓ¸z­Ê—ðŽï ˆæ×w›cÕ)Ç‹ÓnHÊ Z‘wr`ó‹8ýNÔeÈ-w´86Ûû’Ä~b«àå¯(Ý Sb;¶F‚s7¨›Ø¾¥üB=-Þü"ÞÍjð«Óµ3¿„r9-¸«eÝM Ú•UÀŒœÃP,ï³õe?þQÐKdyŽk##XNgÛj@ÒÐ~$‰ïÉG‰;^lðäHçHRxÁÑ×µS"¢ºãÚ%e3a<¡÷ ‘ ¡ôžRd ^èç']ú 1?& üŒÌ2•>òщÐ!Ò°®Vû)/ZÒ])’'I½á³fµÇ˜Ù¾F'X02¦guT_ž½ 5–5šÈZqõúO¸µ]•fŸ…ñ³bC­}PGã+ÁþÙfs"FÏÑ<àÅ{‘»˜ÜKQ¯JùÆüpÀ¥JPn)þŽTé©ÆÎ ªë ]!a‡‘©Ž¡&¯ë!Ä! ŒëÀ Í:Ú‹ÝIù-¤\a+-¹óùfÓ¾Hn™ï@€ ë°ýn?mM&R‡¶IŒ–ëAV“-+ûæ¶AÐFx^VuXölžúë™´5ª÷Uûg-ö@ýUYGKñ©‰,5c…d†xòm‹kCÍþÍžU ·ãA8jc`±žv3€½~ÕN…`ÜWð¸µïò2§¹½áR_‰ö‚Âä4ž°îBH äÚÒìDLlž\a²öìK‚¼›bÔuô§L%®:/å>ô{‡NþÃs%ñÌÊ®2Mhy ]P?=MþÖÄã ¹ˆ[ [=l˜ôf•ÒXP‘Tƒ½9ÎEÄ °9½´†àÂ3ƳÙ*òQ½ }—âÀÎ(l„»ö8Íøò0ËØ1bFÏÕ³8¥v|y/Ÿø.@¢Ï©¸¢ï9N5úUÏ£ ‘>ÙæVù¶[ )í5ªï#Δtx>I4+Båô1ÅB6Áôîpq=z!ËV¤J¯¼ºæ˜êQª D_ .þi®ˆãÔ6Bƒ¯Uó9RŠN)«!‘™&^Ë˾ðh†÷ŒjÓNI¸ÏTÏÐü“ŠS@Y¥’]ÁÑ5Ük·»>å’ñwÍšÐÿF+ Æ3¬}Mo@ÅëeŠÎþýgSQwYÔ/‘“ñê©Ä>iáÚ±ü¿‹9òªn${#»ðqüc ÇŸXTßSE&߆mîRmðÓ 5/¸ÑÔûl{£T‚ÖmlO9á)àEÂ¥n9cOŠ„g„q·Œ­(çY ,ì\—¦òPÅÒ †iÁ4ã;w"ö&J4ÔFøÀÖ Fsƒõ¼~ºã­9ž4wFaÁÝŒ«)4]@¢Géà3/ÆZ\NËÖƒø®UÈ×ô®¶¦U¦ô«1P£íëdšÝQ«}ó艰SV™;št”8L½Vü­N¨n ÃVc‘ƒéÆÍÝŽj?Q&®ž„K”—/–ɪ֩º_øs”¥^Öl¬w®!¼Bs¶%{¥Ù':ùªZ=ªe®É­Ïg.µe¿­6­ _Z[çŽÃ!ÌŸV¤hLòÍgfÙŽgi d|FŠ]4©»#dÙTÞÉ4d¥RÿžðX|ò*­?»o@™þK“½%)ÛX M ‡¦ÉHK‹ëÌ»_™’)þ³Ø]‚”>•jj.f3Ïò#ôp¾þ „®M6—g¦ot`7™^™Á×ÚOÎÖla¯¼R¸§ÓÁЛÖÙÊ-êÔ"Üe;‡n¨ª‘‘>Õ»±ÑmFÉÀ/”y×Oçë!Gût§B‹v!ˆr—û¡±§ý`ñ˜Ê")Uglòz}F¢‰AfÙ®tçF'°^‘ø<Êõ}Dz¶X8#î>~Y* Œn(«Ó)ä4^âŸ|:wšÊ:¬rçqò–g-ѪìS‡v;SŽ‹^DpMâà …YlæÍ%‚› –Y® Ññ…ÀökòæÜÅ2…f˜fJºnÑuá9xVw×OŽuJÔå–Ìå…Šð'‹ ïEÛQªX Êa·¢XTÓ”Ô˜£ôô|³)ï{»ÝÂk^¯u¡¯Å…/õ󑹦Ðrùö†îUMد›!ö-Nê¦îÛF¨¶Ó„ß©ãÖEÎ¥¥;{íH³³Gš¿+¨¢vh¹Ày,³”zA6bezêr•“qßF ì8¤§7*ëÆzŒòHçÔêIvÄצÌ{ü2zÛ´}£V.4gãÐW«K¿=Éì )[]“:‹fNYyö[Ïœ&íGh¥l¸ñ ÞI›Ó~Ó•Íù;÷_ÿÍåÜ{ vBÕï(ýb>ÉÄ>Ã5é\ÂSQnZ9*÷?tàƒ½¿Ï0õNäô=¡”"]²þ‘‹É»ú¹š8ß©¢§ (¼/#Ì3Ø‹eŸ-ŒÈp ci®K“ö°÷,yE4ù˜AؾÚ5"}Ôþº–73…žÒ“ÛœG¤þÜV&ýtøvƒñàÙ4>¥žõI¡òÏ÷^gûËsèÐJægÆU›Ðd9þkÖ_ÃíäD®$Dþ¢‘YœÜ0*C÷[„éô|'éÊ;oŽñó1›ò3¸ /Cr½ìC™ê§ƒQ£FôåèêŸÉW'é_â²¢¡ø£v° ÛîËè`…ÄèXe~4ãDç‡ý$Ú±×ù9„Z™Ñrm8Œ³3HŽe6˜:*ƒ57O¤©%ÉM£»ošÍŒj%ÊñˆBKÎHbÜ3 ·+{hÂþ©ð÷~Õ¾ª†šÕ™ød“[—)Ð…»ƒ©Zq[:‡Scá9^(®,wKTÙÝåÜ&š¿+å’;•»MëbREÃÆôÄ Ê­Ô"› k›”À¸eùž§Üs܉xû”~/³³EõÄ~I«J0âæ(¬ð~ƒÆ1¾¦ G‘YÃ5ij<›”@ªëS>¾iâÙF&¤‘U{ÁIþÏ™/ƒeîc™ƒ%H&?;/`'}f\ª"ù“˜kàÑXЬ¡Òcæ’Èí †kv½×P[‡Æbñ.Þ(sˆ¢¾6“vQòð8ëþVÜ•ÝA5’VD°"jº|0ú´R¦ÚÈ÷F?#¤ëýX–;Éj@Ç:ÕáËgq4<%·c_f+TOl¨.µ¡E2ßã„é3w3Ô„O/6÷¶F\ÅÇSØ÷ k‹eÀ•Ù`´Ä&Œïä]¥Ï š±s²[|n†ÐG[{Ä÷2 A±’ `L{`ÿ¥Ø:Dg¬ºkF—x¤0.’,Äþ‰Ê q:õ4Š/ƒækº!\2ËòÜñäOôeˆe‰ 0ýÔñÊŠ×Fnôy.š·s ïì±ÔíØˆÅ0eÐTJlöÚôoÒì^¼-ÃàaŒz×'6ü(ƯÜ':Z/ ކ?FH¡Úбq$‹¦]gÁ$œW¶^E}XÞÿèá̉±×l$»>#t‹ÒL|tŒ•‡£P\ÎÄP@%}ÉwFõù—úÕÏøR4% $“çgË÷í7'ÔÊKò ¬Ve©Ï&†ÇŠãWÐm±ÈüˆbvY„ë÷î.1$ˆ)„·rn2º%yÄMeÙ´°µ=%8$VO,‘#X³ëH½…8U=»*p°Ô@™NØõ>crPóÄÙiºÇùÝùwDýȃžÓËO5Œ,‡ë´µI<…ml£+Š‘*Ý´SïÞï÷ü¾7^ã>²BoS¦4C0AnË·áø·ž –à9´Ö‹9ÃÊéäcãAºT^ït°ä-ZßµÂ&£æäM« 0 <8»¯,é »â÷~Ñ|&|ôú,t©¥ýb°À™Å±g¶ßŒ4Ë;’—A;waó~Ç£qL9®Ñî‹Þ¯Ð5èBTG1bÈóaº¤¿8Óq]j5üª~YÓ¬D´ò¼VÄY–óu¬ò—° 2#Ê“ßìNåB–Ø«/P”I«*¬êkî<¹›Y6C¢_ 8ãÍ‚±?ÅÈ~{¬äâH¥vÄQyO(“Þ{TÏ‹$]‚¡¥à뮩_8óf­Þ“¡«U|bH@þ®CvSY-ý´ñôû‰·–íSrLÀÙÅ»`é–›vl†+AüøxãçèüU'o¡”)óAž:2I¼X ƒêj%ïk##€'raasè$†棧Q¯ÕTfãå–õý„ÈS.nʶ|'Æ*RC¨Xš1Îgjs$ÙfÉ’~¾îͰ‰ÚªO"+ú¿ÅYk¹ŒmýèìA±FµW7E¼ž]/\xÌ;¯Q0H‘Ä:-,UQAÍ"…e{þëgj½×ŠÙ&LQ~ ’emfÁY¬ÀŠ OXDCð¿X ŒP#1‹3ÏI±›˜`_Ói}+Ðâ]‘ÑÊS´})K½¸)SLÇÌÚÊ8Cè— âú¨ìãÁ>«ý„ß.Œã”s õÒ‰æïßs$°U*›×«‘–*Q’ŽžëºƒŽ¿E èBË7Cx&Ëê,ó×Ì=~²2ª¿' ƒöW)_õjˆpâµ,dQ±H2ÉíW7|2) ´ì»ëN\}iÈ ;·îHIÖaWÈâ–Í$´Ë~înkð:ëeÁµÃÈÛ™z—,ùÐ  +2 B½­¢aTœ òPÛõsu®ç ØItÕW–Ú£6èðéíp Å?´æ0錗‰,‚ÛŽí¢E㵌°DÅ'L»œšaõÎD¢:&®e7dyÀ Û`ÌìÕs·Ô¾$½ìðÚZ©Îµ>´'ä³î†–ˆàtó{¾4Lw·:+T'z 8Û*ïÕ_C¡1¶.+˜¶’BL&úÍl#@7$ÿé u÷ endstream endobj 2683 0 obj << /Length1 2488 /Length2 19072 /Length3 0 /Length 20466 /Filter /FlateDecode >> stream xÚÌúePœÛ¶ w œ‚»»»»k» ,¸{pww î îÜ‚ëí¬}Î^ëìoW}÷ç-ê­îgÌ9Æx†Ì1ß®‚‚TYAÄÌÁ$é`ïÊÀÂÈÌ PiKy9ƒ¤AÎ. ª 7[ 3€•‘™™‘‚BÌtµr°º‚xlÌ®–%SW°>x 33"@ dr¯šL¼ W º—#ˆ@ ü (;¸¸2˜]ÀË { +{ XEÌÁÑËÙÊÂÒõ .†?†æÎ˜þP€<]Aö.`·.ŒŠ2d¦6.6V ½@–Q èàZ¨ì& K ­9ÀÁü/jªj)U% e5F€¦ÈÕhrL-Î@SW³ Àö43ûoi =@Ý~€ö–Œ`ŠjnŽŽÎÿ•˜šº†=@\DQ]Ò¤Hi¨©ÓÕÁ¿VþÈØ›Yÿ¨+H¨‹¨ë(K°0ýÉ€àöiõ‡é„C ðw4`Usg»¿¨-]]y™˜<<<-Ü\\œ-miþ8P·´Çààl:ƒlA¥ØÍÞ \Wp øSc€¼•)8— ¿‚þZTQ”‘”PSgg‹áOÂþ*>£«§ë_¡¨Jˆˆ+Hü—Õ?ô¬lA.Uë%3p‰­l]Á®þ%°×ÌìÒõß1ƒËâú‡®í¿˜\@ °¡ÿ“9˜³ Óÿluaúƒ¤’¢:ƒ¼Œ˜„¢šÄ_$œÿ6àêfñG÷ÿ•âÿIœ%Ðå/ÊòÊÊò; •=¸ç€ö¦`~®@W7Ù_2ð2#ûWÊA17gç?¡)üï’ó¿£ûßbˆ:€ÃÑ·õözügÛíÝ\>ý£Úÿ·¦àv·rquù—EÐÿdÚ,WÖÊþÿoåþìÿcQD\žÀÅÁ `?Ìà3,ao&æ`gæí‚ø§%Ä­Àrupöbú¯G߯ÞÁÃÞû¿¯™[Ù›ýI4ÀÌÍ‘IÃÞÊÉ $#þ?`âß2 +€rŸeSK¦?nÿ: Ä,Äà„øz;:8̶. _+søÑÛèîQg7¯÷?þ/Bdá˜Y™º‚Ï=x¤ þe]ÆÞÜÀó/1˜Éÿ.ýORÿ5ÏhÀÃÌÌÁÞÖ Ü·æˆLŠ®àn¡þÿú4úÖ’n¶¶Š`Ôÿ­@ÿ¹hgeëõÿ³û?viþDOýßMX¹HZy‚Ì”­\M-ÿU«Ée\à³&boa ×ù/‘ÆŸéc >à¡oõçÒ0°°rýǸßMmìA..Ž©À)üÖàrþá `ÒTÓU“’§û¯­ø×V {S3+{ p¯s€ÎÎ@/Dfp±rp¼YÀ‡Æ äùW˜í\Á*G7Wß?åEüÓ$œ\&±?¢!n“øßˆÀ$ñoÄFJÿFܬ&Õ¿€IíoÄ`Rÿ=hýñ€ðoögò7{0ý7baf0™ý²˜@ÿ€`æÿ†`æVîÿ\“°ü7dç#/GKý?v€eVÿ€`f6ÿ€`j¶ÿ€`nvC0·˜bssøssü;`nà‰àòW?ü½ÌÏùLÆåÀäúææöææþææñ7d“ñú þߦRþ3±ÿAÌwÙÿ\Îa5Wg–•øç[€®ÎVžzÌàùÁ–ƒÿþ÷›Áÿq@ñ÷èû‡¶¨¨ƒ§7+€Ü,làRƒçöý?º¦ÿºUþš]àãð¿øÏ@€@ž SÄ¥yS¾ 딦ÒÏùSe0<Œ'8‚Ú²qÐKéS¸â9Ûd ¡‚/-þß( ä¥y >'}±/Ò¦¶}]oM¬œ¼6SÞ~VøL€*!2–­É¨ðMaÑ¿¬‹ŒæP6;O§˜}æ[[\1@cìHŒ§ãûCë·÷WÉdúem«¹0…³,ÍXζž‹èø‹S®oX1‘À^‘%ÚŸÆy!8c²°Ž=ß1÷¦œîÄ*–¯>}`ú@Žè—Àd=²XNÆv¾*1›èDøç}Nèö/gABÖ?Ín¼˜¦FžU÷¼¦­6NJBÞPÕ·MŠÆaRü[*øW¯³b–Ý¥ ;kÏ캙ª"‡˜q·¶w² ¤Ï–±œ’ ¬]ŸöPfÄ%NËn[µž$?ñ*Œ@%/Sq-°tU£oØ>÷*XB™Ç6´EãQ‚Ü”/”¿Ååx=í²EdêmÎTžÖî6M¨ûq`›£÷B(Ò>7=dg"·ùþí¥ÕlÃM< El£ON4ú ªE¨ÌçÈV;¯”)bZÓÓbˆD èšÜOx¡VÐ!Õ#'—æ×AxcªÍÊ‹'›§hÎZåíü\aºš*ÑÕša¯Ï4¨2 ûv5íšj0ïCñá’n\¿É¨(ýê1ËÙ™‡°»äBöQ!4”°mx¼~3½(J òýpĺÝ355è.(ô)ÜÕRápX_O¢¶˜"öñŠÇÝ$ú>ÓÙÈø»#$Ú’1A&ñˆYz°L•€â©Nßv^ Ä,&<œØHRèW£e­5åÕÒÇ1¨z»r¶{sÂbø2°¾qôܹ©Oä·èÅ7x(‘p¹‡mV žÀ2¸îù'0ƒ‚æO¼”Ÿà¿ééŸz#}k =9¬€ÆM:ÑùBÂÎnì°,¡mV¯ç±@|8þ›ÞÛ¢%wzô,Ÿ6àJ£¨+ƒýTò»È}¶ò¾óÂ! é©lùèæ‚tŒµÜ1ƒ\õ‡@¤…¦“»_½þ¨ÐÊÎ"^o×oZá¹X²C¤ÉY1"7é×^ßF8•_‡—úˆi-/ü ô§¢¼8¸ïÞýbz^^tCއÓWÍÊÛVIó$µŒó8$à©wPé•À=N|{Ò…1¨Îâ ›¯ÀH¤2ŠL)@øùÈ·¹iL÷ ÀÞÖO(_ÌO>AC¢!#·â”Y© &J¼‹ý3ëç¡ÀÚç3Áhõ° É‹bc•‹«øIc7§T†=«nw„Þ4HÏmå±üª.5ÜwüGij(°ÎáûÐ$þôgWáÁaSuèÔ‰ ¯czdºcûLŸ|“ß_·ß¢{Ô£.Æ¿Fy ¯£ùÂTõEoòt"w—×FØf÷~¸ëê“Oˆä„Ó%¼S®˜p–އ[&Z4q.Wö¡×/c¢ÕÛ¤30Þãü¹ÜüÝl+tÜœD<ÏNèDôUG¬D¡½W&œEëç^¢k¨ÖÁ&MýWª¯VíöL÷x¤¶°?sÞñÞè.÷”ZÆEv\™É3òr‰]ZnìÁ\”iŸ\,hö pEÊ¡ïå»jÑ>× ‰¤Ft›0—ù¹,A:W#XY–»ý¾<®G2X3€œ f Ÿïoê› àIX]iGÀ`bßÁ} “<9Øøt ­çÒ|ÔÈ¡Éñˆ…|î×ʨlÿžr9â(ðÙnÞºC¸qhÆÐ¬9Ï¡?ö}~²4`úDôŠkÞÞ•~ƒÑU%šßÇ%ïjã´Ö<¤e¬¡º$w9M-Á£ZøÈ¨ŠøÄøBj×pN‡{wÖCpë;Á°ÛiEõÌ01¬ÎÆ –ƒw|kuÿô ÙŠšº °Z’2ïÀ7:?q‡2ÏõºJׇe|•*ŠŽWjŠÐ£èë]DQ(öÌ=æŸ#|oâÎ¥?»p©ÅUAˆ#Wh4T䇮ÈÇí]²Î蜦¯4<¾áT¢Ì­ö¦dýóäįèNY±~'×Þ0ΉÚiÈ^˜¢v'6ú0NÌ?¯~»òË ‡÷¥y›ïHcáþäÍ…™œ‡¸ï`Æ€á}8ÎwÀ[Q\Ø{e1!ÞeÈMG"Ì*¥ (EcÞŠÐÁícö{EÐÕ­dâ|…X¡Pt[#Ë0õ¶Ã¾”—ƒN¯Eñ£|…m›žÉ€Ñõwx3?!nq’NZÆOÇYÃ,ÖhýŠ!…9ádÊUl Ê+ïâ[rŸÕÎû«âe€9“øþÓB9Oò»¾(ò.Ú£ç9)Æ‚rÈ‹ŸòHtƒñÍV¤¼“«qÆ:UA=!máPE”™Þu˜ÎâkÂ: çD¶õ—§*ƒ‰CÙB¿+2Ÿ,+Q€¨¬ƒ<©çO‹íì3¢üÝ®[ÅHjé‰Ä¨£ëÊql §sæ~Î~ÈÍpåãu:~‡BAf®a82ä‹T)ù„‚rìã–×hÈ _ËQ „Ö³â%yÉM>möôÉÚÔj1싈÷¦Ô&èò*†|y¶ ‘â ïÆRÂ33[;÷Üôº¡±ë‰]Bx, ÞüÆ' 'ç±ÜdŒâMùV&iøh¿ÒLÁ=…µ>¶9§iiúd÷)ô†¾¹Taµú÷iÙªA¸ºxA­[ür3ç ®ïÚ@ü‰¿ˆ’‹5Ÿ|ž°–Í:ÐÎ_ý”µÀ°K¯ ·QÏÐü™(oû±6 m¿$ 5­fܰ44/QÞoÐ@­1öV0³J"–c˜š>7íúòk¢ò;ÎYÌ )׎³j}ôGYË·œŠŽ[®™Lš£XR g_œ·J=‚)ïí …V̳ýK×­~5¤õÚT]µ•䇉KbÐdâY®?øÝ‰¶°3!FSt?|ñûÅ;âšzb•‚UJõ¤éß]£{dÓæ·…;HŽSEUï±>¾:žÖ)tP óWxglÓ¡—6¼z̼Oó¬Ì«â˱ÍÖ0!¨7©—@u¶v؇<ƒ#¸·R僻®öCeÖ“í~"saŸ‚©Ë§š¡Ûš£õŒ_wkRνýò¸ŒŽ>cþp&óòp] 奈ã@﬈¦D÷s2Ò¡ôΊˆá„fÖ‰ÍÎ>ÑRª·{.¥^·Ï,M£5_.6Ò7àÔ‘Ã̧ÛAï²ü¹ŒÒ¼êÔô(‘—ª5 îðáa´'‡½úÈ¢kîØFÎ0ÛMâØ–%¡½PS골DRžíÉß-˜8È™ÊÕß ù=ô$½P,Æáî *è. Ù>G%øö ßËÿªŒnئ÷:˜tUBüÊÑ÷ÑM™'šÖøG>îvÓ“äžœ7åŽÑ¡£©w#Yò>ò›>^‚¨©çGVæ=î#jÒ¼¤ïPÞ>P°Y¾¬T ëûüd?óŠñðw ÞÃ^Ýò}N†¹t˜  ‡º|#«§{ÆKÁê3IÂ,t"ªFBÐ^y7¶©6›«˜viÂDQYHE‘¨=h­Ù¬ÈY¼‰æ?Îèè&´¯SŠX°ºOò#CÞ¸lÓ}ÓŒC–iÕú€òúqÐëÍ í䂦ÎzS~…Z:êhJÀ„jú †Ä{3=…°|KÏYΤÝH ¼ó—ÈLc­–¦3$WÙi[9¿‹Ud²› ’lï¶yÛé3ßúýµ ­—Ø‹Àêz9*)?`\PÙe¤^ÚÉïSá¿MV“‘òfQ“-·$®7´”÷ÐÐ¥ë¾üûÚ®OªœM}ìÝšœ“òT²_à–`{9›v°HÕ ÊÁ·Æi~ǧßêæ+ûMwõ±Ã;Vý‘YáÍóѪ¾¯ƒ#¶±xô´®ã<×–[Uª‘n”Œ·MH‹DTމölBØíµŒÅ'¹……UÉ^ò˶‘}U–dÜ‹Ð"Á_´ßÛ¯òW»ÄùÖJÿÞ)!%ÚxÖðyé–\J[jéæˆ< -ÉnEEJ[õ{¼ô£ûùˆPÅ0_ºí´ÁÐÁÀ5áÍñìðóh¹ôšM¼–*urÛ t)Î…ï781ósiÍ@¨ÅF»c~÷6ÍA:cü¬ ‘uðŒ‘}£c§^çøèƒ‹ÂÿK罂ö@de 9…uÖgáߦ¸š&gÛ˜'!N¤¸Ù*5…xm ’}Ñ‘Ûg¢± ôsLKûbþ‹EÞ%®ÈB5Øá©Dç¸ ´8Ô‰H;1h< îÎ ö'è÷rÄÖõO=^R4 v›´^"ä¦oxêЊW6—êè±/[É;Ÿlp'0 _¨ÑgÁÕÅÊË\­É³<[jDä 'Fs•pìÞV+†v3¿Û Ó66w߯8}ÅøéºTµpQ¢kOí—q1î ‹Ûf0Q)™p½åb"?\GÜ>óªÐgT*Q‹°I725ä>péiA¾KZ*f;åãßVóåpÖüÃN2eFì[ž®ŠŠÀvICÚPv´rÍg S¯S ßsåžUI‘í(Œ,utÉë~ÓJ6zÞ9ü‚ôæ›<Öu­™Iïx]€ôM$‹bCeRddÉ©™—ˆs`v¿lÝõåQG•3óÈAŠbKý/¹dÝÊ4§‡×»ˆEóa|©Æf‚>GÏx´âÄ9·zrËÇçŽx;MãC›‘f]M…™ c¿kM–Ÿ˜ƒr².~z˜µ1„·¢®7웦ñÄêétã{ŠøéêD…+ŸçêèHt¹OBt¸FÊäDÙ䊎}r¥43ÊúÀ­·œŠõ´+å€UÍ Ÿ­ûqä1)ŸR(tò±3cþéz˜¥~íOýIZ(ýñøoj‹Ä#›•KÂM¤æO>òðzQhèûÊnÚ†oì:7á¬ìNä>4}ˆÐyØ£4ðМ~)H¨’ª¡BžÎ¸·îóhsšHŸŠØFRê_Bø¦_4;UõáN[c„ÍËŒŒ·š‰øg%Ï>DŒ—?/+•)`M ZÔ|¼U|•-Öyšƒ¶¼%e؇jÊêNU¦üV64Š-õÞ•Ì+< Z(Ãî9¶ð;“‚ž¤óg¬çRÔhè'ž)¥–2é0ùhé¡àq¦†@9‚=vé9³ßøÞ#úçÎ;¸Ú\é{ºoåÀ*žT2$íœÌÀQÞ™ü¹ŒÓQ~Xã `ÅÛ¾¢Äïý¿‡ö")™: èöv¡åFëssöCܲ*´ŸC.H…ì¨b—nɇ¹Ô’ùK ÃÄ¡ {FÐä%Tï±2~Cñ,*ÅäB&í# 9Êd–¶oA— »#Ðá¤Õ æÚzâØËù­èͥ봿«6–á`ERÏF`2k/¤“6Þ!3}™/õúFÞˆO„Œõ[óõ²‹¤8”ÍðÂÌWjêPÄæõch÷€ÍH3El¼]óìî˜_§ÔõC%[àpyâÉr¿$NÍóW¹q26ç–«§éhBË"†÷73“áÔü‚Dj)i¹Üdž³¼À¥G8)ý5#n=n¯šÓ’ÆÄŒ4EÑy(Χ§†Ú:Jd·è1Â&ÇÚÞ7nX~¤Þ&‚\©­LKUm¯®xîïM—9’ù¿kWd¬ï“j²,U°”“ÚœˆKƒ´¦‡.’)ßó.—IC>¤-ð¼A2Uã ¯ê‹S5øÕv«¶-I4ð%i8õ^ژLjüH´ä3Ì'Ί@ ­`8匆ŸCÝyR£Ëæ;B=hR+Æ­Ï{Û¬û9ý»ÉʤxP+s¤ð"zfªCìå)ëÿÁPP®†‡Ü1í ?Î;< i¦)º¨GýŽa–0/%Þ%™h-»»‘ÿîˆþÇ·Ô-nk9ÒÍèÉŒZ ¤@²4óïÑÃé/Œ Ø{l:ØÓ¯±ÓÕ¤Ú±êŸëhIê(Õ5Œ"KðSŸXØ´èL×¼åa³q ¶q5ä>©¬ Ýà´v~»Ký­¬óô½“=Åá¾1AÝ¥ÝÑø±Ç¨Òxê"VÐýâ‘—~2göÚÒ£œŸò)¡ˆÁà5ç²w uwS×ý$ã´È§Ó^ åæBŽ,n GK ·~ޏ¼4Zoóï=”#,‰¥Ý±Éw¤AÙô&ìujùv›5°!5ßw®+ýdªš-XÎ(,%©Vc³NNá03· gÀ^Éâfiå4öx6³ZWÓr®D슲íîÉGBjŒz”åpGÔÝF ˆh°þ¸ƒã‚û¥V¥áÄĨo€Ún¦·-ú¥³çÁÛl ðª2ýqgÂN4X˜6ú¤“2Wì X€<­S‰aàíG(ª.)u[©7“]Aç2Au)OÎ'^¤ïÏ < ™ñÄE1_ò9ldÚí6Z7¢,éÆSÉcLiŠàwp²ÎÅ¡¿½_€Tެ[5Ð6÷LËü~›7¥'d¡—#Q²˜>á@DtÛUóRÇ’§€!t|[Ï<#SÁ¢¥fIðÌ S†eˆ†¥P-±ŒnÞ‰‹íþõõ:J2öÅ«í¨FRïËRÆO,¦kƒs^&Ý€ 2¦R\Ö%")“H̳õÿò6t]7¨…ÞÖ5L´íäðÏàºÇ·Y¹8{~ç aéÕ3ªÈåëáõ‰uצ„ i­T·“{sÜÍöiÉ3ç®Å»"ƒ«wŽN6?O«w½Õ2 €@±h”ÇÎ£ÐÆm£ÝÃ>å?ñsqm'/Ê{©}ÀA€øü ¼~¦#oB/Âô»»ù÷N/›ÈÖ¤ÁƒÌ\=>E÷X¸¡Öo¯ÜL¥6hÏb »Œ&¹=®wÓ“t‡„î ÷û‹—;ë“ÅPì$ ÚŸ,´¶Uƒøó¾i´§MªÀ™~Ь}² ®€sËpÂòƒÚí·Â®¢)D8Ÿ^¬ăà[ùñH%„¦â+Û@*а…=÷ºÃÉ/”N ‹ÝwlÃÝámJ(/õ5õʺ«rà¸7½ƒB‡o¦Ð£ÖÊÍÛૼÄì|Wô(üÜcYùÑaüI^Ïœ¿!”7ð;B¼6|þpÇžèÞQµ±äö^úmÌ Û>ôvò¡w3ûôÇc¨»26¦®eC„ÔÞùV¦Þ¥ñ溌$vÍãI„=Ó/܃Æ[WÂ\en+Àcšr“¯ Õ Ž¡˜kwÛÕ9¤EÇA¿¦‚ÔË^¿,®n}ÈàAê^†%ÌTû¸~~r^Cé'›Á§×XhÊW =¨Œ&X÷åå;9ŽÈšL"“ê ®7z¡ \¯n&ƒßé6ÿÝ_I£ z™ö0„ wq´ˆMw'_ ¼ð¶f¬Ñwšñ=fü5²[mU»†–Ì›} ¢4"פ±Mš(wwE.‚¦>«¬ƒæS¤|Xð“K ]×¹ÚÎò&Gl“žÊ¯âT„ÒÛ6#9ö—¶5aŠèYÇã˜*.T¾{!2Ëêí»Ï¶øa"8ÇëÊnÖ¹¦ÝØ…šÝã„AŠ’©¿ñShMz "¢ï[†O9]çÌA—±¿º;á~ܸœ÷±‘@Ñð/ɦÓõ§cÀ{o¶\Ây7J’o ¤çVY*bóìɤЧ°’ä8Áé4MÓõn¾9— __ÌçHöÝ5µ~t?L_ïLÇîFžÑ¦“kOýb™NåeËírIl`Z »¶ Vó³.Ó˜ôRŸ…/òü8¿NU#ôt†ò5«Jöú(M×¶k®É<e®âÃ\\›¡/è ·C¯ÙŒ"!> eÌ[£áR&=«•¿˜d¤û'cbé¶ŠgSEIá ÅÛg3 â/­Ñþªh"¨P»àüY©‚%ÉNef“õ¥‚ý› ƒn|þâß"fæÐ˜ûö$5*Íóm7E ØüIÚ0—¼’l¶3Hž9t@sÈîñJjއ=Bˆæ¡$#øJ·—•ÒV“% †ìêªCe;&ôõ}—-yªo¶²Cç;%ódîýäVl£ð„¶o1Uê<‰´Äö ƒÍت¡ÄI…6í§9Jýœ"Íâ[aù5'@Qb_¿‚oèôFô8ÕÜÆT×ég!‘Úw* ýc˜&= åXŒ³ãI]v>N°ƒ‚·%Ù™öûÁeïJ-gÕ+ø§äáÒ­Ý ^&eÎhMÞW@À* |ÛÀX-¢¼ÏÃòéwG¤Cúâ¿Ç®Þ¢7˜ýÛ;rÓsìÆ®èA„ç´N%Áº@òžg ç½¥¦!TIµÿsQãÙº…2ŒÁ UU_ùP­# ì*™„¼uFû T¦Gw:òvÐöàGÁ ”àÞ†îA®3t7÷ä¾KV˜äó_d9»1ÓWŽ–çw¦sU—·7¼ÓäÙh" ŠÇiÁ€B¯àç⦧äaíð ƒ7í¢Šâý‘:Tñ0™Òyô$½ÕÁcÅSϯ¡ã~/çcs.ÎZ˜V‚í¥ûÅóüŠÏíGWN–pJ|šñesª¹êjõ‹ŸõòÛOÃ8ÏÊ£¡Ó}Èïðu†cÎûÐóŒ"o³ðÄÄk_¸>G¶Lk¸!œ.x¬ÅüìQ\ìM^3WôL²¹KD£Á%TârXŠ;Ħ›¦—gû" ­Héý ŸŠ…·¯Î‡éZÙŠ ­(irŽxEª®°·6HtSà’l›×(PO«ˆh°X_ŸæýXÆ/M%#tÉ­5ý³Ý££Ä)O„p;ðËÌI S×¼toütÙÛ×ê€EŠèËe‘—²@3oÅ](÷_[–hû „Ða8¡Œ3üâÌÒKl¡OYÇÞŒGµd¶µû—×â•nÔöjé}`fžkIØ($¥*ˆŒZª:̾”ÊÛÏÍhÀ¼{gf©šò"N:q{YÎhJ®¢‘wF‡Š`2‰vù!Ãÿ4=ë ê`ÿšÑ7v³½þ@PBò‚ƒpÍŠÊõÔ®‘‘zäkO+•ä¥_qDi³ŒSRÎTâ‹t¡OíJ7ökLZó÷xfb¼nŠwÙÚ¿¿#ŒøËaóàpáo„@a(Ãdó¯(#u eaÓ3ÃĪŸÅ'Ëh›~M¨1ž Í|x|>ð­^ÔVåQ{ásçÔ¶çð„Ž¯? ÜÖ%Zå-d(A<}¥¡ýWPÇ wŒôøˆlbkvYN(þÿõêzŸ\SGÝšéñÙ–c¾Í}î*ZKnM+•‹3R\*ÿçWŸ n½ãyRJ '/¿“Œp%Ôséöƒ0ÑzHIîÉ„º5{‚ʱ§½æ¹Îdʨ¢\#þ'½l³¦ê¶ú¯f‡Ë]åš2 £?ž÷Ju¾|t—l@*:+¦<ÎÍ¤Ž€t“Ñ5ZÖÀâ¦Û!Å?œS"æB¿ŒydŠcZ$«1˜*ÚžÚ(6#§9¹sä ÉÕ°Ü㦴䍋ޡJ%ñZDf~qÔ8,/x³©èm>Ÿô«!ÓNw6eÎßeérœ›iÕ€…dÞÆi¨U– „T4Ó;7d‰ß5(S‘h¸7=¦G =(ÑP„á)¿|åOs.˜­·ÃÔû%ãY.*ÂeNk>´ùÌPt*5O¸rŸ¼Üý¥*‹üZð„m!–~‡û³¹æ#ΆÁIyÑNóLËK uª©ÅvÿÅG>¦“Ëáf–ü\kjØŠ×$GN»ïS™ü„žDŽ@&úÔ÷:s8&]¶Qû¬˜éðüž 1ÐJ#‹xMAÏú,§2üq+ãhÄ9[…›¸ºNU%¯¦E22ÅJ³!ʆ¹×.˹\7Pò+89‹SŽ™$â-pz6~ÅšéîÐí–r4¦®4@_9õÇÑ*~I…œ:eféÉÖ“¼Œ¹F§ Ks|VUgßU—}]”±4¯‚¤·pæ©áO&•D…E{ÒAãK¸Ö¾" ¢ DayóŠçO;^´¤™RQqÚŽt¯òÇö}«©>Ûãh­ ÷G+MñoäXG¶É£L¿¼!dp˜‘®R[ËùÍÆºõ!\§p;z÷²TòD†~gý7sK}qÎ\ K¥¥;ÉÀ m›T¤üDñ[s›S…5gd€Ű¢…a»‡$Œ±‚ ð§îÓ¸7ÈäI3òUÀáõtsmîç*k¾ÞÊãYNj‰MáB7ÞMÇLº³ì.¤‚ž®5ÉÅÓUÆJS>¤òÖWJ½ì ’(«–œ»²÷åƒLŒòCZÓj †²sv¿…2yÀ)RŒ~ÖyO×zVìmQž¯Ž6‹bœû¯Î%Ø>b¶ F’¬•ÝxÄ¢˜;Æ-¸Wïp\"M„ˆïÔèøM7~*é† Û¿®ÓÒÏ@ÓÇVž¦§–—‰Ûw‡ý&«©®»ËÈÏr Pж¾;Ù¶Õ}l¬EÁÛgëµpÚfþÀ‘æÙˆ©CÈÈóÜ~a|ÓÝ,u¢W([,†-4Þê uø„iq‚0ú©¬µŠJ é—Ê ÚÈïÓÝ·/·/izdÝ?ñ" [Ÿ‘oŠóÉ=W®íq7ÚcÍÎ"¸ÚyòËp%~ÇPf„~V…U4‚¹‚’nO¶ õ ¼÷°wg7Oëä»’Õ*ñòÅ`fQ"¹=S¸Äa„'IíñT·¨ ;Òœð©ÿZÜþ!0q?Œd%Ô²©ohyLIzB!I+›U½˜d'%ºÙÁùQFp±)‰¬ØkaÇ$“ä#¾=2šöH¥ …Î`F`Rí£<“‰t{ ©}®Â:Þ4æÔlhgñ®­€ÕMGÒè)¶]«m/iaÃEnÕ‰i´ÿÄàõ³Ù–pmÓ,ûT˜i¬gë8¥…µ_þNtåaáªÍ>ÝPs¼”ŸDȻڒO;Ä æó_µcš˜{œÇŠÈ*Yú®Ëêå©g©šeù\ë„Æñ©–‰1Tø~¦jïíäü¢qðZždšgãs‚þ59?%V;d?î YTV…jÆvœÕ0Ô(1€]¦¦NnÒY¼’N?¹GƒBùqÁÚ©_oµjOBÉ8#\6ÀÅ+°×¦îÎ$R_ZŠ ¹õÙ6ªô¾÷õC='¿‚ _Ò¤àS+ ÕÑ+3 4²=wÀVåëÆä ÿ¦u<Âl9Yh±#“.)!ùMn!©®õ¼ÄõÒRŽíI"r2Y10§~Ù]Ðìc¿Q¦b¦ÑPèÀŠ`Rý;ž&F×iH*µ“ç‹<|w§|û:kºX£–Mãò¯÷šÉՆ؞<_çÙzR»Û æ|k"O5í>áG·ŸØ±º½8–2šhQ2MÈyN˜{ÑÿåG<œíÛ¸KœØœÖLˆò%~‹jÔªw³Oj?Yµñà‚\/4…7^]}ˆÓ:w§çk‘övË-6Ž%J}·ÎqW%Á|!RÂ<¬˜/ “îi{Uñ¸“‡éÑLaìJJ8¾æ²\Zb³¼ÐO½òª¤ï;þãw9ÎÂà[òrÏfù­Æìz@þœ‚…á;“”ò)Äuƒ™¤Dì¼ý49Â÷ö€ŽÑÏûÁ:ú¯?“âò¿4²ÄÁÎk„G­Ô¯<r°þBÅy»ª¾BÛÔ¬îO9Œ3òæ„@‘@5 7×áÀ¶0¾\– £Ïk¡ 7Ftôèø™Ä!@îçÓá}óc»‰št:f™y¯"IÀižûXŒzòZ5*Å·ªFÛÚæí9 º”ÒwÜüþNZR³èŽ(ŠPbsOhQ#"ú»ˆøMT«¶pZÞwÍžÖË…îÌ}V5ƒ´Ã)åG˜k±qÓ j}v€5Nú¿Ôµìâ"³†Örcsž‘Pp§ô—WdÛ%wà‚)°kGrìsiª;VÜì¢Ûf8 }5ŠÂCq=þü1ŽdBì+ÕŒÎò››\¥Î†„öÌ<ü㥹åòQ=,¹nÉäõí·ŽØ<Œ©—ª æÂɨ­„ CQ÷L’ªV7ÚTÆhñ„ÑÅ7 C?{À‚AÕq)1ú]>Áš1Œ^Û²øe„µÍ{ &o8Vy 3?ÀUû.vr í£ÓAZ¦ä ;Ljz3AZàÚËH÷,¨žÎíEüæõGfÑ®%»ðAewÐ>¯Ñ'ƒÌÊ`ÿDÚ#ÅAKÐ÷<¥V Õ/ê*f©Žü%jåÕúRqoqw5§ˆ„±sV™-uc.²áº—NƼݔ.*W¿¥E£\ÖNÙm‰:õ¾'§’±dAHàm}=ÇíÀé0š9}§‰1…¾¦[#VµæÜdõææ 9²Ô«,H;~¬k?@2ß7PtíVPó¼7iméÌ€~Ú/cYJ=Ùÿ>Þ‡l1>ø– Ûy3tÍz­Ùwœ6oû`ËV%=X²kîšIÉ#ÁX—(ùôîðÚóˆw¶*:u#+pDj.~‹èW°J”˜á¡ŸÂA·™üÛJ›Ü(’ˆõÑr¯è Kd¬¡'Ï÷¡qõ5,oôNŸáËn«³GiWµ°oj’‹º‡CH¦ÔÎA#ÙzÔo_(˜ª‹\’¿’iAñ<ñE~Ämð3~”íRfm.ß´•={°±E~xÚ;÷aüuUP–uÍêbK3vIƒQk`†»Þ+±/¾ÉøªÈ|h¢xÐc½þ¤µCO6õEM‰òö©ÉD-çÃÀÂeô­‰ÖÙ„Þ¦0èì߯d&úÃŒÌ1Zz4“yE5ŠCúY›¸ýØŸ =—[WÊvBt]ü0‡E* dù$(¯Œ› ™‘ƒýÓPƘÆ^UÌ|¢J†æ†óÇÔæ]U¾’þÍ¥1\ŸÑ`apà†³ } Í=¯OPZM—2ê^üWBvVÆ‹£f¥ô€I?mÄáê>b%§MñÚb-”ïžÙÊ]ñ7u°Vhóx;Ý;Œ½Í†az‚馹Dç£ÑCãG3Q+BÃzVIÙ»ƒ==}Á$'ÕzøÐ,¢d±vÛü¸©¸Œ¶Sj‹ïÃË(žÓ¾ªn·×Î,ù½óý&AoËü넘¸§^«–”¶3¥q£0b­Þ[«Xì}ÒGHF$ågèlˆ4Þg8›œú¡ ÌŸ;Ñ.W9VWF³þ’«ž»—³Ø·›í¸¨i°1ò†Ô(±ðëzñ~•,úeV×+, ½ösMªkØŒˆè8Fž…vŽ6x<6OEe·ÔÜGÛtÙi@UUÓ¿¶ªe<B/ & _VepИ/`·Ú³eË>•/]êî±t3y_uA¿qÂࣛKË뻿@©Úú¾AFyFÝpñ†#…Gß”)jÈÃ4°AÑûÖ”&‰ô{Ag¹×€™©29{xïuÕM‚'²4‹Ó6d)âu´8(ðÓ ®O¿¯%u_d?¸Š ¯‚L7JöO |‹(µø;: Ã:ßÖýøêžr ×.Wµ(ópC·õlRåT:É…$$EI'ÛÑž3¡È¡{ÌûT‘ì¶[ÚŸT_•±@1hœÅôÕOï‰(:‰‚ø|Ôj”®·VB4œ©s¹ èÁM‚íÔ3z›šƒ‡ß¨•÷»fn`n÷kŒð»ŒWÜ~¼ñ[ÑM|qmOâ:­¹wOŸeíý2„…ÜC}¥Àinc»¯c“ËÛÁ[íÏÝͯ%øn¥|õ¢žö9°í5š‰@»¼Ï Ï3mŽOž½ #ü·Û義v³Ò…°-ãr9ˆ¤ãfÈ+Àù¥^Í;«9îC¢ðÉ3S>Á Ýw…ŽžE#ÔÙßËc£CÂD{ðU;ˆú­ó(8a•¿w6u»ˆ;ñ»”Ë qHý´G)$&ÕBx³beNÈGÑ`éÀrÊÛ›ŸdBìéz®½Õ½þá‘;ñ¡ûH…”b²ç[p¯wmŠÚ¡=ÓnãÅ×àfÁÓ9™ [þ›@ÚÅ/÷7Å)Æ@+WŠ_úóúpÓˆ\ÔK|̰?%Š Ö;ÕY.bNI¿öf| Ôi›/x&Õå«„'Aƒ)fJjeø½Š˜ñ,ßF¿Ÿ\¡à„t’¤ EµEd¦g°©KêïUг䏱‚šôù$2S@3]ü¹TÓ™°ŠÙyiq,é´›Z)½ˆCäwýþÚú!暈ü”jXõ²•!{Ê'@Y2ù²¤£ÛL.¡}yø6) Ô‚?óŒ½*lEäbí÷Ù#YÑÝòÝ!ƒXw¬a"Ã-Ëy¢|;-=§¶Njâ«I´1‡ODbRô¬ÿ¤Ûò»Ow¡xUxæ¡ðÏáþ”*ί™˜Lqí/Q‰& sËšƒG\cý±z>xF2ü,QØé¼´Á#ª° ä†þFS¹/“Jj®w]xVÎÂùYejÏÈ#Ê ˆþ–BÊ‹B;ù""YrIXÜ%%GDCà%õßÁø­‘®PPè°ˆÆ ,Ú†‚’Ù"{•ÊvµML«jt”:¹éÛ<øe6ïψŠö¯0R›Šfh.ÒsÇ]ÂßÄ]ìZÞyÈL7ÁüNx°³Ž{ðè$ÞàÞvý`L'G‹Î`òž¶Ù-×§çaÌùy ¿[~j}]DN‘™Ï/¸€áú)©³†‘ׯÄ{ɼŽriõê÷C&n°GŠ£c†;ý9F\öFç²6£»e7»l 0Þa ßNĺUòò½ŸSpe›R& ;C´ƒ«OØQ"s\$6-$DI„úlú¿ÿÅ>þmÞî…È‚~ë—‘GRŸ`¨áÚ@±ˆåøá¬ê*í„or‘eÒGC‚óƒ!-L’}Æù@=UiYqU OWÙò¯`Dó/®åS$‹ð¾§7ë!<Ž74e„Ý–PõÄ%zÕï¢.ÔZYN­–p‡g;=/T1¶¨L©Èw¦­çMsFk¦µn»~ÖO¦}ú6|A÷SŒy¦gd}±TQƒ¿î­£ç¿m·þc¦Ö!åV®&A˜r¾g^¦ZöN€ý'Í’Z]“éÎ[gEˆ‚®ó/¿wÔ 8bhgŒ1¸zÝR¬Ò§?Çuzj¤OSµ¿«/NõK8|ë•¶†¬á[ÐÙÝóA7,S»MΑUT.;¦Gí›Wª í´²ãÌnáÙw×1GrXŠÙÍ3óÙHCÛ‡¸Ì.ÚÒ[~øfùÄ¥²mÁ0Ù‚U9µ¿zcoƒSÎí|>¢îB–¾ÜŸ$xv÷Ecº¬Úš0RæƒpÉ+táE*ut^@gª0‹¨4#—ä!´¼9¹IG›ÜÑŸk9<*Ó:Tz}þàÄZ›Óà“IïK'’_Ó¢U(0áe%Ü{¤ `.w©T§Ýg§ºÿEt¦ýÓ±ÏD¢/‰íë´C}¼rS`2þ™¹ßó:sóá|Ï8uêéû…;Óv XÓ]RIè8B³`"†¤XŸ5zåt¨~îˆl•®Äÿ²„)?oÕ”Â×C· Ú¯<xÒ#ZŸ‚±ë Ä9ã¼8hå9¶®Ò[GÕ¶århWœ„IUÉQÌÑnö]ðóâ|À$µ~ðñÑÍäkŠÄã„Izßåä<¾˜ðý¬˜ºËÁD-¦_”^÷¹¬Ò'V]R"ùC«Ã{î"Ó©6㬈“g”U±˜]dM‹Â|Õß|–aNOˆWß½8NÇ|¯ÉÃPÓˆwz”¢vÌ:9ݳ „?F–ÖŽFîI²u §HmÆzêü¨Õr׫f•刋Ê£#ŸÑ§˜ýé’þÃCßA;Å=bÿ¼QßÙÿ‰}’!¡eŽ$9[ÙÆú™îvªçÙŸ,ÊÇfëóa(qõ—~‡Üö´ØcЈ/”ž¯ùj^§Ÿ>ûˆ ¬÷Þy쵩¹=zŒÁž£ôTýÆÜõy8eüx‰»»JbI˜6=â9ëØl|MUé$¶ÒV$èÿ¬ø¿˜‘NCФ©a„ÒR½Þˆíð®c¼ªlþÌû9åH7õ+o ç”p/«õÆ™¬pV n±µðr,Éc<‹Ö“„!FÔp{ª¾ dÏšÿŒ²MRVm¼Ü,^L 1§T*1ʘ+]Oúìˆ{p*ñÇ„]hc¹þœR_~šÐ®–ðD›o3°VÏë_èOñ&+ž¥Å…Œ·±q7,low­1âK¸û¾L’u‹VXJ]ÕÓ1Ïžµ²ç|`IkNU˧êFûÉÿ¾ߟŸoI”¹Ûõ¢•Ãã4SHÚ­6Å}t !ÑòfŽ´¯øBƒ¸ý nËvÜð僰ÖЗÇ3QQWÇ›ì±ÐLFäZüƒSëçÐ_ßÝýc7Ø P ÞV‚˜#½–4¦’¦ìÏœS)~ÀEÎîv’üYézÓ>‡TfÈ̉²«S¢Ø—Ú‘+e·¾îœ6zÔU-b7ö#L¥èï!ÛΪôqÝVvéÉ·> b†çr7f4û4vE¦»ârgØ,+áýDG?„Gf£3Ú¢îÞ£ÁôTÄ;½63 > Ü<ô顨üäxÌu£ ÚÌË]¢Ktfu _z”@’¦MO ö>š‚Œ ´”}bp:ìŠÂvä#󒜺 º„Íûuµ©ÇïJÆHÖªƒ)žtõ_p–*Bù§>ag[Z#}¨+ŒÃ­g¥Õg“;î:h0È62Kí$[­“/<)Oã~H'O¼jd‹©ÐçQþQêìÊB+%ºb´V2ÏË/¸BìQÞ5¡oî¬ukQ¢ÝÇ@í\ˆwª´Úß CºÛ÷û|ö^a9p<«é¸q§¦eUò¢“WG›ËÆK –—´ _ H̃D×´éR'B£%u]'ÐòbÆSÀJ‰š„—mƒGm½­½šE»äh(ûë†1>Áê—íÔød‰¯ýŸU¶vGH¿&¹™ší˜ê†<„†ÂŸDÒduÕ—†0Æ=ï,ÊÛýÀ Q°wXàk3)¿RFÜšTÊÆ‘\¯‘Oã/Æ;nn,»µ4çHôøxý.ÿøÁ؇¬šFÎùü[½":4•jw Ï[–®ÑëÅL_Ô„º½ö)ß@&ðÂ-¦Dç­AÌê/Ú]´8þ²2)•¯û›hA÷dßbæ°\ÛŽY×ùßoBC*¹¦k᳡}•_’ýnå^¦à¿ûtÙ…çT‡òÃõe#¨!÷‰| ðÄʱ®&_­ð“>=ÜmÔ:¯qeîë1F½/¢ÝGn”W³î@„AW Uæ)y“ËP]vP“\WQV´šThM-C´”)L+s#ÎÇYc}‰FÌ8éo-ù ô_NÙxÃÓÅŸ¨,ü 8”Ũüóã½×HL*Ë>HTÍã‡I`÷ ½¸q^ñ#ékTRE–Ì© K\æp†Èý² rŠ7ÿž‡Ñ)aѾ‘\CГ_Êc€Hóȃ?ö(®ÆÅÌ¢TQõÎ&V’<–>¼ßëì¸ á„°þVÁñ˜^`¹NáõÎsáoð.kã%ü)Î7èËøÞºñ&A5¸*‘“5ñú‡Ùsh¼Ñmæ°ˆ:]2Æ#\l¤rÌ…-™Çöû!°õjʶ—9J‘ʕֵóé˜8Úiò5µ•²gÇdOÄQ ¤á ãw …NVv/œvá@5ƒŸÇ2žÞÆ´~¿2ÈiFI@¿"Îj–'ݜ鳹vG6ÑwF5JB¢šžÉkòPÇÑ9=?ð‚"Äg/Öš§½chØ.ÐN a˜òÖì—h®Øðï±=x²/!8ÅKÖ¿.SeßÍÉ ?¨'s)h­·¼¡H^ uj·ÄDú¡hæÏ…=¡ui˜®IøK—#¬;Á§µm Æ+4•/©¿!r ¦åæèrŒwLòphœDâÆ¥ÅNRªÜ’øO,ûÈ[ F—ÊæžÙ®Òã‰D?Ÿ¡"„Ë&[}Z $—Šéõ*úŽ zÏ(³4S瑩Ù÷Õ± %)r³[)mtqU.ÄCfí;ž½ÈÚx‰¬µrMF݆¤Nuå=Ïjø¢Y±ŸM® MÕ4ãÿ?*Õñ¯âCVä‹+`;X~Óï¬À¥›xFI“"V6™Ô' œo‘ƒÄã}íp"j•,QdæŠD4KÄæ­›ý5>áÑÏEýïgú—Õ€†±»9»öÀ¿¾@p©—ûèÚª/*ú ׯG¬0R„GgZ¶bý>hÁLY„ñ‰k_”ªL ùRê œAvÕ¬ûÄŠHCWµÖGóU/‚¦ÃÏ*áî‡føHi¤óWô›ðv| o#a%*ß…çCÃë³{°f†7ÄÍÀ  ºŠ¾>‘°[¸n±¾ܱ$dœ/¥“#(ìŪŽT$Ef–ç†@¨Ã÷Ù}ÅéH”áæ:}€` ”]ùk°fWd³&Djo/6-"*\ëOí+AyèñG½Ûƈ^ûúsC™ À¢³%ˆ²PT8+¿øi«ýñ"Šcqœ5÷ð}—@¼ç÷5@ìžES³~øf^myÕ²Hò+4“gëø=~3]Ñ®#D¼„‡êë¶P#¦ý @n~!…žº®èÑl­0í¶ø2äW墥ÙèK2YcËÃiqã³obÖgU¢òæJ$:Œ‚ât  ü+Á£4®ÚA‹¹ 6)¢xb!òijHèÞ¿9M’`ío0P÷‘b¸Á~2¹ DìâÀ£ó™–Y‚ËG,úç3ήƒfÒH’{ē”h$ÚÌ,ë’âùȎݧtëÛç©WábŠ=‘,à1ÓèÑ<QˆmçáãNHa&`K³,@¦V9é—H4†Ç¸“™ÇCëÑèsØç éoÛÿ-î oK™C†IBóÁ„(Ànñmª3…E=HZ¹…Rãú›Ý·ê⦈æ÷žº%»Ê¡Äñœ>]ëƒU˘§lÈCFT0òX—ƒê¨T DI¨Aë¬4*€ü•/øÔ}r=Êçà1¼lªeÊFâY8¤Ø{Ø®æß|¾€œ*ƒ°ŒlyBÏPFlp²6¼·KÂø5< 0àoCJÔ(NÖ÷Àò-æÉ$=‡!Ûæ‘ 'ÕþAZà"(Žçg} ›µaû¿AK0_|ERvíÍO@{UŠ4Ïpë›LmQ;ÛW]®Ÿ~U­0ŒÙ|¦:Êjµ”0mþa G¾ÿÐbY²VÍö-ÿÐb™ŽkÕO<Õ©òïp;Îéçt_¡7¡U/Û‘ÕÔñ˜vxÚA .<Cr¨#»bf£·žyB*iß§ñum9Â]Eýiš“ÇÏNƒðûÆÄ¿ïáx¼¯)&#î&ŒUµ( "¢å8üŒ¼^¦ºËù¢ä¯Â-±ãzVÒgNñš2F”­³µ$Ié.~‰mßì0 èóçÂâÀÝRgvg,´ç¦Î‰ê|’à6Ç­\x|7¤C `U…?Ê\Eƒ„Zn‰ÉíÅj‚ê;5™ƒ®øcf8oàœSïq¹ô¦´Á½{*C Ãöß@窿\=t õÜKY÷íH DŠ®ÛÖ†• îCÉ1=3®³c2ÔÓ¸!Ò dç^(±ŠG‹f ç£&x3XÀ”62Ö!vè|œâS¡“¿­%u·²;ô´q¾Råm?Ê ÿZ±º dD¯ùªv%¿¦U9p¤öl¢/8‹ ÖÕy2}ï—Û0`BÇq*ï ;”½m—‚°†£¯c™N¯Ph£Û]bG¥‰,ô¡Ù—ª08ao,68¯0ŒyMn÷ᎃÊ£¯U‹'pË'3ø ¡“S=¸<Ï‘Có¡§E=aëµ0D>šìI©L‚îßcF€8U=p°-¢ô˜'Ìðó›àÉL¯žíe}°3yyÚ»Ô…½V0 §”íQÄ¡85¶ˆ·VoÇTÅ‹ñw]a_³€ÃO¹$oÀÈÙì ÍZÆÁÀ‹=§ËÞìÂ%0äìæÖ‰°¤šLDlwðØ—ÙD%禳ÝvàŠMu_`Ï¡ôèO7ÈkÇa$…bŠ{J9@ ý¿ …ÛÔ.ædd8ˆ¬BÀ|_¯wøÃŒ¨FŽagqæÉ =~4y°ÛåO¾9¥ó3&™q:&Ã’"2ûúm÷j"QÇyÛðdŸÒoÐ^±jw‹?1X¢BÍq'÷P0;û3¾T=O2:íåð&ú«g!…> AÑ´¶þmÜš¥†Žº¹¢~ÔDJø°MµÏý6Ž™žµòõ=&:Þj]ÛaËÂÄùÙ}¨j¼´^Z˜H¢H^ÈMï2‡ÞI[ DÚµSrz Le¡Š ú, º^ rÓŽP«¯ªRì_(˜æÖ?&4ã>ÚZÑ:=IŽLN\>Á6ñïÎf—¡þ…+”[yNþ¢êd×u‡ã×P†£D/pC*ñFÉà°u Ägî,ý"lîzó݉a;_­ ¢žóŒ§ÓEe¡N¶ –ØRè‰!ƒÞô‰Náþ¿4>EØ#q8½Q[¿_FÑyù—zª3æªÉPð->{6Åœ¾QR„JUR'Q5UÎßT4û=ïÚvå~ `áížýK¢v1»ϬS/‹¨›n=’#©_ì 5dî& P)Óãe w÷ GÍâH¹Öj ´„s®ó¯¶«º}Ï!ÊGˆï—°‚!¾¾Oưè§0íü[GvÍ34¸×°ùÐX}1¤r öÉœ'#²Ž>É8bÍwïûF© à [w¬¤l«ëؘzÀ܉Tâ®`ì{ƒW¿ÅÚOþEÔYÖÚÐì­šVØ´ÃØlÉ)i˜òÄ´õüüIç¶DcÐ6.‡ü5ÛîÖz®fTaƒ¶‘mYC|òŒC¬æÃ!Ÿê>Ÿµ94´tÍ®oä²OÉž˜âÏã§°ýh…žï´N9 f ©ÈøqZ³è˜Q”¹_±z‹üÊá›BøÅú—ÑãÝ(É^¤½uFýD+WN†Ÿ¡AØÃЬ–àâÁm( lÇ €eÄ8Y^ÍùÒæ[Õ±ld„ ™zVÐ*¥ÝÅÌ–kÖp‰ÀÜJkWÉþåƒÈ$À6Nd nzz3Ý-ÿ¸§×l¾Ëj²W/=ÄÝÁ³p'·Ç'#P]¬Ç’XkîΥ맕Ìß=©ïY »D^Éã¿‚ž¬ríä Œ¼¡CžnÄÜͨ>Ñ3$XÝg“T‰»šÖ "™#õîÍFf¾CxU)Úf£§íŒigαU¶‘2að`D¦òÙ{ýN 0áHž49e£W%~së “À³Yê ý¯Ã†‰A©2iZ>óV§ÍÀ‹öãR¤ÂÂ%èÒéµçw—Åõ8q’ÊY­ã'2¹3¯=3¢',“ºxÕÛ3«‚Ž€; ^/O¤3j¦dƒD³"r@=º¬ýä`b/èÏùš Ç–{µ0™ú­ûÆuäo‚™ƒ$bOÓX^iÑìÎãò²)PîW_é3¥jKŠÓ±ä±&Ù°dðä7[Ý3RNXž|á?8C³ ‹BˆÍ˜Ì„5Kÿ`£gÚ~V1y nc4aÀIЧ‚ƒDñØ6ÉD-Ú qiùaf¤]¼î*¨d,«¸£I!oÌÙñççÝôдR]}îâ}BY-¿¸Èê2_ëßy¦´Ã ‹5Û“kB²WÆ‘÷]%`“}^»7±l8›gŽ€•c¡Qœ©÷ îc¶ïB Ïpc‘ೋ֣ÀêoË‹±¯|Hõ‘ŒŒÀþõÅ–5˜øŸó‹0Ø@`â”Ì•X^Œ‡=£›éZƒÔ7Eì½™ü÷ÇQd¨–˜è&cp(àm-Eü•ѪãCÑ!> stream xÚÌøuTj÷ Ó !ÝC#ÝÝÝ‚€ 0t3twH‡t7Ò)Ý!HI7Hw#Ê7žóüžç}ÖúÞ?ßåš×Þ÷ÞûÚuÏÔäªLb¦öÆ i{;03+?@ôFÆÃ ¤ r²93‰ÛؙۘYY9‘©©%œ@@°¥½$ âð€-*&`ˆ±€••™ ²9A”¦c€ Ôôp±è€U{g0“1Тٙ[Ú^CL$ì<œ,Í-À¿}p3ýv0³wúMð›äÙ9C¢:ÿv*Î šXÛ»9[[€v¦yf%f€²½Dh  ³·ƒ,€6f{³¿\hiH©kdÔU´T5^3´-A`; $1ÀÄè4ƒœœn H ©éß¼evM ä´³`†PÔpqp°wúOVšZ2ŒI1eM)H› £¥¡ÉPÖ„ÿÒü&ù ggj üm®$¥)¦©«*ÅÆò»6€+$¦åo¦ÿ• $Às6S3'{Û¿è,À`~777fsg0³½“9³ƒÍëß4-,!9Ø;Y ?@6 ¿Jìbg i ’È_~7 hi©%诤@ ¿”JbÊrÒRšLj1ý.8Óßg»ƒÿÊE]JLRIê©´´9ÿկ߾L!M¶´qf†û[` é8„$(øŸ¬!ÿ&ló7€3qô¿Óc1ƒ°vfùÏQg–ß™0I«(k2)ÊIH)kHýÅÒÞéÙØÅü·íÿ+ÕÎèüeEUUE€-ÐÒ2u@;?0ìâ  øKù€L)þ.: áâäô;5¥ÿS9ý“ÝÿµCÜ’޾—Ðí¿hçâìùG¿ÿÝJÈÀ[:ƒÿöúO¥m "Ho-íþÿ÷î·Áo—b’Š]åb°C>¬-–²3•°·µ…wFþ=’–ín1}²_2÷H¤0à“M¡½¢,¿or€]ñê`›_k-I•W¦j¢[@_%_"4)±Ñmf­À ¥ÿòNŠ×ûò9ùº%œ_3Zã[IZ£|í]÷ÑìãO˜(ôË[WòàÝŠfØš±l^¹/`v-Lv@ƒŸî±c£€½b‹ôÓFù¡¸£ò=]Xß³[÷„wuèLX±:3„üPÍä sXTú¹#Éœ\µñÛŽé„"7%ÍLUÐ{yyˆ+[gCwŽKÆß Š%ŽóMå<ŸOCÛ\µ8\PË[w±­Ü^O×>½¦0u‚ Ô ’aMaF³y¤ Jâ¡ ®Ò­(ŽÅàzJˆ¿ÆO%;ýÓL Çë§ïì*;˜sÞh¦rnÿdò]›`TåÊõC>a³Þ/„±cÛ5ÑésÚ":ÃS©*G§êºh÷T]×DÅŸÛ=‘Ì<‚ÛÊ6fþ¼ÿŒŸôÒ"ì…«•5i‰ù÷_/® «á8•ÐW#žôéâ$\Gè£Pvm–UÅ8¸8¼¦ßHLV9ÉNs2:-Z3Û”'*É"¥VˆÖe Vâ&8xõµu={3AÞnC'¶çÀÃ(\aÎÎový›ÜôF œÕZN»1 Ÿ•&,¾Dõ ݾ؅À‘"ÐŽ¨Ãçeuf\Œeæ]Rž7FY¥ “¥ø¤‰¸¯ð¤r{^™õ‘w‰6„6b–¾)œŸ>u”!ß"›?ÐcXûÒ¶KX§þ«¢èÃ`Ü«j’t™fóÉ !Êcq‚à'‚„Òe˜o_3‰®?+r—ާ¹ì„ü€bhâƒz(æ!pB}E'˜Ü„$àa÷ º<»ÞyWÅŸôûÎ`ŒÝó€IÙ ÞÀ,q´ ˜^"-àrOmƃ$Û·S÷´£ñ‘Îfñuë0zÂ…+nÑ:¹·ðw ÀOâÉé©Q•°/ìÛP=¡C…”Z}[)ƒVâ*x…%1W£¤Î“ܰ­B³pÚèfRi5 ³å~;Û‘ ú¹åVºÕõp£›¢¥¦® C''¿“H1Ão/¼–½E`Cý&ÐuàaSø³E]­¬¯l­º§|ÿg>¤½VÒnšô• K¥_yÊÄ!ˆÔƒ-ê“.Ë}æyÝ;m¢V=ƒPÖz<ë¨ËÛ¹ÂHÊ/”–"ù.ù9uÁ—¢wûùô¦yPfÊ3ß5u@FÜ^w“)✋±„ô©}fÔÕ,çe§ìÓYëÄ Íi¿°Çßu@’bDÙ­6À…‡Â°Î¾~ÿÕuølR‡rƒùŽ´Û—a®C™î¼=[ª&¢4Óœ'®7›âݺ÷· ö턪PpbšÉÆ{")Ûä@ùù‚5jÖñ²ŸïU5dæP/š‰Ö¶lrœi?ÐÁŠo}:xåþ cÞ<†ΰ"£ß÷×ÌN(•¶ÒÇŠÈ“Î'€;yHFmülÆ«¹ƒŸ}{ßõ¼³6ø×•m‘f¥MyLœ²çþ±´Ãó2×µ•9fx·õ®m "îô®Ðò Š€‰ò"jS.¡ü·éÀÕæAß~:\ §ÎÑ|=|¢&´•ëZ[ÊŠ„•óÄÜ4d/~SßÄúꎙê)@T[‡«º‚hðìòf¢4zDØqfr‡ ¢êΓS:•ð[š¥ÐÎúM6­yë‹~…XR‹Î.^¿ÙÚüÌN3ÂYzG4¢…ß¾¦WïÞcƒ >/„èÙu-‹¨÷|QÔš`fºøâ6–­ ç‡Á™ªÎgà—bNœå½ýŠØKÁß­Žˆcðsb„?å"ÿFŠR÷š\×h?¼ÚÏ!æÕ; ´ÅwøZøÃCOß)`‰݆ó¶”ð¬b‹`âÞ•¦´)S9¨Ç.?m}¯Yi\Y.K~(tñ»ï ÓB̵utöÎ_ýÂqÞLZ04†ûCŒ½oƒ‹˜]Ø a0k^,SFûu"§Ö¦È7Ki?-ìŠ ‰I·®_Ò$zñ©•J)k„3¬Ô„ØJ§ŒùI9ÈÃï[kc¼VõFÒn¼ô¯žöÓ¥Y™58d]ˆr¼à˜ÈÇeœ°öį~LOí ¬ÂµÕŠd¾xë ¿ŸN%Ph†G%<®±›ÜŽ@oÆRd=º÷@2 <©5kàGëê9„öß Wº<ÒÔ­2±c•(пûÌ–{Ï_È"V zÛ­ùöÛS}õUF§\æ˜%à‰ê¤§ë>u bÙØB?šø¾ïB”AUÈ5ëW%ë9ÎÐãŠÎrcÒ<áÇYÅKfÁodA³Ç#¶£w ”‚ìí¤öµ '5”ž˜ú±|…•1¶·ÐÚpƒÅˆØÞt0¨Iöè1°ºNŸ¿jüüjô¨ ,aO+Ì”.!Ô=Ó®÷ƒY ç@cüþt™DƒëÒqû2æ {úsøçšM‰idüUäI–[°Ö¿¾Y¼+h:{ƒ×% nä- Hn×ånÁ¹r>. kv½Nq’“³Œ-A'KÁ&UÊ3•0'LèˆÏVíÃЉÑàw³MÔ ïÇshŠõs¾¶]»!‰Œ5ÞÍíÜ´õt(⌬û´¿sÆiD 2Ò´&«(¤ÅÞ€ÌräíÞóf­Jàl†ùéPS”š•¨ˆo#ø[]¾­Ã·ÉtÙÓælõU€lAAê¼ÊâOL!Ó$¥ˆCf›’pôÖÑ\\’pER脇7ll½µ0ø?h=#’Ø–B»ÏŠ:)ôlR)ÝXg‡´!Šœw#5%Ë Gv’s@)4©+0ÐÏPŠa‹Æ¥l&¼ëº»ï4Ï!Àq<¨S ˆÜéÛÅCX÷*²1H}õ#ëC`óû¯ƒÙBêš_jJd³æÒóæâ’•æ½P?¢‚òôø™âdR#§Ð [ëýþKgž•Qåe¥%×X£@?Χˆ Ê<"z®‡>Æ£±‹ñG¬mâ|W•þüª:Kמ¦]¼öº|³ áÏë7$Sà·§k«ò•Å¥È,%%.¹½$Ÿ*0ºtÕè#*ì¬bc ‡Á'yÍ¢nüÉD­ößÙ{mâ‡ÄWü’ d*1‘Š9*š¸Pk¬䋿¡ÞˆA…»£…]„­²,Úf‹ŠòŽê”B‡Eø7ÒÿúVêÔä¦=§o•£%Èm8kÕ½Óð `«ktz.KLéäu<ÖS $¦lþ¢Åœ„T—H©.ñµsµ|˜áÛs1Þ¦}3¢¾SÛ Æ?½j[fñVfóª´é6ö@tŽÈ·ó½…Emħ`qŠpñ:'EUwÁDc)3[ ´ Cºá6KÔÞÌ9²bBhCÆ Ë%ÚJ`!n^Ór­¦B3Œ[ûÕ*Ëd‘Š´›fŒqŸµgø-€"Ê™{Ã,?üÓëHScÏ_e¨B§/׺ßh´«(£ç”uŸ|ZÞîù˜Y—>e¸úÕÆ‘ìŽFB[X"SH~ó6‡âŒšŸdðß,•rµYÖõ®èÚp€…ÍP§Á»/B£PQÍÝ?;ÆÕÌÂ:áÕXm÷õg¢]ùƲÜUmÿyŸÿën6¾¥>Ðhÿ«ý[¹c»Ç¶pçĤK‚tÍ…Ý8HK-×Õ)ú šÌRSKǦk9 z§Z“<¦‹1Òœü<Ïf*MEÌè ½jÊ‘j¯Uûüw„~°nYŠF=§Æ¡Ûö§!#»¡¢]|…6CÞƒ \ìžÝœ}ä8-8È;¾~6•ÖcžÏë|!l‚ÍŽÚyîµFêcùº¿wHæ\•«®)`Øç5ɫϔ!¸rÆ ñ„egÊ}%|Þø®„™îª©Hž˜ßcûczÈö–:.ÐÓØëÁßi߆V¤¨) b¿+<‘ k{y{ànmuo1$r"%©yzÇÖ™é¶ãûó£3ØˆÇø Ü©¦­Úç#’5kµóˆÓçCF?îo>P3œ>?>µÍŽ¿~Uk `E¼Ú)q.<Éùh*Ÿ1׆ÜbJb;§(Ï{kgÄÇKÜûà ©’ý›Ç*ë˜ÚzUq+ß„±±9 ù=}ûŽÄµ·ãp0âtˆÕÞš±|‡<‰½K®½º­_Éy‘†Õvut—*½<7ó߇ˆ—LJB}9ä3o)´Vtþ¡óeþÛ§ØÜ“B†WåK+buE=cßê½ýUTu¼l±V3Å߬µy§çÈõ,дvKéö5ó f¼ëÔž‰>¥!Ü”âí®6@_öe®KyB¦"w&{hNFe€`Á¤D¸l3K·Í 5‘ T4Ìþ]=¾8«ÞH¡|çÓ“‰x—˜_Ôô7ï&ŒûÍ‚J ¿µuÒŠ2&4gD¾p! ó3M&ì' Ùlƒõ» ·q® ö¡ÜC!i1ºHåê6¦ðåab“L§a9÷?œñgÑF‡ZßááÇ‘hÜ|oZÕ›!ai0ž¥Sˆ]5Ýsç6·!ðÇ5˜~ôÈ/§M >êeéà“œ2v2:©Š;þ<uà›dF"ª PÄZêm°õ£"z±Ý_çF´0Ÿ™Ú2CÁÅ_Ší¼OÇóîàRŽ£‘÷úåŸß‡>Þ`Ÿ¢Â¥ó¯žÎ^»kTÙP@R¦!s˜<ý<%ÆEÆ-xªÑ¹5Lmù_—“ì§xÙ²/Pa¢rbµ=ï/+Ô;gø¼3¾½™ûa=yɨšà0 `XÌ|gí[Ü“çXB‡{UñR1’<í_Òîf/}ŽIã®°µ'0-‹’EØ%Q á éÈ)‚Ê6L`VÂB)Á[×ÿÂNü‹ì»ñX{v|2yM>²„f…»‡ÒôøŒ™·5RLîÉ¿fÚâädö 6á6_3ÖU€ æ}±´~•°BùÓ&?oö±EꑊÇJêb •œÇߟ*ì]é„seßÐåcA©ŸÇËŠL9µ«J‰½®ûÙ_ S bYʆÑÎÉ8²¦??X¯Ðjéy–[ͦ÷’õ…íW[îŸãá³¶ÁQˆ¿Šã~ÜŸ6Û{EéÍÁ{•\œNôqðV1­÷‚äV–`ù«îƳӂôÃu{>RÜ\1"âôÂí*쯛×eÃ’ŒGÏ·‹óm·C5·*ì_ߘr]Ÿ<_äÍç÷Kó¡:”h îblGéB#ˆó £¬ $l ;úÏ£÷~…Œß¶ìÜhTŠÌ[9 ÔëQÆíLŠ>gˆœn%Ù”òÔübNiÊÍä.Cö{ÿ*2ÌŠ5´Äo´Ï]“3¤’ëë[Féz¹w®ô‰}Œc÷0¹›[ :Ëç+âžûȆFÜèÁKI?é_^ÝÂ5ûrêd__Ò¼Û+®­ºÒÑ÷FF¶ %~X•Ó!†)½ØåÔ}IDó]Ô½ëK ‡®lðÑŠç:û—ðÅ7ö]1o(o¿œˆ½Ò-‹5:„ðÒPL’$ `¤^ ÊXÈZqÛmÆ^çÃèܘ'ùÚ(µ/bBî•ÒE»Í­*nžâ×BÝAQx×t~‘pŽ`³šmB½ÐÛjèøî>éHÔ;“èLáâ@’YË̎먅øÐ“¯ ðÁÎÛÀâˆ*/Èg¸ƒ=¯Iðç Vœ8kÒM»îZº´½Ùo¢Ôè+óÊ6›è#BrP´bx"LPh´™‡®ƒ(ª¯fìÞ«y±é`f1q°Vþt»™Å,Ä(ëõëvÕYh\Ã0åj`!£À(‘&ÚRà3læ(Å%Ý?¦‘þ¥;ñÆ `शÒ×0…ŽŒk’Hß§—?ê Ž¿ew½";‚kìa]%⵨ ÅmÀIÄ:£"=èCX&¦Iž[zœ¹ˆ¾<É+B'õDÜ ãí7yBÈ“K×÷]0üvüYËR×a(¯õ(@%h¬ÍŠîZŸÖbÍ;º?mלmÀ§£´/%S†”¡©ÕQ)ö‹í%9VÅÊûWéâ[~.Š»°gˆ2MY1jÙ!ßd¸ŽÍïd®ÛÍ_ÞÀÛËš f¾ E¶AHíË£Eâ q¹;úT?:Šè÷>Æ Æ›XûCÃ]¼?:#* ßg¾ñ¢Ë[}=…êu²´‹]qNëã!¬/5SbwˆríCi­BOz‰ 8›D 2W¢ÌV¦ìèW` ï˜h«ôàž’‹Ds NæÕ³“c×hwh_?@ÛÑìg¦A¡<˜¶Eîh*)h•×ç*߯Jê”òÛ´„mvK2å´ñj¤ï4) ï¼t[Lr&†ÇÊG›OàÐŒâ¡ÉpÜŽ)¶jÕ2»–£ ±ëñ«ÀĆ2eg•€žVÊŒhª¬/_]QΗ¦¿ÿ8Zí†&>Mµ7âá:0-ï’Ÿ)@mÐ{ ,ž*PÀ7%ë&¤}t_Dxl™îGé¿);{±<›JËsC—ÁhĈ€¾"úk££@äË…;O‚C¢Ð{\j— lî6bWgýçN+1ÅïAßß•‡ó¤Ûû’Ïãu’/ª$ÛwA÷âÁÉ3ÉÕ36$ÁEÃmŠV®ø"ñ^S»^ãà%Ë(ìÏПV„„ýD]øìdJü‘"ƒ>9ÜÇFƒ[äEú-öýdipéU›#Lv³˜ô¾æóøy–dV©ýZÊæô£¯T:çÞ òÍ屚@a“U ¤ W{VÍ”ê'¦$IíMí”uL×ÏU€#^øöÖXxF;„väYK>t·æú­‰®î¸Iˆs—€¼mßxü„¤¸é»R…•ñÚ k[Šë-Ê /s)fmK0¿•OY P "U2»H¢¨Tlµm[->¼¦ºø9¡C 8RÎ]Ø f¦ý±›Jñuç¦Ñ„Ï[E’ó+ŒÚ†öúT¯eÿ—yý¬VC¢øŠõæó/#›×ý‡“³dDåŠG 7¼[Ö Qˆ™¡»¾>b¨í$ÌPbÆq"¦šƒêí£€âÛu’ß­B$|-®AƒYÅÈÙ›Ò¿†Üø$<ÕU ›¤TÒ4}ã‡MˆÅ†«FºBq+“fO×Ç¿¯ÆÉ•ø„ø¶ÃÚ¯Dû,Ý®ÍBáµ øµ‘,NÒàÚ֘ƻéÈóÃ@ÜaÏg.ÂÿõÈt•èXC´!^êi¼Ôn²3Š<®mðú!¨Ö-¿Ê€ÿÂ:ð²m*|v•ð¥úfédèbªVsš#‚qÃ/¡z/Ö¥r$ÓšEuõ+8Á-•' 9&í²qizøÎ–Ý›9FQHô"|ˆ <ˆ3áxßãÁ|ú9åªÊò*ЊÛÐ?_ÑAGÚ^ÓÌZå`Vu{b zO@¿[ý_{¼ÄÉöDiÞøÂ/WÞ9^¤ž‹Ÿ±D=&ØÚfÁò=ÕäkªI{耬úô4=lâ]² ãtÆ­µÌññ˜Õ–ôa‘ƒô†#ïýÑðÎöý Ú>Œ6“Kfáôhà{é‚^kí¶j'¯[[hV{l¢2‰²|Óˆ ¸Âx)ô))†YLŠq2æÅ–SáƬ›¥Ã¢Þ› |A©¢H$4pù6íØWðvkIJצþCU ÊüS ÷¾'ëç8üŽõG:%8oceò°[âìmìó<×ÜÖb|oR±íVÜ:‚ªœå½ÚîÚbÝ{G -ƒÑÓºB¤Ñ[ÍýÅ÷³õ¥ûò´ðæ(ÐÔ d!˜c5÷ÚäÑΖHï 6¨y÷¤íóà>¨1½ÂíVÀÛc÷ûÔT ŽóŽI§KÒw"ä9Z &Xïp²4*Âqw/úE€»ˆv_¿[d¾ í13*–uñÀeÑ´,åRWÐ'ŠzP=8’ù¾¹&ÐÁ‹Κðcç4þ$%71/Tç´¸J^õBM*…!Òí"¼Ñ«8g8Ø Ë¦<óv^„*Ä‚p·%ƒ{ÞòõœwŽ.¼¯S>­ö´³=eÔ¿ÀCO³&¿ÍFZè€k*ÙŽpÔ¸Óáí"­Úl+äÑÔ—q bv²ø_Þø^´·£0ýpÐ'Þbaš!wYá:Œ ·ÀH{?½È<02$f§üeeGÑ“Jr穯8êã–j¬ñ‰Åú’šy$†¿Áá'"¬«—"ÑÀ¬æ·­!tÄbìR­ã|H‰%§II›ˆ”zR÷×ʧ(z„<íþÄ× 1oÑXñºÉgIUàÞø%~^\ú€[ŽÎŽdÁ%äýÕ¢j~Ä%èOhC¾ÌÐøuE/é^³Ö"ûíöM ÛE'€&EžÄTí—n4imÆ%h*ŒƒV€7Ü–©&P¿þ”Þ÷k,ìrêòЯâGTÅÐ ’Ô¥‚ ñ²J•-žŸwDO” \Pm Ø.Lˆ¨žƒ´CÖùÃT+{MÉüÑÍÐ]ž±™dHEsb”ÐeáD‹Çú;‚8e0Ž+xgjÖriâ;v?€|jÑLÝ&/ :ܳ,æk–Ö±¸¹Wû‰¬P¹ŽˆºM“ÞÄ­¦þ/²]ñ„$yƒ+ Ø3¼Ü‚B@¯r+ˆ»‘ ‚è)“̃ŒÃˆÓ„ÚÊâ¾â½ Ÿ© ¶3ŠsŸ~¨!?w¬¦ÖœŸ¼t£l ÐÓÄεBບCÒ3Ð+R’2ë³"Ùö W-×óé$¬T]\f~Áiä`ÄyÕ§çwëz~’ÀC8š~}rz"d„kL#¾Íg<†<ëSTF¶ÕCèìSô |íU¢*É`Hq!è=|»m2‹s±JgÌÍí#2°=¯kv ìaö5<øå¶@¡m›,Y‘}[+2mV&ü‘÷ÃGò±Qö„ùÚVXç‚<÷+%âË«ªÏF'cÇÜ¿úHË;%¾ëu–v±ïqJ¶Sú½Ô`ÑŽüê`%{™ô5óìm瑬P ã@Ä2©&—¹þs\x«°ašfo¬æøú=6Æl7-Çr^b,¬†Ð'Á‰x‰Ë¼|»IÕco-¬šÝ/“} ‚ü¾ÒÖ«ŸhSjD6I›&Eï¦@å[ÚR„h•~¶NMHbÖwµÞ”ZÌÇáøÑt¹˜‡ïu=^\TWò†y÷™´å*ð¨(\¬ïÇ–«Kvÿì€ þ9zï T†Cj™ðäû1‘J®ç9¤:k0}õ¶Ú¬ØW‘,ŽÉÊ¥sºí-îïgjòޏ0hëõ±è°‚^ K»=, ãõv5¡i¢ë£i¬òz5L¦BïÁÇĈ–»ÊÌ-\iÄYžA†ŸÞw+×Õ&¯ëÉ#Ÿ¢éUäyñ‰…·^]EÔh²Rç^0&aû˜¶®©;d­ N ``6¦r® оÁ‘t¶?ˆø¯›zÛý¬þ‡Á´eÖÑåíÈïó!ì´;‡pÖ&Î'/4Íì#åçDä7À`¤åDDKÙ©~II¹e×òc¼]ÕkµòÏœÆDšHeEˆ,Qó5õö÷6øªÎÒÕèaU¹¤@úL}ä:ÍÐ Ghùóï¶èÂß.[ªVÂÏ\vÔE„èŸxí÷áS¹yE£ Òã“3|ˆµÓ×±ÝÀ-ûúé¡/oÊö|þvIG~ `­@:<ÊU––Íú,h¾@u¦Ì‡ÙìlD2¾Åï7êu™Â™$ËÃ"Dj@æoÛ2λ*­` |÷åàã!6•Ƚ‚sÅùí¤lŒ°ä"aËuh‹öˆíkqrY¬“«ßÍûã ¼‡Ÿìdú¯Cô^•M~|¼«Ëv…>åúaïÈŠÒö³ ø¦Ä&fé ÞTkç0¦&R,~)¸RšprÁ@K,p¥:-މÉìž©ˆT•Ù[m€V¬+€q8»*é<.‚îÈ´oÃàAb(ý^I~¿Û»Ó>“>¨&ÊÒZÂlÁº]ê–0=sMÂtÌrawú3ƹ\[s¦gäIO\ŽÜ0C¥V%žoѶ®˜ÚºAc¥[Xž1ƒw¢GNSÐŒ³ÑHmP*ŒmWi~aÃÐ,nß‚±"¦|Ç•Mዳ¢ž­n1ýÑÊslÊÚ™faXñ  zèv\]Äôqgè'x–›D7¡ŽD'ï³ë~ a}_Á~”¢\v äo—¢Ö^ål‰JíVë·ñú°U¼"Éš’Û ïø^ÏÞ[ÄbÁm±kÚ·qlL®NÒ'n†%—–“È%-8a¹“ŠO¨JÛÀ9Ôq·7+š¢úlû†k)î+¡ÚíÚá»ã‘)x…Ÿègo|¦Ò³H};µ´JEgksAWNeQ‰óy þ¤cÜeÛÜÑ´pý^é4‰Wú%R]‡QT•lÄgʶ)îä`dml'ï`¹`â'‰…±H½™a=‰µË¼úNÌ2¶7&\²|M¦/ÿÀH5‚@jÆÃÜ+šJjó¨È¼Q¢ë ž¿í1¶®­[À̪ø:Î*…È!|¬‰aÙh5ù Ñ#>óaqQ•”8‘z9÷ÊÓ•}%GÐðǤ£¥BAi¢†ûn4ÍùÛ'ÏÖ í`Nv®äÆ#É‘wTæòÓ•Í:!T Ó8Ćjs¢C’vz1¿$vVB"?:|aaj¤2«f›¬›¦úD‹O>ɸ¬ö¾°¿2–†øW—„?º"v ‹‚9EÇk>{`ã‹«ÚË$°…‰d†¦Æ¥nVŒM˾6®Å4ðP’ÿsoó{„[þõâ/VYRÞýÞOͽuÒ~”WòO ‡o÷Eà¦>ï\±ÖËoÔa°§…ø’HtÈ!Cí‹××ÒC{"–™‘·"Û`ó†‚Q­Zh²É~ ™²S’ÈÔ;åøå„Æ×ç*ë [“5krÔɟߌ¿rÏ ›Ñ¦Ü”¬[å5A¿ oÊ‘ X$‰ô~¶öÓ ¾qn†–U*kFù“‘Ôšž¹ýkÉ5;k“Lž½íŒ™â³8aTN§uUሀesÔëÑÉl<;ýsÙ|¨¸À>+Â<Ù}‹—hæ‹o™PuÚñrˆ§Ó¨ì»–꣆«~ký¨=›èSÞçßBq¯´AWJÖ¾cºr—Á]t>H~Fè||1’Á’¬™³HÄ¿_Ù—ŽZÂx“"&‰L¹³>öî¶‹ü„Íê8×{ˆ×.)˜!¾¬ª‹¼¸ñ0xw2ä…fù¯° ¥J¦#¢È ‹’í2uÊi"†)T'…®JoèüfF Ä& äE>]À-/¢õÎ %@MçûNABMÝ|·´ï"XƒZ‘÷£FùuÍÓN¶J#ù£H_¡$S©EËõ\”HKEݨŸ¤1¦# NÌIŠÂañ^6䡺ҕ•b:ÇÞ:`33¿t§1˜-9.tRÙÙnXiÚº°›ò½I£u¿h·ùöbºêûŠ En’䈷Ftç†éí'½ü!Ë%åÕôÏx\/j9ÕˆjEü»Ý9Î,™™›xܺUÂ]±”ß½v4±n Ô².È·#K¼†(Œ”…Ñ4¾ªDÉ{­£(pMbø;åBÉmŠž9q¼—È—.±³k½€!‚&þäC˜&bœÔp™öÆ"¸ë¾\"¯ɽБ°Z­anî6²»$Èʃh+3ô›ðñ2Q³a“!®§oå“j ÏS¿¿ó¿¹z\ô¾t±Çò¤tÓX›°Îħ&óŠp‰è9ó·VyŸ¡FÌÀ ()fJC#1õX¸±l§o“4Òß ;W°Píy\¿|-ì1_ÍöB¾°DÉ®Šß~º?H^Ã}¥_Ry éSQyÕ)§Ò¶‡I¤•ù;Ô;èr0iÂÔää†ê‚hp1ð!œ%/ÜnÛ`ãz¹‘ G®£…õÏyÃMÏ^¢ÂŠt¿¨`’¢Ä‘#*ìMøá¥±hµÊŠÈàšÁö ˆ7—ºæÐµäEéÅÊ­½öÇÓÉz³µÝx£¼bÞ Ýõ’>[Ã\ÅxjãÌ12©"(¥b®GDÌJúd|uï¹’Ðf¥mì ;R ñ'cîk8g耠*;æ6£Yç3øG GÂJ˜kÎxùVn:Tu=«‹úsõœHÉ]ip}¹Óu¨6v§÷÷ó…*Kn¬„†”€4ŸÚcX¬o“ô*L‹,/eæO貃woª¹‡ñÔDÀ54ÚÒ0Kt‰6’¥*¢ë,q£nqõÆá&~îþJÊ¡Éi7TtÍd•»­E49v4eF™-UÁ¦;Ô7YÎå=ú¥1³Nåæ*9ÞUL²÷Ik¾!ŒØÛ·@o„½ÚDwB Ïíï„âK²VðþmX´_ï÷wènÞÖ'&PXu¡bÜCu ˜PÈr lÒO€ûÌö0mÝW³¡«1oHAšz³bPÊœ`¡8jÿD” öëvÂBG²Æ¯OMÕÞÚ]Fî³^ QTÚ&Ûc ÑÁW¥ÐÑukSXb/§¾3¥ÝoRÖõÎeo®Œ‡ †Ë¢È!ª£m²ãõŒÓ³Ù”¢e™*ñDª]ÏA'>)à°¯5_Z\áT³yû™þzýþ†ÓåòÓäªi¯ˆÔJ„ÜÒ}ÁÏ ©õß0ø×5ðºe.Æãy¶ ú¢}ÞÎq—Ö±#gg µ¸m‰exõMp´d’öŽ»ÝÂÙsÌWBr7Å“ŸÒ¦Œf4ÌïC×Ô‚ëàk°#B›B˜×¥yH L1†àëÁ °IâW 9B›‰òw"4’EƼ%Ñ==,³Š»‚mvd—/ˆð eA‡²¿"PzmsÐ[ØÞrh¢7¯ÄzSpÆY/dØì¶ˆ¨Ó9G® ë%}©_¼^rQޤÁèSÀc’ ù±¾dË1ÃÀ¶!-¤˜˜f¾"}|ôõ•ÈÇSŽ9¤}¡}»Q[å¢[Ýê伉ñŸf=8½k«•Â]ÌÖ™)§?{’•köƿ™6Ó„Ú‹-ºn.u e6Z·Wä íŠz¶¹Vw oä/G"ÁèqùkðÄßN;†SÑC–Õĺ)÷jÌé“ê°G_¤/Ê‹z­Ð<©RE]¥6t!ÝûaÜ¡úåJ@ÆHy`žÿZ¸æüiq%Õ÷ :“ÖÏÜ2ÉZ“XÅW'ÅЈ\ ‰yx¨ `÷È2½œÊ×»3¸dg™´œI¥ªøùŒ"¿LX5sʇ6?7  WŒÙš&Ì[Óÿ0Üÿ|F·~õÖwséʆ’ºzúá+/},pæÑ#âÄý©®ÞkfTxÐïŽÔ×X³—Û53 Hxá:Ÿ3£•Ÿ6Añ§Ín`ô+6%µU*?Ý;-*olp v#Ã/8îEÞÇ—ÀøôÇÀ¾bÿ)Üó¹Y"Õ般1 ÒqÞ{`rw2ãÞÑÓW-^ÒFîù®áƒÑ²/Éz1Wü|ÙDª] -Ø|ùª“êº ™Sƒ»wmNß¾·ñ_Ã>!º?3¸×cd‘wbÊ&ŽV0$Ë›‰xy€PÑnñÅ1‡=ÔϾKnÆJi£ïytÞ]Ú¬ª}XÃ"`ûîÝ;J¿\}0š |£ G?L™©‹¾DçÙ{H¿=©1Ö>ʽ÷5Ì<$±Í‘s΋}¿IÈòV¨æÔK$IlÜqY3k ¹]&ßܯI6êÒú2_ãX·%”,­M…¢Év ¥ÿÊE˜šˆ‰™üî–1p7¢„ÞôãÆpGÞ§ï?Ã⛨=¤ÍþÀrgDf&Þë2Êótäé3| $AÓ­O÷aå«Ò³Åë!ÛÊ'%ëtùŽ=C‡³ s’™1)šRIxsÙvì¿.Ö£²ð…üpÛ[ø£oµFžfž9Û­:c••g‘l®ëîg%“í£aÔ}ÔÔøŠ–% Ÿ`=»Èæp÷Jn ݦ£™…b¸Ë-×JޏÂ0ÎL>f9ë½´_íHWº³®rætFr®'a.§¹ï€DôxÛ#+#çÍmK&ω\d6†ª¬ÀGÉzaWŒ~œ>p–EØ çŠS“ña·EX•FTÔäq×kKWä˜ ÔØ‡úo/<=Eç4©B­üX\ûe'¾ƒ%%íÍ7pº3gÎY‚¼[}ƨýî£  (åU06ËÏ(ÌÛv"BySYÎã-üœ`r ‹î <ÎÙ^ ÿ Äô"þøI‰Š¯iêMµLãÊÙÚ[Skt;ÚרG¥2õ.YYU–i6ÁV¢ ?"k¦À›ß÷û=‹l’ÏWÀ÷ˆJНCе³ Ü„V]Ò˜­S1_` ±Òä|ñÏðò“ùì®§µ„ÓTÚÝû-(ˆðäWhfqŒèâ¡4Dôè]ŤßXô¹À ûÛáв·À R™ ˜ywœcáwËd@zˆ¹D•å{'‹ÓkÔ&¤.wÁ­¸ä°oK¬ƒæ+ç˜ó}aÞ­”öÇZãûomöh©jAéú µÎ£BšÜ¤9}u>gC»~wùjã¸&&ÚKtÉ"²S[ýÑú@fÏ…‡tŒU‘è šC„tQÅÏvýaÝÄ~» #^ëg/Ûµ± g>–“wÚð“÷âr¦" À÷t10X=Àµ\´a#²óÁþ¤·]+{7ƒãzžÑ{Ô;c &BÉE×-Ts¢ÊìÅhT‡=Š}‰PŒ‰tM¨2.[ ÎÂ1èÕ/t¾ÝˆZVȨ4æýHÓ²d&*¶1³é¹ö§¬½Ú6%áúž²™Þ­Kã^·ÍçÌÄ¡ˆ‰35싳NäåÍåüÊœ,ñŒ“=•=žø¶}ÁûÛî¶³·ìc$<µX—IFôd¶t`˧$¿ðïÈù—•²)NLËo¿Bý(ͽ”1PžJÍ8‰¨;`z[Îùý%ûZAã xfÇ2´z˜Ã­Ä¡ØBý-峘D¦jÕ-Zuè6ÊξÄ>1;Ë~ní³i«Õ‡jB ÓÄG–²öíÒþaÑ>¬i¡€Ë¤Žw²OÒððG*gTqÐ-–Ñ*WØ‘Z@<þL@pKëݽŽñO‘ëÒ¡O "0¨„æb;¶üBd1‚N2éf8·‘@[(¶m‘‚!‚˜ÜNC«Bø-âfqJ$áVYðñ¾odÉbp»\Á:¢98\<Ûà[wË^G5¼ŒX9GŽ%ÝSf€VáãÞ¹xV­äªæ“øû~–ú M—³œèϘª„4ìû«óÇ6j.äŒàÍ#AŒ¡+õX5™L؃yÇ€[ª¯âÛY<,!6Xúá¼6·UYRß;ê«àW/Ø®ëߛ݅%)Ió#©înh‚Ø:™ì å"‚Ý÷è…¦ ´>¡TWCÅ©4“ƒ_È<žu´¢!Ø7'óþpI}Á÷IH‡ºÇ`ÊO¦¦ŒTáõñe5ZЗ¸7vï$1a9¹x•í3ae©ÃÌ…R/ª¬ Íï>S¿—òfDb°¦¼³–Ѱ…Iueôñüƒpâ}®W_]É%a…Vø©p¨&Š­×œDºú×T` ¨sãæg°ŸLºeñ-g-W)òìõ¥BȤ>ÒŽr ÎNRLC+Øe`ý`øà.$Üêyìðuº9‚#¥Z¾…g¨X9e>G1ÉÅYÅÌŒÔ9ø Ú¯txí))!^)ÆðcÈ&IÊ0<1fȇ|.8¦?«Ÿ›[z©±øÝËGñ ‡[õ¹F¢y–…Œ9+y¾± IG„Ç»ÃÃÅèKvëÌÿñmÉdÀì…G¹‡¨:œh¾˜@ Ì—?%îßE!å)'O$¯.˜+u ?ˆC‚fÁ,ÿŒðë'˜ã]ùN­ëM“Ëõ7’˜#8Sb•ïÒª¼¤T† M®*MèŸz‘À¾ÿ‰› “-­LÊ->ØA'NœÃß!lÞY"F©.=ˆfÐJíxÔû!b—*wÍXh‹=Qñ²­¦ˆ”z¿±Ý(еÿÝ­¶’{³–¿ž²nBÀ$§Ù‡Ò†<ßbþä!½»Å€º§½}0¦lcÚ[úq¤áɦ[ÂNžÇúÆ4‘">„™7«ÑïM$Q>ñ¤13Íâq:´!ÞHoËs5“Úc‰<’Pé¡# ·1ˆ[šÔ6Eóä˜ì‘â,¡ø2†okÒóD o„Q1߈½tÊÇÁ|uxЋ‰mP-Íßv•ÿÄÙ¯KÒ§€âüBo†w“h|„è&èEx1ê ùI”M¾†¡6ß ›¯Àä²,Œ9C6d»ò)yUz—BUz8DŽŽ‹9+!sº¾NJª-G¶†õó^EͲ|R)ñÈ”–Ñἃ ‡´Z3¬À’ÂäÅ-ø0v£=:÷”»AõДûI{²x~mçK>”˜6ÑfkÄ`£”Gäƒ[óýE¼x,1Ŧ¶>ÞvBR-Êþ{Íš{Ö$ä_ÇüªXm'ö9®7îà裸…]¼lBŸÅbX6Ûs%%®Á]Ú¢•~¥@~`¸¢?ª¥~#ÔùmÔ¡ìu8YL ®|pþ]ËJdî’…jÞˆŸ“bš¼¶Íê°Ù˜Ú¢#œgTy_ë×õ›Gò³ÿ_ÿ<Ã)%oÛF[kîxÙÇê‚ð  e¥"Û`ÒÛeû IzwFÑÑ’jšï_ ¡¶g-»Ü@ÜÚÛFvík¡i_i8„ý1V_¡µ•—Ͳt<ÔC–+cŠË¨5ߥ㶤ÝÔÆí¢•ë’ºP8!¼Ší×´Fª©+‹ÏL<5í'Fh{6WÆü)Ö …7\Wò~X–’è1ÊN†èGz¦Ÿà‡^™|¹RO»VšÞð$d¥} À§P„‘û¢ð»È"[qõ©µcß0ðniÞQm‘RïþdãÃa\§/ô å~|‰M•rØ?­2ø “ vÌ`?î§š0öóæL O8³WÞãæ³MÏ3d™_¶„ˆHã—Šíç BQ 6åþBšš$G[É.!‡Ár,ª*jãÓpöiäP¡bMU{g˜é÷“æÏ3®ÒbÁ³XàÕ/û‚µ‡óÜ4S*ósÞA_DQzî¸@ŽyÇð — ß°tâ"¶BmŠõw¥·ò°Pº ºÑ§ªÒ1*( SCO3Ô8½Žíh^mL4ô×(éè gqò¬­Üþ{ŸW ö5 ßÙ„g. Á¹;´†—F×ÜR{œÕôº¨F‘lôê(šñDVш 4_ÚZ„I¼±é…ŒëÌnZ¶ògæê p ŸÃõ4RÓ4ÁûŒçÆÏ$ú[‰€om hÂö(¤Ý|–Ž—êÚk±h Ç ÞÁ>ËÐðG_¸5¯M%d‰_¢Ç•Gð©"f·$cÍ}ÛŒâVTs¬Ú·ZÑT^zd¹ ¢Wá*e®<ˆC8G­=\O5¹¹´u}XyµY ©(i‡¤˜©êy5ŽÑe(ÒŽPã{¾±ÑUEd]Ç¨Ô ÿ¢’Ѻ$à3E7'íK–ðHS²ÚAhÿ{QB^e¢§ü·ˆ#‡ÈQtü2¦xwi˜PyÖ ÷1—~5ߨCæè0'}3·#[Ÿ&¥z&øœ™ Ûß*Nz>²Áupûо=³3Љ(9Fn1ñ˜é‹¾ ùÈ:±Ô\tçÚ®l[úž…Ôø"wtRS¢ÂjNæ'.Áó›·à\6Í æžœðÝ*5î$©¨ÕâÝ·LÄÄ-ÜŸv„oqÜò1£¨"ÔÒò;<0}ÛSÖ eU]ÎaÀ Vòû×Ä„5éÚ|,;rR3Ž"@*0È#Ýe]¬G#Zº/šzÙœ2:Òá®(àHMù-‹_{!î³J72µ£o½ß,úƒÝ]BQ;ZI<5e“µöíb b[OŒœ©øG‚…£˜îZf&é†ée:Cn°4Ý þ‡g§•Ãç‘(%»’´Ÿ]1ôŸVRd43E«ø É³\´û9&ùÁmƒzKArµ¸V‹J7T'råôÏ #‡"iQñ ”Ogš/Røá„Y#4Ž\všÙh§ø0ë´#°õ]9’É¿' óP„“æ"8¥!ÏÁañÑÛZ ù6¹<Á]引¯ã St^$’lž!Meà‡"Üæ¥v.Û‡êJØ ÃY ÷«™è ý«À„¼ß¢ñ[^YçS/ÌÖº88†°á™œ%ÕçàÍljñ(—å—Ó¬õ2\é»W]\•ë^ké!·³åJ³ˆêqf9ÏÐp¿t@÷l’K ‘®n¯j/‘Yì=’†§õš”2NwøAOCt®½Ê#.KÇRÈ®8Lt6€qûÌÙߪµé?:ìía(sl-%ôÊ+/DâÔ\ÞÃé¾—W¬ÀÏO)Ã1ÃtÐaDÒPãVœtAoGÞ‡e@ËŠ^¢IÞŸˆ+_fŒ¬…;}zÿv=ÓŽsU¿¼ºå·nL7)ª«¥ÍÌwY\aƒY‚ ºOKœÊR…\wŽeE[Õ:‰x‰€RŤaoóô¯ƒ[0]ý€Ä^#NäÐî.7œ·½Û_ÚÏÏ GÓ¡Äõ“UÑ ¯`#QM˜Oa¿ÚVe°Äêæ ¸ y&Ô̜쎙V¿°„cÿ‰gã\©Á&mG¤ö|úËwt^Ý÷ ›j&=ªw8’6‰ùo£ú†ªLP<|¢ÐW±¹äÐtbr8‹'¶¯jìúg-Pê$©Áyú'*pû)GPJÜCMIõœðê ]‰¢^Gyäí…ôÝúÎ#1ÈÓ]±†“i¨Ú©>ÑEñ¶Qo2£v‹Ç×N±!n‘ïQÄ®fxlŠÛŒu ïBV¥Wõ¿ué'ýÒwÜÚjÈoÀšc†•äÿ>>`8uEq†° ¢èÌÈøò‰é¤xŸ>œ2 W¯¿+!Õí¯’1. zN¥âÿ;8u=ÖtÑ+wA@2¶9V-Ïf(’×}Þªî=7èdè—n£ÂãÓ&a.¿rp›|o(ø~69Б’/I”g"ïÔóû¥­™æhÁN¢ÐKCçNJLWñCñï[<|…7¥üЙPÅ yF|ísmžáú€Ìo;{è±°/$bÛ«M…%—¬ª¢Ü›•5,ÜüX¸ ° b–]–ù½Tû„~F“oHoÖa5fĉ;ó–üÚ¢i•jãÌâÅöä‰tôiŽîÐè`S{à^eÔð¥ÙVö›K.Ë[r \ê[xí<Û™uœ'ûKDš9±¬@ß«¸'yC¥€ j@k’î´$óéì@]‚U’’α¥üFÑ:ÔKÂ܃“‡({=s¢>ƒúˆ`Œ^‹\ã¶²_C¾èè°° Ð.›¤VèÕg¯ço–KŸq{Ò‡©LùËôöÂÊÇ'òLµò²>“£Ëp;bø`ÞˆÃej}•Zèž ¬”nü-¡l­ËΟ|RKà•—ˆMT—œ\Ú¨Š»ÞlX¨úAŸ1 ¸½Ðgõ>AûâP›ÝM¢ª,÷€ÚÛÒþŒäH÷å6ZÄtæÙ÷NWõ¥UÚv{{°»U@”wÉ‹G¨i~í4Ý~ Ø©0¯Ýޢ𽛿*ƒplÅu–»Ã&rÊSßlÑÀ?|¯úÌì#›X—o”CL·ƒ4ØtÃYüHzü®y4Öó·’¡%{Ÿõ뻀¦B^ºý&p£Ý##×kÆ™MÝÁ ìz&¯|ÖÃÝò~çß²?RbÖLrºgΤc;îþ¶‹Í‘Ò ûÐ=r”^»½ñ2Yu5ubÉÚdÚ*Sx‰²¡6;$Ù™uŒYX"­ô q½çêa÷G«†bÛ‰Ê1òƒ¼‡l{3N~²WJ·ªw{/RÙB:°¯K9üV˜  Ðêp¯x¥·ò°Pº&çÛ=é»ÕÍÅwF‘–Huamó»øÇJD<$g¾ípu¶u6y/Q»*$1Ïq‘.ÓgK\–ón·P'nËJFÐæKPzÙ9ùÏêseÇeîAª+S¹ g¿É¬ÞŒÍe›TNǪ„·¿¹b;=~Y•G›B³1îéH1Ҟמ´n/–†Oí&Bþó‹0]æöCOjzÆ·‰]÷3<gåÚYn%ó’iH’†€¾êïM' ²Nö¨1ªðOà’ 5&†v|§Q@3z Õs9]ù0ÌÖ»Íy!‰¡/É6k§Nýg¢+Ný¾&ÔáO•±•žê” a N²Ô—íƒÆð3FÌqó˜"Q­ ßÊ÷Wª¿·EË÷Q˜“q/¾‰Ò¦‹Çyl* š$K*ˆÀh5±H´äW#3²( °~í&ì ÿRöX}\g×®¿ ‹‚üŒƒ‹À 4•WÕ{Ldè‰ý¼Áë@ô¾oµ1*4_ñ‹›Ũ¾ x0Yý:,×Õ•‹Ég7"WÏ,éŒ|*leŸ>æÖÕòBõí…æ0HàÝCÌX¾µÓ r’ýƒ¶à'ì™W^òìªÇd‘“„=iNl¥“À8… Qn1:ü .«hÑ+±ÁUeŒc¾mf-„$½HÚH>µzYT¹tûX˜áSDä`) w¾cÙL›ËGjÝ…„«¨Rx§ªst.Úåóµ09yÎ,ˆ1bP´I‡J(k}Î M[Q†K4Sè·VGÁAt -(jüÀ|š¥‰$Üß[ycæì‘{Æþ'æÂ?¿S*Þæ¬…¯?6ß_×ãe—–?[=‰Ük´B FÏJô×l„4æjÛr¶q 0·àâ”%&ñ%Ø¢9¸¬pã&*ö¤CÀ¬›b÷çG²,ÊHµ¸2A'œ·¶®nµóNõ£ìGÅTí-—*Xºý‰/pþ‰ˆ}ˆ®|PA½¹{«€=ýíL¾äÜ#cmâ72<L\Š"é@ÄV‘ñ(³$Ð¢šØ¼ ƒ¯½¾É°0®zRâk<Ùÿ2iêI:‡ZB5ËZq?ßvÚ·‡T^Ênò §ˆ•¶í“‚Ô_Õ8#e`ö©•~q9„ÕqšSë½A³iÏgøËßÄFÊêÔ‘4è [ÅE.뇋²Š PAêK…ÆÏ×4«ñCâ¢SÏ~NFèõ¶%¸‹FC¨ðFˆãޝ¼ÅS µ¹ \ü0P—\¥1¥Ô§O‘üºc¯ÓD»"ô†¿_M+…"—^…ŽQ‘ƒ±*R.ÿSˆ‹Óbã°Ù­²´h‚UÝnè8×}Ûû7uî~„cÿ÷° ?{Y1«$ðiíR/ؤ5§ÿà˜—Œ'wÙ]m™³rÑcÇã´´çï0pÌÇYÖŽœ…Ðpãkº75ÔE™(¯¤ŸÒr>áv¤ Vy©s¼#³Ñe|žËÚµ"áô¨ì”ñ‘˜Õîš}²-XOǶùÃ\GÖ9ùžÝ«+åfä ¢°¨…Ó#i‚T;©ö ;Q™ŠìVШL9e99cû¾Øníö±R=µe»Ã¡î˜ÄéKZ‚MEkpv¥€!· ¸žÄ¹Fy9D÷WỲ᤯Z²°ñu•Ö­ ¹²ÀÄbgq{o{‘#,hQTG=ˆi@ÛñÇJŒ‚²RHw«§3[ÒúÍUùᢿW*v`½O™ç–c¿€±E¸®êp^è±Æ+ ¸TK¢A•'ë“¥âÃs¿fm±&ªˆ…o¯¼ÑÔ‘UTÏŸU•µjŠ>©¼³>¨IŽ×r}'?ö¾]UÈ‹0¯&V”Òº‡«Q^O„ælûÿo¨Îj”ÅÙ¦½$–~Pfúíåõ ,?RÓIGà–Mމö< +é­Ò¦ˆ;ô“={³1Ï ¥é.[û‰E0èðmÒÐ,œØ¥/íK”»¹£Î½¸vÓykU[yÖ›SÏ÷ xÀùÚS±æÂ×_fÈ>ˆZtŽ)–‰Qñ§ñ[eÔßš}b› ‚4¡5ƒôÅÓ,9ÖðY ÜI:8½²!érÖ 6s¼pI‰‰jkùÁ¸oÀ ô>ž•Ç”añ6Žqž:=\ŒúæJ2Ò‰û™¯ ¤ÚÃÅ'—g-/bî·!…ñðm»þ JŠI(U”É_~ŒX"œóY\"ÙÜ6ÿ,ÆÉ™i­úµxG›}1~ ´WŽÔs%¢!éÉ;Ä)¿ª@ 'LáÍÑHrK%a«T¦r¬.ó½?£ÅXŠA*&K‚|`PÜÎw{ykh ²µðíóÎGï#X8:Œß@ÑaŽ@YÜO¸ ¯J‘}Ç7uBß™¨«L +TDËRï»÷]Ëý̲m{M%c»nDü*ý=lž….Oîö’m® ¡­Ác^ÕaFu½H»ŠŒY è>­ß5r’Èò I'q=íÄ®ª–¢£ÐñB éfQ^$ðE(90,ýŒ?Çï¬[Åö#F^u¨cxH\0 dD“PÍmé;zg]µ·õ©1„ˆi4û(úh³xHÁOù3ÎH®aí_„è0ȶêTV¹Û‘Ÿ ›ýÅrÚ3´›!½MÕt•¨ŸG/¿ËíqBÖ‹7¢fø UȬ3 Ù Ðø5ÔÅØñO²Ö»¥±ï`ô½Ïn½‘þ’(ÈåŽãó”JÀ{‰ï“ùþc ©šû“ÓTƒX×bªÉFÂäçO:®D R^ì'Àvs+Å꬜™jgÐFIžGL›ÀGb+ÓÊþH°@×UKepÈPµ_Z·Èùo‰Ùe=—ópV¥Žµ'aÇ©‚•˜çpåä{:ù‡q£d‹X‰V×ï³Ä8ï±°[§)*Ä•²>«‡³9¦Çànñ`Øíž DI(¨2mòrúåÐZ.f韋7ðVXæ÷w¶»3fà[Rdµ@¬LM«OÕðjŠ*ôqbùDîÞn° ¶Çg›ô04yc.\µ¨V1¡ ÐçN³˜ç`{ñ*«²ôÌÏØ¨~ÇÑŦÀðdøkbÖ;À^m;·p¯›Zt~°+Q#µê"Æ:ÖÞ´ÀcÄ‹ž®¢b½¿ç[uTí%VB * U&ð›VæÏbntU9*F•$4ŒWÌ?/Òú‹ ïRÄŒGŽ­òå<±Ê#£3½A|œ:G¹E†]BÊÎ@ªþÿè+) èKgšK-ïbð'ZêGAhÖj¨éPú,Œö¶Ï€³ åGÁûÆ7­ó [ ¼HíýJ½ý殺E#§HÛàJg{1Üs£BCÆë™XæSª ugà AnD‘Ëõ«M±‡]}€9k¦kiÜÄP öðõÃÙ 'áû± z—ýGF‰Q0[÷³¸Lc¢ûÖ°ñnSÞý"UáXgRÀRönŠª6(NõK"Ü+77¹éæ×$-˜„("î‘Ê_TÛ´Ú$Ñ4—ëæ3l÷²={Å’l¨bc„üú÷˜·.[Q˜ewàyPB¥Ü=ºK™±F“ûÃSýÕ:“^U}ð–tó]~[8 Ñ© Ñ` ó?øgëoˆZó‚w5 $Â!?%1‘6ª9|ûRÓÛ™gûO5Š·WÖùÜ¢Fĵóתh&•„»  @¬,ð-Fc+C)—7Y¤‹Jå‹LR–$N5Vo†gd û©d`)[ÁUà?´ÝoQo§ÕÔyªõBö½trsµà³ð-¢V0±UtÜîÀ/§ã¦ut*-&6gd–Gã›F¯¯s -wž¶ÈÃÍfYÓ¢™dŒ%GæÕÐlšn;ÝÍé2Ì£~`3ë1>pÞÆlJãÕã0nÃEô´dð_«Í*çÊ4ÎTE«ÉRmô‹bµŠ©uý1?™N)JB´‘QÑŒGö™÷ [©ku™-K`ñÏ©‰ Ò¨Ï¯·Ñ4o§Z•c£³Ÿ7èVáãšÝj·KInþmˆÙK\)J*Œ&2H2yU6Rƒ6åìÔAØÃ4ã;4ø±+½cádr™Àuس(¦=WâÈ1vGä ÉÆ%&/;9YÀšÞ#vpð ]SÿëiW’{)ðl£+¶VM`ªIÈ‹M4c–fh¸!WÅ1íñxŽj–¿š¦¨iónm´ÂÓ4ƒ›u3*ÎnSÿqÁ {!’è1«'“%v¶ÇÔ=•­Ñfަ¾x#ܵòT|:{”¼Ë^UêKÏj\JýMhÁ@ÆÎ#ÚꂊöÑៅHÓÿ|X¤×Óį㘌hùù œE6×ä„~Ä{¯ðŽYÿ*mƒþ8EÁ˜=‚Xµc$d¢†X& /ÏØ â¼4®ØY6…‘w”0Y ²rç6¹ŸŒ/r9°=-ÍhÌ‘%v6ù2åUÉÆ9Óf+4v¿€‘3ÿ# úg‡Çÿ«åÎ!|d2©r*… «åˆ3hBœTôɃû«öBÞ`wpcÏT–F÷Q|ÏØ•©U =©_9Z¿!è>%”Kö±uFºËbä ;j@€CËúÙ£ºÝühÜÏgåá_ÜÀu.·¨$uñß·I¾ªTôCÄ).N­ZLë88u}öµ¶ÑuPT3‡ûb©·…$˜ÿšúÜó^“Za@i4>mÓP£ÎÞD-6>Ô8±T «ƒ<•{‰vUHÈâ.›þl`?©e2úøÌz•«^Dë‡|oH:ꉉ”_ä’ÀǃD«Âu.=kËÃnŠö.[#n¢€&a%^¾Ü`Ÿþ¬–Ì/¯9‰ww}]þÕG'¶/(àØ¡F<)­–2Í+9Þ½g`ÜŸ£TUpǯ)[Í©J##„ázÌí-ÿV¾¨»]ÕæÃï™A¡‡÷·/šÔ–B§6#Ù‹WÞnN; °Øõßg¹ƒ2sù(ëxtZÞF¹”åv‹ËÔ¥À—Zxf‹I Ã|ë¬îrpêaèvBoE'K{ø¥äuj-K•*Y`$—ycMSÃpáÌõÏÿßýÁ)ôkfBЉַbŸ1ܹÿ¬–^×6 A­W)ÇþTdæǤâ<2Aðf i™ˆzÔÑ-Û˜øãzíåŦêüì»á6`Õ69ö¬Öñ¸¨:èOŽÌìÐÍútýµ˜ecá¡IŒ9@»9r‹"xò²Lé†_ -cXDüž«kà‰o­ÎÎÙ"5þ©{Äi0žÚ…Þä]yÏ•Y’oÙeÊÀ\_\gn xod_›»Ÿ`ÚþXv|J\F¡B]DðÅÐr/ý2ˆ}2ÎY•y¾™ëÌäÙ¥os´|˜©]œ3¬š¸÷4Ë;ÜÄá–á JÄ{z¡$‘‘ƒ)ÀôE¿u÷'4Û—©êã¡ðö(.Ê“ZL˜ÄüœêÏ? Æî9~2CFgðl-Mèq̱痎`ˆÉþ˜EoéÕQïrgÏÁ‘Ä%¶y¨1¶.N‘;¾ú{#ZXi ‹C¤ùÐ!øoû2  *—íd£Ç5éÈ—²?DzÚÿb6Íw3†ãbìzÞM·²Î3hÄo¤îiþÕÉí‡MQ@0:øÐÍ1BC½ùÁÉn®ŒÐ¬Ì¶¨ó-ayx3þÖØNoeüT ê©Ä ôÏŽ6üKÒ1æË35åŠ!!Ôàg1»ÿŠƒ²J¶ðçåa¶¤Höw (¾O¨btžRKBœîUš… X1¨SÊ¿¸Á$Åç[ĆÇ^2( û8UdáæŠé2«>¡õØWœ–Q.êP/©ÞV4jdÅæ§Ëàßë´µ™(¥îuºSÍq¬Š^ÑÓL‚sZy½%úݪ³ «K’xæRÂóñWÂËÛ©Ò[i†¦öË)LŸšà ³Âk_Y\­æñí¯²ò°´Ò­ø*ï0xk¶†LѯlcŽõN&ªˆ…o¯T³Ê›9RÑÖÎ`Ñ ©|™í³úÙПä7"Þäi&Y. yq“- T3‘4+ÎÓj„%_;ü¢=IK/9Y.*mX\íGô¦Ö%º-ÀýË¡Åp«ë¾E,?íÏ6][H*~€ÿð–V!m§ªi`½’÷›04­…3ì6}Žå˸ ³ómd ì60.ö²¤½¼ŒŽ/&4¯=)e…üjÇ/è\óZV˜ w(Zõ? 7Î*–’…C§ÇÚtŽM§…Ó;“Û¼ú5f¥…A )Ju¦*¨2•øÜŸò6ñ@ØnÇ¢B=÷;O>åDÚí›/Ù¯ÍS+ÉÆTÉv~ÊË·åp±ê@)ÇÈ{ÐxÝü¢!Ñ4|ÿQÝT¾ìrlÚtìÇ—ü’$Ä?[F8ÁÈáwÇKÚÎqcµ¤™ÏPîë~ÃiTÔ©ÒˆÒˆ?q4æjä¾k@• `ÌÈ<ÍJ50/¬ÂÄՅØiÚøó/oî ›;v°)ÐuÛ©wœ}¬°Ž‡Ù„:Bo×3ЭÌ!áfW9]Ä~¶€9O~ë‹8´“º™Êd¨Ü_êlvPˆºwOˆ¯µp7z5mìjñúÉ'IaÇ;s3_>Àü¾eHA #‡WúÁhäæDº²}éès%È~8BÑír.ƒ`˜b±QßrKa®ÿË„Övj& áóò9ϳÛ:5CSµ ›-ÉzǘÔþþ/ åow«<&û“¦-]þ z €À¨(¤{°‰TmªÎ÷±‚ûÐЧUr÷ˆÕ/S+è¿QÀq×ÖÓGÌœÌé‹…9 œ9^GŠãÖMPÀ!Ê ¢a2A‰í³ˆ–“>ŲâOƒ_ˆ†ê€£ˆÊh%³ÿy2‰‘œ_HÆŸåXÍÇ-'† ÜÜoÄsD÷ð‡i.¢ h óÞ¸+ûޏ’Ô `5ŒUäÌŽ¢ ”³¶*#"©á´}IØ&DÔŸò´Ë… ˆ9Áb46EËá»n ³c}‘‹Ø\®‰‡B•žÖ®–êé”c5W nšÛðïã>6ùú=Ü8¼¼Õbuœ}üJ(¨seÖ Èß¿ŽN³eNÿÒd\ÕãÿâÛ”>IÂ&—x•'6š®_›ÑË[·‘†5¦>N'§»w”kçNEĸV¸ «¿íÃ=ö #½ªFÍŸY£ç–ítç’~»gË‘jYYw„y´&fÝ"™æ{ùïlËÙâÖ± ?Ÿ7I¸Od±ýY’Áï ®.N’(ó ‹¶YQŠû7L p(;ˆÂà*ìÎ^œÄµ.——Ðþê}=Ìu©0+âZ t™7«/úíïs,øõ%AÜ*4ÊœûÛ©Ïc:Dè‰Ëqè`í}‰©•”áڥמ²ØN8âvTÒä7ÝÃg̓U½@Ï=ZuwoäPjÞ£wYaQxÌž½º>èî‘tù°\ªîœDÉ.|ÊdÕ–5G'©BÊ;Ð;XžYý5^ ®Ï?÷5B¬¬Ë™ˆWŸi…£P[”2Ü{¹ ˆdÒWôS¬¾Xüð„ÅrÀG¸@n-2l ïL€Y4²û~ú ©‹ÁT†ç1cvf ÇÆ‡U]ùÅZØgÚ‘Ú\̽îÙä嵨o9q×0×¶¤p„>n>þ7{uͨ˜Ï΂݂D ñÙ§4Ö9Kzx»UZ?@SÙã'›¥AÙšná%˜LµQºTè×{7zîr–ï z#u/‘óýk…vøÜW¸kÏÚÛsÆ{ؼ¯ev{Èà2êBЃ`ŸÕk>x’]f÷>ò‚ùPŠˆ–Oõå?%¸)*Ê‘4búöWÌBhAl£ÏQ 3‚·†£ÕÐŬ!þÇ«£C‰:èÙ NÃ¥¬(¾¤(Á“G?+u÷wK瘆O/ÐW|ŠŸ,?‰r¦Üø‹tÐûI‡ÐÈ¢ƒ9EŠÎÝê_ r}ƒ…åmîô¦ì«Ø óY«—{4A©P]tíuÊ–×VÏÀ¨¨À¦g5Š æñÚóÍ¿QvÄ}B]³R«’e¶Ô®šVQ¡Ð XlS¸a”Z¼êü˜¹+Ìp¦Þãyv}‹cƒ6½šÅá6î>c,ÜÇPþ`;ÚhWŸ5ÑU%Úˆ ³bûÂMr+f¡ÓóbèN[–RârlµŒ\¦e¶Ý’£xMWyS¾{ì4Å•TµU—é$Êw—؆Ļ7x3So ÃêŒ*ŽŸHy šwÝ®×MÉmá~s:3b¹7RòëVš½X„¹/¬Tÿžox‚%‰¡2…& ?Ö‚óµøbÜú,Ã×ö,ìuÀåýZž!º‰ðTF/!é¢óÁŒ}ÅeB|€ª[„âÿ VKÚ¾¿<öGWfâö‹3i´«g‚Ÿ¡:tFdéqϼu¥žâAs_š3òž«#ßxÛMHòÈÕ`Õ$È:(Ï Ðï{´áUCpTi®†xõãïL"Šª¸`û™áPÆëÅV]{·P²…Oo£÷€›çúôžj†o›|r<Á)’VáÑäíBunÈÝ@">—åa¦Íe \ÆYƒ`N_]ྫྷûYð´XHYrvE“™Ì­žüW§{ñí#‰JÜå6²tIæÞ©/ÙC±Ðâ”ÌEc¦ôw“é¶uˆ¨ïwŸµ$¢Pq²=à©b†3UöLð<‚Â#$|eú™¬„q…Å ˜è§Xáµ*"üÞ¹MœMfk4T²Û×45bˆ:Dç@ ÜÅeó¶•Í3CƒòéÏqehS.è?®48‚Ka¦µÅVQ¶œ]m‡Í!?ŸH¥ú© n‰*Ü,˜,s1IuÙN! ç\æ§½pª˜ÖKîuÆaÍ›É|€C%ìY2 uR`iõ½(¦ÖE e±¡Ô#í€ ‹KÉ¥ˆëXKs–w_I/ణȗÿj× ’GÈ«ý4+iªc×b,£OàÅÃ!ɱö5|¿¼žvY¬Jü ©:ê|ƒI „îÇÂ‘É â+Fá‡ÞöçB]íapF©x±jVáy±‘îøaúi„‘Š9#ŠÕòåŸáª¼¾\Â/'7Ö» ’ôOÛw:}ž¹Eìömðìç5áÕ‘Ô›d4×R!c²‡Ûæ ],YœÌ2ZúIЈÑ'¬ŠÅú¡ùíÈMr¥˜ÕmÉŒgá÷Õ@©jÁ·±¯M­mÿ¢Hù_Ýc"À°ŽŒ6É’‚ú‚3΢\ž$Uúó*àpA«Ë*âœáÁ"òbX¹%k¸"»´šüáÓ-ZqyÐ%˜%÷ð*’ú¼t¤¹ˆ%MΆ ©Èº~÷DÈãè­›A©/MЃÛí¡8lƒ7U£ì¾ùß AydÌ™GTÈÉ7ç™6²}¶AvÊàpêW3™Sm8¢iÝ)"l•µµãÁ.Þ˜Ú^M+ÇŽrâx… ǸiPeƒ‰Àd6¬’œ°Š%\k6í-·†’ÓH—¾_¿(ƒÆ‘i:Š‹,PmVŽì²BVqì¢FR’‰ÙêûÊN0h3x¼Ð±…KŽ+šŒÇš®_5‹0Ó:êQ#"IðÙ­ÅÃX#¸Ó.i†sD/`P%U ES¶@W?>`N~Š%ªä‹¼è}_㻹‚i‹¢ž7Õ)>äÃêArwÈ|utHXî†äƬ%¯y6£Œ.H®tè˜ö+þñÄnÖå€h—!ƒO¤Y&?Ê ¶(Ìda#hDz!Ì>ÏÐ S±NÕ`?2Ï„]ê)÷QYÓo»…-[Fÿð¦"óÆ8X®åaGmifÞ%×[dJIÇEȶzVyLL÷ì©nëå)®eGˆ!µÊ¬ûŠ•+·'GE6&w¡øLØ÷ èŠÂ¹ËÈäƒMñüùOTS¦`Ì–¼mÏLÞrD¤¶í¢¡çZ›Pl;Ÿ® ÑŠŒÿMÃæ¤Tu[÷³é4´žƒnL¡ŽxÛãS‹Ÿömx×8ú1ÃêÏ"È…¦ò„ÐûY %õJÛ:X0ž’™¿v$'î˜@ùí‡ÿwé6í»Ësl¹„ì&p*Ä ^×)Ó¡xDÙź‰V 4w†™QgPmMÖ(l²ã¦Í((™ë~Ó1Éð¶Ò°Y\xd‚<ÆŽ2hâ-ÐAœ{PÒ:"ŒÝ¤5åtYιöE¬©R$ƒ£ðÞJeÈ=ñ1ÿM ŸŠ'ƒZnŸX—÷ë|¾§¡ÐúŸd™×âLg«ÌäC+æUNµÎ@´Ÿ·ÿ% (z¼)n šŒìi‘@-^ŒY õ4ý>siö ýÞ½.ÂÛxì9Ni+ŽÚ±<õkÙè"qS:Õ‡ª¯W¸eœWš(8ækt{ªËè_=;…ÏÞC‹Dƒ:\ôà»Èñ 9Sr5Xt{¢£ªÆÖZQÂÕ4á¯K®UÝÒŠ~=ÍéŽÆoÏòË#gy‹öz‡Áw`Á¦œ€ W·jWG86 l–È>ЕÉm´ÿÛ¼CD$-°0•®—»<¥4CµÈ*„C ZPAΜV·üá×ßOHúÕ…øL-KK4(£ˆWŒðN…ºº(=-Ùø&šÃ'þÔ·ì« K±†|‹z®Wæ& Ï6‹:suQÒõ”C*³õ0¼ªø ßôZ\œ2lט9IýÊðIí{ñ#Ñ먩€Xv²Än¥à’U3C³ÜäVËciUª’û€UÉì]\£Ž=R¦V±¥}‹Û“Ùƒ8s%ôůA—öÿQ MÝüCºÚšæ!IÝx·N i•†]†ÇSÌOB¥Äø²çèþCê%ºOHÇ2»æ§QßÎ`(¿Rëô™Òg®ž*Y$ªˆ[ß–0V:?6sa/&©˜=ݤ×e#¯TñÃ)ªº†ÅâMÑŒ¬WFJ*ËIÝÊÅL’(Á— ÑSB¡ƒ¤™V¦â3sû+IÕ åB9{R Œg08¯õ5;K=†öµ¼ÑÃæÕuߎ-²iÜzhªoËáµ] 9ÑUKoœIÀš×Z'ÕÓö˜n/ŒˆÅ-©nM{YÜë]'´ÍüZÔºµ$TŽk×^úaLÔL‚^ìéÜÎÕ!•f36´^3Œ½9¥a8í¶†TÈô€û ñ9>ªMß^h!¦]Yˆ}ðÂ%³þHnÀ£…Û‚ô±$•)øD6[?j‡°Â…¼'rHxÕàø[–ÔigXÏÌIGœ£H\ËåÃÙ'1¬°’¦¢v$\¦üÇ0ï4ÃéÐIÝêš š}VZÏBÔÍ–—¢û_CºB.úS²"ó<˲†q:£³ŒþþdŠWŽ0äT§{¨Ê¦Ð£·,L̯è;0i²‡Ì ¿À6ÝB$Û}‹ cÁß,Þô}àŠB­vKš MÓmŽ@½½ôðÈ\Âæ7Éý±)BGªS7‹À¥”Pf* L©È` D±Ð½u§àO¤ñèËùݳI#Ü{-j­þ„L²&Ø]sàA¿lúÂHÓâ1EèþJT¦´—¢l^8#<"êãGŠ&̉Ä4ŠŠ%Ì Ù†Ç3{NèȪé¦3KC,C„ðùèpWTÌÒ0—BÜ÷\ŽÆè혗ýq°‡“ÓË¿€a…žáäó#YÐñM¹A^«++ý¸ˆ’ñæzÖtZðŠa“gÐLè)–п4tY#(Ë>?‡ª÷ÐÃX5a„±à¾q¬¥èá>^É'’ÄÿwÚÜDçÇmJ”ý¶@"áY ¶ &Ý5Ýc]²5égõí?Ñ”¤ÃŒHí“03WEréô´¬p ™z#Ó›úç­†xì%,K1t„Tâ’Uè„jã`ï„>-N‹§Ó—-¶Ì~“1¹}lª(½±_^Œ—'ÍjÊ™èêé#oDek ¾Üá½¥¿/”°ICÇ#’“貸Ж™ °<ò›8 „`ÆtßAy¾hån:ûI·`v!“qh1×TbútÿL{ç~*²ôM&ñ@?PÅàõž€ï¤ºÑÍ5Oè•{r><߸-uî!Ù(% )_ô› µmÞ‚swSVˆžT» °B[ìXþh’@yî0•ÐÚ•åÀ£ÓÕÏ:f£…@.ÿ‰u¿è²«Cÿ¿•ÿGDyˆÈ?¥³8ŸZ¨10…+¿{ª1…Õ¸‘à¸úÄ›íǜچmˆuìwFLè0ª¢Î _Œ”ÕñÑäKnGˆpb„ô Åü"¿í­ö2,lž‘’@鿪T«M"ƒÉ‡ˆþÆEÝzc„÷~‚Q|X/A/­)ÿŽ'¯SÐ&lUìå<×iÀšZ$ipFe!AX¡™ÌFù0eB_',bðÛú‚½š ò‰‡¦&÷º`Ö•Ë䢗¬$@Ðv5ƒª-ðרƒa«Ý6DZ‚é—¦(áA:ôÛ2æ%dÙ[؀Ȕü‹8ÎJ¢%é¨Ó+}Ý4A‰s©­:>[/ Lúð€lhPC½“'wTßñ¦Žkl…q¶Q*ò«¶/xè™Qßü^‹ÈEs׃E˜6[Ç«6ÝjÆÊEš5úk×w4jõ“ž•4%•þ5{örq+éjwð]ÛÄjhÅRfoôÇÌé0 ‘ÿ¢¬`L:hñ°ÐM mCR «ú`£ Y\fVœÂ5M{r\ëŠN=îIëúò/-„@we®4yÝ’.Ó•¦ˆî̸e—„’ò©<¹¿‹ÒOàïv«Cðò2D´qñ¦ñ¡l-*ø£™1WÖ[O¥&.yA1¯Ü98öúGéAlôD¿ à»ôàOe‰Õ…6`âè+ä šôžDgân=É?Wxu*˜VK\w©S½û”ECÂ$2wk1ñNE-ÃIG²V ¦°ú$ÝŠ¼²éAŸÑðÔ  -åŽC£Í—¿?¿í[Sh’>K®ýèØZ’ ¢ƒWã=€"Äïçé«Ùõ™ùùxkëd endstream endobj 2687 0 obj << /Length1 2593 /Length2 21540 /Length3 0 /Length 23022 /Filter /FlateDecode >> stream xÚÌ·stÝÞ6;il¬Æ¶ÓÆnl{Å6Û¶íÆlì´ÕØNcó[í³ßý<{ŸïçüyÆ÷Xëúi^?Ì9ïEñ^A™AÈÄÎ(ngëÌÀÂÈÌ PjHx8U€Ž6@'a;k)gCk c+#33;…ˆ#ÐÐÙÂÎVÔÐÈ àr6È;ƒB8X™™y(@[ #Hi0òÈ U<ì,jÃ?@ÁÎÉ™ÁÈÐ ¤ÚšYØi@."vöŽfæÎ¿cp2ü0µsüMð› èî ´u­êô;¨0#@ÚÐØÊÎÍÉÊ`hkf”eÈÙ¹„j;[€ÐÜÐÚ`gú'„ª²˜’2@BI^UA™† ft¶5¥›:;n@Ð:†&&ñ–4´¨˜A¡­9#ˆ¢²‹½½ã¿²QVQ• ˆ É©ˆ€jô Uez€œ HøGó›è@ÊÖÄÂ𷻬˜ŠŠ¦‚ ÓïjX® 5-~3ý¯t(AÉþÎäjêhgógµ¹³³=/“››£™‹“3£££½5ÍïTÌ-@9Ø9Z@ߎ@kàŸ»Øš€ã JäO€ßmÈXƒj ü“øG)+$'%.¦¬ÂªÃï‚3üÕFgwç?¹(‰ ‰ÊŠýßÔ¿ ZXþôëw,P“-¬A‹ý%°uÄ´¨ó¿³5Æù7a뿸œ€@P ÿ{zL¦ ÖNLÿ2ubú ƒ¸¼œ ƒŒ”ˆ˜œ²Ø–vŽpv1ûíûÿÉñ?Jgnèô‡²Œ‚‚ ÀÆÐÂ4u†¶Æ ~ΆÎ.NÒ?2Ð4!ý«è@€ˆ‹£ãïÔdÿGåøïìþ§Âv tt¬½¼ Ýþ{p m]œ<ÿÑïÿl¥1hà-œœþŠüW¥­A"Po-lÿß{÷ÛáwH!QÐ^å`°‚fÐ.³5±³±wBø=¢ 9Û9z0ý¯€•­›­×ÿ®7µ°5ù]q€‰‹=“ª­…ƒ PJô_^ Âß23 3€tmkcs¦ßËÿÙ¿Å,¿Å Êx{ÙÛÙL ­€Þ¦@Ђ—“¡+h\]€Þ^ÿTü'B`á˜X;ƒŽÐé‚ð'º”­©€ç/1ˆÉÿ¨þ5ŒÔN6бfbgkí`S&9;gÐØPÿÿý`ú/Öâ.ÖÖr Ôÿ[“þÛÞÐÆÂÚãÿéñ_fêÀß% þæ¿4Nâî@ gcó¿ºõ—ü¯Õ„lͬŽ¿„ª¿#kÐÝ¿¯Š™ù¿t á7¶²:9¸¹ÿ¨€ 2þkPKs0É(ˆh)KÓý¯#ùÇ\ÌÖØÎÄÂÖ 4ûœCGGCfМ±rp¼X@»ÈèþgLŒ¶vÎ €½‹³÷ï6#ü.n“ÜoÑ_ˆÀ$ÿoÄÍ `Rû7âá0þ@~F#Ÿñ¿;;¶ßßÖ¿ ÁdòÈ`þ²˜Lÿ†¬ h¦ÿÆl¿¡ë?ìÙ@ÑL­ÿá²0û7äE3û}ƒÎª¿M@œÌÿfÈBöæ@ÛX€dÿ€ t­þAùþ½"'ˆ€õï.þ­q¶ù²€ þ›”¯Ý? ˆ¡ýßd@e¶:ZØý£@, ŒþAìÿ‘ hä˜þ±6 (€ó? ˆ¹Ëß­Ùþ¹'ŒíÿQCPB®ÿ€ þnÿhˆ¿û? ˆ¿ÇøŸ³ªðûVøsº1ÿ=¼ÿzøƒ•í¬€ê& ©˜È:;Z¸k3ƒŽ&ôùŸ_ºÿ±Åß§ê?¼……íܽØA;ˆ•4Ü¿Äêý¾ÆÝ\ŽEÐ.ûüûÎî@c„Åy;c¾ ËÔær±ÂÉ h Æ“*l~ éx¨ÅŒÉ\Ѽ-R @‘«_&e‘Œ$¯®O²¿m‰E–õëZ[Rõĵ‰¢à¶¡¬Š˜Ð÷\5FÕ€LÙŸ~]¤4‡Ò¹š¥ìÓ™íñíÄÕïG"<ÝѬãoh—)¤:í+ùÐnų,-˜ŽÖèî?Qñ; ~Nv‚;¿=`ÆFö -Ò΄`—†±ïíÆØËi?àß½êZ !­0:ÂמŸ²zÄú`ZÀð+lîÏb…j}œ¼T-'€eváJ|=…éæV¯ÚéUìU%J®Ç8 ’7gtóØf"4©Œ *>Y/+ù›EϘ "Ó=‰&ï{pVBÈ„ÙR–É:Ë ¥?>÷ž’ø$H$Ë–$¶¬Ú÷([Ïb½žHÜÛ·ÕÙXS.ªnYšrþ˜‡Ýû؈Û_¿¯•¶u¹k„˜,öÚ'¤®Œœ4ì€åS ÎB¶¨ï9˜Örÿ(´·)ƒ$*bB Qu@€.ÛÎ[K-epºÙõÿ…Q5ŸÍß&óuœ:•¯kq…}ÚƒÙQëªCÍÓÖïãUÞ­ N¼VÙÑ.3ÒÍ$¬w¿ü­Þ+)±üux¦e™”&•òç¨vfñÝnÂRñê36}ƒ–æJ•€#ü‚wÃÅüøú—®ÐZ×ax™¯¦Íjö±^¼åŠƒŒÈ°Ró+š€—þî"[Ñ‘…› •f㟦üÖæå©à0p›|M0ƒ>àF:ˆ|Z'‘»*&c½tÖ"š)Y¡{-y[Ÿdq­DÚwuÓ×=¾¨“ú=9é¨_·ŸDq4³øÜwXež}f1Wï< p0s9Î2*ä|Y:,@>»ß>*ìðQE»¦D½»ˆ†èä›e=ÆðVzñe6p“•!dÓèq3Ò¸*rïìÞ_ÎÊ€žùÈ‘öWë’áIˆ“îŒ%ýÛ‘i‚8½OJ {D:i÷4©K¤—ØS™ie¡v•Òœ{óiÞÃB7q,¦ô²‹ÜFç9Ý[ ÒÓª¶§äâåÁQ_gãzF1Nî-5ί¢jq8ÜÌ)1yJ5?íCWxªç5)c>ÏÚc]U¦¸nrˆ®GH³˜ÖeaµçE¥HõZÒ24 ¦S|VÅœ-pcC2”£¦ŠÍ!bK”e‡½¦ÚÊ„‰¨e²±ä†)õ³€o}iKûþi¹ñS‚ÛOü…€UøíS5ÚŠWÂ}Ñp)å$¥¯±žkÚ†ÐÜ ù–Z.û¸QB’|h’i eýèk©#U1©¼œ»Ý ]MÏneõvPs$Äq“ã¨Ñvy UpFG€±U”â’{MÅ ‡Sˆ("'–7DN¡ÇD7 ÊhO¯9¼ëvÿy×j §àjáëš0ø!¸jJ÷ÊdìWÁ:,þH&b{-ÜϽ6ù>µ{—dãÅÃc¡ÑÏH^ùX3ÜQ³9XsÈ×ZM]®Ì‘Çá.kkûš_¿ Ž µýTŸˆQÛ9„ß;UâõøFj*y,¤Ùj·Äè¾X®DÛLì\MøÆáÿÔAô åX^™·H?Žü) òÎ/»Åçiv…qKêƒÓí fôðqor=-èÕs ƒIð²òX0& û57x”Û”>yšøþŒÒkÊ軞;Ý›X * ¤Í Yè¥éZ¢· od ¢yËÀ—|xa1ŒDñ‘œ g¥@ÿmÒ¤ŒCH.ÑÜ,Õ•cO¬Mó¼Z²µM¼îdEár'È‚3ѨVÄ$‘+9'”ħ­¼k‹1§¹O?ì‹ Tšàút 7ÉNF¥ŒÌD‡šãÖ¤+ü )ÕRAG•ª¹^uÆ®ª·E™ä¼ý~rgsäÂnO‰AÏ#P,4ÅO¯£ö:äýN¿Ó×` L×sÆUeL\øøôC;VÃÌg¤¶¶Û¸¾« ýjÙ Ï1ÓýúPÏF˜€£­¤Ÿ XdiP®ÖQ<†ä „jÎ׬dMÄQ¥–r | æè\Jj]Ø‚þXÄ€ŽÖG¡·y0MÝzA¢¹ôȺªq•H’üIÚ¦ÄÐgôåqÊá Ohm³UÀçgѯíMVÕ0ï+Yž²»Lò-ƒùpj×ÅðÂÏ£HZð‰³¶xîùá0Ëaù,eËÏ?œcj§m”<]“Q‹•bm³:ü¾Êûûê]>¥ ³W§"HÚÄÄóoP ”nÕßÓkŠ)°§¥Õ{¼y´”`C2»ÙÔÑ /­ÈiNDÀ^¯¯ûÕ%û fôsáòv6Ì%¢‡0­É.v¯ÿ]G«š„ «I5/áÞ q>ƒ±¦L£Ø>¦ÏÎwiœ¶ðËÕ¸s§×°©8í,©‡±Áª–.0ôå ”¸ë@¡/fÚ‡0§Xi–A"%«ËZeHÆž:ÍË(7W}×@p¢°)¢·ÓþˆLñ¨'Ä·™éNë¯Tpúü¹ÄÏØJ¤‚M"9­ä~ jhù)ê/œ“NÇØÓV JkÓ¥¤¯¥ K'îÊX»-#±%ºùupÁ\‹`CùÍ­æ®1x ;~ÁF©ôŠþSÁ¥OXèõѲE2•04#ŽðY²Û®?Y¦{¸x¸Ó)‘àçfÛ6yÅíꕸl¸…Pý ,,öµÏÉ3G„ \6i!oð˜`ú*šS¨¥µ×ƱêeTíúùrˆÉ‰©•%~iG{(>Ÿ«Û¾·nÀ2zvZà1•ÊøÔDž|d»Ñ9º-Ç™«&V½±¨{ä«ô;ÄhTª¨”ì;ÎKâ—®‡hicøè7ºÎïü›I#zÅ[vn=÷¯PtÉœôÚn©áÐŒ3‚¦ÎT•Æûgy ߣ۱€Û®;Ì"$PÀÄ»‚­÷^šDhª£–àI¨Æ^é‰ ÎM=J£kø ‰ÌŠªqUîl•æégN}×n‰iPÌY“¥œ.®¹ õŸß|i+Ö¿ŠÙÅ(I^[‘6çÆæpq*øž3{WôÓïsn*¢eÁƒÃ•ì>ò²ßîn¼|:ÓÙÛSCy3­³UI¹"jRËô2½£•ño_Ðp­Ñ.ÖñŒ8E¨¶c¼ÚÖ7õñ7ãŠÄí/ äZýþ(2É- &‚W 2¬96^“¬nÞ´š‘ZGr×vLŒæM¿á€ñû3oó¾jê¿_Ao€ù*ÿn"ø­¬a‡ésW¿é®ïÁ2qfDö ô€ŒØgJ ?_c„ t1Ó윴,T¥ûÍ M2öýìüaùQšöªÞE*íJí²uDÐÜZüx¦û“-ÈFWòd<³ÎYËZ| ¼É‹“hÇþ´c‚ƒ—P'~9 ê¸?×…9óÚ˜÷d÷,Œg0°ç´F¦zc'±d~ŽLõ)õÄâWXFLv.c~8SPæöîöÕ É-˜ÛKx'ó@?ܽéiyb¡‹B!·#4Öí(³J,Ï^?㢌V…–àGŸÎž¾1úÚÔñy6ËFíD·ÐÃ\Gqšÿ Øî„­ý"Ðyí0ÚDþKשI¬Ú6«yˆz1~´æZê}q8r1Xó~§œaü¡«ŽL]ˆ³[’>4•ú”'I{68™Ú;™”8bc)ÿ;ùõ tc(ðB"Ú®9–ºRsI1æÛ¥x‚(Ôqxz–”ÈÄd`^}Q@ü¹â2-Ât°÷ÓÖÊG î–_¦ì5õ}R9ï)àý]¹ƒt¹q©Ï¾ƒ7h%OÒˆãKƒ›6|q “õÓu¾,ç›àˆ‹W¾$Ï@_íy’„õ¥èÎzáW¬(7Ö"¾ß•>‘,d™Uð{åû¸NCo/!O”ê¥Ïî*¢žÉÛFNiÊÎLPL¯˜)pM6QÇ>ƪ¿þÝÝ£ ^¡é¸•‹ë$íºäî½µñ)“Ó 5ýýñé(¾ïn•¾!æ ô{c êÉèUOJ:ðLWuBô³”c­‰Åj´6+ɪ²—gEŽX‰&SÃõ çŸ¥lðn”ürõ†·1ÝX•ùÚbã`p}‰7¼,ž,MB´¬†×Ú³½v<‡®Ì‰c7N-cü÷ ¿>ô*É`Ë¿§ë,d@¯C™/¿Hp‰L·â Uxο³Ä¬”q¡¦´Ü‰s±<^çÅ+ÉH¯ 1Ωz×fJ1§=©²¡1sˆ“*I²a?¨ö12$vf«Þ&¢½Q‚(Ò-n}ê™e.4æ#ó(3'Ÿh™:Xl+îÊ‘žG› ²qC3äÇeRãìl£å‰t.lÉ;›¡vx-­äÕ«ˆ ˜áµ QLð×ÔÒ }±jR§L7x©µjdžjo |^Ïs´iLµÙòTt âà=UHµÑ™)™ÎlŽ­õøuÏ”%‹*Qòôi‰t¹¦@c^¡âÂXkQÿ´=4ˆJ¬±¡w¶W—ásV•a°ã#ewãøSRŸ·6¿êîüú ×§jýXq¯{$ý~ Hoét Úd÷È¥VI³èâ¼I_´TMwVÆ€À¸N/ 4#%±‘"‹~ õ™>ÓññÖú†æç©Ç4øíÞ d¬¹¡© ïËuŠ‘(ã‹æ¹v þ%ÑVkòÃ-¬á˜hq£ê¯õ´•ÉR²`ÕÇÊÓ}°¤´eúç‚àí2sÞ/óÁîï4£\ÝaUWo{¨$]Ç2;(Ó/P™aWz*Ô8 )›È—Æ^‘£'˜ð:×Qqö½·Q$C{ö[/ó~Ý÷dh  ‘[ḭ̀¤Œ«–®6”¬øÖD æKû%B¾{öb˜›_‹žOëž!Ý ÷$aáÛq©cÓ¸)I”TמÆmf?tY©¨9š1‰¢{VJù|}NÆ+«e>±¨¬ÜÕä½9:¬Ë¯' ¢»½© –›±xjbÒÄ_ŽfB)ö»¢“b/5¿OÀ)\ÖòóUï˜i É Wí’ÚÛêûŒâ>E„]õšèôtsï)²œŽR¾%öÚ9਎oᬞ,P¼9Ž0Ó7kâK »}Ž£L]ƒC„ô1Ò fg¥( z5àDToRÙÞŠWÖ©eóŒ¨S_-·åIµ£ž8’%ªß€ê’ÐP~Ñ‹\á‡ôhNÄ!’÷b}ÑÞG¨8ès#ªŸ™ôï$Ï.Ö1ðþ>²ØŠ+:²ðQ œ­…“ΊΣ‚“QPIÞ¢˜_¹ÕÀ!÷ !6ó‰+ÿXªþî\õý|¸W é(O’â>[X+ Aó'/"þöÑ!ÚàÚG>oÀ|[æE,ÕJEüø ±x²>s©µ9{è-“ì`D[.Üûê{ØL7s5®Õ4Å!Lø)ÑlVºªc«cUA̓Ë^òl±qœ«èþÅNOEý­0Q6»ÈÞF˜«Õ&Ù\j]ÍÕDðz¦Õ]‘àÃ@ì‘ÈÓ‡Óv^(›¾ÜcãÇ¢Ug Ø€A ½æ×O°ûN$º¶ïâèÑ)¨ñ1œ9f­…æ‡1LsaÒYJŸûe§^ŸäeäyF¶ØÆ®ºüys(TÑéÄóØ’’‘³wUÉÛŸ•ÏŠhãòÓ$ýqC>C¶¤'õö'—c‹»JÖÝSŒúÇØ$éB([mWTçíFË‘«_zqÙFY4¬N¢* EßB/¯÷ÈÔ4UQ-™_$¸Àn“~ãû€™GLÃzù)‹ªóa³¡»]êkqN|Œ|¡UÁ¤DÃ.£5™„YT² ¸@­ ãåm­íÑØ+%̘¬xÇ~è¹ÈýøtÉg…ö*Ñ›š*žwÖ_éËk˜— ØÍÎ5KW`Ïî¡ÐÓZ lv_ÙöÅfðÜ·rf¯¼Õ› SЍÚJ^Q£ %s!Ú®t7lFDšD-S€ãø$J²(‰ô8™—¸±¯üG£÷SÉ? 7b94’º¾ŸqÎ~ 'e%ÿiþÈÜ›"æ*2<=ºóIÆNÕþòµQ¾³cVëó-}?žºù’òšèª6ÍÆÍåOSNë,a¹†uÜ=7FWþز¯þÒnÀP›Ð×UÍ8xWóU/J W¾²Ð#ìUl­›†þ”Ð9=„šóQIÉØÿÕ„†O¿+F, ‚Iˆêr àD>Œ+ºyöܯùãŠO)‘¸ã®Ü=B:JúXp>H½#÷ÂÄ»ž-›¢¥ïBï¢jSMî³ÖêG:íÒM“º³ÃApŸjK\z7ýŸ¡Ñ<uÈòz1v hQÄaçMFÝžQSCc‚_´ÔBlë%ÅidTïãNp¡Ù½Qq³—Ïž1gyĨU¾x*;oŒédÆÌ–½÷Z î#{œŽ"Š|'nË·§s³KõlJ@òné&dgD· _§Èé,ýžÞTPÒÐÌÞ@hñ>¢é.)R×úknÞ‘ÏH;½ëOŠ£§ð„ÌÜà§ÓôiE*Í÷0VjŸkÅ/¯70ÐZû:¶/`øº²°™ÖàwsØq^§”—¿QG›)~vd¦7•;‘gΧÄK©úÕ1˜ÄÌ™ÝD0õ ­FÖ ›ÊK\´ö“‡D„Z~¦Ç·‹†`lxŒ¼œ?Û­ïXÇUü¬ŒÞlŠõw©¦-¸%ÒÄR·ôdžÙÜ…b¤$²à÷¹²MÝ»óE_‡¢ÕiŸÉSþm(BGÒcËü&JØ$M½9«äœº„O³x±yÐÄœ²õ(Ä]ßnPçh7øŒâŽÎªû6çÕÑNyŽ?|ÎùÒ0ë$9à9غo`s„T¶5‰^IàXTœ± 1y‡ãïË ûЇËä«&°a½Aä½0Q÷C1¶bRÙß(üªÅ*Þ3©ù=-\]¹ù1ëÍeSÀòŽ"gykLjø[>3{ëÄÓ¹ïè|£fåó5Îí N)Ô€i¬]oœ÷x‚Æãá];«&[ 퇴{ïisز«p]Ž»cã3VëÙu±Ý‡” “=|±á±ÆuC=úf)¿¬†ô>‘¬`¬É}q—¬—¤†ÞÐÍ$n×Ö¼Kïbß_Ÿ"ñć¿rýl%Kæ-LôÖÊÇZ¬F¨ÕQ7W~|qМº0%;ÏÚ¦Ãàϵü‚´„{)SµË¸ùI_ªýýQ½Nèã+”̦¯£‘¦ÁS÷-ßÛcMi_ Þ]öЬJ™IxÌá=s[ÏxÓ"ÏֹЩ­Ã.‹§í‡Ö09ƒªé`ü¶ÀwlD«âY SìÌ“ˆr2Àl´BYxö´¬ìÍO'‹…tUrËì .sO?}Œ ”zá(]ü«Ì1gå…øU'>û¢•†•Ÿ©KóÞÑ?Éàí RRd ;¹„Ó 4,%j³Ž·•ª‘Û}´Â#?A¸ƒóûwK¶N>»AÕÉSUcÐÛÏc9ZæÃĉ\wª§ó»sŒÑAÒ rœx ?¶2MW¯|2ì@œ[êóá+~‘Tz™o+%Ϙ—O  ìWrÕ¡…"˜lÇ*’|,“zÃV¼ù‰\³<¥H6ú°_jecɉ´ùç”^÷³šÓÓÔùF"äým³ÙAíz á—:ZEU›Áô׉JçÑ#C¼‹iýļ ÌÝñjÕÁËC,dF¿&îõ‚ —9ŽJ¶}º—ïAÎpSãäŸ;ãÃmrÚ°ÄCÁYÅèûN¶­?·DÀ3+%É_Ú L³žÁ] ³™ °„lu°Î|Mh”r?a[L®/…|J³O½–(‹Ë_yø*ß„§ž#«Z=𬤿-–÷èl[V»´~âÆïN?/yŠG#7SJ|ã Nf´ ¤a`AËÀ®>Û¨ù ¾… B%p0N;;g²°ÜŒqé$û@ß[íW­H".=i Iã7¢hð¥Fš¸Ü$³>´ 2†šÉÁ%"5“¦C.‘e"ÔŽ%›1Ÿ-%³!P{ÀÑú“]s¸MÃçÀA†å@Ý=­ùåۑ鎼tXŽ—;ÒÙÑŒú0\r  }c?Q„\ *ÿ éØÏ->v±.4žâ+6Êt^"ÊþR8Ö'°AîˆeEûg‡w4–-~E[ùNtœÅIÃË=Ð! VÙ–F_]Ó^8úžÆXëŸÐND8Ñi ÏÑЙmÖšôÛy¾a^œ©º mF*œÞ11ö¶‡xä›gå¹ö³×!¡‰ÆSjʇCü¸š6ƒ³fÁy¤ä«Ý¤!û³`ýfŸýˆaï~L˜â8iVÄ‚bEq)µ^É‘Fáâ½ÕÎê9 ª©öñZÔ˜•÷;¶KÎv:J´¶²äÁ.Ÿ—£èV|ðÕ÷íZiëö9Ò(ÅÈ*º³Ð 5nà·ãy"O  Í7H`y*·Ö$â¾mè×’•ìHŸ˜¢@T레ĦˆÆNv N4czPçýXbb zŸZI6£ãb..wþ) Óÿ‹y€x«P{ ƒSêQÁŠR¶g^úxF·APšÂ3ŠŒÿâÏzØ*¶fT±Ž'‘ïç¥ o¦\S×ìmF×PˬúqÏÔ¬ò,ö:²p5Úá•…Ëšõ–‰¹ÔXŒwñû[“')„’ÖÀ`üãé0Ü~í+Hç«0x‘ÍX[UrW1¤­©ðY} 86Ô(-dìõgOòz,¬é<>›‚,s>î L.¼•nÐJè·Ü³c.è¬\j»ú<Ô¼×l2-¢îö†rîƈ$®10kâꯟ6RóBù )[°¨û"…W´*@2k.>S –+pMcA×gC4é .¼3§³§€`Pñó®T1Ñ™—'(JúäZu4gžß¾ü#gØîECä݈D b1I×l6‚%(üõaƒlƒ^÷nžSµos#½2ìýƤÐÅ`ñ¯5Ê2ÅÔ»?c^‚MÃÔêqáüü—ˆ¡íbX»ý6ÅGq¶šXÅ|/¢Qg…*á,Ì&>üÚæžq{Wq½ ®Š±Ã¨kRŒ²q’m´ñ0aøK9óÿòžj çØ¨àÙ-@œÊ)ÿ±Ú·Ì±N¿¢’~ø]wG…KJ*zëu¦‰ˆyl×UB¡}ñ{“Êš¥¦k:AξU2'ÑÝd’ö˜x¶—BÀOþHš=nÝ÷ý^[":®G´¡Ë·ê¢?> N/°I¹nsdÌ•!”Wzà>ÖÚoÁtõÀ×9Ÿ–Þ¨\ú‡ìÜøsCÆ{nXÕÏ 0ß2*x±`¾¦ÎÿäXi÷SqŃíC_ÓÕhOdßrÞ²Îd&¨8€àjï)ЪæŸo÷e‰V7ƒvj"11M ] ì>ÂØt†?Þ³TÓˆ`E’ü苦é¹Å§GQ±®S¢QOzæ0˜ÛÏÛGòìÛr—»Éå«r™bw(±|ýɲ0ä¾ÎÁ´¿Ž…,µ4óÜD¶ ;uX,ß:wõÍX1¨ºèG‹g5¼šÄq0•é¶Ig\ ÖÀ&:Aò–ÛÑâ§°µ€™ëâ0¬.y|¿"žñ縲Áû²JD ⥗œh8ºŒ¹,-»/é°äctÑø<ŒÊÄÎP!ær^Ú#%ÉØáx u.Š/‡äy‰Æ Ã[.ÖsІÍ‡©Á´Íëu±ËËÇ>OÆËì§Àªôäº}+/¢T«âZ=aÑX´8Æpóhz†Ç÷N‚ƒA#W3‡¤t_m’„̓ï#v7²l–a‰Éûã})R6L2ý`&@drø"±ÌÑ /ºR‹Ž¯›>þ7JÍФ†ñ8+–WŽÂêÖrjÝ—3û8ëÅ8ùb^{É…ø:ءѢ]ܨ>¬>C»ß³ø7ç0|ݽ¾„Ï(ÍÜCÃO!:c5Iâ s±¬.?" ‚oÀ<h.Ÿ¦ÀŒ¹d†þèÞ¥­.WìXýùÉ*œ÷Œ*Ú7ßFž+Ôû9Vìù‡R$áY7­1’˜Ñ÷${mâLÖùÄ I>FþMì4)Wn3¡£øwÉ{Eû<†4Â<‚Y…¬ß]¨8— Åêmßýzýˆd1¦®äÌû ’™³I«!äB˜ØÌ𣧲RáÎ]¬ñØÊÉ}½›³f—”#kœªÈD±÷>£¼’$ br…ÃÙ6µ¯>ÓS¼Ô󳦙Þѽ<›ªUùÖ(¹E©)”‰l,M2¸’Ò4ŘÁ>¼BÁÖh‘¤ŸÅ ÞÐY¡®™„U^J¼®z¬fÑõÿãƒR®ý4ºÌ×áо$šü¥Šãp‰¦¥$¤²éÆ»sÑKb½@øo‘i+ȯÀ'U_Ž8av´×ÄÖ¹×”(Ñ2F o[ói*DÕ^'²xRö%žãl¶Év±§ù%?wD_Ø:í‚PÿÞ‹”ßÃÄøâ<©"¤‰3ì)‚’‡7*AZ¢o–‰ãÛy”Ü*L¾¨Ñ,?‡”!eF¢å œ°¯A|½.î´™U3ƒÈÌiàÛqö¼øiqÔÅ|ˆ21Ž÷º#öþÛr9Id`ï «Ÿ…Á'J«hcdÊk„ ²ð£ô›ý $e›¨¨T,:n#ûÜ |)~*uÕRŒ}‡Ü—>èå¹Ó…&{Ú/®¾#K¯ónŸ [6X±Ëòö¢'%nгÄÙJxúf­ òêVâ}‚ÖS‚ƒU^¨üpè¹u½è?Mݘ¡A½JLŸ+òm°Ô¹G–ÒN gÍå‹ÿªN| Ë}x|7Ù—ñ©Ü˜¸UfFÏPÈRhœÑWò’D„~ÌP„%ûÚáù¹÷‡“¥ÈmeùZ†žã«ûð‘AóùʨßÌ#R'ßùóKA"ÞÁpðÈ'ÐjlCË»ô ‚Y½}<Ϩ{yã)F:|AÜÿæWð©JêXKÍ]$g¸^JÈn…ŽUo‰døZß+?IÏËÚPõ“¦¿È­ñõ–6×3ûkè DVÌÏ4¬L_õ´÷‰"GrÀì{ª3±ƒV¿ä.ÒÃãéÁ›pÎdÍòG&ÉÑ1 ¤,!¶²OÄkõðÐÓœIî;ÁCe(ýÒ7ýÈKl xMkwV¬&„} áƒu®»Ö—H÷ SGb­ÚR)6 ±/œ©§Ó9V)|òÌZ#Á:» ïIs¤n¾Å¸bV(²ûcsRä²_èõà»ÏÛÁîÄ_f5aQéd;C3‚/vidƒDx F/ˆæ(›qB²;—EH{”‚1æÍ~¶òÿè<]ÜÙmâB8)ŠÒðüª3ËqnßðÓþ´i‹cˆ8X­`.’šÃÃ3‹…YÀ°$¹¸¬3ÕÌÖû˜ªN¿D™-³ì›°ÁŒeíY„v*vSªw…Œˆ)¶²Ž#xœŽNêBg1±ÿšßãá™~øL|n#yê$¿PùE’±¾Å黄Áö”uË\Ï”q; £H0äwKHøTáÑ.¡\OSuwt¹(þƒ~Q&¨›°e ”ḇ¢µìo§n‘<wù¦Þ(x+­Oï;Á¥?¦œ?5€]C?ÂÈèÜ£Á!Þ6<ì›Ç°hòªT=Øê!-ö+šÓ5(&@ÏyÑoç'Åß.Ì;\Îæµ–ÃÖ>I!{'V–Ä…FÖK¬Y § ùÒ¼£d#Œ!/×Àh·ƒYar2J¥ÏÙ¨wàÕýLXdc´3É·VUª9KÈ1;Ù/‰î“­¥ Ç ‘—ÎÃ!Ý‚/ 5 ÁM·ÙŽÄ|¦…(md÷jå†á·ˆhÅ©ÆßòzׄœQšjýi¤¢P&š@Ðæ`ù‡õ tUĸæ°MÖï`xøUK–¥A/°pû   Ò}÷:ŒﻬÄÁ¶¤Çßæ”Ì/‚98lÅTW85.G@‹ Íe=Š®ùªQ³Œ‘­  Ã Ç® ˜ÄÀöú¯CPÂ/š¶rtám‚¡ýSÅæNOÂR:ùŵ r\j"ÞÉ ‹‘XˆŠ\ l=' °Ër¸ù¼îîqP†Fsuá%ŒW­cÕ àjó˱÷îM!د8Z>w¨íïàŦ.Ðx}õT‚ð±OŸß/2±! Kö„Óéc/|']{åQÄL½Rš]SªŒIÍ(aï%m‡ªû-[CÜ«fþšá3[tDšéE×5À¤9&¨Rà‡Öײ}ÆyØ:+V\\U[ØÔNýWîÙGðÚ/Û•¥5P#CqM#\Hís¡l4õÒ³¥"—S‘”ufúV>eA½ù¥Ô(±×UÈ2ïÓO_¬<ݸ(¬-ý°G~¡©p•EÍPß\`´jØ%»!rÊ\d% ý~Œ_£²×N¤YWÍÙ¹cOy™nŠÄD–ÐÅ;®ù¸sUÀú} E(|SJ`HÿS\:òŠ=›üíB£ø­×Âñ•í&ÑPݸSˆ™[© ¬µÌÇ[â:NÆ¥ZÀÀÃFËÂÄbÁêŽÂ`ÀÚ{Œ<ß$FC—ãfãDÞZÁxõ!L“sS“jt˜T×b¥­„xwpiš\Ô2ô¥g.CCrxítdcÕi†2".b‘Æg—RùiÝõ'³â.sïžÁÙAJª§Þ¸†&¢mÌÑF<âTlDQ½èriö:\ #’ÜÌï´[1òÈÇHÇ•Q€{&)iÖÞÌ4,ãÊzÏæ}ññî¬ì©qFƒ¡û—M>Ñ¡]ûܶ¶þ•fU¤©†ùyÌ„—¥[Ô~cðÑÄ)‘¸§ð5ðÓ(±ÑWÉã¶o„]ÑY7ˆ>ljÛöÅ~ˆò¿ÊÓȾ½…îšµ ˜†ÕIÑövŸ ‡ªž.}š‚ëéé…ªcu~úùàCòº(WÄ,1Ý+V¹¥¦ôL·=Í glcpþEGú]_7‹Ò=ÆÅÿ  èX9|ç4z[{‡ü®’ê«i›¼ëBþå⬕|Û‹h¸Ûf•¢@Œ9Rmïáuxÿ“n4†Ã¯V½Çþ‹@}%ýêS•Ž}ú$Ø/ ïÄÝå+ø¨§±Œbv©Ò§†»½g¼ðÜuïi„e<ŒGšå§\åÈ|ð2ÚSŽã6«RLM9_fwb .i en8õ"¾„]SûB(sŠN!;b¾¶GûYƒûáØÖçÝn’ Mƒ‚b‰Ý"åìIýÜ·Í7¯²ðuÞP•œ»–ÌÊpé[â$ìªYÝ!¨îs àD¬ c ‹çêL?¦‚ö¡ +ÓOºz®šE‚™Dï Œvª:ñèR³¯"ö «Ÿ»íg·ù—-vgQDw§•±$n¾ÃèQTø€Ü„ Khs!â“ÕÐV›¤alšz¹(é(üÈô ñÊKÍ8÷Ô3,¿±´Ž[ðÏ'qûÐÜeš­ýp'ê_;M¢ÙÈ'ÖF>`«â*ˆÓ§«|%ù?)ý°tøS[ŦUjzÝ æ=‹jo p Ópê("[‰ÉÃCÇñ1]í\k¾žK¿¢†Ú¹U´KŽ`ht©\ +ÚuY ˜Do œÞÌlЩ¶a… >ø–Ëô|¬#6è8F‹ØE-. ü`îŽñ!/àî&\+åZ.åºf}º6ŠÖÖ8kóÏÛ¯{ÍÅ$tÔXÑ7´ªr/óŽ.½LÃIy>?’æ4ç lóÖ×ôÍ*úp†Ò *‚­[ÍÝ äPû.Â냶ñô鯈±¢1n´h5 kð|ê7Öâ·Ñ2ºßkiqÂÀ6šxã95;K# þ4q¨J™«ÍµGÍ€‡û%"&¸uœ%±ÄKjM“¼C¤/¿ Ê'ÅÊÀ¼ƒƒÜ èR æ' •Q+“‘÷ ãnUKÃÅŠéå[ÁþÁê7DŒæVGcòÉ°Ò Égð5´žKà·W¡OvQ0ç”ÆD¾?ĨPsqì7«GQû@CÅ >¶ÃïÏ÷¹ Ç?§8?ƒù㩨† †oÄ÷ž¸ÁS·Ò߈r¦Fçk‡¡ Š`z‘Oï™ïñlÔÒbô¿Ù¹¼úÖù;œò´¥ 'T}};>¿CBY¥›Ï%Œth™Yö†V!"cà8Ñ瘫†e÷²XÔ³™¼íOÞø"áe"U¬Q-le e›[ªëîÎ odp‰³H$WpÙüºµÕÓáÑ(îÌ­E0Ó¯pEbkXÊVBÕ•*wÙ—ÿë¡©øîyÃGzy£ŸÑk_÷[^ÒòÚVƆ1‚/áI(ÊÉŽ²%˜¹Y¿Áá4RòÜ$d…[€{ÉiyÁ¼ÉbŒ­üšÊbÄlè+‰ðVˆœ0é7^ôš™“Z¥a}Eù‡p¡Z*œ2¸ä' ‰ì‹2Yo¾ÕPÆÖnÏ;jÝî›Ä·€/qvG¥C‹^éµ`ÀÎÞØ˜YAÑîøwÉýI¨†š uï•-òìüJy©fgùìž½4óoõnÿ]I¯ñ@®(l}$‘ƒ6ÓH‹[톦}ÀÚ*_ò;K­zò ÓÖÖÅLßJ—Ö}¯£Z=„»ì—¨LwÒD/Òý»ý·©á¢ÑM_\öî²fêá/<8èÑ[]ªé_ŽÖ;¦¸†º%3Ī[šº´ŒöÆ{WAªï‹Jªî™û Ç©X^Ö}'´ev¸wdCQ~MMu˜ˆ_¬ŸqG}(c†ÈâÃÌ%ÛÛÞe]Æ}½k ϵòvW—ɰ%ÔÔSx¥ˆCñEY‚+Ùq!‘³y„aLôt–`Ý~ëty|Ù”;X‘—µ,…æìŒ1}­(ÿÈ$ó«a5c·¾Öm€\c=Ø5¤‹e³µzqÞçC¢ØM‰²pph®Ã>f}[ÞK£Zt»}âùJŒÚìØzEÖHè[ÑÄ,I 9 Ÿí“„SÄÌ,,ŠÇ©³wj<¾øæzð*-ˆà tÙHmò¥ËõÇçŽï©€ŸÛƒsò‚÷Ÿ\Fj­¤?M²o¿âÔ+7Þüº™}ÃÞ¾lwÖÜû57òt‹áþùmS1jnWÂzzæ *-øê˜ÇiT®»“1kR|® ê \ê–Áíø¦yÀx[‰ï¬e>x…ò;A¨Zºw|VA: K.ÞÐ|¬—ܳ8¾p§Ô]ôÚgp–7w>Ø[×L+PÑ!ŸvÙ§ôU‚¸¸/c ’·+C‡Œ¹q­\—_“*w¬5ù èz}œÖzøÜtl‰œ·O¦‘qMr ‰[”Õ=ŠÛ›~Ò “‰Wv%|•ÒÛXp³ a:YŠg¾ÕEªirc&(„*MÌP54ñ«—ªu‘H/iðÎÒKë䮓÷^¯lèVKÀTÒh”ÉKRꆳ-ãxÈØø"L„¨ñaË\ŽSDX+-¹dXJïæ»SüÉ£¸|£>æ Òf{Oà¤û.cS“Ò·û‰' olc᜿Fª Ûªp™àx 6¦F¹Éá|1a@‚W+ꄯW“Š¿õ³,;%Z‹Ú•?å²?¸íAúåñë¡„óöø–ŠNúaÒ¬<¸5ž)‡æò•Xg!—(’U!›È¹HççÊ»xÂ'ÕபqÞÍ•–¼÷a !tŽ!³øƒF_–´{KSµÈ· ¥Ùd‹Â¿^ëËÂ3aCÒXäáÒ0RÙϳ!.¢4>Ý\²!<¼%l­gr\[T7¹©žËÒV{c°ÀõF™øvH×õQö왥Ç(Xû`ÿåúìák7ðÃ9PBÇ9ìÏr“9…_€ü†jï”eóŒ•W³BÑõt2-^4ÉâX¡ÕÁ=¨8Œ~\¥|¢·¡Ça‡ÇTa~üU£kíÕ¼ƒbLd ¡?¦ÊXjêäǼ[tÆÐçž—åþ•Z%™ [à5ÆÛ¹i(\û|ßeæB`î…x A¦U6L£²õÖW€>ëTKÔ©ÝǺðŒeR˜ZÃx EtÈ0Yéh½þ¢÷Ë-…v2£´JÎ-(ž¡þËǬ•˜7|”æw#Z·ÈXzí ¿úh‚üvN/…Ð_.Z ¨œ¦ƒGC}5õDûÓ-t);Ù>kòÏ„d ˆU&Õ°r-ª†Ìñm>ë;lñÏ ß(]CCvúòC×®…{Ä9f½ûÔQ¨de Q7ÃPÙà"´•EBïÜж·‰ÒÚûH·7À ˆ`&¢Û${šn ·r=¶£÷$^úôü%#\Wbnõ!ú€f¹ICxVFÖÚwP{Žfqøx.ëåSj4i”¹¨’â‡îAÆ’Æxku±éŸ¤!Ô¤¬íìݨ™Døw~’¢¸ØŠÝ«•Œ$¡ E L[®q‘¬4J—Ïì¹Ó-ßV45ÀßÜ%ÁØC—*u3ô¾±a î(Ù‘×…t»Ä>–5»¯£FŒ’B2iªØÍ®UÐÀo‰IÇ…EU‹'Ôõe ëÑ‹úUj,c E!Å¿Ûdˆš/*ÜÉWŒ¡;O_òŽ&=ý6þQß¶npAiPQ¢W«¢vY7™Snú”8€R ¦xµô²böIì©yÝBd}ý¾“®ÐÎWh'íÔvúðÒÈ’h=P7æ;““ÈÁv;±Sv̯vøsqÚ²G^¨J Y¤BE¤QÃÉYóž¦Ô¾{yߣêŸÒÒó!5“s¦;X×wìD tlÉaZÍËw¼?mmòʹñEv|h4ÊaI•#züšÒj'Šö©¾eH4}Ö¥ðUƒužñ4ã(ᾺÉ•M¼¨Óeõ-ùÆäسTƒð ¦0'Œ&ñÇ›ïäs¸‘2B—Õ´5¬nNoyh—›%ŽñÚæ¥0J³`cMVm¬òàWx5eF¼^pG„ðÈÞYz=%Ì7§aa uª^&ì³»æ„Qͱ–"­Ìþ>ǰ¦9þj3Û1ðSÅ#¤”ø$§iXBMPj S1îÑ .œñ×!nWo]­ò·º«+ðÉu8`99E/+`_JÛn4¸ô!Åßzùd…yÈÖäš¶Z\Æad²íV<Ï{Ë»Š´¦Ó£,¨tËÇ 3‘‹‹V»ÛM¨2G\¾z½©«³Bñ¹‰Á¶èÍfùŽ)=×”œ¢oËô½…j¢-<¬Ü˜…<ŸV->/ÌCí&Ó ôE•µ·! ¿ÞfK–zS+.hžÑ¸épGˆøÕ¡wpÐÓ…m‹0GˆxM†^Èlo'2/5\ÝG8Ë6ËL Á¾tŒÙÏÐŽWÌ3ïÊL :Zˆmp¤Ì´Ä‰ÝË‚¥NA^3`…|>0.Çÿ?èç«—Ë©tR—Ù÷¥è©ÁÕFçGÖ7À•Ó¥k=3PHŠã8W‰'ËÇoi›°„ðIã+iâùBéåIy\ ¸VÁJÁ-rôÌFS“§Þ·Ú³*™û/ÇöÿzåvV(Ão·òX0UwÿgÀa§ý»ù±q$£×fLGŽßpHûœ]âÓ¼SÖ§Á"ÀVÖC°5n»õ+`€}_7/é["ØýáÑ[Ÿcú\x¢¨Lß½쪶ÚâØvq$…iOAÏy-ž¤cÂûv¼ˆ“p M†‚ЮÚ(#,Z™§ Òœ¸Eð ~­ˆGæÁ+Æzú!ô‚¶4.N“gÅs6Km²1¹æ•«©çÒ7Gœ¯ûN ´À\JVoá^âAÜÃwq1†[ça„õäd6õÓ|¯ gEâgµ/ƒÀBKùK‹y° p&ÓÊå¼Ó—ºܤ=þ…ÛAEÞì4UÄQ¼ÛHÜAJå):`Z^×8a¤»älÍ’¹€z¶"˜ŠòÉãs4)ÞàTYoƒiŒË•ðT2 OàAF»QÁÛæ*Žg)ÛÏmÂÁ `p»b_ÛGhû^ÀÑ,nË`÷-ævw/Ü÷‡X' wTw²:¶/KÇŸo%?ªœlÍ1á³ÅÔlh¥äû=… Óÿ:ˆ OSSñ¨í2Ä]å?lÒ[\‚*&´V÷!•Eú:ޏTrýåÍáÖ-¨´Qçn8FQ\%Å=¿aû6·ˆðmÚ É¿¹ÿ“ÎîUkÌœCtêk,ÎÞYzù¤öU2ÕÚq<¨k´ŒûR}xõGÝ‚F¤P©}1¯ÃzG%Âã€ôc]eº­ ðïÕᄤ„c]·20ÌyôûhŒÃ¬ÆåþYò…0BGýì¶gÖ½Ç%u™¯Ê” „¾¤+paÉ4·a¡¤— ƒ§¢žýYC¹KÊs›ðâ^OÞÝ;T]æÇGGS£‡äÿk™òˆÜ’/º™ý fÖƒoUWô„Ùs;ê%ºÑÁÀÙÍ(±„„kv«i¬<ñQ;ï 5ý€‡Žâ_³džHíË>Îz”u‹¯¦šú?3.êO†í±ëoFGô±®¢g´à§ˆ£yÓlAÈ9ý"vv {O!ôj­ÁèÉJX‡ÊRÉ•7¬Õy…LÑ庉È:J/_‹u…ŠÓµî ®>°ìJ5ûnVù5¦@“Ã<áÞ¢ÏÂ*¢ÍŒ:Ðu?–kdÉ>žzø=bÇ VéÔ±äË7×ãH3<‰ò›þÊÿ1’*ËxYHd=Ëq”â°dÏÎýÖá÷,-m¾oÄŽsH‡ò¯Efßä—ìv¾¼…úµÓmY‡«>¨ôùÎ]Aœ‡\/ÃØéÝÓ”åÞubŒ0 ƒp¦2ó3µeí[¾Å õ’áb”lÝSTpe›áåUßá+z€þá¯=ÉX¶‡öT¡lÖ1mòã²WìG¸nv<jôÓhtŸ÷À/JbIt7ÙÑU½­ac4àŠž½gO§Ròzpµæ’…&øêr½-9‹ãÃáh=6•úh¦ ݆;Õ6J(ÞBƒÙiyÀéKFßn›Ñnà„lÛ®”k''ÓM>˜-¹:‰ªºLT:åÕ4æ_j€ÝƒÅ7p‹Ô¤ÔÒu£GTçãè_<”<X›k³`’c0ßLô¶¦¨cYåø&P?±¯hJîQƒ’§’µBRnsJžFÀÙK9ÿ¤5´V ±*v‡« e\Tò¸ŒÉ(x:çã,Çð;Ü@jõÛx«ãò¶øéÑÙÉX >.w8¿'ÆžDþ eqð3ÉååÍÈ;ÕV­\.HÐEE-櫓cxÛrî…¨½:…jr$y·‰3»G¯±Aâ2‘Œ×Ái7! «=0h‡­Œ½Þ²ôÕ Zûdh¦ ­ª¢’¯I:—IÎ? ‹;8ò1îñáT{) üùº«FÍÆpþÑGWÉ’ÅŸ¡L«R .–ÛÒÑý¥¾æPE-ž:3Ü¥?µ¤[ÿí7šß…ZkïÉ!´‰mæ‘;lAr´™3¿µ¸üCé£<= D´g¿}ñARhmÄ{ßöÀüY4‡Ô=\›¥rHˆu}bìô1Ä</K/Í027°Òª®Œ”Z Q-b+#ð ¿Öu—X¤ Ûs”Ú¤3 IIºèÛ6×”ów«ˆ¸ÈP­'ò$ˆÁª'[öi."ú¶LÙkBÊÁ&\:Áà0.N†?âëÁµöš«âùdˤÀíT¢,‚½ø’`‹(Ÿ`ÿøÇ2‚] e×ÉY’`|›¯WØ5>¸?Ò#ì{bªecˆ[zæ-¼B@ÍÄ£©.ØöHþ"…㎘äc*’ìMÐA”?3&c Ô˜ï‹:™OØLá)è­„Ž8ÄMÖIÊ¿9  ƒÃ îf+ ¹€pT!~d©8ÖH×½) 1 Ë)þX¾{Ù§¨E?›:h»rV-ÐdÙ0^sÒ£˜B—¿¯ÀÖÑUág#¿îOºe«ÿ|Qo]ç“r×réèaè'=Ø´ÿÓ×Tfñµ “ ß/öÜlU‡9Ýë»ÿapºÎt¼'žElrÉÕФO%GÈ2º=™“³\ªOLfÀÜ#MûÜ›æ.ÃKè3¶äÞ"ÂIGÃaß芓®Nlu™Ý:¶¶Çˆ¢×²¡¢¡ý%*tI ¾åѹÚ×€'|¶›Æ/³PÒ´C«a¢©f»¦u¦VQD%émÙpØI«…ó ŠSüo‹\nG˜]û®:œüÈaxê×BKû"¶¦›ðòöÍ>JN¬S}!8cr§”ð>«Sàyˆ"à\ÐÎë?m½!¡ ûQJ÷6¢#³ëºÁ.ÔÞÒ/Ïe7Êq)r\A*;€-9Q¶Ùk]—Ó0'¼MÑ©wœ}¬°Ž‡Ù„:Bo×2+Îæ`W1i¹ˆJ«Á‹+Ô'-ÅŸákþÓoñ+5ë¢üqu òaPþ«ÉA2ìmTÊ» 5 { ƒÖ–±d­w6þfD«À­ CzÄe2Öa/.BKèìëMBIi@‚ÈG Ã:g=ÜD-­x™ŽiúU}Ø}%èÀm”ú°­Ê–ÿ÷¿œðó +¼› :[[Àu½rB¬Ôr{’{Í•Xi¸‡tj,U¶8fåRÿéÛ9ëÇžPÓߟ>[n±çõQz†»‡aF(Õûêlõm¦h<ò°y|î éçiòf_vIÔ‘o”øÚ{_Ñ 3LþY^r^]ð°·f™ã»Ñ5e–7`îWâži”0 ÆV‚{;I¥ô tõZ±ëµÑ)8¤H6Â@œŒ’¹>fxfY öí”Òê+÷™XR¥‹ ú™ £¡!ld;Û+¤¹z Ñî ³zq:ãUf.µ,‚  ã¶ÒRËi§Á+Hæ«Ó²ü¡ÖÆ•·V²ˆ:Zá‘vP2p‹^Îë+žÉûÉÖædj«º©kò) $^YäÈ•'™d7Ð~÷Dî[Æþ,q±µ ‡6Œ^k\ÊͳEù°w®è¥nÜ60W0#kî(äiâÿæPÈ(¼/ºç•'ðÇKí²éuAþ†D„_–Oy’  üѧۃ6¿f¤êî æ°7I}è®9Í.6ZöX“»"V„µÅf‘»:"l. Òä÷VË•êL/ŸEA´¬þœ¦fÄl}¡kMF$laÆå•F}ŽÓŒÆI#KF¾&Ò°`ÂcŽÉPð->{6ÆE2$Џòº2¢ÜV‹ªRþX©Á¿ÈZ:N—Z4ý¦ÿEØ]̹ÂkŸùщj7uUè…¶w”´XÃ|ÍÙR““Æ \õ9|1ð¯/×\ó¾z)®ŠÚJŸ~Îà:py_«‘ℚ5EXsã#Ýý‘ÿË^ŸmF*À±>ôSüLÑ;Eõu¦–A 4°G.šÄįs%KϰÃ%·ŠãÒWœW{mo­’(¨†Vºf¬T7S–÷¿ˆ 6zÁÔ·¥F<Ù[/ÙâG]…c™ì l|=á38õ/+âYhŠçñQjùúéBK=®o+Nfî%&;„þwŠA•vè*Vç`Pušà'Y™M®É£Ò‹Ù€ŸîýF˜–CB–DàØ³ë:çKâ|Aɧú_®-‚EÍÿ \T݈!'=™lj9ö\5×=Á—åâ*o+ƺŒ/22en´bêªr°´¯z€hëë 0ÛóÕ)ìngBS¸;[Æ!F4·¬ÿÅYaew­ý’?bþ`˜ü=h¤”Z»*®uÏE Žc 7…O2lp³ÙA{)˜¨Cøv)¾h6ùT=<µççwúí©V]„tÇi̤1`*ýÍz€0e6ÆbL¨0EÐ|¿¿'VÌÞM³m<û¬—kDî‹5‡P®È9ùõ1¼‰i§å+~ŒŒd¶1׸ê"²ÅÊRU¨á[Åè1ÏÆ6Ñ€!Y23¶ë’mÚl®¯äMJ‰Ö¼Ö]^דOh.Üêìø}Õ$²'‹°mÇ\ëv-ˆ{cñYV£@M–3M¯ó+¦¤sÉVàÚ<›V×°}8êã¨Ö="vÄ#™+ÝÉ0¯;¥Ãf8X.fAò¥Ô²Ÿ ›ºV%1Òžz2ÇbJ‰W4›K‡ÏÕ@3gC­NlÄ>2!ö¹ÉÏRJþþŸˆmQ‘×ö `å ¾q9öаñóQ9YºÞfÅðÄrŽ'ô1”H¬¼Õ³ê™àº¦¨o›ÿ¼bÁ{0“€Q›„øˆ¨ô–ê”-ôwÐnƒ+ô‘S0âLÿüVÑà] Õ¹ÒŽBâŠ&þ‰c|¡å`þ«]l¢W±K(zg#P x¼æÓ]©PºÀ»§o*°.,-A ¯Ö×ÓN,?Zx¨ØA£YBAÃñ¦6ãò «´ÎÝæ»=f}lêk¨ˆ“½2ê7˜gP«¹H¿0”êyŸ?«Ž’5g§Foׯí/ô$Ú›4Š5Q÷¥=PK¦ü[]ý‚øNTwŸB`•!:eÞ•O0n ÑC”7‹“­ÃÝ3Ó-ÍZ:ø*Èq¯=K —W‰Qj8þHÑ¥3éu¶¯ VÝ??ï€ÔAà$¬P~UyÆàiò{ñÚ¡KìåÆÁä°5¿q9ê,~Ÿ~u0ñ‹„ ²òz E¥oÞ5;.\³/1eÊ’¸Ä[å¬a|4Žþ»ÝL®ÌAºðKyD–ýȼ}¥ù±€e)eV¾wHƒÉ/¦À𪯈ԣˆSl¼ùHÜ?ã„[3Íá¡Gc ,,Þ§e_‡…•dKï]¤yPAùh›ôRd$wå¤þ‚S¡µq5†i\Á†º†_ñÈ_Õ襨k´²jÇʈغ5ÂímOµ?~–«î{·&GcÏ&qpl8—Se³ƒ™ýûO£Zˆ[¿ÑxP °‡U=8Öpƒ?SÀ¨ !)#RÎ2™=/öõ6[¸V®È¼,OFÇ“oëèŨ;sîYÚ$[¥Úì­`Ål,Ƀ»ÔX'¯Ÿ*¾;ïG´ÆU®¿îqA”¤ó½àÂŽwzxº`Í8rÏ Ø Hƒ·ßƒE±¶¯ØmÄÞï·mªÀôœ Dϱqäù¤|º/½ñB#ö¸¤¥Úæ%¹œ~¿™Í èK™*ž…R¢¯gˆÐoÈù‹$÷ËUÛï ¨Åà„Ð8î…šVÐw¨úÜ»öµ¢š*ˆÏ±¯§ÓÌbSÙ\ÿÀ,ª\˜› NåaZäš5ð¹æõ`v‰*ø0½¥þ©7Á‡|}íúJ1‡»¥ÉÓëîíß/¥Â2Nâcüò׃¯O˜–ê±Û­^PD½w¨îÕ–A©Å‰ °ÏJ@EO6(¨z7ç:íÑ_1³!yØ QðN»g¥|(&ÛÜIJJ¢›¶¢G÷R°×‹Njø™­­YŸK³±‹ÂbF gHòÊÑ•¿3´«Ü²D1žævÍR”î!â3£¼9õrì©?-ânyqt|sSôÔ©£¼œà­h©;1%ùO&\6¶´¾è{™öóJ>saDܼ­ݬH©ÍpG[µ‘d\üÎzΠÀ÷ñMþ«À–œÍžwOê¦x~†?ª ß¼Ì?ÞÐù±® Ì\â³ï3Þ8ݲtyˆW•÷ø<ï:'º dv§ØŒå7 §?h•´ì¹&DwBDèUx¦üÅxÝ.ÿª¥*¼òªñ0 ƒÂFnÝ‹¥`½B{ˆÈAšÊ‹‰„==Æï®³*ž™/z¡Üyò`êÒNAqhîœ2rq¾UÁà6Z.åã$yŸ4rȲ–åçAø{è^jÈù˜§QN–õ­xD­Ï÷Ñ»“R!Þi*ÛAb1Þ0¶÷"©Íú6i懭H?ú”&ËË )©†J í"BiX*=õŸÎÝ ¤{r+9ãMY)hf endstream endobj 2689 0 obj << /Length1 3614 /Length2 33413 /Length3 0 /Length 35327 /Filter /FlateDecode >> stream xÚÌúuPÜÛÒŒÁ=hÐ îî\‚»ëƒ[p'Xàîî<¸;„àww p‡½Ï»É>÷ܺߟ_QS3O¯ÕÝOÛú­™‚‚DQ…AØÄÎ$agëÄÀÂÈÌ PiJº;€TA6 Ge™³5ÐÀÊÈÌÌŽHA!ê:YØÙŠ@¼.'s€‚±X¼ƒ™™‘ ²9€MFî9PÕÝÄ þ팀Žàe­™…-ˆ¬"jgïî`afîôlƒ“áÙÀÔÎá™ à™ äæ²u{u|6*Â[Ù¹:ZY€¶&iF9F€¼+Xh ¶³ÌÖ¦;Ó¿L¨©ˆ+«$•ÔUhê '[ 86ÀØè4v98\A`?@“¿y¿ÚTÍAàÐÖœLQÅÙÞÞÎá?Q‰ª¨ªIÒÄ„åUÅ uz€¤šŠ*=@^,ük噸@ÊÖÄø¬.'®*¬ª¥(ÎÂôœ ÀìÓâ™é…C ð XÕÔÁÎæ/js''{^&&WWWF3gG'F;3F{kšgªæàì¬àw5è¯;Ûš€ ãä/Ï5ÈZƒs ú+(è¯E9ay) qUp¶žÎðwñÜœþŠEY\XLNü-?´°9þU¯g[&à"[X;2‚ý-°WÌìÔ韨Á…qz&lý7€#6ô¿Ãc2³vdúÏVG¦çH$äUd¥DÅåUÄÿbiçðbÀÉÙìY÷ÿ‘â¿Rgtü‹²¬¢¢,Àha î: ­1˜ŸÐÉÙ@ú— ü™þt@ÔÙÁá94¹ÿ[rø'ºÿ+‡ˆ8]kOo ë7.ÐÖÙÑãzÿ»”Æà†·ptrüÛ"è?™¶‹Àµµ°ýÿ_»g…g“Âb²àYå`°‚_Ìà)·5µ³±wD|î 1 p…œìÜ™þ÷ô[ÙÚ¹ÚzþÿX4µ°5yÎ5ÀÄÙžIÍÖâƒ3HJì?*`â‹Ì ä`€>€ÚØœéÙñ_ãð,fyƒsâíiog0Z;‚¼-LAà7DOG  ¸QœAÞž.ü!²pL,ŒÀÃ>Wÿ².ekjàù[ fòKÿiCê¿Î4ðfbgkín]SD&y;'pÃPÿ¿ýHú/ÖÎÖÖò`Ôÿ³Bÿ½hcaíþÿ½ý¿¶i€žã§þß6,%,Ü@&ŠNÆæWëo¹”“ÉLôbœZп½rìàëÀ¿‰å?Ò·˜‚=Èá¯{Ñ?[9ÿ’Yؽ4;8±öÖÎÆ–|x ü9ƒÿ:X_Z”ëYj¾'Yÿ{ ع_Vþ»¯9þ³ô_œÿÿ×vp=ÿ(/ Xû…%8SŽ ‹ÇóË5çq´p{ LÜÑú_MÎöÿâöy œÌ@Ì 8ëN®v(€m8¿Œ&Øç_÷`Gc;‡?KN„ËLØõ‰uû‚½ºÿÁe÷xá ¶ärø›Á¿ŸYŠÏ·Â¿î8Ì/±ÿ|ø «89ØY4,LÀ_¤þØ":n:Ìà Xþû¿Ozÿr@ñr·úC[DÄÎÍ“ƒ•ÀÀ >êÁÓËù<\ÞÿÒ5þûæú×å|ˆü~¾3@ 71âY;c¾@ˤ†O%>âyã¥0<Œå8šÒ1Ð?RÇ[ Þˆe¯‘‚óý?¦QæÛɾçÕóIð³-Ô¤Ķ~\nНø~a¢$´ô‘ó!@ÉRgTóO“›ÿXÚNJ³+•«UÄ>™ÖÓL PÙåií¸`{z}–Hª[Úü3Ƶ`šå+–ƒ5†Û<:~Áüx¤ÓÓ-VT8°[øí”aî'œiXû®Ì­Ì摵lí×8êe _OÖnìÉÒ¨~6_–7c}@aRËËZUô’Æœ4ܹgª¦úTäí66‚d15{u«ªSµ8*ôd/ÔR‘¥–³Tq¬]¸$ÉÏ]ÜqR«€ÑüAìø²Ë«³;Fb¡N«ò[™tCã_ØæÊݚݒ}w™ì·;û-}çÆÄ_ˆBún“ÉÎUI>M˜Â1æÑÏCѺ0ú¥Øàw¶oö¯9EqV 15áwSØ9w­É§û ˆœŒÖÏ{]Ôºøƒ=‘Ú¾rô½¯,B[ê«¡PÛÞ…Ý8Úr?2XJ`ŽÀ´½…®Ëí»R­›íææd60ÅQça$ •È ²}o÷µ¦Œœý—ðÜ/‰/1âS‚¡x¦â‰4Ý!Ü1Õ.r*Ä|ºón‡Ä¿±~”; Ï@(ývÖY’{Ý–H ºS;O¬ÉµN‹oUÃ+q+ôC4VlùmŠêoÙ6¶weyƒ}­®N©ãö‹8Ìüm–6+²b‚"$¡q$y¨:–ãv1+çõ·À>̵|†'[EÇ»SÁ›y ž>À„’îæÔWX»•iåš»_j̃ç˜à #ö-ý7Y±.«Ë²¶¥Ê^eåÆlÊjHô·ºÝ¬+_"÷ö®¶÷nñÊ÷ ?êb=PÝéÈ œ]%;B»(àc;»ñl0“Ò÷2ˆÈ„ȱÑU d‡ç¸õKZDeè ‰=Íæ(Ëc0·§øÚÖWµ7Ûª:z¬þþF[š_-ÍÊ..)jµ‹´ÛZç°x…+Nãé ªOGÆí¿ñmA6†¶±*XÊr,è Äóï<Ù!j¿ØÅ­\@¼g-im½+9F =“1¨ åîÆsÕd"_ż/{H „ÿh^¥m¦Ò’Ê%7°ªMÇÐ[X©5Ð-V‡¬'e3’˜oüÚ8tïIË_˜3vÿç­e\‡`ååPBv€ú‰=Ã/ß:r~§6k¿RŒÛô)IV*^ÿž(ð±2ž<è×N8‚žD· íõGí¡ñ~9ñX—†(ŠS®ÓQñôÚzêOÔöóéA·‡"SWow¤F›;Ø÷Ò_ÕÐ$ªØQ°ž¥5ôi_Ã{æ‡U] ·ìW Jû@ä…Î, 5dùeÛ“NýŒeU÷=~§* ³Ë€ÿ+›pŠs ;hšØmêÔˆ—&­q\þ2{ @ýˆÙ°Úëõßd¯uªPçe^¡Æ‡/ã‚2ŠcÛÓ*d Y9â¤Ü—Éî¶ ±¡’ÞC};ü¥ÎËžéI¤…F4à¬kRbªþ§Œ†Yúû¹6ÌïW%¨Ûê³!kæöÑCÚþÆ}x_w¾‹<žïeŨױįzu;ŠããÐìVnptœ×æíÅ}öi+>w)f­RqŒ ¡UÑ•xÕÐϹR]žtRwÚžÚ”²öNq>fzxÑ„>þ£KÓY¯ ’¤8oÓ¦rdÔ‰ŽˆçÏ¿#½UÊÆ‰Ù„YxUÆ•RN¥Ë1¬´vI‰1âG–ÿ¤‰OÙ}"Ùð%5ăd&N£›ENLû¨“ñ }^gÃcúÑÊ$ºþ*læ–b­²‡ioü›ÒOCTùÒ£}l«Û4†1ÄOAõá†èq2iß´ÞE„@ÜtK3ËšíœP>(9”Ït_â~ŠkR}Àœþ­ رÖ?P-Mb±«a׊¥”È¥2/÷h ?ýü…‰xŽ!âjM «¯ï›T[QXBehmbk˜{ʪû(ðÅ)éKcr(. œ³"¥Žþ—èŽQjIã/ÄÀû4i_ì¢é©±…Þ[Ìâ»=ãë¢4ŠÆ{÷ÌîU>1C2‹2§cWv‚K€¥«ÃQ—~Óˆ,kǼ°—Æ÷ñ†¸³ûT®@Y/›Œ ¡óó¡O»KFDï¥Ã^‡i©`³²7$áÄæÏÁ=á`y¥ùçg3ÌXùçwzêÕî©vŒ”1)¯»tÉ„ñrÊJ±…%Õ¾Ivé±E3*¿n¨ÃÖH÷ìĵûî»SÜPšsR'}+çë^}ŹöÐçÑ%Û­ •ƒs€å•ªÈóGéF©ºoÔvÙX–Uaï“ð¨n{ŠY¡(àܲ#fØ~¢FÝ.ü6˜¹À¥T¥Ú*v/e› üfüpôž¸p‰&’ÇɃ<7à]¹ 2¾“•mù§òí_?žL >U ”¹‘ øIi¢ {ŵ&† º ÖVùÖ‡|Zϯ;^%i ÀeŠþˆûù$-Öæaó<¾@èÓ~WëÜ`à+¥ž6 ç ç[Ê6ñÝß+ íÁ2• ЊiJ¥ž¹sª2‚•»Î²eEY]Teͤ9SÞùu«Ø–¡úoAòG[ÛÈ~{¨¨cܰýãÌ')½³ÕƒKúdÏášð X¯uáETÚε’üIùjÊS•Ä^¨™ÎNל0ÝÓF ÙÀ~!—ißQ5C(ƽâ´î!„ù‰l€=c™[Á-ãTÿåƉ§Q´ö:jo‚Ú¯ wŒÒÑ›ó‰ÅE‡"ê½KmŠN‹–“Ž#(I!Lñh]cd¦Ku$ ašºÔÝ3€™ÅV‡„BH˜¥ÛdÚ仕×+ïÄOïÅ¥ó¹by~L¹’· ”ºB'«˜§¥ìe˜lûˆ!†˜cxJë×F² œ¡›®P~Ï ¦$¯ãΑÀ³Â/snÈOíFÖZäã€íGt±³¨¤YßÖ;ôQd7CK—OÑ!Ó ÌŠÓeYÞŽé—Ï—[‡4bùJnàu}Ÿ+ÃŒøÀ­Y0Yæ ™­Ãsš—°nø{¨ÊÊ_ql†PKO79g ö±>¾‘°:´ñmAv2œˆ©ëÈîj#)ÿñ‚˦¢áêaæƒL® KËÛïåº6Ðëïp¯à‘ Jj[T£&çÙœ5óíÍʇï%¡-Üúâkñs¶â–µæ×­ÆOŠptÖ÷b×ͳµŽöx€íC-'N½3Û2$<>¿'•ŒÃ”rÔ@ _åÓ=B‚Oü“ÖdL¡ŽýÃˆåø ‘ õ tÍú®Ž=Ö 3óf<ø§²¿HØ4 öJ!,¾)”êÉ{ÌîYÿjÕcƒ£m¿èó{ž¿]È?¶ƒ4 !_³ÙÓO¯ÂM N@tÍ-*vù xZûqƒØ2Ùú¬ Dÿضêw+r”—íy†>èv™ ãTOü/¨ÉŒÉx­ÐWQÈFžïJÇ&Hµ?.ö“ªÀ<Ã\çYé`(î…¢I˜æ¡Ãxæ¸ …Pj–h4X Ïëš)vøa 1r¥ë£ q8aDr®cÙ-ˆœÛàU0é²É,‹põaöÖÓÄ<ýÆx cÒIbòýb2«#);ãqo±<Šêd䌨ã€Ô7j¹ÀR±G¤ÖWŒšÒwÞLtËJÞ?gm}Ê\v®@hL*6P‰tÃQð­Ó#×®‡—Õ'…¿8Zi%G]x%ÝF’2¥JÉ¿Iü~õ½äúN*è˜Ut–Ësaˆ£µ2òò.Po$;pcÏߣEߥ1ˆçR…¼÷œÛ¾]—X®t½É*Üc•OSë骖£O¢(Ü+¦£ê„+ýÛPßcL‹<ëÁ©¸^«@4mÏ¡R^­§÷0ÿ”oˆüòñÐs. ¨Ù€6ÄY’×ß4R\g™¿7Ôçæ˜"{¡¿þ$d™Áöë§Ñ§`ÃÔÌ$™=’û!2ë—¤ÃhϾ»ûÒõ·cŽžTvî„—2þ‘:¨Lp;Ifˆ 5?æ¡ «6dÕÀÓ&³‘ÎY¤!½óVdø~òäü3üØŽV•x[ &äk­aƒ‰’íã!}âé÷çÑwÚ üžO˜—Žt?¡ëÉóòE6QØiWRô0> Œ]Í’ÈeÕݤI©#q1ˆÜ5öRuÖ§6Ù¶Ö-äßoGšb̵8Y¸_,½Rcï¨K3 (;ýˆT #û)Ùj»‹«‚„$ç-õùÉ©dÜ‹òrJÎ!ìÀ9÷»‘¿gFž)bù¼k5&ãjZµäÅè;£zç;œO~j3F¿Ù%ÞpŒß{¤­®â/þ¢ÛEŒ];]\«jÌúLKùqê¦}«î›XþmîóæÐû»ªÁ‰ž`’SìÚ>]ß¶¯'™µQ^áÅÖé¡?šUY¢T@oÚÕÆ=W,Ò}ïd:õõ)$<}ˆyVÅÖÚן}UÓE ²Ö{0 Ï„ê˲/Ô§o~¬O2Ÿíɤ Ö°ˆÁ¸¨õH¶Và 2±ÌQÈ‹@±JGöÚ!4}…ö† ½ Hùë—JØ"â¬ÀYÑb­Þg9€SÊ ¦ï_xdš-·…'b£ýH­CbÆbpPÚKñïÓFV&¾*Dèº1j¨ë"f)›+»Îz3*d<.\¡1q¤>ŸÊD1dÿ/¾'ŲÜÛ¯{Pö÷œ­BZðÇ›M#ãt6w7ìnÕ%t¾£U8½Ìž\?Ž^ tóž6p%¯Sºâ7ðØh¯øÝ4'ïÅŒkòÆ8¦E(MG5Н¤5þ´»1é&R\¥5{Ö€$ ³QÃo²Çu³6ý»PóüÀËyW¯­öv–SõCK ì¬ZXÄbíâo}ÖmTL§ýjXóêoå…Bf%¬@Îüø/fÖ p2ÒÂäÙÃwxa+‡-çtàÙÌPÿÂ=5¸Ž«Ú([« bš^ΧÔMôˆw…ÚCfÂ~ªÃÀ[ƒ|¸­™ŠØÝScVïñ?Ø!Ð2ÙÒŒ_ýÄy]Ηb)“¯áÅ=8½”ÇŽ’ˆ»ïÁ ó‘|¬fåÆÑÝ^«¿ý£*Ä|n4³*‹bõa#8gvÌ_AÉŠÐ<|ukãÔIˆË¤±}j !íÞ`Gì(OÈ] {Y›L©Q‹EzåžÝô¾ã±wÁŽº öž°û;¤­ÕØ!Áé[£dYƒ œ.áŒ[šÉÌ/bÑyÙ.—kA”±È Q®hkÏåÇÛî¾_n#~ƒ˜*ý /†qöãyO´m<߇¸Æï÷S•=Ì£®Lè ÛÛ¤ù£À4ºÝ¬¡ôÛ—nX¼?|Ï҄ݸöÖN<»Ì´Ï3i‹óÛrˆa]Å­ŒÜÓ*Ô"üAÀq¬<öÆÇ<¬0ï‘à¡«Åå9^GÌ[ÕnÈ+*?ëÇY£‰tÙoõªËïÕ$˜â‰VàÑéFÑìò¨c‹¡2(^è1ÍàíP†rEº)âÃù,4M /:ß¾–zT/E\ÉôW”ÌE”£‡ç<ÅCä-Ó£u@—½n¦¬ñw絈‰†;¸«ZÙÕ÷Aë6ptÉîrílý˜RÕ®]*Ä…<¶3]Ö Û¯Õp\D`‹õîF÷ÛòÑû./|j›R•š$ÉÅ~Åû]µ fǨ¦!™èªP¢µY³`š‚ˆN¥ÉRèÆÒtçÈZziÙ§SÁ¡Ó4k4,øV­+;ì$×uQÄjÆÖ–²ïøN+Êé£t”¡ÀGFÄÛЇO©TšGb3»šQSÄëÑ ‰ùîð±ôÇAá 15#ã‘åx€‹õ„}‹Ÿ«–×î‹ÚBÐnÅ诫ª©‰’,I…½é˜wé×%WAg¿¤,×x¦Y8ÖW N‡Ð»_ÝÉÃ?DˆxzRR]ñ’| 9?àöc27Ý»íô+ÈÁIáT&óÏ[®1ÐŽáÙRw­m=fEyòÆc$ØõeÄå[B”`m™—ÿ)(Ÿ¹”¸ÿ@_²†›.ÛщS¼×y)5ÌæågŽc¡Ý!©&b&wš«G†/¨Uë¸À…úáŒÐCº”ü+ßÕV% M"àgë¥å¸â¡—fÕv"J‚^€ï$U­ò1$n¦i™÷'¸:`¦û™Èwå­7å(±oJƒ2â\.†n=cl~Î8®DÑZvs„Dd¾#ø º€»M5¯ð¨ Î¥LmïÖõñÿ¼e¶;@JÚ(+ëÞ=Ý «²eÔ€'í?™GsW¯ ‚ÎÞ,±áš¶®¾qñ@D8rÿ<<Ì›øw—'¹z¢ÕЋ<'Læ6õˆ½–ðâ!lå*E"QÔÃvƒZ-b¯\TüsZœ|ŒåZ?Ä–±C~ßÊ‹îÛ¶iWD7jÇ‘dÇe¦ŠÉKD\³-)¡~EbK)´e0(†ŽæˆH©bˆp‡ÇW/ƒ;9L>ÿüíq)Íz ¡‰¼üVÛdÏ!b¥âó+æñR~`y 1“ÈõÙ*Åì۪׃©î¿ÐfX‡ú"d&šƒ]{m§ ÈöùÓYÐW^íåï,ýø¬6<–¯'$Q%1Ù†0ŸÄ)]´àG³J,_m›rÁÉã-Ž< á¤tˆSpæIc¦$D[ãVŒI+ü‹\,†o5É:ñhLá ÛÞP€ë;/üágìƒÝoœç'é–U(Ø_4ÇHwöíspŽ|üL]È|CúðnÏ3{ Ö:ξ’`÷-a„ ÎORjsÕNÎZª=îõÅý\Lšø,ò;Åú¨=‹¸…ïÆ V®ðf1fŸ0…_bòº#^‰¢vH‡(“0$ÎeÒjJE.ÛXeé.=C_7ÍâQ‹,šõÕ¦Üq¨£ZÇÕæÎ×ûœ«ïÉßûQû˜[á¨ö×oº#{¬²×YàˆÒ^wà]nm¨Ž O¼dÎ]ˆ›7Š5ÈÂ+yb÷¿Uæ*a‘Jh«BTjÇݰüß1bØ×Òl>.,‡<¾Zíuˆç22­êƒzF—òÆe™jr”F¤h©³è_IC‹ì¢18¿^$²×°¶Af3K££sTÛÙ8¼‡tƒP˜ÉmåÝìÖj]rê˜ì5˜Èƒuž Ž¢Æ]ÞÒ¿Ÿ,6¯U½N wÙ{-Tv·û: a"ˆ:®Z0¬FZuà ¨±S›3B¦'䨢_"{Þ1aB»ugs:£e}™¤›¬¼ÈO~³—qÏ…®Ö+‹K»€ÂlÕ´Ã죻àžÈ cÜáÁg–YlpìJîÚ©³jw~ùî¶ ÁQû’éÆõ£‰ž'‹õ¦Yq?´B_9Új°Æ>@{OðZ gΡ¢=tŸ4)›‚$‰RÃÓ ¸Õ@«ù:eK‡(Ò@ Ó&ê0í8´'ʼnSÛr§š Š© Ψ€4ïÝ8‡OkHÏ9dA£}àéIƒúÇCù ­8©KÔ™÷‚ã‰XšSÎi6YÑ׌9}Lšµþš\o4ï58Wh¨Úò…/ô·Ò6p˜‹iámýÈ›±Ì‘%ÛpUÙúK‡ááKÐØ) ¤7âk … ¿A  á¾Q§Ê=ý9†_vá›â%RJ¾ ÏoZ!ó ácx~²RÔI—®pp} ‰Ö üWm:äd$¤B3Gj}ǹÄåRU›fªj(ËŒæ clœÅ¶õ8.|¢xð»^¥Õï?iÇÄ‚O]¡{§Ì—Öš˜§¿·7= ŠEoŠÍÑ÷ mŒ*ìŸÀ¢¸Ž³{u$¼á^`§ Ÿ<ÚÝþ’ UŒ"9à2¢Ê@^EñXrYfUÅ®[GCù¶{ÐO0rÔh¯Ë¿ú©ïà >‘Ó¯7 ­*QZQ˜ÁåÐñ3†'ôöš‡þÔ¾u¢6T’KÆWœŸÔ 5gï ÷0hø¢ÐPªå8¡LJÅ,"@¼"™ÛÆ$ç¿"¨RgÍ]Wªô¡÷Q¿D¤>à „°i]Ùi0F¿xûC“òj{‰(’|ÃWRîz2¸¥£aéa]úߟ˺*e«¸)ÛpÒ¬¹ðgùµ$&Üo“ó½ŸÙDÈ€(ýÐè®üh‰6†^Ìö3#¢ãþU1úPÇý`Óyž‡GMx¤_G}ôHîbê¹óä’h1Ëò‚kf¿b…ߥ0{)̯wKl%÷k ¾F¡#äÑ»ÔCyhî¥^jsöžÎO£LÝSܨäDäf<Ãøà±óUþ:c€ 3Í‹Y"`µ©é Û,¬ÌÜ©eÕù `eF¡wÓN57ÏjÌx Œ´2ô?»ªÚЗY_ó:X'ñÒN¹È£tÎÙiËE¡Hô‘å=€fĨÈW91˜X@Éñ*ͼ)ÒKßÒ¬«g°;´úÛþ^¤%C Pƒµ ÑgØIaKÙR–Œ[“AÁ„è^dkDM•ŒR’ ÙÌÕUXVÁƒzóNÕës÷1Ô:…‰ Û89HQˆn¹6Ç2öÔù~•á>#ð°šøÓ µà=D«LQ s¬@¢…Y5©» ѪêPá)U„FÝZF,ó}!!NTÑ~ÖzDEDW°€éìÉî/íýúç N˜¦JºWÄ¢g]|ÉnyÎPø O ô†zí/ÒžÎU|kâ— [j©ã7´+®ôý%ª’ã”Uz‘Õ&SZsµPÈ ED™J"Yª'Ö‚ÉŒ<[OvÞ±Ëcñç{4¿D–#9šû9Ó?òçV®KGkÛõ¯øåÝëRyÕU{¶žnÊ?,:| <ãˆÖŽyuN¡ô­í+¿>¶Ze fü¡9ݤÌe&4¼Í§cö%sÛ6ÉÜ¿´ ×UJ,ꀫ·—åþ^´ð*Î,ï¾Ã`´Î,sÆÛuôNް¸Õ¼ý¬'ŒÇ†™:ŠPNÍq,ø¯^@ìú¨VB)øµ20•äZl̗׬6"¥ ¥î”éGZjµj¬%_tŸùô[¡YÖC×Ï%{„ënBðê1O9B¿ûû’[ËoJ>@ù%½[ìñ®º3ò#´¦ÍVмY†7Q§Qª96»·ümŽÛX­ƒVÄT”ûa7iÆ)0<¨õëùœÂJsY"Ëî$ÅazÅÒ?'~  šqÉ~Mô­šeŠ'Ùwe¦±ì”^wÓ9d„vô CU{‘xÉϲ¦DÒòY9j7•}"»:×ÄGØ,ß‹é›`¡1'–#èßrXHHMzö® |Ä  ëùš?'fš(+ýÃð0>d;¹–÷€–ÆÀ*¯Çñã8šó'WžŠ1€`™Q'ÛmáS+LÜìê#}é$xÄuº!:'ÅRœšr?«·å•èkG~ôœ]kuA™Ù®ÊyñâïRسz¯”˜1<ø¶Ü$?p:çO—æèÒ=ôJìxw¯«(~ˆ .µ¡u!”—ý4ÕÏ´»b‘ã ½?ª[}]I~ÒÁÆ _—¶†çŠeâpP!ç_ÂVQV.‹Â¡“²Tƒªtµ:ŒÉh]÷êX”ß^íõZ‚—Gàì¶SÖ­…æS­Çj7:é-%'®q£]¶ßnÄc\ÿ+ª#`. L3¶x`ÆøOB¼hŽ&´›’¸+ßä'7â¹ÓRXnéÕïrNö©ˆM}åÃMŽáGKgø‰ ÚBÏeCrSƒ¬»¸õtH-=$ÒŸ§³ËGXƒP+1ôK}µ\Q(ËVßù¯~UÅ›á&A7Șyä/Ö«h§Wå„¡M³0éÄ·ùIΆŽçº]äÍÇ¡k´˜=0Êx¶)ÐF¯*X?[õù#ô‹ F™0R “ß}Åx—ZΧ¥T¯1KïJ=»~Ê·¢ÅÓ]xoªÛ]•92ë2¹¾¯f›¦ 7¬Z¬L¦Aq‰•µ•Ô†Á› E€lr„´€€`[ñÎÑ5‚nÉGVgµé»þINe¹pÝ [„u;‹Øú Y ‰äýlÌC5Km%öFÝ+¢ÙÌ”¹6µ‹Yϸ}\M:oÏH±ƒÄaêZѸÅI%ØŒJ>'WCv)áÉ1ÞAHºvbéïÈ2àIO­…Þl5ŠñlŽYaý0OÒ}uîÌy’šôH$ºëÌóüuɨ œÙì>ðÑrãϵ_[#¤šy ³ÙëOô±ƒµóRÓô?=#ß&' 2ÚÁƒ£/2ƒÙÁ}…ºá5á|ÀjÄ>!ˆÙ¯5g´LcþÆHÄãN V×’ž*%:¾ý›ÔyLÃRù›uYéhˆ¿ªG?ÞWln SŸ€ÎÎa«úY)ääñE)z´<ËþƒŸ2·œ¶Ì*y«˜H AÝXÐÉ4&P®(”ôŽ:2wL%0ŒìèVÙ²¨ˆ¡`´2o¹vJš–­ª½cúBy,¤+±±”À…Èq‰Ø•‰ž²í:h‹Î!‡¯$´'ØöYö‡ÁOä³íqé˳߅é\ÞËÚ °Õ<>¬k³üÐ"k¯u""÷½`6rŨ4 Ho[R‘r*}êßè ’†rð| 1Ø<†‘ÓÞäfRq4Q¨ÇG×Ì–¤_ƒÉ4SÓØäõõ?‚P&Ó\ÿŽcK´ \_|uóþiÄÛ6²Á á ä´o™¸þ×y ‡Yr~S\¨Å¶ñxo6Al¤³·(a«i–+Êò‚–©'”@ùy¼”H$ÇJЦtsè²VX¥JÍŽF·xü{Ÿoí·‚3µ™Mú`àbS¶"€G5¶<~!ÕyÇâG«ÐX‹–ƒÐ*¤£øI%U©,4"|Hý·Yð!Œ]LQúƒÕônû´çÍ2JˆßsQH㉋Ý>b|zÓÝ㼿sÜ'ºhV/¶CBÇÇ”T(DJ¥ ƒ%}û‡š.o³êú¬«/Ì%çód€µOÌÆl,í7„³#դ΢÷"6- ÕKô\ "×%”Ä9úG÷?´¶FrL܃0ô$] ™F¾×5{?¤‹ão©»ûÅQ•º³ ªÓôÀ»Ö½rÖ­xçÀ©G˧ dQ» L¥÷ 1½zÂéÏBl£Džë‰†7¶˜ÒІççó¨¢!l¨Fò8w:t+ÝܤàÈÜk$¥.ðšÖüeûãæîªªM"ØÝ¥‹qðÝ'ßЦ€ö^£Þ¹K¦ž7·»¥åZjœXo…ùHZZQ­fýyFY? ¾ÎKŒÈîq®•nÒ@ÓNî.m¹‹kWCIǘS/ £6i4 ®DòÜÍRyFÌz £ W$ùÿ&Þúµ>n¸ä©]dÚûKÕ9ùKʆÒMlöEÏzE³…:|@}^½ ²äQa—ÂÒMéZfsÅ~êõrPt³ÈYjŸÛZeò懔èM⟭|!øÞ™ãRò«-|<šš¹pV/—a¸US‡z÷p{øaz;yf&.”Ŭú(¤á–NŸôñ#ï=ɇGmÍš{7\ çI·žŽõ†ß ."T¥2Ø«DCfbÐ?W‚±8”/åà•×pý'µ~!†«‹½O €ñŬå[£úºøòqÁJ‘ßWY²ªüûù¥ªÙÕ{m <›õfjbÛ­Å’ïog…ch­%ÎÐݦ«—-ˆ©¶?¡R¶Püz˜…ø:xæüóFó¤äÒŠŽ×qwî1fÙ÷®ç´«úÓׯêú«ÛÈR&Îí­BÐÃÕ,MEc¾6Ê“~ÜXtþ7v¤ «šž¼6 T–Sª°ÿ )ÕIZ,6¡ËÆYMÕ:IïÂö0½GŸÝ/ꔓ¤Ò«Gå‹[«(ݾ!·^¿9æow2õ¥ÎÁNOq¨À•FâI×y¤’ðMz|ÚòÜÛÁÐN¦²P¾ŸË›­íißgÑö°i›*8™Ç’ct^Þ7õQÉ_!ù1ÒÏ+rf&YÐ _"ßñ°¥Å™¾7WwûiÙ1SD/t9äYŒooÀ: ›Zm9r›@÷ic¬õ‹ôÍ'„¡Z5£²ùþU¤ª›w†Z#W°$ªÒÒð»í`˜Q’ðè»ÍÅðÀÄ({l8µ`ö¡Ÿô]ÜB–xþZ5ùç×ñ”}ÿ5ç½ÅÏ”È ¦¼Ðö² ®£ŽM3)ßÐb ªŽ~ YÍú…ÑäéÖªPWMLï7˜W1¤TrWäxp{$>¥JX xôVŽ…¢Ã½·£²Ù¤ %•6„Õ”†SÞ¸v)<øâ¸õ÷a¿øE=x¨÷=ñƉoì$ˆì$A‡Ó6°R)I &|^Yϸj¸¡œÚïW ™¹®t¡˜$G˜ù\þŒ;5•^ çºæ¬â¯:™8 ï` g~(&O˜ˆýVw LFš‘¡ÒO;‚Èð¹žÈj™ÒŸÏŒ§Uq^ßñãl9F×5]¨æ”ïPí|…tVXdÑ =°ki+=<Ðø‘D^I?û*¢êsß·›2µÜÖcºèò¦ rýß$"“´Ab†%q2ÃVú×ÝRæurrßå;ÔøšèómI®frâ•M>Ìn4,¤Á9 >Ôªðê;gy­CF+ë™z½BIh÷°‹E*7S¾Ò9ËÂüáuaOΣ¯gºu6jáMÙ½¸ÕÞ?»‹GÚÙÑE†ddÎ!  N6.;Ÿÿö® YðÅîC²ƒ34%?ñÞdóëD]ñå®iåÌÂhOL‹Ðá‰OsÆÈž¥û+È·‰’Kìsw˜­µ«>È›^ÝŠ¤¹ÜŸ}è'™p·[ð@|éÛÅ–¦¦k:ezuÖs¤Ükeú:u±-ô¼N—šÍtI‡fþ8¿ÌüÛéÞ8(Kõ=Ø)˜ëä¿qÕ×ÛcÚz\VáËãdkào3lpã`MÒ©àÝ # fqÚþæ?ÒɘQöžÿÎ×ñS˜­i¾Ó].F›€Ù<2'*×]±jà¡‚F}¨ÐVÐ:v Ju`¯Ã–Æ—ÀÆ@ P§ëqµøÎ‡ç^zYø[ƒ‚L~¡d|ˆÌiA‚WI«…íâ&טhµÁþì$޵4 >²ò!Ä$³®}>Žº¯þqW†3–Tìù+C«æ¥ GЬÑËß‚ŽËr‘„µµU%„hß|[öæŠ1ÎB0分™ &f¡(Ó«á¦Ó’7Wúâ2SÃ4¯økBç óÙ·ðÎô®†av\6äë^Wìüj¿0[‚ |;еB"Þ,áqoR æÃP…+” ìÕá¦íX‚ØË§5@’Áâ‡äšõ’YMœ¾šÞLZAÂx§Ü,DER_NWuL¯3V ®£JóÔ¢)£¥µ&}|ú´òƒl\ò‰¥JüG*¾ý°‰L·É·¶átû-#¾Ž–·â«±Ó¦Gæ'k?eU!tÚ“úë-'gîg…Áí‘\Íü^tØi{qíä\ž™Ï¨.*„äÞ.©7š™üRf~iR+…FMH4x{XM$²=°R™Í!Ì¿¶qZHCa‡ÊÅskj´Jcag‹ {ÈDïPô¹~àñîqûúM$¼†¤ã—!JaØšÂSÆÅű¤á7å|,޶ocŸÜ]fDo³ë1ìØUÑ~•–T“b;¯ø–þözµ¢‹Û|àÔ!¬Q„™æ˜Aí“f²¶q1³Ø±ñšZk);š"D€…¹_ý’ÝH½Dî !Rİ ±2i?·Ò4ÙëWùE¥¾j`ùçBü6t;­À–,dš‘| ¶dÔ±/€ßýòŒgû‡Ú|õæ†êœ—ÈW\5³: å¡H*3å?pê“Qõ®"”¢OQ7òn{&ÄlœøŽÃÞô•adܽZçù´Ý{íÙÕ£ËýƒXú¤ýÁ”¨ˆpä~hß6kHã(Ý>›|6cY>«'œ™íç‚RXãF ‰{Í:N-änu»ÓXi§ybÓ–°opg^f]ÝÍø#¡ŸQuÉgôևؘštñŽh½á·§F,eu07ß9¿µZJkOòç7&, *¤©»5öðZü`u_Án­þ·¥¥6Y$™àíVP0LÏÕ†Æ+íQºåHœ©ýÔ¬d`ÄŒ%ñåë5ëüµ#êLæO-¶_<‚áÃ>U¢,9Ü8¬ü»áñéöºœËOþéh"µÓøÇi¦ôÙwrÁ!è‰ —›‚Ô:ªL,Ì åųŧ±é9±~a%m+‚e›q˜ÁüÕ2^Õ™‡aT‡6A—²43ä~W­·Sd®ÿëŸdF¬|½áºjX žš»WnÊé Ùi”£ÞÙ¿M¹­°Ü ½/›Ú"¿' Î/„"À†Pævs7b:}š±ttŽŠ„„T&ƒøý”é…"ET…@=Ù7çÙÙ<0Ä[y!êãOLxÉÚ­d»%ð&–½AgÓÎÂP O’3Ê:Wª,fÓcöåfFÿ¾1]͵½Ö’1yÉmC¨ŽZðð5äÇÆŒÞ »ÛºW!;2Æöç9BBËhÐ â__á±—–„帼¾B¥È>‰–BÊ⢟õ¤w–¿îÍ‚ÃÁ¼Eš/²xBŸkÊðùDüúÒeÒdGá‰Ïáàl= Öó{Èß=é›!LI©‘°“P¤˜™›O."U‘ŸÀ5Ž\$8úÙŠÔÃlsr;NŸ€JÎ&\?s_éß6Æ:Ó<Ž@ëI4Ä©WÓÓmÓvØK&(ƒ©ÌâÍEÀ=³k†£,Ÿ_¹ßPh+#Ô;(î` ÃÊÊ[Êõ¾ìXwÚ´ºL Ió])cM’îc¾Êqà¥ûI#à°É±Ý•ØU~µ M!ãò¸Üßý½h©cpL×½ïWc1Ü!Fê®~5§ë:íšĆ8a>ü¯y: y øó%i;~ÎÍ¢Ô¸›u"Y$ºæжG…#íFu ÄËV}}¸¬Xn®:Ôá¹|VºÝ=hÊørˆÀÂP”²ÌÜ• áX±×Tœyk@:*óÉhIEiÖœz›I ³Ôú†8 v¨±`Õ.QÊv|šQ}kÂQ¥Ê· _÷÷FK=ª0¡c¸#¡D+áÞüæñ½‡%½|þé—€OÛÆ}¦æý™{œÙþÍ;Ÿ·lzXO§‚RÓgŒŸyõ¡£j˜V|‹Ú^_¯ÖÒ:ùJÌÿÕnØzõ åþó+fjn(#x•ëv˜ Ťœ¹¿ÆTÆé®Ã(*Ö!ÜÕoêúªØYðš_ߢ9Ê¢: y÷5 p>ö5±–ØÉ”‘…DÐxÀWOüÞçÐZW8=î:¾ÿ8–õ .3."T̼4{+h½J#c$Llsí---;wûCë(ÛZŽoc>ÍßÎèzAÝYKGþº‡NÐæùÆ·OmÏÃÁßDRzf~6pbâP£èÕ’}Û©)ek{Ù÷ا ­«öóò.\$÷ýûd¿yMî©YžïÒ:h1ð‘ýŽª‹?¼~C ½ÓY 9㺂ÖG©‰ezû}pmÛ@~v*þ°oªT†;R Þ(§®o%‡FïÎy”ž:¥u¯ ÍpÐ^a»UAÇP•©™¯¬yˆXÂ}]½ØÁÇ/2 D d”¯JÆgrAôïÖ}%ë38§W#µQpVäãâ„<Š!Œáe˜½.Ñ7ªÍµD¿±I[?ìÅþ\YOFm½J¸÷ýÈÌ݉&K>û AèÓC*lÁx† )}ÄkÑ ¡Ûõdê!:£…æ^a†Ÿ&¢ëºcQ$e›b”Æ ™³%îèÍùM¢ö6„b˜é_S+‡?e+:JÛéµƺ¿—•…QDZùÊ i²ÂéV ø.übqôåÄÚ…[† x ºÃ1žUfp5¨˜a—ÿˆ¥B¸—ÎrQuãÕ•£×%ÎÌŽOø´G.¸_n5}¥@ö-J¼¶ÊOxIwùkôœ5çîȰvÜw˜ëSvlL}ªrGKd& *ü|"ûéð›XAÚá¯äXÕñ"² µ»B29hã½è,Ša–^K 릯®œæPÇä#‡N¯TÑÆ>¢Î~úùe»iÛ¬³JQÊ2OiÛ7}U°óuIç‹áß–Å¿ÂG3ü²ü/Ãw¤eÁ²ä­¿Ë‡ø¶e’ân=4§ª¦Ûr”ÒÅ;͈¶Keõ÷åyD¬rü¬*àaC¢3`š;)\Á”iÙ mi[4Q)i–Ô¿ü…@äAýÛà÷DC{Ó:»Ùu6P­£5àœ±z܆Àl4 Íç!•mö鬋´(CR«›ÐØWqƒ(€—U YZ<;B¨ü.(òˆ›wûp¿C®Š5CÚ@†ÜsYëø2jžàSñªÆPLd¢nDe±¼7ÜÌ„—\–yð"u6òiH#¨T1ê5b­“·Rjéщ.IZ"?™¶V+A`SCî¼gÐÙ[žkdØtÑFÃú’>ü“öSÂÁX!2‰ F ¹o.ClI×)aÚ&³Ñ|ÇÃ|LE[.ñúêÿ6îa±†kplÛvǶmÛÛ¶mÛ¶“۶ݱÍÿ›¼£snbÕªA=I,Š€¸×YÔ{oÍ%p4K(°™Õõy €Èk´aÖÎY™w²{ÅrÞ?7áâVwu=_i´ÝüT£kû2B¥Gº$Å=r^H9fοîðŽ·žc(¡´\0€à‡ÐÙÔ‹(V‚bš 䌢Îå¾ ¹Šb=.²œËÓHéE8_»ÈgM½WôëNƒ÷ÙþÒùšÆ‹44Õó¹­Ê„`¯Ø‹l´†g‚ËN õ䳜,ýª»­™tÇÃtAšÁ³Œº‰Ø@â”– µe“«!Aº_‰·ï©S×ûŒ<¡’Œéº™†ìk厓îó5¢®® ijÀuÐìçÜÛ®CÌF< ñ†²3kUç}jÁýðyÏØzÑ×ÅWKÛtnÄú-DÈøn1Õõˆ$[h<Ði‘3Ñœ’ŽwÔ;ü!OŒH„$®Éô÷2rð+? ³£‚AGU‘,˜o ùÕÝ3º\»Œ=í$›d•|0Åg BÆzMD /Í\‘×”Âco!p«4e™ZÍ<†5ȹ‹?m1õçàüè Ö¡,>30Øg~N×4k†$À­¶)Ã4­K½†5ó_ ýÝ?R!…½†Œwš¡´ÔífÆ4Z¬ú5x)D¢FUÏ¢{K1Lò>2€å ˜¿Â,fÐv¿A†ÀŸWI>f>*³O Adü·V9ëHŽ»D 3iÏ'«ÓìÜjK/ïÉ“ñƒ¶¢£‘ÓWr(£ì}²èoa¯×þÈþÒ#«_‘!a¿6Ò#ÕKRƈñöK9áàÇ (è’Ç,II`!¦ÌªÄé°(K4—¥ Ç5êñì¡ú®$ÓzdÍ;5ÆàÙ¿âq0ÆpϘçqg"þ‹…ÐB‰§¥ÁÇ5×芴ù¤¡’–{' E4ú‹.7®ÔI‰ê‡ìTÈóà V¯Z!U‹~ŠëZÈšH³f)\(¬ÆïÈá¿Á¡¢²ÊDyêd& ¨v?‡‹Í%ý<6[´Û·þ/jôŽ;–s¥žÎs¼…Ñoá´b<¢ÃŸ×+K놑³n,¸”8À˜µvë|å3‚žè!Ç+¨×{߇&=Ó–: é·Í˜¦½vÃ.ÍhÐÔXÆìøHµu ²n~¿„3Ëzǧ`ÑÚ :M,¥MÞµE=»¸†ùadÒ‹VhÜëˆl‰vcGH˜Ï¥3mÓ§QG)Q‚ñUpà†Ú=ˆp—Ùi?ÑÏndðhSÏÈI„¤/ÓaQÚ“¦±ÍÃ6”8›DÞ `!5Å``2÷8méÍî1Úúº…˰ªÎl! [÷Àåu¸Á…ÃL¡µ3)ÄK=Û1ÇsžKó›­8Žœ«Æ`AU bpQäq-Ä| hW×—Äö0šlI¯¡þšH²ä©¤¯zbëÌ ßÓ¢M³é1ª?ÔɶúýpœRÙHAåEñÜ€×¥¤¤{̘óÐU$ÑíýÉX9…F"Þ'UDÑ/$ù§ªQ›ô:ºæ\­Õº[n+²tãI‹0ÁfbºMuÇ"ùKœDã¶óŽ˜¯UãH®¶j~T®j ­ä`qŒ…ÜTtCû‡ ªMåLֹ׸A­ƒß|¯f¼e‰ùšøGïð.”¤bÁ–¢aü7ÉøôúT7…<øa`½Ð \imtx¸%t[!B ]è‹•&l}ƒA¹ý ~~*Ûö<}‘¼¹Û÷´¹r°akìÁ¹Ðœ£ÃeÂÐe³©þáÈÏEf‘°ä0\ ý/З¹'¿*Ý}Ò(á3ünæÏixš$ùé$oqÔcwžÐtˆÃONÓÆ8ð®\-§o<ãS¤å!‡1^ƹç½þ• õ(moq>5eãÄJ¬ /˜¶—=ùîÐùÀ•/êõõå3œÑF‰ìw—ÔsÝ ÚÇTô±-Nî±U|åÕsÏÇŠnƒT §, ŒLR|÷ñ|;w˜AßÛAFB¹Iȶ³äıE烌ÖrVꤻ5ãúªd{Æ€ãb\=âd¥-§7¤ªX3˜º:ÏUþö¦>ŸŽ†p;—6ìN/EM<“6øÀ{0Lï½M(?4š±N™è§mAÌõf°¬ V€ú€ƒÌï­ËϯQ—Îå%q ïÕXŠþ`´Ñé¶!ï0ì¨êùwkíÆv ÖÚïåiçZ64郲Æä AYäµ¢n •áÅ„B~.ñû‡±÷¬’¬£Ïnñáﵫ足ÞȳR;ÉçñšŠ¼d?ÖmÉ€­a)¤‚¢²f-ÔnVÎÔòÍÜ è]y ð·“x óHr¿÷/ (Ùœø6Áfì¨Ðvj~ܳÝJ늪oÁ@Еï1ªËØe{i4”ÌÊÃöspwi>R^º`÷®õH ÅýœQ&oëÆÔv|( aP¡Íä½£!Ò°Dòñ×4’xj-F>z'C0˜Ë´Í¡Rµà¹ε!øK°v…\+ãdÎÉâü²ìäøuñã3hù‰ [™=GZeEv57” ,Ðaƒ…mï Cƒt€B›TÆŽøðb|ö¦b¬îØB9ÍÛØÁÀØÕ°c$¦¦ÿ=“®³`Õ³¿á¦%ÜyŠ«üUÐô§»5Ð ¿µ"¾”“LPˆ"½IÊž­¡µ•¦Ÿ¡&È’)%À‡C“J'Rð-[ן%%b‚ÔY^ÛߢÓ*Ñ–æc]kÇùú<î¾›…[¾t€T4IeOÜ~+™²rÙB–NUSpèT¡•q1C±ûæS,ø¢–`à|–±á9_/ç°YÉ¥rWZ9†z[wO·§ÓÓF­ý…@ ML(uü,#ýù€Ü8oš©ª_X§9ÂUúd£Ž\$ÉìñÖrp6û@$XõO¾)Ð U0.qÇ%”Nµ/Jsë}}Ž ŸéäpyÁx#þ;ì5Z1†\ES,m)M´ä#O·Ç¤éžg¸üÞ·…ˆÁ_Po°‚ WB ùŸÒ=† å6yèg¯òè°2…y_°*¸'ô ñˆ Íg±:uÎ7ËùDÞZEŤ³Liñî6Í;j¬”V• ‰\ààñUoÑTŒ ³ŽF܆üAÜ '%‹0Œ]û¨ÃCî;Â`¯ËHjn¥³:åNEƃ7S4ûpùök E?4{®úp§Él¦ü3Gã8?û`=(c±´Öyœ`L£ü¼Còà¼Yì5YÈÞuöÅŽ$æ^{r˜åù -ñ8éwf½QëßT•·q—ä/EŒÛV q•¦*RÊ”èemõ©H ÎÊÝ>i(s3k»Íô*9« -¸óˆ[%¾^2Ú½ I5T×3GzJš¸ ±2&a{Çù¿YpŠ|buLiÈ=yÇÿàßzŒêlʆ]\½“<Úò®¾ç4£ÔäqÞrây¯Ã­ï!/|`7|n‹g"ÉmScú½ŠÓëóß2 ÍÞînýˆè…Bö‰NrQã!ø3Ëý´@Cãê R±õY(Ý\o1ž}kFÁ±€p¤)w£òQšUf¶: …yv öÚ,"ñ«Ì`šž(‹—%×RÅRü¶&lF(ŒœÎAYaÑ.½`õ^½Eâ§}=‡8{Ò‘0V|ß»`'îÕ£!’v‰F“£Èà‹Í@sT­ŸšÉ!>s‰Äß^õ~‘ñ;V‰X­ÂNý¢Ð …R¬ðJ—12Æ!©ýÑ›â–`m“ݳeR_`{àÊ Ä ¡jMš‹ :Oažûi¡ CÔmÜ$ãzxè7†€˜a*ï¼ÃŽ—-õ&TKÆ*‡‚G¨®XtÊ)5Ò‰?œÑ}ªOx£Ìï åi±ª~Ć®ÀÓh½Ûµ~}à‡#ê0x<\’¿(ä_zÔèþ—RÒüœ~©nƱü8@e`Õ×t÷Ÿ„|…ä•éTÈüQÿÊâë«%6“Û÷ȤÂѬyƯëf»ì¦dƒÇK‚ü'X½ØáÂePn«ukÈy‚ð9R„° >‡ˆ˜á}UëJã£0ÛÇBq™Ë(²–¡Ôê…§ýÕvs˜”ÏÕ˵o^¿{h(!àá¸âÝË}’Ú퉹`%§åÓØ7i‚²bq=‡þcV9öŒN»)Ä÷†Ý¬ºŒ™AoÁŒ’Ì•æ7Ó’âÑPÓJ—b"1µÌÄ•ýÞ“Ëq‘Œâè3‚ìЗ‡ÐÙÄì6*õ6½EÕƒM[¯_3@GÉ2˜Hö:3I‡WÍ›C Q´dÞtÝ Úa75š×`zÜu ~¦' Ìl§(œ&ß™GÁ»äè½$†)ƒäiîÚø¹ñ•}pmõ ªW.”k=ei}› ½ müÁ÷Q‹Õ²ñJÿ`âÊò Á[ö4÷Ž%;C¾*Á5oé›F^&Ûë}À9À˜0È›>Sâjê= yŃédz;Äpr·! ÄÔƒÜÿ-ºËXgÇudž5‡Ìé i×Êc%cV·õ‰ùiQ!‰ @6¡‘ÖnAÔ€ò8@™Ry÷$5"Àìb“tÖ•œ:4ð¿7~‘_Õ2¡õ"éózì–‚'‹lG.ÊSPñh ~âU3Ô”¸êÿv) ’ˆ‘qxëøôŸÀ&Àä$ºè(]ö[Z Ypn¢-¢Ñ PiÏy6 dt$s—·ä|…©#~,xÏTçÐø7‚fn=p”ƒ‘ˆR¿1Møßº·ù·X–Ûòy×Í-”#ò°ÀKIä¸aŠãi¹wI K‹~U*2dó©ÅŽÀ#ˆµq œ–—>•5Œ»yO®Jn ×Pø×Líµ Q>6õ¿F}D I“&:öÔ`<)bhÏ*^ÑpmeÝ´ôõί ñ4¹£@·¼³­VqÌÅK=sG#hüì²˜Ž«g2·hËB…œ}\›ÏÛ %UX,îÞÆûwÌ]þk3É-»$#…ÞÚ(Àâ¥!ˆ"Øq?sN•oS÷4Fö˜$WÛ¾[ȵÂu/®§8²°ç8f¡p Rî¥Ý.k2Ž’Ô@_Ó!Àíë_?,"ÒiAj>`òy ‘ŸËÿæè2G 7ùkïþT0»i.D›4R¼%ºNm̶E=óBUÃËØHˆФÛti“ÝØà ;5EtHQ‹SG¢§D^·?»r’³g·öôn/ir1š£ÿ*U{L2”µî¶dü1d4oZÔAð)`VèT‹í‹³£Ð.«ÇYøº‚½»k|^V]è”2KM³|–˜¸D7ò u»MÀ€½ôrT2{'a1 }nø}¾#‚Àžci…×°^ÀH ½7%3ÿ£S¦[­v!Lj;,çäPd‚ZPþñõÈ—. Ñ3ß¿Š±«õœ‘‚Y†"êU<üòhø>ã"9‰:•P ¯«c:Rýø0žÞ/Ò1Zð}àÐví—qœq¤"A _«X‹;ƭ׿£©«™› òá&·[¾†ýŽnÿÕ] x|BÇW¥¡pH "]Àæ;Ì-ß*Txj5^'6ÇõªƒÃ×õðaä’Ð ~Ì óbI…8­°âVœvNÛ+|tê‘ݾ¾ûø!—Zûóâ=å¬L}ÚC÷)TþnhKFRÈe/ìøž! Q‰Îˆ¨¾=G£Aºšseî®À4ýi ã]„´¯†Á#¾¬¡z)‰™ktÛæŠ©G°t³4!G>E,îœK Š‚`3›lL˜‘Ow/b´½†ArGJ“[œé8W{‡}÷†,S«K8AW¥uÙÑò𩢕|I”ó,¬„Ú „õæë’ÉšŸ(Î׬ßܵR |£í&ñ_ihŒ§0¥œäÖêQ Ì3þg<Ö¨’ ü¯DÇS'Ív‡Ÿ¾ÎQJM ±MA°’?Ýív'¹¦]hŒ=AóP“oä×R¨VºÝYŸ7½eÔk& þ9¡‘…E5¤ç¢KÛe˜ZT(w‡=…ˆW­>¯¦ œ’Ë) _ Ñ€"Dx¸o­šaó;ÜGB³i2Ð íç#9êaWæ65ïà{_@Jq•*¤1¨¶ÕJPÙ?5æ–ôã™ Z©Ž0×à!º=‹ë†'<¨aWÇBtL¿ÇÇý:¼e×¼ù‹TšlLÅ|îÝám|Úå•︹ÄL#Cqü÷7º¶ï&èåqÊœu·AQS4³ ¡5("Æ'ÁCúß­GÜd ŒeaKXÿ@`LµÅŸÆ5ÓCHZ¬Ž£…,£C¼]uýBnáu,—ì™4Üô+’…Ç@MÛ ?±ä—Ó1ë¥>q‡ê°Jç+‡H9H¯Aq´´´už“dèšE÷Ÿ'0‚¨n8‚ê¶çØHÏÃöÞ™i‡3 Ü%Çå{uDÕ»™>¹,O©ÖíßáTs…Á«£±K« äg!Ôý§¢å"•?¾"ɣʞÀ2»nƒÄ“"Vƒ_W«#ÎBƒ”º&2swDÇÒ"Ý­fÚ#=î*­šPɘ¿ †ÆREûπϖU«nbðn¢ê³ÿõâ,µ£‡JÌ=+f˜tº“L0qgŽpÂÿJ¸SG`ÃЊº=è§|É$ùa<RlZ3~O¤CÁ÷Á'ˆà¦þH¯hy’ñ ¯û0X¥Nbë'•ÝÅkéË$õ’Pn–!•"MÁ¿%¯záO&¾~ô#•ö‰Ö2R…=IÜxp^¶wòUDV2IÖ!%•fŠž|DóÆKQ*¢*bÙ§×Äæ~¹£†Ããžä×*ýÄ>6÷æ‹”pýÎ2pk1vÇ|,Tçò*s²’}p+!%|xegY|)¥-¦î워låž¹¿S ¨ô°þ’U„V”L) {ÜÊ’ÓµC˜æ‘yG¼F !Bš伓[wL)÷ ÕIí?läBÙa t°#^«Üžþ›e½) I=jfàRšÄÞÞ´JhÚ€Ws„cΨA§ÿæ¿Wþ £Ä滾1Q¾bÊ+üò¦XoŸClÈy4è½qP}1(£…ô`èô<9@ªÄÂU믃½qówJSg™²\üRT äcÌfž=V•>Ê8»›×Ž.ôl‹L„:)IM|^â×%R ¨ ¢AÀwBâ¡€ƒ9lÇ9¾lv_#¯¿þ™5ÍÊÙÜÎØêÚ½t·×Ž §Xdßf–ýÛ+ÞK“v†´«ÐWm§øï‹²TîH0½ýÌI¨´–V6¶o&ÝÍïÙlÖê ÿÐÙ€jÐà‘ašªÿ!32ªˆ™bºÔ•¦>©¯k4*âÃl8-á xB¤Ð„aò2Óкßó‘Lduõ²“=¯PÜ}#”\!Ÿêø›{Å5˜aã±_Ѐú´`• ›°†Iõ5’Ë•ÐâŽÆG2Pð apŸÐ›ïÂEa|ɤg´îf‚nüÃ5VŒ™‡ìM°Š7â QNH ¹!,¹“š`é™V×âk ÌÔfzÆ{å·—ºX'„$ÙM ³Ô£ k2‹ÈÝÒ#‡—ÛÆÁ æL‚ +÷ÃWHï t¢U_©‘©|6N‘ô³Ê¸ý ÉaûE|ä¼]ƒ“ªìÇ‘Ѝ}ÒЩç#e“Ýÿ›YÎVŒÅZÑ&Û#MC6-ìèž…zÔ•¾t11Ⱦf°fΓ+‹î0‹6à 2):Àq/E~«avGÁ–„zê$kP^‚R›´õ¥†ç«^…u‰êy)õ‰ìé9¢neFn~ÞªïP„ØhÇðˆST'B¹sqûÖ€#ÝF#ky3'÷ÆÊÎv©Ã­àûе¶ÕFÌžv ÙdY-8¼ùÆ~-ãâëΗ6yÓ]¶†@ÆÄZÖ³ÆènWõ žÄ¡ÚÓî?L\eVÚ ‚¾ÀB†åHo =t8U„&šÏZ;¢¢¬ªŠßŽ€ìZ”ŸÇ[Ø€±$ñ*BÐPøœ]Ì+ÊŠ’³rÞvTZ3ŒL¹ÓÉYΦ«Ð¬<Þ¤OXñØ4Ø”r¨{¬Ø`;d)“%þåEV"–¥.8­Ï»9:ƒÏ-Å%Döp¾+*ߌҠ÷à"F6ý<½œ™z¾Q³ôq`?ñkÿÝ‹³JúXÒS.õÐÄô¾Èuþšd†gò¢=m#¤Wfèy|]€ ‘·1 5Œ}θÀœDàlZžE6T±â?£®o9ÈJ«RQ§``ÔêÛ)Lò_ÁòÖTcGÊ”±…» W–ÅÕ-ßã][÷¬Æ_HWé“e”ƒMt—¨VÚq–¥¦ÔU¿ ³ü‰\JœÔäÉ""ù”YAÈnÒpð×½»h‘Š u±Ýÿ*‰vŒ]´ùÿì J ¦®\> ±”ñØmvÕ_2™qŠÐRúR~EvŠÐëŸ ½]>„ÞÕ"9¬/'±îƒnÃtŽ%ÂÝör²jleN¤EŸDÕœÍÁl¥qOVu[ÛPji¶¬5Íù ,€¾–.Mq×+f"Ö¸&¿€ž¯.¿)Ê55rÝA3ÜÁ•S·?$76óÍæµ›†YĈ¥b²2žß¢Ç=å&&ÉpçÀd·žÎÍŠß;¡OâP%ß!éUñw¹bJ8Îý»’I·Ò‘Àeœ¤1î¡­´¨t¸p~­–—ñý~—ÆB]²— Ás4黯h…Ê“.jÐ$M=ßyOœøÿYþ¥+”ö«”¹YL»zƒ½r4¤GÐñc©·“Õí¡É¾ÕtîhôCîÎø¾Q¼ÍrzŒ¿ˆB©o½¬é¸‡¡<ìtF«ì»æGëÃŒ©(k9'Ê=Äõ̺1Õ7:ˆiõ´•ûÛ ÏÁÜUÆv-`ìã#ž‡÷M8ÉÙ}é.Üì "Î9—Ü´c‡[{%ò¹/iæ^Õ%9cˆªÙ7ªú8¦dßk c€‘Hº! zýÓT™ –Á¤•šÎ®,yBΚŠÜ:½M&æÂ!­R:þ&9ÇOm™@5¸†– èŽÌiFM ©=wJ¿Ñ0ù ð¼Ënú j\8<ñ«õYå~š„*T'muÆ yãý½PcÈ\Øg9Òkɬ¾ø[1£^?úÇ*¢Ë ×GÑîÌ’3#bðRãAéõË7…§ƒ¤x(Ëž«úùA¹(œ ê¦"±AŽ—'‹Š¨‘ ð·Ö¤l&™™ ªIït§Rb•’ÑM„¯!ÜF5j÷31ù¸Àt0(#ÇÓ‚Þ%%Ÿ²3cÔá­nÀ»ª½ow.–ñ¯L{ZPà!1K¥„miç4š“³n߆fn~ ¥E}Lý‚¼4l`²Âód¤,iW #¯‚TÒ<Ÿ§M ôk~F³Ô3T ­ÛçÈÊ*¦“‹B5ÑëÆa @I7Ans<3EÅŽZlîjnŸpÞõÂÀSûþrœè³ˆ®~i{´éIáÑ"ó@OpµvΰaVÀþ\b²#ðþ„xÊö`áõÛùéÇQA<'3°C>ù6‘T‡ºé$¦¢B\÷Y!›= ý7Ü¿ß RyCÞá®ÒÂùÅ ÿ †ïÜw‚@ޝ1Ó6ÊÁæœ䎉J1\AörýH±_®(¯c„wö ·ßóŒc½/›XÉÇÝÿ¤QÖ•ÅçþÆdÒUÈFµ"ÐÉFŽÃ§"«÷†7{]|yP2¼dHL1 ¯þhíM©ÿúêØ¶Í°rIΙ÷_Tƒ;¬4KMÒ`ñ6þJ5ÇèÍXbúDhÒPFο*ìäq#…ê¢ÞóÝ17'L½yÓn¥:›Ùs˜ïÞ½DÝq©öeï—÷¥ór m"n‹JH‡=FvÍ㈠÷‰¦pWR™#ö M]8üøÈì÷2fÐ,V§Õ_³ñ ƒ—˜% ¢™¶.x+²[½^=Há4ž¿z#Jkoî ~{b Â1^ª9¬Ð¯—³1‚×gUyÚfûéÏ÷0f ’9ü>úUÓðãß L$UBà/?›¦±[°2õW'PéÉg³-",‹ ŸN–ý}n˜.r“æ¨ C2û+"|¬¡ØSÀßtóùŠv/ƒÑòŒdvBc†_V>x:RÓÈРZþz˜4 SšEe#ïVÖtqýð…ùKá‹H<¤[s"¿Ä{É>¾Jz!‘òŽ×ÉÛ‡Qö¥.Òz¡<` }kÏgôSîÆžá $¬F2Å*0v:F©uO©í ÕÝËBW½C7<ÀÙ­ BmÅ%û£ÜXì¨çý™ ±óR<Ê@Åi™÷n¤¥DJÌ5é d6÷@…™ëNôWQ ,ðG)”K˜©¸-ùÞ­û€ç6ÍàÖÝzçÄt,ù¯b.&yð,šTb¤€8µH¡A礅ù©ò¨ßì>rTè+ŒG72õ‘|êü}B–ð^¤E2Ì¥x)…$ž~Vyë½ï˜  7„å~3‚Ë-~9ÇKDϪUGäÏ^pf%ýìnœ;ÓtfkõZ~º‡Úܺ±¬à&¯ž*) hàP·žI{žò‘ä M>Ô5žêË9á$Í.1O SLi;¿p€‰Ó¿Lé÷!†YQ¡~ßÁª!ëkýTëm±YXLhÂHÇÛ«Ë× C$À@¡ž9[­óÈ[†Ï…Óž±[øÞ'4»;n}ÞQÍyLDµ6’ wíœ$µ!OÏÐ?œ…ަšAb…iEpgïf.0ãÛGy¼ÏÖF¤9¥R¤6Ë;t‚¾Á‚i5âªË)¯µT)§kØ‚à ¶#gR¹qÐF•õOp´ôË×ʬ!¤h^¥qY\}eýt¶TR¸g¨—êmÒãÔ#ÕiØ0Ò³.nͰÏãÕW®Që’Ó¾¢*t_r˹Äds´²ºKWà·.ÑéÀfQC¯Á¢n´‘I-URaÈ3§èÍL8OTaÛ+k]pGÆ¥‡—0ÍGú©@T—œÉɹH//\t]'Ø+W·Î‹½‚$÷šÝÜrfPã ¦W]½ÆDJïPK"O ¸Ñ²²®°{bg¹x]mhˆr‡ØS¶Lá$ƒýSiÂÉ—|Ó·)ÿw–Ä„0É€yé°žô<Ù}«èxqj¢ß#t«\x•G’Œñ`Dœ*Ë“|®œ¦˜ËûÃ5 ­€Ð‚|´K_¢˜Ö¡m¤µ$u:(›£ZžÎóP,(¹% ³°¢‹JA q¸jšµšÂÅù ¿ßðå+¦:»yÔhæ”%½fRq½‹ÔJê1ÞÐ[y§Å‡Ë:/ «þƒJ’ÕÝ•á»ÂæÃý¼ÿÇ=2w,“6;y0'—ûŒWHº{·jO¡‰./Ï::©œG}s‡%¤ÏvpQyû_^œfÎÇWs£óæârê+š«ïlhØúÉ"Ó¢ ßm»p¿ö!¬ÔÕÒDö¥ÂQÓ¢Ó\˜-ßlru8åõ¾8Óž OV‰Þ*k@zù…FÒ]–V,8O ÝGìêßB‹È9k‘é¬Táhl#¤Zmcä”î1ÄìtÜ ÿÑKäjËãYî´“èämèÚù£ø(„ Àü Êþ딹n:G¼ŠUˆ²X í½/á$ª¢Ùú¾‹^1ï-qØ)j+¬½¡W•3ÇÄ,ƒjt^Èsè@‘äéÚ<þ¥§©>%U@'d™m}ñŸROýÏKÚ›Ï@ò8äñü‚Ö©jDSÆ{3ZIt×o Ÿ î|àÅx¾ÜïËÊ…—¤èïíE"ö·ž% “W²-+;k ÿN‰—`è"ÎK©œÖ‡Õ8c‡@Πл"ê„n‘4(ªÌ,sxh¹“J9D‰¼“QÀkÇñ¿ñ!q·3 ¥v´8‡$ ×g”gϘ4‹£8™äy«ÏÀ¶ÆA)žÄMJ´ÏÜ36Ž“ åí*†dŽqrÑhÿ¾j9äÇãŒZŸ;Ž3YGÕ eÒ5¶¨xãÌÖW¯bWþÆÚ4ý(mþÙË'‰„ÿÏPw“Ú3¸*î3yo‰«0•®M|^)ÎÞ²?³uëGôb¼ó‰ùî òR¡á£A5P2lŒÆ\ÌV[`mCØ»»ôc|Çù‚¨Û~ôÉÁ}¹]ªíežÖšõ€ 3ÐyؤÐ-€’×´„qýzÚ¼ª¥jÆòÉ€±o%ø:"¡}"e>®>@¬ÔµD½ü©þRËÌ^˜´7÷mãÎMLÉZAbA¦5èã¹â™Ò tÞÑôàHp2Lb­¤^ y€ä£ú6ýã Ê–—là^ä’ØÆ5áuàSͲ fDÉE.N\J>„¥Ï%åXKTêj·1¤Ll™“êM_•¦aÎ|Èe¤ª8y×f;ëÌ4誜‚ ò11–P×`c [öì¯Úz6$,r¨ÛDšÀNEVþàA@g‰a}ÃŽÈJ¿'mßMà ]¼0D5M¤èäÓXÍ„°²WfÎ>ïíó5;ñö-±9ÈÂϤoõX…6ù˜ô–2NæeZW„)ë–MZ;É6ERŒÿ  ¼s¥{ᔺŸÇ4!±8 †n³…³©â™“¹[ÍÔiå©óÖIÙÏ2­y´"6ÅK›g|8]–3 ¾ä°Î´UÚ¹ +í$Ó¢žÝwS;µ)¾JDñ-‡y‹Âö¾9 ìï´– Ï••"C9?XMoï$§CC5îP„5ˆÄ»XÓ¤‹Yêl” Õë¸l'èl¸B_câ™Ë˜¥¥GWé+âfìŠÊíËüêÞ©"7%Éo)®F0|¶7¦½»àlS—aim Y”…÷.œ‹.WÔ‘8‹›ïåùµ•‘ølÐa£`!Y{YxåoŒ—-¤¼¢9ì¥"Mªåth*ÁªG7¥ñÎ0@)»;ÛÒXæuäë˜éWËYÅ„Åï„Ìî.[@—)ב»ÃMÜéóƒ&ØL'i,ÑÕ…ýc9Œ{Bú,²ƒ6,¤·ŒH©£çyïÛlŒ·ƒ/?ë`imx· êä#/U×"檄¤þ\ûø_k¯<Û‚=Ÿ†‚ôlÛöË‹ð¼ Þ%òö’FÝÕ–á­ÿ¤²ËŒ6v18U»Fÿfÿ^ï+Ç·{c•²°jîø™³¯GêN»ûŽ ÑöÌÂ9‹È7`û7:'Nô™A4Ub|‹”(És½K³>h`µ£G²Qõ²Ò ¯Ðr2%;‹Cè­˜òB&ã"Æ´éƒA3R¬¬ j“qjKJæF`ž„ñå(ÈOÅg4C<úR À;ç_¬rýó9¢úAoèÃfé~ü„>}µÃ|,e$D|·]ž*°µÆ^8<+V4áü­|Ä›[üÀko%÷€çêÔíÝu—ð7O~å0Ý«ŸÿÚ‡K$§f¾z&$k «£-£`Í…þÁA¿þK¥Ó¶Y*Š$R-btl ÷áüDP, ¨±ÂëˆÀ´ýö_ãˆ:ê sŽ!»" VJçbÀð½å8;(‰bÆÓ‹ï ‰Öv·EÌ·v£9Y£FZ…”g‡ ÅkJSaΑ‚:"Æ«!==d„ü~)JÔáúJ…IÎîG,bÆQÑϬ'~%óÔR£r®+ [µ$M«Z9+s²=Ü–V#÷W2Óªß÷ˆmf|înV)5Jpµ²gÀïw°·—·)ç¿áŽºŠi­ç"¡•ƃ„5†£e®au€ÚÿŽm÷­«1ÉãÞ¬^àdÓ=b,zäœà‡Ô¹dÑ-ˇ”‹ ›±yúc<¨¿‰pÖ˜)QˆødA­ÿ†}~Øè‹ÉŨD–è°¤NÄ#¤gsx½¹W§$Øðø{UÝÚäS‰žIÕ¤umÂC„©bÁbo ÈaÜ“gé}t{°æW<8KÂáµJ‰¯?©Â—d€º)9Ak4MÑY%ÑŠ-¡7ÒgÅfÂÕahž@aYî Ís†ËÝG†-¹y‹ ñ:L¯ÛTÍM%lêPƒ<ñq†[‡²-ó; ½,§Lè.¼›ïŸ´e™’G #Žö¹¤uË o8Vü‘&1—¥ÈØ8maËÓýo%ùyY9 ¸Ó\ž%ŠiSýqî¦{YµAJ;)¼÷ú"<^VÛÌKûcúúô½ÛvµŽÓ ¶ü#Øm=r•dúP0n\DF·WL4…­pcvÔtÿDÛˆ«DÑî'«kãöa֩צ–"«²à¿Ÿj]Ÿ«*ŸL5è a­ÃFÃôéqúEV3íæ‰ƒy–ñkNÛK‚§¾A})½Pð£vÏi(á–T6ë,fƒ# A(ïC ¥‘ÄÏÙeÚ—O£¯ÁØæT­$bÁLôûªEóœŽ1Á½Ãÿïwïµh\"c?N§ ÎàÒä.xM·y8@¿Äôîc&{SJ^ÔÓØÇ*†·‹ákGÄÂÏXRÃÌq£ËHaÞÀŽ~Чòo¦Ò–É…¼=L&S=äÐÝ„OcЦæWô$Âïð'gÝÌE"9ÆcPTJÀ*fZ‚Hì§€0ÖÈÁ…&üâò¾ÖÁJrFº½ >pÛÂ?+ŸL®m' \¦ËñÚS?f6šÛôZâu[âO[ râ4 X<ëw[5ƒgùÓIΰ,¿vŸºß€ƒ6t«&É+-¢ù?ÛaìR¯GêÅZ9úu_ä8„6X•ã䉌õ2>ÚB—ÆÐŒÙä¶8•È"¯æLâUÝVÚmF­q7ÿZlgBÒË‹ÕÓC«Ö Ú"b8Ú@KNDÃGÕgj' àÈU{ì e-mrH`£Ìd¥cZ§q^)süq`´í÷6P1¤©~1ÀDöO«Áƒžz¢l£¢À·~tÕíWºérÞú¸Zk¢ÃÎHØã%ºEÃ!.òiÍá7,Ik­"/ÙÑíM¬« zôB_ÂJ>ã! ¡±Y‰)•ÃC-¦ÃsCäõ}Y*£ðfL"ãe b¯q¥“Ê™6[þ´7ŽOâòÎyÙùs‡ÛñPän!wF—+.~Šûò"¡ì¤+îxQX FÙYòíK Ü»–ÎåM4ÓfkAhª?Ëlï×^75¤ÓD÷©TF‰ÛÝfÊá²Äg¬Û{uzn¶eØYEzf rŒûçPÄ”Æ_îNüÏðŶwNÜܧö*ÑøwFeÞ[ia¯O¡f°T¨þ?m~¤it\Å0|z"…mÁD‘`Õ(‹Ñwä¶‘ú/I¯c»j!¹˜Qáô×ö}1O›¿ôÉDŽ¥TW0ˆj\Íà wÅ'G81 æâŸEb{`LY?§|©ÝÈÆ4¯«»ÔÏX”Ÿ0R#.c§Æ—gôÂY7ÿ´ËÙœEcÂêjèñ¨t¹|Ž¹Ð³r¤¸ê*@ḻò¼ÈßL|3ê8*æ0[„þz÷_·OØ!^-Þþ&äþÁÃÉOhÕ“âW/‘d@ÿnŹÃÑ*‡ã°Uöͤ§£ê…U¾®ÂÝ•XgFîi0D8³ó¦Ôì`—þë ôLÛA†è¤§äÈ EÁéy‘}NåWJ®ˆCç’¸°Ni dò2ü<Îýiø£·h\›l°ºD€}ž‹0à•Éô5Å¢hü8G6+– 俦£ØpiRZÄ]âqôE£ÏFU0¤â Âþ$&àAN¦³Ñ?¤X J ZñW¾žD\'A2Nݼ$s¸× qÔ0?ƒ£â៿t~Ró"ñt –ÒDÎlE6–Ìô‡9n»kWý˜.ÌŠH5!4‚õ–‡“¢úøÖ»³ÇRî5dâ¨b-8¾š÷Ao¼ÀíÓã¸>º¸(8e©îÖN6Ï»™@ùÿ €àwhÇb×´I ] ¥2zh5à3 U0H§c‡‚Åž>YòÄÅœœ«YX‹Tø#_«#ôEx‰o"þ¸!P„f2Sdaë6£4#Àˆ8’¼U‹CbÆÝ(zGöˆÌzòÍQ%•ücaôt ‡þCÃÄg‰¹LÉ&–ÀÒ'Ðê.Pš™ýÅDÔìoМ‡å¾Š›K z‘ðº:‚SY¢“f@µ€2¬­NÍTH_ŒG«æ!)¸£Â5q”ÿÔ1¬S†fÄ&è=qïk Ú8¢•KèLM ÔgžõµÕ]¹á«Þÿò#ò½à¯ïèI_¿}`ÁCñÌTÈœ=›†ƒ˜»W/_Ò*x]~¯EGvë—„Ѥž¤µu@¯ú¨¼#Œ5ã#›–×ýÝ£Ò»¨gÒÍjÇsaŠÓÍâ$ô´ã‰Îkd,q±ì;UórÍf)ö»UJì¬aøƒœ´}Û–\ŒJÓ>xóA=žÜÎ<³Oz0yÜ%#Pà¶»‹…S8Í€ì6àZYÏtS׸7~\W3Ù"%êvêà‚PÆ5íRß"M"~É}jip\öÓºúIa¼ËUÛ5ä?•cSÏ=I›6Ú`ÓåýÓŠ‹b %ò ôEhhêõÄÖoDBšK­%Å~ ºVàrÈ*šŠ9=±¸èê˜_áH½\¿=]ºµr©B3ÛÎæ¦gî °M¯ÔogóòÏÖPNO¶„)[¹’fdaJÙʸ>$ì ž%»¼ 5K ÖI°C¿NÒU;nØCx"Ðý.ããG=áœLæm„dé·#çø­”ýN5ʼnM[mo,Ó•aLßž'«$ ‹ Âÿì,Õž3bFêE~,ÖFBùéÆb5»ßbÿs´t Ú¸´+2Ä»ƒ$©± òtxcJaòîª?9’þpv¸³îÒÍÿJ®Å ôÉñùVwí8“œcEçÒÿÌâ®[÷Õ——nÊ^KÐþj°ü1ûmè³ó•8pÛ,ˆM^¥ÛÑ,e@žß@†YˆL~!”o_Y‘G|üÆðJzÂçq¾¥Ý¨“>fÈž>¹O [ Ú‡‡ ]pší.$ÑïK#‚b.'ËïIDîƒ&Ó[š*ñÅ—Míö\uí¦´Óýã¢OY½Û[¹P2„¨äùÜÆðOo[i‡’„‘á{è}ÁúØn @޽zU·úxØ U]4–UsÔ˜Ãëâ»ÐŒ–ý4醟åí,)E ŽÂÐÝŸ¼AH´Óó½ÊòqhÕoV¦ø(\cq½šçÄþŽ ».#h*´«lŠ¥ôYLV­'£‡ÏtVÔ[P|o²˜6픬x» ³Ä—ës.̾/íXy"9^öÛXš\DŰq'w¨rËÁÐíÏàÎ1²™ÿS° {úc©ÆJÔ²¹*Іó Œ•– ¥“¾‹Ž€€Î¼ö 9ççNLêJî*…@Þ×X;¤Õõ¢"Øm.y4È ËÿÓÆ?sjÍZ/=—d‘nî»&ãvlHµ•–¿:”’›Ï¿¤VÓÙâ—€¶–ò›h}Û?œ‘ø< «úã+ë>N[±Ò˜r@ºÙC&ƒæ°ÿ­jþ-7«I@ÊÅ=®c\uìgßPÚ º°ÒÂd|r`Fìò—IË¿ zŒ3L|PNô™t$”q„ ¤”NR*Ódfò¾‚FfY» CCÙ(Cü‰#N|=õX‚!╨+È¿‰²ðdE¢Tgßw#÷-®´a€@ql0#œzÍlHϳÊs±Ë"tˆI¬ß#À˜=Á2 Òyݽ“õ†ÃöXbRìè0ZDmWW½_àZ˜rUÝC‘KlàC\¦p;…nWãå_x2!àÉJÌÞÌÐiGsdz¼•‡ßü¼+hì¾}ü°5fíÛ*7ÍuEx´ùîb°0^oss&˜bÓó^j¶cÎ @®ëL’Û³†•˜b(ÓŽA*¹wƒ*l—¾"÷u騫 òys¾C3691>'6r±d-$ù¨?Dz˜–Ь2ƒ8ŠØÉfÇò“§Ñ— få±Xktyþ‚Ý=*TÔ„ÇtZ4}[¹Áº£Cú›¥Òz²¦`ªE ´³ÃÀ*_ôž¿ìQ¥ ëØvØ^K§2‰5çeMué»?½ì/ü 2–bq]õ°Nœ_„Ct|k~›þ„‡©%Þæ1jŠþ]æ.»‘Ø£¹ðm ó„K6lz ýš‹ì†ôhŒ@ÈìÙãµ.ßOYM)½PB6œä¥5ÉÉo…;‘‘aÕNq#ý½»<•ƒ¡WÖ!v>k‡Hsä0ÑÊÁCì&m# ‘»¶éÄê$º}Ó°Å4ˆm–KÌùÎxiq28³ãØÖqyÚl<‰BÃt½ö-—`]~3?î­ƒ]H|Ùù5³‹¨"õÔÜŽb[5ÃúOf-/ªçC¦(š<d®"~_¼+¢U0TÌæSˆ1ïH4&V Œäby4]†•‰F]2Ñ¡cÈç‡ì›uJi´E¾ã>"÷NK+iuò]+[ñÊ|Q½¦¢Éˆu²±Kn ×ÑvÂ)ƒz6ûvƺO,vѬ­v‰È{¾‘³šü±/’ñÛëW±ènSºþ׺>~šœ¼rZö×´JѰvEËÔú³ñò©=k”B»”ÏX ÀP€íJsix²XÝT-#«ìD—)–éê—ÝeÇlÈçì»,~²Ã«+L:Ó ¢Û³ 8&}5o½y2õ.Çk„ó[·šgÜà aÊaúŠA—'CdÊE[žôkÞÕ *ÛAʉu¥û!Ù4¤·Crî(¾pp)«.Ú®LÙûUÖÞ).ŠWÒ™Ä[LûÞ­²õ÷aLõ«4 ¯çTÑþz3í$òt¦¯™dkâÔeµ|®<‘Xâ ëfé›¶ÓȧŒAØZ!|@êgÆÇ ,•D‚ÉU/ù\ƒÖ„€¬(;ŸY¦¹Î›Ü¥Íä<¿K‚Ãmsi@e ?ʺZqﺶE9Jqº¢0|]«ÃµÄ0½t“ÓZ°U\~(³ïЃàerF\#ïËþ€§"BD 9RoQRP<ÏNÑ—ÿ©Äëò|‘˜ =m€p ½¤™}w`ë9G|,õZ oÁ©ŠŠâ_H\“™êKuÜTÉè4.u‡çÅ‘´ñWû©P&p÷©÷69ž/bÛ°õAýìKqb¼øYVŒøAɬY _Vo‚…·\ûyþlíË YðÐí@›¹@{2…Â'åb·Õ›ä<”m¢ÂH¾ÏQ”# ?F×€Œu`-&%µÎé×»UƒâžþÑl&u1ºÉ%šõ-Ú–ÝìÖ;Z5"Fyì—Ÿ3C3‰K4 øÕn%Îd™ )ÁõYI­¶ïÝ7Ͱ€ =9 “ZäA4î^ ²–ð¶©ù£7Þ‰p%ÔE9`KOÙç` ,×´Uç× ŒZtïSc&:’ãn͈ÀchÔòçAø˜ÜrýÖ ÑûXºV„³q¨ê?Hu±—h.×Jø­ânª4Žð2•µÚ’OŠUµ 4J‚EÎÌÛñšl<þå4y í+Mºsû€§8¶€ñHT–­˜Ò³•ûÞ?¼³zÕ3QÖí° Ëx ã©wP½±w34¨ÝjZÝ–[ÈÂC "ºd¸æ¡Ü?Á µõOÎ:I/áåž™=p<\ñTerw ºÀ±á¡íÕ×–â^sYH~™+µîæ_S(/vfî%Tð¥=æ˜9}°cg(ùZ†èb¤Ëêà ‚´AÚ¶ã(¿D¡;p{=/<ƒù“…Ó9NõcOï°˜¦†"ÿ’·µ†}\  î»bëbÁP?›Õ°ÎÆt4œ3 -ì; U‚P¢£zH»‡2¹ø‹&R¿¥xe°Ù¿øÕRÕZ™¡÷ô̱ž|Ãûq• ]y Aý47š®„0uN*~ħôOGW¢Š|ç!äõ0lþ Œíœ$^û°Y‹ß‹¨õ$ÛG:›ïe/ݹOž¶4·ghÛa°¾/HËéù1 ´Ƭ†+.ig¯–ô‡ĆÂ9!Ù ë伨vzSÐmÌ´BëoõbpÇ5;–5¯Ë~ÞÙ.†‚¬9y`ŽmTõÖ3Üž¢-”ÅŸ] ŽE´úó8²%cÎ%ØâWÔ¬ï–òó`ì&gÅŠŒ˜/éû€M§ aØc$dÅj?¼‘Ùò;²¸ã:'h^Ì\äJ_Õë÷“•ú¼€Š“9-Û¡‡²O`Ô›y+kEˆ·6ºu”µµüÝýžPEØú{÷»›ÃÈÀÀý™ †ˆýSuñÉñÈuô/&Qq“Yž˜|€Œ­¶}ús,¬±Î´¸ZÅ#+3~“·ÆôT-±ú'™º(ú€Ü‰_çGXªo/L‰ñÁžÈ­ÌÎËù}åîÛ+i…ú¼Å/é¾yDˆ÷ÆÒ‘…þh¸PUïç,ÐÒ½·5p®\Kméšo›ºz$6÷R@Å, 7Âü/rÅyPÞ:¨p·—¶ù–‡jÛc;A\f¬! [Úî¥jòDo¸œaU3[Ï ë—ëæ­‚˜_Ö°EBKm³+‚þ'1ß—¿‘Ó¡;#P±Û†^ˆA`SœOài™92¹°žôÚÖtPßêѽÍVnàÂò:·$¯\¤ÏÿùjIn|w: {üâ Ívó™ Y²ð¿0×Í[1´ÿAû>S0öác {ÇŠ†.XÄz¼}´=Ó§ pá-Ãt/‰ YH»°Š%¸&«q&WJE"oŒ üQ /ý†D–ü@ 8 YQz¥N?Ó74€Or`&¿~YT†e|‚H&Ï5W´¤ˆrß-ÈÇ> hC•쉋eÄgΑ5÷ec}]sã?âò ç½Öngì¨ëdýª:êNýµÄ«>Ž%!3Mj¾N×ÁL›Õ¢ëëõ “9g‡Ç{9Ô² û/_A&¸Äl»­_SYù-vø¨F¦íC÷u—ŸÐGî“É,ã.™ù§‰·}·yß–+ˆßgË*/’ÐË©rb$@édû¬’*c”.~ørû*Æ Y†+¬–ÄnP¢\]Þû±å‚N¤Äd(Þ.°X~çÅ÷qv5dð(’Ùk#¹ÑžO!ÖoðüÚž›‹KI`ŸÆ™!(r4+è›ö'Íæa1þd:ºušæÕ¡ï‚ïzwæRž#ŸØ(cvî:«0:ÊA!éRS†…74˜¯¦܆m| Ïm1“… "DH˜™Ä¨ éªçŸ‚#æÉ¡£àE.í4Oñ-Ðc»YÚ\jv½žÒÞ=·XÙWâÊ!|YøI£}³nvýµÔ¯-¡Îó„MˆDÕÄú¤¤Z¡YŽ»,78A-ô?ø=&Šš£‡`™‰ÛÕdÝ75t%ì’¤½Ø„ÀÛ‚Á*l ‡HÑVHâðQ¯!4ˆë6î-§f!_€8Æì]}¤.{ÄZƒÄI޹ª”XéB\ËØëQ>’4ºËÌYÌ°Ø Š¶ã‚…ÁBWŠX–æ³Ä½Mc8´–ëªä —Ù¾j~œ· ô\äØ endstream endobj 2691 0 obj << /Length1 2929 /Length2 25965 /Length3 0 /Length 27580 /Filter /FlateDecode >> stream xÚÌ÷uTœ]ò '8ׯÝÝÝ5X°à»»Kpww .A‚{p— A‚»ëíäß$3߬õÝ?ïb5Í®:§jïª:çy 'VR¡6¶5JØÚ8Ñ330ñT’î@U ƒ5Б^ÚÉÀÊÜÀÂÀÄÄGN.ê4p2·µ3pò8ÌŠFN í&&n8r€$Ðèr Ýò@'Uw; 3€Êà7P²ut¢74p¹6¦æ6@jÐQ[;wsS3§_18è˜Ø:ü"øÅtsÚ8‚²:þ *Â10²´uu´4Ødä ¶® £9€ÊÖ`43°2Øšü¡¦"®¬TVTSR¡f¨›l @Ò€#3#' ƒ#ÀÊc`lüo)€ªô1°1cQTq¶³³uø—*QU5I:€˜°‚ª8¨NTSQ¥(¨‚Œ¿=¿HþHÛ›üÚ./®*¬ª©$ÎÌø«f€ (§ù/¦ÿ%‡$ðG h«‰ƒ­õï*3'';FFWWWSgG'[S;+ê_ TÍÌAl, o ðw‰mŒAq ùàW‹ræF Z‹;å…¤%ÄUTéAÕ¢ÿUpúzÏàäæô[‹²¸°˜¼øÿrÿ"hntüݯ_±ŒAM6·rd%ûÇ` ê8ˆ(©Ó¿Uƒãô‹°Õ?\Ž@ (Ðÿ–ÇhbíÈø¯¥ŽŒ¿”ÐK(*¨ÒËI‹Š+¨ˆÿfiëð'€“³é¯½ÿ¯6þGéÌ S–SR’X˜Û€¦ÎÀÆÄÏÉÀÉÙ@òÛúIþ): êìàðKšüÿ¹þ­îÿÚ!b ’£cåémàú߃k`ãìèñW¿ÿ³•F 7wtrü'"ð_•¶™@½5·ùÿß»_~…“Uv& èÃ:Åâ6Æ¢¶ÖÖ âŽp¿¦BÌÔ!'[wÆÿyø-ml]m<ÿ·ÏÄÜÆøW¥ÆÎvŒj6æöÎ@i±í™àþØLN&ÐtœÌ¥ý}~™™™Añö´³µ˜X9½ÍM€ /8OGИ:8½=ÿvü'‚cæ›9Ž>èVû]ÚÆÄÀýÄäÿ\ÿBªß75è:3¶µ±r ® £‚­h\¨þ¿~!ýk g++PªÿÕ ÿ^k`mnåþÿ»ú¿–}þ’O¥`ë`m`õ_>sG s7 ±’¹“‘Ù?½úÇþO>aS+ €ž™ý£Ú¯+È t.@7¿ù¯ÈÅÄô_>ÐÈYÚ¿]@Pÿ‹7¨¡¿XßËÈJ‹ªÓþÏaü½TÜÆÈÖØÜÆ4íw8&Є±°³<™AçÆèö{Œ 6¶N -;g'ï_ †û5&ìFá_¦€Qäâ0ŠþA\F±?ˆÀ(þoÄÉ`”øƒ˜Œ’ €Qêb0JÿA ì²(»ÜÊ.ÿ²+üA ìŠÿF\ ìJ(Ÿòʧò±Uÿ Pvµ?”]ýåÓøƒ@ù4ÿ¸AÌ þ ÐJÃ?¤Ý4Õ–@'+ ‰Ó;ë¿íÿœµ;@¡þØAÁŒl­@ƒó–_óÃhü%þAjMþ@P4ó?áXA—¿Ö³‚¢™Xýµ´Âô/*Ù¿!¨@fîvfÀ¿é€læAPÕ,þ‚ ÒXþArþNbgý2ƒ¸ü™¤ÌöOnÐZ[›¿˜3ƒ”ÚýqƒöÚ€FÿQe6æYÿ³Æl ’v@sÛ¿êÈ nÿ wø ‚T:þAœþ‚ •Î:ZûûÝÃÑÈÖáo ñ.A ׿:àö1wÿ ÿó&Púõ¤ýýä`ús5üëµê7Vqr°µ~07½œþµDÞ4gnÚL kŸdýüß_ÿ#ùŸ'Ö_»EDlÝ<éÙ@Ç…žt¶™Yýbâdòþ½Fÿ¼ ü~ä€î°ÿÿžÃ Ð h·4okÄd‘ÒRæ#^0YEÎÍpôS@C&r)}ò+¶Xî `¡³_E¡­œÏGŸ$›b ò «—µ–Äʉ+ã÷B[>ò>xHâÂ#9ê jò‹~å$Ôû29ùš%lÓ­q­„µ‘Qî¯÷Q,㯨É$:å­+yP®E³Ì_ЬÐÜQpÛñ'ÛÁœ^ïÑc" z„—hfôóC0Gd íº;ßíf·î ü°šñßÇΫh3é*1¼‡;C%?¹jNŸuÞ¨‚çwAg™k‚šårÉ ‰`'ä=K$-Ý Ýßߺì´¨x‡údqŠó.L ÛÀñ‰ *© «Oá(vôˆën ÞÀ½Õî&W(="µhñÑYN¡ÅkF¾,±w~VXqÐ'uÞP9Æ Áľˆ÷-ü…’t~]h’%;>íBçìÑ (ôºIá’@¶y:à2o>ê£âÀÍa3éGÈ÷¸e$áñM?°›|%T¹éeºÐ¹ã0)å=TÈjX-äÐ'î–WÎÑ·âÂS†åQg‡Ô<ºÑBÞ"­å(gKöV|è?mïÎ_Û– ["æ¼éxx0fDØ|î4:8ÅT2Y*ùøÖQµ¸ÅS4¡C½ÞÿDðûNbP­Ùb¦¿ecý£Iõ­9=¢|…œnöRÄÂ`È9•×n5 Î3žDj£á: ¹Mi’ò²-q‹y¤r¹]ÿaW +h)ʽÑÂåÛyÒƒÇâ Æ¬D…ïà7-ª Å÷p*;t#müÍp–¹K¸ylFÖ=qTÉs3sG®'µäÎbíL7¶ÇåNfk_ÑùÅ»“÷QãZ/¼mvˆY¥m_z®¾mˆR3Mô*\Ý-OEê2ÁqËdL/à/Z–A†Ù¡ÈS¢ôÍôVWš¿áWv5}ñ¢ë dŸ•œL U«À»û~–šJ¶ŠÇ7Õœon§TÀÒÖ…†µª±ò1£‰Avîê.7ïjIX?†P@,>rŒOÞ¥xp,:;Ƚo'÷Ø ‰Qý42]öÔEçUÎB\[Þ…<^0íAý0l Ù®0%NE$/hyAfcÖ&É*‡'ȶú Pø"0ÿ8`JoTp =è~ÎÒ)ˆoG¯´"­¸ÕF ›Ëèdƒo§H¨æ2TäL4õÂjLK!¡rG›ß›ò6ù€…fÓ.gÙJÍuq ¸âsBŒÓ"Ë+å ãùÂóûªèm{ðÑÊ"/ÜAÝ«‘´·9Ø£BF“ò† ßÞµzvÆÒà )³î2µ:ÀÊ‹·È°‘ˆVÇ–Ô.‰'¡¹ Î-+öExÜ#‡¾7ÜÐF >}³µÒ€óÇ€w”†HSR„}‘ü,xGáÆªÑwŒAO“8¼uIÖ'ö¼ªàAN׌³÷¹¹aÇ¢âøÄ>†½M\i2S&ô¡”Ǫ%t³KŒ>§K%}§IN`ç-­Ãþ>G[?"Ucw0wFÏ{4O‹Ð÷7¯Á¤®C‚öVgñÜÇÁ£”—íëõÃ!¦Ôõæ!4HÓ£öIÝÝS¤ù´Ñ{^¼îmÇq"Ö^Ô­Ž±/&zߊQ ŒÖy~DEU=8G½¥ó¥¢_ŒèðýPèò\pÊ»}ÎÀ«+SY¹Þ„rUOÿ†íÈßzxè²AfõÅVÉ´–Fý«7ïôþ”¥åäCWH9ñtљ̀«b¡a…¡ßDª—Ç:åóX·V÷@²³V2}µ¨™|¼—¦;ö}qP==˜‡ËÓ#PGTŒ‚·õDú_éúG»+%ìx¤¹”®Ä *»„R籘‹ü¢×w†à†¯¼\Ž_+V`}Й­N÷‹&7J¾u;gü8 4©qýI›×òpùÑIq—"Tª’_é½Å}ƒ2A2«®.½Õà]¹8”†¤L™–õ A鎔%K¶›–ÿ;nãoQŽBõzäï®°q²BÜ™¹N£•}ïOh7¶OeÖÓ8ýès1 ø4ób>;ôÎþ8#Eê±ÞÑrŸ¤ÏÑv+2Àð¯ˆõ÷ׇk]ý°¬ )ºð`7ùCRCÿûüß`ŠÆü1&ó=b0èo:¹—ŒŽî&08x1W·—Jˇ·ñÞ}±Ìx^¦«éÊl‰ˆ¸ÐÒ Ô\$÷­±§JG’â"Û¾L` Š›:®pñ ÅÁìF¯T‡×zOÁó”_Coâl¯Ï7˜\-Ýýä‰Udåj>6‡cCYV×þÉônU]Ø‘ÄvÏG¸ívYÏßøPÛL(ªbx•€×Ç/¿wm·!›«b`©þ´2ûaˆ¿ØÚñ>˜‡£³è)ÈW"޶·ÙK2OlÉGÌA ²™åkpËuÿd9¡ÛL{Ó·:Ò:Xèh9ÕJ¾õÕ ˜}ÛoÁ¢’üUu¨>ô9™ûß󷎾4&€Ùdpí¼;ÆdÊÛmetñjC½+9&^…†q¸Û‘œ8^N1˜ÌÒ(ا‘µÏ°†#Mwâ|Rhí»8æTätÜ)s<ó“^‹ÎóÆb3¼4„沦5ÄÚÅø¯¯Ñù\׳VG!«Ø3¹Û#í&ô<0ɬӺÃá ÎÕ>÷œ±pÝj´EJ¿;|u®Yn¹²°gC5| H;3~ÖÐqL279(}¹ê™¼8v4ßÌÌ"-C®õ=–´fb“ºzúé7ýI]¼V¬)¡‘ÍNA‚FJ·ãÌQŠ—ììQzŽús]íj¨¤ÐÇ&Xþ¥ÿûy–BŠL!Ihþ÷Y/¾'x×¶`Ð$q-µØ}–aqPBÖaSôÚ©OÜé3KäKÈ'©ÞÁ¸pnhè!£~,e>Þ÷ñ·dbæ‚·C¡æXVBõÀÝ¢‹‰àN­­4á/ìy¸cî­âäÏËÝ Çtƨ7t0%UÓ¹âE¡DxmC))Œ™çˆ4­íO1µ óH³*‰´Þòv7´ªPiêìÑd‡=£…®ðq ÉZͼ9’uÄÑŒ2A0V«kéÌ‚Ï%Æ»'uqËjI—«[ݤ‡Ýh.D­©ÀäŸSQhÑ›/Gú‰–hÓ»eê`źe6EBÔ)‡’®ww¸qLÀTv"8\¢ñLµé¬“Ô‰6I²5¥®ýG4” Üç¡ëPv\dIˆ4‰AãvÀ§‚S¨ÒUZθ™M¼O‘ŽPÜ#/¯ð¦o ÒxFönÕÀ{çՖΩ#]Ä^güÂÉ ¹"]‡ê!ËÁB Õº÷ü÷Bêòx+ 56sò´#õãaëúL~›}^÷:µÿ¼«^Öíë«b ç>ÖTCÎrøÓ‘#í=Y9¸ Ù`œSxÉ®N ÿÔ€4‘?Ôm¨7>—Ž‚}JDÔ ù2†|Lj:ÑšCz–/äêAÚÕ¿‰¹ï4ùJ¤Ýhpf‚/0é®Uu‰¹±«ÈEb[QÇ5Ámj¾ú›Q¢¼àšQys®•Õ‡ãÕnDœø H¶É ÍûÆbÏ’Ô*eܽ¥´Ï ’Ÿ‚æóTP¾™ …'3L"û HCÀß"fOBÉqQ½é ¿üæ† Éó´ñ³HÑàrð‚¯„Cð¹“ùâ–åQøÎÃ:}¼›D¦š`…½ÓÎéójÔ2I•ݹ¡ çã'@k‰æB½2Åýl/é]<œe¯?)Is'¯1»kÛ-ë`Í­"Ët€†1ûõ)ÀãmÞJç) Ýg:Wmsãª"_uºäÌøy|)¤Þ§³ pàeWZúñôỉ|åaÜ`¶<ƒÈ1f_x¼Úz8ñæ)¯/²Ë…7Ë\—NTfˆ)êzÛS?0ËÍ U½ëÝ'¢Æâ7é#ç‹ ¶óÞGÓŽ¥­5ÑöƒӌɌ›è$ÐW+ñ¸K¤j½Ë%ç2ÖR×oéL™*Òõ/br¢]Én¨Mñ““ñbøÄú-Þ*žxÊÂÆ£ý{“ž?x5æBÚH_CÚwÅ$/‰+ïa,½ðþÓåÍ›¹»6…¤ÉÏñãpÛ¤;hÆð‹¡‡Àé«þZúu¡ wæË&„ QYÛóÎí/Zì騾‚go«#?›é+{·Ó:#`òއ&¤B ”7RCv¢³¶¸¡÷áñi;(ã' ”òB;;XL‘7äùcwÀ*6 ¦:É¥Bå ÑËuá:eDšåËû.èãÝÇÊÚ:­|%¡f_–YM>k&ÆŽR=súñ ôªÐÆ»[ ÎYéV„X W–¡ìÿPME›F-8Yzg©±(7©ñ³™¶µb1^jÀŸ½¡F¥õóäÕ*«SX‰Dþ‘}Ç&_ôº¨&êä*‡]Yƒš»•âwA½a•Ça9̤Q¯ÂfsãÍŠ•Z(÷êaÛ«]ë¸S´‹r=;Êí¥•¦Ü‹= šv¢±U”æúÍ =ä€=ÆbóÊÚ­{èl'Rl+Ý=Aéü°ÞôºOÖp\˜)‡/ŸÏƒ³Ë—ËÎê9Ø]Æä+çÎb­1C «L¬©"§ Þê\µðS:^uÃsÞ3Îx¥”W)¾(ßǺ.]‰kÌŒZ!ç5ÊpP·!pÅ_¾fb½XéU˜±GãÏÊÜ»%BïEQÊ/ž“ÂSn¬_-Xh@¹ãxø=6´ÌÇ/|äªæüø¨c¤V’B9Qs4Ϝԓ!†Ç0ý"t”Ñ%ö&Æ“ÖHuoE|òQž=œÂê@é ¿AŸ­§£eQ)¨œ¸÷Ž3º Òq*bC… Õ·*¶åS†ú~.fp…*c©º{¨ÔÌ/ áÇ´Å6¾üO ©ß¼|½ã—ï„`uq¤QEò&Ìéƒ)Û>h¢n½8bÉžD °÷nj]š¥¨'‡dIÖë^öж7¥9Y6»!•Ì9Ÿu!>ÁtO¤šW|6Ê€±MŒ±[:`|Y.¤:Ë’”1Y‹ÞóÛøþÏþ97ÀbÍ 52Þ Ä‹mÞr†ÎÏ»e C Ò™î!žŽ 0ù²}Ú]üµ‘¼ÝŸP^¤rŒ‚iÐ ÐÛ,Ÿ9üƒE |’‘©óâż0Òý­Ñ‚hc:ÐÔNߎãS0 Õ@Ówõ]#Kª5Œ¨ÞDJ’*É9Yûá[nÈ­!RIE P²Ï¢7jPŠÍÞ)3"„¼ñf>ø({cÓ•94È’bä[‚y®iªNH?áæÀ>öϪüR¯¼µ¬Ý’FõUøáeYz}ßûF-Ø—>ïÌâ,kçÛ3éœøëcä`áÄÉáɦ.kRa ë¡ÚƒžÛ.i}ó>¥dê%C£¸–~xrª”†G³Ã ÿ6ø2S‰=íÖ›ŠaþD÷ wËÏp‡p$óL.å‡âÖk•%“]µÞ–i®F×-›¤Á¡P~c.vz꬟%µ/d'V;ñÒ”ö­Ðym8¹¥¿À{• Oså7Õ?»%·ÉÆ{·Î÷¬˜ÒÞ¿;+ĥǮo%CÁ¶´é–!Æ ~vkQ¼2 }jÑ÷wê¤J“dùÚï1ØüSß&sý鸞‚(¢J(wM:Å1º×ÈîÔÄ®&—áë'\ÞºC™ÑÒ UMÊÈZWü2ÿ#\Œy³N™Dº’ÛJùžý6Õ)ôèVî¿7ŸPÜúë=ÖÐuÌ;}:T/}Ù°,H`¸c³¸ØK,ÉÕ¸n‘*B(Š>Óexì¬n/)Þ±-˜Œ§×öTø¦pÉ1šyµtþAËèŽgz?o>…–´Õ4}5¼§ {#•lLM"Þ-ÁNi—LÏÛZÿ‰Pç°:è<^²¥»m¶×C%Ÿ¢¶u“”xI]@¡%)²‹û“ìç‡jŒg;ìV'É®\F—v¸M¿žñOƒíRN;Ÿu…÷*,Ï¡îÜCf“ß~7”ìŠP†[$YL¥ÿ6ƒ6®Ð᯳luMXÞÕ…ßš‡ð†eï'—Gû^±åÜW5©O ýÃÜî"`¼ªˆÓqœtx`ÞùŒO6Ÿz#”|ƒ÷Q)ŸŽÄÓÚ8G ŠuÓÒµiý>Åògûj¢ÈTN¸;Í‹ 3»¡ì*{#¹ÅD$ßcŽ'eäsw6wÊÆÖ|E8ÿÎÝÑo-òýÜy*Ê…vä'ñ;ÊsAÖÊq/íËüzUc­­Ÿ„ù_îí673‚ÜÚ7íõlREê¢vZÇDh(G#Ìpîio‚H*0îQœ‘Tvq: ä¶/û­!ðà»ãƒè|úÁí1,¼ÀÚÞ&­¿áuý逖‹Ã…­Gp¢Le÷ÒËkÚã:2q£}?ä”RåØ,Äå(bÚÐOÛžcNúv‘å¡ã€¢Òmx–Xèi¯†WModlý[md!0<®¿ã€xµŠ¡ÎeÅÅCS<õ5LqÎNÃê,¸¥Qºëmc[ bhßú`ÑàíŸ0ÛµEQåú¬BÑÄÜw®~ô¡@mÄVn%‰á¨e¼PÕûCËI}Å{ÖWc HŸS²~Ãà§{ÒG:ôhºS8e¯S/œ„Ä¢ƒõ‚àÓÀrS —N®˜œrÏ—ËÄtñ¥í‘‰7ÔœÊÒÁå$Odmñy~Øâû†rMêF \ƒ©&_§äèâÅ’ÈÛCsl|uЯ‹ØÙcNVè%’Ý$ÚˆRÎc­SX§ãáë˜Å'î¤|bNÃAÜÔS©Ô ÑqÚu€¢•Üå¼pÔál©9ûµ B+Œ8WRrh²\ôbU¥,fWF3$ÉqÅ/^‰Ã³’|…á–'¢BXíâ9aLT¸°œàÆN¾#3ÈÙ~B±ÀMeiuÄÎX}YJÓÁ ª·¯:îàù\ù0ç¯Ûãw¦Û)ô–Ý‹M±çâ.fÀM®â×ãÖÓHVžAêÒÅÁ~r<ÑѦfÖ­–Á)T­uúðÛzt©õîáè݆jI¢ÆåDçq*Ò˜&ã‡úK¬ó®§ÉvÇ4Çsáýò%È\ïÚæ4·äE74¨)ªË‡rŸn¦¿AZªÙ½©Ú_‹ ëX×XnbU”zc®±PÂç©*6µ[Ìh|ªé4M^kõ9P_û“^½Ïˆ¶Ï[<ÔÓ[Ax]RCÕ*üZZ$)× wN½ê ® çÃÅ* ɦg/HKMŠÙÇÈRÃãÈ.Ðwìæ‘e(hvSZÅšˆ…û¯Ï?xÓWzG`lYgS ‰D`i´ŽÕ¸fõgÖ±ãcºv,×H80>¿Ã<`üœ“ »'·mrÍ%ا’ŧÆŽ„ îݹ Ì:!BMXÛzpb¦ðj:òHî=ìud'ªÅ ƒ„©ÏbkŠhÂ{S+1½w›Øýá±÷¢~ ]lWU;µøA=±²ÕTÄÿ²šàLØ7­7jبª‹ƒ÷Ó0~š·—'Ûäù„E.åt .©vö¡¢òÛ–ž&u:¯vz¶4ÊgÏî;Ö´L»ý“ÈŽ§>Åí§2ê@1õr?»-Æí©Õu©­-aÛC)`×*Í€FÞŠÈÛy·¥8snÁ #Ä÷ÕþPò÷™¥œ™<•<-+fßR3îlÉ.͵\$QHd*À[©'G„cé¤ÜÔ™bªÂÔØ¿¸ÜEÒô_î 8†ÝRòÍy%»ÚQÚÚ¢¾ÔÒÖ‚îìL –‡NOË&Íèpá–L¯N½}ó΄ü…RÎbºsä\Nõ |Ï—/¸¸‹´<Ë‘;±÷mkaoðêÞD;÷;X ÛˆA#ÈÕ;pb•B>~飿¡ˆ°ßÕä e[û&åÑ«]UŽåžuC«"¶{¹F;½^$^‚ZשÑZ;0Þã€ø‰ÙÀgLƒ’µ90Hãá¾8!®§F§˜êè ¡x•¬üÕk‘Eð†÷”yeꎯ÷¬ž+YÃû›‰!§è(šÓ:¥ÄÒÃÙœ«+ƒ¦ × bŽ«˜Q-îÄc,øZì¼6rð9·; OùVŠ¥áö¤I™ömŸ—ABiÇêúøq6g”l’ åæº »®@Üïetôñ°õkŒ¯ÈÜ¡ývqh áu¨¡O:Ès=ã³s·%Öy•7ñÍË6f}ÈSfÁEa·±í¬›ï¥Gr2ʦg¨ïѵp¿U2N/1aWªÜxÑ–V|”{Q ¶‡((¹PK¬ÊCàM´›|%¤ö ¤/Ë®åÃÛ”Úá¶F ,Ç%,߉<# HTÕÜÖ¡äÙb»§Rè•w +³“ÍÂÑ[°R¨ËX~ì¥ömÈñxð{4מ ¨ Ýñ ž³Î‡Nûv$'¦][Ó¨¼aUL¾eUÛ;w”Ò2• yõM Ÿn &Úha1B&ÿ«dŠY=m&T¯öx)IüЃøR#àvÏíãËù÷zJÑØêîxKÁk̬1ï™7îöÑ¿œd#8H&3’)È ”ˆø}A!à’Å“fppýÌû¨;ÙÖv#¬°.ÁO€!ñ…a‰ò&Šx©ó‡²Ôþý·O½—\Í”_,£šœ¨Ôò0ù‡-yÆeÏ ËUiÄËr4AÅ[}¤þ¨ÁÏ2u[G Ú°2Öuβ;%Ü&*¦Šg;?Ì®@Q òŠfÖžpðSè}`ÂïĽ÷R³”@£kück I>¨6Ç‹Þ ]€Ê{T[µ¬:}GP`X3¾+§¨sÏÆæ&1òܽçòr4R÷}ØÝpH…ÀŽËrÖµÔÁv ÞÙÇ·Ød`Õ—yqÔV´|e7E‡Š¶+~å’&Å÷>æê¾{þÐWwRùèàì{Q4Ûæ­¾‰QMÐIÞlNÑë¿-i&ÛàŠ-K_U²Ðm—•<Æ/©SOä -!fü=V¸ ½OPk,Ž"Œ¸æÜ–Â4xŸÏ&A©«uñ°ƒ¨,+^æm2Á}³ïŠ-Å9u_ÁŒø[Aû€öå|_š.ÁOhÎÞÊÝÈ—b¹É(Õ+½'?EÌá‚Nyè±zÌø«Lß½äÆu é´MNfï‰mÕa©w 9w [jqìK…å%ï±}²d¸êJ Ž¼Ž œ­¾¾GTøð„ç/,&pCúsòÁ–oŒ’!\»ÿev½Ÿ OMvø<Žà‘ ÙyÏ“ü!7^V|ÜZ˲Š_ÓZHîû9Çg÷Àé¶Ësð‹z¶AeÊE¬ÉÆú¸%wW„ÌjH§ZláäŽêÜçˆTÜ=ÎýµA¤ˆ¾wfx‰#ñê]crã‚~ú_Þ0Ô~èëˆÚ˜Ä«ýü¶£Ó%Îu¾¼ï^ã»A£º?Ë2χ&ãì®„Çø*›$‹+VmŠlUåÛ][©›ÕÖï)ƒm©<äµX‚Èb* Ü”ä ³Öz9C”©Âù¥¼$FÒ¢°?º¡%¼)œø^Ó+É9½Bvê‘òh¡khÔ.×ôܼZö{Ô¹ëhdP·Ía¿W²Æž¸y®_h$“üì––w2*Wgµ£ý’YV>žê`\'ï4#dݺ¨ÌGmÁýÆuWóíÒÀ1:ÒD™ì$L»sZS̆ݶK¦ýÿ1˜žh 5KBpb]W!àBÅöj˜Òþj@!8E%õ˜™DaFbå­¢Ë ûÝÆ»ZËròýœ°XEo=* ðg©Íó.;ä<Ì}×”Ê cßo–âF9ðÂ匀{/ùOoZ-2=4²ãcCëwÜ¡ /JúŠ2´¾ó?ÓQx'cG¿î|×ëZ”n'Á¾@ÐËë4S û±Qµjt>[pÿt‹èŽTÁÄwÂ{~‡*Æš\rúiñ® ê«*ÊzQ¬© d³è§8¯¾‰à¨c.Ä ²¯Roª«ÄÃhµ»›ahi>¥6obîã4¯øÒùIx⧉5M;2'íÃÝq´ èÞ_Fiž!Þå‘§(ÛW]2óÚ"†/JE<ĵzd# ´pŽõ1*»Ö(§¨…@ÓŒe"ÊH+èKÙð>X“(év¯5#l…cF÷£›úÏM ô§¤¯gê6 ®}Mb&‰—l`‡I¸]‡KFÄ‘»ðp–*lÔƒ2oŒ»_ÁÝÑ<\ÁWi1ª…ádöO[@1)b·µ4†=ÿ~™ù…^‹á჈æÁ KÞó(7CÌwÆÇ&U½Ë‰B4ÆÅÏœ&Ç¢ó©ºð!+kð1/¹f³ÚH‚°íO° ˺è·\ ÒߎëÕ îR5M5éÀ&šp7?„6G^STÐpC9jôÒú ’çÊ'',øµ[ Œ×(M¿¼—Üv¸¼JäŽøD¤ôŒcW ô*óxV{ÒèO¡ UÜõÆÿ1HT¸IWZñµm~“o§Æw#©7¹®*ZXòÎçÆg÷û éà‡ä°å®^QìZøÀª]ƒ²œP‹ÊIÅú¸GÂ36ý vy°Ï{AÞ v"pËàõª‘M׬T8:DroÆÚ¤ƒ.¥+‡¹ƒÔRj2q¢|‹GBÅ<™õë*¤÷åœ2ßm9ZÈZŸÂ%kùF¬è¥Æ9%hv\°§uå(Šw¹ßÉß÷G%Ý7øÉOÑÐe+ðC’^QÄ]½%2C:`–p¯Ü r£b¨+¡·ÂÌ™µ ûö9zRy vÚÄ1EËÛmSÊqîŽSçv ©zýG5‘ ]¹¬ŽÑöx¨e\öÙÊÝÑÐ}ÏBØf—9Ëò¢CSj㚕͂5¯±m«—ñwJ’ð.?‚ôêcêºßóNëÍŸ®›“ïJ@2CÌUË=ÎgúÈ\·Xü°P¼ra”»÷ó2¥c…ü/>.®Îlà E+3¥áØBd7švÖXvD¬Þ!|J‘·÷çv¤¯D£xQ’< ¸ƒë#E?w‡ŠâÊíî-; ÞÆ¶22cZÉ = ¹ØøsYñ-CxœÄÔLª×·õ´B8#Ñ! ,ô ôÞâ~¬<Ý|#¯EŸ¨òÑ`ù¦uSváD"å­[4ìºèæÝ£(C ý'DÞjD^:Ù#µÈB,ƒÈ=öLê”>òøç Öèv£lfÍŒó(¤)¤8)-×HZúŸ,ŸiSæ6¨×ðÀ¦OSãêYy£*´9ö²š±Ñ–Ó,Øö\t†?[ùXŽÓ‚Ö«õ|´Ç/JŽØU9ŒòØu³òi´ràn,Ç•Z`;¾ò”T^$êj]­›–¢ÁDo¿X!aiH9Í>qƒÏÑ3íîÇWÉÙE\¼qºÙŤÄg¥”ñÒž^9ÈJ—¿Ù4Òå¿Ýê_KÃ]¥IÃRñ`Cu±çJ%DLÃÜÔÙK12OårùÁ}ª»¹Æ¾Î½óƒ”»\¿× ÒpÃ& Îs,¼Ò´ÕF©hyŠÒ2¡øUŒ]QŒ&ñ¥ˆèÇÙ“]P±)»6CJscö_cŒš:ÿÐKÌ2ƒ›õ] …«P¡=ÐñíÝé‹«Éq»×†…q—uóýyÖ}ô™âR!4rLâ›5G¬]f±¶à¯Ì·I‰ô]·*Ýy­n±v†ÔFV™®[ëæ/kñR YPV·‡ÕS}1ÖbBRá?‡=ƒ× ÆÝž©“á[Í Btw»§.ÑÆÂžÌ°ŸŸŠE!—=çÄÑõiëÒ…–Gxp‹e3.]O˜Ã`è2(]µg3Â!2·~/5Ö"ÎAÅÖúÉ$øæ5Ý”²¤––D ­7@`iêéÕòýiñœÓNVûg?Â"ÅŸ>$$0{ƃ—)ŽFѼÓÏË(¨†îø>¶â 2ûhfã§½cÒ ÛkžàB`ão|™o[pHÏÞ[™`I.‡_ô`Ì­BÔR½ï ,k¬ÒC"Äg\ÒÙÜ^( ì· )îIÎø•_Ò êv,bS=­?îSéü°kbÏ(HÉz_QúبAó eÐbÞkX𥸋oUÖÌœ¡;KÞfW<ð.ôn,ËŸõ檇JaE–›d˜‰@[l^'Ê„|从ï9ÉÃ5…w_°W³ ‡“øÅ,[·N ¹Ý—&oMü)%(¶Íƒ¿x“È üÌayF«$ÿ›¬š=¸p–àÓ 5æúŠîé;…>FhJëD»×ücÑmk£;ã•®]þ.ËŒUHËó5ÊÂ7©ôiNWäèƒ&´Œ†KHŒnŽ´Lû‘¡,•âa5ʼn†æ«å÷»$w‹$&Ûí%¢`«¾»Î˜?*0—²’qZ¦‚ÊÁ\ðµt> ™,J+†DÝ,|‰~|Wëš1¡@:A<‡³3ÿcÔË0ŽIõþ¡s56@@q‹å;À½ïÂú¼£ Ûõ´òC7üÄî÷Rš”c5¬®¤©)~ÏìFh´e¶)ÒíŠéR£•ÒÌÏmMi„]‡u-Gå*áåÔaú©~.Ø8ÃG Yg¦ÂAÐj!ÏîùñrèÜœ«lTe(yÙ%¿ÝóÚ!@+‰dèÕèЄ““7œ¿ÁU2‘}Ü¥OWb >í0K!kbÃqL´qY˜0i6Ùý° C˜cÓAŠ›ªçèÚQ.M©­kø5o¢*½I¼V £ZÎÒ°Ÿq—}áûæZ«D-ܹ½îç@¥äÁ0Â[£9™ e”Žã %„/Óè3Y™žÂÉgŒÓ³‘²Ö(6RXtÀ'UÖ«ýËUÚ%K )æâ.öL)L©$«Úƒ8ŸŒkD<“r™ÀºtËåð£"Ž MÙ\ÅÖ÷Ì<"œuã§’Xë4çãqL(HIⳈµ2ÕìŒ3ú R¯X´¨ä–£®4úˆF+k ó|'õ¦÷wÄ_…K^Z:i*Nt;õCØ`àïè¶ Þö²|MªSZõÊg².¼–Ó<ª››[Âh!¤”z¦ˆ¯g‚9³toùX ­„£œ× €z·§¼’ꦟfç˜)av.ÊÀ-/5”4¯6 V•0DÉ”Ž £ÆÐý$W°h{-dVËbef±‘Рð/Žtï; ³/©û…áYfú´GIÅ=ÜÌWžhæBœ©–V”¬‚øñFÜmõ|Ÿ[g•aóúéE«Ôqª=cÁ¡×÷³%ƒ´¼ÅÙð€cIƒlÝ´: ú1ó›Ý Ž$ºŠØöÕ m9ée¦Y “RƒøãNHGDç^ã5gVÌ»BjÁ÷­äœñB/!â’ˆ÷§¨4·k}ÐÝ0}½O”?œ"{à DzœÑ}3w pÁ†¸sïîNßü ­¢Ú»Îkgð2a;  Ý¿nC¬œÖ’¹.¥í ô-î„éœÉ­–Â:ì¦&«EŸLïáJrŽŒ'Yóh H/N$ß¶|q-û¼È×S>*„å ]uFC•ÍæàégÊoYv>ÃÕŒöŒöͳƒ\UY>)ü Ù%e«µ0Gîëg6tFÖVƒeB%óìœL|”!\_uO7ôŸ·=µT\ë>ãÖ€çú¾üÙÕôÅ‚í;ms‘Øà>ʴйJš·>àüéѳh9°O¬—e¥/\¯:a©sÞ/ nR|QW¬ïŸiè“WE´“l,` üþfŸÕÙ´të{½´+[æÒìÒ`Ûª{³4K ÉÅ|ïžù,>Ž"V–Æ “©û8—Å»—õ“ó´4YλœÓ?”[÷©³ír¦éóö~Œ ¶óL¦›§ª71 0xb¾ª´ñ‰èãW~DøÔäXnKìy؈XÅ; M0 ¤D_йyS´Itüœ#sÿr×ñzHF¼fÎC¥8¯µÃ+cg‡KÝ‘ÊKSš#íËÚÛqfrI:„O$$=„8œl!ƒ›s#ȹV8Qì>e®54L‹Éô§R@!þ#¯Xê;ìw¹(Qih½J:ò, ðÒ[&¦Ž°G¥råË\`Ez. 4,½%²ºkw”ð>ïýÉÃcà`PžÖ ¡Ç«ª¤YzÆó1Ø5àK ò)kñGú|äU™]gR¼Ž”Áñ·Œ6_FMð!&••À—Ïfƒ[׎G±v†—6­›TQü!Ð.މžW‘øMlDÅ[|ÖNTÏó„]4ÂsWnEj7µ’Ë|Gceüóò`È÷º·A†Ù„ +é" ­ÂÆÕµœÛ%ψK¹zÅ’•àîVŒÃïs®Â‹ú÷0CÇXÚ®‡åX w<æA£ ­{">±öiÞ©~€ ÙL¯ Ýl½~ðÔßm”’+ˆ„t´ØPŠZ7j²+2Bã±ÛÁ8‡HºFLW>Îa«ß² ‡óß[ËFB²¡ž>=;ßÝ€X:RNʲ1w>žÚšÞüf‚0gçËUåˆÓwº#a®OS}Íh„=ý³%ðÃàÏÞ£$¦ìéVÃÀËNÿ«"M§´ÆIXâÀ9Ü$q‹½;Uû¬¹GNÏbÒ#6â(Ä™©sÿÌ`du~hRÉ‚á$¤úi–ÙsáÞ]üpsêݹ‚IŸòœ#éY¶×”à…²-Q$ƒ4 À§o­5Ôû´ ´&Ñ“eÜ…ÉÃ,ÛšϾ0™Tl›Då0´Œ©‡·¿Ëyã¯TX´ \Müx¡ò#]W\iX!Ô¦šƒß•¥ú§üà6²]î&M±2´\Iö½çSj#Žw‡a¥[F7;+v\×D(·ìÖù[b},…ãŸÔ¡N¦¥œ‹ÊƒîdÜeéàžî4¨vyEBLG^%»ßÊȺ³ç>éÂËcC±­,¾²œA©‹È‘ÑK¾F“ezÀü´D§ô÷.ŒlÝÿpøh` V¦bPäÇ1ûþ)U&à†EôU9%òºÍðá|Ê×føŽIvn‚xUzëQlNýƒQ?´ÜÒ©æ>ìðÅ–o¡_&å]câEæÄrêy¨Ð¸‚ÎutyrßukŠŽsSŽolëš&¸Ï¬XŒEfÏÓ£{‚®ÞxÌ;Î.Û©ŸÞ¦OýR` ä̱³T¡gëQñ¶çHU…¹Xѽl³ÍÈýVÏ€•bä:õZVùrà ^0QbÿËXüЖ YA1¤ÀûôY »¹]3b†GúÔ²ƒì"U’rJ…•/ø:idP¶¬GÖ8¢°! KO¤œà©Ð˜)Lòî ª¥Þ˜†Ú¼µ¨ËŸxb94÷‚Š3p ytæà5sHSòŸ¡™búÞè-ˆêï°n]Ëüi£’ß7ë»è>ÂÚ‚`+L'Ïðíçbò¼±cW¤¿›8$ÒÜlË&„mÝÝÑWe°5 íbr¥;ôïLYkXç²…&Q®o!û„$ãç'Äj59Šê¡ã‚i”Çzß;?Cù§Òû\xšêX¢÷‹!óÏå.³ì‰ Ü4¸ÝÖºtŒÏõ†˜“[·ÅTÔÎáÔ±ùLNƒM,DDTöv߇œK¤%øôï"?ò¼ûœ3Î7`¼9Ù€o6å~ªqÄ$`جPŠòtX—‚‹Ç=V'F½­™»}»¥¹Ñ]FU@DKzDšºQ!Æ£(kñÃ*!M:¾Ÿb¹Ë¨zÍÿF'£¾›(z²–ÈU|Dˆ·Çl¥? VÎQ×h.ɹJ8öü _Œ;fÕz¬œ·hR'1†¤¸IòKÂÊ%H€@&¥b÷Ùu–GÈ<Î ”È9˜ú1£oio¶yò³Røƾ£@Q x¦¼Q•MðjG€í"º¦Ù©/š?½Ûa³±ßC¬ÃöN`âqh`Mé‚60ü2/ûÆM"–LP¨X™#¥Jø2gÀ#’Åç迨*ŒÒ_]õ~²tlÁ5ò_$"‹ï!3¶ýí³’êWT)3­ Þ†ä‡qvíÖì~ÉŸ)oVšòok²Ðò8¹q,Ýþá+;2º3y¯9ÎÞeë¶ÅŸú"½¿ÕŸ¥Âd͇QˆÞFxÍ/ì<›&o¦.ô‚=öx'е…¢NÚ¨£ ‹·¶Nª9-µ=èNá?1o’Lœô¬M¸”·ÔeÆ|Ó°e¦aµƒ<ÜmFE¤yõQº#ÂÎhéÔŒ%K§*ûÉy£LZ!Ôò^ˆF£Ð½!]ºîBù ‚‚ƒÛJR. 7k!ÔN‡jdHÖ7~e±P€Í¶Æ3yÖ•Œ¿ŠÌ©×á§ïOVéûÜXñˆYüŸÌœäu1ÂUý`8Ù$àå¾LuS„ÛÚÅ‘éAÈΫ‰¬K~õlYÆ MêùJÝvò,tMnÂNÞð„ºÃƒàªAFà<½•ÚW¬ðh8ØQrÔjÞIú]J ©îM‚g­éQ´|÷*^Ã[±kõöÛ•7àüGÒZFª™?71lë—¦…m»äTœÓ¾ÈH ´<Ç ï65ë' ]œ.Gc¤ð }ņŸšð–ÝMN€Îg#³ŸTuÊ¡õ„D ^¦ÀfŸ&#Y¹“I`(<'ma‚û8LtM©A^Ít·î)AÿžùRµ:Ðñr•½ÄÅ0VG¡Ï%ãA]%Š`:§•±þ!›Àû'{s„è÷WwO” ÅD²Ëjãâ3ÍS±w?¯¿¼E‘®Û®'ièVú…ë]¾‘z£<ŠÔâúg0¦Í™rÌ“ÁþÙs曳B½}Ç{-N÷Ó 2¼ &¥²·jeÙVèí¦¤ Dñ_1·2Äð©?̼æ«åY²´y6ÊýXÑœ y—VñVщZKÉ0Nâk.-C—ü‚ŸQ^¹Ãöš©ú¨¹È*å› Ž1ÑGì„þ—­˜€ž“ ú9%Rð–Œûw¢ï$¡ˆÜ¶IdPÚ¡¿xq‘¡-¿zYSDŒf¤ØU\»?Åaæ/VkWî­=dHGñ6R• ܘưéüÛâ8©²8S_dÑ¥º_®Èûegn𘴀)¢ ­Øî6ü(Y±ÿظ]²µ„ül o4@©þ°±zi€Ý³$WFééã8x»B˜ ¼ÜCÊAM£ƒO§ýf˜Çø)ªBuê׉R«;Ýôåõ­XÆ‹âáÅ$MKÖ” ¾tZ>ƒø‡þûŸŽ¨Þ×~üÊß5Œ¸§nE–. ]Þ@Nµuf5(Ö]p6·2¤ƒ‡™(38ÒÉÎïóØ;smu›trö:˜'Œ3ðÖ_~¶x7-÷†? áòÙú¸0„`ÿˆ?Π†òÖÈzâ2-sy%õ{ëJð¡ã­Ö'òPŠi!6ý]•#Sgó‰Ò­dm[ê©AßÞ¢âHÐÅÜDta凭ΓyC3Wk°JmÈ^r:Ù¿+æªðIÏÕÃùI í;0¤ÝõcZO†U›äžPÒ£#«cê1V/û… }¾‹ªCŠ •—v¡2Š…žåd™ÿ•! ^ñdoúnÖîú7è– ÚïÏùÛiè~_ã¿Á~R¾c©È‹½ÛÏ}ºÝA€º¦žÇ9ö̯»Ô/êÎfð©æ‘Dì›PJèŠOYqÜ·ðx½Ðò'‰=7»õ£/A Lg¤zPqq}¹¤ô"¨Èù&*Cá“òŽ$Ç“‡=ŸÎ,¡5Ñï=™déí³©´õa?F«ë°U]žÊ^¨"_5Æ{\„BMü µçY±ã÷Ù`‰C­)&%Uø*Ë$ÀžÙ„I™Ú.ã §)´¦â¢C–?7uà®Ðž™Øi%š­áSK…,4²H-]ø {‹…%N}Ø: ‹l[³Ò(}Îa†kn‡ž4½~Ü‚ºß/ò7º›·Ñ5òžuG* ƒÿàÉ8„è×Õ2¿)ë&¨¼œ"íÎÍ*;'Å8:´XÐ0¤ 8*d¡KÇ*7‡ãkM`Ñ*øqä3 óYM©€ôç|Ù89Bg{‚”æ£:uÓ&vêo­!‹5ÖåÙ9 ù‰.Œƒövè.øtcÄ)i`\BΈ­)c—nH‡8U’ùJuÃÄ «¶êïýüâG{_6ÎnÅ÷žJFï-ïÑžîk߫μ:‹QUaL.Ü:†\¡NU ÈŽÜ£¶=.`o+` 7é¿”–Ö¶‚áØ¥›oÒуs\EöîÎq#PŸq ~ÓkÜŒ“-!xÊBþÁau@zV*×”D'kO´0 Oq‡áCµÔÌ^¸yÛ#ÕƒY½›T·â=ë¸T•ÁñG’ÄìW"n#f@D°XyÒ™«2 gÓ¬|ÙÏ×á⋳¬ÃÝÿ§sjÈ@`¶mk³m»Í¶m}é«6Û¶mÛ¶mnµÙ¸{¹·ûó83<äˆñÖW%”a¸dš*kÑÍL(&¿0èë(rÉ«<Ÿé“¬Þlh1z&B¦hŽh`ÌlÏ^,w÷ÇJˆ™ô¸Á‡-Ü=A¢@ºH²“DyÕl%É«P±©²—/ލ CÙq}W_ÌîáµFÞÛÉV\ ÅÆá”w‡f=†ŸªðWg¡žý<€·ùδêr—ÀG7v…€óCÑéoXŒWàŸ´®:~üñÀpî#â7®ëvœO4ê³ZhÒȽØE€ánbj·}2ëYH‰©_…Z>/Ï­®›C”‚ÌÁÙsRž²È«]kP;|1d ÃÛQ9å´Ý‰î† …öI´¼ÊëH-Èô†h—úÓË%Y%Qjh\HøûKÁn©[±ïYüCWRã{s YI·HÐ,Äî ËlMRòéH=Ji‰kBeŸMpæÛåIƒ%A¯Sä]V¹<L¶: ­­Â:²½$׋PS*'ôo‘[²¥bÖ(v¨ 2iÑTØeE”óôÎT˜øÏ­/cD-0Å}8† ¯o«âO§Œ;4Q1,Q„4݉®º*ãÕa‡"]Ë=\üÚ£‰Åoèž _ÏÜU9Yà›.«qa6„ªÃV¸Ý(ùÊfZ‰KÔõE‰°”¦…ŸùÙ¸F¶‘ÿ±öYì²¼²@Mx%tçùÒʼTwMµO±YXÕ÷ÙjÄï-3†×7q‰Žë•2ÄDÑ3`b¼3òOÜ9žtº(F^¸Pr?v£qõ9 lŽ&“å“i~õ¥«îO¾¢XÚìŒV((Ë}‚•/†åhåq5ÇÙgGâ=¾ì¤ßø¹ (ᔜ{Ù¶øÊ«ñT*{®©· F®bdlÈþ®½¦¡HG䃤+½ö˜É&}Å£ˆµJ„ãÐúàùPˆKWuOËN(Ã7WcëÄ£®Ûžu¯¤Ct”ª6¢Ûœ^­T£bæ­T\?Koóí†Ù ºvŠÂ9[YÂ=Ó¶Ê(ç%ʺ&_Å•Õ;KÆ$ŽÎ‡ÄWåó­#M9Ï;uæüÈ· Aª³k¤Þ¬àý»è(%)ÓQ_wQì8߆Ÿ7¯H× îQ—áÙa ¦o#âÉûb‘#LX»¼½èXuàùŸY}3jŠ\¢sa’†½š^Ä2ÙHA—ÄH·H&îÙÖCzDû&˜åßA”"òU†ö~¢æöY˜ú?AMš×7À†))œ¬®"uDÃ3‰˜]:ä jxsã«'RÇ#ºÈ«'~sÚ&éËÄÓ²ÚIÿ‹36q C\¶¢×ýóL šÈ3dÿòÎ(mÓš5*‹àE5¬#TC')ÖWøj0ŒR¢+;–šÄÝœBêÅÑ×ÎÛÍ-Ìp°nícßm2ÙYÎ/б3¼-‘¥ê7ÄÃÌ})Ž?hf/:Ç-Ï"‹O€m?I¢©Zdþ•£H—\ñú2tNZ1.ŽèI×(è±Ê¤ï½ ³ø:GúÎdw—»å ²CL`ÀÊßÑzÑâ7ñÅ”¢˜:½÷1$¨ŸÄß–Tµ~§ v§1IAß[7ÙÕþžkYeFÿäU‹&‚CxõÙ¡Á«¸ )sôïÞÃ^²º .ñë¼ ãþ¸×Ï“¢¯MŒØg¨÷…”?ÄÚ6ó{Ó†/ÚÅ|Äu-û´c¸û²ÞC•ú17ÇœƒÖÐPÏMà­;Uû´œ?ÁÚP—=Mþ5_"rë,ŠÃÒ»G'އä_6)5Ë€Ÿöà uåU@­(â“Ôe3iØì 溩–¨¤çƒ¸rvW83øüà©Ç]ÄÔz–Q4õ™]º"¤ü¡È¥)Adj©þZ׿”`ö4d+›”¤o*Ë4"IÒèpÏÖoïwÎÒ?í¸Ój†ÏH¦±Ô| ¡'Êx Ãt¸NSQÃR.ç´ÿ¦ïíŇÞå1t£5¢Œ ŸÒãɶ%ùÜù€~çUGåÜ{p"¾š0ÀÁ“¿ò¯Ù"·‰mˆ¢®pÛÆHÔ…Žúö Ë œÁ>ÔwfDŸ½Z¨Ì¿ÊóÁ‡M߬LËÈbîx/tgà[ùé² î°M»‡2×ë|º¬§+½#|žN¢º\dô`󰀫g,c¼T¶,æ#š Õ–{™{µî«òo*—ˆÙ"+ÕÃ1‘ÒÐbšÍ‹ ìh>óKŒÿ˜æÃ’êVtüÅ6×ïá"œ.&Óþán:^àœ!‡i¥eþ…œ]‡ï¹Ü&¶#4æƒñFê(Oþ‰/)A:5jÄ U¥&Ãl"¡nÁþ‰p ç¤Ç%A1ÉXIZ^G3®¦å;º%:°aKœ iq™Ÿ˜Ü Ð4S8 gæD¶ˆ[€Ž¹Xm²¿š‘ó‡ ¡†n!*¦‡Ÿz@€}PÿÅšeöúc´¤ƒ6ÂKJ’r.‘ÙW„ÃÝúK‘9\䮬å ?´ï¼y(m,ç}—]{ö¶÷ª)1ºüaNÄD§Âi5¥…iË79nÁ?Zoï"yðÆ>ñÙF“Å,”¦á{•‰Â2 ú[ˆÆ4CÒØ.Q~ʯÇ•5 ¦½Î9Œ#pë%}×'™ýÄW›þÖšM^­×Ýöæ‰<|ÎÁ¿ H ¡›u{€÷÷Túk‰z+TÐãNÆŽ÷îBŠK‰ºÐ4O‘Y„ 4Þ×=M ¤J–ÕZýæ:IþãE3H¾3´vë*ƶ@¼ãfM1–yœhe%áçðÄþE39Ân í¼gq-ǵ[Ë1n‰«úÝGSMõ£tÖ9B[?Ñ4Šˆ©×3¯²:Fmñ´ù æ•¬2»ÈL΢gZ](—óþÙXIže+…±åÒy#1ÀG›Ì®›ý*t‘;Ìûü/Fä­{ g~ó›¾#¾ˆÓ¨tz¦F`i`üuAÎÐøL:ζ—k¿\†H‰;€€RCëSåF:Q^EP"·“* ðA¡z%ÿ^ãðU ñ®*ù[–¬´óí%²Ã™5Bmäõ™#®3¥®@ÖsúÕV —mo-Bç2 ÊÚàQÓsõôTs¡Ze}›§‚è(^3¥*eV͆Û¯äç gf È<à5‚Õ«'‹ä¹¼ØââmÄ2øÝ® .8YÓ7Çižút´-wÅŒnÕI£`u'hK€Ãí=Åã¡Çà¾5‹æ;Í•ls>pRmX„± IjŠ$E3³ã™æc¢E¨–¹—óïC I6’n–m¡Àtq½ÔFýgzüïìHÒöVÚzðg˜ä³$3Ü·VÉbU`"h¾.Ï]QÊ‘4§éûgÐB‡¨€tçä9ìѤÞížJƒñçÄ5Ñ·÷ÌõƒûqÒ+oÓúˆÌáË à¦µZh#(Ï×2#‘} ìÓÚ œ^P&3·ƒ¿Œx¢‰Œ19—ôäsA¨Œ>ÒiÛ£¥É–ñrgÖ|vcûS±Öö–fväýT¹vHm¾SÀàG Í÷Dëý­÷݈M/hµ,7äµmsïá ùÆš§MÛºÃ(FHZŽi9MÕÎ#ü¬ 4|7Ê«Vù׸ÀNô5óÂ_\4âì¤mWÜ61DØ®²ž73 ÆÒ¹Í¢Ý78$QÌÅ­²“ãèsÀÔÞVÁž^îgܻ߄'†•ëxˆÁ‰/G7ö&dñýÌ7´Vƒ.ÿÒ¨Åè€À‰¹@=¼CùEѹÝMI†¹„؃’Y²FŠ­—Š«®ãkùÚ‡ qy¦Jzj¿>ù‰eÌç½=V.¨–ÖºIA7Z)ž¸e«hw%AzQ1NÅ’úØÒ‰ëâf8¯ö³ú>Îeö§Fím˜–÷s¸é“wŽ\:q¸j¨QžÉçJ3¦=Ê!rUù•æüõɈÕªôåL•:ïЖzÅ Ø"W½ÂÓ2[׈œc4Ô-•)aÀ´5J¶SÒþ[2c~ÃÜÇ|¼%번õXܸŸV~5íó`ŒL†%Š0Ò4¥‘’dL;sF˜É Ч¹>ç’/fP³ÚWÖ“Cf1ÌT ö!o*”béwùçüúô2ºz}5û瘌ߜÜþ©C144¹‘Â.‚u¼í|×ÌŸIœ½—E''CÈ'f±ÌFá¿pNÅP鱪ï{zB}­“6Õ#‹×LHtêgþnPÅU笵qþD„˜T_ìü¶ ZcJðÛÃ%×’ìz|+½Ÿd&ïRÛ÷Kn[£MRŽ&°²«1ßÙŸ®ê(¿ø}<,Yé€7y¡¦œŽ°|fKŸf¤ÉNL )еPo~Ôqt‰ow[c‚PéeÕ£èhLºV~Ôrˆv˜È¶-˜ø4ƕ赲‰f/u¼÷ŽÑJ¤à•·ÂèEòñ@%Ô09Á oè Ë+<€òó㨮"a6KP^Ä>~£üá9h¥NfQ½;…S'£°yokýcí™/îèX©í¼™-ïE¨s+Û)nø¦u< Æô˜&þp·u4`ž]’E¯¾Œ*öÎ)]ãÅç‚2|Lƒx\•JA-ƒ¹¹ô&ÿôÄsØÏd7{¤6{sBÄ_Á>”£4ŒY®­B1S¾Ir?™Ÿ‡3¶½oŒ»öÉÜ#öÈjSѼíÿ&pCfÊ£-rŠH–QʱºÔ_x‹¡eF:6èu“wz+úšs¹å:%%¿îŒ‡–ãcš·ú¶Ç,"’qÃ\šEÍ×j$ö—µ¡2†8ß µ rÿn¿"€;*Eç=« ðßük¾èð†ÇVäã áÅ ª—A²<§ÁLž©E—3êR©ºH¶.ßmwy€@ï‘ò I”"EsÝ¢œÙ|³èg–ÜT„‹$•1ˆ±‡ÔãRê1†ÞR<•aܰ2·^¸Þâ{i‰.ne¬¼2Å®×má¶vF!§( wh9×¥ê7ìy°[ö&V£SÕîƒ)ÐÀ¨gÐ&¿ÕG쾟üÔD}®8”âÁK8ä½Ó¼b»!N1™íÊ2Ö?ЕGèY©[—‘Ç—ãY[Š ñ þŸöÁgÆš¦ðzòðgPx3k“upè°Ç) 8ƈޱº«Ê Ë­¿d–d}Ø=lÑ‚ÊA…XÎ'?ò€É‰7üZ öo|†Ë±›ÏfûUM©Š@±ØšÀqâ9€š©ÿÝ@‡Ûø”×*~×]´Ž-Ó¤q°•mhhUð½Xœ¶sÒáW¨Ñ,<šm{ÀÞ²¾C´ùÞ/œ_¥JÞH0áßäûz‰(©ÕÐ,¨)g¯®òî®õM%Uˆ²ë‹tv iöƒç•é_¬çvT«ìô¿Gm¶žQ1h¾ ªÿ6H‚!à_ð2³83< èÖÁ$îeÎ1²òJ×'Ú¾êé—”Ñ_¾¬öŽâvR31C\Úñ>©J7¤Ô¢•èÓ“èò,¾Ú®/…zŸ –ôìcY…sÌšâë»n÷¹tãB…Ë4]M#ÄvSÛ‡/¯(Ìal 8WtôuJ$,†l}ØWItÅDp }âÿ(_‹,FpÉÍikSÃà0ÛJwã§U3 Ìïîª öÛìuºgæ"ïlàäœ Ýçëyv93É^µfÏÀ âæƒh%Õì8ßrÅŒ7:T;O™OF®„fO|ùÊãÊž¯,¹ñÄÿŸ+µ¯à aÍ^Aßëȃ%§¼EW·ë›”ÑN‘¯ã/_pë´cd‚# +¤Ë…øœÑC˜Ñ®k\f>­µ’ßì§õy£¤i½*˜0ْߊ*Ðav™n'4s Ãpr€Ùš°¹\R<ì*e)%ТIR[›ÁËÝ^páºÎ¶xSOFTpï9jÝÛ4ÕÊZ")¼ér<ë˜ÎÑ&ú2¸¢_Òk äÔ¥Ô³ ¼0­Š•µÓñ¯ïûm‹Œbßl!f•™eâ6ú¤/óy‘‚ ±íµ–tïÆÚÃ].*¼ôa&°•Áù¯Ôªn&æÉÈ㥹çí(šö@¾Ï±Ž þ¶»Æû®³Ól_Õz «&eºKˆuìzbs0ï¯T©ÏBÔt –ÿn|ÏèyëW&TW )gqÈS£µE‡ˆ?9aZ’E=‰e2ý=Ƈ ”S(à6¦]ã·yæütDêÙÙ]'ßà ܺsÍíIšUÝ QÅ!T8XÒúú¶'»p·ŒN¿ŠŒ·®?äraèÔ$ðšj"ËcGÎhØÁû˜&¡‡pØIÖýíBÁea¢~iÁºb0¸µ ÷.PI²‘‰VbFØ%Ó JT9AS¼¶:ïÕõù4·Z¬ùØ`޲Q²£by¾k¸[XÖÔ9Jª±‹ |¦¥âëM_˜ºQOÍM7ÞÞ_e/¦Ó~ûæÏJt!…„Ù‡¶ÛU%¾ˆJBŒÇìèÐ)èoí™â߸À=€U%Ÿ÷Iä¡&<åŽÛØ·º{`=M2H+òsTBJ>µ@­‡¬ Ý{eð%ÞRXLÀXè> °•«{ôôKˈâú§ÿì”nC ]ýÒ%p·d·˜÷úªÝÝÏç Dlˆ¸õ} :Q…â«ãžÍAÑ]²%ŒËí£z?ç>ÚËõÁ8‡v³T®gÝ>•ÇÒt¥2¡ÆéøO»·p"ºŸÿ« ‚¹—Èìj?u6ü_³<׃‡Ž×€-Y)ˆ`à;¶°Ñ"«2•7Ô¡®2Bª|ò¡l¤[é-½z‚I?öt*™¤*ÒÃ? ‹+šE:ÊDç+4¤Ü\éf+À—ààr6Ó<(Ð ‹ U Tõ§‡™Ýøù”45åOEèë9»_Ù.žûESÉk£ÉZ6ÞFTK KaLŒåuúÎ-õ®¡¢ÂéãòSáÂJ>U§®èæŽ 3•yUKªÆ-Ú¬„CNM«V¨¨5áÕ6á»÷bu¤õ1Àš¿UNkÇš þœ‹Œ¹Ãì³êMK€GãwIÄE:Øõ¥1Ä]Ì ?¶äª Z¥0i::€‰`"ÿþ á‰ÿk¿Ç~uó!nLž T™Ælá‹÷ÇÒÅácr䬫÷Ï–Å»@¦\mÅcéÒÌúU]Ûüѧ»³¾.Å~ÿËtyˆ»ŒÄÚ¿ÎN­‘ùsY¥ž‡øé Ni]ÌðÄ;8‡ƒà†3.0O’t/Æ(P çÞŠÒ?ª3½9 ;Wå†þQÝò Y &•~ÜøZ®£î‹uÚÂÅT+?>_úÏ P|o¯Á bý{†5m-\ækúÑð‰û/J)nÛÃ6Ço8ÐHðˆ=à*–‚l¾³Db¯ï"Iìæ¨&(³Õ®Žñ(b–¹ƒþŒâ3Ç ôïÝÕ:Ô`‰ÙÌ/’Y~?¥ÒÉbè2(¸ãuµ îˆ+˜60;¢M1Ñ~`÷6Ñ Ò³ à0o.´³£é±ìÓ2šOBôÁSûFfìjH#“¾=+¢lÉYËݳ ´mj4Åa?àg%¾wÛy2s¹­>#? IR%\ÈËçÙcyEÞ?d‚å«çQ/KR.§àäŸÆtg‚6lw*䩯|R¯bhóÙ\‚Ž­¶_²yuŸ"ÑíÞŒ¨²ð|:#ßT´2fYy¯ãÉ¥ý/Yœ±ƒ¹‹ Äm‚\ŠF Î7÷8C,Ø ö2>ØKxIbÇïˆû¤[”þÑ:8´×…;]©Õ\;øNzÄý¹ù7ļÞ¿áa=…Kî9jñ‹FÔî%¡Ì‰´Â¾ã̯™ »Ù5âƒ9PÇ$"Е¿íM…/ö!OJᙎ<ê€Q^Çëg"¸_ò¹ŽÏÆD$=ÎA”Û0’ © 1Ë©oÕ-Ú™½EE³k“Ó³© z Z‚ï–!öyÂgluÍLXZ£ã ÞYÙaÙÈ£ ä×ÞµNý {¬WNámæ@¡¯œ›HÞD#õœ[dœä_üvT¸y¼ ÛÖ-7¼— q4JnÝï® ۢʜUH£Aaz½ô¢?_ªUuþÝ‘‡ðt˜wy‘àÍ:ëÈçe­ãˆß[…ù¬h­áM>u¾•j‚c±œËâ=ÓM Út —Xôô£}Ó^ ‘FÈ00Ö3gò«‡2Q t1÷ŸÍqAõwþIÞÓ|¼gÒiûß“#£®Õ€_2ÒñòqXðÝây±NG¦ähŸçoÁÄ‘& ðÒ\mÕ;d›hÉqM{Tð}̺쿡¸"Ú†Sù±i#ºê^ƒÍQ èвÌÜþ?ú.Ú¾Èfš¢5ž!‹œ+<Ylž2f³Þï§¡¡ÆÐMÁèðïÖj"nwžømÛK2#JGøcä«éH6‚b?„°q‚Å1AÆnK2õ/ŸwªBNiä3š ºk,Io/­ÜKœ¤†¸²öxÐv "åûSröü¾¹lÕ3¦Ñy©C;ӮHŠ…Å,®uWÂ!fèx“p0Ûô ˆð¯²D“ösußg¿ïVc­öÝau\IQ$­Ïµ¯ñŠc‚ —€ËmLÐÓš?®¥KS‡»›Ø°§Kà§¼†/¨ù¯¨–¢üB\TÖÓZýŠYQVt°Ñ«ÊëÈú°`墲®ŸwÊmÆÑ'ëaUŸe~ÙmŽ ˜8”6$¿‘¼CÏÝ!gŽdŽfLæA£õ’8ÈÊEüñ:¯jÏeݨ~Ȥ×éãÅFYœMl]80öo ß ‰rlò”ø2‹š3 Ù ìf‚€=ÿMæ2kÖ\‹‚Wy#¸R=¶PTà(A1 ¢×<ì–“îIÀ¸'>ÏAñ-¥*;ï³ *gw¾Q¢Ûò/C t³LÛG!ý‘XxëȈ㿵"ww±>9ÿ€[©ê¿.rák. æš$§Ëaolq½çÙ8µ÷uu«}™xt{´sáÞúLýj&( Zú·/=þÿÌÍsÕ6› °Û¸‡diëÚn_ð(Úd¼¾†Ê«xƒIv‹Š_*Ìn¡–Oü7X{uvÍz+©¨ÃDB½7=Çh|J§j[ËmIxRšÁæ‘ÅàÙ[öÚ¦ÊJÓ‰vËKߊA¼´URwQó²§BÀÉ8Û@¥Z׫!ZsµÍMå–Ë®WÌõߪUçÀ‘¡pnJLlÏuS¾…—Õ\!±F*£BaôV‡§Çìâæ†^GP*ZöŠ¿ïX9ã8««Èîñ³êö<Ú⾘òbü‚̹®bÿÓ‘9JH<æüW?Ÿ:U>û~'Âf×y”+Ϙ™5hÇuZ×^çÁ¹ŒgÜ‚§áv¨_k˜¶¦R䂯òâQÓð[ª¨²¿=?%@ m)–T3®§cóó(ÂÄ™Š5Ÿ³+x|4g|«ñUÃõöªêh¦U’«yf?áQýœ(,‚éX·ß~YŒfédp!åè,}žc…ò·^P¬•wÐØ…ì1¯Å) ãu®›.vu+‡¿U¢XÆ(¸¦"%é]8ôUxJ§R:€O=×óÊkk ì¸z5ÉiÌ Q©;ª¥¸Lâh[Ìb…É:$ŒüŒèeî•<~„XÏU߯yí×4“à}¾ æç|7m  ËGo™9w„‡olý9߬d¢¥±æGW–TÌxoŠuŽhm#Sàk[ \æ äñô¾ºoJ’Ão7úÒ¸ßê< îKK<é6±”3i‰h燺y{1' âK¾5•d¦øá!½ÃªX]D(uÿet”ü>Lä–ÔŸ”?ºQ/3ëŒÃÎx†‘Ít_Ïwqö ëŽöŸùÖÿæºÄ>]ªg9û›î{›VQm%“i™¬LƒËì`QoiŽýÏÆ²}/uÆc0Û  @bøYhUŒÞÞÿ2P–ÔÒ +\yºQ#~‡r©L;·EFh‡ù¯²¼lky+ïú¨ß|ødCaÅ6®|È}ý'°;p¬áX„xJT'|,á~àïé(U/üñ4zèi^ËpLžëd¿ëWÀºAã =. 1шuFÑÎƒãø·mUá°Â¨¶Ë‘ÁKÀ<5¿«úóç‘þñeôêÅÀ?a‹†ú~{C´°VXÇ(êÙ8®Åž Æ"ÿô]ºNjÞóE,gȇÔ:}D)W%0Ëð‘’öÚD+3ô>. öÀz˜ˆkõ”Rò_I½ßn "`½¡DY&Qq©¨Þ’‘„æós©ñDj@@ÐÙ!¯ö(S'ÇQ 5FÆ%ô Ê#H‚7LŽà¥9‰EcÛAP³°Wbü›[· ø­uÜvR•nå4íTdH°2s½öojÊ*qe)Ž;¯Ï­¤®Ã\Œì,¥0'öÔÅ­¾Ûw@=|ØI#·1 ¢RÑê ¹á¦šä¿´ž+ÖNfÓùÿ%>ÅÓá_aè$ä¸sA\ Èíã6…l¤Æ´{Óðœò³Èï8²Ù؉Yv2¼38u%½ ËZLó&ýõôÅ n@\ MàW²Ÿ·¥i3m›‡º>ì ¾«,q%æÒ–+K©Ì*@$úÇU@kš5bÊÃc!éR5¹ŽH‘òh˜ÅÐôWO%çlqlþðRz Áæ´ïì6„o"\7ˆ43\™®Í:çhúñ1-%EPB3 ,])Tôù[£©ù]Ë’çÎ#Àmìa„“žg=ç†WŸQÌò†Àœ±§ÿÖ,¬›tn©&壺aÒ¸õ;º8±.¨óÉpy¥&u{…cf_Œ¯© 7nТ:I–rubXK—­û-{_ÁZÀÄBÿTÍá\ôËÔ’K2· Ú䯿VÂøÇ=Ÿ;ìOB·ÓåN.ñk+å§Š¡ÛÑ×9Ûî&¥ü.ݪTe0G푺­¬äÛ«{_¨^MMV†xÈðcZ0õvž\‹S"M¨¸_ïËÞœ­ßK¡˜ŠèWY‰;“¿0³°ñôÂaj:ú´Z]­AçñQ#³IR®†•â¢Ê«%YÐŽ»*‡Ô«…*¼ÀoÈ!ít†ÜS»Þ‚íÅì‹_ÚÿÎX. Á ‰Ðy}‰;ÍVIX#“BÉr61ðmèy©;³šªÚŽ7ÖwëÑç둦ð²ŽIêâWë0ºöàÿ{6–{"p´nŽçÉH:ɼk(¶7IJþh0j»u"”i1ËG,m7J5Òïì¾¹Á]î›çg'‡l+Ålsh˜ÔQ•‘eÄßñÏÌî&ÒÄÐJhÙ^€«¯>¸m‘²R Çò ”ŽcŸyŠÔg¦zO”òªÀ¯åg0Þ`‚Æz*½m²ä©XÙòä6jäÖAy›}'×=9ð¥~÷-婯u5Ò–?úêš ‡‘Mf, äRÂûcìqkŸSpÍÎçc®dúÐ?òˆén`O-V¶µ(}Fmî|i35£þ_ÛÍàÎpJ¯Èi,öJÆ]ïx<+‘s¦ÛGI½ÓM)å·™x í“ÝwxCx¼ÌVìr÷°çü"ÈÏÓc«eƒÕplâ0«ÚÀDøk#*ìñªžPÞaŽ<5Òÿ†—ÕË!ÌßÙB¨gرý¬ÈK?4°›ö¸Ê+@¾yð¢ÛK¾£Ï_cžÁyØÑ E̽åâMAà8?½8r§¬4SÚLKÖVî4éV~6ÒÅie[Bcì3ø³øœ[§ ã/’sKáù¤N U±ˆ/uW¤÷dÆNVí DÑvN¨fÞa —Aûyí¿ô¡&«·©í ÷ƒ¦ÂØ…‡Í¨ÔN¥–1 ÇES¹æåÂ:s*ËQn¥B#•ÇsFtÙ‘*UЉÀ ¹ì׆²æî³¥?wIIê'vJ~ñr,˜Ý˜Í8‹ŠBÚ å@8¿¥üdaÕÒÓRêNpñŠëÔ$þB˜DyÍhR»ðëÀ«pk³<;,®¬„?U©jè?ç6w¤JຒÙf¢ÃC»ˆÛ)÷B1Ú¬x„Å6¾4 <& IžfàºÐwj7%YhÁgò÷»¯ÎjH¤Æ¥ª> stream xÚ}–uXTkׯ éT‘@:†nZÚ¡S``‰aF¤ADº$¤»AZJé–îüÆsÞsð{¿ëú®ýÏþ­µöºïçÙ{=×feëñÊCÖ0„3ŠW€_€ð´F¡B|ü„¬¬ŠHG8+AP0I€€ P@(ÈÏÏ€ Ð$‰¾k¡Ë µÜÝ v¿+ø…‚bâ„‚ü(ܰ†ÙÁ ¿ÔœmÑ¿ãPw—rOaH7´€-Ê @KBÎŽ^(Ìýœ»££6Ä àøÛØÿÉCœàŽ^ÿ_… ngphÁ pw§ÿΪ¡ Žpyg;G€ÿïÜMî ƒ‚á({ éû;là …!áÎ00 þ{S¼üüÿ•Ó·‡Û88ÃÜÜ"ÿIi#Pp´9Ãÿ,½FÀC°æ9¡wïŸ~7˜3 þCaÿ€9Cÿ{Ðûû×.•ä5 Õå¹ÿóÿJ*;Û  pg;€ ˆ(‚DB¼ùhøàhóž˜'zµ@>g ýÀÅå°E ¿&QPþwèonH T¼! Pù_ãUnHT½!!P톄@õBëiÜZOó†ÐzZ7$jßZýÑ¿$ŽVßZ]÷†Ðêz7„V׿!´ºÁ ¡Œÿ% tOÓB{ܬÝ=ÿ&ÑZßZÞbãàæq³¿‰¢ ÛüK¿¿& ôa º…íˆ^‚Ý8:i÷{XaÈ?JÐŽìÿ@ôÂà ڽÈöëxÓmÅñ÷g|“G{uºAtóˆöŠøÑÊ@+ÿÑ }Q Úˆûˆò¸AAtg¯¿ðð`Ü¥ïåòïØþž€¿XàoÖC!0#8eÿg‰…„{šñóñ£÷—ÿ÷õÏÝãÿ;Q O^Aq¯ €@@í\\\ÐïÚ¸#‘èÙüëPCÏå?l GŸ(0˜'̆pr a#ü¤<¸áäƒ<­ïRîϹ¦1&á"(¶ñ,{M¼Ô‡Ã® VÐ÷Ô½Éà‰¢Ð¡1_Z®­“~OóÖ´ç3Iª™( åÎ…Þì/§û­v0(â¾Ý€Xò‹…ÛÛ±:ôdVf·ÌØãÆ.BÄÚ„VJ—ó.›ÜVL%6N€‚#r¦$ZT”|FÓV¤ Óƒ9T‰9yô¤YŠ»¾šÁÀ%V°Ë¥Åz€y¨¨dÏão‹?ÍÝŒŒGÙÕý«/s­¹€¶;¸‡‹wõ[<ŽÍ?¾¤³Aô)¤íd¹>ÔÔ}¶êFÖHûUq54•×ÈËt·JPìm[eWŠwc«nqÈóþiERßäôéZ.“F ŸJÈð@dòB6/ù=jâÉBÜOÊuzz=ªbÈÎ& 4+6Ú›JFUÑZ3Y“Ãøâ0{êô~áâLDzJìºK|{§…¥P¯Ç(ºì´Ìw„¸ŠÝæPö™Ây·åà>Jîë¹^SLòp}ícÈWoÉ·áœñÑÊyÈöîd\Ý™;: ´èÉ+/“-¾¥"æ÷ÃÊ¥ýÌvÛaþÛ'9t¬o‰¨Gs§ïn~.¾H3÷ˆ¯‰!#Mei«[߉Nö^ÙâtyÛ¯7òímb—ìmåfEp¶‡Ì\ùoV"šÐSÏÑvM*{n) n•l _ûÚk RžžŒ-½ÇF$ø÷‹ÓH¸Øç4¯e–³G”QÊðcè‡M€¡í +¹ Êä‡4]ŒÍ5ŠñÀñ»dÃ{] $Æn,„Óaس);úÙVÐmaÏC:cz_ÞXº»¹³D—¨Í¡’¨[Pd¿QÎR¥“ÛñŠžfľk€Ã—Uí2×Ú×AR¸)C¥÷zÎòLhˆÓɯŠz#ÐügÝ ÅÆuzù¡ßv©–È(IKlÊðñI^<é‡Ä‹™ô¬\ÆÊ™ó=ãµúÊ× Ui¿ØEK•• þÃÌßkº/³¶ µ¿ Uؽ>š´õO뉖µ#“¢øM¸b ä’¨&>¿Ð«wnO~P»å<“8£k—¸¾7w,³7öu8¹h¯hð8Za»ä“«ŒÈ,BüÅ«„:ÚLn6k‰ªú"¡6ë3ˆK\i€Å'ˆƒ'ºënPéiZ¿.—˜÷¨WJ­xu—´6NÄ¡ŠzÚþ½AtfÎj¤—YÚg£Þw.òåÅ`÷•ºA,æíô°ãñ°ßËñiyvÌ&n—ç‰ìÙ÷;fÔ…%­*MÙ?IhsOÏ^¬:<[“õ{e'POçÙgöWW8‰OY5«µCª;⑯`’ˆ2uøËƤ_¹(1øpë`)¶ Òß# @8ÀdÅákÊÚo©’›¯tt-§Üž"ATMíÀíù.vòÇßßõŒò¥ mã Ô›ñß(È}ôÅ¿¸3%æò„ÎÖÌžú(:wŒîùFÔ3ýlR"ˆ’WÚ“i%›U“âÃBW£Ö1Õ7ªözLݪôïi©>a$´”÷ÎA‰÷b¦W†I°*q9ßù<~mÀž<>±4oÜÙºLrpÇdûݩȅ—·b÷¾iýœ—î]j‚<†8ÈiÒ/7²qòèÆÕ‚³¢ËÇux9ý½Ü)åãyo J°QaF§)39­ýÌ ï-ÜÍ!0Ð÷ìïé;I˜ŠGŽ«ë'ä–ÊD_ÍÍH¦iY¦ì–š¿› •Ž7PÞ’|X\>ôœâù«qožØzxº Nl±ûˆZÜÑÔÍÙ!ÑÚU YißðÜ;ÖÎä²pl ,¢ü+^hõU°Äçk/sx!ÿ„Öa~Sy8}Ydæ' ÈIQ…”+Ÿ£+ŸŠ F›ûoÒi_™*-ÃhÛØ“3ñÄ•Ãp³BÍ «RÇפ²>aÍÒdÍæU´©üÌ÷²ô𬱍òϨ±°ØŸ3î´Ý:(3ºÕ\œÁFÚ?‘uüöPïyèâáób90øÅÛ»«×´sÒ¾ò£þHWƒ=Uסõ;“ÝмœT{̽´óAÎ><v·|+]Žbƒ£z=Ók•*æ{®âï¥4Ú.¹÷.uk]ÃAVµR6 WOM­[Á 7‡A§G0ÌÇ?¶UöêƒeCÕw#tÁW?:™®„/Ç”Ä0dó¾r ÞE²À€ää×îÇu 3‚µL``CnŠncÅGBsö¡ZünÉ»:IçÙ£_¡[©Íˆ¹€»úÉÃý—ÉØÃoîÓ¦<Æœ3 Ö…ŠKXÆ t‡Y‹µ+%ÚO4RTÇÍ®ÊÔÍò˜iÏÅ8Ï:{©YŠ~k\%UíɸµÁ˜É«t@šÃúìsÐ Yãϱ†p "×LJAI/?l "€ã±É 5Õí<¡SLøw;=±Ò"ÕjpÿbGDYZÞ[î'ëú8ÿ¡†¯×èmC¹רTgb9XÅ(?XÕ×1MÖ-þ P.jpˆ¡¸­Šùú‰#>;ùìäÉð’ucÒݰ¡X³–ï8ŸgªŽò™*î)k›hjÓù0´¶½~Kxü¹Ü$$Tá£J¶û°³UÈõb×1”ƒ! ñ½Ô¸Z=ò-Çíz«DæsßXˆ[ñÓüÖXHwO[@ßÓµâ›Ù9Ü óaª²š'þÑCŒ$Ní2‘¬/Ê8¸¿Àìúz*‘å}fûä]Œ+01ÿÕ¾ïÒP,«'(ÙãœïéÇî{(7-Ѷ† WgTÃÆ·ÅÑÉÙèß9Ù³}5‡™µ®žC-DÇ‘0–}ì•—¦G˜‡É²ˆY¶9³H&¶ØÏ yRÒY¿(²¨Åk2[#$ íámíËË}@&öÒàØ¾P‰’>ÕRM«u¶u§¿w AnO‰^HK[ç³ç-½äwc¢†ºnW‘ìÓ‘,žX ä•j¨&ÄSÂ’ßΤÚkN¬ÐgUo¼ÉpÛ˜øÜj͆)t¯aÇ8ß“1S˜-*çĘ´»¼ ¬^_‘—”S8è^3OH‚½•&Sy†\¿½f¢Ô³K€W¾hù2àùñ+ÁСÙ$%­Ú C1Û »é?›Ï=Åêç-ZŸ¼»oõb-eo…‹Š(šÎe‚Í»Ÿ›ziNNñFݦщÑPéLx(‡Í)ï32òŒ•BGϦU¸Œö¬ÄøçœL¾½Ð¬5&Þû‰ðZžy¼»¸KFµ‚_×»&¤ ¹'ìÛ÷¦lc5z¸Y*v•e”µKïqÝ."BQ4<ã·;}‡Ë6ý “`—™mb&Ó9gÅ«k–æŸ[ä‘É“–/뛘¬B Þ^¶½W!À"î„Ö…¤km§öú?m®ÙEJŸFì~]œÆ‹›OŽàì¨ÝqmL]b  z—½+9pQÊØìœ‚Å…þó\T æ”Oæ].þ M¡Nßæ±kÍv)k¦Ïc=Ú_fIžår½}`Êç×À­ÕgHًػE(+lo·מŠ_’õ“¨2¾¥^ãóÐå»Ð#(S®¤‚ÞBG(Ýå:T†ì“T \¹Eƈ‡-XN¶ Ï<çËp(› $ÚQc>³âÏ„ø”cKPœ€šíª³ÎVb@óÉhu¦¢vD÷â[†o–Ô[V¼ùÆTn̦Øvõ·¼<+-†#f%¡þQ2rÖ†3VÉ–%‹*–zÚʯϓžìš®€JißÛ¦:®üØùôTÞÉÄ}øÅö| †ÇuseÞõUK;=Fl‚ÝVÜè*¹/wb­µw—a]_¥~Î᧨i£ÃDuð¥Ð FÕðI)*¦”Y!*œÖ&%Ò )h©?âÁûˆæÁbçe»þkÚ|bYg®ÐÀYcÏ ³0Ò:åô¾[¬@ºÙY?­ú¹rP±Â÷‹…‘Û>Bjöû3 :*Cyo}Ê4¦Ú9B«° ŸŒ*¥…8´º×öfDÆXÎæ:ü¢ÚUÅPq|ó1vàÕª å¾Õ G®u¹6yëÕ7ó¶e–cšQNÖOJ>ü&⓯C‹ (ûL¹D÷CJÜíJj%ߟZê†/³dr¢0Or8àáÎt¥J•Üçjǽ–¿%oÉu–Ö3Pš½Î×ÏÉ5bÚ¶œÁ…¡;ó4Ï}¼¢õTmEùH ôÒoù#j~֪ѱÝ3¨-~ôpCþ±eb1=‘EëÛu†6Åðéz¥KF9&Ì~G8jË¿c{¨WŸü›J”©–Ýí7Ê4ô~2GîA2Xa¬ÐÍ÷S>#^ :ý†»˜² <Ó¢úQöJ24fôä…5b›T®ÍøšØÃ„tµü Sí]Ò0ž+╳^ö¡Ü<Æ*Cî©îúˆÝË+žî܆þ,íWêŽÀçwLÏ…”~•?:;v¤ë#EJÏdõâ¤Ï ®Î,Üî÷f¯ÝJ?¯qœèæ­™z-2¢‘W¾µ)ov/³ؤb%\­äÖÆÑô ]š©bƒk½-gñ¼0ÀR´Ü\;ÖhòqjÙ¢‚ÙÉÆkxÕuñ8¨® —䶺 … ²U …‚dêX™å‚GÓäž0{f‘‡ø¤Ó¥‰a\ÁÔç”äpröe²b”Ù ¬©>gÌH^Ÿõ‰º°¢õ@‘L‡å®Òçb縖\ ùuá§YHýV©ìt\”bV±cûµ~åm›ïVÁÜ¥æLӼ˿l©ò$ÍJA;§ýCî4]Ø__>}„@vcJ~¦•<åÖ²­ç[’ë ´Ò3«BæÝÎÞÅ>µIP“­ºµÞý­¾ÕwIÓs¬D¡C°üM ¿ðëY·>[(‹¸!oŒÄn¡wvÁUßykæ?ñóþYԽ󤮃æM¹Aé[l}GÁÍ!næœ ¼ ÔTÏÓ™÷‚Û±ý“XÐ/–#!ã9ËIرÌõg°•Ë£ Üyls†—ž!Cz—ֆϼÕF¥3=yT¥Bå™ÕbîMMj “$z°Ìµ÷†{ï2,±¢JâK4gš4EÜ‚›ºlôÕ7nŸø~zh‘ë~?¹Í9c½ãaÍ]{„ß`™„Ò0âc\­wMá¨f辚|ä3ÀË8K¦+›Fþ±Où-úEôoì¡ÙÁOµ '%9S_HØ?G®%•©:HJjþÖ#½“òÜ+Ë5oå·j$÷勾æÄé7 †ÀpÍÇbدýØŒÏÎïïþ@çäñ”%M«6†Mn’0«ŸcÜgZ£ÛÆß¶Ur¿Òö€FKáŠhÆFd³&Á7}]û¶?ø#K¯ƒ–°€ˆØdÇ+š §«ÞpI”¡wX ëÖ7P€Xö|ã B$u21¹8nhžT~¿ú £P¹ÖtJ¶ ©µ>ÿ­€öN¦"…ïÔ[öÞ–91ÂU…¸ÖS˜m58d}KNðG­`Û=Ùd¾÷/•úU?&H¿pO\³-5úí¼¼ì¤pª—æ ,ÛoŦˆÀ¬çê–¢¤ (#0ŸîÁ²t­÷€QóÒ¾ì¹ÐšïU‡ã[ÿ<Z¡HÿÒÌ©˜‚W±íUdöÞüt†€SªŠÛã±J 7¢îÓCøÎ7óáÌœHÚ)Ç ‚w[Ð 2ßÊâÈgënü²ß(ûï•I¶<°£ûA"ƒ:騅¯3ö3ü(ûZÌT›Q}–Áæn³´®Ð}>Œ*°WÈè­—j#Y/Õ¬|ò‹¬+ÕÉ@ÕòÓ- ]²}*N°©ip˜ÉÙÆ1Q\÷õ}ÄÿÚDà endstream endobj 2695 0 obj << /Length1 2291 /Length2 10194 /Length3 0 /Length 11435 /Filter /FlateDecode >> stream xÚ}vuXÔkó>(Ò%²4HÇÒÝ-ݵÀKK‡tHJI Ò ÒˆÒÝÝ ÝHw÷o=ç}ž÷{]¿kÿÙ{fž™{îyâCM®¬Æ$jfo–²·sfbcfå8³¹;;8˜YQ¨©ÅÁ gˆ½ÈÌ`cgaãdagee€œ¡ˆúGY¦©èâ²øÁÊÎ `çææäDag˜AL&` ˆ Ëïü²væö6®¿íf.ÿõ¹‚ EtТôhI3{;€ØºÎÅÆF d ÐýÅëÿ¸A¶ÿO€baé  S›A\lÿ×+ë ²˜ŠÚYØ€¬› NRw°™2ÄÙÔàìèþÛ¬agv´Ø•í ¿%0±±²þOÝbjmvrÿãR²w†˜B¹iþ§Eh‡Œie…ÿ%¶…j÷ß| 'S°3€ç¿Ø ü·ý?°ÙÿÊU÷/Xä4Åt”µþâ_>I;S{3ˆ€È9:‚5þ¹€þº±ÿÉÍùÛhï 63±ùc!ÔúÇ<Ø -?¥B[sÛBþ½¿cÀ® MâqâmãÎôdyê mßÙÒüÇîÊäìfÿÇh—§c­éòûÁq2µwüSkèÀ]ŸZ„*ï q‚˜@§î=‹ÄA;qûã´B«¹ÿ¡t<þ€Ð4žOÍ@Kx‚ÿ¦öïH±sV÷pøçýý"ý…ÙþÆjÎŽöÖ`-ˆ™³åŸ!Š è©w×cef…žLÖß¿ÿþ3ø¿/œ˜˜½»úòB/f6 4އÝû_q¦.ŽÐ­äü×ô™ü/6‡@x0ØlŠ23eoÊdõ-¨áª\”Äicai¥),F§3èLó3ÓËRñ“ôØ[1c³Âþ$åé¯!£SïH^\ ¹ë·¦ù/&Êd8ÃHv®‰1eõ^Ÿ¶Z€_™Ù[ s'…­aƪbëÁéÑÆkMÝs·ql–þʽorÚÔåÝØò/^'’8G‰¦7í>‹Ð!§ZqîÓÑñÛQ/ÙE]VcøþY7å½,îÎÇaý.¾>ƒà{¦"œE˜t?¡­Ó‡Þ•Ö@¶<Âù:Žz‹Û¥¾]EäKSGäA±´£Ì·Ò òÂåcÆ,5ÞU__74l$·_½(S=(r¦m;(ƒy¹h÷ð€¶)N¯+çWÑÊ®ôäýß¶\5ûã1w'9î¹Å“±åÏ÷/s*#ÚûŽÇ÷oÚ³îd ü$«½Y#÷†C?Žß|þtä+×¥XP—D“á©ÏçÙ”Mî'éúðÌs=‘¬+žLƒk$¯uY˜ù94Ï€3wbàU¾Ù¨i«µ¸%üRR5‚àáBÐÑÀ1ŸÃ=Ùÿ “ ²µf¦6&›> 쯽öi¾/6qÅY½ƒ_áÚöãw]\§‘´çxQ¹г8‚>a;½ò†4 Ü›;aŒè®Ì¡¶¶­kYAt×KÖ#›=,{v®{FØv’‹×¨\;`b©’Ò5R)º_º?[ ­ÇÉW}W1¹Õ=ŒÜzñnÐñkì^“l3êÜ¢odéÎ{Xc˜ö§_`ï$7Ñbª–"Ûq—–X‰–цuÂëDTNnNv¯| [\Tùl”¶L›÷Z¡D#¾íºc6Á(ÉjÆlƒçõ£à3ŸI¦Þô~ôSååØr3&ö3þÍ,«ÏÁ~DĦ_Ñ:ÛIK±S›ði‹?Ï–‰¥”iÓT^A°àdТkQcÓÔá œ\__¦×g·9ù.·Åš†aJ¡ªJ*hÏüÈú6©-AMë=pöÍéÁCñò”}ªmAúÓ¹ôff uÂWþ"-N~ά ŒZ8&êWÑ–É„ihøXH5žt úF íXÛ/»ÏžM¸Œ ª]tË2ûíT{,<»à19w¾ùÄ0÷ ZöY,æ.'âGq¥1ÿƒ96ô’ãÆ#˜Ùf£F––€éº$ù‚»U‰vï¹"6„â_ÖVÔ'¬¦2ÛµŸ…MH†ž.?øј\5_~’-ÿ,]Zý jv<û¼·¯ßpç;g«E{Pgç2×õ .éKrN† s†R›ð®ªŠ\tšçÝØ¶8ËKU™â\G§#B„&Õ¬yÓkÓéæ?½úó=Þ`r.!/¾|œëU°¶{3ËyŸYÿú±K2?NÃr5‰~:ŒùFþl$(—Þ¯+Ü@Õ–^[ëÒ/Åœ)Íök¡»èü¢Õ¤`\«›ªŸc2m¯°1YSßCá1jW³‹ùD_;o¯ÚÆá&¬ÔÜ÷¨gzÎ% žÖ²ŸÝç~¯Ãîl“0Jždgâz8ïaFàY9ç6`ÿg°€‘±¹GïlÖ¾‡]9ûéÔêí>dÚÏq•+ª]½Ü#baêMþrCWb[äm}@ RX’GË¢zÝǦ‹Þr¿%©è›»\seÁ·ËG›\‘`3œky{SÃ)LLÝ»/“ƒsÀ'ýæI«G{6ÙuŸ‡ È$•Ñ‹VûT§ðô£u^[qtóþH¿ã׉Ç"SÐ0.Ê6Š×k5üj>X}àÈ*±N«H‹ÌÃ6,"ÒòÒ¥Ð]_uh™è𝰯Éaôc·Íw“IÕ—-Û³ÂÙ+”£S>¶õEE]ãò¦Î‡µ@éb–ùaàzlHó‡À7Ýc‡ã[˜é»Â||Ú÷{Vœ0·“t¶|$ñB¨5Èç'>]@Z•ìBÛâK:—¬jÿîG¥ŽÛ”ÝŒgž³Õó‡Q˜•÷©Öˆ¸…»Ú¤%5¨v«'‚z¯ÆÞÇñÜ›‘ƒŒ†Mᘽæå#†ºjZϤ—ûtVÞ·ûF‘;˜ó" .]ÂW’(á^W½vóYèÁ?”·|°Q7õ“òñ‘P08y‘=¢QÙÈWR)B*fùÞúP&øP˜tŒI°"ê_); Ëqõ°ƒîŒãÝÞPgÜᯅÊOöpqà©Iï*ëËms3ךK†ä$]59(¿$‹X’ÍÙeïG†yX§gø23ä+pªÔQÎf¡ˆ±o5!cZãdõÒ§TC€É~{Z¨¸c8YåƒN»zpìaîÉ2QH?ÿYÎ¹á ¹Â.2Nµš©×Hà ÇWXiBŒa„÷Úǰ͓â‚Y.jZ‹ ´fMøâwX5šN$&•:Ëlz4º—ȇó1 ÚÈeӑж»YOOݺ€U^ñsÊY>#ëy¹ÃÑc`¯„•é‘H¸#yÜWµÃ z¼Ê“"‘Û÷ÒX¶HÆ»3ã2±ÿ4 `š3€ úØ]/)mæÒÄÀo•ä4Ç24÷ø‚.\/æ±>”[f–1’Ù’A´ÍÀv®/üÂ|”`;mS½€¬`.¥(ºp~u8ØÕv“§¾éZ®9dùB.8ßðéÅãð¢yÓžôÞPø"æmê/uä0òÕßrRveeÕç‘`ɲ>Ÿqy½â³n"…u®)û…¯¹¹ÕD$‚KÓ£†×?Ðòɇ¶Ü§”d›GšÇÞœc‰DMšâ$¥ñMwIK3%>‰‰¥þ&…oÞ»€Ö ‰-<·Êì^¢¸€›ê…NUnöTÁ-ì=Óªöüá¦Nü2ÙŸ¿û>˜’ô‡¨ˆ¤"øî_" öÖ´™PUyVÚÙ¢`nÝ¿Éôæý F*–Ú{Ž­­¶n§xóäÆ>Y=xBÜeî—l·.‹öèÛŸ„îùj}Yzeå©|üè¿çx´è&´!Ô'àñ”ÅpÛš®)2<„ÇßláˆNþh$‹þÊDep{¸[ãQ,(üêr\þªætÆÔ*ŸÚž«Ÿ$^9lcžyRý£‡jVy¶iuVbÀPÚ/_rc.–žBJÇÜbÊç åV¥'ä(þü”>8‰ Ž=„iL;ѪI©¯¯"#ý:ã0/´±¬,8¢ÔœÒçù_¦su6=ÜÈ4Oäý–¡I×&ç(dì$æ²ÇßCºmŸÅé·Î~ «p?U.Õ.v†á—G‹uÉ]…—æ®|¹zãþ-¶VõŽk3a>òšÓÕk6ýì+MòÝ(†Žœê ¬ÆñjŸN‘²ÅÙ* QaÑA¥§m¾kôû‹UÆ•A ö†½ßÏO& ¶î}JT­äxð£á|J:¨Æ™¨ŽÀý° ’·<'€ÃëÕÒÅš ¼R’ŠL«y¹(ð]bþ1£ìš¡STI¤àúz»*úû6 ×Rà ó#!Oæ*A/y49ë«É'„;gø)ÎËbûHóƒüà³Õ2QFîóOç34ƒtq¹^â#Þ[§(²¬:MÕ4>´7<“é«£=Ïí=á³ØõB–3íÔ•K}5š>FojÁÛ¼3©•W­~uõ=»Z'%Ô¢§‰Lc¸W¤&úk‹ÔO­sCWžtÁ£O¾; bÕN#í`¼•‡‹†/Þï¶8ù¶¢9Uã$Dkæ~"$ÌwÜ(3çGލX[bàѶ &‘ ÄUºÕNœBd‘öúMš³¬ôMšƒµÌcÑ֠ܳ¡I©Ý]_Ëè‡%~¯Í‡w"'È<Ù´'d­oª×«ñ(Û†Juš­`Û¼ª¢Ãúäñ±…4¸+Ò0 s|žÅ|b´fY&‰iw–~›'MΑ$¾W–‚ñœ 솳òczV·Næöúv›Œ¢rñÔö,ÞÅÈÄ;—FzÑv $þ<©w/¥B CJ«– ÝL䵄é¿"ø•Úgbî'ñ¬ÂšÁ«‚Oú¢v#Íóœâ3?yÏR.ÓÓ—kÒèÙ£ÏÆli²ð{û—µmY¬³£ân$— ½)q…D%_®õW t?xû·„ul¸¨žÍ7QjÕÇtç™INs!ø²#µ.'Œj‡å—DœÅ ™FO‰L¬¶ë¸LO=7í’Û·ÂÔ¢öálÇ®Rð1 ˜ÿëÙ‚9Iû¡;„%ñrvÄ“ª˜w°2c(Zïý¯eUIæùÆK?‡ð¥üê…[A[Õ1 ÔÍa²:,„º<[«£Të°û Â>ä¯î+µ4ƒ6zx[¯Tù.\cºØc“Ë\HÆ|”X[p릈ñºúIñ|°Ðn1ëdK‰+”¿ë#‡a¡;Fh˜ßZvV_µ¢QwŸg‹r±é„"-ËLeéo´žôéRx?åpU–”fø?ŽË½v±ÕëA14gœÙwÍ÷g÷!ÏC¾#·Z]úEèÃ<ËC;DdþªÓ¸o lé¥Â +ämKfØsÔ,F1¨ €±­ý†¼#<]¥6P€q˾\¸WB[L:õŸ;L'ßkÊJÜÒHŽö°ð›Q:¾O@Q²Ü0ÎîÁòµt¡& ëã¹S“$zêUbˆ0’¢ö,d„LîIñÔâØ“•Shú&Oµ_S‘ò€så"ˆ £${Ü ™Tꨅ¶¼&WÈõêÔºÞYÒÃRUÏý„AÞ¯'¦®´kØv)´[EÄdpèR?„HE¡:‰ÇÜðóâÈc¡°Áã}œm9…3mÒlPIûÀä³ ;ÂÛµ¨ÜÜÿ² ª¢×F¹K.‹9 õônôeµ{E¢<ª¹²°§ßDÂt.‚v¢ö¹å¯(2Q7áèQÓRDw/´×¸ƒ.á„Ó6›=Œ¶…’9õ”&f†1쟻Jà}CrhŠg˯ålƳœàïÏ‘âõ2ƒi_€cÎÓP^Q¥™°Uê¸!=¿2B˜‡? ×E'˜´«rÛ¢Ò_ä™ÓîÿlÏ:G5þº ž9sZƒà¢±\åöñ{W›Ñ›wé®]ßqªEPçØ « ¿\¥Q“óm¦FÙâu /nhÏ)óÉ&M…g,¯q…bŸìzb2›ÒD⛇(mo©lŒ ÒV`2š)&­§µ“êïÒªÂZ¬lø™™iP.1 «ŽËJ/3ƒh¾ì²Ñаin¿ '_·Áè™U/èÛ­¢Ÿ;è<)ŠÁsQQ\L ƒÉÐÔ0jêo3/žÏ¼%ô觇 “iÐ6‡Ìýñ“ææÆb§I¢¼IÆì¼î´Ã@Eµ¥ÙVÈA¼ßí¯«ìýÕ S"‘Ï}Èâð"\Þ ¶1Vÿª2}ñízšs.i®XdLÖu^&UÝ‘^°›¢Ò^\ÕÇPó;Â&ÞÊò)'YmM}‘-Sõ×øTzv é’gP}áÀΪ%LGÈ®t¹à$ÎTóSSió™`o©Z|“Eä-¶°ÎÖ §|CÂVYz²á¬E$nÅŒJka¤šlûKŒFY ‚z çA|úrâ IƒÐÈ‚œ€ p¥ýé ?< œØn¾@~ºëqѾ¢Ž?=žZއöb´éªáô¶'Sa¶¨ÕújwVŠ™mz%êCškìÜÀž‰¶}Ù>r ÑáÉp½w÷ùÁ¡9‚šäÇ›Dà›ã ‚›¥DA¡ñÌá>á@œ_ö¥°Ôºð‘÷ Å×·Ýåû¿6[ýZtì™§«æ: ו4vÃòJ]Ì€gB8/_:9)ÏEޱ2æLU¶J– ¢?Mî¢Ö™{=™KP*}tŽÍhi%ãr¥Z}ãtÎ?Ò™Ñ Â{3,£§›Vë­µÎZ-(·SÞaF¥SŸ7¯±-µñmÝÑÙݯ}w5:+h¦±eðÓ±L•"U¨¾d“–ËCELT©á€géý"g̵X=ìùC™ ïeÊN OºslñJëþÙ<‹Z´^B„f ÇŠ/è—jL’§“gˆ‚k¾æZf•åI¢©ÒÁó øÇ,Â/+òö0#ŠéDUÝÑËxÿëkådϜϻFÄïPúQyV_bܬÿ@Q•çÔˆ}•'mø3ì›+ßûÀ¸]œÀ<ËHØQ vräH`WÁl«y‚L²7ºíãõrC cÊS—x4ÓÓ¨ˆd?!n uwIèå“]‡;‘q«¾Ë—huh™·u~€ñªüYøë\lK¸S>R¸ÂÍ߈ ºª$rÞÝR^ʈ ú³5•½Ða^k„õU)YòîmꎑXÁÖŒ´mRþ`£Îh‰³ó OlF3¯U‹Oœ\Yit¸"/ ‡5ôù¶-‘TÉ oª“a&—"š\âÿ3>Jê#¹6¾ (è†t¬ü9ghúa`v7AMèë«íM}…«KG©©sr¢-ïÁ¯­Ï}ª{x¨ÑiúVÃnq&Q<8¤Z†?ý_8ŒX(ëä*%û"}ù°lBðU¼>PWþÇ%«tj寙™k¶­cöiL £ð'àÝAkItöÞs…ÒòX[½Ñ2ÊcxÄ­ùg¶_åL·ÈT”Ò¨Ýó%ý)TïHŒJÏõ‰Á¡+>ÁäÒ÷zâ… ÆÀ»lÄQ"ld­@¸Ë—dÙ÷‹/Fu,䟱)>±ùVÔ/˜Êù…¡K›ˆŒ<5üzóý.W!“µºéT-닟oåd¹Äs=³ÁžŠeÕ±ÌhËÉÑa"‹›ºÓ£1ƒ º*4B–=ü8œÑ˜]¬üb Y:$ˆüû 6|Ob͆5næKC–ÈVmbP€KâÂ+Îv„˺͎½ºàuò×ôâ̱=«?Šj,Œð‚îT ÍÛŽ:Ú–©Ê=‡\¬³øFû2jä•ý¥båÚ—ùµ«TP1Àø³‹é WòuEãýŸ‘dÒ觯Ò÷éÀÂãàŸGÓ9œ:[§¤¾áÈ¡@ d1ú¾|yϘ0W]´‘Û…~›fX£üë éè;§Æ{;dSPâg½öh2ùäg.xÁ‚rI ±[¯¾ï2]ÄpÅ×"‰3±…hÞ¶k+j]bË0´êôO³ºäˆ´gd‰a uÛOýLÂÖó6/ßRX»þȳΛšöSUøöìÝÛç½Ä¤^HÄ:±ïòß~íÕiM,óébë"3¢ˆ/©©¶á‚Þ´úÔèýŒôõvaÙF²Þëö‚|«ªÁëÎΛuyöî¥å™¤…¼rM¨Xã”s3Žó˜yàõޝè†ÛNÅOjäß»Ñê vHSw‚ö.–8æ›ùBuîÕ.XÁWGó?t#´‘Ú×O¼Ý(ߨÀŠ=öJ¦M·\ÅÕ«kÊõ¹^¿ð²ê‚”·ª«hv£´¡ ·”›rí÷¢…eþ¶$|»V'ÓüoþJ¯[!¾Am Eœf5sˆÌ¾í:‘,^!ïMBlRSŠï±D ÆÎy爬ŠÓv”}ÚÁ} 5a´_§ÑÙKt¶µ¢n‹Câjä €¢kKŸ B¼öm§ÞOF[»èNn}¶ç‰¾Të:î9ƒc)/Lâ|¸²×ó0ÇŒøÒ~–ˆáˆÙÆòwØ!¸pZ•H¥< iÚfµg•Zú×1j‚O#¦°ÂÙ‡³IVpPãLD„m¾Ü)Æî¯Û—áÕ…ûÓŠý˜ŽÅŒ$Ò.~ƒÿ–ê­ ÁsÕøÒñI&Ø#I³(P$ ûJƒòÞšO¨õè׸ ªH>àµCbˆlYö¯Ün@@#ž¼öâ¾S\ƒˆäùy\ˆpÜrûAÌ ™ñ–táTé9Ú™T{¡b;ãÃ@!Ò{7ð™1õ…àN/Ñu;iG›Ë b'ýœQ빺·ýVÙ¼fBï û±¸|éIÅìâ,|¾ÓKc™Þ%<ÅENæoÓWãgz먄 ~­#VZQn¡2cÌ!§8hØáEu@£r#X…Šxà ·ù(WYq†uIIR`]<Òr´XÚON]àfÊÀñð”šSc˜/Ø…vù;ßÛâj|2…‰Ÿs‹txýΤT>ûi[ôǺf[Û\Ë ¬ÂU;‡‰ëU¥ŠãI‚6¿‘ÁΑ;öuÿ,ÍÒ˜ó`.Í׈ðûÊùs'IF™_¯Þy~æ~‹ù/cœ &¤±6¥V³eºõ”ФÂ1e §FU'Õ±u9¥N´H®^Ô^FÏá¬>¹Kã(ß51ÝTœ:×ö±úጹUÄþ2ĉjøµ-ÐÈÔ›UÒPùŒX–ý%Ê–}»zßžÕÛrYmHÍ®©ð;I)¸öׯZ¤*v¢R§ß+^…41’?z1ÇÊ\pÏë_•‚˜ñ¸GàèÂÂX„²ƒ6+Ë®ø¹…_iØ!òpüŒ´ 9¬*=Z8ªgæ»Ì‹Î0áU+ŸÛ1Þ³À~E @MeéŒùŠHvm·\åŸÙŠß²~ã$qòE9ðKôÛŽ^”8ú1BŒ}ÜFtسÁ<’¹_dž $ép#¦ ›\UŒÖhÕxÈ£ªlÛÜêçÔHOj9—Ê/wë©Ødiã3eÂQ;7ìÌ®<¤Ü ‚ñÝ­ôw´¶›ÓSôuÌc!C"tÌ„b¬2G«Â_Ç*oÆ7+f¼î૲×lJ,ðê.vr¥@˜¨sØEăÓ[}ã/åØu(äxž±EªV·)¨P„å^x£Cιr¡ KZ-z’6Š¥ØÎ!æq—LºÞ @Ӧͬ‰©ÒI[‘Ä›okëjjHvbónφö;.¤“¿”""þb=â«h#B‚•ª"è#;dNzã~¡5\È[e»™4‚_¢šNà«)$ëõÇY¯S‚h#í€N‘àËúvœ¹CäD1ç°ò(:ÒH‹yyÛùÌtÔ·F•Œ^–hæô„b{‚ÌëG>=ü›”êïÍ>yðg.ç\E_Æ×m’õý¢Ðî öÕLt¨åø1p1ÄÙ:kÆ>8iMø*žÄª\Æn&™n4?»ÚÄ ó„P%»ü½°EDIH0 yãY‘hŸï?ì™ëwRw‰q?ã ò}þ2¨f M¨qLTlÍžˆcòa%¨÷}:Ûò3¥†¶Žéôë: ?Ž˜Tç˜ÒZ·pRÉolÆfõGM+pÖ=¾Åó>?ŸÌ:;Ð:\[êÈo%×7P bÀ[¢‹9é=×ýÒŒj—€W6W¢gÉôÂëüoha#ÕOÆ]•„ÆJüeêH}²£ë]¹  Ug^?ñT ïìú!îõ/ ™ñ¶mæ÷®z›¶ïãµ$=« ò½%õfiÚ|°ïÅlË^U•Óq•kÇáü…š2U¦J®/t(Rƒ4îwôè7•µŽHxIÝßYÏ'„W0·|—64)ôÂi‘cQ;Y^•.ïÒh2 ‹}¬“;M¢q Êÿ [Ž`þ¶{‘q—B“ôݸ©7ÄÊB†@½ýßá!úü«Z¤hÏ£ÀóŒÝE¤›JaŠ£9ûµ ©9&vÑõ FãŸfiä¿…)ÉAßOËðëâ :óöw³üXDž’=è3C¾ ÇàûˆqŠ„òËSYƒw?Œ:ôDÝŠçš(,†ÑE”Ö*ß°I$Ø™XÐ fp7_íäûs«Ï{€÷ëÒc|·ù±êùÀ_&‘#µýõˆ­ªÓ«Î# g4]ÞÎwDÍØõÁ³h‡ôÛE7Gï@Ä3þ윿˜Í‡ÝܰlêšÖ§ ßV˜²>gJã'U 0ÆãWõw¡ÞΣ" LnIó²ÊŒA¢Î ìázkñˆ@Ø,kH1ã`éÇq1ÆÛF[¥0ºC6«de™ïD1‘£¤^×m~-f"NÁëÕUOÉ«¢šƒ§+-œµÚÓ«_›lÚUÕÝ«¾Í‡9쥇•ÞåÇ?ÉgKzÞB¯RæÎ»PC‚oÍBg“UÚ¨§âþ¢ú[‰ZÈ[A_JüÀœêþõ£æQá¾µñÚÛ_ºâÌÞ D|Ñü~J‘eFG½V¶j‰šyDÃÂß{X¼2G­~àœ' .³Ñáóìëò ¸Ó‡ÊÞ9î´¸CÔ¼-Ú+;†s°?hI’ ãn~’#IS`"ßz釩øé¶?FV»¿°h[ÀåÕ¿ú5Lµ†–šúýP¶@BB¢;/áwä~²VË zŸývl“:Ø¿ú^?ŠÜ/ÄzûÍéǯì|•M¬P|_’Þ*§ùš¢ ÑŒË=Iµ¥sÚħCI£ ­'*»3yB›‚^Œö\2¯ÙYÕ[âþðPøûèa´!îðb2IMF0 ¤ ®žD¬‘š°!·"7± ²ÜöJd;—SÝÞõ2C\BRs&w%}".Aì‹ FeI%W Ï7e½.¡ÌæªõV#„|÷Á7Ù 3&^ý„ÅsSzáZ±w†TZn5vŠqÔ ˜Øé¯G± ª!~.ì—ì&’‡–s¼ß`'"`“&¿§÷ïå:üÐXÂÚëæ¹tÔ¹¥™Ä óÌÛG|ë!“P)ïÅúáÔÌŽ†Iý(JD2ÎD×â*)°Iè ^ø”u6Òó&¹˜ÖöÿUå” endstream endobj 2697 0 obj << /Length1 1778 /Length2 7278 /Length3 0 /Length 8298 /Filter /FlateDecode >> stream xÚ}uu\zû6 ‚4RRÂ(éÝÝ”H6 1¤»;D@¤¤¤[J¤¤C:”nßyÎs<ÏïóyÿÚ®;¯ëþÞ»ÇD§­Ë)†ZB¡ŽN (tC |\<ØLLrpa u”! ¢ /7Ÿ›—‡‡B ‘(ò‹¶2Ì@ÃÅdý'‚‡—À+$ÄÏÍËÛZ!–k[Glî?õU_@@Á¿í`Ø?¾W¸3² €Ù”€l †:Ú»ÀÈ<{{MÀò¯ÿã9ØÚ»ÿ !¶Ö6‹lëâð¿^ÈÞÖJÆÑÚàáâæùÛaë¬hëkÛ"¬l¸ äo³¾#··u„hCmÿ À Dá¿}z6¶V/!ÎÎÿ¸4¡[+$CƒÿEêä(i«ÿ/ˆr‚ÿÔ9[Aá0ò·÷?ˆ#ø‡œñ_£àÖÕ70Ò2bÿk"œºö G„9PPèï(G+(ØÖÑÀ+ Áá wl‰ž@€-R…↔ÍÍåE S0„7àŽýçÍÜ2L#A·ì-pËÝ"a·ü-p+ü‹„xÜÊ·ˆÀ­r‹Ôn²¦Æ-BÖÔ¼EÈšZÿ"a·ö-âpëÝ"dMý[„Ì3ú‰ óžß"d?Ð-kdä®ÿëD¶·¼EH– «—Îö g›­@^¤K8È by¸cøþ×Fþ[ÉÅê_$€l`µGîÈ?~þ?‡[N6Žü/äC>jo‚߉¸!·"þ 'ým’"òíAwrj^ÜAF¼°}u[Dàêr· 2ÄúD½?R­;Ìâx'i³½‘Äíî@äà_ÞÈIØßÈ1Ý! DŽà¶²2Õù˻Շìäèâ`ùç÷f}‡9 è-GdMè, ©vëFòƒ!_ ¾ÔìtÛ)ÙÉŠ€€-ïP"­wÆDrq¾¥Št:ÛºÝ6ARÿŸýA^HîÛý@RFØÀ!w^©á ½“€¬ár»PÈ~.n‘³~Wr ¯î@¤x×;Û‰,êv"»ºßÈÁxüÿûâhƒlzî0€çöý…c]úbh FØÜ Ñ!à¶nÆ<\<ÈMåüùäùs þ5Lÿïi“•…ºyr O®0(€ æåõþ¯8+8y#ÿúƒAÞÇð [ä}‡@Ü VØSP+± »Š ¦³r*WΕo K-áqF_ÂO&³§-:#.ÏëI,¦P!eD(®ÊäÜý`ü™C›ƽÓÞ…¸Y‚³ãÊ#¼>+§Nq:ZwEÍ—z|ø9£tôôI˜ÑÀ¾ìÃôê/yâ0yZ÷ÌÀ‡0*f.Ï9eÿ/ λ©VËIiÇã¦üÕ>Ë_ †”èß*r;í)Âv?œ”j"t†[ý!%Mgè0ž£TÝ£G<ö°ðOž&ô…]všKK»‚$굦u=Å62^Šù8‚¬4µD -°’¯³mBQN(s A>áÑop¼KæÎbX&£éN–±`Ålk¸6]‰…æö§;úÔΡ®MRdÅvh¬¥–øç­õã£;ÂV?SÚB{­æ5ú¯8˜Ûäøyš+Ȫ¾= ‘”×3¦gºçä匽±¡™O† è°žlo¥Hmoù¦ÀÓq'Û#ŸñQ¸½zý…´«V{–£Ì¶µñR4Á­muGÐ¥x K:<¯#Àž–#$¤³ÆP¡vFl>u‡2¶“Ë¿êO°ËN2YÝ"Þì ð¥ÚlAI'“<„5Þïç(³ôÕ-µ<¹Tôzp³±i,Ib,Y)!xåŽþ lS®ÃXk;,©2~†*$4‰ëÔ¡v…ÎÞBÔ÷‰°èeU"¦k v¯Tº‡´Çï:¡›ÞŠG»ã%å3‹êßТf?ð “=|œ×ý=µö`VÒã^ŠeY1ޏ5ç¯ø#µ€Æ£_tñEù•æmb«­Üï¬ð$–å<„‰ Eû1m?7#±£+Ú32ú¸©ÿžàáK?È|¨ ¦mÌåa‰ŠÚ 15Rø³öÞQ[ÿµ~{ߨQ|xÒ÷ØAgI¼j¾¢×%MQå1ÁèîÉ‚¼oq¸ýêÞû'‹Žò>':‰Ý=8™ çe2Ü×o,úAç^äïø•I;]i²‡tž´¸³Ù'`.\×εlz0lÎ ‚˜µW“Åé>@íüüi±F.‚Kêgì䞈xo €_E1=ä\*Ž™€aNL\À„ Ss¥ÓÂßsù€ùçØzôË*®éÞáðí³*%Ýh[j‘Š_{w…¬ òÆ}ûYÍW#êåìóøµƒ!„‘C&³¬˜5õêÉOd{Û€ã”óheÆØ½E]N[÷&M·Lˆ‡QË’$ßLøŒÓC{â7–NBeä9R`S÷1‰²·ÄXÄY4yÉ8>iìت¥#à­pwP䬸BBórl§˜Jnk—0‘_qêóÑ$®Â³Ðáºprë9Û+.±=-hà™Ù5F¶¿56áí~ªeJ’ýÁSËvþUÀ‡‚×»‚gjäDUDãõõð­¦!ì~ßãWà:ç r˜ÚöC©çßi7]£–?Ä}~ó Ÿó‹1 Šb7'ÑRJXÚýò¦L´7¤ßíF'Ø-˜D¦…5ðWàIèƒß‰­>²CºâñùpÙM_ƒ®„²ëyÞ;m'Ð06jùÜÒÌ¥*ªº@›»ã SÌàù$!üPç&ô‰õÐ25jƒA ƒ³o˜ð‰wëä‡~ÜYYy4¶Ážpä–q=-–ʶ_¾ÉœzòI¶ý½»Zæ§d­ÍˆÜÅÃçim ÒN ¶÷ÞœÕ$À¹Pþ.QqJ«ÏAЯŸÑßo—— ûSñäXZõ 5ñ)®6îóF¶>¨Û’èÎàÕxäw©9eU¯¸ËÁdÒ<Äò4´_ë;Øáó¨ ]´ˆæM¬Ejw\zçã‹™ñµ{ðyGoŽ¥Ô–P¾}vð4 @UÒxpà#ëÞóD3«{Ÿ¦]…¤§ñ}އáTÅšWâÛÐHZ–®Cco…”!ƒíæ×óÃP\±Íuuto+½ß@†#jÌ%úk÷/¼™¤vp Èü{ݧAÓ„‘"j/"º·Ð×fžú›Z¸y)žM¤F–KSÿ £:å+¥×¦/§š±J¾‰ù5C“^‡õñx³×Y§1Z4vê§ð‡³ÑÛEô×B® ëTªoÇr#,ÖÁXQÏäÀ¾áÁ7l›ä…iS3fª¼61mÁ©:“MW£ëƒÖgKA/½š·k¾XÓ¹Ú N­¿6̤^5~-Ô#;KP:ÓÚOÜ,‰Ž—º¢^…ég¥â ›',¡|³¸önÑKNHJ1VÑ-`Rfºt­Lª]ÕÜœn‡ùOε—Yžîù})ïcÐk¾z^ØšYßnhÖ1Z=bf,óêãOפ™ô° ~R‹µó ~ÁšÖ#¡Ïéêµ§•üøÉ? iËk)ÅPYZš)¢§¾}ß/–Þ¸’ÙIµ0œIVÏ%Õ=ú¤tìÝ e޳ |çÔÄÆ^ªó#çwÑ÷Ù”è\åzRïÓëYu¶e|wwÄ1 º4`»|‚?/ùJ6+1Ìp*…±1eŠWe i¹ëÔÍ]O\§Càå^.öÆ™D)iäè=ëñò„ÎûÒ~Ìè5fæ#(AØ:D²-ddDYT5^Œ\Pı¤F™9êQ®½O= ²±•ð:÷KhÓj‘öqÚº‘=0dm± áÀFu}¦;ÛŽÓuÔçÊ+e¨GÆÎ¿`}蔵Où³¢6æ¡úUzÿW­Wmj;Â_¾Fb-ÿÖˆÀ”JÕq€ó/©š=±?ͼçßYúå`71Ìœb+c dvªÁ K_¼|÷4;b|?¼ d¼Bµ.!mbÝŽd‹Ñ©X¥u¶&¼êáü †,»`yú7Ã73+áç>å6´-FY™òSËD‚#(—ÜÑZæ4’!]«O¾æ»3¢OX¢™*ûè¥g.^¤¼–TÔÇx(•OC«D¢7´j2ÛT‡f‹5§€=ïö¢1u¢ +úÃo}ílA™ùªO£^ †Wq^³“ªrÁ%lÁPŒið˜ï>¦·±ª/‰äs3ʧq¶Îêœj¢©ƒ/°¼Ä±_y@ÅöŠÅ‚3?Ú’Y.¯ à7*׆ؚ¿Êß¾¿·2/¶ôȾÓ“Í’([QëyPÜ}‡fº‡ØÁÕ´1A:~œÊ~š=£ Í##º(&ºZ«Ë­Ç¹?YF¾ˆv’‰x<-õêR`›/•<õh;(ûì¼$ (NüÉ{&%ªs²M•e°N®qÒú²ð€·@µ`0Úœ£²ª¾¥ä*EÂ]Å<ºâtÚÖa¸’_<|1¾u“ýͼÝ0'àšèd+¿¯ÜÝÞ$L£ ÕÀE'HÆØSŽåö^?9 @eò&0Ý]ÑR'¤:ȶç¤ÖJÞì•ôÉ=ÞIÐ Ãf|:ùÃtdLÿžz°1wP;¿]!Ý j-З{T¯´¡@ZêcSBô†YÌýFKÄå[®ŒJVhÆ]>A3QÊ##×dOø¹»z®\cÄë^Þ úÏ™Íþ‘QÖ¤wt’O÷:é ÇŠíhëZ(©†6Äç<‹ØîÙ« [ì?Ûpš(q$ºyx®cóšÈû†10­¦üò ¸µµ©Ó äœ;’ôëR\ž›“´àï•i_ƒý‹E×:{WO¹&>”/PL—´>PÖly{Ñ×`+ÚŒ|#I¼9 «â«•V›MÓ÷‹?y7 „+·ß5”{LR.§5®Kã‰x~Ç=h–G‹×¢˜w†í._¨hüå‰ܼÅ2aÂôï­1çÅ CC¿Â.0¯7~о_Lü]|E‰€˜Jò vrp„(ÁW åCï8›–p:àœ¾vÿxoÙ£G™hé(¸SôËÙ½2I§‰«Q½ÓF°Ú%©cB’›µrQË­mŠÃ,ž¡ÆØ Ž/~H&€[pvÿKíaoè"ý¡O/اgC4¬ýÚ\“ÊåÁÃî!mOþÅ`ÖâtÉ/ùdUÓ&G>[¤áܽÇÂR ^æ1ìÕ¹&ÌG¥`ªõ´;Ó~ïTÜÉ^R4ïæ½„€¨J?ÛÕ”xBA\!;gÙ¨¡]sùéí×pS<Ôv£†Î^ª±—•o €Œß#ÉÍðÐWZ½5Ú*SšRQm$¾—ZGq]›Àê!³­`اe°cž„3é¿Aî|~ËPX÷} ÿ˜÷ª^”Ê\=§{Î}]ƒuw©¢·:~„ô¢ÖOó>£RTðû 9~IƒQBŸ’bTWªø/uò'¦ØìŒÜt—òçjâB)z2^‰±K† @âùKa‰ì×8 ¸<†hˆvýþŸäy”J·¾°ò³,‡QÚ6'MmLõMG/¢‰Üû¯IMɌή˜â’©±öñœ bè#àLXrQXš½y°ÙÉHV ?4·ù—*ºÉr§C¼Ï|Mü D˜ñì,é·ž¢Ï¿Ä›¼§WEÆÞmcÿmô=–PK%¾PyV`qâs¿ðÕ•Ùçç ïÜf5¸Ìíº¶ª”¶ÜjZèŸ5¨8n ô¥Ix¦u3íã|ìõ4µ c ­òvñ5 æ°Èè†tRH`ZH·¨Gÿžö”ÿBxø™alµ©uH5ã\ßô!#„}4œ’¸ã'†*=#õW £qBÑœ0éƒVwñëÃÇ]RïÔòŠY´I3k´ ¦úªW~0ñÕâьŠók¼PkÌ1Ú|Ü †T¨ÔÒþ2$ÇÖçjÏkâ§øUèÓîöýôõˆUƒdPå}/¿½OŠa6{yõÎ\ü/­Cösü˜‚Üyµ/³íÊ)H´yÕvSv0±©¶H7§ 4í¡(.úfEµZ/èp‹•Ý›# ¢{*âW}¶>Ù4úÙƒ·wQ7®o3ESØ@ýyüï´ÑÃP^–ë=ö< ò\šoÓðÞ§zä¼ÐáÇåâÓ2=-NÛ"iËJ–[‡¤jh.÷;œ®éŸá>ÂÈÇ”^yºÆáÞÔàÜ|LönâÞ*i«qe·CHe(N/Ï"®L½ ð‡ëYl»kD; zŒž£{”„ÜKmÞ¨Z>, zŠ¹Ô§-:Å`*ážt9ü„wÀü>Úï)#³LeY4°“h¥G SOÑsÇëGÄBÅfa˜×Â*é–¤Þ\jò#zžû¦[T&™Ïô<%ÊÑQ(Ôª ¿1üòð›!QÑ!‘Äÿ@?AÝO_h²HêPµCS)Î1]ìrÁ²¨9ÙÆx€YÎÚ6oåé6níN›RôZ™Ì??}'=”Lœïj«·ÅArg¸˜ž@«¯¼ÂKSQ §ìUKk_þ[þΓ>|‚²ÀQ¬²£B»Ê<ôä¯RS,;ßåhÐ~óâþ à˜ìäqð]€]Qº¨º¦þô‹dOüÈ·Ró’HKáUÔ)ñ÷wÔnó 4–Ò©‹ÆìÒ¾®ékIù¯8]Éå RÐIµ|7Ù Ià Oñwvïñ$Îôß»ÂF˺<ÅÔôó ±¹¦4ÄsÀïE+ºpz°‚ðÞhPýˆáìbà «õ”” ²7sùzöhå±ìT¾+Ϩ%²n-¯óÉ/ ÔŽŠ’aøžŽähUÍqôx`U3þØböu]ÙÙDì®÷%ÛîzÊ!ÓT£"SˆãW7 (®ú‰~"˜Â¹ö >Ù >õ²³ÊÖú¯“7È¡KLXîv+Þ1©J!ÝÐO’„°A&ÊŽ½7í\Mp¡ÕnObL¬¬>)PÀeç[µßùz˜ÅÏ,œTæ¦tûÝYÏJÎíÑNŤvT2£evfÙæ÷ƒ ¤”_Ƨ5öà«Í2;b)zr¶:ÿîX‘¥Ru8¾6ãL¦Ô½Û¢  «EcÅ 4É }ÜJÓ@ù‹+ò4{µ¨u%„õ©¯áó.ª\4ÂCë1> ¯ÞØ :ApÎQ+nåªN™Ëºé} }ëÑ(‹›Å½™:Ky<ÁAb+×Ä"³ÎªÕ *Þ8‹ÃO]NŠÁlA¾KG(Þ¥/ê¥ÇðÄgTÒæ£úA‡ÔTÊ÷fa“4ưf&`<>ý¡ÙØ@Y’~\LL¶Ö$“Å3aùÒ@½|êÙb¨¯¹*xA qä褫æMÏæö}p¦À¡ÌŸ Õö›*ýÀLW¢¬Àz­&¹ãÚ+‹9¼·{7ÎØ)M¼¾Ì]=ݶ4üí*yDG_ÍjRa‹Gå úõ~FwsÊE2#§á˜,‚€òù)ãŒcŽ{´SEyǘ4ŽAO*¨ÍÍÚ…ý(zˆRýôbŒá£X¡Ý[ NóXÕÔ°)¸XŽX6Væ­Ua,9ßæ;!r“GÁ¸ ç“5DÈ"eŽ÷écAìfÁ³®Ã"Z±§£ÆËéÉCŽZ²Å3˜>NH W€N^ÕɇЍÚó¶ü.mè’W1Gà‚_˵a@šF'¢Óyú$èxÜ·_'Ñ¡Iâ5ƒUÀ× ¼BÑ–`ÔFâbhG3ù×>7„@ŽkÙ·9v¶$»ïÙ™>¯7ù•+%çä-ºë= Ã|â}~,ʦ×ohx}öä*"J%s›èÑÊñ~.NÆ)¹VY"÷ÙºUÖÇâx^ïmUšÞýëÉk±w– ŠICqÞŸÂÍdðI{ô–‡fý ߇7Vâ¬Å?fÀÎ8Z¾,å“DŸ¦ÒcÅ;Ó¼ö@L ËW®&EZ% VѤv›,Zûñ/DxT5ÀPtÉ'ØD—pgY´Ça¦¯ hz_´ÙêÝ=máXèëÌ„¥s9íDÞÅ4Àóƒô–HÝu%åò_¤‹ŒIlæ (‘5hÊ¡!J¶ŸÿÈÐ~éÕ´§ždØœ ù3n OÕî÷ Šþß-3^yTðažŒ7b ʹÿäÿù—™´t[‹§›Ønz¶›_i¨8{1¥A´“èj|óKÛ•)÷àµó8€Ê¯v(òLr#¬÷Z7s <—¼o,ØYó£\î*š îº;}5(â0=ªM㻘óþ2T¶â´â endstream endobj 2699 0 obj << /Length1 775 /Length2 772 /Length3 0 /Length 1317 /Filter /FlateDecode >> stream xÚ}RkPW#˜É¢UG‹â )V^É&˜ððÁÃ"FI%¼ ¥„äVÂ.Ùl0B‡6€ø,òP["­¥C©ÆAQ´A°X‹ (ht”R|´0h-XÑjÛMNÅ™Îþ¹çœïÞï|ç[¦$Ê7T§Àµ8FúrÙH å:’~l„á᱆€2űwd$ \‡»œÃCÈH Q‰ˆ*‹i52¥µá-#®FÏÚtÖëûZž¼É¾Ö‘.¢¹t/¹+äùó•ëÁzIÃ(àwUé‚V"gô½Ãµõ¦h8Jïç%=¤Ö¡‘&þ e÷UOZFx+ãW…|y&)«÷’å¼óú²r#‘ÿ¤PÃÙÀ<¥½ÍÉ[ͯr_WÞ&Øœµ=nn»àÛÂð-Á£wxW7Ò:úã ‹õ»“¸ŽÓ#7·t±nÑž7f=3×íjÝûœs4pžûinwQtȪ£Ãi ¦¥¯Èh¼yÖ~ÒTßã)r¸íÙ°×ÇZøq+¤84ò<³¥sèªF?žÔªvN^èökÇ­žÒokß'ŒÉ¦IŸºs=éZ§}-ÍÍ­ž™˜âÕhohZÝN«/ )­yÒx™ýypÁi—áüg'Ív.bÉNôÿ Œ¸·=î ’™É\ìXØG+Óþ¤ºç'Gqï—d‡MÒ…Ðñ1P]xÜpËXÐkØkš¹hf‰[‰·;½)bVYÈ_Cæ¤ruùÍ“#ãCN†@Õxi…ëì ?l¹[ááÂHÜëÜñg¥÷ì°|qpNnsè|Áâ¡¶éDßñ°Ë|•]x—óÖ™âÝ&3ý‘ñ péïcG=Y‡ùާ•û™}µKÞ Žm›¡¼VRmùœÍnY endstream endobj 2701 0 obj << /Length1 1644 /Length2 1359 /Length3 0 /Length 2148 /Filter /FlateDecode >> stream xÚ­Ty\×6((¸´¢€ËEÁLØЬ²E kØ ™! &3y™ $*‹PÙTAPQë²¹WA«´øŠ¨(+ €K—V}°“ðÔþèë?­ÍÜóÝóå;÷ésÎ0¬Ä1’Á2gÚ_T-%üq‘/Îæ0üPvk ##W ‘(޹A$bx Ü>°°,6›­a\q±\‚ bI`äÏ3¥ÓÍ>YW@´üBy¨ÆÔO<"ÄÅ"#)Š¿í€ €ŒE@ *D€ëjn¨—¯0ñð †H !àJ£…(pP>‚ˆ)ˆÁ%@8v|ƒQEi„9ÅåLb„RnˆŒˆ#JÔ?@ @Iõ€ÄŠñ…RX‘eÁ• ‰%8uCDa'H‚/AÅ$ ¢rÝVŽåIÆB¤"6R0Àc¨›0Η*JRb …’Š€Dd¤"V4`” !9›"KPeRÅŸ20DI`!B Å­èΧ:Áª‡Äb¡\é+o}Ì% Dc®Á² bòI*¶Å4–*fÅ ‹Á‹9f‡¥âX<"Q6ÈD13¦TŒcB9€‘¥¾8I…&OeóÏ'ògø³üYäýgâŽ×èøŸ¾çñÔ+¥B¡/$¢`lÇjÉ@ ö àÅ¢B’?ù@"T(ÿ+¯ñ·yÈXºAæEBT[œ1% ƒmneÇd(±•!0%ù± R}SÚƒ0‘Q ¡ôU¶0XLæ8,0å¯ÅBXA¯‚’LYÃRgNHЪUô?/YF€¶(–í˜ — 2P.FÀÿâñVáðǃ‚ÐÅ—õ –`Xر¨×H¥Æ¶°Jü?Á•D¬OçU)Ae œiÎd²(RÅ—©ˆýѾGãŽñqX1H$„ÁÔì}4(`¾T"¡$W®ªþgå+@Â׸׊ó¶Äå•sŠ~t ¿RϚذU|¤&°¬4¥¯KÎOÈ>¾føäVóÚö£çäwûÄ#¼—<þ¡^[¸¸.yq`^¢éåR­ã ¶ôÇ›–F™^ÐÏË\ÿòçÁ¤0fðã®ýü#«Í¿qÁR2åå[ÓƒøÒ”/ Å3’ø{ªsf«Y;afåÁ¾~ãÜŸß.¾Úø}õº_U/?Ò£ïÏQ7r€æ$íîÓßEÊ×HÞÔðGU‡âm‰w‹Îð*´rƒÖéýÖ*]h8ýp«à¹åÁ{gZÓ©5:Ç'áEZêÔl‹²Žf ¯»6zGV}ÛêÕßfóÓ³jGûüµ…mìltê“ÚŒV|ƒ2ëÎQ­`'Ï«w ÃRwÀžÁL;Í¿ÐàŒåͶVUº+ŒÜgd8U¦4ÛÕåt(+ò™¸`ÊòKÊó¿«Ú×Ïe4,G'2²XO¶½ù×2¦“Sh\ê’þÌÁÉCþG­²Wt/ÓUÉë¨Õv9ÖwâvÃ=ÕÉ+òOe_Ô:™àó¢ÇÈrH'M˳CT»Ð>Ó«Øèõ†×»#ÏÔ…_¼”ïn½izËŠ5ÍO¯Ôúîš"¯iõ¼ô|Â7>êŽÙ¾%IV»ÃúGf܉>y­¶Ö,<ã爇ÇõŠÎ»äÖm³éÞå0¿ ¾´Òî6Ž_t ïúôTÙ¶µ3Z²¯UÎôn¤ D-0…½Þ!êÕÀáBXÆÜð˜êw¶¹‹Tr¢Ûº’9ÃMí“]S NVÙu<¡½äœ8ÃØHÜ£¾!>¾ðîö’âòÙ=ÜÙ"­?µ~7mNè­Câšq{s¼ZÑý¼í±eÑkàWÌçåM¢Í lr¼èwÊ[館8^¸¶sSä÷oáñ2|6ÐëÊ=`ƒã!×’=«qö¹•[‹4ES¿‰Ú*«"‚5ãe›Å_²J¹–θà4ûMˆ¦Û¯Ÿ—ñÞ•/š¥ºÍ¥Áþs£¶ìïösRSK|JštöäóÁ«%åÿu{ô ³$¢0ªmÕ•é,•s_àx9Ž®îøÌ¯ Òd¾ïºsù€;æX®ªGkôýj/gkÄk½³Ýž¤½ê>ZÜ–vÇ÷œ©ëŒ–½õù‘ÞvæÚÇØwl¼f¶‡$wª·´ z_vz]ÙÜá6bYéSÖ×ô|cÍÓ–·õû‚Ãà™'˜ÃÙ/¥ë8—Ë+T¹1 EdoXI"ìÌC*´'¸ê>â1ã0}ûCã/Ž ]' ¬Ü±d'â”%âÖMÇsË-‚X¶6¥¿´ŸqÊJðè/<5¿‰fªWOXÎfÝoïK¬æì¨ÒøuÜ<³›:ºm–7+­éÖÂÜü¤{-h¦÷TÁ em¦¾™W ¦©©õù;õLg]¥¹‡,cM;G·ï˜ôõ3í‰qƒa;»Wmn9í§¦³išÄÍZm‚‡4—¾iq7ñ¡mwá¬gw ¡O« ߥ¶H§iév•;쉶ÊFb6/ »¬'%Îw6_ŒŽÒÖ¨týDŸÎaÑ¥ ¯ÂlÙ9[õ±€ß²zµ6ø­JQíõ rŠOªÈ n.¾9PZ,ªæÇrÒ¥o­Û‹7ºŸ³8sshµ7ŽMŠ å6JSÍ‹ Üî’£ôš‹j©½·¢FýÃéQ§MÍ»þRÕâtˆîmÛkîë’Òïy¹–­™kPcÁŸ,½Œ/›»ð×~´ Ó!÷—´à”Èý“^>ÿáÜOXžxkŠ|$cïÓå¥ýý:ß/†ü›ÒR¦ñetD?É)F Öí9¿c‘ýÁ€³:›ÛÞë¦Å¤OÝôäöÆ¡ú¬†ís†Œybÿ*Ò)ñw8ºQ endstream endobj 2593 0 obj << /Type /ObjStm /N 100 /First 1006 /Length 4196 /Filter /FlateDecode >> stream xÚí\ksÛ8–ýî_ÁÝë2A¼­ìTÙN;g§#Û±ãMmQcq"‰j’²“ùõ{/ø(K²¤8;[5S MÄã¾ÎÁH›IKƒ( L°@ЀIcmàlUÀ8¸Ä'ÖÂX¬ªÉ#¼#©á‘Šx ¹Å;60ZÀè3¢ŸÑ€R©±$¡1 G™„§{Wƒ’²X2•ÜÕSUÆWêiZˆ€îêi(™Æ "`‘võ@ ,A§\¸{ðCŽmQ0… )‰Oy5”à©V ŽbðÃ`eEA c-ŒÁ`H+±£§ Ÿ2paŒ\´tÏ•qõdÀ“Š©@DÚõ¬Á ¶à4B£F žJj(ƒ*B:}Á$BZPiÅq4Ρ¤ÑîÐLhRqxªŽË%8%BKrèÏ7Œf Z:–IÔK Ç/ˈ»$åXODPÒ(=ØY2Ž= ( †= p³t6@Ï+ƒR HÃ\=@ Cؼˆÿ‚•PRˆ¥’,€º8.¨ªE ÜSÎöPEéû€ºèix L„オšRŒ+ð eVsÒyA (a(p­®ìªjËÝS¡TfFì,n :YAøZêFÓ,°`CCÐD‘s¸‚±Pp)4"A¡ÿ"«°½¥Ô    È(Ð:`|¸i]hƨ“Ø Ûµƒ‚ED–Âh:á]h&¨‹@€Â9 ã_:»jD•”À‘U3è‘:áÁª€Fg=ƒ(WR.,ZvðìÙyÜ",€þC@®®?eÁ|:4`Úé|<þ|ð·¿­©¶§v*eÓ2xö, g ¸êgyZ¬¾RîJ5W ¯x}…v庽âÈ´©‰WºÕ•Aôšjž¼Ï³A/)ƒ›€¼~óä[´’Ÿ%ð ¾MÈ)H™LËJcûò!)²y>HŠŠÇܽ·É0O²oÁM7K´eŸa 8‡ÖX‘U§Ó z»©èåYÖU8 ½y¿t×oÒé×r’åÃ$wGŸÉïä%9½¡îå€&”ÓP Äoj„ˆb¡…¸–†ÀTPïØY»Ùy€“~) ešMCjCú+Æ÷ŸU[:ºS‘à£Büǽ½{»aÄë·á•ú!׫HIqÃC·àˆhˆy=ãÀ£Q qc£Kþ X©Ø2X;.B 4ùhEfãô)¦|/æ6Çñz4ì«+hŒîHc#mÁ«´· €kàÆXSàMA4ÙTSа¹*üamÐ6ümÅÏT‡°È…Õ4@Ò 4M(\[ãÉÁ‰?{æú'ǤG.>¼Äã—QYΊÿ$äk’÷“<+Â,¿%Eö¥¼…Éý(-“Y‚M( •sPE«=U˜¤ˆz§E2=šd–'wi6/Žî²Ð¶ åô(Σô.!ý¾P0éÿþåî¿Êd0Çá²áG•¢°’¸)§Bm@Ç€-vש?¿-Âq<ŸF³xè¢jÞŸOË99¬hšŒÓþ,ž’t2ŒÇäZ£€ò~]šÊÙ–»/ÝŠ+–«*Iͱì9Ì÷ËKü•#è1Ú¢¢P*ÄÖÇ+BF†›˜Väiy ÓpX#k½ME%BÜH~¼¢P>[h  Fìž7í ö0AÑn ‚¯ ÿç9Ž\±¤|ÿG4‰ŒhÑ$2B7ÓšÙlÜÈ&E’ìi·ót¨A-)`™ ÄJ!»Ð°˜ÄÝ5AW/f`ªÉ§Ü¸©…€8å.ÿ®…vJ¬BèŸ ÅMµ‚eDfƒ%ÔSîArdõBàôø£Bpó„B(º—0Ú†¸ûú¸ö'¸#¡`táH#¥äë… êé…³â«*Ádb` † ’þ! $úta a#pÓKó„€U¾ l…€\R³­;™Ëm÷ dwù/ æIvËi –t´&ÖååÿöSÜ 5`ƒŽïéð¥³FfT[m}˜xÛ-Qà;?<4cîp×à[ ðÚ5Œ"wÀÕ…û®]]¯mW—!olûvïœk!Ü›YŒ\Œ±… 0†/p[F°<Ç3Ž¿¬ Å=oÚAY×mà³55 $R†Z÷„”B6µ*Í0ë…ss¸gøZf?gzµÙæhûÑÑâpc±…ujëwþYÖGòóèÛ,£‰Fõ£ê%vU®¸t%ø0 ÀU~gFñ™7î\§\ºIÊ{¤!OЊµd-XôèD¥ð«¤œ¨°æÀû–EíDÒNTõu39ùâ¯S¿nsn&–æÚÕÃûÍ4^O$xŒmœ¨|ÝÚ´¢¾ïMý«'ªº”ÏÕDU—ÚQšÃ9ŸÊËU Óîh™Ç3 ðû¾Žjgeè£9PdËèƒ,¢1®ï(^gËE똥ŒÌåüÌÃÏ(\.×èî9èAFáËîg«ÑsÔR.W¹¿!òK‰×Yªqœa­°ø‘ä"äU2ÙD™— º¦fjB.hyÔZ~eîå‚MÖÝz¯½lÝyÎëÇ)âwÚI íb¬Nàšór2ÈëÔËmîAÁµAœyÏ–]Çñë>à8ƒëv]É´&ôV2¨¾¶j´Ü¸YbŸ}2] ŠÎ‚¥\sæ5Ãù  Ö‚˜¦7ÌÚ¤ênI¢À2øajs¡G 3-Q\C˜ù4ƒ½ÑÞû·•WZ¹mçäõíƒKÆÅF®ëŸ'Å Oge–Wëüwñž¼8}uõû‡ÃÓ·o_J¸?Žo‹@TNÜž,8ñ¨ú€[Xü7'ŠnÌ* OãÙïIz;‚KÂώ(>|YÆãtp<½'pnôÊdrØè€\Õ­§ÐÉ(ÎqËàçyv?ʲ¯ãäKùk%ÇY ÍÎæÞFöcz_]½~ß½z׫õ‚`ÂO¡)Çï„)&ˆ­ŽLû:ºËVGFmWÇ¨Ñ Ïu/*“rJž“ßÈyá¶½^“7ä-yGþ ïÉÒ#çä‚\’äŠ\“˜ôI?_“]Ý”‰È€ ²q6…Ÿ“IL†$!nDò…|ÿ)ü¿KÈ—lž“[2"£ï³Q2%)ù;ùJÆdB¦dšN’‘ ~ÎÈ ß#¸A\©b–äi6$‘¿æIá^æ¤ Er=é7RŒãbDJRŽò$!å}Fæd>&y1Èò„Ü‘{ò|'ÿ ÿ/,ùÔîâÓ‹?/O^\<ôieÿ5žgEä<Ë}ÏÊ®gå&ÏQ¶ð-_ëÛà¯lë ZY®@£t7t§`î}ê½xÓUüCr;Çù­™ ð[{ü J…ñ´̺KOk³&ž­¯2¾ÊU(ÿQîG°‹_ªøó¯ » ¢­O%D †Ê÷%Cñ] uvýéÅë³ÆPçI>I6ÂÞ(\¸qü J=39.[Gm,ë`Ï­ÇlŠn†ý«G€%„Pñ Îò“–’ ž;SC2"`“¿æñ˜x$1nxâ6Ob÷!_Œ“¢Ø4fãyá3Ç_ó¬L†ý±«Þ\T-žŒTÌN³ß›÷§Ÿz¯V„Ì&VÆ@à0‡/üÃ<|Ñ«(Í6ÎÖ®C‡ú¡#¬: —5°þì8o¥ß:^C̵dÞ`î¡Q—¬¹Ó´ûÇË'WŸ–¬ùU)¤*‡A|I!½©·CTMEëÀ1Ï‚2Ú|>€ß'€q¹ûsõ PœTPô™|ŒãI=£˜+0ß%aYÐmÑ:OúøeÑíôQà¢÷°»ZÜ÷Q=I+ýŸß;% ¾zýòôr)"7c[@@jLãñG¤ý<^Ù¶ñÒö\‹m#ü|—í“ n Ö̰D+“¿íò¾m©Âî”ÔoÕ†ª )ZÀh›kºÌäi…q“lœ×ÑpévÀuCd·~Ž·’óZwlW¡¬FO³-â`€,åƒ8¨áÐæpçÐâh°¢l‡µ†žtœ\¡¶áí–Z ö™¦¼)%°¼3«Vú`]$½þ®Ç­ËþÞÝíèlsTí1S3»¹A¶óµU‹eþžc½ÚøüJÞ‡wx z‰û„my[»¼ê;¸/ŠÏÒ¼(1¾aiz@ÞÄÞÅÇtXŽŠêO¸ºçÙÅœ3LðY˜&ÞÿÍ8¦â endstream endobj 2704 0 obj << /Length 702 /Filter /FlateDecode >> stream xÚmTÁn›@½óÛC¤äàx ^"Ë#ùÐ$Š£ªWÖ)R c©ùûΛY'nÓhöñfÞ›Ùe¯¾=n'Yݽ¸It«Õ“;v§¡r“üû®®®Š®:\;Þ;W»úüõx§‡®ÚºQ]ç›bÓ6ã ‘7mõvªÝ™õÒʽ6í':êúÙýœ ãï~< ÝÄ æs3¾ãëGEˆº@Ó¸áØtí2·ZkÖmw¸?Sï@MÏžöM[Þ†z©À„ªnªÑ¯ø]h HÞ¾GwØ´û.X,Ôô‰>ÇáÝÝÓ‡¡vCÓ¾ªë _„oO}ÿæàAé`¹TµÛS9êù~wpjúµµÂó{ïTÈk#Žª®vÇ~W¹a×¾º`¡õR-Êr¸¶þ盉%åeæ&ÄÕs¼ÌÌ, X#.˜K±Ié†ÉŒ€åCÎÓF\ ` H Ås.¤µ`[¨„’’F§3LŒT&" C,çjd¨WÌXP@v-Œ²ë}‹±5¬—`—+(&ìRŒQŒ'ëódª_»æ})fJ+ =¼Ž>×0¯¥‘¦£cɃ¾¶¯§gˆWôÎy²&Ĩ5ã9¬Ö7Z7¬FŒ_h'XÏ.ÖÞŸ‰ÿÆàÑ$²ƒ˜¾™‹&¦h2Ž5ë¯gMñE'b VG9çúmåØï9|…~ï Ÿh‰ÑŸ•8ƒk¸fˆyØP8˜‡åžL Ö x³±œôie–9Ç|u6ã\öcW‚Ãåƒab® ÿ4bÎ]K¬[r<ƒÏÔkŸú}ベJ.ã^ óI½ê¤^ ç6-dnÐJY+Ιã)he…ÌϨÌÐÿ®þôáÇÅóq!T§a »‚o!¾ðÿ7­û¸¨ú®G?|ÃoR¬ÊàA²xf endstream endobj 2705 0 obj << /Length 690 /Filter /FlateDecode >> stream xÚmTMkã0¼ûWh…öF’Ç.! ùrض4eÙkb+]CbÛí¿_Í{NK—bÆã÷1oò¤›Ï»™©Úƒ›…÷R¼¸¡½ô¥›¥?÷]ps“µååìšñѹÊUׯÃxîÛrçFq›n³mSw>xÛ”§Kå®QßY÷V7Ÿ!è#n_ÝïÙXþÇÙáRŸÆº™IľÖãÉÇ|÷YxN|á¥ürýP·ÍƒP÷RJOäM•¶gÌ0óI‡˜_•ë¦ê'1âiÒ¢ªËqz£gyöf y÷>Œî¼mŽm°^‹ù‹ÿ8Œý;)¼ æO}åúºy·_”ù/»K×Tl6¢rG_ÐÏþ¸?;1ÿnÀ×÷Î MïŠU•må†n_º~ß¼¹`-åF¬‹b¸¦úï[‡㪖>TEþ¡¥ 7Á:Dn˜ø‡”ëxáq¼¤ ÂhÍŠ"<ö¢a"ñ„E a‘b‘n9ÅcO ÅrŠ¥”DÎDJʯ—««æòϾŸ¦“2Ba©8c ]R§05×Y ¼`e1ð’ù 8bl€Wœ»Ž™§x6ÂÀ†yÈ•–ûRLʼÎØIÔTšqŒšZ%ЬưNc½Ðp^³NY4{¥¡G£¯ÖŠpÊ<æÒì–F}]P¯rCÄèUmaƹèæÌCÿ‚xEõ—+Æðm™³6\0†¶ˆø(Â\1m‹ÖøcÊ%æA¯˜g”ÈÍç\±ý\›˜faböÍ oœ3†Î„=4ÈMÜ ÿ]Bû˜+̘ðöøŸL³ fÂzBÔL,ñ 3&Óìð-¡^˼ao ¼5ì­AŒê ¾µì'|°ì9Åg´K2ƒŸãb5m1m-N"n3^^úÞºZèXã@×û¸}º¶CýèÚº^’x{*‚ž©t[ endstream endobj 2706 0 obj << /Length 708 /Filter /FlateDecode >> stream xÚmTMo£0½ó+¼‡Jí!m0U ó!å°mÕT«½¦àt‘Húï×o†4ÛU ÇøÍÌ󳙫ÛYZw/nÞJñä†îÔWn–ý܃««¼«N׎÷ÎÕ®>¯wâ±ïª­Åu¶É7m3Þxò¦­ÞNµ;³¾'Y÷Ú´ úˆëg÷{6jö>úÙ;A òs3¾yÒ·ëÂÅ×  ¤_®š®½êVJéE[gÝÛ‚ù$EÌÏâöM[÷“ñuÒ¢nªqú¢wuð~ yû1Œî°i÷]°Z‰ù“_Æþƒ4Þó‡¾v}Ó¾Šë¯ÒüÒöt<¾9È2X¯Eíö¾¢ßÿýîàÄüÛ=~rž?ŽNhúV¬«êj7w•ëwí« VR®Åª,×këÿÖbÎxÙOÔÔ0ñ/)=Vfá±Yú—–T{œ¦ÄðØ ­â@á r 0,jؘû@†@ÁŒtD˳¢êÏ®Ÿ´K¡µT—M¤Î"`ê¥ó xÁB ð’ã9pÄ8Ž976'>ï;-SŽ'À–û'ã¸ÎÉ…šJ3† ½Ê('ŒúZ%ЯÆðD³N½h¶FCf=tÂu4ôh­ˆ“1ûÕì¢&NI¨‚£C ýaιè‡æ%ö¥ã.sƨ¿,X§.‡GÿœEDœ(B˜üW14yñÓ¨‹ÏF_ÎÂðÝHqÅ('bï ÃÄ„ùî¾vÐmØ; &½xgìå&ò…ý5|6)ö` Æð"ásJ‘›,¸4%¬!Ź&¤AQ߄¶„üR¤3əߪ¿$S>›gcYˆšvú§ Ç²~ ï¬å³!ÌçG¹9ÝW™Ã»’qO ýø—1y>ÇDuê{?Ah<Ñ`ÀHhZ÷9ÁŽÝYôÐè;ÏZ|=”Á_4« endstream endobj 2703 0 obj << /Type /ObjStm /N 100 /First 994 /Length 2425 /Filter /FlateDecode >> stream xÚÅYmOÜHþ>¿ÂßQDWU¿J«•{É…„ / œN'’Œ²HV09íþû«¶«†n»gFd‚ލÆv?ÏSõT·Û6Xç;Ó&Û 9p!u˜9ã: Œ|ÚñáèXìÀX›#â!h;tù kø'þçÎø¬ï PäcyXŒýYìÐôǬc–è2§ï|>Ê>f™ƒA™(‹@G, _ ù&C3ðÌA8ŸLG!SæX„;"ÊäLÉjc–‘:rL‰8òŽ9R\bi:ŠžÏgS ¸ÎšhX®7…È2Ðp”«†HØYk€£ÀÇœ‰œ ÄÎzÆiñØ€,×2²˜r‚<"s8äŒe.Xç8WN•U9t9UÃõ_gsÁ‚á³Î±A“vž Ët.°\Ž%º>¢Î¥lrÙ½1ì׎£\gä{v GÐy„ì‚EÈè½dY12G<ÂQ¾Îñì'ÂQÊ]Ã}àCˆÌÁê¹[22_ì“Ï×±ÁôÝÅ5`µ}ÓP0÷Bêa>Ë2¥|–3 6dã»À ç»àÉÏRìBÈNÀ´”#Ó…Èÿ"HÜÖaÏgCì"÷YŽls ™.›À"#1(G<†ÄŽGô]ÂmÇmŸóÈöÄÐ஋1ç\bî(V ìeL¹wsa“±™ƒL—úyÅEíö#¸wsp—$êG°ýv•ÅgÎ<±!9âÙx0,2…œ¥aÊs–†&†á(柆Q9ÌSÔ¤4ûå—ÙîÉßλÝ·7‹Ùîñ÷O‹þg>³Ýç—÷ó|¦ÛÝûøñõÑñÎþ›ãs7ë¯þm~ÿùîêÏÅí·%—ÐtïùÄÕÝýbÿË;žY³ÝÃËâLJ«/‹?îùZÖß_{r{zsõùöË<·aêýúë#$\œìœÌ?¾üûnþÏùÝíý³ç·×_òxzŽäa(äqÕ }ÜýÅÿ¸aqW7_ùKÉ×{úûÙó—§S½¯—×WŸ[ªq¬ÚúR5¸R5=ê³ã‹ã—‡µê÷ó¯ß¯/ïZ’íD²« e#˜§‘üâüâåë*ùd~÷m¾º3üX0T5ÆªÆø4‚ö/Ž‚W·Æd¾a\]gxÙï^}xþñb${uo$ó˜R?‘æß^¿Ú?i^Yæ„Ö²Ìá‰Úyïðãé›7;o¯¾}ú~ÿþöÛÛÛtØ—ùÙñõåÍâ?àÃTz0éåŠ\*wqª<Œ•3¤}¼øßöÏövð×§Å¢UáÉ‚áÍêF¶?¡œgÏÏ>dEmA“°äKAá':>=;w>Zg©Oëo²õòþgHÛ?8:9ÝY|nÖ*˜ÉŒ¦TJU©\£¡ÜÿaÑIÕ¢C•Æ4™>6dû©ì£Ë¯óûÙîþíwɘG—wsŽúmzðúêË}÷/ÞéôƒósMB+¡zj˜˜ÿþ1*Òa˜H$Ð AÞȤ-¨, •u’ƒõ’•$¥JÛdåŒ08J:4èÒ#ä¶¡²"Ý9ÅsË#b‘ó ÛÆ¥ R@—„Ê9â5O~“€èQT±¢òV|ðê•×ddÑà è©ÛPEi3¹‘æ@‚¦@Jp›¬‚Nž`¥JAM N©´'ƒOÛPiGÍ*£$AJ1nA‡þe«xŽ4Pª äa+*]˜¢.I³JFÈáQT©¢â\±Â™œ^‚Õ nC¥˜ÒPIäG` Àhà%’£âÑVa’Ã<åÀ¢nÄm¨¼*Ê—A”@î/Ãíê©D1€âiž@RI°zĦm¨¤£¤ ‚’=õHzÔ¦¦’û¢ÜM8ôPFM˜ÿ¶ Bí$©Z£q ß†ÊkVA¥k7 ¬»HFæÁ6$P¹ùr GH©4=z\[Œ©¼2hzù­ØD=¢Ína¯¬¶¶¥e îY¹kr GÜ㲂šÊ+ƒ,tèŒÔÍtƒCIÏlA%› †ÑÆËïʇ@kë´¤.nE¥8NûÍË“±ÈË Ÿƒk ­¦ò:¯¼Üðù™uãŒ*íXïÌukBzë±V·š2i@ ×cØ‚ËëÏëv/è>D½ÓëS@Œi®¤{ó”ô†§}eä ¡ÿˆ!K¯Ù‚«ÿð!‹®¢Ag¯.§ä…ËâÆMD~ú_Åeõæà¤Pýg’¡hcÅxÓ»D’ÍørO´¼5-Wˆeû ß}_\_ÝdÔþù²“gÜüx9|[éJ.n9öjqÝ¿ô–×{9–î~ÈVÝÍÿ;|)Ÿ9Á< „P!,‡(Bp-„à Ú€ ßÎÿÊgCjâ >OO¡)I¹{·¾,H V|pãA±"ŠÅg4a. ñ0ÒŽu1¨™½/ qcC(U®™½+ q´¡6Ä5%¹Â›ÖÚÚŸ¶B[øcÝÀÚMÀ¢ìV ‚mÎ[”Âã\èG-£Š¥e\Ý2“9L…]D˜k»ÚD…]˜V*BÓ,üÁ±?8J—êâ«%ë™`Váú% ô› :ÔÌš‹0ëOa† sa1Œ,}‹,…†f] ° hBm4­‚Â*}š^(ï —€M…úR¨´±lÎ,C Y ©¶kô’sä=ÄôMùP°‰à !è×8•dª–YJ”–znú > stream xÚ…XÁ®$5 ¼ÏWô ’ر !!$N!ÄpØiYŸOåu÷¸ÝÏ“wXmzÆ)ÛUNj^×¢¶•­åÍêüÒ°ÙZ³¹hõÒmcš17:e“:cX61ž‹¶©ôG-d›áS,xmSÙÆ ,>®uF7$ª6±'J“ >¿ žT|Ámî(}«½Ì!]ËcÌübc‡Ô^·‡jÈ4 Ñ£ŠÕ­FŒÒÖ°2Ð]ÅWÒ±‹º5Òúøº1#¦#¸#ÿ`w F°ô¬¦ f‚ ½Bð˜_5,úF¥#¦Õj³Ç¨ºêØF%,Ð÷(c#êF‡Ä„`4¶A¤N ’€JCƒ4“J¡™ÔÐ ÊCƒ4“ä2êfh+:04È苊Åü 2‰b`fÄ Aî`ÃÐ w°ahld†ÙÀ†‹m  b Œ{†{Es†ý-)ì` Æõ8êHúÐ![ï˜)mëÒʦfXàcEÛ]£ŽÀbÐ[ˆù©dV1,L±` ¡˜ÆFã¡ TD*Ø7 a´«ŒàŽÂ”,(L Á‚Âì‹‚ÅÔËlW‚§DŠâcõЊ⠈Ԋâ*¸QH¥ í*ÄN£A€öí­‘‚1¡ Twè9ÏŠ $›-q|óÍãë_ÿòǧyNä/¯¿›kÙ×?ÿöùÓŸ_öc¹ðùÓ¿û±}{üéÓó[koß~û°}XàÛíð°: Ø À3ŒŸ#ð ¡s(IÚ·ÆþøÃïŸÿþr©øÇßÞÇQÏ÷ý°¯ì]fºd.ëÌÝB+Gg7À~‘«Ë À!Õ§_ôéQáXyæ-¸8 Þ¹W y—ø¢#ßu> stream xÚ}YËŠG¼ÏWôUå£ Æà“1Æøt؃ÀØ ­?ßQÓì,åÔA¨g»òY³µ¥–-m¥Ò†‡RÚ–¹áÙHÿ§¯µl’ð^i“F[‘¶©àýóŸâ_B¸< —­IÞ ÓÖZß !_JX@‚‡Rñ¶œ…·’Ë–)cM&ü¸¥ÏÇß>}ûëý¹÷Ï_ßþ}îÐç§_ßþÃ;ð6>}úär±åJq®=ú¹ççèÒ¯èR|´¸NŠÜrÕóÓÏ_¾~{·6ùüm¼<Úøéïç⹦ZMZÖL÷þ4S®|åÒ¶Ê¥Åå’ —š**Ë\N•©¢¦Š¦8×­‘*bªÈ¬ŠÓáÐôÔA§*‡m.b2ˆ—°îxå®CÎ'ÑGÑϳhÎ,®jÎsYSŒÛ²,;š%’ŒM2ž$;¢§õ& §eñÄ®xr¹Ü _ŸNÄSM21i3¹’!$S‰hí6 E›…ŒúÜV¹²Û,a_٘ϲÌåT¤h³dS%§U®ä¶N޶N2¶“ƹŽèh>’Xt^ÍÇøvqKvŽê1é¾%N-Îù(sÍtÖÔ^]ÍñÅçV²ë÷k/Íqô³Åñµ*ˆ¦+ºu}Ük·zx¶²Y¤‹š.:érFEÓ¦¦„ôU´8]4ÒELÑe.· Â¾Äø–çÚ£%"XŒ`^œ|+ÝMÈÙç>!æsBdªÉ¦O:$¯i„—Mê«hr:p¤™¤Ë\|Ø™”W¹’ë‹"UÈTÉÓi”Ü ’#TÙøÍ¼ŒvçOŽÎŸll§ç:¢£N’ñ›^ð{°àœìœì-…ç"FüÚ§¥»³›ýŸpöšìGXçš—@2ù´DÎ,æÌ29óÜ£?ÕýA,§¹>{”Éjó\ó’N&?—z?d$2D1£–ɨç軵˜QËdÔâ¬ùE'ÆõdÍâìTNk>ÈjìÈÊ«!ól™<{.rß3y¶˜gËäÙ^]‰<[̳eíÙÂê˜÷èg_4¿@ož-“g_Eö’á5“–ɤçh×päÑb-“GO¹œ·Å}™cËäØâ\V"góh™{5fÊÂëŠÝ(î— Î^óüV³r™¬|®™î¿8Jäåb^.“—_Ñ{.ŠæÎÜ[&÷ž¢³Ó+ro1÷–ɽç\N½°/ór™¼|ÎåT‰¼\ÌËeòò)—sv‰œ]ÌÙ%IœëˆŽöCb‹^^½Œ;â»ðÙ ›³ìS‹¿—p¿.¸û«—«È^²WÜÕ¢i}¿z—ÑA®ëê…[‹sÑQ'­Z´,¹#Ç]r×WŸOîÎ>_ÜØjz½øº³~–¬ÞjÌ×GïxEÑÆ|˜'Ç|u÷rg+ÀF«k ®&Ii«"Å T#Š Td•K›Ë•¢\F|™ˆ×ˆj5ªµ¬j‹ÃQÜÕ1—ûÕñõ)þšÉjúè¤x¸@5â¥ÅÑ{‹Q-Fµ,©r¹Ü¥õÙØWe9)bŠHZ•d7ÚÜO2›Z<©Å\6ªy¹ØBâw>»Ám©.›>ôbcìE†Éô¡åYEÝ~Ù Teõ§ &ˆ&oéî¬ÊÑÊ&I.Ëh×0E'W6¹2-s9¹â¾L‡ÔV¹’S%Gª$Seòî9—Û59Ú¿æäœVlSw‡] ¶™CSÁýMQ´ZôòOX9©“ÎÍÚÕç>käϾ:×¼T¡6ÿý*ÝÑ·¯99}çä>ú®õåbË•V¹ê]‡¸/ókšüzÎ%.×¥ÊÿÊÑr endstream endobj 2716 0 obj << /Type /ObjStm /N 100 /First 891 /Length 2639 /Filter /FlateDecode >> stream xÚ}YM‹-·Ýß_ÑK_ƒc©>ôÆb`B’ñb0CòÀÏ6ãIÈÏOU©»¥Ò¨{ñÞÜ[]**Õ©žL[Ø ‡-Á)m1¡ü”ÏÀpÙ0DùIæ,?ÃF,Ï)m U~–‚øaÙRÊ@Ú2És [‰òÒVª<Øj–8±l1 8DÚb¤"Âõ?²5êž²_Ä’·Xå%|ÄŠ[d¬[,ò/E–ò/  XÄ9ë#û"0囬Œz±Ö òAƒ¦¢Kucñá¬Â#êY Š3 XÌâLâLrŒHzl”}PœSTPJŒÓ“g¡)*Ü¢»ƒ8W³–1¢|ÈzܺaÌâ#<¡,~ˆ%#’D—ã! Kr:dA$‡ÃDY”Ÿr9æZr2,]†„qñ«µnr, r,yDQÐHRJåL$€%c›l“äáFDLL±<ä<IJ©‡R’ˆ_Žšù)þr*E¨¿*™–ÈAÖòÆå¼Yž3@ÖOE6-õ!ŸÄ‰5¯‚ÒÚÈ‹VT-å* ì¬<mIèÐO¼%’dȧ$åĶVŽ[´<²¸æ"{Þí©”YF´OqË a)ënr¾¬Ù‘O´•`XĹÄöTJ³í+g*Üž–­¤dYVŠE&ITºBø“ÂÒJFÛWн²Þ, ¨‰u7á»–h~i«5뉄vÉ{[¢Eß|óøúŸŸÞ~#Ë%üûãë?êAÛÇ¿½¼½þòn7Ó¾ÿú?ýVì۷ߺÕñ\Š[­Õ×¾¿½þ×.›}ûó§·ß5µ¯}Ñouø§_ÿ#+¿âi“”û&ä!aÛ& å¶œ«ÃÝj.ãqåº|ŒÅõŒÅé6¹X+\܉g¸åÒÀ«4pO•»X”\,ZÄ¢Î6ݲ_;Ê)VçžfîË W§ÂÎ6¦ÛÕŽmZ±m„ÛXŽí5®Î6”»XàØÆÛÐÙº.ÖŠmèlÃÛm5¬j;v¶ãmmGÏvrû€Ù.öžŠãb§yËž”xqÚ&q•†ØÓîz âØÇ|'Š®í·þ\¦-CÏV@¿å±Iã(ÄàÇj™nVëø1‹lÅZz,¾å¿Â+õXñ.V‰C¬å+œ±Jö±ŽÕ{,^¬.©¯Æõê¶w©«Õß|Ë/øsàX°VÇFGAÀ´eîiÈSˆÇ-3.çN|Žw«Sçñ¹Ÿòm,v±V¸ROCÂÛXŽÈ´JJêIáz‹³‹µ*îló-ÛŒ.Öªè¹sÏ·Ü“ãžWÜsçž.¸ßW¯Ø¦Î6Mlƒ»2]¡ÀZ¡îEqѹ"õ4`½Û]h•ìi@¾åÒ@«4`OÆ»XàÒ€«4`OäÛX.)¸J ô¤ÀERÚjX=t¶ãm'ŠŽíâ ®•´ÖÒ{Râ… ì€Wiˆ= 1®µtWb§ž'þ¦žÁ«gž7éù S~û°8†Íþõ§°¡§jey=Ù³‡èí;w™‚ïúqÞñLï¤ãcãXÔEíI³Ë8¯ÔE=v‰žºŒÙY)räIÇ-}áÕ‘ýšï° ö¤×eQe]Ÿ'yvÓÚX¬Çé.§Ì…ïRÔuy–å± Vâ×5y–äq¥ä•w9žÕx ã´e…¦+ñ$Ä+MëR;)-:Û8M#§é–Ó®¾“øúðcþV(»ðNºëÈXél—Yºãt¼æÉ…}Ì.ë®ÒEyÖd·×(´¸ñ]vgÕÃ8Í]InW\¼)g'·+µíb‹7µíôm%´]g'™u* ¼úeL _®Ü{óêå¶¿£\CwrŠn®wb ÷Sý0f.÷Ú¥p5Ëu]u¸ÖÔ¼Ê : q1ÌÂsö¦•ì4}>üXòÓËÌTò=7"ºÇwRíe3®iýþåóëïÛ_|÷ëO_ýãýåíý©s“EݾøËûëç?ħލ0Z‚šZ8LæÕÚÐa1q»Ê‡ Íd±~dŸ>zŸ6?œ¶d>S*4š’™x4å§qa439€ÕLž{Ÿnkx`\è XDgR® Œû˜i$ÐLn!™‰–èàÙ½.À±-Y%ª¢Û7›i¤Š™ÜÂj¦4˜ÐÎ~ŽŸ§× 8ÖF35…ÊSmÝü0龕ÇÄ"™i$õìµIötº÷évψJž•<#*9xB„<EFÔÈ&  ý#ºôìnktmý…ÀL#B5å‘)"3L‘0ìø¤d¦¸„§{Ÿnð²­«ŒŠšÒXeTÍ4òÂÆÔÈsr¦h¦²F—ŸÝmŽÁÖL±2ÅŽ)V¦’»)Ìfo('3Çâl&^ÂãóÖŠÛ¼bë݉«™ÆbLÆ”³sk"›Óh)f©klåyz­¡i ÜYúéß/¿½¿¾}iz”ݪFš,‚êl?0…$Æu~Âè÷çùL2ʇà>ÆÉXÔøÑÇè{ XN–}pí~a¢Ì&òÄ·iÌþÄÁ f}µƒîXbI¼Ælú3wz—êDñ耇MxÇ2Ù„v ÃÂú^t+°Šap½ÄZ4ÊD¥œ“ô¿½ü뵕2…ÑÒFr&½iñh\»M›ÒþKäL½[§çû°ÕÅU6cñûkkŠÅ»Íæ×js‚à×jwÚs4âìºãÌb!|XíPû_º›Mˆž^eö?®6eŽkµÛÀlée'sÕö'JÜþG¯Ó›Ìæ!)qÀŽÌhÄÝc·qɉrA¦]ýÓñ ¦Wq6T‡Œ¸êé• ÙÙ”8Œî4zÝÅ–/PÖçàxR/ 82uă³ïï6%ÑÃTâГ®& »œë„))‡5L»æ§ãL›H«»—:êIT—64â²CŽF\ñ~6?—´*ÒeÏ8Ò%Håírv›òFèmÊ‘ãHçM±ù*oä¹´—¦pQ— àô»¹¨>h:È6ufo³a*¸"°¹“}]¶Áóã0ÒtÇ+˜6¨¢kÃ'ºì¶éÓ7ƒ6~’Ë8o®=íèEY*€îx² ¬¾ÞÚZò6…VGº¡ì/~›Cƒ«‚6ˆ^õuEЯ`Úà].Û0êûú>:˜:Žrt(ÛÍd¿á‘Uh¿ÓpX¬ò²3§îjÙ«:—¸„§vÕtÛ{=WO™JqL¦Æì,ÁœF†í]=Á˜]{W_¼øœ[ŸnktöbŸ\s³ûä¦/{±OŽ<{WOÉÁS¦Rv ‹ýŽ—ððìÜx%ÕhL9…PtçÛ,ÆT÷%cÊÝ`íš1;ÒµiŠi]yxj4]I´6ؘÁaQ¦2:,ÊTvwRÛeÌ®dµ[Æìš¿6K1­áѩʹKóÿÓ¿fê endstream endobj 2836 0 obj << /Producer (pdfTeX-1.40.25) /Author(\376\377\000M\000I\000T)/Title(\376\377\000K\000e\000r\000b\000e\000r\000o\000s\000\040\000A\000d\000m\000i\000n\000i\000s\000t\000r\000a\000t\000i\000o\000n\000\040\000G\000u\000i\000d\000e)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20250820154543-04'00') /ModDate (D:20250820154543-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023/Debian) kpathsea version 6.3.5) >> endobj 2750 0 obj << /Type /ObjStm /N 86 /First 887 /Length 3532 /Filter /FlateDecode >> stream xÚ[M$· ½Ï¯¨cÚ@fôAI°X ˆ/A;°“áÃØØ x½‹ÝÙCþ}øX¥ž*‰êZç¦&%ñ=J¢XUìP¨.n %ùŧ‚FX¢'4âB%¢AKŽ´”ªóR‰Ñ(‹÷N‡ñâCNhÕÅS »P²[|vevv˜#‡Å×ZÑ’¹}ÅØ,æbÍhÉ©b–ŒŸj,K—Ê:–ZÖ±u‰1±QÜSˆâ—XU •ÀAð“'ÌRh¡a­¤…RÄô% àýÊBÕaæÂKrUeuIAl°[d)«S8,‰=Ç%û G% à´äTµ•—̤ڲWTÆK‰Œ¸.â^øJ¨À–_ÄU­°pHèWã¤Þh\‚jÓÂ5«V–ó:¬ÈÂèÌb¼f#qveæ»À²^f!Ö»(Ž’¦¬ˆË^¥Qš ׳#YYïT𤩾c—¥™ÖXzL.M¬½‹:™,~} Ö¼X „eeAäC Úk¡& ób-z°bÙpbÀÙ‹µHkS¬ÅW°k1c_²k±¬M±e±ÄZ¬:,ˆ5r24ÅùьؖQ;ˆ5Ù À ëæ‰’JÅ¥¬R±Få ÖÞ&6v °ÅZr„aǯM±–œÎQ¬¥¸6ÅZ"õNLh&º{õêîáëÇ·O—þòþñ×§ûtü(GñÛe“8aSïD"µˆdSìDñ‚Ãö"RNú·?Þ=|õæí›ç½ék¯ï^¿6À<¼›1C¢¢¢²1DéЫª(íDY¹OÀ]Ñå ¸ìtºŸ~’S²ÁOÌ{$Yý$gq'R?–!ƒ{]½9 ƒík· <°«þ`¸¨èàVÑUã~ý1ŽÜ~\y„b]¾¼t³Ñxª¦½ <þúáñýo_Ü{qN £Xì¦<Š…÷ºò#Òzé»x¯ê€SF<G3ð(×Ð; ˆ4qDô\¹Q¾î¢‘ÂY7⑨·ÄH„4ØD;à弿ȱ BåXÞP9¶Û-±[t“®ðð²S_ä8N/å‹gŠFØñçO??¿y÷‡ì§“´3¹“G•ó Àu1°xÑzµ3ÚÇH¢z9Nq¤—Ï*/ƒKÛiy‘u^Š=#²ã€4‚Âm1w'W¸9r…›Çþ · ô¢ÂméÚN®vK˜Ó²ã€4¢Â-ÃjV=4ˆT>x]ó7Ii;9îþH=‰¬y½6l€uè?§5¤·$ö*.šî¸žk‚ãúe`Í[Z*të¥$½8êi÷SüÀtè>‡¯7R¨½ãô µ‡_×8s<$÷þ^às/ƒï»ã,g]©òzÝA_»Ï°ËÁdÉåΆšN! b\Waì-k¢Ä bêÄAMÒlûo˜Žýç‚"¥<Òä1¦RRHÅ bÌ]ÆÞ˜»ð”€b:öŸH ‰Ã`Îã<ˆå”¦Ú#Í ]Ä${?ˆ#ÄiJ@1ûÏ dtξF„@qgˆ{¤E ÄÔ‰«Š©Œbïã”B>RÐs¢Fø¸æ;…x°”—x° ‡¸Â(—<ˆÅÛ#ÙA,®Øž¡L+ªã€[І 7˜AŠæÂñե޲Ï-‹ßI5êÈíyPyºÁ¢\ºS¢:]6¬¨<ûA®æ¹[ µèCU UÞu‘•ӌƊì8`Nƒ”Fè.å{Ejé¥b;:ßK#¤©—¤µ—Ê‹óÓ°â9tŸbØ•Ñecè0ª7c¿³Ô—±?J ¡O$D >4Ý=ŠæÐ{ œÔ ©ô@'§^ :y.'%–¸^‘k/É:u¹¢9ôž×û$ö»BC:õ7³Ftò®—FH©—¤ÜK…éõ›[%ßÚ*Ë©?c¬À#÷Rïo^Vàiè ๻õ. âfÀóa«Ô[YƒFuê/v êt=³Ÿ~Ú?eã2#Kƒ,ß“9("Ö\cŽ*„›4 ýuÍ ú!#¡cö¨Sá5À„Þd› ŠM—Íõ¦ûôÓ.‘]Cì@m€:³øí{ˆSØ™&e:æQ³¡IÞÙ:äwžl’%v:ìú\nñÜ#oEÙ\ef¸@Wl##³°e)¾L´š,„ÙXM=BºEwÃm=ãëài ë©ñ±L´ŠœüD«È)M´j—fvqü½ñRÅ@o >¡­‰>œÆ5yÃÇRS‡ ›‹­#dßÞÖ%èLWhúÅî„jX?‡‘'DãØ6Œøäƒ­Ã3ƒÏ¶NÈpžÌ™ñ¬aΩyÙöikN4—ΉjzÇL¶a Älë@´Në’³uxL"Óžæf5…ÛDÉ šÎ‰jŠWS¶ Ñš­#è&€AÔ^Ñ´>šÒ+§ž­h2ˆæs¢Á«½¢šZV{E5Á¬uD«é¼²>b:²•ë[¯z›ªuë”ûpFµh¨t>Ú¦I•ÅV&}Œö¶2«Ò ;¼ÒÑV*ÝXnÓ-÷ñb =¡Ë+]ûÞà•.M@+]ûÖ¨+£Tl¥2ÊÞV* |rɲA·žß±u½êÜÄ´Þt.ÙʬʑnØZ#z‡5ë “QxÅœO¶qí¯Õuà-žxç±½ 1ì†ûí•H·ÞЬÉyt¶R_‚D²•úJ#²­ÔÏŒùV n¸¡·èÒ:*™m/ ŒMJÛ[ˆ ÕúDolPZÏj,ÅTaBö7(ÒÈN)¯‹B4n0^—„(›*}vWrKtˆƒ©Â„œM&¬·î˜ ë8Î$xíô…¾¯Ý_á•è8†‰ÉFÌ%2Š}ÖpP"wšÚDò4ɨ­¡çlåù…ÓŒC9£T‘ñM(éªNTpbž°E•×|ʶ\̱§tñv¤ºèå Y…rÂ) çñ/ä%~âET7ÔàÎût1ÇžF5D N(}¨a ï„êl³ã­Hmv}Oãrh5)ñŒr°Ö8~Æ–Ö>nZýÆÀ~¢Õ/ œl­Vp8ž#M5ö·ÙA«¹F-g´£E›Â9mÒ¤¡Nh“~3wÚ(AíŒ6\üäÔ E´“-¦• ÁŸÆ/²6xrç´µ®4ÐdŸj‰i ÉFÕjÓ&Ä´ð4¤1-KJ“ÃO‡§œ“¿X#O)ã•Ó„/Þ8MÈ"\Û\P­Rí 5°Ù†õsÚIc;‡óÝteì…ÑwǶFKvíQZÉhk´ÃæOkAé É/ÖÈ3’Z÷2¹Œ´öer I«Pì8CZahl÷@öœØìê Q2ˆ&:%г’ ÅŽ<£‰*sžäü¨-çp–šÔ|±F^ ÿóÍ/2*”í¢‘·FÝÛe+ ßÃ;—/ßýü×ïž?<‹µJwý˱LФßÿ÷ýÓòð÷ÇçÇßßýz÷ðoqÀGäjåîá›OÏ¿¿ùc­ã¶LHÿ¯¬¿1ä_ï~yzøÏǧÖ]…_=þôôûÇW¯¾þôöãNß=|ùúuÐÆ‡×¯©I~,ß¼úão 8I ãÿß?Hì endstream endobj 2837 0 obj << /Type /XRef /Index [0 2838] /Size 2838 /W [1 3 1] /Root 2835 0 R /Info 2836 0 R /ID [ ] /Length 6855 /Filter /FlateDecode >> stream xÚ%›ylçyÆ÷Ý“‡(J¢´¥¥¤¡D]/Q"%RÔMQ%r%Q)’š¤Mn·IÐŒ´N[wœ®ÛY&Hƒ pÜæèns'ã2)ºÓhíØ R$±ÝA´ÙÔiwÿy0ïóÍîÎ|ÏûÌ|;Ïn,–úÆ‹µÇâ±X"f±Äg[ɯæã±–µspÄánÀ¥LI¸›pg(S@îÜiÊ Ð÷îe3Ð¥ò1¸“”­À:8ƒ›¤lÖõÀ l6Àeá&(7›à:áÆ);€Íp[áŽSn²p;áŽQv[ávÁQvÛàöÂRnrp‡àŽRv;àNÀ¡Ü ì‚; 7Bé=pgàSîöÀ]„¦ìöÂiž‡(÷ûá4󔀃pšçÊ>àÜ}¸~JÁܸC”zƒ!8é¡—éÃG•ª6Á¤Ôk†ÓGê¤Gá¤Ç~JMØ1¸V8®&{® n/¥„:· N§*‘O†ÛC©9 7§iRs…; ×C©Æ<wNS<\€» ·‹r¸7'y.—áÔã;(¯Wá4÷’v¸§¹ÏQ^fá4÷j‹9 wnå à&ÜœZê0··•ò6pnNíxX€“FYÊEà^<–Î¥àÔÊKÀ2\;ÜfÊ`nœlpx§¹ßDÙxçX­aö–¶ÛÀG5Ì^‹Ãåà6PböZ®Ö0{- ·n=%f¯5Á€Ã¿5Ì^k;·Ž³×ÖÁi²UjçõpšìJ}Ð85µÞJÙ8…t)×DÉYÖ6é1uÌP- ·.MÉìÖ¶ÂmÓ) Lmœš5I‰ªµ\/œNŸŽ¨í€ÓE!NI7ÕvÁíƒÓÔщµ8Í Õ]\ÛǼ”5÷8 ¶nî%î©í‡;‡n5œW;wn•×ÖÁ‚Cóf¯ Àqá)/SböÚž2ýRÃìµÃpWàîQböÚ8ŒS¦×j˜½6 ‡FåJÌ^;· GŸÖ0{mŽf-ß¡Ä쵆ÙÓÑ&8z¼†Ùk'á:àæ)1{í4s_Æ5Ì^; çÀݤÄìµóp=px«†ÙkàvÃå)1{í"½VÆ—5Ì^» ×7K‰ÙkWá&àðt ³×®Áiþ®Qj`Nó§]ô¦y8.Üå«”: ›pš+½½NfŽ~._¦ÔDÜãBQÖ¡i³›É§á.RJ€{p8–Ä[†kƒ»@)áWáè粦DMóNówž²¡Œ=Ù0û†÷ÇÐ$žƒ3 §IN¹ÈÂq¡(£ìfÏTâpc”]À68.åQÊí@Ž;]ù(e7°n3ÜÊÀ.8Mö¥ôÀ±)¦Ü ìÓœSö{áX=”‡(÷ûáúá)á4§”}À!¸#pý”‚¸£p‡(õCp¬FÊz™>ü0Ü$ÜAJø8î¦e}¤Nzî,Ü~JMØ1¸ p:\Mö8Üu¸½”êœ4Ò©Jä“pÒh¥ä4Ü*œ¦IÍÕøÈ¦l®‡RyŽ;]YS<\€ã_ÞE9 \„cåQ–<—€ËpëàvP^®Â±:,KÚàܸåu`nNm1äáX¡”·QÞnÂÀ©¥nópºpo¥¼ ÜÓ…[íxX€cuSÎR.÷àt1R+/ËpÒr3å ° '-eƒûÀ8VAåM” ³Ç—fïüÝçØg@n neHÂéÊßN™Òp,™Êë)3@œm£lZàXΔ×Q¶­¦¢L§R;¯‡“éZ(õAàX¦”õV:ÈMp,ÙËM”Àf8Ý!t[€,Ë™rš²Ø Çª¥¬Sè¶Á±j)')·98Ý!túÝÀ8Ý!â”;]pºiê N"Ç(w{àÙÓÜ÷{á¸ày(÷ûḻx÷)ḻx«”}À!84òV(û8Œè-SCphä-Q‡á®ÁÝ£ŽÀaXo‘ò(0 ÇÝÊ[ ŽÁq·òîRÆá–àîPN'àXx·)'“p|Íðæ)O§áXx·(Ϙ=ÀØÞMÊsf¸ûy7(§Ì`l/O9 `öc{s”—ÌpGôf)¯˜=XwrÀìËdï¥0{@ÿyÚEoŠÙVŒÞUJfXÉxz{ fXÉx—)5˜=اCÓ$bö€¯›ÞEJ €Ùn¤žNKâaö€žô.PJxÌГž¦DMƒÙn"ÞyÊÆì&ö5ÌÞÝŒÙîÞ980{0w–2`ö@Íz†2`ö€+’wš2`ö€«wвÀìwï$e+€Ù.2Þ$e€Ù.(Þ Êv³jÌ ÊfÔ˜ã”fÔ„Ç)·˜=àû–wŒ²ÀìÁ<Üe€ÙVÞ(åv³¬(¼£”ÝfÔ˜G(w ³7wñ<¡t€8žGx‡)w{ุyÔ½À^85æå>`?œsòpNM8@Ù‚SöS à¸[y‡(õCp\Ü<½L~N wR~Žgž>R'= §†ÛO© ;§æÒáj²Çá†àöRJ¨pÜý<ªD> ÇjÄÛC©9 §Ò4©¹Î©‡z(Õ˜çḃyšâ)à«oå4pNPÉs ¸ § èÊ+ÀU8¾Êx’v¸§þËQ^fáÔj‹9 §ÞØFy¸ ÇJÆSKÝæá¸ñy[)owà¸ñyjÇ»ÀÜ=¸,å"Ð(› º¸©•—€e8–öÞfÊ`Žç/žlpxǪÔÛD‰Ùë ³;c€¥‡ê˜½‡ciêm Äìõ$KSÖ1{= §+ÒzJÌ^o‚SÓàß:f¯·ÀñÂ[G‰Ùëëàøúà©ÔÎëáXêz-”ú  p,­<½•rœš°‰’³¬o†ÓUO‡Á Õ³pjÌ4%³[ß §«žNeêÛàX:{IJT­çàtÔéÓõpÜŽ8%ÝTÇì–ož¦ŽN¬cö‚š:FI×1{%¶«¹ÇuÌ^…{@‰{꘽À…ÖE·:Ϋcö+w•×Ö1{FwѼŽÙ똽@£»Ë”˜½ŽÙ 4ºK¿Ô1{³X)¸÷(1{³¸ »ôZ³×1{å »@‰Ù똽ÀEÚ¥O똽ŽÙ \Ý;”˜½ŽÙ \]z¼ŽÙ똽0 7O‰Ù똽0‡?꘽ŽÙ à ÅÆŽi—~`†}Ž@‡¦cÖÉè,uúšM˜fRS¬¹—(RK2J_ ¯Ž˜¦€C#ø˜Ž@í£«€‚›‹À%à pÁbíÚï20\æ«;‘×è, ïK_µ”.#’¶…òpX{À° ¬«À}Â¥K·-6õ3}_$ÜV‹}q8ÆhHi 4­@Âbw¦ý¸Uº¬Ã\mµÃµ ‘T*:Ú(0RBÔ¬³Ø[Õ»l:€í€BŸnÀ¶Y¬ø í§äg7 gÐc±G4Ú ”Ôôû-öáÿÕh0(‹H`ò#¹Kþ(@Ú’ÈXòÇ’•ü%`ÀbíÑûM“y OÚRy“ü9€œ$?Žä§+G~ æÈ_7òsQEþ²ÅÊOè3tm×ü‘WðD.Å#¸T~¸,ËÀ ñEœ­†ªOÿ±Þ€ç>Ën—²*0³›ÍÚBä*"W¹JXmHûì˜FѼº>K}óøÀ³À·€ç€Ÿ¼Á.ˆ\å «ˆ\Eä*ZVQºŠ´UÀj'€¾Õ6‹}÷}1`¥«H[%Å«¢y•쮊ÈÕœÅ^øvFøêN᫽ûÑË À«¢yµ!÷yâXö¸ù Gú*ðZÒÇuÌÄvU¤JXW¥-ª´E•f¨öYìõWô.tIUùÛ³Ô÷Åiq¢YSGTÇÌ:Þ§Qú¥J3TO˜9#âè’ê@ñÙi³¾˜”°)>£Aª Íh³ª¢2å`Sf‡ŸÒκÏhv†)Õºn6þæ(íS¥#ª·ÍÎ8âxîÓÖ’Ù¥mÑ*ÕU€«@õÙkïT¥*(bjtɽk@)”"&eJ ‘2f¿7¡ÑV Ø´™½ûíài€ÛÁ–€¬(· !ÊuäB9žÜ&³Gߪ—u54G¨ à0 <ó£$?9 ïÉíHyr½ÙN® •É }ÀN³¼ ·ßÏä†R™1LîÙã¾vˆarä.¹£fO=§1€Ü%7LÄ+9ò”Ü€%GD’#;É7ûÛ§õÚsùLî0 ›ä.„%9Ò‘\CîÏC¯Üš5"’Üu€`$7Üf̾ѬIGr·i¾Ì›}û1Þ”d.Ê/W%”‹fÏ'µ!f‰­’þ¡ÙË­ââÿOi‹)eÚ¢Ô´)³ŸÏj:¢Do”è—’ÒÃõf¿yR£¬_\𡤏°ÃâñW5 DQÑ`§ÅÛˆSz¨h°P ¸P H3”zb±Ì0 R¢#JÊî¶[<û„Þ@1 ²;:¢Ôgq§C´J‰>(¡yIqÜQ@!œ¶!‹LigÔ/)ÅCÆê—¹4 |iÂâ#¿ÔÎú¡s£JÈ]Bîr—f€s?ñ”vFýú–з„¾%b¬‚–¹J×,~ñËÚ¥Kˆ\BÕJ—ô-¡jé–ÅuO—»tŸôKåªÅW¯iëÅ_ÛÏV„ã#³ø;别@”9Bä‘#¸D¨¡j„ærDb!^”´xa³ÞŠëAÄ£³GÌF¤-ô¶Xü‘Ú}#ôÐ7Bß}#t‹2~°®ý;Ââ&Žm#œõZü#o¾Õ¥#¤¸ Dh¡[„È"G J‡-¾VÖËÐ)õ#Ô0q$ÍqwôˆN¤J€T]¶øË/j4$-13¥R‰b+ Ì°ÙâÿýGP¬¨Ìp# ¤°PØnñÿ{LûñÕÃíbKÐi‰Ø/4@>È2/Ã2/Ã2/ú.Ã/„2¬ë2_"~H;+¸ðô·¨€–P^&ßk‰u¿¯ýö$v,î2ù>Kd¯k †-ÑÝ#Žt޵^†e^†e^†e^†e^†u]†_eXÜeX¾eòG,±cI¯%aãwFÖ‰~]”aÕ—aÕ—aÕ—aÕ×â’xò;£ ËÆLþ2p¸ äiK<«7½\f9`¸ Ü–ý^1,ʧWÈø ß³ÄéŒvQH­Tš¨ÀUÌ/=®-’åJ@éJÊóïÑñr¥ hµÄÊ#âмÒ |á+_AÚJ'°Þ«_ÖÎzV€¾¥¾ÚRÖ«pw«%ÞqMû!|Eá®(¾Ýi‰wI£Jxß"mE¡í@Qí ÐPÿÑïhç>`PðªTuÈ–Ð(êWз2f ÷¾8…¬§€qK<ñ)qd®Ž-+§-ñ7ê¡ "W¦ó–øä³â¦¤­ mi+H[A· 2V.ZⳟÖÎè[AóÊ U+¨ZAÆÊm}+s–øZ§^q@ß úVî i¿;¬QÉýPy£J¥êKü««Â?·Û’Ó¿T©0‘  ›±ÄM\3Ðd‰²¡@v Àcÿl»%~ºA¯ Èn¶]–øÕG4@íxØŸÝ à߬ìzœ%~ý¼^± ÞË’Óe æ²}@?°×’ñ“Út.{ײ–L¿C£z˜¤$aË‹eZrãAŽÄbÙ3€íS–ÜþQ*W¢} PŽ­zÚ’»«]® ©çEÓ7Ò\›²Š¡o Ÿ•,_·äÀ›òðdÛM°µ,YrâE (m¾(OFÐ"E¥Ã«–<ùç*õc§%kÃ*3@Ê’³/«$I*"c‘¬¨Ø (Vþ‹PÅ&K滵s;€ÜE%¼›,¹XÑš•ð¢[q‹%ïýBJ•×¢eQ‰,ⴸ˒oSò]T,‹ÒE¯JU2¾ë4ª¯dº¢+Fí·ä#ïÑ€’VŨ#ÀQ`Ø’¸«Qe© EG-ù‡ªE…¢“2',ù×U2: œ³ä'~-ŽÄ³ˆÈED.¢jU‹-ùôsÚ…øÂÕ ¢eqÎ’•g5€æÅ»Ùb‹w,ùõÏit‘hK[ ɾýqmÝ·Ô¡qåƒ Q?@·À,ùo_ЀRAt ”¿54úáû5 ÈOùs(u딵!E „™ B½ú¤^Fâî¢L @ž=4 Ç” °PàXòç¯èeà·`@…¦=@Š€é †,ù?©Wಀà:˜ À`äS–ŠI·¿ç€)@Q2 •O[ªéqíŒÁ  8˜Éæ,µécÅo2ÜKå~*Ž ÈÕY¢G°d©ž5 (×½O.¤)^µÔÞ·h€Ç½] K}PÏw»xPÛ•x<ÛÕ ðP¶‹Ø¤+e)­å›»ZžÂvmPº¶]@‡¥&Õ~¤(]Ä&] 1·YêÂcØt;P¦Ù (ÉÜô»-5ó½Lq¦òK=5Õ++Xê¶£]a`8 (e<ŒYjùÍC;Lç‚S€bÀi@áß%`8k©·<¢×*¼(Ï›”âÝ”ÝÝ–€k–úÃwée ðVž¼wI ðàAišÊЀ’3Mö²¥Þ{[»4Tø§^mµ ¾ÚÅ]èQPÈÕtë,õøŸêZ2Å„*(¼BŠ‚"+ô(ht«¥žœÐ+”[!EAiÐ^K}ü?4 °‰I, [êS?§pˆ9-(Âa: ã–zfJ£“[PÐÂĘÉ€P¥Àü.Xª¢.)0íf² ¬ò¦¥¾ùn 0“âÂ]€¤°{ºÊÆ”Z®Xê;_×+Vß5>÷F>|ø T¾| ø2ðà«À×€ƒàA G P®]B¥Ø%T†d¡’ 4 •W QˆF!…ù¡¥¾»¢d%féÜû´…™Â†%ŸT¢eˆÂÎÆ¼Àa¼|x©±˜Ž —…¨¢jˆª!ª†¤ŒáK½ô+½"‡»ÇR¯ÅaΑÃ=–zõ3âøÍ±+¿…û-õŸƒ8!†˜3$8 Ç€>KEê↤‚!ö qhH«„¤}! Ò !’ì…˜)éœS|~UâãøøÃÇ>‰S|žŒùøÃÇ>‰¬S|î[>þðñ‡!|²YŸ0ÖÇ.>ÿñq…S|"XøøÃÇ>þðñ‡?|üácŸøÖ'<õé{¡|„òÊG(¡|„ò1‰I|¼å“½ûXÃÇ.>?Éð1‰I|Lâc“ø˜ÄÇ$>&ñ1‰+|_»øXÃGxá}„÷ÞGxá}„÷ÞGxá}„÷ÞGxá}„÷ÞGxÿ–µ$ŸjH¶9Œý?§ccÒ endstream endobj startxref 660685 %%EOF krb5-1.22.1/doc/pdf/appdev.pdf0000664000175000017500000320177515051422764015657 0ustar ghudsonghudson%PDF-1.5 %ÐÔÅØ 1 0 obj << /Length 843 /Filter /FlateDecode >> stream xÚmUMoâ0½çWx•ÚÅNÈW…œ„H¶­ Zí•&¦‹Tàп~3Ú®öz¿™yóœ87?ž×Ûö¯nÝkõâNýehܤü¹=77Uß\®;?:׺vÜ==¨ç¡oÖî¬nËUµêöç;O^uÍû¥u#ëÿ¤Â½í»O ú¨Ûû=Ù˜‰a³?¿ûkLy 6FÑæ/7œö}÷ Ì½ÖÚ–][öH<Si£¦cãݾké¥^Ñ90¡j÷ÍYVôßü¬H^œÎî°êv}0Ÿ«é‹ß<‡ÒrLŸ†Ö ûîͯ_®/Çã»Ck¥ƒÅBµnç«øy·§¦Wý×øæãèTHkÃý›¾u§ã¶qö{sÁ\ë…š×õ"p]ûϞќòº¹KÏÕµÿ u”/‚¹A² )`JbD>`´öØ2ãš™$`¤TY'`”(ZqŠÇÁ¼BJÅŒ )KÒÌŒ%553<Æ,£è(‡hþl™×wBš6„‹0¦Ða™G„+L¤gıè«cŽWÀ c œrn œqœø9çÖÀ–ã°MÜ—8%Ç àŠCMq.â†5„Sâhr›ê›®®AƒáúI‚Öå皎­ú\SåþÈ©¿ÇÀ á]8 é`Y‡7ÑŒ1OÊyeäµñÖzlÃë,d mYĸ”S£SJfß-›1i‰:C&e c4ÎRÆÄÉØˆËÄ$D&™ Ë Æ&+ü¬bLõÉãaÉjÆ çÁbôÍy°üœ£‡+çÁbèÉYB¹ü‘þœõ§Ägý ñYJõYŠYrÖŸb–œõ§x(rÖÁèœõGT“õÌ›ËÁ`F+ƒÙ­L ,C9ô²â?d+þ£¯ÿ¡ÍŠÿÄÿ1£ÿ1—ÿ¡ÓŠÿðÄŠÿ˜×ŠÿT_ü‡~+þCg!þ£o!þƒ_ˆÿàâ?ôâ?åŠÿÄÿ‰/þ?ã«„°øY ñ³â?^ŒBü‡Ÿ¿\–jò‹UPñœŠ{Åð¡âxᇻLöó^U}9pQãóq½÷›Ë0øO}cèÖÇ}¿ïÜõ3tìÈ¢}¿Æ!VOuðÊñË· endstream endobj 3 0 obj << /Type /ObjStm /N 100 /First 847 /Length 2121 /Filter /FlateDecode >> stream xÚÕ[ÛnÛ8}÷Wð±]4­(J Ú¤M‹î¦Áö,Åv¡Nìõ%Ýì×ïŒ7&5âÅ’/iúPF–HÎÌ93Ã!¥¦,a’‰„Œçð/a\iÆ9KsÁxÆR•Ö%<`™Œk–§ KS–çi/LfÐ[2Y–L¥9N§`2Áa¾‹@¢€¤BE#€Ew$ Å#àI%"‡¹Ê)%~ J ‰<ç—B'SL¡p`K}@= “€Ö2Î@˜–È>0¦5ºP¦5ÂR OÑp…^•ã1øjR ¸ dqTl‡Q›AsàèU¯pª”rn |( xÄ¡0ÊI‹¥Ó碆÷¨W¨Rä \Bö^¾d/>³Çã/cöâˆ=é_•“ùpúœ?e¯^õžœ‰B¿â,I’#l†ØÜš«6cl&ØTØÜ`s‰ÍY’%ø÷‡y6Çæªþì›Ï¦yÍ)6ž:Ê͆ýy5¾yÎ}ê`SbsmÔ[ Yн3j.ŸÍbó§îüŒmÖ’ÊÈœ ¦uÁ}sg)s`®nì çJ­™¢÷òÇ?T½3²2#oÖê-¾sm¨±*Ì#QSšÛ¿¢æÚ±jÆ5ë%ÕmèX5 )eh,(©‚VÂjäY’'&}dØ|½¿Íc&¨€ Wúª×Jè9µgþÜÌ`§¾¥öL[ÐÞÈ“gPÉ÷& OLó›ßë]ß`óÉ ubüªÃ;3d9×q KHKoÍÕQÝ”Zâ1Mip:+‡õ ‰o¥‰®I —¦ûYZñÖZýaž: ÚÒw¾7²ÕÓà’îYÓþ2ƒKÇSl–W夓±'EÚ0žFƒwVŸí Óqè ›q«;ßÍøeÀåu_¶4HžÓ…lOê¡Ê(rAM·”ôý&ؼ07>5¤#W]ß›ÛÖˆ dëF_ê·?RÏéϱ£s´:[A•u­F{[©2_¡ø‰–Hxæ%¥nåf•ÇÊÕ3ŸYQÅ=ÑzLŶ«¬ewÆwÆ4¼ö½'d¾Ò& VTR#‰ô}|y¤/Îk øØ?¥î}Maè¯à­Å#'V­ïkõðù'Í ÊÕ`×Ê}~óÅ穙î}?¨ï“tò·q F.]KNM<š¶ä:%ï•“Ÿ¡· à÷Ñdº¶íª­›xN©ˆšå©éßš­FIcåÿ=ü'ûF}Ú®œw‘DV=ðʱZÄòXæ¨èÚ^QrGNUYR#&†®Q«N`MŸÐºm¶¶]Ù&c»·&É45®d[˜[”=«AR¢…­ T¹Á¡Žô­Þª±M±SKðÒõŽbÒˆQë“#cF ðuI_…G†ô~«µô‚.AÌhjP-»¯uìIOetÔ;L6‰$â=o‚"ê~D@ë*ï&rȵðœ3xAê×tŽ’vøO°¦Á˧Ï×2éÛ? •÷ƒÌØúï}‡[‡ÂÇÀþ³N.ÐaH÷Ï×4¨ÜßÒTo—±sš¨‰ì©QiAí°‰aÕߦëe-œ)} ÎÔ8¸ý%ÓňrsI_•P—Yx’û2EÖܾÄ}à³x=p¸®w¹]­çn¡ú`"çÊS†X~Z'·n@‹«’®%a/ol)ÇfÈ­ÿ…˜k{É{dÀJ-pWû}×X´8™›é¦N…?oDøôQrºž·4ÙoÌ7vJkÂÍQûqåχ)Ý L ³„…!YÐ-`E5w7ƒýÉ«éÖ RàØvÓX¶‹ë°S’][Z6Þ”“qcç¶oNÀ‘åžxÜ~WÙ8`ß]bÝHµGIžÚy1/ÞGþjQ#¶^%[œ¤.þÇÿÃÆÓ<·^Cí»‰õÛ Jã¬/¼ß™Ò÷ïó8fMáû¯Ä[™3I}zÀ_ù÷©±Œ}2X:{ëµÐo¶¥[—Óö[²M·rå£Þ•‰MVûF©Xû§¾Ôwx“æF^XDðD¨ƒ¼‹uŸv¹óUž7wîAQ×6Jê–¾ó£ªM9œ8™²ÃWVmJ³ÒÿRj©Å:hpù¨×ç@ÒÜf¿äèê‡ë9Í:Ö¯N›¯éî{]Q/œwÚ^†>\©<Ÿ>´©1ÚjóÌxL!®èQû]÷WAûŸÂÜRk[¦Ø¬cUsAceè„®EÞ®Þ—Î ÝÀÏ‚¼¾óÉóñå{ A:ú^Å^™;lÅp ìL:œ n^žD>]n°žíõyÛ×*­™½fÑ›Ò÷Ww‘ÏN}z¶¹;àlèN‰~Ëån-²náU£ûšwIKFß·¼{ ´Ý€iC¨¥;¨Ý¹Ãö'P1Þc[¯Æÿl)#5mcY»Œü§ ;ëöïI‰ÿƒŽ¦¦ endstream endobj 204 0 obj << /Type /ObjStm /N 100 /First 951 /Length 2327 /Filter /FlateDecode >> stream xÚí\ËnÛ8Ýû+´lhˇDQ@Q “L»èfÐf™ãØ­ÇòøÑ4ýú94Ê)Š’å4r ´2CñqyÏáå%E’‘ˆ‘4â?2Šc1J£XRü²(M~“HÒ¿"¢L =Íȃ‘ˆŠ$A€#ñcqD3¡bRˆâCºX¥á(2ÎÃYÄD‚‚9bE†’¹ˆ8ÉTLqÊ“ˆ ¢˜XG’”§*X"¤â€&9ÔÀ¡T½Eq–@Å Ò8ƒ\aš$hW B¿¨C¡*¨@ÀJ#(¸R‘2`‚Î8¥)…®8 Å/jç@Ц 4Á.MJå@è¤ðRI¨qàKeŒVsLe‚”¨Ìâ!B1â€ÔÂÁ€Œ€P:ÍNÿM¸"*a‰âW!™@$Eö õ EO©x¹`@H¡J)´Õ!«önð_µw×R`ɯ¨„ƸB–Q%‹TLGq´Ý(s`ŽþÀTçR}E(ñXJ—QS„æŠDév]@1]…ÐÖ˜£8Õ7UoBñéèíÛèÍ—èÍÇ⢈ޜG/ÖÛ+õo:ÙäÅâ¯× y½{7zq ™ñ?½$„ܨÇJ=®Ô#QK0CýÎÔãN=®÷£7êñU‡£'º¤©Î²Þ% 1Q¿¯öÿø¨nö£Çûìê/t±w:ÁJWPVõ˜éB—~a¼°RWª¸ÕIë¥ú¤ŸÕãoݪ3÷zœï§¿Õr®õc¬U¸{ñúe#t¬t_+ê}ˆ.u6ÓblÕcn%-‘ë·µp~6ëÛeÎuÜwzL¿KõÍŠ‘ï!i­|ÊŒ{QæTgY™,zL€|›¾Q£³K’ì~—Zˆ²¶\7h§Ÿûý|»B~è‚§fÙïX µò9›NøšîçìoæºM‡½`üÍTê=¤¨ŸLM_™–mm”e¡ßUài…KPÈ^ p/%i7šî¥º> +æZ?r³ªÂÔìÜ6ׂߘ56kM§¶ø³I3Ý€¯–Së¦~EWÆ…­nÀ¢–ds]ÁÚ¨Ðt1üí+E×lt•Š jûWÒýŒí3“‡syl’°³iknH?ãj®õ™·p2”ýì^gëêÛ—¹»¯hš¶æx½(ûœ«TZhØ›±9ÞŽ•BüzÜ íÂù*|.tYN$ß×¥›nŽS¯ ýúîÉh`صeÝ1Ȳ6ì­®¸b`C±—Ïû™™¯Þ_þàIø\àkF"%ωÆgí~77]ÿuoÓǺ·±fú5ÏL?úv taÏ–.kwU_zå˜&>&õù€q¾xù†ª¬™ÓÚÁ¿IMÎ-q@<ŠÉ£…ÙØ{Ý“ Ó£jÃ{ö»5µ<}ï$¢ËpÃÄÐ6©Ã07ß–fê§ßC9:áúødù'É¿o&¤{‹§©–¦ûµÖS—ÂüFb¤¯ø=ËNÃkÞú›ôªM{^…7æT)-ÉÐ(]ÆÜë|ÓÞ]¾ÊÜÿ®nMÄø–±0›{ïȰÕ¦œŒO(Ù éõCgÉÍÒíq½a‰´-ïîkY–ÛÊ7hŽ nÞá[ðMÜ^ZŸ|Kcs£‚= 7J0hƈ߈1©\Ÿ•Ú°©v¼ÆÙØçãi“Rž)Û­Úv°` ™ $ü;ì|îóÓ®q(ì©Î³Á9ë{ÚîÝ}{\jömúÁï¤G¶lpzQÁ÷ ÈU©òÃZ1lpýÒÚ5bÓf«.Ýo[lö¨Ù”¹tìÑÚ:FÎ…c#bã`ÐŒ’ÃeÔĽï? î4`qô½NsºËø\`0RnL4p[àz¯ü"µéX¦ÑãþÕí<óÓ¶¦Ñ‡nÌ¥„ ’d~{Ñ×2üQMÓI/ºS†˫B¯yçÏkÒØIÄS*R28Ÿ~eªho®e°f¨Öi”°7U¤³tÉYVr{RŽ=%b¸<[›‡é*GâV=ñ«S}3ÓNNÙ•§dp¾üÚTGkßÉ—¿f&èRõ­Ã…Ë­ƒæuÄ£ƒóï7ZÄͳ«ñŽ>×=x;à œ mktý¸Ä•y†ëˆh/'_z;ÄÚB`ßß~ä„¿rá@6âØÜºmkãâBH‡ Û–ÚXÕØ¼cal­!û ˆ~|±ÚéÒÔÚ¬ÜËm2!õ<‚ø ¨Y` 3v5› ]ž]BûöЀõã}wG¸vÓíŸíjîgdë`=+´ A¦¥ÒèiøM†SçgŽEÙk§ˆ–ye•e û1r,îO‡¥£>qË>iM¹²˜yS=ýÞÕêÕ3ÑëöWª,Mϯ\ÛÉM_w^Kˆ Ï÷Á;ÓÆTLÎÊïc·•*w»2Gô^„ Z u©×JǼv/5LÉ{B´§ë¥ZXˆ;sjö}¥ÎÝ \w¦!ýfÝ(V¹Õ'PúþºZe[F9Q xKççÆ=°ÎM OýFÞ—ú [aŒ+½*—#¶¹;†rÖŸZr‡kÕæ"+ÿ{­u9?Ö¥„ M9Ú >”LJ¢0ýCsâ)4×ö8G»Û¨Aßý!Ú•½h·4ÞNm›iæu_+¦MÔÜv°}Œ6jfчriü i³#)Åy¸ûÅ„¾/ 5µØ'¨Ž|{¶ý«pÞšYþÔæöÑc¨®‹ñßšîXé2ßø ÔÔ´C+ó[íÂýElö$ó³Ê‡ßÂ,ú§{]ÌÞ&Zz« [¦Æþi¢ëÔâܽ¶Pª2î–£ÑҜ笻Ï<3§±ßMÑë{ëN*{%¥|²ÛÐ6/&²˜ÑöRÃÿ*SD2 endstream endobj 405 0 obj << /Type /ObjStm /N 100 /First 949 /Length 2503 /Filter /FlateDecode >> stream xÚí\QsÛ6~÷¯Àc{Ós Á™NgÚ¤×Éäæ’KÒ>åE–d[cÙrM)nî×ßÕ$Š¢•Œg $‹Å~ `±XZPA(T‘¬ÄOId†[ƉÌqÏ2¢2…ßœ¨¢ÀoAX&œ¢ @ÉaŠê'AO—„3 b®P9 %á¢Ddœp ž"ËHFKÐd9É."+H–k΂¢ 9ëA„@M&Ù‰’ˆ\ –€H¹B-y˜ Yb™Y@!srýª 9WèLNIžq]•‘\•ú‰ y™©‘KRHô \QúUIвD`ªh†– èBh%P†dúUAJÊÐÄ-)ZŠ‘Rè¾+‚ÈO„’¤TZp¥PPš¸$Œrͺä(ešw™¡TèŽâ9J ¼ tŸ)")Õ%ôCBÑŒhR6”dv"©$ +)ž)”8´-#ãè#”‚6x^k½³ŒC×Zv” ©U†R!Áo h9¤FTl[Ó¾m“×¶ÊÌ\,ÕÂÍŸ÷šöT_,k*\»ë”C¿2mûòW#6ïZ¹?RmÜ%øÎÓÅÊ{lA©ÌåÞ%Ej,OtšÇèȋ¥÷¸Q4ÇhWF¯O±Æä¼¯º«ÀŒ7 [é…y¼ö¹tå^ºçE;Fï]ÆV9s׷몗 3C¿öܲ†aâÐ\a?»M=üiãÜu@k3–³ºÝ$Ùe †ÞRwãÎG™Ûs#˜ÛÒh£òl.V©Í Ü¿CÜÛžŠdhCPu1qm`nôUÙG>‚}Táéhâ‚î§c ?GU™ta;û懽Ö•‘èv”Åç•ym•4‹]rÞ˜åë¯÷ÛÇ¿êËãµ½Õ—ÿ˜f5t•þ«/¿»5?êËk·ú#ý[Cð.!Þð²%$²1ªˆ5‹‚>YŒ= |ev; Å ÌŸå´Q¾»áµR4Ïÿj!lÀû³+˦e–^‚»–UýÌÆc"b‚Ç7±JúðËbÍi òÖpµËëÂëêóÒœRÞ)^›w¯M¥§Yiò£1šç…'ÅJR½á†w-(ëøÎ³@¬ÖÂö%ÖÂÔÑXØó¢÷•­Ék JtœæÛõs#ëÆÈºîÈó6p´zpv#_ìQMÃÄÐв5”¹f=wCŒ³á÷ÊŠ‚mlH>ˆß‡ÏÐÚ@LL´×‘õÆ=þðñúƒyç¾ -é!w%Æø¾YM»“ÖÔp†GÆ7l'}Ë0òá #õ<8m~oÀ=õÌÜŽÃ¥§sÿŒ¬¿9Ä¡ÂnX¬QͽWóÎ\ú«v gµ/ÊJmôÜŒwÛ•æ7+ã`8 KÊ›(é8¨Yk­¹t )\ƒ j4&¬ ›qçʲn™G€°ïÓ–xíÒN½´œ}¦“[réšÌeÄyO¯¥ªQlÿ(pUoˆtÅüÄÀøí‰öÉjtPþÍ5йkÕkϪ'áÙpéµ2xòçy _§99Õvä³it5YÄ ›è›Ø£_nï©»ƒ'ɶ‡#7-IB«=ó‹-ÛÛ@dcÈèyhSªqñ~xWÛ.ïkÇŠ|Ø7Fõø8H²ËQ7¶œÒ'Áö`yúßÐø>Pú=§üÈ ï>ø5_½æÌÜDD©Ð_‚éîã…EÜ„tŽEýnÔwïúù·¸ttn÷ö•iù¹}iŽ4;e)¨öyÊÿZ]º¶¬äØÿÆü4?e§Õá} ß}éõ½ö­ÀÌÛmŒÙ,ÝM‰?vjŸ8œ U„':®B_¸÷xXt†Û‚öÝɼq ÏÜÛ•çQýaz¸×µÃµé%•<`‚³DW#ߨÈ£4qP#Hôyk_ˆÕöÖÕq|hšªæˆNÍS¼D&¦ÔÚy`GòÓûÖ”aw<»P+ NyÃçY¥ O~0x*÷ï."žþ!ªÊÄ n4|]Óp «¾”æC¡ê¡ F¯Ì¼ñHpï¢påMdwÆ­» Oô~Öa°½öña½îÛ€;ØéØúR­†I2ª}rë´i²Œ…gÖÃê½vB:›‹0(N{TÚ¡ÌÒÝlZÕ<¶?öÜhìé~ç+œó¾ ­Ü¿Êpmžùšý}Ö_ ãE8ScÒ²ÇHz _‹Ô›–CÓ×é¥ÏNÑâŽ^ûøvHH@=3½[¹‡ ¾†ö )N¼<ã¸F;sœÛsã–ÌmU-AȶÕÕw­B(ž6Åç±–¢Æ²”¸`ûpF×Þ³}´ÛGÖÇK©ELâ6ƒ~âY àºå(,é*FÏüàz¾¤ÅÕ¶EÕ°Ù9›ðqX‚šûï$còsj‚Üž¿¬\WóÊ£b #BÝðýËܕߞ\{#³–cÚa1‰ÇÑbì“Û†ÿÍ€–x>6àic»×2ÛêJ!¯Ž0õ$€mc¦öõB-(³J Æö=·L¸cÃYбqNK¶Jů“{ôÊøzP‚ ¦]úÇI©Í± {‚©F{›ªÝʬ¨gHÞU,úâ©ÑßÍ‘y6…¤ixtÿ¨1\l•û§áaÒ³ôо(w´k’nÜE¹áƒÎ®ŒmÿÏqª. endstream endobj 606 0 obj << /Type /ObjStm /N 100 /First 951 /Length 2247 /Filter /FlateDecode >> stream xÚí\MoÛ8½ûWðØ.°-?$RŠ^¶Øž ,¶{ÌÅIœÄÇJ-;múë÷1h(S¤dʦd§[ UG4?†ï É᪤9¡DRM„&’Q’å ÿ ’i$³Œ0ÊM‚‚ MJA˜¤‘He28á,7BAó‰ä’p© ¤h•PD JSFDp&!dDHÊ!(šɨ‚xÉÚ‘‡6æ§,‡PЉÌ$É)7?iæ”ä9…bÐ ÏMòŒäÚ´•ã/5må( 44”¦.F%þj4(eA©‰”’(4 íHE‰Ò)J@&%#…P¨µ°’ª EaJ ‚)Up¢¹6BN´ùD’è\£Bmú-,£ÌT ¥ ™ºµA:—…Qç jó+°¦•) °9$)ž ÄA’z¢¨„$ŸòiHÊäƒvŒ3ôUKHP[6yÀ•¡“ç % ŸÂ@ª ¡Â`ªÀ(Ya$´!r.' œ2¡Ÿòi#™|ЪÔZ!)´‹þ±L1€ˆv { YΞ™0h¤À-ËenÀΤ‹‰~ –†Z@/ƒ…¡ø>¹‘„‘€˜ÂC§Q£gm ¦$C/A2$”S`™O¼BÒ¬YaÌG¡<¤eÁ4Ó F¤@5$X‘‚¶LîÈfÚ ¡À6§¸+Ð )ƒVà›Sñ$åF*ÄD¡§Ê`Ê!¬À9gOº dBSpŠLà½5m€sŒä.´킚¦¥‘Ð.&ïÞ‘·ŸÉÛå?%yû¼ª6çæÏìb=/—¿½áYñš¼?yu&”Ä_u½oÍceçæ‘›ÇO¿MÍcckó¸ÙþíÂgýên·nƈG(ù dg<âÿd-1¤ŽîJ%ŠBöãñððÑO>¸ úì ñà~FÃÝèžÕÆM[µ¥ 9ëmjKôï´9ëém]Խ픠[ù#Ã#½ðzâÐð§‹Íew\°^/ÛB´þ6h§#=ñUnXê–klˆ.½æn†¥gw÷î)ÅÒ­ÿÞíY Ñ2 Ñ¥mýÑû­AFÕæoÖ4Ç1P‡B՜̽ÙëKÇéW̰˜Ûêvç,pØåSZs;öîýÞ=Úºh›#}WuÀÁܨ&„E„Mhz¨M\wœ­ÔÓx=q\·ÚÂÇØS“ÖjëØÎ³«öMÿ[wÇÌšD\¿Plßã縰ì‘`*!¹Ú¸g‚Ï¿-m/ïF¹ìÔeûQ‹.þD} £ë`¯¢9?tÃÿ©#ã) q°Ó° mÅ;ü«!tÙ-¨Ñ7\ZÚ; g‚¼¨‡ŽN¼Ðìu ‹þ`U/gÁ”§#eÇzp%Ú+þ¼T¼ÞWî™ãÌõ@vÄyºŠŒåB­-9Ï)øÕ~1‰zÛ÷¾…œ8¼ ¨LGå¡û£Ï.°«wa”ÒŽ‹GƒÅ@ÄÕú_¹¡Ì…—5Úï£Ñ`øê\/ŒÄK’+Duð.4"ª^;Ùò‡ãIà¯ïæ­<"ˆþ¸õ1 ÏuþÓ?¾·ð\üÆíKoÐXvÓ0z’3(ËÒ™JsÁêë¡î\út(O“€4¾ÇÆ¥àU·í¬ glÇ‘ÖwD×£âÎ…Ô÷÷nÜ’7a_nT_µå&v‚•—¿ÆÆ)AŒ ¤qcúûÉ"v;zHj‡ïÓðïïÜbïêKÏìæafkzѶÉj¸ ôò½½¡†:N†{U~«‹Û¾RÍÛ¬ûx®%ãX–Ðx§d+1ôð£ÐSÏš_‡q•æI»å£´²c³½NM˜pkó”åÀ†WÅZGvdëøÖíM쵫ìªvÀÑí{^ɬ*†B™˜ÂÛß–xlèfÓ2âëÑЗe†WÇ9ŽH4K7`™º¦Q…¯“=ö™ìeÚÙ`Omáî7WÞe›•é^yGŒ{(Sw«ÝnOÁ–»­§194.ÍÂæ`~dèј Ú¡—…ØÇ Lã2ðMèmÄ2¿ÇØŸzTÎ`¯ÝðݽWgµ+J=s7.õBÞu‡° w· ¸²×4¸q­³e"ácIû8Ž-w÷ú´ß½D`­\¿ð1âÆF¬Š1ðe‰ákÜ5¾tÞiJäM•î†õ{Ô‘K—~ w„FÏmrXH#þ‰²ûÿ@о=Û÷îý^ª%¾&D‘ÿ¾ÿÕ@z˜ûjÍŒ&F3îË¡€<Ê×à"ã‰1LO~§:]M&Ç+ᢔnŠª«µÒù7°e‹%áÂ2ì–§Æ'±¾©VyC1ôÙê2|¡ðHû¥®Reød¦ÇTäG§nœ.t¬[úÎÅ}ª endstream endobj 807 0 obj << /Type /ObjStm /N 100 /First 942 /Length 2307 /Filter /FlateDecode >> stream xÚå\]“Û4}ϯÐ#0@%Y–¥†(Ða€¦exêK6ɶlbo üzŽL+E¶l˶²¡ËLëȶ>®Î¹÷êêë¨$”(FI¦ñÃÏ3ü Â5ÇoN¤0÷ŠHeî5Ñ( 8'ZäøÍãå¹D"× Å ÂrɈÊ(a’âUÆÓ•g¨”R…DNx¦ME¸ÈLM¸*ЀàhR(´šñM ‰„ÎJ$“F¨²¨Uå Bkäɵª<'‚kT˜+"P M„2õHŽ„F™‘\0Ô#%9[(Y¼‚¨‚’\Qô·`Dò¢‚ÈŒH‰Â@§²0Xš´À+ÜŒ¡ •‘"(¥$ªX(…×”"³‘‰ È\wÛˆ¡…é$.µL¥´22¡„®Qf¸f 5dÒB‰|ól¡)p¦( ƒIAtƒ£èR¤”y–#¥Q«‡ QXdLHGÆräцI¦ ¼6T2H¾Ð†Kžá^2y&‘ϰɕ2)´%P@žeàhŠÑ`”eZ=A‚RH…LÓHE* V™0y4hEJ!xe¹$Ä"e¤³,×…I)£XÌ6dÝ´ÃdÝ°Ë¤Ê èEªà Ó{V@;‰JHh †YQ; Š‘æ-ÚP(ƒÚPk°Ì qx‹^!eÏÈH¢‘Êó…Ó °#¨FJ!Ÿ6š_³²aÆzÀ6Ó¦.Æ8dßÊQóÈMÕr‘,ŠŒÔ¤qª_|ñyò‚*ïo̿ͪÚöŸ|è?&_~¹øèeVHü/^RJ7—“¹Ü˜Kn./YV¿[™ËÁ\Žæò×ù»ºÜÆ>® ïlþ•Íò’ j~?;¿yªøÝ»åùMl+Ÿ<Øùœ^¡ó­ºöæRÙâî¶œV]ôµ­îýã±íÕYo„žŽ…£-·µ}[ÙÛ£íÆn¾Žj*‘†ÊʱòɪÙ_‡Lqí–öI]ͽÍ_ÙÛ“-ƒœ‡Ü­OÚúüÝÒŠàìhm_T-4< ¿ U|Ža£âƒ¯Bûíl}‹}_QŸ4«puê®ËÈc@U@u´mZ ®íÅå*íeÓïð¾ ÕÞïðúprxð+ö(Û¶°_ÚÜ'{ûW„׌í{/’&æåxþÄeôo|çy[‡I5‰¾hçrIiS»$ɳ4Ë%3œqÔ ¼ sçyksíÃåjkQ÷ìCÐ$wC°¸,Árì\ØæRˆ–ÜÀd:üW¡1 E˜>Áø.¦÷n—åL]–³ò²¶ðàx ‡ú$F4Tq±W"”ø…Qzüž ]^Ëí9Ðß6ã©LˆâÝ<ÎÍ{Ö±Z#kÍÆærcæÎÅ™­ˆÕ­ ÜÍ·Å Þe” A¸›½ WÓЃŽÈï¦Øõ¡ýª±p蜾ûe±º’0ÖhÌM* Ëqæ,x™b²ÚîäK×Fwv$_•ß“ïbN‰¬Û©Zc)té{ð–ÑÐëudß}÷àÛtékȺk~0ÁÂTÂHÇ­¬•t¿ÃÕ¿övð­èõ¤ÃƒNg<¡ ƒ²YÛJIÂÙ±¤q•¸š?ì½:­òb´º`ù&}T ÏôˆØÞ„·D—>Ç›pÜÓÀ%†Å„ÑK\ì=ÍÁÅÕhh¶Áó9Ü} (nÄ™Dè„AÄ„ Ôh"úëŽéhÂÁÕAߨ)Ãë¡{›ë®ÕËKêec«§±Ö°ßÁEÿ7’zk_¿;‚·M×Dë}'ímk}Å#ç¹_ÝÉ_HyÓã;g­Ÿ¶8]† :Ö†ê"Ü"ÓÐF§qeË{¸ÉŽÊÿ`.ߨ£ 14É$4ý¹Ø· ¹ÐëÏ{c‚*¾³R•-†d]À³µh´ÎyïØdÚö$Ûr5"…Ø¥ ­’¨HéwúëMÈÜà» ‡Pž&<óÙÚøTõ{â†Ý…W:X(~³ïV-%¤0ˆÌ»\÷~Ö×rðõlß:ã9ð J“°ïìå®åÂíÝú}¬R¸€Ž(<(PË Ôç«])£fŽbjdˆäFÎm‹®‰ÚÇþÅ®ßlŸÖ_ª ë-ç~ã;€SØš:×2º¾¹ƒgÈGßl»6ëpàÕ‰_ ù"1ùÁMß¾àzþZsH¦møøjHÄÐ Wò'óWÓ±¯lMXå݆w+gg6»êŠìN:ñ1v†³V—uBZú†Ê_]½¾ºŒÛ|ö(QËÎ?ûXÚ$1gýŸh ¿¾¶„"àtÎ%n5qP†G®µ 'ŠÌG„Ô·=ç:£Ž(ãò|Çøa`¶å­°Ë/z'+Ñß"v4Õ>õÞ±~ñøÔA]_ŽÞú@¯ûc^Ãö&­#xt,sz}–Cë†nÄÝ$·üíMú&õñ) h%©_‡Íû÷=CyGèî¤t„mÂ3‡ÇGyˆnÖ!°ï‡ÑØúçÓÞù{_ѧòÆö"ä)W>÷w˜Àž)̤C”O}Sj÷±Oí½c•.ö^5ý7Ã[ŸÜ×-ˬ§l_·Ð¨k—g¿µÏžÛ5ÄÃùÝ»Ÿb™ ýnÍqÕòm/-g[yª.ÄÁ϶×O[ûýG/§ô÷v-i „;ëØÖ±Û #þÒ@£sËé'öDF“PØØÕlÆÓÉüµ¿âÿ$­Wb’O`²êù£ÃG,;w)Öá?ÑŽ:ÞFYøØzêYÉPÅ\P7á¿ÊQúQÔ˜} ç¿‹±ì9>0nj¿òµ¯ôDzÈä\ÈúÖ¿£õðYÏ> stream xÚå\Ý“'÷_ÁcrÇ T¥Rå[;©«««ìÙ¹<íË®>ÖÊj%EZ­íûë¯[ ˜a>${}.µ†îþuMƒL‹¢"¡¥¤ÔøÉW%‚ÆDqCh¢‚Á Lc#EYâCÆ ­„¡* 4}”" J¨+)Pß…ÆL” )TU!% S”#¥Ø3/HI%>å%)Y!‘⤔ûãPypEJ¥Qr˜žA ^V†„sнI¸ÈCh Œô² ¿U¥ñ ɉ(5¾Ì/%ðŠiz®(PFæŠY©*HI"9Çž+ ”BIUA¤6ªR |CqR1¨«ŠT%ÓÀC)RqŠi ”À§š‘JìY  4J¯%©*£(])ì™Q¬àH•@¡ QB›§Qõ&D£‚þ`D m(A´D[R°¸Öe”JBm^0x¤±<ÊEÑê7l˜AÙðaÊ(‰ JÔH)äiºë"i fj±GY¢è`rlÆ‘¹.(’øH› °?eLb8ÈQ0à@¡û²ÂÞÑËOý ¤%¸$’Ъ¬ S«‘üľsŠÎA±sN ÈÈø! u_ \#œH쇢Р;ö€Ü7Ø‚?PQIT¹ e Ò0¢8Ð$ÃB")$jNA¥,p¯ à«ÈÜH´<¿ U‰†‚c) Fðn¥>!§‘Dž uU%vÉP&ÉIxWɸ°)賟~"/Þ’¿®_“¯Èw»ý þMëÕß~ä\}O~þùÙwWe%á_uUÅ[,n°X\¬øyŵm5;~fª÷X<`ñ‹©}ð`©Cû;Û`r\½Àbg‹½åcš^Á$‚ŸÏ¿¼Æbe{ZÛÖ³ãV×¶•×ÓÎ2½µ Ï^bñÊòû§ýzÅ?²$Á²¶ÆÿõQZØ&ž01,ü¾ÕÄ¢èkâ­Uí­[7ØV3ò•¯‹{s—´á[ûò6òžƒ)4éáK“R1I=YÖö½?m«‰Õ"fÖf§ïmÿáCó_ÉÞ?70ï¿·šŸÅYÏ–þ0Œ±ð}h4ùÊêõ¾AŽ yÞ×Д¯Eô‹î½YTa3½Áâï¶» [÷ÚÎO‡öÎËÜ×,mõÄ7˵5ß´9Ò~ão.ö¶uz-]Â"¾±t1þܾ4‰–šh5(gÁ619»]õ"xåYî®µê¸Æn|U½tƒÓòP}cAžûžœ¶ÐËZO1ÿÍë¶e÷i¹]8Ö–õe'7—£ :÷½¥eü'žGa5ŠÂ·µ}ª ò­¿<6£”ÇïÑŸ&öñðÊíýïs­’·*N‰÷ƒ«Îšó®æÓ¡›Ûƒ¾IüE\–SÅF1š“~,ñ}#¹U°s¹÷·*€jûø…G¹½´}ÕFäŸ1ž*8 »pln©IƒnW…ˆ[TÐq-;Î º‰œ¤'ýÿX[ßKØ8™1œf ‡¡)öá ³ÈÖOï2«“0NìàÚåÑã,‘ó³y0ö=ü#ë•kfçP/¾u>‘Ö??ÛøQûΟ—AÇÙaÅÎ_'‘É3íµõbiYäXŠŸ2*™D¶ò« •›–æÁ´”[®ãI4«`œ7' uŸ©±–(­eÚOµ‚céÖdNçM_MNçÇš7}nÓ<;õ‘Më©_l½Í1©êkÒ…¿Ô/ü‘g¼œùê/3âJçÏ‘­Åz"yÑõo­œ$aò©ï<î¶B¨s­É™0ûÖIûv‡EÇU åìÓÓ¦©2qúñ¹}3í™Oãè5P6Ðn'þ¯ü•¹Ç¡ýóóØ‹‚E'ûô÷ÒGp‘ÿë9… LÎðeþoŸïžàé¯(ÔØØv8ýý!?ÓÁ¯ Åxvûë)hüScA/SÙÇŠ&â/rœ(hŸE©È›Q'Ñ{œ ˆ¼(°—¦M¢»@ÿѪ»öÇÄ4.oü”kÒW¹XðËË{Gë ‡‡HÐ|;úƤ)Ò wºØ¬AèªèNášþÞÚ×2ý[ÅeÙï≙šºëÚ7¹±oöÜ"Pî%‘Äæ°W¬¦½ÇâÚOãåNk¬èk÷‡¸¡Ó{ÝcCß—-j§ÝÎ߯Óaþ;¿Ú¾:ܬK¤Ü†ž ¶þ@d¹ò!žYpÃÞxï¯T9þÂFñ—“¥öžHžu¸¸Öºá~B>Áø(VLü(nëOkÇÏܽ¡µ»ƒÖÕ^$ø*8.ÜDî&=6ó³øý¦Pι:µùª6äBžÒ»†äúÙ á@ž”éÌ «Q@_…ÑÌ}¯ùªéýµ)%ñ¦Z±lÑŸÒúSö‰WÒ¡}rKàb>wË÷¾-Ho‡ÐºiÙLü¨3©MS´’c vkL}?~ˆ{|=ð'åÍßÉË~9áç1HF´þõXeuºˆ>Ç$ò<&ÉNƒ|u£¥kN$tuÐcãxçùûæÓ–/Š|'ñ3`çWçÞLãwu]¾N¤c&~4²m¸ŠÓ4u¿÷¯Ê¾‹oÕò‚¦æäÐdÜhÑ¥’ÿô³Z~¯«.‰\Ά{Cz05O„ó3çu{Mƒ’º?ä:Þºqu ¯Á¬ýŒ}-ž.¸‹TÝÓΜ9ùV#vÙö»ø5ÉèTs²_%ò´µ3Ü}êó0 ø?7¾çµ endstream endobj 1209 0 obj << /Type /ObjStm /N 100 /First 1051 /Length 2577 /Filter /FlateDecode >> stream xÚí\ÝsÛ6Ï_ÁǶwvðEœét¦—´™›>\ç’éÜC^h‰ªuµ-$;Éýõ· Û —(P¤,»—™„^Qv±¿€Å—¸`&c\d²Ä¿2S¥FAg¹ÌQ(2ÎJ2¥PâW…•à‘C&òL°Ë$S¾©Ì„Ò˜NŠLä ÓI™ £¬¤A2¥"“BˤdJ<“E‰6Ji¤ý6Ï”ÔöÉ”bt¨,–X^.@*°¼\f¹2¨7‡jäÂ~[dš),E3 êÐ<Ó9Ǻ‘¢”gÚØZ‚AÚ :@eÁ­ÍP|Á­Í…Ì Í­¤AÊ9JEf¸F’µÞðÌ¿ƒLa=dò¬‹P2 i:L™•Zâ·¥ÉÖ²• Ô£¨QÔ˜§DDrð— !É‹EPðä(*±þãÒØPw®øL2øÌ tšÄð½&`ÄlUZõñE‰o…µÝfC@^|Šû hVIæ%>\j 5“µ—%¦pŰ–‹Q9 \i¬¦&pU–˜+˜3›¸À¡ÂX"“+[y¬+(³¢A9'àP¬‹D<µÂ§Fp]ûôh#ì[ÐÀ¢ ´µVƒž"Ïí[…biß‚6DÑ ˜3,õ½Dkµnp£­K€ "$°(T ôÑ`6|”÷®FÄJë# áÀet ÚTÁ^Y“Ög@Á”My+sûV£XÚ·E&xŽÞQÀ‘èCÁ](ª š4DÁ€¿Ç XðWߟ½~Ÿ½~·ú°Ê^¿Í¾ÙÞ^à¿z¶[®n¾;‡öõmöï¾ùU„ÿÅGÆØøØàã9>>BÅñïÎ%ص_Ï\–s|lÛ ~wßÝçcŠáß³ö‡÷øø‚Wæ¥+xå¾°Ò­Sqå²=´r¶[e>–.ûcªÍµKµs™*§dÛÎÞÐý{;AÕþðï\-_7êÿãʬ]Á;ÏܵÏ&ýì>ž»ïœï½ùB„ø'-dãœmßÝ9‰x|F½¹ hœˆ ÊÍëç¾8)øC¯iU'¿)}æÌö;œ½6¼Þ>T_Iîö!‰›ïœÊ*`§?À¼wÅl\“h”Ô©üÑOß-EvåÏ»ž–{éñ覇+šƒš¨5¤ô9M SQ “ÑŸÝ:5×NëÆÕí’¾»M… ÷–z³¦}wS‚ýøßþn¡¯¢{#‰&ü·K5Ò±ê¡Ò] ¾‹&6íëFŠŽ~ë×ç1xs¢³räîÜ~³òQ®áMÈ~‘ ”x>@=$X¹.nwÐú÷ý¨¥4 áˆ>æŒú¨`*ZÆÊë*;Nè¤"ÜÙÒ8ï–6Ö[ZJ¨—B‰m8V®š1òáMgÔz|Ý̈´é]õϳýö`;ãíæùðjéÑ'4¢‡&~)ÌÑ0gMu­©?æíôMÝ›àrÓNЙ—li×ZGQýÑ©šGûƒŽã?÷‡Ø‘Øk€©‹NeÛÖÝx±SÐ?Þ\aîi¶&s×¼yðý¥Wr¤`àL¤á‘VAà3Öo¨¿çƒûJ“{š‡”Ÿè¤pýâûRÈœ Z«Î2ûȼ|€NÅ™±íWºœ–.Hïñ<×çü\ú€þêvA©2 Ïäv´Z ºöí¯iîèÜçEÞ—t[åʃ²‰2Iæ 3ö]…‡Œy @kÂýû „¶10ÈŸµ?4ž^Ñu9˜G&Y} ÕÍdÅßmZº– ¬ãVµáêX•Ò讚Qƒ£¶®¾×^WWÓ^²¡àFÂÐ4}͉@’P¯mj„2´`R¯/tæª ê†*nõ¾Ç†²šÀjL”Ùì%ùÝÝ–b1‹MUϘjº»òdÒ{ G ;5GÚk'+©ó3]¼¸ê_‰ï×›Òh/é&ÕœöÉõÜ¿ ¬°Ô=“•¹U4RŠ„’{vìâà?Ü0I³¡v~I¥‰A“9m(!ÂìÙ*Ø›oNƒ—êðȼ³Úüøú#Ë;k–5õä.Zù µ£ gDÏy*:êÈè h£æS|íÕ eI§|ë’®i›îÛ(µó“Ÿœôöå¯'¾Yjm›xHµ¦Óˆ…ÛÔ}¾`éšÞÞö»¥»ðu˜GkWV2 ±¿£ Ö$’ùÙÛ>Öøàî!ÛßýJóýe(Þc"º„Ø"ˆäOéùþ¿»á’ÝðD }톓€Oü³­7´oìt‚Cç‘•šyúÍMñ«šÎ¯¡ùÉ×qREWŸ’É·s‹¯«ãÍ÷¶©~6,hëð®È©>:×-)º^²wml¯òÎóõnßñ΂å*°í7 ¯˜d÷$è©fΆv\f,>{_Û×"¼RzMGzŠn+²’ò‹‹´þæJ·„û—ûøÆ½áåþkç…´S-‹„¶ßˆ¶©k5[ûÂ&0Ú&vš‰f$ðñN:5Ç@?Mس¤¸QŒuã6> stream xÚí[[oÛ6~ϯàc; )ï (0ô†bì[÷’Ûq!iäYvºìׇi(S¤dÒ²›d+Ð2”DËw>’‡M86# CÌÀ_Ž˜”PQˆcV¶B RQŠ¡ j¶‘jöîž#1="œYÁÆÀ«Œ!мË8¢ƒF¦lÍédQeΉ­)Â)bÔéçÂÖ¸{*äqckFZ[»9X ÀM Æ‡K[³Npãžjĵ½’ n赆 û Ô`­I$4¸Å¥±5É­…‘däYÓ$Ó Oq$µr5…¤! WY¤¨yÖ Å(ȳ•Òð®Hi€Žk‰4ujckü0i%Á*Ã5¤Ž U®¦aް橬6 2Š`¨Y¡˜`WPT¶pc©\ÕX«GÀ XƒPaCN°©ÂFÝF@pM¨p lA¸!lìmˆ!ÀŠ%4œ(âO)PA(ÃÄjPeý°U«j(„šãªV8à ^³, Œ]„¥aø" ´Lº×,l0@C¦±kk   Ëëº€× ṵ́LuˆóÂq‡8/ÀANjBB칎ÊL;.;î‡Âõn!kªÕ¦™@§pŒ•(Ц H¹3×ÀŽ¡t ’« h«oA†N" ƒ.€¤¹J‡¬„8 œPÚ ×Ðp©\—t×î®p…»kµIz{:.êèÅ ôüzþ®þ½FÏ_£'Íz ÿæ³UU_ýp,¹|Š^¾û=»ö.=ûã—ë^[†ÝΉ-‹ÏÜkxXCÌŸ÷5°Ü=«¢ÖÁã"sâÆGÅÍé¿ñH͇;ו·6fð¨.àÕ1qš8—¤7yhȵ:¢\ÛS+ÙäFL~È}ƒáðþc7~ð+œñÏÂá açáÌ}á­\{†%±›œryȺR :ð­Cª­C“2ДøÐ˜@æáe³ú«Ð¡á|H_í~|a¥{kÊøÔ(ÐìÞ]âyxæ7ÃÁ)ż×ü|ùþð]ùÑoÁ¾ 3üûF·cN§óTál»·³P81_ @; Gƒà•yM<ÿöK*6zT¶ì©Ó,ŽÇºœD$¢Çidglˈtº#qê™R‡ý5'üzDø;{©¼'g‰?ôÞJkÏóž o’†,ÚŽºÓ¾ ã9í*º³ðïý•^ÒFf’*…ª¯MÛTõúÐŒy¾wf~í´ðE&ê=lpDo|íõ#eÁ‚Œ…J2ÜoòßûÞaÛPñ‡ª Ãî)‚ß;l9 Æ$XCénNZ•§çá~ÏUD€žL¨}ù,Ä»CÕž¥â:­¬.Ju¶¤ZgÉ{©®¢Üó-B ´ÉJ{ !ÈÁß~íó¢Ú‹\&²¦xlžz‹zâ÷ˆ†‹1YVYª[¿O,Ãs>ž3&ê|‡m;ÁÍÞfÚÃ*þ_“¬¡'XÓíÇÄñ„ÓÜïß'ÜѺåϱ<&lj,íg/ëS¸Ot3ðQù:„µÚ6°U‰ÏÑíôÝÙ›j2zBaº¹ tÝwô*Éß¡É×é#_gá°=Ûv¸ä,}Œ§ ¡<Ýfé"\Ì­Âu_í{CÎð"jzjÀùïá×þK¸eu¸ÌhŽKSb«â3{¦0!+…)^>_&ŽÕãïPƒ­ˆ!mw|‰48íÜî1LCôfg.LÝ…‚JžßÛé<È®ç¤ N{ÅM”ˆqEš‚ãƒ;ÙÇ÷`ßq' ³Ð¡)¡CŒ»ÛŸÂ‘¬³™Ù1¹íiQ†ü[»ÑYOÖ‰ÄpW_äÁ}©Âd/õ£‚YHìåp¯„ßœsŽrõŒØ½ÿN/ÖëôWïx%^ù÷=ú  c! endstream endobj 1611 0 obj << /Type /ObjStm /N 100 /First 983 /Length 1082 /Filter /FlateDecode >> stream xÚ½XÁn9 ½ç+tl÷H"%R@ÑS=-°Àî1Çq› IìÆöýû}Ôn4±ÚÇ3@¢Ð–H>¾GŽå„¼ó.äÀŽŠýM.¤j¨ EÍ(޼1:b1ƒ×Ã1;–º%. <3y‡P0‚“Èö;ÉdFrš-©ÓbîÇ ‹#,¶HŒ£¡ØyÆF$s°¤Q¬„—<â'¼$µ ‹—€€Õ`$„JÑ|­–”-GFŽìm·Â©¾¶!Õ7#‡T_›F«ÁRj1_ÁáB†Àª,ÅX@áÑ“•«ò ÑÅlW –ZdÍ.ÆJ… ¬b¨°DŠ 9J€Uk+ì"‡º›\Ld !@LÙ"ƒ°h\ñÈ‘s1 9Ä’ê.r¨ù BEÍz 9Jõ…ʱT_¸‘¯¾š|õ5¥C2_“:¨šE@mbS,uW‘q ‡˜"r€bëA"ªèŠSËÉ©v”@sʬ 4'  9¤F†æ¤Tw‘£xhN…3r@söÁvˆ½µ…@söÕšs¨¾Ðœ£5—@sŽ&žµ {³Ð´TQAsfÓW 9' È)8ÕÚàÆ¹ÆƒælrÃB u9DÌš³V¤ÐœUj#!G©H¡9kGæŒÎAhž‚·sÐ<k~æhØzNaÙ4OÑzH¡y¢¨f‘Klº)4Ol¡•’Í‘BóóâÓ'wõ—»ú}þ÷Ü]}q–ëû™MW÷ó§ß.ÁýG÷ùóŇk’Œ_¹öÞ·åÙ–[’-×êÞ½-OÍZ½Þ«.“vàÖ–¹-¯OÕè3[~~< ûÁû¾êk;=kËËÞ¬a]µSÇ€Êý@ Á‹öƒ°h{5ñ´åZ¶å$É÷ñÜ$»ë¦o¯O­ÐÓ@õìéuCö‹î˜6P?™³#pôlÞZÖŽœ¯-ëË© æ®¶¨ËVËãØþCu™/%dz«ì®_þ?°ÕØ/oo)½Þäq½9•Ë·Éì0_†]Ô¶@õCãlz„4=GxÒê»ÝBþ ø‹ÉóäÛódqgÉÞÖ/›>´$ÝÃbÕ ª£ðt IÙMòGKòØÊêúky˜¦Ìï§éðܼ.#ç¸Ú)MN(m±óX¯°~¨©Œ ¿øô—t>’ðË$é$i8#I{>€6>Ë;VûKVWåx-þ^× ü]{ uMö—Qâ\‚+=?W½Þêý8oõáýån]þïÄÉæôù@Í#Ì—úæKõ#ñ¦¡·ªfÝ p!Ô¡çÍî´ëôFi#\ï4 p½ÓÈ'p5os³Üù²½hî7§kvÄ$Å‘®~eˆ²·¾ÐNÛËîóúá#Ü•¸'*2tÝ­çöä1Œ†0æ÷ñrîÛ rJ–¨Lé|TvSZÿ½2ß_Nᛉ¦S¾™ü ú…i¾ endstream endobj 1812 0 obj << /Type /ObjStm /N 100 /First 977 /Length 1008 /Filter /FlateDecode >> stream xÚ½WËnG¼ë+æhåÍt÷<0|2àSNÉQʦAŽHÓtü}ª&ÉR4.HqZ­éGUõîΦ–Rˆ!µ”ƒ:ÿ–¢ÒÁÚàH Žé{Ä‚´L§•¾Ô‚1²i –Ó 9U^É!g¡SBv&DŽ¢\²ª0Ê4Ô’èX`R85´Ò—Zpa­œ‚—ˆÌL{XÆõØã2þM‘ &ãj,I -À#™( šÕÞhÁfÍ}=Yï§"•UAй£¯Ø’+ ©+d¥U˜’¹Ú´6ækÜ"쥑Vÿ3.ÄÞ°ÙY¨y›±¢†K”¸êž1ÂKILåÏÁ¿¸Ñ£ªô €>x›ôØ‚dCI%×r5 ;p!¥ôUԨʀ‘Z™…S x¨ÑA;UvêíPD¼²謱ׅÐkF (­‰ÈIAn_- Å*„©fv¹U«Ð—ú*F)×~ 5 ¹wH®¥‚+G*­$ÓJ)šk3F@sm«(n‘94·˜Ù34·$ì š[¢æ”Â$2š›æÊQÜ”£â€oÊQu2ãÐ847sf†æ–Y ¹eÊí0ØÆ@µÂaphnÕÍ­¶†m}€šÛ¿ÍÍ;/HoÜ‚‰!Çâô÷åŽ0¸£bŸ%fz ^æHAó,ž®Þ¾ 7¿†›«ßVáæ}xóíû–·«§Ÿ~ÆMuÞ½»zs«µà·Þ¢Ö#͆æŽ&ÓÜ&ík‡µ%Í'šo×eÖ‹Íâ~³XÿÎí°Äû!COø…f1¤îÞ–æfEó4RÄ‹ü2ùc³мÐõä´t.9Ó¬«ç»v˜þ<Ž©é Ä5›‚¸zIâ¶û Ë@>k?‚ôxÈOûµÇa¸Ì ¾ëâ{=ƒ—åh»Ã2ÒüLBã{ ^ÿihâ,ý=Π?N—׋Ðõ8p¶wy÷îY?¿¼ÞçâøèxŠ3›ÒäŠ^„Üí·=ŸEÉ3°(e5¿ŠÅ—ÞTÿo½`¯†ýÇ!jGmðhò*Oz±ãã`¦ç½3›Áô2›,sHnSHžýäœýV»ƒÀqL%Í4åœÑþk˜å‡ýwÕØÅÐå—!×b÷°x¾ÿ3Í÷Ý]3BÎ\wH9ñù¼_ú~ü«çsa9ñ¸r?4±=øª{¼íèGóó «Ý»ä8+uŽƒKâàÒô š.«—ߺ»ƒËy§í6ÇQ¦Mq”i'>wsÚ›O4åxß>×3×åUX”FF°Ìõˆô‘ãŸ;#Àæ8Qø'ŠÄù»,U_¯¯þ/+*M endstream endobj 2013 0 obj << /Type /ObjStm /N 100 /First 977 /Length 1010 /Filter /FlateDecode >> stream xÚ½XMo[7¼ûWð˜ôPs¹»ü‚œôÔS{ôEVó;’#Éòï;»F) jû,)€MÏ{¤vwf–“)…R¤8Ûß(&€q5@ªÀhàÈj`nZ¨œ‚]pZìMš”“-–r¶ÅB¡0P²­ •,²ÔPÕA ­M¡åŠÈxM‘­Í@Ū¦l¡2ʦf±ðH)[Œ, â#-q¶p¹5ã—[ É¥¤@9 rd²b rdµj r”d9*rµÕ´ñÈP*9BŽ}9Úó; mhÉI!GÃÄs¥ Â'¶uö˜ÖQ„)®-E¤…"Šñw(HI ‚ª#LxÍKj¾ÂǼf¨”!G…t‰`qªVÙ’¦Õr´&†Ìex›4P œŒÁN<…3‹U«™«å€×,æ:!KvDè0¯vsV[‡q!ŸEŽbŽrq `9W¶˜àf…sS«H$«ž£û¬f—Ž`¨WÏQ U õwèWöxð\X3rÀsWžCf« ž‹ZÁå 9:BŽòŒ£¸Gð\ª™Bð\ª«Ï¥ù,$F8󞫵=¶Et­H­È„ÁV1»mÐdª¡W‚zï¢ÉÌ}´PuÔ‚ªž«r¹z÷.\ÿ®[ÿ¹×›‡Åfñy³xøò˯¦¾ ïß_½¹á’ñ[nbŒløhÃÒ†{6l:ÚÙðÕ†µ «·YÚq–ß{–o6ÜöGϲ=ޏ}¼µŸËÝ×õÊ¢¦|õ®Gð€jà š¯ÏyŠ}Á}çà\ï&ˆ¤!r¥Yäb¹H®]gsûr•/XõëÇ?Î#Tä2‡ŠÂ©øèy:¥Ï>;ADt&¹ŽÉ³£v/ß,;ÉMgêé7S$ë0’í ’O½Í×D”FÑt‘}Úí‘o›^á÷Kw·ÊˆÝ­:ÇîÖ{ãÛáNöò—•ça ’Ólî^Ñ^ä—Úïzc=öXÿ¬ÿÔ_¯^¥ SHÏPhÛýÞõsýá5y.ÃxÕÓxío@»^Ïn‚M‰£Ø:ÍCOvüfùí=E–GjEæ8ÔJ¾T¾íaÒ§ÃÇc5?.Øëqÿrý_‡2-¦Är÷.³Ü½«þ žFk^ËÍkCó/ÕüD±Z!VãYĪgˆµî•¯¿:&.ûG}uP¤syýßyÙ7ãÁ g5E›‡Ñ–3hïùŸû«¾Ncœ‡1.1^ôê®ßmO»ÝÑ¿ý'×<\)žËu¿Y—ýqîÝO0¤ÑQ›I³ó¿0(ý¬ þ >a½ endstream endobj 2214 0 obj << /Type /ObjStm /N 100 /First 977 /Length 1005 /Filter /FlateDecode >> stream xÚÍXMo7½ëWð÷Ps8$ §9õÔ}‘e'[‚­ Í¿ï ¥²Qѵí¶€M½]çã½á~¥DbH‰r`óßJÂo¢@©¨’ÅÀ®²ƒÿ)q œ}š9é@‚’/çTŠƒŒ@(˜6BV)ruc±PÔ¥†Rh µx~Ê"\c-Å–£æ@Dͬ™;5Ï;6„Ä™=sS óÔÍ {îV²£iˇdDˆ‘ò¯À@™BŒÒÎrJ|mqr²SPà ’{)()šÇ-˜@Ò@5îSK{âjFŒŠ$Ùö‡@Õ½xÍ:À(Œ¥4„RÍ¢#Z5G2 ²ì˘`RÄzj¥ÈHVµsÐ7z ˜œw†ÆLN|öaÙ4´óaÝã=ŽE¡)Hb=Iß[µƒo}îv¬´<Çå–s–{ úoû=ᱦ‘8WÍB'ÔüÕ‡›ïOß sXŽÕÇsl ‘)6…¼²KžzˆçNà>ýNÜq«¬†V‡†úó%í£³µÒ d||‰ØÊ³Õ,3Ô¼éÉmúâ®gÿ¹·Ýá§—\TÕæØ€š§Ø€ÿ;þw}î~Èúº£Ö­›f,ÍÁ¿ñüç9öü¶{]9ÞM±ò,÷£<Éý(ÛÿFŽõÐÃã£ýsßGe%êJ”tN%ž_Ò¸Eæ «ètÕ“¯#Ûa]ß~âI´Î²óë$;¿¾òIôôjxyžLqŽwاx‡MÑÎEÒ?[=6ñX}e§¸´%’SY|^äv½®ýëòH5d3=Õ'Ê'TxÔ-ü—~úáX¹uŽIqŠIz‡V=âàáî‡çºë¡ýýX¥s};J©œ¹ú×½P¤Y>3¦I>3&æŸâîð´´~+¹¹Xü¦Ýƒ¹ endstream endobj 2415 0 obj << /Type /ObjStm /N 100 /First 977 /Length 1098 /Filter /FlateDecode >> stream xÚ½WÙNcG}ç+úqÈôV½H£‘¢a” eAüDâÅxH@,¶l“dþ>çÔˆ6–Ýë…+Aq¸·ºNUêvÛG5>ºbBâßjœõÞ A0®D¼÷ ² ŽÎÁš tÎ0@4Q‱ ŒT“4rô&iäL¶ “ÉQA6Å2²XS"Å™jé,ÑÔXYÄ8g ‰µ·(!m* äí‹%”âeãHâc¶@…+²3N"WäT)#ƒ#%&Á‘ý 8²(boý 8Je䎚¹¢l«YU¸ØÂ·e"ApT$„%|†ðÞ+‚ \!ìT`¢¬±3QBI€‹8póŽ„þÁ¤ ÄÁ9GÆ£:93K(ûRÁ¥2?ÈÁò_¡Ê–ù ev^‘3Á'r€(kÁ¥C@‹0CÑ*ª@‰©AÄ+Ÿ! ‰9Cî £ "$à‚‡¬eAñ33€ä¡8ôJ y(Iß‚£j‡ @¨‰Y!h´VQÊ슎,Ãl2hޱV„y ¢‹Ðà€æh.³B€9ò‚†a¶˜4Çl124ÇD‘ šcŽ£pLšc©"pT՚ǚ=8*wEa7 ¹8¯¨ñÜ*l‰ø¨(ôº% Q”±‘¨e‚梳› ¹HöDÑHrþèý{sziNš|™˜Ó3ón:šþš¦·?œ`ìäØ|øpôî*ä„ß|e­=£¹¡Ó<ÐŒhf -hîh&4OÇ,iåׯòHsÝþU–ùzÄùó5nÆ‹»É£F»õ¾EЀBs…¡%ýfÚȾ¾vøºZߨ£ªè‡è] oÒ»²]ïž[Ò/O|GÞbߨ;kµˆÛ·–ØUK¬–¸]-¯J¯d¶9ñÒÇO -^¿·ÅË 1í0i;fÑÕ¦4Ćü"m×iKqÞÌ?k§†zÝ®–4o ¼xÝ´ê—iÞ4Yº:›9jÒ¡Žšïm=I'þdCâç˲W£=µÄú(–·Û*£¶÷M±•M0Ù׿½Ô©Cy˼qs˜·ê7}vT˜ý`†*ÜY¹,ƒÕ•v¨k¼öäy¹õý¬«È2X‘u×"G Ýö™Çâ†*©ø]KZNæÃAd,q°še»š÷º^ì·K¬)[Þ˜ï[ß:j¨ƒÝ”«Û¹†å·"uí*i° sÝò¼¼Ó»jHƒÕ°åMf¶ë±Y‡º¨»ËwóûO`ßìZÓnÀ}¯36ÚVÜ]»¦MW¿5¼x=®j?k©tÝÇÃɆà¢}"]7º»ÿÙ!ëBo(ðÇÖG5Ÿi¾ÐüÑè>½q“¿zý¾\Þ'Ù?•4?·•šÀeî¼?÷Yûrô¹½ûØ·|~kÁé“Y=Pfj.z0:·?ãy+ôS_ù]8<-MêÃ-â¾Øqö]>P—Ê}|ôD2r endstream endobj 2616 0 obj << /Type /ObjStm /N 100 /First 982 /Length 1201 /Filter /FlateDecode >> stream xÚÕ˜Mo7†ïþ<&=ÔürH  ÊŠkÄvINÀ§=ôRÚþÿ¾3†©o‰ònV Я¸\Î3|‡Ü•|rÑXã“+†ä¯·Æ‘ŒË*ÈxN"ا"›Pdpp†‚ o¢/"¢‰©œA$“’ Űé3‘ˆ`rVA¦'‚³AU6Îa~Ÿ¢ƒJª¼qÁQ*L0£ö¨"*=é½ ìIïMd§( 1²U……äFŒ’U!S«³0†¸ 1$idFjžEedK^f‘ÛHgÖ\œ,Uæ'\( f’Œ$AΪp!Ëô© )."FI&X¥¬®ð±µ&x¢‚ š9[2d¶p!zU°A.xvŠTyX£ "Tâ3¨dÈYíƒÉŽDÁfòEU€‡A"eUÙPÌX¯“Wå q¸M\bÀnʲ~ ¿a‡(mÔ…PE™¨eÅÀˆÞ«Ê&’•;0i$R…‚’Ò’Šb”Ãs Xé+&+ “-BÏ“ ªÈ$/µÁðH3®^¿>Lã]wšÛÚ££~«„Ê3k¡Ý)þ¨(Mc÷ˆ÷5âU˜­úð¾…÷¡<Û2©áçõã´Âµ×Bé ò®.ƤeóÍ75Þ¬ué‚ëJ<­=—«km%U]´ …þf« ŸŽÙUáwËÁ>ÔžùÆ™2ißø—u®y]ÆÑêG½zÛÎ]ÁÇõšoTçuî²…¥te¹©'żªQÙôücuu|ñ‘ëŠÛSñQè r¿ÊðÜ=[å›­•×òÐ÷uè—âø=‰ïkEIÕy/|ÞRJN\Ú²!Æ5¯E®7‡ÎŽñ*ÀxãÚ¨XѧUEiˆ=\¬îßÅI=n¡àž(~ßãàMÅŒËÝ£Õ•{W÷Fœ¶Ð—èguÀb‡<_+ZnI-Ü8n?%÷£çsÜ&Kaø|–—G-ÑŸ]qøôBM6Ò+•¾÷øÄÕ¸v²…æ¾N„gÖ¾TºŸgÜ×þ¿ÝòÍkËŠ· õµ…§uühû:S MŒfG!¶@òP±…¦ Fóò%Ë}þúqÒ{K…Oê&Џû ²ñ–¸ùU¢Ûsº%¹øS$wø¡Ý’+÷™ë¤“Y~Šä¿ž4äZ\÷\w?‡÷eÖN·ý÷黿n§À ~> stream xÚÝYKo7¾ûWð˜ôP“KÉ‚Š$Û‚-YÙ•í8ð)E½Ô‡¶ÿ¿3#˜kjW)­Õªm€„þøœo^$—ª¢ñJ«*VZ9ùk”`à”ATxd•ÕP9ꮢ­”ó¬ð ¼ôg‚ –»hÕQ€S¸íeteEB^*cTÊTVUƳ#Æ¢¦õ!OZ²Š^Š‚ˆ{fH¤L@A$E3O20 ¢¡@…±‚HP%¬éQG2BP•åjäiÎ"A`"# ˆ-$2"U½Èˆ$#x^YiA$5Ë@Z ËÀ@Fe¢ÖÊ-È([‘!d°­¢ PÖFž¦É ®„ÊŠ ÐT„¢ «l<ƒèÚhðŒÉ@à^ò²Ed”3l{$O’j‚€üjQ$‘¯­#C ;ÛFAV9ÇvFr·sÈ2È߯L†pÞ"Á "aÛK2pÛK2¶¬HU0ÒF>#mäs S2¢²:’ ò9¸ÈLÉçž|9Bbbò9DËsiˆA*¯…ùÜo¥‘Ï}%ÒÈÉžìD2ÈçÞq€p¨xЂŒòžcÉçÞA |K’Ï}-ÉQ…3ùSïþøëÿûõ—?{þý§Ÿ3ø^}üxöî‰â›þ‡'¢2çbÅÅ”‹ \¬S2tÉÅŒ xÝ\sÑp1yÝ^¤‹z¶B%Ñ#gæ"Ñíîlí­á>ßdJ2О€ø*¬Xämv˜緆‹„ö¼pLJ÷!9÷\dÛž&¿ó—|"ãÈi½ì9”v·Æ”ô{^$zô/ÑläÌnß(.:nÓÂk2è‘“ºÉoó¯ž1KÈÙ[¤}•gï4£Û”9òí¦Jëg$¥G*è#ä^÷³u•¿“}é¾í’WƒÕÛ‚ÿ#ú´ATëÆü+Ü/{Þ“êž×ΗñíÏ9Óþnç÷‡ºDuûc¨~±óÛòP³ÀÿÂ,í%m™_‹çCõ?þo‹¿Ù5 endstream endobj 3018 0 obj << /Type /ObjStm /N 100 /First 985 /Length 1355 /Filter /FlateDecode >> stream xÚÕYMS9½ó+tLö°¨õÕRU*U6ÆÅ—ã1Øâ´©ö²v÷ÿow›h,1ƒSâ1šQ÷ë§nI3V*­¬6 œü5ÊhËÀ+ãå 0HÊyV« «‚àTÃUôæˆ@T €®8PÉ 0 tâçWVPP`‚ô&V3òZ³‚,!äÍOx$äYðQF¾F@4‚ÈFBö(ûe€ ”%F¨•±V%„‚œ2^l • ‰=ˆ  ŠW‘"”4“d#9Aü˜<ÓŠ–Չ ž#˜¨$ˆ ™ÈqN¨¬5šl¤¨¬£¸Y`úÑ Á ò„¢ SbDM´Œ€†J+Dà sGz‘Œ„•#5¢r&ð(¬3ñbdHNHjç½ ÒÅ.‹b—ÔvI(Üž5'ä”§`1BB‰x)îÓ’ÜÓEFFy´|iîåWž’æA4*x XXL’ç¤ ÅD6Hó<…Hó’ £BŒŽ‘W!AA¡‚’BÐŒÈ8ñŠ4G’•‘SèBaG¯=Ù ÍÑ'ŽiŽÁ 2 Q<%Í‘º‘ÈJ‘ÆÈSHsLø(wÔ ˆsC¢FšG2N6Hóh9â4G %A†RyB«Þ "rÒ<"ç‡)&à‰DÃÇä9Ê6ƒŒPÀ£OŸÔq£Ž§ËuªÏŸ>Ü[ ô‹÷ZësnÜ|áÆssOóß77Ü,¹9[ï;áæš›«|Ä›ÛüïÏ[ç¹Oì\r3ëÜ%Æ.¤ùø<ïBe‘ûŠËM¾ü5Û™äeüI ){H¤–Y§Ëjþ]Ü”ªÜdËçù†»*ØÊIÉq‰´¯‰»œVË¥B¶»2ïŠÎòå“l± Õe…ã†v|œg‹Ü5ªqÒíä$çJûpÍT³~hOÛ)0ÊÑ]èwqhw祧ã\˜¤2Lk|<Õšìä4{ú³¯­jµsÄÁ»X–UmT[!ÜàÉ×z:Ê‘¿è5¯Ý>ix—ûÚ N“½8ÝÕ¶øÞ”ñÕ.®gŽs,/Ëóò6?§sÓ]ŽÛ ×:.´šÇ{&âÆ.j£¬­Û74_wŒÕ­.Ýçç”<ìAi‘›ëÚùé{æÔiæÕìØòµÖYÿŒï™2ÓNðO²“{“*óøzæ¯ÊÂ<+{/òµ?j÷Â>½Šs­KÍSeîª Z'ç'eœ–Y3k-T0 ðRF§í„çæ[öfQ¦ô—Öë¿ìKýºê,5M¹-ª}ñ¯ïˆæWåöbùì¿ÆígÒÆl±«¯Æ¡}²§{†• ½ÜubËNÛ´ùöíFts\¿µ-«ùTAá°‰oÔÉ»¼#¸n•®¡i–æ® è›õY6Zl޾uÖ–yù6o^=»ñ`0yO2n{›¥8nõšo9Ê>ñêq¥£ýˆ_çCÞl_}·€-Ê#Þ$Ïꮪ§Õt·\5å:T5G·-³/ËJ–zV gÙÔ}‚xú½NÏö]|>ÏÔ8é_ÙÉ]Ó¤)}ŸwV®‹<ý§Ï±o¹©÷å*›°~CûÖí¶Æ|z ó³Ês~Ðð"ó–³7û í[˜¯gßsž¯}V,Ϻ£²†veåÜ ‡öo­N”£¦üØ=îdbÿo‹A§¡é]ö ?ÀÐþmû’ÔÆ{^¾Ñ;«¡` 0ïÔí]oì÷-àŽÊÆW†ÍZ5¤p(R[>xT}|Y> stream xÚÝYMS#7½ó+ú¸ä$µ¤–ª¶¶*kc–Z › [Å)©r ‡$ÿ?ÝM¡±ÏšgòŠØF¾5œxˆG?ÂÉNÎp2†ÿû›üüñû?>üõÓÏ–¥:†OŸŽ>Üs@ò/Ýc¾Jq#Åg)‚÷»¶S)¾Kq+Å\Š_¤8+­Oýµz¶\sSú\÷:êt )¾¿ì»³êûrÛ¨Xž—^Ór¸róõä*ÎZsY¨ÌÊ`í¿h¡öGåºÅ?Ú£ËÕÝÚ>³øOÕfój§÷¨´MK¡ÿŽœÃó÷™Å•Õq¥èú?CT{×][ñýUÛãf NíI?‹gX·xJûótRâæ² yG§·PÈû£°t84xêí!xz½>68ŒýÀ |V:Ì{ÛüU™ð©zZ‚¨%ð}8$ß-–ûOW]†,Š•³†ô^ÎJ›rýÖBnIÿö½) œñ祭ÙM½m2§ûÒÛð¾èÒ½6Öòè¨ô…Õ|ÆÛ½PÚ ©.ènJêßlã®ò^ø¬îFÛ)Ú½ê†LÖ?Äo Ox?èßûúWÆIQÝ®vY×µÜ cØ5õþ®§ÅU}„>^­ZЮ \•øG/„nk-šÒ$ïšÊ¬^ïî¤\ôìÜ5 »kÚÛ—ÁOÕwÅ”‘"/·uVN{»öʱ«7äï-ÄñC|Ó॰—%è^8½ýÎÇÑ{f½¨ï'£z7hy<¦| üWŽÃYÙ¨/»¨oà“ÞÁæ5©¯Í~ ¼Á,êËíÛ¾ôŸÖ·æ%çZ¨‡÷Lý¶8ùJÖ´gÖý¯Zã-ëšßÃMåËöàȽîƒjÆC&°£;o²¯ÌêÙ¼¼å÷Ü•b%MÆõ>rþª÷Q™†õze‘×¾çhq3ææçõéú­vw^–öñ)àeŸÉØÁ|þRã7,-ÌÍu—Àóú™²ºÅ_Ô þÔÖ½†8­ÙŽ[è —–Ӛʤ~s7}›Ãåá¼ø5©?€l,yX7oŸÝ霳¯L¸‹ÒÖ?.zº² ÷¿ß®] OÈÉâ¾_üà£æ IÚâ{Ø—ï7õÑwZ"«ÝwÚ¿ï×ÇGÿ ‘rã endstream endobj 3420 0 obj << /Type /ObjStm /N 100 /First 985 /Length 1237 /Filter /FlateDecode >> stream xÚÍYIOcG¾ûWÔqÈ!ôV½H£‘ ðx°Y"qJ”C.áäÿ§ª,u»yˆiÛý ßë­¾Úúu?¬Ó Xg,8ùë@ûÈ €QHGÀjpZ€DÓ~3&AÐnb-=w9 I  •²%A´±¬5¡ È€vÊ3BBN¢ñ ^‘Wñt4‚HGB^œޔE0ZÚ‚&$mÁ€±ž× Æ)A A‰g´¼ ©-ZB^iyB䢤Ñ¢J³•Iç°c´ãÞDÓtDƘ J`­ ‹Jm¼MÈnˆ"H¾$ÄAéðd‚EM"hA¤#jˈtDD:R”(¦Æ’rŽÓžÛ8ÎF r@‘mz#8—q°Ñ 2@¤"#ò¡ .bÜt1EÒAGÅÉ‚rT^ÔQP4›ÞH‰BˆbŽV˜¢d÷RÌe.Å=…‡P IÅ#rÑŘ9ðÊ „d-à7V’ümsoƒ ïÄksœìbí ˜{/œ‰šŠbî£xˆ‚瓬LC‚’•)æA‰sJžAÔ‚I‚<'q£˜ ÞÄzŠ9%Š˜J‚„H#EA¢âšóî¨P¨cb„ä!RN1J„bš|þ §+8½|^?Ãé >ýóßïüóçÿþõü÷/¿ê Ó |ù2ùôdƒ§ß𤔺bqËâ+ dñ¤­ô]ç¾ÛÍg¹ïz0ZúV,ÖÛ}òp)èäç<þ<·›çy´ˆ;ç,f-ÖØ1­Y²xØnb¹o ¸‘ÞÆØ…ñ‚Å÷Œš4‡.š·”\8ÍbÝÙkiLîoeí,-Ò™îáÉØ§À®sh/»9ö©¨[ü}®™ûÜQEú[vë4k,Õ›â}*jësD}O.7mñóm ¥>³ªïŸ÷õco7ö)u]0W™×zΩO9Ýå¾Å`XôØôSŸÚºÈd‡_²{ytïbšÕoŸ³Á!ë"³±ƒ$/ï×–kB £‘\îÿ…2¥ÑX­úG:*}ºµ'W™ý¢n[µp¶cp>¯ï"²Öoõ7ÈóÁ™…ÿZ*«]6~•ˆ `Ö°ÞÊg¦ù`òªÎ¯»ú­>k1*Ѩ—Šë÷vùF´l!žŽHü®þçÓã[F5p×z4îëº,< Gm?S¦…î(%Z8Ü’bëð×Â/ŒÆïq°í}Ïâª\òO&ÿ1GûÖ endstream endobj 3621 0 obj << /Type /ObjStm /N 100 /First 985 /Length 1267 /Filter /FlateDecode >> stream xÚÕYËn#7¼ë+x\ç³ùjX,àÕܵµ’ìuŸäK|Hòÿ)¶#ŽF£…)Y#O/·Ìᣪ«ÉáÐ6­´²Á8åä¯(ˆÊhIYòÖ(ëXåmÈ (ÏX¶ƒÉŽHE àT 0²&i¼ ¤Èè<‚7@NUd#e9#ˆyŸŸ‚ù0C ElóÓà€XæˆIÚaŽ$$C‚4±2¤YeŒh}c’ VÆ™Ì*j U€† ”{Däyeƒ!DQ ÂÉäÙæHA†"é› ‘ôM¬¬IèÁ9´Ö¦ˆ»ü€35oýG¡c„nÑgD0"J„Ói¯3 @I¿4v$Oa-1æ@fËuðÙ² ¯œwÒ.EAI90Û±0€Û.Á< Ì‘¢ Vž²†ážœÆpÜÛì/Ãro½ ¯¼ÏiÀð JHy Ï='AȨ”(£ ‚¶‚S:†çÁxÎð)–ŸÂP¤– ¯‚$)cøí¶Ùžs3<I˜ÂsÖž3I`!­ŒÏÙ:Âðœ=Iò‚¼b–9à9‹û Ï9I<ç$uµè…çñe6XMÎÄ©3Âêp9ºžGO‚<JÈÖ‚Zd-(©]Fð<Æ(s¤¬<Âó˜¢ V‰2çÏy}ü¨.Wêòúyý¬.'êÃ_ÿüš~ÿíï?žÿüáGŠ”.Ô§O£Oˆþñ“Öú&Ë\|Î…ÏÅYy¶ÈÅU.&­ Ú´šåâq»fZÆ”âNÐÅëü ‡ß¬´YI—j¶j×%Zë¿&t_¶ŸIÃ_ÊÓ2ŦÁî|5â|ân‹AÓ"Ü‘»âô¬¨q5µÔµui¿©V?•Ö?—bZÂy]KÜÒ‰Ë/óBò;z`Ï(`Y¢ü5÷å×êÂö²˜šV㎊Eé2o/¹U ]>#ÝD7õF÷¦»óζ, +H:ê—䦦y…u¼¨áiÀ³“βÑMjèû÷§ÿµ†'€çÂÜß’û¶]³j¿ïjvßËBk¢6Ûsš}aXC®—Õ%Qre÷ÜT?–át.Òö³ûÒoZ{÷¾7îW#í)O;ž‡H|»“©Q‘ΨbÙþŽ˜·ëƵk1лp^•±¶Î=µÙìÀ8š(¡¿u:Ý#¥*¦ý­À¦éM5›ÔïbÒÞZçÅyiÐ=ä\•y]F¨1œéýô,Ú‡ŒUc„ÜIÔ°ïo½=”aywìº-íïjôô²üÖåÅñ†C'÷² ï÷oU«ö}Ô¸„sVP÷¢ê¦Øv[ïcVó²mnCn±?Æí‹·¦Õ²£{Ü^M²vÂŽ4,YÍñeÝ^9;W¿g£–ÀyYaÍ%e·USÓLö¥F­–Úæ5#¹k$ð$ìp^!Ódõ›}‰† ±QÖºnŸvná–i‡)óh=~zö]ÐÎOœŸçØZîKÓW%OÚÛÈ¢ŒuU{ªMiXŠN–”IÓ°”­Ê×I³i®kt¼m³x¨™âèõ»ó_¿ö×Þ–ÍÓÎ5꾯´oíMjôðÿHOçüº —D¬œÎ-øDN½ ñ=eë.£†ó1 ò oÅD.Ƚ{ävƒÏí»ƒÛö ðwî„—5LùX¦ã–}÷I-â;Ÿö;MÚçëÕÅè_⸠endstream endobj 3822 0 obj << /Type /ObjStm /N 100 /First 989 /Length 1453 /Filter /FlateDecode >> stream xÚåYKo7¾ûWð˜ôPó5|AE²A+ÖÚN ŸZôÐK}hûÿ;3†IÑK9\Y²…°éÏ»$ç›9äš • Âò_'Td…6¨±š€¡Ç¬pÞðÂ+A(©èUˆ@Ÿ ÒBœ rŒpv0Œ""O¤P>!#Ad…–8"(0 Bkg9EÔ,ÊpZhP4Â"`ä„ö.B‚$ä¥Ð1:B¨„4Œp*mi>ÒEFØÙ2?i}D¤²~†Ó»È'ð@3ü×GBdµÈü¢A[JFVXåÈ.Ñ «%£ , ÁÎR! æ‘”¢gèFNXEa½&¤¤°ØG…2‚gdHm yDŽQ "J‹8 ´AD­ Jô FNß#: Bƒ‹@Èð†Ê8£Ë!jFA8©i:ÊI'Qúܱ¾}îX߈>w@}î8‚"úÜYfŠ>w aT9ÅÈ#F(ÃÒ}Ž1§PNï‚ ô e„ÀÈ /)š"úÜ+E}Žäi,úÜ£MYáAÑô¹`NL¡±½ò’ôâ%¢Ï}d‹£ÏƒäùÐçAò|èó Ù}´dd±–èó`4£ ‚E`X(DAŸ Ò"……DŸg¡ ü¡ Š0+Ñço’ʈ’‘‘þEä£ ¢r”Æèó¨%œ|ø N×âôâ¾»§ñîŸÿ~§Ÿ?ÿø÷¯û¿ùUEß‹OÞÝïð×ßI)gÔ\Qó‰ æNŸŸQ3¦æ†š5×ÔtÔ|Þì¿NN©Ym¾»Is]¥®Üë’šåûï³×jWöç¥ì«¤Ç¼Þ?¿[´ð2»òZ'+=šIÉõqЪ4í2¡n³×y"Î*\$!º$l–ä,7;\§![8L{CÆiÎëô®`5On[Ì ?·9ÏËÇý8íÒLßZÌénsæà—OZŒ_Áx_’fyd÷dyl3vƒFF½‚F—I…Õ ÿç•džš¼ýt[¼Ý¢µù1´®&H‹þpÄú/Ót_KæjQϱzy¹Z¥^¹éÒÛ#;¾±ê—©÷¢Tê±WÞÀV©`%‰×idËÊ”·êØ•Ÿ”É<-»Î[t4Ç®ãç2G{ÒŽpë¶,Y¬ÕÃ(uåæ¶ôsKed®;ë$öá0Ö Ô®"›eáØÕK©Ç'¹æç2;uíêòZ f/Ú¬K’“ÜÏzƒj{ÑâI_áÒÛAŠ=5W?-G ˜‡]2aC£ò]qó¡ëé’¨–ÚâÁyÖno&å QS§δZWµP3oC­—ˆy3·€ƒƒsŸÖëÓa åŸP³ô.¯`-›†;|­Ót7½c̨,góö;oµ­?|jueIvÖšZÞ¼ µ}¤–qj-ËpZ¹Rj"òâÜ¹Ì QnøùªkÝš.þÅé²N;ʪ,Z¯ž):ªÙ݆a— Ùrí°‘¯-’ÍA$÷Ìɱõ[3+Ø «|úh9Û¿g¡_Z„î­³^á>.%Oê[bWÞÛ<·ù÷oò–å:‘¯:ZøMåúä<%W±óo¹™ÿ®E.ëG QÏ<­/žçiÜ´õ* L»ÛÄ!_¨ÎJ·½sq-)s\µÐ¬äá¼w^¯­z}u¥KW¥i»rÝrÒ_”g§Y‹ þ¥*äcÅô™›Ð«JØ¡6¬fŠ•u!kÿuËɱ´ä§Öz>àæ]K©¶P[—7dÅ…á´ îÆ;(Ì vSÿÀ88pPr%ö×åì]kå[¢õ»§…÷!ÚZøùýñË«È~¨U‚7gQNú­Ÿµ¢°A°R[Ïžùr{ÑóÔ²LÚo%¥ë¶ªÙ˜—²yR ÷/> stream xÚmTËŽâ0¼ç+¼$æÀà$0Š ‰Ã£­ö ‰a#A%áÀ߯«›ÀÌjDÕå²»«ífðãc;ZæÕÁŽÌ«Ÿ¶­®MfGÑÏ}í q•]/¶ìÞ­ÍmÞ¯¶o⣩²­íÄ0ZÇë²è^œx]fçkn{ÕÿE+{*ʧyÄpg6;5’PìŠîìVž¤pH8$hù—mÚ¢*ß„z•R:")󨺠ÊÖß3‰qŸûX”ysO'Hî)-ò"ëî}³‹³‹ÍÛ[ÛÙ˺s á3 4†{´¢p¿YôdšrýØëKæ‘+ˆ™ÇÞ a }ÀõàíÑ« W€‡Œ{ Fvm734…4˜‡¢´A­«»èGÞÿc Ú¤Þ_86 endstream endobj 4142 0 obj << /Length 770 /Filter /FlateDecode >> stream xÚmUËn£0ÝóžE¥Î"±y$UÉ6 É¢5Õh¶)8¤"’,ú÷ãc\W³Ýsß/.7?ž·3ÑôozÆï(yѧþ2Ôz¦vÇèæ¦èëËAwçG­ÝŒÒÓ=yúz«ÏäVmŠMמåMW\=jý_Iê÷¶ó*ˆCn_õŸÙÃfö ¯íùÃ&1yØ+ü­‡SÛw÷$¾£”FÙ5ª? ÅS4¿†!ó1ð¾íšá‹¼!r3Ò´õùŠì»>˜Za¼ý<õaÓíûhµ"ó#<‡O›ËÏhþ44zh»wrû°1p{9?4B“4Z¯I£÷Æ‹©çqwÐd>å?ñ¯É»Ü=ûõó¨‰Ã±K«î}:îj=ìºw­(]“UU­#Ý5ßd¦kò¶u¥Ñ¥¥y že¥ÖÑ*†ƒx12+ƒ¹Sx¦æ,öÌÒ09Ì9Ô)5t´J N¦Š'†™™{fSÉ –2Œ¬Rà̼   KÙÀÒV i‰X¤¤†BÆRs>–^ÿÝ ×.¹¢KäCc†2—ÀÜc4‰&WÀ©o"²¦™ÇÖîq¼ð8^zlã p5u%†=c¾K(œq/‡?–xŒQ±Ôcøc™·/€s/G|¶°£•¨•-mõ„¥•鯝P/S8+8èÂÑ 4fÁR§SYZ"?.ì‚0»1Òшŕ[KŽþòÒñ­¾õÃúPKS6Ò×0ÃÔæ—eÈ;Uކ}Z8~S›gÈ;­ _™õÇàg®v»ói;K¹æÊcÄÌ g‡ÝÌ­oZ ÞÜú¦ ú¶ø’'ü êê„LÄá^ î¥àá^Š$ÜK‘†{)²p/Eî¥X„{)–á^ î¥(½ߎ‡¨> stream xÚmVMoÛ8¼ûWhÒCj~H”\HÉrhSÔÁb¯ŽÄd IJ!Û‡üûÕ¼±Ã¢ØƒõøÞ¼!9ÔÝ_?7¾?¼ÄûUe¿âép»øPßgwwÍ¡»ìãpþcûÛÛÓ·ìçxè6ñœÝ×Íã°;™‚‡îýÒÇ[Ôÿ…ø¶Rêd÷ÏñŸ‡§ï›…ˆçÝù}z“³ eÊäõßq<í÷LUJM롯{°<Íæ×JÙüVûu7ôãµ\ö‚â3m²~ׯOòßí§v1yóq:Çýãðz˜-—Ùü×ôòt?„Í—Ùüiìã¸Þ²û‰Ïô¼¹ïµ35[­²>¾Ni¦ž~l÷1›§>_\é“}~þ8ÆÌȳ&±îÐÇÓqÛÅq;¼ÅÙR©U¶lÛÕ,ýï g¼¼^Cs=…~úk*[4õ¢^Í–¥™žåO×mT·I:/nYº·ãµž1ÚLs*J`#¸lœ ne¼ÀÜ¢ì8W—Ìi+Á‹xAì€=±Ì ÄpM¼n˜?¯™SbZbÄhòÏ`-؃6‚+ÔÒ–µtΘ¸ 7 þÆûXøû €ÉßB[Mþ98hò¯ ›&ÿ ýjòwÐJ7Äà¯É¿”qò/1n„¿^ –ÑÄÈi 1z1–ùMN þ¦ F_ƃ›¡þ¹Ä ÝHþ±ä÷Ä’?K|M,ù愆fý[þ«þÐÜ e‘ÓRÿ©Õ S…xKýúµÂ¿¨e¹‚ä‘ýc­Ä íQ×Rþ–ú+™ëe¿y¬‹¥þ ëhÉ_Ë8ùkôh©¿G_–ü=âsêoSsƒ¹9µµ¨›S[‹<9õ”^rê©%æZ:ä¬kÁ³`Nø‚<åÜ'{¸à>© [AžkZ§&ŽûÜ#¿£Îùä· 9%F-—ËÜ‚µÏ©ì=WC'}•k‰_K—óRV³ᯌÔõÄèQàV ç$¾!–6n/xzjgÿu › endstream endobj 4144 0 obj << /Length 1026 /Filter /FlateDecode >> stream xÚm–KoÛ0 ÇïþÞ¡@wÈbK²EÉ ‡=°î©­v;p’C¿ýLÒ2­b‡ü™z”é¿n>ý|ܘnxvù%‰¹óp[·)¿íOÑÍM5´×£ë/ßë\ç½ç¯ñÏqhÝ%¾-ª‡þpù< ~èÛ·kçü¨ÿ²îõÐóØ'¾}r6ßê?›F<.o“‡Æ“OVŒîßn<†þkœ~I1=¨û®Žå9ÚÎ;Å[¿÷Ë¡ïÆy»ø6Rw‡ö2þ·Ç)]˜üø~¾¸ãCÿ2Dwwñö×ä<_ÆwŒæs´ý1vn<ô¯ñíÏÄ×ÓéÍÁÞqÝßÇ{™–™rú¾?ºxË),Ž9|Šž?½Ÿ\LœR`íйóiߺqß¿ºè.Iî㻦¹\ß}𥹢9Ï/íßý8Öß5õdNœžrf=KâʳšXÈÄxΈ—ñ9ñ²¾&^Ößázz_/ë¯ëe¾%^æ—ÀI%À®Ð®s°k°‹f™×ûyé*ïx•7²`?¬Jö#+® rÆuAι.Ț낼㺠\dÃuA¶\är® ØÕ\°Wyã¸UÞÀb•·^å¼:oäÕy#¯ÎyuÞÈ«óF^7ò꼑Wçl8/a9/Qr^8®â¼WyÃù‰†Þ…lf™`…;%»[ mpŒ$[MyX[RŽÞ+Iù¨¥¤ÜL6§Ñ`ÓYÜË 9HKvvI6ä)+²K°k² Ø Ù§šã‡¹Šâ7ð+Š¿€¹Šâ/°×Qe\G…ñ›$Ÿû@if¨Â<„¨½¿`F¿¡ñ‰÷[fô—Ä©÷WÌ诉…÷7ÌàÏ0O‘úùæ*’Ƴ xü÷"ÜE)=+b¿~–ÑúÊsN~¦‰—ýv¼?ÆSðþȆ÷G¶¼?rÉû#W¼?rÍû#7¼?p>çïãËSfôcÊ¥~¹dF¿b†w4ψ}}òœÇkf¿ãþGÁýl¸ÿ‘-÷?rÉý\qÿ#×ÜÿÈ ÷?°žó÷z¢Sfô fˆWKfèUM}k¡5õ­…ÐsßBohÍ:¡çï0οÁÐÿšò¬ ÷4}{ÆCùU¸NµzŽçšVcC6¬¹û ¯&á9&ýà¡öj¯Q¡öš,Ô^“‡Úkt¨½fj¯)Bí5&Ô^S…ÚkêP{MÃÚk®©MCíµ"Ô^+Cíµ*Ô^›…ÚkóP{­µ×îBíµE¨½Ö„Úkm¨½¶ µ×V¡öÚ:Ô^Ûð·µLøÛZ¦¡ö–"ÔÞR†Ú[ªå=™njó îlpÅ\®†íu§[#ÞCñW¿Cï–«êi8Á,üá×ß™~4Ñ?„ãªs endstream endobj 4146 0 obj << /Length 220 /Filter /FlateDecode >> stream xÚeÍNÃ0„ï~Š9&‡.»¶c;G* ¢ˆà[ÕCÛ˜*RJBÊÏëã6=4úff—±c¡øŸ¾+ÉÊx /L•qØÔjÍh²¿S];|Ÿ©¬ Y;¼¨§‹®yTWwV -ùàñÁQm œÓ¤Å#6X¥®Š4nÓØË™ö¡¸†®Ým>Úþm2nR©¹ø*%ƒ]?¤q²Ÿm“Êu\æñ¹³²§c*2& SòµççÔ¥Í1MQ!­I~³ò7±·˜‰6Söñ>žØ‹o£ú4‰Jî endstream endobj 4153 0 obj << /Length 19 /Filter /FlateDecode >> stream xÚ3PHW0Ppç2ÀAc(á endstream endobj 4163 0 obj << /Length 522 /Filter /FlateDecode >> stream xÚ¥TKsÓ0¾ûWìQ:XèaÉÖ±”R†Rˆ/Lè0N¬ ñÛ%ðï‘#¹™$§´{½ö|ÝÏ¢ðf ÷·yôæ}€%D$ŠC¾D1Bµ•pÂ5ƒ¼„%ºÆ}¾ËoîrK´ÀùmD §P"ÒÄ]“LAç@Ïš_gŽB ÐD+®F†XdzO3ʈbÚs0ìž)Eï ýÁB"³mZ[?â˜KŠvvøé«Ùb¹DW÷s/$˜qÒ¡ŽN€—É„xˆ9#š¥†]ß°vŠŠÎkàTd¾Z7uoKÓƒu•ïmF Møô©7¡ÝlüýW·’?[™~ÁQQa&Q{ìféTd™BL\ꃙ7 ¦ÁÚïTÓaÇhêõ$jeÆÆ°ÛÜÔ¾ùÁت,¶þ¡¨K_|šç¾øˆ¹ÃèV#˜DM@:[Èh!Õ1ùJ I°0¯í`'Ykï¤4õØëO² 3BEúœ…ôò0„#!2¹ïl½¶í$¥*jÛ>m÷8™Y[tý˜áÓÁhÎ9â¯Ý­ z®¡­_¦ñÜ~@û0Öî_Ň•ë-‹Éá_kú3ÙiBâ/Þgø§æuiÆý=]šûÿ¤š–Æ•>z“G¿#æJ R2!\¥°®¢å…ÒµoGbÁnÿQåN'¶°ˆ¾<Ÿu‡ƒHŠ”pî cŒ{J{Jø5-Õ endstream endobj 4169 0 obj << /Length 113 /Filter /FlateDecode >> stream xÚ3PHW0Ppç2@£ ¹ ´‚¡‚¹‘‚©‰ž‘™¹Br.Wt¬B PØKÁ@ÏØÒB¡¬(WÁÄÌHç(sr9…pé»™*XêYš™)„¤Œ01Ò344RIQˆÖÈÌÔŒ ñ‚[åÂOz endstream endobj 4180 0 obj << /Length 2781 /Filter /FlateDecode >> stream xÚ½Z[sÛ¶~÷¯Ð#5±q!Ù9s¦Ž£&nÛÇ–ÛœI:Š‚-žP¤*RqòïÏ. HZv.ÎôÅ·ÅâÛ«ŒnGÁèåQ`Û¿´Áˆ¢p±À—\²õÑ»¿‚Ñè¿?IÔèÎÌZ„Š¡-FWGÿ9z>;úéWÁF‰Ÿ¨Pf7#‘0?ØH%¡Ï9š-G3ñDz¯Ž/fÓËñ_³ßÌ&|.TˆkXä3ÆF“û ´fÉùÙ§Mg}•Œüˆ‹oe°s‘¯pȸ/è°Ó?¦¯Ç<ðÎ/NÏÆx/Ç“0н?Og¯¨÷òêjÞñÅ)Ý€ÇKà iöœ w±Ýu¶Ò°V$f-—f-|ÇÞû@/u©·ðxyF³®t¶³”æ³#ácžéšH° ,g´QZî|7¥g'¤›M‘gi“W¥¥4ÍΪõzWâ˜å«Æu‹í»:/oiöïx]½]ème÷‘ÔT[Û6+`„ž0æ'Ò¾v=¸H̼µÎÆLz«´Ìëuí'"Œ¼?Çœ€Bo«‘;].i¾ãF#E õ¤ß(Eà LJ‰´Êo‘'!½I¡ñZqÜÐŒÞlÓµÆW¾Cjµý@kïV91G³t œlÒº6‡ñý¹ÏÞv×®–—ÖÔÒ’«×ö­€r3É>HòÔ/uÓaûw‚7$’yeºŒÝÁIº$!èùâÃv!éƒäeÂmì+GÒóÛ[D~Â9ÝbÉ!>¯ôróêÊ«7:Ëß\è¥(b~Èhžà üåq<Ú‚=¹G¼| ¨xGYXÀ} àÀœ|ùë íF‚ÓÎÖ0 ”LH?Œ•[–TžÆ†òc~ˆ ñ(¡ƒ²ËÈœ3︨++,­ŸÆì†á=¶")ÔdÃYä–í¡KSâl©ëÌ*åÆâ «jWÖŒ˜Æ^fWkKXÙNGC“0Q>¼¯¹ÅljÑ\äºl,Œ[ø[»ÖEôf[ÝÛ jz£³b’‡±·¬²‹Æjï./ ;¸¿éBÓ`{=ÿˆšÚÕ®¶ë ­ÃgkLq.ÊG­¶!Éi]{„{zev¢ë9þšÕ`ÒU$õÌ# ‚!9`lòõ¦Ðxs£Œ 4'ì7§3êà¦Ïú¶èyÑÈ\—Š'­rgDÔÈñ§F—µuh^ª™Ù_Üïa2ðYˆøÑ€op‡ôC¢}ß%Ã-yì'!]’ù¬¿ï7ï?z7‘Aà¡+‡G]kráÍç®Ó"`#6¤ AŽÑþóßá]K„,5á•tΡ¦¨²´ .y*Žn]ÿ óá­‡äÞ‚ g7, ÄÛ·Y¸4.¾­ë9À„TÍk憩î¥áf$$Ó~óÙºÚ–ëý5Pbvˆ<³€9]X*’©T±ÓÆ rù´NÏE)­Ç²' ¨Ì›0C¬w›–}‡óV<] î]O~¼±}³/àÑɰXÀ½Y0\Ó5ʱ/TâŒ+Àa~2?›Í__ᙳçäê§/æWÞJéýqz2=$2ám(Ý>?'1W$*ì´2¤ÏzUíŠ%ö#oai©ÂckÀP¤HDK…mãöÛ;±£d‡0”ÀNëOÁ$c”y€o!üD´ž²ÚØk"¸ð£DôQa·üeUÕCá`ï˜ûjïÓ}4ÿ`ÉÐ ƨµA ÖÝžÈ)¡âH×€ÓšŠl†VßâLÝÐhݱ… µÝ3/ó&MG! 3±é¸ÆÚ‹ôŒuV&ƒê,réÌv=€òþ^È}0ÑwšßÓ™¾iîÇi!»=`½+š|Æ5©ýÇôdB šžü~ù\¢ª\\BZ:9½Çš¾ž›Ïã7éI$TGO8IO°ÓÑΓVOpha§¤ÔlœŠdùÍ0ÒHŠØh`O&zý™$o<¬*틘7wŒö@ïžÂù^ãö¿Æj=‘¥Fÿ\>nw@©™ôÙ^YÿÎ Ýä?Q3Ç“ýÕ¿ÉžYÊöíV:]‚^À1c„ ðÕûÖôŒç£¨`±Ï¥¸g†ú™ƒ¯_¿žŸŸ¾8d{"Ã=ÌX̰Ó~âk`Ûlujœ‹” ¥ˆþÛ]‰Ï¹I·5͈îAi,ì øÌÕà¢`÷>¬LÔ¦À-:© z[ex6‘: [#=çXØLg‘Þ10dá ô¾i eøfb³2A]€©„·Ø5vSúâ¼~à‹cKŒ/¹ÞR„¬"y÷ÍV7¶Pq(Ö5‘½€£«ZS÷€ý@ â;Еøq‹J3„á´\â[>*j–™]íF\l/ŒåÆÆ}v=0> È Þ­8Ðrž}úÐg±èËÁàÉ)¿³ø6¹Â´¤Ð¬XTe›f Q7´Ö®Üˆƒƒ  »X½OàOÑöã3¼ÿùÙßœ__zùêùX ‚ž ½óÛ²Úê%¨…R6Åá´„5`MÙžº/!³ÚŽá»âCÅѾ¾FÙŸ2rÇÆ%µØ‡'!w`yî=^ºC˜ïŠnªÍ®SW1¦Â@D@UF¹pb][}ilq®]¼IÝ@¶+R»8_¶y|a•¬[áÒÞÀGµ=@,+{öÂ2½/4b*¹´ƒ0t°:x ÷w…AÑÑ¡«hÿ2ßcìäÕéÙt~}úâñ@…ùQÄ; • TBÕó H7þÚ]¾œ7Ô­ÿÓYƒVÀXN0|_ÆÜo8Ãÿ –_ endstream endobj 4200 0 obj << /Length 3482 /Filter /FlateDecode >> stream xÚ­ÙvÛÆõ]_ÁGòžë[GNÅImµ/iŽHB’`ÐŽúõ½Ûƒ…²¤æ…Îv÷eÝÏÔ컋on.Þ¼ õ, ²ØÄ³›»YbfI˜afg7›Ù¯ó&šÇUq¬êÅÒ$éüêpØ–ë¼)«=w|[,Œš^h˜¸­Å‘»¿;•›â’Û‹m‘×ÿÑ1^üvóýÅõÍÅPQ3Í Ã QÉl½»øõ75Û@ÿ÷3Ø,}¡Y»Y§ðÝÎ>]üãB í7Ð@… LlqU¬gGu~ì×a`ÃØ8ÊU„a”š„ãëÌ~]FJÍßï˦̛…VóJx³†/pkSìad[÷à¼ygSO j¶4iE†±ºZ,mbçß}ú´°Ñüê—÷ø?œ¯·%ìÅc¹/ <Õ…€ŒF,C›!–iʨ;u\y_×·% [ëÛuµo „úgÓC˜æÚyS14€šÐä«mY?F<›œj^6<âí,–‰ ç7îþæ]{\°© ²Ðd.”>Ko›V7oòýf+Ë{L\ºõK­—ïrÈù®hPaãPÍ7Üôv娠Î/†ZM¹F=ÿŠF†óc <ÞÈ¼Š¿>ÐÐCÁ {_¬QB@µŽ”_íeC_x45—FQ6°ž;ty] §l__|AQnßÞ~@T~¾}ûñúÛë7ï¯~œà‘6Qé̱˜Ä ‚9¡ÙbƒÇƦ¸C§Ÿ¶ w´ÊgcÐl§Õ`ú6ŠIåqRé&#=nã—+%,D¥Ì× ðO屸E#…„y+À3D)P/=GU¾^âà•PÝcZ»7L޳9a§Nëˆ"èîH!ÆiJªË#ùvËKÞËi„žE#ÌÛå¨ú¿õö´qHOY‘²A–j'âMQ—Îtö` JeàÒB· 3à+Ê7KçŽ$_@ÂÃ(;§£0fFO¨ê4³«Ÿ®'pJ!<¥ië îÀd#Eðñ»©Ðt±µ¯¤ëPúŒn¦àžœ?õ¡X—ÿV6\Ë dµGPœ,öë"`]ÀK™•øøžÀ'l&J™©è °×m˜ÌEyNÎ}¿W·<ÍÂñN³d¸î­{¨Øµ,WyíCÂ`e‰TV%èl:ú ¼qËмâž÷ëòÀÀS†jHkGøL‘stÞÕÅñs¹.ÞþÍ}KãÀš¨só°u,®ÛjMhAóXäÛR jöåä4¡ïZ™@…ÆmG|/|v¨‚Ä$-ìú¼#CäT!šr¤3±8…ã'±½’>6sœ‡Ê‘R ‘q;—…°hB%q)ZܪXçTÚë!ÔË#§H¸F‹BûÀÈUÒ.MTxÚc£ÞÓ!&?`éì_qKvà–lß-…}·dGǶŒ§vç;èΟ±¯ì9'@ª,[¬úù:àá¡9¡OÒÓY-“áÚa¬gð’ñaŸ2\w4˜HšÎª®±©˜šMVj5+üïáó¹,-.‘@£‡â¥„³SóU@Î@»ot$ÚMu›ˆc€ÖÐ1@—°Öf^ø *þúîbBP¯M@1Ý;2ñ®æ8,¾uu‰ÿ?1õé—µ„5в&Ž|Ò©zÔâ&#jã¨u•>>Öqwe@Œ|zœvK2¬ê¶œÙ«ŸqùøZq!6Žz•ĉxÖÇOG=íS%áa·,7ƈIÁ AA ¿Ü ™°’²8Ýà@*[£ÿ¬¹ûU9¦~Þ…‚Êœ‡ÂC&?Ž•Ë(Áx)³8RRî°ãjø+®C‡® ¯å‚̸ëVû×\·^!%ëuqX ey—®Y_xÕŠæï_µâÿ6 kZè#z—â6}å+:!–&àÿõӑ礷„“÷wëJ.ÔÛ“:ÜE‚•-mÌ6¶· J‚+>—ž™9>{¨·Î9á)ËÄgnvceWž%ÂÙ'>÷n7ÍIíøŠŠÝé“É.?Q­à©m1¤äð¥ºû-üC¶Ž…® Á4€¹£D0ÊçÒRCÎ)s¦Â̺ìÇóçÕGÊÚ•2ðºa¢Á—I6¯ËÝa[´a žœáÀ™‚ÿÓ^ '˜ø=s‡§ bÛ^ýäž9„v+pÍ!ȪÏ6;¸c >¦póžkÐ]dZêN³Òß w=É}¯ “ ÊÒ‘Dx‹¥NÙ¨tš`IŒ·ÀNÿôÅÃÀ³0ÐàWËÒAþ‚#Ü'aFÞ<JJ¦ù §~{ý8õê§ëKžŠœéèîPxü®KÍ‚µ¤ºåþ¿‰nÄÙËÖ¥[Ñ?3óby¬ö;IÆâñÕŠœQ­Á«qÌr_ñ1ÄÉuµƒ]įŒ®¹¬™ðÁñУ…à{‰šÿì+Yêßùø6pîDy䀃8•œƒ=æ.[¤ZÆD®u…Õ²dŒ,v¶ÚFý “Fó½|[c×Â8JEìÇ\ùœŒñ؆S¯ tDi{YÛzêSß/BÌ&îX³ ±í+èê„c±àWt߯\!ß¾½þåfêÎXIØ:".„Vº/EÞûäÂÏ7ŸØ9ƒ8i± ÐÉp¹Å¤Æ30Ÿ)à„ÙK^X¤A¨’©ð°Ê)Ï™@«iÇûÔ«‰(ȲÎ%é\'tK2 - p0 ~‰Âÿ&FVWüõ£ŸxÙL ½l厡Î1GjàU_ š( ©ùNþù*¯û¡uïðé"N¤o/ÜUº,Åû:`ÔælÍßhCy|Æ>Jc N”†K¡'¢Gº{t‹'ž1è4PÝ‹—ç(UÚn¼§\¯8W˜ç^(W·Ä5»ªe9üCÏNÞX›~ž¡¥رkô¨8„ÔQÑ-sCÎGA2x·5ØcÌÉRóBëTm´ôÊ&aê+W8í ññT+5R+Š>ñJ! "m}ó Sgžaê™gØ, ÅÕÿdš _ms%IÝÍxÂ_ 'pðàþ?¦¼ê endstream endobj 4023 0 obj << /Type /ObjStm /N 100 /First 977 /Length 1969 /Filter /FlateDecode >> stream xÚÍZQo7~ׯ p/ÉÇ%9ä y0 8qÜMÛ v®Í9yPd51âZ†$Òûõ73ÒRR¤:kKꈩo¹Ü™o†Ã.7Ñ…`œ‰. 7òKÆCbÎxRàM@ 8É@)²‰  ˜”Ä`R)=`‚ô !R@&Sdœ)^7ÞÍPd”%ã}2)3*ŠŠñX—ÃÀì|fùÆÇ Œ¡"掌ˆÉ#)b¤wY·ÏNëÈE8±P_”&±Ž¢Úr0Á²Ž &ø$R22*ŠÈ„Å/Å™A{(‘R"#T”LHYQfÿÍEïXGö®ÇˆuÌÒ‡ì^§ˆ xaê½cyA˜zvRÄóì_F™QVT D'X%D $¾Áˆu$ñ.ûÓ²³£çÁ€EëÈ ˆudR$s-Óïe²ó‚tÊ¥OC†<ëˆr‰¢#òcÁ‰ŽÄ$)âÇ@&ß‹s ˆ•2݉DžÐ 'Ú„Zñ>±¼"3è9;‡up¤ wyBè]Œy^ìÅÄHyôŒ²è`Ç&L‚Øí‰Ôr6&Qº<ç)Ëüz¦¼X;ƒÓ»`T Ǥ¶±KT›…Ä""C2Ñgo(¨'yâ €µñËɆ¢Î6 Òç9˜Žèβ@²ôqlQA}>›ì£èÎÅd}™œdµxŽ·ŒjqÎú,gq{¦91Í÷£Ó‘iŽÌ£ÉÍù7L/FW·ÁùòØ|÷]ïÑ; ä?zçœ;•懊ÞyÐîci^Jóýr÷si~Yî9”æM}þùãoÓ~[/¤ù©¢ÓŠ”ÍË.`wþµÐ\ouá¶åðcÕüv¹û•4?KsR%Õ¡zù¬ ?Ú–ßÏuôJ¸œ,÷(±gõùgUÈÉnÛ]¼ÖujÁï„Íëªt‹å°;.êž_W—Û“ÅÜua“öÁæmÍ[‡ób:~ªè—ûúaëx=­”+¥“Õœ¸Ú‹ õt-m<­þY½üáNa7„ýÆì¸9‘®p~²jÊIõpõovÌaC|–f,ÍiÒ²Š4#i®¤™H3í¢‡î¦çºÞ»¨Ê›‰ü^Ç/x +êD®ì˜œöô+¹aÉï˜Ã¸úA‰\*›.D`ÇD&•Èt'üÒÿ‘ßò€ózOŸëwáN„ûåê"ùX%|êbEÙ‡zï¿]— îz¹¨õÔ¡8Üq¥ŒkŽº©ÎëåuwŒý/]dÞ1&¿¨ë6 žIµhÁ†u©G5è®Wƒt°º’†Õ1ï\t5vûuè‘“.v × M¼¥Øý§’¯­¸ÁªEç5¬ÛŸk÷ gò÷å¼ï‹5’‹D±ÉoKÚ7ö‹Õn¯3=hqæµiŽ/¦ïEÊÁA¯9ýãzhšWýÃ^ótt5^M'rþ‚2´×¼NF7ãÁp2;“Ѿ‡çý'£/æL䡆Jxßc!c~Z[TOo®aEõ¯oÿmˆÎ\Ý\^¾o³j#Œ£DÄðYV·Ë²X6ä:ºÉÀüm«7to²[7òýÓ5ùy¦ÐhA›É©ÍäÔfr¢[Òõ¦èsÆ_£EÛô{‡EŸä›“žá¼M$‹`ÐÏÍáÁjh5›“æÍëò÷èÓtz=ùgÓœ÷§ýé¸?øÌ«äb8ýÍŽÆ›óÑ ù4ýý²ÿ6ÁÊÅã?YAß&-Ƹ ™¬+û%·$ LŽ`ái@6ÂíÓÓ”"nKšÍ.³Ïp6Ëç(N‘A>±-åî”§£ÑådAvÍ»›§¶$Î…[°Æh3¯"ÞøXùTÅá‹”:´Dy¿´áþ´ecPäë1o–2¯ënS8Sñ†÷!˜Ý¶"ûY{­|®Ož,yöµ#.k°Μ­ÜלµPéXøVn(|÷S´ÄéNeô[+l(ª|%K,ÇöJ¿Ï¦­ªUpªUÙ¢Zå¶åöU"·¯¹}•(®mi+mi+mi+mi+mi+­ä²]i >Z`Ÿ#% L(EwZ˜Ñ†€ûMe‹ìÅi •b0yË!Æ»b.)ä:äýò[eÎVÈnFÞËËH®ÈÙ“ã…¸´9Q1]~äâÀe™Kœ÷ün(^§ôPi·o üÆ$ÿuF*rúˆÒð`c{^‚+oÙÉü5¼ƒßbMòþLJoÈœé˃w÷> stream xÚÍZKsÛȾëWà2eŽç…`§RÙÝÄZoj³Y[7{‹‚#1Ð(YIå¿§{z eS¶¶*˜zúÝ_Ń›€—ß_]<¥E°ÄH\]2ÖLª$ˆtÌt¢‚«uðnö÷¹ g¶^Ùºjæ ųïv»"ÏÒ6¯Jšø«K>» ØXT;[Óôå>_ÛgôþÆ6m, “’‰ùoW?]üíêâã…~x ‚HÂÑšE< ²íÅ»ßx°†ùŸÎTwn×6Ð&†g¼½øõ‚eQñ@¤%8ã*"1*dJƳڦÅ™Rj–64WTå ¾%ýLÞÒ8÷ã]m[¶~±¤Åvcibm¯QIé¾ð;> >ì\ñÙ}›®Ø|¡¤™½¾ž|t@c»½ÿ¨L·–vdUÙ¦yéÏ^Uí†ÞRTÙóWÆ äT °DkЂ³Aåù·yfi÷H+г(Ž»Íi¹~˜°TL™nçl/ø¬u<ž 3GÝf¯Ý¬ÈAe nZELDI°‚%aHïò¢€½!Ÿ­,=Ó¢¨æ*œÝ¡îìš&ÛÊ/îAue‹®g'+¥Ó5 ¯á¬]¬Àá<‰ZŸƒÆ³|—ú3¯çš“[ ¥'‰úœ.¥×¥?g=>w?£©ÚÞ ÕÓz]ئ¡¹êº[§cÎá¹óâú& —7—G!`bô÷dúœ0jÆÄL$šÔýd¹rv´/NYQ1q09º«R§}CD,Ïs-˜{çÀˆB²ÍÎfù{®´]ƒ•.æp…¼ßÐ+ð™¥eU‚Ù‹üßh¥’Ù¾É1fqõ`G~ƒqX¯i…" ·CøVÅ3–;Ì[÷쪦ÉW~wï.šjxˆóßD‚MäØ}k‹_Ý¢¿ÚºøOgôîL¯íΖkǶórây·Ž÷boǾƒëd¡m%˜ T}Ø×hÚuÙœP¿,½­è éªð‡åž™"_ ’Ys¶ËBÁˆEôX—=&<¦* 3OBƒùÌya ¦y2 ƒ.kŸ0ƒß½oß”à‡@Ø.Ó,³;wFU/!@ ! ‹”üœy° ùŠ31ϰF%3[âkŸ}1UžŠÜP2ãsC2‘éUáÓ5µêøB]ºÄóÑàÙͽîªÒR)#YF…Qî“å #Œ²aÁô¡v®‡†IȸHžØCÃH²˜Ë'ñÑÐp‡çùh E¿÷š× (ËÙϯ¯èåC½ é­ËN…šéJ!fLc ŧ`‚ƒïˆÄPrĹÜþÑæÛuZüa®Ã™'“ow…ÝB9ö8ç0e9’h°1[›¡H›´Ì›­;&ĪÝÒ™UÄÊgP\¸Ëù8ÇñòŽüæ_{ªÁ Ž ‚0É!:¿@¡–)$ÛBénC È=°£Kz½†¾À¨ƒx ‡(#¦"3` ùùKQAyû\žà ‹Õb™dv·±µ= ^ëæu´?éà|&TGÒo¼(¤éDÝÐdmÛ=M• ! ð8dBt0Ï'Ü՜ݸn¢â§÷<äðOœÊ áø¯ ºi‹rãÌ!ÕGÊ;r&ÍÄã®m“×R—¨4Œ™ŒGÚ)=(0ðí™F=†;XsøÌY’^›{Ô$iÑnGß¡÷;ÿv·É)òhØñ±Mw;rë„Pôcx{FÆŽ%Ó&eú±ø¾*;„õh¿Ý¤íðþ¨jŒ»3˜˜vgäv>á3Öãà` ÛN#œ+M‚[ºÞq…6ÍÍÑû`D§À¼cº¦¼[„œC%X€õ¼a¡÷FÞÛ¶ÎWo ’šÑ)– V¸‡2¡$Æ­ïÅ•ÔÀhL³èj8Q€¾k„Ôˆ”µê¢8—™Ô*A&¡‹tœO'‰s$xÓ4˼üˆYgŸ×¶“ž[·O»jóÕø|âˆ/Ó¶KQ “g]ïË ëUã…a¤™—äeRÈU‚ÁЗ‘7¯~ ­B#Æ?g*­˜‰Ä ½#wYê-¶²]2#ÃqÈí©ËŒd—˜½˜Œ¶t)\j¤¬†–¯ëjK˧“ 0À@x¨^5ÒÏ–w~RõBË…;ÎW†G[Dë;”Ý.›-ñÎÄ¢ ŸÚ‰ágl¾Ðà„W/95Œ]î¡rÌœPbq¯z •"Ž'ÙnmÑwÊ.uÝmì4ùød o#äS•Ï“hÁï0z¤vPÂæˆ%Êß˽—â³Crî¡û{.9&ÔE(dÔªn`JøL;ü…—W³„Gã#¯6Ô½‹É'8Çû¾]ø¾Ýååb¿¦–]¸ÄŒÏ¯K(@TûÖ¡1wè5±â âN‡r(»ÐÒâá¾ÍÉv(<ÙïÚÀ™Bð‹_|KÃ'½L·”#|k&â#ׇ%º%®·CPоXõ—ªð ¡ÇGÆÐ{\VtHDEÜl¡Jæ;×wŠøoß–v˜Nønž¥ÍlÓøîõž(´žîC) –œRåðþÃöÎþþŽrÕpËØ¸xï 0âK×O¹’7F }-Äv ¡èï §?€&Aš5:)Á²xÖ´­Ð”»”ÿäPBIýß °z^¿·7yYRjÔ15bîí / ¾Ä3š'ÀÜ©ä ë—oßâÄwÿ|McŸª;ÎÜÜÚfEJ× :ö•xÒ=ÉñLØ¥µ?³§»ü9=–öSË6>yË"™}%ruÏpž O_BµÃÂTiÁ•2c—thếf&èêYÝ™Ã;'Ö zÉú„å«DwåLØïO|: ¦Oï §–¨;êz#3#TC+¹ö(øÀÖµ 9íš ³m×1E†…a見ÁHD€d'3Šq¼ÄÑQiHÄ0£a†ùn޳@ù·"]j%ýHpO?s\ÿW¼\¿`“$Ä€ÁÇe¯hú=Š?ZÅ!‹€)éÅêFpìd,c¡PÀ"嘅‘ì7ôäq"øo4SY¾Æ¿Ž²•vºXˆH­ÅÁíèz+wÚRgÆ_o5m½Ï ø†Å°÷Ë[¼ú^ZºTZwüÇ…¤½B'3î6!wøMÙ …‘Ftÿ9éF3>‘Â7œCàã娙ßç'ëËXËõß—§*"6õØÌ:šSáékÛdýIxY&¾džÆ~Ñ4^e¿ü¼Üçe«¤W[µ/Û“R=ÌÚ7«Ùk¾MÓ㟯˜ãÕ‘²Ï9ì4‰oV ’u§Lˆ·cO'ÍHM×G¿±æ-„!À:ìûVþ¶yYÕ Ë´Ý7ÏŽ! ´#dV÷£3$îíiº®xA8Ÿ—{ÛŒh+»ö®ŽRÉÇpÏ?®5€±³ÿ0áø+€¤@@"ýàS㜠—m=‚Q#–Õÿ‘%cw endstream endobj 4218 0 obj << /Length 2540 /Filter /FlateDecode >> stream xÚÅZKsã8¾çWèhoµµâC¯™Sït¦«gçì©gÊ%ÛL¬Š-¹%9ÙüûPe%éôÔ^"‰$Høø`·A¼¿ø×õÅ?¿×"ÈÃ<‘Ip}¤2Huê\×›àãìßsÏL³2MÝÎ2Ífo‡]¹.º²®¨á™Ëhv?0pWLCÍï导¡÷ßÍέ¡JŠùŸ×?\\^_|º°•(´´Ó( Öû‹FÁÚ¢PåYð`GídðÜW¿]D¬F4TGeAæi$P­ò0É EDa"SÒé(ŽÖuÕ•ÕÑl`Oq4»iê=½ƒ*ß—õ±å–âÖÄh×ý²¡±Îƒñ³¹ žêúý=êì4N²0*ÐY*©QëàScsô†ŽhØès½"UaǶy_q(…@Ûè4á*­ä AëÁ—?hoÊþeA~DvÅõÿmݛ෌Çhw|¼ï-HØÀ¿ù_6Ÿ SØŽd5t¨A iõˆ¹§×Ã5î vï´x©_7§ó"ÉÃHÀq“J…Š[ä'ñà K@¾‚#•ä`v•òõm7_ÄçÛ¶]VÅÞ,ù{cÚ²1Ûöak-„sÇ$ûËOËcYuJÒø®ÙÆ|š;Zç—ï–­-´7ëm;)"krl‹Û~ƒ§_(á²Ë;ó¸¼/vGƒkzÒmW7æù%Ë HØCjûc]äµ€g‚vîx¬³ÕÇîpìhÂmQmvO/êLóÚ%‹uw,vÏõä¾×.Åž_#~k—Zˆ$µ`[HæÍ)À ¶Öl誫‘ˆ¿Þ¾öeU7°DÑÙ"Nìvžqµª¬^ê®—ÃòÉ“p~ ^rÜê{Ó<4eGÖ{‰ÄÆÜÇ]71þ«˜¯^Èö¦ê›—Yÿµ‹&£e{<ÛâĤ‹FR‡yÄIÄõÖ¦3ù¬ØlJL†ŠÉ&É@6‰Â,Ç(@`hæ*š¡Yç"šuø§¦¦‰e!Š³Ì‰Šˆ¹£ä Ýí깊g˜™pbÖ¹­¡×ea]MmíÁ¬Ë›Gj,«›¹¶k/ sÛ÷¹Ì»î¢A[^À¶óÜ™µ¸ª,v-O¼­» u®xõjÁ¼Å¡Î|GvEY¹´ ½´˜=Z/„ó…RŠÍ‹™™Ý©S·¬n©¹>à¦9C+Ü«LæÖX¡é½s³Þ5«˜ÞàâÚpîËvÿð¥8D$¡V¨ ¤—Ù)•”"˨ dÒIÞ»]ÐZSî–Y(`9ú X!Ifßcfm‚bý s,Émd h/+À_ÑѰtè!›};­a$ÆvTßPKßu’âYú­Ò¸šžÛ’ÚiT/N´ÉcÊOÒ˜ô` ŽÍd¯’Å+íÑ’ƒÂ@Ii5ô%k… ¸u µˆÙ’Ø x2kF=|?lCÐIÔ:"µQf ZúÆpÖã1d‘VÂçpµ ¼W»vº¼³¶¶h‡# H)V8.Óq6À™Öñ g*Š'q¦"gøé{DI¶v‘Gp.ô¶ô]w¸oögÛ ²ŸÖÐ(½b¡c‹AÁ®Qò„•Y›¶-h‹ó$ž¹MÔ-ÖÓƒà±1íösž.«§`ô÷úñe„3#•GbH"›& ‘BûÚèd‰3žŠõ….>Q‚yB¤§®±ÿlgMÏ!9 ezrÀ1tŠÄ9H9ûP‘M_E(òž.PuϧB„ží ŒŽ,¬6–/[ê¡XAï ­Ý-æGM#L å=ë =5ë©éüÃaIo§p ÷¬–µý‘Òýe tÕðÛ¶áÓG!îÔR’žGXn"3:¶=KîÆ¢mpu3´g›Ãˆûw‚z°ÄÆfÑP©æé‘T6d$õ#IŸ‘Ô˜‘œ-°Ïa€Äˆ¹i¶ãºã1LRÒÏ ¸¯¦®3¨ƒe´>á•óàŠe,«së+x«’f4ô½7ûÚ±šmð"3~ŸÈ2% ™’Å9ôô8Çi —öÀGUwô²âE¹ðöPv[zë\ZâùRáÅY$_”Â(ª{f¢?šL¥Ù—® Ø‹rþG¥ÂBü2‘þ¹è1_L$æP¨¦=Fm1Æ©¹å¾ÉÕ£L9ý‘4Ê0ÇvgÊf±˜ül/Fqö?¼œH>䳯ñaÌ£PiɧQ}Ái´gð3ih$b/ºèatODáE1Ž.•Ð墋äè"N]9ìzàâ,ƒü ÇÕ$·âoGÀ¢§U1;45fý¶xî!Y¸X‚Šú¥IM´_µ_â?õyÿ½–L™½±›p¶WÜCÕCOð¨ðy4:ãQÕó¨ð¨x‚Gû:HK`òmÇmµ7¤å­Ü—kC-DŒƒ!wåóž„yc£ó˜ÊÖé ‡¶L éÉÊ•ÄøEÿ‰°[ÜžKrά‡\3Þï4‘’†—q.0z)Ÿs1»Êˆ ¤»t€— ¤sPvã•6Œ3E›à%\ÖÃð{;xwäÏS¸É•ÍÍŒËÞг ÇÁy]l|é²IûA6‚¨y¶³?tô:D5`)ä`N¶ð¬øa\pºYúêpTÆ–\bÜ–tª7.?#ýÉoÃ{|!1î%ÎÛºí¦Î¾ µè£´>ú¯ÖÈPSeÎY΋×#ÅàúÄ:äÝ×E8äÀ4”qìÇ2›ÿ'CÁeDotÅù©~"mQˆí=¼ò>é/6ù§\~n¤JÃ8}Êò\ìLB¥ú‘eåoª [‘ˆïR"ºwWþ¥8š‰u+xƒxùoI|÷ùÛFLT˜e£<èTœdïYι5ž¡#£ÄЪà - \ÍeœYBKkp€-×eÎ4‘Q² ½U’,÷‚û`.¾FÌlæ[Ð5žívûq©4žöƒü I,Èó\oD}5ý»Ó=ðfx¯n!¼t´ÎM0a<9—Kâ¼]Ë…ƒM9½RÂÙc\!ð÷ÉV|o©Ïs¸+hŠI„BìIúýÕÕòjùî?¿þøá;ÜÜÛ9ÀäúryùãåO—?_Oh&4–)ý†îO—(i…*×¾ Ï/ÃÓ FUO“ÞH¡ˆé)õîÃÆsÖe˜ÅÉÐú–¹8ó0ã+Aè}q*¥&®Ï® Ç÷‚çW~Cžƒ‹ {š‡“œ<þÌÕÑø‡±†úåÅ¿{˜üÙ†–¡œTj<}x òݶ8̱PádËþüb¾H਌~¶A”’f®"Ä_p\]á·¿~ïý~³ endstream endobj 4224 0 obj << /Length 3442 /Filter /FlateDecode >> stream xÚÝksä¶í»…¾u·ëHQÔ#étÆw¹\wrN¿$V’mõ´ÒFó]}”(­œ^3©?X$‚âA®ðî=ὺx~sñì³Pz©ŸFAäÝÜyAúJ½8Lü0UÞMáý¸ûbè]ÙÊ®í÷—Aœì®N§ºÊ³¡j|Zî±{»—€X·§²#ð«±*ʨý}Y—Y_RGúAàËýÏ7Ÿ_¼¼¹øåB?“^ÀÒ¡‹ØË?þ,¼àŸ{ÂWiâ=¬£F |kïõÅw‚e™¾¾Q„D gEÒë`à øý,½ }FŠË‹ØØ$—~dxüý‹x?^j!v×Çý¥ÞZÔ‹Ø UsOzÈš‚FïÎò'–EÙ UV÷ nž}¦gï„w$~ªâýæu­õînŠ][×í^éÝ#Qð«×¯põí5öCàzéaW{Âɳ†¦5öeA­¡¥ou$¦BtH$!‚‹Q ØÍ²ÀOB‹¢Ì묳”«¥|öY¤áT”øQŠ%áþvß÷Ù©zFŸÛòÝàã$ïÒâ]J ªÐ„ýðw¢¸P—~IKØ“vau˜zë/ïðÖì3X±µaä@*OG±/á vìýânŠ+‡‚ÐVÝüè)2íXùZk®¡§ý@J´ö0Žx@‚¹ªÀÀN/‰ý8…?3}¦~ ¥3ÅT0Ú¼âÊäÔ©í‚DÌäļ\ØÂâóGÉòÿ{ùî¼ï<0žTãéÄÏ«É"È{Ñÿßjó«+ôC.0úÒ<2éËH_¶—Ĭhî‚ujðŸ3­T8ˤ‚µãêÕÀÓP!ªŠßsŽÎ<-­*/£Ô¾x¼44@ŸÆ‘/¼øñ(Ô~v`N÷7_ÝŽU3¨œ)ø"ðà2À3 ·èÐÍäBÜûϰ¼€°gZ]¸dXëX5mwÛÙ0ö§$•†í]º$d×¾­ŠÛ¸2ÝpŸuIóÄù”ÃxwWvvÆÐ¾)ô\Ÿó³ ÊOA5O‰n\öÿVô 9ž”yVÓåÏÑð¤µUT˜uú©ˆÝP Ñø'¡Â®Ç,g ÀÝØä6 Šw}Iá¢[õï’s¥ŒS!7ÜšÀn!õ‰-jÃn´D‘'FXY•Ý'ÐMƒÝ`ùé˼µÄØÀòóÂgs—¤·øÚп˥ŠséïáÊÝkW\“W ÐUQz6³h‘/iÚA%©²k1CyOÀj`ê×wL¯Ù+…¹-p,s¤|Uý±§AJRptJ%"g‹Cú‰ž"?dX@2Œ ›ÐÊ—Idñ‹–[¨_¨x©/#øñ]?žÜÌ'ÒKã0©3&ÆQBÞh™+›'BU]S«+‡‘HX©”›¹C‹‡ž¹„m½}}ûÃטV^í%HøÏ½E]]yõüË—›ùö•Ж€O‹^õÄýc5<¤ÝwÔ\Øô¦ˆœ”Ëh©*{tzTCã–šê ‰ÏSÑ̵ãÁ¶©±yO`°ç²)Œ²`ÌØ6@‘@Û½!(óžÍà˜ d5” #™ã©.`¯¶¦1 Ñ6°äÐ졮è„á›  æ aã<-=n¶X§Ä­Ö|3úÐ!ã̺&¥¬ž¨<þ´Zì§Š ·+rËE .üô™•[ЄaÃLÜÚU³Z—´…X#©”zYÏžªÊÑßà?K£/û~šF#´4ìjfê”=îšwg¹$ƒ­'ÔêÚ¡Ì;DR!¶JŸ’ @w]{¤Viôó «ì‹®=Èx`º™‡³ãɲÛ܃$ f$€•guMS5[Ð8ŽSXÜ!c½˜±œlWhi|%:ºº\H‘ô³ñ,6ú%Û\ÞccX£B=2}MýH èØ@k°`#cgí™rS2õ–Ñ©dœ§Í@ ³ì–»SÆnðý>Ö»¥e“eK8moºƒÆÖ2¼âˆ+¡4GžÍÛ ZóÆ™]yG2•MŽæ#Ùà7#”5±<#ÍÕ†„àº,šâØõO¦©³[ w6ÕNpBð×qîH,­ƒ5G˜Äk¡­öÔ¡˜eX©ŽU'QOÌÖÛª.ï͵\¿eCºÔú.¤ƒs†¾V…&J$"#pá(é¡ë‚hR®“˜fµóÓ hÕVŒÍvWÝWM6 Hìga8ã…ŒÑRÛÆoµã;,“°u4¸¥–=k6uCyqsÄÀ¢ ¨„bŽg:‘€sd„Îú< Œ\´Þ:f¾«Pì»®Dm9àȰiÖ›œÀr²žŽ:vi îBî¡.Ÿ´mÈË jÙR¶² ãÆ%KŠÿЫQD0Ñ•–®Üe'‚ (رÁÔ£¢a:6&Iʃ$?l-¯.å*œÉy_zZƲ„Žå‘e|¿=±)8Yª˜úÎPï.·ÔéøÓ@¦,½Äðo²ÛÀÍÜ\”ÆlÁáÓ‘é*@WæeEj+ˆÄaŠ”YCå«ðE% •Äk UÅH Ë @·µoÑ ÙV×å2ºÌ@í®+JÕϲ j‚È‘é4c gÅǯÅ/vÂ&•낺À51Fµ„'|°-ž G`¬9uÁܼ¥óÔÐè|’¡sà)+çŒÓJÜ@R8Ï4NÌ]È=$5ÍZšà,Ì ûK)›–æÕmCŽ«ÛR íME>µ÷—Ïü ±~è€ETâ§}æˆÿœgŽÝób>²ä‹ 2q„ÍïEü_‡?``þÍO©Ü}Uå]Û·wœ÷¥àuYßÑ =@0øÛÎ8wïiì cÓS@0•nó–« ³ÊéÙ§.mcåÉ)TYTp| lMöm•s c¼ÒÉÙKðvUWN%ئ qNÙÐÑ…lš‰ C;Šhº'€9 4´b OÛ‘)t¥åÊ.„D–ÅÎr//¼–Ã@´ª÷.Ð$²¸À0oƒ‚ŽWÛE£ÝŸ¾ Hµ™ß€³ÁÜð~ìlÍ0ÕÎfiºMÚ]7ûë@‰w¶d[”€8D×Ú” |Qe­Z'® 8äÅ;|øœov¦oÚŠNÖ[ˆNˆããáHÕï´Nfš¤"ä’WÿI‚¥¢e`£) ‚=}Hs>}ä•uY8º>RñTOâèâq…WæÓóaŠœ«“-ÞÆþrû„«¡TÖ¬®Î•‚tY»7ç/nŸ£j¾¹ùÇÆEy”øIb±Ç>£h G2 :’¸Ôâ†VT惡§ +~‚UÜr¥2¤ú5÷îsF…~†–!£ R¢Dùýïï)Êoçío-+.ÃÂW¾+3ÐJþ݈’Â1ÁW"eå؆àOÒù]Æd¼[ÌÏŠ‘_Å' Æ> stream xÚåÙrÜÆñ_GlJ„Ì N¥Š”h…–DÊä:/Žk Ä‚$’]`µ$ëïÓÇ ®ÅR—ãrUø@ zfzúîžÆú΃ã;/OΗ'ßý 'ñjgyïD¡ÉØ“‰p–kç÷Õ"Tn¾¿Ë÷U½8 £Ø=Ûí6E–6EU2àE¾}÷ý"€…›j—ïü²-Öù3ßä›<­s~ ¼0ô‚ůËO.–'ïN Åw>Zz‘9Ùöä—_}g ðßIì| U[Gêžçöä§ß°á{A¨dâLŸûçØÔÍËî\{:ŽöOK‰g;ïX˜ L¤ÏË&¯ÙÖLN$<¥7ð¦¼0Bi3xBŠpN6œ/Jàö÷PáI¥£¤ÇÒ,ìía íß6öÔäpúƒS3x°Áï¶ðÃ'³ÿ>¤D¡Q᣷¶@þÿ¥æzp±IO‹!ÉM™™NnÀr릃ÀHܾ‡žVà=6`~p¾)äCÒ0{I0Ÿ+’¯q®Î5'O+ÒSx~€O?ô|¢\)i5‰F¾ôB•p4º~³j‹²áâTA\z¨ëUš½k‹}¾ÊöùzUl!üÔU™6ùªL·ù¿|å÷{0âøžDmÙÄÄ´;¿ö¿ðC8œ¾-Êj¿ª›´iëg8é„XÚ9+K”b"‘*¦f½j˜Ðßy‹¸)µ+×y]à^„Ín˜ˆ )`ï>7^«{ä×—/Vu>Á¾Í³Çú(=D|[§U=äéMÄñ·Š¹j›]Û¬ž™åê[ÏJ³¦M7OÈã÷³£© l2ø'¿ûAÄ[?íŒ)”^IÎ_>bÖ w—îÁ$0o|÷ݦbxóXÈ}[f&+<Ý›u±-6é~º«¢t  êÞ°™èÇ"Ž™»)DÆùïv8åÓ¨Ý|!”ûþËò]c)H–‚Ö)‡íÄ<¸ÍBø.㈠jˆ$TÝÊš±¶5,qºMÿƒå‰a65Ò¹•?‡·ù†XwN…’^ ÈFš§"Þò+ Z(EX…Ò@}΀W/žóà~!A–{žNÍê"ó™ƒá~_mgø€%;~ÈQ™w 3P XKh70aʦ]0ZªÄ|w›¯ ˆ<_àû"˽ũ–‰{^5sIß‹…ü,]@ˆÖ‘]™–ë9tèK5hΤ+©¥çu…Á øôƒ:|ßø|¯`˜»´®‹òÁ+†äŠÄ‹)›Ó/ooWÏWWh ׫ç7/.®–—g¯gȆ èQÇ(0ƒ<ðT"fq_¡­œ½¹˜ÁÇPdtùPl6ÌS–¶èËÌhnav– ¦î±O‹7£›S¡•§t8ê“ê;ÛØ¶ÖGB gWe“èh ‚”aÿÙß5 ƒ¦^óºð…¸À•36Œó@äÒnÙçu»1H!²|ð(ìÍ&,عÛW¨>>À˜ò²)Ò9«‰·|tÁzÅ M‚¥]y(€së¡„[OC8–?^ÀÄâ<‹0c«0‹¯Ûµñ‘Wß ©EôÐRŒÇ—žn^ke;l¡¶Òâ‹‚ØIoƒÄOèé†*Š0(êãgOªt˪<5QWCz £±Ñõ†à»Èd÷ëônƒÚUSÓñ0•vIâ‹0—Öë2ƒ 20ƒSBðДò˜ÖF¥£¶Ḃ”‚RÁáe¬9ªàÉ¢QÔgo/ù}SÜíS&ó#Cúp¼¯ 1á‚v ª “‚Uì÷Q1J£b쳤p£=½/Àò²üørй±1z\4 hZW\–òṲ̂#–KoÇÈ&å$Ô0‘ zâ9¿›)²Ç*Asä…80¹âÀ¸Ù™èkRtw9Dˆ”5œR÷»˜#°~pD1Éà4g$$ÉeÚ˜‚lS ^XM&Ñì@Ô.38òThó”ZÔŒ@Æö…‘ÏЯH´%(í3ˆ2™šÉ­Ê¨ži‹[ìÝåãæS.”?áb&Ú^¢Î•1|Ž„ÚwË<_×<Ç'&J…$ã†1Ü÷x݇Ç(Ù,üÙ,¼ ?« á„mE=Ú14ú)m}JY«‡…¦ä~8¥¿Âz1Ä%1Q)tÌIÆWú¡Í)´j˜°áýC9úˆ7*c E‡Ö¯nÎÕêåÅ’jÓÕå›·7·×\K.€åõÍ\çÃ…³Ïp§æS±Î)s ôP”L±-h8}Ç\õdUŽFø‚z% ]Ç00”†‘Q{ó\—+þù-ÝßñcÁQyŸ+±åùÔÄ¢}TÐ!-ó04µÂ8iޝ©«;*¥VU±æÕ&‘æeÍF ûPCÄ< P>zZESL* µ¨è )ƒìå¿5óÜA:K5d\øš>ÜÅrÚçx¯ Ã?¼Ï­æÚ¿ê û«›¿jØûU­_Õw~UßøUtûÏÊߟµ¯­ÆmmuÐÕVæ¶’F:C¹ º†¶úsô³á‚ç…ÇÛÙ"†êZGÛÙªaŠBÔÿº‰DÔ¨bÈázQ7=Y“~6½òà©í¸é\Ýý;Ïš£ëïÚûû|]Ýß¡‡¼N›Qm¶vL›­XÉ[ ™Ø6 VAm–qƒoGZ\>’Õå‚Oß•Àx“8ö0 9Ÿ=¨c:¼xÃ0è0î¹'sx¬ˆ ðèI# ޏ3\×Ü«ôMS±£³ë&?…"`K…0íi¡”ùÞH‰v¢àº[>\¼XOo@)\91UcMÌÒÛ–H1\Ĩ‰‹S¶Þ/³bGÕÀ¸\õL„½G`®ç àI®¢5}(Ķˆƒ/Ò_ì'#ý!UÃt¥–‰^‘ðú´"_yA¢?S“§RH yÒ 5…Â4ª#£,(+~Úº4ßîš¼f I˜€Ø†K09…©Eiáäò S늚<0bÞq»ÛQ‡[ç°­+w'µ°VÔH¢O—j\[æöyÓ2’r¦HžD,’oW?›’8œÿ\@éž]¾>;=×nEM¿+ļQˆñ¹‡X`þ„€nÒÇŠ~_€–¤9ò¼P@{IhËæxŒþ‹Á@èûîs°Õ2Ç«ŽÐî]Q®¹  Þü1¥ßi¤˜æ›Lq.ÊÊýÇÙÕÕÅëÕ9êàúç««^/€bXðËqùèê ï°“wß1ÒÍЄ-qf qµ™&ƒDp΀ÖÄóÉ ›bK×*a?r¬Îª]Î0’N¹ÃöÁMŸ"½Ûõ£‰_„ïÊ%¯âÃc‘‹Ø„‹ÌôWaü¹DÆ}ñ©øÄ†!J[úàiåzWA€Â¶!ÆÒ–Wò"êÖÁ¢”_—¯oùý¶¤iÈbn€Yn©Åë5^óÁ…!@õV8{ÁÓj[ÂO˜[¼¾£ðqñûÂt¤¨´—ô7¸Â} ‰†>ê¢75«ŽŠCÇ‹àž2Ó–u,òÂv Ž·E±n2wCezÊfušáwÈcë¹ÉqÊdt:_ ÷?™ñl‘FÜEmð z'ÿ‚Ø$×MTMjžCg@8ü`j,€[2f=éÈ´˜ °M^HîN ‘éVäÏ>/ZBD˜‰g‹Èç@0 —®)zRUÀ}“ ŸÄ7í K!µJâÃÁ§õ2—±A;¡è26'lnú‚ ¨tÖ¾àþ«ú,Ïß`ÀQ¦.À›{èA0–Š5:¤ßÐ µŽp~•#Y°3h;l–8³®J‰CÝâûH´¿Sãiäw„›4]+nÜø}ÁiÂÎ4 ¹ôö¿A‹!Á¨Â•Ñ@eüÆÏùá/:“±‡¾{Ú;ÃD΄<‚’¼Œ>ò± ŒìÅ€H,ºë¶×&—]ëÀB¯­/ÁtÖk™Ê5tßÙ¾ª«û†¼º¸9_½]]¿]^^_pÏ—¼nÒN$ïép½¢²Ãþ°!ƒþ|e¿Bi¨s—üEøïLõ1ù(SÛÜ6}ç‚£sÌò¼Úܵ²¦ûz óÒ|‘ÍÌ΃’d$]™Mvp^ü„Ó²ŠŸÖÂù ¿%%º+TêQQ:ýA±âõgþžxöçÐ\ 0U­ÆN0þ~*ªÝ¯6\}ñÏšùç4“ŸCsÙ®>ý2Ò=^CøÛÏöÿ@¼bJ endstream endobj 4234 0 obj << /Length 2176 /Filter /FlateDecode >> stream xÚåY[SÜÈ~çWèq&Å´û¦[6•*°1ñ^ k“äÁ»¥RƒUÒXÒ€ÙTþ{ÎéÓÒHb¼ƒw³út÷ésïói¸wéqïxïðlïÙK-¼˜Å ¼³ OFšI{¡Ž˜Ž•w–{ïß-¥¿0͹iêv¹’a´8X¯Ë"K»¢®ˆðÂ,%_\/,,ëµiˆ|¼)r³OïoLiÒÖÐ@0)™Xþ|öíÞÑÙÞ‡=òpOx¡„£5 yèeW{ï~æ^ôo=ÎTy7vÕ•§ƒž¥÷vïÇ=>ÖEE#]—àŒ«ÔÈPº÷iU™r¹RB.΋*/ªË–Fi•ÓK÷ÞÐKQ]‘vuCü6v©ZTuÇ–+_Ä‹³~íwGo“ƒÓääôìÕÉë·ÉóÃ3š0Kå/>v¦j­±tS”N‚´lk'ËpfVnr“ÓAÅÅV$°Õ³—)Ƚ•,ö}§_Y˜ªKÒ¥æ‹tYÚ,_˜d¤x2èlÙMì%”Ï|_[ËîÚ±Xc‹ô¼DÏùðÚÒ³5½tµÍñ B¦ƒ°gÕ5³ã@©˜ÃyEEüÊâ<7öðMÙµ 7z+)¦•C+˜§N:ë!ßGQà,š>Ô(˜ˆ÷wX/ŠYýéÇoÁgÉó¿¼~}ô}rˆ†;ùûëÉËï–!_ï²W ™ä4 žÁARWëÒ\KL) ¢>ÄPP6°†¢ÿõNº´ÉFË\ À:²GQ݆P]X€u|Éx,§ñf™YSô௠ä,r¹¥ñ4€0Ê‘¨ðB¢ÂË8`è²ÁÂ@ú‰ûü|ãõºÈ‡kÔÓ4m $P¨Å¡én– ¢ÔT´ÈùΉΛ ¥Cì>¾È¡‚…:ž8TôšðDËê˪ø…²Dr ÒŠæ'õÍ¡üô]Voë"‹2` ÇçoÀ„Ç£ ZAÐL­c½ŠÙVW}PàˆŽEÜÉmŸYºiÝŽ•n¼ö¼¯®”Ù ê4gÄåL‚% ªÂk`âñÍ1]MB3¥é¬àV1©ÚL?øïÝÊç|qptð‚n¥+Ó¶éår…V'Ê ø,²^ƒÍ'§Íl²ÉÌ+I6{-HBÞ‚3벬1ôo  N$œ¾¢e“K¢%fSn²2m0ÞpTÈ»•VD!ãÁ´¹ÖÅ3z$æcÇÞÿuW°p(*ê·aFÒ±F3žvîTÇçôf 37Mº&ŠMJ»¨Â é'‚Þ’R/Œ C,†k}†7E÷ž‚%ÍóÛ‰´¤ñO\ò´më Êž´<í tHábõ}A‰1½— ¨·äBw9t·Ô+Zk2ìSþ…ÿz®¶b9Ø|p?ra>¤Î¦[÷{Ï7íÊ4¦ hó±Ìž.wMA8B#Ô·AAÄ¡<r¦¡VÈûàÁÚݧ9-› ³+OQw*¸Ç}K.aäCÁèin*‚VrDP^6žŽ cø³û·TŸi?ã-OnáöÐ--¶ÛQÙŸº%ñO>:5ƒ‘‚ |ØBn5Ìþoô¼ð~ô ˜b‹>އ¡†˜þ?4<$ Aé̦¡¤ŠHZ»ùnf°[O » Ó‘rïÇš>4å[n üè$9+Mìc­áöZÃÜ×$_’_w. ÷ìMº bÆ<1í" @,¨˜”[ÈFJAa+ØÉÉJŽ’pO@™²›`LR“æXÁ·óT4:¦ÿgåPÜ­œþ4¹nफ¢ª›¤íÒnÓÚþÇ͘/ãiIE ²îcRäIG2e5”Ä]D^š}'·'j4"A&dÖQ3™zöIc>$¥ívz3|¨×½ø +Hêžk°•÷|sqaš~uQAYMlñw3Óþ¯o\§·eæã­O¢îc|gm„®3÷T…î–„®Qã&ñ’þ†nÓÁõ€¡bñÉPÜT¿]0zŒã»¾ýl,ÞׯS[BŒã…zºЇ1 †=6¦«Î)íºÃ]…3L¾nLk¿L!åj¯5ÂWCM‚? lzu‚ å_9)®v!'$ϑҦH )»‘’ïÛo›O”ðŒp¿¢owð$¤´¾é…Y­Ë4s‹L•0¹]#ÞÁÏ€— ÒteV¸¤Eœ6>ãá 6aÄ5µCJÖ@îÓŠCF”6¾\ö¹OkÚk ^öòª\0B[ÀÖÄÔ‘°›¬#ðº›}ÛoºZ§]1|+Ü»Ь©ÛúÂÁ¥ÏèåÍéó§…L™0{ï–Ø}Oz>E¡`zFQP.l§ÛClyǰÀŽm³kß¶í®ò- îøgVŠòJ–Ï#›ØŸ Ž:„b6–w D¨ÇP"4šècU”¶3]¾*d؆ÝNÈ 5ÔÝ2t·kƒ_¸í¥Ûv äÖ¶c+êë¾ÉM›%ãùÛ’ ÁÄRL ¼±»GƒBw>Ê2¿ö¿ùL›Žr‘@Dp-é.¹þóIÅöÝ̘vƒØ¿ÞÛ ö}}p×füg;:ø]zÛY =ÚuÀoÿ¡ió k£hY½©º Rsqp/¤ö[¦âPJ·À|ªè˜…ò“aý»ÍjÈâî3üÅÒ‡:¯]Oè¡#äh­¢Ú˜¶ÿUÅ}Jví*Ö)ý¸g[È]=øü§p_Cç}ï_Âïþš,´„‹G¿˜à¯n:¾ÿOМơ^„qAÌÿ‰Èáú endstream endobj 4238 0 obj << /Length 2776 /Filter /FlateDecode >> stream xÚÝksÛ6ò»§®ÔÅßd;÷AuÏ[ÉL'Íhh²x¥H…¤âøæ~üíb¾D'Vì^›~ˆ°ØvX1íVcÚéÁóƒœ8¦¡gyÚ|©ù–æ;á„¶6O´·ú¿&–«óò†—E5™Z~ Ï6›,£:-rñ‰Åô&fņ—>ݦ ?¤ï+žñ¨âÔ1 Ë2ÌÉ»ùOÇóƒ÷&Â4“¶v ŸùZ¼>xûŽi ÀÒ˜a‡v'f­5Ç  Í´ëƒWL²ÁºìØæ¡ÏLdDZCà b2ó|âéW沸Èë4ßòhr™¾,‹5}mJŽ,H‹m%!Ñ­,#ª›m ÓrP¶å­öÐÐÕ)ò¬8öÃ3mÍuƒ¹.r­½×`nˆÚpMtãµf“ |Ûp]W€3蹆eš(Ç÷ä€iØŽmu¶w‡]f8°–u¾lêÓBÙ0±cü‡í»Ô^i ìÐE¹csÚHlýÅg>cI6Ã6,Á‡+G>€øh†]¦¸x,_b0ÊÜÏS/4˜ -Úã:ȸ°|Ïíd‹!¡æ… vÛ#Ë¿­ªEZ|XÜl—K^.^Ådцƒ’R?‚žÈÐÞN]8ïÀ ø%&f;H¼MHzIš×4Òâb›×xÔ¾ÇÚÔ´™àcjÙFh?/¶€Â¶&bruWFÁZÆóÛz…G¼õT×i^”‹ªŽêm%x•{@ èÀ4Á ÝVºqýq‘&‹š(C/Ã?Ö‹U”'ßCLLb–z{@^€~¹(ùûÅ2‹n‰0¶KÒûb£èÁO˜ÿd}=E˜‚h”%â?ÖDíc«Ê*„­>l¬%…ß¿»½‚·óÀeýED-¢|ëë¦ {–c„L†ùù ˆ:zef%ŽïëÅ’`Ÿ1±!ÜtSR2—Š QNë"Ìj\½Œ&6Óïi¬‹K¢YþÊl[IS W˜Õ¸žéÛ¸Þ–”2um[çQŒc+ÚE”æi~+·¦¦¾ßpEK"‰yèà vÇìewwc2µaó7“éQ–Ê ·‘ OšÇÙ6áßõtáÅéˆÜô t’7Bs”WY&®±;k ZyÙhòéõõâÅâ‡×''ÇW‹ùdj2ý—ËãÅÑÄuõÙÄcú|âà×®¶MÈéF}BôíY0SO¢:"€’õê‚Æo8õ%‰êÑh½âjúo˜ÔòXÏ!Ñ·x,‰Ç„1Éö~S+l…Ü3á½1Έø{Ÿn²(æRüK©‘•4ÄÈq©&°àÐI8d² Çú³Ô)˜pÍcØÏø”ú¦¤‹gWßdz£ã«1¥¹'†~WiÀÂ\±èðüÌ.ϨGs”ù¡Sø&¥ÀÇ6GÌÊP÷â 5â/n‰€u•Æ=LðõiI™žmøž'ee?Ÿ¬æW³³ó„ïAa}’­ºŒRôvÓûöTä¼o@ L`õ6-?g-¦GIä³Ëàr0}vttöÝÔéC²p»²°Ó/QÛQ’ªÃPœKÀs‰m\¬oÒ\œH½KëÁÅ¡Âé(`0Ù’<.êžiqËE 06±°=ÕSö‰Äž;Æ•èi-GÜ7IyÌÖ›Œ¯á̪4LX«¨‚($…¸.àð8W@›†s‘›Éy+µ@Z€m¼ ´+” \ým†Â.‹é‚Žk‚Ü¥YFŠ×½M܆„‘@Ôq¼`d”«³L-3vîÒŸòOÏho×Èðüêxöó¨©Aöô ,;AS.ÏJŽšBï´!°Î¹‰ç ›†nœÝ‘„Ézñû-K‹¨9¥ã3ûŽÏd¤5SÅó(olhîi ‰Jõ®z/È^×QÝWà Wî³ajŸ°ñœj9;}¹¸xyŽ)É/cš+¯ïØ=͸"ä›nOÊ1‡PNm'Лò°à¬•n¥ ‚úSŽJͬ¹ô®äê{–/ ¢3ÄcDó[µ]JÅH’GCª /ÐÅN>áJýµyY¢zŸIêŠgKƒ¨‘yqOq­aæn>ì“¿Õ0çì¡o¨“¥d‰Ø³ôjUl³„F¤S‡‚Ì™RJCÍ2±ûÚ£àÞ(ß ÿÃË‚ ŠîuQJê2­•U£WÍöô:{b6—ónZg«-r„G~†ëœÒÖ^âY‰ÜÑ}ä6!WIA?…IÊÔöB™ÀØš¯å¹¾§•›Mv˜¦vvh’Û†@™üV„mrDJÝ,&Ú>!·²Y›..éí–L¡/è‚qaÐrEt6ò&U§ñ6‹äÌ¢LZ.­@?[’€´«ó¢wŽŽ Ç!Î÷ `ÈnG<‡ëÃ…µÉRI¡º‰÷iÐΈ"aVWN@¤ ‡8 ß9¬‚iÊ奰|Ç0ݾD!ðfòÌî­ËzÛb*LÛv†rë"Iñ ½¶Ð\ç€ [ ,[^!ˆßxeE^kE[oÐ'!¬õ£A7'CQ›U"?€ÀNzê:|¸/¡3îòOÎgèCN³óó‹6é®w<æô}Ï`vŽÑꆒËÐç8 Bß í"[åÊ7ùÚ}$¾ì‘K?ŽGp4ã0Íæ4¹‚ÅK^^W` f[€… øJ»AYɨ¸½ÀóDª…C`U´÷ß•éàL>N¦GcB ÕRB•çfê2ttÔ àG+#Bîxëþ#VÿåƒfÇ‘Äv#‘m+4¨ ¶Q¤¢©w'V£ÀEiâ‡×ˆ5!x÷ @Í‘Â=Û ¬Ñ »!Ë•·GøØæ”Þ"-HËfÓî^$(T¿c‡úœ¢ŽGE`£>Çý>¢F˜ÖÑ ž:lW2ˆ™;–3â{…{©Z¥Â?]iÄ5˜(¥„¤s­“‡@-À[ȈWŲÍÏâúã˜ÑˆâHωâ¾d; û0‰v«i2K¦4G¦±7 “•ÂÑ}?Ç ‚|€z¦*[` ºGW‰dµ±)ZQ•¨)a9¾(\u!!\½ ­ˆQq«-—QËhªì¥JE¢ËZLâÙŸŠ–Ïãö±Û+Ä5Õ5ÇôAÄ”ªÕaá­­ãaOrÔãG° × n†¼<¥(7lwŠt­ÙíÖè|K³,f¸Öx©`ý»(å7>éÿØ‚‰z6«NdMJ°MÉX"Þóugø–ÿnt¿xYÛžõ£ª.‡Èß¾Û·ÖðÏA ÊrÕ^žÜ½i~ó !¿®ªè–ÉÒo†¼6rìÖ…öUÛQϼqb:…9á“4 ˜‹œ]¼i.õýgà}Ðÿ÷è!Ù‘‰Îl~> stream xÚí[ësÛ6ÿî¿‚Ó7T3Áçez3j,»î9q"+™é¸ -Q6[ŠTø°›üõ·‹Ÿbî,Û‰“\ýAÝýíXk¦]jL;Úûi¶÷ôÐâšoøŽéh³•fz–a _s-ϰ|¡Í–Ú¹þï‘iëavfi>Ú7]Oo6q´Š(MˆpŽL¦_8tŒÓM˜ù¨Œ–á*OÃ8 ò*Ü0Mƒ~Ÿý²7™í½Ûã Ó¸æšÀÚ2\æj‹õÞùïL[ýÂ÷´Ùk­YŽÏX;Û{½Ç”.¬­“ð4×ð]ÆQ'Kø†ã…3Ã1]Òé7f³EšQR†KÉfú*K×TÚd!ª|¥e®(Á¥†‘Ô5[ƒ›¶åkýgv©}¬iz„:W;žáp¡9Ü5<ÁQkí}}4‰Å¨[¯ºXk‚€p…aÛ¶$ÇP³ “sÄÆrÕÀ a ³EÚ¢Uó™aÁPÖ„üUÃÔƒI~‹GâºÒ^k´o#æø8ªÑ#¿À_gèLÃaL¥„eX „)µ°UK­EE -ªšÏ”·Õà.®R9Z¥ñ¾ãŒã“{°TQkéòŽÝZÆÜãàMžæø€¸pÈå£ôú ù®Ç Á—#þm °ÕÎ÷mpx«ãì´nø35 Ãî–E£å, Ìòôt#Ö>g¾”kŸs°£­äZu˜ôUq iºzÕÍ'Óéé+ëà4C™ª…©Y†è´\É2ça–ɾ4v%Tp%4A¥”%UP?R©¡Ù7Á©L`b ÉL2yÚÛn1Ϲþ}^)Ò, ’|wEÙÇv¬ ²4û¯èÚ†ã›ußâ*Ìn"ܤQ²*da^ưU^Rõ¢\­Â,¿=`çºqt$¯ïïk×Ú¾ ‡™í({5žtFK4ýežÏ3:æ°Hæ¤öØEÅô—Št-åf»öäבfàöLmÇ+8³<[cRaı<‘¡¼LÜJIZ`ÁÑxj_¥i®º)=³ð݈3½„С âEù¢š &Në0[G‚é社¨ÞdÁ  8LG.Ó1ð-=R“åWi/© ÓZY›J=<Ó<“Ë⊤iqÙ³î’W’£˜$]ážS%]õZžŒ&Ó'Ty5ò™>>88~‰ñÍ‘¢Â~B…Ùt||2™R¥‚&7Fû‚˜häØúx„ÝðgÜëEÕuYëŒJ†MFšBô¤8Eˆ°í4bV¨’F‘šeŠÍi™02@.–€`f¹”‹É5–а"J9à¹H×›²2`sŠx¢c,Šá÷¨!bbY WQñ ©{Z›ŠØÖªIXÍI^X³ hTDA}—ˆ#øÓÏa¦Ä‰rêS‰"¡©ƒõ&®Ø®†P(sÒb¹»4*Ón÷Bûÿ³ZÂòqâRá~öO8Âp}ø“㪛¤ë7s ÇQ¦ £Á¦W\kÍÉZ\Ÿ)ÈüÒõ¼UXë}þ°4PˆWuËpl¸r5³ò-NXS(uð‘h¨±˜ÛBrŸ8¹ÿÜŠ›9Ü9˜°‡g¤lKÀ9¬Â„Óó2J aªh±9>ëì5*ÐÆ­£‰#æË0_ÔQÀùQÀvðû³¡½mqd·Up‘YòDãÌÜ–n‡pI ñc/¸3íJVGIß¡4¿»Ã@}æypÞeèw}UŸìªj?Ò×7Eã<­¸tWa÷1B/,Bñ~ÞÏŠŠˆ·´ãÓ·óŸÞN¦óÙ¯¯&sЬ]xWµùW¤öÁx6þ•¦íé^S\qÞwÕßgÏÜ¿~\UDú  Ál­Ëìmà‚º¾}ÞsÇ2¿¢¥ûJ^ýŽdõНHou¯2· „që†UÝÁôË¢økçw.|û ¯Az>}új~09¿9™É™5n9øwwŸ—oNN>É[Ÿ»½qmKøE¾pÝ]§êõë=tzÐ]q×ÕðÃÐjxäÀïÑ­Ãü6ÁXZ|ê<2ÿŒm¢aºz U\ohlp3KËbž®æù&X´v¶&(êîJê,ØÙ£EÇ÷]ƒŸ&p¼/³oñþ£ˆí×mŒîàA?Üå“Ùßò™ô Þgþí}_¶÷™ß²÷‰ÿïk§T|š«æ×tÇ”tºPÊëæ`úÌßi=ÿë–ÙË—hòwúY¼ú|ÍñÛwRÐæ‚7øÉ;ÀOМë*)"¸ˆ£üJ~̆ÕGf5äìˆNºm¸®SéM?x>™Ÿál³ ©ÿz2Ùw ×tÀ„(N¨:~b¢\‡è¢&J”=Mî ù~.ž§>rôˆÒªY]kMŸÓ´–k»=ÃvµLö½–e9&€d¸þ»"ý¿¦‡I^!½ÞEt‡IãçT×ëYû&’Ÿè]¡¿ˆYš§+4‹kêѧ¯žSÒ\•S€„4!sFå¢Éãú±êZ\Éä9:¯RVÉ€v|ŠÙ+o©R'[È­³q¹ ©) ÚÙñÑËùéË“g`]¢Õi4%Å3Õ{+kdàðèÂÁÑ‚{z‚®K,û[|±}h$õ÷ª)è+ MÑdû` æ  •2I’fKjô¥J¼zt̯A’jëÏ)WYRäÔ–…ë Jò!ƒì"*²@eô _Éô¡Ï(#†éA')íÜLáU™E5`(A‡µ3œ°sª&¯¦Œ‹ˆRM F¹CLçŽ*ÓŸŠP% ꙤµË: %­dAWܺ¼#5¾ÌÑ]+L\âùÐ\&È´“©‡(øePåb µà)3Á–TV Jr¹À³ñr¨´¼j”íZѦZš¨ÂÍUD¹dªŠÒ¨¯– ½Ü&° ÄZ¶3ÆllºC¦í¬¢‡¹‰dþ¢ªÌµ Õ&ù~STIßQ²¿‰áJ¯j«ÆEzP»Á2%!Ù¸mµgyÒKÚZì-«*s6‚QòSKÂuºŒ0î#öÇ…JiKÀͯ¤°›ˆåyw µœÂSL=Þ8…Ç*§ðÈáá'Z¬:ž¡ÑgÓÉø…š ·‰óa–R£ôod™fÕð>4­)r5qZü¸=8µ0œlÛ#°G-€ ®cƒ¶³+5¢-~§¯¬E9õŠÂ“ðBé&بV%žX1´RN6l®O¶.o§ÇÛîñ&2uÓúÿa[†éÜú_#¶ÿ½¦€ó™s“`åg ©cù¸öÁMÞÒQD™2Qÿ¯q’Ú¸ÃÊýK˜¶#t¿/ê»q± endstream endobj 4249 0 obj << /Length 2423 /Filter /FlateDecode >> stream xÚåksÜ6î»…>Ýh3Y™/½’ë͸‰ísëÄ­½íL'Éhd-mëN–6’ÖIî×@P»’vÚ±›öržñŠI@ÉœK‡9‡;ßÏvvwb/DàÌ.œP8¡Š<Kg6wÞ¸?N„ïêú\×U3™Š0r÷‹"ÏÒ6¯J¼ÔÁÜ› ‡ŽEµÐ5—ù\?¥ò©.tÚhªpOOÞÍ~ØÙŸí¼ßá@ s8M­¼…Nv½óæsæÿÁažŒ#çƒéuí¨ ‚oáœíü¼ÃúËÑhœyL†´Œëjž¿eRé9Ð C7/§‹"Í4ÕÚ ¿‘;×ÏÜO‹Öök*dUÙê²m¼ÉTŠØ]Ù¡/'ïîM|ßáÏAÏ—0™4œ€Ú‡¼(h‚sÝMŸ·yZäÿéè! BwQåeK};PÛMÕ§®7OÛ´›¤½ÊK;†{7SνØ÷‰ g(§ÙéþÞ+DÃ×T*梠¸p—e¡›†šs$„ ÷*µ‹v÷ =Vs©<ÎLf&9<;K^$ßÿrp°šïMBæ&{ÇÇ'/P•ö&аOx"ãAìE*êði~zI7ºµô™äÃUž¡Â]‰)WhËs\¥&HŸçÈœ©dx3drºGÒMé“U‹‰–S­º /É$›2F” ¨‰’Âý§®5óÆ¢-é«'Òw?N8sÓëEa;½e>³zœvE°âp‹£ªër ¡§ˆW>sªK#(_ ¦V5URút;;=7\H­/É6AÙ ¾(à.fÌó¸ðU쌿õ¥s[Óé!«ÎT‘péø AŒ+4WÎ{úÆÈ5Ũۨš];’,X(=ß÷ ¸€šï ÎQf* l÷$¨O ¬ßìÇ^ß¿‚(ª Œ×8y lÇõ¤kXh×µ¢›u b=œ¬7k5 Øj}˜Yaö³Î çg” Œ*|WB‡ýÞW=€,X°lSž‚% Ã7ß¶¬øÖˆo«f?¶·õ€yç,¾7Ö,—ü1œ±c cîÊ’/Ù_Ýi>þv,ÂÁ8|qÛ).¯æäüáÉøÐníÈÉ«d ¶FŠÉÔ‡ãç:ýWU?µå¼¬ê烃2 A—M“äÕMr¾¼¸Ðu2×MFCø¦³ °^ÏG1JnÖ‡Àz‘ Îv!x·šOÀáÃiºûbeXíh…ݺ3z¡ÑÞxtûi¡ïÀ0â»Ä£ÿèä×îðŸýöÓ~rfüçÛÜ‘?yÙ$Ü¡¸I‹åã°®Åøå’=ÁMè¨< «øÿÐ>z¹7ÛÛj«ŒE{”iÑê-Ëuº@ã×ù¢weÇ߯ì0æÕšÚ¬ýhK¯9>Þ,Â|Oï!93fö¢÷Üba†6E£ –°ìÀI±>6ƪt1À>:cxà™SÛ*>C‰íŸžžœbÅH‰Á#2¦ž'¸·Ð‰®kÓ—mLýÕÜAƒx±àƒsew°†;ÊñÉ6Õx aŽp°j¢Î/dt Ñ¢ ;æA`0¤ñ÷ñY’òòs’àΉUÄô'²¡V¸&ô14ú¦ôi–ç]ô‚Õêâ ÀA¤Œ‡jöäV+úå+º‡yò%8RÛÕ`¢ežP^2è¤7…Sàý+ðKÁ]˜B ©ò½(VÄîqþÀYp…Œ¹G'àþJ™­WG/¨`ƒj“+›‘¢Âkô#— Â(¯$” u‹¢Bô(p]Ú ¤ $ uEó1×Y±ùœ ¹ ä‡FË瞈‚nOüÌ}ºÈwé“è­wõmi{‘ {ÖŽÓ$™Ieõ`Ùôæ7-õ*í@๠’‰à¡¹H[“"É R\¦ («²ÌZêj3À¬ñÈ¡–ß W4 É/>QÈO€¨;&¾´áÔ— ±s6MR ™‘"fl¶âqs‚)O°è«ç fW6bhRÅЂ³z Ãèp][ňkëád½Y¿V®à¯¾Î;å ⯟+€ r £ã\,¾7Ö,—ü1܈º\¢ý+ä pÛt£°5W ˜ðT°=Y€ñ¥n“ë<ë<âu{zÜO¶ºÇIÓ¦í²1¾¯Ã¥bÞÌD€óœä󤵮4^D|lr Ÿn‹ƒpÐûjÑÀb­ßßÚuœéxèÊzÎü¼¹±ã]¶Û\¤1«–e»r‹a˜åWÏãý¼ŠDÿp9ÂV `£|3‚Ügo £[ôç¥q£k8 ¿ÚŽ—'ˆø£Jâ¡T"¤Qcûqä6NW¼ý²°çÞÂaÎcQ Ã&ãÐÜÑ ÌìVsÝÜíXtën¨qQS-–}7žšû ·Ní=¶õQZ4IwÛiÓ¹8täj.k Š3UèL¦Ýõ¢¡$ÍKã6š) l>––¹-Ü&ÔÑìègnÎŽ—ËR‚ƒkZäö §±®k^fÅr®ŸC_5LN(‰·i¡K{‹ÿÎçñ˜þng`¼õw6™B(c2Pt¿×·…¥-±‚’Õæõãà¾|„PýÎdgG‡¯““×Çȉßn¹,•ì°<©qNꥸY¥ÐÍ¢*çFpØauãMTtœ˜Ü1®Õ ™Ø^éFoÈÆÞ8CéÜ66ùe©ç[®.éúxkŒò´ô¨gUϵÝÛ sïsš0%±>º&ÕÉìäÇý×Û>u†=Á ɳn€ißûéè6xö<‰#/Š”%¾ûR؇%”‰Pw×Äøú%Ö®;#ašìˆ¬º>Ï j^lj­!ðƒ‡¿rþp¹Âcò?0k­§´n[(ŠGÎÃ{L',5  ðUHjK·šMl3[epØtƒl¡Ç5xÛÂ1?º¸ææ6Ôô¨$¼ÉÀ¦F·½Þ›<™Í»ñøåV&CT¶ù’$ \z³äÛ}€ÞK¨¡^áÓ `7.Þæ/6ŽÂA ÄaqÙ⩨Ë:@àØ`ç?ùÊÁß>m}º¥„ǹÝ,°Ï§" ß}q•.&¨96IbÞ`hT<~»E‰h·ï`ð×™y6„;vDüTDök endstream endobj 4253 0 obj << /Length 1649 /Filter /FlateDecode >> stream xÚíZ[sÓ8~ϯðð°“0ª‹¯ËìÎh³…B  Ì0ÀxÒDI¼ëÄÅvZØÙ¿çH²c»-›´ʶÌKÇ:·OÒ‰ô5ÔšZÔêµZÛ{6³¸Üµ‹û6á"°<Û'v ¬ÁØzß~ÞáN[¦Ç2M²N—{~{çä$ŽFÃwHæ'±”Lôs¦¢9Ói–…S5/y8Fa%TÖöŽ%B øt#ãh –™ŠËÑIë– XO(ôSù ÃXJt¡ð:Mnï¹njÆ]b{.8RFùg=¨6Ì&6cÅ•::βå¼0Ÿ'úy,ÍKý8¼ ÕÓ(Yf1¶¾h¹ nx s3+l 2@ÃÂe¿ªUF ãŽXÍg:µ.{uØÃµY¬L×'.°ô<ÂlW§õÉ‚±¦gS=¬ÑÍ-¡¬'ˆã8JCÏ!œ1\ÚyÁˆ°¯„5ªô8 ˆÀ?¥_J9#¶ãzÁÊ&‡¥®œ®d#0»êŅוˆVlÒŠ×ô(ÐBÅ<¨ÊptgòœX¯-XLƒe½r…è…ŸÁÆË‚ ¸MmŸ+Üó¦Ä­hÜŠd`7}N‰ë@\Yƒä+ž°gPªá£1º ˜u!¹Êþ*ŠwóY@ÚuB¡ftqÛ9¶úRP…Þuê…Þõ<"\]Yú/Âe´Èït¨óáŸIºeÚÑ"I]T±jDÉix¼œLdŽe6Ò* |_TÈ—88‚™ÄªÈ =Ø$‚¥?.HÉèò·¡YzάѶqXñ¡´k­MšÚù—¹…Äo #JØ;: ÷ûoÃÇoöövÃÁ»W»áÓÁÎ… ÿà¤õÜ^ËÄé0^^8J¸ƒ#løp…V¬IVŠ® ØÎ¢é‚]EñA3ÙÿéÆr1…cÏ5'qä•¢óM`e?Q=8Úï½ û/ÞÝÆÌïNQà·§(°û¢ðUXÝ«ÁÊ¢¢ðbÿI8è?ß}¹©‡Öð°w°Ó wúOv»õó—FV o$7u//á§Åy]Ði‚®Ž¨æ¸ ×XÓÂüž„¯û¯Â§»{;o[åétkƒ¢tÎPñ–üÈX¡´(Ì…š¬lïÁy{uønV‚IÍzã¤Î\BK¡Â¼vû‡ØQ“‚Áà5i¶:0×̆‹q,C™¦j,=w¼¯f³Ætá²pV?o7öõZSùð¢å1H‡‹låW…×…ûškkötâ¼›Ïdz!ã†,‹Æ.*×­ÕìׇW™ÅúÔ[]ÏG– VQØçùÄR¦˜²²·âËJ­Ø¤¯ß7½åy®Å›ú?€7…²YãM?Ç› »Ê›BÏ TÃG¡ÁKÞÌÞÞ·ÏìKyS›ÚÄñÅm NùåÄiÕßh6Lµƒñ0nvë¤Ü¾gg˯¥;ÇCÝ/}OA]IšË,Nå= ukH(ïRX«µð›Q%æ|ú0&üî0&gSò'×Èé®þMé÷‹vIý-“ ‚œ5'7Yæa2 ³“á¨2ÓåÄ6fɽÿsluÄúž(¾«eÏÑü)¢cî®ýKÄó¿¦Ä 'Œqƒ&ét];hï÷‘gy« 'rÝÈ‘ïIþR¿¢\d:1Ç…[’ºŒ5þìÛLN endstream endobj 4257 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚ»RÃ0E{}Å–Ò ÒFÖ£ ¯ ¡¬.“ÂÄ"ÑŒÇßG‰â†‚jw¯î¬î0'7ž\?( Ž;ü;£,Wn ¾†%}bXÐп…¾=° Kg]×Äu5ÄvŸ…»ÀPÐ/&“±i»Ðgyþëp•û×Єêò 9"—låäÞ“"S2­¸Ö;²\ ¨“¾Á§ÎÂñìÚÒ6ÕJòBÄ匱þØU(Žúß«þ$¡RN‰„Ä”Þj]ÐÛmÕ±‚ìf<‰M´r¿QÄý&¿ã°½P)Ë“eöüx0&O ¾ê[]G endstream endobj 4262 0 obj << /Length 1577 /Filter /FlateDecode >> stream xÚÝËrÛ6ð®¯à‘œ‰P<ìÍI×é$vleÚNšñPeqB‘ Iü÷ÝÅ‚Å(3IõAöžhî=zÜ»Zp·~ZX¹'¼Hz‘àL+ãeûÅûÜÛü•ÇY’ï‹¥Ú{¡‰a-½ûÅÛÅóÕâ——¡ð–i¼ÕÖ Áb.<“H&¸öVï½ÿ"Xjÿ÷‹ÛÕå]ðaõʲˆ©ÐHä­Ñ±·”Š%BË*XJíÿHîß Ïâruj©Ñ‹Tø³–NÔ&†)å¡XH:ÿ¾¼¸µQìK®bÚ½´óæþú·Ë»‹ æþêN„zÀ9Žw÷—|ó’Ö?îžë‡Õõk€k¸N¬ý‹×·t}O<¶”!Ú±ÄûÄÎ’Û›ûë¿‚¥ •ßûœvŸðHZöyû Æø_vE†6ì¿ÏÓ¶oq·s›ªß¯ó÷Ò¯·kó¬®6­;Uæh_¥UŸ-8ý‰ Â-IÄ¥EY0”ö¿âO–ç›™Ú}úµØ÷û™åx}x’¥,Ñ.8šüÐäm^uéºfib¿¨hMii‹Ç à^Éåºè².DÑx?i¢‘ïôÁe`Lù«]ÑpSgýwEí87y›c±Îøª-6ycÉl„ܯ›#jÚs×CŸKÍÉ3¸y}½¢ÍÇf­iWëÆÙ[ä-ÅD,Ȱb.‡²È”’V»RjÆL¸idIßæZҊдÚÔÙOPzA€bàµ(¤K÷'B¥ì7ö±Ýmù›|n,Ò²%™&‚0g%I"3û¬ƒ8=ë­}úSM‰³[ĸ@ã°p&9ä6SQ¿al¼ŠÙ7À»+HúHM’ÍD,– hµÚÐöžxG’ìªâ,I#Ã"£¾îéC4i•@h&F^³vÏ‘¥%ÙÝ@j‚“1…”™¨ÜKì—HÒ2„=¢†°Gø4ì! Ð!Ÿ1óÊ9­²^Š0d:‘§Ž>”iw bîï1°y ‘“c ‘Üš‚ Ì<& Ð„µ¹ B“´—HøDXxÀ㨠2f»ÛꆈcuctÍU€uD¶Îwi ¸»1šúö€íGÉ$1džL¤&ÝvÃ]NŠÅ™ÄÒñŒòÞ³,ªGw¨7.£Û]Ý—›„õ˜âó—Fø‰9XjZ{x[%:§Ïf¨+Õ)% }è~uÙ ¤!ªg«Í‰ó(È h¨C;51ƒ6è…RHHl©Þ'š©4!'²Ù1Û{Šºl¤˜ÖÚ‚K8i!°ñ†4„Ðs•œ”—MÑšE üYö±P›(9J±#;jAˆå p„ð£8~T—ÁA5éiáöfÙÿþ~[ï­Á“h¬y¸\U4‰Ýïφƒd/»BÂå¤õ—v˜Ñ_€ü5¢µs´;a”;ÊñD È;S¿à%:äG]ñ_òˆÏæéa\¹4 ã0Ö.1½Œ@wÚaÔèioÀ( iÙ¢óלRvOCiÀóIËšu*nÊ„G$è]KÝZ»n UÈÎ?¸ûb«ÖÕ§ÀhÛHôwº“Ò'5 ÏYêNJº•OëŽÞIêaV(ikÛg¾vsÁdöœÜ8› Öcåÿ\l†Ût»tзsê°¥-ÏUð“>‡S,ÇÆ„Fa›-Lè,€l;ؼó!Ž…ðn 0à;*IrJ DïÆe@ÀtT¬É÷©} €¶éÖõ4<Û£àBƒ^ê|Mk'UÄÕŽÔŽ“pƒ€hôK+²ãìœõ½Æ4´—Ôµ›¾‡o8Ã7ì§SÏ­+šy¥uö_Ü^ã<\=°ô¸;~ ³¶–n‚C7×Òê¦çt!Ö>#DUw´I×m]ö£·űBÁôpÕ'¢å0œ‹™¡rÒÚѸOÀÝ䃶s®{ÿÄ¯ß 2vhìÇn“gÝÑ-|œQ`;û Èd*9MÒîøÕ¡F&;Oç¤ÉKR^0ahW; (‡‡‹Üü«\‡ >ÄæåØE~ìßZÆ,‘P %0‰X‡ 5Wù/þOj endstream endobj 4268 0 obj << /Length 271 /Filter /FlateDecode >> stream xÚKO„0€ïýsl©m)}}n²žT.f³1,%ÂÕ¿o—ÂÁă—ÎôËt:ó1xt£Ë{ÉÁR«„‚¼-@KC¥M!¯`‡ˆÈ°nð#I„6øªïÛ¦,¦Æ#¸uD0üEx(l}7§¦r1r­+F/œ A9Ùç[t—£OÄÃ( xüZRÍ4”ÚíToÑÔøž«:Ê„ØÂ3zDlYc¿ze’ õïVšaN.¢.IÂ¥µß¼=ÉðDÎbâJ‚’DI‹_ˆ °X)KMÌJƒÀ3<›[\Ö„3ì—òÓèìë?†Cö:5§ùew>ûÙܺr0ø°Emi endstream endobj 4286 0 obj << /Length 1336 /Filter /FlateDecode >> stream xÚ½YÛrÛ6}×Wð­ÔL…âBð’7Ù–c§Ž›Úêd:IFCKÌ Eª$e7ýú.xI3C G IXìYœ=ÖXÛiX{?ÁùóŸ 'ÖˆfQÍ"qfjëýäË7¬m ýƒ†‘ã˜ÚkÚk¯¦ O_{œü9¹XN~»6ˆæ Ǥ¦¶Üj†C‰f:̵åFû¢_Ng\¿™Z.¦ß–Ò!Ä@Ì0©3ÃÈ ÚŒ2ä’XÞ<,²ïd±T=4¹…,f õ°6!&² ®™„!#›îêöúzñ°¸ŸÎÖ/Óµlýb±„®^È_dËÍâöãÕ”q}~—5Ìﯲ—·Ëìå÷ÅÃÀäú¹•ù§ÛN œsD‰Ýb9V „`f#b›%ÀIå²ÉÇû¦9‚Ƥ¹´­J‘m[Z$´­ß±æˆ8ŽÆ Œ°e5aŽ]:½aÎê ¢ªÁ´ÝdÈf¼0Ñp#Šm9eÀÿxIËÍÆ‡÷ÙrZ¬F8ˆ&ÌÇiæËù=zâ+÷˜<¯Öa°Ú‰ÄÝl¢ø+æþ‘t5Š©•U¡ÌD¸5^4¤E«Ò‡m1ĹñF8RÌ®¤E@bä ÷ßMg`\¿ÝJšb]xɳˆ²÷0oƒ–ìåzA"¢8o³§®]%Ó}»Á&{‰Ä>LDí/„Iörÿ×Ýݯùo‰Úg ‘ÛùŠ™“®'À³ ˜Ëõ¥#I1èIl§`ˆDñí»ÆáèW=_r(,y"‚D Ã:LaÀTñ! 6¥9‰OÄ¥Ûá>o>Jï|ò fWæþ¿ j'4!– 2m8wÚÉH!u)F?;£ŸÝ™Œ•Áó$##È‚þÉOÆÑ¢Q&£ŽS“±²?–IRËŸ*IñÀÒ/<ÆC!)]/(ìä¼<øîZôrpüÚ„„“˜cî•Áó’8Èâì BÂ(BÈÑ¢QR Ç©„¬ƒ¬y?¥ ƒ…Bï¾Øƒ´êƪP¾H…ƒm¢”=‚b}ô6½°'!2¢ÞUÏC/ gRç-½‹Äú%>>}?pl´”Scr*ÇêHûEïo¹É)²×|šð Ža‹™Üb(7ǾšÁ³0Óp8ÜuÞ¾X›¡Ì/$319‘™ Ò³©ßðh´9fC<¢úÕ ž‡c6L`×Õo½–ì’,Ûz»Ô-%µÔPœJ­:@yÑw°þ.ãÇEã¦ÒA ‚ÕKÒ«”º‚xn÷¢¼¹IC}W¹;Eòcw”Î )¦Yw—®ý&õtã&nÖK«Ëœ¢S!Ëó;‰êó”Àó©õ¿§×‹;_0ûODaß½gøâµ3Á´e‘fDµ­ þ<Òå7y¿­¬²Rç÷:ôW°6Àñg7؉Uâí…Bôn‚°$¸ŠðT‚תº´³‡ƒ¶YÀš3¦VÏ£‡š,«Æ)†±u~²’ÅŽýM-%eÔpœJ™:Èj»½t×R¢žEܪÊìÇrß…`¤*©J@ûV¥*! ƒÔ£fi90bÓ!o; !Nä>E£&‰ò—ôTšJº:´ªùÞS LqœÈÀW÷({S“ê2 F3F}Qy`ó! 7¹GÛÎÝ%»Ò/RÂóö,¢ß[{‰/ûü(¢—¨§jµŽ–¯CO˜­`Ì@¦Å[5l‚lÂûjØéHÚ®ºõÓ» I;ý·Ùþ¿Èj‹CÁ!3B³ô ¼™çÿi¶º´ endstream endobj 4298 0 obj << /Length 264 /Filter /FlateDecode >> stream xÚÉNÃ0†ï~Š9Ú1Þâ$ÇB¡´‰Å·¶‡4 R6ÒB_§NH=pš~gù|€€¹qäúÞHÈxf•÷‰‚ĤÜd\ kúÈTLqØáÐíY¤’”Îú¾®ŠüPum0æÈ” ?Lúºëqöâ»*ñ*èW¬1ßcH$WŠK¶u+rçÈ‘~2Œ6<  Yo”Þ_à:KáxªjÀØÔÇÞÈ Óçø§Wl¸²ÿnu‘„ñ{J@HË"§ZÑÛϼg1=°L8IsY“ÑyµZ®k œíp¬?Žp‚ö€USæuHò¶ âi邸€ýyyBv¾Õ£û¿³já endstream endobj 4304 0 obj << /Length 2171 /Filter /FlateDecode >> stream xÚåYKÜ6¾Ï¯Ði¡¦µ$%Q-9xÛqbx7vÖ5»‡µÔÖÓÙ_¿õ ^=²aÇÎew#±XU¬ÇÇbQ-¼ƒ'¼çÂ=ß_Hx Oz‰ò)‚8Ô^~¼xû»ðv@ÿÉAšjŽ^¤7ð,¼7¿\üc{ñ÷g‘ôÒ ÕJ{Û½¥2ØééTRÄÞvç½õŸ¬Ö±ÿããmŸ¾^ý¾ý‰Dd„‘V(“I"½µ ƒTJ–x¶’±ÿÏ_‰ýâévn¤ŽA"Œ¾ÔÈÉŠá& ’Mäi¯øâÕ‹í‹Ç/Wk•lü'¯ŸþðôŽß°Ááfâã:”’Ä×hÈÆ)xSíÛ»•Šý¬6¨EúíMÖâ›òO¦†áïW‘ð+~?6Ž+knfkºý¾á‰ÌQ‹êp°å‰]cjG·e[9N&äÕñÔµ´ïnLÉôöƬBáß»õîOf [Çüó ,2õµ©+§ý”5ÍÝ*ŒÁÜó”ÆìÜ$, a¯!iìÒ|@ï ¸ª Xg[›8Hý¼6;Sâ¸áÙw"]ÓeE2÷ÌÕÚ͸%[œp[ ¿Î@C€¤9[ª$ËïëêÈ,SwŸÞøo†Ø"k3KŠ47ðê¬kª£a¾ks“aì>XÌÎÝÙÖéÀ°.Dá=Gÿ$[¦báŸêªwä BI†! ýÉ2hÏ 9¥0 )¯ð˜J#EM¢Ò8Î<7{'TŒÒàUÕÕ¹aI4l3dkfìE•cÖ€gK¦6 ÝVnÐ?ÄÎ4·mub™ƒÎw˜¾Î³[D,/EìCoö݈õèr8ûG„ÁìÀH™`î(¡ômË3Ç®Aÿ[V3F\øvïkoªÆ<ÐÃÙ×Êl9j‰Ð%|4&ïQ0CˆÚ ôÚ¸1&8—K¾£¨°|¯<ê¡N{¸Í®àÔ2ó¦lxUxç¢Ão†Ù(ÎDšû„,o§›p¬NRŸµNÛXÈÏ öGf€ñÏ?< ˜õF3³Åh³q±ö†Úf)³Ì¼a”g-ƒPG¾mø‰XÒ!xÆlP¾0ó¡+JSg×¶°íýJÇþ%ÒØÓyÖavq€DVØÜVSÊ#½™[Ï 1` Å­“¦ãË;¡Ä¿³2«+¨Óܶ*˜”ÀU-F~ÀWå€ÄtyÛ|* !|X´ ˆûû*ܨ?s`ýÓÉd|V¸šÏœ*)¢œ²ˆ#M³Š «—!Áó ‰ÛyØzH§=GÅ|в˜þìjÍrë!‡ÆF¸ƒi¼ý,û7tC€Xr<¿_Qsv°ˆ9â)€g±%È פ8A2ã@ß3‰ ‰{¿ãyy,˜çŸ=”ü~¨¨´瞟ó^dÓ[ŽéÆßweN›^(=l&ü6Ú«¡_@|ýšÛ$œt§q(•Â"ÜÔ×ñÕÁ´WxZ^aýo®hÀ@<ÓaBë¹ëÀY¯+ã4ЉîÕÝÙ¢`c‡fO%ÉxãÌìÁÙ±äÃlæ˜ <<ß5.¡n6™íS€n$µÿ¸t§5q­ wOá†1KùP€9Õ}5L“¡yEbÅÏ?K˜{3|Ð Äà«R¤d4ËÏSƒ“}VfTÄc¢1LЙÿh¨æ€™ÖÙÍf'ý{/;ž ÇD EŸª¢Cá…ÜÔÏêLuÝfÜB"Ê¿<Œ#·Ïö[Ì[1¤,K9]Ó°Ðð¥Kë©»)\Õâ¤w÷TÛ2/³£Y¸ŸEq 6²çD;Ôé`°vx#”ÂÿÝ’Rh¥zÒ`=c&š€ÞO½7¹=qC½ñÉÞyð¦HäP™ ¯gOÂÖò îÈý Yo¸×z& Þ’½÷ß¡ßÌv6Ì^Èç$ â8&r£8PRâ]:J´›p†Ú5B/ŸŒ”Lƒ$…?’¨JBút’Ž:•RŽq\t¤å výª#ILtŠÉª9ŒB½ˆ{ò0ÿ¿ñsïýâ˜ÒË>žê”RB5_0 ÑÎOV‘‹Ò,>'KùÜü™ý%ξšõÏ>¤kB·]’Ð4úð¤ãII ÔÕM:©þ¦®«úŠ+p¬°m¿[ü°€Ìt<0½~œ“*$×â¦ÚÄTWg"ÌsÿÜŸQÀkï-É~?;‡ñÕ¯/_«O¿Ý¡×2ôä Öñÿv¶»wÙ—DH`£@(]¦¦”ÑTq®æ’ÝoìLµG£ú–>Ï,†oêß"Bœ¸ƒ™+¬ü´8^šþhQÃ!vù¥ë=ŒÖ$½ƒc QhÄ#3 ÷&jѳXØýY2Ã3œ¢b8hÑ¿šO}‹$æ_+l¾Ž&+»Ów®—ƒz£ä_˜…OtÀCJ¾: Ø»¿óÈMÎ}ìípR¸¥f¯ßügz¿ ë¹#ú &‹ø_©þd¢†Ë>»¨> stream xÚíkoÜFî»…pZíÁ;™§ h®mriR§M‡´XhµZ[ˆVR%m]߯?rfô\%ñÚ>§@/€WÉ!9Ɉ:užŸüóüäÑ3Éœ„÷œó­ãsÇ—‘¡pÎ7Î;÷å‚+7©ÖIUÔ‹%÷÷iYfi5i‘À7É‚S÷÷Ĭ(“Ê€ŸïÓMrjÞß$YÕ‰0Â9a‹_Ï¿;ùöüä·¢P‡™¥%ñ©ïÄ»“w¿RgðïJD8WkçH/€gæütòã µjtOÂ@ J¸'ÊcNÀ7½âL!=ÞjN}"¥o4—VÆÛ/â¼[*JÝ×åB¹h.kÀí‚Q·°VºX,a” Æ*ÍÓfÃrSôLƒ]¢Î’$T܈z~ ¦ ¤ïn÷y¬7FÓN”Æ—ð+Ï:¾Aî¾p÷Q‡E4ó÷ÕZ­.’N<mUFu}UT›_¨¢ðÇ>&+vBÉ–]½GwIj#q”ã3p‹ÒZeTE»¤AOÂ9\åê2ÑÃ. FÜÒ­­æ‘yäû,CaÀ>‚’PxÎ’10”2‹—Eš[™€á}¸oÑ-}ºÍ¥~ îɈLÂ(û˜AçU”eE|33†„…agÆÂH­é£ÆŠŽVAhgMÖh·ýºû¸ÙWx*.{s7—‚r"Æ&þ¢Û*In¤§ ‰¤|¨'WÔEró–6°uB÷ú‘>G OPîx²¢]™%­bŒ+:Ó§=°sS $¥6$yñ˜p$ÄS Ã’ó›¸!J+©A› ã#L¤òQJip#E8c¼¤ïÙ ÑGð@8ñ`ÄYHüþiúÊ‘ÊóÞ'‡ˆjûE{X lûQÖ®Úƒè€'¬ÃHmIìƒj 㿌ž[çGœ)Tè²øxÞyˆ¹œÌï±îbÜšM *rm7eg:»µc·vX‹Û1§à§pAöÜ@ùÁJ8²VÙG[ÆÒjÃÜÔ$·9_ª}¶&]B¤£ ž’KBìªïkOBlà‰AÜIªª¨Vq±X¡ q©’找è‚” 7­ýѺŒ öfö2à{ ÿ˜ðÐÀ³·¯^÷‚ky‚úµÃ„02ƒ¸KvuÒ`À=B ÷‹©BšÿiL1·QH Ú¤géu¢S6§FÚ:ýORlQ(ͯü›Ý"غ{1å'/Þ¸€”àæôØÕ¾˜ÙüN`D5…4VÒŒFs›òqR74@º\“#÷gé“ T£Ò»­¯VG‚°1·‹oRí2Šçûò‰M“ â2ë2înç,3Ë É4—•&Ì›úþÝç>ã$Xy_åÛáAfÓUmNp‹‚~Ú2XZÎK©HʶoÀï§oð\wš4¿0­‚(‡šJžë]±·­„¶Y»”FÙ1-ƒ§È!n±Å'fJm‡€Œظ [’Ö­,ê:]gOg-ÖM”æ¶Å 6þÚ µÐ¢±+3U>Ön.Šþ sš¢l·4uˆ‘lôÙÒèSÖ­ÜV-,êgýå7_ã…iinÒáâLǹÑJw®P—®íƒÐö¹^Ø â×ÈGôIæ@” Í¹0<2Ý(˜ÏSѺtÉ–Iœn¯-•Á4ùµn˜Çiefþ*m.Íl·œ±/jƒ¡Ý§•dc`‘]|,³TÉ®l®Íì&j,B\ìÊ"·íðˆSÙ„ãFè¯,äîZÛÀÌ@൑Ñ4€@…ªÝ ¯,Š7@Q„‹î*B¦¨`íƒ;Úo)‰ê±m×R0é>EÂ=(ŽÛ¶âQÊ«4³Ò·mV+qʼnAÙkÑ5tz`ö‡—/Î ÚAä|bp0ààD½ã¤®á<á¾SÙEÖ%ó<¸ƒ±Aû§3o£§í¶3ØçzŸÙ»áiŒâtˆ…£b¯“9ã îÑîtüüí«W/Ï^ÿ|öèéÙë³ÿúíO_u°ÇlÆìœBætkbVÿWRYYS+v[qü?í=2%‰aî¡{ ¶ó°'ǘ˜öä$DÓž\ÃnS?êzN=ˆxÒÁªÕ{ü³ëy£Þcøð½GÐ`Ô{dŒO{ ü`%Y+죭ÁÛÞ#²ý3ô™RP}ðö¹òuÔ;î‚¿MÇ„}žVÂzŸfSÙcؾßpÔ60­Á¦Ê’WÙ]ë;ßdŸº¥ ñŒÇªZ¤V®ÚŠÑ³5äÒ‹ò·Iåw QßoÐ6¹„*æ®mcÔ›wlYÌØé34ÿ }-ïÿ}­c½d’cõ].à@ýqÇ…×÷„?[CÊ´4ÌI'@„¶¢l“jΓ™ŠÆ.lí𻪠3U•ÆŽì|´.PÌßñ'±"˜êÚi&vcÉÂ<¨ª ëN”Ð%Ò°ìA" óÚDð/ÔÞÀ«®å4ú@3µKv뤪/ÓrLmt…mi,2 ­+2ǦáHÖz=Sdà„¶òoÔêZÆnÂìM¦Ûº·0¬:T[/`³ µ‹š)0Vl'ÃCͪ+0°á1W`p…ÿ‘Ì?V`Ì|ŒJâ‡ßªæ#£ƒ9ý\ JîÝøk©Ù½$'}™ÅX 7Þ£î×—‘þhiß~™V£¯ðdè¾€0œj+¢ÿÂþ‡÷+™ endstream endobj 4330 0 obj << /Length 3126 /Filter /FlateDecode >> stream xÚÝÙŽãÆñ}¾‚O‰¬¸}“Œ‘â5솽#¶1 $Î ±©©=þ>utóµ;öìSuwõU]WWUSD‘ˆ¾½ùçíÍËWFFYœ9å¢ÛûH¥&V:‹“Æ&ÓÑí>úuõïµ²«â´-NM»Þ¨$]}}n/’ؘ„O=„ãŸß$úuc…XýÒ’”u·Fj®7v•ã^¾Òéˆ"Ú¨4άb|¾^k±:wEÝùëXT%«œ‹3ïBµs^UÈ· 8o׿–§¢e¬‚•t‹á,†6÷\¶ÅîTt\/ëûµ«†ˆóÈW­Víy‡lô˜´ŒŽyÛ¾_k 3÷ñz£¡¯/{²Ëk®l=bíŬØ#R%,SbÙuà ÓU×0!c%R¤bàפŽY3¾FR'zDj£ CÁ>´þ›ÓÖÞ=Ý]Y—ÝbßÞÊ€îo ø—Ÿbœ´Y,S–{WæK :L{ùʹ‰ÚÅiÖö¤!rÃïž'L–7p e† §üPtÀ|à‘g ±Êo•l•Otz<½=G”<žšÃWCºƒÐŠ8ÂLÈŸ×û—¼ƒÑjM½gѳ°lUmóÚƒ7-(ëE¤+ò ßÝ_œŸ îiÞÓad8„í%Üìa|Õ6ÜÉrãV,éË*Êõ CXÑã;ˆ¹[sîé¥|AIæ­ ™‡â§ï~Ä¡/¸5[’°0)vŽE½gE†æL+R`ëñ<õ:gýj8œ9å‡v —Œik¢Ýžàv¹þûDz×_h>†ÃôûÀ³‰ |²ícëJ„RÞ˜i§N÷Æ5–_Ƽþt@ƒzÓÌ+Û ^ÐõæsfÐq6˜Ù’#= ÖXT…Cf,xhÅ®üMhC«½¼¦ö2Ib‘¥½Ÿa°') Ý¥§Ý×Y¬¤ “@—Vv±µY³Ï»|a! U¥.ŒHëQ~¦=µ6N…ùröÔÅ™”a¹˜m“q6¶"›ªã- -õˆØz_Â…Hµ­ï/k4¯ïHÞ _‘mØQäA%°Õ•?¡ +ãi¸V•ÛSÞ_Ÿ! ÂJÎ…·FlÉžÐRÔ¾áJs H-™ ñ”#\¸³Á’Z¥Vÿg`Ànl\ª^Š…šK±€ [îY Z©® ¯V¬‹¼Í6¯ëeqqbzQZÎ8ïÜ/é|å\U$3;0–¤\‚éPÒ>hïËöXåxˆx¦ü0Ï<Ðâ/J8*ÐtÀœc- ›t:rvÒêÒy.]ÍWwqbî3èšY¼m¸¼F_02Y6í¡Mlœìøêä ’Ø]½jõM/܈Kã±kê.Ç»šOâ‘ã‹ cà¥0?á ™‹k®X¹EÉzy!zU$‰€{¾ì;eYìÇr¿/ê…UXM˜¤µì¼±àî'ÙS úê{ô˜ n½,¼×`2/,Îíö±9W{®oýÕïéªÂ%ÆòêØ_ õüäܯGdjNy›ÃT)ß= “^Gª¬‡—4ÂÅÊô$$§³8V—¨¨€•rÆ,ð8o½ýÙbÉLQf†'IJ%ŽVBóŒpB`ƒFè…äÁ¹ÿº6 VþDvr[(p¨{‘;ái6ÿ¸r :¸Ízy{_v~C&&à1"¦·©^~TÃeÎcù‡òp>0¬>¶ì‰PPµ€fêâTÉšUQ?t ˆnŒ±vJØ-IPW´Þ7dBwn¬á…Ñ-쟂7¦ÜS·Oð¦ïýŽàl2™ âçM¼Û¾sDChùÛ[Zð¹àNßÈ$δî}/m³ñÝíÄLx°Ÿ|¯Ðõˆ«mÇX¤gÆ™úf؇ûù36>nÊë®õ§müL޹(nÀ¡a·à€¶ƒÑ•f**|"îO;`¨„Á!°$¨8ƒè|ì|%0‚Ùù¶9û¹þ5RòÚϵóä58ÐE’1Œ½¼QÚøyÜÔ&‰¡žÍÍMXhBÁCà«Uwf‚Ô“ n5è²ø`­ôJQ7ãàÍ+ 1}!^ ”Æž>Ì$? ˜–—U¾­Š¸wûFzt»N­âºÍ6oÉéÈÜ8 Ð2„èœ);‡c¸ØžËªÛ”¾wä@käUB ¢Øª@—. ‹³¥²d”a@Ax&1˜jk@æîØ´å‡'骄‹,í«¼ Þ@<—3o`Ù«1±sö‡nV_F\3Ãýi1 ú5´€ˆ‰ùLä§ey/ð Û —¹^½B[Ò ÌyTÔý7ÏA©,:ö³Ò‡êK]ÀÍonû\¯Kc'u¤Ó,†1ß½"tþK#xج¹;DšSÀ‰†×¸‚–…˜X¢ñ5‰ó2Öˆ=`q XÁM@#ccøƒýŠFùaÃŽ=hKöªß0@İœ¶ÛaF‹0Þ‚N¶û¿?ß}ôs“YÔL,¾í%‚³üø›ýaq@ÇÔ’ÝÇóB(‡SD/ë{zzÓ«oežÐÜ=rÖ¥£µŒm ¦Î˜.¸Ÿ†y*)þŒ]¤Ì|H¹qDP¢z%°'Г<&`‚Xƒ-Ip;¯Ûi~• ħÞÀæý}bf=ðsÙŒ4‹Ý‹?ºÙ_f›­hékêÜU%Ü@p”õŽVÿ"v§§æüÇ_~øÁÏX¸<|òfóqÑ!9† ؉9v/–²Å£ý±Š7ÕW_(Áºé b˜j7äY՗ɳ¾¥úÿDzÕõ.¾t©?@{ž›ò Ú×0–¦Ê$BîñÔœûV9Ÿ4GïöPëÜ’WÚOz–[2cò’Àîw‡ÝõÇ~Š£¢DKÓ» ÷çšÞ á––R»ÕkòÝ{2ÚYžºEY³”ѦÔ!7rî<4˜ B@ÛKïˆo|á·Ÿ…òüä ]xÑn<±º'×tW0|ðf¡‘Þ.ÉO¿¿´”J9y‹àñ«’vóônØÆO„ÉBZ;šz<¬©ŠÇb½EíõùÁK«<Ŧïe 1¸üûó.¼×lG±D|½Ëйª< ÇÏû°PqAK‹ÏKáí§líb\Àùâð&A•1©:ˆÔ2¹–"š^{ßp`ކR×}XzŠ€XkÈuÎ’ÄÃSKÚ?µä»]Ѷᅳ°ÉªÙbsv¼‡ Eô…r‰C2¤ßú%'©4NZd"}"0&òö¹–ÄX`V6‰ozÝÁYº»·€6¡ü¤HÇÙXi‰`@@Û*Y^I‘7ÄYü>û(Wþù%±5×H‹W*ÓÓî=i@͆÷¾]QXª}J‚Q ̱ÞúohfW¦J³¥W €’#²4<©“\ð|êÈ<ñÒl„¢–¦þÝz~¹}µI¹Ê;x™¨PIŒÉü¥÷ID¸F†7ã‚7¬ªÍ›š¯ˆš·žmóê[ví}°OÏÉ”¿ýÁ’¨Ô]œûéØ\^°½/ð{¿X=[ìòxÔ ÇÃÛ_*ú,„Wõåø›Z¾AýÁµè©AgäcÈ“¬¸¸¾ßâÝ^b–V`J¹¦Õµ½[ƒ/e…ïçg`!–ˆƒ`6wo{äÊ»rï;ؤ^ ëÆ¤,¥¦ŒçtÎËŒIL³¹X²½”H,wƒ?„óAÏ%… Ç•ÑäôcñÉ7tYŠþS•sœ‘Ù÷/ìÿ 3§ŸÌ?÷³"'íwùÅ"…°±”jvÖJõ¹Oîà¢uãïd6ÇóçúR. endstream endobj 4203 0 obj << /Type /ObjStm /N 100 /First 962 /Length 2108 /Filter /FlateDecode >> stream xÚÍZmo5þž_a‰/€„×ã±gl!P ¤ª-PåCH¨(9t¹JåßóŒï6íæ®¹íÞ&Š”ï®_Æãgž™±¨&\¢š•hq,Ù êrR—b §E§JŽÄ•Pì{q%U|'rUÈ*&Gó JèCk,ŽRi%E[)V*++UGë„]Œ"üÏloJ.â‡9Û|côOêb­z`}A°(ÉäˆèKÅÆ´ÞJµ¶‘²ÑcvŒ&øà˜17 ÏÌí‹•ÔäÕñFêhê Öƒ:ÖjõjÁq)D“}¥ &5ã©Õo"+!c2 ?œ­w›0CÏ(aˆZŸÐ¤„ö¤)>¡žZÑú(ÕFB/9lÞ‘ËdýÆT\6Atâ2ÇtboÚ*Æd«ØúÍÑåœZ }ˆ‰3úbõ²¸¬ÕFÍh»ÑYÎ.W'bysmãçꄈ0 LW"€~%V[(U8ZP¾ ®•P?G“W%±Q1 H´ŠzZí+–Fj48iuÄôT‚ÓØÖ¶›$À¨&µU.ìt£1,”*”…9¨ë­$§¥€)a“¼V—Û;ƒ°bØ2‰Ã›p2H6™(.‹y•¬¶h€\€ Š–Ê­>ì @@”ª«Š} ®’­5›qÄj_¢ É ü7µW³ÉÏ€}m¦ÆP@[]®k1m1¦A!Ø ¦@ P€èïäôô¤{þß¿ ×=º¼\®Oº¯—«—‹Õ‹³gÝ÷ÝÝ7x@˳“îéâbí^0GU†”^l¡{nѽÏ5¡Ú³7¿¯Ñe÷ã«Ë¿»G§§m€îÑÅúÕò²{Öýüôûýô¯õúß«/»n½\¾¾ò¯ë?ürõg÷×úŸ×Ýꋨ)y{øäjÑš~‘}ü쫯Nð3Aj…à fá ÅA|¨À^c¼S±é±KövFI½1,gñdü˜‹§ü`• )æI½‘#ÌÚ+ðM$>r¹7±¿u/ài*}êº_~ýÍÁô5«/Ýå›×¯Ï>\1y®6ðóT|¼¼\»ÓS×=6‡¶iòØÜa6ObäÃÜ>óãÕöÉ\(ˆÎžÐi÷dµ¼x¶€f]÷äÛÇ®{¾x»vgÃÕyrþçâ¤ûc/.×WæÒZß¶&WË7«‹ÅÕÆ ¶w?-^¾:ÿzùÖµeóÎÕŒàÉù ­­bÞTlk~…›ƒ6yšÞ¤/h_(}a£§³‰"­>6óQš™‚ÿA] HšeR¿~»¾útîÔHï¤f©>4g0£ÔMäèÕçé2'‰¾ær-3 /‘¦Ëüò|}¾^_ü½X½“üåòb¨s{˜.4B0Ÿ,è!òº‘Ýb„RÁƒ%󘼹^†Êá‹jñŠP€5ù’ËC5{EÄÁ9ú`*Þ"A6à¾P÷Zª0ŠÉ‡[ì{¸bÀ”ꈊ ˆïöñ”ì)éÊ' çŠÐÃk0RÃÉÕòÞÔ‡Jš¬ˆ˜vãtoÃÖÓE:ÊÓEÍ-VBÆèÙÇ$ƒXFÀšé¡r™R#$죹9p` ‹1Ü›Ô “‘Gò â"¼›•,W›Ýsà™Ã<—#ðÜÇrQÃsI>Ùn='8·œ}¶@ ÌøPS®8-úAzÈ`Ÿ•ÏdQÑÝfµTw]ÇúF6¢Á+\õ(¼:ÖIMÇëþå8ÝñX£ç¡= rQ épEFPYÃ4›WOµÓ•¹Ç«ó^ïÊ«ÐϤˆÄ»ŠH4RIvX0…£ÈkòƤ$ˆ‘mÇ‘áÔU¥³ Á;H¦’­Õdª-iŠw³¤Úö‘óœÔêžEÔ[ÄÁÔËHjTļJiAÍñ?¤ÏÛô7GŒŸ÷A¦éúËóAg¤"¦O]÷L=1u™:õÉS=Ût¦SX¾mçmK?®ñÏ~F£öp½+v,U Ò ÑYœBK¶Óò¨©â™ë¾[>_:hñÓmdó¹'¸šÏÜ ^’±I¼ÐíÁú8¶Ã.Isî«Êç+2s¢÷޹"»S(iäJÙÁœöû¿ÚïÿjÝJŸ'ê ±/ðœHUõl—Õ CBôF.gö!–ÛŠøç}œÎ"ÂLB$p-GB¬|@™_B‚¡ïĈÕR‡ÒìböxF†²åUPR‡æ¹åHÈBmUz1’ÆpPuv1Ú1YšiRÙþõmp˜ ¹9×|Ž$«åè·±z¡RïúARTüRÒøØ c2?Ö=_åãøñýi×{§x»ù6‡8™âíŠCcm»á0g|av‰¦šE&gÛGԮƯ‡L‚ˆç3‰vÔnçj‡v†°è³]÷)Õ×z€#²ì…]eÊsE:wyÛ¤|Ñ1ø*=¾¶‘S8šq,>#µË p5ûdjÄR÷ûX—8Û±`±Û,™ ¾]’Y#…Í^¾dòÜìÞ¼Ú-+Ït@#2£oŒˆ‘XR»Z¤v×/ÁK%jW‹DôvAt'Õ°ûqH#ÎnVJvNžhÞœdg{`†=2ÞsRÀ£O öX*õÚñö¬Ý+Û¸/¤¾û‚ôÕ¬‰}2³6kj{á@o©ã¬iV»6"ÁN@kÚK¤ÐvU/××vŸ.W–mÔ›v%ÈIj;ä@¨wH÷Šx×â^»›S€O¸kð™ÒhIþÒ» endstream endobj 4345 0 obj << /Length 2203 /Filter /FlateDecode >> stream xÚÕZYsܸ~ׯ`ôpR ÙÚ‡ÝXväÝ’di¶òàlMQŒÅ‡“µ•ÿžn¼†’5’J^DF_wQç½C×G?/Ž^¼ò™“8à³X;!wB?"~ì9‹•óÎýeÆ…+«Y•õlÎÃÈýi»Í³4i²²Ð/åŒS÷ãŒa^ne¥‡_ﲕ<Ñí+™Ë¤–ºÃç„Í~_¼9:]}8b u˜ÞÚ'! tsôîwê¬`üC‰GÎ'Eµqü ‚oî\½=¢F JHO <¤˜SÁÄÞàÕ} 3J¨j…/gÂMêúÓŒQ·¬VZä³¹pw²VJ£àv篼¨ÇŒ:sîÃ^BóZÜJ¤~ñ :"LÆÀW?‹åÕéõåÅùËÓ«åÛßN¯gçËËŸ®¯ÿyqõR3삘Ј[ÿ¢‚–ÕÔF xhÉŽ·¨¨t<ÁRpâQ¿Ç‘Íæ,ä 8˜Gçjãhóe+±ÅÜJ(j3+ucW™ùÂ5“JŒ™'кd6÷hvÊjÍÏr›£Œ`L‹Ç3gŒÄÂXÕ OPwUÊZ·Š²ÑÛdæ!¿Ô#‰þ¤(àm’ç²x¯0}b¦‹•n(¡±QÉz[µéef‡:Ûls\øeDÞ×Ç*[`Àòâ=шy4FGLyŒDž…œ7ÙÆ„ÒöÙH DjD˜Ï¿†Ô‹ÅåH}„1û:H}âGA Ò²ÙNá“„ >Ä'Ñ>qTã[ûøÄÑD4$Ê,5Äɦl¨fÙ™YD{.†Ê;ĵ,jTʉÙ¨Z¡0X ÷òì\´SRI¾3ë™Î,VÐZfÂîñãÓXyO-ßùh·¤@=`e¥é“ÊP¼¹¾8ŸË"-WÒŽ@\c¸DܽÙ5–•aÑ+h :´Aš˜XÝÙ€J° Ñ"ƒMÍÄzW¤ÈÆ\SÚøµÔe¶²qŸiGaøâ´‰IÔÂeU¦²®[²¬©e¾&­„!‰=o}PN#ŒÂò Â¤ Ðñ  ÐÐæsêlÞU7b©SÈJVKÀóò½l–©ñŠÄ@Pø} 8Y“(nYZà/Bw%ÑKµîhˆ@cÊó0œÊŒÐJôg_±w 3^ɪÓþ&IñHq÷·VUáÇÎøkžšµOíP`žy„ÅŸœƨ™O5Õ¨›nìËPàA\ ç½ ’ø£‘JbÁ œ±Èá!„ t=K¡ú©ã™Vî0âù7]Ú± †ª¤Èÿ§dY;oð Ü$ÐþðyÝZ?ªÑƒM,HBq£–íaÐûàG­$PJ =n  g4è£T0k•6c]ž‚¯ö™pôµ¶˜£ýà9ï`§Þ gÀ;žOIÄMPÕpº€ãÏ\@*Q¹SVUY-±fLÞÍ—.¹b*UK h7òs£™˜Î‰î}ÄB¬CÊGØ?JÓÁ(è¼Skþ:È °é*i’% À"ŽÅƒ…h L•6Ÿm¶ûôWýÿPSÂÙßž54CÙü0e—‰[^[ß­z›ÿ`˜PEÕÒ‹b2Ñå‘r¨Gb¦ÅÌÖ£|;¼„^ºFZíL†¾Fck71i!¾öBŒ~ÒW dö‡¹¹ F‚ˆ }N8Ô¦?ŽlÚá½SoxH¸W7@‘òÃt;±ga÷ FPÞ°Ž‚?ŠÃ;·ÜâMå®eläSxQˆ¾y2 ç“f;Žà÷îèv¸ >„Á(Æã®* ‹·Wá6üç!þ¸4ÊDÿd†ï Öɹ{0{ÈÞžH>Ïò<=Ôå4ùü`óý8Â;ó©@:ÏZû#ÝJ:ZøD«=náž©uù¼ÍÕ÷O“x9ÿí×_Çé#€ïEÀ÷‚ç£òéÓÝÂV5‡'eSÆ=ÿ›dPS@¢ˆðqq´Þ2Ùe’æ¡3Ær]É{S€Ö7Ž¿Wêž—º‡—M8† )¾#ÄøÂ`®ñ׉ŽÍŠ}½¶?ÚúÒÙØÛ¸~îØ{Z°ßñ¿ýÄðÈÿ˜ü½ßç„A8+A9Í=Îêþý6Ù΄ÛÌ„kÿ…Á'øb»gE†ÏzF¤} í ÂþÞ,û endstream endobj 4357 0 obj << /Length 2099 /Filter /FlateDecode >> stream xÚÍYëoã6ÿž¿BŸ ¹ˆY¾DI]ôC‹»]ôº—öK·™N„È’W¤¹Ãýï7álIvvMºm€X䈜Ço†ä Ńë€oξ»8ûêµAÊR#Mp±d¢™Tië„éT«à·ðÇ…ŒBÛ\Ù¦nK'á·ÛmYäYWÔþa’‡w Ëzk"¿é‹•=§ö[[Ú¬µÔLJ&¿_üpöÏ‹³÷gôáb ¢5‹y䛳ß~çÁ è?œ©4 îݨM MÏ2ø÷ÙÏgÜÛÂÇ6©$ˆYs6i•2“EpfdL6½ãÏëª+ªÞ®@§ˆ‡ë¦ÞPkÛX4ù®¨ûÖS²kL#­wb™‘Nƒù³¹{õö Ú€±)ºDs6ëæ›@±bQ9r ½ˆI!ÿB0¥•T{Š3 sù¸å~ýDÿàNbþ—É]?v!îøx³Cbƒ~Ÿ Ÿd1¨#½ši0C:;"ÿfgÇ@ ;v=Å+NµáSf·Áæ¥IðTq £ î"ßD£ÕœJ–J±PW†ÿ¾Œ#,Z£EÂ'ùÕkX{fPþu¸îE |ÄÕ—YYÖùpp¹À|¢´/Ž8gÍ ì Åz"`¶Ö…anÞ¿ó6- a g«³îêa™Ù¬ê·~7pKINƒìφó²±í¶®V¶™¸ÀMƒ!¾µyØ;§•¯¼xj®–g!¿<Êö/pÀgˆýmÖ¶÷u³zÑÐ÷ÛÄÁ6NN‰bܨC§ùÍÚnF|Çk1‡2ÑÓãλåëŸ0GÂyÝX{4ŠÝÛ'œæ¸Ð9YuíË»ä%÷£#9ÊóÝÙûxÆ1Iü è! zX™Áß3¢ÓJ,¡!4Ò+©#–¤šØBÒ9eüdˆ'çᯠeZ±~(ªk*³Ðí&+ØÉ¡(ƒ+ðÐÚ,P2Mp” X.IÅ_¨l‹ÃîÆ5L¸î«ÜUä(É]£ctbHÓ9‘Ü¥Fb ‰zßEØÓ®`E×L[ºJàᦅÊÞ-âã)>B$vçÑ`‹¥*ü¾ó†f·XÐÚ–fe‘a…€Ñ-uZ¬v;âßçiTùþÒPx}ãeÅ•Hc¦AëI`]áÄ4 3zT}YRk[°´ð¼¨ŸIœ'žy ¥ZüaÈÝÝ“°‡J(Òb‚=hîa†ä‰ú8ÐÈ!‰Ÿ@¤.]:“u®üN£¶Ð9ÄöÜïƒ1g‰˜msYµz*p2&ñ)°`máˆYÕë¬(OÁHj8L’x‚QÄCàE ï¸äÀok)ˆNÐ@(¥ÂטuCo,Æø ÁÃl³-í×Ã9ô"wPÓC°¦ŸýNÂ(§ðç¦ïˆÓ‘‰Ó=Gcü°½Ä /*vr¸£ð=;¾—¦»¿«}×;£<о«áÌ6Ɉ—1#1Ð!tƸ ~r*Ϲª™?®npy%2>~uiwJ©?¶'Qîv­WÇ®DNØãŸUnß}4k|ÂNúlMžœˆ‹9—ÏSÝÍsþ”ÚæãE˧˙øþH 5%÷÷íxÆ©4ÅKµußB†Zâ1÷@Ä*Û` ùñ3‡ÐêkeÂû[ÂÈÑâpµPKÄî&놖;Ißq¥‡¯(sÓS¾AC3È7 7©×öynQAì^2¤Èç¯ÚÉÏÊANZ:§¦Ã©Ûowé†R¨÷ ?Ù *!“ZL{#°…¼ä•%äû²£YŒŸF¯i\wS´ž²%‘ê‚jRÐÔ)é ~q³2϶Øñ±g]´>EöêOШÐÃCÊÊŠ;×aªy¯bV¤ _ßùÊ®Jäoá`øaY€DŠhô-¾ÂÖ¨8€SI²ôh0áËû¢ôŠìÃÄC€Zß;½È€8 c”îbà>õj’UÄãêè-6YE_¨üǬ+¶3zÀÊC]¯ûføpçRN¥K»KH;X˜lr“³T©a .=—°Dòz³©Wþ@Á‡@ø¨ŸgCëž\<Tf ªLúÒ›ªß\9@¡1†Ï¾{[yÛ`~{ƒFƒV¶½íê­…£êævÚ¡žþv˜L èÕ¿÷ÂÀï~,Œ8‚rYcM-·þ¥HC·‰éG§'} Å,]*ZQø®µyï#¥{ ’ï¶·-qò۬°µm`*rK#²ÆsÛ@YuÒ|Ýïvž>B±‘]µ¶f;@Hk¢ìiM8åö«Û ¬&lÒé#pƒ6kãÜj&(më¾Ém;T>Ù¼M’Ñ—>¤3·cíø+?cåÊvƒVΫ!ª o¿hÁAã½sþõ9ÒLsêÇçÃèÀBK&„Ü]îà×é“og–Š'°ö¥˜«û ó«ê endstream endobj 4364 0 obj << /Length 238 /Filter /FlateDecode >> stream xÚÍRà …÷<Å]ÂŒA¸!–õ¯c]©ì:]Ä„*34‰IÔ×—»pÆ…« g.ç¯ `M®¹¼S,·5¸=£j®l ®ƒ-}`XQ?½øi˜Y¦¦«qŒ¡m–0ôÜx†‚~2™„qý”ñú#tþ"ŸŸ|ôÍìóErD.ÙÎmÈ­#ïD&+dþZq# ´²Ý è߀७áë¤:€ÒušžÉ#?1Îó×®JqÔÿ^õg*ù”˜‹@dE‰R zýÖŒ¬¢ ;“#)Î ­,½ïÚ˜a›“¤óý‘ͧÀg§)ø7FÑZ{ endstream endobj 4391 0 obj << /Length 620 /Filter /FlateDecode >> stream xÚµVËv›0ÝóZÂU/d纎ë4u]‡t“æpdŽñ£<’æï+ q°8鉵°‡#1÷Î\†A`許 ¬,¸¸A‡r-Œ›[bµ~ô}6o-ãž²)¸2~ŸãÓ9ÃÀ‡>'SÀ| =„÷ ÄÈA nÌ®e;æ×Î(è­ÛàbイŒ“ÊsH‘ lB¡qír>øÕ«Þ5zÁn„Üq¡KÙÿFØ¢#ŒCϧ€c YÍ6†–‘ÙŒ,î˜KË&®g~ï £ëËÍVÇò ~ ë­ÎðKýP;Œ¯„~!õZ¢ØØeJ» ÞkH¿Y™2›Èl•+(™ëLYd&Ë(Y‹´^Ë-ì˜E½QFE™É,¤²„ÔeêŸydê8Ç}•¾K[± *èSR1Ï&N¸ÎÊ0…¨ñŸªäÝ<[dúòèž<{ŽÝLŠBÖÙ‹e\?L3)_é$b´Cž”I?þ9HýðGU!¯S„"MWQx/NÅu$Pþ-tÐD«õãéEk3T ÷X¢(œÉâ Ž7jwµX‹§¾8ŸÏ1Ú0IJ„ÓTÌr’R‰åc¨@ºÐ‘Y¾ .DÝéƒ/V*¡QõYY®êçLC«WÈ2¬âÔR9[ôÓ–L›£\êÍ¡$‹W±ÑúºHÒ¤Hd~vúäê²,§ÉLo¿—¹šLæZîIÕeEž?¬²XGWiã‡eu“ToÑԖ̶i]Ýh w÷çYê{âAŸÀÔÀÝ¡V”ÿ½áB endstream endobj 4417 0 obj << /Length 299 /Filter /FlateDecode >> stream xÚ‘MO!†ïüŠ9BbX>v~6©?öV›†îbÝÈî"mõïK¥1Z=x€^&™yÞa°St^£ÓkÉ¡¢•ê'0Œ,©¬ ¨[˜ã"vqåâ¸!aJ|‚ï»íÆ! —ކßO…~ .fyºëZw’ó{çݸüàTÊÉ¢ž¡«½"žFaÀskI 3Ðôh¾`Ð&}ŒU ïŸU=H]¦èáÝ!vÀ`T°r_gdºe©!¦_âýØGÀœQV˜ üWjõý²û`£{dŠ¥“'þjyˆÇJR¡ÿ ð§ÿ2¹ÃEžFÈäY¡U…/žm oÉ~ÙHEÉDË ßÆnhº`}–{;taç¿mÈmN™(¼é†õšDñæû~ endstream endobj 4426 0 obj << /Length 1417 /Filter /FlateDecode >> stream xÚ­X[s›8~÷¯àwŠª bß’Ôé¦M]¯ãÙîNÚñ`[q˜bpoÛ¿GlCp6iw2'Bçè;÷#coíaïÍ»÷×7öˆQ/"q&¼åfpû{+XëaÇÂûfvm¼PHxgÞÍàÁùlðê2$^ŒbA…7»ó˜ ‰‰'bŠæÞlåÝúÀû¿ŸMf£éðóì­a!!b¡ š‡r„#攡˜Ërsõ—Þ:ÍÚPÄÂç<> KÖ„¡°ÁÇýï'×£ÙhÐHúÓÑåh:‚ý ·Ø×ÙäÊã×–x=dÜ?JìφrO„ûOF7F‹ÆÖ0FT0x2A¼>_ðmÀ1ö¿” ~Pè×DZ sn,Œ½€Áò€ùÿB}9¤Ü/u4©¯ú¹Syý°zì*µ²Ôv·ÈÒ¥¥Ó¼ç*à¡Ø¿K–ªúI‡tât„°yluÔæœ/vi¶šoË4_¦Û$k…͹þfÉÄ¡lïË“jIóµ[ÜeY`ؤyb('¥ª]¡†…(ר£ž¡V­î¢QKˆŽZ*‚©¥ÊR›½(çËb¥Z罺„”ã1¸,:rÙ‰üþ7HeGR eZ†¡& DVú6)“MK¼ç>·t¸MóÏ{Ás`ëî®—¡YDq=°,×é¢L¬} 1îwú·:)‰P̨CPìjÁø·çðP"*»‡OöŽuÕÖL5è9× °ç²®æ¥ö#¸¾çd!’ÎÉS×ÚÙG‡ d¬ëû>NÎiØ ìÑ]§}‚Ç"© GÑŽ=,ý¨ÿÑâ;Yv$*<6…!¤ãÑO”àÇ2T";k˜Íتp³[B“©:l/ÂF'QïÊüÙˆÙO ~§“D• U•oú$tØ¢l²`e&Xš£‡íÓ.’ÌÅ«©jw¥Róm+šu57åÁìª ûÖ]pJ¸™t¼SIc¢ û]ßî!Þmt0uÊäî´¬€vJݠוZ©jêa Å›¶ý~®Öiž›.Ì9ó¿¥ †*U¦’JéBŸ@í‡*)hì×÷Ên°)¤©úÇÖQÅ[¹wŒÛNÂÛ32G-[šßéúÓ¸D×y½œT=iɸ€¦½÷ëôœÏdzùÍtȹÿçüj|£ ìǖ3Œ÷Æ¿÷°Q„‰«·¼}ÈÇÑõõ»±–ÿAŸöqÜw lvpì"1£‘Ò/rû6¶!2z`ýQ a¦¤þÌî“μš²–Ó¼‹¾’I$ôèC[o`O¦WcþW=¯Ÿ]÷G .÷m.½³&ö´‚e’ç…ë¯!Ü.hõ¦…jztÇ¥Íô¦ÿô4aþ`‚èÞz(‘ˆCÇëÜzÂXöÞzšä7·Ÿ–5´,Ð Li‘Ǧê¨ßúÚC˜ÑÞ‰®?Í~’¯4ÁOïŸCá(–s[žÛÌÛfV†Ø/,½±ŸLh¹•É2³”T_ 4xŒŸÎ8ÈiÔŠå:ùbJ¡+–“‘¬ÌU–Ó^×» \:*Œ=[CSÛ§%ÍÈ ‚e±Ùîjȇµ‘AÕ“ñ>Œˆî‰ýuÕç= ãÔÞ{ÛfD°®žêžwD”ñçÆ]ïO 0^Sñ „Ù QYàîí”z!E¤ _Ê[Íàÿ s× endstream endobj 4440 0 obj << /Length 1677 /Filter /FlateDecode >> stream xÚÕXKs›H¾ëWpD©h2^:ÆÞ$åÄåõÚÊæà¤Tljhåñï·{¦A€±ãMœÍæC3ÓÓïþf¸sípçÕäh1yöÒΜÍ8‹J'ô"æÍ•³X;Wô]]®tYTÓ™ #÷ùn—¥I\§En ¿é©äîÇ©€‰Y±Ó¥%¿Ú§kýÔŽ/t¦ãJÛÁ¤dbúañzòb1ù{"@ÇB:Évrõ;k ¿v8SóÈùdfm/ˆà9—“?&œÔàL€ôœÉ@áì@8%ü¸E¼¸KaÁW¡Uø¯rå/Wû4[/weš'é.Ζq–ÉÒ¨ƒžpgøâîN´”ØRÚE–šÇ[c/r÷Uš_ÛIÄd¦£%Åß»}=…¯µb7+Óx•iÚ ¼Þou^Û¯,­jfŒØZ¡µ†äªzðô¢ÀZcHk<{Sp8ƒ¥üŽ%tYbå2)Öº·ß³—`»Ž!9ƒÝŒ1²½ýÎjá D¢YþžûÜnö­ÊøLªž0I¦Ãý\ÔPQwÇ"á7+q‘ž*ßý\?ý>y”‚a_¢C¨Ü#O ™ßŠó#’ ÖaPùÜÝçUz› ñ‘ntsfhN%#6÷É¡%æi¦sZ ºUhš>q|—öëI©ãlK3?bÄK¹Îüx7æFP3òæ7ŠñýÊتÛ™Rþô‘律ËxÛcï˜ßa_í«4ÿÐj\›beC`èyÎæa+úÌ.9MWelþ¥ËÄ„ ')q™‰ÍÑ«b_“Æç#›CÍ•ÑpóóÖÛTP€f]`ì“z_ê1)ˆ]_ŠÖ%ò€@‘C…Œ{b Ç…iökšëúfLâc#pËpĘ€òŒ©m×Þ¡v±}…!a½à–×»‘^lF3¤ ‡í®È¡,W”,:_Û:ãO)XÇŒÎÞžžÞ› ·âHB%V}U¬ÙðQÛ”ÌFY+¯«¡d|‘ï¥à÷U@¦ÏšÉܪp¹O]Uƒepæ{aßí©÷eþŸHü“ü€ZÐ+ÆknY”ÛÖº²µ2ð™ç{ýÝ.Ómš¡§ݺ°ï^Oëf&v+,uJ ·¾ð1+6û<±@ ¿ÌRúÛ×náH#È€œV -­«ÃO;:q,éGµÓIúž+»‚ùÓî‰úò~uÔvÖÎéXãmEùn,°)µ¾ÃvÚ ßkm~\7¹ôþ[›çwÕE©X ÚzôéFçÔé(7SòoN{f䞬D×z­×” q&"Åf£,º(6ÝÅÝ™}5†±}u1"|R= †¶´Î’bŸ·°ÈU k¯«_ ùé¶YöЂô™/ç úÄ7£>ïF}ÔV€×  Z݈úc#>‹$à›èÑž„r à 6#÷ €üt€'à݉mþWNý(H÷àˆ >>Šúþü¡ð(ºS袟‰ŽàH©:GJé&P>jM¿bû"œ·)ñÆ£${ÍÎT5øÕ=èØ®ˆóóµ]AÜ­›i^•Ì(~ÍßΖԑÍ`ФŹƒ‘]ŽqôDŠ!Ž4¢Œê†"³òÀE˜øñØqlÒùpÝ#Mo¬ » %ZJ›ävEU¥t_$- ƒén¾çœDÜîj"µÒwD±EµÓ±ø3€–J¹Ç€ô¾"âD:œT¤ž¶ÕÛ¢W•7SNbeSdo×Íï†CÄ{¤¯Ó<7açûŠÜˆ£²¹Éô}o294Ë@έ{q‚­¤8ª¿ìh„qb(7´p(¿Ý#£ÑŠ–¥ùÛP“œh$ÇÕHuV~ø­Íð‹#y¶X^^L}ßýsyrv‰µ©Í‚+¦í,<Ö{ ;‡\ô¢ÙäÝ‹ÓÓ7gÈÿwÜíÝÙØ.з[Ó.+0!h#¢ÈÅÚ!¢ÐÚ CÛ Š‘&¤ME¤YóâÈZ™¬Æ:§ˆ©®ô±Ï/NΰŸœO#î>?5NÀ|ü´4ÝØ c¹• ‰sLBS0=Ù³B×V+Ý@µKû@~x°T¾½Üö$‚Úš `[á©À=¾‰wS¬@$ œ,0pàÍÝcº†2Bì{W½¡ðÌÝ;ç> stream xÚÍY[sÓ8~ï¯ðc¡›eûºÀpY–-Ù&ã8*õàØÅ±)üû=G—ÄrÓ6”ry‰-ùHçþ#…F"==z4?zðD²(#™â*šŸF<•„‹,JdJd&¢ù*z;y1åñD·KÝ6›éŒ'éäáùyUyW6µøCO9|ž2 ¬šsÝÚé§}¹Ò÷íû‰®t¾ÑvÀç„MßÏŸ=ž}:b X”p`-IB“¨X½}O£Ì?(Y]ªu$U Ï*zsô÷uºPÂ@J¸H­XÔ‡K“'û´F®Œ*«ðÇv/ŠbQTxfÇ»™Ü> P”^éº+óÊÍåÅ™£:ËëU¥‰Ñt+êVdNS”+‘ð+SeEO‚Èž(5—F3.Ax ®n[tSÓ.Šf¥~ž€‚mas VÙ§+,^ñ€Z%$ËbOýŽÆÔî}[Ùcˆ/2oêÎΗn$¶H‡ %I™ô+q‘žŠxò¥»ÿ} ¯bd޼˜ :9Ó× $ͶªàPâlŸ !ÖÚ퇞°«ì:ã)J Änæ‚ᔟ1ª´ky–èXEƒ’æ·^ ‹±t!ô~g/A¯m".˜†´Æa±#4Q÷íý¹""ïŽÎ¼Ž6qisçÚ{|ƒnA&$•ìŠnaáÑtTí•prK~ãžaßi3#<¹ûÃ&S$…šûû6¯€œ¤™ºShº ’¿2ɯf1w &Ç &†"ÅRͯ5pPZ‡[ŠÒ-¸8Óõ¾Ì Œ¤É‰Á¡m“¨tܰã1]kƒé÷Õ4ާ‰f4°ÓõalW£©ŒÌ§vIn‡›~¹ÑŸB{²8gS‰| q!7Õ·§…1A´ÎW8÷™ˆ)0Q*´#q²=0;€d™\P ALY¦Â@ʼn!à™ñðphÓŽ” Áʎ˽j¤ê=;X *¶j,uw!¥±£´ «ÊñFü6Ï3/¿oÃüäÜ8ô°%tz B‡û>‚0ëh½Š¡£]Ø€¥})2TÝ<-‚À @“9B§G÷@!Pä§Ò‡«0›ÛmÎÄ >CÓØ½¬Â83¸`„‘U\bšç~q ©]~Qú -œÀËÒ1o!NE¬‹Î€Ç@©*·’Jê<°Yñn³$¶Ê0ƒSƒ44“yŒ‰=ú¸÷Ú®ôH+šæôc Ë1¤ôâ(›ÙñäÕ?/_Ú·Âbôÿå YB’]“ºk©ÃÛUIv9‡þ1JT:o-k¸3É9‘"ÅÑ {†Ø‡ªztG…¾é”¶;2û?í¶Óç=86<ŸŒÿ¯„Öœ«ƒÿ®Üûç£ä„1×J*纙’™qœû»õõ3c+’ñ­õx2ì™mU endstream endobj 4333 0 obj << /Type /ObjStm /N 100 /First 970 /Length 2214 /Filter /FlateDecode >> stream xÚÕZ]o\·}ׯàc›.gÈ!‡€ ‰á¶@ ±Ò~pE`$YÒßs¨½²w××ò]iî.?†3sæ‹·dÍ!…’µÉN‚6#QC‘L¢3‘%T÷п=´Šß<á·q˜/~Qr)¡W®™{IX&—D‹’îÃoñ(&Ü²Ô Õ Óñ¿cIÒr#ZãjA\ŒKgPÆñGzål°¦"…”Uã.–ƒæÎ]¬|Äó˜­K¦„&žÌxÖ©°0¶¨ø¬Ûø ËõΩX)§!8gë¤ZÈ¥óààó9®ö[ã¶øƒYd´aZ*œ ¹i”Pãæƒeœ®3°€9׃`KÓñ-½Ž¹8iïAÚ> Œ»Ûùû¸«úe¸ûôè5Ïeôù£?ø]Žàýᮣ֣¨m!|!–,¢-YD[üL[üL[üL+ a ±¬Ü–•Û²r[Vöee_Vöee_Vöee_Vöeeok:·‚a»%Hj:"¸ÄQ™EnÔ²«cÙP¯±†Gþ€àhlÄâ³ ?«sRPéð&PT:‚«L*ÆõëÅߢ­‹£™…*­ú,½;ƒ8`(Ö59ÊVdT†d³²5¯Ïíu¼¸FÏ£Ÿ]&¥"RƒõIHn{ùȈtÄÄ dÊú 0ËÂ`§ØÈ»Mªxmëóƒ`Ÿs Âð²1ÍÒ#9ƒbrf~†,I{ì‰ MÇ>3ÀØ$B‹@1Âƒ \UcJÈ>+ 5]Ÿ( ×‹J5‰2nû o®xádœ5øŒjSo^Öc%g¤£¼Ùݱ2òtÞ…ŸÄÊA;ÌRí4DZ?ðžæôá C™i¥Ÿ00—ã;¦ÏùÎÀt ïzb3mÿbj¿}¶ßZ;h»–²ëá‰å›%HoïöAšýá Í HóҜ¢.Ä9ºBµv”ð念ÃTs{Lü¢˜dÒSQdÛ(2uÄþŠ„¹¤ü¨øE¸çË* +¼Üâë3§±rŽowÙ~¿s¯¼ý驤‚‰÷;1¯2°QYÊkª ”zÇ "²ä~"+Ÿó®ùÄüý÷y×ÃAdK|>à|)g>w@MÿFåc¯irš×,vô@)‹Ü]Ž—–vD[_ˆ]Ožï+Á}ò½ïÿK÷),•쎾¬àv"'+}¦v¬°]ØQ=ÈŠ§3ô÷Á|TOéTõhAH©wœhëCF'q²²z$ÇÆZeÇ »·¼';‘_U*ŽôOƒZ‰>^OÓx‡ñÎn¹¥2\åî ¹+ßxŸ+?t¯+?h™ož20áàå„|ÏÆzþ8ð¿)Õ— endstream endobj 4474 0 obj << /Length 1478 /Filter /FlateDecode >> stream xÚíXK“œ6¾Ï¯à.#ë‰DnŽ»â¤*Îz«rX»¶Ðz©00Æöþû´°ÀàõƳNœª\x©õu«»¿npð.ÀÁ‹Í÷ç›'Ï9 R”&4 ίIÉâ) ΋à"ü9¢"ÔíV·MÅTªðé~_•yÖ—Mí~ÐÅáûˆÀĪÙëÖ ¿8”…~ìžÏt¥³N»‚(E$z{þróãùæÏ (8 nkŽ$–A¾Û\¼ÅAã/ŒXª‚vÖ.à‰‚{¼Þü¶Á^ Œ Çˆ&ÌÌNHЇ£Á³O)L0ÂL:…ÿh·â2Ï/ Ýõmc4»q°ãAÛÅxæn9¨ (tÝ—YåDzüZ#«éu„L±2¸$‡+W‰ƒ¼ÈOž'É/bÊA1«ÛÖSÓ^æM¡gû=y N´á¬²¦ëY»‰é|p1΃vÒ¿½@”ÍwoêÞzÎÇ~›©é:ŽÃJ³HGL„ûǧáaÌ<.ì‘åÃáµ¾C8%# XJ¸% ‚³'XLLHÖâ3wÊ&Rcš2$„‚ŒRJô}Öf»™ø€”ÄîÂ;ÍEY¿Ø[œÙ™©$ˆ–é=vK~)·mfbÜEÀ(ć׆ÔK‰‰D)cG榛íÏJ¹ØÿY; ²™ûzÕE¥ï4ñ`"PÜô–l#‚Cm.ý{[°ÛšHŧîD^ªú†|—'A„Ù”f'c§ÄëCžë®[,›£æ .ç{MPÚúAüÊ„õ‡]ÙuŽ@;&¶i­ÖÌ\,Ì|~]vnúÕ¡Îûq1d$s¨&Órãg ÈÏËjœÞóœ×•nnY¿›øcÝûÍ•wÊiÜ%Çr¿cÈ/´¥›Žñ Þå7©šNû-ú…ó¹ÁÆÝËÞ3À½IjÁP1%)°XÌRKš:ìçôtpìÁ¡x²,äž¾¯ÄHÉC2¨uœJ…D‚ñ‡e#òÅtÄ¿±“騬OÄ'Ùé´ø¨9ô+ÇH˜>8#2°žÒ3"ùÏ2bY¯e!…ç_D…³l´õï…ϺXèw›„ÃôÇcAd)·µÔßeë V bà³Ma9`ô™ßÝjmÜðÃ±Š­¾2&xÇžÇÈ ƒþcªî²^…”u+|A±Épü6ÀVô‡.‚òÑ÷QdN¶a”ã •B«ÏïGo)¬žŸ°%¨bp©BïumN¢2yù&’"<•–aˆA­ÑXÝV"@Ë—µ³ô-GÙñ¶œôîC?ð”Yâ[Ç-øškl]ãgÞìýT ÷Ú°…IÍ„±+-¼E­›ØH‡·GîHfdÆ%Rœ,ÉìöF8N… *\õ­ôWß.¡ýý•„tÆü¿¿zØþêa:zÿNe´ï¯>Av¾¹²/ñ‚ê‘lb™~Ê?e˜yjYþӢШ¥üèŸVš&«ÿ´¦kOU@RŽ€VïXŽARУ,%CÉPi BšÕ’ÞW<ý·8s™"",ô^‰'Œß# ØÖ@Ôß­EŸ6_g¶×‡±Ñ¹9†î€Ìƒ;;ódÎnöizvöýöìb%”£ió¡ÕÝ¡êÝsé70ÌjïU™ù¡²†‚b¥LHàÌä^m¥Dä¶‹¶m¥Ü]7‡Ê?ײõ“À/"'›«Vš&†vËÜy¸kŠò f|ßú–Ù|³&1ƒyVUP+#ƒ žø^ÜÌC‡Ú½Æ3Ü»—²Î«Cá…y©|š-ì8ð49Sv4t{Ð/?t欶1òö?Ñ™ÝõÔÓÂé5•Qö½­ ŸB¸;@ÁÇhrïΫ9…ñ9‰*ðNÂY>»Îö¦Ò‰|Q ¥Hbm†Ïš©Sö•&¸ï®z¹ò+àZçóÚé髟|½cDÀCÍ>ÌÌŒ©»¥¢p­ endstream endobj 4493 0 obj << /Length 1256 /Filter /FlateDecode >> stream xÚíXMsÛ6½ëWà(f"ß$§§¶®3IzHmõd{<4 [œR¤JQIœ_ß%R$D)¶åNÒN.‚‹·‹}»$èôfòË|rr&( q¨˜Bó;Ä‘/,BŽæ ºœ¾÷˜œêòV—ÅÚ›1?˜þ¼ZeiUi‘›‰Sí12ýèQx0+Vº4Óo6i¢_›ïç:ÓÑZ›3†©w=7ùm>ù{BAù ¶Ø'>Š—“Ëk‚˜‡æa€>5O-‘PŒº˜ü1!Ö‚)¸@0S¼~ZQTÂ;“çc^×»R‚ ÷Õ·ò&Žoî½%SíÉiu³*Ó~8n#»ßZ[“·u^´1ÕjHš§µô‹®å¡N%ðÕzÕ÷äϵ+µ¾lW[ 3ÖÚ‹ÓÏ“” ¬„ly>tOxÊ×Iا…ÎåÔú”Z's»cVä÷¦Z²ó8J¬˜?ºBqÊ „Fr4ãj”êa¥åÉy3_¦½êÌ©U¶KŽ«LÞœzêºÞ½ ´&N"ËÑ+Ãû â>«8À»š@. ÔËÖÿçRc„B¨È‘/.ëÌW˜™?t}Ÿ®?šJHò2ß\˜æ­ 6y<["›MA¢N"›$–›~ÊÈ‹VE¬e‘¤W„ Xå6ç'»‚Ó©^edgøvlVn%w$)oemŽß:Óߨ T/Øö<ÝÍ(¡ÀTøßIR–ÿRRfßWÿçÛÿ}µýãÒ‘Újÿ(Ã<¬NÐ:ñ´þoÇ¡²VØçŒS·kòhù4É ”Úþ‹w€ì?×>§g½x¨é12¨—n¸þɶí]ê˜®×æ¥ìè£G·”§Ú ) Ot×d|+´æÞ¤æ±º¡íÊ«uW-Œue’"ë'Å.:$1@ƺ|÷Ã6c}yí5iw5ÖÖÁýíïhâ „k£äãûÆî¢uÜ}á êÄÔ£ßw¾½ Sjï„ÂÐCÏ”°ïë?¼mÎTHÕÔà ]`ÿÂ6Ä endstream endobj 4513 0 obj << /Length 1651 /Filter /FlateDecode >> stream xÚÕY[s›8~÷¯à2µ¢+‚ݧnºéô2;»mö)íd(5S .—¸ý÷{„ŒS'ig› „tîç|G2v>9Øy¹øãbqzΉ¢Ð§¾sqãHêH 2ç"q.Ý7®*¯UYTÞ’ÊÀ}¾ÙdiÕi‘›‰ʣؽõ,ÌŠ*ÍôË&MÔ3óüNe*ª”y!ˆRD¼¯^,¾,ˆ‚bXs$±tâõâò#v˜í`ÄÂÀÙ¶«Ö÷3çý⟶j`D@zŒ¨ÏôjŸ8%|Ø›|wHa‚fÒ(ü¹¼Wq|•+O¸Û«&O¿xKá6Vø¥ÎJ=©¢Ù/‘Ì>ó›U‰Êë4Êì\¯ìŽâÆŒu7QmTœ~ÀŒ«Ä~ù¶±Ÿ¶i½ñ™ –Gk…Z£öVé­Cq M 9üòÀ7Ö™N‚uNÏ}`ì,)ˉeTYêˆ(Ê«¸HÔˆßé9Ør`X ŽÁS³›6í^`([BŽ—Ý–X`Ãà¡ DÙX€"¯Û8ýZODgÁpGáÝN½IyL¸_kÎë™J“©í«~^E¥y;ÑN;já*Íâ£4$’B€“‰•£ØcØ]©;ud‡Ý¾“4™q¡(¤tà2_ß*P]r&QSKŠQ ¨¡¾‰Êh="ïP‚B"%QؼLó½ië¶ðWNµÃ(”½zK³åmz]¶ÆÇî·!‘ÖµVÿ‘¤–Ê’H26• MÎ}Ö,@4Ögå  hÆ‘‰5 Õ>é4žÅR= ŠŽ¤9Q$dïD’uhäM¥’Y6íÃÅzæ²hj˦‹’1†Êï§ï*Ê“LÝM{¾HBá ô†ò ?õ­®JÀmŽ$âC)ÂS¯~ ß•-€ˆ~NØ(ñ¾‰cUU“m“XÇHðà ÔM™ß[bú‰ßèDÙ¡¸Ð/ztË¢ì2!QV•£Át‚¤K_ ‰ºdÊ'×}ƒ„U‘:šVa„§ïf>EGèÁ½R+x;z<%ü_ôÄCAO»á±X†0:{(–õ x²+6ûÖ¦‰@þpLc€Ã¡.OOÓvð3bÍd~p¿ß’2èV˜ñÚ¾·¹ ½z«Åœ"Ëq,æ‰&. "ú?$A„°HôÉû¹€´Ã•!·sí½4Ëìî4·A4,( êM_F…d"´/ ö¨T£¢P@È®)þ.Õ>m„™„XE]-¬ÚªÚyÒjCú„©÷siVQ"|$v! ‰Ó°ì%G3tÄðØs•ÞªÕªh²dœÞí±VkÑIãq˜5Ej=“ìÔ}ÚWÝ ÿfB²J“ƤдÂÞ#Å3&âDàp\\ÁêsóQ åã "ôb­›!úuºFÓþýs^袶ÍÇ¥¯·E6¬×R€–Œ1÷ÕÍnÝœ¸ð,Ø1žéÖ$…²©‘õ¢4 Y‘?ëB«¶I¸)•Ý“Ú1ªFÛôE6ˆMôÈΑRx[›Öqˆÿ6Ÿ¼¥†«MTU[E™Œ/cv‹Fãþ†ófWÙû+ƒ¸iU§šŠžÙ¿ôŠâ¸hòú—o4µ%¬¥´Ò3gzÌ‘O‚_ºÝ|”VÊÈ}›Æ³÷X–ß¡ãGŸK³m½Ï§÷L™û½ÉL˜šÏ„»+cþ†Ê¡.Ûwt)1#†äˆº'Ø Y[ÝÓøpKkíY뉽ڣP9'²åxè(4ùªªË>KÆý ”~,&’¿×‘9H.#øM³IíB¡ïfö›“’„÷0dJíÄ€c}HˆÛnõ…ê"C$ñ^ØöÑ8 ÝÉÚìjÏ }{öæÅÙ½“NÿÇS`0 üÝ6ã šñî6íô¶æº×¥ å?ýÃ*/õþ¿nöß7¨„X}™Ö@ÝÕ¾Üxr…Ûý¡èC¯ìóÐ=Ó^ƒ&5SÝóÝÜÞØð›ÇãKÆç¿ê:?Û&úÒýûž¢ÿU|ý endstream endobj 4529 0 obj << /Length 1848 /Filter /FlateDecode >> stream xÚÕYYs›H~÷¯à\ÖdNŽ}s|äÞde¥ö!I©0Ùl$P8âxýö @Èë8Îå*Á CÏ×Ç|ݱså`çÙÁÓÙÁ“sNœE>õÙÒ¡!G”ENÀCÄ#æÌÎ÷•G…+‹KYä¥7¡Aèo6«4‰«4ÏÌÄ©ô(v¿z®ò,Ìô³:]È#s?•+—Ò ¢ïÓìåÁÙìàË<Ø!N@akŽ8ÉúàÃ'ì,`þ¥ƒ‹BçF¯Z;Üáºr.~;À]]XØÑEÉ"a5N®ãìJ«v«k{³‰ËòÆcÂÍ‹…™YzÃh°Nª5ßÒRiY¥ ˼­–a7Í’t¯ÌhUéG̸´/=†Ý[¥ð“sßïZœEˆS :hI¡ÊEi–ö¢ …pgW"µÂ™PŸ!ÊCgB1jžÍZÕò²L/WvôUi¯jYšq¾h˜×Õ¦®FP¦â"hö6 ËzUÍ“|!G°BüøA»>.ä/ÚÙ·@<ﬞßG<ð­6î>R‚oõö€õ£f‹WÓ§bþêa÷øâBEãï§ó‹÷''g0ÒÊ}Äcø!f81—²NY–w¢3=2¶7ǯÏßNßœnÑ‘toâÕ6±»n©_<‚]åIŒ6>uÀº,þǵy~<==›N=.Ü·Ó­FtG£ iTùª“,Œœ>òcÏÇîûÙóôlý± üÎ ï–ÿþeÓ_¼=Ÿ€ç;àß©v¸.Q4 ÆBþ!“ ‚MCD±¦Q<짤;“ÓgÃd2¡EÀäFPhIøsq)æÉõæf¾†S‡ìÚ¤0±ICz&¤á>6°®0|cÆ»ï.ÕqÈmÚI”:† aÔÌ–ZnÕÎ[Ù†ýõÛ ÔóD{E‡JË€Ã/}c€á¤6@5±6ƒ¹­î²(”¡ó¢eÎŽç!euòÇ-Ý gI×ÝX QDZÒUA`ø@ü8¿¿žU:Ç«îŠY< Û”/™ÔY©R€‡jÆòÖÁ  ƒÀE\Åw!ã q!šWË>Í ª&¡_5pÍ QÓTî©´¡1 )oÀh†bš¡°e(0Åž##@¶“µcšÝµ³H(FJü»÷@5­í4ÉJV©C]Mòèón×¥R•"É#cTH{ÈבÐá/-£”Õž'”7Î`ʯâJÚAã…rwUk¢ÒÌÄæ2~4áÁ A ð ÜËs2Ï}ÿaŽжònÓ¢.AAC fî4- ^Ë‚6F„–JôMØE_' {Ü›ÚyKìiÖë8t‘{dÙFã&]ÙF÷R¶ÙÀc½¢Þ­áiÖÚu½Ž³I!ãE‡ìl1í,÷¥]¥¿,¤¦è&úÌ©VŽž-‚‚ ågËÈ\ìåsÁà¶-dn ìï"µ‘Ù}W¹nK™” ÙV•êO•6úÊ™á—FCDÞà˿ϗ“*YÄGkà¿*›å:àL>ü°!{†õj©ÜyÓ8Ð\!§ûª‚¡ÿçþ÷ªrÿVc÷ÓìJŠ(gÝj[—98ñó뼬2 §^¯qgyÜ*ýSöº‚fµýxe¿£ÜšQ]¶MÄVb[K¦‰üI}„x¬>BL2RÁbŽ|þ'z‰ˆ=½„ažî7N­£CÐP?<}z˜(÷7köÕò”²œ?~-AnäÛZžþokyD#[C§mãÇný"S–VŸ›Wµå;1ØÛØÊØW7Þ«ö°w €’„î‰_ŒÃ€ ‡RT ?ª*ºçœuÊ:5J:í›<Ó«yW6!HÃ%êôÞšå–OÔ­áu×å3³ÊóÏÞ¤Õ»Oº´ ÿ7Sœ¯ê"ÞbÛX!ë´*¡X‰Õ9µIµÃòêÇ3,f(ˆZ›oÏv÷yÉ'Hl“ÏÏα„ÁvÐ/™‚’‰xyæ endstream endobj 4547 0 obj << /Length 1565 /Filter /FlateDecode >> stream xÚåYÛrÛ6}×WðQÊXnȾ%NìišÉ¤®ú”d4 IœR¢JQ±ó÷]\H «‘“I§ã±yg{Î.i,Ü^NÏo8 b *‚É<4 Ñp¨ª™ªÊíhLe4|±ÙyšÔy¹¶7^©ÅÃÏ#‹r£*{ûv—gêÊžß©B%[e/¢‘ѧɛÁëÉàï(8 viŽ$–Aº|ø„ƒ î¿ 0bqÜ›Q«€‹ŽEðÇà÷vn`D=FT0=Z ‚G7ïN9L0ÂLZ‡ÿªfát>€7jš–ë˜ñÅTÿ-” ÁØntlÜH{'±‡"ßÖîFQ”« Éì™Ö{nÖZŒÆ ©§™š'»¢>Zö#1üÚ µ^»ãó8„ƒ1åàohýù¶S®Ýf4ž{ )£ƒT;,úGç°ù¼íE°B»DáŤ¿m èc—þï4ŠrY«_z<¤1$n<4£Õˆáá½u#wîiŽŸë ¤ÂëÊ…œeŒpDOpÞVõ¡>ñÚBÃý™`³½aºoý0×ê¡î¡XAŽ‹.ƒ!¦G:p’누i÷æ!—8Av³¾ñWçÆCíùÚå Gi‘¼ÚÍ^Ìyô;¨‚dãøBU°Èm¾ô¨˜–qGÞBž˜±Õ 5ÒºŒc‰"Ì4F3W'Ë|k‡Ïwët¯'zÃ݃Äïpƒ"Ž„`‡>Ø\FP(I3¶^&µµ{¯“?q‹¤•JjSÓàb¦Àya¶?_çõôÀŸ¶~™!eÕºUé®R}3UÎ&{‡é°_r“cð*ê-ñªªÊj z¾MšRüå]ßc&ÚÓãÙîb­¬œÝ£éDâ{‹Æ!ÕWýa"£§ÕòÍâÁÛœ®®Z¹Zj/ýæcµ]ô "Aó'WJ¨2á¥êR?ôÑ”"¹ïÂÎU•.BgÅÓ˜ýÊm°ü•%"1é¬ü^ó¤Ìa1麴G{=¬Ö»ÜÖ¯rD Cõ8MíM•¯Ó|“0º^ºhÛ‰Õ'à¬Ççd»Íë†Âv˜×´ký žî};Îæ8ÆÉŸ¸¼_]†‡1}ê!òÂq  ( ÛÄýlêYÑû†ƒâ8|z5̼8ý|½F©³rB¼Àu5‰‡ÝÕßÛ•÷T<‡™Ú·/Ù…r=XÜgÓzýˆå|æ¿ÄßšºëQyÞˆ¸y?Ò­|Ö¢«SÒ4™7i•ø¶~»{9¾¾{ýê¸Oè׉oæDGQŒçPË*W@ØLu˜á©ŒãXø*Ó†M‡¬Gd8"üÿ%2ÉÎÿò\hR"ÞÊ L^N=xgt+Õ²´O/tfL„@$jDE\¦œi‘«õ¥(t$ºTķʪ‹© pÎñðR\’Òß÷4MRýгT_MDP÷}[”¦WÍ'÷:¯!Ð 2_×çqi}°/XU–Ì u¡!=|ß3NdI| >g`«õûY¹«g»yïA^åþõð銣È1…]ý¢ÿJq¤]4?C†ˆ±nçþB'Ìbí¿®?ÆÙ:Q©+£&å¶§ ´ƒâÎô嫲vu¹‘Ÿ¾¥K[è[òìÈûk;Úœozú…rn“[ÕI/k÷ЉF"z ¨~òŒ¶¥ÑU¯§©TªrûäqÐvå¹”¦}_`õ·»î¾]C‘Ö™ÓÕ‚¥·¾ÙFhS Õ|yñ»?ß¾õAï¶îq¦æF†vE}Äíî§[(½TœýßšÞï°:‰ˆsœQ€@8Ãëe²1m™‹.´NÆ‚ÇÃër¥Û¸M¡šö¹mîænü]§þ‡œïí´l™îÕôÇ™/û5ÿÐÑ,ízä endstream endobj 4561 0 obj << /Length 1898 /Filter /FlateDecode >> stream xÚÍY[SÛ8~ϯðcÒiTÉ’|Ù7 ”ÒR–…t÷¡ídL¬O;µÿ~nŽå8,Ðét‡lËÒѹŸì}õ°w2z=½zÈ£8ðo¶ôüˆ!ŸÆ^È"ÄbêÍRïÓøýÄçcQ]‹ª¬'S?ŒÆëuž-’&+ =p$&>ÿ˜˜˜—kQéá“M–Š—úþRä"©…~ È÷™|™½ÏFßGôÁñB¶f(Ä¡·X>}Á^ ãï<Œhy·jÖÊcA×Ü»ý5Â][Ú±…E>óB‚¦¡¶åSV|8/'ËêV—TRó4¹Î…ÔéÕu…ÅXj¨$LõònDs£ì„‡Ù‰4¦ê›r“§úþZØÍ˜Ü ðØìØÙÍQ{j¶›’ÅÔ7j—›Æè wכ倚œ!w®šï/_O/ôÓJÔuòU…SùÞ:¯ÝQ)@ŒQ£’É p1ð¯ù¡,ÊE‚(ÖE}„ÃØ•ôÙ'ØYÛ3 R1ˆ­]X[rµY,À˜Þ2g«©^÷ü­ŽÏeTÿüpüAïyZԛϘ‹LuèÊDõþѪøÏPÂÈç—§ç2OçF±ƒ çãÙá[­Ë¥Šëw‘¨åÄF˜4\k³b‘­!Nj,)ÌË&[Hqßä?aìJK}-JkhÒ,¤È›_êqe¦6n>{?›_}¼¸8;µÙ;` Ñ6K{êÖèPrú½1vÐÔ_nÊááüõö=8:—ÝæàñÖã°)äPfc±H´sM·(’•¹+«ýÜÎZ%y·Á¬ ì=Óœjfqí­æMU<¹’Ÿ•Ó* -¬pù ¯ãÊZ½(S¡JÜ›1Î]OT¶\E.Û.°NÇ…7…;r¦YÑ(Wô ¸1/oJ“Tº)],a1€R«º‚ 5ÛéŽ>E ¤™¬ ä;1²šdV$+šÒ±¦Ó¹á©Ó¹ÑdJÃp|ºÒ3"ˆÑèYzfµÞêüãٙѤHöàqÌíªZJì§*€›D³î.* , ˆªˆÜÁU½,—¦Nï×¢Å/èÐ .'!ÿ={¥c /Í\[5µX”¶§-ÊÕº,Ú6]ùÊ÷!—¢§¢(nçßfyî‚ÿ:™ª…ôœ§b™lòfúB:$ùJsª©åYrR•u™~¡7f½~h… aF€|IuCÿYhKúƒÊÇ»la`eÐ1BT•ÌಚËÊî5  ~ÊÂqËe´DÇreµ)w(G`”]÷sÓŽžkˆ£Žbòé]óP£.‘6Uä"1¡||ט¤Õí>1}îÅ‹|ŸEQŒÈVD$n%tÇ(N ­Å>ÑÒ×I•¬ñžÅIBS¤AŸBk» Í ÑaÜã£gÙu•XÆÔ¢œ3Ć”}l8×ÀÕ:ÏÕ€‚óúÄýH,]Õ•)! ©O"Æa?úÄ8z1Þ%áï"Ñó suÖ„°1ÜHȧ2“D݃†ô˜7ån×wÙÒ²ÊöM5a|<­×b‘Á—³3;â²Ú2N…%r×,—Ÿzª¿Ê¶ØµàcmvUÍeY 1ïèªûœìbªðuåÜ!‡ߺʃî-fºå4·7¢0&4®)Öþ¼,41Ñ)°ØŸF<ùˆA zò95 ÒÃ]Ì;Q³z0'ý¶.ë:»ÎïõˆíU`Bš§Ê•N9¸ÝÝc)‹Â¾NôE&&ÚS$Ž- ò º.=Ð1r€ç`d»þ{€ÿ? lî^þœP<„sG“Y…{#YE¸EåtÐu°ø .SgXqýÇ!.ßAÜæn ¡‡Û`?i§?u±>:£1XE{[´qÝÅ£ù¤‡<3U°4€|£»f¦ˆú…M?PÝ~¾‰y竨Ó%a¡j]R@ÑžÀS*dÓ.Tצö#ÆåhÕÖ% 4Ùʼʚ®@_êy®×ãdÙ£h¢/KÓïír¶‘X:¥AfɦX¨sT‹¸oê :nï+§ýêße•í‘NÇlxÚvöVÊК“†¤Þ`áÁ€Iû*i¡„J»Âʹ–Q½ïÉ0.Pf\à"¤o³ÃîÞzÊ€Ïî«Íù)k|S—Üj;»néÀ*éh¸K`cø²Ìäæ2 c¥Ú9^:4[©L²'6_ÖºÒüHûdµé‚K{ö LÁ²M¨-áøzÒÝIþÉ­þ -÷Oí ¡( ¤jÏž|j/eaŒÀPuâY*^*þ"11 HۮߨÃApž±ÝäG•6%œPwü¼7ô=ÊÙwÑÖ¢žšç¥Tå¶• [Céݘ!ŒùSk¯Ž(d?xô¯+»¿æ+Š© ‚&ӀŶžå¯C§*åÔ™ØPê Øø/vlˆ endstream endobj 4460 0 obj << /Type /ObjStm /N 100 /First 975 /Length 2002 /Filter /FlateDecode >> stream xÚÝZÛŽ·}Ÿ¯àc’Y’| `Xz°³Ðƒ"!ÆN°Zößç§¹—Y¬‡žŒf ÚÝêî"yÈbÕ©b·ˆÖ‚ˆæ ø/•Cn. \ÉšÌ Eš %ÔV]¨Áˆ]h!§Ò›YÈÙl…žRÈÌ®VsÈRÕ% ¹dÂ¥@PoZ $ƒ.ºÎ•;† É)9Qñ°íôýž 0 ”Xp¯¥@´“r ®ÞIÃSÍ>µÆŠø šªÍ§Ð4‘ƒÃD8‡LÉGk˜%û)°wI—ŒÙiPüVÂÃb‹+®ìýšBªÐÂbq£Þú­¯åÀæ¨Ï) ùhEÚŸ!;8E¿¢N]¹`¹!aîÍiÂAÜSß/@¬¸£)†³¶ýZu=9§œzcw?’¶zñbµþ&\Á ^ý}Xÿðã?±pØõ[æpýñçŸß¬¾ø¢+¾Ü^߆/Âú¥{¾û_oòÒ÷›ûÁîÊcÓò 3‚#.W¾Dîµ<¾ŒÆË•ø3éWpýÝÍöÝ«Ím¸ ëï¾yÖ¯7¿Ü†;,¯ýïÞþ{³Z \›ëÛîì½ýjýýæÃöãͻ͇]è÷þ±ùéýÛ¯¶¿„«„UªÑ ôö­=¤µâ—××[ôvµ jާµE!”!Ô!´!Ø"Ô4„Ü…=ø} ÕúÕÇÝöë¿¿¿þÏjýÕöæ§ÍM™Þ¬ÿ¶þvýõUî>¯wX‘šc‚W—†¿ØÏYRô¨WLcâ µ/»™^…õ_·¯·þÓ4|¿½þK´’þìë{ DÍʪyIƾ?Î+Èh@AÈø™…ÒN¸*‹yÖ"6ü°"wdjç´N’˜œFw@H”2ä´ÆuƆ³ aÑ("³HNiÆ"”û5‘œ#Áo/€„RayC”ŠŒƒ`,äеÉg¶N‰ÚÍÒ‘°XDèŸòxI:—T~À% i­±!>â’§ŠÇ ³ÃJ)Å„Ìå ¢’EÝa½Ä‘g‘”Å\gKŠNÙŸy?%OËÇ“gì×ò¶A§mÐé2Íž_/ Ó6èÔÒ“ET…‚厺rŠ@qEdö\õŠ!Ha¯^€EQåĪ÷„Ž[š]ü;}¨ÆVŒ^ÿŒXô0"3¼D¬P–`=‰äd9œ4üîÃÙ"Š“sºF.½*ß!!ß ¨|§œØ}À9^! (¨ècBÝ5 å¤îƒ ’üLf‚2(z9:eÏ}:ËMҺѭï+=Kë{Š`©ˆ²cB±ÔždTd]çET;~ˆð™ñºæ§¼î§2Góº b¶…˜ýjh<BBBÂè'ÿA ~‰Pweò¡.@ðî^; (aó«\²LF¡®~‚;êä–¢’^àc §SHNL ­¡Æ¸_Á¢T?žœƒò ÌCÔzF8ÌC*NigMsôã]Byê'·Îh~ÐGŠœ‡ä¬æa‹Æz%¡"'‚ÒJ=!¤¤ d3Ìã$–æÐ|:@ïÍN˜ KÌ~€± ‘Z=#=ˆ“®¿ê˜J3+>“fP²§iÕ£Ó I´Ë h$4’ Ò!”O0(¼ÛßD§ Ÿ5â1"ʆ„šõ³í §>¨Ñߪ $l©—3HNe ²{ÈF5âÞ¹ÙÈ³Q‘9$ûÆéîOm2à=Rô—¯%2Ï(MóaE‚uýîaÅBO‹°çBÔ^ày°žß_ÖÑ!JêÓµï¸Å# ñ¨rxD&å*‡G•#£Z’ádD8Šœ2°ac6w[X yŒÓŽ$sí¬G$”GfËË+Cx²ùõܵV$ÿ:ƒ r).Èî¼Î÷¿vÞUAr ØM K‰~$>备#Ò"®=¬š=Ÿ3¹DÕLŒˆëßé,U³'ßœùçzŠ$?±/³PJû«’[TDUN+B "k;çNaö³ƒrÅP¥v (BÈOj»ƒ‚ú0ÈtÊißëG/ÿqfx6eÏêË﯇¤L¦Ÿ«‡ö•ž­‡öÕž‘øV,˜gáÊþ>§ÚÄÐþnc #·ÔßVTA ŸPôÏ êÌЄ<Ù¨“Í&=S§£S ’Ÿ¦@js)}’éHxt$<:Îww Ó‰‹3Ï ÉÕÝq!î·&ç䥂û·“;$ŒŒÆ“ª)$'NÇeá»bÄcÀšG#ÿï÷W Æ|ÅÑPÂÿÞ í¥5š endstream endobj 4579 0 obj << /Length 2066 /Filter /FlateDecode >> stream xÚÝYY“Û6~Ÿ_Á·¥¦L˜¸xd«¶Ê™ŒÇ޳÷ÅvMq(Èb E*$egòë·Pœ#ñÖny_$ ÐÝ_ß­Ðûä…Þ‹“ï/Ož>ÔKI±È»Üx1ób‘‘rïrí½÷_­˜ôUs­šº],Nügû}YäYWÔ•YøA­Xè^QØXÖ{Õ˜å‡b­ž˜ç Uª¬Uæ%ŒºúxùÓÉùåÉo'X =jH ‡±—ïNÞ ½5¬ÿä…„§‰÷EïÚy"Jà»ôÞžüzZ1BBû°ˆãîˆz ¼8Z¼¸K`’ÇFà›æZ^}Z4ôÕJúÝÕ¶n»+ ¤ËÊ!°"êæ¹ÛZñŽ›®²²o6+ S[À2ó…ôˆFgo“… Ê øIdÄœ/‚˜OŸGÑDÆÐ ˜äDDÕ4ÈhÝ\åõZ9ôž>P&Áå! 9ÅGõ¸h±à0P”“3iJd÷g>„24þª’0îp×U§-î÷nÆ;O¦çI¨èOâ!µâÒÿ½CÔ!®´xMgâó6k̯SQ¿|²øöôTKßîä§QJ&Ðe•>ð ×òɵ`D˜ˆ@Ÿ!I3·ï³&Û9×{Œ’”Æ^@á[Zµ¿/ªƒÔvZÞ3¸:N{ÖsäuqÝhÉCÿvz‰Óàpjo hLRÎç ñ,æ°mÁ!ýc=UzyB«ª­2Þ¼{ýºù3}©áÄBö¾>t–•}pªHŒ”DQ<ãè zΡ,ƒNHvE•ujmÞ–Å”ßzcÉØ`Ehï5‡¹ w.˜†oüè>#?Y¹x%\%¦3ÎÕòÑð>'‚t öÞò\µíì˜C*0çþ:©ó7h£¿ü|þ³¡ù²jBå…ª,º;µ«{«œ±â(B"ÅÌ&šê¿Þ+hÌ à·ßô†ŒÁX£ê‘$|סö-«(KÜÌý¢²ö> •,‚:Xl³â÷X7‡¬@î¾ÝÖ\œ™¯}]TÆÄ%ó»ÚyWÝaÿܱníŸöÏý“UÀó_Ú×>e ô•¥xg¾T槉ºæØf%l…&Ã·Ž¾ º!I «9CZVTEõÉ(Ã^ˆÎ»AzeeåÔnßÝêÐ3wó¢í—À¾4L•ZëÌŽ yªUáX©©_Ì-Qè/ÅLš‚™ úî‰b@|2“¢¬óžó!´Ž¿­„ôÛ ûöÙê!ô×j¢ç^„€%“¸ëRïZ{DçèM£ÔUOÉ” ˆØ–1)¤jÊÃc¨”„³äÑÖÌR:XóVUV«ªîñE³^­¨µ¶âý‰’rVO4”NpJ’˜ÞQUæ¦(\C$+²²½³¬Ìl‘­×–ÜZXn9^p£k Üþ-”Œy3 ¼P3…‚Dcöÿr±hü*~8ÇG‡#Hg2ûÔÞÇpP©÷hí×rªeÔÅ&Ïrô®­ºNÂÑÅô¬‰ÕWò0¨gãtV°¾ŒÏ¯ïÇ(&á˜eO‹J›Ú×¢$8‰©kÅçfÐØé)Ôš†Ÿ£‡^;J“ÿ|Ÿ (‰(xt#|³}B½×iM~™ƒ„Ïøe?Ù}DjHXG”F[^ Z ç’ž ÁÌ^0œ76«Ö¥ZbÃ\æ¶#Útuaº^”XBÕBgœ¼¬ðþÐ7±GQÖEÁ\áÂ0¶CÆXïæ ŠHÍ1?tõÃ~=¶B3Vßï$$Žão ßù¿l2Þ-—b°cô67]ÌØa)IƲ,ÕÌ|]¾xk¹ÒA?ì`ÅVcnmhÖ:çŠÖ–£Ÿ‹¼ß å,ÜhÑûÞ0ëÌÅXÏ/ôIPnP9̆Œãñ»ÌžGDÊA¤¡†XÌBÊ¿V)0ZÖ¬­”ÕEß±3ª <½.›ïˆ|P[Æã^¨Ô¿{È¿œÎ\ß4r-õ166ðêâ{yõâìê ¥{¶’Ò?ûñüë**k ð6¢T%„Ű9iè&ËL½ ’?ï=G’½{{~¡? Æ ûFÎ1ÇCÛw½ÑŽ+Ù„q‡ù¢4GåPŸ–'RŽÎ°–ëήí&ð™5Ö¿8µH£©ÚbÓÁÃõË/õ¶äËX#\[í±y%`^ñ`õGc„‡QZÆ/Ek¹k5¢DŽÓ ‡²1-ž@Í)gc¦‡˜‚ŽOÆÃD§)8Ñ!6…öq±…’d+^kg:ÎÜî•;ùР¢»ôÚ" 4öP¤Ë€Þ¨Ûë²Ö¹ÿFWDU¹¦´0𢂰±ãµó¨bs×X¦újw1ÿ‡Pâþƒpñï>Á¥6éq´©à‘¶ÍözìbçAà¼À‰Ô?«w8kÙ—ªß0ý_ocOÀg•+góìŸ/û)ÎÚ<€Æqg†€µsAÿ Fá0^ endstream endobj 4600 0 obj << /Length 2160 /Filter /FlateDecode >> stream xÚåYmÛ6þ¾¿BßN^¬R¢ÞîÃ}Ë^› ¸k¶ŸÒÀ%zM¬,¹’œmþýÍp¨WË›m·Àµ(‚,%ŠÎ ‡Ï ÝS+Ø‘M®vé©sªAë~ƒ e~Ýa7Ž=ÕíSj Ý´ôTí¨µÂ襓ˆá¸£dA+”)"™h1¼o™Çc´+’ðWÆ!™<ï4&Ov ‚, FƪºF×V5˜˜«Éz¯^CŽ% >Æ&ò”šxh§ï7;Þ¡ ÆÆ=`bt-DFéµoƒ(©Ýóëëë‘cˆ<Šx$_,;ï -HõÇQâE’%^ Z¤Ó:=LÄ; –˜Áý8Iý3ݧ°Œ]»¦)ßô2BµAŽ=Ú¾9àBm˜ï×øÝ@¼ˆ£ À0{ƒëžRÕOXÐt‚f”›b»å©(Ö=Bê259ôŠš7<8>›Ûˆû#†/{M@{K0Ya[«4§o[‹ëØkÂS—ÚÄeKù¡ ͺÂL3I;2“ Xé(ò½é¦ë*SE(erÉ']WåfMów`ghòÛ°V,ðäó¶K)ã…Pkø%bùø2'§2 X(ƒ99•Ï!§“c‡²bŸI@l£ø; II«þ¹œîBÑg3ZáÎ<öéÔ´È«ŸkJ2xòMy~::¯.pU .$£]Z[Hú/6ûªi7&w¨´8ü…Õ¾Ó¼Ózž'dÈÂpž&~¿)ãŒbTA<0ññk;3bš‰$‹ÅÀµ¹y™>¾€©¦O©"á ð|½Çñ7Ðg9Ò¸µ9.86‰X0ô‡åGéEŒC×ïʺ´é‘ü 9ƒ6e¾ :Jféñ­ÞÖ)%šÏc!f“¬ýM­” 6 WÍQK—PT²@ú3þ] eŸ’1f+»#ï~zû¶sõ™çHè$YCh7ÞÍ©K' ºœjôèbžPóf8©)€ðö&4–Hð N\bæ™D÷§—J€K&ÀIˆÃdJ%P°©Ó#(aûZ+¦”È#úv‰fà€‘‘Üoh;#aI_·mªËnf»¯«Ó½Õa¯lUhÅ鬛SÓh]6 ø‚êä7Uq2 ƸvGBO‚ý Ú}•Ût;b5&øL½ü c·ãu¾<ÚX:Z*Û¶6ìÛ}WÛ²7ugdY>“Íb%¼x³‘P²¢{Œqî.J6FÓ« ø›N¯Þ–,-¬¡Ý™»þ±’ÛŒ¢p^çj´Å–„ÎÄb_®a»•(Ñ,¬ÚÞ¹-p¬¹?3%óñ/gcâ@O–³Äˆ‰5äÍæˆüùÜš*t;©koÍ$zÆ™Úl#Ö®VP^è³Åð©¡ËŽ¡‰§»H¡þ …­õ•ñ“úÜ‚oØŠ°$ù[±•ÉÅÎEÊ‚¤ ÷˵ñâKUôˉ*ÇZ—™>BT>¡Jè ֬г/ÔdíA¹kLàÝ(4ÄÉÅPQö±üöö~C·‚¦|…ù/TO@&ñ”aª¢MŸ ˜Ç=št­ÔÀËꛞcYDÏ?‰5H¼_Ö1¡Ý|]nÚ‡vÓX,ÿ¤3õB C(„˜XL&Š¿9 ÓMuìoH.YŸ$@Eú ¹~y:ƒ‰˜Ñ—îš@é‰?žKCN DFdùY\:üÓpé»fD^—/cÆåqì]rY¢ÎFÆ”9ö›3¾´2ÔQ~<¿e£Ñ†5€ÊÙÂ$âÂÊiGÙº£LõÄvéŠ1oNßß (`yJjÂA†Xæ…ZRÉŠº Rc•¨é/©4Ü3UîPÝU4¥Yúmd«²Š8u€#-t>ÔBÜÞf­$w»º¨$z{©4²:](Õ@A,Y0)JX”ÌMz?ŸyÉÖCÉ™Åà“…]0çwH•½ðÙ?Õ._yLë ¶Z‡21gjþÏ÷{ešòÛÚìsÅþ=™y endstream endobj 4621 0 obj << /Length 1622 /Filter /FlateDecode >> stream xÚíYKsÛ6¾ëWðHe" $›SšÔ™$>bõäx40ÉK¤BRVüï»x"XZIœ4Ó´½˜ˆ}aß·q°pðròã|ò䌑 E©ˆD0_qÄ,A,¥Á|\„o¦Uu¥ª²žÎ¢8 Ÿív›<“M^vâ…šF8¼X¸)wª²Ó/÷ùR=¶ïoÕFÉZÙAQ„ÈôrþzòÓ|ò~BÀkš¡ÇA¶\\â` ó¯Œhš³j0‘ÀsœO~Ÿà~‚ö $AIÄ‚˜`„ilc¹È‹Kpãð†/Öy¶(wS‚CI­ÝyrF“žŽ„"–Ä`ÀϬä«"or¹±ƒ¬RKUÇå®ÓÕù6|Ìà ^b”ÒÈ«´_Ê8w«Æt‚.ÖÓE#„ãÔirù{ìɃDL¤mŒØ†q¾Ï2U×1ßm†g‰o«çõ¾*¾‰ÇotéË“ë~†UY¹•KeB fvšs§ç×9’4 Wû"sEqX©÷:=ÈB]7nÍ›ÏÝâ)ƒtWv ûÌ»ÚÀýÚ¨}ShBô"Š" 1ñ6¦l“ƒàHAF ñ¤]µ¯óbíì;‹VÎLݘ}™RÞÙ F Nµ¾Ž8¢k1I;²ÒZÖ‹u×È«‡˜@wËÑtF‰_­Æ43/na^,š›fQëT‡·y¦F”Ï!(!òEPÊ…“5iŽÃz§²ü¦L-5ÆæýÒ®ØÉªÖÑF< ¥›“î“® (²|gÏnr«ì×w˜ãCÞ\ÛùæÚMWJn¶ÎĺÐ; ‰Ó_,í—½3;“=ynä½׮°ô'› «ñ©©gìv†Û)aµUxÈ ÔBñ;ã2K[ÍLÔ¸„úÔE¤W ÝÃn#±‰ Ù‰ˆÎ"¤’jT$¨àˆþeòíË!«€«’épø¦ºü5.¨)„³Ðg‘}`e­aYÏÊͦÌ,eÌõèÙÀWG%Ò> ­æ`߇­Î¤aÎj78mÆuSí3,³c7Št™#3øËaãNš¸½²‡¸áÐRÁ{«ªÒ^V M¤ìq1(ÇÝ©±»¦ºÝ²;Õn“=r¼ä8A"!­¸®j—ÄÃQD=g²àF³þ‡æ`sÇøˆn ÀÄÃÍã/ó‡Rxõ=ZO™® Ò/*@WTzú”£iŠ’# ?z»;²¯Ð¼¤ ëm+9É÷ŸÚ0á@§g¥‘c'À0¹õÔyûGÿØØØÝ…cüaŒ@8¨ŽÓAGós~UI{öïúJLŠ\üž§N‹GÚå¾¹l› ÓŒ˜§)Ð\40ÿ‹© ¥ƒßDYT2I³Þ™Sª>«¹*(½·Kyho=¼·šy-ÖS;:ÕŸ ÝÑHCCû €q¿¡Q;k)^v•Zé$·¦ qÁüÁlŠkŒDiŸ9²qÂÒi=& #ɲŽtœƒµ¹P4Žx´c`[m×dh=vÔÚ  å¼ó¸up+]Û3ÂŽû–Ë•+rw#óÂ+<ÝÆPþÑ 8`1^±wU)¥µí°õžúËX«'Ü­º–©JƒÚ!qڕõrNÚ.çHÎ…³·) ë£k{ ù¥´=‹}}zy¯ì„òøûL{è}ø ¶F÷SoÛZÂuÝâ­.ð2_Ú öÈ`3þ1rí¥ÑãVè|Â_‡ZɃ¹•}Ü:N­piǘ~uj¥nò€æ–ZÉ÷F­'˜•šõ¾õ_?B¤÷á•ç@Ìcߣså„¥ËFÜÁþúSjº×B¿ý%£¿b%ëfwJ.×µ‡[oÍ÷*ïýÐÕšàá³sø:·žôª*·_ æþÑ7=eönµÑ±œë4*bÿãå§ãå,-‹`¤aó …Û‹H}Úkkö„7Œ!ã#zï›¾Ô ÛŒ Nøß€â ÄG ž5L'ÿ5±ãÖß{fÉ3&(|x;›ÆXã„:·3cÅñ±L%лŠë­«3;üß×?q~ò¿.FÿóÂ"Dˆ “ °KáókiØaêº{  —ÁÒð¹&î6ª]`¿[†Y9 ø[d~'þì·Wî4s½‚—¥lôJÙÜíT= ôO&…hö endstream endobj 4633 0 obj << /Length 1603 /Filter /FlateDecode >> stream xÚÝYK“ÓF¾ûWè(Sh˜§• R$­ÊP.Ùïªe!Él–_Ÿî™ÑÓ‚Ýd—Àæâ‘ZRO÷×Ý_ÏŒ©wîQïÙâdzţ§’y IBzg;Ç’p‘x‘Œ‰L„w¶õÞú/—\ùºZëêP/Åþã²Ì³MÚd‡Â žè%§þÇ%ƒóC©++~v̶ú¡½~­sÖÚÞ0Â9aËwg/?Ÿ->,ØC=æE¦–$¢‘·Ù/Þ¾£Þä/J‚¶QBñš $IBâ°3ïxõðvöAV‡É9u4 ¢þST*egʇ¬®g`…âdP¤=ªl6þ× U ´R„$wˆ¹Õ^¦Uº©÷8# ‹¼€Á¨\6½ÍŠw•ŠbVBݸl¹(ID¾À¾þkÙ¦>ÜÔ&bHÔ?nšc¥÷#;ž€EfœÌoðf1!%QÌ'V¼BŠ;æyÐh;û>+ÒFoJ”)¿J1ŽWÎÍ]?]7Õ?`¡ ×D$¤¾`$þw*6YiËä6ëTIÈÛÅEZ¸—WeZ×—ƒCµ]•¦Ý(¿´ì CŽNãÐÒ^#àØÓÞ ”C¥ÁXé EôËÛ¯¿õï’WÐc‡`‹^9» ¡7²øn†ý§óYßBI¢(ºû0a38va÷”] îA ¤?ÃôÿŒ) Ê8 oB2.câAݦôðˆÐ½gÊ3¼ÚÚÕYHò‘•vIË•ìëO ¿•™cE¸_wnéoõ'Iyƒ‹A)ýç}²9Mu°K*á_ö¶Ë6;ѸQ mÄ‚0™c?ÏòÜ~[étãf°î ·š—à)|úW ¯m0r×>uÇÀT3|³"XHqélnwKIí½_äß¿œÖ­Û‹¦ÑC]_ŠÝíc†æÛvõ«¿áòÑü^•º=>K1¹ìO.0òy~À,¾QºÎµ•êbcá¾j)ÙÊQ_m•dNÔ³:Üœ°:ȾƒÕ¢îq˜;£€BRßùEøuS!ÞÑ5G©LuÇ£:HýƒÖb7Ü‘#§ÁÆqüÅ*×Åys1×}bö4~g݇‡„YÁ…m/7ê>á7î>|:¿6Ó³yz+“é‘Êã/µºRyéê\QWç3Ö9õŸécëF!§4pš˜¶Ç_ìÛ­q§Ç2"‚uÛzêRŠNŠhú˜’@´7þÿköß,É c."P Ð/C™˜úqÿßýöÜd¿„RÁÝ“3TDSÃþ Ð endstream endobj 4653 0 obj << /Length 2348 /Filter /FlateDecode >> stream xÚÕYYoÛH~÷¯àÛR«Óϼe3ëAf{$ö!Õ²–H…¤âxýVu5)6Å8Nì—“죮®úªºÄƒÛ€¿]üõúâÕU$‚œå‰L‚ëMÊ 2å*¸^Ã?2u³ÒMÝ.–2ÍÂ7‡ÃΔEgêŠ~Õ ÉÃ/  wõA74üÛѬõ%½¿×;]´š>“’‰Å§ëß/þv}ñùB€(<Ä:b)OƒrññÖ0þ{À™Ê³àÞ®ÚQ’Ás|¸ø÷wjp&@zÎd¢pu"‚&ÎßKaÁW))|׬â›ÛÅRðP/â°»1•énJP Ô[·7õÁ޶4iUÿz04}S»Ýª(ñãn±Œ—ôø`—Ó{v‹dz{=qþœˆ©ú§éL±sËœHº:Õ‡%ÚŒ²‚åqL:!í–Y‹&L'y†öI#øe ™n:¦{u•$#» Yã‘ÙtÓ »ÔÍMY¯µÇïÕzdu ÎátÆ6׃­ÉÎhd°0Zh°ìIâ- rä'bÿå1'Ö?«Z̤žle]uÖ¿¿v­T6Þ±LDýNܤ*¿v—Ïhé{‡ê5©P´“£‚8GÅáÇäÍs–)¼¿€ÉŸ+¨£H‚&c×°ŽŽ¢ Aw7›cU>&¢€ØÌŒz›®Qb„0lmÖÖÝ—ý*Ï@¿¬‹®˜óÁ2•ÜEÌGÆwž@UU—yjm³ú¹Èˆú¡hнG>°Ó©/êGS}"½Èi:Ýw0P3Í{Ñ—´åïfÕº<|±žçô÷$uT–"e¹’S Ðox8Ç])X¯&Üÿy°èB­u9’åXvÇFÏñwtˆ¿:³Àj†µ¿Ê² ë·Î‘€Ù 7Y áêH|ƒ+øŠÅübNïœq}—9œh{Ü"“[f1Ëä„åݹåNÝ3:]MÏF—ÚX?×4p(ÚöÞú}³v4ªþ¥,ëcå(ÓÑC¼õI‰š½þF ˜Ä°EÓÔ÷ŽÙ3Vù€“÷fIHäy¸Bq¹ÍZªÔ;ÔO¯iÙÐ+=ÔÕóƃ?y€’[KEã(·Ç²Ôm»9îÆûŠò3zîÒÅš-–J$áõÖí𭌫Oòúv†ÅݶwÛ±]Tš1‘ª1ºRÂÄ6K•å,N" 7M½‘²,ì fª[úÜ×~ÑáºÅçò%Y¥½<'°óÊ d@ ÏE-íöˆåœvœîM·íyš–ÞÞü룷ë^èFï È6½ØcªnS»­»œcÅ„H|Ä[9Ÿ6€Tˆqxht§{wvx²YDH»]§sgݾ&¢ž—ºÐz·™1SÆT4¤8ÓÞì€6âÛ e£Ï36‹b–äùi¸I*XÚVd)žJ…3‚—üñë[ziôaðLX€¾³þ³VÀÉeìí0Q7Úq»ßšméóXû•¹=ÖÇvLØTk,Å{ÂN1A œ:aUˆXRð(:¯1¿Êd(RLÅ­¨QbyUw[ 7©léõnãö€+i·ä Š\쎚>íAÚ#†ªvLàü[°ƒ£N"1—‘{Àì¡u­ÓÁò‰+#YÑV$·—3›ÝA¶(¼²Ø@´œd<Ü×¾œ«˜8Wuµü\}fü*Â’LöNâ ÎÑ*ðíêÙöçN¹!M‡ŒæâÅ2íC£+5+?&œhíñöÖÞÍÈ— wsgBx±nI#…Ÿ|è$È.žG¬M{بσEÇ5s­8‹ó'ÄTe"Ê0øRŸ’-ŸŠɃZ >b ¾s†1Dn4Õùð΂3¸yú™ ¹¢!T,CNŸÈ3<adþ GHXÆå9s$=KævÃÜN'£ TéjkˆH¥Ô‘Jõô`ÐG œªšqÖ»$ý(§EÆÑ¬jG{*ò@±ììðvë ³pÎj¨T/‘Q9h‡€0qÆ)᤟Ðqd”r&Á õAWXLôàiÝ[—fí\ý~«(Œ °±ÿ£æ¼›«¸¦±ÅÑFaóT î,^)ŠÏ™Ê#cqœœ®@óµX"‡Z`?-•C5_Žá„FA©þ©ÜÒ =½ ¨³D+¯ì¢ÊÚM¯“ÛrW¬÷¦zEY­¨¼÷4Ù:@þbÊ“¸ö 6Ö=©Ú‰å‘pé  &›\#oyç€Ð´°Ddž Ë_ðnÝöµ8fŸÖ¬ÌÎt¾›'»šõ™ç ¨ú}ç_áæ‘ÙôÕü¶—»,Zí—õÓžšB€‚rfÒSËód¶§6ÞË¢< ±ƒo=¶&!™M)ÄG1`Û3H Pë ¸P?Q>îmzWÀ4·¼‚Ô»‹Í)^ÜЯç’QÂ’¡â‡›[gOB$©mâ‰$;ž¦ñÉEVPMstj855 ¹[ •űu4\gÛk‰]K-*np³-¢,‹š ’ZÓˆço6TH)/Ržä‚­ïö§è‚Šã€U> stream xÚíXKsÛ6¾ëWðHe" LNy9“ºÓ6²:=$ MA6'²¨TœþûîbA†¤hűÝL½ îãÛÅî'pïÂãޛɋÅäÉI(¼„%:ÐÞbíqÈ™xQ³0‘Þbå½÷O§òMynÊ¢šÎ‚(öŸïv›fo’°X·Qx?¦C ¦Wí×ÞÌíë©ÏðýeZÒÖø”>²á²¯o Y1èNÄÄxv~g”°™Œ"%¤&X*b’¾KËôª'Þ³¯£¾CïóíÇÖûÚ–}Šö0Èœ%Q[÷fôɯùyi±àþß]!6úÎÿž¥NÊLD,‘rhÆŽûcÚ¥´ûûÚßÙ>¦Çí¿AÏ£Ô°ƒˆõsE3-ãâ—pTÛjƒN7Rè±êCÉB8;\‡93u…å,ðk*vA·T•ÊÀOiÈ:Úìó7möOál/ÜWNŠ‹‹+® ,Ï0¸ŸðÇÔn­ qWµÉê¾€Nå!}Š1þ¸ê‘UÐî}Õšƒ>ŽTë“iı €1 B m(²ÂAêrÈl+€…µ:á|‹6”@R$²™Š¸KBëðpV0Ip±}e3*$…]Ƈ~?–Ÿ1£ÿév3''œwgû,3UõŒžN-k¯_ìP§,‹Ò-ÐQ)æ×yeˆþÌ´b¡ ûF-ÎI¬c³)01®‰´(ÒÜù¿7NIÚôA÷"_=ø×ÃDh‚Ã?ŒI›Ð§ójÙ ôrþúÝŸoç¯_õÀš[f0hÕ‡ùÑtõn£¾_ŸÆ&•@…¹G·F£í¹†•´\¥ç4PKë mãÖŽÓi`.Ûª³JlJ#“<"®,Ìm‹·cÓâáá Åƒ¢b7zur¤é:hå–®ùŠŽy¯mœñPݪmåuãÚÈ-‡:ÿ«}ûnÔÈmB¾­»gÓg{Önô6Æÿ‹ÑÃw¯8b:V> stream xÚÍZ]\· }Ÿ_¡Ç¶‰¤(0än´@û¡í®3Œ;Åz $ÿ¾‡šÑ¬w'Û‘·wo ^ÞJ:"%’w¤(…(Y¤(‡F2‡LìÏ2þ—R JBmÅm¡PuÁ‚všCK¼@Á$ù'˜'Us QvõZBæ¢.iÈb>²%,þp…P}å–C®ÐÈ…âà€,W#_j]Í,d; (H5g_µµ@Ò×jÀ_¬È*û|†¶!þ§¾=Àá,¾†•ÀÔ|¦Ørîz5pñù4åÀŠaDP«,þAÂîˆ,pË] ó¶âp\°æacó`Ió”ðON}PVÅÖEú¼9, »«þ¨p´âc3P[ó™±bÉ€©Â5*Hp’Ö P  ¾të ûÿœàú¢p=>—a5îgÅ9€ÓL 88¸ V©X€$h–¾‰”ª! *}ÿPÖR:5sè°Ž6üƒYRPS_û„¯aM1â»æ©å ax% ¸ 0 ­œº–BLÒ ¡õ¹ð¥aæ*ê0KêÀ¡VÄA U«ÛH µîTÁRæ‡D¡ev»arìÙ7(54I>´Ò¼8AŽÎhÍajÁXSXÃRÊX¢H@ƒÁ/„bAËîxÅÙ¶¬n@Íq⺙¨ëa"Læè b—Àp¹ãôû™¥Í‹›í7á ‡=á>¶ÿÇ?a@ì¶Æ†;~ýñçŸßl¾øâEø3QôÍ^T”ª˜qB‘Z‹ ^º¬¨‰(¾Ü_߆/Âö¥¦ “÷!/ý˜fxõð›âfòøNüIÆŒF‰ŽOŽÜOõñ»âš‡',¸ýîfÿîÕî6\…íwß¼ Û×»_nà Ëë_ÿ½ÃoÜm¶_×îúöƒßIóñ›í÷»û7ïvý³zøìo»Þ¿ýjÿK¸ò½úÍEäzƒ…ÞÞ`´GÍrPüòúzÙ®ÕñôˆzàÀ£@Cà!ÈÊFy€ºÏ¿Ù¾úø¯Ûþü×÷×?m¶_ío~ØÝtléÍö/Ûo·__åþàÛyCÔܧ À±ø€ï÷׊8°t³.„Dcö@rD‚@ç` ,åhÆÁ®|gœN\ZÓ&%G¿í1g·I‰ÒO?a[Ó&ÌÍYg@i·”9(¦º\舰|BªÄA©³FiÏàŸqR@鱿ƒ¿´]8³Më‚î‘ D6øß¦} ’»k›ä—{ŠàºËJ¸Û vº¨(‚m\VÌ=…™ã–IÆ8ã{œô) =•[4¥sn±ötniƒ%ZÂ`›6ØÆÛØ`lcƒmlÌc:„ú ´P=ÈŸh'qdË+†Ø#äåQµÞÅzB¬ÏeÍXo鄃¥Æâ¹õ Ž…#=Øj=Aqæyë ”fyqßdÓ˜HO¾A•[“5}Ó(/Á4ÈØ‘ JFB»®o`F…3HFX®u É¢|#b‘½YpR2þvßL˜ÿ-ï›@^ÁãpTdØD)’]tŽÑ’‡`d9AA% [ДfmÉlÀ—œ.Žˆ'­³Ê—.Ž%f“ÉÀ=E„s–˜ËŒbj‘ë„"ˆ?zaY‘,:y]T$•G ⇊ÜÎ âÇRŒ‰ÃtÂñiŠñ䤂òYRáM§&Þ­ê9€7«ŽB ‡P† C¨ChÏ‘BpéþìPÄÏ«2w‹Þ¾H¸xDjsH–æn†üq@<3ŽÓ¤QlÉržbõ©Ò+Q%ü媱š¬[ºf„?=AÆI©2eQ£,¥Íß¿[Bè«@Iw¡|Â¥vúÎuÕ”FÀÉÃëÈ$` ñZzÊ¢Þau·ØÉ=Ègb²CŽcdŸÕâpñ~ÿmÞWDk É•L(‰Þ!¼¨(Ø’¿Ð¸¨èÉ­ŠÒæ™âçÐæÿO×W™ÏI”óÓI”Ž¥µ¿@9 ƒ i$µ! Æå´$eöþ¡Ýu{% |“g»½ Þ5¡SùIo'Ú\¤%ë‹-±¿";ôñÜ_éÊ&Îñ>&¥|rŽPE2ok"A ª†ªÒä€ÏGš‘¥ã®®™EôãÀ!—‘€È_U#›i´æqEí]²C*|TÊ$á3j`š¤†{Š´WÏ”k¯>TDFŽËÄ—‹_Ó™ùÍ·†gŠNï+sñdmbBƵ™™º··.*fD€lõ)õÞ­ðî×"õ^ù ª*ÿUÉ(êdu2ÈKyÉà,œ%ƒ³JzŽ”H IÛ]§¸1Âõš/㸿gÒ Þƒë­Ù+üçÆ•×nv(Žü-Ou£ˆÿô²f™wB"¨¥üM¥7q~Ôû4—铟¡¶’^ŒßÕV Æ_µ¶BÄ*ä¿Rò—åÀ㈄”Gòʵ•ENt‚R‹û¯O¦ ,|Np}éä¿; Ñš@@àÐÏ{gÛƒu™%Ð2C ”ÔÒ¢|Y‘Q¨Ô E.1§²ÞûÉ'“I=#©:ùFRë9™”A :š‡:š‡:èE½è µ‘®òÚ)6§¼*™hTd!š âdé=)ÿIªÃÕ{†J¢Øü× ^ùˆÿÞ4hýöW‹µÝyGPiÓß¡=ÆþN¦í1Iì¹ã¼wþ Ta endstream endobj 4693 0 obj << /Length 1738 /Filter /FlateDecode >> stream xÚíYÝsÔ6¿¿Âw 6’%õÒÂ@;-…¼“q|JNƒÏvý‘ÿ¾»ZÙgû|!˜>Àd&’VÒj÷'i÷gs®æ¼Xýz¶zò\r'ñ’гK'òHÆžL„s¶uÞ­ÿØøÁZÕª.›ëGñúiUå:K[]$øMm|¶¾Þp˜—•ªIü¢Ó[õ˜êoT®ÒFQƒ{¾ïñ͇³W«ßÏVÿ®8˜ÂNKK/b‘“íWï>0g òWóD;7fÔÞ‘a eî¼]ý³bÖ æq°žy~(ptÈ:Ž„oN9Ì™ÇDD¬/‚ó«ËÙZm‚u{® ÝžgืmÎËÊH›¾ó<ËÒlg]s©xk:©žZ”tªÎŠ{…ªhuš[ÙA‘féQÿÂ2ö¢ñ ¢$4>‹ÑÿH‡Í\Ðþ:{„Àê¦sЦÃѬ?z(¾ËP7޽(Š—s/ ìÞ=¬¿ÒP¸±aL¡ƒ]CËvêNä„Ç> ‡sÀ‡ÅÝö#ùÉh³ùò‰þL ZÅ!ChÄpœ“ö*­ÓýD½cºgȽÓŸg³{qŽÊÜKæ%Ñ`ºKSþÔuŠÁ­oÇJÌÁ±þO,µZ\y‰s p÷ÙziuK8PTßÛù×NTèù"Mºï-0¨áýdzÄ&8w z»0e €½Zà8[Røþz¯Èÿ´Ð;Á-KáÙÞô£YAøÂî.É(¬eá6*ëÈ1ÝÞ¢‘®¥Šré5^?;œV*u¦mŒ0m¨Ôƒ¡¨æZ—]C+Ïì^p.m[µÇ knÀÍNÓRÔlL/áR[“íèñ7=T¶ý]ªÒ¦Q[·—NKŸüñCºùƒ0>'XðÛ…s‚%?C° mšÔåCæHì-þ í(M„R¿,?ñB>D3Záé¹™zÊ=Îïë ÷½8úRO¾’*Ê(ôdø ªXvíÀEL犞+ŠXR ¥øõ9é3²^‹4À¡h Š§æ”•»tR¿'u ¿3u!ºÄ ߘ;ò“GùÈ£øIä1þöä1€OÕä'y> stream xÚÍYYsœ8~Ÿ_Á#¤‚¢ƒs÷É9+Ù­¬ÏÖ>$©)f†±)3@€‰íýõÛ­cÀøˆoR.[¢R_úú“Ì­c‹[ofÏç³g¯=aÅ,d`Í7–Œ<&Ul…^ļXYóµõÉþѾÖË´.Ç•adTUž­’6+ ¼LÉíoŽ€yY¥5‰ßì²uú”úÓìƒZ«²hµÏÛ‘A*êç±HìõÀRŒÎyûôaú(…Ý¡£C*úªx—¡(¾IQ7ŠX†–+‹}½'àí* ;ˆý¢Ë²„½_Üè¶Ejïpˆ3Æ{"ÎJ0_É^˜Åt6ßÒ¬ªï ,£\ ÎÍ^%u²Loé×#Ÿ}ÊŠ/°Õ|n¢ @xnRth"gqwª»ôÉŸÙ²Nôf·/ú“è”1ö45³¸"d±Rc 0îÜžZóçÒÁfõ¿*„ð†2¤ËnÕîêtj}3Ï5ë׸|?xã½!!ã†:üs’VÕôЖfÀR˜ 6;å±&Ô:1Èó òÐhóqQjÃA7.ü%%-÷vã¸J 0f õÊŠ ö; Ô+%PQ{E'žeyŽ=~‰Î(N¨é©ê~|õáïWG˜szY%î:iÍȬM·Ô£Øc}ÍÚQôÂLÙœfÅqgƒYGW-)Í×™v&º›4 ÈþËê†ä²0Ð.Ó‚ÁÛ„^V” Ù·,O50¯[“%Ùr×ÙŠ"Õæ3WPƒ´›—æ¢r,Gðé)þIÍâÉ®=)Í”ÿîYE`£{˜ãzBÙÏ/hè:Ý &É.Ç8]Á©_M\¾¡v›¬Óß^1›·½¨€Èä£ujU¡Ce:dìõ–&,ùOè¦TÍ6¦5Ÿ7»ª*çšýòÛ®Dã®þ¨s%¸’çË1WònáJš ¶5Î¥$“ža@ïчÄ=Òß&v²ŒY öXöž¸Ôž³ÎÔÂ6ôïj ˆHúßkÊiŸEГò^´ä˜»‹<Óœ/TÔBié1$ê L‹¶G›f_ÚЙášY’ÓC·6~×ÉH „íi"7ŠÔˆž}Ct)³5Åt@Å$0`Ï¿«{fOq±˜Iñ˜\ìaÌ'ŽYìÕ{ÊS‘Bà&ÜD'èɘ€9©ˆý¤çgmÔÓnwô¿_äiqÜžL„Dx‹~×K‚s6»bė§Ub:Ë”Ú]“®©§ë(´tuÀíãbÇí-½Bº¶5™ŽgZ=|ÂÏ > õˆ·´-Ufè_â+*TwØÚàÞRæøŒoÊí2+úSfäð10x¤W™ÂÊ&É[D@½éˆkêÜöi•t¤¿s­:PÎMÑýn7ê5<Ï’en.o\j.k\dødd'5¤/²'&šè'ÇÔÏŠ®Ý×¾h¢öE¿Fí+(+æ_–ªSøÄ#W¾qI)õùã:CÅx<Êù;’XIàxÛñ±ï>ÿìÓ/â4ÒfHßÃ3pÜ¿§š:÷@ɨvRîrƒËôš8ÝÀù<~H¸À‡3(‡ÎŠA¨ „fÐ'T‚«7“ô¾?üê½ânZ€­™]‡n;à€‡+À²_8j0I;g9"úÞ¯M™ƒÇ¥Ìë4o“µð"EÁå%aAgNq ­»êXO2®ÔÇ+O€þ\þ¿xu¨ïÔª{·e“\އûL2±Õ87±Œ`¡ê¡¹òÒ|=…{ì ½[®ýáàöúP ã1‘žã]ÐøZH_šõ•‹¹éb­A ïë«w#€zwþ7Òôí€d`8é0`anàÅ:YÍ¿ÁßjJèÁ9³À˜å‰±bÿ~‹Ð¨ endstream endobj 4737 0 obj << /Length 1735 /Filter /FlateDecode >> stream xÚåYßs›F~×_Á#òD—û ô-ušLÓLš&îô!Éh°„mÆP@qüßw÷î@€ìDJ;™ŽgÜÁÞîw{ß·w¦ÞµG½—“Ÿ/&O_HæE$Ò\{W^À½@†DF»Xzüߦ\ùIy™”y5ñ ôŸÅ*]Äušg¶áy2åÔÿ-ã:IˆP¥¢N>°ñ¤à VE4)(‰¨±ÐZ/â2^÷Ì{¦{î‡4ûd¶ihsi˜B8DëúÌ~ò:½,c$êßw˜Ürñ÷¤[-DgûŒ£§—'¡8 #ìÏù7ÊÓ-[Ìúƒ+ÂÄPß›ÅÚ’1®¤YQéñÿ+ÔÖÁ׆Çë:Í®G+çfyºÍË]Zߨ»Ø^ЏªîÌ"+—X’„ÊöŽ8ð. Ûq\ç¦J–®ÊÏÝ ÀÂU6V[vöÝQû;·n±ž0<~? ”O¦3É`wn .ëxµÂØïÓiÕcm‘rôǹýp~~YÇi†NcëU™¯m»q›>R!K³íùíù¹í)“©pB2ÿrãìß™9Á÷í WnÝ5Àá{°Ž‘v}C½øE9 ]g¼õi±JQ‹ÍËëØâb:²ÄF"Áæ­6EÑâye§ IË$·Ó .QÌiÕ/O‘?Zïb FÂoÚoÖ·õ|•^M‘VÜmxä’© Úþæ{£ɉ÷ÿ‚œ9 ’1"†mÄi%ZÓÔ©5­Û2YÕñA/ À !ÿÜGMN!]`ÊaÇÄéÅ ¦Jƒ¨ýØâÖbG솛?¶Ýç;'.Åai¯¥yÇC͘UyÃÌ"M"H—¯á+I¦B^ö¨åe‡:ÐCÕÈa«=…µ†°³*ã:â1Â4R©ÙÿꈪeºƒÜªÛºîÌy¬+Àaœ¢L³EZ@*:cZ“GýŠÈ–OÚc—¦Ò1x»³~qxT øƒóA &Q×N5pªËùÕâàlÑ[t (ÞŠº9O3Õ2‹ ¨ϗ#‡lG†ƒÙÏôQ²cq]> stream xÚÝY[sÓ8~ϯð£ÍaI¾Î>õJ—Pºm€ÝŽÇµ•Ä[ǶC`ý]|Û)°åa_ ’¥£ï\õÕÔVš©MŽ“/-¬ùÈwˆ£-–ñ,D¨¯¹–‡,Ÿj‹Xû¨¿6ˆ­³â–yiL‰ëéGÛmšDa•䙜8e1õ/†…i¾e…œ>Û%1{._±”…%“ŒAظYü>™-&Ÿ'ð˜Ö\G[È5]-ÚL>Þ˜Z ó¿k&¢¾§íŪf9üŸjד?&fW‡vtÁØC±4›È¤®Ôåc’ÝÛÔã°2¦ØÔCŽâÅKêu¶R™¦rÅž©ÜpYä›m%TƒQ¦émqµïJVÆT ›bù” a” EQU²a#`Š<Š`ü`¾^Œök–É_U¢ Á?¬’s·,Ê7¬”ƒ/Ü™ašÄrøÉ´MSþ\–©çJ½,7¨­ïá3ÓIa’:Ñ¡NITwUP²âK©äúÈõ‡*] ÓB¾G‚kóe-9©’0U.(XÌ2>.[ej.ÞÍç÷¡WÇ߃þÎVIä[s{æY9¢G‘å¹ ÎÇÑ)¶¬&h‡ÿbÓFV; iÁq1N9sT&Ȳº!Méúý(üD°ÙÛ;TÉL‹U”\•å`[﨩Ü×ý]GÍÎ/ÞT;š×†5èAè†/7«Ý¬ü¤p^_ÛÁëÓ“àÝÅÕìȰmýä•„pfY®²,ʳ*ŒÔ €¿Élɰ‚}æ>ÜAb‚‹ëé0Ý<½:—\ÇÔß-^/ ×ÔÎç³S áŒe*¡˜¨ÒǦaµæáÜT}¡wH’î öhÄäGÏÏùqo¯ƒË§ç‹+Wº°,÷¼^åEkŸ®ªdëR¥Ý–›úÉí æ¿ N8⣋ ¯ßÎ Ž~?3¦udè@é×+9.X™§2ÊAÆ']=c•ÒëN® ã¸àÙ'¾6áÄ"Èø’$“‡ñ Æ)ÆÈ·mUK~I´ñÜ™]]¯g³?/rÜ:Tµœñé¯Û¤øÞjcëØ€³N!ÄÞˆL_Ô©>w“”›°Š¸…×OóäÕåýünS·œ`\ISé5ê8:¥~)¹åQ}+Û„XŽZ¯Àà>ûø9.m”(x¸ƒáf‘àÅxâÙé“¥<"cœ…ò®ûf¸6·žEɸõ€ÆSÒÊhh;\ñðÃsmÞÎx=¹å–EÉ'“Z,ævô!ô*ù¥^± ‹²¶J¨æÂÚd’mdQ²ÁÊ‘Ü~qV¿O HÁˆèÀB¤ˆ =ˆãÝgòâ_e9¼è'S%fWÖd«¾l¸PÙô ؆<®Ù;ÈÏßí‡ïRÄ>)Ù`K¿[›®D+X„£'÷JÊV $«Âà(‡ÝÖ (S“WgÃnÈÅÈS­ñ]q €À P €HæMUÏ>­ûxþ±H:¿ü˜/_í1”ëöq` g "I;È­•Áȯï‘áa‡¨ 94_ŽÔr8)´ì9h eŠ:vGMVÈ$+^ŒµÝ%ÝV„›M)’6bÂ6K¸TNÙýÎÐñš ¶ï¥ÄF&„,`C>!uq/Â>WÕ¤>öú% mä¥Î"¤ÆêˆvýA?On‹¦xv„Ã=%()ý§„|WÝ4լܳ_²1|¹¡Ù4.P&òÎ Ó ¿QÙÄ‹YX¥a§Sk<Ú®…|ßÿ¯ž¼'{yøS@îÞ–Ê7¥°ª_ò”¿3EÿG¸¤…Û!G²äÝ‹ÄCÄn=óÛ¿Y]ªuXÕqÛmøPÖñÝ–vÑlïÓ)fñ:PœtËS§¦ ©F¶KZ:(Iuëºý¸Z¬ÙØQ°Â#?o‡MØyÕ©{©eÁj:¡XJ×.A!Ÿ½ù=ÐR‘Ú«œÙRª_36؆ÖÎ20ôÑåùÙáQ•‚UÐ/•ý›tøÒ7qýÐ~øÇa„±²½ƒ0èãX¾¸¦Ô '÷–e;¢+£Ztì_Èpÿ¦ endstream endobj 4768 0 obj << /Length 1673 /Filter /FlateDecode >> stream xÚíYÝsÛ6 ÷_¡·I½Š¡ø¡í)M“.M×e‰»Þ®íùTYNtu$M’“ö¿HP²¤ØnÚ´[ﲋ" ü‹ZµžMžL'{G³"ùÌ·¦ +`V B""nMçÖûÄaÒN«÷iUÔŽË‚ÐÞ/Ëe–ÄMVä8ñ4uµ¯6.‹2­púÙ*›§q|–.Ó¸NñÅ#ŒÏy7}>9œNþžx µ<YU@èì}X`> BÄy½Ã‚‘QÍhØUP~ ¨¾¸B†]*ègÞÏþà êäÜÒ£Ôešdo)é\!MQÑàJ»y fÒÆ„L/†)\EÏMÖ\ªíË~5¨Òxy…ÃÒ´;š³ogyöÖQ¦×ã|ŽƒUšQ\ØÕ·"8ÝŠpبåúnQB‹KHx“Õ`Co½½Éå´S6.ÑUœ·wîÛc˜7.™ñb¥ é6ô¢ãxa’Æèbµ4(BÀ Ú*&UšsÊeœ´{²|“»DÐÛG]¼ ªµ‘—0NB&×>x¿Î„y!°»[ý^¼Ìæqs×ÎdL²©™¨Ç‰¹aÝ¢|§NÃÿ–Æ5*¸«×`’Hýßküð½Æwh54ä>¼^ð?P5ËCë5þT8µá‹» ö°» þ໌ñ7/HØÌ¿ó'¯°#žgKÐËÜ·.cüÕVi¡íC)ë‹È>0Ÿ©–i»¡ÿ?ãÂP¨Ž:IпzÜþ‘h ^¿ú¨Õ}Ùé+úBÖà endstream endobj 4676 0 obj << /Type /ObjStm /N 100 /First 974 /Length 2058 /Filter /FlateDecode >> stream xÚíZM·½Ï¯à1ÎÃú"‹€`À¶ $@–Žy1v‚Õ pþ}^q†;Þ‘7Ó^·Gù$¡º§H««^u·Öj©$­µ&¡%nB£¤¤¸hIÍâ'í–Ø)™ I†_Ù-UбMSµ¾Á$žZ‰i;'ך'*ÚCê‰Èc¼¬É%ÒÊ!I¢Z($MÔ†I˜Ÿ<̨Æ… +¸'&c{bî1¢—Ä*cYØm0‚ãÇZbÙ°¼*Æwà1[ÇUã¸5ö{à6j°1HNu=æèà!MK8àjûÇêM=¿Íx¬5ó+¦ 0Bšα/ůÝö\z¦9IlÁ ¤FÎÔ÷žt±°#߇Ú0bïqœ÷@$–L¾µµÔ‰q"šyêk âÍ“'›íËüý*m¿¸¾ÞÝn¶/>üåv\ÿñÝõß6Û/w7ß]ݼ*8ñåõö÷Û?l¿zEãb³ýúêímz¥¢¹ëÒ%ÇÉ7‘<Ð]$÷Ö ÷Ezò$m_¤íïv/wiû4ýæ=F¾Û]ÿ6÷Ú?KŸ¾Áß_n‰Ô–;ð"­ç†¬€#“K@XX³¤®hI)™j%ŽŽq®6yøŠ~–OžÂÅA,éë´ýæÏß&dY $;pýáûï_?¬ç‡3€x^O83\vVQ¥fFÏ+RÉQÎ*2×ÜúEòž‹lúÙîúv¸ò™Žâãû!Ï"åÏþ*’a{‡ßpB™s¶²ÚüÍBóîJãJÇÜ>¿Ù½}q…§íó§ÏÒöåÕ·éõ}Ì<ó׫Íö+Øuu}û>JÀX7 ñ~÷áæíÕ¸Gû{ºúîÝ›/w?¤¦ŠÞ:ÏßÜ`t”>Û+$¾Ç£.†=£,î/S )Èt 6…:…9Ïyú~ž×ë‚F¹ á"Œ™~HKvle59›ÊЧ+„²:çŠ*"]3Àdaÿ׆7]ÏeÏ NK ׌ʼȔ•s%ç¨+3:J–‡ ÈÉÅùœS|Åðp¢,¹‚~Lœ¨ölDʼneŽš)-S9díA³m‹\(‡¢:M¹+ªKLùUŠê 2g·–™ÕOöì`§( ƒç]( 6à×hZfªÁás‹Þ¡:¢e—ŠtnÙiŠvÊ]ÊS~Šit^È4î)rpñJàETõ¬¢"Eë5ƒZ_`]2;¯†Ðä¶”a,f'ìãGÌ䱜¢QùˆSDëöhNÑ ºÔƒ@Sà)Èt 6…:…ößÉ ðA8ë6É}ÿBz–ÂG !žƒ) ÑÐðñ‘A|d¶ŒA8­™‹! ÄS ࣢SÇÓô—tIð»bGK iG£X.±„¨øz¦0º%0…Ä( ›àšZ<B× ú„Çi•ÑûF2’‘Ú©;ÐÒ/aéG;´ˆ /³Á<­”ñoQ¥¼¯ø@¥üHé¡Jyªh¥‚¸ÛyEmžã!ÒYEA‹/(Pç)¨àE”,B A¬Lé? Kû¸‹=ºÇ3Ö}åY€y`ž˜gæY€y`ž˜} sB™ÊœPæ„2'ýãÿ¿ÚøGtâÙü¢ÆŸŒW¬ -¥íë´¯‚ëÈyê–å²O޽¢{:Z‚™âIÀK¼Óše[³Ene™P–®#'«_´\–|È!j–ã•Ò"KNÊå*é„Z> stream xÚíYYs›H~ׯàmE“9ŽÝ'ÇN²Žsxmmå!I©0YT(>þývÏŒì¸âÝl¥*/bh¦›>¿îAÔ¹t¨óròl>yúÂcND"ŸûÎ|åðÐ#\DNà…Ä‹„3_:Ü“)—®*/TYTÓB÷`»ÍÒ$®Ó"7„#5åÔ½š2ؘ[UòË&]ª'f}¦2WÊÜ0Â9aÓOóW“çóÉ— }¨Ãœ€Ã«=ÐÀI6“Ÿ¨³ú+‡…ε޵qR B·€G†ñ:­t‡:/êãÜÌÖZ  )Ð#´ïŠV1t»)G›Æh iY: {¼Ú5 Ý“WMöÄVøÚŠf)A7á:oÙfq²Û“æcÉ)ÈxЦ`‰ ¨–ÕHŽpABîï3P—00‰p˜d|æ”PÓ_Ï^DZçè&áÌ#¡]>—r‘æi½€^_O!”èç›ÚLV3s9“Ø<פØ\ݬ²ôBﲩuk¨}¡d¿@k¢ÖTñ`¸Ò ‰Ú ž#!ŠÜceÇU–ª¢\ H 0Â=wÂiëÛ¾ÔMm'»( £kã†efòúK˜Ž{ï×Þ©÷¦¾­¥GBÖ"ÇoZaÝ.Ç”0ƒKÞQšá×a¯â0ûŒÃ‚’ˆó…âMO¼ƒ)>ëU臢©?í: ên2n"}"iÛ—f†å5$ZlJü¶+¤uÀƒm íÁò®~kkþ‡ôÜûwO ügžÔ8ÂŽ°­ŠAA û3#2`»½›¦{¸P»ÉK-_ Ôî²&βö¨£ËoU*µè$V¸mаåz­ìX—Ö}ÄÏ혹q¬rbÙ½áUð€H.‡Ô(òG¨]^8S‡0ÏÂ`Œ¸‡Ÿ"„¹¡)"¨/þ(a÷bhBÿlÝMí ",VPÏ7Q}? àÌSæ©ßÇ¢M–ƒÜF× 8L"ÅnRØ ¦%^7ŲɔY×kÙq…±ªvDû´ŸâHÑ=Ål*,_aÔ’Ú$ìIRZµ«´,ò Ì V‘Þ^NL­h“zx¹ïMp"oÊѵK[{õ6[lÃÌ@›ÇŽŽâRHƒQõôð# CÛ`YäÙ~#ŽÕ—F›Î×&¤fªú)f“nüG»=ãà$úwgöÓ)Ðw8€ë¯!å×ò}CÊ!~ÔD2BD2ìRÓ Š[øOÀ6<ŠPîp÷Ù¯_(¢ºÅû­ocvìñÉbnl± ”‹Üƒ,3ä4_M= öúË™eÀ“}¥‡\×ë²h.׆Eƒ?R‡­hämrÊåã P ?ïØï£Gé_SŽD~Üð¿_ÿs"> stream xÚÕXms£6þî_ÁGèŠ$$½Oiz¹éÝM暸Ÿ’ŒÛrÌ„prù÷]½€Ûy«ÝæÆ“„vµûh÷ÑJعq°óyðÛpptʈ£XPá gNHEˆÅ3œ:—îWrWcYä¥çÓ0r—Ë,$Uš/LÇïңؽ÷ Ìò¥,L÷çU:•Ìó¹ÌdRJóB¥ˆx×Ã/ƒOÃÁߦ`‡˜© qèLî—ר™Bÿ£ Žœ=êÎa"‚6s.°u#ÖcDE F âða£ó|—Ã#„ÆáÛbÌGi9šä‹+°›Ñ²H“t™dÆzß4C/Ä®,+óö0—w«yí{bšžhZv¾Ö3¬@ˆ»-@1¤Aj¼l¼¥8R.… þ³HoûàíÑ©-W±ãSHð–§ã<‡¥Yt&::PÖb™ÕÉ-×b÷!-¥åÉï½-À1˜ÈŠzÛ@5×ì,“é¨Lf@òòÛ€[=lî¢D¾¦}Ñ£Uâ‰1^¥Y­7­ææén•UéÚ&ÓY®–ËÜ QhËûØ2Àn‹£ÜÂmq –„ýÍ¢ŸÅ°z̽â‰<š8S™š/¶©fkþßm’0B‹-m’WÑæ™¢kíÎ As-Úb—Ü«¸êí0‡ç…¶âM—:Äá!Û r]îè!jÙUöÀrɦóÉ|>P:ßßdyÙÍà“u­ËnuE¡þÙ¬¬t¢Ž3;lž,¦™üj3Yj}óhr*ŸÊ·”cÑÉ·ÆÙÍt1ßoYFÞ\—±Õe]ú¹•U2~ÒÂCÅ&` D³•ëHÂëÚooœB#@ó§/Änuªô<˜ª†°c œ3‰èòu»e›xðhïUµ$÷ÏŸô ü‰7·©}qéç}*Õh*gɪ.!üú ^ææ´Þ«R:FÉsŒøS°`-ÇTÂ!•ßË1õ}Òá/]>å«mH²av€ã)Dyøº:Küï¬hIâ°ÚM‹k$;æ„…ëbø0Ü3$bö.jKË«ÉD–eO¬k5ȳh§Õo9]¿…ÍÍZ4':®^ôI®Ð'1*S©]Y“uÛæSEiVßò´ó•D¢f&“ª;â„ $DSÊÙs"Lžt¢¢s±ÑTìÀˆz‰ å+‹kÊסº-ÖjºW?E>ú„Ó¿Ç%˜¡6®Þ=.{æWßÎv–[ñ;Eœ‡íS“^hùë8hŒi;3Ûøð`O$ ÓDÈ =rŒüµŽÔmGÐ;/¾ÛÞzSÍ(XnÕ p†°@¸'ód©îÔ턽yÈó‹Ý“üNmÕËLÖÌws0³êâfÒ=ÿÊö–aš˜]¿z\ÊnŠfÿÝ»Ž endstream endobj 4823 0 obj << /Length 1356 /Filter /FlateDecode >> stream xÚÕXÛRã8}ÏWø1ž ]}Ù·ájf¶˜YÈ>•rb1¸06ë8ì×oË’ËÙ]*U±£Hݧ¥Ö9ja燃ÃÑît´3áĉPäSß™^84äˆ²È xˆxÄœi✎¿ºTŒe9—e±t=„ãO77Yºˆ«´Èuþt)ÿt tÌŠYêæÃUšÈúýXf2^Jýƒ Jqϧ_FÓÑ_#x°Cœ€‚kŽ8‹ëÑé9vhÿâ`Ģй­{];Üá™9'£?FØÄ‚0¢>S½}â”ðǃÆã¡¨•W‚føªœ‹ÙU5KäE¼Ê* ÙkÂX™+L¬º­º4/Ö€+ݾîM7×ãxžITÞ"o# 8T0ß<ôuýFˆ`gâûøØñ(‡èD½,KµjE9[‰´üíL ÞNð`Ã$ ‡Á›èö‡Ìmÿ3,°¶¾-z gy_yUOÝ]ÕÃÍÂî8ŽB"š‘jt™ßU_‡‡1õjχ¼¯âù“` X;)Òd`âE¥‰#Ãið̬²ŽU† O\›¯ßÄe|mYw(A ÀS˜L9MósHMÍôÁ¾3KnG¦ƒ¨Aîé!¿§ó2Vû×ùÝ©×À„o5V< ˆj9-V•ÐÌ™å#¤¼çù« ŽZÇ•ÚTúõ2ΓL>9±p h\fK—(ðUýTû(ÎM‚)ÞEKîGxF ~*s`7ùíÔbÄÉj±Ëeo˜šc$xhûê ^•ù¿‚X¯E« BýPÏqY”MV$²Åñ|Ô!ì™>‘M²t7!VXÓÂ`jaQ›U¡½ÅVèì0i–†à¶zM5SCÃÕ`B!×cŒ§Í°«'Ò.5Áç…1 ˜ËÄýÆÒÔÓ%ú«MË ‡µi–Ç×Ò¨C êTm'Lú§2ù‹$Ê{‰Ò30@·˜#_û •Þ ÊÆel¶ËŽù'ÍM6©¶Ù2ý{0N`Âø›ë ¾&0ZXÈû–u~X¾á„DAÏ÷þfÔÐ7Ü£fmÙÆÓÎHo--L>«¥ÈÆtr/dÃnL²Â4ë°O>@¡!®OòÆVƒuãå'@Öa?Š7Eº¹È„›Ébו§Ç½XÏZW_wÅlOEøíhòùpv¤ÖÿÛôàèÏÉÉw7ÂãO®ã½hwu†“¥-Uagy©Ep\=/åÁ%åáöRÎí5("K³lHÏ}à’ÉØC Û y›V—=Ý6R§Ôõb;Iׯ.å LQt¹ºCðý³)A"h7ë«¥ž…}£õ¤'u«Kã÷WºþvÛ´£éFÍu»>½‡‚B|(n"@ÂÒ¶7Ðp²µˆó_Tm²WU›iþJ P˜ì•/ÈíÐÙr³·?šÀ!ªøy_5/í#htÛfÁ1¾EÉkÕ:ó† QÈdqõØÁ©]S›ö"$Ö÷#/*ÉAž}ÄÔ™²ëq¯”Ð*ßòÚÔíÃøJày&ZaªW"Í> stream xÚíYYs›H~ׯà¥Âd.`Ø·$§çØu´OIÊ…ÄÈ¢Œ@ (ŽÿýöœF¶Öv%©­}00}÷×Ý#ì\8Øy={±˜=;áĉPÐÀY¬:!ˆGÌY$Îg÷tN}W–KYÕÜ£¡pŸïvYºŠë´ÈÍÂïrN±ûmNàìØÉÒ,¿Þ§‰|jîÏd&ãJš‚(Edþuñvöj1û{F@ìÚ£‡Îj;ûü; ¬¿u0b‘p®ôW[‡®™óiöç [50" =F4`êë€8%¼¸±xvHa‚f¡Qø²\úç—õùÅÜ#Ø•sß­Ïóxke÷¬nzÝÜÇær©õW?×f^ûn¼ÌìNEi¥[©[é)JÄÃ/‘~¼Ò?; ‚žèØñ(Íüžä²,•ÇŠò|U$rÀïÙ èÚSˆc0ÐHmiÕ…ÀÎïm ¢ÝðûØ¿¯ø>¢Œ ø¯Š¼Öfü^$g¢¿‘#Ax³Sm’sæ»ß마1¸eC‹Èë:^Þ* A!ę̈R¤Á®Ú§¢ßÇîJé´‰KóôD™×¾ÙçUz‘ËÄ<¥¹VÛñÇÈ' nŠ|ë^µ-“ù„c@n!XÏ1d:Îî¸UÖ£ê‘@ Ed †ú..ã퀼£_‡Ca?§ùW«¼vXÅøtl=Œ¢0jD÷Ì–wé²ÔÖÂ:—Z"ÚÇVÿ¤–ŠGB16–àRm´>ÑIm:’@#AN;oš…Úæ3Ünâ<Éä”4†ÒP˜b_[iºä³£ð_ðï%阻"dØÓ±-A4ôD€0ñO·û­y€mõÆÊQ˜ëÌx–5Ñ;ìè8 AR VÎ5øÂOýMáYœM’R¼Ÿáq|¡ß–¿Pë‚6±QáÓ~µ’U5Ú6`å™}÷guzöÂ??]œPî}þþÕùâãÇw?(¿>Òûú.)de׊ºóJ}Ó)ÊïúairAÞPpH€A\ ©ç–}™ÿ—+´ ˆ¯ÔÕ-‹²‡Ä¨âx8@ЀۉBß4Ël²ôŸˆˆ–ÓÌ„‹ÛļJÛØÜpE±žàD(¤-®žŒ¹˜žË~–æ«lŸ¤ùňW}½³w€>Öÿ2K·i FÛ`Ýz!0CÇc‰["+G×éu¦÷ÙØ×݇`œãÚ%t ¬æµ>P*E«ž,¸ÆÜƒæ‡‡Hp2Õüh‰LóóŸî}&lH¡ÄôÑûˆÄ)d=…6€Òÿû”}ÊñÆ¡ðpA¾òÓ{ ÿâ&êiQè×Xì°ÞqÕ¥½fi³Tob Û}6Úº´4¶E’ªbÚ4èMÅY—²YZö¹7¯â,{@n šÆc2D«R!¦¬Š  ×Lßwͨ6ôýZù²(Ê¿ÔäZ*S|›Ân…þ¯‚Ýþ$v7èqK3cãƒ'X€Ñ†òO.ë4™wŒ‚ðñ‡Pp K-¸“ãÀ=øéà>9xM¡9ƒü#Öôija^‹.Poj4Ô¢'‡2QtC¤G®0àT?ú©#Ÿ8nä»9…?k"÷ŸˆøÛ™>ÓU…ƒ©s[f*GÄlˆE|bêu7ÜöØB(ôîYÊïNÌ $+YOP„šG£VëÁJÀ4¤Í]}.c£F[ï`)Md^§ëk3Tuʲ±²Ü(‹æ¨ûW՘Ė™UVTRÕ q†’åªÚ‚ =h ŽVîRÄã>C؆ýéÕ¦ÚÓf¢o§}{,S€BúŒÞ®Ck"“CCÔP0Ž"<ÊÂÃŽ x[ºº¶‰a¡»%†C TêYVݬçܶÐJMàÌTÂoCFuy¿™tªÒdgSH-4ÊÛP6¥ÊFå”Ýa¤!Øï“ŸŠŸ]EœRLwGJ?Ó†ª…K0>dÍUn.ìâÙ vhy2yþàƒYÛÒZª<¬¼Ç„)&†²3IïÚÿc ªM±Ï’a'[íäJ·²«á^[TvqCfµÏšžc4ѵÍ8äcÌ}³nCq"ê94x]ŸtØü¸;ibû"5¨”?I™Èµ. û¬Ë†‰¸Ÿv3òÉ›w¯¦"ÚG!oÅæËøo)hÜhpô¿R“ÿ1AQ„4̸á gûrït—nóZîŒðÈ}YlUó½ËdóyoºþµÝ¡Œ´öýÏÿxc›z ¯p“ĦW>¨ÆŠþÛÌ© endstream endobj 4855 0 obj << /Length 2041 /Filter /FlateDecode >> stream xÚÕY[sÛ¶~÷¯à£Ô±\y9ç¥IgÜxÜ[9}H2J‚"Ž)R%©:é¯ïâF•:N§ÓŽgLö¾û-@}ŒpôêìÅüìÙ'Q†²˜ÆÑ|Ñ”#ʲ(á)â‹æ«èÝäõ”Љl²©ÛéŒ&éäùnW˼+êÊLü(§O~›XXÖ;Ù˜éWûb%ÏÍøF–2o¥ùA¥ˆL?Ì:{9?ûõŒ€<8"QB5G N¢åöìÝ­`þ§#–¥Ñƒ^µxœÂ³ŒnÏþw†‡º°t ‹¢E0Â,1j\®¿gqð»›PÐŒËú£]l£/o=’e½tä”PS!&Vi+ýQœ*Mÿy#„“Ú^ÔàhAÁb10À¢®!À+ѳ ÂÃ6‘ ”õþöÌf"H Ç%0a¿Ç[Ç=Qf‰í±^ÖU§öSí©à(%ÜíT› &ÅäSwþmò0C_¢C,|A°‹èͲS…RÁl³2¶J1›K5Þäùõ]©câØÞ§ˆà¡ÁÉxÐüÉ3(3ƒƒˆÁ(£ÔÊ7ùÖ#Q‚2’D3Oaë]Q}èuêt5Î }¤“̉>3[®ŠE“û|ÑÎ)Y3KeF”1Jà9'䟢„ìßx®±¥ª/°g½ß0¦!ãÃ<¦œ ÂâPi›û0ÔÛ”Žë£]3„ó Ѩ$Õ¿î7…‡AHñaS€ŽÀ¤ï)Á_ p@^ozñüF•¯·/OÛÔÕvS1Íûß tµµ¡.™jueW·#ý× /¦ ž<¿ºµ¼j"Cî¡h¥. `¸à¾>?ÊÎ.´E6?l¤Þ~ ¸I†dAŸ¿§ƒ ”á4Äݧ©™»÷~t‹G ñ¡¬/w§bº—Œö«¾Riš¡$MAu§òWLZy§cxˆ­?@ëÕ·\Ƈ‚m¶ý8 ²bCXµû‚Jìhí—Ý^ #ÿ,•M£r¬n¤VòKšqû(’7Î`ÇU>ìñ?UÅ(ª>Ôrß¿ îØ“ñ·ïl¿óø®Þw#V‡úÿåÀÊ C:“;°ž8upE# Xß*I;gr[ì¹kd+«ÎÈÇ“Ü÷ãÁØ2öÑüö_ûðÛ³PîkêLò0*Ð× 34iˆBîüà[·ì—KÙ¶Á¶À¬ žœ”zßT_-1}‚įõ©²?Ì lÐCLšºqÁ¼’íi¸WÀÃð0á¶v^¬™ºõƨñv±­WÇ;†Ü5fÙÖûZ<Ьš6Ò–Ÿ¢ ±Óá#d u:Á¼”+«×Ö_TÔ‘QÿÁ11üCâqš…Ÿcøc>Çx^V´tîÔZ\e­{_ùŸ±+– Ť¯‰ó‘v!¨»^O6ò¥'C„¤_ó©ÇMÂËCxýAì{>hë„Å–ã6©}´Í9ÀÛ¯´¹{z´‡ÓÜ£¿¦œ‚åìY#Fò<†ÞU…¾ýøæR' ‡2—îöxæJ@É?ýÄý endstream endobj 4868 0 obj << /Length 1663 /Filter /FlateDecode >> stream xÚÍX[sÚ8~çWøÑtŠª«-ï>¥]ÒIï%ô©Í0ˆÄ³³¶)Í¿ß#K6¶0 mÚí¾ !K:ç;wìÝxØ{9x><;çÄ‹PÐÀ›.½z!—ˆGÌ›.¼Ïþë!¾Ê¯UžÃ ¥¶Ù¤É<.“lmþRCŠý¯CÓl£r³ür›,ÔS3Ÿ¨TÅ…2¢‘áÕôÕ`<ü3 À öˆ!ÍQˆCo¾|¾ÂÞÖ_y±Hz»j×Êã„1õ.ØÂÀˆ÷Ñ€éÝñrøp°89˜`„Yhÿ_‹Ù&Â/Ôl¯Ôì f"¾±øGfxðØ2öKó%6CQæÉúÆÌ70'›85õ¥fV ö³Î9Ã@÷À.)oÍ̲‚*ñ5ø9P,5ØÃ/—‘ƒ»rxv-!`oD9ÈH´d ò\ë>Ëgól¡:ôžƒÔZ"„Ë1ˆº+ÀZxËT‹ŽMÑ:Ep„$“õ±/X`CäGADép1ÏÖe¥Ÿo¥Ã?ÐmäH^ŸÔ‡Ô ÿ[©­W`½RèkJûWÏoµ…èO4H»1YÛ-VKOˆpHè¶1Œ{H" Š„UꓱR{~–mË­‰‚–JH¿=0¬Í%Âà·0A‘æv0‘xÕ¹Þ«>‡]¶?'ë«F ej¾YÆ»JÄ( £šõ‘9ò&¹Îcû®}I¥]‹¾Ã©½eDB1ærPùí!iÎ ÈH‡ô¥æ´¬E~csµÉU¡Öe>a-[š16CWK.Ý.·–ðnë¨uÈ0‹Àa™Ãð9øi»Ù¡–ÏUÍïAuhIà1r…ó®òÊ!Ãþ®õ}FçòG08>])ä:®*ýS~ÕQìÈpoË…"ìjÿ %ø>_ƒ\4f‡­î·ó¹* 瘣;Œ—G¹Þæëïæ˜þǯµ™îó»À&™ ?ÏòÚcª‚â¸p$}™¬’´J—ÒYfF'èØ®ƒ „É€2¿¼M ³o¹]Ï'èà›Ú$¾j÷´\”vcl†<)U#[¾¥¿¹¾¥×´oµŽ»¾¥×L.M3r×D†}‰¡CAn7[ÛM<䣈‰àû͸ñÒדçböarQ¹é‹‹Ãûgoffœ\Žgï´Õ¼ŸMÆgoÞN­c¯³:ÐÅéÊLWÛvò¼VµÃWºªó¦ <íìG£íƒTa1Ì¡j•¿õdüñÓÅdÜû'Àe„"!äéx!Yb|¿ëŸŽwün:žÀ†ËqìЖ—uÈy¶Údë L¬ÿÖS¨ã¼ Ððú ÕyñÒ˜q¯F“›uV{aK»Éòd}ByÒÈÕ§[©1FPÀg½Xö$b˜í‹Ô=8@ ÁI N6 ¨k=¤KdˆHã\êéAô#'“Ó²ÔYö@…‚λqUgJ ²oÔ< ÈÕÂ,ô UˆíküãŽö ÞX‚®Î)‡´£õI¢FŸÄ$=Úošª„æ ½¶KR;»¶GÔjSÞ Cá£!x%óßÃeæàì¾K\ú µ¬‚ú6-ÍB‹“ò#ÑHÑ~£´6F%#$GÒ–ñVPÚ•°Y÷;‚ºJ>`ÀðlÄûjb‘©¢NÖ9*Å.ï:5nÙ¤I(ßÀ*"Þu€Ou¼¨Òî2WÊɽuEav•6ëè=@ãàcðªX¸FÔ<‚v·ÊêIíîE7×¥$qZ—,°®ÔB-ì ýä΄Ӗ€'A–F dØ÷„çíJw)l³B9퉞oå®Õnhîù/š ×Y–ªx}_Ä.ëìj¨]õ´ˆ¨Þ–ÿë6£b ¦Ì娨ž §õ¤NŒloÿµ'‘Gr>"ZÇ™àç3H{N $ÿù=Š ¬Ôö(ÂÓzÁoïQP—ƒJÞ¤¯K¢S÷ѯí:ÉÛ%ëa‰vðt57i;T Ð# .— Ð.Ý á¹/÷ßÔ˜N†BøŸÆÝ‚±¼í­€Ý_³­€tûg­£PW[užuÊ‹[n;"˜õ©ÝôÞÞ8‡ºƒX#º½A8 ü·ñf¨-Æf=H'T?¼¢ëÄ“ªzƒùnòÐÒž€ßõ¼›±Î>\Ø>xe0YÄ¥Þ—wU¸@ÿ—‡ endstream endobj 4886 0 obj << /Length 1400 /Filter /FlateDecode >> stream xÚíY[SâH~çWä‘LIÛ—t§3û¤XÎ8ê"î‹ZT€ˆ©„M‚:ÿ~O§;Hb`P`k¶j_ì¤í>ç;·þl-l6Ž{ÃŽC,y‚ «÷`Qé Ê<Ëu$râ-<ýæ(ÕâW4ƒ*gëšP'Ÿ[Át‘wnÓ |5ϳÙâÎa^·ãâôWiRÛ£j +`™ © ç\ÇzñGP-ò¦ú ²]ÁÛð Dí÷‡"BL AvK8^^uæ ÊÕY^ýÈ£‹¶»R/ì=93E endstream endobj 4773 0 obj << /Type /ObjStm /N 100 /First 968 /Length 1946 /Filter /FlateDecode >> stream xÚÝZ[o\·~ß_ÁÇ6\r†3F€\à¶@ ±’~pEa4YÒßo¸Ë•´º,+­à°0çœ!ùq.ß ÏY.9¤PjÅŸ¸H0òË21Õµ@0Ñ¥ PSߦ‚$ÝšÏPÑŠ)¹¹Pái+%h7Á@jâ#÷Zësh¨Y&ðWøÐ%Äcá®—B•nM8AíÞÁ‚Õ@ÂØfmÅ­KØ&¼Ÿ!!ø |Oa3;‡WþÀÝÜÀÜçµ€ÉÜ`âÁ_úÓÌSkDØ…rh©ãD6µÜ/4îÆÜ|±&™}Ù Éa"rš´ì·rhÚ£ IÓÔým°f³Ì«W¯Vëïö"Ÿ ëŸ~þö€ç$Rúüóo¿½[}ýõÊÜbFnU$iQ±ãŠÌÑêâë‹ó«ðêUX¿F@” Wõ!¯É¿½òTȰàöÊ C»¦gˆí¯`çÝUñg¥_aÁõ—Þl®ÂYXÿðýë°~»ùã*ì±¼ýÏï9Ýt«õ›OŸ/?l>m ªßûÇæ×�ø#œù E€€‰Þa¡÷—튺Uüæüü³m ÓñtÂÜ 6„Ö…D}ìjýæó?¯úõß?žÿ{µþöâò×Íe_7½[ÿuý·õwg¹_8ÔØdÍ19E+dž„É%EëÔW#"jßtË¿ ë¿\¼½pÚŸ>aàÇ‹ó¯bÓôg7Ù"@@±€R²«‡ë ’Lµ,egbŠžjÃ&T4’ñ)mR)&äù@¤‘-SHmÒÓÍòtËNtnÜ{òò–"2=YTæãŠ(Ñù¨"Õ õ긢äH*“”p#™)á ío‘ÇÃtñTJ@q¸C ^åŸL 6ÀÚNhi4„2„ÁmðGÃÛn¸·4Ë ÊnLÞ|‘!dQ£›ÄÄõñPE©^0iPkÛH8;¡Ð’e‰„ ŒPÐÕÀ(6i²Å)M@ hw÷ÞP[®ù„Þõ&!©Ë5·–,1·“rk.Q¼áÛ!!µè}Þ’…Ã$qì]û  É,’FËW>ñðëʇ:tâʧ9jj{$ [4Q¦,ìIÛ¢»ƒâ^RœŠ&¡Üv8UçX¾­ˆÜq¥”bÂé諸TŽ8gO(Ä¡Là+PÄùcB‘Òýç†CEN‚&A+ºDœÔŸrnxì¤ðh±À¹Áèž&žÞ$ø+ƒmqÏy4„2B‚ aôô¬½ÁŽV¦Ê಴B%¶½7¡üB½Ú’z£7`º¼6 åX¿XÑ]—ä¾#;¥wÐé{–î€xòϲ Ïs m·¯ƒðQ•rJ“¤˜r éE¨å9$ËÚ!פ…KÙæÐ”%–Q1ùIÁáTÄž†¤Wš­È4S‘i¶"( µˆžç¸ž÷‹3ŠÔ4J– ÅšbeùâÊgIwË'ÛÓË'úÇ£Žò¨£<ê(óFeB}Žª©-f./Y59áÔèU“¢8-‚ŸÅߺ7Ž%¶ÏH‘Ä{(ŒÀ%ÿL0eI¢Tcõ¯I¹Fe§dU÷0Qª–š‘ç=Ù¶P¸ZÕY(Ïq‚¬%‚ö…Ó,ªÚ tz; £Ñ›²pÈbIÿ:·CR¸Å2äžbÅm²XÝR|¨X*=X¬ ÂË„#6õ¸žgv¡v\‘êþMöK«U"wk•ðÓkUU§Œc\Ç8ÕKFõzŽÊTüþw½Ê1ë)ßõfŸWædœ ¦,ÌÁ&ýÕ€â¬(sPðoùójcA™ÞèüXÕò ð@2Xx Éó°ð€RdÛÓÌA9pO§%)“4|K‘z«ÒÈ&Õz0U”üÐ ºÅb°¥9ê< Ä[Dz›ýÖ¾uªÝ¥NÕ§S§ì‰rôû:SG›¯£Í×ñÞLåÿ³»EPØuKSŠ—èî‹CÑk(’ =ÁlwÿêM=ùï"v%λ¶œõ”Ÿ3‹ˆù(ƒ,*þÆ4– áÚ¿¤(…$"g Ê¢Ÿ3÷FٹǑáV¥6ÿO8:MÞúÒcT~ðk¥û;êC¥;êEF´»9*zì¿^üÒ:àÁÄ7i|;çq7³;4^Gw[i×AÚuöøý”ÕÑ%RYäocóì¬Ð7ô_Æa4@ endstream endobj 4900 0 obj << /Length 2050 /Filter /FlateDecode >> stream xÚÍY[oÛÆ~÷¯à#UØÛ½ñÖó”¦MÐ6Nç! J\ÛD)R!©*ù÷ÙÙ¥Hš2œú-‚˜{ýæ>»âÁ]Àƒ×?®/¾¥E±,–q°¾ $:e:SÁº>„¿­dšvcÚ¦[]É$ _ì÷U¹Íû²©ià'³’<üs%`aÕìMKïea.©}m*“w†:‚IÉÄêÓú׋Ÿ×Ÿ/@á £5Kxlw>ñ €ñ_ÎT–G»jè8…o¼»øý‚ÙˆÕˆ !R–J$‚3®âåCYëÃîfß"âf‡÷+ÁþCLß¿RéXKcDh)\Ñö·(”ÃncY…~sKß}Ûìö}G²&rq<"—Å,MO H„°G þø W"‰Yˆ Á2%çŒ<‰(b—3&^Xða›¯¿>ÂH^Ôh hÞØÑÏ¿süI´È|gS-5íŸ(€¼Z$ ¤ôˆ”’Œ'3J¥à“½3ÆÁãÌó͉‹w‡íÖtÝlÛµæ,ÒéYÔ‡¶þfÄòo þ ëä|vHi³¼mSB‚«8b:Ц˜×÷%lL#Þê-¹,öühY÷¦.LA½¾¡ïÆÐ÷Ðù™Ü­ÏéCæX°·Í«j“oëî°•[²ÓQøG»‰nîléoʺìo¶­)º›}ÞuÇ•ëm‹<âð_Ðv؉qàE° x²¼X:£ýØôûذaÄüÿV$r_ìM·à25k/í:ß™瑚¥bpt†‡„àØX jÛäumÚR Ø}nŠ[IvÖû‹æÐC´TZ‡„ C÷4M¬ªeuDgE­(çÆy.®Êi¨68fÅZ•µ±UØß›š–Gò°¦g‘biæ#WÚTM”5 ¥ö™ŒâGÃÚTôói$Š£ð’LZëˆAJ˜ÚÁyˆØÉã#—âüƒÌ+Eá §;ƒ [È…m`DC¬(D‘ŒX†9Œ…“ŦîIz_ÝDC»rꢼ§;Ah–½?,/hÇ-ˆÙa"Ý—5[]EJ„¿LMÂû²(¬ò`àEù£Ý LQcð9‚´à@¤ÜK d¶eˆ«]YC ¦(C6Ñ”õËe.ü@ä³kkãRB˜5ÅßãÍÈ?£ØÇØg¢.dwȯ-ÃׯçÕ p>”&bšqµ»Ù¢Táàœ†¨Ú¸¢ÏË¥9+el 4\có .8b¼o¨³oËz[îóªcË)Iž"ôB ÓiL\Í-W÷® Ȩxè6M%S=KP"²zÂRˆu|, /àÓ;j4.?4'¿Ãèéôñ7‘GLNl›º·…à—þ±,aLüNÜdЛ¿ô—Ïã6çˆ:›´oý=š1«Q$³á²ÞŠç"ã,VñsPxÏÚ#” ú–‹S=Ò·x´x{jQ'Àô²4H€D¤IÞæ» ùÀN'SÀ§Ú•ÔàÉVæ&ÂY–d³šõM¹ió!ŸˆXÛY*Ÿ•I]0®žQ³ ‡kÈç æWhØeK!{(¿ô½öT’Dé1ò €xàn‹s'?Y{1T=ó²ô*É××+¨ßÿìÅ훆ŒQíÜ Š3iÍl]“ÿñJJàjóæ#ÙÀ’Ô±ìÌó’ÏPaÛô u{PŽi¡Ô½²²#¹ÙÞCmlj?;mBÂϵ]Ñ–£Ë3M¸ÔŸ…K›‹¼ÇÃrêÝÚìÔRÇÝ•D¬¦îg\~0Õþ8RÖ³s&ð— ÔŸõUvÆ2&Zö)-(ŒÝ†Ê‹ÜÝa¾#ûŸä6°ÿT‹Yn$lN’]ÊrBÇ ¨]–ë¿<3‡€›‰(š ÅÖ¿^0OÄ•e,͆\ÔZ`>˜.ªÉã"³géç»Ïh‚`_vÚØCu¨”aëÿ„¤PLêçæ þËÒõD²Ä>3=+÷8*gB¿}¸9s|¸žÿk{ƒö^ú¤ó‰Ì™—£Ïx¾ ‹OFXfO1ü>Vô–ypÉâlöþ@ ‡[üU6xI‡û_ZûæÔ}I=:Ìgº;šC®s¸üSß]•ì™+ÅLIE¾:]Œ®ÿP”ÁmÉ3y2ež‘ Ü[³A(Dz¿_|䓼†Uö.¼¬gTš ‘}P¥6œ#ì·ïß¼!¾lZ3úÀçì´½fÁlÝôNÀ1áÎJêQhÿjê‹àgéÉ[Cn=°‰÷Wž…k›T 1VÝa `Çéf…ó½_ø\V˜½©‹Ž–øÁG÷dÖñÎ/U¸±wn;–UE›óêh zc€–#¾q4‡‚ªÏ7•û~ýê*ux£ø´r•ÓÚ‡—íZ3½'+56vå4%ü¦~^•ywIJsÕWéö5µŸ° ;úV ¿‘Þ6` ¬E¡Ï•;7_0ÑH0‘ÄO4ÒÓ›•CIOÂ@¼»o•k;ÃSV¤j×¥}RñÌ8þo[ã‡ü¶Ò>(‚¬ ¼øZÿa’´ÿ 1Î7Xš©¿èoþÝiEW|{kŸ×mD0?,=fㇿ·TÆÙ8ÿb¿ lñTVt„Ñã9ñß )¨?düäS Ò»ÜI`FhPÿËû|Õ+…îמ#ÖÙðÎR¿`üÂrëv`}º>мøï/Ô ÛJNµnÿu?ûÑdöï\# endstream endobj 4916 0 obj << /Length 1905 /Filter /FlateDecode >> stream xÚíY[sœ¸~÷¯àí0® H Ø·\œ­d³NbOö%I¹ðŒ¼¦ÂÀ˜8ûï·[-`ðÚçÄ9·ÚòLKê˧V÷‡Ì½ß=îý|ôtyôøE$¼”¥ZjoyåÉ$b2L½8JX”†Þrí}ðYHå›úÒÔU³dœøO¶Û"_em^•$xn’û_&ÕÖÔ$þy—¯Í#z?3…ÉC?“’‰Å§å«£“åÑ—#þpOx±Ó‹yì­6G>qo òWgašx7vÖÆ‹tÏÂ;?zwÄ],œ 3©Cœ­…WÃÀðl.j´*8ãaL®/Õ„Á4Ûª\›ú¢È›öâ Šv¦Á¸=^Ã0½µ×.Äád’”ÙÆ¸e«ªlq<ËK³&Q^NŒ,!‚ý­e¿÷|ü"L±q/„®(´z»„Þ*î¯ðý:«é×ñdô <~ð °ÒL¤¨ 5A©GÈ®ËûÕB ¦Ñ-ÿȧ ˜ä nQ ªY”hÚ½©ð ÃÓz PAºŽœ±a~kGðL`QK„êV®Úo¾Ï3¡ô–EÈ÷ tO¿Ò”%iïW ŽÍ¢È”–Ål&Üõ­á@k¦Šá{ 9K¥$íÛ¬Î6#õž,±x*—Wòò“K©ÎåQ\¡d±=µvv@S_ç—µÍ=îÿáJf*ŸP:ð´€v†SË5â{‹ù˜ñHNÌŸÙº¶?`‡ö½ YM$´®Ý‘çxlÓØÏè±­rЀ#)åj4VîŠ" Aîoò2kíÙ‡87ݱƒ_Õ=¿,Ç b‡¨Š¤û*n®s:ÀÎLmœp"Mé´A]!$õh;0_Ó>Ï0¢yäDÂTc7‘-‚(VþòÚ„ –œ[YI‘g Tÿ§ÐÀÖkAªY\9T•ÎÂTH¸Ÿ¡¶DøEUþ>–P…A‘_á^™6ßèƒÐk"u¿Xþ´aÛJfMÆšëjW¬ÉLYµ$¼tv7Õ:ÿÈÃȸÉUMò«Út¢K,.6ðWYQ|yˆ¬Œü'4Ámý"þ~û#îÿc)¿¡9®vƒ3Ò‰-ü |³X‹ˆ³8uPk‚i) sƒK¿Z×tvMn‡×Iy'3íÅe¬ã¶ ÙU™}inl¬ïÖÝ€ÞýüNa×âð+±ýƒê;% *V, õ”4DwKF%ué‰PP§j…»ÑšŸfRF¦L‹þÙÙC¸¡ mS‡§`BÜ7¥€ÿ¤ÿl(ßÉ”HYÈõ­üˆd!í’Áûy2–f{º³¾ =Ûù—ö„ÙMm‹C…Ýzm&mzÌ‚¸Ekžu© qÌôîN£þ/!@ÑÿzÔ·æYæJ5.ЧոŸO蚈óî‹ÐÜîÁ1Qá ^)—€œDn•üM½퓚[ìAû]9ôJj‹‰ïÆÔ $X±æl»å·Ø¦„Q}ÂŒ-C N§Ñ}‚²ï:q×-kÄAã‹Ä¯ïϱ .IréÖo»¥mvY8Ùûå‹ ¹31§!Æð9ÎÓ1Ï­ñøÛû}»åƒSGãtãq:ë£ü¯}Â"Ý7Ñ“—§¿-Ø{òºßÜ)ÆÖÚ¸M«ÚŒŽõ›¼½îšo÷åZTcß–×VlàÕ®\9ýð«Ùá%‡¥ÚaDœ¤ƒê`ÃfÍÎHÂWn¿ë{ÿ¹K‚†Š¥¼¯ãÎùCÅÀÚ݇ÉÂÄD X{(—vÄv[W]îÀWˆ  få¾N(jû%‚Qö+'á¯ÍÖ”k‡Q‡\?û`ãì&Hè»:ɨˆáÑ»/Ù aaÇBö$ô‡ÿ)²'Sɤÿf²'± EÉ­d Øßl@æ·êø>‰ Ðã¹±tɾ۽×aèÿröT]œœ¿}súüäìâÝû“sг|ùæôâ­doÝ´UÑ{Fg6Oø8Aš¶Þ­~ ÔO+ÄÏìq3slBÇàž|X2(þßÙàw96Ïg¬lÑÚ·.H»ÜðÀÿ…»pm69‰[3{/¡Mªøá‰¤Ö,’êo"y?"é˜Î‡j×~~ söÆ“iøÏ&0R%kW»{˜$È' ¯{¤D—1Íè¦ÌM¹B]2R˜6¼ïƒŸ°­å'0‘z.çê.–[[x±èâìF…^Ì\(xµ~9ƒØdŸ‰¦‚޼+ÓÅl1/)MµÆDC›osŠ’äÏɉš€`“ÑT¤#8-³øÙ9–Œ$H/,aKF„ Æ;©»\Ó~v™yû‡“V'­©³UKSi‘œ°±?#`Æþ‡ÇMô A„œ€44„Àu‘WçoNQë™ÖSÿzÜ]Ž9’½s36»áWjOù³¦ét_ 3­ç`//ð*r|O×-ïTÛËÊq‡=¸œê¦ïý¿¹YòÜX‡†f@G© Á]&½}i‹”¶ÿ…pçM…SÇþSÝ þ endstream endobj 4933 0 obj << /Length 1475 /Filter /FlateDecode >> stream xÚíXßsÓ8~Ï_áG‡!B¿,Û÷¥e L[ÒðÔëdÜD!ž¦vp ÷×ßJ+§±ë´¥¸™ãɲ¼Öî~»Úo%| hð¦÷jÔ{q Y’TqŒfÃX&D¦"Mƒ³ð]ŸG¡®.tU®ú'áËår‘O2“—N¼Ö}NÃ/}‚‹r©+œ~³Î§ú9އz¡³•ÆF8'¬>zÛÛõ>÷˜B†ª%‰iL®zgç4˜ÂüÛ€‘&Áµ“º ¤Jà¹N{zÔ»AÝ·êS€ƒá›ÖªŒž¨öªòžU8J4ÁQiBhœ#ësÙg44ú/ëЋ‘lÉó”(–Âb7Òº/hx @D4Ì |2ÂŽÛ~´R)%ê»=¡„Axh*ætÜšîHI£½¸¬.¢1„\Y-Ëbª«1"°C€£ÐŒ³buÝ·Iƒáø´iΚ¹Ï†wÃWÑx¸zr|ôz8þðqÿÄF‡ÇGãc›W£”ûlU®õÊæñhÕѯ½ä4±®ÄÒbw^¶'ÁK«Úr‘.hËC]U6óËj<)§º¡ïÅ`²,NUd„ç b®»=7³ˆ•°ú÷¿iDQÙc‰ c&ea\æ}5-7¹ 1NXTÿ91_Ÿÿ˜,&,jÁbsÍíJS’¤»*g˜Û5«ü=686¹³6°˜‘ì0FRPΔÅÊjòÂ;žg¾=ûbãœ-ÖÚ¯{·ô6mG E[QdÝ)zϳUoBŠ iÀÁæwà2«²«ÆòÿÜðú,/ν ækGqœÄ®V8éоÏ/*ç+ ¿mà0P´¢ÃtËB\€'©àmÍ•o‡ú˜PÉ[ꇎm|†á&FO»lô wظɿS%'2f»L½ùÓ[V›b|*—ãïßãMöÓEYè.{½Öönv@3œ‚$ÉNP—5Õ=ÚÆp£L%Q2}š— ` åï¢yG„rþ‹y^ŠÄ9rÏOæÙb¡‹Oý¼ëñ ¥ Ô‚2fcOØìl~r›È\·ˆ©ëÞQζ몀]„K\ô]²•úâÝk7˵"MK-¹ÚÒÜÝ>´‚Új ¾ØšPæ~7N¡Ew4µ*­»è#æDQþ§ øž&à‡ ën: ,]+1´³u6I›«w˜ 2'®í}†=Ä¢3ò„Æ?¡o`ŠHÆÿô ìk{EÉ.žóÍ"f‰5©ÉzõöÊIÊÙ“‡Cc\gÁ¯'3žÂa÷þZ2ãRAÍà;éby™¹¹ƒ-ÀÏT¹ÃãµvÇ@7ÆVw]OÞ޼¼»Äqfq¸×Åi+S­'æ'mÕÓŸmkõ räáßê·Ÿ†ÜØ£ÙMþØ-êì™¶ ô!ü>rÀ-ñ¦>«Ùm\®MGø Ó''8É ÀîG‚KFpÑo#8ñ!8Q“án‚ÖÜ)1ÖÙ† {·‰ /J¨]ëJûk*ï&»¿)%¬Ù6Û\? ‡h]LìZЇ³u1ñ—Ê v=ÏÑD|…Юô ±þÂdWýµ7† rŸm^k4Ökà\ ÂÓÌdöhªTx•]öUîwëÜÒ„ Q˜û”PÙE}"ÏÙÅBûÏ~.2“£Ï8¿Gp~4÷WY-:sb™CÓ}²wöiæùÊ‹l°r:ü¬©×Ê.òEn¾ùÙ'+M[rØï×¹™Û¼p2ù³öÏm0<«¼==>²È7¹«ÝØ[dõà»ýî*‡¶ÃçS$!JL esi |ëzY¼J¦á^yeY¹Ðµ~Ç^`æÿ°™8ÑÍëê“CdÅV23ß–J-Gÿu{´ endstream endobj 4949 0 obj << /Length 1454 /Filter /FlateDecode >> stream xÚíXQsÓ8~ϯðcÂ!É’,ß …)eÚ’†'èdÜD®l§-ÿþVZÙ]§èÁÍÜ=dl+’v÷Óî~»¢Á§€¯G/æ£g¯ b+®‚ùeÀµ <ŒƒHh"â0˜¯‚㣠—cS^˜²¨&Séñóõ:K—I9¼4NÇ׳bmJ~½IWæ)¾ÏLf’Êà#œ69Ÿ¿ÌG_G ô¡ "¢‰h,¯FÎi°‚ñ7%a¬ƒ7ë*JÃ3 ÎFïFtÛ–PoÙb÷b”Ð0B3柭pIÇ¥©7VA:ÎÍ ‡®­‰I¶ñ3®6•5¥Æ¯ ?ºNªªYPøüR^ÈEiªu‘¯L¹XIó´^,íêÏI–™ü“oqYó‘J ?ÖÝ¡ÙÝÎX uv–Ÿ|™½¾’Š9 ¥èƒ$öI…]”¦„‰A:¶šú™¿¬2=PyL‹a³»ÙfÒñ ‘æød„ñ}M‰8‰xô£¦€Î %ÌïPÌ ¹78òr+5T`ˆ÷ <ÄÉlé$ø+¸Á"É«›‰ë½áxŠçÝÑÚù¼Í^ÈÅìàìôäøåÁlñîýÁL›ž/Nç8í«¸1•‹"À Ìš2Fb)Q«K{ …¤"÷‘•×iým(7Þâi‘áT[ó#aqÔ ‘é2à j Ï &·P1ei¸(Ëbe:òž½·@…Í©jth ÞåÖ™±aŸüγ—•¦aÁ¶’ù0]'erÕÙ>€¿cˆb4Tá´i~î-¨oRXùÆ%7{ŠSߦe‚¤ð­E£†Ô&Çx&÷4Ä]k‡¼/¹´Øí*xOü̱„w‡ýäã6(?ìËoO÷¾|ɉ²é±#¿åÆv!rÒDø7ŸSt üLðqzxìWV Ÿ¥@zîµÚØ:(s@¯Æý[gëB­wª¾. ×5˜°ºÓµîÝØqüþíÛór›b÷£,¡Crý(ì+"Ë•áŸb_¡B¨¶Øof_Á#"cö=ö]6%Ô±5”›d[sáÎ_Cؼ²±Óý ©Ø¾¹’ÔvöçYRß”XýÙ-.&.îHx·r^+Wtmê¼azîit¯­ ©™Ár¨e…|˜`E°àÊ×Z‡ÿ“ì‘ì/)6LÇ ¶Í 6%¬·> -ƒ:VD-›=Á <F¤Ÿ©'œ)ÏÔz?¦–ÿ9¦f»˜®s`}륌v±Ý½³ÛU6á¿pè%yø8½$×¶áþSdÆ¡•TTÿf2ã6c½Ö¾k\™Ëd“Õž>’ì ;¸)>Nð¶¤,¡^Áß@ê±_ˆ½Õ®°]Q­Í2ýHCá( \²³€B˜ÜÖÿöFÑö…-ZÎÖ¡N¨æ.Ó=sý4qµ±ü{µQÙNû(ÔDôHЊUH˜Djö³ Ú™éœi¨§ $Žâ_MÔ~—‰2+­çß×Q@vz8UcäØ?¹2uÝdTp@w ˆ‘çî ½°½±V1d‚ž¨¶Kƒþ–qGY¨D7ùÓ>9£9¦&Bµ‡@ц³Íriªª·¬«µÇ=‚ÜÒ åߢñ‘u¯»kfIñf jû¢%Ú•©ðŠCI"¤ìJ;¼ô^µå1æqœ‘aÁ5ìC'!mµiÚYÛ-6™dO§Áö×Ô5ôÂÝäÛç,È&\í}Û½£›"ŒùsSÚŽ©±Kiþ¶þôÐ&¤"1o£Dʾb,†»± endstream endobj 4968 0 obj << /Length 1794 /Filter /FlateDecode >> stream xÚíY[oÓH~ϯ𣃚éÜm,bÛ"E®3¡‰µ ÿ~Ï\ìØŽ“Þ‚$T)_æÌùÎå›3§ØûâaïåèÙåèø”/B‘¤Ò»œ{õ"1ïræ}ôÏÆTøª¸RE^Ž'4ý§«Õ"Mâ*Í3ûà¹Sìøp‘¯Ta¿\§3udÇçj¡âRÙ‚(EdüùòõèÅåèßU°GìÒ8ð’åèãgìÍàùk#…ÞùjéqÂuá]Œþa#ÚcD%Ó_Kâðbëáù.À#Ì økq%¦ ªð«é*.Ë›1Á~^̬î{¹0ïí8¶—íoçö®ûU‘fIºŠöv]¦Ù;,W*I?aÆ•›žÀL°èLeU/Jd Ö nSjx‡_J‹¼ÿŸJÙ‚½ å`ÑB­ŠB{;/¦I>SõŽOÁN-£p Æí˜ÌÙK㇩°žhÍCÑ žñ lå?T(묟äYeBð{ÕÓœ…íy…„×3õ$5fÂÿ^=NÆ`ØÓ¨3 ,÷éÄeTÏ{’ð½Nµr¥FT¹[=¾Ž {÷$SZúÍêf,…ÿHå'„ r ‚"ÑŽ‰MÀî!)‚IµM­žך9\1V³é|ÌMJÀ¯™fÞ“B•ëEeBï‘pˆˆP Idz¸Š÷A˜P %FH×m¥¦ÖÚþZí/T2dHy/9Y´‰§[O­ÜÓ1ÏE+÷È0—Ür©¬m1F ì˜,FB+}ñ²#Þ3¯ƒ®a?¦Ùç&Ê+³Ø¼í§+FQФÇÄNy“^±ü£-Ää±ÃßÑÔI™EŒmiPh¢vyÚ79D6!½õOІ•íƒ:¬ÍÍ×x¶L³ãn@šš—¥²zK5¤©[o‡¦›œÐ4B’óž¦o #šIöA;×·RvYjƒ wS[¿ÐéÍŒ¶µ#Úù|Ë}ì}u­ÔÜ6qu:˯ê¸o8ª¨^ÙB¢R¾®&ëü&Ët8"‚nYÔ^/;ÓÄ>5·Â/jED«‘/{! ñ©bHg·b× ;Už–UÑ$~×ê˜#,zš_hçµøÂ*þ¯–¹N¿iXñBÕ¬\åN¿uI$xC]v—ë°çƒ#ɻډ%NÇýz®ÓŠPÕÚbÊÔ¬oò&® µÌ+7.h¬–=Õr/#náÁÈ;ìâ± ôOå¬8(dñvÝ@n¨ÉEç'Jð¾}ÊsS›±óê:ITé²"Îf5Þ_ìv[ÖA¸q°¹ž?Ó³wãûO/Lˆ|x>½xròââõ”éQø–;m±.²{Û=Àg†“šƒÊŽd´e´7‘qÑã¹KË*Rúóu–¸ó Ü­KåžÛ8‚AÒÚ¶óƒ0‰¤h4ëÔ=ÊÆ°ÉPã o½Ó^p€·Û+! ƒ†ü35¼E0¨E6%džQ; j{))a6Å@3,Î[Åž‘ ¿ûv 4¬ŠÆÿ•Ã.W 5±®âV”¼[?,Áúe/¹›˜ÞÞ=ô©´>±êÛ¹½žŸžØ£œ l4PB<éÉWé"­\µq“V×vôwš@¸ås·ðM&i6Ëõâ7–^¬Gël”pAˆûá§nÛDš¼îÕ|uÚj'¦ÙP Êíeòn‘"4}4 ’C<“u©ª·ž/ádÖ„†:¤0Äy0 ~¯dÁ¦dj–RôŸ®ÕÍÔçý^ƒ ‹­^¿¥a: †Ô²àÀ çhS”åFaõ×pšÊMÍûj>`‡±ˆ$ÉÆ†ý‚ÀûþÍÓ·©ižu«Yû²þ~å šMæ`ÈÏ™}i›DmIkÞ¶Æú”LÀ † ŒB>¸&„ÃúÀ+[ÐevžM²õbqÔ#˜-#´6ÔÝFÐ|“õëÛ.ËÚUãe«úÝ›· D!o††„Ý;1œûqßÄxd“Ža6Œ½Mº©i¨M“$N®ÕÏîØ™E~ÿf]×fÛÝ"`ÿݜӺ#¿zï¬aÒJíUvˆë9š!Ô- ¼eG¥–]tð–Ý=ZUÑŽ–]{Z¿Öb§òÎÿ,œ9E„8 KΤÎã•©ˆ…_ÿÃ^ÂÑKòÈ?Ñ>þj¡êì{[âÎÝ øÍ’nýôÝ+W:g®,†}OW?Vj èQÞø> endstream endobj 4889 0 obj << /Type /ObjStm /N 100 /First 982 /Length 2161 /Filter /FlateDecode >> stream xÚÅZ]‹\¹}Ÿ_¡Ç$j©ªT’À,ì®qHÀØ~Hbüàx‡`²Ì{ ›ŸsÔ­ž/Û}=¹s ÃPÝ]’ŽJUuªt¯µšC Öª„¬•‚©NÁ‚e¥à¡”L¡oB M†rÝ¡×Z9'¡„‰DÛ$å”Tk5ä’9ŸA(%˜%üX:䲫ò+Œt®*j†–*ôk!šF©s²ÞCîZ±†KNDÖ‹R² :ð÷d,ÚºñBp˜@jLjŽaÒ;üØa³Üƒ¦ 5|­©èÖ¯ú˜£Í LÀT*%ìAÍ’õ4¾ó ÕŒÆÒ.,aŸ‹3÷Ó3~€3HXÑTø¬Pj¢„Vƒ¬Z§)0ª6üÛ¤õuHŽÆÑ‰Z†ï{SCÏXs—¬")ÝK9ãÐcO&J5‚ ¥5nGJð$œ +:ŠR ®‰kHnÛýtùá—ó¯"?½Ùýi÷çÝϯóøp¶{qþî*¼®9&8µ{™A(-ªò€JLZ¡öcxò$ì^†Ý/_]†ÝÓð»øþòâ±eû}øá‡3üýÿ@°ßèt &‘Ѭ¥DîÙ»F$‘¯#ÉRׄÒS4Ä Â1›,@Ò¤=‚M§£­G‡/#¶bj²!’ƒ›X­0A=ºII‘77ti gÂ(J‘YÌLShªê›º N…YbBAJ ™EHV=œ£M§£Þ¢5&•µØön’=E°g¶„ÃG^kA³_Ǭ¸¢E ɃGµ(Üž¢0½5‹ ÿM½$ÃK˜Ü÷6ÑŠˆ±,õvH–~ÈÓðÚÈÖ)¼»¿ýý Lðb Ó_|úõ×7_VY‚{O+ÁN,`N*„]BÍsZ15ÉEÉ_´ÓŠ^ôŽâ³Ë‹«aÈg¨P}¶ýg,ÚÆþF\cþVX”ÎO¬V2‚æð¢'cðá+Z¦ü„wÏ?\¾{yŽÃ »çOŸ…Ý«ó߮›Ûþòüí¿ÎÏv?×ùÅÕG& :É ºÅÇËOÞܛ㻿žÿòþíO—¿…áIŽ˜©éýùÛͪø 8¼ð#E1ñŒšø ØÊ| uoVfƒßë7Ø GTg[²V–}éu¥±Qݳ¶mÃÜcïùˆÄ’E–‹ ¬šƒM‘m[?")‚P-öH/¡ŽRT Î’HP‹£¿²ˆŽiÓã1‰(ÁPÐFFÐ2(ÙîçaôËòð-EfNº¨.PLkY ¨¥G(/PÆ­.Ìœ·2àìx+«ÞÌŽ_˱ΜÙïeNv½ÍœlçGVd7| u í ä4…<™‚®™T#£·÷–Güjiû.dI+¶r´T¤z …‰Þx)´ÊhY‰jZWI‡’²ÀXš|Ë’Åõ¾¤&™ª¢ÈÏLï‚b_¶MeÈëõˆÄ¬E÷ºÉcœ 2Aìð’y6$åÖeóѬ‘aÉÒšHå€ÔˆÌ´éé4ÔDíŠá³´…HV=£QÇcÚѦ`ýt —r—ñxºˆñn+~¡ó¸§ô¥Îã®bQtÙ(6O+¦>z¿“Š‚–¬~®—¹§¨ym¾ˆ?o3æ×:;lº~ç¡zŸ?5?œ?eR¢LJ”I‰2©U&µJ™Â¤V™Ô*ý hz„îÄáÿZ®)ÃáÿR6¥ŒÎ4”ƒ Z[8†–~¼T¯ÑeÛ+M”âhœPÌQ3"),ƒ²j^$g>.ÑÎóà34âµ—²-•Â5Ê5Ãg¡uAy«€/ª’E>"´šÚ·¥ëu.ñ€ éuüH†QtËøQéÑQôIªè#? ŒF «M bK9–jG$ì¥ù,q”uiý`”y<摼7Roù”*÷x]e!¯ßRDB­‚À] gùÌö¤¢¥,XlzRQÜ>©xOQ,òaìÊ­ñ#4ÃÖՇ“¹N6ÖÉÆ6éÝ&½Û¤w›ôn“Õͺáϱ–ëŽÂ‘Ý¿GGQ:ªM³£pFYÑïÑQL(‡Žb’u9ª² ðmf=4Áä,rTC^Þö†‚©Â®¡ŸÛB$c” Âf>–4’‘yû¶t¼R;Ž*7ºñ­×-Ë^ÏX¹M ¼çÃëE@îzÉÈÕ3ñž$¨[ŠHÅà´^6ЉžV4×~–Nî*¦=×ÓŠˆ¦y" w«ý!½çŽrñ±UzOo÷éÊýátU&•Ù`–IEe^â–Ùi–Ém>)Í'¥ù¤4ŸúœÐËct£pÚ\oPÚ’«ÔuÃRK4¯Ç·Z¤ñ>H¿Ë 6¨¶Äìú]ŸJ£ØÂ7l¼>‚Qø¨ŠA²%ïo¾ÍN¦ïœWì1à!µ¶#önºJëyÝW=ãà³êÓ0R†#ø†H&¥ôåæ<|#ÕMëÁÏ« X]ùê' ¹W<¶ñ“æ.ûËí3ö8y)”¶¦U,#ŽƒÔ} ŠÐ½ñî[· >Ucçх78•oü¢*+§ ÂU]Ö¸y;)h×mØèÛŒ:Àë׋Ÿÿ¬= endstream endobj 4981 0 obj << /Length 2222 /Filter /FlateDecode >> stream xÚÕÙnÛÆöÝ_ÁG©°¦³rȾµ¹I6Msm÷! š¢lÂ4©KRvò÷=gf¸ E9ÊR…sÖ3gßDƒ›€/Ï~¹:ûñ…dALâ‡ÁÕ6à‘$\Ä–‘±®6Á»ÅoK®Y}ÕU³\q-~ÞíŠìPNŽ Çžõˆã1aÀw´­,à&k=\¢Å.išÇ¥P‹ªÞÌ<©Zv`Êìq÷8ÿ˜’¬;µ]Jº@®ù!é"/Ó|—3O…’`fGœ¡,)o–”víÐ4páÿf½u“CdV"b„F!ˆ‡‘Ädà‘åJ ¾xôóH,òû]‘ÝÓ;¿xñÌ—ÒŽ ¯pà±È¬  uæÓ÷TѼlAupýºÈìòcÞÞÚÑï—öû?{^n*„öˆvÛLÐ1PÈpC‚öäÀsÆp .+£‡Ô'ÑéÓÖNÇHÔSÖ츒ÛQRnì A8m'½gIíÎÕبÙ,3w#/ç”7Œ“½½1f;h׿ÍC9‚ uÔ?Ÿ)I±#×q5²ï¶IÄzë@Rç&‘Ö3àŸ„¬¡¼GŠ8ÿƒõM`/¼jÈ$ ¥šzUù¯zèMåD‚5Þ ð*ƒpöÓ ºÞxøj;ÇôîìÛí2f„ òDg)´¶V†tQø}óçë×çn µV•ñQ uv­`£¼ŒïQq-Ôƒ´É¶#9ºë¾[² çôc¯ˆõIÎW©L J°ÒLÎ3w%#z⫾žÇ ‡‡sg«eU–û¢8·³¶³ý)Wéº+G¹Š›Æï!5»,ÍßS!»>WOµñ€:¡P€zJ8\] ™yä`ñb.£ÂWeH@&†cwõµZCo½«úk ”÷6;ZÙÏ¥9fÇ–0˜5<)6vRmí7±Ÿ>™Mpu!ê~‰„xf¨š.^˜Th¬Ràê9¨j¨F$euB®êÞÙŽ’"àÁˆ!|H1?•×)ITܼ”a¼ýØžBBûõly ŸCb£º{¾i M HÚ0 Su–‰'y¼øá(ËÁ5Ê$ ³šô™ï$„@ž¤IK€&‰¹K¦wIÜ{à.‹ißu½ËË]&|J­°¦2к—ÑÊ^y_׉eϧ1#M³¦™\›è…ª!ò¥÷•Ÿø'*¿KS(Œãa=‘¥UÇÄ‚u‡«ù\ ’d%_q\ƒE Ž:x³™—ÜÏ`çµ|·ñk[ ÑððŸK´¶&S¼ƒrh{È«}3â m'èIt^1ȸCƒŒ*Ò‡1º5ñ6I³ušÅ5¤d0½óÃ4æ&ÛO^è=<<Ôìf† X¹.Iÿ†ŽZ)P=þbw[t7º·!b~ŸÐý•‘;bêo‰Ü0ô0j SÇšÖq÷¤ÓäDm·¥³c UîßÒëõ&i“.‡`°á÷Ö h£ü߬bæ¶œsK‰âi°|æäÅ©1^¼Ûï̫đW­´–+0÷d¾˜eôÙ÷;Ÿ,4­ ÁRÿTäë ²iGß¾AÇMÅâ·‹_Ôúêâç¥R‹gÏ×oÐ?.ÿ|ûÖnçXÅP¾@¯bã.º»eÕÚA³ßí*ïLQˆ‡JûµA@¾ QÛIÛ—ff¾-}øØ@Ó!£h,'Ѹó÷jîÄ~ROd¸Ò×µ81Òm31Ïôq­Jӽ˺&˜Ý@‚ð‹Åíƒîêñælbp¶Õ Ð_ µÏÄyNó0öNÓ.$‡|ð[30 QˆÌ‹Âbxõ„ŠÎÓÝ™tiDÂ\WC€³ÔÊý¶ÆÓt0¢Xï^¸TNW¤4•tÝ×H°Š“›=vM皃¤4jàáØ-O;`êø³ErüM»dÚ¤8°v•é;0•]LìÔ :yiUÂíOŸm2`ÖæðQ§÷ , ‘ÏÞWh˜"t@„îÔ×|ÀMcQ°Sg¶Ï KyÒA°»zœÁz×ršü(®NUVFäC;0»6=æ yòÉXßfN¦Ø+cŸUeFµ¯ÊøÆµcʬ*ã×­‡#Ž èkìB/ XKà ƒG ¹tZ›ÊõÓÚ®ïzfi‘uÃýnÎXA²áijr5j1‚Ó€ªk·+Ѓ¹ˆœØ£Ä$+¦Ü»¬½sKs¥CLôàޱš¿ú´ŽâMÞ¸Ÿ@°>p*h80¨ +Ž:@&°:à'ë”ÒüK;î ¯A8ýwÆLjwRÃÇ$d=_í†^3Wzõ‘-Å/¼:GâbK2ÀÀ¶q×moëjs;Üéo‹È¡w> stream xÚÕXKsÛ6¾ëWðHu, ${sÒ8“ÄM\[9% EA'É’”ÿû.¤Jq¤$“¶â½Øýv±ø@ìÝyØ{9z6_2âÅ(ð¦K/ ¼EˆÅÔ›.¼þ›qÀ}YÍeUÔãIFþEY®³4i²"7Èq€ýû1‰ë¢”•é~¹ÍòÌÔoäZ&µ4 ‚‚‘ñ§éëÑ‹éèïU°GÌÖ …8ôÒÍèÃ'ì- ÿµ‡#ïAÏÚxLDP®½ÛÑ_#lÍÀz¬ºóLåæå@*Á(ˆÄP*û†T Ž .8"ŽŽÎ[es1&ØoäïÊ óKõæ1$a»ÙrL±ÿ@pìg¹) Š5ûf ñ1FâdC0" `Ƙ‚è=ö:o¾‚3ðÐñ¹šóx’ûͬOs?Iåì#¦l-ódc]<1Åm)Ólùh‰)ÌTSß-X* 9‹L –i“åw¦«ÛÊ4{—75²èµÁÐZàH™2…ø_[=ì«ÁË¢g2ö&DxÏbYUê Õ,-ÒÙïü0ê±h}náRX)œ–™EIÇ ì°[GÐ-î‚å#æØló½fpPG´È Ù—f`€´àíˆðv¥Z1Ëý/Í™‰Vè©•˜Æ6U}•T¦õ[/ØH"1ëÙH»îåàXN(ƒ#DCðFq`g™TÉÆï0À4%·îýåŸ:ÃXŸ!, :ìÜ31K®²y¥MÇþc_ˆÆËàhj¥LH Ó¡Cð\Ä`óK…|¦Ï´ÚUGƒ†Œž*•:†R'´{ïÉú HÅz¢h€pg”Eÿc@ðSQWŒèÐ|sóŒÏ¦7cÎýç/fo•Þݾ¿¾6¦MÇðóc²Jœµµ¹°AXoËRgK¹p³k³²­ûÎ ¹¯Ó†71‡w¥Ì­ûúG Ò\N]ô>á,*PÀº@_Ž™Ín FR‚ðEg‹:èi%“fg]{Ò²¥5S¦²®[Õõ©1’rk*$SÙ–vÄc²^Ï“TÁùÙ‚Q˜òÁË‹NO¦*•ãïU«Üê.ËtäMÅqˆ~ÎËb@|Ï;]µ‘²Üæ©e,Ð*”uÆD4…¬1“å;ßa“ìd”I]·¡Ö¬ªb{·Ú­=:ŒÐýˆÇñ …AgD#Іû¬*ò xÅldN¨U=™¯å±¾a„:ܧ҈§YƒƒòðçøœSÄ9ý—XcpMQò‹iÃ1¸Ü¡Y*¹Ì èÒ•C«¦ãŽiݘÖÃJ³±UË»-Ï*«,O³2¸nj)²v¦è¾Žbu ~š<ò§xQD]ÓÇcŸ\DàÿiþôCúPªªCj}.f;o?uçªK·»”Žš»Aü jŠ~‘Rm8ñ7+mrËÓþ®'BúÓ¹$a¤®4£¢ÿ-—ì»÷ lèQþÙ_cn¹Î­÷´0‚¾¢…vþíäp¸ûµ»—C<iß§0\Á BB——öî¶ÊOf·ôxvu,äFñÚ÷/\R׋m×_-Ùì9ã¬åýþ/®n­À¦~¸ð²ZöI-s•~µ<ÀK`„¹“àêüJШ¿3¼;çŠ[Eûoß_]™j%U­Kn:ZÛ‘iV2¸$ÃSt CôK@US¸à©7’A_x0î뫉Ÿª¹bðüÙÚf±4¸4‚kapìuÂsåCþÛ@ÒšÝï=¡Ô»[¨rر.P¿ Nç(Ù$x„[æqÛ¢Qwt/@÷ Æj †‰CÏÒdÆÓ\æLOæ‰aÒз¿L@X7+3šä¦GnÊæÑtÁËi½iG皨ÌZêVæ"iÓ«œRä†@ÀrN«„¢þàgc¥ãæëªh^Q©ì¬šwÛʾ (W@¨Ð}´3’mm'ë¸RúûÙ¡ÂŒÌm;»Ë‹Já¡ýǘ™¦ò‡žÖز6ýe%k° šàBùE á4*öš”˜bxa(âvø2Þ¥ç6™uï%çµ$í‹w• ŸUµùñ§Ÿðù¤u§} wÏZ5fÑØ=z;Z™ÅP…uÒ4°3ÔŽ=K$HÄüô÷)Ýw/ªôìÃb¯+Q„Qá?_%¥âùcûhÆ.”³Yì?/6êïh¹–í3nþ¢.í B©ûöâú•}hÈկפÑ?Z›Ç£Ãhÿ:HÏ endstream endobj 5010 0 obj << /Length 1720 /Filter /FlateDecode >> stream xÚÕY[w›6÷§à÷ÔŠ$ˆ=­ÝzM–u‰³=´=>ØVN1P›fŸ~]Àã4mvÖî%Eúßo?Œ½+{/&Oç“£çŒx J"yóKr†hx1ãˆ%7_{oýã) }Q/E]6Ó¹ÿ¤ªòl•ʬ,ÌÆ¯bJ±ÿiJà`^V¢6Û/¶ÙZ<6ë3‘‹´æ… J™¾Ÿ¿ž<›O>Nȃ=âÅX3ãØ[m&oßco û¯=Œ‚„{7úÔÆc‡gîOþ˜`« FTÀˆF:¯†ìmži­¸Œp…?ÔËpÑéF,ä”`¿\TuV¬²*Íø3«ž(”¦¡ŸÊ)(n6Só¸Üæöðà®"kÔå¦w§Ñv;f+±;Œ´™:=;})æJ©˜Á_Æ#£ïpô=zEŽ²Ø›Q¶]E]+—õbU®EßÑs°Žc* ŽÁ¤û†r€kèÜ#dK’öâ;bÃæ[Õ!N{b¬ÊBêøû, ܽÇ'a{S]Ó ô?K¦!V;"#í«Z_§µy{t]š*•ïu¡1'¤êÌÊ<#%¡ë·¬½K[!JâV[y[=T•¶AÜ3|Ï퇉( ;«?ª…„k:ÖáîH¸0‚‹œh!ãIð…'P \CŒ¢$æ`I õ*­ÓM¼§ÿ÷ þ6+Þw—ºÞ™H] ÏÌ•“lY§Fá[—ˆŽ<«ORKeFb”ÁPC‚#ì#¸Èé€ýËÒ Q'xK§§''f%KóÜêR ‹¼\éÒeØ2#[¾nHËbð3H{Þ/ƒ_#ñ¾`$ÀˆGNá¡XYž:¤”ÀaXÉéPr•3#‚QÓ…´-÷½ûƒP4úö*·Ò²­Ußê4 6æjU£ º'¥R¬ÍkÕé®$JÈÁ7aЗÐë“êH)æ‹"< æw”à» Ì;¯aÛÕJ4ÍàZ_j†QÈxß›ŽÔÛºøO$>Võa73…êE=ýº `Õi‚àH†}nóëL_L`’(VvÒ‚7¨Ó@ZAØ’”ö`jãÌ­×IÁÝňN`ìª`»(ê‚:-Ö#Iˎࡼ¦SAWï¡M•c¤à'‡{É~ ‰ºRa ‘ îí Ü*F1t±Î%µ²›Ð÷¦TÀxÓUO4Wc`h[[ò0ù• óKïÝd¹]-…q°ê;$‰ú ¥¼ò¤QäÕârÊl}ÃþfD˜Éã°oú#×£?Ÿ={ròÛˆVØÒ¤SëæZÔ–¥¹¡—*ÜÔs-¤­¿›L«©6—Êv·f­u¥1\´-aQ‹4ߨ±N5k0K¸ÿª07šrcù­4­Ú™ ½ëœu¬³I-K•+KÛäµ]ÔâÒI€º-¶Š¿ØTòVO ö$È¥Gh5ùö3l,fÔ ¸Ó˜A!«8ï†È´è‹Yíâr ·qqž—Jú›¬¸úéK%Ù­JàE~}Qê=>{.Nç‹ó³iú.^ž«*5WPƒ)-Ê@]žý-³eĆÅõn~€‹-‚a °Yûž—åPʼl«í ³TµE/Lé–e/š„hýåDD?Õа °^ïÒj?ÜR§Ç§ÊF¿OÃÐÿëÔ81….TÉfàZØsöÈUfªuaG£<,Ö¥°Gв…ŽÌN&Môκ¡Ôél픦“ò²bQ !vDRÆb^•kò•u’’À)(E+¬}vzµCda> stream xÚíY[oÛ6~÷¯Ð£\Ô,oºí-½¤K›¦Y’bÚÀm:&K®.ͺ_¿Ã›,*Nœ% Š{±hŠ<ç;Wò³±wåaïíèåÅèÅ!'^‚’†ÞÅÒ‹¨ññ„y ï³ÿ~L_T3Q•õxB£Ø?Ølòlž6YYè‰×bL±ÿmL`a^nD¥§ß¶ÙB<×ã3‘‹´ú A”"2¾¼x7zs1ú:"{D«æ(‘7_>_boóï<ŒX{×jÕÚãa ÏÜ;ý6ÂÆ Œ Çˆ†L®‰WÁ‹“g·L0Â,ÒÿYÍ‚i ¦þ&­ä£Ó"]‹©2ó¯F1ÑWà„Îxi8öÍ%gSeÅ<Û¤¹ž«›ª7­’jœÑŒ öËîuV\éqZ,ô ÅU³BÊ]½ÝÇÒ¸ˆÃ'Cm÷pì~q†=£±7¡|ôlU%c]VÓy¹޾‡à¥žË@8×:guŽ'ÁvÐôvœ ˜ÅvÛ`­ä¡Fˆ2â ˜—E£"¡ôðƒÞÞFŽbÂíN¹IŒY¡}þ8@ŒÁ Õ2ÂM/î@Cåm%ltB™}²”ìÏ¥+™™òÛ³gÒã ·7!Q„(‡'AI`BÛuvUˆ…^žÙWg‹AŠ(Â4éňìN¼=OÊzR'”Qh) ‰yi•®ñžz¹|ΊKcºŠ”.BÝ*FIÔAŸè-ÇÙ¬Jµ¿÷…¨pû¤F ø%Œ 8AêQÄêOîÔ§v Õ•mc4ÊðîR!²-A£í\ú¦±*¯ôd%6•¨EÑØŽ såÒšãÀ(Õ5Rºé6£¤> stream xÚÕY[s›F~ׯàQÒXë½° <¶IÉeÒ4±Ÿ’ŒÃʦ–@åbWùõ={±«žJé$/-Ë9ß¹¬±wãaïÕä×ËÉù…O¼E‚ ïråÑÐG”E^à‡È˜w™zŸ§og”Oey-Ë¢š-hNÙn×Y×Y‘›…—rFñô~F`ãºØÊÒ,¿j²Tž™ûr-ãJšQŠÈìëå›Éo—“¿&ð`xÕ> pà%›Éç¯ØKaý‡‹BïAïÚx¾áºö>Mþ˜`k FLÀˆ ¦v â•ðàÑâÇ1«•V‚f1ø®¼æËLãÓm\ªK%—y¼‘Ë/˜ñø¦Zjsÿ®1 syÎ蜠€§vƒ–·-³<ɶñÚ¬UuÙ$u£¥[§Ô3‚§E÷8ËoÌýJ¯—›ØŠ{Èê[sgá íÈÎG(•ÙýP Á#çBôܽõÁ[¼ç Y–* Šr™©tô_€ÿzÎáœî¸ÜغpµÖçÐÌ{ï_%Fûî̱Ñô_-áÌÄ’y­dô÷Œ`aÿE…ÄoßT/Éãñ³ã1·lˆ¨R®{rY…¹—°5yfßS•ÆÕ/m›· A€¨W‚"Î[§ê”±[å‹[•ãê×|®"d5y•Ýä2ÝË4{ªì› '(ô{¡#ãIù/WÊzRÌgHD` ­Ñqoéž~¸–~Îò¯ÖJ?S±¹kŒ¢ j‘/Ì+ï²ë26ÎÝõ…è$°æ;@­ð9Š"pB;Ô¢€ Ôpâ:ªO¿õ„:äe,‚êj»Xw›Þ7»jµMmÕ¨lѳ#ˆ‚ŽOÐÎÖÒÜW*ëêÖij¸šùªËéEÓê`±Xµþsü1Ðî‚¶ê]×ìAïó×MöÅ#Ðߤ ¦ÑS¡j+CÃÐw× øAë?”øC´‚êŽà -U?º)Ü«®;è=Q~?´áa~¡ì&ÈÌR½[£›$‘U5xmàcŒ¸¸‰ÑCÝ”ùÿ‚ø­*ê=3áØ ^>-‹²­ÚTÂ|\0Ʀ¿çm¦)Ÿf릔ÃfVL%mÖ…¹¾¿z÷ζþçòŒÉXŽ|ݘA£tˆFµ¬³,Vi¬rkçŠr¦J%ëñ+KníMµS«U ûäÆ>Ë6ö¡N[¸¶¢ÁKÇ2ËÜ*™˜›8OÍͦ²[*(·¡6¹-’ÛïÄ7ÄÉøÆÞ£»‘Q#T ‹“²Œœd(w–o¶‡0 x7 çEžVGâÖÊ1wð`ôމ” uGú|“%PêÕHdy„!NNBHsП•…ôf_ßsCBŽ¿ªA3­uoQ ±mULa|zæŠ6ãÚ´ß©þ@'/JÛS¼BEY)-žÆRŠ#à:‰4ŠùùÙáƒ5~êÎN2Âé÷áæƒ¦¡}Ì—·íÐ^5yb$àW)[†)UîUÑH»ÓŒ3•µO¤ŒKúÚôÑ?ì×w_J¿(Ø­L2 ƒ~òH¤¢ˆ»ˆÓ?£|#óG0ðcjaÏ"²Õn7õmªh5äâò.M–YU52uÈÆ•zš‘xÐÇñvÀ öâì1ÐËÅÛ—/^÷)-E™}ë µJtÒpïøÉñÑÈ×.ÐvÂéÂ!ø(‡hSÓ$Ø‘ðĘ;Âïäîz]$ª2î2 ŒÚ±­ù®÷a;>Lh 0‚ÁÖp!®ª¯éØ„ ßQ—ó8U‰`òàH$¾{õ¬H5λ÷æK©>–ÏŽuV †§sÖ|ÞVÏHÉÀgyÄOÏÍ…ˆÃ,øÙOˆîô|2u1rl­?¢g0â»qׯ«±“#Àe\ò~–h„‘ÃAóWRtó73·›z|BB8_Óײ;MÀe¼ÝvmÖm5?Ågm-ŒFŒïkÍ"~¯‰Øp¸+Ý!ÔØ9“jî-QÇmêŽÄWé| k7€¡°âÈÐ"2„|¥üã8I/¯3Û-Kú¿_ ùÀ¡âÙÿqýÿ‰O5£×Ø"h¶~¤›‰¥ ^k çs¢ý¿ C`ÿ}åkÍ endstream endobj 5061 0 obj << /Length 1718 /Filter /FlateDecode >> stream xÚÕYMsÛ6½ëWðV1c!€äôRGŽ=Š3Ž«¨¹8-B6§ÅRTÿû."(2–ídÚ\Ä/ûvñvñaçÖÁÎÙàÍlðú”'D¡ Â™-Ÿ:>  =g;WÃs—ò¡Ìod¾Þ¸#êÃã,[&ó¨HÖ©~q"]Ї_] —ëLæúõÙ6‰å‘¾ŸÊ¥Œ6R?D)"î—Ù»ÁÛÙàŸ(Ø!Ú4C>öùjpõ;1¼ç`ä…s_¶Z9Lp]:pÓ /h¹A0ž¯Ý˜Ý% >ó‡‹m:7Ø™nS×ÃÃû<ÊÌç(Õ×ã“ÑùÉx²Ùle¬›FÛâ.ŽŠíJ7øŒ9ÞH©¿MOÇú-#ë»l˜áˆ"(ô!•™Xß|u=_xÀÃä3ö˜Üè.Iam’ÛÌæÒô¼UÑŽ’t£^¨0¾>¢á;vF„ síúßòA7²D8 ˆŠdÙ¹#Ï#%ãO¢üV – –±~X/ôµ¨ZZQQ+™úA‡œs ðKSiÆIÒà”ˆ{aÊ€ØÇNò9­š iÜ‚¶›Û¬2»LLÔ,gŒQåûÓP§ "8´£cºõ¸û.x> ¸· ¿J†ŠÍh„žâ¾ Nö^NÏtîj«´„b†…ÉD0,$œmàɆœ«Çx8 j’t&o7edà.ÛÞ@QÐ÷ ÌÍéE4F¿À=‹×”ƒ¯¡áu~ïå×sÈ2U€®³iP…þéË~‰ûÄŒWö€åŒ®ëË[}QOì)”«>ƒ_…öË2 íì¦ "ÄQy®p¬sˆE,-{¯O¡6ê" ŽEÅ»f›áÓ$çÍrA[X§¦*~ÚÌsÝ€ŠèY0BQNÑ·¢å€•8œAÝâUOÕIª ú­Pe€cõ¦Nqõ¨îïmÕÓ«4ZɃVå5Jçûž32@tÒ Ç$—ÑruôÂ8ÁRéq+RÖ<õÅIPÄën¯2³À¤ó޹…¤œ5¦–t3ö‘+Œê5Ë¢‘¡ÂºB„ˆY‡³(VÖðŽùlò*I¿ÔQ/J}ñ­è(££Ð¯Y9Ò]Þ'7y¤~hRÒÄøo!5£ŒˆB¶(Ît˜fx´L—…Ãêc[2´%¯m Hl„£X×å-CaÈzL6Ûé¤îÜc:W¥MѵËSÅtÚ2;- _Ý¡å¦îaÛZo c¬$p—¡Ñ =›e=-;UÞ£þcLôU¢ {~µÃê§øª\é†bÍe›"\3Å8ö™ü½L1½ã ÖÎ|ÜÎaYÜü®ŸÖ Y´w÷I)’áñþ\Q·¾p¬—0P'ë¼âv¬Xg$8b¼5ÅFøBÃ†ð…§›m²ŒÍ—¨CÕ!¢æZߌQ BªV‹|½²I¹Éä¼Tµõ~A™Ž´lPž›W·‰ÖÁiÅeEålÛ¥n‰Ï@mù•M•i¨ä>ÖÜÿ#Wª¯‡Ê!AA@,Ù¥DSXê+nUQ–ÜE.åµÍ@µ=­Šµ 24ìí1$Z8ïïêx˜EªšÊÔX[®Ó[-@Ì{)cÁñ\™5"ò*1Tpø…‡Sö3ÄØb¿˜Ø2!üõÅÖ‹ðÀönÛˆt&oUU½]>U™yô¨ì«¾”©O|QfïÜjí×=VÞXôš“›@±[%˜Š¢ „3"*8LDñÿ\Díé‹Þ%Ÿ"_ô¬ø—{+þžÎ({÷ÉŒ>á ?ô{T”]ãsaÓ¿iŒfÕúó¬Ö·å²ZÒê3©6ÚµT~PÕQ™x2TK þð†­wà¿§kkÇË^ä:¹žùp-HamkÑô¡[Ý,S#Ýïù¦Î§oøõäâ“KÀ½ã÷““ëËéäB‘d<¹tC ï4˜Iyff¢ÄÒÛJ®ƒ ÓçB«Iùpq:9ƒ[ýböáòí…†0ŽR—áaÉ#ÖY%™*y¬È’Æ}bjšjp»Íú´äמsvF`(ÊA/‹¶yz(ƒ^4«?ks°‘j‰)d½?xd'ÖV» xxØ­KC’Bšw©}صҦØï‰¡Ý†à¨cØúîTs³Ðu2Ë»ß<\V uœWƒ>æõl|oßAyó`Û©íÿ@ xêØäÀ¿@:ÿÁu‘“t‚‚ „yb8¾‹2W¥Š‘æ ›rG‚… ÛWê`7Ú›ú»>î]˜jƒ6—–Þ?¾œ‰žš“à8*T˨xÈZ¿àè¿"d~ endstream endobj 5080 0 obj << /Length 1243 /Filter /FlateDecode >> stream xÚíY]oÛ6}÷¯à£5D ¿%mÀtkŠvA·%îSŠM7Â)“”¦û÷»ü#*Jâ8M[`EË¢ÉËsî½¼‡dú€z5y1›ìî Š2œ)¦Ðl‰X*0ãJDŠEÆÑlާ¿GLNu}¦ëª‰b–¤Ó½ËËU1ÏÛ¢*]Ão:bdú1¢ÐqU]êÚ5¿º*zÇ}?Ô+7Ú½P̦ÑéìÍäålòÏ„‚(JL-pB4¿˜Ÿ´€ö7ˆ`ž¥èÚöº@B¥ð\¡£É_â¹LÁLqÓ[QT÷ÇX›Y)Á„'Žðßõ™|Ÿ/Àø4Íûyua¾^æ®ÅqˆÝã×±ßÚ눒iå^nû¯g[7غaÍc͇‘Ô€N|ŠT9>ÃFà³»¯T A1ÀUö¸œU8¿ &ÚÝÚ7Ãd‚S^xÀ³vÚŒ†¹do%+ƒÈ:!’¸9¶/!û óªlmV}jèyÚ'pJE7Ò Ò—ÓO­I>ILKcÌ´O„—`Îå-'Eœ˜PÞ PÉ5µÌ(ú™±)LØ6Ðbù¢$C1¥8“²‘Äœ%Xeªr:ž¿<Á* S0ÐÔ‡¬Ë/ëÈþœ„P‹òtíÊÖV"—-Ü%Y‡D`;2·PÁSµþz¸ —}i+÷<Ó0»c¨œý{@±qPB@ià¿x$š£¬`©ÄãdnâÚ”Jm>Ú«º5fDÏ g˜ CpÂ(¹/ËAÏÔºPÍ#)§ï^:&ÅÒ3<×oí™›Úvhò ½Ó1!Ó½ƒ#o«‚>.›®‹Fû½©2 d)V&>Åœâô.iªêE§¶q'´‘t®tZ㟶cQ~ðoK/Tç^±šK=/Nz±±F \Ü)rP‹Ò¯Ÿ@g(Çã*ãˆÜ®7™ÀT$߈ÄÈïó™ }Aiᙂ] èƒÒÍèÿ][¾´zl­ü–>|4;é|õh`[h ÅaÖÕ~ØÚCüªG(Å`ÊfìæÜ^Ê~vóͶ…®ndýÜ „êb÷œ`Ù ,H¿Öyk•îNÐϪ³Îëùy ´G½¦Ü=VEÓ†ȨkZÚ³a ¼O~¿ù¢÷͈vgXÐïÚ½•@F‚Lwž†ô”Ý,¾'à üé#æ©ðJ©ú Aê` ¬ûò›8<ÃÑÑÀáþì˜l¦ïê«ë;Ú1%X¦é`ê=ıã™]‹Æÿçî}iò¨ªGUß¾Gö[ÒFÂ!·èC¨Ö¹0z„¼ÁªýžÁ”ˆÊù·ïÌ‘!§Dbš¤wn ¾îÓÕô@‡½:þEÙëɆþóÕªsÐx§Î´qßOŸQíͪ)+öJÉðZ–&@˜®eÅײö²5‘±Û¼¤Ûˆ¿5Ø+ýãH¢± +º^y¯—>“ûu.s"ïz^!Ó±Üå+ÜæEéÝV•+³Éôë9÷¾´Ó¾xýÇÑ`ßçCRxç_«U˜ã­Ý·t[â&0[^u½»âM£¡ þgÙc£Ñ=[ ŽLm|ß>z{.¦Ô×3…)Žb%2+8þÿ¾¶Ê!@W2¶>B*,( ùNNÌ… endstream endobj 4970 0 obj << /Type /ObjStm /N 100 /First 973 /Length 1972 /Filter /FlateDecode >> stream xÚÝZ][¹ }Ÿ_¡Çnd‰¤Dؤ-ЋMÚòÍEП˜L€í¿ï¡lÙ™q¦ÖwÆÈæ×—(ꈔ®h )ˆd ¬AT‚6ä³±ZC®P°–'”‚TqCÝþ‚FÜ\¨¡i½‚ !'ô©¡£BÞ…L–a?1“[HèFü?A †¥ôî ’ë›``—úU+°ÐЉy'f)PÒ®—Qr FXÔ%$Íû3 T -Z…Pœµ@š\B*Ð’$šÀ‚AjTBIÉYíœ1TH90iÿ žsì8pÁX!•Àp ÕÀz lU!e€ÍÉG‹Yª›-š#|¢ŽÄ¥­UHŒŽJrø".¹³jN.Ÿ¶Þ/zj­¿uƒÄW,”\Ì¡Læzè¾;b`•>gÉÍKa·FźRÙÕ„CÑmõÉ'XÀàjænÁB%u ˜¬*Ùõ0EuëF¸l}Óµ±cçªU‹àÓœÜÜ«ä†:E\eØ´ôAIZ‹ÛT1½^ÐÖ‡ÏhC(xG­ŽAÀ¸ºµ>i¡¥­>ARwB¼Qv£ÀÚ¸­Zé‹xlµô·áæC3òa—,õAT FîArÁç„*„¦nâZ¸!8\]‚u7'L‰¸„¨·Òú[4UëÝj@»7a%#zȘ‡‚%œ—tõâÅÕêûp-f)üVÿÇ?áLü§póñ—_Þ\}ýõãJ)Eœ“ŠÌ=ÂO+¦Ý‹÷_nnî‹aõR|`2z“—®rûä$C˜áÝ»¾:Æ“S¯•Ý;ÄjFãÝ“¯(,w‚ÁÕ·›w¯Öwá:¬~øþeX½^ÿzöX^ÿ÷?k¼xû¯õÕê;àZßÜ}ð%˜½ýÕêÇõ‡ÍÇÛwë[6ê¿ýmýóû·ßn~ ×ΛþG8¼¡··híe«øÍÍͽ]oÓñtÆÜ 2„:ÂÖ!0öÞ®V¯>þtןÿúþæßW«o7·?¯o;’ôfõçÕ_Vß]çþààßaØš1U—¬Q³“lŠÍc†s¬Zßô©xVÚ¼ÞÌâ> ÝûÍÍ£Õô•ûp¤Im„©Æ^Ÿ’AÍË!áš`±í‘€m£:ÃÍ ÁßrHvsÃ Ë ¤5æ† ëð9'§ÖØ@¶ S޹”9$ ÏN)±bP„-Ú<ªŸBéœÔÒ'œ„Í£hlàécòº§ˆ%RÊŠ\#6»ÓŠHH¢¶ =¢IÊ|”úŽHr’\ϦL«Ç”ir>e¶A‡­íKCÈC´jü”Y©DN¶_–‘H¥^`Y$cYN!YvYªª-6d™Zd' p§þ$-/„œµ1ßÈ©cö ûJvßøÂøY©*a Ó=÷EA’6…Ár@dR÷H I4Ôç é|de’2ï)b‰ødØ„žH$n§…{òi=6‹šÚ9¬yO.’h¢8KY³{g²f/OO¯Nw ‡P†P‡ OAŸÕbF‘µ§OC-Àz úlŒÔóÕT, IÏJ{(;§p¦XP6:´Ôè„SŒ$-.X¢|@b=ħù»ÔÈê$ ²ÌÛ5—ào–²Ý:vP„9vŸL Y4ÕÛçá†I9P&æF3_âÄÛr`€8©]äÀ`‹D„ciyÉç“h’0ï)>F˜•%ÌŠB5ú]ÌiÅä‹B¾8Â9&L¡ó “tá GôÈ#æ‘ óÈ…yÐ,våÑ~xô##¹–üûäÛ†ÒºèV+H/B·ŠÊšÌ/~‡æb|+H¿* ³19"`ù9ª°Æ WŒUü¤z‰u@aK‘©ÎBÉeÉ“Š~§6 ˆ¶è7~SP­«v^Œ¨«GœöE{Ö£|N û,'‹ÜüÚïêšß‹Gjòœq‚­&6på€" >ÒI$ ôå’Qì–Ò¯æ#¶ÂÏL'rµ¼d¼‚À`y<Ü2‡dÙê{ï“mÄî\’­y¸ü&—ô´Dx2mº§øXÚôPéÑ´é¢`Ñ E¤bø¨P¬– ›}qYXÍÇYX±ó³°22¬22¬22¬22¬22¬ò$Ý +*.ºkΑ“\ 4*†?¹µ VÍϺSçý›ƒávÆNíÐXì‡}ŒÂU$WT®§Ê´§©\ û%Ú¡tEŽ™¥\¤tÝAÙ×®3P>W»Ö4IÂ5ÍÜÛëIŽéÕiÅ\±Ç×ÓŠlÈôeBO“×&SüzöÎòüÚ>s¿£s÷;h\Žøµ­ƒDë(Së(Su”©:ê^¬¬ƒŒuœ*êèPŸôhw]> stream xÚÕXKsÛ6¾ëWðVªc!¾z³];ã<×R$£¡)Øæ„"X’²ãüú.¸ E0²ë¤É4½ðb±»öñÔ¹v¨ó|r´œ<;̉IðÀY^9!wB{Îrí¼s_N¹ïÊêRVªžÎx¹‡e™giÒdªÀßå”S÷vÊ`b®JYáðóm¶–ø|!s™Ô_ᜰé‡å‹ÉÉròׄ)Ôa¨Z†Nº™¼û@5Œ¿p(ñâȹkgmDpÏÅä 5nPÂÀzJxàéÙs*øðÅàÅC3J¨¢Ã«K•乚2êÞ­î¦àUòq•j¯|÷¾„÷FRú=tgx;ìôkà67Ç ,Ê*-âVUÖH¶¬Ô{ê‰\j‘_4ƵYôÉÖä0ÐdÅ5iñîëã4Òè„®" ¸ñ ÷ì4¨QgÆ€ê@'´CªZ¥ œê{v 00‡Å)ìÍqð¹/¥åA©?cÌ'4ˆ;¹÷Ô§¨å[½ð ÷,+RU4í~|jFö{ÑPNˆ‰NR ɩ统šƒgçÁ£mÑ¥R:Å£Ö„$òz)Y$—¹Üƒø<¶?$þá«zƒUgžA~B8PsŽ‹—I•l¬ÕÎHÌBgÆày—tœR!D8â>v–ûmŸ¡È«ì²JtØS÷~¸H»Æ}ËP³ÊŒ…$ö¼±CØ,å"„ŠÄGÊÌ®´/¤~rý(˜c[‚˜¬³Å€Vé¼ms½¹Õy”ä{—„¥Ä0d8¡c¯ÞsF (ï»,¢>Mò»VñÔÓ˜ÂSÝE XìûféYÞd5J_m‹´«qëìC»š™Ñ5*ˆà¬Â{+q«/‹î­)‹´+‹ƒÕ¡ú¡}ù›Ën±Zš¢áé¹g ŽvÖ–f鉟,׆š(ºš 0¦Â—mm”^"&hÀÇ\uõôÉgÔu ~zŒDVÏ)’\aõ^å*Mr=€-s†·c­oµh{ƒ_¼•UV¤Y ¡Ó¾îè›Ânn«b7ï§oÏš=ª–áÿ ÁÇÕmÕXívÿ±ä×Ùß÷®Õ“…É“¼¨³Ïr•˜û, ‡ðµŠwªQ¸IL¢üúÐŽ—Œâð»wÎbq_?@_‰þ·m'ÙÁfwë>7åªOqÀn©5 < ¶ßá}n‡X¿,Õ‹2I»ú«K!v¨,o›¦‰cÆ0\#ˆi¯w#ÈXæ…m©°­UÛ¦7w?J>#~ŽwÈÔµ¬ß[èÒž¬ìžs)û.ò\®‡ž<9CrUü—½<õòÅ6Me]Ä,U3”ûvU $º4rc8”iܪúB·›”ø"´•ÛVÅW£Å¿Á…—:ówG[Ë.µ×²ðaÛ|vµ'äcÂ"«ºî‰[“hßÖJ¶ú}·P žSe,‘u©Š5~Ũ 4•êȈßwq=ž¦j[4xô{yqä¯^ÍõÔÃ×'«¹vöÍòâp¾@A$C¨ÀÛºRȵ&L"Þï˜'|DÁ.™.!ÎqØ÷ͬîì7Ôàp«ÐZ»@[¬ç}¹×¦iµnë¸y3?={Þùy2{º8ŸÆàüTŸØ pä´6…Ú{ÛUŽì¨Öê€JV ØSáxsÓ’Zõ„²/Ì<Hq7ʼn1^¹Æ§žXÂW8ð_Ogà ´±º×ј§*)ê> stream xÚíXIoÛF¾ëWð(ÑxVrØ›ÄA³Ø­¬ ×0(‰²‰H¤JQNòïûfá24%˱‹ i."9œ·|oÞò‰Ø»õ°÷vp:ŸqâE( hàM•Qy!—ˆG̛̽«á{ŸŠaRL“"ßø#ÊáÉz½Lgq™æ™Yxøï}—ù:)ÌòÛm:O^™ûq²LâMb¢ÿzònðf2ø{@Àì/¤`š£‡Þl5¸ºÆÞÖßy±HzŸõ®•Ç ×¥w9ø}€-Œ@ÀˆLíˆWÀ‹‹ã>ÔÊ*Á³ÐþTLÅMœ8õu•o77 ÅË•ñTaòŰÜ6 q}m‰š¥Žü<.ÕBŒtj öz|ÆdË=ì(ï…ñn–gèÒÈ"Š¥røå20¸»‹c¥5ÚGÍà5å dð*vê8ÂèªEŽÔÖã3ÐÑÚ"éêT±°!Ôðµ @idæH’ ’ú lv9¶ä%©öÜûL ótÁxx®bgInN#¢¥šôü±+he-­#ID#ç‚QD©Ñ¾Ž‹xå¨÷(A a?\…=¾suvµ·Æ¤ö‡(b¶ú&wéÆà\l³™-9x*H<¸ÅÃ̾¯#ÎJ³bó"¾Õ%l˻ؾ^mm"é§,·7S»qQ$ÉÙ¨27!µ‡øebâå&ÿ¥v½ŸŠ›}jç~¼øãòfüæäÃÇKµ2Û´>´œ;µ ¶AÒ©äõzž,âí²¼™æ9t¡¬§ˆ‹´ÕÂl›‹#£ßÇ˭ݲ(r[Ñå]%U[³¥¿IfM£ÌæªCp`‹'u€ “þ sáVàCø=E‚ŒÉn~{{qêUûhKÝ/å¾&#T7à•¤JÜ/å«N–ÛGuæéÀfñ*y°÷YXÔ%¡Ïꕺù=‚´©sæˆéöŒ£|­RÈʧUyñªºÖG{¯ï 1»›ÀtëmßÑr†¾x“¤’¢Gp£º |R“¼J³ë:X¥®L“5ÝdþF•ë##ò!±i_ÛJtõ´³‘Õâ4µÆ›R}Ö#ĨìXw¹‘ꫵpǪ‘vZccµð 6ÓÍ-U"´cw¬[¼a{¬ZÙVóµ2«}ï1"ðŽÙ‹uƒ´ÌÝb2;™©ãû¤~’y¯KFï—T’“n’÷x†ˆD¤ãÝë¦BÌB£Áñ¸5Lmù,ª¡hGe\4öu5’}AÛf½¸¬GnZåÛÒ9aï½À U<ì;­‡ÒCP0cŒ7íB kÚª:g±ëœGD†HJq1Ô¢ÜTä"©«Æ-ƒV³r‚Wô8K$oÙAÞRð×ìq 1,-¬³²ré6Õƒ3ÉúÃ#ÂÚàî’gÂMãl~Ü œŠš1\ølg-S«;XÛ±"÷4žÊ¹ZL f™´O³[5ó›æÿïð¯ ð¬ìöIô«-ò}Ù—x&û²Hz&0Ð_˜|}3÷ÿsîíã^û#°u¶>JË 4À¢§e þø‡`é?FËØOZö=iýAi{YZ¦?a4#õpz„0Uåô øfÑOzöÐ3º›žÙ5.-³Ý¹ûÑ7 þfÞûœS8SëŒ\äiÇì7ÿß~ÕS’‹@ó´! D×±Éù  endstream endobj 5132 0 obj << /Length 1499 /Filter /FlateDecode >> stream xÚíYÛrÛ6}×WðQÊD0î$Û'űÝ&NÒ:ÊLg†a›c‰TH*nþ¾»(‘ å[â´É‹@pö`qv—¤Þ¥G½£Á‹é`ïP2/$¡æÚ›^x>÷| o{§Ã×#®†&?7yVŒÆÜ†“Õj‘Ì£2ÉRÛñÒŒ8~1xp‘­Ln»ÖIlžÛë³0QaìF8'lt6}58˜> @¡³KKâSß›/§gÔ‹¡ÿ•G‰ï¦zjéI@»ðÞþPg% ÐSµÀ§5ór¸ñUçÉ.ƒ%TøÖàëü\Í¢uy5›gé쌳ò±m‘“ÖÈ6­±åî#3—önQæëy¹¶IeÿÆ€!œˆÖ—ð+m év‚!{‡Z7¬ Þ˜K0R5Œ0yŽ@³ÐĦµÞÞ!˜Ýà&§ÀU?¦ ªÆP&ýzÈGª¨]à±(ÂE @Å ºÐ׆.‚æ8I¦ê‘8ÈŒ„Ο!ð²KɈÑáÕ}¡ù>‘¬žaã^¥ŠI›”²~¹£…YEcÖ±Ð,ÿ $äÜN¾ŠòhÙšÝ㌄ cÐ*çF§Iz¾«¨#Ö:s…¼½ 0µÖÈÇvÈqržG¨tø¥9IÓüP7˘ù$¢‹ Aà.¾"B“‘ CkÒr«Z0UG™ÙöÜØ?¾uº„>á@5À1£Ëü)?ãiŒ½SÂT²é}œÐ.9£·¹ˆ¶ÞO­ x.£ÅMµ0òð¯ŠÚµ¼±VD*Ù^gz•Žu:߆|¸QºÝ“lF‹Etƒ–T»zuÝÖ—$MJ„‰ œ(Þ[Í;R"( z…ür4ÆH£8®¸h)ú‘IMÕYÕ¶¢n­ƒ«>5¯'2EaÜdy¶lÅ—šy54v1 ›ã ëJ> ¿üßÄKË]Ñ#\Œ)B·¾÷}‚{t4O ÄÓEƒçöd$iY_\ľê¬2­ : ý‘ ]önJT„ß=š°@…q¢ŠÁÏp’Þ Œ›kÜîÂ'L±€}«)µ°¢ €×øcœ÷Ħ˜[¦’U™å}xÜÔ;𴼪 )…H‡ ÷ð½½Hc ð_ ”ï×ó9(ù¯ö_ûk ¼I —8[_WDoê!…°æY^{ðWxáUP9,LéúaqÛ…taû¢4Þð;7ˬ4®$ÙE ü›¤n³›âŹ Z… í鮯¥T‡›AçP½Åv°ƒ)¶0%´}[Œ‚n¼Ê@ÆÆìbkfÅÄE"TÐÖŠŽ_÷Xåµ-@vœ A%7Õ……€¨3¼‘„½†DÏíM’^¶½ß¥Ò¹Â2Iݸ²ž‹ÝJÜÃ+÷¨Ø 3ñ/oly𘇰;òá.¼Ù›×'/Ôl2ÒtøaúÛl7÷ÝÛéÁ_ÓÙÑÁÛƒ“ÉH©áô`vünÏÕäx6yùòÄ®òž¨t測äÑú¹¹EñäÀOÞ¼ƒfêÚÕ›ÿ¾??„ô:Çv ¿²ÂÒMÿÝ͸դž¹Ã¦Çfü˜ì†P3ß™÷cª=›_™:û†À¹^ÎP;u>h¯í)Ç,¾3ÌõB…s¹Ýô?½½‚x¢¤_?AÒoY»Þ°Õ“hjN˜ä?_=>ùÿ&xý…Asy=Ë1_5ŸfslÑ‘¡iíæ.ÈŒS¢å&Oz†Ï»’ä3âÎw–Ÿ=‹£2êq |rkõw«@$õ‰¯ ßP€¸¨wš­Ë³í«žR‚ßÊn‚nÄ­¹µV [Ïânš6ÛÅÁ*•Žú(Ñ-8ö›ëY6s<…—ë¥IˇU"Rô6²[‰„ze·™©ûåÄë{8éý "AÇ™s ­ “BÃnG«*(ªaýeGC"­e¥èÃßjaêì}û^ì€ßtÞþ€2ùã÷:Pº÷b• àë·/+St ý+’}Ú endstream endobj 5156 0 obj << /Length 1339 /Filter /FlateDecode >> stream xÚíY]SÛ8}ϯð£ÍÔB_–åîmC·……ÂÎΓ1‰B=Mbê8Ðþû½²äÄv ’ݾDþ®Î=ººç*ÆÎµƒ÷7½Îî>'N„"A…Ó9TrDYä„\"1§7tÎݮʮT–Î<Ÿ†ÒÝ»¹'ƒ8OÒ©yðNy»·ŽãôFeæñûy2T¯Ìõ‰«x¦Ì A”"â]ö>vº½Î·<Ø!NHajŽB:ƒIçü;CxþÑÁˆEÒ¹+zM.$´cç´ó¹ƒ­/p#*˜î-ˆ“Á‹•‡'m^ëY F˜…Æá¯ÙUÐçù—þ ö¯=Ÿ`Wy›{~àÆÃa¦[K…_z§ßgI…ó¢ì®fvÀf\‡ön”¥ÛÑR©ç5W0yîiC`ò{Ž ¶î.ܦXjßB¿\ ãvó!¸½»/DÅgìø”%AÅe•ez©Ó üªÚ|»û@R…10ŽÙV¾T®žéñ0iPFH€°ˆÊq8Àf–çz@´ÖPœiö¿ç üLVÇq$ /GêAÊc°üj3<ŒÁ%kòâAü|YZ"NJ %©[‚„£¨OÇ'ÃE|>€Ê§°a)õ AQ`£fggœâ±1±»9¼ ’Ï#¹\𾳓©Iš+3z5 F‚°J’ö½õH VY•"Æ"HS¸Šˆ4Öoâ,žÔÌ;Åë°Îäy2½„]`ŒÅ–7ÐëŽb…‹ôÍÃä*‹uÊÅ"d¬ÿ5¤ÖŠOB1ÖDP ºû`„bL6`ìé…‚±jš/Åáq0ÖVL:Ï-šJ„µà SÞ¤C°®À0“yáF§›£³ÃCs—ŒL;Ms{¡ÔP ËhXAif2(é ÊLïq:ÝÔ¯WbŠ&m'…¼êxÝóÚ‘J0EBuÎ …·pØflñjÆ£7Cé‚üÐn…Úb)Øxr: Àë?Ì] Qdú.™Y^,]:(—ÕH otëfiVÆÛPÙl±vQШ| {Ógɵª‚eÜkÓl½ê-U¿eüÿ´'o‚þž'°{Öû³ÿV¯ÅñQ¯ûO¯ÿî¸ßûðW×8¶(òdÎBBËãÉÍìAlfžÚ‚o ÚI·WÁvZ¬Þ­Þ ›Ü:§ÝÏgÝ# äm“Ç™ú¦ûÎÕt`ŸLç(ê^ ­¦tî*µëán~å¥bíÏ1­W8E„Ø0‚ƒ%Ê‚G…šÙÏIŸ>Û–ës?]œûEØö/ã1p{ endstream endobj 5178 0 obj << /Length 1524 /Filter /FlateDecode >> stream xÚíYKoÛF¾ëWðHáfß\¢'ÇqÒ&EÒ82PÀ ZZÙ‚eR!©¸ù÷}&iZ‘î!q¹Ùogfg>ŽppààÍäåtòâ5'AŠRIe0] ®OY0]§á»ˆŠP—gº,ª(¦‰ 6›õjžÕ«"w¯tDqø-"0q]ltéºßlW ýܵõZg•v/QŠHôeúvr4|€‚â¶æ(ÁI0¿šœ~ÁÁúß±T×vÖUÀ¥‚ç:ø4ù8Áþ@•ÌÌ–$(aàVçñ]&a–¸_–gb–më‹Ù¼ÈgçQLp¨#Ö—ö€æç»;Gܜ͌–«ŽÜ@}á•®ªV[·Ä,Ëâʵ2?ÅìîZ¡ŽÌtýOíG½²[òÎÖÅ<ŠtÁ² n5ÔjŠbeÔ‘pøåJ:M ;AS/^KÙQbÊA‹¢£%]–Æ;ŠTµÐ½ý^¼½v” Â1cTź¾ÔßÍjØRtÌ‘4ÀܪÏX`·Ç=ƒ@”õ0Xõõnûè™ê®ãHѬ4‹tÄäùÏáaÌ4‡Z‰Àá.ö…–$ˆ“FB£Ò‚'$"=p`&ëb ƒ‹íS¸àT%ALJ…w™gÏ.k³ÜÉ¡^ÎÀîö%IÇìdܕ𩬠ć€"ÊIßdevÕØáöÓUþ®›ÀÞúî:Zè}OÁ(MÒzì–ü¹:+3±½ò­k#þR/%& J"èXù.‰@Œ©Œ£xX«óú&|ÿŒ—ÕSlkæÒ¬µi‘¤ L>@ô©‹VPë;Í=ħàr&Äã£N~Ù  ?õ7¡²õ¨HŻב"ïKU<%ö bFÀá÷ç* ²§a+D@ä#ÙX*"üòæ‚?1áDAØÿ™‚à4’=¸‡pAvšY!•¦Î8ä&‘&¿ÇO0º‹qŒ…ê)FƒhH‚à˸¯£§%&eëk»±;´ªÆ}wQ¸$Ê`Þ*]W#é2¡ˆ§7qS©b¤Pí“@—Oh‡E˜—‹°(ÆYDÊ&ê¾$‚!¥T‡D@®w$Ânm£Ç-qÃ,j‹ž„¥/XÜFFÀä¸F<_é–/˜§7AîuÕá Öp,…àHy?"8~ŽEàýøp¡l]é¯ùöꬩçìM ìâ†K|5µˆ­Îç~°+ñɹģ3ºÉ6ð1D8ýU×x"R)–',ÌU^3º —ðqÓ~§<Ûef®Pz:ŒT0 Ñ\ý*c ÷Kµáƒœ[k|» ræ{¯µ·YSˆ`Î.èþìB—1~soÅC–1xÿœÇ6÷ÕN¼I,‹%y¸§¶åS ´Ù@ív¸I.öå®úaˆHrOj!‹öFdùÂoRêzëpç¾Çäx×ÈÇy IÛø±Ëë„)~w+"4Á)Ð7íôÈ)0¤!ExwüRÌ"‰Ã“éï³Cs°ï§GOg¯>Ì>}<9zoŽxxÔðG&²s×¾ÚVfÈ4ÎtãÚM…#-õ;äò¾,ƒþÛƒ-#Îåý¤¾h*)rjú‹>¬m¥—ÛuŸ ÿJ‚m¨ÜûŸ¤Ñÿ…8äiâoT°5áL†‡ÙÆP È×w€¬HS°âixhøŒ7kÝLpã¥éÕK¿~[:äIÕÁ_4Dhዬ63³úûÆ]îAÿ}¹ÿ endstream endobj 5086 0 obj << /Type /ObjStm /N 100 /First 975 /Length 1954 /Filter /FlateDecode >> stream xÚÝZ][·}ׯàcÛŠœ/’€ ‰á¶@ ±Ò~p¡0¬ŠÝ5þûž¡Ä]¯¶²hçî*6°ÀÎÕKžKΜ9CISÉ!M…Bæâ†*ê†É䆕~«« £æPs ʪùÓ•Bmpá×>àÐ <Ã&ê.˲SCƇ°,·*,É>mm!«ö»)dkþDÃ(•š[r3à 8sÿÌ‘À/§ˆ1¼ >G˜S†¥xÅ=qŒ>59RU ¡¥{q ë0áAfy¥9ãÉšú°¨ùxÀŽV LÜïÖÀl}”/+s`Ÿ7­ú¬Y^#¦>ƒ®R ÃVé^nÕ>D Üü3f‘¤êŸÕ ´³Zî@€Z´! b%¹ÅAj*˜J‚,ôm…‰ˆº&bõ9|"i>/ÃÅ<|$+ý# .¾9žìW 3¸Cåî…Ïk_MÆ“­O¬–[‹ÓnähVŒ½»ÂÓ t÷\9Ôq…â€+÷À»ï¯ÄïI¿Â„ëç—Û·/6ØÛ°~þôYX¿Üüz^ß —çoþµY­¿®ÍÅõ•—ìþWÛ÷—o7W»2Þ?ûûæçwo¾Ûþz ôLiÎÏß\âi¯ˆºsìAx…‰»q<]ŠìŒ–†AÃàaÈ0vïôzQαŠÿ®ˆ$JP$ÁΉËǃ»YZs É a3pÖØHç,Ì;šïvEP å9(‹ñ~w!Ȭ|³;ÐÃ17yÔݱØÕŠbA(3þ»èR¦¨ö¸›ƒ¢õ:ˆpT×&H w–¯ÖY¢ë>:,yC‡PcmôI@:I¶:Yî8+ ‡NGË£Bý@*N8r‹.O:’¶hÆŽPµð—Vr¦{eÁ›ªÏ- Þv¦÷&po”aÔa´%‹@ƒâ-·|‡þúf’îZ^e²!·K-óV¹¤Ø¼)!Ë©œZ–f$—è}û€"–â®—Ÿ€²ð¢äÈèGÑ›D?Ò ÓžOœ©VwQ(R•(âŠý攃Eqð£)λëx„óî9ã¼CG­ìe{Âø<O:rÏ ‰al®ŸLqÞ“M3à‡œ÷Ù,Çÿ‡åø7°\T–÷âטö ƒ‡!ÔHƒiŒCíëÔŘÙö?7I ¤sèbômbò.¶]ݘƒbõ«Æ»¶E‰¢ GÛra¼ëZ!?Ï*“Hì•ñ~s<’«> stream xÚåY[s›F~ׯàQx¢õÞY¦Oé´Î4éCë¨OŽGƒÑÚb„… (vþ}Î^@€°|M“¶/-ËÙï\ö|€ƒ«ï&?Ï'Ç'œ1Š%•Áü2 Š#Êâ â ñ˜óep6ýR1Õå….‹*œÑHMßÞÜäYšÔY±q¿èâéçÀļ¸Ñ¥~·Í–ú;?Õ¹N*íþD)"áùüýä×ùäï <8 ADaiŽ"éõäìK`ÄbÜÚY×— Žyðqòç{_0"àFT23[’ „ {ƒ§c^›U F˜EÎáuy!ɶ^-Òb³¸ gOu(¦u™&éÊ»0kܲ²NÜ…º™±€Á›<1¿¸±ŽË²¸vg‰¦YÙO+6uh,‚í»Ùxµ·ŽS¬Œw‡_®¤s|8ŽŸHÙñ3Ê!(¢ã´.K“ì¢Ï—º·Þñ „©30Ž!¶£ÓM¤À¬*:÷ Øâ¸¹ñØ-ó\7l† šÉÃ]=p€©î})"š;ÍM:dÂüæex3§ÃÀ„PB«ÇB‹"ÄIc¡‰ê+Á‘8›pÈVÈ¡>kFaÓR3BP,|Ý™T§FÓÍ0Š1ïd›ŒñG°ÊzH0AŠQ8$D9ë7I™\÷ÌöòðY¶9‡í%°OºÝ[z¿@zÔêÌÝò{vQ&¦»a»•[#65ÞÿRoeF"36DÐIî}0"SoM¶à^½©w}øa0ÞVL±­=šÒ¤qÍ~HâÑÊ©eÓÞØ.&­ ûw•l–¹>˜ø1¤¶Ò Rê,CÛ‡á§þlMòQ“`Šw+" ó‹’rΠK<Èé–žSKÝÕöbí(|GÕOäùTgŸ³Í•³÷x¾÷W½æJÜ¡cï"/R³æÚüü«Ä„Û„F܈Ã×ÕäÙ¡¥®´¾{!óBc B¾¢0H_ ˆ!EU¤ÄVìÓõA)@$³+8f•^ ­MåjÛ»¬êí rÌA„èõUƒÞ ÝlæiÿQª@î©‚ún¤CDR½T x+=Zë¨t¼5îqî3éß™ºý×–”Ær×Ã#)Š€]ï3|az_[ O"xUéý¾äÿq›¦ºª~rÿ ˆ¼ËúmVyªôø`]nŸ•…ùcŽÓ²(›-ñ÷%íI,º’óiZê¤ÖþR⣻Í͆BH²KÌt$'e'IX “dï½G_Ph>’¨§ê †¢ÝS–ÑDMÿª<Ûs.K­c®˜Þo{ƒ…U>,0}â–õwõ°Ÿ 75ôSÕÖò-ì'—£ÌË›F½m wÌ œ}âǵ^êåËåŠEñBµ²°©g¶á0®WL])°=½C{zƼ^³Ä—¢×+0²§W̬ÊÝäÿ–^YŒ±IE~¸W?ŠbÁñ7–,‡°‘€£% 3©ê½›z]Â)CÎaC ˜Òç¾­ø§t ûžº„Ò%cþÇHíôý7‘#’ ˆ«ÿ™¼Á ½7dZéºaaxðfb·?õXƈškI×Ò:ôo?HO¡ìçÍA¹ç ‘H(úŒ7 QO¡@¹9…K¹³§Q:ÒÄ`/èîÇ4;ŸÈ§¦Q#Ä«ÒU#6_ül9uúÅA‰â+løÉB@壿¸Œ~?ážèüÞ…‡;£ä±žÿbôÇo4Ò¶@奈‡À¾½f endstream endobj 5226 0 obj << /Length 1579 /Filter /FlateDecode >> stream xÚíYÛnÛ8}÷WèQ j–‘¢°Oišv·]´ÛÄh C¶éĈ-¹²Ü$¿C e]¢¤Iœb»è¾H)Íœ¹pæH¢Þ™G½×ƒ£ÁóW!ób+®¼ÑÜ‹¸…š„±ðF3ï“ÿ6àÒ7ùÄäÙ&òHû‡ëõr1MŠE–âÄKpê ܸÌÖ&Çé×ÛÅÌ<Ãñ‰Yšdcð‚Î ¾ŒÞ ŽGƒ¯P¨ÇPuH"yÓÕàÓêÍ`þG‰ˆµwYÞµòB¥á¼ôNÔ™A ô”p%ìÝŠy9,ܘ<¹Í`F |‘Oä8Ùçãi–ŽÏ‚!£¾ ¤_€Y`à* `¢€ ³1_ÓíjRÚ ˆ§¼yÑp .çnpCNƒ8»°5éÔÍ4¥Ïól…£$ugÀhG¡@Qh¼*HéÙkv.âT[?D!C­ÐEÝIpÑóWJ5üC=Ðî“ ÷˜<·i‘åࣙié{þ Úð.§…^ßš"7 G‚$P/˜Š¯$|¦’¢¾ÇÚ# ¬¨tŸÓUÑ1Eèæƒ!Ñ,¬ž´™@Hpø³ý CÑu‘MŽóûB‹"Ò¸Q9ø‰ð ™R„ÁÒ1Ëf,ÒB𻀅Šp¶ ÿÁ]†¢ÇQ#ά?¿s©¢ ^0$$1€g¥¯“ÁÕ½-õþ( 9¼u¹½Ùôd¡PþÑy²¶"p$º¾«0ö,1þziªpÍÝpÄÏ 5%9üëŠQ8â1K {gR\¯1‡›†þ-ν? endstream endobj 5247 0 obj << /Length 1634 /Filter /FlateDecode >> stream xÚíYÛrÛ6}×Wð‘ÌX‚ 9}ʽIÚ¦•™Î8 EÁÇ)ó'ýú.nIQ±S7S§“‘ÂeqöìbqaçÂÁ΋ÙãÅìásFœÅœrgqîЈ!êÇNÈ"ÄbßY¬3÷µGWT+Q•µ7§aä>Úíò,Mš¬,tÃSáQì~ô Ì˨tó‹6[‹ýþVä"©…þB¥ˆx¯fϳ«<Ø!NHai†B:évvö;khå`äÇ‘s­FmÆ#xæÎéì6¾`DÀŒ(÷åhNœ :ßNy-W%a?Ô_V«`™´Íf™–Å2+²F£žëÇðüL>uSR¬õ‹œ%yöW×až`MÍ€40®MuŸ¤ØèÜéÜ¢8’ØCŸ,âÚ­q#¸õð9ç=Ÿ°3§ \z.‰ª’¡,+ðk-ë=|$ôã˜;ÊÌ…ƒÞ”˜!ÂB;å=°^àŸ:@"(ºd‚}jFÐý¨?¡ˆv¦œ$‘PÈŒbJµõ]R%Ûy‡“Йx&‘βâ¤o€ µ*w5ôaÀtØAŸë)¿d«*‘µ»ŸûFúþ+s¢Ø7åè¬l¡Gá1FG8y>vÇ;òÍ­ %˜¢0b§!´’¹!äGóQn»$Ÿ´ ¶X?Í(ÂcßS‚¿”WP«UETƒ±vå´MSQ×?éo%øªy¿ÎT †6ÃÅkIݾºò‹|ºUYYVÖ¢–ë;s °!ºÅ&“yàž·EjÈäÌM+(‘Ât%¦ñ B_ŸuÕДzð¦Ì×Ý÷Øgm•ìÐEzk¹÷XL­à¤‘„kÖ‹FÖFµsu‹…kÑ{ ˆª ^ƒs®üÆÃ= Ášœ¦5+Òl—ä†ALõ–H÷£·’äB§fhY¤bŸÌã„Ü$vXš¶&,b:P½0<–;ŠQw-ΕßmÞÈ“—ùP7ü ¹¨u÷ÞKF\XP·C=IezjÑèÅôˆ"Yå¦ÓÌ'n[›–ò|ÔS‰]žÈífà¥I*£e–çÄë·ƒå#c÷Ýâçå¹cÞü¶xöçbùôÍrñò×g²ðLbÕ6šž¢4/µ¸’ó[ÑÑZ´[Èíysß÷Ýw6û‡gxiX’€T¡U£”Ór (ÌI¡Cgú6æÅÌœŒÊÂJò¼„ÈŠµ)s|Xæ™ßmàc§Êá9Gö…mÛêM [™EÏ+!L&^gÍfÊs9dèó5d¡~ËŒ¹¬¶,ëg^"L(`“•_¡ÃF" ‹ÇOE“J b..ÓH¥»”4Õív)7ò@¡ªFy±5šdZ!,«Ätw(ܾk¹©­»ì˜:Ô„ƒgô‡x»­xk·;›Î‰FRKÁÜ^.+Y>ÅÕ2•O™ÆðDódú޳®°Èá'zÇ~”°ËÌÔ†ë¤I&Ò‚CF†Ñ¿/?ã…18«ôeô½ÉÏÁ-Ôg _Ù¿N}ŽÁ[GÀìwö€¡( FžÈ$¢:‰ÌÒ¦ÊÆ©µ™#kCúx Ýd @Œ0fcýå4—•Ü‚íHù*éÍåOrŸ”·¬žI~­ÖÂÞj»{¦5ô©TY¾Oåi%ƒx¨©Dä³\5‰<£Ô(­¤z±”­j3«7;®+$âÊõ ‡‚0ÖòdzÁë,ÏõÛJtæ|[:.Õ¯†µ}ÞH) `Zƒu»ÒcŒöSã 3AJ¡|JГo6IL£Ö:eeÅ ;TU„úP±Ã;ɪ;k85ùÃð&M£¯”dïi”æóNÕ5Ó‚f?å@ÈüŸM%©º´ý4÷\Ðð>qV¾ØÐÃbÚá]‘;qæ#̾ÁU¥(»s#Fn¥Uø®Uè½Ö*±F>@!g7Š–ƒº)˜QˆxD†¨îÅ-¹œxó-néèà–Î(Å} ¡šÖ£ûŒCYѱý…Ó6ˆå w—ÃÖ^¶ØÛ‹¶¶çûÊ^ Ùë‹¡˜1~u7[}gz·jS#ÿ†'ßøÿ(ÀHù­ÿŽšüs‰ÁaDL ,B´9‹íE¤ü;í÷—*p,àê>Þð’1°¿Û> endstream endobj 5272 0 obj << /Length 1431 /Filter /FlateDecode >> stream xÚíY]s›8}÷¯àwjEH‚îSš&Ý6Ýv;;;“d<ÄV¦\ÀIóï÷ 0Χ3ÝíKA÷êÜ£«{O;—vÞ÷ÞŽz;q*œÑ…#©#=ysFSçÄ=ìSîªì\eiÞPé»»óyMÂ"JsãêSì^÷ LŒÓ¹ÊÌí÷‹hª^›ñ‘ŠU˜+óƒ JéŸ>ööG½ï=P°CÌÒ’X:“Yïä ;S¸ÿÑÁˆ¾sSΚ9žðá;ÃÞ×¶a`D=FT0=['ƒk76L0ÂLš€¿eç|.Š«ñ$MÆ€™»EÀÝp:ÍôÕ²00—¡}®ÇÅ• 0N'al†a25ƒÒVÍÒ>Á0†ö¹õªò\YÏQR™Ú+`1#dLî*\R°¤‚b_Ç+=øëùÂPѾ TìQã;êM¼FƒÊ2½ýi\LUc½ ®Æ"8ÇÀv7‡…3×ö°(¯™ÂAewŠ96«<5 Ž(k (9Ó™ù£hág~ÝÎC>ñ*Km¤úŒ˯Ÿ‡‡1²6/: ® MJä‘ÊCEê–àqp4áéŒdXgä]¨1§BPÀmÖ¼*Sßøð°û\t "ž‚âòü%í¯28x…2ÆëIÈ9ŒÖrtŸ¬{®à•Õ b4@ €) ˆøÆû<ÌÂYýS>–MO¢ä Î<Ç6Ëo 7ãÄ(Ëý“OÑyê"ŒÝÛº“2alü ¤ÖË€H0ÖFPK¹M0$GŒù-»zŸÀV%Ū]ÜÆúÚ¦–_ë0‡¾ÅÛlØb¬#3›8íU­©Y•¶WÍô­Š·Ú´¼ÔŧÍÂQÙ?uú­axp&Λ”H% k½ÄØå\yõrDnïô)%ø®³b`U¡±‰b¸˜L Šß̯6ÙäÛM”Û8mø‡:gVòëúêfiV¥ÃT•t˜MhÇ9ºŠJCá^,’I•EÒÍŒ¢°ÏLë…A® j‘fáeÉ»™æyt™¨©›š»K›2!“ºJ/Z«nCÓÍËÕ«ÕŽª•½É¯FÒ«UñΰޔVÝÌ®]Æš¾<Ý]°×,Ðm-Ó0qfGi&8õ8X–½;–'¤¼ŽdÝÈ—²šcŠ´>1Zé7ùæ ùbyj€É¹‚m¾ÖBÅzoû’»¨ëÐ!´™0CU´8Oßt,ˆ›§¼©ULÚ$¥^ÑjdÕ ,1[ú–c¨Ù¬.O1ãáåf]šKcüðT¼* endstream endobj 5287 0 obj << /Length 1440 /Filter /FlateDecode >> stream xÚåXIsÛ6¾ëWð(u" í)6™&=´¶nŽÇCQ°Å%*$ååßçaájÊq,û”ƒD$ÞûÞþ‘8¸ pðiòçbòþcH…” "X\T†ˆ2D¡D¡bÁb\L¿Ì(Ÿêb©‹¼œÍi$§öû,Mâ*Íwná/=£xz;#ð`–ïuá–?Ò•~çÎÏt¦ãR» ‚(Edv¹ø<ù{1ù6!€$ˆ(¨Q„£ ÙN..q°‚õÏFLÉàÎ>µ B!á˜ç“ÿ'¸k‹`[‘HÒ0ˆF˜EΖ‹tw 8ž3‚§z››C¥¯öyQ<ï?2Ù1D° v÷Üm=³Ùæ•vװלL­€Ñð8€7WaÊ‚9‰bÔ)p ,¤[£$ÎFE‚¨°#ŠQ„#å%ù }¥÷ö ƒø UÛ…ç‡$Ñeù‡»Ê«µ#žÞ¥¥·Ô;à‹‰v›Ü\XÎxšä+]ýÁ\prÞG·X§v£š^v‰Ï#¸*\’ø{À”&±ª¼ˆo¬çÝb\–éÍN¯ü³ù`O’ï*½«¼¨üzp;Ëp®´[ÕÚ똪6¦­›Bt/ÀóªIøP™Ð­¯Œn[ ÷c9Å¡ÆxÔlªµ4ï…RWÞw!ˆq“$)p¢Ýn—ÁèP .kñÖÎ+kɪ8Po\Ð.œÇ2†ŒÈÅŒùÒ19oì|R'PГ ]î5„üvÆL³0}˜E|мÚ^#‰Y?yÎµÏÆ8+óßGâþó›bɯ 66.W.…vñjU”_1Çðs#Û1¢ú A•óhñìÓ°i‚:FÀ?cÚ pÀGE'kßúæîpno¸óª¾>lû,6N}pk­©ï¶q}-þ!“p¦2 .ï+4Þ‡ÅÒ…ðJáì.ZûzÁûh¶óŽº(ŒóâÊTú Ñ@ïtPÞFèÚ5.ö¼›r°©¦E™Pù0½Ð “­cP¥Ç:%”«$¼ÞiÛŠIÝûêÝix3§CÇŒ6cТ…¤Ó}ÜÆ×Ç"=p6à-Süký¬9…éN¡ zmËDÚØ4mÊ‘jÃÓÖä‘YúÜK4.N!ÒIßÇE¼í‰ìíÞ–*8§ÚÒko©H (¿鲈Ýô|è ±‘ët^J¯qµ:±=#âˆ19€ñÁë`&KÕòµƒñ²Ž€)LÁìOØÖæe4™ÞÆZŸ4Bìåšr¦ŠD ñ•¿4‰‚ECGìº,Fd×ñðH×ñpËÈ̇wÞýç’èj$¬78“ªåî2H%ŠT“×hDG _(ï.Í2烥ö®ÉòÒ’JX»3”ì±B‰‘Tô$Ç4‘+´^™7$ ´/o£æÙFfg¯-Ë´Or²•¯J¥»oÉ!-מ®ãª¾[îó]™.Ó,­Z¾õ¦¤Ç’™Ä¾–‡åƺ¦Cl~L„Þ¦»·4&⹄ȭݥõÝØ:ò–À“Îù{#þ$Þ„?‡kôÇ Í‹öëR(òbÕ$RÝŸHN  .^‘;%§bHRÙ!±Yhó$["‚Y ½2ÿmcǃíÙV õb!†&^8Q‡ ,}q’G‰Su?Ò At$¢S “—rŒ0%c­_uçõiÉËêVýƾ܎¯_ƒíèꥶ÷™>oz_“?E"…XHûnúÕ¾2áÞW&\$; u=Ÿr¸]'IB"ÜR±¬3¥!y‡¹­-ØwTŒ~d â¸I’aWÖdT«¬?Ȇ_ZÍw(ñì­?ƒˆ"B|öÃû"šÍE¨lûóŠÿûdž'„·IÕN¢ˆ }Zýyl endstream endobj 5184 0 obj << /Type /ObjStm /N 100 /First 978 /Length 1957 /Filter /FlateDecode >> stream xÚÝZM¹ ½÷¯Ð1ÉA-‘)Æû'`±ö!ÉÀÇ;Œ,¦ƒñØüû<ªK5ã¶'­õvOÃ{éfUQÒER¯¨*¹¦Bi5H%×*M2±_CP`(•P(åÀRü‘†¢]Ç‚¥äB •ÛB Í*î´rÎæ’÷X¼§Æ!3.!IÈ…}ئƼfz‹ ¡.5Œ]ûàˆH6 "í·$¯æ AØoHUp ‚P×|Qu)*>᩸”q¯öÞÐ §DH8»M(s`‚™ Ì=W—4p)½…ÖæÃâW&ï9næm)îÉ[¡> +\c)€¡¹Aè𠡘¦º–Šø-gÅ”¬vÀšBMä“Öš;`%øsï®Z…»^ µX×ÓP-gŒ[ÖÚûS8q«½¼xoãÐà*˜;†{ µÉ ƒ%mXvגаİK† ] RI¾ÔpîVúò#nšvÀ0Z«Ú§ ¯O)õ±àö){„‘5ˆT)â2'ñ$ÉTÔ±bØœ´¹ ¡?cÛ<{¶Ù~®±†Àþ!lÿö÷X!¬}óþ§Ÿ^m¾úêQEøTÌðÒ42O(2¥¨°ÚQEjáU*>ßÝÜ…gÏÂö¹x0ÁÝz“çX&?{,ŸG~xPT‡eƒêð :<¨/U!/Ú.ÂèGF?"çà<ÿµ]²âƒ‘½œ:#ðú ’g(jQôÞ(’%^Ÿƒ¢g(³H\ye&>ÿ””¯IZ1²z|#!à¿ù¦j­Ê“.O3Ю¶Bqcp§¦SPNJI‡U–õª±: 4Ñcì8éé9)Þââƒ* ¶ùšè~‚ æ±²ú 0m—ð“eøÉ$”søÉ~uØ ¶g0_%9žÚòG4Ct’f| øÍ8Tz”f(–„yX;®è/Ü& ¯r~¤w\3F¬q4Ã>qÂdŸÂä§«{VPF!¥ vQ»(ƒ]è(¤è`:Ø…v¡£ýèèG×~~«gN^pæ”Klt¡3'¯5>8s"‹Ôì2gNk{pæÄ-ÖÉÓ/ä¥Ó–ümc-ÿàŸ&«?'28YÎýMgådl±½€Ã •è‹¿ û?]Â_$Ã]'‘œÃ]$T^³Ì!9G»PÌíž¹gÔê¼$ƒ‰1Óê&Ùœ£Ê%Üd@~2 å~2 ,im ɉÓ!µÕQz­ßÀ²ü²¼Ö™’Íž¿ÙÌù›Íž¿( ¦ÁÙ&Å+‘Š0Jô¯¬Ž*‚’ÆtHK¿nX?Q‚ª¿¢eƒÁÙ`p6œ:SL°&X¬ç¨3äa•ûtXœŠÔ |YT¤á ‚Ö/‹Ji±e¹Ä—EÊø²hÊ9¾,PÆ—E“PÎðesÆÂÓê)ÜóXyúÃ5?å³õp‹Âaì‡kÊ8\›„rŽÃµe®ÍAyp¸ö?aë4¨ endstream endobj 5308 0 obj << /Length 1233 /Filter /FlateDecode >> stream xÚíY[oÛ6~÷¯Ð£1‚TÖp¢à2£ˆR'}çñMK¼G ¨½€À(ÊD¾H—p|6át&·Ý£(”µÉ[ú!½ÎcS¿°=•f3D ܾ‹V×ÂRJëjŽ“Å4B<ìè=1À¹ыbSZŸÖîD9å´«|fö5#ÖvÎ<¦3Îl±ßT*˜²•ªú£'$¢$jc“›3 Í£¸5Êây¯HÅÛ±ÂaGÒJð¶ô…&ëìÅΙóu’èÕê7÷-¼]¬ïRÛ›`®â½u¹îzÂ|1£Ÿgy™±^ý^ âu-ëFÓ´Ü8Y/’M@¡&–ó®=ÀK¾p;­ÁE¿u¢¥B›ö¦š9ª.kEÖ'Н¥”%¡+F %k1G•MI®oLÂV–§•k¹žØÜËõ"Ñ\ëEݹÌÇ”-ûRÕepäçªËø,ÀööV YŒƒÜ™þÑÔÝÌfŸþµÿhJR'ÍGס! wuì¨îê è(y®'{ò® .@9~”ϬôbÜGA¶±³gòâæîÒêר y×ó,1„ifÿ'®Sª{$7¬÷°D‡|7Óá?Ó!/LtlV1Ó·ɬ†‘ø¥QŽ­ZŠé„"L˜88¢ÐüL,ÉQ¯h b[8P'tíCHEÇžsWðöã@a„´×Cs º7BÀ1æÿýsp ÕcXo¡?<zù<úã²2~ÙP‘MzT€EƒµªH÷,A©º°–kç>ÞiâЦ" .`©ð9|—‰ÃôòjÎòe›óëEÄëEÄžäµ ïЄ³u±ÛMD„Ԇ˲ùJ‚B®Ú-óõâG5ß=îäw÷@ƒjCr÷@ Z¨(üAwj!ųïʱs#teç¿eú/%("¤<„!ggÒ3—– ¿úßH5•<òßd7æ `9×Õ‚æß)“r<] 7”çäÓ_)YÎ8.ÌʸxXº3S{  ý e_ endstream endobj 5329 0 obj << /Length 1391 /Filter /FlateDecode >> stream xÚåXms›Fþ®_ÁG)ï;h?%N•iÜqZ[ùd{4#ÆX¨€¢øßwï¿J™iÚñXp»·ûìÞ>{`難½ƒ÷ÓÁÑ„/D¡ Â›Þx4àˆ²Ð“<@þ¸Næê­Ÿ©TE…²7QŠÈèjúiðÛtð÷€€=Ø#ž¤°4GK/¾\\aoÏ?y±0ð6fÖÇE×Ô;ü5ÀÎŒ¸€LÏÄËáÅÎó>¯õª#̤uø6¿ögѺ\Ìâl9›ýa¹.T®ÿoúçÞº2¶—s3ËŽË…s³PEQc´#™¸Qu…í–-Gz2€ú½D§ÚÑÚaŠí•äðËaî>‡&B4¼ÅÞ˜rÃo8«ò\9ËÁã¹j­w4xXr ˜ö#µ…IÝk-°´ß&\ î“JúûØ®õZ_|ÈÖ–-9ó÷²ã šrį$µ1°~»Ÿ=ŒéaÁÃÅsM“ñ¡ Ú™7&B HúÍ €€]§Yjõ‡áæãPó”uJ~ZÞqÛxwqÎg²³øqµéa¼²F4rg#«¢½2©Zz7pí”  QéÒËqÞ¨YM%öv-ç©zÝ„Ps1m[yº¡{ÓMG¬µÔØÊ½žÙNÎÞû³ãã٩ξÏÓÉç/§´ð–]šª'cK!‚JtÆdØ€iÚ0g˜e@0ˆ³4U±kMà~³È 7®n ¼ë´´ï:Iež%…K®Võ€äb„µ+ROQ¨À¤nÇÑhÌ$Ñ=J¯JDÃp‡/Ò¬šÝí‚ɶÏ/3çëvv·ìòšŠÚe®k0 eõhì ¥…,)ìý2³áâTP€Z&Í–_í‘ÝfÔRÁ®™Wì¬ÿt‘6P˜»ço½º„Ú9ó'ÎßæTÝÚ[Zøã WOu®df[©_ú}¤ŽÀ©=-PëEâz[8Ià红?2°ð¥®ìù)>’Lt)[é½v?«Z¯¢Õ¡»×ÏëÒ~†F+[i_µŸ=}G„ËÿÕW€×47Pã}Û,‚|îm Pt÷²­þ`í ( þí•`ÏÒL"JÉËZC1p½V•]«c=&9íõ]P¶;¾Ñ> stream xÚåY[sÓ8~ϯð£ÓiTÝ,Û»O,l™…³ á ˜Œë(‰§Žl‡Â¿çÈ’]Kqº--,̾Ä7£sÿ¾Q°·ö°÷|òÇ|rvΉ£XPáÍW^H½GˆÇÌ›/½wþË) |Y]ʪ¬§3Fþ“Ý.ÏÒ¤ÉÊB¿x&§ûŸ¦æåNVúõó}¶”§úþµÌeRKý@¥ˆL?Ì_LþœO>N˜‚=¢·æ(Ä¡—n'ï>`o ï_x±8ò®ÛU[‹®¹÷fòÏ70"`=FT0µZ¯‚/_s˜`„Y¨¾ª.ƒEš.d±\Ôòãb=ìËià7Úü™¾œgEVoô}¢/µ¬2i¢T®ºw§³Àßˢɒ\¿ÛUe*ë:+Öú9­Ô¹®I“tc⯕^ÔF¬w¹wâHùrøå‘Ю»/Áõ³s!~coF9„%¸-«J¥»¬i¹”Ö~gç¨AÔ@9†è‰™l”0ì dâ ;™÷8Àz‡oõ @”Û„²hÚ2üÜ8Ƴh(ÈQDx'©„ä”þçæôa1·Ì J’Nö7òVƒÂqïŠ'6òæÐ8ts”î+¥½.«Û,ŠídO@È89eÐeVNÉx•þË´²Ö'Œ %ŠQL©Ö¾Kªdk©÷(A1 ½k`*ù]V|€Æ °É,̦Ϧí ƒê0îLŸi‘‹ì²JÔÃþ—¡’¶<Œÿ–¥FËŒ„0v`A—Ê‘ý9CB„ÎþO«Á°´›¤XærÌ£MÛAìäÏ6"DaH\#úÕwN˜ˆ‘ˆ"; PgjpÂOóIðiL%¨âÊ¢»}O ¾­Z¯DŸI¬Pó%ɯÛU~QwuW¡`1T”ŒµÏ|“ÕZzµ/Rƒp­.ÆÕ´—æ«5ÀUxoÏšàmIeH£¾É e› O¶LX¡³kur õ }× «…XÐE¢ï\4V+ º*¢N±¼‘ÆÚ$¯ËßFc;VÝ<©•)MÛ3p5©8C£2 â}ªõv…馅ŠZ·ÆLº»Â¸ƒá`#(r|€Ü Tׄ? ºðnݾ…äÉiéM’ï &¯ªrk ÃðïÛâaàZh•­ÇP›#µ¿´ƒïÚôÁ -h¡(d‘©Ûñ¹ØUY‘f;g‚ºSPÁ^ÃÎŒ-wª‡˜À0n-ÀÔÛèNPë]º¡±r¥Tê *ÿ^ ûÛ^ÂÐKns LæÑ é–;e L bÑ£ D€£–iD¿ 9 Ùr*hÌ‹mG˜UÁn"(}׌~'78¼šr cN?4=XÛ¥þ»ñx¥¯¯Þ^\Zçåeç–£Êxw½)s9JÝœ`·qõJ%ÉtÌ¡³ ¦7¦Ž·¯Z°5[—«>ãhI0®&—ãI0ÚmËÊ}cLƒæiA1£‚ÌMÃ3Õm:F¥¾^Ê.€ÊËÆiy?¶(€{Ù¥úcÉbäÅ7ûT:GÌaØ<> stream xÚÝYYsÛ6~ׯࣔ±ÜGûÔË™&i¦MÔéC’Ñ0lqB‘*IÅI}(‘}$òÄMÇcóÂ.¾Ýý°»€qtáèÉäÇÅäñ9'‘AFR-."ª9¢ÌDŠkÄ ‹«èõôÙŒŠ©-ßÙ²¨fsªôô‡í6K“¸N‹Ü¿øÙÎ(ž~˜˜[[ú×OvéÊžùû—6³qeýA”"2{»x:ùe1ù{BŽH¤(LÍ‘Â*J6“×oq´‚÷O#Œ˜ÑÑU3jq©ášE¯&Lp°¥½öu9ÒeŒÕÕ•óu$ Eð{“<Ž(CŒ²#‚$0=I‡râ sW p7²’u"« "ŠE S„™òýk¦ð4.ó4¿üÎÅâñ9Ó®ô5ƒÏ]„ X§»inñô“‘”veó:³ð'Ž këãìÊ‘(ž1'w•_ÚzçõäáMì/o0ñe˜,®Þû»âÂ_1j¨ƒ¤Q°"IT‚ùG/_>Ò|.8’TDsD$Âø¾|'–I²„Y žÚ™˜ÖË‹]–-óxh;o©ì>–i‡ôþC½7NÎß„ðpý%»Aðà5÷.NÖ6Ø6à5„µ3HqøËµô¶_6¶JÙ±GsÊÁ]+mYº å2)V¶7ßãs ]‡6 Ë–{Ù®kæ€þƒÁi¦[±7Xà°/4B@Vêƒ(òºqüÇz¿Gaˆ³†øI'dgLL?Ög§áa nˆåÞk{# †°ÙãiÉYX4ÍSÖØ£GÎÅÎÃËbWy™8ªãe2N[®ƒL‹‚"E(ð ¥^û6.ãMO}D 2\ç®"Ðëuš¿ Æ4Άò±É-T«½#æ^äyú®Œûiå±à€Ò eN2Œ!Øç ‘ÜÆ”j0ÿO7'±uœ¯2;†#hë〠 ÇqìaÑP 5`9ŸAòYžBé¤Àžq035ÃBõBÌþ¬‚PCЋÒÚeå„jïcHûne6¼i†ÕEÀ #ƒ™]Ò¸R{Ößb•€ÒËöV]­mî•§u¸†„Ÿ‡I³"¿ôFxo!«6º·6›X…¥‡u’ßÒ5ŒÔIÐE {î¿p+\0j;V$Áï’ì‰üÂHWÁÊ`5AßÕX~\ÑÏ5åîÅð¸íƒÙ¸’KÓÏó›ÂE¤[áBüíèÃU5yUmS|+f²¡ÿóZF¿´–‘V°*“‰„Ñ'Yù7Z0!’òÞë%cê¥ õ’Ü­^ʯ—tˆ *ã’‘Ù!¹ÊC;f_´uñ–Þ¿­*L˜ËÌç ÷e¯ÁÁÎë¶ú›1ðÄ5Å~UÕãÀ U_ 8Œ¿‰NGÁ€õÌyßžrÖl=\µùÐl˜²Q• Š÷­ÄÃ6è ÝœÑ5û{¹(ö¼Ú%‰­ªï[:$ýJdEu¨È×ôŽ ®ú ëµ+ó¯bÐ3·G‡¶bZ¶;XW"®µÔg´í¾â,+’¸¶Gs)`c<ˆÜbí„1Ðå‰?aÔípÓÔ§'¹½Ù£¿3Á´¶>Œ©izág©<¡·<ó¾fZ ct—¡ó}l1ãû…ct V˜1wÇ‘8´§ž-pƒ8€œ ­úFü²m“>óX¡•÷OLOêOáÐÁ%ξÀ·|ÈÛÆQà¤ãJ®u7¯?pOÆÿkç dä€á$8TÁQÃ%»¦a¨ ¥Þ€’¥K’Aö9X¶'bšS&€6ºßOyl¥s”]U7áâ ö;ú€« ãL£°-ÂìÞ{F ›> stream xÚíY[“›6~÷¯àÑdbE"}J6Ù4Ù¦Iwv:IÆÃ‚vÍcpÒý÷=B’Xìõ^ÚÉtú°kâè;W}G`ïÒÃÞ«ÑóéèÉq@¼Å! ½é…Q/  bæM3ïãøÄ§|,«sY-kB#1~¶Zyš4ù²Ô/¤Oñø›O`b±\ÉJ¿Zç™|¬¯Oe!“Zê‚(EÄÿ<}3z9}€‚=¢—P„#/]Œ>~Æ^ão<ŒX,¼ïí¬…„~ ïlôÛwÕ`¢§Á³H«1ç >Çã‹u™ìp÷ ³ (Ì£¼T ž‡aG’`ˆ‹–i夕ÏðXfµžé¬I”Û™ßóf®Å6s©/Jé3>þ«Ñw²l”¥ðøjßêâ ‹]=IÕò o`uŽØ™I™i©IöMy0)SYÈç…l+])/ÖËjhD¸™ŠÔ oÂp€bL½ ‰P ‚Úgj£ð—êœÏ.*)gi%³Yº,кþ„9†?b̳4Žy  ÉÁ7˜KãäÜX܆@iV,–å¥oë™É ¬#Ôˆ@h=MnœI£gRÔ˧€°;¿5GšÎjeä&iW7³Z~iµÌãŽýd™ Mió#¢FÐâÖLdĵÁÓWý4dŒ ¹À,±Xª•t>ƒãÚ±L§îĦsw޳ÁÁyR˜ZqQ-ú*šeÆ’t.‘ÖÇ$ôæQ,”D6 D¨õë¶ú9QúQ7¼£ ¬*zYA fÒYïÉ1$Y§z€p¼ ¤u@ëo:”MˆðÎ;qŒØ¶N(/ÝQŽ(#.HŸÖàPA\ðNÐA¾²)mÎé²óø~€ƒKÖ3J· íÄŽI·†syO8*#Ž8PÌyrYïÃûKˆ;^j_¸/(;¸çªn•Ú…eBY„"Á HóP¿ÿHÅW=`4DÓN€‘ᔹá÷ze¹$4‚˜‚°Jªdáˆ÷ÌcëǼü¬+•3ØÌtlö#£8Š-ô‰~å—ü¼Jœ°«C5ØHq¶šWë …aÔ[ÿ¨ê”!G@{;‡-´C8Œ4§´oqt‚°‡‚A…À¬‡âyÞ|Ïk9ywÚ–w³k×2©4š¡.#uD²k» (â„ì´JínÏçÆ.‹¤1vÊöÆ_g?.N Nýk4K)E‚¨ kGŠp?>Q‚÷å0Úp€'§Ïùìèhö« Øwg޿תµ÷KK«B.ÀÖ'~O+Ëé,™è…MsµêÃ^ô`ăÝvXWå­mÀî`­kߥuWÕu™ý¤ï_$Mbµ-Kk!{°’™{¢oEt5Ñ©¬íÔî[kúiåÜUcUOÒT®šºÇ©ëd!»9¢¯M4­­BIÝ!TíVn¸w.5ašëÈÌÒ+—ôûSD¡r÷ú”8û”î»ÐZ …1(.ö½Õ¾Â(»&‚CÆsØî##Ò¯«B~  N«åDt#1CØøð?£We^^ñâ ä›­l—÷tý ”¬—6R²F÷ãË`U!4w“ºW‡h³\¾Ê;½ð.î|m¢Ãë•LsÕ–Ú÷~Lb>(±VöØM­ Ž‘ÄÃrë;SkþQkú_ Ö⇢֡«&_-Zn}_g 1~{LPôðvÿý·i>ôŽ¥i¾8ŒæóÿiþÑüãBMÖ´ÉG-’úËíýb¥Û‰ƒý†öíðHr1,×Í!m…@8¸ Ãfm`=FWɯJ¸ânê˜ÌîõJw»®C‘œÈ ¦è:nÁ¸7k=ÎÖÀcëÚ°å%¨­“CuzlrW"F¤·Íå†[¯îM‡m¥{=zý—ªþokŒÅ¾s\FÚ‰þQ6Єµ¶UY÷v/z}‹9¦1˜¥jû»«Û<n¬–×Uö6¸¡chÒš'+ÕÑøæ; ô!ò'aTÂÇд٠ú¹nU.Ìð¿L¥Ó#={ÿÚ47¥i‚2H§m/×Wôouè endstream endobj 5290 0 obj << /Type /ObjStm /N 100 /First 978 /Length 2070 /Filter /FlateDecode >> stream xÚÝZMo$¹ ½÷¯Ð1›ƒZ")R ìœH€ÅÎ’s˜Ì6‚AîÀã6ÿ>ªV÷ØŽÑÂl¹/fu±¨'’"ŸTU¨Ö‚–$‡Bµ…J¸l!¡F!«ø(•P8Y`à·Š² ,%$Tn%4«þ‹…œ³¹Ta±¸¥Ûì3Ê…³K>Œ%—8äšÔ% ¹‰¸äc×þD D”6ЉÔÍ ¬«Z ææ q“+fe9P×rI» T0JaªT\Êx .Ö$`Ý@*¿›ÿ¦ÉR®˜{vH¹.ÅŸ X›CÇ@\©¹Ä›V—~í~#x˜útHƒpeŒÁ)H!øÛp³;“áÑäØ1õ˜0$JEDŒº–KÚYÚ(Pkf`ÍF>€-Nƒ4" .*¥ú ·näx¦öñá ïŽVÍŒ*™[ ÀÔŸ¨ž4> ið}gIŽÑŸ@ µ)n`KÙ½ƒ ³äÏ· ¡:’¢Á2¦ÈË=üú”» ¨QñIÀ9¶$Œ¦`Ú­!Xfâ“@P­V‡ÔDî-¡æOUässèH*ÝÀU‹¹†¬@àcäPk§Q¨­ÇÓ8´Üãi©co¡qrìHïæS7¤RãE7…}vPG ð’°•ì^2äùϾ8´¹„˜b$÷:"›S·R‘ö)wocÍåäIQ!"E\ÄJJe1€¥”¬{rª–6¯^m¶ß‡k¬XÅÂþ1lÿú·¿Ã»ÁŠÅ gÝ|úùç·›¯¿~B¨EÏ™óŠªËù¼" G$Є¢R¬¢÷¯ö7wáÕ«°½B2bõÕå‘+¤+Rñ`à ù-n<ÜóeO®°à9½\a,Ä2îyá«ËÜþp»ÿzw®Ãö‡ï¯ÂöÍî—»pÄòæ?ÿÞáÆ»î6Ûï€kws÷ÑWXÇ´Ùþ¸û¸ÿtû~÷q©3ý·¿ì~úðîÛý/á:y¡ÍH×Fo1л[¾[øID%—!èêá¡Ax(aØ¡a‡†Òç`>ÚbÆ|^’ùPlnp$¬!ìÕ¢g™6¤`â‹*Ð CP¤€ÿ[›…²f¥:zå.€Ô·Ò BôýÌkŒ³ù‘(…r$¡K&Š”Ø°ÏH°]@”dÉʉÂæsr 7æGSPð·bK#ñÜhÿÆå¢™’¢Ÿà $äEÍ Ç ’•3…Z=9…Á4’xÊšá‘$½” (âÿé ¡t.@u’ýÜS|ŠýKØJ|VÛ(ƒ!^¶¶q‰â¤ç€„*¦c&_NÇt+éà\:8—ª¥ƒjéàn:8—ªeÃŽ ;6ì? ãŒÚýÙa8Q¥‹ž1`Oä¯ÈÎi¡B3HV®T2—r‚Ò m¥ÎBy†}?·ÿŒù(~Ö‹¾úJ-ú àRlÓ(ÏY78þrÅ¿ì9 Á¦$öoaæ¬Ê{Àw|÷{@‚’ÙKÔå‘éF›ç#ÝÀnB,_šnøWUä/ÿt¡Õ¿­"4Üzqºíí€ÒéÛ,”Õé†ÐŠ˜Ÿê´WìtHý–x XÉz†"«=b>V&™Ï=Eÿ~ ›ÔØóŠXà5ñyEi‚U'Uc’v^‘žš›±Â+|„4ÍŒVa?í°Ÿö+ØO¥Žó¥:HO¤§ÒSÇùR¤§ ÒÓé_5q{ÒS°QE2œH7¹Ë¶U?z¨4/Ne9zò¯(“]ü¸Ü_¬øW¡Š=5›…²öÑ“ˆ6 HÁòêñ±™×º"dˆù·¥$…Ÿšç<(—ë´xÑzâéìu»Ú¥y:Ö®óóTžîyà?­ðÅyº–çé¥ÎB9¥ìyU;‹ endstream endobj 5409 0 obj << /Length 2109 /Filter /FlateDecode >> stream xÚÕYYsÜ6~ׯà#'¥Ap<öMÑá8‘%¯4J%e»¦(äa…CNHNlï¯ßnäG–Jí–JC°‰£ÝAê½÷¨÷âè§ÅÑó’„<ôÂEâEAL‚Dx‹•÷ÆÿuÆ¥¯ê{UWÍlΣØ?Ùn‹¢Ö:´) 61£eèEp¥"26½åŒêå»q?^ˆx0Ì׋Üü$—‹Óå«“™”þâôçåÅ¥n¾¸s$õ/Šô}cšjM#/q~Ð%êB;ÝÄ›¬ž ê«Ucú:*F(Kú®»½k'¿Wýjdd†cûœÓ„Àzs‘Dðïbûâå«óÛåùïZpº0Š,ÖV£Zý5cÔß)£®Zq‘?Ì€£Í7¶£kÐ&m3¼]›[…?âDiÖˆ¿O³HúOÛjô6¦Šïæ±¹ƒ€ÿ?Øq2 ©·øùlJßHñçd»t×®+ܺ€Þÿt»ä«´MŸ4öŸ¶çö½øÛò wÏÉ«óë«Kð1õÿ½xà_—ÖÕpÊjó@\¦ÛÚj+á‘1$ÕèóÖú¡ÌòmZŒ'øõ~8F›@í9c$‘Ò¨_VÖ]í~¤ÅæŸö¿:[.~o×FeUi÷h›g˜ÅÿÄÕ6ß)âß'é â°‹þx}>2@•™‰Ô§í°ÆÇ'kÚ§­jþ |{÷úõõ &…ÅùÙÀ(¬#<ôO×ʆ@ߦEa½–yùÞHTÙZ€j»@Ò®ÓÖ´Ö)Zþ·Î·v¢²óüf·íñ¯Ó³žÎõâŒÑ…6Mt€©U»3ÃÊ«Ò6>äízôl2bûÙ‹Ü­*­Ñ%En+Š6PEnHî;ÇŸõ½\>ÔJ-³Z­–ñÖ¼¥’Â?³KVæŠý¦Jµ ˆYÁ§*5$æ²ëùa­¬QyG,ôJ»bQA5§²r¥VjeHLJ ²P x=Þ¼S7ð¨ 8ÛˆCliŽvD–- _Yk¸×Ü\n¢Ô\0. Õ |•뜇²4[[ÒÖb«L{×19àý$2Ñ5dÐÁmm©»Íú+á4FË¢~ƒ84F…Úh'H€QŽa 檺FçV5Ä}¥F[æ~t“Ó°‹ÛÈWrØ]kíÃŒ`²ûJå%Pmæ®@ÕnûØ>•Z™1 zd"º5Ïh¿M!! )úÀ=¥Oȉìý²¿Ðñ¨ÿjñ˜D77Li†ûq­žônˆÞÃ?àL¢jYí¾ÕUsÎvî¤È¯ôØ{®šM /$”áylz}æ ³ ×x# ¹M¦±™}›ÖéÆ™Þ³[ßäå;“½ þ@ÿíDn””$Qÿ37C.óû:µE`8‰±µßÑÔÎâ0н¹mBØäÑHÛHµpDù&Ô°s9Eç „¬óÄ`ª„1a±©rZîps»†j[¨)eìl‡”Ñ8<¤H©'+%¶l¹âÙ Š«ŽZ5V…?@ÊÉéFŒKpB¿…A¾>/’™\¡8m·uÕY•ÔôÓ¯±Öi?`Òªvåêx6DèS÷ñ€ö(ÓEŽB¯»uÝõ‰ŽG‚¶[ÏT$:Ž2vU¤YCfkÜ(Y8£?|è¸MOºVê‹bº+¦#lXÛC7*mG`´¬+”$—ŽH°(DÀ¢hèW”"GÈKÓn;aV8N3@=2@š—šáêçý¾hŒ`SuÄ»?(ö1‘«Íæ(Ýú O@Zåqâ.Cœét*áa{Fab ƒû¬ªW½ÚèykÎ[*‚÷;0ÃøNݤL£ÿ®è^Nzj½Vb– çYCz4 œo(¯Hzö’U£DWÜa—ÚžÀMp] Q2éKl_\¤ð[#¾ h¾+ÌFÁûÒ.ìð]”[¾;<Y I»‹Í/5†‡Œ°}Éy*Ξ.¥[Ú¾žÀÏ…þÖªUƒ½4ýv!Ÿ£bÀH˜ô¾Î'N êÎÕŒN~]Õ}e]å¸Í,€´!0—ÀÍÐ:_2as ¦&<ÎlÀã ‚²Lç[èxßM38RjÓ67·;žÁž+ÕÚb¼ÉK aؽN¢C}†©dýØdÆ<Å8ié ‡L¼ÒöÙB°îýY°hdØ1F•£"¥y¬ßåOO—:Î׋‹ë»«33…Îøpˆ ˆ ÷ÇÀŸÝo€4bW1uÒuWw——ǦikÇhÙ8ÒÈ'QljÁC»b¤££1p h4q“Ûci<¤“ N“JRºyU?Ù(ƒŒ´Ì›B×™Á@ N@œJhÐ[ÃÄAÁ’CP€îÚet…) NGŠ…ð }A>–I×çÌøÙŒÓc3­ÕnpëR Kí?3Ø”rRà*ðz}(A­T—ÌVøU©/†ö|F—¶#)ãáùøì ‚š©¦1GeV“NòkÃÁús(LÝaþá{¡þƒwÁñ'+1ËdüÉ*øÌ'+ó©jHžq. ©¡ÇêRiÞ¬þ5EH ïþ‘î­O=?¸®zHŸkŠäðj ¾Ô”îêÌ%އÏþ÷øc$Lyˆ1›  jA… Ãì‡È×/5’„÷&Jœ0ò¿^+,_ endstream endobj 5423 0 obj << /Length 1675 /Filter /FlateDecode >> stream xÚÕYÙnÛF}×W𑠢ɬ\Ú§ÄY¥n« Ml"©p‰“¿ï…‡¢'N‹Ä!9Ë=ç.s†ÆÞ•‡½g³GËÙƒ§œx1ŠxËR/äâ1ó–kïÿrN…/«KY•õ|AÃȸÛåYš4YY˜åœbÿãœ@ǼÜÉÊ<~Öfkyß´_Ë\&µ47QŠÈüÝòÅìÉröaFÀì³4G!½t;{ó{kxþÂÈőw£{m=Dpͽ‹Ùï3la`DÀzŒhÀTï€x¼8xøú`‚f¡ü¾º«4]µÂoViY¼ÅŒ_ÓærÑÌ öK Í£Ä\ºî­~7 IÓ“ä­ížî03ÕZM–äöY’^K¤iêqöx)ލÃ/ƒwüð>x°Ø[P\ˆVYUÊÇeX×ÒYïÁS`g@LŽÒ1Qš¥Mv¥ÆÂ‚b0$æˆð°ò løVQæP޼OÍÈt ÇqÑTƒäœ ÿSsÿnö0¦š#J’tΰ-OÄŽI70[ßÑBQȘ©U˜6«]•i¶ƒÀ:aPIô3ìTcßŽÓÆ©Ð£î-A±=—µr@öSÕ¾N*swï½* RÑñyÿŽ(ƒÖwQ®“&9 LæQï {]÷Q˜R‚" ”LçÝ®0+Ì i "bha$²Ô&U²u¦÷ôëÐåõMV¼³”êhMˆ £8Œ;ÓfÈ«ì²JŒ ?'Ñ!oñ;–ÚY$D1cc ²õÄÂ4B4棅ϪASË&& ¤¹½NŠu.§ °³1À‰à1„þØŒ¾ w%næÜmu“˜K½“i¦º¦ÝBøÿÙÂߘëù¯^Ý7Í«¼¼ì0:ó6Ô›ë2—c¦˜×æÜtŒû½ò˜MŸCä J9¦#è窘'[»t¹éÝßmcBíÕª…š\N{ÄÎ~Ä#HóQ:N¥æEM‰‹¢ReQêÚh˜È'§„©øExœ"o)Á'‹*2rEwÆÌE›¦²®GÃ\«9F‚‡nT ¬n«â?±ø¥®Þ½øêF]ýªó•’ .”±¤ã!¬.ÈXÒÅq0)é†cA…FB ¹ã±Gb ÆSˆD1|—9B3< â¶ðP\;~ cD ÙyÀ‰áø¯yYTYqõÓD.ñqÑçø#i‹ìY%DU÷5Ž ãÞÑÆA<Ž[÷› [Ða fýNr£3ú=©ëv+×nV^Z#’Üô5e ZvPQ‹¢ÍóNê?µÑë¿×‘ñ‘¿ þ'h†¹ r® M©3GNqLcø“O™©Là·x:»I[¬å¸æ×}Ý곇XRu¬šsá/nlnYÜš)BŒñ¯eêŽÇ$j&`dò˜´–›¤Í›Ua•ô{Ó6 ñÉÓPð'4ý1x¤öþ,ôÝD4!™Ÿ©­œþ°"zOÛø€B÷;n'– Î«’j’D­|ZW{Á7Q_%”`‹ŒÄQÉñÿJÃ¥fÜΟâ—Õ™BøëùòÉßK³ò£ÄnuÛä*³'ƒ¢Ý^vßQü«>óºÐ¨[>m ’MÞ^ñ±ï¢øè¿«øtÈp1:³]H…s[ì±PÅ~ËðƉeè0Œexmc«³Á„”!"Da_eŽ$h¹€ô5zï.˜tÓj_è¥ÔÇJ½¥×æ¾­Õž?±&u¾ ŠìøðŒô|¢ù‚‘Ⱦ™šö ývp+$™5´;‰*öriŠ÷“¢ð| öYÙZw1û7Ý ™ì¿æ.jicw=.?ûúx7€ˆ+ý¸é: TOïÚõðài¾‚N§½€:±p·Þ! *?¦Á­Ý#öáƒ:f¨ÖÇN$Ÿ%y^»Š·¹îdܦ-Ò½Ì4f .y-G¸*Y÷:ÐQŽ·,uËwZcÀ’ÖJIèíÖÓ#AÌ"Hט3MGOx &hpëoö“Ò’SH[¯"Uþ gvì´z~÷O… bØ?+·J5îrÙu0ï–ÜØð[¤®}øÛsûå]²£êK†úVÿywx”ý,W4 endstream endobj 5443 0 obj << /Length 1609 /Filter /FlateDecode >> stream xÚíY[oÛ6~÷¯Ð£]Ä,ï’6`Àn)ÚC×ä-- Yb!²äJrÓüû^$K´âzM7] ¢(žÃs?i¼ pðlöËåìé9'AŒbIepyЈ#Êâ äâ1 .³àjþrAÅ\ÕkUWÍbIÃhþóv[äiÒæUi'~S ŠçÕVÕvúÙ.ÏÔ™¿V…Je_¢‘ÅÛ˳ß/gïgäÁ B [sâ0H7³«·8È`þE€‹£àάÚ\Fð,‚‹Ù_3ìtÁˆ€ QÉôjI‚>L¾žÒZïJ0Â,´ ßÖk±JÓH+æíê f"yçT_ÚÇ…ùdÇÕVÁnÉh}g¡Ä>R° Ø(Se›'…›KÒ…Œ1zmz­(Ž´è!‡ÿ<’V+´zz.å@%,)Å@#U×Ú“U½J«Lö{z6˜c0œoŽvu]hÍ€öŠ(B1 ;Š7X`Ëÿså†ãý«²5áõ±õ$gÑŽ£ˆðŽR©óíÙãäa †žDà·ÃóuT †pLz€”¸Q‡†Hàp$NuGdÌ’šu礞Às&‰ÀˆñÀ™d:8?ñ®lÀuÉBŠ 21Š)µÜ·IlFìJL,- <… ૼ| Ù"°ó)T¾¹uØ‹¾´$äë:Ñ% Ïï‡LL`8ýG’:.K¢˜± :'NìÏ’2ôöÿµ$üˆy½IʬPSr8nVêË1ràH Cþ2OŠsH];Zç­l’æö¨k}¤.Üc»Ô ‚çJÿk?èòJNqN|(!EØ·ðJð±ð…–${×b«ÁÅ.MUÓühߪöFY?ßå³®Óþ¥™}úE?çuUw1‘)cLPS ‘7’îò&w„×»2u­Þju±Ë¢aŽFT”ÃÌï‹…§…í¨ðóÒpo« ÎŒ !ÈdùÓÜ:×aNî“^“\#®ó¶üNÙê¶ær¬…Nñ~±f£o“®s¾²p›Ø§luüTv ÄúËÎfLqogíê$³o¸a½xÿp{Í¿¡Ü&µ³®j§ 7ŽQÄ¢/Û†É÷>|¼¸)ÝÕš{•åˆDPdtqq´O€ÈxNeaøÅ»1Th¯ô{7~\7®vm'ÈÀ~è1L|)úÕ'{,„l$Ñÿ³ûv©¥ÊÌu}&mu…3aá̮ўtàf­:ÿ…ÊúvêvÛl ÕºmçûZµV\iþtLºOúPk¼]›ÐºJ˜?¨ þ9–I‰$<½s,ÿÄ9ÖœNG~×¼ œêÅÆj+ãrõÃøÃHò¾ë?¿Ö-N:C1 w˜¯ÕV#HÀÌN¬u-½Ÿ@ŽÈ Æi€FF}ÄÜœ7U–Xáv'jï4 ¥Ê‘Œ0È7nT]Ûµý'íM·¨ê¨ìbÌ`òø¶Â±µŸLÌðVF®ÌÉYñ²+ŸˆÀ³>”ºÐ·fNJ»°é·5¯y)+/Tk¥ÁœJÛ.^óò B›]Ñ:fF‹h¥+¢«JÜ85´Ùš“C— h–ÿ4ryCã‚æWj`h!Ûªƒn㛘á’)ˆ×|ƒ0°ª•qò\ˆ9"âk¹‰ÿ¤_óM „–®jÙñ»˜á}?}¢9uC%˜~ù«˜(·~Ÿ þå°8,›:…sŠ!ÊÑŒ‘I× ,’©j¿Œ4>ýÞðÆÐõ«€Ž™gsŒðîêò?‘ø•ýýÃí&ošþêga;Üy-±MßÝëæÅ®VÑ}>>¦£Û©˜A¼õa4yCEQÈö7Tòå:Ž(ïÛ@^N^K°9Fû•h±ä"Ö@u‚%`èýEf/áò§FÛ‡é; fl5Q~b$Yß,ƒX$¥-ã> stream xÚÕX[oÛ6~÷¯ÐÛ¤¢fx§´=eYSô²aK²§4d™Ž…:’')Mûïw(ÒŠ(+®“A –D‘çòñœó WÞN~?›s$(‘Tg‹@Ñ@ññ„góà<üQêj¦«²Ž¦TÅááz½Ê³´ÉËÂü¡#ŠÃ/‰«r­+;üö&Ÿë×öþD¯tZkû@¥ˆDgï'oÎ&ÿM˜‚bUs¤° ²ëÉùæ0þ>Àˆ%qpÛκ¸Œáº N'ÿL°s#ÖcD%3³% *x±5xrŸÃ#Ì”uøs5—YvY߬ץq‡Íe}›7ÙÒš?í¼ap®ó¹v»lG— R{Éà&ÎuÑäéÊ¥ÙÒ­j¾­Ý]_©ƒÛªÎ‹+Ô"ֹܹNqlüSþy,­ëÃApýàXÊžß8˜R°ˆžÛ³²„}*µK>æ³*µaø­/¤ÊùïYê¤L‰B cC îPóT³ÑX TU½41ŠS»Úµ7†Òw–9«ˆàP›¿æ‹)o kL$ˆâ}s)ÂC?Q‚wERÙ{v þûÆz’/zµw]ò ›üfÈäSë?€"ϸ©ÕôxãŽ#…Ãçër—óR;“ŠÒ •.)òá‹Ô^´ùÜmä÷7vSáÌÏ”ö©?d !b1²ÿK´µß‹#KD”´ üe,*ÛÀпŽD,M$dílH Þ:$ {‰x_W8CJð‡ºòƒ„' °0A5|›ãþL?[Bf››u•_ÛÂÙÖ€\:–Ì7\—•«•ÎLgñ d§«ÊDhYuÌõ.ÎS Ë-λëƒ-OKuäÑ\ÇG¹î‡ b n‡=¤3dÂRï4ˆ!œt®ÜU€m ¡C”X<9£Ò8†(øùu§*Š”¤ÕeZÌW$VDÌ}Ÿ€Xé#¸ ['No²L×õkŸž¯u°¯£ Ž+"ŽÃ_"Þ5€}RÞƒ“=ˆ8F‚Ç÷BtSÏÒw|0¡zw„æ¡u¨Ú`d `mäµÛÊ!â=mï» ´Á+ýºC©ê§yW†„ ÚhW¡F |ӗ׺Ñ݈ÙÞšº‚Ò”VêL<[ÛuÌu—¬»Óga¢f+àîØÌï¥fpJ.®œƒMé¨noFÐù”À–IŠýC,Xp™Ý´|]Ï-,skãM¢z/öãyÏ;óÜé1]îËço‡ÅEë{άX&/äÌú\<¾‰b÷r‡Y*†>·KóWÌ„±RO:–Zçäççòn>‘+¤y7{¦†SK¿ˆ#°ÏÔ¿9qßËà•×®v:o@]#ýÉ‘j'>]ÕåØûó·KEaÏ{¦˜@vä4>Ï„Ãf¢‡Ðö!*üÞ=GOtœ"BÜÞÆ¬"œÉðh™®»¯”¶LKM%O£òÚ”ëõªûŒißÛ¢¿p+à¿È|¾8üû£‰bnoæicf¦¦+¨‡Žþ—•X endstream endobj 5482 0 obj << /Length 1464 /Filter /FlateDecode >> stream xÚÝY]SÛ8}ϯðcÒ!B’%Yî>µta¶0´ aö2ãˆÆƒ±³Ž!mý^Y²cB ³ì3‘#Kº÷žûu"°÷ÕÃÞÁàýd°»Ïˆ¢PPáM®<*¢~èL"úÞdæG”Uq©Š|9Ó@ß-iGe’gfâƒQ<¼X˜æ U˜éƒÛd¦vÌó‰JU´Tæ A”"2º˜|ü>ü=  öˆPÍP€/¾œ_`oó=ŒüPz«jÕÇ„„1õN°µ#&`D…¯W âðâÞäIŸÕZ*Áû1øº¸äÓ8Žótß‚)|¸Ì‹i¦F|¸2úÍð¹z©‘Íd9"x˜›ç¤ièôÛ¨z4Ó¹FÔ e‘*çöMU¼F6¿2ãu–ësWv:6g*+“(µsQ™žî$À³»/D ì)èx UÚÀ$ÎgÊ‘·»`¶…Ã1x WƒéJo™¼µ‹àI&ëm_0ÇFÈÏÁ!¨]%ò¬¬àÿVvÔ÷e{C’ðz§Þ¤F>~+w~M߇G¿­@óZD2Änc°ìÁчø‚Œ¤?6áT¿uêØçâP$Æ£Rs:ä@tãïQ‚Bxc#·ñsžd­[4¡jt‘‡£ƒ°V}l¶%—…N5Øô½}Håk¿£©=eLú¶šç·e­B 8WºaK:Ò÷šÕ[#@àiå[  ÆJ”w:‹ {ûŽ„£XÛ•á®%_(Á… ”pÑ@ˆ§·q¬–ËßÌ·ÊŽÁs•T¥欵‡Ú5ë¢Ï±)U|XäEýL-µ|o,8bàaG»Ušu‘ |ú¸ªŸzoë8Ÿ[™I© ÓMŒ…S |DÃ&YÜ éXL%’¢ñ[9¬ «$MÛ’¬Ø\GÎþPÖ¦¨^§Ë-ÌWåVë[´Jm[‹M’ÍÔBez=úÊŒå÷…B$>$œ¹(հ߯W…RºôUykËÍXØVÚ–˜nV³t5WY ‘­m™•šæÙWÃj‡&3Ô—w$„ÄÌ üS¥j—ùÛ…° M_·0©Þ bŠð¶¿ÓõAœO|¬ç› Õîúš”¾í®ÜØž--È6výjßâ…ÚwSwþM8ÂëÒó/÷oöÊû·íB Q+¢5i²JA‚ª;W©é* D˜Û©ßÄë"ÝC- ‘gg$ €ûC쨃ü¯0 zOƒMÄ‚}ÁfbÑ•b—oä/u9Œ ];÷6õ1óue³T=•âp_¸*þï)íoÞÓ8Í—zvõª¯cÃ’7iëfl·c;?‹ž·cëPÃ?>OÇäkHv¶â:ÆßúO¾êŠ]÷ž€JH~vï Ø#÷Õ¯Çv}–Q m!9ÖQýØ.ÕÛ~/´ë¯Æ wì’èph®šmdŸ™}UÖ ©ê™†OÖoRp614¤åùBÕ²g;=ÁFE-"ø‰`«,kV_ÇõñÙÑÚÖeÀN}Àþ‰.ûÅ«J9|½¡óh}eeø&ùQEÈK_è<3#œGwFa%¤ [¾â+¥!èó_ŸPì˜øöú„¼"’³}Ó§H†¯ªé¿ÓPØÒ¤·jcžÕå×ɯž[[ã…Z6?䓬Sx[IíêèØ56J:táIvž¼çÓ½½é±6ìÓdÿÓÙñ£À¤G“Æ›¶´´H@«mW¥ƒS`tÏÑW%DzmýÓÚjµº}cTû ²-C$ð“ B=:GAÕ€Þ¹íÿ$zÛ£ ¹ÅB ‚FcÁªtÙÿ©|þ£bšŒ‹êVÕ!}'dÀÆ®1F endstream endobj 5499 0 obj << /Length 1593 /Filter /FlateDecode >> stream xÚÕXÝoÛ6÷_¡G9˜Y~ék{J»¶X3]êama( v$O’ëæ¿ßIÉ¢ì$mÒŒ„u<Þç޵G½×“çóɳW’y IBzó¥q/’1‘‰ðæ¹÷Á¿˜òÀWõ•ª«f:ãQìŸo·›"KÛ¢*ÍÂïjÊ©ÿyÊ€pSmUm–_ïŠ\ýbæ—j£ÒF™F8'lúiþfòr>ùwÂ@ê1s´$¼ìfòáõrXãQ"’ØÛkªO†1Œïýä¯ µjPÂ@zJx(:d^ /Ž/ïR˜QBEd^×WÁ"që…ªëª^ܨ¦I¯§3F}«ÀÌ /ÈLÛ•}¥Mñ¥‚)Ê\åvù˜é1³ÂZ15CV•z·áC´•z5íøì•ˆPoÆ%(>OEàWEŽ[Ÿ½õ”ô”l¸OSe6»ÃFÆð¤Ûù‘ÔHF8Ѻ‘„ÿ2áÇ‹—(s„ WÔ#Œ7Ôy¤k IÌz ²öËIa —r +;iŇFà*\g,á$ B06% ç†û6­Ó‡½ÇIXô0Ö'Šòø7 ‘µ'‘ŽkM=3¤Wµ0êßÚÍ`$…î5FòfQB‚„ÃYI„ÍØùª€L"ò—»23i*DèïÊFµöŽW\´Ül°â+¾¯#)lÄ" ‚¢4cjÞd‚d$Ce9•Í®VÝikè‹Ö²iÌsYÙ…XhÓ5ƾ*7xæ­!Js: ;þ)l]¸h êڻʲÕC•™2Ö«–f4É “&½±³¡ÒÆÐ¹²¹÷ÕÐ2ÂH0;¨²RÙtøkȺÊ̦ÍZ>dýÞÅ—ŽÜÅÒŠ¶Ï´øþo-•Eé}Ñ®:héÑ)Ýl*†ßXGÉ·ÂïXRËÅル¹È á=GIoã\••—€j}¯‘Ç"†(ÒŠhmYOu3‚Qð,ÝÜÑt„Ò­Xt¬ìGÎè}QmeØ[™]Þï² *Ìh›sÔÌì{üQ—Ïø[œ¿[¼¼¼\¼¿xùÏÀ'z¦aF]pÒã'Ì5l DD4ÏÕÆîÑÈ©]`ª‰©[Søª«s ¡x¢:#ý¡:ùÔRâ›0¦q"Hć¹hðú8²X]|‚Ý© tÓ½²Ú]¯ÜÐêkã ~Z‹ XX{dYUçEy}×ÞªüH…¼†êŸ?Ú‚õ»¢‚?9ý`ß$‰”ñøÖ ¸5軀“È‹Iè­³Þ¢muÅlÕ¯'LÌ(½/ÞOhéÿ¬oéƒõAUhHbξU•'^€TL µoX«¶è‹ÛEšç¦Ú7jÜöÄ’ØÖ¢»Æ˜æ E[ܺ„Ãê§oª­QÞ(~\î’оo»ÀÝ/ÈÔ/¸Œö Ä÷1`»A:ÆýÎ3É2“ gE©ùHê?QÂPÀkþ ¡¨Ç$ÜmÎÎΪ]«Yû[?¤½a ð¡Hèþ%þß¶7֩LJ˘ÄɸÁ9·Å%E_ݺ׳CÒ9Õåª/.[¼ žОä µÂLw¹CNhhŒäDŒ;!áWIÿ-}Y ^F÷øïЗñ'÷e¿YíôEce_tíƒ5Ñ…®ÙýÂ;.ÓÍC‘`Éð{> stream xÚÝZÑŽ[·}×Wð±éEÎp8ÀÄp[ ŒØI ?¸Ž VÅîHÿ¾g(Qò®×³¹«…k,`^jHr†ç y¯°å‚°QÈܼÀ´zACÉ%hΡˆxE ÅþÐ+,Èδ„š5HI-¨è  –Ék8äTÌK%äܺ•`,/ÕKe”r ¹¢•fC¡ôªŒR+n¦!ko@€Ùª`„ œÉ;HÊê¿qö¹*Ò{Ñ@‚I¢d˜9JZ­^*ð(1 ¥†BæUWJ8“÷†¡9×>~LÉ[ Ì¥÷;©Ý®Öäcan [8,¥Ê„íËÄŒq¤`\Bñ%GI°ÌìKÆXøªÞ ¦WZò9²aí‹·õNSë0$Ÿ2l©Ã+î_ÅîŸÂÁ! ªl7Ty?;{´”>ŠRíÓ ÐÈÔY·ÃJV¸ÑKp5õ‰!&*kâ¡Jîm[¨µ/»X¨j>¸· jñ‚ö*ÀIÉP¥(ø€GܤTs_8H³új‚ƒº_[ö¹y©¢¹ø|‹â×Ú¼MùÊ)µêk -™Ï!Òˆ&‚¶qm¡IvOÀE,oÛ845tŠ¶Æ½ ´êÁ +K¾’ ?šøÐ0·`ðŠ¥½%”Ô×›Æ(û$úÆæƒ6 ïø¯°Û¹XËÑ`Öw "1§¯Ñ.'êÞ3ì™Ä•Üs©o.¬DÅIØ(«'OVë—ÿýÏ&¬¿¹¸Ø^¯Ö/Þÿûº?ÿóÝů«õ·ÛËŸ7—¯6}z½þûúëï^åþ°Z¿y{^!F¢OŠsŠè±h±a.ˆûذû&Ë)°Ï½9…øcN¡|NɃJò ’<¨$×QÐQ°}Ò°LEôd@,SÁ2‰õœ,ƒ‘+r%dtQ<µw©ç¤{Vš!‹ž«(Œÿ“'»sP–ÜÝãH¬Šïjšƒ‚l~Iî­HÂì)\À;8ÐT ‚œ@b rï>d¹(†!˹çs†¬". $ ì²4ƒävÈv¢$š¤Þ†àÂi#Ðn‚2œ4Ĺ>úÁö´aEZœi’ȧÉúÉßHIËD^&‰¼ì&tƒÈi4µQlÍiFɃõy°>ÖçÑ~xôS„õ‘+$œJ‘õYb¿GØ#¡VQžC²4ë—H|\Ö ÕY(K²>ÎÈÝè1 :韺8×J¢Èùȵ’k¤zV®p«¶’~÷[•$ J‘˜ýft@1…2¶Y(‹ŠßÙø½ÛJ±s›†¢ºx¤Põ´àH)„ôiݹIÓ’žHú­ñ ’H$õ¸(=‘¬: eÑHñ»4ˆî€R°Ÿj™ôÏ7Y~>—ª”™T¥Ì¦*· ©W¢‰a…r¤2aÈØ:3ó Öb­í‹Ë}*}œûÔtÿÜGF‚#yF‚##Á‘‘àÈHpd$8b™×P‹Œ`ŸÒÍ–Ë’$„S’Ê1™H8¯=F^3îµÅþVîpÉ3_#¶$ ~˜iÈ\#b $~^sgÍ!Y’•‡h6­p¼}qÉ9ŸÓ9~dMv@ÂY¢‘Ì!YØ;’v×Ì{(8]E³i(?’ªš'¥ê†á§¤ê¶Ñ'¥ê–¡_å”Ó†ù$ó>¿oðø=mŒ•ø‹Óªv‡Vµ?¡Uuœ¦uˆ–ÑÒ!Z:DK‡h鸋Õ!ZjÿŸ‡q?cáôp-äŒ Æ~ŒÃ¸Ÿ±êQ? QT¸fö0ÎËë§”®àýl )“GàèR‘yú‡&{Žv;÷ÁfÏÑÊàèI(Kº9eô¯KAÐJ‡²¼šgðwÊÇH¡ìŸ-ØY#¥ú»¿ÆáÇo,¦Üy1Ýf%´ÍHh›•Ð[†’s÷íIÃÒ$²êiC*›ñ„¡o¶’¿8 µ;¾ƒ0½¿„¶q‚kCKmh© -µ¡¥6´Ô†–Ú¢ŸHâÚ¿“;ÜkþåÞã²¤Ò  :·ˆû^o$œ¤ßAM!YX%Ø¢ù‰{(%é,”,Ë¿3$‹’åøÎP°8¹õv<®cO•]jîoX8j+çuOéWè(æoàç@–”ð刣+8Âæ>@:uÛì,Ö>-Vÿh¸Îã endstream endobj 5522 0 obj << /Length 1618 /Filter /FlateDecode >> stream xÚå™ÛŽÛ6†ïýº”˜áYd{Õ¦MÐ4(ÚĹJ‚@kscamÉ•ålÒ§ïð ãÊΜ¶A±ÀJ¢EòŸápæ3£ŽžM~\L?å$ÒHK*£ÅeDG”é(á qÍ¢Å*zÿ:¥"6å…)‹ýtNÿ°Ûm²eZeEî~2SŠãS/nŠ)}ó³C¶2üýK³1éÞø‚(Edúnñ|òóbòç„€‘(¡05G N¢åvòæŽVÐþ<ˆi]»·¶— ®›èÕä ¶`DÀŒ¨dömI¢>¸ÑørÌj;+Á³Ä|U^ˆ÷Ëbgmúü>=TëUZMç"N½ú¹¿< oø§4¸Â¾^”Ù_ïô{o²}…œéöÆŠ•špøÏ•ô6 Á†ÇO¥ì€£9å`Ÿèè7ei×­(Á’•éÍ÷ø)XÜ1Çাñá©í ŠNÍáIÝå-ØOp_DÝ@@^¹húT ¤3ÕíÇ‘"¢îi;™)ñ§êÑÃô0fo{ŠÀS‚ãÆ#Ç$I‚°n¼9M{kD8žeyí×JTöc}/‰sÊ`A£9!H‹5³Ù¬8T#‹M¸Å&ãÑû…+ŒÊº"HBQûpNAQ~ô]Z¦ÛÞð‘û8ék}“åï¼CýšÃ6ü¤÷ã#Ý:iÈ.ÊÔf(¿w›A\àû{JÃ( iƆ Ú %JnLß ˆâ2ÌØ ?Ž8''×ödÔù ¼‰‡eu(Í~Ì.")ì»d`A°¬ ‡ÞTL#Ñî`Ôon³Nޝ}ƒs°ˆËÔ¶}>a«„8üì¶Þ> EšÖ«Ký ¥ßØÕG›EÓÍè˜0ïz†"<Œ“·”àS{ꬫfîeìýôê°\šýþûàµjm¼y×™«ŸÐ¼þ« ü¶2 ûàÝ^”ud¯¼?¢¹ˆƒ£{êëÌvÔI|yÈ—¡bi/K“V&|”úKÞ,¯msUΩjKv¥.¼¾iÞìK³<Ë?ø÷ÒºyWÇ<ÆÕP™u“~ün«Ãc$:¸ri¶<ÀÃ:¾^gK«fí'ÚZm*¾0ÁÀÃf3¯‚¯·YX!ï;Æ$š÷“Ðëz5\Ð^–Æ4%ÓVD—(ÝçUá¯ö• ÄM¢š5¾ëˆ@R5)ázmò}BÉBäa®M®vÜÚYs&Øq”­3îjËÂÅH@@ÿ„9´êm/;VˆÕhåòDá6–ùnÄLª‘$Íê-ÖÁÛ´›3Çr‹É«^JÏòOC(ñ„Ü%”0mÒw'h`ü‹ , ùïõ‹þnWd¹ "¸½µ·1À˜;zûÈË%G‚ÐcÈ µˆoÝS”§¸×_êÄ=Öo_•.3[6_ }åÙÑ7FÜD"ûƒ¶Yæ? À5Ù„¨}˜¼¶°-Òýõ>!5Ñ(aÍæ›Y_–Åö<'š ™±—šÏ¢ÐI„Ü}sùÏ”Ôg'bªT}óDì—Öeúí¿ÙìĆù£˜›xׯ©u†m›™Õ˜Ö0]ï:Û]ä¾§"m±2Ÿ´Àâö®â‰@X©¾—ÿgdÊq—Lá©%SN\íá¸C¦üÈZð#Ä­ôjíï*G0¬ þ¼ò­ã_Ð0ƒÂÑ [i.}Ý z¦€ßš°${‚äC‚l”7é!”Ã~Wý[R…(áC>ŽáW‚!ÏD™·Æ“›Ì…€ìöBb=‘[®ÍҲĕ5cØÞ’NÆ»ýprÞs9kÇ•Õ?z.ÇÚõ;–{s ÿ7¸dis]i¸Ô^:zVǺ'[³¥ œ«3@ lvÁä½eAýçtù.kñòF„J ýŽè@H’oHê…=Š$нƒºÔÛÕ¢aµîÈ~¼cçjý…ìådHˆäöÐáO5†Bȶ'üìÜA¿!î¼ËðÔr<¤þÒr<]~„aypçÑÃNãÑ#Ìsä@L"Ò~ûðåyPøVÓ°Zòà¢>»âòjïžañûügÌ…¢ ßa{9Àk;J˜HŸëHËÇÒ£¨qëÇÏI("õ1 x(¹v~ ?†þþ‹ '. Óñ” û<" endstream endobj 5544 0 obj << /Length 1384 /Filter /FlateDecode >> stream xÚÕXËrÛ6Ýë+¸”<Œ7Áé*uêL“N§MÔ•ãñP"³•I•¢âäï{ñàS¤«H§Ýˆ\œûÎqð)ÀÁ›É‹ÉÅ'A„"Ie°¸ B„\!±`‘×Ów3*¦ºXê"ßÎæ4TÓW›Í:]Åešg®ãµžQ<ý<#0potáºßìÒDŸ»ÿïõZÇ[íQŠÈìfñvòÓbò÷„·4G!ƒÕÃäú ô¿ 0b‘ í¨‡€KÏuðaòû{70"€#*™-IPÀ‹½Î÷cŒ0 ÃKq»Ê7Ƨ¯ð'+gà—i})þ¹{\ú1®»‡Ÿ½?i[»U¹ƒØÀ d¯Ñ×^P¬ ÔÃ/WÒyÑï/.®¤l¹€ƒ9åà¡hy ‹Âd./M¢;ë]\Ï­€q êºï\צÂz¢5C)‘°šñ ìì‹_ ÊzëCM9¹å[È™jÏãH^Í\•_ÎOÃABD„<‰¨fže€å6ß ÅŽCY²¨;2\ ÿò«¬euD<„:À(¢ÔßÄEüбPb37'ð¾\®ÓìjT`A‡¸ã£(´{ÎŽž»¡¿¤Ë"6Ým3ٔˌ‰i]2]€ÎÊb1¶\CˆüÒ݈uÖ—),zëÿj“2cxú¸¿¼íØš¥ƒhwž~2Ð}¼ "¤ÃëZ̆Eá§ül6W¼4 ¦x7~8Œºž¤?UOp˺H°sèÃnµÒÛmoZ5T—à½(·PïŠìE¿3'_CÂ4ÌsZäE•®D[W‚¹ˆC-v"½¸×¾.|Ž!±kòªØ —:IýÃÎ%ßµ–ÞTá8ÈOZ»•µx½N³O®a·ý]¡õmË®9ãì^µCïuæþ¥~Ô»™åî¹ÎÁœ%ÎÊ èÄû“U©à˜g©ažrÄ’l¥¨îø—`'ù¼ìTðûçk…Øœáß™›êS«UJçuÑú"= ^ˆ]€…)m1x‰ 0F§’¨·Ò%ÑI¢=ë“&Ș÷\B˜uV¦ñz;Jš¶¿Ì»g)lÁ´ÎP7˜n1ž·¹)T냄C¬9«ó;¿ªìÖ ëj¶q`Õ—ô31NžÇR>=™òð®—÷Ú¥æ1ÝúDøO¸¬"\KaŠOïv ÅÜÝZŽhý«Ø=²Zw)aør/ÓòÞý+-‡¦¨³ÒL e ѱ öEhœj$šÍ9l—?¶~­{‚hñ6`µUl\„÷ X¦¬¾×¸RCÁ´ê˜¶‚À<}¬¹AŠî¡ñ"* É„$. ÅǪ„îð|ù§^•ÿ‹»+‡ÄC”ÊÿÜÅõÅA˜Q.f`‹¶t™pº.`„žÃH‚‘”² Ažÿ>I¤Ø7jùÝ5Ý×vÅ‑>ß¾6v„c7ü À}B< $ É‘ jd¯Â¡)Ãg§ÿo¸?«—£Þ¿o»lÔ¦h5ô/3@_CÿÐhv³m6£*%½N s0ƒ•€„3š©ýDî«Ü ,:PÁ²2ÀLoßÞ#_ÉѸ €ìqÙR#@àæºc%€£|.‡#£s&õ¡ÀWJÿ#9°•#üâÍ)"Äç^IXšp&§—÷ñffXÇãΗYÉ#ØF lÖºàÞ»/w~üf+ݯ~ûÙëŠ,q*QQ~ÝèmßÑ‹oãe endstream endobj 5568 0 obj << /Length 1518 /Filter /FlateDecode >> stream xÚåY[s›F}ׯà64s=wì"îv¸’U¹vïÊÂ7eeagðs¹µ#RºûYë‚ibBPš$ng¥é«(IBdíßÐ_Ÿ½`ªc˜€r0ŸàCÄ’°Ìçfè³`¸Nì€yz6ìÛO»q0Ûn4U÷ßá;`ˆbeÜ&9ür%œG‡² a2ÀÖ2± ¦êîy°×„#Eøýȹ®Í˜fš5ÏOCÄ—:R]e͈©BŠÓŽ É¨s?w…YYgÖ˜¦™À F)¥nöͬš­{ÓbŒÈ~¬]åÅ5c‚%›îáþRÜMìúÿ–ßT3“ .­ ÅXK›Ð³± Myÿb±¶›OCWm7g«Þ®ü¢1‘(elˆ¶®Œ_²C€ÁÓ”>ð]ÞÜúW[Ó3 +ÇØ.ÎŽå²‘ÅÆ]\1#H’ÙÒÆœùùt³*3CMKGɱ»téL…3wuˆA¾8M\c‘{Ãdå\R¥Ç?&ÇbŸ–Ú‚^ŽdMÊÁ\òi™ç‹³¼Í‚N윷Ñä¸èDx1Ögho“Cˇ Œ$m-uf*Ò‰œHSóXÎÚ$ïU‰äŽ8ŸŒ9M§üDBtv¥{”bR™>ŠbÆHÎÍr€ä–äÊõÈò#¥ä`ù×­¶Tk}D±åßè–‘s=Cä'vˆ¼é®ÊmsÝçêÆLùÌóé— w]ŽAt0ºq'i› Ç.ëƒc¸Â8â@5=ÛV‘lF_}0sÎVä•àÝýQ„‡^zG ~(þAš‹6<°ÛüÛm–AùÁ›ÄJ<+wyíýÒsd+æóàʑ՟ÖFùñ ödP(/os3P°p±-2€§¬Ò³FÛWÜÖ h+¬;îÜÃr<„à¯0ÎÉghªgkgühüš³zÄ¥4Ibb̧ÓAZ‚¤¹ïˆ¢˜IþYû¥, -*­§cXMy°~ß6›m³'9%  ^IB¾¦~Pÿž~à}ï;ýÀÀï;ý`ž¬ëü[$áâoš¡BŒUZ‰ÌŽ+þŠ´ÉØæ«è—c¥Ô1U[H¨r2€~XF´%a§'ì–Ko”zB1à3úHdNO˜iž°WoÊ¢tX;ÒÁzŒ)J:ã)õ›*/²|1ÿÙom×ïBì66òõNÀR~Ûà´Ïž n÷>ˆÔ–ãú–9HU†«ÚòÂlf㘠FŸN=xG‚ª S¦I?IΠ˜ì ¸›)ÙõäZ€€XʼPßí‰{ç¶ÆÛC@†Þ´æöÔñ(Eà§<¤¬;ÇÁ |'?÷QbŸÄ¹‰ÇtÍíüÇ;(ŠSÖ¯¨G*‡ámõTý?Ûè¿f A< BÁS›IþÂ7¿Ú²Âa¿–ù+ÙÀþÚvÑ endstream endobj 5588 0 obj << /Length 1810 /Filter /FlateDecode >> stream xÚÍY[sÓ8~ϯðcÒi„®¾ì>u¡e€N‡…°/…鸉B=Mlc;ö×|­Sº¤³Ë0TÖíè;Gç}R¨÷Ù£ÞËɋɳ3ɼˆD>÷½ÅÚ ¸ÈÈHx‹•w9}3ãjª‹k]dål΃pz’ç›dWI–bà =ãtúuÆ`à&ËuÍ/wÉJã÷;½Ñq©±Âç„Í>-^ON“/P¨ÇpiIxËíäòõVÐþÚ£DD¡wgGm=é‡Pn¼÷“?'Ô©A»êø²£ã!‰Bß %T¨ÓGΨ]¾ž÷ìL„I ¾A‡L´¢Ó÷»åR—åïX˪«&Þ%V-h›cñÆ£5˜2SN‹¬Àú2[éÒ¬ïÍ}E¤RÞœ$\Ü$f"ãÓõ.]:3CmYè¸Ò®+Æ"Õ3°’#¢$]&y¼Á¶ÒìJ…»eµ+4¶ß%Õ ~&N~–V:­ÜÙÚ kúÃp_)Emš$Í X ö,((X½Gfsë(ÝJ·ÅµºZZ_õ!¤ŠÂæ€eÎ 0p ! «×ÈvÕ>0s)$á°ùsÆH¤|œpw£Sܤr¥Û¯4Ãr“¥ŸÑû]»Ö+½"è9„pJ¸/ŒúÌ+À•î5¾{9Œ/êÍ#¡óDk‰e–Ÿù~U%ËÙ\Mom$Í`ß0^æX}™¤ŸšM­ì÷­I/ DÍqáNó予1¹}ï ±¾âôï!uRð$CëÂØ9ÛŽ,/) !ô—_´°Eð÷ÖžG.ÅU.µ]ëTžèÕ'¶w2]B’u€ò³ÒFR±%xLî)àlA4}„møžÏS}k’¶¸¾š<Gà˜ÄAœÐ¡ÝÃÂÿŽÈ>:Ç‚¨Ë Öòƒúxˆ:ü*Màö¼:FI‚‘.'iÇ ŠTÁu8ªµQª (@›»Æ£aÌ!ö¤êrÉ"ÇjЖ+ô‘w¸Œ²~m,²‡+ T-É1i§d£tA)¢†Ùàס ©éê*ÞU7«¸2‡{Üã gIºrNC²"ù»ÃÕû3€•oÍ>þêä`´ Ç#§G$ “ÁÓÒƒŸfj”„GóÙCÖ0ÜXd$H”4j¬yÔòë£Gý jl| Þ9“8­è‡ÐSâŽó«By*¼Œ‚ù{í[}ÏõCXƒ€øª9âÕ•™p¨ ¹äÀIdÿÒrˆ Ž ]î6U9@pÚG*xrúÅ¥OB§«ãW¢_þÿN¿øA%B9†Ñ¦_¨Å#°BŸ¨6‹9X'æ4¶I¯½Mf†>»›x$]W7ô}]jáÝC"MÌXŽôå‡è mVìIÑŸ¼ÅÂÖ€Øéöž4Tí¾O Œ¯1W$£ŸBm%ö(2³£¾‚ËôáµÔm܉´!F5â®]›ÕôxWKÓ|ƒÌ0ÅÔ±´¤&ˆŒB¡bìIPÑaˆ‚Êi©ã%êr„%ÙUËØú7¼{Ig˜k$‘Q›Ãõ²lPÕ­7ŠÚ’0£–IÎ$˜¨@ýjƒúÙÖÖ=zë‡ä[ýö»‘DùªKH#1=MÒ›u’ÔØ$Ôv¹ÖãMç6v7Óu­q›€ ÅU?Ã]|8??6Oc‘¥,3Á Âæ¥}35†tš–»d³Á–4sM×nHgwWp %׳–ô‘Å[™5@N­F‰½Û]£Ug‘ÊÉÛ&)\6V®³Ö¾R8´ë¬`Då tLcÚg7•a­#|µ*a=IËd¥ñûäÅüÕÙüÝéùé_3ÌòäbîÖ¢ £ˆŒ¦ÉÛÑqv†£,,u½±ð]›àú ‹½„˜ööRŽöúaúMÎ0Kí¹~ ´E·ß— ¸yÖlŽâ¯öÍÜ0ûXÆðÁÃý—…÷ÜåÜñ¡]ô7à ª¡ËAöÁž•ú·15#â³&\àÓ¥»«-ÖpͧU…qˆÛ«I]öDçþ£…ýØcÎah^²¥ð§ÏoâÜ>кý‚;˜oœ |ç¹9(!7º€ýø|»v3àoºÔ½ûÞÉÛWîºWßûêKžÉoeiÍþÕ%T© endstream endobj 5604 0 obj << /Length 1117 /Filter /FlateDecode >> stream xÚåY[oÛ6~÷¯à£UT o"ŽuXS¬ Š,óž²ÀPl9æXž$gí¿ßáE²¤*¶§íÀ@HÑäáùÎå;Ç A7ˆ £Ÿ'£“SA‘ÆZ2‰& Äb×H‰ ÍÑdŽ.Ç¿,§ÅuZäe2ß­×Ël–TY¾r ¿¤#ãû€ÂÆe¾N ·üa“ÍÓ·n~‘.Ó¤LÝÅŒa\M>ŽÞOFÿŒ(èCEŠÁÕ+¢ÐìntyEÐÖ?"‚¹ŽÑ¿v×2†q‰þý>" Á Ì$7»%E|ñÕâÅjs+%˜påÿ]\GÓ`4é4™ÏÝ´,S?té1ŒßæVª[?™'•YOÜSY”Œs·uîÖ2oº¤(ÜN°Ý·”/üWí›±µV×'§™ÄÍ ÏUéOÀ˜Æ’6˜Ôˆ–IiVî ¬Ø‰¥lu€î6mµ7|úóìÌÍÖyn*˜l,ˆ „GÚêÈR Ž.Eë©›®§éj6]ûÄ«öT%_…¡íQVÅfVmÜŽGUùôŠmµ©8“r‚Õ6÷_Gá1~2…§å'“[»ÔÓRL6Uèá"D¡X(ùìEˆs É!}¢‡!ùË;¶‚ŒÃ‹÷ç5‰Í<ãx¶ªWøÿ¹9ªu¶¶T‘T¡ƒ °Ç~!8† ¡DqÄëBtx¿>|öéztTÑñª€]%d:~¥§ë£ºm©-ªФ‰iD_Ý›"C=ÞÙξž^Ýûû«W8ïà·ðƒŒ(¦ÔÄB)´Íÿ_„ó_­EE$m$z±î+ö¼êäÊ endstream endobj 5504 0 obj << /Type /ObjStm /N 100 /First 976 /Length 2097 /Filter /FlateDecode >> stream xÚÕZßo$· ~ß¿Bm´’HJ$p¸6@ ¹{hkÜÃõ²( ìÂç’ÿ>µ£]{gîxñƒÁ™¡¤OE~¢V$åBk9p"©Íx”Kñg ¹R¶Jb¼)9»jÚuZ¨f.hPÒ  ÖðYr9g×Î=Š‘Ñ%Yr‰C–¢.U S{‹²bTH²± c«·(Jɺi ¯Šø …!Y Mñ¨ù+Ô¯šsתöú R‡ËhP©¿CoÊ„ðÕT0ÂíƒL÷÷Ýßuós¸òÕýÜÊ; ôþ­±#÷Úl¿¼¾¾AoWû¸êxz\‚MBÎC(C !ðF?yô“G?yßÏÉÌ:†ÍöÍçßõçï>^ÿw³ýêæöÇÝmÇŸÞmÿ¶ývûõUî>å0Vƒ'$3"dæ}GW“˜¨Aí˾‚oÂö¯7ooÿOŸÐðãÍõ_¢Õôg7ý"@ F® U)zÄ(Ž G Šœè÷‘äÒx9(T,²GÆ ^L=ç@AbX · i Ab‹ž´ÖG2ù Šˆ2?a¶‡^ÓOj “0µˆ4‚ìžcϼ-jk«úIC¸E~PX4‚á̃¢©¼€Q¦å!®1y`2¤Þ‘L~R²Eo~‚µØÊñD‘¤ 16/õxRh sÌ&«ú‰PL|„‚$e.ÍmÁx"å$ç!qàŠ# #x>"å#¾ðP™Iö¼ÒS¼çT¤;‚‚ÏPŽl3ð•†%²zâþ=ö<$3¿G{¤ =Ìi—çÓž2¸ ¥! ’CƒÛÐà6$C$‡·¡Ñ~8¿Ûqþ‹ƒÁÙIdi$E-¶Fó,R‹\ŽP¨fd³‹@$C9Ò=Ža8„]su GC”f‘æYxqÀ³S‹=l8ÌB¢uÉÌá™:á*±"Ьd 0àÊÇ-ì^Œ“øšN‹4„åëŽý3ÉÒ^’£e9@!@QœÆgAÑE, FHXJ¬Vž…¤ç[¦™ãâSãTéI‚q¢ˆ“ÍÐKiŽ"‘VfŒŒ¸½öGcU3Œýç†4zÄ0x0Ì@FõDÃÁ0d0 Õ CF?uôSG?uôSG?U–$Åik‡ZKi~BÙ—8ÖÍù†œo(T‘Wp.¸”)žcP2¿Lj ¨YH–>0çP8cY¼ê> J*Kæ}.ÝIp¹Ð% LžBb^û:f~Äܺ¦§hCæG–uÓ´@0Q¾vrVÛºûØ ‰ÿ€„kÂv¶™H]œa“iqˆ[tÒåN’E"òß𑌳M-´j4¬ 1aAR,^^ÇIÂÔÖå† &.àcu-ºdå©FöÛãC²F!fÚxam3yáŧxá‰RUíå±óŠ©Æfz^ñÉ·SE¯ ¦ÚÎ+ú¥6ÝyÅ’ÙkÀç³Öè7Ô´;<ý ª©ÿÕlƒ=¶QŸjƒF¶A#u°Gu.4RÔA#U^¢†…ã'Î}ÇùѪv‚–z@RŽæ…£9HrHÁÔŽPH-Î4IÎf —IŠ€xÄ›q(£˜–<þß»°Ãy’õ¼šá. »dðjÆ{Ë|‰‹Ýe\ì΂²èuêÁ(H„I¼R“Í7‹F[óŠ9¨øO’&$ î˜}yæ!±°ÉÞc&°zî¤Ñ~£t¤s)‚ž$õÊ1ñ =ÒXêy=nO…NAšý*e^­ç^ê|TÏ™]ºŸŽŸ›€3œ&àšÊó°Äi#ÛÈÄ62±LlSAÇf5 ‹^e„«*õxSଭ\âzÄ,oj°a°–ó Àý—¼ iQÁã[@‘ú3ÎyA£äºjLÏȰYP¼mþ»¼9P–C’‘M¡“œÊýR½ydMÈý´êµ‘ßX?†OPˆ,ê< ˦¹©äYpìäv¨xòÃàÊ·œÒ=tBBÎUýÆsœü@ÆC·ÿ8tVry¨xrþüTû endstream endobj 5623 0 obj << /Length 1140 /Filter /FlateDecode >> stream xÚíYKsÛ6¾ëWàV1cÁx“<¦NIÚCëêæx<”YœR¤JQn’_ßŃISŠˉ;ÕExpw±»ØýºC½ü<œ_ Šb+¦ÐxŽB†Bas4ž¡ëᯓC]NtY¬ƒ £áëÕ*K§I•¹›x£F†÷¬XéÒM¿Ý¤3}æúW:ÓÉZ»ÅŒaÜŒß~þPP… ê–8$!š.×7Í`þ="˜ÇúÇR-‘P´úsðÇ€x3¦ =ÁLqC­(*áÃɫ}S‚ Á•y;À};uÙí´È«zyåÝ0rÍ¥ñ§v3ÕÂw°s×&®±+Õ x’uUn¦ÕÆMb룭‘¾=¿äQC‚FL€yÒ©p9,Ò™a=¿ãv” ¬švZ½}VSËÒv|YÕŒˆ$N1ÌHd\ ø‘r^ïN^••j”˜qÚÒúÊÄÏǪesÇV)pDEÍiU6æ~¬Îž¦çÐåmÊ€»/ô!&jë˜W÷&’¬Ï… ÇaØð íÝÚ/µ •7¤BÄp°(†Á1cNú*)“eK±–Fµ'öb˜9+±ˆapë‰Øÿî°öÆlË×£× ¼¾ ¼ží¢zê<±õ t>ë²è¬Ðfþ@¸ÐÙì;"äézÛ9õ,ÕñÁRÁ€°XÿNË¥l '—¢FNóÁf¬™ÛI5ÓýÈ)$¦’=9%kÜjyDÝ­Ö¬doµµe¯í†²ÆÒ‘áðçZk§¤8ÈWœŸa>YRþ–vU¤`hé5(¼J›,s3Ô¬?©"P&„4µÃЉ¾Kó<Íï<ÞûjTnÿñ„Å4¶©á¶V×›•ÖLçwÕ¢½ÃFŸX7È¡‚¡çÉ&«nÝ8É–;öz67èðBQp~Ø~‚ªîϵ¯ “À§U]T€˜GöP!ã]ãµïU'êõ­AýuB’è…œ©ûË„#caA F¯²}ES.Ý2†s®üÏCwV&6·¾ëþ!"wõÑ+peßJ\::×n}Ð}þ€eêѯ½o‚aJ½Óc SÁÕðb‘¬L’™SžžQGãáE±4 ·ÊtMÐLà¹ç0§Ã©nAÄëßßu~õ)¯ú´Ò뮡ÿÓåeh endstream endobj 5641 0 obj << /Length 1184 /Filter /FlateDecode >> stream xÚíXÛnÛ8}÷WðÑ**†wŠûÖÅ6Ŷ‹Ånê·4(d‹i _ä•ä´ýû^ìHŠœ8IÑ ha ¤Îðœáðp$‚>!‚ÞŒ~ŸŒNNEÅš\"– ̸AZdXŽ&:¿K˜Ûjj«²NR¦³ñ«Íf9Ÿåͼ\‡?lÂÈø:¡0qYnl†ßlç…}úgvióÚ†ŠÃ4¹˜¼½žŒþQÀCEšÁÒk¢Ñl5:¿ ¨€ñ·ˆ`n2ôÙÏZ!¡2h—èýè߉\¦@`¦¸›­(ªà·φX»U)Á„ë@xQMåÇKàlìG»ž5_76ROCsêbg„‘<†"¯üpîbñ5 •—¡O.00¾Iäø&zÞ=öÑØÓ‰íÉ)ÏZH J™"2½N¸—󙞜ÖN!Á Í¨ÍÆ›€£#0jgòH aF2>-à¯ÈTˆlðÌUªåOB*Ñ‚Y¹n|Ž|i:l{,¥À;KgdÑ/Í˧⺼ƒ(†ãN4 SivV/®ÝÎçËøQ…Ö­øÑÁ-½¯¯¼åòEaÁ2èl Þ7y•¯:î£ØPR ­Œ r>__¸Œ#1ŠpHCèûÁµÞsLƒÉ_ói•»„%>‘÷NüVDþ¤ÑKJ56œ÷t×Y3,dõWá¨TyÂ÷ëûƒmëHÂSS†vjCëò¼ˆ±q?—þÑWX)`Gm¼†tÈ;_Dÿù¿]ž— xö·ÎÌ`E÷œýlë˜~æëÐRP°#©H£±”ì¡Tž(œRDa…³ªÊêHÕlÍÍ—ËîPHØE?2Mb Bß/\äEXÂ)•?mAl«ÖÄÚ®‹|Û\í¦|/‘õln+„†[UÊŸLaá>„]ñ8„GhLFå+B6}5ÖŸx.ò&½Ú%Q€mgͶ²÷h-JµÁ,ãY áäjEúr š*žh¶Sï+Û"¾nê½Ôöíô¢<Ùٳ8Ì–B ¹›•¯‹ÞJ‡ÈÍ›Ú./£F-‹=ML©äXÈr*¬(¯ÊºÙiØruBÔÐYÙUËÇ£…òS’ d]µÙ[õnE|´ì´S )¨SÑ/µ:zªÁ9Q·õ4@÷ÁâÄL[U}´¨ÊAQ î|\åñ¬½€ !ã³ç·œÇ±ž >Úðo®}¤Hµ§}êÙµõT®ØŠ1Ä ±fâ†öìêË*žKè®óÕ¡:³ o´Å»Ðç*©@/:úûZ±%iC®DWÑIÿ&øÀ(¹+E¡þPûm ÆûílfëºgÖE-–";ˆz[­Œ˜=ñ;—`7_"Ü›@ïs S?QÀ•ôUÚaý^„jݽàOA‚Ýèâ¾:·%ʇÍë¦ò÷‘·|P­ª]«.¬G±øõA lN‡{[ÜIPýŒ+0FýðªýÀŠ5(€ÿ$à·‰vP™ò¾2[{ëý_€¬ýÝtðe^0LiÜ"…¡6L•0þ\Äï¾ÿüé#*¤ò¯I‘‡¡}`ÿ¼™J™ endstream endobj 5659 0 obj << /Length 1276 /Filter /FlateDecode >> stream xÚåXßoÛ6~÷_¡G«ˆþ)mO]·k‹bKü–l3`Çòd9iþûÉ“,)rì¥i° 0`J¼ïx÷Ý‘4øÐàýà·ñàøD² !‰â*_šZÆD&"Ï‚óáÇGCSLL‘¯Ã×ñðíjµÈ¦i™åKßñ» 9Þ† .ò•)|÷ûM63GþùÔ,Lº6þ…Î /ÆŒÿ ¨Bæ—–DSLoç4˜Aÿ‡€‘ÄÁuHC»Î( „ö”p%ìhÅ‚><è<ݘQB…ö€çÅ$º¼ €Æ\Î*ûw?YäSÛ;¿œæË2„îe‰&ùæÄÚ %}OyDò+ߦ¾q«ö-æ?¯Ëb3-7~nâLWcÇöøDÄ X4q ¨#ê6Ñ0ÏfVôø0oGr/#h·ÐÓÂÃuŠ;Y˜q+ˤÝÌJö ¨×p[£k ÿ2V~?º§Vk¥óE„‹–&ÎnÖ*ßÊêÚH’˜ÕœÂð·òèûôÂ>¶4B³„‚Âæ<¢’¢Dó¸}3·1b¬Ô}Ÿc'IÃŽ¬w÷µ0«hÌ:^®@Iûäf_¥EzÓš>àŒ$L#m„sž-/Àù"ŠæõýtMSëZõ‘ù”MŠÔò€…Û˜Äí âoiгŒ˜&‰] æV°i¼–üœòŽ·övÛÅ©‹%øRæ¾ßZgwqŒbæ8Ãkæ_gk¸YN‘õP ?ø(¯@ú‡7q´éQL´¶¼©‹H R8æõÝ”þa™—u×6DJooÇØŸ•k³¸B¾8˜#;9b]Üu$‰÷±di»ÒÉ%˜Áê=?„.· ¢¤_vòÛÕC0C?a>™*jU S˜¢°hòÐÎL‡Zt«arªzé¶D»Ý?J¹ ’§üé8·¬}ªb]ziM¢DÖÄ‹®ÐÏ»<"*–Ïλ’‚m,‘8Þe¯–w3ö¬-9QÉnÂEvÂpÄyšJÝ]çë^ÊL+æÚIÒï’DQÝFV„Ìêå­ ×t±£”R²éœÐ®¾pFsB¨ ·¢ÃÙf:5ëõ¯˜€ì¼Qî²Ê-SÖ5·5 g³"/*«ÍÌ×·?ZîáÔ­©e¤ˆª[SË=5µ«”[&µsA}Î:ôgK¹³¦ù¥ÇKxB«0®’Õ*Ï`ËH•[ëœæ6š M(8.$ÿÚw$õÞ“¡NÏ–_÷d¹´®éë±éj”Ô¥¼™ï™„.í3‚ª*‘:  ¦é3@ŸêŠ|¸Ø9®Sô¹7Øï‚ä,yôìù€CÎ!'½ö:¼e¸v ΉŒº«ŸYe‘ù½«ïaö}ñ.¨&RÆÏBe<o“â)TöÙWŸêîÅðLÇz k(Ø S‘,2à ‡-²õ!,ö@ì…8 Ö›òurÒs—Çvìu„;=ª”ÔDlá> stream xÚÕY[oÜ6~÷¯Ð£&X1¼KÚ·li#›¸‹$È:2#©’&nþýžCRQ–iS»0lJyøÛÇCšFŸ"ýtñ¯ë‹ç—’E9É5×ÑõmÄ3I¸È£TfDæ"ºÞEïã_6\Ŧ»1]Óožfñ‹¶ÝWe1TMí:~4Nã/÷Mk:×ýÓ±Ú™¸ç·foŠÞ¸F8'lóñú狗׿]0ÀC#¥––$¥iT.Þ¤ÑúŽ(yÝÛQ‡Hê Ú}ôîâßÔëB (áZàhÍ¢><è|»¦5®Ê(¡"u înÔötmÌöXãC[Ø÷Þì¶uqðj$®¹Dùá®§pM?tUýÉ=»ï­kzSø03asLmafYµÅžX+Mjúöù¥ÈfÐ(áTN/¡â¦ÚáÔç— ÞÌà§T0a®©Õ4œ´³ó@Úiƒ‰<ÏÆ‰¨¢á4Cã¦þÊL;»/;ß"d­g p” #è÷!Ðy¡«’$crœ‰“ ªûû€¦h\¢Œ;t¾=û‚Î)ö+*¥ ÃcÒˆ­šú[-H3©àErà,–sq‹C >âŒä †1h•wÜûªþèµ°zAR9c,m¢Ó|„ž¸)¯«›ÎªMã¯s!Ö8^ÿ©—’°”äB,† VœHµ\ýÊ·™o=:ap`\ @çиöÆÂÀÛù(:7{©›¤9ᙈÁH6O_X’ÑØlÅÖþýÚšmUßn · ²÷­ýÜU3 sL]â,Ï_}±|†Ö;ßÅ?{Z(žo»æàž~ùñ‡õÔýÓ³Hr«¦é:´{ÓAöìÌ"m‚ćhT ÷É€mFÃ4+’ç(ýßÎùï$<ŠÑD¼OáÑœ¨‰DÛ1Ìí´ïD$)Q'šõ¡,1&1¡ÀQÕ°-»€ØÞõÛ¦µÝOAMXÃUH4Ïšö{m;¸ÎÃÄgÌ“žÔ„¸ã™Ÿ±mŽß GeD‡á½+†â)(R€(>AÁÿ pHFÔ)TÏ’p°¥b 9vfAP+É©DŠüë·/¦ˆ¦ `Êþo·¯ —ëg$‹åßYìúîïšÞïU¸uHØ:ܨÃX¸á—Þµù 7—£q{ŸÙ­b¶+?³™ÆkCžKဠªjÙ™•Ó;ä7 ì×0xa!ˆ1b–’+HÒ”¡,\ß™`î¼ zCÝ ky×Âî¸ÍKwÐøhcŠ®¹4‡|L¸Þ¹=Û:g8:×Õf7Vv«~Œù˜Vò3@´KÅ2ÈßaNœê¢dh’ÏØef¶±RÍ`ºþ|ìg§7còU‡Zu[+aðͪ¾5Y2,é2ÿ>pFŸ¢:8Vêiw£Þ&Dz4}¿˜ÂÆmQ¦a`ÌP»úoAüÂݺl:càÛãFÜ5ÝH]®‹ i©d¸æ;cKHÁ¡–tm5å2¼ U‰ ¸À\ß‚]°SÄ#%¹àÕÁq —KO%Êãd(r¨³§8-Fdžx»¢ô›äø¥.=M·žñ«¯”…+å°s’»8<Ìd¼Ûp·Öd:%TëpÛ±ÈU6ìCgúØÏM"ó4~uëºl»õüRíÀ°¶§n\k ãd¤}ÐB0¨øÍ°blÑ™Šš§ T1¢ÅT6 Í ó0JÒl÷ò Íóõ=ÐüçÍËíÕ¯¯_¯Îp§üˆz¬C†ã’šö“'hU`1 æBÊJ¤D3:ÅŽì¡ð1ŠÔ0/Ûr'Í¡¾nRƒ÷„æÖ{Øï¬÷¸¦ ¹¡G±=Š£QMŒFY6‡ö8˜…ܹµx6~ý ÷É…/tµû¢ôÃ+ÿ­ª× …®”ùy&fj*C­Î u¶ñ.œ™ÒµxÉßÑÏCІ Îçߨ„üµÊc¡¯H–Müx¦ÓUÆB§Ó¹Ó!ò äð¢RiÒêì4´X“Ãö‘M¹q(¼¢©JíeDª²øØãæŠ= {úÖ”Õ­6ÖSöåþ®rÅX| BäI;ý臉ÓqÌ‚¿Á¨Y&ãþx’“ÆE¿:Ö}4uâBÂëDÄ‚óTXîíñ‘Û¢» ×\nR¿°•ȵàËîƒéQ8XÆMÀƒoü‹?’â•ðtuGÑaÛO ûÊaÇ©öhâ8þÀ›Œ9úo‰tYénË œ½ªÀ_â $ÝýÛ<4~ëøÓ'žÊìý”Íý çü¢ Ç­m®Àw;“>©ÊŸ¦O¦I–ê?œAcÜß6FÞ)ƒ‹Î„i¿ojgd_£ÔŽ »1ßð¸ö޵Ë{yÎ3[›/îåå7îåím{°»¡,8cæãuÝz³±eœùçZîæ°¹L6¼rt æýx0s-#,=Wšy¨?ªÊز”$\ŸýߊÕÿ=HN *wêiQœh™Û@õÿmyóʶ„-/”½%r0%(ù_jEVS endstream endobj 5698 0 obj << /Length 1773 /Filter /FlateDecode >> stream xÚåYÛrÛ6}×WðQò„n¼µOiÚ¤m:4q^êd44Yl$’);ùûî ER´âÔžd2Ï$H‹³‹³‡kê]yÔ{>ûé|öø™d^B’‡ÞùÚ‹¸ɘÈDxç+ïbþbÁƒ¹Ò—J—õÂçQ<RUÛ̘B=f—–$¢‘—íf嘆‚þß=JD{7æ­'ÃÚ­÷zö׌ºmPÂÀzJx(ðíyu¾ºmÃŒ*"»á÷ú2X^-|FçjÌ›%lh—7 \«ÕRYó©R ¿Ý¾¸×Ô6Û¼nìU¹¶- Fl‚ù§ töfì/f{Ö °¤t˜Öª®»aï âøó jb í0é°á4F" ¿2-6ãNÀæñ³0ìC=ŸKÀ-èᢴÆx(õ2+Wj°Þãg€dV˜œü}PUfI˜Vzc™ÄiǾ¥µ+ýׄ 60%+‹Æ ÷±mBÄý’ÄL¶#qZˆ`þ±yt?ƒ„€K1°ÈÁqÒš° iG½¿ ?$ zø±éÈøL ³ŠÞ¬¾ˆ8‰àùœ’ücf¯RîÓ{œ‘„EžÏ  \ô\äÅ; }êP°Ð÷SGÝ};äüR§x(Dzoã ·ÿ¥nŸE$ŽÈ.Ê}ãLè7\]vˆ·úß@}~£ìú»¼Hs4á œp ¢ÆÞ™S­;å`kåŽ8tv+Þí( TÆnl½0¬?Í5žÃt;9%L%ûáÀ £ñ–3z*Ö „¨ÝÃë}–ÿüè¶Ûl&7¹avèsˆ½@÷rbbyO3þ[Y8úŠ&Ç|¤t þ–v­¶éé3óe•Ñ9zÊÔ’%™ú+0ÕV SGÚ&¼ªe}}°öKÄX˜ÉG~]1=1&§Ä˜}1†w™V …Ý£Ô6ç¼F'˜vã:zrÁvô#ÉÌØú†@*‹+ðå‰l™mËZTBóhJ„…œˆ¤ã=K6•áÓ©ÐâòÐH-àô¹3¹…¢pËöÔ‚•^q@¢`tü”1-Í0ä¸"$~fñq D~¦b*ƒ¨Å¹€oƒÀ Ž?q×¥ XõÃÔÞ²Ž}^ÚxÊÛ(iÏ”îJ9pË]šj6­’êivŒ®6Lz*s3uVm³BêJ‰´ë¤›ƒZÇÈvÏìݾÈ?àn÷îUwJÛ[øF8I1ò[ nãJˆ’ÝÙ±?/ƒ/uì=‹[<IÔ’ì‘ælòZ–ym:N¶šVKâ(§ †®u¹½ÞV BÙjòß÷ "-<ë5|íLªhBbÿ¿*UˆImX$ÝU§l CÒ+WÕ ¬ZÕ÷´”C@‡ú1/ÁOÙá³$„¯.æH9tíò R¢µj·ð …_Dã 9~ :x'~sy,ÒÈ — cb´ü9Zki¹×ÒFû‰ÓÎeªes[Ÿ²ËN[qÝjÝíÆœÄá—Ø7•I#ïìF%‰¢è[JÉoP×ヺޑFÕõŒšhåÁ‘OÜ“%7fN-»{Í-:Êâ¶qî~åáÿ/5™ˆAÖ1æ€H$l‚IΟnRóÏ Å¡ö‚ü e2Љ4˜W[Õ¾Ð/ô¬Ýˆ‹œÃ*Ñ“—¿Š7ð¥o«FGehØè¿ÙíÏÕ endstream endobj 5611 0 obj << /Type /ObjStm /N 100 /First 964 /Length 1922 /Filter /FlateDecode >> stream xÚÝZ]\· }Ÿ_¡Ç¶I$E0äÛh öCÚ…\gQ v‹µ ¤ÿ¾‡šÑxw6ƒ¹qng‘úÁà½CI‡”ÈCê®ôÒSIF-qMÒ‹&kxì©6ŠgKµs2.©ŽžK-5ëZ mð_/´@Iy¼ÁH+!Hª¥zH˜¹Š†¤XÃcªŠE˜b9¨àÇÚJªZclãTBð‚¦ó¨Œ‘Þ-´:œI ¤±Zq'ø­R˜× æ·{ð.^Á &aZ«\0XË-$~ÝYEaù0 ˜igI¢Yp5ùHíÌ"K´3 Öº18•TÆ+L¢ä°ƒŒb^XJ¦5Æ×Ÿ“Cßó»Ç¬Ü+9$ WŠ%6@"Dp ÅVIMÜwzØ4»&”Ø%–'„¿ A® èÇ,ð˜H‘݆ w,Ñ1JŒðŠwû„W1e-lŠ–Xª««9~SsAÕZl[¸Ìz¬»zl ~…T½Æ–àã@Øcµ¤‡RM]ÇY„›ºY,­8z¥Åå¤Ub µ¤Í@OJ4&qHÊ/GµÆ’ŒyÒðþÓ>ÀJ5Ž_a«º…ÿ fÖqJ,¢F;Ì6ò¡g‘b'â0HØ?Û‰ 4ç@‡£âex±à­ÅX÷ä¿9BÎ9âNÔ! ]a«oŠøGÜøœ8G_µŠ3ýøœ=àsîQX? Ÿï¡ >f ç¾dåt^tdéÊ ®‘XÏgiïeM:GK€Fs" &‹~l’uwgFOk–™õ=ºyŽè™Pˆ<3-…Rš>aQ. Yô‘â)=V:É¢GŠ»¢€=¯(QÝ×cá(p(¶þ”¡~N±¿©-°¥±fÒ~9ÎÇ&ÿ:Ê€¢ŸÏ€<›TžMªL*”I…2©Pf×+“¥¯ÚÑ’fvÿÄ€^‘ØäY:Zœ¸¦ŸÈ˜ íBY å(†WÉö³œÙ~Q¹j¶§b¹Ûƒ†¶·ìnÏÑ[“ã¤Äµà £L¸[]¥¬Y¡8Ü,qù .´ÔP+E‹K†TTúE9p¥µ–ƒ÷HõÌõ²d·ûîP•,H„ËT÷' (¶)žbÀc¥“ x¤Ø¡è,çOö‘Gz „ÜÈÏ+Ê›fz^ñôuî±â¥¯sWb@Õ§ ¨²Œ‘ÍŸ0`Ÿm]ŸTØ'êlur¢NNÔɉÊÿ§wºÚ)ã¦î@;¦Húí’MKöj#¦{CÂ-!( ÷¢´ƒŒ“P¼#ÍéB(ø·F­dL(‚çøb¶‰w_7Õ÷ñ½“Æ%35°ŽÆ‡5Î\è‚wd4ú¬‰$ºdŸeHV½Geø„ÇWØ©5/ùŸdäní éï‘â)ú;V:IGŠl¥BçÅQ*ýæ¸Åí)·xÿ|n±É6;'›“ÍKD›´c“v|ÒŽO¶ñ9Ïy\Ö¤}®Ÿ¬3sý²ë¾Us=Øåa×Å-— ÃghLŒ£9¡ ±ä½éů@çm*Àè/D\ø|±îæôšã¯”&’¨êã+ï"$kï!Ù LJ+^è”uS=ÇŸY|Ú‰dÚ–úÄmõså’µOAßð”.{+ŒDÑ Z‘¸®eTMQÌ¿lÁgT‘·h—A©+Þ°Pn¸E¶ ‰;=) \–O•ÇJ'K‚#E!¤Ã® ‹?n`ÿ ăÉx endstream endobj 5716 0 obj << /Length 1646 /Filter /FlateDecode >> stream xÚíX]oÛ6}÷¯Ð£TÔ,)’úXŸÚ4)Ò]—ºÃ€¶0d›v´É’«¤Ý¯ß¥.eSŠš¤M€Ø^,Š&/ï=¼÷ðPÔÙ8Ôy9y>›<9̉Iø3[;~$ˆÏc'1wf+çƒ{æùÒUåB•EåMý0rŸívYºLê´È±ã…ò|ê^z fÅN•Øý²IWê1¶ÏU¦’Já #¾O˜÷iöjr<›|ž0ð‡:Ì }XZ†Îr;ùð‰:+èåPÂãȹjGmDðÌœw“ß&ÔÄB ƒ(ñ®GÌ)ákçcQëU%”‡ð_åBÎÓ<­çË"¯=ˆIG÷¥žïÊâ#å"3QLñqјG¶] >´!le颕hd¤û{û汯©Ò|Ó³RíÔ2ÕëªvìÝ -‚{öPø4Òñ†~E ÃN€âÉIX8Pgê €IZ0¨²ÔÛ_”€ÅJõÖ{rÀY(‚q ha¨¼ušµ&`]iÍdœ’p?ó#•ñÈ$!1»!•N´ZCIÝf©“Ô=ìÎÜô<Ú÷lûâä¼'¬šù4o²LÇ*ãvƒZ_v7y¹Å}Jë~HÑ>¤m²R8fí ¨Ü»9½ŠÒæ®pˆ•MO¡'ðã–9 O09ã˜HÑ'˜ê¢h²f3æ q’Œ)³fgJ°®ºÄ7á„ÒÕˆrîþîÅÔ…ÌZÙ•‰íËv“³F™ÙI©~°w ì}db¿t?úŒÞÄø à‚ýÎ?—óÓ7§³ù‘Ǩûë›Ùñ³ù»ã£÷çÇèÂé&/JCt*×±\¦e‘oU^Û>cA¦É2ç&§¸|¯ìÀã³GèÍûÊøºïé’»)-:L×#GؼmÎâ»JÇnÔj)©:å ®kG”…«j¾ÆV_5žh8{$FLF2ÑXm€¾jL7Ž«À¶¶3 r©‹£€Ôl‹¸§ã|PÂBŽè¸cQ£Žj­5Üë-÷Ø)HÄD7Ó"‚{ /ΡÉÇ`ѵ¢¡¹£ƒÀ9\ì‘ZÖ_Æàô‰/ă /N%¬ „{ûìnÂ+Ê–[„˜¿[( =5VzôayÐÖM>Ü"¢ÁʧûbB° éºc=· Ë#ÙçáÁ¶bD†ûDÞ6x¤àê Caæl‚ó&ÙšVR þ*rÓØ%U¥V}‘:,RÝÔ%Ø&N;Â:3µÑ´ê)ÈÛÑ!÷dJ"ŒneJàgàzå!D²|¦Q[~ÖÚGß@öúA9õÞ7ëàaoÖífoÔØÕM³Lø?ÿËùXêå÷ñ±üé|Ì È1^.½–Jà§6rû[/úNÓð>º•b$ïšåRUÕSÃÞÀã÷UÚ Wș޹Ã×U­¾ñaÙѵ¦‡ /,$B✵lÎÂØ]7ù¥¯~«¾æKþ â‹¦ê®Ëú¯bQ'infõ6AwúÔÍÄ ±/çfÞ/0çÂÜãô7DúZ¤•|ç"´n2|/\ò[Œò–4iÚ ¿? ¯gMw+ëT0eî)JGÝŠÝî̼Jë‹ñSsÓ~ç6o§ï  º{ÀUT†Ÿò¡*ýàÎ_òG¿Ë Ÿ0fÊ0 :…[ßÕŸ½=msE€Àˆýý×¾Xû½/l endstream endobj 5739 0 obj << /Length 1361 /Filter /FlateDecode >> stream xÚíY[SÛ8~ϯð£Í¡‹%Ù³O,¦…ÙÙmÓ'Ê0ÆQЇÄNè¿ß£‹Û !´l—ÙåÅ–u9:ç;Ò9Ÿdì}õ°w:ø}488 ‰£XPá&ž¤ž #ÆÌ½ ÿ, ÜWåµ*‹E0¤2òçói–&UVä¶âXûwŽÓb®J[}ºÌÆjß–?ª©JÊ~D)"ÁåèÃàÝhðm@@ì;uˆ$–^:\\bo õ<ŒXy÷¦×Ì Eï©÷ið×;30" =FT0Ý[¯„†µÊL0ÂLZƒoËk~•åYu•‚!`Òxqõ5ì«€û­Zk̰6P7–Y Û¤ßtÿeæ†ÙÚZˆÊ«,™:Q“²˜¹AY­´o“yèÉ`Ú‡ PTt(Ž42„g ‹N¿Ð98¢ ö†4äx U–zEåUZŒUg¾ƒÀ²,Çà€uX ¤Ê•´˜—·F†‘lF~ÁÛy~ÔŽ(ëèaPÓ>z¨z°¨=.D ë‘z œ÷NÆ È6!0lÜŽ Æ1b¡l¬~R1"á]—5:mÓcH1`yCBPÌÝrÙ{̽T Œi˽dó²}â RYW ‚@” ‘•>OÊdÖï™fÙÕõ"Ë/aCqì¼lv“U½»"0Še\«>´Cγë2ÑAûßÛBÌRqöw4uR†wÌØšÕÆ™…-õf~ßÄ=®ldž§µp»Z˪V£ Hãøž2 pØÓåP¯v0‚ t=¥¶9¹¯œ€2—N9j'² éGu§c¾I$ˆ »Àá>Ø_(ÁÛÖ3ä¿ÖØZòi™¦j±øÍ~Õ².¿ÏL^ƒ:Ä™^=«ŒÉõ‡~ûeQÖŽ+ØÉQÈîv£› rJüÉ2OmžÕ_i1Ï”kém!é@®kš¤aÆ´…©“Œ] íj!؈­P²Áí:<¦O–WÅ&I‰¸ÙÝðÑq€S^÷¦À£ØO&•†«cãÂB?YÖF³ùT­€)&LF [_·¶öZâ1„¦ÒYÅ„ž!Ìמa‚®u^è \©yÝC!‰ÿY»¼é?)•2ýMØ´]á“yë~c{¢kìI»ŸÔî_gODôty×£.¦i:q|´ï8‡kûãóù¹-eû΋Üq{CŒœ ¥JUv§mnðö!KÙ…ø×²¯ø°¯Ow–¶ñg%½*›©ï ª,ÕnmÕ*1®$üï® ¬ío)ïÕ¤¼!‰ ŒÑÐe‚6ÕÑË”»U†<¯\÷˜j’BlhŽ{¹Z$yùÄa5×r·Ä'þõÄG_éµAË{kI¯e0Ò€Ábç­ ÛU[†ÍƒA¸J|É‹]/èÇÿó n•§ÚKfdŽÕ·. dÿ¢@v—é1[ÚÓ°m¾Iô·ä¢`Nåæº×U3ÀÔ¶öåße‰í¨2k¬®|ò°n$ÛÓ,Þz¶ÝÛéÿx€øMÅÎÿ6þE)"Äa p ™ðn’¹IáܯŒ}‹Æþ‘ÎáÜÐê¶Ý&ï‰Ï> stream xÚíYÝ““HÏ_Ácb™qf¾êž<ï´<-ÏÓø¤ÖÉ.µ D ®ûß_÷ô@€½hÖ*-ï%À0Ý¿îþu7áÎ¥Ãg“ß“GO•p"ùÒw+G†ŠI7r2¹Î"uÞO_̤7ÕåR—E5›Ë œ>Þn×Y×Y‘ÓÀz&ùôóLÀÄu±Õ% ?Ûe©~H÷oôZÇ•¦Á¤dböqñ×äÏÅäÓD€<ÜN áhÅ8Éfòþ#wRÿËáÌBçÆÌÚ8ÊáºvÞNþ™p« gTàLú.Îö…S‹ƒÁ7cZã©‚3î¤ðu¹ô.²<«/PTJ+óH²Ïéò„^Åõ ~i(¦KRä4|±‹V3Á§……%N>áÚ]Vfù% áöY¼¶ØSuŽc38µŠ¶ K¢V‚_ú¤ðp~ôÔ÷;Úrg.€áu”Õe‰F.Ê‹¤Huï¼GOžV°9L‘jQ‚Õp¤×Y$¸b> F«>pÓߪƒ^Ú“Á`ŽÞ÷¥Hï†ÝuŠ…ÂkVâ"=s=°ÒÃóäq]¼íI´ã&Ùlz‡<¾dž'ZyÖ˜üLQdÀ„¢ãn¶ˆÁT^¬’;‘š‹(@ùp#XäYgÙ–°K á­øãÚà‹,¥§i\ÇgjÌ“}0S½®ã;å àYTMcŒ7¸^ÔÙFŸ)°R䊞P—3…QŽ'µlárÃ……úN€CÁ\ÕÇ÷A±ER­ÎuÇ‚Ô ÒFÀã%‚T‹êƒ¤þ2ݰ¹ß n1NXÿq…]Ý.>.#„ lG“Æe¼émï˜×AÇ÷Yþ‘’bœ˜ØˆÞç΢ jDŸÓ’—Ù²4®Ã§·ÝM QXý{’Ú] dÀGÜ LT®\¦Üppøšmî·$DÃ#f¬.èzi’²¸Ïx21Ý®0N!ëŒÈl?"3œ,1ðw‹© cþPŸ3ßs¼n8‚¤‰×ëeœ ®Çä°[‘Ød6‡ãã‘ÃÁÉ9W§nFb£ØånÓšdàt´)‰#‡âTVš’(e —…{š°B-Pœožn®t¾·”Íñ4°ÔIÑLûŒŽ× ±bÎä}«š‡¼@¿¼i¢î^’ç¼Ùg<8¡qÿ&~²p’#'Ý%õ®Ô{Y_½{ùrDÜT¯Œ^»u}Ld:¶/q±«›hj(¨ï !“Q0õ•!8d¼›#aÒä'óx°ª/p‰¸j®µãè–°•êj!oyÄ:ß)ø] IÚo9Ä:ÈÛ]’èªú͹¾Òd£›¬²²½@ÇÜWö>˜”Y6öÂrÐøèé1å ô\\e¦%ð¦«]ž4ý€BpãZÛW1]òÖ8¡6­o½Þb ØAl ð’&uªd¯k@6›+LßQ{¡ÊÒU©5:¥q9³ØÐ( o¬ö²½PLì Öq§ƒ9¾×æ=Ö(eMRd8%CøƒLŸ[_9QyÏ´JMÉ•zìÇ9ˆ) °©vËJJ”/Ñ]E·F?¸‘ ÕÛ ,âDx0Íf—Á,cž‘MðŠnÌ£,ä$Btì'šœ·švÀ9•f`³#èi×x48¹%¥x3fQ!=æ‡Q·ôïÔ?C:Ì Zïå Ê"ÕàÐ"·7Û¸ªtÚOÕV¤B$¶£;¹eô«sáAÉåc‰ÄÂ;zVÀkÓkâAø¹­ñU¼ì5²o·:ÉV·½öØ’Ú´±t¿kšù°·õ¿Co[i€RßÖ€ÅH ìz,Š~©÷ŒŽ¢K¬g )<¯'ØÞHG{/Éà°O:×&Š·±ô÷Ý{ïs¤ÀLòçïsÆ+3 ¹oX™=ÿšBì D§”è׸ÐZ‘ŠõåXë2á„z±·¿åíx¹¶´~çéZUYdƒàÞËB÷'* ;Ïææ~8Öö]ÜX¬w­ Ä@0&…tmÒi¯‡ëuq~JÑ_65g&f~jJÆ2á†ÒfÚOÆæ}/ÎýE>&cÂ5Ê£â#)Wùàäâɹê;åÜûÿŠgrneÝZ:Áû«¸¤¸!p¤~Ÿ$gÄ/¾£6QÈ@ÜŠt#æA¤ýŸ"¿!E~ÜÛÛ-žŽ±0&È׈ÝÀþ'›0^î7¥Ãá?„oÒ?ùÂÑ¿ûÀO…°µƒÏ›Í}™³p¾~n¢@y>‹öÿEDAO@ì_Þò.º endstream endobj 5782 0 obj << /Length 2074 /Filter /FlateDecode >> stream xÚÕYISÜ8¾ó+|w ½õ“Lœ‡8Ç{¯–{¿¿Ô‰¼Èg¾³¼væ"ôDÄåÆyï¾[0éªòJ•yµ8`Aè¾,Š4YÇu’g¦áµZ0â~YP˜æ…*Móq“lÔ¾)_¨TÅ•2ê1æÑÅÇåÛ½£åÞç= PˆCÍÒ Hଷ{ï?gíoâñ(tîô¨­#üž©s¹÷×±Û ýíø¢·ÊB/ }' Ä#<0{úÀ(ÑË·ïýþ†‡½—`û~z0Ð’¸—Íz­ªêSËë[½MâÞ%z[Ðv`ïP;I¬àÓ-óÒÔ×ùFU¸¾sàKOHéÐÀ‹83 .oûâu“­­˜¡V5(xeûbó(⪺[péæåÆ´Ô¹y^YXM¥F=ë<«PYµÙA³®mÿ­}e Ëd¶ñ“Þ΂÷Þ‚ZØ¿ÝJl±%YR'qj_/ÕÞ‡ºÅZªÏ )³¬gdïQ6ñ˜ÏQÃ>uJPƤñâxl¡Ä9àÔ jÄõ©¼’+\µP`‚›j*uàavø%Y[Ó;0ËB­“ë{S‰Íc:¸(“lz[P½Æ=äÖ¸ãõg\¬I`ÌiÚÉ*-+o`nÝÓc$Ä}þ˜©Á¸Q‹À÷‡"`Ä#{"Pe‰®š—+´¯‘yƒkõ\&'~kß}ùÙiÁi1À$°²ìû“@ïmßý@¤u¤ï݉ô§(`µ%_ëÇ|T /¤¢}_Rè_ëýçâŠ|N8è( 'Œ"‹ XÝyŸ­bù6.M< a  @½HZõ¾˜æT'Y¢§:omßx¬¼7ëcÒ㈅šÙ‹¸Œ·ƒéÝ !¿O²ÝvkŒ´ÆZ$^t¡ÖFÐ?“«26;¾ïO¢Õk÷?@jg1Q”OÔ_gVæÌ t&é¯|òhû ;ã(.5@"ÐPäÉå0a¤7 »„“öÂ8Æ¡ÇÔ>†€#ûl˜zJ q ÿê/L`¹)G96NÆâÿES,¤Ø÷S,Ôz)j˜B1N Ð1Q¾:R…nÔgZ›˜”v†]®€††† º«‡š©U¼1 ùµüÖN¶Q×ZYMZ›ˆZõM=EïY³¥’¾ãêá¼j†^C=BºPÓò ɈGüdÆj³x«þèøÃŽY”*N·ÝŒZ¡6H¶ %7YÂz&8°»04âQ‹PÅ€9kfaÊFPÈÚ§kï^š‚™ÈðUÕ¿,‹ðÿ QƒàfèžOÂ˾›>Èÿˆ>°EÂ}x0TʰM\ÇAÀ+Ân//’ì™ÀÚBH‘lq¾JÞ„ÃHL峦ÃÅÍ…¾bêrÿà‚!ûn”v©¡}íP\sèçøãYSM=yõÉ~éû^ Fùç²íðç±m1Ƕ¹ôØ6Ö¦÷Pv˜và%=íc³Ö>ÆÚ׉5ÎÚº 8Ñ.,˜N3/þÙó7Ð/4Bˆç<òAiŽwš–õ ÚA5GÆÆ¼ÛH]æén$ŠbD¬ë2Î 2t´–“@3yN,cÄ†ÑÆ*Óg›¶[ŸN< …Dºg™é6Р{L°±îÏp~Æ&ïÈÅl”£RG­ªÛ¼I-Š+eÖ­”]F‹Aã4uðôØ@qU‚•qèø‡ÍUsUµ[Íz`+”?cnRkb’pøáÅbé_rj,ý;Î.‚l[évW‘EŠš¾`x'4èþ’äÍ#——Z¹= ?E!u·9ð°4Õ$¶Æmw¦À7sº¡˜ÉŽW?¦˜ïù²w—¤©™úÊ.¡E‚Ü#>ß]¼’«“Ó“åêðâèõåêýzyt¾zóçË…”îñê!Ÿ.ONÿ>²€ÁôÌÅ”Ù낾M£Ô)z~е‰{R¶¡ûʾT¤ñ)–[ŠÂGºØÝÎç7F¼`w"× ¡ðBXnžV1Sp•i5Š˜(&€´'å“ÃÃp¤ÅÊÃElvŒÉ"& ‡‚ý·ª2GéÍœ«Ñ#Ñ7dH¥ç‡tˆ¸ï]Æ¡ézÖ-9d³€M}V£Ð§u(õîVzDݘ@ŸU3ù:Oßé¿ÕÑÅÅêâèòüìôòhµ<;[½:9žÛ@çØ “ù~‹D™B³±ÜE€1y›`è`d7¼Ç9Z366•½nap Gž±<<·Ñ#¶‰U™ösÉ߯ÏaN‚æªìu;`þËÏ@tÓ{“|·D/3‰Ú·¾ÒØWH‰¦÷¶½×1WMIÚÝÂLÙÊÀþ¨uįG'àé“ :cÜ6}vÜd·£*Þªá½Sוgj÷‰lü l|]EäêšzOYèN1ÉSC錿sJÑôÉŸ9g¿ÒBž ÔòÚ(„õ©à¾{xú†JºíwX¬Ì‘{˜oñ6©HU; Mum߀ÿlôµìåù‰½®B"‚8*ãȸ¾/T5Þè?%…‰± endstream endobj 5806 0 obj << /Length 1880 /Filter /FlateDecode >> stream xÚåY]s›8}ϯà2µ* ‰Ý§4M:i²Ù®ã>µÁr˜€pÒô×ïÕ0$i’ÝÙÏ ’î¹W÷ÉØº²°õaïÝlïí1#VˆBzÖliÑ€!ꆖÏÄBך-¬/ö©C¹-ŠKQä¥3¡~`¬×iGU’gúÁ{áPlß:¦ùZúñ‡M²oôýT¤"*…þA¥ˆ8ßf÷Žf{îÀƒ-bùL3äcߊoö¾|ÃÖž´0rÃÀºS­n,æpM­‹½?ö°ñ#.`D=W¶öˆUÀ‹‡Ó!¯¥U‚v}íðª¸äó$KªùJy$¿î/Ó‡rˆoŸTºYRêV©¸’í`Žtï\_×QiÆM²–wa]%“XrrÀMÓо»Nbé†*&¹–¶É&Žêyhá‡_Q!ê:\^ßdul€Þu]ûsÝWñó²b>aYnªÊ4äú*››ºk?õ)rYCkÃeF8òR·¹»†j51^dÆVšgzM*eB,¤:™åG.KêKQ_Äq L+VOıGDœ’fú„±X1ÓÀ1äª4Å/nÒy¤ ÅÉr \¡…º…Ê9ÜoR¹¼¡¦:B¥¨ºÓ‚ß<'žHÈÅ–þl _¨†™drಖü+ç…T«béÈœP÷QjžEéMG^‹¶´]ÊøÖÅo8æ&ªbS„wI]ާÓw|>=:>šNÎàæàì·@_æ9ìL²‡ô0÷Qàvå¨ ˆXB$dTv…¢£þŽ(îËPº¤%X5¾L R^wÕê"ª¢‡–"æÂXM—ýbÀŸñ0xuÝGi€‚@ ?ÐU”>SøCõË@Ô=i1U¬¦S¶UÄšï…Yà~FA@­0ÆGĦÈþNõÐpÝlêpn>2t¾¬ÃÒa÷ &õnC=9v|lœ] Ê „Oå’‘hÍ‘q Ú[ëÕ"ž—ÉU6¯ÃJíɬoÓÈ4éÆ'Çãöæ‡æPa—er™Þ×+}œn ,\í^#F$€fG1Ø¿}÷ÝŽØJ mÊfjÅýŸmÀçÕªš¯åöMÖÚC¸|y¼ñhßôÝ.ݯA»¨w0®£øAÖ•Ã65 _¥ õÈÖ¥ÉzþJÅHóu•’¬{Ûš>¹HviâUV¸•s) Bý„q^X¦ åýD{>Ð8M@ƒõñÉ‚|NL\¼×_mÝg¼xù´Qû½0Ë]Óëf((™–ú} Ô:·rÅ,o Ö&/–“ã$ï°HëOG¤IU9*Ìl†høúJ†È ÃÿÚ8Â’Ü8dŠÈíŸ$Í®ÍNG®´´>«1{žíÎ_6¨[Ö‹ïð)—62rÊeµŠÄÆý°|rBÐ6Rê×Q¶Hmšþ#6¡,·Äœ2À‡å‰õ÷£,Ï’XMŒÄ§_ñz³Ý ¢4FFP6Ô7‚·mwC4?<;9:ŸÍOÎ7¡nHTqðÎAàùç³³±³@cm$ö>®t±ßzÚ: ÚM¬Á(v$}¹¹9²”¶Ær­HÔZ’Þ†K‘…?…óô½ÉD}x6’OnŒ×ì§6! vɘŠôÓõÄlêÓÔú¯ ­«E¯†‹í&*:g!$@˜7ó8¼–?J©6ÿ¬óÙC)Û•'ÿ±8|0B!&›=D3ñX¨V(óÇè§%7÷Ô^Öø†€ì/s1á endstream endobj 5703 0 obj << /Type /ObjStm /N 100 /First 983 /Length 2105 /Filter /FlateDecode >> stream xÚÝZËn\¹Ýë+¸L²`“õ «c€yÀI€Œ½Hbxáx„ÀÈ@ ü&ŸSìfË’Fc\ucÆ ¹nß"yX¬Ç!y½R*I{¡$5ió–Œð\5…P4I‘ZÒP饧Ö=KV-O®=ZÕT‹· H”*1Çoœ*÷ÑgOU¡âµAÐñ“A24§’jã@RR‡IªÑ£öxÙ÷úñ›3`´ô1q"ô’´"|ÁH-‘¶˜Y¢^bòDÆ#’÷xË5q­Ñ:eÒcHb¶¡§‰•†^KÜZèIIlèÏÑ1Û0 þ@ß’3%öF’´ÐPÊ^8LZc€iØ=ÊÞà=ј„à­zLB,I äI¬ÇðŠ®J1÷*1X؈`…²PJÑêxÛbÇ[ü1‚„{c«5ðµšþš¦Æ0¨c®MhüÔ á‹¤¦¥c„‡P -ƒ`C Ò~9AêaC·6Ö³—„…èx‰ðN=& 40äx« q Ñ[BŸa”ÞS7ŠIÀÎÝÛhápÄF1†ûb–0–5IÆðÇô1瘪i2)ÑÒ $ÃM-Lû™ñ@ ÷£†‹Ö£z,¸D[',ªÅ¨½SÌ«HÑä},,î΂Y8|¶” //Öø°·•ˆ‰4˜§–.l˜Æä0¼ —‚WÂÑ­c*Ý^<{v±û.½Ë]Òi÷·¿ÿöM\$7ØìêÓO?½¾øê«©·¡{KñùõÕÇôìYÚ=‡‰¥b¹G“çp¡B‡'´–°ÐáòGµù„¨ÅÏwpúŠÆ‡'‰w2ž0àîû÷×o_\~L¯Òîûïž§ÝËËŸ?¦#–—ÿýÏ%^¼ù×åÅî[ຼúø!Äèíb÷Ãå‡ëOïß^~Ø'ñÛ_/|÷æ›ëŸÓ«’ÂÙáqN¯1Л÷hØ€‡ů¯®®ÑÛ«}ú <#ý„>›‚„Z§@SØOõêÑÿÅîŧ~Ïywõï‹Ý7×ï¼|?°•×»?íþ¼ûöU1·0D¯¹ ·æ¹"T)Ù0TsÍ…;Ô¾«ó"íþxýò:aa÷ ß]_ý!Ãa~fÝw @t4£¬@„L“‘G„³~ IÛ‰HÏŠX›H³›, ©Ôe;(T°È Ò4 r2©fBì ŒÅî'…bž£HM(ÈáYë2Ûp>ËðUé7>Ë*Y¨žÐg‘’àvDÂX.Š ¿‚dÛåaFFm˜P„9«,C¹½<‘½ƒ®ÝdoÔTíÙPyï¥ùÛŠQrË‚,U`¹Gµ–\ÁU“Ì ²iË[PTpÿÕ•+öûåŠû——+âCá!™Â,`4 ͺE³nq™Â,`<ûáÙÏ~¸ý&Kõže… Ä\s—ˆ2Âd'M­å–;¡H“ì´ eËÜ-QTíˆD ‹¤k@¬õÍkˆ(j:jýt’¥jöN"­ç»Äƒ“~m^Ïá$Êt’E(Oà$Ép’84XAâ²=Ó xEg™FÑÜŠœÜKabÈïÓK¸àÙÛ9¼dB™^²eK/9Øä°6Øíæ¨1¬É£|´ô{„‡m‘ðÜR|ˆðÜUzðÜQÔJ™yaØ Ï=æŽ:È Š Zq\ñk#‚ ×îç¤@Zs8Mì¥v‹‘9‘2α—fvd*=B‘ØÖ÷ņŠÖ74u9BÑÒr_¶JeßÒ*–ã°µ#öá•l=—ÁÏjyŒ¹mh¦,qþs@¢¨q¦º†ÄÛ†&!ÇZÁÃæÁâR•Ú9Ž9B?=’”½n§Œá`cݦ™G=iÙ#¹ “†0LÂ¥¡|¥ê2”m)*ØA="Q$—‚<·ˆÄis7©-lqô’j¢|J7Aò*qÛÐ%Ç… èYÜϧH=éY%#gÄ]΄"Vr£e(¿pÖx‘ÞR|ˆÞUzÞQ”bYeaXFÈö_<5»£HÁ\åqÅêp3–_94ºO­|99ì“°õIüú$~}¿>‰_ŸÄ¯Oâ×'“ìþ|¯¢Tq½á{¢q}ÒZâÔví yq0Nûƒ'Á¦ì´•¢¡fÙˆtäi[òE\ªbWj7çLRÁrê˜xpÏníÈÄ%hqµs0ñ EÀA{_†²i×–…n¬"î9>X‚b^Ÿ`}žB.ضSÚïÚ ‘ hgŽå9 a0 .öEHF)Ù§Ñ…âyKé Aë® ŠZ2ÕEéN Šùcõòç³Bu¯¤-—Âϋߗ–;+÷¿U°²ø­‚ÕûåÎfá²Y¸l]ø¬„>  ÏŸÐgôÙÏ~üÐO|«rêh ¿ÍO#·(F‡ (`®ç8ALó˜”q;JºøÕ…ð†™ÛZª7]pÏH‹6)ôWC5n@¦È@ª%%û±7¸ô–Ü`ñØAM$Œ„Ü%kH¶, óÕ2RÂÍ=HË­œƒÅDu, Ó“ÅÄGhÞú9XÌ„‚äÿ} Š“l:ž Û‰D«e×e£¸>Áú Œ+Åa‘Ç帕)õ‘s£ ÏÆÖ#’¸SÏé‘Àë²Æçñ%KOñ¥N\$!¨´2³±ƒþt>B%Ä/ÊÑQ)3‹í¡uÖÿ+˳²ø¹ÒmÅNhî)=tBsW1®Cµ~6ìÿcžP„ endstream endobj 5825 0 obj << /Length 2281 /Filter /FlateDecode >> stream xÚÅY[sœ:~÷¯àm™TFÑÁîSÖ¹”O\>Yg6û¤¦0`›2†9ÀÄñùõÛR 0ãL|¼µ5€Ò×­î¯/C½+zïþ¹:zõN2/"QÀouéiîi o•z_ü ®ü¬¾ÈêªY,¹ý×›M‘'q›W%¼Éœúß &Õ&«qøý6O³—xžYÜdøÀç„-¾­~;z»:úãˆê1ÜZMµ—Ü}ùF½Æó(QèÝÙY·ž B¸Þ§£Q'ŠÈ8Œ‡$ O3J¨Ð(ÓWΨݾûîÕ;>ñƒ^ØÉ@+ê[aáÚl“$kš—n´½¶âRÿ.·âÁØ/ŒRvŠSæÁ\ýºªñ9©Ò¬18¼e ˆTÊ[2M"ÁqãOùUiÞ‚DÁgDHÞ¡ÛÄ Î Ë(©º9Û&/¯KACàâÍE·Ô¿7ÜÌlP"ð[¤1è…9fa%y¸)hZê~Ó¸LgÖ`R=ø:·Ë5ßçÖŒ(*º¹d±TTû'p ÌOŠmê‰`yb$B±Zk@q»­ÝÌj!”¯zøch‚ñ÷ز2Y·7í.NzTùåÌJajŸÞÖ s9wdJô_å b.«v fä¯ÞrÂÔh8’JR–ÃHšµ_ßÄém^¾JŒG^ÇpöÆ…7w`uB€Ò­½Š|8VÆ·(Xpðnƒ3MqÜš‹¹1ªÌÜàÇEDašRþñßÒØ K£°*µ†f¿¬&+ÄÛöºr[ÿÙ‘Œ§qãÕœ.…ÖD0~À©€µ(Ù믜lÿ• Y7F!-îÖUû²ÓaHBØu¨p…»:Þl¬Èœár€<.ñùõ›åÉ»åùÛÓ·Ÿ ”ûúl…/’ªl㼄3ÿ¶þÉœ\,âDéÞÚ’"ÏÊv¿q€+Š‘q˜Íʪ\–Û¢0\Ä?NÚ/ƒsZŸž¼=[­OÎÞýŽ’\lA#pJêÛïµ±p+s‚V+\ B™kõ ²ÕY\Üâí¬˜ÂzÄwy»`Ô¿^×Ö Ì§…”@Z¡ «·h3[°Odló«¯<¼9ÿ „"KPÓ"B0tˆq$„;"CDgÆz*#G›ý}Žÿ"°>lØÙ–`\èG…AðâѯŠB D”pbgÀì&Ï÷„‚iòŽJê µ¾I“5†÷:¿¼_®]*àZ+!z„õ%^>N°ñ9ÆËÇE  ¹€5ºœ`S5M~Q¸i;ë³{öè(ݼë-bœ€ˆ44"jit±ßJ?<7Qd²ÔØ–ó@ü YÏŸæ£ÌÖöe—¬”Ž>ÿ< s¡F§¯71«ñ®Ç`ꀪð…ûöå_µd!DÊ'QÔi¯±.ÜlCæc™£IÅ(öÛÔØ&ë]è}^¥ê°Hm/»¿(ªÄðÏÍc€!ÉÓ¼ÿôÅ1F Nèyž ?ðš?g^tþnò@“Vv<œÐDïÒ` Î%Ýû0I³l´Ã'ëj;çü"ŸãßgóŒö“ë$n-E IEÔJ…‚°+êøv´¼g_ONôK^~ëm³µ…Ýv>#‰t/£+yNó‹:Ƹ.byÄÉ?BêVÁ²GLìOö#Z“ÝWì¤ pË,-·‘wlæbáöRÈÜ0ÁsŒ—A5+Õm;À›v®?ŸÙiA")&’ÇÚA‰]äÚ †L†îJÎK—͈:ußÄnÃ=*ß!žKÐ ¢z‚õàD\^¿å‚àgóèPï¶HÉP–fërJ»2ùìß§§oL¥qöHcëKX~¾¾4Æ'£§‹óáÍñsˆà`ŒE¾èd²ÇŒ5=ŽÏ‹Ðé|Á= ¹ÇgpõI<ÚYµg:ægYúS–šÊ2EêØEjR3W^g—œôr ð¦S¶8¤•NZ9Ÿ°…óÿA GŽÑAé·ZÙê]c¥šq[æÃuSg Ônp®ëI¢¢ƒzÑ.›²“TüÍœó½Û¥u{÷]’êUM£=õ*…ðEvn8a»xÞ ‰½ PZÕËl“HC«ŸÒ@ÑBïÝ4Ægˆßí•St×C‘&Lªq ÜßC ÄŽÉòÄv8ƒ â?Œ=osÓnâ·¦> é@ Sæñ')…¥>°ÊpÔÕã4Í]»%p}@‡…< ‹ A™¶…fþÇ"NÜ7™-ɱ f‡#jÒASH ç [ýíú6ûÙN(Èq‡Ý@s¨Æ¿x °/ƒ;ˆUãË8FêG'4×&Y¬¶ejO4‚µ…&ˆêVÇ]Ô˜`ü6nÑL0y€NaÒÿÏËÔñvZí §v žTµUR8l«Ìg¡Aª§­˜¸íS—þˆMæâ¸*)ª&¦8Ý —ü`ýlÊÞ)e=ºU:ÎrÍÎâ$Øå6Ú­æl@Z˜,´s4’…îB{ÂwÑÎðŽkc Ïx×Þ¿ÜNsÀ‡vžx!ôø'y8þa'ð!E{Ç_]Û#ÒܿܖI÷7ðÓ*sã–ÍÍ$©Ñ«Ã«ýÝCxÙw±Ë))E»bœÑl²Ä2D2ÚiëVG„ÂÇÚæ¶YêÚB=È ü/ÉÜ—Ž«QÔ‘'ÜÆîߌaâÞd¦âér5³Ö8Ÿë ¹õ$:®]¹bÒ#›ëØÙwy{=ZþA]™žj;öéŸ,’$Tü—û~¯ ~ˆçiŒrɧø¿5F9ƒTþzcÔ]GkAÞÀƒƒÿqœí˜JÈw˜Km5Y& C(ã®ãm]:ûãÀ[ùÇÕ­ianЬ›€ï±±yé¾P†4³QwõõÇ×Vµ7© à[íýSÑ^LÐÚMX;Ÿ endstream endobj 5848 0 obj << /Length 1363 /Filter /FlateDecode >> stream xÚíY]s£6}÷¯àÑì,Š$„€Çnëd²é¶Û¬gúd<”˜‰ ^Àɦ¿¾WHÆ c'³I·Óƒ±®î¹Ÿç"cëÆÂÖÉàÃxpẗ¢Sn¯-0DÝÐòY€XèZãĺžÙÔŠb*м´êß–ËyGUšgêÁ/¦xxgX8Ï—¢POVi"Þ«ûs1Q)Ô‚(EľŒÆƒ¯x°E,Ÿ‚j†|ì[ñbpq…­ž´0rÃÀº¯W-,Ƹέ/ƒ?XÛ‚0¢Ü•«9± øaëáyŸÕR+Á»¾2ø¶˜z“Ûj%ÉDd•4Æ>(äŽö€45IÔ—H]2a{Ã{uoŠU6Áü³ü¶ö–ühÖ8Þ0šÎªÓXÖXHq Íð|²€+ ͇`áÑ1ç-ó°åPÖ{-ëDQȨæÅ$ÎÑÑwt þh96ÇàÄ~×ôøn©×q“€Vö°{ãÆ[Ü©×/n½W> stream xÚíYÉrÛ8½ë+x¤R€AÎ-q–J<åÌ8Î)q©h ²X¢(…¤¼Ì×Ocáš²å8“¹¤\6 ht7ºû=ÀØ»ò°÷~ôú|ôò#^Œâ†ÞùÂÔ,B,¼ó¹÷Õ?SîËâR›r<¡"ò_m·Y:Kªt“›Ž7rL±=&00ÛleaºßïÒ¹<2ïg2“I)Mƒ J_œ½=}P{Ä,ÍÀ›­G_/°7‡þFAy7zÔÚcaÏÌû<ú{„­¸kNÈ:æ¡8 =A0Â06}£ëåëy/ßQg˜ÆðAÆ 4ÇþçÝl&˲7ÍYkbæMˆ@q@`©åÇÖ×\5ÔÓ/6…iÏ6si?iïÃs¡6(I³]!ÕBÞ$äˆqnÕ°»x¦w±RR°ŸJÕºÐAè'¹yÊܹSmî/ŠÍÚŽ0•ÖpØ¡_%—™r³Lg*–fî:©LS+¬†.µ‚à´°ãJ(âlÖ+y"Í8ÇQ°'õ°£I E:4ô€m‘æ³t›d¢‚‘P,ê:ß !!o…€‰1øq>h" qc¡ÌgÕÝVéE‘H4ž4ò?,$È>EÁÔnÂ?[ZÙÈ/öǃÝ*oÄ1¨BP A¥e-Ó+µ©°·Õ$ß­!\åÜÄâJ©¢ßšÝOó+Ó£dšÀ…7ÎßpÀd6/•­A0l+$¢Pq_LBÇ`Xõ2MˆxÄ*ËŒLdl¦,@$ŠÜúRZíWÅ%Ÿ. )§\€¶¹3mò šå7Ì1üëë5yhO£H—ÆN%Në8  Ú¾YJ[ ÒÊ>­ñõndØ]Çm¿”s9G¶0©ŸâÊ3/gïïeX…ý’Ì)ɦ.²„¸AµOÕvlÆ<#ÿ22F!ijã`l@"ÓÇÓ ÷¢¢Nƒn\.vi]V³£ìMÊ„I›N9Õó’ª÷D–[9Ku^ØœÚZ5L9;xÏpˆbÁžºkØ8QØ9€ÝèEîužía\`ı¥\eʪš.“–èÔsåÃ&æq¼”³ñ„¾èfº0ÏÄ> stream xÚÝY[sÚ8~çWø:AÑͶü¸m;m:ínJgšcl<›5&iþýY²‘Œ!mÓng÷ Y:—ïÜ{·ö^žÏF—/9ñ"4ðfK Ž(‹¼ Ä#æÍRïÓøjBý±¬²*w“) Åø·í6Ï’¸ÎÊBoü.'ï&æåVVzûÕ>Kå…^_Ë\Æ;©¿D)"“ϳ7£³Ñß#ò`x!Ö…8ô’ÍèÓg쥰ÿÆÃˆE»oNm<xæÞ‡ÑŸ#ltÁˆ€ Ñ€©Óñ*xq´y=¤µâJ0Â,Ô ¯«…?_×sÐô‰Óù®QÌ9_7Zª­Ì´Upâë*³ Ð/bý°‰è#J˪Ü8wŽNÔJ¤x‘KÔ€×iß¡@±Pª†>¹4 ýM@áòeX`oJ9 ä[ȪR–/«yR¦Òáwù0³â€îÁg Ó¨ÉEØúÖEB}äÓ¨½yƒ}¬ù|¯>¸/qIÊ¢nPüR÷T`¾ȑ ¼½©.É óÇ_ê‹§ Ä,™#Ѷ̌HÕc…DkåU ?l«2‰+Eàö‰ÂñîÚm[eE’mãüœhSQF!,Š|ã4[íßæþSEÃÈŽKÝå9© qø¼ƒ?QKê¢#‹¤~ØÊ³f ñ;6žêD>,} ù°ÈËD9ÄúS…ˆD®¥ž=³Üi ,)CBXAI†“Í#O ÊlI(V9D¡ Æiâ*Þ8使uÏ·>eÅgð.›Ðéu<÷ÑÇ( ;ô§úÊÛlQÅÚ9l"M|õI •) QÄX_‚µºØ†¢ CŽ·ÂêzÐæÊ©ñFêoåR?ã–ôÁ,ÍF­r½^ªäøîãÛ·æE©ŸûyÊeCyŸ×z£&­íú ÉN(èä€>À…¬§Ò·²5ìT0qCç„&Ð{¬! xöx_õ»k¬Síto¢pØo€C¬—Ë øÍþ*»]ɲeÝÚƒ)R Ð,W68…¤J+BûŠXù¢#EÁ/ŠÄ¸é¶îäoœ•>.lã§„5L]ÔË}}ìØCðGHjëIÓ¹°ijN{÷¹Ürä¸Aoêj1¨ÈÂG­-–’RÜV‡"ÜñJð¹d MqÐ%c‰û$‘»]ïš+µ*fÔôHê}Uü+ëXéy埫֓šF¯Ye&1em{ܾHM⪎ljõ%††á’‡hʳ´i]Á”9ÞuÞo¥òúˆ€O§z±“q•(¢+õŽë•4/¶2Én0ãÒœtÝ 6Úä ËC¼¨}M‚BxÖ‡²/`Z)j‡æÂ.‘vI¦@Tt5ù\Ê„À IWN/ˆïµ C„b4<š2¬ú3A¬^h€OEGM¦Üǯ—Zñ¢<jcÔQð‡ mN&$"ê–íJ‚s7]ª:éxÚ/°ë³Õ©úv®V¶žÕ1½0Ë"7aÚoó8tWøÐ¢KUÕ©®êŠÅPeç!â„¶WZnEYL‹}ž£.0P«©ö›™tr¥r—Ýq-wNÇÐEArrTDˆ³^Ì}l;ˆ¦¯\VR¸‘¦É„okU|šºâ´êø¦ †Ÿ[êùŸDеG÷+i|#«]#†W^·ú§³/e*S3õøß›ý§š=f§ŒÀ¸54ÿoJÅTôs“1Žgû”áÍo#ý+ÿ·!SÞi\|ÌQ€Åð¿{¾÷Ò|Oû£ÝYa ‹9 YúÔA’=’Á¸k[ÂN‰†0kwÁú̪Š£¡ÁølÈ¡j„šaæ¦ÿÙÑ0KSèðžš[¬êµ‚šžË!î†ÔÉi£ B·@Ûµ£v›ÐU<+íõõ3:x•Â_ÙÁ‹¯ëàmVS}ïûY]]?÷çW³ù;àû‰ïÿº~={ñ¸/Š ©Š÷f´>F~pêÕÔ!¾mêpáïÿ)Ù›_ýŸÀà/ü„D Ý xÔ$KóŸÆ¯›&‰Crf¢Ë¦³¾dÿ}KÿU endstream endobj 5910 0 obj << /Length 1865 /Filter /FlateDecode >> stream xÚåYÝs›8÷_Á#ÎÔª$„€¹§^Útúq3½&}J; J̃ 8iú×ßêƒì¦Inzs÷b@h¥Ýß®v¬±sé`çõì÷³ÙóFœEœrçì ¨°±ÈsÎRçÜ}7§¾+ª•¨Êz¾ Aè¾Ønó,‰›¬,ôÀK1§Ø½ž˜˜—[Qéá×»,ÏôýG‘‹¸ú J™9{;{u6û:#  vˆÞš¡N²™ÁN ãoŒ¼(tnÔ¬Ãx×Ü9ý9ÃÆ Œh垜͉SÁ‹;ƒ÷L0Â^  ¾ªVþòªYÖÍ|á»±4»ð(¾./ç ‚]1÷ÝF[²Ð—Skª‹õÄä»(š,ÎõX%GÔ*UÖC×¾-/ôõJá)nõ€Þd•aE¯‘±¢„âPZ0øe!×€Œç'œÐÀ΂2Ë€!ªJAY-“2Ö~ÏO¾–°8ÌÇHÆ•P4RöôRG(ôÂVì3ö±Þä¡FøˆzÄÒ")‹Fáù­éû k%¥˜{¾û­yö8…<n=qÛÄ«ƒÊx=˜2P@ìJ¹ÇêCfÞØOÉ®’ÕeuH-Î ¢Vö„ŒÀÈ«œ¿ 8•LGê®°ª7XuÁ(£ J1Š(Õ‹oã*ÞX«;” ˆ΂ÀÕ7Á|ž_àìøØxýfâÑ–î-\h‘÷Ùª2'üv¸ˆ c¾¥¨YeAyÞXƒ+)hÜ©²ŠŽ…‘&ˆ )ò®=Иœ·ë¸Hs1¥^I+cP;/wM‹ÇÀ‰6h2Òป}o¯p$IhƒÁ& ŸæZæH€SKÂRlVá1¬Ÿ)Á‡BÊïü‰µ§»$u=†‘Ïök½«ŠŸÖ˜>@cíñ®ûòA^ݪ¬ÚPL…2ÅYp1xKç•€#"cGnSêk%âTÞéö˜•K_Üê9BÞ_«PíCƯ¬„¬ÐK5k³K½Iö{L¤{DTØ¢ùÂ#‘û©6bm*Ej*®d, *ƒ ,€:Ú‘ 9ØîlbYÝ߬…r‘,kÃL5·ÌàY”úš—…ÞÑàZ‘ŠÔ”Ø{sŒÁ€½!߆Cz±‰uu_Æ»fƺ²/¯Òd™ÕõNAÖ³‹W…*»šUæ]]öõâåâÝËã79¹hYeß­Ýãb ü©ØÓb2Á >òˆ<-kx0ið'IC['j¹LóHõäyþ˜C¬ò2‘‡êê`ÉÆ( ])>Eî»äi(D÷¨Ö¶Ö*S.·UV$Ùv”âÇIOf½Ž})ÇWs†« PHmà ¤^*Ê<)â=×zR. }Ûð£6z©5óP@øSh}t§ò(í=I<„¦OÎÔ<(úc"$ ÿ TmBò¦# NYèÜ«äûã6±¹Y`ÏææLPCa2Þ÷lmˆ`oÌúœ”,±}%WÌ Ì©‡­†ip8ïp ½Í;õºú%ì”B8!äŽÌ)²ÔUK«Ó•.WÑ®M0Uze,‘5° hÛ¡z[ÓžîÞ=v¢@û+-*ΊÇQMª ‘ú¨¶4:[+þÐ]ìŠÄX O7U¼U/ˆê"ÀHÞoN bdb d“<µhÌ{MÇ™‘0ÄXWÆùeé0Ënrf”Íu„¨a0R\ &È] ¡>žëF(ÖÓk¡!PxQ(îfvR€8¢†ö îo²f=ab(“K_ÖÅÔ&> yW $%õ¼þ(U¢Þå#¾X ÿ Ønÿ¬˜Ø`ñ>þw>‡2Ý雽âÖÖâ2  ¼𪡫&,IPa-ø: éOU½ªzçËD·­Rý•PÛ 0QÁXö]X½/ÍŒ˜(WŸÿíM+°ÛØÜÛ;Á@©|ý¿úVàO¨dÒŸôa¼kèe…B²~zJô#*ù6B>'&‘ð–©Ï (^e žž Q*I81l(¸⿜ Ý©øÊ—ª’ÖS*@.½Ó0êréð<éâ¯Ò]ÞkÓk0eJC½É¾òÞ’ÞÃ6?öà;c/u²·Oï*þ3}¯Ð‡ˆŽ~eß+œî{ýfðZ¨Í½Éj€Õgü™®³cætÊÜ&>ëÂÕJ,#C¨ŸpÜ¢CJ{!¿ ÚÄ&œvuë¼Õ°YÚÊœ¼yÿʘ‘ĉ̱W“É]7ÂzbÏz&¢û2 5æ»ÇL¯¼­Ê¦LÊÐLj~j½ ÒÛE%„ÊqƒØà¤È×S¬ ïá²sMé€'ÝDÕ-Ó‡ü!ý1ƒã¿ô 6Q~ïô&ÿŸcb¢Š`¦º!v×ñVýgzÁ½q¹ÇåFÒŽm.Ú Ã¿Þ.Œü‰°˜Ì‹oF¶¶uÖÜnE=¶ôo‰H% endstream endobj 5930 0 obj << /Length 1646 /Filter /FlateDecode >> stream xÚÍY[s›8~÷¯àgjU’€Ý§^’N·—m]÷©íxÈ1SRÀM»¿~.\ƒc7I/“™}çþ;vžM/&ÏqB *œÅÊ¡CÔ Ÿˆ…ž³Hœî‹)å®,Îe‘—Óõ÷Ñåå&£*Í3³ðTN)v¿N |¸É/ea–ŸíÒD>0÷s¹‘Q)ÍA”"2ý´øgrº˜|™ÀƒâøŽfÈǾo'>a'õŒ¼0p®ôW[‡‰®çÝäí[]0" FTxêkAœ^\[œi­N%aÏ7 .Îùr+‹‹éŒ`W.£]µN¢j:ãndðÏÌåUóy®®¦ð›µ+/Òÿ:fê Ù¤ee šfUw§¹drÊÝ«ö[¤íÕ(Ü(Nq ´óüf0ŠAñ‡gBt´ÆÎŒ20 ï(-‹B9;/–qžÈÞyÏÀL›p ¶X¬1V¤6ɼ³' _ïùˆ96'ÜV±Jzâ\‚ð[5ïÝ „Õ;Õ&9õ¸û­zp7@ž·^˜Cy¶1É>H‚ 6ö<L¥Râ…r잤™µ+¹#Ä@½nqF=8gF 9?•þ>¨kžœä»ªÎâëqÉ}DCÞ‰K2ži® ÕëšËƒ"êûìæ"‘~Ѷ'Þѯý¾U?¤Ù'cOP]¿YèýHÆ(ôÃúÌly™ž‘*ÁØýÞ¢CÜêßCj¥ÌˆBÏ"hco€ˆµIhœ©xH‹nX@ë<å+ £—ÎñÀ¿Ñß7ºÙ`ôÞÅծ嘲Äì?¤-Ý£m8Ôöó&G«)( ûùj†qX5©UòÀê wºuõÒ¢w¬OQЖk«,´R‚oªGÀ¦DSɰ ›]˲üÛZ­ZK£ÞUªY¬Y“¿PÙßò/®ÔÕ-ò¢NïÄØÃ™ ŽwÏg°C0ÅT (¾!<·iÙúUd…GSOÕ¸-…¾[îb%gmw•VÔZÚ…þFýrUä[ûÖ~ÆJÏZ§Ê¾ÒÙ£Ž 2«µÕ@14y¾ç¾/-l8«B¶4C±]±t«‘úd$ ƒÛ–ÝfÆnõ«^nt$>©‡ÖlG\4`TØ\IT-1*’îÙÄv×ÕêÜê™Ëë÷/_š»Ëøº´zœÿXU? ?ê¿;N5Œ Ð.ìrôÏKjÑÅ»etË΋­šP:3È‹ùãÙ“ùéSó´…zõ&ž•[ŠÞž2Í.6ö}©f+ƒ¾Öç«L6å?Öh“Éd„8ŠaÌïw ¹õ<ÃéÂm7>Q¾-ïš̶ºïªö!:*Ì™¤UY,¡1Ý”5¯?:Ë\n¢ï!ù^·æŸê{…i$pÄ–×Ýßè)ŒG·³ÑQ£“øí£"èÄû>>xªu•…ñH9«%CæH‡ÁXY{&›Øðݤkƒq2lÞè¢iz^¨òZRS½Ç`Xa}íäa#|Ì% éÐ%§™*ÚÉQ'[ûNÖ4XÿN >{@ùž€˜kêÙÓa8qdè°¥ –AÃj-[HW5¬ºÌï`® u €‰q¯iÄ3ØÖ;jföÝþ¨Ó×*sþ}uúÊœù<+w±'âÂÀ,må6¯SögB.Ä—ó)Ãî“åüôíûç†é¡Xó";^©@„J"+·i\È/Êg»T±feLºÖI•xú‰#>ó÷†Ä®È~I8Üy@]¬ëi©¾FM½SVüªJžÌÀå±µÏj—uìY­£ªÎÉÍÆŠ¨É[¦jFgLäjĮֽsʪîeû‡ŒaÍésÕkCN~ô.Æ;E„XO¹ùW°P«bÿóòæ¹6#ã|3~̇Èþ¤: endstream endobj 5814 0 obj << /Type /ObjStm /N 100 /First 991 /Length 2133 /Filter /FlateDecode >> stream xÚÝZM¹ ½÷¯Ð1›ƒZ")JŒöN$ÀbíC’ŽwYÌcØüû<ª[ÕóáÙV5ÝëøàaUSÒIQ*•–,¤`Ú‚¤PZN¡eüM2’@êBÖ \\¨¡Ôþ¦…š]9[hb®ŒžZÝ@È!gREèHÅ% YCã,Ò_UHÍ;%¹ô‚wª½©…l}N’4—r Ü‡` Ľ¢¨÷|¤É±±ªÒÛÖ@­ùÜØ§ì81UÎ¥–“y[¡ÀÂŽJ80fˆ1’wS”x7Güǘ$¦ƒ$rP%AÃ0’“÷[2$LÅš@h]‹‚õ.Ð’j˜§ …ÿ ©˜C/5HÝõ §´n …JJN&÷‰¹W¨zÊ¡ˆ»¥¹¡Kézè@7æc×>/…n­€i{–VÓn@üè60þÐÄ.ÁQJâ¿VŠù»$A ¼ zªn&XB[rLµµHÁ‘jï/…J}4DVåâƒ7 UÌõ‡ª}¶°i­˜­™†Ú’ ìNØä”ÐIë‘Ò,Të~žj =C #r½¦†xpxÆÊîw“³¹¡àhÀöÁ¬†æÿõ9[bÆ4Ì‚elÃhÆîìL<ò aeÅü€îzîóÒ8n‡„øMÙ î±›y¸»ïrâŒa,û3#fðÖ\´ìºXI˜zcar¼õfð·÷Û\,ÀFRZƒ]srD10ÚõΠ›sK›/6ÛïÃÖsÁ*ÿ1lÿú·¿ÃXÉqWŸ~þùÍæë¯Õc®‘hÇsŽX±w_^_} /^„íKéˡ횼ô¨'Øs÷äpHÊø­øzOC<ñøñ„Æû§¾²¤?aÀí7×ï^]~ aûÃ÷/Ãöõå/Âåõþ}‰Þþór³ý¸.¯>~ðÓGÚl¼üpýéæÝå‡].êïþrùÓû·ß^ÿ.^(ü†À{ƒÞÞ µ/¡¼Süæêê½]ìV•ãéYr/´!Ø^ 4„<„-îíÝn¶¯>ýãcþóû«m¶ß^ßütyÓ!¥7Û?nÿ´ýî"÷ŸÅ;Ì¿æØsYTõ ›bø¢5*Pû¦;åUØþáúõu€?÷ ß__ý>š¦¯Üš«!ÍQãˆÚ˜aäÜh°xÑ[7å¯ ÉÈßëAáʱ¯ü=‹Ö2ÅHžÁ(«›ŽÅR=os4Ö_GÒ¨­‡D¨EÒi-Šo3H<±­h”&Ñœxìc–¥D¬G¦¹œ 7†ê‚Dˆ#!÷ÎA•¸ ¥gJ’[™;`©±}6¥ÞQÄÖ›R%8®® ¶¹Ü{+k>ȯwòòÝlûx–~rîÝaº›{EŸž{i$X –G‚e‚ ¡ adl›G?2ú‘ÑŒ~„‡0:ÜÛfÝ® ÁxFǦ×Sæp.ˆÂº ¡f±:œA²r'‰Ä£p´J³PŒÖÌ-V¬”åG¬HsPÀþÖƒ²ÔXrY"E”¢(Ÿ2R³y$ŒüåîšB²r¤°DçÇ ”hL³PÖŒÔeÒƒC`ñsP°-¯)D¹ûiD *<ðŠ|†œâQ›/9U|DqŽœ2 Œœ2 eÕHI5zí7 ˆ¡¾Ÿ‚²*1\ü³ª ¨‰:²¦G‰aY3TÌzÉ0 0ø{i:Å„WŒ£˜@D-fìù“6ᇼPê$/¼£"„úñ¸’oÌ£Š‚‹M'Q>ú©ÝQEªÈtà”Ç Å–¾¼3­y«–§óÖ2h ´Œ3 TÕÁ@u0P•ç8<T©~v;|Ý”w–Ýû'ä¤ÝñæQ k“‰] Zù‘ë’5wˆ½o˜´ËÃ7ìë¨ÉI©^ŠÚ¼LO‘Kä´7ù±¹“›ÓîßÖÃb á–:1ŸC².Ñ£Hr@" 5 S@V-çìÄ“ÀD­3²ÿqö¼=ÒçÑêŽb?çoà EM±ÀfGÈûÑêqÅŽ±|qg"Mî-;dOÛ[êØ.êØ.ê8°¨ã¤Žý§Žý§Žý§ý§ý§÷Zù¼nËõ¬ç4O •½ªí’-Ã+j%¶ŠÅªð±E2 âI(ÉlÅä¦â,wR<·d›„‚+ZyÖfµ"gøÇØ¢±æÝQ ŠìS'\­\(«Õ9(«'^.@üðûϬMhýC†i¢[…c;@œò<üqA²çsHÖ=aÔz¼ ñ³(“)$Ÿ+a[™$­L”°÷•-aï)r“¨œ'K‹í>Íøíœ–ÓRàמL lìá6H R`ƒØà6¸€í?‹øíˆ½‡@C!”!èêÿç÷l? ¾´|”È©=Ÿãûˆ”˜K9@1íËý ßG„j4>@会uöûÈ3œz §~Aåð}¤ak> stream xÚÕYYÛ¶~Ÿ_¡G;¨.¢ܧtâôN³Ý: @‰ÓbK®$'Í¿ï9$µP#g zÑË¢Dò;ûw(êýáQï—³Ÿ×gÏ_ùÌ‹IðÀ[_{!÷B?"~,¼uæ}œ½žs9SÕ•ªÊz¾àa4{±ßoó4iò²0/ÕœÓÙ×9ƒ·å^Ufø—Cž©ŸÌÿ•Úª¤Væ†Î ›^ÿz¶\ŸýyÆ õ˜ÙÚ'! ½twöñ3õ2ÿÕ£DÄ‘÷M¿µóü ‚ëÖûpöÛµbPÂ=%<øvÀ¼ Ü\˜QBEhþR]ÉÍîËFUUi%Y˜Ë+”°¬vIcî“"3T‘–™.1—׫Ÿ7ËÕj.gïWfd§ê:ùc¾`t¦ˆ¾CßIÁi„PC~ý(0RŒAŠç¯‚` õÜ å@€–+«Æ6Üïù+y Xœ‚¢¦Ä‡i°—¼„$Žeûö'*©Yû±Ø%á‚9›§eÑh_ú«ÁÑp¢O"æ·3q’š 9û«A—“Gj\¦y"¾!€jï‚燄òÞ³L¥rVÍ}:ûéi¨DL‚ÈU[–4É€¬Å;@à³= Ûf‚.˜™M»ì‰+¬*«.D!#ðWJbÎÍêû¤JvÎòg$f¡·`p•Ö­?æÅçδÎ9ÆCÆŽK‡q }a¦¼É¯ªÅ¥³ïÃE´ÇXù¤v•bŒÀ˜³šÚ“УݗVÑ:¡À½qLç6‡J™ñ¦4×+{oK6‰ÏìcðYE~,Íçnæ1€á!´™¹§ÑÞå c¤$âh¤ÉjŽiš¯KÉvrIXÊ:%'tl“OœÑ»ÜJYÐ95}8¤)dãÿ˜»²¹QF¸oymoÕò¬/~ºAµÕ¸¿·$ñÁWtë›' >»>©-™p—V*i”}”LØ7æDÒ.þÚj"(–“Û6  j겨߶•ë¶Ù /ìÃâKuSŽ»‹$¢]#ó…àáì²¶+ëÌs])¥ÓNݪhj, :gè—´W£ འ<2òã‡Bùv£¬2óÆ^­!|Ù‘q7{6´¶eaTc X(Žo ò½iĈC@ŒD#Q¤°ì”ÝÍ":°8_-_Þ& f䃥%$‰e^I¥wHpÉïf¨¼6×vo0Gžlëãuu©Îa¡ô3ŽG9I8žVËüu%‡Í}s_haH|ÚEÌ63 >A«0©¬>Åú”ôì·~"’b ¾Ù÷g?¬‡“©jÕò‰€ ‡ŠÈÑQÍ~›|? )¥:£=«tL!àsÅñgcÃ8ôBÓ­è_ËÆ F–êMea¼@cÁ\Ì‘]C{Œ]ë˜Ôpc/„ªÎØÅ;Ìš‡ívÑX²Ë –Œ%–p$ˆÕ*Kçx½U—ß§pÚÝ\œ=E´!0McßEOìl8FN+Li@ÐTr4š¡F VºtCx ´‘&)®wc©[^\cƒUZ]ÌŠ¥ãÝå›7ö=«Ä¢l†LàdpÝ¢·@6¤øÒÛhšÞަ9[-̼Çoµ|‡¡öþíò­Ù󢨟¨ÒÜ íÔ®lcü¾Pø# s’›Úü|³ZþvyaX xëat¼‘ëdªQiï •úmvÈ+eé~5r.êH"7ð(‘~xÔ%Uñ¸Ãûª{a‘t/x×$_ôÒöab‡Ç©ŠENUøìvÂpZØ]„p‡`Œ$äºÉŽéà œÆç†| l"7!‹Cß1¬{" úPrü©žê6~<-é;˜ã‰¨»œ†}ÂÜ'µÜŽ*‘mPkm/EŒäEʤ/kíŸ<†î&…\ݵ§“0VA6öy’eàÛµé<étcÈD Ý·g““\t¬.d±]iK*»a¹G·I¶Øk‹Ð$]V¹mºánÁÔ{•æC|•áž3x§ VÄ®×ÄŠ]++šî,áê˜ß¼Ô´*©U‘µ[¡N´Y !J#Ki¢*UùW¬ûms8T—.-ö˜¦Mƒ¦M'¼ÎGŒ±¨k¥ ^Àêz:þÑ™ëÅ< ³Ëõ7ç¨æ÷ïÖËß×›—ï7ë‹·KóèDb3ˆÿQYx­Uc¦LÈ!1<Ô„<«kDÀB:¸qÞŽ°á}§rG"çèaˆ¦+lïZÌúšÆ<–„±K0ób1¬ ù›K{|fÒú°Ì³Þf»qQÐþoT  [’s5¨‰5}Ò4°' 2°šÃŠ_›×9mÕÖ7¾§Aľe#𠌠Ҝ\ÄÂÞ ·í €È¤ACÇ­–këh¸C»„v.½f1™ìt›ü¡Îå“€:ÎE­ßàFMfÑÇŒÉnoOqh û~Ç)lèƒÒû¿W@MÝžh–U»ØtŒ ;êú}]’ÜÍ¥öˆ’÷çdƱ9ÊÀݪŠV‘±ìr ¼ÓBà3€ÔßÈçKózY™%î6ìíy(?ÎÓÎ5ôB«^Ôã„"Bô%ó¾öIÿuÆ–%éG°µáXªHŽÄ³â°»Òz€§ ŒåEº=ènCfT›z3ãcf|O—>|Òè3B³ÔÒf! †Åì ú$ #WQ¬ãXªýüÔ¹¤+°n4¬Àø¿wèù¦¡~õßÍåœ>ãÄFËe{~údwpžì õåN^÷MìÉ.ÊÞ¸º¹×!®eÆãOË€xpï/˓߉¡¡fÌsF¬LQmÇM²Ÿã‡F (Œf8Yžx^îðv¿Uí æ¹9œ½¶3°<¦Ê9%~ñ¿‹ÑGfÝ/CÍl¾ïU=–ôo^+Î endstream endobj 5964 0 obj << /Length 2204 /Filter /FlateDecode >> stream xÚíY[sÛ¶~÷¯à#Õ©€A²}J[;ÇMNÚ:r§3IÆCKÍŠTI*—v± EP”#×}éLŸâ²øöŠ]ywó^œý°8{v!¹—© •·X{a"ƒP¤^,“@¦Â[¬¼·þËYùº¾ÕuÕÌæaœøÏ·Û"_fm^•4𓞅Ìÿ8ã°°¨¶º¦á»|¥¿¥þ•.tÖhúàA|ö~ñóÙùâìÏ3x˜Ç½8„£e³Ø[nÎÞ¾gÞ ÆöX ÒÄûdVm<©h ïÍÙoglÈ‹H¼ -Î&bbcq‡+åotÓdw†)ø”õnÍL”Kdù_¶­^ÑÜ®ÉË;ê¶©F—v¶ÙÝ~@虀]4V­‘ÃgJ EÆAf*Ûµ3Îüû›eU¶F|Ÿ[ÚäðÉ@„²Û”¯‰~ÞÚ¶¡v[kÔ¢ÀUêWõئ!ÁÇ!XXG<ÊÌæ"aþ¥áÀ›‡I„Rzs΃4ŠF©s»‡§#zÐ7 `b*ìÀÀð²Ö+γ¢¡õV 0UV-uŒ6¬£ C)ò3#yìIºz…™æ¾Ú+š¬Êg,¸[»‘Ùù™ˆÀ€Z:­Éº%Ë]m .QC÷YYê"0‚a®D^£*X1¿ÖÛ"ëäßËŒvkú„ƒ-OômÄí®1ö†#%µí}7·ÌP1è4ÌxB}çQçêÅ),ÅØä)n¤„ëF*R&*X‹ ¶ÕßM˜ªÇNygªèt> =»¦F)­²6»©v“ÆNœö«³Üí6Fuœ©ØÈ: ÈüO¶Ëk"Í­mǘ‰Yõòê‡èæùL1ÿzñŸ›qÇ/¯ç,n®Î7‹Ëÿž›… =ÈX? K.\]?LåÍùo×çFT?ž“òÞ1ew®²Ýöºž’ ÉøãCWq·éds*HTøXsa¤Ç “­¸9ä`ðjê®ÁSYÃúPßF7›7Û:ÿH·Äœš cqõ&ké;£0ÿõêòwú²ÎŠó{±{¬!KP,‘³DÖñ `éœ<„ø c{œº®1œT5hc¥óž]g68ë­×a’T¹ÎÀ]üŽEŒHÿUèø­sôÈv ÇF§=ܤ14~†0þ$Ä|,uc‚8^y_¾ )âI©vC¿ãÓ7ðiÇþJ;ºÐæ‚ °nç!€êÛ¬Î6yÏLÇ®Ìßæå{{«ƒ üó‘;+{èsÚò*¿­3çÖ˜®åÞAj©Ì9¤ŒBŒ ŒÿŒ8 „HF0ž£ª`/¦_}ÿu0– Ç`ÐÒÑåV™¹•ýlJ(qÀ¹¡¹nLÂQ @½õL2{ûŽP(4Ï>‰³xìϦ†¬q•\¨‘ Á$-sÖk¦ŽI ™ëù¤¤h¸µ°‚8²šKÀ.eH°s¼”+õúÅÖ„¸´«â°¢ÁÖTqf`ºŠ‹µ§§š› Ø>mÑÊÔ¼H@Iï·9phÌ/Ûl](y¹,v+”ŒÅCŒ’—̓ˆ'®5ùÈT EgG‘}n‘)ØcIíð·ôºÄI::N€Áƒ–Ãvmªt3Xi øžoÀ ô¥óž‚߃÷sbE[Wã…%»>D3e10¡çlkÚ6чníñØG¨¦m[0鬞³y,¥±3\rܼzÓKQ:NdÈa¨C´—~d0¤€¾±Ç0äWòva!±ˆ2En¦,œ§pOïS™ÓjÌÓ… ž¢…ãy# ßC‰Ž Ñpp”.4èì£ N’%Èøñ!UÞ1)XŸeÌÑU=ˆ0‡\C©žJyê–ÄóBçU@0$©rÓ´š(Äöq5JåÃä>5áòª&y¢Š¬oâ>cxfÓN>æø$y¬ò¡ˆß‡7{{G±€£éòM#ånskäS˜Ã±½ÐµÆpÙÞpØ A8môm7”=A¸1&¡ãpÁxÿô eOý“Þþï}ߎ.+—a“,[†G·ÜclSÄ,ˆÄ£lSŒlSòŠÿQò}Ýe¹&Ñ\×Z›bŸŠÐ²mº|stËú)»‰6ý¹Çk,óhÔ¯ûd”6Ì4:Ñ”ö¼¢*IÝõ°ú8õ%4äÍ’¿åݨçœÛ‹lb™‚º½Õþ¸ýõÒ¨FF|€9‹J¸ü?&!tÈ endstream endobj 5987 0 obj << /Length 1759 /Filter /FlateDecode >> stream xÚíY[sÓ8~ϯðcÂÔBK¶gŸJi…¡·tfg “q¥ñØÁv(üû=²$Çv’¥- 3¼Ä‰,}çþIÁ΃WƒãÁó8! ÎxîøÔñ½y!sÆ3çzøvDùPæS™gÅÈ¥~0<\¯—I•I–ê—rDñðˈÀÄe¶–¹~µIfò@¿KRÿ ˆRDFǎǃÏP°CôÖò±ïÄ«ÁõGìÌ`üo#Îm5kåx"€çÒ¹œ°Q#è1¢‚©Ù‚89¼¸3x±Ka‚f¾VøS>å“Õ§ hú¬5dW?N”ŽY¾ŠJý;Jgú‹Lc¥5~[øÐ¾Õ·/&‡g“‹ã3ý{%‹"º¹%ª¬P«Q«Cq 0û|zÐêtAç'B4tÁŽK=P•7T‘y®\˜å“8›ÉÖ~ÏO@ù†%@8‹uì6€E°oÌå>â̳s?`޵äEÎe¤µuœ¥eR_Ëh4z( 5µHŽ~-ˆ1øÊZˆ¢ ÂÞÐ|yµN°X/|x\ †-x³¨Œîƒã1Eí’gÙ¦œnæ=®eù>i¸–ôéwž •5¤ºæÚ "£R-}åѪ%Þ¡…Äw\Onù:I?ªôÂÆÁPn´é»Á¢ýÚ*®^ò.™æ‘ÊN<üÖR¹ÁèßBj¤¸ÄG!c] Gî‚ásÄXÐq8bxkeZn«ç÷ÁYŒ±Ú5øÎ iz±›œŠ-†»¢9 p òðläá¡«ŠÔ]Y,@~ÀíTS¿T[¸70ºšð,f¢m×\e”Tå%2ZöÊY^E¸ë¡”àûÂzš¨Ckë]nâ´ùËØœ£ãä6©zŒç½U¾ÞvA®~Tõ>ÏrëÆ™,ÔþŽ+8ò r[èÆ‹Ä,œoÒxëý˜yË¥y•¤ÆMÍLâoïô7 ‘jwÞ&å„«Ù¨áàêwÓ‹ÕÀ¦HÒ‹c®&gÚ«F°ÎólÕƒ‘„!DH³ÖõÊ»!JD­ÒÆcÂzÀÚÿfí’AŽ€‡ªoBŽG7…ïµ\ zÿ”ðPX›1Ig*We½»jüÕö‘*äg%uÀÎJ7«©ŠŽj^±È6Ë™y3µS6…œÕzp,“*ò*ý‰CáoÕ? |r8xx5~=9R;ž¾ÿ3ž¼<\Ÿ_¿W\Ÿ„•ãÔs÷²‹ãqk]Uåa¡4>¸½2µ’²Ìb•Š^T¨„FÕÖ]…‡U}w0«Ä¥Š›GøÀ¸ÙZªúz{Çm²\êoSƒRG}*sðìÌN²ùRµÒæŒ ¨9Ñ•¯”¥L¨&€µ„íP½²•£4Ï¥¬³îiYXzR™Ù¼’²/¯8vÃöKþº¸ÝB1>(ÍÓØ,5Û-³T«˜[ãÉ™œ2º7—îi—¨R…)ä0AA?›žÌbù´ŒZÌU\eæ òRåEu 9;z"Â-—pWfºËÌ|èa\<.éþaÎÍŸˆsÓ_™s“§cÜO¸©@‚z†p“ý·øß 7ý•7ûC¸7Âý§¿nõà#=-˜ÛþÙm´ç?íêêq;éç?WWo£Ï¹ (KAÛbö4w$—R8Š }2ŠÖÊË“l­ê{qPWøB)i².Vß‘ɱg…©9_’Xîµ`‘é—i´’TBeç˜?„E$iµâ@\€ƒÎ=›ŽÞ8ŠUë\È{ƒ—!ÖN¬Ö(£=Ô@P²Bö;]kBD"Oñ…ŠF¿ßµæ–ÚìA´‚_tœåÒÕû&:Qꋤ,oÎaÎRUt 8—Û#¸Ú}/= †]׳P*Š£ŠBEsTaèS…#vzªëˆ½›ã¸ÒÞŸMNÏÆ—æò,Š—ØºPKÞAg¡ü¨ÊÓƒÈ óxÑe£ZcVe¨eß÷WïÞµ‰Ì¦=ÐÃ(hœ4(†ÚV“˜r”ð]¶U“Õî}×f\Û,4Ø_gͪº7nCÔ­“ݶ®¿}ö6{ï­ëeÅY¢¾Ü¢ˆn/ íÑ¡õ' TE¨Ô^&™²«”ùTlV+ωYZÝ£Ù7gÐÈŸ1úòV#ܡ޶òöETEº£ÛQ`Xën×[ÌÚšfÓ2²ÊÄõb{›]_7UfžäVN³ß¢>5ÊŸöÇyŸ¡ î·v׫ûo5  bï?«{ÿzö("Ä(Mp  à¤E¤¯½ÌÙ¸·@#Wxáð([)º¾^J;A¿×$~nV¨ëËÎUÛáÙ›Î[•p,¿­eÑÕô_2ÑЊ endstream endobj 6002 0 obj << /Length 2151 /Filter /FlateDecode >> stream xÚ½YYoÜ6~÷¯Ðãn±¼tµOIëiÒÆõQ H‚­¥½B´ÒVGÜüû9Ô¹²ëÆAlJ#j4Ç7—z·õ^¼¼<ùîgɼ„$!½ËÇ’p‘x‘Œ‰L„w¹õÞ¯Þ¬y°ÒÕµ®Êzíó(^½8ò,UMVHøI¯9]}^3ؘ—]!ùU›mõs¼>×¹VµÆF8'lýñò—“ÓË“¿NÈC=æE>-ID#/ÝŸ¼ÿH½-Ðñ(IìÝÙ]{O†1¬¹wqòû uºÜ·ZC1Ò1 Iü#F ªX­]ió¯ùl´U¹•mÎ 8É'Á ÏgIGN8£“w¿ûYÄ£wÀ®aìf Öèê¢MS]×?à]Ùì¬ýèê.³öšËcåÁ¹1ëª*+¼OË­®Í÷=? ˆ 'såå.ƒE V7m‘¢ÿD WµÎöY®*¼iJ\?U×ÁfÿiSé¿6z-‚Õß.¶zûþ²À'æ_ªã°Sî*sk[ë÷+$ÜfŸÍ;º0Bƒ}É}Â…ÎZ;PÚx¨P{»'–•Œ„4ì6?_àn‘c7ÔÆt@›¥KÜŒoÁ§=7_DÉJÛ¶\õR¦©J×Àw·È•’8Šº­``ë)RÂ¥# ¸ ù”Emâ©A,´iƒV¸Ô#V|K9 !+Òìøµ4k*| DGx]7*+Z*½ÕE“©¼&V:…ËU‡? ›JëÍV5j²šz@€ÙdðbV³oÁL,$f½Ê¶¹nolÄÆ}ˆÜí´6sÈô ÷¹¼,n1C9º¥¶ƒ0` Ö… 9$d^QyD<5O„>‹ (÷|ÁÀe(Kk>g‚ìýw³6ð…Objóqù7)ûI —7ç/7/Î6ç§¿ãýB_Ý®}›,¥­3PÉ^Ö­Iµï™N|vœù§±Q,’ð_Æ!ê<'Z'ç”ÐmuUÛ–ÕÆd–Ybƒl=¼ó!ü&9Ãå ‡‰`Œ *IÈú˜4xr~ûJ aˆ‰ ª¶,ŸHËl} |c¦{þ4y„0—‰TÛ˜4¶{¬hQD$ë8<ƒ·ñÍo#_ÈÙD¾Tê¶~H$ŸóÈæÒIÆRëîò`êJýTÁBÐz*˜I=I%ðêmý,+ìOu`2.A©Êäw½}ÐD2"t(6F“lŸjP1bᲊýI¢©«ž³ï$"!ÝE$[N2ÿ²Îz.H§`tŸƒ°ZîU©ý„½gÏ„}Ÿ»îÆà“îqá(èÙ×2½Í®+…•ñ˘‰ §ÿDRÇeRA0˜b÷I'Є3IÎ*íãw3,ì˜äMIî+—ÖÙ“›¬û¥¯ÒªÑÛáëÒÃÉ0iNKšXµ=¯‰WÛU™˜]R% A27ê; q¼1I»Ö®Q€Âöîìòoö*…FµÃБ€Èynh' F¯­ŠjÉ×ÂRÎÄšŽ%@°±1éM®œ©ñÀN§Æ…Ÿêv¿ïìÛµFЄ7õø‚Ÿ$5½àØi¿]½}»ˆ#”ð~õRtÀvÉêA@bÊfêý8tk®Ñ2âtrôw†wY‡7ÜdNYÐÊÀŽͬQDªAä—EýPÄ©~C”ÜÛÞA¥ ø(6ŽYÆ}æ|qf”ôM·´ÐòCÎ"Þ5R¦|0gå&˜E1”o0ŠÇ„ñÿ7ÎùÇ:¡ˆ…¹ŠèAh3†è3FpoÆ¡¥“}V•þþß¼!gù—Ú ðµ6t)hsuqº¹8½¸xýî·Í›Ó?Á ³vƒ¸À¨ ˜KkÌ Ÿ@ß>uS\ÙdŒ™{ü:4>,­ÆÔŽDv·x5D*’+üŽé´Þ¹çÓܲ‘™ ¦vC<Ýl¿^]^­Ã`õâ­Q®^ŸŸþ4ܹ °¹¶Ã`ºo›¶?§ò»1U眛ªÜϲX¥S펪5Ü?^yþTÌ\½D¸Hau–|õJº‚ŒD…KÝ^ ‘sÐÀ§\ÇmÂü÷(ÀýsÔñOjÀBr˜û<¸ÊÄ â~N;{m½.¨:à £É\²ÅßëL endstream endobj 6018 0 obj << /Length 2307 /Filter /FlateDecode >> stream xÚÕY[oÛ¸~ϯУ]Ô,o¢¤Ý§l7éé¶Û=›¸Àma(6µ%¯$7í¿?3$u¡¬\ÜôìA€H¦Dò›™o.Ñà: Á«“_æ'/Î% ’(®‚ù:ˆxɘÈDóUðaòfÊÉ.¯tYTÓâÉén·É–i¹øUO9|™2xqSìti‡_í³•~nï/ôF§•¶?ᜰé§ùo'gó“¿O@¡³[KÑ(XnO>|¢Á Æ (IÜš·¶T1\7ÁåÉŸ'Ô‰A ô”p%ðmÅ‚ ^Ü%0£„ŠÈ ü¹¼ ÛÏ‹*]OA yf/ç(cQnÓÚþNíåÍÅ/³KÔÁéù™ÙêªJ¯§3F'šI[¨-dNcÄIø/ce!ò‹s¥zxi0ãÄ {puY¢™Šr±,VÚÛïÅ9Ø“§ •YÍ,Ø*콬8‰`À½ü‘†Ô.ý½ÐCÂ…·õ²ÈkC›¯õ´ˆûó€I‹'é©'_ëçOÃ#Idä!J÷ˆNn -Š€œÍ 0ÙNlá©b\áRõÓÐF ‘ÂG»Jëô>tR©x3åÙ¾Ò%Ny¢Úf_ö|­Ôi­Ý£4oh_k[ÂX8Yíì±+‹Z/ljÈ"I¸TßÅľ[9/Îòë¡7V{¬?asóëªÇŸÖ?Ó®B%Vœ+‡[™j.Ó› ®bôs+W#@‚§Q/Ö‡‹h½±j¹ {XŒ*™,qö^¢I?Wû­{ümgKfѼO>«9¯6…`רoL! ï,ÑàæÊ-på–,ìµÒv$éVbp;¯÷›}3]­J0JC©„ë RV…7…«oœmv–•“ÚäJK»©tÁ¬o¯Jç«&ì¶³K½ÔÙLðf=<j…‹Ó©‚˜=ÿ×â%šåwó³¿æö1µ0½®¬ý©oø¹Ù˜ÇPgŠ¢ò¨ÕŽ2!f$ Õ±LÀ³cø¾Uw¶‚­+m*EÁp ²œ¹3#Œt„tà5â´zÊÓ,Ù\Ö͉œ‡ŠÐ]xÜwCç=L@,IßðóÆz¥ÞB: É8ê«ö¥²ÌÆG¨ ŒŸ@¹×Öž8ÞÚØ]ý…ì€A W˜®KíÖ4`{kgùl ¤ôÖ/{Åþ^¦.ú¹ {]iLmnÙõ!šYËŠžðDá ³#ZÜ&J3Ðä*á šk]§.¤›Ü>B Ii¸†¯ÜI±Ž^ýmMm„76¬HÎ`¨AÔé@ø:诀þÑaè˫ڬ~¢‹³¹ƒÄ“ЀDY–›1–³$’!>>Ū>É!I›v ì2 9"°HÂÉóÔº? ‚!<”úPI@DÕ€ýmRjBžÝ¾({æPpÇI)Ì‘Õ?|úGgܯÍ$Md¦’ÄIäWyHœ¤Ñ™-%ÃDÞO¢Ë³?ߟ½CÈ/ÏìëEi—¸ßÒ‡óP~œg¸7ÂÔôà„M(Ìš).‡ wþgïu¾Ô8"'ù~{eÔ >ÕçÍí¨áø<ÀG^ ÂWŒÉݤ¼Yêè-F&tÆ£¨ñ<­Òd@šctëqË– ~ÕÚŒœÐƒ|w =EDIG¸ï¢§dœÈxpØzßœjL§f]jmz4¶w×V”]ÅØæ{xoŒ:èŽÝâî³µð ±[c´~ÍѨ&wûmŠÜš»ìŸ4›^.þawÊü]¼:èc 0´€}lù@Ût§½ó¬Å!>2î|Û0¢0'UýÓØa›–°FÌù¨»ÁYÈtÆgØu»Äù¯÷Hs<*›6à&†ôbY˜^Ùgkwc¨jÞzLò€Æ W}¡™‰cRСó4Å×À‘î¡?—À]ÊŽOKLEž<‚.©©Ï#<(ÕSç#à¢éÒ}.±óá9;š¡5j¯p«Ö¶wpt¬ÿéH<­v…ãØ4fÿ _Ib&ÿ;_I”Èh;ìUu/"e¢ÓZöì Þÿó;ëPW`«S’4ôÿ§³ÞµY;µù)âxG¼¦î:‚ýÆj±î%\ï(¼+°ËWV® Ðùªí¸ÝBõØë¿ÓbU1cýo±òÇ·X“ÿ]‹5|°ºi»hÇU6"çl»ˆwp¸³äG•5VŸÃì…«G“M5Ksöc Bã˜N^Þ¤;L,M„  tV2™¼,¶˜Avݼ`ŸÛ¼²v3à¾ô¿ÑŸþûµKBæP7æ0›«ÕPÒÿë$ endstream endobj 6038 0 obj << /Length 1484 /Filter /FlateDecode >> stream xÚíYIwÛ6¾ëWðV±/B°riO±,»Ž]Ç•”\b?=Z„l¾H¤JRYþ}I“-˱_–¶Q„Ì7 >ÌŒ°ucaë¸w0í½<âÄò‘ïPÇš.,êqD™o¹ÜCÜgÖ4´Þ÷Om*ú2½–i’ÙêzýWëõ2šy”ÄzàPÚ÷?Ú&.“µLõðñ& å ý},—2Ȥ~!ˆRDì«éëÞhÚû»G¶ˆåRÍ‘‹]k¾ê½¿ÂVã¯-Œ˜ïYŸŠY+‹;<—Ö¤÷W—º`D@Œ¨ÃÔl‡X)ü°58îÒZI%aæj…?¤×b¶æ³ g×›KÌX¥Ñ 4€Ò4 õK 퉹Mp?iM¸°+™èõÀm‡K‰ 3ÔzÔúPì)Ð.‡Oî9Zsôyyä8 e°5 t ]dš*&élž„²%ïåhß0lŽÁd†X,@;X Ecï ·Zs‰Ö¾V!HZæIœ±õ97À3¯¹#ðj¥Z$•µ?ç/žˆ1øÊL£ìBÂÕ¶~µ&?ñ@³€M4ã;0$HíÈü˺8‡+³dÊ–ùÓqû·…AìB4 ÌA¥Ö€ä‹2>­–AE ò˜×*Ò}Lx®¬‰¸°/0¯òO¬ZÛ[ÅÏnêû(¾ªm˜Œ§ãÑ CŒ|·vþ@/9‹®Ó@qîinRÄg© i¹ F>c&‚2þ ÉL ŒMɶv„¦дÓ%³\LD]B=D=×zpG†­•†<½TË£¦<ˆ {,t õ)7„ólg¤˜°3%mSEÞR}äqËÎ-a+ÞÄD6=vI Þu(àšuj‡a­Æd3ŸË,û]¿%ù­Ôqó)*®O+õ=U!xw1 õ¢žý4I+‹„²0è)‡Hn¡›ÞFåÂÅ&ž—×9¼Ý—ã~\·Ü™,¶ÜÚ"+`?âò&÷tx€½ZuÉmš÷E­iøŽ7ZÛR\$0•ì¤ Lá¤AÎ]èøZuT) ®(]e±Íqÿ›+*Õ¶Z¦2¿ìc¸Úî…qô‰NeŠ#í-*|8¬}4¦·åÜ2(£°õº‘Y-f[k×CrJ2‰¥‰¿X($Ëe¢xìSßüf{ë€ <Èûà6ùúr:>³¡ÍÎÞ¿9Ÿœ½iŒ³ä¦Šå(Ö õZé¤u'ÈBà3bŽG‡£óéÉ«³É6Òa*Cp{,³ïd4¶]Ñ7φŒ†§“·¶ OJ>ú¨œ^…ö\å·r®(éC¶Yí ™>ä‹ñÉ;u'ê$¼»÷éáð‰XŸ'ÎN :"aA èïq°*OXMŒy¤ñœŸÿ(±r8:+£ïÓ“®Ã8¬2Î4ˆbYªB9x£t î®ï¯ÎÛ‹óÙáyÇ1}›U¾Öè¢x­!/¸Ï]°ËCJí]±媪ï|¨ rY³d]€8•²U®)µ~øš’Ô°¤QhlÀ•TÜ*­¢îdÌÅVQ¹H¥ìÈüð¦/ž·œü—U“V# j«ç¯—(@Š{ˆ]H“é²^Ê“2—«’ˆÛP§ižªR·²´î¤Z-ËŒü©ÎvïÏÛIžïï‘®:[Ét-§äßœ›y¾©³Ø<“Ëz"!Ѩ ‰Çü¦(⤠º›iãâ·4jôw4ÖŠ *ÙÕ¯‹4YÝGi?CgíFæÿwÖ¾sgín¿ý[kn»µö$ ªÎÜG5Ó÷hµä7Ñ8õë:?Û¥@¶&ÚÔ&4]Õw»§PÝN©,ù]ñ¨(‹³›n¾d“ïÑuã Æv¶úê^ÄãšpââÙ{p(-½oЃ«å›y»Rgï¼:ÿ¿â@!¤Ô×AÙ‡û•”X]œ ±;â „˜Èþ<œb endstream endobj 5935 0 obj << /Type /ObjStm /N 100 /First 1003 /Length 2094 /Filter /FlateDecode >> stream xÚÝZ]‹\¹}Ÿ_¡Ç$j©ªT%YØ]ã$€±ý°‰ñƒã‚É2ÆcØüûœÒmµÝ=2¹Ý¦ú^}I¥sªtUZn!…Ò(…ÌÕ dêÉ솄RÈ´e74TjnXhj08‡œ“†œ²Á»À3‚UÏo µñŒaio¾¢ÃäVA×"n@ÖÅj![õÞo¬(ïV8PnŠ>D1÷r%˜£C¤©—3Œ¥·'5Píía$Ü%o¹0¬ÖüY œÅ'¤¬š½<£Ž@QŽ—¸PGoU{Ë5pMý-j8\ÔHA’9ÍA(û\i ÂÅç À…›Ï¦D¤Ï?šé5*žiîukªâ~¦ä-@.H}ÐÔk`HïÃ|ÍŠ×0L»6F¾ª•ŸÕm Õ4'¯QSPêsUsP®¾Z•‚ò±aêTûÜcAÕš7P+Ü‹Ã`™¯GmÁ¼&' ßRGЬæå°F–Ùû€Yîn†ŽŒ²õa™Ï Þr°Ò¬I0íþ‚¬&AMƒ5ñq4 u™]ªËìb+—âíq¨Ò:<+,þL`Y›BÕÞ/ªU+üNs Žj¯QÜÝj¡ùê£F ðÚäVÆÀº©º™™[0>¯›}ЩxåìÞ•›û]qHÄ„n|×%R?ÂDfo´{'—ìÕº›4ï”­×u“¼+½¬ï¯Z½_øsöÖÜDµœÕÇI¾÷äÉÅæÕþ}6ß_]]ß^l^~üÇmÿý—÷WÿºØüp}óóåÍë:Ho6ÚüyóãëÜ\l^\¾» ¯Å4f€ÕÊ‘ÜëX£©¯=GIŒr߇'OÂæeØüñúÕuØ< ¿û€šï¯¯þ­å߇ᄏÀßÿ„I#ÁT[ÌXX®±rYªtB$–£;•¤þŒkÆæ‹Õ¯;¬„²Ä‚ &¹Rk¬N&Ô"ÈñëH2hrÅÕIÁ˜;(`ÅHX¥I(Z׃"pQç¼Eª»êä¬Tµ#¬ÏÖS¨XtŽsdJlžºêæI>¶CÂØÖr<…$CŒ?‡ò4¼†–{ ñ"l~úÛßAëànë®wõñ—_ÞÜ_ð—& ¥S®Å ç‰nÝ)À÷{åž]_ÝöQ?ƒpIF¼ÐkAŠsí”VV„‚. áЀâw/Ìo ÏA)+Ò¾‚õÛA ”BHü õ ”ϴ𿱴Á endstream endobj 6061 0 obj << /Length 1265 /Filter /FlateDecode >> stream xÚíXYSãF~÷¯Ð£DáanI•'B•Ý­ÙeŸ€rÉ֪ɑeØÍ¯OÏeˆ›ª„­<ࣙž>¾îoZ8¸ pp4ùùd²wÈI¢TRœ\1 bž ž²à$Náªçª®ÖÑ”ÆI¸¿Z-‹EÖUi'~QÅáMD`á²Z©ÚNmŠ\íÚçÏj©²µ²ÿD)"Ñùɇɯ'“¿&TÁ±Gsã8X\ONÏqÃü‡#–&Á­Yup™À¸ ¾Lþ˜à®,˜A0Â,¶f|5‡ þYÏÅì¢Vj–gM6[Te£Êf}††?b5•õ:­çÞ¡”áD0”GÙZ]ÕSbDYêÝ^©Ò -7®íXºÃ–Uyiíæ•ÊUŽŒŸ0" J¦Ý!IPƒåw&? Ã9%1GXÐ`ÊJœ3ŒVÙbvM U$ÂfÖ|_)ᩚ~±©]˜3?Ö  3ïïvªº°ã|s†óèH,ü^;GR„ûá¸ÊÊ|©œ­.¨ÛQœhc¿<‘Ööᤱ½&L)¿ˆŽÕ ”W5D>W½óö4p,}øZ—)ï*‹ ÑÙ’rDxì·hH¹à½Ðê) ÑjÒì[3P½‡<ÁžÂï4×¾þÖì¾NÆôãÐ%iÂA,ñ`í®…öºø[Í\ì,UùJ½¤D¦(´jmŠP/†Ùwg羈2ŒÒ”w"JÆ!úÈRY7)9á( ð ò)õî©³ëžø€”’’Fá`|Z”çÖs6°Pz-† Ññ¶üLí–OżÎtzb“º[!Îþž¦N ””26ÔÀEp2ãáÉÇQŠ!å…My˜°)?v¦ÛoÏtÎ9­6;ð2vh‚hý]çúæzîKª©S0BÅ·N(”+ÂE9RçÓž »ééKhŠh,Njîlìƒ0F"¥•÷ªaEl#¯v§¼vÅ>v2E‚YG†à§¹ÑÞÊ–£"Aïz›"<„Å%ø¡œƒKE›¥ØÚðe³X¨õú'ggs¥l\n Ï×Î-5ÎÛkˆŽ¡sTU{ çÞ/&K)|œ+‹ÒwK†UÖKª>Eªkýj¥éÓ1äq]ÜKå ×^¤´MMSóMGÆsAS@°ù¢+^3J‡:Ý}å]ѧñâÝ:+G©øÁ™“=—9Û"º³­´=·‘%í¢7£' „Êé{e§¶ðŽÓxV°äShpèš{û(_=½ÞR('¢Od?^½mËfW»~Ã¥S_7SÏk³E‰ˆ;×Ç‘h ò_ï²à @ÉeŽUf˜Â·¿Ž>¾ê¹ÒðDÿý–DJíâüžŽ©Ðõ BØë«Jݱݾ7Nû×j¤ºÅ QúƤ@^Ì |”|•Zk1r7úeU䮿YÁ]“ãp¤õy}çC ˜ÅäÝ ‹¡(½ÿ®ÇTïz¬ Ä&ò±Îg{ë}¬„{N¾§õ¡(–ÃÖç“*/›«mÿp·ºB÷ÁZä¬ ~GUJ0Þ×=ƒcßœRÙÿ”úŸ§TçÈá‡^(©T>ù;ïègjN˜c•„íô$ÁáÁUf¯È)T(Q4•< *Û—-•_`ßÛFîÂíšyû\½ü›çfÇÇ9ôeú#èÝ&,ýòM…¿ endstream endobj 6095 0 obj << /Length 1062 /Filter /FlateDecode >> stream xÚíYËrÛ6Ýë+°$3!Œ7Á¥kË™¦žŽë*ݸ E!1Ç’¨RŒbÿ}.Š&)ZM"å¡´“{Ï}&è"èÕà—ÑàäBPáH1…FoÓ3¡Ph,"ŽFStãýæ3é™|bòlå,ÔÞér9K“¸H³…87>#ÞÚ§0q–-Mî†_½O§æ¥{¿63¯ŒûA1c˜ú·£×ƒáhðÏ€‚( ¨8$!J惛[‚¦0þÌ#>”³æH( ÏúsðÇ€T¶LÁ‚™âv¶¢(‡[ƒ×}V[­”`ÂCgð}>‘ãeœŒWé»E ²ÖRkcD[‘¡€¿B+§­;ÚN.”j¨"(`Ȇ&“çÖÃY>N²©ié;¹l   œ€AÏÀ]²1[i0InfÿM$q²¿»„ÔhéN²EQ†ü¡è æº¹N`Mkv‘ñ¹ôŠ—ûááܾv½± ‰±t³æî €j¬IÔP¤s³ò)ñŠx¾ÜE),ë¥ñûâήÜOÀ(ä| (Å‘”íP9Xãež.’tÏv¡ÓPþJÔž²åL¼j­gI<'QzÅ~˜1l¹ðÞ^[Ø«uþýjWaAtËÏÓ¸ˆw Yuy½ØLï4F±æºÑdhÃü—'HåMÿrB¡w[?ãˆêMÁæñ¼%•ŸÃv\ƒç¹®d[. qÄy]ö}Ûì]Ò,™ú#s!ïžRÎ>]ÈúÅ” 颻s*8Û \+·â…5íçëëᙥ‘S_Jo4Qâa(–þ´ Ë€aõq3løM¶½œdœy;+7ú¬ÓàCZÜsÏæû‚q-ùhè^pà“HýgùÞÞ¶üývìv´Ã±îæ Oß>ºûÀ=þòEk8v+[®§Ö£gø6kgÁv1…ÀRýÐôC¶tèuüé>â{í&ö:°Óƒï'xˆCئübÏ}AŽî”ÞSÔ°g–Dœ!ã˜[êû†¼I·µc›\Ùí"[—Gà–\¦“> stream xÚíZKsÛ8¾ûWð(¥, ñâcæ”u•I*ÉÚž¹$)MAË©%);þ÷Û)R¢'ÎlíTÍÅA ÑÝèþú!ûÞµç{¯OþuyòË+Ž˜Å¼Ë¥ /TS±ô.Þ§ÉÛ©ÐS]™ª¬§3F“ç›Mž¥I“•M¼0SáOn§æåÆT4ýz›-Ì)ÏMn’ÚÐ gB0>ýrùûÉËË“ÿœp`Å÷8­Xè‡^º>ùôÅ÷0ÿ»ç3GÞ]µöTÁ3÷.Nþ}â÷ÅdO Î# å…Üg¾ I–OYñXÐþ¤6ÕíT¢`ÈÆ/¯dÔÛ«&Ÿ6ÍhÇ[”ÑL¥?¹§‰¦¤ç-*(ɳEÒ˜Ž8 ð `'STÏʤHæ¦Þ®iö³¯ýÒ­xÿÇ»wðΉ£43ÇÒŒ‡,–b_šM•Yí×·câhŸÅ*þqqÞ¾8ûºËÙîË “ÍY]5åÈüiC£$”ê‘’‚ùa<¤ôYp°wO;`êA§ŸÄ¸Ø¦©©ëßè­lVîBï²Úéd ÅÎ9´ï®{RµIË…©ñ|oh¦´rw¹Êpc$&Ëm‘:—‚·þ-ÔÎ ‚×±bšG-Û›$¹w8GDA»&¹F^“¬¨ñ:$£A½E§6‹‘£"Á„’-kÛÒÚ¶?î="b‚ëvýéEÍdÄ;ÞÑvÖ¸íJÞ?ü1ÄŠ4۵쓊Y :¯NŠ1YAe<Þ©lÛ ®šlmƆLwWÀ¦3%âÉ›åÕ4"¾ŸÇÖ4ЫNwfIq°m³¬Ê‘¶fÚÒ·ˆ‚Ò`Û$ôV¹AQ6­ã·h>ûR™%¥<&TÈ”ßa!‹âÎ.ÊjŒ¦ÏÂø‘† ðÞהßS‡g+Óz sISoÊb‘סYKéaµØ+`€uC‡]Q YnóQ£Õ°S}Ã}û®“êÆ‚N{«õÃlžø6lV× Î_Ä\ƒÚ¥Þ¹ê»c.Ò #¦%'žß£†K âæ×qçŽewßÏÑ~¢‘kÁÙuV¯“†¾áL•iº­h˜-éiï§±„µžœÑ®;‹«µ;ªÜ äÙñ²*ÝQ‰û^Ï*“äkÚzùYº¤¯W.rÚ Ž‘ìº(«¤hè ¢æo´1Éë’,Æ L>Øë$ýpέ&yC$'6¦ Ï/²Ê¤MIkîé+_kð½\Ò¼(°AØ®¸¶ù[a*I삞VÜÌ]Ö¬hyQÒÌa“#.[’†¾&yŽ((ÕäCaèS½*·ùÂm.‹BG ý uâliï'ËÉK•rn ƒ»U™Û¡´HfŠf—ƒÂç+“&ÛÚ­µš°›­ÛÀ¸Çº,”ž\m7j£¡In¦•Íáép˜Úº^Cs‰£¹Ó27¿È4  z‘×m£ÇÀ4-ÓÕ˜BÐß;Èê0m¸a«XN•?qƱnÓˆ¢,fO ©m$þNð_÷™ €4>àöƒÉó#•ˆŠc¦|—½ßTWzX9§J£Ê–÷s[y|m¨®˜ÑãÏ©rŸé=¡ÇÇi Ag 3W”lÀó«Ü-#èm¨7&uZ¢ P@`ãù-~„… 5©—•uòܦ­ýhW.èA÷ä4U…®PVsÌ ÷XÐLOM@ÜïâÄNINA_t?}Œ¡.Ï@¡~T° É, ÉÛk¢óeßZ±ˆw7¼¡¯Íi¼Û|õiü…LJ½¯£‡SH6îEèÓ§q€åèPC˜‹Õ68&ëÍC¬Óq/'µYÜÙ±ÉKéëlÚ›#¶æƒLõhý„”Ü%mý ôç^b YTxcî¯ò2ÅX|ó !ÁÙ¥ÕÏöcçÏåt&¸d<QîrܪõábËò“xÄû¢:¯J±Í<ä¯ÄËî¶1m˜SŠtˆ1JC-÷0æá®Àc»RƒN#…:füÂùg•¬ä=øópx»Ž ! ÅŽñŽI¸ß1y—]UÉ.ùêˆX¸ëÙ8*ƒò ×³Mú!ÊúþþÉÑ~E]nÆÎtûœÙ•€#"GýÕüò+„À¦-5`é°&Ç›TGë^ØÊ+m‹¤­fÛF£sŽhçoÝ”‹žà˜‹¨£æJðb;Ä Q2bß·›¶oHá[ã°<mj/™v5žmõv:¸zli&D q>ú5ù4ȱkòá[;[gë,GhÑœ[ãd/Ûí%íË{T-ª¤Ò¡­eh}²X8r =,&šÆŒ5Zöwà Š¶.P¶<ªl¸+öû]œó#½!¡Á2ù¨·šéß!J»k XÃRº‡“ó³wo^¾¿œ¿yÿê^­žØDÞÖ¢:pÝݳ ã¾Éce˜æÛ…q“d*zg*Á¸©3ÎãG¶údÐn⺳*Ês:£uçñ°)§â¶s “ ™N®Ûn®0Ø}ê‡+¢Qß S¶ˆCãž•žº­3Û÷»#¶e®þ&_¶.µÜáܤj»m¡ÀMÖ-> stream xÚÕYÝSÛ8Ï_áÇ„!ª%Y’}÷D)0\Ê¥ÜSÛaLì€çœ8g;…þ÷·+ÉŸq-t®7©eGÚïÝß®p;ÇuÎFo¯GoN=ê$L:× ‡ùa¼‹'ÌPؘfë87ŸÏ6Išõ,Nã°ˆÍ %Œ:ùrýÇèäzôψ‚<®CÅ€µG”«œùrôé‹ëDðýÇ%<ð½kéxÒ‡gê|ý9r­.»žZGÉ[:’@_Q—¸\ó uÇ1þW~EmÃTËÖ'”¼%Έ«gJ 83”>3êvξ9å~ë ØUðƒÞìN¦Ü ÆhE|›ù<. 0g||r‰6ýprym~Mæ¹ÊÌój¸ã£‰ãã›ã‹sØws~yúÁüx»ùìrŽ~ÐG ó\çq¯J|ñljåºçf¡ùzã“Ù‘æ|vÒå[ÞǨÈ>¥”BNL¸ãy¶*ÃdU˜7`Á1,´E“È|LãÕ]y_Ml*ñ„èÚp¦.Äý "òÕ‹ ã-1ͨƒ»dËôTzÄç•íQm½§ãƒKQí!“©'øø* çqO˜yšhKâ:œÏ³Mõ² —vKXاy˜% ˆòÝí²PªZŠuž¬æHö&Û”2K»iOæóÅ ˆ`ªÚ5ˆøû©ñ„ç)âBfï ³§Lv²åŠøÔ¯ˆ%Ö嫬4‹Ë¿..Írmí'*ûéÐHÊÒL¿€$÷`ͦ¤àNàlL.×u8mëÄ }±¥ÔÁ„„Zm/“­ø/¿sÌbv¶U—$ðÊï×%´]ƒ‚¦<#À%*™éÚÿ6 . ˆ¤uÉлcL«‡Ú(úI õŸ« eàaú½ª¸„‚D.a È/©f²õq6,ÀU(ˆ>Ï7jüߊ›5$(³ŽWÑMœçY~./BH ]5RL-â ÚQd^Bó°Ç!ï½GóE»>³ë{Ka›æBo³ZÓ˜å<‹b²:®RÈ<]0´R_'< uN;Tn9ÀÆ«3Új¿­yl\´“– øu|v…Â\ß1Îó¥qGÿãLÃV;c@<툂U[ÇÕc¹»ÔOêU'çåãáËbKFÚ’€1°øƒAÐ û„Q@Û­ãîÂLݰ¯¸¾->,–¥ÝG°v8ÄxËØt0žzör~Ê1ø¡JAñú¬‚ <\vÈ; j/UÝü)Y}±º”C…˜%ëB<5[/’Û<4`ó­æ#ôÑÅž„†Šb¾ÅÙz£Ï:€ÆŒ÷XŸh[M:uÎö8šÃèo8‚£† ¨7Aá)¶+™QvZ¿oÃ-xv'¼Ä=9m¡ÀÞÃâVn‹‹ÆG]»Úæ,™.Oðè’“*Md~±™o^{ªÌÌ.S·àÃ|cå3}Æ6EV«3€Šž PÏÚé1-”xTµ:.ýñu%@­¾~{HÒÔ¬n­>EŒ\ÆV‘Ež-­*…,ÌÖ¶äÚ˜ð¬tý!)ïmCPENZµÆxèWhܪêül@ê¡ÔmN‰¯:Õš¬d¦¬Ó²ƒ=Ç C=Ý_—= ²gÍ«í¶ØƒˆÅ‹pS1iØu`©¼ËõaHúáê[—|nùíZ·ü™p ¶BÂ+õëYS_hœÃ’÷%*toטgïxˆóa3£ä˜à/EYè}Ö* ËpŸZõ‘ƒ<ò&Dùôõ‘£$`)é"¥ö)dêãà¤UðRÄ´Tv æ:‚/WX]ÆWHU5DØ)r3];£µy˜c™¶î1†'6é÷Õ~/ô|n ذZí† ìek@š¤¡À6ÍF7 yk¡%Mã¨=Ø=;D(tS]+üwW8¨ÁGsuó»yË Ô§>$…ÕØšû=es™6І`å-^†oõ­ŠF9ÚÊü<º™›±)ê`ÜÌ\·èyÈ.4Þáµ ‘¨F'‹xïgo§Ç³“wÛÖO)ñZ ¥ GõLBÜ\º¼:ý08‰ŸN]¨.Kž+šRÐ/¶nZÌÁ×OHB¿¤ê#èU<òB1 3vj‹ñ_Ž×.qTì• /Ñêêpp å*ð&ê¥öñ‰ì…²g†ßž´•âí;¤ƒ÷7·c4ð ]‚ׇu˜Ü¤ `_Ämÿ ë­¨ß%†„ó>È¡³®9ŸÆÒÚ5•Ðø×Õ72Š"ªéu§LñÝZܺ²Þ›Êf¤ìt[MB=¯7Ý7J%z±ëR[ ú—Èn“¦ÓÒÂë2YÙ]c4DS[_g‹þà§ØäQu3ݦÅ&V’=-—ר­â²§ù3äoK^ȶC.Þ¡ÛiÑ»^_Å tôdzö•ñÈBþêÿÕ:'Ë¿ó ØÊä³ÿ¶8x õ‘RÏYd2•^  ²½©¾:×Wž „7C¥¢/Ù¿‚» ú endstream endobj 6045 0 obj << /Type /ObjStm /N 100 /First 1002 /Length 2227 /Filter /FlateDecode >> stream xÚÅZM·½Ï¯à1ÉÃú Y¶%@tH,è Èƒ@ˆ±ì®çßç§9û¡(CË=m@XU÷«_‹U¯È.‰-¤P·@b„×ê%uABÎâ®»ƒAB ­`d*„?ä†4AҺý ÉܦâW⮇?T»bêF ¤ìv ÆJ‚Ö@ù(Y Š±0ÖŠÛË)pJu‰“¿'ÙfÖÀÊ>6—À¹ø3r \Z׳5×+۪í$u,Å%Ž © žQ4áÝñ2©f×ËA˜º½)»Ãô¤¹T0¶r†±âï‹7—Öü=ðH=úºRP8ϨpöÑÛÀ¢GwW zôw-AMÜ Pi+þŒj!ß.µY•¥ÅÜ æÌ>Â8ä’ žçäÚºž†Üº¬a@‚QNnÙ§LºO pÕ|Dƒ©Ân¹A¹vŸ:4ëoÇÖ$>çP® ÷j¨D=¤ìöšA‚2Á±ê÷ðë1àüžÆú°ªŠ§!¦BŃ]âPkk;HÐkî?ÄY0w $DdŸw‰Iîck0m}¬+°„µŠ©€DÁšû‘ZrÿIhd˜sÄhh˜`GêRGhMƒUS¿‡ îqÂäµÌn«£•â& ™Ç$uSÉ'„0à3BìAÅ­+¸§Tü9ìÊ$'^££ìËÇúCÅc¶™ëН,·Ñ‘qöa˜Z¼‹‡" e)»gÏvû7ÿù÷!쿽ºº¾Ûí_úÇ]¿þËÇ«íöß]ßüx¸y› Ò»ýŸöÞÿ–úÅnÿêðá.¼¥¢‘”Â5z 2YôèWŠ2Ô¾ Ïž…ýë°ÿãõ›ë°~w‹¯¯þ ¾ùf‡¿ g‰)Ó=’ƱbŽ&¡´¼”J1! 9qltÒ<)•ؤþ$­¤}¢ïn'$’Rdd­)$ëNˆÆ‚Ds‚R5*‚xÊšÓ#MbŲPTJ¬Â³P2¯Es‹âÁº@Éø_ÄSP¬ÑC$ÏÃ[ÔÍ û¯Âþoÿi5Ô\£a\}úé§w_VDE:¯„ðI§³Š(t± ŒœWԂטPdÅ‹ KžWdê!ÿHñÅõÕ]÷ã °”T;yQPCáúåÊë­×Ìå· MW(-¸’ñê1aðr¥þ›ö+öo?ß…wæåûvûïëpuwëTÀã•ÇÅíõ§›‡Û#è÷þzøñãûï®=”öQë±ñòý F; ’£bÃ[<¸“%ÇÓ¹Ò"´EÈi<‚¡ aØÉG;ïVM‘E[dºO‘¥H¤²mŠLÕzB‚Ld2‡dåÉ-j¹wŠ”;³œƒ²fŠô”(N8(Z‘§*ÏBY3E.‘¢5E§W#R@°¢4Ú2RHcH¸X´<‰dåHIŰ@÷Avœ„r®ƒ¶(–ÓäK̺é2¦¶Wpvô&g ǺS£”#¨ç][Ï&“@OL/o%MôGŠX© 9mBaìñ¬b&'“í¼¢Ú1YœUDKá§ EFWÁm®¨?)ÕÓ%þE½åÏ‹z“¯/êeã2ŠzE½Ž¢^i£º×QÝë¨îuT÷: Öa°ƒ6 Ú0hà ƒ6 Ú0hà ƒ6 ¶a° ƒ/A)°B¨> ^Ð·íº¼PxÝ6Ž™ôX(|‹KR“l^(|mÒ }ʪ]WAkã»J ÅšÖy(”/0A(ŸY½-$DŽª©iºØÖôIEÌÚ ˆrEnsH(q½€O–åã%Ô|9aY—-¡ˆús:Añ­ß:˜‚ò¤)^‡{R¾Ux➨ê(r[¦ÁÑŠ©2 ƒà ÄÖ¾+,à yÛ.EûÒ€"h Jê$”USŠIdt)Š¢[‘y(«¦”1Aâ!Cðùyƒúîã–ÅÀÛ ’Hôýè +§“áeéx[í;B,×M3ê_ôc£EÁÌ×9(Fkö%Åj÷NɨÎÕÏ{¦\ ±ùq̒ר™—£-ó’IóÃóŒšQuZol©ÝvƒÕÉc@‘ZDê,”u7¨K$4 Š‚:q.³PVÍkc‚*Xô±ä™•Ð4*mšØjEBmˆb¶J¶9 +§¶á’ãâaLûIï9´_˜Ùz³Ût²Å¤ø¥=û§J_ܳ¢¨Vdzxm­çõüÞOUÏ+.g›íØm;OT>kçýˆ÷kÛy?2î0-/Ô±A‡‡P†P‡°´Ø~€½à ƒ$h±UKoWîÅjú-6ˆÌôt°©h.Á‹7­E³Ô{(­‚ÍBYu׼·b?¦y(«Ö1AÙÉz8%Çjôk£M{l?RHó•mÈÊ…cødY>’Pæ‘J{FmÛ¶ØŠ+r‚¢ -w±9(«râÁD³Ëû ¢–¢o™R*Çþ)ZAùMþÈ–9ó±XxÛ”‚|ÚOE(Šf²É,’U3Š¢ÃöÏ…$½“L#¡ÏŽ3ü+®)®óXÑ*ZûózýìÁì¼"Þ¬äóŠNÂ…d’ž<:CxBAœ(Ì™¯&+ò?ÈŠü ²Âƒdð <È ²Âƒ¬ð +<8 /Çþ¡Ú" ;2ÈŠ¬JVXÐ5aAg­~$z›áÓ\ÐkŸÝZ]yÞwÌßÍô¯3¦€¬šáÆQ­矮ö†2TŒö6œØÛ ’Ë|–6 (sô¥9ƒdUšâ_\<˜ÿ࢟èO¹ÀÖ¨7¹?Ò÷93ÙtÏÛk7ؘ"?Ãä"Ç­DpNÛ~[êcOP¤æ£“æ ”Uã„bAã8 (Ò‰çµ)(«Êi~–HáŒq$êŸÙ¥²²&›%L‡‘³ èûgSHˆFSä Mù/*ÐÛ< endstream endobj 6156 0 obj << /Length 2394 /Filter /FlateDecode >> stream xÚÕZ[“›8~ï_Á#NÅŠ.HÀÎS&ÓÉf’I2Ž3µUIÊK¹M ÀÝé¿çHƾdgkºÀB—ïÜ?IM½Kz¯Î~žŸ={0/&±âÊ›¯¼{a‘ Þ<õ>ûo&\úº¼ÐeQM¦<Œüç»Ý&[&uVä¶á=áÔ¿š0è¸)vº´Í¯öYªŸÚ÷™Þè¤Òö#œ6ù:ÿõì|~ö×(Ôcv逄4ô–Û³Ï_©—Bû¯%"޼kÓkë*‚çÆûxöûub ŸF,¥:bÅŠÄ0oÈ(¡"´¢-ˉ ¾NÓ¤Nͳ—"ê !‰˜‚ùLçël³ø*ô/P ù©^¢¤Ô¿ÙÕ:µßöU–_Ú×zíú•z©³«¶½Ú_ü‰úÒ¸ømËV¶kV»ß•}îJ]é¼vs ²'bPkP&ûz¨¿^, †ùVˆ&"‚fŒ1÷‹²‡€êª²6†Å»a>o*F"zSÆH,¥ÊÈ!©›^º²ÃÏ#Ù¡ÍÈ Ï¼¨íËAhøaPÁs…n˜d×¹.ì³kƒÁÒ[€Ÿ\ï%2ŒLYHbáÜûSåºÿY^ÈŪÔzQ_Ö‹e©Óê •þXIì3b&$‘’7Jm|«Zû1 €öâ í}½Ö¹ÓF=ÔŠ}nŠÜÊâô‘kêÔvFMd”—ž}™½: +¥8 î ¬‚ï„• #ÑÏJR·Àß¡èrµþLj˜°.‹[Ç4Ça¼3£7ŒÈŠƒÕiÜöNJp¹ß‡aÔż`Üý…ÀöY‰Ñi¿­Ü‹ñÓëÍìg¹x>QÔÿ4ÿçâŽxÿn~þ¯ùbv>_Ì_ÿvn:*ôDãEL@vdÂ9¾rYòÖY>žÿþéܨêŹ5ß*drÙ7u¥Û:˜ð!ÎTØ "nÞ ;/xA;ë¿ïêO‚’( îëOÔÜG`RWÌ,rÔ8;Q—d bª‰×2]è²,\Á™6åhY¤®Ô$ö晞Ïf鿟Ù—À´.=×Âi„ˆÂE‹”;l°KQ“i„’ €£·([w½g/A´Žœ09mý»/¥µžìƤ²X6½1aÙ¹Š].Xoñu`-bmIÁAã¥ÿ­~j}Z*œ¦~$¾!{›ê} Y `®6Ó>Ñùra“¨_^ìWO‰G€¡{pZKߊ)$”‹Ó(c-¨Q;#SaÔ±3÷Ùï<Ù|pÀÏ $rJbîrú.)“mozCªcƒZÿ9Ë¿¶¶­ üv"aÇaÜ@ŸÚ!o³‹2q•»;‰q'©›¥W»¬QÑžc5($á¡b8ç9bê†T?¤cXÜ„},P­¾¶œÄxk¼àäáMZwÃsgóF1 ‚ÀåM}Å”g*ö•áT›Ñ)UBpB‡êÿ½ÍÉ¡LªÖîÔJòq¿\‚0?9reØ:ÁuÖð0§7†&¶ÛŽ¥ ¾*[’•$¸eÝ|mêjù«}¾t›•(vY ;t ° ËÚTÑ à#P5Fì(ˆRmÊ;ö™nž ÒHkó[ÝB]ðD’§VŠR×{««¼²’$¹ý’l6lÇ´ëhÓ¬íº_ q¶ªHt¨ûËò. Ü#y7»'YŽ¬Þ¨?àôõÓCËÃoqf2™ !Æ8øaÐýH80„ð>RÉøQð;3›­™rØf™°› û5WfW=bóÁºî³ù0{ýÇ߯jÔd5FÂRÃI¨~0©y0§‘£œæQx„À×¢Stþ´0„=Hg/`þW(WE$ä¡\Yþx¢…0¹—d‚f_é²Ù_>”‚]Ð@5vÛ¿Û$7ßÅBý`mþyRö7½}úÇ![Ç?œþ @r&cø]ôÿBÿøA'NÁ%l¢Œçh,«óúp ‰;ñS%´‡ÉMy‚’§+:àªÃþŽ'–$¢q—„˜ü>¢YÖMO]þÑ+•î7صŽ0"£ŒÐ˜$´1¨pPSZNÍDŒÈ0[Œ‚.W¿‹íHkáÝeW§¹WO>ÎP¾ø¤|wI¿î"ffMˆöÎy&†±#6wz™­\û»Ooß:×X N<-“¸/µWRü/©}ô÷Qû`”Ú£¨}ã`îK2Fï!+ö˜Èr•õ •/ûBEЬšÕÍ ä"ËÃ\¯úf¢¤ïÆ[Rß&š¢<¿Ïaп]p®ÕÎ_Œ¥ ˆ Üï§"9½B ôŠ1ØO½^¬™Óƒ{I ˜»užu‚ǵ*F>‹Ro‹ÏfPÜ4- ßÅ•F^Ã"éÎnqH÷»½ŸÁ· ÷yo² N„©[zvÃ¸ÄÆvºJç)~<š:ËÝ4MÏéÆ_Ç  >Ê~½Õ_ ªà¸»‰EO<v?À}Ü n\K#þ°êÃ=‚ÙÞ@‹»Ð‚7S!`¬U¶˜ÚÏ#…™k×ß^î´]†Kf¹íæú‹Þ^E ô3iÑÍoÕ(H ÔxTæÜfÔÅM‘;Ð#ï…Œìn‡ðåôý/ïçõؽ9¯ÇwL>‚Çö¼Þ4Œž×+<ª¼¿mc%:sBv0WîBRƒkÉ÷Û Ô=¾+ «+âÔÝÕqNx,úšt–`á@§LÙ/|X"Òµ^b¶÷v©ý€½!eÍÃ4Z;Ãð&†±±[Ìønrç&µÃбá°ýàJÜ?ÇD‡cb¬Æœûï{% £7Î|P«AسÑxpÄqts‰tÒý8w©‹su»ûÙK'ìß^qgh³×DØ0êvPÎåCrr|8sBÕØXÉíJ6àÏÀWŒÉ“í®EÑM¼©ü¸j¦î^6R$ñàüR`Ü$'|^gõ׌9‡Æ›n›Õ¦HbÛR uXó³:\8_Û(ÝY–{Ç?Ì%"¶ œ}<´µÚ´5Ý{bƒI0áh¸`‡£p1¹O·0ínÛʧl¼©£šeâVÞ…×zY7÷îè:Ú£ª“Þ™½©L4¼è“¸A¼ó¿cŒÞÚÁÞ•1ÇPS(fQÿÅ:ÙMPMõˆ|ª‚Ø{ƒ©ôwÝt°ßKlÕ+7Bú.TdÏ?¼v‡c†`Á‹aõÀ„ë›e”]Iÿ‘TŸ× endstream endobj 6174 0 obj << /Length 1549 /Filter /FlateDecode >> stream xÚíYÙnÛF}×Wð‘ ¢Éìä´ON¢¤Yš:¶ pBÇ6Q‰TH*Ëß÷ÎBš¤)ÛIœ ú`p›¹÷ÜýŒŒƒ‹Ï'“GÏ8 R’Ê`qИ#ÊTñqÅ‚Eœ†¯¦T„º<ÓeQMg4ŠÃƒív­–uVäîÅS=¥8ü8%°p]lué^?ße©~èîôZ/+í¢‘éûÅËÉ|1ù0!€$ˆ(¨æ(ÂQ°ÚLNßã …÷/Œ˜ŠƒOvÕ&à2†ë:8ž¼à®-,îØbdŒ0‹œ'V¹Àá_å™HÎK­“tY/“U‘×:¯«wX`ø#nQ]¸«Ygp>z&eG8 Å„j+{WÉ ‡V`±«ÝŽ!À³í†O—:w ²Ú_+wͽâu‘_8Çû÷Z§:EÖgØ:¢¼ÜÍÑók^”Š"&øÐ‹ü.^”¬ïEcD¸rÀߘSÒ¿Œ˜)!®Š4f..ÇœG%"pç×Üê8ˆ¡jW/Kàb·MgËÈznâ°Ô °]Vê´ùvîoj@âV½:z,’ƒ©ÄáÉâ·ä‰ÙñÇ›ÅüÏEr4_$‹¿ÏíB¥Ãb€XÏAJ_7J9ž¿=™[W=™»ð½ÃL,/ú¡®tû|ÌKœ"Ž[W.Á9 äÒæ«-´Ï£ÞâˆÈ¨Ùtçt‘EpýÊtÁ.ŽˆBÊ@‰Jb•\{y4ÖjŒVÊá»O,[•eš@ºƒm[×'fîr8&ðð¡i Ë´‘BbÙEkzÙMè8Y-¼Y~¶;ÿNŸÍh¬ Gû%»®Û&¶Áêm¢óU²5edš÷MG’ˆàHÄõH&Ríf"¯©[®ƒ3£4†j€vKÁâ‡7à^nzâÿ¹gòi–¿oÃ[[RòyÏLQ‘j ÏÜ–×ÙYiÜ›¾t…جñö÷z)3!ÅèA'ïöÁˆb,À80Ⴝ0à®8Öí`¼,† ÁØ$A`rñj\4§‡3×7áÙ÷MCFÆ4{}Í0˽êÒ”n›A}í IÚŸºŽAØÖfŽ[f¿iò£€îœZ’C±|äàYBóÑH\®GE‚(ÞmRáaèßQ‚o*+`²Í9ì,9Þ­V`̯¨;Û?e [õ^ye’芄 ì‰aXe“©®c‘q *=;—–vD"<ß嫆ºsSY•®LSŒI3M­ïýj?i°{æÙ(¤Ð®+'aé¾wƒâô”ÅfŒ×°Gõ}™ ãT‰v ´(ŒâõÚkåM ¡Ç-ÇsÄ–ñ4|<«/½½Þ-EåVºwö0`¾­×”¤ÍJX³Ñ›¢éÖï ˜mÌdŸ)šº]fy–{ög™¨§„\¯Óª9h€·ú  aTBµ…Éåø‹¡ÝqLÿïö~Oýu'H&y•·7{TPqO'œ;3Ë­œ8£G£Ü2IWúGóK÷æÜô•Ÿ†ŸÚ³€9 >ùoÐOë¨ëƒ?‚N&äýRÐof â1Pú3PH(j¡úäé^˜(N¤xÍ.Kø-|X–ƒ<È‹|4ë€Æ‚Þ?Ý„QÎyü?ÝüIèf'}†1à׸æ±ÿÅHç+?9óÝæ¬H##9½‘œ~ (ÔÑ¿ÊE㎋òQ.ªâ.…§–‹2¬®qQÕLe¸ç¢ÊMf¸¨ŠösQ¸çôV.*Њ>-W\öqQ¥ZñûRXc$â½2æZÎ=Ý,©ºy쨨aÙÑ€Šúä†õùÇðç@¬TÞù'øÑßöàhGˆOF‰šÂáKÙyàÿ…pøÂå‚ ·."$"ûÃ[öe endstream endobj 6190 0 obj << /Length 2609 /Filter /FlateDecode >> stream xÚ­Z[sÛ6~÷¯Ð£Ô‰Ip÷Ém“ŽÛtã:ÎÎÎ$ %B6'©’Tœüû=7¥Øq_Ä nçòá;ç€"³»™ývñóíÅËלÎÒ Y<»ÝÎ6K¸xÎnóÙ‡ù Íe³–MÝ.–,óËý¾,6YWÔ•~ñ«\02ÿ² Ð±¬÷²Ñ¯;¹|¡ïod)³Vê0ÐŧÛß/^Ý^ü}AA2£zi$$™mv>‘Y LÅìAõÚÍx,àZÎÞ]üuAŒ$  = Xbï˜Îh8zysJaJ&ZáÏÍ:Z5ù ´}þÖ"/õåzÍ3Õ`uɪ\ßärƒzGóo{èÔ™V}ùãæçÕåõêæÕ_úy'Û6»[,)™Ë@ÙÁ)âbD Ô ‡_.b­Ðø%(ôòu´!³%ã l4PF6 :±nV›:—Þz/_ƒú[Àäl6²XÁJÑ o”QÈmß$"zæ•< XH½¥7uÕ)P}íFB‡b8‚:Ap\„Ñük÷ây…!܆žDÙ"óûÇŠ–$w:ý£õH'à… Ä-ÎÕ=O\ÁùâæY—‡0sòÕú°}¦Ñ–,å°ïØlIiF‘ïέ׭öMQmŠ}VžN õæo« Ë„HG NæÏ””‰ I˜g¯Ïò[—­ÏbIØoä=p&™ã¸ç„sOž$Œ²»ö¬ y_:ˆíq·®ê=²sûl_âì“¾ìŠ ªýY€{BÀ$Y±Ÿp$XM›®›à°Cšh…Näw®0i8T… ØŠI :ÁôTèÙ÷Y“í¼égª9ñ5þPTŸÜVíT°ûj$÷ÁA‚4q¢/õ7źÉ4v¿ 'Q `Ô÷$5³,i¤aè$¨b@#§$i@“x$Éu#—zÝBóMQÝé–ºÑ×Jaùû”1¬ÀÌ:™÷«?J#ÃX£„âš É‘’âd$ùå5î÷¥ŽŸðlâ'&&úEWëëÚ<ƒc[xB*3ÿ ©€e,ÁLˆCp‹ögÖmИ÷Θ{ílËpêÝå·Vž¤2Ïÿyÿæ¯XV–5v0•"Ó •¾ú 5i­•6ä³’QWùŠÄ·Œèmô+U²u)¿«è¡µ.½77¹Ü¢§³C9 3½¶ïÏÁ^>Ę£8QäÅ R Qk¼w¯¶f_ÔÕ²:”å‹‘hc\Z¾Ö:€0ûäèfÍS²;¦T.@Ù§M/ŽöË)¹}êÕÈlêÝw´î¶sT‡Ö*‚¼Šo†X3-è;us”‘¡I UÔ7¸ *iìcž}ìÁ ÄË„ùHÚW(²I>ö,é°§öÌYÜU€»”¹^am´óÀ¢Ô5"dF’z·/egzEgxWe;Ó îQöfð8ã¾½GAßK"ö9hAæn²ª- C[î3—œ©¤DjϺÜDod¸iä¾ÌÁy“™6E)¥b­É=öÖ#ND¥0pb‚xHÓ¼'ˆT|¡Ü×zÝeE¥,)È)Ò¢) xø(ä$=kÁ”Å„‹t‚ EíS‹±˜¸‚–tk®/9æ.¾½ªìĶñÔ"‡ã’CÆ ;ÇGÆ®÷]j’^}ØøÁËãä0UðCãÄTè1ÊbÓ‰qBñ´RêнZœjåF[¢²d h¼ —é¥&Ó¬©_RÚ£Õ-À…Áú!„Ñ[‹Ú!ÈÀ­­Ýz.WÀÜa79tñ“Yõèµ#ö™þ¦o½™Ê«²Æ¥¯Ù,;ƒslm‡[Úmsú_£¤ÆK„ r€‡·Ÿ”]m§(ÒÐè ™¢á…Q%³yQ¾éÒÄ¢O[Ð$ÉEgó¬ªóŠåé@,x‹ä1|€çØ#I{@çl­8y\*>ÉØÇ<):9V(ÂSoþ8}øX`þfP[õF…ø12j!Ûsf¥Q‰ø‰f}¸/ú}LÛzBÍ0ÅÍí¨Çú/Çuzõ:°ëƒ¤_Ç·?K»ÃÎY‘1ˆ,|¢£aX¦OÛz1¤À±øgv¸ªDœWÙ9>ß”ÈdŒí%]SFæÃêaYrÆÎþdÏ_Ú÷ñÉZÅÎ3áæ’÷ñ QÞÝÕZv,6VYž7Óõ†è=¤ä.s¹Ž× Iö¤òØ¢† ŽbÔ0ãM‚ߎ`¾ƒô¬îùB†<>ŒÈl -¡¾0€¡1ƒº$ªùb]óÅ^nKUeàr[|¼ä—æ^×K˜¤«ü¥ÈuÝ+SU`Lù†Æ!¤"ü*ÁþŒIUs‰-Ãâ1V©©£´#ÂPx|T`Fe:J±Ó&x¶V«jc¦ºÂó«bcJ@&ŽÄ(ñ,¼ÄåPåcÛ#äSÛÏQ‹RîLáÔîúN­2 j‹€þª]Za9Š1õñ؃Ü)™›cý¢> R4t'JpëÕ_¦YG0¸Ùoõž²åf’J_µþTÕ¹mÅOzhsF1Æ”‡\gì¸bS·í²‘Y¹3«Ôe±ù¶ˆ#5†¤fN@Ú>S~píÔ„\zŸà9®+rýá"%ïŠl§ FS­·úü  ðÙðõixHô^3z-'6h9ÕNßÕ¶În-ÑTó¦:ìÖÊа˜ÊÙÍv6CǼd·v÷0©Ù`‚8ñ‹+{:Äb&zˆ-yÂt èÉ¿R¤á·ïåõêíõí»ÕŸïoߣ5.ßà? Þ_ݼú†óp¾V%*ܨMWÃÇœ½á@@¥%ªÕ³¼qãÌÍñ¿ELæooÔéN®_=ꔇý´ÎçæÀÌÄf÷ü2 §÷ö´VÕ ÛFÊ•X[‡úŸ°ã©#É~×Ù<>%¢O~û Æ'¸Ê¬ZÖ•>sߨd>Î\Çÿ‚°øÑ‚™üK g¥&¡¢T ÅAæ¿Ügúï)F DÌcaÌÓù/{£9To¶ƒn×ÿƒÙšÑܸµÿSÌåõÕø¿0¼-ºo{ÙŽ5ý?E„ endstream endobj 6205 0 obj << /Length 2200 /Filter /FlateDecode >> stream xÚÕY[oܶ~÷¯Ðãnex‘(霧´Y·ir’ÖÞH‚…,qm!»ÒV—8>¿þÌÔ]¾Å-Ú€EÈá7ùq–:—u~:ùasòâÔeNHBÉ¥³Ù9